[SCM] libav/experimental: Imported Upstream version 10~alpha1

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Fri Jan 10 14:01:55 UTC 2014


The following commit has been merged in the experimental branch:
commit 5eec7f12bb47d98ca7a380305ee9da0d3ec233f9
Author: Reinhard Tartler <siretart at tauware.de>
Date:   Wed Dec 18 15:08:58 2013 +0000

    Imported Upstream version 10~alpha1

diff --git a/.gitignore b/.gitignore
index 3ed55b3..01d93b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,8 @@
 *.dll
 *.exe
 *.exp
+*.gcda
+*.gcno
 *.h.c
 *.ilk
 *.lib
@@ -22,6 +24,7 @@
 /avprobe
 /avserver
 /config.*
+/coverage.info
 /version.h
 /doc/*.1
 /doc/*.html
@@ -29,7 +32,10 @@
 /doc/avoptions_codec.texi
 /doc/avoptions_format.texi
 /doc/doxy/html/
+/doc/examples/output
+/doc/examples/transcode_aac
 /doc/print_options
+/lcov/
 /libavcodec/*_tablegen
 /libavcodec/*_tables.c
 /libavcodec/*_tables.h
diff --git a/Changelog b/Changelog
index 594a6ff..6ec0357 100644
--- a/Changelog
+++ b/Changelog
@@ -1,342 +1,64 @@
-Releases are sorted from youngest to oldest.
-
-version 9.10:
-- alac: Do bounds checking of lpc_order read from the bitstream
-- ape: Don't allow the seektable to be omitted
-- asfdec: Check the return value of asf_read_stream_properties
-- asvdec: Verify the amount of extradata
-- avidec: Make sure a packet is large enough before reading its data
-- bfi: Add some very basic sanity checks for input packet sizes
-- bfi: Avoid divisions by zero
-- cavsdec: Make sure a sequence header has been decoded before decoding pictures
-- dcadec: Validate the lfe parameter
-- dsicin: Add some basic sanity checks for fields read from the file
-- eacmv: Make sure a reference frame exists before referencing it
-- electronicarts: Add more sanity checking for the number of channels
-- electronicarts: Check packet sizes before reading
-- ffv1: Make sure at least one slice context is initialized
-- fraps: Make the input buffer size checks more strict
-- h263dec: Remove a hack that can cause infinite loops
-- idroqdec: Make sure a video stream has been allocated before returning packets
-- ivi_common: Make sure color planes have been initialized
-- lavf: Avoid setting avg_frame_rate if delta_dts is negative
-- mace: Make sure that the channel count is set to a valid value
-- matroskadec: Verify realaudio codec parameters
-- mov: Don't use a negative duration for setting other fields
-- mov: Make sure the read sample count is nonnegative
-- mpc8: Check the seek table size parsed from the bitstream
-- mpc8: Make sure the first stream exists before parsing the seek table
-- mpeg4videodec: Check the width/height in mpeg4_decode_sprite_trajectory
-- mpegaudiodec: Validate that the number of channels fits at the given offset
-- mpegvideo: Initialize chroma_*_shift and codec_tag even if the size is 0
-- mvi: Add sanity checking for the audio frame size
-- mxfdec: set audio timebase to 1/samplerate
-- oggparseogm: Convert to use bytestream2
-- omadec: Properly check lengths before incrementing the position
-- pcx: Check the packet size before assuming it fits a palette
-- pcx: Consume the whole packet if giving up due to missing palette
-- pngdec: Stop trying to decode once inflate returns Z_STREAM_END
-- qpeg: Add checks for running out of rows in qpeg_decode_inter
-- r3d: Add more input value validation
-- riffdec: Add sanity checks for the sample rate
-- rl2: Avoid a division by zero
-- rmdec: Validate the fps value
-- rpza: Fix a buffer size check
-- rv10: Validate the dimensions set from the container
-- rv34: Check the return value from ff_rv34_decode_init
-- segafilm: Validate the number of audio channels
-- shorten: Break out of loop looking for fmt chunk if none is found
-- shorten: Use a checked bytestream reader for the wave header
-- sierravmd: Do sanity checking of frame sizes
-- smacker: Avoid integer overflow when allocating packets
-- smacker: Don't return packets in unallocated streams
-- smacker: Make sure we don't fill in huffman codes out of range
-- svq3: Avoid a division by zero
-- svq3: Check for any negative return value from ff_h264_check_intra_pred_mode
-- truemotion2: Use av_freep properly in an error path
-- twinvqdec: Check the ibps parameter separately
-- vc1dec: Don't decode slices when the latest slice header failed to decode
-- vc1dec: Fix leaks in ff_vc1_decode_init_alloc_tables on errors
-- vc1dec: Make sure last_picture is initialized in vc1_decode_skip_blocks
-- vc1dec: Undo mpegvideo initialization if unable to allocate tables
-- vocdec: Don't update codec parameters mid-stream
-- vp3: Check the framerate for validity
-- vqf: Make sure sample_rate is set to a valid value
-- vqf: Make sure the bitrate is in the valid range
-- wnv1: Make sure the input packet is large enough
-- wtv: Add more sanity checks for a length read from the file
-- xan: Only read within the data that actually was initialized
-- xan: Use bytestream2 to limit reading to within the buffer
-- xmv: Add more sanity checks for parameters read from the bitstream
-- xwma: Avoid division by zero
-- xxan: Disallow odd width
-- zmbvdec: Check the buffer size for uncompressed data
-
-version 9.9:
-- 4xm: check that bits per sample is strictly positive
-- 4xm: Check that the read track value is non-negative
-- 4xm: Reject not a multiple of 16 dimension
-- 8bps: Bound-check the input buffer
-- aac: Check init_get_bits return value
-- aac: return meaningful errors
-- ac3: Clean up the error paths
-- ac3dec: Don't consume more data than the actual input packet size
-- ac3dec: Increment channel pointers only once per channel
-- ac3: Do not clash with normal AVERROR
-- ac3: Return proper error codes
-- adpcm: Write the correct number of samples for ima-dk4
-- alac: Check that the channels fit at the given offset
-- alac: Limit max_samples_per_frame
-- alsdec: Clean up error paths
-- alsdec: Fix the clipping range
-- ape demuxer: check for EOF in potentially long loops
-- atrac3: Error on impossible encoding/channel combinations
-- atrac3: fix error handling
-- atrac3: set the getbits context the right buffer_end
-- avconv: do not use lavfi direct rendering with -deinterlace
-- avidec: Let the inner dv demuxer take care of discarding
-- avio: Handle AVERROR_EOF in the same way as the return value 0
-- bink: Bound check the quantization matrix.
-- dca: Error out on missing DSYNC
-- dca: Respect the current limits in the downmixing capabilities
-- dsicinav: Bound-check the source buffer when needed
-- dsicinav: Clip the source size to the expected maximum
-- dv: Add a guard to not overread the ppcm array
-- dxa: Make sure the reference frame exists
-- h261: check the mtype index
-- iff: Do not read over the source buffer
-- imc: Catch a division by zero
-- indeo4: Check the quantization matrix index
-- indeo4: Do not access missing reference MV
-- indeo4: Validate scantable dimension
-- indeo5: return proper error codes
-- indeo: Bound-check before applying motion compensation
-- indeo: Bound-check before applying transform
-- indeo: Do not reference mismatched tiles
-- indeo: Reject impossible FRAMETYPE_NULL
-- indeo: Sanitize ff_ivi_init_planes fail paths
-- lavf: avoid integer overflow when estimating bitrate
-- lavf: Make sure avg_frame_rate can be calculated without integer overflow
-- matroskadec: Check that .lang was allocated and set before reading it
-- mjpegb: Detect changing number of planes in interlaced video
-- mlpdec: Do not set invalid context in read_restart_header
-- mov: Do not allow updating the time scale after it has been set
-- mov: Seek back if overreading an individual atom
-- mpegvideo: Avoid 32-bit wrapping of linesize multiplications
-- nuv: check ff_rtjpeg_decode_frame_yuv420 return value
-- nuv: Do not ignore lzo decompression failures
-- nuv: Pad the lzo outbuf
-- nuv: Reset the frame on resize
-- nuv: return meaningful error codes.
-- nuv: Use av_fast_realloc
-- ogg: Always alloc the private context in vorbis_header
-- ogg: Fix potential infinite discard loop
-- oma: check geob tag boundary
-- oma: correctly mark and decrypt partial packets
-- oma: refactor seek function
-- pcm: always use codec->id instead of codec_id
-- pcx: Do not overread source buffer in pcx_rle_decode
-- pictordec: break out of both decoding loops when y drops below 0
-- pictordec: pass correct context to avpriv_request_sample
-- qdm2: check and reset dithering index per channel
-- qdm2: Conceal broken samples
-- qdm2: refactor joined stereo support
-- qdm2: use init_static_data
-- rmdec: Use the AVIOContext given as parameter in rm_read_metadata()
-- rtjpeg: Use init_get_bits8
-- rtmp: Do not misuse memcmp
-- rtmp: rename data_size to size
-- segafilm: Error out on impossible packet size
-- vc1: check mb_height validity.
-- vc1: check the source buffer in vc1_mc functions
-- vcr1: add sanity checks
-- vqavideo: check the version
-- westwood_vqa: do not free extradata on error in read_header
-- wmavoice: conceal clearly corrupted blocks
-- wtv: Mark attachment with a negative stream id
-- xl: Make sure the width is valid
-
-version 9.8:
-- kmvc: Clip pixel position to valid range
-- kmvc: Use fixed sized arrays in the context
-- indeo: Reject negative array indexes
-- indeo: Check for reference when inheriting motion vectors
-- indeo: Properly forward the error codes
-- mjpeg: Check the unescaped size for overflows
-- wmapro: Error out on impossible scale factor offsets
-- wmapro: Check the min_samples_per_subframe
-- wmapro: Return early on unsupported condition
-- wmapro: Check num_vec_coeffs against the actual available buffer
-- wmapro: Make sure there is room to store the current packet
-- lavc: Move put_bits_left in put_bits.h
-- 4xm: Do not overread the source buffer in decode_p_block
-- 4xm: Check bitstream_size boundary before using it
-
-version 9.7:
-
-Most of the following fixes resulted from test samples that the Google
-Security Team has kindly made available to us:
-
-- 4xm: fix several programming errors to avoid crashes, etc.
-- apetag: use int64_t for filesize
-- jpegls: Fix invalid writes to memory
-- ljpeg: use the correct number of components in YUV
-- mjpeg: Validate sampling factors
-- mjpegdec: properly report unsupported disabled features
-- mjpegdec: validate parameters in mjpeg_decode_scan_progressive_ac
-- mpegvideo: allocate sufficiently large scratch buffer for interlaced vid
-- pixdesc: mark gray8 as pseudopal
-- smacker: fix several programming errors to avoid crashes, etc.
-- tiff: do not overread the source buffer
-- vmd: drop incomplete chunks and spurious samples
-- vmdav: convert to bytestream2 to avoid invalid reads and writes
-- wavpack: check packet size early
-- wavpack: use bytestream2 in wavpack_decode_block
-- wavpack: validate samples size parsed in wavpack_decode_block
-
-
-version 9.6:
-- aac: check the maximum number of channels to avoid invalid writes
-- indeo3: fix off by one in MV validity check
-- id3v2: check for end of file while unescaping tags to avoid invalid
-  writes, reported by Google Security Team
-- afifo: fix request_samples on the last frame in certain cases
-- hls, segment: fix splitting for audio-only streams
-- wav: Always seek to an even offset, Bug #500, LP: #1174737
-- swscale: Use alpha from the right row in yuva2rgba_c, Bug #504
-- indeo3: use unaligned reads on reference blocks, Bug #503
-- oma: properly forward errors in oma_read_packet
-- af_asyncts: fix offset calculation
-- proresdec: support mixed interlaced/non-interlaced content
-
-version 9.5:
-
-Most of the following fixes resulted from test samples that the Google
-Security Team has kindly made available to us:
-
-- af_channelmap: sanity check input channel indices in all cases
-- avfiltergraph: check for sws opts being non-NULL before using them
-- bmv: check for len being valid in bmv_decode_frame()
-- configure: Enable hwaccels without external dependencies by default
-- dfa: check for invalid access in decode_wdlt()
-- id3v2: pad the APIC packets as required by lavc
-- indeo3: check motion vectors
-- indeo3: fix data size check
-- indeo3: switch parsing the header to bytestream2
-- lavf: make sure stream probe data gets freed
-- matroska: Update the available size after lace parsing
-- matroska: fix a corner case in ebml-lace parsing
-- matroska: pass the lace size to the matroska_parse_rm_audio
-- mp3dec: fallback to generic seeking when a TOC is not present
-- oggdec: fix faulty cleanup prototype
-- oma: Validate sample rates
-- qdm2: check that the FFT size is a power of 2
-- riff: check for eof if chunk size and code are 0 to prevent an infinite loop
-- rv10: check that extradata is large enough
-- svq1dec: check that the reference frame has the same dimensions as the current one
-- svq1dec: clip motion vectors to the frame size
-- xmv: check audio track parameters validity
-- xmv: do not leak memory in the error paths in xmv_read_header()
-
-
-version 9.4:
-- atrac3: avoid oversized shifting in decode_bytes()
-- eamad: allocate a dummy reference frame when the real one is missing
-- ffv1: fix calculating slice dimensions for version 2
-- flacdec: simplify bounds checking in flac_probe()
-- h264: check for luma and chroma bit dept being equal (CVE-2013-2277)
-- hqdn3d: Fix out of array read in LOWPASS
-- iff: validate CMAP palette size (CVE-2013-2495)
-- ivi_common: do not call MC for intra frames when dc_transform is unset
-- libmp3lame: use the correct remaining buffer size when flushing
-- lzo: fix overflow checking in copy_backptr()
-- mp3dec: Fix VBR bit rate parsing
-- png: use av_mallocz_array() for the zlib zalloc function
-- roqvideodec: fix a potential infinite loop in roqvideo_decode_frame()
-- shorten: fix various programming mistakes
-- vf_gradfun: fix uninitialized variable use
-- vf_hqdn3d: fix uninitialized variable use
-- vmdaudio: fix invalid reads when packet size is not a multiple of chunk size
-- wmadec: require block_align to be set
-- wmaprodec: require block_align to be set
-- wmaprodec: return an error, not 0, when the input is too small
-- xxan: fix invalid memory access in xan_decode_frame_type0()
-
-version 9.3:
-- h264: fix deadlocks with broken/fuzzed files
-- flvdec: make decoder more robust
-- vorbisdec: fix buffer overflow (CVE-2013-0894)
-- ac3dec: validate channel output mode against channel count
-- doc: minor improvements
-
-version 9.2:
-- loco: check that there is data left after decoding a plane.
-- mov: use the format context for logging.
-- lagarith: avoid infinite loop in lag_rac_refill() with corrupted files
-- flicvideo: avoid an infinite loop in byte run compression
-- av_memcpy_backptr: avoid an infinite loop for back = 0
-- mlpdec: do not try to allocate a zero-sized output buffer.
-- qtrle: add more checks against pixel_ptr being negative.
-- 4xm: check the return value of read_huffman_tables().
-- cavs: initialize various context tables, avoids crashes with corrupted files
-- x86/H.264: Don't use redzone in AVX h264_deblock on Win64
-- VQA video: check chunk sizes before reading chunks
-- RoQ video decoder: check dimensions validity
-- QDM2: check array index before use, fix out of array accesses
-- mpegvideo: Do REBASE_PICTURE with byte pointers
-- SVQ3: unbreak decoding
-- libopencore-amrwb: Make AMR-WB ifdeffery more precise
-- libopencore-amr: Conditionally compile decoder and encoder bits
-- arm: Fall back to runtime cpu feature detection via /proc/cpuinfo
-- xxan: properly handle odd heights
-- msrledec: check bounds before constructing a possibly invalid pointer (CVE-2496)
-- qtrle: fix the topmost line for 1bit
-- aasc: fix output for msrle compression
-- yop: check for input overreads
-- yop: check that extradata is large enough
-- fraps: fix off-by one bug for version 1
-- vf_delogo: fix copying the input frame
-- vf_delogo: fix an uninitialized read
-- dnxhdenc: fix invalid reads in dnxhd_mb_var_thread()
-- ATRAC3: use correct loop variable in add_tonal_components()
-- MLP: store the channel layout for each substream
-- MLP decoder: TrueHD: use Libav channel order
-- x86: ac3: Fix HAVE_MMXEXT condition to only refer to external assembly
-- arm: vp8: Fix the plain-armv6 version of vp8_luma_dc_wht
-- lavr: call mix_function_init() in ff_audio_mix_set_matrix()
-- rtpenc_chain: Use the original AVFormatContext for getting payload type
-- rtp: Make sure the output format pointer is set
-- rtp: Make sure priv_data is set before reading it
-- videodsp_armv5te: remove #if HAVE_ARMV5TE_EXTERNAL
-- get_bits: change the failure condition in init_get_bits
-- mpegvideo: fix loop condition in draw_line()
-- fate: update ref after rv30_loop_filter fix
-- RV30: fix masking in rv30_loop_filter()
-- libcdio: support recent cdio-paranoia
-- Theora: Skip zero-sized headers
-- H.264: add 3 pixels below for subpixel filter wait position
-- H.264: fix ff_generate_sliding_window_mmcos() prototype
-- H.264: don't clobber mmco opcode tables for non-first slice headers
-- libx264: use the library specific default rc_initial_buffer_occupancy
-- lavc: set the default rc_initial_buffer_occupancy
-- lavc: introduce the convenience function init_get_bits8
-- lavc: check for overflow in init_get_bits
-- configure: enable pic for shared libs on AArch64
-- zmbv: Reset the decoder on keyframe errors
-- VC1 decoder: prevent a crash due missing pred_flag parameter
-- matroska: Fix use after free
-- VP3: Fix double free in vp3_decode_end()
-
-
-version 9.1:
-- Fix a crash on windows platforms related to automatic stack alignment
-  in libavresample
-- Fix memleaks in the Ogg demuxer. Related to CVE-2012-2882
+Entries are sorted chronologically from oldest to youngest within each release,
+releases are sorted from youngest to oldest.
+
+version 10:
+- av_strnstr
+- support ID3v2 tags in ASF files
+- reference-counting for AVFrame and AVPacket data
+- avconv now fails when input options are used for output file
+  or vice versa
+- avconv options -filter_script and -filter_complex_script, which allow a
+  filtergraph description to be read from a file
+- uniform options syntax across all filters
+- interlace filter
+- JPEG 2000 decoder
+- asetpts filter (same as setpts, but for audio)
+- trim and atrim filters
+- avconv -t and -ss (output-only) options are now sample-accurate when
+  transcoding audio
+- Matroska muxer can now put the index at the beginning of the file.
+- avconv -deinterlace option removed, the yadif filter should be used instead
+- Apple Intermediate Codec decoder
+- Escape 130 video decoder
+- support for slice multithreading in libavfilter
+- VC-1 interlaced B-frame support
+- support for WavPack muxing (raw and in Matroska)
+- Go2Webinar decoder
+- WavPack encoding through libwavpack
+- Added the -n parameter to avconv
+- RTMP seek support
+- when transcoding with avconv (i.e. not streamcopying), -ss is now accurate
+  even when used as an input option. Previous behavior can be restored with
+  the -noaccurate_seek option.
+- avconv -t option can now be used for inputs, to limit the duration of
+  data read from an input file
+- Voxware MetaSound decoder
+- WebP decoder
+- Error Resilient AAC syntax (ER AAC LC) decoding
+- Low Delay AAC (ER AAC LD) decoding
+- mux chapters in ASF files
+- Opus in Ogg demuxing
+- Enhanced Low Delay AAC (ER AAC ELD) decoding (no LD SBR support)
+- F4V muxer
+- HNM version 4 demuxer and video decoder
+- HEVC decoder
+- raw HEVC, HEVC in MOV/MP4, HEVC in Matroska, HEVC in MPEG-TS demuxing
+- remove avplay -vismv option, which has not worked for a long time
+- Live HDS muxer
+- setsar/setdar filters now support variables in ratio expressions
+- dar variable in the scale filter now returns the actual DAR (i.e. a * sar)
+- VP9 decoder
+- support for decoding through VDPAU in avconv (the -hwaccel option)
+- remove mp3_header_(de)compress bitstream filters
+- stereoscopic 3d metadata handling
+- png standalone parser
 
 
 version 9:
 - av_basename and av_dirname
 - adobe and limelight publisher authentication in RTMP
+- VDPAU hardware acceleration through normal hwaccel
+- SRTP support
 
 
 version 9_beta3:
@@ -684,7 +406,7 @@ version 0.6:
 - LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks)
 - WMA Pro decoder
 - Core Audio Format demuxer
-- Atrac1 decoder
+- ATRAC1 decoder
 - MD STUDIO audio demuxer
 - RF64 support in WAV demuxer
 - MPEG-4 Audio Lossless Coding (ALS) decoder
@@ -784,7 +506,7 @@ version 0.5:
 - MXF demuxer
 - VC-1/WMV3/WMV9 video decoder
 - MacIntel support
-- AVISynth support
+- AviSynth support
 - VMware video decoder
 - VP5 video decoder
 - VP6 video decoder
@@ -812,7 +534,7 @@ version 0.5:
 - Interplay C93 demuxer and video decoder
 - Bethsoft VID demuxer and video decoder
 - CRYO APC demuxer
-- Atrac3 decoder
+- ATRAC3 decoder
 - V.Flash PTX decoder
 - RoQ muxer, RoQ audio encoder
 - Renderware TXD demuxer and decoder
diff --git a/LICENSE b/LICENSE
index 1266627..1074989 100644
--- a/LICENSE
+++ b/LICENSE
@@ -23,6 +23,11 @@ Specifically, the GPL parts of Libav are
     - vf_hqdn3d.c
     - vf_yadif.c
 
+Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
+the configure parameter --enable-version3 will activate this licensing option
+for you. Read the file COPYING.LGPLv3 or, if you have enabled GPL parts,
+COPYING.GPLv3 to learn the exact legal terms that apply in this case.
+
 There are a handful of files under other licensing terms, namely:
 
 * The files libavcodec/jfdctfst.c, libavcodec/jfdctint_template.c and
@@ -32,11 +37,6 @@ There are a handful of files under other licensing terms, namely:
   You must also indicate any changes including additions and deletions to
   those three files in the documentation.
 
-Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
-the configure parameter --enable-version3 will activate this licensing option
-for you. Read the file COPYING.LGPLv3 or, if you have enabled GPL parts,
-COPYING.GPLv3 to learn the exact legal terms that apply in this case.
-
 
 external libraries
 ==================
diff --git a/Makefile b/Makefile
index 291197b..25c3b32 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ 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
+SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM STRIP
 MSG    = $@
 M      = @$(call ECHO,$(TAG),$@);
 $(foreach VAR,$(BRIEF), \
@@ -28,7 +28,7 @@ CFLAGS     += $(ECFLAGS)
 CCFLAGS     = $(CPPFLAGS) $(CFLAGS)
 ASFLAGS    := $(CPPFLAGS) $(ASFLAGS)
 YASMFLAGS  += $(IFLAGS:%=%/) -Pconfig.asm
-HOSTCCFLAGS = $(IFLAGS) $(HOSTCFLAGS)
+HOSTCCFLAGS = $(IFLAGS) $(HOSTCPPFLAGS) $(HOSTCFLAGS)
 LDFLAGS    := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
 
 define COMPILE
@@ -38,6 +38,7 @@ endef
 
 COMPILE_C = $(call COMPILE,CC)
 COMPILE_S = $(call COMPILE,AS)
+COMPILE_HOSTC = $(call COMPILE,HOSTCC)
 
 %.o: %.c
 	$(COMPILE_C)
@@ -45,6 +46,9 @@ COMPILE_S = $(call COMPILE,AS)
 %.o: %.S
 	$(COMPILE_S)
 
+%_host.o: %.c
+	$(COMPILE_HOSTC)
+
 %.i: %.c
 	$(CC) $(CCFLAGS) $(CC_E) $<
 
@@ -56,23 +60,27 @@ COMPILE_S = $(call COMPILE,AS)
 
 %.c %.h: TAG = GEN
 
-PROGS-$(CONFIG_AVCONV)   += avconv
-PROGS-$(CONFIG_AVPLAY)   += avplay
-PROGS-$(CONFIG_AVPROBE)  += avprobe
-PROGS-$(CONFIG_AVSERVER) += avserver
+AVPROGS-$(CONFIG_AVCONV)   += avconv
+AVPROGS-$(CONFIG_AVPLAY)   += avplay
+AVPROGS-$(CONFIG_AVPROBE)  += avprobe
+AVPROGS-$(CONFIG_AVSERVER) += avserver
+
+AVPROGS    := $(AVPROGS-yes:%=%$(EXESUF))
+PROGS      += $(AVPROGS)
+
+AVBASENAMES = avconv avplay avprobe avserver
+ALLAVPROGS  = $(AVBASENAMES:%=%$(EXESUF))
+
+$(foreach prog,$(AVBASENAMES),$(eval OBJS-$(prog) += cmdutils.o))
+
+OBJS-avconv                   += avconv_opt.o avconv_filter.o
+OBJS-avconv-$(HAVE_VDPAU_X11) += avconv_vdpau.o
 
-PROGS      := $(PROGS-yes:%=%$(EXESUF))
-OBJS        = cmdutils.o $(EXEOBJS)
-OBJS-avconv = avconv_opt.o avconv_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))
-ALLMANPAGES = $(BASENAMES:%=%.1)
-
 FFLIBS-$(CONFIG_AVDEVICE) += avdevice
 FFLIBS-$(CONFIG_AVFILTER) += avfilter
 FFLIBS-$(CONFIG_AVFORMAT) += avformat
@@ -84,14 +92,14 @@ FFLIBS := avutil
 
 DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.avpreset)
 
-SKIPHEADERS = cmdutils_common_opts.h
+SKIPHEADERS = cmdutils_common_opts.h compat/w32pthreads.h
 
 include $(SRC_PATH)/common.mak
 
 FF_EXTRALIBS := $(FFEXTRALIBS)
 FF_DEP_LIBS  := $(DEP_LIBS)
 
-all: $(PROGS)
+all: $(AVPROGS)
 
 $(TOOLS): %$(EXESUF): %.o $(EXEOBJS)
 	$(LD) $(LDFLAGS) $(LD_O) $^ $(ELIBS)
@@ -126,8 +134,10 @@ endef
 
 $(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
 
+include $(SRC_PATH)/doc/Makefile
+
 define DOPROG
-OBJS-$(1) += $(1).o cmdutils.o $(EXEOBJS)
+OBJS-$(1) += $(1).o $(EXEOBJS) $(OBJS-$(1)-yes)
 $(1)$(EXESUF): $$(OBJS-$(1))
 $$(OBJS-$(1)): CFLAGS  += $(CFLAGS-$(1))
 $(1)$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
@@ -135,7 +145,7 @@ $(1)$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1))
 -include $$(OBJS-$(1):.o=.d)
 endef
 
-$(foreach P,$(PROGS-yes),$(eval $(call DOPROG,$(P))))
+$(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(EXESUF)=))))
 
 $(PROGS): %$(EXESUF): %.o $(FF_DEP_LIBS)
 	$(LD) $(LDFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
@@ -157,7 +167,7 @@ version.h .version:
 # force version.sh to run whenever version might have changed
 -include .version
 
-ifdef PROGS
+ifdef AVPROGS
 install: install-progs install-data
 endif
 
@@ -168,9 +178,9 @@ install-libs: install-libs-yes
 install-progs-yes:
 install-progs-$(CONFIG_SHARED): install-libs
 
-install-progs: install-progs-yes $(PROGS)
+install-progs: install-progs-yes $(AVPROGS)
 	$(Q)mkdir -p "$(BINDIR)"
-	$(INSTALL) -c -m 755 $(PROGS) "$(BINDIR)"
+	$(INSTALL) -c -m 755 $(AVPROGS) "$(BINDIR)"
 
 install-data: $(DATA_FILES)
 	$(Q)mkdir -p "$(DATADIR)"
@@ -179,26 +189,26 @@ install-data: $(DATA_FILES)
 uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
 
 uninstall-progs:
-	$(RM) $(addprefix "$(BINDIR)/", $(ALLPROGS))
+	$(RM) $(addprefix "$(BINDIR)/", $(ALLAVPROGS))
 
 uninstall-data:
 	$(RM) -r "$(DATADIR)"
 
 clean::
-	$(RM) $(ALLPROGS)
+	$(RM) $(ALLAVPROGS)
 	$(RM) $(CLEANSUFFIXES)
 	$(RM) $(CLEANSUFFIXES:%=tools/%)
+	$(RM) -rf coverage.info lcov
 
 distclean::
 	$(RM) $(DISTCLEANSUFFIXES)
-	$(RM) config.* .version version.h libavutil/avconfig.h
+	$(RM) config.* .config libavutil/avconfig.h .version version.h
 
 config:
 	$(SRC_PATH)/configure $(value LIBAV_CONFIGURATION)
 
 check: all alltools checkheaders examples testprogs fate
 
-include $(SRC_PATH)/doc/Makefile
 include $(SRC_PATH)/tests/Makefile
 
 $(sort $(OBJDIRS)):
diff --git a/RELEASE b/RELEASE
index 5f3c440..ae33bab 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-9.10
+10_alpha1
diff --git a/VERSION b/VERSION
index 5f3c440..ae33bab 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-9.10
+10_alpha1
diff --git a/avconv.c b/avconv.c
index 6544fc6..17dc468 100644
--- a/avconv.c
+++ b/avconv.c
@@ -27,6 +27,8 @@
 #include <errno.h>
 #include <signal.h>
 #include <limits.h>
+#include <stdint.h>
+
 #include "libavformat/avformat.h"
 #include "libavdevice/avdevice.h"
 #include "libswscale/swscale.h"
@@ -35,7 +37,6 @@
 #include "libavutil/channel_layout.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/samplefmt.h"
-#include "libavutil/colorspace.h"
 #include "libavutil/fifo.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
@@ -48,7 +49,6 @@
 #include "libavformat/os_support.h"
 
 # include "libavfilter/avfilter.h"
-# include "libavfilter/avfiltergraph.h"
 # include "libavfilter/buffersrc.h"
 # include "libavfilter/buffersink.h"
 
@@ -144,7 +144,7 @@ static int decode_interrupt_cb(void *ctx)
 
 const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
 
-static void exit_program(void)
+static void avconv_cleanup(int ret)
 {
     int i, j;
 
@@ -160,6 +160,7 @@ static void exit_program(void)
             av_freep(&filtergraphs[i]->outputs[j]);
         }
         av_freep(&filtergraphs[i]->outputs);
+        av_freep(&filtergraphs[i]->graph_desc);
         av_freep(&filtergraphs[i]);
     }
     av_freep(&filtergraphs);
@@ -167,7 +168,7 @@ static void exit_program(void)
     /* close files */
     for (i = 0; i < nb_output_files; i++) {
         AVFormatContext *s = output_files[i]->ctx;
-        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+        if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE) && s->pb)
             avio_close(s->pb);
         avformat_free_context(s);
         av_dict_free(&output_files[i]->opts);
@@ -181,7 +182,9 @@ static void exit_program(void)
             bsfc = next;
         }
         output_streams[i]->bitstream_filters = NULL;
-        avcodec_free_frame(&output_streams[i]->filtered_frame);
+        av_frame_free(&output_streams[i]->filtered_frame);
+
+        av_parser_close(output_streams[i]->parser);
 
         av_freep(&output_streams[i]->forced_keyframes);
         av_freep(&output_streams[i]->avfilter);
@@ -193,10 +196,11 @@ static void exit_program(void)
         av_freep(&input_files[i]);
     }
     for (i = 0; i < nb_input_streams; i++) {
-        avcodec_free_frame(&input_streams[i]->decoded_frame);
+        av_frame_free(&input_streams[i]->decoded_frame);
+        av_frame_free(&input_streams[i]->filter_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]->hwaccel_device);
         av_freep(&input_streams[i]);
     }
 
@@ -211,7 +215,6 @@ static void exit_program(void)
 
     uninit_opts();
 
-    avfilter_uninit();
     avformat_network_deinit();
 
     if (received_sigterm) {
@@ -226,7 +229,7 @@ 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);
+        exit_program(1);
     }
 }
 
@@ -241,7 +244,7 @@ static void abort_codec_experimental(AVCodec *c, int encoder)
     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);
+    exit_program(1);
 }
 
 /*
@@ -332,25 +335,47 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
                                            pkt->flags & AV_PKT_FLAG_KEY);
         if (a > 0) {
             av_free_packet(pkt);
-            new_pkt.destruct = av_destruct_packet;
+            new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
+                                           av_buffer_default_free, NULL, 0);
+            if (!new_pkt.buf)
+                exit_program(1);
         } 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);
+                exit_program(1);
         }
         *pkt = new_pkt;
 
         bsfc = bsfc->next;
     }
 
+    if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
+        ost->last_mux_dts != AV_NOPTS_VALUE &&
+        pkt->dts < ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT)) {
+        av_log(NULL, AV_LOG_WARNING, "Non-monotonous DTS in output stream "
+               "%d:%d; previous: %"PRId64", current: %"PRId64"; ",
+               ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
+        if (exit_on_error) {
+            av_log(NULL, AV_LOG_FATAL, "aborting.\n");
+            exit_program(1);
+        }
+        av_log(NULL, AV_LOG_WARNING, "changing to %"PRId64". This may result "
+               "in incorrect timestamps in the output file.\n",
+               ost->last_mux_dts + 1);
+        pkt->dts = ost->last_mux_dts + 1;
+        if (pkt->pts != AV_NOPTS_VALUE)
+            pkt->pts = FFMAX(pkt->pts, pkt->dts);
+    }
+    ost->last_mux_dts = pkt->dts;
+
     pkt->stream_index = ost->index;
     ret = av_interleaved_write_frame(s, pkt);
     if (ret < 0) {
         print_error("av_interleaved_write_frame()", ret);
-        exit(1);
+        exit_program(1);
     }
 }
 
@@ -378,16 +403,13 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost,
     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);
+        exit_program(1);
     }
 
     if (got_packet) {
@@ -404,45 +426,6 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost,
     }
 }
 
-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,
@@ -458,7 +441,7 @@ static void do_subtitle_out(AVFormatContext *s,
     if (pts == AV_NOPTS_VALUE) {
         av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
         if (exit_on_error)
-            exit(1);
+            exit_program(1);
         return;
     }
 
@@ -490,7 +473,7 @@ static void do_subtitle_out(AVFormatContext *s,
                                                     subtitle_out_max_size, sub);
         if (subtitle_out_size < 0) {
             av_log(NULL, AV_LOG_FATAL, "Subtitle encoding failed\n");
-            exit(1);
+            exit_program(1);
         }
 
         av_init_packet(&pkt);
@@ -545,8 +528,7 @@ static void do_video_out(AVFormatContext *s,
     pkt.data = NULL;
     pkt.size = 0;
 
-    if (!check_recording_time(ost) ||
-        ost->frame_number >= ost->max_frames)
+    if (ost->frame_number >= ost->max_frames)
         return;
 
     if (s->oformat->flags & AVFMT_RAWPICTURE &&
@@ -564,31 +546,23 @@ static void do_video_out(AVFormatContext *s,
         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 (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) &&
+            ost->top_field_first >= 0)
+            in_picture->top_field_first = !!ost->top_field_first;
+
+        in_picture->quality = ost->st->codec->global_quality;
         if (!enc->me_threshold)
-            big_picture.pict_type = 0;
+            in_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;
+            in_picture->pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
+            in_picture->pict_type = AV_PICTURE_TYPE_I;
             ost->forced_kf_index++;
         }
-        ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);
+        ret = avcodec_encode_video2(enc, &pkt, in_picture, &got_packet);
         if (ret < 0) {
             av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
-            exit(1);
+            exit_program(1);
         }
 
         if (got_packet) {
@@ -632,7 +606,7 @@ static void do_video_stats(OutputStream *ost, int frame_size)
         vstats_file = fopen(vstats_filename, "w");
         if (!vstats_file) {
             perror("fopen");
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -663,45 +637,38 @@ static void do_video_stats(OutputStream *ost, int frame_size)
 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())) {
+    if (!ost->filtered_frame && !(ost->filtered_frame = av_frame_alloc())) {
         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,
+        ret = av_buffersink_get_samples(ost->filter->filter, filtered_frame,
                                          ost->st->codec->frame_size);
     else
-        ret = av_buffersink_read(ost->filter->filter, &picref);
+        ret = av_buffersink_get_frame(ost->filter->filter, filtered_frame);
 
     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,
+    if (filtered_frame->pts != AV_NOPTS_VALUE) {
+        int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
+        filtered_frame->pts = av_rescale_q(filtered_frame->pts,
                                            ost->filter->filter->inputs[0]->time_base,
                                            ost->st->codec->time_base) -
-                              av_rescale_q(of->start_time,
+                              av_rescale_q(start_time,
                                            AV_TIME_BASE_Q,
                                            ost->st->codec->time_base);
-
-        if (of->start_time && filtered_frame->pts < 0) {
-            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;
+            ost->st->codec->sample_aspect_ratio = filtered_frame->sample_aspect_ratio;
 
         do_video_out(of->ctx, ost, filtered_frame, &frame_size);
         if (vstats_filename && frame_size)
@@ -715,7 +682,7 @@ static int poll_filter(OutputStream *ost)
         av_assert0(0);
     }
 
-    avfilter_unref_buffer(picref);
+    av_frame_unref(filtered_frame);
 
     return 0;
 }
@@ -950,7 +917,7 @@ static void flush_encoders(void)
                 ret = encode(enc, &pkt, NULL, &got_packet);
                 if (ret < 0) {
                     av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc);
-                    exit(1);
+                    exit_program(1);
                 }
                 *size += ret;
                 if (ost->logfile && enc->stats_out) {
@@ -986,7 +953,7 @@ static int check_output_constraints(InputStream *ist, OutputStream *ost)
     if (ost->source_index != ist_index)
         return 0;
 
-    if (of->start_time && ist->last_dts < of->start_time)
+    if (of->start_time != AV_NOPTS_VALUE && ist->last_dts < of->start_time)
         return 0;
 
     return 1;
@@ -995,7 +962,9 @@ static int check_output_constraints(InputStream *ist, OutputStream *ost)
 static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt)
 {
     OutputFile *of = output_files[ost->file_index];
-    int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
+    InputFile   *f = input_files [ist->file_index];
+    int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time;
+    int64_t ost_tb_start_time = av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base);
     AVPacket opkt;
 
     av_init_packet(&opkt);
@@ -1005,11 +974,21 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
         return;
 
     if (of->recording_time != INT64_MAX &&
-        ist->last_dts >= of->recording_time + of->start_time) {
+        ist->last_dts >= of->recording_time + start_time) {
         ost->finished = 1;
         return;
     }
 
+    if (f->recording_time != INT64_MAX) {
+        start_time = f->ctx->start_time;
+        if (f->start_time != AV_NOPTS_VALUE)
+            start_time += f->start_time;
+        if (ist->last_dts >= f->recording_time + start_time) {
+            ost->finished = 1;
+            return;
+        }
+    }
+
     /* force the input stream PTS */
     if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
         audio_size += pkt->size;
@@ -1038,8 +1017,14 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
        && 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;
+        if (av_parser_change(ost->parser, ost->st->codec,
+                             &opkt.data, &opkt.size,
+                             pkt->data, pkt->size,
+                             pkt->flags & AV_PKT_FLAG_KEY)) {
+            opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0);
+            if (!opkt.buf)
+                exit_program(1);
+        }
     } else {
         opkt.data = pkt->data;
         opkt.size = pkt->size;
@@ -1049,16 +1034,6 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
     ost->st->codec->frame_number++;
 }
 
-static void rate_emu_sleep(InputStream *ist)
-{
-    if (input_files[ist->file_index]->rate_emu) {
-        int64_t pts = av_rescale(ist->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;
@@ -1079,11 +1054,13 @@ int guess_input_channel_layout(InputStream *ist)
 
 static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
 {
-    AVFrame *decoded_frame;
+    AVFrame *decoded_frame, *f;
     AVCodecContext *avctx = ist->st->codec;
-    int i, ret, resample_changed;
+    int i, ret, err = 0, resample_changed;
 
-    if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+    if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc()))
+        return AVERROR(ENOMEM);
+    if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc()))
         return AVERROR(ENOMEM);
     decoded_frame = ist->decoded_frame;
 
@@ -1091,7 +1068,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
     if (!*got_output || ret < 0) {
         if (!pkt->size) {
             for (i = 0; i < ist->nb_filters; i++)
-                av_buffersrc_buffer(ist->filters[i]->filter, NULL);
+                av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
         }
         return ret;
     }
@@ -1105,8 +1082,6 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
         pkt->pts           = AV_NOPTS_VALUE;
     }
 
-    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 ||
@@ -1118,7 +1093,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
             av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
                    "layout for Input Stream #%d.%d\n", ist->file_index,
                    ist->st->index);
-            exit(1);
+            exit_program(1);
         }
         decoded_frame->channel_layout = avctx->channel_layout;
 
@@ -1144,7 +1119,7 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
             if (ist_in_filtergraph(filtergraphs[i], ist) &&
                 configure_filtergraph(filtergraphs[i]) < 0) {
                 av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
-                exit(1);
+                exit_program(1);
             }
     }
 
@@ -1152,19 +1127,33 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
         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);
+    for (i = 0; i < ist->nb_filters; i++) {
+        if (i < ist->nb_filters - 1) {
+            f = ist->filter_frame;
+            err = av_frame_ref(f, decoded_frame);
+            if (err < 0)
+                break;
+        } else
+            f = decoded_frame;
 
-    return ret;
+        err = av_buffersrc_add_frame(ist->filters[i]->filter, f);
+        if (err < 0)
+            break;
+    }
+
+    av_frame_unref(ist->filter_frame);
+    av_frame_unref(decoded_frame);
+    return err < 0 ? err : 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;
+    AVFrame *decoded_frame, *f;
+    int i, ret = 0, err = 0, resample_changed;
 
-    if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+    if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc()))
+        return AVERROR(ENOMEM);
+    if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc()))
         return AVERROR(ENOMEM);
     decoded_frame = ist->decoded_frame;
 
@@ -1173,17 +1162,21 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
     if (!*got_output || ret < 0) {
         if (!pkt->size) {
             for (i = 0; i < ist->nb_filters; i++)
-                av_buffersrc_buffer(ist->filters[i]->filter, NULL);
+                av_buffersrc_add_frame(ist->filters[i]->filter, NULL);
         }
         return ret;
     }
 
+    if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) {
+        err = ist->hwaccel_retrieve_data(ist->st->codec, decoded_frame);
+        if (err < 0)
+            goto fail;
+    }
+    ist->hwaccel_retrieved_pix_fmt = decoded_frame->format;
+
     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;
@@ -1210,31 +1203,28 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
             if (ist_in_filtergraph(filtergraphs[i], ist) &&
                 configure_filtergraph(filtergraphs[i]) < 0) {
                 av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
-                exit(1);
+                exit_program(1);
             }
     }
 
     for (i = 0; i < ist->nb_filters; i++) {
-        if (ist->st->codec->codec->capabilities & CODEC_CAP_DR1 && !do_deinterlace) {
-            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);
+        if (i < ist->nb_filters - 1) {
+            f = ist->filter_frame;
+            err = av_frame_ref(f, decoded_frame);
+            if (err < 0)
+                break;
         } else
-            av_buffersrc_write_frame(ist->filters[i]->filter, decoded_frame);
+            f = decoded_frame;
+
+        err = av_buffersrc_add_frame(ist->filters[i]->filter, f);
+        if (err < 0)
+            break;
     }
 
-    av_free(buffer_to_free);
-    return ret;
+fail:
+    av_frame_unref(ist->filter_frame);
+    av_frame_unref(decoded_frame);
+    return err < 0 ? err : ret;
 }
 
 static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
@@ -1247,8 +1237,6 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
     if (!*got_output)
         return ret;
 
-    rate_emu_sleep(ist);
-
     for (i = 0; i < nb_output_streams; i++) {
         OutputStream *ost = output_streams[i];
 
@@ -1336,7 +1324,6 @@ static int output_packet(InputStream *ist, const AVPacket *pkt)
 
     /* 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:
@@ -1367,12 +1354,12 @@ static int output_packet(InputStream *ist, const AVPacket *pkt)
 
 static void print_sdp(void)
 {
-    char sdp[2048];
+    char sdp[16384];
     int i;
     AVFormatContext **avc = av_malloc(sizeof(*avc) * nb_output_files);
 
     if (!avc)
-        exit(1);
+        exit_program(1);
     for (i = 0; i < nb_output_files; i++)
         avc[i] = output_files[i]->ctx;
 
@@ -1382,6 +1369,63 @@ static void print_sdp(void)
     av_freep(&avc);
 }
 
+static const HWAccel *get_hwaccel(enum AVPixelFormat pix_fmt)
+{
+    int i;
+    for (i = 0; hwaccels[i].name; i++)
+        if (hwaccels[i].pix_fmt == pix_fmt)
+            return &hwaccels[i];
+    return NULL;
+}
+
+static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts)
+{
+    InputStream *ist = s->opaque;
+    const enum AVPixelFormat *p;
+    int ret;
+
+    for (p = pix_fmts; *p != -1; p++) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
+        const HWAccel *hwaccel;
+
+        if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
+            break;
+
+        hwaccel = get_hwaccel(*p);
+        if (!hwaccel ||
+            (ist->active_hwaccel_id && ist->active_hwaccel_id != hwaccel->id) ||
+            (ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != hwaccel->id))
+            continue;
+
+        ret = hwaccel->init(s);
+        if (ret < 0) {
+            if (ist->hwaccel_id == hwaccel->id) {
+                av_log(NULL, AV_LOG_FATAL,
+                       "%s hwaccel requested for input stream #%d:%d, "
+                       "but cannot be initialized.\n", hwaccel->name,
+                       ist->file_index, ist->st->index);
+                exit_program(1);
+            }
+            continue;
+        }
+        ist->active_hwaccel_id = hwaccel->id;
+        ist->hwaccel_pix_fmt   = *p;
+        break;
+    }
+
+    return *p;
+}
+
+static int get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
+{
+    InputStream *ist = s->opaque;
+
+    if (ist->hwaccel_get_buffer && frame->format == ist->hwaccel_pix_fmt)
+        return ist->hwaccel_get_buffer(s, frame, flags);
+
+    return avcodec_default_get_buffer2(s, frame, flags);
+}
+
 static int init_input_stream(int ist_index, char *error, int error_len)
 {
     int i, ret;
@@ -1404,19 +1448,26 @@ static int init_input_stream(int ist_index, char *error, int error_len)
             }
         }
 
-        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;
-        }
+        ist->st->codec->opaque      = ist;
+        ist->st->codec->get_format  = get_format;
+        ist->st->codec->get_buffer2 = get_buffer;
+        ist->st->codec->thread_safe_callbacks = 1;
+
+        av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0);
 
         if (!av_dict_get(ist->opts, "threads", NULL, 0))
             av_dict_set(&ist->opts, "threads", "auto", 0);
         if ((ret = avcodec_open2(ist->st->codec, codec, &ist->opts)) < 0) {
+            char errbuf[128];
             if (ret == AVERROR_EXPERIMENTAL)
                 abort_codec_experimental(codec, 0);
-            snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d",
-                    ist->file_index, ist->st->index);
+
+            av_strerror(ret, errbuf, sizeof(errbuf));
+
+            snprintf(error, error_len,
+                     "Error while opening decoder for input stream "
+                     "#%d:%d : %s",
+                     ist->file_index, ist->st->index, errbuf);
             return ret;
         }
         assert_avoptions(ist->opts);
@@ -1461,7 +1512,7 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost,
     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);
+        exit_program(1);
     }
 
     p = kf;
@@ -1532,6 +1583,7 @@ static int transcode_init(void)
         }
 
         if (ost->stream_copy) {
+            AVRational sar;
             uint64_t extra_size;
 
             av_assert0(ist && !ost->filter);
@@ -1571,11 +1623,13 @@ static int transcode_init(void)
             } else
                 codec->time_base = ist->st->time_base;
 
+            ost->parser = av_parser_init(codec->codec_id);
+
             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);
+                    exit_program(1);
                 }
                 codec->channel_layout     = icodec->channel_layout;
                 codec->sample_rate        = icodec->sample_rate;
@@ -1589,13 +1643,13 @@ static int transcode_init(void)
                 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};
-                }
+                if (ost->frame_aspect_ratio)
+                    sar = av_d2q(ost->frame_aspect_ratio * codec->height / codec->width, 255);
+                else if (ist->st->sample_aspect_ratio.num)
+                    sar = ist->st->sample_aspect_ratio;
+                else
+                    sar = icodec->sample_aspect_ratio;
+                ost->st->sample_aspect_ratio = codec->sample_aspect_ratio = sar;
                 break;
             case AVMEDIA_TYPE_SUBTITLE:
                 codec->width  = icodec->width;
@@ -1655,7 +1709,7 @@ static int transcode_init(void)
                     fg = init_simple_filtergraph(ist, ost);
                     if (configure_filtergraph(fg)) {
                         av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
-                        exit(1);
+                        exit_program(1);
                     }
             }
 
@@ -1713,7 +1767,7 @@ static int transcode_init(void)
                         if (!f) {
                             av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
                                    logfilename, strerror(errno));
-                            exit(1);
+                            exit_program(1);
                         }
                         ost->logfile = f;
                     } else {
@@ -1722,7 +1776,7 @@ static int transcode_init(void)
                         if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
                             av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
                                    logfilename);
-                            exit(1);
+                            exit_program(1);
                         }
                         codec->stats_in = logbuffer;
                     }
@@ -1763,9 +1817,8 @@ static int transcode_init(void)
                 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;
+        } else {
+            av_opt_set_dict(ost->st->codec, &ost->opts);
         }
     }
 
@@ -1796,10 +1849,11 @@ static int transcode_init(void)
         oc->interrupt_callback = int_cb;
         if ((ret = avformat_write_header(oc, &output_files[i]->opts)) < 0) {
             char errbuf[128];
-            const char *errbuf_ptr = errbuf;
-            if (av_strerror(ret, errbuf, sizeof(errbuf)) < 0)
-                errbuf_ptr = strerror(AVUNERROR(ret));
-            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?): %s", i, errbuf_ptr);
+            av_strerror(ret, errbuf, sizeof(errbuf));
+            snprintf(error, sizeof(error),
+                     "Could not write header for output file #%d "
+                     "(incorrect codec parameters ?): %s",
+                     i, errbuf);
             ret = AVERROR(EINVAL);
             goto dump_format;
         }
@@ -2045,6 +2099,17 @@ static int get_input_packet_mt(InputFile *f, AVPacket *pkt)
 
 static int get_input_packet(InputFile *f, AVPacket *pkt)
 {
+    if (f->rate_emu) {
+        int i;
+        for (i = 0; i < f->nb_streams; i++) {
+            InputStream *ist = input_streams[f->ist_index + i];
+            int64_t pts = av_rescale(ist->last_dts, 1000000, AV_TIME_BASE);
+            int64_t now = av_gettime() - ist->start;
+            if (pts > now)
+                return AVERROR(EAGAIN);
+        }
+    }
+
 #if HAVE_PTHREADS
     if (nb_input_files > 1)
         return get_input_packet_mt(f, pkt);
@@ -2112,7 +2177,7 @@ static int process_input(void)
         if (ret != AVERROR_EOF) {
             print_error(is->filename, ret);
             if (exit_on_error)
-                exit(1);
+                exit_program(1);
         }
         ifile->eof_reached = 1;
 
@@ -2180,7 +2245,7 @@ static int process_input(void)
         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);
+            exit_program(1);
     }
 
 discard_packet:
@@ -2279,6 +2344,8 @@ static int transcode(void)
         ist = input_streams[i];
         if (ist->decoding_needed) {
             avcodec_close(ist->st->codec);
+            if (ist->hwaccel_uninit)
+                ist->hwaccel_uninit(ist->st->codec);
         }
     }
 
@@ -2303,6 +2370,7 @@ static int transcode(void)
                 av_freep(&ost->st->codec->subtitle_header);
                 av_free(ost->forced_kf_pts);
                 av_dict_free(&ost->opts);
+                av_dict_free(&ost->resample_opts);
             }
         }
     }
@@ -2350,7 +2418,7 @@ int main(int argc, char **argv)
     int ret;
     int64_t ti;
 
-    atexit(exit_program);
+    register_exit(avconv_cleanup);
 
     av_log_set_flags(AV_LOG_SKIP_REPEATED);
     parse_loglevel(argc, argv, options);
@@ -2368,29 +2436,29 @@ int main(int argc, char **argv)
     /* parse options and open all input/output files */
     ret = avconv_parse_options(argc, argv);
     if (ret < 0)
-        exit(1);
+        exit_program(1);
 
     if (nb_output_files <= 0 && nb_input_files == 0) {
         show_usage();
         av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
-        exit(1);
+        exit_program(1);
     }
 
     /* file converter / grab */
     if (nb_output_files <= 0) {
         fprintf(stderr, "At least one output file must be specified\n");
-        exit(1);
+        exit_program(1);
     }
 
     ti = getutime();
     if (transcode() < 0)
-        exit(1);
+        exit_program(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);
+    exit_program(0);
     return 0;
 }
diff --git a/avconv.h b/avconv.h
index defdf59..c270401 100644
--- a/avconv.h
+++ b/avconv.h
@@ -36,7 +36,6 @@
 #include "libavcodec/avcodec.h"
 
 #include "libavfilter/avfilter.h"
-#include "libavfilter/avfiltergraph.h"
 
 #include "libavutil/avutil.h"
 #include "libavutil/dict.h"
@@ -49,6 +48,19 @@
 #define VSYNC_CFR         1
 #define VSYNC_VFR         2
 
+enum HWAccelID {
+    HWACCEL_NONE = 0,
+    HWACCEL_AUTO,
+    HWACCEL_VDPAU,
+};
+
+typedef struct HWAccel {
+    const char *name;
+    int (*init)(AVCodecContext *s);
+    enum HWAccelID id;
+    enum AVPixelFormat pix_fmt;
+} HWAccel;
+
 /* select an input stream for an output stream */
 typedef struct StreamMap {
     int disabled;           /* 1 is this mapping is disabled by a negative map */
@@ -89,11 +101,16 @@ typedef struct OptionsContext {
     /* input options */
     int64_t input_ts_offset;
     int rate_emu;
+    int accurate_seek;
 
     SpecifierOpt *ts_scale;
     int        nb_ts_scale;
     SpecifierOpt *dump_attachment;
     int        nb_dump_attachment;
+    SpecifierOpt *hwaccels;
+    int        nb_hwaccels;
+    SpecifierOpt *hwaccel_devices;
+    int        nb_hwaccel_devices;
 
     /* output options */
     StreamMap *stream_maps;
@@ -158,6 +175,8 @@ typedef struct OptionsContext {
     int        nb_copy_initial_nonkeyframes;
     SpecifierOpt *filters;
     int        nb_filters;
+    SpecifierOpt *filter_scripts;
+    int        nb_filter_scripts;
     SpecifierOpt *pass;
     int        nb_pass;
     SpecifierOpt *passlogfiles;
@@ -200,6 +219,7 @@ typedef struct InputStream {
     int decoding_needed;     /* true if the packets must be decoded in 'raw_fifo' */
     AVCodec *dec;
     AVFrame *decoded_frame;
+    AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */
 
     int64_t       start;     /* time when read started */
     /* predicted dts of the next packet read for this stream or (when there are
@@ -223,13 +243,23 @@ typedef struct InputStream {
     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;
+
+    /* hwaccel options */
+    enum HWAccelID hwaccel_id;
+    char  *hwaccel_device;
+
+    /* hwaccel context */
+    enum HWAccelID active_hwaccel_id;
+    void  *hwaccel_ctx;
+    void (*hwaccel_uninit)(AVCodecContext *s);
+    int  (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags);
+    int  (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
+    enum AVPixelFormat hwaccel_pix_fmt;
+    enum AVPixelFormat hwaccel_retrieved_pix_fmt;
 } InputStream;
 
 typedef struct InputFile {
@@ -238,9 +268,12 @@ typedef struct InputFile {
     int eagain;           /* true if last read attempt returned EAGAIN */
     int ist_index;        /* index of first stream in ist_table */
     int64_t ts_offset;
+    int64_t start_time;   /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
+    int64_t recording_time;
     int nb_streams;       /* number of stream that avconv is aware of; may be different
                              from ctx.nb_streams if new streams appear during av_read_frame() */
     int rate_emu;
+    int accurate_seek;
 
 #if HAVE_PTHREADS
     pthread_t thread;           /* thread reading from this file */
@@ -267,6 +300,8 @@ typedef struct OutputStream {
     /* pts of the first frame encoded for this stream, used for limiting
      * recording time */
     int64_t first_pts;
+    /* dts of the last packet sent to the muxer */
+    int64_t last_mux_dts;
     AVBitStreamFilterContext *bitstream_filters;
     AVCodec *enc;
     int64_t max_frames;
@@ -293,12 +328,15 @@ typedef struct OutputStream {
 
     int64_t sws_flags;
     AVDictionary *opts;
+    AVDictionary *resample_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];
+
+    AVCodecParserContext *parser;
 } OutputStream;
 
 typedef struct OutputFile {
@@ -347,11 +385,11 @@ extern const AVIOInterruptCB int_cb;
 
 extern const OptionDef options[];
 
+extern const HWAccel hwaccels[];
+
 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);
@@ -365,4 +403,6 @@ FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
 
 int avconv_parse_options(int argc, char **argv);
 
+int vdpau_init(AVCodecContext *s);
+
 #endif /* AVCONV_H */
diff --git a/avconv_filter.c b/avconv_filter.c
index 50e1e73..892db00 100644
--- a/avconv_filter.c
+++ b/avconv_filter.c
@@ -18,26 +18,31 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "avconv.h"
 
 #include "libavfilter/avfilter.h"
-#include "libavfilter/avfiltergraph.h"
+
+#include "libavresample/avresample.h"
 
 #include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/opt.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)\
+#define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name)           \
 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) {                                     \
+    } else if (ost->enc && ost->enc->supported_list) {                         \
         const type *p;                                                         \
         AVIOContext *s = NULL;                                                 \
         uint8_t *ret;                                                          \
@@ -48,7 +53,7 @@ static char *choose_ ## var ## s(OutputStream *ost)                            \
                                                                                \
         for (p = ost->enc->supported_list; *p != none; p++) {                  \
             get_name(*p);                                                      \
-            avio_printf(s, "%s" separator, name);                              \
+            avio_printf(s, "%s|", name);                                       \
         }                                                                      \
         len = avio_close_dyn_buf(s, &ret);                                     \
         ret[len - 1] = 0;                                                      \
@@ -58,16 +63,16 @@ static char *choose_ ## var ## s(OutputStream *ost)                            \
 }
 
 DEF_CHOOSE_FORMAT(enum AVPixelFormat, pix_fmt, pix_fmts, AV_PIX_FMT_NONE,
-                  GET_PIX_FMT_NAME, ":")
+                  GET_PIX_FMT_NAME)
 
 DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts,
-                  AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME, ",")
+                  AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME)
 
 DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0,
-                  GET_SAMPLE_RATE_NAME, ",")
+                  GET_SAMPLE_RATE_NAME)
 
 DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0,
-                  GET_CH_LAYOUT_NAME, ",")
+                  GET_CH_LAYOUT_NAME)
 
 FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost)
 {
@@ -149,7 +154,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
         }
         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,
+                   "unlabeled input pad %d on filter %s\n", in->pad_idx,
                    in->filter_ctx->name);
             exit(1);
         }
@@ -170,10 +175,62 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
     ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
 }
 
+static int insert_trim(int64_t start_time, int64_t duration,
+                       AVFilterContext **last_filter, int *pad_idx,
+                       const char *filter_name)
+{
+    AVFilterGraph *graph = (*last_filter)->graph;
+    AVFilterContext *ctx;
+    const AVFilter *trim;
+    enum AVMediaType type = avfilter_pad_get_type((*last_filter)->output_pads, *pad_idx);
+    const char *name = (type == AVMEDIA_TYPE_VIDEO) ? "trim" : "atrim";
+    int ret = 0;
+
+    if (duration == INT64_MAX && start_time == AV_NOPTS_VALUE)
+        return 0;
+
+    trim = avfilter_get_by_name(name);
+    if (!trim) {
+        av_log(NULL, AV_LOG_ERROR, "%s filter not present, cannot limit "
+               "recording time.\n", name);
+        return AVERROR_FILTER_NOT_FOUND;
+    }
+
+    ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);
+    if (!ctx)
+        return AVERROR(ENOMEM);
+
+    if (duration != INT64_MAX) {
+        ret = av_opt_set_double(ctx, "duration", (double)duration / 1e6,
+                                AV_OPT_SEARCH_CHILDREN);
+    }
+    if (ret >= 0 && start_time != AV_NOPTS_VALUE) {
+        ret = av_opt_set_double(ctx, "start", (double)start_time / 1e6,
+                                AV_OPT_SEARCH_CHILDREN);
+    }
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);
+        return ret;
+    }
+
+    ret = avfilter_init_str(ctx, NULL);
+    if (ret < 0)
+        return ret;
+
+    ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);
+    if (ret < 0)
+        return ret;
+
+    *last_filter = ctx;
+    *pad_idx     = 0;
+    return 0;
+}
+
 static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
 {
     char *pix_fmts;
     OutputStream *ost = ofilter->ost;
+    OutputFile    *of = output_files[ost->file_index];
     AVCodecContext *codec = ost->st->codec;
     AVFilterContext *last_filter = out->filter_ctx;
     int pad_idx = out->pad_idx;
@@ -191,7 +248,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
         char args[255];
         AVFilterContext *filter;
 
-        snprintf(args, sizeof(args), "%d:%d:flags=0x%X",
+        snprintf(args, sizeof(args), "%d:%d:0x%X",
                  codec->width,
                  codec->height,
                  (unsigned)ost->sws_flags);
@@ -244,6 +301,14 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
         pad_idx = 0;
     }
 
+    snprintf(name, sizeof(name), "trim for output stream %d:%d",
+             ost->file_index, ost->index);
+    ret = insert_trim(of->start_time, of->recording_time,
+                      &last_filter, &pad_idx, name);
+    if (ret < 0)
+        return ret;
+
+
     if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
         return ret;
 
@@ -253,6 +318,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
 static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
 {
     OutputStream *ost = ofilter->ost;
+    OutputFile    *of = output_files[ost->file_index];
     AVCodecContext *codec  = ost->st->codec;
     AVFilterContext *last_filter = out->filter_ctx;
     int pad_idx = out->pad_idx;
@@ -310,6 +376,13 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
         pad_idx = 0;
     }
 
+    snprintf(name, sizeof(name), "trim for output stream %d:%d",
+             ost->file_index, ost->index);
+    ret = insert_trim(of->start_time, of->recording_time,
+                      &last_filter, &pad_idx, name);
+    if (ret < 0)
+        return ret;
+
     if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
         return ret;
 
@@ -320,7 +393,7 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
 {                                                                  \
     AVFilterContext *ctx = inout->filter_ctx;                      \
     AVFilterPad *pads = in ? ctx->input_pads  : ctx->output_pads;  \
-    int       nb_pads = in ? ctx->input_count : ctx->output_count; \
+    int       nb_pads = in ? ctx->nb_inputs   : ctx->nb_outputs;   \
     AVIOContext *pb;                                               \
                                                                    \
     if (avio_open_dyn_buf(&pb) < 0)                                \
@@ -348,28 +421,30 @@ int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOu
 static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
                                         AVFilterInOut *in)
 {
-    AVFilterContext *first_filter = in->filter_ctx;
-    AVFilter *filter = avfilter_get_by_name("buffer");
+    AVFilterContext *last_filter;
+    const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
     InputStream *ist = ifilter->ist;
+    InputFile     *f = input_files[ist->file_index];
     AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
                                          ist->st->time_base;
     AVRational sar;
     char args[255], name[255];
-    int pad_idx = in->pad_idx;
-    int ret;
+    int ret, pad_idx = 0;
 
     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,
+             ist->st->codec->height,
+             ist->hwaccel_retrieve_data ? ist->hwaccel_retrieved_pix_fmt : 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,
+    if ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,
                                             args, NULL, fg->graph)) < 0)
         return ret;
+    last_filter = ifilter->filter;
 
     if (ist->framerate.num) {
         AVFilterContext *setpts;
@@ -382,14 +457,20 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
                                                 fg->graph)) < 0)
             return ret;
 
-        if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0)
+        if ((ret = avfilter_link(last_filter, 0, setpts, 0)) < 0)
             return ret;
 
-        first_filter = setpts;
-        pad_idx = 0;
+        last_filter = setpts;
     }
 
-    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
+    snprintf(name, sizeof(name), "trim for input stream %d:%d",
+             ist->file_index, ist->st->index);
+    ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
+                      AV_NOPTS_VALUE : 0, f->recording_time, &last_filter, &pad_idx, name);
+    if (ret < 0)
+        return ret;
+
+    if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
         return ret;
     return 0;
 }
@@ -397,12 +478,12 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
 static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
                                         AVFilterInOut *in)
 {
-    AVFilterContext *first_filter = in->filter_ctx;
-    AVFilter *filter = avfilter_get_by_name("abuffer");
+    AVFilterContext *last_filter;
+    const AVFilter *abuffer_filt = avfilter_get_by_name("abuffer");
     InputStream *ist = ifilter->ist;
-    int pad_idx = in->pad_idx;
+    InputFile     *f = input_files[ist->file_index];
     char args[255], name[255];
-    int ret;
+    int ret, pad_idx = 0;
 
     snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s"
              ":channel_layout=0x%"PRIx64,
@@ -413,10 +494,11 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
     snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,
              ist->file_index, ist->st->index);
 
-    if ((ret = avfilter_graph_create_filter(&ifilter->filter, filter,
+    if ((ret = avfilter_graph_create_filter(&ifilter->filter, abuffer_filt,
                                             name, args, NULL,
                                             fg->graph)) < 0)
         return ret;
+    last_filter = ifilter->filter;
 
     if (audio_sync_method > 0) {
         AVFilterContext *async;
@@ -439,12 +521,11 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
         if (ret < 0)
             return ret;
 
-        ret = avfilter_link(async, 0, first_filter, pad_idx);
+        ret = avfilter_link(last_filter, 0, async, 0);
         if (ret < 0)
             return ret;
 
-        first_filter = async;
-        pad_idx = 0;
+        last_filter = async;
     }
     if (audio_volume != 256) {
         AVFilterContext *volume;
@@ -462,14 +543,21 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
         if (ret < 0)
             return ret;
 
-        ret = avfilter_link(volume, 0, first_filter, pad_idx);
+        ret = avfilter_link(last_filter, 0, volume, 0);
         if (ret < 0)
             return ret;
 
-        first_filter = volume;
-        pad_idx = 0;
+        last_filter = volume;
     }
-    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
+
+    snprintf(name, sizeof(name), "trim for input stream %d:%d",
+             ist->file_index, ist->st->index);
+    ret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?
+                      AV_NOPTS_VALUE : 0, f->recording_time, &last_filter, &pad_idx, name);
+    if (ret < 0)
+        return ret;
+
+    if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)
         return ret;
 
     return 0;
@@ -501,9 +589,20 @@ int configure_filtergraph(FilterGraph *fg)
 
     if (simple) {
         OutputStream *ost = fg->outputs[0]->ost;
-        char args[255];
+        char args[512];
+        AVDictionaryEntry *e = NULL;
+
         snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
         fg->graph->scale_sws_opts = av_strdup(args);
+
+        args[0] = '\0';
+        while ((e = av_dict_get(fg->outputs[0]->ost->resample_opts, "", e,
+                                AV_DICT_IGNORE_SUFFIX))) {
+            av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
+        }
+        if (strlen(args))
+            args[strlen(args) - 1] = '\0';
+        fg->graph->resample_lavr_opts = av_strdup(args);
     }
 
     if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
diff --git a/avconv_opt.c b/avconv_opt.c
index e67abef..d62d11f 100644
--- a/avconv_opt.c
+++ b/avconv_opt.c
@@ -28,7 +28,6 @@
 #include "libavcodec/avcodec.h"
 
 #include "libavfilter/avfilter.h"
-#include "libavfilter/avfiltergraph.h"
 
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
@@ -50,10 +49,17 @@
         if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
             outvar = o->name[i].u.type;\
         else if (ret < 0)\
-            exit(1);\
+            exit_program(1);\
     }\
 }
 
+const HWAccel hwaccels[] = {
+#if HAVE_VDPAU_X11
+    { "vdpau", vdpau_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU },
+#endif
+    { 0 },
+};
+
 char *vstats_filename;
 
 float audio_drift_threshold = 0.1;
@@ -62,7 +68,6 @@ 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;
@@ -73,6 +78,7 @@ int print_stats       = 1;
 int qp_hist           = 0;
 
 static int file_overwrite     = 0;
+static int file_skip          = 0;
 static int video_discard      = 0;
 static int intra_dc_precision = 8;
 static int using_stdin        = 0;
@@ -114,9 +120,29 @@ static void init_options(OptionsContext *o)
     memset(o, 0, sizeof(*o));
 
     o->mux_max_delay  = 0.7;
+    o->start_time     = AV_NOPTS_VALUE;
     o->recording_time = INT64_MAX;
     o->limit_filesize = UINT64_MAX;
     o->chapters_input_file = INT_MAX;
+    o->accurate_seek  = 1;
+}
+
+/* return a copy of the input with the stream specifiers removed from the keys */
+static AVDictionary *strip_specifiers(AVDictionary *dict)
+{
+    AVDictionaryEntry *e = NULL;
+    AVDictionary    *ret = NULL;
+
+    while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
+        char *p = strchr(e->key, ':');
+
+        if (p)
+            *p = 0;
+        av_dict_set(&ret, e->key, e->value, 0);
+        if (p)
+            *p = ':';
+    }
+    return ret;
 }
 
 static double parse_frame_aspect_ratio(const char *arg)
@@ -138,7 +164,7 @@ static double parse_frame_aspect_ratio(const char *arg)
 
     if (!ar) {
         av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n");
-        exit(1);
+        exit_program(1);
     }
     return ar;
 }
@@ -188,7 +214,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
         sync_file_idx = strtol(sync + 1, &sync, 0);
         if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
             av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
-            exit(1);
+            exit_program(1);
         }
         if (*sync)
             sync++;
@@ -201,7 +227,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
         if (i == input_files[sync_file_idx]->nb_streams) {
             av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
                                        "match any streams.\n", arg);
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -214,13 +240,13 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
         m->linklabel = av_get_token(&c, "]");
         if (!m->linklabel) {
             av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
-            exit(1);
+            exit_program(1);
         }
     } else {
         file_idx = strtol(map, &p, 0);
         if (file_idx >= nb_input_files || file_idx < 0) {
             av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
-            exit(1);
+            exit_program(1);
         }
         if (negative)
             /* disable some already defined maps */
@@ -255,7 +281,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
 
     if (!m) {
         av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
-        exit(1);
+        exit_program(1);
     }
 
     av_freep(&map);
@@ -287,7 +313,7 @@ static void parse_meta_type(char *arg, char *type, int *index, const char **stre
         case 's':
             if (*(++arg) && *arg != ':') {
                 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
-                exit(1);
+                exit_program(1);
             }
             *stream_spec = *arg == ':' ? arg + 1 : "";
             break;
@@ -298,7 +324,7 @@ static void parse_meta_type(char *arg, char *type, int *index, const char **stre
             break;
         default:
             av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
-            exit(1);
+            exit_program(1);
         }
     } else
         *type = 'g';
@@ -331,7 +357,7 @@ static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFor
     if ((index) < 0 || (index) >= (nb_elems)) {\
         av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
                 (desc), (index));\
-        exit(1);\
+        exit_program(1);\
     }
 
 #define SET_DICT(type, meta, context, index)\
@@ -362,11 +388,11 @@ static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFor
                 meta_in = &ic->streams[i]->metadata;
                 break;
             } else if (ret < 0)
-                exit(1);
+                exit_program(1);
         }
         if (!meta_in) {
             av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match  any streams.\n", istream_spec);
-            exit(1);
+            exit_program(1);
         }
     }
 
@@ -376,7 +402,7 @@ static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFor
                 meta_out = &oc->streams[i]->metadata;
                 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
             } else if (ret < 0)
-                exit(1);
+                exit_program(1);
         }
     } else
         av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
@@ -404,11 +430,11 @@ static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int e
 
     if (!codec) {
         av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
-        exit(1);
+        exit_program(1);
     }
     if (codec->type != type) {
         av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
-        exit(1);
+        exit_program(1);
     }
     return codec;
 }
@@ -436,10 +462,10 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
         AVStream *st = ic->streams[i];
         AVCodecContext *dec = st->codec;
         InputStream *ist = av_mallocz(sizeof(*ist));
-        char *framerate = NULL;
+        char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
 
         if (!ist)
-            exit(1);
+            exit_program(1);
 
         GROW_ARRAY(input_streams, nb_input_streams);
         input_streams[nb_input_streams - 1] = ist;
@@ -466,9 +492,44 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
                                                  framerate) < 0) {
                 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
                        framerate);
-                exit(1);
+                exit_program(1);
             }
 
+            MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
+            if (hwaccel) {
+                if (!strcmp(hwaccel, "none"))
+                    ist->hwaccel_id = HWACCEL_NONE;
+                else if (!strcmp(hwaccel, "auto"))
+                    ist->hwaccel_id = HWACCEL_AUTO;
+                else {
+                    int i;
+                    for (i = 0; hwaccels[i].name; i++) {
+                        if (!strcmp(hwaccels[i].name, hwaccel)) {
+                            ist->hwaccel_id = hwaccels[i].id;
+                            break;
+                        }
+                    }
+
+                    if (!ist->hwaccel_id) {
+                        av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
+                               hwaccel);
+                        av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
+                        for (i = 0; hwaccels[i].name; i++)
+                            av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
+                        av_log(NULL, AV_LOG_FATAL, "\n");
+                        exit_program(1);
+                    }
+                }
+            }
+
+            MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
+            if (hwaccel_device) {
+                ist->hwaccel_device = av_strdup(hwaccel_device);
+                if (!ist->hwaccel_device)
+                    exit_program(1);
+            }
+            ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
+
             break;
         case AVMEDIA_TYPE_AUDIO:
             guess_input_channel_layout(ist);
@@ -492,21 +553,26 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
 
 static void assert_file_overwrite(const char *filename)
 {
+    if (file_overwrite && file_skip) {
+        fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
+        exit_program(1);
+    }
+
     if (!file_overwrite &&
         (strchr(filename, ':') == NULL || filename[1] == ':' ||
          av_strstart(filename, "file:", NULL))) {
         if (avio_check(filename, 0) == 0) {
-            if (!using_stdin) {
+            if (!using_stdin && !file_skip) {
                 fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
                 fflush(stderr);
                 if (!read_yesno()) {
                     fprintf(stderr, "Not overwriting - exiting\n");
-                    exit(1);
+                    exit_program(1);
                 }
             }
             else {
                 fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
-                exit(1);
+                exit_program(1);
             }
         }
     }
@@ -528,7 +594,7 @@ static void dump_attachment(AVStream *st, const char *filename)
     if (!*filename) {
         av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
                "in stream #%d:%d.\n", nb_input_files - 1, st->index);
-        exit(1);
+        exit_program(1);
     }
 
     assert_file_overwrite(filename);
@@ -536,7 +602,7 @@ static void dump_attachment(AVStream *st, const char *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);
+        exit_program(1);
     }
 
     avio_write(out, st->codec->extradata, st->codec->extradata_size);
@@ -546,18 +612,21 @@ static void dump_attachment(AVStream *st, const char *filename)
 
 static int open_input_file(OptionsContext *o, const char *filename)
 {
+    InputFile *f;
     AVFormatContext *ic;
     AVInputFormat *file_iformat = NULL;
     int err, i, ret;
     int64_t timestamp;
     uint8_t buf[128];
     AVDictionary **opts;
+    AVDictionary *unused_opts = NULL;
+    AVDictionaryEntry *e = NULL;
     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);
+            exit_program(1);
         }
     }
 
@@ -571,7 +640,7 @@ static int open_input_file(OptionsContext *o, const char *filename)
     ic = avformat_alloc_context();
     if (!ic) {
         print_error(filename, AVERROR(ENOMEM));
-        exit(1);
+        exit_program(1);
     }
     if (o->nb_audio_sample_rate) {
         snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
@@ -612,7 +681,7 @@ static int open_input_file(OptionsContext *o, const char *filename)
     err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
     if (err < 0) {
         print_error(filename, err);
-        exit(1);
+        exit_program(1);
     }
     assert_avoptions(o->g->format_opts);
 
@@ -630,16 +699,16 @@ static int open_input_file(OptionsContext *o, const char *filename)
     if (ret < 0) {
         av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
         avformat_close_input(&ic);
-        exit(1);
+        exit_program(1);
     }
 
-    timestamp = o->start_time;
+    timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
     /* add the stream start time */
     if (ic->start_time != AV_NOPTS_VALUE)
         timestamp += ic->start_time;
 
     /* if seeking requested, we execute it */
-    if (o->start_time != 0) {
+    if (o->start_time != AV_NOPTS_VALUE) {
         ret = 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",
@@ -654,14 +723,52 @@ static int open_input_file(OptionsContext *o, const char *filename)
     av_dump_format(ic, nb_input_files, filename, 0);
 
     GROW_ARRAY(input_files, nb_input_files);
-    if (!(input_files[nb_input_files - 1] = av_mallocz(sizeof(*input_files[0]))))
-        exit(1);
+    f = av_mallocz(sizeof(*f));
+    if (!f)
+        exit_program(1);
+    input_files[nb_input_files - 1] = f;
+
+    f->ctx        = ic;
+    f->ist_index  = nb_input_streams - ic->nb_streams;
+    f->start_time = o->start_time;
+    f->recording_time = o->recording_time;
+    f->ts_offset  = o->input_ts_offset - (copy_ts ? 0 : timestamp);
+    f->nb_streams = ic->nb_streams;
+    f->rate_emu   = o->rate_emu;
+    f->accurate_seek = o->accurate_seek;
+
+    /* check if all codec options have been used */
+    unused_opts = strip_specifiers(o->g->codec_opts);
+    for (i = f->ist_index; i < nb_input_streams; i++) {
+        e = NULL;
+        while ((e = av_dict_get(input_streams[i]->opts, "", e,
+                                AV_DICT_IGNORE_SUFFIX)))
+            av_dict_set(&unused_opts, e->key, NULL, 0);
+    }
+
+    e = NULL;
+    while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
+        const AVClass *class = avcodec_get_class();
+        const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
+                                             AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
+        if (!option)
+            continue;
+        if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
+            av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
+                   "input file #%d (%s) is not a decoding option.\n", e->key,
+                   option->help ? option->help : "", nb_input_files - 1,
+                   filename);
+            exit_program(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;
+        av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
+               "input file #%d (%s) has not been used for any stream. The most "
+               "likely reason is either wrong type (e.g. a video option with "
+               "no video streams) or that it is a private option of some decoder "
+               "which was not actually used for any stream.\n", e->key,
+               option->help ? option->help : "", nb_input_files - 1, filename);
+    }
+    av_dict_free(&unused_opts);
 
     for (i = 0; i < o->nb_dump_attachment; i++) {
         int j;
@@ -689,7 +796,7 @@ static uint8_t *get_line(AVIOContext *s)
 
     if (avio_open_dyn_buf(&line) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
-        exit(1);
+        exit_program(1);
     }
 
     while ((c = avio_r8(s)) && c != '\n')
@@ -754,7 +861,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
 
     if (!st) {
         av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
-        exit(1);
+        exit_program(1);
     }
 
     if (oc->nb_streams - 1 < o->nb_streamid_map)
@@ -762,10 +869,10 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
 
     GROW_ARRAY(output_streams, nb_output_streams);
     if (!(ost = av_mallocz(sizeof(*ost))))
-        exit(1);
+        exit_program(1);
     output_streams[nb_output_streams - 1] = ost;
 
-    ost->file_index = nb_output_files;
+    ost->file_index = nb_output_files - 1;
     ost->index      = idx;
     ost->st         = st;
     st->codec->codec_type = type;
@@ -786,7 +893,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
                 }
                 if (!(arg = strchr(buf, '='))) {
                     av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
-                    exit(1);
+                    exit_program(1);
                 }
                 *arg++ = 0;
                 av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
@@ -798,8 +905,10 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
             av_log(NULL, AV_LOG_FATAL,
                    "Preset %s specified for stream %d:%d, but could not be opened.\n",
                    preset, ost->file_index, ost->index);
-            exit(1);
+            exit_program(1);
         }
+    } else {
+        ost->opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
     }
 
     avcodec_get_context_defaults3(st->codec, ost->enc);
@@ -814,7 +923,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
             *next++ = 0;
         if (!(bsfc = av_bitstream_filter_init(bsf))) {
             av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
-            exit(1);
+            exit_program(1);
         }
         if (bsfc_prev)
             bsfc_prev->next = bsfc;
@@ -844,7 +953,10 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
 
     av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
 
+    av_dict_copy(&ost->resample_opts, o->g->resample_opts, 0);
+
     ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;
+    ost->last_mux_dts = AV_NOPTS_VALUE;
 
     return ost;
 }
@@ -860,51 +972,104 @@ static void parse_matrix_coeffs(uint16_t *dest, const char *str)
         p = strchr(p, ',');
         if (!p) {
             av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
-            exit(1);
+            exit_program(1);
         }
         p++;
     }
 }
 
+/* read file contents into a string */
+static uint8_t *read_file(const char *filename)
+{
+    AVIOContext *pb      = NULL;
+    AVIOContext *dyn_buf = NULL;
+    int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
+    uint8_t buf[1024], *str;
+
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
+        return NULL;
+    }
+
+    ret = avio_open_dyn_buf(&dyn_buf);
+    if (ret < 0) {
+        avio_closep(&pb);
+        return NULL;
+    }
+    while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
+        avio_write(dyn_buf, buf, ret);
+    avio_w8(dyn_buf, 0);
+    avio_closep(&pb);
+
+    ret = avio_close_dyn_buf(dyn_buf, &str);
+    if (ret < 0)
+        return NULL;
+    return str;
+}
+
+static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
+                             OutputStream *ost)
+{
+    AVStream *st = ost->st;
+    char *filter = NULL, *filter_script = NULL;
+
+    MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
+    MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
+
+    if (filter_script && filter) {
+        av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
+               "output stream #%d:%d.\n", nb_output_files, st->index);
+        exit_program(1);
+    }
+
+    if (filter_script)
+        return read_file(filter_script);
+    else if (filter)
+        return av_strdup(filter);
+
+    return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
+                     "null" : "anull");
+}
+
 static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
 {
     AVStream *st;
     OutputStream *ost;
     AVCodecContext *video_enc;
+    char *frame_aspect_ratio = NULL;
 
     ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
     st  = ost->st;
     video_enc = st->codec;
 
+    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);
+
     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 *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);
+            exit_program(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);
+            exit_program(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);
+            exit_program(1);
         }
         st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
 
@@ -912,7 +1077,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
         if (intra_matrix) {
             if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
                 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
-                exit(1);
+                exit_program(1);
             }
             parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
         }
@@ -920,7 +1085,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
         if (inter_matrix) {
             if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
                 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
-                exit(1);
+                exit_program(1);
             }
             parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
         }
@@ -931,7 +1096,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
             int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
             if (e != 3) {
                 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
-                exit(1);
+                exit_program(1);
             }
             video_enc->rc_override =
                 av_realloc(video_enc->rc_override,
@@ -965,7 +1130,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
         MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
         if (ost->logfile_prefix &&
             !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
-            exit(1);
+            exit_program(1);
 
         MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
         if (ost->forced_keyframes)
@@ -976,8 +1141,10 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
         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);
+
+        ost->avfilter = get_ost_filters(o, oc, ost);
+        if (!ost->avfilter)
+            exit_program(1);
     } else {
         MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
     }
@@ -999,7 +1166,6 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
 
     if (!ost->stream_copy) {
         char *sample_fmt = NULL;
-        const char *filters = "anull";
 
         MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
 
@@ -1007,13 +1173,14 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
         if (sample_fmt &&
             (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
             av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
-            exit(1);
+            exit_program(1);
         }
 
         MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
 
-        MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
-        ost->avfilter = av_strdup(filters);
+        ost->avfilter = get_ost_filters(o, oc, ost);
+        if (!ost->avfilter)
+            exit_program(1);
     }
 
     return ost;
@@ -1026,7 +1193,7 @@ static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
     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);
+        exit_program(1);
     }
 
     return ost;
@@ -1036,6 +1203,7 @@ static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *o
 {
     OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
     ost->stream_copy = 1;
+    ost->finished    = 1;
     return ost;
 }
 
@@ -1068,7 +1236,7 @@ static int opt_streamid(void *optctx, const char *opt, const char *arg)
         av_log(NULL, AV_LOG_FATAL,
                "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
                arg, opt);
-        exit(1);
+        exit_program(1);
     }
     *p++ = '\0';
     idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
@@ -1091,7 +1259,8 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
 
     for (i = 0; i < is->nb_chapters; i++) {
         AVChapter *in_ch = is->chapters[i], *out_ch;
-        int64_t ts_off   = av_rescale_q(ofile->start_time - ifile->ts_offset,
+        int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
+        int64_t ts_off   = av_rescale_q(start_time - ifile->ts_offset,
                                        AV_TIME_BASE_Q, in_ch->time_base);
         int64_t rt       = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
                            av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
@@ -1131,7 +1300,7 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
     default:
         av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
                "currently.\n");
-        exit(1);
+        exit_program(1);
     }
 
     ost->source_index = -1;
@@ -1143,12 +1312,12 @@ static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
         av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
                "which is fed from a complex filtergraph. Filtering and streamcopy "
                "cannot be used together.\n", ost->file_index, ost->index);
-        exit(1);
+        exit_program(1);
     }
 
     if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
-        exit(1);
+        exit_program(1);
     }
     avfilter_inout_free(&ofilter->out_tmp);
 }
@@ -1169,35 +1338,54 @@ static int open_output_file(OptionsContext *o, const char *filename)
     AVFormatContext *oc;
     int i, j, err;
     AVOutputFormat *file_oformat;
+    OutputFile *of;
     OutputStream *ost;
     InputStream  *ist;
+    AVDictionary *unused_opts = NULL;
+    AVDictionaryEntry *e = NULL;
 
     if (configure_complex_filters() < 0) {
         av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
-        exit(1);
+        exit_program(1);
     }
 
+    GROW_ARRAY(output_files, nb_output_files);
+    of = av_mallocz(sizeof(*of));
+    if (!of)
+        exit_program(1);
+    output_files[nb_output_files - 1] = of;
+
+    of->ost_index      = nb_output_streams;
+    of->recording_time = o->recording_time;
+    of->start_time     = o->start_time;
+    of->limit_filesize = o->limit_filesize;
+    of->shortest       = o->shortest;
+    av_dict_copy(&of->opts, o->g->format_opts, 0);
+
     if (!strcmp(filename, "-"))
         filename = "pipe:";
 
     oc = avformat_alloc_context();
     if (!oc) {
         print_error(filename, AVERROR(ENOMEM));
-        exit(1);
+        exit_program(1);
     }
+    of->ctx = oc;
+    if (o->recording_time != INT64_MAX)
+        oc->duration = o->recording_time;
 
     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);
+            exit_program(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);
+            exit_program(1);
         }
     }
 
@@ -1298,7 +1486,7 @@ loop_end:
                 if (!ofilter) {
                     av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
                            "in any defined filter graph.\n", map->linklabel);
-                    exit(1);
+                    exit_program(1);
                 }
                 init_output_filter(ofilter, o, oc);
             } else {
@@ -1312,7 +1500,7 @@ loop_end:
                 default:
                     av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
                            map->file_index, map->stream_index);
-                    exit(1);
+                    exit_program(1);
                 }
 
                 ost->source_index = input_files[map->file_index]->ist_index + map->stream_index;
@@ -1334,17 +1522,17 @@ loop_end:
         if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
             av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
                    o->attachments[i]);
-            exit(1);
+            exit_program(1);
         }
         if ((len = avio_size(pb)) <= 0) {
             av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
                    o->attachments[i]);
-            exit(1);
+            exit_program(1);
         }
         if (!(attachment = av_malloc(len))) {
             av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
                    o->attachments[i]);
-            exit(1);
+            exit_program(1);
         }
         avio_read(pb, attachment, len);
 
@@ -1360,25 +1548,44 @@ loop_end:
         avio_close(pb);
     }
 
-    GROW_ARRAY(output_files, nb_output_files);
-    if (!(output_files[nb_output_files - 1] = av_mallocz(sizeof(*output_files[0]))))
-        exit(1);
+    /* check if all codec options have been used */
+    unused_opts = strip_specifiers(o->g->codec_opts);
+    for (i = of->ost_index; i < nb_output_streams; i++) {
+        e = NULL;
+        while ((e = av_dict_get(output_streams[i]->opts, "", e,
+                                AV_DICT_IGNORE_SUFFIX)))
+            av_dict_set(&unused_opts, e->key, NULL, 0);
+    }
 
-    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, o->g->format_opts, 0);
+    e = NULL;
+    while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
+        const AVClass *class = avcodec_get_class();
+        const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
+                                             AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
+        if (!option)
+            continue;
+        if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
+            av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
+                   "output file #%d (%s) is not an encoding option.\n", e->key,
+                   option->help ? option->help : "", nb_output_files - 1,
+                   filename);
+            exit_program(1);
+        }
+
+        av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
+               "output file #%d (%s) has not been used for any stream. The most "
+               "likely reason is either wrong type (e.g. a video option with "
+               "no video streams) or that it is a private option of some encoder "
+               "which was not actually used for any stream.\n", e->key,
+               option->help ? option->help : "", nb_output_files - 1, filename);
+    }
+    av_dict_free(&unused_opts);
 
     /* 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);
+            exit_program(1);
         }
     }
 
@@ -1389,16 +1596,16 @@ loop_end:
         /* open the file */
         if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
                               &oc->interrupt_callback,
-                              &output_files[nb_output_files - 1]->opts)) < 0) {
+                              &of->opts)) < 0) {
             print_error(filename, err);
-            exit(1);
+            exit_program(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);
+        av_dict_set(&of->opts, "preload", buf, 0);
     }
     oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
     oc->flags |= AVFMT_FLAG_NONBLOCK;
@@ -1410,7 +1617,7 @@ loop_end:
 
         if (in_file_index >= nb_input_files) {
             av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
-            exit(1);
+            exit_program(1);
         }
         copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
                       in_file_index >= 0 ?
@@ -1430,11 +1637,11 @@ loop_end:
         } else {
             av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
                    o->chapters_input_file);
-            exit(1);
+            exit_program(1);
         }
     }
     if (o->chapters_input_file >= 0)
-        copy_chapters(input_files[o->chapters_input_file], output_files[nb_output_files - 1],
+        copy_chapters(input_files[o->chapters_input_file], of,
                       !o->metadata_chapters_manual);
 
     /* copy global metadata by default */
@@ -1442,7 +1649,7 @@ loop_end:
         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++) {
+        for (i = of->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;
@@ -1461,7 +1668,7 @@ loop_end:
         if (!val) {
             av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
                    o->metadata[i].u.str);
-            exit(1);
+            exit_program(1);
         }
         *val++ = 0;
 
@@ -1471,7 +1678,7 @@ loop_end:
                 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
                     av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
                 } else if (ret < 0)
-                    exit(1);
+                    exit_program(1);
             }
         }
         else {
@@ -1482,13 +1689,13 @@ loop_end:
             case 'c':
                 if (index < 0 || index >= oc->nb_chapters) {
                     av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
-                    exit(1);
+                    exit_program(1);
                 }
                 m = &oc->chapters[index]->metadata;
                 break;
             default:
                 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
-                exit(1);
+                exit_program(1);
             }
             av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
         }
@@ -1542,7 +1749,7 @@ static int opt_target(void *optctx, const char *opt, const char *arg)
         av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
         av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
         av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
-        exit(1);
+        exit_program(1);
     }
 
     if (!strcmp(arg, "vcd")) {
@@ -1711,24 +1918,6 @@ static int opt_vsync(void *optctx, const char *opt, const char *arg)
     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;
@@ -1776,8 +1965,24 @@ static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
     GROW_ARRAY(filtergraphs, nb_filtergraphs);
     if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
         return AVERROR(ENOMEM);
-    filtergraphs[nb_filtergraphs - 1]->index       = nb_filtergraphs - 1;
-    filtergraphs[nb_filtergraphs - 1]->graph_desc = arg;
+    filtergraphs[nb_filtergraphs - 1]->index      = nb_filtergraphs - 1;
+    filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
+    if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
+static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
+{
+    uint8_t *graph_desc = read_file(arg);
+    if (!graph_desc)
+        return AVERROR(EINVAL);
+
+    GROW_ARRAY(filtergraphs, nb_filtergraphs);
+    if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
+        return AVERROR(ENOMEM);
+    filtergraphs[nb_filtergraphs - 1]->index      = nb_filtergraphs - 1;
+    filtergraphs[nb_filtergraphs - 1]->graph_desc = graph_desc;
     return 0;
 }
 
@@ -1842,6 +2047,7 @@ void show_help_default(const char *opt, const char *arg)
         show_help_children(avcodec_get_class(), flags);
         show_help_children(avformat_get_class(), flags);
         show_help_children(sws_get_class(), flags);
+        show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM);
     }
 }
 
@@ -1858,8 +2064,8 @@ enum OptGroup {
 };
 
 static const OptionGroupDef groups[] = {
-    [GROUP_OUTFILE] = { "output file",  NULL },
-    [GROUP_INFILE]  = { "input file",   "i"  },
+    [GROUP_OUTFILE] = { "output file",  NULL, OPT_OUTPUT },
+    [GROUP_INFILE]  = { "input file",   "i",  OPT_INPUT },
 };
 
 static int open_files(OptionGroupList *l, const char *inout,
@@ -1889,7 +2095,7 @@ static int open_files(OptionGroupList *l, const char *inout,
                    inout, g->arg);
             return ret;
         }
-        av_log(NULL, AV_LOG_DEBUG, "Successfully openened the file.\n");
+        av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
     }
 
     return 0;
@@ -1945,38 +2151,55 @@ fail:
 const OptionDef options[] = {
     /* main options */
 #include "cmdutils_common_opts.h"
-    { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET,           { .off       = OFFSET(format) },
+    { "f",              HAS_ARG | OPT_STRING | OPT_OFFSET |
+                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(format) },
         "force format", "fmt" },
     { "y",              OPT_BOOL,                                    {              &file_overwrite },
         "overwrite output files" },
-    { "c",              HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
+    { "n",              OPT_BOOL,                                    {              &file_skip },
+        "never overwrite output files" },
+    { "c",              HAS_ARG | OPT_STRING | OPT_SPEC |
+                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
         "codec name", "codec" },
-    { "codec",          HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
+    { "codec",          HAS_ARG | OPT_STRING | OPT_SPEC |
+                        OPT_INPUT | OPT_OUTPUT,                      { .off       = OFFSET(codec_names) },
         "codec name", "codec" },
-    { "pre",            HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(presets) },
+    { "pre",            HAS_ARG | OPT_STRING | OPT_SPEC |
+                        OPT_OUTPUT,                                  { .off       = OFFSET(presets) },
         "preset name", "preset" },
-    { "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE,          { .func_arg = opt_map },
+    { "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE |
+                        OPT_OUTPUT,                                  { .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) },
+    { "map_metadata",   HAS_ARG | OPT_STRING | OPT_SPEC |
+                        OPT_OUTPUT,                                  { .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) },
+    { "map_chapters",   HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
+                        OPT_OUTPUT,                                  { .off = OFFSET(chapters_input_file) },
         "set chapters mapping", "input_file_index" },
-    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(recording_time) },
+    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET |
+                        OPT_INPUT | OPT_OUTPUT,                      { .off = OFFSET(recording_time) },
         "record or transcode \"duration\" seconds of audio/video",
         "duration" },
-    { "fs",             HAS_ARG | OPT_INT64 | OPT_OFFSET,            { .off = OFFSET(limit_filesize) },
+    { "fs",             HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
         "set the limit file size in bytes", "limit_size" },
-    { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(start_time) },
+    { "ss",             HAS_ARG | OPT_TIME | OPT_OFFSET |
+                        OPT_INPUT | OPT_OUTPUT,                      { .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) },
+    { "accurate_seek",  OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
+                        OPT_INPUT,                                   { .off = OFFSET(accurate_seek) },
+        "enable/disable accurate seeking with -ss" },
+    { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET |
+                        OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(input_ts_offset) },
         "set the input ts offset", "time_off" },
-    { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(ts_scale) },
+    { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC |
+                        OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(ts_scale) },
         "set the input ts scale", "scale" },
-    { "metadata",       HAS_ARG | OPT_STRING | OPT_SPEC,             { .off = OFFSET(metadata) },
+    { "metadata",       HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
         "add metadata", "string=string" },
-    { "dframes",        HAS_ARG | OPT_PERFILE | OPT_EXPERT,          { .func_arg = opt_data_frames },
+    { "dframes",        HAS_ARG | OPT_PERFILE | OPT_EXPERT |
+                        OPT_OUTPUT,                                  { .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" },
@@ -1986,9 +2209,10 @@ const OptionDef options[] = {
         "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) },
+    { "re",             OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
+                        OPT_INPUT,                                   { .off = OFFSET(rate_emu) },
         "read input at native frame rate", "" },
-    { "target",         HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_target },
+    { "target",         HAS_ARG | OPT_PERFILE | OPT_OUTPUT,          { .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 },
@@ -2001,131 +2225,164 @@ const OptionDef options[] = {
         "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) },
+    { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
+                        OPT_OUTPUT,                                  { .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) },
+    { "copyinkf",       OPT_BOOL | OPT_EXPERT | OPT_SPEC |
+                        OPT_OUTPUT,                                  { .off = OFFSET(copy_initial_nonkeyframes) },
         "copy initial non-keyframes" },
-    { "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC,              { .off = OFFSET(max_frames) },
+    { "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .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) },
+    { "tag",            OPT_STRING | HAS_ARG | OPT_SPEC |
+                        OPT_EXPERT | OPT_OUTPUT,                     { .off = OFFSET(codec_tags) },
         "force codec tag/fourcc", "fourcc/tag" },
-    { "q",              HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC,{ .off = OFFSET(qscale) },
+    { "q",              HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
+                        OPT_SPEC | OPT_OUTPUT,                       { .off = OFFSET(qscale) },
         "use fixed quality scale (VBR)", "q" },
-    { "qscale",         HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC,{ .off = OFFSET(qscale) },
+    { "qscale",         HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
+                        OPT_SPEC | OPT_OUTPUT,                       { .off = OFFSET(qscale) },
         "use fixed quality scale (VBR)", "q" },
-    { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC,             { .off = OFFSET(filters) },
+    { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
         "set stream filterchain", "filter_list" },
+    { "filter_script",  HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
+        "read stream filtergraph description from a file", "filename" },
     { "filter_complex", HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
         "create a complex filtergraph", "graph_description" },
+    { "filter_complex_script", HAS_ARG | OPT_EXPERT,                 { .func_arg = opt_filter_complex_script },
+        "read complex filtergraph description from a file", "filename" },
     { "stats",          OPT_BOOL,                                    { &print_stats },
         "print progress report during encoding", },
-    { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT,          { .func_arg = opt_attach },
+    { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT |
+                        OPT_OUTPUT,                                  { .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) },
+    { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
+                         OPT_EXPERT | OPT_INPUT,                     { .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 },
+    { "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .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) },
+    { "r",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
+                      OPT_INPUT | OPT_OUTPUT,                                    { .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) },
+    { "s",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
+                      OPT_INPUT | OPT_OUTPUT,                                    { .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) },
+    { "aspect",       OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
+                      OPT_OUTPUT,                                                { .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) },
+    { "pix_fmt",      OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
+                      OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(frame_pix_fmts) },
         "set pixel format", "format" },
-    { "vn",           OPT_VIDEO | OPT_BOOL  | OPT_OFFSET,                        { .off = OFFSET(video_disable) },
+    { "vn",           OPT_VIDEO | OPT_BOOL  | OPT_OFFSET | OPT_OUTPUT,           { .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) },
+    { "rc_override",  OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
+                      OPT_OUTPUT,                                                { .off = OFFSET(rc_overrides) },
         "rate control override for specific intervals", "override" },
-    { "vcodec",       OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_codec },
+    { "vcodec",       OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_INPUT |
+                      OPT_OUTPUT,                                                { .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) },
+    { "pass",         OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT,     { .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) },
+    { "passlogfile",  OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
+                      OPT_OUTPUT,                                                { .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 },
+    { "vf",           OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .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) },
+    { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
+                      OPT_OUTPUT,                                                { .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) },
+    { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC |
+                      OPT_OUTPUT,                                                { .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",          OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_INT| OPT_SPEC |
+                      OPT_OUTPUT,                                                { .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 },
+    { "vtag",         OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_PERFILE |
+                      OPT_OUTPUT,                                                { .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_fps",    OPT_VIDEO | OPT_BOOL | OPT_EXPERT  | OPT_SPEC |
+                      OPT_OUTPUT,                                                { .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 },
+    { "streamid",     OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
+                      OPT_OUTPUT,                                                { .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" },
+    { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
+                          OPT_SPEC | OPT_OUTPUT,                                 { .off = OFFSET(forced_key_frames) },
+        "force key frames at specified timestamps", "timestamps" },
+    { "hwaccel",          OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
+                          OPT_SPEC | OPT_INPUT,                                  { .off = OFFSET(hwaccels) },
+        "use HW accelerated decoding", "hwaccel name" },
+    { "hwaccel_device",   OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
+                          OPT_SPEC | OPT_INPUT,                                  { .off = OFFSET(hwaccel_devices) },
+        "select a device for HW acceleration" "devicename" },
 
     /* audio options */
-    { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_frames },
+    { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .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 },
+    { "aq",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .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) },
+    { "ar",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC |
+                        OPT_INPUT | OPT_OUTPUT,                                    { .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) },
+    { "ac",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC |
+                        OPT_INPUT | OPT_OUTPUT,                                    { .off = OFFSET(audio_channels) },
         "set number of audio channels", "channels" },
-    { "an",             OPT_AUDIO | OPT_BOOL | OPT_OFFSET,                         { .off = OFFSET(audio_disable) },
+    { "an",             OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT,            { .off = OFFSET(audio_disable) },
         "disable audio" },
-    { "acodec",         OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_codec },
+    { "acodec",         OPT_AUDIO | HAS_ARG  | OPT_PERFILE |
+                        OPT_INPUT | OPT_OUTPUT,                                    { .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 },
+    { "atag",           OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
+                        OPT_OUTPUT,                                                { .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) },
+    { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC |
+                        OPT_STRING | OPT_INPUT | OPT_OUTPUT,                       { .off = OFFSET(sample_fmts) },
         "set sample format", "format" },
-    { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE,           { .func_arg = opt_channel_layout },
+    { "channel_layout", OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE |
+                        OPT_INPUT | OPT_OUTPUT,                                    { .func_arg = opt_channel_layout },
         "set channel layout", "layout" },
-    { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_filters },
+    { "af",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_audio_filters },
         "audio filters", "filter list" },
 
     /* subtitle options */
-    { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET, { .off = OFFSET(subtitle_disable) },
+    { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
         "disable subtitle" },
-    { "scodec", OPT_SUBTITLE | HAS_ARG  | OPT_PERFILE, { .func_arg = opt_subtitle_codec },
+    { "scodec", OPT_SUBTITLE | HAS_ARG  | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .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 }
+    { "stag",   OPT_SUBTITLE | HAS_ARG  | OPT_EXPERT  | OPT_PERFILE | OPT_OUTPUT, { .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) },
+    { "muxdelay",   OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .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) },
+    { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
         "set the initial demux-decode delay", "seconds" },
 
-    { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT, { .off = OFFSET(bitstream_filters) },
+    { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .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 },
+    { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
         "force data codec ('copy' to copy stream)", "codec" },
 
     { NULL, },
diff --git a/avconv_vdpau.c b/avconv_vdpau.c
new file mode 100644
index 0000000..820678e
--- /dev/null
+++ b/avconv_vdpau.c
@@ -0,0 +1,335 @@
+/*
+ * 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 <vdpau/vdpau.h>
+#include <vdpau/vdpau_x11.h>
+
+#include <X11/Xlib.h>
+
+#include "avconv.h"
+
+#include "libavcodec/vdpau.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/buffer.h"
+#include "libavutil/frame.h"
+#include "libavutil/pixfmt.h"
+
+typedef struct VDPAUContext {
+    Display *dpy;
+
+    VdpDevice  device;
+    VdpDecoder decoder;
+    VdpGetProcAddress *get_proc_address;
+
+    VdpGetErrorString                               *get_error_string;
+    VdpGetInformationString                         *get_information_string;
+    VdpDeviceDestroy                                *device_destroy;
+    VdpDecoderCreate                                *decoder_create;
+    VdpDecoderDestroy                               *decoder_destroy;
+    VdpDecoderRender                                *decoder_render;
+    VdpVideoSurfaceCreate                           *video_surface_create;
+    VdpVideoSurfaceDestroy                          *video_surface_destroy;
+    VdpVideoSurfaceGetBitsYCbCr                     *video_surface_get_bits;
+    VdpVideoSurfaceGetParameters                    *video_surface_get_parameters;
+    VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *video_surface_query;
+
+    AVFrame *tmp_frame;
+
+    enum AVPixelFormat pix_fmt;
+    VdpYCbCrFormat vdpau_format;
+} VDPAUContext;
+
+static void vdpau_uninit(AVCodecContext *s)
+{
+    InputStream  *ist = s->opaque;
+    VDPAUContext *ctx = ist->hwaccel_ctx;
+
+    ist->hwaccel_uninit        = NULL;
+    ist->hwaccel_get_buffer    = NULL;
+    ist->hwaccel_retrieve_data = NULL;
+
+    if (ctx->decoder_destroy)
+        ctx->decoder_destroy(ctx->decoder);
+
+    if (ctx->device_destroy)
+        ctx->device_destroy(ctx->device);
+
+    if (ctx->dpy)
+        XCloseDisplay(ctx->dpy);
+
+    av_frame_free(&ctx->tmp_frame);
+
+    av_freep(&ist->hwaccel_ctx);
+    av_freep(&s->hwaccel_context);
+}
+
+static void vdpau_release_buffer(void *opaque, uint8_t *data)
+{
+    VdpVideoSurface surface = *(VdpVideoSurface*)data;
+    VDPAUContext *ctx = opaque;
+
+    ctx->video_surface_destroy(surface);
+    av_freep(&data);
+}
+
+static int vdpau_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
+{
+    InputStream         *ist = s->opaque;
+    VDPAUContext        *ctx = ist->hwaccel_ctx;
+    VdpVideoSurface *surface;
+    VdpStatus err;
+
+    av_assert0(frame->format == AV_PIX_FMT_VDPAU);
+
+    surface = av_malloc(sizeof(*surface));
+    if (!surface)
+        return AVERROR(ENOMEM);
+
+    frame->buf[0] = av_buffer_create((uint8_t*)surface, sizeof(*surface),
+                                     vdpau_release_buffer, ctx,
+                                     AV_BUFFER_FLAG_READONLY);
+    if (!frame->buf[0]) {
+        av_freep(&surface);
+        return AVERROR(ENOMEM);
+    }
+
+    // properly we should keep a pool of surfaces instead of creating
+    // them anew for each frame, but since we don't care about speed
+    // much in this code, we don't bother
+    err = ctx->video_surface_create(ctx->device, VDP_CHROMA_TYPE_420,
+                                    frame->width, frame->height, surface);
+    if (err != VDP_STATUS_OK) {
+        av_log(NULL, AV_LOG_ERROR, "Error allocating a VDPAU video surface: %s\n",
+               ctx->get_error_string(err));
+        av_buffer_unref(&frame->buf[0]);
+        return AVERROR_UNKNOWN;
+    }
+
+    frame->data[3] = (uint8_t*)(uintptr_t)*surface;
+
+    return 0;
+}
+
+static int vdpau_retrieve_data(AVCodecContext *s, AVFrame *frame)
+{
+    VdpVideoSurface surface = (VdpVideoSurface)(uintptr_t)frame->data[3];
+    InputStream        *ist = s->opaque;
+    VDPAUContext       *ctx = ist->hwaccel_ctx;
+    VdpStatus err;
+    int ret, chroma_type;
+
+    err = ctx->video_surface_get_parameters(surface, &chroma_type,
+                                            &ctx->tmp_frame->width,
+                                            &ctx->tmp_frame->height);
+    if (err != VDP_STATUS_OK) {
+        av_log(NULL, AV_LOG_ERROR, "Error getting surface parameters: %s\n",
+               ctx->get_error_string(err));
+        return AVERROR_UNKNOWN;
+    }
+    ctx->tmp_frame->format = ctx->pix_fmt;
+
+    ret = av_frame_get_buffer(ctx->tmp_frame, 32);
+    if (ret < 0)
+        return ret;
+
+    ctx->tmp_frame->width  = frame->width;
+    ctx->tmp_frame->height = frame->height;
+
+    err = ctx->video_surface_get_bits(surface, ctx->vdpau_format,
+                                      (void * const *)ctx->tmp_frame->data,
+                                      ctx->tmp_frame->linesize);
+    if (err != VDP_STATUS_OK) {
+        av_log(NULL, AV_LOG_ERROR, "Error retrieving frame data from VDPAU: %s\n",
+               ctx->get_error_string(err));
+        ret = AVERROR_UNKNOWN;
+        goto fail;
+    }
+
+    if (ctx->vdpau_format == VDP_YCBCR_FORMAT_YV12)
+        FFSWAP(uint8_t*, ctx->tmp_frame->data[1], ctx->tmp_frame->data[2]);
+
+    ret = av_frame_copy_props(ctx->tmp_frame, frame);
+    if (ret < 0)
+        goto fail;
+
+    av_frame_unref(frame);
+    av_frame_move_ref(frame, ctx->tmp_frame);
+    return 0;
+
+fail:
+    av_frame_unref(ctx->tmp_frame);
+    return ret;
+}
+
+static const int vdpau_formats[][2] = {
+    { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV420P },
+    { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV12 },
+    { VDP_YCBCR_FORMAT_YUYV, AV_PIX_FMT_YUYV422 },
+    { VDP_YCBCR_FORMAT_UYVY, AV_PIX_FMT_UYVY422 },
+};
+
+static int vdpau_alloc(AVCodecContext *s)
+{
+    InputStream  *ist = s->opaque;
+    int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
+    AVVDPAUContext *vdpau_ctx;
+    VDPAUContext *ctx;
+    const char *display, *vendor;
+    VdpStatus err;
+    int i;
+
+    ctx = av_mallocz(sizeof(*ctx));
+    if (!ctx)
+        return AVERROR(ENOMEM);
+
+    ist->hwaccel_ctx           = ctx;
+    ist->hwaccel_uninit        = vdpau_uninit;
+    ist->hwaccel_get_buffer    = vdpau_get_buffer;
+    ist->hwaccel_retrieve_data = vdpau_retrieve_data;
+
+    ctx->tmp_frame = av_frame_alloc();
+    if (!ctx->tmp_frame)
+        goto fail;
+
+    ctx->dpy = XOpenDisplay(ist->hwaccel_device);
+    if (!ctx->dpy) {
+        av_log(NULL, loglevel, "Cannot open the X11 display %s.\n",
+               XDisplayName(ist->hwaccel_device));
+        goto fail;
+    }
+    display = XDisplayString(ctx->dpy);
+
+    err = vdp_device_create_x11(ctx->dpy, XDefaultScreen(ctx->dpy), &ctx->device,
+                                &ctx->get_proc_address);
+    if (err != VDP_STATUS_OK) {
+        av_log(NULL, loglevel, "VDPAU device creation on X11 display %s failed.\n",
+               display);
+        goto fail;
+    }
+
+#define GET_CALLBACK(id, result)                                                \
+do {                                                                            \
+    void *tmp;                                                                  \
+    err = ctx->get_proc_address(ctx->device, id, &tmp);                         \
+    if (err != VDP_STATUS_OK) {                                                 \
+        av_log(NULL, loglevel, "Error getting the " #id " callback.\n");        \
+        goto fail;                                                              \
+    }                                                                           \
+    ctx->result = tmp;                                                          \
+} while (0)
+
+    GET_CALLBACK(VDP_FUNC_ID_GET_ERROR_STRING,               get_error_string);
+    GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING,         get_information_string);
+    GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY,                 device_destroy);
+    GET_CALLBACK(VDP_FUNC_ID_DECODER_CREATE,                 decoder_create);
+    GET_CALLBACK(VDP_FUNC_ID_DECODER_DESTROY,                decoder_destroy);
+    GET_CALLBACK(VDP_FUNC_ID_DECODER_RENDER,                 decoder_render);
+    GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE,           video_surface_create);
+    GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY,          video_surface_destroy);
+    GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, video_surface_get_bits);
+    GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS,   video_surface_get_parameters);
+    GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
+                 video_surface_query);
+
+    for (i = 0; i < FF_ARRAY_ELEMS(vdpau_formats); i++) {
+        VdpBool supported;
+        err = ctx->video_surface_query(ctx->device, VDP_CHROMA_TYPE_420,
+                                       vdpau_formats[i][0], &supported);
+        if (err != VDP_STATUS_OK) {
+            av_log(NULL, loglevel,
+                   "Error querying VDPAU surface capabilities: %s\n",
+                   ctx->get_error_string(err));
+            goto fail;
+        }
+        if (supported)
+            break;
+    }
+    if (i == FF_ARRAY_ELEMS(vdpau_formats)) {
+        av_log(NULL, loglevel,
+               "No supported VDPAU format for retrieving the data.\n");
+        return AVERROR(EINVAL);
+    }
+    ctx->vdpau_format = vdpau_formats[i][0];
+    ctx->pix_fmt      = vdpau_formats[i][1];
+
+    vdpau_ctx = av_vdpau_alloc_context();
+    if (!vdpau_ctx)
+        goto fail;
+    vdpau_ctx->render = ctx->decoder_render;
+
+    s->hwaccel_context = vdpau_ctx;
+
+    ctx->get_information_string(&vendor);
+    av_log(NULL, AV_LOG_VERBOSE, "Using VDPAU -- %s -- on X11 display %s, "
+           "to decode input stream #%d:%d.\n", vendor,
+           display, ist->file_index, ist->st->index);
+
+    return 0;
+
+fail:
+    av_log(NULL, loglevel, "VDPAU init failed for stream #%d:%d.\n",
+           ist->file_index, ist->st->index);
+    vdpau_uninit(s);
+    return AVERROR(EINVAL);
+}
+
+int vdpau_init(AVCodecContext *s)
+{
+    InputStream *ist = s->opaque;
+    int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
+    AVVDPAUContext *vdpau_ctx;
+    VDPAUContext *ctx;
+    VdpStatus err;
+    int profile, ret;
+
+    if (!ist->hwaccel_ctx) {
+        ret = vdpau_alloc(s);
+        if (ret < 0)
+            return ret;
+    }
+    ctx       = ist->hwaccel_ctx;
+    vdpau_ctx = s->hwaccel_context;
+
+    ret = av_vdpau_get_profile(s, &profile);
+    if (ret < 0) {
+        av_log(NULL, loglevel, "No known VDPAU decoder profile for this stream.\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (ctx->decoder)
+        ctx->decoder_destroy(ctx->decoder);
+
+    err = ctx->decoder_create(ctx->device, profile,
+                              s->coded_width, s->coded_height,
+                              16, &ctx->decoder);
+    if (err != VDP_STATUS_OK) {
+        av_log(NULL, loglevel, "Error creating the VDPAU decoder: %s\n",
+               ctx->get_error_string(err));
+        return AVERROR_UNKNOWN;
+    }
+
+    vdpau_ctx->decoder = ctx->decoder;
+
+    ist->hwaccel_get_buffer    = vdpau_get_buffer;
+    ist->hwaccel_retrieve_data = vdpau_retrieve_data;
+
+    return 0;
+}
diff --git a/avplay.c b/avplay.c
index 3e2110f..432db97 100644
--- a/avplay.c
+++ b/avplay.c
@@ -23,6 +23,8 @@
 #include <inttypes.h>
 #include <math.h>
 #include <limits.h>
+#include <stdint.h>
+
 #include "libavutil/avstring.h"
 #include "libavutil/colorspace.h"
 #include "libavutil/mathematics.h"
@@ -41,7 +43,6 @@
 
 #if CONFIG_AVFILTER
 # include "libavfilter/avfilter.h"
-# include "libavfilter/avfiltergraph.h"
 # include "libavfilter/buffersink.h"
 # include "libavfilter/buffersrc.h"
 #endif
@@ -108,9 +109,7 @@ typedef struct VideoPicture {
     int reallocate;
     enum AVPixelFormat pix_fmt;
 
-#if CONFIG_AVFILTER
-    AVFilterBufferRef *picref;
-#endif
+    AVRational sar;
 } VideoPicture;
 
 typedef struct SubPicture {
@@ -217,8 +216,6 @@ typedef struct VideoState {
 #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;
@@ -247,8 +244,6 @@ 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;
@@ -656,10 +651,10 @@ static void video_image_display(VideoState *is)
     vp = &is->pictq[is->pictq_rindex];
     if (vp->bmp) {
 #if CONFIG_AVFILTER
-         if (vp->picref->video->pixel_aspect.num == 0)
+         if (!vp->sar.num)
              aspect_ratio = 0;
          else
-             aspect_ratio = av_q2d(vp->picref->video->pixel_aspect);
+             aspect_ratio = av_q2d(vp->sar);
 #else
 
         /* XXX: use variable in the frame */
@@ -853,7 +848,8 @@ static void video_audio_display(VideoState *s)
                 }
                 av_rdft_calc(s->rdft, data[ch]);
             }
-            // least efficient way to do this, we should of course directly access it but its more than fast enough
+            /* Least efficient way to do this, we should of course
+             * directly access it but it is more than fast enough. */
             for (y = 0; y < s->height; y++) {
                 double w = 1 / sqrt(nb_freq);
                 int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
@@ -1229,9 +1225,6 @@ static void stream_close(VideoState *is)
     /* 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;
@@ -1255,9 +1248,6 @@ static void do_exit(void)
         cur_stream = NULL;
     }
     uninit_opts();
-#if CONFIG_AVFILTER
-    avfilter_uninit();
-#endif
     avformat_network_deinit();
     if (show_status)
         printf("\n");
@@ -1279,8 +1269,6 @@ static void alloc_picture(void *opaque)
         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;
@@ -1369,10 +1357,6 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t
     /* 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);
@@ -1432,6 +1416,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t
 static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
 {
     double frame_delay, pts;
+    int ret;
 
     pts = pts1;
 
@@ -1448,7 +1433,9 @@ static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int6
     frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
     is->video_clock += frame_delay;
 
-    return queue_picture(is, src_frame, pts, pos);
+    ret = queue_picture(is, src_frame, pts, pos);
+    av_frame_unref(src_frame);
+    return ret;
 }
 
 static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
@@ -1495,13 +1482,16 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke
         if (*pts == AV_NOPTS_VALUE) {
             *pts = 0;
         }
+        if (is->video_st->sample_aspect_ratio.num) {
+            frame->sample_aspect_ratio = is->video_st->sample_aspect_ratio;
+        }
 
         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;
         }
-
+        av_frame_unref(frame);
     }
     return 0;
 }
@@ -1569,13 +1559,6 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
     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;
 }
 
@@ -1585,7 +1568,7 @@ static int video_thread(void *arg)
 {
     AVPacket pkt = { 0 };
     VideoState *is = arg;
-    AVFrame *frame = avcodec_alloc_frame();
+    AVFrame *frame = av_frame_alloc();
     int64_t pts_int;
     double pts;
     int ret;
@@ -1593,7 +1576,6 @@ static int video_thread(void *arg)
 #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;
 
@@ -1605,7 +1587,6 @@ static int video_thread(void *arg)
 
     for (;;) {
 #if CONFIG_AVFILTER
-        AVFilterBufferRef *picref;
         AVRational tb;
 #endif
         while (is->paused && !is->videoq.abort_request)
@@ -1636,38 +1617,19 @@ static int video_thread(void *arg)
         }
 
         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);
+        ret = av_buffersrc_add_frame(filt_in, frame);
+        if (ret < 0)
+            goto the_end;
 
         while (ret >= 0) {
-            ret = av_buffersink_read(filt_out, &picref);
+            ret = av_buffersink_get_frame(filt_out, frame);
             if (ret < 0) {
                 ret = 0;
                 break;
             }
 
-            avfilter_copy_buf_props(frame, picref);
-
-            pts_int = picref->pts;
+            pts_int = frame->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);
@@ -1677,7 +1639,7 @@ static int video_thread(void *arg)
                         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);
+            ret = output_picture2(is, frame, pts, 0);
         }
 #else
         pts = pts_int * av_q2d(is->video_st->time_base);
@@ -1687,6 +1649,7 @@ static int video_thread(void *arg)
         if (ret < 0)
             goto the_end;
 
+
         if (step)
             if (cur_stream)
                 stream_pause(cur_stream);
@@ -1697,7 +1660,7 @@ static int video_thread(void *arg)
     avfilter_graph_free(&graph);
 #endif
     av_free_packet(&pkt);
-    avcodec_free_frame(&frame);
+    av_frame_free(&frame);
     return 0;
 }
 
@@ -1881,10 +1844,9 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
             int resample_changed, audio_resample;
 
             if (!is->frame) {
-                if (!(is->frame = avcodec_alloc_frame()))
+                if (!(is->frame = av_frame_alloc()))
                     return AVERROR(ENOMEM);
-            } else
-                avcodec_get_frame_defaults(is->frame);
+            }
 
             if (flush_complete)
                 break;
@@ -2074,8 +2036,6 @@ static int stream_component_open(VideoState *is, int stream_index)
     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;
@@ -2087,6 +2047,8 @@ static int stream_component_open(VideoState *is, int stream_index)
 
     if (!av_dict_get(opts, "threads", NULL, 0))
         av_dict_set(&opts, "threads", "auto", 0);
+    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO)
+        av_dict_set(&opts, "refcounted_frames", "1", 0);
     if (!codec ||
         avcodec_open2(avctx, codec, &opts) < 0)
         return -1;
@@ -2189,7 +2151,7 @@ static void stream_component_close(VideoState *is, int stream_index)
             avresample_free(&is->avr);
         av_freep(&is->audio_buf1);
         is->audio_buf = NULL;
-        avcodec_free_frame(&is->frame);
+        av_frame_free(&is->frame);
 
         if (is->rdft) {
             av_rdft_end(is->rdft);
@@ -2232,9 +2194,6 @@ static void stream_component_close(VideoState *is, int stream_index)
 
     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;
@@ -2852,19 +2811,6 @@ static int opt_duration(void *optctx, const char *opt, const char *arg)
     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" },
@@ -2883,9 +2829,7 @@ static const OptionDef options[] = {
     { "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", ""},
@@ -3002,11 +2946,9 @@ int main(int argc, char **argv)
     }
 
     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);
@@ -3014,7 +2956,7 @@ int main(int argc, char **argv)
     SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
 
     av_init_packet(&flush_pkt);
-    flush_pkt.data = "FLUSH";
+    flush_pkt.data = (uint8_t *)&flush_pkt;
 
     cur_stream = stream_open(input_filename, file_iformat);
 
diff --git a/avprobe.c b/avprobe.c
index 38b74a3..c7b3d39 100644
--- a/avprobe.c
+++ b/avprobe.c
@@ -23,6 +23,7 @@
 
 #include "libavformat/avformat.h"
 #include "libavcodec/avcodec.h"
+#include "libavutil/avstring.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/dict.h"
@@ -59,7 +60,7 @@ 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)
+static void avprobe_cleanup(int ret)
 {
     av_dict_free(&fmt_entries_to_show);
 }
@@ -81,17 +82,17 @@ static void exit_program(void)
 typedef enum {
     ARRAY,
     OBJECT
-} ProbeElementType;
+} PrintElementType;
 
 typedef struct {
     const char *name;
-    ProbeElementType type;
+    PrintElementType type;
     int64_t index;
     int64_t nb_elems;
-} ProbeElement;
+} PrintElement;
 
 typedef struct {
-    ProbeElement *prefix;
+    PrintElement *prefix;
     int level;
     void (*print_header)(void);
     void (*print_footer)(void);
@@ -103,10 +104,10 @@ typedef struct {
 
     void (*print_integer) (const char *key, int64_t value);
     void (*print_string)  (const char *key, const char *value);
-} OutputContext;
+} PrintContext;
 
 static AVIOContext *probe_out = NULL;
-static OutputContext octx;
+static PrintContext octx;
 #define AVP_INDENT() avio_printf(probe_out, "%*c", octx.level * 2, ' ')
 
 /*
@@ -165,7 +166,7 @@ static void ini_print_array_header(const char *name)
 static void ini_print_object_header(const char *name)
 {
     int i;
-    ProbeElement *el = octx.prefix + octx.level -1;
+    PrintElement *el = octx.prefix + octx.level -1;
 
     if (el->nb_elems)
         avio_printf(probe_out, "\n");
@@ -302,7 +303,7 @@ static void old_print_object_header(const char *name)
 
     str = p = av_strdup(name);
     while (*p) {
-        *p = toupper(*p);
+        *p = av_toupper(*p);
         p++;
     }
 
@@ -319,7 +320,7 @@ static void old_print_object_footer(const char *name)
 
     str = p = av_strdup(name);
     while (*p) {
-        *p = toupper(*p);
+        *p = av_toupper(*p);
         p++;
     }
 
@@ -361,21 +362,21 @@ 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));
+        av_realloc(octx.prefix, sizeof(PrintElement) * (octx.level + 1));
 
     if (!octx.prefix || !name) {
         fprintf(stderr, "Out of memory\n");
-        exit(1);
+        exit_program(1);
     }
 
     if (octx.level) {
-        ProbeElement *parent = octx.prefix + octx.level -1;
+        PrintElement *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};
+    octx.prefix[octx.level++] = (PrintElement){name, type, count, 0};
 }
 
 static void probe_group_leave(void)
@@ -525,20 +526,6 @@ static char *tag_string(char *buf, int buf_size, int 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];
@@ -867,7 +854,7 @@ static void opt_input_file(void *optctx, const char *arg)
         fprintf(stderr,
                 "Argument '%s' provided as input filename, but '%s' was already specified.\n",
                 arg, input_filename);
-        exit(1);
+        exit_program(1);
     }
     if (!strcmp(arg, "-"))
         arg = "pipe:";
@@ -932,7 +919,7 @@ int main(int argc, char **argv)
     if (!buffer)
         exit(1);
 
-    atexit(exit_program);
+    register_exit(avprobe_cleanup);
 
     options = real_options;
     parse_loglevel(argc, argv, options);
@@ -962,13 +949,13 @@ int main(int argc, char **argv)
         fprintf(stderr,
                 "Use -h to get full help or, even better, run 'man %s'.\n",
                 program_name);
-        exit(1);
+        exit_program(1);
     }
 
     probe_out = avio_alloc_context(buffer, AVP_BUFFSIZE, 1, NULL, NULL,
                                  probe_buf_write, NULL);
     if (!probe_out)
-        exit(1);
+        exit_program(1);
 
     probe_header();
     ret = probe_file(input_filename);
diff --git a/avserver.c b/avserver.c
index ad7bc78..56bcda9 100644
--- a/avserver.c
+++ b/avserver.c
@@ -32,6 +32,7 @@
 #include "libavformat/network.h"
 #include "libavformat/os_support.h"
 #include "libavformat/rtpdec.h"
+#include "libavformat/rtpproto.h"
 #include "libavformat/rtsp.h"
 #include "libavformat/avio_internal.h"
 #include "libavformat/internal.h"
@@ -58,9 +59,6 @@
 #include <time.h>
 #include <sys/wait.h>
 #include <signal.h>
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
 
 #include "cmdutils.h"
 
@@ -303,7 +301,7 @@ static int rtp_new_av_stream(HTTPContext *c,
 
 static const char *my_program_name;
 
-static const char *config_filename = "/etc/avserver.conf";
+static const char *config_filename;
 
 static int avserver_debug;
 static int no_launch;
@@ -1113,7 +1111,7 @@ static int extract_rates(char *rates, int ratelen, const char *request)
         if (av_strncasecmp(p, "Pragma:", 7) == 0) {
             const char *q = p + 7;
 
-            while (*q && *q != '\n' && isspace(*q))
+            while (*q && *q != '\n' && av_isspace(*q))
                 q++;
 
             if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
@@ -1135,7 +1133,7 @@ static int extract_rates(char *rates, int ratelen, const char *request)
                     if (stream_no < ratelen && stream_no >= 0)
                         rates[stream_no] = rate_no;
 
-                    while (*q && *q != '\n' && !isspace(*q))
+                    while (*q && *q != '\n' && !av_isspace(*q))
                         q++;
                 }
 
@@ -1246,7 +1244,7 @@ static void get_word(char *buf, int buf_size, const char **pp)
     p = *pp;
     skip_spaces(&p);
     q = buf;
-    while (!isspace(*p) && *p != '\0') {
+    while (!av_isspace(*p) && *p != '\0') {
         if ((q - buf) < buf_size - 1)
             *q++ = *p;
         p++;
@@ -1263,7 +1261,7 @@ static void get_arg(char *buf, int buf_size, const char **pp)
     int quote;
 
     p = *pp;
-    while (isspace(*p)) p++;
+    while (av_isspace(*p)) p++;
     q = buf;
     quote = 0;
     if (*p == '\"' || *p == '\'')
@@ -1273,7 +1271,7 @@ static void get_arg(char *buf, int buf_size, const char **pp)
             if (*p == quote)
                 break;
         } else {
-            if (isspace(*p))
+            if (av_isspace(*p))
                 break;
         }
         if (*p == '\0')
@@ -1377,7 +1375,7 @@ static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
             break;
         line_num++;
         p = line;
-        while (isspace(*p))
+        while (av_isspace(*p))
             p++;
         if (*p == '\0' || *p == '#')
             continue;
@@ -1528,7 +1526,7 @@ static int http_parse_request(HTTPContext *c)
     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))
+            if (*useragent && *useragent != '\n' && av_isspace(*useragent))
                 useragent++;
             break;
         }
@@ -1654,7 +1652,7 @@ static int http_parse_request(HTTPContext *c)
             char *eoh;
             char hostbuf[260];
 
-            while (isspace(*hostinfo))
+            while (av_isspace(*hostinfo))
                 hostinfo++;
 
             eoh = strchr(hostinfo, '\n');
@@ -3914,32 +3912,6 @@ static enum AVCodecID opt_video_codec(const char *arg)
     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)
 {
@@ -4060,7 +4032,7 @@ static int parse_ffconfig(const char *filename)
             break;
         line_num++;
         p = line;
-        while (isspace(*p))
+        while (av_isspace(*p))
             p++;
         if (*p == '\0' || *p == '#')
             continue;
@@ -4198,7 +4170,7 @@ static int parse_ffconfig(const char *filename)
                 get_arg(arg, sizeof(arg), &p);
                 p1 = arg;
                 fsize = strtod(p1, &p1);
-                switch(toupper(*p1)) {
+                switch(av_toupper(*p1)) {
                 case 'K':
                     fsize *= 1024;
                     break;
@@ -4505,14 +4477,6 @@ static int parse_ffconfig(const char *filename)
                     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)
@@ -4604,12 +4568,7 @@ static int parse_ffconfig(const char *filename)
                 redirect = NULL;
             }
         } else if (!av_strcasecmp(cmd, "LoadModule")) {
-            get_arg(arg, sizeof(arg), &p);
-#if HAVE_DLOPEN
-            load_module(arg);
-#else
-            ERROR("Module support not compiled into this version: '%s'\n", arg);
-#endif
+            ERROR("Loadable modules no longer supported\n");
         } else {
             ERROR("Incorrect keyword: '%s'\n", cmd);
         }
@@ -4674,6 +4633,8 @@ int main(int argc, char **argv)
 {
     struct sigaction sigact = { { 0 } };
 
+    config_filename = av_strdup("/etc/avserver.conf");
+
     parse_loglevel(argc, argv, options);
     av_register_all();
     avformat_network_init();
diff --git a/cmdutils.c b/cmdutils.c
index 8fa6082..3f1c667 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -20,6 +20,7 @@
  */
 
 #include <string.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <math.h>
@@ -43,6 +44,7 @@
 #include "libavutil/eval.h"
 #include "libavutil/dict.h"
 #include "libavutil/opt.h"
+#include "libavutil/cpu.h"
 #include "cmdutils.h"
 #include "version.h"
 #if CONFIG_NETWORK
@@ -54,7 +56,7 @@
 #endif
 
 struct SwsContext *sws_opts;
-AVDictionary *format_opts, *codec_opts;
+AVDictionary *format_opts, *codec_opts, *resample_opts;
 
 static const int this_year = 2013;
 
@@ -74,6 +76,7 @@ void uninit_opts(void)
 #endif
     av_dict_free(&format_opts);
     av_dict_free(&codec_opts);
+    av_dict_free(&resample_opts);
 }
 
 void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
@@ -81,6 +84,21 @@ void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
     vfprintf(stdout, fmt, vl);
 }
 
+static void (*program_exit)(int ret);
+
+void register_exit(void (*cb)(int ret))
+{
+    program_exit = cb;
+}
+
+void exit_program(int ret)
+{
+    if (program_exit)
+        program_exit(ret);
+
+    exit(ret);
+}
+
 double parse_number_or_die(const char *context, const char *numstr, int type,
                            double min, double max)
 {
@@ -98,7 +116,7 @@ double parse_number_or_die(const char *context, const char *numstr, int type,
     else
         return d;
     av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
-    exit(1);
+    exit_program(1);
     return 0;
 }
 
@@ -109,7 +127,7 @@ int64_t parse_time_or_die(const char *context, const char *timestr,
     if (av_parse_time(&us, timestr, is_duration) < 0) {
         av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
                is_duration ? "duration" : "date", context, timestr);
-        exit(1);
+        exit_program(1);
     }
     return us;
 }
@@ -166,7 +184,10 @@ static const OptionDef *find_option(const OptionDef *po, const char *name)
     return po;
 }
 
-#if HAVE_COMMANDLINETOARGVW
+/* _WIN32 means using the windows libc - cygwin doesn't define that
+ * by default. HAVE_COMMANDLINETOARGVW is true on cygwin, while
+ * it doesn't provide the actual command line via GetCommandLineW(). */
+#if HAVE_COMMANDLINETOARGVW && defined(_WIN32)
 #include <windows.h>
 #include <shellapi.h>
 /* Will be leaked on exit */
@@ -271,7 +292,7 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt,
         }
     }
     if (po->flags & OPT_EXIT)
-        exit(0);
+        exit_program(0);
 
     return 0;
 }
@@ -331,7 +352,7 @@ void parse_options(void *optctx, int argc, char **argv, const OptionDef *options
             opt++;
 
             if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
-                exit(1);
+                exit_program(1);
             optindex += ret;
         } else {
             if (parse_arg_function)
@@ -350,6 +371,16 @@ int parse_optgroup(void *optctx, OptionGroup *g)
     for (i = 0; i < g->nb_opts; i++) {
         Option *o = &g->opts[i];
 
+        if (g->group_def->flags &&
+            !(g->group_def->flags & o->opt->flags)) {
+            av_log(NULL, AV_LOG_ERROR, "Option %s (%s) cannot be applied to "
+                   "%s %s -- you are trying to apply an input option to an "
+                   "output file or vice versa. Move this option before the "
+                   "file it belongs to.\n", o->key, o->opt->help,
+                   g->group_def->name, g->arg);
+            return AVERROR(EINVAL);
+        }
+
         av_log(NULL, AV_LOG_DEBUG, "Applying option %s (%s) with argument %s.\n",
                o->key, o->opt->help, o->val);
 
@@ -405,6 +436,9 @@ int opt_default(void *optctx, const char *opt, const char *arg)
     char opt_stripped[128];
     const char *p;
     const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class();
+#if CONFIG_AVRESAMPLE
+    const AVClass *rc = avresample_get_class();
+#endif
 #if CONFIG_SWSCALE
     const AVClass *sc = sws_get_class();
 #endif
@@ -421,6 +455,11 @@ int opt_default(void *optctx, const char *opt, const char *arg)
     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);
+#if CONFIG_AVRESAMPLE
+    else if ((o = av_opt_find(&rc, opt, NULL, 0,
+                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
+        av_dict_set(&resample_opts, opt, arg, FLAGS);
+#endif
 #if CONFIG_SWSCALE
     else if ((o = av_opt_find(&sc, opt, NULL, 0,
                               AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
@@ -480,9 +519,11 @@ static void finish_group(OptionParseContext *octx, int group_idx,
 #endif
     g->codec_opts  = codec_opts;
     g->format_opts = format_opts;
+    g->resample_opts = resample_opts;
 
     codec_opts  = NULL;
     format_opts = NULL;
+    resample_opts = NULL;
 #if CONFIG_SWSCALE
     sws_opts    = NULL;
 #endif
@@ -517,7 +558,7 @@ static void init_parse_context(OptionParseContext *octx,
     octx->nb_groups = nb_groups;
     octx->groups    = av_mallocz(sizeof(*octx->groups) * octx->nb_groups);
     if (!octx->groups)
-        exit(1);
+        exit_program(1);
 
     for (i = 0; i < octx->nb_groups; i++)
         octx->groups[i].group_def = &groups[i];
@@ -539,6 +580,7 @@ void uninit_parse_context(OptionParseContext *octx)
             av_freep(&l->groups[j].opts);
             av_dict_free(&l->groups[j].codec_opts);
             av_dict_free(&l->groups[j].format_opts);
+            av_dict_free(&l->groups[j].resample_opts);
 #if CONFIG_SWSCALE
             sws_freeContext(l->groups[j].sws_opts);
 #endif
@@ -645,7 +687,7 @@ do {                                                                           \
         return AVERROR_OPTION_NOT_FOUND;
     }
 
-    if (octx->cur_group.nb_opts || codec_opts || format_opts)
+    if (octx->cur_group.nb_opts || codec_opts || format_opts || resample_opts)
         av_log(NULL, AV_LOG_WARNING, "Trailing options were found on the "
                "commandline.\n");
 
@@ -654,6 +696,17 @@ do {                                                                           \
     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;
+}
+
 int opt_loglevel(void *optctx, const char *opt, const char *arg)
 {
     const struct { const char *name; int level; } log_levels[] = {
@@ -683,7 +736,7 @@ int opt_loglevel(void *optctx, const char *opt, const char *arg)
                "Possible levels are numbers or:\n", arg);
         for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
             av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
-        exit(1);
+        exit_program(1);
     }
     av_log_set_level(level);
     return 0;
@@ -1108,12 +1161,12 @@ int show_protocols(void *optctx, const char *opt, const char *arg)
 
 int show_filters(void *optctx, const char *opt, const char *arg)
 {
-    AVFilter av_unused(**filter) = NULL;
+    const AVFilter av_unused(*filter) = NULL;
 
     printf("Filters:\n");
 #if CONFIG_AVFILTER
-    while ((filter = av_filter_next(filter)) && *filter)
-        printf("%-16s %s\n", (*filter)->name, (*filter)->description);
+    while ((filter = avfilter_next(filter)))
+        printf("%-16s %s\n", filter->name, filter->description);
 #endif
     return 0;
 }
@@ -1139,11 +1192,11 @@ int show_pix_fmts(void *optctx, const char *opt, const char *arg)
     while ((pix_desc = av_pix_fmt_desc_next(pix_desc))) {
         enum AVPixelFormat pix_fmt = av_pix_fmt_desc_get_id(pix_desc);
         printf("%c%c%c%c%c %-16s       %d            %2d\n",
-               sws_isSupportedInput (pix_fmt)      ? 'I' : '.',
-               sws_isSupportedOutput(pix_fmt)      ? 'O' : '.',
-               pix_desc->flags & PIX_FMT_HWACCEL   ? 'H' : '.',
-               pix_desc->flags & PIX_FMT_PAL       ? 'P' : '.',
-               pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
+               sws_isSupportedInput (pix_fmt)              ? 'I' : '.',
+               sws_isSupportedOutput(pix_fmt)              ? 'O' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL   ? 'H' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_PAL       ? 'P' : '.',
+               pix_desc->flags & AV_PIX_FMT_FLAG_BITSTREAM ? 'B' : '.',
                pix_desc->name,
                pix_desc->nb_components,
                av_get_bits_per_pixel(pix_desc));
@@ -1246,6 +1299,49 @@ static void show_help_muxer(const char *name)
         show_help_children(fmt->priv_class, AV_OPT_FLAG_ENCODING_PARAM);
 }
 
+#if CONFIG_AVFILTER
+static void show_help_filter(const char *name)
+{
+    const AVFilter *f = avfilter_get_by_name(name);
+    int i, count;
+
+    if (!name) {
+        av_log(NULL, AV_LOG_ERROR, "No filter name specified.\n");
+        return;
+    } else if (!f) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown filter '%s'.\n", name);
+        return;
+    }
+
+    printf("Filter %s [%s]:\n", f->name, f->description);
+
+    if (f->flags & AVFILTER_FLAG_SLICE_THREADS)
+        printf("    slice threading supported\n");
+
+    printf("    Inputs:\n");
+    count = avfilter_pad_count(f->inputs);
+    for (i = 0; i < count; i++) {
+        printf("        %d %s (%s)\n", i, avfilter_pad_get_name(f->inputs, i),
+               media_type_string(avfilter_pad_get_type(f->inputs, i)));
+    }
+    if (f->flags & AVFILTER_FLAG_DYNAMIC_INPUTS)
+        printf("        dynamic (depending on the options)\n");
+
+    printf("    Outputs:\n");
+    count = avfilter_pad_count(f->outputs);
+    for (i = 0; i < count; i++) {
+        printf("        %d %s (%s)\n", i, avfilter_pad_get_name(f->outputs, i),
+               media_type_string(avfilter_pad_get_type(f->outputs, i)));
+    }
+    if (f->flags & AVFILTER_FLAG_DYNAMIC_OUTPUTS)
+        printf("        dynamic (depending on the options)\n");
+
+    if (f->priv_class)
+        show_help_children(f->priv_class, AV_OPT_FLAG_VIDEO_PARAM |
+                                          AV_OPT_FLAG_AUDIO_PARAM);
+}
+#endif
+
 int show_help(void *optctx, const char *opt, const char *arg)
 {
     char *topic, *par;
@@ -1266,6 +1362,10 @@ int show_help(void *optctx, const char *opt, const char *arg)
         show_help_demuxer(par);
     } else if (!strcmp(topic, "muxer")) {
         show_help_muxer(par);
+#if CONFIG_AVFILTER
+    } else if (!strcmp(topic, "filter")) {
+        show_help_filter(par);
+#endif
     } else {
         show_help_default(topic, par);
     }
@@ -1277,7 +1377,7 @@ int show_help(void *optctx, const char *opt, const char *arg)
 int read_yesno(void)
 {
     int c = getchar();
-    int yesno = (toupper(c) == 'Y');
+    int yesno = (av_toupper(c) == 'Y');
 
     while (c != '\n' && c != EOF)
         c = getchar();
@@ -1450,10 +1550,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
     if (!codec)
         codec            = s->oformat ? avcodec_find_encoder(codec_id)
                                       : avcodec_find_decoder(codec_id);
-    if (!codec)
-        return NULL;
 
-    switch (codec->type) {
+    switch (st->codec->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
         prefix  = 'v';
         flags  |= AV_OPT_FLAG_VIDEO_PARAM;
@@ -1519,13 +1617,13 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
 {
     if (new_size >= INT_MAX / elem_size) {
         av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
-        exit(1);
+        exit_program(1);
     }
     if (*size < new_size) {
         uint8_t *tmp = av_realloc(array, new_size*elem_size);
         if (!tmp) {
             av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
-            exit(1);
+            exit_program(1);
         }
         memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
         *size = new_size;
@@ -1534,134 +1632,14 @@ void *grow_array(void *array, int elem_size, int *size, int new_size)
     return array;
 }
 
-static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbuf)
-{
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt);
-    FrameBuffer *buf;
-    int i, ret;
-    int pixel_size;
-    int h_chroma_shift, v_chroma_shift;
-    int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
-    int w = s->width, h = s->height;
-
-    if (!desc)
-        return AVERROR(EINVAL);
-    pixel_size = desc->comp[0].step_minus1 + 1;
-
-    buf = av_mallocz(sizeof(*buf));
-    if (!buf)
-        return AVERROR(ENOMEM);
-
-    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);
-        return ret;
-    }
-    /* XXX this shouldn't be needed, but some tests break without this line
-     * those decoders are buggy and need to be fixed.
-     * the following tests fail:
-     * cdgraphics, ansi
-     */
-    memset(buf->base[0], 128, ret);
-
-    av_pix_fmt_get_chroma_sub_sample(s->pix_fmt,
-                                     &h_chroma_shift, &v_chroma_shift);
-
-    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)
-            buf->data[i] = buf->base[i];
-        else if (buf->base[i])
-            buf->data[i] = buf->base[i] +
-                           FFALIGN((buf->linesize[i]*edge >> v_shift) +
-                                   (pixel_size*edge >> h_shift), 32);
-    }
-    buf->w       = s->width;
-    buf->h       = s->height;
-    buf->pix_fmt = s->pix_fmt;
-    buf->pool    = pool;
-
-    *pbuf = buf;
-    return 0;
-}
-
-int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
-{
-    FrameBuffer **pool = s->opaque;
-    FrameBuffer *buf;
-    int ret, i;
-
-    if (!*pool && (ret = alloc_buffer(pool, s, pool)) < 0)
-        return ret;
-
-    buf              = *pool;
-    *pool            = buf->next;
-    buf->next        = NULL;
-    if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
-        av_freep(&buf->base[0]);
-        av_free(buf);
-        if ((ret = alloc_buffer(pool, s, &buf)) < 0)
-            return ret;
-    }
-    buf->refcount++;
-
-    frame->opaque        = buf;
-    frame->type          = FF_BUFFER_TYPE_USER;
-    frame->extended_data = frame->data;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
-        frame->base[i]     = buf->base[i];  // XXX h264.c uses base though it shouldn't
-        frame->data[i]     = buf->data[i];
-        frame->linesize[i] = buf->linesize[i];
-    }
-
-    return 0;
-}
-
-static void unref_buffer(FrameBuffer *buf)
-{
-    FrameBuffer **pool = buf->pool;
-
-    av_assert0(buf->refcount);
-    buf->refcount--;
-    if (!buf->refcount) {
-        buf->next = *pool;
-        *pool = buf;
-    }
-}
-
-void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
-{
-    FrameBuffer *buf = frame->opaque;
-    int i;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
-        frame->data[i] = NULL;
-
-    unref_buffer(buf);
-}
-
-void filter_release_buffer(AVFilterBuffer *fb)
-{
-    FrameBuffer *buf = fb->priv;
-    av_free(fb);
-    unref_buffer(buf);
-}
-
-void free_buffer_pool(FrameBuffer **pool)
+const char *media_type_string(enum AVMediaType media_type)
 {
-    FrameBuffer *buf = *pool;
-    while (buf) {
-        *pool = buf->next;
-        av_freep(&buf->base[0]);
-        av_free(buf);
-        buf = *pool;
+    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";
     }
 }
diff --git a/cmdutils.h b/cmdutils.h
index ed9c68e..f1b69f9 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -42,7 +42,17 @@ extern const int program_birth_year;
 extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
 extern AVFormatContext *avformat_opts;
 extern struct SwsContext *sws_opts;
-extern AVDictionary *format_opts, *codec_opts;
+extern AVDictionary *format_opts, *codec_opts, *resample_opts;
+
+/**
+ * Register a program-specific cleanup routine.
+ */
+void register_exit(void (*cb)(int ret));
+
+/**
+ * Wraps exit with a program-specific cleanup routine.
+ */
+void exit_program(int ret);
 
 /**
  * Initialize the cmdutils option system, in particular
@@ -62,6 +72,11 @@ void uninit_opts(void);
 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
 
 /**
+ * Override the cpuflags mask.
+ */
+int opt_cpuflags(void *optctx, const char *opt, const char *arg);
+
+/**
  * Fallback for options that are not explicitly handled, these will be
  * parsed through AVOptions.
  */
@@ -144,6 +159,8 @@ typedef struct OptionDef {
                                    an int containing element count in the array. */
 #define OPT_TIME  0x10000
 #define OPT_DOUBLE 0x20000
+#define OPT_INPUT  0x40000
+#define OPT_OUTPUT 0x80000
      union {
         void *dst_ptr;
         int (*func_arg)(void *, const char *, const char *);
@@ -224,6 +241,11 @@ typedef struct OptionGroupDef {
      * are terminated by a non-option argument (e.g. avconv output files)
      */
     const char *sep;
+    /**
+     * Option flags that must be set on each option that is
+     * applied to this group
+     */
+    int flags;
 } OptionGroupDef;
 
 typedef struct OptionGroup {
@@ -235,6 +257,7 @@ typedef struct OptionGroup {
 
     AVDictionary *codec_opts;
     AVDictionary *format_opts;
+    AVDictionary *resample_opts;
     struct SwsContext *sws_opts;
 } OptionGroup;
 
@@ -506,51 +529,13 @@ FILE *get_preset_file(char *filename, size_t filename_size,
  */
 void *grow_array(void *array, int elem_size, int *size, int new_size);
 
-#define GROW_ARRAY(array, nb_elems)\
-    array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
-
-typedef struct FrameBuffer {
-    uint8_t *base[4];
-    uint8_t *data[4];
-    int  linesize[4];
-
-    int h, w;
-    enum AVPixelFormat pix_fmt;
-
-    int refcount;
-    struct FrameBuffer **pool;  ///< head of the buffer pool
-    struct FrameBuffer *next;
-} FrameBuffer;
-
-/**
- * Get a frame from the pool. This is intended to be used as a callback for
- * AVCodecContext.get_buffer.
- *
- * @param s codec context. s->opaque must be a pointer to the head of the
- *          buffer pool.
- * @param frame frame->opaque will be set to point to the FrameBuffer
- *              containing the frame data.
- */
-int codec_get_buffer(AVCodecContext *s, AVFrame *frame);
-
 /**
- * A callback to be used for AVCodecContext.release_buffer along with
- * codec_get_buffer().
+ * Get a string describing a media type.
  */
-void codec_release_buffer(AVCodecContext *s, AVFrame *frame);
+const char *media_type_string(enum AVMediaType media_type);
 
-/**
- * A callback to be used for AVFilterBuffer.free.
- * @param fb buffer to free. fb->priv must be a pointer to the FrameBuffer
- *           containing the buffer data.
- */
-void filter_release_buffer(AVFilterBuffer *fb);
-
-/**
- * Free all the buffers in the pool. This must be called after all the
- * buffers have been released.
- */
-void free_buffer_pool(FrameBuffer **pool);
+#define GROW_ARRAY(array, nb_elems)\
+    array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
 
 #define GET_PIX_FMT_NAME(pix_fmt)\
     const char *name = av_get_pix_fmt_name(pix_fmt);
diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h
index 619cd89..8693f59 100644
--- a/cmdutils_common_opts.h
+++ b/cmdutils_common_opts.h
@@ -15,3 +15,4 @@
     { "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" },
+    { "cpuflags",    HAS_ARG | OPT_EXPERT, { .func_arg = opt_cpuflags },  "set CPU flags mask", "mask" },
diff --git a/common.mak b/common.mak
index 5d80986..6836c11 100644
--- a/common.mak
+++ b/common.mak
@@ -25,8 +25,10 @@ TOOLOBJS  := $(TOOLS:%=tools/%.o)
 TOOLS     := $(TOOLS:%=tools/%$(EXESUF))
 HEADERS   += $(HEADERS-yes)
 
-DEP_LIBS := $(foreach NAME,$(FFLIBS),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
+PATH_LIBNAME = $(foreach NAME,$(1),lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
+DEP_LIBS := $(foreach lib,$(FFLIBS),$(call PATH_LIBNAME,$(lib)))
 
+SRC_DIR    := $(SRC_PATH)/lib$(NAME)
 ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))
 SKIPHEADERS += $(ARCH_HEADERS:%=$(ARCH)/%) $(SKIPHEADERS-)
 SKIPHEADERS := $(SKIPHEADERS:%=$(SUBDIR)%)
@@ -37,19 +39,20 @@ checkheaders: $(HOBJS)
 alltools: $(TOOLS)
 
 $(HOSTOBJS): %.o: %.c
-	$(call COMPILE,HOSTCC)
+	$(COMPILE_HOSTC)
 
 $(HOSTPROGS): %$(HOSTEXESUF): %.o
-	$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $< $(HOSTLIBS)
+	$(HOSTLD) $(HOSTLDFLAGS) $(HOSTLD_O) $^ $(HOSTLIBS)
 
 $(OBJS):     | $(sort $(dir $(OBJS)))
+$(HOBJS):    | $(sort $(dir $(HOBJS)))
 $(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
 $(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
 $(TOOLOBJS): | tools
 
-OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS))
+OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOBJS) $(HOSTOBJS) $(TESTOBJS))
 
-CLEANSUFFIXES     = *.d *.o *~ *.h.c *.map *.ver
+CLEANSUFFIXES     = *.d *.o *~ *.h.c *.map *.ver *.gcno *.gcda
 DISTCLEANSUFFIXES = *.pc
 LIBSUFFIXES       = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
 
diff --git a/compat/aix/math.h b/compat/aix/math.h
new file mode 100644
index 0000000..380f878
--- /dev/null
+++ b/compat/aix/math.h
@@ -0,0 +1,31 @@
+/*
+ * Work around the class() function in AIX math.h clashing with
+ * identifiers named "class".
+ *
+ * This file is part of 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 LIBAV_COMPAT_AIX_MATH_H
+#define LIBAV_COMPAT_AIX_MATH_H
+
+#define class class_in_math_h_causes_problems
+
+#include_next <math.h>
+
+#undef class
+
+#endif /* LIBAV_COMPAT_AIX_MATH_H */
diff --git a/compat/getopt.c b/compat/getopt.c
index 3e7d3e2..7c646f6 100644
--- a/compat/getopt.c
+++ b/compat/getopt.c
@@ -38,8 +38,6 @@ static int optind = 1;
 static int optopt;
 static char *optarg;
 
-#undef fprintf
-
 static int getopt(int argc, char *argv[], char *opts)
 {
     static int sp = 1;
diff --git a/compat/strtod.c b/compat/strtod.c
index 7e979e8..258909f 100644
--- a/compat/strtod.c
+++ b/compat/strtod.c
@@ -19,7 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <ctype.h>
 #include <limits.h>
 #include <stdlib.h>
 
@@ -49,7 +48,7 @@ double avpriv_strtod(const char *nptr, char **endptr)
     double res;
 
     /* Skip leading spaces */
-    while (isspace(*nptr))
+    while (av_isspace(*nptr))
         nptr++;
 
     if (!av_strncasecmp(nptr, "infinity", 8)) {
diff --git a/compat/tms470/math.h b/compat/tms470/math.h
index 1104d74..b686d4d 100644
--- a/compat/tms470/math.h
+++ b/compat/tms470/math.h
@@ -1,3 +1,24 @@
+/*
+ * 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 LIBAV_COMPAT_TMS470_MATH_H
+#define LIBAV_COMPAT_TMS470_MATH_H
+
 #include_next <math.h>
 
 #undef INFINITY
@@ -5,3 +26,5 @@
 
 #define INFINITY (*(const float*)((const unsigned []){ 0x7f800000 }))
 #define NAN      (*(const float*)((const unsigned []){ 0x7fc00000 }))
+
+#endif /* LIBAV_COMPAT_TMS470_MATH_H */
diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h
new file mode 100644
index 0000000..be275ed
--- /dev/null
+++ b/compat/w32pthreads.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2010-2011 x264 project
+ *
+ * Authors: Steven Walters <kemuri9 at gmail.com>
+ *          Pegasys Inc. <http://www.pegasys-inc.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
+ */
+
+/**
+ * @file
+ * w32threads to pthreads wrapper
+ */
+
+#ifndef LIBAV_COMPAT_W32PTHREADS_H
+#define LIBAV_COMPAT_W32PTHREADS_H
+
+/* Build up a pthread-like API using underlying Windows API. Have only static
+ * methods so as to not conflict with a potentially linked in pthread-win32
+ * library.
+ * As most functions here are used without checking return values,
+ * only implement return values as necessary. */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <process.h>
+
+#include "libavutil/internal.h"
+#include "libavutil/mem.h"
+
+typedef struct pthread_t {
+    void *handle;
+    void *(*func)(void* arg);
+    void *arg;
+    void *ret;
+} pthread_t;
+
+/* the conditional variable api for windows 6.0+ uses critical sections and
+ * not mutexes */
+typedef CRITICAL_SECTION pthread_mutex_t;
+
+/* This is the CONDITIONAL_VARIABLE typedef for using Window's native
+ * conditional variables on kernels 6.0+.
+ * MinGW does not currently have this typedef. */
+typedef struct pthread_cond_t {
+    void *ptr;
+} pthread_cond_t;
+
+/* function pointers to conditional variable API on windows 6.0+ kernels */
+#if _WIN32_WINNT < 0x0600
+static void (WINAPI *cond_broadcast)(pthread_cond_t *cond);
+static void (WINAPI *cond_init)(pthread_cond_t *cond);
+static void (WINAPI *cond_signal)(pthread_cond_t *cond);
+static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex,
+                                DWORD milliseconds);
+#else
+#define cond_init      InitializeConditionVariable
+#define cond_broadcast WakeAllConditionVariable
+#define cond_signal    WakeConditionVariable
+#define cond_wait      SleepConditionVariableCS
+#endif
+
+static unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
+{
+    pthread_t *h = arg;
+    h->ret = h->func(h->arg);
+    return 0;
+}
+
+static int pthread_create(pthread_t *thread, const void *unused_attr,
+                          void *(*start_routine)(void*), void *arg)
+{
+    thread->func   = start_routine;
+    thread->arg    = arg;
+    thread->handle = (void*)_beginthreadex(NULL, 0, win32thread_worker, thread,
+                                           0, NULL);
+    return !thread->handle;
+}
+
+static void pthread_join(pthread_t thread, void **value_ptr)
+{
+    DWORD ret = WaitForSingleObject(thread.handle, INFINITE);
+    if (ret != WAIT_OBJECT_0)
+        return;
+    if (value_ptr)
+        *value_ptr = thread.ret;
+    CloseHandle(thread.handle);
+}
+
+static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
+{
+    InitializeCriticalSection(m);
+    return 0;
+}
+static inline int pthread_mutex_destroy(pthread_mutex_t *m)
+{
+    DeleteCriticalSection(m);
+    return 0;
+}
+static inline int pthread_mutex_lock(pthread_mutex_t *m)
+{
+    EnterCriticalSection(m);
+    return 0;
+}
+static inline int pthread_mutex_unlock(pthread_mutex_t *m)
+{
+    LeaveCriticalSection(m);
+    return 0;
+}
+
+/* for pre-Windows 6.0 platforms we need to define and use our own condition
+ * variable and api */
+typedef struct  win32_cond_t {
+    pthread_mutex_t mtx_broadcast;
+    pthread_mutex_t mtx_waiter_count;
+    volatile int waiter_count;
+    HANDLE semaphore;
+    HANDLE waiters_done;
+    volatile int is_broadcast;
+} win32_cond_t;
+
+static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
+{
+    win32_cond_t *win32_cond = NULL;
+    if (cond_init) {
+        cond_init(cond);
+        return;
+    }
+
+    /* non native condition variables */
+    win32_cond = av_mallocz(sizeof(win32_cond_t));
+    if (!win32_cond)
+        return;
+    cond->ptr = win32_cond;
+    win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
+    if (!win32_cond->semaphore)
+        return;
+    win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL);
+    if (!win32_cond->waiters_done)
+        return;
+
+    pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
+    pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
+}
+
+static void pthread_cond_destroy(pthread_cond_t *cond)
+{
+    win32_cond_t *win32_cond = cond->ptr;
+    /* native condition variables do not destroy */
+    if (cond_init)
+        return;
+
+    /* non native condition variables */
+    CloseHandle(win32_cond->semaphore);
+    CloseHandle(win32_cond->waiters_done);
+    pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
+    pthread_mutex_destroy(&win32_cond->mtx_broadcast);
+    av_freep(&win32_cond);
+    cond->ptr = NULL;
+}
+
+static void pthread_cond_broadcast(pthread_cond_t *cond)
+{
+    win32_cond_t *win32_cond = cond->ptr;
+    int have_waiter;
+
+    if (cond_broadcast) {
+        cond_broadcast(cond);
+        return;
+    }
+
+    /* non native condition variables */
+    pthread_mutex_lock(&win32_cond->mtx_broadcast);
+    pthread_mutex_lock(&win32_cond->mtx_waiter_count);
+    have_waiter = 0;
+
+    if (win32_cond->waiter_count) {
+        win32_cond->is_broadcast = 1;
+        have_waiter = 1;
+    }
+
+    if (have_waiter) {
+        ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL);
+        pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+        WaitForSingleObject(win32_cond->waiters_done, INFINITE);
+        ResetEvent(win32_cond->waiters_done);
+        win32_cond->is_broadcast = 0;
+    } else
+        pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+    pthread_mutex_unlock(&win32_cond->mtx_broadcast);
+}
+
+static int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+    win32_cond_t *win32_cond = cond->ptr;
+    int last_waiter;
+    if (cond_wait) {
+        cond_wait(cond, mutex, INFINITE);
+        return 0;
+    }
+
+    /* non native condition variables */
+    pthread_mutex_lock(&win32_cond->mtx_broadcast);
+    pthread_mutex_lock(&win32_cond->mtx_waiter_count);
+    win32_cond->waiter_count++;
+    pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+    pthread_mutex_unlock(&win32_cond->mtx_broadcast);
+
+    // unlock the external mutex
+    pthread_mutex_unlock(mutex);
+    WaitForSingleObject(win32_cond->semaphore, INFINITE);
+
+    pthread_mutex_lock(&win32_cond->mtx_waiter_count);
+    win32_cond->waiter_count--;
+    last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast;
+    pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+
+    if (last_waiter)
+        SetEvent(win32_cond->waiters_done);
+
+    // lock the external mutex
+    return pthread_mutex_lock(mutex);
+}
+
+static void pthread_cond_signal(pthread_cond_t *cond)
+{
+    win32_cond_t *win32_cond = cond->ptr;
+    int have_waiter;
+    if (cond_signal) {
+        cond_signal(cond);
+        return;
+    }
+
+    pthread_mutex_lock(&win32_cond->mtx_broadcast);
+
+    /* non-native condition variables */
+    pthread_mutex_lock(&win32_cond->mtx_waiter_count);
+    have_waiter = win32_cond->waiter_count;
+    pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+
+    if (have_waiter) {
+        ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
+        WaitForSingleObject(win32_cond->waiters_done, INFINITE);
+        ResetEvent(win32_cond->waiters_done);
+    }
+
+    pthread_mutex_unlock(&win32_cond->mtx_broadcast);
+}
+
+static void w32thread_init(void)
+{
+#if _WIN32_WINNT < 0x0600
+    HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
+    /* if one is available, then they should all be available */
+    cond_init      =
+        (void*)GetProcAddress(kernel_dll, "InitializeConditionVariable");
+    cond_broadcast =
+        (void*)GetProcAddress(kernel_dll, "WakeAllConditionVariable");
+    cond_signal    =
+        (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
+    cond_wait      =
+        (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
+#endif
+
+}
+
+#endif /* LIBAV_COMPAT_W32PTHREADS_H */
diff --git a/compat/windows/makedef b/compat/windows/makedef
new file mode 100755
index 0000000..fcaf108
--- /dev/null
+++ b/compat/windows/makedef
@@ -0,0 +1,132 @@
+#!/bin/sh
+
+# Copyright (c) 2013, Derek Buitenhuis
+#
+# 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.
+
+# mktemp isn't POSIX, so supply an implementation
+mktemp() {
+    echo "${2%%XXX*}.${HOSTNAME}.${UID}.$$"
+}
+
+if [ $# -lt 2 ]; then
+    echo "Usage: makedef <version_script> <objects>" >&2
+    exit 0
+fi
+
+vscript=$1
+shift
+
+if [ ! -f "$vscript" ]; then
+    echo "Version script does not exist" >&2
+    exit 1
+fi
+
+for object in "$@"; do
+    if [ ! -f "$object" ]; then
+        echo "Object does not exist: ${object}" >&2
+        exit 1
+    fi
+done
+
+# Create a lib temporarily to dump symbols from.
+# It's just much easier to do it this way
+libname=$(mktemp -u "library").lib
+
+trap 'rm -f -- $libname' EXIT
+
+lib -out:${libname} $@ >/dev/null
+if [ $? != 0 ]; then
+    echo "Could not create temporary library." >&2
+    exit 1
+fi
+
+IFS='
+'
+
+# Determine if we're building for x86 or x86_64 and
+# set the symbol prefix accordingly.
+prefix=""
+arch=$(dumpbin -headers ${libname} |
+       tr '\t' ' ' |
+       grep '^ \+.\+machine \+(.\+)' |
+       head -1 |
+       sed -e 's/^ \{1,\}.\{1,\} \{1,\}machine \{1,\}(\(...\)).*/\1/')
+
+if [ "${arch}" = "x86" ]; then
+    prefix="_"
+else
+    if [ "${arch}" != "ARM" ] && [ "${arch}" != "x64" ]; then
+        echo "Unknown machine type." >&2
+        exit 1
+    fi
+fi
+
+started=0
+regex="none"
+
+for line in $(cat ${vscript} | tr '\t' ' '); do
+    # We only care about global symbols
+    echo "${line}" | grep -q '^ \+global:'
+    if [ $? = 0 ]; then
+        started=1
+        line=$(echo "${line}" | sed -e 's/^ \{1,\}global: *//')
+    else
+        echo "${line}" | grep -q '^ \+local:'
+        if [ $? = 0 ]; then
+            started=0
+        fi
+    fi
+
+    if [ ${started} = 0 ]; then
+        continue
+    fi
+
+    # Handle multiple symbols on one line
+    IFS=';'
+
+    # Work around stupid expansion to filenames
+    line=$(echo "${line}" | sed -e 's/\*/.\\+/g')
+    for exp in ${line}; do
+        # Remove leading and trailing whitespace
+        exp=$(echo "${exp}" | sed -e 's/^ *//' -e 's/ *$//')
+
+        if [ "${regex}" = "none" ]; then
+            regex="${exp}"
+        else
+            regex="${regex};${exp}"
+        fi
+    done
+
+    IFS='
+'
+done
+
+dump=$(dumpbin -linkermember:1 ${libname})
+
+rm ${libname}
+
+IFS=';'
+list=""
+for exp in ${regex}; do
+    list="${list}"'
+'$(echo "${dump}" |
+          sed -e '/public symbols/,$!d' -e '/^ \{1,\}Summary/,$d' -e "s/ \{1,\}${prefix}/ /" -e 's/ \{1,\}/ /g' |
+          tail -n +2 |
+          cut -d' ' -f3 |
+          grep "^${exp}" |
+          sed -e 's/^/    /')
+done
+
+echo "EXPORTS"
+echo "${list}" | sort | uniq | tail -n +2
diff --git a/configure b/configure
index 6ab04ae..52993d7 100755
--- a/configure
+++ b/configure
@@ -81,6 +81,7 @@ Standard options:
   --prefix=PREFIX          install in PREFIX [$prefix]
   --bindir=DIR             install binaries in DIR [PREFIX/bin]
   --datadir=DIR            install data files in DIR [PREFIX/share/avconv]
+  --docdir=DIR             install documentation in DIR [PREFIX/share/doc/libav]
   --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]
@@ -120,15 +121,16 @@ Component options:
   --disable-avresample     disable libavresample build [no]
   --disable-pthreads       disable pthreads [auto]
   --disable-w32threads     disable Win32 threads [auto]
-  --enable-x11grab         enable X11 grabbing [no]
   --disable-network        disable network support [no]
   --disable-dct            disable DCT code
-  --disable-dwt            disable DWT code
+  --disable-error-resilience disable error resilience code
   --disable-lsp            disable LSP code
   --disable-lzo            disable LZO decoder code
   --disable-mdct           disable MDCT code
   --disable-rdft           disable RDFT code
   --disable-fft            disable FFT code
+
+Hardware accelerators:
   --enable-dxva2           enable DXVA2 code
   --enable-vaapi           enable VAAPI code
   --enable-vda             enable VDA code
@@ -172,7 +174,7 @@ Individual component options:
   --disable-filters        disable all filters
 
 External library support:
-  --enable-avisynth        enable reading of AVISynth script files [no]
+  --enable-avisynth        enable reading of AviSynth script files [no]
   --enable-bzlib           enable bzlib [autodetect]
   --enable-frei0r          enable frei0r video filtering
   --enable-gnutls          enable gnutls [no]
@@ -180,7 +182,7 @@ External library support:
   --enable-libdc1394       enable IIDC-1394 grabbing using libdc1394
                            and libraw1394 [no]
   --enable-libfaac         enable AAC encoding via libfaac [no]
-  --enable-libfdk-aac      enable AAC encoding via libfdk-aac [no]
+  --enable-libfdk-aac      enable AAC de/encoding via libfdk-aac [no]
   --enable-libfreetype     enable libfreetype [no]
   --enable-libgsm          enable GSM de/encoding via libgsm [no]
   --enable-libilbc         enable iLBC de/encoding via libilbc [no]
@@ -198,12 +200,14 @@ External library support:
   --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-libvpx          enable VP8 de/encoding via libvpx [no]
+  --enable-libvpx          enable VP8 and VP9 de/encoding via libvpx [no]
+  --enable-libwavpack      enable wavpack encoding via libwavpack [no]
   --enable-libx264         enable H.264 encoding via x264 [no]
   --enable-libxavs         enable AVS encoding via xavs [no]
   --enable-libxvid         enable Xvid encoding via xvidcore,
                            native MPEG-4/Xvid encoder exists [no]
   --enable-openssl         enable openssl [no]
+  --enable-x11grab         enable X11 grabbing [no]
   --enable-zlib            enable zlib [autodetect]
 
 Advanced options (experts only):
@@ -214,6 +218,7 @@ Advanced options (experts only):
   --target-os=OS           compiler targets OS [$target_os]
   --target-exec=CMD        command to run executables on target
   --target-path=DIR        path to view of build directory on target
+  --target-samples=DIR     path to samples directory on target
   --toolchain=NAME         set tool defaults according to NAME
   --nm=NM                  use nm tool
   --ar=AR                  use archive tool AR [$ar_default]
@@ -223,6 +228,7 @@ Advanced options (experts only):
   --ld=LD                  use linker LD
   --host-cc=HOSTCC         use host C compiler HOSTCC
   --host-cflags=HCFLAGS    use HCFLAGS when compiling for host
+  --host-cppflags=HCPPFLAGS use HCPPFLAGS when compiling for host
   --host-ld=HOSTLD         use host linker HOSTLD
   --host-ldflags=HLDFLAGS  use HLDFLAGS when linking for host
   --host-libs=HLIBS        use libs HLIBS when linking for host
@@ -263,6 +269,7 @@ Optimization options (experts only):
   --disable-sse42          disable SSE4.2 optimizations
   --disable-avx            disable AVX optimizations
   --disable-fma4           disable FMA4 optimizations
+  --disable-avx2           disable AVX2 optimizations
   --disable-armv5te        disable armv5te optimizations
   --disable-armv6          disable armv6 optimizations
   --disable-armv6t2        disable armv6t2 optimizations
@@ -323,7 +330,7 @@ die(){
 
 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 at libav.org mailing list or IRC #libav on irc.freenode.net.
+libav-tools at libav.org mailing list or IRC #libav on irc.freenode.net.
 EOF
     if disabled logging; then
         cat <<EOF
@@ -406,32 +413,36 @@ set_weak(){
     done
 }
 
+sanitize_var_name(){
+    echo $@ | sed 's/[^A-Za-z0-9_]/_/g'
+}
+
 set_safe(){
     var=$1
     shift
-    eval $(echo "$var" | sed 's/[^A-Za-z0-9_]/_/g')='$*'
+    eval $(sanitize_var_name "$var")='$*'
 }
 
 get_safe(){
-    eval echo \$$(echo "$1" | sed 's/[^A-Za-z0-9_]/_/g')
+    eval echo \$$(sanitize_var_name "$1")
 }
 
 pushvar(){
-    for var in $*; do
-        eval level=\${${var}_level:=0}
-        eval ${var}_${level}="\$$var"
-        eval ${var}_level=$(($level+1))
+    for pvar in $*; do
+        eval level=\${${pvar}_level:=0}
+        eval ${pvar}_${level}="\$$pvar"
+        eval ${pvar}_level=$(($level+1))
     done
 }
 
 popvar(){
-    for var in $*; do
-        eval level=\${${var}_level:-0}
+    for pvar in $*; do
+        eval level=\${${pvar}_level:-0}
         test $level = 0 && continue
         eval level=$(($level-1))
-        eval $var="\${${var}_${level}}"
-        eval ${var}_level=$level
-        eval unset ${var}_${level}
+        eval $pvar="\${${pvar}_${level}}"
+        eval ${pvar}_level=$level
+        eval unset ${pvar}_${level}
     done
 }
 
@@ -482,8 +493,13 @@ enable_deep(){
 }
 
 enable_deep_weak(){
-    do_enable_deep $*
-    enable_weak $*
+    for var; do
+        disabled $var && continue
+        pushvar var
+        do_enable_deep $var
+        popvar var
+        enable_weak $var
+    done
 }
 
 enabled(){
@@ -643,10 +659,18 @@ add_ldflags(){
     append LDFLAGS $($ldflags_filter "$@")
 }
 
+add_stripflags(){
+    append STRIPFLAGS "$@"
+}
+
 add_extralibs(){
     prepend extralibs $($ldflags_filter "$@")
 }
 
+add_host_cppflags(){
+    append host_cppflags "$@"
+}
+
 add_host_cflags(){
     append host_cflags $($host_cflags_filter "$@")
 }
@@ -759,14 +783,19 @@ int x;
 EOF
 }
 
-check_cflags(){
-    log check_cflags "$@"
+test_cflags(){
+    log test_cflags "$@"
     set -- $($cflags_filter "$@")
-    check_cc "$@" <<EOF && append CFLAGS "$@"
+    check_cc "$@" <<EOF
 int x;
 EOF
 }
 
+check_cflags(){
+    log check_cflags "$@"
+    test_cflags "$@" && add_cflags "$@"
+}
+
 test_ldflags(){
     log test_ldflags "$@"
     check_ld "$@" <<EOF
@@ -779,6 +808,20 @@ check_ldflags(){
     test_ldflags "$@" && add_ldflags "$@"
 }
 
+test_stripflags(){
+    log test_stripflags "$@"
+    # call check_cc to get a fresh TMPO
+    check_cc <<EOF
+int main(void) { return 0; }
+EOF
+    check_cmd $strip $STRIPFLAGS "$@" $TMPO
+}
+
+check_stripflags(){
+    log check_stripflags "$@"
+    test_stripflags "$@" && add_stripflags "$@"
+}
+
 check_header(){
     log check_header "$@"
     header=$1
@@ -866,7 +909,7 @@ check_pkg_config(){
     headers="$2"
     funcs="$3"
     shift 3
-    $pkg_config --exists $pkg || return
+    check_cmd $pkg_config --exists --print-errors $pkg || return
     pkg_cflags=$($pkg_config --cflags $pkg)
     pkg_libs=$($pkg_config --libs $pkg)
     check_func_headers "$headers" "$funcs" $pkg_cflags $pkg_libs "$@" &&
@@ -895,6 +938,7 @@ static void sighandler(int sig){
 int foo(void){
     $code
 }
+int (*func_ptr)(void) = foo;
 int main(void){
     signal(SIGILL, sighandler);
     signal(SIGFPE, sighandler);
@@ -902,7 +946,7 @@ int main(void){
 #ifdef SIGBUS
     signal(SIGBUS, sighandler);
 #endif
-    foo();
+    return func_ptr();
 }
 EOF
 }
@@ -917,7 +961,7 @@ check_type(){
 }
 
 check_struct(){
-    log check_type "$@"
+    log check_struct "$@"
     headers=$1
     struct=$2
     member=$3
@@ -927,6 +971,16 @@ check_struct(){
         enable_safe "${struct}_${member}"
 }
 
+check_builtin(){
+    log check_builtin "$@"
+    name=$1
+    headers=$2
+    builtin=$3
+    shift 3
+    disable "$name"
+    check_code ld "$headers" "$builtin" "$@" && enable "$name"
+}
+
 require(){
     name="$1"
     header="$2"
@@ -950,6 +1004,10 @@ require_pkg_config(){
     add_extralibs $(get_safe ${pkg}_libs)
 }
 
+hostcc_e(){
+    eval printf '%s\\n' $HOSTCC_E
+}
+
 hostcc_o(){
     eval printf '%s\\n' $HOSTCC_O
 }
@@ -961,6 +1019,20 @@ check_host_cc(){
     check_cmd $host_cc $host_cflags "$@" $HOSTCC_C $(hostcc_o $TMPO) $TMPC
 }
 
+check_host_cpp(){
+    log check_host_cpp "$@"
+    cat > $TMPC
+    log_file $TMPC
+    check_cmd $host_cc $HOSTCPPFLAGS $HOSTCFLAGS "$@" $(hostcc_e $TMPO) $TMPC
+}
+
+check_host_cppflags(){
+    log check_host_cppflags "$@"
+    check_host_cc "$@" <<EOF && append host_cppflags "$@"
+int x;
+EOF
+}
+
 check_host_cflags(){
     log check_host_cflags "$@"
     set -- $($host_cflags_filter "$@")
@@ -969,6 +1041,19 @@ int x;
 EOF
 }
 
+check_host_cpp_condition(){
+    log check_host_cpp_condition "$@"
+    header=$1
+    condition=$2
+    shift 2
+    check_host_cpp "$@" <<EOF
+#include <$header>
+#if !($condition)
+#error "unsatisfied condition: $condition"
+#endif
+EOF
+}
+
 apply(){
     file=$1
     shift
@@ -998,39 +1083,16 @@ COMPONENT_LIST="
     protocols
 "
 
-LIBRARY_LIST="
-    avcodec
-    avdevice
-    avfilter
-    avformat
-    avresample
-    avutil
-    swscale
+EXAMPLE_LIST="
+    output_example
+    transcode_aac_example
 "
 
-PROGRAM_LIST="
-    avconv
-    avplay
-    avprobe
-    avserver
-"
-
-CONFIG_LIST="
-    $COMPONENT_LIST
-    $LIBRARY_LIST
-    $PROGRAM_LIST
+EXTERNAL_LIBRARY_LIST="
     avisynth
     bzlib
-    dct
-    doc
-    dwt
-    dxva2
-    fft
     frei0r
     gnutls
-    gpl
-    gray
-    hardcoded_tables
     libcdio
     libdc1394
     libfaac
@@ -1053,16 +1115,59 @@ CONFIG_LIST="
     libvo_amrwbenc
     libvorbis
     libvpx
+    libwavpack
     libx264
     libxavs
     libxvid
+    openssl
+    x11grab
+    zlib
+"
+
+HWACCEL_LIST="
+    dxva2
+    vaapi
+    vda
+    vdpau
+"
+LIBRARY_LIST="
+    avcodec
+    avdevice
+    avfilter
+    avformat
+    avresample
+    avutil
+    swscale
+"
+
+PROGRAM_LIST="
+    avconv
+    avplay
+    avprobe
+    avserver
+"
+
+CONFIG_LIST="
+    $COMPONENT_LIST
+    $EXAMPLE_LIST
+    $EXTERNAL_LIBRARY_LIST
+    $HWACCEL_LIST
+    $LIBRARY_LIST
+    $PROGRAM_LIST
+    dct
+    doc
+    error_resilience
+    fft
+    gpl
+    gray
+    hardcoded_tables
     lsp
     lzo
     mdct
     memalign_hack
     network
     nonfree
-    openssl
+    pod2man
     pic
     rdft
     runtime_cpudetect
@@ -1072,14 +1177,10 @@ CONFIG_LIST="
     sram
     static
     swscale_alpha
+    texi2html
     thumb
-    vaapi
-    vda
-    vdpau
     version3
     xmm_clobber_test
-    x11grab
-    zlib
 "
 
 THREADS_LIST='
@@ -1087,6 +1188,12 @@ THREADS_LIST='
     w32threads
 '
 
+ATOMICS_LIST='
+    atomics_gcc
+    atomics_suncc
+    atomics_win32
+'
+
 ARCH_LIST='
     aarch64
     alpha
@@ -1127,7 +1234,9 @@ ARCH_EXT_LIST_X86='
     amd3dnow
     amd3dnowext
     avx
+    avx2
     fma4
+    i686
     mmx
     mmxext
     sse
@@ -1191,6 +1300,7 @@ HAVE_LIST="
     $HAVE_LIST_CMDLINE
     $HAVE_LIST_PUB
     $THREADS_LIST
+    $ATOMICS_LIST
     $MATH_FUNCS
     aligned_malloc
     aligned_stack
@@ -1199,12 +1309,13 @@ HAVE_LIST="
     arpa_inet_h
     asm_mod_q
     asm_mod_y
+    atomic_cas_ptr
+    atomics_native
     attribute_may_alias
     attribute_packed
     cdio_paranoia_h
     cdio_paranoia_paranoia_h
     closesocket
-    cmov
     CommandLineToArgvW
     cpunop
     CryptGenRandom
@@ -1237,12 +1348,15 @@ HAVE_LIST="
     getservbyport
     gettimeofday
     gnu_as
+    gsm_h
     ibm_asm
     inet_aton
     io_h
+    inline_asm_labels
     isatty
     jack_port_get_latency_range
     ldbrx
+    libc_msvcrt
     libdc1394_1
     libdc1394_2
     local_aligned_16
@@ -1251,21 +1365,22 @@ HAVE_LIST="
     loongson
     machine_ioctl_bt848_h
     machine_ioctl_meteor_h
+    machine_rw_barrier
     malloc_h
     MapViewOfFile
     memalign
+    MemoryBarrier
     mkstemp
     mm_empty
     mmap
     mprotect
-    msvcrt
     nanosleep
     poll_h
     posix_memalign
+    pragma_deprecated
     rdtsc
     sched_getaffinity
     sdl
-    sdl_video_size
     SetConsoleTextAttribute
     setmode
     setrlimit
@@ -1288,6 +1403,7 @@ HAVE_LIST="
     struct_v4l2_frmivalenum_discrete
     symver_asm_label
     symver_gnu_asm
+    sync_val_compare_and_swap
     sysconf
     sysctl
     sys_mman_h
@@ -1296,15 +1412,18 @@ HAVE_LIST="
     sys_select_h
     sys_soundcard_h
     sys_time_h
+    sys_un_h
     sys_videoio_h
     threads
     unistd_h
     usleep
+    vdpau_x11
     vfp_args
     VirtualAlloc
     windows_h
     winsock2_h
     xform_asm
+    xlib
     xmm_clobbers
 "
 
@@ -1313,14 +1432,16 @@ CONFIG_EXTRA="
     aandcttables
     ac3dsp
     audio_frame_queue
-    error_resilience
+    dsputil
     gcrypt
     golomb
     gplv3
+    h263dsp
     h264chroma
     h264dsp
     h264pred
     h264qpel
+    hpeldsp
     huffman
     lgplv3
     lpc
@@ -1330,6 +1451,8 @@ CONFIG_EXTRA="
     mpegvideoenc
     nettle
     rangecoder
+    riffdec
+    riffenc
     rtpdec
     rtpenc_chain
     sinewin
@@ -1354,6 +1477,7 @@ CMDLINE_SELECT="
 PATHS_LIST='
     bindir
     datadir
+    docdir
     incdir
     libdir
     mandir
@@ -1391,11 +1515,13 @@ CMDLINE_SET="
     target_exec
     target_os
     target_path
+    target_samples
     toolchain
 "
 
 CMDLINE_APPEND="
     extra_cflags
+    host_cppflags
 "
 
 # code dependency declarations
@@ -1416,7 +1542,9 @@ ppc4xx_deps="ppc"
 
 vis_deps="sparc"
 
-x86_64_suggest="cmov fast_cmov"
+cpunop_deps="i686"
+x86_64_select="i686"
+x86_64_suggest="fast_cmov"
 
 amd3dnow_deps="mmx"
 amd3dnowext_deps="amd3dnow"
@@ -1430,6 +1558,7 @@ sse4_deps="ssse3"
 sse42_deps="sse4"
 avx_deps="sse42"
 fma4_deps="avx"
+avx2_deps="avx"
 
 mmx_external_deps="yasm"
 mmx_inline_deps="inline_asm"
@@ -1447,77 +1576,108 @@ fast_64bit_if_any="alpha ia64 mips64 parisc64 ppc64 sparc64 x86_64"
 fast_clz_if_any="alpha avr32 mips ppc x86"
 fast_unaligned_if_any="ppc x86"
 
-inline_asm_deps="!tms470"
 need_memalign="altivec neon sse"
 
-symver_if_any="symver_asm_label symver_gnu_asm"
+# system capabilities
+log2_deps="!libc_msvcrt"
 
-log2_deps="!msvcrt"
+symver_if_any="symver_asm_label symver_gnu_asm"
 
 # subsystems
 dct_select="rdft"
+error_resilience_select="dsputil"
+lpc_select="dsputil"
 mdct_select="fft"
 rdft_select="fft"
 mpegaudio_select="mpegaudiodsp"
 mpegaudiodsp_select="dct"
-mpegvideo_select="videodsp"
+mpegvideo_select="dsputil hpeldsp videodsp"
 mpegvideoenc_select="mpegvideo"
 
 # decoders / encoders
 aac_decoder_select="mdct sinewin"
 aac_encoder_select="audio_frame_queue mdct sinewin"
 aac_latm_decoder_select="aac_decoder aac_latm_parser"
-ac3_decoder_select="mdct ac3dsp ac3_parser"
-ac3_encoder_select="mdct ac3dsp"
-ac3_fixed_encoder_select="mdct ac3dsp"
+ac3_decoder_select="mdct ac3dsp ac3_parser dsputil"
+ac3_encoder_select="mdct ac3dsp dsputil"
+ac3_fixed_encoder_select="mdct ac3dsp dsputil"
+aic_decoder_select="dsputil golomb"
 alac_encoder_select="lpc"
+als_decoder_select="dsputil"
 amrnb_decoder_select="lsp"
 amrwb_decoder_select="lsp"
+amv_decoder_select="dsputil hpeldsp"
+ape_decoder_select="dsputil"
+asv1_decoder_select="dsputil"
+asv1_encoder_select="dsputil"
+asv2_decoder_select="dsputil"
+asv2_encoder_select="dsputil"
 atrac1_decoder_select="mdct sinewin"
 atrac3_decoder_select="mdct"
+bink_decoder_select="dsputil hpeldsp"
 binkaudio_dct_decoder_select="mdct rdft dct sinewin"
 binkaudio_rdft_decoder_select="mdct rdft sinewin"
-cavs_decoder_select="golomb mpegvideo"
+cavs_decoder_select="dsputil golomb h264chroma videodsp"
+cllc_decoder_select="dsputil"
 comfortnoise_encoder_select="lpc"
-cook_decoder_select="mdct sinewin"
+cook_decoder_select="dsputil mdct sinewin"
 cscd_decoder_select="lzo"
 cscd_decoder_suggest="zlib"
 dca_decoder_select="mdct"
-dnxhd_encoder_select="aandcttables mpegvideoenc"
-dxa_decoder_select="zlib"
+dnxhd_decoder_select="dsputil"
+dnxhd_encoder_select="aandcttables dsputil mpegvideoenc"
+dvvideo_decoder_select="dsputil"
+dvvideo_encoder_select="dsputil"
+dxa_decoder_deps="zlib"
 eac3_decoder_select="ac3_decoder"
 eac3_encoder_select="ac3_encoder"
-eamad_decoder_select="aandcttables error_resilience mpegvideo"
-eatgq_decoder_select="aandcttables"
+eamad_decoder_select="aandcttables dsputil mpegvideo"
+eatgq_decoder_select="aandcttables dsputil"
 eatqi_decoder_select="aandcttables error_resilience mpegvideo"
-ffv1_decoder_select="golomb rangecoder"
-ffv1_encoder_select="rangecoder"
-ffvhuff_encoder_select="huffman"
+ffv1_decoder_select="dsputil golomb rangecoder"
+ffv1_encoder_select="dsputil rangecoder"
+ffvhuff_decoder_select="dsputil"
+ffvhuff_encoder_select="dsputil huffman"
 flac_decoder_select="golomb"
-flac_encoder_select="golomb lpc"
-flashsv_decoder_select="zlib"
-flashsv_encoder_select="zlib"
-flashsv2_decoder_select="zlib"
+flac_encoder_select="dsputil golomb lpc"
+flashsv_decoder_deps="zlib"
+flashsv_encoder_deps="zlib"
+flashsv2_decoder_deps="zlib"
 flv_decoder_select="h263_decoder"
 flv_encoder_select="h263_encoder"
-fraps_decoder_select="huffman"
+fourxm_decoder_select="dsputil"
+fraps_decoder_select="dsputil huffman"
+g2m_decoder_deps="zlib"
+g2m_decoder_select="dsputil"
 h261_decoder_select="error_resilience mpegvideo"
 h261_encoder_select="aandcttables mpegvideoenc"
-h263_decoder_select="error_resilience h263_parser mpegvideo"
-h263_encoder_select="aandcttables error_resilience mpegvideoenc"
+h263_decoder_select="error_resilience h263_parser h263dsp mpegvideo"
+h263_encoder_select="aandcttables h263dsp mpegvideoenc"
 h263i_decoder_select="h263_decoder"
 h263p_encoder_select="h263_encoder"
-h264_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo"
-huffyuv_encoder_select="huffman"
-iac_decoder_select="fft mdct sinewin"
-imc_decoder_select="fft mdct sinewin"
-jpegls_decoder_select="golomb"
+h264_decoder_select="golomb h264chroma h264dsp h264pred h264qpel videodsp"
+h264_decoder_suggest="error_resilience"
+hevc_decoder_select="dsputil golomb videodsp"
+huffyuv_decoder_select="dsputil"
+huffyuv_encoder_select="dsputil huffman"
+iac_decoder_select="dsputil fft mdct sinewin"
+imc_decoder_select="dsputil fft mdct sinewin"
+indeo3_decoder_select="hpeldsp"
+interplay_video_decoder_select="hpeldsp"
+jpegls_decoder_select="dsputil golomb hpeldsp"
 jpegls_encoder_select="golomb"
+jv_decoder_select="dsputil"
+lagarith_decoder_select="dsputil"
 ljpeg_encoder_select="aandcttables mpegvideoenc"
 loco_decoder_select="golomb"
-mdec_decoder_select="error_resilience mpegvideo"
-mjpeg_encoder_select="aandcttables mpegvideoenc"
-mlp_decoder_select="mlp_parser"
+mdec_decoder_select="dsputil error_resilience mpegvideo"
+metasound_decoder_select="lsp mdct sinewin"
+mimic_decoder_select="dsputil hpeldsp"
+mjpeg_decoder_select="dsputil hpeldsp"
+mjpegb_decoder_select="dsputil hpeldsp"
+mjpeg_encoder_select="aandcttables dsputil mpegvideoenc"
+mlp_decoder_select="dsputil mlp_parser"
+motionpixels_decoder_select="dsputil"
 mp1_decoder_select="mpegaudio"
 mp1float_decoder_select="mpegaudio"
 mp2_decoder_select="mpegaudio"
@@ -1528,63 +1688,74 @@ mp3adufloat_decoder_select="mpegaudio"
 mp3float_decoder_select="mpegaudio"
 mp3on4_decoder_select="mpegaudio"
 mp3on4float_decoder_select="mpegaudio"
-mpc7_decoder_select="mpegaudiodsp"
-mpc8_decoder_select="mpegaudiodsp"
+mpc7_decoder_select="dsputil mpegaudiodsp"
+mpc8_decoder_select="dsputil mpegaudiodsp"
 mpeg_xvmc_decoder_deps="X11_extensions_XvMClib_h"
-mpeg_xvmc_decoder_select="mpegvideo_decoder"
+mpeg_xvmc_decoder_select="mpeg2video_decoder"
 mpeg1video_decoder_select="error_resilience mpegvideo"
-mpeg1video_encoder_select="aandcttables error_resilience mpegvideoenc"
+mpeg1video_encoder_select="aandcttables mpegvideoenc"
 mpeg2video_decoder_select="error_resilience mpegvideo"
-mpeg2video_encoder_select="aandcttables error_resilience mpegvideoenc"
+mpeg2video_encoder_select="aandcttables mpegvideoenc"
 mpeg4_decoder_select="h263_decoder mpeg4video_parser"
 mpeg4_encoder_select="h263_encoder"
 msmpeg4v1_decoder_select="h263_decoder"
-msmpeg4v1_encoder_select="h263_encoder"
 msmpeg4v2_decoder_select="h263_decoder"
 msmpeg4v2_encoder_select="h263_encoder"
 msmpeg4v3_decoder_select="h263_decoder"
 msmpeg4v3_encoder_select="h263_encoder"
-mss2_decoder_select="vc1_decoder"
+mss2_decoder_select="error_resilience vc1_decoder"
+mxpeg_decoder_select="dsputil hpeldsp"
 nellymoser_decoder_select="mdct sinewin"
 nellymoser_encoder_select="audio_frame_queue mdct sinewin"
-nuv_decoder_select="lzo"
-png_decoder_select="zlib"
-png_encoder_select="zlib"
+nuv_decoder_select="dsputil lzo"
+png_decoder_deps="zlib"
+png_decoder_select="dsputil"
+png_encoder_deps="zlib"
+png_encoder_select="dsputil"
+prores_decoder_select="dsputil"
+prores_encoder_select="dsputil"
 qcelp_decoder_select="lsp"
 qdm2_decoder_select="mdct rdft mpegaudiodsp"
 ra_144_encoder_select="audio_frame_queue lpc"
 ralf_decoder_select="golomb"
-rv10_decoder_select="h263_decoder"
+rv10_decoder_select="error_resilience h263_decoder h263dsp"
 rv10_encoder_select="h263_encoder"
-rv20_decoder_select="h263_decoder"
+rv20_decoder_select="error_resilience h263_decoder h263dsp"
 rv20_encoder_select="h263_encoder"
-rv30_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpegvideo"
-rv40_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpegvideo"
+rv30_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpegvideo videodsp"
+rv40_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpegvideo videodsp"
 shorten_decoder_select="golomb"
 sipr_decoder_select="lsp"
-snow_decoder_select="dwt rangecoder"
-snow_encoder_select="aandcttables dwt error_resilience mpegvideoenc rangecoder"
-svq1_decoder_select="error_resilience mpegvideo"
-svq1_encoder_select="aandcttables error_resilience mpegvideoenc"
-svq3_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo"
-svq3_decoder_suggest="zlib"
+sp5x_decoder_select="dsputil hpeldsp"
+svq1_decoder_select="hpeldsp"
+svq1_encoder_select="aandcttables dsputil hpeldsp mpegvideoenc"
+svq3_decoder_select="golomb h264chroma h264dsp h264pred h264qpel hpeldsp mpegvideo videodsp"
+svq3_decoder_suggest="error_resilience zlib"
+tak_decoder_select="dsputil"
 theora_decoder_select="vp3_decoder"
 tiff_decoder_suggest="zlib"
 tiff_encoder_suggest="zlib"
+thp_decoder_select="dsputil hpeldsp"
 truehd_decoder_select="mlp_decoder"
-tscc_decoder_select="zlib"
+truemotion2_decoder_select="dsputil"
+truespeech_decoder_select="dsputil"
+tscc_decoder_deps="zlib"
 twinvq_decoder_select="mdct lsp sinewin"
-utvideo_encoder_select="huffman"
-vc1_decoder_select="h263_decoder h264chroma h264qpel"
+utvideo_decoder_select="dsputil"
+utvideo_encoder_select="dsputil huffman"
+vble_decoder_select="dsputil"
+vc1_decoder_select="error_resilience h263_decoder h264chroma h264qpel"
 vc1image_decoder_select="vc1_decoder"
 vorbis_decoder_select="mdct"
 vorbis_encoder_select="mdct"
-vp3_decoder_select="vp3dsp videodsp"
-vp5_decoder_select="vp3dsp videodsp"
-vp6_decoder_select="huffman vp3dsp videodsp"
+vp3_decoder_select="hpeldsp vp3dsp videodsp"
+vp5_decoder_select="h264chroma hpeldsp videodsp vp3dsp"
+vp6_decoder_select="h264chroma hpeldsp huffman videodsp vp3dsp"
 vp6a_decoder_select="vp6_decoder"
 vp6f_decoder_select="vp6_decoder"
 vp8_decoder_select="h264pred videodsp"
+vp9_decoder_select="videodsp"
+webp_decoder_select="vp8_decoder"
 wmapro_decoder_select="mdct sinewin"
 wmav1_decoder_select="mdct sinewin"
 wmav1_encoder_select="mdct sinewin"
@@ -1593,52 +1764,67 @@ wmav2_encoder_select="mdct sinewin"
 wmavoice_decoder_select="lsp rdft dct mdct sinewin"
 wmv1_decoder_select="h263_decoder"
 wmv1_encoder_select="h263_encoder"
-wmv2_decoder_select="h263_decoder"
+wmv2_decoder_select="h263_decoder videodsp"
 wmv2_encoder_select="h263_encoder"
 wmv3_decoder_select="vc1_decoder"
 wmv3image_decoder_select="wmv3_decoder"
-zerocodec_decoder_select="zlib"
-zlib_decoder_select="zlib"
-zlib_encoder_select="zlib"
-zmbv_decoder_select="zlib"
-zmbv_encoder_select="zlib"
+zerocodec_decoder_deps="zlib"
+zlib_decoder_deps="zlib"
+zlib_encoder_deps="zlib"
+zmbv_decoder_deps="zlib"
+zmbv_encoder_deps="zlib"
 
 # hardware accelerators
 dxva2_deps="dxva2api_h"
 vaapi_deps="va_va_h"
 vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
+vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore"
 vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
 
-h263_vaapi_hwaccel_select="vaapi h263_decoder"
+h263_vaapi_hwaccel_deps="vaapi"
+h263_vaapi_hwaccel_select="h263_decoder"
+h263_vdpau_hwaccel_deps="vdpau"
+h263_vdpau_hwaccel_select="h263_decoder"
 h264_dxva2_hwaccel_deps="dxva2"
 h264_dxva2_hwaccel_select="h264_decoder"
-h264_vaapi_hwaccel_select="vaapi h264_decoder"
-h264_vda_hwaccel_select="vda h264_decoder"
-h264_vdpau_decoder_select="vdpau h264_decoder"
-mpeg_vdpau_decoder_select="vdpau mpegvideo_decoder"
-mpeg1_vdpau_decoder_select="vdpau mpeg1video_decoder"
+h264_vaapi_hwaccel_deps="vaapi"
+h264_vaapi_hwaccel_select="h264_decoder"
+h264_vda_hwaccel_deps="vda"
+h264_vda_hwaccel_select="h264_decoder"
+h264_vdpau_hwaccel_deps="vdpau"
+h264_vdpau_hwaccel_select="h264_decoder"
+mpeg1_vdpau_hwaccel_deps="vdpau"
+mpeg1_vdpau_hwaccel_select="mpeg1video_decoder"
 mpeg2_dxva2_hwaccel_deps="dxva2"
 mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
-mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder"
-mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder"
-mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder"
+mpeg2_vaapi_hwaccel_deps="vaapi"
+mpeg2_vaapi_hwaccel_select="mpeg2video_decoder"
+mpeg2_vdpau_hwaccel_deps="vdpau"
+mpeg2_vdpau_hwaccel_select="mpeg2video_decoder"
+mpeg4_vaapi_hwaccel_deps="vaapi"
+mpeg4_vaapi_hwaccel_select="mpeg4_decoder"
+mpeg4_vdpau_hwaccel_deps="vdpau"
+mpeg4_vdpau_hwaccel_select="mpeg4_decoder"
 vc1_dxva2_hwaccel_deps="dxva2"
 vc1_dxva2_hwaccel_select="vc1_decoder"
-vc1_vaapi_hwaccel_select="vaapi vc1_decoder"
-vc1_vdpau_decoder_select="vdpau vc1_decoder"
+vc1_vaapi_hwaccel_deps="vaapi"
+vc1_vaapi_hwaccel_select="vc1_decoder"
+vc1_vdpau_hwaccel_deps="vdpau"
+vc1_vdpau_hwaccel_select="vc1_decoder"
 wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
 wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
-wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
+wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
 
 # parsers
-h264_parser_select="error_resilience golomb h264dsp h264pred mpegvideo"
+h264_parser_select="golomb h264chroma h264dsp h264pred h264qpel videodsp"
 mpeg4video_parser_select="error_resilience mpegvideo"
 mpegvideo_parser_select="error_resilience mpegvideo"
-vc1_parser_select="error_resilience mpegvideo"
+vc1_parser_select="mpegvideo"
 
 # external libraries
 libfaac_encoder_deps="libfaac"
 libfaac_encoder_select="audio_frame_queue"
+libfdk_aac_decoder_deps="libfdk_aac"
 libfdk_aac_encoder_deps="libfdk_aac"
 libfdk_aac_encoder_select="audio_frame_queue"
 libgsm_decoder_deps="libgsm"
@@ -1669,34 +1855,52 @@ libvo_aacenc_encoder_select="audio_frame_queue"
 libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
 libvorbis_encoder_deps="libvorbis"
 libvorbis_encoder_select="audio_frame_queue"
-libvpx_decoder_deps="libvpx"
-libvpx_encoder_deps="libvpx"
+libvpx_vp8_decoder_deps="libvpx"
+libvpx_vp8_encoder_deps="libvpx"
+libvpx_vp9_decoder_deps="libvpx"
+libvpx_vp9_encoder_deps="libvpx"
+libwavpack_encoder_deps="libwavpack"
 libx264_encoder_deps="libx264"
 libxavs_encoder_deps="libxavs"
 libxvid_encoder_deps="libxvid"
 
 # demuxers / muxers
 ac3_demuxer_select="ac3_parser"
+asf_demuxer_select="riffdec"
+asf_muxer_select="riffenc"
 asf_stream_muxer_select="asf_muxer"
+avi_demuxer_select="riffdec"
+avi_muxer_select="riffenc"
 avisynth_demuxer_deps="avisynth"
+avisynth_demuxer_select="riffdec"
+caf_demuxer_select="riffdec"
 dirac_demuxer_select="dirac_parser"
+dxa_demuxer_select="riffdec"
 eac3_demuxer_select="ac3_parser"
+f4v_muxer_select="mov_muxer"
 flac_demuxer_select="flac_parser"
+hds_muxer_select="flv_muxer"
+hls_muxer_select="mpegts_muxer"
 ipod_muxer_select="mov_muxer"
 ismv_muxer_select="mov_muxer"
 matroska_audio_muxer_select="matroska_muxer"
+matroska_demuxer_select="riffdec"
 matroska_demuxer_suggest="bzlib lzo zlib"
+matroska_muxer_select="riffenc"
+mmf_muxer_select="riffenc"
+mov_demuxer_select="riffdec"
 mov_demuxer_suggest="zlib"
-mov_muxer_select="rtpenc_chain"
+mov_muxer_select="riffenc rtpenc_chain"
 mp3_demuxer_select="mpegaudio_parser"
 mp4_muxer_select="mov_muxer"
-mpegts_muxer_select="adts_muxer latm_muxer mpegvideo"
+mpegts_muxer_select="adts_muxer latm_muxer"
 mpegtsraw_demuxer_select="mpegts_demuxer"
 mxf_d10_muxer_select="mxf_muxer"
+nut_muxer_select="riffenc"
+nuv_demuxer_select="riffdec"
 ogg_demuxer_select="golomb"
 psp_muxer_select="mov_muxer"
 rtp_demuxer_select="sdp_demuxer"
-rtp_muxer_select="mpegvideo"
 rtpdec_select="asf_demuxer rm_demuxer rtp_protocol mpegts_demuxer mov_demuxer"
 rtsp_demuxer_select="http_protocol rtpdec"
 rtsp_muxer_select="rtp_muxer http_protocol rtp_protocol rtpenc_chain"
@@ -1708,15 +1912,22 @@ 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"
+w64_demuxer_select="wav_demuxer"
+wav_demuxer_select="riffdec"
+wav_muxer_select="riffenc"
+webm_muxer_select="riffenc"
+wtv_demuxer_select="riffdec"
+xmv_demuxer_select="riffdec"
+xwma_demuxer_select="riffdec"
 
 # indevs / outdevs
 alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp"
 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"
-dv1394_indev_deps="dv1394 dv_demuxer"
+dv1394_indev_deps="dv1394"
+dv1394_indev_select="dv_demuxer"
 fbdev_indev_deps="linux_fb_h"
-jack_indev_deps="jack_jack_h"
+jack_indev_deps="jack_jack_h pthreads"
 libcdio_indev_deps="libcdio"
 libdc1394_indev_deps="libdc1394"
 oss_indev_deps_any="soundcard_h sys_soundcard_h"
@@ -1757,10 +1968,13 @@ rtmpts_protocol_select="ffrtmphttp_protocol https_protocol"
 rtp_protocol_select="udp_protocol"
 sctp_protocol_deps="struct_sctp_event_subscribe"
 sctp_protocol_select="network"
+srtp_protocol_select="rtp_protocol"
 tcp_protocol_select="network"
 tls_protocol_deps_any="openssl gnutls"
 tls_protocol_select="tcp_protocol"
 udp_protocol_select="network"
+unix_protocol_deps="sys_un_h"
+unix_protocol_select="network"
 
 # filters
 blackframe_filter_deps="gpl"
@@ -1773,11 +1987,16 @@ frei0r_filter_extralibs='$ldl'
 frei0r_src_filter_deps="frei0r dlopen strtok_r"
 frei0r_src_filter_extralibs='$ldl'
 hqdn3d_filter_deps="gpl"
+interlace_filter_deps="gpl"
 resample_filter_deps="avresample"
 ocv_filter_deps="libopencv"
 scale_filter_deps="swscale"
 yadif_filter_deps="gpl"
 
+# examples
+output_example_deps="avcodec avformat avutil swscale"
+transcode_aac_example_deps="avcodec avformat avresample"
+
 # libraries
 avcodec_deps="avutil"
 avdevice_deps="avutil avcodec avformat"
@@ -1788,16 +2007,19 @@ swscale_deps="avutil"
 
 # programs
 avconv_deps="avcodec avfilter avformat avresample swscale"
-avconv_select="aformat_filter anull_filter asyncts_filter format_filter
+avconv_select="aformat_filter anull_filter asyncts_filter atrim_filter format_filter
                fps_filter null_filter resample_filter scale_filter
-               setpts_filter"
+               setpts_filter trim_filter"
 avplay_deps="avcodec avformat avresample swscale sdl"
 avplay_select="rdft"
 avprobe_deps="avcodec avformat"
-avserver_deps="avformat ffm_muxer fork rtp_protocol rtsp_demuxer !shared"
+avserver_deps="avformat fork !shared"
+avserver_select="ffm_muxer rtp_protocol rtsp_demuxer"
 avserver_extralibs='$ldl'
 
-doc_deps="texi2html"
+# documentation
+pod2man_deps="doc"
+texi2html_deps="doc"
 
 # default parameters
 
@@ -1807,6 +2029,7 @@ logfile="config.log"
 prefix_default="/usr/local"
 bindir_default='${prefix}/bin'
 datadir_default='${prefix}/share/avconv'
+docdir_default='${prefix}/share/doc/libav'
 incdir_default='${prefix}/include'
 libdir_default='${prefix}/lib'
 mandir_default='${prefix}/share/man'
@@ -1817,11 +2040,12 @@ ar_default="ar"
 cc_default="gcc"
 host_cc_default="gcc"
 cp_f="cp -f"
-ln_s="ln -sf"
+ln_s="ln -s -f"
 nm_default="nm -g"
 objformat="elf"
 pkg_config_default=pkg-config
 ranlib="ranlib"
+strip="strip"
 yasmexe="yasm"
 
 nogas=":"
@@ -1835,7 +2059,7 @@ target_os_default=$(tolower $(uname -s))
 host_os=$target_os_default
 
 # configurable options
-enable $LIBRARY_LIST $PROGRAM_LIST
+enable $EXAMPLE_LIST $LIBRARY_LIST $PROGRAM_LIST
 
 enable asm
 enable debug
@@ -1850,7 +2074,6 @@ enable dxva2 vdpau
 
 # build settings
 SHFLAGS='-shared -Wl,-soname,$$(@F)'
-AVSERVERLDFLAGS=-Wl,-E
 LIBPREF="lib"
 LIBSUF=".a"
 FULLNAME='$(NAME)$(BUILDSUF)'
@@ -1877,10 +2100,12 @@ LD_O='-o $@'
 LD_LIB='-l%'
 LD_PATH='-L'
 HOSTCC_C='-c'
+HOSTCC_E='-E -o $@'
 HOSTCC_O='-o $@'
 HOSTLD_O='-o $@'
 
-host_cflags='-D_ISOC99_SOURCE -D_XOPEN_SOURCE=600 -O3 -g'
+host_cflags='-O3'
+host_cppflags='-D_ISOC99_SOURCE'
 host_libs='-lm'
 host_cflags_filter=echo
 host_ldflags_filter=echo
@@ -1949,8 +2174,6 @@ for n in $COMPONENT_LIST; do
     eval ${n}_if_any="\$$v"
 done
 
-disable snow_decoder snow_encoder
-
 enable $ARCH_EXT_LIST
 
 die_unknown(){
@@ -1959,10 +2182,14 @@ die_unknown(){
     exit 1
 }
 
+print_3_columns() {
+    cat | tr ' ' '\n' | sort | pr -r -3 -t
+}
+
 show_list() {
     suffix=_$1
     shift
-    echo $* | sed s/$suffix//g | tr ' ' '\n' | sort | pr -3 -t
+    echo $* | sed s/$suffix//g | print_3_columns
     exit 0
 }
 
@@ -2078,33 +2305,84 @@ cc_default="${cross_prefix}${cc_default}"
 nm_default="${cross_prefix}${nm_default}"
 pkg_config_default="${cross_prefix}${pkg_config_default}"
 ranlib="${cross_prefix}${ranlib}"
+strip="${cross_prefix}${strip}"
 
 sysinclude_default="${sysroot}/usr/include"
 
 case "$toolchain" in
     clang-asan)
         cc_default="clang"
-        add_cflags  -faddress-sanitizer
-        add_ldflags -faddress-sanitizer
+        add_cflags  -fsanitize=address
+        add_ldflags -fsanitize=address
     ;;
     clang-tsan)
         cc_default="clang"
-        add_cflags  -fthread-sanitizer
-        add_ldflags -fthread-sanitizer
+        add_cflags  -fsanitize=thread -pie
+        add_ldflags -fsanitize=thread -pie
+    ;;
+    gcc-asan)
+        cc_default="gcc"
+        add_cflags  -fsanitize=address
+        add_ldflags -fsanitize=address
+    ;;
+    gcc-tsan)
+        cc_default="gcc"
+        add_cflags  -fsanitize=thread -pie -fPIC
+        add_ldflags -fsanitize=thread -pie -fPIC
+    ;;
+    valgrind-massif)
+        target_exec_default="valgrind"
+        target_exec_args="--alloc-fn=av_malloc --alloc-fn=av_mallocz"
+    ;;
+    valgrind-memcheck)
+        target_exec_default="valgrind"
+        target_exec_args="--track-origins=yes --leak-check=full"
     ;;
     msvc)
-        cc_default="c99wrap cl"
-        ld_default="c99wrap link"
+        # Check whether the current MSVC version needs the C99 converter.
+        # From MSVC 2013 (compiler major version 18) onwards, it does actually
+        # support enough of C99 to build libav. Default to the new
+        # behaviour if the regexp was unable to match anything, since this
+        # successfully parses the version number of existing supported
+        # versions that require the converter (MSVC 2010 and 2012).
+        cl_major_ver=$(cl 2>&1 | sed -n 's/.*Version \([[:digit:]]\{1,\}\)\..*/\1/p')
+        if [ -z "$cl_major_ver" ] || [ $cl_major_ver -ge 18 ]; then
+            cc_default="cl"
+        else
+            cc_default="c99wrap cl"
+        fi
+        ld_default="link"
         nm_default="dumpbin -symbols"
         ar_default="lib"
         target_os_default="win32"
+        # Use a relative path for TMPDIR. This makes sure all the
+        # ffconf temp files are written with a relative path, avoiding
+        # issues with msys/win32 path conversion for MSVC parameters
+        # such as -Fo<file> or -out:<file>.
+        TMPDIR=.
+    ;;
+    icl)
+        cc_default="icl"
+        ld_default="xilink"
+        nm_default="dumpbin -symbols"
+        ar_default="xilib"
+        target_os_default="win32"
+        TMPDIR=.
+    ;;
+    gcov)
+        add_cflags  -fprofile-arcs -ftest-coverage
+        add_ldflags -fprofile-arcs -ftest-coverage
+    ;;
+    hardened)
+        add_cflags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all
+        add_ldflags -Wl,-z,relro -Wl,-z,now
     ;;
     ?*)
         die "Unknown toolchain $toolchain"
     ;;
 esac
 
-set_default arch cc pkg_config sysinclude target_os
+set_default arch cc pkg_config sysinclude target_exec target_os
 enabled cross_compile || host_cc_default=$cc
 set_default host_cc
 
@@ -2189,20 +2467,35 @@ ccc_flags(){
    done
 }
 
-msvc_flags(){
+cparser_flags(){
     for flag; do
         case $flag in
-            -fomit-frame-pointer) echo -Oy ;;
-            -g)                   echo -Z7 ;;
-            -Wall)                echo -W4 -wd4244 -wd4127 -wd4018 -wd4389 \
-                                       -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 \
-                                       -wd4152 -wd4324 -we4013 -wd4100 -wd4214 \
-                                       -wd4996 -wd4273 ;;
+            -Wno-switch)             echo -Wno-switch-enum ;;
+            -Wno-format-zero-length) ;;
+            -Wdisabled-optimization) ;;
+            -Wno-pointer-sign)       echo -Wno-other ;;
+            *)                       echo $flag ;;
+        esac
+    done
+}
+
+msvc_common_flags(){
+    for flag; do
+        case $flag in
+            # In addition to specifying certain flags under the compiler
+            # specific filters, they must be specified here as well or else the
+            # generic catch all at the bottom will print the original flag.
+            -Wall)                ;;
             -std=c99)             ;;
+            # Common flags
+            -fomit-frame-pointer) ;;
+            -g)                   echo -Z7 ;;
             -fno-math-errno)      ;;
             -fno-common)          ;;
             -fno-signed-zeros)    ;;
             -fPIC)                ;;
+            -mthumb)              ;;
+            -march=*)             ;;
             -lz)                  echo zlib.lib ;;
             -lavifil32)           echo vfw32.lib ;;
             -lavicap32)           echo vfw32.lib user32.lib ;;
@@ -2212,6 +2505,30 @@ msvc_flags(){
     done
 }
 
+msvc_flags(){
+    msvc_common_flags "$@"
+    for flag; do
+        case $flag in
+            -Wall)                echo -W4 -wd4244 -wd4127 -wd4018 -wd4389     \
+                                       -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 \
+                                       -wd4152 -wd4324 -we4013 -wd4100 -wd4214 \
+                                       -wd4273 ;;
+        esac
+    done
+}
+
+icl_flags(){
+    msvc_common_flags "$@"
+    for flag; do
+        case $flag in
+            # Despite what Intel's documentation says -Wall, which is supported
+            # on Windows, does enable remarks so disable them here.
+            -Wall)                echo $flag -Qdiag-disable:remark ;;
+            -std=c99)             echo -Qstd=c99 ;;
+        esac
+    done
+}
+
 pgi_flags(){
     for flag; do
         case $flag in
@@ -2243,17 +2560,18 @@ suncc_flags(){
                     corei7)           echo -xarch=sse4_2 -xchip=nehalem  ;;
                     corei7-avx)       echo -xarch=avx -xchip=sandybridge ;;
                     amdfam10|barcelona|bdver*) echo -xarch=sse4_1        ;;
-                    athlon-4|athlon-[mx]p)    echo -xarch=ssea           ;;
+                    athlon-4|athlon-[mx]p)     echo -xarch=ssea          ;;
                     k8|opteron|athlon64|athlon-fx)
-                                              echo -xarch=sse2a          ;;
-                    athlon*)                  echo -xarch=pentium_proa   ;;
+                                               echo -xarch=sse2a         ;;
+                    athlon*)                   echo -xarch=pentium_proa  ;;
                 esac
                 ;;
             -std=c99)             echo -xc99              ;;
             -fomit-frame-pointer) echo -xregs=frameptr    ;;
             -fPIC)                echo -KPIC -xcode=pic32 ;;
             -W*,*)                echo $flag              ;;
-            -f*-*|-W*)                                    ;;
+            -f*-*|-W*|-mimpure-text)                      ;;
+            -shared)              echo -G                 ;;
             *)                    echo $flag              ;;
         esac
     done
@@ -2316,7 +2634,7 @@ probe_cc(){
         fi
         _cflags_speed='-O3'
         _cflags_size='-Os'
-    elif $_cc --version 2>/dev/null | grep -q Intel; then
+    elif $_cc --version 2>/dev/null | grep -q ^icc; then
         _type=icc
         _ident=$($_cc --version | head -n1)
         _depflags='-MMD'
@@ -2405,22 +2723,54 @@ probe_cc(){
         _DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
         _cflags_speed="-O2"
         _cflags_size="-O1"
-        # Nonstandard output options, to avoid msys path conversion issues, relies on wrapper to remap it
         if $_cc 2>&1 | grep -q Linker; then
-            _ld_o='-out $@'
+            _ld_o='-out:$@'
         else
             _ld_o='-Fe$@'
         fi
-        _cc_o='-Fo $@'
-        _cc_e='-P -Fi $@'
+        _cc_o='-Fo$@'
+        _cc_e='-P -Fi$@'
         _flags_filter=msvc_flags
         _ld_lib='lib%.a'
         _ld_path='-libpath:'
         _flags='-nologo'
-        _cflags='-D_USE_MATH_DEFINES -Dinline=__inline -FIstdlib.h -Dstrtoll=_strtoi64'
+        _cflags='-D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -Dinline=__inline -FIstdlib.h -Dstrtoll=_strtoi64'
+        if [ $pfx = hostcc ]; then
+            append _cflags -Dsnprintf=_snprintf
+        fi
+    elif $_cc 2>&1 | grep -q Intel; then
+        _type=icl
+        _ident=$($cc 2>&1 | head -n1)
+        _depflags='-QMMD -QMF$(@:.o=.d) -QMT$@'
+        # Not only is O3 broken on 13.x+ but it is slower on all previous
+        # versions (tested) as well.
+        _cflags_speed="-O2"
+        _cflags_size="-O1 -Oi" # -O1 without -Oi miscompiles stuff
+        if $_cc 2>&1 | grep -q Linker; then
+            _ld_o='-out:$@'
+        else
+            _ld_o='-Fe$@'
+        fi
+        _cc_o='-Fo$@'
+        _cc_e='-P'
+        _flags_filter=icl_flags
+        _ld_lib='lib%.a'
+        _ld_path='-libpath:'
+        # -Qdiag-error to make icl error when seeing certain unknown arguments
+        _flags='-nologo -Qdiag-error:4044,10157'
+        # -Qvec- -Qsimd- to prevent miscompilation, -GS for consistency
+        # with MSVC which enables it by default.
+        _cflags='-D_USE_MATH_DEFINES -FIstdlib.h -Dstrtoll=_strtoi64 -Qms0 -Qvec- -Qsimd- -GS'
         if [ $pfx = hostcc ]; then
             append _cflags -Dsnprintf=_snprintf
         fi
+    elif $_cc --version 2>/dev/null | grep -q ^cparser; then
+        _type=cparser
+        _ident=$($_cc --version | head -n1)
+        _depflags='-MMD'
+        _cflags_speed='-O4'
+        _cflags_size='-O2'
+        _flags_filter=cparser_flags
     fi
 
     eval ${pfx}_type=\$_type
@@ -2495,6 +2845,9 @@ if $ar 2>&1 | grep -q Microsoft; then
 elif $ar 2>&1 | grep -q 'Texas Instruments'; then
     arflags="rq"
     ar_o='$@'
+elif $ar 2>&1 | grep -q 'Usage: ar.*-X.*any'; then
+    arflags='-Xany -r -c'
+    ar_o='$@'
 else
     arflags="rc"
     ar_o='$@'
@@ -2517,7 +2870,8 @@ if test -n "$sysroot"; then
 fi
 
 if test "$cpu" = host; then
-    enabled cross_compile && die "--cpu=host makes no sense when cross-compiling."
+    enabled cross_compile &&
+        die "--cpu=host makes no sense when cross-compiling."
 
     case "$cc_type" in
         gcc|llvm_gcc)
@@ -2533,7 +2887,8 @@ if test "$cpu" = host; then
         ;;
     esac
 
-    test "${cpu:-host}" = host && die "--cpu=host not supported with compiler $cc"
+    test "${cpu:-host}" = host &&
+        die "--cpu=host not supported with compiler $cc"
 fi
 
 # Deal with common $arch aliases
@@ -2743,21 +3098,21 @@ elif enabled x86; then
             cpuflags="-march=$cpu"
             disable mmx
         ;;
-        # targets that do NOT support conditional mov (cmov)
+        # targets that do NOT support nopl and conditional mov (cmov)
         pentium-mmx|k6|k6-[23]|winchip-c6|winchip2|c3)
             cpuflags="-march=$cpu"
-            disable cmov
+            disable i686
         ;;
-        # targets that do support conditional mov (cmov)
+        # targets that do support nopl and conditional mov (cmov)
         i686|pentiumpro|pentium[23]|pentium-m|athlon|athlon-tbird|athlon-4|athlon-[mx]p|athlon64*|k8*|opteron*|athlon-fx|core2|corei7*|amdfam10|barcelona|atom|bdver*)
             cpuflags="-march=$cpu"
-            enable cmov
+            enable i686
             enable fast_cmov
         ;;
         # targets that do support conditional mov but on which it's slow
         pentium4|pentium4m|prescott|nocona)
             cpuflags="-march=$cpu"
-            enable cmov
+            enable i686
             disable fast_cmov
         ;;
     esac
@@ -2831,27 +3186,32 @@ case "$arch" in
 esac
 
 enable $subarch
-enabled spic && enable pic
+enabled spic && enable_weak pic
 
 # OS specific
 case $target_os in
+    aix)
+        SHFLAGS=-shared
+        add_cppflags '-I\$(SRC_PATH)/compat/aix'
+        enabled shared && add_ldflags -Wl,-brtl
+        ;;
     haiku)
         prefix_default="/boot/common"
         network_extralibs="-lnetwork"
         host_libs=
         ;;
     sunos)
-        AVSERVERLDFLAGS=""
         SHFLAGS='-shared -Wl,-h,$$(@F)'
         enabled x86 && SHFLAGS="-mimpure-text $SHFLAGS"
         network_extralibs="-lsocket -lnsl"
-        add_cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
         # When using suncc to build, the Solaris linker will mark
         # an executable with each instruction set encountered by
         # the Solaris assembler.  As our libraries contain their own
         # guards for processor-specific code, instead suppress
         # generation of the HWCAPS ELF section on Solaris x86 only.
-        enabled_all suncc x86 && echo "hwcap_1 = OVERRIDE;" > mapfile && add_ldflags -Wl,-M,mapfile
+        enabled_all suncc x86 &&
+            echo "hwcap_1 = OVERRIDE;" > mapfile &&
+            add_ldflags -Wl,-M,mapfile
         nm_default='nm -P -g'
         ;;
     netbsd)
@@ -2860,15 +3220,9 @@ case $target_os in
         oss_outdev_extralibs="-lossaudio"
         ;;
     openbsd|bitrig)
-        # On OpenBSD 4.5. the compiler does not use PIC unless
-        # explicitly using -fPIC. Libav builds fine without PIC,
-        # however the generated executable will not do anything
-        # (simply quits with exit-code 1, no crash, no output).
-        # Thus explicitly enable PIC here.
-        enable pic
         disable symver
         SHFLAGS='-shared'
-        SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBVERSION)'
+        SLIB_INSTALL_NAME='$(SLIBNAME).$(LIBMAJOR).$(LIBMINOR)'
         SLIB_INSTALL_LINKS=
         oss_indev_extralibs="-lossaudio"
         oss_outdev_extralibs="-lossaudio"
@@ -2890,7 +3244,6 @@ case $target_os in
         SLIBSUF=".dylib"
         SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME).$(LIBVERSION)$(SLIBSUF)'
         SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME).$(LIBMAJOR)$(SLIBSUF)'
-        AVSERVERLDFLAGS=-Wl,-bind_at_load
         objformat="macho"
         enabled x86_64 && objformat="macho64"
         enabled_any pic shared ||
@@ -2908,6 +3261,8 @@ case $target_os in
         elif enabled arm; then
             LIBTARGET=arm-wince
         fi
+        check_ldflags -Wl,--nxcompat
+        check_ldflags -Wl,--dynamicbase
         shlibdir_default="$bindir_default"
         SLIBPREF=""
         SLIBSUF=".dll"
@@ -2923,15 +3278,14 @@ case $target_os in
         dlltool="${cross_prefix}dlltool"
         ranlib=:
         enable dos_paths
-        add_cppflags -U__STRICT_ANSI__
         ;;
     win32|win64)
+        disable symver
         if enabled shared; then
             # Link to the import library instead of the normal static library
             # for shared libs.
             LD_LIB='%.lib'
-            # Cannot build shared and static libraries at the same time with
-            # MSVC.
+            # Cannot build both shared and static libs with MSVC or icl.
             disable static
         fi
         shlibdir_default="$bindir_default"
@@ -2939,7 +3293,7 @@ case $target_os in
         SLIBSUF=".dll"
         SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
         SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
-        SLIB_CREATE_DEF_CMD='makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)'
+        SLIB_CREATE_DEF_CMD='$(SRC_PATH)/compat/windows/makedef $(SUBDIR)lib$(NAME).ver $(OBJS) > $$(@:$(SLIBSUF)=.def)'
         SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
         SLIB_INSTALL_LINKS=
         SLIB_INSTALL_EXTRA_SHLIB='$(SLIBNAME:$(SLIBSUF)=.lib)'
@@ -2982,7 +3336,6 @@ case $target_os in
         add_cppflags -D_GNU_SOURCE
         add_ldflags -Zomf -Zbin-files -Zargs-wild -Zmap
         SHFLAGS='$(SUBDIR)$(NAME).def -Zdll -Zomf'
-        AVSERVERLDFLAGS=""
         LIBSUF="_s.a"
         SLIBPREF=""
         SLIBSUF=".dll"
@@ -3022,7 +3375,6 @@ case $target_os in
         ;;
     osf1)
         add_cppflags -D_OSF_SOURCE -D_POSIX_PII -D_REENTRANT
-        AVSERVERLDFLAGS=
         ;;
     minix)
         ;;
@@ -3036,7 +3388,6 @@ case $target_os in
         network_extralibs='-lbsd'
         exeobjs=compat/plan9/main.o
         disable avserver
-        ln_s='ln -s -f'
         cp_f='cp'
         ;;
     none)
@@ -3048,36 +3399,75 @@ esac
 
 # determine libc flavour
 
-if check_cpp_condition features.h "defined __UCLIBC__"; then
-    libc_type=uclibc
-    add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
-elif check_cpp_condition features.h "defined __GLIBC__"; then
-    libc_type=glibc
-    add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
-elif check_header _mingw.h; then
-    libc_type=mingw
-    check_cpp_condition _mingw.h \
-        "defined (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION > 3) || \
+probe_libc(){
+    pfx=$1
+    pfx_no_=${pfx%_}
+    # uclibc defines __GLIBC__, so it needs to be checked before glibc.
+    if check_${pfx}cpp_condition features.h "defined __UCLIBC__"; then
+        eval ${pfx}libc_type=uclibc
+        add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
+    elif check_${pfx}cpp_condition features.h "defined __GLIBC__"; then
+        eval ${pfx}libc_type=glibc
+        add_${pfx}cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600
+    # MinGW headers can be installed on Cygwin, so check for newlib first.
+    elif check_${pfx}cpp_condition newlib.h "defined _NEWLIB_VERSION"; then
+        eval ${pfx}libc_type=newlib
+        add_${pfx}cppflags -U__STRICT_ANSI__
+    # MinGW64 is backwards compatible with MinGW32, so check for it first.
+    elif check_${pfx}cpp_condition _mingw.h "defined __MINGW64_VERSION_MAJOR"; then
+        eval ${pfx}libc_type=mingw64
+        add_${pfx}cppflags -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1
+        eval test \$${pfx_no_}cc_type = "gcc" &&
+            add_${pfx}cppflags -D__printf__=__gnu_printf__
+    elif check_${pfx}cpp_condition _mingw.h "defined __MINGW_VERSION"  ||
+         check_${pfx}cpp_condition _mingw.h "defined __MINGW32_VERSION"; then
+        eval ${pfx}libc_type=mingw32
+        check_${pfx}cpp_condition _mingw.h "__MINGW32_MAJOR_VERSION > 3 || \
             (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 15)" ||
-        die "ERROR: MinGW runtime version must be >= 3.15."
-elif check_cpp_condition newlib.h "defined _NEWLIB_VERSION"; then
-    libc_type=newlib
-    add_cppflags -U__STRICT_ANSI__
-elif check_func_headers stdlib.h _get_doserrno; then
-    libc_type=msvcrt
-    add_compat strtod.o strtod=avpriv_strtod
-    add_compat msvcrt/snprintf.o snprintf=avpriv_snprintf   \
-                                 _snprintf=avpriv_snprintf  \
-                                 vsnprintf=avpriv_vsnprintf
-elif check_cpp_condition stddef.h "defined __KLIBC__"; then
-    libc_type=klibc
-fi
+            die "ERROR: MinGW32 runtime version must be >= 3.15."
+        add_${pfx}cppflags -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1
+        eval test \$${pfx_no_}cc_type = "gcc" &&
+            add_${pfx}cppflags -D__printf__=__gnu_printf__
+    elif check_${pfx}cpp_condition crtversion.h "defined _VC_CRT_MAJOR_VERSION"; then
+        eval ${pfx}libc_type=msvcrt
+        # The MSVC 2010 headers (Win 7.0 SDK) set _WIN32_WINNT to
+        # 0x601 by default unless something else is set by the user.
+        # This can easily lead to us detecting functions only present
+        # in such new versions and producing binaries requiring windows 7.0.
+        # Therefore explicitly set the default to XP unless the user has
+        # set something else on the command line.
+        check_${pfx}cpp_condition stdlib.h "defined(_WIN32_WINNT)" ||
+            add_${pfx}cppflags -D_WIN32_WINNT=0x0502
+    elif check_${pfx}cpp_condition stddef.h "defined __KLIBC__"; then
+        eval ${pfx}libc_type=klibc
+    elif check_${pfx}cpp_condition sys/cdefs.h "defined __BIONIC__"; then
+        eval ${pfx}libc_type=bionic
+    elif check_${pfx}cpp_condition sys/brand.h "defined LABELED_BRAND_NAME"; then
+        eval ${pfx}libc_type=solaris
+        add_${pfx}cppflags -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
+    fi
+}
 
-test -n "$libc_type" && enable $libc_type
+probe_libc
+test -n "$libc_type" && enable libc_$libc_type
+probe_libc host_
+test -n "$host_libc_type" && enable host_libc_$host_libc_type
+
+case $libc_type in
+    bionic)
+        add_compat strtod.o strtod=avpriv_strtod
+        ;;
+    msvcrt)
+        add_compat strtod.o strtod=avpriv_strtod
+        add_compat msvcrt/snprintf.o snprintf=avpriv_snprintf   \
+                                     _snprintf=avpriv_snprintf  \
+                                     vsnprintf=avpriv_vsnprintf
+        ;;
+esac
 
 # hacks for compiler/libc/os combinations
 
-if enabled_all tms470 glibc; then
+if enabled_all tms470 libc_glibc; then
     CPPFLAGS="-I${source_path}/compat/tms470 ${CPPFLAGS}"
     add_cppflags -D__USER_LABEL_PREFIX__=
     add_cppflags -D__builtin_memset=memset
@@ -3085,7 +3475,7 @@ if enabled_all tms470 glibc; then
     add_cflags   -pds=48    # incompatible redefinition of macro
 fi
 
-if enabled_all ccc glibc; then
+if enabled_all ccc libc_glibc; then
     add_ldflags -Wl,-z,now  # calls to libots crash without this
 fi
 
@@ -3095,7 +3485,7 @@ esc(){
 
 echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $LIBAV_CONFIGURATION)" >config.fate
 
-check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable pic
+check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable_weak pic
 
 set_default $PATHS_LIST
 set_default nm
@@ -3134,14 +3524,21 @@ enabled version3 && { enabled gpl && enable gplv3 || enable lgplv3; }
 
 disabled optimizations || check_cflags -fomit-frame-pointer
 
-enable_pic() {
+enable_weak_pic() {
+    disabled pic && return
     enable pic
     add_cppflags -DPIC
-    add_cflags   -fPIC
+    case "$target_os" in
+    mingw*|cygwin*)
+        ;;
+    *)
+        add_cflags -fPIC
+        ;;
+    esac
     add_asflags  -fPIC
 }
 
-enabled pic && enable_pic
+enabled pic && enable_weak_pic
 
 check_cc <<EOF || die "Symbol mangling check failed."
 int ff_extern;
@@ -3160,6 +3557,10 @@ void foo(char * $restrict_keyword p);
 EOF
 done
 
+check_cc <<EOF && enable pragma_deprecated
+void foo(void) { _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") }
+EOF
+
 check_cc <<EOF && enable attribute_packed
 struct { int x; } __attribute__((packed)) x;
 EOF
@@ -3173,6 +3574,8 @@ unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E';
 EOF
 od -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian
 
+check_inline_asm inline_asm_labels '"1:\n"'
+
 if enabled alpha; then
 
     check_cflags -mieee
@@ -3210,7 +3613,7 @@ EOF
     check_inline_asm asm_mod_q '"add r0, %Q0, %R0" :: "r"((long long)0)'
     check_inline_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)'
 
-    enabled_all armv6t2 shared !pic && enable_pic
+    [ $target_os != win32 ] && enabled_all armv6t2 shared !pic && enable_weak_pic
 
 elif enabled mips; then
 
@@ -3260,9 +3663,8 @@ elif enabled sparc; then
 
 elif enabled x86; then
 
-    check_code ld intrin.h "__rdtsc()" && enable rdtsc
-
-    check_code ld mmintrin.h "_mm_empty()" && enable mm_empty
+    check_builtin rdtsc    intrin.h   "__rdtsc()"
+    check_builtin mm_empty mmintrin.h "_mm_empty()"
 
     enable local_aligned_8 local_aligned_16
 
@@ -3304,8 +3706,8 @@ EOF
             elf*) enabled debug && append YASMFLAGS $yasm_debug ;;
         esac
 
-        check_yasm "vextractf128 xmm0, ymm0, 0" && enable yasm ||
-            die "yasm not found, use --disable-yasm for a crippled build"
+        check_yasm "movbe ecx, [5]" && enable yasm ||
+            die "yasm/nasm not found or too old. Use --disable-yasm for a crippled build."
         check_yasm "vfmaddps ymm0, ymm1, ymm2, ymm3" || disable fma4_external
         check_yasm "CPU amdnop" && enable cpunop
     fi
@@ -3378,6 +3780,7 @@ check_func nanosleep || { check_func nanosleep -lrt && add_extralibs -lrt; }
 
 check_func  fcntl
 check_func  fork
+check_func_headers stdlib.h getenv
 check_func  gethrtime
 check_func  getopt
 check_func  getrusage
@@ -3397,6 +3800,10 @@ check_func  strerror_r
 check_func  strptime
 check_func  strtok_r
 check_func  sched_getaffinity
+check_builtin sync_val_compare_and_swap "" "int *ptr; int oldval, newval; __sync_val_compare_and_swap(ptr, oldval, newval)"
+check_builtin machine_rw_barrier mbarrier.h "__machine_rw_barrier()"
+check_builtin atomic_cas_ptr atomic.h "void **ptr; void *oldval, *newval; atomic_cas_ptr(ptr, oldval, newval)"
+check_builtin MemoryBarrier windows.h "MemoryBarrier()"
 check_func  sysconf
 check_func  sysctl
 check_func  usleep
@@ -3424,15 +3831,14 @@ check_header sys/param.h
 check_header sys/resource.h
 check_header sys/select.h
 check_header sys/time.h
+check_header sys/un.h
 check_header unistd.h
 check_header vdpau/vdpau.h
 check_header vdpau/vdpau_x11.h
+check_header VideoDecodeAcceleration/VDADecoder.h
 check_header windows.h
 check_header X11/extensions/XvMClib.h
 
-disabled  zlib || check_lib   zlib.h      zlibVersion -lz   || disable  zlib
-disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib
-
 if ! disabled w32threads && ! enabled pthreads; then
     check_func_headers "windows.h process.h" _beginthreadex && enable w32threads
 fi
@@ -3441,17 +3847,17 @@ fi
 # do this before the optional library checks as some of them require pthreads
 if ! disabled pthreads && ! enabled w32threads; then
     enable pthreads
-    if check_func pthread_create; then
-        :
-    elif check_func pthread_create -pthread; then
+    if check_func pthread_join -pthread; then
         add_cflags -pthread
         add_extralibs -pthread
-    elif check_func pthread_create -pthreads; then
+    elif check_func pthread_join -pthreads; then
         add_cflags -pthreads
         add_extralibs -pthreads
-    elif check_func pthread_create -lpthreadGC2; then
+    elif check_func pthread_join -lpthreadGC2; then
         add_extralibs -lpthreadGC2
-    elif ! check_lib pthread.h pthread_create -lpthread; then
+    elif check_lib pthread.h pthread_join -lpthread; then
+        :
+    elif ! check_func pthread_join; then
         disable pthreads
     fi
 fi
@@ -3464,6 +3870,13 @@ for thread in $THREADS_LIST; do
     fi
 done
 
+disabled  zlib || check_lib   zlib.h      zlibVersion -lz   || disable  zlib
+disabled bzlib || check_lib2 bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib
+
+enabled sync_val_compare_and_swap && enable atomics_gcc
+enabled_all atomic_cas_ptr machine_rw_barrier && enable atomics_suncc
+enabled MemoryBarrier && enable atomics_win32
+
 check_lib math.h sin -lm && LIBM="-lm"
 enabled vaapi && require vaapi va/va.h vaInitialize -lva
 
@@ -3476,42 +3889,49 @@ for func in $MATH_FUNCS; do
 done
 
 # these are off by default, so fail if requested and not available
-enabled avisynth   && require2 vfw32 "windows.h vfw.h" AVIFileInit -lavifil32
-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 libfaac    && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
-enabled libfdk_aac && require  libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
-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 libmp3lame && require  "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
-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 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 libtheora  && require  libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
-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 VPX_CQ" -lvpx ||
-                                die "ERROR: libvpx encoder version must be >=0.9.6"; } }
-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."; }
-enabled libxavs    && require  libxavs xavs.h xavs_encoder_encode -lxavs
-enabled libxvid    && require  libxvid xvid.h xvid_global -lxvidcore
-enabled openssl    && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
-                        check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
-                        check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
-                        die "ERROR: openssl not found"; }
+enabled avisynth          && { { check_header "avisynth/avisynth_c.h" && check_lib2 "windows.h" LoadLibrary; } ||
+                               { check_header "avxsynth/avxsynth_c.h" && check_lib2 "dlfcn.h" dlopen -ldl; } ||
+                               die "ERROR: LoadLibrary/dlopen not found, or avisynth header not found"; }
+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 libfaac           && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
+enabled libfdk_aac        && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
+enabled libfreetype       && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType
+enabled libgsm            && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
+                                   check_lib "${gsm_hdr}" gsm_create -lgsm && break;
+                               done || die "ERROR: libgsm not found"; }
+enabled libilbc           && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
+enabled libmp3lame        && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
+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 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 libtheora         && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
+enabled libvo_aacenc      && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc
+enabled libvo_amrwbenc    && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
+enabled libvorbis         && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
+enabled libvpx            && {
+    enabled libvpx_vp8_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_dec_init_ver -lvpx ||
+                                    die "ERROR: libvpx decoder version must be >=0.9.1"; }
+    enabled libvpx_vp8_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_enc_init_ver VPX_CQ" -lvpx ||
+                                    die "ERROR: libvpx encoder version must be >=0.9.6"; }
+    enabled libvpx_vp9_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx || disable libvpx_vp9_decoder; }
+    enabled libvpx_vp9_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx" -lvpx || disable libvpx_vp9_encoder; } }
+enabled libwavpack        && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput  -lwavpack
+enabled libx264           && require libx264 x264.h x264_encoder_encode -lx264 &&
+                             { check_cpp_condition x264.h "X264_BUILD >= 118" ||
+                               die "ERROR: libx264 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 openssl           && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
+                               check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
+                               check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
+                               die "ERROR: openssl not found"; }
 
 if enabled gnutls; then
     { check_lib nettle/bignum.h nettle_mpz_get_str_256 -lnettle -lhogweed -lgmp && enable nettle; } ||
@@ -3529,10 +3949,11 @@ fi
 
 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
+    check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x010300" $sdl_cflags &&
+    enable sdl
 fi
 
+pod2man --help     > /dev/null 2>&1 && enable pod2man   || disable pod2man
 texi2html -version > /dev/null 2>&1 && enable texi2html || disable texi2html
 
 check_header linux/fb.h
@@ -3559,7 +3980,8 @@ check_header sndio.h
 check_header sys/soundcard.h
 check_header soundcard.h
 
-enabled_any alsa_indev alsa_outdev && check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound
+enabled_any alsa_indev alsa_outdev &&
+    check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound
 
 enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack &&
     check_func jack_port_get_latency_range -ljack
@@ -3567,36 +3989,33 @@ enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack &&
 enabled_any sndio_indev sndio_outdev && check_lib2 sndio.h sio_open -lsndio
 
 if enabled libcdio; then
-    check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio || check_lib2 "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio
+    check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio ||
+    check_lib2 "cdio/paranoia/cdda.h cdio/paranoia/paranoia.h" cdio_cddap_open -lcdio_paranoia -lcdio_cdda -lcdio
 fi
 
+check_lib X11/Xlib.h XOpenDisplay -lX11 && enable xlib
+
 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
+require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes &&
+{ enabled xlib || die "ERROR: Xlib not found"; }
 
-# check for VDA header
-if ! disabled vda && check_header VideoDecodeAcceleration/VDADecoder.h; then
-    enable vda && add_extralibs -framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore
-fi
-
-if ! disabled vdpau && enabled vdpau_vdpau_h; then
+enabled vdpau &&
     check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" ||
-        { echolog "Please upgrade to libvdpau >= 0.2 if you would like vdpau support." && disable vdpau; }
-fi
+    disable vdpau
+
+enabled vdpau && enabled xlib &&
+    check_lib2 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau &&
+    enable vdpau_x11
 
 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
 
 # add some useful compiler flags if supported
 check_cflags -Wdeclaration-after-statement
 check_cflags -Wall
-check_cflags -Wno-parentheses
-check_cflags -Wno-switch
-check_cflags -Wno-format-zero-length
 check_cflags -Wdisabled-optimization
 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
@@ -3605,18 +4024,32 @@ check_cflags -Wmissing-prototypes
 check_cflags -Wstrict-prototypes
 enabled extra_warnings && check_cflags -Winline
 
+check_disable_warning(){
+    warning_flag=-W${1#-Wno-}
+    test_cflags $warning_flag && add_cflags $1
+}
+
+check_disable_warning -Wno-parentheses
+check_disable_warning -Wno-switch
+check_disable_warning -Wno-format-zero-length
+check_disable_warning -Wno-pointer-sign
+
 # add some linker flags
 check_ldflags -Wl,--warn-common
 check_ldflags -Wl,-rpath-link=libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
 test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic
 
+# add some strip flags
+# -wN '..@*' is more selective than -x, but not available everywhere.
+check_stripflags -wN \'..@*\' || check_stripflags -x || strip='true'
+
 enabled xmm_clobber_test &&
     check_ldflags -Wl,--wrap,avcodec_open2              \
                   -Wl,--wrap,avcodec_decode_audio4      \
                   -Wl,--wrap,avcodec_decode_video2      \
                   -Wl,--wrap,avcodec_decode_subtitle2   \
                   -Wl,--wrap,avcodec_encode_audio2      \
-                  -Wl,--wrap,avcodec_encode_video       \
+                  -Wl,--wrap,avcodec_encode_video2      \
                   -Wl,--wrap,avcodec_encode_subtitle    \
                   -Wl,--wrap,sws_scale ||
     disable xmm_clobber_test
@@ -3674,8 +4107,6 @@ if enabled icc; then
     # 11030: Warning unknown option --as-needed
     # 10156: ignoring option '-export'; no argument required
     check_ldflags -wd10156,11030
-    # Allow to compile with optimizations
-    check_ldflags -march=$cpu
     # icc 11.0 and 11.1 work with ebp_available, but don't pass the test
     enable ebp_available
     if enabled x86_32; then
@@ -3694,8 +4125,10 @@ elif enabled gcc; then
     check_optflags -fno-tree-vectorize
     check_cflags -Werror=implicit-function-declaration
     check_cflags -Werror=missing-prototypes
+    check_cflags -Werror=return-type
     check_cflags -Werror=declaration-after-statement
     check_cflags -Werror=vla
+    enabled extra_warnings || check_disable_warning -Wno-maybe-uninitialized
 elif enabled llvm_gcc; then
     check_cflags -mllvm -stack-alignment=16
 elif enabled clang; then
@@ -3703,6 +4136,10 @@ elif enabled clang; then
     check_cflags -Qunused-arguments
     check_cflags -Werror=implicit-function-declaration
     check_cflags -Werror=missing-prototypes
+    check_cflags -Werror=return-type
+elif enabled cparser; then
+    add_cflags -Wno-missing-variable-declarations
+    add_cflags -Wno-empty-statement
 elif enabled armcc; then
     # 2523: use of inline assembler is deprecated
     add_cflags -W${armcc_opt},--diag_suppress=2523
@@ -3713,10 +4150,23 @@ elif enabled armcc; then
     add_cflags -W${armcc_opt},--diag_suppress=513  # pointer sign
 elif enabled tms470; then
     add_cflags -pds=824 -pds=837
+    disable inline_asm
 elif enabled pathscale; then
     add_cflags -fstrict-overflow -OPT:wrap_around_unsafe_opt=OFF
-elif enabled msvc; then
+elif enabled_any msvc icl; then
     enabled x86_32 && disable aligned_stack
+    enabled_all x86_32 debug && add_cflags -Oy-
+    enabled debug && add_ldflags -debug
+    enable pragma_deprecated
+    if enabled icl; then
+        # -Qansi-alias is basically -fstrict-aliasing, but does not work
+        # (correctly) on icl 13.x.
+        check_cpp_condition "windows.h" "__ICL < 1300 || __ICL >= 1400" &&
+            add_cflags -Qansi-alias
+        # icl will pass the inline asm tests but inline asm is currently
+        # not supported (build will fail)
+        disable inline_asm
+    fi
 fi
 
 case $target_os in
@@ -3729,6 +4179,7 @@ case $target_os in
 esac
 
 enabled_any $THREADS_LIST      && enable threads
+enabled_any $ATOMICS_LIST      && enable atomics_native
 
 enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; }
 
@@ -3743,6 +4194,11 @@ check_deps $CONFIG_LIST       \
 echo "install prefix            $prefix"
 echo "source path               $source_path"
 echo "C compiler                $cc"
+echo "C library                 $libc_type"
+if test "$host_cc" != "$cc"; then
+    echo "host C compiler           $host_cc"
+    echo "host C library            $host_libc_type"
+fi
 echo "ARCH                      $arch ($cpu)"
 if test "$build_suffix" != ""; then
     echo "build suffix              $build_suffix"
@@ -3762,7 +4218,7 @@ if enabled x86; then
     echo "SSSE3 enabled             ${ssse3-no}"
     echo "AVX enabled               ${avx-no}"
     echo "FMA4 enabled              ${fma4-no}"
-    echo "CMOV enabled              ${cmov-no}"
+    echo "i686 features enabled     ${i686-no}"
     echo "CMOV is fast              ${fast_cmov-no}"
     echo "EBX available             ${ebx_available-no}"
     echo "EBP available             ${ebp_available-no}"
@@ -3792,47 +4248,18 @@ echo "network support           ${network-no}"
 echo "threading support         ${thread_type-no}"
 echo "safe bitstream reader     ${safe_bitstream_reader-no}"
 echo "SDL support               ${sdl-no}"
-echo "libdxva2 enabled          ${dxva2-no}"
-echo "libva enabled             ${vaapi-no}"
-echo "libvdpau enabled          ${vdpau-no}"
-echo "AVISynth enabled          ${avisynth-no}"
-echo "frei0r enabled            ${frei0r-no}"
-echo "gnutls enabled            ${gnutls-no}"
-echo "libcdio support           ${libcdio-no}"
-echo "libdc1394 support         ${libdc1394-no}"
-echo "libfaac enabled           ${libfaac-no}"
-echo "libfdk-aac enabled        ${libfdk_aac-no}"
-echo "libgsm enabled            ${libgsm-no}"
-echo "libilbc enabled           ${libilbc-no}"
-echo "libmp3lame enabled        ${libmp3lame-no}"
-echo "libopencore-amrnb support ${libopencore_amrnb-no}"
-echo "libopencore-amrwb support ${libopencore_amrwb-no}"
-echo "libopencv support         ${libopencv-no}"
-echo "libopenjpeg enabled       ${libopenjpeg-no}"
-echo "libopus enabled           ${libopus-no}"
-echo "libpulse enabled          ${libpulse-no}"
-echo "librtmp enabled           ${librtmp-no}"
-echo "libschroedinger enabled   ${libschroedinger-no}"
-echo "libspeex enabled          ${libspeex-no}"
-echo "libtheora enabled         ${libtheora-no}"
-echo "libvo-aacenc support      ${libvo_aacenc-no}"
-echo "libvo-amrwbenc support    ${libvo_amrwbenc-no}"
-echo "libvorbis enabled         ${libvorbis-no}"
-echo "libvpx enabled            ${libvpx-no}"
-echo "libx264 enabled           ${libx264-no}"
-echo "libxavs enabled           ${libxavs-no}"
-echo "libxvid enabled           ${libxvid-no}"
-echo "openssl enabled           ${openssl-no}"
-echo "zlib enabled              ${zlib-no}"
-echo "bzlib enabled             ${bzlib-no}"
 test -n "$random_seed" &&
     echo "random seed               ${random_seed}"
 echo
 
+echo "External libraries:"
+print_enabled '' $EXTERNAL_LIBRARY_LIST | print_3_columns
+echo
+
 for type in decoder encoder hwaccel parser demuxer muxer protocol filter bsf indev outdev; do
     echo "Enabled ${type}s:"
     eval list=\$$(toupper $type)_LIST
-    print_enabled '_*' $list | sort | pr -r -3 -t
+    print_enabled '_*' $list | print_3_columns
     echo
 done
 
@@ -3851,7 +4278,7 @@ echo "License: $license"
 
 echo "Creating config.mak and config.h..."
 
-test -e Makefile || $ln_s "$source_path/Makefile" .
+test -e Makefile || echo "include $source_path/Makefile" > Makefile
 
 config_files="$TMPH config.mak"
 
@@ -3864,6 +4291,7 @@ SHLIBDIR=\$(DESTDIR)$shlibdir
 INCDIR=\$(DESTDIR)$incdir
 BINDIR=\$(DESTDIR)$bindir
 DATADIR=\$(DESTDIR)$datadir
+DOCDIR=\$(DESTDIR)$docdir
 MANDIR=\$(DESTDIR)$mandir
 SRC_PATH=$source_path
 CC_IDENT=$cc_ident
@@ -3881,6 +4309,7 @@ AR=$ar
 ARFLAGS=$arflags
 AR_O=$ar_o
 RANLIB=$ranlib
+STRIP=$strip
 LN_S=$ln_s
 CPPFLAGS=$CPPFLAGS
 CFLAGS=$CFLAGS
@@ -3895,8 +4324,8 @@ LD_LIB=$LD_LIB
 LD_PATH=$LD_PATH
 DLLTOOL=$dlltool
 LDFLAGS=$LDFLAGS
-LDFLAGS-avserver=$AVSERVERLDFLAGS
-SHFLAGS=$SHFLAGS
+SHFLAGS=$(echo $($ldflags_filter $SHFLAGS))
+STRIPFLAGS=$STRIPFLAGS
 YASMFLAGS=$YASMFLAGS
 BUILDSUF=$build_suffix
 FULLNAME=$FULLNAME
@@ -3916,6 +4345,7 @@ AS_DEPFLAGS=$AS_DEPFLAGS
 HOSTCC=$host_cc
 HOSTLD=$host_ld
 HOSTCFLAGS=$host_cflags
+HOSTCPPFLAGS=$host_cppflags
 HOSTEXESUF=$HOSTEXESUF
 HOSTLDFLAGS=$host_ldflags
 HOSTLIBS=$host_libs
@@ -3927,8 +4357,9 @@ HOSTCC_DEPFLAGS=$HOSTCC_DEPFLAGS
 HOSTCC_C=$HOSTCC_C
 HOSTCC_O=$HOSTCC_O
 HOSTLD_O=$HOSTLD_O
-TARGET_EXEC=$target_exec
+TARGET_EXEC=$target_exec $target_exec_args
 TARGET_PATH=$target_path
+TARGET_SAMPLES=${target_samples:-\$(SAMPLES)}
 LIBS-avplay=$sdl_libs
 CFLAGS-avplay=$sdl_cflags
 ZLIB=$($ldflags_filter -lz)
@@ -3958,6 +4389,7 @@ get_version(){
     eval ${name}_VERSION=\$${name}_VERSION_MAJOR.\$${name}_VERSION_MINOR.\$${name}_VERSION_MICRO
     eval echo "${lcname}_VERSION=\$${name}_VERSION" >> config.mak
     eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> config.mak
+    eval echo "${lcname}_VERSION_MINOR=\$${name}_VERSION_MINOR" >> config.mak
 }
 
 map 'get_version $v' $LIBRARY_LIST
@@ -3984,6 +4416,8 @@ if enabled yasm; then
     printf '' >$TMPASM
 fi
 
+enabled getenv || echo "#define getenv(x) NULL" >> $TMPH
+
 print_config ARCH_   "$config_files" $ARCH_LIST
 print_config HAVE_   "$config_files" $HAVE_LIST
 print_config CONFIG_ "$config_files" $CONFIG_LIST       \
@@ -4055,10 +4489,15 @@ 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" "libavutil = $LIBAVUTIL_VERSION"
+lavfi_libs="libavutil = $LIBAVUTIL_VERSION"
+enabled movie_filter    && prepend lavfi_libs "libavformat >= $LIBAVFORMAT_VERSION, libavcodec >= $LIBAVCODEC_VERSION,"
+enabled resample_filter && prepend lavfi_libs "libavresample >= $LIBAVRESAMPLE_VERSION,"
+enabled scale_filter    && prepend lavfi_libs "libswscale >= $LIBSWSCALE_VERSION,"
+
+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" "$lavfi_libs"
 pkgconfig_generate libavresample "Libav audio resampling library" "$LIBAVRESAMPLE_VERSION" "$extralibs" "libavutil = $LIBAVUTIL_VERSION"
-pkgconfig_generate libswscale "Libav image rescaling library" "$LIBSWSCALE_VERSION" "$LIBM" "libavutil = $LIBAVUTIL_VERSION"
+pkgconfig_generate libswscale    "Libav image rescaling library"  "$LIBSWSCALE_VERSION"    "$LIBM"      "libavutil = $LIBAVUTIL_VERSION"
diff --git a/doc/APIchanges b/doc/APIchanges
index 6e18ef6..944d214 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,17 +2,193 @@ Never assume the API of libav* to be stable unless at least 1 month has passed
 since the last major version increase.
 
 The last version increases were:
-libavcodec:    2012-01-27
-libavdevice:   2011-04-18
-libavfilter:   2012-06-22
-libavformat:   2012-01-27
+libavcodec:    2013-03-xx
+libavdevice:   2013-03-xx
+libavfilter:   2013-12-xx
+libavformat:   2013-03-xx
 libavresample: 2012-10-05
 libswscale:    2011-06-20
-libavutil:     2012-10-22
+libavutil:     2013-12-xx
 
 
 API changes, most recent first:
 
+2013-12-xx - xxxxxxx - lavc 55.28.1 - avcodec.h
+  av_frame_alloc(), av_frame_unref() and av_frame_free() now can and should be
+  used instead of avcodec_alloc_frame(), avcodec_get_frame_defaults() and
+  avcodec_free_frame() respectively. The latter three functions are deprecated.
+
+2013-11-xx - xxxxxxx- - lavu 52.20.0 - frame.h
+  Add AV_FRAME_DATA_STEREO3D value to the AVFrameSideDataType enum and
+  stereo3d.h API, that identify codec-independent stereo3d information.
+
+2013-11-xx - xxxxxxx- - lavu 52.19.0 - frame.h
+  Add AV_FRAME_DATA_A53_CC value to the AVFrameSideDataType enum, which
+  identifies ATSC A53 Part 4 Closed Captions data.
+
+2013-11-xx - xxxxxxx - lavu 52.18.0 - mem.h
+  Move av_fast_malloc() and av_fast_realloc() for libavcodec to libavutil.
+
+2013-10-xx - xxxxxxx - lavc 55.27.0 - avcodec.h
+  Deprecate AVCodecContext.error_rate, it is replaced by the 'error_rate'
+  private option of the mpegvideo encoder family.
+
+2013-11-xx - xxxxxxx - lavc 55.26.0 - vdpau.h
+  Add av_vdpau_get_profile().
+  Add av_vdpau_alloc_context(). This function must from now on be
+  used for allocating AVVDPAUContext.
+
+2013-11-xx - xxxxxxx - lavc 55.25.0 - avcodec.h
+  Add ITU-R BT.2020 and other not yet included values to color primaries,
+  transfer characteristics and colorspaces.
+
+2013-08-xx - xxxxxxx - lavu 52.17.0 - avframe.h
+  Add AVFrame.flags and AV_FRAME_FLAG_CORRUPT.
+
+2013-08-xx - xxxxxxx - lavfi 3.11.0 - avfilter.h
+  Add AVFilterGraph.execute and AVFilterGraph.opaque for custom slice threading
+  implementations.
+
+2013-09-21 - xxxxxxx - lavu 52.16.0 - pixfmt.h
+  Add interleaved 4:2:2 8/10-bit formats AV_PIX_FMT_NV16 and
+  AV_PIX_FMT_NV20.
+
+2013-09-16 - 3feb3d6 - lavu 52.15.0 - mem.h
+  Add av_reallocp.
+
+2013-08-10 - 5a9a9d4 - lavc 55.16.0 - avcodec.h
+  Extend AVPacket API with av_packet_unref, av_packet_ref,
+  av_packet_move_ref, av_packet_copy_props, av_packet_free_side_data.
+
+2013-08-05 - f824535 - lavc 55.13.0 - avcodec.h
+  Deprecate the bitstream-related members from struct AVVDPAUContext.
+  The bistream buffers no longer need to be explicitly freed.
+
+2013-08-05 - 549294f - lavc 55.12.0 - avcodec.h
+  Deprecate the CODEC_CAP_HWACCEL_VDPAU codec capability. Use CODEC_CAP_HWACCEL
+  and select the AV_PIX_FMT_VDPAU format with get_format() instead.
+
+2013-08-05 - a0ad5d0 - lavu 52.14.0 - pixfmt.h
+  Deprecate AV_PIX_FMT_VDPAU_*. Use AV_PIX_FMT_VDPAU instead.
+
+2013-08-02 - a8b1927 - lavc 55.11.0 - avcodec.h
+  Add output_picture_number to AVCodecParserContext.
+
+2013-06-24 - 95d5246 - lavc 55.10.0 - avcodec.h
+  Add MPEG-2 AAC profiles
+
+2013-06-04 - fc962d4 - lavu 52.13.0 - mem.h
+  Add av_realloc_array and av_reallocp_array
+
+2013-05-24 - 129bb23 - lavfi 3.10.0 - avfilter.h
+  Add support for slice multithreading to lavfi. Filters supporting threading
+  are marked with AVFILTER_FLAG_SLICE_THREADS.
+  New fields AVFilterContext.thread_type, AVFilterGraph.thread_type and
+  AVFilterGraph.nb_threads (accessible directly or through AVOptions) may be
+  used to configure multithreading.
+
+2013-05-24 - 2a6eaea - lavu 52.12.0 - cpu.h
+  Add av_cpu_count() function for getting the number of logical CPUs.
+
+2013-05-24 - b493847 - lavc 55.7.0 - avcodec.h
+  Add picture_structure to AVCodecParserContext.
+
+2013-05-15 - e6c4ac7 - lavu 52.11.0 - pixdesc.h
+  Replace PIX_FMT_* flags with AV_PIX_FMT_FLAG_*.
+
+2013-04-03 - 507b1e4 - lavc 55.4.0 - avcodec.h
+  Add field_order to AVCodecParserContext.
+
+2013-04-19 - 5e83d9a - lavc 55.2.0 - avcodec.h
+  Add CODEC_FLAG_UNALIGNED to allow decoders to produce unaligned output.
+
+2013-04-11 - lavfi 3.8.0
+  38f0c07 - Move all content from avfiltergraph.h to avfilter.h. Deprecate
+            avfilterhraph.h, user applications should include just avfilter.h
+  bc1a985 - Add avfilter_graph_alloc_filter(), deprecate avfilter_open() and
+            avfilter_graph_add_filter().
+  1113672 - Add AVFilterContext.graph pointing to the AVFilterGraph that contains the
+            filter.
+  48a5ada - Add avfilter_init_str(), deprecate avfilter_init_filter().
+  1ba95a9 - Add avfilter_init_dict().
+  7cdd737 - Add AVFilter.flags field and AVFILTER_FLAG_DYNAMIC_{INPUTS,OUTPUTS} flags.
+  7e8fe4b - Add avfilter_pad_count() for counting filter inputs/outputs.
+  fa2a34c - Add avfilter_next(), deprecate av_filter_next().
+            Deprecate avfilter_uninit().
+
+2013-04-09 - lavfi 3.7.0 - avfilter.h
+  b439c99 - Add AVFilter.priv_class for exporting filter options through the
+            AVOptions API in the similar way private options work in lavc and lavf.
+  8114c10 - Add avfilter_get_class().
+  Switch all filters to use AVOptions.
+
+2013-03-19 - 2c328a9 - lavu 52.9.0 - pixdesc.h
+  Add av_pix_fmt_count_planes() function for counting planes in a pixel format.
+
+2013-03-16 - 42c7c61 - lavfi 3.6.0
+  Add AVFilterGraph.nb_filters, deprecate AVFilterGraph.filter_count.
+
+2013-03-08 - Reference counted buffers - lavu 52.8.0, lavc 55.0.0, lavf 55.0.0,
+lavd 54.0.0, lavfi 3.5.0
+  8e401db, 1cec062 - add a new API for reference counted buffers and buffer
+                     pools (new header libavutil/buffer.h).
+  1afddbe - add AVPacket.buf to allow reference counting for the AVPacket data.
+            Add av_packet_from_data() function for constructing packets from
+            av_malloc()ed data.
+  7ecc2d4 - move AVFrame from lavc to lavu (new header libavutil/frame.h), add
+            AVFrame.buf/extended_buf to allow reference counting for the AVFrame
+            data. Add new API for working with reference-counted AVFrames.
+  759001c - add the refcounted_frames field to AVCodecContext to make audio and
+            video decoders return reference-counted frames. Add get_buffer2()
+            callback to AVCodecContext which allocates reference-counted frames.
+            Add avcodec_default_get_buffer2() as the default get_buffer2()
+            implementation.
+            Deprecate AVCodecContext.get_buffer() / release_buffer() /
+            reget_buffer(), avcodec_default_get_buffer(),
+            avcodec_default_reget_buffer(), avcodec_default_release_buffer().
+            Remove avcodec_default_free_buffers(), which should not have ever
+            been called from outside of lavc.
+            Deprecate the following AVFrame fields:
+                * base -- is now stored in AVBufferRef
+                * reference, type, buffer_hints -- are unnecessary in the new API
+                * hwaccel_picture_private, owner, thread_opaque -- should not
+                  have been acessed from outside of lavc
+                * qscale_table, qstride, qscale_type, mbskip_table, motion_val,
+                  mb_type, dct_coeff, ref_index -- mpegvideo-specific tables,
+                  which are not exported anymore.
+  7e35037 - switch libavfilter to use AVFrame instead of AVFilterBufferRef. Add
+            av_buffersrc_add_frame(), deprecate av_buffersrc_buffer().
+            Add av_buffersink_get_frame() and av_buffersink_get_samples(),
+            deprecate av_buffersink_read() and av_buffersink_read_samples().
+            Deprecate AVFilterBufferRef and all functions for working with it.
+
+2013-03-17 - 12c5c1d - lavu 52.8.0 - avstring.h
+  Add av_isdigit, av_isgraph, av_isspace, av_isxdigit.
+
+2013-02-23 - 9f12235 - lavfi 3.4.0 - avfiltergraph.h
+  Add resample_lavr_opts to AVFilterGraph for setting libavresample options
+  for auto-inserted resample filters.
+
+2013-01-25 - 38c1466 - lavu 52.7.0 - dict.h
+  Add av_dict_parse_string() to set multiple key/value pairs at once from a
+  string.
+
+2013-01-25 - b85a5e8 - lavu 52.6.0 - avstring.h
+  Add av_strnstr()
+
+2013-01-15 - 8ee288d - lavu 52.5.0 - hmac.h
+  Add AVHMAC.
+
+2013-01-13 - 44e065d - lavc 54.36.0 - vdpau.h
+  Add AVVDPAUContext struct for VDPAU hardware-accelerated decoding.
+
+2013-01-12 - 169fb94 - lavu 52.4.0 - pixdesc.h
+  Add AV_PIX_FMT_VDPAU flag.
+
+2013-01-07 - 074a00d - lavr 1.1.0
+  Add avresample_set_channel_mapping() for input channel reordering,
+  duplication, and silencing.
+
 2012-12-29 - d8fd06c - lavu 52.3.0 - avstring.h
   Add av_basename() and av_dirname().
 
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 3b2236c..ae65478 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -277,7 +277,7 @@ SUBGROUPING            = YES
 # be useful for C code in case the coding convention dictates that all compound
 # types are typedef'ed and only the typedef is referenced, never the tag name.
 
-TYPEDEF_HIDES_STRUCT   = NO
+TYPEDEF_HIDES_STRUCT   = YES
 
 # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
 # determine which symbols to keep in memory and which to flush to disk.
@@ -409,7 +409,7 @@ INLINE_INFO            = YES
 # alphabetically by member name. If set to NO the members will appear in
 # declaration order.
 
-SORT_MEMBER_DOCS       = YES
+SORT_MEMBER_DOCS       = NO
 
 # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
 # brief documentation of file, namespace and class members alphabetically
diff --git a/doc/Makefile b/doc/Makefile
index d22de79..3cd67df 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,6 +1,7 @@
-MANPAGES    = $(PROGS-yes:%=doc/%.1)
-PODPAGES    = $(PROGS-yes:%=doc/%.pod)
-HTMLPAGES   = $(PROGS-yes:%=doc/%.html)                                 \
+ALLMANPAGES = $(AVBASENAMES:%=%.1)
+MANPAGES    = $(AVPROGS-yes:%=doc/%.1)
+PODPAGES    = $(AVPROGS-yes:%=doc/%.pod)
+HTMLPAGES   = $(AVPROGS-yes:%=doc/%.html)                               \
               doc/developer.html                                        \
               doc/faq.html                                              \
               doc/fate.html                                             \
@@ -10,20 +11,32 @@ HTMLPAGES   = $(PROGS-yes:%=doc/%.html)                                 \
               doc/nut.html                                              \
               doc/platform.html                                         \
 
-DOCS = $(HTMLPAGES) $(MANPAGES) $(PODPAGES)
+DOCS-$(CONFIG_POD2MAN)                          += $(MANPAGES) $(PODPAGES)
+DOCS-$(CONFIG_TEXI2HTML)                        += $(HTMLPAGES)
+DOCS = $(DOCS-yes)
 
-all-$(CONFIG_DOC): documentation
+DOC_EXAMPLES-$(CONFIG_OUTPUT_EXAMPLE)           += output
+DOC_EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE)    += transcode_aac
+ALL_DOC_EXAMPLES = output transcode_aac
+
+DOC_EXAMPLES     := $(DOC_EXAMPLES-yes:%=doc/examples/%$(EXESUF))
+ALL_DOC_EXAMPLES := $(ALL_DOC_EXAMPLES:%=doc/examples/%$(EXESUF))
+PROGS            += $(DOC_EXAMPLES)
+
+all: $(DOCS)
 
 apidoc: doc/doxy/html
 documentation: $(DOCS)
 
+examples: $(DOC_EXAMPLES)
+
 TEXIDEP = awk '/^@include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d)
 
 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
@@ -32,7 +45,7 @@ doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
 	$(M)texi2html -I doc -monolithic --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
 
 doc/%.pod: TAG = POD
-doc/%.pod: doc/%.texi $(GENTEXI)
+doc/%.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
 	$(Q)$(TEXIDEP)
 	$(M)$(SRC_PATH)/doc/texi2pod.pl -Idoc $< $@
 
@@ -41,23 +54,35 @@ doc/%.1: doc/%.pod $(GENTEXI)
 	$(M)pod2man --section=1 --center=" " --release=" " $< > $@
 
 $(DOCS) doc/doxy/html: | doc/
+$(DOC_EXAMPLES:%=%.o): | doc/examples
+OBJDIRS += doc/examples
 
 doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(INSTHEADERS)
 	$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $(SRC_PATH) $^
 
-install-progs-$(CONFIG_DOC): install-man
+install-progs-$(CONFIG_POD2MAN): install-man
+install-progs-$(CONFIG_TEXI2HTML): install-doc
+
+install-doc: $(HTMLPAGES)
+	$(Q)mkdir -p "$(DOCDIR)"
+	$(INSTALL) -m 644 $(HTMLPAGES) "$(DOCDIR)"
 
 install-man: $(MANPAGES)
 	$(Q)mkdir -p "$(MANDIR)/man1"
 	$(INSTALL) -m 644 $(MANPAGES) "$(MANDIR)/man1"
 
-uninstall: uninstall-man
+uninstall: uninstall-doc uninstall-man
+
+uninstall-doc:
+	$(RM) -r "$(DOCDIR)"
 
 uninstall-man:
 	$(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES))
 
 clean::
-	$(RM) doc/*.html doc/*.pod doc/*.1 $(CLEANSUFFIXES:%=doc/%) doc/avoptions_*.texi
+	$(RM) $(ALL_DOC_EXAMPLES)
+	$(RM) $(CLEANSUFFIXES:%=doc/%) $(CLEANSUFFIXES:%=doc/examples/%)
+	$(RM) doc/*.html doc/*.pod doc/*.1 doc/avoptions_*.texi
 	$(RM) -r doc/doxy/html
 
 -include $(wildcard $(DOCS:%=%.d))
diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES
index 62207c6..b258e30 100644
--- a/doc/RELEASE_NOTES
+++ b/doc/RELEASE_NOTES
@@ -1,61 +1,40 @@
 Release Notes
 =============
 
-* 9 "Plain Nine"
+* 10 "Eks"
 
 General notes
 -------------
 
-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.
-
-Of big interest to our Windows users, Libav now supports building with the MSVC
-compiler. Since MSVC does not support C99 features used extensively by Libav,
-this has been accomplished using a converter that turns C99 code to C89. See the
-platform-specific documentation for more detailed documentation on building
-Libav with MSVC.
-
-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, 24-bit FLAC encoding, 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.
+One of the main features of this release is the addition of reference-counted
+data buffers to Libav and their use in various structures. Specifically, the
+data buffers used by AVPacket and AVFrame can now be reference counted, which
+should allow to significantly simplify many use cases. In addition,
+reference-counted AVFrames can now be used in libavfilter, avoiding the need
+for a separate libavfilter-specific frame structure. Frames can now be passed
+straight from the decoders into filters or from filters to encoders.
+
+These additions made it necessary to bump the major versions of libavcodec,
+libavformat, libavdevice, libavfilter, and libavutil, which was accompanied by
+dropping some old deprecated APIs. These libraries are thus not ABI- or API-
+compatible with the previous release. All the other libraries (libavresample
+and libswscale) should be both ABI- and API-compatible.
+
+Another major point is the inclusion of the HEVC (AKA H.265, the successor of
+H.264) decoder in the main codebase. It was started in 2012 as a Libav Google
+Summer of Code project by Guillaume Martres and subsequently completed with
+the assistance of the OpenHEVC project and several Libav developers.
+
+As usual, this release also contains support for other new formats, many smaller
+new features and countless bug fixes. We can highlight a native VP9 decoder,
+with encoding provided through libvpx, native decoders for WebP, JPEG 2000, and
+AIC, as well as improved WavPack support with encoding through libwavpack,
+support for more AAC flavors (LD - low delay, ELD - enhanced low delay), slice
+multithreading in libavfilter, or muxing chapters in ASF. Furthermore there is
+more fine-grained detection of host and target libc, which should allow better
+portability to various cross compilation scenarios.
+
+See the Changelog file for a fuller 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
@@ -72,30 +51,31 @@ 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.
+[libavutil]
++ added the reference-counted buffers API (buffers.h)
++ moved the AVFrame struct to libavutil and added a new API for working with
+  reference-counted AVFrames (frame.h)
+
+[libavcodec]
++ added an API for working with reference-counted AVPackets (av_packet_*)
++- converted VDPAU to the hwaccel framework; the old way of using VDPAU is no
+   longer supported
+- old audio encoding and decoding APIs removed
+- old video encoding API removed
+- deprecated enum CodecID removed (enum AVCodecID should be used instead)
+- deprecated audio resampling API removed (libavresample should be used
+  instead)
+
+[libavfilter]
++- replaced AVFilterBufferRef with AVFrame; AVFilterBufferRef and everything
+   related to it still exists, but is deprecated
++ converted all filters to use the AVOptions system for configuration, it is
+  now possible to query the supported options, their values and set them
+  directly with av_opt_*
++ added a slice multithreading framework
++- merged avfiltergraph.h to avfilter.h, using AVFilterGraph is now explicitly
+   mandatory (it was implicitly required even before); added new API for
+   allocating and initializing filters
 
 Please see the file doc/APIchanges for details along with similar
 programmer-centric information.
diff --git a/doc/avconv.texi b/doc/avconv.texi
index 7341d2f..972d13f 100644
--- a/doc/avconv.texi
+++ b/doc/avconv.texi
@@ -233,6 +233,9 @@ input file name
 @item -y (@emph{global})
 Overwrite output files without asking.
 
+ at item -n (@emph{global})
+Immediately exit when output files already exist.
+
 @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
@@ -262,9 +265,15 @@ 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
- at 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.
+ at var{position}. Note the in most formats it is not possible to seek exactly, so
+ at command{avconv} will seek to the closest seek point before @var{position}.
+When transcoding and @option{-accurate_seek} is enabled (the default), this
+extra segment between the seek point and @var{position} will be decoded and
+discarded. When doing stream copy or when @option{-noaccurate_seek} is used, it
+will be preserved.
+
+When used as an output option (before an output filename), decodes but discards
+input until the timestamps reach @var{position}.
 
 @var{position} may be either in seconds or in @code{hh:mm:ss[.xxx]} form.
 
@@ -330,6 +339,12 @@ the stream. Use @code{-filters} to show all the available filters
 
 See also the @option{-filter_complex} option if you want to create filter graphs
 with multiple inputs and/or outputs.
+
+ at item -filter_script[:@var{stream_specifier}] @var{filename} (@emph{output,per-stream})
+This option is similar to @option{-filter}, the only difference is that its
+argument is the name of the file from which a filtergraph description is to be
+read.
+
 @item -pre[:@var{stream_specifier}] @var{preset_name} (@emph{output,per-stream})
 Specify the preset for matching stream(s).
 
@@ -515,10 +530,6 @@ Discard threshold.
 @item -rc_override[:@var{stream_specifier}] @var{override} (@emph{output,per-stream})
 rate control override for specific intervals
 
- at 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}
@@ -541,6 +552,42 @@ 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.
+
+ at item -hwaccel[:@var{stream_specifier}] @var{hwaccel} (@emph{input,per-stream})
+Use hardware acceleration to decode the matching stream(s). The allowed values
+of @var{hwaccel} are:
+ at table @option
+ at item none
+Do not use any hardware acceleration (the default).
+
+ at item auto
+Automatically select the hardware acceleration method.
+
+ at item vdpau
+Use VDPAU (Video Decode and Presentation API for Unix) hardware acceleration.
+ at end table
+
+This option has no effect if the selected hwaccel is not available or not
+supported by the chosen decoder.
+
+Note that most acceleration methods are intended for playback and will not be
+faster than software decoding on modern CPUs. Additionally, @command{avconv}
+will usually need to copy the decoded frames from the GPU memory into the system
+memory, resulting in further performance loss. This option is thus mainly
+useful for testing.
+
+ at item -hwaccel_device[:@var{stream_specifier}] @var{hwaccel_device} (@emph{input,per-stream})
+Select a device to use for hardware acceleration.
+
+This option only makes sense when the @option{-hwaccel} option is also
+specified. Its exact meaning depends on the specific hardware acceleration
+method chosen.
+
+ at table @option
+ at item vdpau
+For VDPAU, this option specifies the X11 display/screen to use. If this option
+is not specified, the value of the @var{DISPLAY} environment variable is used
+ at end table
 @end table
 
 @section Audio Options
@@ -708,7 +755,10 @@ 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.
+Read input at native frame rate. Mainly used to simulate a grab device
+or live input stream (e.g. when reading from a file). Should not be used
+with actual grab devices or live input streams (where it can cause packet
+loss).
 @item -vsync @var{parameter}
 Video sync method.
 
@@ -774,10 +824,6 @@ avconv -i file.mov -an -vn -bsf:s mov2textsub -c:s copy -f rawvideo sub.txt
 @item -tag[:@var{stream_specifier}] @var{codec_tag} (@emph{output,per-stream})
 Force a tag/fourcc for matching streams.
 
- at 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
@@ -823,6 +869,18 @@ 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
+
+ at item -filter_complex_script @var{filename} (@emph{global})
+This option is similar to @option{-filter_complex}, the only difference is that
+its argument is the name of the file from which a complex filtergraph
+description is to be read.
+
+ at item -accurate_seek (@emph{input})
+This option enables or disables accurate seeking in input files with the
+ at option{-ss} option. It is enabled by default, so seeking is accurate when
+transcoding. Use @option{-noaccurate_seek} to disable it, which may be useful
+e.g. when copying some streams and transcoding the others.
+
 @end table
 @c man end OPTIONS
 
diff --git a/doc/avplay.texi b/doc/avplay.texi
index 8fc3308..50142ab 100644
--- a/doc/avplay.texi
+++ b/doc/avplay.texi
@@ -76,12 +76,8 @@ 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.
- at item -debug
-Print specific debug info.
 @item -bug
 Work around bugs.
- at item -vismv
-Visualize motion vectors.
 @item -fast
 Non-spec-compliant optimizations.
 @item -genpts
diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi
index afd2cc3..156319e 100644
--- a/doc/avtools-common-opts.texi
+++ b/doc/avtools-common-opts.texi
@@ -74,6 +74,10 @@ Print detailed information about the demuxer named @var{demuxer_name}. Use the
 Print detailed information about the muxer named @var{muxer_name}. Use the
 @option{-formats} option to get a list of all muxers and demuxers.
 
+ at item filter=@var{filter_name}
+Print detailed information about the filter name @var{filter_name}. Use the
+ at option{-filters} option to get a list of all filters.
+
 @end table
 
 @item -version
@@ -139,6 +143,10 @@ 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.
 
+ at 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.
+
 @end table
 
 @section AVOptions
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index b78cf68..2f2f464 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -88,4 +88,26 @@ 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".
 
+ at section flv
+
+Adobe Flash Video Format demuxer.
+
+This demuxer is used to demux FLV files and RTMP network streams.
+
+ at table @option
+ at item -flv_metadata @var{bool}
+Allocate the streams according to the onMetaData array content.
+ at end table
+
+ at section asf
+
+Advanced Systems Format demuxer.
+
+This demuxer is used to demux ASF files and MMS network streams.
+
+ at table @option
+ at item -no_resync_search @var{bool}
+Do not try to resynchronize by looking for a certain optional start code.
+ at end table
+
 @c man end INPUT DEVICES
diff --git a/doc/developer.texi b/doc/developer.texi
index 7d39f2d..832e21e 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -12,6 +12,7 @@
 @chapter Developers Guide
 
 @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.
@@ -20,14 +21,13 @@ decoding). Look at @file{libavcodec/apiexample.c} to see how to use it.
 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.
-
 @end itemize
 
 @section Integrating libav 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.
+only the public API is used.
 
 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
@@ -47,6 +47,7 @@ mailing list.
 
 @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
@@ -54,6 +55,7 @@ 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
@@ -64,6 +66,7 @@ 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
@@ -72,29 +75,35 @@ 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
 @item
 Indent size is 4.
+
 @item
 The TAB character is forbidden outside of Makefiles as is any
 form of trailing whitespace. Commits containing either will be
 rejected by the git repository.
+
 @item
 You should try to limit your code lines to 80 characters; however, do so if
 and only if this improves readability.
@@ -148,13 +157,17 @@ int myfunc(int my_parameter)
 
 Libav is programmed in the ISO C90 language with a few additional
 features from ISO C99, namely:
+
 @itemize @bullet
 @item
 the @samp{inline} keyword;
+
 @item
 @samp{//} comments;
+
 @item
 designated struct initializers (@samp{struct s x = @{ .i = 17 @};})
+
 @item
 compound literals (@samp{x = (struct s) @{ 17, 23 @};})
 @end itemize
@@ -166,46 +179,67 @@ clarity and performance.
 All code must compile with recent versions of GCC and a number of other
 currently supported compilers. To ensure compatibility, please do not use
 additional C99 features or GCC extensions. Especially watch out for:
+
 @itemize @bullet
 @item
 mixing statements and declarations;
+
 @item
 @samp{long long} (use @samp{int64_t} instead);
+
 @item
 @samp{__attribute__} not protected by @samp{#ifdef __GNUC__} or similar;
+
 @item
 GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}).
 @end itemize
 
 @subsection Naming conventions
-All names are using underscores (_), not CamelCase. For example,
- at samp{avfilter_get_video_buffer} is a valid function name and
- at samp{AVFilterGetVideo} is not. The only exception from this are structure
-names; they should always be in the CamelCase
+All names should be composed with underscores (_), not CamelCase. For example,
+ at samp{avfilter_get_video_buffer} is an acceptable function name and
+ at samp{AVFilterGetVideo} is not. The only exception are structure
+names; they should always be CamelCase.
+
+There are the following conventions for naming variables and functions:
 
-There are following conventions for naming variables and functions:
 @itemize @bullet
 @item
 For local variables no prefix is required.
+
 @item
-For variables and functions declared as @code{static} no prefixes are required.
+For file-scope variables and functions declared as @code{static}, no prefix
+is required.
+
 @item
-For variables and functions used internally by the library, @code{ff_} prefix
-should be used.
-For example, @samp{ff_w64_demuxer}.
+For variables and functions visible outside of file scope, but only used
+internally by a library, an @code{ff_} prefix should be used,
+e.g. @samp{ff_w64_demuxer}.
+
 @item
-For variables and functions used internally across multiple libraries, use
- at code{avpriv_}. For example, @samp{avpriv_aac_parse_header}.
+For variables and functions visible outside of file scope, used internally
+across multiple libraries, use @code{avpriv_} as prefix, for example,
+ at samp{avpriv_aac_parse_header}.
+
 @item
-For exported names, each library has its own prefixes. Just check the existing
-code and name accordingly.
+For externally visible symbols, each library has its own prefix. Check
+the existing code and choose names accordingly.
 @end itemize
 
+Furthermore, name space reserved for the system should not be invaded.
+Identifiers ending in @code{_t} are reserved by
+ at url{http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html#tag_02_02_02, POSIX}.
+Also avoid names starting with @code{__} or @code{_} followed by an uppercase
+letter as they are reserved by the C standard. Names starting with @code{_}
+are reserved at the file level and may not be used for externally visible
+symbols. If in doubt, just avoid names starting with @code{_} altogether.
+
 @subsection Miscellaneous conventions
+
 @itemize @bullet
 @item
 fprintf and printf are forbidden in libavformat and libavcodec,
 please use av_log() instead.
+
 @item
 Casts should be used only when necessary. Unneeded parentheses
 should also be avoided if they don't make the code easier to understand.
@@ -215,7 +249,7 @@ should also be avoided if they don't make the code easier to understand.
 In order to configure Vim to follow Libav formatting conventions, paste
 the following snippet into your @file{.vimrc}:
 @example
-" indentation rules for libav: 4 spaces, no tabs
+" Indentation rules for Libav: 4 spaces, no tabs.
 set expandtab
 set shiftwidth=4
 set softtabstop=4
@@ -248,101 +282,126 @@ For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
 
 @enumerate
 @item
-   Contributions should be licensed under the LGPL 2.1, including an
-   "or any later version" clause, or the MIT license.  GPL 2 including
-   an "or any later version" clause is also acceptable, but LGPL is
-   preferred.
- at item
-   All the patches MUST be reviewed in the mailing list before they are
-   committed.
- at item
-   The Libav coding style should remain consistent. Changes to
-   conform will be suggested during the review or implemented on commit.
- at 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.
- at 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.
- at item
-   Work in progress patches should be sent to the mailing list with the [WIP]
-   or the [RFC] tag.
- at item
-   Branches in public personal repos are advised as way to
-   work on issues collaboratively.
- at 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.
- at item
-   Do not commit unrelated changes together, split them into self-contained
-   pieces. Also do not forget that if part B depends on part A, but A does not
-   depend on B, then A can and should be committed first and separate from B.
-   Keeping changes well split into self-contained parts makes reviewing and
-   understanding them on the commit log mailing list easier. This also helps
-   in case of debugging later on.
- at 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.
- at item
-   When applying patches that have been discussed (at length) on the mailing
-   list, reference the thread in the log message.
- at 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.
- at 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.
- at 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.
- at 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.
- at item
-    Remember to check if you need to bump versions for the specific libav
-    parts (libavutil, libavcodec, libavformat) you are changing. You need
-    to change the version integer.
-    Incrementing the first component means no backward compatibility to
-    previous versions (e.g. removal of a function from the public API).
-    Incrementing the second component means backward compatible change
-    (e.g. addition of a function to the public API or extension of an
-    existing data structure).
-    Incrementing the third component means a noteworthy binary compatible
-    change (e.g. encoder bug fix that matters for the decoder).
- at item
-    Compiler warnings indicate potential bugs or code with bad style.
-    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.
- at 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.
+Contributions should be licensed under the
+ at uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},
+including an "or any later version" clause, or, if you prefer
+a gift-style license, the
+ at uref{http://www.isc.org/software/license/, ISC} or
+ at uref{http://mit-license.org/, MIT} license.
+ at uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} including
+an "or any later version" clause is also acceptable, but LGPL is
+preferred.
+
+ at item
+All the patches MUST be reviewed in the mailing list before they are
+committed.
+
+ at item
+The Libav coding style should remain consistent. Changes to
+conform will be suggested during the review or implemented on commit.
+
+ at 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.
+
+ at item
+The commit message should have a short first line in the form of
+a @samp{topic: short description} as a header, separated by a newline
+from the body consisting of an explanation of why the change is necessary.
+If the commit fixes a known bug on the bug tracker, the commit message
+should include its bug ID. Referring to the issue on the bug tracker does
+not exempt you from writing an excerpt of the bug in the commit message.
+If the patch is a bug fix which should be backported to stable releases,
+i.e. a non-API/ABI-breaking bug fix, add @code{CC: libav-stable@@libav.org}
+to the bottom of your commit message, and make sure to CC your patch to
+this address, too. Some git setups will do this automatically.
+
+ at item
+Work in progress patches should be sent to the mailing list with the [WIP]
+or the [RFC] tag.
+
+ at item
+Branches in public personal repos are advised as way to
+work on issues collaboratively.
+
+ at 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.
+
+ at item
+Do not commit unrelated changes together, split them into self-contained
+pieces. Also do not forget that if part B depends on part A, but A does not
+depend on B, then A can and should be committed first and separate from B.
+Keeping changes well split into self-contained parts makes reviewing and
+understanding them on the commit log mailing list easier. This also helps
+in case of debugging later on.
+
+ at 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.
+
+ at item
+When applying patches that have been discussed (at length) on the mailing
+list, reference the thread in the log message.
+
+ at item
+Subscribe to the
+ at uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel} and
+ at 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.
+
+ at 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.
+
+ at 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.
+
+ at 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 double-check.
+
+ at item
+Remember to check if you need to bump versions for the specific libav
+parts (libavutil, libavcodec, libavformat) you are changing. You need
+to change the version integer.
+Incrementing the first component means no backward compatibility to
+previous versions (e.g. removal of a function from the public API).
+Incrementing the second component means backward compatible change
+(e.g. addition of a function to the public API or extension of an
+existing data structure).
+Incrementing the third component means a noteworthy binary compatible
+change (e.g. encoder bug fix that matters for the decoder).
+
+ at item
+Compiler warnings indicate potential bugs or code with bad style.
+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.
+
+ at item
+If you add a new file, give it a proper license header. Do not copy and
+paste it from a random place, use an existing file as template.
 @end enumerate
 
 We think our rules are not too hard. If you have comments, contact us.
 
-Note, some rules were borrowed from the MPlayer project.
-
 @section Submitting patches
 
 First, read the @ref{Coding Rules} above if you did not yet, in particular
@@ -362,12 +421,6 @@ The tool is located in the tools directory.
 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
- at uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
-mailing list.
-
 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
@@ -376,8 +429,12 @@ commit message.
 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.
+Patches should be posted to the
+ at uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
+mailing list. Use @code{git send-email} when possible since it will properly
+send patches without requiring extra care. If you cannot, then send patches
+as base64-encoded attachments, so your patch is not trashed during
+transmission.
 
 Your patch will be reviewed on the mailing list. You will likely be asked
 to make some changes and are expected to send in an improved version that
@@ -393,40 +450,51 @@ send a reminder by email. Your patch should eventually be dealt with.
 
 @enumerate
 @item
-    Did you use av_cold for codec initialization and close functions?
+Did you use av_cold for codec initialization and close functions?
+
 @item
-    Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or
-    AVInputFormat/AVOutputFormat struct?
+Did you add a long_name under NULL_IF_CONFIG_SMALL to the AVCodec or
+AVInputFormat/AVOutputFormat struct?
+
 @item
-    Did you bump the minor version number (and reset the micro version
-    number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
+Did you bump the minor version number (and reset the micro version
+number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
+
 @item
-    Did you register it in @file{allcodecs.c} or @file{allformats.c}?
+Did you register it in @file{allcodecs.c} or @file{allformats.c}?
+
 @item
-    Did you add the AVCodecID to @file{avcodec.h}?
-    When adding new codec IDs, also add an entry to the codec descriptor
-    list in @file{libavcodec/codec_desc.c}.
+Did you add the AVCodecID to @file{avcodec.h}?
+When adding new codec IDs, also add an entry to the codec descriptor
+list in @file{libavcodec/codec_desc.c}.
+
 @item
-    If it has a fourcc, did you add it to @file{libavformat/riff.c},
-    even if it is only a decoder?
+If it has a FourCC, did you add it to @file{libavformat/riff.c},
+even if it is only a decoder?
+
 @item
-    Did you add a rule to compile the appropriate files in the Makefile?
-    Remember to do this even if you are just adding a format to a file that
-    is already being compiled by some other rule, like a raw demuxer.
+Did you add a rule to compile the appropriate files in the Makefile?
+Remember to do this even if you are just adding a format to a file that
+is already being compiled by some other rule, like a raw demuxer.
+
 @item
-    Did you add an entry to the table of supported formats or codecs in
-    @file{doc/general.texi}?
+Did you add an entry to the table of supported formats or codecs in
+ at file{doc/general.texi}?
+
 @item
-    Did you add an entry in the Changelog?
+Did you add an entry in the Changelog?
+
 @item
-    If it depends on a parser or a library, did you add that dependency in
-    configure?
+If it depends on a parser or a library, did you add that dependency in
+configure?
+
 @item
-    Did you @code{git add} the appropriate files before committing?
+Did you @code{git add} the appropriate files before committing?
+
 @item
-    Did you make sure it compiles standalone, i.e. with
-    @code{configure --disable-everything --enable-decoder=foo}
-    (or @code{--enable-demuxer} or whatever your component is)?
+Did you make sure it compiles standalone, i.e. with
+ at code{configure --disable-everything --enable-decoder=foo}
+(or @code{--enable-demuxer} or whatever your component is)?
 @end enumerate
 
 
@@ -434,66 +502,89 @@ send a reminder by email. Your patch should eventually be dealt with.
 
 @enumerate
 @item
-    Does @code{make check} pass with the patch applied?
+Does @code{make check} pass with the patch applied?
+
 @item
-    Is the patch against latest Libav git master branch?
+Is the patch against latest Libav git master branch?
+
 @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.)
+Are you subscribed to the
+ at uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
+mailing list? (Only list subscribers are allowed to post.)
+
 @item
-    Have you checked that the changes are minimal, so that the same cannot be
-    achieved with a smaller patch and/or simpler final code?
+Have you checked that the changes are minimal, so that the same cannot be
+achieved with a smaller patch and/or simpler final code?
+
 @item
-    If the change is to speed critical code, did you benchmark it?
+If the change is to speed critical code, did you benchmark it?
+
 @item
-    If you did any benchmarks, did you provide them in the mail?
+If you did any benchmarks, did you provide them in the mail?
+
 @item
-    Have you checked that the patch does not introduce buffer overflows or
-    other security issues?
+Have you checked that the patch does not introduce buffer overflows or
+other security issues?
+
 @item
-    Did you test your decoder or demuxer against damaged data? If no, see
-    tools/trasher and the noise bitstream filter. Your decoder or demuxer
-    should not crash or end in a (near) infinite loop when fed damaged data.
+Did you test your decoder or demuxer against damaged data? If no, see
+tools/trasher, the noise bitstream filter, and
+ at uref{http://caca.zoy.org/wiki/zzuf, zzuf}. Your decoder or demuxer
+should not crash, end in a (near) infinite loop, or allocate ridiculous
+amounts of memory when fed damaged data.
+
 @item
-    Does the patch not mix functional and cosmetic changes?
+Does the patch not mix functional and cosmetic changes?
+
 @item
-    Did you add tabs or trailing whitespace to the code? Both are forbidden.
+Did you add tabs or trailing whitespace to the code? Both are forbidden.
+
 @item
-    Is the patch attached to the email you send?
+Is the patch attached to the email you send?
+
 @item
-    Is the mime type of the patch correct? It should be text/x-diff or
-    text/x-patch or at least text/plain and not application/octet-stream.
+Is the mime type of the patch correct? It should be text/x-diff or
+text/x-patch or at least text/plain and not application/octet-stream.
+
 @item
-    If the patch fixes a bug, did you provide a verbose analysis of the bug?
+If the patch fixes a bug, did you provide a verbose analysis of the bug?
+
 @item
-    If the patch fixes a bug, did you provide enough information, including
-    a sample, so the bug can be reproduced and the fix can be verified?
-    Note please do not attach samples >100k to mails but rather provide a
-    URL, you can upload to ftp://upload.libav.org
+If the patch fixes a bug, did you provide enough information, including
+a sample, so the bug can be reproduced and the fix can be verified?
+Note please do not attach samples >100k to mails but rather provide a
+URL, you can upload to ftp://upload.libav.org
+
 @item
-    Did you provide a verbose summary about what the patch does change?
+Did you provide a verbose summary about what the patch does change?
+
 @item
-    Did you provide a verbose explanation why it changes things like it does?
+Did you provide a verbose explanation why it changes things like it does?
+
 @item
-    Did you provide a verbose summary of the user visible advantages and
-    disadvantages if the patch is applied?
+Did you provide a verbose summary of the user visible advantages and
+disadvantages if the patch is applied?
+
 @item
-    Did you provide an example so we can verify the new feature added by the
-    patch easily?
+Did you provide an example so we can verify the new feature added by the
+patch easily?
+
 @item
-    If you added a new file, did you insert a license header? It should be
-    taken from Libav, not randomly copied and pasted from somewhere else.
+If you added a new file, did you insert a license header? It should be
+taken from Libav, not randomly copied and pasted from somewhere else.
+
 @item
-    You should maintain alphabetical order in alphabetically ordered lists as
-    long as doing so does not break API/ABI compatibility.
+You should maintain alphabetical order in alphabetically ordered lists as
+long as doing so does not break API/ABI compatibility.
+
 @item
-    Lines with similar content should be aligned vertically when doing so
-    improves readability.
+Lines with similar content should be aligned vertically when doing so
+improves readability.
+
 @item
-    Make sure you check the return values of function and return appropriate
-    error codes. Especially memory allocation functions like @code{malloc()}
-    are notoriously left unchecked, which is a serious problem.
+Make sure you check the return values of function and return appropriate
+error codes. Especially memory allocation functions like @code{malloc()}
+are notoriously left unchecked, which is a serious problem.
 @end enumerate
 
 @section Patch review process
@@ -532,4 +623,162 @@ why the expected result changed.
 
 Please refer to @url{fate.html}.
 
+ at subsection Visualizing Test Coverage
+
+The Libav build system allows visualizing the test coverage in an easy
+manner with the coverage tools @code{gcov}/@code{lcov}.  This involves
+the following steps:
+
+ at enumerate
+ at item
+    Configure to compile with instrumentation enabled:
+    @code{configure --toolchain=gcov}.
+
+ at item
+    Run your test case, either manually or via FATE. This can be either
+    the full FATE regression suite, or any arbitrary invocation of any
+    front-end tool provided by Libav, in any combination.
+
+ at item
+    Run @code{make lcov} to generate coverage data in HTML format.
+
+ at item
+    View @code{lcov/index.html} in your preferred HTML viewer.
+ at end enumerate
+
+You can use the command @code{make lcov-reset} to reset the coverage
+measurements. You will need to rerun @code{make lcov} after running a
+new test.
+
+ at subsection Using Valgrind
+
+The configure script provides a shortcut for using valgrind to spot bugs
+related to memory handling. Just add the option
+ at code{--toolchain=valgrind-memcheck} or @code{--toolchain=valgrind-massif}
+to your configure line, and reasonable defaults will be set for running
+FATE under the supervision of either the @strong{memcheck} or the
+ at strong{massif} tool of the valgrind suite.
+
+In case you need finer control over how valgrind is invoked, use the
+ at code{--target-exec='valgrind <your_custom_valgrind_options>} option in
+your configure line instead.
+
+ at anchor{Release process}
+ at section Release process
+
+Libav maintains a set of @strong{release branches}, which are the
+recommended deliverable for system integrators and distributors (such as
+Linux distributions, etc.). At irregular times, a @strong{release
+manager} prepares, tests and publishes tarballs on the
+ at url{http://libav.org} website.
+
+There are two kinds of releases:
+
+ at enumerate
+ at item
+ at strong{Major releases} always include the latest and greatest
+features and functionality.
+
+ at item
+ at strong{Point releases} are cut from @strong{release} branches,
+which are named @code{release/X}, with @code{X} being the release
+version number.
+ at end enumerate
+
+Note that we promise to our users that shared libraries from any Libav
+release never break programs that have been @strong{compiled} against
+previous versions of @strong{the same release series} in any case!
+
+However, from time to time, we do make API changes that require adaptations
+in applications. Such changes are only allowed in (new) major releases and
+require further steps such as bumping library version numbers and/or
+adjustments to the symbol versioning file. Please discuss such changes
+on the @strong{libav-devel} mailing list in time to allow forward planning.
+
+ at anchor{Criteria for Point Releases}
+ at subsection Criteria for Point Releases
+
+Changes that match the following criteria are valid candidates for
+inclusion into a point release:
+
+ at enumerate
+ at item
+Fixes a security issue, preferably identified by a @strong{CVE
+number} issued by @url{http://cve.mitre.org/}.
+
+ at item
+Fixes a documented bug in @url{http://bugzilla.libav.org}.
+
+ at item
+Improves the included documentation.
+
+ at item
+Retains both source code and binary compatibility with previous
+point releases of the same release branch.
+ at end enumerate
+
+The order for checking the rules is (1 OR 2 OR 3) AND 4.
+
+All Libav developers are welcome to nominate commits that they push to
+ at code{master} by mailing the @strong{libav-stable} mailing list. The
+easiest way to do so is to include @code{CC: libav-stable@@libav.org} in
+the commit message.
+
+
+ at subsection Release Checklist
+
+The release process involves the following steps:
+
+ at enumerate
+ at item
+Ensure that the @file{RELEASE} file contains the version number for
+the upcoming release.
+
+ at item
+File a release tracking bug in @url{http://bugzilla.libav.org}. Make
+sure that the bug has an alias named @code{ReleaseX.Y} for the
+ at code{X.Y} release.
+
+ at item
+Announce the intent to do a release to the mailing list.
+
+ at item
+Reassign unresolved blocking bugs from previous release
+tracking bugs to the new bug.
+
+ at item
+Review patch nominations that reach the @strong{libav-stable}
+mailing list, and push patches that fulfill the stable release
+criteria to the release branch.
+
+ at item
+Ensure that the FATE regression suite still passes in the release
+branch on at least @strong{i386} and @strong{amd64}
+(cf. @ref{Regression Tests}).
+
+ at item
+Prepare the release tarballs in @code{xz} and @code{gz} formats, and
+supplementing files that contain @code{md5} and @code{sha1}
+checksums.
+
+ at item
+Publish the tarballs at @url{http://libav.org/releases}. Create and
+push an annotated tag in the form @code{vX}, with @code{X}
+containing the version number.
+
+ at item
+Build the tarballs with the Windows binaries, and publish them at
+ at url{http://win32.libav.org/releases}.
+
+ at item
+Propose and send a patch to the @strong{libav-devel} mailing list
+with a news entry for the website.
+
+ at item
+Publish the news entry.
+
+ at item
+Send announcement to the mailing list.
+ at end enumerate
+
 @bye
diff --git a/doc/encoders.texi b/doc/encoders.texi
index 0491d73..d6f4bce 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -412,4 +412,282 @@ Selected by Encoder (default)
 
 @end table
 
+ at section libwavpack
+
+A wrapper providing WavPack encoding through libwavpack.
+
+Only lossless mode using 32-bit integer samples is supported currently.
+The @option{compression_level} option can be used to control speed vs.
+compression tradeoff, with the values mapped to libwavpack as follows:
+
+ at table @option
+
+ at item 0
+Fast mode - corresponding to the wavpack @option{-f} option.
+
+ at item 1
+Normal (default) settings.
+
+ at item 2
+High quality - corresponding to the wavpack @option{-h} option.
+
+ at item 3
+Very high quality - corresponding to the wavpack @option{-hh} option.
+
+ at item 4-8
+Same as 3, but with extra processing enabled - corresponding to the wavpack
+ at option{-x} option. I.e. 4 is the same as @option{-x2} and 8 is the same as
+ at option{-x6}.
+
+ at end table
+
 @c man end AUDIO ENCODERS
+
+ at chapter Video Encoders
+ at c man begin VIDEO ENCODERS
+
+ at section libx264
+
+x264 H.264/MPEG-4 AVC encoder wrapper
+
+x264 supports an impressive number of features, including 8x8 and 4x4 adaptive
+spatial transform, adaptive B-frame placement, CAVLC/CABAC entropy coding,
+interlacing (MBAFF), lossless mode, psy optimizations for detail retention
+(adaptive quantization, psy-RD, psy-trellis).
+
+The Libav wrapper provides a mapping for most of them using global options
+that match those of the encoders and provides private options for the unique
+encoder options. Additionally an expert override is provided to directly pass
+a list of key=value tuples as accepted by x264_param_parse.
+
+ at subsection Option Mapping
+
+The following options are supported by the x264 wrapper, the x264-equivalent
+options follow the Libav ones.
+
+ at multitable @columnfractions .2 .2
+ at item b                 @tab bitrate
+Libav @code{b} option is expressed in bits/s, x264 @code{bitrate} in kilobits/s.
+ at item bf                @tab bframes
+Maximum number of B-frames.
+ at item g                 @tab keyint
+Maximum GOP size.
+ at item qmin              @tab qpmin
+ at item qmax              @tab qpmax
+ at item qdiff             @tab qpstep
+ at item qblur             @tab qblur
+ at item qcomp             @tab qcomp
+ at item refs              @tab ref
+ at item sc_threshold      @tab scenecut
+ at item trellis           @tab trellis
+ at item nr                @tab nr
+Noise reduction.
+ at item me_range          @tab merange
+ at item me_method         @tab me
+ at item subq              @tab subme
+ at item b_strategy        @tab b-adapt
+ at item keyint_min        @tab keyint-min
+ at item coder             @tab cabac
+Set coder to @code{ac} to use CABAC.
+ at item cmp               @tab chroma-me
+Set to @code{chroma} to use chroma motion estimation.
+ at item threads           @tab threads
+ at item thread_type       @tab sliced_threads
+Set to @code{slice} to use sliced threading instead of frame threading.
+ at item flags -cgop       @tab open-gop
+Set @code{-cgop} to use recovery points to close GOPs.
+ at item rc_init_occupancy @tab vbv-init
+Initial buffer occupancy.
+ at end multitable
+
+ at subsection Private Options
+ at table @option
+ at item -preset @var{string}
+Set the encoding preset (cf. x264 --fullhelp).
+ at item -tune @var{string}
+Tune the encoding params (cf. x264 --fullhelp).
+ at item -profile @var{string}
+Set profile restrictions (cf. x264 --fullhelp).
+ at item -fastfirstpass @var{integer}
+Use fast settings when encoding first pass.
+ at item -crf @var{float}
+Select the quality for constant quality mode.
+ at item -crf_max @var{float}
+In CRF mode, prevents VBV from lowering quality beyond this point.
+ at item -qp @var{integer}
+Constant quantization parameter rate control method.
+ at item -aq-mode @var{integer}
+AQ method
+
+Possible values:
+ at table @samp
+ at item none
+
+ at item variance
+Variance AQ (complexity mask).
+ at item autovariance
+Auto-variance AQ (experimental).
+ at end table
+ at item -aq-strength @var{float}
+AQ strength, reduces blocking and blurring in flat and textured areas.
+ at item -psy @var{integer}
+Use psychovisual optimizations.
+ at item -psy-rd @var{string}
+Strength of psychovisual optimization, in <psy-rd>:<psy-trellis> format.
+ at item -rc-lookahead @var{integer}
+Number of frames to look ahead for frametype and ratecontrol.
+ at item -weightb @var{integer}
+Weighted prediction for B-frames.
+ at item -weightp @var{integer}
+Weighted prediction analysis method.
+
+Possible values:
+ at table @samp
+ at item none
+
+ at item simple
+
+ at item smart
+
+ at end table
+ at item -ssim @var{integer}
+Calculate and print SSIM stats.
+ at item -intra-refresh @var{integer}
+Use Periodic Intra Refresh instead of IDR frames.
+ at item -bluray-compat @var{integer}
+Configure the encoder to be compatible with the bluray standard.
+It is a shorthand for setting "bluray-compat=1 force-cfr=1".
+ at item -b-bias @var{integer}
+Influences how often B-frames are used.
+ at item -b-pyramid @var{integer}
+Keep some B-frames as references.
+
+Possible values:
+ at table @samp
+ at item none
+
+ at item strict
+Strictly hierarchical pyramid.
+ at item normal
+Non-strict (not Blu-ray compatible).
+ at end table
+ at item -mixed-refs @var{integer}
+One reference per partition, as opposed to one reference per macroblock.
+ at item -8x8dct @var{integer}
+High profile 8x8 transform.
+ at item -fast-pskip @var{integer}
+ at item -aud @var{integer}
+Use access unit delimiters.
+ at item -mbtree @var{integer}
+Use macroblock tree ratecontrol.
+ at item -deblock @var{string}
+Loop filter parameters, in <alpha:beta> form.
+ at item -cplxblur @var{float}
+Reduce fluctuations in QP (before curve compression).
+ at item -partitions @var{string}
+A comma-separated list of partitions to consider, possible values: p8x8, p4x4, b8x8, i8x8, i4x4, none, all.
+ at item -direct-pred @var{integer}
+Direct MV prediction mode
+
+Possible values:
+ at table @samp
+ at item none
+
+ at item spatial
+
+ at item temporal
+
+ at item auto
+
+ at end table
+ at item -slice-max-size @var{integer}
+Limit the size of each slice in bytes.
+ at item -stats @var{string}
+Filename for 2 pass stats.
+ at item -nal-hrd @var{integer}
+Signal HRD information (requires vbv-bufsize; cbr not allowed in .mp4).
+
+Possible values:
+ at table @samp
+ at item none
+
+ at item vbr
+
+ at item cbr
+
+ at end table
+ at item -x264-params @var{string}
+Override the x264 configuration using a :-separated list of key=value parameters.
+ at example
+-x264-params level=30:bframes=0:weightp=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:subq=6:8x8dct=0:trellis=0
+ at end example
+ at end table
+
+Encoding avpresets for common usages are provided so they can be used with the
+general presets system (e.g. passing the @code{-pre} option).
+
+ at section ProRes
+
+Apple ProRes encoder.
+
+ at subsection Private Options
+
+ at table @option
+ at item profile @var{integer}
+Select the ProRes profile to encode
+ at table @samp
+ at item proxy
+ at item lt
+ at item standard
+ at item hq
+ at item 4444
+ at end table
+
+ at item quant_mat @var{integer}
+Select quantization matrix.
+ at table @samp
+ at item auto
+ at item default
+ at item proxy
+ at item lt
+ at item standard
+ at item hq
+ at end table
+If set to @var{auto}, the matrix matching the profile will be picked.
+If not set, the matrix providing the highest quality, @var{default}, will be
+picked.
+
+ at item bits_per_mb @var{integer}
+How many bits to allot for coding one macroblock. Different profiles use
+between 200 and 2400 bits per macroblock, the maximum is 8000.
+
+ at item mbs_per_slice @var{integer}
+Number of macroblocks in each slice (1-8); the default value (8)
+should be good in almost all situations.
+
+ at item vendor @var{string}
+Override the 4-byte vendor ID.
+A custom vendor ID like @var{apl0} would claim the stream was produced by
+the Apple encoder.
+
+ at item alpha_bits @var{integer}
+Specify number of bits for alpha component.
+Possible values are @var{0}, @var{8} and @var{16}.
+Use @var{0} to disable alpha plane coding.
+
+ at end table
+
+ at subsection Speed considerations
+
+In the default mode of operation the encoder has to honor frame constraints
+(i.e. not produc frames with size bigger than requested) while still making
+output picture as good as possible.
+A frame containing a lot of small details is harder to compress and the encoder
+would spend more time searching for appropriate quantizers for each slice.
+
+Setting a higher @option{bits_per_mb} limit will improve the speed.
+
+For the fastest encoding speed set the @option{qscale} parameter (4 is the
+recommended value) and do not set a size constraint.
+
+ at c man end VIDEO ENCODERS
diff --git a/doc/examples/output.c b/doc/examples/output.c
new file mode 100644
index 0000000..06fdf50
--- /dev/null
+++ b/doc/examples/output.c
@@ -0,0 +1,527 @@
+/*
+ * 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 doc/examples/output.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"
+
+/* 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 = av_frame_alloc();
+    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);
+    }
+    av_frame_free(&frame);
+}
+
+static void close_audio(AVFormatContext *oc, AVStream *st)
+{
+    avcodec_close(st->codec);
+
+    av_free(samples);
+}
+
+/**************************************************************/
+/* video output */
+
+static AVFrame *picture, *tmp_picture;
+static int frame_count;
+
+/* 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 = av_frame_alloc();
+    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);
+    }
+
+    /* 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 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 {
+        AVPacket pkt = { 0 };
+        int got_packet;
+        av_init_packet(&pkt);
+
+        /* encode the image */
+        ret = avcodec_encode_video2(c, &pkt, picture, &got_packet);
+        /* If size is zero, it means the image was buffered. */
+        if (!ret && got_packet && pkt.size) {
+            if (pkt.pts != AV_NOPTS_VALUE) {
+                pkt.pts = av_rescale_q(pkt.pts,
+                                       c->time_base, st->time_base);
+            }
+            if (pkt.dts != AV_NOPTS_VALUE) {
+                pkt.dts = av_rescale_q(pkt.dts,
+                                       c->time_base, st->time_base);
+            }
+            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(picture->data[0]);
+    av_free(picture);
+    if (tmp_picture) {
+        av_free(tmp_picture->data[0]);
+        av_free(tmp_picture);
+    }
+}
+
+/**************************************************************/
+/* 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/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c
new file mode 100644
index 0000000..46f61d8
--- /dev/null
+++ b/doc/examples/transcode_aac.c
@@ -0,0 +1,769 @@
+/*
+ * 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 simple audio converter
+ * Convert an input audio file to AAC in an MP4 container using Libav.
+ * @author Andreas Unterweger (dustsigns at gmail.com)
+ */
+
+#include <stdio.h>
+
+#include "libavformat/avformat.h"
+#include "libavformat/avio.h"
+
+#include "libavcodec/avcodec.h"
+
+#include "libavutil/audio_fifo.h"
+#include "libavutil/avstring.h"
+#include "libavutil/frame.h"
+#include "libavutil/opt.h"
+
+#include "libavresample/avresample.h"
+
+/** The output bit rate in kbit/s */
+#define OUTPUT_BIT_RATE 48000
+/** The number of output channels */
+#define OUTPUT_CHANNELS 2
+/** The audio sample output format */
+#define OUTPUT_SAMPLE_FORMAT AV_SAMPLE_FMT_S16
+
+/**
+ * Convert an error code into a text message.
+ * @param error Error code to be converted
+ * @return Corresponding error text (not thread-safe)
+ */
+static char *const get_error_text(const int error)
+{
+    static char error_buffer[255];
+    av_strerror(error, error_buffer, sizeof(error_buffer));
+    return error_buffer;
+}
+
+/** Open an input file and the required decoder. */
+static int open_input_file(const char *filename,
+                           AVFormatContext **input_format_context,
+                           AVCodecContext **input_codec_context)
+{
+    AVCodec *input_codec;
+    int error;
+
+    /** Open the input file to read from it. */
+    if ((error = avformat_open_input(input_format_context, filename, NULL,
+                                     NULL)) < 0) {
+        fprintf(stderr, "Could not open input file '%s' (error '%s')\n",
+                filename, get_error_text(error));
+        *input_format_context = NULL;
+        return error;
+    }
+
+    /** Get information on the input file (number of streams etc.). */
+    if ((error = avformat_find_stream_info(*input_format_context, NULL)) < 0) {
+        fprintf(stderr, "Could not open find stream info (error '%s')\n",
+                get_error_text(error));
+        avformat_close_input(input_format_context);
+        return error;
+    }
+
+    /** Make sure that there is only one stream in the input file. */
+    if ((*input_format_context)->nb_streams != 1) {
+        fprintf(stderr, "Expected one audio input stream, but found %d\n",
+                (*input_format_context)->nb_streams);
+        avformat_close_input(input_format_context);
+        return AVERROR_EXIT;
+    }
+
+    /** Find a decoder for the audio stream. */
+    if (!(input_codec = avcodec_find_decoder((*input_format_context)->streams[0]->codec->codec_id))) {
+        fprintf(stderr, "Could not find input codec\n");
+        avformat_close_input(input_format_context);
+        return AVERROR_EXIT;
+    }
+
+    /** Open the decoder for the audio stream to use it later. */
+    if ((error = avcodec_open2((*input_format_context)->streams[0]->codec,
+                               input_codec, NULL)) < 0) {
+        fprintf(stderr, "Could not open input codec (error '%s')\n",
+                get_error_text(error));
+        avformat_close_input(input_format_context);
+        return error;
+    }
+
+    /** Save the decoder context for easier access later. */
+    *input_codec_context = (*input_format_context)->streams[0]->codec;
+
+    return 0;
+}
+
+/**
+ * Open an output file and the required encoder.
+ * Also set some basic encoder parameters.
+ * Some of these parameters are based on the input file's parameters.
+ */
+static int open_output_file(const char *filename,
+                            AVCodecContext *input_codec_context,
+                            AVFormatContext **output_format_context,
+                            AVCodecContext **output_codec_context)
+{
+    AVIOContext *output_io_context = NULL;
+    AVStream *stream               = NULL;
+    AVCodec *output_codec          = NULL;
+    int error;
+
+    /** Open the output file to write to it. */
+    if ((error = avio_open(&output_io_context, filename,
+                           AVIO_FLAG_WRITE)) < 0) {
+        fprintf(stderr, "Could not open output file '%s' (error '%s')\n",
+                filename, get_error_text(error));
+        return error;
+    }
+
+    /** Create a new format context for the output container format. */
+    if (!(*output_format_context = avformat_alloc_context())) {
+        fprintf(stderr, "Could not allocate output format context\n");
+        return AVERROR(ENOMEM);
+    }
+
+    /** Associate the output file (pointer) with the container format context. */
+    (*output_format_context)->pb = output_io_context;
+
+    /** Guess the desired container format based on the file extension. */
+    if (!((*output_format_context)->oformat = av_guess_format(NULL, filename,
+                                                              NULL))) {
+        fprintf(stderr, "Could not find output file format\n");
+        goto cleanup;
+    }
+
+    av_strlcpy((*output_format_context)->filename, filename,
+               sizeof((*output_format_context)->filename));
+
+    /** Find the encoder to be used by its name. */
+    if (!(output_codec = avcodec_find_encoder(AV_CODEC_ID_AAC))) {
+        fprintf(stderr, "Could not find an AAC encoder.\n");
+        goto cleanup;
+    }
+
+    /** Create a new audio stream in the output file container. */
+    if (!(stream = avformat_new_stream(*output_format_context, output_codec))) {
+        fprintf(stderr, "Could not create new stream\n");
+        error = AVERROR(ENOMEM);
+        goto cleanup;
+    }
+
+    /** Save the encoder context for easiert access later. */
+    *output_codec_context = stream->codec;
+
+    /**
+     * Set the basic encoder parameters.
+     * The input file's sample rate is used to avoid a sample rate conversion.
+     */
+    (*output_codec_context)->channels       = OUTPUT_CHANNELS;
+    (*output_codec_context)->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS);
+    (*output_codec_context)->sample_rate    = input_codec_context->sample_rate;
+    (*output_codec_context)->sample_fmt     = AV_SAMPLE_FMT_S16;
+    (*output_codec_context)->bit_rate       = OUTPUT_BIT_RATE;
+
+    /**
+     * Some container formats (like MP4) require global headers to be present
+     * Mark the encoder so that it behaves accordingly.
+     */
+    if ((*output_format_context)->oformat->flags & AVFMT_GLOBALHEADER)
+        (*output_codec_context)->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+    /** Open the encoder for the audio stream to use it later. */
+    if ((error = avcodec_open2(*output_codec_context, output_codec, NULL)) < 0) {
+        fprintf(stderr, "Could not open output codec (error '%s')\n",
+                get_error_text(error));
+        goto cleanup;
+    }
+
+    return 0;
+
+cleanup:
+    avio_close((*output_format_context)->pb);
+    avformat_free_context(*output_format_context);
+    *output_format_context = NULL;
+    return error < 0 ? error : AVERROR_EXIT;
+}
+
+/** Initialize one data packet for reading or writing. */
+static void init_packet(AVPacket *packet)
+{
+    av_init_packet(packet);
+    /** Set the packet data and size so that it is recognized as being empty. */
+    packet->data = NULL;
+    packet->size = 0;
+}
+
+/** Initialize one audio frame for reading from the input file */
+static int init_input_frame(AVFrame **frame)
+{
+    if (!(*frame = av_frame_alloc())) {
+        fprintf(stderr, "Could not allocate input frame\n");
+        return AVERROR(ENOMEM);
+    }
+    return 0;
+}
+
+/**
+ * Initialize the audio resampler based on the input and output codec settings.
+ * If the input and output sample formats differ, a conversion is required
+ * libavresample takes care of this, but requires initialization.
+ */
+static int init_resampler(AVCodecContext *input_codec_context,
+                          AVCodecContext *output_codec_context,
+                          AVAudioResampleContext **resample_context)
+{
+    /**
+     * Only initialize the resampler if it is necessary, i.e.,
+     * if and only if the sample formats differ.
+     */
+    if (input_codec_context->sample_fmt != output_codec_context->sample_fmt ||
+        input_codec_context->channels != output_codec_context->channels) {
+        int error;
+
+        /** Create a resampler context for the conversion. */
+        if (!(*resample_context = avresample_alloc_context())) {
+            fprintf(stderr, "Could not allocate resample context\n");
+            return AVERROR(ENOMEM);
+        }
+
+        /**
+         * Set the conversion parameters.
+         * Default channel layouts based on the number of channels
+         * are assumed for simplicity (they are sometimes not detected
+         * properly by the demuxer and/or decoder).
+         */
+        av_opt_set_int(*resample_context, "in_channel_layout",
+                       av_get_default_channel_layout(input_codec_context->channels), 0);
+        av_opt_set_int(*resample_context, "out_channel_layout",
+                       av_get_default_channel_layout(output_codec_context->channels), 0);
+        av_opt_set_int(*resample_context, "in_sample_rate",
+                       input_codec_context->sample_rate, 0);
+        av_opt_set_int(*resample_context, "out_sample_rate",
+                       output_codec_context->sample_rate, 0);
+        av_opt_set_int(*resample_context, "in_sample_fmt",
+                       input_codec_context->sample_fmt, 0);
+        av_opt_set_int(*resample_context, "out_sample_fmt",
+                       output_codec_context->sample_fmt, 0);
+
+        /** Open the resampler with the specified parameters. */
+        if ((error = avresample_open(*resample_context)) < 0) {
+            fprintf(stderr, "Could not open resample context\n");
+            avresample_free(resample_context);
+            return error;
+        }
+    }
+    return 0;
+}
+
+/** Initialize a FIFO buffer for the audio samples to be encoded. */
+static int init_fifo(AVAudioFifo **fifo)
+{
+    /** Create the FIFO buffer based on the specified output sample format. */
+    if (!(*fifo = av_audio_fifo_alloc(OUTPUT_SAMPLE_FORMAT, OUTPUT_CHANNELS, 1))) {
+        fprintf(stderr, "Could not allocate FIFO\n");
+        return AVERROR(ENOMEM);
+    }
+    return 0;
+}
+
+/** Write the header of the output file container. */
+static int write_output_file_header(AVFormatContext *output_format_context)
+{
+    int error;
+    if ((error = avformat_write_header(output_format_context, NULL)) < 0) {
+        fprintf(stderr, "Could not write output file header (error '%s')\n",
+                get_error_text(error));
+        return error;
+    }
+    return 0;
+}
+
+/** Decode one audio frame from the input file. */
+static int decode_audio_frame(AVFrame *frame,
+                              AVFormatContext *input_format_context,
+                              AVCodecContext *input_codec_context,
+                              int *data_present, int *finished)
+{
+    /** Packet used for temporary storage. */
+    AVPacket input_packet;
+    int error;
+    init_packet(&input_packet);
+
+    /** Read one audio frame from the input file into a temporary packet. */
+    if ((error = av_read_frame(input_format_context, &input_packet)) < 0) {
+        /** If we are the the end of the file, flush the decoder below. */
+        if (error == AVERROR_EOF)
+            *finished = 1;
+        else {
+            fprintf(stderr, "Could not read frame (error '%s')\n",
+                    get_error_text(error));
+            return error;
+        }
+    }
+
+    /**
+     * Decode the audio frame stored in the temporary packet.
+     * The input audio stream decoder is used to do this.
+     * If we are at the end of the file, pass an empty packet to the decoder
+     * to flush it.
+     */
+    if ((error = avcodec_decode_audio4(input_codec_context, frame,
+                                       data_present, &input_packet)) < 0) {
+        fprintf(stderr, "Could not decode frame (error '%s')\n",
+                get_error_text(error));
+        av_free_packet(&input_packet);
+        return error;
+    }
+
+    /**
+     * If the decoder has not been flushed completely, we are not finished,
+     * so that this function has to be called again.
+     */
+    if (*finished && *data_present)
+        *finished = 0;
+    av_free_packet(&input_packet);
+    return 0;
+}
+
+/**
+ * Initialize a temporary storage for the specified number of audio samples.
+ * The conversion requires temporary storage due to the different format.
+ * The number of audio samples to be allocated is specified in frame_size.
+ */
+static int init_converted_samples(uint8_t ***converted_input_samples,
+                                  AVCodecContext *output_codec_context,
+                                  int frame_size)
+{
+    int error;
+
+    /**
+     * Allocate as many pointers as there are audio channels.
+     * Each pointer will later point to the audio samples of the corresponding
+     * channels (although it may be NULL for interleaved formats).
+     */
+    if (!(*converted_input_samples = calloc(output_codec_context->channels,
+                                            sizeof(**converted_input_samples)))) {
+        fprintf(stderr, "Could not allocate converted input sample pointers\n");
+        return AVERROR(ENOMEM);
+    }
+
+    /**
+     * Allocate memory for the samples of all channels in one consecutive
+     * block for convenience.
+     */
+    if ((error = av_samples_alloc(*converted_input_samples, NULL,
+                                  output_codec_context->channels,
+                                  frame_size,
+                                  output_codec_context->sample_fmt, 0)) < 0) {
+        fprintf(stderr,
+                "Could not allocate converted input samples (error '%s')\n",
+                get_error_text(error));
+        av_freep(&(*converted_input_samples)[0]);
+        free(*converted_input_samples);
+        return error;
+    }
+    return 0;
+}
+
+/**
+ * Convert the input audio samples into the output sample format.
+ * The conversion happens on a per-frame basis, the size of which is specified
+ * by frame_size.
+ */
+static int convert_samples(uint8_t **input_data,
+                           uint8_t **converted_data, const int frame_size,
+                           AVAudioResampleContext *resample_context)
+{
+    int error;
+
+    /** Convert the samples using the resampler. */
+    if ((error = avresample_convert(resample_context, converted_data, 0,
+                                    frame_size, input_data, 0, frame_size)) < 0) {
+        fprintf(stderr, "Could not convert input samples (error '%s')\n",
+                get_error_text(error));
+        return error;
+    }
+
+    /**
+     * Perform a sanity check so that the number of converted samples is
+     * not greater than the number of samples to be converted.
+     * If the sample rates differ, this case has to be handled differently
+     */
+    if (avresample_available(resample_context)) {
+        fprintf(stderr, "Converted samples left over\n");
+        return AVERROR_EXIT;
+    }
+
+    return 0;
+}
+
+/** Add converted input audio samples to the FIFO buffer for later processing. */
+static int add_samples_to_fifo(AVAudioFifo *fifo,
+                               uint8_t **converted_input_samples,
+                               const int frame_size)
+{
+    int error;
+
+    /**
+     * Make the FIFO as large as it needs to be to hold both,
+     * the old and the new samples.
+     */
+    if ((error = av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size)) < 0) {
+        fprintf(stderr, "Could not reallocate FIFO\n");
+        return error;
+    }
+
+    /** Store the new samples in the FIFO buffer. */
+    if (av_audio_fifo_write(fifo, (void **)converted_input_samples,
+                            frame_size) < frame_size) {
+        fprintf(stderr, "Could not write data to FIFO\n");
+        return AVERROR_EXIT;
+    }
+    return 0;
+}
+
+/**
+ * Read one audio frame from the input file, decodes, converts and stores
+ * it in the FIFO buffer.
+ */
+static int read_decode_convert_and_store(AVAudioFifo *fifo,
+                                         AVFormatContext *input_format_context,
+                                         AVCodecContext *input_codec_context,
+                                         AVCodecContext *output_codec_context,
+                                         AVAudioResampleContext *resampler_context,
+                                         int *finished)
+{
+    /** Temporary storage of the input samples of the frame read from the file. */
+    AVFrame *input_frame = NULL;
+    /** Temporary storage for the converted input samples. */
+    uint8_t **converted_input_samples = NULL;
+    int data_present;
+    int ret = AVERROR_EXIT;
+
+    /** Initialize temporary storage for one input frame. */
+    if (init_input_frame(&input_frame))
+        goto cleanup;
+    /** Decode one frame worth of audio samples. */
+    if (decode_audio_frame(input_frame, input_format_context,
+                           input_codec_context, &data_present, finished))
+        goto cleanup;
+    /**
+     * If we are at the end of the file and there are no more samples
+     * in the decoder which are delayed, we are actually finished.
+     * This must not be treated as an error.
+     */
+    if (*finished && !data_present) {
+        ret = 0;
+        goto cleanup;
+    }
+    /** If there is decoded data, convert and store it */
+    if (data_present) {
+        /** Initialize the temporary storage for the converted input samples. */
+        if (init_converted_samples(&converted_input_samples, output_codec_context,
+                                   input_frame->nb_samples))
+            goto cleanup;
+
+        /**
+         * Convert the input samples to the desired output sample format.
+         * This requires a temporary storage provided by converted_input_samples.
+         */
+        if (convert_samples(input_frame->extended_data, converted_input_samples,
+                            input_frame->nb_samples, resampler_context))
+            goto cleanup;
+
+        /** Add the converted input samples to the FIFO buffer for later processing. */
+        if (add_samples_to_fifo(fifo, converted_input_samples,
+                                input_frame->nb_samples))
+            goto cleanup;
+        ret = 0;
+    }
+    ret = 0;
+
+cleanup:
+    if (converted_input_samples) {
+        av_freep(&converted_input_samples[0]);
+        free(converted_input_samples);
+    }
+    av_frame_free(&input_frame);
+
+    return ret;
+}
+
+/**
+ * Initialize one input frame for writing to the output file.
+ * The frame will be exactly frame_size samples large.
+ */
+static int init_output_frame(AVFrame **frame,
+                             AVCodecContext *output_codec_context,
+                             int frame_size)
+{
+    int error;
+
+    /** Create a new frame to store the audio samples. */
+    if (!(*frame = av_frame_alloc())) {
+        fprintf(stderr, "Could not allocate output frame\n");
+        return AVERROR_EXIT;
+    }
+
+    /**
+     * Set the frame's parameters, especially its size and format.
+     * av_frame_get_buffer needs this to allocate memory for the
+     * audio samples of the frame.
+     * Default channel layouts based on the number of channels
+     * are assumed for simplicity.
+     */
+    (*frame)->nb_samples     = frame_size;
+    (*frame)->channel_layout = output_codec_context->channel_layout;
+    (*frame)->format         = output_codec_context->sample_fmt;
+    (*frame)->sample_rate    = output_codec_context->sample_rate;
+
+    /**
+     * Allocate the samples of the created frame. This call will make
+     * sure that the audio frame can hold as many samples as specified.
+     */
+    if ((error = av_frame_get_buffer(*frame, 0)) < 0) {
+        fprintf(stderr, "Could allocate output frame samples (error '%s')\n",
+                get_error_text(error));
+        av_frame_free(frame);
+        return error;
+    }
+
+    return 0;
+}
+
+/** Encode one frame worth of audio to the output file. */
+static int encode_audio_frame(AVFrame *frame,
+                              AVFormatContext *output_format_context,
+                              AVCodecContext *output_codec_context,
+                              int *data_present)
+{
+    /** Packet used for temporary storage. */
+    AVPacket output_packet;
+    int error;
+    init_packet(&output_packet);
+
+    /**
+     * Encode the audio frame and store it in the temporary packet.
+     * The output audio stream encoder is used to do this.
+     */
+    if ((error = avcodec_encode_audio2(output_codec_context, &output_packet,
+                                       frame, data_present)) < 0) {
+        fprintf(stderr, "Could not encode frame (error '%s')\n",
+                get_error_text(error));
+        av_free_packet(&output_packet);
+        return error;
+    }
+
+    /** Write one audio frame from the temporary packet to the output file. */
+    if (*data_present) {
+        if ((error = av_write_frame(output_format_context, &output_packet)) < 0) {
+            fprintf(stderr, "Could not write frame (error '%s')\n",
+                    get_error_text(error));
+            av_free_packet(&output_packet);
+            return error;
+        }
+
+        av_free_packet(&output_packet);
+    }
+
+    return 0;
+}
+
+/**
+ * Load one audio frame from the FIFO buffer, encode and write it to the
+ * output file.
+ */
+static int load_encode_and_write(AVAudioFifo *fifo,
+                                 AVFormatContext *output_format_context,
+                                 AVCodecContext *output_codec_context)
+{
+    /** Temporary storage of the output samples of the frame written to the file. */
+    AVFrame *output_frame;
+    /**
+     * Use the maximum number of possible samples per frame.
+     * If there is less than the maximum possible frame size in the FIFO
+     * buffer use this number. Otherwise, use the maximum possible frame size
+     */
+    const int frame_size = FFMIN(av_audio_fifo_size(fifo),
+                                 output_codec_context->frame_size);
+    int data_written;
+
+    /** Initialize temporary storage for one output frame. */
+    if (init_output_frame(&output_frame, output_codec_context, frame_size))
+        return AVERROR_EXIT;
+
+    /**
+     * Read as many samples from the FIFO buffer as required to fill the frame.
+     * The samples are stored in the frame temporarily.
+     */
+    if (av_audio_fifo_read(fifo, (void **)output_frame->data, frame_size) < frame_size) {
+        fprintf(stderr, "Could not read data from FIFO\n");
+        av_frame_free(&output_frame);
+        return AVERROR_EXIT;
+    }
+
+    /** Encode one frame worth of audio samples. */
+    if (encode_audio_frame(output_frame, output_format_context,
+                           output_codec_context, &data_written)) {
+        av_frame_free(&output_frame);
+        return AVERROR_EXIT;
+    }
+    av_frame_free(&output_frame);
+    return 0;
+}
+
+/** Write the trailer of the output file container. */
+static int write_output_file_trailer(AVFormatContext *output_format_context)
+{
+    int error;
+    if ((error = av_write_trailer(output_format_context)) < 0) {
+        fprintf(stderr, "Could not write output file trailer (error '%s')\n",
+                get_error_text(error));
+        return error;
+    }
+    return 0;
+}
+
+/** Convert an audio file to an AAC file in an MP4 container. */
+int main(int argc, char **argv)
+{
+    AVFormatContext *input_format_context = NULL, *output_format_context = NULL;
+    AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL;
+    AVAudioResampleContext *resample_context = NULL;
+    AVAudioFifo *fifo = NULL;
+    int ret = AVERROR_EXIT;
+
+    if (argc < 3) {
+        fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
+        exit(1);
+    }
+
+    /** Register all codecs and formats so that they can be used. */
+    av_register_all();
+    /** Open the input file for reading. */
+    if (open_input_file(argv[1], &input_format_context,
+                        &input_codec_context))
+        goto cleanup;
+    /** Open the output file for writing. */
+    if (open_output_file(argv[2], input_codec_context,
+                         &output_format_context, &output_codec_context))
+        goto cleanup;
+    /** Initialize the resampler to be able to convert audio sample formats. */
+    if (init_resampler(input_codec_context, output_codec_context,
+                       &resample_context))
+        goto cleanup;
+    /** Initialize the FIFO buffer to store audio samples to be encoded. */
+    if (init_fifo(&fifo))
+        goto cleanup;
+    /** Write the header of the output file container. */
+    if (write_output_file_header(output_format_context))
+        goto cleanup;
+
+    /**
+     * Loop as long as we have input samples to read or output samples
+     * to write; abort as soon as we have neither.
+     */
+    while (1) {
+        /** Use the encoder's desired frame size for processing. */
+        const int output_frame_size = output_codec_context->frame_size;
+        int finished                = 0;
+
+        /**
+         * Make sure that there is one frame worth of samples in the FIFO
+         * buffer so that the encoder can do its work.
+         * Since the decoder's and the encoder's frame size may differ, we
+         * need to FIFO buffer to store as many frames worth of input samples
+         * that they make up at least one frame worth of output samples.
+         */
+        while (av_audio_fifo_size(fifo) < output_frame_size) {
+            /**
+             * Decode one frame worth of audio samples, convert it to the
+             * output sample format and put it into the FIFO buffer.
+             */
+            if (read_decode_convert_and_store(fifo, input_format_context,
+                                              input_codec_context,
+                                              output_codec_context,
+                                              resample_context, &finished))
+                goto cleanup;
+
+            /**
+             * If we are at the end of the input file, we continue
+             * encoding the remaining audio samples to the output file.
+             */
+            if (finished)
+                break;
+        }
+
+        /**
+         * If we have enough samples for the encoder, we encode them.
+         * At the end of the file, we pass the remaining samples to
+         * the encoder.
+         */
+        while (av_audio_fifo_size(fifo) >= output_frame_size ||
+               (finished && av_audio_fifo_size(fifo) > 0))
+            /**
+             * Take one frame worth of audio samples from the FIFO buffer,
+             * encode it and write it to the output file.
+             */
+            if (load_encode_and_write(fifo, output_format_context,
+                                      output_codec_context))
+                goto cleanup;
+
+        /**
+         * If we are at the end of the input file and have encoded
+         * all remaining samples, we can exit this loop and finish.
+         */
+        if (finished) {
+            int data_written;
+            /** Flush the encoder as it may have delayed frames. */
+            do {
+                if (encode_audio_frame(NULL, output_format_context,
+                                       output_codec_context, &data_written))
+                    goto cleanup;
+            } while (data_written);
+            break;
+        }
+    }
+
+    /** Write the trailer of the output file container. */
+    if (write_output_file_trailer(output_format_context))
+        goto cleanup;
+    ret = 0;
+
+cleanup:
+    if (fifo)
+        av_audio_fifo_free(fifo);
+    if (resample_context) {
+        avresample_close(resample_context);
+        avresample_free(&resample_context);
+    }
+    if (output_codec_context)
+        avcodec_close(output_codec_context);
+    if (output_format_context) {
+        avio_close(output_format_context->pb);
+        avformat_free_context(output_format_context);
+    }
+    if (input_codec_context)
+        avcodec_close(input_codec_context);
+    if (input_format_context)
+        avformat_close_input(&input_format_context);
+
+    return ret;
+}
diff --git a/doc/faq.texi b/doc/faq.texi
index 088ca03..b400124 100644
--- a/doc/faq.texi
+++ b/doc/faq.texi
@@ -202,8 +202,8 @@ Just create an "input.avs" text file with this single line ...
   avconv -i input.avs
 @end example
 
-For ANY other help on Avisynth, please visit the
- at uref{http://www.avisynth.org/, Avisynth homepage}.
+For ANY other help on AviSynth, please visit the
+ at uref{http://www.avisynth.org/, AviSynth homepage}.
 
 @section How can I join video files?
 
diff --git a/doc/fate.texi b/doc/fate.texi
index 975f40a..0185d87 100644
--- a/doc/fate.texi
+++ b/doc/fate.texi
@@ -51,11 +51,14 @@ Specific Makefile targets and Makefile variables are available:
 
 @anchor{Makefile target}
 @section FATE 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.
+
 @item fate
 Run the FATE test suite (requires the fate-suite dataset).
 @end table
@@ -64,27 +67,38 @@ Run the FATE test suite (requires the fate-suite dataset).
 @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
+ at item 0
+show just the test arguments
+
+ at item 1
+show just the command used in the test
+
+ at item 2
+show everything
 @end table
+
 @item SAMPLES
 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.
+
 @item THREAD_TYPE
 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.
+
 @item TARGET_EXEC
 Specify or override the wrapper used to run the tests.
+
+ at item GEN
+Set to @var{1} to generate the missing or mismatched references.
 @end table
 
 @example
@@ -118,16 +132,20 @@ 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
+build_only=     # set to "yes" for a compile-only instance that skips tests
 
 # the following are optional and map to configure options
 arch=
 cpu=
 cross_prefix=
+as=
 cc=
+ld=
 target_os=
 sysroot=
 target_exec=
 target_path=
+target_samples=
 extra_cflags=
 extra_ldflags=
 extra_libs=
diff --git a/doc/filters.texi b/doc/filters.texi
index 1933b17..b32aad1 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -21,7 +21,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
 @code{avfilter_graph_parse()}/@code{avfilter_graph_parse2()} function defined in
- at file{libavfilter/avfiltergraph.h}.
+ at file{libavfilter/avfilter.h}.
 
 A filterchain consists of a sequence of connected filters, each one
 connected to the previous one in the sequence. A filterchain is
@@ -41,8 +41,25 @@ The name of the filter class is optionally followed by a string
 "=@var{arguments}".
 
 @var{arguments} is a string which contains the parameters used to
-initialize the filter instance, and are described in the filter
-descriptions below.
+initialize the filter instance. It may have one of the two allowed forms:
+ at itemize
+
+ at item
+A ':'-separated list of @var{key=value} pairs.
+
+ at item
+A ':'-separated list of @var{value}. In this case, the keys are assumed to be
+the option names in the order they are declared. E.g. the @code{fade} filter
+declares three options in this order -- @option{type}, @option{start_frame} and
+ at option{nb_frames}. Then the parameter list @var{in:0:30} means that the value
+ at var{in} is assigned to the option @option{type}, @var{0} to
+ at option{start_frame} and @var{30} to @option{nb_frames}.
+
+ at end itemize
+
+If the option value itself is a list of items (e.g. the @code{format} filter
+takes a list of pixel formats), the items in the list are usually separated by
+'|'.
 
 The list of arguments can be quoted using the character "'" as initial
 and ending mark, and the character '\' for escaping the characters
@@ -78,7 +95,7 @@ In a complete filterchain all the unlabelled filter input and output
 pads must be connected. A filtergraph is considered valid if all the
 filter input and output pads of all the filterchains are connected.
 
-Libavfilter will automatically insert scale filters where format
+Libavfilter will automatically insert @ref{scale} filters where format
 conversion is required. It is possible to specify swscale flags
 for those automatically inserted scalers by prepending
 @code{sws_flags=@var{flags};}
@@ -116,13 +133,13 @@ The filter accepts the following named parameters:
 @table @option
 
 @item sample_fmts
-A comma-separated list of requested sample formats.
+A '|'-separated list of requested sample formats.
 
 @item sample_rates
-A comma-separated list of requested sample rates.
+A '|'-separated list of requested sample rates.
 
 @item channel_layouts
-A comma-separated list of requested channel layouts.
+A '|'-separated list of requested channel layouts.
 
 @end table
 
@@ -130,7 +147,7 @@ If a parameter is omitted, all values are allowed.
 
 For example to force the output to either unsigned 8-bit or signed 16-bit stereo:
 @example
-aformat=sample_fmts\=u8\,s16:channel_layouts\=stereo
+aformat=sample_fmts=u8|s16:channel_layouts=stereo
 @end example
 
 @section amix
@@ -175,6 +192,75 @@ stream ends. The default value is 2 seconds.
 
 Pass the audio source unchanged to the output.
 
+ at section asetpts
+
+Change the PTS (presentation timestamp) of the input audio frames.
+
+This filter accepts the following options:
+
+ at table @option
+
+ at item expr
+The expression which is evaluated for each frame to construct its timestamp.
+
+ at end table
+
+The expression is evaluated through the eval API and can contain the following
+constants:
+
+ at table @option
+ at item PTS
+the presentation timestamp in input
+
+ at item PI
+Greek PI
+
+ at item PHI
+golden ratio
+
+ at item E
+Euler number
+
+ at item N
+Number of the audio samples pass through the filter so far, starting at 0.
+
+ at item S
+Number of the audio samples in the current frame.
+
+ at item SR
+Audio sample rate.
+
+ at item STARTPTS
+the PTS of the first frame
+
+ at item PREV_INPTS
+previous input PTS
+
+ at item PREV_OUTPTS
+previous output PTS
+
+ at item RTCTIME
+wallclock (RTC) time in microseconds
+
+ at item RTCSTART
+wallclock (RTC) time at the start of the movie in microseconds
+
+ at end table
+
+Some examples follow:
+
+ at example
+# start counting PTS from zero
+asetpts=expr=PTS-STARTPTS
+
+#generate timestamps by counting samples
+asetpts=expr=N/SR/TB
+
+# generate timestamps from a "live source" and rebase onto the current timebase
+asetpts='(RTCTIME - RTCSTART) / (TB * 1000000)"
+ at end example
+
+
 @section ashowinfo
 
 Show a line containing various information for each input audio frame.
@@ -259,6 +345,70 @@ with a negative pts due to encoder delay.
 
 @end table
 
+ at section atrim
+Trim the input so that the output contains one continuous subpart of the input.
+
+This filter accepts the following options:
+ at table @option
+ at item start
+Timestamp (in seconds) of the start of the kept section. I.e. the audio sample
+with the timestamp @var{start} will be the first sample in the output.
+
+ at item end
+Timestamp (in seconds) of the first audio sample that will be dropped. I.e. the
+audio sample immediately preceding the one with the timestamp @var{end} will be
+the last sample in the output.
+
+ at item start_pts
+Same as @var{start}, except this option sets the start timestamp in samples
+instead of seconds.
+
+ at item end_pts
+Same as @var{end}, except this option sets the end timestamp in samples instead
+of seconds.
+
+ at item duration
+Maximum duration of the output in seconds.
+
+ at item start_sample
+Number of the first sample that should be passed to output.
+
+ at item end_sample
+Number of the first sample that should be dropped.
+ at end table
+
+Note that the first two sets of the start/end options and the @option{duration}
+option look at the frame timestamp, while the _sample options simply count the
+samples that pass through the filter. So start/end_pts and start/end_sample will
+give different results when the timestamps are wrong, inexact or do not start at
+zero. Also note that this filter does not modify the timestamps. If you wish
+that the output timestamps start at zero, insert the asetpts filter after the
+atrim filter.
+
+If multiple start or end options are set, this filter tries to be greedy and
+keep all samples that match at least one of the specified constraints. To keep
+only the part that matches all the constraints at once, chain multiple atrim
+filters.
+
+The defaults are such that all the input is kept. So it is possible to set e.g.
+just the end values to keep everything before the specified time.
+
+Examples:
+ at itemize
+ at item
+drop everything except the second minute of input
+ at example
+avconv -i INPUT -af atrim=60:120
+ at end example
+
+ at item
+keep only the first 1000 samples
+ at example
+avconv -i INPUT -af atrim=end_sample=1000
+ at end example
+
+ at end itemize
+
 @section channelsplit
 Split each channel in input audio stream into a separate output stream.
 
@@ -293,7 +443,7 @@ This filter accepts the following named parameters:
 Channel layout of the output stream.
 
 @item map
-Map channels from input to output. The argument is a comma-separated list of
+Map channels from input to output. The argument is a '|'-separated list of
 mappings, each in the @code{@var{in_channel}- at var{out_channel}} or
 @var{in_channel} form. @var{in_channel} can be either the name of the input
 channel (e.g. FL for front left) or its index in the input channel layout.
@@ -307,14 +457,14 @@ output channels preserving index.
 
 For example, assuming a 5.1+downmix input MOV file
 @example
-avconv -i in.mov -filter 'channelmap=map=DL-FL\,DR-FR' out.wav
+avconv -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
+avconv -i in.wav -filter 'channelmap=1|2|0|5|3|4:channel_layout=5.1' out.wav
 @end example
 
 @section join
@@ -330,7 +480,7 @@ Number of input streams. Defaults to 2.
 Desired output channel layout. Defaults to stereo.
 
 @item map
-Map channels from inputs to output. The argument is a comma-separated list of
+Map channels from inputs to output. The argument is a '|'-separated list of
 mappings, each in the @code{@var{input_idx}. at var{in_channel}- at var{out_channel}}
 form. @var{input_idx} is the 0-based index of the input stream. @var{in_channel}
 can be either the name of the input channel (e.g. FL for front left) or its
@@ -350,7 +500,7 @@ avconv -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
 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
-'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'
+'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
 
@@ -516,23 +666,35 @@ the position in the file if known or -1 and the timestamp in seconds.
 In order to display the output lines, you need to set the loglevel at
 least to the AV_LOG_INFO value.
 
-The filter accepts the syntax:
- at example
-blackframe[=@var{amount}:[@var{threshold}]]
- at end example
+The filter accepts the following options:
+
+ at table @option
 
- at var{amount} is the percentage of the pixels that have to be below the
-threshold, and defaults to 98.
+ at item amount
+The percentage of the pixels that have to be below the threshold, defaults to
+98.
 
- at var{threshold} is the threshold below which a pixel value is
-considered black, and defaults to 32.
+ at item threshold
+Threshold below which a pixel value is considered black, defaults to 32.
+
+ at end table
 
 @section boxblur
 
 Apply boxblur algorithm to the input video.
 
-This filter accepts the parameters:
- at var{luma_power}:@var{luma_radius}:@var{chroma_radius}:@var{chroma_power}:@var{alpha_radius}:@var{alpha_power}
+This filter accepts the following options:
+
+ at table @option
+
+ at item luma_radius
+ at item luma_power
+ at item chroma_radius
+ at item chroma_power
+ at item alpha_radius
+ at item alpha_power
+
+ at end table
 
 Chroma and alpha parameters are optional, if not specified they default
 to the corresponding values set for @var{luma_radius} and
@@ -570,7 +732,7 @@ Some examples follow:
 Apply a boxblur filter with luma, chroma, and alpha radius
 set to 2:
 @example
-boxblur=2:1
+boxblur=luma_radius=2:luma_power=1
 @end example
 
 @item
@@ -582,7 +744,7 @@ boxblur=2:1:0:0:0:0
 @item
 Set luma and chroma radius to a fraction of the video dimension
 @example
-boxblur=min(h\,w)/10:1:min(cw\,ch)/10:1
+boxblur=luma_radius=min(h\,w)/10:luma_power=1:chroma_radius=min(cw\,ch)/10:chroma_power=1
 @end example
 
 @end itemize
@@ -594,7 +756,25 @@ testing purposes.
 
 @section crop
 
-Crop the input video to @var{out_w}:@var{out_h}:@var{x}:@var{y}.
+Crop the input video to given dimensions.
+
+This filter accepts the following options:
+
+ at table @option
+
+ at item out_w
+Width of the output video.
+
+ at item out_h
+Height of the output video.
+
+ at item x
+Horizontal position, in the input video, of the left edge of the output video.
+
+ at item y
+Vertical position, in the input video, of the top edge of the output video.
+
+ at end table
 
 The parameters are expressions containing the following constants:
 
@@ -622,9 +802,6 @@ same as @var{out_w} and @var{out_h}
 @item n
 the number of input frame, starting from 0
 
- at item pos
-the position in the file of the input frame, NAN if unknown
-
 @item t
 timestamp expressed in seconds, NAN if the input timestamp is unknown
 
@@ -657,34 +834,34 @@ for @var{y} may depend on @var{x}.
 Follow some examples:
 @example
 # crop the central input area with size 100x100
-crop=100:100
+crop=out_w=100:out_h=100
 
 # crop the central input area with size 2/3 of the input video
-"crop=2/3*in_w:2/3*in_h"
+"crop=out_w=2/3*in_w:out_h=2/3*in_h"
 
 # crop the input video central square
-crop=in_h
+crop=out_w=in_h
 
 # delimit the rectangle with the top-left corner placed at position
 # 100:100 and the right-bottom corner corresponding to the right-bottom
 # corner of the input image.
-crop=in_w-100:in_h-100:100:100
+crop=out_w=in_w-100:out_h=in_h-100:x=100:y=100
 
 # crop 10 pixels from the left and right borders, and 20 pixels from
 # the top and bottom borders
-"crop=in_w-2*10:in_h-2*20"
+"crop=out_w=in_w-2*10:out_h=in_h-2*20"
 
 # keep only the bottom right quarter of the input image
-"crop=in_w/2:in_h/2:in_w/2:in_h/2"
+"crop=out_w=in_w/2:out_h=in_h/2:x=in_w/2:y=in_h/2"
 
 # crop height for getting Greek harmony
-"crop=in_w:1/PHI*in_w"
+"crop=out_w=in_w:out_h=1/PHI*in_w"
 
 # trembling effect
 "crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(n/7)"
 
 # erratic camera effect depending on timestamp
-"crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(t*10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(t*13)"
+"crop=out_w=in_w/2:out_h=in_h/2:x=(in_w-out_w)/2+((in_w-out_w)/2)*sin(t*10):y=(in_h-out_h)/2 +((in_h-out_h)/2)*sin(t*13)"
 
 # set x depending on the value of y
 "crop=in_w/2:in_h/2:y:10+10*sin(n/10)"
@@ -698,10 +875,7 @@ Calculate necessary cropping parameters and prints the recommended
 parameters through the logging system. The detected dimensions
 correspond to the non-black area of the input video.
 
-It accepts the syntax:
- at example
-cropdetect[=@var{limit}[:@var{round}[:@var{reset}]]]
- at end example
+This filter accepts the following options:
 
 @table @option
 
@@ -731,12 +905,7 @@ Suppress a TV station logo by a simple interpolation of the surrounding
 pixels. Just set a rectangle covering the logo and watch it disappear
 (and sometimes something even uglier appear - your mileage may vary).
 
-The filter accepts parameters as a string of the form
-"@var{x}:@var{y}:@var{w}:@var{h}:@var{band}", or as a list of
- at var{key}=@var{value} pairs, separated by ":".
-
-The description of the accepted parameters follows.
-
+This filter accepts the following options:
 @table @option
 
 @item x, y
@@ -766,12 +935,6 @@ Some examples follow.
 Set a rectangle covering the area with top left corner coordinates 0,0
 and size 100x77, setting a band of size 10:
 @example
-delogo=0:0:100:77:10
- at end example
-
- at item
-As the previous example, but use named options:
- at example
 delogo=x=0:y=0:w=100:h=77:band=10
 @end example
 
@@ -781,10 +944,7 @@ delogo=x=0:y=0:w=100:h=77:band=10
 
 Draw a colored box on the input image.
 
-It accepts the syntax:
- at example
-drawbox=@var{x}:@var{y}:@var{width}:@var{height}:@var{color}
- at end example
+This filter accepts the following options:
 
 @table @option
 
@@ -806,7 +966,7 @@ Follow some examples:
 drawbox
 
 # draw a box with color red and an opacity of 50%
-drawbox=10:20:200:60:red@@0.5"
+drawbox=x=10:y=20:width=200:height=60:color=red@@0.5"
 @end example
 
 @section drawtext
@@ -820,9 +980,6 @@ To enable compilation of this filter you need to configure Libav with
 The filter also recognizes strftime() sequences in the provided text
 and expands them accordingly. Check the documentation of strftime().
 
-The filter accepts parameters as a list of @var{key}=@var{value} pairs,
-separated by ":".
-
 The description of the accepted parameters follows.
 
 @table @option
@@ -976,48 +1133,50 @@ For more information about libfreetype, check:
 
 Apply fade-in/out effect to input video.
 
-It accepts the parameters:
- at var{type}:@var{start_frame}:@var{nb_frames}
+This filter accepts the following options:
+
+ at table @option
+
+ at item type
+The effect type -- can be either "in" for fade-in, or "out" for a fade-out
+effect.
 
- at var{type} specifies if the effect type, can be either "in" for
-fade-in, or "out" for a fade-out effect.
+ at item start_frame
+The number of the start frame for starting to apply the fade effect.
 
- at var{start_frame} specifies the number of the start frame for starting
-to apply the fade effect.
+ at item nb_frames
+The number of frames for which the fade effect has to last. At the end of the
+fade-in effect the output video will have the same intensity as the input video,
+at the end of the fade-out transition the output video will be completely black.
 
- at var{nb_frames} specifies the number of frames for which the fade
-effect has to last. At the end of the fade-in effect the output video
-will have the same intensity as the input video, at the end of the
-fade-out transition the output video will be completely black.
+ at end table
 
 A few usage examples follow, usable too as test scenarios.
 @example
 # fade in first 30 frames of video
-fade=in:0:30
+fade=type=in:nb_frames=30
 
 # fade out last 45 frames of a 200-frame video
-fade=out:155:45
+fade=type=out:start_frame=155:nb_frames=45
 
 # fade in first 25 frames and fade out last 25 frames of a 1000-frame video
-fade=in:0:25, fade=out:975:25
+fade=type=in:start_frame=0:nb_frames=25, fade=type=out:start_frame=975:nb_frames=25
 
 # make first 5 frames black, then fade in from frame 5-24
-fade=in:5:20
+fade=type=in:start_frame=5:nb_frames=20
 @end example
 
 @section fieldorder
 
 Transform the field order of the input video.
 
-It accepts one parameter which specifies the required field order that
-the input interlaced video will be transformed to. The parameter can
-assume one of the following values:
+This filter accepts the following options:
 
 @table @option
- at item 0 or bff
-output bottom field first
- at item 1 or tff
-output top field first
+
+ at item order
+Output field order. Valid values are @var{tff} for top field first or @var{bff}
+for bottom field first.
 @end table
 
 Default value is "tff".
@@ -1035,7 +1194,7 @@ which is bottom field first.
 
 For example:
 @example
-./avconv -i in.vob -vf "fieldorder=bff" out.dv
+./avconv -i in.vob -vf "fieldorder=order=bff" out.dv
 @end example
 
 @section fifo
@@ -1053,18 +1212,25 @@ Convert the input video to one of the specified pixel formats.
 Libavfilter will try to pick one that is supported for the input to
 the next filter.
 
-The filter accepts a list of pixel format names, separated by ":",
-for example "yuv420p:monow:rgb24".
+This filter accepts the following parameters:
+ at table @option
+
+ at item pix_fmts
+A '|'-separated list of pixel format names, for example
+"pix_fmts=yuv420p|monow|rgb24".
+
+ at end table
 
 Some examples follow:
 @example
 # convert the input video to the format "yuv420p"
-format=yuv420p
+format=pix_fmts=yuv420p
 
 # convert the input video to any of the formats in the list
-format=yuv420p:yuv444p:yuv410p
+format=pix_fmts=yuv420p|yuv444p|yuv410p
 @end example
 
+ at anchor{fps}
 @section fps
 
 Convert the video to specified constant framerate by duplicating or dropping
@@ -1076,6 +1242,14 @@ This filter accepts the following named parameters:
 @item fps
 Desired output framerate.
 
+ at item start_time
+Assume the first PTS should be the given value, in seconds. This allows for
+padding/trimming at the start of stream. By default, no assumption is made
+about the first frame's expected PTS, so no padding or trimming is done.
+For example, this could be set to 0 to pad the beginning with duplicates of
+the first frame if a video stream starts after the audio stream or to trim any
+frames with a negative PTS.
+
 @end table
 
 @anchor{frei0r}
@@ -1086,20 +1260,22 @@ 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.
 
-The filter supports the syntax:
- at example
- at var{filter_name}[@{:|=@}@var{param1}:@var{param2}:...:@var{paramN}]
- at end example
+This filter accepts the following options:
 
- at var{filter_name} is the name to the frei0r effect to load. If the
-environment variable @env{FREI0R_PATH} is defined, the frei0r effect
-is searched in each one of the directories specified by the colon
-separated list in @env{FREIOR_PATH}, otherwise in the standard frei0r
-paths, which are in this order: @file{HOME/.frei0r-1/lib/},
- at file{/usr/local/lib/frei0r-1/}, @file{/usr/lib/frei0r-1/}.
+ at table @option
 
- at var{param1}, @var{param2}, ... , @var{paramN} specify the parameters
-for the frei0r effect.
+ at item filter_name
+The name to the frei0r effect to load. If the environment variable
+ at env{FREI0R_PATH} is defined, the frei0r effect is searched in each one of the
+directories specified by the colon separated list in @env{FREIOR_PATH},
+otherwise in the standard frei0r paths, which are in this order:
+ at file{HOME/.frei0r-1/lib/}, @file{/usr/local/lib/frei0r-1/},
+ at file{/usr/lib/frei0r-1/}.
+
+ at item filter_params
+A '|'-separated list of parameters to pass to the frei0r effect.
+
+ at end table
 
 A frei0r effect parameter can be a boolean (whose values are specified
 with "y" and "n"), a double, a color (specified by the syntax
@@ -1114,7 +1290,7 @@ 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
+frei0r=filter_name=distort0r:filter_params=0.5|0.01
 
 # apply the colordistance effect, takes a color as first parameter
 frei0r=colordistance:0.2/0.3/0.4
@@ -1123,7 +1299,7 @@ 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
+frei0r=perspective:0.2/0.2|0.8/0.2
 @end example
 
 For more information see:
@@ -1140,23 +1316,27 @@ This filter is designed for playback only.  Do not use it prior to
 lossy compression, because compression tends to lose the dither and
 bring back the bands.
 
-The filter takes two optional parameters, separated by ':':
- at var{strength}:@var{radius}
+This filter accepts the following options:
 
- at var{strength} is the maximum amount by which the filter will change
-any one pixel. Also the threshold for detecting nearly flat
-regions. Acceptable values range from .51 to 255, default value is
-1.2, out-of-range values will be clipped to the valid range.
+ at table @option
+
+ at item strength
+The maximum amount by which the filter will change any one pixel. Also the
+threshold for detecting nearly flat regions. Acceptable values range from .51 to
+64, default value is 1.2, out-of-range values will be clipped to the valid
+range.
 
- at var{radius} is the neighborhood to fit the gradient to. A larger
-radius makes for smoother gradients, but also prevents the filter from
-modifying the pixels near detailed regions. Acceptable values are
-8-32, default value is 16, out-of-range values will be clipped to the
-valid range.
+ at item radius
+The neighborhood to fit the gradient to. A larger radius makes for smoother
+gradients, but also prevents the filter from modifying the pixels near detailed
+regions. Acceptable values are 8-32, default value is 16, out-of-range values
+will be clipped to the valid range.
+
+ at end table
 
 @example
 # default parameters
-gradfun=1.2:16
+gradfun=strength=1.2:radius=16
 
 # omitting radius
 gradfun=1.2
@@ -1178,7 +1358,6 @@ image noise producing smooth images and making still images really
 still. It should enhance compressibility.
 
 It accepts the following optional parameters:
- at var{luma_spatial}:@var{chroma_spatial}:@var{luma_tmp}:@var{chroma_tmp}
 
 @table @option
 @item luma_spatial
@@ -1198,6 +1377,36 @@ a float number which specifies chroma temporal strength, defaults to
 @var{luma_tmp}*@var{chroma_spatial}/@var{luma_spatial}
 @end table
 
+ at section interlace
+
+Simple interlacing filter from progressive contents. This interleaves upper (or
+lower) lines from odd frames with lower (or upper) lines from even frames,
+halving the frame rate and preserving image height.
+
+ at example
+   Original        Original             New Frame
+   Frame 'j'      Frame 'j+1'             (tff)
+  ==========      ===========       ==================
+    Line 0  -------------------->    Frame 'j' Line 0
+    Line 1          Line 1  ---->   Frame 'j+1' Line 1
+    Line 2 --------------------->    Frame 'j' Line 2
+    Line 3          Line 3  ---->   Frame 'j+1' Line 3
+     ...             ...                   ...
+New Frame + 1 will be generated by Frame 'j+2' and Frame 'j+3' and so on
+ at end example
+
+It accepts the following optional parameters:
+
+ at table @option
+ at item scan
+determines whether the interlaced frame is taken from the even (tff - default)
+or odd (bff) lines of the progressive frame.
+
+ at item lowpass
+Enable (default) or disable the vertical lowpass filter to avoid twitter
+interlacing and reduce moire patterns.
+ at end table
+
 @section lut, lutrgb, lutyuv
 
 Compute a look-up table for binding each pixel component input value
@@ -1206,40 +1415,32 @@ to an output value, and apply it to input video.
 @var{lutyuv} applies a lookup table to a YUV input video, @var{lutrgb}
 to an RGB input video.
 
-These filters accept in input a ":"-separated list of options, which
-specify the expressions used for computing the lookup table for the
-corresponding pixel component values.
-
-The @var{lut} filter requires either YUV or RGB pixel formats in
-input, and accepts the options:
+These filters accept the following options:
 @table @option
 @item @var{c0} (first  pixel component)
 @item @var{c1} (second pixel component)
 @item @var{c2} (third  pixel component)
 @item @var{c3} (fourth pixel component, corresponds to the alpha component)
- at end table
 
-The exact component associated to each option depends on the format in
-input.
-
-The @var{lutrgb} filter requires RGB pixel formats in input, and
-accepts the options:
- at table @option
 @item @var{r} (red component)
 @item @var{g} (green component)
 @item @var{b} (blue component)
 @item @var{a} (alpha component)
- at end table
 
-The @var{lutyuv} filter requires YUV pixel formats in input, and
-accepts the options:
- at table @option
 @item @var{y} (Y/luminance component)
 @item @var{u} (U/Cb component)
 @item @var{v} (V/Cr component)
- at item @var{a} (alpha component)
 @end table
 
+Each of them specifies the expression to use for computing the lookup table for
+the corresponding pixel component values.
+
+The exact component associated to each of the @var{c*} options depends on the
+format in input.
+
+The @var{lut} filter requires either YUV or RGB pixel formats in input,
+ at var{lutrgb} requires RGB pixel formats in input, and @var{lutyuv} requires YUV.
+
 The expressions can contain the following constants and functions:
 
 @table @option
@@ -1317,20 +1518,28 @@ Negate input video.
 This filter accepts an integer in input, if non-zero it negates the
 alpha component (if available). The default value in input is 0.
 
+ at section noformat
+
 Force libavfilter not to use any of the specified pixel formats for the
 input to the next filter.
 
-The filter accepts a list of pixel format names, separated by ":",
-for example "yuv420p:monow:rgb24".
+This filter accepts the following parameters:
+ at table @option
+
+ at item pix_fmts
+A '|'-separated list of pixel format names, for example
+"pix_fmts=yuv420p|monow|rgb24".
+
+ at end table
 
 Some examples follow:
 @example
 # force libavfilter to use a format different from "yuv420p" for the
 # input to the vflip filter
-noformat=yuv420p,vflip
+noformat=pix_fmts=yuv420p,vflip
 
 # convert the input video to any of the formats not contained in the list
-noformat=yuv420p:yuv444p:yuv410p
+noformat=yuv420p|yuv444p|yuv410p
 @end example
 
 @section null
@@ -1344,12 +1553,18 @@ Apply video transform using libopencv.
 To enable this filter install libopencv library and headers and
 configure Libav with --enable-libopencv.
 
-The filter takes the parameters: @var{filter_name}@{:=@}@var{filter_params}.
+This filter accepts the following parameters:
+
+ at table @option
+
+ at item filter_name
+The name of the libopencv filter to apply.
 
- at var{filter_name} is the name of the libopencv filter to apply.
+ at item filter_params
+The parameters to pass to the libopencv filter. If not specified the default
+values are assumed.
 
- at var{filter_params} specifies the parameters to pass to the libopencv
-filter. If not specified the default values are assumed.
+ at end table
 
 Refer to the official libopencv documentation for more precise
 information:
@@ -1363,7 +1578,7 @@ Follows the list of supported libopencv filters.
 Dilate an image by using a specific structuring element.
 This filter corresponds to the libopencv function @code{cvDilate}.
 
-It accepts the parameters: @var{struct_el}:@var{nb_iterations}.
+It accepts the parameters: @var{struct_el}|@var{nb_iterations}.
 
 @var{struct_el} represents a structuring element, and has the syntax:
 @var{cols}x at var{rows}+ at var{anchor_x}x at var{anchor_y}/@var{shape}
@@ -1391,7 +1606,7 @@ Follow some example:
 ocv=dilate
 
 # dilate using a structuring element with a 5x5 cross, iterate two times
-ocv=dilate=5x5+2x2/cross:2
+ocv=filter_name=dilate:filter_params=5x5+2x2/cross|2
 
 # read the shape from the file diamond.shape, iterate two times
 # the file diamond.shape may contain a pattern of characters like this:
@@ -1401,7 +1616,7 @@ ocv=dilate=5x5+2x2/cross:2
 #  ***
 #   *
 # the specified cols and rows are ignored (but not the anchor point coordinates)
-ocv=0x0+2x2/custom=diamond.shape:2
+ocv=dilate:0x0+2x2/custom=diamond.shape|2
 @end example
 
 @subsection erode
@@ -1417,7 +1632,7 @@ with the same syntax and semantics as the @ref{dilate} filter.
 Smooth the input video.
 
 The filter takes the following parameters:
- at var{type}:@var{param1}:@var{param2}:@var{param3}:@var{param4}.
+ at var{type}|@var{param1}|@var{param2}|@var{param3}|@var{param4}.
 
 @var{type} is the type of smooth filter to apply, and can be one of
 the following values: "blur", "blur_no_scale", "median", "gaussian",
@@ -1442,11 +1657,19 @@ Overlay one video on top of another.
 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}.
+This filter accepts the following parameters:
+
+ at table @option
+
+ at item x
+The horizontal position of the left edge of the overlaid video on the main video.
+
+ at item y
+The vertical position of the top edge of the overlaid video on the main video.
+
+ at end table
 
- at var{x} is the x coordinate of the overlayed video on the main video,
- at var{y} is the y coordinate. The parameters are expressions containing
-the following parameters:
+The parameters are expressions containing the following parameters:
 
 @table @option
 @item main_w, main_h
@@ -1472,15 +1695,15 @@ Follow some examples:
 @example
 # draw the overlay at 10 pixels from the bottom right
 # corner of the main video.
-overlay=main_w-overlay_w-10:main_h-overlay_h-10
+overlay=x=main_w-overlay_w-10:y=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
+avconv -i input -i logo -filter_complex 'overlay=x=10:y=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
-'overlay=10:H-h-10,overlay=W-w-10:H-h-10' output
+'overlay=x=10:y=H-h-10,overlay=x=W-w-10:y=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
@@ -1495,8 +1718,38 @@ approach is yet to be tested.
 Add paddings to the input image, and places the original input at the
 given coordinates @var{x}, @var{y}.
 
-It accepts the following parameters:
- at var{width}:@var{height}:@var{x}:@var{y}:@var{color}.
+This filter accepts the following parameters:
+
+ at table @option
+ at item width, height
+
+Specify the size of the output image with the paddings added. If the
+value for @var{width} or @var{height} is 0, the corresponding input size
+is used for the output.
+
+The @var{width} expression can reference the value set by the
+ at var{height} expression, and vice versa.
+
+The default value of @var{width} and @var{height} is 0.
+
+ at item x, y
+
+Specify the offsets where to place the input image in the padded area
+with respect to the top/left border of the output image.
+
+The @var{x} expression can reference the value set by the @var{y}
+expression, and vice versa.
+
+The default value of @var{x} and @var{y} is 0.
+
+ at item color
+
+Specify the color of the padded area, it can be the name of a color
+(case insensitive match) or a 0xRRGGBB[AA] sequence.
+
+The default value of @var{color} is "black".
+
+ at end table
 
 The parameters @var{width}, @var{height}, @var{x}, and @var{y} are
 expressions containing the following constants:
@@ -1531,46 +1784,13 @@ horizontal and vertical chroma subsample values. For example for the
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
 @end table
 
-Follows the description of the accepted parameters.
-
- at table @option
- at item width, height
-
-Specify the size of the output image with the paddings added. If the
-value for @var{width} or @var{height} is 0, the corresponding input size
-is used for the output.
-
-The @var{width} expression can reference the value set by the
- at var{height} expression, and vice versa.
-
-The default value of @var{width} and @var{height} is 0.
-
- at item x, y
-
-Specify the offsets where to place the input image in the padded area
-with respect to the top/left border of the output image.
-
-The @var{x} expression can reference the value set by the @var{y}
-expression, and vice versa.
-
-The default value of @var{x} and @var{y} is 0.
-
- at item color
-
-Specify the color of the padded area, it can be the name of a color
-(case insensitive match) or a 0xRRGGBB[AA] sequence.
-
-The default value of @var{color} is "black".
-
- at end table
-
 Some examples follow:
 
 @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
+pad=width=640:height=480:x=0:y=40:color=violet
 
 # 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
@@ -1601,11 +1821,24 @@ format=monow, pixdesctest
 
 can be used to test the monowhite pixel format descriptor definition.
 
+ at anchor{scale}
 @section scale
 
-Scale the input video to @var{width}:@var{height} and/or convert the image format.
+Scale the input video and/or convert the image format.
+
+This filter accepts the following options:
+
+ at table @option
+
+ at item w
+Output video width.
+
+ at item h
+Output video height.
 
-The parameters @var{width} and @var{height} are expressions containing
+ at end table
+
+The parameters @var{w} and @var{h} are expressions containing
 the following constants:
 
 @table @option
@@ -1625,12 +1858,15 @@ the output (cropped) width and height
 @item ow, oh
 same as @var{out_w} and @var{out_h}
 
- at item dar, a
-input display aspect ratio, same as @var{iw} / @var{ih}
+ at item a
+same as @var{iw} / @var{ih}
 
 @item sar
 input sample aspect ratio
 
+ at 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.
@@ -1640,27 +1876,27 @@ If the input image format is different from the format requested by
 the next filter, the scale filter will convert the input to the
 requested format.
 
-If the value for @var{width} or @var{height} is 0, the respective input
+If the value for @var{w} or @var{h} is 0, the respective input
 size is used for the output.
 
-If the value for @var{width} or @var{height} is -1, the scale filter will
-use, for the respective output size, a value that maintains the aspect
-ratio of the input image.
+If the value for @var{w} or @var{h} is -1, the scale filter will use, for the
+respective output size, a value that maintains the aspect ratio of the input
+image.
 
-The default value of @var{width} and @var{height} is 0.
+The default value of @var{w} and @var{h} is 0.
 
 Some examples follow:
 @example
 # scale the input video to a size of 200x100.
-scale=200:100
+scale=w=200:h=100
 
 # scale the input to 2x
-scale=2*iw:2*ih
+scale=w=2*iw:h=2*ih
 # the above is the same as
 scale=2*in_w:2*in_h
 
 # scale the input to half size
-scale=iw/2:ih/2
+scale=w=iw/2:h=ih/2
 
 # increase the width, and set the height to the same size
 scale=3/2*iw:ow
@@ -1670,21 +1906,28 @@ scale=iw:1/PHI*iw
 scale=ih*PHI:ih
 
 # increase the height, and set the width to 3/2 of the height
-scale=3/2*oh:3/5*ih
+scale=w=3/2*oh:h=3/5*ih
 
 # increase the size, but make the size a multiple of the chroma
 scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub"
 
 # increase the width to a maximum of 500 pixels, keep the same input aspect ratio
-scale='min(500\, iw*3/2):-1'
+scale=w='min(500\, iw*3/2):h=-1'
 @end example
 
 @section select
 Select frames to pass in output.
 
-It accepts in input an expression, which is evaluated for each input
-frame. If the expression is evaluated to a non-zero value, the frame
-is selected and passed to the output, otherwise it is discarded.
+This filter accepts the following options:
+
+ at table @option
+
+ at item expr
+An expression, which is evaluated for each input frame. If the expression is
+evaluated to a non-zero value, the frame is selected and passed to the output,
+otherwise it is discarded.
+
+ at end table
 
 The expression can contain the following constants:
 
@@ -1760,9 +2003,6 @@ the frame is bottom-field-first
 @item key
 1 if the filtered frame is a key-frame, 0 otherwise
 
- at item pos
-the position in the file of the filtered frame, -1 if the information
-is not available (e.g. for synthetic video)
 @end table
 
 The default value of the select expression is "1".
@@ -1774,13 +2014,13 @@ Some examples follow:
 select
 
 # the above is the same as:
-select=1
+select=expr=1
 
 # skip all frames:
-select=0
+select=expr=0
 
 # select only I-frames
-select='eq(pict_type\,I)'
+select='expr=eq(pict_type\,I)'
 
 # select one frame every 100
 select='not(mod(n\,100))'
@@ -1809,18 +2049,45 @@ 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".
+This filter accepts the following options:
+
+ at table @option
+
+ at item dar
+Output display aspect ratio.
+
+ at end table
+
+The parameter @var{dar} is an expression containing
+the following constants:
+
+ at table @option
+ at item E, PI, PHI
+the corresponding mathematical approximated values for e
+(euler number), pi (greek PI), phi (golden ratio)
+
+ at item w, h
+the input width and height
+
+ at item a
+same as @var{w} / @var{h}
+
+ at item sar
+input sample aspect ratio
+
+ at item dar
+input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}
+
+ at 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.
+ at end table
 
 For example to change the display aspect ratio to 16:9, specify:
 @example
-setdar=16:9
+setdar=dar=16/9
 # the above is equivalent to
-setdar=1.77777
+setdar=dar=1.77777
 @end example
 
 See also the @ref{setsar} filter documentation.
@@ -1829,8 +2096,17 @@ See also the @ref{setsar} filter documentation.
 
 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:
+This filter accepts the following options:
+
+ at table @option
+
+ at item expr
+The expression which is evaluated for each frame to construct its timestamp.
+
+ at end table
+
+The expression is evaluated through the eval API and can contain the following
+constants:
 
 @table @option
 @item PTS
@@ -1854,26 +2130,31 @@ the PTS of the first video frame
 @item INTERLACED
 tell if the current frame is interlaced
 
- at 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
 
+ at item RTCTIME
+wallclock (RTC) time in microseconds
+
+ at item RTCSTART
+wallclock (RTC) time at the start of the movie in microseconds
+
+ at item TB
+timebase of the input timestamps
+
 @end table
 
 Some examples follow:
 
 @example
 # start counting PTS from zero
-setpts=PTS-STARTPTS
+setpts=expr=PTS-STARTPTS
 
 # fast motion
-setpts=0.5*PTS
+setpts=expr=0.5*PTS
 
 # slow motion
 setpts=2.0*PTS
@@ -1883,6 +2164,9 @@ setpts=N/(25*TB)
 
 # fixed rate 25 fps with some jitter
 setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'
+
+# generate timestamps from a "live source" and rebase onto the current timebase
+setpts='(RTCTIME - RTCSTART) / (TB * 1000000)"
 @end example
 
 @anchor{setsar}
@@ -1899,16 +2183,43 @@ 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".
+This filter accepts the following options:
+
+ at table @option
+
+ at item sar
+Output sample aspect ratio.
+
+ at end table
+
+The parameter @var{sar} is an expression containing
+the following constants:
+
+ at table @option
+ at item E, PI, PHI
+the corresponding mathematical approximated values for e
+(euler number), pi (greek PI), phi (golden ratio)
+
+ at item w, h
+the input width and height
+
+ at item a
+same as @var{w} / @var{h}
+
+ at item sar
+input sample aspect ratio
+
+ at item dar
+input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}
+
+ at 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.
+ at end table
 
 For example to change the sample aspect ratio to 10:11, specify:
 @example
-setsar=10:11
+setsar=sar=10/11
 @end example
 
 @section settb
@@ -1916,7 +2227,15 @@ setsar=10:11
 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.
+This filter accepts the following options:
+
+ at table @option
+
+ at item expr
+The expression which is evaluated into the output timebase.
+
+ at end table
+
 The expression can contain the constants "PI", "E", "PHI", "AVTB" (the
 default timebase), and "intb" (the input timebase).
 
@@ -1926,10 +2245,10 @@ Follow some examples.
 
 @example
 # set the timebase to 1/25
-settb=1/25
+settb=expr=1/25
 
 # set the timebase to 1/10
-settb=0.1
+settb=expr=0.1
 
 #set the timebase to 1001/1000
 settb=1+0.001
@@ -2017,11 +2336,19 @@ will create 5 copies of the input video.
 
 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 options:
+
+ at table @option
+
+ at item dir
+The direction of the transpose.
+
+ at end table
+
+The direction can assume the following values:
 
 @table @samp
- at item 0
+ at item cclock_flip
 Rotate by 90 degrees counterclockwise and vertically flip (default), that is:
 @example
 L.R     L.l
@@ -2029,7 +2356,7 @@ L.R     L.l
 l.r     R.r
 @end example
 
- at item 1
+ at item clock
 Rotate by 90 degrees clockwise, that is:
 @example
 L.R     l.L
@@ -2037,7 +2364,7 @@ L.R     l.L
 l.r     r.R
 @end example
 
- at item 2
+ at item cclock
 Rotate by 90 degrees counterclockwise, that is:
 @example
 L.R     R.r
@@ -2045,7 +2372,7 @@ L.R     R.r
 l.r     L.l
 @end example
 
- at item 3
+ at item clock_flip
 Rotate by 90 degrees clockwise and vertically flip, that is:
 @example
 L.R     r.R
@@ -2054,16 +2381,72 @@ l.r     l.L
 @end example
 @end table
 
+ at section trim
+Trim the input so that the output contains one continuous subpart of the input.
+
+This filter accepts the following options:
+ at table @option
+ at item start
+Timestamp (in seconds) of the start of the kept section. I.e. the frame with the
+timestamp @var{start} will be the first frame in the output.
+
+ at item end
+Timestamp (in seconds) of the first frame that will be dropped. I.e. the frame
+immediately preceding the one with the timestamp @var{end} will be the last
+frame in the output.
+
+ at item start_pts
+Same as @var{start}, except this option sets the start timestamp in timebase
+units instead of seconds.
+
+ at item end_pts
+Same as @var{end}, except this option sets the end timestamp in timebase units
+instead of seconds.
+
+ at item duration
+Maximum duration of the output in seconds.
+
+ at item start_frame
+Number of the first frame that should be passed to output.
+
+ at item end_frame
+Number of the first frame that should be dropped.
+ at end table
+
+Note that the first two sets of the start/end options and the @option{duration}
+option look at the frame timestamp, while the _frame variants simply count the
+frames that pass through the filter. Also note that this filter does not modify
+the timestamps. If you wish that the output timestamps start at zero, insert a
+setpts filter after the trim filter.
+
+If multiple start or end options are set, this filter tries to be greedy and
+keep all the frames that match at least one of the specified constraints. To keep
+only the part that matches all the constraints at once, chain multiple trim
+filters.
+
+The defaults are such that all the input is kept. So it is possible to set e.g.
+just the end values to keep everything before the specified time.
+
+Examples:
+ at itemize
+ at item
+drop everything except the second minute of input
+ at example
+avconv -i INPUT -vf trim=60:120
+ at end example
+
+ at item
+keep only the first second
+ at example
+avconv -i INPUT -vf trim=duration=1
+ at end example
+
+ at end itemize
 @section unsharp
 
 Sharpen or blur the input video.
 
 It accepts the following parameters:
- at var{luma_msize_x}:@var{luma_msize_y}:@var{luma_amount}:@var{chroma_msize_x}:@var{chroma_msize_y}:@var{chroma_amount}
-
-Negative values for the amount will blur the input video, while positive
-values will sharpen. All parameters are optional and default to the
-equivalent of the string '5:5:1.0:5:5:0.0'.
 
 @table @option
 
@@ -2087,15 +2470,19 @@ and 13, default value is 5.
 Set the chroma matrix vertical size. It can be an integer between 3
 and 13, default value is 5.
 
- at item luma_amount
+ at 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.
 
 @end table
 
+Negative values for the amount will blur the input video, while positive
+values will sharpen. All parameters are optional and default to the
+equivalent of the string '5:5:1.0:5:5:0.0'.
+
 @example
 # Strong luma sharpen effect parameters
-unsharp=7:7:2.5
+unsharp=luma_msize_x=7:luma_msize_y=7:luma_amount=2.5
 
 # Strong blur of both luma and chroma parameters
 unsharp=7:7:-2:7:7:-2
@@ -2117,10 +2504,12 @@ Flip the input video vertically.
 Deinterlace the input video ("yadif" means "yet another deinterlacing
 filter").
 
-It accepts the optional parameters: @var{mode}:@var{parity}:@var{auto}.
+This filter accepts the following options:
 
- at var{mode} specifies the interlacing mode to adopt, accepts one of the
-following values:
+ at table @option
+
+ at item mode
+The interlacing mode to adopt, accepts one of the following values:
 
 @table @option
 @item 0
@@ -2135,8 +2524,9 @@ like 1 but skips spatial interlacing check
 
 Default value is 0.
 
- at var{parity} specifies the picture field parity assumed for the input
-interlaced video, accepts one of the following values:
+ at item parity
+The picture field parity assumed for the input interlaced video, accepts one of
+the following values:
 
 @table @option
 @item 0
@@ -2151,8 +2541,9 @@ Default value is -1.
 If interlacing is unknown or decoder does not export this information,
 top field first will be assumed.
 
- at var{auto} specifies if deinterlacer should trust the interlaced flag
-and only deinterlace frames marked as interlaced
+ at item auto
+Whether deinterlacer should trust the interlaced flag and only deinterlace
+frames marked as interlaced
 
 @table @option
 @item 0
@@ -2163,6 +2554,8 @@ only deinterlace frames marked as interlaced
 
 Default value is 0.
 
+ at end table
+
 @c man end VIDEO FILTERS
 
 @chapter Video Sources
@@ -2177,55 +2570,41 @@ Buffer video 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/vsrc_buffer.h}.
 
-It accepts the following parameters:
- at var{width}:@var{height}:@var{pix_fmt_string}:@var{timebase_num}:@var{timebase_den}:@var{sample_aspect_ratio_num}:@var{sample_aspect_ratio.den}
+This filter accepts the following parameters:
 
-All the parameters need to be explicitly defined.
+ at table @option
 
-Follows the list of the accepted parameters.
+ at item width
+Input video width.
 
- at table @option
+ at item height
+Input video height.
 
- at item width, height
-Specify the width and height of the buffered video frames.
+ at item pix_fmt
+Name of the input video pixel format.
 
- at item pix_fmt_string
-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.
+ at item time_base
+The time base used for input timestamps.
 
- at item timebase_num, timebase_den
-Specify numerator and denomitor of the timebase assumed by the
-timestamps of the buffered frames.
+ at item sar
+Sample (pixel) aspect ratio of the input video.
 
- at item sample_aspect_ratio.num, sample_aspect_ratio.den
-Specify numerator and denominator of the sample aspect ratio assumed
-by the video frames.
 @end table
 
 For example:
 @example
-buffer=320:240:yuv410p:1:24:1:1
+buffer=width=320:height=240:pix_fmt=yuv410p:time_base=1/24:sar=1
 @end example
 
 will instruct the source to accept video frames with size 320x240 and
 with format "yuv410p", assuming 1/24 as the timestamps timebase and
 square pixels (1:1 sample aspect ratio).
-Since the pixel format with name "yuv410p" corresponds to the number 6
-(check the enum AVPixelFormat definition in @file{libavutil/pixfmt.h}),
-this example corresponds to:
- at example
-buffer=320:240:6:1:24
- at end example
 
 @section color
 
 Provide an uniformly colored input.
 
 It accepts the following parameters:
- at var{color}:@var{frame_size}:@var{frame_rate}
-
-Follows the description of the accepted parameters.
 
 @table @option
 
@@ -2234,12 +2613,12 @@ 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".
 
- at item frame_size
+ at item size
 Specify the size of the sourced video, it may be a string of the form
 @var{width}x at var{height}, or the name of a size abbreviation. The
 default value is "320x240".
 
- at item frame_rate
+ at item framerate
 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
@@ -2266,16 +2645,14 @@ 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.
 
-It accepts the syntax: @var{movie_name}[:@var{options}] where
- at var{movie_name} is the name of the resource to read (not necessarily
-a file but also a device or a stream accessed through some protocol),
-and @var{options} is an optional sequence of @var{key}=@var{value}
-pairs, separated by ":".
-
-The description of the accepted options follows.
+This filter accepts the following options:
 
 @table @option
 
+ at item filename
+The name of the resource to read (not necessarily a file but also a device or a
+stream accessed through some protocol).
+
 @item format_name, f
 Specifies the format assumed for the movie to read, and can be either
 the name of a container or an input device. If not specified the
@@ -2340,24 +2717,33 @@ 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:
- at example
- at var{size}:@var{rate}:@var{src_name}[@{=|:@}@var{param1}:@var{param2}:...:@var{paramN}]
- at end example
+This source accepts the following options:
+
+ at table @option
+
+ at item size
+The size of the video to generate, may be a string of the form
+ at var{width}x at var{height} or a frame size abbreviation.
+
+ at item framerate
+Framerate of the generated video, may be a string of the form
+ at var{num}/@var{den} or a frame rate abbreviation.
 
- at var{size} is the size of the video to generate, may be a string of the
-form @var{width}x at var{height} or a frame size abbreviation.
- at 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.
- at 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.
+ at item filter_name
+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.
+
+ at item filter_params
+A '|'-separated list of parameters to pass to the frei0r source.
+
+ at end table
 
 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
+frei0r_src=size=200x200:framerate=10:filter_name=partik0l:filter_params=1234 [overlay]; [in][overlay] overlay
 @end example
 
 @section rgbtestsrc, testsrc
@@ -2370,8 +2756,7 @@ 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.
+The sources accept the following options:
 
 @table @option
 
diff --git a/doc/general.texi b/doc/general.texi
index d973902..e34fabd 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -79,6 +79,14 @@ Go to @url{http://www.webmproject.org/} and follow the instructions for
 installing the library. Then pass @code{--enable-libvpx} to configure to
 enable it.
 
+ at section libwavpack
+
+Libav can make use of the libwavpack library for WavPack encoding.
+
+Go to @url{http://www.wavpack.com/} and follow the instructions for
+installing the library. Then pass @code{--enable-libwavpack} to configure to
+enable it.
+
 @section x264
 
 Libav can make use of the x264 library for H.264 encoding.
@@ -128,7 +136,7 @@ library:
 @item Apple HTTP Live Streaming @tab   @tab X
 @item ASF                       @tab X @tab X
 @item AVI                       @tab X @tab X
- at item AVISynth                  @tab   @tab X
+ at item AviSynth                  @tab   @tab X
 @item AVS                       @tab   @tab X
     @tab Multimedia format used by the Creature Shock game.
 @item Beam Software SIFF        @tab   @tab X
@@ -186,6 +194,8 @@ library:
 @item GXF                       @tab X @tab X
     @tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley
          playout servers.
+ at item HNM @tab   @tab X
+    @tab Only version 4 supported, used in some games from Cryo Interactive
 @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.
@@ -262,6 +272,7 @@ library:
 @item raw H.261                 @tab X @tab X
 @item raw H.263                 @tab X @tab X
 @item raw H.264                 @tab X @tab X
+ at item raw HEVC                  @tab   @tab X
 @item raw Ingenient MJPEG       @tab   @tab X
 @item raw MJPEG                 @tab X @tab X
 @item raw MLP                   @tab   @tab X
@@ -373,8 +384,8 @@ following image formats are supported:
     @tab Digital Picture Exchange
 @item JPEG         @tab X @tab X
     @tab Progressive JPEG is not supported.
- at item JPEG 2000    @tab E @tab E
-    @tab decoding supported through external library libopenjpeg
+ at item JPEG 2000    @tab E @tab X
+    @tab encoding supported through external library libopenjpeg
 @item JPEG-LS      @tab X @tab X
 @item LJPEG        @tab X @tab
     @tab Lossless JPEG
@@ -404,6 +415,8 @@ following image formats are supported:
     @tab YUV, JPEG and some extension is not supported yet.
 @item Truevision Targa  @tab X @tab X
     @tab Targa (.TGA) image format
+ at item WebP         @tab @tab X
+    @tab WebP image format
 @item XBM  @tab X @tab
     @tab X BitMap image format
 @item XWD  @tab X @tab X
@@ -430,6 +443,7 @@ following image formats are supported:
 @item AMV Video              @tab     @tab  X
     @tab Used in Chinese MP3 players.
 @item ANSI/ASCII art         @tab     @tab  X
+ at item Apple Intermediate Codec @tab     @tab  X
 @item Apple MJPEG-B          @tab     @tab  X
 @item Apple ProRes           @tab  X  @tab  X
 @item Apple QuickDraw        @tab     @tab  X
@@ -496,6 +510,7 @@ following image formats are supported:
 @item Electronic Arts TGQ video  @tab     @tab  X
 @item Electronic Arts TQI video  @tab     @tab  X
 @item Escape 124             @tab     @tab  X
+ at item Escape 130             @tab     @tab  X
 @item FFmpeg video codec #1  @tab  X  @tab  X
     @tab experimental lossless codec (fourcc: FFV1)
 @item Flash Screen Video v1  @tab  X  @tab  X
@@ -505,12 +520,15 @@ following image formats are supported:
     @tab Sorenson H.263 used in Flash
 @item Forward Uncompressed   @tab     @tab  X
 @item Fraps                  @tab     @tab  X
+ at item Go2Webinar             @tab     @tab  X
+    @tab fourcc: G2M4
 @item H.261                  @tab  X  @tab  X
 @item H.263 / H.263-1996     @tab  X  @tab  X
 @item H.263+ / H.263-1998 / H.263 version 2  @tab  X  @tab  X
 @item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10  @tab  E  @tab  X
     @tab encoding supported through external library libx264
- at item H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)  @tab  E  @tab  X
+ at item HEVC                   @tab     @tab  X
+ at item HNM version 4          @tab     @tab  X
 @item HuffYUV                @tab  X  @tab  X
 @item HuffYUV FFmpeg variant @tab  X  @tab  X
 @item IBM Ultimotion         @tab     @tab  X
@@ -559,8 +577,6 @@ following image formats are supported:
 @item Mobotix MxPEG video    @tab     @tab  X
 @item Motion Pixels video    @tab     @tab  X
 @item MPEG-1 video           @tab  X  @tab  X
- at item MPEG-1/2 video XvMC (X-Video Motion Compensation)  @tab     @tab  X
- at item MPEG-1/2 video (VDPAU acceleration)  @tab     @tab  X
 @item MPEG-2 video           @tab  X  @tab  X
 @item MPEG-4 part 2          @tab  X  @tab  X
     @tab libxvidcore can be used alternatively for encoding.
@@ -578,6 +594,8 @@ following image formats are supported:
     @tab fourcc: VP60,VP61,VP62
 @item VP8                    @tab  E  @tab  X
     @tab fourcc: VP80, encoding supported through external library libvpx
+ at item VP9                    @tab  E  @tab  X
+    @tab Encoding supported through external library libvpx
 @item planar RGB             @tab     @tab  X
     @tab fourcc: 8BPS
 @item Q-team QPEG            @tab     @tab  X
@@ -606,8 +624,6 @@ following image formats are supported:
 @item Smacker video          @tab     @tab  X
     @tab Video encoding used in Smacker.
 @item SMPTE VC-1             @tab     @tab  X
- at item Snow                   @tab  X  @tab  X
-    @tab experimental wavelet codec (fourcc: SNOW)
 @item Sony PlayStation MDEC (Motion DECoder)  @tab     @tab  X
 @item Sorenson Vector Quantizer 1  @tab  X  @tab  X
     @tab fourcc: SVQ1
@@ -711,8 +727,8 @@ following image formats are supported:
     @tab encoding supported through external library libvo-amrwbenc
 @item Apple lossless audio   @tab  X  @tab  X
     @tab QuickTime fourcc 'alac'
- at item Atrac 1                @tab     @tab  X
- at item Atrac 3                @tab     @tab  X
+ at item ATRAC1                 @tab     @tab  X
+ at item ATRAC3                 @tab     @tab  X
 @item Bink Audio             @tab     @tab  X
     @tab Used in Bink and Smacker files in many games.
 @item Delphine Software International CIN audio  @tab     @tab  X
@@ -761,7 +777,9 @@ following image formats are supported:
     @tab supported through external library libopus
 @item PCM A-law              @tab  X  @tab  X
 @item PCM mu-law             @tab  X  @tab  X
- at item PCM 16-bit little-endian planar  @tab     @tab  X
+ at item PCM signed 16-bit little-endian planar  @tab     @tab  X
+ at item PCM signed 24-bit little-endian planar  @tab     @tab  X
+ at item PCM signed 32-bit little-endian planar  @tab     @tab  X
 @item PCM 32-bit floating point big-endian  @tab  X  @tab  X
 @item PCM 32-bit floating point little-endian  @tab  X  @tab  X
 @item PCM 64-bit floating point big-endian  @tab  X  @tab  X
@@ -808,7 +826,9 @@ following image formats are supported:
 @item TwinVQ (VQF flavor)    @tab     @tab  X
 @item Vorbis                 @tab  E  @tab  X
     @tab A native but very primitive encoder exists.
- at item WavPack                @tab     @tab  X
+ at item Voxware MetaSound      @tab     @tab  X
+ at item WavPack                @tab  E  @tab  X
+    @tab supported through external library libwavpack
 @item Westwood Audio (SND1)  @tab     @tab  X
 @item Windows Media Audio 1  @tab  X  @tab  X
 @item Windows Media Audio 2  @tab  X  @tab  X
diff --git a/doc/multithreading.txt b/doc/multithreading.txt
index b72bc16..9b27b10 100644
--- a/doc/multithreading.txt
+++ b/doc/multithreading.txt
@@ -57,6 +57,11 @@ which re-allocates them for other threads.
 Add CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little
 speed gain at this point but it should work.
 
+If there are inter-frame dependencies, so the codec calls
+ff_thread_report/await_progress(), set AVCodecInternal.allocate_progress. The
+frames must then be freed with ff_thread_release_buffer().
+Otherwise leave it at zero and decode directly into the user-supplied frames.
+
 Call ff_thread_report_progress() after some part of the current picture has decoded.
 A good place to put this is where draw_horiz_band() is called - add this if it isn't
 called anywhere, as it's useful too and the implementation is trivial when you're
diff --git a/doc/muxers.texi b/doc/muxers.texi
index d183eaf..6e06e46 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -171,6 +171,12 @@ avconv -i in.avi -f image2 -frames:v 1 img.jpeg
 @table @option
 @item -start_number @var{number}
 Start the sequence from @var{number}.
+
+ at item -update @var{number}
+If @var{number} is nonzero, the filename will always be interpreted as just a
+filename, not a pattern, and this file will be continuously overwritten with new
+images.
+
 @end table
 
 @section MOV/MP4/ISMV
@@ -233,6 +239,10 @@ more efficient), but with this option set, the muxer writes one moof/mdat
 pair for each track, making it easier to separate tracks.
 
 This option is implicitly set when writing ismv (Smooth Streaming) files.
+ at item -movflags faststart
+Run a second pass moving the index (moov atom) to the beginning of the file.
+This operation can take a while, and will not work in various situations such
+as fragmented output, thus it is not enabled by default.
 @end table
 
 Smooth Streaming content can be pushed in real time to a publishing
@@ -367,6 +377,27 @@ For example a 3D WebM clip can be created using the following command line:
 avconv -i sample_left_right_clip.mpg -an -c:v libvpx -metadata STEREO_MODE=left_right -y stereo_clip.webm
 @end example
 
+This muxer supports the following options:
+
+ at table @option
+
+ at item reserve_index_space
+By default, this muxer writes the index for seeking (called cues in Matroska
+terms) at the end of the file, because it cannot know in advance how much space
+to leave for the index at the beginning of the file. However for some use cases
+-- e.g.  streaming where seeking is possible but slow -- it is useful to put the
+index at the beginning of the file.
+
+If this option is set to a non-zero value, the muxer will reserve a given amount
+of space in the file header and then try to write the cues there when the muxing
+finishes. If the available space does not suffice, muxing will fail. A safe size
+for most use cases should be about 50kB per hour of video.
+
+Note that cues are only written if the output is seekable and this option will
+have no effect if it is not.
+
+ at end table
+
 @section segment
 
 Basic stream segmenter.
@@ -434,4 +465,19 @@ avconv -i input.mp3 -i cover.png -c copy -metadata:s:v title="Album cover"
 -metadata:s:v comment="Cover (Front)" out.mp3
 @end example
 
+ at section ogg
+
+Ogg container muxer.
+
+ at table @option
+ at item -page_duration @var{duration}
+Preferred page duration, in microseconds. The muxer will attempt to create
+pages that are approximately @var{duration} microseconds long. This allows the
+user to compromise between seek granularity and container overhead. The default
+is 1 second. A value of 0 will fill all segments, making pages as large as
+possible. A value of 1 will effectively use 1 packet-per-page in most
+situations, giving a small seek granularity at the cost of additional container
+overhead.
+ at end table
+
 @c man end MUXERS
diff --git a/doc/nut.texi b/doc/nut.texi
index 9b84241..39a22ff 100644
--- a/doc/nut.texi
+++ b/doc/nut.texi
@@ -109,7 +109,6 @@ PFD[32]   would for example be signed 32 bit little-endian IEEE float
 @item RV20 @tab RealVideo 2.0
 @item RV30 @tab RealVideo 3.0
 @item RV40 @tab RealVideo 4.0
- at item SNOW @tab FFmpeg Snow
 @item SVQ1 @tab Sorenson Video 1
 @item SVQ3 @tab Sorenson Video 3
 @item theo @tab Xiph Theora
diff --git a/doc/optimization.txt b/doc/optimization.txt
index c3e640c..2b8c51b 100644
--- a/doc/optimization.txt
+++ b/doc/optimization.txt
@@ -148,7 +148,7 @@ Alignment:
 Some instructions on some architectures have strict alignment restrictions,
 for example most SSE/SSE2 instructions on x86.
 The minimum guaranteed alignment is written in the .h files, for example:
-    void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
+    void (*put_pixels_clamped)(const int16_t *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size);
 
 
 General Tips:
diff --git a/doc/platform.texi b/doc/platform.texi
index da08962..a9cacfe 100644
--- a/doc/platform.texi
+++ b/doc/platform.texi
@@ -101,44 +101,53 @@ you can build all libraries as DLLs.
 
 @end itemize
 
- at section Microsoft Visual C++
+ at section Microsoft Visual C++ or Intel C++ Compiler for Windows
 
-Libav can be built with MSVC using a C99-to-C89 conversion utility and
-wrapper.
+Libav can be built with MSVC 2012 or earlier using a C99-to-C89 conversion utility
+and wrapper, or with MSVC 2013 and ICL natively.
 
 You will need the following prerequisites:
 
 @itemize
 @item @uref{https://github.com/libav/c99-to-c89/, C99-to-C89 Converter & Wrapper}
+(if using MSVC 2012 or earlier)
 @item @uref{http://code.google.com/p/msinttypes/, msinttypes}
+(if using MSVC 2012 or earlier)
 @item @uref{http://www.mingw.org/, MSYS}
 @item @uref{http://yasm.tortall.net/, YASM}
 @item @uref{http://gnuwin32.sourceforge.net/packages/bc.htm, bc for Windows} if
 you want to run @uref{fate.html, FATE}.
 @end itemize
 
-To set up a proper MSVC environment in MSYS, you simply need to run
- at code{msys.bat} from the Visual Studio command prompt.
+To set up a proper environment in MSYS, you need to run @code{msys.bat} from
+the Visual Studio or Intel Compiler command prompt.
 
-Place @code{makedef}, @code{c99wrap.exe}, @code{c99conv.exe}, and @code{yasm.exe}
-somewhere in your @code{PATH}.
+Place @code{yasm.exe} somewhere in your @code{PATH}. If using MSVC 2012 or
+earlier, place @code{c99wrap.exe} and @code{c99conv.exe} somewhere in your
+ at code{PATH} as well.
 
-Next, make sure @code{inttypes.h} and any other headers and libs you want to use
-are located in a spot that MSVC can see. Do so by modifying the @code{LIB} and
- at code{INCLUDE} environment variables to include the @strong{Windows} paths to
-these directories. Alternatively, you can try and use the
- at code{--extra-cflags}/@code{--extra-ldflags} configure options.
+Next, make sure any other headers and libs you want to use, such as zlib, are
+located in a spot that the compiler can see. Do so by modifying the @code{LIB}
+and @code{INCLUDE} environment variables to include the @strong{Windows-style}
+paths to these directories. Alternatively, you can try and use the
+ at code{--extra-cflags}/@code{--extra-ldflags} configure options. If using MSVC
+2012 or earlier, place @code{inttypes.h} somewhere the compiler can see too.
 
 Finally, run:
 
 @example
+For MSVC:
 ./configure --toolchain=msvc
+
+For ICL:
+./configure --toolchain=icl
+
 make
 make install
 @end example
 
 If you wish to compile shared libraries, add @code{--enable-shared} to your
-configure options. Note that due to the way MSVC handles DLL imports and
+configure options. Note that due to the way MSVC and ICL handle DLL imports and
 exports, you cannot compile static and shared libraries at the same time, and
 enabling shared libraries will automatically disable the static ones.
 
@@ -168,7 +177,14 @@ erroneously included when building Libav.
 can see.
 @end enumerate
 
- at item Libav has been tested with Visual Studio 2010 and 2012, Pro and Express.
+ at item Libav has been tested with the following on i686 and x86_64:
+ at itemize
+ at item Visual Studio 2010 Pro and Express
+ at item Visual Studio 2012 Pro and Express
+ at item Visual Studio 2013 Pro and Express
+ at item Intel Composer XE 2013
+ at item Intel Composer XE 2013 SP1
+ at end itemize
 Anything else is not officially supported.
 
 @end itemize
@@ -179,16 +195,7 @@ 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
-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
-libavutil/pixdesc.h you should have:
- at example
-extern __declspec(dllimport) const AVPixFmtDescriptor av_pix_fmt_descriptors[];
- at end example
-
-You will also need to define @code{inline} to something MSVC understands:
+You will need to define @code{inline} to something MSVC understands:
 @example
 #define inline __inline
 @end example
diff --git a/doc/print_options.c b/doc/print_options.c
index 4283e6a..aa75a00 100644
--- a/doc/print_options.c
+++ b/doc/print_options.c
@@ -27,7 +27,9 @@
 #include <float.h>
 
 #include "libavformat/avformat.h"
+#include "libavformat/options_table.h"
 #include "libavcodec/avcodec.h"
+#include "libavcodec/options_table.h"
 #include "libavutil/opt.h"
 
 static void print_usage(void)
@@ -39,6 +41,9 @@ static void print_usage(void)
 
 static void print_option(const AVOption *opts, const AVOption *o, int per_stream)
 {
+    if (!(o->flags & (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM)))
+        return;
+
     printf("@item -%s%s @var{", o->name, per_stream ? "[:stream_specifier]" : "");
     switch (o->type) {
     case AV_OPT_TYPE_BINARY:   printf("hexadecimal string"); break;
@@ -93,18 +98,14 @@ static void show_opts(const AVOption *opts, int per_stream)
 
 static void show_format_opts(void)
 {
-#include "libavformat/options_table.h"
-
     printf("@section Format AVOptions\n");
-    show_opts(options, 0);
+    show_opts(avformat_options, 0);
 }
 
 static void show_codec_opts(void)
 {
-#include "libavcodec/options_table.h"
-
     printf("@section Codec AVOptions\n");
-    show_opts(options, 1);
+    show_opts(avcodec_options, 1);
 }
 
 int main(int argc, char **argv)
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 0d40e5e..1a9f575 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -164,12 +164,18 @@ content across a TCP/IP network.
 
 The required syntax is:
 @example
-rtmp://@var{server}[:@var{port}][/@var{app}][/@var{instance}][/@var{playpath}]
+rtmp://[@var{username}:@var{password}@@]@var{server}[:@var{port}][/@var{app}][/@var{instance}][/@var{playpath}]
 @end example
 
 The accepted parameters are:
 @table @option
 
+ at item username
+An optional username (mostly for publishing).
+
+ at item password
+An optional password (mostly for publishing).
+
 @item server
 The address of the RTMP server.
 
@@ -220,7 +226,8 @@ times to construct arbitrary AMF sequences.
 
 @item rtmp_flashver
 Version of the Flash plugin used to run the SWF player. The default
-is LNX 9,0,124,2.
+is LNX 9,0,124,2. (When publishing, the default is FMLE/3.0 (compatible;
+<libavformat version>).)
 
 @item rtmp_flush_interval
 Number of packets flushed in the same request (RTMPT only). The default
@@ -270,6 +277,12 @@ For example to read with @command{avplay} a multimedia resource named
 avplay rtmp://myserver/vod/sample
 @end example
 
+To publish to a password protected server, passing the playpath and
+app names separately:
+ at example
+avconv -re -i <input> -f flv -rtmp_playpath some/long/path -rtmp_app long/app/name rtmp://username:password@@myserver/
+ at end example
+
 @section rtmpe
 
 Encrypted Real-Time Messaging Protocol.
@@ -310,7 +323,7 @@ The Real-Time Messaging Protocol tunneled through HTTPS (RTMPTS) is used
 for streaming multimedia content within HTTPS requests to traverse
 firewalls.
 
- at section rtmp, rtmpe, rtmps, rtmpt, rtmpte
+ at section librtmp rtmp, rtmpe, rtmps, rtmpt, rtmpte
 
 Real-Time Messaging Protocol and its variants supported through
 librtmp.
@@ -555,6 +568,52 @@ avplay tcp://@var{hostname}:@var{port}
 
 @end table
 
+ at section tls
+
+Transport Layer Security (TLS) / Secure Sockets Layer (SSL)
+
+The required syntax for a TLS url is:
+ at example
+tls://@var{hostname}:@var{port}
+ at end example
+
+The following parameters can be set via command line options
+(or in code via @code{AVOption}s):
+
+ at table @option
+
+ at item ca_file
+A file containing certificate authority (CA) root certificates to treat
+as trusted. If the linked TLS library contains a default this might not
+need to be specified for verification to work, but not all libraries and
+setups have defaults built in.
+
+ at item tls_verify=@var{1|0}
+If enabled, try to verify the peer that we are communicating with.
+Note, if using OpenSSL, this currently only makes sure that the
+peer certificate is signed by one of the root certificates in the CA
+database, but it does not validate that the certificate actually
+matches the host name we are trying to connect to. (With GnuTLS,
+the host name is validated as well.)
+
+This is disabled by default since it requires a CA database to be
+provided by the caller in many cases.
+
+ at item cert_file
+A file containing a certificate to use in the handshake with the peer.
+(When operating as server, in listen mode, this is more often required
+by the peer, while client certificates only are mandated in certain
+setups.)
+
+ at item key_file
+A file containing the private key for the certificate.
+
+ at item listen=@var{1|0}
+If enabled, listen for connections on the provided port, and assume
+the server role in the handshake instead of the client role.
+
+ at end table
+
 @section udp
 
 User Datagram Protocol.
@@ -564,7 +623,7 @@ The required syntax for a UDP url is:
 udp://@var{hostname}:@var{port}[?@var{options}]
 @end example
 
- at var{options} contains a list of &-seperated options of the form @var{key}=@var{val}.
+ at var{options} contains a list of &-separated options of the form @var{key}=@var{val}.
 Follow the list of supported options.
 
 @table @option
@@ -626,4 +685,24 @@ To receive over UDP from a remote endpoint:
 avconv -i udp://[@var{multicast-address}]:@var{port}
 @end example
 
+ at section unix
+
+Unix local socket
+
+The required syntax for a Unix socket URL is:
+
+ at example
+unix://@var{filepath}
+ at end example
+
+The following parameters can be set via command line options
+(or in code via @code{AVOption}s):
+
+ at table @option
+ at item timeout
+Timeout in ms.
+ at item listen
+Create the Unix socket in listening mode.
+ at end table
+
 @c man end PROTOCOLS
diff --git a/doc/snow.txt b/doc/snow.txt
deleted file mode 100644
index f991339..0000000
--- a/doc/snow.txt
+++ /dev/null
@@ -1,630 +0,0 @@
-=============================================
-Snow Video Codec Specification Draft 20080110
-=============================================
-
-Introduction:
-=============
-This specification describes the Snow bitstream syntax and semantics as
-well as the formal Snow decoding process.
-
-The decoding process is described precisely and any compliant decoder
-MUST produce the exact same output for a spec-conformant Snow stream.
-For encoding, though, any process which generates a stream compliant to
-the syntactical and semantic requirements and which is decodable by
-the process described in this spec shall be considered a conformant
-Snow encoder.
-
-Definitions:
-============
-
-MUST    the specific part must be done to conform to this standard
-SHOULD  it is recommended to be done that way, but not strictly required
-
-ilog2(x) is the rounded down logarithm of x with basis 2
-ilog2(0) = 0
-
-Type definitions:
-=================
-
-b   1-bit range coded
-u   unsigned scalar value range coded
-s   signed scalar value range coded
-
-
-Bitstream syntax:
-=================
-
-frame:
-    header
-    prediction
-    residual
-
-header:
-    keyframe                            b   MID_STATE
-    if(keyframe || always_reset)
-        reset_contexts
-    if(keyframe){
-        version                         u   header_state
-        always_reset                    b   header_state
-        temporal_decomposition_type     u   header_state
-        temporal_decomposition_count    u   header_state
-        spatial_decomposition_count     u   header_state
-        colorspace_type                 u   header_state
-        chroma_h_shift                  u   header_state
-        chroma_v_shift                  u   header_state
-        spatial_scalability             b   header_state
-        max_ref_frames-1                u   header_state
-        qlogs
-    }
-    if(!keyframe){
-        update_mc                       b   header_state
-        if(update_mc){
-            for(plane=0; plane<2; plane++){
-                diag_mc                 b   header_state
-                htaps/2-1               u   header_state
-                for(i= p->htaps/2; i; i--)
-                    |hcoeff[i]|         u   header_state
-            }
-        }
-        update_qlogs                    b   header_state
-        if(update_qlogs){
-            spatial_decomposition_count u   header_state
-            qlogs
-        }
-    }
-
-    spatial_decomposition_type          s   header_state
-    qlog                                s   header_state
-    mv_scale                            s   header_state
-    qbias                               s   header_state
-    block_max_depth                     s   header_state
-
-qlogs:
-    for(plane=0; plane<2; plane++){
-        quant_table[plane][0][0]        s   header_state
-        for(level=0; level < spatial_decomposition_count; level++){
-            quant_table[plane][level][1]s   header_state
-            quant_table[plane][level][3]s   header_state
-        }
-    }
-
-reset_contexts
-    *_state[*]= MID_STATE
-
-prediction:
-    for(y=0; y<block_count_vertical; y++)
-        for(x=0; x<block_count_horizontal; x++)
-            block(0)
-
-block(level):
-    mvx_diff=mvy_diff=y_diff=cb_diff=cr_diff=0
-    if(keyframe){
-        intra=1
-    }else{
-        if(level!=max_block_depth){
-            s_context= 2*left->level + 2*top->level + topleft->level + topright->level
-            leaf                        b   block_state[4 + s_context]
-        }
-        if(level==max_block_depth || leaf){
-            intra                       b   block_state[1 + left->intra + top->intra]
-            if(intra){
-                y_diff                  s   block_state[32]
-                cb_diff                 s   block_state[64]
-                cr_diff                 s   block_state[96]
-            }else{
-                ref_context= ilog2(2*left->ref) + ilog2(2*top->ref)
-                if(ref_frames > 1)
-                    ref                 u   block_state[128 + 1024 + 32*ref_context]
-                mx_context= ilog2(2*abs(left->mx - top->mx))
-                my_context= ilog2(2*abs(left->my - top->my))
-                mvx_diff                s   block_state[128 + 32*(mx_context + 16*!!ref)]
-                mvy_diff                s   block_state[128 + 32*(my_context + 16*!!ref)]
-            }
-        }else{
-            block(level+1)
-            block(level+1)
-            block(level+1)
-            block(level+1)
-        }
-    }
-
-
-residual:
-    residual2(luma)
-    residual2(chroma_cr)
-    residual2(chroma_cb)
-
-residual2:
-    for(level=0; level<spatial_decomposition_count; level++){
-        if(level==0)
-            subband(LL, 0)
-        subband(HL, level)
-        subband(LH, level)
-        subband(HH, level)
-    }
-
-subband:
-    FIXME
-
-
-
-Tag description:
-----------------
-
-version
-    0
-    this MUST NOT change within a bitstream
-
-always_reset
-    if 1 then the range coder contexts will be reset after each frame
-
-temporal_decomposition_type
-    0
-
-temporal_decomposition_count
-    0
-
-spatial_decomposition_count
-    FIXME
-
-colorspace_type
-    0
-    this MUST NOT change within a bitstream
-
-chroma_h_shift
-    log2(luma.width / chroma.width)
-    this MUST NOT change within a bitstream
-
-chroma_v_shift
-    log2(luma.height / chroma.height)
-    this MUST NOT change within a bitstream
-
-spatial_scalability
-    0
-
-max_ref_frames
-    maximum number of reference frames
-    this MUST NOT change within a bitstream
-
-update_mc
-    indicates that motion compensation filter parameters are stored in the
-    header
-
-diag_mc
-    flag to enable faster diagonal interpolation
-    this SHOULD be 1 unless it turns out to be covered by a valid patent
-
-htaps
-    number of half pel interpolation filter taps, MUST be even, >0 and <10
-
-hcoeff
-    half pel interpolation filter coefficients, hcoeff[0] are the 2 middle
-    coefficients [1] are the next outer ones and so on, resulting in a filter
-    like: ...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ...
-    the sign of the coefficients is not explicitly stored but alternates
-    after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,...
-    hcoeff[0] is not explicitly stored but found by subtracting the sum
-    of all stored coefficients with signs from 32
-    hcoeff[0]= 32 - hcoeff[1] - hcoeff[2] - ...
-    a good choice for hcoeff and htaps is
-    htaps= 6
-    hcoeff={40,-10,2}
-    an alternative which requires more computations at both encoder and
-    decoder side and may or may not be better is
-    htaps= 8
-    hcoeff={42,-14,6,-2}
-
-
-ref_frames
-    minimum of the number of available reference frames and max_ref_frames
-    for example the first frame after a key frame always has ref_frames=1
-
-spatial_decomposition_type
-    wavelet type
-    0 is a 9/7 symmetric compact integer wavelet
-    1 is a 5/3 symmetric compact integer wavelet
-    others are reserved
-    stored as delta from last, last is reset to 0 if always_reset || keyframe
-
-qlog
-    quality (logarthmic quantizer scale)
-    stored as delta from last, last is reset to 0 if always_reset || keyframe
-
-mv_scale
-    stored as delta from last, last is reset to 0 if always_reset || keyframe
-    FIXME check that everything works fine if this changes between frames
-
-qbias
-    dequantization bias
-    stored as delta from last, last is reset to 0 if always_reset || keyframe
-
-block_max_depth
-    maximum depth of the block tree
-    stored as delta from last, last is reset to 0 if always_reset || keyframe
-
-quant_table
-    quantiztation table
-
-
-Highlevel bitstream structure:
-=============================
- --------------------------------------------
-|                   Header                   |
- --------------------------------------------
-|    ------------------------------------    |
-|   |               Block0               |   |
-|   |             split?                 |   |
-|   |     yes              no            |   |
-|   |  .........         intra?          |   |
-|   | : Block01 :    yes         no      |   |
-|   | : Block02 :  .......   ..........  |   |
-|   | : Block03 : :  y DC : : ref index: |   |
-|   | : Block04 : : cb DC : : motion x : |   |
-|   |  .........  : cr DC : : motion y : |   |
-|   |              .......   ..........  |   |
-|    ------------------------------------    |
-|    ------------------------------------    |
-|   |               Block1               |   |
-|                    ...                     |
- --------------------------------------------
-| ------------   ------------   ------------ |
-|| Y subbands | | Cb subbands| | Cr subbands||
-||  ---  ---  | |  ---  ---  | |  ---  ---  ||
-|| |LL0||HL0| | | |LL0||HL0| | | |LL0||HL0| ||
-||  ---  ---  | |  ---  ---  | |  ---  ---  ||
-||  ---  ---  | |  ---  ---  | |  ---  ---  ||
-|| |LH0||HH0| | | |LH0||HH0| | | |LH0||HH0| ||
-||  ---  ---  | |  ---  ---  | |  ---  ---  ||
-||  ---  ---  | |  ---  ---  | |  ---  ---  ||
-|| |HL1||LH1| | | |HL1||LH1| | | |HL1||LH1| ||
-||  ---  ---  | |  ---  ---  | |  ---  ---  ||
-||  ---  ---  | |  ---  ---  | |  ---  ---  ||
-|| |HH1||HL2| | | |HH1||HL2| | | |HH1||HL2| ||
-||    ...     | |    ...     | |    ...     ||
-| ------------   ------------   ------------ |
- --------------------------------------------
-
-Decoding process:
-=================
-
-                                         ------------
-                                        |            |
-                                        |  Subbands  |
-                   ------------         |            |
-                  |            |         ------------
-                  |  Intra DC  |               |
-                  |            |    LL0 subband prediction
-                   ------------                |
-                                \        Dequantizaton
- -------------------             \             |
-|  Reference frames |             \           IDWT
-| -------   ------- |    Motion    \           |
-||Frame 0| |Frame 1|| Compensation  .   OBMC   v      -------
-| -------   ------- | --------------. \------> + --->|Frame n|-->output
-| -------   ------- |                                 -------
-||Frame 2| |Frame 3||<----------------------------------/
-|        ...        |
- -------------------
-
-
-Range Coder:
-============
-
-Binary Range Coder:
--------------------
-The implemented range coder is an adapted version based upon "Range encoding:
-an algorithm for removing redundancy from a digitised message." by G. N. N.
-Martin.
-The symbols encoded by the Snow range coder are bits (0|1). The
-associated probabilities are not fix but change depending on the symbol mix
-seen so far.
-
-
-bit seen | new state
----------+-----------------------------------------------
-    0    | 256 - state_transition_table[256 - old_state];
-    1    |       state_transition_table[      old_state];
-
-state_transition_table = {
-  0,   0,   0,   0,   0,   0,   0,   0,  20,  21,  22,  23,  24,  25,  26,  27,
- 28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  37,  38,  39,  40,  41,  42,
- 43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,  56,  56,  57,
- 58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,
- 74,  75,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,
- 89,  90,  91,  92,  93,  94,  94,  95,  96,  97,  98,  99, 100, 101, 102, 103,
-104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118,
-119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133,
-134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
-150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
-165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179,
-180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194,
-195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209,
-210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225,
-226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240,
-241, 242, 243, 244, 245, 246, 247, 248, 248,   0,   0,   0,   0,   0,   0,   0};
-
-FIXME
-
-
-Range Coding of integers:
--------------------------
-FIXME
-
-
-Neighboring Blocks:
-===================
-left and top are set to the respective blocks unless they are outside of
-the image in which case they are set to the Null block
-
-top-left is set to the top left block unless it is outside of the image in
-which case it is set to the left block
-
-if this block has no larger parent block or it is at the left side of its
-parent block and the top right block is not outside of the image then the
-top right block is used for top-right else the top-left block is used
-
-Null block
-y,cb,cr are 128
-level, ref, mx and my are 0
-
-
-Motion Vector Prediction:
-=========================
-1. the motion vectors of all the neighboring blocks are scaled to
-compensate for the difference of reference frames
-
-scaled_mv= (mv * (256 * (current_reference+1) / (mv.reference+1)) + 128)>>8
-
-2. the median of the scaled left, top and top-right vectors is used as
-motion vector prediction
-
-3. the used motion vector is the sum of the predictor and
-   (mvx_diff, mvy_diff)*mv_scale
-
-
-Intra DC Predicton:
-======================
-the luma and chroma values of the left block are used as predictors
-
-the used luma and chroma is the sum of the predictor and y_diff, cb_diff, cr_diff
-to reverse this in the decoder apply the following:
-block[y][x].dc[0] = block[y][x-1].dc[0] +  y_diff;
-block[y][x].dc[1] = block[y][x-1].dc[1] + cb_diff;
-block[y][x].dc[2] = block[y][x-1].dc[2] + cr_diff;
-block[*][-1].dc[*]= 128;
-
-
-Motion Compensation:
-====================
-
-Halfpel interpolation:
-----------------------
-halfpel interpolation is done by convolution with the halfpel filter stored
-in the header:
-
-horizontal halfpel samples are found by
-H1[y][x] =    hcoeff[0]*(F[y][x  ] + F[y][x+1])
-            + hcoeff[1]*(F[y][x-1] + F[y][x+2])
-            + hcoeff[2]*(F[y][x-2] + F[y][x+3])
-            + ...
-h1[y][x] = (H1[y][x] + 32)>>6;
-
-vertical halfpel samples are found by
-H2[y][x] =    hcoeff[0]*(F[y  ][x] + F[y+1][x])
-            + hcoeff[1]*(F[y-1][x] + F[y+2][x])
-            + ...
-h2[y][x] = (H2[y][x] + 32)>>6;
-
-vertical+horizontal halfpel samples are found by
-H3[y][x] =    hcoeff[0]*(H2[y][x  ] + H2[y][x+1])
-            + hcoeff[1]*(H2[y][x-1] + H2[y][x+2])
-            + ...
-H3[y][x] =    hcoeff[0]*(H1[y  ][x] + H1[y+1][x])
-            + hcoeff[1]*(H1[y+1][x] + H1[y+2][x])
-            + ...
-h3[y][x] = (H3[y][x] + 2048)>>12;
-
-
-                   F   H1  F
-                   |   |   |
-                   |   |   |
-                   |   |   |
-                   F   H1  F
-                   |   |   |
-                   |   |   |
-                   |   |   |
-   F-------F-------F-> H1<-F-------F-------F
-                   v   v   v
-                  H2   H3  H2
-                   ^   ^   ^
-   F-------F-------F-> H1<-F-------F-------F
-                   |   |   |
-                   |   |   |
-                   |   |   |
-                   F   H1  F
-                   |   |   |
-                   |   |   |
-                   |   |   |
-                   F   H1  F
-
-
-unavailable fullpel samples (outside the picture for example) shall be equal
-to the closest available fullpel sample
-
-
-Smaller pel interpolation:
---------------------------
-if diag_mc is set then points which lie on a line between 2 vertically,
-horiziontally or diagonally adjacent halfpel points shall be interpolated
-linearls with rounding to nearest and halfway values rounded up.
-points which lie on 2 diagonals at the same time should only use the one
-diagonal not containing the fullpel point
-
-
-
-           F-->O---q---O<--h1->O---q---O<--F
-           v \           / v \           / v
-           O   O       O   O   O       O   O
-           |         /     |     \         |
-           q       q       q       q       q
-           |     /         |         \     |
-           O   O       O   O   O       O   O
-           ^ /           \ ^ /           \ ^
-          h2-->O---q---O<--h3->O---q---O<--h2
-           v \           / v \           / v
-           O   O       O   O   O       O   O
-           |     \         |         /     |
-           q       q       q       q       q
-           |         \     |     /         |
-           O   O       O   O   O       O   O
-           ^ /           \ ^ /           \ ^
-           F-->O---q---O<--h1->O---q---O<--F
-
-
-
-the remaining points shall be bilinearly interpolated from the
-up to 4 surrounding halfpel and fullpel points, again rounding should be to
-nearest and halfway values rounded up
-
-compliant Snow decoders MUST support 1-1/8 pel luma and 1/2-1/16 pel chroma
-interpolation at least
-
-
-Overlapped block motion compensation:
--------------------------------------
-FIXME
-
-LL band prediction:
-===================
-Each sample in the LL0 subband is predicted by the median of the left, top and
-left+top-topleft samples, samples outside the subband shall be considered to
-be 0. To reverse this prediction in the decoder apply the following.
-for(y=0; y<height; y++){
-    for(x=0; x<width; x++){
-        sample[y][x] += median(sample[y-1][x],
-                               sample[y][x-1],
-                               sample[y-1][x]+sample[y][x-1]-sample[y-1][x-1]);
-    }
-}
-sample[-1][*]=sample[*][-1]= 0;
-width,height here are the width and height of the LL0 subband not of the final
-video
-
-
-Dequantizaton:
-==============
-FIXME
-
-Wavelet Transform:
-==================
-
-Snow supports 2 wavelet transforms, the symmetric biorthogonal 5/3 integer
-transform and a integer approximation of the symmetric biorthogonal 9/7
-daubechies wavelet.
-
-2D IDWT (inverse discrete wavelet transform)
---------------------------------------------
-The 2D IDWT applies a 2D filter recursively, each time combining the
-4 lowest frequency subbands into a single subband until only 1 subband
-remains.
-The 2D filter is done by first applying a 1D filter in the vertical direction
-and then applying it in the horizontal one.
- ---------------    ---------------    ---------------    ---------------
-|LL0|HL0|       |  |   |   |       |  |       |       |  |       |       |
-|---+---|  HL1  |  | L0|H0 |  HL1  |  |  LL1  |  HL1  |  |       |       |
-|LH0|HH0|       |  |   |   |       |  |       |       |  |       |       |
-|-------+-------|->|-------+-------|->|-------+-------|->|   L1  |  H1   |->...
-|       |       |  |       |       |  |       |       |  |       |       |
-|  LH1  |  HH1  |  |  LH1  |  HH1  |  |  LH1  |  HH1  |  |       |       |
-|       |       |  |       |       |  |       |       |  |       |       |
- ---------------    ---------------    ---------------    ---------------
-
-
-1D Filter:
-----------
-1. interleave the samples of the low and high frequency subbands like
-s={L0, H0, L1, H1, L2, H2, L3, H3, ... }
-note, this can end with a L or a H, the number of elements shall be w
-s[-1] shall be considered equivalent to s[1  ]
-s[w ] shall be considered equivalent to s[w-2]
-
-2. perform the lifting steps in order as described below
-
-5/3 Integer filter:
-1. s[i] -= (s[i-1] + s[i+1] + 2)>>2; for all even i < w
-2. s[i] += (s[i-1] + s[i+1]    )>>1; for all odd  i < w
-
-\ | /|\ | /|\ | /|\ | /|\
- \|/ | \|/ | \|/ | \|/ |
-  +  |  +  |  +  |  +  |   -1/4
- /|\ | /|\ | /|\ | /|\ |
-/ | \|/ | \|/ | \|/ | \|/
-  |  +  |  +  |  +  |  +   +1/2
-
-
-Snow's 9/7 Integer filter:
-1. s[i] -= (3*(s[i-1] + s[i+1])         + 4)>>3; for all even i < w
-2. s[i] -=     s[i-1] + s[i+1]                 ; for all odd  i < w
-3. s[i] += (   s[i-1] + s[i+1] + 4*s[i] + 8)>>4; for all even i < w
-4. s[i] += (3*(s[i-1] + s[i+1])            )>>1; for all odd  i < w
-
-\ | /|\ | /|\ | /|\ | /|\
- \|/ | \|/ | \|/ | \|/ |
-  +  |  +  |  +  |  +  |   -3/8
- /|\ | /|\ | /|\ | /|\ |
-/ | \|/ | \|/ | \|/ | \|/
- (|  + (|  + (|  + (|  +   -1
-\ + /|\ + /|\ + /|\ + /|\  +1/4
- \|/ | \|/ | \|/ | \|/ |
-  +  |  +  |  +  |  +  |   +1/16
- /|\ | /|\ | /|\ | /|\ |
-/ | \|/ | \|/ | \|/ | \|/
-  |  +  |  +  |  +  |  +   +3/2
-
-optimization tips:
-following are exactly identical
-(3a)>>1 == a + (a>>1)
-(a + 4b + 8)>>4 == ((a>>2) + b + 2)>>2
-
-16bit implementation note:
-The IDWT can be implemented with 16bits, but this requires some care to
-prevent overflows, the following list, lists the minimum number of bits needed
-for some terms
-1. lifting step
-A= s[i-1] + s[i+1]                              16bit
-3*A + 4                                         18bit
-A + (A>>1) + 2                                  17bit
-
-3. lifting step
-s[i-1] + s[i+1]                                 17bit
-
-4. lifiting step
-3*(s[i-1] + s[i+1])                             17bit
-
-
-TODO:
-=====
-Important:
-finetune initial contexts
-flip wavelet?
-try to use the wavelet transformed predicted image (motion compensated image) as context for coding the residual coefficients
-try the MV length as context for coding the residual coefficients
-use extradata for stuff which is in the keyframes now?
-the MV median predictor is patented IIRC
-implement per picture halfpel interpolation
-try different range coder state transition tables for different contexts
-
-Not Important:
-compare the 6 tap and 8 tap hpel filters (psnr/bitrate and subjective quality)
-spatial_scalability b vs u (!= 0 breaks syntax anyway so we can add a u later)
-
-
-Credits:
-========
-Michael Niedermayer
-Loren Merritt
-
-
-Copyright:
-==========
-GPL + GFDL + whatever is needed to make this a RFC
diff --git a/doc/t2h.init b/doc/t2h.init
index 78c5177..a42637a 100644
--- a/doc/t2h.init
+++ b/doc/t2h.init
@@ -185,7 +185,7 @@ $print_page_head = \&Libav_print_page_head;
 sub Libav_print_page_head($$)
 {
     my $fh = shift;
-    my $longtitle = "$Texi2HTML::THISDOC{'title_no_texi'}";
+    my $longtitle = "$Texi2HTML::THISDOC{'fulltitle_no_texi'}";
     $longtitle .= ": $Texi2HTML::NO_TEXI{'This'}" if exists $Texi2HTML::NO_TEXI{'This'};
     my $description = $DOCUMENT_DESCRIPTION;
     $description = $longtitle if (!defined($description));
diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl
index 94323be..fb4f7be 100755
--- a/doc/texi2pod.pl
+++ b/doc/texi2pod.pl
@@ -1,4 +1,4 @@
-#! /usr/bin/perl -w
+#!/usr/bin/env 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 = ();
@@ -161,7 +163,7 @@ INF: while(<$inf>) {
         } elsif ($ended =~ /^(?:example|smallexample|display)$/) {
             $shift = "";
             $_ = "";        # need a paragraph break
-        } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
+        } elsif ($ended =~ /^(?:itemize|enumerate|(?:multi|[fv])?table)$/) {
             $_ = "\n=back\n";
             $ic = pop @icstack;
         } else {
@@ -262,7 +264,7 @@ INF: while(<$inf>) {
         $endw = "enumerate";
     };
 
-    /^\@([fv]?table)\s+(\@[a-z]+)/ and do {
+    /^\@((?:multi|[fv])?table)\s+(\@[a-z]+)/ and do {
         push @endwstack, $endw;
         push @icstack, $ic;
         $endw = $1;
@@ -271,6 +273,7 @@ INF: while(<$inf>) {
         $ic =~ s/\@(?:code|kbd)/C/;
         $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
         $ic =~ s/\@(?:file)/F/;
+        $ic =~ s/\@(?:columnfractions)//;
         $_ = "\n=over 4\n";
     };
 
@@ -281,6 +284,21 @@ INF: while(<$inf>) {
         $_ = "";        # need a paragraph break
     };
 
+    /^\@item\s+(.*\S)\s*$/ and $endw eq "multitable" and do {
+        my $columns = $1;
+        $columns =~ s/\@tab/ : /;
+
+        $_ = "\n=item B<". $columns .">\n";
+    };
+
+    /^\@tab\s+(.*\S)\s*$/ and $endw eq "multitable" and do {
+        my $columns = $1;
+        $columns =~ s/\@tab/ : /;
+
+        $_ = " : ". $columns;
+        $section =~ s/\n+\s+$//;
+    };
+
     /^\@itemx?\s*(.+)?$/ and do {
         if (defined $1) {
             # Entity escapes prevent munging by the <> processing below.
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index cc0361d..09336b0 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -24,6 +24,7 @@
  * 4XM codec.
  */
 
+#include "libavutil/frame.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
@@ -31,9 +32,6 @@
 #include "get_bits.h"
 #include "internal.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
 #define BLOCK_TYPE_VLC_BITS 5
 #define ACDC_VLC_BITS 9
 
@@ -131,7 +129,7 @@ typedef struct CFrameBuffer {
 typedef struct FourXContext {
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame current_picture, last_picture;
+    AVFrame *last_picture;
     GetBitContext pre_gb;          ///< ac/dc prefix
     GetBitContext gb;
     GetByteContext g;
@@ -139,7 +137,7 @@ typedef struct FourXContext {
     int mv[256];
     VLC pre_vlc;
     int last_dc;
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
     void *bitstream_buffer;
     unsigned int bitstream_buffer_size;
     int version;
@@ -154,7 +152,7 @@ typedef struct FourXContext {
 
 #define MULTIPLY(var, const) (((var) * (const)) >> 16)
 
-static void idct(DCTELEM block[64])
+static void idct(int16_t block[64])
 {
     int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     int tmp10, tmp11, tmp12, tmp13;
@@ -256,15 +254,15 @@ static av_cold void init_vlcs(FourXContext *f)
     }
 }
 
-static void init_mv(FourXContext *f)
+static void init_mv(FourXContext *f, int linesize)
 {
     int i;
 
     for (i = 0; i < 256; i++) {
         if (f->version > 1)
-            f->mv[i] = mv[i][0] + mv[i][1] * f->current_picture.linesize[0] / 2;
+            f->mv[i] = mv[i][0] + mv[i][1] * linesize / 2;
         else
-            f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * f->current_picture.linesize[0] / 2;
+            f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * linesize / 2;
     }
 }
 
@@ -341,55 +339,29 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
     int code        = get_vlc2(&f->gb,
                                block_type_vlc[1 - (f->version > 1)][index].table,
                                BLOCK_TYPE_VLC_BITS, 1);
-    uint16_t *start = (uint16_t *)f->last_picture.data[0];
+    uint16_t *start = (uint16_t *)f->last_picture->data[0];
     uint16_t *end   = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
     int ret;
+    int scale   = 1;
+    unsigned dc = 0;
 
     if (code < 0 || code > 6 || log2w < 0)
         return AVERROR_INVALIDDATA;
 
-    if (code == 0) {
-        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 AVERROR_INVALIDDATA;
-        }
-        mcdc(dst, src, log2w, h, stride, 1, 0);
-    } else if (code == 1) {
+    if (code == 1) {
         log2h--;
         if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0)
             return ret;
-        if ((ret = decode_p_block(f, dst + (stride << log2h),
-                                  src + (stride << log2h),
-                                  log2w, log2h, stride)) < 0)
-            return ret;
+        return decode_p_block(f, dst + (stride << log2h),
+                              src + (stride << log2h),
+                              log2w, log2h, stride);
     } else if (code == 2) {
         log2w--;
         if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0)
             return ret;
-        if ((ret = decode_p_block(f, dst + (1 << log2w),
-                                  src + (1 << log2w),
-                                  log2w, log2h, stride)) < 0)
-            return ret;
-    } else if (code == 3 && f->version < 2) {
-        if (start > src || src > end) {
-            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
-            return AVERROR_INVALIDDATA;
-        }
-        mcdc(dst, src, log2w, h, stride, 1, 0);
-    } else if (code == 4) {
-        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 AVERROR_INVALIDDATA;
-        }
-        mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2));
-    } else if (code == 5) {
-        if (start > src || src > end) {
-            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
-            return AVERROR_INVALIDDATA;
-        }
-        mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2));
+        return decode_p_block(f, dst + (1 << log2w),
+                              src + (1 << log2w),
+                              log2w, log2h, stride);
     } else if (code == 6) {
         if (log2w) {
             dst[0]      = bytestream2_get_le16(&f->g2);
@@ -398,31 +370,56 @@ static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
             dst[0]      = bytestream2_get_le16(&f->g2);
             dst[stride] = bytestream2_get_le16(&f->g2);
         }
+        return 0;
     }
+
+    if (code == 0) {
+        src  += f->mv[bytestream2_get_byte(&f->g)];
+    } else if (code == 3 && f->version >= 2) {
+        return 0;
+    } else if (code == 4) {
+        src  += f->mv[bytestream2_get_byte(&f->g)];
+        dc    = bytestream2_get_le16(&f->g2);
+    } else if (code == 5) {
+        scale = 0;
+        dc    = bytestream2_get_le16(&f->g2);
+    }
+
+    if (start > src || src > end) {
+        av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    mcdc(dst, src, log2w, h, stride, scale, dc);
+
     return 0;
 }
 
-static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
+static int decode_p_frame(FourXContext *f, AVFrame *frame,
+                          const uint8_t *buf, int length)
 {
     int x, y;
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
-    uint16_t *src    = (uint16_t *)f->last_picture.data[0];
-    uint16_t *dst    = (uint16_t *)f->current_picture.data[0];
-    const int stride =             f->current_picture.linesize[0] >> 1;
+    uint16_t *dst    = (uint16_t *)frame->data[0];
+    const int stride =             frame->linesize[0] >> 1;
+    uint16_t *src;
     unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
                  bytestream_offset, wordstream_offset;
     int ret;
 
-    if (!f->last_picture.data[0]) {
-        if ((ret = ff_get_buffer(f->avctx, &f->last_picture)) < 0) {
+    if (!f->last_picture->data[0]) {
+        if ((ret = ff_get_buffer(f->avctx, f->last_picture,
+                                 AV_GET_BUFFER_FLAG_REF)) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
-        memset(f->last_picture.data[0], 0,
-               f->avctx->height * FFABS(f->last_picture.linesize[0]));
+        memset(f->last_picture->data[0], 0,
+               f->avctx->height * FFABS(f->last_picture->linesize[0]));
     }
 
+    src = (uint16_t *)f->last_picture->data[0];
+
     if (f->version > 1) {
         if (length < 20)
             return AVERROR_INVALIDDATA;
@@ -444,7 +441,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
         av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n",
                bitstream_size, bytestream_size, wordstream_size,
                bitstream_size + bytestream_size + wordstream_size - length);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
@@ -464,7 +461,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
     bytestream2_init(&f->g, buf + bytestream_offset,
                      length - bytestream_offset);
 
-    init_mv(f);
+    init_mv(f, frame->linesize[0]);
 
     for (y = 0; y < height; y += 8) {
         for (x = 0; x < width; x += 8)
@@ -481,7 +478,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
  * decode block and dequantize.
  * Note this is almost identical to MJPEG.
  */
-static int decode_i_block(FourXContext *f, DCTELEM *block)
+static int decode_i_block(FourXContext *f, int16_t *block)
 {
     int code, i, j, level, val;
 
@@ -524,12 +521,12 @@ static int decode_i_block(FourXContext *f, DCTELEM *block)
     return 0;
 }
 
-static inline void idct_put(FourXContext *f, int x, int y)
+static inline void idct_put(FourXContext *f, AVFrame *frame, int x, int y)
 {
-    DCTELEM (*block)[64] = f->block;
-    int stride           = f->current_picture.linesize[0] >> 1;
+    int16_t (*block)[64] = f->block;
+    int stride           = frame->linesize[0] >> 1;
     int i;
-    uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
+    uint16_t *dst = ((uint16_t*)frame->data[0]) + y * stride + x;
 
     for (i = 0; i < 4; i++) {
         block[i][0] += 0x80 * 8 * 8;
@@ -547,7 +544,7 @@ static inline void idct_put(FourXContext *f, int x, int y)
      * cr = (-1b - 4g + 5r) / 14 */
     for (y = 0; y < 8; y++) {
         for (x = 0; x < 8; x++) {
-            DCTELEM *temp = block[(x >> 2) + 2 * (y >> 2)] +
+            int16_t *temp = block[(x >> 2) + 2 * (y >> 2)] +
                             2 * (x & 3) + 2 * 8 * (y & 3); // FIXME optimize
             int cb = block[4][x + 8 * y];
             int cr = block[5][x + 8 * y];
@@ -572,13 +569,14 @@ static inline void idct_put(FourXContext *f, int x, int y)
 
 static int decode_i_mb(FourXContext *f)
 {
+    int ret;
     int i;
 
     f->dsp.clear_blocks(f->block[0]);
 
     for (i = 0; i < 6; i++)
-        if (decode_i_block(f, f->block[i]) < 0)
-            return -1;
+        if ((ret = decode_i_block(f, f->block[i])) < 0)
+            return ret;
 
     return 0;
 }
@@ -685,14 +683,14 @@ static int mix(int c0, int c1)
     return red / 3 * 1024 + green / 3 * 32 + blue / 3;
 }
 
-static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
+static int decode_i2_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, int length)
 {
     int x, y, x2, y2;
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
     const int mbs    = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4);
-    uint16_t *dst    = (uint16_t*)f->current_picture.data[0];
-    const int stride =            f->current_picture.linesize[0]>>1;
+    uint16_t *dst    = (uint16_t*)frame->data[0];
+    const int stride =            frame->linesize[0]>>1;
     GetByteContext g3;
 
     if (length < mbs * 8) {
@@ -731,9 +729,9 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
     return 0;
 }
 
-static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
+static int decode_i_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, int length)
 {
-    int x, y;
+    int x, y, ret;
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
     const unsigned int bitstream_size = AV_RL32(buf);
@@ -757,7 +755,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
         || prestream_size > (1 << 26)) {
         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n",
                prestream_size, bitstream_size, length);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     prestream = read_huffman_tables(f, prestream, prestream_size);
@@ -784,10 +782,10 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
 
     for (y = 0; y < height; y += 16) {
         for (x = 0; x < width; x += 16) {
-            if (decode_i_mb(f) < 0)
-                return -1;
+            if ((ret = decode_i_mb(f)) < 0)
+                return ret;
 
-            idct_put(f, x, y);
+            idct_put(f, frame, x, y);
         }
     }
 
@@ -804,8 +802,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     int buf_size          = avpkt->size;
     FourXContext *const f = avctx->priv_data;
     AVFrame *picture      = data;
-    AVFrame *p, temp;
-    int i, frame_4cc, frame_size;
+    int i, frame_4cc, frame_size, ret;
 
     if (buf_size < 20)
         return AVERROR_INVALIDDATA;
@@ -859,7 +856,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
         // explicit check needed as memcpy below might not catch a NULL
         if (!cfrm->data) {
             av_log(f->avctx, AV_LOG_ERROR, "realloc failure");
-            return -1;
+            return AVERROR(ENOMEM);
         }
 
         memcpy(cfrm->data + cfrm->size, buf + 20, data_size);
@@ -885,38 +882,26 @@ static int decode_frame(AVCodecContext *avctx, void *data,
         frame_size = buf_size - 12;
     }
 
-    temp               = f->current_picture;
-    f->current_picture = f->last_picture;
-    f->last_picture    = temp;
-
-    p                  = &f->current_picture;
-    avctx->coded_frame = p;
-
     // 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 (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, picture, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (frame_4cc == AV_RL32("ifr2")) {
-        p->pict_type = AV_PICTURE_TYPE_I;
-        if (decode_i2_frame(f, buf - 4, frame_size + 4) < 0)
-            return -1;
+        picture->pict_type = AV_PICTURE_TYPE_I;
+        if ((ret = decode_i2_frame(f, picture, buf - 4, frame_size + 4)) < 0)
+            return ret;
     } else if (frame_4cc == AV_RL32("ifrm")) {
-        p->pict_type = AV_PICTURE_TYPE_I;
-        if (decode_i_frame(f, buf, frame_size) < 0)
-            return -1;
+        picture->pict_type = AV_PICTURE_TYPE_I;
+        if ((ret = decode_i_frame(f, picture, buf, frame_size)) < 0)
+            return ret;
     } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
-
-        p->pict_type = AV_PICTURE_TYPE_P;
-        if (decode_p_frame(f, buf, frame_size) < 0)
-            return -1;
+        picture->pict_type = AV_PICTURE_TYPE_P;
+        if ((ret = decode_p_frame(f, picture, buf, frame_size)) < 0)
+            return ret;
     } else if (frame_4cc == AV_RL32("snd_")) {
         av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n",
                buf_size);
@@ -925,9 +910,11 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                buf_size);
     }
 
-    p->key_frame = p->pict_type == AV_PICTURE_TYPE_I;
+    picture->key_frame = picture->pict_type == AV_PICTURE_TYPE_I;
 
-    *picture   = *p;
+    av_frame_unref(f->last_picture);
+    if ((ret = av_frame_ref(f->last_picture, picture)) < 0)
+        return ret;
     *got_frame = 1;
 
     emms_c();
@@ -935,16 +922,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     return buf_size;
 }
 
-
-static av_cold void common_init(AVCodecContext *avctx)
-{
-    FourXContext * const f = avctx->priv_data;
-
-    ff_dsputil_init(&f->dsp, avctx);
-
-    f->avctx = avctx;
-}
-
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     FourXContext * const f = avctx->priv_data;
@@ -955,7 +932,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
     }
 
     f->version = AV_RL32(avctx->extradata) >> 16;
-    common_init(avctx);
+    ff_dsputil_init(&f->dsp, avctx);
+    f->avctx = avctx;
     init_vlcs(f);
 
     if (f->version > 2)
@@ -963,6 +941,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
     else
         avctx->pix_fmt = AV_PIX_FMT_BGR555;
 
+    f->last_picture = av_frame_alloc();
+    if (!f->last_picture)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
@@ -979,16 +961,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
         f->cfrm[i].allocated_size = 0;
     }
     ff_free_vlc(&f->pre_vlc);
-    if (f->current_picture.data[0])
-        avctx->release_buffer(avctx, &f->current_picture);
-    if (f->last_picture.data[0])
-        avctx->release_buffer(avctx, &f->last_picture);
+    av_frame_free(&f->last_picture);
 
     return 0;
 }
 
 AVCodec ff_fourxm_decoder = {
     .name           = "4xm",
+    .long_name      = NULL_IF_CONFIG_SMALL("4X Movie"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_4XM,
     .priv_data_size = sizeof(FourXContext),
@@ -996,5 +976,4 @@ AVCodec ff_fourxm_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("4X Movie"),
 };
diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c
index 3d81810..cfeb486 100644
--- a/libavcodec/8bps.c
+++ b/libavcodec/8bps.c
@@ -46,7 +46,6 @@ static const enum AVPixelFormat pixfmt_rgb24[] = {
 
 typedef struct EightBpsContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     unsigned char planes;
     unsigned char planemap[4];
@@ -57,6 +56,7 @@ typedef struct EightBpsContext {
 static int decode_frame(AVCodecContext *avctx, void *data,
                         int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     EightBpsContext * const c = avctx->priv_data;
@@ -69,15 +69,11 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     unsigned int px_inc;
     unsigned int planes     = c->planes;
     unsigned char *planemap = c->planemap;
+    int ret;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference    = 0;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if (ff_get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     ep = encoded + buf_size;
@@ -97,29 +93,29 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 
         /* Decode a plane */
         for (row = 0; row < height; row++) {
-            pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p];
-            pixptr_end = pixptr + c->pic.linesize[0];
+            pixptr = frame->data[0] + row * frame->linesize[0] + planemap[p];
+            pixptr_end = pixptr + frame->linesize[0];
             if (ep - lp < row * 2 + 2)
                 return AVERROR_INVALIDDATA;
             dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2));
             /* Decode a row of this plane */
             while (dlen > 0) {
                 if (ep - dp <= 1)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 if ((count = *dp++) <= 127) {
                     count++;
                     dlen -= count + 1;
-                    if (pixptr + count * px_inc > pixptr_end)
+                    if (pixptr_end - pixptr < count * px_inc)
                         break;
                     if (ep - dp < count)
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     while (count--) {
                         *pixptr = *dp++;
                         pixptr += px_inc;
                     }
                 } else {
                     count = 257 - count;
-                    if (pixptr + count * px_inc > pixptr_end)
+                    if (pixptr_end - pixptr < count * px_inc)
                         break;
                     while (count--) {
                         *pixptr = *dp;
@@ -137,15 +133,14 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                                                      AV_PKT_DATA_PALETTE,
                                                      NULL);
         if (pal) {
-            c->pic.palette_has_changed = 1;
+            frame->palette_has_changed = 1;
             memcpy(c->pal, pal, AVPALETTE_SIZE);
         }
 
-        memcpy (c->pic.data[1], c->pal, AVPALETTE_SIZE);
+        memcpy (frame->data[1], c->pal, AVPALETTE_SIZE);
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -156,7 +151,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     EightBpsContext * const c = avctx->priv_data;
 
     c->avctx       = avctx;
-    c->pic.data[0] = NULL;
 
     switch (avctx->bits_per_coded_sample) {
     case 8:
@@ -174,45 +168,30 @@ static av_cold int decode_init(AVCodecContext *avctx)
     case 32:
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
         c->planes      = 4;
-#if HAVE_BIGENDIAN
-        c->planemap[0] = 1; // 1st plane is red
-        c->planemap[1] = 2; // 2nd plane is green
-        c->planemap[2] = 3; // 3rd plane is blue
-        c->planemap[3] = 0; // 4th plane is alpha???
-#else
-        c->planemap[0] = 2; // 1st plane is red
-        c->planemap[1] = 1; // 2nd plane is green
-        c->planemap[2] = 0; // 3rd plane is blue
-        c->planemap[3] = 3; // 4th plane is alpha???
-#endif
+        /* handle planemap setup later for decoding rgb24 data as rbg32 */
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n",
                avctx->bits_per_coded_sample);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    EightBpsContext * const c = avctx->priv_data;
-
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
+    if (avctx->pix_fmt == AV_PIX_FMT_RGB32) {
+        c->planemap[0] = HAVE_BIGENDIAN ? 1 : 2; // 1st plane is red
+        c->planemap[1] = HAVE_BIGENDIAN ? 2 : 1; // 2nd plane is green
+        c->planemap[2] = HAVE_BIGENDIAN ? 3 : 0; // 3rd plane is blue
+        c->planemap[3] = HAVE_BIGENDIAN ? 0 : 3; // 4th plane is alpha???
+    }
     return 0;
 }
 
 AVCodec ff_eightbps_decoder = {
     .name           = "8bps",
+    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_8BPS,
     .priv_data_size = sizeof(EightBpsContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
 };
diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c
index dda181b..11fbf19 100644
--- a/libavcodec/8svx.c
+++ b/libavcodec/8svx.c
@@ -34,7 +34,6 @@
 
 /** decoder context */
 typedef struct EightSvxContext {
-    AVFrame frame;
     uint8_t fib_acc[2];
     const int8_t *table;
 
@@ -85,6 +84,7 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data,
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
     EightSvxContext *esc = avctx->priv_data;
+    AVFrame *frame       = data;
     int buf_size;
     int ch, ret;
     int is_compr = (avctx->codec_id != AV_CODEC_ID_PCM_S8_PLANAR);
@@ -136,26 +136,25 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    esc->frame.nb_samples = buf_size * (is_compr + 1);
-    if ((ret = ff_get_buffer(avctx, &esc->frame)) < 0) {
+    frame->nb_samples = buf_size * (is_compr + 1);
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     for (ch = 0; ch < avctx->channels; ch++) {
         if (is_compr) {
-            delta_decode(esc->frame.data[ch], &esc->data[ch][esc->data_idx],
+            delta_decode(frame->data[ch], &esc->data[ch][esc->data_idx],
                          buf_size, &esc->fib_acc[ch], esc->table);
         } else {
-            raw_decode(esc->frame.data[ch], &esc->data[ch][esc->data_idx],
+            raw_decode(frame->data[ch], &esc->data[ch][esc->data_idx],
                        buf_size);
         }
     }
 
     esc->data_idx += buf_size;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = esc->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
@@ -184,9 +183,6 @@ static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
     }
     avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
 
-    avcodec_get_frame_defaults(&esc->frame);
-    avctx->coded_frame = &esc->frame;
-
     return 0;
 }
 
@@ -202,6 +198,7 @@ static av_cold int eightsvx_decode_close(AVCodecContext *avctx)
 
 AVCodec ff_eightsvx_fib_decoder = {
   .name           = "8svx_fib",
+  .long_name      = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
   .type           = AVMEDIA_TYPE_AUDIO,
   .id             = AV_CODEC_ID_8SVX_FIB,
   .priv_data_size = sizeof (EightSvxContext),
@@ -209,13 +206,13 @@ AVCodec ff_eightsvx_fib_decoder = {
   .close          = eightsvx_decode_close,
   .decode         = eightsvx_decode_frame,
   .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
-  .long_name      = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
   .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                     AV_SAMPLE_FMT_NONE },
 };
 
 AVCodec ff_eightsvx_exp_decoder = {
   .name           = "8svx_exp",
+  .long_name      = NULL_IF_CONFIG_SMALL("8SVX exponential"),
   .type           = AVMEDIA_TYPE_AUDIO,
   .id             = AV_CODEC_ID_8SVX_EXP,
   .priv_data_size = sizeof (EightSvxContext),
@@ -223,13 +220,13 @@ AVCodec ff_eightsvx_exp_decoder = {
   .close          = eightsvx_decode_close,
   .decode         = eightsvx_decode_frame,
   .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
-  .long_name      = NULL_IF_CONFIG_SMALL("8SVX exponential"),
   .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                     AV_SAMPLE_FMT_NONE },
 };
 
 AVCodec ff_pcm_s8_planar_decoder = {
     .name           = "pcm_s8_planar",
+    .long_name      = NULL_IF_CONFIG_SMALL("PCM signed 8-bit planar"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_PCM_S8_PLANAR,
     .priv_data_size = sizeof(EightSvxContext),
@@ -237,7 +234,6 @@ AVCodec ff_pcm_s8_planar_decoder = {
     .close          = eightsvx_decode_close,
     .decode         = eightsvx_decode_frame,
     .capabilities   = CODEC_CAP_DELAY | 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 },
 };
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index a32ff96..fb79c32 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -4,7 +4,6 @@ FFLIBS = avutil
 HEADERS = avcodec.h                                                     \
           avfft.h                                                       \
           dxva2.h                                                       \
-          old_codec_ids.h                                               \
           vaapi.h                                                       \
           vda.h                                                         \
           vdpau.h                                                       \
@@ -12,25 +11,18 @@ HEADERS = avcodec.h                                                     \
           xvmc.h                                                        \
 
 OBJS = allcodecs.o                                                      \
-       audioconvert.o                                                   \
        avpacket.o                                                       \
        avpicture.o                                                      \
        bitstream.o                                                      \
        bitstream_filter.o                                               \
        codec_desc.o                                                     \
-       dsputil.o                                                        \
-       faanidct.o                                                       \
        fmtconvert.o                                                     \
        imgconvert.o                                                     \
-       jrevdct.o                                                        \
        log2_tab.o                                                       \
        mathtables.o                                                     \
        options.o                                                        \
        parser.o                                                         \
        raw.o                                                            \
-       resample.o                                                       \
-       resample2.o                                                      \
-       simple_idct.o                                                    \
        utils.o                                                          \
 
 # parts needed for many different codecs
@@ -38,16 +30,21 @@ OBJS-$(CONFIG_AANDCTTABLES)            += aandcttab.o
 OBJS-$(CONFIG_AC3DSP)                  += ac3dsp.o
 OBJS-$(CONFIG_AUDIO_FRAME_QUEUE)       += audio_frame_queue.o
 OBJS-$(CONFIG_DCT)                     += dct.o dct32_fixed.o dct32_float.o
-OBJS-$(CONFIG_DWT)                     += dwt.o
 OBJS-$(CONFIG_DXVA2)                   += dxva2.o
+OBJS-$(CONFIG_DSPUTIL)                 += dsputil.o faanidct.o          \
+                                          simple_idct.o jrevdct.o
 OBJS-$(CONFIG_ENCODERS)                += faandct.o jfdctfst.o jfdctint.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)        += error_resilience.o
 FFT-OBJS-$(CONFIG_HARDCODED_TABLES)    += cos_tables.o cos_fixed_tables.o
 OBJS-$(CONFIG_FFT)                     += avfft.o fft_fixed.o fft_float.o \
                                           $(FFT-OBJS-yes)
 OBJS-$(CONFIG_GOLOMB)                  += golomb.o
+OBJS-$(CONFIG_H263DSP)                 += h263dsp.o
+OBJS-$(CONFIG_H264CHROMA)              += h264chroma.o
 OBJS-$(CONFIG_H264DSP)                 += h264dsp.o h264idct.o
 OBJS-$(CONFIG_H264PRED)                += h264pred.o
+OBJS-$(CONFIG_H264QPEL)                += h264qpel.o
+OBJS-$(CONFIG_HPELDSP)                 += hpeldsp.o
 OBJS-$(CONFIG_HUFFMAN)                 += huffman.o
 OBJS-$(CONFIG_LIBXVID)                 += libxvid_rc.o
 OBJS-$(CONFIG_LPC)                     += lpc.o
@@ -71,7 +68,7 @@ OBJS-$(CONFIG_VDPAU)                   += vdpau.o
 OBJS-$(CONFIG_VIDEODSP)                += videodsp.o
 OBJS-$(CONFIG_VP3DSP)                  += vp3dsp.o
 
-# decoders/encoders/hardware accelerators
+# decoders/encoders
 OBJS-$(CONFIG_A64MULTI_ENCODER)        += a64multienc.o elbg.o
 OBJS-$(CONFIG_A64MULTI5_ENCODER)       += a64multienc.o elbg.o
 OBJS-$(CONFIG_AAC_DECODER)             += aacdec.o aactab.o aacsbr.o aacps.o \
@@ -86,6 +83,7 @@ OBJS-$(CONFIG_AC3_DECODER)             += ac3dec.o ac3dec_data.o ac3.o kbdwin.o
 OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc_float.o ac3enc.o ac3tab.o \
                                           ac3.o kbdwin.o
 OBJS-$(CONFIG_AC3_FIXED_ENCODER)       += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o
+OBJS-$(CONFIG_AIC_DECODER)             += aic.o
 OBJS-$(CONFIG_ALAC_DECODER)            += alac.o alac_data.o
 OBJS-$(CONFIG_ALAC_ENCODER)            += alacenc.o alac_data.o
 OBJS-$(CONFIG_ALS_DECODER)             += alsdec.o bgmc.o mpeg4audio.o
@@ -136,7 +134,7 @@ OBJS-$(CONFIG_COMFORTNOISE_ENCODER)    += cngenc.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
+                                          synth_filter.o
 OBJS-$(CONFIG_DFA_DECODER)             += dfa.o
 OBJS-$(CONFIG_DNXHD_DECODER)           += dnxhddec.o dnxhddata.o
 OBJS-$(CONFIG_DNXHD_ENCODER)           += dnxhdenc.o dnxhddata.o
@@ -149,7 +147,7 @@ OBJS-$(CONFIG_DVBSUB_ENCODER)          += dvbsub.o
 OBJS-$(CONFIG_DVDSUB_DECODER)          += dvdsubdec.o
 OBJS-$(CONFIG_DVDSUB_ENCODER)          += dvdsubenc.o
 OBJS-$(CONFIG_DVVIDEO_DECODER)         += dvdec.o dv.o dvdata.o dv_profile.o
-OBJS-$(CONFIG_DVVIDEO_ENCODER)         += dv.o dvdata.o dv_profile.o
+OBJS-$(CONFIG_DVVIDEO_ENCODER)         += dvenc.o dv.o dvdata.o dv_profile.o
 OBJS-$(CONFIG_DXA_DECODER)             += dxa.o
 OBJS-$(CONFIG_DXTORY_DECODER)          += dxtory.o
 OBJS-$(CONFIG_EAC3_DECODER)            += eac3dec.o eac3_data.o
@@ -159,12 +157,13 @@ OBJS-$(CONFIG_EAMAD_DECODER)           += eamad.o eaidct.o mpeg12.o \
                                           mpeg12data.o
 OBJS-$(CONFIG_EATGQ_DECODER)           += eatgq.o eaidct.o
 OBJS-$(CONFIG_EATGV_DECODER)           += eatgv.o
-OBJS-$(CONFIG_EATQI_DECODER)           += eatqi.o eaidct.o mpeg12.o \
-                                          mpeg12data.o
+OBJS-$(CONFIG_EATQI_DECODER)           += eatqi.o eaidct.o mpeg12dec.o  \
+                                          mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_EIGHTBPS_DECODER)        += 8bps.o
 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_FFV1_DECODER)            += ffv1dec.o ffv1.o
 OBJS-$(CONFIG_FFV1_ENCODER)            += ffv1enc.o ffv1.o
 OBJS-$(CONFIG_FFVHUFF_DECODER)         += huffyuv.o huffyuvdec.o
@@ -178,27 +177,28 @@ OBJS-$(CONFIG_FLIC_DECODER)            += flicvideo.o
 OBJS-$(CONFIG_FOURXM_DECODER)          += 4xm.o
 OBJS-$(CONFIG_FRAPS_DECODER)           += fraps.o
 OBJS-$(CONFIG_FRWU_DECODER)            += frwu.o
+OBJS-$(CONFIG_G2M_DECODER)             += g2meet.o mjpeg.o
 OBJS-$(CONFIG_G723_1_DECODER)          += g723_1.o acelp_vectors.o \
                                           celp_filters.o
 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 h261data.o h261.o
+OBJS-$(CONFIG_H261_ENCODER)            += h261enc.o h261data.o h261.o
 OBJS-$(CONFIG_H263_DECODER)            += h263dec.o h263.o ituh263dec.o        \
                                           mpeg4video.o mpeg4videodec.o flvdec.o\
                                           intelh263dec.o
-OBJS-$(CONFIG_H263_VAAPI_HWACCEL)      += vaapi_mpeg4.o
 OBJS-$(CONFIG_H263_ENCODER)            += mpeg4videoenc.o mpeg4video.o  \
                                           h263.o ituh263enc.o flvenc.o
 OBJS-$(CONFIG_H264_DECODER)            += h264.o                               \
                                           h264_loopfilter.o h264_direct.o      \
                                           cabac.o h264_sei.o h264_ps.o         \
                                           h264_refs.o h264_cavlc.o h264_cabac.o
-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_HEVC_DECODER)            += hevc.o hevc_mvs.o hevc_ps.o hevc_sei.o \
+                                          hevc_cabac.o hevc_refs.o hevcpred.o    \
+                                          hevcdsp.o hevc_filter.o cabac.o
+OBJS-$(CONFIG_HNM4_VIDEO_DECODER)      += hnm4video.o
 OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o huffyuvdec.o
 OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o huffyuvenc.o
 OBJS-$(CONFIG_IAC_DECODER)             += imc.o
@@ -212,6 +212,8 @@ OBJS-$(CONFIG_INDEO4_DECODER)          += indeo4.o ivi_common.o ivi_dsp.o
 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_JPEG2000_DECODER)        += jpeg2000dec.o jpeg2000.o      \
+                                          jpeg2000dwt.o mqcdec.o mqc.o
 OBJS-$(CONFIG_JPEGLS_DECODER)          += jpeglsdec.o jpegls.o \
                                           mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_JPEGLS_ENCODER)          += jpeglsenc.o jpegls.o
@@ -224,6 +226,8 @@ OBJS-$(CONFIG_LOCO_DECODER)            += loco.o
 OBJS-$(CONFIG_MACE3_DECODER)           += mace.o
 OBJS-$(CONFIG_MACE6_DECODER)           += mace.o
 OBJS-$(CONFIG_MDEC_DECODER)            += mdec.o mpeg12.o mpeg12data.o
+OBJS-$(CONFIG_METASOUND_DECODER)       += metasound.o metasound_data.o \
+                                          twinvq.o
 OBJS-$(CONFIG_MIMIC_DECODER)           += mimic.o
 OBJS-$(CONFIG_MJPEG_DECODER)           += mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_MJPEG_ENCODER)           += mjpegenc.o mjpeg.o
@@ -231,39 +235,36 @@ OBJS-$(CONFIG_MJPEGB_DECODER)          += mjpegbdec.o mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_MLP_DECODER)             += mlpdec.o mlpdsp.o
 OBJS-$(CONFIG_MMVIDEO_DECODER)         += mmvideo.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)    += motionpixels.o
-OBJS-$(CONFIG_MP1_DECODER)             += mpegaudiodec.o
+OBJS-$(CONFIG_MP1_DECODER)             += mpegaudiodec_fixed.o
 OBJS-$(CONFIG_MP1FLOAT_DECODER)        += mpegaudiodec_float.o
-OBJS-$(CONFIG_MP2_DECODER)             += mpegaudiodec.o
+OBJS-$(CONFIG_MP2_DECODER)             += mpegaudiodec_fixed.o
 OBJS-$(CONFIG_MP2_ENCODER)             += mpegaudioenc.o mpegaudio.o \
                                           mpegaudiodata.o mpegaudiodsp_data.o
 OBJS-$(CONFIG_MP2FLOAT_DECODER)        += mpegaudiodec_float.o
-OBJS-$(CONFIG_MP3_DECODER)             += mpegaudiodec.o
-OBJS-$(CONFIG_MP3ADU_DECODER)          += mpegaudiodec.o
+OBJS-$(CONFIG_MP3_DECODER)             += mpegaudiodec_fixed.o
+OBJS-$(CONFIG_MP3ADU_DECODER)          += mpegaudiodec_fixed.o
 OBJS-$(CONFIG_MP3ADUFLOAT_DECODER)     += mpegaudiodec_float.o
 OBJS-$(CONFIG_MP3FLOAT_DECODER)        += mpegaudiodec_float.o
-OBJS-$(CONFIG_MP3ON4_DECODER)          += mpegaudiodec.o mpeg4audio.o
+OBJS-$(CONFIG_MP3ON4_DECODER)          += mpegaudiodec_fixed.o mpeg4audio.o
 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_MPEG_XVMC_DECODER)       += mpegvideo_xvmc.o
-OBJS-$(CONFIG_MPEG1VIDEO_DECODER)      += mpeg12.o mpeg12data.o
+OBJS-$(CONFIG_MPEG1VIDEO_DECODER)      += mpeg12dec.o mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_MPEG1VIDEO_ENCODER)      += mpeg12enc.o mpeg12.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_DECODER)      += mpeg12dec.o mpeg12.o mpeg12data.o
 OBJS-$(CONFIG_MPEG2VIDEO_ENCODER)      += mpeg12enc.o mpeg12.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 \
-                                          h263.o ituh263dec.o mpeg4videodec.o
+OBJS-$(CONFIG_MSMPEG4V1_DECODER)       += msmpeg4dec.o msmpeg4.o msmpeg4data.o
+OBJS-$(CONFIG_MSMPEG4V2_DECODER)       += msmpeg4dec.o msmpeg4.o msmpeg4data.o \
+                                          h263dec.o h263.o ituh263dec.o \
+                                          mpeg4videodec.o
 OBJS-$(CONFIG_MSMPEG4V2_ENCODER)       += msmpeg4.o msmpeg4enc.o msmpeg4data.o \
-                                          h263dec.o h263.o ituh263dec.o        \
+                                          h263.o
+OBJS-$(CONFIG_MSMPEG4V3_DECODER)       += msmpeg4dec.o msmpeg4.o msmpeg4data.o \
+                                          h263dec.o h263.o ituh263dec.o \
                                           mpeg4videodec.o
-OBJS-$(CONFIG_MSMPEG4V3_DECODER)       += msmpeg4.o msmpeg4data.o h263dec.o \
-                                          h263.o ituh263dec.o mpeg4videodec.o
 OBJS-$(CONFIG_MSMPEG4V3_ENCODER)       += msmpeg4.o msmpeg4enc.o msmpeg4data.o \
-                                          h263dec.o h263.o ituh263dec.o        \
-                                          mpeg4videodec.o
+                                          h263.o
 OBJS-$(CONFIG_MSRLE_DECODER)           += msrle.o msrledec.o
 OBJS-$(CONFIG_MSA1_DECODER)            += mss3.o mss34dsp.o
 OBJS-$(CONFIG_MSS1_DECODER)            += mss1.o mss12.o
@@ -276,21 +277,21 @@ OBJS-$(CONFIG_NELLYMOSER_DECODER)      += nellymoserdec.o nellymoser.o
 OBJS-$(CONFIG_NELLYMOSER_ENCODER)      += nellymoserenc.o nellymoser.o
 OBJS-$(CONFIG_NUV_DECODER)             += nuv.o rtjpeg.o
 OBJS-$(CONFIG_PAM_DECODER)             += pnmdec.o pnm.o
-OBJS-$(CONFIG_PAM_ENCODER)             += pamenc.o pnm.o
+OBJS-$(CONFIG_PAM_ENCODER)             += pamenc.o
 OBJS-$(CONFIG_PBM_DECODER)             += pnmdec.o pnm.o
-OBJS-$(CONFIG_PBM_ENCODER)             += pnmenc.o pnm.o
+OBJS-$(CONFIG_PBM_ENCODER)             += pnmenc.o
 OBJS-$(CONFIG_PCX_DECODER)             += pcx.o
 OBJS-$(CONFIG_PCX_ENCODER)             += pcxenc.o
 OBJS-$(CONFIG_PGM_DECODER)             += pnmdec.o pnm.o
-OBJS-$(CONFIG_PGM_ENCODER)             += pnmenc.o pnm.o
+OBJS-$(CONFIG_PGM_ENCODER)             += pnmenc.o
 OBJS-$(CONFIG_PGMYUV_DECODER)          += pnmdec.o pnm.o
-OBJS-$(CONFIG_PGMYUV_ENCODER)          += pnmenc.o pnm.o
+OBJS-$(CONFIG_PGMYUV_ENCODER)          += pnmenc.o
 OBJS-$(CONFIG_PGSSUB_DECODER)          += pgssubdec.o
 OBJS-$(CONFIG_PICTOR_DECODER)          += pictordec.o cga_data.o
 OBJS-$(CONFIG_PNG_DECODER)             += png.o pngdec.o pngdsp.o
 OBJS-$(CONFIG_PNG_ENCODER)             += png.o pngenc.o
 OBJS-$(CONFIG_PPM_DECODER)             += pnmdec.o pnm.o
-OBJS-$(CONFIG_PPM_ENCODER)             += pnmenc.o pnm.o
+OBJS-$(CONFIG_PPM_ENCODER)             += pnmenc.o
 OBJS-$(CONFIG_PRORES_DECODER)          += proresdec.o proresdata.o proresdsp.o
 OBJS-$(CONFIG_PRORES_ENCODER)          += proresenc.o proresdata.o proresdsp.o
 OBJS-$(CONFIG_PTX_DECODER)             += ptx.o
@@ -333,9 +334,6 @@ OBJS-$(CONFIG_SIPR_DECODER)            += sipr.o acelp_pitch_delay.o \
 OBJS-$(CONFIG_SMACKAUD_DECODER)        += smacker.o
 OBJS-$(CONFIG_SMACKER_DECODER)         += smacker.o
 OBJS-$(CONFIG_SMC_DECODER)             += smc.o
-OBJS-$(CONFIG_SNOW_DECODER)            += snowdec.o snow.o
-OBJS-$(CONFIG_SNOW_ENCODER)            += snowenc.o snow.o              \
-                                          h263.o ituh263enc.o
 OBJS-$(CONFIG_SOL_DPCM_DECODER)        += dpcm.o
 OBJS-$(CONFIG_SP5X_DECODER)            += sp5xdec.o mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_SRT_DECODER)             += srtdec.o ass.o
@@ -363,7 +361,7 @@ OBJS-$(CONFIG_TRUESPEECH_DECODER)      += truespeech.o
 OBJS-$(CONFIG_TSCC_DECODER)            += tscc.o msrledec.o
 OBJS-$(CONFIG_TSCC2_DECODER)           += tscc2.o
 OBJS-$(CONFIG_TTA_DECODER)             += tta.o
-OBJS-$(CONFIG_TWINVQ_DECODER)          += twinvq.o
+OBJS-$(CONFIG_TWINVQ_DECODER)          += twinvqdec.o twinvq.o
 OBJS-$(CONFIG_TXD_DECODER)             += txd.o s3tc.o
 OBJS-$(CONFIG_ULTI_DECODER)            += ulti.o
 OBJS-$(CONFIG_UTVIDEO_DECODER)         += utvideodec.o utvideo.o
@@ -376,16 +374,13 @@ OBJS-$(CONFIG_V210X_DECODER)           += v210x.o
 OBJS-$(CONFIG_VB_DECODER)              += vb.o
 OBJS-$(CONFIG_VBLE_DECODER)            += vble.o
 OBJS-$(CONFIG_VC1_DECODER)             += vc1dec.o vc1.o vc1data.o vc1dsp.o \
-                                          msmpeg4.o msmpeg4data.o           \
+                                          msmpeg4dec.o msmpeg4.o msmpeg4data.o \
                                           intrax8.o intrax8dsp.o
-OBJS-$(CONFIG_VC1_DXVA2_HWACCEL)       += dxva2_vc1.o
-OBJS-$(CONFIG_VC1_VAAPI_HWACCEL)       += vaapi_vc1.o
 OBJS-$(CONFIG_VCR1_DECODER)            += vcr1.o
-OBJS-$(CONFIG_VCR1_ENCODER)            += vcr1.o
 OBJS-$(CONFIG_VMDAUDIO_DECODER)        += vmdav.o
 OBJS-$(CONFIG_VMDVIDEO_DECODER)        += vmdav.o
 OBJS-$(CONFIG_VMNC_DECODER)            += vmnc.o
-OBJS-$(CONFIG_VORBIS_DECODER)          += vorbisdec.o vorbis.o \
+OBJS-$(CONFIG_VORBIS_DECODER)          += vorbisdec.o vorbisdsp.o vorbis.o \
                                           vorbis_data.o xiph.o
 OBJS-$(CONFIG_VORBIS_ENCODER)          += vorbisenc.o vorbis.o \
                                           vorbis_data.o
@@ -395,8 +390,11 @@ OBJS-$(CONFIG_VP5_DECODER)             += vp5.o vp56.o vp56data.o vp56dsp.o \
 OBJS-$(CONFIG_VP6_DECODER)             += vp6.o vp56.o vp56data.o vp56dsp.o \
                                           vp6dsp.o vp56rac.o
 OBJS-$(CONFIG_VP8_DECODER)             += vp8.o vp8dsp.o vp56rac.o
+OBJS-$(CONFIG_VP9_DECODER)             += vp9.o vp9data.o vp9dsp.o \
+                                          vp9block.o vp9prob.o vp9mvs.o vp56rac.o
 OBJS-$(CONFIG_VQA_DECODER)             += vqavideo.o
 OBJS-$(CONFIG_WAVPACK_DECODER)         += wavpack.o
+OBJS-$(CONFIG_WEBP_DECODER)            += webp.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
@@ -406,13 +404,12 @@ OBJS-$(CONFIG_WMAV2_ENCODER)           += wmaenc.o wma.o wma_common.o aactab.o
 OBJS-$(CONFIG_WMAVOICE_DECODER)        += wmavoice.o \
                                           celp_filters.o \
                                           acelp_vectors.o acelp_filters.o
-OBJS-$(CONFIG_WMV1_DECODER)            += msmpeg4.o msmpeg4data.o
-OBJS-$(CONFIG_WMV2_DECODER)            += wmv2dec.o wmv2.o        \
-                                          msmpeg4.o msmpeg4data.o \
+OBJS-$(CONFIG_WMV1_DECODER)            += msmpeg4dec.o msmpeg4.o msmpeg4data.o
+OBJS-$(CONFIG_WMV2_DECODER)            += wmv2dec.o wmv2.o wmv2dsp.o \
+                                          msmpeg4dec.o msmpeg4.o msmpeg4data.o \
                                           intrax8.o intrax8dsp.o
-OBJS-$(CONFIG_WMV2_ENCODER)            += wmv2enc.o wmv2.o \
-                                          msmpeg4.o msmpeg4enc.o msmpeg4data.o \
-                                          mpeg4videodec.o ituh263dec.o h263dec.o
+OBJS-$(CONFIG_WMV2_ENCODER)            += wmv2enc.o wmv2.o wmv2dsp.o \
+                                          msmpeg4.o msmpeg4enc.o msmpeg4data.o
 OBJS-$(CONFIG_WNV1_DECODER)            += wnv1.o
 OBJS-$(CONFIG_WS_SND1_DECODER)         += ws-snd1.o
 OBJS-$(CONFIG_XAN_DPCM_DECODER)        += dpcm.o
@@ -434,8 +431,8 @@ OBJS-$(CONFIG_ZMBV_ENCODER)            += zmbvenc.o
 # (AD)PCM decoders/encoders
 OBJS-$(CONFIG_PCM_ALAW_DECODER)           += pcm.o
 OBJS-$(CONFIG_PCM_ALAW_ENCODER)           += pcm.o
-OBJS-$(CONFIG_PCM_BLURAY_DECODER)         += pcm-mpeg.o
-OBJS-$(CONFIG_PCM_DVD_DECODER)            += pcm.o
+OBJS-$(CONFIG_PCM_BLURAY_DECODER)         += pcm-bluray.o
+OBJS-$(CONFIG_PCM_DVD_DECODER)            += pcm-dvd.o
 OBJS-$(CONFIG_PCM_F32BE_DECODER)          += pcm.o
 OBJS-$(CONFIG_PCM_F32BE_ENCODER)          += pcm.o
 OBJS-$(CONFIG_PCM_F32LE_DECODER)          += pcm.o
@@ -461,10 +458,12 @@ OBJS-$(CONFIG_PCM_S24DAUD_DECODER)        += pcm.o
 OBJS-$(CONFIG_PCM_S24DAUD_ENCODER)        += pcm.o
 OBJS-$(CONFIG_PCM_S24LE_DECODER)          += pcm.o
 OBJS-$(CONFIG_PCM_S24LE_ENCODER)          += pcm.o
+OBJS-$(CONFIG_PCM_S24LE_PLANAR_DECODER)   += pcm.o
 OBJS-$(CONFIG_PCM_S32BE_DECODER)          += pcm.o
 OBJS-$(CONFIG_PCM_S32BE_ENCODER)          += pcm.o
 OBJS-$(CONFIG_PCM_S32LE_DECODER)          += pcm.o
 OBJS-$(CONFIG_PCM_S32LE_ENCODER)          += pcm.o
+OBJS-$(CONFIG_PCM_S32LE_PLANAR_DECODER)   += pcm.o
 OBJS-$(CONFIG_PCM_U8_DECODER)             += pcm.o
 OBJS-$(CONFIG_PCM_U8_ENCODER)             += pcm.o
 OBJS-$(CONFIG_PCM_U16BE_DECODER)          += pcm.o
@@ -520,6 +519,23 @@ 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
 
+# hardware accelerators
+OBJS-$(CONFIG_H263_VAAPI_HWACCEL)         += vaapi_mpeg4.o
+OBJS-$(CONFIG_H263_VDPAU_HWACCEL)         += vdpau_mpeg4.o
+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_VDPAU_HWACCEL)         += vdpau_h264.o
+OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL)        += vdpau_mpeg12.o
+OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL)        += dxva2_mpeg2.o
+OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL)        += vaapi_mpeg2.o
+OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL)        += vdpau_mpeg12.o
+OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL)        += vaapi_mpeg4.o
+OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL)        += vdpau_mpeg4.o
+OBJS-$(CONFIG_VC1_DXVA2_HWACCEL)          += dxva2_vc1.o
+OBJS-$(CONFIG_VC1_VAAPI_HWACCEL)          += vaapi_vc1.o
+OBJS-$(CONFIG_VC1_VDPAU_HWACCEL)          += vdpau_vc1.o
+
 # libavformat dependencies
 OBJS-$(CONFIG_ADTS_MUXER)              += mpeg4audio.o
 OBJS-$(CONFIG_ADX_DEMUXER)             += adx.o
@@ -562,6 +578,7 @@ OBJS-$(CONFIG_WTV_DEMUXER)             += mpeg4audio.o mpegaudiodata.o
 
 # external codec libraries
 OBJS-$(CONFIG_LIBFAAC_ENCODER)            += libfaac.o
+OBJS-$(CONFIG_LIBFDK_AAC_DECODER)         += libfdk-aacdec.o
 OBJS-$(CONFIG_LIBFDK_AAC_ENCODER)         += libfdk-aacenc.o
 OBJS-$(CONFIG_LIBGSM_DECODER)             += libgsm.o
 OBJS-$(CONFIG_LIBGSM_ENCODER)             += libgsm.o
@@ -590,8 +607,11 @@ OBJS-$(CONFIG_LIBVO_AACENC_ENCODER)       += libvo-aacenc.o mpeg4audio.o
 OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER)     += libvo-amrwbenc.o
 OBJS-$(CONFIG_LIBVORBIS_ENCODER)          += libvorbis.o \
                                              vorbis_data.o vorbis_parser.o
-OBJS-$(CONFIG_LIBVPX_DECODER)             += libvpxdec.o
-OBJS-$(CONFIG_LIBVPX_ENCODER)             += libvpxenc.o
+OBJS-$(CONFIG_LIBVPX_VP8_DECODER)         += libvpxdec.o
+OBJS-$(CONFIG_LIBVPX_VP8_ENCODER)         += libvpxenc.o
+OBJS-$(CONFIG_LIBVPX_VP9_DECODER)         += libvpxdec.o libvpx.o
+OBJS-$(CONFIG_LIBVPX_VP9_ENCODER)         += libvpxenc.o libvpx.o
+OBJS-$(CONFIG_LIBWAVPACK_ENCODER)         += libwavpackenc.o
 OBJS-$(CONFIG_LIBX264_ENCODER)            += libx264.o
 OBJS-$(CONFIG_LIBXAVS_ENCODER)            += libxavs.o
 OBJS-$(CONFIG_LIBXVID_ENCODER)            += libxvid.o
@@ -619,6 +639,7 @@ OBJS-$(CONFIG_H264_PARSER)             += h264_parser.o h264.o            \
                                           h264_refs.o h264_sei.o h264_direct.o \
                                           h264_loopfilter.o h264_cabac.o \
                                           h264_cavlc.o h264_ps.o
+OBJS-$(CONFIG_HEVC_PARSER)             += hevc_parser.o
 OBJS-$(CONFIG_MJPEG_PARSER)            += mjpeg_parser.o
 OBJS-$(CONFIG_MLP_PARSER)              += mlp_parser.o mlp.o
 OBJS-$(CONFIG_MPEG4VIDEO_PARSER)       += mpeg4video_parser.o h263.o \
@@ -628,6 +649,7 @@ OBJS-$(CONFIG_MPEGAUDIO_PARSER)        += mpegaudio_parser.o \
                                           mpegaudiodecheader.o mpegaudiodata.o
 OBJS-$(CONFIG_MPEGVIDEO_PARSER)        += mpegvideo_parser.o    \
                                           mpeg12.o mpeg12data.o
+OBJS-$(CONFIG_PNG_PARSER)              += png_parser.o
 OBJS-$(CONFIG_PNM_PARSER)              += pnm_parser.o pnm.o
 OBJS-$(CONFIG_RV30_PARSER)             += rv34_parser.o
 OBJS-$(CONFIG_RV40_PARSER)             += rv34_parser.o
@@ -649,22 +671,18 @@ OBJS-$(CONFIG_IMX_DUMP_HEADER_BSF)        += imx_dump_header_bsf.o
 OBJS-$(CONFIG_MJPEG2JPEG_BSF)             += mjpeg2jpeg_bsf.o mjpeg.o
 OBJS-$(CONFIG_MJPEGA_DUMP_HEADER_BSF)     += mjpega_dump_header_bsf.o
 OBJS-$(CONFIG_MOV2TEXTSUB_BSF)            += movsub_bsf.o
-OBJS-$(CONFIG_MP3_HEADER_COMPRESS_BSF)    += mp3_header_compress_bsf.o
-OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF)  += mp3_header_decompress_bsf.o \
-                                             mpegaudiodata.o
 OBJS-$(CONFIG_NOISE_BSF)                  += noise_bsf.o
 OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF)       += remove_extradata_bsf.o
 OBJS-$(CONFIG_TEXT2MOVSUB_BSF)            += movsub_bsf.o
 
 # thread libraries
-OBJS-$(HAVE_PTHREADS)                  += pthread.o
-OBJS-$(HAVE_W32THREADS)                += pthread.o
+OBJS-$(HAVE_LIBC_MSVCRT)               += file_open.o
+OBJS-$(HAVE_THREADS)                   += pthread.o pthread_slice.o pthread_frame.o
 
 SKIPHEADERS                            += %_tablegen.h                  \
                                           %_tables.h                    \
                                           aac_tablegen_decl.h           \
                                           fft-internal.h                \
-                                          old_codec_ids.h               \
                                           tableprint.h                  \
                                           $(ARCH)/vp56_arith.h          \
 
@@ -673,8 +691,7 @@ SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.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_W32THREADS)         += w32pthreads.h
+SKIPHEADERS-$(CONFIG_VDPAU)            += vdpau.h vdpau_internal.h
 
 EXAMPLES = api
 
@@ -701,6 +718,7 @@ HOSTPROGS = aac_tablegen                                                \
 CLEANFILES = *_tables.c *_tables.h *_tablegen$(HOSTEXESUF)
 
 $(SUBDIR)dct-test$(EXESUF): $(SUBDIR)dctref.o $(SUBDIR)aandcttab.o
+$(SUBDIR)dv_tablegen$(HOSTEXESUF): $(SUBDIR)dvdata_host.o
 
 TRIG_TABLES  = cos cos_fixed sin
 TRIG_TABLES := $(TRIG_TABLES:%=$(SUBDIR)%_tables.c)
@@ -726,9 +744,9 @@ ifdef CONFIG_HARDCODED_TABLES
 $(SUBDIR)aacdec.o: $(SUBDIR)cbrt_tables.h
 $(SUBDIR)aacps.o: $(SUBDIR)aacps_tables.h
 $(SUBDIR)aactab.o: $(SUBDIR)aac_tables.h
-$(SUBDIR)dv.o: $(SUBDIR)dv_tables.h
+$(SUBDIR)dvenc.o: $(SUBDIR)dv_tables.h
 $(SUBDIR)sinewin.o: $(SUBDIR)sinewin_tables.h
-$(SUBDIR)mpegaudiodec.o: $(SUBDIR)mpegaudio_tables.h
+$(SUBDIR)mpegaudiodec_fixed.o: $(SUBDIR)mpegaudio_tables.h
 $(SUBDIR)mpegaudiodec_float.o: $(SUBDIR)mpegaudio_tables.h
 $(SUBDIR)motionpixels.o: $(SUBDIR)motionpixels_tables.h
 $(SUBDIR)pcm.o: $(SUBDIR)pcm_tables.h
diff --git a/libavcodec/a64enc.h b/libavcodec/a64enc.h
index d5f8e9a..65c1d30 100644
--- a/libavcodec/a64enc.h
+++ b/libavcodec/a64enc.h
@@ -34,9 +34,6 @@
 #define C64YRES 200
 
 typedef struct A64Context {
-    /* general variables */
-    AVFrame picture;
-
     /* variables for multicolor modes */
     AVLFG randctx;
     int mc_lifetime;
diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c
index beddf9f..11d6e2c 100644
--- a/libavcodec/a64multienc.c
+++ b/libavcodec/a64multienc.c
@@ -165,6 +165,7 @@ static void render_charset(AVCodecContext *avctx, uint8_t *charset,
 static av_cold int a64multi_close_encoder(AVCodecContext *avctx)
 {
     A64Context *c = avctx->priv_data;
+    av_frame_free(&avctx->coded_frame);
     av_free(c->mc_meta_charset);
     av_free(c->mc_best_cb);
     av_free(c->mc_charset);
@@ -216,8 +217,12 @@ static av_cold int a64multi_init_encoder(AVCodecContext *avctx)
     AV_WB32(avctx->extradata, c->mc_lifetime);
     AV_WB32(avctx->extradata + 16, INTERLACED);
 
-    avcodec_get_frame_defaults(&c->picture);
-    avctx->coded_frame            = &c->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame) {
+        a64multi_close_encoder(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     avctx->coded_frame->key_frame = 1;
     if (!avctx->codec_tag)
@@ -247,7 +252,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                  const AVFrame *pict, int *got_packet)
 {
     A64Context *c = avctx->priv_data;
-    AVFrame *const p = &c->picture;
+    AVFrame *const p = avctx->coded_frame;
 
     int frame;
     int x, y;
@@ -373,6 +378,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
 AVCodec ff_a64multi_encoder = {
     .name           = "a64multi",
+    .long_name      = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_A64_MULTI,
     .priv_data_size = sizeof(A64Context),
@@ -380,12 +386,12 @@ AVCodec ff_a64multi_encoder = {
     .encode2        = a64multi_encode_frame,
     .close          = a64multi_close_encoder,
     .pix_fmts       = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
-    .long_name      = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
     .capabilities   = CODEC_CAP_DELAY,
 };
 
 AVCodec ff_a64multi5_encoder = {
     .name           = "a64multi5",
+    .long_name      = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_A64_MULTI5,
     .priv_data_size = sizeof(A64Context),
@@ -393,6 +399,5 @@ AVCodec ff_a64multi5_encoder = {
     .encode2        = a64multi_encode_frame,
     .close          = a64multi_close_encoder,
     .pix_fmts       = (const enum AVPixelFormat[]) {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE},
-    .long_name      = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
     .capabilities   = CODEC_CAP_DELAY,
 };
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index 6c5d962..375e6b1 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -32,7 +32,6 @@
 
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "mpeg4audio.h"
 #include "sbr.h"
@@ -158,7 +157,7 @@ typedef struct LongTermPrediction {
 typedef struct IndividualChannelStream {
     uint8_t max_sfb;            ///< number of scalefactor bands per group
     enum WindowSequence window_sequence[2];
-    uint8_t use_kb_window[2];   ///< If set, use Kaiser-Bessel window, otherwise use a sinus window.
+    uint8_t use_kb_window[2];   ///< If set, use Kaiser-Bessel window, otherwise use a sine window.
     int num_window_groups;
     uint8_t group_len[8];
     LongTermPrediction ltp;
@@ -235,7 +234,7 @@ typedef struct SingleChannelElement {
     int sf_idx[128];                                ///< scalefactor indices (used by encoder)
     uint8_t zeroes[128];                            ///< band is not coded (used by encoder)
     DECLARE_ALIGNED(32, float,   coeffs)[1024];     ///< coefficients for IMDCT
-    DECLARE_ALIGNED(32, float,   saved)[1024];      ///< overlap
+    DECLARE_ALIGNED(32, float,   saved)[1536];      ///< overlap
     DECLARE_ALIGNED(32, float,   ret_buf)[2048];    ///< PCM output buffer
     DECLARE_ALIGNED(16, float,   ltp_state)[3072];  ///< time signal for LTP
     PredictorState predictor_state[MAX_PREDICTORS];
@@ -262,7 +261,7 @@ typedef struct ChannelElement {
  */
 typedef struct AACContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     int is_saved;                 ///< Set if elements have stored overlap from previous frame.
     DynamicRangeControl che_drc;
@@ -290,8 +289,8 @@ typedef struct AACContext {
      */
     FFTContext mdct;
     FFTContext mdct_small;
+    FFTContext mdct_ld;
     FFTContext mdct_ltp;
-    DSPContext dsp;
     FmtConvertContext fmt_conv;
     AVFloatDSPContext fdsp;
     int random_state;
diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c
index b17cd4d..d3da9b7 100644
--- a/libavcodec/aac_ac3_parser.c
+++ b/libavcodec/aac_ac3_parser.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "parser.h"
 #include "aac_ac3_parser.h"
@@ -82,14 +83,23 @@ get_next:
     if (avctx->codec_id != AV_CODEC_ID_AAC) {
         avctx->sample_rate = s->sample_rate;
 
-        /* allow downmixing to stereo (or mono for AC-3) */
-        if(avctx->request_channels > 0 &&
-                avctx->request_channels < s->channels &&
-                (avctx->request_channels <= 2 ||
-                (avctx->request_channels == 1 &&
-                (avctx->codec_id == AV_CODEC_ID_AC3 ||
-                 avctx->codec_id == AV_CODEC_ID_EAC3)))) {
-            avctx->channels = avctx->request_channels;
+        /* (E-)AC-3: allow downmixing to stereo or mono */
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+        if (avctx->request_channels == 1)
+            avctx->request_channel_layout = AV_CH_LAYOUT_MONO;
+        else if (avctx->request_channels == 2)
+            avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+        if (s->channels > 1 &&
+            avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
+            avctx->channels       = 1;
+            avctx->channel_layout = AV_CH_LAYOUT_MONO;
+        } else if (s->channels > 2 &&
+                   avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+            avctx->channels       = 2;
+            avctx->channel_layout = AV_CH_LAYOUT_STEREO;
         } else {
             avctx->channels = s->channels;
             avctx->channel_layout = s->channel_layout;
diff --git a/libavcodec/aac_adtstoasc_bsf.c b/libavcodec/aac_adtstoasc_bsf.c
index df9a395..bec6e7f 100644
--- a/libavcodec/aac_adtstoasc_bsf.c
+++ b/libavcodec/aac_adtstoasc_bsf.c
@@ -61,7 +61,8 @@ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,
     }
 
     if (!hdr.crc_absent && hdr.num_aac_frames > 1) {
-        av_log_missing_feature(avctx, "Multiple RDBs per frame with CRC", 0);
+        avpriv_report_missing_feature(avctx,
+                                      "Multiple RDBs per frame with CRC");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -74,7 +75,10 @@ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,
         if (!hdr.chan_config) {
             init_get_bits(&gb, buf, buf_size * 8);
             if (get_bits(&gb, 3) != 5) {
-                av_log_missing_feature(avctx, "PCE based channel configuration, where the PCE is not the first syntax element", 0);
+                avpriv_report_missing_feature(avctx,
+                                              "PCE-based channel configuration "
+                                              "without PCE as first syntax "
+                                              "element");
                 return AVERROR_PATCHWELCOME;
             }
             init_put_bits(&pb, pce_data, MAX_PCE_SIZE);
diff --git a/libavcodec/aac_tablegen.h b/libavcodec/aac_tablegen.h
index a45de9a..8a05ec5 100644
--- a/libavcodec/aac_tablegen.h
+++ b/libavcodec/aac_tablegen.h
@@ -35,7 +35,7 @@ void ff_aac_tableinit(void)
 {
     int i;
     for (i = 0; i < 428; i++)
-        ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.);
+        ff_aac_pow2sf_tab[i] = pow(2, (i - POW_SF2_ZERO) / 4.0);
 }
 #endif /* CONFIG_HARDCODED_TABLES */
 
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index d65d8d9..35b98a9 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -710,7 +710,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
                                           const float lambda)
 {
     int start = 0, i, w, w2, g;
-    int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels;
+    int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f);
     float dists[128] = { 0 }, uplims[128];
     float maxvals[128];
     int fflag, minscaler;
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 325bf63..426a652 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -2,6 +2,7 @@
  * AAC decoder
  * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
  * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2008-2013 Alex Converse <alex.converse at gmail.com>
  *
  * AAC LATM decoder
  * Copyright (c) 2008-2010 Paul Kendall <paul at kcbbs.gen.nz>
@@ -83,7 +84,6 @@
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "fmtconvert.h"
 #include "lpc.h"
@@ -103,6 +103,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <math.h>
+#include <stdint.h>
 #include <string.h>
 
 #if ARCH_ARM
@@ -182,8 +183,9 @@ static int frame_configure_elements(AVCodecContext *avctx)
     }
 
     /* get output buffer */
-    ac->frame.nb_samples = 2048;
-    if ((ret = ff_get_buffer(avctx, &ac->frame)) < 0) {
+    av_frame_unref(ac->frame);
+    ac->frame->nb_samples = 2048;
+    if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -191,7 +193,7 @@ static int frame_configure_elements(AVCodecContext *avctx)
     /* map output channel pointers to AVFrame data */
     for (ch = 0; ch < avctx->channels; ch++) {
         if (ac->output_element[ch])
-            ac->output_element[ch]->ret = (float *)ac->frame.extended_data[ch];
+            ac->output_element[ch]->ret = (float *)ac->frame->extended_data[ch];
     }
 
     return 0;
@@ -706,12 +708,12 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
                                      MPEG4AudioConfig *m4ac,
                                      int channel_config)
 {
-    int extension_flag, ret;
+    int extension_flag, ret, ep_config, res_flags;
     uint8_t layout_map[MAX_ELEM_ID*4][3];
     int tags = 0;
 
     if (get_bits1(gb)) { // frameLengthFlag
-        av_log_missing_feature(avctx, "960/120 MDCT window", 1);
+        avpriv_request_sample(avctx, "960/120 MDCT window");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -752,14 +754,90 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
         case AOT_ER_AAC_LTP:
         case AOT_ER_AAC_SCALABLE:
         case AOT_ER_AAC_LD:
-            skip_bits(gb, 3);      /* aacSectionDataResilienceFlag
-                                    * aacScalefactorDataResilienceFlag
-                                    * aacSpectralDataResilienceFlag
-                                    */
+            res_flags = get_bits(gb, 3);
+            if (res_flags) {
+                avpriv_report_missing_feature(avctx,
+                                              "AAC data resilience (flags %x)",
+                                              res_flags);
+                return AVERROR_PATCHWELCOME;
+            }
             break;
         }
         skip_bits1(gb);    // extensionFlag3 (TBD in version 3)
     }
+    switch (m4ac->object_type) {
+    case AOT_ER_AAC_LC:
+    case AOT_ER_AAC_LTP:
+    case AOT_ER_AAC_SCALABLE:
+    case AOT_ER_AAC_LD:
+        ep_config = get_bits(gb, 2);
+        if (ep_config) {
+            avpriv_report_missing_feature(avctx,
+                                          "epConfig %d", ep_config);
+            return AVERROR_PATCHWELCOME;
+        }
+    }
+    return 0;
+}
+
+static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
+                                     GetBitContext *gb,
+                                     MPEG4AudioConfig *m4ac,
+                                     int channel_config)
+{
+    int ret, ep_config, res_flags;
+    uint8_t layout_map[MAX_ELEM_ID*4][3];
+    int tags = 0;
+    const int ELDEXT_TERM = 0;
+
+    m4ac->ps  = 0;
+    m4ac->sbr = 0;
+
+    if (get_bits1(gb)) { // frameLengthFlag
+        avpriv_request_sample(avctx, "960/120 MDCT window");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    res_flags = get_bits(gb, 3);
+    if (res_flags) {
+        avpriv_report_missing_feature(avctx,
+                                      "AAC data resilience (flags %x)",
+                                      res_flags);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (get_bits1(gb)) { // ldSbrPresentFlag
+        avpriv_report_missing_feature(avctx,
+                                      "Low Delay SBR");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    while (get_bits(gb, 4) != ELDEXT_TERM) {
+        int len = get_bits(gb, 4);
+        if (len == 15)
+            len += get_bits(gb, 8);
+        if (len == 15 + 255)
+            len += get_bits(gb, 16);
+        if (get_bits_left(gb) < len * 8 + 4) {
+            av_log(ac->avctx, AV_LOG_ERROR, overread_err);
+            return AVERROR_INVALIDDATA;
+        }
+        skip_bits_long(gb, 8 * len);
+    }
+
+    if ((ret = set_default_channel_config(avctx, layout_map,
+                                          &tags, channel_config)))
+        return ret;
+
+    if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0)))
+        return ret;
+
+    ep_config = get_bits(gb, 2);
+    if (ep_config) {
+        avpriv_report_missing_feature(avctx,
+                                      "epConfig %d", ep_config);
+        return AVERROR_PATCHWELCOME;
+    }
     return 0;
 }
 
@@ -801,6 +879,13 @@ static int decode_audio_specific_config(AACContext *ac,
                m4ac->sampling_index);
         return AVERROR_INVALIDDATA;
     }
+    if (m4ac->object_type == AOT_ER_AAC_LD &&
+        (m4ac->sampling_index < 3 || m4ac->sampling_index > 7)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "invalid low delay sampling rate index %d\n",
+               m4ac->sampling_index);
+        return AVERROR_INVALIDDATA;
+    }
 
     skip_bits_long(&gb, i);
 
@@ -808,15 +893,22 @@ static int decode_audio_specific_config(AACContext *ac,
     case AOT_AAC_MAIN:
     case AOT_AAC_LC:
     case AOT_AAC_LTP:
+    case AOT_ER_AAC_LC:
+    case AOT_ER_AAC_LD:
         if ((ret = decode_ga_specific_config(ac, avctx, &gb,
                                             m4ac, m4ac->chan_config)) < 0)
             return ret;
         break;
+    case AOT_ER_AAC_ELD:
+        if ((ret = decode_eld_specific_config(ac, avctx, &gb,
+                                              m4ac, m4ac->chan_config)) < 0)
+            return ret;
+        break;
     default:
-        av_log(avctx, AV_LOG_ERROR,
-               "Audio object type %s%d is not supported.\n",
-               m4ac->sbr == 1 ? "SBR+" : "",
-               m4ac->object_type);
+        avpriv_report_missing_feature(avctx,
+                                      "Audio object type %s%d",
+                                      m4ac->sbr == 1 ? "SBR+" : "",
+                                      m4ac->object_type);
         return AVERROR(ENOSYS);
     }
 
@@ -950,7 +1042,6 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
 
     ff_aac_sbr_init();
 
-    ff_dsputil_init(&ac->dsp, avctx);
     ff_fmt_convert_init(&ac->fmt_conv, avctx);
     avpriv_float_dsp_init(&ac->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
@@ -969,19 +1060,19 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
                     352);
 
     ff_mdct_init(&ac->mdct,       11, 1, 1.0 / (32768.0 * 1024.0));
+    ff_mdct_init(&ac->mdct_ld,    10, 1, 1.0 / (32768.0 * 512.0));
     ff_mdct_init(&ac->mdct_small,  8, 1, 1.0 / (32768.0 * 128.0));
     ff_mdct_init(&ac->mdct_ltp,   11, 0, -2.0 * 32768.0);
     // window initialization
     ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
+    ff_kbd_window_init(ff_aac_kbd_long_512,  4.0, 512);
     ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
     ff_init_ff_sine_windows(10);
+    ff_init_ff_sine_windows( 9);
     ff_init_ff_sine_windows( 7);
 
     cbrt_tableinit();
 
-    avcodec_get_frame_defaults(&ac->frame);
-    avctx->coded_frame = &ac->frame;
-
     return 0;
 }
 
@@ -1044,14 +1135,25 @@ static void decode_ltp(LongTermPrediction *ltp,
 static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
                            GetBitContext *gb)
 {
-    if (get_bits1(gb)) {
-        av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
-        return AVERROR_INVALIDDATA;
+    int aot = ac->oc[1].m4ac.object_type;
+    if (aot != AOT_ER_AAC_ELD) {
+        if (get_bits1(gb)) {
+            av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
+            return AVERROR_INVALIDDATA;
+        }
+        ics->window_sequence[1] = ics->window_sequence[0];
+        ics->window_sequence[0] = get_bits(gb, 2);
+        if (aot == AOT_ER_AAC_LD &&
+            ics->window_sequence[0] != ONLY_LONG_SEQUENCE) {
+            av_log(ac->avctx, AV_LOG_ERROR,
+                   "AAC LD is only defined for ONLY_LONG_SEQUENCE but "
+                   "window sequence %d found.\n", ics->window_sequence[0]);
+            ics->window_sequence[0] = ONLY_LONG_SEQUENCE;
+            return AVERROR_INVALIDDATA;
+        }
+        ics->use_kb_window[1]   = ics->use_kb_window[0];
+        ics->use_kb_window[0]   = get_bits1(gb);
     }
-    ics->window_sequence[1] = ics->window_sequence[0];
-    ics->window_sequence[0] = get_bits(gb, 2);
-    ics->use_kb_window[1]   = ics->use_kb_window[0];
-    ics->use_kb_window[0]   = get_bits1(gb);
     ics->num_window_groups  = 1;
     ics->group_len[0]       = 1;
     if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
@@ -1073,21 +1175,36 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
     } else {
         ics->max_sfb               = get_bits(gb, 6);
         ics->num_windows           = 1;
-        ics->swb_offset            =    ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index];
-        ics->num_swb               =   ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index];
+        if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
+            ics->swb_offset        =     ff_swb_offset_512[ac->oc[1].m4ac.sampling_index];
+            ics->num_swb           =    ff_aac_num_swb_512[ac->oc[1].m4ac.sampling_index];
+            if (!ics->num_swb || !ics->swb_offset)
+                return AVERROR_BUG;
+        } else {
+            ics->swb_offset        =    ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index];
+            ics->num_swb           =   ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index];
+        }
         ics->tns_max_bands         = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index];
-        ics->predictor_present     = get_bits1(gb);
-        ics->predictor_reset_group = 0;
+        if (aot != AOT_ER_AAC_ELD) {
+            ics->predictor_present     = get_bits1(gb);
+            ics->predictor_reset_group = 0;
+        }
         if (ics->predictor_present) {
-            if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) {
+            if (aot == AOT_AAC_MAIN) {
                 if (decode_prediction(ac, ics, gb)) {
                     return AVERROR_INVALIDDATA;
                 }
-            } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC) {
+            } else if (aot == AOT_AAC_LC ||
+                       aot == AOT_ER_AAC_LC) {
                 av_log(ac->avctx, AV_LOG_ERROR,
                        "Prediction is not allowed in AAC-LC.\n");
                 return AVERROR_INVALIDDATA;
             } else {
+                if (aot == AOT_ER_AAC_LD) {
+                    av_log(ac->avctx, AV_LOG_ERROR,
+                           "LTP in ER AAC LD not yet implemented.\n");
+                    return AVERROR_PATCHWELCOME;
+                }
                 if ((ics->ltp.present = get_bits(gb, 1)))
                     decode_ltp(&ics->ltp, gb, ics->max_sfb);
             }
@@ -1177,17 +1294,17 @@ static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb,
             int run_end = band_type_run_end[idx];
             if (band_type[idx] == ZERO_BT) {
                 for (; i < run_end; i++, idx++)
-                    sf[idx] = 0.;
+                    sf[idx] = 0.0;
             } else if ((band_type[idx] == INTENSITY_BT) ||
                        (band_type[idx] == INTENSITY_BT2)) {
                 for (; i < run_end; i++, idx++) {
                     offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
                     clipped_offset = av_clip(offset[2], -155, 100);
                     if (offset[2] != clipped_offset) {
-                        av_log_ask_for_sample(ac->avctx, "Intensity stereo "
-                                "position clipped (%d -> %d).\nIf you heard an "
-                                "audible artifact, there may be a bug in the "
-                                "decoder. ", offset[2], clipped_offset);
+                        avpriv_request_sample(ac->avctx,
+                                              "If you heard an audible artifact, there may be a bug in the decoder. "
+                                              "Clipped intensity stereo position (%d -> %d)",
+                                              offset[2], clipped_offset);
                     }
                     sf[idx] = ff_aac_pow2sf_tab[-clipped_offset + POW_SF2_ZERO];
                 }
@@ -1199,10 +1316,10 @@ static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb,
                         offset[1] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
                     clipped_offset = av_clip(offset[1], -100, 155);
                     if (offset[1] != clipped_offset) {
-                        av_log_ask_for_sample(ac->avctx, "Noise gain clipped "
-                                "(%d -> %d).\nIf you heard an audible "
-                                "artifact, there may be a bug in the decoder. ",
-                                offset[1], clipped_offset);
+                        avpriv_request_sample(ac->avctx,
+                                              "If you heard an audible artifact, there may be a bug in the decoder. "
+                                              "Clipped noise gain (%d -> %d)",
+                                              offset[1], clipped_offset);
                     }
                     sf[idx] = -ff_aac_pow2sf_tab[clipped_offset + POW_SF2_ZERO];
                 }
@@ -1427,7 +1544,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024],
                         cfo[k] = ac->random_state;
                     }
 
-                    band_energy = ac->dsp.scalarproduct_float(cfo, cfo, off_len);
+                    band_energy = ac->fdsp.scalarproduct_float(cfo, cfo, off_len);
                     scale = sf[idx] / sqrtf(band_energy);
                     ac->fdsp.vector_fmul_scalar(cfo, cfo, scale, off_len);
                 }
@@ -1705,9 +1822,15 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce,
     TemporalNoiseShaping    *tns = &sce->tns;
     IndividualChannelStream *ics = &sce->ics;
     float *out = sce->coeffs;
-    int global_gain, pulse_present = 0;
+    int global_gain, eld_syntax, er_syntax, pulse_present = 0;
     int ret;
 
+    eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
+    er_syntax  = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC ||
+                 ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP ||
+                 ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD ||
+                 ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
+
     /* This assignment is to silence a GCC warning about the variable being used
      * uninitialized when in fact it always is.
      */
@@ -1729,7 +1852,7 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce,
 
     pulse_present = 0;
     if (!scale_flag) {
-        if ((pulse_present = get_bits1(gb))) {
+        if (!eld_syntax && (pulse_present = get_bits1(gb))) {
             if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
                 av_log(ac->avctx, AV_LOG_ERROR,
                        "Pulse tool not allowed in eight short sequence.\n");
@@ -1741,12 +1864,19 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce,
                 return AVERROR_INVALIDDATA;
             }
         }
-        if ((tns->present = get_bits1(gb)) && decode_tns(ac, tns, gb, ics))
-            return AVERROR_INVALIDDATA;
-        if (get_bits1(gb)) {
-            av_log_missing_feature(ac->avctx, "SSR", 1);
+        tns->present = get_bits1(gb);
+        if (tns->present && !er_syntax)
+            if (decode_tns(ac, tns, gb, ics) < 0)
+                return AVERROR_INVALIDDATA;
+        if (!eld_syntax && get_bits1(gb)) {
+            avpriv_request_sample(ac->avctx, "SSR");
             return AVERROR_PATCHWELCOME;
         }
+        // I see no textual basis in the spec for this occuring after SSR gain
+        // control, but this is what both reference and real implmentations do
+        if (tns->present && er_syntax)
+            if (decode_tns(ac, tns, gb, ics) < 0)
+                return AVERROR_INVALIDDATA;
     }
 
     if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present,
@@ -1775,9 +1905,9 @@ static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe)
                 cpe->ch[0].band_type[idx] < NOISE_BT &&
                 cpe->ch[1].band_type[idx] < NOISE_BT) {
                 for (group = 0; group < ics->group_len[g]; group++) {
-                    ac->dsp.butterflies_float(ch0 + group * 128 + offsets[i],
-                                              ch1 + group * 128 + offsets[i],
-                                              offsets[i+1] - offsets[i]);
+                    ac->fdsp.butterflies_float(ch0 + group * 128 + offsets[i],
+                                               ch1 + group * 128 + offsets[i],
+                                               offsets[i+1] - offsets[i]);
                 }
             }
         }
@@ -1838,8 +1968,9 @@ static void apply_intensity_stereo(AACContext *ac,
 static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe)
 {
     int i, ret, common_window, ms_present = 0;
+    int eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
 
-    common_window = get_bits1(gb);
+    common_window = eld_syntax || get_bits1(gb);
     if (common_window) {
         if (decode_ics_info(ac, &cpe->ch[0].ics, gb))
             return AVERROR_INVALIDDATA;
@@ -1921,7 +2052,7 @@ static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
         int idx  = 0;
         int cge  = 1;
         int gain = 0;
-        float gain_cache = 1.;
+        float gain_cache = 1.0;
         if (c) {
             cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
             gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
@@ -2055,10 +2186,12 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt,
         } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) {
             ac->oc[1].m4ac.sbr = 1;
             ac->oc[1].m4ac.ps = 1;
+            ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
             output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
                              ac->oc[1].status, 1);
         } else {
             ac->oc[1].m4ac.sbr = 1;
+            ac->avctx->profile = FF_PROFILE_AAC_HE;
         }
         res = ff_decode_sbr_extension(ac, &che->sbr, gb, crc_flag, cnt, elem_type);
         break;
@@ -2152,9 +2285,9 @@ static void windowing_and_mdct_ltp(AACContext *ac, float *out,
         ac->fdsp.vector_fmul(in + 448, in + 448, swindow_prev, 128);
     }
     if (ics->window_sequence[0] != LONG_START_SEQUENCE) {
-        ac->dsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
+        ac->fdsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
     } else {
-        ac->dsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
+        ac->fdsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
         memset(in + 1024 + 576, 0, 448 * sizeof(float));
     }
     ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in);
@@ -2207,17 +2340,17 @@ static void update_ltp(AACContext *ac, SingleChannelElement *sce)
     if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
         memcpy(saved_ltp,       saved, 512 * sizeof(float));
         memset(saved_ltp + 576, 0,     448 * sizeof(float));
-        ac->dsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
+        ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
         for (i = 0; i < 64; i++)
             saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i];
     } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
         memcpy(saved_ltp,       ac->buf_mdct + 512, 448 * sizeof(float));
         memset(saved_ltp + 576, 0,                  448 * sizeof(float));
-        ac->dsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
+        ac->fdsp.vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960,     &swindow[64],      64);
         for (i = 0; i < 64; i++)
             saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * swindow[63 - i];
     } else { // LONG_STOP or ONLY_LONG
-        ac->dsp.vector_fmul_reverse(saved_ltp,       ac->buf_mdct + 512,     &lwindow[512],     512);
+        ac->fdsp.vector_fmul_reverse(saved_ltp,       ac->buf_mdct + 512,     &lwindow[512],     512);
         for (i = 0; i < 512; i++)
             saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * lwindow[511 - i];
     }
@@ -2258,38 +2391,113 @@ static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
      */
     if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
             (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
-        ac->dsp.vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 512);
+        ac->fdsp.vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 512);
     } else {
-        memcpy(                        out,               saved,            448 * sizeof(float));
+        memcpy(                         out,               saved,            448 * sizeof(float));
 
         if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-            ac->dsp.vector_fmul_window(out + 448 + 0*128, saved + 448,      buf + 0*128, swindow_prev, 64);
-            ac->dsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow,      64);
-            ac->dsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow,      64);
-            ac->dsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow,      64);
-            ac->dsp.vector_fmul_window(temp,              buf + 3*128 + 64, buf + 4*128, swindow,      64);
-            memcpy(                    out + 448 + 4*128, temp, 64 * sizeof(float));
+            ac->fdsp.vector_fmul_window(out + 448 + 0*128, saved + 448,      buf + 0*128, swindow_prev, 64);
+            ac->fdsp.vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow,      64);
+            ac->fdsp.vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow,      64);
+            ac->fdsp.vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow,      64);
+            ac->fdsp.vector_fmul_window(temp,              buf + 3*128 + 64, buf + 4*128, swindow,      64);
+            memcpy(                     out + 448 + 4*128, temp, 64 * sizeof(float));
         } else {
-            ac->dsp.vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, 64);
-            memcpy(                    out + 576,         buf + 64,         448 * sizeof(float));
+            ac->fdsp.vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, 64);
+            memcpy(                     out + 576,         buf + 64,         448 * sizeof(float));
         }
     }
 
     // buffer update
     if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-        memcpy(                    saved,       temp + 64,         64 * sizeof(float));
-        ac->dsp.vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 64);
-        ac->dsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
-        ac->dsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
-        memcpy(                    saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
+        memcpy(                     saved,       temp + 64,         64 * sizeof(float));
+        ac->fdsp.vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 64);
+        ac->fdsp.vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
+        ac->fdsp.vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
+        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
     } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
-        memcpy(                    saved,       buf + 512,        448 * sizeof(float));
-        memcpy(                    saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
+        memcpy(                     saved,       buf + 512,        448 * sizeof(float));
+        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(float));
     } else { // LONG_STOP or ONLY_LONG
-        memcpy(                    saved,       buf + 512,        512 * sizeof(float));
+        memcpy(                     saved,       buf + 512,        512 * sizeof(float));
     }
 }
 
+static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce)
+{
+    IndividualChannelStream *ics = &sce->ics;
+    float *in    = sce->coeffs;
+    float *out   = sce->ret;
+    float *saved = sce->saved;
+    const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_512 : ff_sine_512;
+    float *buf  = ac->buf_mdct;
+
+    // imdct
+    ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
+
+    // window overlapping
+    ac->fdsp.vector_fmul_window(out, saved, buf, lwindow_prev, 256);
+
+    // buffer update
+    memcpy(saved, buf + 256, 256 * sizeof(float));
+}
+
+static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce)
+{
+    float *in    = sce->coeffs;
+    float *out   = sce->ret;
+    float *saved = sce->saved;
+    const float *const window = ff_aac_eld_window;
+    float *buf  = ac->buf_mdct;
+    int i;
+    const int n  = 512;
+    const int n2 = n >> 1;
+    const int n4 = n >> 2;
+
+    // Inverse transform, mapped to the conventional IMDCT by
+    // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
+    // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks,"
+    // Audio, Language and Image Processing, 2008. ICALIP 2008. International Conference on
+    // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950
+    for (i = 0; i < n2; i+=2) {
+        float temp;
+        temp =  in[i    ]; in[i    ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
+        temp = -in[i + 1]; in[i + 1] =  in[n - 2 - i]; in[n - 2 - i] = temp;
+    }
+    ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
+    for (i = 0; i < n; i+=2) {
+        buf[i] = -buf[i];
+    }
+    // Like with the regular IMDCT at this point we still have the middle half
+    // of a transform but with even symmetry on the left and odd symmetry on
+    // the right
+
+    // window overlapping
+    // The spec says to use samples [0..511] but the reference decoder uses
+    // samples [128..639].
+    for (i = n4; i < n2; i ++) {
+        out[i - n4] =    buf[n2 - 1 - i]       * window[i       - n4] +
+                       saved[      i + n2]     * window[i +   n - n4] +
+                      -saved[  n + n2 - 1 - i] * window[i + 2*n - n4] +
+                      -saved[2*n + n2 + i]     * window[i + 3*n - n4];
+    }
+    for (i = 0; i < n2; i ++) {
+        out[n4 + i] =    buf[i]               * window[i + n2       - n4] +
+                      -saved[      n - 1 - i] * window[i + n2 +   n - n4] +
+                      -saved[  n + i]         * window[i + n2 + 2*n - n4] +
+                       saved[2*n + n - 1 - i] * window[i + n2 + 3*n - n4];
+    }
+    for (i = 0; i < n4; i ++) {
+        out[n2 + n4 + i] =    buf[      i + n2]     * window[i +   n - n4] +
+                           -saved[      n2 - 1 - i] * window[i + 2*n - n4] +
+                           -saved[  n + n2 + i]     * window[i + 3*n - n4];
+    }
+
+    // buffer update
+    memmove(saved + n, saved, 2 * n * sizeof(float));
+    memcpy( saved,       buf,     n * sizeof(float));
+}
+
 /**
  * Apply dependent channel coupling (applied before IMDCT).
  *
@@ -2386,6 +2594,17 @@ static void apply_channel_coupling(AACContext *ac, ChannelElement *cc,
 static void spectral_to_sample(AACContext *ac)
 {
     int i, type;
+    void (*imdct_and_window)(AACContext *ac, SingleChannelElement *sce);
+    switch (ac->oc[1].m4ac.object_type) {
+    case AOT_ER_AAC_LD:
+        imdct_and_window = imdct_and_windowing_ld;
+        break;
+    case AOT_ER_AAC_ELD:
+        imdct_and_window = imdct_and_windowing_eld;
+        break;
+    default:
+        imdct_and_window = imdct_and_windowing;
+    }
     for (type = 3; type >= 0; type--) {
         for (i = 0; i < MAX_ELEM_ID; i++) {
             ChannelElement *che = ac->che[type][i];
@@ -2407,11 +2626,11 @@ static void spectral_to_sample(AACContext *ac)
                 if (type <= TYPE_CPE)
                     apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, apply_dependent_coupling);
                 if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) {
-                    imdct_and_windowing(ac, &che->ch[0]);
+                    imdct_and_window(ac, &che->ch[0]);
                     if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP)
                         update_ltp(ac, &che->ch[0]);
                     if (type == TYPE_CPE) {
-                        imdct_and_windowing(ac, &che->ch[1]);
+                        imdct_and_window(ac, &che->ch[1]);
                         if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP)
                             update_ltp(ac, &che->ch[1]);
                     }
@@ -2431,23 +2650,27 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
     int size;
     AACADTSHeaderInfo hdr_info;
     uint8_t layout_map[MAX_ELEM_ID*4][3];
-    int layout_map_tags;
+    int layout_map_tags, ret;
 
     size = avpriv_aac_parse_header(gb, &hdr_info);
     if (size > 0) {
         if (hdr_info.num_aac_frames != 1) {
-            av_log_missing_feature(ac->avctx, "More than one AAC RDB per ADTS frame", 0);
+            avpriv_report_missing_feature(ac->avctx,
+                                          "More than one AAC RDB per ADTS frame");
             return AVERROR_PATCHWELCOME;
         }
         push_output_configuration(ac);
         if (hdr_info.chan_config) {
             ac->oc[1].m4ac.chan_config = hdr_info.chan_config;
-            if (set_default_channel_config(ac->avctx, layout_map,
-                    &layout_map_tags, hdr_info.chan_config))
-                return -7;
-            if (output_configure(ac, layout_map, layout_map_tags,
-                                 FFMAX(ac->oc[1].status, OC_TRIAL_FRAME), 0))
-                return -7;
+            if ((ret = set_default_channel_config(ac->avctx,
+                                                  layout_map,
+                                                  &layout_map_tags,
+                                                  hdr_info.chan_config)) < 0)
+                return ret;
+            if ((ret = output_configure(ac, layout_map, layout_map_tags,
+                                        FFMAX(ac->oc[1].status,
+                                              OC_TRIAL_FRAME), 0)) < 0)
+                return ret;
         } else {
             ac->oc[1].m4ac.chan_config = 0;
         }
@@ -2466,6 +2689,70 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
     return size;
 }
 
+static int aac_decode_er_frame(AVCodecContext *avctx, void *data,
+                               int *got_frame_ptr, GetBitContext *gb)
+{
+    AACContext *ac = avctx->priv_data;
+    ChannelElement *che;
+    int err, i;
+    int samples = 1024;
+    int chan_config = ac->oc[1].m4ac.chan_config;
+    int aot = ac->oc[1].m4ac.object_type;
+
+    if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD)
+        samples >>= 1;
+
+    ac->frame = data;
+
+    if ((err = frame_configure_elements(avctx)) < 0)
+        return err;
+
+    // The FF_PROFILE_AAC_* defines are all object_type - 1
+    // This may lead to an undefined profile being signaled
+    ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
+
+    ac->tags_mapped = 0;
+
+    if (chan_config < 0 || chan_config >= 8) {
+        avpriv_request_sample(avctx, "Unknown ER channel configuration %d",
+                              ac->oc[1].m4ac.chan_config);
+        return AVERROR_INVALIDDATA;
+    }
+    for (i = 0; i < tags_per_config[chan_config]; i++) {
+        const int elem_type = aac_channel_layout_map[chan_config-1][i][0];
+        const int elem_id   = aac_channel_layout_map[chan_config-1][i][1];
+        if (!(che=get_che(ac, elem_type, elem_id))) {
+            av_log(ac->avctx, AV_LOG_ERROR,
+                   "channel element %d.%d is not allocated\n",
+                   elem_type, elem_id);
+            return AVERROR_INVALIDDATA;
+        }
+        if (aot != AOT_ER_AAC_ELD)
+            skip_bits(gb, 4);
+        switch (elem_type) {
+        case TYPE_SCE:
+            err = decode_ics(ac, &che->ch[0], gb, 0, 0);
+            break;
+        case TYPE_CPE:
+            err = decode_cpe(ac, gb, che);
+            break;
+        case TYPE_LFE:
+            err = decode_ics(ac, &che->ch[0], gb, 0, 0);
+            break;
+        }
+        if (err < 0)
+            return err;
+    }
+
+    spectral_to_sample(ac);
+
+    ac->frame->nb_samples = samples;
+    *got_frame_ptr = 1;
+
+    skip_bits_long(gb, get_bits_left(gb));
+    return 0;
+}
+
 static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
                                 int *got_frame_ptr, GetBitContext *gb)
 {
@@ -2475,23 +2762,26 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
     int err, elem_id;
     int samples = 0, multiplier, audio_found = 0, pce_found = 0;
 
+    ac->frame = data;
+
     if (show_bits(gb, 12) == 0xfff) {
-        if (parse_adts_frame_header(ac, gb) < 0) {
+        if ((err = parse_adts_frame_header(ac, gb)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
-            err = -1;
             goto fail;
         }
         if (ac->oc[1].m4ac.sampling_index > 12) {
             av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index);
-            err = -1;
+            err = AVERROR_INVALIDDATA;
             goto fail;
         }
     }
 
-    if (frame_configure_elements(avctx) < 0) {
-        err = -1;
+    if ((err = frame_configure_elements(avctx)) < 0)
         goto fail;
-    }
+
+    // The FF_PROFILE_AAC_* defines are all object_type - 1
+    // This may lead to an undefined profile being signaled
+    ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
 
     ac->tags_mapped = 0;
     // parse
@@ -2502,7 +2792,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
             if (!(che=get_che(ac, elem_type, elem_id))) {
                 av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
                        elem_type, elem_id);
-                err = -1;
+                err = AVERROR_INVALIDDATA;
                 goto fail;
             }
             samples = 1024;
@@ -2558,7 +2848,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
                 elem_id += get_bits(gb, 8) - 1;
             if (get_bits_left(gb) < 8 * elem_id) {
                     av_log(avctx, AV_LOG_ERROR, overread_err);
-                    err = -1;
+                    err = AVERROR_INVALIDDATA;
                     goto fail;
             }
             while (elem_id > 0)
@@ -2567,7 +2857,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
             break;
 
         default:
-            err = -1; /* should not happen, but keeps compiler happy */
+            err = AVERROR_BUG; /* should not happen, but keeps compiler happy */
             break;
         }
 
@@ -2579,7 +2869,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
 
         if (get_bits_left(gb) < 3) {
             av_log(avctx, AV_LOG_ERROR, overread_err);
-            err = -1;
+            err = AVERROR_INVALIDDATA;
             goto fail;
         }
     }
@@ -2589,10 +2879,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
     multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0;
     samples <<= multiplier;
 
-    if (samples) {
-        ac->frame.nb_samples = samples;
-        *(AVFrame *)data = ac->frame;
-    }
+    if (samples)
+        ac->frame->nb_samples = samples;
     *got_frame_ptr = !!samples;
 
     if (ac->oc[1].status && audio_found) {
@@ -2642,7 +2930,17 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data,
     if ((err = init_get_bits(&gb, buf, buf_size * 8)) < 0)
         return err;
 
-    if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb)) < 0)
+    switch (ac->oc[1].m4ac.object_type) {
+    case AOT_ER_AAC_LC:
+    case AOT_ER_AAC_LTP:
+    case AOT_ER_AAC_LD:
+    case AOT_ER_AAC_ELD:
+        err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb);
+        break;
+    default:
+        err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb);
+    }
+    if (err < 0)
         return err;
 
     buf_consumed = (get_bits_count(&gb) + 7) >> 3;
@@ -2668,6 +2966,7 @@ static av_cold int aac_decode_close(AVCodecContext *avctx)
 
     ff_mdct_end(&ac->mdct);
     ff_mdct_end(&ac->mdct_small);
+    ff_mdct_end(&ac->mdct_ld);
     ff_mdct_end(&ac->mdct_ltp);
     return 0;
 }
@@ -2709,8 +3008,8 @@ static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
         asclen         = get_bits_left(gb);
 
     if (config_start_bit % 8) {
-        av_log_missing_feature(latmctx->aac_ctx.avctx,
-                               "Non-byte-aligned audio-specific config", 1);
+        avpriv_request_sample(latmctx->aac_ctx.avctx,
+                              "Non-byte-aligned audio-specific config");
         return AVERROR_PATCHWELCOME;
     }
     if (asclen <= 0)
@@ -2764,8 +3063,7 @@ static int read_stream_mux_config(struct LATMContext *latmctx,
         skip_bits(gb, 6);                       // numSubFrames
         // numPrograms
         if (get_bits(gb, 4)) {                  // numPrograms
-            av_log_missing_feature(latmctx->aac_ctx.avctx,
-                                   "Multiple programs", 1);
+            avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple programs");
             return AVERROR_PATCHWELCOME;
         }
 
@@ -2773,8 +3071,7 @@ static int read_stream_mux_config(struct LATMContext *latmctx,
 
         // for each layer (which there is only on in DVB)
         if (get_bits(gb, 3)) {                   // numLayer
-            av_log_missing_feature(latmctx->aac_ctx.avctx,
-                                   "Multiple layers", 1);
+            avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple layers");
             return AVERROR_PATCHWELCOME;
         }
 
@@ -2943,13 +3240,13 @@ static av_cold int latm_decode_init(AVCodecContext *avctx)
 
 AVCodec ff_aac_decoder = {
     .name            = "aac",
+    .long_name       = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
     .type            = AVMEDIA_TYPE_AUDIO,
     .id              = AV_CODEC_ID_AAC,
     .priv_data_size  = sizeof(AACContext),
     .init            = aac_decode_init,
     .close           = aac_decode_close,
     .decode          = aac_decode_frame,
-    .long_name       = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
     .sample_fmts     = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
     },
@@ -2964,13 +3261,13 @@ AVCodec ff_aac_decoder = {
 */
 AVCodec ff_aac_latm_decoder = {
     .name            = "aac_latm",
+    .long_name       = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"),
     .type            = AVMEDIA_TYPE_AUDIO,
     .id              = AV_CODEC_ID_AAC_LATM,
     .priv_data_size  = sizeof(struct LATMContext),
     .init            = latm_decode_init,
     .close           = aac_decode_close,
     .decode          = latm_decode_frame,
-    .long_name       = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"),
     .sample_fmts     = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
     },
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 6f582ca..55aa2f1 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -34,7 +34,6 @@
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "mpeg4audio.h"
 #include "kbdwin.h"
@@ -183,7 +182,7 @@ static void put_audio_specific_config(AVCodecContext *avctx)
 }
 
 #define WINDOW_FUNC(type) \
-static void apply_ ##type ##_window(DSPContext *dsp, AVFloatDSPContext *fdsp, \
+static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \
                                     SingleChannelElement *sce, \
                                     const float *audio)
 
@@ -193,8 +192,8 @@ WINDOW_FUNC(only_long)
     const float *pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_long_1024 : ff_sine_1024;
     float *out = sce->ret_buf;
 
-    fdsp->vector_fmul       (out,        audio,        lwindow, 1024);
-    dsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024);
+    fdsp->vector_fmul        (out,        audio,        lwindow, 1024);
+    fdsp->vector_fmul_reverse(out + 1024, audio + 1024, pwindow, 1024);
 }
 
 WINDOW_FUNC(long_start)
@@ -205,7 +204,7 @@ WINDOW_FUNC(long_start)
 
     fdsp->vector_fmul(out, audio, lwindow, 1024);
     memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448);
-    dsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128);
+    fdsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128);
     memset(out + 1024 + 576, 0, sizeof(out[0]) * 448);
 }
 
@@ -218,7 +217,7 @@ WINDOW_FUNC(long_stop)
     memset(out, 0, sizeof(out[0]) * 448);
     fdsp->vector_fmul(out + 448, audio + 448, swindow, 128);
     memcpy(out + 576, audio + 576, sizeof(out[0]) * 448);
-    dsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024);
+    fdsp->vector_fmul_reverse(out + 1024, audio + 1024, lwindow, 1024);
 }
 
 WINDOW_FUNC(eight_short)
@@ -230,15 +229,15 @@ WINDOW_FUNC(eight_short)
     int w;
 
     for (w = 0; w < 8; w++) {
-        fdsp->vector_fmul       (out, in, w ? pwindow : swindow, 128);
+        fdsp->vector_fmul        (out, in, w ? pwindow : swindow, 128);
         out += 128;
         in  += 128;
-        dsp->vector_fmul_reverse(out, in, swindow, 128);
+        fdsp->vector_fmul_reverse(out, in, swindow, 128);
         out += 128;
     }
 }
 
-static void (*const apply_window[4])(DSPContext *dsp, AVFloatDSPContext *fdsp,
+static void (*const apply_window[4])(AVFloatDSPContext *fdsp,
                                      SingleChannelElement *sce,
                                      const float *audio) = {
     [ONLY_LONG_SEQUENCE]   = apply_only_long_window,
@@ -253,7 +252,7 @@ static void apply_window_and_mdct(AACEncContext *s, SingleChannelElement *sce,
     int i;
     float *output = sce->ret_buf;
 
-    apply_window[sce->ics.window_sequence[0]](&s->dsp, &s->fdsp, sce, audio);
+    apply_window[sce->ics.window_sequence[0]](&s->fdsp, sce, audio);
 
     if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE)
         s->mdct1024.mdct_calc(&s->mdct1024, sce->coeffs, output);
@@ -598,7 +597,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                 coeffs[ch] = cpe->ch[ch].coeffs;
             s->psy.model->analyze(&s->psy, start_ch, coeffs, wi);
             for (ch = 0; ch < chans; ch++) {
-                s->cur_channel = start_ch * 2 + ch;
+                s->cur_channel = start_ch + ch;
                 s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda);
             }
             cpe->common_window = 0;
@@ -614,7 +613,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                     }
                 }
             }
-            s->cur_channel = start_ch * 2;
+            s->cur_channel = start_ch;
             if (s->options.stereo_mode && cpe->common_window) {
                 if (s->options.stereo_mode > 0) {
                     IndividualChannelStream *ics = &cpe->ch[0].ics;
@@ -684,9 +683,6 @@ static av_cold int aac_encode_end(AVCodecContext *avctx)
     av_freep(&s->buffer.samples);
     av_freep(&s->cpe);
     ff_af_queue_close(&s->afq);
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     return 0;
 }
 
@@ -694,7 +690,6 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s)
 {
     int ret = 0;
 
-    ff_dsputil_init(&s->dsp, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     // window init
@@ -721,11 +716,6 @@ static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s)
     for(ch = 0; ch < s->channels; ch++)
         s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    if (!(avctx->coded_frame = avcodec_alloc_frame()))
-        goto alloc_fail;
-#endif
-
     return 0;
 alloc_fail:
     return AVERROR(ENOMEM);
@@ -814,6 +804,7 @@ static const AVClass aacenc_class = {
 
 AVCodec ff_aac_encoder = {
     .name           = "aac",
+    .long_name      = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AAC,
     .priv_data_size = sizeof(AACEncContext),
@@ -824,6 +815,5 @@ AVCodec ff_aac_encoder = {
                       CODEC_CAP_EXPERIMENTAL,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
     .priv_class     = &aacenc_class,
 };
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 81ffb97..dec445c 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -25,7 +25,6 @@
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 
 #include "aac.h"
 #include "audio_frame_queue.h"
@@ -58,7 +57,6 @@ typedef struct AACEncContext {
     PutBitContext pb;
     FFTContext mdct1024;                         ///< long (1024 samples) frame transform context
     FFTContext mdct128;                          ///< short (128 samples) frame transform context
-    DSPContext  dsp;
     AVFloatDSPContext fdsp;
     float *planar_samples[6];                    ///< saved preprocessed input
 
diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
index fa7e9ac..8f55c7f 100644
--- a/libavcodec/aacps.c
+++ b/libavcodec/aacps.c
@@ -21,13 +21,13 @@
 
 #include <stdint.h>
 #include "libavutil/common.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "aacps.h"
 #include "aacps_tablegen.h"
 #include "aacpsdata.c"
-#include "dsputil.h"
 
 #define PS_BASELINE 0  ///< Operate in Baseline PS mode
                        ///< Baseline implies 10 or 20 stereo bands,
@@ -305,14 +305,15 @@ static void hybrid2_re(float (*in)[2], float (*out)[32][2], const float filter[8
 }
 
 /** Split one subband into 6 subsubbands with a complex filter */
-static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int len)
+static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2],
+                       TABLE_CONST float (*filter)[8][2], int len)
 {
     int i;
     int N = 8;
     LOCAL_ALIGNED_16(float, temp, [8], [2]);
 
     for (i = 0; i < len; i++, in++) {
-        dsp->hybrid_analysis(temp, in, filter, 1, N);
+        dsp->hybrid_analysis(temp, in, (const float (*)[8][2]) filter, 1, N);
         out[0][i][0] = temp[6][0];
         out[0][i][1] = temp[6][1];
         out[1][i][0] = temp[7][0];
@@ -328,12 +329,14 @@ static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], c
     }
 }
 
-static void hybrid4_8_12_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int N, int len)
+static void hybrid4_8_12_cx(PSDSPContext *dsp,
+                            float (*in)[2], float (*out)[32][2],
+                            TABLE_CONST float (*filter)[8][2], int N, int len)
 {
     int i;
 
     for (i = 0; i < len; i++, in++) {
-        dsp->hybrid_analysis(out[0] + i, in, filter, 32, N);
+        dsp->hybrid_analysis(out[0] + i, in, (const float (*)[8][2]) filter, 32, N);
     }
 }
 
@@ -669,7 +672,8 @@ static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[3
             memcpy(ap_delay[k][m],   ap_delay[k][m]+numQMFSlots,           5*sizeof(ap_delay[k][m][0]));
         }
         ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k],
-                            phi_fract[is34][k], Q_fract_allpass[is34][k],
+                            phi_fract[is34][k],
+                            (const float (*)[2]) Q_fract_allpass[is34][k],
                             transient_gain[b], g_decay_slope, nL - n0);
     }
     for (; k < SHORT_DELAY_BAND[is34]; k++) {
@@ -747,7 +751,7 @@ static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2
     int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf;
     int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf;
     const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20;
-    const float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB;
+    TABLE_CONST float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB;
 
     //Remapping
     if (ps->num_env_old) {
@@ -897,7 +901,7 @@ int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float
         memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0]));
 
     hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
-    decorrelation(ps, Rbuf, Lbuf, is34);
+    decorrelation(ps, Rbuf, (const float (*)[32][2]) Lbuf, is34);
     stereo_processing(ps, Lbuf, Rbuf, is34);
     hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
     hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
diff --git a/libavcodec/aacps_tablegen.c b/libavcodec/aacps_tablegen.c
index 635737d..537b6ba 100644
--- a/libavcodec/aacps_tablegen.c
+++ b/libavcodec/aacps_tablegen.c
@@ -82,7 +82,7 @@ int main(void)
     write_float_3d_array(f34_2_4, 4, 8, 2);
     printf("};\n");
 
-    printf("static const DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n");
+    printf("static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n");
     write_float_4d_array(Q_fract_allpass, 2, 50, 3, 2);
     printf("};\n");
     printf("static const DECLARE_ALIGNED(16, float, phi_fract)[2][50][2] = {\n");
diff --git a/libavcodec/aacps_tablegen.h b/libavcodec/aacps_tablegen.h
index 0c610ed..a53f9fa 100644
--- a/libavcodec/aacps_tablegen.h
+++ b/libavcodec/aacps_tablegen.h
@@ -28,6 +28,7 @@
 
 #if CONFIG_HARDCODED_TABLES
 #define ps_tableinit()
+#define TABLE_CONST const
 #include "libavcodec/aacps_tables.h"
 #else
 #include "libavutil/common.h"
@@ -37,6 +38,7 @@
 #define NR_ALLPASS_BANDS20 30
 #define NR_ALLPASS_BANDS34 50
 #define PS_AP_LINKS 3
+#define TABLE_CONST
 static float pd_re_smooth[8*8*8];
 static float pd_im_smooth[8*8*8];
 static float HA[46][8][4];
@@ -45,7 +47,7 @@ static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2];
 static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2];
 static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2];
 static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2];
-static DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2];
+static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2];
 static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2];
 
 static const float g0_Q8[] = {
@@ -192,7 +194,7 @@ static void ps_tableinit(void)
     for (k = 0; k < NR_ALLPASS_BANDS34; k++) {
         double f_center, theta;
         if (k < FF_ARRAY_ELEMS(f_center_34))
-            f_center = f_center_34[k] / 24.;
+            f_center = f_center_34[k] / 24.0;
         else
             f_center = k - 26.5f;
         for (m = 0; m < PS_AP_LINKS; m++) {
diff --git a/libavcodec/aacpsdsp.c b/libavcodec/aacpsdsp.c
index e90c50b..88e731f 100644
--- a/libavcodec/aacpsdsp.c
+++ b/libavcodec/aacpsdsp.c
@@ -93,7 +93,7 @@ static void ps_hybrid_synthesis_deint_c(float out[2][38][64],
 
 static void ps_decorrelate_c(float (*out)[2], float (*delay)[2],
                              float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2],
-                             const float phi_fract[2], float (*Q_fract)[2],
+                             const float phi_fract[2], const float (*Q_fract)[2],
                              const float *transient_gain,
                              float g_decay_slope,
                              int len)
diff --git a/libavcodec/aacpsdsp.h b/libavcodec/aacpsdsp.h
index 93737d2..dc380b1 100644
--- a/libavcodec/aacpsdsp.h
+++ b/libavcodec/aacpsdsp.h
@@ -38,7 +38,7 @@ typedef struct PSDSPContext {
                                    int i, int len);
     void (*decorrelate)(float (*out)[2], float (*delay)[2],
                         float (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2],
-                        const float phi_fract[2], float (*Q_fract)[2],
+                        const float phi_fract[2], const float (*Q_fract)[2],
                         const float *transient_gain,
                         float g_decay_slope,
                         int len);
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
index e4b4405..66cf6d5 100644
--- a/libavcodec/aacpsy.c
+++ b/libavcodec/aacpsy.c
@@ -24,6 +24,7 @@
  * AAC encoder psychoacoustic model
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "aactab.h"
 #include "psymodel.h"
@@ -248,7 +249,8 @@ static float lame_calc_attack_threshold(int bitrate)
 /**
  * LAME psy model specific initialization
  */
-static void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx) {
+static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx)
+{
     int i, j;
 
     for (i = 0; i < avctx->channels; i++) {
@@ -310,7 +312,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) {
         AacPsyCoeffs *coeffs = pctx->psy_coef[j];
         const uint8_t *band_sizes = ctx->bands[j];
         float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f);
-        float avg_chan_bits = chan_bitrate / ctx->avctx->sample_rate * (j ? 128.0f : 1024.0f);
+        float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate;
         /* reference encoder uses 2.4% here instead of 60% like the spec says */
         float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark;
         float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L;
@@ -804,7 +806,8 @@ static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio,
                 sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]);
                 sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]);
             }
-            /* NOTE: The LAME psymodel expects it's input in the range -32768 to 32768. Tuning this for normalized floats would be difficult. */
+            /* NOTE: The LAME psymodel expects its input in the range -32768 to
+             * 32768. Tuning this for normalized floats would be difficult. */
             hpfsmpl[i] = (sum1 + sum2) * 32768.0f;
         }
 
diff --git a/libavcodec/aacpsy.h b/libavcodec/aacpsy.h
deleted file mode 100644
index 5d1e142..0000000
--- a/libavcodec/aacpsy.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * AAC encoder psychoacoustic model
- * Copyright (C) 2008 Konstantin Shishkov
- *
- * This file is part of 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_AACPSY_H
-#define AVCODEC_AACPSY_H
-
-#include "avcodec.h"
-#include "aac.h"
-//#include "lowpass.h"
-
-enum AACPsyModelType{
-    AAC_PSY_TEST,              ///< a sample model to exercise encoder
-    AAC_PSY_3GPP,              ///< model following recommendations from 3GPP TS 26.403
-
-    AAC_NB_PSY_MODELS          ///< total number of psychoacoustic models, since it's not a part of the ABI new models can be added freely
-};
-
-/**
- * context used by psychoacoustic model
- */
-typedef struct AACPsyContext {
-    AVCodecContext *avctx;            ///< encoder context
-}AACPsyContext;
-
-/**
- * Cleanup model context at the end.
- *
- * @param ctx model context
- */
-void ff_aac_psy_end(AACPsyContext *ctx);
-
-#endif /* AVCODEC_AACPSY_H */
diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c
index add9f18..4d2ac6c 100644
--- a/libavcodec/aacsbr.c
+++ b/libavcodec/aacsbr.c
@@ -33,6 +33,7 @@
 #include "fft.h"
 #include "aacps.h"
 #include "sbrdsp.h"
+#include "libavutil/internal.h"
 #include "libavutil/libm.h"
 
 #include <stdint.h>
@@ -918,15 +919,16 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
         } else {
 #if 1
             *num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps, *num_bits_left);
+            ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
 #else
-            av_log_missing_feature(ac->avctx, "Parametric Stereo", 0);
+            avpriv_report_missing_feature(ac->avctx, "Parametric Stereo");
             skip_bits_long(gb, *num_bits_left); // bs_fill_bits
             *num_bits_left = 0;
 #endif
         }
         break;
     default:
-        av_log_missing_feature(ac->avctx, "Reserved SBR extensions", 1);
+        avpriv_request_sample(ac->avctx, "Reserved SBR extensions");
         skip_bits_long(gb, *num_bits_left); // bs_fill_bits
         *num_bits_left = 0;
         break;
@@ -1150,7 +1152,7 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
  * @param   x       pointer to the beginning of the first sample window
  * @param   W       array of complex-valued samples split into subbands
  */
-static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct,
+static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
                              SBRDSPContext *sbrdsp, const float *in, float *x,
                              float z[320], float W[2][32][32][2], int buf_idx)
 {
@@ -1172,8 +1174,8 @@ static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct,
  * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank
  * (14496-3 sp04 p206)
  */
-static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct,
-                              SBRDSPContext *sbrdsp, AVFloatDSPContext *fdsp,
+static void sbr_qmf_synthesis(FFTContext *mdct,
+                              SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp,
                               float *out, float X[2][38][64],
                               float mdct_buf[2][64],
                               float *v0, int *v_off, const unsigned int div)
@@ -1204,7 +1206,7 @@ static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct,
             mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
             sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
         }
-        fdsp->vector_fmul   (out, v                , sbr_qmf_window                       , 64 >> div);
+        dsp->vector_fmul    (out, v                , sbr_qmf_window                       , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out   , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out   , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out   , 64 >> div);
@@ -1663,15 +1665,21 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
     }
     for (ch = 0; ch < nch; ch++) {
         /* decode channel */
-        sbr_qmf_analysis(&ac->dsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
+        sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
                          (float*)sbr->qmf_filter_scratch,
                          sbr->data[ch].W, sbr->data[ch].Ypos);
-        sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos);
+        sbr_lf_gen(ac, sbr, sbr->X_low,
+                   (const float (*)[32][32][2]) sbr->data[ch].W,
+                   sbr->data[ch].Ypos);
         sbr->data[ch].Ypos ^= 1;
         if (sbr->start) {
-            sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]);
+            sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1,
+                                  (const float (*)[40][2]) sbr->X_low, sbr->k[0]);
             sbr_chirp(sbr, &sbr->data[ch]);
-            sbr_hf_gen(ac, sbr, sbr->X_high, sbr->X_low, sbr->alpha0, sbr->alpha1,
+            sbr_hf_gen(ac, sbr, sbr->X_high,
+                       (const float (*)[40][2]) sbr->X_low,
+                       (const float (*)[2]) sbr->alpha0,
+                       (const float (*)[2]) sbr->alpha1,
                        sbr->data[ch].bw_array, sbr->data[ch].t_env,
                        sbr->data[ch].bs_num_env);
 
@@ -1681,16 +1689,17 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
                 sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
                 sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
                 sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
-                                sbr->X_high, sbr, &sbr->data[ch],
+                                (const float (*)[40][2]) sbr->X_high,
+                                sbr, &sbr->data[ch],
                                 sbr->data[ch].e_a);
             }
         }
 
         /* synthesis */
         sbr_x_gen(sbr, sbr->X[ch],
-                  sbr->data[ch].Y[1-sbr->data[ch].Ypos],
-                  sbr->data[ch].Y[  sbr->data[ch].Ypos],
-                  sbr->X_low, ch);
+                  (const float (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos],
+                  (const float (*)[64][2]) sbr->data[ch].Y[  sbr->data[ch].Ypos],
+                  (const float (*)[40][2]) sbr->X_low, ch);
     }
 
     if (ac->oc[1].m4ac.ps == 1) {
@@ -1702,13 +1711,13 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
         nch = 2;
     }
 
-    sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, &sbr->dsp, &ac->fdsp,
+    sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
                       L, sbr->X[0], sbr->qmf_filter_scratch,
                       sbr->data[0].synthesis_filterbank_samples,
                       &sbr->data[0].synthesis_filterbank_samples_offset,
                       downsampled);
     if (nch == 2)
-        sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, &sbr->dsp, &ac->fdsp,
+        sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
                           R, sbr->X[1], sbr->qmf_filter_scratch,
                           sbr->data[1].synthesis_filterbank_samples,
                           &sbr->data[1].synthesis_filterbank_samples_offset,
diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h
index 153070d..9bc5e29 100644
--- a/libavcodec/aacsbr.h
+++ b/libavcodec/aacsbr.h
@@ -34,11 +34,11 @@
 #include "sbr.h"
 
 /** Initialize SBR. */
-av_cold void ff_aac_sbr_init(void);
+void ff_aac_sbr_init(void);
 /** Initialize one SBR context. */
-av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr);
+void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr);
 /** Close one SBR context. */
-av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr);
+void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr);
 /** Decode one SBR element. */
 int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
                             GetBitContext *gb, int crc, int cnt, int id_aac);
diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c
index 9176e37..77cbc2d 100644
--- a/libavcodec/aactab.c
+++ b/libavcodec/aactab.c
@@ -34,12 +34,17 @@
 #include <stdint.h>
 
 DECLARE_ALIGNED(32, float,  ff_aac_kbd_long_1024)[1024];
+DECLARE_ALIGNED(32, float,  ff_aac_kbd_long_512 )[512];
 DECLARE_ALIGNED(32, float,  ff_aac_kbd_short_128)[128];
 
 const uint8_t ff_aac_num_swb_1024[] = {
     41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40
 };
 
+const uint8_t ff_aac_num_swb_512[] = {
+     0,  0,  0, 36, 36, 37, 31, 31,  0,  0,  0,  0,  0
+};
+
 const uint8_t ff_aac_num_swb_128[] = {
     12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15
 };
@@ -1114,6 +1119,14 @@ static const uint16_t swb_offset_1024_48[] = {
     928, 1024
 };
 
+static const uint16_t swb_offset_512_48[] = {
+      0,   4,   8,  12,  16,  20,  24,  28,
+     32,  36,  40,  44,  48,  52,  56,  60,
+     68,  76,  84,  92, 100, 112, 124, 136,
+    148, 164, 184, 208, 236, 268, 300, 332,
+    364, 396, 428, 460, 512
+};
+
 static const uint16_t swb_offset_128_48[] = {
      0,   4,   8,  12,  16,  20,  28,  36,
     44,  56,  68,  80,  96, 112, 128
@@ -1129,6 +1142,14 @@ static const uint16_t swb_offset_1024_32[] = {
     928, 960, 992, 1024
 };
 
+static const uint16_t swb_offset_512_32[] = {
+      0,   4,   8,  12,  16,  20,  24,  28,
+     32,  36,  40,  44,  48,  52,  56,  64,
+     72,  80,  88,  96, 108, 120, 132, 144,
+    160, 176, 192, 212, 236, 260, 288, 320,
+    352, 384, 416, 448, 480, 512
+};
+
 static const uint16_t swb_offset_1024_24[] = {
       0,   4,   8,  12,  16,  20,  24,  28,
      32,  36,  40,  44,  52,  60,  68,  76,
@@ -1138,6 +1159,13 @@ static const uint16_t swb_offset_1024_24[] = {
     600, 652, 704, 768, 832, 896, 960, 1024
 };
 
+static const uint16_t swb_offset_512_24[] = {
+      0,   4,   8,  12,  16,  20,  24,  28,
+     32,  36,  40,  44,  52,  60,  68,  80,
+     92, 104, 120, 140, 164, 192, 224, 256,
+    288, 320, 352, 384, 416, 448, 480, 512,
+};
+
 static const uint16_t swb_offset_128_24[] = {
      0,   4,   8,  12,  16,  20,  24,  28,
     36,  44,  52,  64,  76,  92, 108, 128
@@ -1179,6 +1207,14 @@ const uint16_t * const ff_swb_offset_1024[] = {
     swb_offset_1024_8
 };
 
+const uint16_t * const ff_swb_offset_512[] = {
+    NULL,               NULL,               NULL,
+    swb_offset_512_48,  swb_offset_512_48,  swb_offset_512_32,
+    swb_offset_512_24,  swb_offset_512_24,  NULL,
+    NULL,               NULL,               NULL,
+    NULL
+};
+
 const uint16_t * const ff_swb_offset_128[] = {
     /* The last entry on the following row is swb_offset_128_64 but is a
        duplicate of swb_offset_128_96. */
@@ -1205,3 +1241,486 @@ const uint8_t ff_tns_max_bands_128[] = {
     9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14
 };
 // @}
+
+const DECLARE_ALIGNED(32, float, ff_aac_eld_window)[1920] = {
+     0.00338834,  0.00567745,  0.00847677,  0.01172641,
+     0.01532555,  0.01917664,  0.02318809,  0.02729259,
+     0.03144503,  0.03560261,  0.03972499,  0.04379783,
+     0.04783094,  0.05183357,  0.05581342,  0.05977723,
+     0.06373173,  0.06768364,  0.07163937,  0.07559976,
+     0.07956096,  0.08352024,  0.08747623,  0.09143035,
+     0.09538618,  0.09934771,  0.10331917,  0.10730456,
+     0.11130697,  0.11532867,  0.11937133,  0.12343922,
+     0.12753911,  0.13167705,  0.13585812,  0.14008529,
+     0.14435986,  0.14868291,  0.15305531,  0.15747594,
+     0.16194193,  0.16645070,  0.17099991,  0.17558633,
+     0.18020600,  0.18485548,  0.18953191,  0.19423322,
+     0.19895800,  0.20370512,  0.20847374,  0.21326312,
+     0.21807244,  0.22290083,  0.22774742,  0.23261210,
+     0.23749542,  0.24239767,  0.24731889,  0.25225887,
+     0.25721719,  0.26219330,  0.26718648,  0.27219630,
+     0.27722262,  0.28226514,  0.28732336,  0.29239628,
+     0.29748247,  0.30258055,  0.30768914,  0.31280508,
+     0.31792385,  0.32304172,  0.32815579,  0.33326397,
+     0.33836470,  0.34345661,  0.34853868,  0.35361188,
+     0.35867865,  0.36374072,  0.36879900,  0.37385347,
+     0.37890349,  0.38394836,  0.38898730,  0.39401912,
+     0.39904236,  0.40405575,  0.40905820,  0.41404819,
+     0.41902398,  0.42398423,  0.42892805,  0.43385441,
+     0.43876210,  0.44365014,  0.44851786,  0.45336632,
+     0.45819759,  0.46301302,  0.46781309,  0.47259722,
+     0.47736435,  0.48211365,  0.48684450,  0.49155594,
+     0.49624679,  0.50091636,  0.50556440,  0.51019132,
+     0.51479771,  0.51938391,  0.52394998,  0.52849587,
+     0.53302151,  0.53752680,  0.54201160,  0.54647575,
+     0.55091916,  0.55534181,  0.55974376,  0.56412513,
+     0.56848615,  0.57282710,  0.57714834,  0.58145030,
+     0.58492489,  0.58918511,  0.59342326,  0.59763936,
+     0.60183347,  0.60600561,  0.61015581,  0.61428412,
+     0.61839056,  0.62247517,  0.62653799,  0.63057912,
+     0.63459872,  0.63859697,  0.64257403,  0.64653001,
+     0.65046495,  0.65437887,  0.65827181,  0.66214383,
+     0.66599499,  0.66982535,  0.67363499,  0.67742394,
+     0.68119219,  0.68493972,  0.68866653,  0.69237258,
+     0.69605778,  0.69972207,  0.70336537,  0.70698758,
+     0.71058862,  0.71416837,  0.71772674,  0.72126361,
+     0.72477889,  0.72827246,  0.73174419,  0.73519392,
+     0.73862141,  0.74202643,  0.74540874,  0.74876817,
+     0.75210458,  0.75541785,  0.75870785,  0.76197437,
+     0.76521709,  0.76843570,  0.77162988,  0.77479939,
+     0.77794403,  0.78106359,  0.78415789,  0.78722670,
+     0.79026979,  0.79328694,  0.79627791,  0.79924244,
+     0.80218027,  0.80509112,  0.80797472,  0.81083081,
+     0.81365915,  0.81645949,  0.81923160,  0.82197528,
+     0.82469037,  0.82737673,  0.83003419,  0.83266262,
+     0.83526186,  0.83783176,  0.84037217,  0.84288297,
+     0.84536401,  0.84781517,  0.85023632,  0.85262739,
+     0.85498836,  0.85731921,  0.85961993,  0.86189052,
+     0.86413101,  0.86634140,  0.86852173,  0.87067211,
+     0.87279275,  0.87488384,  0.87694559,  0.87897824,
+     0.88098206,  0.88295729,  0.88490423,  0.88682332,
+     0.88871519,  0.89058048,  0.89241983,  0.89423391,
+     0.89602338,  0.89778893,  0.89953126,  0.90125142,
+     0.90295086,  0.90463104,  0.90629341,  0.90793946,
+     0.90957067,  0.91118856,  0.91279464,  0.91439073,
+     0.91597898,  0.91756153,  0.91914049,  0.92071690,
+     0.92229070,  0.92386182,  0.92542993,  0.92698946,
+     0.92852960,  0.93003929,  0.93150727,  0.93291739,
+     0.93424863,  0.93547974,  0.93658982,  0.93756587,
+     0.93894072,  0.93922780,  0.93955477,  0.93991290,
+     0.94029104,  0.94067794,  0.94106258,  0.94144084,
+     0.94181549,  0.94218963,  0.94256628,  0.94294662,
+     0.94332998,  0.94371562,  0.94410280,  0.94449122,
+     0.94488106,  0.94527249,  0.94566568,  0.94606074,
+     0.94645772,  0.94685665,  0.94725759,  0.94766054,
+     0.94806547,  0.94847234,  0.94888115,  0.94929190,
+     0.94970469,  0.95011960,  0.95053672,  0.95095604,
+     0.95137751,  0.95180105,  0.95222658,  0.95265413,
+     0.95308380,  0.95351571,  0.95394994,  0.95438653,
+     0.95482538,  0.95526643,  0.95570958,  0.95615486,
+     0.95660234,  0.95705214,  0.95750433,  0.95795892,
+     0.95841582,  0.95887493,  0.95933616,  0.95979949,
+     0.96026500,  0.96073277,  0.96120286,  0.96167526,
+     0.96214986,  0.96262655,  0.96310522,  0.96358586,
+     0.96406853,  0.96455330,  0.96504026,  0.96552936,
+     0.96602051,  0.96651360,  0.96700850,  0.96750520,
+     0.96800376,  0.96850424,  0.96900670,  0.96951112,
+     0.97001738,  0.97052533,  0.97103488,  0.97154597,
+     0.97205867,  0.97257304,  0.97308915,  0.97360694,
+     0.97412631,  0.97464711,  0.97516923,  0.97569262,
+     0.97621735,  0.97674350,  0.97727111,  0.97780016,
+     0.97833051,  0.97886205,  0.97939463,  0.97992823,
+     0.98046291,  0.98099875,  0.98153580,  0.98207405,
+     0.98261337,  0.98315364,  0.98369474,  0.98423664,
+     0.98477941,  0.98532311,  0.98586780,  0.98641348,
+     0.98696003,  0.98750734,  0.98805530,  0.98860389,
+     0.98915320,  0.98970328,  0.99025423,  0.99080602,
+     0.99135855,  0.99191171,  0.99246541,  0.99301962,
+     0.99357443,  0.99412992,  0.99468617,  0.99524320,
+     0.99580092,  0.99635926,  0.99691814,  0.99747748,
+     0.99803721,  0.99859725,  0.99915752,  0.99971793,
+     1.00028215,  1.00084319,  1.00140472,  1.00196665,
+     1.00252889,  1.00309139,  1.00365404,  1.00421679,
+     1.00477954,  1.00534221,  1.00590474,  1.00646713,
+     1.00702945,  1.00759179,  1.00815424,  1.00871678,
+     1.00927930,  1.00984169,  1.01040384,  1.01096575,
+     1.01152747,  1.01208910,  1.01265070,  1.01321226,
+     1.01377365,  1.01433478,  1.01489551,  1.01545584,
+     1.01601582,  1.01657553,  1.01713502,  1.01769427,
+     1.01825316,  1.01881154,  1.01936929,  1.01992639,
+     1.02048289,  1.02103888,  1.02159441,  1.02214945,
+     1.02270387,  1.02325751,  1.02381025,  1.02436204,
+     1.02491295,  1.02546304,  1.02601238,  1.02656092,
+     1.02710853,  1.02765508,  1.02820041,  1.02874449,
+     1.02928737,  1.02982913,  1.03036981,  1.03090937,
+     1.03144768,  1.03198460,  1.03252000,  1.03305384,
+     1.03358617,  1.03411707,  1.03464659,  1.03517470,
+     1.03570128,  1.03622620,  1.03674934,  1.03727066,
+     1.03779024,  1.03830815,  1.03882446,  1.03933914,
+     1.03985206,  1.04036312,  1.04087217,  1.04137920,
+     1.04188428,  1.04238748,  1.04288888,  1.04338845,
+     1.04388610,  1.04438170,  1.04487515,  1.04536645,
+     1.04585569,  1.04634297,  1.04682838,  1.04731192,
+     1.04779350,  1.04827303,  1.04875042,  1.04922568,
+     1.04969891,  1.05017022,  1.05063974,  1.05110746,
+     1.05157332,  1.05203721,  1.05249907,  1.05295889,
+     1.05341676,  1.05387277,  1.05432700,  1.05477948,
+     1.05523018,  1.05567906,  1.05612608,  1.05657124,
+     1.05701459,  1.05745616,  1.05789601,  1.05833426,
+     1.05877109,  1.05920669,  1.05964125,  1.06007444,
+     1.06050542,  1.06093335,  1.06135746,  1.06177909,
+     1.06220164,  1.06262858,  1.06306309,  1.06350050,
+     1.06392837,  1.06433391,  1.06470443,  1.06502996,
+     1.06481076,  1.06469765,  1.06445004,  1.06408002,
+     1.06361382,  1.06307719,  1.06249453,  1.06188365,
+     1.06125612,  1.06062291,  1.05999418,  1.05937132,
+     1.05874726,  1.05811486,  1.05746728,  1.05680000,
+     1.05611070,  1.05539715,  1.05465735,  1.05389329,
+     1.05311083,  1.05231578,  1.05151372,  1.05070811,
+     1.04990044,  1.04909210,  1.04828434,  1.04747647,
+     1.04666590,  1.04585003,  1.04502628,  1.04419009,
+     1.04333499,  1.04245452,  1.04154244,  1.04059452,
+     1.03960846,  1.03858207,  1.03751326,  1.03640189,
+     1.03524976,  1.03405868,  1.03283047,  1.03156812,
+     1.03027574,  1.02895743,  1.02761717,  1.02625804,
+     1.02488222,  1.02349184,  1.02208892,  1.02067450,
+     1.01924861,  1.01781123,  1.01636229,  1.01490045,
+     1.01342315,  1.01192778,  1.01041175,  1.00887284,
+     1.00730915,  1.00571882,  1.00409996,  1.00245032,
+     1.00076734,  0.99904842,  0.99729101,  0.99549380,
+     0.99365664,  0.99177946,  0.98986234,  0.98791024,
+     0.98593294,  0.98394037,  0.98194226,  0.97994532,
+     0.97795324,  0.97596955,  0.97399748,  0.97203326,
+     0.97006624,  0.96808546,  0.96608018,  0.96404416,
+     0.96197556,  0.95987276,  0.95773420,  0.95556018,
+     0.95335291,  0.95111462,  0.94884764,  0.94655663,
+     0.94424858,  0.94193055,  0.93960953,  0.93729154,
+     0.93498157,  0.93268456,  0.93040503,  0.92813771,
+     0.92586755,  0.92357910,  0.92125731,  0.91889642,
+     0.91649998,  0.91407191,  0.91161623,  0.90913975,
+     0.90665202,  0.90416271,  0.90168115,  0.89920934,
+     0.89674189,  0.89427312,  0.89179743,  0.88931147,
+     0.88681415,  0.88430445,  0.88178141,  0.87924528,
+     0.87669753,  0.87413966,  0.87157318,  0.86899958,
+     0.86642037,  0.86383703,  0.86125106,  0.85866393,
+     0.85604236,  0.85344385,  0.85083093,  0.84820550,
+     0.84556943,  0.84292458,  0.84027278,  0.83761586,
+     0.83495565,  0.83229393,  0.82963243,  0.82697135,
+     0.82430933,  0.82164496,  0.81897669,  0.81630017,
+     0.81360822,  0.81089355,  0.80814924,  0.80537741,
+     0.80258920,  0.79979611,  0.79700954,  0.79423813,
+     0.79148780,  0.78876432,  0.78607290,  0.78340590,
+     0.78074288,  0.77806279,  0.77534514,  0.77258187,
+     0.76977737,  0.76693654,  0.76406441,  0.76116851,
+     0.75825892,  0.75534582,  0.75243924,  0.74954634,
+     0.74667135,  0.74381840,  0.74099145,  0.73819147,
+     0.73541641,  0.73266408,  0.72993193,  0.72720913,
+     0.72447661,  0.72171494,  0.71890515,  0.71603932,
+     0.71312056,  0.71015250,  0.70713900,  0.70409084,
+     0.70102565,  0.69796137,  0.69491556,  0.69189772,
+     0.68890931,  0.68595141,  0.68302498,  0.68012852,
+     0.67725801,  0.67440936,  0.67157841,  0.66876081,
+     0.66595195,  0.66314722,  0.66034194,  0.65753027,
+     0.65470525,  0.65185984,  0.64898709,  0.64608214,
+     0.64314221,  0.64016460,  0.63714680,  0.63409034,
+     0.63100082,  0.62788400,  0.62474577,  0.62159473,
+     0.61844225,  0.61529977,  0.61217866,  0.60908811,
+     0.60603510,  0.60302654,  0.60006916,  0.59716588,
+     0.59431580,  0.59151787,  0.58877068,  0.58606495,
+     0.58338353,  0.58070891,  0.57802356,  0.57530864,
+     0.57254404,  0.56970958,  0.56678577,  0.56376860,
+     0.56066951,  0.55750064,  0.55427451,  0.55101301,
+     0.54774732,  0.54450907,  0.54132936,  0.53822744,
+     0.53521072,  0.53228613,  0.52945979,  0.52671997,
+     0.52403708,  0.52138072,  0.51872085,  0.51603570,
+     0.51331170,  0.51053560,  0.50769466,  0.50478931,
+     0.50183308,  0.49884001,  0.49582406,  0.49279905,
+     0.48985748,  0.48679641,  0.48379429,  0.48085363,
+     0.47796576,  0.47512151,  0.47231151,  0.46952402,
+     0.46674486,  0.46395978,  0.46115496,  0.45832607,
+     0.45547830,  0.45261727,  0.44974866,  0.44688011,
+     0.44402125,  0.44118178,  0.43837094,  0.43558772,
+     0.43282082,  0.43005847,  0.42728913,  0.42450572,
+     0.42170567,  0.41888658,  0.41604633,  0.41318897,
+     0.41032472,  0.40746405,  0.40461724,  0.40178943,
+     0.39898066,  0.39619073,  0.39341940,  0.39066519,
+     0.38792536,  0.38519713,  0.38247773,  0.37976476,
+     0.37705620,  0.37435006,  0.37164438,  0.36893869,
+     0.36623396,  0.36353124,  0.36083153,  0.35813533,
+     0.35544262,  0.35275338,  0.35006755,  0.34738530,
+     0.34470699,  0.34203296,  0.33936359,  0.33669922,
+     0.33404027,  0.33138711,  0.32874013,  0.32609944,
+     0.32346493,  0.32083645,  0.31821388,  0.31559703,
+     0.31298573,  0.31037987,  0.30777941,  0.30518446,
+     0.30259525,  0.30001202,  0.29743499,  0.29486428,
+     0.29229989,  0.28974179,  0.28718997,  0.28464452,
+     0.28210562,  0.27957346,  0.27704820,  0.27452992,
+     0.27201854,  0.26951399,  0.26701622,  0.26452533,
+     0.26204158,  0.25956526,  0.25709662,  0.25463583,
+     0.25218294,  0.24973798,  0.24730100,  0.24487207,
+     0.24245133,  0.24003893,  0.23763500,  0.23523959,
+     0.23285262,  0.23047401,  0.22810369,  0.22574170,
+     0.22338818,  0.22104329,  0.21870719,  0.21637986,
+     0.21406117,  0.21175095,  0.20944904,  0.20715535,
+     0.20486987,  0.20259261,  0.20032356,  0.19806259,
+     0.19580944,  0.19356385,  0.19132556,  0.18909442,
+     0.18687040,  0.18465350,  0.18244372,  0.18024164,
+     0.17804841,  0.17586521,  0.17369322,  0.17153360,
+     0.16938755,  0.16725622,  0.16514081,  0.16304247,
+     0.16098974,  0.15896561,  0.15696026,  0.15497259,
+     0.15300151,  0.15104590,  0.14910466,  0.14717666,
+     0.14526081,  0.14335599,  0.14146111,  0.13957570,
+     0.13769993,  0.13583399,  0.13397806,  0.13213229,
+     0.13029682,  0.12847178,  0.12665729,  0.12485353,
+     0.12306074,  0.12127916,  0.11950900,  0.11775043,
+     0.11600347,  0.11426820,  0.11254464,  0.11083292,
+     0.10913318,  0.10744559,  0.10577028,  0.10410733,
+     0.10245672,  0.10081842,  0.09919240,  0.09757872,
+     0.09597750,  0.09438884,  0.09281288,  0.09124964,
+     0.08969907,  0.08816111,  0.08663570,  0.08512288,
+     0.08362274,  0.08213540,  0.08066096,  0.07919944,
+     0.07775076,  0.07631484,  0.07489161,  0.07348108,
+     0.07208335,  0.07069851,  0.06932666,  0.06796781,
+     0.06662187,  0.06528874,  0.06396833,  0.06266065,
+     0.06136578,  0.06008380,  0.05881480,  0.05755876,
+     0.05631557,  0.05508511,  0.05386728,  0.05266206,
+     0.05146951,  0.05028971,  0.04912272,  0.04796855,
+     0.04682709,  0.04569825,  0.04458194,  0.04347817,
+     0.04238704,  0.04130868,  0.04024318,  0.03919056,
+     0.03815071,  0.03712352,  0.03610890,  0.03510679,
+     0.03411720,  0.03314013,  0.03217560,  0.03122343,
+     0.03028332,  0.02935494,  0.02843799,  0.02753230,
+     0.02663788,  0.02575472,  0.02488283,  0.02402232,
+     0.02317341,  0.02233631,  0.02151124,  0.02069866,
+     0.01989922,  0.01911359,  0.01834241,  0.01758563,
+     0.01684248,  0.01611219,  0.01539397,  0.01468726,
+     0.01399167,  0.01330687,  0.01263250,  0.01196871,
+     0.01131609,  0.01067527,  0.01004684,  0.00943077,
+     0.00882641,  0.00823307,  0.00765011,  0.00707735,
+     0.00651513,  0.00596377,  0.00542364,  0.00489514,
+     0.00437884,  0.00387530,  0.00338509,  0.00290795,
+     0.00244282,  0.00198860,  0.00154417,  0.00110825,
+     0.00067934,  0.00025589, -0.00016357, -0.00057897,
+    -0.00098865, -0.00139089, -0.00178397, -0.00216547,
+    -0.00253230, -0.00288133, -0.00320955, -0.00351626,
+    -0.00380315, -0.00407198, -0.00432457, -0.00456373,
+    -0.00479326, -0.00501699, -0.00523871, -0.00546066,
+    -0.00568360, -0.00590821, -0.00613508, -0.00636311,
+    -0.00658944, -0.00681117, -0.00702540, -0.00722982,
+    -0.00742268, -0.00760226, -0.00776687, -0.00791580,
+    -0.00804933, -0.00816774, -0.00827139, -0.00836122,
+    -0.00843882, -0.00850583, -0.00856383, -0.00861430,
+    -0.00865853, -0.00869781, -0.00873344, -0.00876633,
+    -0.00879707, -0.00882622, -0.00885433, -0.00888132,
+    -0.00890652, -0.00892925, -0.00894881, -0.00896446,
+    -0.00897541, -0.00898088, -0.00898010, -0.00897234,
+    -0.00895696, -0.00893330, -0.00890076, -0.00885914,
+    -0.00880875, -0.00874987, -0.00868282, -0.00860825,
+    -0.00852716, -0.00844055, -0.00834941, -0.00825485,
+    -0.00815807, -0.00806025, -0.00796253, -0.00786519,
+    -0.00776767, -0.00766937, -0.00756971, -0.00746790,
+    -0.00736305, -0.00725422, -0.00714055, -0.00702161,
+    -0.00689746, -0.00676816, -0.00663381, -0.00649489,
+    -0.00635230, -0.00620694, -0.00605969, -0.00591116,
+    -0.00576167, -0.00561155, -0.00546110, -0.00531037,
+    -0.00515917, -0.00500732, -0.00485462, -0.00470075,
+    -0.00454530, -0.00438786, -0.00422805, -0.00406594,
+    -0.00390204, -0.00373686, -0.00357091, -0.00340448,
+    -0.00323770, -0.00307066, -0.00290344, -0.00273610,
+    -0.00256867, -0.00240117, -0.00223365, -0.00206614,
+    -0.00189866, -0.00173123, -0.00156390, -0.00139674,
+    -0.00122989, -0.00106351, -0.00089772, -0.00073267,
+    -0.00056849, -0.00040530, -0.00024324, -0.00008241,
+     0.00008214,  0.00024102,  0.00039922,  0.00055660,
+     0.00071299,  0.00086826,  0.00102224,  0.00117480,
+     0.00132579,  0.00147507,  0.00162252,  0.00176804,
+     0.00191161,  0.00205319,  0.00219277,  0.00233029,
+     0.00246567,  0.00259886,  0.00272975,  0.00285832,
+     0.00298453,  0.00310839,  0.00322990,  0.00334886,
+     0.00346494,  0.00357778,  0.00368706,  0.00379273,
+     0.00389501,  0.00399411,  0.00409020,  0.00418350,
+     0.00427419,  0.00436249,  0.00444858,  0.00453250,
+     0.00461411,  0.00469328,  0.00476988,  0.00484356,
+     0.00491375,  0.00497987,  0.00504139,  0.00509806,
+     0.00514990,  0.00519693,  0.00523920,  0.00527700,
+     0.00531083,  0.00534122,  0.00536864,  0.00539357,
+     0.00541649,  0.00543785,  0.00545809,  0.00547713,
+     0.00549441,  0.00550936,  0.00552146,  0.00553017,
+     0.00553494,  0.00553524,  0.00553058,  0.00552065,
+     0.00550536,  0.00548459,  0.00545828,  0.00542662,
+     0.00539007,  0.00534910,  0.00530415,  0.00525568,
+     0.00520417,  0.00515009,  0.00509387,  0.00503595,
+     0.00497674,  0.00491665,  0.00485605,  0.00479503,
+     0.00473336,  0.00467082,  0.00460721,  0.00454216,
+     0.00447517,  0.00440575,  0.00433344,  0.00425768,
+     0.00417786,  0.00409336,  0.00400363,  0.00390837,
+     0.00380759,  0.00370130,  0.00358952,  0.00347268,
+     0.00335157,  0.00322699,  0.00309975,  0.00297088,
+     0.00284164,  0.00271328,  0.00258700,  0.00246328,
+     0.00234195,  0.00222281,  0.00210562,  0.00198958,
+     0.00187331,  0.00175546,  0.00163474,  0.00151020,
+     0.00138130,  0.00124750,  0.00110831,  0.00096411,
+     0.00081611,  0.00066554,  0.00051363,  0.00036134,
+     0.00020940,  0.00005853, -0.00009058, -0.00023783,
+    -0.00038368, -0.00052861, -0.00067310, -0.00081757,
+    -0.00096237, -0.00110786, -0.00125442, -0.00140210,
+    -0.00155065, -0.00169984, -0.00184940, -0.00199910,
+    -0.00214872, -0.00229798, -0.00244664, -0.00259462,
+    -0.00274205, -0.00288912, -0.00303596, -0.00318259,
+    -0.00332890, -0.00347480, -0.00362024, -0.00376519,
+    -0.00390962, -0.00405345, -0.00419658, -0.00433902,
+    -0.00448085, -0.00462219, -0.00476309, -0.00490357,
+    -0.00504361, -0.00518321, -0.00532243, -0.00546132,
+    -0.00559988, -0.00573811, -0.00587602, -0.00601363,
+    -0.00615094, -0.00628795, -0.00642466, -0.00656111,
+    -0.00669737, -0.00683352, -0.00696963, -0.00710578,
+    -0.00724208, -0.00737862, -0.00751554, -0.00765295,
+    -0.00779098, -0.00792976, -0.00806941, -0.00821006,
+    -0.00835183, -0.00849485, -0.00863926, -0.00878522,
+    -0.00893293, -0.00908260, -0.00923444, -0.00938864,
+    -0.00954537, -0.00970482, -0.00986715, -0.01003173,
+    -0.01019711, -0.01036164, -0.01052357, -0.01068184,
+    -0.01083622, -0.01098652, -0.01113252, -0.01127409,
+    -0.01141114, -0.01154358, -0.01167135, -0.01179439,
+    -0.01191268, -0.01202619, -0.01213493, -0.01223891,
+    -0.01233817, -0.01243275, -0.01252272, -0.01260815,
+    -0.01268915, -0.01276583, -0.01283832, -0.01290685,
+    -0.01297171, -0.01303320, -0.01309168, -0.01314722,
+    -0.01319969, -0.01324889, -0.01329466, -0.01333693,
+    -0.01337577, -0.01341125, -0.01344345, -0.01347243,
+    -0.01349823, -0.01352089, -0.01354045, -0.01355700,
+    -0.01357068, -0.01358164, -0.01359003, -0.01359587,
+    -0.01359901, -0.01359931, -0.01359661, -0.01359087,
+    -0.01358219, -0.01357065, -0.01355637, -0.01353935,
+    -0.01351949, -0.01349670, -0.01347088, -0.01344214,
+    -0.01341078, -0.01337715, -0.01334158, -0.01330442,
+    -0.01326601, -0.01322671, -0.01318689, -0.01314692,
+    -0.01310123, -0.01306470, -0.01302556, -0.01298381,
+    -0.01293948, -0.01289255, -0.01284305, -0.01279095,
+    -0.01273625, -0.01267893, -0.01261897, -0.01255632,
+    -0.01249096, -0.01242283, -0.01235190, -0.01227827,
+    -0.01220213, -0.01212366, -0.01204304, -0.01196032,
+    -0.01187543, -0.01178829, -0.01169884, -0.01160718,
+    -0.01151352, -0.01141809, -0.01132111, -0.01122272,
+    -0.01112304, -0.01102217, -0.01092022, -0.01081730,
+    -0.01071355, -0.01060912, -0.01050411, -0.01039854,
+    -0.01029227, -0.01018521, -0.01007727, -0.00996859,
+    -0.00985959, -0.00975063, -0.00964208, -0.00953420,
+    -0.00942723, -0.00932135, -0.00921677, -0.00911364,
+    -0.00901208, -0.00891220, -0.00881412, -0.00871792,
+    -0.00862369, -0.00853153, -0.00844149, -0.00835360,
+    -0.00826785, -0.00818422, -0.00810267, -0.00802312,
+    -0.00794547, -0.00786959, -0.00779533, -0.00772165,
+    -0.00764673, -0.00756886, -0.00748649, -0.00739905,
+    -0.00730681, -0.00721006, -0.00710910, -0.00700419,
+    -0.00689559, -0.00678354, -0.00666829, -0.00655007,
+    -0.00642916, -0.00630579, -0.00618022, -0.00605267,
+    -0.00592333, -0.00579240, -0.00566006, -0.00552651,
+    -0.00539194, -0.00525653, -0.00512047, -0.00498390,
+    -0.00484693, -0.00470969, -0.00457228, -0.00443482,
+    -0.00429746, -0.00416034, -0.00402359, -0.00388738,
+    -0.00375185, -0.00361718, -0.00348350, -0.00335100,
+    -0.00321991, -0.00309043, -0.00296276, -0.00283698,
+    -0.00271307, -0.00259098, -0.00247066, -0.00235210,
+    -0.00223531, -0.00212030, -0.00200709, -0.00189576,
+    -0.00178647, -0.00167936, -0.00157457, -0.00147216,
+    -0.00137205, -0.00127418, -0.00117849, -0.00108498,
+    -0.00099375, -0.00090486, -0.00081840, -0.00073444,
+    -0.00065309, -0.00057445, -0.00049860, -0.00042551,
+    -0.00035503, -0.00028700, -0.00022125, -0.00015761,
+    -0.00009588, -0.00003583,  0.00002272,  0.00007975,
+     0.00013501,  0.00018828,  0.00023933,  0.00028784,
+     0.00033342,  0.00037572,  0.00041438,  0.00044939,
+     0.00048103,  0.00050958,  0.00053533,  0.00055869,
+     0.00058015,  0.00060022,  0.00061935,  0.00063781,
+     0.00065568,  0.00067303,  0.00068991,  0.00070619,
+     0.00072155,  0.00073567,  0.00074826,  0.00075912,
+     0.00076811,  0.00077509,  0.00077997,  0.00078275,
+     0.00078351,  0.00078237,  0.00077943,  0.00077484,
+     0.00076884,  0.00076160,  0.00075335,  0.00074423,
+     0.00073442,  0.00072404,  0.00071323,  0.00070209,
+     0.00069068,  0.00067906,  0.00066728,  0.00065534,
+     0.00064321,  0.00063086,  0.00061824,  0.00060534,
+     0.00059211,  0.00057855,  0.00056462,  0.00055033,
+     0.00053566,  0.00052063,  0.00050522,  0.00048949,
+     0.00047349,  0.00045728,  0.00044092,  0.00042447,
+     0.00040803,  0.00039166,  0.00037544,  0.00035943,
+     0.00034371,  0.00032833,  0.00031333,  0.00029874,
+     0.00028452,  0.00027067,  0.00025715,  0.00024395,
+     0.00023104,  0.00021842,  0.00020606,  0.00019398,
+     0.00018218,  0.00017069,  0.00015953,  0.00014871,
+     0.00013827,  0.00012823,  0.00011861,  0.00010942,
+     0.00010067,  0.00009236,  0.00008448,  0.00007703,
+     0.00006999,  0.00006337,  0.00005714,  0.00005129,
+     0.00004583,  0.00004072,  0.00003597,  0.00003157,
+     0.00002752,  0.00002380,  0.00002042,  0.00001736,
+     0.00001461,  0.00001215,  0.00000998,  0.00000807,
+     0.00000641,  0.00000499,  0.00000378,  0.00000278,
+     0.00000196,  0.00000132,  0.00000082,  0.00000046,
+     0.00000020,  0.00000005, -0.00000003, -0.00000006,
+    -0.00000004, -0.00000001,  0.00000001,  0.00000001,
+     0.00000001,  0.00000001, -0.00000001, -0.00000004,
+    -0.00000005, -0.00000003,  0.00000005,  0.00000020,
+     0.00000043,  0.00000077,  0.00000123,  0.00000183,
+     0.00000257,  0.00000348,  0.00000455,  0.00000581,
+     0.00000727,  0.00000893,  0.00001080,  0.00001290,
+     0.00001522,  0.00001778,  0.00002057,  0.00002362,
+     0.00002691,  0.00003044,  0.00003422,  0.00003824,
+     0.00004250,  0.00004701,  0.00005176,  0.00005676,
+     0.00006200,  0.00006749,  0.00007322,  0.00007920,
+     0.00008541,  0.00009186,  0.00009854,  0.00010543,
+     0.00011251,  0.00011975,  0.00012714,  0.00013465,
+     0.00014227,  0.00014997,  0.00015775,  0.00016558,
+     0.00017348,  0.00018144,  0.00018947,  0.00019756,
+     0.00020573,  0.00021399,  0.00022233,  0.00023076,
+     0.00023924,  0.00024773,  0.00025621,  0.00026462,
+     0.00027293,  0.00028108,  0.00028904,  0.00029675,
+     0.00030419,  0.00031132,  0.00031810,  0.00032453,
+     0.00033061,  0.00033632,  0.00034169,  0.00034672,
+     0.00035142,  0.00035580,  0.00035988,  0.00036369,
+     0.00036723,  0.00037053,  0.00037361,  0.00037647,
+     0.00037909,  0.00038145,  0.00038352,  0.00038527,
+     0.00038663,  0.00038757,  0.00038801,  0.00038790,
+     0.00038717,  0.00038572,  0.00038350,  0.00038044,
+     0.00037651,  0.00037170,  0.00036597,  0.00035936,
+     0.00035191,  0.00034370,  0.00033480,  0.00032531,
+     0.00031537,  0.00030512,  0.00029470,  0.00028417,
+     0.00027354,  0.00026279,  0.00025191,  0.00024081,
+     0.00022933,  0.00021731,  0.00020458,  0.00019101,
+     0.00017654,  0.00016106,  0.00014452,  0.00012694,
+     0.00010848,  0.00008929,  0.00006953,  0.00004935,
+     0.00002884,  0.00000813, -0.00001268, -0.00003357,
+    -0.00005457, -0.00007574, -0.00009714, -0.00011882,
+    -0.00014082, -0.00016318, -0.00018595, -0.00020912,
+    -0.00023265, -0.00025650, -0.00028060, -0.00030492,
+    -0.00032941, -0.00035400, -0.00037865, -0.00040333,
+    -0.00042804, -0.00045279, -0.00047759, -0.00050243,
+    -0.00052728, -0.00055209, -0.00057685, -0.00060153,
+    -0.00062611, -0.00065056, -0.00067485, -0.00069895,
+    -0.00072287, -0.00074660, -0.00077013, -0.00079345,
+    -0.00081653, -0.00083936, -0.00086192, -0.00088421,
+    -0.00090619, -0.00092786, -0.00094919, -0.00097017,
+    -0.00099077, -0.00101098, -0.00103077, -0.00105012,
+    -0.00106904, -0.00108750, -0.00110549, -0.00112301,
+    -0.00114005, -0.00115660, -0.00117265, -0.00118821,
+    -0.00120325, -0.00121779, -0.00123180, -0.00124528,
+    -0.00125822, -0.00127061, -0.00128243, -0.00129368,
+    -0.00130435, -0.00131445, -0.00132395, -0.00133285,
+    -0.00134113, -0.00134878, -0.00135577, -0.00136215,
+    -0.00136797, -0.00137333, -0.00137834, -0.00138305,
+    -0.00138748, -0.00139163, -0.00139551, -0.00139913,
+    -0.00140249, -0.00140559, -0.00140844, -0.00141102,
+    -0.00141334, -0.00141538, -0.00141714, -0.00141861,
+    -0.00141978, -0.00142064, -0.00142117, -0.00142138,
+    -0.00142125, -0.00142077, -0.00141992, -0.00141870,
+    -0.00141710, -0.00141510, -0.00141268, -0.00140986,
+    -0.00140663, -0.00140301, -0.00139900, -0.00139460,
+    -0.00138981, -0.00138464, -0.00137908, -0.00137313,
+    -0.00136680, -0.00136010, -0.00135301, -0.00134555,
+    -0.00133772, -0.00132952, -0.00132095, -0.00131201,
+    -0.00130272, -0.00129307, -0.00128309, -0.00127277,
+    -0.00126211, -0.00125113, -0.00123981, -0.00122817,
+    -0.00121622, -0.00120397, -0.00119141, -0.00117859,
+    -0.00116552, -0.00115223, -0.00113877, -0.00112517,
+    -0.00111144, -0.00109764, -0.00108377, -0.00106989,
+};
diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h
index 56e5796..a2dc46b 100644
--- a/libavcodec/aactab.h
+++ b/libavcodec/aactab.h
@@ -45,13 +45,16 @@
  * @{
  */
 DECLARE_ALIGNED(32, extern float,  ff_aac_kbd_long_1024)[1024];
+DECLARE_ALIGNED(32, extern float,  ff_aac_kbd_long_512 )[512];
 DECLARE_ALIGNED(32, extern float,  ff_aac_kbd_short_128)[128];
+const DECLARE_ALIGNED(32, extern float, ff_aac_eld_window)[1920];
 // @}
 
 /* @name number of scalefactor window bands for long and short transform windows respectively
  * @{
  */
 extern const uint8_t ff_aac_num_swb_1024[];
+extern const uint8_t ff_aac_num_swb_512 [];
 extern const uint8_t ff_aac_num_swb_128 [];
 // @}
 
@@ -69,6 +72,7 @@ extern const float *ff_aac_codebook_vector_vals[];
 extern const uint16_t *ff_aac_codebook_vector_idx[];
 
 extern const uint16_t * const ff_swb_offset_1024[13];
+extern const uint16_t * const ff_swb_offset_512 [13];
 extern const uint16_t * const ff_swb_offset_128 [13];
 
 extern const uint8_t ff_tns_max_bands_1024[13];
diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c
index 7063cbe..468e394 100644
--- a/libavcodec/aasc.c
+++ b/libavcodec/aasc.c
@@ -29,13 +29,13 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "msrledec.h"
 
 typedef struct AascContext {
     AVCodecContext *avctx;
     GetByteContext gb;
-    AVFrame frame;
+    AVFrame *frame;
 } AascContext;
 
 static av_cold int aasc_decode_init(AVCodecContext *avctx)
@@ -46,6 +46,10 @@ static av_cold int aasc_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_BGR24;
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
@@ -56,13 +60,14 @@ static int aasc_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     AascContext *s     = avctx->priv_data;
-    int compr, i, stride;
+    int compr, i, stride, ret;
+
+    if (buf_size < 4)
+        return AVERROR_INVALIDDATA;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     compr     = AV_RL32(buf);
@@ -71,22 +76,25 @@ static int aasc_decode_frame(AVCodecContext *avctx,
     switch (compr) {
     case 0:
         stride = (avctx->width * 3 + 3) & ~3;
+        if (buf_size < stride * avctx->height)
+            return AVERROR_INVALIDDATA;
         for (i = avctx->height - 1; i >= 0; i--) {
-            memcpy(s->frame.data[0] + i * s->frame.linesize[0], buf, avctx->width * 3);
+            memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * 3);
             buf += stride;
         }
         break;
     case 1:
         bytestream2_init(&s->gb, buf, buf_size);
-        ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb);
+        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;
+        return AVERROR_INVALIDDATA;
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -96,15 +104,14 @@ static av_cold int aasc_decode_end(AVCodecContext *avctx)
 {
     AascContext *s = avctx->priv_data;
 
-    /* release the last frame */
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_aasc_decoder = {
     .name           = "aasc",
+    .long_name      = NULL_IF_CONFIG_SMALL("Autodesk RLE"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_AASC,
     .priv_data_size = sizeof(AascContext),
@@ -112,5 +119,4 @@ AVCodec ff_aasc_decoder = {
     .close          = aasc_decode_end,
     .decode         = aasc_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Autodesk RLE"),
 };
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 51ac334..e1c6962 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -29,6 +29,7 @@
 #include <math.h>
 #include <string.h>
 
+#include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
 #include "libavutil/opt.h"
 #include "internal.h"
@@ -170,6 +171,7 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
     ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
     ff_kbd_window_init(s->window, 5.0, 256);
     ff_dsputil_init(&s->dsp, avctx);
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_fmt_convert_init(&s->fmt_conv, avctx);
     av_lfg_init(&s->dith_state, 0);
@@ -177,16 +179,22 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     /* allow downmixing to stereo or mono */
-    if (avctx->channels > 0 && avctx->request_channels > 0 &&
-            avctx->request_channels < avctx->channels &&
-            avctx->request_channels <= 2) {
-        avctx->channels = avctx->request_channels;
-    }
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->request_channels == 1)
+        avctx->request_channel_layout = AV_CH_LAYOUT_MONO;
+    else if (avctx->request_channels == 2)
+        avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    if (avctx->channels > 1 &&
+        avctx->request_channel_layout == AV_CH_LAYOUT_MONO)
+        avctx->channels = 1;
+    else if (avctx->channels > 2 &&
+             avctx->request_channel_layout == AV_CH_LAYOUT_STEREO)
+        avctx->channels = 2;
     s->downmixed = 1;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     for (i = 0; i < AC3_MAX_CHANNELS; i++) {
         s->xcfptr[i] = s->transform_coeffs[i];
         s->dlyptr[i] = s->delay[i];
@@ -253,7 +261,6 @@ static int parse_frame_header(AC3DecodeContext *s)
     s->bit_alloc_params.sr_code     = hdr.sr_code;
     s->bitstream_mode               = hdr.bitstream_mode;
     s->channel_mode                 = hdr.channel_mode;
-    s->channel_layout               = hdr.channel_layout;
     s->lfe_on                       = hdr.lfe_on;
     s->bit_alloc_params.sr_shift    = hdr.sr_shift;
     s->sample_rate                  = hdr.sample_rate;
@@ -431,7 +438,7 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma
     int end_freq   = s->end_freq[ch_index];
     uint8_t *baps  = s->bap[ch_index];
     int8_t *exps   = s->dexps[ch_index];
-    int *coeffs    = s->fixed_coeffs[ch_index];
+    int32_t *coeffs = s->fixed_coeffs[ch_index];
     int dither     = (ch_index == CPL_CH) || s->dither_flag[ch_index];
     GetBitContext *gbc = &s->gbc;
     int freq;
@@ -441,8 +448,9 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma
         int mantissa;
         switch (bap) {
         case 0:
+            /* random noise with approximate range of -0.707 to 0.707 */
             if (dither)
-                mantissa = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
+                mantissa = (av_lfg_get(&s->dith_state) / 362) - 5932275;
             else
                 mantissa = 0;
             break;
@@ -606,15 +614,15 @@ static inline void do_imdct(AC3DecodeContext *s, int channels)
             for (i = 0; i < 128; i++)
                 x[i] = s->transform_coeffs[ch][2 * i];
             s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
-            s->dsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
-                                      s->tmp_output, s->window, 128);
+            s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+                                       s->tmp_output, s->window, 128);
             for (i = 0; i < 128; i++)
                 x[i] = s->transform_coeffs[ch][2 * i + 1];
             s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x);
         } else {
             s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
-            s->dsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
-                                      s->tmp_output, s->window, 128);
+            s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+                                       s->tmp_output, s->window, 128);
             memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(float));
         }
     }
@@ -748,8 +756,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
     i = !s->channel_mode;
     do {
         if (get_bits1(gbc)) {
-            s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)] - 1.0) *
-                                  s->drc_scale) + 1.0;
+            s->dynamic_range[i] = powf(dynamic_range_tab[get_bits(gbc, 8)],
+                                       s->drc_scale);
         } else if (blk == 0) {
             s->dynamic_range[i] = 1.0f;
         }
@@ -875,7 +883,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
             /* check for enhanced coupling */
             if (s->eac3 && get_bits1(gbc)) {
                 /* TODO: parse enhanced coupling strategy info */
-                av_log_missing_feature(s->avctx, "Enhanced coupling", 1);
+                avpriv_request_sample(s->avctx, "Enhanced coupling");
                 return AVERROR_PATCHWELCOME;
             }
 
@@ -1265,6 +1273,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
 static int ac3_decode_frame(AVCodecContext * avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     AC3DecodeContext *s = avctx->priv_data;
@@ -1330,6 +1339,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
             if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2],
                        s->frame_size - 2)) {
                 av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n");
+                if (avctx->err_recognition & AV_EF_EXPLODE)
+                    return AVERROR_INVALIDDATA;
                 err = AAC_AC3_PARSE_ERROR_CRC;
             }
         }
@@ -1347,14 +1358,15 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
         s->output_mode  = s->channel_mode;
         if (s->lfe_on)
             s->output_mode |= AC3_OUTPUT_LFEON;
-        if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
-                avctx->request_channels < s->channels) {
-            s->out_channels = avctx->request_channels;
-            s->output_mode  = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO;
-            s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode];
+        if (s->channels > 1 &&
+            avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
+            s->out_channels = 1;
+            s->output_mode  = AC3_CHMODE_MONO;
+        } else if (s->channels > 2 &&
+                   avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+            s->out_channels = 2;
+            s->output_mode  = AC3_CHMODE_STEREO;
         }
-        avctx->channels       = s->out_channels;
-        avctx->channel_layout = s->channel_layout;
 
         /* set downmixing coefficients if needed */
         if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
@@ -1366,6 +1378,9 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
     avctx->channels = s->out_channels;
+    avctx->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON];
+    if (s->output_mode & AC3_OUTPUT_LFEON)
+        avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
 
     /* set audio service type based on bitstream mode for AC-3 */
     avctx->audio_service_type = s->bitstream_mode;
@@ -1373,8 +1388,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
         avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
 
     /* get output buffer */
-    s->frame.nb_samples = s->num_blocks * 256;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -1383,7 +1398,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
     channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
     for (ch = 0; ch < s->channels; ch++) {
         if (ch < s->out_channels)
-            s->outptr[channel_map[ch]] = (float *)s->frame.data[ch];
+            s->outptr[channel_map[ch]] = (float *)frame->data[ch];
         else
             s->outptr[ch] = s->output[ch];
         output[ch] = s->output[ch];
@@ -1395,19 +1410,18 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
         }
         if (err)
             for (ch = 0; ch < s->out_channels; ch++)
-                memcpy(s->outptr[channel_map[ch]], output[ch], 1024);
+                memcpy(s->outptr[channel_map[ch]], output[ch], sizeof(**output) * AC3_BLOCK_SIZE);
         for (ch = 0; ch < s->out_channels; ch++)
             output[ch] = s->outptr[channel_map[ch]];
-        for (ch = 0; ch < s->channels; ch++)
+        for (ch = 0; ch < s->out_channels; ch++)
             s->outptr[ch] += AC3_BLOCK_SIZE;
     }
 
     /* keep last block for error concealment in next frame */
     for (ch = 0; ch < s->out_channels; ch++)
-        memcpy(s->output[ch], output[ch], 1024);
+        memcpy(s->output[ch], output[ch], sizeof(**output) * AC3_BLOCK_SIZE);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return FFMIN(buf_size, s->frame_size);
 }
@@ -1440,6 +1454,7 @@ static const AVClass ac3_decoder_class = {
 
 AVCodec ff_ac3_decoder = {
     .name           = "ac3",
+    .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AC3,
     .priv_data_size = sizeof (AC3DecodeContext),
@@ -1447,7 +1462,6 @@ AVCodec ff_ac3_decoder = {
     .close          = ac3_decode_end,
     .decode         = ac3_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class     = &ac3_decoder_class,
@@ -1463,6 +1477,7 @@ static const AVClass eac3_decoder_class = {
 
 AVCodec ff_eac3_decoder = {
     .name           = "eac3",
+    .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_EAC3,
     .priv_data_size = sizeof (AC3DecodeContext),
@@ -1470,7 +1485,6 @@ AVCodec ff_eac3_decoder = {
     .close          = ac3_decode_end,
     .decode         = ac3_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class     = &eac3_decoder_class,
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index 1e8ee68..7b4a528 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -50,6 +50,7 @@
 #ifndef AVCODEC_AC3DEC_H
 #define AVCODEC_AC3DEC_H
 
+#include "libavutil/float_dsp.h"
 #include "libavutil/lfg.h"
 #include "ac3.h"
 #include "ac3dsp.h"
@@ -68,7 +69,6 @@
 typedef struct AC3DecodeContext {
     AVClass        *class;                  ///< class for AVOptions
     AVCodecContext *avctx;                  ///< parent context
-    AVFrame frame;                          ///< AVFrame for decoded output
     GetBitContext gbc;                      ///< bitstream reader
 
 ///@name Bit stream information
@@ -81,7 +81,6 @@ typedef struct AC3DecodeContext {
     int num_blocks;                         ///< number of audio blocks
     int bitstream_mode;                     ///< bitstream mode                         (bsmod)
     int channel_mode;                       ///< channel mode                           (acmod)
-    int channel_layout;                     ///< channel layout
     int lfe_on;                             ///< lfe channel in use
     int channel_map;                        ///< custom channel map
     int center_mix_level;                   ///< Center mix level index
@@ -193,6 +192,7 @@ typedef struct AC3DecodeContext {
 
 ///@name Optimization
     DSPContext dsp;                         ///< for optimization
+    AVFloatDSPContext fdsp;
     AC3DSPContext ac3dsp;
     FmtConvertContext fmt_conv;             ///< optimized conversion functions
 ///@}
@@ -202,7 +202,7 @@ typedef struct AC3DecodeContext {
     float *dlyptr[AC3_MAX_CHANNELS];
 
 ///@name Aligned arrays
-    DECLARE_ALIGNED(16, int,   fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS];       ///< fixed-point transform coefficients
+    DECLARE_ALIGNED(16, int32_t, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS];     ///< fixed-point transform coefficients
     DECLARE_ALIGNED(32, float, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS];   ///< transform coefficients
     DECLARE_ALIGNED(32, float, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE];             ///< delay - added to the next block
     DECLARE_ALIGNED(32, float, window)[AC3_BLOCK_SIZE];                              ///< window coefficients
diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c
index ef19f6a..e792bcf 100644
--- a/libavcodec/ac3dsp.c
+++ b/libavcodec/ac3dsp.c
@@ -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)
 {
@@ -196,6 +197,19 @@ static void ac3_downmix_c(float **samples, float (*matrix)[2],
     }
 }
 
+static void apply_window_int16_c(int16_t *output, const int16_t *input,
+                                 const int16_t *window, unsigned int len)
+{
+    int i;
+    int len2 = len >> 1;
+
+    for (i = 0; i < len2; i++) {
+        int16_t w       = window[i];
+        output[i]       = (MUL16(input[i],       w) + (1 << 14)) >> 15;
+        output[len-i-1] = (MUL16(input[len-i-1], w) + (1 << 14)) >> 15;
+    }
+}
+
 av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
 {
     c->ac3_exponent_min = ac3_exponent_min_c;
@@ -208,6 +222,7 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
     c->compute_mantissa_size = ac3_compute_mantissa_size_c;
     c->extract_exponents = ac3_extract_exponents_c;
     c->downmix = ac3_downmix_c;
+    c->apply_window_int16 = apply_window_int16_c;
 
     if (ARCH_ARM)
         ff_ac3dsp_init_arm(c, bit_exact);
diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h
index 882eb76..e350c88 100644
--- a/libavcodec/ac3dsp.h
+++ b/libavcodec/ac3dsp.h
@@ -128,6 +128,20 @@ typedef struct AC3DSPContext {
 
     void (*downmix)(float **samples, float (*matrix)[2], int out_ch,
                     int in_ch, int len);
+
+    /**
+     * Apply symmetric window in 16-bit fixed-point.
+     * @param output destination array
+     *               constraints: 16-byte aligned
+     * @param input  source array
+     *               constraints: 16-byte aligned
+     * @param window window array
+     *               constraints: 16-byte aligned, at least len/2 elements
+     * @param len    full window length
+     *               constraints: multiple of ? greater than zero
+     */
+    void (*apply_window_int16)(int16_t *output, const int16_t *input,
+                               const int16_t *window, unsigned int len);
 } AC3DSPContext;
 
 void ff_ac3dsp_init    (AC3DSPContext *c, int bit_exact);
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index c0acc64..ce6c1a6 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -26,18 +26,17 @@
  * The simplest AC-3 encoder.
  */
 
-//#define ASSERT_LEVEL 2
-
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "ac3dsp.h"
 #include "ac3.h"
 #include "fft.h"
@@ -754,7 +753,7 @@ static void count_frame_bits_fixed(AC3EncodeContext *s)
  * Initialize bit allocation.
  * Set default parameter codes and calculate parameter values.
  */
-static void bit_alloc_init(AC3EncodeContext *s)
+static av_cold void bit_alloc_init(AC3EncodeContext *s)
 {
     int ch;
 
@@ -2052,9 +2051,6 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx)
 
     s->mdct_end(s);
 
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     return 0;
 }
 
@@ -2484,14 +2480,6 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
     if (ret)
         goto init_fail;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame= avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        ret = AVERROR(ENOMEM);
-        goto init_fail;
-    }
-#endif
-
     ff_dsputil_init(&s->dsp, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index e471edf..7d0ddab 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -66,17 +66,6 @@ av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s)
 
 
 /*
- * Apply KBD window to input samples prior to MDCT.
- */
-static void apply_window(void *dsp, int16_t *output, const int16_t *input,
-                         const int16_t *window, unsigned int len)
-{
-    DSPContext *dsp0 = dsp;
-    dsp0->apply_window_int16(output, input, window, len);
-}
-
-
-/*
  * Normalize the input samples to use the maximum available precision.
  * This assumes signed 16-bit input samples.
  */
@@ -143,6 +132,7 @@ static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx)
 
 AVCodec ff_ac3_fixed_encoder = {
     .name            = "ac3_fixed",
+    .long_name       = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
     .type            = AVMEDIA_TYPE_AUDIO,
     .id              = AV_CODEC_ID_AC3,
     .priv_data_size  = sizeof(AC3EncodeContext),
@@ -151,7 +141,6 @@ AVCodec ff_ac3_fixed_encoder = {
     .close           = ff_ac3_encode_close,
     .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
-    .long_name       = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
     .priv_class      = &ac3enc_class,
     .channel_layouts = ff_ac3_channel_layouts,
     .defaults        = ac3_defaults,
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index a225d9b..71db68c 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -84,18 +84,6 @@ av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s)
 
 
 /*
- * Apply KBD window to input samples prior to MDCT.
- */
-static void apply_window(void *dsp, float *output,
-                         const float *input, const float *window,
-                         unsigned int len)
-{
-    AVFloatDSPContext *fdsp = dsp;
-    fdsp->vector_fmul(output, input, window, len);
-}
-
-
-/*
  * Normalize the input samples.
  * Not needed for the floating-point encoder.
  */
@@ -142,6 +130,7 @@ static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
 #if CONFIG_AC3_ENCODER
 AVCodec ff_ac3_encoder = {
     .name            = "ac3",
+    .long_name       = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
     .type            = AVMEDIA_TYPE_AUDIO,
     .id              = AV_CODEC_ID_AC3,
     .priv_data_size  = sizeof(AC3EncodeContext),
@@ -150,7 +139,6 @@ AVCodec ff_ac3_encoder = {
     .close           = ff_ac3_encode_close,
     .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
-    .long_name       = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
     .priv_class      = &ac3enc_class,
     .channel_layouts = ff_ac3_channel_layouts,
     .defaults        = ac3_defaults,
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index 388d753..1b88726 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -28,15 +28,12 @@
 
 #include <stdint.h>
 
+#include "libavutil/internal.h"
 
 /* prototypes for static functions in ac3enc_fixed.c and ac3enc_float.c */
 
 static void scale_coefficients(AC3EncodeContext *s);
 
-static void apply_window(void *dsp, SampleType *output,
-                         const SampleType *input, const SampleType *window,
-                         unsigned int len);
-
 static int normalize_samples(AC3EncodeContext *s);
 
 static void clip_coefficients(DSPContext *dsp, CoefType *coef, unsigned int len);
@@ -101,11 +98,11 @@ static void apply_mdct(AC3EncodeContext *s)
             const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
 
 #if CONFIG_AC3ENC_FLOAT
-            apply_window(&s->fdsp, s->windowed_samples, input_samples,
-                         s->mdct_window, AC3_WINDOW_SIZE);
+            s->fdsp.vector_fmul(s->windowed_samples, input_samples,
+                                s->mdct_window, AC3_WINDOW_SIZE);
 #else
-            apply_window(&s->dsp, s->windowed_samples, input_samples,
-                         s->mdct_window, AC3_WINDOW_SIZE);
+            s->ac3dsp.apply_window_int16(s->windowed_samples, input_samples,
+                                         s->mdct_window, AC3_WINDOW_SIZE);
 #endif
 
             if (s->fixed_point)
diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c
index a9668fa..ab09bdb 100644
--- a/libavcodec/acelp_pitch_delay.c
+++ b/libavcodec/acelp_pitch_delay.c
@@ -21,9 +21,9 @@
  */
 
 #include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/mathematics.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "acelp_pitch_delay.h"
 #include "celp_math.h"
 
@@ -120,7 +120,7 @@ float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
     // Note 10^(0.05 * -10log(average x2)) = 1/sqrt((average x2)).
     float val = fixed_gain_factor *
         exp2f(M_LOG2_10 * 0.05 *
-              (ff_scalarproduct_float_c(pred_table, prediction_error, 4) +
+              (avpriv_scalarproduct_float_c(pred_table, prediction_error, 4) +
                energy_mean)) /
         sqrtf(fixed_mean_energy);
 
diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c
index b50c5f3..0c660ac 100644
--- a/libavcodec/acelp_vectors.c
+++ b/libavcodec/acelp_vectors.c
@@ -23,8 +23,8 @@
 #include <inttypes.h>
 
 #include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "acelp_vectors.h"
 
 const uint8_t ff_fc_2pulses_9bits_track1[16] =
@@ -94,10 +94,10 @@ const float ff_b60_sinc[61] = {
  0.898529  ,  0.865051  ,  0.769257  ,  0.624054  ,  0.448639  ,  0.265289   ,
  0.0959167 , -0.0412598 , -0.134338  , -0.178986  , -0.178528  , -0.142609   ,
 -0.0849304 , -0.0205078 ,  0.0369568 ,  0.0773926 ,  0.0955200 ,  0.0912781  ,
- 0.0689392 ,  0.0357056 ,  0.        , -0.0305481 , -0.0504150 , -0.0570068  ,
+ 0.0689392 ,  0.0357056 ,  0.0       , -0.0305481 , -0.0504150 , -0.0570068  ,
 -0.0508423 , -0.0350037 , -0.0141602 ,  0.00665283,  0.0230713 ,  0.0323486  ,
  0.0335388 ,  0.0275879 ,  0.0167847 ,  0.00411987, -0.00747681, -0.0156860  ,
--0.0193481 , -0.0183716 , -0.0137634 , -0.00704956,  0.        ,  0.00582886 ,
+-0.0193481 , -0.0183716 , -0.0137634 , -0.00704956,  0.0       ,  0.00582886 ,
  0.00939941,  0.0103760 ,  0.00903320,  0.00604248,  0.00238037, -0.00109863 ,
 -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
  0.00103760,  0.00222778,  0.00277710,  0.00271606,  0.00213623,  0.00115967 ,
@@ -183,7 +183,7 @@ void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
                               int size, float alpha, float *gain_mem)
 {
     int i;
-    float postfilter_energ = ff_scalarproduct_float_c(in, in, size);
+    float postfilter_energ = avpriv_scalarproduct_float_c(in, in, size);
     float gain_scale_factor = 1.0;
     float mem = *gain_mem;
 
@@ -204,7 +204,7 @@ void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
                                              float sum_of_squares, const int n)
 {
     int i;
-    float scalefactor = ff_scalarproduct_float_c(in, in, n);
+    float scalefactor = avpriv_scalarproduct_float_c(in, in, n);
     if (scalefactor)
         scalefactor = sqrt(sum_of_squares / scalefactor);
     for (i = 0; i < n; i++)
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index df6b9d3..c6bc4d0 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -1,6 +1,18 @@
 /*
  * Copyright (c) 2001-2003 The ffmpeg Project
  *
+ * first version by Francois Revol (revol at free.fr)
+ * fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
+ *   by Mike Melanson (melanson at pcisys.net)
+ * CD-ROM XA ADPCM codec by BERO
+ * EA ADPCM decoder by Robin Kay (komadori at myrealbox.com)
+ * EA ADPCM R1/R2/R3 decoder by Peter Ross (pross at xvid.org)
+ * EA IMA EACS decoder by Peter Ross (pross at xvid.org)
+ * EA IMA SEAD decoder by Peter Ross (pross at xvid.org)
+ * EA ADPCM XAS decoder by Peter Ross (pross at xvid.org)
+ * MAXIS EA ADPCM decoder by Robert Marston (rmarston at gmail.com)
+ * THP ADPCM decoder by Marco Gerards (mgerards at xs4all.nl)
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -28,18 +40,6 @@
 /**
  * @file
  * ADPCM decoders
- * First version by Francois Revol (revol at free.fr)
- * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
- *   by Mike Melanson (melanson at pcisys.net)
- * CD-ROM XA ADPCM codec by BERO
- * EA ADPCM decoder by Robin Kay (komadori at myrealbox.com)
- * EA ADPCM R1/R2/R3 decoder by Peter Ross (pross at xvid.org)
- * EA IMA EACS decoder by Peter Ross (pross at xvid.org)
- * EA IMA SEAD decoder by Peter Ross (pross at xvid.org)
- * EA ADPCM XAS decoder by Peter Ross (pross at xvid.org)
- * MAXIS EA ADPCM decoder by Robert Marston (rmarston at gmail.com)
- * THP ADPCM decoder by Marco Gerards (mgerards at xs4all.nl)
- *
  * Features and limitations:
  *
  * Reference documents:
@@ -85,7 +85,6 @@ static const int swf_index_tables[4][16] = {
 /* end of tables */
 
 typedef struct ADPCMDecodeContext {
-    AVFrame frame;
     ADPCMChannelStatus status[6];
     int vqa_version;                /**< VQA version. Used for ADPCM_IMA_WS */
 } ADPCMDecodeContext;
@@ -156,9 +155,6 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx)
             avctx->sample_fmt = AV_SAMPLE_FMT_S16;
     }
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -591,6 +587,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
 static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     ADPCMDecodeContext *c = avctx->priv_data;
@@ -611,20 +608,20 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    c->frame.nb_samples = nb_samples;
-    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = nb_samples;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (short *)c->frame.data[0];
-    samples_p = (int16_t **)c->frame.extended_data;
+    samples = (short *)frame->data[0];
+    samples_p = (int16_t **)frame->extended_data;
 
     /* use coded_samples when applicable */
     /* it is always <= nb_samples, so the output buffer will be large enough */
     if (coded_samples) {
         if (coded_samples != nb_samples)
             av_log(avctx, AV_LOG_WARNING, "mismatch in coded sample count\n");
-        c->frame.nb_samples = nb_samples = coded_samples;
+        frame->nb_samples = nb_samples = coded_samples;
     }
 
     st = avctx->channels == 2 ? 1 : 0;
@@ -710,7 +707,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
         }
 
         for (i = 0; i < avctx->channels; i++) {
-            samples = (int16_t *)c->frame.data[i];
+            samples = (int16_t *)frame->data[i];
             cs = &c->status[i];
             for (n = nb_samples >> 1; n > 0; n--) {
                 int v = bytestream2_get_byteu(&gb);
@@ -1097,7 +1094,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
             }
         }
 
-        c->frame.nb_samples = count * 28;
+        frame->nb_samples = count * 28;
         bytestream2_seek(&gb, 0, SEEK_END);
         break;
     }
@@ -1278,8 +1275,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
         return -1;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return bytestream2_tell(&gb);
 }
@@ -1296,13 +1292,13 @@ static const enum AVSampleFormat sample_fmts_both[] = { AV_SAMPLE_FMT_S16,
 #define ADPCM_DECODER(id_, sample_fmts_, name_, long_name_) \
 AVCodec ff_ ## name_ ## _decoder = {                        \
     .name           = #name_,                               \
+    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
     .type           = AVMEDIA_TYPE_AUDIO,                   \
     .id             = id_,                                  \
     .priv_data_size = sizeof(ADPCMDecodeContext),           \
     .init           = adpcm_decode_init,                    \
     .decode         = adpcm_decode_frame,                   \
     .capabilities   = CODEC_CAP_DR1,                        \
-    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
     .sample_fmts    = sample_fmts_,                         \
 }
 
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
index f81d7fd..fb3ce0d 100644
--- a/libavcodec/adpcmenc.c
+++ b/libavcodec/adpcmenc.c
@@ -1,6 +1,10 @@
 /*
  * Copyright (c) 2001-2003 The ffmpeg Project
  *
+ * first version by Francois Revol (revol at free.fr)
+ * fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
+ *   by Mike Melanson (melanson at pcisys.net)
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -29,10 +33,6 @@
 /**
  * @file
  * ADPCM encoders
- * First version by Francois Revol (revol at free.fr)
- * Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
- *   by Mike Melanson (melanson at pcisys.net)
- *
  * See ADPCM decoder reference documents for codec information.
  */
 
@@ -142,11 +142,6 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx)
         goto error;
     }
 
-#if FF_API_OLD_ENCODE_AUDIO
-    if (!(avctx->coded_frame = avcodec_alloc_frame()))
-        goto error;
-#endif
-
     return 0;
 error:
     av_freep(&s->paths);
@@ -159,9 +154,6 @@ error:
 static av_cold int adpcm_encode_close(AVCodecContext *avctx)
 {
     ADPCMEncodeContext *s = avctx->priv_data;
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     av_freep(&s->paths);
     av_freep(&s->node_buf);
     av_freep(&s->nodep_buf);
@@ -716,6 +708,7 @@ static const enum AVSampleFormat sample_fmts_p[] = {
 #define ADPCM_ENCODER(id_, name_, sample_fmts_, long_name_) \
 AVCodec ff_ ## name_ ## _encoder = {                        \
     .name           = #name_,                               \
+    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
     .type           = AVMEDIA_TYPE_AUDIO,                   \
     .id             = id_,                                  \
     .priv_data_size = sizeof(ADPCMEncodeContext),           \
@@ -723,7 +716,6 @@ AVCodec ff_ ## name_ ## _encoder = {                        \
     .encode2        = adpcm_encode_frame,                   \
     .close          = adpcm_encode_close,                   \
     .sample_fmts    = sample_fmts_,                         \
-    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
 }
 
 ADPCM_ENCODER(AV_CODEC_ID_ADPCM_IMA_QT,  adpcm_ima_qt,  sample_fmts_p, "ADPCM IMA QuickTime");
diff --git a/libavcodec/adx.c b/libavcodec/adx.c
index 870216c..6335865 100644
--- a/libavcodec/adx.c
+++ b/libavcodec/adx.c
@@ -53,7 +53,7 @@ int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
 
     /* check for encoding=3 block_size=18, sample_size=4 */
     if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) {
-        av_log_ask_for_sample(avctx, "unsupported ADX format\n");
+        avpriv_request_sample(avctx, "Support for this ADX format");
         return AVERROR_PATCHWELCOME;
     }
 
diff --git a/libavcodec/adx.h b/libavcodec/adx.h
index 47d9f24..ff4c2d6 100644
--- a/libavcodec/adx.h
+++ b/libavcodec/adx.h
@@ -40,7 +40,6 @@ typedef struct ADXChannelState {
 } ADXChannelState;
 
 typedef struct ADXContext {
-    AVFrame frame;
     int channels;
     ADXChannelState prev[2];
     int header_parsed;
diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c
index d8ea351..17d5bec 100644
--- a/libavcodec/adxdec.c
+++ b/libavcodec/adxdec.c
@@ -52,9 +52,6 @@ static av_cold int adx_decode_init(AVCodecContext *avctx)
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -98,6 +95,7 @@ static int adx_decode(ADXContext *c, int16_t *out, int offset,
 static int adx_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame      = data;
     int buf_size        = avpkt->size;
     ADXContext *c       = avctx->priv_data;
     int16_t **samples;
@@ -142,12 +140,12 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    c->frame.nb_samples = num_blocks * BLOCK_SAMPLES;
-    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = num_blocks * BLOCK_SAMPLES;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t **)c->frame.extended_data;
+    samples = (int16_t **)frame->extended_data;
     samples_offset = 0;
 
     while (num_blocks--) {
@@ -163,8 +161,7 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data,
         samples_offset += BLOCK_SAMPLES;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return buf - avpkt->data;
 }
@@ -178,6 +175,7 @@ static void adx_decode_flush(AVCodecContext *avctx)
 
 AVCodec ff_adpcm_adx_decoder = {
     .name           = "adpcm_adx",
+    .long_name      = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ADPCM_ADX,
     .priv_data_size = sizeof(ADXContext),
@@ -185,7 +183,6 @@ AVCodec ff_adpcm_adx_decoder = {
     .decode         = adx_decode_frame,
     .flush          = adx_decode_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
index 8a50539..e730811 100644
--- a/libavcodec/adxenc.c
+++ b/libavcodec/adxenc.c
@@ -117,11 +117,6 @@ static av_cold int adx_encode_init(AVCodecContext *avctx)
     }
     avctx->frame_size = BLOCK_SAMPLES;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-#endif
-
     /* the cutoff can be adjusted, but this seems to work pretty well */
     c->cutoff = 500;
     ff_adx_calculate_coeffs(c->cutoff, avctx->sample_rate, COEFF_BITS, c->coeff);
@@ -165,6 +160,7 @@ static int adx_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_adpcm_adx_encoder = {
     .name           = "adpcm_adx",
+    .long_name      = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ADPCM_ADX,
     .priv_data_size = sizeof(ADXContext),
@@ -172,5 +168,4 @@ AVCodec ff_adpcm_adx_encoder = {
     .encode2        = adx_encode_frame,
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
                                                       AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
 };
diff --git a/libavcodec/aic.c b/libavcodec/aic.c
new file mode 100644
index 0000000..5981dd8
--- /dev/null
+++ b/libavcodec/aic.c
@@ -0,0 +1,480 @@
+/*
+ * Apple Intermediate Codec decoder
+ *
+ * Copyright (c) 2013 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 "avcodec.h"
+#include "bytestream.h"
+#include "dsputil.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "golomb.h"
+#include "unary.h"
+
+#define AIC_HDR_SIZE    24
+#define AIC_BAND_COEFFS (64 + 32 + 192 + 96)
+
+enum AICBands {
+    COEFF_LUMA = 0,
+    COEFF_CHROMA,
+    COEFF_LUMA_EXT,
+    COEFF_CHROMA_EXT,
+    NUM_BANDS
+};
+
+static const int aic_num_band_coeffs[NUM_BANDS] = { 64, 32, 192, 96 };
+
+static const int aic_band_off[NUM_BANDS] = { 0, 64, 96, 288 };
+
+static const uint8_t aic_quant_matrix[64] = {
+     8, 16, 19, 22, 22, 26, 26, 27,
+    16, 16, 22, 22, 26, 27, 27, 29,
+    19, 22, 26, 26, 27, 29, 29, 35,
+    22, 24, 27, 27, 29, 32, 34, 38,
+    26, 27, 29, 29, 32, 35, 38, 46,
+    27, 29, 34, 34, 35, 40, 46, 56,
+    29, 34, 34, 37, 40, 48, 56, 69,
+    34, 37, 38, 40, 48, 58, 69, 83,
+};
+
+static const uint8_t aic_y_scan[64] = {
+     0,  4,  1,  2,  5,  8, 12,  9,
+     6,  3,  7, 10, 13, 14, 11, 15,
+    47, 43, 46, 45, 42, 39, 35, 38,
+    41, 44, 40, 37, 34, 33, 36, 32,
+    16, 20, 17, 18, 21, 24, 28, 25,
+    22, 19, 23, 26, 29, 30, 27, 31,
+    63, 59, 62, 61, 58, 55, 51, 54,
+    57, 60, 56, 53, 50, 49, 52, 48,
+};
+
+static const uint8_t aic_y_ext_scan[192] = {
+     64,  72,  65,  66,  73,  80,  88,  81,
+     74,  67,  75,  82,  89,  90,  83,  91,
+      0,   4,   1,   2,   5,   8,  12,   9,
+      6,   3,   7,  10,  13,  14,  11,  15,
+     16,  20,  17,  18,  21,  24,  28,  25,
+     22,  19,  23,  26,  29,  30,  27,  31,
+    155, 147, 154, 153, 146, 139, 131, 138,
+    145, 152, 144, 137, 130, 129, 136, 128,
+     47,  43,  46,  45,  42,  39,  35,  38,
+     41,  44,  40,  37,  34,  33,  36,  32,
+     63,  59,  62,  61,  58,  55,  51,  54,
+     57,  60,  56,  53,  50,  49,  52,  48,
+     96, 104,  97,  98, 105, 112, 120, 113,
+    106,  99, 107, 114, 121, 122, 115, 123,
+     68,  76,  69,  70,  77,  84,  92,  85,
+     78,  71,  79,  86,  93,  94,  87,  95,
+    100, 108, 101, 102, 109, 116, 124, 117,
+    110, 103, 111, 118, 125, 126, 119, 127,
+    187, 179, 186, 185, 178, 171, 163, 170,
+    177, 184, 176, 169, 162, 161, 168, 160,
+    159, 151, 158, 157, 150, 143, 135, 142,
+    149, 156, 148, 141, 134, 133, 140, 132,
+    191, 183, 190, 189, 182, 175, 167, 174,
+    181, 188, 180, 173, 166, 165, 172, 164,
+};
+
+static const uint8_t aic_c_scan[64] = {
+     0,  4,  1,  2,  5,  8, 12,  9,
+     6,  3,  7, 10, 13, 14, 11, 15,
+    31, 27, 30, 29, 26, 23, 19, 22,
+    25, 28, 24, 21, 18, 17, 20, 16,
+    32, 36, 33, 34, 37, 40, 44, 41,
+    38, 35, 39, 42, 45, 46, 43, 47,
+    63, 59, 62, 61, 58, 55, 51, 54,
+    57, 60, 56, 53, 50, 49, 52, 48,
+};
+
+static const uint8_t aic_c_ext_scan[192] = {
+     16,  24,  17,  18,  25,  32,  40,  33,
+     26,  19,  27,  34,  41,  42,  35,  43,
+      0,   4,   1,   2,   5,   8,  12,   9,
+      6,   3,   7,  10,  13,  14,  11,  15,
+     20,  28,  21,  22,  29,  36,  44,  37,
+     30,  23,  31,  38,  45,  46,  39,  47,
+     95,  87,  94,  93,  86,  79,  71,  78,
+     85,  92,  84,  77,  70,  69,  76,  68,
+     63,  59,  62,  61,  58,  55,  51,  54,
+     57,  60,  56,  53,  50,  49,  52,  48,
+     91,  83,  90,  89,  82,  75,  67,  74,
+     81,  88,  80,  73,  66,  65,  72,  64,
+    112, 120, 113, 114, 121, 128, 136, 129,
+    122, 115, 123, 130, 137, 138, 131, 139,
+     96, 100,  97,  98, 101, 104, 108, 105,
+    102,  99, 103, 106, 109, 110, 107, 111,
+    116, 124, 117, 118, 125, 132, 140, 133,
+    126, 119, 127, 134, 141, 142, 135, 143,
+    191, 183, 190, 189, 182, 175, 167, 174,
+    181, 188, 180, 173, 166, 165, 172, 164,
+    159, 155, 158, 157, 154, 151, 147, 150,
+    153, 156, 152, 149, 146, 145, 148, 144,
+    187, 179, 186, 185, 178, 171, 163, 170,
+    177, 184, 176, 169, 162, 161, 168, 160,
+};
+
+static const uint8_t *aic_scan[NUM_BANDS] = {
+    aic_y_scan, aic_c_scan, aic_y_ext_scan, aic_c_ext_scan
+};
+
+typedef struct AICContext {
+    AVCodecContext *avctx;
+    AVFrame        *frame;
+    DSPContext     dsp;
+    ScanTable      scantable;
+
+    int            num_x_slices;
+    int            slice_width;
+    int            mb_width, mb_height;
+    int            quant;
+    int            interlaced;
+
+    int16_t        *slice_data;
+    int16_t        *data_ptr[NUM_BANDS];
+
+    DECLARE_ALIGNED(16, int16_t, block)[64];
+} AICContext;
+
+static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
+{
+    uint32_t frame_size;
+    int width, height;
+
+    if (src[0] != 1) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Invalid version %d\n", src[0]);
+        return AVERROR_INVALIDDATA;
+    }
+    if (src[1] != AIC_HDR_SIZE - 2) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Invalid header size %d\n", src[1]);
+        return AVERROR_INVALIDDATA;
+    }
+    frame_size = AV_RB32(src + 2);
+    width      = AV_RB16(src + 6);
+    height     = AV_RB16(src + 8);
+    if (frame_size > size) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Frame size should be %d got %d\n",
+               frame_size, size);
+        return AVERROR_INVALIDDATA;
+    }
+    if (width != ctx->avctx->width || height != ctx->avctx->height) {
+        av_log(ctx->avctx, AV_LOG_ERROR,
+               "Picture dimension changed: old: %d x %d, new: %d x %d\n",
+               ctx->avctx->width, ctx->avctx->height, width, height);
+        return AVERROR_INVALIDDATA;
+    }
+    ctx->quant      = src[15];
+    ctx->interlaced = ((src[16] >> 4) == 3);
+
+    return 0;
+}
+
+#define GET_CODE(val, type, add_bits)                         \
+    do {                                                      \
+        if (type)                                             \
+            val = get_ue_golomb(gb);                          \
+        else                                                  \
+            val = get_unary(gb, 1, 31);                       \
+        if (add_bits)                                         \
+            val = (val << add_bits) + get_bits(gb, add_bits); \
+    } while (0)
+
+static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
+                             int band, int slice_width, int force_chroma)
+{
+    int has_skips, coeff_type, coeff_bits, skip_type, skip_bits;
+    const int num_coeffs = aic_num_band_coeffs[band];
+    const uint8_t *scan = aic_scan[band | force_chroma];
+    int mb, idx, val;
+
+    has_skips  = get_bits1(gb);
+    coeff_type = get_bits1(gb);
+    coeff_bits = get_bits(gb, 3);
+
+    if (has_skips) {
+        skip_type = get_bits1(gb);
+        skip_bits = get_bits(gb, 3);
+
+        for (mb = 0; mb < slice_width; mb++) {
+            idx = -1;
+            do {
+                GET_CODE(val, skip_type, skip_bits);
+                if (val < 0)
+                    return AVERROR_INVALIDDATA;
+                idx += val + 1;
+                if (idx >= num_coeffs)
+                    break;
+                GET_CODE(val, coeff_type, coeff_bits);
+                val++;
+                if (val >= 0x10000 || val < 0)
+                    return AVERROR_INVALIDDATA;
+                dst[scan[idx]] = val;
+            } while (idx < num_coeffs - 1);
+            dst += num_coeffs;
+        }
+    } else {
+        for (mb = 0; mb < slice_width; mb++) {
+            for (idx = 0; idx < num_coeffs; idx++) {
+                GET_CODE(val, coeff_type, coeff_bits);
+                if (val >= 0x10000 || val < 0)
+                    return AVERROR_INVALIDDATA;
+                dst[scan[idx]] = val;
+            }
+            dst += num_coeffs;
+        }
+    }
+    return 0;
+}
+
+static void recombine_block(int16_t *dst, const uint8_t *scan,
+                            int16_t **base, int16_t **ext)
+{
+    int i, j;
+
+    for (i = 0; i < 4; i++) {
+        for (j = 0; j < 4; j++)
+            dst[scan[i * 8 + j]]     = (*base)[j];
+        for (j = 0; j < 4; j++)
+            dst[scan[i * 8 + j + 4]] = (*ext)[j];
+        *base += 4;
+        *ext  += 4;
+    }
+    for (; i < 8; i++) {
+        for (j = 0; j < 8; j++)
+            dst[scan[i * 8 + j]] = (*ext)[j];
+        *ext  += 8;
+    }
+}
+
+static void recombine_block_il(int16_t *dst, const uint8_t *scan,
+                               int16_t **base, int16_t **ext,
+                               int block_no)
+{
+    int i, j;
+
+    if (block_no < 2) {
+        for (i = 0; i < 8; i++) {
+            for (j = 0; j < 4; j++)
+                dst[scan[i * 8 + j]]     = (*base)[j];
+            for (j = 0; j < 4; j++)
+                dst[scan[i * 8 + j + 4]] = (*ext)[j];
+            *base += 4;
+            *ext  += 4;
+        }
+    } else {
+        for (i = 0; i < 64; i++)
+            dst[scan[i]] = (*ext)[i];
+        *ext += 64;
+    }
+}
+
+static void unquant_block(int16_t *block, int q)
+{
+    int i;
+
+    for (i = 0; i < 64; i++) {
+        int val  = (uint16_t)block[i];
+        int sign = val & 1;
+
+        block[i] = (((val >> 1) ^ -sign) * q * aic_quant_matrix[i] >> 4)
+                   + sign;
+    }
+}
+
+static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
+                            const uint8_t *src, int src_size)
+{
+    GetBitContext gb;
+    int ret, i, mb, blk;
+    int slice_width = FFMIN(ctx->slice_width, ctx->mb_width - mb_x);
+    uint8_t *Y, *C[2];
+    uint8_t *dst;
+    int16_t *base_y = ctx->data_ptr[COEFF_LUMA];
+    int16_t *base_c = ctx->data_ptr[COEFF_CHROMA];
+    int16_t *ext_y  = ctx->data_ptr[COEFF_LUMA_EXT];
+    int16_t *ext_c  = ctx->data_ptr[COEFF_CHROMA_EXT];
+    const int ystride = ctx->frame->linesize[0];
+
+    Y = ctx->frame->data[0] + mb_x * 16 + mb_y * 16 * ystride;
+    for (i = 0; i < 2; i++)
+        C[i] = ctx->frame->data[i + 1] + mb_x * 8
+               + mb_y * 8 * ctx->frame->linesize[i + 1];
+    init_get_bits(&gb, src, src_size * 8);
+
+    memset(ctx->slice_data, 0,
+           sizeof(*ctx->slice_data) * slice_width * AIC_BAND_COEFFS);
+    for (i = 0; i < NUM_BANDS; i++)
+        if ((ret = aic_decode_coeffs(&gb, ctx->data_ptr[i],
+                                     i, slice_width,
+                                     !ctx->interlaced)) < 0)
+            return ret;
+
+    for (mb = 0; mb < slice_width; mb++) {
+        for (blk = 0; blk < 4; blk++) {
+            if (!ctx->interlaced)
+                recombine_block(ctx->block, ctx->scantable.permutated,
+                                &base_y, &ext_y);
+            else
+                recombine_block_il(ctx->block, ctx->scantable.permutated,
+                                   &base_y, &ext_y, blk);
+            unquant_block(ctx->block, ctx->quant);
+            ctx->dsp.idct(ctx->block);
+
+            if (!ctx->interlaced) {
+                dst = Y + (blk >> 1) * 8 * ystride + (blk & 1) * 8;
+                ctx->dsp.put_signed_pixels_clamped(ctx->block, dst,
+                                                   ystride);
+            } else {
+                dst = Y + (blk & 1) * 8 + (blk >> 1) * ystride;
+                ctx->dsp.put_signed_pixels_clamped(ctx->block, dst,
+                                                   ystride * 2);
+            }
+        }
+        Y += 16;
+
+        for (blk = 0; blk < 2; blk++) {
+            recombine_block(ctx->block, ctx->scantable.permutated,
+                            &base_c, &ext_c);
+            unquant_block(ctx->block, ctx->quant);
+            ctx->dsp.idct(ctx->block);
+            ctx->dsp.put_signed_pixels_clamped(ctx->block, C[blk],
+                                               ctx->frame->linesize[blk + 1]);
+            C[blk] += 8;
+        }
+    }
+
+    return 0;
+}
+
+static int aic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                            AVPacket *avpkt)
+{
+    AICContext *ctx    = avctx->priv_data;
+    const uint8_t *buf = avpkt->data;
+    int buf_size       = avpkt->size;
+    GetByteContext gb;
+    uint32_t off;
+    int x, y, ret;
+    int slice_size;
+
+    ctx->frame            = data;
+    ctx->frame->pict_type = AV_PICTURE_TYPE_I;
+    ctx->frame->key_frame = 1;
+
+    off = FFALIGN(AIC_HDR_SIZE + ctx->num_x_slices * ctx->mb_height * 2, 4);
+
+    if (buf_size < off) {
+        av_log(avctx, AV_LOG_ERROR, "Too small frame\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((ret = aic_decode_header(ctx, buf, buf_size)) < 0)
+        return ret;
+
+    if ((ret = ff_get_buffer(avctx, ctx->frame, 0)) < 0)
+        return ret;
+
+    bytestream2_init(&gb, buf + AIC_HDR_SIZE,
+                     ctx->num_x_slices * ctx->mb_height * 2);
+
+    for (y = 0; y < ctx->mb_height; y++) {
+        for (x = 0; x < ctx->mb_width; x += ctx->slice_width) {
+            slice_size = bytestream2_get_le16(&gb) * 4;
+            if (slice_size + off > buf_size || !slice_size) {
+                av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            if ((ret = aic_decode_slice(ctx, x, y,
+                                        buf + off, slice_size)) < 0)
+                return ret;
+
+            off += slice_size;
+        }
+    }
+
+    *got_frame = 1;
+
+    return avpkt->size;
+}
+
+static av_cold int aic_decode_init(AVCodecContext *avctx)
+{
+    AICContext *ctx = avctx->priv_data;
+    int i;
+    uint8_t scan[64];
+
+    ctx->avctx = avctx;
+
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    ff_dsputil_init(&ctx->dsp, avctx);
+
+    for (i = 0; i < 64; i++)
+        scan[i] = i;
+    ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, scan);
+
+    ctx->mb_width  = FFALIGN(avctx->width,  16) >> 4;
+    ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
+
+    ctx->num_x_slices = 16;
+    ctx->slice_width  = ctx->mb_width / 16;
+    for (i = 1; i < 32; i++) {
+        if (!(ctx->mb_width % i) && (ctx->mb_width / i < 32)) {
+            ctx->slice_width  = ctx->mb_width / i;
+            ctx->num_x_slices = i;
+            break;
+        }
+    }
+
+    ctx->slice_data = av_malloc(ctx->slice_width * AIC_BAND_COEFFS
+                                * sizeof(*ctx->slice_data));
+    if (!ctx->slice_data) {
+        av_log(avctx, AV_LOG_ERROR, "Error allocating slice buffer\n");
+
+        return AVERROR(ENOMEM);
+    }
+
+    for (i = 0; i < NUM_BANDS; i++)
+        ctx->data_ptr[i] = ctx->slice_data + ctx->slice_width
+                                             * aic_band_off[i];
+
+    return 0;
+}
+
+static av_cold int aic_decode_close(AVCodecContext *avctx)
+{
+    AICContext *ctx = avctx->priv_data;
+
+    av_freep(&ctx->slice_data);
+
+    return 0;
+}
+
+AVCodec ff_aic_decoder = {
+    .name           = "aic",
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_AIC,
+    .priv_data_size = sizeof(AICContext),
+    .init           = aic_decode_init,
+    .close          = aic_decode_close,
+    .decode         = aic_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+};
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 139e352..f972531 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -58,7 +58,6 @@
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame frame;
     GetBitContext gb;
     int channels;
 
@@ -248,7 +247,7 @@ static void append_extra_bits(int32_t *buffer[2], int32_t *extra_bits_buffer[2],
             buffer[ch][i] = (buffer[ch][i] << extra_bits) | extra_bits_buffer[ch][i];
 }
 
-static int decode_element(AVCodecContext *avctx, void *data, int ch_index,
+static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
                           int channels)
 {
     ALACContext *alac = avctx->priv_data;
@@ -283,8 +282,8 @@ static int decode_element(AVCodecContext *avctx, void *data, int ch_index,
     }
     if (!alac->nb_samples) {
         /* get output buffer */
-        alac->frame.nb_samples = output_samples;
-        if ((ret = ff_get_buffer(avctx, &alac->frame)) < 0) {
+        frame->nb_samples = output_samples;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
@@ -296,7 +295,7 @@ static int decode_element(AVCodecContext *avctx, void *data, int ch_index,
     alac->nb_samples = output_samples;
     if (alac->sample_size > 16) {
         for (ch = 0; ch < channels; ch++)
-            alac->output_samples_buffer[ch] = (int32_t *)alac->frame.extended_data[ch_index + ch];
+            alac->output_samples_buffer[ch] = (int32_t *)frame->extended_data[ch_index + ch];
     }
 
     if (is_compressed) {
@@ -380,7 +379,7 @@ static int decode_element(AVCodecContext *avctx, void *data, int ch_index,
     switch(alac->sample_size) {
     case 16: {
         for (ch = 0; ch < channels; ch++) {
-            int16_t *outbuffer = (int16_t *)alac->frame.extended_data[ch_index + ch];
+            int16_t *outbuffer = (int16_t *)frame->extended_data[ch_index + ch];
             for (i = 0; i < alac->nb_samples; i++)
                 *outbuffer++ = alac->output_samples_buffer[ch][i];
         }}
@@ -400,6 +399,7 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     ALACContext *alac = avctx->priv_data;
+    AVFrame *frame    = data;
     enum AlacRawDataBlockType element;
     int channels;
     int ch, ret, got_end;
@@ -427,7 +427,7 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
         }
 
-        ret = decode_element(avctx, data,
+        ret = decode_element(avctx, frame,
                              ff_alac_channel_layout_offsets[alac->channels - 1][ch],
                              channels);
         if (ret < 0 && get_bits_left(&alac->gb))
@@ -445,8 +445,7 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data,
                avpkt->size * 8 - get_bits_count(&alac->gb));
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = alac->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
@@ -541,8 +540,7 @@ static av_cold int alac_decode_init(AVCodecContext * avctx)
     case 24:
     case 32: avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
              break;
-    default: av_log_ask_for_sample(avctx, "Sample depth %d is not supported.\n",
-                                   alac->sample_size);
+    default: avpriv_request_sample(avctx, "Sample depth %d", alac->sample_size);
              return AVERROR_PATCHWELCOME;
     }
     avctx->bits_per_raw_sample = alac->sample_size;
@@ -568,14 +566,12 @@ static av_cold int alac_decode_init(AVCodecContext * avctx)
         return ret;
     }
 
-    avcodec_get_frame_defaults(&alac->frame);
-    avctx->coded_frame = &alac->frame;
-
     return 0;
 }
 
 AVCodec ff_alac_decoder = {
     .name           = "alac",
+    .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ALAC,
     .priv_data_size = sizeof(ALACContext),
@@ -583,5 +579,4 @@ AVCodec ff_alac_decoder = {
     .close          = alac_decode_close,
     .decode         = alac_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
 };
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 3bc920a..401f26f 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -21,7 +21,6 @@
 
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "lpc.h"
 #include "mathops.h"
@@ -580,7 +579,7 @@ static av_cold int alac_encode_init(AVCodecContext *avctx)
         goto error;
     }
 
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame) {
         ret = AVERROR(ENOMEM);
         goto error;
@@ -644,6 +643,7 @@ static int alac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_alac_encoder = {
     .name           = "alac",
+    .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ALAC,
     .priv_data_size = sizeof(AlacEncodeContext),
@@ -655,5 +655,4 @@ AVCodec ff_alac_encoder = {
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P,
                                                      AV_SAMPLE_FMT_S16P,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
 };
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 5786719..8b2bdc1 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -24,8 +24,9 @@
  * Provide registration of all codecs, parsers and bitstream filters for libavcodec.
  */
 
-#include "avcodec.h"
 #include "config.h"
+#include "avcodec.h"
+#include "version.h"
 
 #define REGISTER_HWACCEL(X, x)                                          \
     {                                                                   \
@@ -74,21 +75,29 @@ void avcodec_register_all(void)
 
     /* hardware accelerators */
     REGISTER_HWACCEL(H263_VAAPI,        h263_vaapi);
+    REGISTER_HWACCEL(H263_VDPAU,        h263_vdpau);
     REGISTER_HWACCEL(H264_DXVA2,        h264_dxva2);
     REGISTER_HWACCEL(H264_VAAPI,        h264_vaapi);
     REGISTER_HWACCEL(H264_VDA,          h264_vda);
+    REGISTER_HWACCEL(H264_VDPAU,        h264_vdpau);
+    REGISTER_HWACCEL(MPEG1_VDPAU,       mpeg1_vdpau);
     REGISTER_HWACCEL(MPEG2_DXVA2,       mpeg2_dxva2);
     REGISTER_HWACCEL(MPEG2_VAAPI,       mpeg2_vaapi);
+    REGISTER_HWACCEL(MPEG2_VDPAU,       mpeg2_vdpau);
     REGISTER_HWACCEL(MPEG4_VAAPI,       mpeg4_vaapi);
+    REGISTER_HWACCEL(MPEG4_VDPAU,       mpeg4_vdpau);
     REGISTER_HWACCEL(VC1_DXVA2,         vc1_dxva2);
     REGISTER_HWACCEL(VC1_VAAPI,         vc1_vaapi);
+    REGISTER_HWACCEL(VC1_VDPAU,         vc1_vdpau);
     REGISTER_HWACCEL(WMV3_DXVA2,        wmv3_dxva2);
     REGISTER_HWACCEL(WMV3_VAAPI,        wmv3_vaapi);
+    REGISTER_HWACCEL(WMV3_VDPAU,        wmv3_vdpau);
 
     /* video codecs */
     REGISTER_ENCODER(A64MULTI,          a64multi);
     REGISTER_ENCODER(A64MULTI5,         a64multi5);
     REGISTER_DECODER(AASC,              aasc);
+    REGISTER_DECODER(AIC,               aic);
     REGISTER_DECODER(AMV,               amv);
     REGISTER_DECODER(ANM,               anm);
     REGISTER_DECODER(ANSI,              ansi);
@@ -128,6 +137,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER(EIGHTSVX_EXP,      eightsvx_exp);
     REGISTER_DECODER(EIGHTSVX_FIB,      eightsvx_fib);
     REGISTER_DECODER(ESCAPE124,         escape124);
+    REGISTER_DECODER(ESCAPE130,         escape130);
     REGISTER_ENCDEC (FFV1,              ffv1);
     REGISTER_ENCDEC (FFVHUFF,           ffvhuff);
     REGISTER_ENCDEC (FLASHSV,           flashsv);
@@ -137,13 +147,15 @@ void avcodec_register_all(void)
     REGISTER_DECODER(FOURXM,            fourxm);
     REGISTER_DECODER(FRAPS,             fraps);
     REGISTER_DECODER(FRWU,              frwu);
+    REGISTER_DECODER(G2M,               g2m);
     REGISTER_ENCDEC (GIF,               gif);
     REGISTER_ENCDEC (H261,              h261);
     REGISTER_ENCDEC (H263,              h263);
     REGISTER_DECODER(H263I,             h263i);
     REGISTER_ENCODER(H263P,             h263p);
     REGISTER_DECODER(H264,              h264);
-    REGISTER_DECODER(H264_VDPAU,        h264_vdpau);
+    REGISTER_DECODER(HEVC,              hevc);
+    REGISTER_DECODER(HNM4_VIDEO,        hnm4_video);
     REGISTER_ENCDEC (HUFFYUV,           huffyuv);
     REGISTER_DECODER(IDCIN,             idcin);
     REGISTER_DECODER(IFF_BYTERUN1,      iff_byterun1);
@@ -153,6 +165,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER(INDEO4,            indeo4);
     REGISTER_DECODER(INDEO5,            indeo5);
     REGISTER_DECODER(INTERPLAY_VIDEO,   interplay_video);
+    REGISTER_DECODER(JPEG2000,          jpeg2000);
     REGISTER_ENCDEC (JPEGLS,            jpegls);
     REGISTER_DECODER(JV,                jv);
     REGISTER_DECODER(KGV1,              kgv1);
@@ -166,13 +179,12 @@ void avcodec_register_all(void)
     REGISTER_DECODER(MJPEGB,            mjpegb);
     REGISTER_DECODER(MMVIDEO,           mmvideo);
     REGISTER_DECODER(MOTIONPIXELS,      motionpixels);
+#if FF_API_XVMC
     REGISTER_DECODER(MPEG_XVMC,         mpeg_xvmc);
+#endif /* FF_API_XVMC */
     REGISTER_ENCDEC (MPEG1VIDEO,        mpeg1video);
     REGISTER_ENCDEC (MPEG2VIDEO,        mpeg2video);
     REGISTER_ENCDEC (MPEG4,             mpeg4);
-    REGISTER_DECODER(MPEG4_VDPAU,       mpeg4_vdpau);
-    REGISTER_DECODER(MPEG_VDPAU,        mpeg_vdpau);
-    REGISTER_DECODER(MPEG1_VDPAU,       mpeg1_vdpau);
     REGISTER_DECODER(MSA1,              msa1);
     REGISTER_DECODER(MSMPEG4V1,         msmpeg4v1);
     REGISTER_ENCDEC (MSMPEG4V2,         msmpeg4v2);
@@ -212,7 +224,6 @@ void avcodec_register_all(void)
     REGISTER_ENCDEC (SGI,               sgi);
     REGISTER_DECODER(SMACKER,           smacker);
     REGISTER_DECODER(SMC,               smc);
-    REGISTER_ENCDEC (SNOW,              snow);
     REGISTER_DECODER(SP5X,              sp5x);
     REGISTER_ENCDEC (SUNRAST,           sunrast);
     REGISTER_ENCDEC (SVQ1,              svq1);
@@ -236,7 +247,6 @@ void avcodec_register_all(void)
     REGISTER_DECODER(VB,                vb);
     REGISTER_DECODER(VBLE,              vble);
     REGISTER_DECODER(VC1,               vc1);
-    REGISTER_DECODER(VC1_VDPAU,         vc1_vdpau);
     REGISTER_DECODER(VC1IMAGE,          vc1image);
     REGISTER_DECODER(VCR1,              vcr1);
     REGISTER_DECODER(VMDVIDEO,          vmdvideo);
@@ -247,11 +257,12 @@ void avcodec_register_all(void)
     REGISTER_DECODER(VP6A,              vp6a);
     REGISTER_DECODER(VP6F,              vp6f);
     REGISTER_DECODER(VP8,               vp8);
+    REGISTER_DECODER(VP9,               vp9);
     REGISTER_DECODER(VQA,               vqa);
+    REGISTER_DECODER(WEBP,              webp);
     REGISTER_ENCDEC (WMV1,              wmv1);
     REGISTER_ENCDEC (WMV2,              wmv2);
     REGISTER_DECODER(WMV3,              wmv3);
-    REGISTER_DECODER(WMV3_VDPAU,        wmv3_vdpau);
     REGISTER_DECODER(WMV3IMAGE,         wmv3image);
     REGISTER_DECODER(WNV1,              wnv1);
     REGISTER_DECODER(XAN_WC3,           xan_wc3);
@@ -291,6 +302,7 @@ void avcodec_register_all(void)
     REGISTER_DECODER(IMC,               imc);
     REGISTER_DECODER(MACE3,             mace3);
     REGISTER_DECODER(MACE6,             mace6);
+    REGISTER_DECODER(METASOUND,         metasound);
     REGISTER_DECODER(MLP,               mlp);
     REGISTER_DECODER(MP1,               mp1);
     REGISTER_DECODER(MP1FLOAT,          mp1float);
@@ -346,8 +358,10 @@ void avcodec_register_all(void)
     REGISTER_ENCDEC (PCM_S24BE,         pcm_s24be);
     REGISTER_ENCDEC (PCM_S24DAUD,       pcm_s24daud);
     REGISTER_ENCDEC (PCM_S24LE,         pcm_s24le);
+    REGISTER_DECODER(PCM_S24LE_PLANAR,  pcm_s24le_planar);
     REGISTER_ENCDEC (PCM_S32BE,         pcm_s32be);
     REGISTER_ENCDEC (PCM_S32LE,         pcm_s32le);
+    REGISTER_DECODER(PCM_S32LE_PLANAR,  pcm_s32le_planar);
     REGISTER_ENCDEC (PCM_U8,            pcm_u8);
     REGISTER_ENCDEC (PCM_U16BE,         pcm_u16be);
     REGISTER_ENCDEC (PCM_U16LE,         pcm_u16le);
@@ -405,7 +419,7 @@ void avcodec_register_all(void)
 
     /* external libraries */
     REGISTER_ENCODER(LIBFAAC,           libfaac);
-    REGISTER_ENCODER(LIBFDK_AAC,        libfdk_aac);
+    REGISTER_ENCDEC (LIBFDK_AAC,        libfdk_aac);
     REGISTER_ENCDEC (LIBGSM,            libgsm);
     REGISTER_ENCDEC (LIBGSM_MS,         libgsm_ms);
     REGISTER_ENCDEC (LIBILBC,           libilbc);
@@ -420,7 +434,9 @@ void avcodec_register_all(void)
     REGISTER_ENCODER(LIBVO_AACENC,      libvo_aacenc);
     REGISTER_ENCODER(LIBVO_AMRWBENC,    libvo_amrwbenc);
     REGISTER_ENCODER(LIBVORBIS,         libvorbis);
-    REGISTER_ENCDEC (LIBVPX,            libvpx);
+    REGISTER_ENCDEC (LIBVPX_VP8,        libvpx_vp8);
+    REGISTER_ENCDEC (LIBVPX_VP9,        libvpx_vp9);
+    REGISTER_ENCODER(LIBWAVPACK,        libwavpack);
     REGISTER_ENCODER(LIBX264,           libx264);
     REGISTER_ENCODER(LIBXAVS,           libxavs);
     REGISTER_ENCODER(LIBXVID,           libxvid);
@@ -442,11 +458,13 @@ void avcodec_register_all(void)
     REGISTER_PARSER(H261,               h261);
     REGISTER_PARSER(H263,               h263);
     REGISTER_PARSER(H264,               h264);
+    REGISTER_PARSER(HEVC,               hevc);
     REGISTER_PARSER(MJPEG,              mjpeg);
     REGISTER_PARSER(MLP,                mlp);
     REGISTER_PARSER(MPEG4VIDEO,         mpeg4video);
     REGISTER_PARSER(MPEGAUDIO,          mpegaudio);
     REGISTER_PARSER(MPEGVIDEO,          mpegvideo);
+    REGISTER_PARSER(PNG,                png);
     REGISTER_PARSER(PNM,                pnm);
     REGISTER_PARSER(RV30,               rv30);
     REGISTER_PARSER(RV40,               rv40);
@@ -464,8 +482,6 @@ void avcodec_register_all(void)
     REGISTER_BSF(IMX_DUMP_HEADER,       imx_dump_header);
     REGISTER_BSF(MJPEG2JPEG,            mjpeg2jpeg);
     REGISTER_BSF(MJPEGA_DUMP_HEADER,    mjpega_dump_header);
-    REGISTER_BSF(MP3_HEADER_COMPRESS,   mp3_header_compress);
-    REGISTER_BSF(MP3_HEADER_DECOMPRESS, mp3_header_decompress);
     REGISTER_BSF(MOV2TEXTSUB,           mov2textsub);
     REGISTER_BSF(NOISE,                 noise);
     REGISTER_BSF(REMOVE_EXTRADATA,      remove_extradata);
diff --git a/libavcodec/alpha/Makefile b/libavcodec/alpha/Makefile
deleted file mode 100644
index e28200d..0000000
--- a/libavcodec/alpha/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-OBJS += alpha/dsputil_alpha.o                                           \
-        alpha/dsputil_alpha_asm.o                                       \
-        alpha/motion_est_alpha.o                                        \
-        alpha/motion_est_mvi_asm.o                                      \
-        alpha/simple_idct_alpha.o                                       \
-
-OBJS-$(CONFIG_MPEGVIDEO)                += alpha/mpegvideo_alpha.o
diff --git a/libavcodec/alpha/asm.h b/libavcodec/alpha/asm.h
deleted file mode 100644
index ab4cfcc..0000000
--- a/libavcodec/alpha/asm.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Alpha optimized DSP utils
- * Copyright (c) 2002 Falk Hueffner <falk at debian.org>
- *
- * 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_ALPHA_ASM_H
-#define AVCODEC_ALPHA_ASM_H
-
-#include <inttypes.h>
-
-#include "libavutil/common.h"
-
-#if AV_GCC_VERSION_AT_LEAST(2,96)
-# define likely(x)      __builtin_expect((x) != 0, 1)
-# define unlikely(x)    __builtin_expect((x) != 0, 0)
-#else
-# define likely(x)      (x)
-# define unlikely(x)    (x)
-#endif
-
-#define AMASK_BWX (1 << 0)
-#define AMASK_FIX (1 << 1)
-#define AMASK_CIX (1 << 2)
-#define AMASK_MVI (1 << 8)
-
-static inline uint64_t BYTE_VEC(uint64_t x)
-{
-    x |= x <<  8;
-    x |= x << 16;
-    x |= x << 32;
-    return x;
-}
-static inline uint64_t WORD_VEC(uint64_t x)
-{
-    x |= x << 16;
-    x |= x << 32;
-    return x;
-}
-
-#define sextw(x) ((int16_t) (x))
-
-#ifdef __GNUC__
-#define ldq(p)                                                  \
-    (((const union {                                            \
-        uint64_t __l;                                           \
-        __typeof__(*(p)) __s[sizeof (uint64_t) / sizeof *(p)];  \
-    } *) (p))->__l)
-#define ldl(p)                                                  \
-    (((const union {                                            \
-        int32_t __l;                                            \
-        __typeof__(*(p)) __s[sizeof (int32_t) / sizeof *(p)];   \
-    } *) (p))->__l)
-#define stq(l, p)                                                       \
-    do {                                                                \
-        (((union {                                                      \
-            uint64_t __l;                                               \
-            __typeof__(*(p)) __s[sizeof (uint64_t) / sizeof *(p)];      \
-        } *) (p))->__l) = l;                                            \
-    } while (0)
-#define stl(l, p)                                                       \
-    do {                                                                \
-        (((union {                                                      \
-            int32_t __l;                                                \
-            __typeof__(*(p)) __s[sizeof (int32_t) / sizeof *(p)];       \
-        } *) (p))->__l) = l;                                            \
-    } while (0)
-struct unaligned_long { uint64_t l; } __attribute__((packed));
-#define ldq_u(p)        (*(const uint64_t *) (((uint64_t) (p)) & ~7ul))
-#define uldq(a)         (((const struct unaligned_long *) (a))->l)
-
-#if AV_GCC_VERSION_AT_LEAST(3,3)
-#define prefetch(p)     __builtin_prefetch((p), 0, 1)
-#define prefetch_en(p)  __builtin_prefetch((p), 0, 0)
-#define prefetch_m(p)   __builtin_prefetch((p), 1, 1)
-#define prefetch_men(p) __builtin_prefetch((p), 1, 0)
-#define cmpbge          __builtin_alpha_cmpbge
-/* Avoid warnings.  */
-#define extql(a, b)     __builtin_alpha_extql(a, (uint64_t) (b))
-#define extwl(a, b)     __builtin_alpha_extwl(a, (uint64_t) (b))
-#define extqh(a, b)     __builtin_alpha_extqh(a, (uint64_t) (b))
-#define zap             __builtin_alpha_zap
-#define zapnot          __builtin_alpha_zapnot
-#define amask           __builtin_alpha_amask
-#define implver         __builtin_alpha_implver
-#define rpcc            __builtin_alpha_rpcc
-#else
-#define prefetch(p)     __asm__ volatile("ldl $31,%0"  : : "m"(*(const char *) (p)) : "memory")
-#define prefetch_en(p)  __asm__ volatile("ldq $31,%0"  : : "m"(*(const char *) (p)) : "memory")
-#define prefetch_m(p)   __asm__ volatile("lds $f31,%0" : : "m"(*(const char *) (p)) : "memory")
-#define prefetch_men(p) __asm__ volatile("ldt $f31,%0" : : "m"(*(const char *) (p)) : "memory")
-#define cmpbge(a, b) ({ uint64_t __r; __asm__ ("cmpbge  %r1,%2,%0"  : "=r" (__r) : "rJ"  (a), "rI" (b)); __r; })
-#define extql(a, b)  ({ uint64_t __r; __asm__ ("extql   %r1,%2,%0"  : "=r" (__r) : "rJ"  (a), "rI" (b)); __r; })
-#define extwl(a, b)  ({ uint64_t __r; __asm__ ("extwl   %r1,%2,%0"  : "=r" (__r) : "rJ"  (a), "rI" (b)); __r; })
-#define extqh(a, b)  ({ uint64_t __r; __asm__ ("extqh   %r1,%2,%0"  : "=r" (__r) : "rJ"  (a), "rI" (b)); __r; })
-#define zap(a, b)    ({ uint64_t __r; __asm__ ("zap     %r1,%2,%0"  : "=r" (__r) : "rJ"  (a), "rI" (b)); __r; })
-#define zapnot(a, b) ({ uint64_t __r; __asm__ ("zapnot  %r1,%2,%0"  : "=r" (__r) : "rJ"  (a), "rI" (b)); __r; })
-#define amask(a)     ({ uint64_t __r; __asm__ ("amask   %1,%0"      : "=r" (__r) : "rI"  (a));           __r; })
-#define implver()    ({ uint64_t __r; __asm__ ("implver %0"         : "=r" (__r));                       __r; })
-#define rpcc()       ({ uint64_t __r; __asm__ volatile ("rpcc %0"   : "=r" (__r));                       __r; })
-#endif
-#define wh64(p) __asm__ volatile("wh64 (%0)" : : "r"(p) : "memory")
-
-#if AV_GCC_VERSION_AT_LEAST(3,3) && defined(__alpha_max__)
-#define minub8  __builtin_alpha_minub8
-#define minsb8  __builtin_alpha_minsb8
-#define minuw4  __builtin_alpha_minuw4
-#define minsw4  __builtin_alpha_minsw4
-#define maxub8  __builtin_alpha_maxub8
-#define maxsb8  __builtin_alpha_maxsb8
-#define maxuw4  __builtin_alpha_maxuw4
-#define maxsw4  __builtin_alpha_maxsw4
-#define perr    __builtin_alpha_perr
-#define pklb    __builtin_alpha_pklb
-#define pkwb    __builtin_alpha_pkwb
-#define unpkbl  __builtin_alpha_unpkbl
-#define unpkbw  __builtin_alpha_unpkbw
-#else
-#define minub8(a, b) ({ uint64_t __r; __asm__ (".arch ev6; minub8  %r1,%2,%0"  : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
-#define minsb8(a, b) ({ uint64_t __r; __asm__ (".arch ev6; minsb8  %r1,%2,%0"  : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
-#define minuw4(a, b) ({ uint64_t __r; __asm__ (".arch ev6; minuw4  %r1,%2,%0"  : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
-#define minsw4(a, b) ({ uint64_t __r; __asm__ (".arch ev6; minsw4  %r1,%2,%0"  : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
-#define maxub8(a, b) ({ uint64_t __r; __asm__ (".arch ev6; maxub8  %r1,%2,%0"  : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
-#define maxsb8(a, b) ({ uint64_t __r; __asm__ (".arch ev6; maxsb8  %r1,%2,%0"  : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
-#define maxuw4(a, b) ({ uint64_t __r; __asm__ (".arch ev6; maxuw4  %r1,%2,%0"  : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
-#define maxsw4(a, b) ({ uint64_t __r; __asm__ (".arch ev6; maxsw4  %r1,%2,%0"  : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; })
-#define perr(a, b)   ({ uint64_t __r; __asm__ (".arch ev6; perr    %r1,%r2,%0" : "=r" (__r) : "%rJ" (a), "rJ" (b)); __r; })
-#define pklb(a)      ({ uint64_t __r; __asm__ (".arch ev6; pklb    %r1,%0"     : "=r" (__r) : "rJ"  (a));           __r; })
-#define pkwb(a)      ({ uint64_t __r; __asm__ (".arch ev6; pkwb    %r1,%0"     : "=r" (__r) : "rJ"  (a));           __r; })
-#define unpkbl(a)    ({ uint64_t __r; __asm__ (".arch ev6; unpkbl  %r1,%0"     : "=r" (__r) : "rJ"  (a));           __r; })
-#define unpkbw(a)    ({ uint64_t __r; __asm__ (".arch ev6; unpkbw  %r1,%0"     : "=r" (__r) : "rJ"  (a));           __r; })
-#endif
-
-#elif defined(__DECC)           /* Digital/Compaq/hp "ccc" compiler */
-
-#include <c_asm.h>
-#define ldq(p) (*(const uint64_t *) (p))
-#define ldl(p) (*(const int32_t *)  (p))
-#define stq(l, p) do { *(uint64_t *) (p) = (l); } while (0)
-#define stl(l, p) do { *(int32_t *)  (p) = (l); } while (0)
-#define ldq_u(a)     asm ("ldq_u   %v0,0(%a0)", a)
-#define uldq(a)      (*(const __unaligned uint64_t *) (a))
-#define cmpbge(a, b) asm ("cmpbge  %a0,%a1,%v0", a, b)
-#define extql(a, b)  asm ("extql   %a0,%a1,%v0", a, b)
-#define extwl(a, b)  asm ("extwl   %a0,%a1,%v0", a, b)
-#define extqh(a, b)  asm ("extqh   %a0,%a1,%v0", a, b)
-#define zap(a, b)    asm ("zap     %a0,%a1,%v0", a, b)
-#define zapnot(a, b) asm ("zapnot  %a0,%a1,%v0", a, b)
-#define amask(a)     asm ("amask   %a0,%v0", a)
-#define implver()    asm ("implver %v0")
-#define rpcc()       asm ("rpcc           %v0")
-#define minub8(a, b) asm ("minub8  %a0,%a1,%v0", a, b)
-#define minsb8(a, b) asm ("minsb8  %a0,%a1,%v0", a, b)
-#define minuw4(a, b) asm ("minuw4  %a0,%a1,%v0", a, b)
-#define minsw4(a, b) asm ("minsw4  %a0,%a1,%v0", a, b)
-#define maxub8(a, b) asm ("maxub8  %a0,%a1,%v0", a, b)
-#define maxsb8(a, b) asm ("maxsb8  %a0,%a1,%v0", a, b)
-#define maxuw4(a, b) asm ("maxuw4  %a0,%a1,%v0", a, b)
-#define maxsw4(a, b) asm ("maxsw4  %a0,%a1,%v0", a, b)
-#define perr(a, b)   asm ("perr    %a0,%a1,%v0", a, b)
-#define pklb(a)      asm ("pklb    %a0,%v0", a)
-#define pkwb(a)      asm ("pkwb    %a0,%v0", a)
-#define unpkbl(a)    asm ("unpkbl  %a0,%v0", a)
-#define unpkbw(a)    asm ("unpkbw  %a0,%v0", a)
-#define wh64(a)      asm ("wh64    %a0", a)
-
-#else
-#error "Unknown compiler!"
-#endif
-
-#endif /* AVCODEC_ALPHA_ASM_H */
diff --git a/libavcodec/alpha/dsputil_alpha.c b/libavcodec/alpha/dsputil_alpha.c
deleted file mode 100644
index ce7cecb..0000000
--- a/libavcodec/alpha/dsputil_alpha.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Alpha optimized DSP utils
- * Copyright (c) 2002 Falk Hueffner <falk at debian.org>
- *
- * 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 "libavcodec/dsputil.h"
-#include "dsputil_alpha.h"
-#include "asm.h"
-
-void (*put_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels,
-                                 int line_size);
-void (*add_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels,
-                                 int line_size);
-
-#if 0
-/* These functions were the base for the optimized assembler routines,
-   and remain here for documentation purposes.  */
-static void put_pixels_clamped_mvi(const DCTELEM *block, uint8_t *pixels,
-                                   int line_size)
-{
-    int i = 8;
-    uint64_t clampmask = zap(-1, 0xaa); /* 0x00ff00ff00ff00ff */
-
-    do {
-        uint64_t shorts0, shorts1;
-
-        shorts0 = ldq(block);
-        shorts0 = maxsw4(shorts0, 0);
-        shorts0 = minsw4(shorts0, clampmask);
-        stl(pkwb(shorts0), pixels);
-
-        shorts1 = ldq(block + 4);
-        shorts1 = maxsw4(shorts1, 0);
-        shorts1 = minsw4(shorts1, clampmask);
-        stl(pkwb(shorts1), pixels + 4);
-
-        pixels += line_size;
-        block += 8;
-    } while (--i);
-}
-
-void add_pixels_clamped_mvi(const DCTELEM *block, uint8_t *pixels,
-                            int line_size)
-{
-    int h = 8;
-    /* Keep this function a leaf function by generating the constants
-       manually (mainly for the hack value ;-).  */
-    uint64_t clampmask = zap(-1, 0xaa); /* 0x00ff00ff00ff00ff */
-    uint64_t signmask  = zap(-1, 0x33);
-    signmask ^= signmask >> 1;  /* 0x8000800080008000 */
-
-    do {
-        uint64_t shorts0, pix0, signs0;
-        uint64_t shorts1, pix1, signs1;
-
-        shorts0 = ldq(block);
-        shorts1 = ldq(block + 4);
-
-        pix0    = unpkbw(ldl(pixels));
-        /* Signed subword add (MMX paddw).  */
-        signs0  = shorts0 & signmask;
-        shorts0 &= ~signmask;
-        shorts0 += pix0;
-        shorts0 ^= signs0;
-        /* Clamp. */
-        shorts0 = maxsw4(shorts0, 0);
-        shorts0 = minsw4(shorts0, clampmask);
-
-        /* Next 4.  */
-        pix1    = unpkbw(ldl(pixels + 4));
-        signs1  = shorts1 & signmask;
-        shorts1 &= ~signmask;
-        shorts1 += pix1;
-        shorts1 ^= signs1;
-        shorts1 = maxsw4(shorts1, 0);
-        shorts1 = minsw4(shorts1, clampmask);
-
-        stl(pkwb(shorts0), pixels);
-        stl(pkwb(shorts1), pixels + 4);
-
-        pixels += line_size;
-        block += 8;
-    } while (--h);
-}
-#endif
-
-static void clear_blocks_axp(DCTELEM *blocks) {
-    uint64_t *p = (uint64_t *) blocks;
-    int n = sizeof(DCTELEM) * 6 * 64;
-
-    do {
-        p[0] = 0;
-        p[1] = 0;
-        p[2] = 0;
-        p[3] = 0;
-        p[4] = 0;
-        p[5] = 0;
-        p[6] = 0;
-        p[7] = 0;
-        p += 8;
-        n -= 8 * 8;
-    } while (n);
-}
-
-static inline uint64_t avg2_no_rnd(uint64_t a, uint64_t b)
-{
-    return (a & b) + (((a ^ b) & BYTE_VEC(0xfe)) >> 1);
-}
-
-static inline uint64_t avg2(uint64_t a, uint64_t b)
-{
-    return (a | b) - (((a ^ b) & BYTE_VEC(0xfe)) >> 1);
-}
-
-#if 0
-/* The XY2 routines basically utilize this scheme, but reuse parts in
-   each iteration.  */
-static inline uint64_t avg4(uint64_t l1, uint64_t l2, uint64_t l3, uint64_t l4)
-{
-    uint64_t r1 = ((l1 & ~BYTE_VEC(0x03)) >> 2)
-                + ((l2 & ~BYTE_VEC(0x03)) >> 2)
-                + ((l3 & ~BYTE_VEC(0x03)) >> 2)
-                + ((l4 & ~BYTE_VEC(0x03)) >> 2);
-    uint64_t r2 = ((  (l1 & BYTE_VEC(0x03))
-                    + (l2 & BYTE_VEC(0x03))
-                    + (l3 & BYTE_VEC(0x03))
-                    + (l4 & BYTE_VEC(0x03))
-                    + BYTE_VEC(0x02)) >> 2) & BYTE_VEC(0x03);
-    return r1 + r2;
-}
-#endif
-
-#define OP(LOAD, STORE)                         \
-    do {                                        \
-        STORE(LOAD(pixels), block);             \
-        pixels += line_size;                    \
-        block += line_size;                     \
-    } while (--h)
-
-#define OP_X2(LOAD, STORE)                                      \
-    do {                                                        \
-        uint64_t pix1, pix2;                                    \
-                                                                \
-        pix1 = LOAD(pixels);                                    \
-        pix2 = pix1 >> 8 | ((uint64_t) pixels[8] << 56);        \
-        STORE(AVG2(pix1, pix2), block);                         \
-        pixels += line_size;                                    \
-        block += line_size;                                     \
-    } while (--h)
-
-#define OP_Y2(LOAD, STORE)                      \
-    do {                                        \
-        uint64_t pix = LOAD(pixels);            \
-        do {                                    \
-            uint64_t next_pix;                  \
-                                                \
-            pixels += line_size;                \
-            next_pix = LOAD(pixels);            \
-            STORE(AVG2(pix, next_pix), block);  \
-            block += line_size;                 \
-            pix = next_pix;                     \
-        } while (--h);                          \
-    } while (0)
-
-#define OP_XY2(LOAD, STORE)                                                 \
-    do {                                                                    \
-        uint64_t pix1 = LOAD(pixels);                                       \
-        uint64_t pix2 = pix1 >> 8 | ((uint64_t) pixels[8] << 56);           \
-        uint64_t pix_l = (pix1 & BYTE_VEC(0x03))                            \
-                       + (pix2 & BYTE_VEC(0x03));                           \
-        uint64_t pix_h = ((pix1 & ~BYTE_VEC(0x03)) >> 2)                    \
-                       + ((pix2 & ~BYTE_VEC(0x03)) >> 2);                   \
-                                                                            \
-        do {                                                                \
-            uint64_t npix1, npix2;                                          \
-            uint64_t npix_l, npix_h;                                        \
-            uint64_t avg;                                                   \
-                                                                            \
-            pixels += line_size;                                            \
-            npix1 = LOAD(pixels);                                           \
-            npix2 = npix1 >> 8 | ((uint64_t) pixels[8] << 56);              \
-            npix_l = (npix1 & BYTE_VEC(0x03))                               \
-                   + (npix2 & BYTE_VEC(0x03));                              \
-            npix_h = ((npix1 & ~BYTE_VEC(0x03)) >> 2)                       \
-                   + ((npix2 & ~BYTE_VEC(0x03)) >> 2);                      \
-            avg = (((pix_l + npix_l + AVG4_ROUNDER) >> 2) & BYTE_VEC(0x03)) \
-                + pix_h + npix_h;                                           \
-            STORE(avg, block);                                              \
-                                                                            \
-            block += line_size;                                             \
-            pix_l = npix_l;                                                 \
-            pix_h = npix_h;                                                 \
-        } while (--h);                                                      \
-    } while (0)
-
-#define MAKE_OP(OPNAME, SUFF, OPKIND, STORE)                                \
-static void OPNAME ## _pixels ## SUFF ## _axp                               \
-        (uint8_t *restrict block, const uint8_t *restrict pixels,           \
-         int line_size, int h)                                              \
-{                                                                           \
-    if ((size_t) pixels & 0x7) {                                            \
-        OPKIND(uldq, STORE);                                                \
-    } else {                                                                \
-        OPKIND(ldq, STORE);                                                 \
-    }                                                                       \
-}                                                                           \
-                                                                            \
-static void OPNAME ## _pixels16 ## SUFF ## _axp                             \
-        (uint8_t *restrict block, const uint8_t *restrict pixels,           \
-         int line_size, int h)                                              \
-{                                                                           \
-    OPNAME ## _pixels ## SUFF ## _axp(block,     pixels,     line_size, h); \
-    OPNAME ## _pixels ## SUFF ## _axp(block + 8, pixels + 8, line_size, h); \
-}
-
-#define PIXOP(OPNAME, STORE)                    \
-    MAKE_OP(OPNAME, ,     OP,     STORE)        \
-    MAKE_OP(OPNAME, _x2,  OP_X2,  STORE)        \
-    MAKE_OP(OPNAME, _y2,  OP_Y2,  STORE)        \
-    MAKE_OP(OPNAME, _xy2, OP_XY2, STORE)
-
-/* Rounding primitives.  */
-#define AVG2 avg2
-#define AVG4 avg4
-#define AVG4_ROUNDER BYTE_VEC(0x02)
-#define STORE(l, b) stq(l, b)
-PIXOP(put, STORE);
-
-#undef STORE
-#define STORE(l, b) stq(AVG2(l, ldq(b)), b);
-PIXOP(avg, STORE);
-
-/* Not rounding primitives.  */
-#undef AVG2
-#undef AVG4
-#undef AVG4_ROUNDER
-#undef STORE
-#define AVG2 avg2_no_rnd
-#define AVG4 avg4_no_rnd
-#define AVG4_ROUNDER BYTE_VEC(0x01)
-#define STORE(l, b) stq(l, b)
-PIXOP(put_no_rnd, STORE);
-
-#undef STORE
-#define STORE(l, b) stq(AVG2(l, ldq(b)), b);
-PIXOP(avg_no_rnd, STORE);
-
-static void put_pixels16_axp_asm(uint8_t *block, const uint8_t *pixels,
-                                 int line_size, int h)
-{
-    put_pixels_axp_asm(block,     pixels,     line_size, h);
-    put_pixels_axp_asm(block + 8, pixels + 8, line_size, h);
-}
-
-void ff_dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx)
-{
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-    if (!high_bit_depth) {
-    c->put_pixels_tab[0][0] = put_pixels16_axp_asm;
-    c->put_pixels_tab[0][1] = put_pixels16_x2_axp;
-    c->put_pixels_tab[0][2] = put_pixels16_y2_axp;
-    c->put_pixels_tab[0][3] = put_pixels16_xy2_axp;
-
-    c->put_no_rnd_pixels_tab[0][0] = put_pixels16_axp_asm;
-    c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_axp;
-    c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_axp;
-    c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_axp;
-
-    c->avg_pixels_tab[0][0] = avg_pixels16_axp;
-    c->avg_pixels_tab[0][1] = avg_pixels16_x2_axp;
-    c->avg_pixels_tab[0][2] = avg_pixels16_y2_axp;
-    c->avg_pixels_tab[0][3] = avg_pixels16_xy2_axp;
-
-    c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_axp;
-    c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x2_axp;
-    c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y2_axp;
-    c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy2_axp;
-
-    c->put_pixels_tab[1][0] = put_pixels_axp_asm;
-    c->put_pixels_tab[1][1] = put_pixels_x2_axp;
-    c->put_pixels_tab[1][2] = put_pixels_y2_axp;
-    c->put_pixels_tab[1][3] = put_pixels_xy2_axp;
-
-    c->put_no_rnd_pixels_tab[1][0] = put_pixels_axp_asm;
-    c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels_x2_axp;
-    c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels_y2_axp;
-    c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels_xy2_axp;
-
-    c->avg_pixels_tab[1][0] = avg_pixels_axp;
-    c->avg_pixels_tab[1][1] = avg_pixels_x2_axp;
-    c->avg_pixels_tab[1][2] = avg_pixels_y2_axp;
-    c->avg_pixels_tab[1][3] = avg_pixels_xy2_axp;
-
-    c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels_axp;
-    c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels_x2_axp;
-    c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels_y2_axp;
-    c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels_xy2_axp;
-
-    c->clear_blocks = clear_blocks_axp;
-    }
-
-    /* amask clears all bits that correspond to present features.  */
-    if (amask(AMASK_MVI) == 0) {
-        c->put_pixels_clamped = put_pixels_clamped_mvi_asm;
-        c->add_pixels_clamped = add_pixels_clamped_mvi_asm;
-
-        if (!high_bit_depth)
-            c->get_pixels   = get_pixels_mvi;
-        c->diff_pixels      = diff_pixels_mvi;
-        c->sad[0]           = pix_abs16x16_mvi_asm;
-        c->sad[1]           = pix_abs8x8_mvi;
-        c->pix_abs[0][0]    = pix_abs16x16_mvi_asm;
-        c->pix_abs[1][0]    = pix_abs8x8_mvi;
-        c->pix_abs[0][1]    = pix_abs16x16_x2_mvi;
-        c->pix_abs[0][2]    = pix_abs16x16_y2_mvi;
-        c->pix_abs[0][3]    = pix_abs16x16_xy2_mvi;
-    }
-
-    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 &&
-        (avctx->idct_algo == FF_IDCT_AUTO ||
-         avctx->idct_algo == FF_IDCT_SIMPLEALPHA)) {
-        c->idct_put = ff_simple_idct_put_axp;
-        c->idct_add = ff_simple_idct_add_axp;
-        c->idct =     ff_simple_idct_axp;
-    }
-}
diff --git a/libavcodec/alpha/dsputil_alpha.h b/libavcodec/alpha/dsputil_alpha.h
deleted file mode 100644
index 0dcacab..0000000
--- a/libavcodec/alpha/dsputil_alpha.h
+++ /dev/null
@@ -1,50 +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 AVCODEC_ALPHA_DSPUTIL_ALPHA_H
-#define AVCODEC_ALPHA_DSPUTIL_ALPHA_H
-
-#include "libavcodec/dsputil.h"
-
-void ff_simple_idct_axp(DCTELEM *block);
-void ff_simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_add_axp(uint8_t *dest, int line_size, DCTELEM *block);
-
-void put_pixels_axp_asm(uint8_t *block, const uint8_t *pixels,
-                        int line_size, int h);
-void put_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels,
-                                int line_size);
-void add_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels,
-                                int line_size);
-extern void (*put_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels,
-                                        int line_size);
-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 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);
-int pix_abs16x16_mvi_asm(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-int pix_abs16x16_x2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-int pix_abs16x16_y2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-int pix_abs16x16_xy2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-
-
-#endif /* AVCODEC_ALPHA_DSPUTIL_ALPHA_H */
diff --git a/libavcodec/alpha/dsputil_alpha_asm.S b/libavcodec/alpha/dsputil_alpha_asm.S
deleted file mode 100644
index ca857ac..0000000
--- a/libavcodec/alpha/dsputil_alpha_asm.S
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Alpha optimized DSP utils
- * Copyright (c) 2002 Falk Hueffner <falk at debian.org>
- *
- * 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
- */
-
-/*
- * These functions are scheduled for pca56. They should work
- * reasonably on ev6, though.
- */
-
-#include "regdef.h"
-
-/* Some nicer register names.  */
-#define ta t10
-#define tb t11
-#define tc t12
-#define td AT
-/* Danger: these overlap with the argument list and the return value */
-#define te a5
-#define tf a4
-#define tg a3
-#define th v0
-
-        .set noat
-        .set noreorder
-        .arch pca56
-        .text
-
-/************************************************************************
- * void put_pixels_axp_asm(uint8_t *block, const uint8_t *pixels,
- *                         int line_size, int h)
- */
-        .align 6
-        .globl put_pixels_axp_asm
-        .ent put_pixels_axp_asm
-put_pixels_axp_asm:
-        .frame sp, 0, ra
-        .prologue 0
-
-        and     a1, 7, t0
-        beq     t0, $aligned
-
-        .align 4
-$unaligned:
-        ldq_u   t0, 0(a1)
-        ldq_u   t1, 8(a1)
-        addq    a1, a2, a1
-        nop
-
-        ldq_u   t2, 0(a1)
-        ldq_u   t3, 8(a1)
-        addq    a1, a2, a1
-        nop
-
-        ldq_u   t4, 0(a1)
-        ldq_u   t5, 8(a1)
-        addq    a1, a2, a1
-        nop
-
-        ldq_u   t6, 0(a1)
-        ldq_u   t7, 8(a1)
-        extql   t0, a1, t0
-        addq    a1, a2, a1
-
-        extqh   t1, a1, t1
-        addq    a0, a2, t8
-        extql   t2, a1, t2
-        addq    t8, a2, t9
-
-        extqh   t3, a1, t3
-        addq    t9, a2, ta
-        extql   t4, a1, t4
-        or      t0, t1, t0
-
-        extqh   t5, a1, t5
-        or      t2, t3, t2
-        extql   t6, a1, t6
-        or      t4, t5, t4
-
-        extqh   t7, a1, t7
-        or      t6, t7, t6
-        stq     t0, 0(a0)
-        stq     t2, 0(t8)
-
-        stq     t4, 0(t9)
-        subq    a3, 4, a3
-        stq     t6, 0(ta)
-        addq    ta, a2, a0
-
-        bne     a3, $unaligned
-        ret
-
-        .align 4
-$aligned:
-        ldq     t0, 0(a1)
-        addq    a1, a2, a1
-        ldq     t1, 0(a1)
-        addq    a1, a2, a1
-
-        ldq     t2, 0(a1)
-        addq    a1, a2, a1
-        ldq     t3, 0(a1)
-
-        addq    a0, a2, t4
-        addq    a1, a2, a1
-        addq    t4, a2, t5
-        subq    a3, 4, a3
-
-        stq     t0, 0(a0)
-        addq    t5, a2, t6
-        stq     t1, 0(t4)
-        addq    t6, a2, a0
-
-        stq     t2, 0(t5)
-        stq     t3, 0(t6)
-
-        bne     a3, $aligned
-        ret
-        .end put_pixels_axp_asm
-
-/************************************************************************
- * void put_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels,
- *                                 int line_size)
- */
-        .align 6
-        .globl put_pixels_clamped_mvi_asm
-        .ent put_pixels_clamped_mvi_asm
-put_pixels_clamped_mvi_asm:
-        .frame sp, 0, ra
-        .prologue 0
-
-        lda     t8, -1
-        lda     t9, 8           # loop counter
-        zap     t8, 0xaa, t8    # 00ff00ff00ff00ff
-
-        .align 4
-1:      ldq     t0,  0(a0)
-        ldq     t1,  8(a0)
-        ldq     t2, 16(a0)
-        ldq     t3, 24(a0)
-
-        maxsw4  t0, zero, t0
-        subq    t9, 2, t9
-        maxsw4  t1, zero, t1
-        lda     a0, 32(a0)
-
-        maxsw4  t2, zero, t2
-        addq    a1, a2, ta
-        maxsw4  t3, zero, t3
-        minsw4  t0, t8, t0
-
-        minsw4  t1, t8, t1
-        minsw4  t2, t8, t2
-        minsw4  t3, t8, t3
-        pkwb    t0, t0
-
-        pkwb    t1, t1
-        pkwb    t2, t2
-        pkwb    t3, t3
-        stl     t0, 0(a1)
-
-        stl     t1, 4(a1)
-        addq    ta, a2, a1
-        stl     t2, 0(ta)
-        stl     t3, 4(ta)
-
-        bne     t9, 1b
-        ret
-        .end put_pixels_clamped_mvi_asm
-
-/************************************************************************
- * void add_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels,
- *                                 int line_size)
- */
-        .align 6
-        .globl add_pixels_clamped_mvi_asm
-        .ent add_pixels_clamped_mvi_asm
-add_pixels_clamped_mvi_asm:
-        .frame sp, 0, ra
-        .prologue 0
-
-        lda     t1, -1
-        lda     th, 8
-        zap     t1, 0x33, tg
-        nop
-
-        srl     tg, 1, t0
-        xor     tg, t0, tg      # 0x8000800080008000
-        zap     t1, 0xaa, tf    # 0x00ff00ff00ff00ff
-
-        .align 4
-1:      ldl     t1, 0(a1)       # pix0 (try to hit cache line soon)
-        ldl     t4, 4(a1)       # pix1
-        addq    a1, a2, te      # pixels += line_size
-        ldq     t0, 0(a0)       # shorts0
-
-        ldl     t7, 0(te)       # pix2 (try to hit cache line soon)
-        ldl     ta, 4(te)       # pix3
-        ldq     t3, 8(a0)       # shorts1
-        ldq     t6, 16(a0)      # shorts2
-
-        ldq     t9, 24(a0)      # shorts3
-        unpkbw  t1, t1          # 0 0 (quarter/op no.)
-        and     t0, tg, t2      # 0 1
-        unpkbw  t4, t4          # 1 0
-
-        bic     t0, tg, t0      # 0 2
-        unpkbw  t7, t7          # 2 0
-        and     t3, tg, t5      # 1 1
-        addq    t0, t1, t0      # 0 3
-
-        xor     t0, t2, t0      # 0 4
-        unpkbw  ta, ta          # 3 0
-        and     t6, tg, t8      # 2 1
-        maxsw4  t0, zero, t0    # 0 5
-
-        bic     t3, tg, t3      # 1 2
-        bic     t6, tg, t6      # 2 2
-        minsw4  t0, tf, t0      # 0 6
-        addq    t3, t4, t3      # 1 3
-
-        pkwb    t0, t0          # 0 7
-        xor     t3, t5, t3      # 1 4
-        maxsw4  t3, zero, t3    # 1 5
-        addq    t6, t7, t6      # 2 3
-
-        xor     t6, t8, t6      # 2 4
-        and     t9, tg, tb      # 3 1
-        minsw4  t3, tf, t3      # 1 6
-        bic     t9, tg, t9      # 3 2
-
-        maxsw4  t6, zero, t6    # 2 5
-        addq    t9, ta, t9      # 3 3
-        stl     t0, 0(a1)       # 0 8
-        minsw4  t6, tf, t6      # 2 6
-
-        xor     t9, tb, t9      # 3 4
-        maxsw4  t9, zero, t9    # 3 5
-        lda     a0, 32(a0)      # block += 16;
-        pkwb    t3, t3          # 1 7
-
-        minsw4  t9, tf, t9      # 3 6
-        subq    th, 2, th
-        pkwb    t6, t6          # 2 7
-        pkwb    t9, t9          # 3 7
-
-        stl     t3, 4(a1)       # 1 8
-        addq    te, a2, a1      # pixels += line_size
-        stl     t6, 0(te)       # 2 8
-        stl     t9, 4(te)       # 3 8
-
-        bne     th, 1b
-        ret
-        .end add_pixels_clamped_mvi_asm
diff --git a/libavcodec/alpha/motion_est_alpha.c b/libavcodec/alpha/motion_est_alpha.c
deleted file mode 100644
index bb9ab13..0000000
--- a/libavcodec/alpha/motion_est_alpha.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Alpha optimized DSP utils
- * Copyright (c) 2002 Falk Hueffner <falk at debian.org>
- *
- * 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 "libavcodec/dsputil.h"
-#include "dsputil_alpha.h"
-#include "asm.h"
-
-void get_pixels_mvi(DCTELEM *restrict block,
-                    const uint8_t *restrict pixels, int line_size)
-{
-    int h = 8;
-
-    do {
-        uint64_t p;
-
-        p = ldq(pixels);
-        stq(unpkbw(p),       block);
-        stq(unpkbw(p >> 32), block + 4);
-
-        pixels += line_size;
-        block += 8;
-    } while (--h);
-}
-
-void diff_pixels_mvi(DCTELEM *block, const uint8_t *s1, const uint8_t *s2,
-                     int stride) {
-    int h = 8;
-    uint64_t mask = 0x4040;
-
-    mask |= mask << 16;
-    mask |= mask << 32;
-    do {
-        uint64_t x, y, c, d, a;
-        uint64_t signs;
-
-        x = ldq(s1);
-        y = ldq(s2);
-        c = cmpbge(x, y);
-        d = x - y;
-        a = zap(mask, c);       /* We use 0x4040404040404040 here...  */
-        d += 4 * a;             /* ...so we can use s4addq here.      */
-        signs = zap(-1, c);
-
-        stq(unpkbw(d)       | (unpkbw(signs)       << 8), block);
-        stq(unpkbw(d >> 32) | (unpkbw(signs >> 32) << 8), block + 4);
-
-        s1 += stride;
-        s2 += stride;
-        block += 8;
-    } while (--h);
-}
-
-static inline uint64_t avg2(uint64_t a, uint64_t b)
-{
-    return (a | b) - (((a ^ b) & BYTE_VEC(0xfe)) >> 1);
-}
-
-static inline uint64_t avg4(uint64_t l1, uint64_t l2, uint64_t l3, uint64_t l4)
-{
-    uint64_t r1 = ((l1 & ~BYTE_VEC(0x03)) >> 2)
-                + ((l2 & ~BYTE_VEC(0x03)) >> 2)
-                + ((l3 & ~BYTE_VEC(0x03)) >> 2)
-                + ((l4 & ~BYTE_VEC(0x03)) >> 2);
-    uint64_t r2 = ((  (l1 & BYTE_VEC(0x03))
-                    + (l2 & BYTE_VEC(0x03))
-                    + (l3 & BYTE_VEC(0x03))
-                    + (l4 & BYTE_VEC(0x03))
-                    + BYTE_VEC(0x02)) >> 2) & BYTE_VEC(0x03);
-    return r1 + r2;
-}
-
-int pix_abs8x8_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    int result = 0;
-
-    if ((size_t) pix2 & 0x7) {
-        /* works only when pix2 is actually unaligned */
-        do {                    /* do 8 pixel a time */
-            uint64_t p1, p2;
-
-            p1  = ldq(pix1);
-            p2  = uldq(pix2);
-            result += perr(p1, p2);
-
-            pix1 += line_size;
-            pix2 += line_size;
-        } while (--h);
-    } else {
-        do {
-            uint64_t p1, p2;
-
-            p1 = ldq(pix1);
-            p2 = ldq(pix2);
-            result += perr(p1, p2);
-
-            pix1 += line_size;
-            pix2 += line_size;
-        } while (--h);
-    }
-
-    return result;
-}
-
-#if 0                           /* now done in assembly */
-int pix_abs16x16_mvi(uint8_t *pix1, uint8_t *pix2, int line_size)
-{
-    int result = 0;
-    int h = 16;
-
-    if ((size_t) pix2 & 0x7) {
-        /* works only when pix2 is actually unaligned */
-        do {                    /* do 16 pixel a time */
-            uint64_t p1_l, p1_r, p2_l, p2_r;
-            uint64_t t;
-
-            p1_l  = ldq(pix1);
-            p1_r  = ldq(pix1 + 8);
-            t     = ldq_u(pix2 + 8);
-            p2_l  = extql(ldq_u(pix2), pix2) | extqh(t, pix2);
-            p2_r  = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2);
-            pix1 += line_size;
-            pix2 += line_size;
-
-            result += perr(p1_l, p2_l)
-                    + perr(p1_r, p2_r);
-        } while (--h);
-    } else {
-        do {
-            uint64_t p1_l, p1_r, p2_l, p2_r;
-
-            p1_l = ldq(pix1);
-            p1_r = ldq(pix1 + 8);
-            p2_l = ldq(pix2);
-            p2_r = ldq(pix2 + 8);
-            pix1 += line_size;
-            pix2 += line_size;
-
-            result += perr(p1_l, p2_l)
-                    + perr(p1_r, p2_r);
-        } while (--h);
-    }
-
-    return result;
-}
-#endif
-
-int pix_abs16x16_x2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    int result = 0;
-    uint64_t disalign = (size_t) pix2 & 0x7;
-
-    switch (disalign) {
-    case 0:
-        do {
-            uint64_t p1_l, p1_r, p2_l, p2_r;
-            uint64_t l, r;
-
-            p1_l = ldq(pix1);
-            p1_r = ldq(pix1 + 8);
-            l    = ldq(pix2);
-            r    = ldq(pix2 + 8);
-            p2_l = avg2(l, (l >> 8) | ((uint64_t) r << 56));
-            p2_r = avg2(r, (r >> 8) | ((uint64_t) pix2[16] << 56));
-            pix1 += line_size;
-            pix2 += line_size;
-
-            result += perr(p1_l, p2_l)
-                    + perr(p1_r, p2_r);
-        } while (--h);
-        break;
-    case 7:
-        /* |.......l|lllllllr|rrrrrrr*|
-           This case is special because disalign1 would be 8, which
-           gets treated as 0 by extqh.  At least it is a bit faster
-           that way :)  */
-        do {
-            uint64_t p1_l, p1_r, p2_l, p2_r;
-            uint64_t l, m, r;
-
-            p1_l = ldq(pix1);
-            p1_r = ldq(pix1 + 8);
-            l     = ldq_u(pix2);
-            m     = ldq_u(pix2 + 8);
-            r     = ldq_u(pix2 + 16);
-            p2_l  = avg2(extql(l, disalign) | extqh(m, disalign), m);
-            p2_r  = avg2(extql(m, disalign) | extqh(r, disalign), r);
-            pix1 += line_size;
-            pix2 += line_size;
-
-            result += perr(p1_l, p2_l)
-                    + perr(p1_r, p2_r);
-        } while (--h);
-        break;
-    default:
-        do {
-            uint64_t disalign1 = disalign + 1;
-            uint64_t p1_l, p1_r, p2_l, p2_r;
-            uint64_t l, m, r;
-
-            p1_l  = ldq(pix1);
-            p1_r  = ldq(pix1 + 8);
-            l     = ldq_u(pix2);
-            m     = ldq_u(pix2 + 8);
-            r     = ldq_u(pix2 + 16);
-            p2_l  = avg2(extql(l, disalign) | extqh(m, disalign),
-                         extql(l, disalign1) | extqh(m, disalign1));
-            p2_r  = avg2(extql(m, disalign) | extqh(r, disalign),
-                         extql(m, disalign1) | extqh(r, disalign1));
-            pix1 += line_size;
-            pix2 += line_size;
-
-            result += perr(p1_l, p2_l)
-                    + perr(p1_r, p2_r);
-        } while (--h);
-        break;
-    }
-    return result;
-}
-
-int pix_abs16x16_y2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    int result = 0;
-
-    if ((size_t) pix2 & 0x7) {
-        uint64_t t, p2_l, p2_r;
-        t     = ldq_u(pix2 + 8);
-        p2_l  = extql(ldq_u(pix2), pix2) | extqh(t, pix2);
-        p2_r  = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2);
-
-        do {
-            uint64_t p1_l, p1_r, np2_l, np2_r;
-            uint64_t t;
-
-            p1_l  = ldq(pix1);
-            p1_r  = ldq(pix1 + 8);
-            pix2 += line_size;
-            t     = ldq_u(pix2 + 8);
-            np2_l = extql(ldq_u(pix2), pix2) | extqh(t, pix2);
-            np2_r = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2);
-
-            result += perr(p1_l, avg2(p2_l, np2_l))
-                    + perr(p1_r, avg2(p2_r, np2_r));
-
-            pix1 += line_size;
-            p2_l  = np2_l;
-            p2_r  = np2_r;
-
-        } while (--h);
-    } else {
-        uint64_t p2_l, p2_r;
-        p2_l = ldq(pix2);
-        p2_r = ldq(pix2 + 8);
-        do {
-            uint64_t p1_l, p1_r, np2_l, np2_r;
-
-            p1_l = ldq(pix1);
-            p1_r = ldq(pix1 + 8);
-            pix2 += line_size;
-            np2_l = ldq(pix2);
-            np2_r = ldq(pix2 + 8);
-
-            result += perr(p1_l, avg2(p2_l, np2_l))
-                    + perr(p1_r, avg2(p2_r, np2_r));
-
-            pix1 += line_size;
-            p2_l  = np2_l;
-            p2_r  = np2_r;
-        } while (--h);
-    }
-    return result;
-}
-
-int pix_abs16x16_xy2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    int result = 0;
-
-    uint64_t p1_l, p1_r;
-    uint64_t p2_l, p2_r, p2_x;
-
-    p1_l = ldq(pix1);
-    p1_r = ldq(pix1 + 8);
-
-    if ((size_t) pix2 & 0x7) { /* could be optimized a lot */
-        p2_l = uldq(pix2);
-        p2_r = uldq(pix2 + 8);
-        p2_x = (uint64_t) pix2[16] << 56;
-    } else {
-        p2_l = ldq(pix2);
-        p2_r = ldq(pix2 + 8);
-        p2_x = ldq(pix2 + 16) << 56;
-    }
-
-    do {
-        uint64_t np1_l, np1_r;
-        uint64_t np2_l, np2_r, np2_x;
-
-        pix1 += line_size;
-        pix2 += line_size;
-
-        np1_l = ldq(pix1);
-        np1_r = ldq(pix1 + 8);
-
-        if ((size_t) pix2 & 0x7) { /* could be optimized a lot */
-            np2_l = uldq(pix2);
-            np2_r = uldq(pix2 + 8);
-            np2_x = (uint64_t) pix2[16] << 56;
-        } else {
-            np2_l = ldq(pix2);
-            np2_r = ldq(pix2 + 8);
-            np2_x = ldq(pix2 + 16) << 56;
-        }
-
-        result += perr(p1_l,
-                       avg4( p2_l, ( p2_l >> 8) | ((uint64_t)  p2_r << 56),
-                            np2_l, (np2_l >> 8) | ((uint64_t) np2_r << 56)))
-                + perr(p1_r,
-                       avg4( p2_r, ( p2_r >> 8) | ((uint64_t)  p2_x),
-                            np2_r, (np2_r >> 8) | ((uint64_t) np2_x)));
-
-        p1_l = np1_l;
-        p1_r = np1_r;
-        p2_l = np2_l;
-        p2_r = np2_r;
-        p2_x = np2_x;
-    } while (--h);
-
-    return result;
-}
diff --git a/libavcodec/alpha/motion_est_mvi_asm.S b/libavcodec/alpha/motion_est_mvi_asm.S
deleted file mode 100644
index 7fe4e16..0000000
--- a/libavcodec/alpha/motion_est_mvi_asm.S
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Alpha optimized DSP utils
- * Copyright (c) 2002 Falk Hueffner <falk at debian.org>
- *
- * 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 "regdef.h"
-
-/* Some nicer register names.  */
-#define ta t10
-#define tb t11
-#define tc t12
-#define td AT
-/* Danger: these overlap with the argument list and the return value */
-#define te a5
-#define tf a4
-#define tg a3
-#define th v0
-
-        .set noat
-        .set noreorder
-        .arch pca56
-        .text
-
-/*****************************************************************************
- * int pix_abs16x16_mvi_asm(uint8_t *pix1, uint8_t *pix2, int line_size)
- *
- * This code is written with a pca56 in mind. For ev6, one should
- * really take the increased latency of 3 cycles for MVI instructions
- * into account.
- *
- * It is important to keep the loading and first use of a register as
- * far apart as possible, because if a register is accessed before it
- * has been fetched from memory, the CPU will stall.
- */
-        .align 4
-        .globl pix_abs16x16_mvi_asm
-        .ent pix_abs16x16_mvi_asm
-pix_abs16x16_mvi_asm:
-        .frame sp, 0, ra, 0
-        .prologue 0
-
-        and     a2, 7, t0
-        clr     v0
-        beq     t0, $aligned
-        .align 4
-$unaligned:
-        /* Registers:
-           line 0:
-           t0:  left_u -> left lo -> left
-           t1:  mid
-           t2:  right_u -> right hi -> right
-           t3:  ref left
-           t4:  ref right
-           line 1:
-           t5:  left_u -> left lo -> left
-           t6:  mid
-           t7:  right_u -> right hi -> right
-           t8:  ref left
-           t9:  ref right
-           temp:
-           ta:  left hi
-           tb:  right lo
-           tc:  error left
-           td:  error right  */
-
-        /* load line 0 */
-        ldq_u   t0, 0(a2)       # left_u
-        ldq_u   t1, 8(a2)       # mid
-        ldq_u   t2, 16(a2)      # right_u
-        ldq     t3, 0(a1)       # ref left
-        ldq     t4, 8(a1)       # ref right
-        addq    a1, a3, a1      # pix1
-        addq    a2, a3, a2      # pix2
-        /* load line 1 */
-        ldq_u   t5, 0(a2)       # left_u
-        ldq_u   t6, 8(a2)       # mid
-        ldq_u   t7, 16(a2)      # right_u
-        ldq     t8, 0(a1)       # ref left
-        ldq     t9, 8(a1)       # ref right
-        addq    a1, a3, a1      # pix1
-        addq    a2, a3, a2      # pix2
-        /* calc line 0 */
-        extql   t0, a2, t0      # left lo
-        extqh   t1, a2, ta      # left hi
-        extql   t1, a2, tb      # right lo
-        or      t0, ta, t0      # left
-        extqh   t2, a2, t2      # right hi
-        perr    t3, t0, tc      # error left
-        or      t2, tb, t2      # right
-        perr    t4, t2, td      # error right
-        addq    v0, tc, v0      # add error left
-        addq    v0, td, v0      # add error left
-        /* calc line 1 */
-        extql   t5, a2, t5      # left lo
-        extqh   t6, a2, ta      # left hi
-        extql   t6, a2, tb      # right lo
-        or      t5, ta, t5      # left
-        extqh   t7, a2, t7      # right hi
-        perr    t8, t5, tc      # error left
-        or      t7, tb, t7      # right
-        perr    t9, t7, td      # error right
-        addq    v0, tc, v0      # add error left
-        addq    v0, td, v0      # add error left
-        /* loop */
-        subq    a4,  2, a4      # h -= 2
-        bne     a4, $unaligned
-        ret
-
-        .align 4
-$aligned:
-        /* load line 0 */
-        ldq     t0, 0(a2)       # left
-        ldq     t1, 8(a2)       # right
-        addq    a2, a3, a2      # pix2
-        ldq     t2, 0(a1)       # ref left
-        ldq     t3, 8(a1)       # ref right
-        addq    a1, a3, a1      # pix1
-        /* load line 1 */
-        ldq     t4, 0(a2)       # left
-        ldq     t5, 8(a2)       # right
-        addq    a2, a3, a2      # pix2
-        ldq     t6, 0(a1)       # ref left
-        ldq     t7, 8(a1)       # ref right
-        addq    a1, a3, a1      # pix1
-        /* load line 2 */
-        ldq     t8, 0(a2)       # left
-        ldq     t9, 8(a2)       # right
-        addq    a2, a3, a2      # pix2
-        ldq     ta, 0(a1)       # ref left
-        ldq     tb, 8(a1)       # ref right
-        addq    a1, a3, a1      # pix1
-        /* load line 3 */
-        ldq     tc, 0(a2)       # left
-        ldq     td, 8(a2)       # right
-        addq    a2, a3, a2      # pix2
-        ldq     te, 0(a1)       # ref left
-        ldq     a0, 8(a1)       # ref right
-        /* calc line 0 */
-        perr    t0, t2, t0      # error left
-        addq    a1, a3, a1      # pix1
-        perr    t1, t3, t1      # error right
-        addq    v0, t0, v0      # add error left
-        /* calc line 1 */
-        perr    t4, t6, t0      # error left
-        addq    v0, t1, v0      # add error right
-        perr    t5, t7, t1      # error right
-        addq    v0, t0, v0      # add error left
-        /* calc line 2 */
-        perr    t8, ta, t0      # error left
-        addq    v0, t1, v0      # add error right
-        perr    t9, tb, t1      # error right
-        addq    v0, t0, v0      # add error left
-        /* calc line 3 */
-        perr    tc, te, t0      # error left
-        addq    v0, t1, v0      # add error right
-        perr    td, a0, t1      # error right
-        addq    v0, t0, v0      # add error left
-        addq    v0, t1, v0      # add error right
-        /* loop */
-        subq    a4,  4, a4      # h -= 4
-        bne     a4, $aligned
-        ret
-        .end pix_abs16x16_mvi_asm
diff --git a/libavcodec/alpha/mpegvideo_alpha.c b/libavcodec/alpha/mpegvideo_alpha.c
deleted file mode 100644
index a1a8a27..0000000
--- a/libavcodec/alpha/mpegvideo_alpha.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Alpha optimized DSP utils
- * Copyright (c) 2002 Falk Hueffner <falk at debian.org>
- *
- * 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 "libavcodec/dsputil.h"
-#include "libavcodec/mpegvideo.h"
-#include "asm.h"
-
-static void dct_unquantize_h263_axp(DCTELEM *block, int n_coeffs,
-                                    uint64_t qscale, uint64_t qadd)
-{
-    uint64_t qmul = qscale << 1;
-    uint64_t correction = WORD_VEC(qmul * 255 >> 8);
-    int i;
-
-    qadd = WORD_VEC(qadd);
-
-    for(i = 0; i <= n_coeffs; block += 4, i += 4) {
-        uint64_t levels, negmask, zeros, add, sub;
-
-        levels = ldq(block);
-        if (levels == 0)
-            continue;
-
-#ifdef __alpha_max__
-        /* I don't think the speed difference justifies runtime
-           detection.  */
-        negmask = maxsw4(levels, -1); /* negative -> ffff (-1) */
-        negmask = minsw4(negmask, 0); /* positive -> 0000 (0) */
-#else
-        negmask = cmpbge(WORD_VEC(0x7fff), levels);
-        negmask &= (negmask >> 1) | (1 << 7);
-        negmask = zap(-1, negmask);
-#endif
-
-        zeros = cmpbge(0, levels);
-        zeros &= zeros >> 1;
-        /* zeros |= zeros << 1 is not needed since qadd <= 255, so
-           zapping the lower byte suffices.  */
-
-        levels *= qmul;
-        levels -= correction & (negmask << 16);
-
-        add = qadd & ~negmask;
-        sub = qadd &  negmask;
-        /* Set qadd to 0 for levels == 0.  */
-        add = zap(add, zeros);
-        levels += add;
-        levels -= sub;
-
-        stq(levels, block);
-    }
-}
-
-static void dct_unquantize_h263_intra_axp(MpegEncContext *s, DCTELEM *block,
-                                    int n, int qscale)
-{
-    int n_coeffs;
-    uint64_t qadd;
-    DCTELEM block0 = block[0];
-
-    if (!s->h263_aic) {
-        if (n < 4)
-            block0 *= s->y_dc_scale;
-        else
-            block0 *= s->c_dc_scale;
-        qadd = (qscale - 1) | 1;
-    } else {
-        qadd = 0;
-    }
-
-    if(s->ac_pred)
-        n_coeffs = 63;
-    else
-        n_coeffs = s->inter_scantable.raster_end[s->block_last_index[n]];
-
-    dct_unquantize_h263_axp(block, n_coeffs, qscale, qadd);
-
-    block[0] = block0;
-}
-
-static void dct_unquantize_h263_inter_axp(MpegEncContext *s, DCTELEM *block,
-                                    int n, int qscale)
-{
-    int n_coeffs = s->inter_scantable.raster_end[s->block_last_index[n]];
-    dct_unquantize_h263_axp(block, n_coeffs, qscale, (qscale - 1) | 1);
-}
-
-void ff_MPV_common_init_axp(MpegEncContext *s)
-{
-    s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_axp;
-    s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_axp;
-}
diff --git a/libavcodec/alpha/regdef.h b/libavcodec/alpha/regdef.h
deleted file mode 100644
index fa9ad98..0000000
--- a/libavcodec/alpha/regdef.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Alpha optimized DSP utils
- * copyright (c) 2002 Falk Hueffner <falk at debian.org>
- *
- * 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
- */
-
-/* Some BSDs don't seem to have regdef.h... sigh  */
-#ifndef AVCODEC_ALPHA_REGDEF_H
-#define AVCODEC_ALPHA_REGDEF_H
-
-#define v0      $0      /* function return value */
-
-#define t0      $1      /* temporary registers (caller-saved) */
-#define t1      $2
-#define t2      $3
-#define t3      $4
-#define t4      $5
-#define t5      $6
-#define t6      $7
-#define t7      $8
-
-#define s0      $9      /* saved-registers (callee-saved registers) */
-#define s1      $10
-#define s2      $11
-#define s3      $12
-#define s4      $13
-#define s5      $14
-#define s6      $15
-#define fp      s6      /* frame-pointer (s6 in frame-less procedures) */
-
-#define a0      $16     /* argument registers (caller-saved) */
-#define a1      $17
-#define a2      $18
-#define a3      $19
-#define a4      $20
-#define a5      $21
-
-#define t8      $22     /* more temps (caller-saved) */
-#define t9      $23
-#define t10     $24
-#define t11     $25
-#define ra      $26     /* return address register */
-#define t12     $27
-
-#define pv      t12     /* procedure-variable register */
-#define AT      $at     /* assembler temporary */
-#define gp      $29     /* global pointer */
-#define sp      $30     /* stack pointer */
-#define zero    $31     /* reads as zero, writes are noops */
-
-#endif /* AVCODEC_ALPHA_REGDEF_H */
diff --git a/libavcodec/alpha/simple_idct_alpha.c b/libavcodec/alpha/simple_idct_alpha.c
deleted file mode 100644
index 61bc5f2..0000000
--- a/libavcodec/alpha/simple_idct_alpha.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Simple IDCT (Alpha optimized)
- *
- * Copyright (c) 2001 Michael Niedermayer <michaelni at gmx.at>
- *
- * based upon some outcommented C code from mpeg2dec (idct_mmx.c
- * written by Aaron Holtzman <aholtzma at ess.engr.uvic.ca>)
- *
- * Alpha optimizations by Måns Rullgård <mans at mansr.com>
- *                     and Falk Hueffner <falk at debian.org>
- *
- * 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 "libavcodec/dsputil.h"
-#include "dsputil_alpha.h"
-#include "asm.h"
-
-// cos(i * M_PI / 16) * sqrt(2) * (1 << 14)
-// W4 is actually exactly 16384, but using 16383 works around
-// accumulating rounding errors for some encoders
-#define W1 22725
-#define W2 21407
-#define W3 19266
-#define W4 16383
-#define W5 12873
-#define W6  8867
-#define W7  4520
-#define ROW_SHIFT 11
-#define COL_SHIFT 20
-
-/* 0: all entries 0, 1: only first entry nonzero, 2: otherwise  */
-static inline int idct_row(DCTELEM *row)
-{
-    int a0, a1, a2, a3, b0, b1, b2, b3, t;
-    uint64_t l, r, t2;
-    l = ldq(row);
-    r = ldq(row + 4);
-
-    if (l == 0 && r == 0)
-        return 0;
-
-    a0 = W4 * sextw(l) + (1 << (ROW_SHIFT - 1));
-
-    if (((l & ~0xffffUL) | r) == 0) {
-        a0 >>= ROW_SHIFT;
-        t2 = (uint16_t) a0;
-        t2 |= t2 << 16;
-        t2 |= t2 << 32;
-
-        stq(t2, row);
-        stq(t2, row + 4);
-        return 1;
-    }
-
-    a1 = a0;
-    a2 = a0;
-    a3 = a0;
-
-    t = extwl(l, 4);            /* row[2] */
-    if (t != 0) {
-        t = sextw(t);
-        a0 += W2 * t;
-        a1 += W6 * t;
-        a2 -= W6 * t;
-        a3 -= W2 * t;
-    }
-
-    t = extwl(r, 0);            /* row[4] */
-    if (t != 0) {
-        t = sextw(t);
-        a0 += W4 * t;
-        a1 -= W4 * t;
-        a2 -= W4 * t;
-        a3 += W4 * t;
-    }
-
-    t = extwl(r, 4);            /* row[6] */
-    if (t != 0) {
-        t = sextw(t);
-        a0 += W6 * t;
-        a1 -= W2 * t;
-        a2 += W2 * t;
-        a3 -= W6 * t;
-    }
-
-    t = extwl(l, 2);            /* row[1] */
-    if (t != 0) {
-        t = sextw(t);
-        b0 = W1 * t;
-        b1 = W3 * t;
-        b2 = W5 * t;
-        b3 = W7 * t;
-    } else {
-        b0 = 0;
-        b1 = 0;
-        b2 = 0;
-        b3 = 0;
-    }
-
-    t = extwl(l, 6);            /* row[3] */
-    if (t) {
-        t = sextw(t);
-        b0 += W3 * t;
-        b1 -= W7 * t;
-        b2 -= W1 * t;
-        b3 -= W5 * t;
-    }
-
-
-    t = extwl(r, 2);            /* row[5] */
-    if (t) {
-        t = sextw(t);
-        b0 += W5 * t;
-        b1 -= W1 * t;
-        b2 += W7 * t;
-        b3 += W3 * t;
-    }
-
-    t = extwl(r, 6);            /* row[7] */
-    if (t) {
-        t = sextw(t);
-        b0 += W7 * t;
-        b1 -= W5 * t;
-        b2 += W3 * t;
-        b3 -= W1 * t;
-    }
-
-    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;
-
-    return 2;
-}
-
-static inline void idct_col(DCTELEM *col)
-{
-    int a0, a1, a2, a3, b0, b1, b2, b3;
-
-    col[0] += (1 << (COL_SHIFT - 1)) / W4;
-
-    a0 = W4 * col[8 * 0];
-    a1 = W4 * col[8 * 0];
-    a2 = W4 * col[8 * 0];
-    a3 = W4 * col[8 * 0];
-
-    if (col[8 * 2]) {
-        a0 += W2 * col[8 * 2];
-        a1 += W6 * col[8 * 2];
-        a2 -= W6 * col[8 * 2];
-        a3 -= W2 * col[8 * 2];
-    }
-
-    if (col[8 * 4]) {
-        a0 += W4 * col[8 * 4];
-        a1 -= W4 * col[8 * 4];
-        a2 -= W4 * col[8 * 4];
-        a3 += W4 * col[8 * 4];
-    }
-
-    if (col[8 * 6]) {
-        a0 += W6 * col[8 * 6];
-        a1 -= W2 * col[8 * 6];
-        a2 += W2 * col[8 * 6];
-        a3 -= W6 * col[8 * 6];
-    }
-
-    if (col[8 * 1]) {
-        b0 = W1 * col[8 * 1];
-        b1 = W3 * col[8 * 1];
-        b2 = W5 * col[8 * 1];
-        b3 = W7 * col[8 * 1];
-    } else {
-        b0 = 0;
-        b1 = 0;
-        b2 = 0;
-        b3 = 0;
-    }
-
-    if (col[8 * 3]) {
-        b0 += W3 * col[8 * 3];
-        b1 -= W7 * col[8 * 3];
-        b2 -= W1 * col[8 * 3];
-        b3 -= W5 * col[8 * 3];
-    }
-
-    if (col[8 * 5]) {
-        b0 += W5 * col[8 * 5];
-        b1 -= W1 * col[8 * 5];
-        b2 += W7 * col[8 * 5];
-        b3 += W3 * col[8 * 5];
-    }
-
-    if (col[8 * 7]) {
-        b0 += W7 * col[8 * 7];
-        b1 -= W5 * col[8 * 7];
-        b2 += W3 * col[8 * 7];
-        b3 -= W1 * col[8 * 7];
-    }
-
-    col[8 * 0] = (a0 + b0) >> COL_SHIFT;
-    col[8 * 7] = (a0 - b0) >> COL_SHIFT;
-    col[8 * 1] = (a1 + b1) >> COL_SHIFT;
-    col[8 * 6] = (a1 - b1) >> COL_SHIFT;
-    col[8 * 2] = (a2 + b2) >> COL_SHIFT;
-    col[8 * 5] = (a2 - b2) >> COL_SHIFT;
-    col[8 * 3] = (a3 + b3) >> COL_SHIFT;
-    col[8 * 4] = (a3 - b3) >> COL_SHIFT;
-}
-
-/* If all rows but the first one are zero after row transformation,
-   all rows will be identical after column transformation.  */
-static inline void idct_col2(DCTELEM *col)
-{
-    int i;
-    uint64_t l, r;
-
-    for (i = 0; i < 8; ++i) {
-        int a0 = col[i] + (1 << (COL_SHIFT - 1)) / W4;
-
-        a0 *= W4;
-        col[i] = a0 >> COL_SHIFT;
-    }
-
-    l = ldq(col + 0 * 4); r = ldq(col + 1 * 4);
-    stq(l, col +  2 * 4); stq(r, col +  3 * 4);
-    stq(l, col +  4 * 4); stq(r, col +  5 * 4);
-    stq(l, col +  6 * 4); stq(r, col +  7 * 4);
-    stq(l, col +  8 * 4); stq(r, col +  9 * 4);
-    stq(l, col + 10 * 4); stq(r, col + 11 * 4);
-    stq(l, col + 12 * 4); stq(r, col + 13 * 4);
-    stq(l, col + 14 * 4); stq(r, col + 15 * 4);
-}
-
-void ff_simple_idct_axp(DCTELEM *block)
-{
-
-    int i;
-    int rowsZero = 1;           /* all rows except row 0 zero */
-    int rowsConstant = 1;       /* all rows consist of a constant value */
-
-    for (i = 0; i < 8; i++) {
-        int sparseness = idct_row(block + 8 * i);
-
-        if (i > 0 && sparseness > 0)
-            rowsZero = 0;
-        if (sparseness == 2)
-            rowsConstant = 0;
-    }
-
-    if (rowsZero) {
-        idct_col2(block);
-    } else if (rowsConstant) {
-        idct_col(block);
-        for (i = 0; i < 8; i += 2) {
-            uint64_t v = (uint16_t) block[0];
-            uint64_t w = (uint16_t) block[8];
-
-            v |= v << 16;
-            w |= w << 16;
-            v |= v << 32;
-            w |= w << 32;
-            stq(v, block + 0 * 4);
-            stq(v, block + 1 * 4);
-            stq(w, block + 2 * 4);
-            stq(w, block + 3 * 4);
-            block += 4 * 4;
-        }
-    } else {
-        for (i = 0; i < 8; i++)
-            idct_col(block + i);
-    }
-}
-
-void ff_simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block)
-{
-    ff_simple_idct_axp(block);
-    put_pixels_clamped_axp_p(block, dest, line_size);
-}
-
-void ff_simple_idct_add_axp(uint8_t *dest, int line_size, DCTELEM *block)
-{
-    ff_simple_idct_axp(block);
-    add_pixels_clamped_axp_p(block, dest, line_size);
-}
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index f1d01a2..f7dee7d 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -25,10 +25,6 @@
  * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
  */
 
-
-//#define DEBUG
-
-
 #include "avcodec.h"
 #include "get_bits.h"
 #include "unary.h"
@@ -192,7 +188,6 @@ typedef struct {
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame frame;
     ALSSpecificConfig sconf;
     GetBitContext gb;
     DSPContext dsp;
@@ -423,7 +418,8 @@ static int check_specific_config(ALSDecContext *ctx)
     #define MISSING_ERR(cond, str, errval)              \
     {                                                   \
         if (cond) {                                     \
-            av_log_missing_feature(ctx->avctx, str, 0); \
+            avpriv_report_missing_feature(ctx->avctx,   \
+                                          str);         \
             error = errval;                             \
         }                                               \
     }
@@ -1380,6 +1376,11 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
 
         for (b = 0; b < ctx->num_blocks; b++) {
             bd.block_length = div_blocks[b];
+            if (bd.block_length <= 0) {
+                av_log(ctx->avctx, AV_LOG_WARNING,
+                       "Invalid block length %d in channel data!\n", bd.block_length);
+                continue;
+            }
 
             for (c = 0; c < avctx->channels; c++) {
                 bd.const_block = ctx->const_block + c;
@@ -1445,6 +1446,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
                         AVPacket *avpkt)
 {
     ALSDecContext *ctx       = avctx->priv_data;
+    AVFrame *frame           = data;
     ALSSpecificConfig *sconf = &ctx->sconf;
     const uint8_t *buffer    = avpkt->data;
     int buffer_size          = avpkt->size;
@@ -1474,8 +1476,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
     ctx->frame_id++;
 
     /* get output buffer */
-    ctx->frame.nb_samples = ctx->cur_frame_length;
-    if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    frame->nb_samples = ctx->cur_frame_length;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -1483,7 +1485,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
     // transform decoded frame into output format
     #define INTERLEAVE_OUTPUT(bps)                                 \
     {                                                              \
-        int##bps##_t *dest = (int##bps##_t*)ctx->frame.data[0];    \
+        int##bps##_t *dest = (int##bps##_t*)frame->data[0];        \
         shift = bps - ctx->avctx->bits_per_raw_sample;             \
         for (sample = 0; sample < ctx->cur_frame_length; sample++) \
             for (c = 0; c < avctx->channels; c++)                  \
@@ -1501,7 +1503,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
         int swap = HAVE_BIGENDIAN != sconf->msb_first;
 
         if (ctx->avctx->bits_per_raw_sample == 24) {
-            int32_t *src = (int32_t *)ctx->frame.data[0];
+            int32_t *src = (int32_t *)frame->data[0];
 
             for (sample = 0;
                  sample < ctx->cur_frame_length * avctx->channels;
@@ -1522,7 +1524,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
 
             if (swap) {
                 if (ctx->avctx->bits_per_raw_sample <= 16) {
-                    int16_t *src  = (int16_t*) ctx->frame.data[0];
+                    int16_t *src  = (int16_t*) frame->data[0];
                     int16_t *dest = (int16_t*) ctx->crc_buffer;
                     for (sample = 0;
                          sample < ctx->cur_frame_length * avctx->channels;
@@ -1530,12 +1532,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
                         *dest++ = av_bswap16(src[sample]);
                 } else {
                     ctx->dsp.bswap_buf((uint32_t*)ctx->crc_buffer,
-                                       (uint32_t *)ctx->frame.data[0],
+                                       (uint32_t *)frame->data[0],
                                        ctx->cur_frame_length * avctx->channels);
                 }
                 crc_source = ctx->crc_buffer;
             } else {
-                crc_source = ctx->frame.data[0];
+                crc_source = frame->data[0];
             }
 
             ctx->crc = av_crc(ctx->crc_table, ctx->crc, crc_source,
@@ -1548,12 +1550,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
         if (ctx->cur_frame_length != sconf->frame_length &&
             ctx->crc_org != ctx->crc) {
             av_log(avctx, AV_LOG_ERROR, "CRC error.\n");
+            if (avctx->err_recognition & AV_EF_EXPLODE)
+                return AVERROR_INVALIDDATA;
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ctx->frame;
-
+    *got_frame_ptr = 1;
 
     bytes_read = invalid_frame ? buffer_size :
                                  (get_bits_count(&ctx->gb) + 7) >> 3;
@@ -1751,9 +1753,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     ff_dsputil_init(&ctx->dsp, avctx);
 
-    avcodec_get_frame_defaults(&ctx->frame);
-    avctx->coded_frame = &ctx->frame;
-
     return 0;
 
 fail:
@@ -1774,6 +1773,7 @@ static av_cold void flush(AVCodecContext *avctx)
 
 AVCodec ff_als_decoder = {
     .name           = "als",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MP4ALS,
     .priv_data_size = sizeof(ALSDecContext),
@@ -1782,5 +1782,4 @@ AVCodec ff_als_decoder = {
     .decode         = decode_frame,
     .flush          = flush,
     .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"),
 };
diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c
index 5c359a8..7692cf0 100644
--- a/libavcodec/amrnbdec.c
+++ b/libavcodec/amrnbdec.c
@@ -44,8 +44,8 @@
 #include <math.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "libavutil/common.h"
 #include "celp_filters.h"
 #include "acelp_filters.h"
@@ -96,7 +96,6 @@
 #define AMR_AGC_ALPHA      0.9
 
 typedef struct AMRContext {
-    AVFrame                         avframe; ///< AVFrame for decoded samples
     AMRNBFrame                        frame; ///< decoded AMR parameters (lsf coefficients, codebook indexes, etc)
     uint8_t             bad_frame_indicator; ///< bad frame ? 1 : 0
     enum Mode                cur_frame_mode;
@@ -157,7 +156,7 @@ static av_cold int amrnb_decode_init(AVCodecContext *avctx)
     int i;
 
     if (avctx->channels > 1) {
-        av_log_missing_feature(avctx, "multi-channel AMR", 0);
+        avpriv_report_missing_feature(avctx, "multi-channel AMR");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -177,9 +176,6 @@ static av_cold int amrnb_decode_init(AVCodecContext *avctx)
     for (i = 0; i < 4; i++)
         p->prediction_error[i] = MIN_ENERGY;
 
-    avcodec_get_frame_defaults(&p->avframe);
-    avctx->coded_frame = &p->avframe;
-
     return 0;
 }
 
@@ -794,8 +790,8 @@ static int synthesis(AMRContext *p, float *lpc,
 
     // emphasize pitch vector contribution
     if (p->pitch_gain[4] > 0.5 && !overflow) {
-        float energy = ff_scalarproduct_float_c(excitation, excitation,
-                                                AMR_SUBFRAME_SIZE);
+        float energy = avpriv_scalarproduct_float_c(excitation, excitation,
+                                                    AMR_SUBFRAME_SIZE);
         float pitch_factor =
             p->pitch_gain[4] *
             (p->cur_frame_mode == MODE_12k2 ?
@@ -871,8 +867,8 @@ static float tilt_factor(float *lpc_n, float *lpc_d)
     ff_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 = avpriv_scalarproduct_float_c(hf, hf,     AMR_TILT_RESPONSE);
+    rh1 = avpriv_scalarproduct_float_c(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.
@@ -892,8 +888,8 @@ static void postfilter(AMRContext *p, float *lpc, float *buf_out)
     int i;
     float *samples          = p->samples_in + LP_FILTER_ORDER; // Start of input
 
-    float speech_gain       = ff_scalarproduct_float_c(samples, samples,
-                                                       AMR_SUBFRAME_SIZE);
+    float speech_gain       = avpriv_scalarproduct_float_c(samples, samples,
+                                                           AMR_SUBFRAME_SIZE);
 
     float pole_out[AMR_SUBFRAME_SIZE + LP_FILTER_ORDER];  // Output of pole filter
     const float *gamma_n, *gamma_d;                       // Formant filter factor table
@@ -936,6 +932,7 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
 {
 
     AMRContext *p = avctx->priv_data;        // pointer to private data
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     float *buf_out;                          // pointer to the output data buffer
@@ -947,12 +944,12 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
     const float *synth_fixed_vector;         // pointer to the fixed vector that synthesis should use
 
     /* get output buffer */
-    p->avframe.nb_samples = AMR_BLOCK_SIZE;
-    if ((ret = ff_get_buffer(avctx, &p->avframe)) < 0) {
+    frame->nb_samples = AMR_BLOCK_SIZE;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    buf_out = (float *)p->avframe.data[0];
+    buf_out = (float *)frame->data[0];
 
     p->cur_frame_mode = unpack_bitstream(p, buf, buf_size);
     if (p->cur_frame_mode == NO_DATA) {
@@ -960,7 +957,7 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
     if (p->cur_frame_mode == MODE_DTX) {
-        av_log_missing_feature(avctx, "dtx mode", 1);
+        avpriv_request_sample(avctx, "dtx mode");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -998,9 +995,9 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
 
         p->fixed_gain[4] =
             ff_amr_set_fixed_gain(fixed_gain_factor,
-                                  ff_scalarproduct_float_c(p->fixed_vector,
-                                                           p->fixed_vector,
-                                                           AMR_SUBFRAME_SIZE) /
+                                  avpriv_scalarproduct_float_c(p->fixed_vector,
+                                                               p->fixed_vector,
+                                                               AMR_SUBFRAME_SIZE) /
                                   AMR_SUBFRAME_SIZE,
                        p->prediction_error,
                        energy_mean[p->cur_frame_mode], energy_pred_fac);
@@ -1058,8 +1055,7 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
     ff_weighted_vector_sumf(p->lsf_avg, p->lsf_avg, p->lsf_q[3],
                             0.84, 0.16, LP_FILTER_ORDER);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = p->avframe;
+    *got_frame_ptr = 1;
 
     /* return the amount of bytes consumed if everything was OK */
     return frame_sizes_nb[p->cur_frame_mode] + 1; // +7 for rounding and +8 for TOC
@@ -1068,13 +1064,13 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
 
 AVCodec ff_amrnb_decoder = {
     .name           = "amrnb",
+    .long_name      = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AMR_NB,
     .priv_data_size = sizeof(AMRContext),
     .init           = amrnb_decode_init,
     .decode         = amrnb_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("AMR-NB (Adaptive Multi-Rate NarrowBand)"),
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 01d95f6..668c84d 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -26,10 +26,10 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/lfg.h"
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "lsp.h"
 #include "celp_filters.h"
 #include "acelp_filters.h"
@@ -43,7 +43,6 @@
 #include "amrwbdata.h"
 
 typedef struct {
-    AVFrame                              avframe; ///< AVFrame for decoded samples
     AMRWBFrame                             frame; ///< AMRWB parameters decoded from bitstream
     enum Mode                        fr_cur_mode; ///< mode index of current frame
     uint8_t                           fr_quality; ///< frame quality index (FQI)
@@ -93,7 +92,7 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx)
     int i;
 
     if (avctx->channels > 1) {
-        av_log_missing_feature(avctx, "multi-channel AMR", 0);
+        avpriv_report_missing_feature(avctx, "multi-channel AMR");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -113,9 +112,6 @@ static av_cold int amrwb_decode_init(AVCodecContext *avctx)
     for (i = 0; i < 4; i++)
         ctx->prediction_error[i] = MIN_ENERGY;
 
-    avcodec_get_frame_defaults(&ctx->avframe);
-    avctx->coded_frame = &ctx->avframe;
-
     return 0;
 }
 
@@ -595,11 +591,11 @@ static void pitch_sharpening(AMRWBContext *ctx, float *fixed_vector)
 static float voice_factor(float *p_vector, float p_gain,
                           float *f_vector, float f_gain)
 {
-    double p_ener = (double) ff_scalarproduct_float_c(p_vector, p_vector,
-                                                      AMRWB_SFR_SIZE) *
+    double p_ener = (double) avpriv_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) *
+    double f_ener = (double) avpriv_scalarproduct_float_c(f_vector, f_vector,
+                                                          AMRWB_SFR_SIZE) *
                     f_gain * f_gain;
 
     return (p_ener - f_ener) / (p_ener + f_ener);
@@ -768,8 +764,8 @@ static void synthesis(AMRWBContext *ctx, float *lpc, float *excitation,
     /* 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,
-                                                AMRWB_SFR_SIZE);
+        float energy = avpriv_scalarproduct_float_c(excitation, excitation,
+                                                    AMRWB_SFR_SIZE);
 
         // XXX: Weird part in both ref code and spec. A unknown parameter
         // {beta} seems to be identical to the current pitch gain
@@ -828,9 +824,9 @@ static void upsample_5_4(float *out, const float *in, int o_size)
         i++;
 
         for (k = 1; k < 5; k++) {
-            out[i] = ff_scalarproduct_float_c(in0 + int_part,
-                                              upsample_fir[4 - frac_part],
-                                              UPS_MEM_SIZE);
+            out[i] = avpriv_scalarproduct_float_c(in0 + int_part,
+                                                  upsample_fir[4 - frac_part],
+                                                  UPS_MEM_SIZE);
             int_part++;
             frac_part--;
             i++;
@@ -856,8 +852,8 @@ static float find_hb_gain(AMRWBContext *ctx, const float *synth,
     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 = avpriv_scalarproduct_float_c(synth, synth + 1, AMRWB_SFR_SIZE - 1) /
+           avpriv_scalarproduct_float_c(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);
@@ -876,7 +872,8 @@ static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
                                  const float *synth_exc, float hb_gain)
 {
     int i;
-    float energy = ff_scalarproduct_float_c(synth_exc, synth_exc, AMRWB_SFR_SIZE);
+    float energy = avpriv_scalarproduct_float_c(synth_exc, synth_exc,
+                                                AMRWB_SFR_SIZE);
 
     /* Generate a white-noise excitation */
     for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
@@ -1076,6 +1073,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
     AMRWBContext *ctx  = avctx->priv_data;
+    AVFrame *frame     = data;
     AMRWBFrame   *cf   = &ctx->frame;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
@@ -1093,12 +1091,12 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
     int sub, i, ret;
 
     /* get output buffer */
-    ctx->avframe.nb_samples = 4 * AMRWB_SFR_SIZE_16k;
-    if ((ret = ff_get_buffer(avctx, &ctx->avframe)) < 0) {
+    frame->nb_samples = 4 * AMRWB_SFR_SIZE_16k;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    buf_out = (float *)ctx->avframe.data[0];
+    buf_out = (float *)frame->data[0];
 
     header_size      = decode_mime_header(ctx, buf);
     if (ctx->fr_cur_mode > MODE_SID) {
@@ -1119,7 +1117,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
         av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n");
 
     if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */
-        av_log_missing_feature(avctx, "SID mode", 1);
+        avpriv_request_sample(avctx, "SID mode");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -1168,9 +1166,9 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
 
         ctx->fixed_gain[0] =
             ff_amr_set_fixed_gain(fixed_gain_factor,
-                                  ff_scalarproduct_float_c(ctx->fixed_vector,
-                                                           ctx->fixed_vector,
-                                                           AMRWB_SFR_SIZE) /
+                                  avpriv_scalarproduct_float_c(ctx->fixed_vector,
+                                                               ctx->fixed_vector,
+                                                               AMRWB_SFR_SIZE) /
                                   AMRWB_SFR_SIZE,
                        ctx->prediction_error,
                        ENERGY_MEAN, energy_pred_fac);
@@ -1243,21 +1241,20 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
     memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0]));
     memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float));
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ctx->avframe;
+    *got_frame_ptr = 1;
 
     return expected_fr_size;
 }
 
 AVCodec ff_amrwb_decoder = {
     .name           = "amrwb",
+    .long_name      = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AMR_WB,
     .priv_data_size = sizeof(AMRWBContext),
     .init           = amrwb_decode_init,
     .decode         = amrwb_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"),
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index d08ed8d..3d5affb 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -26,9 +26,10 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct AnmContext {
-    AVFrame frame;
+    AVFrame *frame;
     int palette[AVPALETTE_COUNT];
     GetByteContext gb;
     int x;  ///< x coordinate position
@@ -41,10 +42,13 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    s->frame.reference = 1;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
     if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     bytestream2_skipu(&s->gb, 16 * 8);
     for (i = 0; i < 256; i++)
@@ -111,23 +115,23 @@ static int decode_frame(AVCodecContext *avctx,
     AnmContext *s = avctx->priv_data;
     const int buf_size = avpkt->size;
     uint8_t *dst, *dst_end;
-    int count;
+    int count, ret;
 
-    if(avctx->reget_buffer(avctx, &s->frame) < 0){
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    dst     = s->frame.data[0];
-    dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height;
+    dst     = s->frame->data[0];
+    dst_end = s->frame->data[0] + s->frame->linesize[0]*avctx->height;
 
     bytestream2_init(&s->gb, avpkt->data, buf_size);
 
     if (bytestream2_get_byte(&s->gb) != 0x42) {
-        av_log_ask_for_sample(avctx, "unknown record type\n");
+        avpriv_request_sample(avctx, "Unknown record type");
         return buf_size;
     }
     if (bytestream2_get_byte(&s->gb)) {
-        av_log_ask_for_sample(avctx, "padding bytes not supported\n");
+        avpriv_request_sample(avctx, "Padding bytes");
         return buf_size;
     }
     bytestream2_skip(&s->gb, 2);
@@ -136,7 +140,7 @@ static int decode_frame(AVCodecContext *avctx,
     do {
         /* if statements are ordered by probability */
 #define OP(gb, pixel, count) \
-    op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame.linesize[0])
+    op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame->linesize[0])
 
         int type = bytestream2_get_byte(&s->gb);
         count = type & 0x7F;
@@ -157,7 +161,7 @@ static int decode_frame(AVCodecContext *avctx,
                 if (type == 0)
                     break; // stop
                 if (type == 2) {
-                    av_log_ask_for_sample(avctx, "unknown opcode");
+                    avpriv_request_sample(avctx, "Unknown opcode");
                     return AVERROR_PATCHWELCOME;
                 }
                 continue;
@@ -168,23 +172,26 @@ static int decode_frame(AVCodecContext *avctx,
         }
     } while (bytestream2_get_bytes_left(&s->gb) > 0);
 
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     return buf_size;
 }
 
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     AnmContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+
+    av_frame_free(&s->frame);
     return 0;
 }
 
 AVCodec ff_anm_decoder = {
     .name           = "anm",
+    .long_name      = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ANM,
     .priv_data_size = sizeof(AnmContext),
@@ -192,5 +199,4 @@ AVCodec ff_anm_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
 };
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index 861d4e5..95b5be4 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -25,6 +25,7 @@
  */
 
 #include "libavutil/common.h"
+#include "libavutil/frame.h"
 #include "libavutil/lfg.h"
 #include "avcodec.h"
 #include "cga_data.h"
@@ -49,7 +50,7 @@ static const uint8_t ansi_to_cga[16] = {
 };
 
 typedef struct {
-    AVFrame frame;
+    AVFrame *frame;
     int x;                /**< x cursor position (pixels) */
     int y;                /**< y cursor position (pixels) */
     int sx;               /**< saved x cursor position (pixels) */
@@ -77,6 +78,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
     AnsiContext *s = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     /* defaults */
     s->font        = ff_vga16_font;
     s->font_height = 16;
@@ -84,7 +89,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     s->bg          = DEFAULT_BG_COLOR;
 
     if (!avctx->width || !avctx->height)
-        avcodec_set_dimensions(avctx, 80<<3, 25<<4);
+        ff_set_dimensions(avctx, 80 << 3, 25 << 4);
 
     return 0;
 }
@@ -101,11 +106,11 @@ static void hscroll(AVCodecContext *avctx)
 
     i = 0;
     for (; i < avctx->height - s->font_height; i++)
-        memcpy(s->frame.data[0] + i * s->frame.linesize[0],
-               s->frame.data[0] + (i + s->font_height) * s->frame.linesize[0],
+        memcpy(s->frame->data[0] + i * s->frame->linesize[0],
+               s->frame->data[0] + (i + s->font_height) * s->frame->linesize[0],
                avctx->width);
     for (; i < avctx->height; i++)
-        memset(s->frame.data[0] + i * s->frame.linesize[0],
+        memset(s->frame->data[0] + i * s->frame->linesize[0],
             DEFAULT_BG_COLOR, avctx->width);
 }
 
@@ -114,7 +119,7 @@ static void erase_line(AVCodecContext * avctx, int xoffset, int xlength)
     AnsiContext *s = avctx->priv_data;
     int i;
     for (i = 0; i < s->font_height; i++)
-        memset(s->frame.data[0] + (s->y + i)*s->frame.linesize[0] + xoffset,
+        memset(s->frame->data[0] + (s->y + i)*s->frame->linesize[0] + xoffset,
             DEFAULT_BG_COLOR, xlength);
 }
 
@@ -123,7 +128,7 @@ static void erase_screen(AVCodecContext *avctx)
     AnsiContext *s = avctx->priv_data;
     int i;
     for (i = 0; i < avctx->height; i++)
-        memset(s->frame.data[0] + i * s->frame.linesize[0], DEFAULT_BG_COLOR, avctx->width);
+        memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width);
     s->x = s->y = 0;
 }
 
@@ -144,8 +149,8 @@ static void draw_char(AVCodecContext *avctx, int c)
         FFSWAP(int, fg, bg);
     if ((s->attributes & ATTR_CONCEALED))
         fg = bg;
-    ff_draw_pc_font(s->frame.data[0] + s->y * s->frame.linesize[0] + s->x,
-                    s->frame.linesize[0], s->font, s->font_height, c, fg, bg);
+    ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x,
+                    s->frame->linesize[0], s->font, s->font_height, c, fg, bg);
     s->x += FONT_WIDTH;
     if (s->x >= avctx->width) {
         s->x = 0;
@@ -160,7 +165,10 @@ static void draw_char(AVCodecContext *avctx, int c)
 static int execute_code(AVCodecContext * avctx, int c)
 {
     AnsiContext *s = avctx->priv_data;
-    int ret, i, width, height;
+    int ret, i;
+    int width = 0;
+    int height = 0;
+
     switch(c) {
     case 'A': //Cursor Up
         s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0);
@@ -217,20 +225,22 @@ static int execute_code(AVCodecContext * avctx, int c)
             height = 60<<4;
             break;
         default:
-            av_log_ask_for_sample(avctx, "unsupported screen mode\n");
+            avpriv_request_sample(avctx, "Unsupported screen mode");
         }
-        if (width != avctx->width || height != avctx->height) {
-            if (s->frame.data[0])
-                avctx->release_buffer(avctx, &s->frame);
-            avcodec_set_dimensions(avctx, width, height);
-            ret = ff_get_buffer(avctx, &s->frame);
+        if (width != 0 && height != 0 &&
+            (width != avctx->width || height != avctx->height)) {
+            av_frame_unref(s->frame);
+            ret = ff_set_dimensions(avctx, width, height);
+            if (ret < 0)
+                return ret;
+            ret = ff_get_buffer(avctx, s->frame, AV_GET_BUFFER_FLAG_REF);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return ret;
             }
-            s->frame.pict_type           = AV_PICTURE_TYPE_I;
-            s->frame.palette_has_changed = 1;
-            memcpy(s->frame.data[1], ff_cga_palette, 16 * 4);
+            s->frame->pict_type           = AV_PICTURE_TYPE_I;
+            s->frame->palette_has_changed = 1;
+            memcpy(s->frame->data[1], ff_cga_palette, 16 * 4);
             erase_screen(avctx);
         } else if (c == 'l') {
             erase_screen(avctx);
@@ -241,13 +251,13 @@ static int execute_code(AVCodecContext * avctx, int c)
         case 0:
             erase_line(avctx, s->x, avctx->width - s->x);
             if (s->y < avctx->height - s->font_height)
-                memset(s->frame.data[0] + (s->y + s->font_height)*s->frame.linesize[0],
-                    DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame.linesize[0]);
+                memset(s->frame->data[0] + (s->y + s->font_height)*s->frame->linesize[0],
+                    DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame->linesize[0]);
             break;
         case 1:
             erase_line(avctx, 0, s->x);
             if (s->y > 0)
-                memset(s->frame.data[0], DEFAULT_BG_COLOR, s->y * s->frame.linesize[0]);
+                memset(s->frame->data[0], DEFAULT_BG_COLOR, s->y * s->frame->linesize[0]);
             break;
         case 2:
             erase_screen(avctx);
@@ -287,7 +297,7 @@ static int execute_code(AVCodecContext * avctx, int c)
             } else if (m == 49) {
                 s->fg = ansi_to_cga[DEFAULT_BG_COLOR];
             } else {
-                av_log_ask_for_sample(avctx, "unsupported rendition parameter\n");
+                avpriv_request_sample(avctx, "Unsupported rendition parameter");
             }
         }
         break;
@@ -304,7 +314,7 @@ static int execute_code(AVCodecContext * avctx, int c)
         s->y = av_clip(s->sy, 0, avctx->height - s->font_height);
         break;
     default:
-        av_log_ask_for_sample(avctx, "unsupported escape code\n");
+        avpriv_request_sample(avctx, "Unknown escape code");
         break;
     }
     return 0;
@@ -320,19 +330,19 @@ static int decode_frame(AVCodecContext *avctx,
     const uint8_t *buf_end   = buf+buf_size;
     int ret, i, count;
 
-    ret = avctx->reget_buffer(avctx, &s->frame);
+    ret = ff_reget_buffer(avctx, s->frame);
     if (ret < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
     if (!avctx->frame_number) {
-        memset(s->frame.data[0], 0, avctx->height * FFABS(s->frame.linesize[0]));
-        memset(s->frame.data[1], 0, AVPALETTE_SIZE);
+        memset(s->frame->data[0], 0, avctx->height * FFABS(s->frame->linesize[0]));
+        memset(s->frame->data[1], 0, AVPALETTE_SIZE);
     }
 
-    s->frame.pict_type           = AV_PICTURE_TYPE_I;
-    s->frame.palette_has_changed = 1;
-    memcpy(s->frame.data[1], ff_cga_palette, 16 * 4);
+    s->frame->pict_type           = AV_PICTURE_TYPE_I;
+    s->frame->palette_has_changed = 1;
+    memcpy(s->frame->data[1], ff_cga_palette, 16 * 4);
 
     while(buf < buf_end) {
         switch(s->state) {
@@ -401,8 +411,8 @@ static int decode_frame(AVCodecContext *avctx,
                     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])
                     s->nb_args++;
-                if (execute_code(avctx, buf[0]) < 0)
-                    return -1;
+                if ((ret = execute_code(avctx, buf[0])) < 0)
+                    return ret;
                 s->state = STATE_NORMAL;
             }
             break;
@@ -416,20 +426,22 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
     return buf_size;
 }
 
 static av_cold int decode_close(AVCodecContext *avctx)
 {
     AnsiContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+
+    av_frame_free(&s->frame);
     return 0;
 }
 
 AVCodec ff_ansi_decoder = {
     .name           = "ansi",
+    .long_name      = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ANSI,
     .priv_data_size = sizeof(AnsiContext),
@@ -437,5 +449,4 @@ AVCodec ff_ansi_decoder = {
     .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"),
 };
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index 61eecfe..8669db8 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -27,6 +27,8 @@
 #include "dsputil.h"
 #include "bytestream.h"
 #include "internal.h"
+#include "get_bits.h"
+#include "unary.h"
 
 /**
  * @file
@@ -123,13 +125,14 @@ typedef struct APEPredictor {
     int32_t coeffsA[2][4];  ///< adaption coefficients
     int32_t coeffsB[2][5];  ///< adaption coefficients
     int32_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE];
+
+    unsigned int sample_pos;
 } APEPredictor;
 
 /** Decoder context */
 typedef struct APEContext {
     AVClass *class;                          ///< class for AVOptions
     AVCodecContext *avctx;
-    AVFrame frame;
     DSPContext dsp;
     int channels;
     int samples;                             ///< samples left to decode in current frame
@@ -155,6 +158,7 @@ typedef struct APEContext {
     APERice riceX;                           ///< rice code parameters for the second channel
     APERice riceY;                           ///< rice code parameters for the first channel
     APEFilter filters[APE_FILTER_LEVELS][2]; ///< filters used for reconstruction
+    GetBitContext gb;
 
     uint8_t *data;                           ///< current frame data
     uint8_t *data_end;                       ///< frame data end
@@ -162,8 +166,33 @@ typedef struct APEContext {
     const uint8_t *ptr;                      ///< current position in frame data
 
     int error;
+
+    void (*entropy_decode_mono)(struct APEContext *ctx, int blockstodecode);
+    void (*entropy_decode_stereo)(struct APEContext *ctx, int blockstodecode);
+    void (*predictor_decode_mono)(struct APEContext *ctx, int count);
+    void (*predictor_decode_stereo)(struct APEContext *ctx, int count);
 } APEContext;
 
+static void ape_apply_filters(APEContext *ctx, int32_t *decoded0,
+                              int32_t *decoded1, int count);
+
+static void entropy_decode_mono_0000(APEContext *ctx, int blockstodecode);
+static void entropy_decode_stereo_0000(APEContext *ctx, int blockstodecode);
+static void entropy_decode_mono_3860(APEContext *ctx, int blockstodecode);
+static void entropy_decode_stereo_3860(APEContext *ctx, int blockstodecode);
+static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode);
+static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode);
+static void entropy_decode_stereo_3930(APEContext *ctx, int blockstodecode);
+static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode);
+static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode);
+
+static void predictor_decode_mono_3800(APEContext *ctx, int count);
+static void predictor_decode_stereo_3800(APEContext *ctx, int count);
+static void predictor_decode_mono_3930(APEContext *ctx, int count);
+static void predictor_decode_stereo_3930(APEContext *ctx, int count);
+static void predictor_decode_mono_3950(APEContext *ctx, int count);
+static void predictor_decode_stereo_3950(APEContext *ctx, int count);
+
 // TODO: dsputilize
 
 static av_cold int ape_decode_close(AVCodecContext *avctx)
@@ -206,8 +235,8 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
         avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
         break;
     default:
-        av_log_ask_for_sample(avctx, "Unsupported bits per coded sample %d\n",
-                              s->bps);
+        avpriv_request_sample(avctx,
+                              "%d bits per coded sample", s->bps);
         return AVERROR_PATCHWELCOME;
     }
     s->avctx             = avctx;
@@ -218,7 +247,8 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
 
     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->fileversion < 3930 && s->compression_level == COMPRESSION_LEVEL_INSANE)) {
         av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n",
                s->compression_level);
         return AVERROR_INVALIDDATA;
@@ -232,12 +262,37 @@ static av_cold int ape_decode_init(AVCodecContext *avctx)
                          filter_alloc_fail);
     }
 
+    if (s->fileversion < 3860) {
+        s->entropy_decode_mono   = entropy_decode_mono_0000;
+        s->entropy_decode_stereo = entropy_decode_stereo_0000;
+    } else if (s->fileversion < 3900) {
+        s->entropy_decode_mono   = entropy_decode_mono_3860;
+        s->entropy_decode_stereo = entropy_decode_stereo_3860;
+    } else if (s->fileversion < 3930) {
+        s->entropy_decode_mono   = entropy_decode_mono_3900;
+        s->entropy_decode_stereo = entropy_decode_stereo_3900;
+    } else if (s->fileversion < 3990) {
+        s->entropy_decode_mono   = entropy_decode_mono_3900;
+        s->entropy_decode_stereo = entropy_decode_stereo_3930;
+    } else {
+        s->entropy_decode_mono   = entropy_decode_mono_3990;
+        s->entropy_decode_stereo = entropy_decode_stereo_3990;
+    }
+
+    if (s->fileversion < 3930) {
+        s->predictor_decode_mono   = predictor_decode_mono_3800;
+        s->predictor_decode_stereo = predictor_decode_stereo_3800;
+    } else if (s->fileversion < 3950) {
+        s->predictor_decode_mono   = predictor_decode_mono_3930;
+        s->predictor_decode_stereo = predictor_decode_stereo_3930;
+    } else {
+        s->predictor_decode_mono   = predictor_decode_mono_3950;
+        s->predictor_decode_stereo = predictor_decode_stereo_3950;
+    }
+
     ff_dsputil_init(&s->dsp, avctx);
     avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 filter_alloc_fail:
     ape_decode_close(avctx);
@@ -405,67 +460,120 @@ static inline void update_rice(APERice *rice, unsigned int x)
         rice->k++;
 }
 
-static inline int ape_decode_value(APEContext *ctx, APERice *rice)
+static inline int get_rice_ook(GetBitContext *gb, int k)
 {
-    unsigned int x, overflow;
+    unsigned int x;
 
-    if (ctx->fileversion < 3990) {
-        int tmpk;
+    x = get_unary(gb, 1, get_bits_left(gb));
 
-        overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970);
+    if (k)
+        x = (x << k) | get_bits(gb, k);
 
-        if (overflow == (MODEL_ELEMENTS - 1)) {
-            tmpk = range_decode_bits(ctx, 5);
-            overflow = 0;
-        } else
-            tmpk = (rice->k < 1) ? 0 : rice->k - 1;
+    return x;
+}
 
-        if (tmpk <= 16)
-            x = range_decode_bits(ctx, tmpk);
-        else if (tmpk <= 32) {
-            x = range_decode_bits(ctx, 16);
-            x |= (range_decode_bits(ctx, tmpk - 16) << 16);
-        } else {
-            av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk);
-            return AVERROR_INVALIDDATA;
+static inline int ape_decode_value_3860(APEContext *ctx, GetBitContext *gb,
+                                        APERice *rice)
+{
+    unsigned int x, overflow;
+
+    overflow = get_unary(gb, 1, get_bits_left(gb));
+
+    if (ctx->fileversion > 3880) {
+        while (overflow >= 16) {
+            overflow -= 16;
+            rice->k  += 4;
         }
-        x += overflow << tmpk;
+    }
+
+    if (!rice->k)
+        x = overflow;
+    else
+        x = (overflow << rice->k) + get_bits(gb, rice->k);
+
+    rice->ksum += x - (rice->ksum + 8 >> 4);
+    if (rice->ksum < (rice->k ? 1 << (rice->k + 4) : 0))
+        rice->k--;
+    else if (rice->ksum >= (1 << (rice->k + 5)) && rice->k < 24)
+        rice->k++;
+
+    /* Convert to signed */
+    if (x & 1)
+        return (x >> 1) + 1;
+    else
+        return -(x >> 1);
+}
+
+static inline int ape_decode_value_3900(APEContext *ctx, APERice *rice)
+{
+    unsigned int x, overflow;
+    int tmpk;
+
+    overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970);
+
+    if (overflow == (MODEL_ELEMENTS - 1)) {
+        tmpk = range_decode_bits(ctx, 5);
+        overflow = 0;
+    } else
+        tmpk = (rice->k < 1) ? 0 : rice->k - 1;
+
+    if (tmpk <= 16 || ctx->fileversion < 3910)
+        x = range_decode_bits(ctx, tmpk);
+    else if (tmpk <= 32) {
+        x = range_decode_bits(ctx, 16);
+        x |= (range_decode_bits(ctx, tmpk - 16) << 16);
     } else {
-        int base, pivot;
+        av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk);
+        return AVERROR_INVALIDDATA;
+    }
+    x += overflow << tmpk;
 
-        pivot = rice->ksum >> 5;
-        if (pivot == 0)
-            pivot = 1;
+    update_rice(rice, x);
 
-        overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980);
+    /* Convert to signed */
+    if (x & 1)
+        return (x >> 1) + 1;
+    else
+        return -(x >> 1);
+}
 
-        if (overflow == (MODEL_ELEMENTS - 1)) {
-            overflow  = range_decode_bits(ctx, 16) << 16;
-            overflow |= range_decode_bits(ctx, 16);
-        }
+static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice)
+{
+    unsigned int x, overflow;
+    int base, pivot;
 
-        if (pivot < 0x10000) {
-            base = range_decode_culfreq(ctx, pivot);
-            range_decode_update(ctx, 1, base);
-        } else {
-            int base_hi = pivot, base_lo;
-            int bbits = 0;
+    pivot = rice->ksum >> 5;
+    if (pivot == 0)
+        pivot = 1;
 
-            while (base_hi & ~0xFFFF) {
-                base_hi >>= 1;
-                bbits++;
-            }
-            base_hi = range_decode_culfreq(ctx, base_hi + 1);
-            range_decode_update(ctx, 1, base_hi);
-            base_lo = range_decode_culfreq(ctx, 1 << bbits);
-            range_decode_update(ctx, 1, base_lo);
+    overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980);
 
-            base = (base_hi << bbits) + base_lo;
+    if (overflow == (MODEL_ELEMENTS - 1)) {
+        overflow  = range_decode_bits(ctx, 16) << 16;
+        overflow |= range_decode_bits(ctx, 16);
+    }
+
+    if (pivot < 0x10000) {
+        base = range_decode_culfreq(ctx, pivot);
+        range_decode_update(ctx, 1, base);
+    } else {
+        int base_hi = pivot, base_lo;
+        int bbits = 0;
+
+        while (base_hi & ~0xFFFF) {
+            base_hi >>= 1;
+            bbits++;
         }
+        base_hi = range_decode_culfreq(ctx, base_hi + 1);
+        range_decode_update(ctx, 1, base_hi);
+        base_lo = range_decode_culfreq(ctx, 1 << bbits);
+        range_decode_update(ctx, 1, base_lo);
 
-        x = base + overflow * pivot;
+        base = (base_hi << bbits) + base_lo;
     }
 
+    x = base + overflow * pivot;
+
     update_rice(rice, x);
 
     /* Convert to signed */
@@ -475,24 +583,148 @@ static inline int ape_decode_value(APEContext *ctx, APERice *rice)
         return -(x >> 1);
 }
 
-static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo)
+static void decode_array_0000(APEContext *ctx, GetBitContext *gb,
+                              int32_t *out, APERice *rice, int blockstodecode)
+{
+    int i;
+    int ksummax, ksummin;
+
+    rice->ksum = 0;
+    for (i = 0; i < 5; i++) {
+        out[i] = get_rice_ook(&ctx->gb, 10);
+        rice->ksum += out[i];
+    }
+    rice->k = av_log2(rice->ksum / 10) + 1;
+    for (; i < 64; i++) {
+        out[i] = get_rice_ook(&ctx->gb, rice->k);
+        rice->ksum += out[i];
+        rice->k = av_log2(rice->ksum / ((i + 1) * 2)) + 1;
+    }
+    ksummax = 1 << rice->k + 7;
+    ksummin = rice->k ? (1 << rice->k + 6) : 0;
+    for (; i < blockstodecode; i++) {
+        out[i] = get_rice_ook(&ctx->gb, rice->k);
+        rice->ksum += out[i] - out[i - 64];
+        while (rice->ksum < ksummin) {
+            rice->k--;
+            ksummin = rice->k ? ksummin >> 1 : 0;
+            ksummax >>= 1;
+        }
+        while (rice->ksum >= ksummax) {
+            rice->k++;
+            if (rice->k > 24)
+                return;
+            ksummax <<= 1;
+            ksummin = ksummin ? ksummin << 1 : 128;
+        }
+    }
+
+    for (i = 0; i < blockstodecode; i++) {
+        if (out[i] & 1)
+            out[i] = (out[i] >> 1) + 1;
+        else
+            out[i] = -(out[i] >> 1);
+    }
+}
+
+static void entropy_decode_mono_0000(APEContext *ctx, int blockstodecode)
+{
+    decode_array_0000(ctx, &ctx->gb, ctx->decoded[0], &ctx->riceY,
+                      blockstodecode);
+}
+
+static void entropy_decode_stereo_0000(APEContext *ctx, int blockstodecode)
+{
+    decode_array_0000(ctx, &ctx->gb, ctx->decoded[0], &ctx->riceY,
+                      blockstodecode);
+    decode_array_0000(ctx, &ctx->gb, ctx->decoded[1], &ctx->riceX,
+                      blockstodecode);
+}
+
+static void entropy_decode_mono_3860(APEContext *ctx, int blockstodecode)
+{
+    int32_t *decoded0 = ctx->decoded[0];
+
+    while (blockstodecode--)
+        *decoded0++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceY);
+}
+
+static void entropy_decode_stereo_3860(APEContext *ctx, int blockstodecode)
+{
+    int32_t *decoded0 = ctx->decoded[0];
+    int32_t *decoded1 = ctx->decoded[1];
+    int blocks = blockstodecode;
+
+    while (blockstodecode--)
+        *decoded0++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceY);
+    while (blocks--)
+        *decoded1++ = ape_decode_value_3860(ctx, &ctx->gb, &ctx->riceX);
+}
+
+static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode)
+{
+    int32_t *decoded0 = ctx->decoded[0];
+
+    while (blockstodecode--)
+        *decoded0++ = ape_decode_value_3900(ctx, &ctx->riceY);
+}
+
+static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode)
+{
+    int32_t *decoded0 = ctx->decoded[0];
+    int32_t *decoded1 = ctx->decoded[1];
+    int blocks = blockstodecode;
+
+    while (blockstodecode--)
+        *decoded0++ = ape_decode_value_3900(ctx, &ctx->riceY);
+    range_dec_normalize(ctx);
+    // because of some implementation peculiarities we need to backpedal here
+    ctx->ptr -= 1;
+    range_start_decoding(ctx);
+    while (blocks--)
+        *decoded1++ = ape_decode_value_3900(ctx, &ctx->riceX);
+}
+
+static void entropy_decode_stereo_3930(APEContext *ctx, int blockstodecode)
+{
+    int32_t *decoded0 = ctx->decoded[0];
+    int32_t *decoded1 = ctx->decoded[1];
+
+    while (blockstodecode--) {
+        *decoded0++ = ape_decode_value_3900(ctx, &ctx->riceY);
+        *decoded1++ = ape_decode_value_3900(ctx, &ctx->riceX);
+    }
+}
+
+static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode)
+{
+    int32_t *decoded0 = ctx->decoded[0];
+
+    while (blockstodecode--)
+        *decoded0++ = ape_decode_value_3990(ctx, &ctx->riceY);
+}
+
+static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode)
 {
     int32_t *decoded0 = ctx->decoded[0];
     int32_t *decoded1 = ctx->decoded[1];
 
     while (blockstodecode--) {
-        *decoded0++ = ape_decode_value(ctx, &ctx->riceY);
-        if (stereo)
-            *decoded1++ = ape_decode_value(ctx, &ctx->riceX);
+        *decoded0++ = ape_decode_value_3990(ctx, &ctx->riceY);
+        *decoded1++ = ape_decode_value_3990(ctx, &ctx->riceX);
     }
 }
 
 static int init_entropy_decoder(APEContext *ctx)
 {
     /* Read the CRC */
-    if (ctx->data_end - ctx->ptr < 6)
-        return AVERROR_INVALIDDATA;
-    ctx->CRC = bytestream_get_be32(&ctx->ptr);
+    if (ctx->fileversion >= 3900) {
+        if (ctx->data_end - ctx->ptr < 6)
+            return AVERROR_INVALIDDATA;
+        ctx->CRC = bytestream_get_be32(&ctx->ptr);
+    } else {
+        ctx->CRC = get_bits_long(&ctx->gb, 32);
+    }
 
     /* Read the frame flags if they exist */
     ctx->frameflags = 0;
@@ -510,15 +742,29 @@ static int init_entropy_decoder(APEContext *ctx)
     ctx->riceY.k = 10;
     ctx->riceY.ksum = (1 << ctx->riceY.k) * 16;
 
-    /* The first 8 bits of input are ignored. */
-    ctx->ptr++;
+    if (ctx->fileversion >= 3900) {
+        /* The first 8 bits of input are ignored. */
+        ctx->ptr++;
 
-    range_start_decoding(ctx);
+        range_start_decoding(ctx);
+    }
 
     return 0;
 }
 
-static const int32_t initial_coeffs[4] = {
+static const int32_t initial_coeffs_fast_3320[1] = {
+    375,
+};
+
+static const int32_t initial_coeffs_a_3800[3] = {
+    64, 115, 64,
+};
+
+static const int32_t initial_coeffs_b_3800[2] = {
+    740, 0
+};
+
+static const int32_t initial_coeffs_3930[4] = {
     360, 317, -109, 98
 };
 
@@ -531,13 +777,35 @@ static void init_predictor_decoder(APEContext *ctx)
     p->buf = p->historybuffer;
 
     /* Initialize and zero the coefficients */
-    memcpy(p->coeffsA[0], initial_coeffs, sizeof(initial_coeffs));
-    memcpy(p->coeffsA[1], initial_coeffs, sizeof(initial_coeffs));
+    if (ctx->fileversion < 3930) {
+        if (ctx->compression_level == COMPRESSION_LEVEL_FAST) {
+            memcpy(p->coeffsA[0], initial_coeffs_fast_3320,
+                   sizeof(initial_coeffs_fast_3320));
+            memcpy(p->coeffsA[1], initial_coeffs_fast_3320,
+                   sizeof(initial_coeffs_fast_3320));
+        } else {
+            memcpy(p->coeffsA[0], initial_coeffs_a_3800,
+                   sizeof(initial_coeffs_a_3800));
+            memcpy(p->coeffsA[1], initial_coeffs_a_3800,
+                   sizeof(initial_coeffs_a_3800));
+        }
+    } else {
+        memcpy(p->coeffsA[0], initial_coeffs_3930, sizeof(initial_coeffs_3930));
+        memcpy(p->coeffsA[1], initial_coeffs_3930, sizeof(initial_coeffs_3930));
+    }
     memset(p->coeffsB, 0, sizeof(p->coeffsB));
+    if (ctx->fileversion < 3930) {
+        memcpy(p->coeffsB[0], initial_coeffs_b_3800,
+               sizeof(initial_coeffs_b_3800));
+        memcpy(p->coeffsB[1], initial_coeffs_b_3800,
+               sizeof(initial_coeffs_b_3800));
+    }
 
     p->filterA[0] = p->filterA[1] = 0;
     p->filterB[0] = p->filterB[1] = 0;
     p->lastA[0]   = p->lastA[1]   = 0;
+
+    p->sample_pos = 0;
 }
 
 /** Get inverse sign of integer (-1 for positive, 1 for negative and 0 for zero) */
@@ -545,6 +813,304 @@ static inline int APESIGN(int32_t x) {
     return (x < 0) - (x > 0);
 }
 
+static av_always_inline int filter_fast_3320(APEPredictor *p,
+                                             const int decoded, const int filter,
+                                             const int delayA)
+{
+    int32_t predictionA;
+
+    p->buf[delayA] = p->lastA[filter];
+    if (p->sample_pos < 3) {
+        p->lastA[filter]   = decoded;
+        p->filterA[filter] = decoded;
+        return decoded;
+    }
+
+    predictionA = p->buf[delayA] * 2 - p->buf[delayA - 1];
+    p->lastA[filter] = decoded + (predictionA  * p->coeffsA[filter][0] >> 9);
+
+    if ((decoded ^ predictionA) > 0)
+        p->coeffsA[filter][0]++;
+    else
+        p->coeffsA[filter][0]--;
+
+    p->filterA[filter] += p->lastA[filter];
+
+    return p->filterA[filter];
+}
+
+static av_always_inline int filter_3800(APEPredictor *p,
+                                        const int decoded, const int filter,
+                                        const int delayA,  const int delayB,
+                                        const int start,   const int shift)
+{
+    int32_t predictionA, predictionB, sign;
+    int32_t d0, d1, d2, d3, d4;
+
+    p->buf[delayA] = p->lastA[filter];
+    p->buf[delayB] = p->filterB[filter];
+    if (p->sample_pos < start) {
+        predictionA = decoded + p->filterA[filter];
+        p->lastA[filter]   = decoded;
+        p->filterB[filter] = decoded;
+        p->filterA[filter] = predictionA;
+        return predictionA;
+    }
+    d2 =  p->buf[delayA];
+    d1 = (p->buf[delayA] - p->buf[delayA - 1]) << 1;
+    d0 =  p->buf[delayA] + ((p->buf[delayA - 2] - p->buf[delayA - 1]) << 3);
+    d3 =  p->buf[delayB] * 2 - p->buf[delayB - 1];
+    d4 =  p->buf[delayB];
+
+    predictionA = d0 * p->coeffsA[filter][0] +
+                  d1 * p->coeffsA[filter][1] +
+                  d2 * p->coeffsA[filter][2];
+
+    sign = APESIGN(decoded);
+    p->coeffsA[filter][0] += (((d0 >> 30) & 2) - 1) * sign;
+    p->coeffsA[filter][1] += (((d1 >> 28) & 8) - 4) * sign;
+    p->coeffsA[filter][2] += (((d2 >> 28) & 8) - 4) * sign;
+
+    predictionB = d3 * p->coeffsB[filter][0] -
+                  d4 * p->coeffsB[filter][1];
+    p->lastA[filter] = decoded + (predictionA >> 11);
+    sign = APESIGN(p->lastA[filter]);
+    p->coeffsB[filter][0] += (((d3 >> 29) & 4) - 2) * sign;
+    p->coeffsB[filter][1] -= (((d4 >> 30) & 2) - 1) * sign;
+
+    p->filterB[filter] = p->lastA[filter] + (predictionB >> shift);
+    p->filterA[filter] = p->filterB[filter] + ((p->filterA[filter] * 31) >> 5);
+
+    return p->filterA[filter];
+}
+
+static void long_filter_high_3800(int32_t *buffer, int order, int shift,
+                                  int32_t *coeffs, int32_t *delay, int length)
+{
+    int i, j;
+    int32_t dotprod, sign;
+
+    memset(coeffs, 0, order * sizeof(*coeffs));
+    for (i = 0; i < order; i++)
+        delay[i] = buffer[i];
+    for (i = order; i < length; i++) {
+        dotprod = 0;
+        sign = APESIGN(buffer[i]);
+        for (j = 0; j < order; j++) {
+            dotprod += delay[j] * coeffs[j];
+            coeffs[j] -= (((delay[j] >> 30) & 2) - 1) * sign;
+        }
+        buffer[i] -= dotprod >> shift;
+        for (j = 0; j < order - 1; j++)
+            delay[j] = delay[j + 1];
+        delay[order - 1] = buffer[i];
+    }
+}
+
+static void long_filter_ehigh_3830(int32_t *buffer, int length)
+{
+    int i, j;
+    int32_t dotprod, sign;
+    int32_t coeffs[8], delay[8];
+
+    memset(coeffs, 0, sizeof(coeffs));
+    memset(delay,  0, sizeof(delay));
+    for (i = 0; i < length; i++) {
+        dotprod = 0;
+        sign = APESIGN(buffer[i]);
+        for (j = 7; j >= 0; j--) {
+            dotprod += delay[j] * coeffs[j];
+            coeffs[j] -= (((delay[j] >> 30) & 2) - 1) * sign;
+        }
+        for (j = 7; j > 0; j--)
+            delay[j] = delay[j - 1];
+        delay[0] = buffer[i];
+        buffer[i] -= dotprod >> 9;
+    }
+}
+
+static void predictor_decode_stereo_3800(APEContext *ctx, int count)
+{
+    APEPredictor *p = &ctx->predictor;
+    int32_t *decoded0 = ctx->decoded[0];
+    int32_t *decoded1 = ctx->decoded[1];
+    int32_t coeffs[256], delay[256];
+    int start = 4, shift = 10;
+
+    if (ctx->compression_level == COMPRESSION_LEVEL_HIGH) {
+        start = 16;
+        long_filter_high_3800(decoded0, 16, 9, coeffs, delay, count);
+        long_filter_high_3800(decoded1, 16, 9, coeffs, delay, count);
+    } else if (ctx->compression_level == COMPRESSION_LEVEL_EXTRA_HIGH) {
+        int order = 128, shift2 = 11;
+
+        if (ctx->fileversion >= 3830) {
+            order <<= 1;
+            shift++;
+            shift2++;
+            long_filter_ehigh_3830(decoded0 + order, count - order);
+            long_filter_ehigh_3830(decoded1 + order, count - order);
+        }
+        start = order;
+        long_filter_high_3800(decoded0, order, shift2, coeffs, delay, count);
+        long_filter_high_3800(decoded1, order, shift2, coeffs, delay, count);
+    }
+
+    while (count--) {
+        int X = *decoded0, Y = *decoded1;
+        if (ctx->compression_level == COMPRESSION_LEVEL_FAST) {
+            *decoded0 = filter_fast_3320(p, Y, 0, YDELAYA);
+            decoded0++;
+            *decoded1 = filter_fast_3320(p, X, 1, XDELAYA);
+            decoded1++;
+        } else {
+            *decoded0 = filter_3800(p, Y, 0, YDELAYA, YDELAYB,
+                                    start, shift);
+            decoded0++;
+            *decoded1 = filter_3800(p, X, 1, XDELAYA, XDELAYB,
+                                    start, shift);
+            decoded1++;
+        }
+
+        /* Combined */
+        p->buf++;
+        p->sample_pos++;
+
+        /* Have we filled the history buffer? */
+        if (p->buf == p->historybuffer + HISTORY_SIZE) {
+            memmove(p->historybuffer, p->buf,
+                    PREDICTOR_SIZE * sizeof(*p->historybuffer));
+            p->buf = p->historybuffer;
+        }
+    }
+}
+
+static void predictor_decode_mono_3800(APEContext *ctx, int count)
+{
+    APEPredictor *p = &ctx->predictor;
+    int32_t *decoded0 = ctx->decoded[0];
+    int32_t coeffs[256], delay[256];
+    int start = 4, shift = 10;
+
+    if (ctx->compression_level == COMPRESSION_LEVEL_HIGH) {
+        start = 16;
+        long_filter_high_3800(decoded0, 16, 9, coeffs, delay, count);
+    } else if (ctx->compression_level == COMPRESSION_LEVEL_EXTRA_HIGH) {
+        int order = 128, shift2 = 11;
+
+        if (ctx->fileversion >= 3830) {
+            order <<= 1;
+            shift++;
+            shift2++;
+            long_filter_ehigh_3830(decoded0 + order, count - order);
+        }
+        start = order;
+        long_filter_high_3800(decoded0, order, shift2, coeffs, delay, count);
+    }
+
+    while (count--) {
+        if (ctx->compression_level == COMPRESSION_LEVEL_FAST) {
+            *decoded0 = filter_fast_3320(p, *decoded0, 0, YDELAYA);
+            decoded0++;
+        } else {
+            *decoded0 = filter_3800(p, *decoded0, 0, YDELAYA, YDELAYB,
+                                    start, shift);
+            decoded0++;
+        }
+
+        /* Combined */
+        p->buf++;
+        p->sample_pos++;
+
+        /* Have we filled the history buffer? */
+        if (p->buf == p->historybuffer + HISTORY_SIZE) {
+            memmove(p->historybuffer, p->buf,
+                    PREDICTOR_SIZE * sizeof(*p->historybuffer));
+            p->buf = p->historybuffer;
+        }
+    }
+}
+
+static av_always_inline int predictor_update_3930(APEPredictor *p,
+                                                  const int decoded, const int filter,
+                                                  const int delayA)
+{
+    int32_t predictionA, sign;
+    int32_t d0, d1, d2, d3;
+
+    p->buf[delayA]     = p->lastA[filter];
+    d0 = p->buf[delayA    ];
+    d1 = p->buf[delayA    ] - p->buf[delayA - 1];
+    d2 = p->buf[delayA - 1] - p->buf[delayA - 2];
+    d3 = p->buf[delayA - 2] - p->buf[delayA - 3];
+
+    predictionA = d0 * p->coeffsA[filter][0] +
+                  d1 * p->coeffsA[filter][1] +
+                  d2 * p->coeffsA[filter][2] +
+                  d3 * p->coeffsA[filter][3];
+
+    p->lastA[filter] = decoded + (predictionA >> 9);
+    p->filterA[filter] = p->lastA[filter] + ((p->filterA[filter] * 31) >> 5);
+
+    sign = APESIGN(decoded);
+    p->coeffsA[filter][0] += ((d0 < 0) * 2 - 1) * sign;
+    p->coeffsA[filter][1] += ((d1 < 0) * 2 - 1) * sign;
+    p->coeffsA[filter][2] += ((d2 < 0) * 2 - 1) * sign;
+    p->coeffsA[filter][3] += ((d3 < 0) * 2 - 1) * sign;
+
+    return p->filterA[filter];
+}
+
+static void predictor_decode_stereo_3930(APEContext *ctx, int count)
+{
+    APEPredictor *p = &ctx->predictor;
+    int32_t *decoded0 = ctx->decoded[0];
+    int32_t *decoded1 = ctx->decoded[1];
+
+    ape_apply_filters(ctx, ctx->decoded[0], ctx->decoded[1], count);
+
+    while (count--) {
+        /* Predictor Y */
+        int Y = *decoded1, X = *decoded0;
+        *decoded0 = predictor_update_3930(p, Y, 0, YDELAYA);
+        decoded0++;
+        *decoded1 = predictor_update_3930(p, X, 1, XDELAYA);
+        decoded1++;
+
+        /* Combined */
+        p->buf++;
+
+        /* Have we filled the history buffer? */
+        if (p->buf == p->historybuffer + HISTORY_SIZE) {
+            memmove(p->historybuffer, p->buf,
+                    PREDICTOR_SIZE * sizeof(*p->historybuffer));
+            p->buf = p->historybuffer;
+        }
+    }
+}
+
+static void predictor_decode_mono_3930(APEContext *ctx, int count)
+{
+    APEPredictor *p = &ctx->predictor;
+    int32_t *decoded0 = ctx->decoded[0];
+
+    ape_apply_filters(ctx, ctx->decoded[0], NULL, count);
+
+    while (count--) {
+        *decoded0 = predictor_update_3930(p, *decoded0, 0, YDELAYA);
+        decoded0++;
+
+        p->buf++;
+
+        /* Have we filled the history buffer? */
+        if (p->buf == p->historybuffer + HISTORY_SIZE) {
+            memmove(p->historybuffer, p->buf,
+                    PREDICTOR_SIZE * sizeof(*p->historybuffer));
+            p->buf = p->historybuffer;
+        }
+    }
+}
+
 static av_always_inline int predictor_update_filter(APEPredictor *p,
                                                     const int decoded, const int filter,
                                                     const int delayA,  const int delayB,
@@ -592,12 +1158,14 @@ static av_always_inline int predictor_update_filter(APEPredictor *p,
     return p->filterA[filter];
 }
 
-static void predictor_decode_stereo(APEContext *ctx, int count)
+static void predictor_decode_stereo_3950(APEContext *ctx, int count)
 {
     APEPredictor *p = &ctx->predictor;
     int32_t *decoded0 = ctx->decoded[0];
     int32_t *decoded1 = ctx->decoded[1];
 
+    ape_apply_filters(ctx, ctx->decoded[0], ctx->decoded[1], count);
+
     while (count--) {
         /* Predictor Y */
         *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB,
@@ -619,12 +1187,14 @@ static void predictor_decode_stereo(APEContext *ctx, int count)
     }
 }
 
-static void predictor_decode_mono(APEContext *ctx, int count)
+static void predictor_decode_mono_3950(APEContext *ctx, int count)
 {
     APEPredictor *p = &ctx->predictor;
     int32_t *decoded0 = ctx->decoded[0];
     int32_t predictionA, currentA, A, sign;
 
+    ape_apply_filters(ctx, ctx->decoded[0], NULL, count);
+
     currentA = p->lastA[0];
 
     while (count--) {
@@ -783,11 +1353,10 @@ static void ape_unpack_mono(APEContext *ctx, int count)
         return;
     }
 
-    entropy_decode(ctx, count, 0);
-    ape_apply_filters(ctx, ctx->decoded[0], NULL, count);
+    ctx->entropy_decode_mono(ctx, count);
 
     /* Now apply the predictor decoding */
-    predictor_decode_mono(ctx, count);
+    ctx->predictor_decode_mono(ctx, count);
 
     /* Pseudo-stereo - just copy left channel to right channel */
     if (ctx->channels == 2) {
@@ -807,11 +1376,10 @@ static void ape_unpack_stereo(APEContext *ctx, int count)
         return;
     }
 
-    entropy_decode(ctx, count, 1);
-    ape_apply_filters(ctx, decoded0, decoded1, count);
+    ctx->entropy_decode_stereo(ctx, count);
 
     /* Now apply the predictor decoding */
-    predictor_decode_stereo(ctx, count);
+    ctx->predictor_decode_stereo(ctx, count);
 
     /* Decorrelate and scale to output depth */
     while (count--) {
@@ -826,6 +1394,7 @@ static void ape_unpack_stereo(APEContext *ctx, int count)
 static int ape_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     APEContext *s = avctx->priv_data;
     uint8_t *sample8;
@@ -833,7 +1402,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     int32_t *sample24;
     int i, ch, ret;
     int blockstodecode;
-    int bytes_used = 0;
 
     /* this should never be negative, but bad things will happen if it is, so
        check it just to make sure. */
@@ -856,26 +1424,36 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
             av_log(avctx, AV_LOG_WARNING, "packet size is not a multiple of 4. "
                    "extra bytes at the end will be skipped.\n");
         }
-
+        if (s->fileversion < 3950) // previous versions overread two bytes
+            buf_size += 2;
         av_fast_malloc(&s->data, &s->data_size, buf_size);
         if (!s->data)
             return AVERROR(ENOMEM);
         s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2);
+        memset(s->data + (buf_size & ~3), 0, buf_size & 3);
         s->ptr = s->data;
         s->data_end = s->data + buf_size;
 
         nblocks = bytestream_get_be32(&s->ptr);
         offset  = bytestream_get_be32(&s->ptr);
-        if (offset > 3) {
-            av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n");
-            s->data = NULL;
-            return AVERROR_INVALIDDATA;
-        }
-        if (s->data_end - s->ptr < offset) {
-            av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
-            return AVERROR_INVALIDDATA;
+        if (s->fileversion >= 3900) {
+            if (offset > 3) {
+                av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n");
+                s->data = NULL;
+                return AVERROR_INVALIDDATA;
+            }
+            if (s->data_end - s->ptr < offset) {
+                av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+                return AVERROR_INVALIDDATA;
+            }
+            s->ptr += offset;
+        } else {
+            init_get_bits(&s->gb, s->ptr, (s->data_end - s->ptr) * 8);
+            if (s->fileversion > 3800)
+                skip_bits_long(&s->gb, offset * 8);
+            else
+                skip_bits_long(&s->gb, offset);
         }
-        s->ptr += offset;
 
         if (!nblocks || nblocks > INT_MAX) {
             av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks);
@@ -889,7 +1467,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
         }
 
-        bytes_used = avpkt->size;
     }
 
     if (!s->data) {
@@ -898,6 +1475,10 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     blockstodecode = FFMIN(s->blocks_per_loop, s->samples);
+    // for old files coefficients were not interleaved,
+    // so we need to decode all of them at once
+    if (s->fileversion < 3930)
+        blockstodecode = s->samples;
 
     /* reallocate decoded sample buffer if needed */
     av_fast_malloc(&s->decoded_buffer, &s->decoded_size,
@@ -909,8 +1490,8 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     s->decoded[1] = s->decoded_buffer + FFALIGN(blockstodecode, 8);
 
     /* get output buffer */
-    s->frame.nb_samples = blockstodecode;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = blockstodecode;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -932,21 +1513,21 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
     switch (s->bps) {
     case 8:
         for (ch = 0; ch < s->channels; ch++) {
-            sample8 = (uint8_t *)s->frame.data[ch];
+            sample8 = (uint8_t *)frame->data[ch];
             for (i = 0; i < blockstodecode; i++)
                 *sample8++ = (s->decoded[ch][i] + 0x80) & 0xff;
         }
         break;
     case 16:
         for (ch = 0; ch < s->channels; ch++) {
-            sample16 = (int16_t *)s->frame.data[ch];
+            sample16 = (int16_t *)frame->data[ch];
             for (i = 0; i < blockstodecode; i++)
                 *sample16++ = s->decoded[ch][i];
         }
         break;
     case 24:
         for (ch = 0; ch < s->channels; ch++) {
-            sample24 = (int32_t *)s->frame.data[ch];
+            sample24 = (int32_t *)frame->data[ch];
             for (i = 0; i < blockstodecode; i++)
                 *sample24++ = s->decoded[ch][i] << 8;
         }
@@ -955,10 +1536,9 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
 
     s->samples -= blockstodecode;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
-    return bytes_used;
+    return (s->samples == 0) ? avpkt->size : 0;
 }
 
 static void ape_flush(AVCodecContext *avctx)
@@ -984,6 +1564,7 @@ static const AVClass ape_decoder_class = {
 
 AVCodec ff_ape_decoder = {
     .name           = "ape",
+    .long_name      = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_APE,
     .priv_data_size = sizeof(APEContext),
@@ -992,7 +1573,6 @@ AVCodec ff_ape_decoder = {
     .decode         = ape_decode_frame,
     .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1,
     .flush          = ape_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                       AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_S32P,
diff --git a/libavcodec/api-example.c b/libavcodec/api-example.c
index 949b3ef..6abbddc 100644
--- a/libavcodec/api-example.c
+++ b/libavcodec/api-example.c
@@ -82,7 +82,7 @@ static int select_channel_layout(AVCodec *codec)
 {
     const uint64_t *p;
     uint64_t best_ch_layout = 0;
-    int best_nb_channells   = 0;
+    int best_nb_channels   = 0;
 
     if (!codec->channel_layouts)
         return AV_CH_LAYOUT_STEREO;
@@ -91,9 +91,9 @@ static int select_channel_layout(AVCodec *codec)
     while (*p) {
         int nb_channels = av_get_channel_layout_nb_channels(*p);
 
-        if (nb_channels > best_nb_channells) {
+        if (nb_channels > best_nb_channels) {
             best_ch_layout    = *p;
-            best_nb_channells = nb_channels;
+            best_nb_channels = nb_channels;
         }
         p++;
     }
@@ -155,7 +155,7 @@ static void audio_encode_example(const char *filename)
     }
 
     /* frame containing input raw audio */
-    frame = avcodec_alloc_frame();
+    frame = av_frame_alloc();
     if (!frame) {
         fprintf(stderr, "could not allocate audio frame\n");
         exit(1);
@@ -212,7 +212,7 @@ static void audio_encode_example(const char *filename)
     fclose(f);
 
     av_freep(&samples);
-    avcodec_free_frame(&frame);
+    av_frame_free(&frame);
     avcodec_close(c);
     av_free(c);
 }
@@ -268,12 +268,11 @@ static void audio_decode_example(const char *outfilename, const char *filename)
         int got_frame = 0;
 
         if (!decoded_frame) {
-            if (!(decoded_frame = avcodec_alloc_frame())) {
+            if (!(decoded_frame = av_frame_alloc())) {
                 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) {
@@ -308,7 +307,7 @@ static void audio_decode_example(const char *outfilename, const char *filename)
 
     avcodec_close(c);
     av_free(c);
-    avcodec_free_frame(&decoded_frame);
+    av_frame_free(&decoded_frame);
 }
 
 /*
@@ -334,7 +333,7 @@ static void video_encode_example(const char *filename)
     }
 
     c = avcodec_alloc_context3(codec);
-    picture= avcodec_alloc_frame();
+    picture = av_frame_alloc();
 
     /* put sample parameters */
     c->bit_rate = 400000;
@@ -432,7 +431,7 @@ static void video_encode_example(const char *filename)
     avcodec_close(c);
     av_free(c);
     av_freep(&picture->data[0]);
-    avcodec_free_frame(&picture);
+    av_frame_free(&picture);
     printf("\n");
 }
 
@@ -479,7 +478,7 @@ static void video_decode_example(const char *outfilename, const char *filename)
     }
 
     c = avcodec_alloc_context3(codec);
-    picture= avcodec_alloc_frame();
+    picture = av_frame_alloc();
 
     if(codec->capabilities&CODEC_CAP_TRUNCATED)
         c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
@@ -568,7 +567,7 @@ static void video_decode_example(const char *outfilename, const char *filename)
 
     avcodec_close(c);
     av_free(c);
-    avcodec_free_frame(&picture);
+    av_frame_free(&picture);
     printf("\n");
 }
 
diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile
index ac486f4..201f897 100644
--- a/libavcodec/arm/Makefile
+++ b/libavcodec/arm/Makefile
@@ -1,102 +1,95 @@
-OBJS-$(CONFIG_AC3DSP)                  += arm/ac3dsp_init_arm.o         \
-                                          arm/ac3dsp_arm.o
+ARCH_HEADERS = mathops.h
 
-OBJS-$(CONFIG_AAC_DECODER)             += arm/sbrdsp_init_arm.o         \
-                                          arm/aacpsdsp_init_arm.o
-
-OBJS-$(CONFIG_DCA_DECODER)             += arm/dcadsp_init_arm.o         \
-
-ARMV6-OBJS-$(CONFIG_AC3DSP)            += arm/ac3dsp_armv6.o
+OBJS                                   += arm/fmtconvert_init_arm.o
 
+OBJS-$(CONFIG_AAC_DECODER)             += arm/aacpsdsp_init_arm.o       \
+                                          arm/sbrdsp_init_arm.o
+OBJS-$(CONFIG_AC3DSP)                  += arm/ac3dsp_init_arm.o         \
+                                          arm/ac3dsp_arm.o
+OBJS-$(CONFIG_DCA_DECODER)             += arm/dcadsp_init_arm.o
+OBJS-$(CONFIG_DSPUTIL)                 += arm/dsputil_init_arm.o        \
+                                          arm/dsputil_arm.o             \
+                                          arm/jrevdct_arm.o             \
+                                          arm/simple_idct_arm.o
+OBJS-$(CONFIG_FFT)                     += arm/fft_init_arm.o            \
+                                          arm/fft_fixed_init_arm.o
 OBJS-$(CONFIG_FLAC_DECODER)            += arm/flacdsp_init_arm.o        \
-                                          arm/flacdsp_arm.o             \
-
+                                          arm/flacdsp_arm.o
+OBJS-$(CONFIG_H264CHROMA)              += arm/h264chroma_init_arm.o
+OBJS-$(CONFIG_H264DSP)                 += arm/h264dsp_init_arm.o
+OBJS-$(CONFIG_H264PRED)                += arm/h264pred_init_arm.o
+OBJS-$(CONFIG_H264QPEL)                += arm/h264qpel_init_arm.o
+OBJS-$(CONFIG_HPELDSP)                 += arm/hpeldsp_init_arm.o        \
+                                          arm/hpeldsp_arm.o
 OBJS-$(CONFIG_MPEGAUDIODSP)            += arm/mpegaudiodsp_init_arm.o
-ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP)      += arm/mpegaudiodsp_fixed_armv6.o
-
 OBJS-$(CONFIG_MPEGVIDEO)               += arm/mpegvideo_arm.o
+OBJS-$(CONFIG_VORBIS_DECODER)          += arm/vorbisdsp_init_arm.o
 OBJS-$(CONFIG_VP3DSP)                  += arm/vp3dsp_init_arm.o
-OBJS-$(CONFIG_VP5_DECODER)             += arm/vp56dsp_init_arm.o
-OBJS-$(CONFIG_VP6_DECODER)             += arm/vp56dsp_init_arm.o
+OBJS-$(CONFIG_VP6_DECODER)             += arm/vp6dsp_init_arm.o
 OBJS-$(CONFIG_VP8_DECODER)             += arm/vp8dsp_init_arm.o
-ARMV6-OBJS-$(CONFIG_VP8_DECODER)       += arm/vp8_armv6.o               \
-                                          arm/vp8dsp_init_armv6.o       \
-                                          arm/vp8dsp_armv6.o
-
-OBJS-$(CONFIG_H264DSP)                 += arm/h264dsp_init_arm.o
-OBJS-$(CONFIG_H264PRED)                += arm/h264pred_init_arm.o
-
 OBJS-$(CONFIG_RV30_DECODER)            += arm/rv34dsp_init_arm.o
 OBJS-$(CONFIG_RV40_DECODER)            += arm/rv34dsp_init_arm.o        \
-                                          arm/rv40dsp_init_arm.o        \
-
+                                          arm/rv40dsp_init_arm.o
 OBJS-$(CONFIG_VIDEODSP)                += arm/videodsp_init_arm.o       \
 
-OBJS                                   += arm/dsputil_init_arm.o        \
-                                          arm/dsputil_arm.o             \
-                                          arm/fft_init_arm.o            \
-                                          arm/fft_fixed_init_arm.o      \
-                                          arm/fmtconvert_init_arm.o     \
-                                          arm/jrevdct_arm.o             \
-                                          arm/simple_idct_arm.o         \
-
+ARMV5TE-OBJS-$(CONFIG_DSPUTIL)         += arm/dsputil_init_armv5te.o    \
+                                          arm/simple_idct_armv5te.o
 ARMV5TE-OBJS-$(CONFIG_MPEGVIDEO)       += arm/mpegvideo_armv5te.o       \
-                                          arm/mpegvideo_armv5te_s.o     \
-
+                                          arm/mpegvideo_armv5te_s.o
 ARMV5TE-OBJS-$(CONFIG_VIDEODSP)        += arm/videodsp_init_armv5te.o   \
-                                          arm/videodsp_armv5te.o        \
-
-ARMV5TE-OBJS                           += arm/dsputil_init_armv5te.o    \
-                                          arm/simple_idct_armv5te.o     \
+                                          arm/videodsp_armv5te.o
 
-ARMV6-OBJS                             += arm/dsputil_init_armv6.o      \
+ARMV6-OBJS-$(CONFIG_DSPUTIL)           += arm/dsputil_init_armv6.o      \
                                           arm/dsputil_armv6.o           \
                                           arm/simple_idct_armv6.o       \
 
-VFP-OBJS-$(HAVE_ARMV6)                 += arm/fmtconvert_vfp.o
-
-VFP-OBJS                               += arm/dsputil_vfp.o             \
-                                          arm/dsputil_init_vfp.o        \
-
-NEON-OBJS-$(CONFIG_FFT)                += arm/fft_neon.o                \
-                                          arm/fft_fixed_neon.o          \
-
-NEON-OBJS-$(CONFIG_MDCT)               += arm/mdct_neon.o               \
-                                          arm/mdct_fixed_neon.o         \
+ARMV6-OBJS-$(CONFIG_AC3DSP)            += arm/ac3dsp_armv6.o
+ARMV6-OBJS-$(CONFIG_H264DSP)           += arm/h264dsp_armv6.o
+ARMV6-OBJS-$(CONFIG_HPELDSP)           += arm/hpeldsp_init_armv6.o      \
+                                          arm/hpeldsp_armv6.o
+ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP)      += arm/mpegaudiodsp_fixed_armv6.o
+ARMV6-OBJS-$(CONFIG_VP8_DECODER)       += arm/vp8_armv6.o               \
+                                          arm/vp8dsp_init_armv6.o       \
+                                          arm/vp8dsp_armv6.o
 
-NEON-OBJS-$(CONFIG_RDFT)               += arm/rdft_neon.o               \
+VFP-OBJS                               += arm/fmtconvert_vfp.o
 
-NEON-OBJS-$(CONFIG_H264DSP)            += arm/h264dsp_neon.o            \
-                                          arm/h264idct_neon.o           \
-                                          arm/h264cmc_neon.o            \
+VFP-OBJS-$(CONFIG_DCA_DECODER)         += arm/dcadsp_vfp.o              \
+                                          arm/synth_filter_vfp.o
+VFP-OBJS-$(CONFIG_FFT)                 += arm/fft_vfp.o
+VFP-OBJS-$(CONFIG_MDCT)                += arm/mdct_vfp.o
+VFP-OBJS-$(HAVE_ARMV6)                 += arm/fmtconvert_vfp_armv6.o
 
-NEON-OBJS-$(CONFIG_H264PRED)           += arm/h264pred_neon.o           \
+NEON-OBJS                              += arm/fmtconvert_neon.o
 
 NEON-OBJS-$(CONFIG_AC3DSP)             += arm/ac3dsp_neon.o
-
-NEON-OBJS-$(CONFIG_AAC_DECODER)        += arm/sbrdsp_neon.o             \
-                                          arm/aacpsdsp_neon.o
-
+NEON-OBJS-$(CONFIG_AAC_DECODER)        += arm/aacpsdsp_neon.o           \
+                                          arm/sbrdsp_neon.o
 NEON-OBJS-$(CONFIG_DCA_DECODER)        += arm/dcadsp_neon.o             \
-                                          arm/synth_filter_neon.o       \
-
+                                          arm/synth_filter_neon.o
+NEON-OBJS-$(CONFIG_DSPUTIL)            += arm/dsputil_init_neon.o       \
+                                          arm/dsputil_neon.o            \
+                                          arm/int_neon.o                \
+                                          arm/simple_idct_neon.o
+NEON-OBJS-$(CONFIG_FFT)                += arm/fft_neon.o                \
+                                          arm/fft_fixed_neon.o
+NEON-OBJS-$(CONFIG_H264CHROMA)         += arm/h264cmc_neon.o
+NEON-OBJS-$(CONFIG_H264DSP)            += arm/h264dsp_neon.o            \
+                                          arm/h264idct_neon.o
+NEON-OBJS-$(CONFIG_H264PRED)           += arm/h264pred_neon.o
+NEON-OBJS-$(CONFIG_H264QPEL)           += arm/h264qpel_neon.o           \
+                                          arm/hpeldsp_neon.o
+NEON-OBJS-$(CONFIG_HPELDSP)            += arm/hpeldsp_init_neon.o       \
+                                          arm/hpeldsp_neon.o
+NEON-OBJS-$(CONFIG_MDCT)               += arm/mdct_neon.o               \
+                                          arm/mdct_fixed_neon.o
 NEON-OBJS-$(CONFIG_MPEGVIDEO)          += arm/mpegvideo_neon.o
+NEON-OBJS-$(CONFIG_RDFT)               += arm/rdft_neon.o
 NEON-OBJS-$(CONFIG_RV30_DECODER)       += arm/rv34dsp_neon.o
 NEON-OBJS-$(CONFIG_RV40_DECODER)       += arm/rv34dsp_neon.o            \
-                                          arm/rv40dsp_neon.o            \
-                                          arm/h264cmc_neon.o            \
-
+                                          arm/rv40dsp_neon.o
+NEON-OBJS-$(CONFIG_VORBIS_DECODER)     += arm/vorbisdsp_neon.o
 NEON-OBJS-$(CONFIG_VP3DSP)             += arm/vp3dsp_neon.o
-
-NEON-OBJS-$(CONFIG_VP5_DECODER)        += arm/vp56dsp_neon.o            \
-
-NEON-OBJS-$(CONFIG_VP6_DECODER)        += arm/vp56dsp_neon.o            \
-
+NEON-OBJS-$(CONFIG_VP6_DECODER)        += arm/vp6dsp_neon.o
 NEON-OBJS-$(CONFIG_VP8_DECODER)        += arm/vp8dsp_init_neon.o        \
                                           arm/vp8dsp_neon.o
-
-NEON-OBJS                              += arm/dsputil_init_neon.o       \
-                                          arm/dsputil_neon.o            \
-                                          arm/fmtconvert_neon.o         \
-                                          arm/int_neon.o                \
-                                          arm/simple_idct_neon.o        \
diff --git a/libavcodec/arm/ac3dsp_init_arm.c b/libavcodec/arm/ac3dsp_init_arm.c
index d7cb95b..a48353a 100644
--- a/libavcodec/arm/ac3dsp_init_arm.c
+++ b/libavcodec/arm/ac3dsp_init_arm.c
@@ -31,6 +31,8 @@ void ff_ac3_lshift_int16_neon(int16_t *src, unsigned len, unsigned shift);
 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_apply_window_int16_neon(int16_t *dst, const int16_t *src,
+                                const int16_t *window, unsigned n);
 
 void ff_ac3_bit_alloc_calc_bap_armv6(int16_t *mask, int16_t *psd,
                                      int start, int end,
@@ -56,5 +58,6 @@ av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact)
         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->apply_window_int16    = ff_apply_window_int16_neon;
     }
 }
diff --git a/libavcodec/arm/ac3dsp_neon.S b/libavcodec/arm/ac3dsp_neon.S
index 82ff8af..f97b190 100644
--- a/libavcodec/arm/ac3dsp_neon.S
+++ b/libavcodec/arm/ac3dsp_neon.S
@@ -108,3 +108,26 @@ function ff_ac3_extract_exponents_neon, export=1
         bgt             1b
         bx              lr
 endfunc
+
+function ff_apply_window_int16_neon, export=1
+        push            {r4,lr}
+        add             r4,  r1,  r3,  lsl #1
+        add             lr,  r0,  r3,  lsl #1
+        sub             r4,  r4,  #16
+        sub             lr,  lr,  #16
+        mov             r12, #-16
+1:
+        vld1.16         {q0},     [r1,:128]!
+        vld1.16         {q2},     [r2,:128]!
+        vld1.16         {q1},     [r4,:128], r12
+        vrev64.16       q3,  q2
+        vqrdmulh.s16    q0,  q0,  q2
+        vqrdmulh.s16    d2,  d2,  d7
+        vqrdmulh.s16    d3,  d3,  d6
+        vst1.16         {q0},     [r0,:128]!
+        vst1.16         {q1},     [lr,:128], r12
+        subs            r3,  r3,  #16
+        bgt             1b
+
+        pop             {r4,pc}
+endfunc
diff --git a/libavcodec/arm/dca.h b/libavcodec/arm/dca.h
index 09b6e64..39ec2b6 100644
--- a/libavcodec/arm/dca.h
+++ b/libavcodec/arm/dca.h
@@ -22,16 +22,17 @@
 #define AVCODEC_ARM_DCA_H
 
 #include <stdint.h>
+
 #include "config.h"
-#include "libavutil/intmath.h"
+#include "libavcodec/mathops.h"
 
 #if HAVE_ARMV6_INLINE && AV_GCC_VERSION_AT_LEAST(4,4)
 
 #define decode_blockcodes decode_blockcodes
 static inline int decode_blockcodes(int code1, int code2, int levels,
-                                    int *values)
+                                    int32_t *values)
 {
-    int v0, v1, v2, v3, v4, v5;
+    int32_t v0, v1, v2, v3, v4, v5;
 
     __asm__ ("smmul   %8,  %14, %18           \n"
              "smmul   %11, %15, %18           \n"
diff --git a/libavcodec/arm/dcadsp_init_arm.c b/libavcodec/arm/dcadsp_init_arm.c
index f0375c9..d49a176 100644
--- a/libavcodec/arm/dcadsp_init_arm.c
+++ b/libavcodec/arm/dcadsp_init_arm.c
@@ -24,13 +24,47 @@
 #include "libavutil/attributes.h"
 #include "libavcodec/dcadsp.h"
 
+void ff_dca_lfe_fir_vfp(float *out, const float *in, const float *coefs,
+                        int decifactor, float scale);
+void ff_dca_qmf_32_subbands_vfp(float samples_in[32][8], int sb_act,
+                                SynthFilterContext *synth, FFTContext *imdct,
+                                float synth_buf_ptr[512],
+                                int *synth_buf_offset, float synth_buf2[32],
+                                const float window[512], float *samples_out,
+                                float raXin[32], float scale);
 void ff_dca_lfe_fir_neon(float *out, const float *in, const float *coefs,
                          int decifactor, float scale);
 
+void ff_synth_filter_float_vfp(FFTContext *imdct,
+                               float *synth_buf_ptr, int *synth_buf_offset,
+                               float synth_buf2[32], const float window[512],
+                               float out[32], const float in[32],
+                               float scale);
+
+void ff_synth_filter_float_neon(FFTContext *imdct,
+                                float *synth_buf_ptr, int *synth_buf_offset,
+                                float synth_buf2[32], const float window[512],
+                                float out[32], const float in[32],
+                                float scale);
+
 av_cold void ff_dcadsp_init_arm(DCADSPContext *s)
 {
     int cpu_flags = av_get_cpu_flags();
 
+    if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) {
+        s->lfe_fir = ff_dca_lfe_fir_vfp;
+        s->qmf_32_subbands = ff_dca_qmf_32_subbands_vfp;
+    }
     if (have_neon(cpu_flags))
         s->lfe_fir = ff_dca_lfe_fir_neon;
 }
+
+av_cold void ff_synth_filter_init_arm(SynthFilterContext *s)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags))
+        s->synth_filter_float = ff_synth_filter_float_vfp;
+    if (have_neon(cpu_flags))
+        s->synth_filter_float = ff_synth_filter_float_neon;
+}
diff --git a/libavcodec/arm/dcadsp_vfp.S b/libavcodec/arm/dcadsp_vfp.S
new file mode 100644
index 0000000..5892a84
--- /dev/null
+++ b/libavcodec/arm/dcadsp_vfp.S
@@ -0,0 +1,493 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison at riscosopen.org>
+ *
+ * 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/arm/asm.S"
+
+POUT          .req    a1
+PIN           .req    a2
+PCOEF         .req    a3
+DECIFACTOR    .req    a4
+OLDFPSCR      .req    a4
+COUNTER       .req    ip
+
+SCALE32       .req    s28  @ use vector of 4 in place of 9th scalar when decifactor=32 / JMAX=8
+SCALE64       .req    s0   @ spare register in scalar bank when decifactor=64 / JMAX=4
+IN0           .req    s4
+IN1           .req    s5
+IN2           .req    s6
+IN3           .req    s7
+IN4           .req    s0
+IN5           .req    s1
+IN6           .req    s2
+IN7           .req    s3
+COEF0         .req    s8   @ coefficient elements
+COEF1         .req    s9
+COEF2         .req    s10
+COEF3         .req    s11
+COEF4         .req    s12
+COEF5         .req    s13
+COEF6         .req    s14
+COEF7         .req    s15
+ACCUM0        .req    s16  @ double-buffered multiply-accumulate results
+ACCUM4        .req    s20
+POST0         .req    s24  @ do long-latency post-multiply in this vector in parallel
+POST1         .req    s25
+POST2         .req    s26
+POST3         .req    s27
+
+
+.macro inner_loop  decifactor, dir, tail, head
+ .ifc "\dir","up"
+  .set X, 0
+  .set Y, 4
+ .else
+  .set X, 4*JMAX*4 - 4
+  .set Y, -4
+ .endif
+ .ifnc "\head",""
+        vldr    COEF0, [PCOEF, #X + (0*JMAX + 0) * Y]
+        vldr    COEF1, [PCOEF, #X + (1*JMAX + 0) * Y]
+        vldr    COEF2, [PCOEF, #X + (2*JMAX + 0) * Y]
+        vldr    COEF3, [PCOEF, #X + (3*JMAX + 0) * Y]
+ .endif
+ .ifnc "\tail",""
+        vadd.f  POST0, ACCUM0, ACCUM4   @ vector operation
+ .endif
+ .ifnc "\head",""
+        vmul.f  ACCUM0, COEF0, IN0      @ vector = vector * scalar
+        vldr    COEF4, [PCOEF, #X + (0*JMAX + 1) * Y]
+        vldr    COEF5, [PCOEF, #X + (1*JMAX + 1) * Y]
+        vldr    COEF6, [PCOEF, #X + (2*JMAX + 1) * Y]
+ .endif
+ .ifnc "\tail",""
+        vmul.f  POST0, POST0, SCALE\decifactor  @ vector operation (SCALE may be scalar)
+ .endif
+ .ifnc "\head",""
+        vldr    COEF7, [PCOEF, #X + (3*JMAX + 1) * Y]
+   .ifc "\tail",""
+        vmul.f  ACCUM4, COEF4, IN1      @ vector operation
+   .endif
+        vldr    COEF0, [PCOEF, #X + (0*JMAX + 2) * Y]
+        vldr    COEF1, [PCOEF, #X + (1*JMAX + 2) * Y]
+   .ifnc "\tail",""
+        vmul.f  ACCUM4, COEF4, IN1      @ vector operation
+   .endif
+        vldr    COEF2, [PCOEF, #X + (2*JMAX + 2) * Y]
+        vldr    COEF3, [PCOEF, #X + (3*JMAX + 2) * Y]
+ .endif
+ .ifnc "\tail",""
+        vstmia  POUT!, {POST0-POST3}
+ .endif
+ .ifnc "\head",""
+        vmla.f  ACCUM0, COEF0, IN2      @ vector = vector * scalar
+        vldr    COEF4, [PCOEF, #X + (0*JMAX + 3) * Y]
+        vldr    COEF5, [PCOEF, #X + (1*JMAX + 3) * Y]
+        vldr    COEF6, [PCOEF, #X + (2*JMAX + 3) * Y]
+        vldr    COEF7, [PCOEF, #X + (3*JMAX + 3) * Y]
+        vmla.f  ACCUM4, COEF4, IN3      @ vector = vector * scalar
+  .if \decifactor == 32
+        vldr    COEF0, [PCOEF, #X + (0*JMAX + 4) * Y]
+        vldr    COEF1, [PCOEF, #X + (1*JMAX + 4) * Y]
+        vldr    COEF2, [PCOEF, #X + (2*JMAX + 4) * Y]
+        vldr    COEF3, [PCOEF, #X + (3*JMAX + 4) * Y]
+        vmla.f  ACCUM0, COEF0, IN4      @ vector = vector * scalar
+        vldr    COEF4, [PCOEF, #X + (0*JMAX + 5) * Y]
+        vldr    COEF5, [PCOEF, #X + (1*JMAX + 5) * Y]
+        vldr    COEF6, [PCOEF, #X + (2*JMAX + 5) * Y]
+        vldr    COEF7, [PCOEF, #X + (3*JMAX + 5) * Y]
+        vmla.f  ACCUM4, COEF4, IN5      @ vector = vector * scalar
+        vldr    COEF0, [PCOEF, #X + (0*JMAX + 6) * Y]
+        vldr    COEF1, [PCOEF, #X + (1*JMAX + 6) * Y]
+        vldr    COEF2, [PCOEF, #X + (2*JMAX + 6) * Y]
+        vldr    COEF3, [PCOEF, #X + (3*JMAX + 6) * Y]
+        vmla.f  ACCUM0, COEF0, IN6      @ vector = vector * scalar
+        vldr    COEF4, [PCOEF, #X + (0*JMAX + 7) * Y]
+        vldr    COEF5, [PCOEF, #X + (1*JMAX + 7) * Y]
+        vldr    COEF6, [PCOEF, #X + (2*JMAX + 7) * Y]
+        vldr    COEF7, [PCOEF, #X + (3*JMAX + 7) * Y]
+        vmla.f  ACCUM4, COEF4, IN7      @ vector = vector * scalar
+  .endif
+ .endif
+.endm
+
+.macro dca_lfe_fir  decifactor
+ .if \decifactor == 32
+  .set JMAX, 8
+        vpush   {s16-s31}
+        vmov    SCALE32, s0             @ duplicate scalar across vector
+        vldr    IN4, [PIN, #-4*4]
+        vldr    IN5, [PIN, #-5*4]
+        vldr    IN6, [PIN, #-6*4]
+        vldr    IN7, [PIN, #-7*4]
+ .else
+  .set JMAX, 4
+        vpush   {s16-s27}
+ .endif
+
+        mov     COUNTER, #\decifactor/4 - 1
+        inner_loop  \decifactor, up,, head
+1:      add     PCOEF, PCOEF, #4*JMAX*4
+        subs    COUNTER, COUNTER, #1
+        inner_loop  \decifactor, up, tail, head
+        bne     1b
+        inner_loop  \decifactor, up, tail
+
+        mov     COUNTER, #\decifactor/4 - 1
+        inner_loop  \decifactor, down,, head
+1:      sub     PCOEF, PCOEF, #4*JMAX*4
+        subs    COUNTER, COUNTER, #1
+        inner_loop  \decifactor, down, tail, head
+        bne     1b
+        inner_loop  \decifactor, down, tail
+
+ .if \decifactor == 32
+        vpop    {s16-s31}
+ .else
+        vpop    {s16-s27}
+ .endif
+        fmxr    FPSCR, OLDFPSCR
+        bx      lr
+.endm
+
+
+/* void ff_dca_lfe_fir_vfp(float *out, const float *in, const float *coefs,
+ *                         int decifactor, float scale)
+ */
+function ff_dca_lfe_fir_vfp, export=1
+        teq     DECIFACTOR, #32
+        fmrx    OLDFPSCR, FPSCR
+        ldr     ip, =0x03030000         @ RunFast mode, short vectors of length 4, stride 1
+        fmxr    FPSCR, ip
+NOVFP   vldr    s0, [sp]
+        vldr    IN0, [PIN, #-0*4]
+        vldr    IN1, [PIN, #-1*4]
+        vldr    IN2, [PIN, #-2*4]
+        vldr    IN3, [PIN, #-3*4]
+        beq     32f
+64:     dca_lfe_fir  64
+ .ltorg
+32:     dca_lfe_fir  32
+endfunc
+
+        .unreq  POUT
+        .unreq  PIN
+        .unreq  PCOEF
+        .unreq  DECIFACTOR
+        .unreq  OLDFPSCR
+        .unreq  COUNTER
+
+        .unreq  SCALE32
+        .unreq  SCALE64
+        .unreq  IN0
+        .unreq  IN1
+        .unreq  IN2
+        .unreq  IN3
+        .unreq  IN4
+        .unreq  IN5
+        .unreq  IN6
+        .unreq  IN7
+        .unreq  COEF0
+        .unreq  COEF1
+        .unreq  COEF2
+        .unreq  COEF3
+        .unreq  COEF4
+        .unreq  COEF5
+        .unreq  COEF6
+        .unreq  COEF7
+        .unreq  ACCUM0
+        .unreq  ACCUM4
+        .unreq  POST0
+        .unreq  POST1
+        .unreq  POST2
+        .unreq  POST3
+
+
+IN      .req    a1
+SBACT   .req    a2
+OLDFPSCR .req   a3
+IMDCT   .req    a4
+WINDOW  .req    v1
+OUT     .req    v2
+BUF     .req    v3
+SCALEINT .req   v4 @ only used in softfp case
+COUNT   .req    v5
+
+SCALE   .req    s0
+
+/* Stack layout differs in softfp and hardfp cases:
+ *
+ * hardfp
+ *      fp -> 6 arg words saved by caller
+ *            a3,a4,v1-v3,v5,fp,lr on entry (a3 just to pad to 8 bytes)
+ *            s16-s23 on entry
+ *            align 16
+ *     buf -> 8*32*4 bytes buffer
+ *            s0 on entry
+ *      sp -> 3 arg words for callee
+ *
+ * softfp
+ *      fp -> 7 arg words saved by caller
+ *            a4,v1-v5,fp,lr on entry
+ *            s16-s23 on entry
+ *            align 16
+ *     buf -> 8*32*4 bytes buffer
+ *      sp -> 4 arg words for callee
+ */
+
+/* void ff_dca_qmf_32_subbands_vfp(float samples_in[32][8], int sb_act,
+ *                                 SynthFilterContext *synth, FFTContext *imdct,
+ *                                 float (*synth_buf_ptr)[512],
+ *                                 int *synth_buf_offset, float (*synth_buf2)[32],
+ *                                 const float (*window)[512], float *samples_out,
+ *                                 float (*raXin)[32], float scale);
+ */
+function ff_dca_qmf_32_subbands_vfp, export=1
+VFP     push    {a3-a4,v1-v3,v5,fp,lr}
+NOVFP   push    {a4,v1-v5,fp,lr}
+        add     fp, sp, #8*4
+        vpush   {s16-s23}
+        @ The buffer pointed at by raXin isn't big enough for us to do a
+        @ complete matrix transposition as we want to, so allocate an
+        @ alternative buffer from the stack. Align to 4 words for speed.
+        sub     BUF, sp, #8*32*4
+        bic     BUF, BUF, #15
+        mov     sp, BUF
+        ldr     lr, =0x03330000     @ RunFast mode, short vectors of length 4, stride 2
+        fmrx    OLDFPSCR, FPSCR
+        fmxr    FPSCR, lr
+        @ COUNT is used to count down 2 things at once:
+        @ bits 0-4 are the number of word pairs remaining in the output row
+        @ bits 5-31 are the number of words to copy (with possible negation)
+        @   from the source matrix before we start zeroing the remainder
+        mov     COUNT, #(-4 << 5) + 16
+        adds    COUNT, COUNT, SBACT, lsl #5
+        bmi     2f
+1:
+        vldr    s8,  [IN, #(0*8+0)*4]
+        vldr    s10, [IN, #(0*8+1)*4]
+        vldr    s12, [IN, #(0*8+2)*4]
+        vldr    s14, [IN, #(0*8+3)*4]
+        vldr    s16, [IN, #(0*8+4)*4]
+        vldr    s18, [IN, #(0*8+5)*4]
+        vldr    s20, [IN, #(0*8+6)*4]
+        vldr    s22, [IN, #(0*8+7)*4]
+        vneg.f  s8, s8
+        vldr    s9,  [IN, #(1*8+0)*4]
+        vldr    s11, [IN, #(1*8+1)*4]
+        vldr    s13, [IN, #(1*8+2)*4]
+        vldr    s15, [IN, #(1*8+3)*4]
+        vneg.f  s16, s16
+        vldr    s17, [IN, #(1*8+4)*4]
+        vldr    s19, [IN, #(1*8+5)*4]
+        vldr    s21, [IN, #(1*8+6)*4]
+        vldr    s23, [IN, #(1*8+7)*4]
+        vstr    d4,  [BUF, #(0*32+0)*4]
+        vstr    d5,  [BUF, #(1*32+0)*4]
+        vstr    d6,  [BUF, #(2*32+0)*4]
+        vstr    d7,  [BUF, #(3*32+0)*4]
+        vstr    d8,  [BUF, #(4*32+0)*4]
+        vstr    d9,  [BUF, #(5*32+0)*4]
+        vstr    d10, [BUF, #(6*32+0)*4]
+        vstr    d11, [BUF, #(7*32+0)*4]
+        vldr    s9,  [IN, #(3*8+0)*4]
+        vldr    s11, [IN, #(3*8+1)*4]
+        vldr    s13, [IN, #(3*8+2)*4]
+        vldr    s15, [IN, #(3*8+3)*4]
+        vldr    s17, [IN, #(3*8+4)*4]
+        vldr    s19, [IN, #(3*8+5)*4]
+        vldr    s21, [IN, #(3*8+6)*4]
+        vldr    s23, [IN, #(3*8+7)*4]
+        vneg.f  s9, s9
+        vldr    s8,  [IN, #(2*8+0)*4]
+        vldr    s10, [IN, #(2*8+1)*4]
+        vldr    s12, [IN, #(2*8+2)*4]
+        vldr    s14, [IN, #(2*8+3)*4]
+        vneg.f  s17, s17
+        vldr    s16, [IN, #(2*8+4)*4]
+        vldr    s18, [IN, #(2*8+5)*4]
+        vldr    s20, [IN, #(2*8+6)*4]
+        vldr    s22, [IN, #(2*8+7)*4]
+        vstr    d4,  [BUF, #(0*32+2)*4]
+        vstr    d5,  [BUF, #(1*32+2)*4]
+        vstr    d6,  [BUF, #(2*32+2)*4]
+        vstr    d7,  [BUF, #(3*32+2)*4]
+        vstr    d8,  [BUF, #(4*32+2)*4]
+        vstr    d9,  [BUF, #(5*32+2)*4]
+        vstr    d10, [BUF, #(6*32+2)*4]
+        vstr    d11, [BUF, #(7*32+2)*4]
+        add     IN, IN, #4*8*4
+        add     BUF, BUF, #4*4
+        subs    COUNT, COUNT, #(4 << 5) + 2
+        bpl     1b
+2:      @ Now deal with trailing < 4 samples
+        adds    COUNT, COUNT, #3 << 5
+        bmi     4f  @ sb_act was a multiple of 4
+        bics    lr, COUNT, #0x1F
+        bne     3f
+        @ sb_act was n*4+1
+        vldr    s8,  [IN, #(0*8+0)*4]
+        vldr    s10, [IN, #(0*8+1)*4]
+        vldr    s12, [IN, #(0*8+2)*4]
+        vldr    s14, [IN, #(0*8+3)*4]
+        vldr    s16, [IN, #(0*8+4)*4]
+        vldr    s18, [IN, #(0*8+5)*4]
+        vldr    s20, [IN, #(0*8+6)*4]
+        vldr    s22, [IN, #(0*8+7)*4]
+        vneg.f  s8, s8
+        vldr    s9,  zero
+        vldr    s11, zero
+        vldr    s13, zero
+        vldr    s15, zero
+        vneg.f  s16, s16
+        vldr    s17, zero
+        vldr    s19, zero
+        vldr    s21, zero
+        vldr    s23, zero
+        vstr    d4,  [BUF, #(0*32+0)*4]
+        vstr    d5,  [BUF, #(1*32+0)*4]
+        vstr    d6,  [BUF, #(2*32+0)*4]
+        vstr    d7,  [BUF, #(3*32+0)*4]
+        vstr    d8,  [BUF, #(4*32+0)*4]
+        vstr    d9,  [BUF, #(5*32+0)*4]
+        vstr    d10, [BUF, #(6*32+0)*4]
+        vstr    d11, [BUF, #(7*32+0)*4]
+        add     BUF, BUF, #2*4
+        sub     COUNT, COUNT, #1
+        b       4f
+3:      @ sb_act was n*4+2 or n*4+3, so do the first 2
+        vldr    s8,  [IN, #(0*8+0)*4]
+        vldr    s10, [IN, #(0*8+1)*4]
+        vldr    s12, [IN, #(0*8+2)*4]
+        vldr    s14, [IN, #(0*8+3)*4]
+        vldr    s16, [IN, #(0*8+4)*4]
+        vldr    s18, [IN, #(0*8+5)*4]
+        vldr    s20, [IN, #(0*8+6)*4]
+        vldr    s22, [IN, #(0*8+7)*4]
+        vneg.f  s8, s8
+        vldr    s9,  [IN, #(1*8+0)*4]
+        vldr    s11, [IN, #(1*8+1)*4]
+        vldr    s13, [IN, #(1*8+2)*4]
+        vldr    s15, [IN, #(1*8+3)*4]
+        vneg.f  s16, s16
+        vldr    s17, [IN, #(1*8+4)*4]
+        vldr    s19, [IN, #(1*8+5)*4]
+        vldr    s21, [IN, #(1*8+6)*4]
+        vldr    s23, [IN, #(1*8+7)*4]
+        vstr    d4,  [BUF, #(0*32+0)*4]
+        vstr    d5,  [BUF, #(1*32+0)*4]
+        vstr    d6,  [BUF, #(2*32+0)*4]
+        vstr    d7,  [BUF, #(3*32+0)*4]
+        vstr    d8,  [BUF, #(4*32+0)*4]
+        vstr    d9,  [BUF, #(5*32+0)*4]
+        vstr    d10, [BUF, #(6*32+0)*4]
+        vstr    d11, [BUF, #(7*32+0)*4]
+        add     BUF, BUF, #2*4
+        sub     COUNT, COUNT, #(2 << 5) + 1
+        bics    lr, COUNT, #0x1F
+        bne     4f
+        @ sb_act was n*4+3
+        vldr    s8,  [IN, #(2*8+0)*4]
+        vldr    s10, [IN, #(2*8+1)*4]
+        vldr    s12, [IN, #(2*8+2)*4]
+        vldr    s14, [IN, #(2*8+3)*4]
+        vldr    s16, [IN, #(2*8+4)*4]
+        vldr    s18, [IN, #(2*8+5)*4]
+        vldr    s20, [IN, #(2*8+6)*4]
+        vldr    s22, [IN, #(2*8+7)*4]
+        vldr    s9,  zero
+        vldr    s11, zero
+        vldr    s13, zero
+        vldr    s15, zero
+        vldr    s17, zero
+        vldr    s19, zero
+        vldr    s21, zero
+        vldr    s23, zero
+        vstr    d4,  [BUF, #(0*32+0)*4]
+        vstr    d5,  [BUF, #(1*32+0)*4]
+        vstr    d6,  [BUF, #(2*32+0)*4]
+        vstr    d7,  [BUF, #(3*32+0)*4]
+        vstr    d8,  [BUF, #(4*32+0)*4]
+        vstr    d9,  [BUF, #(5*32+0)*4]
+        vstr    d10, [BUF, #(6*32+0)*4]
+        vstr    d11, [BUF, #(7*32+0)*4]
+        add     BUF, BUF, #2*4
+        sub     COUNT, COUNT, #1
+4:      @ Now fill the remainder with 0
+        vldr    s8, zero
+        vldr    s9, zero
+        ands    COUNT, COUNT, #0x1F
+        beq     6f
+5:      vstr    d4, [BUF, #(0*32+0)*4]
+        vstr    d4, [BUF, #(1*32+0)*4]
+        vstr    d4, [BUF, #(2*32+0)*4]
+        vstr    d4, [BUF, #(3*32+0)*4]
+        vstr    d4, [BUF, #(4*32+0)*4]
+        vstr    d4, [BUF, #(5*32+0)*4]
+        vstr    d4, [BUF, #(6*32+0)*4]
+        vstr    d4, [BUF, #(7*32+0)*4]
+        add     BUF, BUF, #2*4
+        subs    COUNT, COUNT, #1
+        bne     5b
+6:
+        fmxr    FPSCR, OLDFPSCR
+        ldr     WINDOW, [fp, #3*4]
+        ldr     OUT, [fp, #4*4]
+        sub     BUF, BUF, #32*4
+NOVFP   ldr     SCALEINT, [fp, #6*4]
+        mov     COUNT, #8
+VFP     vpush   {SCALE}
+VFP     sub     sp, sp, #3*4
+NOVFP   sub     sp, sp, #4*4
+7:
+VFP     ldr     a1, [fp, #-7*4]     @ imdct
+NOVFP   ldr     a1, [fp, #-8*4]
+        ldmia   fp, {a2-a4}
+VFP     stmia   sp, {WINDOW, OUT, BUF}
+NOVFP   stmia   sp, {WINDOW, OUT, BUF, SCALEINT}
+VFP     vldr    SCALE, [sp, #3*4]
+        bl      X(ff_synth_filter_float_vfp)
+        add     OUT, OUT, #32*4
+        add     BUF, BUF, #32*4
+        subs    COUNT, COUNT, #1
+        bne     7b
+
+A       sub     sp, fp, #(8+8)*4
+T       sub     fp, fp, #(8+8)*4
+T       mov     sp, fp
+        vpop    {s16-s23}
+VFP     pop     {a3-a4,v1-v3,v5,fp,pc}
+NOVFP   pop     {a4,v1-v5,fp,pc}
+endfunc
+
+        .unreq  IN
+        .unreq  SBACT
+        .unreq  OLDFPSCR
+        .unreq  IMDCT
+        .unreq  WINDOW
+        .unreq  OUT
+        .unreq  BUF
+        .unreq  SCALEINT
+        .unreq  COUNT
+
+        .unreq  SCALE
+
+        .align 2
+zero:   .word   0
diff --git a/libavcodec/arm/dsputil_arm.S b/libavcodec/arm/dsputil_arm.S
index 8504032..1692a58 100644
--- a/libavcodec/arm/dsputil_arm.S
+++ b/libavcodec/arm/dsputil_arm.S
@@ -26,590 +26,6 @@
 #define pld @
 #endif
 
-.macro  ALIGN_QWORD_D shift, Rd0, Rd1, Rd2, Rd3, Rn0, Rn1, Rn2, Rn3, Rn4
-        mov             \Rd0, \Rn0, lsr #(\shift * 8)
-        mov             \Rd1, \Rn1, lsr #(\shift * 8)
-        mov             \Rd2, \Rn2, lsr #(\shift * 8)
-        mov             \Rd3, \Rn3, lsr #(\shift * 8)
-        orr             \Rd0, \Rd0, \Rn1, lsl #(32 - \shift * 8)
-        orr             \Rd1, \Rd1, \Rn2, lsl #(32 - \shift * 8)
-        orr             \Rd2, \Rd2, \Rn3, lsl #(32 - \shift * 8)
-        orr             \Rd3, \Rd3, \Rn4, lsl #(32 - \shift * 8)
-.endm
-.macro  ALIGN_DWORD shift, R0, R1, R2
-        mov             \R0, \R0, lsr #(\shift * 8)
-        orr             \R0, \R0, \R1, lsl #(32 - \shift * 8)
-        mov             \R1, \R1, lsr #(\shift * 8)
-        orr             \R1, \R1, \R2, lsl #(32 - \shift * 8)
-.endm
-.macro  ALIGN_DWORD_D shift, Rdst0, Rdst1, Rsrc0, Rsrc1, Rsrc2
-        mov             \Rdst0, \Rsrc0, lsr #(\shift * 8)
-        mov             \Rdst1, \Rsrc1, lsr #(\shift * 8)
-        orr             \Rdst0, \Rdst0, \Rsrc1, lsl #(32 - (\shift * 8))
-        orr             \Rdst1, \Rdst1, \Rsrc2, lsl #(32 - (\shift * 8))
-.endm
-
-.macro  RND_AVG32 Rd0, Rd1, Rn0, Rn1, Rm0, Rm1, Rmask
-        @ Rd = (Rn | Rm) - (((Rn ^ Rm) & ~0x01010101) >> 1)
-        @ Rmask = 0xFEFEFEFE
-        @ Rn = destroy
-        eor             \Rd0, \Rn0, \Rm0
-        eor             \Rd1, \Rn1, \Rm1
-        orr             \Rn0, \Rn0, \Rm0
-        orr             \Rn1, \Rn1, \Rm1
-        and             \Rd0, \Rd0, \Rmask
-        and             \Rd1, \Rd1, \Rmask
-        sub             \Rd0, \Rn0, \Rd0, lsr #1
-        sub             \Rd1, \Rn1, \Rd1, lsr #1
-.endm
-
-.macro  NO_RND_AVG32 Rd0, Rd1, Rn0, Rn1, Rm0, Rm1, Rmask
-        @ Rd = (Rn & Rm) - (((Rn ^ Rm) & ~0x01010101) >> 1)
-        @ Rmask = 0xFEFEFEFE
-        @ Rn = destroy
-        eor             \Rd0, \Rn0, \Rm0
-        eor             \Rd1, \Rn1, \Rm1
-        and             \Rn0, \Rn0, \Rm0
-        and             \Rn1, \Rn1, \Rm1
-        and             \Rd0, \Rd0, \Rmask
-        and             \Rd1, \Rd1, \Rmask
-        add             \Rd0, \Rn0, \Rd0, lsr #1
-        add             \Rd1, \Rn1, \Rd1, lsr #1
-.endm
-
-.macro  JMP_ALIGN tmp, reg
-        ands            \tmp, \reg, #3
-        bic             \reg, \reg, #3
-        beq             1f
-        subs            \tmp, \tmp, #1
-        beq             2f
-        subs            \tmp, \tmp, #1
-        beq             3f
-        b    4f
-.endm
-
-@ ----------------------------------------------------------------
-        .align 5
-function ff_put_pixels16_arm, export=1
-        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-        @ block = word aligned, pixles = unaligned
-        pld             [r1]
-        push            {r4-r11, lr}
-        JMP_ALIGN       r5,  r1
-1:
-        ldm             r1,  {r4-r7}
-        add             r1,  r1,  r2
-        stm             r0,  {r4-r7}
-        pld             [r1]
-        subs            r3,  r3,  #1
-        add             r0,  r0,  r2
-        bne             1b
-        pop             {r4-r11, pc}
-        .align 5
-2:
-        ldm             r1,  {r4-r8}
-        add             r1,  r1,  r2
-        ALIGN_QWORD_D   1,   r9,  r10, r11, r12, r4,  r5,  r6,  r7,  r8
-        pld             [r1]
-        subs            r3,  r3,  #1
-        stm             r0,  {r9-r12}
-        add             r0,  r0,  r2
-        bne             2b
-        pop             {r4-r11, pc}
-        .align 5
-3:
-        ldm             r1,  {r4-r8}
-        add             r1,  r1,  r2
-        ALIGN_QWORD_D   2,   r9,  r10, r11, r12, r4,  r5,  r6,  r7,  r8
-        pld             [r1]
-        subs            r3,  r3,  #1
-        stm             r0,  {r9-r12}
-        add             r0,  r0,  r2
-        bne             3b
-        pop             {r4-r11, pc}
-        .align 5
-4:
-        ldm             r1,  {r4-r8}
-        add             r1,  r1,  r2
-        ALIGN_QWORD_D   3,   r9,  r10, r11, r12, r4,  r5,  r6,  r7,  r8
-        pld             [r1]
-        subs            r3,  r3,  #1
-        stm             r0,  {r9-r12}
-        add             r0,  r0,  r2
-        bne             4b
-        pop             {r4-r11,pc}
-endfunc
-
-@ ----------------------------------------------------------------
-        .align 5
-function ff_put_pixels8_arm, export=1
-        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-        @ block = word aligned, pixles = unaligned
-        pld             [r1]
-        push            {r4-r5,lr}
-        JMP_ALIGN       r5,  r1
-1:
-        ldm             r1,  {r4-r5}
-        add             r1,  r1,  r2
-        subs            r3,  r3,  #1
-        pld             [r1]
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bne             1b
-        pop             {r4-r5,pc}
-        .align 5
-2:
-        ldm             r1,  {r4-r5, r12}
-        add             r1,  r1,  r2
-        ALIGN_DWORD     1,   r4,  r5,  r12
-        pld             [r1]
-        subs            r3,  r3,  #1
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bne             2b
-        pop             {r4-r5,pc}
-        .align 5
-3:
-        ldm             r1,  {r4-r5, r12}
-        add             r1,  r1,  r2
-        ALIGN_DWORD     2,   r4,  r5,  r12
-        pld             [r1]
-        subs            r3,  r3,  #1
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bne             3b
-        pop             {r4-r5,pc}
-        .align 5
-4:
-        ldm             r1,  {r4-r5, r12}
-        add             r1,  r1,  r2
-        ALIGN_DWORD     3,   r4,  r5,  r12
-        pld             [r1]
-        subs            r3,  r3,  #1
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bne             4b
-        pop             {r4-r5,pc}
-endfunc
-
-@ ----------------------------------------------------------------
-        .align 5
-function ff_put_pixels8_x2_arm, export=1
-        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-        @ block = word aligned, pixles = unaligned
-        pld             [r1]
-        push            {r4-r10,lr}
-        ldr             r12, =0xfefefefe
-        JMP_ALIGN       r5,  r1
-1:
-        ldm             r1,  {r4-r5, r10}
-        add             r1,  r1,  r2
-        ALIGN_DWORD_D   1,   r6,  r7,  r4,  r5,  r10
-        pld             [r1]
-        RND_AVG32       r8,  r9,  r4,  r5,  r6,  r7,  r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r8-r9}
-        add             r0,  r0,  r2
-        bne             1b
-        pop             {r4-r10,pc}
-        .align 5
-2:
-        ldm             r1,  {r4-r5, r10}
-        add             r1,  r1,  r2
-        ALIGN_DWORD_D   1,   r6,  r7,  r4,  r5,  r10
-        ALIGN_DWORD_D   2,   r8,  r9,  r4,  r5,  r10
-        pld             [r1]
-        RND_AVG32       r4,  r5,  r6,  r7,  r8,  r9,  r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bne             2b
-        pop             {r4-r10,pc}
-        .align 5
-3:
-        ldm             r1,  {r4-r5, r10}
-        add             r1,  r1,  r2
-        ALIGN_DWORD_D   2,   r6,  r7,  r4,  r5,  r10
-        ALIGN_DWORD_D   3,   r8,  r9,  r4,  r5,  r10
-        pld             [r1]
-        RND_AVG32       r4,  r5,  r6,  r7,  r8,  r9,  r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bne             3b
-        pop             {r4-r10,pc}
-        .align 5
-4:
-        ldm             r1,  {r4-r5, r10}
-        add             r1,  r1,  r2
-        ALIGN_DWORD_D   3,   r6,  r7,  r4,  r5,  r10
-        pld             [r1]
-        RND_AVG32       r8,  r9,  r6,  r7,  r5,  r10, r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r8-r9}
-        add             r0,  r0,  r2
-        bne             4b
-        pop             {r4-r10,pc}
-endfunc
-
-        .align 5
-function ff_put_no_rnd_pixels8_x2_arm, export=1
-        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-        @ block = word aligned, pixles = unaligned
-        pld             [r1]
-        push            {r4-r10,lr}
-        ldr             r12, =0xfefefefe
-        JMP_ALIGN       r5,  r1
-1:
-        ldm             r1,  {r4-r5, r10}
-        add             r1,  r1,  r2
-        ALIGN_DWORD_D   1,   r6,  r7,  r4,  r5,  r10
-        pld             [r1]
-        NO_RND_AVG32    r8,  r9,  r4,  r5,  r6,  r7,  r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r8-r9}
-        add             r0,  r0,  r2
-        bne             1b
-        pop             {r4-r10,pc}
-        .align 5
-2:
-        ldm             r1,  {r4-r5, r10}
-        add             r1,  r1,  r2
-        ALIGN_DWORD_D   1,   r6,  r7,  r4,  r5,  r10
-        ALIGN_DWORD_D   2,   r8,  r9,  r4,  r5,  r10
-        pld             [r1]
-        NO_RND_AVG32    r4,  r5,  r6,  r7,  r8,  r9,  r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bne             2b
-        pop             {r4-r10,pc}
-        .align 5
-3:
-        ldm             r1,  {r4-r5, r10}
-        add             r1,  r1,  r2
-        ALIGN_DWORD_D   2,   r6,  r7,  r4,  r5,  r10
-        ALIGN_DWORD_D   3,   r8,  r9,  r4,  r5,  r10
-        pld             [r1]
-        NO_RND_AVG32    r4,  r5,  r6,  r7,  r8,  r9,  r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bne             3b
-        pop             {r4-r10,pc}
-        .align 5
-4:
-        ldm             r1,  {r4-r5, r10}
-        add             r1,  r1,  r2
-        ALIGN_DWORD_D   3,   r6,  r7,  r4,  r5,  r10
-        pld             [r1]
-        NO_RND_AVG32    r8,  r9,  r6,  r7,  r5,  r10, r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r8-r9}
-        add             r0,  r0,  r2
-        bne             4b
-        pop             {r4-r10,pc}
-endfunc
-
-
-@ ----------------------------------------------------------------
-        .align 5
-function ff_put_pixels8_y2_arm, export=1
-        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-        @ block = word aligned, pixles = unaligned
-        pld             [r1]
-        push            {r4-r11,lr}
-        mov             r3,  r3,  lsr #1
-        ldr             r12, =0xfefefefe
-        JMP_ALIGN       r5,  r1
-1:
-        ldm             r1,  {r4-r5}
-        add             r1,  r1,  r2
-6:      ldm             r1,  {r6-r7}
-        add             r1,  r1,  r2
-        pld             [r1]
-        RND_AVG32       r8,  r9,  r4,  r5,  r6,  r7,  r12
-        ldm             r1,  {r4-r5}
-        add             r1,  r1,  r2
-        stm             r0,  {r8-r9}
-        add             r0,  r0,  r2
-        pld             [r1]
-        RND_AVG32       r8,  r9,  r6,  r7,  r4,  r5,  r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r8-r9}
-        add             r0,  r0,  r2
-        bne             6b
-        pop             {r4-r11,pc}
-        .align 5
-2:
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     1,   r4,  r5,  r6
-6:      ldm             r1,  {r7-r9}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     1,   r7,  r8,  r9
-        RND_AVG32       r10, r11, r4,  r5,  r7,  r8,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     1,   r4,  r5,  r6
-        subs            r3,  r3,  #1
-        RND_AVG32       r10, r11, r7,  r8,  r4,  r5,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        bne             6b
-        pop             {r4-r11,pc}
-        .align 5
-3:
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     2,   r4,  r5,  r6
-6:      ldm             r1,  {r7-r9}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     2,   r7,  r8,  r9
-        RND_AVG32       r10, r11, r4,  r5,  r7,  r8,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     2,   r4,  r5,  r6
-        subs            r3,  r3,  #1
-        RND_AVG32       r10, r11, r7,  r8,  r4,  r5,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        bne             6b
-        pop             {r4-r11,pc}
-        .align 5
-4:
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     3,   r4,  r5,  r6
-6:      ldm             r1,  {r7-r9}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     3,   r7,  r8,  r9
-        RND_AVG32       r10, r11, r4,  r5,  r7,  r8,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     3,   r4,  r5,  r6
-        subs            r3,  r3,  #1
-        RND_AVG32       r10, r11, r7,  r8,  r4,  r5,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        bne             6b
-        pop             {r4-r11,pc}
-endfunc
-
-        .align 5
-function ff_put_no_rnd_pixels8_y2_arm, export=1
-        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-        @ block = word aligned, pixles = unaligned
-        pld             [r1]
-        push            {r4-r11,lr}
-        mov             r3,  r3,  lsr #1
-        ldr             r12, =0xfefefefe
-        JMP_ALIGN       r5,  r1
-1:
-        ldm             r1,  {r4-r5}
-        add             r1,  r1,  r2
-6:      ldm             r1,  {r6-r7}
-        add             r1,  r1,  r2
-        pld             [r1]
-        NO_RND_AVG32    r8,  r9,  r4,  r5,  r6,  r7,  r12
-        ldm             r1,  {r4-r5}
-        add             r1,  r1,  r2
-        stm             r0,  {r8-r9}
-        add             r0,  r0,  r2
-        pld             [r1]
-        NO_RND_AVG32    r8,  r9,  r6,  r7,  r4,  r5,  r12
-        subs            r3,  r3,  #1
-        stm             r0,  {r8-r9}
-        add             r0,  r0,  r2
-        bne             6b
-        pop             {r4-r11,pc}
-        .align 5
-2:
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     1,   r4,  r5,  r6
-6:      ldm             r1,  {r7-r9}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     1,   r7,  r8,  r9
-        NO_RND_AVG32    r10, r11, r4,  r5,  r7,  r8,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     1,   r4,  r5,  r6
-        subs            r3,  r3,  #1
-        NO_RND_AVG32    r10, r11, r7,  r8,  r4,  r5,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        bne             6b
-        pop             {r4-r11,pc}
-        .align 5
-3:
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     2,   r4,  r5,  r6
-6:      ldm             r1,  {r7-r9}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     2,   r7,  r8,  r9
-        NO_RND_AVG32    r10, r11, r4,  r5,  r7,  r8,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     2,   r4,  r5,  r6
-        subs            r3,  r3,  #1
-        NO_RND_AVG32    r10, r11, r7,  r8,  r4,  r5,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        bne             6b
-        pop             {r4-r11,pc}
-        .align 5
-4:
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     3,   r4,  r5,  r6
-6:      ldm             r1,  {r7-r9}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     3,   r7,  r8,  r9
-        NO_RND_AVG32    r10, r11, r4,  r5,  r7,  r8,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        ldm             r1,  {r4-r6}
-        add             r1,  r1,  r2
-        pld             [r1]
-        ALIGN_DWORD     3,   r4,  r5,  r6
-        subs            r3,  r3,  #1
-        NO_RND_AVG32    r10, r11, r7,  r8,  r4,  r5,  r12
-        stm             r0,  {r10-r11}
-        add             r0,  r0,  r2
-        bne             6b
-        pop             {r4-r11,pc}
-endfunc
-
-        .ltorg
-
-@ ----------------------------------------------------------------
-.macro  RND_XY2_IT align, rnd
-        @ l1=  (a & 0x03030303) + (b & 0x03030303) ?(+ 0x02020202)
-        @ h1= ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2)
-.if \align == 0
-        ldm             r1,  {r6-r8}
-.elseif \align == 3
-        ldm             r1,  {r5-r7}
-.else
-        ldm             r1,  {r8-r10}
-.endif
-        add             r1,  r1,  r2
-        pld             [r1]
-.if \align == 0
-        ALIGN_DWORD_D   1,   r4,  r5,  r6,  r7,  r8
-.elseif \align == 1
-        ALIGN_DWORD_D   1,   r4,  r5,  r8,  r9,  r10
-        ALIGN_DWORD_D   2,   r6,  r7,  r8,  r9,  r10
-.elseif \align == 2
-        ALIGN_DWORD_D   2,   r4,  r5,  r8,  r9,  r10
-        ALIGN_DWORD_D   3,   r6,  r7,  r8,  r9,  r10
-.elseif \align == 3
-        ALIGN_DWORD_D   3,   r4,  r5,  r5,  r6,  r7
-.endif
-        ldr             r14, =0x03030303
-        tst             r3,  #1
-        and             r8,  r4,  r14
-        and             r9,  r5,  r14
-        and             r10, r6,  r14
-        and             r11, r7,  r14
-        it              eq
-        andeq           r14, r14, r14, \rnd #1
-        add             r8,  r8,  r10
-        add             r9,  r9,  r11
-        ldr             r12, =0xfcfcfcfc >> 2
-        itt             eq
-        addeq           r8,  r8,  r14
-        addeq           r9,  r9,  r14
-        and             r4,  r12, r4,  lsr #2
-        and             r5,  r12, r5,  lsr #2
-        and             r6,  r12, r6,  lsr #2
-        and             r7,  r12, r7,  lsr #2
-        add             r10, r4,  r6
-        add             r11, r5,  r7
-        subs            r3,  r3,  #1
-.endm
-
-.macro RND_XY2_EXPAND align, rnd
-        RND_XY2_IT      \align, \rnd
-6:      push            {r8-r11}
-        RND_XY2_IT      \align, \rnd
-        pop             {r4-r7}
-        add             r4,  r4,  r8
-        add             r5,  r5,  r9
-        ldr             r14, =0x0f0f0f0f
-        add             r6,  r6,  r10
-        add             r7,  r7,  r11
-        and             r4,  r14, r4,  lsr #2
-        and             r5,  r14, r5,  lsr #2
-        add             r4,  r4,  r6
-        add             r5,  r5,  r7
-        stm             r0,  {r4-r5}
-        add             r0,  r0,  r2
-        bge             6b
-        pop             {r4-r11,pc}
-.endm
-
-        .align 5
-function ff_put_pixels8_xy2_arm, export=1
-        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-        @ block = word aligned, pixles = unaligned
-        pld             [r1]
-        push            {r4-r11,lr} @ R14 is also called LR
-        JMP_ALIGN       r5,  r1
-1:      RND_XY2_EXPAND  0, lsl
-        .align 5
-2:      RND_XY2_EXPAND  1, lsl
-        .align 5
-3:      RND_XY2_EXPAND  2, lsl
-        .align 5
-4:      RND_XY2_EXPAND  3, lsl
-endfunc
-
-        .align 5
-function ff_put_no_rnd_pixels8_xy2_arm, export=1
-        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-        @ block = word aligned, pixles = unaligned
-        pld             [r1]
-        push            {r4-r11,lr}
-        JMP_ALIGN       r5,  r1
-1:      RND_XY2_EXPAND  0, lsr
-        .align 5
-2:      RND_XY2_EXPAND  1, lsr
-        .align 5
-3:      RND_XY2_EXPAND  2, lsr
-        .align 5
-4:      RND_XY2_EXPAND  3, lsr
-endfunc
-
         .align 5
 @ void ff_add_pixels_clamped_arm(int16_t *block, uint8_t *dest, int stride)
 function ff_add_pixels_clamped_arm, export=1
diff --git a/libavcodec/arm/dsputil_armv6.S b/libavcodec/arm/dsputil_armv6.S
index 61535a1..e667a47 100644
--- a/libavcodec/arm/dsputil_armv6.S
+++ b/libavcodec/arm/dsputil_armv6.S
@@ -20,244 +20,6 @@
 
 #include "libavutil/arm/asm.S"
 
-.macro  call_2x_pixels  type, subp
-function ff_\type\()_pixels16\subp\()_armv6, export=1
-        push            {r0-r3, lr}
-        bl              ff_\type\()_pixels8\subp\()_armv6
-        pop             {r0-r3, lr}
-        add             r0,  r0,  #8
-        add             r1,  r1,  #8
-        b               ff_\type\()_pixels8\subp\()_armv6
-endfunc
-.endm
-
-call_2x_pixels          avg
-call_2x_pixels          put, _x2
-call_2x_pixels          put, _y2
-call_2x_pixels          put, _x2_no_rnd
-call_2x_pixels          put, _y2_no_rnd
-
-function ff_put_pixels16_armv6, export=1
-        push            {r4-r11}
-1:
-        ldr             r5,  [r1, #4]
-        ldr             r6,  [r1, #8]
-        ldr             r7,  [r1, #12]
-        ldr_post        r4,  r1,  r2
-        strd            r6,  r7,  [r0, #8]
-        ldr             r9,  [r1, #4]
-        strd_post       r4,  r5,  r0,  r2
-        ldr             r10, [r1, #8]
-        ldr             r11, [r1, #12]
-        ldr_post        r8,  r1,  r2
-        strd            r10, r11, [r0, #8]
-        subs            r3,  r3,  #2
-        strd_post       r8,  r9,  r0,  r2
-        bne             1b
-
-        pop             {r4-r11}
-        bx              lr
-endfunc
-
-function ff_put_pixels8_armv6, export=1
-        push            {r4-r7}
-1:
-        ldr             r5,  [r1, #4]
-        ldr_post        r4,  r1,  r2
-        ldr             r7,  [r1, #4]
-        strd_post       r4,  r5,  r0,  r2
-        ldr_post        r6,  r1,  r2
-        subs            r3,  r3,  #2
-        strd_post       r6,  r7,  r0,  r2
-        bne             1b
-
-        pop             {r4-r7}
-        bx              lr
-endfunc
-
-function ff_put_pixels8_x2_armv6, export=1
-        push            {r4-r11, lr}
-        mov             r12, #1
-        orr             r12, r12, r12, lsl #8
-        orr             r12, r12, r12, lsl #16
-1:
-        ldr             r4,  [r1]
-        subs            r3,  r3,  #2
-        ldr             r5,  [r1, #4]
-        ldr             r7,  [r1, #5]
-        lsr             r6,  r4,  #8
-        ldr_pre         r8,  r1,  r2
-        orr             r6,  r6,  r5,  lsl #24
-        ldr             r9,  [r1, #4]
-        ldr             r11, [r1, #5]
-        lsr             r10, r8,  #8
-        add             r1,  r1,  r2
-        orr             r10, r10, r9,  lsl #24
-        eor             r14, r4,  r6
-        uhadd8          r4,  r4,  r6
-        eor             r6,  r5,  r7
-        uhadd8          r5,  r5,  r7
-        and             r14, r14, r12
-        and             r6,  r6,  r12
-        uadd8           r4,  r4,  r14
-        eor             r14, r8,  r10
-        uadd8           r5,  r5,  r6
-        eor             r6,  r9,  r11
-        uhadd8          r8,  r8,  r10
-        and             r14, r14, r12
-        uhadd8          r9,  r9,  r11
-        and             r6,  r6,  r12
-        uadd8           r8,  r8,  r14
-        strd_post       r4,  r5,  r0,  r2
-        uadd8           r9,  r9,  r6
-        strd_post       r8,  r9,  r0,  r2
-        bne             1b
-
-        pop             {r4-r11, pc}
-endfunc
-
-function ff_put_pixels8_y2_armv6, export=1
-        push            {r4-r11}
-        mov             r12, #1
-        orr             r12, r12, r12, lsl #8
-        orr             r12, r12, r12, lsl #16
-        ldr             r4,  [r1]
-        ldr             r5,  [r1, #4]
-        ldr_pre         r6,  r1,  r2
-        ldr             r7,  [r1, #4]
-1:
-        subs            r3,  r3,  #2
-        uhadd8          r8,  r4,  r6
-        eor             r10, r4,  r6
-        uhadd8          r9,  r5,  r7
-        eor             r11, r5,  r7
-        and             r10, r10, r12
-        ldr_pre         r4,  r1,  r2
-        uadd8           r8,  r8,  r10
-        and             r11, r11, r12
-        uadd8           r9,  r9,  r11
-        ldr             r5,  [r1, #4]
-        uhadd8          r10, r4,  r6
-        eor             r6,  r4,  r6
-        uhadd8          r11, r5,  r7
-        and             r6,  r6,  r12
-        eor             r7,  r5,  r7
-        uadd8           r10, r10, r6
-        and             r7,  r7,  r12
-        ldr_pre         r6,  r1,  r2
-        uadd8           r11, r11, r7
-        strd_post       r8,  r9,  r0,  r2
-        ldr             r7,  [r1, #4]
-        strd_post       r10, r11, r0,  r2
-        bne             1b
-
-        pop             {r4-r11}
-        bx              lr
-endfunc
-
-function ff_put_pixels8_x2_no_rnd_armv6, export=1
-        push            {r4-r9, lr}
-1:
-        subs            r3,  r3,  #2
-        ldr             r4,  [r1]
-        ldr             r5,  [r1, #4]
-        ldr             r7,  [r1, #5]
-        ldr_pre         r8,  r1,  r2
-        ldr             r9,  [r1, #4]
-        ldr             r14, [r1, #5]
-        add             r1,  r1,  r2
-        lsr             r6,  r4,  #8
-        orr             r6,  r6,  r5,  lsl #24
-        lsr             r12, r8,  #8
-        orr             r12, r12, r9,  lsl #24
-        uhadd8          r4,  r4,  r6
-        uhadd8          r5,  r5,  r7
-        uhadd8          r8,  r8,  r12
-        uhadd8          r9,  r9,  r14
-        stm             r0,  {r4,r5}
-        add             r0,  r0,  r2
-        stm             r0,  {r8,r9}
-        add             r0,  r0,  r2
-        bne             1b
-
-        pop             {r4-r9, pc}
-endfunc
-
-function ff_put_pixels8_y2_no_rnd_armv6, export=1
-        push            {r4-r9, lr}
-        ldr             r4,  [r1]
-        ldr             r5,  [r1, #4]
-        ldr_pre         r6,  r1,  r2
-        ldr             r7,  [r1, #4]
-1:
-        subs            r3,  r3,  #2
-        uhadd8          r8,  r4,  r6
-        ldr_pre         r4,  r1,  r2
-        uhadd8          r9,  r5,  r7
-        ldr             r5,  [r1, #4]
-        uhadd8          r12, r4,  r6
-        ldr_pre         r6,  r1,  r2
-        uhadd8          r14, r5,  r7
-        ldr             r7,  [r1, #4]
-        stm             r0,  {r8,r9}
-        add             r0,  r0,  r2
-        stm             r0,  {r12,r14}
-        add             r0,  r0,  r2
-        bne             1b
-
-        pop             {r4-r9, pc}
-endfunc
-
-function ff_avg_pixels8_armv6, export=1
-        pld             [r1, r2]
-        push            {r4-r10, lr}
-        mov             lr,  #1
-        orr             lr,  lr,  lr,  lsl #8
-        orr             lr,  lr,  lr,  lsl #16
-        ldrd            r4,  r5,  [r0]
-        ldr             r10, [r1, #4]
-        ldr_post        r9,  r1,  r2
-        subs            r3,  r3,  #2
-1:
-        pld             [r1, r2]
-        eor             r8,  r4,  r9
-        uhadd8          r4,  r4,  r9
-        eor             r12, r5,  r10
-        ldrd_reg        r6,  r7,  r0,  r2
-        uhadd8          r5,  r5,  r10
-        and             r8,  r8,  lr
-        ldr             r10, [r1, #4]
-        and             r12, r12, lr
-        uadd8           r4,  r4,  r8
-        ldr_post        r9,  r1,  r2
-        eor             r8,  r6,  r9
-        uadd8           r5,  r5,  r12
-        pld             [r1, r2,  lsl #1]
-        eor             r12, r7,  r10
-        uhadd8          r6,  r6,  r9
-        strd_post       r4,  r5,  r0,  r2
-        uhadd8          r7,  r7,  r10
-        beq             2f
-        and             r8,  r8,  lr
-        ldrd_reg        r4,  r5,  r0,  r2
-        uadd8           r6,  r6,  r8
-        ldr             r10, [r1, #4]
-        and             r12, r12, lr
-        subs            r3,  r3,  #2
-        uadd8           r7,  r7,  r12
-        ldr_post        r9,  r1,  r2
-        strd_post       r6,  r7,  r0,  r2
-        b               1b
-2:
-        and             r8,  r8,  lr
-        and             r12, r12, lr
-        uadd8           r6,  r6,  r8
-        uadd8           r7,  r7,  r12
-        strd_post       r6,  r7,  r0,  r2
-
-        pop             {r4-r10, pc}
-endfunc
-
 function ff_add_pixels_clamped_armv6, export=1
         push            {r4-r8,lr}
         mov             r3,  #8
diff --git a/libavcodec/arm/dsputil_init_arm.c b/libavcodec/arm/dsputil_init_arm.c
index 0c1563d..bb68eb6 100644
--- a/libavcodec/arm/dsputil_init_arm.c
+++ b/libavcodec/arm/dsputil_init_arm.c
@@ -19,64 +19,45 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_arm.h"
 
-void ff_j_rev_dct_arm(DCTELEM *data);
-void ff_simple_idct_arm(DCTELEM *data);
+void ff_j_rev_dct_arm(int16_t *data);
+void ff_simple_idct_arm(int16_t *data);
 
 /* XXX: local hack */
-static void (*ff_put_pixels_clamped)(const DCTELEM *block, uint8_t *pixels, int line_size);
-static void (*ff_add_pixels_clamped)(const DCTELEM *block, uint8_t *pixels, int line_size);
+static void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size);
+static void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, int line_size);
 
-void ff_put_pixels8_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-
-void ff_put_no_rnd_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_no_rnd_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_no_rnd_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-
-void ff_put_pixels16_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-
-CALL_2X_PIXELS(ff_put_pixels16_x2_arm,         ff_put_pixels8_x2_arm,        8)
-CALL_2X_PIXELS(ff_put_pixels16_y2_arm,         ff_put_pixels8_y2_arm,        8)
-CALL_2X_PIXELS(ff_put_pixels16_xy2_arm,        ff_put_pixels8_xy2_arm,       8)
-CALL_2X_PIXELS(ff_put_no_rnd_pixels16_x2_arm,  ff_put_no_rnd_pixels8_x2_arm, 8)
-CALL_2X_PIXELS(ff_put_no_rnd_pixels16_y2_arm,  ff_put_no_rnd_pixels8_y2_arm, 8)
-CALL_2X_PIXELS(ff_put_no_rnd_pixels16_xy2_arm, ff_put_no_rnd_pixels8_xy2_arm,8)
-
-void ff_add_pixels_clamped_arm(const DCTELEM *block, uint8_t *dest,
+void ff_add_pixels_clamped_arm(const int16_t *block, uint8_t *dest,
                                int line_size);
 
 /* XXX: those functions should be suppressed ASAP when all IDCTs are
    converted */
-static void j_rev_dct_arm_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void j_rev_dct_arm_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct_arm (block);
     ff_put_pixels_clamped(block, dest, line_size);
 }
-static void j_rev_dct_arm_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void j_rev_dct_arm_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct_arm (block);
     ff_add_pixels_clamped(block, dest, line_size);
 }
-static void simple_idct_arm_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void simple_idct_arm_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_simple_idct_arm (block);
     ff_put_pixels_clamped(block, dest, line_size);
 }
-static void simple_idct_arm_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void simple_idct_arm_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_simple_idct_arm (block);
     ff_add_pixels_clamped(block, dest, line_size);
 }
 
-void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_arm(DSPContext *c, AVCodecContext *avctx)
 {
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
     int cpu_flags = av_get_cpu_flags();
 
     ff_put_pixels_clamped = c->put_pixels_clamped;
@@ -99,28 +80,7 @@ void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx)
 
     c->add_pixels_clamped = ff_add_pixels_clamped_arm;
 
-    if (!high_bit_depth) {
-    c->put_pixels_tab[0][0] = ff_put_pixels16_arm;
-    c->put_pixels_tab[0][1] = ff_put_pixels16_x2_arm;
-    c->put_pixels_tab[0][2] = ff_put_pixels16_y2_arm;
-    c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_arm;
-    c->put_pixels_tab[1][0] = ff_put_pixels8_arm;
-    c->put_pixels_tab[1][1] = ff_put_pixels8_x2_arm;
-    c->put_pixels_tab[1][2] = ff_put_pixels8_y2_arm;
-    c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_arm;
-
-    c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_arm;
-    c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_arm;
-    c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_arm;
-    c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_arm;
-    c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_arm;
-    c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_arm;
-    c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_arm;
-    c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_arm;
-    }
-
     if (have_armv5te(cpu_flags)) ff_dsputil_init_armv5te(c, avctx);
     if (have_armv6(cpu_flags))   ff_dsputil_init_armv6(c, avctx);
-    if (have_vfp(cpu_flags))     ff_dsputil_init_vfp(c, avctx);
     if (have_neon(cpu_flags))    ff_dsputil_init_neon(c, avctx);
 }
diff --git a/libavcodec/arm/dsputil_init_armv5te.c b/libavcodec/arm/dsputil_init_armv5te.c
index 17017aa..302a655 100644
--- a/libavcodec/arm/dsputil_init_armv5te.c
+++ b/libavcodec/arm/dsputil_init_armv5te.c
@@ -18,12 +18,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
 #include "dsputil_arm.h"
 
-void ff_simple_idct_armv5te(DCTELEM *data);
-void ff_simple_idct_put_armv5te(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_add_armv5te(uint8_t *dest, int line_size, DCTELEM *data);
+void ff_simple_idct_armv5te(int16_t *data);
+void ff_simple_idct_put_armv5te(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_add_armv5te(uint8_t *dest, int line_size, int16_t *data);
 
 av_cold void ff_dsputil_init_armv5te(DSPContext *c, AVCodecContext *avctx)
 {
diff --git a/libavcodec/arm/dsputil_init_armv6.c b/libavcodec/arm/dsputil_init_armv6.c
index fbe6014..4c8ba47 100644
--- a/libavcodec/arm/dsputil_init_armv6.c
+++ b/libavcodec/arm/dsputil_init_armv6.c
@@ -21,37 +21,18 @@
 #include <stdint.h>
 
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_arm.h"
 
-void ff_simple_idct_armv6(DCTELEM *data);
-void ff_simple_idct_put_armv6(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_add_armv6(uint8_t *dest, int line_size, DCTELEM *data);
+void ff_simple_idct_armv6(int16_t *data);
+void ff_simple_idct_put_armv6(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_add_armv6(uint8_t *dest, int line_size, int16_t *data);
 
-void ff_put_pixels16_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_x2_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_y2_armv6(uint8_t *, const uint8_t *, int, int);
-
-void ff_put_pixels16_x2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_y2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int);
-
-void ff_avg_pixels16_armv6(uint8_t *, const uint8_t *, int, int);
-
-void ff_put_pixels8_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_x2_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_y2_armv6(uint8_t *, const uint8_t *, int, int);
-
-void ff_put_pixels8_x2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_y2_no_rnd_armv6(uint8_t *, const uint8_t *, int, int);
-
-void ff_avg_pixels8_armv6(uint8_t *, const uint8_t *, int, int);
-
-void ff_add_pixels_clamped_armv6(const DCTELEM *block,
+void ff_add_pixels_clamped_armv6(const int16_t *block,
                                  uint8_t *restrict pixels,
                                  int line_size);
 
-void ff_get_pixels_armv6(DCTELEM *block, const uint8_t *pixels, int stride);
-void ff_diff_pixels_armv6(DCTELEM *block, const uint8_t *s1,
+void ff_get_pixels_armv6(int16_t *block, const uint8_t *pixels, int stride);
+void ff_diff_pixels_armv6(int16_t *block, const uint8_t *s1,
                           const uint8_t *s2, int stride);
 
 int ff_pix_abs16_armv6(void *s, uint8_t *blk1, uint8_t *blk2,
@@ -83,29 +64,6 @@ av_cold void ff_dsputil_init_armv6(DSPContext *c, AVCodecContext *avctx)
         c->idct_permutation_type = FF_LIBMPEG2_IDCT_PERM;
     }
 
-    if (!high_bit_depth) {
-    c->put_pixels_tab[0][0] = ff_put_pixels16_armv6;
-    c->put_pixels_tab[0][1] = ff_put_pixels16_x2_armv6;
-    c->put_pixels_tab[0][2] = ff_put_pixels16_y2_armv6;
-/*     c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_armv6; */
-    c->put_pixels_tab[1][0] = ff_put_pixels8_armv6;
-    c->put_pixels_tab[1][1] = ff_put_pixels8_x2_armv6;
-    c->put_pixels_tab[1][2] = ff_put_pixels8_y2_armv6;
-/*     c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_armv6; */
-
-    c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_armv6;
-    c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_armv6;
-    c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_armv6;
-/*     c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_armv6; */
-    c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_armv6;
-    c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_armv6;
-    c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_armv6;
-/*     c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_armv6; */
-
-    c->avg_pixels_tab[0][0] = ff_avg_pixels16_armv6;
-    c->avg_pixels_tab[1][0] = ff_avg_pixels8_armv6;
-    }
-
     if (!high_bit_depth)
         c->get_pixels = ff_get_pixels_armv6;
     c->add_pixels_clamped = ff_add_pixels_clamped_armv6;
diff --git a/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c
index b2e7204..0926c84 100644
--- a/libavcodec/arm/dsputil_init_neon.c
+++ b/libavcodec/arm/dsputil_init_neon.c
@@ -21,151 +21,31 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_arm.h"
 
-void ff_simple_idct_neon(DCTELEM *data);
-void ff_simple_idct_put_neon(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_add_neon(uint8_t *dest, int line_size, DCTELEM *data);
+void ff_simple_idct_neon(int16_t *data);
+void ff_simple_idct_put_neon(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_add_neon(uint8_t *dest, int line_size, int16_t *data);
 
-void ff_clear_block_neon(DCTELEM *block);
-void ff_clear_blocks_neon(DCTELEM *blocks);
+void ff_clear_block_neon(int16_t *block);
+void ff_clear_blocks_neon(int16_t *blocks);
 
-void ff_put_pixels16_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_x2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_y2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_xy2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_x2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_y2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_xy2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_put_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-
-void ff_avg_pixels16_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_x2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_y2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_xy2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_x2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_y2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_xy2_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_x2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-void ff_avg_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, int, int);
-
-void ff_add_pixels_clamped_neon(const DCTELEM *, uint8_t *, int);
-void ff_put_pixels_clamped_neon(const DCTELEM *, uint8_t *, int);
-void ff_put_signed_pixels_clamped_neon(const DCTELEM *, uint8_t *, int);
-
-void ff_put_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, int);
-
-void ff_put_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, int);
-void ff_put_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, int);
-
-void ff_avg_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, int);
-
-void ff_avg_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, int);
-void ff_avg_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, int);
-
-void ff_put_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_put_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_put_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
-
-void ff_avg_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_avg_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
-void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
-
-void ff_vector_fmul_window_neon(float *dst, const float *src0,
-                                const float *src1, const float *win, int len);
-void ff_butterflies_float_neon(float *v1, float *v2, int len);
-float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
-void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
-                                 const float *src1, int len);
-void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1,
-                             const float *src2, int len);
+void ff_add_pixels_clamped_neon(const int16_t *, uint8_t *, int);
+void ff_put_pixels_clamped_neon(const int16_t *, uint8_t *, int);
+void ff_put_signed_pixels_clamped_neon(const int16_t *, uint8_t *, int);
 
 void ff_vector_clipf_neon(float *dst, const float *src, float min, float max,
                           int len);
 void ff_vector_clip_int32_neon(int32_t *dst, const int32_t *src, int32_t min,
                                int32_t max, unsigned int len);
 
-void ff_vorbis_inverse_coupling_neon(float *mag, float *ang, int blocksize);
-
 int32_t ff_scalarproduct_int16_neon(const int16_t *v1, const int16_t *v2, int len);
 int32_t ff_scalarproduct_and_madd_int16_neon(int16_t *v1, const int16_t *v2,
                                              const int16_t *v3, int len, int mul);
 
-void ff_apply_window_int16_neon(int16_t *dst, const int16_t *src,
-                                const int16_t *window, unsigned n);
-
-void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -182,139 +62,15 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
     if (!high_bit_depth) {
         c->clear_block  = ff_clear_block_neon;
         c->clear_blocks = ff_clear_blocks_neon;
-
-        c->put_pixels_tab[0][0] = ff_put_pixels16_neon;
-        c->put_pixels_tab[0][1] = ff_put_pixels16_x2_neon;
-        c->put_pixels_tab[0][2] = ff_put_pixels16_y2_neon;
-        c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_neon;
-        c->put_pixels_tab[1][0] = ff_put_pixels8_neon;
-        c->put_pixels_tab[1][1] = ff_put_pixels8_x2_neon;
-        c->put_pixels_tab[1][2] = ff_put_pixels8_y2_neon;
-        c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_neon;
-
-        c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_neon;
-        c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_neon;
-        c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_neon;
-        c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_neon;
-        c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_neon;
-        c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_neon;
-        c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_neon;
-        c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_neon;
-
-        c->avg_pixels_tab[0][0] = ff_avg_pixels16_neon;
-        c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_neon;
-        c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_neon;
-        c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_neon;
-        c->avg_pixels_tab[1][0] = ff_avg_pixels8_neon;
-        c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_neon;
-        c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_neon;
-        c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_neon;
-
-        c->avg_no_rnd_pixels_tab[0][0] = ff_avg_pixels16_neon;
-        c->avg_no_rnd_pixels_tab[0][1] = ff_avg_pixels16_x2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[0][2] = ff_avg_pixels16_y2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[0][3] = ff_avg_pixels16_xy2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[1][0] = ff_avg_pixels8_neon;
-        c->avg_no_rnd_pixels_tab[1][1] = ff_avg_pixels8_x2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[1][2] = ff_avg_pixels8_y2_no_rnd_neon;
-        c->avg_no_rnd_pixels_tab[1][3] = ff_avg_pixels8_xy2_no_rnd_neon;
     }
 
     c->add_pixels_clamped = ff_add_pixels_clamped_neon;
     c->put_pixels_clamped = ff_put_pixels_clamped_neon;
     c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_neon;
 
-    if (CONFIG_H264_DECODER && !high_bit_depth) {
-        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_neon;
-        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_neon;
-        c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_neon;
-
-        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_neon;
-        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_neon;
-        c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_neon;
-
-        c->put_h264_qpel_pixels_tab[0][ 0] = ff_put_h264_qpel16_mc00_neon;
-        c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon;
-        c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon;
-        c->put_h264_qpel_pixels_tab[0][ 3] = ff_put_h264_qpel16_mc30_neon;
-        c->put_h264_qpel_pixels_tab[0][ 4] = ff_put_h264_qpel16_mc01_neon;
-        c->put_h264_qpel_pixels_tab[0][ 5] = ff_put_h264_qpel16_mc11_neon;
-        c->put_h264_qpel_pixels_tab[0][ 6] = ff_put_h264_qpel16_mc21_neon;
-        c->put_h264_qpel_pixels_tab[0][ 7] = ff_put_h264_qpel16_mc31_neon;
-        c->put_h264_qpel_pixels_tab[0][ 8] = ff_put_h264_qpel16_mc02_neon;
-        c->put_h264_qpel_pixels_tab[0][ 9] = ff_put_h264_qpel16_mc12_neon;
-        c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_neon;
-        c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_neon;
-        c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_neon;
-        c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_neon;
-        c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_neon;
-        c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon;
-
-        c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon;
-        c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon;
-        c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_neon;
-        c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon;
-        c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon;
-        c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon;
-        c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon;
-        c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon;
-        c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon;
-        c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon;
-        c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon;
-        c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon;
-        c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon;
-        c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon;
-        c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon;
-        c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon;
-
-        c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 1] = ff_avg_h264_qpel16_mc10_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 2] = ff_avg_h264_qpel16_mc20_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 3] = ff_avg_h264_qpel16_mc30_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 4] = ff_avg_h264_qpel16_mc01_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 5] = ff_avg_h264_qpel16_mc11_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 6] = ff_avg_h264_qpel16_mc21_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 7] = ff_avg_h264_qpel16_mc31_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 8] = ff_avg_h264_qpel16_mc02_neon;
-        c->avg_h264_qpel_pixels_tab[0][ 9] = ff_avg_h264_qpel16_mc12_neon;
-        c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_neon;
-        c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_neon;
-        c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_neon;
-        c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_neon;
-        c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_neon;
-        c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_neon;
-
-        c->avg_h264_qpel_pixels_tab[1][ 0] = ff_avg_h264_qpel8_mc00_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_neon;
-        c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_neon;
-        c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_neon;
-        c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_neon;
-        c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_neon;
-        c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon;
-        c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon;
-        c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon;
-    }
-
-    c->vector_fmul_window         = ff_vector_fmul_window_neon;
-    c->butterflies_float          = ff_butterflies_float_neon;
-    c->scalarproduct_float        = ff_scalarproduct_float_neon;
-    c->vector_fmul_reverse        = ff_vector_fmul_reverse_neon;
-    c->vector_fmul_add            = ff_vector_fmul_add_neon;
     c->vector_clipf               = ff_vector_clipf_neon;
     c->vector_clip_int32          = ff_vector_clip_int32_neon;
 
-    if (CONFIG_VORBIS_DECODER)
-        c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon;
-
     c->scalarproduct_int16 = ff_scalarproduct_int16_neon;
     c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_neon;
-
-    c->apply_window_int16 = ff_apply_window_int16_neon;
 }
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/arm/dsputil_init_vfp.c
deleted file mode 100644
index d77d686..0000000
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb at users.sourceforge.net>
- *
- * 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 "libavcodec/dsputil.h"
-#include "dsputil_arm.h"
-
-void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-                                const float *src1, int len);
-
-void ff_dsputil_init_vfp(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
-}
diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S
index cf9ad9e..e30bd10 100644
--- a/libavcodec/arm/dsputil_neon.S
+++ b/libavcodec/arm/dsputil_neon.S
@@ -19,7 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "config.h"
 #include "libavutil/arm/asm.S"
 
 function ff_clear_block_neon, export=1
@@ -38,394 +37,6 @@ function ff_clear_blocks_neon, export=1
         bx              lr
 endfunc
 
-.macro  pixels16        rnd=1, avg=0
-  .if \avg
-        mov             r12, r0
-  .endif
-1:      vld1.8          {q0},     [r1], r2
-        vld1.8          {q1},     [r1], r2
-        vld1.8          {q2},     [r1], r2
-        pld             [r1, r2, lsl #2]
-        vld1.8          {q3},     [r1], r2
-        pld             [r1]
-        pld             [r1, r2]
-        pld             [r1, r2, lsl #1]
-  .if \avg
-        vld1.8          {q8},     [r12,:128], r2
-        vrhadd.u8       q0,  q0,  q8
-        vld1.8          {q9},     [r12,:128], r2
-        vrhadd.u8       q1,  q1,  q9
-        vld1.8          {q10},    [r12,:128], r2
-        vrhadd.u8       q2,  q2,  q10
-        vld1.8          {q11},    [r12,:128], r2
-        vrhadd.u8       q3,  q3,  q11
-  .endif
-        subs            r3,  r3,  #4
-        vst1.64         {q0},     [r0,:128], r2
-        vst1.64         {q1},     [r0,:128], r2
-        vst1.64         {q2},     [r0,:128], r2
-        vst1.64         {q3},     [r0,:128], r2
-        bne             1b
-        bx              lr
-.endm
-
-.macro  pixels16_x2     rnd=1, avg=0
-1:      vld1.8          {d0-d2},  [r1], r2
-        vld1.8          {d4-d6},  [r1], r2
-        pld             [r1]
-        pld             [r1, r2]
-        subs            r3,  r3,  #2
-        vext.8          q1,  q0,  q1,  #1
-        avg             q0,  q0,  q1
-        vext.8          q3,  q2,  q3,  #1
-        avg             q2,  q2,  q3
-  .if \avg
-        vld1.8          {q1},     [r0,:128], r2
-        vld1.8          {q3},     [r0,:128]
-        vrhadd.u8       q0,  q0,  q1
-        vrhadd.u8       q2,  q2,  q3
-        sub             r0,  r0,  r2
-  .endif
-        vst1.8          {q0},     [r0,:128], r2
-        vst1.8          {q2},     [r0,:128], r2
-        bne             1b
-        bx              lr
-.endm
-
-.macro  pixels16_y2     rnd=1, avg=0
-        sub             r3,  r3,  #2
-        vld1.8          {q0},     [r1], r2
-        vld1.8          {q1},     [r1], r2
-1:      subs            r3,  r3,  #2
-        avg             q2,  q0,  q1
-        vld1.8          {q0},     [r1], r2
-        avg             q3,  q0,  q1
-        vld1.8          {q1},     [r1], r2
-        pld             [r1]
-        pld             [r1, r2]
-  .if \avg
-        vld1.8          {q8},     [r0,:128], r2
-        vld1.8          {q9},     [r0,:128]
-        vrhadd.u8       q2,  q2,  q8
-        vrhadd.u8       q3,  q3,  q9
-        sub             r0,  r0,  r2
-  .endif
-        vst1.8          {q2},     [r0,:128], r2
-        vst1.8          {q3},     [r0,:128], r2
-        bne             1b
-
-        avg             q2,  q0,  q1
-        vld1.8          {q0},     [r1], r2
-        avg             q3,  q0,  q1
-  .if \avg
-        vld1.8          {q8},     [r0,:128], r2
-        vld1.8          {q9},     [r0,:128]
-        vrhadd.u8       q2,  q2,  q8
-        vrhadd.u8       q3,  q3,  q9
-        sub             r0,  r0,  r2
-  .endif
-        vst1.8          {q2},     [r0,:128], r2
-        vst1.8          {q3},     [r0,:128], r2
-
-        bx              lr
-.endm
-
-.macro  pixels16_xy2    rnd=1, avg=0
-        sub             r3,  r3,  #2
-        vld1.8          {d0-d2},  [r1], r2
-        vld1.8          {d4-d6},  [r1], r2
-NRND    vmov.i16        q13, #1
-        pld             [r1]
-        pld             [r1, r2]
-        vext.8          q1,  q0,  q1,  #1
-        vext.8          q3,  q2,  q3,  #1
-        vaddl.u8        q8,  d0,  d2
-        vaddl.u8        q10, d1,  d3
-        vaddl.u8        q9,  d4,  d6
-        vaddl.u8        q11, d5,  d7
-1:      subs            r3,  r3,  #2
-        vld1.8          {d0-d2},  [r1], r2
-        vadd.u16        q12, q8,  q9
-        pld             [r1]
-NRND    vadd.u16        q12, q12, q13
-        vext.8          q15, q0,  q1,  #1
-        vadd.u16        q1 , q10, q11
-        shrn            d28, q12, #2
-NRND    vadd.u16        q1,  q1,  q13
-        shrn            d29, q1,  #2
-  .if \avg
-        vld1.8          {q8},     [r0,:128]
-        vrhadd.u8       q14, q14, q8
-  .endif
-        vaddl.u8        q8,  d0,  d30
-        vld1.8          {d2-d4},  [r1], r2
-        vaddl.u8        q10, d1,  d31
-        vst1.8          {q14},    [r0,:128], r2
-        vadd.u16        q12, q8,  q9
-        pld             [r1, r2]
-NRND    vadd.u16        q12, q12, q13
-        vext.8          q2,  q1,  q2,  #1
-        vadd.u16        q0,  q10, q11
-        shrn            d30, q12, #2
-NRND    vadd.u16        q0,  q0,  q13
-        shrn            d31, q0,  #2
-  .if \avg
-        vld1.8          {q9},     [r0,:128]
-        vrhadd.u8       q15, q15, q9
-  .endif
-        vaddl.u8        q9,  d2,  d4
-        vaddl.u8        q11, d3,  d5
-        vst1.8          {q15},    [r0,:128], r2
-        bgt             1b
-
-        vld1.8          {d0-d2},  [r1], r2
-        vadd.u16        q12, q8,  q9
-NRND    vadd.u16        q12, q12, q13
-        vext.8          q15, q0,  q1,  #1
-        vadd.u16        q1 , q10, q11
-        shrn            d28, q12, #2
-NRND    vadd.u16        q1,  q1,  q13
-        shrn            d29, q1,  #2
-  .if \avg
-        vld1.8          {q8},     [r0,:128]
-        vrhadd.u8       q14, q14, q8
-  .endif
-        vaddl.u8        q8,  d0,  d30
-        vaddl.u8        q10, d1,  d31
-        vst1.8          {q14},    [r0,:128], r2
-        vadd.u16        q12, q8,  q9
-NRND    vadd.u16        q12, q12, q13
-        vadd.u16        q0,  q10, q11
-        shrn            d30, q12, #2
-NRND    vadd.u16        q0,  q0,  q13
-        shrn            d31, q0,  #2
-  .if \avg
-        vld1.8          {q9},     [r0,:128]
-        vrhadd.u8       q15, q15, q9
-  .endif
-        vst1.8          {q15},    [r0,:128], r2
-
-        bx              lr
-.endm
-
-.macro  pixels8         rnd=1, avg=0
-1:      vld1.8          {d0},     [r1], r2
-        vld1.8          {d1},     [r1], r2
-        vld1.8          {d2},     [r1], r2
-        pld             [r1, r2, lsl #2]
-        vld1.8          {d3},     [r1], r2
-        pld             [r1]
-        pld             [r1, r2]
-        pld             [r1, r2, lsl #1]
-  .if \avg
-        vld1.8          {d4},     [r0,:64], r2
-        vrhadd.u8       d0,  d0,  d4
-        vld1.8          {d5},     [r0,:64], r2
-        vrhadd.u8       d1,  d1,  d5
-        vld1.8          {d6},     [r0,:64], r2
-        vrhadd.u8       d2,  d2,  d6
-        vld1.8          {d7},     [r0,:64], r2
-        vrhadd.u8       d3,  d3,  d7
-        sub             r0,  r0,  r2,  lsl #2
-  .endif
-        subs            r3,  r3,  #4
-        vst1.8          {d0},     [r0,:64], r2
-        vst1.8          {d1},     [r0,:64], r2
-        vst1.8          {d2},     [r0,:64], r2
-        vst1.8          {d3},     [r0,:64], r2
-        bne             1b
-        bx              lr
-.endm
-
-.macro  pixels8_x2      rnd=1, avg=0
-1:      vld1.8          {q0},     [r1], r2
-        vext.8          d1,  d0,  d1,  #1
-        vld1.8          {q1},     [r1], r2
-        vext.8          d3,  d2,  d3,  #1
-        pld             [r1]
-        pld             [r1, r2]
-        subs            r3,  r3,  #2
-        vswp            d1,  d2
-        avg             q0,  q0,  q1
-  .if \avg
-        vld1.8          {d4},     [r0,:64], r2
-        vld1.8          {d5},     [r0,:64]
-        vrhadd.u8       q0,  q0,  q2
-        sub             r0,  r0,  r2
-  .endif
-        vst1.8          {d0},     [r0,:64], r2
-        vst1.8          {d1},     [r0,:64], r2
-        bne             1b
-        bx              lr
-.endm
-
-.macro  pixels8_y2      rnd=1, avg=0
-        sub             r3,  r3,  #2
-        vld1.8          {d0},     [r1], r2
-        vld1.8          {d1},     [r1], r2
-1:      subs            r3,  r3,  #2
-        avg             d4,  d0,  d1
-        vld1.8          {d0},     [r1], r2
-        avg             d5,  d0,  d1
-        vld1.8          {d1},     [r1], r2
-        pld             [r1]
-        pld             [r1, r2]
-  .if \avg
-        vld1.8          {d2},     [r0,:64], r2
-        vld1.8          {d3},     [r0,:64]
-        vrhadd.u8       q2,  q2,  q1
-        sub             r0,  r0,  r2
-  .endif
-        vst1.8          {d4},     [r0,:64], r2
-        vst1.8          {d5},     [r0,:64], r2
-        bne             1b
-
-        avg             d4,  d0,  d1
-        vld1.8          {d0},     [r1], r2
-        avg             d5,  d0,  d1
-  .if \avg
-        vld1.8          {d2},     [r0,:64], r2
-        vld1.8          {d3},     [r0,:64]
-        vrhadd.u8       q2,  q2,  q1
-        sub             r0,  r0,  r2
-  .endif
-        vst1.8          {d4},     [r0,:64], r2
-        vst1.8          {d5},     [r0,:64], r2
-
-        bx              lr
-.endm
-
-.macro  pixels8_xy2     rnd=1, avg=0
-        sub             r3,  r3,  #2
-        vld1.8          {q0},     [r1], r2
-        vld1.8          {q1},     [r1], r2
-NRND    vmov.i16        q11, #1
-        pld             [r1]
-        pld             [r1, r2]
-        vext.8          d4,  d0,  d1,  #1
-        vext.8          d6,  d2,  d3,  #1
-        vaddl.u8        q8,  d0,  d4
-        vaddl.u8        q9,  d2,  d6
-1:      subs            r3,  r3,  #2
-        vld1.8          {q0},     [r1], r2
-        pld             [r1]
-        vadd.u16        q10, q8,  q9
-        vext.8          d4,  d0,  d1,  #1
-NRND    vadd.u16        q10, q10, q11
-        vaddl.u8        q8,  d0,  d4
-        shrn            d5,  q10, #2
-        vld1.8          {q1},     [r1], r2
-        vadd.u16        q10, q8,  q9
-        pld             [r1, r2]
-  .if \avg
-        vld1.8          {d7},     [r0,:64]
-        vrhadd.u8       d5,  d5,  d7
-  .endif
-NRND    vadd.u16        q10, q10, q11
-        vst1.8          {d5},     [r0,:64], r2
-        shrn            d7,  q10, #2
-  .if \avg
-        vld1.8          {d5},     [r0,:64]
-        vrhadd.u8       d7,  d7,  d5
-  .endif
-        vext.8          d6,  d2,  d3,  #1
-        vaddl.u8        q9,  d2,  d6
-        vst1.8          {d7},     [r0,:64], r2
-        bgt             1b
-
-        vld1.8          {q0},     [r1], r2
-        vadd.u16        q10, q8,  q9
-        vext.8          d4,  d0,  d1,  #1
-NRND    vadd.u16        q10, q10, q11
-        vaddl.u8        q8,  d0,  d4
-        shrn            d5,  q10, #2
-        vadd.u16        q10, q8,  q9
-  .if \avg
-        vld1.8          {d7},     [r0,:64]
-        vrhadd.u8       d5,  d5,  d7
-  .endif
-NRND    vadd.u16        q10, q10, q11
-        vst1.8          {d5},     [r0,:64], r2
-        shrn            d7,  q10, #2
-  .if \avg
-        vld1.8          {d5},     [r0,:64]
-        vrhadd.u8       d7,  d7,  d5
-  .endif
-        vst1.8          {d7},     [r0,:64], r2
-
-        bx              lr
-.endm
-
-.macro  pixfunc         pfx, name, suf, rnd=1, avg=0
-  .if \rnd
-    .macro avg  rd, rn, rm
-        vrhadd.u8       \rd, \rn, \rm
-    .endm
-    .macro shrn rd, rn, rm
-        vrshrn.u16      \rd, \rn, \rm
-    .endm
-    .macro NRND insn:vararg
-    .endm
-  .else
-    .macro avg  rd, rn, rm
-        vhadd.u8        \rd, \rn, \rm
-    .endm
-    .macro shrn rd, rn, rm
-        vshrn.u16       \rd, \rn, \rm
-    .endm
-    .macro NRND insn:vararg
-        \insn
-    .endm
-  .endif
-function ff_\pfx\name\suf\()_neon, export=1
-        \name           \rnd, \avg
-endfunc
-        .purgem         avg
-        .purgem         shrn
-        .purgem         NRND
-.endm
-
-.macro  pixfunc2        pfx, name, avg=0
-        pixfunc         \pfx, \name,          rnd=1, avg=\avg
-        pixfunc         \pfx, \name, _no_rnd, rnd=0, avg=\avg
-.endm
-
-function ff_put_h264_qpel16_mc00_neon, export=1
-        mov             r3,  #16
-endfunc
-
-        pixfunc         put_, pixels16,     avg=0
-        pixfunc2        put_, pixels16_x2,  avg=0
-        pixfunc2        put_, pixels16_y2,  avg=0
-        pixfunc2        put_, pixels16_xy2, avg=0
-
-function ff_avg_h264_qpel16_mc00_neon, export=1
-        mov             r3,  #16
-endfunc
-
-        pixfunc         avg_, pixels16,     avg=1
-        pixfunc2        avg_, pixels16_x2,  avg=1
-        pixfunc2        avg_, pixels16_y2,  avg=1
-        pixfunc2        avg_, pixels16_xy2, avg=1
-
-function ff_put_h264_qpel8_mc00_neon, export=1
-        mov             r3,  #8
-endfunc
-
-        pixfunc         put_, pixels8,     avg=0
-        pixfunc2        put_, pixels8_x2,  avg=0
-        pixfunc2        put_, pixels8_y2,  avg=0
-        pixfunc2        put_, pixels8_xy2, avg=0
-
-function ff_avg_h264_qpel8_mc00_neon, export=1
-        mov             r3,  #8
-endfunc
-
-        pixfunc         avg_, pixels8,     avg=1
-        pixfunc2        avg_, pixels8_x2,  avg=1
-        pixfunc2        avg_, pixels8_y2,  avg=1
-        pixfunc2        avg_, pixels8_xy2, avg=1
-
 function ff_put_pixels_clamped_neon, export=1
         vld1.16         {d16-d19}, [r0,:128]!
         vqmovun.s16     d0, q8
@@ -532,192 +143,6 @@ function ff_add_pixels_clamped_neon, export=1
         bx              lr
 endfunc
 
-function ff_vector_fmul_window_neon, export=1
-        push            {r4,r5,lr}
-        ldr             lr,  [sp, #12]
-        sub             r2,  r2,  #8
-        sub             r5,  lr,  #2
-        add             r2,  r2,  r5, lsl #2
-        add             r4,  r3,  r5, lsl #3
-        add             ip,  r0,  r5, lsl #3
-        mov             r5,  #-16
-        vld1.32         {d0,d1},  [r1,:128]!
-        vld1.32         {d2,d3},  [r2,:128], r5
-        vld1.32         {d4,d5},  [r3,:128]!
-        vld1.32         {d6,d7},  [r4,:128], r5
-1:      subs            lr,  lr,  #4
-        vmul.f32        d22, d0,  d4
-        vrev64.32       q3,  q3
-        vmul.f32        d23, d1,  d5
-        vrev64.32       q1,  q1
-        vmul.f32        d20, d0,  d7
-        vmul.f32        d21, d1,  d6
-        beq             2f
-        vmla.f32        d22, d3,  d7
-        vld1.32         {d0,d1},  [r1,:128]!
-        vmla.f32        d23, d2,  d6
-        vld1.32         {d18,d19},[r2,:128], r5
-        vmls.f32        d20, d3,  d4
-        vld1.32         {d24,d25},[r3,:128]!
-        vmls.f32        d21, d2,  d5
-        vld1.32         {d6,d7},  [r4,:128], r5
-        vmov            q1,  q9
-        vrev64.32       q11, q11
-        vmov            q2,  q12
-        vswp            d22, d23
-        vst1.32         {d20,d21},[r0,:128]!
-        vst1.32         {d22,d23},[ip,:128], r5
-        b               1b
-2:      vmla.f32        d22, d3,  d7
-        vmla.f32        d23, d2,  d6
-        vmls.f32        d20, d3,  d4
-        vmls.f32        d21, d2,  d5
-        vrev64.32       q11, q11
-        vswp            d22, d23
-        vst1.32         {d20,d21},[r0,:128]!
-        vst1.32         {d22,d23},[ip,:128], r5
-        pop             {r4,r5,pc}
-endfunc
-
-#if CONFIG_VORBIS_DECODER
-function ff_vorbis_inverse_coupling_neon, export=1
-        vmov.i32        q10, #1<<31
-        subs            r2,  r2,  #4
-        mov             r3,  r0
-        mov             r12, r1
-        beq             3f
-
-        vld1.32         {d24-d25},[r1,:128]!
-        vld1.32         {d22-d23},[r0,:128]!
-        vcle.s32        q8,  q12, #0
-        vand            q9,  q11, q10
-        veor            q12, q12, q9
-        vand            q2,  q12, q8
-        vbic            q3,  q12, q8
-        vadd.f32        q12, q11, q2
-        vsub.f32        q11, q11, q3
-1:      vld1.32         {d2-d3},  [r1,:128]!
-        vld1.32         {d0-d1},  [r0,:128]!
-        vcle.s32        q8,  q1,  #0
-        vand            q9,  q0,  q10
-        veor            q1,  q1,  q9
-        vst1.32         {d24-d25},[r3, :128]!
-        vst1.32         {d22-d23},[r12,:128]!
-        vand            q2,  q1,  q8
-        vbic            q3,  q1,  q8
-        vadd.f32        q1,  q0,  q2
-        vsub.f32        q0,  q0,  q3
-        subs            r2,  r2,  #8
-        ble             2f
-        vld1.32         {d24-d25},[r1,:128]!
-        vld1.32         {d22-d23},[r0,:128]!
-        vcle.s32        q8,  q12, #0
-        vand            q9,  q11, q10
-        veor            q12, q12, q9
-        vst1.32         {d2-d3},  [r3, :128]!
-        vst1.32         {d0-d1},  [r12,:128]!
-        vand            q2,  q12, q8
-        vbic            q3,  q12, q8
-        vadd.f32        q12, q11, q2
-        vsub.f32        q11, q11, q3
-        b               1b
-
-2:      vst1.32         {d2-d3},  [r3, :128]!
-        vst1.32         {d0-d1},  [r12,:128]!
-        it              lt
-        bxlt            lr
-
-3:      vld1.32         {d2-d3},  [r1,:128]
-        vld1.32         {d0-d1},  [r0,:128]
-        vcle.s32        q8,  q1,  #0
-        vand            q9,  q0,  q10
-        veor            q1,  q1,  q9
-        vand            q2,  q1,  q8
-        vbic            q3,  q1,  q8
-        vadd.f32        q1,  q0,  q2
-        vsub.f32        q0,  q0,  q3
-        vst1.32         {d2-d3},  [r0,:128]!
-        vst1.32         {d0-d1},  [r1,:128]!
-        bx              lr
-endfunc
-#endif
-
-function ff_butterflies_float_neon, export=1
-1:      vld1.32         {q0},[r0,:128]
-        vld1.32         {q1},[r1,:128]
-        vsub.f32        q2,  q0,  q1
-        vadd.f32        q1,  q0,  q1
-        vst1.32         {q2},[r1,:128]!
-        vst1.32         {q1},[r0,:128]!
-        subs            r2,  r2,  #4
-        bgt             1b
-        bx              lr
-endfunc
-
-function ff_scalarproduct_float_neon, export=1
-        vmov.f32        q2,  #0.0
-1:      vld1.32         {q0},[r0,:128]!
-        vld1.32         {q1},[r1,:128]!
-        vmla.f32        q2,  q0,  q1
-        subs            r2,  r2,  #4
-        bgt             1b
-        vadd.f32        d0,  d4,  d5
-        vpadd.f32       d0,  d0,  d0
-NOVFP   vmov.32         r0,  d0[0]
-        bx              lr
-endfunc
-
-function ff_vector_fmul_reverse_neon, export=1
-        add             r2,  r2,  r3,  lsl #2
-        sub             r2,  r2,  #32
-        mov             r12, #-32
-        vld1.32         {q0-q1},  [r1,:128]!
-        vld1.32         {q2-q3},  [r2,:128], r12
-1:      pld             [r1, #32]
-        vrev64.32       q3,  q3
-        vmul.f32        d16, d0,  d7
-        vmul.f32        d17, d1,  d6
-        pld             [r2, #-32]
-        vrev64.32       q2,  q2
-        vmul.f32        d18, d2,  d5
-        vmul.f32        d19, d3,  d4
-        subs            r3,  r3,  #8
-        beq             2f
-        vld1.32         {q0-q1},  [r1,:128]!
-        vld1.32         {q2-q3},  [r2,:128], r12
-        vst1.32         {q8-q9},  [r0,:128]!
-        b               1b
-2:      vst1.32         {q8-q9},  [r0,:128]!
-        bx              lr
-endfunc
-
-function ff_vector_fmul_add_neon, export=1
-        ldr             r12, [sp]
-        vld1.32         {q0-q1},  [r1,:128]!
-        vld1.32         {q8-q9},  [r2,:128]!
-        vld1.32         {q2-q3},  [r3,:128]!
-        vmul.f32        q10, q0,  q8
-        vmul.f32        q11, q1,  q9
-1:      vadd.f32        q12, q2,  q10
-        vadd.f32        q13, q3,  q11
-        pld             [r1, #16]
-        pld             [r2, #16]
-        pld             [r3, #16]
-        subs            r12, r12, #8
-        beq             2f
-        vld1.32         {q0},     [r1,:128]!
-        vld1.32         {q8},     [r2,:128]!
-        vmul.f32        q10, q0,  q8
-        vld1.32         {q1},     [r1,:128]!
-        vld1.32         {q9},     [r2,:128]!
-        vmul.f32        q11, q1,  q9
-        vld1.32         {q2-q3},  [r3,:128]!
-        vst1.32         {q12-q13},[r0,:128]!
-        b               1b
-2:      vst1.32         {q12-q13},[r0,:128]!
-        bx              lr
-endfunc
-
 function ff_vector_clipf_neon, export=1
 VFP     vdup.32         q1,  d0[1]
 VFP     vdup.32         q0,  d0[0]
@@ -744,29 +169,6 @@ NOVFP   ldr             r2,  [sp]
         bx              lr
 endfunc
 
-function ff_apply_window_int16_neon, export=1
-        push            {r4,lr}
-        add             r4,  r1,  r3,  lsl #1
-        add             lr,  r0,  r3,  lsl #1
-        sub             r4,  r4,  #16
-        sub             lr,  lr,  #16
-        mov             r12, #-16
-1:
-        vld1.16         {q0},     [r1,:128]!
-        vld1.16         {q2},     [r2,:128]!
-        vld1.16         {q1},     [r4,:128], r12
-        vrev64.16       q3,  q2
-        vqrdmulh.s16    q0,  q0,  q2
-        vqrdmulh.s16    d2,  d2,  d7
-        vqrdmulh.s16    d3,  d3,  d6
-        vst1.16         {q0},     [r0,:128]!
-        vst1.16         {q1},     [lr,:128], r12
-        subs            r3,  r3,  #16
-        bgt             1b
-
-        pop             {r4,pc}
-endfunc
-
 function ff_vector_clip_int32_neon, export=1
         vdup.32         q0,  r2
         vdup.32         q1,  r3
diff --git a/libavcodec/arm/dsputil_vfp.S b/libavcodec/arm/dsputil_vfp.S
deleted file mode 100644
index 9df955d..0000000
--- a/libavcodec/arm/dsputil_vfp.S
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb at users.sourceforge.net>
- *
- * 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 "libavutil/arm/asm.S"
-
-/*
- * VFP is a floating point coprocessor used in some ARM cores. VFP11 has 1 cycle
- * throughput for almost all the instructions (except for double precision
- * arithmetics), but rather high latency. Latency is 4 cycles for loads and 8 cycles
- * for arithmetic operations. Scheduling code to avoid pipeline stalls is very
- * important for performance. One more interesting feature is that VFP has
- * independent load/store and arithmetics pipelines, so it is possible to make
- * them work simultaneously and get more than 1 operation per cycle. Load/store
- * pipeline can process 2 single precision floating point values per cycle and
- * supports bulk loads and stores for large sets of registers. Arithmetic operations
- * can be done on vectors, which allows to keep the arithmetics pipeline busy,
- * while the processor may issue and execute other instructions. Detailed
- * optimization manuals can be found at http://www.arm.com
- */
-
-/**
- * ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
- * Assume that len is a positive number and is multiple of 8
- */
-@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
-@                                 const float *src1, int len)
-function ff_vector_fmul_reverse_vfp, export=1
-        vpush           {d8-d15}
-        add             r2,  r2,  r3, lsl #2
-        vldmdb          r2!, {s0-s3}
-        vldmia          r1!, {s8-s11}
-        vldmdb          r2!, {s4-s7}
-        vldmia          r1!, {s12-s15}
-        vmul.f32        s8,  s3,  s8
-        vmul.f32        s9,  s2,  s9
-        vmul.f32        s10, s1,  s10
-        vmul.f32        s11, s0,  s11
-1:
-        subs            r3,  r3,  #16
-        it              ge
-        vldmdbge        r2!, {s16-s19}
-        vmul.f32        s12, s7,  s12
-        it              ge
-        vldmiage        r1!, {s24-s27}
-        vmul.f32        s13, s6,  s13
-        it              ge
-        vldmdbge        r2!, {s20-s23}
-        vmul.f32        s14, s5,  s14
-        it              ge
-        vldmiage        r1!, {s28-s31}
-        vmul.f32        s15, s4,  s15
-        it              ge
-        vmulge.f32      s24, s19, s24
-        it              gt
-        vldmdbgt        r2!, {s0-s3}
-        it              ge
-        vmulge.f32      s25, s18, s25
-        vstmia          r0!, {s8-s13}
-        it              ge
-        vmulge.f32      s26, s17, s26
-        it              gt
-        vldmiagt        r1!, {s8-s11}
-        itt             ge
-        vmulge.f32      s27, s16, s27
-        vmulge.f32      s28, s23, s28
-        it              gt
-        vldmdbgt        r2!, {s4-s7}
-        it              ge
-        vmulge.f32      s29, s22, s29
-        vstmia          r0!, {s14-s15}
-        ittt            ge
-        vmulge.f32      s30, s21, s30
-        vmulge.f32      s31, s20, s31
-        vmulge.f32      s8,  s3,  s8
-        it              gt
-        vldmiagt        r1!, {s12-s15}
-        itttt           ge
-        vmulge.f32      s9,  s2,  s9
-        vmulge.f32      s10, s1,  s10
-        vstmiage        r0!, {s24-s27}
-        vmulge.f32      s11, s0,  s11
-        it              ge
-        vstmiage        r0!, {s28-s31}
-        bgt             1b
-
-        vpop            {d8-d15}
-        bx              lr
-endfunc
diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c
index 9ec620f..3a3d1a7 100644
--- a/libavcodec/arm/fft_init_arm.c
+++ b/libavcodec/arm/fft_init_arm.c
@@ -26,22 +26,25 @@
 void ff_fft_permute_neon(FFTContext *s, FFTComplex *z);
 void ff_fft_calc_neon(FFTContext *s, FFTComplex *z);
 
+void ff_imdct_half_vfp(FFTContext *s, FFTSample *output, const FFTSample *input);
+
 void ff_imdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_imdct_half_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_mdct_calc_neon(FFTContext *s, FFTSample *output, const FFTSample *input);
 
 void ff_rdft_calc_neon(struct RDFTContext *s, FFTSample *z);
 
-void ff_synth_filter_float_neon(FFTContext *imdct,
-                                float *synth_buf_ptr, int *synth_buf_offset,
-                                float synth_buf2[32], const float window[512],
-                                float out[32], const float in[32],
-                                float scale);
-
 av_cold void ff_fft_init_arm(FFTContext *s)
 {
     int cpu_flags = av_get_cpu_flags();
 
+    if (have_vfp(cpu_flags)) {
+#if CONFIG_MDCT
+        if (!have_vfpv3(cpu_flags))
+            s->imdct_half   = ff_imdct_half_vfp;
+#endif
+    }
+
     if (have_neon(cpu_flags)) {
         s->fft_permute  = ff_fft_permute_neon;
         s->fft_calc     = ff_fft_calc_neon;
@@ -63,13 +66,3 @@ av_cold void ff_rdft_init_arm(RDFTContext *s)
         s->rdft_calc    = ff_rdft_calc_neon;
 }
 #endif
-
-#if CONFIG_DCA_DECODER
-av_cold void ff_synth_filter_init_arm(SynthFilterContext *s)
-{
-    int cpu_flags = av_get_cpu_flags();
-
-    if (have_neon(cpu_flags))
-        s->synth_filter_float = ff_synth_filter_float_neon;
-}
-#endif
diff --git a/libavcodec/arm/fft_vfp.S b/libavcodec/arm/fft_vfp.S
new file mode 100644
index 0000000..7845ebb
--- /dev/null
+++ b/libavcodec/arm/fft_vfp.S
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison at riscosopen.org>
+ *
+ * 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/arm/asm.S"
+
+@ TODO: * FFTs wider than 16
+@       * dispatch code
+
+function fft4_vfp
+        vldr    d0, [a1, #0*2*4]   @ s0,s1   = z[0]
+        vldr    d4, [a1, #1*2*4]   @ s8,s9   = z[1]
+        vldr    d1, [a1, #2*2*4]   @ s2,s3   = z[2]
+        vldr    d5, [a1, #3*2*4]   @ s10,s11 = z[3]
+        @ stall
+        vadd.f  s12, s0, s8        @ i0
+        vadd.f  s13, s1, s9        @ i1
+        vadd.f  s14, s2, s10       @ i2
+        vadd.f  s15, s3, s11       @ i3
+        vsub.f  s8, s0, s8         @ i4
+        vsub.f  s9, s1, s9         @ i5
+        vsub.f  s10, s2, s10       @ i6
+        vsub.f  s11, s3, s11       @ i7
+        @ stall
+        @ stall
+        vadd.f  s0, s12, s14       @ z[0].re
+        vsub.f  s4, s12, s14       @ z[2].re
+        vadd.f  s1, s13, s15       @ z[0].im
+        vsub.f  s5, s13, s15       @ z[2].im
+        vadd.f  s7, s9, s10        @ z[3].im
+        vsub.f  s3, s9, s10        @ z[1].im
+        vadd.f  s2, s8, s11        @ z[1].re
+        vsub.f  s6, s8, s11        @ z[3].re
+        @ stall
+        @ stall
+        vstr    d0, [a1, #0*2*4]
+        vstr    d2, [a1, #2*2*4]
+        @ stall
+        @ stall
+        vstr    d1, [a1, #1*2*4]
+        vstr    d3, [a1, #3*2*4]
+
+        bx      lr
+endfunc
+
+.macro macro_fft8_head
+        @ FFT4
+        vldr    d4, [a1, #0 * 2*4]
+        vldr    d6, [a1, #1 * 2*4]
+        vldr    d5, [a1, #2 * 2*4]
+        vldr    d7, [a1, #3 * 2*4]
+            @ BF
+            vldr    d12, [a1, #4 * 2*4]
+        vadd.f  s16, s8, s12    @ vector op
+            vldr    d14, [a1, #5 * 2*4]
+            vldr    d13, [a1, #6 * 2*4]
+            vldr    d15, [a1, #7 * 2*4]
+        vsub.f  s20, s8, s12    @ vector op
+        vadd.f  s0, s16, s18
+        vsub.f  s2, s16, s18
+        vadd.f  s1, s17, s19
+        vsub.f  s3, s17, s19
+        vadd.f  s7, s21, s22
+        vsub.f  s5, s21, s22
+        vadd.f  s4, s20, s23
+        vsub.f  s6, s20, s23
+            vsub.f  s20, s24, s28   @ vector op
+        vstr    d0, [a1, #0 * 2*4]  @ transfer s0-s7 to s24-s31 via memory
+        vstr    d1, [a1, #1 * 2*4]
+        vldr    s0, cos1pi4
+            vadd.f  s16, s24, s28   @ vector op
+        vstr    d2, [a1, #2 * 2*4]
+        vstr    d3, [a1, #3 * 2*4]
+        vldr    d12, [a1, #0 * 2*4]
+            @ TRANSFORM
+            vmul.f  s20, s20, s0    @ vector x scalar op
+        vldr    d13, [a1, #1 * 2*4]
+        vldr    d14, [a1, #2 * 2*4]
+        vldr    d15, [a1, #3 * 2*4]
+        @ BUTTERFLIES
+        vadd.f  s0, s18, s16
+        vadd.f  s1, s17, s19
+        vsub.f  s2, s17, s19
+        vsub.f  s3, s18, s16
+            vadd.f  s4, s21, s20
+            vsub.f  s5, s21, s20
+            vadd.f  s6, s22, s23
+            vsub.f  s7, s22, s23
+        vadd.f  s8, s0, s24         @ vector op
+        vstr    d0, [a1, #0 * 2*4]  @ transfer s0-s3 to s12-s15 via memory
+        vstr    d1, [a1, #1 * 2*4]
+        vldr    d6, [a1, #0 * 2*4]
+        vldr    d7, [a1, #1 * 2*4]
+            vadd.f  s1, s5, s6
+            vadd.f  s0, s7, s4
+            vsub.f  s2, s5, s6
+            vsub.f  s3, s7, s4
+        vsub.f  s12, s24, s12       @ vector op
+            vsub.f  s5, s29, s1
+            vsub.f  s4, s28, s0
+            vsub.f  s6, s30, s2
+            vsub.f  s7, s31, s3
+            vadd.f  s16, s0, s28    @ vector op
+        vstr    d6, [a1, #4 * 2*4]
+        vstr    d7, [a1, #6 * 2*4]
+        vstr    d4, [a1, #0 * 2*4]
+        vstr    d5, [a1, #2 * 2*4]
+             vstr    d2, [a1, #5 * 2*4]
+             vstr    d3, [a1, #7 * 2*4]
+.endm
+
+.macro macro_fft8_tail
+             vstr    d8, [a1, #1 * 2*4]
+             vstr    d9, [a1, #3 * 2*4]
+.endm
+
+function fft8_vfp
+        ldr     a3, =0x03030000     @ RunFast mode, vector length 4, stride 1
+        fmrx    a2, FPSCR
+        fmxr    FPSCR, a3
+        vpush   {s16-s31}
+
+        macro_fft8_head
+        macro_fft8_tail
+
+        vpop    {s16-s31}
+        fmxr    FPSCR, a2
+        bx      lr
+endfunc
+
+.align 3
+cos1pi4:    @ cos(1*pi/4) = sqrt(2)
+        .float  0.707106769084930419921875
+cos1pi8:    @ cos(1*pi/8) = sqrt(2+sqrt(2))/2
+        .float  0.92387950420379638671875
+cos3pi8:    @ cos(2*pi/8) = sqrt(2-sqrt(2))/2
+        .float  0.3826834261417388916015625
+
+function ff_fft16_vfp, export=1
+        ldr     a3, =0x03030000     @ RunFast mode, vector length 4, stride 1
+        fmrx    a2, FPSCR
+        fmxr    FPSCR, a3
+        vpush   {s16-s31}
+
+        macro_fft8_head
+        @ FFT4(z+8)
+        vldr    d10, [a1, #8 * 2*4]
+        vldr    d12, [a1, #9 * 2*4]
+        vldr    d11, [a1, #10 * 2*4]
+        vldr    d13, [a1, #11 * 2*4]
+        macro_fft8_tail
+        vadd.f  s16, s20, s24   @ vector op
+            @ FFT4(z+12)
+            vldr    d4, [a1, #12 * 2*4]
+            vldr    d6, [a1, #13 * 2*4]
+            vldr    d5, [a1, #14 * 2*4]
+        vsub.f  s20, s20, s24   @ vector op
+            vldr    d7, [a1, #15 * 2*4]
+        vadd.f  s0, s16, s18
+        vsub.f  s4, s16, s18
+        vadd.f  s1, s17, s19
+        vsub.f  s5, s17, s19
+        vadd.f  s7, s21, s22
+        vsub.f  s3, s21, s22
+        vadd.f  s2, s20, s23
+        vsub.f  s6, s20, s23
+            vadd.f  s16, s8, s12    @ vector op
+        vstr    d0, [a1, #8 * 2*4]
+        vstr    d2, [a1, #10 * 2*4]
+        vstr    d1, [a1, #9 * 2*4]
+            vsub.f  s20, s8, s12
+        vstr    d3, [a1, #11 * 2*4]
+        @ TRANSFORM(z[2],z[6],z[10],z[14],cos1pi4,cos1pi4)
+        vldr    d12, [a1, #10 * 2*4]
+            vadd.f  s0, s16, s18
+            vadd.f  s1, s17, s19
+            vsub.f  s6, s16, s18
+            vsub.f  s7, s17, s19
+            vsub.f  s3, s21, s22
+            vadd.f  s2, s20, s23
+            vadd.f  s5, s21, s22
+            vsub.f  s4, s20, s23
+            vstr    d0, [a1, #12 * 2*4]
+        vmov    s0, s6
+          @ TRANSFORM(z[1],z[5],z[9],z[13],cos1pi8,cos3pi8)
+          vldr    d6, [a1, #9 * 2*4]
+            vstr    d1, [a1, #13 * 2*4]
+        vldr    d1, cos1pi4 @ s2 = cos1pi4, s3 = cos1pi8
+            vstr    d2, [a1, #15 * 2*4]
+          vldr    d7, [a1, #13 * 2*4]
+        vadd.f  s4, s25, s24
+        vsub.f  s5, s25, s24
+        vsub.f  s6, s0, s7
+        vadd.f  s7, s0, s7
+          vmul.f  s20, s12, s3  @ vector op
+            @ TRANSFORM(z[3],z[7],z[11],z[15],cos3pi8,cos1pi8)
+            vldr    d4, [a1, #11 * 2*4]
+            vldr    d5, [a1, #15 * 2*4]
+            vldr    s1, cos3pi8
+        vmul.f  s24, s4, s2     @ vector * scalar op
+          vmul.f  s28, s12, s1  @ vector * scalar op
+            vmul.f  s12, s8, s1 @ vector * scalar op
+          vadd.f  s4, s20, s29
+          vsub.f  s5, s21, s28
+          vsub.f  s6, s22, s31
+          vadd.f  s7, s23, s30
+            vmul.f  s8, s8, s3  @ vector * scalar op
+          vldr    d8, [a1, #1 * 2*4]
+          vldr    d9, [a1, #5 * 2*4]
+            vldr    d10, [a1, #3 * 2*4]
+            vldr    d11, [a1, #7 * 2*4]
+        vldr    d14, [a1, #2 * 2*4]
+          vadd.f  s0, s6, s4
+          vadd.f  s1, s5, s7
+          vsub.f  s2, s5, s7
+          vsub.f  s3, s6, s4
+            vadd.f  s4, s12, s9
+            vsub.f  s5, s13, s8
+            vsub.f  s6, s14, s11
+            vadd.f  s7, s15, s10
+          vadd.f  s12, s0, s16  @ vector op
+          vstr    d0, [a1, #1 * 2*4]
+          vstr    d1, [a1, #5 * 2*4]
+          vldr    d4, [a1, #1 * 2*4]
+          vldr    d5, [a1, #5 * 2*4]
+            vadd.f  s0, s6, s4
+            vadd.f  s1, s5, s7
+            vsub.f  s2, s5, s7
+            vsub.f  s3, s6, s4
+          vsub.f  s8, s16, s8   @ vector op
+          vstr    d6, [a1, #1 * 2*4]
+          vstr    d7, [a1, #5 * 2*4]
+        vldr    d15, [a1, #6 * 2*4]
+            vsub.f  s4, s20, s0
+            vsub.f  s5, s21, s1
+            vsub.f  s6, s22, s2
+            vsub.f  s7, s23, s3
+            vadd.f  s20, s0, s20    @ vector op
+          vstr    d4, [a1, #9 * 2*4]
+              @ TRANSFORM_ZERO(z[0],z[4],z[8],z[12])
+              vldr    d6, [a1, #8 * 2*4]
+          vstr    d5, [a1, #13 * 2*4]
+              vldr    d7, [a1, #12 * 2*4]
+          vstr    d2, [a1, #11 * 2*4]
+              vldr    d8, [a1, #0 * 2*4]
+          vstr    d3, [a1, #15 * 2*4]
+              vldr    d9, [a1, #4 * 2*4]
+        vadd.f  s0, s26, s24
+        vadd.f  s1, s25, s27
+        vsub.f  s2, s25, s27
+        vsub.f  s3, s26, s24
+              vadd.f  s4, s14, s12
+              vadd.f  s5, s13, s15
+              vsub.f  s6, s13, s15
+              vsub.f  s7, s14, s12
+        vadd.f  s8, s0, s28 @ vector op
+        vstr    d0, [a1, #3 * 2*4]
+        vstr    d1, [a1, #7 * 2*4]
+        vldr    d6, [a1, #3 * 2*4]
+        vldr    d7, [a1, #7 * 2*4]
+              vsub.f  s0, s16, s4
+              vsub.f  s1, s17, s5
+              vsub.f  s2, s18, s6
+              vsub.f  s3, s19, s7
+        vsub.f  s12, s28, s12       @ vector op
+              vadd.f  s16, s4, s16  @ vector op
+            vstr    d10, [a1, #3 * 2*4]
+            vstr    d11, [a1, #7 * 2*4]
+        vstr    d4, [a1, #2 * 2*4]
+        vstr    d5, [a1, #6 * 2*4]
+              vstr    d0, [a1, #8 * 2*4]
+              vstr    d1, [a1, #12 * 2*4]
+        vstr    d6, [a1, #10 * 2*4]
+        vstr    d7, [a1, #14 * 2*4]
+              vstr    d8, [a1, #0 * 2*4]
+              vstr    d9, [a1, #4 * 2*4]
+
+        vpop    {s16-s31}
+        fmxr    FPSCR, a2
+        bx      lr
+endfunc
diff --git a/libavcodec/arm/fmtconvert_init_arm.c b/libavcodec/arm/fmtconvert_init_arm.c
index 9435263..7c5bd91 100644
--- a/libavcodec/arm/fmtconvert_init_arm.c
+++ b/libavcodec/arm/fmtconvert_init_arm.c
@@ -20,24 +20,38 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/fmtconvert.h"
 
-void ff_int32_to_float_fmul_scalar_neon(float *dst, const int *src,
+void ff_int32_to_float_fmul_scalar_neon(float *dst, const int32_t *src,
                                         float mul, int len);
 
+void ff_int32_to_float_fmul_scalar_vfp(float *dst, const int32_t *src,
+                                       float mul, int len);
+void ff_int32_to_float_fmul_array8_vfp(FmtConvertContext *c, float *dst,
+                                       const int32_t *src, const float *mul,
+                                       int len);
+
 void ff_float_to_int16_neon(int16_t *dst, const float *src, long len);
 void ff_float_to_int16_interleave_neon(int16_t *, const float **, long, int);
 
 void ff_float_to_int16_vfp(int16_t *dst, const float *src, long len);
 
-void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx)
+av_cold void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx)
 {
     int cpu_flags = av_get_cpu_flags();
 
-    if (have_vfp(cpu_flags) && have_armv6(cpu_flags)) {
-        c->float_to_int16 = ff_float_to_int16_vfp;
+    if (have_vfp(cpu_flags)) {
+        if (!have_vfpv3(cpu_flags)) {
+            c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_vfp;
+            c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_vfp;
+        }
+
+        if (have_armv6(cpu_flags)) {
+            c->float_to_int16 = ff_float_to_int16_vfp;
+        }
     }
 
     if (have_neon(cpu_flags)) {
diff --git a/libavcodec/arm/fmtconvert_vfp.S b/libavcodec/arm/fmtconvert_vfp.S
index fb12de1..4e43f42 100644
--- a/libavcodec/arm/fmtconvert_vfp.S
+++ b/libavcodec/arm/fmtconvert_vfp.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Siarhei Siamashka <ssvb at users.sourceforge.net>
+ * Copyright (c) 2013 RISC OS Open Ltd <bavison at riscosopen.org>
  *
  * This file is part of Libav.
  *
@@ -22,57 +22,200 @@
 #include "libavutil/arm/asm.S"
 
 /**
- * ARM VFP optimized float to int16 conversion.
- * Assume that len is a positive number and is multiple of 8, destination
- * buffer is at least 4 bytes aligned (8 bytes alignment is better for
- * performance), little-endian byte sex.
+ * ARM VFP optimised int32 to float conversion.
+ * Assume len is a multiple of 8, destination buffer is at least 4 bytes aligned
+ * (16 bytes alignment is best for BCM2835), little-endian.
  */
-@ void ff_float_to_int16_vfp(int16_t *dst, const float *src, int len)
-function ff_float_to_int16_vfp, export=1
-        push            {r4-r8,lr}
-        vpush           {d8-d11}
-        vldmia          r1!, {s16-s23}
-        vcvt.s32.f32    s0,  s16
-        vcvt.s32.f32    s1,  s17
-        vcvt.s32.f32    s2,  s18
-        vcvt.s32.f32    s3,  s19
-        vcvt.s32.f32    s4,  s20
-        vcvt.s32.f32    s5,  s21
-        vcvt.s32.f32    s6,  s22
-        vcvt.s32.f32    s7,  s23
+@ void ff_int32_to_float_fmul_array8_vfp(FmtConvertContext *c, float *dst, const int32_t *src, const float *mul, int len)
+function ff_int32_to_float_fmul_array8_vfp, export=1
+        push    {lr}
+        ldr     a1, [sp, #4]
+        subs    lr, a1, #3*8
+        bcc     50f                        @ too short to pipeline
+        @ Now need to find (len / 8) % 3. The approximation
+        @ x / 24 = (x * 0xAB) >> 12
+        @ is good for x < 4096, which is true for both AC3 and DCA.
+        mov     a1, #0xAB
+        ldr     ip, =0x03070000            @ RunFast mode, short vectors of length 8, stride 1
+        mul     a1, lr, a1
+        vpush   {s16-s31}
+        mov     a1, a1, lsr #12
+        add     a1, a1, a1, lsl #1
+        rsb     a1, a1, lr, lsr #3
+        cmp     a1, #1
+        fmrx    a1, FPSCR
+        fmxr    FPSCR, ip
+        beq     11f
+        blo     10f
+        @ Array is (2 + multiple of 3) x 8 floats long
+        @ drop through...
+        vldmia          a3!, {s16-s23}
+        vldmia          a4!, {s2,s3}
+        vldmia          a3!, {s24-s31}
+        vcvt.f32.s32    s16, s16
+        vcvt.f32.s32    s17, s17
+        vcvt.f32.s32    s18, s18
+        vcvt.f32.s32    s19, s19
+        vcvt.f32.s32    s20, s20
+        vcvt.f32.s32    s21, s21
+        vcvt.f32.s32    s22, s22
+        vcvt.f32.s32    s23, s23
+        vmul.f32        s16, s16, s2
+        @ drop through...
+3:
+        vldmia          a3!, {s8-s15}
+        vldmia          a4!, {s1}
+        vcvt.f32.s32    s24, s24
+        vcvt.f32.s32    s25, s25
+        vcvt.f32.s32    s26, s26
+        vcvt.f32.s32    s27, s27
+        vcvt.f32.s32    s28, s28
+        vcvt.f32.s32    s29, s29
+        vcvt.f32.s32    s30, s30
+        vcvt.f32.s32    s31, s31
+        vmul.f32        s24, s24, s3
+        vstmia          a2!, {s16-s19}
+        vstmia          a2!, {s20-s23}
+2:
+        vldmia          a3!, {s16-s23}
+        vldmia          a4!, {s2}
+        vcvt.f32.s32    s8, s8
+        vcvt.f32.s32    s9, s9
+        vcvt.f32.s32    s10, s10
+        vcvt.f32.s32    s11, s11
+        vcvt.f32.s32    s12, s12
+        vcvt.f32.s32    s13, s13
+        vcvt.f32.s32    s14, s14
+        vcvt.f32.s32    s15, s15
+        vmul.f32        s8, s8, s1
+        vstmia          a2!, {s24-s27}
+        vstmia          a2!, {s28-s31}
 1:
-        subs            r2,  r2,  #8
-        vmov            r3,  r4,  s0, s1
-        vmov            r5,  r6,  s2, s3
-        vmov            r7,  r8,  s4, s5
-        vmov            ip,  lr,  s6, s7
-        it              gt
-        vldmiagt        r1!, {s16-s23}
-        ssat            r4,  #16, r4
-        ssat            r3,  #16, r3
-        ssat            r6,  #16, r6
-        ssat            r5,  #16, r5
-        pkhbt           r3,  r3,  r4, lsl #16
-        pkhbt           r4,  r5,  r6, lsl #16
-        itttt           gt
-        vcvtgt.s32.f32  s0,  s16
-        vcvtgt.s32.f32  s1,  s17
-        vcvtgt.s32.f32  s2,  s18
-        vcvtgt.s32.f32  s3,  s19
-        itttt           gt
-        vcvtgt.s32.f32  s4,  s20
-        vcvtgt.s32.f32  s5,  s21
-        vcvtgt.s32.f32  s6,  s22
-        vcvtgt.s32.f32  s7,  s23
-        ssat            r8,  #16, r8
-        ssat            r7,  #16, r7
-        ssat            lr,  #16, lr
-        ssat            ip,  #16, ip
-        pkhbt           r5,  r7,  r8, lsl #16
-        pkhbt           r6,  ip,  lr, lsl #16
-        stmia           r0!, {r3-r6}
-        bgt             1b
+        vldmia          a3!, {s24-s31}
+        vldmia          a4!, {s3}
+        vcvt.f32.s32    s16, s16
+        vcvt.f32.s32    s17, s17
+        vcvt.f32.s32    s18, s18
+        vcvt.f32.s32    s19, s19
+        vcvt.f32.s32    s20, s20
+        vcvt.f32.s32    s21, s21
+        vcvt.f32.s32    s22, s22
+        vcvt.f32.s32    s23, s23
+        vmul.f32        s16, s16, s2
+        vstmia          a2!, {s8-s11}
+        vstmia          a2!, {s12-s15}
 
-        vpop            {d8-d11}
-        pop             {r4-r8,pc}
+        subs            lr, lr, #8*3
+        bpl             3b
+
+        vcvt.f32.s32    s24, s24
+        vcvt.f32.s32    s25, s25
+        vcvt.f32.s32    s26, s26
+        vcvt.f32.s32    s27, s27
+        vcvt.f32.s32    s28, s28
+        vcvt.f32.s32    s29, s29
+        vcvt.f32.s32    s30, s30
+        vcvt.f32.s32    s31, s31
+        vmul.f32        s24, s24, s3
+        vstmia          a2!, {s16-s19}
+        vstmia          a2!, {s20-s23}
+        vstmia          a2!, {s24-s27}
+        vstmia          a2!, {s28-s31}
+
+        fmxr    FPSCR, a1
+        vpop    {s16-s31}
+        pop     {pc}
+
+10:     @ Array is (multiple of 3) x 8 floats long
+        vldmia          a3!, {s8-s15}
+        vldmia          a4!, {s1,s2}
+        vldmia          a3!, {s16-s23}
+        vcvt.f32.s32    s8, s8
+        vcvt.f32.s32    s9, s9
+        vcvt.f32.s32    s10, s10
+        vcvt.f32.s32    s11, s11
+        vcvt.f32.s32    s12, s12
+        vcvt.f32.s32    s13, s13
+        vcvt.f32.s32    s14, s14
+        vcvt.f32.s32    s15, s15
+        vmul.f32        s8, s8, s1
+        b               1b
+
+11:     @ Array is (1 + multiple of 3) x 8 floats long
+        vldmia          a3!, {s24-s31}
+        vldmia          a4!, {s3}
+        vldmia          a3!, {s8-s15}
+        vldmia          a4!, {s1}
+        vcvt.f32.s32    s24, s24
+        vcvt.f32.s32    s25, s25
+        vcvt.f32.s32    s26, s26
+        vcvt.f32.s32    s27, s27
+        vcvt.f32.s32    s28, s28
+        vcvt.f32.s32    s29, s29
+        vcvt.f32.s32    s30, s30
+        vcvt.f32.s32    s31, s31
+        vmul.f32        s24, s24, s3
+        b               2b
+
+50:
+        ldr     lr, =0x03070000         @ RunFast mode, short vectors of length 8, stride 1
+        fmrx    ip, FPSCR
+        fmxr    FPSCR, lr
+51:
+        vldmia          a3!, {s8-s15}
+        vldmia          a4!, {s0}
+        vcvt.f32.s32    s8, s8
+        vcvt.f32.s32    s9, s9
+        vcvt.f32.s32    s10, s10
+        vcvt.f32.s32    s11, s11
+        vcvt.f32.s32    s12, s12
+        vcvt.f32.s32    s13, s13
+        vcvt.f32.s32    s14, s14
+        vcvt.f32.s32    s15, s15
+        vmul.f32        s8, s8, s0
+        subs            a1, a1, #8
+        vstmia          a2!, {s8-s11}
+        vstmia          a2!, {s12-s15}
+        bne             51b
+
+        fmxr    FPSCR, ip
+        pop     {pc}
+endfunc
+
+/**
+ * ARM VFP optimised int32 to float conversion.
+ * Assume len is a multiple of 8, destination buffer is at least 4 bytes aligned
+ * (16 bytes alignment is best for BCM2835), little-endian.
+ * TODO: could be further optimised by unrolling and interleaving, as above
+ */
+@ void ff_int32_to_float_fmul_scalar_vfp(float *dst, const int32_t *src, float mul, int len)
+function ff_int32_to_float_fmul_scalar_vfp, export=1
+VFP     tmp     .req    a4
+VFP     len     .req    a3
+NOVFP   tmp     .req    a3
+NOVFP   len     .req    a4
+NOVFP   vmov    s0, a3
+        ldr     tmp, =0x03070000           @ RunFast mode, short vectors of length 8, stride 1
+        fmrx    ip, FPSCR
+        fmxr    FPSCR, tmp
+1:
+        vldmia          a2!, {s8-s15}
+        vcvt.f32.s32    s8, s8
+        vcvt.f32.s32    s9, s9
+        vcvt.f32.s32    s10, s10
+        vcvt.f32.s32    s11, s11
+        vcvt.f32.s32    s12, s12
+        vcvt.f32.s32    s13, s13
+        vcvt.f32.s32    s14, s14
+        vcvt.f32.s32    s15, s15
+        vmul.f32        s8, s8, s0
+        subs            len, len, #8
+        vstmia          a1!, {s8-s11}
+        vstmia          a1!, {s12-s15}
+        bne             1b
+
+        fmxr    FPSCR, ip
+        bx      lr
 endfunc
+        .unreq  tmp
+        .unreq  len
diff --git a/libavcodec/arm/fmtconvert_vfp.S b/libavcodec/arm/fmtconvert_vfp_armv6.S
similarity index 100%
copy from libavcodec/arm/fmtconvert_vfp.S
copy to libavcodec/arm/fmtconvert_vfp_armv6.S
diff --git a/libavcodec/arm/h264chroma_init_arm.c b/libavcodec/arm/h264chroma_init_arm.c
new file mode 100644
index 0000000..6f36553
--- /dev/null
+++ b/libavcodec/arm/h264chroma_init_arm.c
@@ -0,0 +1,51 @@
+/*
+ * ARM NEON optimised H.264 chroma functions
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.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 <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/h264chroma.h"
+
+void ff_put_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_put_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_put_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
+
+void ff_avg_h264_chroma_mc8_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_avg_h264_chroma_mc4_neon(uint8_t *, uint8_t *, int, int, int, int);
+void ff_avg_h264_chroma_mc2_neon(uint8_t *, uint8_t *, int, int, int, int);
+
+av_cold void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth)
+{
+    const int high_bit_depth = bit_depth > 8;
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_neon(cpu_flags) && !high_bit_depth) {
+        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_neon;
+        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_neon;
+        c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_neon;
+
+        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_neon;
+        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_neon;
+        c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_neon;
+    }
+}
diff --git a/libavcodec/arm/h264cmc_neon.S b/libavcodec/arm/h264cmc_neon.S
index 3427e36..15301f8 100644
--- a/libavcodec/arm/h264cmc_neon.S
+++ b/libavcodec/arm/h264cmc_neon.S
@@ -376,14 +376,12 @@ function ff_\type\()_h264_chroma_mc2_neon, export=1
 endfunc
 .endm
 
-#if CONFIG_H264_DECODER
         h264_chroma_mc8 put
         h264_chroma_mc8 avg
         h264_chroma_mc4 put
         h264_chroma_mc4 avg
         h264_chroma_mc2 put
         h264_chroma_mc2 avg
-#endif
 
 #if CONFIG_RV40_DECODER
 const   rv40bias
diff --git a/libavcodec/arm/h264dsp_armv6.S b/libavcodec/arm/h264dsp_armv6.S
new file mode 100644
index 0000000..c4f12a6
--- /dev/null
+++ b/libavcodec/arm/h264dsp_armv6.S
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison at riscosopen.org>
+ *
+ * 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/arm/asm.S"
+
+RESULT  .req    a1
+BUF     .req    a1
+SIZE    .req    a2
+PATTERN .req    a3
+PTR     .req    a4
+DAT0    .req    v1
+DAT1    .req    v2
+DAT2    .req    v3
+DAT3    .req    v4
+TMP0    .req    v5
+TMP1    .req    v6
+TMP2    .req    ip
+TMP3    .req    lr
+
+#define PRELOAD_DISTANCE 4
+
+.macro innerloop4
+        ldr     DAT0, [PTR], #4
+        subs    SIZE, SIZE, #4 @ C flag survives rest of macro
+        sub     TMP0, DAT0, PATTERN, lsr #14
+        bic     TMP0, TMP0, DAT0
+        ands    TMP0, TMP0, PATTERN
+.endm
+
+.macro innerloop16  decrement, do_preload
+        ldmia   PTR!, {DAT0,DAT1,DAT2,DAT3}
+ .ifnc "\do_preload",""
+        pld     [PTR, #PRELOAD_DISTANCE*32]
+ .endif
+ .ifnc "\decrement",""
+        subs    SIZE, SIZE, #\decrement @ C flag survives rest of macro
+ .endif
+        sub     TMP0, DAT0, PATTERN, lsr #14
+        sub     TMP1, DAT1, PATTERN, lsr #14
+        bic     TMP0, TMP0, DAT0
+        bic     TMP1, TMP1, DAT1
+        sub     TMP2, DAT2, PATTERN, lsr #14
+        sub     TMP3, DAT3, PATTERN, lsr #14
+        ands    TMP0, TMP0, PATTERN
+        bic     TMP2, TMP2, DAT2
+        it      eq
+        andseq  TMP1, TMP1, PATTERN
+        bic     TMP3, TMP3, DAT3
+        itt     eq
+        andseq  TMP2, TMP2, PATTERN
+        andseq  TMP3, TMP3, PATTERN
+.endm
+
+/* int ff_h264_find_start_code_candidate_armv6(const uint8_t *buf, int size) */
+function ff_h264_find_start_code_candidate_armv6, export=1
+        push    {v1-v6,lr}
+        mov     PTR, BUF
+        @ Ensure there are at least (PRELOAD_DISTANCE+2) complete cachelines to go
+        @ before using code that does preloads
+        cmp     SIZE, #(PRELOAD_DISTANCE+3)*32 - 1
+        blo     60f
+
+        @ Get to word-alignment, 1 byte at a time
+        tst     PTR, #3
+        beq     2f
+1:      ldrb    DAT0, [PTR], #1
+        sub     SIZE, SIZE, #1
+        teq     DAT0, #0
+        beq     90f
+        tst     PTR, #3
+        bne     1b
+2:      @ Get to 4-word alignment, 1 word at a time
+        ldr     PATTERN, =0x80008000
+        setend  be
+        tst     PTR, #12
+        beq     4f
+3:      innerloop4
+        bne     91f
+        tst     PTR, #12
+        bne     3b
+4:      @ Get to cacheline (8-word) alignment
+        tst     PTR, #16
+        beq     5f
+        innerloop16  16
+        bne     93f
+5:      @ Check complete cachelines, with preloading
+        @ We need to stop when there are still (PRELOAD_DISTANCE+1)
+        @ complete cachelines to go
+        sub     SIZE, SIZE, #(PRELOAD_DISTANCE+2)*32
+6:      innerloop16  , do_preload
+        bne     93f
+        innerloop16  32
+        bne     93f
+        bcs     6b
+        @ Preload trailing part-cacheline, if any
+        tst     SIZE, #31
+        beq     7f
+        pld     [PTR, #(PRELOAD_DISTANCE+1)*32]
+        @ Check remaining data without doing any more preloads. First
+        @ do in chunks of 4 words:
+7:      adds    SIZE, SIZE, #(PRELOAD_DISTANCE+2)*32 - 16
+        bmi     9f
+8:      innerloop16  16
+        bne     93f
+        bcs     8b
+        @ Then in words:
+9:      adds    SIZE, SIZE, #16 - 4
+        bmi     11f
+10:     innerloop4
+        bne     91f
+        bcs     10b
+11:     setend  le
+        @ Check second byte of final halfword
+        ldrb    DAT0, [PTR, #-1]
+        teq     DAT0, #0
+        beq     90f
+        @ Check any remaining bytes
+        tst     SIZE, #3
+        beq     13f
+12:     ldrb    DAT0, [PTR], #1
+        sub     SIZE, SIZE, #1
+        teq     DAT0, #0
+        beq     90f
+        tst     SIZE, #3
+        bne     12b
+        @ No candidate found
+13:     sub     RESULT, PTR, BUF
+        b       99f
+
+60:     @ Small buffer - simply check by looping over bytes
+        subs    SIZE, SIZE, #1
+        bcc     99f
+61:     ldrb    DAT0, [PTR], #1
+        subs    SIZE, SIZE, #1
+        teq     DAT0, #0
+        beq     90f
+        bcs     61b
+        @ No candidate found
+        sub     RESULT, PTR, BUF
+        b       99f
+
+90:     @ Found a candidate at the preceding byte
+        sub     RESULT, PTR, BUF
+        sub     RESULT, RESULT, #1
+        b       99f
+
+91:     @ Found a candidate somewhere in the preceding 4 bytes
+        sub     RESULT, PTR, BUF
+        sub     RESULT, RESULT, #4
+        sub     TMP0, DAT0, #0x20000
+        bics    TMP0, TMP0, DAT0
+        itt     pl
+        ldrbpl  DAT0, [PTR, #-3]
+        addpl   RESULT, RESULT, #2
+        bpl     92f
+        teq     RESULT, #0
+        beq     98f @ don't look back a byte if found at first byte in buffer
+        ldrb    DAT0, [PTR, #-5]
+92:     teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        b       98f
+
+93:     @ Found a candidate somewhere in the preceding 16 bytes
+        sub     RESULT, PTR, BUF
+        sub     RESULT, RESULT, #16
+        teq     TMP0, #0
+        beq     95f @ not in first 4 bytes
+        sub     TMP0, DAT0, #0x20000
+        bics    TMP0, TMP0, DAT0
+        itt     pl
+        ldrbpl  DAT0, [PTR, #-15]
+        addpl   RESULT, RESULT, #2
+        bpl     94f
+        teq     RESULT, #0
+        beq     98f @ don't look back a byte if found at first byte in buffer
+        ldrb    DAT0, [PTR, #-17]
+94:     teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        b       98f
+95:     add     RESULT, RESULT, #4
+        teq     TMP1, #0
+        beq     96f @ not in next 4 bytes
+        sub     TMP1, DAT1, #0x20000
+        bics    TMP1, TMP1, DAT1
+        itee    mi
+        ldrbmi  DAT0, [PTR, #-13]
+        ldrbpl  DAT0, [PTR, #-11]
+        addpl   RESULT, RESULT, #2
+        teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        b       98f
+96:     add     RESULT, RESULT, #4
+        teq     TMP2, #0
+        beq     97f @ not in next 4 bytes
+        sub     TMP2, DAT2, #0x20000
+        bics    TMP2, TMP2, DAT2
+        itee    mi
+        ldrbmi  DAT0, [PTR, #-9]
+        ldrbpl  DAT0, [PTR, #-7]
+        addpl   RESULT, RESULT, #2
+        teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        b       98f
+97:     add     RESULT, RESULT, #4
+        sub     TMP3, DAT3, #0x20000
+        bics    TMP3, TMP3, DAT3
+        itee    mi
+        ldrbmi  DAT0, [PTR, #-5]
+        ldrbpl  DAT0, [PTR, #-3]
+        addpl   RESULT, RESULT, #2
+        teq     DAT0, #0
+        it      eq
+        subeq   RESULT, RESULT, #1
+        @ drop through to 98f
+98:     setend  le
+99:     pop     {v1-v6,pc}
+.endfunc
+
+        .unreq  RESULT
+        .unreq  BUF
+        .unreq  SIZE
+        .unreq  PATTERN
+        .unreq  PTR
+        .unreq  DAT0
+        .unreq  DAT1
+        .unreq  DAT2
+        .unreq  DAT3
+        .unreq  TMP0
+        .unreq  TMP1
+        .unreq  TMP2
+        .unreq  TMP3
diff --git a/libavcodec/arm/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c
index b4277a5..b206a1b 100644
--- a/libavcodec/arm/h264dsp_init_arm.c
+++ b/libavcodec/arm/h264dsp_init_arm.c
@@ -20,10 +20,12 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/h264dsp.h"
 
+int ff_h264_find_start_code_candidate_armv6(const uint8_t *buf, int size);
+
 void ff_h264_v_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha,
                                      int beta, int8_t *tc0);
 void ff_h264_h_loop_filter_luma_neon(uint8_t *pix, int stride, int alpha,
@@ -50,25 +52,26 @@ void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, int stride,
                                     int height, int log2_den, int weightd,
                                     int weights, int offset);
 
-void ff_h264_idct_add_neon(uint8_t *dst, DCTELEM *block, int stride);
-void ff_h264_idct_dc_add_neon(uint8_t *dst, DCTELEM *block, int stride);
+void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
 void ff_h264_idct_add16_neon(uint8_t *dst, const int *block_offset,
-                             DCTELEM *block, int stride,
+                             int16_t *block, int stride,
                              const uint8_t nnzc[6*8]);
 void ff_h264_idct_add16intra_neon(uint8_t *dst, const int *block_offset,
-                                  DCTELEM *block, int stride,
+                                  int16_t *block, int stride,
                                   const uint8_t nnzc[6*8]);
 void ff_h264_idct_add8_neon(uint8_t **dest, const int *block_offset,
-                            DCTELEM *block, int stride,
+                            int16_t *block, int stride,
                             const uint8_t nnzc[6*8]);
 
-void ff_h264_idct8_add_neon(uint8_t *dst, DCTELEM *block, int stride);
-void ff_h264_idct8_dc_add_neon(uint8_t *dst, DCTELEM *block, int stride);
+void ff_h264_idct8_add_neon(uint8_t *dst, int16_t *block, int stride);
+void ff_h264_idct8_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
 void ff_h264_idct8_add4_neon(uint8_t *dst, const int *block_offset,
-                             DCTELEM *block, int stride,
+                             int16_t *block, int stride,
                              const uint8_t nnzc[6*8]);
 
-static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
+static av_cold void h264dsp_init_neon(H264DSPContext *c, const int bit_depth,
+                                      const int chroma_format_idc)
 {
     if (bit_depth == 8) {
     c->h264_v_loop_filter_luma   = ff_h264_v_loop_filter_luma_neon;
@@ -96,10 +99,13 @@ static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, const i
     }
 }
 
-void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
+av_cold void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth,
+                                 const int chroma_format_idc)
 {
     int cpu_flags = av_get_cpu_flags();
 
+    if (have_armv6(cpu_flags))
+        c->h264_find_start_code_candidate = ff_h264_find_start_code_candidate_armv6;
     if (have_neon(cpu_flags))
-        ff_h264dsp_init_neon(c, bit_depth, chroma_format_idc);
+        h264dsp_init_neon(c, bit_depth, chroma_format_idc);
 }
diff --git a/libavcodec/arm/h264dsp_neon.S b/libavcodec/arm/h264dsp_neon.S
index 9daabe0..5e75565 100644
--- a/libavcodec/arm/h264dsp_neon.S
+++ b/libavcodec/arm/h264dsp_neon.S
@@ -271,939 +271,6 @@ function ff_h264_h_loop_filter_chroma_neon, export=1
         bx              lr
 endfunc
 
-        /* H.264 qpel MC */
-
-.macro  lowpass_const   r
-        movw            \r,  #5
-        movt            \r,  #20
-        vmov.32         d6[0], \r
-.endm
-
-.macro  lowpass_8       r0,  r1,  r2,  r3,  d0,  d1,  narrow=1
-  .if \narrow
-        t0 .req q0
-        t1 .req q8
-  .else
-        t0 .req \d0
-        t1 .req \d1
-  .endif
-        vext.8          d2,  \r0, \r1, #2
-        vext.8          d3,  \r0, \r1, #3
-        vaddl.u8        q1,  d2,  d3
-        vext.8          d4,  \r0, \r1, #1
-        vext.8          d5,  \r0, \r1, #4
-        vaddl.u8        q2,  d4,  d5
-        vext.8          d30, \r0, \r1, #5
-        vaddl.u8        t0,  \r0, d30
-        vext.8          d18, \r2, \r3, #2
-        vmla.i16        t0,  q1,  d6[1]
-        vext.8          d19, \r2, \r3, #3
-        vaddl.u8        q9,  d18, d19
-        vext.8          d20, \r2, \r3, #1
-        vmls.i16        t0,  q2,  d6[0]
-        vext.8          d21, \r2, \r3, #4
-        vaddl.u8        q10, d20, d21
-        vext.8          d31, \r2, \r3, #5
-        vaddl.u8        t1,  \r2, d31
-        vmla.i16        t1,  q9,  d6[1]
-        vmls.i16        t1,  q10, d6[0]
-  .if \narrow
-        vqrshrun.s16    \d0, t0,  #5
-        vqrshrun.s16    \d1, t1,  #5
-  .endif
-        .unreq  t0
-        .unreq  t1
-.endm
-
-.macro  lowpass_8_1     r0,  r1,  d0,  narrow=1
-  .if \narrow
-        t0 .req q0
-  .else
-        t0 .req \d0
-  .endif
-        vext.8          d2,  \r0, \r1, #2
-        vext.8          d3,  \r0, \r1, #3
-        vaddl.u8        q1,  d2,  d3
-        vext.8          d4,  \r0, \r1, #1
-        vext.8          d5,  \r0, \r1, #4
-        vaddl.u8        q2,  d4,  d5
-        vext.8          d30, \r0, \r1, #5
-        vaddl.u8        t0,  \r0, d30
-        vmla.i16        t0,  q1,  d6[1]
-        vmls.i16        t0,  q2,  d6[0]
-  .if \narrow
-        vqrshrun.s16    \d0, t0,  #5
-  .endif
-        .unreq  t0
-.endm
-
-.macro  lowpass_8.16    r0,  r1,  l0,  h0,  l1,  h1,  d
-        vext.16         q1,  \r0, \r1, #2
-        vext.16         q0,  \r0, \r1, #3
-        vaddl.s16       q9,  d2,  d0
-        vext.16         q2,  \r0, \r1, #1
-        vaddl.s16       q1,  d3,  d1
-        vext.16         q3,  \r0, \r1, #4
-        vaddl.s16       q10, d4,  d6
-        vext.16         \r1, \r0, \r1, #5
-        vaddl.s16       q2,  d5,  d7
-        vaddl.s16       q0,  \h0, \h1
-        vaddl.s16       q8,  \l0, \l1
-
-        vshl.i32        q3,  q9,  #4
-        vshl.i32        q9,  q9,  #2
-        vshl.i32        q15, q10, #2
-        vadd.i32        q9,  q9,  q3
-        vadd.i32        q10, q10, q15
-
-        vshl.i32        q3,  q1,  #4
-        vshl.i32        q1,  q1,  #2
-        vshl.i32        q15, q2,  #2
-        vadd.i32        q1,  q1,  q3
-        vadd.i32        q2,  q2,  q15
-
-        vadd.i32        q9,  q9,  q8
-        vsub.i32        q9,  q9,  q10
-
-        vadd.i32        q1,  q1,  q0
-        vsub.i32        q1,  q1,  q2
-
-        vrshrn.s32      d18, q9,  #10
-        vrshrn.s32      d19, q1,  #10
-
-        vqmovun.s16     \d,  q9
-.endm
-
-function put_h264_qpel16_h_lowpass_neon_packed
-        mov             r4,  lr
-        mov             r12, #16
-        mov             r3,  #8
-        bl              put_h264_qpel8_h_lowpass_neon
-        sub             r1,  r1,  r2, lsl #4
-        add             r1,  r1,  #8
-        mov             r12, #16
-        mov             lr,  r4
-        b               put_h264_qpel8_h_lowpass_neon
-endfunc
-
-.macro  h264_qpel_h_lowpass type
-function \type\()_h264_qpel16_h_lowpass_neon
-        push            {lr}
-        mov             r12, #16
-        bl              \type\()_h264_qpel8_h_lowpass_neon
-        sub             r0,  r0,  r3, lsl #4
-        sub             r1,  r1,  r2, lsl #4
-        add             r0,  r0,  #8
-        add             r1,  r1,  #8
-        mov             r12, #16
-        pop             {lr}
-endfunc
-
-function \type\()_h264_qpel8_h_lowpass_neon
-1:      vld1.8          {d0, d1},  [r1], r2
-        vld1.8          {d16,d17}, [r1], r2
-        subs            r12, r12, #2
-        lowpass_8       d0,  d1,  d16, d17, d0,  d16
-  .ifc \type,avg
-        vld1.8          {d2},     [r0,:64], r3
-        vrhadd.u8       d0,  d0,  d2
-        vld1.8          {d3},     [r0,:64]
-        vrhadd.u8       d16, d16, d3
-        sub             r0,  r0,  r3
-  .endif
-        vst1.8          {d0},     [r0,:64], r3
-        vst1.8          {d16},    [r0,:64], r3
-        bne             1b
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel_h_lowpass put
-        h264_qpel_h_lowpass avg
-
-.macro  h264_qpel_h_lowpass_l2 type
-function \type\()_h264_qpel16_h_lowpass_l2_neon
-        push            {lr}
-        mov             r12, #16
-        bl              \type\()_h264_qpel8_h_lowpass_l2_neon
-        sub             r0,  r0,  r2, lsl #4
-        sub             r1,  r1,  r2, lsl #4
-        sub             r3,  r3,  r2, lsl #4
-        add             r0,  r0,  #8
-        add             r1,  r1,  #8
-        add             r3,  r3,  #8
-        mov             r12, #16
-        pop             {lr}
-endfunc
-
-function \type\()_h264_qpel8_h_lowpass_l2_neon
-1:      vld1.8          {d0, d1},  [r1], r2
-        vld1.8          {d16,d17}, [r1], r2
-        vld1.8          {d28},     [r3], r2
-        vld1.8          {d29},     [r3], r2
-        subs            r12, r12, #2
-        lowpass_8       d0,  d1,  d16, d17, d0,  d1
-        vrhadd.u8       q0,  q0,  q14
-  .ifc \type,avg
-        vld1.8          {d2},      [r0,:64], r2
-        vrhadd.u8       d0,  d0,  d2
-        vld1.8          {d3},      [r0,:64]
-        vrhadd.u8       d1,  d1,  d3
-        sub             r0,  r0,  r2
-  .endif
-        vst1.8          {d0},      [r0,:64], r2
-        vst1.8          {d1},      [r0,:64], r2
-        bne             1b
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel_h_lowpass_l2 put
-        h264_qpel_h_lowpass_l2 avg
-
-function put_h264_qpel16_v_lowpass_neon_packed
-        mov             r4,  lr
-        mov             r2,  #8
-        bl              put_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              put_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        bl              put_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r4
-        b               put_h264_qpel8_v_lowpass_neon
-endfunc
-
-.macro  h264_qpel_v_lowpass type
-function \type\()_h264_qpel16_v_lowpass_neon
-        mov             r4,  lr
-        bl              \type\()_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              \type\()_h264_qpel8_v_lowpass_neon
-        sub             r0,  r0,  r2, lsl #4
-        add             r0,  r0,  #8
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        bl              \type\()_h264_qpel8_v_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r4
-endfunc
-
-function \type\()_h264_qpel8_v_lowpass_neon
-        vld1.8          {d8},  [r1], r3
-        vld1.8          {d10}, [r1], r3
-        vld1.8          {d12}, [r1], r3
-        vld1.8          {d14}, [r1], r3
-        vld1.8          {d22}, [r1], r3
-        vld1.8          {d24}, [r1], r3
-        vld1.8          {d26}, [r1], r3
-        vld1.8          {d28}, [r1], r3
-        vld1.8          {d9},  [r1], r3
-        vld1.8          {d11}, [r1], r3
-        vld1.8          {d13}, [r1], r3
-        vld1.8          {d15}, [r1], r3
-        vld1.8          {d23}, [r1]
-
-        transpose_8x8   q4,  q5,  q6,  q7,  q11, q12, q13, q14
-        lowpass_8       d8,  d9,  d10, d11, d8,  d10
-        lowpass_8       d12, d13, d14, d15, d12, d14
-        lowpass_8       d22, d23, d24, d25, d22, d24
-        lowpass_8       d26, d27, d28, d29, d26, d28
-        transpose_8x8   d8,  d10, d12, d14, d22, d24, d26, d28
-
-  .ifc \type,avg
-        vld1.8          {d9},  [r0,:64], r2
-        vrhadd.u8       d8,  d8,  d9
-        vld1.8          {d11}, [r0,:64], r2
-        vrhadd.u8       d10, d10, d11
-        vld1.8          {d13}, [r0,:64], r2
-        vrhadd.u8       d12, d12, d13
-        vld1.8          {d15}, [r0,:64], r2
-        vrhadd.u8       d14, d14, d15
-        vld1.8          {d23}, [r0,:64], r2
-        vrhadd.u8       d22, d22, d23
-        vld1.8          {d25}, [r0,:64], r2
-        vrhadd.u8       d24, d24, d25
-        vld1.8          {d27}, [r0,:64], r2
-        vrhadd.u8       d26, d26, d27
-        vld1.8          {d29}, [r0,:64], r2
-        vrhadd.u8       d28, d28, d29
-        sub             r0,  r0,  r2,  lsl #3
-  .endif
-
-        vst1.8          {d8},  [r0,:64], r2
-        vst1.8          {d10}, [r0,:64], r2
-        vst1.8          {d12}, [r0,:64], r2
-        vst1.8          {d14}, [r0,:64], r2
-        vst1.8          {d22}, [r0,:64], r2
-        vst1.8          {d24}, [r0,:64], r2
-        vst1.8          {d26}, [r0,:64], r2
-        vst1.8          {d28}, [r0,:64], r2
-
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel_v_lowpass put
-        h264_qpel_v_lowpass avg
-
-.macro  h264_qpel_v_lowpass_l2 type
-function \type\()_h264_qpel16_v_lowpass_l2_neon
-        mov             r4,  lr
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        sub             r0,  r0,  r3, lsl #4
-        sub             r12, r12, r2, lsl #4
-        add             r0,  r0,  #8
-        add             r12, r12, #8
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r4
-endfunc
-
-function \type\()_h264_qpel8_v_lowpass_l2_neon
-        vld1.8          {d8},  [r1], r3
-        vld1.8          {d10}, [r1], r3
-        vld1.8          {d12}, [r1], r3
-        vld1.8          {d14}, [r1], r3
-        vld1.8          {d22}, [r1], r3
-        vld1.8          {d24}, [r1], r3
-        vld1.8          {d26}, [r1], r3
-        vld1.8          {d28}, [r1], r3
-        vld1.8          {d9},  [r1], r3
-        vld1.8          {d11}, [r1], r3
-        vld1.8          {d13}, [r1], r3
-        vld1.8          {d15}, [r1], r3
-        vld1.8          {d23}, [r1]
-
-        transpose_8x8   q4,  q5,  q6,  q7,  q11, q12, q13, q14
-        lowpass_8       d8,  d9,  d10, d11, d8,  d9
-        lowpass_8       d12, d13, d14, d15, d12, d13
-        lowpass_8       d22, d23, d24, d25, d22, d23
-        lowpass_8       d26, d27, d28, d29, d26, d27
-        transpose_8x8   d8,  d9,  d12, d13, d22, d23, d26, d27
-
-        vld1.8          {d0},  [r12], r2
-        vld1.8          {d1},  [r12], r2
-        vld1.8          {d2},  [r12], r2
-        vld1.8          {d3},  [r12], r2
-        vld1.8          {d4},  [r12], r2
-        vrhadd.u8       q0,  q0,  q4
-        vld1.8          {d5},  [r12], r2
-        vrhadd.u8       q1,  q1,  q6
-        vld1.8          {d10}, [r12], r2
-        vrhadd.u8       q2,  q2,  q11
-        vld1.8          {d11}, [r12], r2
-        vrhadd.u8       q5,  q5,  q13
-
-  .ifc \type,avg
-        vld1.8          {d16}, [r0,:64], r3
-        vrhadd.u8       d0,  d0,  d16
-        vld1.8          {d17}, [r0,:64], r3
-        vrhadd.u8       d1,  d1,  d17
-        vld1.8          {d16}, [r0,:64], r3
-        vrhadd.u8       d2,  d2,  d16
-        vld1.8          {d17}, [r0,:64], r3
-        vrhadd.u8       d3,  d3,  d17
-        vld1.8          {d16}, [r0,:64], r3
-        vrhadd.u8       d4,  d4,  d16
-        vld1.8          {d17}, [r0,:64], r3
-        vrhadd.u8       d5,  d5,  d17
-        vld1.8          {d16}, [r0,:64], r3
-        vrhadd.u8       d10, d10, d16
-        vld1.8          {d17}, [r0,:64], r3
-        vrhadd.u8       d11, d11, d17
-        sub             r0,  r0,  r3,  lsl #3
-  .endif
-
-        vst1.8          {d0},  [r0,:64], r3
-        vst1.8          {d1},  [r0,:64], r3
-        vst1.8          {d2},  [r0,:64], r3
-        vst1.8          {d3},  [r0,:64], r3
-        vst1.8          {d4},  [r0,:64], r3
-        vst1.8          {d5},  [r0,:64], r3
-        vst1.8          {d10}, [r0,:64], r3
-        vst1.8          {d11}, [r0,:64], r3
-
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel_v_lowpass_l2 put
-        h264_qpel_v_lowpass_l2 avg
-
-function put_h264_qpel8_hv_lowpass_neon_top
-        lowpass_const   r12
-        mov             r12, #12
-1:      vld1.8          {d0, d1},  [r1], r3
-        vld1.8          {d16,d17}, [r1], r3
-        subs            r12, r12, #2
-        lowpass_8       d0,  d1,  d16, d17, q11, q12, narrow=0
-        vst1.8          {d22-d25}, [r4,:128]!
-        bne             1b
-
-        vld1.8          {d0, d1},  [r1]
-        lowpass_8_1     d0,  d1,  q12, narrow=0
-
-        mov             r12, #-16
-        add             r4,  r4,  r12
-        vld1.8          {d30,d31}, [r4,:128], r12
-        vld1.8          {d20,d21}, [r4,:128], r12
-        vld1.8          {d18,d19}, [r4,:128], r12
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d14,d15}, [r4,:128], r12
-        vld1.8          {d12,d13}, [r4,:128], r12
-        vld1.8          {d10,d11}, [r4,:128], r12
-        vld1.8          {d8, d9},  [r4,:128], r12
-        vld1.8          {d6, d7},  [r4,:128], r12
-        vld1.8          {d4, d5},  [r4,:128], r12
-        vld1.8          {d2, d3},  [r4,:128], r12
-        vld1.8          {d0, d1},  [r4,:128]
-
-        swap4           d1,  d3,  d5,  d7,  d8,  d10, d12, d14
-        transpose16_4x4 q0,  q1,  q2,  q3,  q4,  q5,  q6,  q7
-
-        swap4           d17, d19, d21, d31, d24, d26, d28, d22
-        transpose16_4x4 q8,  q9,  q10, q15, q12, q13, q14, q11
-
-        vst1.8          {d30,d31}, [r4,:128]!
-        vst1.8          {d6, d7},  [r4,:128]!
-        vst1.8          {d20,d21}, [r4,:128]!
-        vst1.8          {d4, d5},  [r4,:128]!
-        vst1.8          {d18,d19}, [r4,:128]!
-        vst1.8          {d2, d3},  [r4,:128]!
-        vst1.8          {d16,d17}, [r4,:128]!
-        vst1.8          {d0, d1},  [r4,:128]
-
-        lowpass_8.16    q4,  q12, d8,  d9,  d24, d25, d8
-        lowpass_8.16    q5,  q13, d10, d11, d26, d27, d9
-        lowpass_8.16    q6,  q14, d12, d13, d28, d29, d10
-        lowpass_8.16    q7,  q11, d14, d15, d22, d23, d11
-
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d30,d31}, [r4,:128], r12
-        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d12
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d30,d31}, [r4,:128], r12
-        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d13
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d30,d31}, [r4,:128], r12
-        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d14
-        vld1.8          {d16,d17}, [r4,:128], r12
-        vld1.8          {d30,d31}, [r4,:128]
-        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d15
-
-        transpose_8x8   d12, d13, d14, d15, d8,  d9,  d10, d11
-
-        bx              lr
-endfunc
-
-.macro  h264_qpel8_hv_lowpass type
-function \type\()_h264_qpel8_hv_lowpass_neon
-        mov             r10, lr
-        bl              put_h264_qpel8_hv_lowpass_neon_top
-  .ifc \type,avg
-        vld1.8          {d0},      [r0,:64], r2
-        vrhadd.u8       d12, d12, d0
-        vld1.8          {d1},      [r0,:64], r2
-        vrhadd.u8       d13, d13, d1
-        vld1.8          {d2},      [r0,:64], r2
-        vrhadd.u8       d14, d14, d2
-        vld1.8          {d3},      [r0,:64], r2
-        vrhadd.u8       d15, d15, d3
-        vld1.8          {d4},      [r0,:64], r2
-        vrhadd.u8       d8,  d8,  d4
-        vld1.8          {d5},      [r0,:64], r2
-        vrhadd.u8       d9,  d9,  d5
-        vld1.8          {d6},      [r0,:64], r2
-        vrhadd.u8       d10, d10, d6
-        vld1.8          {d7},      [r0,:64], r2
-        vrhadd.u8       d11, d11, d7
-        sub             r0,  r0,  r2,  lsl #3
-  .endif
-
-        vst1.8          {d12},     [r0,:64], r2
-        vst1.8          {d13},     [r0,:64], r2
-        vst1.8          {d14},     [r0,:64], r2
-        vst1.8          {d15},     [r0,:64], r2
-        vst1.8          {d8},      [r0,:64], r2
-        vst1.8          {d9},      [r0,:64], r2
-        vst1.8          {d10},     [r0,:64], r2
-        vst1.8          {d11},     [r0,:64], r2
-
-        mov             lr,  r10
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel8_hv_lowpass put
-        h264_qpel8_hv_lowpass avg
-
-.macro  h264_qpel8_hv_lowpass_l2 type
-function \type\()_h264_qpel8_hv_lowpass_l2_neon
-        mov             r10, lr
-        bl              put_h264_qpel8_hv_lowpass_neon_top
-
-        vld1.8          {d0, d1},  [r2,:128]!
-        vld1.8          {d2, d3},  [r2,:128]!
-        vrhadd.u8       q0,  q0,  q6
-        vld1.8          {d4, d5},  [r2,:128]!
-        vrhadd.u8       q1,  q1,  q7
-        vld1.8          {d6, d7},  [r2,:128]!
-        vrhadd.u8       q2,  q2,  q4
-        vrhadd.u8       q3,  q3,  q5
-  .ifc \type,avg
-        vld1.8          {d16},     [r0,:64], r3
-        vrhadd.u8       d0,  d0,  d16
-        vld1.8          {d17},     [r0,:64], r3
-        vrhadd.u8       d1,  d1,  d17
-        vld1.8          {d18},     [r0,:64], r3
-        vrhadd.u8       d2,  d2,  d18
-        vld1.8          {d19},     [r0,:64], r3
-        vrhadd.u8       d3,  d3,  d19
-        vld1.8          {d20},     [r0,:64], r3
-        vrhadd.u8       d4,  d4,  d20
-        vld1.8          {d21},     [r0,:64], r3
-        vrhadd.u8       d5,  d5,  d21
-        vld1.8          {d22},     [r0,:64], r3
-        vrhadd.u8       d6,  d6,  d22
-        vld1.8          {d23},     [r0,:64], r3
-        vrhadd.u8       d7,  d7,  d23
-        sub             r0,  r0,  r3,  lsl #3
-  .endif
-        vst1.8          {d0},      [r0,:64], r3
-        vst1.8          {d1},      [r0,:64], r3
-        vst1.8          {d2},      [r0,:64], r3
-        vst1.8          {d3},      [r0,:64], r3
-        vst1.8          {d4},      [r0,:64], r3
-        vst1.8          {d5},      [r0,:64], r3
-        vst1.8          {d6},      [r0,:64], r3
-        vst1.8          {d7},      [r0,:64], r3
-
-        mov             lr,  r10
-        bx              lr
-endfunc
-.endm
-
-        h264_qpel8_hv_lowpass_l2 put
-        h264_qpel8_hv_lowpass_l2 avg
-
-.macro  h264_qpel16_hv  type
-function \type\()_h264_qpel16_hv_lowpass_neon
-        mov             r9,  lr
-        bl              \type\()_h264_qpel8_hv_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              \type\()_h264_qpel8_hv_lowpass_neon
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        sub             r0,  r0,  r2, lsl #4
-        add             r0,  r0,  #8
-        bl              \type\()_h264_qpel8_hv_lowpass_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r9
-        b               \type\()_h264_qpel8_hv_lowpass_neon
-endfunc
-
-function \type\()_h264_qpel16_hv_lowpass_l2_neon
-        mov             r9,  lr
-        sub             r2,  r4,  #256
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #2
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #4
-        sub             r1,  r1,  r3, lsl #2
-        add             r1,  r1,  #8
-        sub             r0,  r0,  r3, lsl #4
-        add             r0,  r0,  #8
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        sub             r1,  r1,  r3, lsl #2
-        mov             lr,  r9
-        b               \type\()_h264_qpel8_hv_lowpass_l2_neon
-endfunc
-.endm
-
-        h264_qpel16_hv put
-        h264_qpel16_hv avg
-
-.macro  h264_qpel8      type
-function ff_\type\()_h264_qpel8_mc10_neon, export=1
-        lowpass_const   r3
-        mov             r3,  r1
-        sub             r1,  r1,  #2
-        mov             r12, #8
-        b               \type\()_h264_qpel8_h_lowpass_l2_neon
-endfunc
-
-function ff_\type\()_h264_qpel8_mc20_neon, export=1
-        lowpass_const   r3
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        mov             r12, #8
-        b               \type\()_h264_qpel8_h_lowpass_neon
-endfunc
-
-function ff_\type\()_h264_qpel8_mc30_neon, export=1
-        lowpass_const   r3
-        add             r3,  r1,  #1
-        sub             r1,  r1,  #2
-        mov             r12, #8
-        b               \type\()_h264_qpel8_h_lowpass_l2_neon
-endfunc
-
-function ff_\type\()_h264_qpel8_mc01_neon, export=1
-        push            {lr}
-        mov             r12, r1
-\type\()_h264_qpel8_mc01:
-        lowpass_const   r3
-        mov             r3,  r2
-        sub             r1,  r1,  r2, lsl #1
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        vpop            {d8-d15}
-        pop             {pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc11_neon, export=1
-        push            {r0, r1, r11, lr}
-\type\()_h264_qpel8_mc11:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #64
-        mov             r0,  sp
-        sub             r1,  r1,  #2
-        mov             r3,  #8
-        mov             r12, #8
-        vpush           {d8-d15}
-        bl              put_h264_qpel8_h_lowpass_neon
-        ldrd            r0,  r1,  [r11], #8
-        mov             r3,  r2
-        add             r12, sp,  #64
-        sub             r1,  r1,  r2, lsl #1
-        mov             r2,  #8
-        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc21_neon, export=1
-        push            {r0, r1, r4, r10, r11, lr}
-\type\()_h264_qpel8_mc21:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #(8*8+16*12)
-        sub             r1,  r1,  #2
-        mov             r3,  #8
-        mov             r0,  sp
-        mov             r12, #8
-        vpush           {d8-d15}
-        bl              put_h264_qpel8_h_lowpass_neon
-        mov             r4,  r0
-        ldrd            r0,  r1,  [r11], #8
-        sub             r1,  r1,  r2, lsl #1
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        sub             r2,  r4,  #64
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r10, r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc31_neon, export=1
-        add             r1,  r1,  #1
-        push            {r0, r1, r11, lr}
-        sub             r1,  r1,  #1
-        b               \type\()_h264_qpel8_mc11
-endfunc
-
-function ff_\type\()_h264_qpel8_mc02_neon, export=1
-        push            {lr}
-        lowpass_const   r3
-        sub             r1,  r1,  r2, lsl #1
-        mov             r3,  r2
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel8_v_lowpass_neon
-        vpop            {d8-d15}
-        pop             {pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc12_neon, export=1
-        push            {r0, r1, r4, r10, r11, lr}
-\type\()_h264_qpel8_mc12:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #(8*8+16*12)
-        sub             r1,  r1,  r2, lsl #1
-        mov             r3,  r2
-        mov             r2,  #8
-        mov             r0,  sp
-        vpush           {d8-d15}
-        bl              put_h264_qpel8_v_lowpass_neon
-        mov             r4,  r0
-        ldrd            r0,  r1,  [r11], #8
-        sub             r1,  r1,  r3, lsl #1
-        sub             r1,  r1,  #2
-        sub             r2,  r4,  #64
-        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r10, r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc22_neon, export=1
-        push            {r4, r10, r11, lr}
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r4,  r11, #15
-T       mov             sp,  r4
-        sub             r1,  r1,  r2, lsl #1
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        sub             sp,  sp,  #(16*12)
-        mov             r4,  sp
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel8_hv_lowpass_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r10, r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel8_mc32_neon, export=1
-        push            {r0, r1, r4, r10, r11, lr}
-        add             r1,  r1,  #1
-        b               \type\()_h264_qpel8_mc12
-endfunc
-
-function ff_\type\()_h264_qpel8_mc03_neon, export=1
-        push            {lr}
-        add             r12, r1,  r2
-        b               \type\()_h264_qpel8_mc01
-endfunc
-
-function ff_\type\()_h264_qpel8_mc13_neon, export=1
-        push            {r0, r1, r11, lr}
-        add             r1,  r1,  r2
-        b               \type\()_h264_qpel8_mc11
-endfunc
-
-function ff_\type\()_h264_qpel8_mc23_neon, export=1
-        push            {r0, r1, r4, r10, r11, lr}
-        add             r1,  r1,  r2
-        b               \type\()_h264_qpel8_mc21
-endfunc
-
-function ff_\type\()_h264_qpel8_mc33_neon, export=1
-        add             r1,  r1,  #1
-        push            {r0, r1, r11, lr}
-        add             r1,  r1,  r2
-        sub             r1,  r1,  #1
-        b               \type\()_h264_qpel8_mc11
-endfunc
-.endm
-
-        h264_qpel8 put
-        h264_qpel8 avg
-
-.macro  h264_qpel16     type
-function ff_\type\()_h264_qpel16_mc10_neon, export=1
-        lowpass_const   r3
-        mov             r3,  r1
-        sub             r1,  r1,  #2
-        b               \type\()_h264_qpel16_h_lowpass_l2_neon
-endfunc
-
-function ff_\type\()_h264_qpel16_mc20_neon, export=1
-        lowpass_const   r3
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        b               \type\()_h264_qpel16_h_lowpass_neon
-endfunc
-
-function ff_\type\()_h264_qpel16_mc30_neon, export=1
-        lowpass_const   r3
-        add             r3,  r1,  #1
-        sub             r1,  r1,  #2
-        b               \type\()_h264_qpel16_h_lowpass_l2_neon
-endfunc
-
-function ff_\type\()_h264_qpel16_mc01_neon, export=1
-        push            {r4, lr}
-        mov             r12, r1
-\type\()_h264_qpel16_mc01:
-        lowpass_const   r3
-        mov             r3,  r2
-        sub             r1,  r1,  r2, lsl #1
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel16_v_lowpass_l2_neon
-        vpop            {d8-d15}
-        pop             {r4, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc11_neon, export=1
-        push            {r0, r1, r4, r11, lr}
-\type\()_h264_qpel16_mc11:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #256
-        mov             r0,  sp
-        sub             r1,  r1,  #2
-        mov             r3,  #16
-        vpush           {d8-d15}
-        bl              put_h264_qpel16_h_lowpass_neon
-        ldrd            r0,  r1,  [r11], #8
-        mov             r3,  r2
-        add             r12, sp,  #64
-        sub             r1,  r1,  r2, lsl #1
-        mov             r2,  #16
-        bl              \type\()_h264_qpel16_v_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc21_neon, export=1
-        push            {r0, r1, r4-r5, r9-r11, lr}
-\type\()_h264_qpel16_mc21:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #(16*16+16*12)
-        sub             r1,  r1,  #2
-        mov             r0,  sp
-        vpush           {d8-d15}
-        bl              put_h264_qpel16_h_lowpass_neon_packed
-        mov             r4,  r0
-        ldrd            r0,  r1,  [r11], #8
-        sub             r1,  r1,  r2, lsl #1
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        bl              \type\()_h264_qpel16_hv_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4-r5, r9-r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc31_neon, export=1
-        add             r1,  r1,  #1
-        push            {r0, r1, r4, r11, lr}
-        sub             r1,  r1,  #1
-        b               \type\()_h264_qpel16_mc11
-endfunc
-
-function ff_\type\()_h264_qpel16_mc02_neon, export=1
-        push            {r4, lr}
-        lowpass_const   r3
-        sub             r1,  r1,  r2, lsl #1
-        mov             r3,  r2
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel16_v_lowpass_neon
-        vpop            {d8-d15}
-        pop             {r4, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc12_neon, export=1
-        push            {r0, r1, r4-r5, r9-r11, lr}
-\type\()_h264_qpel16_mc12:
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r0,  r11, #15
-T       mov             sp,  r0
-        sub             sp,  sp,  #(16*16+16*12)
-        sub             r1,  r1,  r2, lsl #1
-        mov             r0,  sp
-        mov             r3,  r2
-        vpush           {d8-d15}
-        bl              put_h264_qpel16_v_lowpass_neon_packed
-        mov             r4,  r0
-        ldrd            r0,  r1,  [r11], #8
-        sub             r1,  r1,  r3, lsl #1
-        sub             r1,  r1,  #2
-        mov             r2,  r3
-        bl              \type\()_h264_qpel16_hv_lowpass_l2_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4-r5, r9-r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc22_neon, export=1
-        push            {r4, r9-r11, lr}
-        lowpass_const   r3
-        mov             r11, sp
-A       bic             sp,  sp,  #15
-T       bic             r4,  r11, #15
-T       mov             sp,  r4
-        sub             r1,  r1,  r2, lsl #1
-        sub             r1,  r1,  #2
-        mov             r3,  r2
-        sub             sp,  sp,  #(16*12)
-        mov             r4,  sp
-        vpush           {d8-d15}
-        bl              \type\()_h264_qpel16_hv_lowpass_neon
-        vpop            {d8-d15}
-        mov             sp,  r11
-        pop             {r4, r9-r11, pc}
-endfunc
-
-function ff_\type\()_h264_qpel16_mc32_neon, export=1
-        push            {r0, r1, r4-r5, r9-r11, lr}
-        add             r1,  r1,  #1
-        b               \type\()_h264_qpel16_mc12
-endfunc
-
-function ff_\type\()_h264_qpel16_mc03_neon, export=1
-        push            {r4, lr}
-        add             r12, r1,  r2
-        b               \type\()_h264_qpel16_mc01
-endfunc
-
-function ff_\type\()_h264_qpel16_mc13_neon, export=1
-        push            {r0, r1, r4, r11, lr}
-        add             r1,  r1,  r2
-        b               \type\()_h264_qpel16_mc11
-endfunc
-
-function ff_\type\()_h264_qpel16_mc23_neon, export=1
-        push            {r0, r1, r4-r5, r9-r11, lr}
-        add             r1,  r1,  r2
-        b               \type\()_h264_qpel16_mc21
-endfunc
-
-function ff_\type\()_h264_qpel16_mc33_neon, export=1
-        add             r1,  r1,  #1
-        push            {r0, r1, r4, r11, lr}
-        add             r1,  r1,  r2
-        sub             r1,  r1,  #1
-        b               \type\()_h264_qpel16_mc11
-endfunc
-.endm
-
-        h264_qpel16 put
-        h264_qpel16 avg
-
 @ Biweighted prediction
 
 .macro  biweight_16     macs, macd
diff --git a/libavcodec/arm/h264idct_neon.S b/libavcodec/arm/h264idct_neon.S
index b23ddb1..3e5321c 100644
--- a/libavcodec/arm/h264idct_neon.S
+++ b/libavcodec/arm/h264idct_neon.S
@@ -22,9 +22,12 @@
 
 function ff_h264_idct_add_neon, export=1
         vld1.64         {d0-d3},  [r1,:128]
+        vmov.i16        q15, #0
 
         vswp            d1,  d2
+        vst1.16         {q15},    [r1,:128]!
         vadd.i16        d4,  d0,  d1
+        vst1.16         {q15},    [r1,:128]!
         vshr.s16        q8,  q1,  #1
         vsub.i16        d5,  d0,  d1
         vadd.i16        d6,  d2,  d17
@@ -65,11 +68,14 @@ function ff_h264_idct_add_neon, export=1
         vst1.32         {d0[1]},  [r0,:32], r2
         vst1.32         {d1[0]},  [r0,:32], r2
 
+        sub             r1,  r1,  #32
         bx              lr
 endfunc
 
 function ff_h264_idct_dc_add_neon, export=1
+        mov             r3,       #0
         vld1.16         {d2[],d3[]}, [r1,:16]
+        strh            r3,       [r1]
         vrshr.s16       q1,  q1,  #6
         vld1.32         {d0[0]},  [r0,:32], r2
         vld1.32         {d0[1]},  [r0,:32], r2
@@ -148,7 +154,7 @@ function ff_h264_idct_add8_neon, export=1
         add             r5,  r1,  #16*4
         add             r1,  r2,  #16*32
         mov             r2,  r3
-        mov             r3,  r1
+        mov             r10, r1
         ldr             r6,  [sp, #32]
         movrel          r7,  scan8+16
         mov             r12, #0
@@ -156,7 +162,7 @@ function ff_h264_idct_add8_neon, export=1
         ldr             r0,  [r5, r12, lsl #2]
         ldrb            r8,  [r6, r8]
         add             r0,  r0,  r4
-        add             r1,  r3,  r12, lsl #5
+        add             r1,  r10, r12, lsl #5
         cmp             r8,  #0
         ldrsh           r8,  [r1]
         iteet           ne
@@ -180,7 +186,9 @@ endfunc
         qb      .req    q14
         vshr.s16        q2,  q10, #1
         vadd.i16        q0,  q8,  q12
-        vld1.16         {q14-q15},[r1,:128]!
+        vld1.16         {q14-q15},[r1,:128]
+        vst1.16         {q3},     [r1,:128]!
+        vst1.16         {q3},     [r1,:128]!
         vsub.i16        q1,  q8,  q12
         vshr.s16        q3,  q14, #1
         vsub.i16        q2,  q2,  q14
@@ -259,9 +267,16 @@ endfunc
 .endm
 
 function ff_h264_idct8_add_neon, export=1
-        vld1.16         {q8-q9},  [r1,:128]!
-        vld1.16         {q10-q11},[r1,:128]!
-        vld1.16         {q12-q13},[r1,:128]!
+        vmov.i16        q3,       #0
+        vld1.16         {q8-q9},  [r1,:128]
+        vst1.16         {q3},     [r1,:128]!
+        vst1.16         {q3},     [r1,:128]!
+        vld1.16         {q10-q11},[r1,:128]
+        vst1.16         {q3},     [r1,:128]!
+        vst1.16         {q3},     [r1,:128]!
+        vld1.16         {q12-q13},[r1,:128]
+        vst1.16         {q3},     [r1,:128]!
+        vst1.16         {q3},     [r1,:128]!
 
         idct8x8_cols    0
         idct8x8_cols    1
@@ -313,7 +328,9 @@ function ff_h264_idct8_add_neon, export=1
 endfunc
 
 function ff_h264_idct8_dc_add_neon, export=1
+        mov             r3,       #0
         vld1.16         {d30[],d31[]},[r1,:16]
+        strh            r3,       [r1]
         vld1.32         {d0},     [r0,:64], r2
         vrshr.s16       q15, q15, #6
         vld1.32         {d1},     [r0,:64], r2
diff --git a/libavcodec/arm/h264pred_init_arm.c b/libavcodec/arm/h264pred_init_arm.c
index 39c0121..2e25c2a 100644
--- a/libavcodec/arm/h264pred_init_arm.c
+++ b/libavcodec/arm/h264pred_init_arm.c
@@ -20,7 +20,9 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
+#include "libavcodec/avcodec.h"
 #include "libavcodec/h264pred.h"
 
 void ff_pred16x16_vert_neon(uint8_t *src, ptrdiff_t stride);
@@ -43,7 +45,9 @@ void ff_pred8x8_0lt_dc_neon(uint8_t *src, ptrdiff_t stride);
 void ff_pred8x8_l00_dc_neon(uint8_t *src, ptrdiff_t stride);
 void ff_pred8x8_0l0_dc_neon(uint8_t *src, ptrdiff_t stride);
 
-static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc)
+static av_cold void h264_pred_init_neon(H264PredContext *h, int codec_id,
+                                        const int bit_depth,
+                                        const int chroma_format_idc)
 {
     const int high_depth = bit_depth > 8;
 
@@ -75,10 +79,11 @@ static void ff_h264_pred_init_neon(H264PredContext *h, int codec_id, const int b
         h->pred16x16[PLANE_PRED8x8  ] = ff_pred16x16_plane_neon;
 }
 
-void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, int bit_depth, const int chroma_format_idc)
+av_cold void ff_h264_pred_init_arm(H264PredContext *h, int codec_id,
+                                   int bit_depth, const int chroma_format_idc)
 {
     int cpu_flags = av_get_cpu_flags();
 
     if (have_neon(cpu_flags))
-        ff_h264_pred_init_neon(h, codec_id, bit_depth, chroma_format_idc);
+        h264_pred_init_neon(h, codec_id, bit_depth, chroma_format_idc);
 }
diff --git a/libavcodec/arm/h264qpel_init_arm.c b/libavcodec/arm/h264qpel_init_arm.c
new file mode 100644
index 0000000..a232689
--- /dev/null
+++ b/libavcodec/arm/h264qpel_init_arm.c
@@ -0,0 +1,171 @@
+/*
+ * ARM NEON optimised DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.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 <stdint.h>
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/h264qpel.h"
+
+void ff_put_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, ptrdiff_t);
+
+void ff_put_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_put_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, ptrdiff_t);
+
+void ff_avg_h264_qpel16_mc00_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc10_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc20_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc30_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc01_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc11_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc21_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc31_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc02_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc12_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc22_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc32_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc03_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc13_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc23_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel16_mc33_neon(uint8_t *, uint8_t *, ptrdiff_t);
+
+void ff_avg_h264_qpel8_mc00_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc10_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc20_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc30_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc01_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc11_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc21_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc31_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc02_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc12_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc22_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc32_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc03_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc13_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc23_neon(uint8_t *, uint8_t *, ptrdiff_t);
+void ff_avg_h264_qpel8_mc33_neon(uint8_t *, uint8_t *, ptrdiff_t);
+
+av_cold void ff_h264qpel_init_arm(H264QpelContext *c, int bit_depth)
+{
+    const int high_bit_depth = bit_depth > 8;
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_neon(cpu_flags) && !high_bit_depth) {
+        c->put_h264_qpel_pixels_tab[0][ 0] = ff_put_h264_qpel16_mc00_neon;
+        c->put_h264_qpel_pixels_tab[0][ 1] = ff_put_h264_qpel16_mc10_neon;
+        c->put_h264_qpel_pixels_tab[0][ 2] = ff_put_h264_qpel16_mc20_neon;
+        c->put_h264_qpel_pixels_tab[0][ 3] = ff_put_h264_qpel16_mc30_neon;
+        c->put_h264_qpel_pixels_tab[0][ 4] = ff_put_h264_qpel16_mc01_neon;
+        c->put_h264_qpel_pixels_tab[0][ 5] = ff_put_h264_qpel16_mc11_neon;
+        c->put_h264_qpel_pixels_tab[0][ 6] = ff_put_h264_qpel16_mc21_neon;
+        c->put_h264_qpel_pixels_tab[0][ 7] = ff_put_h264_qpel16_mc31_neon;
+        c->put_h264_qpel_pixels_tab[0][ 8] = ff_put_h264_qpel16_mc02_neon;
+        c->put_h264_qpel_pixels_tab[0][ 9] = ff_put_h264_qpel16_mc12_neon;
+        c->put_h264_qpel_pixels_tab[0][10] = ff_put_h264_qpel16_mc22_neon;
+        c->put_h264_qpel_pixels_tab[0][11] = ff_put_h264_qpel16_mc32_neon;
+        c->put_h264_qpel_pixels_tab[0][12] = ff_put_h264_qpel16_mc03_neon;
+        c->put_h264_qpel_pixels_tab[0][13] = ff_put_h264_qpel16_mc13_neon;
+        c->put_h264_qpel_pixels_tab[0][14] = ff_put_h264_qpel16_mc23_neon;
+        c->put_h264_qpel_pixels_tab[0][15] = ff_put_h264_qpel16_mc33_neon;
+
+        c->put_h264_qpel_pixels_tab[1][ 0] = ff_put_h264_qpel8_mc00_neon;
+        c->put_h264_qpel_pixels_tab[1][ 1] = ff_put_h264_qpel8_mc10_neon;
+        c->put_h264_qpel_pixels_tab[1][ 2] = ff_put_h264_qpel8_mc20_neon;
+        c->put_h264_qpel_pixels_tab[1][ 3] = ff_put_h264_qpel8_mc30_neon;
+        c->put_h264_qpel_pixels_tab[1][ 4] = ff_put_h264_qpel8_mc01_neon;
+        c->put_h264_qpel_pixels_tab[1][ 5] = ff_put_h264_qpel8_mc11_neon;
+        c->put_h264_qpel_pixels_tab[1][ 6] = ff_put_h264_qpel8_mc21_neon;
+        c->put_h264_qpel_pixels_tab[1][ 7] = ff_put_h264_qpel8_mc31_neon;
+        c->put_h264_qpel_pixels_tab[1][ 8] = ff_put_h264_qpel8_mc02_neon;
+        c->put_h264_qpel_pixels_tab[1][ 9] = ff_put_h264_qpel8_mc12_neon;
+        c->put_h264_qpel_pixels_tab[1][10] = ff_put_h264_qpel8_mc22_neon;
+        c->put_h264_qpel_pixels_tab[1][11] = ff_put_h264_qpel8_mc32_neon;
+        c->put_h264_qpel_pixels_tab[1][12] = ff_put_h264_qpel8_mc03_neon;
+        c->put_h264_qpel_pixels_tab[1][13] = ff_put_h264_qpel8_mc13_neon;
+        c->put_h264_qpel_pixels_tab[1][14] = ff_put_h264_qpel8_mc23_neon;
+        c->put_h264_qpel_pixels_tab[1][15] = ff_put_h264_qpel8_mc33_neon;
+
+        c->avg_h264_qpel_pixels_tab[0][ 0] = ff_avg_h264_qpel16_mc00_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 1] = ff_avg_h264_qpel16_mc10_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 2] = ff_avg_h264_qpel16_mc20_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 3] = ff_avg_h264_qpel16_mc30_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 4] = ff_avg_h264_qpel16_mc01_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 5] = ff_avg_h264_qpel16_mc11_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 6] = ff_avg_h264_qpel16_mc21_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 7] = ff_avg_h264_qpel16_mc31_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 8] = ff_avg_h264_qpel16_mc02_neon;
+        c->avg_h264_qpel_pixels_tab[0][ 9] = ff_avg_h264_qpel16_mc12_neon;
+        c->avg_h264_qpel_pixels_tab[0][10] = ff_avg_h264_qpel16_mc22_neon;
+        c->avg_h264_qpel_pixels_tab[0][11] = ff_avg_h264_qpel16_mc32_neon;
+        c->avg_h264_qpel_pixels_tab[0][12] = ff_avg_h264_qpel16_mc03_neon;
+        c->avg_h264_qpel_pixels_tab[0][13] = ff_avg_h264_qpel16_mc13_neon;
+        c->avg_h264_qpel_pixels_tab[0][14] = ff_avg_h264_qpel16_mc23_neon;
+        c->avg_h264_qpel_pixels_tab[0][15] = ff_avg_h264_qpel16_mc33_neon;
+
+        c->avg_h264_qpel_pixels_tab[1][ 0] = ff_avg_h264_qpel8_mc00_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 1] = ff_avg_h264_qpel8_mc10_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 2] = ff_avg_h264_qpel8_mc20_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 3] = ff_avg_h264_qpel8_mc30_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 4] = ff_avg_h264_qpel8_mc01_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 5] = ff_avg_h264_qpel8_mc11_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 6] = ff_avg_h264_qpel8_mc21_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 7] = ff_avg_h264_qpel8_mc31_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 8] = ff_avg_h264_qpel8_mc02_neon;
+        c->avg_h264_qpel_pixels_tab[1][ 9] = ff_avg_h264_qpel8_mc12_neon;
+        c->avg_h264_qpel_pixels_tab[1][10] = ff_avg_h264_qpel8_mc22_neon;
+        c->avg_h264_qpel_pixels_tab[1][11] = ff_avg_h264_qpel8_mc32_neon;
+        c->avg_h264_qpel_pixels_tab[1][12] = ff_avg_h264_qpel8_mc03_neon;
+        c->avg_h264_qpel_pixels_tab[1][13] = ff_avg_h264_qpel8_mc13_neon;
+        c->avg_h264_qpel_pixels_tab[1][14] = ff_avg_h264_qpel8_mc23_neon;
+        c->avg_h264_qpel_pixels_tab[1][15] = ff_avg_h264_qpel8_mc33_neon;
+    }
+}
diff --git a/libavcodec/arm/h264qpel_neon.S b/libavcodec/arm/h264qpel_neon.S
new file mode 100644
index 0000000..6c51250
--- /dev/null
+++ b/libavcodec/arm/h264qpel_neon.S
@@ -0,0 +1,955 @@
+/*
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.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/arm/asm.S"
+#include "neon.S"
+
+        /* H.264 qpel MC */
+
+.macro  lowpass_const   r
+        movw            \r,  #5
+        movt            \r,  #20
+        vmov.32         d6[0], \r
+.endm
+
+.macro  lowpass_8       r0,  r1,  r2,  r3,  d0,  d1,  narrow=1
+  .if \narrow
+        t0 .req q0
+        t1 .req q8
+  .else
+        t0 .req \d0
+        t1 .req \d1
+  .endif
+        vext.8          d2,  \r0, \r1, #2
+        vext.8          d3,  \r0, \r1, #3
+        vaddl.u8        q1,  d2,  d3
+        vext.8          d4,  \r0, \r1, #1
+        vext.8          d5,  \r0, \r1, #4
+        vaddl.u8        q2,  d4,  d5
+        vext.8          d30, \r0, \r1, #5
+        vaddl.u8        t0,  \r0, d30
+        vext.8          d18, \r2, \r3, #2
+        vmla.i16        t0,  q1,  d6[1]
+        vext.8          d19, \r2, \r3, #3
+        vaddl.u8        q9,  d18, d19
+        vext.8          d20, \r2, \r3, #1
+        vmls.i16        t0,  q2,  d6[0]
+        vext.8          d21, \r2, \r3, #4
+        vaddl.u8        q10, d20, d21
+        vext.8          d31, \r2, \r3, #5
+        vaddl.u8        t1,  \r2, d31
+        vmla.i16        t1,  q9,  d6[1]
+        vmls.i16        t1,  q10, d6[0]
+  .if \narrow
+        vqrshrun.s16    \d0, t0,  #5
+        vqrshrun.s16    \d1, t1,  #5
+  .endif
+        .unreq  t0
+        .unreq  t1
+.endm
+
+.macro  lowpass_8_1     r0,  r1,  d0,  narrow=1
+  .if \narrow
+        t0 .req q0
+  .else
+        t0 .req \d0
+  .endif
+        vext.8          d2,  \r0, \r1, #2
+        vext.8          d3,  \r0, \r1, #3
+        vaddl.u8        q1,  d2,  d3
+        vext.8          d4,  \r0, \r1, #1
+        vext.8          d5,  \r0, \r1, #4
+        vaddl.u8        q2,  d4,  d5
+        vext.8          d30, \r0, \r1, #5
+        vaddl.u8        t0,  \r0, d30
+        vmla.i16        t0,  q1,  d6[1]
+        vmls.i16        t0,  q2,  d6[0]
+  .if \narrow
+        vqrshrun.s16    \d0, t0,  #5
+  .endif
+        .unreq  t0
+.endm
+
+.macro  lowpass_8.16    r0,  r1,  l0,  h0,  l1,  h1,  d
+        vext.16         q1,  \r0, \r1, #2
+        vext.16         q0,  \r0, \r1, #3
+        vaddl.s16       q9,  d2,  d0
+        vext.16         q2,  \r0, \r1, #1
+        vaddl.s16       q1,  d3,  d1
+        vext.16         q3,  \r0, \r1, #4
+        vaddl.s16       q10, d4,  d6
+        vext.16         \r1, \r0, \r1, #5
+        vaddl.s16       q2,  d5,  d7
+        vaddl.s16       q0,  \h0, \h1
+        vaddl.s16       q8,  \l0, \l1
+
+        vshl.i32        q3,  q9,  #4
+        vshl.i32        q9,  q9,  #2
+        vshl.i32        q15, q10, #2
+        vadd.i32        q9,  q9,  q3
+        vadd.i32        q10, q10, q15
+
+        vshl.i32        q3,  q1,  #4
+        vshl.i32        q1,  q1,  #2
+        vshl.i32        q15, q2,  #2
+        vadd.i32        q1,  q1,  q3
+        vadd.i32        q2,  q2,  q15
+
+        vadd.i32        q9,  q9,  q8
+        vsub.i32        q9,  q9,  q10
+
+        vadd.i32        q1,  q1,  q0
+        vsub.i32        q1,  q1,  q2
+
+        vrshrn.s32      d18, q9,  #10
+        vrshrn.s32      d19, q1,  #10
+
+        vqmovun.s16     \d,  q9
+.endm
+
+function put_h264_qpel16_h_lowpass_neon_packed
+        mov             r4,  lr
+        mov             r12, #16
+        mov             r3,  #8
+        bl              put_h264_qpel8_h_lowpass_neon
+        sub             r1,  r1,  r2, lsl #4
+        add             r1,  r1,  #8
+        mov             r12, #16
+        mov             lr,  r4
+        b               put_h264_qpel8_h_lowpass_neon
+endfunc
+
+.macro  h264_qpel_h_lowpass type
+function \type\()_h264_qpel16_h_lowpass_neon
+        push            {lr}
+        mov             r12, #16
+        bl              \type\()_h264_qpel8_h_lowpass_neon
+        sub             r0,  r0,  r3, lsl #4
+        sub             r1,  r1,  r2, lsl #4
+        add             r0,  r0,  #8
+        add             r1,  r1,  #8
+        mov             r12, #16
+        pop             {lr}
+endfunc
+
+function \type\()_h264_qpel8_h_lowpass_neon
+1:      vld1.8          {d0, d1},  [r1], r2
+        vld1.8          {d16,d17}, [r1], r2
+        subs            r12, r12, #2
+        lowpass_8       d0,  d1,  d16, d17, d0,  d16
+  .ifc \type,avg
+        vld1.8          {d2},     [r0,:64], r3
+        vrhadd.u8       d0,  d0,  d2
+        vld1.8          {d3},     [r0,:64]
+        vrhadd.u8       d16, d16, d3
+        sub             r0,  r0,  r3
+  .endif
+        vst1.8          {d0},     [r0,:64], r3
+        vst1.8          {d16},    [r0,:64], r3
+        bne             1b
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel_h_lowpass put
+        h264_qpel_h_lowpass avg
+
+.macro  h264_qpel_h_lowpass_l2 type
+function \type\()_h264_qpel16_h_lowpass_l2_neon
+        push            {lr}
+        mov             r12, #16
+        bl              \type\()_h264_qpel8_h_lowpass_l2_neon
+        sub             r0,  r0,  r2, lsl #4
+        sub             r1,  r1,  r2, lsl #4
+        sub             r3,  r3,  r2, lsl #4
+        add             r0,  r0,  #8
+        add             r1,  r1,  #8
+        add             r3,  r3,  #8
+        mov             r12, #16
+        pop             {lr}
+endfunc
+
+function \type\()_h264_qpel8_h_lowpass_l2_neon
+1:      vld1.8          {d0, d1},  [r1], r2
+        vld1.8          {d16,d17}, [r1], r2
+        vld1.8          {d28},     [r3], r2
+        vld1.8          {d29},     [r3], r2
+        subs            r12, r12, #2
+        lowpass_8       d0,  d1,  d16, d17, d0,  d1
+        vrhadd.u8       q0,  q0,  q14
+  .ifc \type,avg
+        vld1.8          {d2},      [r0,:64], r2
+        vrhadd.u8       d0,  d0,  d2
+        vld1.8          {d3},      [r0,:64]
+        vrhadd.u8       d1,  d1,  d3
+        sub             r0,  r0,  r2
+  .endif
+        vst1.8          {d0},      [r0,:64], r2
+        vst1.8          {d1},      [r0,:64], r2
+        bne             1b
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel_h_lowpass_l2 put
+        h264_qpel_h_lowpass_l2 avg
+
+function put_h264_qpel16_v_lowpass_neon_packed
+        mov             r4,  lr
+        mov             r2,  #8
+        bl              put_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              put_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        bl              put_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r4
+        b               put_h264_qpel8_v_lowpass_neon
+endfunc
+
+.macro  h264_qpel_v_lowpass type
+function \type\()_h264_qpel16_v_lowpass_neon
+        mov             r4,  lr
+        bl              \type\()_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              \type\()_h264_qpel8_v_lowpass_neon
+        sub             r0,  r0,  r2, lsl #4
+        add             r0,  r0,  #8
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        bl              \type\()_h264_qpel8_v_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r4
+endfunc
+
+function \type\()_h264_qpel8_v_lowpass_neon
+        vld1.8          {d8},  [r1], r3
+        vld1.8          {d10}, [r1], r3
+        vld1.8          {d12}, [r1], r3
+        vld1.8          {d14}, [r1], r3
+        vld1.8          {d22}, [r1], r3
+        vld1.8          {d24}, [r1], r3
+        vld1.8          {d26}, [r1], r3
+        vld1.8          {d28}, [r1], r3
+        vld1.8          {d9},  [r1], r3
+        vld1.8          {d11}, [r1], r3
+        vld1.8          {d13}, [r1], r3
+        vld1.8          {d15}, [r1], r3
+        vld1.8          {d23}, [r1]
+
+        transpose_8x8   q4,  q5,  q6,  q7,  q11, q12, q13, q14
+        lowpass_8       d8,  d9,  d10, d11, d8,  d10
+        lowpass_8       d12, d13, d14, d15, d12, d14
+        lowpass_8       d22, d23, d24, d25, d22, d24
+        lowpass_8       d26, d27, d28, d29, d26, d28
+        transpose_8x8   d8,  d10, d12, d14, d22, d24, d26, d28
+
+  .ifc \type,avg
+        vld1.8          {d9},  [r0,:64], r2
+        vrhadd.u8       d8,  d8,  d9
+        vld1.8          {d11}, [r0,:64], r2
+        vrhadd.u8       d10, d10, d11
+        vld1.8          {d13}, [r0,:64], r2
+        vrhadd.u8       d12, d12, d13
+        vld1.8          {d15}, [r0,:64], r2
+        vrhadd.u8       d14, d14, d15
+        vld1.8          {d23}, [r0,:64], r2
+        vrhadd.u8       d22, d22, d23
+        vld1.8          {d25}, [r0,:64], r2
+        vrhadd.u8       d24, d24, d25
+        vld1.8          {d27}, [r0,:64], r2
+        vrhadd.u8       d26, d26, d27
+        vld1.8          {d29}, [r0,:64], r2
+        vrhadd.u8       d28, d28, d29
+        sub             r0,  r0,  r2,  lsl #3
+  .endif
+
+        vst1.8          {d8},  [r0,:64], r2
+        vst1.8          {d10}, [r0,:64], r2
+        vst1.8          {d12}, [r0,:64], r2
+        vst1.8          {d14}, [r0,:64], r2
+        vst1.8          {d22}, [r0,:64], r2
+        vst1.8          {d24}, [r0,:64], r2
+        vst1.8          {d26}, [r0,:64], r2
+        vst1.8          {d28}, [r0,:64], r2
+
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel_v_lowpass put
+        h264_qpel_v_lowpass avg
+
+.macro  h264_qpel_v_lowpass_l2 type
+function \type\()_h264_qpel16_v_lowpass_l2_neon
+        mov             r4,  lr
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        sub             r0,  r0,  r3, lsl #4
+        sub             r12, r12, r2, lsl #4
+        add             r0,  r0,  #8
+        add             r12, r12, #8
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r4
+endfunc
+
+function \type\()_h264_qpel8_v_lowpass_l2_neon
+        vld1.8          {d8},  [r1], r3
+        vld1.8          {d10}, [r1], r3
+        vld1.8          {d12}, [r1], r3
+        vld1.8          {d14}, [r1], r3
+        vld1.8          {d22}, [r1], r3
+        vld1.8          {d24}, [r1], r3
+        vld1.8          {d26}, [r1], r3
+        vld1.8          {d28}, [r1], r3
+        vld1.8          {d9},  [r1], r3
+        vld1.8          {d11}, [r1], r3
+        vld1.8          {d13}, [r1], r3
+        vld1.8          {d15}, [r1], r3
+        vld1.8          {d23}, [r1]
+
+        transpose_8x8   q4,  q5,  q6,  q7,  q11, q12, q13, q14
+        lowpass_8       d8,  d9,  d10, d11, d8,  d9
+        lowpass_8       d12, d13, d14, d15, d12, d13
+        lowpass_8       d22, d23, d24, d25, d22, d23
+        lowpass_8       d26, d27, d28, d29, d26, d27
+        transpose_8x8   d8,  d9,  d12, d13, d22, d23, d26, d27
+
+        vld1.8          {d0},  [r12], r2
+        vld1.8          {d1},  [r12], r2
+        vld1.8          {d2},  [r12], r2
+        vld1.8          {d3},  [r12], r2
+        vld1.8          {d4},  [r12], r2
+        vrhadd.u8       q0,  q0,  q4
+        vld1.8          {d5},  [r12], r2
+        vrhadd.u8       q1,  q1,  q6
+        vld1.8          {d10}, [r12], r2
+        vrhadd.u8       q2,  q2,  q11
+        vld1.8          {d11}, [r12], r2
+        vrhadd.u8       q5,  q5,  q13
+
+  .ifc \type,avg
+        vld1.8          {d16}, [r0,:64], r3
+        vrhadd.u8       d0,  d0,  d16
+        vld1.8          {d17}, [r0,:64], r3
+        vrhadd.u8       d1,  d1,  d17
+        vld1.8          {d16}, [r0,:64], r3
+        vrhadd.u8       d2,  d2,  d16
+        vld1.8          {d17}, [r0,:64], r3
+        vrhadd.u8       d3,  d3,  d17
+        vld1.8          {d16}, [r0,:64], r3
+        vrhadd.u8       d4,  d4,  d16
+        vld1.8          {d17}, [r0,:64], r3
+        vrhadd.u8       d5,  d5,  d17
+        vld1.8          {d16}, [r0,:64], r3
+        vrhadd.u8       d10, d10, d16
+        vld1.8          {d17}, [r0,:64], r3
+        vrhadd.u8       d11, d11, d17
+        sub             r0,  r0,  r3,  lsl #3
+  .endif
+
+        vst1.8          {d0},  [r0,:64], r3
+        vst1.8          {d1},  [r0,:64], r3
+        vst1.8          {d2},  [r0,:64], r3
+        vst1.8          {d3},  [r0,:64], r3
+        vst1.8          {d4},  [r0,:64], r3
+        vst1.8          {d5},  [r0,:64], r3
+        vst1.8          {d10}, [r0,:64], r3
+        vst1.8          {d11}, [r0,:64], r3
+
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel_v_lowpass_l2 put
+        h264_qpel_v_lowpass_l2 avg
+
+function put_h264_qpel8_hv_lowpass_neon_top
+        lowpass_const   r12
+        mov             r12, #12
+1:      vld1.8          {d0, d1},  [r1], r3
+        vld1.8          {d16,d17}, [r1], r3
+        subs            r12, r12, #2
+        lowpass_8       d0,  d1,  d16, d17, q11, q12, narrow=0
+        vst1.8          {d22-d25}, [r4,:128]!
+        bne             1b
+
+        vld1.8          {d0, d1},  [r1]
+        lowpass_8_1     d0,  d1,  q12, narrow=0
+
+        mov             r12, #-16
+        add             r4,  r4,  r12
+        vld1.8          {d30,d31}, [r4,:128], r12
+        vld1.8          {d20,d21}, [r4,:128], r12
+        vld1.8          {d18,d19}, [r4,:128], r12
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d14,d15}, [r4,:128], r12
+        vld1.8          {d12,d13}, [r4,:128], r12
+        vld1.8          {d10,d11}, [r4,:128], r12
+        vld1.8          {d8, d9},  [r4,:128], r12
+        vld1.8          {d6, d7},  [r4,:128], r12
+        vld1.8          {d4, d5},  [r4,:128], r12
+        vld1.8          {d2, d3},  [r4,:128], r12
+        vld1.8          {d0, d1},  [r4,:128]
+
+        swap4           d1,  d3,  d5,  d7,  d8,  d10, d12, d14
+        transpose16_4x4 q0,  q1,  q2,  q3,  q4,  q5,  q6,  q7
+
+        swap4           d17, d19, d21, d31, d24, d26, d28, d22
+        transpose16_4x4 q8,  q9,  q10, q15, q12, q13, q14, q11
+
+        vst1.8          {d30,d31}, [r4,:128]!
+        vst1.8          {d6, d7},  [r4,:128]!
+        vst1.8          {d20,d21}, [r4,:128]!
+        vst1.8          {d4, d5},  [r4,:128]!
+        vst1.8          {d18,d19}, [r4,:128]!
+        vst1.8          {d2, d3},  [r4,:128]!
+        vst1.8          {d16,d17}, [r4,:128]!
+        vst1.8          {d0, d1},  [r4,:128]
+
+        lowpass_8.16    q4,  q12, d8,  d9,  d24, d25, d8
+        lowpass_8.16    q5,  q13, d10, d11, d26, d27, d9
+        lowpass_8.16    q6,  q14, d12, d13, d28, d29, d10
+        lowpass_8.16    q7,  q11, d14, d15, d22, d23, d11
+
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d30,d31}, [r4,:128], r12
+        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d12
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d30,d31}, [r4,:128], r12
+        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d13
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d30,d31}, [r4,:128], r12
+        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d14
+        vld1.8          {d16,d17}, [r4,:128], r12
+        vld1.8          {d30,d31}, [r4,:128]
+        lowpass_8.16    q8,  q15, d16, d17, d30, d31, d15
+
+        transpose_8x8   d12, d13, d14, d15, d8,  d9,  d10, d11
+
+        bx              lr
+endfunc
+
+.macro  h264_qpel8_hv_lowpass type
+function \type\()_h264_qpel8_hv_lowpass_neon
+        mov             r10, lr
+        bl              put_h264_qpel8_hv_lowpass_neon_top
+  .ifc \type,avg
+        vld1.8          {d0},      [r0,:64], r2
+        vrhadd.u8       d12, d12, d0
+        vld1.8          {d1},      [r0,:64], r2
+        vrhadd.u8       d13, d13, d1
+        vld1.8          {d2},      [r0,:64], r2
+        vrhadd.u8       d14, d14, d2
+        vld1.8          {d3},      [r0,:64], r2
+        vrhadd.u8       d15, d15, d3
+        vld1.8          {d4},      [r0,:64], r2
+        vrhadd.u8       d8,  d8,  d4
+        vld1.8          {d5},      [r0,:64], r2
+        vrhadd.u8       d9,  d9,  d5
+        vld1.8          {d6},      [r0,:64], r2
+        vrhadd.u8       d10, d10, d6
+        vld1.8          {d7},      [r0,:64], r2
+        vrhadd.u8       d11, d11, d7
+        sub             r0,  r0,  r2,  lsl #3
+  .endif
+
+        vst1.8          {d12},     [r0,:64], r2
+        vst1.8          {d13},     [r0,:64], r2
+        vst1.8          {d14},     [r0,:64], r2
+        vst1.8          {d15},     [r0,:64], r2
+        vst1.8          {d8},      [r0,:64], r2
+        vst1.8          {d9},      [r0,:64], r2
+        vst1.8          {d10},     [r0,:64], r2
+        vst1.8          {d11},     [r0,:64], r2
+
+        mov             lr,  r10
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel8_hv_lowpass put
+        h264_qpel8_hv_lowpass avg
+
+.macro  h264_qpel8_hv_lowpass_l2 type
+function \type\()_h264_qpel8_hv_lowpass_l2_neon
+        mov             r10, lr
+        bl              put_h264_qpel8_hv_lowpass_neon_top
+
+        vld1.8          {d0, d1},  [r2,:128]!
+        vld1.8          {d2, d3},  [r2,:128]!
+        vrhadd.u8       q0,  q0,  q6
+        vld1.8          {d4, d5},  [r2,:128]!
+        vrhadd.u8       q1,  q1,  q7
+        vld1.8          {d6, d7},  [r2,:128]!
+        vrhadd.u8       q2,  q2,  q4
+        vrhadd.u8       q3,  q3,  q5
+  .ifc \type,avg
+        vld1.8          {d16},     [r0,:64], r3
+        vrhadd.u8       d0,  d0,  d16
+        vld1.8          {d17},     [r0,:64], r3
+        vrhadd.u8       d1,  d1,  d17
+        vld1.8          {d18},     [r0,:64], r3
+        vrhadd.u8       d2,  d2,  d18
+        vld1.8          {d19},     [r0,:64], r3
+        vrhadd.u8       d3,  d3,  d19
+        vld1.8          {d20},     [r0,:64], r3
+        vrhadd.u8       d4,  d4,  d20
+        vld1.8          {d21},     [r0,:64], r3
+        vrhadd.u8       d5,  d5,  d21
+        vld1.8          {d22},     [r0,:64], r3
+        vrhadd.u8       d6,  d6,  d22
+        vld1.8          {d23},     [r0,:64], r3
+        vrhadd.u8       d7,  d7,  d23
+        sub             r0,  r0,  r3,  lsl #3
+  .endif
+        vst1.8          {d0},      [r0,:64], r3
+        vst1.8          {d1},      [r0,:64], r3
+        vst1.8          {d2},      [r0,:64], r3
+        vst1.8          {d3},      [r0,:64], r3
+        vst1.8          {d4},      [r0,:64], r3
+        vst1.8          {d5},      [r0,:64], r3
+        vst1.8          {d6},      [r0,:64], r3
+        vst1.8          {d7},      [r0,:64], r3
+
+        mov             lr,  r10
+        bx              lr
+endfunc
+.endm
+
+        h264_qpel8_hv_lowpass_l2 put
+        h264_qpel8_hv_lowpass_l2 avg
+
+.macro  h264_qpel16_hv  type
+function \type\()_h264_qpel16_hv_lowpass_neon
+        mov             r9,  lr
+        bl              \type\()_h264_qpel8_hv_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              \type\()_h264_qpel8_hv_lowpass_neon
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        sub             r0,  r0,  r2, lsl #4
+        add             r0,  r0,  #8
+        bl              \type\()_h264_qpel8_hv_lowpass_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r9
+        b               \type\()_h264_qpel8_hv_lowpass_neon
+endfunc
+
+function \type\()_h264_qpel16_hv_lowpass_l2_neon
+        mov             r9,  lr
+        sub             r2,  r4,  #256
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #2
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #4
+        sub             r1,  r1,  r3, lsl #2
+        add             r1,  r1,  #8
+        sub             r0,  r0,  r3, lsl #4
+        add             r0,  r0,  #8
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        sub             r1,  r1,  r3, lsl #2
+        mov             lr,  r9
+        b               \type\()_h264_qpel8_hv_lowpass_l2_neon
+endfunc
+.endm
+
+        h264_qpel16_hv put
+        h264_qpel16_hv avg
+
+.macro  h264_qpel8      type
+function ff_\type\()_h264_qpel8_mc10_neon, export=1
+        lowpass_const   r3
+        mov             r3,  r1
+        sub             r1,  r1,  #2
+        mov             r12, #8
+        b               \type\()_h264_qpel8_h_lowpass_l2_neon
+endfunc
+
+function ff_\type\()_h264_qpel8_mc20_neon, export=1
+        lowpass_const   r3
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        mov             r12, #8
+        b               \type\()_h264_qpel8_h_lowpass_neon
+endfunc
+
+function ff_\type\()_h264_qpel8_mc30_neon, export=1
+        lowpass_const   r3
+        add             r3,  r1,  #1
+        sub             r1,  r1,  #2
+        mov             r12, #8
+        b               \type\()_h264_qpel8_h_lowpass_l2_neon
+endfunc
+
+function ff_\type\()_h264_qpel8_mc01_neon, export=1
+        push            {lr}
+        mov             r12, r1
+\type\()_h264_qpel8_mc01:
+        lowpass_const   r3
+        mov             r3,  r2
+        sub             r1,  r1,  r2, lsl #1
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        vpop            {d8-d15}
+        pop             {pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc11_neon, export=1
+        push            {r0, r1, r11, lr}
+\type\()_h264_qpel8_mc11:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #64
+        mov             r0,  sp
+        sub             r1,  r1,  #2
+        mov             r3,  #8
+        mov             r12, #8
+        vpush           {d8-d15}
+        bl              put_h264_qpel8_h_lowpass_neon
+        ldrd            r0,  r1,  [r11], #8
+        mov             r3,  r2
+        add             r12, sp,  #64
+        sub             r1,  r1,  r2, lsl #1
+        mov             r2,  #8
+        bl              \type\()_h264_qpel8_v_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc21_neon, export=1
+        push            {r0, r1, r4, r10, r11, lr}
+\type\()_h264_qpel8_mc21:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #(8*8+16*12)
+        sub             r1,  r1,  #2
+        mov             r3,  #8
+        mov             r0,  sp
+        mov             r12, #8
+        vpush           {d8-d15}
+        bl              put_h264_qpel8_h_lowpass_neon
+        mov             r4,  r0
+        ldrd            r0,  r1,  [r11], #8
+        sub             r1,  r1,  r2, lsl #1
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        sub             r2,  r4,  #64
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r10, r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc31_neon, export=1
+        add             r1,  r1,  #1
+        push            {r0, r1, r11, lr}
+        sub             r1,  r1,  #1
+        b               \type\()_h264_qpel8_mc11
+endfunc
+
+function ff_\type\()_h264_qpel8_mc02_neon, export=1
+        push            {lr}
+        lowpass_const   r3
+        sub             r1,  r1,  r2, lsl #1
+        mov             r3,  r2
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel8_v_lowpass_neon
+        vpop            {d8-d15}
+        pop             {pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc12_neon, export=1
+        push            {r0, r1, r4, r10, r11, lr}
+\type\()_h264_qpel8_mc12:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #(8*8+16*12)
+        sub             r1,  r1,  r2, lsl #1
+        mov             r3,  r2
+        mov             r2,  #8
+        mov             r0,  sp
+        vpush           {d8-d15}
+        bl              put_h264_qpel8_v_lowpass_neon
+        mov             r4,  r0
+        ldrd            r0,  r1,  [r11], #8
+        sub             r1,  r1,  r3, lsl #1
+        sub             r1,  r1,  #2
+        sub             r2,  r4,  #64
+        bl              \type\()_h264_qpel8_hv_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r10, r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc22_neon, export=1
+        push            {r4, r10, r11, lr}
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r4,  r11, #15
+T       mov             sp,  r4
+        sub             r1,  r1,  r2, lsl #1
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        sub             sp,  sp,  #(16*12)
+        mov             r4,  sp
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel8_hv_lowpass_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r10, r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel8_mc32_neon, export=1
+        push            {r0, r1, r4, r10, r11, lr}
+        add             r1,  r1,  #1
+        b               \type\()_h264_qpel8_mc12
+endfunc
+
+function ff_\type\()_h264_qpel8_mc03_neon, export=1
+        push            {lr}
+        add             r12, r1,  r2
+        b               \type\()_h264_qpel8_mc01
+endfunc
+
+function ff_\type\()_h264_qpel8_mc13_neon, export=1
+        push            {r0, r1, r11, lr}
+        add             r1,  r1,  r2
+        b               \type\()_h264_qpel8_mc11
+endfunc
+
+function ff_\type\()_h264_qpel8_mc23_neon, export=1
+        push            {r0, r1, r4, r10, r11, lr}
+        add             r1,  r1,  r2
+        b               \type\()_h264_qpel8_mc21
+endfunc
+
+function ff_\type\()_h264_qpel8_mc33_neon, export=1
+        add             r1,  r1,  #1
+        push            {r0, r1, r11, lr}
+        add             r1,  r1,  r2
+        sub             r1,  r1,  #1
+        b               \type\()_h264_qpel8_mc11
+endfunc
+.endm
+
+        h264_qpel8 put
+        h264_qpel8 avg
+
+.macro  h264_qpel16     type
+function ff_\type\()_h264_qpel16_mc10_neon, export=1
+        lowpass_const   r3
+        mov             r3,  r1
+        sub             r1,  r1,  #2
+        b               \type\()_h264_qpel16_h_lowpass_l2_neon
+endfunc
+
+function ff_\type\()_h264_qpel16_mc20_neon, export=1
+        lowpass_const   r3
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        b               \type\()_h264_qpel16_h_lowpass_neon
+endfunc
+
+function ff_\type\()_h264_qpel16_mc30_neon, export=1
+        lowpass_const   r3
+        add             r3,  r1,  #1
+        sub             r1,  r1,  #2
+        b               \type\()_h264_qpel16_h_lowpass_l2_neon
+endfunc
+
+function ff_\type\()_h264_qpel16_mc01_neon, export=1
+        push            {r4, lr}
+        mov             r12, r1
+\type\()_h264_qpel16_mc01:
+        lowpass_const   r3
+        mov             r3,  r2
+        sub             r1,  r1,  r2, lsl #1
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel16_v_lowpass_l2_neon
+        vpop            {d8-d15}
+        pop             {r4, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc11_neon, export=1
+        push            {r0, r1, r4, r11, lr}
+\type\()_h264_qpel16_mc11:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #256
+        mov             r0,  sp
+        sub             r1,  r1,  #2
+        mov             r3,  #16
+        vpush           {d8-d15}
+        bl              put_h264_qpel16_h_lowpass_neon
+        ldrd            r0,  r1,  [r11], #8
+        mov             r3,  r2
+        add             r12, sp,  #64
+        sub             r1,  r1,  r2, lsl #1
+        mov             r2,  #16
+        bl              \type\()_h264_qpel16_v_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc21_neon, export=1
+        push            {r0, r1, r4-r5, r9-r11, lr}
+\type\()_h264_qpel16_mc21:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #(16*16+16*12)
+        sub             r1,  r1,  #2
+        mov             r0,  sp
+        vpush           {d8-d15}
+        bl              put_h264_qpel16_h_lowpass_neon_packed
+        mov             r4,  r0
+        ldrd            r0,  r1,  [r11], #8
+        sub             r1,  r1,  r2, lsl #1
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        bl              \type\()_h264_qpel16_hv_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4-r5, r9-r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc31_neon, export=1
+        add             r1,  r1,  #1
+        push            {r0, r1, r4, r11, lr}
+        sub             r1,  r1,  #1
+        b               \type\()_h264_qpel16_mc11
+endfunc
+
+function ff_\type\()_h264_qpel16_mc02_neon, export=1
+        push            {r4, lr}
+        lowpass_const   r3
+        sub             r1,  r1,  r2, lsl #1
+        mov             r3,  r2
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel16_v_lowpass_neon
+        vpop            {d8-d15}
+        pop             {r4, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc12_neon, export=1
+        push            {r0, r1, r4-r5, r9-r11, lr}
+\type\()_h264_qpel16_mc12:
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r0,  r11, #15
+T       mov             sp,  r0
+        sub             sp,  sp,  #(16*16+16*12)
+        sub             r1,  r1,  r2, lsl #1
+        mov             r0,  sp
+        mov             r3,  r2
+        vpush           {d8-d15}
+        bl              put_h264_qpel16_v_lowpass_neon_packed
+        mov             r4,  r0
+        ldrd            r0,  r1,  [r11], #8
+        sub             r1,  r1,  r3, lsl #1
+        sub             r1,  r1,  #2
+        mov             r2,  r3
+        bl              \type\()_h264_qpel16_hv_lowpass_l2_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4-r5, r9-r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc22_neon, export=1
+        push            {r4, r9-r11, lr}
+        lowpass_const   r3
+        mov             r11, sp
+A       bic             sp,  sp,  #15
+T       bic             r4,  r11, #15
+T       mov             sp,  r4
+        sub             r1,  r1,  r2, lsl #1
+        sub             r1,  r1,  #2
+        mov             r3,  r2
+        sub             sp,  sp,  #(16*12)
+        mov             r4,  sp
+        vpush           {d8-d15}
+        bl              \type\()_h264_qpel16_hv_lowpass_neon
+        vpop            {d8-d15}
+        mov             sp,  r11
+        pop             {r4, r9-r11, pc}
+endfunc
+
+function ff_\type\()_h264_qpel16_mc32_neon, export=1
+        push            {r0, r1, r4-r5, r9-r11, lr}
+        add             r1,  r1,  #1
+        b               \type\()_h264_qpel16_mc12
+endfunc
+
+function ff_\type\()_h264_qpel16_mc03_neon, export=1
+        push            {r4, lr}
+        add             r12, r1,  r2
+        b               \type\()_h264_qpel16_mc01
+endfunc
+
+function ff_\type\()_h264_qpel16_mc13_neon, export=1
+        push            {r0, r1, r4, r11, lr}
+        add             r1,  r1,  r2
+        b               \type\()_h264_qpel16_mc11
+endfunc
+
+function ff_\type\()_h264_qpel16_mc23_neon, export=1
+        push            {r0, r1, r4-r5, r9-r11, lr}
+        add             r1,  r1,  r2
+        b               \type\()_h264_qpel16_mc21
+endfunc
+
+function ff_\type\()_h264_qpel16_mc33_neon, export=1
+        add             r1,  r1,  #1
+        push            {r0, r1, r4, r11, lr}
+        add             r1,  r1,  r2
+        sub             r1,  r1,  #1
+        b               \type\()_h264_qpel16_mc11
+endfunc
+.endm
+
+        h264_qpel16 put
+        h264_qpel16 avg
diff --git a/libavcodec/arm/hpeldsp_arm.S b/libavcodec/arm/hpeldsp_arm.S
new file mode 100644
index 0000000..d4f97e3
--- /dev/null
+++ b/libavcodec/arm/hpeldsp_arm.S
@@ -0,0 +1,611 @@
+@
+@ ARMv4 optimized DSP utils
+@ Copyright (c) 2004 AGAWA Koji <i (AT) atty (DOT) jp>
+@
+@ 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 "libavutil/arm/asm.S"
+
+#if !HAVE_ARMV5TE_EXTERNAL
+#define pld @
+#endif
+
+.macro  ALIGN_QWORD_D shift, Rd0, Rd1, Rd2, Rd3, Rn0, Rn1, Rn2, Rn3, Rn4
+        mov             \Rd0, \Rn0, lsr #(\shift * 8)
+        mov             \Rd1, \Rn1, lsr #(\shift * 8)
+        mov             \Rd2, \Rn2, lsr #(\shift * 8)
+        mov             \Rd3, \Rn3, lsr #(\shift * 8)
+        orr             \Rd0, \Rd0, \Rn1, lsl #(32 - \shift * 8)
+        orr             \Rd1, \Rd1, \Rn2, lsl #(32 - \shift * 8)
+        orr             \Rd2, \Rd2, \Rn3, lsl #(32 - \shift * 8)
+        orr             \Rd3, \Rd3, \Rn4, lsl #(32 - \shift * 8)
+.endm
+.macro  ALIGN_DWORD shift, R0, R1, R2
+        mov             \R0, \R0, lsr #(\shift * 8)
+        orr             \R0, \R0, \R1, lsl #(32 - \shift * 8)
+        mov             \R1, \R1, lsr #(\shift * 8)
+        orr             \R1, \R1, \R2, lsl #(32 - \shift * 8)
+.endm
+.macro  ALIGN_DWORD_D shift, Rdst0, Rdst1, Rsrc0, Rsrc1, Rsrc2
+        mov             \Rdst0, \Rsrc0, lsr #(\shift * 8)
+        mov             \Rdst1, \Rsrc1, lsr #(\shift * 8)
+        orr             \Rdst0, \Rdst0, \Rsrc1, lsl #(32 - (\shift * 8))
+        orr             \Rdst1, \Rdst1, \Rsrc2, lsl #(32 - (\shift * 8))
+.endm
+
+.macro  RND_AVG32 Rd0, Rd1, Rn0, Rn1, Rm0, Rm1, Rmask
+        @ Rd = (Rn | Rm) - (((Rn ^ Rm) & ~0x01010101) >> 1)
+        @ Rmask = 0xFEFEFEFE
+        @ Rn = destroy
+        eor             \Rd0, \Rn0, \Rm0
+        eor             \Rd1, \Rn1, \Rm1
+        orr             \Rn0, \Rn0, \Rm0
+        orr             \Rn1, \Rn1, \Rm1
+        and             \Rd0, \Rd0, \Rmask
+        and             \Rd1, \Rd1, \Rmask
+        sub             \Rd0, \Rn0, \Rd0, lsr #1
+        sub             \Rd1, \Rn1, \Rd1, lsr #1
+.endm
+
+.macro  NO_RND_AVG32 Rd0, Rd1, Rn0, Rn1, Rm0, Rm1, Rmask
+        @ Rd = (Rn & Rm) - (((Rn ^ Rm) & ~0x01010101) >> 1)
+        @ Rmask = 0xFEFEFEFE
+        @ Rn = destroy
+        eor             \Rd0, \Rn0, \Rm0
+        eor             \Rd1, \Rn1, \Rm1
+        and             \Rn0, \Rn0, \Rm0
+        and             \Rn1, \Rn1, \Rm1
+        and             \Rd0, \Rd0, \Rmask
+        and             \Rd1, \Rd1, \Rmask
+        add             \Rd0, \Rn0, \Rd0, lsr #1
+        add             \Rd1, \Rn1, \Rd1, lsr #1
+.endm
+
+.macro  JMP_ALIGN tmp, reg
+        ands            \tmp, \reg, #3
+        bic             \reg, \reg, #3
+        beq             1f
+        subs            \tmp, \tmp, #1
+        beq             2f
+        subs            \tmp, \tmp, #1
+        beq             3f
+        b    4f
+.endm
+
+@ ----------------------------------------------------------------
+        .align 5
+function ff_put_pixels16_arm, export=1
+        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+        @ block = word aligned, pixles = unaligned
+        pld             [r1]
+        push            {r4-r11, lr}
+        JMP_ALIGN       r5,  r1
+1:
+        ldm             r1,  {r4-r7}
+        add             r1,  r1,  r2
+        stm             r0,  {r4-r7}
+        pld             [r1]
+        subs            r3,  r3,  #1
+        add             r0,  r0,  r2
+        bne             1b
+        pop             {r4-r11, pc}
+        .align 5
+2:
+        ldm             r1,  {r4-r8}
+        add             r1,  r1,  r2
+        ALIGN_QWORD_D   1,   r9,  r10, r11, r12, r4,  r5,  r6,  r7,  r8
+        pld             [r1]
+        subs            r3,  r3,  #1
+        stm             r0,  {r9-r12}
+        add             r0,  r0,  r2
+        bne             2b
+        pop             {r4-r11, pc}
+        .align 5
+3:
+        ldm             r1,  {r4-r8}
+        add             r1,  r1,  r2
+        ALIGN_QWORD_D   2,   r9,  r10, r11, r12, r4,  r5,  r6,  r7,  r8
+        pld             [r1]
+        subs            r3,  r3,  #1
+        stm             r0,  {r9-r12}
+        add             r0,  r0,  r2
+        bne             3b
+        pop             {r4-r11, pc}
+        .align 5
+4:
+        ldm             r1,  {r4-r8}
+        add             r1,  r1,  r2
+        ALIGN_QWORD_D   3,   r9,  r10, r11, r12, r4,  r5,  r6,  r7,  r8
+        pld             [r1]
+        subs            r3,  r3,  #1
+        stm             r0,  {r9-r12}
+        add             r0,  r0,  r2
+        bne             4b
+        pop             {r4-r11,pc}
+endfunc
+
+@ ----------------------------------------------------------------
+        .align 5
+function ff_put_pixels8_arm, export=1
+        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+        @ block = word aligned, pixles = unaligned
+        pld             [r1]
+        push            {r4-r5,lr}
+        JMP_ALIGN       r5,  r1
+1:
+        ldm             r1,  {r4-r5}
+        add             r1,  r1,  r2
+        subs            r3,  r3,  #1
+        pld             [r1]
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bne             1b
+        pop             {r4-r5,pc}
+        .align 5
+2:
+        ldm             r1,  {r4-r5, r12}
+        add             r1,  r1,  r2
+        ALIGN_DWORD     1,   r4,  r5,  r12
+        pld             [r1]
+        subs            r3,  r3,  #1
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bne             2b
+        pop             {r4-r5,pc}
+        .align 5
+3:
+        ldm             r1,  {r4-r5, r12}
+        add             r1,  r1,  r2
+        ALIGN_DWORD     2,   r4,  r5,  r12
+        pld             [r1]
+        subs            r3,  r3,  #1
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bne             3b
+        pop             {r4-r5,pc}
+        .align 5
+4:
+        ldm             r1,  {r4-r5, r12}
+        add             r1,  r1,  r2
+        ALIGN_DWORD     3,   r4,  r5,  r12
+        pld             [r1]
+        subs            r3,  r3,  #1
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bne             4b
+        pop             {r4-r5,pc}
+endfunc
+
+@ ----------------------------------------------------------------
+        .align 5
+function ff_put_pixels8_x2_arm, export=1
+        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+        @ block = word aligned, pixles = unaligned
+        pld             [r1]
+        push            {r4-r10,lr}
+        ldr             r12, =0xfefefefe
+        JMP_ALIGN       r5,  r1
+1:
+        ldm             r1,  {r4-r5, r10}
+        add             r1,  r1,  r2
+        ALIGN_DWORD_D   1,   r6,  r7,  r4,  r5,  r10
+        pld             [r1]
+        RND_AVG32       r8,  r9,  r4,  r5,  r6,  r7,  r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r8-r9}
+        add             r0,  r0,  r2
+        bne             1b
+        pop             {r4-r10,pc}
+        .align 5
+2:
+        ldm             r1,  {r4-r5, r10}
+        add             r1,  r1,  r2
+        ALIGN_DWORD_D   1,   r6,  r7,  r4,  r5,  r10
+        ALIGN_DWORD_D   2,   r8,  r9,  r4,  r5,  r10
+        pld             [r1]
+        RND_AVG32       r4,  r5,  r6,  r7,  r8,  r9,  r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bne             2b
+        pop             {r4-r10,pc}
+        .align 5
+3:
+        ldm             r1,  {r4-r5, r10}
+        add             r1,  r1,  r2
+        ALIGN_DWORD_D   2,   r6,  r7,  r4,  r5,  r10
+        ALIGN_DWORD_D   3,   r8,  r9,  r4,  r5,  r10
+        pld             [r1]
+        RND_AVG32       r4,  r5,  r6,  r7,  r8,  r9,  r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bne             3b
+        pop             {r4-r10,pc}
+        .align 5
+4:
+        ldm             r1,  {r4-r5, r10}
+        add             r1,  r1,  r2
+        ALIGN_DWORD_D   3,   r6,  r7,  r4,  r5,  r10
+        pld             [r1]
+        RND_AVG32       r8,  r9,  r6,  r7,  r5,  r10, r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r8-r9}
+        add             r0,  r0,  r2
+        bne             4b
+        pop             {r4-r10,pc}
+endfunc
+
+        .align 5
+function ff_put_no_rnd_pixels8_x2_arm, export=1
+        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+        @ block = word aligned, pixles = unaligned
+        pld             [r1]
+        push            {r4-r10,lr}
+        ldr             r12, =0xfefefefe
+        JMP_ALIGN       r5,  r1
+1:
+        ldm             r1,  {r4-r5, r10}
+        add             r1,  r1,  r2
+        ALIGN_DWORD_D   1,   r6,  r7,  r4,  r5,  r10
+        pld             [r1]
+        NO_RND_AVG32    r8,  r9,  r4,  r5,  r6,  r7,  r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r8-r9}
+        add             r0,  r0,  r2
+        bne             1b
+        pop             {r4-r10,pc}
+        .align 5
+2:
+        ldm             r1,  {r4-r5, r10}
+        add             r1,  r1,  r2
+        ALIGN_DWORD_D   1,   r6,  r7,  r4,  r5,  r10
+        ALIGN_DWORD_D   2,   r8,  r9,  r4,  r5,  r10
+        pld             [r1]
+        NO_RND_AVG32    r4,  r5,  r6,  r7,  r8,  r9,  r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bne             2b
+        pop             {r4-r10,pc}
+        .align 5
+3:
+        ldm             r1,  {r4-r5, r10}
+        add             r1,  r1,  r2
+        ALIGN_DWORD_D   2,   r6,  r7,  r4,  r5,  r10
+        ALIGN_DWORD_D   3,   r8,  r9,  r4,  r5,  r10
+        pld             [r1]
+        NO_RND_AVG32    r4,  r5,  r6,  r7,  r8,  r9,  r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bne             3b
+        pop             {r4-r10,pc}
+        .align 5
+4:
+        ldm             r1,  {r4-r5, r10}
+        add             r1,  r1,  r2
+        ALIGN_DWORD_D   3,   r6,  r7,  r4,  r5,  r10
+        pld             [r1]
+        NO_RND_AVG32    r8,  r9,  r6,  r7,  r5,  r10, r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r8-r9}
+        add             r0,  r0,  r2
+        bne             4b
+        pop             {r4-r10,pc}
+endfunc
+
+
+@ ----------------------------------------------------------------
+        .align 5
+function ff_put_pixels8_y2_arm, export=1
+        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+        @ block = word aligned, pixles = unaligned
+        pld             [r1]
+        push            {r4-r11,lr}
+        mov             r3,  r3,  lsr #1
+        ldr             r12, =0xfefefefe
+        JMP_ALIGN       r5,  r1
+1:
+        ldm             r1,  {r4-r5}
+        add             r1,  r1,  r2
+6:      ldm             r1,  {r6-r7}
+        add             r1,  r1,  r2
+        pld             [r1]
+        RND_AVG32       r8,  r9,  r4,  r5,  r6,  r7,  r12
+        ldm             r1,  {r4-r5}
+        add             r1,  r1,  r2
+        stm             r0,  {r8-r9}
+        add             r0,  r0,  r2
+        pld             [r1]
+        RND_AVG32       r8,  r9,  r6,  r7,  r4,  r5,  r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r8-r9}
+        add             r0,  r0,  r2
+        bne             6b
+        pop             {r4-r11,pc}
+        .align 5
+2:
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     1,   r4,  r5,  r6
+6:      ldm             r1,  {r7-r9}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     1,   r7,  r8,  r9
+        RND_AVG32       r10, r11, r4,  r5,  r7,  r8,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     1,   r4,  r5,  r6
+        subs            r3,  r3,  #1
+        RND_AVG32       r10, r11, r7,  r8,  r4,  r5,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        bne             6b
+        pop             {r4-r11,pc}
+        .align 5
+3:
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     2,   r4,  r5,  r6
+6:      ldm             r1,  {r7-r9}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     2,   r7,  r8,  r9
+        RND_AVG32       r10, r11, r4,  r5,  r7,  r8,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     2,   r4,  r5,  r6
+        subs            r3,  r3,  #1
+        RND_AVG32       r10, r11, r7,  r8,  r4,  r5,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        bne             6b
+        pop             {r4-r11,pc}
+        .align 5
+4:
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     3,   r4,  r5,  r6
+6:      ldm             r1,  {r7-r9}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     3,   r7,  r8,  r9
+        RND_AVG32       r10, r11, r4,  r5,  r7,  r8,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     3,   r4,  r5,  r6
+        subs            r3,  r3,  #1
+        RND_AVG32       r10, r11, r7,  r8,  r4,  r5,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        bne             6b
+        pop             {r4-r11,pc}
+endfunc
+
+        .align 5
+function ff_put_no_rnd_pixels8_y2_arm, export=1
+        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+        @ block = word aligned, pixles = unaligned
+        pld             [r1]
+        push            {r4-r11,lr}
+        mov             r3,  r3,  lsr #1
+        ldr             r12, =0xfefefefe
+        JMP_ALIGN       r5,  r1
+1:
+        ldm             r1,  {r4-r5}
+        add             r1,  r1,  r2
+6:      ldm             r1,  {r6-r7}
+        add             r1,  r1,  r2
+        pld             [r1]
+        NO_RND_AVG32    r8,  r9,  r4,  r5,  r6,  r7,  r12
+        ldm             r1,  {r4-r5}
+        add             r1,  r1,  r2
+        stm             r0,  {r8-r9}
+        add             r0,  r0,  r2
+        pld             [r1]
+        NO_RND_AVG32    r8,  r9,  r6,  r7,  r4,  r5,  r12
+        subs            r3,  r3,  #1
+        stm             r0,  {r8-r9}
+        add             r0,  r0,  r2
+        bne             6b
+        pop             {r4-r11,pc}
+        .align 5
+2:
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     1,   r4,  r5,  r6
+6:      ldm             r1,  {r7-r9}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     1,   r7,  r8,  r9
+        NO_RND_AVG32    r10, r11, r4,  r5,  r7,  r8,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     1,   r4,  r5,  r6
+        subs            r3,  r3,  #1
+        NO_RND_AVG32    r10, r11, r7,  r8,  r4,  r5,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        bne             6b
+        pop             {r4-r11,pc}
+        .align 5
+3:
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     2,   r4,  r5,  r6
+6:      ldm             r1,  {r7-r9}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     2,   r7,  r8,  r9
+        NO_RND_AVG32    r10, r11, r4,  r5,  r7,  r8,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     2,   r4,  r5,  r6
+        subs            r3,  r3,  #1
+        NO_RND_AVG32    r10, r11, r7,  r8,  r4,  r5,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        bne             6b
+        pop             {r4-r11,pc}
+        .align 5
+4:
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     3,   r4,  r5,  r6
+6:      ldm             r1,  {r7-r9}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     3,   r7,  r8,  r9
+        NO_RND_AVG32    r10, r11, r4,  r5,  r7,  r8,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        ldm             r1,  {r4-r6}
+        add             r1,  r1,  r2
+        pld             [r1]
+        ALIGN_DWORD     3,   r4,  r5,  r6
+        subs            r3,  r3,  #1
+        NO_RND_AVG32    r10, r11, r7,  r8,  r4,  r5,  r12
+        stm             r0,  {r10-r11}
+        add             r0,  r0,  r2
+        bne             6b
+        pop             {r4-r11,pc}
+endfunc
+
+        .ltorg
+
+@ ----------------------------------------------------------------
+.macro  RND_XY2_IT align, rnd
+        @ l1=  (a & 0x03030303) + (b & 0x03030303) ?(+ 0x02020202)
+        @ h1= ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2)
+.if \align == 0
+        ldm             r1,  {r6-r8}
+.elseif \align == 3
+        ldm             r1,  {r5-r7}
+.else
+        ldm             r1,  {r8-r10}
+.endif
+        add             r1,  r1,  r2
+        pld             [r1]
+.if \align == 0
+        ALIGN_DWORD_D   1,   r4,  r5,  r6,  r7,  r8
+.elseif \align == 1
+        ALIGN_DWORD_D   1,   r4,  r5,  r8,  r9,  r10
+        ALIGN_DWORD_D   2,   r6,  r7,  r8,  r9,  r10
+.elseif \align == 2
+        ALIGN_DWORD_D   2,   r4,  r5,  r8,  r9,  r10
+        ALIGN_DWORD_D   3,   r6,  r7,  r8,  r9,  r10
+.elseif \align == 3
+        ALIGN_DWORD_D   3,   r4,  r5,  r5,  r6,  r7
+.endif
+        ldr             r14, =0x03030303
+        tst             r3,  #1
+        and             r8,  r4,  r14
+        and             r9,  r5,  r14
+        and             r10, r6,  r14
+        and             r11, r7,  r14
+        it              eq
+        andeq           r14, r14, r14, \rnd #1
+        add             r8,  r8,  r10
+        add             r9,  r9,  r11
+        ldr             r12, =0xfcfcfcfc >> 2
+        itt             eq
+        addeq           r8,  r8,  r14
+        addeq           r9,  r9,  r14
+        and             r4,  r12, r4,  lsr #2
+        and             r5,  r12, r5,  lsr #2
+        and             r6,  r12, r6,  lsr #2
+        and             r7,  r12, r7,  lsr #2
+        add             r10, r4,  r6
+        add             r11, r5,  r7
+        subs            r3,  r3,  #1
+.endm
+
+.macro RND_XY2_EXPAND align, rnd
+        RND_XY2_IT      \align, \rnd
+6:      push            {r8-r11}
+        RND_XY2_IT      \align, \rnd
+        pop             {r4-r7}
+        add             r4,  r4,  r8
+        add             r5,  r5,  r9
+        ldr             r14, =0x0f0f0f0f
+        add             r6,  r6,  r10
+        add             r7,  r7,  r11
+        and             r4,  r14, r4,  lsr #2
+        and             r5,  r14, r5,  lsr #2
+        add             r4,  r4,  r6
+        add             r5,  r5,  r7
+        stm             r0,  {r4-r5}
+        add             r0,  r0,  r2
+        bge             6b
+        pop             {r4-r11,pc}
+.endm
+
+        .align 5
+function ff_put_pixels8_xy2_arm, export=1
+        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+        @ block = word aligned, pixles = unaligned
+        pld             [r1]
+        push            {r4-r11,lr} @ R14 is also called LR
+        JMP_ALIGN       r5,  r1
+1:      RND_XY2_EXPAND  0, lsl
+        .align 5
+2:      RND_XY2_EXPAND  1, lsl
+        .align 5
+3:      RND_XY2_EXPAND  2, lsl
+        .align 5
+4:      RND_XY2_EXPAND  3, lsl
+endfunc
+
+        .align 5
+function ff_put_no_rnd_pixels8_xy2_arm, export=1
+        @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h)
+        @ block = word aligned, pixles = unaligned
+        pld             [r1]
+        push            {r4-r11,lr}
+        JMP_ALIGN       r5,  r1
+1:      RND_XY2_EXPAND  0, lsr
+        .align 5
+2:      RND_XY2_EXPAND  1, lsr
+        .align 5
+3:      RND_XY2_EXPAND  2, lsr
+        .align 5
+4:      RND_XY2_EXPAND  3, lsr
+endfunc
diff --git a/libavcodec/arm/hpeldsp_arm.h b/libavcodec/arm/hpeldsp_arm.h
new file mode 100644
index 0000000..6b5c1ce
--- /dev/null
+++ b/libavcodec/arm/hpeldsp_arm.h
@@ -0,0 +1,27 @@
+/*
+ * 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_ARM_HPELDSP_H
+#define AVCODEC_ARM_HPELDSP_H
+
+#include "libavcodec/hpeldsp.h"
+
+void ff_hpeldsp_init_armv6(HpelDSPContext *c, int flags);
+void ff_hpeldsp_init_neon(HpelDSPContext *c, int flags);
+
+#endif /* AVCODEC_ARM_HPELDSP_H */
diff --git a/libavcodec/arm/hpeldsp_armv6.S b/libavcodec/arm/hpeldsp_armv6.S
new file mode 100644
index 0000000..a030d42
--- /dev/null
+++ b/libavcodec/arm/hpeldsp_armv6.S
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2009 Mans Rullgard <mans at mansr.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/arm/asm.S"
+
+.macro  call_2x_pixels  type, subp
+function ff_\type\()_pixels16\subp\()_armv6, export=1
+        push            {r0-r3, lr}
+        bl              ff_\type\()_pixels8\subp\()_armv6
+        pop             {r0-r3, lr}
+        add             r0,  r0,  #8
+        add             r1,  r1,  #8
+        b               ff_\type\()_pixels8\subp\()_armv6
+endfunc
+.endm
+
+call_2x_pixels          avg
+call_2x_pixels          put, _x2
+call_2x_pixels          put, _y2
+call_2x_pixels          put, _x2_no_rnd
+call_2x_pixels          put, _y2_no_rnd
+
+function ff_put_pixels16_armv6, export=1
+        push            {r4-r11}
+1:
+        ldr             r5,  [r1, #4]
+        ldr             r6,  [r1, #8]
+        ldr             r7,  [r1, #12]
+        ldr_post        r4,  r1,  r2
+        strd            r6,  r7,  [r0, #8]
+        ldr             r9,  [r1, #4]
+        strd_post       r4,  r5,  r0,  r2
+        ldr             r10, [r1, #8]
+        ldr             r11, [r1, #12]
+        ldr_post        r8,  r1,  r2
+        strd            r10, r11, [r0, #8]
+        subs            r3,  r3,  #2
+        strd_post       r8,  r9,  r0,  r2
+        bne             1b
+
+        pop             {r4-r11}
+        bx              lr
+endfunc
+
+function ff_put_pixels8_armv6, export=1
+        push            {r4-r7}
+1:
+        ldr             r5,  [r1, #4]
+        ldr_post        r4,  r1,  r2
+        ldr             r7,  [r1, #4]
+        strd_post       r4,  r5,  r0,  r2
+        ldr_post        r6,  r1,  r2
+        subs            r3,  r3,  #2
+        strd_post       r6,  r7,  r0,  r2
+        bne             1b
+
+        pop             {r4-r7}
+        bx              lr
+endfunc
+
+function ff_put_pixels8_x2_armv6, export=1
+        push            {r4-r11, lr}
+        mov             r12, #1
+        orr             r12, r12, r12, lsl #8
+        orr             r12, r12, r12, lsl #16
+1:
+        ldr             r4,  [r1]
+        subs            r3,  r3,  #2
+        ldr             r5,  [r1, #4]
+        ldr             r7,  [r1, #5]
+        lsr             r6,  r4,  #8
+        ldr_pre         r8,  r1,  r2
+        orr             r6,  r6,  r5,  lsl #24
+        ldr             r9,  [r1, #4]
+        ldr             r11, [r1, #5]
+        lsr             r10, r8,  #8
+        add             r1,  r1,  r2
+        orr             r10, r10, r9,  lsl #24
+        eor             r14, r4,  r6
+        uhadd8          r4,  r4,  r6
+        eor             r6,  r5,  r7
+        uhadd8          r5,  r5,  r7
+        and             r14, r14, r12
+        and             r6,  r6,  r12
+        uadd8           r4,  r4,  r14
+        eor             r14, r8,  r10
+        uadd8           r5,  r5,  r6
+        eor             r6,  r9,  r11
+        uhadd8          r8,  r8,  r10
+        and             r14, r14, r12
+        uhadd8          r9,  r9,  r11
+        and             r6,  r6,  r12
+        uadd8           r8,  r8,  r14
+        strd_post       r4,  r5,  r0,  r2
+        uadd8           r9,  r9,  r6
+        strd_post       r8,  r9,  r0,  r2
+        bne             1b
+
+        pop             {r4-r11, pc}
+endfunc
+
+function ff_put_pixels8_y2_armv6, export=1
+        push            {r4-r11}
+        mov             r12, #1
+        orr             r12, r12, r12, lsl #8
+        orr             r12, r12, r12, lsl #16
+        ldr             r4,  [r1]
+        ldr             r5,  [r1, #4]
+        ldr_pre         r6,  r1,  r2
+        ldr             r7,  [r1, #4]
+1:
+        subs            r3,  r3,  #2
+        uhadd8          r8,  r4,  r6
+        eor             r10, r4,  r6
+        uhadd8          r9,  r5,  r7
+        eor             r11, r5,  r7
+        and             r10, r10, r12
+        ldr_pre         r4,  r1,  r2
+        uadd8           r8,  r8,  r10
+        and             r11, r11, r12
+        uadd8           r9,  r9,  r11
+        ldr             r5,  [r1, #4]
+        uhadd8          r10, r4,  r6
+        eor             r6,  r4,  r6
+        uhadd8          r11, r5,  r7
+        and             r6,  r6,  r12
+        eor             r7,  r5,  r7
+        uadd8           r10, r10, r6
+        and             r7,  r7,  r12
+        ldr_pre         r6,  r1,  r2
+        uadd8           r11, r11, r7
+        strd_post       r8,  r9,  r0,  r2
+        ldr             r7,  [r1, #4]
+        strd_post       r10, r11, r0,  r2
+        bne             1b
+
+        pop             {r4-r11}
+        bx              lr
+endfunc
+
+function ff_put_pixels8_x2_no_rnd_armv6, export=1
+        push            {r4-r9, lr}
+1:
+        subs            r3,  r3,  #2
+        ldr             r4,  [r1]
+        ldr             r5,  [r1, #4]
+        ldr             r7,  [r1, #5]
+        ldr_pre         r8,  r1,  r2
+        ldr             r9,  [r1, #4]
+        ldr             r14, [r1, #5]
+        add             r1,  r1,  r2
+        lsr             r6,  r4,  #8
+        orr             r6,  r6,  r5,  lsl #24
+        lsr             r12, r8,  #8
+        orr             r12, r12, r9,  lsl #24
+        uhadd8          r4,  r4,  r6
+        uhadd8          r5,  r5,  r7
+        uhadd8          r8,  r8,  r12
+        uhadd8          r9,  r9,  r14
+        stm             r0,  {r4,r5}
+        add             r0,  r0,  r2
+        stm             r0,  {r8,r9}
+        add             r0,  r0,  r2
+        bne             1b
+
+        pop             {r4-r9, pc}
+endfunc
+
+function ff_put_pixels8_y2_no_rnd_armv6, export=1
+        push            {r4-r9, lr}
+        ldr             r4,  [r1]
+        ldr             r5,  [r1, #4]
+        ldr_pre         r6,  r1,  r2
+        ldr             r7,  [r1, #4]
+1:
+        subs            r3,  r3,  #2
+        uhadd8          r8,  r4,  r6
+        ldr_pre         r4,  r1,  r2
+        uhadd8          r9,  r5,  r7
+        ldr             r5,  [r1, #4]
+        uhadd8          r12, r4,  r6
+        ldr_pre         r6,  r1,  r2
+        uhadd8          r14, r5,  r7
+        ldr             r7,  [r1, #4]
+        stm             r0,  {r8,r9}
+        add             r0,  r0,  r2
+        stm             r0,  {r12,r14}
+        add             r0,  r0,  r2
+        bne             1b
+
+        pop             {r4-r9, pc}
+endfunc
+
+function ff_avg_pixels8_armv6, export=1
+        pld             [r1, r2]
+        push            {r4-r10, lr}
+        mov             lr,  #1
+        orr             lr,  lr,  lr,  lsl #8
+        orr             lr,  lr,  lr,  lsl #16
+        ldrd            r4,  r5,  [r0]
+        ldr             r10, [r1, #4]
+        ldr_post        r9,  r1,  r2
+        subs            r3,  r3,  #2
+1:
+        pld             [r1, r2]
+        eor             r8,  r4,  r9
+        uhadd8          r4,  r4,  r9
+        eor             r12, r5,  r10
+        ldrd_reg        r6,  r7,  r0,  r2
+        uhadd8          r5,  r5,  r10
+        and             r8,  r8,  lr
+        ldr             r10, [r1, #4]
+        and             r12, r12, lr
+        uadd8           r4,  r4,  r8
+        ldr_post        r9,  r1,  r2
+        eor             r8,  r6,  r9
+        uadd8           r5,  r5,  r12
+        pld             [r1, r2,  lsl #1]
+        eor             r12, r7,  r10
+        uhadd8          r6,  r6,  r9
+        strd_post       r4,  r5,  r0,  r2
+        uhadd8          r7,  r7,  r10
+        beq             2f
+        and             r8,  r8,  lr
+        ldrd_reg        r4,  r5,  r0,  r2
+        uadd8           r6,  r6,  r8
+        ldr             r10, [r1, #4]
+        and             r12, r12, lr
+        subs            r3,  r3,  #2
+        uadd8           r7,  r7,  r12
+        ldr_post        r9,  r1,  r2
+        strd_post       r6,  r7,  r0,  r2
+        b               1b
+2:
+        and             r8,  r8,  lr
+        and             r12, r12, lr
+        uadd8           r6,  r6,  r8
+        uadd8           r7,  r7,  r12
+        strd_post       r6,  r7,  r0,  r2
+
+        pop             {r4-r10, pc}
+endfunc
diff --git a/libavcodec/arm/hpeldsp_init_arm.c b/libavcodec/arm/hpeldsp_init_arm.c
new file mode 100644
index 0000000..8176afe
--- /dev/null
+++ b/libavcodec/arm/hpeldsp_init_arm.c
@@ -0,0 +1,71 @@
+/*
+ * ARM optimized DSP utils
+ * Copyright (c) 2001 Lionel Ulmer
+ *
+ * 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/arm/cpu.h"
+#include "libavutil/attributes.h"
+#include "libavcodec/rnd_avg.h"
+#include "hpeldsp_arm.h"
+
+void ff_put_pixels8_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+
+void ff_put_no_rnd_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+
+void ff_put_pixels16_arm(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
+
+CALL_2X_PIXELS(ff_put_pixels16_x2_arm,         ff_put_pixels8_x2_arm,        8)
+CALL_2X_PIXELS(ff_put_pixels16_y2_arm,         ff_put_pixels8_y2_arm,        8)
+CALL_2X_PIXELS(ff_put_pixels16_xy2_arm,        ff_put_pixels8_xy2_arm,       8)
+CALL_2X_PIXELS(ff_put_no_rnd_pixels16_x2_arm,  ff_put_no_rnd_pixels8_x2_arm, 8)
+CALL_2X_PIXELS(ff_put_no_rnd_pixels16_y2_arm,  ff_put_no_rnd_pixels8_y2_arm, 8)
+CALL_2X_PIXELS(ff_put_no_rnd_pixels16_xy2_arm, ff_put_no_rnd_pixels8_xy2_arm,8)
+
+av_cold void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    c->put_pixels_tab[0][0] = ff_put_pixels16_arm;
+    c->put_pixels_tab[0][1] = ff_put_pixels16_x2_arm;
+    c->put_pixels_tab[0][2] = ff_put_pixels16_y2_arm;
+    c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_arm;
+    c->put_pixels_tab[1][0] = ff_put_pixels8_arm;
+    c->put_pixels_tab[1][1] = ff_put_pixels8_x2_arm;
+    c->put_pixels_tab[1][2] = ff_put_pixels8_y2_arm;
+    c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_arm;
+
+    c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_arm;
+    c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_arm;
+    c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_arm;
+    c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_arm;
+    c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_arm;
+    c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_arm;
+    c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_arm;
+    c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_arm;
+
+    if (have_armv6(cpu_flags))
+        ff_hpeldsp_init_armv6(c, flags);
+    if (have_neon(cpu_flags))
+        ff_hpeldsp_init_neon(c, flags);
+}
diff --git a/libavcodec/arm/hpeldsp_init_armv6.c b/libavcodec/arm/hpeldsp_init_armv6.c
new file mode 100644
index 0000000..67a500d
--- /dev/null
+++ b/libavcodec/arm/hpeldsp_init_armv6.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009 Mans Rullgard <mans at mansr.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 <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "hpeldsp_arm.h"
+
+void ff_put_pixels16_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_x2_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_y2_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+
+void ff_put_pixels16_x2_no_rnd_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_y2_no_rnd_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+
+void ff_avg_pixels16_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+
+void ff_put_pixels8_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_x2_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_y2_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+
+void ff_put_pixels8_x2_no_rnd_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_y2_no_rnd_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+
+void ff_avg_pixels8_armv6(uint8_t *, const uint8_t *, ptrdiff_t, int);
+
+av_cold void ff_hpeldsp_init_armv6(HpelDSPContext *c, int flags)
+{
+    c->put_pixels_tab[0][0] = ff_put_pixels16_armv6;
+    c->put_pixels_tab[0][1] = ff_put_pixels16_x2_armv6;
+    c->put_pixels_tab[0][2] = ff_put_pixels16_y2_armv6;
+/*     c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_armv6; */
+    c->put_pixels_tab[1][0] = ff_put_pixels8_armv6;
+    c->put_pixels_tab[1][1] = ff_put_pixels8_x2_armv6;
+    c->put_pixels_tab[1][2] = ff_put_pixels8_y2_armv6;
+/*     c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_armv6; */
+
+    c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_armv6;
+    c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_armv6;
+    c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_armv6;
+/*     c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_armv6; */
+    c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_armv6;
+    c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_armv6;
+    c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_armv6;
+/*     c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_armv6; */
+
+    c->avg_pixels_tab[0][0] = ff_avg_pixels16_armv6;
+    c->avg_pixels_tab[1][0] = ff_avg_pixels8_armv6;
+}
diff --git a/libavcodec/arm/hpeldsp_init_neon.c b/libavcodec/arm/hpeldsp_init_neon.c
new file mode 100644
index 0000000..76d4eaf
--- /dev/null
+++ b/libavcodec/arm/hpeldsp_init_neon.c
@@ -0,0 +1,88 @@
+/*
+ * ARM NEON optimised DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.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 <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "hpeldsp_arm.h"
+
+void ff_put_pixels16_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_x2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_y2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_xy2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_x2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_y2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_xy2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_x2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_y2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_put_pixels8_xy2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+
+void ff_avg_pixels16_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_x2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_y2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_xy2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels8_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels8_x2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels8_y2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels8_xy2_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_x2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_y2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+void ff_avg_pixels16_xy2_no_rnd_neon(uint8_t *, const uint8_t *, ptrdiff_t, int);
+
+av_cold void ff_hpeldsp_init_neon(HpelDSPContext *c, int flags)
+{
+    c->put_pixels_tab[0][0] = ff_put_pixels16_neon;
+    c->put_pixels_tab[0][1] = ff_put_pixels16_x2_neon;
+    c->put_pixels_tab[0][2] = ff_put_pixels16_y2_neon;
+    c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_neon;
+    c->put_pixels_tab[1][0] = ff_put_pixels8_neon;
+    c->put_pixels_tab[1][1] = ff_put_pixels8_x2_neon;
+    c->put_pixels_tab[1][2] = ff_put_pixels8_y2_neon;
+    c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_neon;
+
+    c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_neon;
+    c->put_no_rnd_pixels_tab[0][1] = ff_put_pixels16_x2_no_rnd_neon;
+    c->put_no_rnd_pixels_tab[0][2] = ff_put_pixels16_y2_no_rnd_neon;
+    c->put_no_rnd_pixels_tab[0][3] = ff_put_pixels16_xy2_no_rnd_neon;
+    c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_neon;
+    c->put_no_rnd_pixels_tab[1][1] = ff_put_pixels8_x2_no_rnd_neon;
+    c->put_no_rnd_pixels_tab[1][2] = ff_put_pixels8_y2_no_rnd_neon;
+    c->put_no_rnd_pixels_tab[1][3] = ff_put_pixels8_xy2_no_rnd_neon;
+
+    c->avg_pixels_tab[0][0] = ff_avg_pixels16_neon;
+    c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_neon;
+    c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_neon;
+    c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_neon;
+    c->avg_pixels_tab[1][0] = ff_avg_pixels8_neon;
+    c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_neon;
+    c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_neon;
+    c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_neon;
+
+    c->avg_no_rnd_pixels_tab[0] = ff_avg_pixels16_neon;
+    c->avg_no_rnd_pixels_tab[1] = ff_avg_pixels16_x2_no_rnd_neon;
+    c->avg_no_rnd_pixels_tab[2] = ff_avg_pixels16_y2_no_rnd_neon;
+    c->avg_no_rnd_pixels_tab[3] = ff_avg_pixels16_xy2_no_rnd_neon;
+}
diff --git a/libavcodec/arm/hpeldsp_neon.S b/libavcodec/arm/hpeldsp_neon.S
new file mode 100644
index 0000000..90bc3cb
--- /dev/null
+++ b/libavcodec/arm/hpeldsp_neon.S
@@ -0,0 +1,410 @@
+/*
+ * ARM NEON optimised DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.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/arm/asm.S"
+
+.macro  pixels16        rnd=1, avg=0
+  .if \avg
+        mov             r12, r0
+  .endif
+1:      vld1.8          {q0},     [r1], r2
+        vld1.8          {q1},     [r1], r2
+        vld1.8          {q2},     [r1], r2
+        pld             [r1, r2, lsl #2]
+        vld1.8          {q3},     [r1], r2
+        pld             [r1]
+        pld             [r1, r2]
+        pld             [r1, r2, lsl #1]
+  .if \avg
+        vld1.8          {q8},     [r12,:128], r2
+        vrhadd.u8       q0,  q0,  q8
+        vld1.8          {q9},     [r12,:128], r2
+        vrhadd.u8       q1,  q1,  q9
+        vld1.8          {q10},    [r12,:128], r2
+        vrhadd.u8       q2,  q2,  q10
+        vld1.8          {q11},    [r12,:128], r2
+        vrhadd.u8       q3,  q3,  q11
+  .endif
+        subs            r3,  r3,  #4
+        vst1.64         {q0},     [r0,:128], r2
+        vst1.64         {q1},     [r0,:128], r2
+        vst1.64         {q2},     [r0,:128], r2
+        vst1.64         {q3},     [r0,:128], r2
+        bne             1b
+        bx              lr
+.endm
+
+.macro  pixels16_x2     rnd=1, avg=0
+1:      vld1.8          {d0-d2},  [r1], r2
+        vld1.8          {d4-d6},  [r1], r2
+        pld             [r1]
+        pld             [r1, r2]
+        subs            r3,  r3,  #2
+        vext.8          q1,  q0,  q1,  #1
+        avg             q0,  q0,  q1
+        vext.8          q3,  q2,  q3,  #1
+        avg             q2,  q2,  q3
+  .if \avg
+        vld1.8          {q1},     [r0,:128], r2
+        vld1.8          {q3},     [r0,:128]
+        vrhadd.u8       q0,  q0,  q1
+        vrhadd.u8       q2,  q2,  q3
+        sub             r0,  r0,  r2
+  .endif
+        vst1.8          {q0},     [r0,:128], r2
+        vst1.8          {q2},     [r0,:128], r2
+        bne             1b
+        bx              lr
+.endm
+
+.macro  pixels16_y2     rnd=1, avg=0
+        sub             r3,  r3,  #2
+        vld1.8          {q0},     [r1], r2
+        vld1.8          {q1},     [r1], r2
+1:      subs            r3,  r3,  #2
+        avg             q2,  q0,  q1
+        vld1.8          {q0},     [r1], r2
+        avg             q3,  q0,  q1
+        vld1.8          {q1},     [r1], r2
+        pld             [r1]
+        pld             [r1, r2]
+  .if \avg
+        vld1.8          {q8},     [r0,:128], r2
+        vld1.8          {q9},     [r0,:128]
+        vrhadd.u8       q2,  q2,  q8
+        vrhadd.u8       q3,  q3,  q9
+        sub             r0,  r0,  r2
+  .endif
+        vst1.8          {q2},     [r0,:128], r2
+        vst1.8          {q3},     [r0,:128], r2
+        bne             1b
+
+        avg             q2,  q0,  q1
+        vld1.8          {q0},     [r1], r2
+        avg             q3,  q0,  q1
+  .if \avg
+        vld1.8          {q8},     [r0,:128], r2
+        vld1.8          {q9},     [r0,:128]
+        vrhadd.u8       q2,  q2,  q8
+        vrhadd.u8       q3,  q3,  q9
+        sub             r0,  r0,  r2
+  .endif
+        vst1.8          {q2},     [r0,:128], r2
+        vst1.8          {q3},     [r0,:128], r2
+
+        bx              lr
+.endm
+
+.macro  pixels16_xy2    rnd=1, avg=0
+        sub             r3,  r3,  #2
+        vld1.8          {d0-d2},  [r1], r2
+        vld1.8          {d4-d6},  [r1], r2
+NRND    vmov.i16        q13, #1
+        pld             [r1]
+        pld             [r1, r2]
+        vext.8          q1,  q0,  q1,  #1
+        vext.8          q3,  q2,  q3,  #1
+        vaddl.u8        q8,  d0,  d2
+        vaddl.u8        q10, d1,  d3
+        vaddl.u8        q9,  d4,  d6
+        vaddl.u8        q11, d5,  d7
+1:      subs            r3,  r3,  #2
+        vld1.8          {d0-d2},  [r1], r2
+        vadd.u16        q12, q8,  q9
+        pld             [r1]
+NRND    vadd.u16        q12, q12, q13
+        vext.8          q15, q0,  q1,  #1
+        vadd.u16        q1 , q10, q11
+        shrn            d28, q12, #2
+NRND    vadd.u16        q1,  q1,  q13
+        shrn            d29, q1,  #2
+  .if \avg
+        vld1.8          {q8},     [r0,:128]
+        vrhadd.u8       q14, q14, q8
+  .endif
+        vaddl.u8        q8,  d0,  d30
+        vld1.8          {d2-d4},  [r1], r2
+        vaddl.u8        q10, d1,  d31
+        vst1.8          {q14},    [r0,:128], r2
+        vadd.u16        q12, q8,  q9
+        pld             [r1, r2]
+NRND    vadd.u16        q12, q12, q13
+        vext.8          q2,  q1,  q2,  #1
+        vadd.u16        q0,  q10, q11
+        shrn            d30, q12, #2
+NRND    vadd.u16        q0,  q0,  q13
+        shrn            d31, q0,  #2
+  .if \avg
+        vld1.8          {q9},     [r0,:128]
+        vrhadd.u8       q15, q15, q9
+  .endif
+        vaddl.u8        q9,  d2,  d4
+        vaddl.u8        q11, d3,  d5
+        vst1.8          {q15},    [r0,:128], r2
+        bgt             1b
+
+        vld1.8          {d0-d2},  [r1], r2
+        vadd.u16        q12, q8,  q9
+NRND    vadd.u16        q12, q12, q13
+        vext.8          q15, q0,  q1,  #1
+        vadd.u16        q1 , q10, q11
+        shrn            d28, q12, #2
+NRND    vadd.u16        q1,  q1,  q13
+        shrn            d29, q1,  #2
+  .if \avg
+        vld1.8          {q8},     [r0,:128]
+        vrhadd.u8       q14, q14, q8
+  .endif
+        vaddl.u8        q8,  d0,  d30
+        vaddl.u8        q10, d1,  d31
+        vst1.8          {q14},    [r0,:128], r2
+        vadd.u16        q12, q8,  q9
+NRND    vadd.u16        q12, q12, q13
+        vadd.u16        q0,  q10, q11
+        shrn            d30, q12, #2
+NRND    vadd.u16        q0,  q0,  q13
+        shrn            d31, q0,  #2
+  .if \avg
+        vld1.8          {q9},     [r0,:128]
+        vrhadd.u8       q15, q15, q9
+  .endif
+        vst1.8          {q15},    [r0,:128], r2
+
+        bx              lr
+.endm
+
+.macro  pixels8         rnd=1, avg=0
+1:      vld1.8          {d0},     [r1], r2
+        vld1.8          {d1},     [r1], r2
+        vld1.8          {d2},     [r1], r2
+        pld             [r1, r2, lsl #2]
+        vld1.8          {d3},     [r1], r2
+        pld             [r1]
+        pld             [r1, r2]
+        pld             [r1, r2, lsl #1]
+  .if \avg
+        vld1.8          {d4},     [r0,:64], r2
+        vrhadd.u8       d0,  d0,  d4
+        vld1.8          {d5},     [r0,:64], r2
+        vrhadd.u8       d1,  d1,  d5
+        vld1.8          {d6},     [r0,:64], r2
+        vrhadd.u8       d2,  d2,  d6
+        vld1.8          {d7},     [r0,:64], r2
+        vrhadd.u8       d3,  d3,  d7
+        sub             r0,  r0,  r2,  lsl #2
+  .endif
+        subs            r3,  r3,  #4
+        vst1.8          {d0},     [r0,:64], r2
+        vst1.8          {d1},     [r0,:64], r2
+        vst1.8          {d2},     [r0,:64], r2
+        vst1.8          {d3},     [r0,:64], r2
+        bne             1b
+        bx              lr
+.endm
+
+.macro  pixels8_x2      rnd=1, avg=0
+1:      vld1.8          {q0},     [r1], r2
+        vext.8          d1,  d0,  d1,  #1
+        vld1.8          {q1},     [r1], r2
+        vext.8          d3,  d2,  d3,  #1
+        pld             [r1]
+        pld             [r1, r2]
+        subs            r3,  r3,  #2
+        vswp            d1,  d2
+        avg             q0,  q0,  q1
+  .if \avg
+        vld1.8          {d4},     [r0,:64], r2
+        vld1.8          {d5},     [r0,:64]
+        vrhadd.u8       q0,  q0,  q2
+        sub             r0,  r0,  r2
+  .endif
+        vst1.8          {d0},     [r0,:64], r2
+        vst1.8          {d1},     [r0,:64], r2
+        bne             1b
+        bx              lr
+.endm
+
+.macro  pixels8_y2      rnd=1, avg=0
+        sub             r3,  r3,  #2
+        vld1.8          {d0},     [r1], r2
+        vld1.8          {d1},     [r1], r2
+1:      subs            r3,  r3,  #2
+        avg             d4,  d0,  d1
+        vld1.8          {d0},     [r1], r2
+        avg             d5,  d0,  d1
+        vld1.8          {d1},     [r1], r2
+        pld             [r1]
+        pld             [r1, r2]
+  .if \avg
+        vld1.8          {d2},     [r0,:64], r2
+        vld1.8          {d3},     [r0,:64]
+        vrhadd.u8       q2,  q2,  q1
+        sub             r0,  r0,  r2
+  .endif
+        vst1.8          {d4},     [r0,:64], r2
+        vst1.8          {d5},     [r0,:64], r2
+        bne             1b
+
+        avg             d4,  d0,  d1
+        vld1.8          {d0},     [r1], r2
+        avg             d5,  d0,  d1
+  .if \avg
+        vld1.8          {d2},     [r0,:64], r2
+        vld1.8          {d3},     [r0,:64]
+        vrhadd.u8       q2,  q2,  q1
+        sub             r0,  r0,  r2
+  .endif
+        vst1.8          {d4},     [r0,:64], r2
+        vst1.8          {d5},     [r0,:64], r2
+
+        bx              lr
+.endm
+
+.macro  pixels8_xy2     rnd=1, avg=0
+        sub             r3,  r3,  #2
+        vld1.8          {q0},     [r1], r2
+        vld1.8          {q1},     [r1], r2
+NRND    vmov.i16        q11, #1
+        pld             [r1]
+        pld             [r1, r2]
+        vext.8          d4,  d0,  d1,  #1
+        vext.8          d6,  d2,  d3,  #1
+        vaddl.u8        q8,  d0,  d4
+        vaddl.u8        q9,  d2,  d6
+1:      subs            r3,  r3,  #2
+        vld1.8          {q0},     [r1], r2
+        pld             [r1]
+        vadd.u16        q10, q8,  q9
+        vext.8          d4,  d0,  d1,  #1
+NRND    vadd.u16        q10, q10, q11
+        vaddl.u8        q8,  d0,  d4
+        shrn            d5,  q10, #2
+        vld1.8          {q1},     [r1], r2
+        vadd.u16        q10, q8,  q9
+        pld             [r1, r2]
+  .if \avg
+        vld1.8          {d7},     [r0,:64]
+        vrhadd.u8       d5,  d5,  d7
+  .endif
+NRND    vadd.u16        q10, q10, q11
+        vst1.8          {d5},     [r0,:64], r2
+        shrn            d7,  q10, #2
+  .if \avg
+        vld1.8          {d5},     [r0,:64]
+        vrhadd.u8       d7,  d7,  d5
+  .endif
+        vext.8          d6,  d2,  d3,  #1
+        vaddl.u8        q9,  d2,  d6
+        vst1.8          {d7},     [r0,:64], r2
+        bgt             1b
+
+        vld1.8          {q0},     [r1], r2
+        vadd.u16        q10, q8,  q9
+        vext.8          d4,  d0,  d1,  #1
+NRND    vadd.u16        q10, q10, q11
+        vaddl.u8        q8,  d0,  d4
+        shrn            d5,  q10, #2
+        vadd.u16        q10, q8,  q9
+  .if \avg
+        vld1.8          {d7},     [r0,:64]
+        vrhadd.u8       d5,  d5,  d7
+  .endif
+NRND    vadd.u16        q10, q10, q11
+        vst1.8          {d5},     [r0,:64], r2
+        shrn            d7,  q10, #2
+  .if \avg
+        vld1.8          {d5},     [r0,:64]
+        vrhadd.u8       d7,  d7,  d5
+  .endif
+        vst1.8          {d7},     [r0,:64], r2
+
+        bx              lr
+.endm
+
+.macro  pixfunc         pfx, name, suf, rnd=1, avg=0
+  .if \rnd
+    .macro avg  rd, rn, rm
+        vrhadd.u8       \rd, \rn, \rm
+    .endm
+    .macro shrn rd, rn, rm
+        vrshrn.u16      \rd, \rn, \rm
+    .endm
+    .macro NRND insn:vararg
+    .endm
+  .else
+    .macro avg  rd, rn, rm
+        vhadd.u8        \rd, \rn, \rm
+    .endm
+    .macro shrn rd, rn, rm
+        vshrn.u16       \rd, \rn, \rm
+    .endm
+    .macro NRND insn:vararg
+        \insn
+    .endm
+  .endif
+function ff_\pfx\name\suf\()_neon, export=1
+        \name           \rnd, \avg
+endfunc
+        .purgem         avg
+        .purgem         shrn
+        .purgem         NRND
+.endm
+
+.macro  pixfunc2        pfx, name, avg=0
+        pixfunc         \pfx, \name,          rnd=1, avg=\avg
+        pixfunc         \pfx, \name, _no_rnd, rnd=0, avg=\avg
+.endm
+
+function ff_put_h264_qpel16_mc00_neon, export=1
+        mov             r3,  #16
+endfunc
+
+        pixfunc         put_, pixels16,     avg=0
+        pixfunc2        put_, pixels16_x2,  avg=0
+        pixfunc2        put_, pixels16_y2,  avg=0
+        pixfunc2        put_, pixels16_xy2, avg=0
+
+function ff_avg_h264_qpel16_mc00_neon, export=1
+        mov             r3,  #16
+endfunc
+
+        pixfunc         avg_, pixels16,     avg=1
+        pixfunc2        avg_, pixels16_x2,  avg=1
+        pixfunc2        avg_, pixels16_y2,  avg=1
+        pixfunc2        avg_, pixels16_xy2, avg=1
+
+function ff_put_h264_qpel8_mc00_neon, export=1
+        mov             r3,  #8
+endfunc
+
+        pixfunc         put_, pixels8,     avg=0
+        pixfunc2        put_, pixels8_x2,  avg=0
+        pixfunc2        put_, pixels8_y2,  avg=0
+        pixfunc2        put_, pixels8_xy2, avg=0
+
+function ff_avg_h264_qpel8_mc00_neon, export=1
+        mov             r3,  #8
+endfunc
+
+        pixfunc         avg_, pixels8,     avg=1
+        pixfunc         avg_, pixels8_x2,  avg=1
+        pixfunc         avg_, pixels8_y2,  avg=1
+        pixfunc         avg_, pixels8_xy2, avg=1
diff --git a/libavcodec/arm/jrevdct_arm.S b/libavcodec/arm/jrevdct_arm.S
index 331ad85..f951e2a 100644
--- a/libavcodec/arm/jrevdct_arm.S
+++ b/libavcodec/arm/jrevdct_arm.S
@@ -66,7 +66,7 @@ row_loop:
         ldrsh r2, [lr, # 2]             @ r2 = 'd2'
 
         @ Optimization for row that have all items except the first set to 0
-        @ (this works as the DCTELEMS are always 4-byte aligned)
+        @ (this works as the int16_t are always 4-byte aligned)
         ldr r5, [lr, # 0]
         ldr r6, [lr, # 4]
         ldr r3, [lr, # 8]
diff --git a/libavcodec/arm/mdct_vfp.S b/libavcodec/arm/mdct_vfp.S
new file mode 100644
index 0000000..94db24f
--- /dev/null
+++ b/libavcodec/arm/mdct_vfp.S
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison at riscosopen.org>
+ *
+ * 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/arm/asm.S"
+
+CONTEXT .req    a1
+ORIGOUT .req    a2
+IN      .req    a3
+OUT     .req    v1
+REVTAB  .req    v2
+TCOS    .req    v3
+TSIN    .req    v4
+OLDFPSCR .req   v5
+J0      .req    a2
+J1      .req    a4
+J2      .req    ip
+J3      .req    lr
+
+.macro prerotation_innerloop
+ .set trig_lo, k
+ .set trig_hi, n4 - k - 2
+ .set in_lo, trig_lo * 2
+ .set in_hi, trig_hi * 2
+        vldr    d8, [TCOS, #trig_lo*4]          @ s16,s17
+        vldr    d9, [TCOS, #trig_hi*4]          @ s18,s19
+        vldr    s0, [IN, #in_hi*4 + 12]
+        vldr    s1, [IN, #in_hi*4 + 4]
+        vldr    s2, [IN, #in_lo*4 + 12]
+        vldr    s3, [IN, #in_lo*4 + 4]
+        vmul.f  s8, s0, s16                     @ vector operation
+        vldr    d10, [TSIN, #trig_lo*4]         @ s20,s21
+        vldr    d11, [TSIN, #trig_hi*4]         @ s22,s23
+        vldr    s4, [IN, #in_lo*4]
+        vldr    s5, [IN, #in_lo*4 + 8]
+        vldr    s6, [IN, #in_hi*4]
+        vldr    s7, [IN, #in_hi*4 + 8]
+        ldr     J0, [REVTAB, #trig_lo*2]
+        vmul.f  s12, s0, s20                    @ vector operation
+        ldr     J2, [REVTAB, #trig_hi*2]
+        mov     J1, J0, lsr #16
+        and     J0, J0, #255                    @ halfword value will be < n4
+        vmls.f  s8, s4, s20                     @ vector operation
+        mov     J3, J2, lsr #16
+        and     J2, J2, #255                    @ halfword value will be < n4
+        add     J0, OUT, J0, lsl #3
+        vmla.f  s12, s4, s16                    @ vector operation
+        add     J1, OUT, J1, lsl #3
+        add     J2, OUT, J2, lsl #3
+        add     J3, OUT, J3, lsl #3
+        vstr    s8, [J0]
+        vstr    s9, [J1]
+        vstr    s10, [J2]
+        vstr    s11, [J3]
+        vstr    s12, [J0, #4]
+        vstr    s13, [J1, #4]
+        vstr    s14, [J2, #4]
+        vstr    s15, [J3, #4]
+ .set k, k + 2
+.endm
+
+.macro postrotation_innerloop tail, head
+ .set trig_lo_head, n8 - k - 2
+ .set trig_hi_head, n8 + k
+ .set out_lo_head, trig_lo_head * 2
+ .set out_hi_head, trig_hi_head * 2
+ .set trig_lo_tail, n8 - (k - 2) - 2
+ .set trig_hi_tail, n8 + (k - 2)
+ .set out_lo_tail, trig_lo_tail * 2
+ .set out_hi_tail, trig_hi_tail * 2
+ .if (k & 2) == 0
+  TCOS_D0_HEAD .req d10 @ s20,s21
+  TCOS_D1_HEAD .req d11 @ s22,s23
+  TCOS_S0_TAIL .req s24
+ .else
+  TCOS_D0_HEAD .req d12 @ s24,s25
+  TCOS_D1_HEAD .req d13 @ s26,s27
+  TCOS_S0_TAIL .req s20
+ .endif
+ .ifnc "\tail",""
+        vmls.f  s8, s0, TCOS_S0_TAIL        @ vector operation
+ .endif
+ .ifnc "\head",""
+        vldr    d8, [TSIN, #trig_lo_head*4] @ s16,s17
+        vldr    d9, [TSIN, #trig_hi_head*4] @ s18,s19
+        vldr    TCOS_D0_HEAD, [TCOS, #trig_lo_head*4]
+ .endif
+ .ifnc "\tail",""
+        vmla.f  s12, s4, TCOS_S0_TAIL       @ vector operation
+ .endif
+ .ifnc "\head",""
+        vldr    s0, [OUT, #out_lo_head*4]
+        vldr    s1, [OUT, #out_lo_head*4 + 8]
+        vldr    s2, [OUT, #out_hi_head*4]
+        vldr    s3, [OUT, #out_hi_head*4 + 8]
+        vldr    s4, [OUT, #out_lo_head*4 + 4]
+        vldr    s5, [OUT, #out_lo_head*4 + 12]
+        vldr    s6, [OUT, #out_hi_head*4 + 4]
+        vldr    s7, [OUT, #out_hi_head*4 + 12]
+ .endif
+ .ifnc "\tail",""
+        vstr    s8, [OUT, #out_lo_tail*4]
+        vstr    s9, [OUT, #out_lo_tail*4 + 8]
+        vstr    s10, [OUT, #out_hi_tail*4]
+        vstr    s11, [OUT, #out_hi_tail*4 + 8]
+ .endif
+ .ifnc "\head",""
+        vmul.f  s8, s4, s16                 @ vector operation
+ .endif
+ .ifnc "\tail",""
+        vstr    s12, [OUT, #out_hi_tail*4 + 12]
+        vstr    s13, [OUT, #out_hi_tail*4 + 4]
+        vstr    s14, [OUT, #out_lo_tail*4 + 12]
+        vstr    s15, [OUT, #out_lo_tail*4 + 4]
+ .endif
+ .ifnc "\head",""
+        vmul.f  s12, s0, s16                @ vector operation
+        vldr    TCOS_D1_HEAD, [TCOS, #trig_hi_head*4]
+ .endif
+ .unreq TCOS_D0_HEAD
+ .unreq TCOS_D1_HEAD
+ .unreq TCOS_S0_TAIL
+ .ifnc "\head",""
+  .set k, k + 2
+ .endif
+.endm
+
+
+/* void ff_imdct_half_vfp(FFTContext *s,
+ *                        FFTSample *output,
+ *                        const FFTSample *input)
+ */
+function ff_imdct_half_vfp, export=1
+        ldr     ip, [CONTEXT, #5*4]         @ mdct_bits
+        teq     ip, #6
+        it      ne
+        bne     X(ff_imdct_half_c)          @ only case currently accelerated is the one used by DCA
+
+ .set n, 1<<6
+ .set n2, n/2
+ .set n4, n/4
+ .set n8, n/8
+
+        push    {v1-v5,lr}
+        vpush   {s16-s27}
+        fmrx    OLDFPSCR, FPSCR
+        ldr     lr, =0x03030000             @ RunFast mode, short vectors of length 4, stride 1
+        fmxr    FPSCR, lr
+        mov     OUT, ORIGOUT
+        ldr     REVTAB, [CONTEXT, #2*4]
+        ldr     TCOS, [CONTEXT, #6*4]
+        ldr     TSIN, [CONTEXT, #7*4]
+
+ .set k, 0
+ .rept n8/2
+        prerotation_innerloop
+ .endr
+
+        fmxr    FPSCR, OLDFPSCR
+        mov     a1, OUT
+        bl      X(ff_fft16_vfp)
+        ldr     lr, =0x03030000             @ RunFast mode, short vectors of length 4, stride 1
+        fmxr    FPSCR, lr
+
+ .set k, 0
+        postrotation_innerloop , head
+ .rept n8/2 - 1
+        postrotation_innerloop tail, head
+ .endr
+        postrotation_innerloop tail
+
+        fmxr    FPSCR, OLDFPSCR
+        vpop    {s16-s27}
+        pop     {v1-v5,pc}
+endfunc
+
+        .unreq  CONTEXT
+        .unreq  ORIGOUT
+        .unreq  IN
+        .unreq  OUT
+        .unreq  REVTAB
+        .unreq  TCOS
+        .unreq  TSIN
+        .unreq  OLDFPSCR
+        .unreq  J0
+        .unreq  J1
+        .unreq  J2
+        .unreq  J3
diff --git a/libavcodec/arm/mpegaudiodsp_init_arm.c b/libavcodec/arm/mpegaudiodsp_init_arm.c
index a9804e9..e73aee6 100644
--- a/libavcodec/arm/mpegaudiodsp_init_arm.c
+++ b/libavcodec/arm/mpegaudiodsp_init_arm.c
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/mpegaudiodsp.h"
 #include "config.h"
@@ -27,7 +28,7 @@
 void ff_mpadsp_apply_window_fixed_armv6(int32_t *synth_buf, int32_t *window,
                                         int *dither, int16_t *out, int incr);
 
-void ff_mpadsp_init_arm(MPADSPContext *s)
+av_cold void ff_mpadsp_init_arm(MPADSPContext *s)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/mpegvideo_arm.c b/libavcodec/arm/mpegvideo_arm.c
index cce90c7..0c04688 100644
--- a/libavcodec/arm/mpegvideo_arm.c
+++ b/libavcodec/arm/mpegvideo_arm.c
@@ -20,7 +20,6 @@
 
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "mpegvideo_arm.h"
 #include "asm-offsets.h"
@@ -34,12 +33,12 @@ CHK_OFFS(MpegEncContext, inter_scantable.raster_end, INTER_SCANTAB_RASTER_END);
 CHK_OFFS(MpegEncContext, h263_aic,         H263_AIC);
 #endif
 
-void ff_dct_unquantize_h263_inter_neon(MpegEncContext *s, DCTELEM *block,
+void ff_dct_unquantize_h263_inter_neon(MpegEncContext *s, int16_t *block,
                                        int n, int qscale);
-void ff_dct_unquantize_h263_intra_neon(MpegEncContext *s, DCTELEM *block,
+void ff_dct_unquantize_h263_intra_neon(MpegEncContext *s, int16_t *block,
                                        int n, int qscale);
 
-void ff_MPV_common_init_arm(MpegEncContext *s)
+av_cold void ff_MPV_common_init_arm(MpegEncContext *s)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/mpegvideo_armv5te.c b/libavcodec/arm/mpegvideo_armv5te.c
index f6839dd..2066cbc 100644
--- a/libavcodec/arm/mpegvideo_armv5te.c
+++ b/libavcodec/arm/mpegvideo_armv5te.c
@@ -19,12 +19,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "mpegvideo_arm.h"
 
-void ff_dct_unquantize_h263_armv5te(DCTELEM *block, int qmul, int qadd, int count);
+void ff_dct_unquantize_h263_armv5te(int16_t *block, int qmul, int qadd, int count);
 
 #ifdef ENABLE_ARM_TESTS
 /**
@@ -32,7 +32,7 @@ void ff_dct_unquantize_h263_armv5te(DCTELEM *block, int qmul, int qadd, int coun
  * have optimized implementations for each architecture. Is also used as a reference
  * implementation in regression tests
  */
-static inline void dct_unquantize_h263_helper_c(DCTELEM *block, int qmul, int qadd, int count)
+static inline void dct_unquantize_h263_helper_c(int16_t *block, int qmul, int qadd, int count)
 {
     int i, level;
     for (i = 0; i < count; i++) {
@@ -50,7 +50,7 @@ static inline void dct_unquantize_h263_helper_c(DCTELEM *block, int qmul, int qa
 #endif
 
 static void dct_unquantize_h263_intra_armv5te(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     int level, qmul, qadd;
     int nCoeffs;
@@ -79,7 +79,7 @@ static void dct_unquantize_h263_intra_armv5te(MpegEncContext *s,
 }
 
 static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     int qmul, qadd;
     int nCoeffs;
@@ -94,7 +94,7 @@ static void dct_unquantize_h263_inter_armv5te(MpegEncContext *s,
     ff_dct_unquantize_h263_armv5te(block, qmul, qadd, nCoeffs + 1);
 }
 
-void ff_MPV_common_init_armv5te(MpegEncContext *s)
+av_cold void ff_MPV_common_init_armv5te(MpegEncContext *s)
 {
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_armv5te;
     s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_armv5te;
diff --git a/libavcodec/arm/rv34dsp_init_arm.c b/libavcodec/arm/rv34dsp_init_arm.c
index 07f5598..5ce787b 100644
--- a/libavcodec/arm/rv34dsp_init_arm.c
+++ b/libavcodec/arm/rv34dsp_init_arm.c
@@ -20,18 +20,19 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/rv34dsp.h"
 #include "libavutil/arm/cpu.h"
 
-void ff_rv34_inv_transform_noround_neon(DCTELEM *block);
+void ff_rv34_inv_transform_noround_neon(int16_t *block);
 
-void ff_rv34_inv_transform_noround_dc_neon(DCTELEM *block);
+void ff_rv34_inv_transform_noround_dc_neon(int16_t *block);
 
-void ff_rv34_idct_add_neon(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
+void ff_rv34_idct_add_neon(uint8_t *dst, ptrdiff_t stride, int16_t *block);
 void ff_rv34_idct_dc_add_neon(uint8_t *dst, ptrdiff_t stride, int dc);
 
-void ff_rv34dsp_init_arm(RV34DSPContext *c, DSPContext* dsp)
+av_cold void ff_rv34dsp_init_arm(RV34DSPContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
diff --git a/libavcodec/arm/rv34dsp_neon.S b/libavcodec/arm/rv34dsp_neon.S
index 522e387..a29123f 100644
--- a/libavcodec/arm/rv34dsp_neon.S
+++ b/libavcodec/arm/rv34dsp_neon.S
@@ -67,7 +67,7 @@
         vsub.s32        q15, q14, q9    @ z0 - z3
 .endm
 
-/* void rv34_idct_add_c(uint8_t *dst, int stride, DCTELEM *block) */
+/* void rv34_idct_add_c(uint8_t *dst, int stride, int16_t *block) */
 function ff_rv34_idct_add_neon, export=1
         mov             r3,  r0
         rv34_inv_transform   r2
@@ -97,7 +97,7 @@ function ff_rv34_idct_add_neon, export=1
         bx              lr
 endfunc
 
-/* void rv34_inv_transform_noround_neon(DCTELEM *block); */
+/* void rv34_inv_transform_noround_neon(int16_t *block); */
 function ff_rv34_inv_transform_noround_neon, export=1
         rv34_inv_transform   r0
         vshl.s32        q11, q2,  #1
@@ -142,7 +142,7 @@ function ff_rv34_idct_dc_add_neon, export=1
         bx              lr
 endfunc
 
-/* void rv34_inv_transform_dc_noround_c(DCTELEM *block) */
+/* void rv34_inv_transform_dc_noround_c(int16_t *block) */
 function ff_rv34_inv_transform_noround_dc_neon, export=1
         vld1.16         {d28[]}, [r0,:16]       @ block[0]
         vmov.i16        d4,  #251
diff --git a/libavcodec/arm/rv40dsp_init_arm.c b/libavcodec/arm/rv40dsp_init_arm.c
index 83f4355..6ad60fa 100644
--- a/libavcodec/arm/rv40dsp_init_arm.c
+++ b/libavcodec/arm/rv40dsp_init_arm.c
@@ -20,13 +20,14 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/rv34dsp.h"
 #include "libavutil/arm/cpu.h"
 
 #define DECL_QPEL3(type, w, pos) \
     void ff_##type##_rv40_qpel##w##_mc##pos##_neon(uint8_t *dst, uint8_t *src,\
-                                                   int stride)
+                                                   ptrdiff_t stride)
 #define DECL_QPEL2(w, pos)                      \
     DECL_QPEL3(put, w, pos);                    \
     DECL_QPEL3(avg, w, pos)
@@ -69,7 +70,7 @@ void ff_rv40_v_weak_loop_filter_neon(uint8_t *src, ptrdiff_t stride, int filter_
                                      int filter_q1, int alpha, int beta,
                                      int lim_p0q0, int lim_q1, int lim_p1);
 
-static void ff_rv40dsp_init_neon(RV34DSPContext *c)
+static av_cold void rv40dsp_init_neon(RV34DSPContext *c)
 {
     c->put_pixels_tab[0][ 1] = ff_put_rv40_qpel16_mc10_neon;
     c->put_pixels_tab[0][ 3] = ff_put_rv40_qpel16_mc30_neon;
@@ -138,10 +139,10 @@ static void ff_rv40dsp_init_neon(RV34DSPContext *c)
     c->rv40_weak_loop_filter[1]     = ff_rv40_v_weak_loop_filter_neon;
 }
 
-void ff_rv40dsp_init_arm(RV34DSPContext *c, DSPContext* dsp)
+av_cold void ff_rv40dsp_init_arm(RV34DSPContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
     if (have_neon(cpu_flags))
-        ff_rv40dsp_init_neon(c);
+        rv40dsp_init_neon(c);
 }
diff --git a/libavcodec/arm/simple_idct_arm.S b/libavcodec/arm/simple_idct_arm.S
index 8ba6c48..8227898 100644
--- a/libavcodec/arm/simple_idct_arm.S
+++ b/libavcodec/arm/simple_idct_arm.S
@@ -83,7 +83,7 @@ __row_loop:
         orrs r5, r5, r7          @ R5=R4 | R3 | R2 | R7
         beq __almost_empty_row
 
-__b_evaluation:
+@@ __b_evaluation:
         @@ at this point, R0=block (temp),  R1(free), R2=ROWr32[1], R3=ROWr32[2], R4=ROWr32[3],
         @@     R5=(temp), R6=ROWr16[0], R7=ROWr16[1], R8-R11 free,
         @@     R12=__const_ptr_, R14=&block[n]
@@ -159,7 +159,7 @@ __end_b_evaluation:
         @@     R5=b2, R6=ROWr16[0], R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
         @@     R12=__const_ptr_, R14=&block[n]
 
-__a_evaluation:
+@@ __a_evaluation:
         @@ a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
         @@ a1 = a0 + W6 * row[2];
         @@ a2 = a0 - W6 * row[2];
@@ -295,7 +295,7 @@ __end_row_loop:
         add r14, r0, #14        @ R14=&block[7], better start from the last col, and decrease the value until col=0, i.e. R14=block.
 __col_loop:
 
-__b_evaluation2:
+@@ __b_evaluation2:
         @@ at this point, R0=block (temp),  R1-R11 (free)
         @@     R12=__const_ptr_, R14=&block[n]
         @@ proceed with b0-b3 first, followed by a0-a3
@@ -357,12 +357,12 @@ __b_evaluation2:
         it    ne
         mlane r1, r10, r4, r1    @ R1-=W5*ROWr16[7x8]=b1
         @@ R4 is free now
-__end_b_evaluation2:
+@@ __end_b_evaluation2:
         @@ at this point, R0=b0,  R1=b1, R2 (free), R3 (free), R4 (free),
         @@     R5=b2, R6 (free), R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
         @@     R12=__const_ptr_, R14=&block[n]
 
-__a_evaluation2:
+@@ __a_evaluation2:
         @@ a0 = (W4 * col[8x0]) + (1 << (COL_SHIFT - 1));
         @@ a1 = a0 + W6 * row[2];
         @@ a2 = a0 - W6 * row[2];
@@ -414,7 +414,7 @@ __a_evaluation2:
         itt   ne
         subne r2, r2, r10        @ R2-=W2*ROWr16[6] (a1)
         addne r3, r3, r10        @ R3+=W2*ROWr16[6] (a2)
-__end_a_evaluation2:
+@@ __end_a_evaluation2:
         @@ at this point, R0=b0,  R1=b1, R2=a1, R3=a2, R4=a3,
         @@     R5=b2, R6=a0, R7=b3, R8 (free), R9 (free), R10 (free), R11 (free),
         @@     R12=__const_ptr_, R14=&block[n]
@@ -452,7 +452,7 @@ __end_a_evaluation2:
         strh r8, [r14, #96]
         strh r9, [r14, #112]
 
-__end_col_loop:
+@@ __end_col_loop:
         @@ at this point, R0-R11 (free)
         @@     R12=__const_ptr_, R14=&block[n]
         ldr r0, [sp, #0]         @ R0=block
@@ -463,7 +463,7 @@ __end_col_loop:
 
 
 
-__end_simple_idct_arm:
+@@ __end_simple_idct_arm:
         @@ restore registers to previous status!
         add sp, sp, #8 @@ the local variables!
         ldmfd sp!, {r4-r11, r15} @@ update PC with LR content.
diff --git a/libavcodec/arm/simple_idct_armv6.S b/libavcodec/arm/simple_idct_armv6.S
index 0342b06..6072346 100644
--- a/libavcodec/arm/simple_idct_armv6.S
+++ b/libavcodec/arm/simple_idct_armv6.S
@@ -375,7 +375,7 @@ endfunc
         sub    r0, r0, #(16*7)
         .endm
 
-/* void ff_simple_idct_armv6(DCTELEM *data); */
+/* void ff_simple_idct_armv6(int16_t *data); */
 function ff_simple_idct_armv6, export=1
         push   {r4-r11, lr}
         sub    sp, sp, #128
@@ -390,7 +390,7 @@ function ff_simple_idct_armv6, export=1
         pop    {r4-r11, pc}
 endfunc
 
-/* ff_simple_idct_add_armv6(uint8_t *dest, int line_size, DCTELEM *data); */
+/* ff_simple_idct_add_armv6(uint8_t *dest, int line_size, int16_t *data); */
 function ff_simple_idct_add_armv6, export=1
         push   {r0, r1, r4-r11, lr}
         sub    sp, sp, #128
@@ -407,7 +407,7 @@ function ff_simple_idct_add_armv6, export=1
         pop    {r4-r11, pc}
 endfunc
 
-/* ff_simple_idct_put_armv6(uint8_t *dest, int line_size, DCTELEM *data); */
+/* ff_simple_idct_put_armv6(uint8_t *dest, int line_size, int16_t *data); */
 function ff_simple_idct_put_armv6, export=1
         push   {r0, r1, r4-r11, lr}
         sub    sp, sp, #128
diff --git a/libavcodec/arm/simple_idct_neon.S b/libavcodec/arm/simple_idct_neon.S
index b3e97d5..a1cde8d 100644
--- a/libavcodec/arm/simple_idct_neon.S
+++ b/libavcodec/arm/simple_idct_neon.S
@@ -261,7 +261,7 @@ endconst
         pop             {r4-r7, pc}
         .endm
 
-/* void ff_simple_idct_put_neon(uint8_t *dst, int line_size, DCTELEM *data); */
+/* void ff_simple_idct_put_neon(uint8_t *dst, int line_size, int16_t *data); */
 function ff_simple_idct_put_neon, export=1
         idct_start      r2
 
@@ -316,7 +316,7 @@ function idct_col4_add8_neon
         bx              lr
 endfunc
 
-/* void ff_simple_idct_add_neon(uint8_t *dst, int line_size, DCTELEM *data); */
+/* void ff_simple_idct_add_neon(uint8_t *dst, int line_size, int16_t *data); */
 function ff_simple_idct_add_neon, export=1
         idct_start      r2
 
@@ -355,7 +355,7 @@ function idct_col4_st16_neon
         bx              lr
 endfunc
 
-/* void ff_simple_idct_neon(DCTELEM *data); */
+/* void ff_simple_idct_neon(int16_t *data); */
 function ff_simple_idct_neon, export=1
         idct_start      r0
 
diff --git a/libavcodec/arm/synth_filter_vfp.S b/libavcodec/arm/synth_filter_vfp.S
new file mode 100644
index 0000000..e6e6408
--- /dev/null
+++ b/libavcodec/arm/synth_filter_vfp.S
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2013 RISC OS Open Ltd
+ * Author: Ben Avison <bavison at riscosopen.org>
+ *
+ * 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/arm/asm.S"
+
+IMDCT         .req    r0
+ORIG_P_SB     .req    r1
+P_SB_OFF      .req    r2
+I             .req    r0
+P_SB2_UP      .req    r1
+OLDFPSCR      .req    r2
+P_SB2_DN      .req    r3
+P_WIN_DN      .req    r4
+P_OUT_DN      .req    r5
+P_SB          .req    r6
+J_WRAP        .req    r7
+P_WIN_UP      .req    r12
+P_OUT_UP      .req    r14
+
+SCALE         .req    s0
+SBUF_DAT_REV0 .req    s4
+SBUF_DAT_REV1 .req    s5
+SBUF_DAT_REV2 .req    s6
+SBUF_DAT_REV3 .req    s7
+VA0           .req    s8
+VA3           .req    s11
+VB0           .req    s12
+VB3           .req    s15
+VC0           .req    s8
+VC3           .req    s11
+VD0           .req    s12
+VD3           .req    s15
+SBUF_DAT0     .req    s16
+SBUF_DAT1     .req    s17
+SBUF_DAT2     .req    s18
+SBUF_DAT3     .req    s19
+SBUF_DAT_ALT0 .req    s20
+SBUF_DAT_ALT1 .req    s21
+SBUF_DAT_ALT2 .req    s22
+SBUF_DAT_ALT3 .req    s23
+WIN_DN_DAT0   .req    s24
+WIN_UP_DAT0   .req    s28
+
+
+.macro inner_loop  half, tail, head
+ .if (OFFSET & (64*4)) == 0                @ even numbered call
+        SBUF_DAT_THIS0 .req SBUF_DAT0
+        SBUF_DAT_THIS1 .req SBUF_DAT1
+        SBUF_DAT_THIS2 .req SBUF_DAT2
+        SBUF_DAT_THIS3 .req SBUF_DAT3
+  .ifnc "\head",""
+        vldr    d8, [P_SB, #OFFSET]        @ d8 = SBUF_DAT
+        vldr    d9, [P_SB, #OFFSET+8]
+  .endif
+ .else
+        SBUF_DAT_THIS0 .req SBUF_DAT_ALT0
+        SBUF_DAT_THIS1 .req SBUF_DAT_ALT1
+        SBUF_DAT_THIS2 .req SBUF_DAT_ALT2
+        SBUF_DAT_THIS3 .req SBUF_DAT_ALT3
+  .ifnc "\head",""
+        vldr    d10, [P_SB, #OFFSET]       @ d10 = SBUF_DAT_ALT
+        vldr    d11, [P_SB, #OFFSET+8]
+  .endif
+ .endif
+ .ifnc "\tail",""
+  .ifc "\half","ab"
+        vmls.f  VA0, SBUF_DAT_REV0, WIN_DN_DAT0  @ all operands treated as vectors
+  .else
+        vmla.f  VD0, SBUF_DAT_REV0, WIN_DN_DAT0  @ all operands treated as vectors
+  .endif
+ .endif
+ .ifnc "\head",""
+        vldr    d14, [P_WIN_UP, #OFFSET]   @ d14 = WIN_UP_DAT
+        vldr    d15, [P_WIN_UP, #OFFSET+8]
+        vldr    d12, [P_WIN_DN, #OFFSET]   @ d12 = WIN_DN_DAT
+        vldr    d13, [P_WIN_DN, #OFFSET+8]
+        vmov    SBUF_DAT_REV3, SBUF_DAT_THIS0
+        vmov    SBUF_DAT_REV2, SBUF_DAT_THIS1
+        vmov    SBUF_DAT_REV1, SBUF_DAT_THIS2
+        vmov    SBUF_DAT_REV0, SBUF_DAT_THIS3
+  .ifc "\half","ab"
+        vmla.f  VB0, SBUF_DAT_THIS0, WIN_UP_DAT0
+  .else
+        vmla.f  VC0, SBUF_DAT_THIS0, WIN_UP_DAT0
+  .endif
+        teq     J_WRAP, #J
+        bne     2f             @ strongly predictable, so better than cond exec in this case
+        sub     P_SB, P_SB, #512*4
+2:
+  .set J, J - 64
+  .set OFFSET, OFFSET + 64*4
+ .endif
+        .unreq  SBUF_DAT_THIS0
+        .unreq  SBUF_DAT_THIS1
+        .unreq  SBUF_DAT_THIS2
+        .unreq  SBUF_DAT_THIS3
+.endm
+
+
+/* void ff_synth_filter_float_vfp(FFTContext *imdct,
+ *                                float *synth_buf_ptr, int *synth_buf_offset,
+ *                                float synth_buf2[32], const float window[512],
+ *                                float out[32], const float in[32], float scale)
+ */
+function ff_synth_filter_float_vfp, export=1
+        push    {r3-r7,lr}
+        vpush   {s16-s31}
+        ldr     lr, [P_SB_OFF]
+        add     a2, ORIG_P_SB, lr, LSL #2 @ calculate synth_buf to pass to imdct_half
+        mov     P_SB, a2                  @ and keep a copy for ourselves
+        bic     J_WRAP, lr, #63           @ mangled to make testing for wrap easier in inner loop
+        sub     lr, lr, #32
+        and     lr, lr, #512-32
+        str     lr, [P_SB_OFF]            @ rotate offset, modulo buffer size, ready for next call
+        ldr     a3, [sp, #(16+6+2)*4]     @ fetch in from stack, to pass to imdct_half
+VFP     vmov    s16, SCALE                @ imdct_half is free to corrupt s0, but it contains one of our arguments in hardfp case
+        bl      X(ff_imdct_half_vfp)
+VFP     vmov    SCALE, s16
+
+        fmrx    OLDFPSCR, FPSCR
+        ldr     lr, =0x03030000           @ RunFast mode, short vectors of length 4, stride 1
+        fmxr    FPSCR, lr
+        ldr     P_SB2_DN, [sp, #16*4]
+        ldr     P_WIN_DN, [sp, #(16+6+0)*4]
+        ldr     P_OUT_DN, [sp, #(16+6+1)*4]
+NOVFP   vldr    SCALE, [sp, #(16+6+3)*4]
+
+#define IMM_OFF_SKEW 956                   /* also valid immediate constant when you add 16*4 */
+        add     P_SB, P_SB, #IMM_OFF_SKEW  @ so we can use -ve offsets to use full immediate offset range
+        add     P_SB2_UP, P_SB2_DN, #16*4
+        add     P_WIN_UP, P_WIN_DN, #16*4+IMM_OFF_SKEW
+        add     P_OUT_UP, P_OUT_DN, #16*4
+        add     P_SB2_DN, P_SB2_DN, #16*4
+        add     P_WIN_DN, P_WIN_DN, #12*4+IMM_OFF_SKEW
+        add     P_OUT_DN, P_OUT_DN, #16*4
+        mov     I, #4
+1:
+        vldmia  P_SB2_UP!, {VB0-VB3}
+        vldmdb  P_SB2_DN!, {VA0-VA3}
+ .set J, 512 - 64
+ .set OFFSET, -IMM_OFF_SKEW
+        inner_loop  ab,, head
+ .rept 7
+        inner_loop  ab, tail, head
+ .endr
+        inner_loop  ab, tail
+        add     P_WIN_UP, P_WIN_UP, #4*4
+        sub     P_WIN_DN, P_WIN_DN, #4*4
+        vmul.f  VB0, VB0, SCALE      @ SCALE treated as scalar
+        add     P_SB, P_SB, #(512+4)*4
+        subs    I, I, #1
+        vmul.f  VA0, VA0, SCALE
+        vstmia  P_OUT_UP!, {VB0-VB3}
+        vstmdb  P_OUT_DN!, {VA0-VA3}
+        bne     1b
+
+        add     P_SB2_DN, P_SB2_DN, #(16+28-12)*4
+        sub     P_SB2_UP, P_SB2_UP, #(16+16)*4
+        add     P_WIN_DN, P_WIN_DN, #(32+16+28-12)*4
+        mov     I, #4
+1:
+        vldr.d  d4, zero             @ d4 = VC0
+        vldr.d  d5, zero
+        vldr.d  d6, zero             @ d6 = VD0
+        vldr.d  d7, zero
+ .set J, 512 - 64
+ .set OFFSET, -IMM_OFF_SKEW
+        inner_loop  cd,, head
+ .rept 7
+        inner_loop  cd, tail, head
+ .endr
+        inner_loop  cd, tail
+        add     P_WIN_UP, P_WIN_UP, #4*4
+        sub     P_WIN_DN, P_WIN_DN, #4*4
+        add     P_SB, P_SB, #(512+4)*4
+        subs    I, I, #1
+        vstmia  P_SB2_UP!, {VC0-VC3}
+        vstmdb  P_SB2_DN!, {VD0-VD3}
+        bne     1b
+
+        fmxr    FPSCR, OLDFPSCR
+        vpop    {s16-s31}
+        pop     {r3-r7,pc}
+endfunc
+
+        .unreq  IMDCT
+        .unreq  ORIG_P_SB
+        .unreq  P_SB_OFF
+        .unreq  I
+        .unreq  P_SB2_UP
+        .unreq  OLDFPSCR
+        .unreq  P_SB2_DN
+        .unreq  P_WIN_DN
+        .unreq  P_OUT_DN
+        .unreq  P_SB
+        .unreq  J_WRAP
+        .unreq  P_WIN_UP
+        .unreq  P_OUT_UP
+
+        .unreq  SCALE
+        .unreq  SBUF_DAT_REV0
+        .unreq  SBUF_DAT_REV1
+        .unreq  SBUF_DAT_REV2
+        .unreq  SBUF_DAT_REV3
+        .unreq  VA0
+        .unreq  VA3
+        .unreq  VB0
+        .unreq  VB3
+        .unreq  VC0
+        .unreq  VC3
+        .unreq  VD0
+        .unreq  VD3
+        .unreq  SBUF_DAT0
+        .unreq  SBUF_DAT1
+        .unreq  SBUF_DAT2
+        .unreq  SBUF_DAT3
+        .unreq  SBUF_DAT_ALT0
+        .unreq  SBUF_DAT_ALT1
+        .unreq  SBUF_DAT_ALT2
+        .unreq  SBUF_DAT_ALT3
+        .unreq  WIN_DN_DAT0
+        .unreq  WIN_UP_DAT0
+
+        .align  3
+zero:   .word   0, 0
diff --git a/libavcodec/arm/videodsp_init_arm.c b/libavcodec/arm/videodsp_init_arm.c
index 6c97b2c..20c6e4a 100644
--- a/libavcodec/arm/videodsp_init_arm.c
+++ b/libavcodec/arm/videodsp_init_arm.c
@@ -18,11 +18,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/videodsp.h"
 #include "videodsp_arm.h"
 
-void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc)
+av_cold void ff_videodsp_init_arm(VideoDSPContext *ctx, int bpc)
 {
     int cpu_flags = av_get_cpu_flags();
     if (have_armv5te(cpu_flags)) ff_videodsp_init_armv5te(ctx, bpc);
diff --git a/libavcodec/arm/videodsp_init_armv5te.c b/libavcodec/arm/videodsp_init_armv5te.c
index a7b8b23..832191f 100644
--- a/libavcodec/arm/videodsp_init_armv5te.c
+++ b/libavcodec/arm/videodsp_init_armv5te.c
@@ -18,13 +18,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
-#include <libavcodec/videodsp.h>
+#include "libavcodec/videodsp.h"
 #include "videodsp_arm.h"
 
 void ff_prefetch_arm(uint8_t *mem, ptrdiff_t stride, int h);
 
-void ff_videodsp_init_armv5te(VideoDSPContext *ctx, int bpc)
+av_cold void ff_videodsp_init_armv5te(VideoDSPContext *ctx, int bpc)
 {
     ctx->prefetch = ff_prefetch_arm;
 }
diff --git a/libavcodec/arm/vorbisdsp_init_arm.c b/libavcodec/arm/vorbisdsp_init_arm.c
new file mode 100644
index 0000000..853ba2d
--- /dev/null
+++ b/libavcodec/arm/vorbisdsp_init_arm.c
@@ -0,0 +1,37 @@
+/*
+ * ARM NEON optimised DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.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/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/vorbisdsp.h"
+
+void ff_vorbis_inverse_coupling_neon(float *mag, float *ang,
+                                     intptr_t blocksize);
+
+av_cold void ff_vorbisdsp_init_arm(VorbisDSPContext *c)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_neon(cpu_flags)) {
+        c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_neon;
+    }
+}
diff --git a/libavcodec/arm/vorbisdsp_neon.S b/libavcodec/arm/vorbisdsp_neon.S
new file mode 100644
index 0000000..7df876c
--- /dev/null
+++ b/libavcodec/arm/vorbisdsp_neon.S
@@ -0,0 +1,83 @@
+/*
+ * ARM NEON optimised DSP functions
+ * Copyright (c) 2008 Mans Rullgard <mans at mansr.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/arm/asm.S"
+
+function ff_vorbis_inverse_coupling_neon, export=1
+        vmov.i32        q10, #1<<31
+        subs            r2,  r2,  #4
+        mov             r3,  r0
+        mov             r12, r1
+        beq             3f
+
+        vld1.32         {d24-d25},[r1,:128]!
+        vld1.32         {d22-d23},[r0,:128]!
+        vcle.s32        q8,  q12, #0
+        vand            q9,  q11, q10
+        veor            q12, q12, q9
+        vand            q2,  q12, q8
+        vbic            q3,  q12, q8
+        vadd.f32        q12, q11, q2
+        vsub.f32        q11, q11, q3
+1:      vld1.32         {d2-d3},  [r1,:128]!
+        vld1.32         {d0-d1},  [r0,:128]!
+        vcle.s32        q8,  q1,  #0
+        vand            q9,  q0,  q10
+        veor            q1,  q1,  q9
+        vst1.32         {d24-d25},[r3, :128]!
+        vst1.32         {d22-d23},[r12,:128]!
+        vand            q2,  q1,  q8
+        vbic            q3,  q1,  q8
+        vadd.f32        q1,  q0,  q2
+        vsub.f32        q0,  q0,  q3
+        subs            r2,  r2,  #8
+        ble             2f
+        vld1.32         {d24-d25},[r1,:128]!
+        vld1.32         {d22-d23},[r0,:128]!
+        vcle.s32        q8,  q12, #0
+        vand            q9,  q11, q10
+        veor            q12, q12, q9
+        vst1.32         {d2-d3},  [r3, :128]!
+        vst1.32         {d0-d1},  [r12,:128]!
+        vand            q2,  q12, q8
+        vbic            q3,  q12, q8
+        vadd.f32        q12, q11, q2
+        vsub.f32        q11, q11, q3
+        b               1b
+
+2:      vst1.32         {d2-d3},  [r3, :128]!
+        vst1.32         {d0-d1},  [r12,:128]!
+        it              lt
+        bxlt            lr
+
+3:      vld1.32         {d2-d3},  [r1,:128]
+        vld1.32         {d0-d1},  [r0,:128]
+        vcle.s32        q8,  q1,  #0
+        vand            q9,  q0,  q10
+        veor            q1,  q1,  q9
+        vand            q2,  q1,  q8
+        vbic            q3,  q1,  q8
+        vadd.f32        q1,  q0,  q2
+        vsub.f32        q0,  q0,  q3
+        vst1.32         {d2-d3},  [r0,:128]!
+        vst1.32         {d0-d1},  [r1,:128]!
+        bx              lr
+endfunc
diff --git a/libavcodec/arm/vp3dsp_init_arm.c b/libavcodec/arm/vp3dsp_init_arm.c
index ea99bfd..dfd6078 100644
--- a/libavcodec/arm/vp3dsp_init_arm.c
+++ b/libavcodec/arm/vp3dsp_init_arm.c
@@ -21,11 +21,12 @@
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/arm/cpu.h"
+#include "libavcodec/dsputil.h"
 #include "libavcodec/vp3dsp.h"
 
-void ff_vp3_idct_put_neon(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_vp3_idct_add_neon(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_vp3_idct_dc_add_neon(uint8_t *dest, int line_size, const DCTELEM *data);
+void ff_vp3_idct_put_neon(uint8_t *dest, int line_size, int16_t *data);
+void ff_vp3_idct_add_neon(uint8_t *dest, int line_size, int16_t *data);
+void ff_vp3_idct_dc_add_neon(uint8_t *dest, int line_size, const int16_t *data);
 
 void ff_vp3_v_loop_filter_neon(uint8_t *, int, int *);
 void ff_vp3_h_loop_filter_neon(uint8_t *, int, int *);
@@ -40,6 +41,5 @@ av_cold void ff_vp3dsp_init_arm(VP3DSPContext *c, int flags)
         c->idct_dc_add   = ff_vp3_idct_dc_add_neon;
         c->v_loop_filter = ff_vp3_v_loop_filter_neon;
         c->h_loop_filter = ff_vp3_h_loop_filter_neon;
-        c->idct_perm     = FF_TRANSPOSE_IDCT_PERM;
     }
 }
diff --git a/libavcodec/arm/vp3dsp_neon.S b/libavcodec/arm/vp3dsp_neon.S
index e09de57..e5ecfc3 100644
--- a/libavcodec/arm/vp3dsp_neon.S
+++ b/libavcodec/arm/vp3dsp_neon.S
@@ -108,14 +108,20 @@ endfunc
 
 function vp3_idct_start_neon
     vpush           {d8-d15}
+    vmov.i16        q4,  #0
+    vmov.i16        q5,  #0
     movrel          r3,  vp3_idct_constants
     vld1.64         {d0-d1},   [r3,:128]
-    vld1.64         {d16-d19}, [r2,:128]!
-    vld1.64         {d20-d23}, [r2,:128]!
-    vld1.64         {d24-d27}, [r2,:128]!
+    vld1.64         {d16-d19}, [r2,:128]
+    vst1.64         {q4-q5},   [r2,:128]!
+    vld1.64         {d20-d23}, [r2,:128]
+    vst1.64         {q4-q5},   [r2,:128]!
+    vld1.64         {d24-d27}, [r2,:128]
+    vst1.64         {q4-q5},   [r2,:128]!
     vadd.s16        q1,  q8,  q12
     vsub.s16        q8,  q8,  q12
-    vld1.64         {d28-d31}, [r2,:128]!
+    vld1.64         {d28-d31}, [r2,:128]
+    vst1.64         {q4-q5},   [r2,:128]!
 
 vp3_idct_core_neon:
     vmull.s16       q2,  d18, xC1S7     // (ip[1] * C1) << 16
@@ -345,10 +351,12 @@ function ff_vp3_idct_add_neon, export=1
 endfunc
 
 function ff_vp3_idct_dc_add_neon, export=1
-    ldrsh           r2,  [r2]
+    ldrsh           r12, [r2]
     mov             r3,  r0
-    add             r2,  r2,  #15
-    vdup.16         q15, r2
+    add             r12, r12,  #15
+    vdup.16         q15, r12
+    mov             r12, 0
+    strh            r12, [r2]
     vshr.s16        q15, q15, #5
 
     vld1.8          {d0}, [r0,:64], r1
diff --git a/libavcodec/arm/vp56dsp_init_arm.c b/libavcodec/arm/vp56dsp_init_arm.c
deleted file mode 100644
index afa5070..0000000
--- a/libavcodec/arm/vp56dsp_init_arm.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010 Mans Rullgard <mans at mansr.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 <stdint.h>
-
-#include "libavutil/arm/cpu.h"
-#include "libavcodec/avcodec.h"
-#include "libavcodec/vp56dsp.h"
-
-void ff_vp6_edge_filter_hor_neon(uint8_t *yuv, int stride, int t);
-void ff_vp6_edge_filter_ver_neon(uint8_t *yuv, int stride, int t);
-
-void ff_vp56dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec)
-{
-    int cpu_flags = av_get_cpu_flags();
-
-    if (codec != AV_CODEC_ID_VP5 && have_neon(cpu_flags)) {
-        s->edge_filter_hor = ff_vp6_edge_filter_hor_neon;
-        s->edge_filter_ver = ff_vp6_edge_filter_ver_neon;
-    }
-}
diff --git a/libavcodec/arm/vp6dsp_init_arm.c b/libavcodec/arm/vp6dsp_init_arm.c
new file mode 100644
index 0000000..4ec41ed
--- /dev/null
+++ b/libavcodec/arm/vp6dsp_init_arm.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010 Mans Rullgard <mans at mansr.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 <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/arm/cpu.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/vp56dsp.h"
+
+void ff_vp6_edge_filter_hor_neon(uint8_t *yuv, int stride, int t);
+void ff_vp6_edge_filter_ver_neon(uint8_t *yuv, int stride, int t);
+
+av_cold void ff_vp6dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (have_neon(cpu_flags)) {
+        s->edge_filter_hor = ff_vp6_edge_filter_hor_neon;
+        s->edge_filter_ver = ff_vp6_edge_filter_ver_neon;
+    }
+}
diff --git a/libavcodec/arm/vp56dsp_neon.S b/libavcodec/arm/vp6dsp_neon.S
similarity index 100%
rename from libavcodec/arm/vp56dsp_neon.S
rename to libavcodec/arm/vp6dsp_neon.S
diff --git a/libavcodec/arm/vp8.h b/libavcodec/arm/vp8.h
index 5ce17a4..cd3428b 100644
--- a/libavcodec/arm/vp8.h
+++ b/libavcodec/arm/vp8.h
@@ -19,11 +19,15 @@
 #ifndef AVCODEC_ARM_VP8_H
 #define AVCODEC_ARM_VP8_H
 
+#include <stdint.h>
+
 #include "config.h"
+#include "libavcodec/vp56.h"
+#include "libavcodec/vp8.h"
 
 #if HAVE_ARMV6_EXTERNAL
 #define decode_block_coeffs_internal ff_decode_block_coeffs_armv6
-int ff_decode_block_coeffs_armv6(VP56RangeCoder *rc, DCTELEM block[16],
+int ff_decode_block_coeffs_armv6(VP56RangeCoder *rc, int16_t block[16],
                                  uint8_t probs[8][3][NUM_DCT_TOKENS-1],
                                  int i, uint8_t *token_prob, int16_t qmul[2]);
 #endif
diff --git a/libavcodec/arm/vp8dsp_armv6.S b/libavcodec/arm/vp8dsp_armv6.S
index 4047aab..5207758 100644
--- a/libavcodec/arm/vp8dsp_armv6.S
+++ b/libavcodec/arm/vp8dsp_armv6.S
@@ -56,7 +56,7 @@
 
 @ idct
 
-@ void vp8_luma_dc_wht(DCTELEM block[4][4][16], DCTELEM dc[16])
+@ void vp8_luma_dc_wht(int16_t block[4][4][16], int16_t dc[16])
 function ff_vp8_luma_dc_wht_armv6, export=1
         push            {r4-r10, lr}
 
@@ -179,7 +179,7 @@ function ff_vp8_luma_dc_wht_armv6, export=1
         pop             {r4-r10, pc}
 endfunc
 
-@ void vp8_luma_dc_wht_dc(DCTELEM block[4][4][16], DCTELEM dc[16])
+@ void vp8_luma_dc_wht_dc(int16_t block[4][4][16], int16_t dc[16])
 function ff_vp8_luma_dc_wht_dc_armv6, export=1
         ldrsh           r2,  [r1]
         mov             r3,  #0
@@ -192,7 +192,7 @@ function ff_vp8_luma_dc_wht_dc_armv6, export=1
         bx              lr
 endfunc
 
-@ void vp8_idct_add(uint8_t *dst, DCTELEM block[16], int stride)
+@ void vp8_idct_add(uint8_t *dst, int16_t block[16], int stride)
 function ff_vp8_idct_add_armv6, export=1
         push            {r4-r12, lr}
         sub             sp,  sp,  #32
@@ -314,7 +314,7 @@ function ff_vp8_idct_add_armv6, export=1
         pop             {r4-r12, pc}
 endfunc
 
-@ void vp8_idct_dc_add(uint8_t *dst, DCTELEM block[16], int stride)
+@ void vp8_idct_dc_add(uint8_t *dst, int16_t block[16], int stride)
 function ff_vp8_idct_dc_add_armv6, export=1
         push            {r4-r6, lr}
         add             r6,  r0,  r2,  lsl #1
@@ -355,7 +355,7 @@ function ff_vp8_idct_dc_add_armv6, export=1
         pop             {r4-r6, pc}
 endfunc
 
-@ void vp8_idct_dc_add4uv(uint8_t *dst, DCTELEM block[4][16], int stride)
+@ void vp8_idct_dc_add4uv(uint8_t *dst, int16_t block[4][16], int stride)
 function ff_vp8_idct_dc_add4uv_armv6, export=1
         push            {r4, lr}
 
@@ -371,7 +371,7 @@ function ff_vp8_idct_dc_add4uv_armv6, export=1
         pop             {r4, pc}
 endfunc
 
-@ void vp8_idct_dc_add4y(uint8_t *dst, DCTELEM block[4][16], int stride)
+@ void vp8_idct_dc_add4y(uint8_t *dst, int16_t block[4][16], int stride)
 function ff_vp8_idct_dc_add4y_armv6, export=1
         push            {r4, lr}
 
diff --git a/libavcodec/arm/vp8dsp_init_arm.c b/libavcodec/arm/vp8dsp_init_arm.c
index 603f68c..b7897cd 100644
--- a/libavcodec/arm/vp8dsp_init_arm.c
+++ b/libavcodec/arm/vp8dsp_init_arm.c
@@ -18,6 +18,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/arm/cpu.h"
 #include "libavcodec/vp8dsp.h"
 #include "vp8dsp.h"
diff --git a/libavcodec/arm/vp8dsp_init_armv6.c b/libavcodec/arm/vp8dsp_init_armv6.c
index 85a803a..e15e191 100644
--- a/libavcodec/arm/vp8dsp_init_armv6.c
+++ b/libavcodec/arm/vp8dsp_init_armv6.c
@@ -17,16 +17,18 @@
  */
 
 #include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "libavcodec/vp8dsp.h"
 #include "vp8dsp.h"
 
-void ff_vp8_luma_dc_wht_armv6(DCTELEM block[4][4][16], DCTELEM dc[16]);
-void ff_vp8_luma_dc_wht_dc_armv6(DCTELEM block[4][4][16], DCTELEM dc[16]);
+void ff_vp8_luma_dc_wht_armv6(int16_t block[4][4][16], int16_t dc[16]);
+void ff_vp8_luma_dc_wht_dc_armv6(int16_t block[4][4][16], int16_t dc[16]);
 
-void ff_vp8_idct_add_armv6(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add_armv6(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4y_armv6(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4uv_armv6(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
+void ff_vp8_idct_add_armv6(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add_armv6(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4y_armv6(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4uv_armv6(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride);
 
 VP8_LF(armv6);
 
diff --git a/libavcodec/arm/vp8dsp_init_neon.c b/libavcodec/arm/vp8dsp_init_neon.c
index dbe5b9f..0468181 100644
--- a/libavcodec/arm/vp8dsp_init_neon.c
+++ b/libavcodec/arm/vp8dsp_init_neon.c
@@ -17,15 +17,17 @@
  */
 
 #include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "libavcodec/vp8dsp.h"
 #include "vp8dsp.h"
 
-void ff_vp8_luma_dc_wht_neon(DCTELEM block[4][4][16], DCTELEM dc[16]);
+void ff_vp8_luma_dc_wht_neon(int16_t block[4][4][16], int16_t dc[16]);
 
-void ff_vp8_idct_add_neon(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add_neon(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
-void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride);
+void ff_vp8_idct_add_neon(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add_neon(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride);
+void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride);
 
 VP8_LF(neon);
 
diff --git a/libavcodec/ass.c b/libavcodec/ass.c
index 3585b93..098050a 100644
--- a/libavcodec/ass.c
+++ b/libavcodec/ass.c
@@ -39,11 +39,11 @@
  *                  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)
+static int 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];
 
@@ -69,14 +69,14 @@ static int ff_ass_subtitle_header(AVCodecContext *avctx,
 
 int ff_ass_subtitle_header_default(AVCodecContext *avctx)
 {
-    return ff_ass_subtitle_header(avctx, ASS_DEFAULT_FONT,
-                                         ASS_DEFAULT_FONT_SIZE,
-                                         ASS_DEFAULT_COLOR,
-                                         ASS_DEFAULT_BACK_COLOR,
-                                         ASS_DEFAULT_BOLD,
-                                         ASS_DEFAULT_ITALIC,
-                                         ASS_DEFAULT_UNDERLINE,
-                                         ASS_DEFAULT_ALIGNMENT);
+    return ass_subtitle_header(avctx, ASS_DEFAULT_FONT,
+                               ASS_DEFAULT_FONT_SIZE,
+                               ASS_DEFAULT_COLOR,
+                               ASS_DEFAULT_BACK_COLOR,
+                               ASS_DEFAULT_BOLD,
+                               ASS_DEFAULT_ITALIC,
+                               ASS_DEFAULT_UNDERLINE,
+                               ASS_DEFAULT_ALIGNMENT);
 }
 
 void ff_ass_init(AVSubtitle *sub)
diff --git a/libavcodec/asv.c b/libavcodec/asv.c
index b15182d..9e3a023 100644
--- a/libavcodec/asv.c
+++ b/libavcodec/asv.c
@@ -27,7 +27,6 @@
 
 #include "asv.h"
 #include "avcodec.h"
-#include "dsputil.h"
 
 const uint8_t ff_asv_scantab[64] = {
     0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19,
@@ -90,6 +89,5 @@ av_cold void ff_asv_common_init(AVCodecContext *avctx) {
     a->mb_width2  = (avctx->width  + 0) / 16;
     a->mb_height2 = (avctx->height + 0) / 16;
 
-    avctx->coded_frame= &a->picture;
     a->avctx= avctx;
 }
diff --git a/libavcodec/asv.h b/libavcodec/asv.h
index 3440f93..3e56857 100644
--- a/libavcodec/asv.h
+++ b/libavcodec/asv.h
@@ -28,7 +28,6 @@
 
 #include <stdint.h>
 
-#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 
 #include "avcodec.h"
@@ -39,7 +38,6 @@
 typedef struct ASV1Context{
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame picture;
     PutBitContext pb;
     GetBitContext gb;
     ScanTable scantable;
@@ -48,7 +46,7 @@ typedef struct ASV1Context{
     int mb_height;
     int mb_width2;
     int mb_height2;
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
     uint16_t intra_matrix[64];
     int q_intra_matrix[64];
     uint8_t *bitstream_buffer;
@@ -62,6 +60,6 @@ extern const uint8_t ff_asv_dc_ccp_tab[8][2];
 extern const uint8_t ff_asv_ac_ccp_tab[16][2];
 extern const uint8_t ff_asv2_level_tab[63][2];
 
-av_cold void ff_asv_common_init(AVCodecContext *avctx);
+void ff_asv_common_init(AVCodecContext *avctx);
 
 #endif /* AVCODEC_ASV_H */
diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
index d3579de..f160434 100644
--- a/libavcodec/asvdec.c
+++ b/libavcodec/asvdec.c
@@ -29,14 +29,10 @@
 #include "asv.h"
 #include "avcodec.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "mathops.h"
 #include "mpeg12data.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
 #define VLC_BITS 6
 #define ASV2_LEVEL_VLC_BITS 10
 
@@ -97,7 +93,7 @@ static inline int asv2_get_level(GetBitContext *gb)
         return code - 31;
 }
 
-static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64])
+static inline int asv1_decode_block(ASV1Context *a, int16_t block[64])
 {
     int i;
 
@@ -111,7 +107,7 @@ static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64])
                 break;
             if (ccp < 0 || i >= 10) {
                 av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
             if (ccp & 8)
@@ -128,7 +124,7 @@ static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64])
     return 0;
 }
 
-static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64])
+static inline int asv2_decode_block(ASV1Context *a, int16_t block[64])
 {
     int i, count, ccp;
 
@@ -164,7 +160,7 @@ static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64])
     return 0;
 }
 
-static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64])
+static inline int decode_mb(ASV1Context *a, int16_t block[6][64])
 {
     int i;
 
@@ -184,14 +180,14 @@ static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64])
     return 0;
 }
 
-static inline void idct_put(ASV1Context *a, int mb_x, int mb_y)
+static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y)
 {
-    DCTELEM (*block)[64] = a->block;
-    int linesize         = a->picture.linesize[0];
+    int16_t (*block)[64] = a->block;
+    int linesize         = frame->linesize[0];
 
-    uint8_t *dest_y  = a->picture.data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
-    uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
+    uint8_t *dest_y  = frame->data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
 
     a->dsp.idct_put(dest_y                 , linesize, block[0]);
     a->dsp.idct_put(dest_y              + 8, linesize, block[1]);
@@ -199,8 +195,8 @@ static inline void idct_put(ASV1Context *a, int mb_x, int mb_y)
     a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
 
     if (!(a->avctx->flags&CODEC_FLAG_GRAY)) {
-        a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
-        a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
+        a->dsp.idct_put(dest_cb, frame->linesize[1], block[4]);
+        a->dsp.idct_put(dest_cr, frame->linesize[2], block[5]);
     }
 }
 
@@ -211,17 +207,12 @@ static int decode_frame(AVCodecContext *avctx,
     ASV1Context * const a = avctx->priv_data;
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
-    AVFrame *picture      = data;
-    AVFrame * const p     = &a->picture;
-    int mb_x, mb_y;
-
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    AVFrame * const p     = data;
+    int mb_x, mb_y, ret;
 
-    p->reference = 0;
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
@@ -243,34 +234,33 @@ static int decode_frame(AVCodecContext *avctx,
 
     for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
         for (mb_x = 0; mb_x < a->mb_width2; mb_x++) {
-            if (decode_mb(a, a->block) < 0)
-                return -1;
+            if ((ret = decode_mb(a, a->block)) < 0)
+                return ret;
 
-            idct_put(a, mb_x, mb_y);
+            idct_put(a, p, mb_x, mb_y);
         }
     }
 
     if (a->mb_width2 != a->mb_width) {
         mb_x = a->mb_width2;
         for (mb_y = 0; mb_y < a->mb_height2; mb_y++) {
-            if (decode_mb(a, a->block) < 0)
-                return -1;
+            if ((ret = decode_mb(a, a->block)) < 0)
+                return ret;
 
-            idct_put(a, mb_x, mb_y);
+            idct_put(a, p, mb_x, mb_y);
         }
     }
 
     if (a->mb_height2 != a->mb_height) {
         mb_y = a->mb_height2;
         for (mb_x = 0; mb_x < a->mb_width; mb_x++) {
-            if (decode_mb(a, a->block) < 0)
-                return -1;
+            if ((ret = decode_mb(a, a->block)) < 0)
+                return ret;
 
-            idct_put(a, mb_x, mb_y);
+            idct_put(a, p, mb_x, mb_y);
         }
     }
 
-    *picture   = a->picture;
     *got_frame = 1;
 
     emms_c();
@@ -281,7 +271,6 @@ static int decode_frame(AVCodecContext *avctx,
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     ASV1Context * const a = avctx->priv_data;
-    AVFrame *p            = &a->picture;
     const int scale       = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
     int i;
 
@@ -310,11 +299,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
         a->intra_matrix[i] = 64 * scale * ff_mpeg1_default_intra_matrix[index] / a->inv_qscale;
     }
 
-    p->qstride      = a->mb_width;
-    p->qscale_table = av_malloc(p->qstride * a->mb_height);
-    p->quality      = (32 * scale + a->inv_qscale / 2) / a->inv_qscale;
-    memset(p->qscale_table, p->quality, p->qstride * a->mb_height);
-
     return 0;
 }
 
@@ -323,17 +307,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
     ASV1Context * const a = avctx->priv_data;
 
     av_freep(&a->bitstream_buffer);
-    av_freep(&a->picture.qscale_table);
     a->bitstream_buffer_size = 0;
 
-    if (a->picture.data[0])
-        avctx->release_buffer(avctx, &a->picture);
-
     return 0;
 }
 
 AVCodec ff_asv1_decoder = {
     .name           = "asv1",
+    .long_name      = NULL_IF_CONFIG_SMALL("ASUS V1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ASV1,
     .priv_data_size = sizeof(ASV1Context),
@@ -341,11 +322,11 @@ AVCodec ff_asv1_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ASUS V1"),
 };
 
 AVCodec ff_asv2_decoder = {
     .name           = "asv2",
+    .long_name      = NULL_IF_CONFIG_SMALL("ASUS V2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ASV2,
     .priv_data_size = sizeof(ASV1Context),
@@ -353,6 +334,5 @@ AVCodec ff_asv2_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ASUS V2"),
 };
 
diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c
index f36f3ef..40257f0 100644
--- a/libavcodec/asvenc.c
+++ b/libavcodec/asvenc.c
@@ -55,7 +55,7 @@ static inline void asv2_put_level(PutBitContext *pb, int level){
     }
 }
 
-static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){
+static inline void asv1_encode_block(ASV1Context *a, int16_t block[64]){
     int i;
     int nc_count=0;
 
@@ -88,7 +88,7 @@ static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){
     put_bits(&a->pb, ff_asv_ccp_tab[16][1], ff_asv_ccp_tab[16][0]);
 }
 
-static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){
+static inline void asv2_encode_block(ASV1Context *a, int16_t block[64]){
     int i;
     int count=0;
 
@@ -129,7 +129,7 @@ static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){
 
 #define MAX_MB_SIZE (30*16*16*3/2/8)
 
-static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){
+static inline int encode_mb(ASV1Context *a, int16_t block[6][64]){
     int i;
 
     if (a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < MAX_MB_SIZE) {
@@ -147,14 +147,16 @@ static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){
     return 0;
 }
 
-static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
-    DCTELEM (*block)[64]= a->block;
-    int linesize= a->picture.linesize[0];
+static inline void dct_get(ASV1Context *a, const AVFrame *frame,
+                           int mb_x, int mb_y)
+{
+    int16_t (*block)[64]= a->block;
+    int linesize = frame->linesize[0];
     int i;
 
-    uint8_t *ptr_y  = a->picture.data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
-    uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
-    uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
+    uint8_t *ptr_y  = frame->data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
+    uint8_t *ptr_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
+    uint8_t *ptr_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
 
     a->dsp.get_pixels(block[0], ptr_y                 , linesize);
     a->dsp.get_pixels(block[1], ptr_y              + 8, linesize);
@@ -164,8 +166,8 @@ static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
         a->dsp.fdct(block[i]);
 
     if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
-        a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]);
-        a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]);
+        a->dsp.get_pixels(block[4], ptr_cb, frame->linesize[1]);
+        a->dsp.get_pixels(block[5], ptr_cr, frame->linesize[2]);
         for(i=4; i<6; i++)
             a->dsp.fdct(block[i]);
     }
@@ -175,7 +177,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *pict, int *got_packet)
 {
     ASV1Context * const a = avctx->priv_data;
-    AVFrame * const p= &a->picture;
     int size, ret;
     int mb_x, mb_y;
 
@@ -188,13 +189,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
     init_put_bits(&a->pb, pkt->data, pkt->size);
 
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
-
     for(mb_y=0; mb_y<a->mb_height2; mb_y++){
         for(mb_x=0; mb_x<a->mb_width2; mb_x++){
-            dct_get(a, mb_x, mb_y);
+            dct_get(a, pict, mb_x, mb_y);
             encode_mb(a, a->block);
         }
     }
@@ -202,7 +199,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     if(a->mb_width2 != a->mb_width){
         mb_x= a->mb_width2;
         for(mb_y=0; mb_y<a->mb_height2; mb_y++){
-            dct_get(a, mb_x, mb_y);
+            dct_get(a, pict, mb_x, mb_y);
             encode_mb(a, a->block);
         }
     }
@@ -210,7 +207,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     if(a->mb_height2 != a->mb_height){
         mb_y= a->mb_height2;
         for(mb_x=0; mb_x<a->mb_width; mb_x++){
-            dct_get(a, mb_x, mb_y);
+            dct_get(a, pict, mb_x, mb_y);
             encode_mb(a, a->block);
         }
     }
@@ -242,6 +239,12 @@ static av_cold int encode_init(AVCodecContext *avctx){
     int i;
     const int scale= avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
 
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+
     ff_asv_common_init(avctx);
 
     if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE;
@@ -264,6 +267,7 @@ static av_cold int encode_init(AVCodecContext *avctx){
 #if CONFIG_ASV1_ENCODER
 AVCodec ff_asv1_encoder = {
     .name           = "asv1",
+    .long_name      = NULL_IF_CONFIG_SMALL("ASUS V1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ASV1,
     .priv_data_size = sizeof(ASV1Context),
@@ -271,13 +275,13 @@ AVCodec ff_asv1_encoder = {
     .encode2        = encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
                                                     AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("ASUS V1"),
 };
 #endif
 
 #if CONFIG_ASV2_ENCODER
 AVCodec ff_asv2_encoder = {
     .name           = "asv2",
+    .long_name      = NULL_IF_CONFIG_SMALL("ASUS V2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ASV2,
     .priv_data_size = sizeof(ASV1Context),
@@ -285,6 +289,5 @@ AVCodec ff_asv2_encoder = {
     .encode2        = encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
                                                     AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("ASUS V2"),
 };
 #endif
diff --git a/libavcodec/atrac.c b/libavcodec/atrac.c
index a772e7d..f36db9e 100644
--- a/libavcodec/atrac.c
+++ b/libavcodec/atrac.c
@@ -1,6 +1,7 @@
 /*
- * Atrac common functions
- * Copyright (c) 2006-2008 Maxim Poliakovski
+ * common functions for the ATRAC family of decoders
+ *
+ * Copyright (c) 2006-2013 Maxim Poliakovski
  * Copyright (c) 2006-2008 Benjamin Larsson
  *
  * This file is part of Libav.
@@ -30,7 +31,6 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "atrac.h"
 
 float ff_atrac_sf_table[64];
@@ -45,11 +45,7 @@ static const float qmf_48tap_half[24] = {
    -0.043596379,   -0.099384367,   0.13207909,    0.46424159
 };
 
-/**
- * Generate common tables
- */
-
-void ff_atrac_generate_tables(void)
+av_cold void ff_atrac_generate_tables(void)
 {
     int i;
     float s;
@@ -67,18 +63,66 @@ void ff_atrac_generate_tables(void)
         }
 }
 
+av_cold void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset,
+                                             int loc_scale)
+{
+    int i;
 
-/**
- * Quadrature mirror synthesis filter.
- *
- * @param inlo      lower part of spectrum
- * @param inhi      higher part of spectrum
- * @param nIn       size of spectrum buffer
- * @param pOut      out buffer
- * @param delayBuf  delayBuf buffer
- * @param temp      temp buffer
- */
+    gctx->loc_scale     = loc_scale;
+    gctx->loc_size      = 1 << loc_scale;
+    gctx->id2exp_offset = id2exp_offset;
 
+    /* Generate gain level table. */
+    for (i = 0; i < 16; i++)
+        gctx->gain_tab1[i] = powf(2.0, id2exp_offset - i);
+
+    /* Generate gain interpolation table. */
+    for (i = -15; i < 16; i++)
+        gctx->gain_tab2[i + 15] = powf(2.0, -1.0f / gctx->loc_size * i);
+}
+
+void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev,
+                                AtracGainInfo *gc_now, AtracGainInfo *gc_next,
+                                int num_samples, float *out)
+{
+    float lev, gc_scale, gain_inc;
+    int i, pos, lastpos;
+
+    gc_scale = gc_next->num_points ? gctx->gain_tab1[gc_next->lev_code[0]]
+                                   : 1.0f;
+
+    if (!gc_now->num_points) {
+        for (pos = 0; pos < num_samples; pos++)
+            out[pos] = in[pos] * gc_scale + prev[pos];
+    } else {
+        pos = 0;
+
+        for (i = 0; i < gc_now->num_points; i++) {
+            lastpos = gc_now->loc_code[i] << gctx->loc_scale;
+
+            lev = gctx->gain_tab1[gc_now->lev_code[i]];
+            gain_inc = gctx->gain_tab2[(i + 1 < gc_now->num_points ? gc_now->lev_code[i + 1]
+                                                                   : gctx->id2exp_offset) -
+                                       gc_now->lev_code[i] + 15];
+
+            /* apply constant gain level and overlap */
+            for (; pos < lastpos; pos++)
+                out[pos] = (in[pos] * gc_scale + prev[pos]) * lev;
+
+            /* interpolate between two different gain levels */
+            for (; pos < lastpos + gctx->loc_size; pos++) {
+                out[pos] = (in[pos] * gc_scale + prev[pos]) * lev;
+                lev *= gain_inc;
+            }
+        }
+
+        for (; pos < num_samples; pos++)
+            out[pos] = in[pos] * gc_scale + prev[pos];
+    }
+
+    /* copy the overlapping part into the delay buffer */
+    memcpy(prev, &in[num_samples], num_samples * sizeof(float));
+}
 
 void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp)
 {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 39fb331..8909323 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -1,6 +1,7 @@
 /*
- * Atrac common data
- * Copyright (c) 2009 Maxim Poliakovski
+ * common functions for the ATRAC family of decoders
+ *
+ * Copyright (c) 2009-2013 Maxim Poliakovski
  * Copyright (c) 2009 Benjamin Larsson
  *
  * This file is part of Libav.
@@ -22,15 +23,74 @@
 
 /**
  * @file
- * Atrac common header
+ * ATRAC common header
  */
 
 #ifndef AVCODEC_ATRAC_H
 #define AVCODEC_ATRAC_H
 
+/**
+ *  Gain control parameters for one subband.
+ */
+typedef struct AtracGainInfo {
+    int   num_points;   ///< number of gain control points
+    int   lev_code[7];  ///< level at corresponding control point
+    int   loc_code[7];  ///< location of gain control points
+} AtracGainInfo;
+
+/**
+ *  Gain compensation context structure.
+ */
+typedef struct AtracGCContext {
+    float   gain_tab1[16];  ///< gain compensation level table
+    float   gain_tab2[31];  ///< gain compensation interpolation table
+    int     id2exp_offset;  ///< offset for converting level index into level exponent
+    int     loc_scale;      ///< scale of location code = 2^loc_scale samples
+    int     loc_size;       ///< size of location code in samples
+} AtracGCContext;
+
 extern float ff_atrac_sf_table[64];
 
+/**
+ * Generate common tables.
+ */
 void ff_atrac_generate_tables(void);
+
+/**
+ *  Initialize gain compensation context.
+ *
+ * @param gctx            pointer to gain compensation context to initialize
+ * @param id2exp_offset   offset for converting level index into level exponent
+ * @param loc_scale       location size factor
+ */
+void ff_atrac_init_gain_compensation(AtracGCContext *gctx, int id2exp_offset,
+                                     int loc_scale);
+
+/**
+ * Apply gain compensation and perform the MDCT overlapping part.
+ *
+ * @param gctx         pointer to gain compensation context
+ * @param in           input buffer
+ * @param prev         previous buffer to perform overlap against
+ * @param gc_now       gain control information for current frame
+ * @param gc_next      gain control information for next frame
+ * @param num_samples  number of samples to process
+ * @param out          output data goes here
+ */
+void ff_atrac_gain_compensation(AtracGCContext *gctx, float *in, float *prev,
+                                AtracGainInfo *gc_now, AtracGainInfo *gc_next,
+                                int num_samples, float *out);
+
+/**
+ * Quadrature mirror synthesis filter.
+ *
+ * @param inlo      lower part of spectrum
+ * @param inhi      higher part of spectrum
+ * @param nIn       size of spectrum buffer
+ * @param pOut      out buffer
+ * @param delayBuf  delayBuf buffer
+ * @param temp      temp buffer
+ */
 void ff_atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp);
 
 #endif /* AVCODEC_ATRAC_H */
diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c
index 268ce86..9a89785 100644
--- a/libavcodec/atrac1.c
+++ b/libavcodec/atrac1.c
@@ -1,5 +1,5 @@
 /*
- * Atrac 1 compatible decoder
+ * ATRAC1 compatible decoder
  * Copyright (c) 2009 Maxim Poliakovski
  * Copyright (c) 2009 Benjamin Larsson
  *
@@ -22,7 +22,7 @@
 
 /**
  * @file
- * Atrac 1 compatible decoder.
+ * ATRAC1 compatible decoder.
  * This decoder handles raw ATRAC1 data and probably SDDS data.
  */
 
@@ -32,9 +32,9 @@
 #include <stddef.h>
 #include <stdio.h>
 
+#include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "internal.h"
 #include "sinewin.h"
@@ -72,7 +72,6 @@ typedef struct {
  * The atrac1 context, holds all needed parameters for decoding
  */
 typedef struct {
-    AVFrame frame;
     AT1SUCtx            SUs[AT1_MAX_CHANNELS];              ///< channel sound unit
     DECLARE_ALIGNED(32, float, spec)[AT1_SU_SAMPLES];      ///< the mdct spectrum buffer
 
@@ -81,7 +80,7 @@ typedef struct {
     DECLARE_ALIGNED(32, float, high)[512];
     float*              bands[3];
     FFTContext          mdct_ctx[3];
-    DSPContext          dsp;
+    AVFloatDSPContext   fdsp;
 } AT1Ctx;
 
 /** size of the transform in samples in the long mode for each QMF band */
@@ -141,8 +140,8 @@ static int at1_imdct_block(AT1SUCtx* su, AT1Ctx *q)
             at1_imdct(q, &q->spec[pos], &su->spectrum[0][ref_pos + start_pos], nbits, band_num);
 
             /* overlap and window */
-            q->dsp.vector_fmul_window(&q->bands[band_num][start_pos], prev_buf,
-                                      &su->spectrum[0][ref_pos + start_pos], ff_sine_32, 16);
+            q->fdsp.vector_fmul_window(&q->bands[band_num][start_pos], prev_buf,
+                                       &su->spectrum[0][ref_pos + start_pos], ff_sine_32, 16);
 
             prev_buf = &su->spectrum[0][ref_pos+start_pos + 16];
             start_pos += block_size;
@@ -273,6 +272,7 @@ static void at1_subband_synthesis(AT1Ctx *q, AT1SUCtx* su, float *pOut)
 static int atrac1_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     AT1Ctx *q          = avctx->priv_data;
@@ -286,8 +286,8 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    q->frame.nb_samples = AT1_SU_SAMPLES;
-    if ((ret = ff_get_buffer(avctx, &q->frame)) < 0) {
+    frame->nb_samples = AT1_SU_SAMPLES;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -309,11 +309,10 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data,
         ret = at1_imdct_block(su, q);
         if (ret < 0)
             return ret;
-        at1_subband_synthesis(q, su, (float *)q->frame.extended_data[ch]);
+        at1_subband_synthesis(q, su, (float *)frame->extended_data[ch]);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = q->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
@@ -357,7 +356,7 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx)
 
     ff_atrac_generate_tables();
 
-    ff_dsputil_init(&q->dsp, avctx);
+    avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     q->bands[0] = q->low;
     q->bands[1] = q->mid;
@@ -369,15 +368,13 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx)
     q->SUs[1].spectrum[0] = q->SUs[1].spec1;
     q->SUs[1].spectrum[1] = q->SUs[1].spec2;
 
-    avcodec_get_frame_defaults(&q->frame);
-    avctx->coded_frame = &q->frame;
-
     return 0;
 }
 
 
 AVCodec ff_atrac1_decoder = {
     .name           = "atrac1",
+    .long_name      = NULL_IF_CONFIG_SMALL("ATRAC1 (Adaptive TRansform Acoustic Coding)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ATRAC1,
     .priv_data_size = sizeof(AT1Ctx),
@@ -385,7 +382,6 @@ AVCodec ff_atrac1_decoder = {
     .close          = atrac1_decode_end,
     .decode         = atrac1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Atrac 1 (Adaptive TRansform Acoustic Coding)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/atrac1data.h b/libavcodec/atrac1data.h
index 7d5dbeb..d4b8cd0 100644
--- a/libavcodec/atrac1data.h
+++ b/libavcodec/atrac1data.h
@@ -1,5 +1,5 @@
 /*
- * Atrac 1 compatible decoder data
+ * ATRAC 1 compatible decoder data
  * Copyright (c) 2009 Maxim Poliakovski
  * Copyright (c) 2009 Benjamin Larsson
  *
@@ -22,7 +22,7 @@
 
 /**
  * @file
- * Atrac 1 compatible decoder data
+ * ATRAC1 compatible decoder data
  */
 
 #ifndef AVCODEC_ATRAC1DATA_H
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index 68ce247..76fd0d1 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -1,5 +1,5 @@
 /*
- * Atrac 3 compatible decoder
+ * ATRAC3 compatible decoder
  * Copyright (c) 2006-2008 Maxim Poliakovski
  * Copyright (c) 2006-2008 Benjamin Larsson
  *
@@ -22,10 +22,10 @@
 
 /**
  * @file
- * Atrac 3 compatible decoder.
+ * ATRAC3 compatible decoder.
  * This decoder handles Sony's ATRAC3 data.
  *
- * Container formats used to store atrac 3 data:
+ * Container formats used to store ATRAC3 data:
  * RealMedia (.rm), RIFF WAV (.wav, .at3), Sony OpenMG (.oma, .aa3).
  *
  * To use this decoder, a calling application must supply the extradata
@@ -36,6 +36,7 @@
 #include <stddef.h>
 #include <stdio.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "bytestream.h"
@@ -53,14 +54,8 @@
 #define SAMPLES_PER_FRAME 1024
 #define MDCT_SIZE          512
 
-typedef struct GainInfo {
-    int num_gain_data;
-    int lev_code[8];
-    int loc_code[8];
-} GainInfo;
-
 typedef struct GainBlock {
-    GainInfo g_block[4];
+    AtracGainInfo g_block[4];
 } GainBlock;
 
 typedef struct TonalComponent {
@@ -86,7 +81,6 @@ typedef struct ChannelUnit {
 } ChannelUnit;
 
 typedef struct ATRAC3Context {
-    AVFrame frame;
     GetBitContext gb;
     //@{
     /** stream data */
@@ -111,6 +105,7 @@ typedef struct ATRAC3Context {
     int scrambled_stream;
     //@}
 
+    AtracGCContext  gainc_ctx;
     FFTContext mdct_ctx;
     FmtConvertContext fmt_conv;
     AVFloatDSPContext fdsp;
@@ -119,11 +114,8 @@ typedef struct ATRAC3Context {
 static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE];
 static VLC_TYPE atrac3_vlc_table[4096][2];
 static VLC   spectral_coeff_tab[7];
-static float gain_tab1[16];
-static float gain_tab2[31];
-
 
-/*
+/**
  * Regular 512 points IMDCT without overlapping, with the exception of the
  * swapping of odd bands caused by the reverse spectra of the QMF.
  *
@@ -173,12 +165,12 @@ static int decode_bytes(const uint8_t *input, uint8_t *out, int bytes)
         output[i] = c ^ buf[i];
 
     if (off)
-        av_log_ask_for_sample(NULL, "Offset of %d not handled.\n", off);
+        avpriv_request_sample(NULL, "Offset of %d", off);
 
     return off;
 }
 
-static av_cold void init_atrac3_window(void)
+static av_cold void init_imdct_window(void)
 {
     int i, j;
 
@@ -205,7 +197,7 @@ static av_cold int atrac3_decode_close(AVCodecContext *avctx)
     return 0;
 }
 
-/*
+/**
  * Mantissa decoding
  *
  * @param selector     which table the output values are coded with
@@ -267,7 +259,7 @@ static void read_quant_spectral_coeffs(GetBitContext *gb, int selector,
     }
 }
 
-/*
+/**
  * Restore the quantized band spectrum coefficients
  *
  * @return subband count, fix for broken specification/files
@@ -324,7 +316,7 @@ static int decode_spectrum(GetBitContext *gb, float *output)
     return num_subbands;
 }
 
-/*
+/**
  * Restore the quantized tonal components
  *
  * @param components tonal components
@@ -408,7 +400,7 @@ static int decode_tonal_components(GetBitContext *gb,
     return component_count;
 }
 
-/*
+/**
  * Decode gain parameters for the coded bands
  *
  * @param block      the gainblock for the current band
@@ -417,90 +409,32 @@ static int decode_tonal_components(GetBitContext *gb,
 static int decode_gain_control(GetBitContext *gb, GainBlock *block,
                                int num_bands)
 {
-    int i, cf, num_data;
+    int i, j;
     int *level, *loc;
 
-    GainInfo *gain = block->g_block;
+    AtracGainInfo *gain = block->g_block;
 
     for (i = 0; i <= num_bands; i++) {
-        num_data              = get_bits(gb, 3);
-        gain[i].num_gain_data = num_data;
+        gain[i].num_points    = get_bits(gb, 3);
         level                 = gain[i].lev_code;
         loc                   = gain[i].loc_code;
 
-        for (cf = 0; cf < gain[i].num_gain_data; cf++) {
-            level[cf] = get_bits(gb, 4);
-            loc  [cf] = get_bits(gb, 5);
-            if (cf && loc[cf] <= loc[cf - 1])
+        for (j = 0; j < gain[i].num_points; j++) {
+            level[j] = get_bits(gb, 4);
+            loc[j]   = get_bits(gb, 5);
+            if (j && loc[j] <= loc[j - 1])
                 return AVERROR_INVALIDDATA;
         }
     }
 
     /* Clear the unused blocks. */
     for (; i < 4 ; i++)
-        gain[i].num_gain_data = 0;
+        gain[i].num_points = 0;
 
     return 0;
 }
 
-/*
- * Apply gain parameters and perform the MDCT overlapping part
- *
- * @param input   input buffer
- * @param prev    previous buffer to perform overlap against
- * @param output  output buffer
- * @param gain1   current band gain info
- * @param gain2   next band gain info
- */
-static void gain_compensate_and_overlap(float *input, float *prev,
-                                        float *output, GainInfo *gain1,
-                                        GainInfo *gain2)
-{
-    float g1, g2, gain_inc;
-    int i, j, num_data, start_loc, end_loc;
-
-
-    if (gain2->num_gain_data == 0)
-        g1 = 1.0;
-    else
-        g1 = gain_tab1[gain2->lev_code[0]];
-
-    if (gain1->num_gain_data == 0) {
-        for (i = 0; i < 256; i++)
-            output[i] = input[i] * g1 + prev[i];
-    } else {
-        num_data = gain1->num_gain_data;
-        gain1->loc_code[num_data] = 32;
-        gain1->lev_code[num_data] = 4;
-
-        for (i = 0, j = 0; i < num_data; i++) {
-            start_loc = gain1->loc_code[i] * 8;
-            end_loc   = start_loc + 8;
-
-            g2       = gain_tab1[gain1->lev_code[i]];
-            gain_inc = gain_tab2[gain1->lev_code[i + 1] -
-                                 gain1->lev_code[i    ] + 15];
-
-            /* interpolate */
-            for (; j < start_loc; j++)
-                output[j] = (input[j] * g1 + prev[j]) * g2;
-
-            /* interpolation is done over eight samples */
-            for (; j < end_loc; j++) {
-                output[j] = (input[j] * g1 + prev[j]) * g2;
-                g2 *= gain_inc;
-            }
-        }
-
-        for (; j < 256; j++)
-            output[j] = input[j] * g1 + prev[j];
-    }
-
-    /* Delay for the overlapping part. */
-    memcpy(prev, &input[256], 256 * sizeof(*prev));
-}
-
-/*
+/**
  * Combine the tonal band spectrum and regular band spectrum
  *
  * @param spectrum        output spectrum buffer
@@ -627,7 +561,7 @@ static void channel_weighting(float *su1, float *su2, int *p3)
     }
 }
 
-/*
+/**
  * Decode a Sound Unit
  *
  * @param snd           the channel unit to be used
@@ -690,11 +624,10 @@ static int decode_channel_sound_unit(ATRAC3Context *q, GetBitContext *gb,
             memset(snd->imdct_buf, 0, 512 * sizeof(*snd->imdct_buf));
 
         /* gain compensation and overlapping */
-        gain_compensate_and_overlap(snd->imdct_buf,
-                                    &snd->prev_frame[band * 256],
-                                    &output[band * 256],
-                                    &gain1->g_block[band],
-                                    &gain2->g_block[band]);
+        ff_atrac_gain_compensation(&q->gainc_ctx, snd->imdct_buf,
+                                   &snd->prev_frame[band * 256],
+                                   &gain1->g_block[band], &gain2->g_block[band],
+                                   256, &output[band * 256]);
     }
 
     /* Swap the gain control buffers for the next frame. */
@@ -801,6 +734,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *databuf,
 static int atrac3_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     ATRAC3Context *q = avctx->priv_data;
@@ -814,8 +748,8 @@ static int atrac3_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    q->frame.nb_samples = SAMPLES_PER_FRAME;
-    if ((ret = ff_get_buffer(avctx, &q->frame)) < 0) {
+    frame->nb_samples = SAMPLES_PER_FRAME;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -828,23 +762,22 @@ static int atrac3_decode_frame(AVCodecContext *avctx, void *data,
         databuf = buf;
     }
 
-    ret = decode_frame(avctx, databuf, (float **)q->frame.extended_data);
+    ret = decode_frame(avctx, databuf, (float **)frame->extended_data);
     if (ret) {
         av_log(NULL, AV_LOG_ERROR, "Frame decoding error!\n");
         return ret;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = q->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
 
-static void atrac3_init_static_data(AVCodec *codec)
+static av_cold void atrac3_init_static_data(AVCodec *codec)
 {
     int i;
 
-    init_atrac3_window();
+    init_imdct_window();
     ff_atrac_generate_tables();
 
     /* Initialize the VLC tables. */
@@ -856,13 +789,6 @@ static void atrac3_init_static_data(AVCodec *codec)
                  huff_bits[i],  1, 1,
                  huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC);
     }
-
-    /* Generate gain tables */
-    for (i = 0; i < 16; i++)
-        gain_tab1[i] = powf(2.0, (4 - i));
-
-    for (i = -15; i < 16; i++)
-        gain_tab2[i + 15] = powf(2.0, i * -0.125);
 }
 
 static av_cold int atrac3_decode_init(AVCodecContext *avctx)
@@ -982,6 +908,7 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
         q->matrix_coeff_index_next[i] = 3;
     }
 
+    ff_atrac_init_gain_compensation(&q->gainc_ctx, 4, 3);
     avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     ff_fmt_convert_init(&q->fmt_conv, avctx);
 
@@ -991,14 +918,12 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
-    avcodec_get_frame_defaults(&q->frame);
-    avctx->coded_frame = &q->frame;
-
     return 0;
 }
 
 AVCodec ff_atrac3_decoder = {
     .name             = "atrac3",
+    .long_name        = NULL_IF_CONFIG_SMALL("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"),
     .type             = AVMEDIA_TYPE_AUDIO,
     .id               = AV_CODEC_ID_ATRAC3,
     .priv_data_size   = sizeof(ATRAC3Context),
@@ -1007,7 +932,6 @@ AVCodec ff_atrac3_decoder = {
     .close            = atrac3_decode_close,
     .decode           = atrac3_decode_frame,
     .capabilities     = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
-    .long_name        = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"),
     .sample_fmts      = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                         AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/atrac3data.h b/libavcodec/atrac3data.h
index 40518ab..4f5c122 100644
--- a/libavcodec/atrac3data.h
+++ b/libavcodec/atrac3data.h
@@ -1,5 +1,5 @@
 /*
- * Atrac 3 compatible decoder data
+ * ATRAC3 compatible decoder data
  * Copyright (c) 2006-2007 Maxim Poliakovski
  * Copyright (c) 2006-2007 Benjamin Larsson
  *
@@ -22,7 +22,7 @@
 
 /**
  * @file
- * Atrac 3 AKA RealAudio 8 compatible decoder data
+ * ATRAC3 AKA RealAudio 8 compatible decoder data
  */
 
 #ifndef AVCODEC_ATRAC3DATA_H
diff --git a/libavcodec/audio_frame_queue.c b/libavcodec/audio_frame_queue.c
index 80f3100..0a8b25c 100644
--- a/libavcodec/audio_frame_queue.c
+++ b/libavcodec/audio_frame_queue.c
@@ -19,12 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/mathematics.h"
 #include "internal.h"
 #include "audio_frame_queue.h"
 
-void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
+av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
 {
     afq->avctx             = avctx;
     afq->next_pts          = AV_NOPTS_VALUE;
diff --git a/libavcodec/audioconvert.c b/libavcodec/audioconvert.c
deleted file mode 100644
index 3714de7..0000000
--- a/libavcodec/audioconvert.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * audio conversion
- * Copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- * audio conversion
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#include "libavutil/avstring.h"
-#include "libavutil/common.h"
-#include "libavutil/libm.h"
-#include "libavutil/samplefmt.h"
-#include "avcodec.h"
-#include "audioconvert.h"
-
-struct AVAudioConvert {
-    int in_channels, out_channels;
-    int fmt_pair;
-};
-
-AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
-                                       enum AVSampleFormat in_fmt, int in_channels,
-                                       const float *matrix, int flags)
-{
-    AVAudioConvert *ctx;
-    if (in_channels!=out_channels)
-        return NULL;  /* FIXME: not supported */
-    ctx = av_malloc(sizeof(AVAudioConvert));
-    if (!ctx)
-        return NULL;
-    ctx->in_channels = in_channels;
-    ctx->out_channels = out_channels;
-    ctx->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt;
-    return ctx;
-}
-
-void av_audio_convert_free(AVAudioConvert *ctx)
-{
-    av_free(ctx);
-}
-
-int av_audio_convert(AVAudioConvert *ctx,
-                           void * const out[6], const int out_stride[6],
-                     const void * const  in[6], const int  in_stride[6], int len)
-{
-    int ch;
-
-    //FIXME optimize common cases
-
-    for(ch=0; ch<ctx->out_channels; ch++){
-        const int is=  in_stride[ch];
-        const int os= out_stride[ch];
-        const uint8_t *pi=  in[ch];
-        uint8_t *po= out[ch];
-        uint8_t *end= po + os*len;
-        if(!out[ch])
-            continue;
-
-#define CONV(ofmt, otype, ifmt, expr)\
-if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\
-    do{\
-        *(otype*)po = expr; pi += is; po += os;\
-    }while(po < end);\
-}
-
-//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
-//FIXME rounding ?
-
-             CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 ,  *(const uint8_t*)pi)
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
-        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16,  *(const int16_t*)pi)
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16,  *(const int16_t*)pi<<16)
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_S16,  *(const int16_t*)pi*(1.0 / (1<<15)))
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16,  *(const int16_t*)pi*(1.0 / (1<<15)))
-        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32,  *(const int32_t*)pi>>16)
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32,  *(const int32_t*)pi)
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_S32,  *(const int32_t*)pi*(1.0 / (1U<<31)))
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32,  *(const int32_t*)pi*(1.0 / (1U<<31)))
-        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(  lrintf(*(const float*)pi * (1<<7)) + 0x80))
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(  lrintf(*(const float*)pi * (1<<15))))
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_FLT, *(const float*)pi)
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi)
-        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(  lrint(*(const double*)pi * (1<<7)) + 0x80))
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(  lrint(*(const double*)pi * (1<<15))))
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_DBL, *(const double*)pi)
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi)
-        else return -1;
-    }
-    return 0;
-}
diff --git a/libavcodec/audioconvert.h b/libavcodec/audioconvert.h
deleted file mode 100644
index 7d76fd6..0000000
--- a/libavcodec/audioconvert.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * audio conversion
- * Copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
- * Copyright (c) 2008 Peter Ross
- *
- * 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_AUDIOCONVERT_H
-#define AVCODEC_AUDIOCONVERT_H
-
-/**
- * @file
- * Audio format conversion routines
- */
-
-
-#include "libavutil/cpu.h"
-#include "avcodec.h"
-#include "libavutil/channel_layout.h"
-
-struct AVAudioConvert;
-typedef struct AVAudioConvert AVAudioConvert;
-
-/**
- * Create an audio sample format converter context
- * @param out_fmt Output sample format
- * @param out_channels Number of output channels
- * @param in_fmt Input sample format
- * @param in_channels Number of input channels
- * @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore.
- * @param flags See AV_CPU_FLAG_xx
- * @return NULL on error
- */
-AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
-                                       enum AVSampleFormat in_fmt, int in_channels,
-                                       const float *matrix, int flags);
-
-/**
- * Free audio sample format converter context
- */
-void av_audio_convert_free(AVAudioConvert *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] out_stride distance between consecutive output samples (measured in bytes)
- * @param[in] in array of input buffers for each channel
- * @param[in] in_stride distance between consecutive input samples (measured in bytes)
- * @param len length of audio frame size (measured in samples)
- */
-int av_audio_convert(AVAudioConvert *ctx,
-                           void * const out[6], const int out_stride[6],
-                     const void * const  in[6], const int  in_stride[6], int len);
-
-#endif /* AVCODEC_AUDIOCONVERT_H */
diff --git a/libavcodec/aura.c b/libavcodec/aura.c
index 4960bf8..a32c18b 100644
--- a/libavcodec/aura.c
+++ b/libavcodec/aura.c
@@ -27,19 +27,11 @@
 #include "internal.h"
 #include "libavutil/internal.h"
 
-typedef struct AuraDecodeContext {
-    AVCodecContext *avctx;
-    AVFrame frame;
-} AuraDecodeContext;
-
 static av_cold int aura_decode_init(AVCodecContext *avctx)
 {
-    AuraDecodeContext *s = avctx->priv_data;
-
-    s->avctx = avctx;
     /* width needs to be divisible by 4 for this codec to work */
     if (avctx->width & 0x3)
-        return -1;
+        return AVERROR(EINVAL);
     avctx->pix_fmt = AV_PIX_FMT_YUV422P;
 
     return 0;
@@ -49,10 +41,10 @@ static int aura_decode_frame(AVCodecContext *avctx,
                              void *data, int *got_frame,
                              AVPacket *pkt)
 {
-    AuraDecodeContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     uint8_t *Y, *U, *V;
     uint8_t val;
-    int x, y;
+    int x, y, ret;
     const uint8_t *buf = pkt->data;
 
     /* prediction error tables (make it clear that they are signed values) */
@@ -61,25 +53,20 @@ static int aura_decode_frame(AVCodecContext *avctx,
     if (pkt->size != 48 + avctx->height * avctx->width) {
         av_log(avctx, AV_LOG_ERROR, "got a buffer with %d bytes when %d were expected\n",
                pkt->size, 48 + avctx->height * avctx->width);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* pixel data starts 48 bytes in, after 3x16-byte tables */
     buf += 48;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-    s->frame.reference = 0;
-    if (ff_get_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    Y = s->frame.data[0];
-    U = s->frame.data[1];
-    V = s->frame.data[2];
+    Y = frame->data[0];
+    U = frame->data[1];
+    V = frame->data[2];
 
     /* iterate through each line in the height */
     for (y = 0; y < avctx->height; y++) {
@@ -102,35 +89,22 @@ static int aura_decode_frame(AVCodecContext *avctx,
             Y[1] = Y[ 0] + delta_table[val & 0xF];
             Y   += 2; U++; V++;
         }
-        Y += s->frame.linesize[0] -  avctx->width;
-        U += s->frame.linesize[1] - (avctx->width >> 1);
-        V += s->frame.linesize[2] - (avctx->width >> 1);
+        Y += frame->linesize[0] -  avctx->width;
+        U += frame->linesize[1] - (avctx->width >> 1);
+        V += frame->linesize[2] - (avctx->width >> 1);
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return pkt->size;
 }
 
-static av_cold int aura_decode_end(AVCodecContext *avctx)
-{
-    AuraDecodeContext *s = avctx->priv_data;
-
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    return 0;
-}
-
 AVCodec ff_aura2_decoder = {
     .name           = "aura2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Auravision Aura 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_AURA2,
-    .priv_data_size = sizeof(AuraDecodeContext),
     .init           = aura_decode_init,
-    .close          = aura_decode_end,
     .decode         = aura_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Auravision Aura 2"),
 };
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index e6b8ec6..0e6ac05 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -23,19 +23,29 @@
 
 /**
  * @file
- * external API header
+ * @ingroup libavc
+ * Libavcodec external API header
  */
 
 #include <errno.h>
 #include "libavutil/samplefmt.h"
+#include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
+#include "libavutil/buffer.h"
 #include "libavutil/cpu.h"
 #include "libavutil/dict.h"
+#include "libavutil/frame.h"
 #include "libavutil/log.h"
 #include "libavutil/pixfmt.h"
 #include "libavutil/rational.h"
 
-#include "libavcodec/version.h"
+#include "version.h"
+
+#if FF_API_FAST_MALLOC
+// to provide fast_*alloc
+#include "libavutil/mem.h"
+#endif
+
 /**
  * @defgroup libavc Encoding/Decoding Library
  * @{
@@ -98,7 +108,9 @@ enum AVCodecID {
     /* video codecs */
     AV_CODEC_ID_MPEG1VIDEO,
     AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
+#if FF_API_XVMC
     AV_CODEC_ID_MPEG2VIDEO_XVMC,
+#endif /* FF_API_XVMC */
     AV_CODEC_ID_H261,
     AV_CODEC_ID_H263,
     AV_CODEC_ID_RV10,
@@ -152,7 +164,6 @@ enum AVCodecID {
     AV_CODEC_ID_MSZH,
     AV_CODEC_ID_ZLIB,
     AV_CODEC_ID_QTRLE,
-    AV_CODEC_ID_SNOW,
     AV_CODEC_ID_TSCC,
     AV_CODEC_ID_ULTI,
     AV_CODEC_ID_QDRAW,
@@ -265,6 +276,13 @@ enum AVCodecID {
     AV_CODEC_ID_MTS2,
     AV_CODEC_ID_CLLC,
     AV_CODEC_ID_MSS2,
+    AV_CODEC_ID_VP9,
+    AV_CODEC_ID_AIC,
+    AV_CODEC_ID_ESCAPE130,
+    AV_CODEC_ID_G2M,
+    AV_CODEC_ID_WEBP,
+    AV_CODEC_ID_HNM4_VIDEO,
+    AV_CODEC_ID_HEVC,
 
     /* various PCM "codecs" */
     AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
@@ -296,6 +314,8 @@ enum AVCodecID {
     AV_CODEC_ID_PCM_LXF,
     AV_CODEC_ID_S302M,
     AV_CODEC_ID_PCM_S8_PLANAR,
+    AV_CODEC_ID_PCM_S24LE_PLANAR,
+    AV_CODEC_ID_PCM_S32LE_PLANAR,
 
     /* various ADPCM codecs */
     AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
@@ -376,7 +396,9 @@ enum AVCodecID {
     AV_CODEC_ID_MLP,
     AV_CODEC_ID_GSM_MS, /* as found in WAV */
     AV_CODEC_ID_ATRAC3,
+#if FF_API_VOXWARE
     AV_CODEC_ID_VOXWARE,
+#endif
     AV_CODEC_ID_APE,
     AV_CODEC_ID_NELLYMOSER,
     AV_CODEC_ID_MUSEPACK8,
@@ -408,6 +430,7 @@ enum AVCodecID {
     AV_CODEC_ID_OPUS,
     AV_CODEC_ID_COMFORT_NOISE,
     AV_CODEC_ID_TAK,
+    AV_CODEC_ID_METASOUND,
 
     /* subtitle codecs */
     AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
@@ -432,16 +455,8 @@ enum AVCodecID {
     AV_CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems
                                 * stream (only used by libavformat) */
     AV_CODEC_ID_FFMETADATA = 0x21000,   ///< Dummy codec for streams containing only metadata information.
-
-#if FF_API_CODEC_ID
-#include "old_codec_ids.h"
-#endif
 };
 
-#if FF_API_CODEC_ID
-#define CodecID AVCodecID
-#endif
-
 /**
  * This struct describes the properties of a single codec described by an
  * AVCodecID.
@@ -482,11 +497,6 @@ typedef struct AVCodecDescriptor {
  */
 #define AV_CODEC_PROP_LOSSLESS      (1 << 2)
 
-#if FF_API_OLD_DECODE_AUDIO
-/* in bytes */
-#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
-#endif
-
 /**
  * @ingroup lavc_decoding
  * Required number of additionally allocated bytes at the end of the input bitstream for decoding.
@@ -518,7 +528,6 @@ enum Motion_Est_ID {
     ME_X1,          ///< reserved for experiments
     ME_HEX,         ///< hexagon based search
     ME_UMH,         ///< uneven multi-hexagon search
-    ME_ITER,        ///< iterative search
     ME_TESA,        ///< transformed exhaustive search algorithm
 };
 
@@ -544,28 +553,40 @@ enum AVColorPrimaries{
     AVCOL_PRI_SMPTE170M   = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
     AVCOL_PRI_SMPTE240M   = 7, ///< functionally identical to above
     AVCOL_PRI_FILM        = 8,
+    AVCOL_PRI_BT2020      = 9, ///< ITU-R BT2020
     AVCOL_PRI_NB             , ///< Not part of ABI
 };
 
 enum AVColorTransferCharacteristic{
-    AVCOL_TRC_BT709       = 1, ///< also ITU-R BT1361
-    AVCOL_TRC_UNSPECIFIED = 2,
-    AVCOL_TRC_GAMMA22     = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
-    AVCOL_TRC_GAMMA28     = 5, ///< also ITU-R BT470BG
-    AVCOL_TRC_SMPTE240M   = 7,
-    AVCOL_TRC_NB             , ///< Not part of ABI
+    AVCOL_TRC_BT709        =  1, ///< also ITU-R BT1361
+    AVCOL_TRC_UNSPECIFIED  =  2,
+    AVCOL_TRC_GAMMA22      =  4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
+    AVCOL_TRC_GAMMA28      =  5, ///< also ITU-R BT470BG
+    AVCOL_TRC_SMPTE170M    =  6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
+    AVCOL_TRC_SMPTE240M    =  7,
+    AVCOL_TRC_LINEAR       =  8, ///< "Linear transfer characteristics"
+    AVCOL_TRC_LOG          =  9, ///< "Logarithmic transfer characteristic (100:1 range)"
+    AVCOL_TRC_LOG_SQRT     = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt( 10 ) : 1 range)"
+    AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4
+    AVCOL_TRC_BT1361_ECG   = 12, ///< ITU-R BT1361 Extended Colour Gamut
+    AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC)
+    AVCOL_TRC_BT2020_10    = 14, ///< ITU-R BT2020 for 10 bit system
+    AVCOL_TRC_BT2020_12    = 15, ///< ITU-R BT2020 for 12 bit system
+    AVCOL_TRC_NB               , ///< Not part of ABI
 };
 
 enum AVColorSpace{
-    AVCOL_SPC_RGB         = 0,
-    AVCOL_SPC_BT709       = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
-    AVCOL_SPC_UNSPECIFIED = 2,
-    AVCOL_SPC_FCC         = 4,
-    AVCOL_SPC_BT470BG     = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
-    AVCOL_SPC_SMPTE170M   = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
-    AVCOL_SPC_SMPTE240M   = 7,
-    AVCOL_SPC_YCOCG       = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
-    AVCOL_SPC_NB             , ///< Not part of ABI
+    AVCOL_SPC_RGB         =  0,
+    AVCOL_SPC_BT709       =  1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+    AVCOL_SPC_UNSPECIFIED =  2,
+    AVCOL_SPC_FCC         =  4,
+    AVCOL_SPC_BT470BG     =  5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+    AVCOL_SPC_SMPTE170M   =  6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
+    AVCOL_SPC_SMPTE240M   =  7,
+    AVCOL_SPC_YCOCG       =  8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+    AVCOL_SPC_BT2020_NCL  =  9, ///< ITU-R BT2020 non-constant luminance system
+    AVCOL_SPC_BT2020_CL   = 10, ///< ITU-R BT2020 constant luminance system
+    AVCOL_SPC_NB              , ///< Not part of ABI
 };
 
 enum AVColorRange{
@@ -614,15 +635,26 @@ typedef struct RcOverride{
     float quality_factor;
 } RcOverride;
 
+#if FF_API_MAX_BFRAMES
+/**
+ * @deprecated there is no libavcodec-wide limit on the number of B-frames
+ */
 #define FF_MAX_B_FRAMES 16
+#endif
 
 /* encoding support
    These flags can be passed in AVCodecContext.flags before initialization.
    Note: Not everything is supported yet.
 */
 
+/**
+ * Allow decoders to produce frames with data planes that are not aligned
+ * to CPU requirements (e.g. due to cropping).
+ */
+#define CODEC_FLAG_UNALIGNED 0x0001
 #define CODEC_FLAG_QSCALE 0x0002  ///< Use fixed qscale.
 #define CODEC_FLAG_4MV    0x0004  ///< 4 MV per MB allowed / advanced prediction for H.263.
+#define CODEC_FLAG_OUTPUT_CORRUPT 0x0008 ///< Output even those frames that might be corrupted
 #define CODEC_FLAG_QPEL   0x0010  ///< Use qpel MC.
 #define CODEC_FLAG_GMC    0x0020  ///< Use GMC.
 #define CODEC_FLAG_MV0    0x0040  ///< Always try a MB with MV=<0,0>.
@@ -652,12 +684,8 @@ typedef struct RcOverride{
 #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.
-#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.
-#define CODEC_FLAG2_STRICT_GOP    0x00000002 ///< Strictly enforce GOP size.
-#define CODEC_FLAG2_SKIP_RD       0x00004000 ///< RD optimal MB level residual skipping
-#endif
+#define CODEC_FLAG2_IGNORE_CROP   0x00010000 ///< Discard cropping information from SPS.
+
 #define CODEC_FLAG2_CHUNKS        0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
 
 /* Unsupported options :
@@ -675,8 +703,10 @@ typedef struct RcOverride{
  */
 #define CODEC_CAP_DR1             0x0002
 #define CODEC_CAP_TRUNCATED       0x0008
+#if FF_API_XVMC
 /* Codec can export data for HW decoding (XvMC). */
 #define CODEC_CAP_HWACCEL         0x0010
+#endif /* FF_API_XVMC */
 /**
  * Encoder or decoder requires flushing with NULL input at the end in order to
  * give the complete and correct output.
@@ -706,10 +736,12 @@ typedef struct RcOverride{
  * This can be used to prevent truncation of the last audio samples.
  */
 #define CODEC_CAP_SMALL_LAST_FRAME 0x0040
+#if FF_API_CAP_VDPAU
 /**
  * Codec can export data for HW decoding (VDPAU).
  */
 #define CODEC_CAP_HWACCEL_VDPAU    0x0080
+#endif
 /**
  * Codec can output multiple frames per AVPacket
  * Normally demuxers return one frame at a time, demuxers which do not do
@@ -731,10 +763,12 @@ typedef struct RcOverride{
  * Codec should fill in channel configuration and samplerate instead of container
  */
 #define CODEC_CAP_CHANNEL_CONF     0x0400
+#if FF_API_NEG_LINESIZES
 /**
- * Codec is able to deal with negative linesizes
+ * @deprecated no codecs use this capability
  */
 #define CODEC_CAP_NEG_LINESIZES    0x0800
+#endif
 /**
  * Codec supports frame-level multithreading.
  */
@@ -756,6 +790,7 @@ typedef struct RcOverride{
  */
 #define CODEC_CAP_VARIABLE_FRAME_SIZE 0x10000
 
+#if FF_API_MB_TYPE
 //The following defines may change, don't expect compatibility if you use them.
 #define MB_TYPE_INTRA4x4   0x0001
 #define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
@@ -779,6 +814,7 @@ typedef struct RcOverride{
 #define MB_TYPE_QUANT      0x00010000
 #define MB_TYPE_CBP        0x00020000
 //Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)
+#endif
 
 /**
  * Pan Scan area.
@@ -809,11 +845,14 @@ typedef struct AVPanScan{
     int16_t position[3][2];
 }AVPanScan;
 
+#if FF_API_QSCALE_TYPE
 #define FF_QSCALE_TYPE_MPEG1 0
 #define FF_QSCALE_TYPE_MPEG2 1
 #define FF_QSCALE_TYPE_H264  2
 #define FF_QSCALE_TYPE_VP56  3
+#endif
 
+#if FF_API_GET_BUFFER
 #define FF_BUFFER_TYPE_INTERNAL 1
 #define FF_BUFFER_TYPE_USER     2 ///< direct rendering buffers (image is (de)allocated by user)
 #define FF_BUFFER_TYPE_SHARED   4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared.
@@ -823,6 +862,12 @@ typedef struct AVPanScan{
 #define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer.
 #define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
 #define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
+#endif
+
+/**
+ * The decoder will keep a reference to the frame and may reuse it later.
+ */
+#define AV_GET_BUFFER_FLAG_REF (1 << 0)
 
 /**
  * @defgroup lavc_packet AVPacket
@@ -885,18 +930,24 @@ enum AVPacketSideDataType {
  * ABI. Thus it may be allocated on stack and no new fields can be added to it
  * without libavcodec and libavformat major bump.
  *
- * The semantics of data ownership depends on the destruct field.
- * If it is set, the packet data is dynamically allocated and is valid
- * indefinitely until av_free_packet() is called (which in turn calls the
- * destruct callback to free the data). If destruct is not set, the packet data
- * is typically backed by some static buffer somewhere and is only valid for a
- * limited time (e.g. until the next read call when demuxing).
+ * The semantics of data ownership depends on the buf or destruct (deprecated)
+ * fields. If either is set, the packet data is dynamically allocated and is
+ * valid indefinitely until av_free_packet() is called (which in turn calls
+ * av_buffer_unref()/the destruct callback to free the data). If neither is set,
+ * the packet data is typically backed by some static buffer somewhere and is
+ * only valid for a limited time (e.g. until the next read call when demuxing).
  *
  * The side data is always allocated with av_malloc() and is freed in
  * av_free_packet().
  */
 typedef struct AVPacket {
     /**
+     * A reference to the reference-counted buffer where the packet data is
+     * stored.
+     * May be NULL, then the packet data is not reference-counted.
+     */
+    AVBufferRef *buf;
+    /**
      * Presentation timestamp in AVStream->time_base units; the time at which
      * the decompressed packet will be presented to the user.
      * Can be AV_NOPTS_VALUE if it is not stored in the file.
@@ -935,8 +986,12 @@ typedef struct AVPacket {
      * Equals next_pts - this_pts in presentation order.
      */
     int   duration;
+#if FF_API_DESTRUCT_PACKET
+    attribute_deprecated
     void  (*destruct)(struct AVPacket *);
+    attribute_deprecated
     void  *priv;
+#endif
     int64_t pos;                            ///< byte position in stream, -1 if unknown
 
     /**
@@ -971,353 +1026,6 @@ enum AVSideDataParamChangeFlags {
  * @}
  */
 
-/**
- * This structure describes decoded (raw) audio or video data.
- *
- * AVFrame must be allocated using avcodec_alloc_frame() and freed with
- * avcodec_free_frame(). Note that this allocates only the AVFrame itself. The
- * buffers for the data must be managed through other means.
- *
- * AVFrame is typically allocated once and then reused multiple times to hold
- * different data (e.g. a single AVFrame to hold frames received from a
- * decoder). In such a case, avcodec_get_frame_defaults() should be used to
- * reset the frame to its original clean state before it is reused again.
- *
- * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added
- * to the end with a minor bump.
- */
-typedef struct AVFrame {
-#define AV_NUM_DATA_POINTERS 8
-    /**
-     * pointer to the picture/channel planes.
-     * This might be different from the first allocated byte
-     * - encoding: Set by user
-     * - decoding: set by AVCodecContext.get_buffer()
-     */
-    uint8_t *data[AV_NUM_DATA_POINTERS];
-
-    /**
-     * Size, in bytes, of the data for each picture/channel plane.
-     *
-     * For audio, only linesize[0] may be set. For planar audio, each channel
-     * plane must be the same size.
-     *
-     * - encoding: Set by user
-     * - decoding: set by AVCodecContext.get_buffer()
-     */
-    int linesize[AV_NUM_DATA_POINTERS];
-
-    /**
-     * pointers to the data planes/channels.
-     *
-     * For video, this should simply point to data[].
-     *
-     * For planar audio, each channel has a separate data pointer, and
-     * linesize[0] contains the size of each channel buffer.
-     * For packed audio, there is just one data pointer, and linesize[0]
-     * contains the total size of the buffer for all channels.
-     *
-     * Note: Both data and extended_data will always be set by get_buffer(),
-     * but for planar audio with more channels that can fit in data,
-     * extended_data must be used by the decoder in order to access all
-     * channels.
-     *
-     * encoding: set by user
-     * decoding: set by AVCodecContext.get_buffer()
-     */
-    uint8_t **extended_data;
-
-    /**
-     * width and height of the video frame
-     * - encoding: unused
-     * - decoding: Read by user.
-     */
-    int width, height;
-
-    /**
-     * number of audio samples (per channel) described by this frame
-     * - encoding: Set by user
-     * - decoding: Set by libavcodec
-     */
-    int nb_samples;
-
-    /**
-     * format of the frame, -1 if unknown or unset
-     * Values correspond to enum AVPixelFormat for video frames,
-     * enum AVSampleFormat for audio)
-     * - encoding: unused
-     * - decoding: Read by user.
-     */
-    int format;
-
-    /**
-     * 1 -> keyframe, 0-> not
-     * - encoding: Set by libavcodec.
-     * - decoding: Set by libavcodec.
-     */
-    int key_frame;
-
-    /**
-     * Picture type of the frame, see ?_TYPE below.
-     * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
-     * - decoding: Set by libavcodec.
-     */
-    enum AVPictureType pict_type;
-
-    /**
-     * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.
-     * This isn't used by libavcodec unless the default get/release_buffer() is used.
-     * - encoding:
-     * - decoding:
-     */
-    uint8_t *base[AV_NUM_DATA_POINTERS];
-
-    /**
-     * sample aspect ratio for the video frame, 0/1 if unknown/unspecified
-     * - encoding: unused
-     * - decoding: Read by user.
-     */
-    AVRational sample_aspect_ratio;
-
-    /**
-     * presentation timestamp in time_base units (time when frame should be shown to user)
-     * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.
-     * - encoding: MUST be set by user.
-     * - decoding: Set by libavcodec.
-     */
-    int64_t pts;
-
-    /**
-     * pts copied from the AVPacket that was decoded to produce this frame
-     * - encoding: unused
-     * - decoding: Read by user.
-     */
-    int64_t pkt_pts;
-
-    /**
-     * dts copied from the AVPacket that triggered returning this frame
-     * - encoding: unused
-     * - decoding: Read by user.
-     */
-    int64_t pkt_dts;
-
-    /**
-     * picture number in bitstream order
-     * - encoding: set by
-     * - decoding: Set by libavcodec.
-     */
-    int coded_picture_number;
-    /**
-     * picture number in display order
-     * - encoding: set by
-     * - decoding: Set by libavcodec.
-     */
-    int display_picture_number;
-
-    /**
-     * quality (between 1 (good) and FF_LAMBDA_MAX (bad))
-     * - encoding: Set by libavcodec. for coded_picture (and set by user for input).
-     * - decoding: Set by libavcodec.
-     */
-    int quality;
-
-    /**
-     * is this picture used as reference
-     * The values for this are the same as the MpegEncContext.picture_structure
-     * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.
-     * Set to 4 for delayed, non-reference frames.
-     * - encoding: unused
-     * - decoding: Set by libavcodec. (before get_buffer() call)).
-     */
-    int reference;
-
-    /**
-     * QP table
-     * - encoding: unused
-     * - decoding: Set by libavcodec.
-     */
-    int8_t *qscale_table;
-    /**
-     * QP store stride
-     * - encoding: unused
-     * - decoding: Set by libavcodec.
-     */
-    int qstride;
-
-    /**
-     *
-     */
-    int qscale_type;
-
-    /**
-     * mbskip_table[mb]>=1 if MB didn't change
-     * stride= mb_width = (width+15)>>4
-     * - encoding: unused
-     * - decoding: Set by libavcodec.
-     */
-    uint8_t *mbskip_table;
-
-    /**
-     * motion vector table
-     * @code
-     * example:
-     * int mv_sample_log2= 4 - motion_subsample_log2;
-     * int mb_width= (width+15)>>4;
-     * int mv_stride= (mb_width << mv_sample_log2) + 1;
-     * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];
-     * @endcode
-     * - encoding: Set by user.
-     * - decoding: Set by libavcodec.
-     */
-    int16_t (*motion_val[2])[2];
-
-    /**
-     * macroblock type table
-     * mb_type_base + mb_width + 2
-     * - encoding: Set by user.
-     * - decoding: Set by libavcodec.
-     */
-    uint32_t *mb_type;
-
-    /**
-     * DCT coefficients
-     * - encoding: unused
-     * - decoding: Set by libavcodec.
-     */
-    short *dct_coeff;
-
-    /**
-     * motion reference frame index
-     * the order in which these are stored can depend on the codec.
-     * - encoding: Set by user.
-     * - decoding: Set by libavcodec.
-     */
-    int8_t *ref_index[2];
-
-    /**
-     * for some private data of the user
-     * - encoding: unused
-     * - decoding: Set by user.
-     */
-    void *opaque;
-
-    /**
-     * error
-     * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.
-     * - decoding: unused
-     */
-    uint64_t error[AV_NUM_DATA_POINTERS];
-
-    /**
-     * type of the buffer (to keep track of who has to deallocate data[*])
-     * - encoding: Set by the one who allocates it.
-     * - decoding: Set by the one who allocates it.
-     * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.
-     */
-    int type;
-
-    /**
-     * When decoding, this signals how much the picture must be delayed.
-     * extra_delay = repeat_pict / (2*fps)
-     * - encoding: unused
-     * - decoding: Set by libavcodec.
-     */
-    int repeat_pict;
-
-    /**
-     * The content of the picture is interlaced.
-     * - encoding: Set by user.
-     * - decoding: Set by libavcodec. (default 0)
-     */
-    int interlaced_frame;
-
-    /**
-     * If the content is interlaced, is top field displayed first.
-     * - encoding: Set by user.
-     * - decoding: Set by libavcodec.
-     */
-    int top_field_first;
-
-    /**
-     * Tell user application that palette has changed from previous frame.
-     * - encoding: ??? (no palette-enabled encoder yet)
-     * - decoding: Set by libavcodec. (default 0).
-     */
-    int palette_has_changed;
-
-    /**
-     * codec suggestion on buffer type if != 0
-     * - encoding: unused
-     * - decoding: Set by libavcodec. (before get_buffer() call)).
-     */
-    int buffer_hints;
-
-    /**
-     * Pan scan.
-     * - encoding: Set by user.
-     * - decoding: Set by libavcodec.
-     */
-    AVPanScan *pan_scan;
-
-    /**
-     * reordered opaque 64bit (generally an integer or a double precision float
-     * PTS but can be anything).
-     * The user sets AVCodecContext.reordered_opaque to represent the input at
-     * that time,
-     * the decoder reorders values as needed and sets AVFrame.reordered_opaque
-     * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
-     * @deprecated in favor of pkt_pts
-     * - encoding: unused
-     * - decoding: Read by user.
-     */
-    int64_t reordered_opaque;
-
-    /**
-     * hardware accelerator private data (Libav-allocated)
-     * - encoding: unused
-     * - decoding: Set by libavcodec
-     */
-    void *hwaccel_picture_private;
-
-    /**
-     * the AVCodecContext which ff_thread_get_buffer() was last called on
-     * - encoding: Set by libavcodec.
-     * - decoding: Set by libavcodec.
-     */
-    struct AVCodecContext *owner;
-
-    /**
-     * used by multithreading to store frame-specific info
-     * - encoding: Set by libavcodec.
-     * - decoding: Set by libavcodec.
-     */
-    void *thread_opaque;
-
-    /**
-     * log2 of the size of the block which a single vector in motion_val represents:
-     * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
-     * - encoding: unused
-     * - decoding: Set by libavcodec.
-     */
-    uint8_t motion_subsample_log2;
-
-    /**
-     * Sample rate of the audio data.
-     *
-     * - encoding: unused
-     * - decoding: set by get_buffer()
-     */
-    int sample_rate;
-
-    /**
-     * Channel layout of the audio data.
-     *
-     * - encoding: unused
-     * - decoding: set by get_buffer()
-     */
-    uint64_t channel_layout;
-} AVFrame;
-
 struct AVCodecInternal;
 
 enum AVFieldOrder {
@@ -1372,13 +1080,6 @@ typedef struct AVCodecContext {
      */
     unsigned int stream_codec_tag;
 
-#if FF_API_SUB_ID
-    /**
-     * @deprecated this field is unused
-     */
-    attribute_deprecated int sub_id;
-#endif
-
     void *priv_data;
 
     /**
@@ -1501,20 +1202,26 @@ typedef struct AVCodecContext {
     /**
      * picture width / height.
      * - encoding: MUST be set by user.
-     * - decoding: Set by libavcodec.
-     * Note: For compatibility it is possible to set this instead of
-     * coded_width/height before decoding.
+     * - decoding: May be set by the user before opening the decoder if known e.g.
+     *             from the container. Some decoders will require the dimensions
+     *             to be set by the caller. During decoding, the decoder may
+     *             overwrite those values as required.
      */
     int width, height;
 
     /**
-     * Bitstream width / height, may be different from width/height.
+     * Bitstream width / height, may be different from width/height e.g. when
+     * the decoded frame is cropped before being output.
      * - encoding: unused
-     * - decoding: Set by user before init if known. Codec should override / dynamically change if needed.
+     * - decoding: May be set by the user before opening the decoder if known
+     *             e.g. from the container. During decoding, the decoder may
+     *             overwrite those values as required.
      */
     int coded_width, coded_height;
 
+#if FF_API_ASPECT_EXTENDED
 #define FF_ASPECT_EXTENDED 15
+#endif
 
     /**
      * the number of pictures in a group of pictures, or 0 for intra_only
@@ -1535,7 +1242,7 @@ typedef struct AVCodecContext {
     /**
      * Motion estimation algorithm used for video coding.
      * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex),
-     * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific]
+     * 8 (umh), 10 (tesa) [7, 8, 10 are x264 specific]
      * - encoding: MUST be set by user.
      * - decoding: unused
      */
@@ -1602,22 +1309,6 @@ typedef struct AVCodecContext {
 
     int b_frame_strategy;
 
-#if FF_API_MPV_GLOBAL_OPTS
-    /**
-     * luma single coefficient elimination threshold
-     * - encoding: Set by user.
-     * - decoding: unused
-     */
-    attribute_deprecated int luma_elim_threshold;
-
-    /**
-     * chroma single coeff elimination threshold
-     * - encoding: Set by user.
-     * - decoding: unused
-     */
-    attribute_deprecated int chroma_elim_threshold;
-#endif
-
     /**
      * qscale offset between IP and B-frames
      * - encoding: Set by user.
@@ -1758,8 +1449,6 @@ typedef struct AVCodecContext {
 #define FF_CMP_VSAD   8
 #define FF_CMP_VSSE   9
 #define FF_CMP_NSSE   10
-#define FF_CMP_W53    11
-#define FF_CMP_W97    12
 #define FF_CMP_DCTMAX 13
 #define FF_CMP_DCT264 14
 #define FF_CMP_CHROMA 256
@@ -1847,16 +1536,6 @@ typedef struct AVCodecContext {
      */
     int inter_quant_bias;
 
-#if FF_API_COLOR_TABLE_ID
-    /**
-     * color table ID
-     * - encoding: unused
-     * - decoding: Which clrtable should be used for 8bit RGB images.
-     *             Tables have to be stored somewhere. FIXME
-     */
-    attribute_deprecated int color_table_id;
-#endif
-
     /**
      * slice flags
      * - encoding: unused
@@ -1867,12 +1546,15 @@ typedef struct AVCodecContext {
 #define SLICE_FLAG_ALLOW_FIELD    0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
 #define SLICE_FLAG_ALLOW_PLANE    0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
 
+#if FF_API_XVMC
     /**
      * XVideo Motion Acceleration
      * - encoding: forbidden
      * - decoding: set by decoder
+     * @deprecated XvMC support is slated for removal.
      */
-    int xvmc_acceleration;
+    attribute_deprecated int xvmc_acceleration;
+#endif /* FF_API_XVMC */
 
     /**
      * macroblock decision mode
@@ -1913,20 +1595,6 @@ typedef struct AVCodecContext {
      */
     int noise_reduction;
 
-#if FF_API_INTER_THRESHOLD
-    /**
-     * @deprecated this field is unused
-     */
-    attribute_deprecated int inter_threshold;
-#endif
-
-#if FF_API_MPV_GLOBAL_OPTS
-    /**
-     * @deprecated use mpegvideo private options instead
-     */
-    attribute_deprecated int quantizer_noise_shaping;
-#endif
-
     /**
      * Motion estimation threshold below which no motion estimation is
      * performed, but instead the user specified motion vectors are used.
@@ -2154,7 +1822,7 @@ typedef struct AVCodecContext {
      * - decoding: Set by user.
      * @deprecated Deprecated in favor of request_channel_layout.
      */
-    int request_channels;
+    attribute_deprecated int request_channels;
 #endif
 
     /**
@@ -2185,6 +1853,7 @@ typedef struct AVCodecContext {
      */
     enum AVSampleFormat request_sample_fmt;
 
+#if FF_API_GET_BUFFER
     /**
      * Called at the beginning of each frame to get a buffer for it.
      *
@@ -2207,35 +1876,151 @@ typedef struct AVCodecContext {
      *
      * Video:
      *
-     * If pic.reference is set then the frame will be read later by libavcodec.
+     * If pic.reference is set then the frame will be read later by libavcodec.
+     * avcodec_align_dimensions2() should be used to find the required width and
+     * height, as they normally need to be rounded up to the next multiple of 16.
+     *
+     * If frame multithreading is used and thread_safe_callbacks is set,
+     * it may be called from a different thread, but not from more than one at
+     * once. Does not need to be reentrant.
+     *
+     * @see release_buffer(), reget_buffer()
+     * @see avcodec_align_dimensions2()
+     *
+     * Audio:
+     *
+     * Decoders request a buffer of a particular size by setting
+     * AVFrame.nb_samples prior to calling get_buffer(). The decoder may,
+     * however, utilize only part of the buffer by setting AVFrame.nb_samples
+     * to a smaller value in the output frame.
+     *
+     * Decoders cannot use the buffer after returning from
+     * avcodec_decode_audio4(), so they will not call release_buffer(), as it
+     * is assumed to be released immediately upon return. In some rare cases,
+     * a decoder may need to call get_buffer() more than once in a single
+     * call to avcodec_decode_audio4(). In that case, when get_buffer() is
+     * called again after it has already been called once, the previously
+     * acquired buffer is assumed to be released at that time and may not be
+     * reused by the decoder.
+     *
+     * As a convenience, av_samples_get_buffer_size() and
+     * av_samples_fill_arrays() in libavutil may be used by custom get_buffer()
+     * functions to find the required data size and to fill data pointers and
+     * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
+     * since all planes must be the same size.
+     *
+     * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec, user can override.
+     *
+     * @deprecated use get_buffer2()
+     */
+    attribute_deprecated
+    int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+    /**
+     * Called to release buffers which were allocated with get_buffer.
+     * A released buffer can be reused in get_buffer().
+     * pic.data[*] must be set to NULL.
+     * May be called from a different thread if frame multithreading is used,
+     * but not by more than one thread at once, so does not need to be reentrant.
+     * - encoding: unused
+     * - decoding: Set by libavcodec, user can override.
+     *
+     * @deprecated custom freeing callbacks should be set from get_buffer2()
+     */
+    attribute_deprecated
+    void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+    /**
+     * Called at the beginning of a frame to get cr buffer for it.
+     * Buffer type (size, hints) must be the same. libavcodec won't check it.
+     * libavcodec will pass previous buffer in pic, function should return
+     * same buffer or new buffer with old frame "painted" into it.
+     * If pic.data[0] == NULL must behave like get_buffer().
+     * if CODEC_CAP_DR1 is not set then reget_buffer() must call
+     * avcodec_default_reget_buffer() instead of providing buffers allocated by
+     * some other means.
+     * - encoding: unused
+     * - decoding: Set by libavcodec, user can override.
+     */
+    attribute_deprecated
+    int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
+#endif
+
+    /**
+     * This callback is called at the beginning of each frame to get data
+     * buffer(s) for it. There may be one contiguous buffer for all the data or
+     * there may be a buffer per each data plane or anything in between. What
+     * this means is, you may set however many entries in buf[] you feel necessary.
+     * Each buffer must be reference-counted using the AVBuffer API (see description
+     * of buf[] below).
+     *
+     * The following fields will be set in the frame before this callback is
+     * called:
+     * - format
+     * - width, height (video only)
+     * - sample_rate, channel_layout, nb_samples (audio only)
+     * Their values may differ from the corresponding values in
+     * AVCodecContext. This callback must use the frame values, not the codec
+     * context values, to calculate the required buffer size.
+     *
+     * This callback must fill the following fields in the frame:
+     * - data[]
+     * - linesize[]
+     * - extended_data:
+     *   * if the data is planar audio with more than 8 channels, then this
+     *     callback must allocate and fill extended_data to contain all pointers
+     *     to all data planes. data[] must hold as many pointers as it can.
+     *     extended_data must be allocated with av_malloc() and will be freed in
+     *     av_frame_unref().
+     *   * otherwise exended_data must point to data
+     * - buf[] must contain one or more pointers to AVBufferRef structures. Each of
+     *   the frame's data and extended_data pointers must be contained in these. That
+     *   is, one AVBufferRef for each allocated chunk of memory, not necessarily one
+     *   AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(),
+     *   and av_buffer_ref().
+     * - extended_buf and nb_extended_buf must be allocated with av_malloc() by
+     *   this callback and filled with the extra buffers if there are more
+     *   buffers than buf[] can hold. extended_buf will be freed in
+     *   av_frame_unref().
+     *
+     * If CODEC_CAP_DR1 is not set then get_buffer2() must call
+     * avcodec_default_get_buffer2() instead of providing buffers allocated by
+     * some other means.
+     *
+     * Each data plane must be aligned to the maximum required by the target
+     * CPU.
+     *
+     * @see avcodec_default_get_buffer2()
+     *
+     * Video:
+     *
+     * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused
+     * (read and/or written to if it is writable) later by libavcodec.
+     *
+     * If CODEC_FLAG_EMU_EDGE is not set in s->flags, the buffer must contain an
+     * edge of the size returned by avcodec_get_edge_width() on all sides.
+     *
      * avcodec_align_dimensions2() should be used to find the required width and
      * height, as they normally need to be rounded up to the next multiple of 16.
      *
      * If frame multithreading is used and thread_safe_callbacks is set,
-     * it may be called from a different thread, but not from more than one at
-     * once. Does not need to be reentrant.
+     * this callback may be called from a different thread, but not from more
+     * than one at once. Does not need to be reentrant.
      *
-     * @see release_buffer(), reget_buffer()
      * @see avcodec_align_dimensions2()
      *
      * Audio:
      *
      * Decoders request a buffer of a particular size by setting
-     * AVFrame.nb_samples prior to calling get_buffer(). The decoder may,
+     * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may,
      * however, utilize only part of the buffer by setting AVFrame.nb_samples
      * to a smaller value in the output frame.
      *
-     * Decoders cannot use the buffer after returning from
-     * avcodec_decode_audio4(), so they will not call release_buffer(), as it
-     * is assumed to be released immediately upon return. In some rare cases,
-     * a decoder may need to call get_buffer() more than once in a single
-     * call to avcodec_decode_audio4(). In that case, when get_buffer() is
-     * called again after it has already been called once, the previously
-     * acquired buffer is assumed to be released at that time and may not be
-     * reused by the decoder.
-     *
      * As a convenience, av_samples_get_buffer_size() and
-     * av_samples_fill_arrays() in libavutil may be used by custom get_buffer()
+     * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2()
      * functions to find the required data size and to fill data pointers and
      * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
      * since all planes must be the same size.
@@ -2245,33 +2030,20 @@ typedef struct AVCodecContext {
      * - encoding: unused
      * - decoding: Set by libavcodec, user can override.
      */
-    int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
-
-    /**
-     * Called to release buffers which were allocated with get_buffer.
-     * A released buffer can be reused in get_buffer().
-     * pic.data[*] must be set to NULL.
-     * May be called from a different thread if frame multithreading is used,
-     * but not by more than one thread at once, so does not need to be reentrant.
-     * - encoding: unused
-     * - decoding: Set by libavcodec, user can override.
-     */
-    void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
+    int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
 
     /**
-     * Called at the beginning of a frame to get cr buffer for it.
-     * Buffer type (size, hints) must be the same. libavcodec won't check it.
-     * libavcodec will pass previous buffer in pic, function should return
-     * same buffer or new buffer with old frame "painted" into it.
-     * If pic.data[0] == NULL must behave like get_buffer().
-     * if CODEC_CAP_DR1 is not set then reget_buffer() must call
-     * avcodec_default_reget_buffer() instead of providing buffers allocated by
-     * some other means.
+     * If non-zero, the decoded audio and video frames returned from
+     * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted
+     * and are valid indefinitely. The caller must free them with
+     * av_frame_unref() when they are not needed anymore.
+     * Otherwise, the decoded frames must not be freed by the caller and are
+     * only valid until the next decode call.
+     *
      * - encoding: unused
-     * - decoding: Set by libavcodec, user can override.
+     * - decoding: set by the caller before avcodec_open2().
      */
-    int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
-
+    int refcounted_frames;
 
     /* - encoding parameters */
     float qcompress;  ///< amount of qscale change between easy & hard scenes (0.0-1.0)
@@ -2516,12 +2288,16 @@ typedef struct AVCodecContext {
      */
     int workaround_bugs;
 #define FF_BUG_AUTODETECT       1  ///< autodetection
+#if FF_API_OLD_MSMPEG4
 #define FF_BUG_OLD_MSMPEG4      2
+#endif
 #define FF_BUG_XVID_ILACE       4
 #define FF_BUG_UMP4             8
 #define FF_BUG_NO_PADDING       16
 #define FF_BUG_AMV              32
+#if FF_API_AC_VLC
 #define FF_BUG_AC_VLC           0  ///< Will be removed, libavcodec can now handle these non-compliant files by default.
+#endif
 #define FF_BUG_QPEL_CHROMA      64
 #define FF_BUG_STD_QPEL         128
 #define FF_BUG_QPEL_CHROMA2     256
@@ -2571,7 +2347,12 @@ typedef struct AVCodecContext {
 #define FF_DEBUG_BITSTREAM   4
 #define FF_DEBUG_MB_TYPE     8
 #define FF_DEBUG_QP          16
+#if FF_API_DEBUG_MV
+/**
+ * @deprecated this option does nothing
+ */
 #define FF_DEBUG_MV          32
+#endif
 #define FF_DEBUG_DCT_COEFF   0x00000040
 #define FF_DEBUG_SKIP        0x00000080
 #define FF_DEBUG_STARTCODE   0x00000100
@@ -2579,20 +2360,23 @@ typedef struct AVCodecContext {
 #define FF_DEBUG_ER          0x00000400
 #define FF_DEBUG_MMCO        0x00000800
 #define FF_DEBUG_BUGS        0x00001000
+#if FF_API_DEBUG_MV
 #define FF_DEBUG_VIS_QP      0x00002000
 #define FF_DEBUG_VIS_MB_TYPE 0x00004000
+#endif
 #define FF_DEBUG_BUFFERS     0x00008000
 #define FF_DEBUG_THREADS     0x00010000
 
+#if FF_API_DEBUG_MV
     /**
-     * debug
-     * - encoding: Set by user.
-     * - decoding: Set by user.
+     * @deprecated this option does not have any effect
      */
+    attribute_deprecated
     int debug_mv;
 #define FF_DEBUG_VIS_MV_P_FOR  0x00000001 //visualize forward predicted MVs of P frames
 #define FF_DEBUG_VIS_MV_B_FOR  0x00000002 //visualize forward predicted MVs of B frames
 #define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
+#endif
 
     /**
      * Error recognition; may misdetect some more or less valid parts as errors.
@@ -2600,6 +2384,13 @@ typedef struct AVCodecContext {
      * - decoding: Set by user.
      */
     int err_recognition;
+
+/**
+ * Verify checksums embedded in the bitstream (could be of either encoded or
+ * decoded data, depending on the codec) and print an error message on mismatch.
+ * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the
+ * decoder returning an error.
+ */
 #define AV_EF_CRCCHECK  (1<<0)
 #define AV_EF_BITSTREAM (1<<1)
 #define AV_EF_BUFFER    (1<<2)
@@ -2663,37 +2454,19 @@ typedef struct AVCodecContext {
 #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
-#if FF_API_MMI
-#define FF_IDCT_MMI           5
-#endif
 #define FF_IDCT_ARM           7
 #define FF_IDCT_ALTIVEC       8
 #define FF_IDCT_SH4           9
 #define FF_IDCT_SIMPLEARM     10
-#define FF_IDCT_H264          11
-#define FF_IDCT_VP3           12
 #define FF_IDCT_IPP           13
 #define FF_IDCT_XVIDMMX       14
-#define FF_IDCT_CAVS          15
 #define FF_IDCT_SIMPLEARMV5TE 16
 #define FF_IDCT_SIMPLEARMV6   17
 #define FF_IDCT_SIMPLEVIS     18
-#define FF_IDCT_WMV2          19
 #define FF_IDCT_FAAN          20
-#define FF_IDCT_EA            21
 #define FF_IDCT_SIMPLENEON    22
+#if FF_API_ARCH_ALPHA
 #define FF_IDCT_SIMPLEALPHA   23
-#define FF_IDCT_BINK          24
-
-#if FF_API_DSP_MASK
-    /**
-     * Unused.
-     * @deprecated use av_set_cpu_flags_mask() instead.
-     */
-    attribute_deprecated unsigned dsp_mask;
 #endif
 
     /**
@@ -2710,17 +2483,21 @@ typedef struct AVCodecContext {
      */
     int bits_per_raw_sample;
 
+#if FF_API_LOWRES
     /**
      * low resolution decoding, 1-> 1/2 size, 2->1/4 size
      * - encoding: unused
      * - decoding: Set by user.
+     *
+     * @deprecated use decoder private options instead
      */
     attribute_deprecated int lowres;
+#endif
 
     /**
      * the picture in the bitstream
      * - encoding: Set by libavcodec.
-     * - decoding: Set by libavcodec.
+     * - decoding: unused
      */
     AVFrame *coded_frame;
 
@@ -2792,13 +2569,13 @@ typedef struct AVCodecContext {
      */
     int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
 
+#if FF_API_THREAD_OPAQUE
     /**
-     * thread opaque
-     * Can be used by execute() to store some per AVCodecContext stuff.
-     * - encoding: set by execute()
-     * - decoding: set by execute()
+     * @deprecated this field should not be used from outside of lavc
      */
+    attribute_deprecated
     void *thread_opaque;
+#endif
 
     /**
      * noise vs. sse weight for the nsse comparsion function
@@ -2824,6 +2601,8 @@ typedef struct AVCodecContext {
 #define FF_PROFILE_AAC_HE_V2 28
 #define FF_PROFILE_AAC_LD   22
 #define FF_PROFILE_AAC_ELD  38
+#define FF_PROFILE_MPEG2_AAC_LOW 128
+#define FF_PROFILE_MPEG2_AAC_HE  131
 
 #define FF_PROFILE_DTS         20
 #define FF_PROFILE_DTS_ES      30
@@ -2877,6 +2656,12 @@ typedef struct AVCodecContext {
 #define FF_PROFILE_MPEG4_SIMPLE_STUDIO             14
 #define FF_PROFILE_MPEG4_ADVANCED_SIMPLE           15
 
+#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0   0
+#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1   1
+#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION  2
+#define FF_PROFILE_JPEG2000_DCINEMA_2K              3
+#define FF_PROFILE_JPEG2000_DCINEMA_4K              4
+
     /**
      * level
      * - encoding: Set by user.
@@ -2917,21 +2702,22 @@ typedef struct AVCodecContext {
     uint8_t *subtitle_header;
     int subtitle_header_size;
 
+#if FF_API_ERROR_RATE
     /**
-     * Simulates errors in the bitstream to test error concealment.
-     * - encoding: Set by user.
-     * - decoding: unused
+     * @deprecated use the 'error_rate' private AVOption of the mpegvideo
+     * encoders
      */
+    attribute_deprecated
     int error_rate;
+#endif
 
+#if FF_API_CODEC_PKT
     /**
-     * Current packet as passed into the decoder, to avoid having
-     * to pass the packet into every function. Currently only valid
-     * inside lavc and get/release_buffer callbacks.
-     * - decoding: set by avcodec_decode_*, read by get_buffer() for setting pkt_pts
-     * - encoding: unused
+     * @deprecated this field is not supposed to be accessed from outside lavc
      */
+    attribute_deprecated
     AVPacket *pkt;
+#endif
 
     /**
      * VBV delay coded in the last frame (in periods of a 27 MHz clock).
@@ -2982,7 +2768,9 @@ typedef struct AVCodec {
     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
+#if FF_API_LOWRES
     attribute_deprecated uint8_t max_lowres; ///< maximum value for lowres supported by the decoder
+#endif
     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}
 
@@ -3309,20 +3097,21 @@ const AVClass *avcodec_get_class(void);
  */
 int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
 
+#if FF_API_AVFRAME_LAVC
 /**
- * Allocate an AVFrame and set its fields to default values.  The resulting
- * struct must be freed using avcodec_free_frame().
- *
- * @return An AVFrame filled with default values or NULL on failure.
- * @see avcodec_get_frame_defaults
+ * @deprecated use av_frame_alloc()
  */
+attribute_deprecated
 AVFrame *avcodec_alloc_frame(void);
 
 /**
  * Set the fields of the given AVFrame to default values.
  *
  * @param frame The AVFrame of which the fields should be set to default values.
+ *
+ * @deprecated use av_frame_unref()
  */
+attribute_deprecated
 void avcodec_get_frame_defaults(AVFrame *frame);
 
 /**
@@ -3334,8 +3123,12 @@ void avcodec_get_frame_defaults(AVFrame *frame);
  * @warning this function does NOT free the data buffers themselves
  * (it does not know how, since they might have been allocated with
  *  a custom get_buffer()).
+ *
+ * @deprecated use av_frame_free()
  */
+attribute_deprecated
 void avcodec_free_frame(AVFrame **frame);
+#endif
 
 /**
  * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
@@ -3402,10 +3195,14 @@ void avsubtitle_free(AVSubtitle *sub);
  * @{
  */
 
+#if FF_API_DESTRUCT_PACKET
 /**
  * Default packet destructor.
+ * @deprecated use the AVBuffer API instead
  */
+attribute_deprecated
 void av_destruct_packet(AVPacket *pkt);
+#endif
 
 /**
  * Initialize optional fields of a packet with default values.
@@ -3444,6 +3241,21 @@ void av_shrink_packet(AVPacket *pkt, int size);
 int av_grow_packet(AVPacket *pkt, int grow_by);
 
 /**
+ * Initialize a reference-counted packet from av_malloc()ed data.
+ *
+ * @param pkt packet to be initialized. This function will set the data, size,
+ *        buf and destruct fields, all others are left untouched.
+ * @param data Data allocated by av_malloc() to be used as packet data. If this
+ *        function returns successfully, the data is owned by the underlying AVBuffer.
+ *        The caller may not access the data through other means.
+ * @param size size of data in bytes, without the padding. I.e. the full buffer
+ *        size is assumed to be size + FF_INPUT_BUFFER_PADDING_SIZE.
+ *
+ * @return 0 on success, a negative AVERROR on error
+ */
+int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size);
+
+/**
  * @warning This is a hack - the packet memory allocation stuff is broken. The
  * packet is allocated if it was not really allocated.
  */
@@ -3490,6 +3302,66 @@ uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
                                  int *size);
 
 /**
+ * Convenience function to free all the side data stored.
+ * All the other fields stay untouched.
+ *
+ * @param pkt packet
+ */
+void av_packet_free_side_data(AVPacket *pkt);
+
+/**
+ * Setup a new reference to the data described by a given packet
+ *
+ * If src is reference-counted, setup dst as a new reference to the
+ * buffer in src. Otherwise allocate a new buffer in dst and copy the
+ * data from src into it.
+ *
+ * All the other fields are copied from src.
+ *
+ * @see av_packet_unref
+ *
+ * @param dst Destination packet
+ * @param src Source packet
+ *
+ * @return 0 on success, a negative AVERROR on error.
+ */
+int av_packet_ref(AVPacket *dst, AVPacket *src);
+
+/**
+ * Wipe the packet.
+ *
+ * Unreference the buffer referenced by the packet and reset the
+ * remaining packet fields to their default values.
+ *
+ * @param pkt The packet to be unreferenced.
+ */
+void av_packet_unref(AVPacket *pkt);
+
+/**
+ * Move every field in src to dst and reset src.
+ *
+ * @see av_packet_unref
+ *
+ * @param src Source packet, will be reset
+ * @param dst Destination packet
+ */
+void av_packet_move_ref(AVPacket *dst, AVPacket *src);
+
+/**
+ * Copy only "properties" fields from src to dst.
+ *
+ * Properties for the purpose of this function are all the fields
+ * beside those related to the packet data (buf, data, size)
+ *
+ * @param dst Destination packet
+ * @param src Source packet
+ *
+ * @return 0 on success AVERROR on failure.
+ *
+ */
+int av_packet_copy_props(AVPacket *dst, const AVPacket *src);
+
+/**
  * @}
  */
 
@@ -3514,9 +3386,18 @@ AVCodec *avcodec_find_decoder(enum AVCodecID id);
  */
 AVCodec *avcodec_find_decoder_by_name(const char *name);
 
-int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
-void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
-int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
+#if FF_API_GET_BUFFER
+attribute_deprecated int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
+attribute_deprecated void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
+attribute_deprecated int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
+#endif
+
+/**
+ * The default callback for AVCodecContext.get_buffer2(). It is made public so
+ * it can be called by custom get_buffer2() implementations for decoders without
+ * CODEC_CAP_DR1 set.
+ */
+int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags);
 
 /**
  * Return the amount of padding in pixels which the get_buffer callback must
@@ -3550,92 +3431,47 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
 void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
                                int linesize_align[AV_NUM_DATA_POINTERS]);
 
-#if FF_API_OLD_DECODE_AUDIO
-/**
- * Wrapper function which calls avcodec_decode_audio4.
- *
- * @deprecated Use avcodec_decode_audio4 instead.
- *
- * Decode the audio frame of size avpkt->size from avpkt->data into samples.
- * Some decoders may support multiple frames in a single AVPacket, such
- * decoders would then just decode the first frame. In this case,
- * avcodec_decode_audio3 has to be called again with an AVPacket that contains
- * the remaining data in order to decode the second frame etc.
- * If no frame
- * could be outputted, frame_size_ptr is zero. Otherwise, it is the
- * decompressed frame size in bytes.
- *
- * @warning You must set frame_size_ptr to the allocated size of the
- * output buffer before calling avcodec_decode_audio3().
- *
- * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than
- * the actual read bytes because some optimized bitstream readers read 32 or 64
- * bits at once and could read over the end.
- *
- * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that
- * no overreading happens for damaged MPEG streams.
- *
- * @warning You must not provide a custom get_buffer() when using
- * avcodec_decode_audio3().  Doing so will override it with
- * avcodec_default_get_buffer.  Use avcodec_decode_audio4() instead,
- * which does allow the application to provide a custom get_buffer().
- *
- * @note You might have to align the input buffer avpkt->data and output buffer
- * samples. The alignment requirements depend on the CPU: On some CPUs it isn't
- * necessary at all, on others it won't work at all if not aligned and on others
- * it will work but it will have an impact on performance.
- *
- * In practice, avpkt->data should have 4 byte alignment at minimum and
- * samples should be 16 byte aligned unless the CPU doesn't need it
- * (AltiVec and SSE do).
- *
- * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
- * between input and output, these need to be fed with avpkt->data=NULL,
- * avpkt->size=0 at the end to return the remaining frames.
- *
- * @param avctx the codec context
- * @param[out] samples the output buffer, sample type in avctx->sample_fmt
- *                     If the sample format is planar, each channel plane will
- *                     be the same size, with no padding between channels.
- * @param[in,out] frame_size_ptr the output buffer size in bytes
- * @param[in] avpkt The input AVPacket containing the input buffer.
- *            You can create such packet with av_init_packet() and by then setting
- *            data and size, some decoders might in addition need other fields.
- *            All decoders are designed to use the least fields possible though.
- * @return On error a negative value is returned, otherwise the number of bytes
- * used or zero if no frame data was decompressed (used) from the input AVPacket.
- */
-attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
-                         int *frame_size_ptr,
-                         AVPacket *avpkt);
-#endif
-
 /**
  * Decode the audio frame of size avpkt->size from avpkt->data into frame.
  *
  * Some decoders may support multiple frames in a single AVPacket. Such
- * decoders would then just decode the first frame. In this case,
- * avcodec_decode_audio4 has to be called again with an AVPacket containing
- * the remaining data in order to decode the second frame, etc...
- * Even if no frames are returned, the packet needs to be fed to the decoder
- * with remaining data until it is completely consumed or an error occurs.
+ * decoders would then just decode the first frame and the return value would be
+ * less than the packet size. In this case, avcodec_decode_audio4 has to be
+ * called again with an AVPacket containing the remaining data in order to
+ * decode the second frame, etc...  Even if no frames are returned, the packet
+ * needs to be fed to the decoder with remaining data until it is completely
+ * consumed or an error occurs.
+ *
+ * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input
+ * and output. This means that for some packets they will not immediately
+ * produce decoded output and need to be flushed at the end of decoding to get
+ * all the decoded data. Flushing is done by calling this function with packets
+ * with avpkt->data set to NULL and avpkt->size set to 0 until it stops
+ * returning samples. It is safe to flush even those decoders that are not
+ * marked with CODEC_CAP_DELAY, then no samples will be returned.
  *
  * @warning The input buffer, avpkt->data must be FF_INPUT_BUFFER_PADDING_SIZE
  *          larger than the actual read bytes because some optimized bitstream
  *          readers read 32 or 64 bits at once and could read over the end.
  *
- * @note You might have to align the input buffer. The alignment requirements
- *       depend on the CPU and the decoder.
- *
  * @param      avctx the codec context
  * @param[out] frame The AVFrame in which to store decoded audio samples.
- *                   Decoders request a buffer of a particular size by setting
- *                   AVFrame.nb_samples prior to calling get_buffer(). The
- *                   decoder may, however, only utilize part of the buffer by
- *                   setting AVFrame.nb_samples to a smaller value in the
- *                   output frame.
+ *                   The decoder will allocate a buffer for the decoded frame by
+ *                   calling the AVCodecContext.get_buffer2() callback.
+ *                   When AVCodecContext.refcounted_frames is set to 1, the frame is
+ *                   reference counted and the returned reference belongs to the
+ *                   caller. The caller must release the frame using av_frame_unref()
+ *                   when the frame is no longer needed. The caller may safely write
+ *                   to the frame if av_frame_is_writable() returns 1.
+ *                   When AVCodecContext.refcounted_frames is set to 0, the returned
+ *                   reference belongs to the decoder and is valid only until the
+ *                   next call to this function or until closing or flushing the
+ *                   decoder. The caller may not write to it.
  * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is
- *                           non-zero.
+ *                           non-zero. Note that this field being set to zero
+ *                           does not mean that an error has occurred. For
+ *                           decoders with CODEC_CAP_DELAY set, no given decode
+ *                           call is guaranteed to produce a frame.
  * @param[in]  avpkt The input AVPacket containing the input buffer.
  *                   At least avpkt->data and avpkt->size should be set. Some
  *                   decoders might also require additional fields to be set.
@@ -3658,25 +3494,24 @@ int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
  * @warning The end of the input buffer buf should be set to 0 to ensure that
  * no overreading happens for damaged MPEG streams.
  *
- * @note You might have to align the input buffer avpkt->data.
- * The alignment requirements depend on the CPU: on some CPUs it isn't
- * necessary at all, on others it won't work at all if not aligned and on others
- * it will work but it will have an impact on performance.
- *
- * In practice, avpkt->data should have 4 byte alignment at minimum.
- *
  * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
  * between input and output, these need to be fed with avpkt->data=NULL,
  * avpkt->size=0 at the end to return the remaining frames.
  *
  * @param avctx the codec context
  * @param[out] picture The AVFrame in which the decoded video frame will be stored.
- *             Use avcodec_alloc_frame to get an AVFrame, the codec will
- *             allocate memory for the actual bitmap.
- *             with default get/release_buffer(), the decoder frees/reuses the bitmap as it sees fit.
- *             with overridden get/release_buffer() (needs CODEC_CAP_DR1) the user decides into what buffer the decoder
- *                   decodes and the decoder tells the user once it does not need the data anymore,
- *                   the user app can at this point free/reuse/keep the memory as it sees fit.
+ *             Use av_frame_alloc() to get an AVFrame. The codec will
+ *             allocate memory for the actual bitmap by calling the
+ *             AVCodecContext.get_buffer2() callback.
+ *             When AVCodecContext.refcounted_frames is set to 1, the frame is
+ *             reference counted and the returned reference belongs to the
+ *             caller. The caller must release the frame using av_frame_unref()
+ *             when the frame is no longer needed. The caller may safely write
+ *             to the frame if av_frame_is_writable() returns 1.
+ *             When AVCodecContext.refcounted_frames is set to 0, the returned
+ *             reference belongs to the decoder and is valid only until the
+ *             next call to this function or until closing or flushing the
+ *             decoder. The caller may not write to it.
  *
  * @param[in] avpkt The input AVpacket containing the input buffer.
  *            You can create such packet with av_init_packet() and by then setting
@@ -3716,6 +3551,13 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
  * @{
  */
 
+enum AVPictureStructure {
+    AV_PICTURE_STRUCTURE_UNKNOWN,      //< unknown
+    AV_PICTURE_STRUCTURE_TOP_FIELD,    //< coded as top field
+    AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field
+    AV_PICTURE_STRUCTURE_FRAME,        //< coded as frame
+};
+
 typedef struct AVCodecParserContext {
     void *priv_data;
     struct AVCodecParser *parser;
@@ -3849,6 +3691,26 @@ typedef struct AVCodecParserContext {
      * For all other types, this is in units of AVCodecContext.time_base.
      */
     int duration;
+
+    enum AVFieldOrder field_order;
+
+    /**
+     * Indicate whether a picture is coded as a frame, top field or bottom field.
+     *
+     * For example, H.264 field_pic_flag equal to 0 corresponds to
+     * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag
+     * equal to 1 and bottom_field_flag equal to 0 corresponds to
+     * AV_PICTURE_STRUCTURE_TOP_FIELD.
+     */
+    enum AVPictureStructure picture_structure;
+
+    /**
+     * Picture number incremented in presentation or output order.
+     * This field may be reinitialized at the first picture of a new sequence.
+     *
+     * For example, this corresponds to H.264 PicOrderCnt.
+     */
+    int output_picture_number;
 } AVCodecParserContext;
 
 typedef struct AVCodecParser {
@@ -3940,36 +3802,6 @@ AVCodec *avcodec_find_encoder(enum AVCodecID id);
  */
 AVCodec *avcodec_find_encoder_by_name(const char *name);
 
-#if FF_API_OLD_ENCODE_AUDIO
-/**
- * Encode an audio frame from samples into buf.
- *
- * @deprecated Use avcodec_encode_audio2 instead.
- *
- * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large.
- * However, for codecs with avctx->frame_size equal to 0 (e.g. PCM) the user
- * will know how much space is needed because it depends on the value passed
- * in buf_size as described below. In that case a lower value can be used.
- *
- * @param avctx the codec context
- * @param[out] buf the output buffer
- * @param[in] buf_size the output buffer size
- * @param[in] samples the input buffer containing the samples
- * The number of samples read from this buffer is frame_size*channels,
- * both of which are defined in avctx.
- * For codecs which have avctx->frame_size equal to 0 (e.g. PCM) the number of
- * samples read from samples is equal to:
- * buf_size * 8 / (avctx->channels * av_get_bits_per_sample(avctx->codec_id))
- * This also implies that av_get_bits_per_sample() must not return 0 for these
- * codecs.
- * @return On error a negative value is returned, on success zero or the number
- * of bytes used to encode the data read from the input buffer.
- */
-int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx,
-                                              uint8_t *buf, int buf_size,
-                                              const short *samples);
-#endif
-
 /**
  * Encode a frame of audio.
  *
@@ -4011,26 +3843,6 @@ int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx,
 int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt,
                           const AVFrame *frame, int *got_packet_ptr);
 
-#if FF_API_OLD_ENCODE_VIDEO
-/**
- * @deprecated use avcodec_encode_video2() instead.
- *
- * Encode a video frame from pict into buf.
- * The input picture should be
- * stored using a specific format, namely avctx.pix_fmt.
- *
- * @param avctx the codec context
- * @param[out] buf the output buffer for the bitstream of encoded frame
- * @param[in] buf_size the size of the output buffer in bytes
- * @param[in] pict the input picture to encode
- * @return On error a negative value is returned, on success zero or the number
- * of bytes used from the output buffer.
- */
-attribute_deprecated
-int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
-                         const AVFrame *pict);
-#endif
-
 /**
  * Encode a frame of video.
  *
@@ -4076,103 +3888,6 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
  * @}
  */
 
-#if FF_API_AVCODEC_RESAMPLE
-/**
- * @defgroup lavc_resample Audio resampling
- * @ingroup libavc
- * @deprecated use libavresample instead
- *
- * @{
- */
-struct ReSampleContext;
-struct AVResampleContext;
-
-typedef struct ReSampleContext ReSampleContext;
-
-/**
- *  Initialize audio resampling context.
- *
- * @param output_channels  number of output channels
- * @param input_channels   number of input channels
- * @param output_rate      output sample rate
- * @param input_rate       input sample rate
- * @param sample_fmt_out   requested output sample format
- * @param sample_fmt_in    input sample format
- * @param filter_length    length of each FIR filter in the filterbank relative to the cutoff frequency
- * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
- * @param linear           if 1 then the used FIR filter will be linearly interpolated
-                           between the 2 closest, if 0 the closest will be used
- * @param cutoff           cutoff frequency, 1.0 corresponds to half the output sampling rate
- * @return allocated ReSampleContext, NULL if error occurred
- */
-attribute_deprecated
-ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
-                                        int output_rate, int input_rate,
-                                        enum AVSampleFormat sample_fmt_out,
-                                        enum AVSampleFormat sample_fmt_in,
-                                        int filter_length, int log2_phase_count,
-                                        int linear, double cutoff);
-
-attribute_deprecated
-int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples);
-
-/**
- * Free resample context.
- *
- * @param s a non-NULL pointer to a resample context previously
- *          created with av_audio_resample_init()
- */
-attribute_deprecated
-void audio_resample_close(ReSampleContext *s);
-
-
-/**
- * Initialize an audio resampler.
- * Note, if either rate is not an integer then simply scale both rates up so they are.
- * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq
- * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
- * @param linear If 1 then the used FIR filter will be linearly interpolated
-                 between the 2 closest, if 0 the closest will be used
- * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
- */
-attribute_deprecated
-struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff);
-
-/**
- * Resample an array of samples using a previously configured context.
- * @param src an array of unconsumed samples
- * @param consumed the number of samples of src which have been consumed are returned here
- * @param src_size the number of unconsumed samples available
- * @param dst_size the amount of space in samples available in dst
- * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context.
- * @return the number of samples written in dst or -1 if an error occurred
- */
-attribute_deprecated
-int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx);
-
-
-/**
- * Compensate samplerate/timestamp drift. The compensation is done by changing
- * the resampler parameters, so no audible clicks or similar distortions occur
- * @param compensation_distance distance in output samples over which the compensation should be performed
- * @param sample_delta number of output samples which should be output less
- *
- * example: av_resample_compensate(c, 10, 500)
- * here instead of 510 samples only 500 samples would be output
- *
- * note, due to rounding the actual compensation might be slightly different,
- * especially if the compensation_distance is large and the in_rate used during init is small
- */
-attribute_deprecated
-void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance);
-attribute_deprecated
-void av_resample_close(struct AVResampleContext *c);
-
-/**
- * @}
- */
-#endif
-
 /**
  * @addtogroup lavc_picture
  * @{
@@ -4256,11 +3971,16 @@ int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
  */
 int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);
 
+#if FF_API_DEINTERLACE
 /**
  *  deinterlace - if not supported return -1
+ *
+ * @deprecated - use yadif (in libavfilter) instead
  */
+attribute_deprecated
 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
                           enum AVPixelFormat pix_fmt, int width, int height);
+#endif
 /**
  * Copy image src to dst. Wraps av_picture_data_copy() above.
  */
@@ -4339,36 +4059,6 @@ unsigned int avcodec_pix_fmt_to_codec_tag(enum AVPixelFormat 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.
- *
- * Find the best pixel format to convert to given a certain source pixel
- * 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_fmt() 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_mask parameter.
- *
- * @code
- * src_pix_fmt = AV_PIX_FMT_YUV420P;
- * 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
- *
- * @param[in] pix_fmt_mask bitmask determining which pixel format 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[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.
- */
-attribute_deprecated
-enum AVPixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum AVPixelFormat src_pix_fmt,
-                              int has_alpha, int *loss_ptr);
-#endif /* FF_API_FIND_BEST_PIX_FMT */
-
 /**
  * Find the best pixel format to convert to given a certain source pixel
  * format.  When converting from one pixel format to another, information loss
@@ -4396,7 +4086,13 @@ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const en
  * @}
  */
 
+#if FF_API_SET_DIMENSIONS
+/**
+ * @deprecated this function is not supposed to be used from outside of lavc
+ */
+attribute_deprecated
 void avcodec_set_dimensions(AVCodecContext *s, int width, int height);
+#endif
 
 /**
  * Put a string representing the codec tag codec_tag in buf.
@@ -4443,12 +4139,16 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
                              int buf_size, int align);
 
 /**
- * Flush buffers, should be called when seeking or when switching to a different stream.
+ * Reset the internal decoder state / flush internal buffers. Should be called
+ * e.g. when seeking or when switching to a different stream.
+ *
+ * @note when refcounted frames are not used (i.e. avctx->refcounted_frames is 0),
+ * this invalidates the frames previously returned from the decoder. When
+ * refcounted frames are used, the decoder just releases any references it might
+ * keep internally, but the caller's reference remains valid.
  */
 void avcodec_flush_buffers(AVCodecContext *avctx);
 
-void avcodec_default_free_buffers(AVCodecContext *s);
-
 /**
  * Return codec bits per sample.
  *
@@ -4510,27 +4210,6 @@ AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f);
 /* memory */
 
 /**
- * Reallocate the given block if it is not large enough, otherwise do nothing.
- *
- * @see av_realloc
- */
-void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size);
-
-/**
- * Allocate a buffer, reusing the given one if large enough.
- *
- * Contrary to av_fast_realloc the current buffer contents might not be
- * preserved and on error the old buffer is freed, thus no special
- * handling to avoid memleaks is necessary.
- *
- * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer
- * @param size size of the buffer *ptr points to
- * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and
- *                 *size 0 if an error occurred.
- */
-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
@@ -4548,6 +4227,7 @@ void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size);
  */
 unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
 
+#if FF_API_MISSING_SAMPLE
 /**
  * Log a generic warning message about a missing feature. This function is
  * intended to be used internally by Libav (libavcodec, libavformat, etc.)
@@ -4559,7 +4239,9 @@ unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
  * If want_sample is non-zero, additional verbage will be added to the log
  * message which tells the user how to report samples to the development
  * mailing list.
+ * @deprecated Use avpriv_report_missing_feature() instead.
  */
+attribute_deprecated
 void av_log_missing_feature(void *avc, const char *feature, int want_sample);
 
 /**
@@ -4569,8 +4251,11 @@ void av_log_missing_feature(void *avc, const char *feature, int want_sample);
  * @param[in] avc a pointer to an arbitrary struct of which the first field is
  * a pointer to an AVClass struct
  * @param[in] msg string containing an optional message, or NULL if no message
+ * @deprecated Use avpriv_request_sample() instead.
  */
+attribute_deprecated
 void av_log_ask_for_sample(void *avc, const char *msg, ...) av_printf_format(2, 3);
+#endif /* FF_API_MISSING_SAMPLE */
 
 /**
  * Register the hardware accelerator hwaccel.
diff --git a/libavcodec/avfft.c b/libavcodec/avfft.c
index 9ed06fb..513f57e 100644
--- a/libavcodec/avfft.c
+++ b/libavcodec/avfft.c
@@ -16,6 +16,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 #include "avfft.h"
 #include "fft.h"
@@ -44,7 +45,7 @@ void av_fft_calc(FFTContext *s, FFTComplex *z)
     s->fft_calc(s, z);
 }
 
-void av_fft_end(FFTContext *s)
+av_cold void av_fft_end(FFTContext *s)
 {
     if (s) {
         ff_fft_end(s);
@@ -79,7 +80,7 @@ void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
     s->mdct_calc(s, output, input);
 }
 
-void av_mdct_end(FFTContext *s)
+av_cold void av_mdct_end(FFTContext *s)
 {
     if (s) {
         ff_mdct_end(s);
@@ -106,7 +107,7 @@ void av_rdft_calc(RDFTContext *s, FFTSample *data)
     s->rdft_calc(s, data);
 }
 
-void av_rdft_end(RDFTContext *s)
+av_cold void av_rdft_end(RDFTContext *s)
 {
     if (s) {
         ff_rdft_end(s);
@@ -133,7 +134,7 @@ void av_dct_calc(DCTContext *s, FFTSample *data)
     s->dct_calc(s, data);
 }
 
-void av_dct_end(DCTContext *s)
+av_cold void av_dct_end(DCTContext *s)
 {
     if (s) {
         ff_dct_end(s);
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index cb24948..c0a0f8c 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -22,22 +22,26 @@
 #include <string.h>
 
 #include "libavutil/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "avcodec.h"
+#if FF_API_DESTRUCT_PACKET
 
 void av_destruct_packet(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;
+/* a dummy destruct callback for the callers that assume AVPacket.destruct ==
+ * NULL => static data */
+static void dummy_destruct_packet(AVPacket *pkt)
+{
+    av_assert0(0);
 }
+#endif
 
 void av_init_packet(AVPacket *pkt)
 {
@@ -48,27 +52,48 @@ void av_init_packet(AVPacket *pkt)
     pkt->convergence_duration = 0;
     pkt->flags                = 0;
     pkt->stream_index         = 0;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
     pkt->destruct             = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    pkt->buf                  = NULL;
     pkt->side_data            = NULL;
     pkt->side_data_elems      = 0;
 }
 
+static int packet_alloc(AVBufferRef **buf, int size)
+{
+    int ret;
+    if ((unsigned)size >= (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
+        return AVERROR(EINVAL);
+
+    ret = av_buffer_realloc(buf, size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (ret < 0)
+        return ret;
+
+    memset((*buf)->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+    return 0;
+}
+
 int av_new_packet(AVPacket *pkt, int size)
 {
-    uint8_t *data = NULL;
-    if ((unsigned)size < (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
-        data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (data) {
-        memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-    } else
-        size = 0;
+    AVBufferRef *buf = NULL;
+    int ret = packet_alloc(&buf, size);
+    if (ret < 0)
+        return ret;
 
     av_init_packet(pkt);
-    pkt->data     = data;
+    pkt->buf      = buf;
+    pkt->data     = buf->data;
     pkt->size     = size;
-    pkt->destruct = av_destruct_packet;
-    if (!data)
-        return AVERROR(ENOMEM);
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+    pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
     return 0;
 }
 
@@ -82,33 +107,75 @@ void av_shrink_packet(AVPacket *pkt, int size)
 
 int av_grow_packet(AVPacket *pkt, int grow_by)
 {
-    void *new_ptr;
+    int new_size;
     av_assert0((unsigned)pkt->size <= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE);
     if (!pkt->size)
         return av_new_packet(pkt, grow_by);
     if ((unsigned)grow_by >
         INT_MAX - (pkt->size + FF_INPUT_BUFFER_PADDING_SIZE))
         return -1;
-    new_ptr = av_realloc(pkt->data,
-                         pkt->size + grow_by + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!new_ptr)
-        return AVERROR(ENOMEM);
-    pkt->data  = new_ptr;
+
+    new_size = pkt->size + grow_by + FF_INPUT_BUFFER_PADDING_SIZE;
+    if (pkt->buf) {
+        int ret = av_buffer_realloc(&pkt->buf, new_size);
+        if (ret < 0)
+            return ret;
+    } else {
+        pkt->buf = av_buffer_alloc(new_size);
+        if (!pkt->buf)
+            return AVERROR(ENOMEM);
+        memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+        pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    }
+    pkt->data  = pkt->buf->data;
     pkt->size += grow_by;
     memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
     return 0;
 }
 
-#define DUP_DATA(dst, src, size, padding)                               \
+int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
+{
+    if (size >= INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
+        return AVERROR(EINVAL);
+
+    pkt->buf = av_buffer_create(data, size + FF_INPUT_BUFFER_PADDING_SIZE,
+                                av_buffer_default_free, NULL, 0);
+    if (!pkt->buf)
+        return AVERROR(ENOMEM);
+
+    pkt->data = data;
+    pkt->size = size;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+    pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+    return 0;
+}
+
+#define ALLOC_MALLOC(data, size) data = av_malloc(size)
+#define ALLOC_BUF(data, size)                \
+do {                                         \
+    av_buffer_realloc(&pkt->buf, size);      \
+    data = pkt->buf ? pkt->buf->data : NULL; \
+} while (0)
+
+#define DUP_DATA(dst, src, size, padding, ALLOC)                        \
     do {                                                                \
         void *data;                                                     \
         if (padding) {                                                  \
             if ((unsigned)(size) >                                      \
                 (unsigned)(size) + FF_INPUT_BUFFER_PADDING_SIZE)        \
                 goto failed_alloc;                                      \
-            data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);      \
+            ALLOC(data, size + FF_INPUT_BUFFER_PADDING_SIZE);           \
         } else {                                                        \
-            data = av_malloc(size);                                     \
+            ALLOC(data, size);                                          \
         }                                                               \
         if (!data)                                                      \
             goto failed_alloc;                                          \
@@ -123,42 +190,71 @@ int av_dup_packet(AVPacket *pkt)
 {
     AVPacket tmp_pkt;
 
-    if (pkt->destruct == NULL && pkt->data) {
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (!pkt->buf && pkt->data
+#if FF_API_DESTRUCT_PACKET
+        && !pkt->destruct
+#endif
+        ) {
+FF_ENABLE_DEPRECATION_WARNINGS
         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;
+        DUP_DATA(pkt->data, tmp_pkt.data, pkt->size, 1, ALLOC_BUF);
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+        pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
 
         if (pkt->side_data_elems) {
             int i;
 
             DUP_DATA(pkt->side_data, tmp_pkt.side_data,
-                     pkt->side_data_elems * sizeof(*pkt->side_data), 0);
+                     pkt->side_data_elems * sizeof(*pkt->side_data), 0, ALLOC_MALLOC);
             memset(pkt->side_data, 0,
                    pkt->side_data_elems * sizeof(*pkt->side_data));
-            for (i = 0; i < pkt->side_data_elems; i++)
+            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);
+                         tmp_pkt.side_data[i].size, 1, ALLOC_MALLOC);
+                pkt->side_data[i].size = tmp_pkt.side_data[i].size;
+                pkt->side_data[i].type = tmp_pkt.side_data[i].type;
+            }
         }
     }
     return 0;
 
 failed_alloc:
-    av_destruct_packet(pkt);
+    av_free_packet(pkt);
     return AVERROR(ENOMEM);
 }
 
+void av_packet_free_side_data(AVPacket *pkt)
+{
+    int i;
+    for (i = 0; i < pkt->side_data_elems; i++)
+        av_free(pkt->side_data[i].data);
+    av_freep(&pkt->side_data);
+    pkt->side_data_elems = 0;
+}
+
 void av_free_packet(AVPacket *pkt)
 {
     if (pkt) {
-        if (pkt->destruct)
+FF_DISABLE_DEPRECATION_WARNINGS
+        if (pkt->buf)
+            av_buffer_unref(&pkt->buf);
+#if FF_API_DESTRUCT_PACKET
+        else if (pkt->destruct)
             pkt->destruct(pkt);
+        pkt->destruct = NULL;
+#endif
+FF_ENABLE_DEPRECATION_WARNINGS
         pkt->data            = NULL;
         pkt->size            = 0;
-        pkt->side_data       = NULL;
-        pkt->side_data_elems = 0;
+
+        av_packet_free_side_data(pkt);
     }
 }
 
@@ -217,3 +313,71 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
     }
     return AVERROR(ENOENT);
 }
+
+int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
+{
+    int i;
+
+    dst->pts                  = src->pts;
+    dst->dts                  = src->dts;
+    dst->pos                  = src->pos;
+    dst->duration             = src->duration;
+    dst->convergence_duration = src->convergence_duration;
+    dst->flags                = src->flags;
+    dst->stream_index         = src->stream_index;
+    dst->side_data_elems      = src->side_data_elems;
+
+    for (i = 0; i < src->side_data_elems; i++) {
+         enum AVPacketSideDataType type = src->side_data[i].type;
+         int size          = src->side_data[i].size;
+         uint8_t *src_data = src->side_data[i].data;
+         uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
+
+        if (!dst_data) {
+            av_packet_free_side_data(dst);
+            return AVERROR(ENOMEM);
+        }
+        memcpy(dst_data, src_data, size);
+    }
+
+    return 0;
+}
+
+void av_packet_unref(AVPacket *pkt)
+{
+    av_packet_free_side_data(pkt);
+    av_buffer_unref(&pkt->buf);
+    av_init_packet(pkt);
+    pkt->data = NULL;
+    pkt->size = 0;
+}
+
+int av_packet_ref(AVPacket *dst, AVPacket *src)
+{
+    int ret;
+
+    ret = av_packet_copy_props(dst, src);
+    if (ret < 0)
+        return ret;
+
+    if (!src->buf) {
+        ret = packet_alloc(&dst->buf, src->size);
+        if (ret < 0)
+            goto fail;
+        memcpy(dst->buf->data, src->data, src->size);
+    } else
+        dst->buf = av_buffer_ref(src->buf);
+
+    dst->size = src->size;
+    dst->data = dst->buf->data;
+    return 0;
+fail:
+    av_packet_free_side_data(dst);
+    return ret;
+}
+
+void av_packet_move_ref(AVPacket *dst, AVPacket *src)
+{
+    *dst = *src;
+    av_init_packet(src);
+}
diff --git a/libavcodec/avpicture.c b/libavcodec/avpicture.c
index 259fd8e..a50bbc4 100644
--- a/libavcodec/avpicture.c
+++ b/libavcodec/avpicture.c
@@ -75,7 +75,7 @@ int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
         }
     }
 
-    if (desc->flags & PIX_FMT_PAL)
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL)
         memcpy((unsigned char *)(((size_t)dest + 3) & ~3),
                src->data[1], 256 * 4);
 
@@ -92,7 +92,7 @@ int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
         return AVERROR(EINVAL);
     if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
         return ret;
-    if (desc->flags & PIX_FMT_PSEUDOPAL)
+    if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
         // do not include palette for these pseudo-paletted formats
         return width * height;
     return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
diff --git a/libavcodec/avs.c b/libavcodec/avs.c
index 98a53f2..53e3320 100644
--- a/libavcodec/avs.c
+++ b/libavcodec/avs.c
@@ -21,10 +21,11 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 
 
 typedef struct {
-    AVFrame picture;
+    AVFrame *frame;
 } AvsContext;
 
 typedef enum {
@@ -51,24 +52,23 @@ avs_decode_frame(AVCodecContext * avctx,
     int buf_size = avpkt->size;
     AvsContext *const avs = avctx->priv_data;
     AVFrame *picture = data;
-    AVFrame *const p =  &avs->picture;
+    AVFrame *const p =  avs->frame;
     const uint8_t *table, *vect;
     uint8_t *out;
-    int i, j, x, y, stride, vect_w = 3, vect_h = 3;
+    int i, j, x, y, stride, ret, vect_w = 3, vect_h = 3;
     AvsVideoSubType sub_type;
     AvsBlockType type;
     GetBitContext change_map;
 
-    if (avctx->reget_buffer(avctx, p)) {
+    if ((ret = ff_reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    p->reference = 1;
     p->pict_type = AV_PICTURE_TYPE_P;
     p->key_frame = 0;
 
-    out = avs->picture.data[0];
-    stride = avs->picture.linesize[0];
+    out    = p->data[0];
+    stride = p->linesize[0];
 
     if (buf_end - buf < 4)
         return AVERROR_INVALIDDATA;
@@ -78,7 +78,7 @@ avs_decode_frame(AVCodecContext * avctx,
 
     if (type == AVS_PALETTE) {
         int first, last;
-        uint32_t *pal = (uint32_t *) avs->picture.data[1];
+        uint32_t *pal = (uint32_t *) p->data[1];
 
         first = AV_RL16(buf);
         last = first + AV_RL16(buf + 2);
@@ -94,7 +94,7 @@ avs_decode_frame(AVCodecContext * avctx,
     }
 
     if (type != AVS_VIDEO)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     switch (sub_type) {
     case AVS_I_FRAME:
@@ -116,7 +116,7 @@ avs_decode_frame(AVCodecContext * avctx,
         break;
 
     default:
-      return -1;
+      return AVERROR_INVALIDDATA;
     }
 
     if (buf_end - buf < 256 * vect_w * vect_h)
@@ -149,7 +149,8 @@ avs_decode_frame(AVCodecContext * avctx,
             align_get_bits(&change_map);
     }
 
-    *picture   = avs->picture;
+    if ((ret = av_frame_ref(picture, p)) < 0)
+        return ret;
     *got_frame = 1;
 
     return buf_size;
@@ -157,22 +158,29 @@ avs_decode_frame(AVCodecContext * avctx,
 
 static av_cold int avs_decode_init(AVCodecContext * avctx)
 {
+    AvsContext *s = avctx->priv_data;
+
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
-    avcodec_set_dimensions(avctx, 318, 198);
+    ff_set_dimensions(avctx, 318, 198);
+
     return 0;
 }
 
 static av_cold int avs_decode_end(AVCodecContext *avctx)
 {
     AvsContext *s = avctx->priv_data;
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
+    av_frame_free(&s->frame);
     return 0;
 }
 
 
 AVCodec ff_avs_decoder = {
     .name           = "avs",
+    .long_name      = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_AVS,
     .priv_data_size = sizeof(AvsContext),
@@ -180,5 +188,4 @@ AVCodec ff_avs_decoder = {
     .decode         = avs_decode_frame,
     .close          = avs_decode_end,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"),
 };
diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c
index 316adb6..7e93a27 100644
--- a/libavcodec/bethsoftvideo.c
+++ b/libavcodec/bethsoftvideo.c
@@ -28,28 +28,31 @@
  */
 
 #include "libavutil/common.h"
-#include "dsputil.h"
+#include "avcodec.h"
 #include "bethsoftvideo.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct BethsoftvidContext {
-    AVFrame frame;
+    AVFrame *frame;
     GetByteContext g;
 } BethsoftvidContext;
 
 static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx)
 {
     BethsoftvidContext *vid = avctx->priv_data;
-    vid->frame.reference = 1;
-    vid->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
-        FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+    vid->frame = av_frame_alloc();
+    if (!vid->frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
 static int set_palette(BethsoftvidContext *ctx)
 {
-    uint32_t *palette = (uint32_t *)ctx->frame.data[1];
+    uint32_t *palette = (uint32_t *)ctx->frame->data[1];
     int a;
 
     if (bytestream2_get_bytes_left(&ctx->g) < 256*3)
@@ -58,7 +61,7 @@ static int set_palette(BethsoftvidContext *ctx)
     for(a = 0; a < 256; a++){
         palette[a] = bytestream2_get_be24u(&ctx->g) * 4;
     }
-    ctx->frame.palette_has_changed = 1;
+    ctx->frame->palette_has_changed = 1;
     return 0;
 }
 
@@ -75,11 +78,11 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
     int code, ret;
     int yoffset;
 
-    if (avctx->reget_buffer(avctx, &vid->frame)) {
+    if ((ret = ff_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;
+    wrap_to_next_line = vid->frame->linesize[0] - avctx->width;
 
     if (avpkt->side_data_elems > 0 &&
         avpkt->side_data[0].type == AV_PKT_DATA_PALETTE) {
@@ -90,8 +93,8 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
     }
 
     bytestream2_init(&vid->g, avpkt->data, avpkt->size);
-    dst = vid->frame.data[0];
-    frame_end = vid->frame.data[0] + vid->frame.linesize[0] * avctx->height;
+    dst = vid->frame->data[0];
+    frame_end = vid->frame->data[0] + vid->frame->linesize[0] * avctx->height;
 
     switch(block_type = bytestream2_get_byte(&vid->g)){
         case PALETTE_BLOCK: {
@@ -105,8 +108,8 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
         case VIDEO_YOFF_P_FRAME:
             yoffset = bytestream2_get_le16(&vid->g);
             if(yoffset >= avctx->height)
-                return -1;
-            dst += vid->frame.linesize[0] * yoffset;
+                return AVERROR_INVALIDDATA;
+            dst += vid->frame->linesize[0] * yoffset;
     }
 
     // main code
@@ -136,8 +139,10 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
     }
     end:
 
+    if ((ret = av_frame_ref(data, vid->frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = vid->frame;
 
     return avpkt->size;
 }
@@ -145,13 +150,13 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
 static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx)
 {
     BethsoftvidContext * vid = avctx->priv_data;
-    if(vid->frame.data[0])
-        avctx->release_buffer(avctx, &vid->frame);
+    av_frame_free(&vid->frame);
     return 0;
 }
 
 AVCodec ff_bethsoftvid_decoder = {
     .name           = "bethsoftvid",
+    .long_name      = NULL_IF_CONFIG_SMALL("Bethesda VID video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_BETHSOFTVID,
     .priv_data_size = sizeof(BethsoftvidContext),
@@ -159,5 +164,4 @@ AVCodec ff_bethsoftvid_decoder = {
     .close          = bethsoftvid_decode_end,
     .decode         = bethsoftvid_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Bethesda VID video"),
 };
diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c
index 50b20ba..75b6710 100644
--- a/libavcodec/bfi.c
+++ b/libavcodec/bfi.c
@@ -33,7 +33,6 @@
 
 typedef struct BFIContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     uint8_t *dst;
 } BFIContext;
 
@@ -48,6 +47,7 @@ static av_cold int bfi_decode_init(AVCodecContext *avctx)
 static int bfi_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     GetByteContext g;
     int buf_size    = avpkt->size;
     BFIContext *bfi = avctx->priv_data;
@@ -55,30 +55,25 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
     uint8_t *src, *dst_offset, colour1, colour2;
     uint8_t *frame_end = bfi->dst + avctx->width * avctx->height;
     uint32_t *pal;
-    int i, j, height = avctx->height;
+    int i, j, ret, height = avctx->height;
 
-    if (bfi->frame.data[0])
-        avctx->release_buffer(avctx, &bfi->frame);
-
-    bfi->frame.reference = 1;
-
-    if (ff_get_buffer(avctx, &bfi->frame) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     bytestream2_init(&g, avpkt->data, buf_size);
 
     /* Set frame parameters and palette, if necessary */
     if (!avctx->frame_number) {
-        bfi->frame.pict_type = AV_PICTURE_TYPE_I;
-        bfi->frame.key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        frame->key_frame = 1;
         /* Setting the palette */
         if (avctx->extradata_size > 768) {
             av_log(NULL, AV_LOG_ERROR, "Palette is too large.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
-        pal = (uint32_t *)bfi->frame.data[1];
+        pal = (uint32_t *)frame->data[1];
         for (i = 0; i < avctx->extradata_size / 3; i++) {
             int shift = 16;
             *pal = 0;
@@ -87,10 +82,10 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
                          (avctx->extradata[i * 3 + j] >> 4)) << shift;
             pal++;
         }
-        bfi->frame.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
     } else {
-        bfi->frame.pict_type = AV_PICTURE_TYPE_P;
-        bfi->frame.key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
     }
 
     bytestream2_skip(&g, 4); // Unpacked size, not required.
@@ -104,7 +99,7 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
         if (!bytestream2_get_bytes_left(&g)) {
             av_log(avctx, AV_LOG_ERROR,
                    "Input resolution larger than actual frame.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         /* Get length and offset (if required) */
@@ -130,7 +125,7 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
         case 0:                // normal chain
             if (length >= bytestream2_get_bytes_left(&g)) {
                 av_log(avctx, AV_LOG_ERROR, "Frame larger than buffer.\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             bytestream2_get_buffer(&g, dst, length);
             dst += length;
@@ -158,28 +153,27 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     src = bfi->dst;
-    dst = bfi->frame.data[0];
+    dst = frame->data[0];
     while (height--) {
         memcpy(dst, src, avctx->width);
         src += avctx->width;
-        dst += bfi->frame.linesize[0];
+        dst += frame->linesize[0];
     }
     *got_frame = 1;
-    *(AVFrame *)data = bfi->frame;
+
     return buf_size;
 }
 
 static av_cold int bfi_decode_close(AVCodecContext *avctx)
 {
     BFIContext *bfi = avctx->priv_data;
-    if (bfi->frame.data[0])
-        avctx->release_buffer(avctx, &bfi->frame);
     av_free(bfi->dst);
     return 0;
 }
 
 AVCodec ff_bfi_decoder = {
     .name           = "bfi",
+    .long_name      = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_BFI,
     .priv_data_size = sizeof(BFIContext),
@@ -187,5 +181,4 @@ AVCodec ff_bfi_decoder = {
     .close          = bfi_decode_close,
     .decode         = bfi_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
 };
diff --git a/libavcodec/bfin/Makefile b/libavcodec/bfin/Makefile
index be81e6c..c293360 100644
--- a/libavcodec/bfin/Makefile
+++ b/libavcodec/bfin/Makefile
@@ -2,7 +2,9 @@ OBJS += bfin/dsputil_bfin.o                                             \
         bfin/fdct_bfin.o                                                \
         bfin/idct_bfin.o                                                \
         bfin/pixels_bfin.o                                              \
-        bfin/vp3_bfin.o                                                 \
-        bfin/vp3_idct_bfin.o                                            \
 
+OBJS-$(CONFIG_HPELDSP)                  += bfin/hpeldsp_bfin.o          \
+                                           bfin/hpel_pixels_bfin.o
 OBJS-$(CONFIG_MPEGVIDEOENC)             += bfin/mpegvideo_bfin.o
+OBJS-$(CONFIG_VP3DSP)                   += bfin/vp3_bfin.o              \
+                                           bfin/vp3_idct_bfin.o
diff --git a/libavcodec/bfin/config_bfin.h b/libavcodec/bfin/config_bfin.h
index 0fee494..e714070 100644
--- a/libavcodec/bfin/config_bfin.h
+++ b/libavcodec/bfin/config_bfin.h
@@ -21,7 +21,7 @@
    low level assembler interface wrapper
 
 DEFUN(put_pixels_clamped,mL1,
-        (DCTELEM *block, uint8_t *dest, int line_size)):
+        (int16_t *block, uint8_t *dest, int line_size)):
 
       body
 
diff --git a/libavcodec/bfin/dsputil_bfin.c b/libavcodec/bfin/dsputil_bfin.c
index 8597ec1..3ce2941 100644
--- a/libavcodec/bfin/dsputil_bfin.c
+++ b/libavcodec/bfin/dsputil_bfin.c
@@ -21,26 +21,27 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
 #include "dsputil_bfin.h"
 
 int off;
 
-static void bfin_idct_add (uint8_t *dest, int line_size, DCTELEM *block)
+static void bfin_idct_add (uint8_t *dest, int line_size, int16_t *block)
 {
     ff_bfin_idct (block);
     ff_bfin_add_pixels_clamped (block, dest, line_size);
 }
 
-static void bfin_idct_put (uint8_t *dest, int line_size, DCTELEM *block)
+static void bfin_idct_put (uint8_t *dest, int line_size, int16_t *block)
 {
     ff_bfin_idct (block);
     ff_bfin_put_pixels_clamped (block, dest, line_size);
 }
 
 
-static void bfin_clear_blocks (DCTELEM *blocks)
+static void bfin_clear_blocks (int16_t *blocks)
 {
     // This is just a simple memset.
     //
@@ -53,79 +54,6 @@ static void bfin_clear_blocks (DCTELEM *blocks)
         ::"a" (blocks):"P0","I0","R0");
 }
 
-
-
-static void bfin_put_pixels8 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels8uc (block, pixels, pixels, line_size, line_size, h);
-}
-
-static void bfin_put_pixels8_x2(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels8uc (block, pixels, pixels+1, line_size, line_size, h);
-}
-
-static void bfin_put_pixels8_y2 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels8uc (block, pixels, pixels+line_size, line_size, line_size, h);
-}
-
-static void bfin_put_pixels8_xy2 (uint8_t *block, const uint8_t *s0, int line_size, int h)
-{
-    ff_bfin_z_put_pixels8_xy2 (block,s0,line_size, line_size, h);
-}
-
-static void bfin_put_pixels16 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels16uc (block, pixels, pixels, line_size, line_size, h);
-}
-
-static void bfin_put_pixels16_x2 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels16uc (block, pixels, pixels+1, line_size, line_size, h);
-}
-
-static void bfin_put_pixels16_y2 (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels16uc (block, pixels, pixels+line_size, line_size, line_size, h);
-}
-
-static void bfin_put_pixels16_xy2 (uint8_t *block, const uint8_t *s0, int line_size, int h)
-{
-    ff_bfin_z_put_pixels16_xy2 (block,s0,line_size, line_size, h);
-}
-
-static void bfin_put_pixels8_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels8uc_nornd (block, pixels, pixels, line_size, h);
-}
-
-static void bfin_put_pixels8_x2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels8uc_nornd (block, pixels, pixels+1, line_size, h);
-}
-
-static void bfin_put_pixels8_y2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels8uc_nornd (block, pixels, pixels+line_size, line_size, h);
-}
-
-
-static void bfin_put_pixels16_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels16uc_nornd (block, pixels, pixels, line_size, h);
-}
-
-static void bfin_put_pixels16_x2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+1, line_size, h);
-}
-
-static void bfin_put_pixels16_y2_nornd (uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+line_size, line_size, h);
-}
-
 static int bfin_pix_abs16 (void *c, uint8_t *blk1, uint8_t *blk2, int line_size, int h)
 {
     return ff_bfin_z_sad16x16 (blk1,blk2,line_size,line_size,h);
@@ -195,7 +123,7 @@ static int bfin_pix_abs8_xy2 (void *c, uint8_t *blk1, uint8_t *blk2, int line_si
 
 */
 
-void ff_dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx )
+av_cold void ff_dsputil_init_bfin(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -204,7 +132,7 @@ void ff_dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx )
     c->add_pixels_clamped = ff_bfin_add_pixels_clamped;
 
     if (!high_bit_depth)
-    c->get_pixels         = ff_bfin_get_pixels;
+        c->get_pixels     = ff_bfin_get_pixels;
     c->clear_blocks       = bfin_clear_blocks;
     c->pix_sum            = ff_bfin_pix_sum;
     c->pix_norm1          = ff_bfin_pix_norm1;
@@ -231,38 +159,11 @@ void ff_dsputil_init_bfin( DSPContext* c, AVCodecContext *avctx )
     c->sse[1] = ff_bfin_sse8;
     c->sse[2] = ff_bfin_sse4;
 
-    if (!high_bit_depth) {
-    c->put_pixels_tab[0][0] = bfin_put_pixels16;
-    c->put_pixels_tab[0][1] = bfin_put_pixels16_x2;
-    c->put_pixels_tab[0][2] = bfin_put_pixels16_y2;
-    c->put_pixels_tab[0][3] = bfin_put_pixels16_xy2;
-
-    c->put_pixels_tab[1][0] = bfin_put_pixels8;
-    c->put_pixels_tab[1][1] = bfin_put_pixels8_x2;
-    c->put_pixels_tab[1][2] = bfin_put_pixels8_y2;
-    c->put_pixels_tab[1][3] = bfin_put_pixels8_xy2;
-
-    c->put_no_rnd_pixels_tab[1][0] = bfin_put_pixels8_nornd;
-    c->put_no_rnd_pixels_tab[1][1] = bfin_put_pixels8_x2_nornd;
-    c->put_no_rnd_pixels_tab[1][2] = bfin_put_pixels8_y2_nornd;
-/*     c->put_no_rnd_pixels_tab[1][3] = ff_bfin_put_pixels8_xy2_nornd; */
-
-    c->put_no_rnd_pixels_tab[0][0] = bfin_put_pixels16_nornd;
-    c->put_no_rnd_pixels_tab[0][1] = bfin_put_pixels16_x2_nornd;
-    c->put_no_rnd_pixels_tab[0][2] = bfin_put_pixels16_y2_nornd;
-/*     c->put_no_rnd_pixels_tab[0][3] = ff_bfin_put_pixels16_xy2_nornd; */
-    }
-
     if (avctx->bits_per_raw_sample <= 8) {
         if (avctx->dct_algo == FF_DCT_AUTO)
             c->fdct                  = ff_bfin_fdct;
 
-        if (avctx->idct_algo == FF_IDCT_VP3) {
-            c->idct_permutation_type = FF_NO_IDCT_PERM;
-            c->idct                  = ff_bfin_vp3_idct;
-            c->idct_add              = ff_bfin_vp3_idct_add;
-            c->idct_put              = ff_bfin_vp3_idct_put;
-        } else if (avctx->idct_algo == FF_IDCT_AUTO) {
+        if (avctx->idct_algo == FF_IDCT_AUTO) {
             c->idct_permutation_type = FF_NO_IDCT_PERM;
             c->idct                  = ff_bfin_idct;
             c->idct_add              = bfin_idct_add;
diff --git a/libavcodec/bfin/dsputil_bfin.h b/libavcodec/bfin/dsputil_bfin.h
index f1a9b32..a082cd7 100644
--- a/libavcodec/bfin/dsputil_bfin.h
+++ b/libavcodec/bfin/dsputil_bfin.h
@@ -24,8 +24,9 @@
 #ifndef AVCODEC_BFIN_DSPUTIL_BFIN_H
 #define AVCODEC_BFIN_DSPUTIL_BFIN_H
 
+#include <stdint.h>
+
 #include "config.h"
-#include "libavcodec/dsputil.h"
 
 #if defined(__FDPIC__) && CONFIG_SRAM
 #define attribute_l1_text  __attribute__ ((l1_text))
@@ -35,32 +36,18 @@
 #define attribute_l1_data_b
 #endif
 
-void ff_bfin_idct (DCTELEM *block) attribute_l1_text;
-void ff_bfin_fdct (DCTELEM *block) attribute_l1_text;
-void ff_bfin_vp3_idct (DCTELEM *block);
-void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, DCTELEM *block);
-void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, DCTELEM *block);
-void ff_bfin_add_pixels_clamped (const DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text;
-void ff_bfin_put_pixels_clamped (const DCTELEM *block, uint8_t *dest, int line_size) attribute_l1_text;
-void ff_bfin_diff_pixels (DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride)  attribute_l1_text;
-void ff_bfin_get_pixels  (DCTELEM *restrict block, const uint8_t *pixels, int line_size) attribute_l1_text;
+void ff_bfin_idct (int16_t *block) attribute_l1_text;
+void ff_bfin_fdct (int16_t *block) attribute_l1_text;
+void ff_bfin_add_pixels_clamped (const int16_t *block, uint8_t *dest, int line_size) attribute_l1_text;
+void ff_bfin_put_pixels_clamped (const int16_t *block, uint8_t *dest, int line_size) attribute_l1_text;
+void ff_bfin_diff_pixels (int16_t *block, const uint8_t *s1, const uint8_t *s2, int stride)  attribute_l1_text;
+void ff_bfin_get_pixels  (int16_t *restrict block, const uint8_t *pixels, int line_size) attribute_l1_text;
 int  ff_bfin_pix_norm1  (uint8_t * pix, int line_size) attribute_l1_text;
 int  ff_bfin_z_sad8x8   (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) attribute_l1_text;
 int  ff_bfin_z_sad16x16 (uint8_t *blk1, uint8_t *blk2, int dsz, int line_size, int h) attribute_l1_text;
 
-void ff_bfin_z_put_pixels16_xy2     (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) attribute_l1_text;
-void ff_bfin_z_put_pixels8_xy2      (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) attribute_l1_text;
-void ff_bfin_put_pixels16_xy2_nornd (uint8_t *block, const uint8_t *s0, int line_size, int h) attribute_l1_text;
-void ff_bfin_put_pixels8_xy2_nornd  (uint8_t *block, const uint8_t *s0, int line_size, int h) attribute_l1_text;
-
-
 int  ff_bfin_pix_sum (uint8_t *p, int stride) attribute_l1_text;
 
-void ff_bfin_put_pixels8uc        (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) attribute_l1_text;
-void ff_bfin_put_pixels16uc       (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) attribute_l1_text;
-void ff_bfin_put_pixels8uc_nornd  (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) attribute_l1_text;
-void ff_bfin_put_pixels16uc_nornd (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) attribute_l1_text;
-
 int ff_bfin_sse4  (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text;
 int ff_bfin_sse8  (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text;
 int ff_bfin_sse16 (void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) attribute_l1_text;
diff --git a/libavcodec/bfin/fdct_bfin.S b/libavcodec/bfin/fdct_bfin.S
index 8ca490d..c923d76 100644
--- a/libavcodec/bfin/fdct_bfin.S
+++ b/libavcodec/bfin/fdct_bfin.S
@@ -20,7 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 /*
-  void ff_bfin_fdct (DCTELEM *buf);
+  void ff_bfin_fdct (int16_t *buf);
 
   This implementation works only for 8x8 input. The range of input
   must be -256 to 255 i.e. 8bit input represented in a 16bit data
@@ -61,9 +61,9 @@ Notation
   Other registers used:
         I0, I1, I2, I3, B0, B2, B3, M0, M1, L3 registers and LC0.
 
-  Input - r0 - pointer to start of DCTELEM *block
+  Input - r0 - pointer to start of int16_t *block
 
-  Output - The DCT output coefficients in the DCTELEM *block
+  Output - The DCT output coefficients in the int16_t *block
 
   Register constraint:
                This code is called from jpeg_encode.
@@ -145,7 +145,7 @@ vtmp:   .space 128
 
 .text
 DEFUN(fdct,mL1,
-        (DCTELEM *block)):
+        (int16_t *block)):
     [--SP] = (R7:4, P5:3);          // Push the registers onto the stack.
 
     b0 = r0;
diff --git a/libavcodec/bfin/hpel_pixels_bfin.S b/libavcodec/bfin/hpel_pixels_bfin.S
new file mode 100644
index 0000000..9b927b0
--- /dev/null
+++ b/libavcodec/bfin/hpel_pixels_bfin.S
@@ -0,0 +1,380 @@
+/*
+ * Blackfin Pixel Operations
+ * Copyright (C) 2007 Marc Hoffman <marc.hoffman at analog.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 "config_bfin.h"
+
+/*
+  motion compensation
+  primitives
+
+     * Halfpel motion compensation with rounding (a+b+1)>>1.
+     * This is an array[4][4] of motion compensation funcions for 4
+     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
+     * @param block destination where the result is stored
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+
+*/
+
+DEFUN(put_pixels8uc,mL1,
+        (uint8_t *block, const uint8_t *s0, const uint8_t *s1,
+                 int dest_size, int line_size, int h)):
+        i3=r0;        // dest
+        i0=r1;        // src0
+        i1=r2;        // src1
+        r0=[sp+12];   // dest_size
+        r2=[sp+16];   // line_size
+        p0=[sp+20];   // h
+        [--sp] = (r7:6);
+        r0+=-4;
+        m3=r0;
+        r2+=-8;
+        m0=r2;
+        LSETUP(pp8$0,pp8$1) LC0=P0;
+        DISALGNEXCPT                || R0 = [I0++]  || R2  =[I1++];
+
+pp8$0:  DISALGNEXCPT                || R1 = [I0++]  || R3  =[I1++];
+        R6 = BYTEOP1P(R1:0,R3:2)    || R0 = [I0++M0]|| R2  =[I1++M0];
+        R7 = BYTEOP1P(R1:0,R3:2)(R) || R0 = [I0++]  || [I3++] = R6 ;
+pp8$1:  DISALGNEXCPT                || R2 = [I1++]  || [I3++M3] = R7;
+
+        (r7:6) = [sp++];
+        RTS;
+DEFUN_END(put_pixels8uc)
+
+DEFUN(put_pixels16uc,mL1,
+        (uint8_t *block, const uint8_t *s0, const uint8_t *s1,
+                 int dest_size, int line_size, int h)):
+        link 0;
+        [--sp] = (r7:6);
+        i3=r0;        // dest
+        i0=r1;        // src0
+        i1=r2;        // src1
+        r0=[fp+20];   // dest_size
+        r2=[fp+24];   // line_size
+        p0=[fp+28];   // h
+
+
+        r0+=-12;
+        m3=r0;        // line_size
+        r2+=-16;
+        m0=r2;
+
+        LSETUP(pp16$0,pp16$1) LC0=P0;
+         DISALGNEXCPT                || R0 = [I0++]   || R2  =[I1++];
+
+pp16$0:  DISALGNEXCPT                || R1 = [I0++]   || R3  =[I1++];
+         R6 = BYTEOP1P(R1:0,R3:2)    || R0 = [I0++]   || R2  =[I1++];
+         R7 = BYTEOP1P(R1:0,R3:2)(R) || R1 = [I0++]   || R3  =[I1++];
+         [I3++] = R6;
+         R6 = BYTEOP1P(R1:0,R3:2)    || R0 = [I0++M0] || R2  =[I1++M0];
+         R7 = BYTEOP1P(R1:0,R3:2)(R) || R0 = [I0++]   || [I3++] = R7 ;
+         [I3++] = R6;
+pp16$1:  DISALGNEXCPT                || R2 = [I1++]   || [I3++M3] = R7;
+
+        (r7:6) = [sp++];
+        unlink;
+        RTS;
+DEFUN_END(put_pixels16uc)
+
+
+
+
+
+
+DEFUN(put_pixels8uc_nornd,mL1,
+        (uint8_t *block, const uint8_t *s0, const uint8_t *s1,
+                 int line_size, int h)):
+        i3=r0;        // dest
+        i0=r1;        // src0
+        i1=r2;        // src1
+        r2=[sp+12];   // line_size
+        p0=[sp+16];   // h
+        [--sp] = (r7:6);
+        r2+=-4;
+        m3=r2;
+        r2+=-4;
+        m0=r2;
+        LSETUP(pp8$2,pp8$3) LC0=P0;
+        DISALGNEXCPT                || R0 = [I0++]  || R2  =[I1++];
+
+pp8$2:  DISALGNEXCPT                || R1 = [I0++]  || R3  =[I1++];
+        R6 = BYTEOP1P(R1:0,R3:2)(T)  || R0 = [I0++M0]|| R2  =[I1++M0];
+        R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R0 = [I0++]  || [I3++] = R6 ;
+pp8$3:  DISALGNEXCPT                || R2 = [I1++]  || [I3++M3] = R7;
+
+        (r7:6) = [sp++];
+        RTS;
+DEFUN_END(put_pixels8uc_nornd)
+
+DEFUN(put_pixels16uc_nornd,mL1,
+        (uint8_t *block, const uint8_t *s0, const uint8_t *s1,
+                 int line_size, int h)):
+        i3=r0;        // dest
+        i0=r1;        // src0
+        i1=r2;        // src1
+        r2=[sp+12];   // line_size
+        p0=[sp+16];   // h
+
+        [--sp] = (r7:6);
+        r2+=-12;
+        m3=r2;        // line_size
+        r2+=-4;
+        m0=r2;
+
+        LSETUP(pp16$2,pp16$3) LC0=P0;
+        DISALGNEXCPT                || R0 = [I0++]   || R2  =[I1++];
+
+pp16$2:
+        DISALGNEXCPT                || R1 = [I0++]   || R3  =[I1++];
+        R6 = BYTEOP1P(R1:0,R3:2)(T)    || R0 = [I0++]   || R2  =[I1++];
+        R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R1 = [I0++]   || R3  =[I1++];
+        [I3++] = R6;
+
+        R6 = BYTEOP1P(R1:0,R3:2)(T)    || R0 = [I0++M0] || R2  =[I1++M0];
+        R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R0 = [I0++]   || [I3++] = R7 ;
+        [I3++] = R6;
+pp16$3: DISALGNEXCPT                || R2 = [I1++]   || [I3++M3] = R7;
+
+        (r7:6) = [sp++];
+
+        RTS;
+DEFUN_END(put_pixels16uc_nornd)
+
+DEFUN(z_put_pixels16_xy2,mL1,
+        (uint8_t *block, const uint8_t *s0,
+                 int dest_size, int line_size, int h)):
+        link 0;
+        [--sp] = (r7:4);
+        i3=r0;        // dest
+        i0=r1;        // src0--> pixels
+        i1=r1;        // src1--> pixels + line_size
+        r2+=-12;
+        m2=r2;        // m2=dest_width-4
+        r2=[fp+20];
+        m3=r2;        // line_size
+        p0=[fp+24];   // h
+        r2+=-16;
+        i1+=m3;       /* src1 + line_size */
+        m0=r2;        /* line-size - 20 */
+
+        B0 = I0;
+        B1 = I1;
+        B3 = I3;
+
+        DISALGNEXCPT                       || R0 = [I0++] || R2  =[I1++];
+
+        LSETUP(LS$16E,LE$16E) LC0=P0;
+LS$16E: DISALGNEXCPT                       || R1 = [I0++] || R3  =[I1++];
+        R4 = BYTEOP2P (R3:2,R1:0) (RNDL)   || R0 = [I0++] || R2  =[I1++];
+        R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R1 = [I0++] || [I3++] = R4 ;
+        DISALGNEXCPT                       || R3 = [I1++] || [I3++] = R5;
+        R4 = BYTEOP2P (R3:2,R1:0) (RNDL)   || R0 = [I0++M0]|| R2  = [I1++M0];
+        R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R0 = [I0++] || [I3++] = R4 ;
+LE$16E: DISALGNEXCPT                       || R2 = [I1++] || [I3++M2] = R5;
+
+        M1 = 1;
+        I3 = B3;
+        I1 = B1;
+        I0 = B0;
+
+        I0 += M1;
+        I1 += M1;
+
+        DISALGNEXCPT                       || R0 = [I0++] || R2  =[I1++];
+        LSETUP(LS$16O,LE$16O) LC0=P0;
+LS$16O: DISALGNEXCPT                       || R1 = [I0++] || R3  =[I1++];
+        R4 = BYTEOP2P (R3:2,R1:0) (RNDH)   || R0 = [I0++] || R2  =[I1++];
+        R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R1 = [I0++] || R6  =[I3++];
+        R4 = R4 +|+ R6                       || R7 = [I3--];
+        R5 = R5 +|+ R7                       || [I3++] = R4;
+        DISALGNEXCPT                       || R3  =[I1++] || [I3++] = R5;
+        R4 = BYTEOP2P (R3:2,R1:0) (RNDH)   || R0 = [I0++M0]|| R2  = [I1++M0];
+        R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R0 = [I0++] || R6 = [I3++];
+        R4 = R4 +|+ R6                       || R7 = [I3--];
+        R5 = R5 +|+ R7                       || [I3++] = R4;
+LE$16O: DISALGNEXCPT                       || R2 = [I1++] || [I3++M2] = R5;
+
+        (r7:4) = [sp++];
+        unlink;
+        rts;
+DEFUN_END(z_put_pixels16_xy2)
+
+DEFUN(put_pixels16_xy2_nornd,mL1,
+        (uint8_t *block, const uint8_t *s0,
+                 int line_size, int h)):
+        link 0;
+        [--sp] = (r7:4);
+        i3=r0;        // dest
+        i0=r1;        // src0--> pixels
+        i1=r1;        // src1--> pixels + line_size
+        m3=r2;
+        r2+=-12;
+        m2=r2;
+        r2+=-4;
+        i1+=m3;       /* src1 + line_size */
+        m0=r2;        /* line-size - 20 */
+        p0=[fp+20];   // h
+
+        B0=I0;
+        B1=I1;
+        B3=I3;
+
+        DISALGNEXCPT                       || R0 = [I0++] || R2  =[I1++];
+
+        LSETUP(LS$16ET,LE$16ET) LC0=P0;
+LS$16ET:DISALGNEXCPT                       || R1 = [I0++] || R3  =[I1++];
+        R4 = BYTEOP2P (R3:2,R1:0) (TL)     || R0 = [I0++] || R2  =[I1++];
+        R5 = BYTEOP2P (R3:2,R1:0) (TL,R)   || R1 = [I0++] || [I3++] = R4 ;
+        DISALGNEXCPT                       || R3 = [I1++] || [I3++] = R5;
+        R4 = BYTEOP2P (R3:2,R1:0) (TL)     || R0 = [I0++M0]|| R2  = [I1++M0];
+        R5 = BYTEOP2P (R3:2,R1:0) (TL,R)   || R0 = [I0++] || [I3++] = R4 ;
+LE$16ET:DISALGNEXCPT                       || R2 = [I1++] || [I3++M2] = R5;
+
+        M1 = 1;
+        I3=B3;
+        I1=B1;
+        I0=B0;
+
+        I0 += M1;
+        I1 += M1;
+
+        DISALGNEXCPT                       || R0 = [I0++] || R2  =[I1++];
+        LSETUP(LS$16OT,LE$16OT) LC0=P0;
+LS$16OT:DISALGNEXCPT                       || R1 = [I0++] || R3  =[I1++];
+        R4 = BYTEOP2P (R3:2,R1:0) (TH)     || R0 = [I0++] || R2  =[I1++];
+        R5 = BYTEOP2P (R3:2,R1:0) (TH,R)   || R1 = [I0++] || R6  =[I3++];
+        R4 = R4 +|+ R6                                    || R7 = [I3--];
+        R5 = R5 +|+ R7                                    || [I3++] = R4;
+        DISALGNEXCPT                       || R3  =[I1++] || [I3++] = R5;
+        R4 = BYTEOP2P (R3:2,R1:0) (TH)     || R0 = [I0++M0]|| R2  = [I1++M0];
+        R5 = BYTEOP2P (R3:2,R1:0) (TH,R)   || R0 = [I0++] || R6 = [I3++];
+        R4 = R4 +|+ R6                                    || R7 = [I3--];
+        R5 = R5 +|+ R7                                    || [I3++] = R4;
+LE$16OT:DISALGNEXCPT                       || R2 = [I1++] || [I3++M2] = R5;
+
+        (r7:4) = [sp++];
+        unlink;
+        rts;
+DEFUN_END(put_pixels16_xy2_nornd)
+
+DEFUN(z_put_pixels8_xy2,mL1,
+        (uint8_t *block, const uint8_t *s0,
+                 int dest_size, int line_size, int h)):
+        link 0;
+        [--sp] = (r7:4);
+        i3=r0;        // dest
+        i0=r1;        // src0--> pixels
+        i1=r1;        // src1--> pixels + line_size
+        r2+=-4;
+        m2=r2;        // m2=dest_width-4
+        r2=[fp+20];
+        m3=r2;        // line_size
+        p0=[fp+24];   // h
+        r2+=-8;
+        i1+=m3;       /* src1 + line_size */
+        m0=r2;        /* line-size - 20 */
+
+        b0 = I0;
+        b1 = I1;
+        b3 = I3;
+
+        LSETUP(LS$8E,LE$8E) LC0=P0;
+        DISALGNEXCPT                       || R0 = [I0++]   || R2  =[I1++];
+LS$8E:  DISALGNEXCPT                       || R1 = [I0++]   || R3  =[I1++];
+        R4 = BYTEOP2P (R3:2,R1:0) (RNDL)   || R0 = [I0++M0] || R2  =[I1++M0];
+        R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R0 = [I0++]   || [I3++] = R4 ;
+LE$8E:  DISALGNEXCPT                       || R2 = [I1++]   || [I3++M2] = R5;
+
+        M1 = 1;
+        I3 = b3;
+        I1 = b1;
+        I0 = b0;
+
+        I0 += M1;
+        I1 += M1;
+
+        LSETUP(LS$8O,LE$8O) LC0=P0;
+        DISALGNEXCPT                       || R0 = [I0++]   || R2  =[I1++];
+LS$8O:  DISALGNEXCPT                       || R1 = [I0++]   || R3  =[I1++];
+        R4 = BYTEOP2P (R3:2,R1:0) (RNDH)   || R0 = [I0++M0] || R2  =[I1++M0];
+        R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R0 = [I0++]   || R6  =[I3++];
+        R4 = R4 +|+ R6                                      || R7 = [I3--];
+        R5 = R5 +|+ R7                                      || [I3++] = R4;
+LE$8O:  DISALGNEXCPT                       || R2  =[I1++]   || [I3++M2] = R5;
+
+        (r7:4) = [sp++];
+        unlink;
+        rts;
+DEFUN_END(z_put_pixels8_xy2)
+
+DEFUN(put_pixels8_xy2_nornd,mL1,
+        (uint8_t *block, const uint8_t *s0, int line_size, int h)):
+        link 0;
+        [--sp] = (r7:4);
+        i3=r0;        // dest
+        i0=r1;        // src0--> pixels
+        i1=r1;        // src1--> pixels + line_size
+        m3=r2;
+        r2+=-4;
+        m2=r2;
+        r2+=-4;
+        i1+=m3;       /* src1 + line_size */
+        m0=r2;        /* line-size - 20 */
+        p0=[fp+20];   // h
+
+
+        b0 = I0;
+        b1 = I1;
+        b3 = I3;
+
+        LSETUP(LS$8ET,LE$8ET) LC0=P0;
+        DISALGNEXCPT                       || R0 = [I0++]   || R2  =[I1++];
+
+LS$8ET: DISALGNEXCPT                       || R1 = [I0++]   || R3 = [I1++];
+        R4 = BYTEOP2P (R3:2,R1:0) (TL)     || R0 = [I0++M0] || R2 = [I1++M0];
+        R5 = BYTEOP2P (R3:2,R1:0) (TL,R)   || R0 = [I0++]   || [I3++] = R4 ;
+LE$8ET: DISALGNEXCPT                       || R2 = [I1++]   || [I3++M2] = R5;
+
+        M1 = 1;
+        I3 = b3;
+        I1 = b1;
+        I0 = b0;
+
+        I0 += M1;
+        I1 += M1;
+
+        LSETUP(LS$8OT,LE$8OT) LC0=P0;
+        DISALGNEXCPT                       || R0 = [I0++]   || R2 = [I1++];
+
+LS$8OT: DISALGNEXCPT                       || R1 = [I0++]   || R3 = [I1++];
+        R4 = BYTEOP2P (R3:2,R1:0) (TH)     || R0 = [I0++M0] || R2 = [I1++M0];
+        R5 = BYTEOP2P (R3:2,R1:0) (TH,R)   || R0 = [I0++]   || R6 = [I3++];
+        R4 = R4 +|+ R6                                      || R7 = [I3--];
+        R5 = R5 +|+ R7                                      || [I3++] = R4;
+LE$8OT: DISALGNEXCPT                       || R2  =[I1++]   || [I3++M2] = R5;
+
+        (r7:4) = [sp++];
+        unlink;
+        rts;
+DEFUN_END(put_pixels8_xy2_nornd)
diff --git a/libavcodec/bfin/hpeldsp_bfin.c b/libavcodec/bfin/hpeldsp_bfin.c
new file mode 100644
index 0000000..cecb1db
--- /dev/null
+++ b/libavcodec/bfin/hpeldsp_bfin.c
@@ -0,0 +1,123 @@
+/*
+ * BlackFin DSPUTILS
+ *
+ * Copyright (C) 2007 Marc Hoffman <marc.hoffman at analog.com>
+ * Copyright (c) 2006 Michael Benjamin <michael.benjamin at analog.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 <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavcodec/hpeldsp.h"
+#include "hpeldsp_bfin.h"
+
+static void bfin_put_pixels8 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels8uc (block, pixels, pixels, line_size, line_size, h);
+}
+
+static void bfin_put_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels8uc (block, pixels, pixels+1, line_size, line_size, h);
+}
+
+static void bfin_put_pixels8_y2 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels8uc (block, pixels, pixels+line_size, line_size, line_size, h);
+}
+
+static void bfin_put_pixels8_xy2 (uint8_t *block, const uint8_t *s0, ptrdiff_t line_size, int h)
+{
+    ff_bfin_z_put_pixels8_xy2 (block,s0,line_size, line_size, h);
+}
+
+static void bfin_put_pixels16 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels16uc (block, pixels, pixels, line_size, line_size, h);
+}
+
+static void bfin_put_pixels16_x2 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels16uc (block, pixels, pixels+1, line_size, line_size, h);
+}
+
+static void bfin_put_pixels16_y2 (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels16uc (block, pixels, pixels+line_size, line_size, line_size, h);
+}
+
+static void bfin_put_pixels16_xy2 (uint8_t *block, const uint8_t *s0, ptrdiff_t line_size, int h)
+{
+    ff_bfin_z_put_pixels16_xy2 (block,s0,line_size, line_size, h);
+}
+
+static void bfin_put_pixels8_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels8uc_nornd (block, pixels, pixels, line_size, h);
+}
+
+static void bfin_put_pixels8_x2_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels8uc_nornd (block, pixels, pixels+1, line_size, h);
+}
+
+static void bfin_put_pixels8_y2_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels8uc_nornd (block, pixels, pixels+line_size, line_size, h);
+}
+
+
+static void bfin_put_pixels16_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels16uc_nornd (block, pixels, pixels, line_size, h);
+}
+
+static void bfin_put_pixels16_x2_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+1, line_size, h);
+}
+
+static void bfin_put_pixels16_y2_nornd (uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    ff_bfin_put_pixels16uc_nornd (block, pixels, pixels+line_size, line_size, h);
+}
+
+av_cold void ff_hpeldsp_init_bfin(HpelDSPContext *c, int flags)
+{
+    c->put_pixels_tab[0][0] = bfin_put_pixels16;
+    c->put_pixels_tab[0][1] = bfin_put_pixels16_x2;
+    c->put_pixels_tab[0][2] = bfin_put_pixels16_y2;
+    c->put_pixels_tab[0][3] = bfin_put_pixels16_xy2;
+
+    c->put_pixels_tab[1][0] = bfin_put_pixels8;
+    c->put_pixels_tab[1][1] = bfin_put_pixels8_x2;
+    c->put_pixels_tab[1][2] = bfin_put_pixels8_y2;
+    c->put_pixels_tab[1][3] = bfin_put_pixels8_xy2;
+
+    c->put_no_rnd_pixels_tab[1][0] = bfin_put_pixels8_nornd;
+    c->put_no_rnd_pixels_tab[1][1] = bfin_put_pixels8_x2_nornd;
+    c->put_no_rnd_pixels_tab[1][2] = bfin_put_pixels8_y2_nornd;
+/*     c->put_no_rnd_pixels_tab[1][3] = ff_bfin_put_pixels8_xy2_nornd; */
+
+    c->put_no_rnd_pixels_tab[0][0] = bfin_put_pixels16_nornd;
+    c->put_no_rnd_pixels_tab[0][1] = bfin_put_pixels16_x2_nornd;
+    c->put_no_rnd_pixels_tab[0][2] = bfin_put_pixels16_y2_nornd;
+/*     c->put_no_rnd_pixels_tab[0][3] = ff_bfin_put_pixels16_xy2_nornd; */
+}
diff --git a/libavcodec/bfin/hpeldsp_bfin.h b/libavcodec/bfin/hpeldsp_bfin.h
new file mode 100644
index 0000000..2de16f7
--- /dev/null
+++ b/libavcodec/bfin/hpeldsp_bfin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 Marc Hoffman <mmh at pleasantst.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_BFIN_HPELDSP_BFIN_H
+#define AVCODEC_BFIN_HPELDSP_BFIN_H
+
+#include <stdint.h>
+
+#include "config.h"
+
+#if defined(__FDPIC__) && CONFIG_SRAM
+#define attribute_l1_text  __attribute__ ((l1_text))
+#define attribute_l1_data_b __attribute__((l1_data_B))
+#else
+#define attribute_l1_text
+#define attribute_l1_data_b
+#endif
+
+void ff_bfin_z_put_pixels16_xy2     (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) attribute_l1_text;
+void ff_bfin_z_put_pixels8_xy2      (uint8_t *block, const uint8_t *s0, int dest_size, int line_size, int h) attribute_l1_text;
+void ff_bfin_put_pixels16_xy2_nornd (uint8_t *block, const uint8_t *s0, int line_size, int h) attribute_l1_text;
+void ff_bfin_put_pixels8_xy2_nornd  (uint8_t *block, const uint8_t *s0, int line_size, int h) attribute_l1_text;
+
+
+void ff_bfin_put_pixels8uc        (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) attribute_l1_text;
+void ff_bfin_put_pixels16uc       (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int dest_size, int line_size, int h) attribute_l1_text;
+void ff_bfin_put_pixels8uc_nornd  (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) attribute_l1_text;
+void ff_bfin_put_pixels16uc_nornd (uint8_t *block, const uint8_t *s0, const uint8_t *s1, int line_size, int h) attribute_l1_text;
+
+#endif /* AVCODEC_BFIN_HPELDSP_BFIN_H */
diff --git a/libavcodec/bfin/idct_bfin.S b/libavcodec/bfin/idct_bfin.S
index b384840..0eeffc2 100644
--- a/libavcodec/bfin/idct_bfin.S
+++ b/libavcodec/bfin/idct_bfin.S
@@ -22,7 +22,7 @@
 /*
    This blackfin DSP code implements an 8x8 inverse type II DCT.
 
-Prototype       : void ff_bfin_idct(DCTELEM *in)
+Prototype       : void ff_bfin_idct(int16_t *in)
 
 Registers Used  : A0, A1, R0-R7, I0-I3, B0, B2, B3, M0-M2, L0-L3, P0-P5, LC0.
 
@@ -90,7 +90,7 @@ vtmp: .space 256
 
 .text
 DEFUN(idct,mL1,
-        (DCTELEM *block)):
+        (int16_t *block)):
 
 /********************** Function Prologue *********************************/
     link 16;
diff --git a/libavcodec/bfin/mpegvideo_bfin.c b/libavcodec/bfin/mpegvideo_bfin.c
index 8e88d88..d03d3c0 100644
--- a/libavcodec/bfin/mpegvideo_bfin.c
+++ b/libavcodec/bfin/mpegvideo_bfin.c
@@ -20,13 +20,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "dsputil_bfin.h"
 
 static int dct_quantize_bfin (MpegEncContext *s,
-                              DCTELEM *block, int n,
+                              int16_t *block, int n,
                               int qscale, int *overflow)
 {
     int last_non_zero, q, start_i;
@@ -141,7 +141,7 @@ static int dct_quantize_bfin (MpegEncContext *s,
     return last_non_zero;
 }
 
-void ff_MPV_common_init_bfin (MpegEncContext *s)
+av_cold void ff_MPV_common_init_bfin (MpegEncContext *s)
 {
 /*     s->dct_quantize= dct_quantize_bfin; */
 }
diff --git a/libavcodec/bfin/pixels_bfin.S b/libavcodec/bfin/pixels_bfin.S
index 45a3ab6..70d9de5 100644
--- a/libavcodec/bfin/pixels_bfin.S
+++ b/libavcodec/bfin/pixels_bfin.S
@@ -21,7 +21,7 @@
 #include "config_bfin.h"
 
 DEFUN(put_pixels_clamped,mL1,
-        (DCTELEM *block, uint8_t *dest, int line_size)):
+        (int16_t *block, uint8_t *dest, int line_size)):
     [--SP] = (R7:4);
     R4 = 0;
     R5.l = 0x00ff;
@@ -51,7 +51,7 @@ ppc$1: R2 = Max(R0, R4) (V)      || [I1++M1] = R6;
 DEFUN_END(put_pixels_clamped)
 
 DEFUN(add_pixels_clamped,mL1,
-        (DCTELEM *block, uint8_t *dest, int line_size)):
+        (int16_t *block, uint8_t *dest, int line_size)):
     [-- SP] = (R7:4);
     R4 = 0;
     I0 = 0;
@@ -83,366 +83,8 @@ apc$3: R6 = BYTEOP3P(R1:0, R3:2) (LO)    || [I2++M0] = R6   || R2 = [I1];
     RTS;
 DEFUN_END(add_pixels_clamped)
 
-
-/*
-  motion compensation
-  primitives
-
-     * Halfpel motion compensation with rounding (a+b+1)>>1.
-     * This is an array[4][4] of motion compensation funcions for 4
-     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
-     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
-     * @param block destination where the result is stored
-     * @param pixels source
-     * @param line_size number of bytes in a horizontal line of block
-     * @param h height
-
-*/
-
-DEFUN(put_pixels8uc,mL1,
-        (uint8_t *block, const uint8_t *s0, const uint8_t *s1,
-                 int dest_size, int line_size, int h)):
-        i3=r0;        // dest
-        i0=r1;        // src0
-        i1=r2;        // src1
-        r0=[sp+12];   // dest_size
-        r2=[sp+16];   // line_size
-        p0=[sp+20];   // h
-        [--sp] = (r7:6);
-        r0+=-4;
-        m3=r0;
-        r2+=-8;
-        m0=r2;
-        LSETUP(pp8$0,pp8$1) LC0=P0;
-        DISALGNEXCPT                || R0 = [I0++]  || R2  =[I1++];
-
-pp8$0:  DISALGNEXCPT                || R1 = [I0++]  || R3  =[I1++];
-        R6 = BYTEOP1P(R1:0,R3:2)    || R0 = [I0++M0]|| R2  =[I1++M0];
-        R7 = BYTEOP1P(R1:0,R3:2)(R) || R0 = [I0++]  || [I3++] = R6 ;
-pp8$1:  DISALGNEXCPT                || R2 = [I1++]  || [I3++M3] = R7;
-
-        (r7:6) = [sp++];
-        RTS;
-DEFUN_END(put_pixels8uc)
-
-DEFUN(put_pixels16uc,mL1,
-        (uint8_t *block, const uint8_t *s0, const uint8_t *s1,
-                 int dest_size, int line_size, int h)):
-        link 0;
-        [--sp] = (r7:6);
-        i3=r0;        // dest
-        i0=r1;        // src0
-        i1=r2;        // src1
-        r0=[fp+20];   // dest_size
-        r2=[fp+24];   // line_size
-        p0=[fp+28];   // h
-
-
-        r0+=-12;
-        m3=r0;        // line_size
-        r2+=-16;
-        m0=r2;
-
-        LSETUP(pp16$0,pp16$1) LC0=P0;
-         DISALGNEXCPT                || R0 = [I0++]   || R2  =[I1++];
-
-pp16$0:  DISALGNEXCPT                || R1 = [I0++]   || R3  =[I1++];
-         R6 = BYTEOP1P(R1:0,R3:2)    || R0 = [I0++]   || R2  =[I1++];
-         R7 = BYTEOP1P(R1:0,R3:2)(R) || R1 = [I0++]   || R3  =[I1++];
-         [I3++] = R6;
-         R6 = BYTEOP1P(R1:0,R3:2)    || R0 = [I0++M0] || R2  =[I1++M0];
-         R7 = BYTEOP1P(R1:0,R3:2)(R) || R0 = [I0++]   || [I3++] = R7 ;
-         [I3++] = R6;
-pp16$1:  DISALGNEXCPT                || R2 = [I1++]   || [I3++M3] = R7;
-
-        (r7:6) = [sp++];
-        unlink;
-        RTS;
-DEFUN_END(put_pixels16uc)
-
-
-
-
-
-
-DEFUN(put_pixels8uc_nornd,mL1,
-        (uint8_t *block, const uint8_t *s0, const uint8_t *s1,
-                 int line_size, int h)):
-        i3=r0;        // dest
-        i0=r1;        // src0
-        i1=r2;        // src1
-        r2=[sp+12];   // line_size
-        p0=[sp+16];   // h
-        [--sp] = (r7:6);
-        r2+=-4;
-        m3=r2;
-        r2+=-4;
-        m0=r2;
-        LSETUP(pp8$2,pp8$3) LC0=P0;
-        DISALGNEXCPT                || R0 = [I0++]  || R2  =[I1++];
-
-pp8$2:  DISALGNEXCPT                || R1 = [I0++]  || R3  =[I1++];
-        R6 = BYTEOP1P(R1:0,R3:2)(T)  || R0 = [I0++M0]|| R2  =[I1++M0];
-        R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R0 = [I0++]  || [I3++] = R6 ;
-pp8$3:  DISALGNEXCPT                || R2 = [I1++]  || [I3++M3] = R7;
-
-        (r7:6) = [sp++];
-        RTS;
-DEFUN_END(put_pixels8uc_nornd)
-
-DEFUN(put_pixels16uc_nornd,mL1,
-        (uint8_t *block, const uint8_t *s0, const uint8_t *s1,
-                 int line_size, int h)):
-        i3=r0;        // dest
-        i0=r1;        // src0
-        i1=r2;        // src1
-        r2=[sp+12];   // line_size
-        p0=[sp+16];   // h
-
-        [--sp] = (r7:6);
-        r2+=-12;
-        m3=r2;        // line_size
-        r2+=-4;
-        m0=r2;
-
-        LSETUP(pp16$2,pp16$3) LC0=P0;
-        DISALGNEXCPT                || R0 = [I0++]   || R2  =[I1++];
-
-pp16$2:
-        DISALGNEXCPT                || R1 = [I0++]   || R3  =[I1++];
-        R6 = BYTEOP1P(R1:0,R3:2)(T)    || R0 = [I0++]   || R2  =[I1++];
-        R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R1 = [I0++]   || R3  =[I1++];
-        [I3++] = R6;
-
-        R6 = BYTEOP1P(R1:0,R3:2)(T)    || R0 = [I0++M0] || R2  =[I1++M0];
-        R7 = BYTEOP1P(R1:0,R3:2)(T,R) || R0 = [I0++]   || [I3++] = R7 ;
-        [I3++] = R6;
-pp16$3: DISALGNEXCPT                || R2 = [I1++]   || [I3++M3] = R7;
-
-        (r7:6) = [sp++];
-
-        RTS;
-DEFUN_END(put_pixels16uc_nornd)
-
-DEFUN(z_put_pixels16_xy2,mL1,
-        (uint8_t *block, const uint8_t *s0,
-                 int dest_size, int line_size, int h)):
-        link 0;
-        [--sp] = (r7:4);
-        i3=r0;        // dest
-        i0=r1;        // src0--> pixels
-        i1=r1;        // src1--> pixels + line_size
-        r2+=-12;
-        m2=r2;        // m2=dest_width-4
-        r2=[fp+20];
-        m3=r2;        // line_size
-        p0=[fp+24];   // h
-        r2+=-16;
-        i1+=m3;       /* src1 + line_size */
-        m0=r2;        /* line-size - 20 */
-
-        B0 = I0;
-        B1 = I1;
-        B3 = I3;
-
-        DISALGNEXCPT                       || R0 = [I0++] || R2  =[I1++];
-
-        LSETUP(LS$16E,LE$16E) LC0=P0;
-LS$16E: DISALGNEXCPT                       || R1 = [I0++] || R3  =[I1++];
-        R4 = BYTEOP2P (R3:2,R1:0) (RNDL)   || R0 = [I0++] || R2  =[I1++];
-        R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R1 = [I0++] || [I3++] = R4 ;
-        DISALGNEXCPT                       || R3 = [I1++] || [I3++] = R5;
-        R4 = BYTEOP2P (R3:2,R1:0) (RNDL)   || R0 = [I0++M0]|| R2  = [I1++M0];
-        R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R0 = [I0++] || [I3++] = R4 ;
-LE$16E: DISALGNEXCPT                       || R2 = [I1++] || [I3++M2] = R5;
-
-        M1 = 1;
-        I3 = B3;
-        I1 = B1;
-        I0 = B0;
-
-        I0 += M1;
-        I1 += M1;
-
-        DISALGNEXCPT                       || R0 = [I0++] || R2  =[I1++];
-        LSETUP(LS$16O,LE$16O) LC0=P0;
-LS$16O: DISALGNEXCPT                       || R1 = [I0++] || R3  =[I1++];
-        R4 = BYTEOP2P (R3:2,R1:0) (RNDH)   || R0 = [I0++] || R2  =[I1++];
-        R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R1 = [I0++] || R6  =[I3++];
-        R4 = R4 +|+ R6                       || R7 = [I3--];
-        R5 = R5 +|+ R7                       || [I3++] = R4;
-        DISALGNEXCPT                       || R3  =[I1++] || [I3++] = R5;
-        R4 = BYTEOP2P (R3:2,R1:0) (RNDH)   || R0 = [I0++M0]|| R2  = [I1++M0];
-        R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R0 = [I0++] || R6 = [I3++];
-        R4 = R4 +|+ R6                       || R7 = [I3--];
-        R5 = R5 +|+ R7                       || [I3++] = R4;
-LE$16O: DISALGNEXCPT                       || R2 = [I1++] || [I3++M2] = R5;
-
-        (r7:4) = [sp++];
-        unlink;
-        rts;
-DEFUN_END(z_put_pixels16_xy2)
-
-DEFUN(put_pixels16_xy2_nornd,mL1,
-        (uint8_t *block, const uint8_t *s0,
-                 int line_size, int h)):
-        link 0;
-        [--sp] = (r7:4);
-        i3=r0;        // dest
-        i0=r1;        // src0--> pixels
-        i1=r1;        // src1--> pixels + line_size
-        m3=r2;
-        r2+=-12;
-        m2=r2;
-        r2+=-4;
-        i1+=m3;       /* src1 + line_size */
-        m0=r2;        /* line-size - 20 */
-        p0=[fp+20];   // h
-
-        B0=I0;
-        B1=I1;
-        B3=I3;
-
-        DISALGNEXCPT                       || R0 = [I0++] || R2  =[I1++];
-
-        LSETUP(LS$16ET,LE$16ET) LC0=P0;
-LS$16ET:DISALGNEXCPT                       || R1 = [I0++] || R3  =[I1++];
-        R4 = BYTEOP2P (R3:2,R1:0) (TL)     || R0 = [I0++] || R2  =[I1++];
-        R5 = BYTEOP2P (R3:2,R1:0) (TL,R)   || R1 = [I0++] || [I3++] = R4 ;
-        DISALGNEXCPT                       || R3 = [I1++] || [I3++] = R5;
-        R4 = BYTEOP2P (R3:2,R1:0) (TL)     || R0 = [I0++M0]|| R2  = [I1++M0];
-        R5 = BYTEOP2P (R3:2,R1:0) (TL,R)   || R0 = [I0++] || [I3++] = R4 ;
-LE$16ET:DISALGNEXCPT                       || R2 = [I1++] || [I3++M2] = R5;
-
-        M1 = 1;
-        I3=B3;
-        I1=B1;
-        I0=B0;
-
-        I0 += M1;
-        I1 += M1;
-
-        DISALGNEXCPT                       || R0 = [I0++] || R2  =[I1++];
-        LSETUP(LS$16OT,LE$16OT) LC0=P0;
-LS$16OT:DISALGNEXCPT                       || R1 = [I0++] || R3  =[I1++];
-        R4 = BYTEOP2P (R3:2,R1:0) (TH)     || R0 = [I0++] || R2  =[I1++];
-        R5 = BYTEOP2P (R3:2,R1:0) (TH,R)   || R1 = [I0++] || R6  =[I3++];
-        R4 = R4 +|+ R6                                    || R7 = [I3--];
-        R5 = R5 +|+ R7                                    || [I3++] = R4;
-        DISALGNEXCPT                       || R3  =[I1++] || [I3++] = R5;
-        R4 = BYTEOP2P (R3:2,R1:0) (TH)     || R0 = [I0++M0]|| R2  = [I1++M0];
-        R5 = BYTEOP2P (R3:2,R1:0) (TH,R)   || R0 = [I0++] || R6 = [I3++];
-        R4 = R4 +|+ R6                                    || R7 = [I3--];
-        R5 = R5 +|+ R7                                    || [I3++] = R4;
-LE$16OT:DISALGNEXCPT                       || R2 = [I1++] || [I3++M2] = R5;
-
-        (r7:4) = [sp++];
-        unlink;
-        rts;
-DEFUN_END(put_pixels16_xy2_nornd)
-
-DEFUN(z_put_pixels8_xy2,mL1,
-        (uint8_t *block, const uint8_t *s0,
-                 int dest_size, int line_size, int h)):
-        link 0;
-        [--sp] = (r7:4);
-        i3=r0;        // dest
-        i0=r1;        // src0--> pixels
-        i1=r1;        // src1--> pixels + line_size
-        r2+=-4;
-        m2=r2;        // m2=dest_width-4
-        r2=[fp+20];
-        m3=r2;        // line_size
-        p0=[fp+24];   // h
-        r2+=-8;
-        i1+=m3;       /* src1 + line_size */
-        m0=r2;        /* line-size - 20 */
-
-        b0 = I0;
-        b1 = I1;
-        b3 = I3;
-
-        LSETUP(LS$8E,LE$8E) LC0=P0;
-        DISALGNEXCPT                       || R0 = [I0++]   || R2  =[I1++];
-LS$8E:  DISALGNEXCPT                       || R1 = [I0++]   || R3  =[I1++];
-        R4 = BYTEOP2P (R3:2,R1:0) (RNDL)   || R0 = [I0++M0] || R2  =[I1++M0];
-        R5 = BYTEOP2P (R3:2,R1:0) (RNDL,R) || R0 = [I0++]   || [I3++] = R4 ;
-LE$8E:  DISALGNEXCPT                       || R2 = [I1++]   || [I3++M2] = R5;
-
-        M1 = 1;
-        I3 = b3;
-        I1 = b1;
-        I0 = b0;
-
-        I0 += M1;
-        I1 += M1;
-
-        LSETUP(LS$8O,LE$8O) LC0=P0;
-        DISALGNEXCPT                       || R0 = [I0++]   || R2  =[I1++];
-LS$8O:  DISALGNEXCPT                       || R1 = [I0++]   || R3  =[I1++];
-        R4 = BYTEOP2P (R3:2,R1:0) (RNDH)   || R0 = [I0++M0] || R2  =[I1++M0];
-        R5 = BYTEOP2P (R3:2,R1:0) (RNDH,R) || R0 = [I0++]   || R6  =[I3++];
-        R4 = R4 +|+ R6                                      || R7 = [I3--];
-        R5 = R5 +|+ R7                                      || [I3++] = R4;
-LE$8O:  DISALGNEXCPT                       || R2  =[I1++]   || [I3++M2] = R5;
-
-        (r7:4) = [sp++];
-        unlink;
-        rts;
-DEFUN_END(z_put_pixels8_xy2)
-
-DEFUN(put_pixels8_xy2_nornd,mL1,
-        (uint8_t *block, const uint8_t *s0, int line_size, int h)):
-        link 0;
-        [--sp] = (r7:4);
-        i3=r0;        // dest
-        i0=r1;        // src0--> pixels
-        i1=r1;        // src1--> pixels + line_size
-        m3=r2;
-        r2+=-4;
-        m2=r2;
-        r2+=-4;
-        i1+=m3;       /* src1 + line_size */
-        m0=r2;        /* line-size - 20 */
-        p0=[fp+20];   // h
-
-
-        b0 = I0;
-        b1 = I1;
-        b3 = I3;
-
-        LSETUP(LS$8ET,LE$8ET) LC0=P0;
-        DISALGNEXCPT                       || R0 = [I0++]   || R2  =[I1++];
-
-LS$8ET: DISALGNEXCPT                       || R1 = [I0++]   || R3 = [I1++];
-        R4 = BYTEOP2P (R3:2,R1:0) (TL)     || R0 = [I0++M0] || R2 = [I1++M0];
-        R5 = BYTEOP2P (R3:2,R1:0) (TL,R)   || R0 = [I0++]   || [I3++] = R4 ;
-LE$8ET: DISALGNEXCPT                       || R2 = [I1++]   || [I3++M2] = R5;
-
-        M1 = 1;
-        I3 = b3;
-        I1 = b1;
-        I0 = b0;
-
-        I0 += M1;
-        I1 += M1;
-
-        LSETUP(LS$8OT,LE$8OT) LC0=P0;
-        DISALGNEXCPT                       || R0 = [I0++]   || R2 = [I1++];
-
-LS$8OT: DISALGNEXCPT                       || R1 = [I0++]   || R3 = [I1++];
-        R4 = BYTEOP2P (R3:2,R1:0) (TH)     || R0 = [I0++M0] || R2 = [I1++M0];
-        R5 = BYTEOP2P (R3:2,R1:0) (TH,R)   || R0 = [I0++]   || R6 = [I3++];
-        R4 = R4 +|+ R6                                      || R7 = [I3--];
-        R5 = R5 +|+ R7                                      || [I3++] = R4;
-LE$8OT: DISALGNEXCPT                       || R2  =[I1++]   || [I3++M2] = R5;
-
-        (r7:4) = [sp++];
-        unlink;
-        rts;
-
 DEFUN(diff_pixels,mL1,
-       (DCTELEM *block, uint8_t *s1, uint8_t *s2, int stride)):
+       (int16_t *block, uint8_t *s1, uint8_t *s2, int stride)):
         link 0;
         [--sp] = (r7:4);
         p0=8;
@@ -467,7 +109,7 @@ DEFUN(diff_pixels,mL1,
         (r7:4) = [sp++];
         unlink;
         rts;
-DEFUN_END(put_pixels8_xy2_nornd)
+DEFUN_END(diff_pixels)
 
 /*
     for (i = 0; i < 16; i++) {
@@ -518,7 +160,7 @@ DEFUN_END(pix_sum)
 
 
 DEFUN(get_pixels,mL1,
-        (DCTELEM *restrict block, const uint8_t *pixels, int line_size)):
+        (int16_t *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..a8cdcb6 100644
--- a/libavcodec/bfin/vp3_bfin.c
+++ b/libavcodec/bfin/vp3_bfin.c
@@ -18,26 +18,48 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <string.h>
+
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
+#include "libavcodec/vp3dsp.h"
 #include "libavcodec/dsputil.h"
 #include "dsputil_bfin.h"
+#include "vp3_bfin.h"
 
 /* Intra iDCT offset 128 */
-void ff_bfin_vp3_idct_put (uint8_t *dest, int line_size, DCTELEM *block)
+static void bfin_vp3_idct_put(uint8_t *dest, int line_size, int16_t *block)
 {
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + 128;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + 128;
     int i,j;
 
     ff_bfin_vp3_idct (block);
 
     for (i=0;i<8;i++)
         for (j=0;j<8;j++)
-            dest[line_size*i+j]=cm[block[i*8+j]];
+            dest[line_size*i + j] = cm[block[j*8 + i]];
+
+    memset(block, 0, 128);
 }
 
 /* Inter iDCT */
-void ff_bfin_vp3_idct_add (uint8_t *dest, int line_size, DCTELEM *block)
+static void bfin_vp3_idct_add(uint8_t *dest, int line_size, int16_t *block)
 {
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    int i, j;
+
     ff_bfin_vp3_idct (block);
-    ff_bfin_add_pixels_clamped (block, dest, line_size);
+    for (i = 0; i < 8; i++)
+        for (j = 0; j < 8; j++)
+            dest[line_size*i + j] = cm[dest[line_size*i + j] + block[j*8 + i]];
+
+    memset(block, 0, 128);
+}
+
+av_cold void ff_vp3dsp_init_bfin(VP3DSPContext *c, int flags)
+{
+    if (!(flags & CODEC_FLAG_BITEXACT)) {
+        c->idct_add = bfin_vp3_idct_add;
+        c->idct_put = bfin_vp3_idct_put;
+    }
 }
diff --git a/libavcodec/bfin/vp3_bfin.h b/libavcodec/bfin/vp3_bfin.h
new file mode 100644
index 0000000..5a2c5a4
--- /dev/null
+++ b/libavcodec/bfin/vp3_bfin.h
@@ -0,0 +1,27 @@
+/*
+ * 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_BFIN_VP3_BFIN_H
+#define AVCODEC_BFIN_VP3_BFIN_H
+
+#include <stdint.h>
+
+void ff_bfin_vp3_idct(int16_t *block);
+
+#endif /* AVCODEC_BFIN_VP3_BFIN_H */
diff --git a/libavcodec/bfin/vp3_idct_bfin.S b/libavcodec/bfin/vp3_idct_bfin.S
index 2e18f91..05ec96a 100644
--- a/libavcodec/bfin/vp3_idct_bfin.S
+++ b/libavcodec/bfin/vp3_idct_bfin.S
@@ -22,7 +22,7 @@
 /*
    This blackfin DSP code implements an 8x8 inverse type II DCT.
 
-Prototype       : void ff_bfin_vp3_idct(DCTELEM *in)
+Prototype       : void ff_bfin_vp3_idct(int16_t *in)
 
 Registers Used  : A0, A1, R0-R7, I0-I3, B0, B2, B3, M0-M2, L0-L3, P0-P5, LC0.
 
@@ -63,7 +63,7 @@ vtmp: .space 256
 
 .text
 DEFUN(vp3_idct,mL1,
-        (DCTELEM *block)):
+        (int16_t *block)):
 
 /********************** Function Prologue *********************************/
     link 16;
diff --git a/libavcodec/bgmc.c b/libavcodec/bgmc.c
index ec8cf9b..c7f732e 100644
--- a/libavcodec/bgmc.c
+++ b/libavcodec/bgmc.c
@@ -25,6 +25,7 @@
  * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
  */
 
+#include "libavutil/attributes.h"
 #include "bgmc.h"
 
 #define FREQ_BITS  14                      // bits used by frequency counters
@@ -456,7 +457,8 @@ static uint8_t *bgmc_lut_getp(uint8_t *lut, int *lut_status, int delta)
 
 
 /** Initialize the lookup table arrays */
-int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, int **cf_lut_status)
+av_cold int ff_bgmc_init(AVCodecContext *avctx,
+                         uint8_t **cf_lut, int **cf_lut_status)
 {
     *cf_lut        = av_malloc(sizeof(*cf_lut)        * LUT_BUFF * 16 * LUT_SIZE);
     *cf_lut_status = av_malloc(sizeof(*cf_lut_status) * LUT_BUFF);
@@ -475,7 +477,7 @@ int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, int **cf_lut_status)
 
 
 /** Release the lookup table arrays */
-void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status)
+av_cold void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status)
 {
     av_freep(cf_lut);
     av_freep(cf_lut_status);
@@ -483,8 +485,8 @@ void ff_bgmc_end(uint8_t **cf_lut, int **cf_lut_status)
 
 
 /** Initialize decoding and reads the first value */
-void ff_bgmc_decode_init(GetBitContext *gb, unsigned int *h, unsigned int *l,
-                         unsigned int *v)
+void ff_bgmc_decode_init(GetBitContext *gb, unsigned int *h,
+                         unsigned int *l, unsigned int *v)
 {
     *h = TOP_VALUE;
     *l = 0;
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index c637f4e..0057542 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -20,11 +20,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "binkdata.h"
 #include "binkdsp.h"
+#include "hpeldsp.h"
 #include "internal.h"
 #include "mathops.h"
 
@@ -111,8 +114,9 @@ typedef struct Bundle {
 typedef struct BinkContext {
     AVCodecContext *avctx;
     DSPContext     dsp;
+    HpelDSPContext hdsp;
     BinkDSPContext bdsp;
-    AVFrame        pic, last;
+    AVFrame        *last;
     int            version;              ///< internal Bink file version
     int            has_alpha;
     int            swap_planes;
@@ -313,7 +317,7 @@ static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (get_bits1(gb)) {
         v = get_bits(gb, 4);
@@ -335,7 +339,7 @@ static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(avctx, AV_LOG_ERROR, "Too many motion values\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (get_bits1(gb)) {
         v = get_bits(gb, 4);
@@ -370,7 +374,7 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(avctx, AV_LOG_ERROR, "Too many block type values\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (get_bits1(gb)) {
         v = get_bits(gb, 4);
@@ -386,7 +390,7 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
                 int run = bink_rlelens[v - 12];
 
                 if (dec_end - b->cur_dec < run)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 memset(b->cur_dec, last, run);
                 b->cur_dec += run;
             }
@@ -404,7 +408,7 @@ static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b)
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     while (b->cur_dec < dec_end) {
         v  = GET_HUFF(gb, b->tree);
@@ -424,7 +428,7 @@ static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c)
     dec_end = b->cur_dec + t;
     if (dec_end > b->data_end) {
         av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (get_bits1(gb)) {
         c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]);
@@ -470,13 +474,13 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b,
         v = (v ^ sign) - sign;
     }
     if (dst_end - dst < 1)
-        return -1;
+        return AVERROR_INVALIDDATA;
     *dst++ = v;
     len--;
     for (i = 0; i < len; i += 8) {
         len2 = FFMIN(len - i, 8);
         if (dst_end - dst < len2)
-            return -1;
+            return AVERROR_INVALIDDATA;
         bsize = get_bits(gb, 4);
         if (bsize) {
             for (j = 0; j < len2; j++) {
@@ -489,7 +493,7 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b,
                 *dst++ = v;
                 if (v < -32768 || v > 32767) {
                     av_log(avctx, AV_LOG_ERROR, "DC value went out of bounds: %d\n", v);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
             }
         } else {
@@ -521,14 +525,14 @@ static inline int get_value(BinkContext *c, int bundle)
     return ret;
 }
 
-static void binkb_init_bundle(BinkContext *c, int bundle_num)
+static av_cold void binkb_init_bundle(BinkContext *c, int bundle_num)
 {
     c->bundle[bundle_num].cur_dec =
     c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data;
     c->bundle[bundle_num].len = 13;
 }
 
-static void binkb_init_bundles(BinkContext *c)
+static av_cold void binkb_init_bundles(BinkContext *c)
 {
     int i;
     for (i = 0; i < BINKB_NB_SRC; i++)
@@ -545,7 +549,7 @@ static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num)
 
     CHECK_READ_VAL(gb, b, len);
     if (b->data_end - b->cur_dec < len * (1 + (bits > 8)))
-        return -1;
+        return AVERROR_INVALIDDATA;
     if (bits <= 8) {
         if (!issigned) {
             for (i = 0; i < len; i++)
@@ -699,7 +703,7 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t *
  * @param masks_count number of masks to decode
  * @return 0 on success, negative value in other cases
  */
-static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count)
+static int read_residue(GetBitContext *gb, int16_t block[64], int masks_count)
 {
     int coef_list[128];
     int mode_list[128];
@@ -794,39 +798,39 @@ static inline void put_pixels8x8_overlapped(uint8_t *dst, uint8_t *src, int stri
         memcpy(dst + i*stride, tmp + i*8, 8);
 }
 
-static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
-                              int is_key, int is_chroma)
+static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
+                              int plane_idx, int is_key, int is_chroma)
 {
-    int blk;
+    int blk, ret;
     int i, j, bx, by;
     uint8_t *dst, *ref, *ref_start, *ref_end;
     int v, col[2];
     const uint8_t *scan;
     int xoff, yoff;
-    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+    LOCAL_ALIGNED_16(int16_t, block, [64]);
     LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
     int coordmap[64];
     int ybias = is_key ? -15 : 0;
     int qp;
 
-    const int stride = c->pic.linesize[plane_idx];
+    const int stride = frame->linesize[plane_idx];
     int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;
     int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
 
     binkb_init_bundles(c);
-    ref_start = c->pic.data[plane_idx];
-    ref_end   = c->pic.data[plane_idx] + (bh * c->pic.linesize[plane_idx] + bw) * 8;
+    ref_start = frame->data[plane_idx];
+    ref_end   = frame->data[plane_idx] + (bh * frame->linesize[plane_idx] + bw) * 8;
 
     for (i = 0; i < 64; i++)
         coordmap[i] = (i & 7) + (i >> 3) * stride;
 
     for (by = 0; by < bh; by++) {
         for (i = 0; i < BINKB_NB_SRC; i++) {
-            if (binkb_read_bundle(c, gb, i) < 0)
-                return -1;
+            if ((ret = binkb_read_bundle(c, gb, i)) < 0)
+                return ret;
         }
 
-        dst  = c->pic.data[plane_idx]  + 8*by*stride;
+        dst  = frame->data[plane_idx]  + 8*by*stride;
         for (bx = 0; bx < bw; bx++, dst += 8) {
             blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES);
             switch (blk) {
@@ -844,7 +848,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                     i += run;
                     if (i > 64) {
                         av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     if (mode) {
                         v = binkb_get_value(c, BINKB_SRC_COLORS);
@@ -872,7 +876,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 if (ref < ref_start || ref + 8*stride > ref_end) {
                     av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n");
                 } else if (ref + 8*stride < dst || ref >= dst + 8*stride) {
-                    c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
+                    c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 } else {
                     put_pixels8x8_overlapped(dst, ref, stride);
                 }
@@ -888,7 +892,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 if (ref < ref_start || ref + 8 * stride > ref_end) {
                     av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n");
                 } else if (ref + 8*stride < dst || ref >= dst + 8*stride) {
-                    c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
+                    c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 } else {
                     put_pixels8x8_overlapped(dst, ref, stride);
                 }
@@ -918,7 +922,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 if (ref < ref_start || ref + 8 * stride > ref_end) {
                     av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n");
                 } else if (ref + 8*stride < dst || ref >= dst + 8*stride) {
-                    c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
+                    c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 } else {
                     put_pixels8x8_overlapped(dst, ref, stride);
                 }
@@ -930,7 +934,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 break;
             default:
                 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }
@@ -940,21 +944,21 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
     return 0;
 }
 
-static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
-                             int is_chroma)
+static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
+                             int plane_idx, int is_chroma)
 {
-    int blk;
+    int blk, ret;
     int i, j, bx, by;
     uint8_t *dst, *prev, *ref, *ref_start, *ref_end;
     int v, col[2];
     const uint8_t *scan;
     int xoff, yoff;
-    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+    LOCAL_ALIGNED_16(int16_t, block, [64]);
     LOCAL_ALIGNED_16(uint8_t, ublock, [64]);
     LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
     int coordmap[64];
 
-    const int stride = c->pic.linesize[plane_idx];
+    const int stride = frame->linesize[plane_idx];
     int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;
     int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
     int width = c->avctx->width >> is_chroma;
@@ -963,39 +967,39 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
     for (i = 0; i < BINK_NB_SRC; i++)
         read_bundle(gb, c, i);
 
-    ref_start = c->last.data[plane_idx] ? c->last.data[plane_idx]
-                                        : c->pic.data[plane_idx];
+    ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx]
+                                         : frame->data[plane_idx];
     ref_end   = ref_start
-                + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8;
+                + (bw - 1 + c->last->linesize[plane_idx] * (bh - 1)) * 8;
 
     for (i = 0; i < 64; i++)
         coordmap[i] = (i & 7) + (i >> 3) * stride;
 
     for (by = 0; by < bh; by++) {
-        if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0)
-            return -1;
-        if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0)
-            return -1;
-        if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0)
-            return -1;
-        if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0)
-            return -1;
-        if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0)
-            return -1;
-        if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0)
-            return -1;
-        if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0)
-            return -1;
-        if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0)
-            return -1;
-        if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0)
-            return -1;
+        if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES])) < 0)
+            return ret;
+        if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0)
+            return ret;
+        if ((ret = read_colors(gb, &c->bundle[BINK_SRC_COLORS], c)) < 0)
+            return ret;
+        if ((ret = read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN])) < 0)
+            return ret;
+        if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF])) < 0)
+            return ret;
+        if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF])) < 0)
+            return ret;
+        if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0)
+            return ret;
+        if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0)
+            return ret;
+        if ((ret = read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN])) < 0)
+            return ret;
 
         if (by == bh)
             break;
-        dst  = c->pic.data[plane_idx]  + 8*by*stride;
-        prev = (c->last.data[plane_idx] ? c->last.data[plane_idx]
-                                        : c->pic.data[plane_idx]) + 8*by*stride;
+        dst  = frame->data[plane_idx]  + 8*by*stride;
+        prev = (c->last->data[plane_idx] ? c->last->data[plane_idx]
+                                         : frame->data[plane_idx]) + 8*by*stride;
         for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {
             blk = get_value(c, BINK_SRC_BLOCK_TYPES);
             // 16x16 block type on odd line means part of the already decoded block, so skip it
@@ -1007,7 +1011,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
             }
             switch (blk) {
             case SKIP_BLOCK:
-                c->dsp.put_pixels_tab[1][0](dst, prev, stride, 8);
+                c->hdsp.put_pixels_tab[1][0](dst, prev, stride, 8);
                 break;
             case SCALED_BLOCK:
                 blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES);
@@ -1021,7 +1025,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                         i += run;
                         if (i > 64) {
                             av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                            return -1;
+                            return AVERROR_INVALIDDATA;
                         }
                         if (get_bits1(gb)) {
                             v = get_value(c, BINK_SRC_COLORS);
@@ -1061,7 +1065,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                     break;
                 default:
                     av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 if (blk != FILL_BLOCK)
                 c->bdsp.scale_block(ublock, dst, stride);
@@ -1076,9 +1080,9 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 if (ref < ref_start || ref > ref_end) {
                     av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
                            bx*8 + xoff, by*8 + yoff);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
-                c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
+                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 break;
             case RUN_BLOCK:
                 scan = bink_patterns[get_bits(gb, 4)];
@@ -1089,7 +1093,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                     i += run;
                     if (i > 64) {
                         av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     if (get_bits1(gb)) {
                         v = get_value(c, BINK_SRC_COLORS);
@@ -1110,9 +1114,9 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 if (ref < ref_start || ref > ref_end) {
                     av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n",
                            bx*8 + xoff, by*8 + yoff);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
-                c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
+                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 c->dsp.clear_block(block);
                 v = get_bits(gb, 7);
                 read_residue(gb, block, v);
@@ -1132,7 +1136,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 xoff = get_value(c, BINK_SRC_X_OFF);
                 yoff = get_value(c, BINK_SRC_Y_OFF);
                 ref = prev + xoff + yoff * stride;
-                c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
+                c->hdsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 memset(dctblock, 0, sizeof(*dctblock) * 64);
                 dctblock[0] = get_value(c, BINK_SRC_INTER_DC);
                 read_dct_coeffs(gb, dctblock, bink_scan, bink_inter_quant, -1);
@@ -1154,7 +1158,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 break;
             default:
                 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }
@@ -1167,31 +1171,31 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
 {
     BinkContext * const c = avctx->priv_data;
+    AVFrame *frame = data;
     GetBitContext gb;
-    int plane, plane_idx;
+    int plane, plane_idx, ret;
     int bits_count = pkt->size << 3;
 
     if (c->version > 'b') {
-        if(c->pic.data[0])
-            avctx->release_buffer(avctx, &c->pic);
-
-        if(ff_get_buffer(avctx, &c->pic) < 0){
+        if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
     } else {
-        if(avctx->reget_buffer(avctx, &c->pic) < 0){
+        if ((ret = ff_reget_buffer(avctx, c->last)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
+            return ret;
         }
+        if ((ret = av_frame_ref(frame, c->last)) < 0)
+            return ret;
     }
 
     init_get_bits(&gb, pkt->data, bits_count);
     if (c->has_alpha) {
         if (c->version >= 'i')
             skip_bits_long(&gb, 32);
-        if (bink_decode_plane(c, &gb, 3, 0) < 0)
-            return -1;
+        if ((ret = bink_decode_plane(c, frame, &gb, 3, 0)) < 0)
+            return ret;
     }
     if (c->version >= 'i')
         skip_bits_long(&gb, 32);
@@ -1200,22 +1204,25 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3);
 
         if (c->version > 'b') {
-            if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0)
-                return -1;
+            if ((ret = bink_decode_plane(c, frame, &gb, plane_idx, !!plane)) < 0)
+                return ret;
         } else {
-            if (binkb_decode_plane(c, &gb, plane_idx, !pkt->pts, !!plane) < 0)
-                return -1;
+            if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx,
+                                          !avctx->frame_number, !!plane)) < 0)
+                return ret;
         }
         if (get_bits_count(&gb) >= bits_count)
             break;
     }
     emms_c();
 
-    *got_frame = 1;
-    *(AVFrame*)data = c->pic;
+    if (c->version > 'b') {
+        av_frame_unref(c->last);
+        if ((ret = av_frame_ref(c->last, frame)) < 0)
+            return ret;
+    }
 
-    if (c->version > 'b')
-        FFSWAP(AVFrame, c->pic, c->last);
+    *got_frame = 1;
 
     /* always report that the buffer was completely consumed */
     return pkt->size;
@@ -1271,13 +1278,13 @@ static av_cold int decode_init(AVCodecContext *avctx)
     BinkContext * const c = avctx->priv_data;
     static VLC_TYPE table[16 * 128][2];
     static int binkb_initialised = 0;
-    int i;
+    int i, ret;
     int flags;
 
     c->version = avctx->codec_tag >> 24;
     if (avctx->extradata_size < 4) {
         av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     flags = AV_RL32(avctx->extradata);
     c->has_alpha = flags & BINK_FLAG_ALPHA;
@@ -1294,16 +1301,17 @@ static av_cold int decode_init(AVCodecContext *avctx)
     }
     c->avctx = avctx;
 
-    c->pic.data[0] = NULL;
+    c->last = av_frame_alloc();
+    if (!c->last)
+        return AVERROR(ENOMEM);
 
-    if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
-        return 1;
-    }
+    if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
+        return ret;
 
     avctx->pix_fmt = c->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
 
-    avctx->idct_algo = FF_IDCT_BINK;
     ff_dsputil_init(&c->dsp, avctx);
+    ff_hpeldsp_init(&c->hdsp, avctx->flags);
     ff_binkdsp_init(&c->bdsp);
 
     init_bundles(c);
@@ -1322,10 +1330,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     BinkContext * const c = avctx->priv_data;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    if (c->last.data[0])
-        avctx->release_buffer(avctx, &c->last);
+    av_frame_free(&c->last);
 
     free_bundles(c);
     return 0;
@@ -1333,12 +1338,12 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
 AVCodec ff_bink_decoder = {
     .name           = "binkvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Bink video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_BINKVIDEO,
     .priv_data_size = sizeof(BinkContext),
     .init           = decode_init,
     .close          = decode_end,
     .decode         = decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("Bink video"),
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index 0e5d981..ddaa613 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -32,22 +32,19 @@
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
-#include "dsputil.h"
 #include "dct.h"
 #include "rdft.h"
 #include "fmtconvert.h"
 #include "internal.h"
+#include "wma.h"
 #include "libavutil/intfloat.h"
 
-extern const uint16_t ff_wma_critical_freqs[25];
-
 static float quant_table[96];
 
 #define MAX_CHANNELS 2
 #define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11)
 
 typedef struct {
-    AVFrame frame;
     GetBitContext gb;
     int version_b;          ///< Bink version 'b'
     int first;
@@ -143,9 +140,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     else
         return -1;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -294,6 +288,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                         int *got_frame_ptr, AVPacket *avpkt)
 {
     BinkAudioContext *s = avctx->priv_data;
+    AVFrame *frame      = data;
     GetBitContext *gb = &s->gb;
     int ret, consumed = 0;
 
@@ -321,28 +316,28 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    s->frame.nb_samples = s->frame_len;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->frame_len;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    if (decode_block(s, (float **)s->frame.extended_data,
+    if (decode_block(s, (float **)frame->extended_data,
                      avctx->codec->id == AV_CODEC_ID_BINKAUDIO_DCT)) {
         av_log(avctx, AV_LOG_ERROR, "Incomplete packet\n");
         return AVERROR_INVALIDDATA;
     }
     get_bits_align32(gb);
 
-    s->frame.nb_samples = s->block_size / avctx->channels;
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    frame->nb_samples = s->block_size / avctx->channels;
+    *got_frame_ptr    = 1;
 
     return consumed;
 }
 
 AVCodec ff_binkaudio_rdft_decoder = {
     .name           = "binkaudio_rdft",
+    .long_name      = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_BINKAUDIO_RDFT,
     .priv_data_size = sizeof(BinkAudioContext),
@@ -350,11 +345,11 @@ AVCodec ff_binkaudio_rdft_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)")
 };
 
 AVCodec ff_binkaudio_dct_decoder = {
     .name           = "binkaudio_dct",
+    .long_name      = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_BINKAUDIO_DCT,
     .priv_data_size = sizeof(BinkAudioContext),
@@ -362,5 +357,4 @@ AVCodec ff_binkaudio_dct_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)")
 };
diff --git a/libavcodec/binkdata.h b/libavcodec/binkdata.h
index 60f0a59..3da6b7e 100644
--- a/libavcodec/binkdata.h
+++ b/libavcodec/binkdata.h
@@ -1,6 +1,6 @@
 /*
  * Bink video decoder
- * Copyright (C) 2009 Kostya Shishkov
+ * Copyright (C) 2009 Konstantin Shishkov
  *
  * This file is part of Libav.
  *
diff --git a/libavcodec/binkdsp.c b/libavcodec/binkdsp.c
index 1f7855b..a0ac2a8 100644
--- a/libavcodec/binkdsp.c
+++ b/libavcodec/binkdsp.c
@@ -1,6 +1,6 @@
 /*
  * Bink DSP routines
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of Libav.
  *
@@ -24,6 +24,7 @@
  * Bink DSP routines
  */
 
+#include "libavutil/attributes.h"
 #include "dsputil.h"
 #include "binkdsp.h"
 
@@ -128,7 +129,7 @@ static void scale_block_c(const uint8_t src[64]/*align 8*/, uint8_t *dst/*align
     }
 }
 
-void ff_binkdsp_init(BinkDSPContext *c)
+av_cold void ff_binkdsp_init(BinkDSPContext *c)
 {
     c->idct_add    = bink_idct_add_c;
     c->idct_put    = bink_idct_put_c;
diff --git a/libavcodec/binkdsp.h b/libavcodec/binkdsp.h
index d105f71..4c1f73f 100644
--- a/libavcodec/binkdsp.h
+++ b/libavcodec/binkdsp.h
@@ -1,6 +1,6 @@
 /*
  * Bink DSP routines
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of Libav.
  *
@@ -27,7 +27,7 @@
 #ifndef AVCODEC_BINKDSP_H
 #define AVCODEC_BINKDSP_H
 
-#include "dsputil.h"
+#include <stdint.h>
 
 typedef struct BinkDSPContext {
     void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int32_t *block/*align 16*/);
diff --git a/libavcodec/bit_depth_template.c b/libavcodec/bit_depth_template.c
index 9071ec2..37d02ad 100644
--- a/libavcodec/bit_depth_template.c
+++ b/libavcodec/bit_depth_template.c
@@ -16,7 +16,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "dsputil.h"
+#include "rnd_avg.h"
 
 #ifndef BIT_DEPTH
 #define BIT_DEPTH 8
@@ -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 const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
 #   define no_rnd_avg_pixel4 no_rnd_avg32
 #   define    rnd_avg_pixel4    rnd_avg32
 #   define AV_RN2P  AV_RN16
diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index 2c8692a..8e9f657 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -44,81 +44,89 @@ const uint8_t ff_log2_run[41]={
 
 void avpriv_align_put_bits(PutBitContext *s)
 {
-    put_bits(s,s->bit_left & 7,0);
+    put_bits(s, s->bit_left & 7, 0);
 }
 
-void avpriv_put_string(PutBitContext *pb, const char *string, int terminate_string)
+void avpriv_put_string(PutBitContext *pb, const char *string,
+                       int terminate_string)
 {
-    while(*string){
+    while (*string) {
         put_bits(pb, 8, *string);
         string++;
     }
-    if(terminate_string)
+    if (terminate_string)
         put_bits(pb, 8, 0);
 }
 
 void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
 {
-    int words= length>>4;
-    int bits= length&15;
+    int words = length >> 4;
+    int bits  = length & 15;
     int i;
 
-    if(length==0) return;
+    if (length == 0)
+        return;
 
-    if(CONFIG_SMALL || words < 16 || put_bits_count(pb)&7){
-        for(i=0; i<words; i++) put_bits(pb, 16, AV_RB16(src + 2*i));
-    }else{
-        for(i=0; put_bits_count(pb)&31; i++)
+    if (CONFIG_SMALL || words < 16 || put_bits_count(pb) & 7) {
+        for (i = 0; i < words; i++)
+            put_bits(pb, 16, AV_RB16(src + 2 * i));
+    } else {
+        for (i = 0; put_bits_count(pb) & 31; i++)
             put_bits(pb, 8, src[i]);
         flush_put_bits(pb);
-        memcpy(put_bits_ptr(pb), src+i, 2*words-i);
-        skip_put_bytes(pb, 2*words-i);
+        memcpy(put_bits_ptr(pb), src + i, 2 * words - i);
+        skip_put_bytes(pb, 2 * words - i);
     }
 
-    put_bits(pb, bits, AV_RB16(src + 2*words)>>(16-bits));
+    put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits));
 }
 
 /* VLC decoding */
 
-#define GET_DATA(v, table, i, wrap, size) \
-{\
-    const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
-    switch(size) {\
-    case 1:\
-        v = *(const uint8_t *)ptr;\
-        break;\
-    case 2:\
-        v = *(const uint16_t *)ptr;\
-        break;\
-    default:\
-        v = *(const uint32_t *)ptr;\
-        break;\
-    }\
+#define GET_DATA(v, table, i, wrap, size)                   \
+{                                                           \
+    const uint8_t *ptr = (const uint8_t *)table + i * wrap; \
+    switch(size) {                                          \
+    case 1:                                                 \
+        v = *(const uint8_t *)ptr;                          \
+        break;                                              \
+    case 2:                                                 \
+        v = *(const uint16_t *)ptr;                         \
+        break;                                              \
+    default:                                                \
+        v = *(const uint32_t *)ptr;                         \
+        break;                                              \
+    }                                                       \
 }
 
 
 static int alloc_table(VLC *vlc, int size, int use_static)
 {
-    int index;
-    index = vlc->table_size;
+    int index = vlc->table_size;
+
     vlc->table_size += size;
     if (vlc->table_size > vlc->table_allocated) {
-        if(use_static)
-            abort(); // cannot do anything, init_vlc() is used with too little memory
+        int err;
+        if (use_static)
+            return AVERROR_BUG;
         vlc->table_allocated += (1 << vlc->bits);
-        vlc->table = av_realloc(vlc->table,
-                                sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
-        if (!vlc->table)
-            return -1;
+        if ((err = av_reallocp(&vlc->table,
+                               sizeof(VLC_TYPE) * 2 *
+                               vlc->table_allocated)) < 0) {
+            vlc->table_allocated = 0;
+            vlc->table_size = 0;
+            return err;
+        }
     }
     return index;
 }
 
-static av_always_inline uint32_t bitswap_32(uint32_t x) {
-    return (uint32_t)ff_reverse[x&0xFF]<<24
-         | (uint32_t)ff_reverse[(x>>8)&0xFF]<<16
-         | (uint32_t)ff_reverse[(x>>16)&0xFF]<<8
-         | (uint32_t)ff_reverse[x>>24];
+static av_always_inline uint32_t bitswap_32(uint32_t x)
+{
+    return (uint32_t)ff_reverse[ x        & 0xFF] << 24 |
+           (uint32_t)ff_reverse[(x >> 8)  & 0xFF] << 16 |
+           (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8  |
+           (uint32_t)ff_reverse[ x >> 24];
 }
 
 typedef struct {
@@ -131,10 +139,9 @@ typedef struct {
 
 static int compare_vlcspec(const void *a, const void *b)
 {
-    const VLCcode *sa=a, *sb=b;
+    const VLCcode *sa = a, *sb = b;
     return (sa->code >> 1) - (sb->code >> 1);
 }
-
 /**
  * Build VLC decoding tables suitable for use with get_vlc().
  *
@@ -161,7 +168,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
     table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
     av_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
     if (table_index < 0)
-        return -1;
+        return table_index;
     table = &vlc->table[table_index];
 
     for (i = 0; i < table_size; i++) {
@@ -171,8 +178,8 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
 
     /* first pass: map codes and compute auxiliary table sizes */
     for (i = 0; i < nb_codes; i++) {
-        n = codes[i].bits;
-        code = codes[i].code;
+        n      = codes[i].bits;
+        code   = codes[i].code;
         symbol = codes[i].symbol;
         av_dlog(NULL, "i=%d n=%d code=0x%x\n", i, n, code);
         if (n <= table_nb_bits) {
@@ -188,7 +195,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
                 av_dlog(NULL, "%4x: code=%d n=%d\n", j, i, n);
                 if (table[j][1] /*bits*/ != 0) {
                     av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 table[j][1] = n; //bits
                 table[j][0] = symbol;
@@ -219,7 +226,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
                     j, codes[i].bits + table_nb_bits);
             index = build_table(vlc, subtable_bits, k-i, codes+i, flags);
             if (index < 0)
-                return -1;
+                return index;
             /* note: realloc has been done, so reload tables */
             table = &vlc->table[table_index];
             table[j][0] = index; //code
@@ -257,48 +264,50 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
    with av_free_static(), 0 if ff_free_vlc() will be used.
 */
 int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
-             const void *bits, int bits_wrap, int bits_size,
-             const void *codes, int codes_wrap, int codes_size,
-             const void *symbols, int symbols_wrap, int symbols_size,
-             int flags)
+                       const void *bits, int bits_wrap, int bits_size,
+                       const void *codes, int codes_wrap, int codes_size,
+                       const void *symbols, int symbols_wrap, int symbols_size,
+                       int flags)
 {
     VLCcode *buf;
     int i, j, ret;
 
     vlc->bits = nb_bits;
-    if(flags & INIT_VLC_USE_NEW_STATIC){
-        if(vlc->table_size && vlc->table_size == vlc->table_allocated){
+    if (flags & INIT_VLC_USE_NEW_STATIC) {
+        if (vlc->table_size && vlc->table_size == vlc->table_allocated) {
             return 0;
-        }else if(vlc->table_size){
-            abort(); // fatal error, we are called on a partially initialized table
+        } else if (vlc->table_size) {
+            return AVERROR_BUG;
         }
-    }else {
-        vlc->table = NULL;
+    } else {
+        vlc->table           = NULL;
         vlc->table_allocated = 0;
-        vlc->table_size = 0;
+        vlc->table_size      = 0;
     }
 
     av_dlog(NULL, "build table nb_codes=%d\n", nb_codes);
 
-    buf = av_malloc((nb_codes+1)*sizeof(VLCcode));
+    buf = av_malloc((nb_codes + 1) * sizeof(VLCcode));
+    if (!buf)
+        return AVERROR(ENOMEM);
 
     assert(symbols_size <= 2 || !symbols);
     j = 0;
-#define COPY(condition)\
-    for (i = 0; i < nb_codes; i++) {\
-        GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);\
-        if (!(condition))\
-            continue;\
-        GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);\
-        if (flags & INIT_VLC_LE)\
-            buf[j].code = bitswap_32(buf[j].code);\
-        else\
-            buf[j].code <<= 32 - buf[j].bits;\
-        if (symbols)\
-            GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size)\
-        else\
-            buf[j].symbol = i;\
-        j++;\
+#define COPY(condition)                                                     \
+    for (i = 0; i < nb_codes; i++) {                                        \
+        GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);               \
+        if (!(condition))                                                   \
+            continue;                                                       \
+        GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);            \
+        if (flags & INIT_VLC_LE)                                            \
+            buf[j].code = bitswap_32(buf[j].code);                          \
+        else                                                                \
+            buf[j].code <<= 32 - buf[j].bits;                               \
+        if (symbols)                                                        \
+            GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size) \
+            else                                                            \
+                buf[j].symbol = i;                                          \
+        j++;                                                                \
     }
     COPY(buf[j].bits > nb_bits);
     // qsort is the slowest part of init_vlc, and could probably be improved or avoided
@@ -311,10 +320,12 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
     av_free(buf);
     if (ret < 0) {
         av_freep(&vlc->table);
-        return -1;
+        return ret;
     }
-    if((flags & INIT_VLC_USE_NEW_STATIC) && vlc->table_size != vlc->table_allocated)
-        av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
+    if ((flags & INIT_VLC_USE_NEW_STATIC) &&
+        vlc->table_size != vlc->table_allocated)
+        av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n",
+               vlc->table_size, vlc->table_allocated);
     return 0;
 }
 
diff --git a/libavcodec/bitstream_filter.c b/libavcodec/bitstream_filter.c
index b2d61da..8960b19 100644
--- a/libavcodec/bitstream_filter.c
+++ b/libavcodec/bitstream_filter.c
@@ -23,35 +23,43 @@
 #include "avcodec.h"
 #include "libavutil/mem.h"
 
-static AVBitStreamFilter *first_bitstream_filter= NULL;
+static AVBitStreamFilter *first_bitstream_filter = NULL;
 
-AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f){
-    if(f) return f->next;
-    else  return first_bitstream_filter;
+AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f)
+{
+    if (f)
+        return f->next;
+    else
+        return first_bitstream_filter;
 }
 
-void av_register_bitstream_filter(AVBitStreamFilter *bsf){
-    bsf->next = first_bitstream_filter;
-    first_bitstream_filter= bsf;
+void av_register_bitstream_filter(AVBitStreamFilter *bsf)
+{
+    bsf->next              = first_bitstream_filter;
+    first_bitstream_filter = bsf;
 }
 
-AVBitStreamFilterContext *av_bitstream_filter_init(const char *name){
-    AVBitStreamFilter *bsf= first_bitstream_filter;
+AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)
+{
+    AVBitStreamFilter *bsf = first_bitstream_filter;
 
-    while(bsf){
-        if(!strcmp(name, bsf->name)){
-            AVBitStreamFilterContext *bsfc= av_mallocz(sizeof(AVBitStreamFilterContext));
-            bsfc->filter= bsf;
-            bsfc->priv_data = bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL;
+    while (bsf) {
+        if (!strcmp(name, bsf->name)) {
+            AVBitStreamFilterContext *bsfc =
+                av_mallocz(sizeof(AVBitStreamFilterContext));
+            bsfc->filter    = bsf;
+            bsfc->priv_data =
+                bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL;
             return bsfc;
         }
-        bsf= bsf->next;
+        bsf = bsf->next;
     }
     return NULL;
 }
 
-void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){
-    if(bsfc->filter->close)
+void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc)
+{
+    if (bsfc->filter->close)
         bsfc->filter->close(bsfc);
     av_freep(&bsfc->priv_data);
     av_parser_close(bsfc->parser);
@@ -60,9 +68,11 @@ void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){
 
 int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
                                AVCodecContext *avctx, const char *args,
-                     uint8_t **poutbuf, int *poutbuf_size,
-                     const uint8_t *buf, int buf_size, int keyframe){
-    *poutbuf= (uint8_t *) buf;
-    *poutbuf_size= buf_size;
-    return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe);
+                               uint8_t **poutbuf, int *poutbuf_size,
+                               const uint8_t *buf, int buf_size, int keyframe)
+{
+    *poutbuf      = (uint8_t *)buf;
+    *poutbuf_size = buf_size;
+    return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size,
+                                buf, buf_size, keyframe);
 }
diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index 9c8988c..e5f7ebb 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -25,31 +25,19 @@
 #include "internal.h"
 #include "msrledec.h"
 
-static av_cold int bmp_decode_init(AVCodecContext *avctx)
-{
-    BMPContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
 static int bmp_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    BMPContext *s      = avctx->priv_data;
-    AVFrame *picture   = data;
-    AVFrame *p         = &s->picture;
+    AVFrame *p         = data;
     unsigned int fsize, hsize;
     int width, height;
     unsigned int depth;
     BiCompression comp;
     unsigned int ihsize;
-    int i, j, n, linesize;
+    int i, j, n, linesize, ret;
     uint32_t rgb[3];
     uint8_t *ptr;
     int dsize;
@@ -58,13 +46,13 @@ static int bmp_decode_frame(AVCodecContext *avctx,
 
     if (buf_size < 14) {
         av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (bytestream_get_byte(&buf) != 'B' ||
         bytestream_get_byte(&buf) != 'M') {
         av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     fsize = bytestream_get_le32(&buf);
@@ -81,7 +69,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
     ihsize = bytestream_get_le32(&buf); /* more header size */
     if (ihsize + 14 > hsize) {
         av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* sometimes file size is set to some headers size, set a real size in that case */
@@ -91,7 +79,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
     if (fsize <= hsize) {
         av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
                fsize, hsize);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     switch (ihsize) {
@@ -108,13 +96,13 @@ static int bmp_decode_frame(AVCodecContext *avctx,
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     /* planes */
     if (bytestream_get_le16(&buf) != 1) {
         av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     depth = bytestream_get_le16(&buf);
@@ -127,7 +115,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
     if (comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 &&
         comp != BMP_RLE8) {
         av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (comp == BMP_BITFIELDS) {
@@ -192,26 +180,22 @@ static int bmp_decode_frame(AVCodecContext *avctx,
             avctx->pix_fmt = AV_PIX_FMT_PAL8;
         } else {
             av_log(avctx, AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 1<<depth);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
         av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
@@ -225,7 +209,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
     if (n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8) {
         av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
                dsize, n * avctx->height);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     // RLE may skip decoding some picture areas, so blank picture before decoding
@@ -346,34 +330,20 @@ static int bmp_decode_frame(AVCodecContext *avctx,
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
-    *picture = s->picture;
     *got_frame = 1;
 
     return buf_size;
 }
 
-static av_cold int bmp_decode_end(AVCodecContext *avctx)
-{
-    BMPContext* c = avctx->priv_data;
-
-    if (c->picture.data[0])
-        avctx->release_buffer(avctx, &c->picture);
-
-    return 0;
-}
-
 AVCodec ff_bmp_decoder = {
     .name           = "bmp",
+    .long_name      = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_BMP,
-    .priv_data_size = sizeof(BMPContext),
-    .init           = bmp_decode_init,
-    .close          = bmp_decode_end,
     .decode         = bmp_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
 };
diff --git a/libavcodec/bmp.h b/libavcodec/bmp.h
index ab11523..a472f59 100644
--- a/libavcodec/bmp.h
+++ b/libavcodec/bmp.h
@@ -24,10 +24,6 @@
 
 #include "avcodec.h"
 
-typedef struct BMPContext {
-    AVFrame picture;
-} BMPContext;
-
 typedef enum {
     BMP_RGB         =0,
     BMP_RLE8        =1,
diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c
index d27282d..a14fc61 100644
--- a/libavcodec/bmpenc.c
+++ b/libavcodec/bmpenc.c
@@ -31,11 +31,6 @@ static const uint32_t rgb565_masks[]  = { 0xF800, 0x07E0, 0x001F };
 static const uint32_t rgb444_masks[]  = { 0x0F00, 0x00F0, 0x000F };
 
 static av_cold int bmp_encode_init(AVCodecContext *avctx){
-    BMPContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_BGR24:
         avctx->bits_per_coded_sample = 24;
@@ -61,22 +56,25 @@ static av_cold int bmp_encode_init(AVCodecContext *avctx){
         return -1;
     }
 
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
 static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *pict, int *got_packet)
 {
-    BMPContext *s = avctx->priv_data;
-    AVFrame * const p = &s->picture;
+    const AVFrame * const p = pict;
     int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret;
     const uint32_t *pal = NULL;
     int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB;
     int bit_count = avctx->bits_per_coded_sample;
     uint8_t *ptr, *buf;
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_RGB444:
         compression = BMP_BITFIELDS;
@@ -159,13 +157,20 @@ static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
+static av_cold int bmp_encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
 AVCodec ff_bmp_encoder = {
     .name           = "bmp",
+    .long_name      = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_BMP,
-    .priv_data_size = sizeof(BMPContext),
     .init           = bmp_encode_init,
     .encode2        = bmp_encode_frame,
+    .close          = bmp_encode_close,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_BGR24,
         AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444, AV_PIX_FMT_RGB565,
@@ -173,5 +178,4 @@ AVCodec ff_bmp_encoder = {
         AV_PIX_FMT_MONOBLACK,
         AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
 };
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
index bcb1380..3c017d0 100644
--- a/libavcodec/bmv.c
+++ b/libavcodec/bmv.c
@@ -43,7 +43,6 @@ enum BMVFlags{
 
 typedef struct BMVDecContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     uint8_t *frame, frame_base[SCREEN_WIDE * (SCREEN_HIGH + 1)];
     uint32_t pal[256];
@@ -67,7 +66,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
     int i;
 
     if (src_len <= 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (forward) {
         src = source;
@@ -91,7 +90,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
          */
         if (!mode || (tmplen == 4)) {
             if (src < source || src >= source_end)
-                return -1;
+                return AVERROR_INVALIDDATA;
             val = *src;
             read_two_nibbles = 1;
         } else {
@@ -102,7 +101,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
             for (;;) {
                 if (!read_two_nibbles) {
                     if (src < source || src >= source_end)
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     shift += 2;
                     val |= *src << shift;
                     if (*src & 0xC)
@@ -137,7 +136,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
         if (mode >= 4)
             mode -= 3;
         if (len <= 0 || FFABS(dst_end - dst) < len)
-            return -1;
+            return AVERROR_INVALIDDATA;
         switch (mode) {
         case 1:
             if (forward) {
@@ -145,7 +144,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
                         dst - frame + SCREEN_WIDE + frame_off < 0 ||
                         frame_end - dst < frame_off + len ||
                         frame_end - dst < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 for (i = 0; i < len; i++)
                     dst[i] = dst[frame_off + i];
                 dst += len;
@@ -155,7 +154,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
                         dst - frame + SCREEN_WIDE + frame_off < 0 ||
                         frame_end - dst < frame_off + len ||
                         frame_end - dst < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 for (i = len - 1; i >= 0; i--)
                     dst[i] = dst[frame_off + i];
             }
@@ -163,13 +162,13 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
         case 2:
             if (forward) {
                 if (source + src_len - src < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 memcpy(dst, src, len);
                 dst += len;
                 src += len;
             } else {
                 if (src - source < len)
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 dst -= len;
                 src -= len;
                 memcpy(dst, src, len);
@@ -198,6 +197,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *pkt)
 {
     BMVDecContext * const c = avctx->priv_data;
+    AVFrame *frame = data;
     int type, scr_off;
     int i, ret;
     uint8_t *srcptr, *outptr;
@@ -240,11 +240,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         scr_off = 0;
     }
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 3;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -254,20 +250,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
-    c->pic.palette_has_changed = type & BMV_PALETTE;
+    memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
+    frame->palette_has_changed = type & BMV_PALETTE;
 
-    outptr = c->pic.data[0];
+    outptr = frame->data[0];
     srcptr = c->frame;
 
     for (i = 0; i < avctx->height; i++) {
         memcpy(outptr, srcptr, avctx->width);
         srcptr += avctx->width;
-        outptr += c->pic.linesize[0];
+        outptr += frame->linesize[0];
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return pkt->size;
@@ -285,42 +280,23 @@ static av_cold int decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    BMVDecContext *c = avctx->priv_data;
-
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    return 0;
-}
-
-typedef struct BMVAudioDecContext {
-    AVFrame frame;
-} BMVAudioDecContext;
-
 static const int bmv_aud_mults[16] = {
     16512, 8256, 4128, 2064, 1032, 516, 258, 192, 129, 88, 64, 56, 48, 40, 36, 32
 };
 
 static av_cold int bmv_aud_decode_init(AVCodecContext *avctx)
 {
-    BMVAudioDecContext *c = avctx->priv_data;
-
     avctx->channels       = 2;
     avctx->channel_layout = AV_CH_LAYOUT_STEREO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
 static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame_ptr, AVPacket *avpkt)
 {
-    BMVAudioDecContext *c = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     int blocks = 0, total_blocks, i;
@@ -336,12 +312,12 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    c->frame.nb_samples = total_blocks * 32;
-    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = total_blocks * 32;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output_samples = (int16_t *)c->frame.data[0];
+    output_samples = (int16_t *)frame->data[0];
 
     for (blocks = 0; blocks < total_blocks; blocks++) {
         uint8_t code = *buf++;
@@ -354,31 +330,28 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
 
 AVCodec ff_bmv_video_decoder = {
     .name           = "bmv_video",
+    .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_BMV_VIDEO,
     .priv_data_size = sizeof(BMVDecContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
 };
 
 AVCodec ff_bmv_audio_decoder = {
     .name           = "bmv_audio",
+    .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV audio"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_BMV_AUDIO,
-    .priv_data_size = sizeof(BMVAudioDecContext),
     .init           = bmv_aud_decode_init,
     .decode         = bmv_aud_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV audio"),
 };
diff --git a/libavcodec/c93.c b/libavcodec/c93.c
index b820f5a..c7cc682 100644
--- a/libavcodec/c93.c
+++ b/libavcodec/c93.c
@@ -21,9 +21,10 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct {
-    AVFrame pictures[2];
+    AVFrame *pictures[2];
     int currentpic;
 } C93DecoderContext;
 
@@ -45,20 +46,28 @@ typedef enum {
 #define C93_HAS_PALETTE 0x01
 #define C93_FIRST_FRAME 0x02
 
-static av_cold int decode_init(AVCodecContext *avctx)
+static av_cold int decode_end(AVCodecContext *avctx)
 {
-    avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    C93DecoderContext * const c93 = avctx->priv_data;
+
+    av_frame_free(&c93->pictures[0]);
+    av_frame_free(&c93->pictures[1]);
+
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
+static av_cold int decode_init(AVCodecContext *avctx)
 {
-    C93DecoderContext * const c93 = avctx->priv_data;
+    C93DecoderContext *s = avctx->priv_data;
+    avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+    s->pictures[0] = av_frame_alloc();
+    s->pictures[1] = av_frame_alloc();
+    if (!s->pictures[0] || !s->pictures[1]) {
+        decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
-    if (c93->pictures[0].data[0])
-        avctx->release_buffer(avctx, &c93->pictures[0]);
-    if (c93->pictures[1].data[0])
-        avctx->release_buffer(avctx, &c93->pictures[1]);
     return 0;
 }
 
@@ -79,7 +88,7 @@ static inline int copy_block(AVCodecContext *avctx, uint8_t *to,
     if (from_y + height > HEIGHT) {
         av_log(avctx, AV_LOG_ERROR, "invalid offset %d during C93 decoding\n",
                offset);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (overflow > 0) {
@@ -118,21 +127,17 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     C93DecoderContext * const c93 = avctx->priv_data;
-    AVFrame * const newpic = &c93->pictures[c93->currentpic];
-    AVFrame * const oldpic = &c93->pictures[c93->currentpic^1];
-    AVFrame *picture = data;
+    AVFrame * const newpic = c93->pictures[c93->currentpic];
+    AVFrame * const oldpic = c93->pictures[c93->currentpic^1];
     GetByteContext gb;
     uint8_t *out;
-    int stride, i, x, y, b, bt = 0;
+    int stride, ret, i, x, y, b, bt = 0;
 
     c93->currentpic ^= 1;
 
-    newpic->reference = 1;
-    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)) {
+    if ((ret = ff_reget_buffer(avctx, newpic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     stride = newpic->linesize[0];
@@ -162,8 +167,8 @@ static int decode_frame(AVCodecContext *avctx, void *data,
             switch (block_type) {
             case C93_8X8_FROM_PREV:
                 offset = bytestream2_get_le16(&gb);
-                if (copy_block(avctx, out, copy_from, offset, 8, stride))
-                    return -1;
+                if ((ret = copy_block(avctx, out, copy_from, offset, 8, stride)) < 0)
+                    return ret;
                 break;
 
             case C93_4X4_FROM_CURR:
@@ -172,9 +177,9 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                 for (j = 0; j < 8; j += 4) {
                     for (i = 0; i < 8; i += 4) {
                         offset = bytestream2_get_le16(&gb);
-                        if (copy_block(avctx, &out[j*stride+i],
-                                           copy_from, offset, 4, stride))
-                            return -1;
+                        if ((ret = copy_block(avctx, &out[j*stride+i],
+                                              copy_from, offset, 4, stride)) < 0)
+                            return ret;
                     }
                 }
                 break;
@@ -221,7 +226,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
             default:
                 av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n",
                        block_type, x, y);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             bt >>= 4;
             out += 8;
@@ -239,7 +244,8 @@ static int decode_frame(AVCodecContext *avctx, void *data,
             memcpy(newpic->data[1], oldpic->data[1], 256 * 4);
     }
 
-    *picture = *newpic;
+    if ((ret = av_frame_ref(data, newpic)) < 0)
+        return ret;
     *got_frame = 1;
 
     return buf_size;
@@ -247,6 +253,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 
 AVCodec ff_c93_decoder = {
     .name           = "c93",
+    .long_name      = NULL_IF_CONFIG_SMALL("Interplay C93"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_C93,
     .priv_data_size = sizeof(C93DecoderContext),
@@ -254,5 +261,4 @@ AVCodec ff_c93_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Interplay C93"),
 };
diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c
index 02d2911..e1cd811 100644
--- a/libavcodec/cabac.c
+++ b/libavcodec/cabac.c
@@ -73,8 +73,6 @@ static const uint8_t lps_range[64][4]= {
 {  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 const uint8_t mps_state[64]= {
   1, 2, 3, 4, 5, 6, 7, 8,
   9,10,11,12,13,14,15,16,
@@ -136,8 +134,13 @@ void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
     c->range= 0x1FE;
 }
 
-void ff_init_cabac_states(CABACContext *c){
+void ff_init_cabac_states(void)
+{
     int i, j;
+    static int initialized = 0;
+
+    if (initialized)
+        return;
 
     for(i=0; i<64; i++){
         for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save
@@ -145,10 +148,8 @@ void ff_init_cabac_states(CABACContext *c){
             ff_h264_lps_range[j*2*64+2*i+1]= lps_range[i][j];
         }
 
-        ff_h264_mlps_state[128+2*i+0]=
-        h264_mps_state[2 * i + 0] = 2 * mps_state[i] + 0;
-        ff_h264_mlps_state[128+2*i+1]=
-        h264_mps_state[2 * i + 1] = 2 * mps_state[i] + 1;
+        ff_h264_mlps_state[128 + 2 * i + 0] = 2 * mps_state[i] + 0;
+        ff_h264_mlps_state[128 + 2 * i + 1] = 2 * mps_state[i] + 1;
 
         if( i ){
             ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0;
@@ -161,4 +162,6 @@ void ff_init_cabac_states(CABACContext *c){
     for(i=0; i< 63; i++){
       ff_h264_last_coeff_flag_offset_8x8[i] = last_coeff_flag_offset_8x8[i];
     }
+
+    initialized = 1;
 }
diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h
index 1f1c943..04495a6 100644
--- a/libavcodec/cabac.h
+++ b/libavcodec/cabac.h
@@ -51,6 +51,6 @@ typedef struct CABACContext{
 
 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..11c9646 100644
--- a/libavcodec/cabac_functions.h
+++ b/libavcodec/cabac_functions.h
@@ -113,6 +113,7 @@ static int av_unused get_cabac(CABACContext *c, uint8_t * const state){
     return get_cabac_inline(c,state);
 }
 
+#ifndef get_cabac_bypass
 static int av_unused get_cabac_bypass(CABACContext *c){
     int range;
     c->low += c->low;
@@ -128,7 +129,7 @@ static int av_unused get_cabac_bypass(CABACContext *c){
         return 1;
     }
 }
-
+#endif
 
 #ifndef get_cabac_bypass_sign
 static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
@@ -161,4 +162,24 @@ static int av_unused get_cabac_terminate(CABACContext *c){
     }
 }
 
+/**
+ * Skip @p n bytes and reset the decoder.
+ * @return the address of the first skipped byte or NULL if there's less than @p n bytes left
+ */
+static av_unused const uint8_t* skip_bytes(CABACContext *c, int n) {
+    const uint8_t *ptr = c->bytestream;
+
+    if (c->low & 0x1)
+        ptr--;
+#if CABAC_BITS == 16
+    if (c->low & 0x1FF)
+        ptr--;
+#endif
+    if ((int) (c->bytestream_end - ptr) < n)
+        return NULL;
+    ff_init_cabac_decoder(c, ptr + n, c->bytestream_end - ptr - n);
+
+    return ptr;
+}
+
 #endif /* AVCODEC_CABAC_FUNCTIONS_H */
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c
index f9b876f..5a81089 100644
--- a/libavcodec/cavs.c
+++ b/libavcodec/cavs.c
@@ -28,32 +28,33 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "golomb.h"
+#include "h264chroma.h"
 #include "mathops.h"
 #include "cavs.h"
 
 static const uint8_t alpha_tab[64] = {
-   0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  3,  3,
-   4,  4,  5,  5,  6,  7,  8,  9, 10, 11, 12, 13, 15, 16, 18, 20,
-  22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
-  46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
+     0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  3,  3,
+     4,  4,  5,  5,  6,  7,  8,  9, 10, 11, 12, 13, 15, 16, 18, 20,
+    22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
+    46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
 };
 
 static const uint8_t beta_tab[64] = {
-   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,  4,  5,  5,  5,  5,  6,  6,
-   6,  7,  7,  7,  8,  8,  8,  9,  9, 10, 10, 11, 11, 12, 13, 14,
-  15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
+     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,  4,  5,  5,  5,  5,  6,  6,
+     6,  7,  7,  7,  8,  8,  8,  9,  9, 10, 10, 11, 11, 12, 13, 14,
+    15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
 };
 
 static const uint8_t tc_tab[64] = {
-  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, 2, 2,
-  2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
-  5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
+    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, 2, 2,
+    2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
+    5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
 };
 
 /** mark block as unavailable, i.e. out of picture
-    or not yet decoded */
+ *  or not yet decoded */
 static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
 
 static const int8_t left_modifier_l[8] = {  0, -1,  6, -1, -1, 7, 6, 7 };
@@ -76,7 +77,7 @@ static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b)
     if (b) {
         mvP += MV_BWD_OFFS;
         mvQ += MV_BWD_OFFS;
-        if ((abs(mvP->x - mvQ->x) >= 4) ||  (abs(mvP->y - mvQ->y) >= 4))
+        if ((abs(mvP->x - mvQ->x) >= 4) || (abs(mvP->y - mvQ->y) >= 4))
             return 1;
     } else {
         if (mvP->ref != mvQ->ref)
@@ -125,7 +126,7 @@ void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type)
         /* determine bs */
         if (mb_type == I_8X8)
             memset(bs, 2, 8);
-        else{
+        else {
             memset(bs, 0, 8);
             if (ff_cavs_partition_flags[mb_type] & SPLITV) {
                 bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8);
@@ -228,31 +229,30 @@ void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top,
 void ff_cavs_load_intra_pred_chroma(AVSContext *h)
 {
     /* extend borders by one pixel */
-    h->left_border_u[9] = h->left_border_u[8];
-    h->left_border_v[9] = h->left_border_v[8];
+    h->left_border_u[9]              = h->left_border_u[8];
+    h->left_border_v[9]              = h->left_border_v[8];
     h->top_border_u[h->mbx * 10 + 9] = h->top_border_u[h->mbx * 10 + 8];
     h->top_border_v[h->mbx * 10 + 9] = h->top_border_v[h->mbx * 10 + 8];
     if (h->mbx && h->mby) {
         h->top_border_u[h->mbx * 10] = h->left_border_u[0] = h->topleft_border_u;
         h->top_border_v[h->mbx * 10] = h->left_border_v[0] = h->topleft_border_v;
     } else {
-        h->left_border_u[0] = h->left_border_u[1];
-        h->left_border_v[0] = h->left_border_v[1];
+        h->left_border_u[0]          = h->left_border_u[1];
+        h->left_border_v[0]          = h->left_border_v[1];
         h->top_border_u[h->mbx * 10] = h->top_border_u[h->mbx * 10 + 1];
         h->top_border_v[h->mbx * 10] = h->top_border_v[h->mbx * 10 + 1];
     }
 }
 
-static void intra_pred_vert(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int y;
     uint64_t a = AV_RN64(&top[1]);
-    for (y = 0; y < 8; y++) {
+    for (y = 0; y < 8; y++)
         *((uint64_t *)(d + y * stride)) = a;
-    }
 }
 
-static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int y;
     uint64_t a;
@@ -262,7 +262,7 @@ static void intra_pred_horiz(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
     }
 }
 
-static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int y;
     uint64_t a = 0x8080808080808080ULL;
@@ -270,15 +270,15 @@ static void intra_pred_dc_128(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
         *((uint64_t *)(d + y * stride)) = a;
 }
 
-static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int x, y, ia;
     int ih = 0;
     int iv = 0;
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
 
     for (x = 0; x < 4; x++) {
-        ih += (x + 1) * (top [5 + x] - top [3 - x]);
+        ih += (x + 1) *  (top[5 + x] -  top[3 - x]);
         iv += (x + 1) * (left[5 + x] - left[3 - x]);
     }
     ia = (top[8] + left[8]) << 4;
@@ -289,10 +289,10 @@ static void intra_pred_plane(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
             d[y * stride + x] = cm[(ia + (x - 3) * ih + (y - 3) * iv + 16) >> 5];
 }
 
-#define LOWPASS(ARRAY,INDEX)                                            \
+#define LOWPASS(ARRAY, INDEX)                                           \
     ((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2)
 
-static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int x, y;
     for (y = 0; y < 8; y++)
@@ -300,7 +300,7 @@ static void intra_pred_lp(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
             d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1;
 }
 
-static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int x, y;
     for (y = 0; y < 8; y++)
@@ -308,7 +308,7 @@ static void intra_pred_down_left(uint8_t *d,uint8_t *top,uint8_t *left,int strid
             d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1;
 }
 
-static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int x, y;
     for (y = 0; y < 8; y++)
@@ -321,7 +321,7 @@ static void intra_pred_down_right(uint8_t *d,uint8_t *top,uint8_t *left,int stri
                 d[y * stride + x] = LOWPASS(left, y - x);
 }
 
-static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int x, y;
     for (y = 0; y < 8; y++)
@@ -329,7 +329,7 @@ static void intra_pred_lp_left(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
             d[y * stride + x] = LOWPASS(left, y + 1);
 }
 
-static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
+static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
 {
     int x, y;
     for (y = 0; y < 8; y++)
@@ -351,8 +351,8 @@ static inline void modify_pred(const int8_t *mod_table, int *mode)
 void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
 {
     /* save pred modes before they get modified */
-    h->pred_mode_Y[3] =  h->pred_mode_Y[5];
-    h->pred_mode_Y[6] =  h->pred_mode_Y[8];
+    h->pred_mode_Y[3]             = h->pred_mode_Y[5];
+    h->pred_mode_Y[6]             = h->pred_mode_Y[8];
     h->top_pred_Y[h->mbx * 2 + 0] = h->pred_mode_Y[7];
     h->top_pred_Y[h->mbx * 2 + 1] = h->pred_mode_Y[8];
 
@@ -375,119 +375,144 @@ void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
  *
  ****************************************************************************/
 
-static inline void mc_dir_part(AVSContext *h, AVFrame *pic,
-                               int chroma_height,int delta,int list,uint8_t *dest_y,
-                               uint8_t *dest_cb,uint8_t *dest_cr,int src_x_offset,
-                               int src_y_offset,qpel_mc_func *qpix_op,
-                               h264_chroma_mc_func chroma_op,cavs_vector *mv)
+static inline void mc_dir_part(AVSContext *h, AVFrame *pic, int chroma_height,
+                               int delta, int list, uint8_t *dest_y,
+                               uint8_t *dest_cb, uint8_t *dest_cr,
+                               int src_x_offset, int src_y_offset,
+                               qpel_mc_func *qpix_op,
+                               h264_chroma_mc_func chroma_op, cavs_vector *mv)
 {
-    const int mx= mv->x + src_x_offset*8;
-    const int my= mv->y + src_y_offset*8;
-    const int luma_xy= (mx&3) + ((my&3)<<2);
-    uint8_t * src_y  = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
-    uint8_t * src_cb = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
-    uint8_t * src_cr = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
-    int extra_width = 0;
-    int extra_height= extra_width;
-    int emu=0;
-    const int full_mx= mx>>2;
-    const int full_my= my>>2;
-    const int pic_width  = 16*h->mb_width;
-    const int pic_height = 16*h->mb_height;
+    const int mx         = mv->x + src_x_offset * 8;
+    const int my         = mv->y + src_y_offset * 8;
+    const int luma_xy    = (mx & 3) + ((my & 3) << 2);
+    uint8_t *src_y       = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
+    uint8_t *src_cb      = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
+    uint8_t *src_cr      = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
+    int extra_width      = 0;
+    int extra_height     = extra_width;
+    const int full_mx    = mx >> 2;
+    const int full_my    = my >> 2;
+    const int pic_width  = 16 * h->mb_width;
+    const int pic_height = 16 * h->mb_height;
+    int emu = 0;
 
     if (!pic->data[0])
         return;
-    if(mx&7) extra_width -= 3;
-    if(my&7) extra_height -= 3;
-
-    if(   full_mx < 0-extra_width
-          || full_my < 0-extra_height
-          || full_mx + 16/*FIXME*/ > pic_width + extra_width
-          || full_my + 16/*FIXME*/ > pic_height + extra_height){
-        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_y - 2 - 2*h->l_stride, h->l_stride,
-                            16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);
-        src_y= h->edge_emu_buffer + 2 + 2*h->l_stride;
-        emu=1;
+    if (mx & 7)
+        extra_width  -= 3;
+    if (my & 7)
+        extra_height -= 3;
+
+    if (full_mx < 0 - extra_width ||
+        full_my < 0 - extra_height ||
+        full_mx + 16 /* FIXME */ > pic_width + extra_width ||
+        full_my + 16 /* FIXME */ > pic_height + extra_height) {
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
+                                 src_y - 2 - 2 * h->l_stride,
+                                 h->l_stride, h->l_stride,
+                                 16 + 5, 16 + 5 /* FIXME */,
+                                 full_mx - 2, full_my - 2,
+                                 pic_width, pic_height);
+        src_y = h->edge_emu_buffer + 2 + 2 * h->l_stride;
+        emu   = 1;
     }
 
-    qpix_op[luma_xy](dest_y, src_y, h->l_stride); //FIXME try variable height perhaps?
+    // FIXME try variable height perhaps?
+    qpix_op[luma_xy](dest_y, src_y, h->l_stride);
 
-    if(emu){
-        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->c_stride,
-                            9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
-        src_cb= h->edge_emu_buffer;
+    if (emu) {
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb,
+                                 h->c_stride, h->c_stride,
+                                 9, 9 /* FIXME */,
+                                 mx >> 3, my >> 3,
+                                 pic_width >> 1, pic_height >> 1);
+        src_cb = h->edge_emu_buffer;
     }
-    chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx&7, my&7);
-
-    if(emu){
-        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->c_stride,
-                            9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
-        src_cr= h->edge_emu_buffer;
+    chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx & 7, my & 7);
+
+    if (emu) {
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr,
+                                 h->c_stride, h->c_stride,
+                                 9, 9 /* FIXME */,
+                                 mx >> 3, my >> 3,
+                                 pic_width >> 1, pic_height >> 1);
+        src_cr = h->edge_emu_buffer;
     }
-    chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx&7, my&7);
+    chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx & 7, my & 7);
 }
 
-static inline void mc_part_std(AVSContext *h,int chroma_height,int delta,
-                               uint8_t *dest_y,uint8_t *dest_cb,uint8_t *dest_cr,
-                               int x_offset, int y_offset,qpel_mc_func *qpix_put,
-                               h264_chroma_mc_func chroma_put,qpel_mc_func *qpix_avg,
-                               h264_chroma_mc_func chroma_avg, cavs_vector *mv)
+static inline void mc_part_std(AVSContext *h, int chroma_height, int delta,
+                               uint8_t *dest_y,
+                               uint8_t *dest_cb,
+                               uint8_t *dest_cr,
+                               int x_offset, int y_offset,
+                               qpel_mc_func *qpix_put,
+                               h264_chroma_mc_func chroma_put,
+                               qpel_mc_func *qpix_avg,
+                               h264_chroma_mc_func chroma_avg,
+                               cavs_vector *mv)
 {
-    qpel_mc_func *qpix_op=  qpix_put;
-    h264_chroma_mc_func chroma_op= chroma_put;
+    qpel_mc_func *qpix_op =  qpix_put;
+    h264_chroma_mc_func chroma_op = chroma_put;
 
-    dest_y  += 2*x_offset + 2*y_offset*h->l_stride;
-    dest_cb +=   x_offset +   y_offset*h->c_stride;
-    dest_cr +=   x_offset +   y_offset*h->c_stride;
-    x_offset += 8*h->mbx;
-    y_offset += 8*h->mby;
+    dest_y   += x_offset * 2 + y_offset * h->l_stride * 2;
+    dest_cb  += x_offset     + y_offset * h->c_stride;
+    dest_cr  += x_offset     + y_offset * h->c_stride;
+    x_offset += 8 * h->mbx;
+    y_offset += 8 * h->mby;
 
-    if(mv->ref >= 0){
+    if (mv->ref >= 0) {
         AVFrame *ref = h->DPB[mv->ref].f;
         mc_dir_part(h, ref, chroma_height, delta, 0,
                     dest_y, dest_cb, dest_cr, x_offset, y_offset,
                     qpix_op, chroma_op, mv);
 
-        qpix_op=  qpix_avg;
-        chroma_op= chroma_avg;
+        qpix_op   = qpix_avg;
+        chroma_op = chroma_avg;
     }
 
-    if((mv+MV_BWD_OFFS)->ref >= 0){
+    if ((mv + MV_BWD_OFFS)->ref >= 0) {
         AVFrame *ref = h->DPB[0].f;
         mc_dir_part(h, ref, chroma_height, delta, 1,
                     dest_y, dest_cb, dest_cr, x_offset, y_offset,
-                    qpix_op, chroma_op, mv+MV_BWD_OFFS);
+                    qpix_op, chroma_op, mv + MV_BWD_OFFS);
     }
 }
 
-void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type) {
-    if(ff_cavs_partition_flags[mb_type] == 0){ // 16x16
+void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type)
+{
+    if (ff_cavs_partition_flags[mb_type] == 0) { // 16x16
         mc_part_std(h, 8, 0, h->cy, h->cu, h->cv, 0, 0,
-                h->cdsp.put_cavs_qpel_pixels_tab[0],
-                h->dsp.put_h264_chroma_pixels_tab[0],
-                h->cdsp.avg_cavs_qpel_pixels_tab[0],
-                h->dsp.avg_h264_chroma_pixels_tab[0],&h->mv[MV_FWD_X0]);
-    }else{
+                    h->cdsp.put_cavs_qpel_pixels_tab[0],
+                    h->h264chroma.put_h264_chroma_pixels_tab[0],
+                    h->cdsp.avg_cavs_qpel_pixels_tab[0],
+                    h->h264chroma.avg_h264_chroma_pixels_tab[0],
+                    &h->mv[MV_FWD_X0]);
+    } else {
         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 0,
-                h->cdsp.put_cavs_qpel_pixels_tab[1],
-                h->dsp.put_h264_chroma_pixels_tab[1],
-                h->cdsp.avg_cavs_qpel_pixels_tab[1],
-                h->dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X0]);
+                    h->cdsp.put_cavs_qpel_pixels_tab[1],
+                    h->h264chroma.put_h264_chroma_pixels_tab[1],
+                    h->cdsp.avg_cavs_qpel_pixels_tab[1],
+                    h->h264chroma.avg_h264_chroma_pixels_tab[1],
+                    &h->mv[MV_FWD_X0]);
         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 0,
-                h->cdsp.put_cavs_qpel_pixels_tab[1],
-                h->dsp.put_h264_chroma_pixels_tab[1],
-                h->cdsp.avg_cavs_qpel_pixels_tab[1],
-                h->dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X1]);
+                    h->cdsp.put_cavs_qpel_pixels_tab[1],
+                    h->h264chroma.put_h264_chroma_pixels_tab[1],
+                    h->cdsp.avg_cavs_qpel_pixels_tab[1],
+                    h->h264chroma.avg_h264_chroma_pixels_tab[1],
+                    &h->mv[MV_FWD_X1]);
         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 4,
-                h->cdsp.put_cavs_qpel_pixels_tab[1],
-                h->dsp.put_h264_chroma_pixels_tab[1],
-                h->cdsp.avg_cavs_qpel_pixels_tab[1],
-                h->dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X2]);
+                    h->cdsp.put_cavs_qpel_pixels_tab[1],
+                    h->h264chroma.put_h264_chroma_pixels_tab[1],
+                    h->cdsp.avg_cavs_qpel_pixels_tab[1],
+                    h->h264chroma.avg_h264_chroma_pixels_tab[1],
+                    &h->mv[MV_FWD_X2]);
         mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 4,
-                h->cdsp.put_cavs_qpel_pixels_tab[1],
-                h->dsp.put_h264_chroma_pixels_tab[1],
-                h->cdsp.avg_cavs_qpel_pixels_tab[1],
-                h->dsp.avg_h264_chroma_pixels_tab[1],&h->mv[MV_FWD_X3]);
+                    h->cdsp.put_cavs_qpel_pixels_tab[1],
+                    h->h264chroma.put_h264_chroma_pixels_tab[1],
+                    h->cdsp.avg_cavs_qpel_pixels_tab[1],
+                    h->h264chroma.avg_h264_chroma_pixels_tab[1],
+                    &h->mv[MV_FWD_X3]);
     }
 }
 
@@ -497,15 +522,21 @@ void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type) {
  *
  ****************************************************************************/
 
-static inline void scale_mv(AVSContext *h, int *d_x, int *d_y, cavs_vector *src, int distp) {
+static inline void scale_mv(AVSContext *h, int *d_x, int *d_y,
+                            cavs_vector *src, int distp)
+{
     int den = h->scale_den[src->ref];
 
-    *d_x = (src->x*distp*den + 256 + (src->x>>31)) >> 9;
-    *d_y = (src->y*distp*den + 256 + (src->y>>31)) >> 9;
+    *d_x = (src->x * distp * den + 256 + (src->x >> 31)) >> 9;
+    *d_y = (src->y * distp * den + 256 + (src->y >> 31)) >> 9;
 }
 
-static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP,
-                        cavs_vector *mvA, cavs_vector *mvB, cavs_vector *mvC) {
+static inline void mv_pred_median(AVSContext *h,
+                                  cavs_vector *mvP,
+                                  cavs_vector *mvA,
+                                  cavs_vector *mvB,
+                                  cavs_vector *mvC)
+{
     int ax, ay, bx, by, cx, cy;
     int len_ab, len_bc, len_ca, len_mid;
 
@@ -514,14 +545,14 @@ static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP,
     scale_mv(h, &bx, &by, mvB, mvP->dist);
     scale_mv(h, &cx, &cy, mvC, mvP->dist);
     /* find the geometrical median of the three candidates */
-    len_ab = abs(ax - bx) + abs(ay - by);
-    len_bc = abs(bx - cx) + abs(by - cy);
-    len_ca = abs(cx - ax) + abs(cy - ay);
+    len_ab  = abs(ax - bx) + abs(ay - by);
+    len_bc  = abs(bx - cx) + abs(by - cy);
+    len_ca  = abs(cx - ax) + abs(cy - ay);
     len_mid = mid_pred(len_ab, len_bc, len_ca);
-    if(len_mid == len_ab) {
+    if (len_mid == len_ab) {
         mvP->x = cx;
         mvP->y = cy;
-    } else if(len_mid == len_bc) {
+    } else if (len_mid == len_bc) {
         mvP->x = ax;
         mvP->y = ay;
     } else {
@@ -531,47 +562,49 @@ static inline void mv_pred_median(AVSContext *h, cavs_vector *mvP,
 }
 
 void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC,
-                enum cavs_mv_pred mode, enum cavs_block size, int ref) {
+                enum cavs_mv_pred mode, enum cavs_block size, int ref)
+{
     cavs_vector *mvP = &h->mv[nP];
     cavs_vector *mvA = &h->mv[nP-1];
     cavs_vector *mvB = &h->mv[nP-4];
     cavs_vector *mvC = &h->mv[nC];
     const cavs_vector *mvP2 = NULL;
 
-    mvP->ref = ref;
+    mvP->ref  = ref;
     mvP->dist = h->dist[mvP->ref];
-    if(mvC->ref == NOT_AVAIL)
-        mvC = &h->mv[nP-5]; // set to top-left (mvD)
-    if((mode == MV_PRED_PSKIP) &&
-       ((mvA->ref == NOT_AVAIL) || (mvB->ref == NOT_AVAIL) ||
-           ((mvA->x | mvA->y | mvA->ref) == 0)  ||
-           ((mvB->x | mvB->y | mvB->ref) == 0) )) {
+    if (mvC->ref == NOT_AVAIL)
+        mvC = &h->mv[nP - 5];  // set to top-left (mvD)
+    if (mode == MV_PRED_PSKIP &&
+        (mvA->ref == NOT_AVAIL ||
+         mvB->ref == NOT_AVAIL ||
+         (mvA->x | mvA->y | mvA->ref) == 0 ||
+         (mvB->x | mvB->y | mvB->ref) == 0)) {
         mvP2 = &un_mv;
     /* if there is only one suitable candidate, take it */
-    } else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) {
-        mvP2= mvA;
-    } else if((mvA->ref < 0) && (mvB->ref >= 0) && (mvC->ref < 0)) {
-        mvP2= mvB;
-    } else if((mvA->ref < 0) && (mvB->ref < 0) && (mvC->ref >= 0)) {
-        mvP2= mvC;
-    } else if(mode == MV_PRED_LEFT     && mvA->ref == ref){
-        mvP2= mvA;
-    } else if(mode == MV_PRED_TOP      && mvB->ref == ref){
-        mvP2= mvB;
-    } else if(mode == MV_PRED_TOPRIGHT && mvC->ref == ref){
-        mvP2= mvC;
+    } else if (mvA->ref >= 0 && mvB->ref < 0  && mvC->ref < 0) {
+        mvP2 = mvA;
+    } else if (mvA->ref < 0  && mvB->ref >= 0 && mvC->ref < 0) {
+        mvP2 = mvB;
+    } else if (mvA->ref < 0  && mvB->ref < 0  && mvC->ref >= 0) {
+        mvP2 = mvC;
+    } else if (mode == MV_PRED_LEFT     && mvA->ref == ref) {
+        mvP2 = mvA;
+    } else if (mode == MV_PRED_TOP      && mvB->ref == ref) {
+        mvP2 = mvB;
+    } else if (mode == MV_PRED_TOPRIGHT && mvC->ref == ref) {
+        mvP2 = mvC;
     }
-    if(mvP2){
+    if (mvP2) {
         mvP->x = mvP2->x;
         mvP->y = mvP2->y;
-    }else
+    } else
         mv_pred_median(h, mvP, mvA, mvB, mvC);
 
-    if(mode < MV_PRED_PSKIP) {
+    if (mode < MV_PRED_PSKIP) {
         mvP->x += get_se_golomb(&h->gb);
         mvP->y += get_se_golomb(&h->gb);
     }
-    set_mvs(mvP,size);
+    set_mvs(mvP, size);
 }
 
 /*****************************************************************************
@@ -583,36 +616,37 @@ void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC,
 /**
  * initialise predictors for motion vectors and intra prediction
  */
-void ff_cavs_init_mb(AVSContext *h) {
+void ff_cavs_init_mb(AVSContext *h)
+{
     int i;
 
     /* copy predictors from top line (MB B and C) into cache */
-    for(i=0;i<3;i++) {
-        h->mv[MV_FWD_B2+i] = h->top_mv[0][h->mbx*2+i];
-        h->mv[MV_BWD_B2+i] = h->top_mv[1][h->mbx*2+i];
+    for (i = 0; i < 3; i++) {
+        h->mv[MV_FWD_B2 + i] = h->top_mv[0][h->mbx * 2 + i];
+        h->mv[MV_BWD_B2 + i] = h->top_mv[1][h->mbx * 2 + i];
     }
-    h->pred_mode_Y[1] = h->top_pred_Y[h->mbx*2+0];
-    h->pred_mode_Y[2] = h->top_pred_Y[h->mbx*2+1];
+    h->pred_mode_Y[1] = h->top_pred_Y[h->mbx * 2 + 0];
+    h->pred_mode_Y[2] = h->top_pred_Y[h->mbx * 2 + 1];
     /* clear top predictors if MB B is not available */
-    if(!(h->flags & B_AVAIL)) {
-        h->mv[MV_FWD_B2] = un_mv;
-        h->mv[MV_FWD_B3] = un_mv;
-        h->mv[MV_BWD_B2] = un_mv;
-        h->mv[MV_BWD_B3] = un_mv;
+    if (!(h->flags & B_AVAIL)) {
+        h->mv[MV_FWD_B2]  = un_mv;
+        h->mv[MV_FWD_B3]  = un_mv;
+        h->mv[MV_BWD_B2]  = un_mv;
+        h->mv[MV_BWD_B3]  = un_mv;
         h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL;
-        h->flags &= ~(C_AVAIL|D_AVAIL);
-    } else if(h->mbx) {
+        h->flags         &= ~(C_AVAIL | D_AVAIL);
+    } else if (h->mbx) {
         h->flags |= D_AVAIL;
     }
-    if(h->mbx == h->mb_width-1) //MB C not available
+    if (h->mbx == h->mb_width - 1) // MB C not available
         h->flags &= ~C_AVAIL;
     /* clear top-right predictors if MB C is not available */
-    if(!(h->flags & C_AVAIL)) {
+    if (!(h->flags & C_AVAIL)) {
         h->mv[MV_FWD_C2] = un_mv;
         h->mv[MV_BWD_C2] = un_mv;
     }
     /* clear top-left predictors if MB D is not available */
-    if(!(h->flags & D_AVAIL)) {
+    if (!(h->flags & D_AVAIL)) {
         h->mv[MV_FWD_D3] = un_mv;
         h->mv[MV_BWD_D3] = un_mv;
     }
@@ -623,38 +657,39 @@ void ff_cavs_init_mb(AVSContext *h) {
  * macroblock address
  * @return 0 if end of frame is reached, 1 otherwise
  */
-int ff_cavs_next_mb(AVSContext *h) {
+int ff_cavs_next_mb(AVSContext *h)
+{
     int i;
 
     h->flags |= A_AVAIL;
-    h->cy += 16;
-    h->cu += 8;
-    h->cv += 8;
+    h->cy    += 16;
+    h->cu    += 8;
+    h->cv    += 8;
     /* copy mvs as predictors to the left */
-    for(i=0;i<=20;i+=4)
-        h->mv[i] = h->mv[i+2];
+    for (i = 0; i <= 20; i += 4)
+        h->mv[i] = h->mv[i + 2];
     /* copy bottom mvs from cache to top line */
-    h->top_mv[0][h->mbx*2+0] = h->mv[MV_FWD_X2];
-    h->top_mv[0][h->mbx*2+1] = h->mv[MV_FWD_X3];
-    h->top_mv[1][h->mbx*2+0] = h->mv[MV_BWD_X2];
-    h->top_mv[1][h->mbx*2+1] = h->mv[MV_BWD_X3];
+    h->top_mv[0][h->mbx * 2 + 0] = h->mv[MV_FWD_X2];
+    h->top_mv[0][h->mbx * 2 + 1] = h->mv[MV_FWD_X3];
+    h->top_mv[1][h->mbx * 2 + 0] = h->mv[MV_BWD_X2];
+    h->top_mv[1][h->mbx * 2 + 1] = h->mv[MV_BWD_X3];
     /* next MB address */
     h->mbidx++;
     h->mbx++;
-    if(h->mbx == h->mb_width) { //new mb line
-        h->flags = B_AVAIL|C_AVAIL;
+    if (h->mbx == h->mb_width) { // New mb line
+        h->flags = B_AVAIL | C_AVAIL;
         /* clear left pred_modes */
         h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
         /* clear left mv predictors */
-        for(i=0;i<=20;i+=4)
+        for (i = 0; i <= 20; i += 4)
             h->mv[i] = un_mv;
         h->mbx = 0;
         h->mby++;
         /* re-calculate sample pointers */
         h->cy = h->cur.f->data[0] + h->mby * 16 * h->l_stride;
-        h->cu = h->cur.f->data[1] + h->mby *  8 * h->c_stride;
-        h->cv = h->cur.f->data[2] + h->mby *  8 * h->c_stride;
-        if(h->mby == h->mb_height) { //frame end
+        h->cu = h->cur.f->data[1] + h->mby * 8 * h->c_stride;
+        h->cv = h->cur.f->data[2] + h->mby * 8 * h->c_stride;
+        if (h->mby == h->mb_height) { // Frame end
             return 0;
         }
     }
@@ -667,26 +702,27 @@ int ff_cavs_next_mb(AVSContext *h) {
  *
  ****************************************************************************/
 
-void ff_cavs_init_pic(AVSContext *h) {
+void ff_cavs_init_pic(AVSContext *h)
+{
     int i;
 
     /* clear some predictors */
-    for(i=0;i<=20;i+=4)
+    for (i = 0; i <= 20; i += 4)
         h->mv[i] = un_mv;
     h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
     set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
     h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
     set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
     h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
-    h->cy           = h->cur.f->data[0];
-    h->cu           = h->cur.f->data[1];
-    h->cv           = h->cur.f->data[2];
-    h->l_stride     = h->cur.f->linesize[0];
-    h->c_stride     = h->cur.f->linesize[1];
-    h->luma_scan[2] = 8*h->l_stride;
-    h->luma_scan[3] = 8*h->l_stride+8;
-    h->mbx = h->mby = h->mbidx = 0;
-    h->flags = 0;
+    h->cy             = h->cur.f->data[0];
+    h->cu             = h->cur.f->data[1];
+    h->cv             = h->cur.f->data[2];
+    h->l_stride       = h->cur.f->linesize[0];
+    h->c_stride       = h->cur.f->linesize[1];
+    h->luma_scan[2]   = 8 * h->l_stride;
+    h->luma_scan[3]   = 8 * h->l_stride + 8;
+    h->mbx            = h->mby = h->mbidx = 0;
+    h->flags          = 0;
 }
 
 /*****************************************************************************
@@ -700,77 +736,76 @@ void ff_cavs_init_pic(AVSContext *h) {
  * this data has to be stored for one complete row of macroblocks
  * and this storage space is allocated here
  */
-void ff_cavs_init_top_lines(AVSContext *h) {
+void ff_cavs_init_top_lines(AVSContext *h)
+{
     /* alloc top line of predictors */
-    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);
+    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_mallocz( h->mb_width*h->mb_height*4*sizeof(cavs_vector));
-    h->col_type_base = av_mallocz(h->mb_width*h->mb_height);
-    h->block        = av_mallocz(64*sizeof(DCTELEM));
+    h->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(int16_t));
 }
 
-av_cold int ff_cavs_init(AVCodecContext *avctx) {
+av_cold int ff_cavs_init(AVCodecContext *avctx)
+{
     AVSContext *h = avctx->priv_data;
 
     ff_dsputil_init(&h->dsp, avctx);
+    ff_h264chroma_init(&h->h264chroma, 8);
     ff_videodsp_init(&h->vdsp, 8);
     ff_cavsdsp_init(&h->cdsp, avctx);
     ff_init_scantable_permutation(h->dsp.idct_permutation,
                                   h->cdsp.idct_perm);
     ff_init_scantable(h->dsp.idct_permutation, &h->scantable, ff_zigzag_direct);
 
-    h->avctx = avctx;
-    avctx->pix_fmt= AV_PIX_FMT_YUV420P;
+    h->avctx       = avctx;
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    h->cur.f    = avcodec_alloc_frame();
-    h->DPB[0].f = avcodec_alloc_frame();
-    h->DPB[1].f = avcodec_alloc_frame();
+    h->cur.f    = av_frame_alloc();
+    h->DPB[0].f = av_frame_alloc();
+    h->DPB[1].f = av_frame_alloc();
     if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) {
         ff_cavs_end(avctx);
         return AVERROR(ENOMEM);
     }
 
-    h->luma_scan[0] = 0;
-    h->luma_scan[1] = 8;
-    h->intra_pred_l[      INTRA_L_VERT] = intra_pred_vert;
-    h->intra_pred_l[     INTRA_L_HORIZ] = intra_pred_horiz;
-    h->intra_pred_l[        INTRA_L_LP] = intra_pred_lp;
-    h->intra_pred_l[ INTRA_L_DOWN_LEFT] = intra_pred_down_left;
+    h->luma_scan[0]                     = 0;
+    h->luma_scan[1]                     = 8;
+    h->intra_pred_l[INTRA_L_VERT]       = intra_pred_vert;
+    h->intra_pred_l[INTRA_L_HORIZ]      = intra_pred_horiz;
+    h->intra_pred_l[INTRA_L_LP]         = intra_pred_lp;
+    h->intra_pred_l[INTRA_L_DOWN_LEFT]  = intra_pred_down_left;
     h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right;
-    h->intra_pred_l[   INTRA_L_LP_LEFT] = intra_pred_lp_left;
-    h->intra_pred_l[    INTRA_L_LP_TOP] = intra_pred_lp_top;
-    h->intra_pred_l[    INTRA_L_DC_128] = intra_pred_dc_128;
-    h->intra_pred_c[        INTRA_C_LP] = intra_pred_lp;
-    h->intra_pred_c[     INTRA_C_HORIZ] = intra_pred_horiz;
-    h->intra_pred_c[      INTRA_C_VERT] = intra_pred_vert;
-    h->intra_pred_c[     INTRA_C_PLANE] = intra_pred_plane;
-    h->intra_pred_c[   INTRA_C_LP_LEFT] = intra_pred_lp_left;
-    h->intra_pred_c[    INTRA_C_LP_TOP] = intra_pred_lp_top;
-    h->intra_pred_c[    INTRA_C_DC_128] = intra_pred_dc_128;
-    h->mv[ 7] = un_mv;
-    h->mv[19] = un_mv;
+    h->intra_pred_l[INTRA_L_LP_LEFT]    = intra_pred_lp_left;
+    h->intra_pred_l[INTRA_L_LP_TOP]     = intra_pred_lp_top;
+    h->intra_pred_l[INTRA_L_DC_128]     = intra_pred_dc_128;
+    h->intra_pred_c[INTRA_C_LP]         = intra_pred_lp;
+    h->intra_pred_c[INTRA_C_HORIZ]      = intra_pred_horiz;
+    h->intra_pred_c[INTRA_C_VERT]       = intra_pred_vert;
+    h->intra_pred_c[INTRA_C_PLANE]      = intra_pred_plane;
+    h->intra_pred_c[INTRA_C_LP_LEFT]    = intra_pred_lp_left;
+    h->intra_pred_c[INTRA_C_LP_TOP]     = intra_pred_lp_top;
+    h->intra_pred_c[INTRA_C_DC_128]     = intra_pred_dc_128;
+    h->mv[7]                            = un_mv;
+    h->mv[19]                           = un_mv;
     return 0;
 }
 
-av_cold int ff_cavs_end(AVCodecContext *avctx) {
+av_cold int ff_cavs_end(AVCodecContext *avctx)
+{
     AVSContext *h = avctx->priv_data;
 
-    if (h->cur.f->data[0])
-        avctx->release_buffer(avctx, h->cur.f);
-    if (h->DPB[0].f->data[0])
-        avctx->release_buffer(avctx, h->DPB[0].f);
-    if (h->DPB[1].f->data[0])
-        avctx->release_buffer(avctx, h->DPB[1].f);
-    avcodec_free_frame(&h->cur.f);
-    avcodec_free_frame(&h->DPB[0].f);
-    avcodec_free_frame(&h->DPB[1].f);
+    av_frame_free(&h->cur.f);
+    av_frame_free(&h->DPB[0].f);
+    av_frame_free(&h->DPB[1].f);
 
     av_free(h->top_qp);
     av_free(h->top_mv[0]);
diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h
index 26f1e9c..7d9b94e 100644
--- a/libavcodec/cavs.h
+++ b/libavcodec/cavs.h
@@ -24,6 +24,7 @@
 
 #include "cavsdsp.h"
 #include "dsputil.h"
+#include "h264chroma.h"
 #include "get_bits.h"
 #include "videodsp.h"
 
@@ -161,6 +162,7 @@ typedef struct AVSFrame {
 typedef struct AVSContext {
     AVCodecContext *avctx;
     DSPContext       dsp;
+    H264ChromaContext h264chroma;
     VideoDSPContext vdsp;
     CAVSDSPContext  cdsp;
     GetBitContext gb;
@@ -208,7 +210,7 @@ typedef struct AVSContext {
        6:    A3  X2  X3   */
     int pred_mode_Y[3*3];
     int *top_pred_Y;
-    int l_stride, c_stride;
+    ptrdiff_t l_stride, c_stride;
     int luma_scan[4];
     int qp;
     int qp_fixed;
@@ -234,7 +236,7 @@ typedef struct AVSContext {
     uint8_t *edge_emu_buffer;
 
     int got_keyframe;
-    DCTELEM *block;
+    int16_t *block;
 } AVSContext;
 
 extern const uint8_t     ff_cavs_partition_flags[30];
diff --git a/libavcodec/cavsdata.h b/libavcodec/cavsdata.h
deleted file mode 100644
index b6117e3..0000000
--- a/libavcodec/cavsdata.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
- * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer at gmx.de>
- *
- * 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_CAVSDATA_H
-#define AVCODEC_CAVSDATA_H
-
-#include "cavs.h"
-
-const uint8_t ff_cavs_partition_flags[30] = {
-  0,                                 //I_8X8
-  0,                                 //P_SKIP
-  0,                                 //P_16X16
-                      SPLITH,        //P_16X8
-                             SPLITV, //P_8X16
-                      SPLITH|SPLITV, //P_8X8
-                      SPLITH|SPLITV, //B_SKIP
-                      SPLITH|SPLITV, //B_DIRECT
-  0,                                 //B_FWD_16X16
-  0,                                 //B_BWD_16X16
-  0,                                 //B_SYM_16X16
-  FWD0|FWD1          |SPLITH,
-  FWD0|FWD1                 |SPLITV,
-  BWD0|BWD1          |SPLITH,
-  BWD0|BWD1                 |SPLITV,
-  FWD0|BWD1          |SPLITH,
-  FWD0|BWD1                 |SPLITV,
-  BWD0|FWD1          |SPLITH,
-  BWD0|FWD1                 |SPLITV,
-  FWD0|FWD1     |SYM1|SPLITH,
-  FWD0|FWD1     |SYM1       |SPLITV,
-  BWD0|FWD1     |SYM1|SPLITH,
-  BWD0|FWD1     |SYM1       |SPLITV,
-  FWD0|FWD1|SYM0     |SPLITH,
-  FWD0|FWD1|SYM0            |SPLITV,
-  FWD0|BWD1|SYM0     |SPLITH,
-  FWD0|BWD1|SYM0            |SPLITV,
-  FWD0|FWD1|SYM0|SYM1|SPLITH,
-  FWD0|FWD1|SYM0|SYM1       |SPLITV,
-                      SPLITH|SPLITV, //B_8X8 = 29
-};
-
-/** mark block as "no prediction from this direction"
-    e.g. forward motion vector in BWD partition */
-const cavs_vector ff_cavs_dir_mv   = {0,0,1,REF_DIR};
-
-/** mark block as using intra prediction */
-const cavs_vector ff_cavs_intra_mv = {0,0,1,REF_INTRA};
-
-#endif /* AVCODEC_CAVSDATA_H */
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 7cfb2ca..142b844 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -516,8 +516,8 @@ static inline int get_ue_code(GetBitContext *gb, int order)
     return get_ue_golomb(gb);
 }
 
-static inline int dequant(AVSContext *h, DCTELEM *level_buf, uint8_t *run_buf,
-                          DCTELEM *dst, int mul, int shift, int coeff_num)
+static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf,
+                          int16_t *dst, int mul, int shift, int coeff_num)
 {
     int round = 1 << (shift - 1);
     int pos = -1;
@@ -530,7 +530,7 @@ static inline int dequant(AVSContext *h, DCTELEM *level_buf, uint8_t *run_buf,
             av_log(h->avctx, AV_LOG_ERROR,
                    "position out of block bounds at pic %d MB(%d,%d)\n",
                    h->cur.poc, h->mbx, h->mby);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         dst[scantab[pos]] = (level_buf[coeff_num] * mul + round) >> shift;
     }
@@ -550,10 +550,10 @@ 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;
-    DCTELEM level_buf[65];
+    int i, level_code, esc_code, level, run, mask, ret;
+    int16_t level_buf[65];
     uint8_t run_buf[65];
-    DCTELEM *block = h->block;
+    int16_t *block = h->block;
 
     for (i = 0;i < 65; i++) {
         level_code = get_ue_code(gb, r->golomb_order);
@@ -577,9 +577,9 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb,
         level_buf[i] = level;
         run_buf[i]   = run;
     }
-    if (dequant(h, level_buf, run_buf, block, dequant_mul[qp],
-                dequant_shift[qp], i))
-        return -1;
+    if ((ret = dequant(h, level_buf, run_buf, block, dequant_mul[qp],
+                      dequant_shift[qp], i)) < 0)
+        return ret;
     h->cdsp.cavs_idct8_add(dst, block, stride);
     h->dsp.clear_block(block);
     return 0;
@@ -602,9 +602,9 @@ static inline int decode_residual_inter(AVSContext *h)
 
     /* get coded block pattern */
     int cbp = get_ue_golomb(&h->gb);
-    if (cbp > 63) {
-        av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp\n");
-        return -1;
+    if (cbp > 63 || cbp < 0) {
+        av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp %d\n", cbp);
+        return AVERROR_INVALIDDATA;
     }
     h->cbp = cbp_tab[cbp][1];
 
@@ -666,16 +666,16 @@ static int decode_mb_i(AVSContext *h, int cbp_code)
     pred_mode_uv = get_ue_golomb(gb);
     if (pred_mode_uv > 6) {
         av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     ff_cavs_modify_mb_i(h, &pred_mode_uv);
 
     /* get coded block pattern */
     if (h->cur.f->pict_type == AV_PICTURE_TYPE_I)
         cbp_code = get_ue_golomb(gb);
-    if (cbp_code > 63) {
+    if (cbp_code > 63 || cbp_code < 0) {
         av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     h->cbp = cbp_tab[cbp_code][0];
     if (h->cbp && !h->qp_fixed)
@@ -936,17 +936,19 @@ static int decode_pic(AVSContext *h)
         return AVERROR_INVALIDDATA;
     }
 
+    av_frame_unref(h->cur.f);
+
     skip_bits(&h->gb, 16);//bbv_dwlay
     if (h->stc == PIC_PB_START_CODE) {
         h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I;
         if (h->cur.f->pict_type > AV_PICTURE_TYPE_B) {
             av_log(h->avctx, AV_LOG_ERROR, "illegal picture type\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         /* make sure we have the reference frames we need */
         if (!h->DPB[0].f->data[0] ||
            (!h->DPB[1].f->data[0] && h->cur.f->pict_type == AV_PICTURE_TYPE_B))
-            return -1;
+            return AVERROR_INVALIDDATA;
     } else {
         h->cur.f->pict_type = AV_PICTURE_TYPE_I;
         if (get_bits1(&h->gb))
@@ -961,11 +963,9 @@ static int decode_pic(AVSContext *h)
         if (h->stream_revision > 0)
             skip_bits(&h->gb, 1); //marker_bit
     }
-    /* release last B frame */
-    if (h->cur.f->data[0])
-        h->avctx->release_buffer(h->avctx, h->cur.f);
 
-    ff_get_buffer(h->avctx, h->cur.f);
+    ff_get_buffer(h->avctx, h->cur.f, h->cur.f->pict_type == AV_PICTURE_TYPE_B ?
+                  0 : AV_GET_BUFFER_FLAG_REF);
 
     if (!h->edge_emu_buffer) {
         int alloc_size = FFALIGN(FFABS(h->cur.f->linesize[0]) + 32, 32);
@@ -1061,8 +1061,7 @@ static int decode_pic(AVSContext *h)
         } while (ff_cavs_next_mb(h));
     }
     if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
-        if (h->DPB[1].f->data[0])
-            h->avctx->release_buffer(h->avctx, h->DPB[1].f);
+        av_frame_unref(h->DPB[1].f);
         FFSWAP(AVSFrame, h->cur, h->DPB[1]);
         FFSWAP(AVSFrame, h->DPB[0], h->DPB[1]);
     }
@@ -1087,7 +1086,8 @@ static int decode_seq_header(AVSContext *h)
     width  = get_bits(&h->gb, 14);
     height = get_bits(&h->gb, 14);
     if ((h->width || h->height) && (h->width != width || h->height != height)) {
-        av_log_missing_feature(h->avctx, "Width/height changing in CAVS", 0);
+        avpriv_report_missing_feature(h->avctx,
+                                      "Width/height changing in CAVS");
         return AVERROR_PATCHWELCOME;
     }
     h->width  = width;
@@ -1124,19 +1124,15 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     AVSContext *h      = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    AVFrame *picture   = data;
     uint32_t stc       = -1;
-    int input_size;
+    int input_size, ret;
     const uint8_t *buf_end;
     const uint8_t *buf_ptr;
 
     if (buf_size == 0) {
         if (!h->low_delay && h->DPB[0].f->data[0]) {
             *got_frame = 1;
-            *picture = *h->DPB[0].f;
-            if (h->cur.f->data[0])
-                avctx->release_buffer(avctx, h->cur.f);
-            FFSWAP(AVSFrame, h->cur, h->DPB[0]);
+            av_frame_move_ref(data, h->DPB[0].f);
         }
         return 0;
     }
@@ -1144,7 +1140,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     buf_ptr = buf;
     buf_end = buf + buf_size;
     for(;;) {
-        buf_ptr = avpriv_mpv_find_start_code(buf_ptr, buf_end, &stc);
+        buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc);
         if ((stc & 0xFFFFFE00) || buf_ptr == buf_end)
             return FFMAX(0, buf_ptr - buf);
         input_size = (buf_end - buf_ptr) * 8;
@@ -1155,10 +1151,8 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             break;
         case PIC_I_START_CODE:
             if (!h->got_keyframe) {
-                if(h->DPB[0].f->data[0])
-                    avctx->release_buffer(avctx, h->DPB[0].f);
-                if(h->DPB[1].f->data[0])
-                    avctx->release_buffer(avctx, h->DPB[1].f);
+                av_frame_unref(h->DPB[0].f);
+                av_frame_unref(h->DPB[1].f);
                 h->got_keyframe = 1;
             }
         case PIC_PB_START_CODE:
@@ -1172,12 +1166,14 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             *got_frame = 1;
             if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
                 if (h->DPB[1].f->data[0]) {
-                    *picture = *h->DPB[1].f;
+                    if ((ret = av_frame_ref(data, h->DPB[1].f)) < 0)
+                        return ret;
                 } else {
                     *got_frame = 0;
                 }
-            } else
-                *picture = *h->cur.f;
+            } else {
+                av_frame_move_ref(data, h->cur.f);
+            }
             break;
         case EXT_START_CODE:
             //mpeg_decode_extension(avctx, buf_ptr, input_size);
@@ -1197,6 +1193,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
 AVCodec ff_cavs_decoder = {
     .name           = "cavs",
+    .long_name      = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CAVS,
     .priv_data_size = sizeof(AVSContext),
@@ -1205,5 +1202,4 @@ AVCodec ff_cavs_decoder = {
     .decode         = cavs_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
     .flush          = cavs_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"),
 };
diff --git a/libavcodec/cavsdsp.c b/libavcodec/cavsdsp.c
index 15020a8..2716e33 100644
--- a/libavcodec/cavsdsp.c
+++ b/libavcodec/cavsdsp.c
@@ -183,10 +183,10 @@ static void cavs_filter_ch_c(uint8_t *d, int stride, int alpha, int beta, int tc
  *
  ****************************************************************************/
 
-static void cavs_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride) {
+static void cavs_idct8_add_c(uint8_t *dst, int16_t *block, int stride) {
     int i;
-    DCTELEM (*src)[8] = (DCTELEM(*)[8])block;
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    int16_t (*src)[8] = (int16_t(*)[8])block;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
 
     src[0][0] += 8;
 
@@ -261,7 +261,7 @@ static void cavs_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride) {
 #define CAVS_SUBPIX(OPNAME, OP, NAME, A, B, C, D, E, F) \
 static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
     const int h=8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     for(i=0; i<h; i++)\
     {\
@@ -280,7 +280,7 @@ static void OPNAME ## cavs_filt8_h_ ## NAME(uint8_t *dst, uint8_t *src, int dstS
 \
 static void OPNAME ## cavs_filt8_v_  ## NAME(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
     const int w=8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     for(i=0; i<w; i++)\
     {\
@@ -334,7 +334,7 @@ static void OPNAME ## cavs_filt8_hv_ ## NAME(uint8_t *dst, uint8_t *src1, uint8_
     int16_t *tmp = temp;\
     const int h=8;\
     const int w=8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     src1 -= 2*srcStride;\
     for(i=0; i<h+5; i++)\
@@ -421,63 +421,78 @@ static void OPNAME ## cavs_filt16_hv_ ## NAME(uint8_t *dst, uint8_t *src1, uint8
 }\
 
 #define CAVS_MC(OPNAME, SIZE) \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_filt ## SIZE ## _h_qpel_l(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_filt ## SIZE ## _h_hpel(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc30_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc30_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_filt ## SIZE ## _h_qpel_r(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_filt ## SIZE ## _v_qpel_l(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_filt ## SIZE ## _v_hpel(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc03_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc03_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_filt ## SIZE ## _v_qpel_r(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_jj(dst, src, NULL, stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_egpr(dst, src, src, stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc13_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc13_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_egpr(dst, src, src+stride, stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc31_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc31_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_egpr(dst, src, src+1, stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc33_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_egpr(dst, src, src+stride+1,stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_ff(dst, src, src+stride+1,stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_ii(dst, src, src+stride+1,stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc32_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc32_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_kk(dst, src, src+stride+1,stride, stride); \
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc23_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc23_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
   OPNAME ## cavs_filt ## SIZE ## _hv_qq(dst, src, src+stride+1,stride, stride); \
 }\
 
@@ -512,29 +527,29 @@ CAVS_MC(put_, 16)
 CAVS_MC(avg_, 8)
 CAVS_MC(avg_, 16)
 
-#define ff_put_cavs_qpel8_mc00_c  ff_put_pixels8x8_c
-#define ff_avg_cavs_qpel8_mc00_c  ff_avg_pixels8x8_c
-#define ff_put_cavs_qpel16_mc00_c ff_put_pixels16x16_c
-#define ff_avg_cavs_qpel16_mc00_c ff_avg_pixels16x16_c
+#define put_cavs_qpel8_mc00_c  ff_put_pixels8x8_c
+#define avg_cavs_qpel8_mc00_c  ff_avg_pixels8x8_c
+#define put_cavs_qpel16_mc00_c ff_put_pixels16x16_c
+#define avg_cavs_qpel16_mc00_c ff_avg_pixels16x16_c
 
 av_cold void ff_cavsdsp_init(CAVSDSPContext* c, AVCodecContext *avctx) {
 #define dspfunc(PFX, IDX, NUM) \
-    c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_c; \
-    c->PFX ## _pixels_tab[IDX][ 1] = ff_ ## PFX ## NUM ## _mc10_c; \
-    c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_c; \
-    c->PFX ## _pixels_tab[IDX][ 3] = ff_ ## PFX ## NUM ## _mc30_c; \
-    c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_c; \
-    c->PFX ## _pixels_tab[IDX][ 5] = ff_ ## PFX ## NUM ## _mc11_c; \
-    c->PFX ## _pixels_tab[IDX][ 6] = ff_ ## PFX ## NUM ## _mc21_c; \
-    c->PFX ## _pixels_tab[IDX][ 7] = ff_ ## PFX ## NUM ## _mc31_c; \
-    c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_c; \
-    c->PFX ## _pixels_tab[IDX][ 9] = ff_ ## PFX ## NUM ## _mc12_c; \
-    c->PFX ## _pixels_tab[IDX][10] = ff_ ## PFX ## NUM ## _mc22_c; \
-    c->PFX ## _pixels_tab[IDX][11] = ff_ ## PFX ## NUM ## _mc32_c; \
-    c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_c; \
-    c->PFX ## _pixels_tab[IDX][13] = ff_ ## PFX ## NUM ## _mc13_c; \
-    c->PFX ## _pixels_tab[IDX][14] = ff_ ## PFX ## NUM ## _mc23_c; \
-    c->PFX ## _pixels_tab[IDX][15] = ff_ ## PFX ## NUM ## _mc33_c
+    c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \
+    c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \
+    c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_c; \
+    c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_c; \
+    c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_c; \
+    c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_c; \
+    c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_c; \
+    c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_c; \
+    c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_c; \
+    c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_c; \
+    c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \
+    c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \
+    c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \
+    c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \
+    c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \
+    c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c
     dspfunc(put_cavs_qpel, 0, 16);
     dspfunc(put_cavs_qpel, 1, 8);
     dspfunc(avg_cavs_qpel, 0, 16);
diff --git a/libavcodec/cavsdsp.h b/libavcodec/cavsdsp.h
index fff9c1c..333bd10 100644
--- a/libavcodec/cavsdsp.h
+++ b/libavcodec/cavsdsp.h
@@ -32,7 +32,7 @@ typedef struct CAVSDSPContext {
     void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
     void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
     void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
-    void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride);
+    void (*cavs_idct8_add)(uint8_t *dst, int16_t *block, int stride);
     int idct_perm;
 } CAVSDSPContext;
 
diff --git a/libavcodec/cbrt_tablegen.h b/libavcodec/cbrt_tablegen.h
index 01963a3..60d900a 100644
--- a/libavcodec/cbrt_tablegen.h
+++ b/libavcodec/cbrt_tablegen.h
@@ -36,12 +36,13 @@ static void cbrt_tableinit(void)
 {
     if (!cbrt_tab[(1<<13) - 1]) {
         int i;
+        /* cbrtf() isn't available on all systems, so we use powf(). */
         for (i = 0; i < 1<<13; i++) {
             union {
                 float f;
                 uint32_t i;
             } f;
-            f.f = cbrtf(i) * i;
+            f.f = powf(i, 1.0 / 3.0) * i;
             cbrt_tab[i] = f.i;
         }
     }
diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c
index e4ed83b..b8a6fb8 100644
--- a/libavcodec/cdgraphics.c
+++ b/libavcodec/cdgraphics.c
@@ -64,26 +64,18 @@
 #define CDG_PALETTE_SIZE          16
 
 typedef struct CDGraphicsContext {
-    AVFrame frame;
+    AVFrame *frame;
     int hscroll;
     int vscroll;
 } CDGraphicsContext;
 
-static void cdg_init_frame(AVFrame *frame)
-{
-    avcodec_get_frame_defaults(frame);
-    frame->reference = 3;
-    frame->buffer_hints = FF_BUFFER_HINTS_VALID    |
-                          FF_BUFFER_HINTS_READABLE |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-}
-
 static av_cold int cdg_decode_init(AVCodecContext *avctx)
 {
     CDGraphicsContext *cc = avctx->priv_data;
 
-    cdg_init_frame(&cc->frame);
+    cc->frame = av_frame_alloc();
+    if (!cc->frame)
+        return AVERROR(ENOMEM);
 
     avctx->width   = CDG_FULL_WIDTH;
     avctx->height  = CDG_FULL_HEIGHT;
@@ -95,8 +87,8 @@ static av_cold int cdg_decode_init(AVCodecContext *avctx)
 static void cdg_border_preset(CDGraphicsContext *cc, uint8_t *data)
 {
     int y;
-    int lsize    = cc->frame.linesize[0];
-    uint8_t *buf = cc->frame.data[0];
+    int lsize    = cc->frame->linesize[0];
+    uint8_t *buf = cc->frame->data[0];
     int color    = data[0] & 0x0F;
 
     if (!(data[1] & 0x0F)) {
@@ -120,7 +112,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low)
     uint16_t color;
     int i;
     int array_offset  = low ? 0 : 8;
-    uint32_t *palette = (uint32_t *) cc->frame.data[1];
+    uint32_t *palette = (uint32_t *) cc->frame->data[1];
 
     for (i = 0; i < 8; i++) {
         color = (data[2 * i] << 6) + (data[2 * i + 1] & 0x3F);
@@ -129,7 +121,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low)
         b = ((color     ) & 0x000F) * 17;
         palette[i + array_offset] = r << 16 | g << 8 | b;
     }
-    cc->frame.palette_has_changed = 1;
+    cc->frame->palette_has_changed = 1;
 }
 
 static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b)
@@ -138,8 +130,8 @@ static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b)
     int color;
     int x, y;
     int ai;
-    int stride   = cc->frame.linesize[0];
-    uint8_t *buf = cc->frame.data[0];
+    int stride   = cc->frame->linesize[0];
+    uint8_t *buf = cc->frame->data[0];
 
     ri = (data[2] & 0x1F) * CDG_TILE_HEIGHT + cc->vscroll;
     ci = (data[3] & 0x3F) * CDG_TILE_WIDTH  + cc->hscroll;
@@ -210,8 +202,8 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data,
     int color;
     int hscmd, h_off, hinc, vscmd, v_off, vinc;
     int y;
-    int stride   = cc->frame.linesize[0];
-    uint8_t *in  = cc->frame.data[0];
+    int stride   = cc->frame->linesize[0];
+    uint8_t *in  = cc->frame->data[0];
     uint8_t *out = new_frame->data[0];
 
     color =  data[0] & 0x0F;
@@ -239,7 +231,7 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data,
     if (!hinc && !vinc)
         return;
 
-    memcpy(new_frame->data[1], cc->frame.data[1], CDG_PALETTE_SIZE * 4);
+    memcpy(new_frame->data[1], cc->frame->data[1], CDG_PALETTE_SIZE * 4);
 
     for (y = FFMAX(0, vinc); y < FFMIN(CDG_FULL_HEIGHT + vinc, CDG_FULL_HEIGHT); y++)
         memcpy(out + FFMAX(0, hinc) + stride * y,
@@ -274,7 +266,7 @@ static int cdg_decode_frame(AVCodecContext *avctx,
     int ret;
     uint8_t command, inst;
     uint8_t cdg_data[CDG_DATA_SIZE];
-    AVFrame new_frame;
+    AVFrame *frame = data;
     CDGraphicsContext *cc = avctx->priv_data;
 
     if (buf_size < CDG_MINIMUM_PKT_SIZE) {
@@ -282,11 +274,13 @@ static int cdg_decode_frame(AVCodecContext *avctx,
         return AVERROR(EINVAL);
     }
 
-    ret = avctx->reget_buffer(avctx, &cc->frame);
+    ret = ff_reget_buffer(avctx, cc->frame);
     if (ret) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
+    if (!avctx->frame_number)
+        memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height);
 
     command = bytestream_get_byte(&buf);
     inst    = bytestream_get_byte(&buf);
@@ -298,8 +292,8 @@ static int cdg_decode_frame(AVCodecContext *avctx,
         switch (inst) {
         case CDG_INST_MEMORY_PRESET:
             if (!(cdg_data[1] & 0x0F))
-                memset(cc->frame.data[0], cdg_data[0] & 0x0F,
-                       cc->frame.linesize[0] * CDG_FULL_HEIGHT);
+                memset(cc->frame->data[0], cdg_data[0] & 0x0F,
+                       cc->frame->linesize[0] * CDG_FULL_HEIGHT);
             break;
         case CDG_INST_LOAD_PAL_LO:
         case CDG_INST_LOAD_PAL_HIGH:
@@ -333,28 +327,33 @@ static int cdg_decode_frame(AVCodecContext *avctx,
                 return AVERROR(EINVAL);
             }
 
-            cdg_init_frame(&new_frame);
-            ret = ff_get_buffer(avctx, &new_frame);
+            ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
             if (ret) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return ret;
             }
 
-            cdg_scroll(cc, cdg_data, &new_frame, inst == CDG_INST_SCROLL_COPY);
-            avctx->release_buffer(avctx, &cc->frame);
-            cc->frame = new_frame;
+            cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY);
+            av_frame_unref(cc->frame);
+            ret = av_frame_ref(cc->frame, frame);
+            if (ret < 0)
+                return ret;
             break;
         default:
             break;
         }
 
+        if (!frame->data[0]) {
+            ret = av_frame_ref(frame, cc->frame);
+            if (ret < 0)
+                return ret;
+        }
         *got_frame = 1;
     } else {
         *got_frame = 0;
         buf_size   = 0;
     }
 
-    *(AVFrame *) data = cc->frame;
     return buf_size;
 }
 
@@ -362,14 +361,14 @@ static av_cold int cdg_decode_end(AVCodecContext *avctx)
 {
     CDGraphicsContext *cc = avctx->priv_data;
 
-    if (cc->frame.data[0])
-        avctx->release_buffer(avctx, &cc->frame);
+    av_frame_free(&cc->frame);
 
     return 0;
 }
 
 AVCodec ff_cdgraphics_decoder = {
     .name           = "cdgraphics",
+    .long_name      = NULL_IF_CONFIG_SMALL("CD Graphics video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CDGRAPHICS,
     .priv_data_size = sizeof(CDGraphicsContext),
@@ -377,5 +376,4 @@ AVCodec ff_cdgraphics_decoder = {
     .close          = cdg_decode_end,
     .decode         = cdg_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("CD Graphics video"),
 };
diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c
index 0b3d59c..80a3671 100644
--- a/libavcodec/cdxl.c
+++ b/libavcodec/cdxl.c
@@ -33,7 +33,6 @@
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame        frame;
     int            bpp;
     int            format;
     int            padded_bits;
@@ -49,7 +48,6 @@ static av_cold int cdxl_decode_init(AVCodecContext *avctx)
 {
     CDXLVideoContext *c = avctx->priv_data;
 
-    avcodec_get_frame_defaults(&c->frame);
     c->new_video_size = 0;
     c->avctx          = avctx;
 
@@ -113,15 +111,15 @@ static void import_format(CDXLVideoContext *c, int linesize, uint8_t *out)
     }
 }
 
-static void cdxl_decode_rgb(CDXLVideoContext *c)
+static void cdxl_decode_rgb(CDXLVideoContext *c, AVFrame *frame)
 {
-    uint32_t *new_palette = (uint32_t *)c->frame.data[1];
+    uint32_t *new_palette = (uint32_t *)frame->data[1];
 
     import_palette(c, new_palette);
-    import_format(c, c->frame.linesize[0], c->frame.data[0]);
+    import_format(c, frame->linesize[0], frame->data[0]);
 }
 
-static void cdxl_decode_ham6(CDXLVideoContext *c)
+static void cdxl_decode_ham6(CDXLVideoContext *c, AVFrame *frame)
 {
     AVCodecContext *avctx = c->avctx;
     uint32_t new_palette[16], r, g, b;
@@ -129,7 +127,7 @@ static void cdxl_decode_ham6(CDXLVideoContext *c)
     int x, y;
 
     ptr = c->new_video;
-    out = c->frame.data[0];
+    out = frame->data[0];
 
     import_palette(c, new_palette);
     import_format(c, avctx->width, c->new_video);
@@ -160,11 +158,11 @@ static void cdxl_decode_ham6(CDXLVideoContext *c)
             }
             AV_WL24(out + x * 3, r | g | b);
         }
-        out += c->frame.linesize[0];
+        out += frame->linesize[0];
     }
 }
 
-static void cdxl_decode_ham8(CDXLVideoContext *c)
+static void cdxl_decode_ham8(CDXLVideoContext *c, AVFrame *frame)
 {
     AVCodecContext *avctx = c->avctx;
     uint32_t new_palette[64], r, g, b;
@@ -172,7 +170,7 @@ static void cdxl_decode_ham8(CDXLVideoContext *c)
     int x, y;
 
     ptr = c->new_video;
-    out = c->frame.data[0];
+    out = frame->data[0];
 
     import_palette(c, new_palette);
     import_format(c, avctx->width, c->new_video);
@@ -203,7 +201,7 @@ static void cdxl_decode_ham8(CDXLVideoContext *c)
             }
             AV_WL24(out + x * 3, r | g | b);
         }
-        out += c->frame.linesize[0];
+        out += frame->linesize[0];
     }
 }
 
@@ -211,7 +209,7 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *pkt)
 {
     CDXLVideoContext *c = avctx->priv_data;
-    AVFrame * const p = &c->frame;
+    AVFrame * const p = data;
     int ret, w, h, encoding, aligned_width, buf_size = pkt->size;
     const uint8_t *buf = pkt->data;
 
@@ -234,14 +232,12 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
     if (c->bpp < 1)
         return AVERROR_INVALIDDATA;
     if (c->format != BIT_PLANAR && c->format != BIT_LINE) {
-        av_log_ask_for_sample(avctx, "unsupported pixel format: 0x%0x\n", c->format);
+        avpriv_request_sample(avctx, "Pixel format 0x%0x", c->format);
         return AVERROR_PATCHWELCOME;
     }
 
-    if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
         return ret;
-    if (w != avctx->width || h != avctx->height)
-        avcodec_set_dimensions(avctx, w, h);
 
     aligned_width = FFALIGN(c->avctx->width, 16);
     c->padded_bits  = aligned_width - c->avctx->width;
@@ -254,16 +250,12 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
         avctx->pix_fmt = AV_PIX_FMT_BGR24;
     } else {
-        av_log_ask_for_sample(avctx, "unsupported encoding %d and bpp %d\n",
+        avpriv_request_sample(avctx, "Encoding %d and bpp %d",
                               encoding, c->bpp);
         return AVERROR_PATCHWELCOME;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -275,14 +267,13 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
         if (!c->new_video)
             return AVERROR(ENOMEM);
         if (c->bpp == 8)
-            cdxl_decode_ham8(c);
+            cdxl_decode_ham8(c, p);
         else
-            cdxl_decode_ham6(c);
+            cdxl_decode_ham6(c, p);
     } else {
-        cdxl_decode_rgb(c);
+        cdxl_decode_rgb(c, p);
     }
     *got_frame = 1;
-    *(AVFrame*)data = c->frame;
 
     return buf_size;
 }
@@ -292,14 +283,13 @@ static av_cold int cdxl_decode_end(AVCodecContext *avctx)
     CDXLVideoContext *c = avctx->priv_data;
 
     av_free(c->new_video);
-    if (c->frame.data[0])
-        avctx->release_buffer(avctx, &c->frame);
 
     return 0;
 }
 
 AVCodec ff_cdxl_decoder = {
     .name           = "cdxl",
+    .long_name      = NULL_IF_CONFIG_SMALL("Commodore CDXL video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CDXL,
     .priv_data_size = sizeof(CDXLVideoContext),
@@ -307,5 +297,4 @@ AVCodec ff_cdxl_decoder = {
     .close          = cdxl_decode_end,
     .decode         = cdxl_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Commodore CDXL video"),
 };
diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c
index 9bf6863..caf14cb 100644
--- a/libavcodec/cinepak.c
+++ b/libavcodec/cinepak.c
@@ -37,6 +37,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 
 typedef struct {
@@ -57,7 +58,7 @@ typedef struct {
 typedef struct CinepakContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     const unsigned char *data;
     int size;
@@ -137,14 +138,14 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
 
     for (y=strip->y1; y < strip->y2; y+=4) {
 
-        iy[0] = strip->x1 + (y * s->frame.linesize[0]);
-        iy[1] = iy[0] + s->frame.linesize[0];
-        iy[2] = iy[1] + s->frame.linesize[0];
-        iy[3] = iy[2] + s->frame.linesize[0];
-        iu[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[1]);
-        iu[1] = iu[0] + s->frame.linesize[1];
-        iv[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[2]);
-        iv[1] = iv[0] + s->frame.linesize[2];
+        iy[0] = strip->x1 + (y * s->frame->linesize[0]);
+        iy[1] = iy[0] + s->frame->linesize[0];
+        iy[2] = iy[1] + s->frame->linesize[0];
+        iy[3] = iy[2] + s->frame->linesize[0];
+        iu[0] = (strip->x1/2) + ((y/2) * s->frame->linesize[1]);
+        iu[1] = iu[0] + s->frame->linesize[1];
+        iv[0] = (strip->x1/2) + ((y/2) * s->frame->linesize[2]);
+        iv[1] = iv[0] + s->frame->linesize[2];
 
         for (x=strip->x1; x < strip->x2; x+=4) {
             if ((chunk_id & 0x01) && !(mask >>= 1)) {
@@ -171,40 +172,40 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
                         return AVERROR_INVALIDDATA;
 
                     codebook = &strip->v1_codebook[*data++];
-                    s->frame.data[0][iy[0] + 0] = codebook->y0;
-                    s->frame.data[0][iy[0] + 1] = codebook->y0;
-                    s->frame.data[0][iy[1] + 0] = codebook->y0;
-                    s->frame.data[0][iy[1] + 1] = codebook->y0;
+                    s->frame->data[0][iy[0] + 0] = codebook->y0;
+                    s->frame->data[0][iy[0] + 1] = codebook->y0;
+                    s->frame->data[0][iy[1] + 0] = codebook->y0;
+                    s->frame->data[0][iy[1] + 1] = codebook->y0;
                     if (!s->palette_video) {
-                        s->frame.data[1][iu[0]] = codebook->u;
-                        s->frame.data[2][iv[0]] = codebook->v;
+                        s->frame->data[1][iu[0]] = codebook->u;
+                        s->frame->data[2][iv[0]] = codebook->v;
                     }
 
-                    s->frame.data[0][iy[0] + 2] = codebook->y1;
-                    s->frame.data[0][iy[0] + 3] = codebook->y1;
-                    s->frame.data[0][iy[1] + 2] = codebook->y1;
-                    s->frame.data[0][iy[1] + 3] = codebook->y1;
+                    s->frame->data[0][iy[0] + 2] = codebook->y1;
+                    s->frame->data[0][iy[0] + 3] = codebook->y1;
+                    s->frame->data[0][iy[1] + 2] = codebook->y1;
+                    s->frame->data[0][iy[1] + 3] = codebook->y1;
                     if (!s->palette_video) {
-                        s->frame.data[1][iu[0] + 1] = codebook->u;
-                        s->frame.data[2][iv[0] + 1] = codebook->v;
+                        s->frame->data[1][iu[0] + 1] = codebook->u;
+                        s->frame->data[2][iv[0] + 1] = codebook->v;
                     }
 
-                    s->frame.data[0][iy[2] + 0] = codebook->y2;
-                    s->frame.data[0][iy[2] + 1] = codebook->y2;
-                    s->frame.data[0][iy[3] + 0] = codebook->y2;
-                    s->frame.data[0][iy[3] + 1] = codebook->y2;
+                    s->frame->data[0][iy[2] + 0] = codebook->y2;
+                    s->frame->data[0][iy[2] + 1] = codebook->y2;
+                    s->frame->data[0][iy[3] + 0] = codebook->y2;
+                    s->frame->data[0][iy[3] + 1] = codebook->y2;
                     if (!s->palette_video) {
-                        s->frame.data[1][iu[1]] = codebook->u;
-                        s->frame.data[2][iv[1]] = codebook->v;
+                        s->frame->data[1][iu[1]] = codebook->u;
+                        s->frame->data[2][iv[1]] = codebook->v;
                     }
 
-                    s->frame.data[0][iy[2] + 2] = codebook->y3;
-                    s->frame.data[0][iy[2] + 3] = codebook->y3;
-                    s->frame.data[0][iy[3] + 2] = codebook->y3;
-                    s->frame.data[0][iy[3] + 3] = codebook->y3;
+                    s->frame->data[0][iy[2] + 2] = codebook->y3;
+                    s->frame->data[0][iy[2] + 3] = codebook->y3;
+                    s->frame->data[0][iy[3] + 2] = codebook->y3;
+                    s->frame->data[0][iy[3] + 3] = codebook->y3;
                     if (!s->palette_video) {
-                        s->frame.data[1][iu[1] + 1] = codebook->u;
-                        s->frame.data[2][iv[1] + 1] = codebook->v;
+                        s->frame->data[1][iu[1] + 1] = codebook->u;
+                        s->frame->data[2][iv[1] + 1] = codebook->v;
                     }
 
                 } else if (flag & mask) {
@@ -212,43 +213,43 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
                         return AVERROR_INVALIDDATA;
 
                     codebook = &strip->v4_codebook[*data++];
-                    s->frame.data[0][iy[0] + 0] = codebook->y0;
-                    s->frame.data[0][iy[0] + 1] = codebook->y1;
-                    s->frame.data[0][iy[1] + 0] = codebook->y2;
-                    s->frame.data[0][iy[1] + 1] = codebook->y3;
+                    s->frame->data[0][iy[0] + 0] = codebook->y0;
+                    s->frame->data[0][iy[0] + 1] = codebook->y1;
+                    s->frame->data[0][iy[1] + 0] = codebook->y2;
+                    s->frame->data[0][iy[1] + 1] = codebook->y3;
                     if (!s->palette_video) {
-                        s->frame.data[1][iu[0]] = codebook->u;
-                        s->frame.data[2][iv[0]] = codebook->v;
+                        s->frame->data[1][iu[0]] = codebook->u;
+                        s->frame->data[2][iv[0]] = codebook->v;
                     }
 
                     codebook = &strip->v4_codebook[*data++];
-                    s->frame.data[0][iy[0] + 2] = codebook->y0;
-                    s->frame.data[0][iy[0] + 3] = codebook->y1;
-                    s->frame.data[0][iy[1] + 2] = codebook->y2;
-                    s->frame.data[0][iy[1] + 3] = codebook->y3;
+                    s->frame->data[0][iy[0] + 2] = codebook->y0;
+                    s->frame->data[0][iy[0] + 3] = codebook->y1;
+                    s->frame->data[0][iy[1] + 2] = codebook->y2;
+                    s->frame->data[0][iy[1] + 3] = codebook->y3;
                     if (!s->palette_video) {
-                        s->frame.data[1][iu[0] + 1] = codebook->u;
-                        s->frame.data[2][iv[0] + 1] = codebook->v;
+                        s->frame->data[1][iu[0] + 1] = codebook->u;
+                        s->frame->data[2][iv[0] + 1] = codebook->v;
                     }
 
                     codebook = &strip->v4_codebook[*data++];
-                    s->frame.data[0][iy[2] + 0] = codebook->y0;
-                    s->frame.data[0][iy[2] + 1] = codebook->y1;
-                    s->frame.data[0][iy[3] + 0] = codebook->y2;
-                    s->frame.data[0][iy[3] + 1] = codebook->y3;
+                    s->frame->data[0][iy[2] + 0] = codebook->y0;
+                    s->frame->data[0][iy[2] + 1] = codebook->y1;
+                    s->frame->data[0][iy[3] + 0] = codebook->y2;
+                    s->frame->data[0][iy[3] + 1] = codebook->y3;
                     if (!s->palette_video) {
-                        s->frame.data[1][iu[1]] = codebook->u;
-                        s->frame.data[2][iv[1]] = codebook->v;
+                        s->frame->data[1][iu[1]] = codebook->u;
+                        s->frame->data[2][iv[1]] = codebook->v;
                     }
 
                     codebook = &strip->v4_codebook[*data++];
-                    s->frame.data[0][iy[2] + 2] = codebook->y0;
-                    s->frame.data[0][iy[2] + 3] = codebook->y1;
-                    s->frame.data[0][iy[3] + 2] = codebook->y2;
-                    s->frame.data[0][iy[3] + 3] = codebook->y3;
+                    s->frame->data[0][iy[2] + 2] = codebook->y0;
+                    s->frame->data[0][iy[2] + 3] = codebook->y1;
+                    s->frame->data[0][iy[3] + 2] = codebook->y2;
+                    s->frame->data[0][iy[3] + 3] = codebook->y3;
                     if (!s->palette_video) {
-                        s->frame.data[1][iu[1] + 1] = codebook->u;
-                        s->frame.data[2][iv[1] + 1] = codebook->v;
+                        s->frame->data[1][iu[1] + 1] = codebook->u;
+                        s->frame->data[2][iv[1] + 1] = codebook->v;
                     }
 
                 }
@@ -333,7 +334,7 @@ static int cinepak_decode (CinepakContext *s)
     /* if this is the first frame, check for deviant Sega FILM data */
     if (s->sega_film_skip_bytes == -1) {
         if (!encoded_buf_size) {
-            av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0");
+            avpriv_request_sample(s->avctx, "encoded_buf_size 0");
             return AVERROR_PATCHWELCOME;
         }
         if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) {
@@ -413,7 +414,9 @@ static av_cold int cinepak_decode_init(AVCodecContext *avctx)
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
     }
 
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -429,10 +432,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
     s->data = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame))) {
+    if ((ret = ff_reget_buffer(avctx, s->frame))) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -440,7 +440,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
     if (s->palette_video) {
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
         if (pal) {
-            s->frame.palette_has_changed = 1;
+            s->frame->palette_has_changed = 1;
             memcpy(s->pal, pal, AVPALETTE_SIZE);
         }
     }
@@ -448,10 +448,12 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
     cinepak_decode(s);
 
     if (s->palette_video)
-        memcpy (s->frame.data[1], s->pal, AVPALETTE_SIZE);
+        memcpy (s->frame->data[1], s->pal, AVPALETTE_SIZE);
+
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -461,14 +463,14 @@ static av_cold int cinepak_decode_end(AVCodecContext *avctx)
 {
     CinepakContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_cinepak_decoder = {
     .name           = "cinepak",
+    .long_name      = NULL_IF_CONFIG_SMALL("Cinepak"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CINEPAK,
     .priv_data_size = sizeof(CinepakContext),
@@ -476,5 +478,4 @@ AVCodec ff_cinepak_decoder = {
     .close          = cinepak_decode_end,
     .decode         = cinepak_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Cinepak"),
 };
diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c
index 9ba5138..ad0f729 100644
--- a/libavcodec/cljr.c
+++ b/libavcodec/cljr.c
@@ -29,19 +29,6 @@
 #include "internal.h"
 #include "put_bits.h"
 
-typedef struct CLJRContext {
-    AVFrame         picture;
-} CLJRContext;
-
-static av_cold int common_init(AVCodecContext *avctx)
-{
-    CLJRContext * const a = avctx->priv_data;
-
-    avctx->coded_frame = &a->picture;
-
-    return 0;
-}
-
 #if CONFIG_CLJR_DECODER
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
@@ -49,14 +36,9 @@ static int decode_frame(AVCodecContext *avctx,
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    CLJRContext * const a = avctx->priv_data;
     GetBitContext gb;
-    AVFrame *picture = data;
-    AVFrame * const p = &a->picture;
-    int x, y;
-
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    AVFrame * const p = data;
+    int x, y, ret;
 
     if (avctx->height <= 0 || avctx->width <= 0) {
         av_log(avctx, AV_LOG_ERROR, "Invalid width or height\n");
@@ -69,10 +51,9 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
-    p->reference = 0;
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
@@ -80,9 +61,9 @@ static int decode_frame(AVCodecContext *avctx,
     init_get_bits(&gb, buf, buf_size * 8);
 
     for (y = 0; y < avctx->height; y++) {
-        uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]];
-        uint8_t *cb   = &a->picture.data[1][y * a->picture.linesize[1]];
-        uint8_t *cr   = &a->picture.data[2][y * a->picture.linesize[2]];
+        uint8_t *luma = &p->data[0][y * p->linesize[0]];
+        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) {
             luma[3] = get_bits(&gb, 5) << 3;
             luma[2] = get_bits(&gb, 5) << 3;
@@ -94,7 +75,6 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
-    *picture   = a->picture;
     *got_frame = 1;
 
     return buf_size;
@@ -103,32 +83,36 @@ static int decode_frame(AVCodecContext *avctx,
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     avctx->pix_fmt = AV_PIX_FMT_YUV411P;
-    return common_init(avctx);
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    CLJRContext *a = avctx->priv_data;
-
-    if (a->picture.data[0])
-        avctx->release_buffer(avctx, &a->picture);
     return 0;
 }
 
 AVCodec ff_cljr_decoder = {
     .name           = "cljr",
+    .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CLJR,
-    .priv_data_size = sizeof(CLJRContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
 };
 #endif
 
 #if CONFIG_CLJR_ENCODER
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *p, int *got_packet)
 {
@@ -170,13 +154,13 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
 AVCodec ff_cljr_encoder = {
     .name           = "cljr",
+    .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CLJR,
-    .priv_data_size = sizeof(CLJRContext),
-    .init           = common_init,
+    .init           = encode_init,
     .encode2        = encode_frame,
+    .close          = encode_close,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
                                                    AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
 };
 #endif
diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c
index 30dc53c..6818f9f 100644
--- a/libavcodec/cllc.c
+++ b/libavcodec/cllc.c
@@ -1,7 +1,7 @@
 /*
  * Canopus Lossless Codec decoder
  *
- * Copyright (c) 2012 Derek Buitenhuis
+ * Copyright (c) 2012-2013 Derek Buitenhuis
  *
  * This file is part of Libav.
  *
@@ -136,14 +136,13 @@ static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left,
 
     CLOSE_READER(bits, gb);
 
-    dst         -= 4 * ctx->avctx->width;
-    top_left[0]  = dst[0];
+    top_left[0]  = outbuf[0];
 
     /* Only stash components if they are not transparent */
     if (top_left[0]) {
-        top_left[1] = dst[1];
-        top_left[2] = dst[2];
-        top_left[3] = dst[3];
+        top_left[1] = outbuf[1];
+        top_left[2] = outbuf[2];
+        top_left[3] = outbuf[3];
     }
 
     return 0;
@@ -174,7 +173,35 @@ static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb,
     CLOSE_READER(bits, gb);
 
     /* Stash the first pixel */
-    *top_left = dst[-3 * ctx->avctx->width];
+    *top_left = outbuf[0];
+
+    return 0;
+}
+
+static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb,
+                                   int *top_left, VLC *vlc, uint8_t *outbuf,
+                                   int is_chroma)
+{
+    int pred, code;
+    int i;
+
+    OPEN_READER(bits, gb);
+
+    pred = *top_left;
+
+    /* Simultaneously read and restore the line */
+    for (i = 0; i < ctx->avctx->width >> is_chroma; i++) {
+        UPDATE_CACHE(bits, gb);
+        GET_VLC(code, bits, gb, vlc->table, 7, 2);
+
+        pred     += code;
+        outbuf[i] = pred;
+    }
+
+    CLOSE_READER(bits, gb);
+
+    /* Stash the first pixel */
+    *top_left = outbuf[0];
 
     return 0;
 }
@@ -267,22 +294,72 @@ static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
     return 0;
 }
 
+static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
+{
+    AVCodecContext *avctx = ctx->avctx;
+    uint8_t block;
+    uint8_t *dst[3];
+    int pred[3];
+    int ret;
+    int i, j;
+    VLC vlc[2];
+
+    pred[0] = 0x80;
+    pred[1] = 0x80;
+    pred[2] = 0x80;
+
+    dst[0] = pic->data[0];
+    dst[1] = pic->data[1];
+    dst[2] = pic->data[2];
+
+    skip_bits(gb, 8);
+
+    block = get_bits(gb, 8);
+    if (block) {
+        avpriv_request_sample(ctx->avctx, "Blocked YUV");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    /* Read in code table for luma and chroma */
+    for (i = 0; i < 2; i++) {
+        ret = read_code_table(ctx, gb, &vlc[i]);
+        if (ret < 0) {
+            for (j = 0; j <= i; j++)
+                ff_free_vlc(&vlc[j]);
+
+            av_log(ctx->avctx, AV_LOG_ERROR,
+                   "Could not read code table %d.\n", i);
+            return ret;
+        }
+    }
+
+    /* Read in and restore every line */
+    for (i = 0; i < avctx->height; i++) {
+        read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */
+        read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */
+        read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */
+
+        for (j = 0; j < 3; j++)
+            dst[j] += pic->linesize[j];
+    }
+
+    for (i = 0; i < 2; i++)
+        ff_free_vlc(&vlc[i]);
+
+    return 0;
+}
+
 static int cllc_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_picture_ptr, AVPacket *avpkt)
 {
     CLLCContext *ctx = avctx->priv_data;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     uint8_t *src = avpkt->data;
     uint32_t info_tag, info_offset;
     int data_size;
     GetBitContext gb;
     int coding_type, ret;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    pic->reference = 0;
-
     /* Skip the INFO header if present */
     info_offset = 0;
     info_tag    = AV_RL32(src);
@@ -329,12 +406,27 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
     av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
 
     switch (coding_type) {
+    case 0:
+        avctx->pix_fmt             = AV_PIX_FMT_YUV422P;
+        avctx->bits_per_raw_sample = 8;
+
+        ret = ff_get_buffer(avctx, pic, 0);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+            return ret;
+        }
+
+        ret = decode_yuv_frame(ctx, &gb, pic);
+        if (ret < 0)
+            return ret;
+
+        break;
     case 1:
     case 2:
         avctx->pix_fmt             = AV_PIX_FMT_RGB24;
         avctx->bits_per_raw_sample = 8;
 
-        ret = ff_get_buffer(avctx, pic);
+        ret = ff_get_buffer(avctx, pic, 0);
         if (ret < 0) {
             av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
             return ret;
@@ -349,7 +441,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
         avctx->pix_fmt             = AV_PIX_FMT_ARGB;
         avctx->bits_per_raw_sample = 8;
 
-        ret = ff_get_buffer(avctx, pic);
+        ret = ff_get_buffer(avctx, pic, 0);
         if (ret < 0) {
             av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
             return ret;
@@ -369,7 +461,6 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
     pic->pict_type = AV_PICTURE_TYPE_I;
 
     *got_picture_ptr = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
@@ -378,10 +469,6 @@ static av_cold int cllc_decode_close(AVCodecContext *avctx)
 {
     CLLCContext *ctx = avctx->priv_data;
 
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
     av_freep(&ctx->swapped_buf);
 
     return 0;
@@ -398,17 +485,12 @@ static av_cold int cllc_decode_init(AVCodecContext *avctx)
 
     ff_dsputil_init(&ctx->dsp, 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;
 }
 
 AVCodec ff_cllc_decoder = {
     .name           = "cllc",
+    .long_name      = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CLLC,
     .priv_data_size = sizeof(CLLCContext),
@@ -416,5 +498,4 @@ AVCodec ff_cllc_decoder = {
     .decode         = cllc_decode_frame,
     .close          = cllc_decode_close,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
 };
diff --git a/libavcodec/cngdec.c b/libavcodec/cngdec.c
index 6eb0e72..89f5c81 100644
--- a/libavcodec/cngdec.c
+++ b/libavcodec/cngdec.c
@@ -28,7 +28,6 @@
 #include "libavutil/lfg.h"
 
 typedef struct CNGContext {
-    AVFrame avframe;
     float *refl_coef, *target_refl_coef;
     float *lpc_coef;
     int order;
@@ -58,8 +57,6 @@ static av_cold int cng_decode_init(AVCodecContext *avctx)
     avctx->channels    = 1;
     avctx->sample_rate = 8000;
 
-    avcodec_get_frame_defaults(&p->avframe);
-    avctx->coded_frame  = &p->avframe;
     p->order            = 12;
     avctx->frame_size   = 640;
     p->refl_coef        = av_mallocz(p->order * sizeof(*p->refl_coef));
@@ -105,7 +102,7 @@ static void cng_decode_flush(AVCodecContext *avctx)
 static int cng_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
-
+    AVFrame *frame = data;
     CNGContext *p = avctx->priv_data;
     int buf_size  = avpkt->size;
     int ret, i;
@@ -144,25 +141,25 @@ static int cng_decode_frame(AVCodecContext *avctx, void *data,
     ff_celp_lp_synthesis_filterf(p->filter_out + p->order, p->lpc_coef,
                                  p->excitation, avctx->frame_size, p->order);
 
-    p->avframe.nb_samples = avctx->frame_size;
-    if ((ret = ff_get_buffer(avctx, &p->avframe)) < 0) {
+    frame->nb_samples = avctx->frame_size;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    buf_out = (int16_t *)p->avframe.data[0];
+    buf_out = (int16_t *)frame->data[0];
     for (i = 0; i < avctx->frame_size; i++)
         buf_out[i] = p->filter_out[i + p->order];
     memcpy(p->filter_out, p->filter_out + avctx->frame_size,
            p->order * sizeof(*p->filter_out));
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = p->avframe;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
 
 AVCodec ff_comfortnoise_decoder = {
     .name           = "comfortnoise",
+    .long_name      = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_COMFORT_NOISE,
     .priv_data_size = sizeof(CNGContext),
@@ -170,7 +167,6 @@ AVCodec ff_comfortnoise_decoder = {
     .decode         = cng_decode_frame,
     .flush          = cng_decode_flush,
     .close          = cng_decode_close,
-    .long_name      = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"),
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
diff --git a/libavcodec/cngenc.c b/libavcodec/cngenc.c
index a553a3f..98f3c4e 100644
--- a/libavcodec/cngenc.c
+++ b/libavcodec/cngenc.c
@@ -104,13 +104,13 @@ static int cng_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_comfortnoise_encoder = {
     .name           = "comfortnoise",
+    .long_name      = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_COMFORT_NOISE,
     .priv_data_size = sizeof(CNGContext),
     .init           = cng_encode_init,
     .encode2        = cng_encode_frame,
     .close          = cng_encode_close,
-    .long_name      = NULL_IF_CONFIG_SMALL("RFC 3389 comfort noise generator"),
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 0400c31..68c895d 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -18,10 +18,10 @@
 
 #include <string.h>
 
-#include "avcodec.h"
-
 #include "libavutil/common.h"
 #include "libavutil/internal.h"
+#include "avcodec.h"
+#include "version.h"
 
 static const AVCodecDescriptor codec_descriptors[] = {
     /* video codecs */
@@ -39,6 +39,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
+#if FF_API_XVMC
     {
         .id        = AV_CODEC_ID_MPEG2VIDEO_XVMC,
         .type      = AVMEDIA_TYPE_VIDEO,
@@ -46,6 +47,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
+#endif /* FF_API_XVMC */
     {
         .id        = AV_CODEC_ID_H261,
         .type      = AVMEDIA_TYPE_VIDEO,
@@ -419,13 +421,6 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .props     = AV_CODEC_PROP_LOSSLESS,
     },
     {
-        .id        = AV_CODEC_ID_SNOW,
-        .type      = AVMEDIA_TYPE_VIDEO,
-        .name      = "snow",
-        .long_name = NULL_IF_CONFIG_SMALL("Snow"),
-        .props     = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS,
-    },
-    {
         .id        = AV_CODEC_ID_TSCC,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "tscc",
@@ -1020,6 +1015,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .props     = AV_CODEC_PROP_LOSSY,
     },
     {
+        .id        = AV_CODEC_ID_VP9,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "vp9",
+        .long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
+    {
         .id        = AV_CODEC_ID_PICTOR,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "pictor",
@@ -1207,6 +1209,49 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .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_AIC,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "aic",
+        .long_name = NULL_IF_CONFIG_SMALL("Apple Intermediate Codec"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
+    },
+    {
+        .id        = AV_CODEC_ID_ESCAPE130,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "escape130",
+        .long_name = NULL_IF_CONFIG_SMALL("Escape 130"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
+    {
+        .id        = AV_CODEC_ID_G2M,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "g2m",
+        .long_name = NULL_IF_CONFIG_SMALL("Go2Meeting"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
+    {
+        .id        = AV_CODEC_ID_WEBP,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "webp",
+        .long_name = NULL_IF_CONFIG_SMALL("WebP"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY |
+                     AV_CODEC_PROP_LOSSLESS,
+    },
+    {
+        .id        = AV_CODEC_ID_HNM4_VIDEO,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "hnm4video",
+        .long_name = NULL_IF_CONFIG_SMALL("HNM 4 video"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
+    {
+        .id        = AV_CODEC_ID_HEVC,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "hevc",
+        .long_name = NULL_IF_CONFIG_SMALL("HEVC (High Efficiency Video Coding)"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
 
     /* various PCM "codecs" */
     {
@@ -1341,6 +1386,20 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .props     = AV_CODEC_PROP_LOSSLESS,
     },
     {
+        .id        = AV_CODEC_ID_PCM_S24LE_PLANAR,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "pcm_s24le_planar",
+        .long_name = NULL_IF_CONFIG_SMALL("PCM signed 24-bit little-endian planar"),
+        .props     = AV_CODEC_PROP_LOSSLESS,
+    },
+    {
+        .id        = AV_CODEC_ID_PCM_S32LE_PLANAR,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "pcm_s32le_planar",
+        .long_name = NULL_IF_CONFIG_SMALL("PCM signed 32-bit little-endian planar"),
+        .props     = AV_CODEC_PROP_LOSSLESS,
+    },
+    {
         .id        = AV_CODEC_ID_PCM_DVD,
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "pcm_dvd",
@@ -1899,9 +1958,10 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .id        = AV_CODEC_ID_ATRAC3,
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "atrac3",
-        .long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"),
+        .long_name = NULL_IF_CONFIG_SMALL("ATRAC3 (Adaptive TRansform Acoustic Coding 3)"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
+#if FF_API_VOXWARE
     {
         .id        = AV_CODEC_ID_VOXWARE,
         .type      = AVMEDIA_TYPE_AUDIO,
@@ -1909,6 +1969,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("Voxware RT29 Metasound"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
+#endif
     {
         .id        = AV_CODEC_ID_APE,
         .type      = AVMEDIA_TYPE_AUDIO,
@@ -1962,7 +2023,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .id        = AV_CODEC_ID_ATRAC3P,
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "atrac3p",
-        .long_name = NULL_IF_CONFIG_SMALL("Sony ATRAC3+"),
+        .long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ (Adaptive TRansform Acoustic Coding 3+)"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
     {
@@ -2011,7 +2072,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .id        = AV_CODEC_ID_ATRAC1,
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "atrac1",
-        .long_name = NULL_IF_CONFIG_SMALL("Atrac 1 (Adaptive TRansform Acoustic Coding)"),
+        .long_name = NULL_IF_CONFIG_SMALL("ATRAC1 (Adaptive TRansform Acoustic Coding)"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
     {
@@ -2126,6 +2187,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
         .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
         .props     = AV_CODEC_PROP_LOSSLESS,
     },
+    {
+        .id        = AV_CODEC_ID_METASOUND,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "metasound",
+        .long_name = NULL_IF_CONFIG_SMALL("Voxware MetaSound"),
+        .props     = AV_CODEC_PROP_LOSSY,
+    },
 
     /* subtitle codecs */
     {
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 85565bb..190d28c 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -123,7 +123,6 @@ typedef struct cook {
 
     AVCodecContext*     avctx;
     DSPContext          dsp;
-    AVFrame             frame;
     GetBitContext       gb;
     /* stream data */
     int                 num_vectors;
@@ -944,6 +943,7 @@ static int decode_subpacket(COOKContext *q, COOKSubpacket *p,
 static int cook_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     COOKContext *q = avctx->priv_data;
@@ -957,12 +957,12 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     if (q->discarded_packets >= 2) {
-        q->frame.nb_samples = q->samples_per_channel;
-        if ((ret = ff_get_buffer(avctx, &q->frame)) < 0) {
+        frame->nb_samples = q->samples_per_channel;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
-        samples = (float **)q->frame.extended_data;
+        samples = (float **)frame->extended_data;
     }
 
     /* estimate subpacket sizes */
@@ -1003,8 +1003,7 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data,
         return avctx->block_align;
     }
 
-    *got_frame_ptr    = 1;
-    *(AVFrame *) data = q->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
@@ -1101,7 +1100,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
         switch (q->subpacket[s].cookversion) {
         case MONO:
             if (avctx->channels != 1) {
-                av_log_ask_for_sample(avctx, "Container channels != 1.\n");
+                avpriv_request_sample(avctx, "Container channels != 1");
                 return AVERROR_PATCHWELCOME;
             }
             av_log(avctx, AV_LOG_DEBUG, "MONO\n");
@@ -1115,7 +1114,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
             break;
         case JOINT_STEREO:
             if (avctx->channels != 2) {
-                av_log_ask_for_sample(avctx, "Container channels != 2.\n");
+                avpriv_request_sample(avctx, "Container channels != 2");
                 return AVERROR_PATCHWELCOME;
             }
             av_log(avctx, AV_LOG_DEBUG, "JOINT_STEREO\n");
@@ -1155,7 +1154,8 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
 
             break;
         default:
-            av_log_ask_for_sample(avctx, "Unknown Cook version.\n");
+            avpriv_request_sample(avctx, "Cook version %d",
+                                  q->subpacket[s].cookversion);
             return AVERROR_PATCHWELCOME;
         }
 
@@ -1171,7 +1171,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
 
         /* Try to catch some obviously faulty streams, othervise it might be exploitable */
         if (q->subpacket[s].total_subbands > 53) {
-            av_log_ask_for_sample(avctx, "total_subbands > 53\n");
+            avpriv_request_sample(avctx, "total_subbands > 53");
             return AVERROR_PATCHWELCOME;
         }
 
@@ -1183,7 +1183,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
         }
 
         if (q->subpacket[s].subbands > 50) {
-            av_log_ask_for_sample(avctx, "subbands > 50\n");
+            avpriv_request_sample(avctx, "subbands > 50");
             return AVERROR_PATCHWELCOME;
         }
         q->subpacket[s].gains1.now      = q->subpacket[s].gain_1;
@@ -1194,7 +1194,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
         q->num_subpackets++;
         s++;
         if (s > MAX_SUBPACKETS) {
-            av_log_ask_for_sample(avctx, "Too many subpackets > 5\n");
+            avpriv_request_sample(avctx, "subpackets > %d", MAX_SUBPACKETS);
             return AVERROR_PATCHWELCOME;
         }
     }
@@ -1236,8 +1236,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
     /* Try to catch some obviously faulty streams, othervise it might be exploitable */
     if (q->samples_per_channel != 256 && q->samples_per_channel != 512 &&
         q->samples_per_channel != 1024) {
-        av_log_ask_for_sample(avctx,
-                              "unknown amount of samples_per_channel = %d\n",
+        avpriv_request_sample(avctx, "samples_per_channel = %d",
                               q->samples_per_channel);
         return AVERROR_PATCHWELCOME;
     }
@@ -1248,9 +1247,6 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
     else
         avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&q->frame);
-    avctx->coded_frame = &q->frame;
-
 #ifdef DEBUG
     dump_cook_context(q);
 #endif
@@ -1259,6 +1255,7 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
 
 AVCodec ff_cook_decoder = {
     .name           = "cook",
+    .long_name      = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_COOK,
     .priv_data_size = sizeof(COOKContext),
@@ -1266,7 +1263,6 @@ AVCodec ff_cook_decoder = {
     .close          = cook_decode_close,
     .decode         = cook_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Cook / Cooker / Gecko (RealAudio G2)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/copy_block.h b/libavcodec/copy_block.h
new file mode 100644
index 0000000..ec465db
--- /dev/null
+++ b/libavcodec/copy_block.h
@@ -0,0 +1,61 @@
+/*
+ * 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_COPY_BLOCK_H
+#define AVCODEC_COPY_BLOCK_H
+
+#include <stdint.h>
+
+#include "libavutil/intreadwrite.h"
+
+static inline void copy_block8(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY64U(dst, src);
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void copy_block9(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY64U(dst, src);
+        dst[8]= src[8];
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void copy_block17(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_COPY128U(dst, src);
+        dst[16]= src[16];
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+#endif /* AVCODEC_COPY_BLOCK_H */
diff --git a/libavcodec/cos_tablegen.c b/libavcodec/cos_tablegen.c
index 8a90857..9cf9cef 100644
--- a/libavcodec/cos_tablegen.c
+++ b/libavcodec/cos_tablegen.c
@@ -37,11 +37,16 @@ static int clip_f15(int v)
 
 static void printval(double val, int fixed)
 {
-    if (fixed)
-        printf(" "FIXEDFMT",", clip_f15(lrint(val * (double)(1<<15))));
-    else
-        printf(" "FLOATFMT",", val);
+    if (fixed) {
+        /* lrint() isn't always available, so round and cast manually. */
+        double new_val = val * (double) (1 << 15);
+
+        new_val = new_val >= 0 ? floor(new_val + 0.5) : ceil(new_val - 0.5);
 
+        printf(" "FIXEDFMT",", clip_f15((long int) new_val));
+    } else {
+        printf(" "FLOATFMT",", val);
+    }
 }
 
 int main(int argc, char *argv[])
diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c
index 2c1b2e7..9ae7e33 100644
--- a/libavcodec/cscd.c
+++ b/libavcodec/cscd.c
@@ -31,7 +31,6 @@
 #include "libavutil/lzo.h"
 
 typedef struct {
-    AVFrame pic;
     int linelen, height, bpp;
     unsigned int decomp_size;
     unsigned char* decomp_buf;
@@ -143,20 +142,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int buf_size = avpkt->size;
     CamStudioContext *c = avctx->priv_data;
     AVFrame *picture = data;
+    int ret;
 
     if (buf_size < 2) {
         av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
-                          FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (ff_get_buffer(avctx, &c->pic) < 0) {
+    if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     // decompress data
@@ -175,46 +170,45 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             break;
 #else
             av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n");
-            return -1;
+            return AVERROR(ENOSYS);
 #endif
         }
         default:
             av_log(avctx, AV_LOG_ERROR, "unknown compression\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
     // flip upside down, add difference frame
     if (buf[0] & 1) { // keyframe
-        c->pic.pict_type = AV_PICTURE_TYPE_I;
-        c->pic.key_frame = 1;
+        picture->pict_type = AV_PICTURE_TYPE_I;
+        picture->key_frame = 1;
         switch (c->bpp) {
           case 16:
-              copy_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height);
+              copy_frame_16(picture, c->decomp_buf, c->linelen, c->height);
               break;
           case 32:
-              copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height);
+              copy_frame_32(picture, c->decomp_buf, c->linelen, c->height);
               break;
           default:
-              copy_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4),
+              copy_frame_default(picture, c->decomp_buf, FFALIGN(c->linelen, 4),
                                  c->linelen, c->height);
         }
     } else {
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
-        c->pic.key_frame = 0;
+        picture->pict_type = AV_PICTURE_TYPE_P;
+        picture->key_frame = 0;
         switch (c->bpp) {
           case 16:
-              add_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height);
+              add_frame_16(picture, c->decomp_buf, c->linelen, c->height);
               break;
           case 32:
-              add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height);
+              add_frame_32(picture, c->decomp_buf, c->linelen, c->height);
               break;
           default:
-              add_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4),
+              add_frame_default(picture, c->decomp_buf, FFALIGN(c->linelen, 4),
                                 c->linelen, c->height);
         }
     }
 
-    *picture = c->pic;
     *got_frame = 1;
     return buf_size;
 }
@@ -233,7 +227,6 @@ static av_cold int decode_init(AVCodecContext *avctx) {
             return AVERROR_INVALIDDATA;
     }
     c->bpp = avctx->bits_per_coded_sample;
-    c->pic.data[0] = NULL;
     c->linelen = avctx->width * avctx->bits_per_coded_sample / 8;
     c->height = avctx->height;
     stride = c->linelen;
@@ -251,13 +244,12 @@ static av_cold int decode_init(AVCodecContext *avctx) {
 static av_cold int decode_end(AVCodecContext *avctx) {
     CamStudioContext *c = avctx->priv_data;
     av_freep(&c->decomp_buf);
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
     return 0;
 }
 
 AVCodec ff_cscd_decoder = {
     .name           = "camstudio",
+    .long_name      = NULL_IF_CONFIG_SMALL("CamStudio"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CSCD,
     .priv_data_size = sizeof(CamStudioContext),
@@ -265,5 +257,4 @@ AVCodec ff_cscd_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("CamStudio"),
 };
diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c
index 49cf64c..f628ba1 100644
--- a/libavcodec/cyuv.c
+++ b/libavcodec/cyuv.c
@@ -33,7 +33,6 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "libavutil/internal.h"
 
@@ -41,7 +40,6 @@
 typedef struct CyuvDecodeContext {
     AVCodecContext *avctx;
     int width, height;
-    AVFrame frame;
 } CyuvDecodeContext;
 
 static av_cold int cyuv_decode_init(AVCodecContext *avctx)
@@ -52,7 +50,7 @@ static av_cold int cyuv_decode_init(AVCodecContext *avctx)
     s->width = avctx->width;
     /* width needs to be divisible by 4 for this codec to work */
     if (s->width & 0x3)
-        return -1;
+        return AVERROR_INVALIDDATA;
     s->height = avctx->height;
     avctx->pix_fmt = AV_PIX_FMT_YUV411P;
 
@@ -66,6 +64,7 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     CyuvDecodeContext *s=avctx->priv_data;
+    AVFrame *frame = data;
 
     unsigned char *y_plane;
     unsigned char *u_plane;
@@ -83,6 +82,7 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
     int stream_ptr;
     unsigned char cur_byte;
     int pixel_groups;
+    int ret;
 
     if (avctx->codec_id == AV_CODEC_ID_AURA) {
         y_table = u_table;
@@ -95,32 +95,27 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
     if (buf_size != 48 + s->height * (s->width * 3 / 4)) {
         av_log(avctx, AV_LOG_ERROR, "got a buffer with %d bytes when %d were expected\n",
                buf_size, 48 + s->height * (s->width * 3 / 4));
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* pixel data starts 48 bytes in, after 3x16-byte tables */
     stream_ptr = 48;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-    s->frame.reference = 0;
-    if (ff_get_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    y_plane = s->frame.data[0];
-    u_plane = s->frame.data[1];
-    v_plane = s->frame.data[2];
+    y_plane = frame->data[0];
+    u_plane = frame->data[1];
+    v_plane = frame->data[2];
 
     /* 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]);
-         y_ptr += s->frame.linesize[0] - s->width,
-         u_ptr += s->frame.linesize[1] - s->width / 4,
-         v_ptr += s->frame.linesize[2] - s->width / 4) {
+         y_ptr < (s->height * frame->linesize[0]);
+         y_ptr += frame->linesize[0] - s->width,
+         u_ptr += frame->linesize[1] - s->width / 4,
+         v_ptr += frame->linesize[2] - s->width / 4) {
 
         /* reset predictors */
         cur_byte = buf[stream_ptr++];
@@ -164,45 +159,32 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data= s->frame;
 
     return buf_size;
 }
 
-static av_cold int cyuv_decode_end(AVCodecContext *avctx)
-{
-    CyuvDecodeContext *s = avctx->priv_data;
-
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    return 0;
-}
-
 #if CONFIG_AURA_DECODER
 AVCodec ff_aura_decoder = {
     .name           = "aura",
+    .long_name      = NULL_IF_CONFIG_SMALL("Auravision AURA"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_AURA,
     .priv_data_size = sizeof(CyuvDecodeContext),
     .init           = cyuv_decode_init,
-    .close          = cyuv_decode_end,
     .decode         = cyuv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Auravision AURA"),
 };
 #endif
 
 #if CONFIG_CYUV_DECODER
 AVCodec ff_cyuv_decoder = {
     .name           = "cyuv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CYUV,
     .priv_data_size = sizeof(CyuvDecodeContext),
     .init           = cyuv_decode_init,
-    .close          = cyuv_decode_end,
     .decode         = cyuv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"),
 };
 #endif
diff --git a/libavcodec/dca.c b/libavcodec/dca.c
index 0f1eeec..308211f 100644
--- a/libavcodec/dca.c
+++ b/libavcodec/dca.c
@@ -19,7 +19,9 @@
  */
 
 #include <stdint.h>
+#include <string.h>
 
+#include "put_bits.h"
 #include "dca.h"
 
 const uint32_t avpriv_dca_sample_rates[16] =
@@ -27,3 +29,38 @@ const uint32_t avpriv_dca_sample_rates[16] =
     0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
     12000, 24000, 48000, 96000, 192000
 };
+
+int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
+                             int max_size)
+{
+    uint32_t mrk;
+    int i, tmp;
+    const uint16_t *ssrc = (const uint16_t *) src;
+    uint16_t *sdst = (uint16_t *) dst;
+    PutBitContext pb;
+
+    if ((unsigned) src_size > (unsigned) max_size)
+        src_size = max_size;
+
+    mrk = AV_RB32(src);
+    switch (mrk) {
+    case DCA_MARKER_RAW_BE:
+        memcpy(dst, src, src_size);
+        return src_size;
+    case DCA_MARKER_RAW_LE:
+        for (i = 0; i < (src_size + 1) >> 1; i++)
+            *sdst++ = av_bswap16(*ssrc++);
+        return src_size;
+    case DCA_MARKER_14B_BE:
+    case DCA_MARKER_14B_LE:
+        init_put_bits(&pb, dst, max_size);
+        for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) {
+            tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF;
+            put_bits(&pb, 14, tmp);
+        }
+        flush_put_bits(&pb);
+        return (put_bits_count(&pb) + 7) >> 3;
+    default:
+        return AVERROR_INVALIDDATA;
+    }
+}
diff --git a/libavcodec/dca.h b/libavcodec/dca.h
index 76342f0..0037de2 100644
--- a/libavcodec/dca.h
+++ b/libavcodec/dca.h
@@ -39,4 +39,10 @@
 
 extern av_export const uint32_t avpriv_dca_sample_rates[16];
 
+/**
+ * Convert bitstream to one representation based on sync marker
+ */
+int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
+                             int max_size);
+
 #endif /* AVCODEC_DCA_H */
diff --git a/libavcodec/dca_parser.c b/libavcodec/dca_parser.c
index ab235cf..e233f50 100644
--- a/libavcodec/dca_parser.c
+++ b/libavcodec/dca_parser.c
@@ -24,9 +24,7 @@
 
 #include "parser.h"
 #include "dca.h"
-#include "dca_parser.h"
 #include "get_bits.h"
-#include "put_bits.h"
 
 typedef struct DCAParseContext {
     ParseContext pc;
@@ -62,10 +60,12 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf,
             if (IS_MARKER(state, i, buf, buf_size)) {
                 if (pc1->lastmarker && state == pc1->lastmarker) {
                     start_found = 1;
+                    i++;
                     break;
                 } else if (!pc1->lastmarker) {
                     start_found = 1;
                     pc1->lastmarker = state;
+                    i++;
                     break;
                 }
             }
@@ -80,9 +80,6 @@ static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf,
             if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size)) {
                 if(pc1->framesize > pc1->size)
                     continue;
-                if(!pc1->framesize){
-                    pc1->framesize = pc1->hd_pos ? pc1->hd_pos : pc1->size;
-                }
                 pc->frame_start_found = 0;
                 pc->state = -1;
                 pc1->size = 0;
@@ -103,43 +100,8 @@ static av_cold int dca_parse_init(AVCodecParserContext * s)
     return 0;
 }
 
-int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
-                             int max_size)
-{
-    uint32_t mrk;
-    int i, tmp;
-    const uint16_t *ssrc = (const uint16_t *) src;
-    uint16_t *sdst = (uint16_t *) dst;
-    PutBitContext pb;
-
-    if ((unsigned) src_size > (unsigned) max_size)
-        src_size = max_size;
-
-    mrk = AV_RB32(src);
-    switch (mrk) {
-    case DCA_MARKER_RAW_BE:
-        memcpy(dst, src, src_size);
-        return src_size;
-    case DCA_MARKER_RAW_LE:
-        for (i = 0; i < (src_size + 1) >> 1; i++)
-            *sdst++ = av_bswap16(*ssrc++);
-        return src_size;
-    case DCA_MARKER_14B_BE:
-    case DCA_MARKER_14B_LE:
-        init_put_bits(&pb, dst, max_size);
-        for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) {
-            tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF;
-            put_bits(&pb, 14, tmp);
-        }
-        flush_put_bits(&pb);
-        return (put_bits_count(&pb) + 7) >> 3;
-    default:
-        return AVERROR_INVALIDDATA;
-    }
-}
-
 static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration,
-                            int *sample_rate)
+                            int *sample_rate, int *framesize)
 {
     GetBitContext gb;
     uint8_t hdr[12 + FF_INPUT_BUFFER_PADDING_SIZE] = { 0 };
@@ -159,7 +121,11 @@ static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration,
         return AVERROR_INVALIDDATA;
     *duration = 256 * (sample_blocks / 8);
 
-    skip_bits(&gb, 20);
+    *framesize = get_bits(&gb, 14) + 1;
+    if (*framesize < 95)
+        return AVERROR_INVALIDDATA;
+
+    skip_bits(&gb, 6);
     sr_code = get_bits(&gb, 4);
     *sample_rate = avpriv_dca_sample_rates[sr_code];
     if (*sample_rate == 0)
@@ -190,7 +156,7 @@ static int dca_parse(AVCodecParserContext * s,
     }
 
     /* read the duration and sample rate from the frame header */
-    if (!dca_parse_params(buf, buf_size, &duration, &sample_rate)) {
+    if (!dca_parse_params(buf, buf_size, &duration, &sample_rate, &pc1->framesize)) {
         s->duration = duration;
         avctx->sample_rate = sample_rate;
     } else
diff --git a/libavcodec/dca_parser.h b/libavcodec/dca_parser.h
deleted file mode 100644
index f480eab..0000000
--- a/libavcodec/dca_parser.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * DCA parser
- * 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.
- *
- * 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_DCA_PARSER_H
-#define AVCODEC_DCA_PARSER_H
-
-#include <stdint.h>
-
-/**
- * Convert bitstream to one representation based on sync marker
- */
-int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst,
-                             int max_size);
-
-#endif /* AVCODEC_DCA_PARSER_H */
diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h
index 324e40f..dc4e8b9 100644
--- a/libavcodec/dcadata.h
+++ b/libavcodec/dcadata.h
@@ -7505,34 +7505,63 @@ DECLARE_ALIGNED(16, static const float, lfe_fir_128)[] =
     0.01724460535, 0.47964480519, 0.48503074050, 0.01805862412,
 };
 
-/* 10^-(dB/20), with dB being a list of dB values ranging from 0 to -72 */
-/* do a 20*log10(dca_downmix_coeffs) to reconvert the values */
-
-static const float dca_downmix_coeffs[65] = {
-  1.000000000000000, 0.988553094656939, 0.971627951577106, 0.944060876285923, 0.917275935389780, 0.891250938133746,
-  0.865964323360065, 0.841395141645195, 0.817523037943650, 0.794328234724281, 0.771791515585012, 0.749894209332456,
-  0.728618174513228, 0.707945784384138, 0.687859912308808, 0.668343917568615, 0.649381631576211, 0.630957344480193,
-  0.613055792149821, 0.595662143529010, 0.578761988349121, 0.562341325190349, 0.546386549881854, 0.530884444230988,
-  0.515822165072306, 0.501187233627272, 0.446683592150963, 0.398107170553497, 0.354813389233575, 0.316227766016838,
-  0.281838293126445, 0.251188643150958, 0.223872113856834, 0.199526231496888, 0.177827941003892, 0.158489319246111,
-  0.141253754462275, 0.125892541179417, 0.112201845430196, 0.100000000000000, 0.089125093813374, 0.079432823472428,
-  0.070794578438414, 0.063095734448019, 0.053088444423099, 0.044668359215096, 0.037583740428844, 0.031622776601684,
-  0.026607250597988, 0.022387211385683, 0.018836490894898, 0.015848931924611, 0.013335214321633, 0.011220184543020,
-  0.009440608762859, 0.007943282347243, 0.005623413251903, 0.003981071705535, 0.002818382931264, 0.001995262314969,
-  0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000,
+/*
+ * D.11 Look-up Table for Downmix Scale Factors
+ *
+ * Note that the range of the entries in DmixTable[] is between -60 dB and 0 dB
+ * with addition of -inf (|DMixCoeff| = 0), which is coded with a DmixCode = 0.
+ * Furthermore, the range [-60 to 0] is subdivided into 3 regions, each with a
+ * different grid resolution:
+ *
+ * 1) [-60.000 to -30] with resolution of 0.500 dB
+ * 2) [-29.750 to -15] with resolution of 0.250 dB
+ * 3) [-14.875 to   0] with resolution of 0.125 dB
+ */
+static const float dca_dmixtable[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 },                                     },
-    { {  0, 64 }, { 64,  0 },                                     },
-    { {  0, 64 }, { 64,  0 },                                     },
-    { {  0, 64 }, { 64,  0 },                                     },
-    { {  6,  6 }, {  0, 25 }, { 25,  0 },                         },
-    { {  0, 25 }, { 25,  0 }, { 13, 13 },                         },
-    { {  6,  6 }, {  0, 25 }, { 25,  0 }, { 13, 13 },             },
-    { {  0, 25 }, { 25,  0 }, {  0, 13 }, { 13,  0 },             },
-    { {  6,  6 }, {  0, 25 }, { 25,  0 }, {  0, 13 }, { 13,  0 }, },
+static const float dca_default_coeffs[10][6][2] = {
+    { { 0.707107, 0.707107 }, { 0.000000, 0.000000 },                                                                                                 }, // A [LFE]
+    { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 },                                                                         }, // A + B (dual mono) [LFE]
+    { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 },                                                                         }, // L + R (stereo) [LFE]
+    { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 },                                                                         }, // (L+R) + (L-R) (sum-difference) [LFE]
+    { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 },                                                                         }, // LT + RT (left and right total) [LFE]
+    { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.000000, 0.000000 },                                                 }, // C + L + R [LFE]
+    { { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 },                                                 }, // L + R + S [LFE]
+    { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 },                         }, // C + L + R + S [LFE]
+    { { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 },                         }, // L + R + SL + SR [LFE]
+    { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + SL + SR [LFE]
 };
 
 /* downmix coeffs
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index eecdeaa..aa713f3 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -29,19 +29,19 @@
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/float_dsp.h"
-#include "libavutil/intmath.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 #include "libavutil/samplefmt.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "get_bits.h"
 #include "put_bits.h"
 #include "dcadata.h"
 #include "dcahuff.h"
 #include "dca.h"
-#include "dca_parser.h"
+#include "mathops.h"
 #include "synth_filter.h"
 #include "dcadsp.h"
 #include "fmtconvert.h"
@@ -263,6 +263,8 @@ static const int8_t dca_channel_reorder_nolfe_xch[][9] = {
 
 #define DCA_BUFFER_PADDING_SIZE   1024
 
+#define DCA_NSYNCAUX        0x9A1105A0
+
 /** Bit allocation */
 typedef struct {
     int offset;                 ///< code values offset
@@ -284,8 +286,8 @@ static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba,
 }
 
 typedef struct {
+    AVClass *class;             ///< class for AVOptions
     AVCodecContext *avctx;
-    AVFrame frame;
     /* Frame header */
     int frame_type;             ///< type of the current frame
     int samples_deficit;        ///< deficit sample count
@@ -297,7 +299,6 @@ typedef struct {
     int bit_rate;               ///< transmission bit rate
     int bit_rate_index;         ///< transmission bit rate index
 
-    int downmix;                ///< embedded downmix enabled
     int dynrange;               ///< embedded dynamic range flag
     int timestamp;              ///< embedded time stamp flag
     int aux_data;               ///< auxiliary data flag
@@ -339,9 +340,16 @@ typedef struct {
     int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2];    ///< scale factors (2 if transient)
     int joint_huff[DCA_PRIM_CHANNELS_MAX];                       ///< joint subband scale factors codebook
     int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors
-    int downmix_coef[DCA_PRIM_CHANNELS_MAX][2];                  ///< stereo downmix coefficients
+    float downmix_coef[DCA_PRIM_CHANNELS_MAX + 1][2];            ///< stereo downmix coefficients
     int dynrange_coef;                                           ///< dynamic range coefficient
 
+    /* Core substream's embedded downmix coefficients (cf. ETSI TS 102 114 V1.4.1)
+     * Input:  primary audio channels (incl. LFE if present)
+     * Output: downmix audio channels (up to 4, no LFE) */
+    uint8_t  core_downmix;                                       ///< embedded downmix coefficients available
+    uint8_t  core_downmix_amode;                                 ///< audio channel arrangement of embedded downmix
+    uint16_t core_downmix_codes[DCA_PRIM_CHANNELS_MAX + 1][4];   ///< embedded downmix coefficients (9-bit codes)
+
     int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS];       ///< VQ encoded high frequency subbands
 
     float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)];      ///< Low frequency effect data
@@ -376,6 +384,7 @@ typedef struct {
     /* XCh extension information */
     int xch_present;            ///< XCh extension present and valid
     int xch_base_channel;       ///< index of first (only) channel containing XCH data
+    int xch_disable;            ///< whether the XCh extension should be decoded or not
 
     /* ExSS header parser */
     int static_fields;          ///< static fields present
@@ -571,7 +580,7 @@ static int dca_parse_frame_header(DCAContext *s)
     if (!s->bit_rate)
         return AVERROR_INVALIDDATA;
 
-    s->downmix           = get_bits(&s->gb, 1);
+    skip_bits1(&s->gb); // always 0 (reserved, cf. ETSI TS 102 114 V1.4.1)
     s->dynrange          = get_bits(&s->gb, 1);
     s->timestamp         = get_bits(&s->gb, 1);
     s->aux_data          = get_bits(&s->gb, 1);
@@ -617,7 +626,6 @@ static int dca_parse_frame_header(DCAContext *s)
            s->sample_rate);
     av_log(s->avctx, AV_LOG_DEBUG, "bit rate: %i bits/s\n",
            s->bit_rate);
-    av_log(s->avctx, AV_LOG_DEBUG, "downmix: %i\n", s->downmix);
     av_log(s->avctx, AV_LOG_DEBUG, "dynrange: %i\n", s->dynrange);
     av_log(s->avctx, AV_LOG_DEBUG, "timestamp: %i\n", s->timestamp);
     av_log(s->avctx, AV_LOG_DEBUG, "aux_data: %i\n", s->aux_data);
@@ -800,33 +808,6 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index)
         }
     }
 
-    /* Stereo downmix coefficients */
-    if (!base_channel && s->prim_channels > 2) {
-        if (s->downmix) {
-            for (j = base_channel; j < s->prim_channels; j++) {
-                s->downmix_coef[j][0] = get_bits(&s->gb, 7);
-                s->downmix_coef[j][1] = get_bits(&s->gb, 7);
-            }
-        } else {
-            int am = s->amode & DCA_CHANNEL_MASK;
-            if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) {
-                av_log(s->avctx, AV_LOG_ERROR,
-                       "Invalid channel mode %d\n", am);
-                return AVERROR_INVALIDDATA;
-            }
-            if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) {
-                av_log_ask_for_sample(s->avctx, "Downmixing %d channels",
-                                      s->prim_channels);
-                return AVERROR_PATCHWELCOME;
-            }
-
-            for (j = base_channel; j < s->prim_channels; j++) {
-                s->downmix_coef[j][0] = dca_default_coeffs[am][j][0];
-                s->downmix_coef[j][1] = dca_default_coeffs[am][j][1];
-            }
-        }
-    }
-
     /* Dynamic range coefficient */
     if (!base_channel && s->dynrange)
         s->dynrange_coef = get_bits(&s->gb, 8);
@@ -921,16 +902,6 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index)
             av_log(s->avctx, AV_LOG_DEBUG, "\n");
         }
     }
-    if (!base_channel && s->prim_channels > 2 && s->downmix) {
-        av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n");
-        for (j = 0; j < s->prim_channels; j++) {
-            av_log(s->avctx, AV_LOG_DEBUG, "Channel 0, %d = %f\n", j,
-                   dca_downmix_coeffs[s->downmix_coef[j][0]]);
-            av_log(s->avctx, AV_LOG_DEBUG, "Channel 1, %d = %f\n", j,
-                   dca_downmix_coeffs[s->downmix_coef[j][1]]);
-        }
-        av_log(s->avctx, AV_LOG_DEBUG, "\n");
-    }
     for (j = base_channel; j < s->prim_channels; j++)
         for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++)
             av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]);
@@ -953,10 +924,8 @@ static void qmf_32_subbands(DCAContext *s, int chans,
                             float scale)
 {
     const float *prCoeff;
-    int i;
 
     int sb_act = s->subband_activity[chans];
-    int subindex;
 
     scale *= sqrt(1 / 8.0);
 
@@ -966,25 +935,11 @@ static void qmf_32_subbands(DCAContext *s, int chans,
     else                        /* Perfect reconstruction */
         prCoeff = fir_32bands_perfect;
 
-    for (i = sb_act; i < 32; i++)
-        s->raXin[i] = 0.0;
-
-    /* Reconstructed channel sample index */
-    for (subindex = 0; subindex < 8; subindex++) {
-        /* Load in one sample from each subband and clear inactive subbands */
-        for (i = 0; i < sb_act; i++) {
-            unsigned sign = (i - 1) & 2;
-            uint32_t v    = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30;
-            AV_WN32A(&s->raXin[i], v);
-        }
-
-        s->synth.synth_filter_float(&s->imdct,
-                                    s->subband_fir_hist[chans],
-                                    &s->hist_index[chans],
-                                    s->subband_fir_noidea[chans], prCoeff,
-                                    samples_out, s->raXin, scale);
-        samples_out += 32;
-    }
+    s->dcadsp.qmf_32_subbands(samples_in, sb_act, &s->synth, &s->imdct,
+                              s->subband_fir_hist[chans],
+                              &s->hist_index[chans],
+                              s->subband_fir_noidea[chans], prCoeff,
+                              samples_out, s->raXin, scale);
 }
 
 static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
@@ -1041,29 +996,23 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
         op2                                     \
     }
 
-static void dca_downmix(float **samples, int srcfmt,
-                        int downmix_coef[DCA_PRIM_CHANNELS_MAX][2],
+static void dca_downmix(float **samples, int srcfmt, int lfe_present,
+                        float coef[DCA_PRIM_CHANNELS_MAX + 1][2],
                         const int8_t *channel_mapping)
 {
     int c, l, r, sl, sr, s;
     int i;
     float t, u, v;
-    float coef[DCA_PRIM_CHANNELS_MAX][2];
-
-    for (i = 0; i < DCA_PRIM_CHANNELS_MAX; i++) {
-        coef[i][0] = dca_downmix_coeffs[downmix_coef[i][0]];
-        coef[i][1] = dca_downmix_coeffs[downmix_coef[i][1]];
-    }
 
     switch (srcfmt) {
     case DCA_MONO:
-    case DCA_CHANNEL:
-    case DCA_STEREO_TOTAL:
-    case DCA_STEREO_SUMDIFF:
     case DCA_4F2R:
         av_log(NULL, 0, "Not implemented!\n");
         break;
+    case DCA_CHANNEL:
     case DCA_STEREO:
+    case DCA_STEREO_TOTAL:
+    case DCA_STEREO_SUMDIFF:
         break;
     case DCA_3F:
         c = channel_mapping[0];
@@ -1098,13 +1047,21 @@ static void dca_downmix(float **samples, int srcfmt,
                           MIX_REAR2(samples, sl, sr, 3, coef));
         break;
     }
+    if (lfe_present) {
+        int lf_buf = dca_lfe_index[srcfmt];
+        int lf_idx = dca_channels [srcfmt];
+        for (i = 0; i < 256; i++) {
+            samples[0][i] += samples[lf_buf][i] * coef[lf_idx][0];
+            samples[1][i] += samples[lf_buf][i] * coef[lf_idx][1];
+        }
+    }
 }
 
 
 #ifndef decode_blockcodes
 /* Very compact version of the block code decoder that does not use table
  * look-up but is slightly slower */
-static int decode_blockcode(int code, int levels, int *values)
+static int decode_blockcode(int code, int levels, int32_t *values)
 {
     int i;
     int offset = (levels - 1) >> 1;
@@ -1118,7 +1075,7 @@ static int decode_blockcode(int code, int levels, int *values)
     return code;
 }
 
-static int decode_blockcodes(int code1, int code2, int levels, int *values)
+static int decode_blockcodes(int code1, int code2, int levels, int32_t *values)
 {
     return decode_blockcode(code1, levels, values) |
            decode_blockcode(code2, levels, values + 4);
@@ -1147,7 +1104,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index)
 
     /* FIXME */
     float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index];
-    LOCAL_ALIGNED_16(int, block, [8]);
+    LOCAL_ALIGNED_16(int32_t, block, [8 * DCA_SUBBANDS]);
 
     /*
      * Audio data
@@ -1160,6 +1117,8 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index)
         quant_step_table = lossy_quant_d;
 
     for (k = base_channel; k < s->prim_channels; k++) {
+        float rscale[DCA_SUBBANDS];
+
         if (get_bits_left(&s->gb) < 0)
             return AVERROR_INVALIDDATA;
 
@@ -1182,11 +1141,12 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index)
              * Extract bits from the bit stream
              */
             if (!abits) {
-                memset(subband_samples[k][l], 0, 8 * sizeof(subband_samples[0][0][0]));
+                rscale[l] = 0;
+                memset(block + 8 * l, 0, 8 * sizeof(block[0]));
             } else {
                 /* Deal with transients */
                 int sfi = s->transition_mode[k][l] && subsubframe >= s->transition_mode[k][l];
-                float rscale = quant_step_size * s->scale_factor[k][l][sfi] *
+                rscale[l] = quant_step_size * s->scale_factor[k][l][sfi] *
                                s->scalefactor_adj[k][sel];
 
                 if (abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table) {
@@ -1200,7 +1160,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index)
                         block_code1 = get_bits(&s->gb, size);
                         block_code2 = get_bits(&s->gb, size);
                         err = decode_blockcodes(block_code1, block_code2,
-                                                levels, block);
+                                                levels, block + 8 * l);
                         if (err) {
                             av_log(s->avctx, AV_LOG_ERROR,
                                    "ERROR: block code look-up failed\n");
@@ -1209,19 +1169,23 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index)
                     } else {
                         /* no coding */
                         for (m = 0; m < 8; m++)
-                            block[m] = get_sbits(&s->gb, abits - 3);
+                            block[8 * l + m] = get_sbits(&s->gb, abits - 3);
                     }
                 } else {
                     /* Huffman coded */
                     for (m = 0; m < 8; m++)
-                        block[m] = get_bitalloc(&s->gb,
+                        block[8 * l + m] = get_bitalloc(&s->gb,
                                                 &dca_smpl_bitalloc[abits], sel);
                 }
 
-                s->fmt_conv.int32_to_float_fmul_scalar(subband_samples[k][l],
-                                                       block, rscale, 8);
             }
+        }
 
+        s->fmt_conv.int32_to_float_fmul_array8(&s->fmt_conv, subband_samples[k][0],
+                                               block, rscale, 8 * s->vq_start_subband[k]);
+
+        for (l = 0; l < s->vq_start_subband[k]; l++) {
+            int m;
             /*
              * Inverse ADPCM if in prediction mode
              */
@@ -1298,13 +1262,8 @@ static int dca_filter_channels(DCAContext *s, int block_index)
                             M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */);
     }
 
-    /* Down mixing */
-    if (s->avctx->request_channels == 2 && s->prim_channels > 2) {
-        dca_downmix(s->samples_chanptr, s->amode, s->downmix_coef, s->channel_order_tab);
-    }
-
     /* Generate LFE samples for this subsubframe FIXME!!! */
-    if (s->output & DCA_LFE) {
+    if (s->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]],
@@ -1312,13 +1271,21 @@ static int dca_filter_channels(DCAContext *s, int block_index)
         /* Outputs 20bits pcm samples */
     }
 
+    /* Downmixing to Stereo */
+    if (s->prim_channels + !!s->lfe > 2 &&
+        s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+        dca_downmix(s->samples_chanptr, s->amode, !!s->lfe, s->downmix_coef,
+                    s->channel_order_tab);
+    }
+
     return 0;
 }
 
 
 static int dca_subframe_footer(DCAContext *s, int base_channel)
 {
-    int aux_data_count = 0, i;
+    int in, out, aux_data_count, aux_data_end, reserved;
+    uint32_t nsyncaux;
 
     /*
      * Unpack optional information
@@ -1329,13 +1296,89 @@ static int dca_subframe_footer(DCAContext *s, int base_channel)
         if (s->timestamp)
             skip_bits_long(&s->gb, 32);
 
-        if (s->aux_data)
+        if (s->aux_data) {
             aux_data_count = get_bits(&s->gb, 6);
 
-        for (i = 0; i < aux_data_count; i++)
-            get_bits(&s->gb, 8);
+            // align (32-bit)
+            skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
+
+            aux_data_end = 8 * aux_data_count + get_bits_count(&s->gb);
+
+            if ((nsyncaux = get_bits_long(&s->gb, 32)) != DCA_NSYNCAUX) {
+                av_log(s->avctx, AV_LOG_ERROR, "nSYNCAUX mismatch %#"PRIx32"\n",
+                       nsyncaux);
+                return AVERROR_INVALIDDATA;
+            }
+
+            if (get_bits1(&s->gb)) { // bAUXTimeStampFlag
+                avpriv_request_sample(s->avctx,
+                                      "Auxiliary Decode Time Stamp Flag");
+                // align (4-bit)
+                skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 4);
+                // 44 bits: nMSByte (8), nMarker (4), nLSByte (28), nMarker (4)
+                skip_bits_long(&s->gb, 44);
+            }
+
+            if ((s->core_downmix = get_bits1(&s->gb))) {
+                int am = get_bits(&s->gb, 3);
+                switch (am) {
+                case 0:
+                    s->core_downmix_amode = DCA_MONO;
+                    break;
+                case 1:
+                    s->core_downmix_amode = DCA_STEREO;
+                    break;
+                case 2:
+                    s->core_downmix_amode = DCA_STEREO_TOTAL;
+                    break;
+                case 3:
+                    s->core_downmix_amode = DCA_3F;
+                    break;
+                case 4:
+                    s->core_downmix_amode = DCA_2F1R;
+                    break;
+                case 5:
+                    s->core_downmix_amode = DCA_2F2R;
+                    break;
+                case 6:
+                    s->core_downmix_amode = DCA_3F1R;
+                    break;
+                default:
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "Invalid mode %d for embedded downmix coefficients\n",
+                           am);
+                    return AVERROR_INVALIDDATA;
+                }
+                for (out = 0; out < dca_channels[s->core_downmix_amode]; out++) {
+                    for (in = 0; in < s->prim_channels + !!s->lfe; in++) {
+                        uint16_t tmp = get_bits(&s->gb, 9);
+                        if ((tmp & 0xFF) > 241) {
+                            av_log(s->avctx, AV_LOG_ERROR,
+                                   "Invalid downmix coefficient code %"PRIu16"\n",
+                                   tmp);
+                            return AVERROR_INVALIDDATA;
+                        }
+                        s->core_downmix_codes[in][out] = tmp;
+                    }
+                }
+            }
+
+            align_get_bits(&s->gb); // byte align
+            skip_bits(&s->gb, 16);  // nAUXCRC16
+
+            // additional data (reserved, cf. ETSI TS 102 114 V1.4.1)
+            if ((reserved = (aux_data_end - get_bits_count(&s->gb))) < 0) {
+                 av_log(s->avctx, AV_LOG_ERROR,
+                        "Overread auxiliary data by %d bits\n", -reserved);
+                return AVERROR_INVALIDDATA;
+            } else if (reserved) {
+                avpriv_request_sample(s->avctx,
+                                      "Core auxiliary data reserved content");
+                skip_bits_long(&s->gb, reserved);
+            }
+        }
 
-        if (s->crc_present && (s->downmix || s->dynrange))
+        if (s->crc_present && s->dynrange)
             get_bits(&s->gb, 16);
     }
 
@@ -1611,14 +1654,15 @@ static void dca_exss_parse_header(DCAContext *s)
 
         num_audiop = get_bits(&s->gb, 3) + 1;
         if (num_audiop > 1) {
-            av_log_ask_for_sample(s->avctx, "Multiple DTS-HD audio presentations.");
+            avpriv_request_sample(s->avctx,
+                                  "Multiple DTS-HD audio presentations");
             /* ignore such streams for now */
             return;
         }
 
         num_assets = get_bits(&s->gb, 3) + 1;
         if (num_assets > 1) {
-            av_log_ask_for_sample(s->avctx, "Multiple DTS-HD audio assets.");
+            avpriv_request_sample(s->avctx, "Multiple DTS-HD audio assets");
             /* ignore such streams for now */
             return;
         }
@@ -1665,6 +1709,7 @@ static void dca_exss_parse_header(DCAContext *s)
 static int dca_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
 
@@ -1812,8 +1857,15 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
     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)) {
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+        if (s->xch_present && !s->xch_disable &&
+            (!avctx->request_channels ||
+             avctx->request_channels > num_core_channels + !!s->lfe)) {
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+        if (s->xch_present && !s->xch_disable) {
+#endif
             avctx->channel_layout |= AV_CH_BACK_CENTER;
             if (s->lfe) {
                 avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
@@ -1835,10 +1887,56 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
             s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
             return AVERROR_INVALIDDATA;
 
-        if (avctx->request_channels == 2 && s->prim_channels > 2) {
+        if (s->prim_channels + !!s->lfe > 2 &&
+            avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
             channels = 2;
             s->output = DCA_STEREO;
             avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+
+            /* Stereo downmix coefficients
+             *
+             * The decoder can only downmix to 2-channel, so we need to ensure
+             * embedded downmix coefficients are actually targeting 2-channel.
+             */
+            if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||
+                                    s->core_downmix_amode == DCA_STEREO_TOTAL)) {
+                int sign, code;
+                for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
+                    sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1;
+                    code = s->core_downmix_codes[i][0] & 0x0FF;
+                    s->downmix_coef[i][0] = (!code ? 0.0f :
+                                             sign * dca_dmixtable[code - 1]);
+                    sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1;
+                    code = s->core_downmix_codes[i][1] & 0x0FF;
+                    s->downmix_coef[i][1] = (!code ? 0.0f :
+                                             sign * dca_dmixtable[code - 1]);
+                }
+            } else {
+                int am = s->amode & DCA_CHANNEL_MASK;
+                if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) {
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "Invalid channel mode %d\n", am);
+                    return AVERROR_INVALIDDATA;
+                }
+                if (s->prim_channels + !!s->lfe >
+                    FF_ARRAY_ELEMS(dca_default_coeffs[0])) {
+                    avpriv_request_sample(s->avctx, "Downmixing %d channels",
+                                          s->prim_channels + !!s->lfe);
+                    return AVERROR_PATCHWELCOME;
+                }
+                for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
+                    s->downmix_coef[i][0] = dca_default_coeffs[am][i][0];
+                    s->downmix_coef[i][1] = dca_default_coeffs[am][i][1];
+                }
+            }
+            av_dlog(s->avctx, "Stereo downmix coeffs:\n");
+            for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
+                av_dlog(s->avctx, "L, input channel %d = %f\n", i,
+                        s->downmix_coef[i][0]);
+                av_dlog(s->avctx, "R, input channel %d = %f\n", i,
+                        s->downmix_coef[i][1]);
+            }
+            av_dlog(s->avctx, "\n");
         }
     } else {
         av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);
@@ -1847,17 +1945,17 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
     avctx->channels = channels;
 
     /* get output buffer */
-    s->frame.nb_samples = 256 * (s->sample_blocks / 8);
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 256 * (s->sample_blocks / 8);
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples_flt = (float  **) s->frame.extended_data;
+    samples_flt = (float **)frame->extended_data;
 
     /* allocate buffer for extra channels if downmixing */
     if (avctx->channels < full_channels) {
         ret = av_samples_get_buffer_size(NULL, full_channels - channels,
-                                         s->frame.nb_samples,
+                                         frame->nb_samples,
                                          avctx->sample_fmt, 0);
         if (ret < 0)
             return ret;
@@ -1870,7 +1968,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
         ret = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,
                                      s->extra_channels_buffer,
                                      full_channels - channels,
-                                     s->frame.nb_samples, avctx->sample_fmt, 0);
+                                     frame->nb_samples, avctx->sample_fmt, 0);
         if (ret < 0)
             return ret;
     }
@@ -1902,8 +2000,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
     for (i = 0; i < 2 * s->lfe * 4; i++)
         s->lfe_data[i] = s->lfe_data[i + lfe_samples];
 
-    *got_frame_ptr    = 1;
-    *(AVFrame *) data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -1932,13 +2029,15 @@ static av_cold int dca_decode_init(AVCodecContext *avctx)
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     /* allow downmixing to stereo */
-    if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
-        avctx->request_channels == 2) {
-        avctx->channels = avctx->request_channels;
-    }
-
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->request_channels == 2)
+        avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    if (avctx->channels > 2 &&
+        avctx->request_channel_layout == AV_CH_LAYOUT_STEREO)
+        avctx->channels = 2;
 
     return 0;
 }
@@ -1960,17 +2059,30 @@ static const AVProfile profiles[] = {
     { FF_PROFILE_UNKNOWN },
 };
 
+static const AVOption options[] = {
+    { "disable_xch", "disable decoding of the XCh extension", offsetof(DCAContext, xch_disable), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_AUDIO_PARAM },
+    { NULL },
+};
+
+static const AVClass dca_decoder_class = {
+    .class_name = "DCA decoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_dca_decoder = {
     .name            = "dca",
+    .long_name       = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
     .type            = AVMEDIA_TYPE_AUDIO,
     .id              = AV_CODEC_ID_DTS,
     .priv_data_size  = sizeof(DCAContext),
     .init            = dca_decode_init,
     .decode          = dca_decode_frame,
     .close           = dca_decode_end,
-    .long_name       = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
     .capabilities    = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
     .sample_fmts     = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                        AV_SAMPLE_FMT_NONE },
     .profiles        = NULL_IF_CONFIG_SMALL(profiles),
+    .priv_class      = &dca_decoder_class,
 };
diff --git a/libavcodec/dcadsp.c b/libavcodec/dcadsp.c
index 14932e6..57d716e 100644
--- a/libavcodec/dcadsp.c
+++ b/libavcodec/dcadsp.c
@@ -20,6 +20,8 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/intreadwrite.h"
 #include "dcadsp.h"
 
 static void dca_lfe_fir_c(float *out, const float *in, const float *coefs,
@@ -44,8 +46,37 @@ static void dca_lfe_fir_c(float *out, const float *in, const float *coefs,
     }
 }
 
-void ff_dcadsp_init(DCADSPContext *s)
+static void dca_qmf_32_subbands(float samples_in[32][8], int sb_act,
+                                SynthFilterContext *synth, FFTContext *imdct,
+                                float synth_buf_ptr[512],
+                                int *synth_buf_offset, float synth_buf2[32],
+                                const float window[512], float *samples_out,
+                                float raXin[32], float scale)
+{
+    int i;
+    int subindex;
+
+    for (i = sb_act; i < 32; i++)
+        raXin[i] = 0.0;
+
+    /* Reconstructed channel sample index */
+    for (subindex = 0; subindex < 8; subindex++) {
+        /* Load in one sample from each subband and clear inactive subbands */
+        for (i = 0; i < sb_act; i++) {
+            unsigned sign = (i - 1) & 2;
+            uint32_t v    = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30;
+            AV_WN32A(&raXin[i], v);
+        }
+
+        synth->synth_filter_float(imdct, synth_buf_ptr, synth_buf_offset,
+                                  synth_buf2, window, samples_out, raXin, scale);
+        samples_out += 32;
+    }
+}
+
+av_cold void ff_dcadsp_init(DCADSPContext *s)
 {
     s->lfe_fir = dca_lfe_fir_c;
+    s->qmf_32_subbands = dca_qmf_32_subbands;
     if (ARCH_ARM) ff_dcadsp_init_arm(s);
 }
diff --git a/libavcodec/dcadsp.h b/libavcodec/dcadsp.h
index 3c6f1f9..ec88be7 100644
--- a/libavcodec/dcadsp.h
+++ b/libavcodec/dcadsp.h
@@ -19,9 +19,18 @@
 #ifndef AVCODEC_DCADSP_H
 #define AVCODEC_DCADSP_H
 
+#include "avfft.h"
+#include "synth_filter.h"
+
 typedef struct DCADSPContext {
     void (*lfe_fir)(float *out, const float *in, const float *coefs,
                     int decifactor, float scale);
+    void (*qmf_32_subbands)(float samples_in[32][8], int sb_act,
+                            SynthFilterContext *synth, FFTContext *imdct,
+                            float synth_buf_ptr[512],
+                            int *synth_buf_offset, float synth_buf2[32],
+                            const float window[512], float *samples_out,
+                            float raXin[32], float scale);
 } DCADSPContext;
 
 void ff_dcadsp_init(DCADSPContext *s);
diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c
index 3ce0270..d71f7a3 100644
--- a/libavcodec/dct-test.c
+++ b/libavcodec/dct-test.c
@@ -39,6 +39,7 @@
 #include "libavutil/lfg.h"
 #include "libavutil/time.h"
 
+#include "dct.h"
 #include "simple_idct.h"
 #include "aandcttab.h"
 #include "faandct.h"
@@ -46,27 +47,23 @@
 #include "x86/idct_xvid.h"
 #include "dctref.h"
 
-#undef printf
-
 // BFIN
-void ff_bfin_idct(DCTELEM *block);
-void ff_bfin_fdct(DCTELEM *block);
+void ff_bfin_idct(int16_t *block);
+void ff_bfin_fdct(int16_t *block);
 
 // ALTIVEC
-void ff_fdct_altivec(DCTELEM *block);
+void ff_fdct_altivec(int16_t *block);
 
 // ARM
-void ff_j_rev_dct_arm(DCTELEM *data);
-void ff_simple_idct_arm(DCTELEM *data);
-void ff_simple_idct_armv5te(DCTELEM *data);
-void ff_simple_idct_armv6(DCTELEM *data);
-void ff_simple_idct_neon(DCTELEM *data);
-
-void ff_simple_idct_axp(DCTELEM *data);
+void ff_j_rev_dct_arm(int16_t *data);
+void ff_simple_idct_arm(int16_t *data);
+void ff_simple_idct_armv5te(int16_t *data);
+void ff_simple_idct_armv6(int16_t *data);
+void ff_simple_idct_neon(int16_t *data);
 
 struct algo {
     const char *name;
-    void (*func)(DCTELEM *block);
+    void (*func)(int16_t *block);
     enum formattag { NO_PERM, MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM,
                      SSE2_PERM, PARTTRANS_PERM } format;
     int mm_support;
@@ -83,7 +80,11 @@ static const struct algo fdct_tab[] = {
 
 #if HAVE_MMX_INLINE
     { "MMX",            ff_fdct_mmx,           NO_PERM,   AV_CPU_FLAG_MMX     },
+#endif
+#if HAVE_MMXEXT_INLINE
     { "MMXEXT",         ff_fdct_mmxext,        NO_PERM,   AV_CPU_FLAG_MMXEXT  },
+#endif
+#if HAVE_SSE2_INLINE
     { "SSE2",           ff_fdct_sse2,          NO_PERM,   AV_CPU_FLAG_SSE2    },
 #endif
 
@@ -107,7 +108,11 @@ static const struct algo idct_tab[] = {
 #if HAVE_MMX_INLINE
     { "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 },
+#endif
+#if HAVE_MMXEXT_INLINE
     { "XVID-MMXEXT",    ff_idct_xvid_mmxext,   NO_PERM,   AV_CPU_FLAG_MMXEXT, 1 },
+#endif
+#if HAVE_SSE2_INLINE
     { "XVID-SSE2",      ff_idct_xvid_sse2,     SSE2_PERM, AV_CPU_FLAG_SSE2, 1 },
 #endif
 
@@ -129,10 +134,6 @@ static const struct algo idct_tab[] = {
     { "SIMPLE-NEON",    ff_simple_idct_neon, PARTTRANS_PERM, AV_CPU_FLAG_NEON },
 #endif
 
-#if ARCH_ALPHA
-    { "SIMPLE-ALPHA",   ff_simple_idct_axp,    NO_PERM },
-#endif
-
     { 0 }
 };
 
@@ -166,10 +167,10 @@ static void idct_mmx_init(void)
     }
 }
 
-DECLARE_ALIGNED(16, static DCTELEM, block)[64];
-DECLARE_ALIGNED(8,  static DCTELEM, block1)[64];
+DECLARE_ALIGNED(16, static int16_t, block)[64];
+DECLARE_ALIGNED(8,  static int16_t, block1)[64];
 
-static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng)
+static void init_block(int16_t block[64], int test, int is_idct, AVLFG *prng)
 {
     int i, j;
 
@@ -197,7 +198,7 @@ static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng)
     }
 }
 
-static void permute(DCTELEM dst[64], const DCTELEM src[64], int perm)
+static void permute(int16_t dst[64], const int16_t src[64], int perm)
 {
     int i;
 
@@ -221,7 +222,7 @@ static void permute(DCTELEM dst[64], const DCTELEM src[64], int perm)
 
 static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
 {
-    void (*ref)(DCTELEM *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
+    void (*ref)(int16_t *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
     int it, i, scale;
     int err_inf, v;
     int64_t err2, ti, ti1, it1, err_sum = 0;
@@ -522,5 +523,8 @@ int main(int argc, char **argv)
             }
     }
 
-    return err;
+    if (err)
+        printf("Error: %d.\n", err);
+
+    return !!err;
 }
diff --git a/libavcodec/dct.c b/libavcodec/dct.c
index 0128c7d..4dbbff8 100644
--- a/libavcodec/dct.c
+++ b/libavcodec/dct.c
@@ -40,7 +40,7 @@
 /* cos((M_PI * x / (2 * n)) */
 #define COS(s, n, x) (s->costab[x])
 
-static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data)
+static void dst_calc_I_c(DCTContext *ctx, FFTSample *data)
 {
     int n = 1 << ctx->nbits;
     int i;
@@ -70,7 +70,7 @@ static void ff_dst_calc_I_c(DCTContext *ctx, FFTSample *data)
     data[n - 1] = 0;
 }
 
-static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data)
+static void dct_calc_I_c(DCTContext *ctx, FFTSample *data)
 {
     int n = 1 << ctx->nbits;
     int i;
@@ -100,7 +100,7 @@ static void ff_dct_calc_I_c(DCTContext *ctx, FFTSample *data)
         data[i] = data[i - 2] - data[i];
 }
 
-static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data)
+static void dct_calc_III_c(DCTContext *ctx, FFTSample *data)
 {
     int n = 1 << ctx->nbits;
     int i;
@@ -133,7 +133,7 @@ static void ff_dct_calc_III_c(DCTContext *ctx, FFTSample *data)
     }
 }
 
-static void ff_dct_calc_II_c(DCTContext *ctx, FFTSample *data)
+static void dct_calc_II_c(DCTContext *ctx, FFTSample *data)
 {
     int n = 1 << ctx->nbits;
     int i;
@@ -201,10 +201,10 @@ av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)
             s->csc2[i] = 0.5 / sin((M_PI / (2 * n) * (2 * i + 1)));
 
         switch (inverse) {
-        case DCT_I  : s->dct_calc = ff_dct_calc_I_c;   break;
-        case DCT_II : s->dct_calc = ff_dct_calc_II_c;  break;
-        case DCT_III: s->dct_calc = ff_dct_calc_III_c; break;
-        case DST_I  : s->dct_calc = ff_dst_calc_I_c;   break;
+        case DCT_I  : s->dct_calc = dct_calc_I_c;   break;
+        case DCT_II : s->dct_calc = dct_calc_II_c;  break;
+        case DCT_III: s->dct_calc = dct_calc_III_c; break;
+        case DST_I  : s->dct_calc = dst_calc_I_c;   break;
         }
     }
 
diff --git a/libavcodec/dct.h b/libavcodec/dct.h
index 905cc01..3de10b9 100644
--- a/libavcodec/dct.h
+++ b/libavcodec/dct.h
@@ -24,6 +24,8 @@
 #ifndef AVCODEC_DCT_H
 #define AVCODEC_DCT_H
 
+#include <stdint.h>
+
 #include "rdft.h"
 
 struct DCTContext {
@@ -49,4 +51,17 @@ void ff_dct_end (DCTContext *s);
 
 void ff_dct_init_x86(DCTContext *s);
 
+void ff_fdct_ifast(int16_t *data);
+void ff_fdct_ifast248(int16_t *data);
+void ff_jpeg_fdct_islow_8(int16_t *data);
+void ff_jpeg_fdct_islow_10(int16_t *data);
+void ff_fdct248_islow_8(int16_t *data);
+void ff_fdct248_islow_10(int16_t *data);
+
+void ff_j_rev_dct(int16_t *data);
+
+void ff_fdct_mmx(int16_t *block);
+void ff_fdct_mmxext(int16_t *block);
+void ff_fdct_sse2(int16_t *block);
+
 #endif /* AVCODEC_DCT_H */
diff --git a/libavcodec/dct32_fixed.c b/libavcodec/dct32_fixed.c
index 7eb9dc1..64efe8b 100644
--- a/libavcodec/dct32_fixed.c
+++ b/libavcodec/dct32_fixed.c
@@ -17,4 +17,4 @@
  */
 
 #define DCT32_FLOAT 0
-#include "dct32.c"
+#include "dct32_template.c"
diff --git a/libavcodec/dct32_float.c b/libavcodec/dct32_float.c
index 727ec3c..ef37ce9 100644
--- a/libavcodec/dct32_float.c
+++ b/libavcodec/dct32_float.c
@@ -17,4 +17,4 @@
  */
 
 #define DCT32_FLOAT 1
-#include "dct32.c"
+#include "dct32_template.c"
diff --git a/libavcodec/dct32.c b/libavcodec/dct32_template.c
similarity index 100%
rename from libavcodec/dct32.c
rename to libavcodec/dct32_template.c
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 332a53e..ab65fdc 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -28,8 +28,6 @@
 #include "libavutil/mem.h"
 
 typedef struct DfaContext {
-    AVFrame pic;
-
     uint32_t pal[256];
     uint8_t *frame_buf;
 } DfaContext;
@@ -286,9 +284,26 @@ static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height
     return 0;
 }
 
-static int decode_unk6(GetByteContext *gb, uint8_t *frame, int width, int height)
+static int decode_tdlt(GetByteContext *gb, uint8_t *frame, int width, int height)
 {
-    return AVERROR_PATCHWELCOME;
+    const uint8_t *frame_end = frame + width * height;
+    int segments = bytestream2_get_le32(gb);
+    int skip, copy;
+
+    while (segments--) {
+        if (bytestream2_get_bytes_left(gb) < 2)
+            return AVERROR_INVALIDDATA;
+        copy = bytestream2_get_byteu(gb) * 2;
+        skip = bytestream2_get_byteu(gb) * 2;
+        if (frame_end - frame < copy + skip ||
+            bytestream2_get_bytes_left(gb) < copy)
+            return AVERROR_INVALIDDATA;
+        frame += skip;
+        bytestream2_get_buffer(gb, frame, copy);
+        frame += copy;
+    }
+
+    return 0;
 }
 
 static int decode_blck(GetByteContext *gb, uint8_t *frame, int width, int height)
@@ -302,17 +317,18 @@ typedef int (*chunk_decoder)(GetByteContext *gb, uint8_t *frame, int width, int
 
 static const chunk_decoder decoder[8] = {
     decode_copy, decode_tsw1, decode_bdlt, decode_wdlt,
-    decode_unk6, decode_dsw1, decode_blck, decode_dds1,
+    decode_tdlt, decode_dsw1, decode_blck, decode_dds1,
 };
 
 static const char* chunk_name[8] = {
-    "COPY", "TSW1", "BDLT", "WDLT", "????", "DSW1", "BLCK", "DDS1"
+    "COPY", "TSW1", "BDLT", "WDLT", "TDLT", "DSW1", "BLCK", "DDS1"
 };
 
 static int dfa_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     DfaContext *s = avctx->priv_data;
     GetByteContext gb;
     const uint8_t *buf = avpkt->data;
@@ -321,10 +337,7 @@ static int dfa_decode_frame(AVCodecContext *avctx,
     int ret;
     int i, pal_elems;
 
-    if (s->pic.data[0])
-        avctx->release_buffer(avctx, &s->pic);
-
-    if ((ret = ff_get_buffer(avctx, &s->pic))) {
+    if ((ret = ff_get_buffer(avctx, frame, 0))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -342,7 +355,7 @@ static int dfa_decode_frame(AVCodecContext *avctx,
                 s->pal[i] = bytestream2_get_be24(&gb) << 2;
                 s->pal[i] |= (s->pal[i] >> 6) & 0x333;
             }
-            s->pic.palette_has_changed = 1;
+            frame->palette_has_changed = 1;
         } else if (chunk_type <= 9) {
             if (decoder[chunk_type - 2](&gb, s->frame_buf, avctx->width, avctx->height)) {
                 av_log(avctx, AV_LOG_ERROR, "Error decoding %s chunk\n",
@@ -357,16 +370,15 @@ static int dfa_decode_frame(AVCodecContext *avctx,
     }
 
     buf = s->frame_buf;
-    dst = s->pic.data[0];
+    dst = frame->data[0];
     for (i = 0; i < avctx->height; i++) {
         memcpy(dst, buf, avctx->width);
-        dst += s->pic.linesize[0];
+        dst += frame->linesize[0];
         buf += avctx->width;
     }
-    memcpy(s->pic.data[1], s->pal, sizeof(s->pal));
+    memcpy(frame->data[1], s->pal, sizeof(s->pal));
 
     *got_frame = 1;
-    *(AVFrame*)data = s->pic;
 
     return avpkt->size;
 }
@@ -375,9 +387,6 @@ static av_cold int dfa_decode_end(AVCodecContext *avctx)
 {
     DfaContext *s = avctx->priv_data;
 
-    if (s->pic.data[0])
-        avctx->release_buffer(avctx, &s->pic);
-
     av_freep(&s->frame_buf);
 
     return 0;
@@ -385,6 +394,7 @@ static av_cold int dfa_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_dfa_decoder = {
     .name           = "dfa",
+    .long_name      = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DFA,
     .priv_data_size = sizeof(DfaContext),
@@ -392,5 +402,4 @@ AVCodec ff_dfa_decoder = {
     .close          = dfa_decode_end,
     .decode         = dfa_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
 };
diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c
index e11fea7..f0fb85d 100644
--- a/libavcodec/dirac.c
+++ b/libavcodec/dirac.c
@@ -29,6 +29,7 @@
 #include "dirac.h"
 #include "avcodec.h"
 #include "golomb.h"
+#include "internal.h"
 #include "mpeg12data.h"
 
 // defaults for source parameters
@@ -311,11 +312,10 @@ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
     if (ret = parse_source_parameters(avctx, gb, source))
         return ret;
 
-    if (ret = av_image_check_size(source->width, source->height, 0, avctx))
+    ret = ff_set_dimensions(avctx, source->width, source->height);
+    if (ret < 0)
         return ret;
 
-    avcodec_set_dimensions(avctx, source->width, source->height);
-
     /* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames
      * currently only used to signal field coding */
     picture_coding_mode = svq3_get_ue_golomb(gb);
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 7cc17c4..5c29b3e 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -22,9 +22,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define TRACE
-//#define DEBUG
-
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "get_bits.h"
@@ -34,7 +31,6 @@
 
 typedef struct DNXHDContext {
     AVCodecContext *avctx;
-    AVFrame picture;
     GetBitContext gb;
     int cid;                            ///< compression id
     unsigned int width, height;
@@ -44,28 +40,25 @@ typedef struct DNXHDContext {
     VLC ac_vlc, dc_vlc, run_vlc;
     int last_dc[3];
     DSPContext dsp;
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[8][64];
+    DECLARE_ALIGNED(16, int16_t, blocks)[8][64];
     ScanTable scantable;
     const CIDEntry *cid_table;
     int bit_depth; // 8, 10 or 0 if not initialized at all.
-    void (*decode_dct_block)(struct DNXHDContext *ctx, DCTELEM *block,
+    void (*decode_dct_block)(struct DNXHDContext *ctx, int16_t *block,
                              int n, int qscale);
 } DNXHDContext;
 
 #define DNXHD_VLC_BITS 9
 #define DNXHD_DC_VLC_BITS 7
 
-static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, DCTELEM *block, int n, int qscale);
-static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, DCTELEM *block, int n, int qscale);
+static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block, int n, int qscale);
+static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block, int n, int qscale);
 
 static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
 {
     DNXHDContext *ctx = avctx->priv_data;
 
     ctx->avctx = avctx;
-    avctx->coded_frame = &ctx->picture;
-    ctx->picture.type = AV_PICTURE_TYPE_I;
-    ctx->picture.key_frame = 1;
     return 0;
 }
 
@@ -100,7 +93,8 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid)
     return 0;
 }
 
-static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field)
+static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
+                               const uint8_t *buf, int buf_size, int first_field)
 {
     static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 };
     int i, cid;
@@ -114,8 +108,8 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si
     }
     if (buf[5] & 2) { /* interlaced */
         ctx->cur_field = buf[5] & 1;
-        ctx->picture.interlaced_frame = 1;
-        ctx->picture.top_field_first = first_field ^ ctx->cur_field;
+        frame->interlaced_frame = 1;
+        frame->top_field_first  = first_field ^ ctx->cur_field;
         av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field);
     }
 
@@ -158,11 +152,11 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si
 
     av_dlog(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height);
 
-    if ((ctx->height+15)>>4 == ctx->mb_height && ctx->picture.interlaced_frame)
+    if ((ctx->height+15)>>4 == ctx->mb_height && frame->interlaced_frame)
         ctx->height <<= 1;
 
     if (ctx->mb_height > 68 ||
-        (ctx->mb_height<<ctx->picture.interlaced_frame) > (ctx->height+15)>>4) {
+        (ctx->mb_height << frame->interlaced_frame) > (ctx->height+15)>>4) {
         av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big: %d\n", ctx->mb_height);
         return -1;
     }
@@ -180,7 +174,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si
 }
 
 static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
-                                                    DCTELEM *block, int n,
+                                                    int16_t *block, int n,
                                                     int qscale,
                                                     int index_bits,
                                                     int level_bias,
@@ -250,23 +244,23 @@ static av_always_inline void dnxhd_decode_dct_block(DNXHDContext *ctx,
     CLOSE_READER(bs, &ctx->gb);
 }
 
-static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, DCTELEM *block,
+static void dnxhd_decode_dct_block_8(DNXHDContext *ctx, int16_t *block,
                                      int n, int qscale)
 {
     dnxhd_decode_dct_block(ctx, block, n, qscale, 4, 32, 6);
 }
 
-static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, DCTELEM *block,
+static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block,
                                       int n, int qscale)
 {
     dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4);
 }
 
-static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
+static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int y)
 {
     int shift1 = ctx->bit_depth == 10;
-    int dct_linesize_luma   = ctx->picture.linesize[0];
-    int dct_linesize_chroma = ctx->picture.linesize[1];
+    int dct_linesize_luma   = frame->linesize[0];
+    int dct_linesize_chroma = frame->linesize[1];
     uint8_t *dest_y, *dest_u, *dest_v;
     int dct_y_offset, dct_x_offset;
     int qscale, i;
@@ -279,19 +273,19 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
         ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale);
     }
 
-    if (ctx->picture.interlaced_frame) {
+    if (frame->interlaced_frame) {
         dct_linesize_luma   <<= 1;
         dct_linesize_chroma <<= 1;
     }
 
-    dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma)   << 4) + (x << (4 + shift1));
-    dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
-    dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
+    dest_y = frame->data[0] + ((y * dct_linesize_luma)   << 4) + (x << (4 + shift1));
+    dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
+    dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
 
     if (ctx->cur_field) {
-        dest_y += ctx->picture.linesize[0];
-        dest_u += ctx->picture.linesize[1];
-        dest_v += ctx->picture.linesize[2];
+        dest_y += frame->linesize[0];
+        dest_u += frame->linesize[1];
+        dest_v += frame->linesize[2];
     }
 
     dct_y_offset = dct_linesize_luma << 3;
@@ -312,7 +306,8 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
     return 0;
 }
 
-static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size)
+static int dnxhd_decode_macroblocks(DNXHDContext *ctx, AVFrame *frame,
+                                    const uint8_t *buf, int buf_size)
 {
     int x, y;
     for (y = 0; y < ctx->mb_height; y++) {
@@ -322,7 +317,7 @@ static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int b
         init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3);
         for (x = 0; x < ctx->mb_width; x++) {
             //START_TIMER;
-            dnxhd_decode_macroblock(ctx, x, y);
+            dnxhd_decode_macroblock(ctx, frame, x, y);
             //STOP_TIMER("decode macroblock");
         }
     }
@@ -337,11 +332,12 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     DNXHDContext *ctx = avctx->priv_data;
     AVFrame *picture = data;
     int first_field = 1;
+    int ret;
 
     av_dlog(avctx, "frame size %d\n", buf_size);
 
  decode_coding_unit:
-    if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0)
+    if (dnxhd_decode_header(ctx, picture, buf, buf_size, first_field) < 0)
         return -1;
 
     if ((avctx->width || avctx->height) &&
@@ -351,29 +347,28 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         first_field = 1;
     }
 
-    if (av_image_check_size(ctx->width, ctx->height, 0, avctx))
-        return -1;
-    avcodec_set_dimensions(avctx, ctx->width, ctx->height);
+    ret = ff_set_dimensions(avctx, ctx->width, ctx->height);
+    if (ret < 0)
+        return ret;
 
     if (first_field) {
-        if (ctx->picture.data[0])
-            avctx->release_buffer(avctx, &ctx->picture);
-        if (ff_get_buffer(avctx, &ctx->picture) < 0) {
+        if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
+        picture->pict_type = AV_PICTURE_TYPE_I;
+        picture->key_frame = 1;
     }
 
-    dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280);
+    dnxhd_decode_macroblocks(ctx, picture, buf + 0x280, buf_size - 0x280);
 
-    if (first_field && ctx->picture.interlaced_frame) {
+    if (first_field && picture->interlaced_frame) {
         buf      += ctx->cid_table->coding_unit_size;
         buf_size -= ctx->cid_table->coding_unit_size;
         first_field = 0;
         goto decode_coding_unit;
     }
 
-    *picture = ctx->picture;
     *got_frame = 1;
     return buf_size;
 }
@@ -382,8 +377,6 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx)
 {
     DNXHDContext *ctx = avctx->priv_data;
 
-    if (ctx->picture.data[0])
-        avctx->release_buffer(avctx, &ctx->picture);
     ff_free_vlc(&ctx->ac_vlc);
     ff_free_vlc(&ctx->dc_vlc);
     ff_free_vlc(&ctx->run_vlc);
@@ -392,6 +385,7 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx)
 
 AVCodec ff_dnxhd_decoder = {
     .name           = "dnxhd",
+    .long_name      = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DNXHD,
     .priv_data_size = sizeof(DNXHDContext),
@@ -399,5 +393,4 @@ AVCodec ff_dnxhd_decoder = {
     .close          = dnxhd_decode_close,
     .decode         = dnxhd_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
 };
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 97e0fed..5eef57e 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -23,9 +23,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
 #define RC_VARIANCE 1 // use variance or ssd for fast rc
 
+#include "libavutil/attributes.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "dsputil.h"
@@ -44,7 +45,7 @@ static const AVClass class = { "dnxhd", av_default_item_name, options, LIBAVUTIL
 
 #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(int16_t *restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
     for (i = 0; i < 4; i++) {
@@ -61,7 +62,7 @@ static void dnxhd_8bit_get_pixels_8x4_sym(DCTELEM *restrict block, const uint8_t
     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(int16_t *restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
 
@@ -73,7 +74,7 @@ static av_always_inline void dnxhd_10bit_get_pixels_8x4_sym(DCTELEM *restrict bl
     }
 }
 
-static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block,
+static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, int16_t *block,
                                     int n, int qscale, int *overflow)
 {
     const uint8_t *scantable= ctx->intra_scantable.scantable;
@@ -99,7 +100,7 @@ static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block,
     return last_non_zero;
 }
 
-static int dnxhd_init_vlc(DNXHDEncContext *ctx)
+static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx)
 {
     int i, j, level, run;
     int max_level = 1<<(ctx->cid_table->bit_depth+2);
@@ -154,7 +155,7 @@ static int dnxhd_init_vlc(DNXHDEncContext *ctx)
     return -1;
 }
 
-static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
+static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
 {
     // init first elem to 1 to avoid div by 0 in convert_matrix
     uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t*
@@ -213,7 +214,7 @@ static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
     return -1;
 }
 
-static int dnxhd_init_rc(DNXHDEncContext *ctx)
+static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx)
 {
     FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail);
     if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)
@@ -227,7 +228,7 @@ static int dnxhd_init_rc(DNXHDEncContext *ctx)
     return -1;
 }
 
-static int dnxhd_encode_init(AVCodecContext *avctx)
+static av_cold int dnxhd_encode_init(AVCodecContext *avctx)
 {
     DNXHDEncContext *ctx = avctx->priv_data;
     int i, index, bit_depth;
@@ -306,9 +307,12 @@ static int dnxhd_encode_init(AVCodecContext *avctx)
     FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits,    ctx->m.mb_num   *sizeof(uint16_t), fail);
     FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale,  ctx->m.mb_num   *sizeof(uint8_t),  fail);
 
-    ctx->frame.key_frame = 1;
-    ctx->frame.pict_type = AV_PICTURE_TYPE_I;
-    ctx->m.avctx->coded_frame = &ctx->frame;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->key_frame = 1;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
 
     if (avctx->thread_count > MAX_THREADS) {
         av_log(avctx, AV_LOG_ERROR, "too many threads\n");
@@ -370,7 +374,7 @@ static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff)
              (ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1)));
 }
 
-static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, DCTELEM *block, int last_index, int n)
+static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, int16_t *block, int last_index, int n)
 {
     int last_non_zero = 0;
     int slevel, i, j;
@@ -393,7 +397,7 @@ static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, DCTELEM *b
     put_bits(&ctx->m.pb, ctx->vlc_bits[0], ctx->vlc_codes[0]); // EOB
 }
 
-static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *block, int n, int qscale, int last_index)
+static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, int16_t *block, int n, int qscale, int last_index)
 {
     const uint8_t *weight_matrix;
     int level;
@@ -434,7 +438,7 @@ static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *b
     }
 }
 
-static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
+static av_always_inline int dnxhd_ssd_block(int16_t *qblock, int16_t *block)
 {
     int score = 0;
     int i;
@@ -443,7 +447,7 @@ static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
     return score;
 }
 
-static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index)
+static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, int16_t *block, int last_index)
 {
     int last_non_zero = 0;
     int bits = 0;
@@ -512,7 +516,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, i
     DNXHDEncContext *ctx = avctx->priv_data;
     int mb_y = jobnr, mb_x;
     int qscale = ctx->qscale;
-    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+    LOCAL_ALIGNED_16(int16_t, block, [64]);
     ctx = ctx->thread[threadnr];
 
     ctx->m.last_dc[0] =
@@ -529,7 +533,7 @@ static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, i
         dnxhd_get_blocks(ctx, mb_x, mb_y);
 
         for (i = 0; i < 8; i++) {
-            DCTELEM *src_block = ctx->blocks[i];
+            int16_t *src_block = ctx->blocks[i];
             int overflow, nbits, diff, last_index;
             int n = dnxhd_switch_matrix(ctx, i);
 
@@ -578,7 +582,7 @@ static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg, int jobnr, int
         dnxhd_get_blocks(ctx, mb_x, mb_y);
 
         for (i = 0; i < 8; i++) {
-            DCTELEM *block = ctx->blocks[i];
+            int16_t *block = ctx->blocks[i];
             int overflow, n = dnxhd_switch_matrix(ctx, i);
             int last_index = ctx->m.dct_quantize(&ctx->m, block, i,
                                                  qscale, &overflow);
@@ -907,19 +911,14 @@ static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
 {
     int i;
 
-    for (i = 0; i < 3; i++) {
-        ctx->frame.data[i]     = frame->data[i];
-        ctx->frame.linesize[i] = frame->linesize[i];
-    }
-
     for (i = 0; i < ctx->m.avctx->thread_count; i++) {
-        ctx->thread[i]->m.linesize    = ctx->frame.linesize[0]<<ctx->interlaced;
-        ctx->thread[i]->m.uvlinesize  = ctx->frame.linesize[1]<<ctx->interlaced;
+        ctx->thread[i]->m.linesize    = frame->linesize[0] << ctx->interlaced;
+        ctx->thread[i]->m.uvlinesize  = frame->linesize[1] << ctx->interlaced;
         ctx->thread[i]->dct_y_offset  = ctx->m.linesize  *8;
         ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
     }
 
-    ctx->frame.interlaced_frame = frame->interlaced_frame;
+    ctx->m.avctx->coded_frame->interlaced_frame = frame->interlaced_frame;
     ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
 }
 
@@ -941,9 +940,9 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 
  encode_coding_unit:
     for (i = 0; i < 3; i++) {
-        ctx->src[i] = ctx->frame.data[i];
+        ctx->src[i] = frame->data[i];
         if (ctx->interlaced && ctx->cur_field)
-            ctx->src[i] += ctx->frame.linesize[i];
+            ctx->src[i] += frame->linesize[i];
     }
 
     dnxhd_write_header(avctx, buf);
@@ -981,14 +980,14 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
         goto encode_coding_unit;
     }
 
-    ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA;
+    avctx->coded_frame->quality = ctx->qscale * FF_QP2LAMBDA;
 
     pkt->flags |= AV_PKT_FLAG_KEY;
     *got_packet = 1;
     return 0;
 }
 
-static int dnxhd_encode_end(AVCodecContext *avctx)
+static av_cold int dnxhd_encode_end(AVCodecContext *avctx)
 {
     DNXHDEncContext *ctx = avctx->priv_data;
     int max_level = 1<<(ctx->cid_table->bit_depth+2);
@@ -1014,11 +1013,14 @@ static int dnxhd_encode_end(AVCodecContext *avctx)
     for (i = 1; i < avctx->thread_count; i++)
         av_freep(&ctx->thread[i]);
 
+    av_frame_free(&avctx->coded_frame);
+
     return 0;
 }
 
 AVCodec ff_dnxhd_encoder = {
     .name           = "dnxhd",
+    .long_name      = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DNXHD,
     .priv_data_size = sizeof(DNXHDEncContext),
@@ -1029,6 +1031,5 @@ AVCodec ff_dnxhd_encoder = {
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P,
                                                   AV_PIX_FMT_YUV422P10,
                                                   AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
     .priv_class     = &class,
 };
diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h
index c74b9a7..232e334 100644
--- a/libavcodec/dnxhdenc.h
+++ b/libavcodec/dnxhdenc.h
@@ -43,7 +43,6 @@ typedef struct DNXHDEncContext {
     AVClass *class;
     MpegEncContext m; ///< Used for quantization dsp functions
 
-    AVFrame frame;
     int cid;
     const CIDEntry *cid_table;
     uint8_t *msip; ///< Macroblock Scan Indexes Payload
@@ -64,7 +63,7 @@ typedef struct DNXHDEncContext {
     int nitris_compat;
     unsigned min_padding;
 
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[8][64];
+    DECLARE_ALIGNED(16, int16_t, blocks)[8][64];
 
     int      (*qmatrix_c)     [64];
     int      (*qmatrix_l)     [64];
@@ -92,7 +91,7 @@ typedef struct DNXHDEncContext {
     RCCMPEntry *mb_cmp;
     RCEntry   (*mb_rc)[8160];
 
-    void (*get_pixels_8x4_sym)(DCTELEM * /*align 16*/, const uint8_t *, int);
+    void (*get_pixels_8x4_sym)(int16_t * /*align 16*/, const uint8_t *, int);
 } DNXHDEncContext;
 
 void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx);
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index 2726d35..5ab2331 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -44,7 +44,6 @@
 #include "mathops.h"
 
 typedef struct DPCMContext {
-    AVFrame frame;
     int16_t roq_square_array[256];
     int sample[2];                  ///< previous sample (for SOL_DPCM)
     const int8_t *sol_table;        ///< delta table for SOL_DPCM
@@ -163,9 +162,6 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
     else
         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -175,6 +171,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
 {
     int buf_size = avpkt->size;
     DPCMContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int out = 0, ret;
     int predictor[2];
     int ch = 0;
@@ -210,12 +207,12 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    s->frame.nb_samples = out / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = out / avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output_samples = (int16_t *)s->frame.data[0];
+    output_samples = (int16_t *)frame->data[0];
     samples_end = output_samples + out;
 
     switch(avctx->codec->id) {
@@ -295,7 +292,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
     }
     case AV_CODEC_ID_SOL_DPCM:
         if (avctx->codec_tag != 3) {
-            uint8_t *output_samples_u8 = s->frame.data[0],
+            uint8_t *output_samples_u8 = frame->data[0],
                     *samples_end_u8 = output_samples_u8 + out;
             while (output_samples_u8 < samples_end_u8) {
                 int n = bytestream2_get_byteu(&gb);
@@ -322,8 +319,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
         break;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
@@ -331,13 +327,13 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
 #define DPCM_DECODER(id_, name_, long_name_)                \
 AVCodec ff_ ## name_ ## _decoder = {                        \
     .name           = #name_,                               \
+    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
     .type           = AVMEDIA_TYPE_AUDIO,                   \
     .id             = id_,                                  \
     .priv_data_size = sizeof(DPCMContext),                  \
     .init           = dpcm_decode_init,                     \
     .decode         = dpcm_decode_frame,                    \
     .capabilities   = CODEC_CAP_DR1,                        \
-    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
 }
 
 DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 7c01bab..0dfa538 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -25,11 +25,6 @@
 #include "avcodec.h"
 #include "internal.h"
 
-typedef struct DPXContext {
-    AVFrame picture;
-} DPXContext;
-
-
 static unsigned int read32(const uint8_t **ptr, int is_big)
 {
     unsigned int temp;
@@ -58,14 +53,12 @@ static int decode_frame(AVCodecContext *avctx,
     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;
+    AVFrame *const p = data;
     uint8_t *ptr;
 
     unsigned int offset;
     int magic_num, endian;
-    int x, y;
+    int x, y, ret;
     int w, h, stride, bits_per_color, descriptor, elements, target_packet_size, source_packet_size;
 
     unsigned int rgbBuffer;
@@ -86,7 +79,7 @@ static int decode_frame(AVCodecContext *avctx,
         endian = 1;
     } else {
         av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     offset = read32(&buf, endian);
@@ -121,7 +114,7 @@ static int decode_frame(AVCodecContext *avctx,
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Unsupported descriptor %d\n", descriptor);
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
     switch (bits_per_color) {
@@ -151,18 +144,15 @@ static int decode_frame(AVCodecContext *avctx,
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Unsupported color depth : %d\n", bits_per_color);
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-    if (av_image_check_size(w, h, 0, avctx))
-        return -1;
-    if (w != avctx->width || h != avctx->height)
-        avcodec_set_dimensions(avctx, w, h);
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
+        return ret;
+
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     // Move pointer to offset from start of file
@@ -173,7 +163,7 @@ static int decode_frame(AVCodecContext *avctx,
 
     if (source_packet_size*avctx->width*avctx->height > buf_end - buf) {
         av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     switch (bits_per_color) {
         case 10:
@@ -212,37 +202,16 @@ static int decode_frame(AVCodecContext *avctx,
             break;
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    DPXContext *s = avctx->priv_data;
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-    return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    DPXContext *s = avctx->priv_data;
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_dpx_decoder = {
     .name           = "dpx",
+    .long_name      = NULL_IF_CONFIG_SMALL("DPX image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DPX,
-    .priv_data_size = sizeof(DPXContext),
-    .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("DPX image"),
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c
index d263161..2232933 100644
--- a/libavcodec/dpxenc.c
+++ b/libavcodec/dpxenc.c
@@ -26,7 +26,6 @@
 #include "internal.h"
 
 typedef struct DPXContext {
-    AVFrame picture;
     int big_endian;
     int bits_per_component;
     int descriptor;
@@ -36,7 +35,10 @@ static av_cold int encode_init(AVCodecContext *avctx)
 {
     DPXContext *s = avctx->priv_data;
 
-    avctx->coded_frame = &s->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     avctx->coded_frame->key_frame = 1;
 
@@ -173,18 +175,25 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
 AVCodec ff_dpx_encoder = {
     .name = "dpx",
+    .long_name = NULL_IF_CONFIG_SMALL("DPX image"),
     .type = AVMEDIA_TYPE_VIDEO,
     .id   = AV_CODEC_ID_DPX,
     .priv_data_size = sizeof(DPXContext),
     .init   = encode_init,
     .encode2 = encode_frame,
+    .close   = encode_close,
     .pix_fmts = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24,
         AV_PIX_FMT_RGBA,
         AV_PIX_FMT_RGB48LE,
         AV_PIX_FMT_RGB48BE,
         AV_PIX_FMT_NONE},
-    .long_name = NULL_IF_CONFIG_SMALL("DPX image"),
 };
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index 772fb8d..6e26c74 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -39,14 +39,13 @@ typedef enum CinVideoBitmapIndex {
 
 typedef struct CinVideoContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
     unsigned int bitmap_size;
     uint32_t palette[256];
     uint8_t *bitmap_table[3];
 } CinVideoContext;
 
 typedef struct CinAudioContext {
-    AVFrame frame;
     int initial_decode_frame;
     int delta;
 } CinAudioContext;
@@ -97,7 +96,9 @@ static av_cold int cinvideo_decode_init(AVCodecContext *avctx)
     cin->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    cin->frame.data[0] = NULL;
+    cin->frame = av_frame_alloc();
+    if (!cin->frame)
+        return AVERROR(ENOMEM);
 
     cin->bitmap_size = avctx->width * avctx->height;
     for (i = 0; i < 3; ++i) {
@@ -296,25 +297,26 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
         break;
     }
 
-    cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((res = avctx->reget_buffer(avctx, &cin->frame)) < 0) {
+    if ((res = ff_reget_buffer(avctx, cin->frame)) < 0) {
         av_log(cin->avctx, AV_LOG_ERROR,
                "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
         return res;
     }
 
-    memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
-    cin->frame.palette_has_changed = 1;
+    memcpy(cin->frame->data[1], cin->palette, sizeof(cin->palette));
+    cin->frame->palette_has_changed = 1;
     for (y = 0; y < cin->avctx->height; ++y)
-        memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
+        memcpy(cin->frame->data[0] + (cin->avctx->height - 1 - y) * cin->frame->linesize[0],
                cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
                cin->avctx->width);
 
     FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP],
                       cin->bitmap_table[CIN_PRE_BMP]);
 
+    if ((res = av_frame_ref(data, cin->frame)) < 0)
+        return res;
+
     *got_frame = 1;
-    *(AVFrame *)data = cin->frame;
 
     return buf_size;
 }
@@ -324,8 +326,7 @@ static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
     CinVideoContext *cin = avctx->priv_data;
     int i;
 
-    if (cin->frame.data[0])
-        avctx->release_buffer(avctx, &cin->frame);
+    av_frame_free(&cin->frame);
 
     for (i = 0; i < 3; ++i)
         av_free(cin->bitmap_table[i]);
@@ -343,15 +344,13 @@ static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
     avctx->channels           = 1;
     avctx->channel_layout     = AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&cin->frame);
-    avctx->coded_frame = &cin->frame;
-
     return 0;
 }
 
 static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame         = data;
     const uint8_t *buf     = avpkt->data;
     CinAudioContext *cin   = avctx->priv_data;
     const uint8_t *buf_end = buf + avpkt->size;
@@ -359,12 +358,12 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
     int delta, ret;
 
     /* get output buffer */
-    cin->frame.nb_samples = avpkt->size - cin->initial_decode_frame;
-    if ((ret = ff_get_buffer(avctx, &cin->frame)) < 0) {
+    frame->nb_samples = avpkt->size - cin->initial_decode_frame;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)cin->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     delta = cin->delta;
     if (cin->initial_decode_frame) {
@@ -380,14 +379,14 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
     }
     cin->delta = delta;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = cin->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
 
 AVCodec ff_dsicinvideo_decoder = {
     .name           = "dsicinvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DSICINVIDEO,
     .priv_data_size = sizeof(CinVideoContext),
@@ -395,16 +394,15 @@ AVCodec ff_dsicinvideo_decoder = {
     .close          = cinvideo_decode_end,
     .decode         = cinvideo_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
 };
 
 AVCodec ff_dsicinaudio_decoder = {
     .name           = "dsicinaudio",
+    .long_name      = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_DSICINAUDIO,
     .priv_data_size = sizeof(CinAudioContext),
     .init           = cinaudio_decode_init,
     .decode         = cinaudio_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
 };
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index 4696bc7..56207e8 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -27,25 +27,24 @@
  * DSP utils
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
+#include "copy_block.h"
+#include "dct.h"
 #include "dsputil.h"
 #include "simple_idct.h"
 #include "faandct.h"
 #include "faanidct.h"
+#include "imgconvert.h"
 #include "mathops.h"
 #include "mpegvideo.h"
 #include "config.h"
-#include "vorbis.h"
 
-uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP] = {0, };
 uint32_t ff_squareTbl[512] = {0, };
 
-#define BIT_DEPTH 9
-#include "dsputil_template.c"
-#undef BIT_DEPTH
-
-#define BIT_DEPTH 10
+#define BIT_DEPTH 16
 #include "dsputil_template.c"
 #undef BIT_DEPTH
 
@@ -56,17 +55,6 @@ uint32_t ff_squareTbl[512] = {0, };
 #define pb_7f (~0UL/255 * 0x7f)
 #define pb_80 (~0UL/255 * 0x80)
 
-const uint8_t ff_zigzag_direct[64] = {
-    0,   1,  8, 16,  9,  2,  3, 10,
-    17, 24, 32, 25, 18, 11,  4,  5,
-    12, 19, 26, 33, 40, 48, 41, 34,
-    27, 20, 13,  6,  7, 14, 21, 28,
-    35, 42, 49, 56, 57, 50, 43, 36,
-    29, 22, 15, 23, 30, 37, 44, 51,
-    58, 59, 52, 45, 38, 31, 39, 46,
-    53, 60, 61, 54, 47, 55, 62, 63
-};
-
 /* Specific zigzag scan for 248 idct. NOTE that unlike the
    specification, we interleave the fields */
 const uint8_t ff_zigzag248_direct[64] = {
@@ -80,9 +68,6 @@ const uint8_t ff_zigzag248_direct[64] = {
     53, 61, 54, 62, 39, 47, 55, 63,
 };
 
-/* not permutated inverse zigzag_direct + 1 for MMX quantizer */
-DECLARE_ALIGNED(16, uint16_t, ff_inv_zigzag_direct16)[64];
-
 const uint8_t ff_alternate_horizontal_scan[64] = {
     0,  1,   2,  3,  8,  9, 16, 17,
     10, 11,  4,  5,  6,  7, 15, 14,
@@ -119,7 +104,9 @@ static const uint8_t simple_mmx_permutation[64]={
 
 static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7};
 
-void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable){
+av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st,
+                               const uint8_t *src_scantable)
+{
     int i;
     int end;
 
@@ -140,8 +127,8 @@ void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_s
     }
 }
 
-void ff_init_scantable_permutation(uint8_t *idct_permutation,
-                                   int idct_permutation_type)
+av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation,
+                                           int idct_permutation_type)
 {
     int i;
 
@@ -337,7 +324,7 @@ static int sse16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
     return s;
 }
 
-static void diff_pixels_c(DCTELEM *restrict block, const uint8_t *s1,
+static void diff_pixels_c(int16_t *restrict block, const uint8_t *s1,
                           const uint8_t *s2, int stride){
     int i;
 
@@ -358,7 +345,7 @@ static void diff_pixels_c(DCTELEM *restrict block, const uint8_t *s1,
 }
 
 
-static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
+static void put_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels,
                                  int line_size)
 {
     int i;
@@ -379,7 +366,7 @@ static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
     }
 }
 
-static void put_signed_pixels_clamped_c(const DCTELEM *block,
+static void put_signed_pixels_clamped_c(const int16_t *block,
                                         uint8_t *restrict pixels,
                                         int line_size)
 {
@@ -400,7 +387,27 @@ static void put_signed_pixels_clamped_c(const DCTELEM *block,
     }
 }
 
-static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
+static void add_pixels8_c(uint8_t *restrict pixels,
+                          int16_t *block,
+                          int line_size)
+{
+    int i;
+
+    for(i=0;i<8;i++) {
+        pixels[0] += block[0];
+        pixels[1] += block[1];
+        pixels[2] += block[2];
+        pixels[3] += block[3];
+        pixels[4] += block[4];
+        pixels[5] += block[5];
+        pixels[6] += block[6];
+        pixels[7] += block[7];
+        pixels += line_size;
+        block += 8;
+    }
+}
+
+static void add_pixels_clamped_c(const int16_t *block, uint8_t *restrict pixels,
                                  int line_size)
 {
     int i;
@@ -420,7 +427,7 @@ static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
     }
 }
 
-static int sum_abs_dctelem_c(DCTELEM *block)
+static int sum_abs_dctelem_c(int16_t *block)
 {
     int sum=0, i;
     for(i=0; i<64; i++)
@@ -728,7 +735,7 @@ static inline void avg_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int
 
 #define QPEL_MC(r, OPNAME, RND, OP) \
 static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     for(i=0; i<h; i++)\
     {\
@@ -747,7 +754,7 @@ static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstS
 \
 static void OPNAME ## mpeg4_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
     const int w=8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     for(i=0; i<w; i++)\
     {\
@@ -774,7 +781,7 @@ static void OPNAME ## mpeg4_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstS
 }\
 \
 static void OPNAME ## mpeg4_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     \
     for(i=0; i<h; i++)\
@@ -801,7 +808,7 @@ static void OPNAME ## mpeg4_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dst
 }\
 \
 static void OPNAME ## mpeg4_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     const int w=16;\
     for(i=0; i<w; i++)\
@@ -844,23 +851,27 @@ static void OPNAME ## mpeg4_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dst
     }\
 }\
 \
-static void OPNAME ## qpel8_mc10_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t half[64];\
     put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8);\
     OPNAME ## pixels8_l2_8(dst, src, half, stride, stride, 8, 8);\
 }\
 \
-static void OPNAME ## qpel8_mc20_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc20_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## mpeg4_qpel8_h_lowpass(dst, src, stride, stride, 8);\
 }\
 \
-static void OPNAME ## qpel8_mc30_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc30_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t half[64];\
     put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8);\
     OPNAME ## pixels8_l2_8(dst, src+1, half, stride, stride, 8, 8);\
 }\
 \
-static void OPNAME ## qpel8_mc01_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc01_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t half[64];\
     copy_block9(full, src, 16, stride, 9);\
@@ -868,20 +879,23 @@ static void OPNAME ## qpel8_mc01_c(uint8_t *dst, uint8_t *src, int stride){\
     OPNAME ## pixels8_l2_8(dst, full, half, stride, 16, 8, 8);\
 }\
 \
-static void OPNAME ## qpel8_mc02_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc02_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     copy_block9(full, src, 16, stride, 9);\
     OPNAME ## mpeg4_qpel8_v_lowpass(dst, full, stride, 16);\
 }\
 \
-static void OPNAME ## qpel8_mc03_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc03_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t half[64];\
     copy_block9(full, src, 16, stride, 9);\
     put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16);\
     OPNAME ## pixels8_l2_8(dst, full+16, half, stride, 16, 8, 8);\
 }\
-void ff_ ## OPNAME ## qpel8_mc11_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel8_mc11_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfV[64];\
@@ -892,7 +906,8 @@ void ff_ ## OPNAME ## qpel8_mc11_old_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l4_8(dst, full, halfH, halfV, halfHV, stride, 16, 8, 8, 8, 8);\
 }\
-static void OPNAME ## qpel8_mc11_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc11_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfHV[64];\
@@ -902,7 +917,8 @@ static void OPNAME ## qpel8_mc11_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8);\
 }\
-void ff_ ## OPNAME ## qpel8_mc31_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel8_mc31_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfV[64];\
@@ -913,7 +929,8 @@ void ff_ ## OPNAME ## qpel8_mc31_old_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l4_8(dst, full+1, halfH, halfV, halfHV, stride, 16, 8, 8, 8, 8);\
 }\
-static void OPNAME ## qpel8_mc31_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc31_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfHV[64];\
@@ -923,7 +940,8 @@ static void OPNAME ## qpel8_mc31_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8);\
 }\
-void ff_ ## OPNAME ## qpel8_mc13_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel8_mc13_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfV[64];\
@@ -934,7 +952,8 @@ void ff_ ## OPNAME ## qpel8_mc13_old_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l4_8(dst, full+16, halfH+8, halfV, halfHV, stride, 16, 8, 8, 8, 8);\
 }\
-static void OPNAME ## qpel8_mc13_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc13_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfHV[64];\
@@ -944,7 +963,8 @@ static void OPNAME ## qpel8_mc13_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l2_8(dst, halfH+8, halfHV, stride, 8, 8, 8);\
 }\
-void ff_ ## OPNAME ## qpel8_mc33_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel8_mc33_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfV[64];\
@@ -955,7 +975,8 @@ void ff_ ## OPNAME ## qpel8_mc33_old_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l4_8(dst, full+17, halfH+8, halfV, halfHV, stride, 16, 8, 8, 8, 8);\
 }\
-static void OPNAME ## qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfHV[64];\
@@ -965,21 +986,24 @@ static void OPNAME ## qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l2_8(dst, halfH+8, halfHV, stride, 8, 8, 8);\
 }\
-static void OPNAME ## qpel8_mc21_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc21_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t halfH[72];\
     uint8_t halfHV[64];\
     put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l2_8(dst, halfH, halfHV, stride, 8, 8, 8);\
 }\
-static void OPNAME ## qpel8_mc23_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc23_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t halfH[72];\
     uint8_t halfHV[64];\
     put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l2_8(dst, halfH+8, halfHV, stride, 8, 8, 8);\
 }\
-void ff_ ## OPNAME ## qpel8_mc12_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel8_mc12_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfV[64];\
@@ -990,7 +1014,8 @@ void ff_ ## OPNAME ## qpel8_mc12_old_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);\
 }\
-static void OPNAME ## qpel8_mc12_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     copy_block9(full, src, 16, stride, 9);\
@@ -998,7 +1023,8 @@ static void OPNAME ## qpel8_mc12_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## pixels8_l2_8(halfH, halfH, full, 8, 8, 16, 9);\
     OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\
 }\
-void ff_ ## OPNAME ## qpel8_mc32_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel8_mc32_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     uint8_t halfV[64];\
@@ -1009,7 +1035,8 @@ void ff_ ## OPNAME ## qpel8_mc32_old_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
     OPNAME ## pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);\
 }\
-static void OPNAME ## qpel8_mc32_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc32_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[16*9];\
     uint8_t halfH[72];\
     copy_block9(full, src, 16, stride, 9);\
@@ -1017,29 +1044,34 @@ static void OPNAME ## qpel8_mc32_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## pixels8_l2_8(halfH, halfH, full+1, 8, 8, 16, 9);\
     OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\
 }\
-static void OPNAME ## qpel8_mc22_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel8_mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t halfH[72];\
     put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\
     OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\
 }\
 \
-static void OPNAME ## qpel16_mc10_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t half[256];\
     put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16);\
     OPNAME ## pixels16_l2_8(dst, src, half, stride, stride, 16, 16);\
 }\
 \
-static void OPNAME ## qpel16_mc20_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc20_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## mpeg4_qpel16_h_lowpass(dst, src, stride, stride, 16);\
 }\
 \
-static void OPNAME ## qpel16_mc30_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc30_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t half[256];\
     put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16);\
     OPNAME ## pixels16_l2_8(dst, src+1, half, stride, stride, 16, 16);\
 }\
 \
-static void OPNAME ## qpel16_mc01_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc01_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t half[256];\
     copy_block17(full, src, 24, stride, 17);\
@@ -1047,20 +1079,23 @@ static void OPNAME ## qpel16_mc01_c(uint8_t *dst, uint8_t *src, int stride){\
     OPNAME ## pixels16_l2_8(dst, full, half, stride, 24, 16, 16);\
 }\
 \
-static void OPNAME ## qpel16_mc02_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc02_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     copy_block17(full, src, 24, stride, 17);\
     OPNAME ## mpeg4_qpel16_v_lowpass(dst, full, stride, 24);\
 }\
 \
-static void OPNAME ## qpel16_mc03_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc03_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t half[256];\
     copy_block17(full, src, 24, stride, 17);\
     put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24);\
     OPNAME ## pixels16_l2_8(dst, full+24, half, stride, 24, 16, 16);\
 }\
-void ff_ ## OPNAME ## qpel16_mc11_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel16_mc11_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfV[256];\
@@ -1071,7 +1106,8 @@ void ff_ ## OPNAME ## qpel16_mc11_old_c(uint8_t *dst, uint8_t *src, int stride){
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l4_8(dst, full, halfH, halfV, halfHV, stride, 24, 16, 16, 16, 16);\
 }\
-static void OPNAME ## qpel16_mc11_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc11_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfHV[256];\
@@ -1081,7 +1117,8 @@ static void OPNAME ## qpel16_mc11_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16);\
 }\
-void ff_ ## OPNAME ## qpel16_mc31_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel16_mc31_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfV[256];\
@@ -1092,7 +1129,8 @@ void ff_ ## OPNAME ## qpel16_mc31_old_c(uint8_t *dst, uint8_t *src, int stride){
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l4_8(dst, full+1, halfH, halfV, halfHV, stride, 24, 16, 16, 16, 16);\
 }\
-static void OPNAME ## qpel16_mc31_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc31_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfHV[256];\
@@ -1102,7 +1140,8 @@ static void OPNAME ## qpel16_mc31_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16);\
 }\
-void ff_ ## OPNAME ## qpel16_mc13_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel16_mc13_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfV[256];\
@@ -1113,7 +1152,8 @@ void ff_ ## OPNAME ## qpel16_mc13_old_c(uint8_t *dst, uint8_t *src, int stride){
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l4_8(dst, full+24, halfH+16, halfV, halfHV, stride, 24, 16, 16, 16, 16);\
 }\
-static void OPNAME ## qpel16_mc13_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc13_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfHV[256];\
@@ -1123,7 +1163,8 @@ static void OPNAME ## qpel16_mc13_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l2_8(dst, halfH+16, halfHV, stride, 16, 16, 16);\
 }\
-void ff_ ## OPNAME ## qpel16_mc33_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel16_mc33_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfV[256];\
@@ -1134,7 +1175,8 @@ void ff_ ## OPNAME ## qpel16_mc33_old_c(uint8_t *dst, uint8_t *src, int stride){
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l4_8(dst, full+25, halfH+16, halfV, halfHV, stride, 24, 16, 16, 16, 16);\
 }\
-static void OPNAME ## qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfHV[256];\
@@ -1144,21 +1186,24 @@ static void OPNAME ## qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l2_8(dst, halfH+16, halfHV, stride, 16, 16, 16);\
 }\
-static void OPNAME ## qpel16_mc21_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc21_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t halfH[272];\
     uint8_t halfHV[256];\
     put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l2_8(dst, halfH, halfHV, stride, 16, 16, 16);\
 }\
-static void OPNAME ## qpel16_mc23_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc23_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t halfH[272];\
     uint8_t halfHV[256];\
     put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l2_8(dst, halfH+16, halfHV, stride, 16, 16, 16);\
 }\
-void ff_ ## OPNAME ## qpel16_mc12_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel16_mc12_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfV[256];\
@@ -1169,7 +1214,8 @@ void ff_ ## OPNAME ## qpel16_mc12_old_c(uint8_t *dst, uint8_t *src, int stride){
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l2_8(dst, halfV, halfHV, stride, 16, 16, 16);\
 }\
-static void OPNAME ## qpel16_mc12_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     copy_block17(full, src, 24, stride, 17);\
@@ -1177,7 +1223,8 @@ static void OPNAME ## qpel16_mc12_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## pixels16_l2_8(halfH, halfH, full, 16, 16, 24, 17);\
     OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\
 }\
-void ff_ ## OPNAME ## qpel16_mc32_old_c(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OPNAME ## qpel16_mc32_old_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     uint8_t halfV[256];\
@@ -1188,7 +1235,8 @@ void ff_ ## OPNAME ## qpel16_mc32_old_c(uint8_t *dst, uint8_t *src, int stride){
     put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
     OPNAME ## pixels16_l2_8(dst, halfV, halfHV, stride, 16, 16, 16);\
 }\
-static void OPNAME ## qpel16_mc32_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc32_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[24*17];\
     uint8_t halfH[272];\
     copy_block17(full, src, 24, stride, 17);\
@@ -1196,7 +1244,8 @@ static void OPNAME ## qpel16_mc32_c(uint8_t *dst, uint8_t *src, int stride){\
     put ## RND ## pixels16_l2_8(halfH, halfH, full+1, 16, 16, 24, 17);\
     OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\
 }\
-static void OPNAME ## qpel16_mc22_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## qpel16_mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t halfH[272];\
     put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\
     OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\
@@ -1216,15 +1265,32 @@ QPEL_MC(0, avg_       , _       , op_avg)
 #undef op_put
 #undef op_put_no_rnd
 
+void ff_put_pixels8x8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
+    put_pixels8_8_c(dst, src, stride, 8);
+}
+void ff_avg_pixels8x8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
+    avg_pixels8_8_c(dst, src, stride, 8);
+}
+void ff_put_pixels16x16_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
+    put_pixels16_8_c(dst, src, stride, 16);
+}
+void ff_avg_pixels16x16_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
+    avg_pixels16_8_c(dst, src, stride, 16);
+}
+
 #define put_qpel8_mc00_c  ff_put_pixels8x8_c
 #define avg_qpel8_mc00_c  ff_avg_pixels8x8_c
 #define put_qpel16_mc00_c ff_put_pixels16x16_c
 #define avg_qpel16_mc00_c ff_avg_pixels16x16_c
 #define put_no_rnd_qpel8_mc00_c  ff_put_pixels8x8_c
-#define put_no_rnd_qpel16_mc00_c ff_put_pixels16x16_8_c
+#define put_no_rnd_qpel16_mc00_c ff_put_pixels16x16_c
 
 static void wmv2_mspel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     int i;
 
     for(i=0; i<h; i++){
@@ -1242,22 +1308,26 @@ static void wmv2_mspel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int
 }
 
 #if CONFIG_RV40_DECODER
-void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){
+void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     put_pixels16_xy2_8_c(dst, src, stride, 16);
 }
-void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride){
+void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     avg_pixels16_xy2_8_c(dst, src, stride, 16);
 }
-void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){
+void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     put_pixels8_xy2_8_c(dst, src, stride, 8);
 }
-void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride){
+void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     avg_pixels8_xy2_8_c(dst, src, stride, 8);
 }
 #endif /* CONFIG_RV40_DECODER */
 
 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;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     int i;
 
     for(i=0; i<w; i++){
@@ -1285,27 +1355,32 @@ static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int
     }
 }
 
-static void put_mspel8_mc10_c(uint8_t *dst, uint8_t *src, int stride){
+static void put_mspel8_mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     uint8_t half[64];
     wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
     put_pixels8_l2_8(dst, src, half, stride, stride, 8, 8);
 }
 
-static void put_mspel8_mc20_c(uint8_t *dst, uint8_t *src, int stride){
+static void put_mspel8_mc20_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8);
 }
 
-static void put_mspel8_mc30_c(uint8_t *dst, uint8_t *src, int stride){
+static void put_mspel8_mc30_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     uint8_t half[64];
     wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
     put_pixels8_l2_8(dst, src+1, half, stride, stride, 8, 8);
 }
 
-static void put_mspel8_mc02_c(uint8_t *dst, uint8_t *src, int stride){
+static void put_mspel8_mc02_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8);
 }
 
-static void put_mspel8_mc12_c(uint8_t *dst, uint8_t *src, int stride){
+static void put_mspel8_mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     uint8_t halfH[88];
     uint8_t halfV[64];
     uint8_t halfHV[64];
@@ -1314,7 +1389,8 @@ static void put_mspel8_mc12_c(uint8_t *dst, uint8_t *src, int stride){
     wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8);
     put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
 }
-static void put_mspel8_mc32_c(uint8_t *dst, uint8_t *src, int stride){
+static void put_mspel8_mc32_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     uint8_t halfH[88];
     uint8_t halfV[64];
     uint8_t halfHV[64];
@@ -1323,113 +1399,13 @@ static void put_mspel8_mc32_c(uint8_t *dst, uint8_t *src, int stride){
     wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8);
     put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
 }
-static void put_mspel8_mc22_c(uint8_t *dst, uint8_t *src, int stride){
+static void put_mspel8_mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)
+{
     uint8_t halfH[88];
     wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11);
     wmv2_mspel8_v_lowpass(dst, halfH+8, stride, 8, 8);
 }
 
-static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale){
-    if(CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-    int x;
-    const int strength= ff_h263_loop_filter_strength[qscale];
-
-    for(x=0; x<8; x++){
-        int d1, d2, ad1;
-        int p0= src[x-2*stride];
-        int p1= src[x-1*stride];
-        int p2= src[x+0*stride];
-        int p3= src[x+1*stride];
-        int d = (p0 - p3 + 4*(p2 - p1)) / 8;
-
-        if     (d<-2*strength) d1= 0;
-        else if(d<-  strength) d1=-2*strength - d;
-        else if(d<   strength) d1= d;
-        else if(d< 2*strength) d1= 2*strength - d;
-        else                   d1= 0;
-
-        p1 += d1;
-        p2 -= d1;
-        if(p1&256) p1= ~(p1>>31);
-        if(p2&256) p2= ~(p2>>31);
-
-        src[x-1*stride] = p1;
-        src[x+0*stride] = p2;
-
-        ad1= FFABS(d1)>>1;
-
-        d2= av_clip((p0-p3)/4, -ad1, ad1);
-
-        src[x-2*stride] = p0 - d2;
-        src[x+  stride] = p3 + d2;
-    }
-    }
-}
-
-static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){
-    if(CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-    int y;
-    const int strength= ff_h263_loop_filter_strength[qscale];
-
-    for(y=0; y<8; y++){
-        int d1, d2, ad1;
-        int p0= src[y*stride-2];
-        int p1= src[y*stride-1];
-        int p2= src[y*stride+0];
-        int p3= src[y*stride+1];
-        int d = (p0 - p3 + 4*(p2 - p1)) / 8;
-
-        if     (d<-2*strength) d1= 0;
-        else if(d<-  strength) d1=-2*strength - d;
-        else if(d<   strength) d1= d;
-        else if(d< 2*strength) d1= 2*strength - d;
-        else                   d1= 0;
-
-        p1 += d1;
-        p2 -= d1;
-        if(p1&256) p1= ~(p1>>31);
-        if(p2&256) p2= ~(p2>>31);
-
-        src[y*stride-1] = p1;
-        src[y*stride+0] = p2;
-
-        ad1= FFABS(d1)>>1;
-
-        d2= av_clip((p0-p3)/4, -ad1, ad1);
-
-        src[y*stride-2] = p0 - d2;
-        src[y*stride+1] = p3 + d2;
-    }
-    }
-}
-
-static void h261_loop_filter_c(uint8_t *src, int stride){
-    int x,y,xy,yz;
-    int temp[64];
-
-    for(x=0; x<8; x++){
-        temp[x      ] = 4*src[x           ];
-        temp[x + 7*8] = 4*src[x + 7*stride];
-    }
-    for(y=1; y<7; y++){
-        for(x=0; x<8; x++){
-            xy = y * stride + x;
-            yz = y * 8 + x;
-            temp[yz] = src[xy - stride] + 2*src[xy] + src[xy + stride];
-        }
-    }
-
-    for(y=0; y<8; y++){
-        src[  y*stride] = (temp[  y*8] + 2)>>2;
-        src[7+y*stride] = (temp[7+y*8] + 2)>>2;
-        for(x=1; x<7; x++){
-            xy = y * stride + x;
-            yz = y * 8 + x;
-            src[xy] = (temp[yz-1] + 2*temp[yz] + temp[yz+1] + 8)>>4;
-        }
-    }
-}
-
 static inline int pix_abs16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
 {
     int s, i;
@@ -1705,35 +1681,6 @@ static void add_8x8basis_c(int16_t rem[64], int16_t basis[64], int scale){
     }
 }
 
-/**
- * Permute an 8x8 block.
- * @param block the block which will be permuted according to the given permutation vector
- * @param permutation the permutation vector
- * @param last the last non zero coefficient in scantable order, used to speed the permutation up
- * @param scantable the used scantable, this is only used to speed the permutation up, the block is not
- *                  (inverse) permutated to scantable order!
- */
-void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last)
-{
-    int i;
-    DCTELEM temp[64];
-
-    if(last<=0) return;
-    //if(permutation[1]==1) return; //FIXME it is ok but not clean and might fail for some permutations
-
-    for(i=0; i<=last; i++){
-        const int j= scantable[i];
-        temp[j]= block[j];
-        block[j]=0;
-    }
-
-    for(i=0; i<=last; i++){
-        const int j= scantable[i];
-        const int perm_j= permutation[j];
-        block[perm_j]= temp[j];
-    }
-}
-
 static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){
     return 0;
 }
@@ -1784,14 +1731,6 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){
         case FF_CMP_NSSE:
             cmp[i]= c->nsse[i];
             break;
-#if CONFIG_DWT
-        case FF_CMP_W53:
-            cmp[i]= c->w53[i];
-            break;
-        case FF_CMP_W97:
-            cmp[i]= c->w97[i];
-            break;
-#endif
         default:
             av_log(NULL, AV_LOG_ERROR,"internal error in cmp function selection\n");
         }
@@ -1800,7 +1739,7 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){
 
 static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){
     long i;
-    for(i=0; i<=w-sizeof(long); i+=sizeof(long)){
+    for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) {
         long a = *(long*)(src+i);
         long b = *(long*)(dst+i);
         *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80);
@@ -1825,7 +1764,7 @@ static void diff_bytes_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){
         }
     }else
 #endif
-    for(i=0; i<=w-sizeof(long); i+=sizeof(long)){
+    for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) {
         long a = *(long*)(src1+i);
         long b = *(long*)(src2+i);
         *(long*)(dst+i) = ((a|pb_80) - (b&pb_7f)) ^ ((a^b^pb_80)&pb_80);
@@ -2039,7 +1978,7 @@ static int hadamard8_intra8x8_c(/*MpegEncContext*/ void *s, uint8_t *src, uint8_
 
 static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
+    LOCAL_ALIGNED_16(int16_t, temp, [64]);
 
     assert(h==8);
 
@@ -2078,7 +2017,7 @@ static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2
 
 static int dct264_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
-    DCTELEM dct[8][8];
+    int16_t dct[8][8];
     int i;
     int sum=0;
 
@@ -2103,7 +2042,7 @@ static int dct264_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *s
 
 static int dct_max8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
+    LOCAL_ALIGNED_16(int16_t, temp, [64]);
     int sum=0, i;
 
     assert(h==8);
@@ -2119,8 +2058,8 @@ static int dct_max8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2
 
 static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64*2]);
-    DCTELEM * const bak = temp+64;
+    LOCAL_ALIGNED_16(int16_t, temp, [64*2]);
+    int16_t * const bak = temp+64;
     int sum=0, i;
 
     assert(h==8);
@@ -2128,7 +2067,7 @@ static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *s
 
     s->dsp.diff_pixels(temp, src1, src2, stride);
 
-    memcpy(bak, temp, 64*sizeof(DCTELEM));
+    memcpy(bak, temp, 64*sizeof(int16_t));
 
     s->block_last_index[0/*FIXME*/]= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i);
     s->dct_unquantize_inter(s, temp, 0, s->qscale);
@@ -2143,7 +2082,7 @@ static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *s
 static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
     const uint8_t *scantable= s->intra_scantable.permutated;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
+    LOCAL_ALIGNED_16(int16_t, temp, [64]);
     LOCAL_ALIGNED_16(uint8_t, lsrc1, [64]);
     LOCAL_ALIGNED_16(uint8_t, lsrc2, [64]);
     int i, last, run, bits, level, distortion, start_i;
@@ -2219,7 +2158,7 @@ static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int
 static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){
     MpegEncContext * const s= (MpegEncContext *)c;
     const uint8_t *scantable= s->intra_scantable.permutated;
-    LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
+    LOCAL_ALIGNED_16(int16_t, temp, [64]);
     int i, last, run, bits, level, start_i;
     const int esc_length= s->ac_esc_length;
     uint8_t * length;
@@ -2351,6 +2290,20 @@ static int ssd_int8_vs_int16_c(const int8_t *pix1, const int16_t *pix2,
     return score;
 }
 
+#define WRAPPER8_16_SQ(name8, name16)\
+static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
+    int score=0;\
+    score +=name8(s, dst           , src           , stride, 8);\
+    score +=name8(s, dst+8         , src+8         , stride, 8);\
+    if(h==16){\
+        dst += 8*stride;\
+        src += 8*stride;\
+        score +=name8(s, dst           , src           , stride, 8);\
+        score +=name8(s, dst+8         , src+8         , stride, 8);\
+    }\
+    return score;\
+}
+
 WRAPPER8_16_SQ(hadamard8_diff8x8_c, hadamard8_diff16_c)
 WRAPPER8_16_SQ(hadamard8_intra8x8_c, hadamard8_intra16_c)
 WRAPPER8_16_SQ(dct_sad8x8_c, dct_sad16_c)
@@ -2362,70 +2315,6 @@ WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
 WRAPPER8_16_SQ(rd8x8_c, rd16_c)
 WRAPPER8_16_SQ(bit8x8_c, bit16_c)
 
-static void vector_fmul_reverse_c(float *dst, const float *src0, const float *src1, int len){
-    int i;
-    src1 += len-1;
-    for(i=0; i<len; i++)
-        dst[i] = src0[i] * src1[-i];
-}
-
-static void vector_fmul_add_c(float *dst, const float *src0, const float *src1, const float *src2, int len){
-    int i;
-    for(i=0; i<len; i++)
-        dst[i] = src0[i] * src1[i] + src2[i];
-}
-
-static void vector_fmul_window_c(float *dst, const float *src0,
-                                 const float *src1, const float *win, int len)
-{
-    int i,j;
-    dst += len;
-    win += len;
-    src0+= len;
-    for(i=-len, j=len-1; i<0; i++, j--) {
-        float s0 = src0[i];
-        float s1 = src1[j];
-        float wi = win[i];
-        float wj = win[j];
-        dst[i] = s0*wj - s1*wi;
-        dst[j] = s0*wi + s1*wj;
-    }
-}
-
-static void butterflies_float_c(float *restrict v1, float *restrict v2,
-                                int len)
-{
-    int i;
-    for (i = 0; i < len; i++) {
-        float t = v1[i] - v2[i];
-        v1[i] += v2[i];
-        v2[i] = t;
-    }
-}
-
-static void butterflies_float_interleave_c(float *dst, const float *src0,
-                                           const float *src1, int len)
-{
-    int i;
-    for (i = 0; i < len; i++) {
-        float f1 = src0[i];
-        float f2 = src1[i];
-        dst[2*i    ] = f1 + f2;
-        dst[2*i + 1] = f1 - f2;
-    }
-}
-
-float ff_scalarproduct_float_c(const float *v1, const float *v2, int len)
-{
-    float p = 0.0;
-    int i;
-
-    for (i = 0; i < len; i++)
-        p += v1[i] * v2[i];
-
-    return p;
-}
-
 static inline uint32_t clipf_c_one(uint32_t a, uint32_t mini,
                    uint32_t maxi, uint32_t maxisign)
 {
@@ -2491,19 +2380,6 @@ static int32_t scalarproduct_and_madd_int16_c(int16_t *v1, const int16_t *v2, co
     return res;
 }
 
-static void apply_window_int16_c(int16_t *output, const int16_t *input,
-                                 const int16_t *window, unsigned int len)
-{
-    int i;
-    int len2 = len >> 1;
-
-    for (i = 0; i < len2; i++) {
-        int16_t w       = window[i];
-        output[i]       = (MUL16(input[i],       w) + (1 << 14)) >> 15;
-        output[len-i-1] = (MUL16(input[len-i-1], w) + (1 << 14)) >> 15;
-    }
-}
-
 static void vector_clip_int32_c(int32_t *dst, const int32_t *src, int32_t min,
                                 int32_t max, unsigned int len)
 {
@@ -2520,96 +2396,12 @@ static void vector_clip_int32_c(int32_t *dst, const int32_t *src, int32_t min,
     } while (len > 0);
 }
 
-#define W0 2048
-#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
-#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
-#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
-#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
-#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
-#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
-#define W7 565  /* 2048*sqrt (2)*cos (7*pi/16) */
-
-static void wmv2_idct_row(short * b)
-{
-    int s1,s2;
-    int a0,a1,a2,a3,a4,a5,a6,a7;
-    /*step 1*/
-    a1 = W1*b[1]+W7*b[7];
-    a7 = W7*b[1]-W1*b[7];
-    a5 = W5*b[5]+W3*b[3];
-    a3 = W3*b[5]-W5*b[3];
-    a2 = W2*b[2]+W6*b[6];
-    a6 = W6*b[2]-W2*b[6];
-    a0 = W0*b[0]+W0*b[4];
-    a4 = W0*b[0]-W0*b[4];
-    /*step 2*/
-    s1 = (181*(a1-a5+a7-a3)+128)>>8;//1,3,5,7,
-    s2 = (181*(a1-a5-a7+a3)+128)>>8;
-    /*step 3*/
-    b[0] = (a0+a2+a1+a5 + (1<<7))>>8;
-    b[1] = (a4+a6 +s1   + (1<<7))>>8;
-    b[2] = (a4-a6 +s2   + (1<<7))>>8;
-    b[3] = (a0-a2+a7+a3 + (1<<7))>>8;
-    b[4] = (a0-a2-a7-a3 + (1<<7))>>8;
-    b[5] = (a4-a6 -s2   + (1<<7))>>8;
-    b[6] = (a4+a6 -s1   + (1<<7))>>8;
-    b[7] = (a0+a2-a1-a5 + (1<<7))>>8;
-}
-static void wmv2_idct_col(short * b)
-{
-    int s1,s2;
-    int a0,a1,a2,a3,a4,a5,a6,a7;
-    /*step 1, with extended precision*/
-    a1 = (W1*b[8*1]+W7*b[8*7] + 4)>>3;
-    a7 = (W7*b[8*1]-W1*b[8*7] + 4)>>3;
-    a5 = (W5*b[8*5]+W3*b[8*3] + 4)>>3;
-    a3 = (W3*b[8*5]-W5*b[8*3] + 4)>>3;
-    a2 = (W2*b[8*2]+W6*b[8*6] + 4)>>3;
-    a6 = (W6*b[8*2]-W2*b[8*6] + 4)>>3;
-    a0 = (W0*b[8*0]+W0*b[8*4]    )>>3;
-    a4 = (W0*b[8*0]-W0*b[8*4]    )>>3;
-    /*step 2*/
-    s1 = (181*(a1-a5+a7-a3)+128)>>8;
-    s2 = (181*(a1-a5-a7+a3)+128)>>8;
-    /*step 3*/
-    b[8*0] = (a0+a2+a1+a5 + (1<<13))>>14;
-    b[8*1] = (a4+a6 +s1   + (1<<13))>>14;
-    b[8*2] = (a4-a6 +s2   + (1<<13))>>14;
-    b[8*3] = (a0-a2+a7+a3 + (1<<13))>>14;
-
-    b[8*4] = (a0-a2-a7-a3 + (1<<13))>>14;
-    b[8*5] = (a4-a6 -s2   + (1<<13))>>14;
-    b[8*6] = (a4+a6 -s1   + (1<<13))>>14;
-    b[8*7] = (a0+a2-a1-a5 + (1<<13))>>14;
-}
-void ff_wmv2_idct_c(short * block){
-    int i;
-
-    for(i=0;i<64;i+=8){
-        wmv2_idct_row(block+i);
-    }
-    for(i=0;i<8;i++){
-        wmv2_idct_col(block+i);
-    }
-}
-/* XXX: those functions should be suppressed ASAP when all IDCTs are
- converted */
-static void ff_wmv2_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block)
-{
-    ff_wmv2_idct_c(block);
-    put_pixels_clamped_c(block, dest, line_size);
-}
-static void ff_wmv2_idct_add_c(uint8_t *dest, int line_size, DCTELEM *block)
-{
-    ff_wmv2_idct_c(block);
-    add_pixels_clamped_c(block, dest, line_size);
-}
-static void ff_jref_idct_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void jref_idct_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct (block);
     put_pixels_clamped_c(block, dest, line_size);
 }
-static void ff_jref_idct_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void jref_idct_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_j_rev_dct (block);
     add_pixels_clamped_c(block, dest, line_size);
@@ -2620,17 +2412,9 @@ av_cold void ff_dsputil_static_init(void)
 {
     int i;
 
-    for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i;
-    for(i=0;i<MAX_NEG_CROP;i++) {
-        ff_cropTbl[i] = 0;
-        ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
-    }
-
     for(i=0;i<512;i++) {
         ff_squareTbl[i] = (i - 256) * (i - 256);
     }
-
-    for(i=0; i<64; i++) ff_inv_zigzag_direct16[ff_zigzag_direct[i]]= i+1;
 }
 
 int ff_check_alignment(void){
@@ -2655,8 +2439,6 @@ int ff_check_alignment(void){
 
 av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
 {
-    int i, j;
-
     ff_check_alignment();
 
 #if CONFIG_ENCODERS
@@ -2686,15 +2468,10 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
         c->idct_permutation_type = FF_NO_IDCT_PERM;
     } else {
         if(avctx->idct_algo==FF_IDCT_INT){
-            c->idct_put= ff_jref_idct_put;
-            c->idct_add= ff_jref_idct_add;
+            c->idct_put= jref_idct_put;
+            c->idct_add= jref_idct_add;
             c->idct    = ff_j_rev_dct;
             c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;
-        }else if(avctx->idct_algo==FF_IDCT_WMV2){
-            c->idct_put= ff_wmv2_idct_put_c;
-            c->idct_add= ff_wmv2_idct_add_c;
-            c->idct    = ff_wmv2_idct_c;
-            c->idct_permutation_type= FF_NO_IDCT_PERM;
         }else if(avctx->idct_algo==FF_IDCT_FAAN){
             c->idct_put= ff_faanidct_put;
             c->idct_add= ff_faanidct_add;
@@ -2820,9 +2597,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
     c->vsse[5]= vsse_intra8_c;
     c->nsse[0]= nsse16_c;
     c->nsse[1]= nsse8_c;
-#if CONFIG_DWT
-    ff_dsputil_init_dwt(c);
-#endif
 
     c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c;
 
@@ -2835,146 +2609,56 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
     c->bswap_buf= bswap_buf;
     c->bswap16_buf = bswap16_buf;
 
-    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-        c->h263_h_loop_filter= h263_h_loop_filter_c;
-        c->h263_v_loop_filter= h263_v_loop_filter_c;
-    }
-
-    c->h261_loop_filter= h261_loop_filter_c;
-
     c->try_8x8basis= try_8x8basis_c;
     c->add_8x8basis= add_8x8basis_c;
 
-#if CONFIG_VORBIS_DECODER
-    c->vorbis_inverse_coupling = ff_vorbis_inverse_coupling;
-#endif
-    c->vector_fmul_reverse = vector_fmul_reverse_c;
-    c->vector_fmul_add = vector_fmul_add_c;
-    c->vector_fmul_window = vector_fmul_window_c;
     c->vector_clipf = vector_clipf_c;
     c->scalarproduct_int16 = scalarproduct_int16_c;
     c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c;
-    c->apply_window_int16 = apply_window_int16_c;
     c->vector_clip_int32 = vector_clip_int32_c;
-    c->scalarproduct_float = ff_scalarproduct_float_c;
-    c->butterflies_float = butterflies_float_c;
-    c->butterflies_float_interleave = butterflies_float_interleave_c;
 
     c->shrink[0]= av_image_copy_plane;
     c->shrink[1]= ff_shrink22;
     c->shrink[2]= ff_shrink44;
     c->shrink[3]= ff_shrink88;
 
-    memset(c->put_2tap_qpel_pixels_tab, 0, sizeof(c->put_2tap_qpel_pixels_tab));
-    memset(c->avg_2tap_qpel_pixels_tab, 0, sizeof(c->avg_2tap_qpel_pixels_tab));
+    c->add_pixels8 = add_pixels8_c;
 
 #undef FUNC
 #undef FUNCC
 #define FUNC(f, depth) f ## _ ## depth
 #define FUNCC(f, depth) f ## _ ## depth ## _c
 
-#define dspfunc1(PFX, IDX, NUM, depth)\
-    c->PFX ## _pixels_tab[IDX][0] = FUNCC(PFX ## _pixels ## NUM        , depth);\
-    c->PFX ## _pixels_tab[IDX][1] = FUNCC(PFX ## _pixels ## NUM ## _x2 , depth);\
-    c->PFX ## _pixels_tab[IDX][2] = FUNCC(PFX ## _pixels ## NUM ## _y2 , depth);\
-    c->PFX ## _pixels_tab[IDX][3] = FUNCC(PFX ## _pixels ## NUM ## _xy2, depth)
-
-#define dspfunc2(PFX, IDX, NUM, depth)\
-    c->PFX ## _pixels_tab[IDX][ 0] = FUNCC(PFX ## NUM ## _mc00, depth);\
-    c->PFX ## _pixels_tab[IDX][ 1] = FUNCC(PFX ## NUM ## _mc10, depth);\
-    c->PFX ## _pixels_tab[IDX][ 2] = FUNCC(PFX ## NUM ## _mc20, depth);\
-    c->PFX ## _pixels_tab[IDX][ 3] = FUNCC(PFX ## NUM ## _mc30, depth);\
-    c->PFX ## _pixels_tab[IDX][ 4] = FUNCC(PFX ## NUM ## _mc01, depth);\
-    c->PFX ## _pixels_tab[IDX][ 5] = FUNCC(PFX ## NUM ## _mc11, depth);\
-    c->PFX ## _pixels_tab[IDX][ 6] = FUNCC(PFX ## NUM ## _mc21, depth);\
-    c->PFX ## _pixels_tab[IDX][ 7] = FUNCC(PFX ## NUM ## _mc31, depth);\
-    c->PFX ## _pixels_tab[IDX][ 8] = FUNCC(PFX ## NUM ## _mc02, depth);\
-    c->PFX ## _pixels_tab[IDX][ 9] = FUNCC(PFX ## NUM ## _mc12, depth);\
-    c->PFX ## _pixels_tab[IDX][10] = FUNCC(PFX ## NUM ## _mc22, depth);\
-    c->PFX ## _pixels_tab[IDX][11] = FUNCC(PFX ## NUM ## _mc32, depth);\
-    c->PFX ## _pixels_tab[IDX][12] = FUNCC(PFX ## NUM ## _mc03, depth);\
-    c->PFX ## _pixels_tab[IDX][13] = FUNCC(PFX ## NUM ## _mc13, depth);\
-    c->PFX ## _pixels_tab[IDX][14] = FUNCC(PFX ## NUM ## _mc23, depth);\
-    c->PFX ## _pixels_tab[IDX][15] = FUNCC(PFX ## NUM ## _mc33, depth)
-
-
-#define BIT_DEPTH_FUNCS(depth, dct)\
-    c->get_pixels                    = FUNCC(get_pixels   ## dct   , depth);\
-    c->draw_edges                    = FUNCC(draw_edges            , depth);\
-    c->clear_block                   = FUNCC(clear_block  ## dct   , depth);\
-    c->clear_blocks                  = FUNCC(clear_blocks ## dct   , depth);\
-    c->add_pixels8                   = FUNCC(add_pixels8  ## dct   , depth);\
-    c->add_pixels4                   = FUNCC(add_pixels4  ## dct   , depth);\
-    c->put_no_rnd_pixels_l2[0]       = FUNCC(put_no_rnd_pixels16_l2, depth);\
-    c->put_no_rnd_pixels_l2[1]       = FUNCC(put_no_rnd_pixels8_l2 , depth);\
-\
-    c->put_h264_chroma_pixels_tab[0] = FUNCC(put_h264_chroma_mc8   , depth);\
-    c->put_h264_chroma_pixels_tab[1] = FUNCC(put_h264_chroma_mc4   , depth);\
-    c->put_h264_chroma_pixels_tab[2] = FUNCC(put_h264_chroma_mc2   , depth);\
-    c->avg_h264_chroma_pixels_tab[0] = FUNCC(avg_h264_chroma_mc8   , depth);\
-    c->avg_h264_chroma_pixels_tab[1] = FUNCC(avg_h264_chroma_mc4   , depth);\
-    c->avg_h264_chroma_pixels_tab[2] = FUNCC(avg_h264_chroma_mc2   , depth);\
-\
-    dspfunc1(put       , 0, 16, depth);\
-    dspfunc1(put       , 1,  8, depth);\
-    dspfunc1(put       , 2,  4, depth);\
-    dspfunc1(put       , 3,  2, depth);\
-    dspfunc1(put_no_rnd, 0, 16, depth);\
-    dspfunc1(put_no_rnd, 1,  8, depth);\
-    dspfunc1(avg       , 0, 16, depth);\
-    dspfunc1(avg       , 1,  8, depth);\
-    dspfunc1(avg       , 2,  4, depth);\
-    dspfunc1(avg       , 3,  2, depth);\
-    dspfunc1(avg_no_rnd, 0, 16, depth);\
-    dspfunc1(avg_no_rnd, 1,  8, depth);\
-\
-    dspfunc2(put_h264_qpel, 0, 16, depth);\
-    dspfunc2(put_h264_qpel, 1,  8, depth);\
-    dspfunc2(put_h264_qpel, 2,  4, depth);\
-    dspfunc2(put_h264_qpel, 3,  2, depth);\
-    dspfunc2(avg_h264_qpel, 0, 16, depth);\
-    dspfunc2(avg_h264_qpel, 1,  8, depth);\
-    dspfunc2(avg_h264_qpel, 2,  4, depth);
+    c->draw_edges                    = FUNCC(draw_edges, 8);
+    c->clear_block                   = FUNCC(clear_block, 8);
+    c->clear_blocks                  = FUNCC(clear_blocks, 8);
+
+#define BIT_DEPTH_FUNCS(depth) \
+    c->get_pixels                    = FUNCC(get_pixels,   depth);
 
     switch (avctx->bits_per_raw_sample) {
     case 9:
-        if (c->dct_bits == 32) {
-            BIT_DEPTH_FUNCS(9, _32);
-        } else {
-            BIT_DEPTH_FUNCS(9, _16);
-        }
-        break;
     case 10:
-        if (c->dct_bits == 32) {
-            BIT_DEPTH_FUNCS(10, _32);
-        } else {
-            BIT_DEPTH_FUNCS(10, _16);
-        }
+        BIT_DEPTH_FUNCS(16);
         break;
     default:
-        BIT_DEPTH_FUNCS(8, _16);
+        BIT_DEPTH_FUNCS(8);
         break;
     }
 
 
-    if (HAVE_MMX)        ff_dsputil_init_mmx   (c, avctx);
-    if (ARCH_ARM)        ff_dsputil_init_arm   (c, avctx);
-    if (HAVE_VIS)        ff_dsputil_init_vis   (c, avctx);
-    if (ARCH_ALPHA)      ff_dsputil_init_alpha (c, avctx);
-    if (ARCH_PPC)        ff_dsputil_init_ppc   (c, avctx);
-    if (ARCH_SH4)        ff_dsputil_init_sh4   (c, avctx);
-    if (ARCH_BFIN)       ff_dsputil_init_bfin  (c, avctx);
-
-    for (i = 0; i < 4; i++) {
-        for (j = 0; j < 16; j++) {
-            if(!c->put_2tap_qpel_pixels_tab[i][j])
-                c->put_2tap_qpel_pixels_tab[i][j] =
-                    c->put_h264_qpel_pixels_tab[i][j];
-            if(!c->avg_2tap_qpel_pixels_tab[i][j])
-                c->avg_2tap_qpel_pixels_tab[i][j] =
-                    c->avg_h264_qpel_pixels_tab[i][j];
-        }
-    }
+    if (ARCH_ARM)
+        ff_dsputil_init_arm(c, avctx);
+    if (ARCH_BFIN)
+        ff_dsputil_init_bfin(c, avctx);
+    if (ARCH_PPC)
+        ff_dsputil_init_ppc(c, avctx);
+    if (ARCH_SH4)
+        ff_dsputil_init_sh4(c, avctx);
+    if (HAVE_VIS)
+        ff_dsputil_init_vis(c, avctx);
+    if (ARCH_X86)
+        ff_dsputil_init_x86(c, avctx);
 
     ff_init_scantable_permutation(c->idct_permutation,
                                   c->idct_permutation_type);
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 57c8beb..7bd92e5 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -32,46 +32,7 @@
 
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
-
-
-//#define DEBUG
-/* dct code */
-typedef short DCTELEM;
-
-void ff_fdct_ifast (DCTELEM *data);
-void ff_fdct_ifast248 (DCTELEM *data);
-void ff_jpeg_fdct_islow_8(DCTELEM *data);
-void ff_jpeg_fdct_islow_10(DCTELEM *data);
-void ff_fdct248_islow_8(DCTELEM *data);
-void ff_fdct248_islow_10(DCTELEM *data);
-
-void ff_j_rev_dct (DCTELEM *data);
-void ff_wmv2_idct_c(DCTELEM *data);
-
-void ff_fdct_mmx(DCTELEM *block);
-void ff_fdct_mmxext(DCTELEM *block);
-void ff_fdct_sse2(DCTELEM *block);
-
-#define H264_IDCT(depth) \
-void ff_h264_idct8_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_idct_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_idct8_dc_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, DCTELEM *block, int stride);\
-void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int *blockoffset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]);\
-void ff_h264_luma_dc_dequant_idct_ ## depth ## _c(DCTELEM *output, DCTELEM *input, int qmul);\
-void ff_h264_chroma422_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int qmul);\
-void ff_h264_chroma_dc_dequant_idct_ ## depth ## _c(DCTELEM *block, int qmul);
-
-H264_IDCT( 8)
-H264_IDCT( 9)
-H264_IDCT(10)
-
-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);
+#include "rnd_avg.h"
 
 /* encoding scans */
 extern const uint8_t ff_alternate_horizontal_scan[64];
@@ -84,33 +45,18 @@ extern const uint8_t ff_zigzag248_direct[64];
 
 /* temporary */
 extern uint32_t ff_squareTbl[512];
-extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP];
-
-#define PUTAVG_PIXELS(depth)\
-void ff_put_pixels8x8_ ## depth ## _c(uint8_t *dst, uint8_t *src, int stride);\
-void ff_avg_pixels8x8_ ## depth ## _c(uint8_t *dst, uint8_t *src, int stride);\
-void ff_put_pixels16x16_ ## depth ## _c(uint8_t *dst, uint8_t *src, int stride);\
-void ff_avg_pixels16x16_ ## depth ## _c(uint8_t *dst, uint8_t *src, int stride);
+extern const uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP];
 
-PUTAVG_PIXELS( 8)
-PUTAVG_PIXELS( 9)
-PUTAVG_PIXELS(10)
-
-#define ff_put_pixels8x8_c ff_put_pixels8x8_8_c
-#define ff_avg_pixels8x8_c ff_avg_pixels8x8_8_c
-#define ff_put_pixels16x16_c ff_put_pixels16x16_8_c
-#define ff_avg_pixels16x16_c ff_avg_pixels16x16_8_c
+void ff_put_pixels8x8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
+void ff_avg_pixels8x8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
+void ff_put_pixels16x16_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
+void ff_avg_pixels16x16_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
 
 /* RV40 functions */
-void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride);
-void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, int stride);
-void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride);
-void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, int stride);
-
-/* 1/2^n downscaling functions from imgconvert.c */
-void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
-void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
-void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
+void ff_put_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
+void ff_avg_rv40_qpel16_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
+void ff_put_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
+void ff_avg_rv40_qpel8_mc33_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride);
 
 void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy,
               int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height);
@@ -128,28 +74,18 @@ could be reached easily ...
 !future video codecs might need functions with less strict alignment
 */
 
-/*
-void get_pixels_c(DCTELEM *block, const uint8_t *pixels, int line_size);
-void diff_pixels_c(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride);
-void put_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size);
-void add_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size);
-void clear_blocks_c(DCTELEM *blocks);
-*/
-
 /* add and put pixel (decoding) */
 // blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16
 //h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller than 4
-typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h);
 typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h);
-typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);
-typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
+typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, ptrdiff_t stride);
 
 typedef void (*op_fill_func)(uint8_t *block/*align width (8 or 16)*/, uint8_t value, int line_size, int h);
 
 #define DEF_OLD_QPEL(name)\
-void ff_put_        ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\
-void ff_put_no_rnd_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\
-void ff_avg_        ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);
+void ff_put_        ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, ptrdiff_t stride);\
+void ff_put_no_rnd_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, ptrdiff_t stride);\
+void ff_avg_        ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, ptrdiff_t stride);
 
 DEF_OLD_QPEL(qpel16_mc11_old_c)
 DEF_OLD_QPEL(qpel16_mc31_old_c)
@@ -164,12 +100,6 @@ DEF_OLD_QPEL(qpel8_mc32_old_c)
 DEF_OLD_QPEL(qpel8_mc13_old_c)
 DEF_OLD_QPEL(qpel8_mc33_old_c)
 
-#define CALL_2X_PIXELS(a, b, n)\
-static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    b(block  , pixels  , line_size, h);\
-    b(block+n, pixels+n, line_size, h);\
-}
-
 /* motion estimation */
 // h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller than 2
 // although currently h<4 is not used as functions with width <8 are neither used nor implemented
@@ -192,20 +122,14 @@ void ff_init_scantable_permutation(uint8_t *idct_permutation,
  * DSPContext.
  */
 typedef struct DSPContext {
-    /**
-     * Size of DCT coefficients.
-     */
-    int dct_bits;
-
     /* pixel ops : interface with DCT */
-    void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size);
-    void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride);
-    void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
-    void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
-    void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
-    void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size);
-    void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size);
-    int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/);
+    void (*get_pixels)(int16_t *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size);
+    void (*diff_pixels)(int16_t *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride);
+    void (*put_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
+    void (*put_signed_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
+    void (*add_pixels_clamped)(const int16_t *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
+    void (*add_pixels8)(uint8_t *pixels, int16_t *block, int line_size);
+    int (*sum_abs_dctelem)(int16_t *block/*align 16*/);
     /**
      * translational global motion compensation.
      */
@@ -215,8 +139,8 @@ typedef struct DSPContext {
      */
     void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy,
                     int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height);
-    void (*clear_block)(DCTELEM *block/*align 16*/);
-    void (*clear_blocks)(DCTELEM *blocks/*align 16*/);
+    void (*clear_block)(int16_t *block/*align 16*/);
+    void (*clear_blocks)(int16_t *blocks/*align 16*/);
     int (*pix_sum)(uint8_t * pix, int line_size);
     int (*pix_norm1)(uint8_t * pix, int line_size);
 // 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4
@@ -231,8 +155,6 @@ typedef struct DSPContext {
     me_cmp_func vsad[6];
     me_cmp_func vsse[6];
     me_cmp_func nsse[6];
-    me_cmp_func w53[6];
-    me_cmp_func w97[6];
     me_cmp_func dct_max[6];
     me_cmp_func dct264_sad[6];
 
@@ -247,56 +169,6 @@ typedef struct DSPContext {
                              int size);
 
     /**
-     * Halfpel motion compensation with rounding (a+b+1)>>1.
-     * this is an array[4][4] of motion compensation functions for 4
-     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
-     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
-     * @param block destination where the result is stored
-     * @param pixels source
-     * @param line_size number of bytes in a horizontal line of block
-     * @param h height
-     */
-    op_pixels_func put_pixels_tab[4][4];
-
-    /**
-     * Halfpel motion compensation with rounding (a+b+1)>>1.
-     * This is an array[4][4] of motion compensation functions for 4
-     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
-     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
-     * @param block destination into which the result is averaged (a+b+1)>>1
-     * @param pixels source
-     * @param line_size number of bytes in a horizontal line of block
-     * @param h height
-     */
-    op_pixels_func avg_pixels_tab[4][4];
-
-    /**
-     * Halfpel motion compensation with no rounding (a+b)>>1.
-     * this is an array[2][4] of motion compensation functions for 2
-     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
-     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
-     * @param block destination where the result is stored
-     * @param pixels source
-     * @param line_size number of bytes in a horizontal line of block
-     * @param h height
-     */
-    op_pixels_func put_no_rnd_pixels_tab[4][4];
-
-    /**
-     * Halfpel motion compensation with no rounding (a+b)>>1.
-     * this is an array[2][4] of motion compensation functions for 2
-     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
-     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
-     * @param block destination into which the result is averaged (a+b)>>1
-     * @param pixels source
-     * @param line_size number of bytes in a horizontal line of block
-     * @param h height
-     */
-    op_pixels_func avg_no_rnd_pixels_tab[4][4];
-
-    void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h);
-
-    /**
      * Thirdpel motion compensation with rounding (a+b+1)>>1.
      * this is an array[12] of motion compensation functions for the 9 thirdpe
      * positions<br>
@@ -312,21 +184,8 @@ typedef struct DSPContext {
     qpel_mc_func put_qpel_pixels_tab[2][16];
     qpel_mc_func avg_qpel_pixels_tab[2][16];
     qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16];
-    qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16];
     qpel_mc_func put_mspel_pixels_tab[8];
 
-    /**
-     * h264 Chroma MC
-     */
-    h264_chroma_mc_func put_h264_chroma_pixels_tab[3];
-    h264_chroma_mc_func avg_h264_chroma_pixels_tab[3];
-
-    qpel_mc_func put_h264_qpel_pixels_tab[4][16];
-    qpel_mc_func avg_h264_qpel_pixels_tab[4][16];
-
-    qpel_mc_func put_2tap_qpel_pixels_tab[4][16];
-    qpel_mc_func avg_2tap_qpel_pixels_tab[4][16];
-
     me_cmp_func pix_abs[2][4];
 
     /* huffyuv specific */
@@ -343,72 +202,28 @@ typedef struct DSPContext {
     void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w);
     void (*bswap16_buf)(uint16_t *dst, const uint16_t *src, int len);
 
-    void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale);
-    void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale);
-
-    void (*h261_loop_filter)(uint8_t *src, int stride);
-
-    /* assume len is a multiple of 4, and arrays are 16-byte aligned */
-    void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize);
-    /* assume len is a multiple of 16, and arrays are 32-byte aligned */
-    void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len);
-    /* assume len is a multiple of 8, and src arrays are 16-byte aligned */
-    void (*vector_fmul_add)(float *dst, const float *src0, const float *src1, const float *src2, int len);
-    /* assume len is a multiple of 4, and arrays are 16-byte aligned */
-    void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, int len);
     /* assume len is a multiple of 8, and arrays are 16-byte aligned */
     void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */);
-    /**
-     * Calculate the scalar product of two vectors of floats.
-     * @param v1  first vector, 16-byte aligned
-     * @param v2  second vector, 16-byte aligned
-     * @param len length of vectors, multiple of 4
-     */
-    float (*scalarproduct_float)(const float *v1, const float *v2, int len);
-    /**
-     * Calculate the sum and difference of two vectors of floats.
-     * @param v1  first input vector, sum output, 16-byte aligned
-     * @param v2  second input vector, difference output, 16-byte aligned
-     * @param len length of vectors, multiple of 4
-     */
-    void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);
-
-    /**
-     * Calculate the sum and difference of two vectors of floats and interleave
-     * results into a separate output vector of floats, with each sum
-     * positioned before the corresponding difference.
-     *
-     * @param dst  output vector
-     *             constraints: 16-byte aligned
-     * @param src0 first input vector
-     *             constraints: 32-byte aligned
-     * @param src1 second input vector
-     *             constraints: 32-byte aligned
-     * @param len  number of elements in the input
-     *             constraints: multiple of 8
-     */
-    void (*butterflies_float_interleave)(float *dst, const float *src0,
-                                         const float *src1, int len);
 
     /* (I)DCT */
-    void (*fdct)(DCTELEM *block/* align 16*/);
-    void (*fdct248)(DCTELEM *block/* align 16*/);
+    void (*fdct)(int16_t *block/* align 16*/);
+    void (*fdct248)(int16_t *block/* align 16*/);
 
     /* IDCT really*/
-    void (*idct)(DCTELEM *block/* align 16*/);
+    void (*idct)(int16_t *block/* align 16*/);
 
     /**
      * block -> idct -> clip to unsigned 8 bit -> dest.
      * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...)
      * @param line_size size in bytes of a horizontal line of dest
      */
-    void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
+    void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, int16_t *block/*align 16*/);
 
     /**
      * block -> idct -> add dest -> clip to unsigned 8 bit -> dest.
      * @param line_size size in bytes of a horizontal line of dest
      */
-    void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
+    void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, int16_t *block/*align 16*/);
 
     /**
      * idct input permutation.
@@ -457,20 +272,6 @@ typedef struct DSPContext {
     int32_t (*scalarproduct_and_madd_int16)(int16_t *v1/*align 16*/, const int16_t *v2, const int16_t *v3, int len, int mul);
 
     /**
-     * Apply symmetric window in 16-bit fixed-point.
-     * @param output destination array
-     *               constraints: 16-byte aligned
-     * @param input  source array
-     *               constraints: 16-byte aligned
-     * @param window window array
-     *               constraints: 16-byte aligned, at least len/2 elements
-     * @param len    full window length
-     *               constraints: multiple of ? greater than zero
-     */
-    void (*apply_window_int16)(int16_t *output, const int16_t *input,
-                               const int16_t *window, unsigned int len);
-
-    /**
      * Clip each element in an array of int32_t to a given minimum and maximum value.
      * @param dst  destination array
      *             constraints: 16-byte aligned
@@ -494,195 +295,13 @@ void ff_dsputil_init(DSPContext* p, AVCodecContext *avctx);
 
 int ff_check_alignment(void);
 
-/**
- * Return the scalar product of two vectors.
- *
- * @param v1  first input vector
- * @param v2  first input vector
- * @param len number of elements
- *
- * @return sum of elementwise products
- */
-float ff_scalarproduct_float_c(const float *v1, const float *v2, int len);
-
-/**
- * permute block according to permuatation.
- * @param last last non zero element in scantable order
- */
-void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last);
-
 void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type);
 
-#define         BYTE_VEC32(c)   ((c)*0x01010101UL)
-#define         BYTE_VEC64(c)   ((c)*0x0001000100010001UL)
-
-static inline uint32_t rnd_avg32(uint32_t a, uint32_t b)
-{
-    return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
-}
-
-static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
-{
-    return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
-}
-
-static inline uint64_t rnd_avg64(uint64_t a, uint64_t b)
-{
-    return (a | b) - (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
-}
-
-static inline uint64_t no_rnd_avg64(uint64_t a, uint64_t b)
-{
-    return (a & b) + (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
-}
-
-static inline int get_penalty_factor(int lambda, int lambda2, int type){
-    switch(type&0xFF){
-    default:
-    case FF_CMP_SAD:
-        return lambda>>FF_LAMBDA_SHIFT;
-    case FF_CMP_DCT:
-        return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
-    case FF_CMP_W53:
-        return (4*lambda)>>(FF_LAMBDA_SHIFT);
-    case FF_CMP_W97:
-        return (2*lambda)>>(FF_LAMBDA_SHIFT);
-    case FF_CMP_SATD:
-    case FF_CMP_DCT264:
-        return (2*lambda)>>FF_LAMBDA_SHIFT;
-    case FF_CMP_RD:
-    case FF_CMP_PSNR:
-    case FF_CMP_SSE:
-    case FF_CMP_NSSE:
-        return lambda2>>FF_LAMBDA_SHIFT;
-    case FF_CMP_BIT:
-        return 1;
-    }
-}
-
-void ff_dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx);
 void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx);
 void ff_dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx);
-void ff_dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx);
 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_dwt(DSPContext *c);
-
-#if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX
-#   define STRIDE_ALIGN 16
-#else
-#   define STRIDE_ALIGN 8
-#endif
-
-// Some broken preprocessors need a second expansion
-// to be forced to tokenize __VA_ARGS__
-#define E(x) x
-
-#define LOCAL_ALIGNED_A(a, t, v, s, o, ...)             \
-    uint8_t la_##v[sizeof(t s o) + (a)];                \
-    t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
-
-#define LOCAL_ALIGNED_D(a, t, v, s, o, ...)             \
-    DECLARE_ALIGNED(a, t, la_##v) s o;                  \
-    t (*v) o = la_##v
-
-#define LOCAL_ALIGNED(a, t, v, ...) E(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,))
-
-#if HAVE_LOCAL_ALIGNED_8
-#   define LOCAL_ALIGNED_8(t, v, ...) E(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
-#else
-#   define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__)
-#endif
-
-#if HAVE_LOCAL_ALIGNED_16
-#   define LOCAL_ALIGNED_16(t, v, ...) E(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
-#else
-#   define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__)
-#endif
-
-#define WRAPPER8_16_SQ(name8, name16)\
-static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
-    int score=0;\
-    score +=name8(s, dst           , src           , stride, 8);\
-    score +=name8(s, dst+8         , src+8         , stride, 8);\
-    if(h==16){\
-        dst += 8*stride;\
-        src += 8*stride;\
-        score +=name8(s, dst           , src           , stride, 8);\
-        score +=name8(s, dst+8         , src+8         , stride, 8);\
-    }\
-    return score;\
-}
-
-
-static inline void copy_block2(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY16U(dst, src);
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block4(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY32U(dst, src);
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block8(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY64U(dst, src);
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block9(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY64U(dst, src);
-        dst[8]= src[8];
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block16(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY128U(dst, src);
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void copy_block17(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_COPY128U(dst, src);
-        dst[16]= src[16];
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
+void ff_dsputil_init_x86(DSPContext* c, AVCodecContext *avctx);
 
 #endif /* AVCODEC_DSPUTIL_H */
diff --git a/libavcodec/dsputil_template.c b/libavcodec/dsputil_template.c
index 13f7628..3a6d27f 100644
--- a/libavcodec/dsputil_template.c
+++ b/libavcodec/dsputil_template.c
@@ -29,54 +29,7 @@
 
 #include "bit_depth_template.c"
 
-static inline void FUNC(copy_block2)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_WN2P(dst   , AV_RN2P(src   ));
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void FUNC(copy_block4)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_WN4P(dst   , AV_RN4P(src   ));
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void FUNC(copy_block8)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_WN4P(dst                , AV_RN4P(src                ));
-        AV_WN4P(dst+4*sizeof(pixel), AV_RN4P(src+4*sizeof(pixel)));
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
-static inline void FUNC(copy_block16)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
-{
-    int i;
-    for(i=0; i<h; i++)
-    {
-        AV_WN4P(dst                 , AV_RN4P(src                 ));
-        AV_WN4P(dst+ 4*sizeof(pixel), AV_RN4P(src+ 4*sizeof(pixel)));
-        AV_WN4P(dst+ 8*sizeof(pixel), AV_RN4P(src+ 8*sizeof(pixel)));
-        AV_WN4P(dst+12*sizeof(pixel), AV_RN4P(src+12*sizeof(pixel)));
-        dst+=dstStride;
-        src+=srcStride;
-    }
-}
-
+#if BIT_DEPTH == 8
 /* 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)
@@ -89,16 +42,8 @@ static void FUNCC(draw_edges)(uint8_t *_buf, int _wrap, int width, int height, i
     /* left and right */
     ptr = buf;
     for(i=0;i<height;i++) {
-#if BIT_DEPTH > 8
-        int j;
-        for (j = 0; j < w; j++) {
-            ptr[j-w] = ptr[0];
-            ptr[j+width] = ptr[width-1];
-        }
-#else
         memset(ptr - w, ptr[0], w);
         memset(ptr + width, ptr[width-1], w);
-#endif
         ptr += wrap;
     }
 
@@ -112,121 +57,47 @@ static void FUNCC(draw_edges)(uint8_t *_buf, int _wrap, int width, int height, i
         for (i = 0; i < h; i++)
             memcpy(last_line + (i + 1) * wrap, last_line, (width + w + w) * sizeof(pixel)); // bottom
 }
+#endif
+
+static void FUNCC(get_pixels)(int16_t *restrict block,
+                              const uint8_t *_pixels,
+                              int line_size)
+{
+    const pixel *pixels = (const pixel *) _pixels;
+    int i;
 
-#define DCTELEM_FUNCS(dctcoef, suffix)                                  \
-static void FUNCC(get_pixels ## suffix)(DCTELEM *restrict _block,       \
-                                        const uint8_t *_pixels,         \
-                                        int line_size)                  \
-{                                                                       \
-    const pixel *pixels = (const pixel *) _pixels;                      \
-    dctcoef *restrict block = (dctcoef *) _block;                       \
-    int i;                                                              \
-                                                                        \
-    /* read the pixels */                                               \
-    for(i=0;i<8;i++) {                                                  \
-        block[0] = pixels[0];                                           \
-        block[1] = pixels[1];                                           \
-        block[2] = pixels[2];                                           \
-        block[3] = pixels[3];                                           \
-        block[4] = pixels[4];                                           \
-        block[5] = pixels[5];                                           \
-        block[6] = pixels[6];                                           \
-        block[7] = pixels[7];                                           \
-        pixels += line_size / sizeof(pixel);                            \
-        block += 8;                                                     \
-    }                                                                   \
-}                                                                       \
-                                                                        \
-static void FUNCC(add_pixels8 ## suffix)(uint8_t *restrict _pixels,     \
-                                         DCTELEM *_block,               \
-                                         int line_size)                 \
-{                                                                       \
-    int i;                                                              \
-    pixel *restrict pixels = (pixel *restrict)_pixels;                  \
-    dctcoef *block = (dctcoef*)_block;                                  \
-    line_size /= sizeof(pixel);                                         \
-                                                                        \
-    for(i=0;i<8;i++) {                                                  \
-        pixels[0] += block[0];                                          \
-        pixels[1] += block[1];                                          \
-        pixels[2] += block[2];                                          \
-        pixels[3] += block[3];                                          \
-        pixels[4] += block[4];                                          \
-        pixels[5] += block[5];                                          \
-        pixels[6] += block[6];                                          \
-        pixels[7] += block[7];                                          \
-        pixels += line_size;                                            \
-        block += 8;                                                     \
-    }                                                                   \
-}                                                                       \
-                                                                        \
-static void FUNCC(add_pixels4 ## suffix)(uint8_t *restrict _pixels,     \
-                                         DCTELEM *_block,               \
-                                         int line_size)                 \
-{                                                                       \
-    int i;                                                              \
-    pixel *restrict pixels = (pixel *restrict)_pixels;                  \
-    dctcoef *block = (dctcoef*)_block;                                  \
-    line_size /= sizeof(pixel);                                         \
-                                                                        \
-    for(i=0;i<4;i++) {                                                  \
-        pixels[0] += block[0];                                          \
-        pixels[1] += block[1];                                          \
-        pixels[2] += block[2];                                          \
-        pixels[3] += block[3];                                          \
-        pixels += line_size;                                            \
-        block += 4;                                                     \
-    }                                                                   \
-}                                                                       \
-                                                                        \
-static void FUNCC(clear_block ## suffix)(DCTELEM *block)                \
-{                                                                       \
-    memset(block, 0, sizeof(dctcoef)*64);                               \
-}                                                                       \
-                                                                        \
-/**                                                                     \
- * memset(blocks, 0, sizeof(DCTELEM)*6*64)                              \
- */                                                                     \
-static void FUNCC(clear_blocks ## suffix)(DCTELEM *blocks)              \
-{                                                                       \
-    memset(blocks, 0, sizeof(dctcoef)*6*64);                            \
+    /* read the pixels */
+    for(i=0;i<8;i++) {
+        block[0] = pixels[0];
+        block[1] = pixels[1];
+        block[2] = pixels[2];
+        block[3] = pixels[3];
+        block[4] = pixels[4];
+        block[5] = pixels[5];
+        block[6] = pixels[6];
+        block[7] = pixels[7];
+        pixels += line_size / sizeof(pixel);
+        block += 8;
+    }
 }
 
-DCTELEM_FUNCS(DCTELEM, _16)
-#if BIT_DEPTH > 8
-DCTELEM_FUNCS(dctcoef, _32)
+#if BIT_DEPTH == 8
+static void FUNCC(clear_block)(int16_t *block)
+{
+    memset(block, 0, sizeof(int16_t)*64);
+}
+
+static void FUNCC(clear_blocks)(int16_t *blocks)
+{
+    memset(blocks, 0, sizeof(int16_t)*6*64);
+}
+#endif
+
+#if BIT_DEPTH == 8
+#include "hpel_template.c"
 #endif
 
 #define PIXOP2(OPNAME, OP) \
-static void FUNCC(OPNAME ## _pixels2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        OP(*((pixel2*)(block  )), AV_RN2P(pixels  ));\
-        pixels+=line_size;\
-        block +=line_size;\
-    }\
-}\
-static void FUNCC(OPNAME ## _pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        OP(*((pixel4*)(block  )), AV_RN4P(pixels  ));\
-        pixels+=line_size;\
-        block +=line_size;\
-    }\
-}\
-static void FUNCC(OPNAME ## _pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        OP(*((pixel4*)(block                )), AV_RN4P(pixels                ));\
-        OP(*((pixel4*)(block+4*sizeof(pixel))), AV_RN4P(pixels+4*sizeof(pixel)));\
-        pixels+=line_size;\
-        block +=line_size;\
-    }\
-}\
-static inline void FUNCC(OPNAME ## _no_rnd_pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNCC(OPNAME ## _pixels8)(block, pixels, line_size, h);\
-}\
-\
 static inline void FUNC(OPNAME ## _no_rnd_pixels8_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
                                                 int src_stride1, int src_stride2, int h){\
     int i;\
@@ -241,70 +112,12 @@ static inline void FUNC(OPNAME ## _no_rnd_pixels8_l2)(uint8_t *dst, const uint8_
     }\
 }\
 \
-static inline void FUNC(OPNAME ## _pixels8_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        pixel4 a,b;\
-        a= AV_RN4P(&src1[i*src_stride1  ]);\
-        b= AV_RN4P(&src2[i*src_stride2  ]);\
-        OP(*((pixel4*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
-        a= AV_RN4P(&src1[i*src_stride1+4*sizeof(pixel)]);\
-        b= AV_RN4P(&src2[i*src_stride2+4*sizeof(pixel)]);\
-        OP(*((pixel4*)&dst[i*dst_stride+4*sizeof(pixel)]), rnd_avg_pixel4(a, b));\
-    }\
-}\
-\
-static inline void FUNC(OPNAME ## _pixels4_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        pixel4 a,b;\
-        a= AV_RN4P(&src1[i*src_stride1  ]);\
-        b= AV_RN4P(&src2[i*src_stride2  ]);\
-        OP(*((pixel4*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
-    }\
-}\
-\
-static inline void FUNC(OPNAME ## _pixels2_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    int i;\
-    for(i=0; i<h; i++){\
-        pixel4 a,b;\
-        a= AV_RN2P(&src1[i*src_stride1  ]);\
-        b= AV_RN2P(&src2[i*src_stride2  ]);\
-        OP(*((pixel2*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
-    }\
-}\
-\
-static inline void FUNC(OPNAME ## _pixels16_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
-                                                int src_stride1, int src_stride2, int h){\
-    FUNC(OPNAME ## _pixels8_l2)(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
-    FUNC(OPNAME ## _pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
-}\
-\
 static inline void FUNC(OPNAME ## _no_rnd_pixels16_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
                                                 int src_stride1, int src_stride2, int h){\
     FUNC(OPNAME ## _no_rnd_pixels8_l2)(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
     FUNC(OPNAME ## _no_rnd_pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
 }\
 \
-static inline void FUNCC(OPNAME ## _no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
-}\
-\
-static inline void FUNCC(OPNAME ## _pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
-}\
-\
-static inline void FUNCC(OPNAME ## _no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
-}\
-\
-static inline void FUNCC(OPNAME ## _pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
-}\
-\
 static inline void FUNC(OPNAME ## _pixels8_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
                  int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
     /* FIXME HIGH BIT DEPTH */\
@@ -342,22 +155,6 @@ static inline void FUNC(OPNAME ## _pixels8_l4)(uint8_t *dst, const uint8_t *src1
     }\
 }\
 \
-static inline void FUNCC(OPNAME ## _pixels4_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
-}\
-\
-static inline void FUNCC(OPNAME ## _pixels4_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
-}\
-\
-static inline void FUNCC(OPNAME ## _pixels2_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
-}\
-\
-static inline void FUNCC(OPNAME ## _pixels2_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
-    FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
-}\
-\
 static inline void FUNC(OPNAME ## _no_rnd_pixels8_l4)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, const uint8_t *src4,\
                  int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
     /* FIXME HIGH BIT DEPTH*/\
@@ -405,80 +202,7 @@ static inline void FUNC(OPNAME ## _no_rnd_pixels16_l4)(uint8_t *dst, const uint8
     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)\
-{\
-        int i, a0, b0, a1, b1;\
-        pixel *block = (pixel*)_block;\
-        const pixel *pixels = (const pixel*)_pixels;\
-        line_size /= sizeof(pixel);\
-        a0= pixels[0];\
-        b0= pixels[1] + 2;\
-        a0 += b0;\
-        b0 += pixels[2];\
-\
-        pixels+=line_size;\
-        for(i=0; i<h; i+=2){\
-            a1= pixels[0];\
-            b1= pixels[1];\
-            a1 += b1;\
-            b1 += pixels[2];\
-\
-            block[0]= (a1+a0)>>2; /* FIXME non put */\
-            block[1]= (b1+b0)>>2;\
-\
-            pixels+=line_size;\
-            block +=line_size;\
-\
-            a0= pixels[0];\
-            b0= pixels[1] + 2;\
-            a0 += b0;\
-            b0 += pixels[2];\
-\
-            block[0]= (a1+a0)>>2;\
-            block[1]= (b1+b0)>>2;\
-            pixels+=line_size;\
-            block +=line_size;\
-        }\
-}\
-\
-static inline void FUNCC(OPNAME ## _pixels4_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
-        /* FIXME HIGH BIT DEPTH */\
-        int i;\
-        const uint32_t a= AV_RN32(pixels  );\
-        const uint32_t b= AV_RN32(pixels+1);\
-        uint32_t l0=  (a&0x03030303UL)\
-                    + (b&0x03030303UL)\
-                    + 0x02020202UL;\
-        uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\
-                   + ((b&0xFCFCFCFCUL)>>2);\
-        uint32_t l1,h1;\
-\
-        pixels+=line_size;\
-        for(i=0; i<h; i+=2){\
-            uint32_t a= AV_RN32(pixels  );\
-            uint32_t b= AV_RN32(pixels+1);\
-            l1=  (a&0x03030303UL)\
-               + (b&0x03030303UL);\
-            h1= ((a&0xFCFCFCFCUL)>>2)\
-              + ((b&0xFCFCFCFCUL)>>2);\
-            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
-            pixels+=line_size;\
-            block +=line_size;\
-            a= AV_RN32(pixels  );\
-            b= AV_RN32(pixels+1);\
-            l0=  (a&0x03030303UL)\
-               + (b&0x03030303UL)\
-               + 0x02020202UL;\
-            h0= ((a&0xFCFCFCFCUL)>>2)\
-              + ((b&0xFCFCFCFCUL)>>2);\
-            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
-            pixels+=line_size;\
-            block +=line_size;\
-        }\
-}\
-\
-static inline void FUNCC(OPNAME ## _pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
+static inline void FUNCC(OPNAME ## _pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
 {\
     /* FIXME HIGH BIT DEPTH */\
     int j;\
@@ -520,681 +244,14 @@ static inline void FUNCC(OPNAME ## _pixels8_xy2)(uint8_t *block, const uint8_t *
     }\
 }\
 \
-static inline void FUNCC(OPNAME ## _no_rnd_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)\
-{\
-    /* FIXME HIGH BIT DEPTH */\
-    int j;\
-    for(j=0; j<2; j++){\
-        int i;\
-        const uint32_t a= AV_RN32(pixels  );\
-        const uint32_t b= AV_RN32(pixels+1);\
-        uint32_t l0=  (a&0x03030303UL)\
-                    + (b&0x03030303UL)\
-                    + 0x01010101UL;\
-        uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\
-                   + ((b&0xFCFCFCFCUL)>>2);\
-        uint32_t l1,h1;\
-\
-        pixels+=line_size;\
-        for(i=0; i<h; i+=2){\
-            uint32_t a= AV_RN32(pixels  );\
-            uint32_t b= AV_RN32(pixels+1);\
-            l1=  (a&0x03030303UL)\
-               + (b&0x03030303UL);\
-            h1= ((a&0xFCFCFCFCUL)>>2)\
-              + ((b&0xFCFCFCFCUL)>>2);\
-            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
-            pixels+=line_size;\
-            block +=line_size;\
-            a= AV_RN32(pixels  );\
-            b= AV_RN32(pixels+1);\
-            l0=  (a&0x03030303UL)\
-               + (b&0x03030303UL)\
-               + 0x01010101UL;\
-            h0= ((a&0xFCFCFCFCUL)>>2)\
-              + ((b&0xFCFCFCFCUL)>>2);\
-            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
-            pixels+=line_size;\
-            block +=line_size;\
-        }\
-        pixels+=4-line_size*(h+1);\
-        block +=4-line_size*h;\
-    }\
-}\
-\
-CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16)    , FUNCC(OPNAME ## _pixels8)    , 8*sizeof(pixel))\
-CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_x2) , FUNCC(OPNAME ## _pixels8_x2) , 8*sizeof(pixel))\
-CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_y2) , FUNCC(OPNAME ## _pixels8_y2) , 8*sizeof(pixel))\
 CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_xy2), FUNCC(OPNAME ## _pixels8_xy2), 8*sizeof(pixel))\
-av_unused CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16)    , FUNCC(OPNAME ## _pixels8) , 8*sizeof(pixel))\
-CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_x2) , FUNCC(OPNAME ## _no_rnd_pixels8_x2) , 8*sizeof(pixel))\
-CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_y2) , FUNCC(OPNAME ## _no_rnd_pixels8_y2) , 8*sizeof(pixel))\
-CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_xy2), FUNCC(OPNAME ## _no_rnd_pixels8_xy2), 8*sizeof(pixel))\
 
 #define op_avg(a, b) a = rnd_avg_pixel4(a, b)
 #define op_put(a, b) a = b
-
+#if BIT_DEPTH == 8
+#define put_no_rnd_pixels8_8_c put_pixels8_8_c
 PIXOP2(avg, op_avg)
 PIXOP2(put, op_put)
+#endif
 #undef op_avg
 #undef op_put
-
-#define put_no_rnd_pixels8_c  put_pixels8_c
-#define put_no_rnd_pixels16_c put_pixels16_c
-
-static void FUNCC(put_no_rnd_pixels16_l2)(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){
-    FUNC(put_no_rnd_pixels16_l2)(dst, a, b, stride, stride, stride, h);
-}
-
-static void FUNCC(put_no_rnd_pixels8_l2)(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){
-    FUNC(put_no_rnd_pixels8_l2)(dst, a, b, stride, stride, stride, h);
-}
-
-#define H264_CHROMA_MC(OPNAME, OP)\
-static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    const int A=(8-x)*(8-y);\
-    const int B=(  x)*(8-y);\
-    const int C=(8-x)*(  y);\
-    const int D=(  x)*(  y);\
-    int i;\
-    stride /= sizeof(pixel);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    if(D){\
-        for(i=0; i<h; i++){\
-            OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
-            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }else{\
-        const int E= B+C;\
-        const int step= C ? stride : 1;\
-        for(i=0; i<h; i++){\
-            OP(dst[0], (A*src[0] + E*src[step+0]));\
-            OP(dst[1], (A*src[1] + E*src[step+1]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }\
-}\
-\
-static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    const int A=(8-x)*(8-y);\
-    const int B=(  x)*(8-y);\
-    const int C=(8-x)*(  y);\
-    const int D=(  x)*(  y);\
-    int i;\
-    stride /= sizeof(pixel);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    if(D){\
-        for(i=0; i<h; i++){\
-            OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
-            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
-            OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
-            OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }else{\
-        const int E= B+C;\
-        const int step= C ? stride : 1;\
-        for(i=0; i<h; i++){\
-            OP(dst[0], (A*src[0] + E*src[step+0]));\
-            OP(dst[1], (A*src[1] + E*src[step+1]));\
-            OP(dst[2], (A*src[2] + E*src[step+2]));\
-            OP(dst[3], (A*src[3] + E*src[step+3]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }\
-}\
-\
-static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    const int A=(8-x)*(8-y);\
-    const int B=(  x)*(8-y);\
-    const int C=(8-x)*(  y);\
-    const int D=(  x)*(  y);\
-    int i;\
-    stride /= sizeof(pixel);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    if(D){\
-        for(i=0; i<h; i++){\
-            OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
-            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
-            OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
-            OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
-            OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));\
-            OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));\
-            OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));\
-            OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }else{\
-        const int E= B+C;\
-        const int step= C ? stride : 1;\
-        for(i=0; i<h; i++){\
-            OP(dst[0], (A*src[0] + E*src[step+0]));\
-            OP(dst[1], (A*src[1] + E*src[step+1]));\
-            OP(dst[2], (A*src[2] + E*src[step+2]));\
-            OP(dst[3], (A*src[3] + E*src[step+3]));\
-            OP(dst[4], (A*src[4] + E*src[step+4]));\
-            OP(dst[5], (A*src[5] + E*src[step+5]));\
-            OP(dst[6], (A*src[6] + E*src[step+6]));\
-            OP(dst[7], (A*src[7] + E*src[step+7]));\
-            dst+= stride;\
-            src+= stride;\
-        }\
-    }\
-}
-
-#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1)
-#define op_put(a, b) a = (((b) + 32)>>6)
-
-H264_CHROMA_MC(put_       , op_put)
-H264_CHROMA_MC(avg_       , op_avg)
-#undef op_avg
-#undef op_put
-
-#define H264_LOWPASS(OPNAME, OP, OP2) \
-static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *_dst, uint8_t *_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);\
-    for(i=0; i<h; i++)\
-    {\
-        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
-        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
-        dst+=dstStride;\
-        src+=srcStride;\
-    }\
-}\
-\
-static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *_dst, uint8_t *_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);\
-    for(i=0; i<w; i++)\
-    {\
-        const int srcB= src[-2*srcStride];\
-        const int srcA= src[-1*srcStride];\
-        const int src0= src[0 *srcStride];\
-        const int src1= src[1 *srcStride];\
-        const int src2= src[2 *srcStride];\
-        const int src3= src[3 *srcStride];\
-        const int src4= src[4 *srcStride];\
-        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        dst++;\
-        src++;\
-    }\
-}\
-\
-static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_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;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
-    src -= 2*srcStride;\
-    for(i=0; i<h+5; i++)\
-    {\
-        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\
-        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\
-        tmp+=tmpStride;\
-        src+=srcStride;\
-    }\
-    tmp -= tmpStride*(h+5-2);\
-    for(i=0; i<w; i++)\
-    {\
-        const int tmpB= tmp[-2*tmpStride] - pad;\
-        const int tmpA= tmp[-1*tmpStride] - pad;\
-        const int tmp0= tmp[0 *tmpStride] - pad;\
-        const int tmp1= tmp[1 *tmpStride] - pad;\
-        const int tmp2= tmp[2 *tmpStride] - pad;\
-        const int tmp3= tmp[3 *tmpStride] - pad;\
-        const int tmp4= tmp[4 *tmpStride] - pad;\
-        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
-        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
-        dst++;\
-        tmp++;\
-    }\
-}\
-static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *_dst, uint8_t *_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);\
-    for(i=0; i<h; i++)\
-    {\
-        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
-        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
-        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]));\
-        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]));\
-        dst+=dstStride;\
-        src+=srcStride;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *_dst, uint8_t *_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);\
-    for(i=0; i<w; i++)\
-    {\
-        const int srcB= src[-2*srcStride];\
-        const int srcA= src[-1*srcStride];\
-        const int src0= src[0 *srcStride];\
-        const int src1= src[1 *srcStride];\
-        const int src2= src[2 *srcStride];\
-        const int src3= src[3 *srcStride];\
-        const int src4= src[4 *srcStride];\
-        const int src5= src[5 *srcStride];\
-        const int src6= src[6 *srcStride];\
-        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
-        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
-        dst++;\
-        src++;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_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;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
-    src -= 2*srcStride;\
-    for(i=0; i<h+5; i++)\
-    {\
-        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\
-        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\
-        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]) + pad;\
-        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]) + pad;\
-        tmp+=tmpStride;\
-        src+=srcStride;\
-    }\
-    tmp -= tmpStride*(h+5-2);\
-    for(i=0; i<w; i++)\
-    {\
-        const int tmpB= tmp[-2*tmpStride] - pad;\
-        const int tmpA= tmp[-1*tmpStride] - pad;\
-        const int tmp0= tmp[0 *tmpStride] - pad;\
-        const int tmp1= tmp[1 *tmpStride] - pad;\
-        const int tmp2= tmp[2 *tmpStride] - pad;\
-        const int tmp3= tmp[3 *tmpStride] - pad;\
-        const int tmp4= tmp[4 *tmpStride] - pad;\
-        const int tmp5= tmp[5 *tmpStride] - pad;\
-        const int tmp6= tmp[6 *tmpStride] - pad;\
-        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
-        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
-        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\
-        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\
-        dst++;\
-        tmp++;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *_dst, uint8_t *_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);\
-    for(i=0; i<h; i++)\
-    {\
-        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]));\
-        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]));\
-        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]));\
-        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]));\
-        OP(dst[4], (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]));\
-        OP(dst[5], (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]));\
-        OP(dst[6], (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]));\
-        OP(dst[7], (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]));\
-        dst+=dstStride;\
-        src+=srcStride;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *_dst, uint8_t *_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);\
-    for(i=0; i<w; i++)\
-    {\
-        const int srcB= src[-2*srcStride];\
-        const int srcA= src[-1*srcStride];\
-        const int src0= src[0 *srcStride];\
-        const int src1= src[1 *srcStride];\
-        const int src2= src[2 *srcStride];\
-        const int src3= src[3 *srcStride];\
-        const int src4= src[4 *srcStride];\
-        const int src5= src[5 *srcStride];\
-        const int src6= src[6 *srcStride];\
-        const int src7= src[7 *srcStride];\
-        const int src8= src[8 *srcStride];\
-        const int src9= src[9 *srcStride];\
-        const int src10=src[10*srcStride];\
-        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
-        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
-        OP(dst[4*dstStride], (src4+src5)*20 - (src3+src6)*5 + (src2+src7));\
-        OP(dst[5*dstStride], (src5+src6)*20 - (src4+src7)*5 + (src3+src8));\
-        OP(dst[6*dstStride], (src6+src7)*20 - (src5+src8)*5 + (src4+src9));\
-        OP(dst[7*dstStride], (src7+src8)*20 - (src6+src9)*5 + (src5+src10));\
-        dst++;\
-        src++;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel8_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_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;\
-    INIT_CLIP\
-    int i;\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
-    src -= 2*srcStride;\
-    for(i=0; i<h+5; i++)\
-    {\
-        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]) + pad;\
-        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]) + pad;\
-        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]) + pad;\
-        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]) + pad;\
-        tmp[4]= (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]) + pad;\
-        tmp[5]= (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]) + pad;\
-        tmp[6]= (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]) + pad;\
-        tmp[7]= (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]) + pad;\
-        tmp+=tmpStride;\
-        src+=srcStride;\
-    }\
-    tmp -= tmpStride*(h+5-2);\
-    for(i=0; i<w; i++)\
-    {\
-        const int tmpB= tmp[-2*tmpStride] - pad;\
-        const int tmpA= tmp[-1*tmpStride] - pad;\
-        const int tmp0= tmp[0 *tmpStride] - pad;\
-        const int tmp1= tmp[1 *tmpStride] - pad;\
-        const int tmp2= tmp[2 *tmpStride] - pad;\
-        const int tmp3= tmp[3 *tmpStride] - pad;\
-        const int tmp4= tmp[4 *tmpStride] - pad;\
-        const int tmp5= tmp[5 *tmpStride] - pad;\
-        const int tmp6= tmp[6 *tmpStride] - pad;\
-        const int tmp7= tmp[7 *tmpStride] - pad;\
-        const int tmp8= tmp[8 *tmpStride] - pad;\
-        const int tmp9= tmp[9 *tmpStride] - pad;\
-        const int tmp10=tmp[10*tmpStride] - pad;\
-        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
-        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
-        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\
-        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\
-        OP2(dst[4*dstStride], (tmp4+tmp5)*20 - (tmp3+tmp6)*5 + (tmp2+tmp7));\
-        OP2(dst[5*dstStride], (tmp5+tmp6)*20 - (tmp4+tmp7)*5 + (tmp3+tmp8));\
-        OP2(dst[6*dstStride], (tmp6+tmp7)*20 - (tmp5+tmp8)*5 + (tmp4+tmp9));\
-        OP2(dst[7*dstStride], (tmp7+tmp8)*20 - (tmp6+tmp9)*5 + (tmp5+tmp10));\
-        dst++;\
-        tmp++;\
-    }\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel16_v_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
-    src += 8*srcStride;\
-    dst += 8*dstStride;\
-    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel16_h_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
-    src += 8*srcStride;\
-    dst += 8*dstStride;\
-    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
-}\
-\
-static void FUNC(OPNAME ## h264_qpel16_hv_lowpass)(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
-    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\
-    src += 8*srcStride;\
-    dst += 8*dstStride;\
-    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\
-    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\
-}\
-
-#define H264_MC(OPNAME, SIZE) \
-static av_unused void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc00)(uint8_t *dst, uint8_t *src, int stride){\
-    FUNCC(OPNAME ## pixels ## SIZE)(dst, src, stride, SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc10)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src, half, stride, stride, SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc20)(uint8_t *dst, uint8_t *src, int stride){\
-    FUNC(OPNAME ## h264_qpel ## SIZE ## _h_lowpass)(dst, src, stride, stride);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc30)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src+sizeof(pixel), half, stride, stride, SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc01)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid, half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc02)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(OPNAME ## h264_qpel ## SIZE ## _v_lowpass)(dst, full_mid, stride, SIZE*sizeof(pixel));\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc03)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid+SIZE*sizeof(pixel), half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc11)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc31)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc13)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc33)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
-    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc22)(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t 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)];\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
-    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc23)(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
-    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc12)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    int16_t tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-\
-static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc32)(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
-    int16_t tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
-    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
-    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
-    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
-    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
-    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
-    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
-}\
-
-#define op_avg(a, b)  a = (((a)+CLIP(((b) + 16)>>5)+1)>>1)
-//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7)
-#define op_put(a, b)  a = CLIP(((b) + 16)>>5)
-#define op2_avg(a, b)  a = (((a)+CLIP(((b) + 512)>>10)+1)>>1)
-#define op2_put(a, b)  a = CLIP(((b) + 512)>>10)
-
-H264_LOWPASS(put_       , op_put, op2_put)
-H264_LOWPASS(avg_       , op_avg, op2_avg)
-H264_MC(put_, 2)
-H264_MC(put_, 4)
-H264_MC(put_, 8)
-H264_MC(put_, 16)
-H264_MC(avg_, 4)
-H264_MC(avg_, 8)
-H264_MC(avg_, 16)
-
-#undef op_avg
-#undef op_put
-#undef op2_avg
-#undef op2_put
-
-#if BIT_DEPTH == 8
-#   define put_h264_qpel8_mc00_8_c  ff_put_pixels8x8_8_c
-#   define avg_h264_qpel8_mc00_8_c  ff_avg_pixels8x8_8_c
-#   define put_h264_qpel16_mc00_8_c ff_put_pixels16x16_8_c
-#   define avg_h264_qpel16_mc00_8_c ff_avg_pixels16x16_8_c
-#elif BIT_DEPTH == 9
-#   define put_h264_qpel8_mc00_9_c  ff_put_pixels8x8_9_c
-#   define avg_h264_qpel8_mc00_9_c  ff_avg_pixels8x8_9_c
-#   define put_h264_qpel16_mc00_9_c ff_put_pixels16x16_9_c
-#   define avg_h264_qpel16_mc00_9_c ff_avg_pixels16x16_9_c
-#elif BIT_DEPTH == 10
-#   define put_h264_qpel8_mc00_10_c  ff_put_pixels8x8_10_c
-#   define avg_h264_qpel8_mc00_10_c  ff_avg_pixels8x8_10_c
-#   define put_h264_qpel16_mc00_10_c ff_put_pixels16x16_10_c
-#   define avg_h264_qpel16_mc00_10_c ff_avg_pixels16x16_10_c
-#endif
-
-void FUNCC(ff_put_pixels8x8)(uint8_t *dst, uint8_t *src, int stride) {
-    FUNCC(put_pixels8)(dst, src, stride, 8);
-}
-void FUNCC(ff_avg_pixels8x8)(uint8_t *dst, uint8_t *src, int stride) {
-    FUNCC(avg_pixels8)(dst, src, stride, 8);
-}
-void FUNCC(ff_put_pixels16x16)(uint8_t *dst, uint8_t *src, int stride) {
-    FUNCC(put_pixels16)(dst, src, stride, 16);
-}
-void FUNCC(ff_avg_pixels16x16)(uint8_t *dst, uint8_t *src, int stride) {
-    FUNCC(avg_pixels16)(dst, src, stride, 16);
-}
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index 0cbb106..a6f614a 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -38,15 +38,15 @@
  * DV codec.
  */
 
+#include "libavutil/internal.h"
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
 #include "internal.h"
 #include "put_bits.h"
 #include "simple_idct.h"
 #include "dvdata.h"
-#include "dv_tablegen.h"
+#include "dv.h"
 
 /* XXX: also include quantization */
 RL_VLC_ELEM ff_dv_rl_vlc[1184];
@@ -254,20 +254,20 @@ av_cold int ff_dvvideo_init(AVCodecContext *avctx)
 
         /* it's faster to include sign bit in a generic VLC parsing scheme */
         for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
-            new_dv_vlc_bits[j]  = dv_vlc_bits[i];
-            new_dv_vlc_len[j]   = dv_vlc_len[i];
-            new_dv_vlc_run[j]   = dv_vlc_run[i];
-            new_dv_vlc_level[j] = dv_vlc_level[i];
+            new_dv_vlc_bits[j]  = ff_dv_vlc_bits[i];
+            new_dv_vlc_len[j]   = ff_dv_vlc_len[i];
+            new_dv_vlc_run[j]   = ff_dv_vlc_run[i];
+            new_dv_vlc_level[j] = ff_dv_vlc_level[i];
 
-            if (dv_vlc_level[i]) {
+            if (ff_dv_vlc_level[i]) {
                 new_dv_vlc_bits[j] <<= 1;
                 new_dv_vlc_len[j]++;
 
                 j++;
-                new_dv_vlc_bits[j]  = (dv_vlc_bits[i] << 1) | 1;
-                new_dv_vlc_len[j]   =  dv_vlc_len[i] + 1;
-                new_dv_vlc_run[j]   =  dv_vlc_run[i];
-                new_dv_vlc_level[j] = -dv_vlc_level[i];
+                new_dv_vlc_bits[j]  = (ff_dv_vlc_bits[i] << 1) | 1;
+                new_dv_vlc_len[j]   =  ff_dv_vlc_len[i] + 1;
+                new_dv_vlc_run[j]   =  ff_dv_vlc_run[i];
+                new_dv_vlc_level[j] = -ff_dv_vlc_level[i];
             }
         }
 
@@ -313,675 +313,8 @@ av_cold int ff_dvvideo_init(AVCodecContext *avctx)
     s->idct_put[1] = ff_simple_idct248_put;  // FIXME: need to add it to DSP
     memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
 
-    avctx->coded_frame = &s->picture;
     s->avctx = avctx;
     avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
 
     return 0;
 }
-
-static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
-{
-    if (!avpriv_dv_codec_profile(avctx)) {
-        av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video. "
-               "Valid DV profiles are:\n",
-               avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
-        ff_dv_print_profiles(avctx, AV_LOG_ERROR);
-        return AVERROR(EINVAL);
-    }
-
-    dv_vlc_map_tableinit();
-
-    return ff_dvvideo_init(avctx);
-}
-
-/* bit budget for AC only in 5 MBs */
-static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
-static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
-
-#if CONFIG_SMALL
-/* Converts run and level (where level != 0) pair into VLC, returning bit size */
-static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
-{
-    int size;
-    if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
-        *vlc = dv_vlc_map[run][level].vlc | sign;
-        size = dv_vlc_map[run][level].size;
-    }
-    else {
-        if (level < DV_VLC_MAP_LEV_SIZE) {
-            *vlc = dv_vlc_map[0][level].vlc | sign;
-            size = dv_vlc_map[0][level].size;
-        } else {
-            *vlc = 0xfe00 | (level << 1) | sign;
-            size = 16;
-        }
-        if (run) {
-            *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
-                                  (0x1f80 | (run - 1))) << size;
-            size +=  (run < 16) ? dv_vlc_map[run-1][0].size : 13;
-        }
-    }
-
-    return size;
-}
-
-static av_always_inline int dv_rl2vlc_size(int run, int level)
-{
-    int size;
-
-    if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
-        size = dv_vlc_map[run][level].size;
-    }
-    else {
-        size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
-        if (run) {
-            size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
-        }
-    }
-    return size;
-}
-#else
-static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
-{
-    *vlc = dv_vlc_map[run][l].vlc | sign;
-    return dv_vlc_map[run][l].size;
-}
-
-static av_always_inline int dv_rl2vlc_size(int run, int l)
-{
-    return dv_vlc_map[run][l].size;
-}
-#endif
-
-typedef struct EncBlockInfo {
-    int      area_q[4];
-    int      bit_size[4];
-    int      prev[5];
-    int      cur_ac;
-    int      cno;
-    int      dct_mode;
-    DCTELEM  mb[64];
-    uint8_t  next[64];
-    uint8_t  sign[64];
-    uint8_t  partial_bit_count;
-    uint32_t partial_bit_buffer; /* we can't use uint16_t here */
-} EncBlockInfo;
-
-static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
-                                                    PutBitContext* pb_pool,
-                                                    PutBitContext* pb_end)
-{
-    int prev, bits_left;
-    PutBitContext* pb = pb_pool;
-    int size = bi->partial_bit_count;
-    uint32_t vlc = bi->partial_bit_buffer;
-
-    bi->partial_bit_count = bi->partial_bit_buffer = 0;
-    for (;;){
-       /* Find suitable storage space */
-       for (; size > (bits_left = put_bits_left(pb)); pb++) {
-          if (bits_left) {
-              size -= bits_left;
-              put_bits(pb, bits_left, vlc >> size);
-              vlc = vlc & ((1 << size) - 1);
-          }
-          if (pb + 1 >= pb_end) {
-              bi->partial_bit_count  = size;
-              bi->partial_bit_buffer = vlc;
-              return pb;
-          }
-       }
-
-       /* Store VLC */
-       put_bits(pb, size, vlc);
-
-       if (bi->cur_ac >= 64)
-           break;
-
-       /* Construct the next VLC */
-       prev       = bi->cur_ac;
-       bi->cur_ac = bi->next[prev];
-       if (bi->cur_ac < 64){
-           size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
-       } else {
-           size = 4; vlc = 6; /* End Of Block stamp */
-       }
-    }
-    return pb;
-}
-
-static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
-    if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
-        int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
-        if (ps > 0) {
-            int is = s->ildct_cmp(NULL, data           , NULL, linesize<<1, 4) +
-                     s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
-            return ps > is;
-        }
-    }
-
-    return 0;
-}
-
-static const int dv_weight_bits = 18;
-static const int dv_weight_88[64] = {
- 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536,
- 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935,
- 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916,
- 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433,
- 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704,
- 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568,
- 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627,
- 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258,
-};
-static const int dv_weight_248[64] = {
- 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754,
- 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536,
- 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568,
- 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965,
- 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627,
- 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965,
- 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364,
- 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651,
-};
-
-static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
-{
-    const int *weight;
-    const uint8_t* zigzag_scan;
-    LOCAL_ALIGNED_16(DCTELEM, blk, [64]);
-    int i, area;
-    /* We offer two different methods for class number assignment: the
-       method suggested in SMPTE 314M Table 22, and an improved
-       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
-       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
-       (for blocks whose largest AC component exceeds 255). */
-
-#if 0 /* SMPTE spec method */
-    static const int classes[] = {12, 24, 36, 0xffff};
-#else /* improved Libav method */
-    static const int classes[] = {-1, -1, 255, 0xffff};
-#endif
-    int max  = classes[0];
-    int prev = 0;
-
-    assert((((int)blk) & 15) == 0);
-
-    bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
-    bi->partial_bit_count = 0;
-    bi->partial_bit_buffer = 0;
-    bi->cur_ac = 0;
-    if (data) {
-        bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
-        s->get_pixels(blk, data, linesize);
-        s->fdct[bi->dct_mode](blk);
-    } else {
-        /* We rely on the fact that encoding all zeros leads to an immediate EOB,
-           which is precisely what the spec calls for in the "dummy" blocks. */
-        memset(blk, 0, 64*sizeof(*blk));
-        bi->dct_mode = 0;
-    }
-    bi->mb[0] = blk[0];
-
-    zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
-    weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
-
-    for (area = 0; area < 4; area++) {
-       bi->prev[area]     = prev;
-       bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
-       for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
-          int level = blk[zigzag_scan[i]];
-
-          if (level + 15 > 30U) {
-              bi->sign[i] = (level >> 31) & 1;
-              /* weight it and and shift down into range, adding for rounding */
-              /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT
-                 AND the 2x doubling of the weights */
-              level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
-              bi->mb[i] = level;
-              if (level > max)
-                  max = level;
-              bi->bit_size[area] += dv_rl2vlc_size(i - prev  - 1, level);
-              bi->next[prev]= i;
-              prev = i;
-          }
-       }
-    }
-    bi->next[prev]= i;
-    for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
-
-    bi->cno += bias;
-
-    if (bi->cno >= 3) {
-        bi->cno = 3;
-        prev    = 0;
-        i       = bi->next[prev];
-        for (area = 0; area < 4; area++) {
-            bi->prev[area]     = prev;
-            bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
-            for (; i < mb_area_start[area+1]; i = bi->next[i]) {
-                bi->mb[i] >>= 1;
-
-                if (bi->mb[i]) {
-                    bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
-                    bi->next[prev]= i;
-                    prev = i;
-                }
-            }
-        }
-        bi->next[prev]= i;
-    }
-
-    return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
-}
-
-static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
-{
-    int size[5];
-    int i, j, k, a, prev, a2;
-    EncBlockInfo* b;
-
-    size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
-    do {
-       b = blks;
-       for (i = 0; i < 5; i++) {
-          if (!qnos[i])
-              continue;
-
-          qnos[i]--;
-          size[i] = 0;
-          for (j = 0; j < 6; j++, b++) {
-             for (a = 0; a < 4; a++) {
-                if (b->area_q[a] != ff_dv_quant_shifts[qnos[i] + ff_dv_quant_offset[b->cno]][a]) {
-                    b->bit_size[a] = 1; // 4 areas 4 bits for EOB :)
-                    b->area_q[a]++;
-                    prev = b->prev[a];
-                    assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
-                    for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
-                       b->mb[k] >>= 1;
-                       if (b->mb[k]) {
-                           b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
-                           prev = k;
-                       } else {
-                           if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
-                                for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
-                                    b->prev[a2] = prev;
-                                assert(a2 < 4);
-                                assert(b->mb[b->next[k]]);
-                                b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
-                                                  -dv_rl2vlc_size(b->next[k] -    k - 1, b->mb[b->next[k]]);
-                                assert(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
-                                b->prev[a2] = prev;
-                           }
-                           b->next[prev] = b->next[k];
-                       }
-                    }
-                    b->prev[a+1]= prev;
-                }
-                size[i] += b->bit_size[a];
-             }
-          }
-          if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
-                return;
-       }
-    } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
-
-
-    for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
-        b = blks;
-        size[0] = 5 * 6 * 4; //EOB
-        for (j = 0; j < 6 *5; j++, b++) {
-            prev = b->prev[0];
-            for (k = b->next[prev]; k < 64; k = b->next[k]) {
-                if (b->mb[k] < a && b->mb[k] > -a){
-                    b->next[prev] = b->next[k];
-                }else{
-                    size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
-                    prev = k;
-                }
-            }
-        }
-    }
-}
-
-static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
-{
-    DVVideoContext *s = avctx->priv_data;
-    DVwork_chunk *work_chunk = arg;
-    int mb_index, i, j;
-    int mb_x, mb_y, c_offset, linesize, y_stride;
-    uint8_t*  y_ptr;
-    uint8_t*  dif;
-    LOCAL_ALIGNED_8(uint8_t, scratch, [128]);
-    EncBlockInfo  enc_blks[5*DV_MAX_BPM];
-    PutBitContext pbs[5*DV_MAX_BPM];
-    PutBitContext* pb;
-    EncBlockInfo* enc_blk;
-    int       vs_bit_size = 0;
-    int       qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */
-    int*      qnosp = &qnos[0];
-
-    dif = &s->buf[work_chunk->buf_offset*80];
-    enc_blk = &enc_blks[0];
-    for (mb_index = 0; mb_index < 5; mb_index++) {
-        dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
-
-        /* initializing luminance blocks */
-        if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) ||
-            (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
-            (s->sys->height >= 720 && mb_y != 134)) {
-            y_stride = s->picture.linesize[0] << 3;
-        } else {
-            y_stride = 16;
-        }
-        y_ptr    = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
-        linesize = s->picture.linesize[0];
-
-        if (s->sys->video_stype == 4) { /* SD 422 */
-            vs_bit_size +=
-            dv_init_enc_block(enc_blk+0, y_ptr               , linesize, s, 0) +
-            dv_init_enc_block(enc_blk+1, NULL                , linesize, s, 0) +
-            dv_init_enc_block(enc_blk+2, y_ptr + 8           , linesize, s, 0) +
-            dv_init_enc_block(enc_blk+3, NULL                , linesize, s, 0);
-        } else {
-            vs_bit_size +=
-            dv_init_enc_block(enc_blk+0, y_ptr               , linesize, s, 0) +
-            dv_init_enc_block(enc_blk+1, y_ptr + 8           , linesize, s, 0) +
-            dv_init_enc_block(enc_blk+2, y_ptr     + y_stride, linesize, s, 0) +
-            dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
-        }
-        enc_blk += 4;
-
-        /* initializing chrominance blocks */
-        c_offset = (((mb_y >>  (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] +
-                     (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << 3);
-        for (j = 2; j; j--) {
-            uint8_t *c_ptr = s->picture.data[j] + c_offset;
-            linesize = s->picture.linesize[j];
-            y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3);
-            if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
-                uint8_t* d;
-                uint8_t* b = scratch;
-                for (i = 0; i < 8; i++) {
-                    d = c_ptr + (linesize << 3);
-                    b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
-                    b[4] =     d[0]; b[5] =     d[1]; b[6] =     d[2]; b[7] =     d[3];
-                    c_ptr += linesize;
-                    b += 16;
-                }
-                c_ptr = scratch;
-                linesize = 16;
-            }
-
-            vs_bit_size += dv_init_enc_block(    enc_blk++, c_ptr           , linesize, s, 1);
-            if (s->sys->bpm == 8) {
-                vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
-            }
-        }
-    }
-
-    if (vs_total_ac_bits < vs_bit_size)
-        dv_guess_qnos(&enc_blks[0], qnosp);
-
-    /* DIF encoding process */
-    for (j=0; j<5*s->sys->bpm;) {
-        int start_mb = j;
-
-        dif[3] = *qnosp++;
-        dif += 4;
-
-        /* First pass over individual cells only */
-        for (i=0; i<s->sys->bpm; i++, j++) {
-            int sz = s->sys->block_sizes[i]>>3;
-
-            init_put_bits(&pbs[j], dif, sz);
-            put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
-            put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
-            put_bits(&pbs[j], 2, enc_blks[j].cno);
-
-            dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
-            dif += sz;
-        }
-
-        /* Second pass over each MB space */
-        pb = &pbs[start_mb];
-        for (i=0; i<s->sys->bpm; i++) {
-            if (enc_blks[start_mb+i].partial_bit_count)
-                pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
-        }
-    }
-
-    /* Third and final pass over the whole video segment space */
-    pb = &pbs[0];
-    for (j=0; j<5*s->sys->bpm; j++) {
-       if (enc_blks[j].partial_bit_count)
-           pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
-       if (enc_blks[j].partial_bit_count)
-            av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
-    }
-
-    for (j=0; j<5*s->sys->bpm; j++) {
-       int pos;
-       int size = pbs[j].size_in_bits >> 3;
-       flush_put_bits(&pbs[j]);
-       pos = put_bits_count(&pbs[j]) >> 3;
-       if (pos > size) {
-           av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
-           return -1;
-       }
-       memset(pbs[j].buf + pos, 0xff, size - pos);
-    }
-
-    return 0;
-}
-
-static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
-                                uint8_t* buf)
-{
-    /*
-     * Here's what SMPTE314M says about these two:
-     *    (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical
-     *             as track application IDs (APTn = 001, AP1n =
-     *             001, AP2n = 001, AP3n = 001), if the source signal
-     *             comes from a digital VCR. If the signal source is
-     *             unknown, all bits for these data shall be set to 1.
-     *    (page 12) STYPE: STYPE defines a signal type of video signal
-     *                     00000b = 4:1:1 compression
-     *                     00100b = 4:2:2 compression
-     *                     XXXXXX = Reserved
-     * Now, I've got two problems with these statements:
-     *   1. it looks like APT == 111b should be a safe bet, but it isn't.
-     *      It seems that for PAL as defined in IEC 61834 we have to set
-     *      APT to 000 and for SMPTE314M to 001.
-     *   2. It is not at all clear what STYPE is used for 4:2:0 PAL
-     *      compression scheme (if any).
-     */
-    int apt   = (c->sys->pix_fmt == AV_PIX_FMT_YUV420P ? 0 : 1);
-
-    uint8_t aspect = 0;
-    if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */
-        aspect = 0x02;
-
-    buf[0] = (uint8_t)pack_id;
-    switch (pack_id) {
-    case dv_header525: /* I can't imagine why these two weren't defined as real */
-    case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
-          buf[1] = 0xf8 |        /* reserved -- always 1 */
-                   (apt & 0x07); /* APT: Track application ID */
-          buf[2] = (0    << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */
-                   (0x0f << 3) | /* reserved -- always 1 */
-                   (apt & 0x07); /* AP1: Audio application ID */
-          buf[3] = (0    << 7) | /* TF2: video data is 0 - valid; 1 - invalid */
-                   (0x0f << 3) | /* reserved -- always 1 */
-                   (apt & 0x07); /* AP2: Video application ID */
-          buf[4] = (0    << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */
-                   (0x0f << 3) | /* reserved -- always 1 */
-                   (apt & 0x07); /* AP3: Subcode application ID */
-          break;
-    case dv_video_source:
-          buf[1] = 0xff;      /* reserved -- always 1 */
-          buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
-                   (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
-                   (3 << 4) | /* CLF: color frames ID (see ITU-R BT.470-4) */
-                   0xf;       /* reserved -- always 1 */
-          buf[3] = (3 << 6) | /* reserved -- always 1 */
-                   (c->sys->dsf << 5) | /*  system: 60fields/50fields */
-                   c->sys->video_stype; /* signal type video compression */
-          buf[4] = 0xff;      /* VISC: 0xff -- no information */
-          break;
-    case dv_video_control:
-          buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
-                   0x3f;      /* reserved -- always 1 */
-          buf[2] = 0xc8 |     /* reserved -- always b11001xxx */
-                   aspect;
-          buf[3] = (1 << 7) | /* frame/field flag 1 -- frame, 0 -- field */
-                   (1 << 6) | /* first/second field flag 0 -- field 2, 1 -- field 1 */
-                   (1 << 5) | /* frame change flag 0 -- same picture as before, 1 -- different */
-                   (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
-                   0xc;       /* reserved -- always b1100 */
-          buf[4] = 0xff;      /* reserved -- always 1 */
-          break;
-    default:
-          buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
-    }
-    return 5;
-}
-
-#if CONFIG_DVVIDEO_ENCODER
-static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
-                                  uint8_t seq_num, uint8_t dif_num,
-                                  uint8_t* buf)
-{
-    buf[0] = (uint8_t)t;       /* Section type */
-    buf[1] = (seq_num  << 4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */
-             (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */
-             7;                /* reserved -- always 1 */
-    buf[2] = dif_num;          /* DIF block number Video: 0-134, Audio: 0-8 */
-    return 3;
-}
-
-
-static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf)
-{
-    if (syb_num == 0 || syb_num == 6) {
-        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
-                 (0  << 4) | /* AP3 (Subcode application ID) */
-                 0x0f;       /* reserved -- always 1 */
-    }
-    else if (syb_num == 11) {
-        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
-                 0x7f;       /* reserved -- always 1 */
-    }
-    else {
-        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
-                 (0  << 4) | /* APT (Track application ID) */
-                 0x0f;       /* reserved -- always 1 */
-    }
-    buf[1] = 0xf0 |            /* reserved -- always 1 */
-             (syb_num & 0x0f); /* SSYB number 0 - 11   */
-    buf[2] = 0xff;             /* reserved -- always 1 */
-    return 3;
-}
-
-static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
-{
-    int chan, i, j, k;
-
-    for (chan = 0; chan < c->sys->n_difchan; chan++) {
-        for (i = 0; i < c->sys->difseg_size; i++) {
-            memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */
-
-            /* DV header: 1DIF */
-            buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
-            buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
-            buf += 72; /* unused bytes */
-
-            /* DV subcode: 2DIFs */
-            for (j = 0; j < 2; j++) {
-                buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
-                for (k = 0; k < 6; k++)
-                     buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
-                buf += 29; /* unused bytes */
-            }
-
-            /* DV VAUX: 3DIFS */
-            for (j = 0; j < 3; j++) {
-                buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
-                buf += dv_write_pack(dv_video_source,  c, buf);
-                buf += dv_write_pack(dv_video_control, c, buf);
-                buf += 7*5;
-                buf += dv_write_pack(dv_video_source,  c, buf);
-                buf += dv_write_pack(dv_video_control, c, buf);
-                buf += 4*5 + 2; /* unused bytes */
-            }
-
-            /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
-            for (j = 0; j < 135; j++) {
-                if (j%15 == 0) {
-                    memset(buf, 0xff, 80);
-                    buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
-                    buf += 77; /* audio control & shuffled PCM audio */
-                }
-                buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
-                buf += 77; /* 1 video macroblock: 1 bytes control
-                              4 * 14 bytes Y 8x8 data
-                              10 bytes Cr 8x8 data
-                              10 bytes Cb 8x8 data */
-            }
-        }
-    }
-}
-
-
-static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
-                                const AVFrame *frame, int *got_packet)
-{
-    DVVideoContext *s = c->priv_data;
-    int ret;
-
-    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");
-        return ret;
-    }
-
-    c->pix_fmt           = s->sys->pix_fmt;
-    s->picture           = *frame;
-    s->picture.key_frame = 1;
-    s->picture.pict_type = AV_PICTURE_TYPE_I;
-
-    s->buf = pkt->data;
-    c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
-               dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
-
-    emms_c();
-
-    dv_format_frame(s, pkt->data);
-
-    pkt->flags |= AV_PKT_FLAG_KEY;
-    *got_packet = 1;
-
-    return 0;
-}
-
-AVCodec ff_dvvideo_encoder = {
-    .name           = "dvvideo",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_DVVIDEO,
-    .priv_data_size = sizeof(DVVideoContext),
-    .init           = dvvideo_init_encoder,
-    .encode2        = dvvideo_encode_frame,
-    .capabilities   = CODEC_CAP_SLICE_THREADS,
-    .pix_fmts       = (const enum AVPixelFormat[]) {
-        AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
-    },
-    .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
-};
-#endif // CONFIG_DVVIDEO_ENCODER
diff --git a/libavcodec/dv.h b/libavcodec/dv.h
new file mode 100644
index 0000000..01a4eec
--- /dev/null
+++ b/libavcodec/dv.h
@@ -0,0 +1,118 @@
+/*
+ * Constants for DV codec
+ * Copyright (c) 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
+ */
+
+/**
+ * @file
+ * Constants for DV codec.
+ */
+
+#ifndef AVCODEC_DV_H
+#define AVCODEC_DV_H
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "get_bits.h"
+#include "dv_profile.h"
+
+typedef struct DVVideoContext {
+    const DVprofile *sys;
+    AVFrame         *frame;
+    AVCodecContext  *avctx;
+    uint8_t         *buf;
+
+    uint8_t  dv_zigzag[2][64];
+
+    void (*get_pixels)(int16_t *block, const uint8_t *pixels, int line_size);
+    void (*fdct[2])(int16_t *block);
+    void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block);
+    me_cmp_func ildct_cmp;
+} DVVideoContext;
+
+enum dv_section_type {
+     dv_sect_header  = 0x1f,
+     dv_sect_subcode = 0x3f,
+     dv_sect_vaux    = 0x56,
+     dv_sect_audio   = 0x76,
+     dv_sect_video   = 0x96,
+};
+
+enum dv_pack_type {
+     dv_header525     = 0x3f, /* see dv_write_pack for important details on */
+     dv_header625     = 0xbf, /* these two packs */
+     dv_timecode      = 0x13,
+     dv_audio_source  = 0x50,
+     dv_audio_control = 0x51,
+     dv_audio_recdate = 0x52,
+     dv_audio_rectime = 0x53,
+     dv_video_source  = 0x60,
+     dv_video_control = 0x61,
+     dv_video_recdate = 0x62,
+     dv_video_rectime = 0x63,
+     dv_unknown_pack  = 0xff,
+};
+
+#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10)
+#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)
+ */
+#define DV_MAX_FRAME_SIZE 576000
+
+/**
+ * maximum number of blocks per macroblock in any DV format
+ */
+#define DV_MAX_BPM 8
+
+#define TEX_VLC_BITS 9
+
+extern RL_VLC_ELEM ff_dv_rl_vlc[1184];
+
+int ff_dv_init_dynamic_tables(const DVprofile *d);
+int ff_dvvideo_init(AVCodecContext *avctx);
+
+static inline int dv_work_pool_size(const DVprofile *d)
+{
+    int size = d->n_difchan*d->difseg_size*27;
+    if (DV_PROFILE_IS_1080i50(d))
+        size -= 3*27;
+    if (DV_PROFILE_IS_720p50(d))
+        size -= 4*27;
+    return size;
+}
+
+static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
+{
+     *mb_x = work_chunk->mb_coordinates[m] & 0xff;
+     *mb_y = work_chunk->mb_coordinates[m] >> 8;
+
+     /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */
+     if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
+         *mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */
+     }
+}
+
+#endif /* AVCODEC_DV_H */
diff --git a/libavcodec/dv_tablegen.c b/libavcodec/dv_tablegen.c
index f463550..9b2b954 100644
--- a/libavcodec/dv_tablegen.c
+++ b/libavcodec/dv_tablegen.c
@@ -22,9 +22,6 @@
 
 #include <stdlib.h>
 #define CONFIG_HARDCODED_TABLES 0
-#ifndef CONFIG_SMALL
-#error CONFIG_SMALL must be defined to generate tables
-#endif
 #include "dv_tablegen.h"
 #include "tableprint.h"
 #include <inttypes.h>
diff --git a/libavcodec/dv_tablegen.h b/libavcodec/dv_tablegen.h
index 05831ea..2f3fd95 100644
--- a/libavcodec/dv_tablegen.h
+++ b/libavcodec/dv_tablegen.h
@@ -25,7 +25,7 @@
 
 #include <stdint.h>
 
-#include "dv_vlc_data.h"
+#include "dvdata.h"
 
 #if CONFIG_SMALL
 #define DV_VLC_MAP_RUN_SIZE 15
@@ -51,20 +51,20 @@ static void dv_vlc_map_tableinit(void)
 {
     int i, j;
     for (i = 0; i < NB_DV_VLC - 1; i++) {
-       if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
+       if (ff_dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)
            continue;
 #if CONFIG_SMALL
-       if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
+       if (ff_dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)
            continue;
 #endif
 
-       if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0)
+       if (dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].size != 0)
            continue;
 
-       dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc  =
-           dv_vlc_bits[i] << (!!dv_vlc_level[i]);
-       dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size =
-           dv_vlc_len[i] + (!!dv_vlc_level[i]);
+       dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].vlc  =
+           ff_dv_vlc_bits[i] << (!!ff_dv_vlc_level[i]);
+       dv_vlc_map[ff_dv_vlc_run[i]][ff_dv_vlc_level[i]].size =
+           ff_dv_vlc_len[i] + (!!ff_dv_vlc_level[i]);
     }
     for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) {
 #if CONFIG_SMALL
diff --git a/libavcodec/dv_vlc_data.h b/libavcodec/dv_vlc_data.h
deleted file mode 100644
index d62fd6b..0000000
--- a/libavcodec/dv_vlc_data.h
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * VLC constants for DV codec
- * Copyright (c) 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
- */
-
-/**
- * @file
- * VLC constants for DV codec.
- */
-
-#ifndef AVCODEC_DV_VLC_DATA_H
-#define AVCODEC_DV_VLC_DATA_H
-
-#include <stdint.h>
-
-#define NB_DV_VLC 409
-
-/*
- * There's a catch about the following three tables: the mapping they establish
- * between (run, level) and vlc is not 1-1. So you have to watch out for that
- * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82.
- */
-static const uint16_t dv_vlc_bits[NB_DV_VLC] = {
- 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016,
- 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a,
- 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2,
- 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea,
- 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2,
- 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea,
- 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2,
- 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1,
- 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
- 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
- 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
- 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
- 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
- 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97,
- 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,
- 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7,
- 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf,
- 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7,
- 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf,
- 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07,
- 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f,
- 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17,
- 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f,
- 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27,
- 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f,
- 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37,
- 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f,
- 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47,
- 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f,
- 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57,
- 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f,
- 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67,
- 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f,
- 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77,
- 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f,
- 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87,
- 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f,
- 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97,
- 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f,
- 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7,
- 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf,
- 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7,
- 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf,
- 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7,
- 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf,
- 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7,
- 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf,
- 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7,
- 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef,
- 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7,
- 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff,
- 0x0006,
-};
-
-static const uint8_t dv_vlc_len[NB_DV_VLC] = {
-  2,  3,  4,  4,  4,  5,  5,  5,
-  5,  6,  6,  6,  6,  7,  7,  7,
-  7,  7,  7,  7,  7,  8,  8,  8,
-  8,  8,  8,  8,  8,  8,  8,  8,
-  8,  8,  8,  8,  8,  9,  9,  9,
-  9,  9,  9,  9,  9,  9,  9,  9,
-  9,  9,  9,  9,  9, 10, 10, 10,
- 10, 10, 10, 10, 11, 11, 11, 11,
- 11, 11, 11, 11, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 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,
- 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,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
-  4,
-};
-
-static const uint8_t dv_vlc_run[NB_DV_VLC] = {
-  0,  0,  1,  0,  0,  2,  1,  0,
-  0,  3,  4,  0,  0,  5,  6,  2,
-  1,  1,  0,  0,  0,  7,  8,  9,
- 10,  3,  4,  2,  1,  1,  1,  0,
-  0,  0,  0,  0,  0, 11, 12, 13,
- 14,  5,  6,  3,  4,  2,  2,  1,
-  0,  0,  0,  0,  0,  5,  3,  3,
-  2,  1,  1,  1,  0,  1,  6,  4,
-  3,  1,  1,  1,  2,  3,  4,  5,
-  7,  8,  9, 10,  7,  8,  4,  3,
-  2,  2,  2,  2,  2,  1,  1,  1,
-  0,  1,  2,  3,  4,  5,  6,  7,
-  8,  9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,
-127,
-};
-
-static const uint8_t dv_vlc_level[NB_DV_VLC] = {
-   1,   2,   1,   3,   4,   1,   2,   5,
-   6,   1,   1,   7,   8,   1,   1,   2,
-   3,   4,   9,  10,  11,   1,   1,   1,
-   1,   2,   2,   3,   5,   6,   7,  12,
-  13,  14,  15,  16,  17,   1,   1,   1,
-   1,   2,   2,   3,   3,   4,   5,   8,
-  18,  19,  20,  21,  22,   3,   4,   5,
-   6,   9,  10,  11,   0,   0,   3,   4,
-   6,  12,  13,  14,   0,   0,   0,   0,
-   2,   2,   2,   2,   3,   3,   5,   7,
-   7,   8,   9,  10,  11,  15,  16,  17,
-   0,   0,   0,   0,   0,   0,   0,   0,
-   0,   0,   0,   0,   0,   0,   0,   0,
-   0,   0,   0,   0,   0,   0,   0,   0,
-   0,   0,   0,   0,   0,   0,   0,   0,
-   0,   0,   0,   0,   0,   0,   0,   0,
-   0,   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,   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,  65,  66,  67,  68,  69,  70,  71,
-  72,  73,  74,  75,  76,  77,  78,  79,
-  80,  81,  82,  83,  84,  85,  86,  87,
-  88,  89,  90,  91,  92,  93,  94,  95,
-  96,  97,  98,  99, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127,
- 128, 129, 130, 131, 132, 133, 134, 135,
- 136, 137, 138, 139, 140, 141, 142, 143,
- 144, 145, 146, 147, 148, 149, 150, 151,
- 152, 153, 154, 155, 156, 157, 158, 159,
- 160, 161, 162, 163, 164, 165, 166, 167,
- 168, 169, 170, 171, 172, 173, 174, 175,
- 176, 177, 178, 179, 180, 181, 182, 183,
- 184, 185, 186, 187, 188, 189, 190, 191,
- 192, 193, 194, 195, 196, 197, 198, 199,
- 200, 201, 202, 203, 204, 205, 206, 207,
- 208, 209, 210, 211, 212, 213, 214, 215,
- 216, 217, 218, 219, 220, 221, 222, 223,
- 224, 225, 226, 227, 228, 229, 230, 231,
- 232, 233, 234, 235, 236, 237, 238, 239,
- 240, 241, 242, 243, 244, 245, 246, 247,
- 248, 249, 250, 251, 252, 253, 254, 255,
-   0,
-};
-
-#endif /* AVCODEC_DV_VLC_DATA_H */
diff --git a/libavcodec/dvbsub.c b/libavcodec/dvbsub.c
index 26d14bd..de0808f 100644
--- a/libavcodec/dvbsub.c
+++ b/libavcodec/dvbsub.c
@@ -404,9 +404,9 @@ static int dvbsub_encode(AVCodecContext *avctx,
 
 AVCodec ff_dvbsub_encoder = {
     .name           = "dvbsub",
+    .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
     .type           = AVMEDIA_TYPE_SUBTITLE,
     .id             = AV_CODEC_ID_DVB_SUBTITLE,
     .priv_data_size = sizeof(DVBSubtitleContext),
     .encode_sub     = dvbsub_encode,
-    .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
 };
diff --git a/libavcodec/dvbsub_parser.c b/libavcodec/dvbsub_parser.c
index c13aab6..295e03b 100644
--- a/libavcodec/dvbsub_parser.c
+++ b/libavcodec/dvbsub_parser.c
@@ -19,7 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
 
 /* Parser (mostly) copied from dvdsub.c */
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index b4aba49..6ce187f 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -34,8 +34,6 @@
 #define cm (ff_cropTbl + MAX_NEG_CROP)
 
 #ifdef DEBUG
-#undef fprintf
-#undef perror
 #if 0
 static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
                      uint32_t *rgba_palette)
@@ -1465,11 +1463,11 @@ static int dvbsub_decode(AVCodecContext *avctx,
 
 AVCodec ff_dvbsub_decoder = {
     .name           = "dvbsub",
+    .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
     .type           = AVMEDIA_TYPE_SUBTITLE,
     .id             = AV_CODEC_ID_DVB_SUBTITLE,
     .priv_data_size = sizeof(DVBSubContext),
     .init           = dvbsub_init_decoder,
     .close          = dvbsub_close_decoder,
     .decode         = dvbsub_decode,
-    .long_name      = NULL_IF_CONFIG_SMALL("DVB subtitles"),
 };
diff --git a/libavcodec/dvdata.c b/libavcodec/dvdata.c
index c779277..f9c22ac 100644
--- a/libavcodec/dvdata.c
+++ b/libavcodec/dvdata.c
@@ -24,7 +24,8 @@
  * Constants for DV codec.
  */
 
-#include "avcodec.h"
+#include <stdint.h>
+
 #include "dvdata.h"
 
 /* unquant tables (not used directly) */
@@ -120,3 +121,227 @@ const int ff_dv_iweight_720_c[64] = {
     394, 406, 418, 438, 418, 464, 464, 492,
 };
 
+/*
+ * There's a catch about the following three tables: the mapping they establish
+ * between (run, level) and vlc is not 1-1. So you have to watch out for that
+ * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82.
+ */
+const uint16_t ff_dv_vlc_bits[NB_DV_VLC] = {
+ 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016,
+ 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a,
+ 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2,
+ 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea,
+ 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2,
+ 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea,
+ 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2,
+ 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1,
+ 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
+ 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
+ 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
+ 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
+ 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
+ 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97,
+ 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,
+ 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7,
+ 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf,
+ 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7,
+ 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf,
+ 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07,
+ 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f,
+ 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17,
+ 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f,
+ 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27,
+ 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f,
+ 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37,
+ 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f,
+ 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47,
+ 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f,
+ 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57,
+ 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f,
+ 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67,
+ 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f,
+ 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77,
+ 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f,
+ 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87,
+ 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f,
+ 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97,
+ 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f,
+ 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7,
+ 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf,
+ 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7,
+ 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf,
+ 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7,
+ 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf,
+ 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7,
+ 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf,
+ 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7,
+ 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef,
+ 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7,
+ 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff,
+ 0x0006,
+};
+
+const uint8_t ff_dv_vlc_len[NB_DV_VLC] = {
+  2,  3,  4,  4,  4,  5,  5,  5,
+  5,  6,  6,  6,  6,  7,  7,  7,
+  7,  7,  7,  7,  7,  8,  8,  8,
+  8,  8,  8,  8,  8,  8,  8,  8,
+  8,  8,  8,  8,  8,  9,  9,  9,
+  9,  9,  9,  9,  9,  9,  9,  9,
+  9,  9,  9,  9,  9, 10, 10, 10,
+ 10, 10, 10, 10, 11, 11, 11, 11,
+ 11, 11, 11, 11, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 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,
+ 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,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+  4,
+};
+
+const uint8_t ff_dv_vlc_run[NB_DV_VLC] = {
+  0,  0,  1,  0,  0,  2,  1,  0,
+  0,  3,  4,  0,  0,  5,  6,  2,
+  1,  1,  0,  0,  0,  7,  8,  9,
+ 10,  3,  4,  2,  1,  1,  1,  0,
+  0,  0,  0,  0,  0, 11, 12, 13,
+ 14,  5,  6,  3,  4,  2,  2,  1,
+  0,  0,  0,  0,  0,  5,  3,  3,
+  2,  1,  1,  1,  0,  1,  6,  4,
+  3,  1,  1,  1,  2,  3,  4,  5,
+  7,  8,  9, 10,  7,  8,  4,  3,
+  2,  2,  2,  2,  2,  1,  1,  1,
+  0,  1,  2,  3,  4,  5,  6,  7,
+  8,  9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,
+127,
+};
+
+const uint8_t ff_dv_vlc_level[NB_DV_VLC] = {
+   1,   2,   1,   3,   4,   1,   2,   5,
+   6,   1,   1,   7,   8,   1,   1,   2,
+   3,   4,   9,  10,  11,   1,   1,   1,
+   1,   2,   2,   3,   5,   6,   7,  12,
+  13,  14,  15,  16,  17,   1,   1,   1,
+   1,   2,   2,   3,   3,   4,   5,   8,
+  18,  19,  20,  21,  22,   3,   4,   5,
+   6,   9,  10,  11,   0,   0,   3,   4,
+   6,  12,  13,  14,   0,   0,   0,   0,
+   2,   2,   2,   2,   3,   3,   5,   7,
+   7,   8,   9,  10,  11,  15,  16,  17,
+   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   0,   0,   0,   0,   0,   0,   0,
+   0,   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,   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,  65,  66,  67,  68,  69,  70,  71,
+  72,  73,  74,  75,  76,  77,  78,  79,
+  80,  81,  82,  83,  84,  85,  86,  87,
+  88,  89,  90,  91,  92,  93,  94,  95,
+  96,  97,  98,  99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255,
+   0,
+};
diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h
index c50fa5f..164ef1b 100644
--- a/libavcodec/dvdata.h
+++ b/libavcodec/dvdata.h
@@ -1,7 +1,4 @@
 /*
- * Constants for DV codec
- * Copyright (c) 2002 Fabrice Bellard
- *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -19,55 +16,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/**
- * @file
- * Constants for DV codec.
- */
-
 #ifndef AVCODEC_DVDATA_H
 #define AVCODEC_DVDATA_H
 
-#include "avcodec.h"
-#include "dsputil.h"
-#include "get_bits.h"
-#include "dv_profile.h"
-
-typedef struct DVVideoContext {
-    const DVprofile *sys;
-    AVFrame          picture;
-    AVCodecContext  *avctx;
-    uint8_t         *buf;
-
-    uint8_t  dv_zigzag[2][64];
-
-    void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size);
-    void (*fdct[2])(DCTELEM *block);
-    void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
-    me_cmp_func ildct_cmp;
-} DVVideoContext;
-
-enum dv_section_type {
-     dv_sect_header  = 0x1f,
-     dv_sect_subcode = 0x3f,
-     dv_sect_vaux    = 0x56,
-     dv_sect_audio   = 0x76,
-     dv_sect_video   = 0x96,
-};
-
-enum dv_pack_type {
-     dv_header525     = 0x3f, /* see dv_write_pack for important details on */
-     dv_header625     = 0xbf, /* these two packs */
-     dv_timecode      = 0x13,
-     dv_audio_source  = 0x50,
-     dv_audio_control = 0x51,
-     dv_audio_recdate = 0x52,
-     dv_audio_rectime = 0x53,
-     dv_video_source  = 0x60,
-     dv_video_control = 0x61,
-     dv_video_recdate = 0x62,
-     dv_video_rectime = 0x63,
-     dv_unknown_pack  = 0xff,
-};
+#include <stdint.h>
 
 extern const uint8_t ff_dv_quant_shifts[22][4];
 extern const uint8_t ff_dv_quant_offset[4];
@@ -79,50 +31,11 @@ extern const int ff_dv_iweight_1080_c[64];
 extern const int ff_dv_iweight_720_y[64];
 extern const int ff_dv_iweight_720_c[64];
 
-#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10)
-#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)
- */
-#define DV_MAX_FRAME_SIZE 576000
-
-/**
- * maximum number of blocks per macroblock in any DV format
- */
-#define DV_MAX_BPM 8
-
-#define TEX_VLC_BITS 9
-
-extern RL_VLC_ELEM ff_dv_rl_vlc[1184];
-
-int ff_dv_init_dynamic_tables(const DVprofile *d);
-int ff_dvvideo_init(AVCodecContext *avctx);
-
-static inline int dv_work_pool_size(const DVprofile *d)
-{
-    int size = d->n_difchan*d->difseg_size*27;
-    if (DV_PROFILE_IS_1080i50(d))
-        size -= 3*27;
-    if (DV_PROFILE_IS_720p50(d))
-        size -= 4*27;
-    return size;
-}
-
-static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
-{
-     *mb_x = work_chunk->mb_coordinates[m] & 0xff;
-     *mb_y = work_chunk->mb_coordinates[m] >> 8;
+#define NB_DV_VLC 409
 
-     /* We work with 720p frames split in half. The odd half-frame (chan==2,3) is displaced :-( */
-     if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
-         *mb_y -= (*mb_y>17)?18:-72; /* shifting the Y coordinate down by 72/2 macro blocks */
-     }
-}
+extern const uint16_t ff_dv_vlc_bits[NB_DV_VLC];
+extern const uint8_t ff_dv_vlc_len[NB_DV_VLC];
+extern const uint8_t ff_dv_vlc_run[NB_DV_VLC];
+extern const uint8_t ff_dv_vlc_level[NB_DV_VLC];
 
 #endif /* AVCODEC_DVDATA_H */
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index bc1bb55..ef9ba4c 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -35,20 +35,21 @@
  * DV decoder
  */
 
+#include "libavutil/internal.h"
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "get_bits.h"
 #include "put_bits.h"
 #include "simple_idct.h"
 #include "dvdata.h"
+#include "dv.h"
 
 typedef struct BlockInfo {
     const uint32_t *factor_table;
     const uint8_t *scan_table;
     uint8_t pos; /* position in block */
-    void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
+    void (*idct_put)(uint8_t *dest, int line_size, int16_t *block);
     uint8_t partial_bit_count;
     uint32_t partial_bit_buffer;
     int shift_offset;
@@ -57,7 +58,7 @@ typedef struct BlockInfo {
 static const int dv_iweight_bits = 14;
 
 /* decode AC coefficients */
-static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
+static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, int16_t *block)
 {
     int last_index = gb->size_in_bits;
     const uint8_t  *scan_table   = mb->scan_table;
@@ -135,14 +136,14 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
     int quant, dc, dct_mode, class1, j;
     int mb_index, mb_x, mb_y, last_index;
     int y_stride, linesize;
-    DCTELEM *block, *block1;
+    int16_t *block, *block1;
     int c_offset;
     uint8_t *y_ptr;
     const uint8_t *buf_ptr;
     PutBitContext pb, vs_pb;
     GetBitContext gb;
     BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
-    LOCAL_ALIGNED_16(DCTELEM, sblock, [5*DV_MAX_BPM], [64]);
+    LOCAL_ALIGNED_16(int16_t, sblock, [5*DV_MAX_BPM], [64]);
     LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [  80 + FF_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
     LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5*80 + FF_INPUT_BUFFER_PADDING_SIZE]); /* allow some slack */
     const int log2_blocksize = 3;
@@ -257,12 +258,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
         if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) ||
             (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
             (s->sys->height >= 720 && mb_y != 134)) {
-            y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
+            y_stride = (s->frame->linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
         } else {
             y_stride = (2 << log2_blocksize);
         }
-        y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize);
-        linesize = s->picture.linesize[0] << is_field_mode[mb_index];
+        y_ptr = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << log2_blocksize);
+        linesize = s->frame->linesize[0] << is_field_mode[mb_index];
         mb[0]    .idct_put(y_ptr                                   , linesize, block + 0*64);
         if (s->sys->video_stype == 4) { /* SD 422 */
             mb[2].idct_put(y_ptr + (1 << log2_blocksize)           , linesize, block + 2*64);
@@ -275,19 +276,19 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
         block += 4*64;
 
         /* idct_put'ting chrominance */
-        c_offset = (((mb_y >>  (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] +
+        c_offset = (((mb_y >>  (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] +
                      (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize);
         for (j = 2; j; j--) {
-            uint8_t *c_ptr = s->picture.data[j] + c_offset;
+            uint8_t *c_ptr = s->frame->data[j] + c_offset;
             if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
                   uint64_t aligned_pixels[64/8];
                   uint8_t *pixels = (uint8_t*)aligned_pixels;
                   uint8_t *c_ptr1, *ptr1;
                   int x, y;
                   mb->idct_put(pixels, 8, block);
-                  for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
+                  for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->frame->linesize[j], pixels += 8) {
                       ptr1   = pixels + (1 << (log2_blocksize - 1));
-                      c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize);
+                      c_ptr1 = c_ptr + (s->frame->linesize[j] << log2_blocksize);
                       for (x = 0; x < (1 << (log2_blocksize - 1)); x++) {
                           c_ptr[x]  = pixels[x];
                           c_ptr1[x] = ptr1[x];
@@ -296,8 +297,8 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
                   block += 64; mb++;
             } else {
                   y_stride = (mb_y == 134) ? (1 << log2_blocksize) :
-                                             s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
-                  linesize = s->picture.linesize[j] << is_field_mode[mb_index];
+                                             s->frame->linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
+                  linesize = s->frame->linesize[j] << is_field_mode[mb_index];
                   (mb++)->    idct_put(c_ptr           , linesize, block); block += 64;
                   if (s->sys->bpm == 8) {
                       (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64;
@@ -318,7 +319,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     DVVideoContext *s = avctx->priv_data;
     const uint8_t* vsc_pack;
-    int apt, is16_9;
+    int apt, is16_9, ret;
 
     s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size);
     if (!s->sys || buf_size < s->sys->frame_size || ff_dv_init_dynamic_tables(s->sys)) {
@@ -326,21 +327,22 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
         return -1; /* NOTE: we only accept several full frames */
     }
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    s->picture.reference = 0;
-    s->picture.key_frame = 1;
-    s->picture.pict_type = AV_PICTURE_TYPE_I;
+    s->frame            = data;
+    s->frame->key_frame = 1;
+    s->frame->pict_type = AV_PICTURE_TYPE_I;
     avctx->pix_fmt   = s->sys->pix_fmt;
     avctx->time_base = s->sys->time_base;
-    avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
-    if (ff_get_buffer(avctx, &s->picture) < 0) {
+
+    ret = ff_set_dimensions(avctx, s->sys->width, s->sys->height);
+    if (ret < 0)
+        return ret;
+
+    if (ff_get_buffer(avctx, s->frame, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
-    s->picture.interlaced_frame = 1;
-    s->picture.top_field_first  = 0;
+    s->frame->interlaced_frame = 1;
+    s->frame->top_field_first  = 0;
 
     s->buf = buf;
     avctx->execute(avctx, dv_decode_video_segment, s->sys->work_chunks, NULL,
@@ -350,7 +352,6 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
 
     /* return image */
     *got_frame = 1;
-    *(AVFrame*)data = s->picture;
 
     /* Determine the codec's sample_aspect ratio from the packet */
     vsc_pack = buf + 80*5 + 48 + 5;
@@ -363,24 +364,13 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
     return s->sys->frame_size;
 }
 
-static int dvvideo_close(AVCodecContext *c)
-{
-    DVVideoContext *s = c->priv_data;
-
-    if (s->picture.data[0])
-        c->release_buffer(c, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_dvvideo_decoder = {
     .name           = "dvvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DVVIDEO,
     .priv_data_size = sizeof(DVVideoContext),
     .init           = ff_dvvideo_init,
-    .close          = dvvideo_close,
     .decode         = dvvideo_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
-    .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
 };
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index e52205d..6b168cb 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -21,13 +21,21 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
+
+#include "libavutil/attributes.h"
 #include "libavutil/colorspace.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/avstring.h"
 
-//#define DEBUG
+typedef struct DVDSubContext {
+    uint32_t palette[16];
+    int      has_palette;
+} 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;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     uint8_t r, g, b;
     int i, y, cb, cr;
     int r_add, g_add, b_add;
@@ -115,7 +123,8 @@ static int decode_rle(uint8_t *bitmap, int linesize, int w, int h,
     return 0;
 }
 
-static void guess_palette(uint32_t *rgba_palette,
+static void guess_palette(DVDSubContext* ctx,
+                          uint32_t *rgba_palette,
                           uint8_t *colormap,
                           uint8_t *alpha,
                           uint32_t subtitle_color)
@@ -123,6 +132,13 @@ static void guess_palette(uint32_t *rgba_palette,
     uint8_t color_used[16] = { 0 };
     int nb_opaque_colors, i, level, j, r, g, b;
 
+    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;
 
@@ -159,13 +175,13 @@ static void guess_palette(uint32_t *rgba_palette,
 
 #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[4] = { 0 }, alpha[256] = { 0 };
     int date;
     int i;
     int is_menu = 0;
@@ -325,7 +341,8 @@ static int decode_dvd_subtitles(AVSubtitle *sub_header,
                     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],
+                    guess_palette(ctx,
+                                  (uint32_t*)sub_header->rects[0]->pict.data[1],
                                   colormap, alpha, 0xffff00);
                 }
                 sub_header->rects[0]->x = x1;
@@ -422,9 +439,6 @@ static int find_smallest_bounding_rectangle(AVSubtitle *s)
 }
 
 #ifdef DEBUG
-#undef fprintf
-#undef perror
-#undef exit
 static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h,
                      uint32_t *rgba_palette)
 {
@@ -456,12 +470,13 @@ static int dvdsub_decode(AVCodecContext *avctx,
                          void *data, int *data_size,
                          AVPacket *avpkt)
 {
+    DVDSubContext *ctx = 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 +499,52 @@ static int dvdsub_decode(AVCodecContext *avctx,
     return buf_size;
 }
 
+static av_cold int dvdsub_init(AVCodecContext *avctx)
+{
+    DVDSubContext *ctx = avctx->priv_data;
+    char *data, *cur;
+
+    if (!avctx->extradata || !avctx->extradata_size)
+        return 0;
+
+    data = av_malloc(avctx->extradata_size + 1);
+    if (!data)
+        return AVERROR(ENOMEM);
+    memcpy(data, avctx->extradata, avctx->extradata_size);
+    data[avctx->extradata_size] = '\0';
+    cur = data;
+
+    while (*cur) {
+        if (strncmp("palette:", cur, 8) == 0) {
+            int i;
+            char *p = cur + 8;
+            ctx->has_palette = 1;
+            for (i = 0; i < 16; i++) {
+                ctx->palette[i] = strtoul(p, &p, 16);
+                while (*p == ',' || av_isspace(*p))
+                    p++;
+            }
+        } else if (!strncmp("size:", cur, 5)) {
+            int w, h;
+            if (sscanf(cur + 5, "%dx%d", &w, &h) == 2) {
+               int ret = ff_set_dimensions(avctx, w, h);
+               if (ret < 0)
+                   return ret;
+            }
+        }
+        cur += strcspn(cur, "\n\r");
+        cur += strspn(cur, "\n\r");
+    }
+    av_free(data);
+    return 0;
+}
+
 AVCodec ff_dvdsub_decoder = {
     .name           = "dvdsub",
+    .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),
     .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..db6749e 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -217,8 +217,8 @@ static int dvdsub_encode(AVCodecContext *avctx,
 
 AVCodec ff_dvdsub_encoder = {
     .name           = "dvdsub",
+    .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),
     .type           = AVMEDIA_TYPE_SUBTITLE,
     .id             = AV_CODEC_ID_DVD_SUBTITLE,
     .encode_sub     = dvdsub_encode,
-    .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),
 };
diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c
new file mode 100644
index 0000000..73c07f2
--- /dev/null
+++ b/libavcodec/dvenc.c
@@ -0,0 +1,709 @@
+/*
+ * DV encoder
+ * Copyright (c) 2003 Roman Shaposhnik
+ *
+ * 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
+ * DV encoder
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/pixdesc.h"
+#include "config.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "put_bits.h"
+#include "dv.h"
+#include "dv_tablegen.h"
+
+static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
+{
+    if (!avpriv_dv_codec_profile(avctx)) {
+        av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video. "
+               "Valid DV profiles are:\n",
+               avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
+        ff_dv_print_profiles(avctx, AV_LOG_ERROR);
+        return AVERROR(EINVAL);
+    }
+
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    dv_vlc_map_tableinit();
+
+    return ff_dvvideo_init(avctx);
+}
+
+/* bit budget for AC only in 5 MBs */
+static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
+static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
+
+#if CONFIG_SMALL
+/* Converts run and level (where level != 0) pair into VLC, returning bit size */
+static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
+{
+    int size;
+    if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
+        *vlc = dv_vlc_map[run][level].vlc | sign;
+        size = dv_vlc_map[run][level].size;
+    }
+    else {
+        if (level < DV_VLC_MAP_LEV_SIZE) {
+            *vlc = dv_vlc_map[0][level].vlc | sign;
+            size = dv_vlc_map[0][level].size;
+        } else {
+            *vlc = 0xfe00 | (level << 1) | sign;
+            size = 16;
+        }
+        if (run) {
+            *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
+                                  (0x1f80 | (run - 1))) << size;
+            size +=  (run < 16) ? dv_vlc_map[run-1][0].size : 13;
+        }
+    }
+
+    return size;
+}
+
+static av_always_inline int dv_rl2vlc_size(int run, int level)
+{
+    int size;
+
+    if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
+        size = dv_vlc_map[run][level].size;
+    }
+    else {
+        size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
+        if (run) {
+            size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
+        }
+    }
+    return size;
+}
+#else
+static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
+{
+    *vlc = dv_vlc_map[run][l].vlc | sign;
+    return dv_vlc_map[run][l].size;
+}
+
+static av_always_inline int dv_rl2vlc_size(int run, int l)
+{
+    return dv_vlc_map[run][l].size;
+}
+#endif
+
+typedef struct EncBlockInfo {
+    int      area_q[4];
+    int      bit_size[4];
+    int      prev[5];
+    int      cur_ac;
+    int      cno;
+    int      dct_mode;
+    int16_t  mb[64];
+    uint8_t  next[64];
+    uint8_t  sign[64];
+    uint8_t  partial_bit_count;
+    uint32_t partial_bit_buffer; /* we can't use uint16_t here */
+} EncBlockInfo;
+
+static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
+                                                    PutBitContext* pb_pool,
+                                                    PutBitContext* pb_end)
+{
+    int prev, bits_left;
+    PutBitContext* pb = pb_pool;
+    int size = bi->partial_bit_count;
+    uint32_t vlc = bi->partial_bit_buffer;
+
+    bi->partial_bit_count = bi->partial_bit_buffer = 0;
+    for (;;){
+       /* Find suitable storage space */
+       for (; size > (bits_left = put_bits_left(pb)); pb++) {
+          if (bits_left) {
+              size -= bits_left;
+              put_bits(pb, bits_left, vlc >> size);
+              vlc = vlc & ((1 << size) - 1);
+          }
+          if (pb + 1 >= pb_end) {
+              bi->partial_bit_count  = size;
+              bi->partial_bit_buffer = vlc;
+              return pb;
+          }
+       }
+
+       /* Store VLC */
+       put_bits(pb, size, vlc);
+
+       if (bi->cur_ac >= 64)
+           break;
+
+       /* Construct the next VLC */
+       prev       = bi->cur_ac;
+       bi->cur_ac = bi->next[prev];
+       if (bi->cur_ac < 64){
+           size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
+       } else {
+           size = 4; vlc = 6; /* End Of Block stamp */
+       }
+    }
+    return pb;
+}
+
+static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
+    if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
+        int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
+        if (ps > 0) {
+            int is = s->ildct_cmp(NULL, data           , NULL, linesize<<1, 4) +
+                     s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
+            return ps > is;
+        }
+    }
+
+    return 0;
+}
+
+static const int dv_weight_bits = 18;
+static const int dv_weight_88[64] = {
+ 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536,
+ 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935,
+ 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916,
+ 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433,
+ 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704,
+ 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568,
+ 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627,
+ 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258,
+};
+static const int dv_weight_248[64] = {
+ 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754,
+ 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536,
+ 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568,
+ 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965,
+ 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627,
+ 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965,
+ 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364,
+ 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651,
+};
+
+static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
+{
+    const int *weight;
+    const uint8_t* zigzag_scan;
+    LOCAL_ALIGNED_16(int16_t, blk, [64]);
+    int i, area;
+    /* We offer two different methods for class number assignment: the
+       method suggested in SMPTE 314M Table 22, and an improved
+       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
+       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
+       (for blocks whose largest AC component exceeds 255). */
+
+#if 0 /* SMPTE spec method */
+    static const int classes[] = {12, 24, 36, 0xffff};
+#else /* improved Libav method */
+    static const int classes[] = {-1, -1, 255, 0xffff};
+#endif
+    int max  = classes[0];
+    int prev = 0;
+
+    assert((((int)blk) & 15) == 0);
+
+    bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
+    bi->partial_bit_count = 0;
+    bi->partial_bit_buffer = 0;
+    bi->cur_ac = 0;
+    if (data) {
+        bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
+        s->get_pixels(blk, data, linesize);
+        s->fdct[bi->dct_mode](blk);
+    } else {
+        /* We rely on the fact that encoding all zeros leads to an immediate EOB,
+           which is precisely what the spec calls for in the "dummy" blocks. */
+        memset(blk, 0, 64*sizeof(*blk));
+        bi->dct_mode = 0;
+    }
+    bi->mb[0] = blk[0];
+
+    zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
+    weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
+
+    for (area = 0; area < 4; area++) {
+       bi->prev[area]     = prev;
+       bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
+       for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
+          int level = blk[zigzag_scan[i]];
+
+          if (level + 15 > 30U) {
+              bi->sign[i] = (level >> 31) & 1;
+              /* weight it and and shift down into range, adding for rounding */
+              /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT
+                 AND the 2x doubling of the weights */
+              level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
+              bi->mb[i] = level;
+              if (level > max)
+                  max = level;
+              bi->bit_size[area] += dv_rl2vlc_size(i - prev  - 1, level);
+              bi->next[prev]= i;
+              prev = i;
+          }
+       }
+    }
+    bi->next[prev]= i;
+    for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
+
+    bi->cno += bias;
+
+    if (bi->cno >= 3) {
+        bi->cno = 3;
+        prev    = 0;
+        i       = bi->next[prev];
+        for (area = 0; area < 4; area++) {
+            bi->prev[area]     = prev;
+            bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
+            for (; i < mb_area_start[area+1]; i = bi->next[i]) {
+                bi->mb[i] >>= 1;
+
+                if (bi->mb[i]) {
+                    bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
+                    bi->next[prev]= i;
+                    prev = i;
+                }
+            }
+        }
+        bi->next[prev]= i;
+    }
+
+    return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
+}
+
+static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
+{
+    int size[5];
+    int i, j, k, a, prev, a2;
+    EncBlockInfo* b;
+
+    size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
+    do {
+       b = blks;
+       for (i = 0; i < 5; i++) {
+          if (!qnos[i])
+              continue;
+
+          qnos[i]--;
+          size[i] = 0;
+          for (j = 0; j < 6; j++, b++) {
+             for (a = 0; a < 4; a++) {
+                if (b->area_q[a] != ff_dv_quant_shifts[qnos[i] + ff_dv_quant_offset[b->cno]][a]) {
+                    b->bit_size[a] = 1; // 4 areas 4 bits for EOB :)
+                    b->area_q[a]++;
+                    prev = b->prev[a];
+                    assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
+                    for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
+                       b->mb[k] >>= 1;
+                       if (b->mb[k]) {
+                           b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
+                           prev = k;
+                       } else {
+                           if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
+                                for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
+                                    b->prev[a2] = prev;
+                                assert(a2 < 4);
+                                assert(b->mb[b->next[k]]);
+                                b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
+                                                  -dv_rl2vlc_size(b->next[k] -    k - 1, b->mb[b->next[k]]);
+                                assert(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
+                                b->prev[a2] = prev;
+                           }
+                           b->next[prev] = b->next[k];
+                       }
+                    }
+                    b->prev[a+1]= prev;
+                }
+                size[i] += b->bit_size[a];
+             }
+          }
+          if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
+                return;
+       }
+    } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
+
+
+    for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
+        b = blks;
+        size[0] = 5 * 6 * 4; //EOB
+        for (j = 0; j < 6 *5; j++, b++) {
+            prev = b->prev[0];
+            for (k = b->next[prev]; k < 64; k = b->next[k]) {
+                if (b->mb[k] < a && b->mb[k] > -a){
+                    b->next[prev] = b->next[k];
+                }else{
+                    size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
+                    prev = k;
+                }
+            }
+        }
+    }
+}
+
+static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
+{
+    DVVideoContext *s = avctx->priv_data;
+    DVwork_chunk *work_chunk = arg;
+    int mb_index, i, j;
+    int mb_x, mb_y, c_offset, linesize, y_stride;
+    uint8_t*  y_ptr;
+    uint8_t*  dif;
+    LOCAL_ALIGNED_8(uint8_t, scratch, [128]);
+    EncBlockInfo  enc_blks[5*DV_MAX_BPM];
+    PutBitContext pbs[5*DV_MAX_BPM];
+    PutBitContext* pb;
+    EncBlockInfo* enc_blk;
+    int       vs_bit_size = 0;
+    int       qnos[5] = {15, 15, 15, 15, 15}; /* No quantization */
+    int*      qnosp = &qnos[0];
+
+    dif = &s->buf[work_chunk->buf_offset*80];
+    enc_blk = &enc_blks[0];
+    for (mb_index = 0; mb_index < 5; mb_index++) {
+        dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
+
+        /* initializing luminance blocks */
+        if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) ||
+            (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
+            (s->sys->height >= 720 && mb_y != 134)) {
+            y_stride = s->frame->linesize[0] << 3;
+        } else {
+            y_stride = 16;
+        }
+        y_ptr    = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << 3);
+        linesize = s->frame->linesize[0];
+
+        if (s->sys->video_stype == 4) { /* SD 422 */
+            vs_bit_size +=
+            dv_init_enc_block(enc_blk+0, y_ptr               , linesize, s, 0) +
+            dv_init_enc_block(enc_blk+1, NULL                , linesize, s, 0) +
+            dv_init_enc_block(enc_blk+2, y_ptr + 8           , linesize, s, 0) +
+            dv_init_enc_block(enc_blk+3, NULL                , linesize, s, 0);
+        } else {
+            vs_bit_size +=
+            dv_init_enc_block(enc_blk+0, y_ptr               , linesize, s, 0) +
+            dv_init_enc_block(enc_blk+1, y_ptr + 8           , linesize, s, 0) +
+            dv_init_enc_block(enc_blk+2, y_ptr     + y_stride, linesize, s, 0) +
+            dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
+        }
+        enc_blk += 4;
+
+        /* initializing chrominance blocks */
+        c_offset = (((mb_y >>  (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] +
+                     (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << 3);
+        for (j = 2; j; j--) {
+            uint8_t *c_ptr = s->frame->data[j] + c_offset;
+            linesize = s->frame->linesize[j];
+            y_stride = (mb_y == 134) ? 8 : (s->frame->linesize[j] << 3);
+            if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
+                uint8_t* d;
+                uint8_t* b = scratch;
+                for (i = 0; i < 8; i++) {
+                    d = c_ptr + (linesize << 3);
+                    b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
+                    b[4] =     d[0]; b[5] =     d[1]; b[6] =     d[2]; b[7] =     d[3];
+                    c_ptr += linesize;
+                    b += 16;
+                }
+                c_ptr = scratch;
+                linesize = 16;
+            }
+
+            vs_bit_size += dv_init_enc_block(    enc_blk++, c_ptr           , linesize, s, 1);
+            if (s->sys->bpm == 8) {
+                vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
+            }
+        }
+    }
+
+    if (vs_total_ac_bits < vs_bit_size)
+        dv_guess_qnos(&enc_blks[0], qnosp);
+
+    /* DIF encoding process */
+    for (j=0; j<5*s->sys->bpm;) {
+        int start_mb = j;
+
+        dif[3] = *qnosp++;
+        dif += 4;
+
+        /* First pass over individual cells only */
+        for (i=0; i<s->sys->bpm; i++, j++) {
+            int sz = s->sys->block_sizes[i]>>3;
+
+            init_put_bits(&pbs[j], dif, sz);
+            put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
+            put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
+            put_bits(&pbs[j], 2, enc_blks[j].cno);
+
+            dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
+            dif += sz;
+        }
+
+        /* Second pass over each MB space */
+        pb = &pbs[start_mb];
+        for (i=0; i<s->sys->bpm; i++) {
+            if (enc_blks[start_mb+i].partial_bit_count)
+                pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
+        }
+    }
+
+    /* Third and final pass over the whole video segment space */
+    pb = &pbs[0];
+    for (j=0; j<5*s->sys->bpm; j++) {
+       if (enc_blks[j].partial_bit_count)
+           pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
+       if (enc_blks[j].partial_bit_count)
+            av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
+    }
+
+    for (j=0; j<5*s->sys->bpm; j++) {
+       int pos;
+       int size = pbs[j].size_in_bits >> 3;
+       flush_put_bits(&pbs[j]);
+       pos = put_bits_count(&pbs[j]) >> 3;
+       if (pos > size) {
+           av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
+           return -1;
+       }
+       memset(pbs[j].buf + pos, 0xff, size - pos);
+    }
+
+    return 0;
+}
+
+static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
+                                uint8_t* buf)
+{
+    /*
+     * Here's what SMPTE314M says about these two:
+     *    (page 6) APTn, AP1n, AP2n, AP3n: These data shall be identical
+     *             as track application IDs (APTn = 001, AP1n =
+     *             001, AP2n = 001, AP3n = 001), if the source signal
+     *             comes from a digital VCR. If the signal source is
+     *             unknown, all bits for these data shall be set to 1.
+     *    (page 12) STYPE: STYPE defines a signal type of video signal
+     *                     00000b = 4:1:1 compression
+     *                     00100b = 4:2:2 compression
+     *                     XXXXXX = Reserved
+     * Now, I've got two problems with these statements:
+     *   1. it looks like APT == 111b should be a safe bet, but it isn't.
+     *      It seems that for PAL as defined in IEC 61834 we have to set
+     *      APT to 000 and for SMPTE314M to 001.
+     *   2. It is not at all clear what STYPE is used for 4:2:0 PAL
+     *      compression scheme (if any).
+     */
+    int apt   = (c->sys->pix_fmt == AV_PIX_FMT_YUV420P ? 0 : 1);
+
+    uint8_t aspect = 0;
+    if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */
+        aspect = 0x02;
+
+    buf[0] = (uint8_t)pack_id;
+    switch (pack_id) {
+    case dv_header525: /* I can't imagine why these two weren't defined as real */
+    case dv_header625: /* packs in SMPTE314M -- they definitely look like ones */
+          buf[1] = 0xf8 |        /* reserved -- always 1 */
+                   (apt & 0x07); /* APT: Track application ID */
+          buf[2] = (0    << 7) | /* TF1: audio data is 0 - valid; 1 - invalid */
+                   (0x0f << 3) | /* reserved -- always 1 */
+                   (apt & 0x07); /* AP1: Audio application ID */
+          buf[3] = (0    << 7) | /* TF2: video data is 0 - valid; 1 - invalid */
+                   (0x0f << 3) | /* reserved -- always 1 */
+                   (apt & 0x07); /* AP2: Video application ID */
+          buf[4] = (0    << 7) | /* TF3: subcode(SSYB) is 0 - valid; 1 - invalid */
+                   (0x0f << 3) | /* reserved -- always 1 */
+                   (apt & 0x07); /* AP3: Subcode application ID */
+          break;
+    case dv_video_source:
+          buf[1] = 0xff;      /* reserved -- always 1 */
+          buf[2] = (1 << 7) | /* B/W: 0 - b/w, 1 - color */
+                   (1 << 6) | /* following CLF is valid - 0, invalid - 1 */
+                   (3 << 4) | /* CLF: color frames ID (see ITU-R BT.470-4) */
+                   0xf;       /* reserved -- always 1 */
+          buf[3] = (3 << 6) | /* reserved -- always 1 */
+                   (c->sys->dsf << 5) | /*  system: 60fields/50fields */
+                   c->sys->video_stype; /* signal type video compression */
+          buf[4] = 0xff;      /* VISC: 0xff -- no information */
+          break;
+    case dv_video_control:
+          buf[1] = (0 << 6) | /* Copy generation management (CGMS) 0 -- free */
+                   0x3f;      /* reserved -- always 1 */
+          buf[2] = 0xc8 |     /* reserved -- always b11001xxx */
+                   aspect;
+          buf[3] = (1 << 7) | /* frame/field flag 1 -- frame, 0 -- field */
+                   (1 << 6) | /* first/second field flag 0 -- field 2, 1 -- field 1 */
+                   (1 << 5) | /* frame change flag 0 -- same picture as before, 1 -- different */
+                   (1 << 4) | /* 1 - interlaced, 0 - noninterlaced */
+                   0xc;       /* reserved -- always b1100 */
+          buf[4] = 0xff;      /* reserved -- always 1 */
+          break;
+    default:
+          buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
+    }
+    return 5;
+}
+
+static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
+                                  uint8_t seq_num, uint8_t dif_num,
+                                  uint8_t* buf)
+{
+    buf[0] = (uint8_t)t;       /* Section type */
+    buf[1] = (seq_num  << 4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */
+             (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */
+             7;                /* reserved -- always 1 */
+    buf[2] = dif_num;          /* DIF block number Video: 0-134, Audio: 0-8 */
+    return 3;
+}
+
+
+static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf)
+{
+    if (syb_num == 0 || syb_num == 6) {
+        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+                 (0  << 4) | /* AP3 (Subcode application ID) */
+                 0x0f;       /* reserved -- always 1 */
+    }
+    else if (syb_num == 11) {
+        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+                 0x7f;       /* reserved -- always 1 */
+    }
+    else {
+        buf[0] = (fr << 7) | /* FR ID 1 - first half of each channel; 0 - second */
+                 (0  << 4) | /* APT (Track application ID) */
+                 0x0f;       /* reserved -- always 1 */
+    }
+    buf[1] = 0xf0 |            /* reserved -- always 1 */
+             (syb_num & 0x0f); /* SSYB number 0 - 11   */
+    buf[2] = 0xff;             /* reserved -- always 1 */
+    return 3;
+}
+
+static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
+{
+    int chan, i, j, k;
+
+    for (chan = 0; chan < c->sys->n_difchan; chan++) {
+        for (i = 0; i < c->sys->difseg_size; i++) {
+            memset(buf, 0xff, 80 * 6); /* first 6 DIF blocks are for control data */
+
+            /* DV header: 1DIF */
+            buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
+            buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
+            buf += 72; /* unused bytes */
+
+            /* DV subcode: 2DIFs */
+            for (j = 0; j < 2; j++) {
+                buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
+                for (k = 0; k < 6; k++)
+                     buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
+                buf += 29; /* unused bytes */
+            }
+
+            /* DV VAUX: 3DIFS */
+            for (j = 0; j < 3; j++) {
+                buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
+                buf += dv_write_pack(dv_video_source,  c, buf);
+                buf += dv_write_pack(dv_video_control, c, buf);
+                buf += 7*5;
+                buf += dv_write_pack(dv_video_source,  c, buf);
+                buf += dv_write_pack(dv_video_control, c, buf);
+                buf += 4*5 + 2; /* unused bytes */
+            }
+
+            /* DV Audio/Video: 135 Video DIFs + 9 Audio DIFs */
+            for (j = 0; j < 135; j++) {
+                if (j%15 == 0) {
+                    memset(buf, 0xff, 80);
+                    buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
+                    buf += 77; /* audio control & shuffled PCM audio */
+                }
+                buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
+                buf += 77; /* 1 video macroblock: 1 bytes control
+                              4 * 14 bytes Y 8x8 data
+                              10 bytes Cr 8x8 data
+                              10 bytes Cb 8x8 data */
+            }
+        }
+    }
+}
+
+
+static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
+                                const AVFrame *frame, int *got_packet)
+{
+    DVVideoContext *s = c->priv_data;
+    int ret;
+
+    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");
+        return ret;
+    }
+
+    c->pix_fmt                = s->sys->pix_fmt;
+    s->frame                  = frame;
+    c->coded_frame->key_frame = 1;
+    c->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+
+    s->buf = pkt->data;
+    c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
+               dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
+
+    emms_c();
+
+    dv_format_frame(s, pkt->data);
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+
+    return 0;
+}
+
+static int dvvideo_encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
+AVCodec ff_dvvideo_encoder = {
+    .name           = "dvvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_DVVIDEO,
+    .priv_data_size = sizeof(DVVideoContext),
+    .init           = dvvideo_init_encoder,
+    .encode2        = dvvideo_encode_frame,
+    .close          = dvvideo_encode_close,
+    .capabilities   = CODEC_CAP_SLICE_THREADS,
+    .pix_fmts       = (const enum AVPixelFormat[]) {
+        AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
+    },
+};
diff --git a/libavcodec/dwt.c b/libavcodec/dwt.c
deleted file mode 100644
index 93cf2c6..0000000
--- a/libavcodec/dwt.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * Copyright (C) 2004-2010 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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/attributes.h"
-#include "libavutil/common.h"
-#include "dsputil.h"
-#include "dwt.h"
-
-int ff_slice_buffer_init(slice_buffer *buf, int line_count,
-                         int max_allocated_lines, int line_width,
-                         IDWTELEM *base_buffer)
-{
-    int i;
-
-    buf->base_buffer = base_buffer;
-    buf->line_count  = line_count;
-    buf->line_width  = line_width;
-    buf->data_count  = max_allocated_lines;
-    buf->line        = av_mallocz(sizeof(IDWTELEM *) * line_count);
-    if (!buf->line)
-        return AVERROR(ENOMEM);
-    buf->data_stack  = av_malloc(sizeof(IDWTELEM *) * max_allocated_lines);
-    if (!buf->data_stack) {
-        av_free(buf->line);
-        return AVERROR(ENOMEM);
-    }
-
-    for (i = 0; i < max_allocated_lines; i++) {
-        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);
-            return AVERROR(ENOMEM);
-        }
-    }
-
-    buf->data_stack_top = max_allocated_lines - 1;
-    return 0;
-}
-
-IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int line)
-{
-    IDWTELEM *buffer;
-
-    assert(buf->data_stack_top >= 0);
-//  assert(!buf->line[line]);
-    if (buf->line[line])
-        return buf->line[line];
-
-    buffer = buf->data_stack[buf->data_stack_top];
-    buf->data_stack_top--;
-    buf->line[line] = buffer;
-
-    return buffer;
-}
-
-void ff_slice_buffer_release(slice_buffer *buf, int line)
-{
-    IDWTELEM *buffer;
-
-    assert(line >= 0 && line < buf->line_count);
-    assert(buf->line[line]);
-
-    buffer = buf->line[line];
-    buf->data_stack_top++;
-    buf->data_stack[buf->data_stack_top] = buffer;
-    buf->line[line]                      = NULL;
-}
-
-void ff_slice_buffer_flush(slice_buffer *buf)
-{
-    int i;
-    for (i = 0; i < buf->line_count; i++)
-        if (buf->line[i])
-            ff_slice_buffer_release(buf, i);
-}
-
-void ff_slice_buffer_destroy(slice_buffer *buf)
-{
-    int i;
-    ff_slice_buffer_flush(buf);
-
-    for (i = buf->data_count - 1; i >= 0; i--)
-        av_freep(&buf->data_stack[i]);
-    av_freep(&buf->data_stack);
-    av_freep(&buf->line);
-}
-
-static inline int mirror(int v, int m)
-{
-    while ((unsigned)v > (unsigned)m) {
-        v = -v;
-        if (v < 0)
-            v += 2 * m;
-    }
-    return v;
-}
-
-static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
-                                  int dst_step, int src_step, int ref_step,
-                                  int width, int mul, int add, int shift,
-                                  int highpass, int inverse)
-{
-    const int mirror_left  = !highpass;
-    const int mirror_right = (width & 1) ^ highpass;
-    const int w            = (width >> 1) - 1 + (highpass & width);
-    int i;
-
-#define LIFT(src, ref, inv) ((src) + ((inv) ? -(ref) : +(ref)))
-    if (mirror_left) {
-        dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
-        dst   += dst_step;
-        src   += src_step;
-    }
-
-    for (i = 0; i < w; i++)
-        dst[i * dst_step] = LIFT(src[i * src_step],
-                                 ((mul * (ref[i * ref_step] +
-                                          ref[(i + 1) * ref_step]) +
-                                   add) >> shift),
-                                 inverse);
-
-    if (mirror_right)
-        dst[w * dst_step] = LIFT(src[w * src_step],
-                                 ((mul * 2 * ref[w * ref_step] + add) >> shift),
-                                 inverse);
-}
-
-static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
-                                   int dst_step, int src_step, int ref_step,
-                                   int width, int mul, int add, int shift,
-                                   int highpass, int inverse)
-{
-    const int mirror_left  = !highpass;
-    const int mirror_right = (width & 1) ^ highpass;
-    const int w            = (width >> 1) - 1 + (highpass & width);
-    int i;
-
-    assert(shift == 4);
-#define LIFTS(src, ref, inv)                                            \
-    ((inv) ? (src) + (((ref) + 4 * (src)) >> shift)                     \
-           : -((-16 * (src) + (ref) + add /                             \
-                4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
-    if (mirror_left) {
-        dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
-        dst   += dst_step;
-        src   += src_step;
-    }
-
-    for (i = 0; i < w; i++)
-        dst[i * dst_step] = LIFTS(src[i * src_step],
-                                  mul * (ref[i * ref_step] +
-                                         ref[(i + 1) * ref_step]) + add,
-                                  inverse);
-
-    if (mirror_right)
-        dst[w * dst_step] = LIFTS(src[w * src_step],
-                                  mul * 2 * ref[w * ref_step] + add,
-                                  inverse);
-}
-
-static void horizontal_decompose53i(DWTELEM *b, DWTELEM *temp, int width)
-{
-    const int width2 = width >> 1;
-    int x;
-    const int w2 = (width + 1) >> 1;
-
-    for (x = 0; x < width2; x++) {
-        temp[x]      = b[2 * x];
-        temp[x + w2] = b[2 * x + 1];
-    }
-    if (width & 1)
-        temp[x] = b[2 * x];
-    lift(b + w2, temp + w2, temp,   1, 1, 1, width, -1, 0, 1, 1, 0);
-    lift(b,      temp,      b + w2, 1, 1, 1, width,  1, 2, 2, 0, 0);
-}
-
-static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
-                                    int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] -= (b0[i] + b2[i]) >> 1;
-}
-
-static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
-                                    int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] += (b0[i] + b2[i] + 2) >> 2;
-}
-
-static void spatial_decompose53i(DWTELEM *buffer, DWTELEM *temp,
-                                 int width, int height, int stride)
-{
-    int y;
-    DWTELEM *b0 = buffer + mirror(-2 - 1, height - 1) * stride;
-    DWTELEM *b1 = buffer + mirror(-2,     height - 1) * stride;
-
-    for (y = -2; y < height; y += 2) {
-        DWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
-        DWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
-
-        if (y + 1 < (unsigned)height)
-            horizontal_decompose53i(b2, temp, width);
-        if (y + 2 < (unsigned)height)
-            horizontal_decompose53i(b3, temp, width);
-
-        if (y + 1 < (unsigned)height)
-            vertical_decompose53iH0(b1, b2, b3, width);
-        if (y + 0 < (unsigned)height)
-            vertical_decompose53iL0(b0, b1, b2, width);
-
-        b0 = b2;
-        b1 = b3;
-    }
-}
-
-static void horizontal_decompose97i(DWTELEM *b, DWTELEM *temp, int width)
-{
-    const int w2 = (width + 1) >> 1;
-
-    lift(temp + w2, b + 1, b,         1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1);
-    liftS(temp,     b,     temp + w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0);
-    lift(b + w2, temp + w2, temp,     1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
-    lift(b,      temp,      b + w2,   1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
-}
-
-static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
-                                    int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] -= (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
-}
-
-static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
-                                    int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] += (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
-}
-
-static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
-                                    int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] = (16 * 4 * b1[i] - 4 * (b0[i] + b2[i]) + W_BO * 5 + (5 << 27)) /
-                (5 * 16) - (1 << 23);
-}
-
-static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
-                                    int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] += (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
-}
-
-static void spatial_decompose97i(DWTELEM *buffer, DWTELEM *temp,
-                                 int width, int height, int stride)
-{
-    int y;
-    DWTELEM *b0 = buffer + mirror(-4 - 1, height - 1) * stride;
-    DWTELEM *b1 = buffer + mirror(-4,     height - 1) * stride;
-    DWTELEM *b2 = buffer + mirror(-4 + 1, height - 1) * stride;
-    DWTELEM *b3 = buffer + mirror(-4 + 2, height - 1) * stride;
-
-    for (y = -4; y < height; y += 2) {
-        DWTELEM *b4 = buffer + mirror(y + 3, height - 1) * stride;
-        DWTELEM *b5 = buffer + mirror(y + 4, height - 1) * stride;
-
-        if (y + 3 < (unsigned)height)
-            horizontal_decompose97i(b4, temp, width);
-        if (y + 4 < (unsigned)height)
-            horizontal_decompose97i(b5, temp, width);
-
-        if (y + 3 < (unsigned)height)
-            vertical_decompose97iH0(b3, b4, b5, width);
-        if (y + 2 < (unsigned)height)
-            vertical_decompose97iL0(b2, b3, b4, width);
-        if (y + 1 < (unsigned)height)
-            vertical_decompose97iH1(b1, b2, b3, width);
-        if (y + 0 < (unsigned)height)
-            vertical_decompose97iL1(b0, b1, b2, width);
-
-        b0 = b2;
-        b1 = b3;
-        b2 = b4;
-        b3 = b5;
-    }
-}
-
-void ff_spatial_dwt(DWTELEM *buffer, DWTELEM *temp, int width, int height,
-                    int stride, int type, int decomposition_count)
-{
-    int level;
-
-    for (level = 0; level < decomposition_count; level++) {
-        switch (type) {
-        case DWT_97:
-            spatial_decompose97i(buffer, temp,
-                                 width >> level, height >> level,
-                                 stride << level);
-            break;
-        case DWT_53:
-            spatial_decompose53i(buffer, temp,
-                                 width >> level, height >> level,
-                                 stride << level);
-            break;
-        }
-    }
-}
-
-static void horizontal_compose53i(IDWTELEM *b, IDWTELEM *temp, int width)
-{
-    const int width2 = width >> 1;
-    const int w2     = (width + 1) >> 1;
-    int x;
-
-    for (x = 0; x < width2; x++) {
-        temp[2 * x]     = b[x];
-        temp[2 * x + 1] = b[x + w2];
-    }
-    if (width & 1)
-        temp[2 * x] = b[x];
-
-    b[0] = temp[0] - ((temp[1] + 1) >> 1);
-    for (x = 2; x < width - 1; x += 2) {
-        b[x]     = temp[x]     - ((temp[x - 1] + temp[x + 1] + 2) >> 2);
-        b[x - 1] = temp[x - 1] + ((b[x - 2]    + b[x]        + 1) >> 1);
-    }
-    if (width & 1) {
-        b[x]     = temp[x]     - ((temp[x - 1]     + 1) >> 1);
-        b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
-    } else
-        b[x - 1] = temp[x - 1] + b[x - 2];
-}
-
-static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                  int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] += (b0[i] + b2[i]) >> 1;
-}
-
-static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                  int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] -= (b0[i] + b2[i] + 2) >> 2;
-}
-
-static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer *sb,
-                                             int height, int stride_line)
-{
-    cs->b0 = slice_buffer_get_line(sb,
-                                   mirror(-1 - 1, height - 1) * stride_line);
-    cs->b1 = slice_buffer_get_line(sb, mirror(-1, height - 1) * stride_line);
-    cs->y  = -1;
-}
-
-static void spatial_compose53i_init(DWTCompose *cs, IDWTELEM *buffer,
-                                    int height, int stride)
-{
-    cs->b0 = buffer + mirror(-1 - 1, height - 1) * stride;
-    cs->b1 = buffer + mirror(-1,     height - 1) * stride;
-    cs->y  = -1;
-}
-
-static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer *sb,
-                                           IDWTELEM *temp,
-                                           int width, int height,
-                                           int stride_line)
-{
-    int y = cs->y;
-
-    IDWTELEM *b0 = cs->b0;
-    IDWTELEM *b1 = cs->b1;
-    IDWTELEM *b2 = slice_buffer_get_line(sb,
-                                         mirror(y + 1, height - 1) *
-                                         stride_line);
-    IDWTELEM *b3 = slice_buffer_get_line(sb,
-                                         mirror(y + 2, height - 1) *
-                                         stride_line);
-
-    if (y + 1 < (unsigned)height && y < (unsigned)height) {
-        int x;
-
-        for (x = 0; x < width; x++) {
-            b2[x] -= (b1[x] + b3[x] + 2) >> 2;
-            b1[x] += (b0[x] + b2[x])     >> 1;
-        }
-    } else {
-        if (y + 1 < (unsigned)height)
-            vertical_compose53iL0(b1, b2, b3, width);
-        if (y + 0 < (unsigned)height)
-            vertical_compose53iH0(b0, b1, b2, width);
-    }
-
-    if (y - 1 < (unsigned)height)
-        horizontal_compose53i(b0, temp, width);
-    if (y + 0 < (unsigned)height)
-        horizontal_compose53i(b1, temp, width);
-
-    cs->b0  = b2;
-    cs->b1  = b3;
-    cs->y  += 2;
-}
-
-static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer,
-                                  IDWTELEM *temp, int width, int height,
-                                  int stride)
-{
-    int y        = cs->y;
-    IDWTELEM *b0 = cs->b0;
-    IDWTELEM *b1 = cs->b1;
-    IDWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
-    IDWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
-
-    if (y + 1 < (unsigned)height)
-        vertical_compose53iL0(b1, b2, b3, width);
-    if (y + 0 < (unsigned)height)
-        vertical_compose53iH0(b0, b1, b2, width);
-
-    if (y - 1 < (unsigned)height)
-        horizontal_compose53i(b0, temp, width);
-    if (y + 0 < (unsigned)height)
-        horizontal_compose53i(b1, temp, width);
-
-    cs->b0  = b2;
-    cs->b1  = b3;
-    cs->y  += 2;
-}
-
-void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width)
-{
-    const int w2 = (width + 1) >> 1;
-    int x;
-
-    temp[0] = b[0] - ((3 * b[w2] + 2) >> 2);
-    for (x = 1; x < (width >> 1); x++) {
-        temp[2 * x]     = b[x] - ((3 * (b[x + w2 - 1] + b[x + w2]) + 4) >> 3);
-        temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
-    }
-    if (width & 1) {
-        temp[2 * x]     = b[x] - ((3 * b[x + w2 - 1] + 2) >> 2);
-        temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
-    } else
-        temp[2 * x - 1] = b[x + w2 - 1] - 2 * temp[2 * x - 2];
-
-    b[0] = temp[0] + ((2 * temp[0] + temp[1] + 4) >> 3);
-    for (x = 2; x < width - 1; x += 2) {
-        b[x]     = temp[x] + ((4 * temp[x] + temp[x - 1] + temp[x + 1] + 8) >> 4);
-        b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
-    }
-    if (width & 1) {
-        b[x]     = temp[x] + ((2 * temp[x] + temp[x - 1] + 4) >> 3);
-        b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
-    } else
-        b[x - 1] = temp[x - 1] + 3 * b[x - 2];
-}
-
-static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                  int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
-}
-
-static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                  int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] -= (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
-}
-
-static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                  int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] += (W_BM * (b0[i] + b2[i]) + 4 * b1[i] + W_BO) >> W_BS;
-}
-
-static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                  int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++)
-        b1[i] -= (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
-}
-
-void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                 IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
-                                 int width)
-{
-    int i;
-
-    for (i = 0; i < width; i++) {
-        b4[i] -= (W_DM * (b3[i] + b5[i]) + W_DO) >> W_DS;
-        b3[i] -= (W_CM * (b2[i] + b4[i]) + W_CO) >> W_CS;
-        b2[i] += (W_BM * (b1[i] + b3[i]) + 4 * b2[i] + W_BO) >> W_BS;
-        b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
-    }
-}
-
-static void spatial_compose97i_buffered_init(DWTCompose *cs, slice_buffer *sb,
-                                             int height, int stride_line)
-{
-    cs->b0 = slice_buffer_get_line(sb, mirror(-3 - 1, height - 1) * stride_line);
-    cs->b1 = slice_buffer_get_line(sb, mirror(-3,     height - 1) * stride_line);
-    cs->b2 = slice_buffer_get_line(sb, mirror(-3 + 1, height - 1) * stride_line);
-    cs->b3 = slice_buffer_get_line(sb, mirror(-3 + 2, height - 1) * stride_line);
-    cs->y  = -3;
-}
-
-static void spatial_compose97i_init(DWTCompose *cs, IDWTELEM *buffer, int height,
-                                    int stride)
-{
-    cs->b0 = buffer + mirror(-3 - 1, height - 1) * stride;
-    cs->b1 = buffer + mirror(-3,     height - 1) * stride;
-    cs->b2 = buffer + mirror(-3 + 1, height - 1) * stride;
-    cs->b3 = buffer + mirror(-3 + 2, height - 1) * stride;
-    cs->y  = -3;
-}
-
-static void spatial_compose97i_dy_buffered(DWTContext *dsp, DWTCompose *cs,
-                                           slice_buffer * sb, IDWTELEM *temp,
-                                           int width, int height,
-                                           int stride_line)
-{
-    int y = cs->y;
-
-    IDWTELEM *b0 = cs->b0;
-    IDWTELEM *b1 = cs->b1;
-    IDWTELEM *b2 = cs->b2;
-    IDWTELEM *b3 = cs->b3;
-    IDWTELEM *b4 = slice_buffer_get_line(sb,
-                                         mirror(y + 3, height - 1) *
-                                         stride_line);
-    IDWTELEM *b5 = slice_buffer_get_line(sb,
-                                         mirror(y + 4, height - 1) *
-                                         stride_line);
-
-    if (y > 0 && y + 4 < height) {
-        dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
-    } else {
-        if (y + 3 < (unsigned)height)
-            vertical_compose97iL1(b3, b4, b5, width);
-        if (y + 2 < (unsigned)height)
-            vertical_compose97iH1(b2, b3, b4, width);
-        if (y + 1 < (unsigned)height)
-            vertical_compose97iL0(b1, b2, b3, width);
-        if (y + 0 < (unsigned)height)
-            vertical_compose97iH0(b0, b1, b2, width);
-    }
-
-    if (y - 1 < (unsigned)height)
-        dsp->horizontal_compose97i(b0, temp, width);
-    if (y + 0 < (unsigned)height)
-        dsp->horizontal_compose97i(b1, temp, width);
-
-    cs->b0  = b2;
-    cs->b1  = b3;
-    cs->b2  = b4;
-    cs->b3  = b5;
-    cs->y  += 2;
-}
-
-static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer,
-                                  IDWTELEM *temp, int width, int height,
-                                  int stride)
-{
-    int y        = cs->y;
-    IDWTELEM *b0 = cs->b0;
-    IDWTELEM *b1 = cs->b1;
-    IDWTELEM *b2 = cs->b2;
-    IDWTELEM *b3 = cs->b3;
-    IDWTELEM *b4 = buffer + mirror(y + 3, height - 1) * stride;
-    IDWTELEM *b5 = buffer + mirror(y + 4, height - 1) * stride;
-
-    if (y + 3 < (unsigned)height)
-        vertical_compose97iL1(b3, b4, b5, width);
-    if (y + 2 < (unsigned)height)
-        vertical_compose97iH1(b2, b3, b4, width);
-    if (y + 1 < (unsigned)height)
-        vertical_compose97iL0(b1, b2, b3, width);
-    if (y + 0 < (unsigned)height)
-        vertical_compose97iH0(b0, b1, b2, width);
-
-    if (y - 1 < (unsigned)height)
-        ff_snow_horizontal_compose97i(b0, temp, width);
-    if (y + 0 < (unsigned)height)
-        ff_snow_horizontal_compose97i(b1, temp, width);
-
-    cs->b0  = b2;
-    cs->b1  = b3;
-    cs->b2  = b4;
-    cs->b3  = b5;
-    cs->y  += 2;
-}
-
-void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
-                                   int height, int stride_line, int type,
-                                   int decomposition_count)
-{
-    int level;
-    for (level = decomposition_count - 1; level >= 0; level--) {
-        switch (type) {
-        case DWT_97:
-            spatial_compose97i_buffered_init(cs + level, sb, height >> level,
-                                             stride_line << level);
-            break;
-        case DWT_53:
-            spatial_compose53i_buffered_init(cs + level, sb, height >> level,
-                                             stride_line << level);
-            break;
-        }
-    }
-}
-
-void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs,
-                                    slice_buffer *slice_buf, IDWTELEM *temp,
-                                    int width, int height, int stride_line,
-                                    int type, int decomposition_count, int y)
-{
-    const int support = type == 1 ? 3 : 5;
-    int level;
-    if (type == 2)
-        return;
-
-    for (level = decomposition_count - 1; level >= 0; level--)
-        while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
-            switch (type) {
-            case DWT_97:
-                spatial_compose97i_dy_buffered(dsp, cs + level, slice_buf, temp,
-                                               width >> level,
-                                               height >> level,
-                                               stride_line << level);
-                break;
-            case DWT_53:
-                spatial_compose53i_dy_buffered(cs + level, slice_buf, temp,
-                                               width >> level,
-                                               height >> level,
-                                               stride_line << level);
-                break;
-            }
-        }
-}
-
-static void ff_spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width,
-                                 int height, int stride, int type,
-                                 int decomposition_count)
-{
-    int level;
-    for (level = decomposition_count - 1; level >= 0; level--) {
-        switch (type) {
-        case DWT_97:
-            spatial_compose97i_init(cs + level, buffer, height >> level,
-                                    stride << level);
-            break;
-        case DWT_53:
-            spatial_compose53i_init(cs + level, buffer, height >> level,
-                                    stride << level);
-            break;
-        }
-    }
-}
-
-static void ff_spatial_idwt_slice(DWTCompose *cs, IDWTELEM *buffer,
-                                  IDWTELEM *temp, int width, int height,
-                                  int stride, int type,
-                                  int decomposition_count, int y)
-{
-    const int support = type == 1 ? 3 : 5;
-    int level;
-    if (type == 2)
-        return;
-
-    for (level = decomposition_count - 1; level >= 0; level--)
-        while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
-            switch (type) {
-            case DWT_97:
-                spatial_compose97i_dy(cs + level, buffer, temp, width >> level,
-                                      height >> level, stride << level);
-                break;
-            case DWT_53:
-                spatial_compose53i_dy(cs + level, buffer, temp, width >> level,
-                                      height >> level, stride << level);
-                break;
-            }
-        }
-}
-
-void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
-                     int stride, int type, int decomposition_count)
-{
-    DWTCompose cs[MAX_DECOMPOSITIONS];
-    int y;
-    ff_spatial_idwt_init(cs, buffer, width, height, stride, type,
-                         decomposition_count);
-    for (y = 0; y < height; y += 4)
-        ff_spatial_idwt_slice(cs, buffer, temp, width, height, stride, type,
-                              decomposition_count, y);
-}
-
-static inline int w_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size,
-                      int w, int h, int type)
-{
-    int s, i, j;
-    const int dec_count = w == 8 ? 3 : 4;
-    int tmp[32 * 32], tmp2[32];
-    int level, ori;
-    static const int scale[2][2][4][4] = {
-        {
-            { // 9/7 8x8 dec=3
-                { 268, 239, 239, 213 },
-                { 0,   224, 224, 152 },
-                { 0,   135, 135, 110 },
-            },
-            { // 9/7 16x16 or 32x32 dec=4
-                { 344, 310, 310, 280 },
-                { 0,   320, 320, 228 },
-                { 0,   175, 175, 136 },
-                { 0,   129, 129, 102 },
-            }
-        },
-        {
-            { // 5/3 8x8 dec=3
-                { 275, 245, 245, 218 },
-                { 0,   230, 230, 156 },
-                { 0,   138, 138, 113 },
-            },
-            { // 5/3 16x16 or 32x32 dec=4
-                { 352, 317, 317, 286 },
-                { 0,   328, 328, 233 },
-                { 0,   180, 180, 140 },
-                { 0,   132, 132, 105 },
-            }
-        }
-    };
-
-    for (i = 0; i < h; i++) {
-        for (j = 0; j < w; j += 4) {
-            tmp[32 * i + j + 0] = (pix1[j + 0] - pix2[j + 0]) << 4;
-            tmp[32 * i + j + 1] = (pix1[j + 1] - pix2[j + 1]) << 4;
-            tmp[32 * i + j + 2] = (pix1[j + 2] - pix2[j + 2]) << 4;
-            tmp[32 * i + j + 3] = (pix1[j + 3] - pix2[j + 3]) << 4;
-        }
-        pix1 += line_size;
-        pix2 += line_size;
-    }
-
-    ff_spatial_dwt(tmp, tmp2, w, h, 32, type, dec_count);
-
-    s = 0;
-    assert(w == h);
-    for (level = 0; level < dec_count; level++)
-        for (ori = level ? 1 : 0; ori < 4; ori++) {
-            int size   = w >> (dec_count - level);
-            int sx     = (ori & 1) ? size : 0;
-            int stride = 32 << (dec_count - level);
-            int sy     = (ori & 2) ? stride >> 1 : 0;
-
-            for (i = 0; i < size; i++)
-                for (j = 0; j < size; j++) {
-                    int v = tmp[sx + sy + i * stride + j] *
-                            scale[type][dec_count - 3][level][ori];
-                    s += FFABS(v);
-                }
-        }
-    assert(s >= 0);
-    return s >> 9;
-}
-
-static int w53_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    return w_c(v, pix1, pix2, line_size, 8, h, 1);
-}
-
-static int w97_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    return w_c(v, pix1, pix2, line_size, 8, h, 0);
-}
-
-static int w53_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    return w_c(v, pix1, pix2, line_size, 16, h, 1);
-}
-
-static int w97_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    return w_c(v, pix1, pix2, line_size, 16, h, 0);
-}
-
-int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    return w_c(v, pix1, pix2, line_size, 32, h, 1);
-}
-
-int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
-{
-    return w_c(v, pix1, pix2, line_size, 32, h, 0);
-}
-
-void ff_dsputil_init_dwt(DSPContext *c)
-{
-    c->w53[0] = w53_16_c;
-    c->w53[1] = w53_8_c;
-    c->w97[0] = w97_16_c;
-    c->w97[1] = w97_8_c;
-}
-
-void ff_dwt_init(DWTContext *c)
-{
-    c->vertical_compose97i   = ff_snow_vertical_compose97i;
-    c->horizontal_compose97i = ff_snow_horizontal_compose97i;
-    c->inner_add_yblock      = ff_snow_inner_add_yblock;
-
-    if (HAVE_MMX)
-        ff_dwt_init_x86(c);
-}
diff --git a/libavcodec/dwt.h b/libavcodec/dwt.h
deleted file mode 100644
index e06f3f9..0000000
--- a/libavcodec/dwt.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2004-2010 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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_DWT_H
-#define AVCODEC_DWT_H
-
-#include <stdint.h>
-
-typedef int DWTELEM;
-typedef short IDWTELEM;
-
-typedef struct DWTCompose {
-    IDWTELEM *b0;
-    IDWTELEM *b1;
-    IDWTELEM *b2;
-    IDWTELEM *b3;
-    int y;
-} DWTCompose;
-
-/** Used to minimize the amount of memory used in order to
- *  optimize cache performance. **/
-typedef struct slice_buffer_s {
-    IDWTELEM **line;   ///< For use by idwt and predict_slices.
-    IDWTELEM **data_stack;   ///< Used for internal purposes.
-    int data_stack_top;
-    int line_count;
-    int line_width;
-    int data_count;
-    IDWTELEM *base_buffer;  ///< Buffer that this structure is caching.
-} slice_buffer;
-
-typedef struct DWTContext {
-    void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
-                                int width);
-    void (*horizontal_compose97i)(IDWTELEM *b, IDWTELEM *temp, int width);
-    void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride,
-                             uint8_t **block, int b_w, int b_h, int src_x,
-                             int src_y, int src_stride, slice_buffer *sb,
-                             int add, uint8_t *dst8);
-} DWTContext;
-
-#define MAX_DECOMPOSITIONS 8
-
-#define DWT_97 0
-#define DWT_53 1
-
-#define liftS lift
-#define W_AM 3
-#define W_AO 0
-#define W_AS 1
-
-#undef liftS
-#define W_BM 1
-#define W_BO 8
-#define W_BS 4
-
-#define W_CM 1
-#define W_CO 0
-#define W_CS 0
-
-#define W_DM 3
-#define W_DO 4
-#define W_DS 3
-
-#define slice_buffer_get_line(slice_buf, line_num)                          \
-    ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num]              \
-                                 : ff_slice_buffer_load_line((slice_buf),   \
-                                                             (line_num)))
-
-int ff_slice_buffer_init(slice_buffer *buf, int line_count,
-                         int max_allocated_lines, int line_width,
-                         IDWTELEM *base_buffer);
-void ff_slice_buffer_release(slice_buffer *buf, int line);
-void ff_slice_buffer_flush(slice_buffer *buf);
-void ff_slice_buffer_destroy(slice_buffer *buf);
-IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int line);
-
-void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
-                                 IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
-                                 int width);
-void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width);
-void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride,
-                              uint8_t **block, int b_w, int b_h, int src_x,
-                              int src_y, int src_stride, slice_buffer *sb,
-                              int add, uint8_t *dst8);
-
-int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h);
-
-void ff_spatial_dwt(int *buffer, int *temp, int width, int height, int stride,
-                    int type, int decomposition_count);
-
-void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
-                                   int height, int stride_line, int type,
-                                   int decomposition_count);
-void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs,
-                                    slice_buffer *slice_buf, IDWTELEM *temp,
-                                    int width, int height, int stride_line,
-                                    int type, int decomposition_count, int y);
-void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
-                     int stride, int type, int decomposition_count);
-
-void ff_dwt_init(DWTContext *c);
-void ff_dwt_init_x86(DWTContext *c);
-
-#endif /* AVCODEC_DWT_H */
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index ddc8d98..fa0677d 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -38,7 +38,7 @@
  * Decoder context
  */
 typedef struct DxaDecContext {
-    AVFrame pic, prev;
+    AVFrame *prev;
 
     int dsize;
     uint8_t *decomp_buf;
@@ -48,12 +48,12 @@ typedef struct DxaDecContext {
 static const int shift1[6] = { 0, 8, 8, 8, 4, 4 };
 static const int shift2[6] = { 0, 0, 8, 4, 0, 4 };
 
-static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint8_t *src, uint8_t *ref)
+static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst,
+                     int stride, uint8_t *src, uint8_t *ref)
 {
     uint8_t *code, *data, *mv, *msk, *tmp, *tmp2;
     int i, j, k;
     int type, x, y, d, d2;
-    int stride = c->pic.linesize[0];
     uint32_t mask;
 
     code = src  + 12;
@@ -180,7 +180,7 @@ static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint
                 break;
             default:
                 av_log(avctx, AV_LOG_ERROR, "Unknown opcode %d\n", type);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
         dst += stride * 4;
@@ -191,12 +191,13 @@ static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     DxaDecContext * const c = avctx->priv_data;
     uint8_t *outptr, *srcptr, *tmpptr;
     unsigned long dsize;
-    int i, j, compr;
+    int i, j, compr, ret;
     int stride;
     int orig_buf_size = buf_size;
     int pc = 0;
@@ -216,17 +217,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         buf_size -= 768+4;
     }
 
-    if(ff_get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
-    c->pic.palette_has_changed = pc;
+    memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
+    frame->palette_has_changed = pc;
 
-    outptr = c->pic.data[0];
+    outptr = frame->data[0];
     srcptr = c->decomp_buf;
-    tmpptr = c->prev.data[0];
-    stride = c->pic.linesize[0];
+    tmpptr = c->prev->data[0];
+    stride = frame->linesize[0];
 
     if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L')
         compr = -1;
@@ -236,60 +237,62 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     dsize = c->dsize;
     if((compr != 4 && compr != -1) && uncompress(c->decomp_buf, &dsize, buf + 9, buf_size - 9) != Z_OK){
         av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n");
-        return -1;
+        return AVERROR_UNKNOWN;
     }
     switch(compr){
     case -1:
-        c->pic.key_frame = 0;
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
-        if(c->prev.data[0])
-            memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] * avctx->height);
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        if (c->prev->data[0])
+            memcpy(frame->data[0], c->prev->data[0], frame->linesize[0] * avctx->height);
         else{ // Should happen only when first frame is 'NULL'
-            memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height);
-            c->pic.key_frame = 1;
-            c->pic.pict_type = AV_PICTURE_TYPE_I;
+            memset(frame->data[0], 0, frame->linesize[0] * avctx->height);
+            frame->key_frame = 1;
+            frame->pict_type = AV_PICTURE_TYPE_I;
         }
         break;
     case 2:
-    case 3:
     case 4:
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        for (j = 0; j < avctx->height; j++) {
+                memcpy(outptr, srcptr, avctx->width);
+            outptr += stride;
+            srcptr += avctx->width;
+        }
+        break;
+    case 3:
     case 5:
-        c->pic.key_frame = !(compr & 1);
-        c->pic.pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
-
-        if (!tmpptr && !c->pic.key_frame) {
+        if (!tmpptr) {
             av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
             return AVERROR_INVALIDDATA;
         }
-
-        for(j = 0; j < avctx->height; j++){
-            if(compr & 1){
-                for(i = 0; i < avctx->width; i++)
-                    outptr[i] = srcptr[i] ^ tmpptr[i];
-                tmpptr += stride;
-            }else
-                memcpy(outptr, srcptr, avctx->width);
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        for (j = 0; j < avctx->height; j++) {
+            for (i = 0; i < avctx->width; i++)
+                outptr[i] = srcptr[i] ^ tmpptr[i];
+            tmpptr += stride;
             outptr += stride;
             srcptr += avctx->width;
         }
         break;
     case 12: // ScummVM coding
     case 13:
-        c->pic.key_frame = 0;
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
-        decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]);
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        decode_13(avctx, c, frame->data[0], frame->linesize[0], srcptr, c->prev->data[0]);
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    FFSWAP(AVFrame, c->pic, c->prev);
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_unref(c->prev);
+    if ((ret = av_frame_ref(c->prev, frame)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame*)data = c->prev;
 
     /* always report that the buffer was completely consumed */
     return orig_buf_size;
@@ -299,12 +302,16 @@ static av_cold int decode_init(AVCodecContext *avctx)
 {
     DxaDecContext * const c = avctx->priv_data;
 
+    c->prev = av_frame_alloc();
+    if (!c->prev)
+        return AVERROR(ENOMEM);
+
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     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");
-        return -1;
+        return AVERROR(ENOMEM);
     }
 
     return 0;
@@ -315,16 +322,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
     DxaDecContext * const c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
-    if(c->prev.data[0])
-        avctx->release_buffer(avctx, &c->prev);
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_free(&c->prev);
 
     return 0;
 }
 
 AVCodec ff_dxa_decoder = {
     .name           = "dxa",
+    .long_name      = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DXA,
     .priv_data_size = sizeof(DxaDecContext),
@@ -332,5 +337,4 @@ AVCodec ff_dxa_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"),
 };
diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c
index 30983f8..6018ebb 100644
--- a/libavcodec/dxtory.c
+++ b/libavcodec/dxtory.c
@@ -20,51 +20,31 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#define BITSTREAM_READER_LE
 #include "avcodec.h"
+#include "bytestream.h"
+#include "get_bits.h"
 #include "internal.h"
+#include "unary.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    avctx->pix_fmt     = AV_PIX_FMT_YUV420P;
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
-    return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                        AVPacket *avpkt)
+static int dxtory_decode_v1(AVCodecContext *avctx, AVFrame *pic,
+                            const uint8_t *src, int src_size)
 {
     int h, w;
-    AVFrame *pic = avctx->coded_frame;
-    const uint8_t *src = avpkt->data;
     uint8_t *Y1, *Y2, *U, *V;
     int ret;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    if (avpkt->size < avctx->width * avctx->height * 3 / 2 + 16) {
+    if (src_size < avctx->width * avctx->height * 3 / 2) {
         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
         return AVERROR_INVALIDDATA;
     }
 
-    pic->reference = 0;
-    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
-    pic->pict_type = AV_PICTURE_TYPE_I;
-    pic->key_frame = 1;
-
-    if (AV_RL32(src) != 0x01000002) {
-        av_log_ask_for_sample(avctx, "Unknown frame header %X\n", AV_RL32(src));
-        return AVERROR_PATCHWELCOME;
-    }
-    src += 16;
-
     Y1 = pic->data[0];
     Y2 = pic->data[0] + pic->linesize[0];
     U  = pic->data[1];
@@ -83,29 +63,164 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         V  += pic->linesize[2];
     }
 
-    *got_frame = 1;
-    *(AVFrame*)data = *pic;
+    return 0;
+}
 
-    return avpkt->size;
+const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
+
+static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
+{
+    uint8_t c, val;
+
+    c = get_unary(gb, 0, 8);
+    if (!c) {
+        val = get_bits(gb, 8);
+        memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
+    } else {
+        val = lru[c - 1];
+        memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
+    }
+    lru[0] = val;
+
+    return val;
+}
+
+static int dx2_decode_slice(GetBitContext *gb, int width, int height,
+                            uint8_t *Y, uint8_t *U, uint8_t *V,
+                            int ystride, int ustride, int vstride)
+{
+    int x, y, i;
+    uint8_t lru[3][8];
+
+    for (i = 0; i < 3; i++)
+        memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
+
+    for (y = 0; y < height; y+=2) {
+        for (x = 0; x < width; x += 2) {
+            Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
+            Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
+            Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
+            Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
+            U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
+            V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
+        }
+
+        Y += ystride << 1;
+        U += ustride;
+        V += vstride;
+    }
+
+    return 0;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
+static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,
+                            const uint8_t *src, int src_size)
 {
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
+    GetByteContext gb;
+    GetBitContext  gb2;
+    int nslices, slice, slice_height;
+    uint32_t off, slice_size;
+    uint8_t *Y, *U, *V;
+    int ret;
+
+    bytestream2_init(&gb, src, src_size);
+    nslices = bytestream2_get_le16(&gb);
+    off = FFALIGN(nslices * 4 + 2, 16);
+    if (src_size < off) {
+        av_log(avctx, AV_LOG_ERROR, "no slice data\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (!nslices || avctx->height % nslices) {
+        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
+                              avctx->width, avctx->height);
+        return AVERROR(ENOSYS);
+    }
+
+    slice_height = avctx->height / nslices;
+    if ((avctx->width & 1) || (slice_height & 1)) {
+        avpriv_request_sample(avctx, "slice dimensions %dx%d",
+                              avctx->width, slice_height);
+    }
+
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+        return ret;
+
+    Y = pic->data[0];
+    U = pic->data[1];
+    V = pic->data[2];
+
+    for (slice = 0; slice < nslices; slice++) {
+        slice_size = bytestream2_get_le32(&gb);
+        if (slice_size > src_size - off) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "invalid slice size %d (only %d bytes left)\n",
+                   slice_size, src_size - off);
+            return AVERROR_INVALIDDATA;
+        }
+        if (slice_size <= 16) {
+            av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (AV_RL32(src + off) != slice_size - 16) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Slice sizes mismatch: got %d instead of %d\n",
+                   AV_RL32(src + off), slice_size - 16);
+        }
+        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
+        dx2_decode_slice(&gb2, avctx->width, slice_height, Y, U, V,
+                         pic->linesize[0], pic->linesize[1], pic->linesize[2]);
+
+        Y += pic->linesize[0] *  slice_height;
+        U += pic->linesize[1] * (slice_height >> 1);
+        V += pic->linesize[2] * (slice_height >> 1);
+        off += slice_size;
+    }
 
     return 0;
 }
 
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
+{
+    AVFrame *pic = data;
+    const uint8_t *src = avpkt->data;
+    int ret;
+
+    if (avpkt->size < 16) {
+        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    switch (AV_RB32(src)) {
+    case 0x02000001:
+        ret = dxtory_decode_v1(avctx, pic, src + 16, avpkt->size - 16);
+        break;
+    case 0x02000009:
+        ret = dxtory_decode_v2(avctx, pic, src + 16, avpkt->size - 16);
+        break;
+    default:
+        avpriv_request_sample(avctx, "Frame header %X", AV_RB32(src));
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (ret)
+        return ret;
+
+    pic->pict_type = AV_PICTURE_TYPE_I;
+    pic->key_frame = 1;
+    *got_frame = 1;
+
+    return avpkt->size;
+}
+
 AVCodec ff_dxtory_decoder = {
     .name           = "dxtory",
     .long_name      = NULL_IF_CONFIG_SMALL("Dxtory"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DXTORY,
-    .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
index 71c8405..bc43cae 100644
--- a/libavcodec/dxva2.c
+++ b/libavcodec/dxva2.c
@@ -76,7 +76,7 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
     return result;
 }
 
-int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
+int ff_dxva2_common_end_frame(AVCodecContext *avctx, Picture *pic,
                               const void *pp, unsigned pp_size,
                               const void *qm, unsigned qm_size,
                               int (*commit_bs_si)(AVCodecContext *,
@@ -90,7 +90,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, MpegEncContext *s,
     int      result;
 
     if (FAILED(IDirectXVideoDecoder_BeginFrame(ctx->decoder,
-                                               ff_dxva2_get_surface(s->current_picture_ptr),
+                                               ff_dxva2_get_surface(pic),
                                                NULL))) {
         av_log(avctx, AV_LOG_ERROR, "Failed to begin frame\n");
         return -1;
@@ -146,7 +146,5 @@ end:
         result = -1;
     }
 
-    if (!result)
-        ff_draw_horiz_band(s, 0, s->avctx->height);
     return result;
 }
diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h
index c06f1f3..d161eb9 100644
--- a/libavcodec/dxva2.h
+++ b/libavcodec/dxva2.h
@@ -29,8 +29,8 @@
  * Public libavcodec DXVA2 header.
  */
 
+#define _WIN32_WINNT 0x0600
 #include <stdint.h>
-
 #include <d3d9.h>
 #include <dxva2api.h>
 
diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index 2fd0767..6457824 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -44,15 +44,14 @@ static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
 static void fill_picture_parameters(struct dxva_context *ctx, const H264Context *h,
                                     DXVA_PicParams_H264 *pp)
 {
-    const MpegEncContext *s = &h->s;
-    const Picture *current_picture = s->current_picture_ptr;
+    const Picture *current_picture = h->cur_pic_ptr;
     int i, j;
 
     memset(pp, 0, sizeof(*pp));
     /* Configure current picture */
     fill_picture_entry(&pp->CurrPic,
                        ff_dxva2_get_surface_index(ctx, current_picture),
-                       s->picture_structure == PICT_BOTTOM_FIELD);
+                       h->picture_structure == PICT_BOTTOM_FIELD);
     /* Configure the set of references */
     pp->UsedForReferenceFlags  = 0;
     pp->NonExistingFrameFlags  = 0;
@@ -70,15 +69,15 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
                                ff_dxva2_get_surface_index(ctx, r),
                                r->long_ref != 0);
 
-            if ((r->f.reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
+            if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
                 pp->FieldOrderCntList[i][0] = r->field_poc[0];
-            if ((r->f.reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)
+            if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)
                 pp->FieldOrderCntList[i][1] = r->field_poc[1];
 
             pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num;
-            if (r->f.reference & PICT_TOP_FIELD)
+            if (r->reference & PICT_TOP_FIELD)
                 pp->UsedForReferenceFlags |= 1 << (2*i + 0);
-            if (r->f.reference & PICT_BOTTOM_FIELD)
+            if (r->reference & PICT_BOTTOM_FIELD)
                 pp->UsedForReferenceFlags |= 1 << (2*i + 1);
         } else {
             pp->RefFrameList[i].bPicEntry = 0xff;
@@ -88,13 +87,13 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
         }
     }
 
-    pp->wFrameWidthInMbsMinus1        = s->mb_width  - 1;
-    pp->wFrameHeightInMbsMinus1       = s->mb_height - 1;
+    pp->wFrameWidthInMbsMinus1        = h->mb_width  - 1;
+    pp->wFrameHeightInMbsMinus1       = h->mb_height - 1;
     pp->num_ref_frames                = h->sps.ref_frame_count;
 
-    pp->wBitFields                    = ((s->picture_structure != PICT_FRAME) <<  0) |
+    pp->wBitFields                    = ((h->picture_structure != PICT_FRAME) <<  0) |
                                         ((h->sps.mb_aff &&
-                                        (s->picture_structure == PICT_FRAME)) <<  1) |
+                                        (h->picture_structure == PICT_FRAME)) <<  1) |
                                         (h->sps.residual_color_transform_flag <<  2) |
                                         /* sp_for_switch_flag (not implemented by Libav) */
                                         (0                                    <<  3) |
@@ -109,7 +108,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
                                         (h->pps.transform_8x8_mode            << 13) |
                                         ((h->sps.level_idc >= 31)             << 14) |
                                         /* IntraPicFlag (Modified if we detect a non
-                                         * intra slice in decode_slice) */
+                                         * intra slice in dxva2_h264_decode_slice) */
                                         (1                                    << 15);
 
     pp->bit_depth_luma_minus8         = h->sps.bit_depth_luma - 8;
@@ -120,11 +119,11 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
         pp->Reserved16Bits            = 3; /* FIXME is there a way to detect the right mode ? */
     pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
     pp->CurrFieldOrderCnt[0] = 0;
-    if ((s->picture_structure & PICT_TOP_FIELD) &&
+    if ((h->picture_structure & PICT_TOP_FIELD) &&
         current_picture->field_poc[0] != INT_MAX)
         pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0];
     pp->CurrFieldOrderCnt[1] = 0;
-    if ((s->picture_structure & PICT_BOTTOM_FIELD) &&
+    if ((h->picture_structure & PICT_BOTTOM_FIELD) &&
         current_picture->field_poc[1] != INT_MAX)
         pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1];
     pp->pic_init_qs_minus26           = h->pps.init_qs - 26;
@@ -200,7 +199,6 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const MpegEncContext *s = &h->s;
     unsigned list;
 
     memset(slice, 0, sizeof(*slice));
@@ -208,9 +206,9 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
     slice->SliceBytesInBuffer    = size;
     slice->wBadSliceChopping     = 0;
 
-    slice->first_mb_in_slice     = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x;
+    slice->first_mb_in_slice     = (h->mb_y >> FIELD_OR_MBAFF_PICTURE(h)) * h->mb_width + h->mb_x;
     slice->NumMbsForSlice        = 0; /* XXX it is set once we have all slices */
-    slice->BitOffsetToSliceData  = get_bits_count(&s->gb);
+    slice->BitOffsetToSliceData  = get_bits_count(&h->gb);
     slice->slice_type            = ff_h264_get_slice_type(h);
     if (h->slice_type_fixed)
         slice->slice_type += 5;
@@ -232,7 +230,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
                 unsigned plane;
                 fill_picture_entry(&slice->RefPicList[list][i],
                                    ff_dxva2_get_surface_index(ctx, r),
-                                   r->f.reference == PICT_BOTTOM_FIELD);
+                                   r->reference == PICT_BOTTOM_FIELD);
                 for (plane = 0; plane < 3; plane++) {
                     int w, o;
                     if (plane == 0 && h->luma_weight_flag[list]) {
@@ -260,7 +258,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
         }
     }
     slice->slice_qs_delta    = 0; /* XXX not implemented by Libav */
-    slice->slice_qp_delta    = s->qscale - h->pps.init_qp;
+    slice->slice_qp_delta    = h->qscale - h->pps.init_qp;
     slice->redundant_pic_cnt = h->redundant_pic_count;
     if (h->slice_type == AV_PICTURE_TYPE_B)
         slice->direct_spatial_mv_pred_flag = h->direct_spatial_mv_pred;
@@ -277,11 +275,10 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
                                              DXVA2_DecodeBufferDesc *sc)
 {
     const H264Context *h = avctx->priv_data;
-    const MpegEncContext *s = &h->s;
-    const unsigned mb_count = s->mb_width * s->mb_height;
+    const unsigned mb_count = h->mb_width * h->mb_height;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const Picture *current_picture = h->s.current_picture_ptr;
-    struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
+    const Picture *current_picture = h->cur_pic_ptr;
+    struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
     DXVA_Slice_H264_Short *slice = NULL;
     uint8_t  *dxva_data, *current, *end;
     unsigned dxva_size;
@@ -370,13 +367,13 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
 }
 
 
-static int start_frame(AVCodecContext *avctx,
-                       av_unused const uint8_t *buffer,
-                       av_unused uint32_t size)
+static int dxva2_h264_start_frame(AVCodecContext *avctx,
+                                  av_unused const uint8_t *buffer,
+                                  av_unused uint32_t size)
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    struct dxva2_picture_context *ctx_pic = h->s.current_picture_ptr->f.hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = h->cur_pic_ptr->hwaccel_picture_private;
 
     if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
         return -1;
@@ -394,13 +391,14 @@ static int start_frame(AVCodecContext *avctx,
     return 0;
 }
 
-static int decode_slice(AVCodecContext *avctx,
-                        const uint8_t *buffer, uint32_t size)
+static int dxva2_h264_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t *buffer,
+                                   uint32_t size)
 {
     const H264Context *h = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    const Picture *current_picture = h->s.current_picture_ptr;
-    struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
+    const Picture *current_picture = h->cur_pic_ptr;
+    struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
     unsigned position;
 
     if (ctx_pic->slice_count >= MAX_SLICES)
@@ -424,19 +422,22 @@ static int decode_slice(AVCodecContext *avctx,
     return 0;
 }
 
-static int end_frame(AVCodecContext *avctx)
+static int dxva2_h264_end_frame(AVCodecContext *avctx)
 {
     H264Context *h = avctx->priv_data;
-    MpegEncContext *s = &h->s;
     struct dxva2_picture_context *ctx_pic =
-        h->s.current_picture_ptr->f.hwaccel_picture_private;
+        h->cur_pic_ptr->hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
-    return ff_dxva2_common_end_frame(avctx, s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, h->cur_pic_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_h264_draw_horiz_band(h, 0, h->avctx->height);
+    return ret;
 }
 
 AVHWAccel ff_h264_dxva2_hwaccel = {
@@ -444,8 +445,8 @@ AVHWAccel ff_h264_dxva2_hwaccel = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H264,
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = start_frame,
-    .decode_slice   = decode_slice,
-    .end_frame      = end_frame,
+    .start_frame    = dxva2_h264_start_frame,
+    .decode_slice   = dxva2_h264_decode_slice,
+    .end_frame      = dxva2_h264_end_frame,
     .priv_data_size = sizeof(struct dxva2_picture_context),
 };
diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
index e2305b1..a81cfbe 100644
--- a/libavcodec/dxva2_internal.h
+++ b/libavcodec/dxva2_internal.h
@@ -47,7 +47,7 @@ int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *,
                            unsigned mb_count);
 
 
-int ff_dxva2_common_end_frame(AVCodecContext *, MpegEncContext *,
+int ff_dxva2_common_end_frame(AVCodecContext *, Picture *,
                               const void *pp, unsigned pp_size,
                               const void *qm, unsigned qm_size,
                               int (*commit_bs_si)(AVCodecContext *,
diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
index fa6ae7b..049fa48 100644
--- a/libavcodec/dxva2_mpeg2.c
+++ b/libavcodec/dxva2_mpeg2.c
@@ -151,7 +151,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
     const struct MpegEncContext *s = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
     struct dxva2_picture_context *ctx_pic =
-        s->current_picture_ptr->f.hwaccel_picture_private;
+        s->current_picture_ptr->hwaccel_picture_private;
     const int is_field = s->picture_structure != PICT_FRAME;
     const unsigned mb_count = s->mb_width * (s->mb_height >> is_field);
     uint8_t  *dxva_data, *current, *end;
@@ -203,14 +203,14 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
                                   mb_count);
 }
 
-static int start_frame(AVCodecContext *avctx,
-                       av_unused const uint8_t *buffer,
-                       av_unused uint32_t size)
+static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,
+                                   av_unused const uint8_t *buffer,
+                                   av_unused uint32_t size)
 {
     const struct MpegEncContext *s = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
     struct dxva2_picture_context *ctx_pic =
-        s->current_picture_ptr->f.hwaccel_picture_private;
+        s->current_picture_ptr->hwaccel_picture_private;
 
     if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
         return -1;
@@ -225,12 +225,12 @@ static int start_frame(AVCodecContext *avctx,
     return 0;
 }
 
-static int decode_slice(AVCodecContext *avctx,
-                        const uint8_t *buffer, uint32_t size)
+static int dxva2_mpeg2_decode_slice(AVCodecContext *avctx,
+                                    const uint8_t *buffer, uint32_t size)
 {
     const struct MpegEncContext *s = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic =
-        s->current_picture_ptr->f.hwaccel_picture_private;
+        s->current_picture_ptr->hwaccel_picture_private;
     unsigned position;
 
     if (ctx_pic->slice_count >= MAX_SLICES)
@@ -246,18 +246,22 @@ static int decode_slice(AVCodecContext *avctx,
     return 0;
 }
 
-static int end_frame(AVCodecContext *avctx)
+static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
 {
     struct MpegEncContext *s = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic =
-        s->current_picture_ptr->f.hwaccel_picture_private;
+        s->current_picture_ptr->hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
-    return ff_dxva2_common_end_frame(avctx, s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, s->current_picture_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->qm, sizeof(ctx_pic->qm),
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_mpeg_draw_horiz_band(s, 0, avctx->height);
+    return ret;
 }
 
 AVHWAccel ff_mpeg2_dxva2_hwaccel = {
@@ -265,8 +269,8 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MPEG2VIDEO,
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = start_frame,
-    .decode_slice   = decode_slice,
-    .end_frame      = end_frame,
+    .start_frame    = dxva2_mpeg2_start_frame,
+    .decode_slice   = dxva2_mpeg2_decode_slice,
+    .end_frame      = dxva2_mpeg2_end_frame,
     .priv_data_size = sizeof(struct dxva2_picture_context),
 };
diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
index 5aed2f3..a72d91e 100644
--- a/libavcodec/dxva2_vc1.c
+++ b/libavcodec/dxva2_vc1.c
@@ -97,7 +97,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
                                   (v->vstransform      );
     pp->bPicOverflowBlocks      = (v->quantizer_mode << 6) |
                                   (v->multires       << 5) |
-                                  (s->resync_marker  << 4) |
+                                  (v->resync_marker  << 4) |
                                   (v->rangered       << 3) |
                                   (s->max_b_frames       );
     pp->bPicExtrapolation       = (!v->interlace || v->fcm == PROGRESSIVE) ? 1 : 2;
@@ -162,7 +162,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
     const VC1Context *v = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
     const MpegEncContext *s = &v->s;
-    struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->f.hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private;
 
     DXVA_SliceInfo *slice = &ctx_pic->si;
 
@@ -208,13 +208,13 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
                                   slice, sizeof(*slice), bs->NumMBsInBuffer);
 }
 
-static int start_frame(AVCodecContext *avctx,
-                       av_unused const uint8_t *buffer,
-                       av_unused uint32_t size)
+static int dxva2_vc1_start_frame(AVCodecContext *avctx,
+                                 av_unused const uint8_t *buffer,
+                                 av_unused uint32_t size)
 {
     const VC1Context *v = avctx->priv_data;
     struct dxva_context *ctx = avctx->hwaccel_context;
-    struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->f.hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
 
     if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
         return -1;
@@ -227,12 +227,13 @@ static int start_frame(AVCodecContext *avctx,
     return 0;
 }
 
-static int decode_slice(AVCodecContext *avctx,
-                        const uint8_t *buffer, uint32_t size)
+static int dxva2_vc1_decode_slice(AVCodecContext *avctx,
+                                  const uint8_t *buffer,
+                                  uint32_t size)
 {
     const VC1Context *v = avctx->priv_data;
     const Picture *current_picture = v->s.current_picture_ptr;
-    struct dxva2_picture_context *ctx_pic = current_picture->f.hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
 
     if (ctx_pic->bitstream_size > 0)
         return -1;
@@ -250,18 +251,22 @@ static int decode_slice(AVCodecContext *avctx,
     return 0;
 }
 
-static int end_frame(AVCodecContext *avctx)
+static int dxva2_vc1_end_frame(AVCodecContext *avctx)
 {
     VC1Context *v = avctx->priv_data;
-    struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->f.hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
+    int ret;
 
     if (ctx_pic->bitstream_size <= 0)
         return -1;
 
-    return ff_dxva2_common_end_frame(avctx, &v->s,
-                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
-                                     NULL, 0,
-                                     commit_bitstream_and_slice_buffer);
+    ret = ff_dxva2_common_end_frame(avctx, v->s.current_picture_ptr,
+                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    NULL, 0,
+                                    commit_bitstream_and_slice_buffer);
+    if (!ret)
+        ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);
+    return ret;
 }
 
 #if CONFIG_WMV3_DXVA2_HWACCEL
@@ -270,9 +275,9 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WMV3,
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = start_frame,
-    .decode_slice   = decode_slice,
-    .end_frame      = end_frame,
+    .start_frame    = dxva2_vc1_start_frame,
+    .decode_slice   = dxva2_vc1_decode_slice,
+    .end_frame      = dxva2_vc1_end_frame,
     .priv_data_size = sizeof(struct dxva2_picture_context),
 };
 #endif
@@ -282,8 +287,8 @@ AVHWAccel ff_vc1_dxva2_hwaccel = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VC1,
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
-    .start_frame    = start_frame,
-    .decode_slice   = decode_slice,
-    .end_frame      = end_frame,
+    .start_frame    = dxva2_vc1_start_frame,
+    .decode_slice   = dxva2_vc1_decode_slice,
+    .end_frame      = dxva2_vc1_end_frame,
     .priv_data_size = sizeof(struct dxva2_picture_context),
 };
diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c
index 3a80cb1..baba454 100644
--- a/libavcodec/eac3dec.c
+++ b/libavcodec/eac3dec.c
@@ -300,7 +300,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
        application can select from. each independent stream can also contain
        dependent streams which are used to add or replace channels. */
     if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
-        av_log_missing_feature(s->avctx, "Dependent substream decoding", 1);
+        avpriv_request_sample(s->avctx, "Dependent substream decoding");
         return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
     } else if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) {
         av_log(s->avctx, AV_LOG_ERROR, "Reserved frame type\n");
@@ -312,7 +312,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
        associated to an independent stream have matching substream id's. */
     if (s->substreamid) {
         /* only decode substream with id=0. skip any additional substreams. */
-        av_log_missing_feature(s->avctx, "Additional substreams", 1);
+        avpriv_request_sample(s->avctx, "Additional substreams");
         return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
     }
 
@@ -321,7 +321,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
            rates in bit allocation.  The best assumption would be that it is
            handled like AC-3 DolbyNet, but we cannot be sure until we have a
            sample which utilizes this feature. */
-        av_log_missing_feature(s->avctx, "Reduced sampling rate", 1);
+        avpriv_request_sample(s->avctx, "Reduced sampling rate");
         return AVERROR_PATCHWELCOME;
     }
     skip_bits(gbc, 5); // skip bitstream id
@@ -593,7 +593,7 @@ int ff_eac3_parse_header(AC3DecodeContext *s)
            It is likely the offset of each block within the frame. */
         int block_start_bits = (s->num_blocks-1) * (4 + av_log2(s->frame_size-2));
         skip_bits_long(gbc, block_start_bits);
-        av_log_missing_feature(s->avctx, "Block start info", 1);
+        avpriv_request_sample(s->avctx, "Block start info");
     }
 
     /* syntax state initialization */
diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
index 3c7a611..c238fc1 100644
--- a/libavcodec/eac3enc.c
+++ b/libavcodec/eac3enc.c
@@ -25,6 +25,8 @@
  */
 
 #define CONFIG_AC3ENC_FLOAT 1
+
+#include "libavutil/attributes.h"
 #include "ac3enc.h"
 #include "eac3enc.h"
 #include "eac3_data.h"
@@ -43,7 +45,7 @@ static const AVClass eac3enc_class = { "E-AC-3 Encoder", av_default_item_name,
 static int8_t eac3_frame_expstr_index_tab[3][4][4][4][4][4];
 
 
-void ff_eac3_exponent_init(void)
+av_cold void ff_eac3_exponent_init(void)
 {
     int i;
 
@@ -248,6 +250,7 @@ void ff_eac3_output_frame_header(AC3EncodeContext *s)
 #if CONFIG_EAC3_ENCODER
 AVCodec ff_eac3_encoder = {
     .name            = "eac3",
+    .long_name       = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"),
     .type            = AVMEDIA_TYPE_AUDIO,
     .id              = AV_CODEC_ID_EAC3,
     .priv_data_size  = sizeof(AC3EncodeContext),
@@ -256,7 +259,6 @@ AVCodec ff_eac3_encoder = {
     .close           = ff_ac3_encode_close,
     .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
-    .long_name       = NULL_IF_CONFIG_SMALL("ATSC A/52 E-AC-3"),
     .priv_class      = &eac3enc_class,
     .channel_layouts = ff_ac3_channel_layouts,
     .defaults        = ac3_defaults,
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
index b7e13b1..d39ebd3 100644
--- a/libavcodec/eacmv.c
+++ b/libavcodec/eacmv.c
@@ -36,9 +36,8 @@
 
 typedef struct CmvContext {
     AVCodecContext *avctx;
-    AVFrame frame;        ///< current
-    AVFrame last_frame;   ///< last
-    AVFrame last2_frame;  ///< second-last
+    AVFrame *last_frame;   ///< last
+    AVFrame *last2_frame;  ///< second-last
     int width, height;
     unsigned int palette[AVPALETTE_COUNT];
 } CmvContext;
@@ -47,16 +46,27 @@ static av_cold int cmv_decode_init(AVCodecContext *avctx){
     CmvContext *s = avctx->priv_data;
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+    s->last_frame  = av_frame_alloc();
+    s->last2_frame = av_frame_alloc();
+    if (!s->last_frame || !s->last2_frame) {
+        av_frame_free(&s->last_frame);
+        av_frame_free(&s->last2_frame);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
-static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){
-    unsigned char *dst = s->frame.data[0];
+static void cmv_decode_intra(CmvContext * s, AVFrame *frame,
+                             const uint8_t *buf, const uint8_t *buf_end)
+{
+    unsigned char *dst = frame->data[0];
     int i;
 
     for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++) {
         memcpy(dst, buf, s->avctx->width);
-        dst += s->frame.linesize[0];
+        dst += frame->linesize[0];
         buf += s->avctx->width;
     }
 }
@@ -80,7 +90,9 @@ static void cmv_motcomp(unsigned char *dst, int dst_stride,
     }
 }
 
-static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){
+static void cmv_decode_inter(CmvContext *s, AVFrame *frame, const uint8_t *buf,
+                             const uint8_t *buf_end)
+{
     const uint8_t *raw = buf + (s->avctx->width*s->avctx->height/16);
     int x,y,i;
 
@@ -88,48 +100,50 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t *
     for(y=0; y<s->avctx->height/4; y++)
     for(x=0; x<s->avctx->width/4 && buf_end - buf > i; x++) {
         if (buf[i]==0xFF) {
-            unsigned char *dst = s->frame.data[0] + (y*4)*s->frame.linesize[0] + x*4;
+            unsigned char *dst = frame->data[0] + (y*4)*frame->linesize[0] + x*4;
             if (raw+16<buf_end && *raw==0xFF) { /* intra */
                 raw++;
                 memcpy(dst, raw, 4);
-                memcpy(dst+s->frame.linesize[0], raw+4, 4);
-                memcpy(dst+2*s->frame.linesize[0], raw+8, 4);
-                memcpy(dst+3*s->frame.linesize[0], raw+12, 4);
+                memcpy(dst +     frame->linesize[0], raw+4, 4);
+                memcpy(dst + 2 * frame->linesize[0], raw+8, 4);
+                memcpy(dst + 3 * frame->linesize[0], raw+12, 4);
                 raw+=16;
             }else if(raw<buf_end) {  /* inter using second-last frame as reference */
                 int xoffset = (*raw & 0xF) - 7;
                 int yoffset = ((*raw >> 4)) - 7;
-                if (s->last2_frame.data[0])
-                    cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
-                                s->last2_frame.data[0], s->last2_frame.linesize[0],
+                if (s->last2_frame->data[0])
+                    cmv_motcomp(frame->data[0], frame->linesize[0],
+                                s->last2_frame->data[0], s->last2_frame->linesize[0],
                                 x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height);
                 raw++;
             }
         }else{  /* inter using last frame as reference */
             int xoffset = (buf[i] & 0xF) - 7;
             int yoffset = ((buf[i] >> 4)) - 7;
-            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],
+            if (s->last_frame->data[0])
+                cmv_motcomp(frame->data[0], 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++;
     }
 }
 
-static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end)
+static int cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end)
 {
-    int pal_start, pal_count, i;
+    int pal_start, pal_count, i, ret;
 
     if(buf_end - buf < 16) {
         av_log(s->avctx, AV_LOG_WARNING, "truncated header\n");
-        return;
+        return AVERROR_INVALIDDATA;
     }
 
     s->width  = AV_RL16(&buf[4]);
     s->height = AV_RL16(&buf[6]);
-    if (s->avctx->width!=s->width || s->avctx->height!=s->height)
-        avcodec_set_dimensions(s->avctx, s->width, s->height);
+
+    ret = ff_set_dimensions(s->avctx, s->width, s->height);
+    if (ret < 0)
+        return ret;
 
     s->avctx->time_base.num = 1;
     s->avctx->time_base.den = AV_RL16(&buf[10]);
@@ -142,6 +156,8 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t
         s->palette[i] = AV_RB24(buf);
         buf += 3;
     }
+
+    return 0;
 }
 
 #define EA_PREAMBLE_SIZE 8
@@ -155,64 +171,62 @@ static int cmv_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     CmvContext *s = avctx->priv_data;
     const uint8_t *buf_end = buf + buf_size;
+    AVFrame *frame = data;
+    int ret;
 
     if (buf_end - buf < EA_PREAMBLE_SIZE)
         return AVERROR_INVALIDDATA;
 
     if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) {
-        cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end);
+        ret = cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end);
+        if (ret < 0)
+            return ret;
         return buf_size;
     }
 
     if (av_image_check_size(s->width, s->height, 0, s->avctx))
         return -1;
 
-    /* shuffle */
-    if (s->last2_frame.data[0])
-        avctx->release_buffer(avctx, &s->last2_frame);
-    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;
-    if (ff_get_buffer(avctx, &s->frame)<0) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
 
     buf += EA_PREAMBLE_SIZE;
     if ((buf[0]&1)) {  // subtype
-        cmv_decode_inter(s, buf+2, buf_end);
-        s->frame.key_frame = 0;
-        s->frame.pict_type = AV_PICTURE_TYPE_P;
+        cmv_decode_inter(s, frame, buf+2, buf_end);
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
     }else{
-        s->frame.key_frame = 1;
-        s->frame.pict_type = AV_PICTURE_TYPE_I;
-        cmv_decode_intra(s, buf+2, buf_end);
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        cmv_decode_intra(s, frame, buf+2, buf_end);
     }
 
+    av_frame_unref(s->last2_frame);
+    av_frame_move_ref(s->last2_frame, s->last_frame);
+    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
 
 static av_cold int cmv_decode_end(AVCodecContext *avctx){
     CmvContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        s->avctx->release_buffer(avctx, &s->frame);
-    if (s->last_frame.data[0])
-        s->avctx->release_buffer(avctx, &s->last_frame);
-    if (s->last2_frame.data[0])
-        s->avctx->release_buffer(avctx, &s->last2_frame);
+
+    av_frame_free(&s->last_frame);
+    av_frame_free(&s->last2_frame);
 
     return 0;
 }
 
 AVCodec ff_eacmv_decoder = {
     .name           = "eacmv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts CMV video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CMV,
     .priv_data_size = sizeof(CmvContext),
@@ -220,5 +234,4 @@ AVCodec ff_eacmv_decoder = {
     .close          = cmv_decode_end,
     .decode         = cmv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts CMV video"),
 };
diff --git a/libavcodec/eaidct.c b/libavcodec/eaidct.c
index 9f2d5cc..5b2db44 100644
--- a/libavcodec/eaidct.c
+++ b/libavcodec/eaidct.c
@@ -25,7 +25,6 @@
  * @author Peter Ross <pross at xvid.org>
  */
 
-#include "dsputil.h"
 #include "eaidct.h"
 #include "libavutil/common.h"
 
@@ -64,7 +63,7 @@
 #define MUNGE_8BIT(x) av_clip_uint8((x)>>4)
 #define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_8BIT,src)
 
-static inline void ea_idct_col(DCTELEM *dest, const DCTELEM *src) {
+static inline void ea_idct_col(int16_t *dest, const int16_t *src) {
     if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
         dest[0]  =
         dest[8]  =
@@ -78,9 +77,9 @@ static inline void ea_idct_col(DCTELEM *dest, const DCTELEM *src) {
         IDCT_COL(dest, src);
 }
 
-void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block) {
+void ff_ea_idct_put_c(uint8_t *dest, int linesize, int16_t *block) {
     int i;
-    DCTELEM temp[64];
+    int16_t temp[64];
     block[0] += 4;
     for (i=0; i<8; i++)
         ea_idct_col(&temp[i], &block[i]);
diff --git a/libavcodec/eaidct.h b/libavcodec/eaidct.h
index 4c0b5ae..e78de04 100644
--- a/libavcodec/eaidct.h
+++ b/libavcodec/eaidct.h
@@ -20,8 +20,7 @@
 #define AVCODEC_EAIDCT_H
 
 #include <stdint.h>
-#include "dsputil.h"
 
-void ff_ea_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block);
+void ff_ea_idct_put_c(uint8_t *dest, int linesize, int16_t *block);
 
 #endif /* AVCODEC_EAIDCT_H */
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index bb4c7ba..22070a4 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -30,7 +30,6 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "aandcttab.h"
 #include "eaidct.h"
 #include "internal.h"
@@ -46,12 +45,11 @@
 typedef struct MadContext {
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame frame;
-    AVFrame last_frame;
+    AVFrame *last_frame;
     GetBitContext gb;
     void *bitstream_buf;
     unsigned int bitstream_buf_size;
-    DECLARE_ALIGNED(16, DCTELEM, block)[64];
+    DECLARE_ALIGNED(16, int16_t, block)[64];
     ScanTable scantable;
     uint16_t quant_matrix[64];
     int mb_x;
@@ -67,6 +65,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
     ff_init_scantable_permutation(s->dsp.idct_permutation, FF_NO_IDCT_PERM);
     ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
     ff_mpeg12_init_vlcs();
+
+    s->last_frame = av_frame_alloc();
+    if (!s->last_frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
@@ -79,38 +82,40 @@ static inline void comp(unsigned char *dst, int dst_stride,
             dst[j*dst_stride + i] = av_clip_uint8(src[j*src_stride + i] + add);
 }
 
-static inline void comp_block(MadContext *t, int mb_x, int mb_y,
+static inline void comp_block(MadContext *t, AVFrame *frame,
+                              int mb_x, int mb_y,
                               int j, int mv_x, int mv_y, int add)
 {
     if (j < 4) {
-        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.linesize[0], add);
+        comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
+             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->linesize[0], add);
     } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
         int index = j - 3;
-        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.linesize[index], add);
+        comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8,
+             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->linesize[index], add);
     }
 }
 
-static inline void idct_put(MadContext *t, DCTELEM *block, int mb_x, int mb_y, int j)
+static inline void idct_put(MadContext *t, AVFrame *frame, int16_t *block,
+                            int mb_x, int mb_y, int j)
 {
     if (j < 4) {
         ff_ea_idct_put_c(
-            t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3),
-            t->frame.linesize[0], block);
+            frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
+            frame->linesize[0], block);
     } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
         int index = j - 3;
         ff_ea_idct_put_c(
-            t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x*8,
-            t->frame.linesize[index], block);
+            frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x*8,
+            frame->linesize[index], block);
     }
 }
 
-static inline void decode_block_intra(MadContext *s, DCTELEM * block)
+static inline void decode_block_intra(MadContext *s, int16_t * block)
 {
     int level, i, j, run;
     RLTable *rl = &ff_rl_mpeg1;
@@ -180,7 +185,7 @@ static int decode_motion(GetBitContext *gb)
     return value;
 }
 
-static void decode_mb(MadContext *s, int inter)
+static void decode_mb(MadContext *s, AVFrame *frame, int inter)
 {
     int mv_map = 0;
     int mv_x, mv_y;
@@ -200,11 +205,11 @@ static void decode_mb(MadContext *s, int inter)
     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);
+            comp_block(s, frame, 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);
-            idct_put(s, s->block, s->mb_x, s->mb_y, j);
+            idct_put(s, frame, s->block, s->mb_x, s->mb_y, j);
         }
     }
 }
@@ -226,9 +231,10 @@ static int decode_frame(AVCodecContext *avctx,
     int buf_size       = avpkt->size;
     const uint8_t *buf_end = buf+buf_size;
     MadContext *s     = avctx->priv_data;
+    AVFrame *frame    = data;
     int width, height;
     int chunk_type;
-    int inter;
+    int inter, ret;
 
     if (buf_size < 17) {
         av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n");
@@ -249,34 +255,27 @@ static int decode_frame(AVCodecContext *avctx,
     buf += 16;
 
     if (avctx->width != width || avctx->height != height) {
-        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);
+        av_frame_unref(s->last_frame);
+        if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
+            return ret;
     }
 
-    s->frame.reference = 1;
-    if (!s->frame.data[0]) {
-        if (ff_get_buffer(avctx, &s->frame) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
-        }
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
     }
 
-    if (inter && !s->last_frame.data[0]) {
-        int ret;
+    if (inter && !s->last_frame->data[0]) {
         av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n");
-        s->last_frame.reference = 1;
-        ret = ff_get_buffer(avctx, &s->last_frame);
+        ret = ff_get_buffer(avctx, s->last_frame, AV_GET_BUFFER_FLAG_REF);
         if (ret < 0)
             return ret;
-        memset(s->last_frame.data[0], 0, s->last_frame.height *
-               s->last_frame.linesize[0]);
-        memset(s->last_frame.data[1], 0x80, s->last_frame.height / 2 *
-               s->last_frame.linesize[1]);
-        memset(s->last_frame.data[2], 0x80, s->last_frame.height / 2 *
-               s->last_frame.linesize[2]);
+        memset(s->last_frame->data[0], 0, s->last_frame->height *
+               s->last_frame->linesize[0]);
+        memset(s->last_frame->data[1], 0x80, s->last_frame->height / 2 *
+               s->last_frame->linesize[1]);
+        memset(s->last_frame->data[2], 0x80, s->last_frame->height / 2 *
+               s->last_frame->linesize[2]);
     }
 
     av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
@@ -288,13 +287,15 @@ static int decode_frame(AVCodecContext *avctx,
 
     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);
+            decode_mb(s, frame, inter);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
-    if (chunk_type != MADe_TAG)
-        FFSWAP(AVFrame, s->frame, s->last_frame);
+    if (chunk_type != MADe_TAG) {
+        av_frame_unref(s->last_frame);
+        if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
+            return ret;
+    }
 
     return buf_size;
 }
@@ -302,16 +303,14 @@ static int decode_frame(AVCodecContext *avctx,
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     MadContext *t = avctx->priv_data;
-    if (t->frame.data[0])
-        avctx->release_buffer(avctx, &t->frame);
-    if (t->last_frame.data[0])
-        avctx->release_buffer(avctx, &t->last_frame);
+    av_frame_free(&t->last_frame);
     av_free(t->bitstream_buf);
     return 0;
 }
 
 AVCodec ff_eamad_decoder = {
     .name           = "eamad",
+    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MAD,
     .priv_data_size = sizeof(MadContext),
@@ -319,5 +318,4 @@ AVCodec ff_eamad_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video")
 };
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index d6a6e55..1ead5f7 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -39,162 +39,173 @@
 
 typedef struct TgqContext {
     AVCodecContext *avctx;
-    AVFrame frame;
-    int width,height;
+    int width, height;
     ScanTable scantable;
     int qtable[64];
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
     GetByteContext gb;
 } TgqContext;
 
-static av_cold int tgq_decode_init(AVCodecContext *avctx){
+static av_cold int tgq_decode_init(AVCodecContext *avctx)
+{
     TgqContext *s = avctx->priv_data;
     uint8_t idct_permutation[64];
     s->avctx = avctx;
     ff_init_scantable_permutation(idct_permutation, FF_NO_IDCT_PERM);
     ff_init_scantable(idct_permutation, &s->scantable, ff_zigzag_direct);
     avctx->time_base = (AVRational){1, 15};
-    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    avctx->pix_fmt   = AV_PIX_FMT_YUV420P;
     return 0;
 }
 
-static void tgq_decode_block(TgqContext *s, DCTELEM block[64], GetBitContext *gb){
+static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb)
+{
     uint8_t *perm = s->scantable.permutated;
-    int i,j,value;
-    block[0] = get_sbits(gb,8) * s->qtable[0];
-    for(i=1; i<64; ) {
-        switch(show_bits(gb,3)) {
+    int i, j, value;
+    block[0] = get_sbits(gb, 8) * s->qtable[0];
+    for (i = 1; i < 64;) {
+        switch (show_bits(gb, 3)) {
         case 4:
             block[perm[i++]] = 0;
         case 0:
             block[perm[i++]] = 0;
-            skip_bits(gb,3);
+            skip_bits(gb, 3);
             break;
         case 5:
         case 1:
-            skip_bits(gb,2);
-            value = get_bits(gb,6);
-            for(j=0; j<value; j++)
+            skip_bits(gb, 2);
+            value = get_bits(gb, 6);
+            for (j = 0; j < value; j++)
                 block[perm[i++]] = 0;
             break;
         case 6:
-            skip_bits(gb,3);
+            skip_bits(gb, 3);
             block[perm[i]] = -s->qtable[perm[i]];
             i++;
             break;
         case 2:
-            skip_bits(gb,3);
+            skip_bits(gb, 3);
             block[perm[i]] = s->qtable[perm[i]];
             i++;
             break;
         case 7: // 111b
         case 3: // 011b
-            skip_bits(gb,2);
-            if (show_bits(gb,6)==0x3F) {
+            skip_bits(gb, 2);
+            if (show_bits(gb, 6) == 0x3F) {
                 skip_bits(gb, 6);
-                block[perm[i]] = get_sbits(gb,8)*s->qtable[perm[i]];
-            }else{
-                block[perm[i]] = get_sbits(gb,6)*s->qtable[perm[i]];
+                block[perm[i]] = get_sbits(gb, 8) * s->qtable[perm[i]];
+            } else {
+                block[perm[i]] = get_sbits(gb, 6) * s->qtable[perm[i]];
             }
             i++;
             break;
         }
     }
-    block[0] += 128<<4;
+    block[0] += 128 << 4;
 }
 
-static void tgq_idct_put_mb(TgqContext *s, DCTELEM (*block)[64], int mb_x, int mb_y){
-    int linesize= s->frame.linesize[0];
-    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16* linesize            ) + mb_x * 16;
-    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8;
-
-    ff_ea_idct_put_c(dest_y                 , linesize, block[0]);
-    ff_ea_idct_put_c(dest_y              + 8, linesize, block[1]);
-    ff_ea_idct_put_c(dest_y + 8*linesize    , linesize, block[2]);
-    ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]);
-    if(!(s->avctx->flags&CODEC_FLAG_GRAY)){
-         ff_ea_idct_put_c(dest_cb, s->frame.linesize[1], block[4]);
-         ff_ea_idct_put_c(dest_cr, s->frame.linesize[2], block[5]);
+static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame,
+                            int mb_x, int mb_y)
+{
+    int linesize = frame->linesize[0];
+    uint8_t *dest_y  = frame->data[0] + (mb_y * 16 * linesize)           + mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (mb_y * 8  * frame->linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (mb_y * 8  * frame->linesize[2]) + mb_x * 8;
+
+    ff_ea_idct_put_c(dest_y                   , linesize, block[0]);
+    ff_ea_idct_put_c(dest_y                + 8, linesize, block[1]);
+    ff_ea_idct_put_c(dest_y + 8 * linesize    , linesize, block[2]);
+    ff_ea_idct_put_c(dest_y + 8 * linesize + 8, linesize, block[3]);
+    if (!(s->avctx->flags & CODEC_FLAG_GRAY)) {
+         ff_ea_idct_put_c(dest_cb, frame->linesize[1], block[4]);
+         ff_ea_idct_put_c(dest_cr, frame->linesize[2], block[5]);
     }
 }
 
-static inline void tgq_dconly(TgqContext *s, unsigned char *dst, int dst_stride, int dc){
-    int level = av_clip_uint8((dc*s->qtable[0] + 2056)>>4);
+static inline void tgq_dconly(TgqContext *s, unsigned char *dst,
+                              int dst_stride, int dc)
+{
+    int level = av_clip_uint8((dc*s->qtable[0] + 2056) >> 4);
     int j;
-    for(j=0;j<8;j++)
-        memset(dst+j*dst_stride, level, 8);
+    for (j = 0; j < 8; j++)
+        memset(dst + j * dst_stride, level, 8);
 }
 
-static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8_t *dc)
+static void tgq_idct_put_mb_dconly(TgqContext *s, AVFrame *frame,
+                                   int mb_x, int mb_y, const int8_t *dc)
 {
-    int linesize= s->frame.linesize[0];
-    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16* linesize            ) + mb_x * 16;
-    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8 * s->frame.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8 * s->frame.linesize[2]) + mb_x * 8;
-    tgq_dconly(s,dest_y                 , linesize, dc[0]);
-    tgq_dconly(s,dest_y              + 8, linesize, dc[1]);
-    tgq_dconly(s,dest_y + 8*linesize    , linesize, dc[2]);
-    tgq_dconly(s,dest_y + 8*linesize + 8, linesize, dc[3]);
-    if(!(s->avctx->flags&CODEC_FLAG_GRAY)) {
-        tgq_dconly(s,dest_cb, s->frame.linesize[1], dc[4]);
-        tgq_dconly(s,dest_cr, s->frame.linesize[2], dc[5]);
+    int linesize = frame->linesize[0];
+    uint8_t *dest_y  = frame->data[0] + (mb_y * 16 * linesize)             + mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (mb_y * 8  * frame->linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (mb_y * 8  * frame->linesize[2]) + mb_x * 8;
+    tgq_dconly(s, dest_y,                    linesize, dc[0]);
+    tgq_dconly(s, dest_y                + 8, linesize, dc[1]);
+    tgq_dconly(s, dest_y + 8 * linesize,     linesize, dc[2]);
+    tgq_dconly(s, dest_y + 8 * linesize + 8, linesize, dc[3]);
+    if (!(s->avctx->flags & CODEC_FLAG_GRAY)) {
+        tgq_dconly(s, dest_cb, frame->linesize[1], dc[4]);
+        tgq_dconly(s, dest_cr, frame->linesize[2], dc[5]);
     }
 }
 
-static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x){
+static void tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x)
+{
     int mode;
     int i;
     int8_t dc[6];
 
     mode = bytestream2_get_byte(&s->gb);
-    if (mode>12) {
+    if (mode > 12) {
         GetBitContext gb;
         init_get_bits(&gb, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8);
-        for(i=0; i<6; i++)
+        for (i = 0; i < 6; i++)
             tgq_decode_block(s, s->block[i], &gb);
-        tgq_idct_put_mb(s, s->block, mb_x, mb_y);
+        tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y);
         bytestream2_skip(&s->gb, mode);
-    }else{
-        if (mode==3) {
+    } else {
+        if (mode == 3) {
             memset(dc, bytestream2_get_byte(&s->gb), 4);
             dc[4] = bytestream2_get_byte(&s->gb);
             dc[5] = bytestream2_get_byte(&s->gb);
-        }else if (mode==6) {
+        } else if (mode == 6) {
             bytestream2_get_buffer(&s->gb, dc, 6);
-        }else if (mode==12) {
+        } else if (mode == 12) {
             for (i = 0; i < 6; i++) {
                 dc[i] = bytestream2_get_byte(&s->gb);
                 bytestream2_skip(&s->gb, 1);
             }
-        }else{
+        } else {
             av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
         }
-        tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc);
+        tgq_idct_put_mb_dconly(s, frame, mb_x, mb_y, dc);
     }
 }
 
-static void tgq_calculate_qtable(TgqContext *s, int quant){
-    int i,j;
-    const int a = (14*(100-quant))/100 + 1;
-    const int b = (11*(100-quant))/100 + 4;
-    for(j=0;j<8;j++)
-    for(i=0;i<8;i++)
-        s->qtable[j*8+i] = ((a*(j+i)/(7+7) + b)*ff_inv_aanscales[j*8+i])>>(14-4);
+static void tgq_calculate_qtable(TgqContext *s, int quant)
+{
+    int i, j;
+    const int a = (14 * (100 - quant)) / 100 + 1;
+    const int b = (11 * (100 - quant)) / 100 + 4;
+    for (j = 0; j < 8; j++)
+        for (i = 0; i < 8; i++)
+            s->qtable[j * 8 + i] = ((a * (j + i) / (7 + 7) + b) *
+                                    ff_inv_aanscales[j * 8 + i]) >> (14 - 4);
 }
 
 static int tgq_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
-                            AVPacket *avpkt){
+                            AVPacket *avpkt)
+{
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    TgqContext *s = avctx->priv_data;
-    int x,y;
+    int buf_size       = avpkt->size;
+    TgqContext *s      = avctx->priv_data;
+    AVFrame *frame     = data;
+    int x, y, ret;
     int big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
 
     if (buf_size < 16) {
         av_log(avctx, AV_LOG_WARNING, "truncated header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     bytestream2_init(&s->gb, buf + 8, buf_size - 8);
     if (big_endian) {
@@ -205,49 +216,36 @@ static int tgq_decode_frame(AVCodecContext *avctx,
         s->height = bytestream2_get_le16u(&s->gb);
     }
 
-    if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
-        avcodec_set_dimensions(s->avctx, s->width, s->height);
-        if (s->frame.data[0])
-            avctx->release_buffer(avctx, &s->frame);
-    }
+    ret = ff_set_dimensions(s->avctx, s->width, s->height);
+    if (ret < 0)
+        return ret;
+
     tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb));
     bytestream2_skip(&s->gb, 3);
 
-    if (!s->frame.data[0]) {
-        s->frame.key_frame = 1;
-        s->frame.pict_type = AV_PICTURE_TYPE_I;
-        s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-        if (ff_get_buffer(avctx, &s->frame)) {
-            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
-        }
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
     }
+    frame->key_frame = 1;
+    frame->pict_type = AV_PICTURE_TYPE_I;
 
     for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
         for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
-            tgq_decode_mb(s, y, x);
+            tgq_decode_mb(s, frame, y, x);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return avpkt->size;
 }
 
-static av_cold int tgq_decode_end(AVCodecContext *avctx){
-    TgqContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        s->avctx->release_buffer(avctx, &s->frame);
-    return 0;
-}
-
 AVCodec ff_eatgq_decoder = {
     .name           = "eatgq",
+    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TGQ,
     .priv_data_size = sizeof(TgqContext),
     .init           = tgq_decode_init,
-    .close          = tgq_decode_end,
     .decode         = tgq_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
 };
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index 46644ab..3bc6506 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -31,6 +31,7 @@
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mem.h"
 
@@ -39,22 +40,28 @@
 
 typedef struct TgvContext {
     AVCodecContext *avctx;
-    AVFrame frame;
-    AVFrame last_frame;
+    AVFrame *last_frame;
+    uint8_t *frame_buffer;
     int width,height;
-    unsigned int palette[AVPALETTE_COUNT];
+    uint32_t palette[AVPALETTE_COUNT];
 
     int (*mv_codebook)[2];
-    unsigned char (*block_codebook)[16];
+    uint8_t (*block_codebook)[16];
     int num_mvs;           ///< current length of mv_codebook
     int num_blocks_packed; ///< current length of block_codebook
 } TgvContext;
 
-static av_cold int tgv_decode_init(AVCodecContext *avctx){
+static av_cold int tgv_decode_init(AVCodecContext *avctx)
+{
     TgvContext *s = avctx->priv_data;
-    s->avctx = avctx;
+    s->avctx         = avctx;
     avctx->time_base = (AVRational){1, 15};
-    avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    avctx->pix_fmt   = AV_PIX_FMT_PAL8;
+
+    s->last_frame = av_frame_alloc();
+    if (!s->last_frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
@@ -62,67 +69,69 @@ static av_cold int tgv_decode_init(AVCodecContext *avctx){
  * Unpack buffer
  * @return 0 on success, -1 on critical buffer underflow
  */
-static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst, int width, int height) {
-    unsigned char *dst_end = dst + width*height;
+static int unpack(const uint8_t *src, const uint8_t *src_end,
+                  uint8_t *dst, int width, int height)
+{
+    uint8_t *dst_end = dst + width*height;
     int size, size1, size2, offset, run;
-    unsigned char *dst_start = dst;
+    uint8_t *dst_start = dst;
 
     if (src[0] & 0x01)
         src += 5;
     else
         src += 2;
 
-    if (src+3>src_end)
-        return -1;
+    if (src + 3 > src_end)
+        return AVERROR_INVALIDDATA;
     size = AV_RB24(src);
     src += 3;
 
-    while(size>0 && src<src_end) {
+    while (size > 0 && src < src_end) {
 
         /* determine size1 and size2 */
         size1 = (src[0] & 3);
-        if ( src[0] & 0x80 ) {  // 1
+        if (src[0] & 0x80) {  // 1
             if (src[0] & 0x40 ) {  // 11
-                if ( src[0] & 0x20 ) {  // 111
-                    if ( src[0] < 0xFC )  // !(111111)
+                if (src[0] & 0x20) {  // 111
+                    if (src[0] < 0xFC)  // !(111111)
                         size1 = (((src[0] & 31) + 1) << 2);
                     src++;
                     size2 = 0;
                 } else {  // 110
                     offset = ((src[0] & 0x10) << 12) + AV_RB16(&src[1]) + 1;
-                    size2 = ((src[0] & 0xC) << 6) + src[3] + 5;
-                    src += 4;
+                    size2  = ((src[0] & 0xC) << 6) + src[3] + 5;
+                    src   += 4;
                 }
             } else {  // 10
-                size1 = ( ( src[1] & 0xC0) >> 6 );
+                size1  = ((src[1] & 0xC0) >> 6);
                 offset = (AV_RB16(&src[1]) & 0x3FFF) + 1;
-                size2 = (src[0] & 0x3F) + 4;
-                src += 3;
+                size2  = (src[0] & 0x3F) + 4;
+                src   += 3;
             }
         } else {  // 0
             offset = ((src[0] & 0x60) << 3) + src[1] + 1;
-            size2 = ((src[0] & 0x1C) >> 2) + 3;
-            src += 2;
+            size2  = ((src[0] & 0x1C) >> 2) + 3;
+            src   += 2;
         }
 
 
         /* fetch strip from src */
-        if (size1>src_end-src)
+        if (size1 > src_end - src)
             break;
 
-        if (size1>0) {
+        if (size1 > 0) {
             size -= size1;
-            run = FFMIN(size1, dst_end-dst);
+            run   = FFMIN(size1, dst_end - dst);
             memcpy(dst, src, run);
             dst += run;
             src += run;
         }
 
-        if (size2>0) {
-            if (dst-dst_start<offset)
+        if (size2 > 0) {
+            if (dst - dst_start < offset)
                 return 0;
             size -= size2;
-            run = FFMIN(size2, dst_end-dst);
+            run   = FFMIN(size2, dst_end - dst);
             av_memcpy_backptr(dst, offset, run);
             dst += run;
         }
@@ -135,7 +144,9 @@ static int unpack(const uint8_t *src, const uint8_t *src_end, unsigned char *dst
  * Decode inter-frame
  * @return 0 on success, -1 on critical buffer underflow
  */
-static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *buf_end){
+static int tgv_decode_inter(TgvContext *s, AVFrame *frame,
+                            const uint8_t *buf, const uint8_t *buf_end)
+{
     int num_mvs;
     int num_blocks_raw;
     int num_blocks_packed;
@@ -143,10 +154,10 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b
     int i,j,x,y;
     GetBitContext gb;
     int mvbits;
-    const unsigned char *blocks_raw;
+    const uint8_t *blocks_raw;
 
-    if(buf+12>buf_end)
-        return -1;
+    if (buf + 12 > buf_end)
+        return AVERROR_INVALIDDATA;
 
     num_mvs           = AV_RL16(&buf[0]);
     num_blocks_raw    = AV_RL16(&buf[2]);
@@ -167,166 +178,160 @@ static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *b
     }
 
     if (num_blocks_packed > s->num_blocks_packed) {
-        s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16*sizeof(unsigned char));
+        int err;
+        if ((err = av_reallocp(&s->block_codebook, num_blocks_packed * 16)) < 0) {
+            s->num_blocks_packed = 0;
+            return err;
+        }
         s->num_blocks_packed = num_blocks_packed;
     }
 
     /* read motion vectors */
-    mvbits = (num_mvs*2*10+31) & ~31;
+    mvbits = (num_mvs * 2 * 10 + 31) & ~31;
 
-    if (buf+(mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed>buf_end)
-        return -1;
+    if (buf + (mvbits >> 3) + 16 * num_blocks_raw + 8 * num_blocks_packed > buf_end)
+        return AVERROR_INVALIDDATA;
 
     init_get_bits(&gb, buf, mvbits);
-    for (i=0; i<num_mvs; i++) {
+    for (i = 0; i < num_mvs; i++) {
         s->mv_codebook[i][0] = get_sbits(&gb, 10);
         s->mv_codebook[i][1] = get_sbits(&gb, 10);
     }
-    buf += mvbits>>3;
+    buf += mvbits >> 3;
 
     /* note ptr to uncompressed blocks */
     blocks_raw = buf;
-    buf += num_blocks_raw*16;
+    buf       += num_blocks_raw * 16;
 
     /* read compressed blocks */
-    init_get_bits(&gb, buf, (buf_end-buf)<<3);
-    for (i=0; i<num_blocks_packed; i++) {
+    init_get_bits(&gb, buf, (buf_end - buf) << 3);
+    for (i = 0; i < num_blocks_packed; i++) {
         int tmp[4];
-        for(j=0; j<4; j++)
+        for (j = 0; j < 4; j++)
             tmp[j] = get_bits(&gb, 8);
-        for(j=0; j<16; j++)
+        for (j = 0; j < 16; j++)
             s->block_codebook[i][15-j] = tmp[get_bits(&gb, 2)];
     }
 
     if (get_bits_left(&gb) < vector_bits *
-        (s->avctx->height/4) * (s->avctx->width/4))
-        return -1;
+        (s->avctx->height / 4) * (s->avctx->width / 4))
+        return AVERROR_INVALIDDATA;
 
     /* read vectors and build frame */
-    for(y=0; y<s->avctx->height/4; y++)
-    for(x=0; x<s->avctx->width/4; x++) {
-        unsigned int vector = get_bits(&gb, vector_bits);
-        const unsigned char *src;
-        int src_stride;
-
-        if (vector < num_mvs) {
-            int mx = x * 4 + s->mv_codebook[vector][0];
-            int my = y * 4 + s->mv_codebook[vector][1];
-
-            if (   mx < 0 || mx + 4 > s->avctx->width
-                || my < 0 || my + 4 > s->avctx->height)
-                continue;
-
-            src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0];
-            src_stride = s->last_frame.linesize[0];
-        }else{
-            int offset = vector - num_mvs;
-            if (offset<num_blocks_raw)
-                src = blocks_raw + 16*offset;
-            else if (offset-num_blocks_raw<num_blocks_packed)
-                src = s->block_codebook[offset-num_blocks_raw];
-            else
-                continue;
-            src_stride = 4;
-        }
+    for (y = 0; y < s->avctx->height / 4; y++)
+        for (x = 0; x < s->avctx->width / 4; x++) {
+            unsigned int vector = get_bits(&gb, vector_bits);
+            const uint8_t *src;
+            int src_stride;
+
+            if (vector < num_mvs) {
+                int mx = x * 4 + s->mv_codebook[vector][0];
+                int my = y * 4 + s->mv_codebook[vector][1];
+
+                if (mx < 0 || mx + 4 > s->avctx->width ||
+                    my < 0 || my + 4 > s->avctx->height)
+                    continue;
+
+                src = s->last_frame->data[0] + mx + my * s->last_frame->linesize[0];
+                src_stride = s->last_frame->linesize[0];
+            } else {
+                int offset = vector - num_mvs;
+                if (offset < num_blocks_raw)
+                    src = blocks_raw + 16*offset;
+                else if (offset - num_blocks_raw < num_blocks_packed)
+                    src = s->block_codebook[offset - num_blocks_raw];
+                else
+                    continue;
+                src_stride = 4;
+            }
 
-        for(j=0; j<4; j++)
-        for(i=0; i<4; i++)
-            s->frame.data[0][ (y*4+j)*s->frame.linesize[0] + (x*4+i)  ] =
-               src[j*src_stride + i];
+            for (j = 0; j < 4; j++)
+                for (i = 0; i < 4; i++)
+                    frame->data[0][(y * 4 + j) * frame->linesize[0] + (x * 4 + i)] =
+                        src[j * src_stride + i];
     }
 
     return 0;
 }
 
-/** release AVFrame buffers if allocated */
-static void cond_release_buffer(AVFrame *pic)
-{
-    if (pic->data[0]) {
-        av_freep(&pic->data[0]);
-        av_free(pic->data[1]);
-    }
-}
-
 static int tgv_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    TgvContext *s = avctx->priv_data;
+    const uint8_t *buf     = avpkt->data;
+    int buf_size           = avpkt->size;
+    TgvContext *s          = avctx->priv_data;
     const uint8_t *buf_end = buf + buf_size;
-    int chunk_type;
+    AVFrame *frame         = data;
+    int chunk_type, ret;
 
     chunk_type = AV_RL32(&buf[0]);
-    buf += EA_PREAMBLE_SIZE;
+    buf       += EA_PREAMBLE_SIZE;
 
-    if (chunk_type==kVGT_TAG) {
+    if (chunk_type == kVGT_TAG) {
         int pal_count, i;
-        if(buf+12>buf_end) {
+        if (buf + 12 > buf_end) {
             av_log(avctx, AV_LOG_WARNING, "truncated header\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         s->width  = AV_RL16(&buf[0]);
         s->height = AV_RL16(&buf[2]);
-        if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
-            avcodec_set_dimensions(s->avctx, s->width, s->height);
-            cond_release_buffer(&s->frame);
-            cond_release_buffer(&s->last_frame);
+        if (s->avctx->width != s->width || s->avctx->height != s->height) {
+            av_freep(&s->frame_buffer);
+            av_frame_unref(s->last_frame);
+            if ((ret = ff_set_dimensions(s->avctx, s->width, s->height)) < 0)
+                return ret;
         }
 
         pal_count = AV_RL16(&buf[6]);
         buf += 12;
-        for(i=0; i<pal_count && i<AVPALETTE_COUNT && buf+2<buf_end; i++) {
+        for (i = 0; i < pal_count && i < AVPALETTE_COUNT && buf + 2 < buf_end; i++) {
             s->palette[i] = AV_RB24(buf);
             buf += 3;
         }
     }
 
-    if (av_image_check_size(s->width, s->height, 0, avctx))
-        return -1;
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
+        return ret;
 
-    /* shuffle */
-    FFSWAP(AVFrame, s->frame, s->last_frame);
-    if (!s->frame.data[0]) {
-        s->frame.reference = 1;
-        s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-        s->frame.linesize[0] = s->width;
+    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
 
-        s->frame.data[0] = av_malloc(s->width * s->height);
-        if (!s->frame.data[0])
-            return AVERROR(ENOMEM);
-        s->frame.data[1] = av_malloc(AVPALETTE_SIZE);
-        if (!s->frame.data[1]) {
-            av_freep(&s->frame.data[0]);
+    if (chunk_type == kVGT_TAG) {
+        int y;
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
+
+        if (!s->frame_buffer &&
+            !(s->frame_buffer = av_malloc(s->width * s->height)))
             return AVERROR(ENOMEM);
-        }
-    }
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
-    if(chunk_type==kVGT_TAG) {
-        s->frame.key_frame = 1;
-        s->frame.pict_type = AV_PICTURE_TYPE_I;
-        if (unpack(buf, buf_end, s->frame.data[0], s->avctx->width, s->avctx->height)<0) {
+        if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width, s->avctx->height) < 0) {
             av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
-    }else{
-        if (!s->last_frame.data[0]) {
+        for (y = 0; y < s->height; y++)
+            memcpy(frame->data[0]  + y * frame->linesize[0],
+                   s->frame_buffer + y * s->width,
+                   s->width);
+    } else {
+        if (!s->last_frame->data[0]) {
             av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n");
             return buf_size;
         }
-        s->frame.key_frame = 0;
-        s->frame.pict_type = AV_PICTURE_TYPE_P;
-        if (tgv_decode_inter(s, buf, buf_end)<0) {
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        if (tgv_decode_inter(s, frame, buf, buf_end) < 0) {
             av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
+    av_frame_unref(s->last_frame);
+    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
@@ -334,8 +339,8 @@ static int tgv_decode_frame(AVCodecContext *avctx,
 static av_cold int tgv_decode_end(AVCodecContext *avctx)
 {
     TgvContext *s = avctx->priv_data;
-    cond_release_buffer(&s->frame);
-    cond_release_buffer(&s->last_frame);
+    av_frame_free(&s->last_frame);
+    av_freep(&s->frame_buffer);
     av_free(s->mv_codebook);
     av_free(s->block_codebook);
     return 0;
@@ -343,11 +348,12 @@ static av_cold int tgv_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_eatgv_decoder = {
     .name           = "eatgv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TGV,
     .priv_data_size = sizeof(TgvContext),
     .init           = tgv_decode_init,
     .close          = tgv_decode_end,
     .decode         = tgv_decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
+    .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index f9141e2..2345cc7 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -28,7 +28,6 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "aandcttab.h"
 #include "eaidct.h"
 #include "internal.h"
@@ -37,10 +36,9 @@
 
 typedef struct TqiContext {
     MpegEncContext s;
-    AVFrame frame;
     void *bitstream_buf;
     unsigned int bitstream_buf_size;
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
 } TqiContext;
 
 static av_cold int tqi_decode_init(AVCodecContext *avctx)
@@ -58,7 +56,7 @@ static av_cold int tqi_decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static int tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64])
+static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64])
 {
     int n;
     s->dsp.clear_blocks(block[0]);
@@ -69,21 +67,21 @@ static int tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64])
     return 0;
 }
 
-static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64])
+static inline void tqi_idct_put(TqiContext *t, AVFrame *frame, int16_t (*block)[64])
 {
     MpegEncContext *s = &t->s;
-    int linesize= t->frame.linesize[0];
-    uint8_t *dest_y  = t->frame.data[0] + (s->mb_y * 16* linesize            ) + s->mb_x * 16;
-    uint8_t *dest_cb = t->frame.data[1] + (s->mb_y * 8 * t->frame.linesize[1]) + s->mb_x * 8;
-    uint8_t *dest_cr = t->frame.data[2] + (s->mb_y * 8 * t->frame.linesize[2]) + s->mb_x * 8;
+    int linesize = frame->linesize[0];
+    uint8_t *dest_y  = frame->data[0] + (s->mb_y * 16* linesize            ) + s->mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (s->mb_y * 8 * frame->linesize[1]) + s->mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (s->mb_y * 8 * frame->linesize[2]) + s->mb_x * 8;
 
     ff_ea_idct_put_c(dest_y                 , linesize, block[0]);
     ff_ea_idct_put_c(dest_y              + 8, linesize, block[1]);
     ff_ea_idct_put_c(dest_y + 8*linesize    , linesize, block[2]);
     ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]);
     if(!(s->avctx->flags&CODEC_FLAG_GRAY)) {
-        ff_ea_idct_put_c(dest_cb, t->frame.linesize[1], block[4]);
-        ff_ea_idct_put_c(dest_cr, t->frame.linesize[2], block[5]);
+        ff_ea_idct_put_c(dest_cb, frame->linesize[1], block[4]);
+        ff_ea_idct_put_c(dest_cr, frame->linesize[2], block[5]);
     }
 }
 
@@ -105,21 +103,21 @@ static int tqi_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf_end = buf+buf_size;
     TqiContext *t = avctx->priv_data;
     MpegEncContext *s = &t->s;
+    AVFrame *frame = data;
+    int ret;
 
     s->width  = AV_RL16(&buf[0]);
     s->height = AV_RL16(&buf[2]);
     tqi_calculate_qtable(s, buf[4]);
     buf += 8;
 
-    if (t->frame.data[0])
-        avctx->release_buffer(avctx, &t->frame);
+    ret = ff_set_dimensions(s->avctx, s->width, s->height);
+    if (ret < 0)
+        return ret;
 
-    if (s->avctx->width!=s->width || s->avctx->height!=s->height)
-        avcodec_set_dimensions(s->avctx, s->width, s->height);
-
-    if(ff_get_buffer(avctx, &t->frame) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     av_fast_padded_malloc(&t->bitstream_buf, &t->bitstream_buf_size,
@@ -135,25 +133,23 @@ static int tqi_decode_frame(AVCodecContext *avctx,
     {
         if (tqi_decode_mb(s, t->block) < 0)
             break;
-        tqi_idct_put(t, t->block);
+        tqi_idct_put(t, frame, t->block);
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = t->frame;
     return buf_size;
 }
 
 static av_cold int tqi_decode_end(AVCodecContext *avctx)
 {
     TqiContext *t = avctx->priv_data;
-    if(t->frame.data[0])
-        avctx->release_buffer(avctx, &t->frame);
     av_free(t->bitstream_buf);
     return 0;
 }
 
 AVCodec ff_eatqi_decoder = {
     .name           = "eatqi",
+    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TQI,
     .priv_data_size = sizeof(TqiContext),
@@ -161,5 +157,4 @@ AVCodec ff_eatqi_decoder = {
     .close          = tqi_decode_end,
     .decode         = tqi_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"),
 };
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index ae9ef68..51ebc04 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -27,60 +27,24 @@
 
 #include <limits.h>
 
+#include "libavutil/internal.h"
 #include "avcodec.h"
-#include "dsputil.h"
+#include "error_resilience.h"
 #include "mpegvideo.h"
-#include "h264.h"
 #include "rectangle.h"
 #include "thread.h"
-
-/*
- * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
- * but error concealment must support both h264 and h263 thus we must undo this
- */
-#undef mb_intra
-
-static void decode_mb(MpegEncContext *s, int ref)
-{
-    s->dest[0] = s->current_picture.f.data[0] + (s->mb_y *  16                       * s->linesize)   + s->mb_x *  16;
-    s->dest[1] = s->current_picture.f.data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
-    s->dest[2] = s->current_picture.f.data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
-
-    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);
-        /* 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;
-        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);
-        ff_h264_hl_decode_mb(h);
-    } else {
-        assert(ref == 0);
-        ff_MPV_decode_mb(s, s->block);
-    }
-}
+#include "version.h"
 
 /**
  * @param stride the number of MVs to get to the next row
  * @param mv_step the number of MVs per row or column in a macroblock
  */
-static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride)
+static void set_mv_strides(ERContext *s, int *mv_step, int *stride)
 {
-    if (s->codec_id == AV_CODEC_ID_H264) {
-        H264Context *h = (void*)s;
+    if (s->avctx->codec_id == AV_CODEC_ID_H264) {
         assert(s->quarter_sample);
         *mv_step = 4;
-        *stride  = h->b_stride;
+        *stride  = s->mb_width * 4;
     } else {
         *mv_step = 2;
         *stride  = s->b8_stride;
@@ -90,9 +54,10 @@ static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride)
 /**
  * Replace the current MB with a flat dc-only version.
  */
-static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb,
+static void put_dc(ERContext *s, uint8_t *dest_y, uint8_t *dest_cb,
                    uint8_t *dest_cr, int mb_x, int mb_y)
 {
+    int *linesize = s->cur_pic->f.linesize;
     int dc, dcu, dcv, y, i;
     for (i = 0; i < 4; i++) {
         dc = s->dc_val[0][mb_x * 2 + (i &  1) + (mb_y * 2 + (i >> 1)) * s->b8_stride];
@@ -103,7 +68,7 @@ static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb,
         for (y = 0; y < 8; y++) {
             int x;
             for (x = 0; x < 8; x++)
-                dest_y[x + (i &  1) * 8 + (y + (i >> 1) * 8) * s->linesize] = dc / 8;
+                dest_y[x + (i &  1) * 8 + (y + (i >> 1) * 8) * linesize[0]] = dc / 8;
         }
     }
     dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride];
@@ -119,8 +84,8 @@ static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb,
     for (y = 0; y < 8; y++) {
         int x;
         for (x = 0; x < 8; x++) {
-            dest_cb[x + y * s->uvlinesize] = dcu / 8;
-            dest_cr[x + y * s->uvlinesize] = dcv / 8;
+            dest_cb[x + y * linesize[1]] = dcu / 8;
+            dest_cr[x + y * linesize[2]] = dcv / 8;
         }
     }
 }
@@ -166,7 +131,7 @@ static void filter181(int16_t *data, int width, int height, int stride)
  * @param w     width in 8 pixel blocks
  * @param h     height in 8 pixel blocks
  */
-static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
+static void guess_dc(ERContext *s, int16_t *dc, int w,
                      int h, int stride, int is_luma)
 {
     int b_x, b_y;
@@ -180,7 +145,7 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
             mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
             error    = s->error_status_table[mb_index];
 
-            if (IS_INTER(s->current_picture.f.mb_type[mb_index]))
+            if (IS_INTER(s->cur_pic->mb_type[mb_index]))
                 continue; // inter
             if (!(error & ER_DC_ERROR))
                 continue; // dc-ok
@@ -189,7 +154,7 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
             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]);
+                int intra_j    = IS_INTRA(s->cur_pic->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;
@@ -201,7 +166,7 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
             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]);
+                int intra_j    = IS_INTRA(s->cur_pic->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;
@@ -213,7 +178,7 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
             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]);
+                int intra_j    = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
 
                 if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
                     color[2]    = dc[b_x + j * stride];
@@ -226,7 +191,7 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
             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]);
+                int intra_j    = IS_INTRA(s->cur_pic->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;
@@ -252,11 +217,11 @@ static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
  * @param w     width in 8 pixel blocks
  * @param h     height in 8 pixel blocks
  */
-static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w,
+static void h_block_filter(ERContext *s, uint8_t *dst, int w,
                            int h, int stride, int is_luma)
 {
     int b_x, b_y, mvx_stride, mvy_stride;
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     set_mv_strides(s, &mvx_stride, &mvy_stride);
     mvx_stride >>= is_luma;
     mvy_stride *= mvx_stride;
@@ -266,13 +231,13 @@ static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w,
             int y;
             int left_status  = s->error_status_table[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride];
             int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
-            int left_intra   = IS_INTRA(s->current_picture.f.mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
-            int right_intra  = IS_INTRA(s->current_picture.f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
+            int left_intra   = IS_INTRA(s->cur_pic->mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
+            int right_intra  = IS_INTRA(s->cur_pic->mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
             int left_damage  = left_status & ER_MB_ERROR;
             int right_damage = right_status & ER_MB_ERROR;
             int offset       = b_x * 8 + b_y * stride * 8;
-            int16_t *left_mv  = s->current_picture.f.motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
-            int16_t *right_mv = s->current_picture.f.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
+            int16_t *left_mv  = s->cur_pic->motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
+            int16_t *right_mv = s->cur_pic->motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
             if (!(left_damage || right_damage))
                 continue; // both undamaged
             if ((!left_intra) && (!right_intra) &&
@@ -320,11 +285,11 @@ static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w,
  * @param w     width in 8 pixel blocks
  * @param h     height in 8 pixel blocks
  */
-static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h,
+static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
                            int stride, int is_luma)
 {
     int b_x, b_y, mvx_stride, mvy_stride;
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     set_mv_strides(s, &mvx_stride, &mvy_stride);
     mvx_stride >>= is_luma;
     mvy_stride *= mvx_stride;
@@ -334,14 +299,14 @@ static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h,
             int x;
             int top_status    = s->error_status_table[(b_x >> is_luma) +  (b_y      >> is_luma) * s->mb_stride];
             int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
-            int top_intra     = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
-            int bottom_intra  = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
+            int top_intra     = IS_INTRA(s->cur_pic->mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
+            int bottom_intra  = IS_INTRA(s->cur_pic->mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
             int top_damage    = top_status & ER_MB_ERROR;
             int bottom_damage = bottom_status & ER_MB_ERROR;
             int offset        = b_x * 8 + b_y * stride * 8;
 
-            int16_t *top_mv    = s->current_picture.f.motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
-            int16_t *bottom_mv = s->current_picture.f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
+            int16_t *top_mv    = s->cur_pic->motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
+            int16_t *bottom_mv = s->cur_pic->motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
 
             if (!(top_damage || bottom_damage))
                 continue; // both undamaged
@@ -386,7 +351,7 @@ static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h,
     }
 }
 
-static void guess_mv(MpegEncContext *s)
+static void guess_mv(ERContext *s)
 {
     uint8_t *fixed = s->er_temp_buffer;
 #define MV_FROZEN    3
@@ -406,7 +371,7 @@ static void guess_mv(MpegEncContext *s)
         int f = 0;
         int error = s->error_status_table[mb_xy];
 
-        if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
+        if (IS_INTRA(s->cur_pic->mb_type[mb_xy]))
             f = MV_FROZEN; // intra // FIXME check
         if (!(error & ER_MV_ERROR))
             f = MV_FROZEN; // inter with undamaged MV
@@ -419,32 +384,19 @@ static void guess_mv(MpegEncContext *s)
     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;
+                int mv_dir = (s->last_pic && s->last_pic->f.data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
 
-                ff_update_block_index(s);
-
-                if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
+                if (IS_INTRA(s->cur_pic->mb_type[mb_xy]))
                     continue;
                 if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
                     continue;
 
-                s->mv_dir     = s->last_picture.f.data[0] ? MV_DIR_FORWARD
-                                                          : MV_DIR_BACKWARD;
-                s->mb_intra   = 0;
-                s->mv_type    = MV_TYPE_16X16;
-                s->mb_skipped = 0;
-
-                s->dsp.clear_blocks(s->block[0]);
-
-                s->mb_x        = mb_x;
-                s->mb_y        = mb_y;
                 s->mv[0][0][0] = 0;
                 s->mv[0][0][1] = 0;
-                decode_mb(s, 0);
+                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
+                             mb_x, mb_y, 0, 0);
             }
         }
         return;
@@ -461,9 +413,6 @@ static void guess_mv(MpegEncContext *s)
 
             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 +424,13 @@ static void guess_mv(MpegEncContext *s)
                     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]);
+                    assert(!IS_INTRA(s->cur_pic->mb_type[mb_xy]));
+                    assert(s->last_pic && s->last_pic->f.data[0]);
 
                     j = 0;
                     if (mb_x > 0             && fixed[mb_xy - 1]         == MV_FROZEN)
@@ -513,38 +460,38 @@ static void guess_mv(MpegEncContext *s)
 
                     if (mb_x > 0 && fixed[mb_xy - 1]) {
                         mv_predictor[pred_count][0] =
-                            s->current_picture.f.motion_val[0][mot_index - mot_step][0];
+                            s->cur_pic->motion_val[0][mot_index - mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->current_picture.f.motion_val[0][mot_index - mot_step][1];
+                            s->cur_pic->motion_val[0][mot_index - mot_step][1];
                         ref[pred_count] =
-                            s->current_picture.f.ref_index[0][4 * (mb_xy - 1)];
+                            s->cur_pic->ref_index[0][4 * (mb_xy - 1)];
                         pred_count++;
                     }
                     if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
                         mv_predictor[pred_count][0] =
-                            s->current_picture.f.motion_val[0][mot_index + mot_step][0];
+                            s->cur_pic->motion_val[0][mot_index + mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->current_picture.f.motion_val[0][mot_index + mot_step][1];
+                            s->cur_pic->motion_val[0][mot_index + mot_step][1];
                         ref[pred_count] =
-                            s->current_picture.f.ref_index[0][4 * (mb_xy + 1)];
+                            s->cur_pic->ref_index[0][4 * (mb_xy + 1)];
                         pred_count++;
                     }
                     if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
                         mv_predictor[pred_count][0] =
-                            s->current_picture.f.motion_val[0][mot_index - mot_stride * mot_step][0];
+                            s->cur_pic->motion_val[0][mot_index - mot_stride * mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->current_picture.f.motion_val[0][mot_index - mot_stride * mot_step][1];
+                            s->cur_pic->motion_val[0][mot_index - mot_stride * mot_step][1];
                         ref[pred_count] =
-                            s->current_picture.f.ref_index[0][4 * (mb_xy - s->mb_stride)];
+                            s->cur_pic->ref_index[0][4 * (mb_xy - s->mb_stride)];
                         pred_count++;
                     }
                     if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride]) {
                         mv_predictor[pred_count][0] =
-                            s->current_picture.f.motion_val[0][mot_index + mot_stride * mot_step][0];
+                            s->cur_pic->motion_val[0][mot_index + mot_stride * mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->current_picture.f.motion_val[0][mot_index + mot_stride * mot_step][1];
+                            s->cur_pic->motion_val[0][mot_index + mot_stride * mot_step][1];
                         ref[pred_count] =
-                            s->current_picture.f.ref_index[0][4 * (mb_xy + s->mb_stride)];
+                            s->cur_pic->ref_index[0][4 * (mb_xy + s->mb_stride)];
                         pred_count++;
                     }
                     if (pred_count == 0)
@@ -602,19 +549,19 @@ skip_mean_and_median:
                         if (s->avctx->codec_id == AV_CODEC_ID_H264) {
                             // FIXME
                         } else {
-                            ff_thread_await_progress(&s->last_picture_ptr->f,
+                            ff_thread_await_progress(&s->last_pic->tf,
                                                      mb_y, 0);
                         }
-                        if (!s->last_picture.f.motion_val[0] ||
-                            !s->last_picture.f.ref_index[0])
+                        if (!s->last_pic->motion_val[0] ||
+                            !s->last_pic->ref_index[0])
                             goto skip_last_mv;
-                        prev_x   = s->last_picture.f.motion_val[0][mot_index][0];
-                        prev_y   = s->last_picture.f.motion_val[0][mot_index][1];
-                        prev_ref = s->last_picture.f.ref_index[0][4 * mb_xy];
+                        prev_x   = s->last_pic->motion_val[0][mot_index][0];
+                        prev_y   = s->last_pic->motion_val[0][mot_index][1];
+                        prev_ref = s->last_pic->ref_index[0][4 * mb_xy];
                     } else {
-                        prev_x   = s->current_picture.f.motion_val[0][mot_index][0];
-                        prev_y   = s->current_picture.f.motion_val[0][mot_index][1];
-                        prev_ref = s->current_picture.f.ref_index[0][4 * mb_xy];
+                        prev_x   = s->cur_pic->motion_val[0][mot_index][0];
+                        prev_y   = s->cur_pic->motion_val[0][mot_index][1];
+                        prev_ref = s->cur_pic->ref_index[0][4 * mb_xy];
                     }
 
                     /* last MV */
@@ -624,54 +571,47 @@ skip_mean_and_median:
                     pred_count++;
 
 skip_last_mv:
-                    s->mv_dir     = MV_DIR_FORWARD;
-                    s->mb_intra   = 0;
-                    s->mv_type    = MV_TYPE_16X16;
-                    s->mb_skipped = 0;
-
-                    s->dsp.clear_blocks(s->block[0]);
-
-                    s->mb_x = mb_x;
-                    s->mb_y = mb_y;
 
                     for (j = 0; j < pred_count; j++) {
+                        int *linesize = s->cur_pic->f.linesize;
                         int score = 0;
-                        uint8_t *src = s->current_picture.f.data[0] +
-                                       mb_x * 16 + mb_y * 16 * s->linesize;
+                        uint8_t *src = s->cur_pic->f.data[0] +
+                                       mb_x * 16 + mb_y * 16 * linesize[0];
 
-                        s->current_picture.f.motion_val[0][mot_index][0] =
+                        s->cur_pic->motion_val[0][mot_index][0] =
                             s->mv[0][0][0] = mv_predictor[j][0];
-                        s->current_picture.f.motion_val[0][mot_index][1] =
+                        s->cur_pic->motion_val[0][mot_index][1] =
                             s->mv[0][0][1] = mv_predictor[j][1];
 
                         // predictor intra or otherwise not available
                         if (ref[j] < 0)
                             continue;
 
-                        decode_mb(s, ref[j]);
+                        s->decode_mb(s->opaque, ref[j], MV_DIR_FORWARD,
+                                     MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
 
                         if (mb_x > 0 && fixed[mb_xy - 1]) {
                             int k;
                             for (k = 0; k < 16; k++)
-                                score += FFABS(src[k * s->linesize - 1] -
-                                               src[k * s->linesize]);
+                                score += FFABS(src[k * linesize[0] - 1] -
+                                               src[k * linesize[0]]);
                         }
                         if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
                             int k;
                             for (k = 0; k < 16; k++)
-                                score += FFABS(src[k * s->linesize + 15] -
-                                               src[k * s->linesize + 16]);
+                                score += FFABS(src[k * linesize[0] + 15] -
+                                               src[k * linesize[0] + 16]);
                         }
                         if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
                             int k;
                             for (k = 0; k < 16; k++)
-                                score += FFABS(src[k - s->linesize] - src[k]);
+                                score += FFABS(src[k - linesize[0]] - src[k]);
                         }
                         if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride]) {
                             int k;
                             for (k = 0; k < 16; k++)
-                                score += FFABS(src[k + s->linesize * 15] -
-                                               src[k + s->linesize * 16]);
+                                score += FFABS(src[k + linesize[0] * 15] -
+                                               src[k + linesize[0] * 16]);
                         }
 
                         if (score <= best_score) { // <= will favor the last MV
@@ -685,11 +625,12 @@ skip_last_mv:
 
                     for (i = 0; i < mot_step; i++)
                         for (j = 0; j < mot_step; j++) {
-                            s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
-                            s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
+                            s->cur_pic->motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
+                            s->cur_pic->motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
                         }
 
-                    decode_mb(s, ref[best_pred]);
+                    s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
+                                 MV_TYPE_16X16, &s->mv, mb_x, mb_y, 0, 0);
 
 
                     if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
@@ -712,11 +653,11 @@ skip_last_mv:
     }
 }
 
-static int is_intra_more_likely(MpegEncContext *s)
+static int is_intra_more_likely(ERContext *s)
 {
     int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
 
-    if (!s->last_picture_ptr || !s->last_picture_ptr->f.data[0])
+    if (!s->last_pic || !s->last_pic->f.data[0])
         return 1; // no previous frame available -> use spatial prediction
 
     undamaged_count = 0;
@@ -727,21 +668,21 @@ static int is_intra_more_likely(MpegEncContext *s)
             undamaged_count++;
     }
 
-    if (s->codec_id == AV_CODEC_ID_H264) {
-        H264Context *h = (void*) s;
-        if (h->list_count <= 0 || h->ref_count[0] <= 0 ||
-            !h->ref_list[0][0].f.data[0])
-            return 1;
-    }
+    if (s->avctx->codec_id == AV_CODEC_ID_H264 && s->ref_count <= 0)
+        return 1;
 
     if (undamaged_count < 5)
         return 0; // almost all MBs damaged -> use temporal prediction
 
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
     // prevent dsp.sad() check, that requires access to the image
     if (CONFIG_MPEG_XVMC_DECODER    &&
         s->avctx->xvmc_acceleration &&
-        s->pict_type == AV_PICTURE_TYPE_I)
+        s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I)
         return 1;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
 
     skip_amount     = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
     is_intra_likely = 0;
@@ -761,25 +702,25 @@ static int is_intra_more_likely(MpegEncContext *s)
             if ((j % skip_amount) != 0)
                 continue;
 
-            if (s->pict_type == AV_PICTURE_TYPE_I) {
-                uint8_t *mb_ptr      = s->current_picture.f.data[0] +
-                                       mb_x * 16 + mb_y * 16 * s->linesize;
-                uint8_t *last_mb_ptr = s->last_picture.f.data[0] +
-                                       mb_x * 16 + mb_y * 16 * s->linesize;
+            if (s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I) {
+                int *linesize = s->cur_pic->f.linesize;
+                uint8_t *mb_ptr      = s->cur_pic->f.data[0] +
+                                       mb_x * 16 + mb_y * 16 * linesize[0];
+                uint8_t *last_mb_ptr = s->last_pic->f.data[0] +
+                                       mb_x * 16 + mb_y * 16 * linesize[0];
 
                 if (s->avctx->codec_id == AV_CODEC_ID_H264) {
                     // FIXME
                 } else {
-                    ff_thread_await_progress(&s->last_picture_ptr->f,
-                                             mb_y, 0);
+                    ff_thread_await_progress(&s->last_pic->tf, 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,
+                                                 linesize[0], 16);
+                is_intra_likely -= s->dsp->sad[0](NULL, last_mb_ptr,
+                                                 last_mb_ptr + linesize[0] * 16,
+                                                 linesize[0], 16);
             } else {
-                if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
+                if (IS_INTRA(s->cur_pic->mb_type[mb_xy]))
                    is_intra_likely++;
                 else
                    is_intra_likely--;
@@ -789,9 +730,9 @@ static int is_intra_more_likely(MpegEncContext *s)
     return is_intra_likely > 0;
 }
 
-void ff_er_frame_start(MpegEncContext *s)
+void ff_er_frame_start(ERContext *s)
 {
-    if (!s->err_recognition)
+    if (!s->avctx->error_concealment)
         return;
 
     memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
@@ -807,7 +748,7 @@ void ff_er_frame_start(MpegEncContext *s)
  * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is
  *               assumed that no earlier end or error of the same type occurred
  */
-void ff_er_add_slice(MpegEncContext *s, int startx, int starty,
+void ff_er_add_slice(ERContext *s, int startx, int starty,
                      int endx, int endy, int status)
 {
     const int start_i  = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
@@ -825,7 +766,7 @@ void ff_er_add_slice(MpegEncContext *s, int startx, int starty,
         return;
     }
 
-    if (!s->err_recognition)
+    if (!s->avctx->error_concealment)
         return;
 
     mask &= ~VP_START;
@@ -875,37 +816,46 @@ void ff_er_add_slice(MpegEncContext *s, int startx, int starty,
     }
 }
 
-void ff_er_frame_end(MpegEncContext *s)
+void ff_er_frame_end(ERContext *s)
 {
+    int *linesize = s->cur_pic->f.linesize;
     int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
     int distance;
     int threshold_part[4] = { 100, 100, 100 };
     int threshold = 50;
     int is_intra_likely;
     int size = s->b8_stride * 2 * s->mb_height;
-    Picture *pic = s->current_picture_ptr;
 
     /* We do not support ER of field pictures yet,
      * though it should not crash if enabled. */
-    if (!s->err_recognition || s->error_count == 0                     ||
+    if (!s->avctx->error_concealment || s->error_count == 0            ||
         s->avctx->hwaccel                                              ||
-        s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU          ||
-        s->picture_structure != PICT_FRAME                             ||
+        !s->cur_pic || s->cur_pic->field_picture                               ||
         s->error_count == 3 * s->mb_width *
                           (s->avctx->skip_top + s->avctx->skip_bottom)) {
         return;
     };
 
-    if (s->current_picture.f.motion_val[0] == NULL) {
+    if (s->cur_pic->motion_val[0] == NULL) {
         av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
 
         for (i = 0; i < 2; i++) {
-            pic->f.ref_index[i]     = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
-            pic->motion_val_base[i] = av_mallocz((size + 4) * 2 * sizeof(uint16_t));
-            pic->f.motion_val[i]    = pic->motion_val_base[i] + 4;
+            s->cur_pic->ref_index_buf[i]  = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
+            s->cur_pic->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t));
+            if (!s->cur_pic->ref_index_buf[i] || !s->cur_pic->motion_val_buf[i])
+                break;
+            s->cur_pic->ref_index[i]  = s->cur_pic->ref_index_buf[i]->data;
+            s->cur_pic->motion_val[i] = (int16_t (*)[2])s->cur_pic->motion_val_buf[i]->data + 4;
+        }
+        if (i < 2) {
+            for (i = 0; i < 2; i++) {
+                av_buffer_unref(&s->cur_pic->ref_index_buf[i]);
+                av_buffer_unref(&s->cur_pic->motion_val_buf[i]);
+                s->cur_pic->ref_index[i]  = NULL;
+                s->cur_pic->motion_val[i] = NULL;
+            }
+            return;
         }
-        pic->f.motion_subsample_log2 = 3;
-        s->current_picture = *s->current_picture_ptr;
     }
 
     if (s->avctx->debug & FF_DEBUG_ER) {
@@ -964,7 +914,7 @@ void ff_er_frame_end(MpegEncContext *s)
     }
 
     /* handle missing slices */
-    if (s->err_recognition & AV_EF_EXPLODE) {
+    if (s->avctx->err_recognition & AV_EF_EXPLODE) {
         int end_ok = 1;
 
         // FIXME + 100 hack
@@ -1063,30 +1013,28 @@ void ff_er_frame_end(MpegEncContext *s)
             continue;
 
         if (is_intra_likely)
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
+            s->cur_pic->mb_type[mb_xy] = MB_TYPE_INTRA4x4;
         else
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+            s->cur_pic->mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
     }
 
     // change inter to intra blocks if no reference frames are available
-    if (!s->last_picture.f.data[0] && !s->next_picture.f.data[0])
+    if (!(s->last_pic && s->last_pic->f.data[0]) &&
+        !(s->next_pic && s->next_pic->f.data[0]))
         for (i = 0; i < s->mb_num; i++) {
             const int mb_xy = s->mb_index2xy[i];
-            if (!IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
-                s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
+            if (!IS_INTRA(s->cur_pic->mb_type[mb_xy]))
+                s->cur_pic->mb_type[mb_xy] = MB_TYPE_INTRA4x4;
         }
 
     /* 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);
+            const int mb_type = s->cur_pic->mb_type[mb_xy];
+            const int dir     = !(s->last_pic && s->last_pic->f.data[0]);
+            const int mv_dir  = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
+            int mv_type;
 
             error = s->error_status_table[mb_xy];
 
@@ -1097,43 +1045,33 @@ void ff_er_frame_end(MpegEncContext *s)
             if (!(error & ER_AC_ERROR))
                 continue; // undamaged inter
 
-            s->mv_dir     = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
-            s->mb_intra   = 0;
-            s->mb_skipped = 0;
             if (IS_8X8(mb_type)) {
                 int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
                 int j;
-                s->mv_type = MV_TYPE_8X8;
+                mv_type = MV_TYPE_8X8;
                 for (j = 0; j < 4; j++) {
-                    s->mv[0][j][0] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
-                    s->mv[0][j][1] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
+                    s->mv[0][j][0] = s->cur_pic->motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
+                    s->mv[0][j][1] = s->cur_pic->motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
                 }
             } else {
-                s->mv_type     = MV_TYPE_16X16;
-                s->mv[0][0][0] = s->current_picture.f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
-                s->mv[0][0][1] = s->current_picture.f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
+                mv_type     = MV_TYPE_16X16;
+                s->mv[0][0][0] = s->cur_pic->motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
+                s->mv[0][0][1] = s->cur_pic->motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
             }
 
-            s->dsp.clear_blocks(s->block[0]);
-
-            s->mb_x = mb_x;
-            s->mb_y = mb_y;
-            decode_mb(s, 0 /* FIXME h264 partitioned slices need this set */);
+            s->decode_mb(s->opaque, 0 /* FIXME h264 partitioned slices need this set */,
+                         mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);
         }
     }
 
     /* guess MVs */
-    if (s->pict_type == AV_PICTURE_TYPE_B) {
+    if (s->cur_pic->f.pict_type == AV_PICTURE_TYPE_B) {
         for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-            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);
+                const int mb_type = s->cur_pic->mb_type[mb_xy];
+                int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
 
                 error = s->error_status_table[mb_xy];
 
@@ -1144,28 +1082,21 @@ void ff_er_frame_end(MpegEncContext *s)
                 if (!(error & ER_AC_ERROR))
                     continue; // undamaged inter
 
-                s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
-                if (!s->last_picture.f.data[0])
-                    s->mv_dir &= ~MV_DIR_FORWARD;
-                if (!s->next_picture.f.data[0])
-                    s->mv_dir &= ~MV_DIR_BACKWARD;
-                s->mb_intra   = 0;
-                s->mv_type    = MV_TYPE_16X16;
-                s->mb_skipped = 0;
+                if (!(s->last_pic && s->last_pic->f.data[0]))
+                    mv_dir &= ~MV_DIR_FORWARD;
+                if (!(s->next_pic && s->next_pic->f.data[0]))
+                    mv_dir &= ~MV_DIR_BACKWARD;
 
                 if (s->pp_time) {
                     int time_pp = s->pp_time;
                     int time_pb = s->pb_time;
 
-                    if (s->avctx->codec_id == AV_CODEC_ID_H264) {
-                        // FIXME
-                    } else {
-                        ff_thread_await_progress(&s->next_picture_ptr->f, mb_y, 0);
-                    }
-                    s->mv[0][0][0] = s->next_picture.f.motion_val[0][xy][0] *  time_pb            / time_pp;
-                    s->mv[0][0][1] = s->next_picture.f.motion_val[0][xy][1] *  time_pb            / time_pp;
-                    s->mv[1][0][0] = s->next_picture.f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
-                    s->mv[1][0][1] = s->next_picture.f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
+                    ff_thread_await_progress(&s->next_pic->tf, mb_y, 0);
+
+                    s->mv[0][0][0] = s->next_pic->motion_val[0][xy][0] *  time_pb            / time_pp;
+                    s->mv[0][0][1] = s->next_pic->motion_val[0][xy][1] *  time_pb            / time_pp;
+                    s->mv[1][0][0] = s->next_pic->motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
+                    s->mv[1][0][1] = s->next_pic->motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
                 } else {
                     s->mv[0][0][0] = 0;
                     s->mv[0][0][1] = 0;
@@ -1173,18 +1104,20 @@ void ff_er_frame_end(MpegEncContext *s)
                     s->mv[1][0][1] = 0;
                 }
 
-                s->dsp.clear_blocks(s->block[0]);
-                s->mb_x = mb_x;
-                s->mb_y = mb_y;
-                decode_mb(s, 0);
+                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,
+                             mb_x, mb_y, 0, 0);
             }
         }
     } else
         guess_mv(s);
 
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
     /* the filters below are not XvMC compatible, skip them */
     if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
         goto ec_clean;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
     /* fill DC for inter blocks */
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
@@ -1192,7 +1125,7 @@ void ff_er_frame_end(MpegEncContext *s)
             int16_t *dc_ptr;
             uint8_t *dest_y, *dest_cb, *dest_cr;
             const int mb_xy   = mb_x + mb_y * s->mb_stride;
-            const int mb_type = s->current_picture.f.mb_type[mb_xy];
+            const int mb_type = s->cur_pic->mb_type[mb_xy];
 
             error = s->error_status_table[mb_xy];
 
@@ -1201,9 +1134,9 @@ void ff_er_frame_end(MpegEncContext *s)
             // if (error & ER_MV_ERROR)
             //     continue; // inter data damaged FIXME is this good?
 
-            dest_y  = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
-            dest_cb = s->current_picture.f.data[1] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
-            dest_cr = s->current_picture.f.data[2] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
+            dest_y  = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
+            dest_cb = s->cur_pic->f.data[1] + mb_x *  8 + mb_y *  8 * linesize[1];
+            dest_cr = s->cur_pic->f.data[2] + mb_x *  8 + mb_y *  8 * linesize[2];
 
             dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
             for (n = 0; n < 4; n++) {
@@ -1212,7 +1145,7 @@ void ff_er_frame_end(MpegEncContext *s)
                     int x;
                     for (x = 0; x < 8; x++)
                        dc += dest_y[x + (n & 1) * 8 +
-                             (y + (n >> 1) * 8) * s->linesize];
+                             (y + (n >> 1) * 8) * linesize[0]];
                 }
                 dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
             }
@@ -1221,8 +1154,8 @@ void ff_er_frame_end(MpegEncContext *s)
             for (y = 0; y < 8; y++) {
                 int x;
                 for (x = 0; x < 8; x++) {
-                    dcu += dest_cb[x + y * s->uvlinesize];
-                    dcv += dest_cr[x + y * s->uvlinesize];
+                    dcu += dest_cb[x + y * linesize[1]];
+                    dcv += dest_cr[x + y * linesize[2]];
                 }
             }
             s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
@@ -1243,7 +1176,7 @@ void ff_er_frame_end(MpegEncContext *s)
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
             uint8_t *dest_y, *dest_cb, *dest_cr;
             const int mb_xy   = mb_x + mb_y * s->mb_stride;
-            const int mb_type = s->current_picture.f.mb_type[mb_xy];
+            const int mb_type = s->cur_pic->mb_type[mb_xy];
 
             error = s->error_status_table[mb_xy];
 
@@ -1252,9 +1185,9 @@ void ff_er_frame_end(MpegEncContext *s)
             if (!(error & ER_AC_ERROR))
                 continue; // undamaged
 
-            dest_y  = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
-            dest_cb = s->current_picture.f.data[1] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
-            dest_cr = s->current_picture.f.data[2] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
+            dest_y  = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0];
+            dest_cb = s->cur_pic->f.data[1] + mb_x *  8 + mb_y *  8 * linesize[1];
+            dest_cr = s->cur_pic->f.data[2] + mb_x *  8 + mb_y *  8 * linesize[2];
 
             put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
         }
@@ -1262,20 +1195,20 @@ void ff_er_frame_end(MpegEncContext *s)
 
     if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
         /* filter horizontal block boundaries */
-        h_block_filter(s, s->current_picture.f.data[0], s->mb_width * 2,
-                       s->mb_height * 2, s->linesize, 1);
-        h_block_filter(s, s->current_picture.f.data[1], s->mb_width,
-                       s->mb_height  , s->uvlinesize, 0);
-        h_block_filter(s, s->current_picture.f.data[2], s->mb_width,
-                       s->mb_height  , s->uvlinesize, 0);
+        h_block_filter(s, s->cur_pic->f.data[0], s->mb_width * 2,
+                       s->mb_height * 2, linesize[0], 1);
+        h_block_filter(s, s->cur_pic->f.data[1], s->mb_width,
+                       s->mb_height, linesize[1], 0);
+        h_block_filter(s, s->cur_pic->f.data[2], s->mb_width,
+                       s->mb_height, linesize[2], 0);
 
         /* filter vertical block boundaries */
-        v_block_filter(s, s->current_picture.f.data[0], s->mb_width * 2,
-                       s->mb_height * 2, s->linesize, 1);
-        v_block_filter(s, s->current_picture.f.data[1], s->mb_width,
-                       s->mb_height  , s->uvlinesize, 0);
-        v_block_filter(s, s->current_picture.f.data[2], s->mb_width,
-                       s->mb_height  , s->uvlinesize, 0);
+        v_block_filter(s, s->cur_pic->f.data[0], s->mb_width * 2,
+                       s->mb_height * 2, linesize[0], 1);
+        v_block_filter(s, s->cur_pic->f.data[1], s->mb_width,
+                       s->mb_height, linesize[1], 0);
+        v_block_filter(s, s->cur_pic->f.data[2], s->mb_width,
+                       s->mb_height, linesize[2], 0);
     }
 
 ec_clean:
@@ -1284,10 +1217,13 @@ ec_clean:
         const int mb_xy = s->mb_index2xy[i];
         int       error = s->error_status_table[mb_xy];
 
-        if (s->pict_type != AV_PICTURE_TYPE_B &&
+        if (s->cur_pic->f.pict_type != AV_PICTURE_TYPE_B &&
             (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {
             s->mbskip_table[mb_xy] = 0;
         }
         s->mbintra_table[mb_xy] = 1;
     }
+    s->cur_pic = NULL;
+    s->next_pic    = NULL;
+    s->last_pic    = NULL;
 }
diff --git a/libavcodec/error_resilience.h b/libavcodec/error_resilience.h
new file mode 100644
index 0000000..f979656
--- /dev/null
+++ b/libavcodec/error_resilience.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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_ERROR_RESILIENCE_H
+#define AVCODEC_ERROR_RESILIENCE_H
+
+#include <stdint.h>
+
+#include "avcodec.h"
+#include "dsputil.h"
+
+///< current MB is the first after a resync marker
+#define VP_START               1
+#define ER_AC_ERROR            2
+#define ER_DC_ERROR            4
+#define ER_MV_ERROR            8
+#define ER_AC_END              16
+#define ER_DC_END              32
+#define ER_MV_END              64
+
+#define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR)
+#define ER_MB_END   (ER_AC_END|ER_DC_END|ER_MV_END)
+
+typedef struct ERContext {
+    AVCodecContext *avctx;
+    DSPContext *dsp;
+
+    int *mb_index2xy;
+    int mb_num;
+    int mb_width, mb_height;
+    int mb_stride;
+    int b8_stride;
+
+    int error_count, error_occurred;
+    uint8_t *error_status_table;
+    uint8_t *er_temp_buffer;
+    int16_t *dc_val[3];
+    uint8_t *mbskip_table;
+    uint8_t *mbintra_table;
+    int mv[2][4][2];
+
+    struct Picture *cur_pic;
+    struct Picture *last_pic;
+    struct Picture *next_pic;
+
+    uint16_t pp_time;
+    uint16_t pb_time;
+    int quarter_sample;
+    int partitioned_frame;
+    int ref_count;
+
+    void (*decode_mb)(void *opaque, int ref, int mv_dir, int mv_type,
+                      int (*mv)[2][4][2],
+                      int mb_x, int mb_y, int mb_intra, int mb_skipped);
+    void *opaque;
+} ERContext;
+
+void ff_er_frame_start(ERContext *s);
+void ff_er_frame_end(ERContext *s);
+void ff_er_add_slice(ERContext *s, int startx, int starty, int endx, int endy,
+                     int status);
+
+#endif /* AVCODEC_ERROR_RESILIENCE_H */
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index a27ab68..30f22e0 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -42,7 +42,7 @@ typedef struct CodeBook {
 } CodeBook;
 
 typedef struct Escape124Context {
-    AVFrame frame;
+    AVFrame *frame;
 
     unsigned num_superblocks;
 
@@ -67,6 +67,10 @@ static av_cold int escape124_decode_init(AVCodecContext *avctx)
     s->num_superblocks = ((unsigned)avctx->width / 8) *
                          ((unsigned)avctx->height / 8);
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
@@ -78,8 +82,7 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx)
     for (i = 0; i < 3; i++)
         av_free(s->codebooks[i].blocks);
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
@@ -203,6 +206,7 @@ static int escape124_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     Escape124Context *s = avctx->priv_data;
+    AVFrame *frame = data;
 
     GetBitContext gb;
     unsigned frame_flags, frame_size;
@@ -214,8 +218,7 @@ static int escape124_decode_frame(AVCodecContext *avctx,
 
     uint16_t* old_frame_data, *new_frame_data;
     unsigned old_stride, new_stride;
-
-    AVFrame new_frame = { { 0 } };
+    int ret;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -230,10 +233,14 @@ static int escape124_decode_frame(AVCodecContext *avctx,
     // Leave last frame unchanged
     // FIXME: Is this necessary?  I haven't seen it in any real samples
     if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) {
+        if (!s->frame->data[0])
+            return AVERROR_INVALIDDATA;
+
         av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n");
 
         *got_frame = 1;
-        *(AVFrame*)data = s->frame;
+        if ((ret = av_frame_ref(frame, s->frame)) < 0)
+            return ret;
 
         return frame_size;
     }
@@ -266,16 +273,15 @@ static int escape124_decode_frame(AVCodecContext *avctx,
         }
     }
 
-    new_frame.reference = 3;
-    if (ff_get_buffer(avctx, &new_frame)) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    new_frame_data = (uint16_t*)new_frame.data[0];
-    new_stride = new_frame.linesize[0] / 2;
-    old_frame_data = (uint16_t*)s->frame.data[0];
-    old_stride = s->frame.linesize[0] / 2;
+    new_frame_data = (uint16_t*)frame->data[0];
+    new_stride = frame->linesize[0] / 2;
+    old_frame_data = (uint16_t*)s->frame->data[0];
+    old_stride = s->frame->linesize[0] / 2;
 
     for (superblock_index = 0; superblock_index < s->num_superblocks;
          superblock_index++) {
@@ -354,10 +360,10 @@ static int escape124_decode_frame(AVCodecContext *avctx,
            "Escape sizes: %i, %i, %i\n",
            frame_size, buf_size, get_bits_count(&gb) / 8);
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(s->frame);
+    if ((ret = av_frame_ref(s->frame, frame)) < 0)
+        return ret;
 
-    *(AVFrame*)data = s->frame = new_frame;
     *got_frame = 1;
 
     return frame_size;
@@ -366,6 +372,7 @@ static int escape124_decode_frame(AVCodecContext *avctx,
 
 AVCodec ff_escape124_decoder = {
     .name           = "escape124",
+    .long_name      = NULL_IF_CONFIG_SMALL("Escape 124"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ESCAPE124,
     .priv_data_size = sizeof(Escape124Context),
@@ -373,5 +380,4 @@ AVCodec ff_escape124_decoder = {
     .close          = escape124_decode_close,
     .decode         = escape124_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Escape 124"),
 };
diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c
new file mode 100644
index 0000000..bc865a3
--- /dev/null
+++ b/libavcodec/escape130.c
@@ -0,0 +1,356 @@
+/*
+ * Escape 130 video decoder
+ * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/mem.h"
+#include "avcodec.h"
+#define BITSTREAM_READER_LE
+#include "get_bits.h"
+#include "internal.h"
+
+typedef struct Escape130Context {
+    uint8_t *old_y_avg;
+
+    uint8_t *new_y, *old_y;
+    uint8_t *new_u, *old_u;
+    uint8_t *new_v, *old_v;
+
+    uint8_t *buf1, *buf2;
+    int     linesize[3];
+} Escape130Context;
+
+static const uint8_t offset_table[] = { 2, 4, 10, 20 };
+static const int8_t sign_table[64][4] = {
+    {  0,  0,  0,  0 },
+    { -1,  1,  0,  0 },
+    {  1, -1,  0,  0 },
+    { -1,  0,  1,  0 },
+    { -1,  1,  1,  0 },
+    {  0, -1,  1,  0 },
+    {  1, -1,  1,  0 },
+    { -1, -1,  1,  0 },
+    {  1,  0, -1,  0 },
+    {  0,  1, -1,  0 },
+    {  1,  1, -1,  0 },
+    { -1,  1, -1,  0 },
+    {  1, -1, -1,  0 },
+    { -1,  0,  0,  1 },
+    { -1,  1,  0,  1 },
+    {  0, -1,  0,  1 },
+
+    {  0,  0,  0,  0 },
+    {  1, -1,  0,  1 },
+    { -1, -1,  0,  1 },
+    { -1,  0,  1,  1 },
+    { -1,  1,  1,  1 },
+    {  0, -1,  1,  1 },
+    {  1, -1,  1,  1 },
+    { -1, -1,  1,  1 },
+    {  0,  0, -1,  1 },
+    {  1,  0, -1,  1 },
+    { -1,  0, -1,  1 },
+    {  0,  1, -1,  1 },
+    {  1,  1, -1,  1 },
+    { -1,  1, -1,  1 },
+    {  0, -1, -1,  1 },
+    {  1, -1, -1,  1 },
+
+    {  0,  0,  0,  0 },
+    { -1, -1, -1,  1 },
+    {  1,  0,  0, -1 },
+    {  0,  1,  0, -1 },
+    {  1,  1,  0, -1 },
+    { -1,  1,  0, -1 },
+    {  1, -1,  0, -1 },
+    {  0,  0,  1, -1 },
+    {  1,  0,  1, -1 },
+    { -1,  0,  1, -1 },
+    {  0,  1,  1, -1 },
+    {  1,  1,  1, -1 },
+    { -1,  1,  1, -1 },
+    {  0, -1,  1, -1 },
+    {  1, -1,  1, -1 },
+    { -1, -1,  1, -1 },
+
+    {  0,  0,  0,  0 },
+    {  1,  0, -1, -1 },
+    {  0,  1, -1, -1 },
+    {  1,  1, -1, -1 },
+    { -1,  1, -1, -1 },
+    {  1, -1, -1, -1 }
+};
+
+static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 };
+
+static const int8_t chroma_adjust[2][8] = {
+    { 1, 1, 0, -1, -1, -1,  0,  1 },
+    { 0, 1, 1,  1,  0, -1, -1, -1 }
+};
+
+const uint8_t chroma_vals[] = {
+     20,  28,  36,  44,  52,  60,  68,  76,
+     84,  92, 100, 106, 112, 116, 120, 124,
+    128, 132, 136, 140, 144, 150, 156, 164,
+    172, 180, 188, 196, 204, 212, 220, 228
+};
+
+static av_cold int escape130_decode_init(AVCodecContext *avctx)
+{
+    Escape130Context *s = avctx->priv_data;
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    if ((avctx->width & 1) || (avctx->height & 1)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Dimensions should be a multiple of two.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    s->old_y_avg = av_malloc(avctx->width * avctx->height / 4);
+    s->buf1      = av_malloc(avctx->width * avctx->height * 3 / 2);
+    s->buf2      = av_malloc(avctx->width * avctx->height * 3 / 2);
+    if (!s->old_y_avg || !s->buf1 || !s->buf2) {
+        av_freep(&s->old_y_avg);
+        av_freep(&s->buf1);
+        av_freep(&s->buf2);
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    s->linesize[0] = avctx->width;
+    s->linesize[1] =
+    s->linesize[2] = avctx->width / 2;
+
+    s->new_y = s->buf1;
+    s->new_u = s->new_y + avctx->width * avctx->height;
+    s->new_v = s->new_u + avctx->width * avctx->height / 4;
+    s->old_y = s->buf2;
+    s->old_u = s->old_y + avctx->width * avctx->height;
+    s->old_v = s->old_u + avctx->width * avctx->height / 4;
+    memset(s->old_y, 0,    avctx->width * avctx->height);
+    memset(s->old_u, 0x10, avctx->width * avctx->height / 4);
+    memset(s->old_v, 0x10, avctx->width * avctx->height / 4);
+
+    return 0;
+}
+
+static av_cold int escape130_decode_close(AVCodecContext *avctx)
+{
+    Escape130Context *s = avctx->priv_data;
+
+    av_freep(&s->old_y_avg);
+    av_freep(&s->buf1);
+    av_freep(&s->buf2);
+
+    return 0;
+}
+
+static int decode_skip_count(GetBitContext* gb)
+{
+    int value;
+
+    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;
+}
+
+static int escape130_decode_frame(AVCodecContext *avctx, void *data,
+                                  int *got_frame, AVPacket *avpkt)
+{
+    const uint8_t *buf  = avpkt->data;
+    int buf_size        = avpkt->size;
+    Escape130Context *s = avctx->priv_data;
+    AVFrame *pic        = data;
+    GetBitContext gb;
+    int ret;
+
+    uint8_t *old_y, *old_cb, *old_cr,
+            *new_y, *new_cb, *new_cr;
+    uint8_t *dstY, *dstU, *dstV;
+    unsigned old_y_stride, old_cb_stride, old_cr_stride,
+             new_y_stride, new_cb_stride, new_cr_stride;
+    unsigned total_blocks = avctx->width * avctx->height / 4,
+             block_index, block_x = 0;
+    unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10;
+    int skip = -1, y_avg = 0, i, j;
+    uint8_t *ya = s->old_y_avg;
+
+    // first 16 bytes are header; no useful information in here
+    if (buf_size <= 16) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+        return ret;
+
+    init_get_bits(&gb, buf + 16, (buf_size - 16) * 8);
+
+    new_y  = s->new_y;
+    new_cb = s->new_u;
+    new_cr = s->new_v;
+    new_y_stride  = s->linesize[0];
+    new_cb_stride = s->linesize[1];
+    new_cr_stride = s->linesize[2];
+    old_y  = s->old_y;
+    old_cb = s->old_u;
+    old_cr = s->old_v;
+    old_y_stride  = s->linesize[0];
+    old_cb_stride = s->linesize[1];
+    old_cr_stride = s->linesize[2];
+
+    for (block_index = 0; block_index < total_blocks; block_index++) {
+        // Note that this call will make us skip the rest of the blocks
+        // if the frame ends prematurely.
+        if (skip == -1)
+            skip = decode_skip_count(&gb);
+        if (skip == -1) {
+            av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (skip) {
+            y[0] = old_y[0];
+            y[1] = old_y[1];
+            y[2] = old_y[old_y_stride];
+            y[3] = old_y[old_y_stride + 1];
+            y_avg = ya[0];
+            cb = old_cb[0];
+            cr = old_cr[0];
+        } else {
+            if (get_bits1(&gb)) {
+                unsigned sign_selector       = get_bits(&gb, 6);
+                unsigned difference_selector = get_bits(&gb, 2);
+                y_avg = 2 * get_bits(&gb, 5);
+                for (i = 0; i < 4; i++) {
+                    y[i] = av_clip(y_avg + offset_table[difference_selector] *
+                                   sign_table[sign_selector][i], 0, 63);
+                }
+            } else if (get_bits1(&gb)) {
+                if (get_bits1(&gb)) {
+                    y_avg = get_bits(&gb, 6);
+                } else {
+                    unsigned adjust_index = get_bits(&gb, 3);
+                    y_avg = (y_avg + luma_adjust[adjust_index]) & 63;
+                }
+                for (i = 0; i < 4; i++)
+                    y[i] = y_avg;
+            }
+
+            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);
+                    cb = (cb + chroma_adjust[0][adjust_index]) & 31;
+                    cr = (cr + chroma_adjust[1][adjust_index]) & 31;
+                }
+            }
+        }
+        *ya++ = y_avg;
+
+        new_y[0]                = y[0];
+        new_y[1]                = y[1];
+        new_y[new_y_stride]     = y[2];
+        new_y[new_y_stride + 1] = y[3];
+        *new_cb = cb;
+        *new_cr = cr;
+
+        old_y += 2;
+        old_cb++;
+        old_cr++;
+        new_y += 2;
+        new_cb++;
+        new_cr++;
+        block_x++;
+        if (block_x * 2 == avctx->width) {
+            block_x = 0;
+            old_y  += old_y_stride * 2  - avctx->width;
+            old_cb += old_cb_stride     - avctx->width / 2;
+            old_cr += old_cr_stride     - avctx->width / 2;
+            new_y  += new_y_stride * 2  - avctx->width;
+            new_cb += new_cb_stride     - avctx->width / 2;
+            new_cr += new_cr_stride     - avctx->width / 2;
+        }
+
+        skip--;
+    }
+
+    new_y  = s->new_y;
+    new_cb = s->new_u;
+    new_cr = s->new_v;
+    dstY   = pic->data[0];
+    dstU   = pic->data[1];
+    dstV   = pic->data[2];
+    for (j = 0; j < avctx->height; j++) {
+        for (i = 0; i < avctx->width; i++)
+            dstY[i] = new_y[i] << 2;
+        dstY  += pic->linesize[0];
+        new_y += new_y_stride;
+    }
+    for (j = 0; j < avctx->height / 2; j++) {
+        for (i = 0; i < avctx->width / 2; i++) {
+            dstU[i] = chroma_vals[new_cb[i]];
+            dstV[i] = chroma_vals[new_cr[i]];
+        }
+        dstU   += pic->linesize[1];
+        dstV   += pic->linesize[2];
+        new_cb += new_cb_stride;
+        new_cr += new_cr_stride;
+    }
+
+    av_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n",
+            buf_size, get_bits_count(&gb) >> 3);
+
+    FFSWAP(uint8_t*, s->old_y, s->new_y);
+    FFSWAP(uint8_t*, s->old_u, s->new_u);
+    FFSWAP(uint8_t*, s->old_v, s->new_v);
+
+    *got_frame = 1;
+
+    return buf_size;
+}
+
+AVCodec ff_escape130_decoder = {
+    .name           = "escape130",
+    .long_name      = NULL_IF_CONFIG_SMALL("Escape 130"),
+    .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,
+};
diff --git a/libavcodec/faandct.c b/libavcodec/faandct.c
index 1379394..b1d7a14 100644
--- a/libavcodec/faandct.c
+++ b/libavcodec/faandct.c
@@ -25,7 +25,6 @@
  * @author Michael Niedermayer <michaelni at gmx.at>
  */
 
-#include "dsputil.h"
 #include "faandct.h"
 #include "libavutil/internal.h"
 #include "libavutil/libm.h"
@@ -64,7 +63,7 @@ B6*B0, B6*B1, B6*B2, B6*B3, B6*B4, B6*B5, B6*B6, B6*B7,
 B7*B0, B7*B1, B7*B2, B7*B3, B7*B4, B7*B5, B7*B6, B7*B7,
 };
 
-static av_always_inline void row_fdct(FLOAT temp[64], DCTELEM * data)
+static av_always_inline void row_fdct(FLOAT temp[64], int16_t *data)
 {
     FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     FLOAT tmp10, tmp11, tmp12, tmp13;
@@ -119,7 +118,7 @@ static av_always_inline void row_fdct(FLOAT temp[64], DCTELEM * data)
     }
 }
 
-void ff_faandct(DCTELEM * data)
+void ff_faandct(int16_t *data)
 {
     FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     FLOAT tmp10, tmp11, tmp12, tmp13;
@@ -179,7 +178,7 @@ void ff_faandct(DCTELEM * data)
     }
 }
 
-void ff_faandct248(DCTELEM * data)
+void ff_faandct248(int16_t *data)
 {
     FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
     FLOAT tmp10, tmp11, tmp12, tmp13;
diff --git a/libavcodec/faandct.h b/libavcodec/faandct.h
index cd98236..59d5ff3 100644
--- a/libavcodec/faandct.h
+++ b/libavcodec/faandct.h
@@ -29,9 +29,9 @@
 #ifndef AVCODEC_FAANDCT_H
 #define AVCODEC_FAANDCT_H
 
-#include "dsputil.h"
+#include <stdint.h>
 
-void ff_faandct(DCTELEM * data);
-void ff_faandct248(DCTELEM * data);
+void ff_faandct(int16_t *data);
+void ff_faandct248(int16_t *data);
 
 #endif /* AVCODEC_FAANDCT_H */
diff --git a/libavcodec/faanidct.c b/libavcodec/faanidct.c
index cd8ca27..5cacfdd 100644
--- a/libavcodec/faanidct.c
+++ b/libavcodec/faanidct.c
@@ -47,7 +47,7 @@ B6*B0/8, B6*B1/8, B6*B2/8, B6*B3/8, B6*B4/8, B6*B5/8, B6*B6/8, B6*B7/8,
 B7*B0/8, B7*B1/8, B7*B2/8, B7*B3/8, B7*B4/8, B7*B5/8, B7*B6/8, B7*B7/8,
 };
 
-static inline void p8idct(DCTELEM data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){
+static inline void p8idct(int16_t data[64], FLOAT temp[64], uint8_t *dest, int stride, int x, int y, int type){
     int i;
     FLOAT av_unused tmp0;
     FLOAT s04, d04, s17, d17, s26, d26, s53, d53;
@@ -129,7 +129,7 @@ static inline void p8idct(DCTELEM data[64], FLOAT temp[64], uint8_t *dest, int s
     }
 }
 
-void ff_faanidct(DCTELEM block[64]){
+void ff_faanidct(int16_t block[64]){
     FLOAT temp[64];
     int i;
 
@@ -142,7 +142,7 @@ void ff_faanidct(DCTELEM block[64]){
     p8idct(block, temp, NULL, 0, 8, 1, 1);
 }
 
-void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]){
+void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]){
     FLOAT temp[64];
     int i;
 
@@ -155,7 +155,7 @@ void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]){
     p8idct(NULL , temp, dest, line_size, 8, 1, 2);
 }
 
-void ff_faanidct_put(uint8_t *dest, int line_size, DCTELEM block[64]){
+void ff_faanidct_put(uint8_t *dest, int line_size, int16_t block[64]){
     FLOAT temp[64];
     int i;
 
diff --git a/libavcodec/faanidct.h b/libavcodec/faanidct.h
index f3896f7..0c01520 100644
--- a/libavcodec/faanidct.h
+++ b/libavcodec/faanidct.h
@@ -23,10 +23,9 @@
 #define AVCODEC_FAANIDCT_H
 
 #include <stdint.h>
-#include "dsputil.h"
 
-void ff_faanidct(DCTELEM block[64]);
-void ff_faanidct_add(uint8_t *dest, int line_size, DCTELEM block[64]);
-void ff_faanidct_put(uint8_t *dest, int line_size, DCTELEM block[64]);
+void ff_faanidct(int16_t block[64]);
+void ff_faanidct_add(uint8_t *dest, int line_size, int16_t block[64]);
+void ff_faanidct_put(uint8_t *dest, int line_size, int16_t block[64]);
 
 #endif /* AVCODEC_FAANIDCT_H */
diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c
index 077e740..4cbda3f 100644
--- a/libavcodec/faxcompr.c
+++ b/libavcodec/faxcompr.c
@@ -103,13 +103,13 @@ av_cold void ff_ccitt_unpack_init(void)
     int i;
     static int initialized = 0;
 
-    if(initialized)
+    if (initialized)
         return;
     ccitt_vlc[0].table = code_table1;
     ccitt_vlc[0].table_allocated = 528;
     ccitt_vlc[1].table = code_table2;
     ccitt_vlc[1].table_allocated = 648;
-    for(i = 0; i < 2; i++){
+    for (i = 0; i < 2; i++) {
         ff_init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS,
                            ccitt_codes_lens[i], 1, 1,
                            ccitt_codes_bits[i], 1, 1,
@@ -124,32 +124,33 @@ av_cold void ff_ccitt_unpack_init(void)
 
 
 static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb,
-                                 unsigned int pix_left, int *runs, const int *runend)
+                                 unsigned int pix_left, int *runs,
+                                 const int *runend)
 {
-    int mode = 0;
-    unsigned int run=0;
+    int mode         = 0;
+    unsigned int run = 0;
     unsigned int t;
-    for(;;){
-        t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
+    for (;;) {
+        t    = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
         run += t;
-        if(t < 64){
+        if (t < 64) {
             *runs++ = run;
-            if(runs >= runend){
+            if (runs >= runend) {
                 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
-            if(pix_left <= run){
-                if(pix_left == run)
+            if (pix_left <= run) {
+                if (pix_left == run)
                     break;
                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             pix_left -= run;
-            run = 0;
-            mode = !mode;
-        }else if((int)t == -1){
+            run       = 0;
+            mode      = !mode;
+        } else if ((int)t == -1) {
             av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
     *runs++ = 0;
@@ -157,78 +158,79 @@ static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb,
 }
 
 static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb,
-                                 unsigned int width, int *runs, const int *runend, const int *ref)
+                                 unsigned int width, int *runs,
+                                 const int *runend, const int *ref)
 {
-    int mode = 0, saved_run = 0, t;
-    int run_off = *ref++;
-    unsigned int offs=0, run= 0;
+    int mode          = 0, saved_run = 0, t;
+    int run_off       = *ref++;
+    unsigned int offs = 0, run = 0;
 
     runend--; // for the last written 0
 
-    while(offs < width){
+    while (offs < width) {
         int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1);
-        if(cmode == -1){
+        if (cmode == -1) {
             av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
-        if(!cmode){//pass mode
+        if (!cmode) { //pass mode
             run_off += *ref++;
-            run = run_off - offs;
-            offs= run_off;
+            run      = run_off - offs;
+            offs     = run_off;
             run_off += *ref++;
-            if(offs > width){
+            if (offs > width) {
                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             saved_run += run;
-        }else if(cmode == 1){//horizontal mode
+        } else if (cmode == 1) { //horizontal mode
             int k;
-            for(k = 0; k < 2; k++){
+            for (k = 0; k < 2; k++) {
                 run = 0;
-                for(;;){
+                for (;;) {
                     t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2);
-                    if(t == -1){
+                    if (t == -1) {
                         av_log(avctx, AV_LOG_ERROR, "Incorrect code\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     run += t;
-                    if(t < 64)
+                    if (t < 64)
                         break;
                 }
                 *runs++ = run + saved_run;
-                if(runs >= runend){
+                if (runs >= runend) {
                     av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 saved_run = 0;
-                offs += run;
-                if(offs > width || run > width){
+                offs     += run;
+                if (offs > width || run > width) {
                     av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 mode = !mode;
             }
-        }else if(cmode == 9 || cmode == 10){
-            av_log(avctx, AV_LOG_ERROR, "Special modes are not supported (yet)\n");
-            return -1;
-        }else{//vertical mode
-            run = run_off - offs + (cmode - 5);
+        } else if (cmode == 9 || cmode == 10) {
+            avpriv_report_missing_feature(avctx, "Special modes support");
+            return AVERROR_PATCHWELCOME;
+        } else { //vertical mode
+            run      = run_off - offs + (cmode - 5);
             run_off -= *--ref;
-            offs += run;
-            if(offs > width || run > width){
+            offs    += run;
+            if (offs > width || run > width) {
                 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             *runs++ = run + saved_run;
-            if(runs >= runend){
+            if (runs >= runend) {
                 av_log(avctx, AV_LOG_ERROR, "Run overrun\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             saved_run = 0;
-            mode = !mode;
+            mode      = !mode;
         }
         //sync line pointers
-        while(run_off <= offs){
+        while (run_off <= offs) {
             run_off += *ref++;
             run_off += *ref++;
         }
@@ -243,14 +245,14 @@ static void put_line(uint8_t *dst, int size, int width, const int *runs)
     PutBitContext pb;
     int run, mode = ~0, pix_left = width, run_idx = 0;
 
-    init_put_bits(&pb, dst, size*8);
-    while(pix_left > 0){
-        run = runs[run_idx++];
-        mode = ~mode;
+    init_put_bits(&pb, dst, size * 8);
+    while (pix_left > 0) {
+        run       = runs[run_idx++];
+        mode      = ~mode;
         pix_left -= run;
-        for(; run > 16; run -= 16)
+        for (; run > 16; run -= 16)
             put_sbits(&pb, 16, mode);
-        if(run)
+        if (run)
             put_sbits(&pb, run, mode);
     }
     flush_put_bits(&pb);
@@ -260,16 +262,15 @@ static int find_group3_syncmarker(GetBitContext *gb, int srcsize)
 {
     unsigned int state = -1;
     srcsize -= get_bits_count(gb);
-    while(srcsize-- > 0){
-        state+= state + get_bits1(gb);
-        if((state & 0xFFF) == 1)
+    while (srcsize-- > 0) {
+        state += state + get_bits1(gb);
+        if ((state & 0xFFF) == 1)
             return 0;
     }
     return -1;
 }
 
-int ff_ccitt_unpack(AVCodecContext *avctx,
-                    const uint8_t *src, int srcsize,
+int ff_ccitt_unpack(AVCodecContext *avctx, const uint8_t *src, int srcsize,
                     uint8_t *dst, int height, int stride,
                     enum TiffCompr compr, int opts)
 {
@@ -277,48 +278,53 @@ int ff_ccitt_unpack(AVCodecContext *avctx,
     GetBitContext gb;
     int *runs, *ref = NULL, *runend;
     int ret;
-    int runsize= avctx->width + 2;
-    int err = 0;
+    int runsize = avctx->width + 2;
 
     runs = av_malloc(runsize * sizeof(runs[0]));
     ref  = av_malloc(runsize * sizeof(ref[0]));
-    if (!runs || ! ref) {
-        err = AVERROR(ENOMEM);
+    if (!runs || !ref) {
+        ret = AVERROR(ENOMEM);
         goto fail;
     }
     ref[0] = avctx->width;
     ref[1] = 0;
     ref[2] = 0;
-    init_get_bits(&gb, src, srcsize*8);
-    for(j = 0; j < height; j++){
+    init_get_bits(&gb, src, srcsize * 8);
+    for (j = 0; j < height; j++) {
         runend = runs + runsize;
-        if(compr == TIFF_G4){
-            ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
-            if(ret < 0){
-                err = -1;
+        if (compr == TIFF_G4) {
+            ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend,
+                                        ref);
+            if (ret < 0)
                 goto fail;
-            }
-        }else{
+        } else {
             int g3d1 = (compr == TIFF_G3) && !(opts & 1);
-            if(compr!=TIFF_CCITT_RLE && find_group3_syncmarker(&gb, srcsize*8) < 0)
+            if (compr != TIFF_CCITT_RLE &&
+                find_group3_syncmarker(&gb, srcsize * 8) < 0)
                 break;
-            if(compr==TIFF_CCITT_RLE || g3d1 || get_bits1(&gb))
-                ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend);
+            if (compr == TIFF_CCITT_RLE || g3d1 || get_bits1(&gb))
+                ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs,
+                                            runend);
             else
-                ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs, runend, ref);
-            if(compr==TIFF_CCITT_RLE)
+                ret = decode_group3_2d_line(avctx, &gb, avctx->width, runs,
+                                            runend, ref);
+            if (compr == TIFF_CCITT_RLE)
                 align_get_bits(&gb);
         }
-        if(ret < 0){
+        if (avctx->err_recognition & AV_EF_EXPLODE && ret < 0)
+            goto fail;
+
+        if (ret < 0) {
             put_line(dst, stride, avctx->width, ref);
-        }else{
+        } else {
             put_line(dst, stride, avctx->width, runs);
-            FFSWAP(int*, runs, ref);
+            FFSWAP(int *, runs, ref);
         }
         dst += stride;
     }
+    ret = 0;
 fail:
     av_free(runs);
     av_free(ref);
-    return err;
+    return ret;
 }
diff --git a/libavcodec/fft-internal.h b/libavcodec/fft-internal.h
index d30571b..c312625 100644
--- a/libavcodec/fft-internal.h
+++ b/libavcodec/fft-internal.h
@@ -36,7 +36,7 @@
 
 #else
 
-#include "libavutil/intmath.h"
+#include "fft.h"
 #include "mathops.h"
 
 void ff_mdct_calcw_c(FFTContext *s, FFTDouble *output, const FFTSample *input);
diff --git a/libavcodec/fft-test.c b/libavcodec/fft-test.c
index 1e46750..7e923d5 100644
--- a/libavcodec/fft-test.c
+++ b/libavcodec/fft-test.c
@@ -37,6 +37,7 @@
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -489,5 +490,8 @@ int main(int argc, char **argv)
     av_free(tab_ref);
     av_free(exptab);
 
-    return err;
+    if (err)
+        printf("Error: %d.\n", err);
+
+    return !!err;
 }
diff --git a/libavcodec/fft.c b/libavcodec/fft.c
deleted file mode 100644
index 0983e80..0000000
--- a/libavcodec/fft.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * FFT/IFFT transforms
- * Copyright (c) 2008 Loren Merritt
- * Copyright (c) 2002 Fabrice Bellard
- * Partly based on libdjbfft by D. J. Bernstein
- *
- * This file is part of Libav.
- *
- * 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
- * FFT/IFFT transforms.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "libavutil/mathematics.h"
-#include "fft.h"
-#include "fft-internal.h"
-
-/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
-#if !CONFIG_HARDCODED_TABLES
-COSTABLE(16);
-COSTABLE(32);
-COSTABLE(64);
-COSTABLE(128);
-COSTABLE(256);
-COSTABLE(512);
-COSTABLE(1024);
-COSTABLE(2048);
-COSTABLE(4096);
-COSTABLE(8192);
-COSTABLE(16384);
-COSTABLE(32768);
-COSTABLE(65536);
-#endif
-COSTABLE_CONST FFTSample * const FFT_NAME(ff_cos_tabs)[] = {
-    NULL, NULL, NULL, NULL,
-    FFT_NAME(ff_cos_16),
-    FFT_NAME(ff_cos_32),
-    FFT_NAME(ff_cos_64),
-    FFT_NAME(ff_cos_128),
-    FFT_NAME(ff_cos_256),
-    FFT_NAME(ff_cos_512),
-    FFT_NAME(ff_cos_1024),
-    FFT_NAME(ff_cos_2048),
-    FFT_NAME(ff_cos_4096),
-    FFT_NAME(ff_cos_8192),
-    FFT_NAME(ff_cos_16384),
-    FFT_NAME(ff_cos_32768),
-    FFT_NAME(ff_cos_65536),
-};
-
-static void ff_fft_permute_c(FFTContext *s, FFTComplex *z);
-static void ff_fft_calc_c(FFTContext *s, FFTComplex *z);
-
-static int split_radix_permutation(int i, int n, int inverse)
-{
-    int m;
-    if(n <= 2) return i&1;
-    m = n >> 1;
-    if(!(i&m))            return split_radix_permutation(i, m, inverse)*2;
-    m >>= 1;
-    if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1;
-    else                  return split_radix_permutation(i, m, inverse)*4 - 1;
-}
-
-av_cold void ff_init_ff_cos_tabs(int index)
-{
-#if !CONFIG_HARDCODED_TABLES
-    int i;
-    int m = 1<<index;
-    double freq = 2*M_PI/m;
-    FFTSample *tab = FFT_NAME(ff_cos_tabs)[index];
-    for(i=0; i<=m/4; i++)
-        tab[i] = FIX15(cos(i*freq));
-    for(i=1; i<m/4; i++)
-        tab[m/2-i] = tab[i];
-#endif
-}
-
-static const int avx_tab[] = {
-    0, 4, 1, 5, 8, 12, 9, 13, 2, 6, 3, 7, 10, 14, 11, 15
-};
-
-static int is_second_half_of_fft32(int i, int n)
-{
-    if (n <= 32)
-        return i >= 16;
-    else if (i < n/2)
-        return is_second_half_of_fft32(i, n/2);
-    else if (i < 3*n/4)
-        return is_second_half_of_fft32(i - n/2, n/4);
-    else
-        return is_second_half_of_fft32(i - 3*n/4, n/4);
-}
-
-static av_cold void fft_perm_avx(FFTContext *s)
-{
-    int i;
-    int n = 1 << s->nbits;
-
-    for (i = 0; i < n; i += 16) {
-        int k;
-        if (is_second_half_of_fft32(i, n)) {
-            for (k = 0; k < 16; k++)
-                s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] =
-                    i + avx_tab[k];
-
-        } else {
-            for (k = 0; k < 16; k++) {
-                int j = i + k;
-                j = (j & ~7) | ((j >> 1) & 3) | ((j << 2) & 4);
-                s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] = j;
-            }
-        }
-    }
-}
-
-av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse)
-{
-    int i, j, n;
-
-    if (nbits < 2 || nbits > 16)
-        goto fail;
-    s->nbits = nbits;
-    n = 1 << nbits;
-
-    s->revtab = av_malloc(n * sizeof(uint16_t));
-    if (!s->revtab)
-        goto fail;
-    s->tmp_buf = av_malloc(n * sizeof(FFTComplex));
-    if (!s->tmp_buf)
-        goto fail;
-    s->inverse = inverse;
-    s->fft_permutation = FF_FFT_PERM_DEFAULT;
-
-    s->fft_permute = ff_fft_permute_c;
-    s->fft_calc    = ff_fft_calc_c;
-#if CONFIG_MDCT
-    s->imdct_calc  = ff_imdct_calc_c;
-    s->imdct_half  = ff_imdct_half_c;
-    s->mdct_calc   = ff_mdct_calc_c;
-#endif
-
-#if CONFIG_FFT_FLOAT
-    if (ARCH_ARM)     ff_fft_init_arm(s);
-    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;
-#else
-    if (CONFIG_MDCT)  s->mdct_calcw = ff_mdct_calcw_c;
-    if (ARCH_ARM)     ff_fft_fixed_init_arm(s);
-#endif
-
-    for(j=4; j<=nbits; j++) {
-        ff_init_ff_cos_tabs(j);
-    }
-
-    if (s->fft_permutation == FF_FFT_PERM_AVX) {
-        fft_perm_avx(s);
-    } else {
-        for(i=0; i<n; i++) {
-            int j = i;
-            if (s->fft_permutation == FF_FFT_PERM_SWAP_LSBS)
-                j = (j&~3) | ((j>>1)&1) | ((j<<1)&2);
-            s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = j;
-        }
-    }
-
-    return 0;
- fail:
-    av_freep(&s->revtab);
-    av_freep(&s->tmp_buf);
-    return -1;
-}
-
-static void ff_fft_permute_c(FFTContext *s, FFTComplex *z)
-{
-    int j, np;
-    const uint16_t *revtab = s->revtab;
-    np = 1 << s->nbits;
-    /* TODO: handle split-radix permute in a more optimal way, probably in-place */
-    for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j];
-    memcpy(z, s->tmp_buf, np * sizeof(FFTComplex));
-}
-
-av_cold void ff_fft_end(FFTContext *s)
-{
-    av_freep(&s->revtab);
-    av_freep(&s->tmp_buf);
-}
-
-#define BUTTERFLIES(a0,a1,a2,a3) {\
-    BF(t3, t5, t5, t1);\
-    BF(a2.re, a0.re, a0.re, t5);\
-    BF(a3.im, a1.im, a1.im, t3);\
-    BF(t4, t6, t2, t6);\
-    BF(a3.re, a1.re, a1.re, t4);\
-    BF(a2.im, a0.im, a0.im, t6);\
-}
-
-// force loading all the inputs before storing any.
-// this is slightly slower for small data, but avoids store->load aliasing
-// for addresses separated by large powers of 2.
-#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\
-    FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
-    BF(t3, t5, t5, t1);\
-    BF(a2.re, a0.re, r0, t5);\
-    BF(a3.im, a1.im, i1, t3);\
-    BF(t4, t6, t2, t6);\
-    BF(a3.re, a1.re, r1, t4);\
-    BF(a2.im, a0.im, i0, t6);\
-}
-
-#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\
-    CMUL(t1, t2, a2.re, a2.im, wre, -wim);\
-    CMUL(t5, t6, a3.re, a3.im, wre,  wim);\
-    BUTTERFLIES(a0,a1,a2,a3)\
-}
-
-#define TRANSFORM_ZERO(a0,a1,a2,a3) {\
-    t1 = a2.re;\
-    t2 = a2.im;\
-    t5 = a3.re;\
-    t6 = a3.im;\
-    BUTTERFLIES(a0,a1,a2,a3)\
-}
-
-/* z[0...8n-1], w[1...2n-1] */
-#define PASS(name)\
-static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\
-{\
-    FFTDouble t1, t2, t3, t4, t5, t6;\
-    int o1 = 2*n;\
-    int o2 = 4*n;\
-    int o3 = 6*n;\
-    const FFTSample *wim = wre+o1;\
-    n--;\
-\
-    TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\
-    TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
-    do {\
-        z += 2;\
-        wre += 2;\
-        wim -= 2;\
-        TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\
-        TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
-    } while(--n);\
-}
-
-PASS(pass)
-#undef BUTTERFLIES
-#define BUTTERFLIES BUTTERFLIES_BIG
-PASS(pass_big)
-
-#define DECL_FFT(n,n2,n4)\
-static void fft##n(FFTComplex *z)\
-{\
-    fft##n2(z);\
-    fft##n4(z+n4*2);\
-    fft##n4(z+n4*3);\
-    pass(z,FFT_NAME(ff_cos_##n),n4/2);\
-}
-
-static void fft4(FFTComplex *z)
-{
-    FFTDouble t1, t2, t3, t4, t5, t6, t7, t8;
-
-    BF(t3, t1, z[0].re, z[1].re);
-    BF(t8, t6, z[3].re, z[2].re);
-    BF(z[2].re, z[0].re, t1, t6);
-    BF(t4, t2, z[0].im, z[1].im);
-    BF(t7, t5, z[2].im, z[3].im);
-    BF(z[3].im, z[1].im, t4, t8);
-    BF(z[3].re, z[1].re, t3, t7);
-    BF(z[2].im, z[0].im, t2, t5);
-}
-
-static void fft8(FFTComplex *z)
-{
-    FFTDouble t1, t2, t3, t4, t5, t6;
-
-    fft4(z);
-
-    BF(t1, z[5].re, z[4].re, -z[5].re);
-    BF(t2, z[5].im, z[4].im, -z[5].im);
-    BF(t5, z[7].re, z[6].re, -z[7].re);
-    BF(t6, z[7].im, z[6].im, -z[7].im);
-
-    BUTTERFLIES(z[0],z[2],z[4],z[6]);
-    TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf);
-}
-
-#if !CONFIG_SMALL
-static void fft16(FFTComplex *z)
-{
-    FFTDouble t1, t2, t3, t4, t5, t6;
-    FFTSample cos_16_1 = FFT_NAME(ff_cos_16)[1];
-    FFTSample cos_16_3 = FFT_NAME(ff_cos_16)[3];
-
-    fft8(z);
-    fft4(z+8);
-    fft4(z+12);
-
-    TRANSFORM_ZERO(z[0],z[4],z[8],z[12]);
-    TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf);
-    TRANSFORM(z[1],z[5],z[9],z[13],cos_16_1,cos_16_3);
-    TRANSFORM(z[3],z[7],z[11],z[15],cos_16_3,cos_16_1);
-}
-#else
-DECL_FFT(16,8,4)
-#endif
-DECL_FFT(32,16,8)
-DECL_FFT(64,32,16)
-DECL_FFT(128,64,32)
-DECL_FFT(256,128,64)
-DECL_FFT(512,256,128)
-#if !CONFIG_SMALL
-#define pass pass_big
-#endif
-DECL_FFT(1024,512,256)
-DECL_FFT(2048,1024,512)
-DECL_FFT(4096,2048,1024)
-DECL_FFT(8192,4096,2048)
-DECL_FFT(16384,8192,4096)
-DECL_FFT(32768,16384,8192)
-DECL_FFT(65536,32768,16384)
-
-static void (* const fft_dispatch[])(FFTComplex*) = {
-    fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
-    fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
-};
-
-static void ff_fft_calc_c(FFTContext *s, FFTComplex *z)
-{
-    fft_dispatch[s->nbits-2](z);
-}
diff --git a/libavcodec/fft.h b/libavcodec/fft.h
index 7f10f72..d1425ad 100644
--- a/libavcodec/fft.h
+++ b/libavcodec/fft.h
@@ -133,13 +133,11 @@ void ff_init_ff_cos_tabs(int index);
  */
 int ff_fft_init(FFTContext *s, int nbits, int inverse);
 
-#if CONFIG_FFT_FLOAT
-void ff_fft_init_altivec(FFTContext *s);
 void ff_fft_init_x86(FFTContext *s);
 void ff_fft_init_arm(FFTContext *s);
-#else
+void ff_fft_init_ppc(FFTContext *s);
+
 void ff_fft_fixed_init_arm(FFTContext *s);
-#endif
 
 void ff_fft_end(FFTContext *s);
 
diff --git a/libavcodec/fft_fixed.c b/libavcodec/fft_fixed.c
index b28091d..91dc69d 100644
--- a/libavcodec/fft_fixed.c
+++ b/libavcodec/fft_fixed.c
@@ -17,4 +17,4 @@
  */
 
 #define CONFIG_FFT_FLOAT 0
-#include "fft.c"
+#include "fft_template.c"
diff --git a/libavcodec/fft_float.c b/libavcodec/fft_float.c
index 24c9fdb..213da9f 100644
--- a/libavcodec/fft_float.c
+++ b/libavcodec/fft_float.c
@@ -17,4 +17,4 @@
  */
 
 #define CONFIG_FFT_FLOAT 1
-#include "fft.c"
+#include "fft_template.c"
diff --git a/libavcodec/fft_template.c b/libavcodec/fft_template.c
new file mode 100644
index 0000000..0b8140a
--- /dev/null
+++ b/libavcodec/fft_template.c
@@ -0,0 +1,352 @@
+/*
+ * FFT/IFFT transforms
+ * Copyright (c) 2008 Loren Merritt
+ * Copyright (c) 2002 Fabrice Bellard
+ * Partly based on libdjbfft by D. J. Bernstein
+ *
+ * This file is part of Libav.
+ *
+ * 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
+ * FFT/IFFT transforms.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "libavutil/mathematics.h"
+#include "fft.h"
+#include "fft-internal.h"
+
+/* cos(2*pi*x/n) for 0<=x<=n/4, followed by its reverse */
+#if !CONFIG_HARDCODED_TABLES
+COSTABLE(16);
+COSTABLE(32);
+COSTABLE(64);
+COSTABLE(128);
+COSTABLE(256);
+COSTABLE(512);
+COSTABLE(1024);
+COSTABLE(2048);
+COSTABLE(4096);
+COSTABLE(8192);
+COSTABLE(16384);
+COSTABLE(32768);
+COSTABLE(65536);
+#endif
+COSTABLE_CONST FFTSample * const FFT_NAME(ff_cos_tabs)[] = {
+    NULL, NULL, NULL, NULL,
+    FFT_NAME(ff_cos_16),
+    FFT_NAME(ff_cos_32),
+    FFT_NAME(ff_cos_64),
+    FFT_NAME(ff_cos_128),
+    FFT_NAME(ff_cos_256),
+    FFT_NAME(ff_cos_512),
+    FFT_NAME(ff_cos_1024),
+    FFT_NAME(ff_cos_2048),
+    FFT_NAME(ff_cos_4096),
+    FFT_NAME(ff_cos_8192),
+    FFT_NAME(ff_cos_16384),
+    FFT_NAME(ff_cos_32768),
+    FFT_NAME(ff_cos_65536),
+};
+
+static void fft_permute_c(FFTContext *s, FFTComplex *z);
+static void fft_calc_c(FFTContext *s, FFTComplex *z);
+
+static int split_radix_permutation(int i, int n, int inverse)
+{
+    int m;
+    if(n <= 2) return i&1;
+    m = n >> 1;
+    if(!(i&m))            return split_radix_permutation(i, m, inverse)*2;
+    m >>= 1;
+    if(inverse == !(i&m)) return split_radix_permutation(i, m, inverse)*4 + 1;
+    else                  return split_radix_permutation(i, m, inverse)*4 - 1;
+}
+
+av_cold void ff_init_ff_cos_tabs(int index)
+{
+#if !CONFIG_HARDCODED_TABLES
+    int i;
+    int m = 1<<index;
+    double freq = 2*M_PI/m;
+    FFTSample *tab = FFT_NAME(ff_cos_tabs)[index];
+    for(i=0; i<=m/4; i++)
+        tab[i] = FIX15(cos(i*freq));
+    for(i=1; i<m/4; i++)
+        tab[m/2-i] = tab[i];
+#endif
+}
+
+static const int avx_tab[] = {
+    0, 4, 1, 5, 8, 12, 9, 13, 2, 6, 3, 7, 10, 14, 11, 15
+};
+
+static int is_second_half_of_fft32(int i, int n)
+{
+    if (n <= 32)
+        return i >= 16;
+    else if (i < n/2)
+        return is_second_half_of_fft32(i, n/2);
+    else if (i < 3*n/4)
+        return is_second_half_of_fft32(i - n/2, n/4);
+    else
+        return is_second_half_of_fft32(i - 3*n/4, n/4);
+}
+
+static av_cold void fft_perm_avx(FFTContext *s)
+{
+    int i;
+    int n = 1 << s->nbits;
+
+    for (i = 0; i < n; i += 16) {
+        int k;
+        if (is_second_half_of_fft32(i, n)) {
+            for (k = 0; k < 16; k++)
+                s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] =
+                    i + avx_tab[k];
+
+        } else {
+            for (k = 0; k < 16; k++) {
+                int j = i + k;
+                j = (j & ~7) | ((j >> 1) & 3) | ((j << 2) & 4);
+                s->revtab[-split_radix_permutation(i + k, n, s->inverse) & (n - 1)] = j;
+            }
+        }
+    }
+}
+
+av_cold int ff_fft_init(FFTContext *s, int nbits, int inverse)
+{
+    int i, j, n;
+
+    if (nbits < 2 || nbits > 16)
+        goto fail;
+    s->nbits = nbits;
+    n = 1 << nbits;
+
+    s->revtab = av_malloc(n * sizeof(uint16_t));
+    if (!s->revtab)
+        goto fail;
+    s->tmp_buf = av_malloc(n * sizeof(FFTComplex));
+    if (!s->tmp_buf)
+        goto fail;
+    s->inverse = inverse;
+    s->fft_permutation = FF_FFT_PERM_DEFAULT;
+
+    s->fft_permute = fft_permute_c;
+    s->fft_calc    = fft_calc_c;
+#if CONFIG_MDCT
+    s->imdct_calc  = ff_imdct_calc_c;
+    s->imdct_half  = ff_imdct_half_c;
+    s->mdct_calc   = ff_mdct_calc_c;
+#endif
+
+#if CONFIG_FFT_FLOAT
+    if (ARCH_ARM)     ff_fft_init_arm(s);
+    if (ARCH_PPC)     ff_fft_init_ppc(s);
+    if (ARCH_X86)     ff_fft_init_x86(s);
+    if (CONFIG_MDCT)  s->mdct_calcw = s->mdct_calc;
+#else
+    if (CONFIG_MDCT)  s->mdct_calcw = ff_mdct_calcw_c;
+    if (ARCH_ARM)     ff_fft_fixed_init_arm(s);
+#endif
+
+    for(j=4; j<=nbits; j++) {
+        ff_init_ff_cos_tabs(j);
+    }
+
+    if (s->fft_permutation == FF_FFT_PERM_AVX) {
+        fft_perm_avx(s);
+    } else {
+        for(i=0; i<n; i++) {
+            int j = i;
+            if (s->fft_permutation == FF_FFT_PERM_SWAP_LSBS)
+                j = (j&~3) | ((j>>1)&1) | ((j<<1)&2);
+            s->revtab[-split_radix_permutation(i, n, s->inverse) & (n-1)] = j;
+        }
+    }
+
+    return 0;
+ fail:
+    av_freep(&s->revtab);
+    av_freep(&s->tmp_buf);
+    return -1;
+}
+
+static void fft_permute_c(FFTContext *s, FFTComplex *z)
+{
+    int j, np;
+    const uint16_t *revtab = s->revtab;
+    np = 1 << s->nbits;
+    /* TODO: handle split-radix permute in a more optimal way, probably in-place */
+    for(j=0;j<np;j++) s->tmp_buf[revtab[j]] = z[j];
+    memcpy(z, s->tmp_buf, np * sizeof(FFTComplex));
+}
+
+av_cold void ff_fft_end(FFTContext *s)
+{
+    av_freep(&s->revtab);
+    av_freep(&s->tmp_buf);
+}
+
+#define BUTTERFLIES(a0,a1,a2,a3) {\
+    BF(t3, t5, t5, t1);\
+    BF(a2.re, a0.re, a0.re, t5);\
+    BF(a3.im, a1.im, a1.im, t3);\
+    BF(t4, t6, t2, t6);\
+    BF(a3.re, a1.re, a1.re, t4);\
+    BF(a2.im, a0.im, a0.im, t6);\
+}
+
+// force loading all the inputs before storing any.
+// this is slightly slower for small data, but avoids store->load aliasing
+// for addresses separated by large powers of 2.
+#define BUTTERFLIES_BIG(a0,a1,a2,a3) {\
+    FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
+    BF(t3, t5, t5, t1);\
+    BF(a2.re, a0.re, r0, t5);\
+    BF(a3.im, a1.im, i1, t3);\
+    BF(t4, t6, t2, t6);\
+    BF(a3.re, a1.re, r1, t4);\
+    BF(a2.im, a0.im, i0, t6);\
+}
+
+#define TRANSFORM(a0,a1,a2,a3,wre,wim) {\
+    CMUL(t1, t2, a2.re, a2.im, wre, -wim);\
+    CMUL(t5, t6, a3.re, a3.im, wre,  wim);\
+    BUTTERFLIES(a0,a1,a2,a3)\
+}
+
+#define TRANSFORM_ZERO(a0,a1,a2,a3) {\
+    t1 = a2.re;\
+    t2 = a2.im;\
+    t5 = a3.re;\
+    t6 = a3.im;\
+    BUTTERFLIES(a0,a1,a2,a3)\
+}
+
+/* z[0...8n-1], w[1...2n-1] */
+#define PASS(name)\
+static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\
+{\
+    FFTDouble t1, t2, t3, t4, t5, t6;\
+    int o1 = 2*n;\
+    int o2 = 4*n;\
+    int o3 = 6*n;\
+    const FFTSample *wim = wre+o1;\
+    n--;\
+\
+    TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\
+    TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
+    do {\
+        z += 2;\
+        wre += 2;\
+        wim -= 2;\
+        TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\
+        TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
+    } while(--n);\
+}
+
+PASS(pass)
+#undef BUTTERFLIES
+#define BUTTERFLIES BUTTERFLIES_BIG
+PASS(pass_big)
+
+#define DECL_FFT(n,n2,n4)\
+static void fft##n(FFTComplex *z)\
+{\
+    fft##n2(z);\
+    fft##n4(z+n4*2);\
+    fft##n4(z+n4*3);\
+    pass(z,FFT_NAME(ff_cos_##n),n4/2);\
+}
+
+static void fft4(FFTComplex *z)
+{
+    FFTDouble t1, t2, t3, t4, t5, t6, t7, t8;
+
+    BF(t3, t1, z[0].re, z[1].re);
+    BF(t8, t6, z[3].re, z[2].re);
+    BF(z[2].re, z[0].re, t1, t6);
+    BF(t4, t2, z[0].im, z[1].im);
+    BF(t7, t5, z[2].im, z[3].im);
+    BF(z[3].im, z[1].im, t4, t8);
+    BF(z[3].re, z[1].re, t3, t7);
+    BF(z[2].im, z[0].im, t2, t5);
+}
+
+static void fft8(FFTComplex *z)
+{
+    FFTDouble t1, t2, t3, t4, t5, t6;
+
+    fft4(z);
+
+    BF(t1, z[5].re, z[4].re, -z[5].re);
+    BF(t2, z[5].im, z[4].im, -z[5].im);
+    BF(t5, z[7].re, z[6].re, -z[7].re);
+    BF(t6, z[7].im, z[6].im, -z[7].im);
+
+    BUTTERFLIES(z[0],z[2],z[4],z[6]);
+    TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf);
+}
+
+#if !CONFIG_SMALL
+static void fft16(FFTComplex *z)
+{
+    FFTDouble t1, t2, t3, t4, t5, t6;
+    FFTSample cos_16_1 = FFT_NAME(ff_cos_16)[1];
+    FFTSample cos_16_3 = FFT_NAME(ff_cos_16)[3];
+
+    fft8(z);
+    fft4(z+8);
+    fft4(z+12);
+
+    TRANSFORM_ZERO(z[0],z[4],z[8],z[12]);
+    TRANSFORM(z[2],z[6],z[10],z[14],sqrthalf,sqrthalf);
+    TRANSFORM(z[1],z[5],z[9],z[13],cos_16_1,cos_16_3);
+    TRANSFORM(z[3],z[7],z[11],z[15],cos_16_3,cos_16_1);
+}
+#else
+DECL_FFT(16,8,4)
+#endif
+DECL_FFT(32,16,8)
+DECL_FFT(64,32,16)
+DECL_FFT(128,64,32)
+DECL_FFT(256,128,64)
+DECL_FFT(512,256,128)
+#if !CONFIG_SMALL
+#define pass pass_big
+#endif
+DECL_FFT(1024,512,256)
+DECL_FFT(2048,1024,512)
+DECL_FFT(4096,2048,1024)
+DECL_FFT(8192,4096,2048)
+DECL_FFT(16384,8192,4096)
+DECL_FFT(32768,16384,8192)
+DECL_FFT(65536,32768,16384)
+
+static void (* const fft_dispatch[])(FFTComplex*) = {
+    fft4, fft8, fft16, fft32, fft64, fft128, fft256, fft512, fft1024,
+    fft2048, fft4096, fft8192, fft16384, fft32768, fft65536,
+};
+
+static void fft_calc_c(FFTContext *s, FFTComplex *z)
+{
+    fft_dispatch[s->nbits-2](z);
+}
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index f6d9eaf..9e7ba2e 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -25,11 +25,11 @@
  * FF Video Codec 1 (a lossless codec)
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "rangecoder.h"
 #include "golomb.h"
 #include "mathops.h"
@@ -131,7 +131,7 @@ const uint8_t ffv1_ver2_state[256] = {
 };
 
 
-int ffv1_common_init(AVCodecContext *avctx)
+av_cold int ffv1_common_init(AVCodecContext *avctx)
 {
     FFV1Context *s = avctx->priv_data;
 
@@ -141,8 +141,6 @@ int ffv1_common_init(AVCodecContext *avctx)
     if (!avctx->width || !avctx->height)
         return AVERROR_INVALIDDATA;
 
-    avcodec_get_frame_defaults(&s->picture);
-
     ff_dsputil_init(&s->dsp, avctx);
 
     s->width  = avctx->width;
@@ -271,11 +269,6 @@ av_cold int ffv1_close(AVCodecContext *avctx)
     FFV1Context *s = avctx->priv_data;
     int i, j;
 
-    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];
         for (i = 0; i < s->plane_count; i++) {
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index 4752cea..40fc393 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -79,7 +79,10 @@ typedef struct FFV1Context {
     int transparency;
     int flags;
     int picture_number;
-    AVFrame picture, last_picture;
+    AVFrame *frame;
+    AVFrame *last_picture;
+
+    AVFrame *cur;
     int plane_count;
     int ac;     // 1 = range coder <-> 0 = golomb rice
     int ac_byte_count;      // number of bytes used for AC coding
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 97e2bd5..5edc667 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -34,7 +34,6 @@
 #include "internal.h"
 #include "get_bits.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "rangecoder.h"
 #include "golomb.h"
 #include "mathops.h"
@@ -317,16 +316,16 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs)
 
     ps = get_symbol(c, state, 0);
     if (ps == 1) {
-        f->picture.interlaced_frame = 1;
-        f->picture.top_field_first  = 1;
+        f->cur->interlaced_frame = 1;
+        f->cur->top_field_first  = 1;
     } else if (ps == 2) {
-        f->picture.interlaced_frame = 1;
-        f->picture.top_field_first  = 0;
+        f->cur->interlaced_frame = 1;
+        f->cur->top_field_first  = 0;
     } else if (ps == 3) {
-        f->picture.interlaced_frame = 0;
+        f->cur->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);
+    f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0);
+    f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0);
 
     return 0;
 }
@@ -336,10 +335,10 @@ static int decode_slice(AVCodecContext *c, void *arg)
     FFV1Context *fs = *(void **)arg;
     FFV1Context *f  = fs->avctx->priv_data;
     int width, height, x, y, ret;
-    const int ps = (av_pix_fmt_desc_get(c->pix_fmt)->flags & PIX_FMT_PLANAR)
+    const int ps = (av_pix_fmt_desc_get(c->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR)
                    ? (c->bits_per_raw_sample > 8) + 1
                    : 4;
-    AVFrame *const p = &f->picture;
+    AVFrame *const p = f->cur;
 
     if (f->version > 2) {
         if (decode_slice_header(f, fs) < 0) {
@@ -349,7 +348,7 @@ static int decode_slice(AVCodecContext *c, void *arg)
     }
     if ((ret = ffv1_init_slice_state(f, fs)) < 0)
         return ret;
-    if (f->picture.key_frame)
+    if (f->cur->key_frame)
         ffv1_clear_slice_state(f, fs);
     width  = fs->slice_width;
     height = fs->slice_height;
@@ -670,6 +669,7 @@ static int read_header(FFV1Context *f)
             return AVERROR(ENOSYS);
         }
         switch (f->avctx->bits_per_raw_sample) {
+        case 0:
         case 8:
             f->avctx->pix_fmt = AV_PIX_FMT_RGB32;
             break;
@@ -784,6 +784,10 @@ static av_cold int ffv1_decode_init(AVCodecContext *avctx)
 
     ffv1_common_init(avctx);
 
+    f->last_picture = av_frame_alloc();
+    if (!f->last_picture)
+        return AVERROR(ENOMEM);
+
     if (avctx->extradata && (ret = read_extra_header(f)) < 0)
         return ret;
 
@@ -800,16 +804,12 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
     int buf_size        = avpkt->size;
     FFV1Context *f      = avctx->priv_data;
     RangeCoder *const c = &f->slice_context[0]->c;
-    AVFrame *const p    = &f->picture;
     int i, ret;
     uint8_t keystate = 128;
     const uint8_t *buf_p;
+    AVFrame *const p    = data;
 
-    AVFrame *picture = data;
-
-    /* release previously stored data */
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    f->cur = p;
 
     ff_init_range_decoder(c, buf, buf_size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
@@ -830,8 +830,7 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
         p->key_frame = 0;
     }
 
-    p->reference = 3; //for error concealment
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -870,6 +869,8 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
             ff_init_range_decoder(&fs->c, buf_p, v);
         } else
             fs->c.bytestream_end = (uint8_t *)(buf_p + v);
+
+        fs->cur = p;
     }
 
     avctx->execute(avctx, decode_slice, &f->slice_context[0], NULL,
@@ -879,20 +880,20 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
     for (i = f->slice_count - 1; i >= 0; i--) {
         FFV1Context *fs = f->slice_context[i];
         int j;
-        if (fs->slice_damaged && f->last_picture.data[0]) {
+        if (fs->slice_damaged && f->last_picture->data[0]) {
             const uint8_t *src[4];
             uint8_t *dst[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] *
+                dst[j] = p->data[j] + p->linesize[j] *
                          (fs->slice_y >> sv) + (fs->slice_x >> sh);
-                src[j] = f->last_picture.data[j] +
-                         f->last_picture.linesize[j] *
+                src[j] = f->last_picture->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,
+            av_image_copy(dst, p->linesize, (const uint8_t **)src,
+                          f->last_picture->linesize,
                           avctx->pix_fmt, fs->slice_width,
                           fs->slice_height);
         }
@@ -900,23 +901,36 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
 
     f->picture_number++;
 
-    *picture   = *p;
-    *got_frame = 1;
+    av_frame_unref(f->last_picture);
+    if ((ret = av_frame_ref(f->last_picture, p)) < 0)
+        return ret;
+    f->cur = NULL;
 
-    FFSWAP(AVFrame, f->picture, f->last_picture);
+    *got_frame = 1;
 
     return buf_size;
 }
 
+static av_cold int ffv1_decode_close(AVCodecContext *avctx)
+{
+    FFV1Context *s = avctx->priv_data;;
+
+    av_frame_free(&s->last_picture);
+
+    ffv1_close(avctx);
+
+    return 0;
+}
+
 AVCodec ff_ffv1_decoder = {
     .name           = "ffv1",
+    .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FFV1,
     .priv_data_size = sizeof(FFV1Context),
     .init           = ffv1_decode_init,
-    .close          = ffv1_close,
+    .close          = ffv1_decode_close,
     .decode         = ffv1_decode_frame,
     .capabilities   = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ |
                       CODEC_CAP_SLICE_THREADS,
-    .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
 };
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c
index 8c6fc9a..179453d 100644
--- a/libavcodec/ffv1enc.c
+++ b/libavcodec/ffv1enc.c
@@ -25,6 +25,7 @@
  * FF Video Codec 1 (a lossless codec) encoder
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/crc.h"
@@ -34,7 +35,6 @@
 #include "internal.h"
 #include "get_bits.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "rangecoder.h"
 #include "golomb.h"
 #include "mathops.h"
@@ -545,7 +545,7 @@ static int sort_stt(FFV1Context *s, uint8_t stt[256])
     return print;
 }
 
-static int init_slices_state(FFV1Context *f)
+static av_cold int init_slices_state(FFV1Context *f)
 {
     int i, ret;
     for (i = 0; i < f->slice_count; i++) {
@@ -721,7 +721,12 @@ static av_cold int ffv1_encode_init(AVCodecContext *avctx)
     if ((ret = ffv1_allocate_initial_states(s)) < 0)
         return ret;
 
-    avctx->coded_frame = &s->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+
     if (!s->transparency)
         s->plane_count = 2;
 
@@ -858,12 +863,12 @@ static void encode_slice_header(FFV1Context *f, FFV1Context *fs)
         put_symbol(c, state, f->plane[j].quant_table_index, 0);
         av_assert0(f->plane[j].quant_table_index == f->avctx->context_model);
     }
-    if (!f->picture.interlaced_frame)
+    if (!f->avctx->coded_frame->interlaced_frame)
         put_symbol(c, state, 3, 0);
     else
-        put_symbol(c, state, 1 + !f->picture.top_field_first, 0);
-    put_symbol(c, state, f->picture.sample_aspect_ratio.num, 0);
-    put_symbol(c, state, f->picture.sample_aspect_ratio.den, 0);
+        put_symbol(c, state, 1 + !f->avctx->coded_frame->top_field_first, 0);
+    put_symbol(c, state, f->avctx->coded_frame->sample_aspect_ratio.num, 0);
+    put_symbol(c, state, f->avctx->coded_frame->sample_aspect_ratio.den, 0);
 }
 
 static int encode_slice(AVCodecContext *c, void *arg)
@@ -874,12 +879,12 @@ static int encode_slice(AVCodecContext *c, void *arg)
     int height       = fs->slice_height;
     int x            = fs->slice_x;
     int y            = fs->slice_y;
-    AVFrame *const p = &f->picture;
-    const int ps     = (av_pix_fmt_desc_get(c->pix_fmt)->flags & PIX_FMT_PLANAR)
+    const AVFrame *const p = f->frame;
+    const int ps     = (av_pix_fmt_desc_get(c->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR)
                        ? (f->bits_per_raw_sample > 8) + 1
                        : 4;
 
-    if (p->key_frame)
+    if (c->coded_frame->key_frame)
         ffv1_clear_slice_state(f, fs);
     if (f->version > 2) {
         encode_slice_header(f, fs);
@@ -926,12 +931,14 @@ static int ffv1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 {
     FFV1Context *f      = avctx->priv_data;
     RangeCoder *const c = &f->slice_context[0]->c;
-    AVFrame *const p    = &f->picture;
+    AVFrame *const p    = avctx->coded_frame;
     int used_count      = 0;
     uint8_t keystate    = 128;
     uint8_t *buf_p;
     int i, ret;
 
+    f->frame = pict;
+
     if ((ret = ff_alloc_packet(pkt, avctx->width * avctx->height *
                              ((8 * 2 + 1 + 1) * 4) / 8 +
                              FF_MIN_BUFFER_SIZE)) < 0) {
@@ -942,9 +949,6 @@ static int ffv1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     ff_init_range_encoder(c, pkt->data, pkt->size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
 
-    *p           = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-
     if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
         put_rac(c, &keystate, 1);
         p->key_frame = 1;
@@ -1054,6 +1058,13 @@ static int ffv1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
+static av_cold int ffv1_encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    ffv1_close(avctx);
+    return 0;
+}
+
 #define OFFSET(x) offsetof(FFV1Context, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
@@ -1076,12 +1087,13 @@ static const AVCodecDefault ffv1_defaults[] = {
 
 AVCodec ff_ffv1_encoder = {
     .name           = "ffv1",
+    .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FFV1,
     .priv_data_size = sizeof(FFV1Context),
     .init           = ffv1_encode_init,
     .encode2        = ffv1_encode_frame,
-    .close          = ffv1_close,
+    .close          = ffv1_encode_close,
     .capabilities   = CODEC_CAP_SLICE_THREADS,
     .pix_fmts       = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_YUV420P,   AV_PIX_FMT_YUV422P,   AV_PIX_FMT_YUV444P,
@@ -1096,7 +1108,6 @@ AVCodec ff_ffv1_encoder = {
         AV_PIX_FMT_NONE
 
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
     .defaults       = ffv1_defaults,
     .priv_class     = &class,
 };
diff --git a/libavcodec/file_open.c b/libavcodec/file_open.c
new file mode 100644
index 0000000..494a5d3
--- /dev/null
+++ b/libavcodec/file_open.c
@@ -0,0 +1 @@
+#include "libavutil/file_open.c"
diff --git a/libavcodec/flac.c b/libavcodec/flac.c
index 32b28d0..b3e3847 100644
--- a/libavcodec/flac.c
+++ b/libavcodec/flac.c
@@ -29,13 +29,15 @@
 
 static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
 
-static const int64_t flac_channel_layouts[6] = {
+static const uint64_t flac_channel_layouts[8] = {
     AV_CH_LAYOUT_MONO,
     AV_CH_LAYOUT_STEREO,
     AV_CH_LAYOUT_SURROUND,
     AV_CH_LAYOUT_QUAD,
     AV_CH_LAYOUT_5POINT0,
-    AV_CH_LAYOUT_5POINT1
+    AV_CH_LAYOUT_5POINT1,
+    AV_CH_LAYOUT_6POINT1,
+    AV_CH_LAYOUT_7POINT1
 };
 
 static int64_t get_utf8(GetBitContext *gb)
@@ -53,7 +55,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
     /* frame sync code */
     if ((get_bits(gb, 15) & 0x7FFF) != 0x7FFC) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid sync code\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* variable block size stream code */
@@ -74,7 +76,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
     } else {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "invalid channel mode: %d\n", fi->ch_mode);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* bits per sample */
@@ -83,7 +85,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "invalid sample size code (%d)\n",
                bps_code);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     fi->bps = sample_size_table[bps_code];
 
@@ -91,7 +93,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
     if (get_bits1(gb)) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "broken stream, invalid padding\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* sample or frame count */
@@ -99,14 +101,14 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
     if (fi->frame_or_sample_num < 0) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "sample/frame number invalid; utf8 fscked\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* blocksize */
     if (bs_code == 0) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "reserved blocksize code: 0\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     } else if (bs_code == 6) {
         fi->blocksize = get_bits(gb, 8) + 1;
     } else if (bs_code == 7) {
@@ -128,7 +130,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "illegal sample rate code %d\n",
                sr_code);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* header CRC-8 check */
@@ -137,7 +139,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
                get_bits_count(gb)/8)) {
         av_log(avctx, AV_LOG_ERROR + log_level_offset,
                "header crc mismatch\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     return 0;
diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
index 3d8e17f..bf2c118 100644
--- a/libavcodec/flac_parser.c
+++ b/libavcodec/flac_parser.c
@@ -27,11 +27,12 @@
  * Each time it finds and verifies a CRC-8 header it sees which of the
  * FLAC_MAX_SEQUENTIAL_HEADERS that came before it have a valid CRC-16 footer
  * that ends at the newly found header.
- * Headers are scored by FLAC_HEADER_BASE_SCORE plus the max of it's crc-verified
+ * Headers are scored by FLAC_HEADER_BASE_SCORE plus the max of its crc-verified
  * children, penalized by changes in sample rate, frame number, etc.
  * The parser returns the frame with the highest score.
  **/
 
+#include "libavutil/attributes.h"
 #include "libavutil/crc.h"
 #include "libavutil/fifo.h"
 #include "bytestream.h"
@@ -458,7 +459,7 @@ static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf,
     }
 
     if (header->fi.channels != fpc->avctx->channels ||
-        (!fpc->avctx->channel_layout && header->fi.channels <= 6)) {
+        !fpc->avctx->channel_layout) {
         fpc->avctx->channels = header->fi.channels;
         ff_flac_set_channel_layout(fpc->avctx);
     }
@@ -653,7 +654,7 @@ handle_error:
     return read_end - buf;
 }
 
-static int flac_parse_init(AVCodecParserContext *c)
+static av_cold int flac_parse_init(AVCodecParserContext *c)
 {
     FLACParseContext *fpc = c->priv_data;
     fpc->pc = c;
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 51fd196..0305d50 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -44,14 +44,10 @@
 #include "flacdata.h"
 #include "flacdsp.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 typedef struct FLACContext {
     FLACSTREAMINFO
 
     AVCodecContext *avctx;                  ///< parent AVCodecContext
-    AVFrame frame;
     GetBitContext gb;                       ///< GetBitContext initialized to start at the current frame
 
     int blocksize;                          ///< number of samples in the current frame
@@ -104,7 +100,7 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
         return 0;
 
     if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     /* initialize based on the demuxer-supplied streamdata header */
     avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo);
@@ -115,9 +111,6 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
     ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->bps);
     s->got_streaminfo = 1;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -134,8 +127,6 @@ static int allocate_buffers(FLACContext *s)
 {
     int buf_size;
 
-    assert(s->max_blocksize);
-
     buf_size = av_samples_get_buffer_size(NULL, s->channels, s->max_blocksize,
                                           AV_SAMPLE_FMT_S32P, 0);
     if (buf_size < 0)
@@ -218,7 +209,7 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order)
     if (method_type > 1) {
         av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n",
                method_type);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     rice_order = get_bits(&s->gb, 4);
@@ -227,7 +218,7 @@ static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order)
     if (pred_order > samples) {
         av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n",
                pred_order, samples);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     rice_bits = 4 + method_type;
@@ -256,15 +247,15 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
                                  int pred_order, int bps)
 {
     const int blocksize = s->blocksize;
-    int a, b, c, d, i;
+    int a, b, c, d, i, ret;
 
     /* warm up samples */
     for (i = 0; i < pred_order; i++) {
         decoded[i] = get_sbits_long(&s->gb, bps);
     }
 
-    if (decode_residuals(s, decoded, pred_order) < 0)
-        return -1;
+    if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
+        return ret;
 
     if (pred_order > 0)
         a = decoded[pred_order-1];
@@ -296,7 +287,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
         break;
     default:
         av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     return 0;
@@ -305,7 +296,7 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
 static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
                                int bps)
 {
-    int i;
+    int i, ret;
     int coeff_prec, qlevel;
     int coeffs[32];
 
@@ -317,21 +308,21 @@ static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
     coeff_prec = get_bits(&s->gb, 4) + 1;
     if (coeff_prec == 16) {
         av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     qlevel = get_sbits(&s->gb, 5);
     if (qlevel < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n",
                qlevel);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     for (i = 0; i < pred_order; i++) {
         coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec);
     }
 
-    if (decode_residuals(s, decoded, pred_order) < 0)
-        return -1;
+    if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
+        return ret;
 
     s->dsp.lpc(decoded, coeffs, pred_order, qlevel, s->blocksize);
 
@@ -343,7 +334,7 @@ static inline int decode_subframe(FLACContext *s, int channel)
     int32_t *decoded = s->decoded[channel];
     int type, wasted = 0;
     int bps = s->bps;
-    int i, tmp;
+    int i, tmp, ret;
 
     if (channel == 0) {
         if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE)
@@ -355,7 +346,7 @@ static inline int decode_subframe(FLACContext *s, int channel)
 
     if (get_bits1(&s->gb)) {
         av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     type = get_bits(&s->gb, 6);
 
@@ -375,7 +366,7 @@ static inline int decode_subframe(FLACContext *s, int channel)
         bps -= wasted;
     }
     if (bps > 32) {
-        av_log_missing_feature(s->avctx, "Decorrelated bit depth > 32", 0);
+        avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -388,14 +379,14 @@ static inline int decode_subframe(FLACContext *s, int channel)
         for (i = 0; i < s->blocksize; i++)
             decoded[i] = get_sbits_long(&s->gb, bps);
     } else if ((type >= 8) && (type <= 12)) {
-        if (decode_subframe_fixed(s, decoded, type & ~0x8, bps) < 0)
-            return -1;
+        if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0)
+            return ret;
     } else if (type >= 32) {
-        if (decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps) < 0)
-            return -1;
+        if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0)
+            return ret;
     } else {
         av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (wasted) {
@@ -413,9 +404,9 @@ static int decode_frame(FLACContext *s)
     GetBitContext *gb = &s->gb;
     FLACFrameInfo fi;
 
-    if (ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) {
+    if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n");
-        return -1;
+        return ret;
     }
 
     if (s->channels && fi.channels != s->channels && s->got_streaminfo) {
@@ -426,20 +417,20 @@ static int decode_frame(FLACContext *s)
             return ret;
     }
     s->channels = s->avctx->channels = fi.channels;
-    if (!s->avctx->channel_layout && s->channels <= 6)
+    if (!s->avctx->channel_layout)
         ff_flac_set_channel_layout(s->avctx);
     s->ch_mode = fi.ch_mode;
 
     if (!s->bps && !fi.bps) {
         av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (!fi.bps) {
         fi.bps = s->bps;
     } else if (s->bps && fi.bps != s->bps) {
         av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not "
                                        "supported\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (!s->bps) {
@@ -452,14 +443,14 @@ static int decode_frame(FLACContext *s)
     if (fi.blocksize > s->max_blocksize) {
         av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize,
                s->max_blocksize);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->blocksize = fi.blocksize;
 
     if (!s->samplerate && !fi.samplerate) {
         av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO"
                                         " or frame header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (fi.samplerate == 0)
         fi.samplerate = s->samplerate;
@@ -478,8 +469,8 @@ static int decode_frame(FLACContext *s)
 
     /* subframes */
     for (i = 0; i < s->channels; i++) {
-        if (decode_subframe(s, i) < 0)
-            return -1;
+        if ((ret = decode_subframe(s, i)) < 0)
+            return ret;
     }
 
     align_get_bits(gb);
@@ -493,6 +484,7 @@ static int decode_frame(FLACContext *s)
 static int flac_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     FLACContext *s = avctx->priv_data;
@@ -515,42 +507,41 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data,
 
     /* check for inline header */
     if (AV_RB32(buf) == MKBETAG('f','L','a','C')) {
-        if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) {
+        if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) {
             av_log(s->avctx, AV_LOG_ERROR, "invalid header\n");
-            return -1;
+            return ret;
         }
         return get_metadata_size(buf, buf_size);
     }
 
     /* decode frame */
     init_get_bits(&s->gb, buf, buf_size*8);
-    if (decode_frame(s) < 0) {
+    if ((ret = decode_frame(s)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");
-        return -1;
+        return ret;
     }
     bytes_read = (get_bits_count(&s->gb)+7)/8;
 
     /* get output buffer */
-    s->frame.nb_samples = s->blocksize;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->blocksize;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    s->dsp.decorrelate[s->ch_mode](s->frame.data, s->decoded, s->channels,
+    s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, s->channels,
                                    s->blocksize, s->sample_shift);
 
     if (bytes_read > buf_size) {
         av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (bytes_read < buf_size) {
         av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n",
                buf_size - bytes_read, buf_size);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return bytes_read;
 }
@@ -566,6 +557,7 @@ static av_cold int flac_decode_close(AVCodecContext *avctx)
 
 AVCodec ff_flac_decoder = {
     .name           = "flac",
+    .long_name      = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_FLAC,
     .priv_data_size = sizeof(FLACContext),
@@ -573,7 +565,6 @@ AVCodec ff_flac_decoder = {
     .close          = flac_decode_close,
     .decode         = flac_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
                                                       AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_S32,
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index 7808e20..58e86be 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -394,12 +394,6 @@ static av_cold int flac_encode_init(AVCodecContext *avctx)
     s->frame_count   = 0;
     s->min_framesize = s->max_framesize;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-#endif
-
     ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size,
                       s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON);
 
@@ -1238,7 +1232,7 @@ static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
     frame_bytes = encode_frame(s);
 
-    /* fallback to verbatim mode if the compressed frame is larger than it
+    /* Fall back on verbatim mode if the compressed frame is larger than it
        would be if encoded uncompressed. */
     if (frame_bytes < 0 || frame_bytes > s->max_framesize) {
         s->frame.verbatim_only = 1;
@@ -1285,9 +1279,6 @@ static av_cold int flac_encode_close(AVCodecContext *avctx)
     }
     av_freep(&avctx->extradata);
     avctx->extradata_size = 0;
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     return 0;
 }
 
@@ -1327,6 +1318,7 @@ static const AVClass flac_encoder_class = {
 
 AVCodec ff_flac_encoder = {
     .name           = "flac",
+    .long_name      = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_FLAC,
     .priv_data_size = sizeof(FlacEncodeContext),
@@ -1337,6 +1329,5 @@ AVCodec ff_flac_encoder = {
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_S32,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
     .priv_class     = &flac_encoder_class,
 };
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 3c5a35c..de7979c 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -41,6 +41,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "get_bits.h"
+#include "internal.h"
 
 typedef struct BlockInfo {
     uint8_t *pos;
@@ -49,7 +50,7 @@ typedef struct BlockInfo {
 
 typedef struct FlashSVContext {
     AVCodecContext *avctx;
-    AVFrame         frame;
+    AVFrame        *frame;
     int             image_width, image_height;
     int             block_width, block_height;
     uint8_t        *tmpblock;
@@ -68,14 +69,13 @@ typedef struct FlashSVContext {
     int             diff_start, diff_height;
 } FlashSVContext;
 
-
 static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
                          int h, int w, int stride, const uint32_t *pal)
 {
     int x, y;
     const uint8_t *orig_src = sptr;
 
-    for (y = dx+h; y > dx; y--) {
+    for (y = dx + h; y > dx; y--) {
         uint8_t *dst = dptr + (y * stride) + dy * 3;
         for (x = 0; x < w; x++) {
             if (*sptr & 0x80) {
@@ -99,6 +99,19 @@ static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
     return sptr - orig_src;
 }
 
+static av_cold int flashsv_decode_end(AVCodecContext *avctx)
+{
+    FlashSVContext *s = avctx->priv_data;
+    inflateEnd(&s->zstream);
+    /* release the frame if needed */
+    av_frame_free(&s->frame);
+
+    /* free the tmpblock */
+    av_free(s->tmpblock);
+
+    return 0;
+}
+
 static av_cold int flashsv_decode_init(AVCodecContext *avctx)
 {
     FlashSVContext *s = avctx->priv_data;
@@ -114,12 +127,16 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx)
         return 1;
     }
     avctx->pix_fmt = AV_PIX_FMT_BGR24;
-    s->frame.data[0] = NULL;
+
+    s->frame = av_frame_alloc();
+    if (!s->frame) {
+        flashsv_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
     return 0;
 }
 
-
 static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size)
 {
     z_stream zs;
@@ -193,25 +210,28 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
     }
 
     if (s->is_keyframe) {
-        s->blocks[blk_idx].pos      = s->keyframedata + (get_bits_count(gb) / 8);
-        s->blocks[blk_idx].size     = block_size;
+        s->blocks[blk_idx].pos  = s->keyframedata + (get_bits_count(gb) / 8);
+        s->blocks[blk_idx].size = block_size;
     }
+
+    y_pos += s->diff_start;
+
     if (!s->color_depth) {
         /* Flash Screen Video stores the image upside down, so copy
          * lines to destination in reverse order. */
         for (k = 1; k <= s->diff_height; k++) {
-            memcpy(s->frame.data[0] + x_pos * 3 +
-                   (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
+            memcpy(s->frame->data[0] + x_pos * 3 +
+                   (s->image_height - y_pos - k) * s->frame->linesize[0],
                    line, width * 3);
             /* advance source pointer to next line */
             line += width * 3;
         }
     } else {
         /* hybrid 15-bit/palette mode */
-        decode_hybrid(s->tmpblock, s->frame.data[0],
-                      s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
+        decode_hybrid(s->tmpblock, s->frame->data[0],
+                      s->image_height - (y_pos + 1 + s->diff_height),
                       x_pos, s->diff_height, width,
-                      s->frame.linesize[0], s->pal);
+                      s->frame->linesize[0], s->pal);
     }
     skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
     return 0;
@@ -236,9 +256,9 @@ static int calc_deflate_block_size(int tmpblock_size)
 static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame, AVPacket *avpkt)
 {
-    int buf_size       = avpkt->size;
-    FlashSVContext *s  = avctx->priv_data;
-    int h_blocks, v_blocks, h_part, v_part, i, j;
+    int buf_size = avpkt->size;
+    FlashSVContext *s = avctx->priv_data;
+    int h_blocks, v_blocks, h_part, v_part, i, j, ret;
     GetBitContext gb;
 
     /* no supplementary picture */
@@ -250,19 +270,19 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
     init_get_bits(&gb, avpkt->data, buf_size * 8);
 
     /* start to parse the bitstream */
-    s->block_width  = 16 * (get_bits(&gb,  4) + 1);
-    s->image_width  =       get_bits(&gb, 12);
-    s->block_height = 16 * (get_bits(&gb,  4) + 1);
-    s->image_height =       get_bits(&gb, 12);
+    s->block_width  = 16 * (get_bits(&gb, 4) + 1);
+    s->image_width  = get_bits(&gb, 12);
+    s->block_height = 16 * (get_bits(&gb, 4) + 1);
+    s->image_height = get_bits(&gb, 12);
 
     if (s->ver == 2) {
         skip_bits(&gb, 6);
         if (get_bits1(&gb)) {
-            av_log_missing_feature(avctx, "iframe", 1);
+            avpriv_request_sample(avctx, "iframe");
             return AVERROR_PATCHWELCOME;
         }
         if (get_bits1(&gb)) {
-            av_log_missing_feature(avctx, "Custom palette", 1);
+            avpriv_request_sample(avctx, "Custom palette");
             return AVERROR_PATCHWELCOME;
         }
     }
@@ -276,23 +296,25 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
     /* the block size could change between frames, make sure the buffer
      * is large enough, if not, get a larger one */
     if (s->block_size < s->block_width * s->block_height) {
-        int tmpblock_size = 3 * s->block_width * s->block_height;
+        int tmpblock_size = 3 * s->block_width * s->block_height, err;
 
-        s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
-        if (!s->tmpblock) {
-            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
-            return AVERROR(ENOMEM);
+        if ((err = av_reallocp(&s->tmpblock, tmpblock_size)) < 0) {
+            s->block_size = 0;
+            av_log(avctx, AV_LOG_ERROR,
+                   "Cannot allocate decompression buffer.\n");
+            return err;
         }
         if (s->ver == 2) {
             s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
             if (s->deflate_block_size <= 0) {
-                av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
+                av_log(avctx, AV_LOG_ERROR,
+                       "Cannot determine deflate buffer size.\n");
                 return -1;
             }
-            s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);
-            if (!s->deflate_block) {
-                av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
-                return AVERROR(ENOMEM);
+            if ((err = av_reallocp(&s->deflate_block, s->deflate_block_size)) < 0) {
+                s->block_size = 0;
+                av_log(avctx, AV_LOG_ERROR, "Cannot allocate deflate buffer.\n");
+                return err;
             }
         }
     }
@@ -316,24 +338,22 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
     /* we care for keyframes only in Screen Video v2 */
     s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
     if (s->is_keyframe) {
-        s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
+        int err;
+        if ((err = av_reallocp(&s->keyframedata, avpkt->size)) < 0)
+            return err;
         memcpy(s->keyframedata, avpkt->data, avpkt->size);
-        s->blocks = av_realloc(s->blocks,
-                               (v_blocks + !!v_part) * (h_blocks + !!h_part)
-                               * sizeof(s->blocks[0]));
+        if ((err = av_reallocp(&s->blocks, (v_blocks + !!v_part) *
+                               (h_blocks + !!h_part) * sizeof(s->blocks[0]))) < 0)
+            return err;
     }
 
     av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
             s->image_width, s->image_height, s->block_width, s->block_height,
             h_blocks, v_blocks, h_part, v_part);
 
-    s->frame.reference    = 3;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID    |
-                            FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* loop over all block columns */
@@ -358,8 +378,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
             s->diff_height    = cur_blk_height;
 
             if (8 * size > get_bits_left(&gb)) {
-                avctx->release_buffer(avctx, &s->frame);
-                s->frame.data[0] = NULL;
+                av_frame_unref(s->frame);
                 return AVERROR_INVALIDDATA;
             }
 
@@ -372,18 +391,25 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
 
                 if (s->color_depth != 0 && s->color_depth != 2) {
                     av_log(avctx, AV_LOG_ERROR,
-                           "%dx%d invalid color depth %d\n", i, j, s->color_depth);
+                           "%dx%d invalid color depth %d\n",
+                           i, j, s->color_depth);
                     return AVERROR_INVALIDDATA;
                 }
 
                 if (has_diff) {
                     if (!s->keyframe) {
                         av_log(avctx, AV_LOG_ERROR,
-                               "inter frame without keyframe\n");
+                               "Inter frame without keyframe\n");
                         return AVERROR_INVALIDDATA;
                     }
                     s->diff_start  = get_bits(&gb, 8);
                     s->diff_height = get_bits(&gb, 8);
+                    if (s->diff_start + s->diff_height > cur_blk_height) {
+                        av_log(avctx, AV_LOG_ERROR,
+                               "Block parameters invalid: %d + %d > %d\n",
+                               s->diff_start, s->diff_height, cur_blk_height);
+                        return AVERROR_INVALIDDATA;
+                    }
                     av_log(avctx, AV_LOG_DEBUG,
                            "%dx%d diff start %d height %d\n",
                            i, j, s->diff_start, s->diff_height);
@@ -396,14 +422,15 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
                 if (s->zlibprime_curr) {
                     int col = get_bits(&gb, 8);
                     int row = get_bits(&gb, 8);
-                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
+                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n",
+                           i, j, col, row);
                     size -= 2;
-                    av_log_missing_feature(avctx, "zlibprime_curr", 1);
+                    avpriv_request_sample(avctx, "zlibprime_curr");
                     return AVERROR_PATCHWELCOME;
                 }
                 if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
-                    av_log(avctx, AV_LOG_ERROR, "no data available for zlib "
-                           "priming\n");
+                    av_log(avctx, AV_LOG_ERROR,
+                           "no data available for zlib priming\n");
                     return AVERROR_INVALIDDATA;
                 }
                 size--; // account for flags byte
@@ -411,12 +438,13 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
 
             if (has_diff) {
                 int k;
-                int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
+                int off = (s->image_height - y_pos - 1) * s->frame->linesize[0];
 
-                for (k = 0; k < cur_blk_height; k++)
-                    memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
-                           s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
+                for (k = 0; k < cur_blk_height; k++) {
+                    int x = off - k * s->frame->linesize[0] + x_pos * 3;
+                    memcpy(s->frame->data[0] + x, s->keyframe + x,
                            cur_blk_width * 3);
+                }
             }
 
             /* skip unchanged blocks, which have size 0 */
@@ -432,17 +460,20 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
     }
     if (s->is_keyframe && s->ver == 2) {
         if (!s->keyframe) {
-            s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
+            s->keyframe = av_malloc(s->frame->linesize[0] * avctx->height);
             if (!s->keyframe) {
                 av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
                 return AVERROR(ENOMEM);
             }
         }
-        memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
+        memcpy(s->keyframe, s->frame->data[0],
+               s->frame->linesize[0] * avctx->height);
     }
 
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     if ((get_bits_count(&gb) / 8) != buf_size)
         av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
@@ -452,25 +483,10 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
     return buf_size;
 }
 
-
-static av_cold int flashsv_decode_end(AVCodecContext *avctx)
-{
-    FlashSVContext *s = avctx->priv_data;
-    inflateEnd(&s->zstream);
-    /* release the frame if needed */
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    /* free the tmpblock */
-    av_free(s->tmpblock);
-
-    return 0;
-}
-
-
 #if CONFIG_FLASHSV_DECODER
 AVCodec ff_flashsv_decoder = {
     .name           = "flashsv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FLASHSV,
     .priv_data_size = sizeof(FlashSVContext),
@@ -478,8 +494,7 @@ AVCodec ff_flashsv_decoder = {
     .close          = flashsv_decode_end,
     .decode         = flashsv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
 };
 #endif /* CONFIG_FLASHSV_DECODER */
 
@@ -534,6 +549,7 @@ static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_flashsv2_decoder = {
     .name           = "flashsv2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FLASHSV2,
     .priv_data_size = sizeof(FlashSVContext),
@@ -541,7 +557,6 @@ AVCodec ff_flashsv2_decoder = {
     .close          = flashsv2_decode_end,
     .decode         = flashsv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
 };
 #endif /* CONFIG_FLASHSV2_DECODER */
diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c
index 0b78880..71c81bd 100644
--- a/libavcodec/flashsvenc.c
+++ b/libavcodec/flashsvenc.c
@@ -57,7 +57,6 @@
 typedef struct FlashSVContext {
     AVCodecContext *avctx;
     uint8_t        *previous_frame;
-    AVFrame         frame;
     int             image_width, image_height;
     int             block_width, block_height;
     uint8_t        *tmpblock;
@@ -89,6 +88,21 @@ static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, int dx, int dy,
     return 0;
 }
 
+static av_cold int flashsv_encode_end(AVCodecContext *avctx)
+{
+    FlashSVContext *s = avctx->priv_data;
+
+    deflateEnd(&s->zstream);
+
+    av_free(s->encbuffer);
+    av_free(s->previous_frame);
+    av_free(s->tmpblock);
+
+    av_frame_free(&avctx->coded_frame);
+
+    return 0;
+}
+
 static av_cold int flashsv_encode_init(AVCodecContext *avctx)
 {
     FlashSVContext *s = avctx->priv_data;
@@ -117,11 +131,17 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame) {
+        flashsv_encode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
 
-static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf,
+static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf,
                             int buf_size, int block_width, int block_height,
                             uint8_t *previous_frame, int *I_frame)
 {
@@ -199,14 +219,12 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                 const AVFrame *pict, int *got_packet)
 {
     FlashSVContext * const s = avctx->priv_data;
-    AVFrame * const p = &s->frame;
+    const AVFrame * const p = pict;
     uint8_t *pfptr;
     int res;
     int I_frame = 0;
     int opt_w = 4, opt_h = 4;
 
-    *p = *pict;
-
     /* First frame needs to be a keyframe */
     if (avctx->frame_number == 0) {
         s->previous_frame = av_mallocz(FFABS(p->linesize[0]) * s->image_height);
@@ -248,39 +266,25 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
     //mark the frame type so the muxer can mux it correctly
     if (I_frame) {
-        p->pict_type      = AV_PICTURE_TYPE_I;
-        p->key_frame      = 1;
+        avctx->coded_frame->pict_type      = AV_PICTURE_TYPE_I;
+        avctx->coded_frame->key_frame      = 1;
         s->last_key_frame = avctx->frame_number;
         av_dlog(avctx, "Inserting keyframe at frame %d\n", avctx->frame_number);
     } else {
-        p->pict_type = AV_PICTURE_TYPE_P;
-        p->key_frame = 0;
+        avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
+        avctx->coded_frame->key_frame = 0;
     }
 
-    avctx->coded_frame = p;
-
-    if (p->key_frame)
+    if (avctx->coded_frame->key_frame)
         pkt->flags |= AV_PKT_FLAG_KEY;
     *got_packet = 1;
 
     return 0;
 }
 
-static av_cold int flashsv_encode_end(AVCodecContext *avctx)
-{
-    FlashSVContext *s = avctx->priv_data;
-
-    deflateEnd(&s->zstream);
-
-    av_free(s->encbuffer);
-    av_free(s->previous_frame);
-    av_free(s->tmpblock);
-
-    return 0;
-}
-
 AVCodec ff_flashsv_encoder = {
     .name           = "flashsv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FLASHSV,
     .priv_data_size = sizeof(FlashSVContext),
@@ -288,5 +292,4 @@ AVCodec ff_flashsv_encoder = {
     .encode2        = flashsv_encode_frame,
     .close          = flashsv_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video"),
 };
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 0841335..68f45b4 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -42,6 +42,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "mathops.h"
 
 #define FLI_256_COLOR 4
@@ -65,12 +66,12 @@
     if (pixel_ptr + n > pixel_limit) { \
         av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
         pixel_ptr + n, pixel_limit); \
-        return -1; \
+        return AVERROR_INVALIDDATA; \
     } \
 
 typedef struct FlicDecodeContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     unsigned int palette[256];
     int new_palette;
@@ -116,13 +117,16 @@ static av_cold int flic_decode_init(AVCodecContext *avctx)
         case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
         case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
                   av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n");
-                  return -1;
+                  return AVERROR_PATCHWELCOME;
         default :
                   av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
-                  return -1;
+                  return AVERROR_INVALIDDATA;
     }
 
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     s->new_palette = 0;
 
     return 0;
@@ -147,7 +151,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
     unsigned int chunk_size;
     int chunk_type;
 
-    int i, j;
+    int i, j, ret;
 
     int color_packets;
     int color_changes;
@@ -167,15 +171,13 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
 
     bytestream2_init(&g2, buf, buf_size);
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    pixels = s->frame.data[0];
-    pixel_limit = s->avctx->height * s->frame.linesize[0];
+    pixels = s->frame->data[0];
+    pixel_limit = s->avctx->height * s->frame->linesize[0];
     frame_size = bytestream2_get_le32(&g2);
     bytestream2_skip(&g2, 2); /* skip the magic number */
     num_chunks = bytestream2_get_le16(&g2);
@@ -249,12 +251,12 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
                 if ((line_packets & 0xC000) == 0xC000) {
                     // line skip opcode
                     line_packets = -line_packets;
-                    y_ptr += line_packets * s->frame.linesize[0];
+                    y_ptr += line_packets * s->frame->linesize[0];
                 } else if ((line_packets & 0xC000) == 0x4000) {
                     av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
                 } else if ((line_packets & 0xC000) == 0x8000) {
                     // "last byte" opcode
-                    pixel_ptr= y_ptr + s->frame.linesize[0] - 1;
+                    pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
                     CHECK_PIXEL_PTR(0);
                     pixels[pixel_ptr] = line_packets & 0xff;
                 } else {
@@ -285,7 +287,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
                         }
                     }
 
-                    y_ptr += s->frame.linesize[0];
+                    y_ptr += s->frame->linesize[0];
                 }
             }
             break;
@@ -294,7 +296,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
             /* line compressed */
             starting_line = bytestream2_get_le16(&g2);
             y_ptr = 0;
-            y_ptr += starting_line * s->frame.linesize[0];
+            y_ptr += starting_line * s->frame->linesize[0];
 
             compressed_lines = bytestream2_get_le16(&g2);
             while (compressed_lines > 0) {
@@ -325,7 +327,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
                     }
                 }
 
-                y_ptr += s->frame.linesize[0];
+                y_ptr += s->frame->linesize[0];
                 compressed_lines--;
             }
             break;
@@ -333,7 +335,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
         case FLI_BLACK:
             /* set the whole frame to color 0 (which is usually black) */
             memset(pixels, 0,
-                s->frame.linesize[0] * s->avctx->height);
+                s->frame->linesize[0] * s->avctx->height);
             break;
 
         case FLI_BRUN:
@@ -376,7 +378,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
                     }
                 }
 
-                y_ptr += s->frame.linesize[0];
+                y_ptr += s->frame->linesize[0];
             }
             break;
 
@@ -387,8 +389,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
                        "bigger than image, 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;
-                     y_ptr += s->frame.linesize[0]) {
+                for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
+                     y_ptr += s->frame->linesize[0]) {
                     bytestream2_get_buffer(&g2, &pixels[y_ptr],
                                            s->avctx->width);
                 }
@@ -418,14 +420,16 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
                buf_size - bytestream2_get_bytes_left(&g2));
 
     /* make the palette available on the way out */
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
     if (s->new_palette) {
-        s->frame.palette_has_changed = 1;
+        s->frame->palette_has_changed = 1;
         s->new_palette = 0;
     }
 
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
@@ -448,7 +452,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
     unsigned int chunk_size;
     int chunk_type;
 
-    int i, j;
+    int i, j, ret;
 
     int lines;
     int compressed_lines;
@@ -463,15 +467,13 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
 
     bytestream2_init(&g2, buf, buf_size);
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    pixels = s->frame.data[0];
-    pixel_limit = s->avctx->height * s->frame.linesize[0];
+    pixels = s->frame->data[0];
+    pixel_limit = s->avctx->height * s->frame->linesize[0];
 
     frame_size = bytestream2_get_le32(&g2);
     bytestream2_skip(&g2, 2);  /* skip the magic number */
@@ -505,7 +507,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
                 line_packets = bytestream2_get_le16(&g2);
                 if (line_packets < 0) {
                     line_packets = -line_packets;
-                    y_ptr += line_packets * s->frame.linesize[0];
+                    y_ptr += line_packets * s->frame->linesize[0];
                 } else {
                     compressed_lines--;
                     pixel_ptr = y_ptr;
@@ -534,20 +536,20 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
                         }
                     }
 
-                    y_ptr += s->frame.linesize[0];
+                    y_ptr += s->frame->linesize[0];
                 }
             }
             break;
 
         case FLI_LC:
-            av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
+            av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
             bytestream2_skip(&g2, chunk_size - 6);
             break;
 
         case FLI_BLACK:
             /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
             memset(pixels, 0x0000,
-                   s->frame.linesize[0] * s->avctx->height);
+                   s->frame->linesize[0] * s->avctx->height);
             break;
 
         case FLI_BRUN:
@@ -598,7 +600,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
                     pixel_ptr += 2;
                 }
 #endif
-                y_ptr += s->frame.linesize[0];
+                y_ptr += s->frame->linesize[0];
             }
             break;
 
@@ -638,7 +640,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
                     }
                 }
 
-                y_ptr += s->frame.linesize[0];
+                y_ptr += s->frame->linesize[0];
             }
             break;
 
@@ -651,8 +653,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
                 bytestream2_skip(&g2, chunk_size - 6);
             } else {
 
-                for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
-                     y_ptr += s->frame.linesize[0]) {
+                for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
+                     y_ptr += s->frame->linesize[0]) {
 
                     pixel_countdown = s->avctx->width;
                     pixel_ptr = 0;
@@ -685,9 +687,10 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
                "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
 
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
@@ -697,7 +700,7 @@ static int flic_decode_frame_24BPP(AVCodecContext *avctx,
                                    const uint8_t *buf, int buf_size)
 {
   av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
-  return -1;
+  return AVERROR_PATCHWELCOME;
 }
 
 static int flic_decode_frame(AVCodecContext *avctx,
@@ -725,7 +728,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
     /* the finite set of possibilites allowable by here. */
     /* But in case we do, just error out. */
     av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
-    return -1;
+    return AVERROR_BUG;
 }
 
 
@@ -733,14 +736,14 @@ static av_cold int flic_decode_end(AVCodecContext *avctx)
 {
     FlicDecodeContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_flic_decoder = {
     .name           = "flic",
+    .long_name      = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FLIC,
     .priv_data_size = sizeof(FlicDecodeContext),
@@ -748,5 +751,4 @@ AVCodec ff_flic_decoder = {
     .close          = flic_decode_end,
     .decode         = flic_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
 };
diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index 3640d29..665208a 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -121,6 +121,7 @@ int ff_flv_decode_picture_header(MpegEncContext *s)
 
 AVCodec ff_flv_decoder = {
     .name           = "flv",
+    .long_name      = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FLV1,
     .priv_data_size = sizeof(MpegEncContext),
@@ -128,6 +129,5 @@ AVCodec ff_flv_decoder = {
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
-    .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..fbdb23d 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -88,6 +88,7 @@ FF_MPV_GENERIC_CLASS(flv)
 
 AVCodec ff_flv_encoder = {
     .name           = "flv",
+    .long_name      = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FLV1,
     .priv_data_size = sizeof(MpegEncContext),
@@ -95,6 +96,5 @@ AVCodec ff_flv_encoder = {
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
     .priv_class     = &flv_class,
 };
diff --git a/libavcodec/fmtconvert.c b/libavcodec/fmtconvert.c
index 642e1d2..63f62c3 100644
--- a/libavcodec/fmtconvert.c
+++ b/libavcodec/fmtconvert.c
@@ -24,12 +24,23 @@
 #include "fmtconvert.h"
 #include "libavutil/common.h"
 
-static void int32_to_float_fmul_scalar_c(float *dst, const int *src, float mul, int len){
+static void int32_to_float_fmul_scalar_c(float *dst, const int32_t *src,
+                                         float mul, int len)
+{
     int i;
     for(i=0; i<len; i++)
         dst[i] = src[i] * mul;
 }
 
+static void int32_to_float_fmul_array8_c(FmtConvertContext *c, float *dst,
+                                         const int32_t *src, const float *mul,
+                                         int len)
+{
+    int i;
+    for (i = 0; i < len; i += 8)
+        c->int32_to_float_fmul_scalar(&dst[i], &src[i], *mul++, 8);
+}
+
 static av_always_inline int float_to_int16_one(const float *src){
     return av_clip_int16(lrintf(*src));
 }
@@ -79,11 +90,12 @@ void ff_float_interleave_c(float *dst, const float **src, unsigned int len,
 av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx)
 {
     c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c;
+    c->int32_to_float_fmul_array8 = int32_to_float_fmul_array8_c;
     c->float_to_int16             = float_to_int16_c;
     c->float_to_int16_interleave  = float_to_int16_interleave_c;
     c->float_interleave           = ff_float_interleave_c;
 
     if (ARCH_ARM) ff_fmt_convert_init_arm(c, avctx);
-    if (HAVE_ALTIVEC) ff_fmt_convert_init_altivec(c, avctx);
+    if (ARCH_PPC) ff_fmt_convert_init_ppc(c, avctx);
     if (ARCH_X86) ff_fmt_convert_init_x86(c, avctx);
 }
diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h
index b879ee6..bd833ef 100644
--- a/libavcodec/fmtconvert.h
+++ b/libavcodec/fmtconvert.h
@@ -35,7 +35,24 @@ typedef struct FmtConvertContext {
      * @param len number of elements to convert.
      *            constraints: multiple of 8
      */
-    void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len);
+    void (*int32_to_float_fmul_scalar)(float *dst, const int32_t *src,
+                                       float mul, int len);
+
+    /**
+     * Convert an array of int32_t to float and multiply by a float value from another array,
+     * stepping along the float array once for each 8 integers.
+     * @param c   pointer to FmtConvertContext.
+     * @param dst destination array of float.
+     *            constraints: 16-byte aligned
+     * @param src source array of int32_t.
+     *            constraints: 16-byte aligned
+     * @param mul source array of float multipliers.
+     * @param len number of elements to convert.
+     *            constraints: multiple of 8
+     */
+    void (*int32_to_float_fmul_array8)(struct FmtConvertContext *c,
+                                       float *dst, const int32_t *src,
+                                       const float *mul, int len);
 
     /**
      * Convert an array of float to an array of int16_t.
@@ -87,10 +104,10 @@ typedef struct FmtConvertContext {
 void ff_float_interleave_c(float *dst, const float **src, unsigned int len,
                            int channels);
 
-av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx);
+void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx);
 
 void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx);
-void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx);
+void ff_fmt_convert_init_ppc(FmtConvertContext *c, AVCodecContext *avctx);
 void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx);
 
 #endif /* AVCODEC_FMTCONVERT_H */
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index a691d9e..f12e4e0 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -36,15 +36,16 @@
 #include "huffman.h"
 #include "bytestream.h"
 #include "dsputil.h"
+#include "internal.h"
 
 #define FPS_TAG MKTAG('F', 'P', 'S', 'x')
 
 /**
  * local variable storage
  */
-typedef struct FrapsContext{
+typedef struct FrapsContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
     uint8_t *tmpbuf;
     int tmpbuf_size;
     DSPContext dsp;
@@ -60,12 +61,15 @@ static av_cold int decode_init(AVCodecContext *avctx)
 {
     FrapsContext * const s = avctx->priv_data;
 
-    avctx->coded_frame = &s->frame;
-    avctx->pix_fmt= AV_PIX_FMT_NONE; /* set in decode_frame */
+    avctx->pix_fmt     = AV_PIX_FMT_NONE; /* set in decode_frame */
 
-    s->avctx = avctx;
+    s->avctx  = avctx;
     s->tmpbuf = NULL;
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     ff_dsputil_init(&s->dsp, avctx);
 
     return 0;
@@ -75,7 +79,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
  * Comparator - our nodes should ascend by count
  * but with preserved symbol order
  */
-static int huff_cmp(const void *va, const void *vb){
+static int huff_cmp(const void *va, const void *vb)
+{
     const Node *a = va, *b = vb;
     return (a->count - b->count)*256 + a->sym - b->sym;
 }
@@ -87,31 +92,33 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w,
                                int h, const uint8_t *src, int size, int Uoff,
                                const int step)
 {
-    int i, j;
+    int i, j, ret;
     GetBitContext gb;
     VLC vlc;
     Node nodes[512];
 
-    for(i = 0; i < 256; i++)
+    for (i = 0; i < 256; i++)
         nodes[i].count = bytestream_get_le32(&src);
     size -= 1024;
-    if (ff_huff_build_tree(s->avctx, &vlc, 256, nodes, huff_cmp,
-                           FF_HUFFMAN_FLAG_ZERO_COUNT) < 0)
-        return -1;
+    if ((ret = ff_huff_build_tree(s->avctx, &vlc, 256, nodes, huff_cmp,
+                                  FF_HUFFMAN_FLAG_ZERO_COUNT)) < 0)
+        return ret;
     /* we have built Huffman table and are ready to decode plane */
 
     /* convert bits so they may be used by standard bitreader */
     s->dsp.bswap_buf((uint32_t *)s->tmpbuf, (const uint32_t *)src, size >> 2);
 
     init_get_bits(&gb, s->tmpbuf, size * 8);
-    for(j = 0; j < h; j++){
-        for(i = 0; i < w*step; i += step){
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < w*step; i += step) {
             dst[i] = get_vlc2(&gb, vlc.table, 9, 3);
             /* lines are stored as deltas between previous lines
              * and we need to add 0x80 to the first lines of chroma planes
              */
-            if(j) dst[i] += dst[i - stride];
-            else if(Uoff) dst[i] += 0x80;
+            if (j)
+                dst[i] += dst[i - stride];
+            else if (Uoff)
+                dst[i] += 0x80;
             if (get_bits_left(&gb) < 0) {
                 ff_free_vlc(&vlc);
                 return AVERROR_INVALIDDATA;
@@ -127,18 +134,18 @@ static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     FrapsContext * const s = avctx->priv_data;
-    AVFrame *frame = data;
-    AVFrame * const f = &s->frame;
+    const uint8_t *buf     = avpkt->data;
+    int buf_size           = avpkt->size;
+    AVFrame *frame         = data;
+    AVFrame * const f      = s->frame;
     uint32_t header;
     unsigned int version,header_size;
     unsigned int x, y;
     const uint32_t *buf32;
     uint32_t *luma1,*luma2,*cb,*cr;
     uint32_t offs[4];
-    int i, j, is_chroma, planes;
+    int i, j, ret, is_chroma, planes;
     enum AVPixelFormat pix_fmt;
     int prev_pic_bit, expected_size;
 
@@ -147,8 +154,8 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
-    header = AV_RL32(buf);
-    version = header & 0xff;
+    header      = AV_RL32(buf);
+    version     = header & 0xff;
     header_size = (header & (1<<30))? 8 : 4; /* bit 30 means pad to 8 bytes */
     prev_pic_bit = header & (1U << 31); /* bit 31 means same as previous pic */
 
@@ -156,16 +163,16 @@ static int decode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR,
                "This file is encoded with Fraps version %d. " \
                "This codec can only decode versions <= 5.\n", version);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
-    buf+=4;
+    buf += 4;
     if (header_size == 8)
-        buf+=4;
+        buf += 4;
 
     pix_fmt = version & 1 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P;
     if (avctx->pix_fmt != pix_fmt && f->data[0]) {
-        avctx->release_buffer(avctx, f);
+        av_frame_unref(f);
     }
     avctx->pix_fmt = pix_fmt;
 
@@ -184,31 +191,27 @@ static int decode_frame(AVCodecContext *avctx,
             return AVERROR_INVALIDDATA;
         }
 
-        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;
+            return AVERROR_INVALIDDATA;
         }
 
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if (avctx->reget_buffer(avctx, f)) {
+        if ((ret = ff_reget_buffer(avctx, f)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
+            return ret;
         }
         f->pict_type = prev_pic_bit ? 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){
+            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++);
@@ -231,22 +234,18 @@ static int decode_frame(AVCodecContext *avctx,
             return AVERROR_INVALIDDATA;
         }
 
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if (avctx->reget_buffer(avctx, f)) {
+        if ((ret = ff_reget_buffer(avctx, f)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
+            return ret;
         }
         f->pict_type = prev_pic_bit ? 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 -1) * f->linesize[0]],
-                       &buf[y*avctx->width*3],
-                       3*avctx->width);
+            for (y = 0; y<avctx->height; y++)
+                memcpy(&f->data[0][(avctx->height - y - 1) * f->linesize[0]],
+                       &buf[y * avctx->width * 3],
+                       3 * avctx->width);
         }
         break;
 
@@ -257,44 +256,43 @@ static int decode_frame(AVCodecContext *avctx,
          * 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)) {
+        if ((ret = ff_reget_buffer(avctx, f)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
+            return ret;
         }
         /* skip frame */
-        if(buf_size == 8) {
+        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))) {
+        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;
+            return AVERROR_INVALIDDATA;
         }
-        for(i = 0; i < planes; i++) {
+        for (i = 0; i < planes; i++) {
             offs[i] = AV_RL32(buf + 4 + i * 4);
-            if(offs[i] >= buf_size || (i && offs[i] <= offs[i - 1] + 1024)) {
+            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;
+                return AVERROR_INVALIDDATA;
             }
         }
         offs[planes] = buf_size;
-        for(i = 0; i < planes; i++){
+        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) {
+            if ((ret = fraps2_decode_plane(s, f->data[i], f->linesize[i],
+                                           avctx->width  >> is_chroma,
+                                           avctx->height >> is_chroma,
+                                           buf + offs[i], offs[i + 1] - offs[i],
+                                           is_chroma, 1)) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
-                return -1;
+                return ret;
             }
         }
         break;
@@ -302,16 +300,12 @@ static int decode_frame(AVCodecContext *avctx,
     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)) {
+        if ((ret = ff_reget_buffer(avctx, f)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
+            return ret;
         }
         /* skip frame */
-        if(buf_size == 8) {
+        if (buf_size == 8) {
             f->pict_type = AV_PICTURE_TYPE_P;
             f->key_frame = 0;
             break;
@@ -320,30 +314,31 @@ static int decode_frame(AVCodecContext *avctx,
         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;
+            return AVERROR_INVALIDDATA;
         }
-        for(i = 0; i < planes; i++) {
+        for (i = 0; i < planes; i++) {
             offs[i] = AV_RL32(buf + 4 + i * 4);
-            if(offs[i] >= buf_size || (i && offs[i] <= offs[i - 1] + 1024)) {
+            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;
+                return AVERROR_INVALIDDATA;
             }
         }
         offs[planes] = buf_size;
-        for(i = 0; i < planes; i++){
+        for (i = 0; i < planes; i++) {
             av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size,
                                   offs[i + 1] - offs[i] - 1024);
             if (!s->tmpbuf)
                 return AVERROR(ENOMEM);
-            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) {
+            if ((ret = fraps2_decode_plane(s, f->data[0] + i + (f->linesize[0] * (avctx->height - 1)),
+                                           -f->linesize[0], avctx->width, avctx->height,
+                                           buf + offs[i], offs[i + 1] - offs[i], 0, 3)) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
-                return -1;
+                return ret;
             }
         }
         // convert pseudo-YUV into real RGB
-        for(j = 0; j < avctx->height; j++){
-            for(i = 0; i < avctx->width; i++){
+        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]];
             }
@@ -351,7 +346,8 @@ static int decode_frame(AVCodecContext *avctx,
         break;
     }
 
-    *frame = *f;
+    if ((ret = av_frame_ref(frame, f)) < 0)
+        return ret;
     *got_frame = 1;
 
     return buf_size;
@@ -367,8 +363,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     FrapsContext *s = (FrapsContext*)avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     av_freep(&s->tmpbuf);
     return 0;
@@ -377,6 +372,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
 AVCodec ff_fraps_decoder = {
     .name           = "fraps",
+    .long_name      = NULL_IF_CONFIG_SMALL("Fraps"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FRAPS,
     .priv_data_size = sizeof(FrapsContext),
@@ -384,5 +380,4 @@ AVCodec ff_fraps_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Fraps"),
 };
diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c
index 3f8f6ba..568b94f 100644
--- a/libavcodec/frwu.c
+++ b/libavcodec/frwu.c
@@ -32,10 +32,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     }
     avctx->pix_fmt = AV_PIX_FMT_UYVY422;
 
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
     return 0;
 }
 
@@ -43,13 +39,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     int field, ret;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = buf + avpkt->size;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < avctx->width * 2 * avctx->height + 4 + 2*8) {
         av_log(avctx, AV_LOG_ERROR, "Packet is too small.\n");
         return AVERROR_INVALIDDATA;
@@ -59,8 +52,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    pic->reference = 0;
-    if ((ret = ff_get_buffer(avctx, pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -98,28 +90,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = *pic;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_frwu_decoder = {
     .name           = "frwu",
+    .long_name      = NULL_IF_CONFIG_SMALL("Forward Uncompressed"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FRWU,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Forward Uncompressed"),
 };
diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c
new file mode 100644
index 0000000..0b36dbd
--- /dev/null
+++ b/libavcodec/g2meet.c
@@ -0,0 +1,868 @@
+/*
+ * Go2Webinar decoder
+ * 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
+ */
+
+/**
+ * @file
+ * Go2Webinar decoder
+ */
+
+#include <zlib.h>
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "dsputil.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "mjpeg.h"
+
+enum ChunkType {
+    FRAME_INFO = 0xC8,
+    TILE_DATA,
+    CURSOR_POS,
+    CURSOR_SHAPE,
+    CHUNK_CC,
+    CHUNK_CD
+};
+
+enum Compression {
+    COMPR_EPIC_J_B = 2,
+    COMPR_KEMPF_J_B,
+};
+
+static const uint8_t luma_quant[64] = {
+     8,  6,  5,  8, 12, 20, 26, 31,
+     6,  6,  7, 10, 13, 29, 30, 28,
+     7,  7,  8, 12, 20, 29, 35, 28,
+     7,  9, 11, 15, 26, 44, 40, 31,
+     9, 11, 19, 28, 34, 55, 52, 39,
+    12, 18, 28, 32, 41, 52, 57, 46,
+    25, 32, 39, 44, 52, 61, 60, 51,
+    36, 46, 48, 49, 56, 50, 52, 50
+};
+
+static const uint8_t chroma_quant[64] = {
+     9,  9, 12, 24, 50, 50, 50, 50,
+     9, 11, 13, 33, 50, 50, 50, 50,
+    12, 13, 28, 50, 50, 50, 50, 50,
+    24, 33, 50, 50, 50, 50, 50, 50,
+    50, 50, 50, 50, 50, 50, 50, 50,
+    50, 50, 50, 50, 50, 50, 50, 50,
+    50, 50, 50, 50, 50, 50, 50, 50,
+    50, 50, 50, 50, 50, 50, 50, 50,
+};
+
+typedef struct JPGContext {
+    DSPContext dsp;
+    ScanTable  scantable;
+
+    VLC        dc_vlc[2], ac_vlc[2];
+    int        prev_dc[3];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
+
+    uint8_t    *buf;
+} JPGContext;
+
+typedef struct G2MContext {
+    JPGContext jc;
+    int        version;
+
+    int        compression;
+    int        width, height, bpp;
+    int        tile_width, tile_height;
+    int        tiles_x, tiles_y, tile_x, tile_y;
+
+    int        got_header;
+
+    uint8_t    *framebuf;
+    int        framebuf_stride, old_width, old_height;
+
+    uint8_t    *synth_tile, *jpeg_tile;
+    int        tile_stride, old_tile_w, old_tile_h;
+
+    uint8_t    *kempf_buf, *kempf_flags;
+
+    uint8_t    *cursor;
+    int        cursor_stride;
+    int        cursor_fmt;
+    int        cursor_w, cursor_h, cursor_x, cursor_y;
+    int        cursor_hot_x, cursor_hot_y;
+} G2MContext;
+
+static av_cold int build_vlc(VLC *vlc, const uint8_t *bits_table,
+                             const uint8_t *val_table, int nb_codes,
+                             int is_ac)
+{
+    uint8_t  huff_size[256] = { 0 };
+    uint16_t huff_code[256];
+    uint16_t huff_sym[256];
+    int i;
+
+    ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table);
+
+    for (i = 0; i < 256; i++)
+        huff_sym[i] = i + 16 * is_ac;
+
+    if (is_ac)
+        huff_sym[0] = 16 * 256;
+
+    return ff_init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1,
+                              huff_code, 2, 2, huff_sym, 2, 2, 0);
+}
+
+static av_cold int jpg_init(AVCodecContext *avctx, JPGContext *c)
+{
+    int ret;
+
+    ret = build_vlc(&c->dc_vlc[0], avpriv_mjpeg_bits_dc_luminance,
+                    avpriv_mjpeg_val_dc, 12, 0);
+    if (ret)
+        return ret;
+    ret = build_vlc(&c->dc_vlc[1], avpriv_mjpeg_bits_dc_chrominance,
+                    avpriv_mjpeg_val_dc, 12, 0);
+    if (ret)
+        return ret;
+    ret = build_vlc(&c->ac_vlc[0], avpriv_mjpeg_bits_ac_luminance,
+                    avpriv_mjpeg_val_ac_luminance, 251, 1);
+    if (ret)
+        return ret;
+    ret = build_vlc(&c->ac_vlc[1], avpriv_mjpeg_bits_ac_chrominance,
+                    avpriv_mjpeg_val_ac_chrominance, 251, 1);
+    if (ret)
+        return ret;
+
+    ff_dsputil_init(&c->dsp, avctx);
+    ff_init_scantable(c->dsp.idct_permutation, &c->scantable,
+                      ff_zigzag_direct);
+
+    return 0;
+}
+
+static av_cold void jpg_free_context(JPGContext *ctx)
+{
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        ff_free_vlc(&ctx->dc_vlc[i]);
+        ff_free_vlc(&ctx->ac_vlc[i]);
+    }
+
+    av_freep(&ctx->buf);
+}
+
+static void jpg_unescape(const uint8_t *src, int src_size,
+                         uint8_t *dst, int *dst_size)
+{
+    const uint8_t *src_end = src + src_size;
+    uint8_t *dst_start = dst;
+
+    while (src < src_end) {
+        uint8_t x = *src++;
+
+        *dst++ = x;
+
+        if (x == 0xFF && !*src)
+            src++;
+    }
+    *dst_size = dst - dst_start;
+}
+
+static int jpg_decode_block(JPGContext *c, GetBitContext *gb,
+                            int plane, int16_t *block)
+{
+    int dc, val, pos;
+    const int is_chroma = !!plane;
+    const uint8_t *qmat = is_chroma ? chroma_quant : luma_quant;
+
+    c->dsp.clear_block(block);
+    dc = get_vlc2(gb, c->dc_vlc[is_chroma].table, 9, 3);
+    if (dc < 0)
+        return AVERROR_INVALIDDATA;
+    if (dc)
+        dc = get_xbits(gb, dc);
+    dc = dc * qmat[0] + c->prev_dc[plane];
+    block[0] = dc;
+    c->prev_dc[plane] = dc;
+
+    pos = 0;
+    while (pos < 63) {
+        val = get_vlc2(gb, c->ac_vlc[is_chroma].table, 9, 3);
+        if (val < 0)
+            return AVERROR_INVALIDDATA;
+        pos += val >> 4;
+        val &= 0xF;
+        if (pos > 63)
+            return val ? AVERROR_INVALIDDATA : 0;
+        if (val) {
+            int nbits = val;
+
+            val = get_xbits(gb, nbits);
+            val *= qmat[ff_zigzag_direct[pos]];
+            block[c->scantable.permutated[pos]] = val;
+        }
+    }
+    return 0;
+}
+
+static inline void yuv2rgb(uint8_t *out, int Y, int U, int V)
+{
+    out[0] = av_clip_uint8(Y + (             91881 * V + 32768 >> 16));
+    out[1] = av_clip_uint8(Y + (-22554 * U - 46802 * V + 32768 >> 16));
+    out[2] = av_clip_uint8(Y + (116130 * U             + 32768 >> 16));
+}
+
+static int jpg_decode_data(JPGContext *c, int width, int height,
+                           const uint8_t *src, int src_size,
+                           uint8_t *dst, int dst_stride,
+                           const uint8_t *mask, int mask_stride, int num_mbs,
+                           int swapuv)
+{
+    GetBitContext gb;
+    int mb_w, mb_h, mb_x, mb_y, i, j;
+    int bx, by;
+    int unesc_size;
+    int ret;
+
+    if ((ret = av_reallocp(&c->buf,
+                           src_size + FF_INPUT_BUFFER_PADDING_SIZE)) < 0)
+        return ret;
+    jpg_unescape(src, src_size, c->buf, &unesc_size);
+    memset(c->buf + unesc_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    init_get_bits(&gb, c->buf, unesc_size * 8);
+
+    width = FFALIGN(width, 16);
+    mb_w  =  width        >> 4;
+    mb_h  = (height + 15) >> 4;
+
+    if (!num_mbs)
+        num_mbs = mb_w * mb_h;
+
+    for (i = 0; i < 3; i++)
+        c->prev_dc[i] = 1024;
+    bx = by = 0;
+    for (mb_y = 0; mb_y < mb_h; mb_y++) {
+        for (mb_x = 0; mb_x < mb_w; mb_x++) {
+            if (mask && !mask[mb_x]) {
+                bx += 16;
+                continue;
+            }
+            for (j = 0; j < 2; j++) {
+                for (i = 0; i < 2; i++) {
+                    if ((ret = jpg_decode_block(c, &gb, 0,
+                                                c->block[i + j * 2])) != 0)
+                        return ret;
+                    c->dsp.idct(c->block[i + j * 2]);
+                }
+            }
+            for (i = 1; i < 3; i++) {
+                if ((ret = jpg_decode_block(c, &gb, i, c->block[i + 3])) != 0)
+                    return ret;
+                c->dsp.idct(c->block[i + 3]);
+            }
+
+            for (j = 0; j < 16; j++) {
+                uint8_t *out = dst + bx * 3 + (by + j) * dst_stride;
+                for (i = 0; i < 16; i++) {
+                    int Y, U, V;
+
+                    Y = c->block[(j >> 3) * 2 + (i >> 3)][(i & 7) + (j & 7) * 8];
+                    U = c->block[4 ^ swapuv][(i >> 1) + (j >> 1) * 8] - 128;
+                    V = c->block[5 ^ swapuv][(i >> 1) + (j >> 1) * 8] - 128;
+                    yuv2rgb(out + i * 3, Y, U, V);
+                }
+            }
+
+            if (!--num_mbs)
+                return 0;
+            bx += 16;
+        }
+        bx  = 0;
+        by += 16;
+        if (mask)
+            mask += mask_stride;
+    }
+
+    return 0;
+}
+
+static void kempf_restore_buf(const uint8_t *src, int len,
+                              uint8_t *dst, int stride,
+                              const uint8_t *jpeg_tile, int tile_stride,
+                              int width, int height,
+                              const uint8_t *pal, int npal, int tidx)
+{
+    GetBitContext gb;
+    int i, j, nb, col;
+
+    init_get_bits(&gb, src, len * 8);
+
+    if (npal <= 2)       nb = 1;
+    else if (npal <= 4)  nb = 2;
+    else if (npal <= 16) nb = 4;
+    else                 nb = 8;
+
+    for (j = 0; j < height; j++, dst += stride, jpeg_tile += tile_stride) {
+        if (get_bits(&gb, 8))
+            continue;
+        for (i = 0; i < width; i++) {
+            col = get_bits(&gb, nb);
+            if (col != tidx)
+                memcpy(dst + i * 3, pal + col * 3, 3);
+            else
+                memcpy(dst + i * 3, jpeg_tile + i * 3, 3);
+        }
+    }
+}
+
+static int kempf_decode_tile(G2MContext *c, int tile_x, int tile_y,
+                             const uint8_t *src, int src_size)
+{
+    int width, height;
+    int hdr, zsize, npal, tidx = -1, ret;
+    int i, j;
+    const uint8_t *src_end = src + src_size;
+    uint8_t pal[768], transp[3];
+    uLongf dlen = (c->tile_width + 1) * c->tile_height;
+    int sub_type;
+    int nblocks, cblocks, bstride;
+    int bits, bitbuf, coded;
+    uint8_t *dst = c->framebuf + tile_x * c->tile_width * 3 +
+                   tile_y * c->tile_height * c->framebuf_stride;
+
+    if (src_size < 2)
+        return AVERROR_INVALIDDATA;
+
+    width  = FFMIN(c->width  - tile_x * c->tile_width,  c->tile_width);
+    height = FFMIN(c->height - tile_y * c->tile_height, c->tile_height);
+
+    hdr = *src++;
+    sub_type = hdr >> 5;
+    if (sub_type == 0) {
+        int j;
+        memcpy(transp, src, 3);
+        src += 3;
+        for (j = 0; j < height; j++, dst += c->framebuf_stride)
+            for (i = 0; i < width; i++)
+                memcpy(dst + i * 3, transp, 3);
+        return 0;
+    } else if (sub_type == 1) {
+        return jpg_decode_data(&c->jc, width, height, src, src_end - src,
+                               dst, c->framebuf_stride, NULL, 0, 0, 0);
+    }
+
+    if (sub_type != 2) {
+        memcpy(transp, src, 3);
+        src += 3;
+    }
+    npal = *src++ + 1;
+    memcpy(pal, src, npal * 3); src += npal * 3;
+    if (sub_type != 2) {
+        for (i = 0; i < npal; i++) {
+            if (!memcmp(pal + i * 3, transp, 3)) {
+               tidx = i;
+               break;
+            }
+        }
+    }
+
+    if (src_end - src < 2)
+        return 0;
+    zsize = (src[0] << 8) | src[1]; src += 2;
+
+    if (src_end - src < zsize)
+        return AVERROR_INVALIDDATA;
+
+    ret = uncompress(c->kempf_buf, &dlen, src, zsize);
+    if (ret)
+        return AVERROR_INVALIDDATA;
+    src += zsize;
+
+    if (sub_type == 2) {
+        kempf_restore_buf(c->kempf_buf, dlen, dst, c->framebuf_stride,
+                          NULL, 0, width, height, pal, npal, tidx);
+        return 0;
+    }
+
+    nblocks = *src++ + 1;
+    cblocks = 0;
+    bstride = FFALIGN(width, 16) >> 4;
+    // blocks are coded LSB and we need normal bitreader for JPEG data
+    bits = 0;
+    for (i = 0; i < (FFALIGN(height, 16) >> 4); i++) {
+        for (j = 0; j < (FFALIGN(width, 16) >> 4); j++) {
+            if (!bits) {
+                bitbuf = *src++;
+                bits   = 8;
+            }
+            coded = bitbuf & 1;
+            bits--;
+            bitbuf >>= 1;
+            cblocks += coded;
+            if (cblocks > nblocks)
+                return AVERROR_INVALIDDATA;
+            c->kempf_flags[j + i * bstride] = coded;
+        }
+    }
+
+    memset(c->jpeg_tile, 0, c->tile_stride * height);
+    jpg_decode_data(&c->jc, width, height, src, src_end - src,
+                    c->jpeg_tile, c->tile_stride,
+                    c->kempf_flags, bstride, nblocks, 0);
+
+    kempf_restore_buf(c->kempf_buf, dlen, dst, c->framebuf_stride,
+                      c->jpeg_tile, c->tile_stride,
+                      width, height, pal, npal, tidx);
+
+    return 0;
+}
+
+static int g2m_init_buffers(G2MContext *c)
+{
+    int aligned_height;
+
+    if (!c->framebuf || c->old_width < c->width || c->old_height < c->height) {
+        c->framebuf_stride = FFALIGN(c->width * 3, 16);
+        aligned_height     = FFALIGN(c->height,    16);
+        av_free(c->framebuf);
+        c->framebuf = av_mallocz(c->framebuf_stride * aligned_height);
+        if (!c->framebuf)
+            return AVERROR(ENOMEM);
+    }
+    if (!c->synth_tile || !c->jpeg_tile ||
+        c->old_tile_w < c->tile_width ||
+        c->old_tile_h < c->tile_height) {
+        c->tile_stride = FFALIGN(c->tile_width * 3, 16);
+        aligned_height = FFALIGN(c->tile_height,    16);
+        av_free(c->synth_tile);
+        av_free(c->jpeg_tile);
+        av_free(c->kempf_buf);
+        av_free(c->kempf_flags);
+        c->synth_tile  = av_mallocz(c->tile_stride      * aligned_height);
+        c->jpeg_tile   = av_mallocz(c->tile_stride      * aligned_height);
+        c->kempf_buf   = av_mallocz((c->tile_width + 1) * aligned_height
+                                    + FF_INPUT_BUFFER_PADDING_SIZE);
+        c->kempf_flags = av_mallocz( c->tile_width      * aligned_height);
+        if (!c->synth_tile || !c->jpeg_tile ||
+            !c->kempf_buf || !c->kempf_flags)
+            return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int g2m_load_cursor(AVCodecContext *avctx, G2MContext *c,
+                           GetByteContext *gb)
+{
+    int i, j, k;
+    uint8_t *dst;
+    uint32_t bits;
+    uint32_t cur_size, cursor_w, cursor_h, cursor_stride;
+    uint32_t cursor_hot_x, cursor_hot_y;
+    int cursor_fmt, err;
+
+    cur_size      = bytestream2_get_be32(gb);
+    cursor_w      = bytestream2_get_byte(gb);
+    cursor_h      = bytestream2_get_byte(gb);
+    cursor_hot_x  = bytestream2_get_byte(gb);
+    cursor_hot_y  = bytestream2_get_byte(gb);
+    cursor_fmt    = bytestream2_get_byte(gb);
+
+    cursor_stride = FFALIGN(cursor_w, 32) * 4;
+
+    if (cursor_w < 1 || cursor_w > 256 ||
+        cursor_h < 1 || cursor_h > 256) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid cursor dimensions %dx%d\n",
+               cursor_w, cursor_h);
+        return AVERROR_INVALIDDATA;
+    }
+    if (cursor_hot_x > cursor_w || cursor_hot_y > cursor_h) {
+        av_log(avctx, AV_LOG_WARNING, "Invalid hotspot position %d,%d\n",
+               cursor_hot_x, cursor_hot_y);
+        cursor_hot_x = FFMIN(cursor_hot_x, cursor_w - 1);
+        cursor_hot_y = FFMIN(cursor_hot_y, cursor_h - 1);
+    }
+    if (cur_size - 9 > bytestream2_get_bytes_left(gb) ||
+        c->cursor_w * c->cursor_h / 4 > cur_size) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d/%d\n",
+               cur_size, bytestream2_get_bytes_left(gb));
+        return AVERROR_INVALIDDATA;
+    }
+    if (cursor_fmt != 1 && cursor_fmt != 32) {
+        avpriv_report_missing_feature(avctx, "Cursor format %d",
+                                      cursor_fmt);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if ((err = av_reallocp(&c->cursor, cursor_stride * cursor_h)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Cannot allocate cursor buffer\n");
+        return err;
+    }
+
+    c->cursor_w      = cursor_w;
+    c->cursor_h      = cursor_h;
+    c->cursor_hot_x  = cursor_hot_x;
+    c->cursor_hot_y  = cursor_hot_y;
+    c->cursor_fmt    = cursor_fmt;
+    c->cursor_stride = cursor_stride;
+
+    dst = c->cursor;
+    switch (c->cursor_fmt) {
+    case 1: // old monochrome
+        for (j = 0; j < c->cursor_h; j++) {
+            for (i = 0; i < c->cursor_w; i += 32) {
+                bits = bytestream2_get_be32(gb);
+                for (k = 0; k < 32; k++) {
+                    dst[0] = !!(bits & 0x80000000);
+                    dst += 4;
+                    bits <<= 1;
+                }
+            }
+            dst += c->cursor_stride - c->cursor_w * 4;
+        }
+
+        dst = c->cursor;
+        for (j = 0; j < c->cursor_h; j++) {
+            for (i = 0; i < c->cursor_w; i += 32) {
+                bits = bytestream2_get_be32(gb);
+                for (k = 0; k < 32; k++) {
+                    int mask_bit = !!(bits & 0x80000000);
+                    switch (dst[0] * 2 + mask_bit) {
+                    case 0:
+                        dst[0] = 0xFF; dst[1] = 0x00;
+                        dst[2] = 0x00; dst[3] = 0x00;
+                        break;
+                    case 1:
+                        dst[0] = 0xFF; dst[1] = 0xFF;
+                        dst[2] = 0xFF; dst[3] = 0xFF;
+                        break;
+                    default:
+                        dst[0] = 0x00; dst[1] = 0x00;
+                        dst[2] = 0x00; dst[3] = 0x00;
+                    }
+                    dst += 4;
+                    bits <<= 1;
+                }
+            }
+            dst += c->cursor_stride - c->cursor_w * 4;
+        }
+        break;
+    case 32: // full colour
+        /* skip monochrome version of the cursor and decode RGBA instead */
+        bytestream2_skip(gb, c->cursor_h * (FFALIGN(c->cursor_w, 32) >> 3));
+        for (j = 0; j < c->cursor_h; j++) {
+            for (i = 0; i < c->cursor_w; i++) {
+                int val = bytestream2_get_be32(gb);
+                *dst++ = val >>  0;
+                *dst++ = val >>  8;
+                *dst++ = val >> 16;
+                *dst++ = val >> 24;
+            }
+            dst += c->cursor_stride - c->cursor_w * 4;
+        }
+        break;
+    default:
+        return AVERROR_PATCHWELCOME;
+    }
+    return 0;
+}
+
+#define APPLY_ALPHA(src, new, alpha) \
+    src = (src * (256 - alpha) + new * alpha) >> 8
+
+static void g2m_paint_cursor(G2MContext *c, uint8_t *dst, int stride)
+{
+    int i, j;
+    int x, y, w, h;
+    const uint8_t *cursor;
+
+    if (!c->cursor)
+        return;
+
+    x = c->cursor_x - c->cursor_hot_x;
+    y = c->cursor_y - c->cursor_hot_y;
+
+    cursor = c->cursor;
+    w      = c->cursor_w;
+    h      = c->cursor_h;
+
+    if (x + w > c->width)
+        w = c->width - x;
+    if (y + h > c->height)
+        h = c->height - y;
+    if (x < 0) {
+        w      +=  x;
+        cursor += -x * 4;
+    } else {
+        dst    +=  x * 3;
+    }
+    if (y < 0) {
+        h      +=  y;
+        cursor += -y * c->cursor_stride;
+    } else {
+        dst    +=  y * stride;
+    }
+    if (w < 0 || h < 0)
+        return;
+
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < w; i++) {
+            uint8_t alpha = cursor[i * 4];
+            APPLY_ALPHA(dst[i * 3 + 0], cursor[i * 4 + 1], alpha);
+            APPLY_ALPHA(dst[i * 3 + 1], cursor[i * 4 + 2], alpha);
+            APPLY_ALPHA(dst[i * 3 + 2], cursor[i * 4 + 3], alpha);
+        }
+        dst    += stride;
+        cursor += c->cursor_stride;
+    }
+}
+
+static int g2m_decode_frame(AVCodecContext *avctx, void *data,
+                            int *got_picture_ptr, AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
+    G2MContext *c = avctx->priv_data;
+    AVFrame *pic = data;
+    GetByteContext bc, tbc;
+    int magic;
+    int got_header = 0;
+    uint32_t chunk_size;
+    int chunk_type;
+    int i;
+    int ret;
+
+    if (buf_size < 12) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Frame should have at least 12 bytes, got %d instead\n",
+               buf_size);
+        return AVERROR_INVALIDDATA;
+    }
+
+    bytestream2_init(&bc, buf, buf_size);
+
+    magic = bytestream2_get_be32(&bc);
+    if ((magic & ~0xF) != MKBETAG('G', '2', 'M', '0') ||
+        (magic & 0xF) < 2 || (magic & 0xF) > 4) {
+        av_log(avctx, AV_LOG_ERROR, "Wrong magic %08X\n", magic);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((magic & 0xF) != 4) {
+        av_log(avctx, AV_LOG_ERROR, "G2M2 and G2M3 are not yet supported\n");
+        return AVERROR(ENOSYS);
+    }
+
+    while (bytestream2_get_bytes_left(&bc) > 5) {
+        chunk_size = bytestream2_get_le32(&bc) - 1;
+        chunk_type = bytestream2_get_byte(&bc);
+        if (chunk_size > bytestream2_get_bytes_left(&bc)) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid chunk size %d type %02X\n",
+                   chunk_size, chunk_type);
+            break;
+        }
+        switch (chunk_type) {
+        case FRAME_INFO:
+            c->got_header = 0;
+            if (chunk_size < 21) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid frame info size %d\n",
+                       chunk_size);
+                break;
+            }
+            c->width  = bytestream2_get_be32(&bc);
+            c->height = bytestream2_get_be32(&bc);
+            if (c->width  < 16 || c->width  > avctx->width ||
+                c->height < 16 || c->height > avctx->height) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Invalid frame dimensions %dx%d\n",
+                       c->width, c->height);
+                ret = AVERROR_INVALIDDATA;
+                goto header_fail;
+            }
+            if (c->width != avctx->width || c->height != avctx->height)
+                ff_set_dimensions(avctx, c->width, c->height);
+            c->compression = bytestream2_get_be32(&bc);
+            if (c->compression != 2 && c->compression != 3) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Unknown compression method %d\n",
+                       c->compression);
+                return AVERROR_PATCHWELCOME;
+            }
+            c->tile_width  = bytestream2_get_be32(&bc);
+            c->tile_height = bytestream2_get_be32(&bc);
+            if (!c->tile_width || !c->tile_height ||
+                ((c->tile_width | c->tile_height) & 0xF)) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Invalid tile dimensions %dx%d\n",
+                       c->tile_width, c->tile_height);
+                ret = AVERROR_INVALIDDATA;
+                goto header_fail;
+            }
+            c->tiles_x = (c->width  + c->tile_width  - 1) / c->tile_width;
+            c->tiles_y = (c->height + c->tile_height - 1) / c->tile_height;
+            c->bpp = bytestream2_get_byte(&bc);
+            chunk_size -= 21;
+            bytestream2_skip(&bc, chunk_size);
+            if (g2m_init_buffers(c)) {
+                ret = AVERROR(ENOMEM);
+                goto header_fail;
+            }
+            got_header = 1;
+            break;
+        case TILE_DATA:
+            if (!c->tiles_x || !c->tiles_y) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "No frame header - skipping tile\n");
+                bytestream2_skip(&bc, bytestream2_get_bytes_left(&bc));
+                break;
+            }
+            if (chunk_size < 2) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid tile data size %d\n",
+                       chunk_size);
+                break;
+            }
+            c->tile_x = bytestream2_get_byte(&bc);
+            c->tile_y = bytestream2_get_byte(&bc);
+            if (c->tile_x >= c->tiles_x || c->tile_y >= c->tiles_y) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Invalid tile pos %d,%d (in %dx%d grid)\n",
+                       c->tile_x, c->tile_y, c->tiles_x, c->tiles_y);
+                break;
+            }
+            chunk_size -= 2;
+            ret = 0;
+            switch (c->compression) {
+            case COMPR_EPIC_J_B:
+                av_log(avctx, AV_LOG_ERROR,
+                       "ePIC j-b compression is not implemented yet\n");
+                return AVERROR(ENOSYS);
+            case COMPR_KEMPF_J_B:
+                ret = kempf_decode_tile(c, c->tile_x, c->tile_y,
+                                        buf + bytestream2_tell(&bc),
+                                        chunk_size);
+                break;
+            }
+            if (ret && c->framebuf)
+                av_log(avctx, AV_LOG_ERROR, "Error decoding tile %d,%d\n",
+                       c->tile_x, c->tile_y);
+            bytestream2_skip(&bc, chunk_size);
+            break;
+        case CURSOR_POS:
+            if (chunk_size < 5) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid cursor pos size %d\n",
+                       chunk_size);
+                break;
+            }
+            c->cursor_x = bytestream2_get_be16(&bc);
+            c->cursor_y = bytestream2_get_be16(&bc);
+            bytestream2_skip(&bc, chunk_size - 4);
+            break;
+        case CURSOR_SHAPE:
+            if (chunk_size < 8) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d\n",
+                       chunk_size);
+                break;
+            }
+            bytestream2_init(&tbc, buf + bytestream2_tell(&bc),
+                             chunk_size - 4);
+            g2m_load_cursor(avctx, c, &tbc);
+            bytestream2_skip(&bc, chunk_size);
+            break;
+        case CHUNK_CC:
+        case CHUNK_CD:
+            bytestream2_skip(&bc, chunk_size);
+            break;
+        default:
+            av_log(avctx, AV_LOG_WARNING, "Skipping chunk type %02X\n",
+                   chunk_type);
+            bytestream2_skip(&bc, chunk_size);
+        }
+    }
+    if (got_header)
+        c->got_header = 1;
+
+    if (c->width && c->height) {
+        if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+            return ret;
+        }
+
+        pic->key_frame = got_header;
+        pic->pict_type = got_header ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+
+        for (i = 0; i < avctx->height; i++)
+            memcpy(pic->data[0] + i * pic->linesize[0],
+                   c->framebuf  + i * c->framebuf_stride,
+                   c->width * 3);
+        g2m_paint_cursor(c, pic->data[0], pic->linesize[0]);
+
+        *got_picture_ptr = 1;
+    }
+
+    return buf_size;
+header_fail:
+    c->width   = c->height  = 0;
+    c->tiles_x = c->tiles_y = 0;
+    return ret;
+}
+
+static av_cold int g2m_decode_init(AVCodecContext *avctx)
+{
+    G2MContext * const c = avctx->priv_data;
+    int ret;
+
+    if ((ret = jpg_init(avctx, &c->jc)) != 0) {
+        av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n");
+        jpg_free_context(&c->jc);
+        return AVERROR(ENOMEM);
+    }
+
+    avctx->pix_fmt = AV_PIX_FMT_RGB24;
+
+    return 0;
+}
+
+static av_cold int g2m_decode_end(AVCodecContext *avctx)
+{
+    G2MContext * const c = avctx->priv_data;
+
+    jpg_free_context(&c->jc);
+
+    av_freep(&c->kempf_buf);
+    av_freep(&c->kempf_flags);
+    av_freep(&c->synth_tile);
+    av_freep(&c->jpeg_tile);
+    av_freep(&c->cursor);
+    av_freep(&c->framebuf);
+
+    return 0;
+}
+
+AVCodec ff_g2m_decoder = {
+    .name           = "g2m",
+    .long_name      = NULL_IF_CONFIG_SMALL("Go2Meeting"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_G2M,
+    .priv_data_size = sizeof(G2MContext),
+    .init           = g2m_decode_init,
+    .close          = g2m_decode_end,
+    .decode         = g2m_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+};
diff --git a/libavcodec/g722.h b/libavcodec/g722.h
index bab1da4..71d03fc 100644
--- a/libavcodec/g722.h
+++ b/libavcodec/g722.h
@@ -32,7 +32,6 @@
 
 typedef struct G722Context {
     const AVClass *class;
-    AVFrame frame;
     int     bits_per_codeword;
     int16_t prev_samples[PREV_SAMPLES_BUF_SIZE]; ///< memory of past decoded samples
     int     prev_samples_pos;        ///< the number of values in prev_samples
diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c
index 51d5721..26f288b 100644
--- a/libavcodec/g722dec.c
+++ b/libavcodec/g722dec.c
@@ -44,7 +44,7 @@
 #define OFFSET(x) offsetof(G722Context, x)
 #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
-    { "bits_per_codeword", "Bits per G722 codeword", OFFSET(bits_per_codeword), AV_OPT_TYPE_FLAGS, { .i64 = 8 }, 6, 8, AD },
+    { "bits_per_codeword", "Bits per G722 codeword", OFFSET(bits_per_codeword), AV_OPT_TYPE_INT, { .i64 = 8 }, 6, 8, AD },
     { NULL }
 };
 
@@ -67,9 +67,6 @@ static av_cold int g722_decode_init(AVCodecContext * avctx)
     c->band[1].scale_factor = 2;
     c->prev_samples_pos = 22;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -88,6 +85,7 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     G722Context *c = avctx->priv_data;
+    AVFrame *frame = data;
     int16_t *out_buf;
     int j, ret;
     const int skip = 8 - c->bits_per_codeword;
@@ -95,12 +93,12 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data,
     GetBitContext gb;
 
     /* get output buffer */
-    c->frame.nb_samples = avpkt->size * 2;
-    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = avpkt->size * 2;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out_buf = (int16_t *)c->frame.data[0];
+    out_buf = (int16_t *)frame->data[0];
 
     init_get_bits(&gb, avpkt->data, avpkt->size * 8);
 
@@ -135,20 +133,19 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
 
 AVCodec ff_adpcm_g722_decoder = {
     .name           = "g722",
+    .long_name      = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ADPCM_G722,
     .priv_data_size = sizeof(G722Context),
     .init           = g722_decode_init,
     .decode         = g722_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
     .priv_class     = &g722_decoder_class,
 };
diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c
index 11d3f20..e7b67da 100644
--- a/libavcodec/g722enc.c
+++ b/libavcodec/g722enc.c
@@ -52,9 +52,6 @@ static av_cold int g722_encode_close(AVCodecContext *avctx)
         av_freep(&c->node_buf[i]);
         av_freep(&c->nodep_buf[i]);
     }
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     return 0;
 }
 
@@ -122,14 +119,6 @@ static av_cold int g722_encode_init(AVCodecContext * avctx)
         }
     }
 
-#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:
     g722_encode_close(avctx);
@@ -393,6 +382,7 @@ static int g722_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_adpcm_g722_encoder = {
     .name           = "g722",
+    .long_name      = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ADPCM_G722,
     .priv_data_size = sizeof(G722Context),
@@ -400,7 +390,6 @@ AVCodec ff_adpcm_g722_encoder = {
     .close          = g722_encode_close,
     .encode2        = g722_encode_frame,
     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME,
-    .long_name      = NULL_IF_CONFIG_SMALL("G.722 ADPCM"),
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index b1fbe98..bbdb404 100644
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -76,7 +76,6 @@ typedef struct {
 
 typedef struct g723_1_context {
     AVClass *class;
-    AVFrame frame;
 
     G723_1_Subframe subframe[4];
     enum FrameType cur_frame_type;
@@ -117,9 +116,6 @@ static av_cold int g723_1_decode_init(AVCodecContext *avctx)
     avctx->sample_rate    = 8000;
     p->pf_gain            = 1 << 12;
 
-    avcodec_get_frame_defaults(&p->frame);
-    avctx->coded_frame    = &p->frame;
-
     memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(*p->prev_lsp));
     memcpy(p->sid_lsp,  dc_lsp, LPC_ORDER * sizeof(*p->sid_lsp));
 
@@ -1191,6 +1187,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
     G723_1_Context *p  = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     int dec_mode       = buf[0] & 3;
@@ -1220,13 +1217,13 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
             p->cur_frame_type = UNTRANSMITTED_FRAME;
     }
 
-    p->frame.nb_samples = FRAME_LEN;
-    if ((ret = ff_get_buffer(avctx, &p->frame)) < 0) {
+    frame->nb_samples = FRAME_LEN;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
          return ret;
     }
 
-    out = (int16_t *)p->frame.data[0];
+    out = (int16_t *)frame->data[0];
 
     if (p->cur_frame_type == ACTIVE_FRAME) {
         if (!bad_frame)
@@ -1297,7 +1294,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
                        (FRAME_LEN + PITCH_MAX) * sizeof(*p->excitation));
                 memset(p->prev_excitation, 0,
                        PITCH_MAX * sizeof(*p->excitation));
-                memset(p->frame.data[0], 0,
+                memset(frame->data[0], 0,
                        (FRAME_LEN + LPC_ORDER) * sizeof(int16_t));
             } else {
                 int16_t *buf = p->audio + LPC_ORDER;
@@ -1346,8 +1343,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
             out[i] = av_clip_int16(p->audio[LPC_ORDER + i] << 1);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = p->frame;
+    *got_frame_ptr = 1;
 
     return frame_size[dec_mode];
 }
@@ -1371,12 +1367,12 @@ static const AVClass g723_1dec_class = {
 
 AVCodec ff_g723_1_decoder = {
     .name           = "g723_1",
+    .long_name      = NULL_IF_CONFIG_SMALL("G.723.1"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_G723_1,
     .priv_data_size = sizeof(G723_1_Context),
     .init           = g723_1_decode_init,
     .decode         = g723_1_decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("G.723.1"),
     .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
     .priv_class     = &g723_1dec_class,
 };
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index dbe9e02..62aeb79 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -77,7 +77,6 @@ typedef struct G726Tables {
 
 typedef struct G726Context {
     AVClass *class;
-    AVFrame frame;
     G726Tables tbls;    /**< static tables needed for computation */
 
     Float11 sr[2];      /**< prev. reconstructed samples */
@@ -332,13 +331,6 @@ static av_cold int g726_encode_init(AVCodecContext *avctx)
 
     g726_reset(c);
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-    avctx->coded_frame->key_frame = 1;
-#endif
-
     /* select a frame size that will end on a byte boundary and have a size of
        approximately 1024 bytes */
     avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[c->code_size - 2];
@@ -346,14 +338,6 @@ static av_cold int g726_encode_init(AVCodecContext *avctx)
     return 0;
 }
 
-#if FF_API_OLD_ENCODE_AUDIO
-static av_cold int g726_encode_close(AVCodecContext *avctx)
-{
-    av_freep(&avctx->coded_frame);
-    return 0;
-}
-#endif
-
 static int g726_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                              const AVFrame *frame, int *got_packet_ptr)
 {
@@ -400,18 +384,15 @@ static const AVCodecDefault defaults[] = {
 
 AVCodec ff_adpcm_g726_encoder = {
     .name           = "g726",
+    .long_name      = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ADPCM_G726,
     .priv_data_size = sizeof(G726Context),
     .init           = g726_encode_init,
     .encode2        = g726_encode_frame,
-#if FF_API_OLD_ENCODE_AUDIO
-    .close          = g726_encode_close,
-#endif
     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
     .priv_class     = &class,
     .defaults       = defaults,
 };
@@ -434,15 +415,13 @@ static av_cold int g726_decode_init(AVCodecContext *avctx)
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
 static int g726_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     G726Context *c = avctx->priv_data;
@@ -453,12 +432,12 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data,
     out_samples = buf_size * 8 / c->code_size;
 
     /* get output buffer */
-    c->frame.nb_samples = out_samples;
-    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = out_samples;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)c->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -468,8 +447,7 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data,
     if (get_bits_left(&gb) > 0)
         av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n");
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -482,6 +460,7 @@ static void g726_decode_flush(AVCodecContext *avctx)
 
 AVCodec ff_adpcm_g726_decoder = {
     .name           = "g726",
+    .long_name      = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ADPCM_G726,
     .priv_data_size = sizeof(G726Context),
@@ -489,6 +468,5 @@ AVCodec ff_adpcm_g726_decoder = {
     .decode         = g726_decode_frame,
     .flush          = g726_decode_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
 };
 #endif
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index ffa0656..5a0089a 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -27,6 +27,7 @@
 #define AVCODEC_GET_BITS_H
 
 #include <stdint.h>
+
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
@@ -73,46 +74,48 @@ typedef struct RL_VLC_ELEM {
 } RL_VLC_ELEM;
 
 /* Bitstream reader API docs:
-name
-    arbitrary name which is used as prefix for the internal variables
-
-gb
-    getbitcontext
-
-OPEN_READER(name, gb)
-    load gb into local variables
-
-CLOSE_READER(name, gb)
-    store local vars in gb
-
-UPDATE_CACHE(name, gb)
-    refill the internal cache from the bitstream
-    after this call at least MIN_CACHE_BITS will be available,
-
-GET_CACHE(name, gb)
-    will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit)
-
-SHOW_UBITS(name, gb, num)
-    will return the next num bits
-
-SHOW_SBITS(name, gb, num)
-    will return the next num bits and do sign extension
-
-SKIP_BITS(name, gb, num)
-    will skip over the next num bits
-    note, this is equivalent to SKIP_CACHE; SKIP_COUNTER
-
-SKIP_CACHE(name, gb, num)
-    will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER)
-
-SKIP_COUNTER(name, gb, num)
-    will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS)
-
-LAST_SKIP_BITS(name, gb, num)
-    like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER
-
-for examples see get_bits, show_bits, skip_bits, get_vlc
-*/
+ * name
+ *   arbitrary name which is used as prefix for the internal variables
+ *
+ * gb
+ *   getbitcontext
+ *
+ * OPEN_READER(name, gb)
+ *   load gb into local variables
+ *
+ * CLOSE_READER(name, gb)
+ *   store local vars in gb
+ *
+ * UPDATE_CACHE(name, gb)
+ *   Refill the internal cache from the bitstream.
+ *   After this call at least MIN_CACHE_BITS will be available.
+ *
+ * GET_CACHE(name, gb)
+ *   Will output the contents of the internal cache,
+ *   next bit is MSB of 32 or 64 bit (FIXME 64bit).
+ *
+ * SHOW_UBITS(name, gb, num)
+ *   Will return the next num bits.
+ *
+ * SHOW_SBITS(name, gb, num)
+ *   Will return the next num bits and do sign extension.
+ *
+ * SKIP_BITS(name, gb, num)
+ *   Will skip over the next num bits.
+ *   Note, this is equivalent to SKIP_CACHE; SKIP_COUNTER.
+ *
+ * SKIP_CACHE(name, gb, num)
+ *   Will remove the next num bits from the cache (note SKIP_COUNTER
+ *   MUST be called before UPDATE_CACHE / CLOSE_READER).
+ *
+ * SKIP_COUNTER(name, gb, num)
+ *   Will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS).
+ *
+ * LAST_SKIP_BITS(name, gb, num)
+ *   Like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER.
+ *
+ * For examples see get_bits, show_bits, skip_bits, get_vlc.
+ */
 
 #ifdef LONG_BITSTREAM_READER
 #   define MIN_CACHE_BITS 32
@@ -122,57 +125,56 @@ for examples see get_bits, show_bits, skip_bits, get_vlc
 
 #if UNCHECKED_BITSTREAM_READER
 #define OPEN_READER(name, gb)                   \
-    unsigned int name##_index = (gb)->index;    \
-    unsigned int av_unused name##_cache = 0
+    unsigned int name ## _index = (gb)->index;  \
+    unsigned int av_unused name ## _cache = 0
 
 #define HAVE_BITS_REMAINING(name, gb) 1
 #else
 #define OPEN_READER(name, gb)                   \
-    unsigned int name##_index = (gb)->index;    \
-    unsigned int av_unused name##_cache = 0;    \
-    unsigned int av_unused name##_size_plus8 =  \
-                (gb)->size_in_bits_plus8
+    unsigned int name ## _index = (gb)->index;  \
+    unsigned int av_unused name ## _cache = 0;  \
+    unsigned int av_unused name ## _size_plus8 = (gb)->size_in_bits_plus8
 
-#define HAVE_BITS_REMAINING(name, gb)           \
-    name##_index < name##_size_plus8
+#define HAVE_BITS_REMAINING(name, gb) name ## _index < name ## _size_plus8
 #endif
 
-#define CLOSE_READER(name, gb) (gb)->index = name##_index
+#define CLOSE_READER(name, gb) (gb)->index = name ## _index
 
 #ifdef BITSTREAM_READER_LE
 
 # ifdef LONG_BITSTREAM_READER
-#   define UPDATE_CACHE(name, gb) name##_cache = \
-        AV_RL64((gb)->buffer + (name##_index >> 3)) >> (name##_index & 7)
+#   define UPDATE_CACHE(name, gb) name ## _cache = \
+        AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
 # else
-#   define UPDATE_CACHE(name, gb) name##_cache = \
-        AV_RL32((gb)->buffer + (name##_index >> 3)) >> (name##_index & 7)
+#   define UPDATE_CACHE(name, gb) name ## _cache = \
+        AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7)
 # endif
 
-# define SKIP_CACHE(name, gb, num) name##_cache >>= (num)
+# define SKIP_CACHE(name, gb, num) name ## _cache >>= (num)
 
 #else
 
 # ifdef LONG_BITSTREAM_READER
-#   define UPDATE_CACHE(name, gb) name##_cache = \
-        AV_RB64((gb)->buffer + (name##_index >> 3)) >> (32 - (name##_index & 7))
+#   define UPDATE_CACHE(name, gb) name ## _cache = \
+        AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7))
 # else
-#   define UPDATE_CACHE(name, gb) name##_cache = \
-        AV_RB32((gb)->buffer + (name##_index >> 3)) << (name##_index & 7)
+#   define UPDATE_CACHE(name, gb) name ## _cache = \
+        AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7)
 # endif
 
-# define SKIP_CACHE(name, gb, num) name##_cache <<= (num)
+# define SKIP_CACHE(name, gb, num) name ## _cache <<= (num)
 
 #endif
 
 #if UNCHECKED_BITSTREAM_READER
-#   define SKIP_COUNTER(name, gb, num) name##_index += (num)
+#   define SKIP_COUNTER(name, gb, num) name ## _index += (num)
 #else
 #   define SKIP_COUNTER(name, gb, num) \
-    name##_index = FFMIN(name##_size_plus8, name##_index + (num))
+    name ## _index = FFMIN(name ## _size_plus8, name ## _index + (num))
 #endif
 
-#define SKIP_BITS(name, gb, num) do {           \
+#define SKIP_BITS(name, gb, num)                \
+    do {                                        \
         SKIP_CACHE(name, gb, num);              \
         SKIP_COUNTER(name, gb, num);            \
     } while (0)
@@ -180,21 +182,22 @@ for examples see get_bits, show_bits, skip_bits, get_vlc
 #define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num)
 
 #ifdef BITSTREAM_READER_LE
-#   define SHOW_UBITS(name, gb, num) zero_extend(name##_cache, num)
-#   define SHOW_SBITS(name, gb, num) sign_extend(name##_cache, num)
+#   define SHOW_UBITS(name, gb, num) zero_extend(name ## _cache, num)
+#   define SHOW_SBITS(name, gb, num) sign_extend(name ## _cache, num)
 #else
-#   define SHOW_UBITS(name, gb, num) NEG_USR32(name##_cache, num)
-#   define SHOW_SBITS(name, gb, num) NEG_SSR32(name##_cache, num)
+#   define SHOW_UBITS(name, gb, num) NEG_USR32(name ## _cache, num)
+#   define SHOW_SBITS(name, gb, num) NEG_SSR32(name ## _cache, num)
 #endif
 
-#define GET_CACHE(name, gb) ((uint32_t)name##_cache)
+#define GET_CACHE(name, gb) ((uint32_t) name ## _cache)
 
 static inline int get_bits_count(const GetBitContext *s)
 {
     return s->index;
 }
 
-static inline void skip_bits_long(GetBitContext *s, int n){
+static inline void skip_bits_long(GetBitContext *s, int n)
+{
 #if UNCHECKED_BITSTREAM_READER
     s->index += n;
 #else
@@ -214,7 +217,7 @@ static inline int get_xbits(GetBitContext *s, int n)
     OPEN_READER(re, s);
     UPDATE_CACHE(re, s);
     cache = GET_CACHE(re, s);
-    sign = ~cache >> 31;
+    sign  = ~cache >> 31;
     LAST_SKIP_BITS(re, s, n);
     CLOSE_READER(re, s);
     return (NEG_USR32(sign ^ cache, n) ^ sign) - sign;
@@ -268,10 +271,10 @@ static inline void skip_bits(GetBitContext *s, int n)
 static inline unsigned int get_bits1(GetBitContext *s)
 {
     unsigned int index = s->index;
-    uint8_t result = s->buffer[index>>3];
+    uint8_t result     = s->buffer[index >> 3];
 #ifdef BITSTREAM_READER_LE
     result >>= index & 7;
-    result &= 1;
+    result  &= 1;
 #else
     result <<= index & 7;
     result >>= 8 - 1;
@@ -300,15 +303,15 @@ static inline void skip_bits1(GetBitContext *s)
  */
 static inline unsigned int get_bits_long(GetBitContext *s, int n)
 {
-    if (n <= MIN_CACHE_BITS)
+    if (n <= MIN_CACHE_BITS) {
         return get_bits(s, n);
-    else {
+    } else {
 #ifdef BITSTREAM_READER_LE
         int ret = get_bits(s, 16);
-        return ret | (get_bits(s, n-16) << 16);
+        return ret | (get_bits(s, n - 16) << 16);
 #else
-        int ret = get_bits(s, 16) << (n-16);
-        return ret | get_bits(s, n-16);
+        int ret = get_bits(s, 16) << (n - 16);
+        return ret | get_bits(s, n - 16);
 #endif
     }
 }
@@ -323,9 +326,9 @@ static inline uint64_t get_bits64(GetBitContext *s, int 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;
+        return ret | (uint64_t) get_bits_long(s, n - 32) << 32;
 #else
-        uint64_t ret = (uint64_t)get_bits_long(s, n - 32) << 32;
+        uint64_t ret = (uint64_t) get_bits_long(s, n - 32) << 32;
         return ret | get_bits_long(s, 32);
 #endif
     }
@@ -344,9 +347,9 @@ static inline int get_sbits_long(GetBitContext *s, int n)
  */
 static inline unsigned int show_bits_long(GetBitContext *s, int n)
 {
-    if (n <= MIN_CACHE_BITS)
+    if (n <= MIN_CACHE_BITS) {
         return show_bits(s, n);
-    else {
+    } else {
         GetBitContext gb = *s;
         return get_bits_long(&gb, n);
     }
@@ -377,19 +380,20 @@ static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
 
     if (bit_size > INT_MAX - 7 || bit_size < 0 || !buffer) {
         buffer_size = bit_size = 0;
-        buffer = NULL;
-        ret = AVERROR_INVALIDDATA;
+        buffer      = NULL;
+        ret         = AVERROR_INVALIDDATA;
     }
 
     buffer_size = (bit_size + 7) >> 3;
 
-    s->buffer       = buffer;
-    s->size_in_bits = bit_size;
+    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;
+    s->buffer_end         = buffer + buffer_size;
+    s->index              = 0;
+
     return ret;
 }
 
@@ -409,37 +413,40 @@ static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer,
     return init_get_bits(s, buffer, byte_size * 8);
 }
 
-static inline void align_get_bits(GetBitContext *s)
+static inline const uint8_t *align_get_bits(GetBitContext *s)
 {
     int n = -get_bits_count(s) & 7;
-    if (n) skip_bits(s, n);
+    if (n)
+        skip_bits(s, n);
+    return s->buffer + (s->index >> 3);
 }
 
 #define init_vlc(vlc, nb_bits, nb_codes,                \
                  bits, bits_wrap, bits_size,            \
                  codes, codes_wrap, codes_size,         \
                  flags)                                 \
-        ff_init_vlc_sparse(vlc, nb_bits, nb_codes,         \
-                           bits, bits_wrap, bits_size,     \
-                           codes, codes_wrap, codes_size,  \
-                           NULL, 0, 0, flags)
+    ff_init_vlc_sparse(vlc, nb_bits, nb_codes,          \
+                       bits, bits_wrap, bits_size,      \
+                       codes, codes_wrap, codes_size,   \
+                       NULL, 0, 0, flags)
 
 int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
-             const void *bits, int bits_wrap, int bits_size,
-             const void *codes, int codes_wrap, int codes_size,
-             const void *symbols, int symbols_wrap, int symbols_size,
-             int flags);
-#define INIT_VLC_LE         2
-#define INIT_VLC_USE_NEW_STATIC 4
+                       const void *bits, int bits_wrap, int bits_size,
+                       const void *codes, int codes_wrap, int codes_size,
+                       const void *symbols, int symbols_wrap, int symbols_size,
+                       int flags);
 void ff_free_vlc(VLC *vlc);
 
-#define INIT_VLC_STATIC(vlc, bits, a,b,c,d,e,f,g, static_size) do {     \
-        static VLC_TYPE table[static_size][2];                          \
-        (vlc)->table = table;                                           \
-        (vlc)->table_allocated = static_size;                           \
-        init_vlc(vlc, bits, a,b,c,d,e,f,g, INIT_VLC_USE_NEW_STATIC);    \
-    } while (0)
+#define INIT_VLC_LE             2
+#define INIT_VLC_USE_NEW_STATIC 4
 
+#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size)       \
+    do {                                                                   \
+        static VLC_TYPE table[static_size][2];                             \
+        (vlc)->table           = table;                                    \
+        (vlc)->table_allocated = static_size;                              \
+        init_vlc(vlc, bits, a, b, c, d, e, f, g, INIT_VLC_USE_NEW_STATIC); \
+    } while (0)
 
 /**
  * If the vlc code is invalid and max_depth=1, then no bits will be removed.
@@ -478,32 +485,32 @@ void ff_free_vlc(VLC *vlc);
         SKIP_BITS(name, gb, n);                                 \
     } while (0)
 
-#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update) \
-    do {                                                                \
-        int n, nb_bits;                                                 \
-        unsigned int index;                                             \
-                                                                        \
-        index = SHOW_UBITS(name, gb, bits);                             \
-        level = table[index].level;                                     \
-        n     = table[index].len;                                       \
-                                                                        \
-        if (max_depth > 1 && n < 0) {                                   \
-            SKIP_BITS(name, gb, bits);                                  \
-            if (need_update) {                                          \
-                UPDATE_CACHE(name, gb);                                 \
-            }                                                           \
-                                                                        \
-            nb_bits = -n;                                               \
-                                                                        \
-            index = SHOW_UBITS(name, gb, nb_bits) + level;              \
-            level = table[index].level;                                 \
-            n     = table[index].len;                                   \
-        }                                                               \
-        run = table[index].run;                                         \
-        SKIP_BITS(name, gb, n);                                         \
+#define GET_RL_VLC(level, run, name, gb, table, bits,           \
+                   max_depth, need_update)                      \
+    do {                                                        \
+        int n, nb_bits;                                         \
+        unsigned int index;                                     \
+                                                                \
+        index = SHOW_UBITS(name, gb, bits);                     \
+        level = table[index].level;                             \
+        n     = table[index].len;                               \
+                                                                \
+        if (max_depth > 1 && n < 0) {                           \
+            SKIP_BITS(name, gb, bits);                          \
+            if (need_update) {                                  \
+                UPDATE_CACHE(name, gb);                         \
+            }                                                   \
+                                                                \
+            nb_bits = -n;                                       \
+                                                                \
+            index = SHOW_UBITS(name, gb, nb_bits) + level;      \
+            level = table[index].level;                         \
+            n     = table[index].len;                           \
+        }                                                       \
+        run = table[index].run;                                 \
+        SKIP_BITS(name, gb, n);                                 \
     } while (0)
 
-
 /**
  * Parse a vlc code.
  * @param bits is the number of bits which will be read at once, must be
@@ -523,6 +530,7 @@ static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2],
     GET_VLC(code, re, s, table, bits, max_depth);
 
     CLOSE_READER(re, s);
+
     return code;
 }
 
@@ -556,9 +564,8 @@ static inline void print_bin(int bits, int n)
 {
     int i;
 
-    for (i = n-1; i >= 0; i--) {
-        av_log(NULL, AV_LOG_DEBUG, "%d", (bits>>i)&1);
-    }
+    for (i = n - 1; i >= 0; i--)
+        av_log(NULL, AV_LOG_DEBUG, "%d", (bits >> i) & 1);
     for (i = n; i < 24; i++)
         av_log(NULL, AV_LOG_DEBUG, " ");
 }
@@ -570,9 +577,11 @@ static inline int get_bits_trace(GetBitContext *s, int n, const char *file,
 
     print_bin(r, n);
     av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d bit @%5d in %s %s:%d\n",
-           r, n, r, get_bits_count(s)-n, file, func, line);
+           r, n, r, get_bits_count(s) - n, file, func, line);
+
     return r;
 }
+
 static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2],
                                 int bits, int max_depth, const char *file,
                                 const char *func, int line)
@@ -581,14 +590,16 @@ static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2],
     int pos   = get_bits_count(s);
     int r     = get_vlc2(s, table, bits, max_depth);
     int len   = get_bits_count(s) - pos;
-    int bits2 = show >> (24-len);
+    int bits2 = show >> (24 - len);
 
     print_bin(bits2, len);
 
     av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d vlc @%5d in %s %s:%d\n",
            bits2, len, r, pos, file, func, line);
+
     return r;
 }
+
 static inline int get_xbits_trace(GetBitContext *s, int n, const char *file,
                                   const char *func, int line)
 {
@@ -597,20 +608,22 @@ static inline int get_xbits_trace(GetBitContext *s, int n, const char *file,
 
     print_bin(show, n);
     av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d xbt @%5d in %s %s:%d\n",
-           show, n, r, get_bits_count(s)-n, file, func, line);
+           show, n, r, get_bits_count(s) - n, file, func, line);
+
     return r;
 }
 
-#define get_bits(s, n)  get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_bits1(s)    get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_bits(s, n)  get_bits_trace(s , n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_bits1(s)    get_bits_trace(s,  1, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 #define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_vlc(s, vlc)            get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+
+#define get_vlc(s, vlc)             get_vlc_trace(s, (vlc)->table, (vlc)->bits,   3, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_vlc2(s, tab, bits, max) get_vlc_trace(s,          tab,        bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 
 #define tprintf(p, ...) av_log(p, AV_LOG_DEBUG, __VA_ARGS__)
 
 #else //TRACE
-#define tprintf(p, ...) {}
+#define tprintf(p, ...) { }
 #endif
 
 #endif /* AVCODEC_GET_BITS_H */
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index af57fff..c6c37b6 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -4,6 +4,8 @@
  * Copyright (c) 2002 Francois Revol
  * Copyright (c) 2006 Baptiste Coudurier
  *
+ * first version by Francois Revol <revol at free.fr>
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -22,8 +24,6 @@
  */
 
 /*
- * First version by Francois Revol revol at free.fr
- *
  * Features and limitations:
  * - currently no compression is performed,
  *   in fact the size of the data is 9/8 the size of the image in 8bpp
@@ -53,7 +53,6 @@
 #include "put_bits.h"
 
 typedef struct {
-    AVFrame picture;
     LZWState *lzw;
     uint8_t *buf;
 } GIFContext;
@@ -131,7 +130,13 @@ static av_cold int gif_encode_init(AVCodecContext *avctx)
 {
     GIFContext *s = avctx->priv_data;
 
-    avctx->coded_frame = &s->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+
     s->lzw = av_mallocz(ff_lzw_encode_state_size);
     if (!s->lzw)
         return AVERROR(ENOMEM);
@@ -145,8 +150,6 @@ static av_cold int gif_encode_init(AVCodecContext *avctx)
 static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *pict, int *got_packet)
 {
-    GIFContext *s = avctx->priv_data;
-    AVFrame *const p = &s->picture;
     uint8_t *outbuf_ptr, *end;
     int ret;
 
@@ -157,9 +160,6 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     outbuf_ptr = pkt->data;
     end        = pkt->data + pkt->size;
 
-    *p = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
     gif_image_write_header(avctx, &outbuf_ptr, (uint32_t *)pict->data[1]);
     gif_image_write_image(avctx, &outbuf_ptr, end, pict->data[0], pict->linesize[0]);
 
@@ -174,6 +174,8 @@ static int gif_encode_close(AVCodecContext *avctx)
 {
     GIFContext *s = avctx->priv_data;
 
+    av_frame_free(&avctx->coded_frame);
+
     av_freep(&s->lzw);
     av_freep(&s->buf);
     return 0;
@@ -181,6 +183,7 @@ static int gif_encode_close(AVCodecContext *avctx)
 
 AVCodec ff_gif_encoder = {
     .name           = "gif",
+    .long_name      = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_GIF,
     .priv_data_size = sizeof(GIFContext),
@@ -191,5 +194,4 @@ AVCodec ff_gif_encoder = {
         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_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
 };
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 8f1d694..cdb7f23 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -20,8 +20,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "bytestream.h"
@@ -34,7 +32,6 @@
 #define GCE_DISPOSAL_RESTORE    3
 
 typedef struct GifState {
-    AVFrame picture;
     int screen_width;
     int screen_height;
     int bits_per_pixel;
@@ -49,8 +46,7 @@ typedef struct GifState {
     int gce_delay;
 
     /* LZW compatible decoder */
-    const uint8_t *bytestream;
-    const uint8_t *bytestream_end;
+    GetByteContext gb;
     LZWState *lzw;
 
     /* aux buffers */
@@ -63,17 +59,17 @@ typedef struct GifState {
 static const uint8_t gif87a_sig[6] = "GIF87a";
 static const uint8_t gif89a_sig[6] = "GIF89a";
 
-static int gif_read_image(GifState *s)
+static int gif_read_image(GifState *s, AVFrame *frame)
 {
     int left, top, width, height, bits_per_pixel, code_size, flags;
     int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i;
     uint8_t *ptr, *spal, *palette, *ptr1;
 
-    left = bytestream_get_le16(&s->bytestream);
-    top = bytestream_get_le16(&s->bytestream);
-    width = bytestream_get_le16(&s->bytestream);
-    height = bytestream_get_le16(&s->bytestream);
-    flags = bytestream_get_byte(&s->bytestream);
+    left   = bytestream2_get_le16(&s->gb);
+    top    = bytestream2_get_le16(&s->gb);
+    width  = bytestream2_get_le16(&s->gb);
+    height = bytestream2_get_le16(&s->gb);
+    flags  = bytestream2_get_byte(&s->gb);
     is_interleaved = flags & 0x40;
     has_local_palette = flags & 0x80;
     bits_per_pixel = (flags & 0x07) + 1;
@@ -81,7 +77,7 @@ static int gif_read_image(GifState *s)
     av_dlog(s->avctx, "gif: 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));
+        bytestream2_get_buffer(&s->gb, s->local_palette, 3 * (1 << bits_per_pixel));
         palette = s->local_palette;
     } else {
         palette = s->global_palette;
@@ -90,8 +86,11 @@ static int gif_read_image(GifState *s)
 
     /* verify that all the image is inside the screen dimensions */
     if (left + width > s->screen_width ||
-        top + height > s->screen_height)
-        return AVERROR(EINVAL);
+        top + height > s->screen_height ||
+        !width || !height) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid image dimensions.\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     /* build the palette */
     n = (1 << bits_per_pixel);
@@ -107,13 +106,13 @@ static int gif_read_image(GifState *s)
         s->image_palette[s->transparent_color_index] = 0;
 
     /* now get the image data */
-    code_size = bytestream_get_byte(&s->bytestream);
-    ff_lzw_decode_init(s->lzw, code_size, s->bytestream,
-                       s->bytestream_end - s->bytestream, FF_LZW_GIF);
+    code_size = bytestream2_get_byte(&s->gb);
+    ff_lzw_decode_init(s->lzw, code_size, s->gb.buffer,
+                       bytestream2_get_bytes_left(&s->gb), FF_LZW_GIF);
 
     /* read all the image */
-    linesize = s->picture.linesize[0];
-    ptr1 = s->picture.data[0] + top * linesize + left;
+    linesize = frame->linesize[0];
+    ptr1 = frame->data[0] + top * linesize + left;
     ptr = ptr1;
     pass = 0;
     y1 = 0;
@@ -152,7 +151,8 @@ static int gif_read_image(GifState *s)
     }
     /* read the garbage data until end marker is found */
     ff_lzw_decode_tail(s->lzw);
-    s->bytestream = ff_lzw_cur_ptr(s->lzw);
+
+    bytestream2_skip(&s->gb, ff_lzw_size_read(s->lzw));
     return 0;
 }
 
@@ -161,8 +161,8 @@ static int gif_read_extension(GifState *s)
     int ext_code, ext_len, i, gce_flags, gce_transparent_index;
 
     /* extension */
-    ext_code = bytestream_get_byte(&s->bytestream);
-    ext_len = bytestream_get_byte(&s->bytestream);
+    ext_code = bytestream2_get_byte(&s->gb);
+    ext_len  = bytestream2_get_byte(&s->gb);
 
     av_dlog(s->avctx, "gif: ext_code=0x%x len=%d\n", ext_code, ext_len);
 
@@ -171,9 +171,9 @@ static int gif_read_extension(GifState *s)
         if (ext_len != 4)
             goto discard_ext;
         s->transparent_color_index = -1;
-        gce_flags = bytestream_get_byte(&s->bytestream);
-        s->gce_delay = bytestream_get_le16(&s->bytestream);
-        gce_transparent_index = bytestream_get_byte(&s->bytestream);
+        gce_flags    = bytestream2_get_byte(&s->gb);
+        s->gce_delay = bytestream2_get_le16(&s->gb);
+        gce_transparent_index = bytestream2_get_byte(&s->gb);
         if (gce_flags & 0x01)
             s->transparent_color_index = gce_transparent_index;
         else
@@ -184,7 +184,7 @@ static int gif_read_extension(GifState *s)
                gce_flags, s->gce_delay,
                s->transparent_color_index, s->gce_disposal);
 
-        ext_len = bytestream_get_byte(&s->bytestream);
+        ext_len = bytestream2_get_byte(&s->gb);
         break;
     }
 
@@ -192,8 +192,8 @@ static int gif_read_extension(GifState *s)
  discard_ext:
     while (ext_len != 0) {
         for (i = 0; i < ext_len; i++)
-            bytestream_get_byte(&s->bytestream);
-        ext_len = bytestream_get_byte(&s->bytestream);
+            bytestream2_get_byte(&s->gb);
+        ext_len = bytestream2_get_byte(&s->gb);
 
         av_dlog(s->avctx, "gif: ext_len1=%d\n", ext_len);
     }
@@ -206,31 +206,31 @@ static int gif_read_header1(GifState *s)
     int v, n;
     int has_global_palette;
 
-    if (s->bytestream_end < s->bytestream + 13)
-        return -1;
+    if (bytestream2_get_bytes_left(&s->gb) < 13)
+        return AVERROR_INVALIDDATA;
 
     /* read gif signature */
-    bytestream_get_buffer(&s->bytestream, sig, 6);
+    bytestream2_get_buffer(&s->gb, 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;
-    s->screen_width = bytestream_get_le16(&s->bytestream);
-    s->screen_height = bytestream_get_le16(&s->bytestream);
+    s->screen_width  = bytestream2_get_le16(&s->gb);
+    s->screen_height = bytestream2_get_le16(&s->gb);
     if(   (unsigned)s->screen_width  > 32767
        || (unsigned)s->screen_height > 32767){
         av_log(NULL, AV_LOG_ERROR, "picture size too large\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    v = bytestream_get_byte(&s->bytestream);
+    v = bytestream2_get_byte(&s->gb);
     s->color_resolution = ((v & 0x70) >> 4) + 1;
     has_global_palette = (v & 0x80);
     s->bits_per_pixel = (v & 0x07) + 1;
-    s->background_color_index = bytestream_get_byte(&s->bytestream);
-    bytestream_get_byte(&s->bytestream);                /* ignored */
+    s->background_color_index = bytestream2_get_byte(&s->gb);
+    bytestream2_get_byte(&s->gb);                /* ignored */
 
     av_dlog(s->avctx, "gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n",
            s->screen_width, s->screen_height, s->bits_per_pixel,
@@ -238,35 +238,36 @@ static int gif_read_header1(GifState *s)
 
     if (has_global_palette) {
         n = 1 << s->bits_per_pixel;
-        if (s->bytestream_end < s->bytestream + n * 3)
-            return -1;
-        bytestream_get_buffer(&s->bytestream, s->global_palette, n * 3);
+        if (bytestream2_get_bytes_left(&s->gb) < n * 3)
+            return AVERROR_INVALIDDATA;
+        bytestream2_get_buffer(&s->gb, s->global_palette, n * 3);
     }
     return 0;
 }
 
-static int gif_parse_next_image(GifState *s)
+static int gif_parse_next_image(GifState *s, AVFrame *frame)
 {
-    while (s->bytestream < s->bytestream_end) {
-        int code = bytestream_get_byte(&s->bytestream);
+    while (bytestream2_get_bytes_left(&s->gb) > 0) {
+        int code = bytestream2_get_byte(&s->gb);
+        int ret;
 
         av_dlog(s->avctx, "gif: code=%02x '%c'\n", code, code);
 
         switch (code) {
         case ',':
-            return gif_read_image(s);
+            return gif_read_image(s, frame);
         case '!':
-            if (gif_read_extension(s) < 0)
-                return -1;
+            if ((ret = gif_read_extension(s)) < 0)
+                return ret;
             break;
         case ';':
             /* end of image */
         default:
             /* error or erroneous EOF */
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
-    return -1;
+    return AVERROR_INVALIDDATA;
 }
 
 static av_cold int gif_decode_init(AVCodecContext *avctx)
@@ -275,9 +276,6 @@ static av_cold int gif_decode_init(AVCodecContext *avctx)
 
     s->avctx = avctx;
 
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame= &s->picture;
-    s->picture.data[0] = NULL;
     ff_lzw_decode_open(&s->lzw);
     return 0;
 }
@@ -291,30 +289,26 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     AVFrame *picture = data;
     int ret;
 
-    s->bytestream = buf;
-    s->bytestream_end = buf + buf_size;
-    if (gif_read_header1(s) < 0)
-        return -1;
+    bytestream2_init(&s->gb, buf, buf_size);
+    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))
-        return -1;
-    avcodec_set_dimensions(avctx, s->screen_width, s->screen_height);
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-    if (ff_get_buffer(avctx, &s->picture) < 0) {
+    if ((ret = ff_set_dimensions(avctx, s->screen_width, s->screen_height)) < 0)
+        return ret;
+
+    if ((ret = ff_get_buffer(avctx, picture, 0)) < 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);
+    s->image_palette = (uint32_t *)picture->data[1];
+    ret = gif_parse_next_image(s, picture);
     if (ret < 0)
         return ret;
 
-    *picture = s->picture;
     *got_frame = 1;
-    return s->bytestream - buf;
+    return bytestream2_tell(&s->gb);
 }
 
 static av_cold int gif_decode_close(AVCodecContext *avctx)
@@ -322,13 +316,12 @@ static av_cold int gif_decode_close(AVCodecContext *avctx)
     GifState *s = avctx->priv_data;
 
     ff_lzw_decode_close(&s->lzw);
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
     return 0;
 }
 
 AVCodec ff_gif_decoder = {
     .name           = "gif",
+    .long_name      = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_GIF,
     .priv_data_size = sizeof(GifState),
@@ -336,5 +329,4 @@ AVCodec ff_gif_decoder = {
     .close          = gif_decode_close,
     .decode         = gif_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("GIF (Graphics Interchange Format)"),
 };
diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 564ba4e..efe5059 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -31,6 +31,7 @@
 #define AVCODEC_GOLOMB_H
 
 #include <stdint.h>
+
 #include "get_bits.h"
 #include "put_bits.h"
 
@@ -46,27 +47,26 @@ extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256];
 extern const  int8_t ff_interleaved_se_golomb_vlc_code[256];
 extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256];
 
-
- /**
+/**
  * read unsigned exp golomb code.
  */
-static inline int get_ue_golomb(GetBitContext *gb){
+static inline int get_ue_golomb(GetBitContext *gb)
+{
     unsigned int buf;
-    int log;
 
     OPEN_READER(re, gb);
     UPDATE_CACHE(re, gb);
-    buf=GET_CACHE(re, gb);
+    buf = GET_CACHE(re, gb);
 
-    if(buf >= (1<<27)){
+    if (buf >= (1 << 27)) {
         buf >>= 32 - 9;
         LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
         CLOSE_READER(re, gb);
 
         return ff_ue_golomb_vlc_code[buf];
-    }else{
-        log= 2*av_log2(buf) - 31;
-        buf>>= log;
+    } else {
+        int log = 2 * av_log2(buf) - 31;
+        buf >>= log;
         buf--;
         LAST_SKIP_BITS(re, gb, 32 - log);
         CLOSE_READER(re, gb);
@@ -89,16 +89,17 @@ static inline unsigned get_ue_golomb_long(GetBitContext *gb)
     return get_bits_long(gb, log + 1) - 1;
 }
 
- /**
+/**
  * read unsigned exp golomb code, constraint to a max of 31.
  * the return value is undefined if the stored value exceeds 31.
  */
-static inline int get_ue_golomb_31(GetBitContext *gb){
+static inline int get_ue_golomb_31(GetBitContext *gb)
+{
     unsigned int buf;
 
     OPEN_READER(re, gb);
     UPDATE_CACHE(re, gb);
-    buf=GET_CACHE(re, gb);
+    buf = GET_CACHE(re, gb);
 
     buf >>= 32 - 9;
     LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
@@ -113,24 +114,25 @@ static inline unsigned svq3_get_ue_golomb(GetBitContext *gb)
 
     OPEN_READER(re, gb);
     UPDATE_CACHE(re, gb);
-    buf=GET_CACHE(re, gb);
+    buf = GET_CACHE(re, gb);
 
-    if(buf&0xAA800000){
+    if (buf & 0xAA800000) {
         buf >>= 32 - 8;
         LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
         CLOSE_READER(re, gb);
 
         return ff_interleaved_ue_golomb_vlc_code[buf];
-    }else{
+    } else {
         unsigned ret = 1;
 
         do {
             buf >>= 32 - 8;
-            LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));
+            LAST_SKIP_BITS(re, gb,
+                           FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));
 
-            if (ff_interleaved_golomb_vlc_len[buf] != 9){
+            if (ff_interleaved_golomb_vlc_len[buf] != 9) {
                 ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1;
-                ret |= ff_interleaved_dirac_golomb_vlc_code[buf];
+                ret  |= ff_interleaved_dirac_golomb_vlc_code[buf];
                 break;
             }
             ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];
@@ -146,96 +148,103 @@ static inline unsigned svq3_get_ue_golomb(GetBitContext *gb)
 /**
  * read unsigned truncated exp golomb code.
  */
-static inline int get_te0_golomb(GetBitContext *gb, int range){
+static inline int get_te0_golomb(GetBitContext *gb, int range)
+{
     assert(range >= 1);
 
-    if(range==1)      return 0;
-    else if(range==2) return get_bits1(gb)^1;
-    else              return get_ue_golomb(gb);
+    if (range == 1)
+        return 0;
+    else if (range == 2)
+        return get_bits1(gb) ^ 1;
+    else
+        return get_ue_golomb(gb);
 }
 
 /**
  * read unsigned truncated exp golomb code.
  */
-static inline int get_te_golomb(GetBitContext *gb, int range){
+static inline int get_te_golomb(GetBitContext *gb, int range)
+{
     assert(range >= 1);
 
-    if(range==2) return get_bits1(gb)^1;
-    else         return get_ue_golomb(gb);
+    if (range == 2)
+        return get_bits1(gb) ^ 1;
+    else
+        return get_ue_golomb(gb);
 }
 
-
 /**
  * read signed exp golomb code.
  */
-static inline int get_se_golomb(GetBitContext *gb){
+static inline int get_se_golomb(GetBitContext *gb)
+{
     unsigned int buf;
-    int log;
 
     OPEN_READER(re, gb);
     UPDATE_CACHE(re, gb);
-    buf=GET_CACHE(re, gb);
+    buf = GET_CACHE(re, gb);
 
-    if(buf >= (1<<27)){
+    if (buf >= (1 << 27)) {
         buf >>= 32 - 9;
         LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
         CLOSE_READER(re, gb);
 
         return ff_se_golomb_vlc_code[buf];
-    }else{
-        log= 2*av_log2(buf) - 31;
-        buf>>= log;
+    } else {
+        int log = 2 * av_log2(buf) - 31;
+        buf >>= log;
 
         LAST_SKIP_BITS(re, gb, 32 - log);
         CLOSE_READER(re, gb);
 
-        if(buf&1) buf= -(buf>>1);
-        else      buf=  (buf>>1);
+        if (buf & 1)
+            buf = -(buf >> 1);
+        else
+            buf = (buf >> 1);
 
         return buf;
     }
 }
 
-static inline int svq3_get_se_golomb(GetBitContext *gb){
+static inline int svq3_get_se_golomb(GetBitContext *gb)
+{
     unsigned int buf;
-    int log;
 
     OPEN_READER(re, gb);
     UPDATE_CACHE(re, gb);
-    buf=GET_CACHE(re, gb);
+    buf = GET_CACHE(re, gb);
 
-    if(buf&0xAA800000){
+    if (buf & 0xAA800000) {
         buf >>= 32 - 8;
         LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
         CLOSE_READER(re, gb);
 
         return ff_interleaved_se_golomb_vlc_code[buf];
-    }else{
+    } else {
+        int log;
         LAST_SKIP_BITS(re, gb, 8);
         UPDATE_CACHE(re, gb);
         buf |= 1 | (GET_CACHE(re, gb) >> 8);
 
-        if((buf & 0xAAAAAAAA) == 0)
+        if ((buf & 0xAAAAAAAA) == 0)
             return INVALID_VLC;
 
-        for(log=31; (buf & 0x80000000) == 0; log--){
+        for (log = 31; (buf & 0x80000000) == 0; log--)
             buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30);
-        }
 
-        LAST_SKIP_BITS(re, gb, 63 - 2*log - 8);
+        LAST_SKIP_BITS(re, gb, 63 - 2 * log - 8);
         CLOSE_READER(re, gb);
 
         return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1;
     }
 }
 
-static inline int dirac_get_se_golomb(GetBitContext *gb){
-    uint32_t buf;
-    uint32_t ret;
-
-    ret = svq3_get_ue_golomb(gb);
+static inline int dirac_get_se_golomb(GetBitContext *gb)
+{
+    uint32_t ret = svq3_get_ue_golomb(gb);
 
     if (ret) {
+        uint32_t buf;
         OPEN_READER(re, gb);
         UPDATE_CACHE(re, gb);
         buf = SHOW_SBITS(re, gb, 1);
@@ -250,24 +259,26 @@ static inline int dirac_get_se_golomb(GetBitContext *gb){
 /**
  * read unsigned golomb rice code (ffv1).
  */
-static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){
+static inline int get_ur_golomb(GetBitContext *gb, int k, int limit,
+                                int esc_len)
+{
     unsigned int buf;
     int log;
 
     OPEN_READER(re, gb);
     UPDATE_CACHE(re, gb);
-    buf=GET_CACHE(re, gb);
+    buf = GET_CACHE(re, gb);
 
-    log= av_log2(buf);
+    log = av_log2(buf);
 
-    if(log > 31-limit){
+    if (log > 31 - limit) {
         buf >>= log - k;
-        buf += (30-log)<<k;
+        buf  += (30 - log) << k;
         LAST_SKIP_BITS(re, gb, 32 + k - log);
         CLOSE_READER(re, gb);
 
         return buf;
-    }else{
+    } else {
         LAST_SKIP_BITS(re, gb, limit);
         UPDATE_CACHE(re, gb);
 
@@ -283,24 +294,27 @@ static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len
 /**
  * read unsigned golomb rice code (jpegls).
  */
-static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len){
+static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit,
+                                       int esc_len)
+{
     unsigned int buf;
     int log;
 
     OPEN_READER(re, gb);
     UPDATE_CACHE(re, gb);
-    buf=GET_CACHE(re, gb);
+    buf = GET_CACHE(re, gb);
 
-    log= av_log2(buf);
+    log = av_log2(buf);
 
-    if(log - k >= 32-MIN_CACHE_BITS+(MIN_CACHE_BITS==32) && 32-log < limit){
+    if (log - k >= 32 - MIN_CACHE_BITS + (MIN_CACHE_BITS == 32) &&
+        32 - log < limit) {
         buf >>= log - k;
-        buf += (30-log)<<k;
+        buf  += (30 - log) << k;
         LAST_SKIP_BITS(re, gb, 32 + k - log);
         CLOSE_READER(re, gb);
 
         return buf;
-    }else{
+    } else {
         int i;
         for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0 && HAVE_BITS_REMAINING(re, gb); i++) {
             LAST_SKIP_BITS(re, gb, 1);
@@ -308,23 +322,23 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int
         }
         SKIP_BITS(re, gb, 1);
 
-        if(i < limit - 1){
-            if(k){
+        if (i < limit - 1) {
+            if (k) {
                 buf = SHOW_UBITS(re, gb, k);
                 LAST_SKIP_BITS(re, gb, k);
-            }else{
-                buf=0;
+            } else {
+                buf = 0;
             }
 
             CLOSE_READER(re, gb);
-            return buf + (i<<k);
-        }else if(i == limit - 1){
+            return buf + (i << k);
+        } else if (i == limit - 1) {
             buf = SHOW_UBITS(re, gb, esc_len);
             LAST_SKIP_BITS(re, gb, esc_len);
             CLOSE_READER(re, gb);
 
             return buf + 1;
-        }else
+        } else
             return -1;
     }
 }
@@ -332,12 +346,16 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int
 /**
  * read signed golomb rice code (ffv1).
  */
-static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, int esc_len){
-    int v= get_ur_golomb(gb, k, limit, esc_len);
+static inline int get_sr_golomb(GetBitContext *gb, int k, int limit,
+                                int esc_len)
+{
+    int v = get_ur_golomb(gb, k, limit, esc_len);
 
     v++;
-    if (v&1) return v>>1;
-    else return -(v>>1);
+    if (v & 1)
+        return v >> 1;
+    else
+        return -(v >> 1);
 
 //    return (v>>1) ^ -(v&1);
 }
@@ -345,22 +363,25 @@ static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, int esc_len
 /**
  * read signed golomb rice code (flac).
  */
-static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len){
-    int v= get_ur_golomb_jpegls(gb, k, limit, esc_len);
-    return (v>>1) ^ -(v&1);
+static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit,
+                                     int esc_len)
+{
+    int v = get_ur_golomb_jpegls(gb, k, limit, esc_len);
+    return (v >> 1) ^ -(v & 1);
 }
 
 /**
  * read unsigned golomb rice code (shorten).
  */
-static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k){
-        return get_ur_golomb_jpegls(gb, k, INT_MAX, 0);
+static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k)
+{
+    return get_ur_golomb_jpegls(gb, k, INT_MAX, 0);
 }
 
 /**
  * read signed golomb rice code (shorten).
  */
-static inline int get_sr_golomb_shorten(GetBitContext* gb, int k)
+static inline int get_sr_golomb_shorten(GetBitContext *gb, int k)
 {
     int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0);
     if (uvar & 1)
@@ -369,22 +390,21 @@ static inline int get_sr_golomb_shorten(GetBitContext* gb, int k)
         return uvar >> 1;
 }
 
-
-
 #ifdef TRACE
 
 static inline int get_ue(GetBitContext *s, const char *file, const char *func,
                          int line)
 {
-    int show= show_bits(s, 24);
-    int pos= get_bits_count(s);
-    int i= get_ue_golomb(s);
-    int len= get_bits_count(s) - pos;
-    int bits= show>>(24-len);
+    int show = show_bits(s, 24);
+    int pos  = get_bits_count(s);
+    int i    = get_ue_golomb(s);
+    int len  = get_bits_count(s) - pos;
+    int bits = show >> (24 - len);
 
     print_bin(bits, len);
 
-    av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue  @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
+    av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue  @%5d in %s %s:%d\n",
+           bits, len, i, pos, file, func, line);
 
     return i;
 }
@@ -392,87 +412,96 @@ static inline int get_ue(GetBitContext *s, const char *file, const char *func,
 static inline int get_se(GetBitContext *s, const char *file, const char *func,
                          int line)
 {
-    int show= show_bits(s, 24);
-    int pos= get_bits_count(s);
-    int i= get_se_golomb(s);
-    int len= get_bits_count(s) - pos;
-    int bits= show>>(24-len);
+    int show = show_bits(s, 24);
+    int pos  = get_bits_count(s);
+    int i    = get_se_golomb(s);
+    int len  = get_bits_count(s) - pos;
+    int bits = show >> (24 - len);
 
     print_bin(bits, len);
 
-    av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se  @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
+    av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se  @%5d in %s %s:%d\n",
+           bits, len, i, pos, file, func, line);
 
     return i;
 }
 
-static inline int get_te(GetBitContext *s, int r, char *file, const char *func, int line){
-    int show= show_bits(s, 24);
-    int pos= get_bits_count(s);
-    int i= get_te0_golomb(s, r);
-    int len= get_bits_count(s) - pos;
-    int bits= show>>(24-len);
+static inline int get_te(GetBitContext *s, int r, char *file, const char *func,
+                         int line)
+{
+    int show = show_bits(s, 24);
+    int pos  = get_bits_count(s);
+    int i    = get_te0_golomb(s, r);
+    int len  = get_bits_count(s) - pos;
+    int bits = show >> (24 - len);
 
     print_bin(bits, len);
 
-    av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te  @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
+    av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te  @%5d in %s %s:%d\n",
+           bits, len, i, pos, file, func, line);
 
     return i;
 }
 
 #define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 #define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
-#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_te_golomb(a, r)  get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 #define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 
-#endif
+#endif /* TRACE */
 
 /**
  * write unsigned exp golomb code.
  */
-static inline void set_ue_golomb(PutBitContext *pb, int i){
-    int e;
-
-    assert(i>=0);
+static inline void set_ue_golomb(PutBitContext *pb, int i)
+{
+    assert(i >= 0);
 
 #if 0
-    if(i=0){
+    if (i = 0) {
         put_bits(pb, 1, 1);
         return;
     }
 #endif
-    if(i<256)
-        put_bits(pb, ff_ue_golomb_len[i], i+1);
-    else{
-        e= av_log2(i+1);
-
-        put_bits(pb, 2*e+1, i+1);
+    if (i < 256)
+        put_bits(pb, ff_ue_golomb_len[i], i + 1);
+    else {
+        int e = av_log2(i + 1);
+        put_bits(pb, 2 * e + 1, i + 1);
     }
 }
 
 /**
  * write truncated unsigned exp golomb code.
  */
-static inline void set_te_golomb(PutBitContext *pb, int i, int range){
+static inline void set_te_golomb(PutBitContext *pb, int i, int range)
+{
     assert(range >= 1);
-    assert(i<=range);
+    assert(i <= range);
 
-    if(range==2) put_bits(pb, 1, i^1);
-    else         set_ue_golomb(pb, i);
+    if (range == 2)
+        put_bits(pb, 1, i ^ 1);
+    else
+        set_ue_golomb(pb, i);
 }
 
 /**
  * write signed exp golomb code. 16 bits at most.
  */
-static inline void set_se_golomb(PutBitContext *pb, int i){
+static inline void set_se_golomb(PutBitContext *pb, int i)
+{
 #if 0
-    if(i<=0) i= -2*i;
-    else     i=  2*i-1;
+    if (i <= 0)
+        i = -2 * i;
+    else
+        i = 2 * i - 1;
 #elif 1
-    i= 2*i-1;
-    if(i<0) i^= -1; //FIXME check if gcc does the right thing
+    i = 2 * i - 1;
+    if (i < 0)
+        i ^= -1;    //FIXME check if gcc does the right thing
 #else
-    i= 2*i-1;
-    i^= (i>>31);
+    i  = 2 * i - 1;
+    i ^= (i >> 31);
 #endif
     set_ue_golomb(pb, i);
 }
@@ -480,42 +509,45 @@ static inline void set_se_golomb(PutBitContext *pb, int i){
 /**
  * write unsigned golomb rice code (ffv1).
  */
-static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){
+static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit,
+                                 int esc_len)
+{
     int e;
 
-    assert(i>=0);
+    assert(i >= 0);
 
-    e= i>>k;
-    if(e<limit){
-        put_bits(pb, e + k + 1, (1<<k) + (i&((1<<k)-1)));
-    }else{
+    e = i >> k;
+    if (e < limit)
+        put_bits(pb, e + k + 1, (1 << k) + (i & ((1 << k) - 1)));
+    else
         put_bits(pb, limit + esc_len, i - limit + 1);
-    }
 }
 
 /**
  * write unsigned golomb rice code (jpegls).
  */
-static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int limit, int esc_len){
+static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k,
+                                        int limit, int esc_len)
+{
     int e;
 
-    assert(i>=0);
+    assert(i >= 0);
 
-    e= (i>>k) + 1;
-    if(e<limit){
-        while(e > 31) {
+    e = (i >> k) + 1;
+    if (e < limit) {
+        while (e > 31) {
             put_bits(pb, 31, 0);
             e -= 31;
         }
         put_bits(pb, e, 1);
-        if(k)
+        if (k)
             put_sbits(pb, k, i);
-    }else{
-        while(limit > 31) {
+    } else {
+        while (limit > 31) {
             put_bits(pb, 31, 0);
             limit -= 31;
         }
-        put_bits(pb, limit  , 1);
+        put_bits(pb, limit, 1);
         put_bits(pb, esc_len, i - 1);
     }
 }
@@ -523,11 +555,13 @@ static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int lim
 /**
  * write signed golomb rice code (ffv1).
  */
-static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){
+static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit,
+                                 int esc_len)
+{
     int v;
 
-    v = -2*i-1;
-    v ^= (v>>31);
+    v  = -2 * i - 1;
+    v ^= (v >> 31);
 
     set_ur_golomb(pb, v, k, limit, esc_len);
 }
@@ -535,11 +569,13 @@ static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int
 /**
  * write signed golomb rice code (flac).
  */
-static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, int limit, int esc_len){
+static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k,
+                                      int limit, int esc_len)
+{
     int v;
 
-    v = -2*i-1;
-    v ^= (v>>31);
+    v  = -2 * i - 1;
+    v ^= (v >> 31);
 
     set_ur_golomb_jpegls(pb, v, k, limit, esc_len);
 }
diff --git a/libavcodec/gsm.h b/libavcodec/gsm.h
index c7c3e22..238cb73 100644
--- a/libavcodec/gsm.h
+++ b/libavcodec/gsm.h
@@ -22,10 +22,24 @@
 #define AVCODEC_GSM_H
 
 /* bytes per block */
-#define GSM_BLOCK_SIZE    33
-#define GSM_MS_BLOCK_SIZE 65
+#define GSM_BLOCK_SIZE     33
+#define GSM_MS_BLOCK_SIZE  65
+#define MSN_MIN_BLOCK_SIZE 41
 
 /* samples per block */
 #define GSM_FRAME_SIZE 160
 
+enum GSMModes {
+    GSM_13000 = 0,
+    MSN_12400,
+    MSN_11800,
+    MSN_11200,
+    MSN_10600,
+    MSN_10000,
+    MSN_9400,
+    MSN_8800,
+    MSN_8200,
+    NUM_GSM_MODES
+};
+
 #endif /* AVCODEC_GSM_H */
diff --git a/libavcodec/gsm_parser.c b/libavcodec/gsm_parser.c
index 1d381fc..c0befc7 100644
--- a/libavcodec/gsm_parser.c
+++ b/libavcodec/gsm_parser.c
@@ -50,7 +50,8 @@ static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
             s->duration   = GSM_FRAME_SIZE;
             break;
         case AV_CODEC_ID_GSM_MS:
-            s->block_size = GSM_MS_BLOCK_SIZE;
+            s->block_size = avctx->block_align ? avctx->block_align
+                                               : GSM_MS_BLOCK_SIZE;
             s->duration   = GSM_FRAME_SIZE * 2;
             break;
         default:
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index 4304723..b763ce8 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -34,11 +34,10 @@
 
 static av_cold int gsm_init(AVCodecContext *avctx)
 {
-    GSMContext *s = avctx->priv_data;
-
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
-    avctx->sample_rate    = 8000;
+    if (!avctx->sample_rate)
+        avctx->sample_rate = 8000;
     avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
 
     switch (avctx->codec_id) {
@@ -48,19 +47,25 @@ static av_cold int gsm_init(AVCodecContext *avctx)
         break;
     case AV_CODEC_ID_GSM_MS:
         avctx->frame_size  = 2 * GSM_FRAME_SIZE;
-        avctx->block_align = GSM_MS_BLOCK_SIZE;
+        if (!avctx->block_align)
+            avctx->block_align = GSM_MS_BLOCK_SIZE;
+        else
+            if (avctx->block_align < MSN_MIN_BLOCK_SIZE ||
+                avctx->block_align > GSM_MS_BLOCK_SIZE  ||
+                (avctx->block_align - MSN_MIN_BLOCK_SIZE) % 3) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid block alignment %d\n",
+                       avctx->block_align);
+                return AVERROR_INVALIDDATA;
+            }
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int gsm_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
-    GSMContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int res;
     GetBitContext gb;
     const uint8_t *buf = avpkt->data;
@@ -73,30 +78,30 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    s->frame.nb_samples = avctx->frame_size;
-    if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = avctx->frame_size;
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
-    samples = (int16_t *)s->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     switch (avctx->codec_id) {
     case AV_CODEC_ID_GSM:
         init_get_bits(&gb, buf, buf_size * 8);
         if (get_bits(&gb, 4) != 0xd)
             av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n");
-        res = gsm_decode_block(avctx, samples, &gb);
+        res = gsm_decode_block(avctx, samples, &gb, GSM_13000);
         if (res < 0)
             return res;
         break;
     case AV_CODEC_ID_GSM_MS:
-        res = ff_msgsm_decode_block(avctx, samples, buf);
+        res = ff_msgsm_decode_block(avctx, samples, buf,
+                                    (GSM_MS_BLOCK_SIZE - avctx->block_align) / 3);
         if (res < 0)
             return res;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
@@ -109,6 +114,7 @@ static void gsm_flush(AVCodecContext *avctx)
 
 AVCodec ff_gsm_decoder = {
     .name           = "gsm",
+    .long_name      = NULL_IF_CONFIG_SMALL("GSM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_GSM,
     .priv_data_size = sizeof(GSMContext),
@@ -116,11 +122,11 @@ AVCodec ff_gsm_decoder = {
     .decode         = gsm_decode_frame,
     .flush          = gsm_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("GSM"),
 };
 
 AVCodec ff_gsm_ms_decoder = {
     .name           = "gsm_ms",
+    .long_name      = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_GSM_MS,
     .priv_data_size = sizeof(GSMContext),
@@ -128,5 +134,4 @@ AVCodec ff_gsm_ms_decoder = {
     .decode         = gsm_decode_frame,
     .flush          = gsm_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"),
 };
diff --git a/libavcodec/gsmdec_data.c b/libavcodec/gsmdec_data.c
index 8b75bb6..c9b3183 100644
--- a/libavcodec/gsmdec_data.c
+++ b/libavcodec/gsmdec_data.c
@@ -92,3 +92,29 @@ const int16_t ff_gsm_dequant_tab[64][8] = {
     {-26879, -19199, -11520,  -3840,   3840,  11520,  19199,  26879},
     {-28671, -20479, -12288,  -4096,   4096,  12288,  20479,  28671}
 };
+
+static const int apcm_bits[11][13] = {
+    { 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 },
+    { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 },
+    { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 },
+    { 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 },
+    { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+    { 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+    { 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+    { 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+    { 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+    { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }
+};
+
+const int* const ff_gsm_apcm_bits[][4] = {
+    { apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[10] }, // 13000
+    { apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[ 6] }, // 12400
+    { apcm_bits[10], apcm_bits[10], apcm_bits[ 7], apcm_bits[ 5] }, // 11800
+    { apcm_bits[10], apcm_bits[ 8], apcm_bits[ 5], apcm_bits[ 5] }, // 11200
+    { apcm_bits[ 9], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5] }, // 10600
+    { apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 1] }, // 10000
+    { apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 2], apcm_bits[ 0] }, //  9400
+    { apcm_bits[ 5], apcm_bits[ 3], apcm_bits[ 0], apcm_bits[ 0] }, //  8800
+    { apcm_bits[ 4], apcm_bits[ 0], apcm_bits[ 0], apcm_bits[ 0] }, //  8200
+};
diff --git a/libavcodec/gsmdec_data.h b/libavcodec/gsmdec_data.h
index 2f3a2d2..f5581d5 100644
--- a/libavcodec/gsmdec_data.h
+++ b/libavcodec/gsmdec_data.h
@@ -26,7 +26,6 @@
 #include "avcodec.h"
 
 typedef struct GSMContext {
-    AVFrame frame;
     // Contains first 120 elements from the previous frame
     // (used by long_term_synth according to the "lag"),
     // then in the following 160 elements the current
@@ -41,4 +40,6 @@ typedef struct GSMContext {
 extern const uint16_t ff_gsm_long_term_gain_tab[4];
 extern const int16_t ff_gsm_dequant_tab[64][8];
 
+extern const int* const ff_gsm_apcm_bits[][4];
+
 #endif /* AVCODEC_GSMDEC_DATA_H */
diff --git a/libavcodec/gsmdec_template.c b/libavcodec/gsmdec_template.c
index b5222af..0b54dc5 100644
--- a/libavcodec/gsmdec_template.c
+++ b/libavcodec/gsmdec_template.c
@@ -28,13 +28,22 @@
 #include "gsm.h"
 #include "gsmdec_data.h"
 
-static void apcm_dequant_add(GetBitContext *gb, int16_t *dst)
+static const int requant_tab[4][8] = {
+    { 0 },
+    { 0, 7 },
+    { 0, 2, 5, 7 },
+    { 0, 1, 2, 3, 4, 5, 6, 7 }
+};
+
+static void apcm_dequant_add(GetBitContext *gb, int16_t *dst, const int *frame_bits)
 {
-    int i;
+    int i, val;
     int maxidx = get_bits(gb, 6);
     const int16_t *tab = ff_gsm_dequant_tab[maxidx];
-    for (i = 0; i < 13; i++)
-        dst[3*i] += tab[get_bits(gb, 3)];
+    for (i = 0; i < 13; i++) {
+        val = get_bits(gb, frame_bits[i]);
+        dst[3*i] += tab[requant_tab[frame_bits[i]][val]];
+    }
 }
 
 static inline int gsm_mult(int a, int b)
@@ -118,7 +127,7 @@ static int postprocess(int16_t *data, int msr)
 }
 
 static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples,
-                            GetBitContext *gb)
+                            GetBitContext *gb, int mode)
 {
     GSMContext *ctx = avctx->priv_data;
     int i;
@@ -139,7 +148,7 @@ static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples,
         int offset   = get_bits(gb, 2);
         lag = av_clip(lag, 40, 120);
         long_term_synth(ref_dst, lag, gain_idx);
-        apcm_dequant_add(gb, ref_dst + offset);
+        apcm_dequant_add(gb, ref_dst + offset, ff_gsm_apcm_bits[mode][i]);
         ref_dst += 40;
     }
     memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf));
diff --git a/libavcodec/h261.c b/libavcodec/h261.c
index 9555613..b9783f1 100644
--- a/libavcodec/h261.c
+++ b/libavcodec/h261.c
@@ -25,29 +25,68 @@
  * h261codec.
  */
 
-#include "dsputil.h"
 #include "avcodec.h"
 #include "h261.h"
 
-#define IS_FIL(a)    ((a)&MB_TYPE_H261_FIL)
+#define IS_FIL(a)    ((a) & MB_TYPE_H261_FIL)
 
-uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
+uint8_t ff_h261_rl_table_store[2][2 * MAX_RUN + MAX_LEVEL + 3];
 
-void ff_h261_loop_filter(MpegEncContext *s){
-    H261Context * h= (H261Context*)s;
-    const int linesize  = s->linesize;
-    const int uvlinesize= s->uvlinesize;
-    uint8_t *dest_y = s->dest[0];
-    uint8_t *dest_cb= s->dest[1];
-    uint8_t *dest_cr= s->dest[2];
+static void h261_loop_filter(uint8_t *src, int stride)
+{
+    int x, y, xy, yz;
+    int temp[64];
 
-    if(!(IS_FIL (h->mtype)))
+    for (x = 0; x < 8; x++) {
+        temp[x]         = 4 * src[x];
+        temp[x + 7 * 8] = 4 * src[x + 7 * stride];
+    }
+    for (y = 1; y < 7; y++) {
+        for (x = 0; x < 8; x++) {
+            xy       = y * stride + x;
+            yz       = y * 8      + x;
+            temp[yz] = src[xy - stride] + 2 * src[xy] + src[xy + stride];
+        }
+    }
+
+    for (y = 0; y < 8; y++) {
+        src[y * stride]     = (temp[y * 8]     + 2) >> 2;
+        src[y * stride + 7] = (temp[y * 8 + 7] + 2) >> 2;
+        for (x = 1; x < 7; x++) {
+            xy      = y * stride + x;
+            yz      = y * 8      + x;
+            src[xy] = (temp[yz - 1] + 2 * temp[yz] + temp[yz + 1] + 8) >> 4;
+        }
+    }
+}
+
+void ff_h261_loop_filter(MpegEncContext *s)
+{
+    H261Context *h       = (H261Context *)s;
+    const int linesize   = s->linesize;
+    const int uvlinesize = s->uvlinesize;
+    uint8_t *dest_y      = s->dest[0];
+    uint8_t *dest_cb     = s->dest[1];
+    uint8_t *dest_cr     = s->dest[2];
+
+    if (!(IS_FIL(h->mtype)))
+        return;
+
+    h261_loop_filter(dest_y,                    linesize);
+    h261_loop_filter(dest_y + 8,                linesize);
+    h261_loop_filter(dest_y + 8 * linesize,     linesize);
+    h261_loop_filter(dest_y + 8 * linesize + 8, linesize);
+    h261_loop_filter(dest_cb, uvlinesize);
+    h261_loop_filter(dest_cr, uvlinesize);
+}
+
+av_cold void ff_h261_common_init(void)
+{
+    static int done = 0;
+
+    if (done)
         return;
 
-    s->dsp.h261_loop_filter(dest_y                   , linesize);
-    s->dsp.h261_loop_filter(dest_y                + 8, linesize);
-    s->dsp.h261_loop_filter(dest_y + 8 * linesize    , linesize);
-    s->dsp.h261_loop_filter(dest_y + 8 * linesize + 8, linesize);
-    s->dsp.h261_loop_filter(dest_cb, uvlinesize);
-    s->dsp.h261_loop_filter(dest_cr, uvlinesize);
+    ff_init_rl(&ff_h261_rl_tcoeff, ff_h261_rl_table_store);
+    done = 1;
 }
diff --git a/libavcodec/h261.h b/libavcodec/h261.h
index 6461329..ad7e28b 100644
--- a/libavcodec/h261.h
+++ b/libavcodec/h261.h
@@ -29,11 +29,12 @@
 #define AVCODEC_H261_H
 
 #include "mpegvideo.h"
+#include "rl.h"
 
 /**
  * H261Context
  */
-typedef struct H261Context{
+typedef struct H261Context {
     MpegEncContext s;
 
     int current_mba;
@@ -44,8 +45,29 @@ typedef struct H261Context{
     int current_mv_y;
     int gob_number;
     int gob_start_code_skipped; // 1 if gob start code is already read before gob header is read
-}H261Context;
+} H261Context;
 
 #define MB_TYPE_H261_FIL 0x800000
 
+extern uint8_t ff_h261_rl_table_store[2][2 * MAX_RUN + MAX_LEVEL + 3];
+
+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;
+
+void ff_h261_loop_filter(MpegEncContext *s);
+void ff_h261_common_init(void);
+
+int ff_h261_get_picture_format(int width, int height);
+void ff_h261_reorder_mb_index(MpegEncContext *s);
+void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64],
+                       int motion_x, int motion_y);
+void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number);
+void ff_h261_encode_init(MpegEncContext *s);
+
 #endif /* AVCODEC_H261_H */
diff --git a/libavcodec/h261_parser.c b/libavcodec/h261_parser.c
index 8a507ee..2469424 100644
--- a/libavcodec/h261_parser.c
+++ b/libavcodec/h261_parser.c
@@ -27,38 +27,39 @@
 
 #include "parser.h"
 
-
-static int h261_find_frame_end(ParseContext *pc, AVCodecContext* avctx, const uint8_t *buf, int buf_size){
+static int h261_find_frame_end(ParseContext *pc, AVCodecContext *avctx,
+                               const uint8_t *buf, int buf_size)
+{
     int vop_found, i, j;
     uint32_t state;
 
-    vop_found= pc->frame_start_found;
-    state= pc->state;
+    vop_found = pc->frame_start_found;
+    state     = pc->state;
 
-    for(i=0; i<buf_size && !vop_found; i++){
-        state= (state<<8) | buf[i];
-        for(j=0; j<8; j++){
-            if(((state>>j)&0xFFFFF0) == 0x000100){
-                vop_found=1;
+    for (i = 0; i < buf_size && !vop_found; i++) {
+        state = (state << 8) | buf[i];
+        for (j = 0; j < 8; j++) {
+            if (((state >> j) & 0xFFFFF0) == 0x000100) {
+                vop_found = 1;
                 break;
             }
         }
     }
-    if(vop_found){
-        for(; i<buf_size; i++){
-            state= (state<<8) | buf[i];
-            for(j=0; j<8; j++){
-                if(((state>>j)&0xFFFFF0) == 0x000100){
-                    pc->frame_start_found=0;
-                    pc->state= (state>>(3*8))+0xFF00;
-                    return i-2;
+    if (vop_found) {
+        for (; i < buf_size; i++) {
+            state = (state << 8) | buf[i];
+            for (j = 0; j < 8; j++) {
+                if (((state >> j) & 0xFFFFF0) == 0x000100) {
+                    pc->frame_start_found = 0;
+                    pc->state             = (state >> (3 * 8)) + 0xFF00;
+                    return i - 2;
                 }
             }
         }
     }
 
-    pc->frame_start_found= vop_found;
-    pc->state= state;
+    pc->frame_start_found = vop_found;
+    pc->state             = state;
     return END_NOT_FOUND;
 }
 
@@ -70,13 +71,13 @@ static int h261_parse(AVCodecParserContext *s,
     ParseContext *pc = s->priv_data;
     int next;
 
-    next= h261_find_frame_end(pc,avctx, buf, buf_size);
+    next = h261_find_frame_end(pc, avctx, buf, buf_size);
     if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
-        *poutbuf = NULL;
+        *poutbuf      = NULL;
         *poutbuf_size = 0;
         return buf_size;
     }
-    *poutbuf = buf;
+    *poutbuf      = buf;
     *poutbuf_size = buf_size;
     return next;
 }
diff --git a/libavcodec/h261data.c b/libavcodec/h261data.c
new file mode 100644
index 0000000..eb8e64a
--- /dev/null
+++ b/libavcodec/h261data.c
@@ -0,0 +1,155 @@
+/*
+ * copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ * copyright (c) 2004 Maarten Daniels
+ *
+ * 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
+ * H.261 tables.
+ */
+
+#include <stdint.h>
+
+#include "rl.h"
+#include "h261.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_CBP | MB_TYPE_QUANT,
+    MB_TYPE_16x16,
+    MB_TYPE_16x16 | MB_TYPE_CBP,
+    MB_TYPE_16x16 | MB_TYPE_CBP | MB_TYPE_QUANT,
+    MB_TYPE_16x16 | MB_TYPE_H261_FIL,
+    MB_TYPE_16x16 | MB_TYPE_H261_FIL | MB_TYPE_CBP,
+    MB_TYPE_16x16 | MB_TYPE_H261_FIL | MB_TYPE_CBP | MB_TYPE_QUANT
+};
+
+// 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
deleted file mode 100644
index 2c61015..0000000
--- a/libavcodec/h261data.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
- * copyright (c) 2004 Maarten Daniels
- *
- * 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
- * H.261 tables.
- */
-
-#ifndef AVCODEC_H261DATA_H
-#define AVCODEC_H261DATA_H
-
-#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,
-};
-
-#endif /* AVCODEC_H261DATA_H */
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 77c6cab..49eaee1 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -25,12 +25,11 @@
  * H.261 decoder.
  */
 
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
 #include "h261.h"
-#include "h261data.h"
+#include "internal.h"
 
 #define H261_MBA_VLC_BITS 9
 #define H261_MTYPE_VLC_BITS 6
@@ -40,55 +39,50 @@
 #define MBA_STUFFING 33
 #define MBA_STARTCODE 34
 
-extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
-
 static VLC h261_mba_vlc;
 static VLC h261_mtype_vlc;
 static VLC h261_mv_vlc;
 static VLC h261_cbp_vlc;
 
-static int h261_decode_block(H261Context * h, DCTELEM * block, int n, int coded);
-
-static av_cold void h261_decode_init_vlc(H261Context *h){
+static av_cold void h261_decode_init_vlc(H261Context *h)
+{
     static int done = 0;
 
-    if(!done){
+    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);
+        INIT_VLC_RL(ff_h261_rl_tcoeff, 552);
     }
 }
 
-static av_cold int h261_decode_init(AVCodecContext *avctx){
-    H261Context *h= avctx->priv_data;
-    MpegEncContext * const s = &h->s;
+static av_cold int h261_decode_init(AVCodecContext *avctx)
+{
+    H261Context *h          = avctx->priv_data;
+    MpegEncContext *const s = &h->s;
 
     // set defaults
     ff_MPV_decode_defaults(s);
-    s->avctx = avctx;
-
-    s->width  = s->avctx->coded_width;
-    s->height = s->avctx->coded_height;
-    s->codec_id = s->avctx->codec->id;
-
-    s->out_format = FMT_H261;
-    s->low_delay= 1;
-    avctx->pix_fmt= AV_PIX_FMT_YUV420P;
-
-    s->codec_id= avctx->codec->id;
-
+    s->avctx       = avctx;
+    s->width       = s->avctx->coded_width;
+    s->height      = s->avctx->coded_height;
+    s->codec_id    = s->avctx->codec->id;
+    s->out_format  = FMT_H261;
+    s->low_delay   = 1;
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    s->codec_id    = avctx->codec->id;
+
+    ff_h261_common_init();
     h261_decode_init_vlc(h);
 
     h->gob_start_code_skipped = 0;
@@ -100,14 +94,15 @@ static av_cold int h261_decode_init(AVCodecContext *avctx){
  * Decode the group of blocks header or slice header.
  * @return <0 if an error occurred
  */
-static int h261_decode_gob_header(H261Context *h){
+static int h261_decode_gob_header(H261Context *h)
+{
     unsigned int val;
-    MpegEncContext * const s = &h->s;
+    MpegEncContext *const s = &h->s;
 
-    if ( !h->gob_start_code_skipped ){
+    if (!h->gob_start_code_skipped) {
         /* Check for GOB Start Code */
         val = show_bits(&s->gb, 15);
-        if(val)
+        if (val)
             return -1;
 
         /* We have a GBSC */
@@ -117,34 +112,34 @@ static int h261_decode_gob_header(H261Context *h){
     h->gob_start_code_skipped = 0;
 
     h->gob_number = get_bits(&s->gb, 4); /* GN */
-    s->qscale = get_bits(&s->gb, 5); /* GQUANT */
+    s->qscale     = get_bits(&s->gb, 5); /* GQUANT */
 
     /* Check if gob_number is valid */
-    if (s->mb_height==18){ //cif
-        if ((h->gob_number<=0) || (h->gob_number>12))
+    if (s->mb_height == 18) { // CIF
+        if ((h->gob_number <= 0) || (h->gob_number > 12))
             return -1;
-    }
-    else{ //qcif
-        if ((h->gob_number!=1) && (h->gob_number!=3) && (h->gob_number!=5))
+    } else { // QCIF
+        if ((h->gob_number != 1) && (h->gob_number != 3) &&
+            (h->gob_number != 5))
             return -1;
     }
 
     /* GEI */
-    while (get_bits1(&s->gb) != 0) {
+    while (get_bits1(&s->gb) != 0)
         skip_bits(&s->gb, 8);
-    }
 
-    if(s->qscale==0) {
+    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)
             return -1;
     }
 
-    // For the first transmitted macroblock in a GOB, MBA is the absolute address. For
-    // subsequent macroblocks, MBA is the difference between the absolute addresses of
-    // the macroblock and the last transmitted macroblock.
+    /* For the first transmitted macroblock in a GOB, MBA is the absolute
+     * address. For subsequent macroblocks, MBA is the difference between
+     * the absolute addresses of the macroblock and the last transmitted
+     * macroblock. */
     h->current_mba = 0;
-    h->mba_diff = 0;
+    h->mba_diff    = 0;
 
     return 0;
 }
@@ -153,35 +148,35 @@ static int h261_decode_gob_header(H261Context *h){
  * Decode the group of blocks / video packet header.
  * @return <0 if no resync found
  */
-static int ff_h261_resync(H261Context *h){
-    MpegEncContext * const s = &h->s;
+static int h261_resync(H261Context *h)
+{
+    MpegEncContext *const s = &h->s;
     int left, ret;
 
-    if ( h->gob_start_code_skipped ){
-        ret= h261_decode_gob_header(h);
-        if(ret>=0)
+    if (h->gob_start_code_skipped) {
+        ret = h261_decode_gob_header(h);
+        if (ret >= 0)
             return 0;
-    }
-    else{
-        if(show_bits(&s->gb, 15)==0){
-            ret= h261_decode_gob_header(h);
-            if(ret>=0)
+    } else {
+        if (show_bits(&s->gb, 15) == 0) {
+            ret = h261_decode_gob_header(h);
+            if (ret >= 0)
                 return 0;
         }
-        //OK, it is not where it is supposed to be ...
-        s->gb= s->last_resync_gb;
+        // OK, it is not where it is supposed to be ...
+        s->gb = s->last_resync_gb;
         align_get_bits(&s->gb);
-        left= get_bits_left(&s->gb);
+        left = get_bits_left(&s->gb);
 
-        for(;left>15+1+4+5; left-=8){
-            if(show_bits(&s->gb, 15)==0){
-                GetBitContext bak= s->gb;
+        for (; left > 15 + 1 + 4 + 5; left -= 8) {
+            if (show_bits(&s->gb, 15) == 0) {
+                GetBitContext bak = s->gb;
 
-                ret= h261_decode_gob_header(h);
-                if(ret>=0)
+                ret = h261_decode_gob_header(h);
+                if (ret >= 0)
                     return 0;
 
-                s->gb= bak;
+                s->gb = bak;
             }
             skip_bits(&s->gb, 8);
         }
@@ -194,32 +189,32 @@ static int ff_h261_resync(H261Context *h){
  * Decode skipped macroblocks.
  * @return 0
  */
-static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 )
+static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2)
 {
-    MpegEncContext * const s = &h->s;
+    MpegEncContext *const s = &h->s;
     int i;
 
     s->mb_intra = 0;
 
-    for(i=mba1; i<mba2; i++){
+    for (i = mba1; i < mba2; i++) {
         int j, xy;
 
-        s->mb_x= ((h->gob_number-1) % 2) * 11 + i % 11;
-        s->mb_y= ((h->gob_number-1) / 2) * 3 + i / 11;
-        xy = s->mb_x + s->mb_y * s->mb_stride;
+        s->mb_x = ((h->gob_number - 1) % 2) * 11 + i % 11;
+        s->mb_y = ((h->gob_number - 1) / 2) * 3 + i / 11;
+        xy      = s->mb_x + s->mb_y * s->mb_stride;
         ff_init_block_index(s);
         ff_update_block_index(s);
 
-        for(j=0;j<6;j++)
+        for (j = 0; j < 6; j++)
             s->block_last_index[j] = -1;
 
-        s->mv_dir = MV_DIR_FORWARD;
-        s->mv_type = MV_TYPE_16X16;
-        s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
-        s->mv[0][0][0] = 0;
-        s->mv[0][0][1] = 0;
-        s->mb_skipped = 1;
-        h->mtype &= ~MB_TYPE_H261_FIL;
+        s->mv_dir                      = MV_DIR_FORWARD;
+        s->mv_type                     = MV_TYPE_16X16;
+        s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+        s->mv[0][0][0]                 = 0;
+        s->mv[0][0][1]                 = 0;
+        s->mb_skipped                  = 1;
+        h->mtype                      &= ~MB_TYPE_H261_FIL;
 
         ff_MPV_decode_mb(s, s->block);
     }
@@ -227,44 +222,140 @@ static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 )
     return 0;
 }
 
-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
+};
+
+static int decode_mv_component(GetBitContext *gb, int v)
+{
     int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2);
 
     /* check if mv_diff is valid */
-    if ( mv_diff < 0 )
+    if (mv_diff < 0)
         return v;
 
     mv_diff = mvmap[mv_diff];
 
-    if(mv_diff && !get_bits1(gb))
-        mv_diff= -mv_diff;
+    if (mv_diff && !get_bits1(gb))
+        mv_diff = -mv_diff;
 
     v += mv_diff;
-    if     (v <=-16) v+= 32;
-    else if(v >= 16) v-= 32;
+    if (v <= -16)
+        v += 32;
+    else if (v >= 16)
+        v -= 32;
 
     return v;
 }
 
-static int h261_decode_mb(H261Context *h){
-    MpegEncContext * const s = &h->s;
+/**
+ * Decode a macroblock.
+ * @return <0 if an error occurred
+ */
+static int h261_decode_block(H261Context *h, int16_t *block, int n, int coded)
+{
+    MpegEncContext *const s = &h->s;
+    int code, level, i, j, run;
+    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 the first transmitted LEVEL in INTER, INTER + MC and
+     * INTER + MC + FIL blocks, the second for all other LEVELs except the
+     * first one in INTRA blocks which is fixed length coded with 8 bits.
+     * NOTE: The two code tables only differ in one VLC so we handle that
+     * manually. */
+    scan_table = s->intra_scantable.permutated;
+    if (s->mb_intra) {
+        /* DC coef */
+        level = get_bits(&s->gb, 8);
+        // 0 (00000000b) and -128 (10000000b) are FORBIDDEN
+        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);
+            return -1;
+        }
+        /* The code 1000 0000 is not used, the reconstruction level of 1024
+         * being coded as 1111 1111. */
+        if (level == 255)
+            level = 128;
+        block[0] = level;
+        i        = 1;
+    } else if (coded) {
+        // Run  Level   Code
+        // EOB          Not possible for first level when cbp is available (that's why the table is different)
+        // 0    1       1s
+        // *    *       0*
+        int check = show_bits(&s->gb, 2);
+        i = 0;
+        if (check & 0x2) {
+            skip_bits(&s->gb, 2);
+            block[0] = (check & 0x1) ? -1 : 1;
+            i        = 1;
+        }
+    } else {
+        i = 0;
+    }
+    if (!coded) {
+        s->block_last_index[n] = i - 1;
+        return 0;
+    }
+    for (;;) {
+        code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2);
+        if (code < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n",
+                   s->mb_x, s->mb_y);
+            return -1;
+        }
+        if (code == rl->n) {
+            /* escape */
+            /* The remaining combinations of (run, level) are encoded with a
+             * 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits
+             * level. */
+            run   = get_bits(&s->gb, 6);
+            level = get_sbits(&s->gb, 8);
+        } else if (code == 0) {
+            break;
+        } else {
+            run   = rl->table_run[code];
+            level = rl->table_level[code];
+            if (get_bits1(&s->gb))
+                level = -level;
+        }
+        i += run;
+        if (i >= 64) {
+            av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n",
+                   s->mb_x, s->mb_y);
+            return -1;
+        }
+        j        = scan_table[i];
+        block[j] = level;
+        i++;
+    }
+    s->block_last_index[n] = i - 1;
+    return 0;
+}
+
+static int h261_decode_mb(H261Context *h)
+{
+    MpegEncContext *const s = &h->s;
     int i, cbp, xy;
 
     cbp = 63;
     // Read mba
-    do{
-        h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, H261_MBA_VLC_BITS, 2);
+    do {
+        h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table,
+                               H261_MBA_VLC_BITS, 2);
 
         /* Check for slice end */
         /* NOTE: GOB can be empty (no MB data) or exist only of MBA_stuffing */
-        if (h->mba_diff == MBA_STARTCODE){ // start code
+        if (h->mba_diff == MBA_STARTCODE) { // start code
             h->gob_start_code_skipped = 1;
             return SLICE_END;
         }
-    }
-    while( h->mba_diff == MBA_STUFFING ); // stuffing
+    } while (h->mba_diff == MBA_STUFFING); // stuffing
 
-    if ( h->mba_diff < 0 ){
+    if (h->mba_diff < 0) {
         if (get_bits_left(&s->gb) <= 7)
             return SLICE_END;
 
@@ -272,86 +363,84 @@ static int h261_decode_mb(H261Context *h){
         return SLICE_ERROR;
     }
 
-    h->mba_diff += 1;
+    h->mba_diff    += 1;
     h->current_mba += h->mba_diff;
 
-    if ( h->current_mba > MBA_STUFFING )
+    if (h->current_mba > MBA_STUFFING)
         return SLICE_ERROR;
 
-    s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1) % 11);
-    s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1) / 11);
-    xy = s->mb_x + s->mb_y * s->mb_stride;
+    s->mb_x = ((h->gob_number - 1) % 2) * 11 + ((h->current_mba - 1) % 11);
+    s->mb_y = ((h->gob_number - 1) / 2) * 3 + ((h->current_mba - 1) / 11);
+    xy      = s->mb_x + s->mb_y * s->mb_stride;
     ff_init_block_index(s);
     ff_update_block_index(s);
 
     // Read mtype
     h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2);
-    if (h->mtype < 0 || h->mtype >= FF_ARRAY_ELEMS(h261_mtype_map)) {
+    if (h->mtype < 0 || h->mtype >= FF_ARRAY_ELEMS(ff_h261_mtype_map)) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid mtype index %d\n",
                h->mtype);
         return SLICE_ERROR;
     }
-    h->mtype = h261_mtype_map[h->mtype];
+    h->mtype = ff_h261_mtype_map[h->mtype];
 
     // Read mquant
-    if ( IS_QUANT ( h->mtype ) ){
+    if (IS_QUANT(h->mtype))
         ff_set_qscale(s, get_bits(&s->gb, 5));
-    }
 
     s->mb_intra = IS_INTRA4x4(h->mtype);
 
     // Read mv
-    if ( IS_16X16 ( h->mtype ) ){
-        // Motion vector data is included for all MC macroblocks. MVD is obtained from the macroblock vector by subtracting the
-        // vector of the preceding macroblock. For this calculation the vector of the preceding macroblock is regarded as zero in the
-        // following three situations:
-        // 1) evaluating MVD for macroblocks 1, 12 and 23;
-        // 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1;
-        // 3) MTYPE of the previous macroblock was not MC.
-        if ( ( h->current_mba == 1 ) || ( h->current_mba == 12 ) || ( h->current_mba == 23 ) ||
-             ( h->mba_diff != 1))
-        {
+    if (IS_16X16(h->mtype)) {
+        /* Motion vector data is included for all MC macroblocks. MVD is
+         * obtained from the macroblock vector by subtracting the vector
+         * of the preceding macroblock. For this calculation the vector
+         * of the preceding macroblock is regarded as zero in the
+         * following three situations:
+         * 1) evaluating MVD for macroblocks 1, 12 and 23;
+         * 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1;
+         * 3) MTYPE of the previous macroblock was not MC. */
+        if ((h->current_mba ==  1) || (h->current_mba == 12) ||
+            (h->current_mba == 23) || (h->mba_diff != 1)) {
             h->current_mv_x = 0;
             h->current_mv_y = 0;
         }
 
-        h->current_mv_x= decode_mv_component(&s->gb, h->current_mv_x);
-        h->current_mv_y= decode_mv_component(&s->gb, h->current_mv_y);
-    }else{
+        h->current_mv_x = decode_mv_component(&s->gb, h->current_mv_x);
+        h->current_mv_y = decode_mv_component(&s->gb, h->current_mv_y);
+    } else {
         h->current_mv_x = 0;
         h->current_mv_y = 0;
     }
 
     // Read cbp
-    if ( HAS_CBP( h->mtype ) ){
+    if (HAS_CBP(h->mtype))
         cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1;
-    }
 
-    if(s->mb_intra){
-        s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+    if (s->mb_intra) {
+        s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
         goto intra;
     }
 
     //set motion vectors
-    s->mv_dir = MV_DIR_FORWARD;
-    s->mv_type = MV_TYPE_16X16;
-    s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
-    s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation
-    s->mv[0][0][1] = h->current_mv_y * 2;
+    s->mv_dir                      = MV_DIR_FORWARD;
+    s->mv_type                     = MV_TYPE_16X16;
+    s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+    s->mv[0][0][0]                 = h->current_mv_x * 2; // gets divided by 2 in motion compensation
+    s->mv[0][0][1]                 = h->current_mv_y * 2;
 
 intra:
     /* decode each block */
-    if(s->mb_intra || HAS_CBP(h->mtype)){
+    if (s->mb_intra || HAS_CBP(h->mtype)) {
         s->dsp.clear_blocks(s->block[0]);
         for (i = 0; i < 6; i++) {
-            if (h261_decode_block(h, s->block[i], i, cbp&32) < 0){
+            if (h261_decode_block(h, s->block[i], i, cbp & 32) < 0)
                 return SLICE_ERROR;
-            }
-            cbp+=cbp;
+            cbp += cbp;
         }
-    }else{
+    } else {
         for (i = 0; i < 6; i++)
-            s->block_last_index[i]= -1;
+            s->block_last_index[i] = -1;
     }
 
     ff_MPV_decode_mb(s, s->block);
@@ -360,117 +449,34 @@ intra:
 }
 
 /**
- * Decode a macroblock.
- * @return <0 if an error occurred
- */
-static int h261_decode_block(H261Context * h, DCTELEM * block,
-                             int n, int coded)
-{
-    MpegEncContext * const s = &h->s;
-    int code, level, i, j, run;
-    RLTable *rl = &h261_rl_tcoeff;
-    const uint8_t *scan_table;
-
-    // For the variable length encoding there are two code tables, one being used for
-    // the first transmitted LEVEL in INTER, INTER+MC and INTER+MC+FIL blocks, the second
-    // for all other LEVELs except the first one in INTRA blocks which is fixed length
-    // coded with 8 bits.
-    // NOTE: the two code tables only differ in one VLC so we handle that manually.
-    scan_table = s->intra_scantable.permutated;
-    if (s->mb_intra){
-        /* DC coef */
-        level = get_bits(&s->gb, 8);
-        // 0 (00000000b) and -128 (10000000b) are FORBIDDEN
-        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);
-            return -1;
-        }
-        // The code 1000 0000 is not used, the reconstruction level of 1024 being coded as 1111 1111.
-        if (level == 255)
-            level = 128;
-        block[0] = level;
-        i = 1;
-    }else if(coded){
-        // Run  Level   Code
-        // EOB                  Not possible for first level when cbp is available (that's why the table is different)
-        // 0    1               1s
-        // *    *               0*
-        int check = show_bits(&s->gb, 2);
-        i = 0;
-        if ( check & 0x2 ){
-            skip_bits(&s->gb, 2);
-            block[0] = ( check & 0x1 ) ? -1 : 1;
-            i = 1;
-        }
-    }else{
-        i = 0;
-    }
-    if(!coded){
-        s->block_last_index[n] = i - 1;
-        return 0;
-    }
-    for(;;){
-        code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2);
-        if (code < 0){
-            av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y);
-            return -1;
-        }
-        if (code == rl->n) {
-            /* escape */
-            // The remaining combinations of (run, level) are encoded with a 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits level.
-            run = get_bits(&s->gb, 6);
-            level = get_sbits(&s->gb, 8);
-        }else if(code == 0){
-            break;
-        }else{
-            run = rl->table_run[code];
-            level = rl->table_level[code];
-            if (get_bits1(&s->gb))
-                level = -level;
-        }
-        i += run;
-        if (i >= 64){
-            av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y);
-            return -1;
-        }
-        j = scan_table[i];
-        block[j] = level;
-        i++;
-    }
-    s->block_last_index[n] = i-1;
-    return 0;
-}
-
-/**
  * Decode the H.261 picture header.
  * @return <0 if no startcode found
  */
-static int h261_decode_picture_header(H261Context *h){
-    MpegEncContext * const s = &h->s;
+static int h261_decode_picture_header(H261Context *h)
+{
+    MpegEncContext *const s = &h->s;
     int format, i;
-    uint32_t startcode= 0;
+    uint32_t startcode = 0;
 
-    for(i= get_bits_left(&s->gb); i>24; i-=1){
+    for (i = get_bits_left(&s->gb); i > 24; i -= 1) {
         startcode = ((startcode << 1) | get_bits(&s->gb, 1)) & 0x000FFFFF;
 
-        if(startcode == 0x10)
+        if (startcode == 0x10)
             break;
     }
 
-    if (startcode != 0x10){
+    if (startcode != 0x10) {
         av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");
         return -1;
     }
 
     /* temporal reference */
-    i= get_bits(&s->gb, 5); /* picture timestamp */
-    if(i < (s->picture_number&31))
+    i = get_bits(&s->gb, 5); /* picture timestamp */
+    if (i < (s->picture_number & 31))
         i += 32;
-    s->picture_number = (s->picture_number&~31) + i;
-
-    s->avctx->time_base= (AVRational){1001, 30000};
-    s->current_picture.f.pts = s->picture_number;
+    s->picture_number = (s->picture_number & ~31) + i;
 
+    s->avctx->time_base      = (AVRational) { 1001, 30000 };
 
     /* PTYPE starts here */
     skip_bits1(&s->gb); /* split screen off */
@@ -479,16 +485,16 @@ static int h261_decode_picture_header(H261Context *h){
 
     format = get_bits1(&s->gb);
 
-    //only 2 formats possible
-    if (format == 0){//QCIF
-        s->width = 176;
-        s->height = 144;
-        s->mb_width = 11;
+    // only 2 formats possible
+    if (format == 0) { // QCIF
+        s->width     = 176;
+        s->height    = 144;
+        s->mb_width  = 11;
         s->mb_height = 9;
-    }else{//CIF
-        s->width = 352;
-        s->height = 288;
-        s->mb_width = 22;
+    } else { // CIF
+        s->width     = 352;
+        s->height    = 288;
+        s->mb_width  = 22;
         s->mb_height = 18;
     }
 
@@ -498,39 +504,42 @@ static int h261_decode_picture_header(H261Context *h){
     skip_bits1(&s->gb); /* Reserved */
 
     /* PEI */
-    while (get_bits1(&s->gb) != 0){
+    while (get_bits1(&s->gb) != 0)
         skip_bits(&s->gb, 8);
-    }
 
-    // h261 has no I-FRAMES, but if we pass AV_PICTURE_TYPE_I for the first frame, the codec crashes if it does
-    // not contain all I-blocks (e.g. when a packet is lost)
+    /* H.261 has no I-frames, but if we pass AV_PICTURE_TYPE_I for the first
+     * frame, the codec crashes if it does not contain all I-blocks
+     * (e.g. when a packet is lost). */
     s->pict_type = AV_PICTURE_TYPE_P;
 
     h->gob_number = 0;
     return 0;
 }
 
-static int h261_decode_gob(H261Context *h){
-    MpegEncContext * const s = &h->s;
+static int h261_decode_gob(H261Context *h)
+{
+    MpegEncContext *const s = &h->s;
 
     ff_set_qscale(s, s->qscale);
 
     /* decode mb's */
-    while(h->current_mba <= MBA_STUFFING)
-    {
+    while (h->current_mba <= MBA_STUFFING) {
         int ret;
         /* DCT & quantize */
-        ret= h261_decode_mb(h);
-        if(ret<0){
-            if(ret==SLICE_END){
+        ret = h261_decode_mb(h);
+        if (ret < 0) {
+            if (ret == SLICE_END) {
                 h261_decode_mb_skipped(h, h->current_mba, 33);
                 return 0;
             }
-            av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", s->mb_x + s->mb_y*s->mb_stride);
+            av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n",
+                   s->mb_x + s->mb_y * s->mb_stride);
             return -1;
         }
 
-        h261_decode_mb_skipped(h, h->current_mba-h->mba_diff, h->current_mba-1);
+        h261_decode_mb_skipped(h,
+                               h->current_mba - h->mba_diff,
+                               h->current_mba - 1);
     }
 
     return -1;
@@ -539,65 +548,60 @@ static int h261_decode_gob(H261Context *h){
 /**
  * returns the number of bytes consumed for building the current frame
  */
-static int get_consumed_bytes(MpegEncContext *s, int buf_size){
-    int pos= get_bits_count(&s->gb)>>3;
-    if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...)
-    if(pos+10>buf_size) pos=buf_size; // oops ;)
+static int get_consumed_bytes(MpegEncContext *s, int buf_size)
+{
+    int pos = get_bits_count(&s->gb) >> 3;
+    if (pos == 0)
+        pos = 1;      // avoid infinite loops (i doubt that is needed but ...)
+    if (pos + 10 > buf_size)
+        pos = buf_size;               // oops ;)
 
     return pos;
 }
 
-static int h261_decode_frame(AVCodecContext *avctx,
-                             void *data, int *got_frame,
-                             AVPacket *avpkt)
+static int h261_decode_frame(AVCodecContext *avctx, void *data,
+                             int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    H261Context *h= avctx->priv_data;
-    MpegEncContext *s = &h->s;
+    int buf_size       = avpkt->size;
+    H261Context *h     = avctx->priv_data;
+    MpegEncContext *s  = &h->s;
     int ret;
     AVFrame *pict = data;
 
     av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
     av_dlog(avctx, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
-    s->flags= avctx->flags;
-    s->flags2= avctx->flags2;
+    s->flags  = avctx->flags;
+    s->flags2 = avctx->flags2;
 
-    h->gob_start_code_skipped=0;
+    h->gob_start_code_skipped = 0;
 
 retry:
+    init_get_bits(&s->gb, buf, buf_size * 8);
 
-    init_get_bits(&s->gb, buf, buf_size*8);
-
-    if(!s->context_initialized){
-        if (ff_MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix
+    if (!s->context_initialized)
+        // we need the IDCT permutaton for reading a custom matrix
+        if (ff_MPV_common_init(s) < 0)
             return -1;
-    }
-
-    //we need to set current_picture_ptr before reading the header, otherwise we cannot store anyting im there
-    if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
-        int i= ff_find_unused_picture(s, 0);
-        if (i < 0)
-            return i;
-        s->current_picture_ptr= &s->picture[i];
-    }
 
     ret = h261_decode_picture_header(h);
 
     /* skip if the header was thrashed */
-    if (ret < 0){
+    if (ret < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
         return -1;
     }
 
-    if (s->width != avctx->coded_width || s->height != avctx->coded_height){
-        ParseContext pc= s->parse_context; //FIXME move this demuxing hack to libavformat
-        s->parse_context.buffer=0;
+    if (s->width != avctx->coded_width || s->height != avctx->coded_height) {
+        ParseContext pc = s->parse_context; // FIXME move this demuxing hack to libavformat
+        s->parse_context.buffer = 0;
         ff_MPV_common_end(s);
-        s->parse_context= pc;
+        s->parse_context = pc;
     }
     if (!s->context_initialized) {
-        avcodec_set_dimensions(avctx, s->width, s->height);
+        ret = ff_set_dimensions(avctx, s->width, s->height);
+        if (ret < 0)
+            return ret;
 
         goto retry;
     }
@@ -606,32 +610,33 @@ retry:
     s->current_picture.f.pict_type = s->pict_type;
     s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
-    if(  (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B)
-       ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I)
-       || avctx->skip_frame >= AVDISCARD_ALL)
+    if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) ||
+        (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) ||
+         avctx->skip_frame >= AVDISCARD_ALL)
         return get_consumed_bytes(s, buf_size);
 
-    if(ff_MPV_frame_start(s, avctx) < 0)
+    if (ff_MPV_frame_start(s, avctx) < 0)
         return -1;
 
-    ff_er_frame_start(s);
+    ff_mpeg_er_frame_start(s);
 
     /* decode each macroblock */
-    s->mb_x=0;
-    s->mb_y=0;
+    s->mb_x = 0;
+    s->mb_y = 0;
 
-    while(h->gob_number < (s->mb_height==18 ? 12 : 5)){
-        if(ff_h261_resync(h)<0)
+    while (h->gob_number < (s->mb_height == 18 ? 12 : 5)) {
+        if (h261_resync(h) < 0)
             break;
         h261_decode_gob(h);
     }
     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);
+    assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
+    assert(s->current_picture.f.pict_type == s->pict_type);
 
-    *pict = s->current_picture_ptr->f;
-    ff_print_debug_info(s, pict);
+    if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+        return ret;
+    ff_print_debug_info(s, s->current_picture_ptr);
 
     *got_frame = 1;
 
@@ -640,7 +645,7 @@ assert(s->current_picture.f.pict_type == s->pict_type);
 
 static av_cold int h261_decode_end(AVCodecContext *avctx)
 {
-    H261Context *h= avctx->priv_data;
+    H261Context *h    = avctx->priv_data;
     MpegEncContext *s = &h->s;
 
     ff_MPV_common_end(s);
@@ -649,6 +654,7 @@ static av_cold int h261_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_h261_decoder = {
     .name           = "h261",
+    .long_name      = NULL_IF_CONFIG_SMALL("H.261"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H261,
     .priv_data_size = sizeof(H261Context),
@@ -656,5 +662,4 @@ AVCodec ff_h261_decoder = {
     .close          = h261_decode_end,
     .decode         = h261_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("H.261"),
 };
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index d6b4cfc..4cff998 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -25,19 +25,14 @@
  * H.261 encoder.
  */
 
-#include "dsputil.h"
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
 #include "h261.h"
-#include "h261data.h"
 
-extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
-
-static void h261_encode_block(H261Context * h, DCTELEM * block,
-                              int n);
-
-int ff_h261_get_picture_format(int width, int height){
+int ff_h261_get_picture_format(int width, int height)
+{
     // QCIF
     if (width == 176 && height == 144)
         return 0;
@@ -49,8 +44,9 @@ int ff_h261_get_picture_format(int width, int height){
         return -1;
 }
 
-void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){
-    H261Context * h = (H261Context *) s;
+void ff_h261_encode_picture_header(MpegEncContext *s, int picture_number)
+{
+    H261Context *h = (H261Context *)s;
     int format, temp_ref;
 
     avpriv_align_put_bits(&s->pb);
@@ -60,8 +56,8 @@ void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){
 
     put_bits(&s->pb, 20, 0x10); /* PSC */
 
-    temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num /
-                         (1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp
+    temp_ref = s->picture_number * (int64_t)30000 * s->avctx->time_base.num /
+               (1001 * (int64_t)s->avctx->time_base.den);   // FIXME maybe this should use a timestamp
     put_sbits(&s->pb, 5, temp_ref); /* TemporalReference */
 
     put_bits(&s->pb, 1, 0); /* split screen off */
@@ -76,7 +72,7 @@ void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){
     put_bits(&s->pb, 1, 0); /* reserved */
 
     put_bits(&s->pb, 1, 0); /* no PEI */
-    if(format == 0)
+    if (format == 0)
         h->gob_number = -1;
     else
         h->gob_number = 0;
@@ -86,192 +82,99 @@ void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){
 /**
  * Encode a group of blocks header.
  */
-static void h261_encode_gob_header(MpegEncContext * s, int mb_line){
-    H261Context * h = (H261Context *)s;
-    if(ff_h261_get_picture_format(s->width, s->height) == 0){
-        h->gob_number+=2; // QCIF
-    }
-    else{
-        h->gob_number++; // CIF
+static void h261_encode_gob_header(MpegEncContext *s, int mb_line)
+{
+    H261Context *h = (H261Context *)s;
+    if (ff_h261_get_picture_format(s->width, s->height) == 0) {
+        h->gob_number += 2; // QCIF
+    } else {
+        h->gob_number++;    // CIF
     }
-    put_bits(&s->pb, 16, 1); /* GBSC */
+    put_bits(&s->pb, 16, 1);            /* GBSC */
     put_bits(&s->pb, 4, h->gob_number); /* GN */
-    put_bits(&s->pb, 5, s->qscale); /* GQUANT */
-    put_bits(&s->pb, 1, 0); /* no GEI */
-    h->current_mba = 0;
+    put_bits(&s->pb, 5, s->qscale);     /* GQUANT */
+    put_bits(&s->pb, 1, 0);             /* no GEI */
+    h->current_mba  = 0;
     h->previous_mba = 0;
-    h->current_mv_x=0;
-    h->current_mv_y=0;
+    h->current_mv_x = 0;
+    h->current_mv_y = 0;
 }
 
-void ff_h261_reorder_mb_index(MpegEncContext* s){
-    int index= s->mb_x + s->mb_y*s->mb_width;
+void ff_h261_reorder_mb_index(MpegEncContext *s)
+{
+    int index = s->mb_x + s->mb_y * s->mb_width;
 
-    if(index % 33 == 0)
-        h261_encode_gob_header(s,0);
+    if (index % 33 == 0)
+        h261_encode_gob_header(s, 0);
 
     /* for CIF the GOB's are fragmented in the middle of a scanline
-       that's why we need to adjust the x and y index of the macroblocks */
-    if(ff_h261_get_picture_format(s->width,s->height) == 1){ // CIF
-        s->mb_x =     index % 11 ; index /= 11;
-        s->mb_y =     index %  3 ; index /=  3;
-        s->mb_x+= 11*(index %  2); index /=  2;
-        s->mb_y+=  3*index;
+     * that's why we need to adjust the x and y index of the macroblocks */
+    if (ff_h261_get_picture_format(s->width, s->height) == 1) { // CIF
+        s->mb_x  = index % 11;
+        index   /= 11;
+        s->mb_y  = index % 3;
+        index   /= 3;
+        s->mb_x += 11 * (index % 2);
+        index   /= 2;
+        s->mb_y += 3 * index;
 
         ff_init_block_index(s);
         ff_update_block_index(s);
     }
 }
 
-static void h261_encode_motion(H261Context * h, int val){
-    MpegEncContext * const s = &h->s;
+static void h261_encode_motion(H261Context *h, int val)
+{
+    MpegEncContext *const s = &h->s;
     int sign, code;
-    if(val==0){
+    if (val == 0) {
         code = 0;
-        put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]);
-    }
-    else{
-        if(val > 15)
-            val -=32;
-        if(val < -16)
-            val+=32;
+        put_bits(&s->pb, ff_h261_mv_tab[code][1], ff_h261_mv_tab[code][0]);
+    } else {
+        if (val > 15)
+            val -= 32;
+        if (val < -16)
+            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,1,sign);
+        put_bits(&s->pb, ff_h261_mv_tab[code][1], ff_h261_mv_tab[code][0]);
+        put_bits(&s->pb, 1, sign);
     }
 }
 
-static inline int get_cbp(MpegEncContext * s,
-                      DCTELEM block[6][64])
+static inline int get_cbp(MpegEncContext *s, int16_t block[6][64])
 {
     int i, cbp;
-    cbp= 0;
-    for (i = 0; i < 6; i++) {
+    cbp = 0;
+    for (i = 0; i < 6; i++)
         if (s->block_last_index[i] >= 0)
             cbp |= 1 << (5 - i);
-    }
     return cbp;
 }
-void ff_h261_encode_mb(MpegEncContext * s,
-         DCTELEM block[6][64],
-         int motion_x, int motion_y)
-{
-    H261Context * h = (H261Context *)s;
-    int mvd, mv_diff_x, mv_diff_y, i, cbp;
-    cbp = 63; // avoid warning
-    mvd = 0;
-
-    h->current_mba++;
-    h->mtype = 0;
-
-    if (!s->mb_intra){
-        /* compute cbp */
-        cbp= get_cbp(s, block);
-
-        /* mvd indicates if this block is motion compensated */
-        mvd = motion_x | motion_y;
-
-        if((cbp | mvd | s->dquant ) == 0) {
-            /* skip macroblock */
-            s->skip_count++;
-            h->current_mv_x=0;
-            h->current_mv_y=0;
-            return;
-        }
-    }
-
-    /* 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]);
-
-    /* calculate MTYPE */
-    if(!s->mb_intra){
-        h->mtype++;
-
-        if(mvd || s->loop_filter)
-            h->mtype+=3;
-        if(s->loop_filter)
-            h->mtype+=3;
-        if(cbp || s->dquant)
-            h->mtype++;
-        assert(h->mtype > 1);
-    }
-
-    if(s->dquant)
-        h->mtype++;
-
-    put_bits(&s->pb, h261_mtype_bits[h->mtype], h261_mtype_code[h->mtype]);
-
-    h->mtype = h261_mtype_map[h->mtype];
-
-    if(IS_QUANT(h->mtype)){
-        ff_set_qscale(s,s->qscale+s->dquant);
-        put_bits(&s->pb, 5, s->qscale);
-    }
-
-    if(IS_16X16(h->mtype)){
-        mv_diff_x = (motion_x >> 1) - h->current_mv_x;
-        mv_diff_y = (motion_y >> 1) - h->current_mv_y;
-        h->current_mv_x = (motion_x >> 1);
-        h->current_mv_y = (motion_y >> 1);
-        h261_encode_motion(h,mv_diff_x);
-        h261_encode_motion(h,mv_diff_y);
-    }
-
-    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]);
-    }
-    for(i=0; i<6; i++) {
-        /* encode each block */
-        h261_encode_block(h, block[i], i);
-    }
-
-    if ( ( h->current_mba == 11 ) || ( h->current_mba == 22 ) || ( h->current_mba == 33 ) || ( !IS_16X16 ( h->mtype ) )){
-        h->current_mv_x=0;
-        h->current_mv_y=0;
-    }
-}
-
-void ff_h261_encode_init(MpegEncContext *s){
-    static int done = 0;
-
-    if (!done) {
-        done = 1;
-        ff_init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store);
-    }
-
-    s->min_qcoeff= -127;
-    s->max_qcoeff=  127;
-    s->y_dc_scale_table=
-    s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
-}
-
 
 /**
  * Encode an 8x8 block.
  * @param block the 8x8 block
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static void h261_encode_block(H261Context * h, DCTELEM * block, int n){
-    MpegEncContext * const s = &h->s;
+static void h261_encode_block(H261Context *h, int16_t *block, int n)
+{
+    MpegEncContext *const s = &h->s;
     int level, run, i, j, last_index, last_non_zero, sign, slevel, code;
     RLTable *rl;
 
-    rl = &h261_rl_tcoeff;
+    rl = &ff_h261_rl_tcoeff;
     if (s->mb_intra) {
         /* DC coef */
         level = block[0];
         /* 255 cannot be represented, so we clamp */
         if (level > 254) {
-            level = 254;
+            level    = 254;
             block[0] = 254;
         }
         /* 0 cannot be represented also */
         else if (level < 1) {
-            level = 1;
+            level    = 1;
             block[0] = 1;
         }
         if (level == 128)
@@ -279,31 +182,33 @@ static void h261_encode_block(H261Context * h, DCTELEM * block, int n){
         else
             put_bits(&s->pb, 8, level);
         i = 1;
-    } else if((block[0]==1 || block[0] == -1) && (s->block_last_index[n] > -1)){
-        //special case
-        put_bits(&s->pb,2,block[0]>0 ? 2 : 3 );
+    } else if ((block[0] == 1 || block[0] == -1) &&
+               (s->block_last_index[n] > -1)) {
+        // special case
+        put_bits(&s->pb, 2, block[0] > 0 ? 2 : 3);
         i = 1;
     } else {
         i = 0;
     }
 
     /* AC coefs */
-    last_index = s->block_last_index[n];
+    last_index    = s->block_last_index[n];
     last_non_zero = i - 1;
     for (; i <= last_index; i++) {
-        j = s->intra_scantable.permutated[i];
+        j     = s->intra_scantable.permutated[i];
         level = block[j];
         if (level) {
-            run = i - last_non_zero - 1;
-            sign = 0;
+            run    = i - last_non_zero - 1;
+            sign   = 0;
             slevel = level;
             if (level < 0) {
-                sign = 1;
+                sign  = 1;
                 level = -level;
             }
-            code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, run, level);
-            if(run==0 && level < 16)
-            code+=1;
+            code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/,
+                                run, level);
+            if (run == 0 && level < 16)
+                code += 1;
             put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
             if (code == rl->n) {
                 put_bits(&s->pb, 6, run);
@@ -316,22 +221,119 @@ static void h261_encode_block(H261Context * h, DCTELEM * block, int n){
             last_non_zero = i;
         }
     }
-    if(last_index > -1){
-        put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]);// END OF BLOCK
+    if (last_index > -1)
+        put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]); // EOB
+}
+
+void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64],
+                       int motion_x, int motion_y)
+{
+    H261Context *h = (H261Context *)s;
+    int mvd, mv_diff_x, mv_diff_y, i, cbp;
+    cbp = 63; // avoid warning
+    mvd = 0;
+
+    h->current_mba++;
+    h->mtype = 0;
+
+    if (!s->mb_intra) {
+        /* compute cbp */
+        cbp = get_cbp(s, block);
+
+        /* mvd indicates if this block is motion compensated */
+        mvd = motion_x | motion_y;
+
+        if ((cbp | mvd | s->dquant) == 0) {
+            /* skip macroblock */
+            s->skip_count++;
+            h->current_mv_x = 0;
+            h->current_mv_y = 0;
+            return;
+        }
+    }
+
+    /* MB is not skipped, encode MBA */
+    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) {
+        h->mtype++;
+
+        if (mvd || s->loop_filter)
+            h->mtype += 3;
+        if (s->loop_filter)
+            h->mtype += 3;
+        if (cbp || s->dquant)
+            h->mtype++;
+        assert(h->mtype > 1);
+    }
+
+    if (s->dquant)
+        h->mtype++;
+
+    put_bits(&s->pb,
+             ff_h261_mtype_bits[h->mtype],
+             ff_h261_mtype_code[h->mtype]);
+
+    h->mtype = ff_h261_mtype_map[h->mtype];
+
+    if (IS_QUANT(h->mtype)) {
+        ff_set_qscale(s, s->qscale + s->dquant);
+        put_bits(&s->pb, 5, s->qscale);
+    }
+
+    if (IS_16X16(h->mtype)) {
+        mv_diff_x       = (motion_x >> 1) - h->current_mv_x;
+        mv_diff_y       = (motion_y >> 1) - h->current_mv_y;
+        h->current_mv_x = (motion_x >> 1);
+        h->current_mv_y = (motion_y >> 1);
+        h261_encode_motion(h, mv_diff_x);
+        h261_encode_motion(h, mv_diff_y);
+    }
+
+    h->previous_mba = h->current_mba;
+
+    if (HAS_CBP(h->mtype)) {
+        assert(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 */
+        h261_encode_block(h, block[i], i);
+
+    if ((h->current_mba == 11) || (h->current_mba == 22) ||
+        (h->current_mba == 33) || (!IS_16X16(h->mtype))) {
+        h->current_mv_x = 0;
+        h->current_mv_y = 0;
     }
 }
 
+av_cold void ff_h261_encode_init(MpegEncContext *s)
+{
+    ff_h261_common_init();
+
+    s->min_qcoeff       = -127;
+    s->max_qcoeff       = 127;
+    s->y_dc_scale_table =
+    s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
+}
+
 FF_MPV_GENERIC_CLASS(h261)
 
 AVCodec ff_h261_encoder = {
     .name           = "h261",
+    .long_name      = NULL_IF_CONFIG_SMALL("H.261"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H261,
     .priv_data_size = sizeof(H261Context),
     .init           = ff_MPV_encode_init,
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("H.261"),
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
+                                                     AV_PIX_FMT_NONE },
     .priv_class     = &h261_class,
 };
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index 7f1966f..2fa6ca3 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -27,10 +27,8 @@
  * h263/mpeg4 codec.
  */
 
-//#define DEBUG
 #include <limits.h>
 
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -40,8 +38,6 @@
 #include "flv.h"
 #include "mpeg4video.h"
 
-//#undef NDEBUG
-//#include <assert.h>
 
 uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
 
@@ -52,7 +48,7 @@ void ff_h263_update_motion_val(MpegEncContext * s){
     const int wrap = s->b8_stride;
     const int xy = s->block_index[0];
 
-    s->current_picture.f.mbskip_table[mb_xy] = s->mb_skipped;
+    s->current_picture.mbskip_table[mb_xy] = s->mb_skipped;
 
     if(s->mv_type != MV_TYPE_8X8){
         int motion_x, motion_y;
@@ -71,30 +67,30 @@ void ff_h263_update_motion_val(MpegEncContext * s){
                 s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0];
                 s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1];
             }
-            s->current_picture.f.ref_index[0][4*mb_xy    ] =
-            s->current_picture.f.ref_index[0][4*mb_xy + 1] = s->field_select[0][0];
-            s->current_picture.f.ref_index[0][4*mb_xy + 2] =
-            s->current_picture.f.ref_index[0][4*mb_xy + 3] = s->field_select[0][1];
+            s->current_picture.ref_index[0][4*mb_xy    ] =
+            s->current_picture.ref_index[0][4*mb_xy + 1] = s->field_select[0][0];
+            s->current_picture.ref_index[0][4*mb_xy + 2] =
+            s->current_picture.ref_index[0][4*mb_xy + 3] = s->field_select[0][1];
         }
 
         /* no update if 8X8 because it has been done during parsing */
-        s->current_picture.f.motion_val[0][xy][0]            = motion_x;
-        s->current_picture.f.motion_val[0][xy][1]            = motion_y;
-        s->current_picture.f.motion_val[0][xy + 1][0]        = motion_x;
-        s->current_picture.f.motion_val[0][xy + 1][1]        = motion_y;
-        s->current_picture.f.motion_val[0][xy + wrap][0]     = motion_x;
-        s->current_picture.f.motion_val[0][xy + wrap][1]     = motion_y;
-        s->current_picture.f.motion_val[0][xy + 1 + wrap][0] = motion_x;
-        s->current_picture.f.motion_val[0][xy + 1 + wrap][1] = motion_y;
+        s->current_picture.motion_val[0][xy][0]            = motion_x;
+        s->current_picture.motion_val[0][xy][1]            = motion_y;
+        s->current_picture.motion_val[0][xy + 1][0]        = motion_x;
+        s->current_picture.motion_val[0][xy + 1][1]        = motion_y;
+        s->current_picture.motion_val[0][xy + wrap][0]     = motion_x;
+        s->current_picture.motion_val[0][xy + wrap][1]     = motion_y;
+        s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x;
+        s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y;
     }
 
     if(s->encoding){ //FIXME encoding MUST be cleaned up
         if (s->mv_type == MV_TYPE_8X8)
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_8x8;
+            s->current_picture.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_8x8;
         else if(s->mb_intra)
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA;
+            s->current_picture.mb_type[mb_xy] = MB_TYPE_INTRA;
         else
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_16x16;
+            s->current_picture.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_16x16;
     }
 }
 
@@ -154,20 +150,20 @@ void ff_h263_loop_filter(MpegEncContext * s){
        Diag Top
        Left Center
     */
-    if (!IS_SKIP(s->current_picture.f.mb_type[xy])) {
+    if (!IS_SKIP(s->current_picture.mb_type[xy])) {
         qp_c= s->qscale;
-        s->dsp.h263_v_loop_filter(dest_y+8*linesize  , linesize, qp_c);
-        s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c);
+        s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize,     linesize, qp_c);
+        s->h263dsp.h263_v_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c);
     }else
         qp_c= 0;
 
     if(s->mb_y){
         int qp_dt, qp_tt, qp_tc;
 
-        if (IS_SKIP(s->current_picture.f.mb_type[xy - s->mb_stride]))
+        if (IS_SKIP(s->current_picture.mb_type[xy - s->mb_stride]))
             qp_tt=0;
         else
-            qp_tt = s->current_picture.f.qscale_table[xy - s->mb_stride];
+            qp_tt = s->current_picture.qscale_table[xy - s->mb_stride];
 
         if(qp_c)
             qp_tc= qp_c;
@@ -176,57 +172,57 @@ void ff_h263_loop_filter(MpegEncContext * s){
 
         if(qp_tc){
             const int chroma_qp= s->chroma_qscale_table[qp_tc];
-            s->dsp.h263_v_loop_filter(dest_y  ,   linesize, qp_tc);
-            s->dsp.h263_v_loop_filter(dest_y+8,   linesize, qp_tc);
+            s->h263dsp.h263_v_loop_filter(dest_y,     linesize, qp_tc);
+            s->h263dsp.h263_v_loop_filter(dest_y + 8, linesize, qp_tc);
 
-            s->dsp.h263_v_loop_filter(dest_cb , uvlinesize, chroma_qp);
-            s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp);
+            s->h263dsp.h263_v_loop_filter(dest_cb, uvlinesize, chroma_qp);
+            s->h263dsp.h263_v_loop_filter(dest_cr, uvlinesize, chroma_qp);
         }
 
         if(qp_tt)
-            s->dsp.h263_h_loop_filter(dest_y-8*linesize+8  ,   linesize, qp_tt);
+            s->h263dsp.h263_h_loop_filter(dest_y - 8 * linesize + 8, linesize, qp_tt);
 
         if(s->mb_x){
-            if (qp_tt || IS_SKIP(s->current_picture.f.mb_type[xy - 1 - s->mb_stride]))
+            if (qp_tt || IS_SKIP(s->current_picture.mb_type[xy - 1 - s->mb_stride]))
                 qp_dt= qp_tt;
             else
-                qp_dt = s->current_picture.f.qscale_table[xy - 1 - s->mb_stride];
+                qp_dt = s->current_picture.qscale_table[xy - 1 - s->mb_stride];
 
             if(qp_dt){
                 const int chroma_qp= s->chroma_qscale_table[qp_dt];
-                s->dsp.h263_h_loop_filter(dest_y -8*linesize  ,   linesize, qp_dt);
-                s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp);
-                s->dsp.h263_h_loop_filter(dest_cr-8*uvlinesize, uvlinesize, chroma_qp);
+                s->h263dsp.h263_h_loop_filter(dest_y  - 8 * linesize,   linesize,   qp_dt);
+                s->h263dsp.h263_h_loop_filter(dest_cb - 8 * uvlinesize, uvlinesize, chroma_qp);
+                s->h263dsp.h263_h_loop_filter(dest_cr - 8 * uvlinesize, uvlinesize, chroma_qp);
             }
         }
     }
 
     if(qp_c){
-        s->dsp.h263_h_loop_filter(dest_y +8,   linesize, qp_c);
+        s->h263dsp.h263_h_loop_filter(dest_y + 8, linesize, qp_c);
         if(s->mb_y + 1 == s->mb_height)
-            s->dsp.h263_h_loop_filter(dest_y+8*linesize+8,   linesize, qp_c);
+            s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize + 8, linesize, qp_c);
     }
 
     if(s->mb_x){
         int qp_lc;
-        if (qp_c || IS_SKIP(s->current_picture.f.mb_type[xy - 1]))
+        if (qp_c || IS_SKIP(s->current_picture.mb_type[xy - 1]))
             qp_lc= qp_c;
         else
-            qp_lc = s->current_picture.f.qscale_table[xy - 1];
+            qp_lc = s->current_picture.qscale_table[xy - 1];
 
         if(qp_lc){
-            s->dsp.h263_h_loop_filter(dest_y,   linesize, qp_lc);
+            s->h263dsp.h263_h_loop_filter(dest_y, linesize, qp_lc);
             if(s->mb_y + 1 == s->mb_height){
                 const int chroma_qp= s->chroma_qscale_table[qp_lc];
-                s->dsp.h263_h_loop_filter(dest_y +8*  linesize,   linesize, qp_lc);
-                s->dsp.h263_h_loop_filter(dest_cb             , uvlinesize, chroma_qp);
-                s->dsp.h263_h_loop_filter(dest_cr             , uvlinesize, chroma_qp);
+                s->h263dsp.h263_h_loop_filter(dest_y + 8 * linesize, linesize, qp_lc);
+                s->h263dsp.h263_h_loop_filter(dest_cb, uvlinesize, chroma_qp);
+                s->h263dsp.h263_h_loop_filter(dest_cr, uvlinesize, chroma_qp);
             }
         }
     }
 }
 
-void ff_h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n)
+void ff_h263_pred_acdc(MpegEncContext * s, int16_t *block, int n)
 {
     int x, y, wrap, a, c, pred_dc, scale, i;
     int16_t *dc_val, *ac_val, *ac_val1;
@@ -321,7 +317,7 @@ int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir,
     static const int off[4]= {2, 1, 1, -1};
 
     wrap = s->b8_stride;
-    mot_val = s->current_picture.f.motion_val[dir] + s->block_index[block];
+    mot_val = s->current_picture.motion_val[dir] + s->block_index[block];
 
     A = mot_val[ - 1];
     /* special case for first (slice) line */
diff --git a/libavcodec/h263.h b/libavcodec/h263.h
index beb32c4..c6ad618 100644
--- a/libavcodec/h263.h
+++ b/libavcodec/h263.h
@@ -26,6 +26,10 @@
 #include "mpegvideo.h"
 #include "rl.h"
 
+#if !FF_API_ASPECT_EXTENDED
+#define FF_ASPECT_EXTENDED 15
+#endif
+
 // 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
@@ -53,6 +57,10 @@ extern VLC ff_h263_intra_MCBPC_vlc;
 extern VLC ff_h263_inter_MCBPC_vlc;
 extern VLC ff_h263_cbpy_vlc;
 
+extern const uint16_t ff_inter_vlc[103][2];
+extern const int8_t ff_inter_level[102];
+extern const int8_t ff_inter_run[102];
+
 extern RLTable ff_h263_rl_inter;
 
 extern RLTable ff_rl_intra_aic;
@@ -64,6 +72,8 @@ extern uint8_t ff_mba_length[7];
 
 extern uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
 
+extern const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[];
+
 
 int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code);
 av_const int ff_h263_aspect_to_info(AVRational aspect);
@@ -73,14 +83,14 @@ int ff_h263_decode_frame(AVCodecContext *avctx,
                              AVPacket *avpkt);
 int ff_h263_decode_end(AVCodecContext *avctx);
 void ff_h263_encode_mb(MpegEncContext *s,
-                       DCTELEM block[6][64],
+                       int16_t block[6][64],
                        int motion_x, int motion_y);
 void ff_h263_encode_picture_header(MpegEncContext *s, int picture_number);
 void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line);
 int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir,
                              int *px, int *py);
 void ff_h263_encode_init(MpegEncContext *s);
-void ff_h263_decode_init_vlc(MpegEncContext *s);
+void ff_h263_decode_init_vlc(void);
 int ff_h263_decode_picture_header(MpegEncContext *s);
 int ff_h263_decode_gob_header(MpegEncContext *s);
 void ff_h263_update_motion_val(MpegEncContext * s);
@@ -89,7 +99,7 @@ int ff_h263_decode_mba(MpegEncContext *s);
 void ff_h263_encode_mba(MpegEncContext *s);
 void ff_init_qscale_tab(MpegEncContext *s);
 int ff_h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr);
-void ff_h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n);
+void ff_h263_pred_acdc(MpegEncContext * s, int16_t *block, int n);
 
 
 /**
@@ -99,7 +109,7 @@ void ff_h263_show_pict_info(MpegEncContext *s);
 
 int ff_intel_h263_decode_picture_header(MpegEncContext *s);
 int ff_h263_decode_mb(MpegEncContext *s,
-                      DCTELEM block[6][64]);
+                      int16_t block[6][64]);
 
 /**
  * Return the value of the 3bit "source format" syntax element.
@@ -144,7 +154,7 @@ static inline void ff_h263_encode_motion_vector(MpegEncContext * s, int x, int y
 }
 
 static inline int get_p_cbp(MpegEncContext * s,
-                      DCTELEM block[6][64],
+                      int16_t block[6][64],
                       int motion_x, int motion_y){
     int cbp, i;
 
diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h
index e3b83ad..c966aab 100644
--- a/libavcodec/h263data.h
+++ b/libavcodec/h263data.h
@@ -272,11 +272,6 @@ uint8_t ff_mba_length[7]={
       6,   7,   9,  11,  13,  14,  14
 };
 
-const uint8_t ff_h263_loop_filter_strength[32]={
-//  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
-    0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,11,12,12,12
-};
-
 const AVRational ff_h263_pixel_aspect[16]={
  {0, 1},
  {1, 1},
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index db58fd2..6c2f322 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -26,79 +26,75 @@
  */
 
 #include "libavutil/cpu.h"
-#include "internal.h"
 #include "avcodec.h"
-#include "dsputil.h"
-#include "mpegvideo.h"
+#include "error_resilience.h"
+#include "flv.h"
 #include "h263.h"
 #include "h263_parser.h"
+#include "internal.h"
+#include "mpeg4video.h"
 #include "mpeg4video_parser.h"
+#include "mpegvideo.h"
 #include "msmpeg4.h"
-#include "vdpau_internal.h"
 #include "thread.h"
-#include "flv.h"
-#include "mpeg4video.h"
-
-//#define DEBUG
-//#define PRINT_FRAME_TIME
 
 av_cold int ff_h263_decode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
+    int ret;
 
-    s->avctx = avctx;
-    s->out_format = FMT_H263;
-
-    s->width  = avctx->coded_width;
-    s->height = avctx->coded_height;
-    s->workaround_bugs= avctx->workaround_bugs;
+    s->avctx           = avctx;
+    s->out_format      = FMT_H263;
+    s->width           = avctx->coded_width;
+    s->height          = avctx->coded_height;
+    s->workaround_bugs = avctx->workaround_bugs;
 
     // set defaults
     ff_MPV_decode_defaults(s);
-    s->quant_precision=5;
-    s->decode_mb= ff_h263_decode_mb;
-    s->low_delay= 1;
+    s->quant_precision = 5;
+    s->decode_mb       = ff_h263_decode_mb;
+    s->low_delay       = 1;
     if (avctx->codec->id == AV_CODEC_ID_MSS2)
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     else
         avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
-    s->unrestricted_mv= 1;
+    s->unrestricted_mv = 1;
 
     /* select sub codec */
-    switch(avctx->codec->id) {
+    switch (avctx->codec->id) {
     case AV_CODEC_ID_H263:
-        s->unrestricted_mv= 0;
+        s->unrestricted_mv = 0;
         avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
         break;
     case AV_CODEC_ID_MPEG4:
         break;
     case AV_CODEC_ID_MSMPEG4V1:
-        s->h263_pred = 1;
-        s->msmpeg4_version=1;
+        s->h263_pred       = 1;
+        s->msmpeg4_version = 1;
         break;
     case AV_CODEC_ID_MSMPEG4V2:
-        s->h263_pred = 1;
-        s->msmpeg4_version=2;
+        s->h263_pred       = 1;
+        s->msmpeg4_version = 2;
         break;
     case AV_CODEC_ID_MSMPEG4V3:
-        s->h263_pred = 1;
-        s->msmpeg4_version=3;
+        s->h263_pred       = 1;
+        s->msmpeg4_version = 3;
         break;
     case AV_CODEC_ID_WMV1:
-        s->h263_pred = 1;
-        s->msmpeg4_version=4;
+        s->h263_pred       = 1;
+        s->msmpeg4_version = 4;
         break;
     case AV_CODEC_ID_WMV2:
-        s->h263_pred = 1;
-        s->msmpeg4_version=5;
+        s->h263_pred       = 1;
+        s->msmpeg4_version = 5;
         break;
     case AV_CODEC_ID_VC1:
     case AV_CODEC_ID_WMV3:
     case AV_CODEC_ID_VC1IMAGE:
     case AV_CODEC_ID_WMV3IMAGE:
     case AV_CODEC_ID_MSS2:
-        s->h263_pred = 1;
-        s->msmpeg4_version=6;
+        s->h263_pred       = 1;
+        s->msmpeg4_version = 6;
         avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
         break;
     case AV_CODEC_ID_H263I:
@@ -107,17 +103,21 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
         s->h263_flv = 1;
         break;
     default:
-        return -1;
+        av_log(avctx, AV_LOG_ERROR, "Unsupported codec %d\n",
+               avctx->codec->id);
+        return AVERROR(ENOSYS);
     }
-    s->codec_id= avctx->codec->id;
-    avctx->hwaccel= ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
+    s->codec_id    = avctx->codec->id;
+    avctx->hwaccel = ff_find_hwaccel(avctx);
 
     /* 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_MPEG4)
+        if ((ret = ff_MPV_common_init(s)) < 0)
+            return ret;
 
-        ff_h263_decode_init_vlc(s);
+    ff_h263dsp_init(&s->h263dsp);
+    ff_h263_decode_init_vlc();
 
     return 0;
 }
@@ -133,234 +133,250 @@ av_cold int ff_h263_decode_end(AVCodecContext *avctx)
 /**
  * Return the number of bytes consumed for building the current frame.
  */
-static int get_consumed_bytes(MpegEncContext *s, int buf_size){
-    int pos= (get_bits_count(&s->gb)+7)>>3;
+static int get_consumed_bytes(MpegEncContext *s, int buf_size)
+{
+    int pos = (get_bits_count(&s->gb) + 7) >> 3;
 
-    if(s->divx_packed || s->avctx->hwaccel){
-        //we would have to scan through the whole buf to handle the weird reordering ...
+    if (s->divx_packed || s->avctx->hwaccel) {
+        /* We would have to scan through the whole buf to handle the weird
+         * reordering ... */
         return buf_size;
-    }else if(s->flags&CODEC_FLAG_TRUNCATED){
+    } else if (s->flags & CODEC_FLAG_TRUNCATED) {
         pos -= s->parse_context.last_index;
-        if(pos<0) pos=0; // padding is not really read so this might be -1
+        // padding is not really read so this might be -1
+        if (pos < 0)
+            pos = 0;
         return pos;
-    }else{
-        if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...)
-        if(pos+10>buf_size) pos=buf_size; // oops ;)
+    } else {
+        // avoid infinite loops (maybe not needed...)
+        if (pos == 0)
+            pos = 1;
+        // oops ;)
+        if (pos + 10 > buf_size)
+            pos = buf_size;
 
         return pos;
     }
 }
 
-static int decode_slice(MpegEncContext *s){
-    const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;
+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;
-    s->last_resync_gb= s->gb;
-    s->first_slice_line= 1;
+    int ret;
 
-    s->resync_mb_x= s->mb_x;
-    s->resync_mb_y= s->mb_y;
+    s->last_resync_gb   = s->gb;
+    s->first_slice_line = 1;
+    s->resync_mb_x      = s->mb_x;
+    s->resync_mb_y      = s->mb_y;
 
     ff_set_qscale(s, s->qscale);
 
     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);
-        skip_bits_long(&s->gb, 8*(end - start));
+        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);
+        skip_bits_long(&s->gb, 8 * (end - start));
         return s->avctx->hwaccel->decode_slice(s->avctx, start, end - start);
     }
 
-    if(s->partitioned_frame){
-        const int qscale= s->qscale;
+    if (s->partitioned_frame) {
+        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 (CONFIG_MPEG4_DECODER && s->codec_id == AV_CODEC_ID_MPEG4)
+            if ((ret = ff_mpeg4_decode_partitions(s->avctx->priv_data)) < 0)
+                return ret;
 
         /* restore variables which were modified */
-        s->first_slice_line=1;
-        s->mb_x= s->resync_mb_x;
-        s->mb_y= s->resync_mb_y;
+        s->first_slice_line = 1;
+        s->mb_x             = s->resync_mb_x;
+        s->mb_y             = s->resync_mb_y;
         ff_set_qscale(s, qscale);
     }
 
-    for(; s->mb_y < s->mb_height; s->mb_y++) {
+    for (; s->mb_y < s->mb_height; s->mb_y++) {
         /* per-row end of slice checks */
-        if(s->msmpeg4_version){
-            if(s->resync_mb_y + s->slice_height == s->mb_y){
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+        if (s->msmpeg4_version) {
+            if (s->resync_mb_y + s->slice_height == s->mb_y) {
+                ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                                s->mb_x - 1, s->mb_y, ER_MB_END);
 
                 return 0;
             }
         }
 
-        if(s->msmpeg4_version==1){
-            s->last_dc[0]=
-            s->last_dc[1]=
-            s->last_dc[2]= 128;
+        if (s->msmpeg4_version == 1) {
+            s->last_dc[0] =
+            s->last_dc[1] =
+            s->last_dc[2] = 128;
         }
 
         ff_init_block_index(s);
-        for(; s->mb_x < s->mb_width; s->mb_x++) {
+        for (; s->mb_x < s->mb_width; s->mb_x++) {
             int ret;
 
             ff_update_block_index(s);
 
-            if(s->resync_mb_x == s->mb_x && s->resync_mb_y+1 == s->mb_y){
-                s->first_slice_line=0;
-            }
+            if (s->resync_mb_x == s->mb_x && s->resync_mb_y + 1 == s->mb_y)
+                s->first_slice_line = 0;
 
             /* DCT & quantize */
 
-            s->mv_dir = MV_DIR_FORWARD;
+            s->mv_dir  = MV_DIR_FORWARD;
             s->mv_type = MV_TYPE_16X16;
-//            s->mb_skipped = 0;
             av_dlog(s, "%d %d %06X\n",
                     ret, get_bits_count(&s->gb), show_bits(&s->gb, 24));
-            ret= s->decode_mb(s, s->block);
+            ret = s->decode_mb(s, s->block);
 
-            if (s->pict_type!=AV_PICTURE_TYPE_B)
+            if (s->pict_type != AV_PICTURE_TYPE_B)
                 ff_h263_update_motion_val(s);
 
-            if(ret<0){
-                const int xy= s->mb_x + s->mb_y*s->mb_stride;
-                if(ret==SLICE_END){
+            if (ret < 0) {
+                const int xy = s->mb_x + s->mb_y * s->mb_stride;
+                if (ret == SLICE_END) {
                     ff_MPV_decode_mb(s, s->block);
-                    if(s->loop_filter)
+                    if (s->loop_filter)
                         ff_h263_loop_filter(s);
 
-                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
+                    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                                    s->mb_x, s->mb_y, ER_MB_END & part_mask);
 
                     s->padding_bug_score--;
 
-                    if(++s->mb_x >= s->mb_width){
-                        s->mb_x=0;
-                        ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
+                    if (++s->mb_x >= s->mb_width) {
+                        s->mb_x = 0;
+                        ff_mpeg_draw_horiz_band(s, s->mb_y * mb_size, mb_size);
                         ff_MPV_report_decode_progress(s);
                         s->mb_y++;
                     }
                     return 0;
-                }else if(ret==SLICE_NOEND){
-                    av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy);
-                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, ER_MB_END&part_mask);
-                    return -1;
+                } else if (ret == SLICE_NOEND) {
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "Slice mismatch at MB: %d\n", xy);
+                    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                                    s->mb_x + 1, s->mb_y,
+                                    ER_MB_END & part_mask);
+                    return AVERROR_INVALIDDATA;
                 }
                 av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy);
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
+                ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                                s->mb_x, s->mb_y, ER_MB_ERROR & part_mask);
 
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
             ff_MPV_decode_mb(s, s->block);
-            if(s->loop_filter)
+            if (s->loop_filter)
                 ff_h263_loop_filter(s);
         }
 
-        ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
+        ff_mpeg_draw_horiz_band(s, s->mb_y * mb_size, mb_size);
         ff_MPV_report_decode_progress(s);
 
-        s->mb_x= 0;
+        s->mb_x = 0;
     }
 
-    assert(s->mb_x==0 && s->mb_y==s->mb_height);
+    assert(s->mb_x == 0 && s->mb_y == s->mb_height);
 
-    if(s->codec_id==AV_CODEC_ID_MPEG4
-       && (s->workaround_bugs&FF_BUG_AUTODETECT)
-       && get_bits_left(&s->gb) >= 48
-       && show_bits(&s->gb, 24)==0x4010
-       && !s->data_partitioning)
-        s->padding_bug_score+=32;
+    if (s->codec_id == AV_CODEC_ID_MPEG4         &&
+        (s->workaround_bugs & FF_BUG_AUTODETECT) &&
+        get_bits_left(&s->gb) >= 48              &&
+        show_bits(&s->gb, 24) == 0x4010          &&
+        !s->data_partitioning)
+        s->padding_bug_score += 32;
 
     /* try to detect the padding bug */
-    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
-//       &&   !s->resync_marker
-       &&   !s->data_partitioning){
-
-        const int bits_count= get_bits_count(&s->gb);
-        const int bits_left = s->gb.size_in_bits - bits_count;
-
-        if(bits_left==0){
-            s->padding_bug_score+=16;
-        } else if(bits_left != 1){
-            int v= show_bits(&s->gb, 8);
-            v|= 0x7F >> (7-(bits_count&7));
-
-            if(v==0x7F && bits_left<=8)
+    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               &&
+        !s->data_partitioning) {
+        const int bits_count = get_bits_count(&s->gb);
+        const int bits_left  = s->gb.size_in_bits - bits_count;
+
+        if (bits_left == 0) {
+            s->padding_bug_score += 16;
+        } else if (bits_left != 1) {
+            int v = show_bits(&s->gb, 8);
+            v |= 0x7F >> (7 - (bits_count & 7));
+
+            if (v == 0x7F && bits_left <= 8)
                 s->padding_bug_score--;
-            else if(v==0x7F && ((get_bits_count(&s->gb)+8)&8) && bits_left<=16)
-                s->padding_bug_score+= 4;
+            else if (v == 0x7F && ((get_bits_count(&s->gb) + 8) & 8) &&
+                     bits_left <= 16)
+                s->padding_bug_score += 4;
             else
                 s->padding_bug_score++;
         }
     }
 
-    if(s->workaround_bugs&FF_BUG_AUTODETECT){
-        if(s->padding_bug_score > -2 && !s->data_partitioning /*&& (s->divx_version>=0 || !s->resync_marker)*/)
-            s->workaround_bugs |=  FF_BUG_NO_PADDING;
+    if (s->workaround_bugs & FF_BUG_AUTODETECT) {
+        if (s->padding_bug_score > -2 && !s->data_partitioning)
+            s->workaround_bugs |= FF_BUG_NO_PADDING;
         else
             s->workaround_bugs &= ~FF_BUG_NO_PADDING;
     }
 
     // handle formats which don't have unique end markers
-    if(s->msmpeg4_version || (s->workaround_bugs&FF_BUG_NO_PADDING)){ //FIXME perhaps solve this more cleanly
-        int left= get_bits_left(&s->gb);
-        int max_extra=7;
+    if (s->msmpeg4_version || (s->workaround_bugs & FF_BUG_NO_PADDING)) { // FIXME perhaps solve this more cleanly
+        int left      = get_bits_left(&s->gb);
+        int max_extra = 7;
 
         /* no markers in M$ crap */
-        if(s->msmpeg4_version && s->pict_type==AV_PICTURE_TYPE_I)
-            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))
-            max_extra+= 48;
-        else if((s->workaround_bugs&FF_BUG_NO_PADDING))
-            max_extra+= 256*256*256*64;
-
-        if(left>max_extra){
-            av_log(s->avctx, AV_LOG_ERROR, "discarding %d junk bits at end, next would be %X\n", left, show_bits(&s->gb, 24));
-        }
-        else if(left<0){
+        if (s->msmpeg4_version && s->pict_type == AV_PICTURE_TYPE_I)
+            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))
+            max_extra += 48;
+        else if ((s->workaround_bugs & FF_BUG_NO_PADDING))
+            max_extra += 256 * 256 * 256 * 64;
+
+        if (left > max_extra)
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "discarding %d junk bits at end, next would be %X\n",
+                   left, show_bits(&s->gb, 24));
+        else if (left < 0)
             av_log(s->avctx, AV_LOG_ERROR, "overreading %d bits\n", -left);
-        }else
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+        else
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                            s->mb_x - 1, s->mb_y, ER_MB_END);
 
         return 0;
     }
 
-    av_log(s->avctx, AV_LOG_ERROR, "slice end not reached but screenspace end (%d left %06X, score= %d)\n",
-            get_bits_left(&s->gb),
-            show_bits(&s->gb, 24), s->padding_bug_score);
+    av_log(s->avctx, AV_LOG_ERROR,
+           "slice end not reached but screenspace end (%d left %06X, score= %d)\n",
+           get_bits_left(&s->gb), show_bits(&s->gb, 24), s->padding_bug_score);
 
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
+    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y,
+                    ER_MB_END & part_mask);
 
-    return -1;
+    return AVERROR_INVALIDDATA;
 }
 
-int ff_h263_decode_frame(AVCodecContext *avctx,
-                             void *data, int *got_frame,
-                             AVPacket *avpkt)
+int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    MpegEncContext *s = avctx->priv_data;
+    int buf_size       = avpkt->size;
+    MpegEncContext *s  = avctx->priv_data;
     int ret;
     AVFrame *pict = data;
 
-#ifdef PRINT_FRAME_TIME
-uint64_t time= rdtsc();
-#endif
-    s->flags= avctx->flags;
-    s->flags2= avctx->flags2;
+    s->flags  = avctx->flags;
+    s->flags2 = avctx->flags2;
 
     /* no supplementary picture */
     if (buf_size == 0) {
         /* special case for last picture */
-        if (s->low_delay==0 && s->next_picture_ptr) {
-            *pict = s->next_picture_ptr->f;
-            s->next_picture_ptr= NULL;
+        if (s->low_delay == 0 && s->next_picture_ptr) {
+            if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
+                return ret;
+            s->next_picture_ptr = NULL;
 
             *got_frame = 1;
         }
@@ -368,56 +384,64 @@ uint64_t time= rdtsc();
         return 0;
     }
 
-    if(s->flags&CODEC_FLAG_TRUNCATED){
+    if (s->flags & CODEC_FLAG_TRUNCATED) {
         int next;
 
-        if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){
-            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{
-            av_log(s->avctx, AV_LOG_ERROR, "this codec does not support truncated bitstreams\n");
-            return -1;
+        if (CONFIG_MPEG4_DECODER && s->codec_id == AV_CODEC_ID_MPEG4) {
+            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 {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "this codec does not support truncated bitstreams\n");
+            return AVERROR(ENOSYS);
         }
 
-        if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )
+        if (ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf,
+                             &buf_size) < 0)
             return buf_size;
     }
 
+    if (s->bitstream_buffer_size && (s->divx_packed || buf_size < 20)) // divx 5.01+/xvid frame reorder
+        ret = init_get_bits8(&s->gb, s->bitstream_buffer,
+                             s->bitstream_buffer_size);
+    else
+        ret = init_get_bits8(&s->gb, buf, buf_size);
+    s->bitstream_buffer_size = 0;
 
-    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);
-    }else
-        init_get_bits(&s->gb, buf, buf_size*8);
-    s->bitstream_buffer_size=0;
+    if (ret < 0)
+        return ret;
 
-    if (!s->context_initialized) {
-        if (ff_MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix
-            return -1;
-    }
+    if (!s->context_initialized)
+        // we need the idct permutaton for reading a custom matrix
+        if ((ret = ff_MPV_common_init(s)) < 0)
+            return ret;
 
     /* We need to set current_picture_ptr before reading the header,
      * otherwise we cannot store anyting in there */
     if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
-        int i= ff_find_unused_picture(s, 0);
+        int i = ff_find_unused_picture(s, 0);
         if (i < 0)
             return i;
-        s->current_picture_ptr= &s->picture[i];
+        s->current_picture_ptr = &s->picture[i];
     }
 
     /* let's go :-) */
-    if (CONFIG_WMV2_DECODER && s->msmpeg4_version==5) {
-        ret= ff_wmv2_decode_picture_header(s);
+    if (CONFIG_WMV2_DECODER && s->msmpeg4_version == 5) {
+        ret = ff_wmv2_decode_picture_header(s);
     } else if (CONFIG_MSMPEG4_DECODER && s->msmpeg4_version) {
         ret = ff_msmpeg4_decode_picture_header(s);
-    } else if (CONFIG_MPEG4_DECODER && s->h263_pred) {
-        if(s->avctx->extradata_size && s->picture_number==0){
+    } else if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) {
+        if (s->avctx->extradata_size && s->picture_number == 0) {
             GetBitContext gb;
 
-            init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8);
-            ret = ff_mpeg4_decode_picture_header(s, &gb);
+            ret = init_get_bits8(&gb, s->avctx->extradata,
+                                 s->avctx->extradata_size);
+            if (ret < 0)
+                return ret;
+            ff_mpeg4_decode_picture_header(avctx->priv_data, &gb);
         }
-        ret = ff_mpeg4_decode_picture_header(s, &s->gb);
+        ret = ff_mpeg4_decode_picture_header(avctx->priv_data, &s->gb);
     } else if (CONFIG_H263I_DECODER && s->codec_id == AV_CODEC_ID_H263I) {
         ret = ff_intel_h263_decode_picture_header(s);
     } else if (CONFIG_FLV_DECODER && s->h263_flv) {
@@ -426,160 +450,59 @@ uint64_t time= rdtsc();
         ret = ff_h263_decode_picture_header(s);
     }
 
-    if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size);
+    if (ret == FRAME_SKIPPED)
+        return get_consumed_bytes(s, buf_size);
 
     /* skip if the header was thrashed */
-    if (ret < 0){
+    if (ret < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
-        return -1;
-    }
-
-    avctx->has_b_frames= !s->low_delay;
-
-    if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){
-        if(s->stream_codec_tag == AV_RL32("XVID") ||
-           s->codec_tag == AV_RL32("XVID") || s->codec_tag == AV_RL32("XVIX") ||
-           s->codec_tag == AV_RL32("RMP4") ||
-           s->codec_tag == AV_RL32("SIPP")
-           )
-            s->xvid_build= 0;
-#if 0
-        if(s->codec_tag == AV_RL32("DIVX") && s->vo_type==0 && s->vol_control_parameters==1
-           && s->padding_bug_score > 0 && s->low_delay) // XVID with modified fourcc
-            s->xvid_build= 0;
-#endif
-    }
-
-    if(s->xvid_build==-1 && s->divx_version==-1 && s->lavc_build==-1){
-        if(s->codec_tag == AV_RL32("DIVX") && s->vo_type==0 && s->vol_control_parameters==0)
-            s->divx_version= 400; //divx 4
-    }
-
-    if(s->xvid_build>=0 && s->divx_version>=0){
-        s->divx_version=
-        s->divx_build= -1;
+        return ret;
     }
 
-    if(s->workaround_bugs&FF_BUG_AUTODETECT){
-        if(s->codec_tag == AV_RL32("XVIX"))
-            s->workaround_bugs|= FF_BUG_XVID_ILACE;
-
-        if(s->codec_tag == AV_RL32("UMP4")){
-            s->workaround_bugs|= FF_BUG_UMP4;
-        }
-
-        if(s->divx_version>=500 && s->divx_build<1814){
-            s->workaround_bugs|= FF_BUG_QPEL_CHROMA;
-        }
-
-        if(s->divx_version>502 && s->divx_build<1814){
-            s->workaround_bugs|= FF_BUG_QPEL_CHROMA2;
-        }
-
-        if(s->xvid_build<=3U)
-            s->padding_bug_score= 256*256*256*64;
-
-        if(s->xvid_build<=1U)
-            s->workaround_bugs|= FF_BUG_QPEL_CHROMA;
-
-        if(s->xvid_build<=12U)
-            s->workaround_bugs|= FF_BUG_EDGE;
-
-        if(s->xvid_build<=32U)
-            s->workaround_bugs|= FF_BUG_DC_CLIP;
+    avctx->has_b_frames = !s->low_delay;
 
-#define SET_QPEL_FUNC(postfix1, postfix2) \
-    s->dsp.put_ ## postfix1 = ff_put_ ## postfix2;\
-    s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;\
-    s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2;
+#define SET_QPEL_FUNC(postfix1, postfix2)                           \
+    s->dsp.put_        ## postfix1 = ff_put_        ## postfix2;    \
+    s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;    \
+    s->dsp.avg_        ## postfix1 = ff_avg_        ## postfix2;
 
-        if(s->lavc_build<4653U)
-            s->workaround_bugs|= FF_BUG_STD_QPEL;
-
-        if(s->lavc_build<4655U)
-            s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;
-
-        if(s->lavc_build<4670U){
-            s->workaround_bugs|= FF_BUG_EDGE;
-        }
-
-        if(s->lavc_build<=4712U)
-            s->workaround_bugs|= FF_BUG_DC_CLIP;
-
-        if(s->divx_version>=0)
-            s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;
-        if(s->divx_version==501 && s->divx_build==20020416)
-            s->padding_bug_score= 256*256*256*64;
-
-        if(s->divx_version<500U){
-            s->workaround_bugs|= FF_BUG_EDGE;
-        }
-
-        if(s->divx_version>=0)
-            s->workaround_bugs|= FF_BUG_HPEL_CHROMA;
-#if 0
-        if(s->divx_version==500)
-            s->padding_bug_score= 256*256*256*64;
-
-        /* very ugly XVID padding bug detection FIXME/XXX solve this differently
-         * Let us hope this at least works.
-         */
-        if(   s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==-1
-           && s->codec_id==AV_CODEC_ID_MPEG4 && s->vo_type==0)
-            s->workaround_bugs|= FF_BUG_NO_PADDING;
-
-        if(s->lavc_build<4609U) //FIXME not sure about the version num but a 4609 file seems ok
-            s->workaround_bugs|= FF_BUG_NO_PADDING;
-#endif
-    }
-
-    if(s->workaround_bugs& FF_BUG_STD_QPEL){
-        SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_old_c)
-        SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_old_c)
-        SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_old_c)
+    if (s->workaround_bugs & FF_BUG_STD_QPEL) {
+        SET_QPEL_FUNC(qpel_pixels_tab[0][5], qpel16_mc11_old_c)
+        SET_QPEL_FUNC(qpel_pixels_tab[0][7], qpel16_mc31_old_c)
+        SET_QPEL_FUNC(qpel_pixels_tab[0][9], qpel16_mc12_old_c)
         SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c)
         SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c)
         SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c)
 
-        SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_old_c)
-        SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_old_c)
-        SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_old_c)
+        SET_QPEL_FUNC(qpel_pixels_tab[1][5], qpel8_mc11_old_c)
+        SET_QPEL_FUNC(qpel_pixels_tab[1][7], qpel8_mc31_old_c)
+        SET_QPEL_FUNC(qpel_pixels_tab[1][9], qpel8_mc12_old_c)
         SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c)
         SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c)
         SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c)
     }
 
-    if(avctx->debug & FF_DEBUG_BUGS)
-        av_log(s->avctx, AV_LOG_DEBUG, "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
-               s->workaround_bugs, s->lavc_build, s->xvid_build, s->divx_version, s->divx_build,
-               s->divx_packed ? "p" : "");
-
-#if HAVE_MMX
-    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;
-    }
-#endif
-
-        /* After H263 & mpeg4 header decode we have the height, width,*/
-        /* and other parameters. So then we could init the picture   */
-        /* FIXME: By the way H263 decoder is evolving it should have */
-        /* an H263EncContext                                         */
-
+    /* After H263 & mpeg4 header decode we have the height, width,
+     * and other parameters. So then we could init the picture.
+     * FIXME: By the way H263 decoder is evolving it should have
+     * an H263EncContext */
     if (s->width  != avctx->coded_width  ||
         s->height != avctx->coded_height ||
         s->context_reinit) {
         /* H.263 could change picture size any time */
         s->context_reinit = 0;
 
-        avcodec_set_dimensions(avctx, s->width, s->height);
+        ret = ff_set_dimensions(avctx, s->width, s->height);
+        if (ret < 0)
+            return ret;
 
         if ((ret = ff_MPV_common_frame_size_change(s)))
             return ret;
     }
 
-    if((s->codec_id==AV_CODEC_ID_H263 || s->codec_id==AV_CODEC_ID_H263P || s->codec_id == AV_CODEC_ID_H263I))
+    if (s->codec_id == AV_CODEC_ID_H263  ||
+        s->codec_id == AV_CODEC_ID_H263P ||
+        s->codec_id == AV_CODEC_ID_H263I)
         s->gob_index = ff_h263_get_gob_height(s);
 
     // for skipping the frame
@@ -590,147 +513,140 @@ uint64_t time= rdtsc();
     if (s->last_picture_ptr == NULL &&
         (s->pict_type == AV_PICTURE_TYPE_B || s->droppable))
         return get_consumed_bytes(s, buf_size);
-    if(   (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B)
-       || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I)
-       ||  avctx->skip_frame >= AVDISCARD_ALL)
+    if ((avctx->skip_frame >= AVDISCARD_NONREF &&
+         s->pict_type == AV_PICTURE_TYPE_B)    ||
+        (avctx->skip_frame >= AVDISCARD_NONKEY &&
+         s->pict_type != AV_PICTURE_TYPE_I)    ||
+        avctx->skip_frame >= AVDISCARD_ALL)
         return get_consumed_bytes(s, buf_size);
 
-    if(s->next_p_frame_damaged){
-        if(s->pict_type==AV_PICTURE_TYPE_B)
+    if (s->next_p_frame_damaged) {
+        if (s->pict_type == AV_PICTURE_TYPE_B)
             return get_consumed_bytes(s, buf_size);
         else
-            s->next_p_frame_damaged=0;
+            s->next_p_frame_damaged = 0;
     }
 
-    if((s->avctx->flags2 & CODEC_FLAG2_FAST) && s->pict_type==AV_PICTURE_TYPE_B){
-        s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab;
-        s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab;
-    }else if((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
-        s->me.qpel_put= s->dsp.put_qpel_pixels_tab;
-        s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
-    }else{
-        s->me.qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab;
-        s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
+    if ((!s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) {
+        s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
+        s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
+    } else {
+        s->me.qpel_put = s->dsp.put_no_rnd_qpel_pixels_tab;
+        s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
     }
 
-    if(ff_MPV_frame_start(s, avctx) < 0)
-        return -1;
-
-    if (!s->divx_packed) ff_thread_finish_setup(avctx);
+    if ((ret = ff_MPV_frame_start(s, avctx)) < 0)
+        return ret;
 
-    if (CONFIG_MPEG4_VDPAU_DECODER && (s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)) {
-        ff_vdpau_mpeg4_decode_picture(s, s->gb.buffer, s->gb.buffer_end - s->gb.buffer);
-        goto frame_end;
-    }
+    if (!s->divx_packed && !avctx->hwaccel)
+        ff_thread_finish_setup(avctx);
 
     if (avctx->hwaccel) {
-        if (avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer) < 0)
-            return -1;
+        ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer,
+                                          s->gb.buffer_end - s->gb.buffer);
+        if (ret < 0 )
+            return ret;
     }
 
-    ff_er_frame_start(s);
+    ff_mpeg_er_frame_start(s);
 
-    //the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type
-    //which is not available before ff_MPV_frame_start()
-    if (CONFIG_WMV2_DECODER && s->msmpeg4_version==5){
+    /* the second part of the wmv2 header contains the MB skip bits which
+     * are stored in current_picture->mb_type which is not available before
+     * ff_MPV_frame_start() */
+    if (CONFIG_WMV2_DECODER && s->msmpeg4_version == 5) {
         ret = ff_wmv2_decode_secondary_picture_header(s);
-        if(ret<0) return ret;
-        if(ret==1) goto intrax8_decoded;
+        if (ret < 0)
+            return ret;
+        if (ret == 1)
+            goto intrax8_decoded;
     }
 
     /* decode each macroblock */
-    s->mb_x=0;
-    s->mb_y=0;
+    s->mb_x = 0;
+    s->mb_y = 0;
 
     ret = decode_slice(s);
-    while(s->mb_y<s->mb_height){
-        if(s->msmpeg4_version){
-            if(s->slice_height==0 || s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_left(&s->gb)<0)
+    while (s->mb_y < s->mb_height) {
+        if (s->msmpeg4_version) {
+            if (s->slice_height == 0 || s->mb_x != 0 ||
+                (s->mb_y % s->slice_height) != 0 || get_bits_left(&s->gb) < 0)
                 break;
-        }else{
-            int prev_x=s->mb_x, prev_y=s->mb_y;
-            if(ff_h263_resync(s)<0)
+        } else {
+            int prev_x = s->mb_x, prev_y = s->mb_y;
+            if (ff_h263_resync(s) < 0)
                 break;
             if (prev_y * s->mb_width + prev_x < s->mb_y * s->mb_width + s->mb_x)
-                s->error_occurred = 1;
+                s->er.error_occurred = 1;
         }
 
-        if(s->msmpeg4_version<4 && s->h263_pred)
+        if (s->msmpeg4_version < 4 && s->h263_pred)
             ff_mpeg4_clean_buffers(s);
 
-        if (decode_slice(s) < 0) ret = AVERROR_INVALIDDATA;
+        if (decode_slice(s) < 0)
+            ret = AVERROR_INVALIDDATA;
     }
 
-    if (s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type==AV_PICTURE_TYPE_I)
-        if(!CONFIG_MSMPEG4_DECODER || ff_msmpeg4_decode_ext_header(s, buf_size) < 0){
-            s->error_status_table[s->mb_num-1]= ER_MB_ERROR;
-        }
+    if (s->msmpeg4_version && s->msmpeg4_version < 4 &&
+        s->pict_type == AV_PICTURE_TYPE_I)
+        if (!CONFIG_MSMPEG4_DECODER ||
+            ff_msmpeg4_decode_ext_header(s, buf_size) < 0)
+            s->er.error_status_table[s->mb_num - 1] = ER_MB_ERROR;
 
-    assert(s->bitstream_buffer_size==0);
-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 startcode_found=0;
-
-        if(buf_size - current_pos > 5){
-            int i;
-            for(i=current_pos; i<buf_size-3; i++){
-                if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
-                    startcode_found=1;
-                    break;
-                }
-            }
-        }
-        if(s->gb.buffer == s->bitstream_buffer && buf_size>7 && s->xvid_build>=0){ //xvid style
-            startcode_found=1;
-            current_pos=0;
-        }
+    assert(s->bitstream_buffer_size == 0);
 
-        if(startcode_found){
-            av_fast_malloc(
-                &s->bitstream_buffer,
-                &s->allocated_bitstream_buffer_size,
-                buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!s->bitstream_buffer)
-                return AVERROR(ENOMEM);
-            memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos);
-            s->bitstream_buffer_size= buf_size - current_pos;
-        }
-    }
+    if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4)
+        ff_mpeg4_frame_end(avctx, buf, buf_size);
 
 intrax8_decoded:
-    ff_er_frame_end(s);
+    ff_er_frame_end(&s->er);
 
     if (avctx->hwaccel) {
-        if (avctx->hwaccel->end_frame(avctx) < 0)
-            return -1;
+        ret = avctx->hwaccel->end_frame(avctx);
+        if (ret < 0)
+            return ret;
     }
 
     ff_MPV_frame_end(s);
 
-    assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
+    if (!s->divx_packed && avctx->hwaccel)
+        ff_thread_finish_setup(avctx);
+
+    assert(s->current_picture.f.pict_type ==
+           s->current_picture_ptr->f.pict_type);
     assert(s->current_picture.f.pict_type == s->pict_type);
     if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-        *pict = s->current_picture_ptr->f;
+        if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+            return ret;
+        ff_print_debug_info(s, s->current_picture_ptr);
     } else if (s->last_picture_ptr != NULL) {
-        *pict = s->last_picture_ptr->f;
+        if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+            return ret;
+        ff_print_debug_info(s, s->last_picture_ptr);
     }
 
-    if(s->last_picture_ptr || s->low_delay){
+    if (s->last_picture_ptr || s->low_delay)
         *got_frame = 1;
-        ff_print_debug_info(s, pict);
-    }
-
-#ifdef PRINT_FRAME_TIME
-av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time);
-#endif
 
-    return (ret && (avctx->err_recognition & AV_EF_EXPLODE))?ret:get_consumed_bytes(s, buf_size);
+    if (ret && (avctx->err_recognition & AV_EF_EXPLODE))
+        return ret;
+    else
+        return get_consumed_bytes(s, buf_size);
 }
 
+const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_VAAPI
+    AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_VDPAU
+    AV_PIX_FMT_VDPAU,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
 AVCodec ff_h263_decoder = {
     .name           = "h263",
+    .long_name      = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H263,
     .priv_data_size = sizeof(MpegEncContext),
@@ -740,6 +656,5 @@ AVCodec ff_h263_decoder = {
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 |
                       CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
     .flush          = ff_mpeg_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
-    .pix_fmts       = ff_hwaccel_pixfmt_list_420,
+    .pix_fmts       = ff_h263_hwaccel_pixfmt_list_420,
 };
diff --git a/libavcodec/h263dsp.c b/libavcodec/h263dsp.c
new file mode 100644
index 0000000..70ecdb9
--- /dev/null
+++ b/libavcodec/h263dsp.c
@@ -0,0 +1,124 @@
+/*
+ * 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 "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "config.h"
+#include "h263dsp.h"
+
+const uint8_t ff_h263_loop_filter_strength[32] = {
+    0, 1, 1, 2, 2, 3, 3,  4,  4,  4,  5,  5,  6,  6,  7, 7,
+    7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12
+};
+
+static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale)
+{
+    int y;
+    const int strength = ff_h263_loop_filter_strength[qscale];
+
+    for (y = 0; y < 8; y++) {
+        int d1, d2, ad1;
+        int p0 = src[y * stride - 2];
+        int p1 = src[y * stride - 1];
+        int p2 = src[y * stride + 0];
+        int p3 = src[y * stride + 1];
+        int d  = (p0 - p3 + 4 * (p2 - p1)) / 8;
+
+        if (d < -2 * strength)
+            d1 = 0;
+        else if (d < -strength)
+            d1 = -2 * strength - d;
+        else if (d < strength)
+            d1 = d;
+        else if (d < 2 * strength)
+            d1 = 2 * strength - d;
+        else
+            d1 = 0;
+
+        p1 += d1;
+        p2 -= d1;
+        if (p1 & 256)
+            p1 = ~(p1 >> 31);
+        if (p2 & 256)
+            p2 = ~(p2 >> 31);
+
+        src[y * stride - 1] = p1;
+        src[y * stride + 0] = p2;
+
+        ad1 = FFABS(d1) >> 1;
+
+        d2 = av_clip((p0 - p3) / 4, -ad1, ad1);
+
+        src[y * stride - 2] = p0 - d2;
+        src[y * stride + 1] = p3 + d2;
+    }
+}
+
+static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale)
+{
+    int x;
+    const int strength = ff_h263_loop_filter_strength[qscale];
+
+    for (x = 0; x < 8; x++) {
+        int d1, d2, ad1;
+        int p0 = src[x - 2 * stride];
+        int p1 = src[x - 1 * stride];
+        int p2 = src[x + 0 * stride];
+        int p3 = src[x + 1 * stride];
+        int d  = (p0 - p3 + 4 * (p2 - p1)) / 8;
+
+        if (d < -2 * strength)
+            d1 = 0;
+        else if (d < -strength)
+            d1 = -2 * strength - d;
+        else if (d < strength)
+            d1 = d;
+        else if (d < 2 * strength)
+            d1 = 2 * strength - d;
+        else
+            d1 = 0;
+
+        p1 += d1;
+        p2 -= d1;
+        if (p1 & 256)
+            p1 = ~(p1 >> 31);
+        if (p2 & 256)
+            p2 = ~(p2 >> 31);
+
+        src[x - 1 * stride] = p1;
+        src[x + 0 * stride] = p2;
+
+        ad1 = FFABS(d1) >> 1;
+
+        d2 = av_clip((p0 - p3) / 4, -ad1, ad1);
+
+        src[x - 2 * stride] = p0 - d2;
+        src[x + stride]     = p3 + d2;
+    }
+}
+
+av_cold void ff_h263dsp_init(H263DSPContext *ctx)
+{
+    ctx->h263_h_loop_filter = h263_h_loop_filter_c;
+    ctx->h263_v_loop_filter = h263_v_loop_filter_c;
+
+    if (ARCH_X86)
+        ff_h263dsp_init_x86(ctx);
+}
diff --git a/libavcodec/h263dsp.h b/libavcodec/h263dsp.h
new file mode 100644
index 0000000..40f041c
--- /dev/null
+++ b/libavcodec/h263dsp.h
@@ -0,0 +1,34 @@
+/*
+ * 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_H263DSP_H
+#define AVCODEC_H263DSP_H
+
+#include <stdint.h>
+
+extern const uint8_t ff_h263_loop_filter_strength[32];
+
+typedef struct H263DSPContext {
+    void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale);
+    void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale);
+} H263DSPContext;
+
+void ff_h263dsp_init(H263DSPContext *ctx);
+void ff_h263dsp_init_x86(H263DSPContext *ctx);
+
+#endif /* AVCODEC_H263DSP_H */
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 8625b0f..07a93cf 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -25,24 +25,26 @@
  * @author Michael Niedermayer <michaelni at gmx.at>
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/stereo3d.h"
 #include "internal.h"
 #include "cabac.h"
 #include "cabac_functions.h"
 #include "dsputil.h"
+#include "error_resilience.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h264.h"
 #include "h264data.h"
+#include "h264chroma.h"
 #include "h264_mvpred.h"
 #include "golomb.h"
 #include "mathops.h"
 #include "rectangle.h"
+#include "svq3.h"
 #include "thread.h"
-#include "vdpau_internal.h"
-#include "libavutil/avassert.h"
 
-// #undef NDEBUG
 #include <assert.h>
 
 const uint16_t ff_h264_mb_sizes[4] = { 256, 384, 512, 768 };
@@ -59,21 +61,432 @@ static const uint8_t div6[QP_MAX_NUM + 1] = {
     7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10,
 };
 
-static const enum AVPixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
+static const uint8_t field_scan[16] = {
+    0 + 0 * 4, 0 + 1 * 4, 1 + 0 * 4, 0 + 2 * 4,
+    0 + 3 * 4, 1 + 1 * 4, 1 + 2 * 4, 1 + 3 * 4,
+    2 + 0 * 4, 2 + 1 * 4, 2 + 2 * 4, 2 + 3 * 4,
+    3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4,
+};
+
+static const uint8_t field_scan8x8[64] = {
+    0 + 0 * 8, 0 + 1 * 8, 0 + 2 * 8, 1 + 0 * 8,
+    1 + 1 * 8, 0 + 3 * 8, 0 + 4 * 8, 1 + 2 * 8,
+    2 + 0 * 8, 1 + 3 * 8, 0 + 5 * 8, 0 + 6 * 8,
+    0 + 7 * 8, 1 + 4 * 8, 2 + 1 * 8, 3 + 0 * 8,
+    2 + 2 * 8, 1 + 5 * 8, 1 + 6 * 8, 1 + 7 * 8,
+    2 + 3 * 8, 3 + 1 * 8, 4 + 0 * 8, 3 + 2 * 8,
+    2 + 4 * 8, 2 + 5 * 8, 2 + 6 * 8, 2 + 7 * 8,
+    3 + 3 * 8, 4 + 1 * 8, 5 + 0 * 8, 4 + 2 * 8,
+    3 + 4 * 8, 3 + 5 * 8, 3 + 6 * 8, 3 + 7 * 8,
+    4 + 3 * 8, 5 + 1 * 8, 6 + 0 * 8, 5 + 2 * 8,
+    4 + 4 * 8, 4 + 5 * 8, 4 + 6 * 8, 4 + 7 * 8,
+    5 + 3 * 8, 6 + 1 * 8, 6 + 2 * 8, 5 + 4 * 8,
+    5 + 5 * 8, 5 + 6 * 8, 5 + 7 * 8, 6 + 3 * 8,
+    7 + 0 * 8, 7 + 1 * 8, 6 + 4 * 8, 6 + 5 * 8,
+    6 + 6 * 8, 6 + 7 * 8, 7 + 2 * 8, 7 + 3 * 8,
+    7 + 4 * 8, 7 + 5 * 8, 7 + 6 * 8, 7 + 7 * 8,
+};
+
+static const uint8_t field_scan8x8_cavlc[64] = {
+    0 + 0 * 8, 1 + 1 * 8, 2 + 0 * 8, 0 + 7 * 8,
+    2 + 2 * 8, 2 + 3 * 8, 2 + 4 * 8, 3 + 3 * 8,
+    3 + 4 * 8, 4 + 3 * 8, 4 + 4 * 8, 5 + 3 * 8,
+    5 + 5 * 8, 7 + 0 * 8, 6 + 6 * 8, 7 + 4 * 8,
+    0 + 1 * 8, 0 + 3 * 8, 1 + 3 * 8, 1 + 4 * 8,
+    1 + 5 * 8, 3 + 1 * 8, 2 + 5 * 8, 4 + 1 * 8,
+    3 + 5 * 8, 5 + 1 * 8, 4 + 5 * 8, 6 + 1 * 8,
+    5 + 6 * 8, 7 + 1 * 8, 6 + 7 * 8, 7 + 5 * 8,
+    0 + 2 * 8, 0 + 4 * 8, 0 + 5 * 8, 2 + 1 * 8,
+    1 + 6 * 8, 4 + 0 * 8, 2 + 6 * 8, 5 + 0 * 8,
+    3 + 6 * 8, 6 + 0 * 8, 4 + 6 * 8, 6 + 2 * 8,
+    5 + 7 * 8, 6 + 4 * 8, 7 + 2 * 8, 7 + 6 * 8,
+    1 + 0 * 8, 1 + 2 * 8, 0 + 6 * 8, 3 + 0 * 8,
+    1 + 7 * 8, 3 + 2 * 8, 2 + 7 * 8, 4 + 2 * 8,
+    3 + 7 * 8, 5 + 2 * 8, 4 + 7 * 8, 5 + 4 * 8,
+    6 + 3 * 8, 6 + 5 * 8, 7 + 3 * 8, 7 + 7 * 8,
+};
+
+// zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)]
+static const uint8_t zigzag_scan8x8_cavlc[64] = {
+    0 + 0 * 8, 1 + 1 * 8, 1 + 2 * 8, 2 + 2 * 8,
+    4 + 1 * 8, 0 + 5 * 8, 3 + 3 * 8, 7 + 0 * 8,
+    3 + 4 * 8, 1 + 7 * 8, 5 + 3 * 8, 6 + 3 * 8,
+    2 + 7 * 8, 6 + 4 * 8, 5 + 6 * 8, 7 + 5 * 8,
+    1 + 0 * 8, 2 + 0 * 8, 0 + 3 * 8, 3 + 1 * 8,
+    3 + 2 * 8, 0 + 6 * 8, 4 + 2 * 8, 6 + 1 * 8,
+    2 + 5 * 8, 2 + 6 * 8, 6 + 2 * 8, 5 + 4 * 8,
+    3 + 7 * 8, 7 + 3 * 8, 4 + 7 * 8, 7 + 6 * 8,
+    0 + 1 * 8, 3 + 0 * 8, 0 + 4 * 8, 4 + 0 * 8,
+    2 + 3 * 8, 1 + 5 * 8, 5 + 1 * 8, 5 + 2 * 8,
+    1 + 6 * 8, 3 + 5 * 8, 7 + 1 * 8, 4 + 5 * 8,
+    4 + 6 * 8, 7 + 4 * 8, 5 + 7 * 8, 6 + 7 * 8,
+    0 + 2 * 8, 2 + 1 * 8, 1 + 3 * 8, 5 + 0 * 8,
+    1 + 4 * 8, 2 + 4 * 8, 6 + 0 * 8, 4 + 3 * 8,
+    0 + 7 * 8, 4 + 4 * 8, 7 + 2 * 8, 3 + 6 * 8,
+    5 + 5 * 8, 6 + 5 * 8, 6 + 6 * 8, 7 + 7 * 8,
+};
+
+static const uint8_t dequant4_coeff_init[6][3] = {
+    { 10, 13, 16 },
+    { 11, 14, 18 },
+    { 13, 16, 20 },
+    { 14, 18, 23 },
+    { 16, 20, 25 },
+    { 18, 23, 29 },
+};
+
+static const uint8_t dequant8_coeff_init_scan[16] = {
+    0, 3, 4, 3, 3, 1, 5, 1, 4, 5, 2, 5, 3, 1, 5, 1
+};
+
+static const uint8_t dequant8_coeff_init[6][6] = {
+    { 20, 18, 32, 19, 25, 24 },
+    { 22, 19, 35, 21, 28, 26 },
+    { 26, 23, 42, 24, 33, 31 },
+    { 28, 25, 45, 26, 35, 33 },
+    { 32, 28, 51, 30, 40, 38 },
+    { 36, 32, 58, 34, 46, 43 },
+};
+
+static const enum AVPixelFormat h264_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_H264_DXVA2_HWACCEL
+    AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_H264_VAAPI_HWACCEL
+    AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_H264_VDA_HWACCEL
+    AV_PIX_FMT_VDA_VLD,
+#endif
+#if CONFIG_H264_VDPAU_HWACCEL
+    AV_PIX_FMT_VDPAU,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat h264_hwaccel_pixfmt_list_jpeg_420[] = {
+#if CONFIG_H264_DXVA2_HWACCEL
     AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_H264_VAAPI_HWACCEL
     AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_H264_VDA_HWACCEL
     AV_PIX_FMT_VDA_VLD,
+#endif
+#if CONFIG_H264_VDPAU_HWACCEL
+    AV_PIX_FMT_VDPAU,
+#endif
     AV_PIX_FMT_YUVJ420P,
     AV_PIX_FMT_NONE
 };
 
+static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
+                              int (*mv)[2][4][2],
+                              int mb_x, int mb_y, int mb_intra, int mb_skipped)
+{
+    H264Context *h = opaque;
+
+    h->mb_x  = mb_x;
+    h->mb_y  = mb_y;
+    h->mb_xy = mb_x + mb_y * h->mb_stride;
+    memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
+    assert(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;
+    fill_rectangle(&h->cur_pic.ref_index[0][4 * h->mb_xy],
+                   2, 2, 2, ref, 1);
+    fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
+    fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
+                   pack16to32((*mv)[0][0][0], (*mv)[0][0][1]), 4);
+    assert(!FRAME_MBAFF(h));
+    ff_h264_hl_decode_mb(h);
+}
+
+void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
+{
+    AVCodecContext *avctx = h->avctx;
+    Picture *cur  = &h->cur_pic;
+    Picture *last = h->ref_list[0][0].f.data[0] ? &h->ref_list[0][0] : NULL;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    int vshift = desc->log2_chroma_h;
+    const int field_pic = h->picture_structure != PICT_FRAME;
+    if (field_pic) {
+        height <<= 1;
+        y      <<= 1;
+    }
+
+    height = FFMIN(height, avctx->height - y);
+
+    if (field_pic && h->first_field && !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD))
+        return;
+
+    if (avctx->draw_horiz_band) {
+        AVFrame *src;
+        int offset[AV_NUM_DATA_POINTERS];
+        int i;
+
+        if (cur->f.pict_type == AV_PICTURE_TYPE_B || h->low_delay ||
+            (avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
+            src = &cur->f;
+        else if (last)
+            src = &last->f;
+        else
+            return;
+
+        offset[0] = y * src->linesize[0];
+        offset[1] =
+        offset[2] = (y >> vshift) * src->linesize[1];
+        for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
+            offset[i] = 0;
+
+        emms_c();
+
+        avctx->draw_horiz_band(avctx, src, offset,
+                               y, h->picture_structure, height);
+    }
+}
+
+static void unref_picture(H264Context *h, Picture *pic)
+{
+    int off = offsetof(Picture, tf) + sizeof(pic->tf);
+    int i;
+
+    if (!pic->f.buf[0])
+        return;
+
+    ff_thread_release_buffer(h->avctx, &pic->tf);
+    av_buffer_unref(&pic->hwaccel_priv_buf);
+
+    av_buffer_unref(&pic->qscale_table_buf);
+    av_buffer_unref(&pic->mb_type_buf);
+    for (i = 0; i < 2; i++) {
+        av_buffer_unref(&pic->motion_val_buf[i]);
+        av_buffer_unref(&pic->ref_index_buf[i]);
+    }
+
+    memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
+}
+
+static void release_unused_pictures(H264Context *h, int remove_current)
+{
+    int i;
+
+    /* release non reference frames */
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        if (h->DPB[i].f.buf[0] && !h->DPB[i].reference &&
+            (remove_current || &h->DPB[i] != h->cur_pic_ptr)) {
+            unref_picture(h, &h->DPB[i]);
+        }
+    }
+}
+
+static int ref_picture(H264Context *h, Picture *dst, Picture *src)
+{
+    int ret, i;
+
+    av_assert0(!dst->f.buf[0]);
+    av_assert0(src->f.buf[0]);
+
+    src->tf.f = &src->f;
+    dst->tf.f = &dst->f;
+    ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+    if (ret < 0)
+        goto fail;
+
+    dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf);
+    dst->mb_type_buf      = av_buffer_ref(src->mb_type_buf);
+    if (!dst->qscale_table_buf || !dst->mb_type_buf)
+        goto fail;
+    dst->qscale_table = src->qscale_table;
+    dst->mb_type      = src->mb_type;
+
+    for (i = 0; i < 2; i++) {
+        dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]);
+        dst->ref_index_buf[i]  = av_buffer_ref(src->ref_index_buf[i]);
+        if (!dst->motion_val_buf[i] || !dst->ref_index_buf[i])
+            goto fail;
+        dst->motion_val[i] = src->motion_val[i];
+        dst->ref_index[i]  = src->ref_index[i];
+    }
+
+    if (src->hwaccel_picture_private) {
+        dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
+        if (!dst->hwaccel_priv_buf)
+            goto fail;
+        dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
+    }
+
+    for (i = 0; i < 2; i++)
+        dst->field_poc[i] = src->field_poc[i];
+
+    memcpy(dst->ref_poc,   src->ref_poc,   sizeof(src->ref_poc));
+    memcpy(dst->ref_count, src->ref_count, sizeof(src->ref_count));
+
+    dst->poc           = src->poc;
+    dst->frame_num     = src->frame_num;
+    dst->mmco_reset    = src->mmco_reset;
+    dst->pic_id        = src->pic_id;
+    dst->long_ref      = src->long_ref;
+    dst->mbaff         = src->mbaff;
+    dst->field_picture = src->field_picture;
+    dst->needs_realloc = src->needs_realloc;
+    dst->reference     = src->reference;
+    dst->recovered     = src->recovered;
+
+    return 0;
+fail:
+    unref_picture(h, dst);
+    return ret;
+}
+
+static int alloc_scratch_buffers(H264Context *h, int linesize)
+{
+    int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
+
+    if (h->bipred_scratchpad)
+        return 0;
+
+    h->bipred_scratchpad = av_malloc(16 * 6 * alloc_size);
+    // edge emu needs blocksize + filter length - 1
+    // (= 21x21 for  h264)
+    h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 21);
+    h->me.scratchpad   = av_mallocz(alloc_size * 2 * 16 * 2);
+
+    if (!h->bipred_scratchpad || !h->edge_emu_buffer || !h->me.scratchpad) {
+        av_freep(&h->bipred_scratchpad);
+        av_freep(&h->edge_emu_buffer);
+        av_freep(&h->me.scratchpad);
+        return AVERROR(ENOMEM);
+    }
+
+    h->me.temp = h->me.scratchpad;
+
+    return 0;
+}
+
+static int init_table_pools(H264Context *h)
+{
+    const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
+    const int mb_array_size = h->mb_stride * h->mb_height;
+    const int b4_stride     = h->mb_width * 4 + 1;
+    const int b4_array_size = b4_stride * h->mb_height * 4;
+
+    h->qscale_table_pool = av_buffer_pool_init(big_mb_num + h->mb_stride,
+                                               av_buffer_allocz);
+    h->mb_type_pool      = av_buffer_pool_init((big_mb_num + h->mb_stride) *
+                                               sizeof(uint32_t), av_buffer_allocz);
+    h->motion_val_pool = av_buffer_pool_init(2 * (b4_array_size + 4) *
+                                             sizeof(int16_t), av_buffer_allocz);
+    h->ref_index_pool  = av_buffer_pool_init(4 * mb_array_size, av_buffer_allocz);
+
+    if (!h->qscale_table_pool || !h->mb_type_pool || !h->motion_val_pool ||
+        !h->ref_index_pool) {
+        av_buffer_pool_uninit(&h->qscale_table_pool);
+        av_buffer_pool_uninit(&h->mb_type_pool);
+        av_buffer_pool_uninit(&h->motion_val_pool);
+        av_buffer_pool_uninit(&h->ref_index_pool);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int alloc_picture(H264Context *h, Picture *pic)
+{
+    int i, ret = 0;
+
+    av_assert0(!pic->f.data[0]);
+
+    pic->tf.f = &pic->f;
+    ret = ff_thread_get_buffer(h->avctx, &pic->tf, pic->reference ?
+                                                   AV_GET_BUFFER_FLAG_REF : 0);
+    if (ret < 0)
+        goto fail;
+
+    h->linesize   = pic->f.linesize[0];
+    h->uvlinesize = pic->f.linesize[1];
+
+    if (h->avctx->hwaccel) {
+        const AVHWAccel *hwaccel = h->avctx->hwaccel;
+        av_assert0(!pic->hwaccel_picture_private);
+        if (hwaccel->priv_data_size) {
+            pic->hwaccel_priv_buf = av_buffer_allocz(hwaccel->priv_data_size);
+            if (!pic->hwaccel_priv_buf)
+                return AVERROR(ENOMEM);
+            pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data;
+        }
+    }
+
+    if (!h->qscale_table_pool) {
+        ret = init_table_pools(h);
+        if (ret < 0)
+            goto fail;
+    }
+
+    pic->qscale_table_buf = av_buffer_pool_get(h->qscale_table_pool);
+    pic->mb_type_buf      = av_buffer_pool_get(h->mb_type_pool);
+    if (!pic->qscale_table_buf || !pic->mb_type_buf)
+        goto fail;
+
+    pic->mb_type      = (uint32_t*)pic->mb_type_buf->data + 2 * h->mb_stride + 1;
+    pic->qscale_table = pic->qscale_table_buf->data + 2 * h->mb_stride + 1;
+
+    for (i = 0; i < 2; i++) {
+        pic->motion_val_buf[i] = av_buffer_pool_get(h->motion_val_pool);
+        pic->ref_index_buf[i]  = av_buffer_pool_get(h->ref_index_pool);
+        if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i])
+            goto fail;
+
+        pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
+        pic->ref_index[i]  = pic->ref_index_buf[i]->data;
+    }
+
+    return 0;
+fail:
+    unref_picture(h, pic);
+    return (ret < 0) ? ret : AVERROR(ENOMEM);
+}
+
+static inline int pic_is_unused(H264Context *h, Picture *pic)
+{
+    if (!pic->f.buf[0])
+        return 1;
+    if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF))
+        return 1;
+    return 0;
+}
+
+static int find_unused_picture(H264Context *h)
+{
+    int i;
+
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        if (pic_is_unused(h, &h->DPB[i]))
+            break;
+    }
+    if (i == MAX_PICTURE_COUNT)
+        return AVERROR_INVALIDDATA;
+
+    if (h->DPB[i].needs_realloc) {
+        h->DPB[i].needs_realloc = 0;
+        unref_picture(h, &h->DPB[i]);
+    }
+
+    return i;
+}
+
 /**
  * Check if the top & left blocks are available if needed and
  * change the dc mode so it only uses the available blocks.
  */
 int ff_h264_check_intra4x4_pred_mode(H264Context *h)
 {
-    MpegEncContext *const s     = &h->s;
     static const int8_t top[12] = {
         -1, 0, LEFT_DC_PRED, -1, -1, -1, -1, -1, 0
     };
@@ -86,10 +499,10 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
         for (i = 0; i < 4; i++) {
             int status = top[h->intra4x4_pred_mode_cache[scan8[0] + i]];
             if (status < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "top block unavailable for requested intra4x4 mode %d at %d %d\n",
-                       status, s->mb_x, s->mb_y);
-                return -1;
+                       status, h->mb_x, h->mb_y);
+                return AVERROR_INVALIDDATA;
             } else if (status) {
                 h->intra4x4_pred_mode_cache[scan8[0] + i] = status;
             }
@@ -102,10 +515,10 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
             if (!(h->left_samples_available & mask[i])) {
                 int status = left[h->intra4x4_pred_mode_cache[scan8[0] + 8 * i]];
                 if (status < 0) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "left block unavailable for requested intra4x4 mode %d at %d %d\n",
-                           status, s->mb_x, s->mb_y);
-                    return -1;
+                           status, h->mb_x, h->mb_y);
+                    return AVERROR_INVALIDDATA;
                 } else if (status) {
                     h->intra4x4_pred_mode_cache[scan8[0] + 8 * i] = status;
                 }
@@ -121,24 +534,23 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
  */
 int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
 {
-    MpegEncContext *const s     = &h->s;
     static const int8_t top[7]  = { LEFT_DC_PRED8x8, 1, -1, -1 };
     static const int8_t left[7] = { TOP_DC_PRED8x8, -1, 2, -1, DC_128_PRED8x8 };
 
     if (mode > 6U) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "out of range intra chroma pred mode at %d %d\n",
-               s->mb_x, s->mb_y);
-        return -1;
+               h->mb_x, h->mb_y);
+        return AVERROR_INVALIDDATA;
     }
 
     if (!(h->top_samples_available & 0x8000)) {
         mode = top[mode];
         if (mode < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "top block unavailable for requested intra mode at %d %d\n",
-                   s->mb_x, s->mb_y);
-            return -1;
+                   h->mb_x, h->mb_y);
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -151,10 +563,10 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
                    2 * (mode == DC_128_PRED8x8);
         }
         if (mode < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "left block unavailable for requested intra mode at %d %d\n",
-                   s->mb_x, s->mb_y);
-            return -1;
+                   h->mb_x, h->mb_y);
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -176,19 +588,21 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src,
     length--;
 
 #define STARTCODE_TEST                                                  \
-        if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) {     \
-            if (src[i + 2] != 3) {                                      \
-                /* startcode, so we must be past the end */             \
-                length = i;                                             \
-            }                                                           \
-            break;                                                      \
-        }
+    if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) {         \
+        if (src[i + 2] != 3) {                                          \
+            /* startcode, so we must be past the end */                 \
+            length = i;                                                 \
+        }                                                               \
+        break;                                                          \
+    }
+
 #if HAVE_FAST_UNALIGNED
 #define FIND_FIRST_ZERO                                                 \
-        if (i > 0 && !src[i])                                           \
-            i--;                                                        \
-        while (src[i])                                                  \
-            i++
+    if (i > 0 && !src[i])                                               \
+        i--;                                                            \
+    while (src[i])                                                      \
+        i++
+
 #if HAVE_FAST_64BIT
     for (i = 0; i + 1 < length; i += 9) {
         if (!((~AV_RN64A(src + i) &
@@ -256,8 +670,8 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src,
     }
     while (si < length)
         dst[di++] = src[si++];
-nsc:
 
+nsc:
     memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 
     *dst_length = di;
@@ -276,7 +690,7 @@ static int decode_rbsp_trailing(H264Context *h, const uint8_t *src)
     int v = *src;
     int r;
 
-    tprintf(h->s.avctx, "rbsp trailing %X\n", v);
+    tprintf(h->avctx, "rbsp trailing %X\n", v);
 
     for (r = 1; r < 9; r++) {
         if (v & 1)
@@ -289,12 +703,12 @@ static int decode_rbsp_trailing(H264Context *h, const uint8_t *src)
 static inline int get_lowest_part_list_y(H264Context *h, Picture *pic, int n,
                                          int height, int y_offset, int list)
 {
-    int raw_my        = h->mv_cache[list][scan8[n]][1];
+    int raw_my             = h->mv_cache[list][scan8[n]][1];
     int filter_height_up   = (raw_my & 3) ? 2 : 0;
     int filter_height_down = (raw_my & 3) ? 3 : 0;
-    int full_my       = (raw_my >> 2) + y_offset;
-    int top           = full_my - filter_height_up;
-    int bottom        = full_my + filter_height_down + height;
+    int full_my            = (raw_my >> 2) + y_offset;
+    int top                = full_my - filter_height_up;
+    int bottom             = full_my + filter_height_down + height;
 
     return FFMAX(abs(top), bottom);
 }
@@ -303,10 +717,9 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
                                      int height, int y_offset, int list0,
                                      int list1, int *nrefs)
 {
-    MpegEncContext *const s = &h->s;
     int my;
 
-    y_offset += 16 * (s->mb_y >> MB_FIELD);
+    y_offset += 16 * (h->mb_y >> MB_FIELD(h));
 
     if (list0) {
         int ref_n    = h->ref_cache[0][scan8[n]];
@@ -315,8 +728,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
         // Error resilience puts the current picture in the ref list.
         // Don't try to wait on these as it will cause a deadlock.
         // Fields can wait on each other, though.
-        if (ref->f.thread_opaque   != s->current_picture.f.thread_opaque ||
-            (ref->f.reference & 3) != s->picture_structure) {
+        if (ref->tf.progress->data != h->cur_pic.tf.progress->data ||
+            (ref->reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0);
             if (refs[0][ref_n] < 0)
                 nrefs[0] += 1;
@@ -328,8 +741,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
         int ref_n    = h->ref_cache[1][scan8[n]];
         Picture *ref = &h->ref_list[1][ref_n];
 
-        if (ref->f.thread_opaque   != s->current_picture.f.thread_opaque ||
-            (ref->f.reference & 3) != s->picture_structure) {
+        if (ref->tf.progress->data != h->cur_pic.tf.progress->data ||
+            (ref->reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1);
             if (refs[1][ref_n] < 0)
                 nrefs[1] += 1;
@@ -345,9 +758,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
  */
 static void await_references(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     int refs[2][48];
     int nrefs[2] = { 0 };
     int ref, list;
@@ -419,32 +831,32 @@ static void await_references(H264Context *h)
             int row = refs[list][ref];
             if (row >= 0) {
                 Picture *ref_pic      = &h->ref_list[list][ref];
-                int ref_field         = ref_pic->f.reference - 1;
+                int ref_field         = ref_pic->reference - 1;
                 int ref_field_picture = ref_pic->field_picture;
-                int pic_height        = 16 * s->mb_height >> ref_field_picture;
+                int pic_height        = 16 * h->mb_height >> ref_field_picture;
 
-                row <<= MB_MBAFF;
+                row <<= MB_MBAFF(h);
                 nrefs[list]--;
 
-                if (!FIELD_PICTURE && ref_field_picture) { // frame referencing two fields
-                    ff_thread_await_progress(&ref_pic->f,
+                if (!FIELD_PICTURE(h) && ref_field_picture) { // frame referencing two fields
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN((row >> 1) - !(row & 1),
                                                    pic_height - 1),
                                              1);
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN((row >> 1), pic_height - 1),
                                              0);
-                } else if (FIELD_PICTURE && !ref_field_picture) { // field referencing one field of a frame
-                    ff_thread_await_progress(&ref_pic->f,
+                } else if (FIELD_PICTURE(h) && !ref_field_picture) { // field referencing one field of a frame
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row * 2 + ref_field,
                                                    pic_height - 1),
                                              0);
-                } else if (FIELD_PICTURE) {
-                    ff_thread_await_progress(&ref_pic->f,
+                } else if (FIELD_PICTURE(h)) {
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row, pic_height - 1),
                                              ref_field);
                 } else {
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row, pic_height - 1),
                                              0);
                 }
@@ -462,20 +874,19 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
                                          h264_chroma_mc_func chroma_op,
                                          int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s = &h->s;
     const int mx      = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8;
     int my            = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8;
     const int luma_xy = (mx & 3) + ((my & 3) << 2);
-    int offset        = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize;
+    ptrdiff_t offset  = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize;
     uint8_t *src_y    = pic->f.data[0] + offset;
     uint8_t *src_cb, *src_cr;
-    int extra_width  = h->emu_edge_width;
-    int extra_height = h->emu_edge_height;
+    int extra_width  = 0;
+    int extra_height = 0;
     int emu = 0;
     const int full_mx    = mx >> 2;
     const int full_my    = my >> 2;
-    const int pic_width  = 16 * s->mb_width;
-    const int pic_height = 16 * s->mb_height >> MB_FIELD;
+    const int pic_width  = 16 * h->mb_width;
+    const int pic_height = 16 * h->mb_height >> MB_FIELD(h);
     int ysh;
 
     if (mx & 7)
@@ -487,12 +898,12 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
         full_my                <          0 - extra_height ||
         full_mx + 16 /*FIXME*/ > pic_width  + extra_width  ||
         full_my + 16 /*FIXME*/ > pic_height + extra_height) {
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
                                  src_y - (2 << pixel_shift) - 2 * h->mb_linesize,
-                                 h->mb_linesize,
+                                 h->mb_linesize, h->mb_linesize,
                                  16 + 5, 16 + 5 /*FIXME*/, full_mx - 2,
                                  full_my - 2, pic_width, pic_height);
-        src_y = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+        src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         emu   = 1;
     }
 
@@ -500,19 +911,19 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
     if (!square)
         qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize);
 
-    if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY)
+    if (CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY)
         return;
 
     if (chroma_idc == 3 /* yuv444 */) {
         src_cb = pic->f.data[1] + offset;
         if (emu) {
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+            h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
                                      src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,
-                                     h->mb_linesize,
+                                     h->mb_linesize, h->mb_linesize,
                                      16 + 5, 16 + 5 /*FIXME*/,
                                      full_mx - 2, full_my - 2,
                                      pic_width, pic_height);
-            src_cb = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+            src_cb = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         }
         qpix_op[luma_xy](dest_cb, src_cb, h->mb_linesize); // FIXME try variable height perhaps?
         if (!square)
@@ -520,13 +931,13 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
 
         src_cr = pic->f.data[2] + offset;
         if (emu) {
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+            h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
                                      src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,
-                                     h->mb_linesize,
+                                     h->mb_linesize, h->mb_linesize,
                                      16 + 5, 16 + 5 /*FIXME*/,
                                      full_mx - 2, full_my - 2,
                                      pic_width, pic_height);
-            src_cr = s->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
+            src_cr = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;
         }
         qpix_op[luma_xy](dest_cr, src_cr, h->mb_linesize); // FIXME try variable height perhaps?
         if (!square)
@@ -535,9 +946,9 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
     }
 
     ysh = 3 - (chroma_idc == 2 /* yuv422 */);
-    if (chroma_idc == 1 /* yuv420 */ && MB_FIELD) {
+    if (chroma_idc == 1 /* yuv420 */ && MB_FIELD(h)) {
         // chroma offset when predicting from a field of opposite parity
-        my  += 2 * ((s->mb_y & 1) - (pic->f.reference - 1));
+        my  += 2 * ((h->mb_y & 1) - (pic->reference - 1));
         emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1);
     }
 
@@ -547,20 +958,22 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
              (my >> ysh) * h->mb_uvlinesize;
 
     if (emu) {
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src_cb, h->mb_uvlinesize,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb,
+                                 h->mb_uvlinesize, h->mb_uvlinesize,
                                  9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
                                  pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
-        src_cb = s->edge_emu_buffer;
+        src_cb = h->edge_emu_buffer;
     }
     chroma_op(dest_cb, src_cb, h->mb_uvlinesize,
               height >> (chroma_idc == 1 /* yuv420 */),
               mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);
 
     if (emu) {
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src_cr, h->mb_uvlinesize,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr,
+                                 h->mb_uvlinesize, h->mb_uvlinesize,
                                  9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),
                                  pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));
-        src_cr = s->edge_emu_buffer;
+        src_cr = h->edge_emu_buffer;
     }
     chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 /* yuv420 */),
               mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);
@@ -578,7 +991,6 @@ static av_always_inline void mc_part_std(H264Context *h, int n, int square,
                                          int list0, int list1,
                                          int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s       = &h->s;
     qpel_mc_func *qpix_op         = qpix_put;
     h264_chroma_mc_func chroma_op = chroma_put;
 
@@ -593,8 +1005,8 @@ static av_always_inline void mc_part_std(H264Context *h, int n, int square,
         dest_cb += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
         dest_cr += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
     }
-    x_offset += 8 * s->mb_x;
-    y_offset += 8 * (s->mb_y >> MB_FIELD);
+    x_offset += 8 * h->mb_x;
+    y_offset += 8 * (h->mb_y >> MB_FIELD(h));
 
     if (list0) {
         Picture *ref = &h->ref_list[0][h->ref_cache[0][scan8[n]]];
@@ -628,7 +1040,6 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square,
                                               int list0, int list1,
                                               int pixel_shift, int chroma_idc)
 {
-    MpegEncContext *const s = &h->s;
     int chroma_height;
 
     dest_y += (2 * x_offset << pixel_shift) + 2 * y_offset * h->mb_linesize;
@@ -647,8 +1058,8 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square,
         dest_cb      += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
         dest_cr      += (x_offset << pixel_shift) + y_offset * h->mb_uvlinesize;
     }
-    x_offset += 8 * s->mb_x;
-    y_offset += 8 * (s->mb_y >> MB_FIELD);
+    x_offset += 8 * h->mb_x;
+    y_offset += 8 * (h->mb_y >> MB_FIELD(h));
 
     if (list0 && list1) {
         /* don't optimize for luma-only case, since B-frames usually
@@ -669,7 +1080,7 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square,
                     pixel_shift, chroma_idc);
 
         if (h->use_weight == 2) {
-            int weight0 = h->implicit_weight[refn0][refn1][s->mb_y & 1];
+            int weight0 = h->implicit_weight[refn0][refn1][h->mb_y & 1];
             int weight1 = 64 - weight0;
             luma_weight_avg(dest_y, tmp_y, h->mb_linesize,
                             height, 5, weight0, weight1, 0);
@@ -727,24 +1138,23 @@ static av_always_inline void prefetch_motion(H264Context *h, int list,
 {
     /* fetch pixels for estimated mv 4 macroblocks ahead
      * optimized for 64byte cache lines */
-    MpegEncContext *const s = &h->s;
     const int refn = h->ref_cache[list][scan8[0]];
     if (refn >= 0) {
-        const int mx  = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * s->mb_x + 8;
-        const int my  = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * s->mb_y;
+        const int mx  = (h->mv_cache[list][scan8[0]][0] >> 2) + 16 * h->mb_x + 8;
+        const int my  = (h->mv_cache[list][scan8[0]][1] >> 2) + 16 * h->mb_y;
         uint8_t **src = h->ref_list[list][refn].f.data;
         int off       = (mx << pixel_shift) +
-                        (my + (s->mb_x & 3) * 4) * h->mb_linesize +
+                        (my + (h->mb_x & 3) * 4) * h->mb_linesize +
                         (64 << pixel_shift);
-        s->vdsp.prefetch(src[0] + off, s->linesize, 4);
+        h->vdsp.prefetch(src[0] + off, h->linesize, 4);
         if (chroma_idc == 3 /* yuv444 */) {
-            s->vdsp.prefetch(src[1] + off, s->linesize, 4);
-            s->vdsp.prefetch(src[2] + off, s->linesize, 4);
+            h->vdsp.prefetch(src[1] + off, h->linesize, 4);
+            h->vdsp.prefetch(src[2] + off, h->linesize, 4);
         } else {
             off = ((mx >> 1) << pixel_shift) +
-                  ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize +
+                  ((my >> 1) + (h->mb_x & 7)) * h->uvlinesize +
                   (64 << pixel_shift);
-            s->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
+            h->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
         }
     }
 }
@@ -768,6 +1178,22 @@ static void free_tables(H264Context *h, int free_rbsp)
     av_freep(&h->mb2b_xy);
     av_freep(&h->mb2br_xy);
 
+    av_buffer_pool_uninit(&h->qscale_table_pool);
+    av_buffer_pool_uninit(&h->mb_type_pool);
+    av_buffer_pool_uninit(&h->motion_val_pool);
+    av_buffer_pool_uninit(&h->ref_index_pool);
+
+    if (free_rbsp && h->DPB) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++)
+            unref_picture(h, &h->DPB[i]);
+        av_freep(&h->DPB);
+    } else if (h->DPB) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++)
+            h->DPB[i].needs_realloc = 1;
+    }
+
+    h->cur_pic_ptr = NULL;
+
     for (i = 0; i < MAX_THREADS; i++) {
         hx = h->thread_context[i];
         if (!hx)
@@ -775,6 +1201,15 @@ static void free_tables(H264Context *h, int free_rbsp)
         av_freep(&hx->top_borders[1]);
         av_freep(&hx->top_borders[0]);
         av_freep(&hx->bipred_scratchpad);
+        av_freep(&hx->edge_emu_buffer);
+        av_freep(&hx->dc_val_base);
+        av_freep(&hx->me.scratchpad);
+        av_freep(&hx->er.mb_index2xy);
+        av_freep(&hx->er.error_status_table);
+        av_freep(&hx->er.er_temp_buffer);
+        av_freep(&hx->er.mbintra_table);
+        av_freep(&hx->er.mbskip_table);
+
         if (free_rbsp) {
             av_freep(&hx->rbsp_buffer[1]);
             av_freep(&hx->rbsp_buffer[0]);
@@ -858,55 +1293,63 @@ static void init_dequant_tables(H264Context *h)
 
 int ff_h264_alloc_tables(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int big_mb_num    = s->mb_stride * (s->mb_height + 1);
-    const int row_mb_num    = s->mb_stride * 2 * s->avctx->thread_count;
-    int x, y;
+    const int big_mb_num = h->mb_stride * (h->mb_height + 1);
+    const int row_mb_num = h->mb_stride * 2 * h->avctx->thread_count;
+    int x, y, i;
 
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->intra4x4_pred_mode,
                       row_mb_num * 8 * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->non_zero_count,
                       big_mb_num * 48 * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base,
-                      (big_mb_num + s->mb_stride) * sizeof(*h->slice_table_base), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->slice_table_base,
+                      (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base), fail)
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->cbp_table,
                       big_mb_num * sizeof(uint16_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->chroma_pred_mode_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->chroma_pred_mode_table,
                       big_mb_num * sizeof(uint8_t), fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0],
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mvd_table[0],
                       16 * row_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1],
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mvd_table[1],
                       16 * row_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->direct_table,
                       4 * big_mb_num * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->list_counts,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->list_counts,
                       big_mb_num * sizeof(uint8_t), fail)
 
     memset(h->slice_table_base, -1,
-           (big_mb_num + s->mb_stride) * sizeof(*h->slice_table_base));
-    h->slice_table = h->slice_table_base + s->mb_stride * 2 + 1;
+           (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base));
+    h->slice_table = h->slice_table_base + h->mb_stride * 2 + 1;
 
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b_xy,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2b_xy,
                       big_mb_num * sizeof(uint32_t), fail);
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2br_xy,
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2br_xy,
                       big_mb_num * sizeof(uint32_t), fail);
-    for (y = 0; y < s->mb_height; y++)
-        for (x = 0; x < s->mb_width; x++) {
-            const int mb_xy = x + y * s->mb_stride;
+    for (y = 0; y < h->mb_height; y++)
+        for (x = 0; x < h->mb_width; x++) {
+            const int mb_xy = x + y * h->mb_stride;
             const int b_xy  = 4 * x + 4 * y * h->b_stride;
 
             h->mb2b_xy[mb_xy]  = b_xy;
-            h->mb2br_xy[mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * s->mb_stride)));
+            h->mb2br_xy[mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * h->mb_stride)));
         }
 
     if (!h->dequant4_coeff[0])
         init_dequant_tables(h);
 
+    if (!h->DPB) {
+        h->DPB = av_mallocz_array(MAX_PICTURE_COUNT, sizeof(*h->DPB));
+        if (!h->DPB)
+            return AVERROR(ENOMEM);
+        for (i = 0; i < MAX_PICTURE_COUNT; i++)
+            av_frame_unref(&h->DPB[i].f);
+        av_frame_unref(&h->cur_pic.f);
+    }
+
     return 0;
 
 fail:
     free_tables(h, 1);
-    return -1;
+    return AVERROR(ENOMEM);
 }
 
 /**
@@ -914,20 +1357,24 @@ fail:
  */
 static void clone_tables(H264Context *dst, H264Context *src, int i)
 {
-    MpegEncContext *const s     = &src->s;
-    dst->intra4x4_pred_mode     = src->intra4x4_pred_mode + i * 8 * 2 * s->mb_stride;
+    dst->intra4x4_pred_mode     = src->intra4x4_pred_mode + i * 8 * 2 * src->mb_stride;
     dst->non_zero_count         = src->non_zero_count;
     dst->slice_table            = src->slice_table;
     dst->cbp_table              = src->cbp_table;
     dst->mb2b_xy                = src->mb2b_xy;
     dst->mb2br_xy               = src->mb2br_xy;
     dst->chroma_pred_mode_table = src->chroma_pred_mode_table;
-    dst->mvd_table[0]           = src->mvd_table[0] + i * 8 * 2 * s->mb_stride;
-    dst->mvd_table[1]           = src->mvd_table[1] + i * 8 * 2 * s->mb_stride;
+    dst->mvd_table[0]           = src->mvd_table[0] + i * 8 * 2 * src->mb_stride;
+    dst->mvd_table[1]           = src->mvd_table[1] + i * 8 * 2 * src->mb_stride;
     dst->direct_table           = src->direct_table;
     dst->list_counts            = src->list_counts;
+    dst->DPB                    = src->DPB;
+    dst->cur_pic_ptr            = src->cur_pic_ptr;
+    dst->cur_pic                = src->cur_pic;
     dst->bipred_scratchpad      = NULL;
-    ff_h264_pred_init(&dst->hpc, src->s.codec_id, src->sps.bit_depth_luma,
+    dst->edge_emu_buffer        = NULL;
+    dst->me.scratchpad          = NULL;
+    ff_h264_pred_init(&dst->hpc, src->avctx->codec_id, src->sps.bit_depth_luma,
                       src->sps.chroma_format_idc);
 }
 
@@ -937,10 +1384,17 @@ static void clone_tables(H264Context *dst, H264Context *src, int i)
  */
 static int context_init(H264Context *h)
 {
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[0],
-                      h->s.mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
-    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->top_borders[1],
-                      h->s.mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
+    ERContext *er = &h->er;
+    int mb_array_size = h->mb_height * h->mb_stride;
+    int y_size  = (2 * h->mb_width + 1) * (2 * h->mb_height + 1);
+    int c_size  = h->mb_stride * (h->mb_height + 1);
+    int yc_size = y_size + 2   * c_size;
+    int x, y, i;
+
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[0],
+                      h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
+    FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[1],
+                      h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
 
     h->ref_cache[0][scan8[5]  + 1] =
     h->ref_cache[0][scan8[7]  + 1] =
@@ -949,40 +1403,61 @@ static int context_init(H264Context *h)
     h->ref_cache[1][scan8[7]  + 1] =
     h->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
 
-    return 0;
+    if (CONFIG_ERROR_RESILIENCE) {
+        /* init ER */
+        er->avctx          = h->avctx;
+        er->dsp            = &h->dsp;
+        er->decode_mb      = h264_er_decode_mb;
+        er->opaque         = h;
+        er->quarter_sample = 1;
 
-fail:
-    return -1; // free_tables will clean up for us
-}
+        er->mb_num      = h->mb_num;
+        er->mb_width    = h->mb_width;
+        er->mb_height   = h->mb_height;
+        er->mb_stride   = h->mb_stride;
+        er->b8_stride   = h->mb_width * 2 + 1;
 
-static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
-                            int parse_extradata);
+        FF_ALLOCZ_OR_GOTO(h->avctx, er->mb_index2xy, (h->mb_num + 1) * sizeof(int),
+                          fail); // error ressilience code looks cleaner with this
+        for (y = 0; y < h->mb_height; y++)
+            for (x = 0; x < h->mb_width; x++)
+                er->mb_index2xy[x + y * h->mb_width] = x + y * h->mb_stride;
 
-static av_cold void common_init(H264Context *h)
-{
-    MpegEncContext *const s = &h->s;
+        er->mb_index2xy[h->mb_height * h->mb_width] = (h->mb_height - 1) *
+                                                      h->mb_stride + h->mb_width;
 
-    s->width    = s->avctx->width;
-    s->height   = s->avctx->height;
-    s->codec_id = s->avctx->codec->id;
+        FF_ALLOCZ_OR_GOTO(h->avctx, er->error_status_table,
+                          mb_array_size * sizeof(uint8_t), fail);
 
-    ff_h264dsp_init(&h->h264dsp, 8, 1);
-    ff_h264_pred_init(&h->hpc, s->codec_id, 8, 1);
+        FF_ALLOC_OR_GOTO(h->avctx, er->mbintra_table, mb_array_size, fail);
+        memset(er->mbintra_table, 1, mb_array_size);
 
-    h->dequant_coeff_pps = -1;
-    s->unrestricted_mv   = 1;
+        FF_ALLOCZ_OR_GOTO(h->avctx, er->mbskip_table, mb_array_size + 2, fail);
 
-    /* needed so that IDCT permutation is known early */
-    ff_dsputil_init(&s->dsp, s->avctx);
-    ff_videodsp_init(&s->vdsp, 8);
+        FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer, h->mb_height * h->mb_stride,
+                         fail);
 
-    memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
-    memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
+        FF_ALLOCZ_OR_GOTO(h->avctx, h->dc_val_base, yc_size * sizeof(int16_t), fail);
+        er->dc_val[0] = h->dc_val_base + h->mb_width * 2 + 2;
+        er->dc_val[1] = h->dc_val_base + y_size + h->mb_stride + 1;
+        er->dc_val[2] = er->dc_val[1] + c_size;
+        for (i = 0; i < yc_size; i++)
+            h->dc_val_base[i] = 1024;
+    }
+
+    return 0;
+
+fail:
+    return AVERROR(ENOMEM); // free_tables will clean up for us
 }
 
+static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
+                            int parse_extradata);
+
 int ff_h264_decode_extradata(H264Context *h)
 {
-    AVCodecContext *avctx = h->s.avctx;
+    AVCodecContext *avctx = h->avctx;
+    int ret;
 
     if (avctx->extradata[0] == 1) {
         int i, cnt, nalsize;
@@ -992,7 +1467,7 @@ int ff_h264_decode_extradata(H264Context *h)
 
         if (avctx->extradata_size < 7) {
             av_log(avctx, AV_LOG_ERROR, "avcC too short\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         /* sps and pps in the avcC always have length coded with 2 bytes,
          * so put a fake nal_length_size = 2 while parsing them */
@@ -1003,11 +1478,12 @@ int ff_h264_decode_extradata(H264Context *h)
         for (i = 0; i < cnt; i++) {
             nalsize = AV_RB16(p) + 2;
             if (p - avctx->extradata + nalsize > avctx->extradata_size)
-                return -1;
-            if (decode_nal_units(h, p, nalsize, 1) < 0) {
+                return AVERROR_INVALIDDATA;
+            ret = decode_nal_units(h, p, nalsize, 1);
+            if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Decoding sps %d from avcC failed\n", i);
-                return -1;
+                return ret;
             }
             p += nalsize;
         }
@@ -1016,11 +1492,12 @@ int ff_h264_decode_extradata(H264Context *h)
         for (i = 0; i < cnt; i++) {
             nalsize = AV_RB16(p) + 2;
             if (p - avctx->extradata + nalsize > avctx->extradata_size)
-                return -1;
-            if (decode_nal_units(h, p, nalsize, 1) < 0) {
+                return AVERROR_INVALIDDATA;
+            ret = decode_nal_units(h, p, nalsize, 1);
+            if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Decoding pps %d from avcC failed\n", i);
-                return -1;
+                return ret;
             }
             p += nalsize;
         }
@@ -1028,8 +1505,9 @@ int ff_h264_decode_extradata(H264Context *h)
         h->nal_length_size = (avctx->extradata[4] & 0x03) + 1;
     } else {
         h->is_avc = 0;
-        if (decode_nal_units(h, avctx->extradata, avctx->extradata_size, 1) < 0)
-            return -1;
+        ret = decode_nal_units(h, avctx->extradata, avctx->extradata_size, 1);
+        if (ret < 0)
+            return ret;
     }
     return 0;
 }
@@ -1037,28 +1515,46 @@ int ff_h264_decode_extradata(H264Context *h)
 av_cold int ff_h264_decode_init(AVCodecContext *avctx)
 {
     H264Context *h = avctx->priv_data;
-    MpegEncContext *const s = &h->s;
     int i;
+    int ret;
+
+    h->avctx = avctx;
+
+    h->bit_depth_luma    = 8;
+    h->chroma_format_idc = 1;
+
+    ff_h264dsp_init(&h->h264dsp, 8, 1);
+    ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
+    ff_h264qpel_init(&h->h264qpel, 8);
+    ff_h264_pred_init(&h->hpc, h->avctx->codec_id, 8, 1);
+
+    h->dequant_coeff_pps = -1;
 
-    ff_MPV_decode_defaults(s);
+    /* needed so that IDCT permutation is known early */
+    if (CONFIG_ERROR_RESILIENCE)
+        ff_dsputil_init(&h->dsp, h->avctx);
+    ff_videodsp_init(&h->vdsp, 8);
 
-    s->avctx = avctx;
-    common_init(h);
+    memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
+    memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
 
-    s->out_format      = FMT_H264;
-    s->workaround_bugs = avctx->workaround_bugs;
+    h->picture_structure   = PICT_FRAME;
+    h->slice_context_count = 1;
+    h->workaround_bugs     = avctx->workaround_bugs;
+    h->flags               = avctx->flags;
 
     /* set defaults */
     // s->decode_mb = ff_h263_decode_mb;
-    s->quarter_sample = 1;
     if (!avctx->has_b_frames)
-        s->low_delay = 1;
+        h->low_delay = 1;
 
     avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
 
     ff_h264_decode_init_vlc();
 
-    h->pixel_shift = 0;
+    ff_init_cabac_states();
+
+    h->pixel_shift        = 0;
     h->sps.bit_depth_luma = avctx->bits_per_raw_sample = 8;
 
     h->thread_context[0] = h;
@@ -1068,55 +1564,71 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
     h->prev_poc_msb = 1 << 16;
     h->x264_build   = -1;
     ff_h264_reset_sei(h);
+    h->recovery_frame = -1;
+    h->frame_recovered = 0;
     if (avctx->codec_id == AV_CODEC_ID_H264) {
         if (avctx->ticks_per_frame == 1)
-            s->avctx->time_base.den *= 2;
+            h->avctx->time_base.den *= 2;
         avctx->ticks_per_frame = 2;
     }
 
-    if (avctx->extradata_size > 0 && avctx->extradata &&
-        ff_h264_decode_extradata(h))
-        return -1;
+    if (avctx->extradata_size > 0 && avctx->extradata) {
+       ret = ff_h264_decode_extradata(h);
+       if (ret < 0)
+           return ret;
+    }
 
     if (h->sps.bitstream_restriction_flag &&
-        s->avctx->has_b_frames < h->sps.num_reorder_frames) {
-        s->avctx->has_b_frames = h->sps.num_reorder_frames;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames < h->sps.num_reorder_frames) {
+        h->avctx->has_b_frames = h->sps.num_reorder_frames;
+        h->low_delay           = 0;
     }
 
+    avctx->internal->allocate_progress = 1;
+
     return 0;
 }
 
 #define IN_RANGE(a, b, size) (((a) >= (b)) && ((a) < ((b) + (size))))
+#undef REBASE_PICTURE
+#define REBASE_PICTURE(pic, new_ctx, old_ctx)             \
+    ((pic && pic >= old_ctx->DPB &&                       \
+      pic < old_ctx->DPB + MAX_PICTURE_COUNT) ?           \
+     &new_ctx->DPB[pic - old_ctx->DPB] : NULL)
 
 static void copy_picture_range(Picture **to, Picture **from, int count,
-                               MpegEncContext *new_base,
-                               MpegEncContext *old_base)
+                               H264Context *new_base,
+                               H264Context *old_base)
 {
     int i;
 
     for (i = 0; i < count; i++) {
         assert((IN_RANGE(from[i], old_base, sizeof(*old_base)) ||
-                IN_RANGE(from[i], old_base->picture,
-                         sizeof(Picture) * old_base->picture_count) ||
+                IN_RANGE(from[i], old_base->DPB,
+                         sizeof(Picture) * MAX_PICTURE_COUNT) ||
                 !from[i]));
         to[i] = REBASE_PICTURE(from[i], new_base, old_base);
     }
 }
 
-static void copy_parameter_set(void **to, void **from, int count, int size)
+static int copy_parameter_set(void **to, void **from, int count, int size)
 {
     int i;
 
     for (i = 0; i < count; i++) {
-        if (to[i] && !from[i])
+        if (to[i] && !from[i]) {
             av_freep(&to[i]);
-        else if (from[i] && !to[i])
+        } else if (from[i] && !to[i]) {
             to[i] = av_malloc(size);
+            if (!to[i])
+                return AVERROR(ENOMEM);
+        }
 
         if (from[i])
             memcpy(to[i], from[i], size);
     }
+
+    return 0;
 }
 
 static int decode_init_thread_copy(AVCodecContext *avctx)
@@ -1128,7 +1640,7 @@ static int decode_init_thread_copy(AVCodecContext *avctx)
     memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
     memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
 
-    h->s.context_initialized = 0;
+    h->context_initialized = 0;
 
     return 0;
 }
@@ -1145,49 +1657,52 @@ static int decode_update_thread_context(AVCodecContext *dst,
                                         const AVCodecContext *src)
 {
     H264Context *h = dst->priv_data, *h1 = src->priv_data;
-    MpegEncContext *const s = &h->s, *const s1 = &h1->s;
-    int inited = s->context_initialized, err;
-    int i;
+    int inited = h->context_initialized, err = 0;
+    int context_reinitialized = 0;
+    int i, ret;
 
-    if (dst == src || !s1->context_initialized)
+    if (dst == src || !h1->context_initialized)
         return 0;
 
     if (inited &&
-        (s->width      != s1->width      ||
-         s->height     != s1->height     ||
-         s->mb_width   != s1->mb_width   ||
-         s->mb_height  != s1->mb_height  ||
+        (h->width                 != h1->width                 ||
+         h->height                != h1->height                ||
+         h->mb_width              != h1->mb_width              ||
+         h->mb_height             != h1->mb_height             ||
          h->sps.bit_depth_luma    != h1->sps.bit_depth_luma    ||
          h->sps.chroma_format_idc != h1->sps.chroma_format_idc ||
          h->sps.colorspace        != h1->sps.colorspace)) {
 
+        /* set bits_per_raw_sample to the previous value. the check for changed
+         * bit depth in h264_set_parameter_from_sps() uses it and sets it to
+         * the current value */
+        h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
+
         av_freep(&h->bipred_scratchpad);
 
-        s->width     = s1->width;
-        s->height    = s1->height;
-        s->mb_height = s1->mb_height;
+        h->width     = h1->width;
+        h->height    = h1->height;
+        h->mb_height = h1->mb_height;
+        h->mb_width  = h1->mb_width;
+        h->mb_num    = h1->mb_num;
+        h->mb_stride = h1->mb_stride;
         h->b_stride  = h1->b_stride;
 
         if ((err = h264_slice_header_init(h, 1)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");
+            av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");
             return err;
         }
-        h->context_reinitialized = 1;
+        context_reinitialized = 1;
 
-        /* update linesize on resize for h264. The h264 decoder doesn't
-         * necessarily call ff_MPV_frame_start in the new thread */
-        s->linesize   = s1->linesize;
-        s->uvlinesize = s1->uvlinesize;
+        /* update linesize on resize. The decoder doesn't
+         * necessarily call h264_frame_start in the new thread */
+        h->linesize   = h1->linesize;
+        h->uvlinesize = h1->uvlinesize;
 
         /* copy block_offset since frame_start may not be called */
         memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
-        h264_set_parameter_from_sps(h);
     }
 
-    err = ff_mpeg_update_thread_context(dst, src);
-    if (err)
-        return err;
-
     if (!inited) {
         for (i = 0; i < MAX_SPS_COUNT; i++)
             av_freep(h->sps_buffers + i);
@@ -1195,43 +1710,97 @@ static int decode_update_thread_context(AVCodecContext *dst,
         for (i = 0; i < MAX_PPS_COUNT; i++)
             av_freep(h->pps_buffers + i);
 
-        // copy all fields after MpegEnc
-        memcpy(&h->s + 1, &h1->s + 1,
-               sizeof(H264Context) - sizeof(MpegEncContext));
+        memcpy(h, h1, sizeof(*h1));
         memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
         memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
-        if (ff_h264_alloc_tables(h) < 0) {
+        memset(&h->er, 0, sizeof(h->er));
+        memset(&h->me, 0, sizeof(h->me));
+        memset(&h->mb, 0, sizeof(h->mb));
+        memset(&h->mb_luma_dc, 0, sizeof(h->mb_luma_dc));
+        memset(&h->mb_padding, 0, sizeof(h->mb_padding));
+        h->context_initialized = 0;
+
+        memset(&h->cur_pic, 0, sizeof(h->cur_pic));
+        av_frame_unref(&h->cur_pic.f);
+        h->cur_pic.tf.f = &h->cur_pic.f;
+
+        h->avctx             = dst;
+        h->DPB               = NULL;
+        h->qscale_table_pool = NULL;
+        h->mb_type_pool      = NULL;
+        h->ref_index_pool    = NULL;
+        h->motion_val_pool   = NULL;
+
+        ret = ff_h264_alloc_tables(h);
+        if (ret < 0) {
             av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");
-            return AVERROR(ENOMEM);
+            return ret;
+        }
+        ret = context_init(h);
+        if (ret < 0) {
+            av_log(dst, AV_LOG_ERROR, "context_init() failed.\n");
+            return ret;
         }
-        context_init(h);
 
         for (i = 0; i < 2; i++) {
             h->rbsp_buffer[i]      = NULL;
             h->rbsp_buffer_size[i] = 0;
         }
         h->bipred_scratchpad = NULL;
+        h->edge_emu_buffer   = NULL;
 
         h->thread_context[0] = h;
 
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << h->pixel_shift));
+        h->context_initialized = 1;
+    }
+
+    h->avctx->coded_height  = h1->avctx->coded_height;
+    h->avctx->coded_width   = h1->avctx->coded_width;
+    h->avctx->width         = h1->avctx->width;
+    h->avctx->height        = h1->avctx->height;
+    h->coded_picture_number = h1->coded_picture_number;
+    h->first_field          = h1->first_field;
+    h->picture_structure    = h1->picture_structure;
+    h->qscale               = h1->qscale;
+    h->droppable            = h1->droppable;
+    h->data_partitioning    = h1->data_partitioning;
+    h->low_delay            = h1->low_delay;
+
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        unref_picture(h, &h->DPB[i]);
+        if (h1->DPB[i].f.buf[0] &&
+            (ret = ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0)
+            return ret;
     }
 
+    h->cur_pic_ptr = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);
+    unref_picture(h, &h->cur_pic);
+    if ((ret = ref_picture(h, &h->cur_pic, &h1->cur_pic)) < 0)
+        return ret;
+
+    h->workaround_bugs = h1->workaround_bugs;
+    h->low_delay       = h1->low_delay;
+    h->droppable       = h1->droppable;
+
     /* frame_start may not be called for the next thread (if it's decoding
      * a bottom field) so this has to be allocated here */
-    if (!h->bipred_scratchpad)
-        h->bipred_scratchpad = av_malloc(16 * 6 * s->linesize);
+    err = alloc_scratch_buffers(h, h1->linesize);
+    if (err < 0)
+        return err;
 
     // extradata/NAL handling
     h->is_avc = h1->is_avc;
 
     // SPS/PPS
-    copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers,
-                       MAX_SPS_COUNT, sizeof(SPS));
+    if ((ret = copy_parameter_set((void **)h->sps_buffers,
+                                  (void **)h1->sps_buffers,
+                                  MAX_SPS_COUNT, sizeof(SPS))) < 0)
+        return ret;
     h->sps = h1->sps;
-    copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers,
-                       MAX_PPS_COUNT, sizeof(PPS));
+    if ((ret = copy_parameter_set((void **)h->pps_buffers,
+                                  (void **)h1->pps_buffers,
+                                  MAX_PPS_COUNT, sizeof(PPS))) < 0)
+        return ret;
     h->pps = h1->pps;
 
     // Dequantization matrices
@@ -1252,21 +1821,22 @@ static int decode_update_thread_context(AVCodecContext *dst,
     copy_fields(h, h1, poc_lsb, redundant_pic_count);
 
     // reference lists
-    copy_fields(h, h1, ref_count, list_count);
-    copy_fields(h, h1, ref_list, intra_gb);
     copy_fields(h, h1, short_ref, cabac_init_idc);
 
-    copy_picture_range(h->short_ref, h1->short_ref, 32, s, s1);
-    copy_picture_range(h->long_ref, h1->long_ref, 32, s, s1);
+    copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1);
+    copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1);
     copy_picture_range(h->delayed_pic, h1->delayed_pic,
-                       MAX_DELAYED_PIC_COUNT + 2, s, s1);
+                       MAX_DELAYED_PIC_COUNT + 2, h, h1);
 
     h->last_slice_type = h1->last_slice_type;
 
-    if (!s->current_picture_ptr)
+    if (context_reinitialized)
+        h264_set_parameter_from_sps(h);
+
+    if (!h->cur_pic_ptr)
         return 0;
 
-    if (!s->droppable) {
+    if (!h->droppable) {
         err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
         h->prev_poc_msb = h->poc_msb;
         h->prev_poc_lsb = h->poc_lsb;
@@ -1275,50 +1845,77 @@ static int decode_update_thread_context(AVCodecContext *dst,
     h->prev_frame_num        = h->frame_num;
     h->outputed_poc          = h->next_outputed_poc;
 
+    h->recovery_frame        = h1->recovery_frame;
+    h->frame_recovered       = h1->frame_recovered;
+
     return err;
 }
 
-int ff_h264_frame_start(H264Context *h)
+static int h264_frame_start(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    int i;
+    Picture *pic;
+    int i, ret;
     const int pixel_shift = h->pixel_shift;
 
-    if (ff_MPV_frame_start(s, s->avctx) < 0)
-        return -1;
-    ff_er_frame_start(s);
+    release_unused_pictures(h, 1);
+    h->cur_pic_ptr = NULL;
+
+    i = find_unused_picture(h);
+    if (i < 0) {
+        av_log(h->avctx, AV_LOG_ERROR, "no frame buffer available\n");
+        return i;
+    }
+    pic = &h->DPB[i];
+
+    pic->reference              = h->droppable ? 0 : h->picture_structure;
+    pic->f.coded_picture_number = h->coded_picture_number++;
+    pic->field_picture          = h->picture_structure != PICT_FRAME;
     /*
-     * ff_MPV_frame_start uses pict_type to derive key_frame.
-     * This is incorrect for H.264; IDR markings must be used.
-     * Zero here; IDR markings per slice in frame or fields are ORed in later.
+     * Zero key_frame here; IDR markings per slice in frame or fields are ORed
+     * in later.
      * See decode_nal_units().
      */
-    s->current_picture_ptr->f.key_frame = 0;
-    s->current_picture_ptr->mmco_reset  = 0;
+    pic->f.key_frame = 0;
+    pic->mmco_reset  = 0;
+    pic->recovered   = 0;
+
+    if ((ret = alloc_picture(h, pic)) < 0)
+        return ret;
+
+    h->cur_pic_ptr = pic;
+    unref_picture(h, &h->cur_pic);
+    if ((ret = ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0)
+        return ret;
+
+    if (CONFIG_ERROR_RESILIENCE)
+        ff_er_frame_start(&h->er);
 
-    assert(s->linesize && s->uvlinesize);
+    assert(h->linesize && h->uvlinesize);
 
     for (i = 0; i < 16; i++) {
-        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * s->linesize * ((scan8[i] - scan8[0]) >> 3);
-        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * s->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
     }
     for (i = 0; i < 16; i++) {
         h->block_offset[16 + i]      =
-        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * s->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
         h->block_offset[48 + 16 + i] =
-        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * s->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
     }
 
     /* can't be in alloc_tables because linesize isn't known there.
      * FIXME: redo bipred weight to not require extra buffer? */
-    for (i = 0; i < s->slice_context_count; i++)
-        if (h->thread_context[i] && !h->thread_context[i]->bipred_scratchpad)
-            h->thread_context[i]->bipred_scratchpad = av_malloc(16 * 6 * s->linesize);
+    for (i = 0; i < h->slice_context_count; i++)
+        if (h->thread_context[i]) {
+            ret = alloc_scratch_buffers(h->thread_context[i], h->linesize);
+            if (ret < 0)
+                return ret;
+        }
 
     /* Some macroblocks can be accessed before they're available in case
      * of lost slices, MBAFF or threading. */
     memset(h->slice_table, -1,
-           (s->mb_height * s->mb_stride - 1) * sizeof(*h->slice_table));
+           (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
 
     // s->decode = (s->flags & CODEC_FLAG_PSNR) || !s->encoding ||
     //             s->current_picture.f.reference /* || h->contains_intra */ || 1;
@@ -1326,18 +1923,14 @@ int ff_h264_frame_start(H264Context *h)
     /* We mark the current picture as non-reference after allocating it, so
      * that if we break out due to an error it can be released automatically
      * in the next ff_MPV_frame_start().
-     * SVQ3 as well as most other codecs have only last/next/current and thus
-     * get released even with set reference, besides SVQ3 and others do not
-     * mark frames as reference later "naturally". */
-    if (s->codec_id != AV_CODEC_ID_SVQ3)
-        s->current_picture_ptr->f.reference = 0;
+     */
+    h->cur_pic_ptr->reference = 0;
 
-    s->current_picture_ptr->field_poc[0]     =
-        s->current_picture_ptr->field_poc[1] = INT_MAX;
+    h->cur_pic_ptr->field_poc[0] = h->cur_pic_ptr->field_poc[1] = INT_MAX;
 
     h->next_output_pic = NULL;
 
-    assert(s->current_picture_ptr->long_ref == 0);
+    assert(h->cur_pic_ptr->long_ref == 0);
 
     return 0;
 }
@@ -1352,14 +1945,12 @@ int ff_h264_frame_start(H264Context *h)
  */
 static void decode_postinit(H264Context *h, int setup_finished)
 {
-    MpegEncContext *const s = &h->s;
-    Picture *out = s->current_picture_ptr;
-    Picture *cur = s->current_picture_ptr;
+    Picture *out = h->cur_pic_ptr;
+    Picture *cur = h->cur_pic_ptr;
     int i, pics, out_of_order, out_idx;
     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;
+    h->cur_pic_ptr->f.pict_type = h->pict_type;
 
     if (h->next_output_pic)
         return;
@@ -1370,7 +1961,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
          * The check in decode_nal_units() is not good enough to find this
          * yet, so we assume the worst for now. */
         // if (setup_finished)
-        //    ff_thread_finish_setup(s->avctx);
+        //    ff_thread_finish_setup(h->avctx);
         return;
     }
 
@@ -1391,7 +1982,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
             break;
         case SEI_PIC_STRUCT_TOP_BOTTOM:
         case SEI_PIC_STRUCT_BOTTOM_TOP:
-            if (FIELD_OR_MBAFF_PICTURE)
+            if (FIELD_OR_MBAFF_PICTURE(h))
                 cur->f.interlaced_frame = 1;
             else
                 // try to flag soft telecine progressive
@@ -1405,7 +1996,6 @@ static void decode_postinit(H264Context *h, int setup_finished)
             cur->f.repeat_pict = 1;
             break;
         case SEI_PIC_STRUCT_FRAME_DOUBLING:
-            // Force progressive here, doubling interlaced frame is a bad idea.
             cur->f.repeat_pict = 2;
             break;
         case SEI_PIC_STRUCT_FRAME_TRIPLING:
@@ -1418,7 +2008,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
             cur->f.interlaced_frame = (h->sei_ct_type & (1 << 1)) != 0;
     } else {
         /* Derive interlacing flag from used decoding process. */
-        cur->f.interlaced_frame = FIELD_OR_MBAFF_PICTURE;
+        cur->f.interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);
     }
     h->prev_interlaced_frame = cur->f.interlaced_frame;
 
@@ -1440,20 +2030,60 @@ static void decode_postinit(H264Context *h, int setup_finished)
         }
     }
 
+    if (h->sei_frame_packing_present &&
+        h->frame_packing_arrangement_type >= 0 &&
+        h->frame_packing_arrangement_type <= 6 &&
+        h->content_interpretation_type > 0 &&
+        h->content_interpretation_type < 3) {
+        AVStereo3D *stereo = av_stereo3d_create_side_data(&cur->f);
+        if (!stereo)
+            return;
+
+        switch (h->frame_packing_arrangement_type) {
+        case 0:
+            stereo->type = AV_STEREO3D_CHECKERBOARD;
+            break;
+        case 1:
+            stereo->type = AV_STEREO3D_LINES;
+            break;
+        case 2:
+            stereo->type = AV_STEREO3D_COLUMNS;
+            break;
+        case 3:
+            if (h->quincunx_subsampling)
+                stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+            else
+                stereo->type = AV_STEREO3D_SIDEBYSIDE;
+            break;
+        case 4:
+            stereo->type = AV_STEREO3D_TOPBOTTOM;
+            break;
+        case 5:
+            stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+            break;
+        case 6:
+            stereo->type = AV_STEREO3D_2D;
+            break;
+        }
+
+        if (h->content_interpretation_type == 2)
+            stereo->flags = AV_STEREO3D_FLAG_INVERT;
+    }
+
     // FIXME do something with unavailable reference frames
 
     /* Sort B-frames into display order */
 
     if (h->sps.bitstream_restriction_flag &&
-        s->avctx->has_b_frames < h->sps.num_reorder_frames) {
-        s->avctx->has_b_frames = h->sps.num_reorder_frames;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames < h->sps.num_reorder_frames) {
+        h->avctx->has_b_frames = h->sps.num_reorder_frames;
+        h->low_delay           = 0;
     }
 
-    if (s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
+    if (h->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT &&
         !h->sps.bitstream_restriction_flag) {
-        s->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
-        s->low_delay           = 0;
+        h->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
+        h->low_delay           = 0;
     }
 
     pics = 0;
@@ -1463,8 +2093,8 @@ static void decode_postinit(H264Context *h, int setup_finished)
     assert(pics <= MAX_DELAYED_PIC_COUNT);
 
     h->delayed_pic[pics++] = cur;
-    if (cur->f.reference == 0)
-        cur->f.reference = DELAYED_PIC_REF;
+    if (cur->reference == 0)
+        cur->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
@@ -1474,7 +2104,7 @@ static void decode_postinit(H264Context *h, int setup_finished)
      * 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),
+     * FIXME: if we detect insufficient delays (as per h->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
@@ -1506,40 +2136,39 @@ static void decode_postinit(H264Context *h, int setup_finished)
             out     = h->delayed_pic[i];
             out_idx = i;
         }
-    if (s->avctx->has_b_frames == 0 &&
+    if (h->avctx->has_b_frames == 0 &&
         (h->delayed_pic[0]->f.key_frame || h->mmco_reset))
         h->next_outputed_poc = INT_MIN;
     out_of_order = !out->f.key_frame && !h->mmco_reset &&
                    (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) {
+        h->avctx->has_b_frames >= h->sps.num_reorder_frames) {
+    } else if (out_of_order && pics - 1 == h->avctx->has_b_frames &&
+               h->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);
+            h->avctx->has_b_frames = FFMAX(h->avctx->has_b_frames, cnt);
         }
-        s->low_delay = 0;
-    } else if (s->low_delay &&
+        h->low_delay = 0;
+    } else if (h->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++;
+        h->low_delay = 0;
+        h->avctx->has_b_frames++;
     }
 
-    if (pics > s->avctx->has_b_frames) {
-        out->f.reference &= ~DELAYED_PIC_REF;
+    if (pics > h->avctx->has_b_frames) {
+        out->reference &= ~DELAYED_PIC_REF;
         // for frame threading, the owner must be the second field's thread or
         // else the first thread can release the picture and reuse it unsafely
-        out->owner2       = s;
         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) {
+    if (!out_of_order && pics > h->avctx->has_b_frames) {
         h->next_output_pic = out;
         if (out->mmco_reset) {
             if (out_idx > 0) {
@@ -1557,11 +2186,20 @@ static void decode_postinit(H264Context *h, int setup_finished)
         }
         h->mmco_reset = 0;
     } else {
-        av_log(s->avctx, AV_LOG_DEBUG, "no picture\n");
+        av_log(h->avctx, AV_LOG_DEBUG, "no picture\n");
     }
 
-    if (setup_finished)
-        ff_thread_finish_setup(s->avctx);
+    if (h->next_output_pic) {
+        if (h->next_output_pic->recovered) {
+            // We have reached an recovery point and all frames after it in
+            // display order are "recovered".
+            h->frame_recovered |= FRAME_RECOVERED_SEI;
+        }
+        h->next_output_pic->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_SEI);
+    }
+
+    if (setup_finished && !h->avctx->hwaccel)
+        ff_thread_finish_setup(h->avctx);
 }
 
 static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
@@ -1569,25 +2207,24 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
                                               int linesize, int uvlinesize,
                                               int simple)
 {
-    MpegEncContext *const s = &h->s;
     uint8_t *top_border;
     int top_idx = 1;
     const int pixel_shift = h->pixel_shift;
-    int chroma444 = CHROMA444;
-    int chroma422 = CHROMA422;
+    int chroma444 = CHROMA444(h);
+    int chroma422 = CHROMA422(h);
 
     src_y  -= linesize;
     src_cb -= uvlinesize;
     src_cr -= uvlinesize;
 
-    if (!simple && FRAME_MBAFF) {
-        if (s->mb_y & 1) {
-            if (!MB_MBAFF) {
-                top_border = h->top_borders[0][s->mb_x];
+    if (!simple && FRAME_MBAFF(h)) {
+        if (h->mb_y & 1) {
+            if (!MB_MBAFF(h)) {
+                top_border = h->top_borders[0][h->mb_x];
                 AV_COPY128(top_border, src_y + 15 * linesize);
                 if (pixel_shift)
                     AV_COPY128(top_border + 16, src_y + 15 * linesize + 16);
-                if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+                if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                     if (chroma444) {
                         if (pixel_shift) {
                             AV_COPY128(top_border + 32, src_cb + 15 * uvlinesize);
@@ -1617,20 +2254,20 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
                     }
                 }
             }
-        } else if (MB_MBAFF) {
+        } else if (MB_MBAFF(h)) {
             top_idx = 0;
         } else
             return;
     }
 
-    top_border = h->top_borders[top_idx][s->mb_x];
+    top_border = h->top_borders[top_idx][h->mb_x];
     /* There are two lines saved, the line above the top macroblock
      * of a pair, and the line above the bottom macroblock. */
     AV_COPY128(top_border, src_y + 16 * linesize);
     if (pixel_shift)
         AV_COPY128(top_border + 16, src_y + 16 * linesize + 16);
 
-    if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+    if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
         if (chroma444) {
             if (pixel_shift) {
                 AV_COPY128(top_border + 32, src_cb + 16 * linesize);
@@ -1667,36 +2304,35 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
                                             int xchg, int chroma444,
                                             int simple, int pixel_shift)
 {
-    MpegEncContext *const s = &h->s;
     int deblock_topleft;
     int deblock_top;
     int top_idx = 1;
     uint8_t *top_border_m1;
     uint8_t *top_border;
 
-    if (!simple && FRAME_MBAFF) {
-        if (s->mb_y & 1) {
-            if (!MB_MBAFF)
+    if (!simple && FRAME_MBAFF(h)) {
+        if (h->mb_y & 1) {
+            if (!MB_MBAFF(h))
                 return;
         } else {
-            top_idx = MB_MBAFF ? 0 : 1;
+            top_idx = MB_MBAFF(h) ? 0 : 1;
         }
     }
 
     if (h->deblocking_filter == 2) {
-        deblock_topleft = h->slice_table[h->mb_xy - 1 - s->mb_stride] == h->slice_num;
+        deblock_topleft = h->slice_table[h->mb_xy - 1 - h->mb_stride] == h->slice_num;
         deblock_top     = h->top_type;
     } else {
-        deblock_topleft = (s->mb_x > 0);
-        deblock_top     = (s->mb_y > !!MB_FIELD);
+        deblock_topleft = (h->mb_x > 0);
+        deblock_top     = (h->mb_y > !!MB_FIELD(h));
     }
 
     src_y  -= linesize   + 1 + pixel_shift;
     src_cb -= uvlinesize + 1 + pixel_shift;
     src_cr -= uvlinesize + 1 + pixel_shift;
 
-    top_border_m1 = h->top_borders[top_idx][s->mb_x - 1];
-    top_border    = h->top_borders[top_idx][s->mb_x];
+    top_border_m1 = h->top_borders[top_idx][h->mb_x - 1];
+    top_border    = h->top_borders[top_idx][h->mb_x];
 
 #define XCHG(a, b, xchg)                        \
     if (pixel_shift) {                          \
@@ -1718,12 +2354,12 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
         }
         XCHG(top_border + (0 << pixel_shift), src_y + (1 << pixel_shift), xchg);
         XCHG(top_border + (8 << pixel_shift), src_y + (9 << pixel_shift), 1);
-        if (s->mb_x + 1 < s->mb_width) {
-            XCHG(h->top_borders[top_idx][s->mb_x + 1],
+        if (h->mb_x + 1 < h->mb_width) {
+            XCHG(h->top_borders[top_idx][h->mb_x + 1],
                  src_y + (17 << pixel_shift), 1);
         }
     }
-    if (simple || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+    if (simple || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
         if (chroma444) {
             if (deblock_topleft) {
                 XCHG(top_border_m1 + (24 << pixel_shift), src_cb - (7 << pixel_shift), 1);
@@ -1733,9 +2369,9 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
             XCHG(top_border + (24 << pixel_shift), src_cb + (9 << pixel_shift), 1);
             XCHG(top_border + (32 << pixel_shift), src_cr + (1 << pixel_shift), xchg);
             XCHG(top_border + (40 << pixel_shift), src_cr + (9 << pixel_shift), 1);
-            if (s->mb_x + 1 < s->mb_width) {
-                XCHG(h->top_borders[top_idx][s->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
-                XCHG(h->top_borders[top_idx][s->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
+            if (h->mb_x + 1 < h->mb_width) {
+                XCHG(h->top_borders[top_idx][h->mb_x + 1] + (16 << pixel_shift), src_cb + (17 << pixel_shift), 1);
+                XCHG(h->top_borders[top_idx][h->mb_x + 1] + (32 << pixel_shift), src_cr + (17 << pixel_shift), 1);
             }
         } else {
             if (deblock_top) {
@@ -1750,7 +2386,7 @@ static av_always_inline void xchg_mb_border(H264Context *h, uint8_t *src_y,
     }
 }
 
-static av_always_inline int dctcoef_get(DCTELEM *mb, int high_bit_depth,
+static av_always_inline int dctcoef_get(int16_t *mb, int high_bit_depth,
                                         int index)
 {
     if (high_bit_depth) {
@@ -1759,7 +2395,7 @@ static av_always_inline int dctcoef_get(DCTELEM *mb, int high_bit_depth,
         return AV_RN16A(mb + index);
 }
 
-static av_always_inline void dctcoef_set(DCTELEM *mb, int high_bit_depth,
+static av_always_inline void dctcoef_set(int16_t *mb, int high_bit_depth,
                                          int index, int value)
 {
     if (high_bit_depth) {
@@ -1777,84 +2413,81 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
                                                        int linesize,
                                                        uint8_t *dest_y, int p)
 {
-    MpegEncContext *const s = &h->s;
-    void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
-    void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride);
+    void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
+    void (*idct_dc_add)(uint8_t *dst, int16_t *block, int stride);
     int i;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p - 1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p - 1];
     block_offset += 16 * p;
     if (IS_INTRA4x4(mb_type)) {
-        if (simple || !s->encoding) {
-            if (IS_8x8DCT(mb_type)) {
-                if (transform_bypass) {
-                    idct_dc_add  =
-                    idct_add     = s->dsp.add_pixels8;
+        if (IS_8x8DCT(mb_type)) {
+            if (transform_bypass) {
+                idct_dc_add =
+                idct_add    = h->h264dsp.h264_add_pixels8_clear;
+            } else {
+                idct_dc_add = h->h264dsp.h264_idct8_dc_add;
+                idct_add    = h->h264dsp.h264_idct8_add;
+            }
+            for (i = 0; i < 16; i += 4) {
+                uint8_t *const ptr = dest_y + block_offset[i];
+                const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
+                if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
+                    h->hpc.pred8x8l_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
                 } else {
-                    idct_dc_add = h->h264dsp.h264_idct8_dc_add;
-                    idct_add    = h->h264dsp.h264_idct8_add;
-                }
-                for (i = 0; i < 16; i += 4) {
-                    uint8_t *const ptr = dest_y + block_offset[i];
-                    const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
-                    if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
-                        h->hpc.pred8x8l_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                    } else {
-                        const int nnz = h->non_zero_count_cache[scan8[i + p * 16]];
-                        h->hpc.pred8x8l[dir](ptr, (h->topleft_samples_available << i) & 0x8000,
-                                             (h->topright_samples_available << i) & 0x4000, linesize);
-                        if (nnz) {
-                            if (nnz == 1 && dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
-                                idct_dc_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                            else
-                                idct_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                        }
+                    const int nnz = h->non_zero_count_cache[scan8[i + p * 16]];
+                    h->hpc.pred8x8l[dir](ptr, (h->topleft_samples_available << i) & 0x8000,
+                                         (h->topright_samples_available << i) & 0x4000, linesize);
+                    if (nnz) {
+                        if (nnz == 1 && dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
+                            idct_dc_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
+                        else
+                            idct_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
                     }
                 }
+            }
+        } else {
+            if (transform_bypass) {
+                idct_dc_add  =
+                idct_add     = h->h264dsp.h264_add_pixels4_clear;
             } else {
-                if (transform_bypass) {
-                    idct_dc_add  =
-                        idct_add = s->dsp.add_pixels4;
-                } else {
-                    idct_dc_add = h->h264dsp.h264_idct_dc_add;
-                    idct_add    = h->h264dsp.h264_idct_add;
-                }
-                for (i = 0; i < 16; i++) {
-                    uint8_t *const ptr = dest_y + block_offset[i];
-                    const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
+                idct_dc_add = h->h264dsp.h264_idct_dc_add;
+                idct_add    = h->h264dsp.h264_idct_add;
+            }
+            for (i = 0; i < 16; i++) {
+                uint8_t *const ptr = dest_y + block_offset[i];
+                const int dir      = h->intra4x4_pred_mode_cache[scan8[i]];
 
-                    if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
-                        h->hpc.pred4x4_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                    } else {
-                        uint8_t *topright;
-                        int nnz, tr;
-                        uint64_t tr_high;
-                        if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) {
-                            const int topright_avail = (h->topright_samples_available << i) & 0x8000;
-                            assert(s->mb_y || linesize <= block_offset[i]);
-                            if (!topright_avail) {
-                                if (pixel_shift) {
-                                    tr_high  = ((uint16_t *)ptr)[3 - linesize / 2] * 0x0001000100010001ULL;
-                                    topright = (uint8_t *)&tr_high;
-                                } else {
-                                    tr       = ptr[3 - linesize] * 0x01010101u;
-                                    topright = (uint8_t *)&tr;
-                                }
-                            } else
-                                topright = ptr + (4 << pixel_shift) - linesize;
+                if (transform_bypass && h->sps.profile_idc == 244 && dir <= 1) {
+                    h->hpc.pred4x4_add[dir](ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
+                } else {
+                    uint8_t *topright;
+                    int nnz, tr;
+                    uint64_t tr_high;
+                    if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) {
+                        const int topright_avail = (h->topright_samples_available << i) & 0x8000;
+                        assert(h->mb_y || linesize <= block_offset[i]);
+                        if (!topright_avail) {
+                            if (pixel_shift) {
+                                tr_high  = ((uint16_t *)ptr)[3 - linesize / 2] * 0x0001000100010001ULL;
+                                topright = (uint8_t *)&tr_high;
+                            } else {
+                                tr       = ptr[3 - linesize] * 0x01010101u;
+                                topright = (uint8_t *)&tr;
+                            }
                         } else
-                            topright = NULL;
-
-                        h->hpc.pred4x4[dir](ptr, topright, linesize);
-                        nnz = h->non_zero_count_cache[scan8[i + p * 16]];
-                        if (nnz) {
-                            if (is_h264) {
-                                if (nnz == 1 && dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
-                                    idct_dc_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                                else
-                                    idct_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
-                            } else if (CONFIG_SVQ3_DECODER)
-                                ff_svq3_add_idct_c(ptr, h->mb + i * 16 + p * 256, linesize, qscale, 0);
-                        }
+                            topright = ptr + (4 << pixel_shift) - linesize;
+                    } else
+                        topright = NULL;
+
+                    h->hpc.pred4x4[dir](ptr, topright, linesize);
+                    nnz = h->non_zero_count_cache[scan8[i + p * 16]];
+                    if (nnz) {
+                        if (is_h264) {
+                            if (nnz == 1 && dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
+                                idct_dc_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
+                            else
+                                idct_add(ptr, h->mb + (i * 16 + p * 256 << pixel_shift), linesize);
+                        } else if (CONFIG_SVQ3_DECODER)
+                            ff_svq3_add_idct_c(ptr, h->mb + i * 16 + p * 256, linesize, qscale, 0);
                     }
                 }
             }
@@ -1872,7 +2505,8 @@ static av_always_inline void hl_decode_mb_predict_luma(H264Context *h,
                          0 * 16,  1 * 16,  4 * 16,  5 * 16,
                          2 * 16,  3 * 16,  6 * 16,  7 * 16,
                          8 * 16,  9 * 16, 12 * 16, 13 * 16,
-                        10 * 16, 11 * 16, 14 * 16, 15 * 16 };
+                        10 * 16, 11 * 16, 14 * 16, 15 * 16
+                    };
                     for (i = 0; i < 16; i++)
                         dctcoef_set(h->mb + (p * 256 << pixel_shift),
                                     pixel_shift, dc_mapping[i],
@@ -1894,8 +2528,7 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
                                                     int linesize,
                                                     uint8_t *dest_y, int p)
 {
-    MpegEncContext *const s = &h->s;
-    void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
+    void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
     int i;
     block_offset += 16 * p;
     if (!IS_INTRA4x4(mb_type)) {
@@ -1912,9 +2545,9 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
                         for (i = 0; i < 16; i++)
                             if (h->non_zero_count_cache[scan8[i + p * 16]] ||
                                 dctcoef_get(h->mb, pixel_shift, i * 16 + p * 256))
-                                s->dsp.add_pixels4(dest_y + block_offset[i],
-                                                   h->mb + (i * 16 + p * 256 << pixel_shift),
-                                                   linesize);
+                                h->h264dsp.h264_add_pixels4_clear(dest_y + block_offset[i],
+                                                                  h->mb + (i * 16 + p * 256 << pixel_shift),
+                                                                  linesize);
                     }
                 } else {
                     h->h264dsp.h264_idct_add16intra(dest_y, block_offset,
@@ -1925,8 +2558,8 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
             } else if (h->cbp & 15) {
                 if (transform_bypass) {
                     const int di = IS_8x8DCT(mb_type) ? 4 : 1;
-                    idct_add = IS_8x8DCT(mb_type) ? s->dsp.add_pixels8
-                                                  : s->dsp.add_pixels4;
+                    idct_add = IS_8x8DCT(mb_type) ? h->h264dsp.h264_add_pixels8_clear
+                                                  : h->h264dsp.h264_add_pixels4_clear;
                     for (i = 0; i < 16; i += di)
                         if (h->non_zero_count_cache[scan8[i + p * 16]])
                             idct_add(dest_y + block_offset[i],
@@ -1951,7 +2584,7 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
                     // FIXME benchmark weird rule, & below
                     uint8_t *const ptr = dest_y + block_offset[i];
                     ff_svq3_add_idct_c(ptr, h->mb + i * 16 + p * 256, linesize,
-                                       s->qscale, IS_INTRA(mb_type) ? 1 : 0);
+                                       h->qscale, IS_INTRA(mb_type) ? 1 : 0);
                 }
         }
     }
@@ -1971,12 +2604,12 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
 
 void ff_h264_hl_decode_mb(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
-    int is_complex    = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0;
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
+    int is_complex    = CONFIG_SMALL || h->is_complex ||
+                        IS_INTRA_PCM(mb_type) || h->qscale == 0;
 
-    if (CHROMA444) {
+    if (CHROMA444(h)) {
         if (is_complex || h->pixel_shift)
             hl_decode_mb_444_complex(h);
         else
@@ -1989,17 +2622,16 @@ void ff_h264_hl_decode_mb(H264Context *h)
         hl_decode_mb_simple_8(h);
 }
 
-static int pred_weight_table(H264Context *h)
+int ff_pred_weight_table(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     int list, i;
     int luma_def, chroma_def;
 
     h->use_weight             = 0;
     h->use_weight_chroma      = 0;
-    h->luma_log2_weight_denom = get_ue_golomb(&s->gb);
+    h->luma_log2_weight_denom = get_ue_golomb(&h->gb);
     if (h->sps.chroma_format_idc)
-        h->chroma_log2_weight_denom = get_ue_golomb(&s->gb);
+        h->chroma_log2_weight_denom = get_ue_golomb(&h->gb);
     luma_def   = 1 << h->luma_log2_weight_denom;
     chroma_def = 1 << h->chroma_log2_weight_denom;
 
@@ -2009,10 +2641,10 @@ static int pred_weight_table(H264Context *h)
         for (i = 0; i < h->ref_count[list]; i++) {
             int luma_weight_flag, chroma_weight_flag;
 
-            luma_weight_flag = get_bits1(&s->gb);
+            luma_weight_flag = get_bits1(&h->gb);
             if (luma_weight_flag) {
-                h->luma_weight[i][list][0] = get_se_golomb(&s->gb);
-                h->luma_weight[i][list][1] = get_se_golomb(&s->gb);
+                h->luma_weight[i][list][0] = get_se_golomb(&h->gb);
+                h->luma_weight[i][list][1] = get_se_golomb(&h->gb);
                 if (h->luma_weight[i][list][0] != luma_def ||
                     h->luma_weight[i][list][1] != 0) {
                     h->use_weight             = 1;
@@ -2024,15 +2656,15 @@ static int pred_weight_table(H264Context *h)
             }
 
             if (h->sps.chroma_format_idc) {
-                chroma_weight_flag = get_bits1(&s->gb);
+                chroma_weight_flag = get_bits1(&h->gb);
                 if (chroma_weight_flag) {
                     int j;
                     for (j = 0; j < 2; j++) {
-                        h->chroma_weight[i][list][j][0] = get_se_golomb(&s->gb);
-                        h->chroma_weight[i][list][j][1] = get_se_golomb(&s->gb);
+                        h->chroma_weight[i][list][j][0] = get_se_golomb(&h->gb);
+                        h->chroma_weight[i][list][j][1] = get_se_golomb(&h->gb);
                         if (h->chroma_weight[i][list][j][0] != chroma_def ||
                             h->chroma_weight[i][list][j][1] != 0) {
-                            h->use_weight_chroma = 1;
+                            h->use_weight_chroma        = 1;
                             h->chroma_weight_flag[list] = 1;
                         }
                     }
@@ -2059,7 +2691,6 @@ static int pred_weight_table(H264Context *h)
  */
 static void implicit_weight_table(H264Context *h, int field)
 {
-    MpegEncContext *const s = &h->s;
     int ref0, ref1, i, cur_poc, ref_start, ref_count0, ref_count1;
 
     for (i = 0; i < 2; i++) {
@@ -2068,14 +2699,14 @@ static void implicit_weight_table(H264Context *h, int field)
     }
 
     if (field < 0) {
-        if (s->picture_structure == PICT_FRAME) {
-            cur_poc = s->current_picture_ptr->poc;
+        if (h->picture_structure == PICT_FRAME) {
+            cur_poc = h->cur_pic_ptr->poc;
         } else {
-            cur_poc = s->current_picture_ptr->field_poc[s->picture_structure - 1];
+            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure - 1];
         }
-        if (h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF &&
+        if (h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF(h) &&
             h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2 * cur_poc) {
-            h->use_weight = 0;
+            h->use_weight        = 0;
             h->use_weight_chroma = 0;
             return;
         }
@@ -2083,7 +2714,7 @@ static void implicit_weight_table(H264Context *h, int field)
         ref_count0 = h->ref_count[0];
         ref_count1 = h->ref_count[1];
     } else {
-        cur_poc    = s->current_picture_ptr->field_poc[field];
+        cur_poc    = h->cur_pic_ptr->field_poc[field];
         ref_start  = 16;
         ref_count0 = 16 + 2 * h->ref_count[0];
         ref_count1 = 16 + 2 * h->ref_count[1];
@@ -2137,17 +2768,19 @@ static void flush_change(H264Context *h)
     int i;
     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->outputed_poc          = h->next_outputed_poc = INT_MIN;
     h->prev_interlaced_frame = 1;
     idr(h);
-    if (h->s.current_picture_ptr)
-        h->s.current_picture_ptr->f.reference = 0;
-    h->s.first_field = 0;
+    if (h->cur_pic_ptr)
+        h->cur_pic_ptr->reference = 0;
+    h->first_field = 0;
     memset(h->ref_list[0], 0, sizeof(h->ref_list[0]));
     memset(h->ref_list[1], 0, sizeof(h->ref_list[1]));
     memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));
     memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1]));
     ff_h264_reset_sei(h);
+    h->recovery_frame = -1;
+    h->frame_recovered = 0;
 }
 
 /* forget old pics after a seek */
@@ -2158,20 +2791,35 @@ static void flush_dpb(AVCodecContext *avctx)
 
     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]->reference = 0;
         h->delayed_pic[i] = NULL;
     }
 
     flush_change(h);
-    ff_mpeg_flush(avctx);
+
+    if (h->DPB)
+        for (i = 0; i < MAX_PICTURE_COUNT; i++)
+            unref_picture(h, &h->DPB[i]);
+    h->cur_pic_ptr = NULL;
+    unref_picture(h, &h->cur_pic);
+
+    h->mb_x = h->mb_y = 0;
+
+    h->parse_context.state             = -1;
+    h->parse_context.frame_start_found = 0;
+    h->parse_context.overread          = 0;
+    h->parse_context.overread_index    = 0;
+    h->parse_context.index             = 0;
+    h->parse_context.last_index        = 0;
+
+    free_tables(h, 1);
+    h->context_initialized = 0;
 }
 
-static int init_poc(H264Context *h)
+int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc)
 {
-    MpegEncContext *const s = &h->s;
     const int max_frame_num = 1 << h->sps.log2_max_frame_num;
     int field_poc[2];
-    Picture *cur = s->current_picture_ptr;
 
     h->frame_num_offset = h->prev_frame_num_offset;
     if (h->frame_num < h->prev_frame_num)
@@ -2180,15 +2828,17 @@ static int init_poc(H264Context *h)
     if (h->sps.poc_type == 0) {
         const int max_poc_lsb = 1 << h->sps.log2_max_poc_lsb;
 
-        if (h->poc_lsb < h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2)
+        if (h->poc_lsb < h->prev_poc_lsb &&
+            h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb / 2)
             h->poc_msb = h->prev_poc_msb + max_poc_lsb;
-        else if (h->poc_lsb > h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2)
+        else if (h->poc_lsb > h->prev_poc_lsb &&
+                 h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb / 2)
             h->poc_msb = h->prev_poc_msb - max_poc_lsb;
         else
             h->poc_msb = h->prev_poc_msb;
         field_poc[0] =
         field_poc[1] = h->poc_msb + h->poc_lsb;
-        if (s->picture_structure == PICT_FRAME)
+        if (h->picture_structure == PICT_FRAME)
             field_poc[1] += h->delta_poc_bottom;
     } else if (h->sps.poc_type == 1) {
         int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc;
@@ -2223,7 +2873,7 @@ static int init_poc(H264Context *h)
         field_poc[0] = expectedpoc + h->delta_poc[0];
         field_poc[1] = field_poc[0] + h->sps.offset_for_top_to_bottom_field;
 
-        if (s->picture_structure == PICT_FRAME)
+        if (h->picture_structure == PICT_FRAME)
             field_poc[1] += h->delta_poc[1];
     } else {
         int poc = 2 * (h->frame_num_offset + h->frame_num);
@@ -2235,11 +2885,11 @@ static int init_poc(H264Context *h)
         field_poc[1] = poc;
     }
 
-    if (s->picture_structure != PICT_BOTTOM_FIELD)
-        s->current_picture_ptr->field_poc[0] = field_poc[0];
-    if (s->picture_structure != PICT_TOP_FIELD)
-        s->current_picture_ptr->field_poc[1] = field_poc[1];
-    cur->poc = FFMIN(cur->field_poc[0], cur->field_poc[1]);
+    if (h->picture_structure != PICT_BOTTOM_FIELD)
+        pic_field_poc[0] = field_poc[0];
+    if (h->picture_structure != PICT_TOP_FIELD)
+        pic_field_poc[1] = field_poc[1];
+    *pic_poc = FFMIN(pic_field_poc[0], pic_field_poc[1]);
 
     return 0;
 }
@@ -2283,21 +2933,16 @@ static void init_scan_tables(H264Context *h)
 
 static int field_end(H264Context *h, int in_setup)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     int err = 0;
-    s->mb_y = 0;
+    h->mb_y = 0;
 
-    if (!in_setup && !s->droppable)
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                  s->picture_structure == PICT_BOTTOM_FIELD);
-
-    if (CONFIG_H264_VDPAU_DECODER &&
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_h264_set_reference_frames(s);
+    if (!in_setup && !h->droppable)
+        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
+                                  h->picture_structure == PICT_BOTTOM_FIELD);
 
     if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {
-        if (!s->droppable) {
+        if (!h->droppable) {
             err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
             h->prev_poc_msb = h->poc_msb;
             h->prev_poc_lsb = h->poc_lsb;
@@ -2313,10 +2958,6 @@ static int field_end(H264Context *h, int in_setup)
                    "hardware accelerator failed to decode picture\n");
     }
 
-    if (CONFIG_H264_VDPAU_DECODER &&
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_h264_picture_complete(s);
-
     /*
      * FIXME: Error handling code does not seem to support interlaced
      * when slices span multiple rows
@@ -2329,10 +2970,13 @@ static int field_end(H264Context *h, int in_setup)
      * past end by one (callers fault) and resync_mb_y != 0
      * causes problems for the first MB line, too.
      */
-    if (!FIELD_PICTURE)
-        ff_er_frame_end(s);
-
-    ff_MPV_frame_end(s);
+    if (CONFIG_ERROR_RESILIENCE && !FIELD_PICTURE(h)) {
+        h->er.cur_pic  = h->cur_pic_ptr;
+        h->er.last_pic = h->ref_count[0] ? &h->ref_list[0][0] : NULL;
+        h->er.next_pic = h->ref_count[1] ? &h->ref_list[1][0] : NULL;
+        ff_er_frame_end(&h->er);
+    }
+    emms_c();
 
     h->current_slice = 0;
 
@@ -2344,21 +2988,12 @@ static int field_end(H264Context *h, int in_setup)
  */
 static int clone_slice(H264Context *dst, H264Context *src)
 {
-    int ret;
-
     memcpy(dst->block_offset, src->block_offset, sizeof(dst->block_offset));
-    dst->s.current_picture_ptr = src->s.current_picture_ptr;
-    dst->s.current_picture     = src->s.current_picture;
-    dst->s.linesize            = src->s.linesize;
-    dst->s.uvlinesize          = src->s.uvlinesize;
-    dst->s.first_field         = src->s.first_field;
-
-    if (!dst->s.edge_emu_buffer &&
-        (ret = ff_mpv_frame_size_alloc(&dst->s, dst->s.linesize))) {
-        av_log(dst->s.avctx, AV_LOG_ERROR,
-               "Failed to allocate scratch buffers\n");
-        return ret;
-    }
+    dst->cur_pic_ptr = src->cur_pic_ptr;
+    dst->cur_pic     = src->cur_pic;
+    dst->linesize    = src->linesize;
+    dst->uvlinesize  = src->uvlinesize;
+    dst->first_field = src->first_field;
 
     dst->prev_poc_msb          = src->prev_poc_msb;
     dst->prev_poc_lsb          = src->prev_poc_lsb;
@@ -2369,7 +3004,6 @@ static int clone_slice(H264Context *dst, H264Context *src)
     memcpy(dst->short_ref,        src->short_ref,        sizeof(dst->short_ref));
     memcpy(dst->long_ref,         src->long_ref,         sizeof(dst->long_ref));
     memcpy(dst->default_ref_list, src->default_ref_list, sizeof(dst->default_ref_list));
-    memcpy(dst->ref_list,         src->ref_list,         sizeof(dst->ref_list));
 
     memcpy(dst->dequant4_coeff,   src->dequant4_coeff,   sizeof(src->dequant4_coeff));
     memcpy(dst->dequant8_coeff,   src->dequant8_coeff,   sizeof(src->dequant8_coeff));
@@ -2406,50 +3040,43 @@ int ff_h264_get_profile(SPS *sps)
 
 static int h264_set_parameter_from_sps(H264Context *h)
 {
-    MpegEncContext *s = &h->s;
-
-    if (s->flags & CODEC_FLAG_LOW_DELAY ||
+    if (h->flags & CODEC_FLAG_LOW_DELAY ||
         (h->sps.bitstream_restriction_flag &&
          !h->sps.num_reorder_frames)) {
-        if (s->avctx->has_b_frames > 1 || h->delayed_pic[0])
-            av_log(h->s.avctx, AV_LOG_WARNING, "Delayed frames seen. "
+        if (h->avctx->has_b_frames > 1 || h->delayed_pic[0])
+            av_log(h->avctx, AV_LOG_WARNING, "Delayed frames seen. "
                    "Reenabling low delay requires a codec flush.\n");
         else
-            s->low_delay = 1;
+            h->low_delay = 1;
     }
 
-    if (s->avctx->has_b_frames < 2)
-        s->avctx->has_b_frames = !s->low_delay;
+    if (h->avctx->has_b_frames < 2)
+        h->avctx->has_b_frames = !h->low_delay;
 
     if (h->sps.bit_depth_luma != h->sps.bit_depth_chroma) {
-        av_log_missing_feature(s->avctx,
-            "Different bit depth between chroma and luma", 1);
+        avpriv_request_sample(h->avctx,
+                              "Different chroma and luma bit depth");
         return AVERROR_PATCHWELCOME;
     }
 
-    if (s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
+    if (h->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(s->avctx, AV_LOG_ERROR,
-                   "VDPAU decoding does not support video colorspace.\n");
-            return AVERROR_INVALIDDATA;
-        }
         if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) {
-            s->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
+            h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;
             h->cur_chroma_format_idc      = h->sps.chroma_format_idc;
             h->pixel_shift                = h->sps.bit_depth_luma > 8;
 
             ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma,
                             h->sps.chroma_format_idc);
-            ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma,
+            ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
+            ff_h264qpel_init(&h->h264qpel, h->sps.bit_depth_luma);
+            ff_h264_pred_init(&h->hpc, h->avctx->codec_id, h->sps.bit_depth_luma,
                               h->sps.chroma_format_idc);
-            s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16;
-            ff_dsputil_init(&s->dsp, s->avctx);
-            ff_videodsp_init(&s->vdsp, h->sps.bit_depth_luma);
+            if (CONFIG_ERROR_RESILIENCE)
+                ff_dsputil_init(&h->dsp, h->avctx);
+            ff_videodsp_init(&h->vdsp, h->sps.bit_depth_luma);
         } else {
-            av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
+            av_log(h->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
                    h->sps.bit_depth_luma);
             return AVERROR_INVALIDDATA;
         }
@@ -2457,124 +3084,236 @@ static int h264_set_parameter_from_sps(H264Context *h)
     return 0;
 }
 
-static enum PixelFormat get_pixel_format(H264Context *h)
+static enum AVPixelFormat get_pixel_format(H264Context *h)
 {
-    MpegEncContext *const s  = &h->s;
     switch (h->sps.bit_depth_luma) {
     case 9:
-        if (CHROMA444) {
-            if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+        if (CHROMA444(h)) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
                 return AV_PIX_FMT_GBRP9;
             } else
                 return AV_PIX_FMT_YUV444P9;
-        } else if (CHROMA422)
+        } else if (CHROMA422(h))
             return AV_PIX_FMT_YUV422P9;
         else
             return AV_PIX_FMT_YUV420P9;
         break;
     case 10:
-        if (CHROMA444) {
-            if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+        if (CHROMA444(h)) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
                 return AV_PIX_FMT_GBRP10;
             } else
                 return AV_PIX_FMT_YUV444P10;
-        } else if (CHROMA422)
+        } else if (CHROMA422(h))
             return AV_PIX_FMT_YUV422P10;
         else
             return AV_PIX_FMT_YUV420P10;
         break;
     case 8:
-        if (CHROMA444) {
-            if (s->avctx->colorspace == AVCOL_SPC_RGB) {
+        if (CHROMA444(h)) {
+            if (h->avctx->colorspace == AVCOL_SPC_RGB) {
                 return AV_PIX_FMT_GBRP;
             } else
-                return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
+                return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ444P
                                                                  : AV_PIX_FMT_YUV444P;
-        } else if (CHROMA422) {
-            return s->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
+        } else if (CHROMA422(h)) {
+            return h->avctx->color_range == AVCOL_RANGE_JPEG ? AV_PIX_FMT_YUVJ422P
                                                              : AV_PIX_FMT_YUV422P;
         } else {
-            return s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts ?
-                                        s->avctx->codec->pix_fmts :
-                                        s->avctx->color_range == AVCOL_RANGE_JPEG ?
-                                        hwaccel_pixfmt_list_h264_jpeg_420 :
-                                        ff_hwaccel_pixfmt_list_420);
+            return h->avctx->get_format(h->avctx, h->avctx->codec->pix_fmts ?
+                                        h->avctx->codec->pix_fmts :
+                                        h->avctx->color_range == AVCOL_RANGE_JPEG ?
+                                        h264_hwaccel_pixfmt_list_jpeg_420 :
+                                        h264_hwaccel_pixfmt_list_420);
         }
         break;
     default:
-        av_log(s->avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
         return AVERROR_INVALIDDATA;
     }
 }
 
+/* export coded and cropped frame dimensions to AVCodecContext */
+static int init_dimensions(H264Context *h)
+{
+    int width  = h->width  - (h->sps.crop_right + h->sps.crop_left);
+    int height = h->height - (h->sps.crop_top   + h->sps.crop_bottom);
+
+    /* handle container cropping */
+    if (!h->sps.crop &&
+        FFALIGN(h->avctx->width,  16) == h->width &&
+        FFALIGN(h->avctx->height, 16) == h->height) {
+        width  = h->avctx->width;
+        height = h->avctx->height;
+    }
+
+    if (width <= 0 || height <= 0) {
+        av_log(h->avctx, AV_LOG_ERROR, "Invalid cropped dimensions: %dx%d.\n",
+               width, height);
+        if (h->avctx->err_recognition & AV_EF_EXPLODE)
+            return AVERROR_INVALIDDATA;
+
+        av_log(h->avctx, AV_LOG_WARNING, "Ignoring cropping information.\n");
+        h->sps.crop_bottom = h->sps.crop_top = h->sps.crop_right = h->sps.crop_left = 0;
+        h->sps.crop        = 0;
+
+        width  = h->width;
+        height = h->height;
+    }
+
+    h->avctx->coded_width  = h->width;
+    h->avctx->coded_height = h->height;
+    h->avctx->width        = width;
+    h->avctx->height       = height;
+
+    return 0;
+}
+
 static int h264_slice_header_init(H264Context *h, int reinit)
 {
-    MpegEncContext *const s  = &h->s;
+    int nb_slices = (HAVE_THREADS &&
+                     h->avctx->active_thread_type & FF_THREAD_SLICE) ?
+                    h->avctx->thread_count : 1;
     int i, ret;
 
-    avcodec_set_dimensions(s->avctx, s->width, s->height);
-    s->avctx->sample_aspect_ratio = h->sps.sar;
-    av_assert0(s->avctx->sample_aspect_ratio.den);
+    h->avctx->sample_aspect_ratio = h->sps.sar;
+    av_assert0(h->avctx->sample_aspect_ratio.den);
+    av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt,
+                                     &h->chroma_x_shift, &h->chroma_y_shift);
 
     if (h->sps.timing_info_present_flag) {
         int64_t den = h->sps.time_scale;
         if (h->x264_build < 44U)
             den *= 2;
-        av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
+        av_reduce(&h->avctx->time_base.num, &h->avctx->time_base.den,
                   h->sps.num_units_in_tick, den, 1 << 30);
     }
 
-    s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt);
+    h->avctx->hwaccel = ff_find_hwaccel(h->avctx);
 
-    if (reinit) {
+    if (reinit)
         free_tables(h, 0);
-        if ((ret = ff_MPV_common_frame_size_change(s)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_frame_size_change() failed.\n");
-            return ret;
-        }
-    } else {
-        if ((ret = ff_MPV_common_init(s) < 0)) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "ff_MPV_common_init() failed.\n");
-            return ret;
-        }
-    }
-    s->first_field = 0;
+    h->first_field           = 0;
     h->prev_interlaced_frame = 1;
 
     init_scan_tables(h);
-    if (ff_h264_alloc_tables(h) < 0) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+    ret = ff_h264_alloc_tables(h);
+    if (ret < 0) {
+        av_log(h->avctx, AV_LOG_ERROR,
                "Could not allocate memory for h264\n");
-        return AVERROR(ENOMEM);
+        return ret;
     }
 
-    if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_SLICE)) {
-        if (context_init(h) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
-            return -1;
+    if (nb_slices > MAX_THREADS || (nb_slices > h->mb_height && h->mb_height)) {
+        int max_slices;
+        if (h->mb_height)
+            max_slices = FFMIN(MAX_THREADS, h->mb_height);
+        else
+            max_slices = MAX_THREADS;
+        av_log(h->avctx, AV_LOG_WARNING, "too many threads/slices (%d),"
+               " reducing to %d\n", nb_slices, max_slices);
+        nb_slices = max_slices;
+    }
+    h->slice_context_count = nb_slices;
+
+    if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) {
+        ret = context_init(h);
+        if (ret < 0) {
+            av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
+            return ret;
         }
     } else {
-        for (i = 1; i < s->slice_context_count; i++) {
+        for (i = 1; i < h->slice_context_count; i++) {
             H264Context *c;
-            c = h->thread_context[i] = av_malloc(sizeof(H264Context));
-            memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext));
-            memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));
-            c->h264dsp     = h->h264dsp;
-            c->sps         = h->sps;
-            c->pps         = h->pps;
-            c->pixel_shift = h->pixel_shift;
+            c                    = h->thread_context[i] = av_mallocz(sizeof(H264Context));
+            if (!c)
+                return AVERROR(ENOMEM);
+            c->avctx             = h->avctx;
+            c->dsp               = h->dsp;
+            c->vdsp              = h->vdsp;
+            c->h264dsp           = h->h264dsp;
+            c->h264qpel          = h->h264qpel;
+            c->h264chroma        = h->h264chroma;
+            c->sps               = h->sps;
+            c->pps               = h->pps;
+            c->pixel_shift       = h->pixel_shift;
+            c->width             = h->width;
+            c->height            = h->height;
+            c->linesize          = h->linesize;
+            c->uvlinesize        = h->uvlinesize;
+            c->chroma_x_shift    = h->chroma_x_shift;
+            c->chroma_y_shift    = h->chroma_y_shift;
+            c->qscale            = h->qscale;
+            c->droppable         = h->droppable;
+            c->data_partitioning = h->data_partitioning;
+            c->low_delay         = h->low_delay;
+            c->mb_width          = h->mb_width;
+            c->mb_height         = h->mb_height;
+            c->mb_stride         = h->mb_stride;
+            c->mb_num            = h->mb_num;
+            c->flags             = h->flags;
+            c->workaround_bugs   = h->workaround_bugs;
+            c->pict_type         = h->pict_type;
+
             init_scan_tables(c);
             clone_tables(c, h, i);
+            c->context_initialized = 1;
         }
 
-        for (i = 0; i < s->slice_context_count; i++)
-            if (context_init(h->thread_context[i]) < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n");
-                return -1;
+        for (i = 0; i < h->slice_context_count; i++)
+            if ((ret = context_init(h->thread_context[i])) < 0) {
+                av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
+                return ret;
             }
     }
 
+    h->context_initialized = 1;
+
+    return 0;
+}
+
+int ff_set_ref_count(H264Context *h)
+{
+    int num_ref_idx_active_override_flag, max_refs;
+
+    // set defaults, might be overridden a few lines later
+    h->ref_count[0] = h->pps.ref_count[0];
+    h->ref_count[1] = h->pps.ref_count[1];
+
+    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
+        if (h->slice_type_nos == AV_PICTURE_TYPE_B)
+            h->direct_spatial_mv_pred = get_bits1(&h->gb);
+        num_ref_idx_active_override_flag = get_bits1(&h->gb);
+
+        if (num_ref_idx_active_override_flag) {
+            h->ref_count[0] = get_ue_golomb(&h->gb) + 1;
+            if (h->ref_count[0] < 1)
+                return AVERROR_INVALIDDATA;
+            if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
+                h->ref_count[1] = get_ue_golomb(&h->gb) + 1;
+                if (h->ref_count[1] < 1)
+                    return AVERROR_INVALIDDATA;
+            }
+        }
+
+        if (h->slice_type_nos == AV_PICTURE_TYPE_B)
+            h->list_count = 2;
+        else
+            h->list_count = 1;
+    } else {
+        h->list_count   = 0;
+        h->ref_count[0] = h->ref_count[1] = 0;
+    }
+
+    max_refs = h->picture_structure == PICT_FRAME ? 16 : 32;
+
+    if (h->ref_count[0] > max_refs || h->ref_count[1] > max_refs) {
+        av_log(h->avctx, AV_LOG_ERROR, "reference overflow\n");
+        h->ref_count[0] = h->ref_count[1] = 0;
+        return AVERROR_INVALIDDATA;
+    }
+
     return 0;
 }
 
@@ -2590,50 +3329,41 @@ static int h264_slice_header_init(H264Context *h, int reinit)
  */
 static int decode_slice_header(H264Context *h, H264Context *h0)
 {
-    MpegEncContext *const s  = &h->s;
-    MpegEncContext *const s0 = &h0->s;
     unsigned int first_mb_in_slice;
     unsigned int pps_id;
-    int num_ref_idx_active_override_flag, max_refs, ret;
+    int ret;
     unsigned int slice_type, tmp, i, j;
     int default_ref_list_done = 0;
     int last_pic_structure, last_pic_droppable;
     int needs_reinit = 0;
+    int field_pic_flag, bottom_field_flag;
 
-    /* FIXME: 2tap qpel isn't implemented for high bit depth. */
-    if ((s->avctx->flags2 & CODEC_FLAG2_FAST) &&
-        !h->nal_ref_idc && !h->pixel_shift) {
-        s->me.qpel_put = s->dsp.put_2tap_qpel_pixels_tab;
-        s->me.qpel_avg = s->dsp.avg_2tap_qpel_pixels_tab;
-    } else {
-        s->me.qpel_put = s->dsp.put_h264_qpel_pixels_tab;
-        s->me.qpel_avg = s->dsp.avg_h264_qpel_pixels_tab;
-    }
+    h->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;
+    h->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;
 
-    first_mb_in_slice = get_ue_golomb(&s->gb);
+    first_mb_in_slice = get_ue_golomb(&h->gb);
 
     if (first_mb_in_slice == 0) { // FIXME better field boundary detection
-        if (h0->current_slice && FIELD_PICTURE) {
+        if (h0->current_slice && FIELD_PICTURE(h)) {
             field_end(h, 1);
         }
 
         h0->current_slice = 0;
-        if (!s0->first_field) {
-            if (s->current_picture_ptr && !s->droppable &&
-                s->current_picture_ptr->owner2 == s) {
-                ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                          s->picture_structure == PICT_BOTTOM_FIELD);
+        if (!h0->first_field) {
+            if (h->cur_pic_ptr && !h->droppable) {
+                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
+                                          h->picture_structure == PICT_BOTTOM_FIELD);
             }
-            s->current_picture_ptr = NULL;
+            h->cur_pic_ptr = NULL;
         }
     }
 
-    slice_type = get_ue_golomb_31(&s->gb);
+    slice_type = get_ue_golomb_31(&h->gb);
     if (slice_type > 9) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "slice type too large (%d) at %d %d\n",
-               h->slice_type, s->mb_x, s->mb_y);
-        return -1;
+               h->slice_type, h->mb_x, h->mb_y);
+        return AVERROR_INVALIDDATA;
     }
     if (slice_type > 4) {
         slice_type -= 5;
@@ -2650,93 +3380,87 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     h->slice_type_nos = slice_type & 3;
 
     // to make a few old functions happy, it's wrong though
-    s->pict_type = h->slice_type;
+    h->pict_type = h->slice_type;
 
-    pps_id = get_ue_golomb(&s->gb);
+    pps_id = get_ue_golomb(&h->gb);
     if (pps_id >= MAX_PPS_COUNT) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
-        return -1;
+        av_log(h->avctx, AV_LOG_ERROR, "pps_id out of range\n");
+        return AVERROR_INVALIDDATA;
     }
     if (!h0->pps_buffers[pps_id]) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "non-existing PPS %u referenced\n",
                pps_id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     h->pps = *h0->pps_buffers[pps_id];
 
     if (!h0->sps_buffers[h->pps.sps_id]) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "non-existing SPS %u referenced\n",
                h->pps.sps_id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (h->pps.sps_id != h->current_sps_id ||
-        h->context_reinitialized           ||
         h0->sps_buffers[h->pps.sps_id]->new) {
-        SPS *new_sps = h0->sps_buffers[h->pps.sps_id];
-
         h0->sps_buffers[h->pps.sps_id]->new = 0;
 
-        if (h->sps.chroma_format_idc != new_sps->chroma_format_idc ||
-            h->sps.bit_depth_luma    != new_sps->bit_depth_luma)
-            needs_reinit = 1;
-
         h->current_sps_id = h->pps.sps_id;
         h->sps            = *h0->sps_buffers[h->pps.sps_id];
 
+        if (h->bit_depth_luma    != h->sps.bit_depth_luma ||
+            h->chroma_format_idc != h->sps.chroma_format_idc) {
+            h->bit_depth_luma    = h->sps.bit_depth_luma;
+            h->chroma_format_idc = h->sps.chroma_format_idc;
+            needs_reinit         = 1;
+        }
         if ((ret = h264_set_parameter_from_sps(h)) < 0)
             return ret;
     }
 
-    s->avctx->profile = ff_h264_get_profile(&h->sps);
-    s->avctx->level   = h->sps.level_idc;
-    s->avctx->refs    = h->sps.ref_frame_count;
+    h->avctx->profile = ff_h264_get_profile(&h->sps);
+    h->avctx->level   = h->sps.level_idc;
+    h->avctx->refs    = h->sps.ref_frame_count;
 
-    if (s->mb_width  != h->sps.mb_width ||
-        s->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag))
+    if (h->mb_width  != h->sps.mb_width ||
+        h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag))
         needs_reinit = 1;
 
-    s->mb_width  = h->sps.mb_width;
-    s->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
+    h->mb_width  = h->sps.mb_width;
+    h->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
+    h->mb_num    = h->mb_width * h->mb_height;
+    h->mb_stride = h->mb_width + 1;
 
-    h->b_stride = s->mb_width * 4;
+    h->b_stride = h->mb_width * 4;
 
-    s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
+    h->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);
+    h->width  = 16 * h->mb_width;
+    h->height = 16 * h->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;
-    }
+    ret = init_dimensions(h);
+    if (ret < 0)
+        return ret;
 
     if (h->sps.video_signal_type_present_flag) {
-        s->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG
+        h->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG
                                                   : AVCOL_RANGE_MPEG;
         if (h->sps.colour_description_present_flag) {
-            if (s->avctx->colorspace != h->sps.colorspace)
+            if (h->avctx->colorspace != h->sps.colorspace)
                 needs_reinit = 1;
-            s->avctx->color_primaries = h->sps.color_primaries;
-            s->avctx->color_trc       = h->sps.color_trc;
-            s->avctx->colorspace      = h->sps.colorspace;
+            h->avctx->color_primaries = h->sps.color_primaries;
+            h->avctx->color_trc       = h->sps.color_trc;
+            h->avctx->colorspace      = h->sps.colorspace;
         }
     }
 
-    if (s->context_initialized &&
-        (s->width  != s->avctx->width   ||
-         s->height != s->avctx->height  ||
-         needs_reinit                   ||
-         av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) {
-
+    if (h->context_initialized &&
+        (h->width  != h->avctx->coded_width   ||
+         h->height != h->avctx->coded_height  ||
+         needs_reinit)) {
         if (h != h0) {
-            av_log(s->avctx, AV_LOG_ERROR, "changing width/height on "
+            av_log(h->avctx, AV_LOG_ERROR, "changing width/height on "
                    "slice %d\n", h0->current_slice + 1);
             return AVERROR_INVALIDDATA;
         }
@@ -2745,31 +3469,30 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
 
         if ((ret = get_pixel_format(h)) < 0)
             return ret;
-        s->avctx->pix_fmt = ret;
+        h->avctx->pix_fmt = ret;
 
-        av_log(h->s.avctx, AV_LOG_INFO, "Reinit context to %dx%d, "
-               "pix_fmt: %d\n", s->width, s->height, s->avctx->pix_fmt);
+        av_log(h->avctx, AV_LOG_INFO, "Reinit context to %dx%d, "
+               "pix_fmt: %d\n", h->width, h->height, h->avctx->pix_fmt);
 
         if ((ret = h264_slice_header_init(h, 1)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "h264_slice_header_init() failed\n");
             return ret;
         }
-        h->context_reinitialized = 1;
     }
-    if (!s->context_initialized) {
+    if (!h->context_initialized) {
         if (h != h0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "Cannot (re-)initialize context during parallel decoding.\n");
-            return -1;
+            return AVERROR_PATCHWELCOME;
         }
 
         if ((ret = get_pixel_format(h)) < 0)
             return ret;
-        s->avctx->pix_fmt = ret;
+        h->avctx->pix_fmt = ret;
 
         if ((ret = h264_slice_header_init(h, 0)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "h264_slice_header_init() failed\n");
             return ret;
         }
@@ -2780,37 +3503,39 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         init_dequant_tables(h);
     }
 
-    h->frame_num = get_bits(&s->gb, h->sps.log2_max_frame_num);
+    h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);
 
     h->mb_mbaff        = 0;
     h->mb_aff_frame    = 0;
-    last_pic_structure = s0->picture_structure;
-    last_pic_droppable = s0->droppable;
-    s->droppable       = h->nal_ref_idc == 0;
+    last_pic_structure = h0->picture_structure;
+    last_pic_droppable = h0->droppable;
+    h->droppable       = h->nal_ref_idc == 0;
     if (h->sps.frame_mbs_only_flag) {
-        s->picture_structure = PICT_FRAME;
+        h->picture_structure = PICT_FRAME;
     } else {
-        if (get_bits1(&s->gb)) { // field_pic_flag
-            s->picture_structure = PICT_TOP_FIELD + get_bits1(&s->gb); // bottom_field_flag
+        field_pic_flag = get_bits1(&h->gb);
+        if (field_pic_flag) {
+            bottom_field_flag = get_bits1(&h->gb);
+            h->picture_structure = PICT_TOP_FIELD + bottom_field_flag;
         } else {
-            s->picture_structure = PICT_FRAME;
+            h->picture_structure = PICT_FRAME;
             h->mb_aff_frame      = h->sps.mb_aff;
         }
     }
-    h->mb_field_decoding_flag = s->picture_structure != PICT_FRAME;
+    h->mb_field_decoding_flag = h->picture_structure != PICT_FRAME;
 
     if (h0->current_slice != 0) {
-        if (last_pic_structure != s->picture_structure ||
-            last_pic_droppable != s->droppable) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+        if (last_pic_structure != h->picture_structure ||
+            last_pic_droppable != h->droppable) {
+            av_log(h->avctx, AV_LOG_ERROR,
                    "Changing field mode (%d -> %d) between slices is not allowed\n",
-                   last_pic_structure, s->picture_structure);
-            s->picture_structure = last_pic_structure;
-            s->droppable         = last_pic_droppable;
+                   last_pic_structure, h->picture_structure);
+            h->picture_structure = last_pic_structure;
+            h->droppable         = last_pic_droppable;
             return AVERROR_INVALIDDATA;
-        } else if (!s0->current_picture_ptr) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "unset current_picture_ptr on %d. slice\n",
+        } else if (!h0->cur_pic_ptr) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "unset cur_pic_ptr on %d. slice\n",
                    h0->current_slice + 1);
             return AVERROR_INVALIDDATA;
         }
@@ -2838,63 +3563,48 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
          * decode frames as "finished".
          * We have to do that before the "dummy" in-between frame allocation,
          * since that can modify s->current_picture_ptr. */
-        if (s0->first_field) {
-            assert(s0->current_picture_ptr);
-            assert(s0->current_picture_ptr->f.data[0]);
-            assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
-
-            /* Mark old field/frame as completed */
-            if (!last_pic_droppable && s0->current_picture_ptr->owner2 == s0) {
-                ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
-                                          last_pic_structure == PICT_BOTTOM_FIELD);
-            }
+        if (h0->first_field) {
+            assert(h0->cur_pic_ptr);
+            assert(h0->cur_pic_ptr->f.buf[0]);
+            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);
 
             /* figure out if we have a complementary field pair */
-            if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
+            if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
                 if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
-                    ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                    ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                               last_pic_structure == PICT_TOP_FIELD);
                 }
             } else {
-                if (s0->current_picture_ptr->frame_num != h->frame_num) {
+                if (h0->cur_pic_ptr->frame_num != h->frame_num) {
                     /* This and previous field were reference, but had
                      * different frame_nums. Consider this field first in
                      * pair. Throw away previous field except for reference
                      * purposes. */
                     if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
-                        ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX,
+                        ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                                   last_pic_structure == PICT_TOP_FIELD);
                     }
                 } else {
                     /* Second field in complementary pair */
                     if (!((last_pic_structure   == PICT_TOP_FIELD &&
-                           s->picture_structure == PICT_BOTTOM_FIELD) ||
+                           h->picture_structure == PICT_BOTTOM_FIELD) ||
                           (last_pic_structure   == PICT_BOTTOM_FIELD &&
-                           s->picture_structure == PICT_TOP_FIELD))) {
-                        av_log(s->avctx, AV_LOG_ERROR,
+                           h->picture_structure == PICT_TOP_FIELD))) {
+                        av_log(h->avctx, AV_LOG_ERROR,
                                "Invalid field mode combination %d/%d\n",
-                               last_pic_structure, s->picture_structure);
-                        s->picture_structure = last_pic_structure;
-                        s->droppable         = last_pic_droppable;
+                               last_pic_structure, h->picture_structure);
+                        h->picture_structure = last_pic_structure;
+                        h->droppable         = last_pic_droppable;
                         return AVERROR_INVALIDDATA;
-                    } else if (last_pic_droppable != s->droppable) {
-                        av_log(s->avctx, AV_LOG_ERROR,
-                               "Cannot combine reference and non-reference fields in the same frame\n");
-                        av_log_ask_for_sample(s->avctx, NULL);
-                        s->picture_structure = last_pic_structure;
-                        s->droppable         = last_pic_droppable;
+                    } else if (last_pic_droppable != h->droppable) {
+                        avpriv_request_sample(h->avctx,
+                                              "Found reference and non-reference fields in the same frame, which");
+                        h->picture_structure = last_pic_structure;
+                        h->droppable         = last_pic_droppable;
                         return AVERROR_PATCHWELCOME;
                     }
-
-                    /* Take ownership of this buffer. Note that if another thread owned
-                     * the first field of this buffer, we're not operating on that pointer,
-                     * so the original thread is still responsible for reporting progress
-                     * on that first field (or if that was us, we just did that above).
-                     * By taking ownership, we assign responsibility to ourselves to
-                     * report progress on the second field. */
-                    s0->current_picture_ptr->owner2 = s0;
                 }
             }
         }
@@ -2902,32 +3612,38 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         while (h->frame_num != h->prev_frame_num &&
                h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {
             Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;
-            av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
+            av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",
                    h->frame_num, h->prev_frame_num);
-            if (ff_h264_frame_start(h) < 0)
-                return -1;
+            ret = h264_frame_start(h);
+            if (ret < 0)
+                return ret;
             h->prev_frame_num++;
-            h->prev_frame_num %= 1 << h->sps.log2_max_frame_num;
-            s->current_picture_ptr->frame_num = h->prev_frame_num;
-            ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
-            ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 1);
-            if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 &&
-                s->avctx->err_recognition & AV_EF_EXPLODE)
+            h->prev_frame_num        %= 1 << h->sps.log2_max_frame_num;
+            h->cur_pic_ptr->frame_num = h->prev_frame_num;
+            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
+            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
+            ret = ff_generate_sliding_window_mmcos(h, 1);
+            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
-            if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 &&
-                (s->avctx->err_recognition & AV_EF_EXPLODE))
-                return AVERROR_INVALIDDATA;
-            /* Error concealment: if a ref is missing, copy the previous ref in its place.
-             * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions
-             * about there being no actual duplicates.
-             * FIXME: this doesn't copy padding for out-of-frame motion vectors.  Given we're
-             * concealing a lost frame, this probably isn't noticeable by comparison, but it should
-             * be fixed. */
+            ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
+            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
+                return ret;
+            /* Error concealment: If a ref is missing, copy the previous ref
+             * in its place.
+             * FIXME: Avoiding a memcpy would be nice, but ref handling makes
+             * many assumptions about there being no actual duplicates.
+             * FIXME: This does not copy padding for out-of-frame motion
+             * vectors.  Given we are concealing a lost frame, this probably
+             * is not noticeable by comparison, but it should be fixed. */
             if (h->short_ref_count) {
                 if (prev) {
-                    av_image_copy(h->short_ref[0]->f.data, h->short_ref[0]->f.linesize,
-                                  (const uint8_t **)prev->f.data, prev->f.linesize,
-                                  s->avctx->pix_fmt, s->mb_width * 16, s->mb_height * 16);
+                    av_image_copy(h->short_ref[0]->f.data,
+                                  h->short_ref[0]->f.linesize,
+                                  (const uint8_t **)prev->f.data,
+                                  prev->f.linesize,
+                                  h->avctx->pix_fmt,
+                                  h->mb_width  * 16,
+                                  h->mb_height * 16);
                     h->short_ref[0]->poc = prev->poc + 2;
                 }
                 h->short_ref[0]->frame_num = h->prev_frame_num;
@@ -2937,61 +3653,62 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         /* See if we have a decoded first field looking for a pair...
          * We're using that to see whether to continue decoding in that
          * frame, or to allocate a new one. */
-        if (s0->first_field) {
-            assert(s0->current_picture_ptr);
-            assert(s0->current_picture_ptr->f.data[0]);
-            assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF);
+        if (h0->first_field) {
+            assert(h0->cur_pic_ptr);
+            assert(h0->cur_pic_ptr->f.buf[0]);
+            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);
 
             /* figure out if we have a complementary field pair */
-            if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
+            if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
-                s0->current_picture_ptr = NULL;
-                s0->first_field         = FIELD_PICTURE;
+                h0->cur_pic_ptr = NULL;
+                h0->first_field = FIELD_PICTURE(h);
             } else {
-                if (s0->current_picture_ptr->frame_num != h->frame_num) {
+                if (h0->cur_pic_ptr->frame_num != h->frame_num) {
                     /* This and the previous field had different frame_nums.
                      * Consider this field first in pair. Throw away previous
                      * one except for reference purposes. */
-                    s0->first_field         = 1;
-                    s0->current_picture_ptr = NULL;
+                    h0->first_field = 1;
+                    h0->cur_pic_ptr = NULL;
                 } else {
                     /* Second field in complementary pair */
-                    s0->first_field = 0;
+                    h0->first_field = 0;
                 }
             }
         } else {
             /* Frame or first field in a potentially complementary pair */
-            s0->first_field = FIELD_PICTURE;
+            h0->first_field = FIELD_PICTURE(h);
         }
 
-        if (!FIELD_PICTURE || s0->first_field) {
-            if (ff_h264_frame_start(h) < 0) {
-                s0->first_field = 0;
-                return -1;
+        if (!FIELD_PICTURE(h) || h0->first_field) {
+            if (h264_frame_start(h) < 0) {
+                h0->first_field = 0;
+                return AVERROR_INVALIDDATA;
             }
         } else {
-            ff_release_unused_pictures(s, 0);
+            release_unused_pictures(h, 0);
         }
     }
     if (h != h0 && (ret = clone_slice(h, h0)) < 0)
         return ret;
 
-    s->current_picture_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
+    h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
 
-    assert(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");
-        return -1;
+    assert(h->mb_num == h->mb_width * h->mb_height);
+    if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE(h) >= h->mb_num ||
+        first_mb_in_slice >= h->mb_num) {
+        av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
+        return AVERROR_INVALIDDATA;
     }
-    s->resync_mb_x = s->mb_x =  first_mb_in_slice % s->mb_width;
-    s->resync_mb_y = s->mb_y = (first_mb_in_slice / s->mb_width) << FIELD_OR_MBAFF_PICTURE;
-    if (s->picture_structure == PICT_BOTTOM_FIELD)
-        s->resync_mb_y = s->mb_y = s->mb_y + 1;
-    assert(s->mb_y < s->mb_height);
+    h->resync_mb_x = h->mb_x =  first_mb_in_slice % h->mb_width;
+    h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) <<
+                               FIELD_OR_MBAFF_PICTURE(h);
+    if (h->picture_structure == PICT_BOTTOM_FIELD)
+        h->resync_mb_y = h->mb_y = h->mb_y + 1;
+    assert(h->mb_y < h->mb_height);
 
-    if (s->picture_structure == PICT_FRAME) {
+    if (h->picture_structure == PICT_FRAME) {
         h->curr_pic_num = h->frame_num;
         h->max_pic_num  = 1 << h->sps.log2_max_frame_num;
     } else {
@@ -3000,89 +3717,46 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     }
 
     if (h->nal_unit_type == NAL_IDR_SLICE)
-        get_ue_golomb(&s->gb); /* idr_pic_id */
+        get_ue_golomb(&h->gb); /* idr_pic_id */
 
     if (h->sps.poc_type == 0) {
-        h->poc_lsb = get_bits(&s->gb, h->sps.log2_max_poc_lsb);
+        h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);
 
-        if (h->pps.pic_order_present == 1 && s->picture_structure == PICT_FRAME)
-            h->delta_poc_bottom = get_se_golomb(&s->gb);
+        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+            h->delta_poc_bottom = get_se_golomb(&h->gb);
     }
 
     if (h->sps.poc_type == 1 && !h->sps.delta_pic_order_always_zero_flag) {
-        h->delta_poc[0] = get_se_golomb(&s->gb);
+        h->delta_poc[0] = get_se_golomb(&h->gb);
 
-        if (h->pps.pic_order_present == 1 && s->picture_structure == PICT_FRAME)
-            h->delta_poc[1] = get_se_golomb(&s->gb);
+        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)
+            h->delta_poc[1] = get_se_golomb(&h->gb);
     }
 
-    init_poc(h);
+    ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc);
 
     if (h->pps.redundant_pic_cnt_present)
-        h->redundant_pic_count = get_ue_golomb(&s->gb);
-
-    // set defaults, might be overridden a few lines later
-    h->ref_count[0] = h->pps.ref_count[0];
-    h->ref_count[1] = h->pps.ref_count[1];
-
-    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
-        if (h->slice_type_nos == AV_PICTURE_TYPE_B)
-            h->direct_spatial_mv_pred = get_bits1(&s->gb);
-        num_ref_idx_active_override_flag = get_bits1(&s->gb);
-
-        if (num_ref_idx_active_override_flag) {
-            h->ref_count[0] = get_ue_golomb(&s->gb) + 1;
-            if (h->ref_count[0] < 1)
-                return AVERROR_INVALIDDATA;
-            if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
-                h->ref_count[1] = get_ue_golomb(&s->gb) + 1;
-                if (h->ref_count[1] < 1)
-                    return AVERROR_INVALIDDATA;
-            }
-        }
-
-        if (h->slice_type_nos == AV_PICTURE_TYPE_B)
-            h->list_count = 2;
-        else
-            h->list_count = 1;
-    } else {
-        h->list_count = 0;
-        h->ref_count[0] = h->ref_count[1] = 0;
-    }
+        h->redundant_pic_count = get_ue_golomb(&h->gb);
 
-
-    max_refs = s->picture_structure == PICT_FRAME ? 16 : 32;
-
-    if (h->ref_count[0] > max_refs || h->ref_count[1] > max_refs) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
-        h->ref_count[0] = h->ref_count[1] = 0;
-        return AVERROR_INVALIDDATA;
-    }
+    ret = ff_set_ref_count(h);
+    if (ret < 0)
+        return ret;
 
     if (!default_ref_list_done)
         ff_h264_fill_default_ref_list(h);
 
-    if (h->slice_type_nos != AV_PICTURE_TYPE_I &&
-        ff_h264_decode_ref_pic_list_reordering(h) < 0) {
-        h->ref_count[1] = h->ref_count[0] = 0;
-        return -1;
-    }
-
     if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
-        s->last_picture_ptr = &h->ref_list[0][0];
-        s->last_picture_ptr->owner2 = s;
-        ff_copy_picture(&s->last_picture, s->last_picture_ptr);
-    }
-    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
-        s->next_picture_ptr = &h->ref_list[1][0];
-        s->next_picture_ptr->owner2 = s;
-        ff_copy_picture(&s->next_picture, s->next_picture_ptr);
+       ret = ff_h264_decode_ref_pic_list_reordering(h);
+       if (ret < 0) {
+           h->ref_count[1] = h->ref_count[0] = 0;
+           return ret;
+       }
     }
 
     if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
         (h->pps.weighted_bipred_idc == 1 &&
          h->slice_type_nos == AV_PICTURE_TYPE_B))
-        pred_weight_table(h);
+        ff_pred_weight_table(h);
     else if (h->pps.weighted_bipred_idc == 2 &&
              h->slice_type_nos == AV_PICTURE_TYPE_B) {
         implicit_weight_table(h, -1);
@@ -3099,14 +3773,15 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     // or h->mmco, which will cause ref list mix-ups and decoding errors
     // further down the line. This may break decoding if the first slice is
     // corrupt, thus we only do this if frame-mt is enabled.
-    if (h->nal_ref_idc &&
-        ff_h264_decode_ref_pic_marking(h0, &s->gb,
-                            !(s->avctx->active_thread_type & FF_THREAD_FRAME) ||
-                            h0->current_slice == 0) < 0 &&
-        (s->avctx->err_recognition & AV_EF_EXPLODE))
-        return AVERROR_INVALIDDATA;
+    if (h->nal_ref_idc) {
+        ret = ff_h264_decode_ref_pic_marking(h0, &h->gb,
+                                             !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||
+                                             h0->current_slice == 0);
+        if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
+            return AVERROR_INVALIDDATA;
+    }
 
-    if (FRAME_MBAFF) {
+    if (FRAME_MBAFF(h)) {
         ff_h264_fill_mbaff_ref_list(h);
 
         if (h->pps.weighted_bipred_idc == 2 && h->slice_type_nos == AV_PICTURE_TYPE_B) {
@@ -3120,80 +3795,80 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
     ff_h264_direct_ref_list_init(h);
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_I && h->pps.cabac) {
-        tmp = get_ue_golomb_31(&s->gb);
+        tmp = get_ue_golomb_31(&h->gb);
         if (tmp > 2) {
-            av_log(s->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
-            return -1;
+            av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
+            return AVERROR_INVALIDDATA;
         }
         h->cabac_init_idc = tmp;
     }
 
     h->last_qscale_diff = 0;
-    tmp = h->pps.init_qp + get_se_golomb(&s->gb);
+    tmp = h->pps.init_qp + get_se_golomb(&h->gb);
     if (tmp > 51 + 6 * (h->sps.bit_depth_luma - 8)) {
-        av_log(s->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
-        return -1;
+        av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
+        return AVERROR_INVALIDDATA;
     }
-    s->qscale       = tmp;
-    h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+    h->qscale       = tmp;
+    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
     // FIXME qscale / qp ... stuff
     if (h->slice_type == AV_PICTURE_TYPE_SP)
-        get_bits1(&s->gb); /* sp_for_switch_flag */
+        get_bits1(&h->gb); /* sp_for_switch_flag */
     if (h->slice_type == AV_PICTURE_TYPE_SP ||
         h->slice_type == AV_PICTURE_TYPE_SI)
-        get_se_golomb(&s->gb); /* slice_qs_delta */
+        get_se_golomb(&h->gb); /* slice_qs_delta */
 
     h->deblocking_filter     = 1;
     h->slice_alpha_c0_offset = 52;
     h->slice_beta_offset     = 52;
     if (h->pps.deblocking_filter_parameters_present) {
-        tmp = get_ue_golomb_31(&s->gb);
+        tmp = get_ue_golomb_31(&h->gb);
         if (tmp > 2) {
-            av_log(s->avctx, AV_LOG_ERROR,
+            av_log(h->avctx, AV_LOG_ERROR,
                    "deblocking_filter_idc %u out of range\n", tmp);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         h->deblocking_filter = tmp;
         if (h->deblocking_filter < 2)
             h->deblocking_filter ^= 1;  // 1<->0
 
         if (h->deblocking_filter) {
-            h->slice_alpha_c0_offset += get_se_golomb(&s->gb) << 1;
-            h->slice_beta_offset     += get_se_golomb(&s->gb) << 1;
+            h->slice_alpha_c0_offset += get_se_golomb(&h->gb) << 1;
+            h->slice_beta_offset     += get_se_golomb(&h->gb) << 1;
             if (h->slice_alpha_c0_offset > 104U ||
                 h->slice_beta_offset     > 104U) {
-                av_log(s->avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "deblocking filter parameters %d %d out of range\n",
                        h->slice_alpha_c0_offset, h->slice_beta_offset);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }
 
-    if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&
+    if (h->avctx->skip_loop_filter >= AVDISCARD_ALL ||
+        (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&
          h->slice_type_nos != AV_PICTURE_TYPE_I) ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&
+        (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&
          h->slice_type_nos == AV_PICTURE_TYPE_B) ||
-        (s->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
+        (h->avctx->skip_loop_filter >= AVDISCARD_NONREF &&
          h->nal_ref_idc == 0))
         h->deblocking_filter = 0;
 
     if (h->deblocking_filter == 1 && h0->max_contexts > 1) {
-        if (s->avctx->flags2 & CODEC_FLAG2_FAST) {
+        if (h->avctx->flags2 & CODEC_FLAG2_FAST) {
             /* Cheat slightly for speed:
              * Do not bother to deblock across slices. */
             h->deblocking_filter = 2;
         } else {
             h0->max_contexts = 1;
             if (!h0->single_decode_warning) {
-                av_log(s->avctx, AV_LOG_INFO,
+                av_log(h->avctx, AV_LOG_INFO,
                        "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n");
                 h0->single_decode_warning = 1;
             }
             if (h != h0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "Deblocking switched inside frame.\n");
                 return 1;
             }
@@ -3207,9 +3882,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
                    6 * (h->sps.bit_depth_luma - 8);
 
     h0->last_slice_type = slice_type;
-    h->slice_num = ++h0->current_slice;
+    h->slice_num        = ++h0->current_slice;
     if (h->slice_num >= MAX_SLICES) {
-        av_log(s->avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "Too many slices, increase MAX_SLICES and recompile\n");
     }
 
@@ -3218,55 +3893,48 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j];
         for (i = 0; i < 16; i++) {
             id_list[i] = 60;
-            if (h->ref_list[j][i].f.data[0]) {
+            if (j < h->list_count && i < h->ref_count[j] &&
+                h->ref_list[j][i].f.buf[0]) {
                 int k;
-                uint8_t *base = h->ref_list[j][i].f.base[0];
+                AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer;
                 for (k = 0; k < h->short_ref_count; k++)
-                    if (h->short_ref[k]->f.base[0] == base) {
+                    if (h->short_ref[k]->f.buf[0]->buffer == buf) {
                         id_list[i] = k;
                         break;
                     }
                 for (k = 0; k < h->long_ref_count; k++)
-                    if (h->long_ref[k] && h->long_ref[k]->f.base[0] == base) {
+                    if (h->long_ref[k] && h->long_ref[k]->f.buf[0]->buffer == buf) {
                         id_list[i] = h->short_ref_count + k;
                         break;
                     }
             }
         }
 
-        ref2frm[0]     =
-            ref2frm[1] = -1;
+        ref2frm[0] =
+        ref2frm[1] = -1;
         for (i = 0; i < 16; i++)
-            ref2frm[i + 2] = 4 * id_list[i] +
-                             (h->ref_list[j][i].f.reference & 3);
-        ref2frm[18 + 0]     =
-            ref2frm[18 + 1] = -1;
+            ref2frm[i + 2] = 4 * id_list[i] + (h->ref_list[j][i].reference & 3);
+        ref2frm[18 + 0] =
+        ref2frm[18 + 1] = -1;
         for (i = 16; i < 48; i++)
             ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] +
-                             (h->ref_list[j][i].f.reference & 3);
+                             (h->ref_list[j][i].reference & 3);
     }
 
-    // FIXME: fix draw_edges + PAFF + frame threads
-    h->emu_edge_width  = (s->flags & CODEC_FLAG_EMU_EDGE ||
-                          (!h->sps.frame_mbs_only_flag &&
-                           s->avctx->active_thread_type))
-                         ? 0 : 16;
-    h->emu_edge_height = (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width;
-
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
-        av_log(h->s.avctx, AV_LOG_DEBUG,
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
+        av_log(h->avctx, AV_LOG_DEBUG,
                "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
                h->slice_num,
-               (s->picture_structure == PICT_FRAME ? "F" : s->picture_structure == PICT_TOP_FIELD ? "T" : "B"),
+               (h->picture_structure == PICT_FRAME ? "F" : h->picture_structure == PICT_TOP_FIELD ? "T" : "B"),
                first_mb_in_slice,
                av_get_picture_type_char(h->slice_type),
                h->slice_type_fixed ? " fix" : "",
                h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",
                pps_id, h->frame_num,
-               s->current_picture_ptr->field_poc[0],
-               s->current_picture_ptr->field_poc[1],
+               h->cur_pic_ptr->field_poc[0],
+               h->cur_pic_ptr->field_poc[1],
                h->ref_count[0], h->ref_count[1],
-               s->qscale,
+               h->qscale,
                h->deblocking_filter,
                h->slice_alpha_c0_offset / 2 - 26, h->slice_beta_offset / 2 - 26,
                h->use_weight,
@@ -3291,12 +3959,11 @@ int ff_h264_get_slice_type(const H264Context *h)
     case AV_PICTURE_TYPE_SI:
         return 4;
     default:
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 }
 
 static av_always_inline void fill_filter_caches_inter(H264Context *h,
-                                                      MpegEncContext *const s,
                                                       int mb_type, int top_xy,
                                                       int left_xy[LEFT_MBS],
                                                       int top_type,
@@ -3310,12 +3977,12 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
         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);
-            AV_COPY128(mv_dst - 1 * 8, s->current_picture.f.motion_val[list][b_xy + 0]);
+            int (*ref2frm)[64] = h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2);
+            AV_COPY128(mv_dst - 1 * 8, h->cur_pic.motion_val[list][b_xy + 0]);
             ref_cache[0 - 1 * 8] =
-            ref_cache[1 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 0]];
+            ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 0]];
             ref_cache[2 - 1 * 8] =
-            ref_cache[3 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 1]];
+            ref_cache[3 - 1 * 8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 1]];
         } else {
             AV_ZERO128(mv_dst - 1 * 8);
             AV_WN32A(&ref_cache[0 - 1 * 8], ((LIST_NOT_USED) & 0xFF) * 0x01010101u);
@@ -3325,15 +3992,15 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
             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);
-                AV_COPY32(mv_dst - 1 +  0, s->current_picture.f.motion_val[list][b_xy + b_stride * 0]);
-                AV_COPY32(mv_dst - 1 +  8, s->current_picture.f.motion_val[list][b_xy + b_stride * 1]);
-                AV_COPY32(mv_dst - 1 + 16, s->current_picture.f.motion_val[list][b_xy + b_stride * 2]);
-                AV_COPY32(mv_dst - 1 + 24, s->current_picture.f.motion_val[list][b_xy + b_stride * 3]);
+                int (*ref2frm)[64] = h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 20 : 2);
+                AV_COPY32(mv_dst - 1 +  0, h->cur_pic.motion_val[list][b_xy + b_stride * 0]);
+                AV_COPY32(mv_dst - 1 +  8, h->cur_pic.motion_val[list][b_xy + b_stride * 1]);
+                AV_COPY32(mv_dst - 1 + 16, h->cur_pic.motion_val[list][b_xy + b_stride * 2]);
+                AV_COPY32(mv_dst - 1 + 24, h->cur_pic.motion_val[list][b_xy + b_stride * 3]);
                 ref_cache[-1 +  0] =
-                ref_cache[-1 +  8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2 * 0]];
+                ref_cache[-1 +  8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 2 * 0]];
                 ref_cache[-1 + 16] =
-                ref_cache[-1 + 24] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 2 * 1]];
+                ref_cache[-1 + 24] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 2 * 1]];
             } else {
                 AV_ZERO32(mv_dst - 1 +  0);
                 AV_ZERO32(mv_dst - 1 +  8);
@@ -3357,8 +4024,8 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
     }
 
     {
-        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);
+        int8_t *ref = &h->cur_pic.ref_index[list][4 * mb_xy];
+        int (*ref2frm)[64] = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF(h) ? 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);
@@ -3368,7 +4035,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
     }
 
     {
-        int16_t(*mv_src)[2] = &s->current_picture.f.motion_val[list][4 * s->mb_x + 4 * s->mb_y * b_stride];
+        int16_t(*mv_src)[2] = &h->cur_pic.motion_val[list][4 * h->mb_x + 4 * h->mb_y * b_stride];
         AV_COPY128(mv_dst + 8 * 0, mv_src + 0 * b_stride);
         AV_COPY128(mv_dst + 8 * 1, mv_src + 1 * b_stride);
         AV_COPY128(mv_dst + 8 * 2, mv_src + 2 * b_stride);
@@ -3382,31 +4049,30 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
  */
 static int fill_filter_caches(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int top_xy, left_xy[LEFT_MBS];
     int top_type, left_type[LEFT_MBS];
     uint8_t *nnz;
     uint8_t *nnz_cache;
 
-    top_xy = mb_xy - (s->mb_stride << MB_FIELD);
+    top_xy = mb_xy - (h->mb_stride << MB_FIELD(h));
 
     /* Wow, what a mess, why didn't they simplify the interlacing & intra
      * stuff, I can't imagine that these complex rules are worth it. */
 
     left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
-    if (FRAME_MBAFF) {
-        const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
+    if (FRAME_MBAFF(h)) {
+        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]);
         const int curr_mb_field_flag = IS_INTERLACED(mb_type);
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (left_mb_field_flag != curr_mb_field_flag)
-                left_xy[LTOP] -= s->mb_stride;
+                left_xy[LTOP] -= h->mb_stride;
         } else {
             if (curr_mb_field_flag)
-                top_xy += s->mb_stride &
-                    (((s->current_picture.f.mb_type[top_xy] >> 7) & 1) - 1);
+                top_xy += h->mb_stride &
+                          (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1);
             if (left_mb_field_flag != curr_mb_field_flag)
-                left_xy[LBOT] += s->mb_stride;
+                left_xy[LBOT] += h->mb_stride;
         }
     }
 
@@ -3418,25 +4084,25 @@ static int fill_filter_caches(H264Context *h, int mb_type)
          * This is a conservative estimate: could also check beta_offset
          * and more accurate chroma_qp. */
         int qp_thresh = h->qp_thresh; // FIXME strictly we should store qp_thresh for each mb of a slice
-        int qp        = s->current_picture.f.qscale_table[mb_xy];
+        int qp        = h->cur_pic.qscale_table[mb_xy];
         if (qp <= qp_thresh &&
             (left_xy[LTOP] < 0 ||
-             ((qp + s->current_picture.f.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&
+             ((qp + h->cur_pic.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&
             (top_xy < 0 ||
-             ((qp + s->current_picture.f.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {
-            if (!FRAME_MBAFF)
+             ((qp + h->cur_pic.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {
+            if (!FRAME_MBAFF(h))
                 return 1;
             if ((left_xy[LTOP] < 0 ||
-                 ((qp + s->current_picture.f.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&
-                (top_xy < s->mb_stride ||
-                 ((qp + s->current_picture.f.qscale_table[top_xy - s->mb_stride] + 1) >> 1) <= qp_thresh))
+                 ((qp + h->cur_pic.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&
+                (top_xy < h->mb_stride ||
+                 ((qp + h->cur_pic.qscale_table[top_xy - h->mb_stride] + 1) >> 1) <= qp_thresh))
                 return 1;
         }
     }
 
-    top_type        = s->current_picture.f.mb_type[top_xy];
-    left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
-    left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
+    top_type        = h->cur_pic.mb_type[top_xy];
+    left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]];
+    left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]];
     if (h->deblocking_filter == 2) {
         if (h->slice_table[top_xy] != h->slice_num)
             top_type = 0;
@@ -3455,10 +4121,10 @@ static int fill_filter_caches(H264Context *h, int mb_type)
     if (IS_INTRA(mb_type))
         return 0;
 
-    fill_filter_caches_inter(h, s, mb_type, top_xy, left_xy,
+    fill_filter_caches_inter(h, mb_type, top_xy, left_xy,
                              top_type, left_type, mb_xy, 0);
     if (h->list_count == 2)
-        fill_filter_caches_inter(h, s, mb_type, top_xy, left_xy,
+        fill_filter_caches_inter(h, mb_type, top_xy, left_xy,
                                  top_type, left_type, mb_xy, 1);
 
     nnz       = h->non_zero_count[mb_xy];
@@ -3484,20 +4150,20 @@ static int fill_filter_caches(H264Context *h, int mb_type)
 
     /* CAVLC 8x8dct requires NNZ values for residual decoding that differ
      * from what the loop filter needs */
-    if (!CABAC && h->pps.transform_8x8_mode) {
+    if (!CABAC(h) && h->pps.transform_8x8_mode) {
         if (IS_8x8DCT(top_type)) {
-            nnz_cache[4 + 8 * 0]     =
-                nnz_cache[5 + 8 * 0] = (h->cbp_table[top_xy] & 0x4000) >> 12;
-            nnz_cache[6 + 8 * 0]     =
-                nnz_cache[7 + 8 * 0] = (h->cbp_table[top_xy] & 0x8000) >> 12;
+            nnz_cache[4 + 8 * 0] =
+            nnz_cache[5 + 8 * 0] = (h->cbp_table[top_xy] & 0x4000) >> 12;
+            nnz_cache[6 + 8 * 0] =
+            nnz_cache[7 + 8 * 0] = (h->cbp_table[top_xy] & 0x8000) >> 12;
         }
         if (IS_8x8DCT(left_type[LTOP])) {
-            nnz_cache[3 + 8 * 1]     =
-                nnz_cache[3 + 8 * 2] = (h->cbp_table[left_xy[LTOP]] & 0x2000) >> 12; // FIXME check MBAFF
+            nnz_cache[3 + 8 * 1] =
+            nnz_cache[3 + 8 * 2] = (h->cbp_table[left_xy[LTOP]] & 0x2000) >> 12; // FIXME check MBAFF
         }
         if (IS_8x8DCT(left_type[LBOT])) {
-            nnz_cache[3 + 8 * 3]     =
-                nnz_cache[3 + 8 * 4] = (h->cbp_table[left_xy[LBOT]] & 0x8000) >> 12; // FIXME check MBAFF
+            nnz_cache[3 + 8 * 3] =
+            nnz_cache[3 + 8 * 4] = (h->cbp_table[left_xy[LBOT]] & 0x8000) >> 12; // FIXME check MBAFF
         }
 
         if (IS_8x8DCT(mb_type)) {
@@ -3528,59 +4194,58 @@ static int fill_filter_caches(H264Context *h, int mb_type)
 
 static void loop_filter(H264Context *h, int start_x, int end_x)
 {
-    MpegEncContext *const s = &h->s;
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize, mb_x, mb_y;
-    const int end_mb_y       = s->mb_y + FRAME_MBAFF;
+    const int end_mb_y       = h->mb_y + FRAME_MBAFF(h);
     const int old_slice_type = h->slice_type;
     const int pixel_shift    = h->pixel_shift;
-    const int block_h        = 16 >> s->chroma_y_shift;
+    const int block_h        = 16 >> h->chroma_y_shift;
 
     if (h->deblocking_filter) {
         for (mb_x = start_x; mb_x < end_x; mb_x++)
-            for (mb_y = end_mb_y - FRAME_MBAFF; mb_y <= end_mb_y; mb_y++) {
+            for (mb_y = end_mb_y - FRAME_MBAFF(h); mb_y <= end_mb_y; mb_y++) {
                 int mb_xy, mb_type;
-                mb_xy         = h->mb_xy = mb_x + mb_y * s->mb_stride;
+                mb_xy         = h->mb_xy = mb_x + mb_y * h->mb_stride;
                 h->slice_num  = h->slice_table[mb_xy];
-                mb_type       = s->current_picture.f.mb_type[mb_xy];
+                mb_type       = h->cur_pic.mb_type[mb_xy];
                 h->list_count = h->list_counts[mb_xy];
 
-                if (FRAME_MBAFF)
+                if (FRAME_MBAFF(h))
                     h->mb_mbaff               =
                     h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type);
 
-                s->mb_x = mb_x;
-                s->mb_y = mb_y;
-                dest_y  = s->current_picture.f.data[0] +
-                          ((mb_x << pixel_shift) + mb_y * s->linesize) * 16;
-                dest_cb = s->current_picture.f.data[1] +
-                          (mb_x << pixel_shift) * (8 << CHROMA444) +
-                          mb_y * s->uvlinesize * block_h;
-                dest_cr = s->current_picture.f.data[2] +
-                          (mb_x << pixel_shift) * (8 << CHROMA444) +
-                          mb_y * s->uvlinesize * block_h;
+                h->mb_x = mb_x;
+                h->mb_y = mb_y;
+                dest_y  = h->cur_pic.f.data[0] +
+                          ((mb_x << pixel_shift) + mb_y * h->linesize) * 16;
+                dest_cb = h->cur_pic.f.data[1] +
+                          (mb_x << pixel_shift) * (8 << CHROMA444(h)) +
+                          mb_y * h->uvlinesize * block_h;
+                dest_cr = h->cur_pic.f.data[2] +
+                          (mb_x << pixel_shift) * (8 << CHROMA444(h)) +
+                          mb_y * h->uvlinesize * block_h;
                 // FIXME simplify above
 
-                if (MB_FIELD) {
-                    linesize   = h->mb_linesize   = s->linesize   * 2;
-                    uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;
+                if (MB_FIELD(h)) {
+                    linesize   = h->mb_linesize   = h->linesize   * 2;
+                    uvlinesize = h->mb_uvlinesize = h->uvlinesize * 2;
                     if (mb_y & 1) { // FIXME move out of this function?
-                        dest_y  -= s->linesize   * 15;
-                        dest_cb -= s->uvlinesize * (block_h - 1);
-                        dest_cr -= s->uvlinesize * (block_h - 1);
+                        dest_y  -= h->linesize   * 15;
+                        dest_cb -= h->uvlinesize * (block_h - 1);
+                        dest_cr -= h->uvlinesize * (block_h - 1);
                     }
                 } else {
-                    linesize   = h->mb_linesize   = s->linesize;
-                    uvlinesize = h->mb_uvlinesize = s->uvlinesize;
+                    linesize   = h->mb_linesize   = h->linesize;
+                    uvlinesize = h->mb_uvlinesize = h->uvlinesize;
                 }
                 backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
                                  uvlinesize, 0);
                 if (fill_filter_caches(h, mb_type))
                     continue;
-                h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mb_xy]);
-                h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mb_xy]);
+                h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]);
+                h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]);
 
-                if (FRAME_MBAFF) {
+                if (FRAME_MBAFF(h)) {
                     ff_h264_filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr,
                                       linesize, uvlinesize);
                 } else {
@@ -3590,20 +4255,19 @@ static void loop_filter(H264Context *h, int start_x, int end_x)
             }
     }
     h->slice_type   = old_slice_type;
-    s->mb_x         = end_x;
-    s->mb_y         = end_mb_y - FRAME_MBAFF;
-    h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+    h->mb_x         = end_x;
+    h->mb_y         = end_mb_y - FRAME_MBAFF(h);
+    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
 }
 
 static void predict_field_decoding_flag(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_xy = s->mb_x + s->mb_y * s->mb_stride;
+    const int mb_xy = h->mb_x + h->mb_y * h->mb_stride;
     int mb_type     = (h->slice_table[mb_xy - 1] == h->slice_num) ?
-                      s->current_picture.f.mb_type[mb_xy - 1] :
-                      (h->slice_table[mb_xy - s->mb_stride] == h->slice_num) ?
-                      s->current_picture.f.mb_type[mb_xy - s->mb_stride] : 0;
+                      h->cur_pic.mb_type[mb_xy - 1] :
+                      (h->slice_table[mb_xy - h->mb_stride] == h->slice_num) ?
+                      h->cur_pic.mb_type[mb_xy - h->mb_stride] : 0;
     h->mb_mbaff     = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0;
 }
 
@@ -3612,11 +4276,10 @@ static void predict_field_decoding_flag(H264Context *h)
  */
 static void decode_finish_row(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    int top            = 16 * (s->mb_y      >> FIELD_PICTURE);
-    int pic_height     = 16 *  s->mb_height >> FIELD_PICTURE;
-    int height         =  16      << FRAME_MBAFF;
-    int deblock_border = (16 + 4) << FRAME_MBAFF;
+    int top            = 16 * (h->mb_y      >> FIELD_PICTURE(h));
+    int pic_height     = 16 *  h->mb_height >> FIELD_PICTURE(h);
+    int height         =  16      << FRAME_MBAFF(h);
+    int deblock_border = (16 + 4) << FRAME_MBAFF(h);
 
     if (h->deblocking_filter) {
         if ((top + height) >= pic_height)
@@ -3624,47 +4287,54 @@ static void decode_finish_row(H264Context *h)
         top -= deblock_border;
     }
 
-    if (top >= pic_height || (top + height) < h->emu_edge_height)
+    if (top >= pic_height || (top + height) < 0)
         return;
 
     height = FFMIN(height, pic_height - top);
-    if (top < h->emu_edge_height) {
+    if (top < 0) {
         height = top + height;
         top    = 0;
     }
 
-    ff_draw_horiz_band(s, top, height);
+    ff_h264_draw_horiz_band(h, top, height);
 
-    if (s->droppable)
+    if (h->droppable)
         return;
 
-    ff_thread_report_progress(&s->current_picture_ptr->f, top + height - 1,
-                              s->picture_structure == PICT_BOTTOM_FIELD);
+    ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1,
+                              h->picture_structure == PICT_BOTTOM_FIELD);
+}
+
+static void er_add_slice(H264Context *h, int startx, int starty,
+                         int endx, int endy, int status)
+{
+#if CONFIG_ERROR_RESILIENCE
+    ERContext *er = &h->er;
+
+    er->ref_count = h->ref_count[0];
+    ff_er_add_slice(er, startx, starty, endx, endy, status);
+#endif
 }
 
 static int decode_slice(struct AVCodecContext *avctx, void *arg)
 {
     H264Context *h = *(void **)arg;
-    MpegEncContext *const s = &h->s;
-    const int part_mask     = s->partitioned_frame ? (ER_AC_END | ER_AC_ERROR)
-                                                   : 0x7F;
-    int lf_x_start = s->mb_x;
+    int lf_x_start = h->mb_x;
 
-    s->mb_skip_run = -1;
+    h->mb_skip_run = -1;
 
-    h->is_complex = FRAME_MBAFF || s->picture_structure != PICT_FRAME ||
-                    s->codec_id != AV_CODEC_ID_H264 ||
-                    (CONFIG_GRAY && (s->flags & CODEC_FLAG_GRAY));
+    h->is_complex = FRAME_MBAFF(h) || h->picture_structure != PICT_FRAME ||
+                    avctx->codec_id != AV_CODEC_ID_H264 ||
+                    (CONFIG_GRAY && (h->flags & CODEC_FLAG_GRAY));
 
     if (h->pps.cabac) {
         /* realign */
-        align_get_bits(&s->gb);
+        align_get_bits(&h->gb);
 
         /* init cabac */
-        ff_init_cabac_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);
+                              h->gb.buffer + get_bits_count(&h->gb) / 8,
+                              (get_bits_left(&h->gb) + 7) / 8);
 
         ff_h264_init_cabac_states(h);
 
@@ -3678,54 +4348,54 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                 ff_h264_hl_decode_mb(h);
 
             // FIXME optimal? or let mb_decode decode 16x32 ?
-            if (ret >= 0 && FRAME_MBAFF) {
-                s->mb_y++;
+            if (ret >= 0 && FRAME_MBAFF(h)) {
+                h->mb_y++;
 
                 ret = ff_h264_decode_mb_cabac(h);
 
                 if (ret >= 0)
                     ff_h264_hl_decode_mb(h);
-                s->mb_y--;
+                h->mb_y--;
             }
             eos = get_cabac_terminate(&h->cabac);
 
-            if ((s->workaround_bugs & FF_BUG_TRUNCATED) &&
+            if ((h->workaround_bugs & FF_BUG_TRUNCATED) &&
                 h->cabac.bytestream > h->cabac.bytestream_end + 2) {
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
-                                s->mb_y, ER_MB_END & part_mask);
-                if (s->mb_x >= lf_x_start)
-                    loop_filter(h, lf_x_start, s->mb_x + 1);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
+                             h->mb_y, ER_MB_END);
+                if (h->mb_x >= lf_x_start)
+                    loop_filter(h, lf_x_start, h->mb_x + 1);
                 return 0;
             }
             if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
+                av_log(h->avctx, AV_LOG_ERROR,
                        "error while decoding MB %d %d, bytestream (%td)\n",
-                       s->mb_x, s->mb_y,
+                       h->mb_x, h->mb_y,
                        h->cabac.bytestream_end - h->cabac.bytestream);
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                s->mb_y, ER_MB_ERROR & part_mask);
-                return -1;
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                             h->mb_y, ER_MB_ERROR);
+                return AVERROR_INVALIDDATA;
             }
 
-            if (++s->mb_x >= s->mb_width) {
-                loop_filter(h, lf_x_start, s->mb_x);
-                s->mb_x = lf_x_start = 0;
+            if (++h->mb_x >= h->mb_width) {
+                loop_filter(h, lf_x_start, h->mb_x);
+                h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
-                ++s->mb_y;
-                if (FIELD_OR_MBAFF_PICTURE) {
-                    ++s->mb_y;
-                    if (FRAME_MBAFF && s->mb_y < s->mb_height)
+                ++h->mb_y;
+                if (FIELD_OR_MBAFF_PICTURE(h)) {
+                    ++h->mb_y;
+                    if (FRAME_MBAFF(h) && h->mb_y < h->mb_height)
                         predict_field_decoding_flag(h);
                 }
             }
 
-            if (eos || s->mb_y >= s->mb_height) {
-                tprintf(s->avctx, "slice end %d %d\n",
-                        get_bits_count(&s->gb), s->gb.size_in_bits);
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1,
-                                s->mb_y, ER_MB_END & part_mask);
-                if (s->mb_x > lf_x_start)
-                    loop_filter(h, lf_x_start, s->mb_x);
+            if (eos || h->mb_y >= h->mb_height) {
+                tprintf(h->avctx, "slice end %d %d\n",
+                        get_bits_count(&h->gb), h->gb.size_in_bits);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
+                             h->mb_y, ER_MB_END);
+                if (h->mb_x > lf_x_start)
+                    loop_filter(h, lf_x_start, h->mb_x);
                 return 0;
             }
         }
@@ -3737,69 +4407,70 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                 ff_h264_hl_decode_mb(h);
 
             // FIXME optimal? or let mb_decode decode 16x32 ?
-            if (ret >= 0 && FRAME_MBAFF) {
-                s->mb_y++;
+            if (ret >= 0 && FRAME_MBAFF(h)) {
+                h->mb_y++;
                 ret = ff_h264_decode_mb_cavlc(h);
 
                 if (ret >= 0)
                     ff_h264_hl_decode_mb(h);
-                s->mb_y--;
+                h->mb_y--;
             }
 
             if (ret < 0) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
-                       "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                s->mb_y, ER_MB_ERROR & part_mask);
-                return -1;
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "error while decoding MB %d %d\n", h->mb_x, h->mb_y);
+                er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                             h->mb_y, ER_MB_ERROR);
+                return ret;
             }
 
-            if (++s->mb_x >= s->mb_width) {
-                loop_filter(h, lf_x_start, s->mb_x);
-                s->mb_x = lf_x_start = 0;
+            if (++h->mb_x >= h->mb_width) {
+                loop_filter(h, lf_x_start, h->mb_x);
+                h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
-                ++s->mb_y;
-                if (FIELD_OR_MBAFF_PICTURE) {
-                    ++s->mb_y;
-                    if (FRAME_MBAFF && s->mb_y < s->mb_height)
+                ++h->mb_y;
+                if (FIELD_OR_MBAFF_PICTURE(h)) {
+                    ++h->mb_y;
+                    if (FRAME_MBAFF(h) && h->mb_y < h->mb_height)
                         predict_field_decoding_flag(h);
                 }
-                if (s->mb_y >= s->mb_height) {
-                    tprintf(s->avctx, "slice end %d %d\n",
-                            get_bits_count(&s->gb), s->gb.size_in_bits);
+                if (h->mb_y >= h->mb_height) {
+                    tprintf(h->avctx, "slice end %d %d\n",
+                            get_bits_count(&h->gb), h->gb.size_in_bits);
 
-                    if (get_bits_left(&s->gb) == 0) {
-                        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
-                                        s->mb_x - 1, s->mb_y,
-                                        ER_MB_END & part_mask);
+                    if (get_bits_left(&h->gb) == 0) {
+                        er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                                     h->mb_x - 1, h->mb_y,
+                                     ER_MB_END);
 
                         return 0;
                     } else {
-                        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
-                                        s->mb_x - 1, s->mb_y,
-                                        ER_MB_END & part_mask);
+                        er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                                     h->mb_x - 1, h->mb_y,
+                                     ER_MB_END);
 
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                 }
             }
 
-            if (get_bits_left(&s->gb) <= 0 && s->mb_skip_run <= 0) {
-                tprintf(s->avctx, "slice end %d %d\n",
-                        get_bits_count(&s->gb), s->gb.size_in_bits);
-                if (get_bits_left(&s->gb) == 0) {
-                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
-                                    s->mb_x - 1, s->mb_y,
-                                    ER_MB_END & part_mask);
-                    if (s->mb_x > lf_x_start)
-                        loop_filter(h, lf_x_start, s->mb_x);
+            if (get_bits_left(&h->gb) <= 0 && h->mb_skip_run <= 0) {
+                tprintf(h->avctx, "slice end %d %d\n",
+                        get_bits_count(&h->gb), h->gb.size_in_bits);
+
+                if (get_bits_left(&h->gb) == 0) {
+                    er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
+                                 h->mb_x - 1, h->mb_y,
+                                 ER_MB_END);
+                    if (h->mb_x > lf_x_start)
+                        loop_filter(h, lf_x_start, h->mb_x);
 
                     return 0;
                 } else {
-                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x,
-                                    s->mb_y, ER_MB_ERROR & part_mask);
+                    er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x,
+                                 h->mb_y, ER_MB_ERROR);
 
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
             }
         }
@@ -3814,21 +4485,18 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
  */
 static int execute_decode_slices(H264Context *h, int context_count)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     H264Context *hx;
     int i;
 
-    if (s->avctx->hwaccel ||
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+    if (h->avctx->hwaccel)
         return 0;
     if (context_count == 1) {
         return decode_slice(avctx, &h);
     } else {
         for (i = 1; i < context_count; i++) {
-            hx                    = h->thread_context[i];
-            hx->s.err_recognition = avctx->err_recognition;
-            hx->s.error_count     = 0;
+            hx                 = h->thread_context[i];
+            hx->er.error_count = 0;
         }
 
         avctx->execute(avctx, decode_slice, h->thread_context,
@@ -3836,12 +4504,12 @@ static int execute_decode_slices(H264Context *h, int context_count)
 
         /* pull back stuff from slices to master context */
         hx                   = h->thread_context[context_count - 1];
-        s->mb_x              = hx->s.mb_x;
-        s->mb_y              = hx->s.mb_y;
-        s->droppable         = hx->s.droppable;
-        s->picture_structure = hx->s.picture_structure;
+        h->mb_x              = hx->mb_x;
+        h->mb_y              = hx->mb_y;
+        h->droppable         = hx->droppable;
+        h->picture_structure = hx->picture_structure;
         for (i = 1; i < context_count; i++)
-            h->s.error_count += h->thread_context[i]->s.error_count;
+            h->er.error_count += h->thread_context[i]->er.error_count;
     }
 
     return 0;
@@ -3850,8 +4518,7 @@ static int execute_decode_slices(H264Context *h, int context_count)
 static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                             int parse_extradata)
 {
-    MpegEncContext *const s     = &h->s;
-    AVCodecContext *const avctx = s->avctx;
+    AVCodecContext *const avctx = h->avctx;
     H264Context *hx; ///< thread context
     int buf_index;
     int context_count;
@@ -3859,12 +4526,13 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
     int pass = !(avctx->active_thread_type & FF_THREAD_FRAME);
     int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts
     int nal_index;
+    int ret = 0;
 
-    h->max_contexts = s->slice_context_count;
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS)) {
+    h->max_contexts = h->slice_context_count;
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) {
         h->current_slice = 0;
-        if (!s->first_field)
-            s->current_picture_ptr = NULL;
+        if (!h->first_field)
+            h->cur_pic_ptr = NULL;
         ff_h264_reset_sei(h);
     }
 
@@ -3888,7 +4556,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                 for (i = 0; i < h->nal_length_size; i++)
                     nalsize = (nalsize << 8) | buf[buf_index++];
                 if (nalsize <= 0 || nalsize > buf_size - buf_index) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "AVC: nal size %d\n", nalsize);
                     break;
                 }
@@ -3917,29 +4585,29 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
             ptr = ff_h264_decode_nal(hx, buf + buf_index, &dst_length,
                                      &consumed, next_avc - buf_index);
             if (ptr == NULL || dst_length < 0) {
-                buf_index = -1;
+                ret = -1;
                 goto end;
             }
             i = buf_index + consumed;
-            if ((s->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
+            if ((h->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
                 buf[i]     == 0x00 && buf[i + 1] == 0x00 &&
                 buf[i + 2] == 0x01 && buf[i + 3] == 0xE0)
-                s->workaround_bugs |= FF_BUG_TRUNCATED;
+                h->workaround_bugs |= FF_BUG_TRUNCATED;
 
-            if (!(s->workaround_bugs & FF_BUG_TRUNCATED))
-                while (ptr[dst_length - 1] == 0 && dst_length > 0)
+            if (!(h->workaround_bugs & FF_BUG_TRUNCATED))
+                while (dst_length > 0 && ptr[dst_length - 1] == 0)
                     dst_length--;
             bit_length = !dst_length ? 0
                                      : (8 * dst_length -
                                         decode_rbsp_trailing(h, ptr + dst_length - 1));
 
-            if (s->avctx->debug & FF_DEBUG_STARTCODE)
-                av_log(h->s.avctx, AV_LOG_DEBUG,
+            if (h->avctx->debug & FF_DEBUG_STARTCODE)
+                av_log(h->avctx, AV_LOG_DEBUG,
                        "NAL %d at %d/%d length %d\n",
                        hx->nal_unit_type, buf_index, buf_size, dst_length);
 
             if (h->is_avc && (nalsize != consumed) && nalsize)
-                av_log(h->s.avctx, AV_LOG_DEBUG,
+                av_log(h->avctx, AV_LOG_DEBUG,
                        "AVC: Consumed only %d bytes instead of %d\n",
                        consumed, nalsize);
 
@@ -3959,15 +4627,16 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
                 case NAL_DPA:
                 case NAL_IDR_SLICE:
                 case NAL_SLICE:
-                    init_get_bits(&hx->s.gb, ptr, bit_length);
-                    if (!get_ue_golomb(&hx->s.gb))
+                    init_get_bits(&hx->gb, ptr, bit_length);
+                    if (!get_ue_golomb(&hx->gb))
                         nals_needed = nal_index;
                 }
                 continue;
             }
 
-            // FIXME do not discard SEI id
-            if (avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)
+            if (avctx->skip_frame >= AVDISCARD_NONREF &&
+                h->nal_ref_idc == 0 &&
+                h->nal_unit_type != NAL_SEI)
                 continue;
 
 again:
@@ -3975,46 +4644,62 @@ again:
              * parsing. Decoding slices is not possible in codec init
              * with frame-mt */
             if (parse_extradata && HAVE_THREADS &&
-                (s->avctx->active_thread_type & FF_THREAD_FRAME) &&
+                (h->avctx->active_thread_type & FF_THREAD_FRAME) &&
                 (hx->nal_unit_type != NAL_PPS &&
                  hx->nal_unit_type != NAL_SPS)) {
-                av_log(avctx, AV_LOG_INFO, "Ignoring NAL unit %d during "
-                       "extradata parsing\n", hx->nal_unit_type);
+                if (hx->nal_unit_type < NAL_AUD ||
+                    hx->nal_unit_type > NAL_AUXILIARY_SLICE)
+                    av_log(avctx, AV_LOG_INFO,
+                           "Ignoring NAL unit %d during extradata parsing\n",
+                           hx->nal_unit_type);
                 hx->nal_unit_type = NAL_FF_IGNORE;
             }
             err = 0;
             switch (hx->nal_unit_type) {
             case NAL_IDR_SLICE:
                 if (h->nal_unit_type != NAL_IDR_SLICE) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "Invalid mix of idr and non-idr slices\n");
-                    buf_index = -1;
+                    ret = -1;
                     goto end;
                 }
                 idr(h); // FIXME ensure we don't lose some frames if there is reordering
             case NAL_SLICE:
-                init_get_bits(&hx->s.gb, ptr, bit_length);
-                hx->intra_gb_ptr        =
-                    hx->inter_gb_ptr    = &hx->s.gb;
-                hx->s.data_partitioning = 0;
+                init_get_bits(&hx->gb, ptr, bit_length);
+                hx->intra_gb_ptr      =
+                hx->inter_gb_ptr      = &hx->gb;
+                hx->data_partitioning = 0;
 
                 if ((err = decode_slice_header(hx, h)))
                     break;
 
-                s->current_picture_ptr->f.key_frame |=
+                if (h->sei_recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
+                    h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) &
+                                        ((1 << h->sps.log2_max_frame_num) - 1);
+                }
+
+                h->cur_pic_ptr->f.key_frame |=
                     (hx->nal_unit_type == NAL_IDR_SLICE) ||
                     (h->sei_recovery_frame_cnt >= 0);
 
+                if (hx->nal_unit_type == NAL_IDR_SLICE ||
+                    h->recovery_frame == h->frame_num) {
+                    h->recovery_frame         = -1;
+                    h->cur_pic_ptr->recovered = 1;
+                }
+                // If we have an IDR, all frames after it in decoded order are
+                // "recovered".
+                if (hx->nal_unit_type == NAL_IDR_SLICE)
+                    h->frame_recovered |= FRAME_RECOVERED_IDR;
+                h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR);
+
                 if (h->current_slice == 1) {
-                    if (!(s->flags2 & CODEC_FLAG2_CHUNKS))
+                    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS))
                         decode_postinit(h, nal_index >= nals_needed);
 
-                    if (s->avctx->hwaccel &&
-                        s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)
-                        return -1;
-                    if (CONFIG_H264_VDPAU_DECODER &&
-                        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
-                        ff_vdpau_h264_picture_start(s);
+                    if (h->avctx->hwaccel &&
+                        (ret = h->avctx->hwaccel->start_frame(h->avctx, NULL, 0)) < 0)
+                        return ret;
                 }
 
                 if (hx->redundant_pic_count == 0 &&
@@ -4026,31 +4711,24 @@ again:
                      hx->slice_type_nos == AV_PICTURE_TYPE_I) &&
                     avctx->skip_frame < AVDISCARD_ALL) {
                     if (avctx->hwaccel) {
-                        if (avctx->hwaccel->decode_slice(avctx,
-                                                         &buf[buf_index - consumed],
-                                                         consumed) < 0)
-                            return -1;
-                    } else if (CONFIG_H264_VDPAU_DECODER &&
-                               s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
-                        static const uint8_t start_code[] = {
-                            0x00, 0x00, 0x01 };
-                        ff_vdpau_add_data_chunk(s, start_code,
-                                                sizeof(start_code));
-                        ff_vdpau_add_data_chunk(s, &buf[buf_index - consumed],
-                                                consumed);
+                        ret = avctx->hwaccel->decode_slice(avctx,
+                                                           &buf[buf_index - consumed],
+                                                           consumed);
+                        if (ret < 0)
+                            return ret;
                     } else
                         context_count++;
                 }
                 break;
             case NAL_DPA:
-                init_get_bits(&hx->s.gb, ptr, bit_length);
+                init_get_bits(&hx->gb, ptr, bit_length);
                 hx->intra_gb_ptr =
                 hx->inter_gb_ptr = NULL;
 
                 if ((err = decode_slice_header(hx, h)) < 0)
                     break;
 
-                hx->s.data_partitioning = 1;
+                hx->data_partitioning = 1;
                 break;
             case NAL_DPB:
                 init_get_bits(&hx->intra_gb, ptr, bit_length);
@@ -4062,9 +4740,8 @@ again:
 
                 if (hx->redundant_pic_count == 0 &&
                     hx->intra_gb_ptr &&
-                    hx->s.data_partitioning &&
-                    s->current_picture_ptr &&
-                    s->context_initialized &&
+                    hx->data_partitioning &&
+                    h->cur_pic_ptr && h->context_initialized &&
                     (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) &&
                     (avctx->skip_frame < AVDISCARD_BIDIR  ||
                      hx->slice_type_nos != AV_PICTURE_TYPE_B) &&
@@ -4074,27 +4751,27 @@ again:
                     context_count++;
                 break;
             case NAL_SEI:
-                init_get_bits(&s->gb, ptr, bit_length);
+                init_get_bits(&h->gb, ptr, bit_length);
                 ff_h264_decode_sei(h);
                 break;
             case NAL_SPS:
-                init_get_bits(&s->gb, ptr, bit_length);
-                if (ff_h264_decode_seq_parameter_set(h) < 0 &&
-                    h->is_avc && (nalsize != consumed) && nalsize) {
-                    av_log(h->s.avctx, AV_LOG_DEBUG,
+                init_get_bits(&h->gb, ptr, bit_length);
+                ret = ff_h264_decode_seq_parameter_set(h);
+                if (ret < 0 && h->is_avc && (nalsize != consumed) && nalsize) {
+                    av_log(h->avctx, AV_LOG_DEBUG,
                            "SPS decoding failure, trying again with the complete NAL\n");
-                    init_get_bits(&s->gb, buf + buf_index + 1 - consumed,
+                    init_get_bits(&h->gb, buf + buf_index + 1 - consumed,
                                   8 * (nalsize - 1));
                     ff_h264_decode_seq_parameter_set(h);
                 }
 
-                if (h264_set_parameter_from_sps(h) < 0) {
-                    buf_index = -1;
+                ret = h264_set_parameter_from_sps(h);
+                if (ret < 0)
                     goto end;
-                }
+
                 break;
             case NAL_PPS:
-                init_get_bits(&s->gb, ptr, bit_length);
+                init_get_bits(&h->gb, ptr, bit_length);
                 ff_h264_decode_picture_parameter_set(h, bit_length);
                 break;
             case NAL_AUD:
@@ -4117,7 +4794,7 @@ again:
             }
 
             if (err < 0)
-                av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n");
+                av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n");
             else if (err == 1) {
                 /* Slice could not be decoded in parallel mode, copy down
                  * NAL unit stuff to context 0 and restart. Note that
@@ -4135,19 +4812,18 @@ again:
 
 end:
     /* clean up */
-    if (s->current_picture_ptr && s->current_picture_ptr->owner2 == s &&
-        !s->droppable) {
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,
-                                  s->picture_structure == PICT_BOTTOM_FIELD);
+    if (h->cur_pic_ptr && !h->droppable) {
+        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
+                                  h->picture_structure == PICT_BOTTOM_FIELD);
     }
 
-    return buf_index;
+    return (ret < 0) ? ret : buf_index;
 }
 
 /**
  * Return the number of bytes consumed for building the current frame.
  */
-static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size)
+static int get_consumed_bytes(int pos, int buf_size)
 {
     if (pos == 0)
         pos = 1;          // avoid infinite loops (i doubt that is needed but ...)
@@ -4157,18 +4833,37 @@ static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size)
     return pos;
 }
 
+static int output_frame(H264Context *h, AVFrame *dst, AVFrame *src)
+{
+    int i;
+    int ret = av_frame_ref(dst, src);
+    if (ret < 0)
+        return ret;
+
+    if (!h->sps.crop)
+        return 0;
+
+    for (i = 0; i < 3; i++) {
+        int hshift = (i > 0) ? h->chroma_x_shift : 0;
+        int vshift = (i > 0) ? h->chroma_y_shift : 0;
+        int off    = ((h->sps.crop_left >> hshift) << h->pixel_shift) +
+                     (h->sps.crop_top >> vshift) * dst->linesize[i];
+        dst->data[i] += off;
+    }
+    return 0;
+}
+
 static int decode_frame(AVCodecContext *avctx, void *data,
                         int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     H264Context *h     = avctx->priv_data;
-    MpegEncContext *s  = &h->s;
     AVFrame *pict      = data;
     int buf_index      = 0;
+    int ret;
 
-    s->flags  = avctx->flags;
-    s->flags2 = avctx->flags2;
+    h->flags = avctx->flags;
 
     /* end of stream, output what is still in the buffers */
 out:
@@ -4176,7 +4871,7 @@ out:
         Picture *out;
         int i, out_idx;
 
-        s->current_picture_ptr = NULL;
+        h->cur_pic_ptr = NULL;
 
         // FIXME factorize this with the output code below
         out     = h->delayed_pic[0];
@@ -4195,8 +4890,10 @@ out:
             h->delayed_pic[i] = h->delayed_pic[i + 1];
 
         if (out) {
+            ret = output_frame(h, pict, &out->f);
+            if (ret < 0)
+                return ret;
             *got_frame = 1;
-            *pict      = out->f;
         }
 
         return buf_index;
@@ -4204,41 +4901,43 @@ out:
 
     buf_index = decode_nal_units(h, buf, buf_size, 0);
     if (buf_index < 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
-    if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
+    if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
         buf_size = 0;
         goto out;
     }
 
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr) {
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) {
         if (avctx->skip_frame >= AVDISCARD_NONREF)
             return 0;
         av_log(avctx, AV_LOG_ERROR, "no frame!\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if (!(s->flags2 & CODEC_FLAG2_CHUNKS) ||
-        (s->mb_y >= s->mb_height && s->mb_height)) {
-        if (s->flags2 & CODEC_FLAG2_CHUNKS)
+    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||
+        (h->mb_y >= h->mb_height && h->mb_height)) {
+        if (avctx->flags2 & CODEC_FLAG2_CHUNKS)
             decode_postinit(h, 1);
 
         field_end(h, 0);
-        h->context_reinitialized = 0;
 
-        if (!h->next_output_pic) {
-            /* Wait for second field. */
-            *got_frame = 0;
-        } else {
+        *got_frame = 0;
+        if (h->next_output_pic && ((avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT) ||
+                                   h->next_output_pic->recovered)) {
+            if (!h->next_output_pic->recovered)
+                h->next_output_pic->f.flags |= AV_FRAME_FLAG_CORRUPT;
+
+            ret = output_frame(h, pict, &h->next_output_pic->f);
+            if (ret < 0)
+                return ret;
             *got_frame = 1;
-            *pict      = h->next_output_pic->f;
         }
     }
 
-    assert(pict->data[0] || !*got_frame);
-    ff_print_debug_info(s, pict);
+    assert(pict->buf[0] || !*got_frame);
 
-    return get_consumed_bytes(s, buf_index, buf_size);
+    return get_consumed_bytes(buf_index, buf_size);
 }
 
 av_cold void ff_h264_free_context(H264Context *h)
@@ -4256,14 +4955,11 @@ av_cold void ff_h264_free_context(H264Context *h)
 
 static av_cold int h264_decode_end(AVCodecContext *avctx)
 {
-    H264Context *h    = avctx->priv_data;
-    MpegEncContext *s = &h->s;
+    H264Context *h = avctx->priv_data;
 
     ff_h264_free_context(h);
 
-    ff_MPV_common_end(s);
-
-    // memset(h, 0, sizeof(H264Context));
+    unref_picture(h, &h->cur_pic);
 
     return 0;
 }
@@ -4287,6 +4983,7 @@ static const AVProfile profiles[] = {
 
 AVCodec ff_h264_decoder = {
     .name                  = "h264",
+    .long_name             = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
     .type                  = AVMEDIA_TYPE_VIDEO,
     .id                    = AV_CODEC_ID_H264,
     .priv_data_size        = sizeof(H264Context),
@@ -4297,26 +4994,7 @@ AVCodec ff_h264_decoder = {
                              CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS |
                              CODEC_CAP_FRAME_THREADS,
     .flush                 = flush_dpb,
-    .long_name             = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
     .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),
 };
-
-#if CONFIG_H264_VDPAU_DECODER
-AVCodec ff_h264_vdpau_decoder = {
-    .name           = "h264_vdpau",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_H264,
-    .priv_data_size = sizeof(H264Context),
-    .init           = ff_h264_decode_init,
-    .close          = h264_decode_end,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
-    .flush          = flush_dpb,
-    .long_name      = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (VDPAU acceleration)"),
-    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_VDPAU_H264,
-                                                   AV_PIX_FMT_NONE},
-    .profiles       = NULL_IF_CONFIG_SMALL(profiles),
-};
-#endif
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 898ebf7..a828bf9 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -29,16 +29,16 @@
 #define AVCODEC_H264_H
 
 #include "libavutil/intreadwrite.h"
-#include "dsputil.h"
 #include "cabac.h"
+#include "error_resilience.h"
+#include "get_bits.h"
 #include "mpegvideo.h"
+#include "h264chroma.h"
 #include "h264dsp.h"
 #include "h264pred.h"
+#include "h264qpel.h"
 #include "rectangle.h"
 
-#define interlaced_dct interlaced_dct_is_a_bad_name
-#define mb_intra       mb_intra_is_not_initialized_see_mb_type
-
 #define MAX_SPS_COUNT          32
 #define MAX_PPS_COUNT         256
 
@@ -59,19 +59,19 @@
 #define MAX_SLICES 16
 
 #ifdef ALLOW_INTERLACE
-#define MB_MBAFF    h->mb_mbaff
-#define MB_FIELD    h->mb_field_decoding_flag
-#define FRAME_MBAFF h->mb_aff_frame
-#define FIELD_PICTURE (s->picture_structure != PICT_FRAME)
+#define MB_MBAFF(h)    h->mb_mbaff
+#define MB_FIELD(h)    h->mb_field_decoding_flag
+#define FRAME_MBAFF(h) h->mb_aff_frame
+#define FIELD_PICTURE(h) (h->picture_structure != PICT_FRAME)
 #define LEFT_MBS 2
 #define LTOP     0
 #define LBOT     1
 #define LEFT(i)  (i)
 #else
-#define MB_MBAFF      0
-#define MB_FIELD      0
-#define FRAME_MBAFF   0
-#define FIELD_PICTURE 0
+#define MB_MBAFF(h)      0
+#define MB_FIELD(h)      0
+#define FRAME_MBAFF(h)   0
+#define FIELD_PICTURE(h) 0
 #undef  IS_INTERLACED
 #define IS_INTERLACED(mb_type) 0
 #define LEFT_MBS 1
@@ -79,14 +79,14 @@
 #define LBOT     0
 #define LEFT(i)  0
 #endif
-#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE)
+#define FIELD_OR_MBAFF_PICTURE(h) (FRAME_MBAFF(h) || FIELD_PICTURE(h))
 
 #ifndef CABAC
-#define CABAC h->pps.cabac
+#define CABAC(h) h->pps.cabac
 #endif
 
-#define CHROMA422 (h->sps.chroma_format_idc == 2)
-#define CHROMA444 (h->sps.chroma_format_idc == 3)
+#define CHROMA422(h) (h->sps.chroma_format_idc == 2)
+#define CHROMA444(h) (h->sps.chroma_format_idc == 3)
 
 #define EXTENDED_SAR       255
 
@@ -123,7 +123,8 @@ typedef enum {
     SEI_BUFFERING_PERIOD            = 0,   ///< buffering period (H.264, D.1.1)
     SEI_TYPE_PIC_TIMING             = 1,   ///< picture timing
     SEI_TYPE_USER_DATA_UNREGISTERED = 5,   ///< unregistered user data
-    SEI_TYPE_RECOVERY_POINT         = 6    ///< recovery point (frame # to decoder sync)
+    SEI_TYPE_RECOVERY_POINT         = 6,   ///< recovery point (frame # to decoder sync)
+    SEI_TYPE_FRAME_PACKING          = 45,  ///< frame packing arrangement
 } SEI_Type;
 
 /**
@@ -164,6 +165,8 @@ typedef struct SPS {
     int mb_aff;                        ///< mb_adaptive_frame_field_flag
     int direct_8x8_inference_flag;
     int crop;                          ///< frame_cropping_flag
+
+    /* those 4 are already in luma samples */
     unsigned int crop_left;            ///< frame_cropping_rect_left_offset
     unsigned int crop_right;           ///< frame_cropping_rect_right_offset
     unsigned int crop_top;             ///< frame_cropping_rect_top_offset
@@ -252,13 +255,41 @@ typedef struct MMCO {
  * H264Context
  */
 typedef struct H264Context {
-    MpegEncContext s;
+    AVCodecContext *avctx;
+    DSPContext       dsp;
+    VideoDSPContext vdsp;
     H264DSPContext h264dsp;
+    H264ChromaContext h264chroma;
+    H264QpelContext h264qpel;
+    MotionEstContext me;
+    ParseContext parse_context;
+    GetBitContext gb;
+    ERContext er;
+
+    Picture *DPB;
+    Picture *cur_pic_ptr;
+    Picture cur_pic;
+
     int pixel_shift;    ///< 0 for 8-bit H264, 1 for high-bit-depth H264
     int chroma_qp[2];   // QPc
 
     int qp_thresh;      ///< QP threshold to skip loopfilter
 
+    /* coded dimensions -- 16 * mb w/h */
+    int width, height;
+    ptrdiff_t linesize, uvlinesize;
+    int chroma_x_shift, chroma_y_shift;
+
+    int qscale;
+    int droppable;
+    int data_partitioning;
+    int coded_picture_number;
+    int low_delay;
+
+    int context_initialized;
+    int flags;
+    int workaround_bugs;
+
     int prev_mb_skipped;
     int next_mb_skipped;
 
@@ -319,11 +350,8 @@ typedef struct H264Context {
     uint32_t *mb2br_xy;
     int b_stride;       // FIXME use s->b4_stride
 
-    int mb_linesize;    ///< may be equal to s->linesize or s->linesize * 2, for mbaff
-    int mb_uvlinesize;
-
-    int emu_edge_width;
-    int emu_edge_height;
+    ptrdiff_t mb_linesize;  ///< may be equal to s->linesize or s->linesize * 2, for mbaff
+    ptrdiff_t mb_uvlinesize;
 
     unsigned current_sps_id; ///< id of the current SPS
     SPS sps; ///< current sps
@@ -348,6 +376,8 @@ typedef struct H264Context {
     int mb_aff_frame;
     int mb_field_decoding_flag;
     int mb_mbaff;               ///< mb_aff_frame && mb_field_decoding_flag
+    int picture_structure;
+    int first_field;
 
     DECLARE_ALIGNED(8, uint16_t, sub_mb_type)[4];
 
@@ -386,9 +416,10 @@ typedef struct H264Context {
     GetBitContext *intra_gb_ptr;
     GetBitContext *inter_gb_ptr;
 
-    DECLARE_ALIGNED(16, DCTELEM, mb)[16 * 48 * 2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space.
-    DECLARE_ALIGNED(16, DCTELEM, mb_luma_dc)[3][16 * 2];
-    DCTELEM mb_padding[256 * 2];        ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb
+    const uint8_t *intra_pcm_ptr;
+    DECLARE_ALIGNED(16, int16_t, mb)[16 * 48 * 2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space.
+    DECLARE_ALIGNED(16, int16_t, mb_luma_dc)[3][16 * 2];
+    int16_t mb_padding[256 * 2];        ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb
 
     /**
      * Cabac
@@ -424,6 +455,13 @@ typedef struct H264Context {
 
     int x264_build;
 
+    int mb_x, mb_y;
+    int resync_mb_x;
+    int resync_mb_y;
+    int mb_skip_run;
+    int mb_height, mb_width;
+    int mb_stride;
+    int mb_num;
     int mb_xy;
 
     int is_complex;
@@ -448,7 +486,8 @@ typedef struct H264Context {
     int nal_length_size;  ///< Number of bytes used for nal length (1, 2 or 4)
     int got_first;        ///< this flag is != 0 if we've parsed a frame
 
-    int context_reinitialized;
+    int bit_depth_luma;         ///< luma bit depth from sps to detect changes
+    int chroma_format_idc;      ///< chroma format from sps to detect changes
 
     SPS *sps_buffers[MAX_SPS_COUNT];
     PPS *pps_buffers[MAX_PPS_COUNT];
@@ -481,9 +520,9 @@ typedef struct H264Context {
 
     int redundant_pic_count;
 
+    Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture
     Picture *short_ref[32];
     Picture *long_ref[32];
-    Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture
     Picture *delayed_pic[MAX_DELAYED_PIC_COUNT + 2]; // FIXME size?
     int last_pocs[MAX_DELAYED_PIC_COUNT];
     Picture *next_output_pic;
@@ -521,12 +560,16 @@ typedef struct H264Context {
      */
     int max_contexts;
 
+    int slice_context_count;
+
     /**
      *  1 if the single thread fallback warning has already been
      *  displayed, 0 otherwise.
      */
     int single_decode_warning;
 
+    enum AVPictureType pict_type;
+
     int last_slice_type;
     /** @} */
 
@@ -544,6 +587,14 @@ typedef struct H264Context {
     int prev_interlaced_frame;
 
     /**
+     * frame_packing_arrangment SEI message
+     */
+    int sei_frame_packing_present;
+    int frame_packing_arrangement_type;
+    int content_interpretation_type;
+    int quincunx_subsampling;
+
+    /**
      * Bit set of clock types for fields/frames in picture timing SEI message.
      * For each found ct_type, appropriate bit is set (e.g., bit 1 for
      * interlaced).
@@ -569,6 +620,27 @@ typedef struct H264Context {
      */
     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;
+
+/**
+ * We have seen an IDR, so all the following frames in coded order are correctly
+ * decodable.
+ */
+#define FRAME_RECOVERED_IDR  (1 << 0)
+/**
+ * Sufficient number of frames have been decoded since a SEI recovery point,
+ * so all the following frames in presentation order are correct.
+ */
+#define FRAME_RECOVERED_SEI  (1 << 1)
+
+    int frame_recovered;    ///< Initial frame has been completely recovered
+
     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,6 +650,13 @@ typedef struct H264Context {
 
     int cur_chroma_format_idc;
     uint8_t *bipred_scratchpad;
+    uint8_t *edge_emu_buffer;
+    int16_t *dc_val_base;
+
+    AVBufferPool *qscale_table_pool;
+    AVBufferPool *mb_type_pool;
+    AVBufferPool *motion_val_pool;
+    AVBufferPool *ref_index_pool;
 } 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).
@@ -618,7 +697,7 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src,
  * Free any data that may have been allocated in the H264 context
  * like SPS, PPS etc.
  */
-av_cold void ff_h264_free_context(H264Context *h);
+void ff_h264_free_context(H264Context *h);
 
 /**
  * Reconstruct bitstream slice_type.
@@ -663,10 +742,9 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h);
 int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma);
 
 void ff_h264_hl_decode_mb(H264Context *h);
-int ff_h264_frame_start(H264Context *h);
 int ff_h264_decode_extradata(H264Context *h);
-av_cold int ff_h264_decode_init(AVCodecContext *avctx);
-av_cold void ff_h264_decode_init_vlc(void);
+int ff_h264_decode_init(AVCodecContext *avctx);
+void ff_h264_decode_init_vlc(void);
 
 /**
  * Decode a macroblock
@@ -786,7 +864,7 @@ static av_always_inline int pred_intra_mode(H264Context *h, int n)
     const int top    = h->intra4x4_pred_mode_cache[index8 - 8];
     const int min    = FFMIN(left, top);
 
-    tprintf(h->s.avctx, "mode:%d %d min:%d\n", left, top, min);
+    tprintf(h->avctx, "mode:%d %d min:%d\n", left, top, min);
 
     if (min < 0)
         return DC_PRED;
@@ -820,7 +898,7 @@ static av_always_inline void write_back_non_zero_count(H264Context *h)
     AV_COPY32(&nnz[32], &nnz_cache[4 + 8 * 11]);
     AV_COPY32(&nnz[36], &nnz_cache[4 + 8 * 12]);
 
-    if (!h->s.chroma_y_shift) {
+    if (!h->chroma_y_shift) {
         AV_COPY32(&nnz[24], &nnz_cache[4 + 8 * 8]);
         AV_COPY32(&nnz[28], &nnz_cache[4 + 8 * 9]);
         AV_COPY32(&nnz[40], &nnz_cache[4 + 8 * 13]);
@@ -829,18 +907,17 @@ static av_always_inline void write_back_non_zero_count(H264Context *h)
 }
 
 static av_always_inline void write_back_motion_list(H264Context *h,
-                                                    MpegEncContext *const s,
                                                     int b_stride,
                                                     int b_xy, int b8_xy,
                                                     int mb_type, int list)
 {
-    int16_t(*mv_dst)[2] = &s->current_picture.f.motion_val[list][b_xy];
+    int16_t(*mv_dst)[2] = &h->cur_pic.motion_val[list][b_xy];
     int16_t(*mv_src)[2] = &h->mv_cache[list][scan8[0]];
     AV_COPY128(mv_dst + 0 * b_stride, mv_src + 8 * 0);
     AV_COPY128(mv_dst + 1 * b_stride, mv_src + 8 * 1);
     AV_COPY128(mv_dst + 2 * b_stride, mv_src + 8 * 2);
     AV_COPY128(mv_dst + 3 * b_stride, mv_src + 8 * 3);
-    if (CABAC) {
+    if (CABAC(h)) {
         uint8_t (*mvd_dst)[2] = &h->mvd_table[list][FMO ? 8 * h->mb_xy
                                                         : h->mb2br_xy[h->mb_xy]];
         uint8_t(*mvd_src)[2]  = &h->mvd_cache[list][scan8[0]];
@@ -855,7 +932,7 @@ static av_always_inline void write_back_motion_list(H264Context *h,
     }
 
     {
-        int8_t *ref_index = &s->current_picture.f.ref_index[list][b8_xy];
+        int8_t *ref_index = &h->cur_pic.ref_index[list][b8_xy];
         int8_t *ref_cache = h->ref_cache[list];
         ref_index[0 + 0 * 2] = ref_cache[scan8[0]];
         ref_index[1 + 0 * 2] = ref_cache[scan8[4]];
@@ -866,21 +943,20 @@ static av_always_inline void write_back_motion_list(H264Context *h,
 
 static av_always_inline void write_back_motion(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int b_stride      = h->b_stride;
-    const int b_xy  = 4 * s->mb_x + 4 * s->mb_y * h->b_stride; // try mb2b(8)_xy
+    const int b_xy  = 4 * h->mb_x + 4 * h->mb_y * h->b_stride; // try mb2b(8)_xy
     const int b8_xy = 4 * h->mb_xy;
 
     if (USES_LIST(mb_type, 0)) {
-        write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 0);
+        write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 0);
     } else {
-        fill_rectangle(&s->current_picture.f.ref_index[0][b8_xy],
+        fill_rectangle(&h->cur_pic.ref_index[0][b8_xy],
                        2, 2, 2, (uint8_t)LIST_NOT_USED, 1);
     }
     if (USES_LIST(mb_type, 1))
-        write_back_motion_list(h, s, b_stride, b_xy, b8_xy, mb_type, 1);
+        write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 1);
 
-    if (h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC) {
+    if (h->slice_type_nos == AV_PICTURE_TYPE_B && CABAC(h)) {
         if (IS_8X8(mb_type)) {
             uint8_t *direct_table = &h->direct_table[4 * h->mb_xy];
             direct_table[1] = h->sub_mb_type[1] >> 1;
@@ -902,4 +978,9 @@ static av_always_inline int get_dct8x8_allowed(H264Context *h)
                   0x0001000100010001ULL));
 }
 
+void ff_h264_draw_horiz_band(H264Context *h, int y, int height);
+int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc);
+int ff_pred_weight_table(H264Context *h);
+int ff_set_ref_count(H264Context *h);
+
 #endif /* AVCODEC_H264_H */
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 92c1c03..43ddf7d 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -25,13 +25,13 @@
  * @author Michael Niedermayer <michaelni at gmx.at>
  */
 
-#define CABAC 1
+#define CABAC(h) 1
 
+#include "libavutil/attributes.h"
 #include "config.h"
 #include "cabac.h"
 #include "cabac_functions.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "h264.h"
 #include "h264data.h"
@@ -42,7 +42,6 @@
 #include "x86/h264_i386.h"
 #endif
 
-//#undef NDEBUG
 #include <assert.h>
 
 /* Cabac pre state table */
@@ -1260,10 +1259,9 @@ static const int8_t cabac_context_init_PB[3][1024][2] =
 };
 
 void ff_h264_init_cabac_states(H264Context *h) {
-    MpegEncContext * const s = &h->s;
     int i;
     const int8_t (*tab)[2];
-    const int slice_qp = av_clip(s->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
+    const int slice_qp = av_clip(h->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_I ) tab = cabac_context_init_I;
     else                                 tab = cabac_context_init_PB[h->cabac_init_idc];
@@ -1281,13 +1279,12 @@ void ff_h264_init_cabac_states(H264Context *h) {
 }
 
 static int decode_cabac_field_decoding_flag(H264Context *h) {
-    MpegEncContext * const s = &h->s;
-    const long mbb_xy = h->mb_xy - 2L*s->mb_stride;
+    const long mbb_xy = h->mb_xy - 2L*h->mb_stride;
 
     unsigned long ctx = 0;
 
-    ctx += h->mb_field_decoding_flag & !!s->mb_x; //for FMO:(s->current_picture.f.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
-    ctx += (s->current_picture.f.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
+    ctx += h->mb_field_decoding_flag & !!h->mb_x; //for FMO:(s->current_picture.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
+    ctx += (h->cur_pic.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
 
     return get_cabac_noinline( &h->cabac, &(h->cabac_state+70)[ctx] );
 }
@@ -1323,34 +1320,33 @@ static int decode_cabac_intra_mb_type(H264Context *h, int ctx_base, int intra_sl
 }
 
 static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
-    MpegEncContext * const s = &h->s;
     int mba_xy, mbb_xy;
     int ctx = 0;
 
-    if(FRAME_MBAFF){ //FIXME merge with the stuff in fill_caches?
-        int mb_xy = mb_x + (mb_y&~1)*s->mb_stride;
+    if (FRAME_MBAFF(h)) { //FIXME merge with the stuff in fill_caches?
+        int mb_xy = mb_x + (mb_y&~1)*h->mb_stride;
         mba_xy = mb_xy - 1;
         if( (mb_y&1)
             && h->slice_table[mba_xy] == h->slice_num
-            && MB_FIELD == !!IS_INTERLACED( s->current_picture.f.mb_type[mba_xy] ) )
-            mba_xy += s->mb_stride;
-        if( MB_FIELD ){
-            mbb_xy = mb_xy - s->mb_stride;
+            && MB_FIELD(h) == !!IS_INTERLACED( h->cur_pic.mb_type[mba_xy] ) )
+            mba_xy += h->mb_stride;
+        if (MB_FIELD(h)) {
+            mbb_xy = mb_xy - h->mb_stride;
             if( !(mb_y&1)
                 && h->slice_table[mbb_xy] == h->slice_num
-                && IS_INTERLACED( s->current_picture.f.mb_type[mbb_xy] ) )
-                mbb_xy -= s->mb_stride;
+                && IS_INTERLACED( h->cur_pic.mb_type[mbb_xy] ) )
+                mbb_xy -= h->mb_stride;
         }else
-            mbb_xy = mb_x + (mb_y-1)*s->mb_stride;
+            mbb_xy = mb_x + (mb_y-1)*h->mb_stride;
     }else{
         int mb_xy = h->mb_xy;
         mba_xy = mb_xy - 1;
-        mbb_xy = mb_xy - (s->mb_stride << FIELD_PICTURE);
+        mbb_xy = mb_xy - (h->mb_stride << FIELD_PICTURE(h));
     }
 
-    if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.f.mb_type[mba_xy] ))
+    if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP(h->cur_pic.mb_type[mba_xy] ))
         ctx++;
-    if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.f.mb_type[mbb_xy] ))
+    if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP(h->cur_pic.mb_type[mbb_xy] ))
         ctx++;
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_B )
@@ -1507,7 +1503,7 @@ static int decode_cabac_mb_mvd( H264Context *h, int ctxbase, int amvd, int *mvda
             mvd += 1 << k;
             k++;
             if(k>24){
-                av_log(h->s.avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
+                av_log(h->avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
                 return INT_MIN;
             }
         }
@@ -1561,7 +1557,7 @@ static av_always_inline int get_cabac_cbf_ctx( H264Context *h, int cat, int idx,
 }
 
 static av_always_inline void
-decode_cabac_residual_internal(H264Context *h, DCTELEM *block,
+decode_cabac_residual_internal(H264Context *h, int16_t *block,
                                int cat, int n, const uint8_t *scantable,
                                const uint32_t *qmul, int max_coeff,
                                int is_dc, int chroma422)
@@ -1629,9 +1625,9 @@ decode_cabac_residual_internal(H264Context *h, DCTELEM *block,
 #endif
 
     significant_coeff_ctx_base = h->cabac_state
-        + significant_coeff_flag_offset[MB_FIELD][cat];
+        + significant_coeff_flag_offset[MB_FIELD(h)][cat];
     last_coeff_ctx_base = h->cabac_state
-        + last_coeff_flag_offset[MB_FIELD][cat];
+        + last_coeff_flag_offset[MB_FIELD(h)][cat];
     abs_level_m1_ctx_base = h->cabac_state
         + coeff_abs_level_m1_offset[cat];
 
@@ -1651,7 +1647,7 @@ decode_cabac_residual_internal(H264Context *h, DCTELEM *block,
         if( last == max_coeff -1 ) {\
             index[coeff_count++] = last;\
         }
-        const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD];
+        const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD(h)];
 #ifdef decode_significance
         coeff_count = decode_significance_8x8(CC, significant_coeff_ctx_base, index,
                                                  last_coeff_ctx_base, sig_off);
@@ -1745,18 +1741,31 @@ decode_cabac_residual_internal(H264Context *h, DCTELEM *block,
 
 }
 
-static void decode_cabac_residual_dc_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, int max_coeff ) {
+static av_noinline void decode_cabac_residual_dc_internal(H264Context *h,
+                                                          int16_t *block,
+                                                          int cat, int n,
+                                                          const uint8_t *scantable,
+                                                          int max_coeff)
+{
     decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1, 0);
 }
 
-static void decode_cabac_residual_dc_internal_422(H264Context *h, DCTELEM *block,
-                                                  int cat, int n, const uint8_t *scantable,
-                                                  int max_coeff)
+static av_noinline void decode_cabac_residual_dc_internal_422(H264Context *h,
+                                                              int16_t *block,
+                                                              int cat, int n,
+                                                              const uint8_t *scantable,
+                                                              int max_coeff)
 {
     decode_cabac_residual_internal(h, block, cat, n, scantable, NULL, max_coeff, 1, 1);
 }
 
-static void decode_cabac_residual_nondc_internal( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
+static av_noinline void decode_cabac_residual_nondc_internal(H264Context *h,
+                                                             int16_t *block,
+                                                             int cat, int n,
+                                                             const uint8_t *scantable,
+                                                             const uint32_t *qmul,
+                                                             int max_coeff)
+{
     decode_cabac_residual_internal(h, block, cat, n, scantable, qmul, max_coeff, 0, 0);
 }
 
@@ -1772,7 +1781,12 @@ static void decode_cabac_residual_nondc_internal( H264Context *h, DCTELEM *block
  * because it allows improved constant propagation into get_cabac_cbf_ctx,
  * as well as because most blocks have zero CBFs. */
 
-static av_always_inline void decode_cabac_residual_dc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, int max_coeff ) {
+static av_always_inline void decode_cabac_residual_dc(H264Context *h,
+                                                      int16_t *block,
+                                                      int cat, int n,
+                                                      const uint8_t *scantable,
+                                                      int max_coeff)
+{
     /* read coded block flag */
     if( get_cabac( &h->cabac, &h->cabac_state[get_cabac_cbf_ctx( h, cat, n, max_coeff, 1 ) ] ) == 0 ) {
         h->non_zero_count_cache[scan8[n]] = 0;
@@ -1782,7 +1796,7 @@ static av_always_inline void decode_cabac_residual_dc( H264Context *h, DCTELEM *
 }
 
 static av_always_inline void
-decode_cabac_residual_dc_422(H264Context *h, DCTELEM *block,
+decode_cabac_residual_dc_422(H264Context *h, int16_t *block,
                              int cat, int n, const uint8_t *scantable,
                              int max_coeff)
 {
@@ -1794,9 +1808,15 @@ decode_cabac_residual_dc_422(H264Context *h, DCTELEM *block,
     decode_cabac_residual_dc_internal_422(h, block, cat, n, scantable, max_coeff);
 }
 
-static av_always_inline void decode_cabac_residual_nondc( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff ) {
+static av_always_inline void decode_cabac_residual_nondc(H264Context *h,
+                                                         int16_t *block,
+                                                         int cat, int n,
+                                                         const uint8_t *scantable,
+                                                         const uint32_t *qmul,
+                                                         int max_coeff)
+{
     /* read coded block flag */
-    if( (cat != 5 || CHROMA444) && get_cabac( &h->cabac, &h->cabac_state[get_cabac_cbf_ctx( h, cat, n, max_coeff, 0 ) ] ) == 0 ) {
+    if( (cat != 5 || CHROMA444(h)) && get_cabac( &h->cabac, &h->cabac_state[get_cabac_cbf_ctx( h, cat, n, max_coeff, 0 ) ] ) == 0 ) {
         if( max_coeff == 64 ) {
             fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, 0, 1);
         } else {
@@ -1812,8 +1832,7 @@ static av_always_inline void decode_cabac_luma_residual( H264Context *h, const u
     static const uint8_t ctx_cat[4][3] = {{0,6,10},{1,7,11},{2,8,12},{5,9,13}};
     const uint32_t *qmul;
     int i8x8, i4x4;
-    MpegEncContext * const s = &h->s;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p-1];
     if( IS_INTRA16x16( mb_type ) ) {
         AV_ZERO128(h->mb_luma_dc[p]+0);
         AV_ZERO128(h->mb_luma_dc[p]+8);
@@ -1859,28 +1878,27 @@ static av_always_inline void decode_cabac_luma_residual( H264Context *h, const u
  * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
  */
 int ff_h264_decode_mb_cabac(H264Context *h) {
-    MpegEncContext * const s = &h->s;
     int mb_xy;
     int mb_type, partition_count, cbp = 0;
     int dct8x8_allowed= h->pps.transform_8x8_mode;
     int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
     const int pixel_shift = h->pixel_shift;
 
-    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+    mb_xy = h->mb_xy = h->mb_x + h->mb_y*h->mb_stride;
 
-    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
+    tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
     if( h->slice_type_nos != AV_PICTURE_TYPE_I ) {
         int skip;
         /* a skipped mb needs the aff flag from the following mb */
-        if( FRAME_MBAFF && (s->mb_y&1)==1 && h->prev_mb_skipped )
+        if (FRAME_MBAFF(h) && (h->mb_y & 1) == 1 && h->prev_mb_skipped)
             skip = h->next_mb_skipped;
         else
-            skip = decode_cabac_mb_skip( h, s->mb_x, s->mb_y );
+            skip = decode_cabac_mb_skip( h, h->mb_x, h->mb_y );
         /* read skip flags */
         if( skip ) {
-            if( FRAME_MBAFF && (s->mb_y&1)==0 ){
-                s->current_picture.f.mb_type[mb_xy] = MB_TYPE_SKIP;
-                h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 );
+            if (FRAME_MBAFF(h) && (h->mb_y & 1) == 0) {
+                h->cur_pic.mb_type[mb_xy] = MB_TYPE_SKIP;
+                h->next_mb_skipped = decode_cabac_mb_skip( h, h->mb_x, h->mb_y+1 );
                 if(!h->next_mb_skipped)
                     h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
             }
@@ -1895,15 +1913,15 @@ int ff_h264_decode_mb_cabac(H264Context *h) {
 
         }
     }
-    if(FRAME_MBAFF){
-        if( (s->mb_y&1) == 0 )
+    if (FRAME_MBAFF(h)) {
+        if( (h->mb_y&1) == 0 )
             h->mb_mbaff =
             h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
     }
 
     h->prev_mb_skipped = 0;
 
-    fill_decode_neighbors(h, -(MB_FIELD));
+    fill_decode_neighbors(h, -(MB_FIELD(h)));
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_B ) {
         int ctx = 0;
@@ -1967,7 +1985,7 @@ decode_intra_mb:
         h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode;
         mb_type= i_mb_type_info[mb_type].type;
     }
-    if(MB_FIELD)
+    if(MB_FIELD(h))
         mb_type |= MB_TYPE_INTERLACED;
 
     h->slice_table[ mb_xy ]= h->slice_num;
@@ -1989,7 +2007,8 @@ decode_intra_mb:
         // The pixels are stored in the same order as levels in h->mb array.
         if ((int) (h->cabac.bytestream_end - ptr) < mb_size)
             return -1;
-        memcpy(h->mb, ptr, mb_size); ptr+=mb_size;
+        h->intra_pcm_ptr = ptr;
+        ptr += mb_size;
 
         ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);
 
@@ -1997,10 +2016,10 @@ decode_intra_mb:
         h->cbp_table[mb_xy] = 0xf7ef;
         h->chroma_pred_mode_table[mb_xy] = 0;
         // In deblocking, the quantizer is 0
-        s->current_picture.f.qscale_table[mb_xy] = 0;
+        h->cur_pic.qscale_table[mb_xy] = 0;
         // All coeffs are present
         memset(h->non_zero_count[mb_xy], 16, 48);
-        s->current_picture.f.mb_type[mb_xy] = mb_type;
+        h->cur_pic.mb_type[mb_xy] = mb_type;
         h->last_qscale_diff = 0;
         return 0;
     }
@@ -2022,7 +2041,7 @@ decode_intra_mb:
                     int pred = pred_intra_mode( h, i );
                     h->intra4x4_pred_mode_cache[ scan8[i] ] = decode_cabac_mb_intra4x4_pred_mode( h, pred );
 
-                    av_dlog(s->avctx, "i4x4 pred=%d mode=%d\n", pred,
+                    av_dlog(h->avctx, "i4x4 pred=%d mode=%d\n", pred,
                             h->intra4x4_pred_mode_cache[scan8[i]]);
                 }
             }
@@ -2073,11 +2092,11 @@ decode_intra_mb:
                 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;
+                        int rc = h->ref_count[list] << MB_MBAFF(h);
                         if (rc > 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);
+                                av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);
                                 return -1;
                             }
                         }else
@@ -2112,7 +2131,7 @@ decode_intra_mb:
                         uint8_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ];
                         pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, index)
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         if(IS_SUB_8X8(sub_mb_type)){
                             mv_cache[ 1 ][0]=
@@ -2159,11 +2178,11 @@ decode_intra_mb:
         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;
+                    int ref, rc = h->ref_count[list] << MB_MBAFF(h);
                     if (rc > 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);
+                            av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
                             return -1;
                         }
                     }else
@@ -2176,7 +2195,7 @@ decode_intra_mb:
                     int mx,my,mpx,mpy;
                     pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
                     DECODE_CABAC_MB_MVD( h, list, 0)
-                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                    tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                     fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2);
                     fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
@@ -2187,11 +2206,11 @@ decode_intra_mb:
             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;
+                            int ref, rc = h->ref_count[list] << MB_MBAFF(h);
                             if (rc > 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);
+                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
                                     return -1;
                                 }
                             }else
@@ -2207,7 +2226,7 @@ decode_intra_mb:
                         int mx,my,mpx,mpy;
                         pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, 8*i)
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2);
                         fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);
@@ -2222,11 +2241,11 @@ decode_intra_mb:
             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;
+                            int ref, rc = h->ref_count[list] << MB_MBAFF(h);
                             if (rc > 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);
+                                    av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
                                     return -1;
                                 }
                             }else
@@ -2243,7 +2262,7 @@ decode_intra_mb:
                         pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
                         DECODE_CABAC_MB_MVD( h, list, 4*i)
 
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
                         fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2);
                         fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);
                     }else{
@@ -2274,7 +2293,7 @@ decode_intra_mb:
 
     /* It would be better to do this in fill_decode_caches, but we don't know
      * the transform mode of the current macroblock there. */
-    if (CHROMA444 && IS_8x8DCT(mb_type)){
+    if (CHROMA444(h) && IS_8x8DCT(mb_type)){
         int i;
         uint8_t *nnz_cache = h->non_zero_count_cache;
         for (i = 0; i < 2; i++){
@@ -2288,24 +2307,24 @@ decode_intra_mb:
             }
         }
         if (h->top_type && !IS_8x8DCT(h->top_type)){
-            uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;
+            uint32_t top_empty = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 0x40404040;
             AV_WN32A(&nnz_cache[4+8* 0], top_empty);
             AV_WN32A(&nnz_cache[4+8* 5], top_empty);
             AV_WN32A(&nnz_cache[4+8*10], top_empty);
         }
     }
-    s->current_picture.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.mb_type[mb_xy] = mb_type;
 
     if( cbp || IS_INTRA16x16( mb_type ) ) {
         const uint8_t *scan, *scan8x8;
         const uint32_t *qmul;
 
         if(IS_INTERLACED(mb_type)){
-            scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
-            scan= s->qscale ? h->field_scan : h->field_scan_q0;
+            scan8x8= h->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
+            scan= h->qscale ? h->field_scan : h->field_scan_q0;
         }else{
-            scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
-            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+            scan8x8= h->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
+            scan= h->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
         }
 
         // decode_cabac_mb_dqp
@@ -2318,7 +2337,7 @@ decode_intra_mb:
                 ctx= 3;
                 val++;
                 if(val > 2*max_qp){ //prevent infinite loop
-                    av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", h->mb_x, h->mb_y);
                     return -1;
                 }
             }
@@ -2328,21 +2347,21 @@ decode_intra_mb:
             else
                 val= -((val + 1)>>1);
             h->last_qscale_diff = val;
-            s->qscale += val;
-            if(((unsigned)s->qscale) > max_qp){
-                if(s->qscale<0) s->qscale+= max_qp+1;
-                else            s->qscale-= max_qp+1;
+            h->qscale += val;
+            if(((unsigned)h->qscale) > max_qp){
+                if(h->qscale<0) h->qscale+= max_qp+1;
+                else            h->qscale-= max_qp+1;
             }
-            h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-            h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+            h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
+            h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
         }else
             h->last_qscale_diff=0;
 
         decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 0);
-        if(CHROMA444){
+        if (CHROMA444(h)) {
             decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 1);
             decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 2);
-        } else if (CHROMA422) {
+        } else if (CHROMA422(h)) {
             if( cbp&0x30 ){
                 int c;
                 for (c = 0; c < 2; c++)
@@ -2354,7 +2373,7 @@ decode_intra_mb:
             if( cbp&0x20 ) {
                 int c, i, i8x8;
                 for( c = 0; c < 2; c++ ) {
-                    DCTELEM *mb = h->mb + (16*(16 + 16*c) << pixel_shift);
+                    int16_t *mb = h->mb + (16*(16 + 16*c) << pixel_shift);
                     qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]];
                     for (i8x8 = 0; i8x8 < 2; i8x8++) {
                         for (i = 0; i < 4; i++) {
@@ -2396,7 +2415,7 @@ decode_intra_mb:
         h->last_qscale_diff = 0;
     }
 
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    h->cur_pic.qscale_table[mb_xy] = h->qscale;
     write_back_non_zero_count(h);
 
     return 0;
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index 0cc7214..d3f6dcb 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -25,7 +25,7 @@
  * @author Michael Niedermayer <michaelni at gmx.at>
  */
 
-#define CABAC 0
+#define CABAC(h) 0
 
 #include "internal.h"
 #include "avcodec.h"
@@ -35,7 +35,6 @@
 #include "h264_mvpred.h"
 #include "golomb.h"
 
-//#undef NDEBUG
 #include <assert.h>
 
 static const uint8_t golomb_to_inter_cbp_gray[16]={
@@ -292,7 +291,7 @@ static inline int pred_non_zero_count(H264Context *h, int n){
 
     if(i<64) i= (i+1)>>1;
 
-    tprintf(h->s.avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
+    tprintf(h->avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
 
     return i&31;
 }
@@ -442,8 +441,7 @@ static inline int get_level_prefix(GetBitContext *gb){
  * @param max_coeff number of coefficients in the block
  * @return <0 if an error occurred
  */
-static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff){
-    MpegEncContext * const s = &h->s;
+static int decode_residual(H264Context *h, GetBitContext *gb, int16_t *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff){
     static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
     int level[16];
     int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
@@ -474,12 +472,12 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
     if(total_coeff==0)
         return 0;
     if(total_coeff > (unsigned)max_coeff) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", s->mb_x, s->mb_y, total_coeff);
+        av_log(h->avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", h->mb_x, h->mb_y, total_coeff);
         return -1;
     }
 
     trailing_ones= coeff_token&3;
-    tprintf(h->s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
+    tprintf(h->avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
     assert(total_coeff<=16);
 
     i = show_bits(gb, 3);
@@ -515,7 +513,7 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
                 level_code= 30 + get_bits(gb, prefix-3); //part
                 if(prefix>=16){
                     if(prefix > 25+3){
-                        av_log(h->s.avctx, AV_LOG_ERROR, "Invalid level prefix\n");
+                        av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n");
                         return -1;
                     }
                     level_code += (1<<(prefix-3))-4096;
@@ -611,8 +609,8 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
     }
 
     if (zeros_left < 0) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
-               "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y);
+        av_log(h->avctx, AV_LOG_ERROR,
+               "negative number of zero coeffs at %d %d\n", h->mb_x, h->mb_y);
         return AVERROR_INVALIDDATA;
     }
 
@@ -627,8 +625,7 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
 
 static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *gb, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p){
     int i4x4, i8x8;
-    MpegEncContext * const s = &h->s;
-    int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
+    int qscale = p == 0 ? h->qscale : h->chroma_qp[p-1];
     if(IS_INTRA16x16(mb_type)){
         AV_ZERO128(h->mb_luma_dc[p]+0);
         AV_ZERO128(h->mb_luma_dc[p]+8);
@@ -662,7 +659,7 @@ static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *
         for(i8x8=0; i8x8<4; i8x8++){
             if(cbp & (1<<i8x8)){
                 if(IS_8x8DCT(mb_type)){
-                    DCTELEM *buf = &h->mb[64*i8x8+256*p << pixel_shift];
+                    int16_t *buf = &h->mb[64*i8x8+256*p << pixel_shift];
                     uint8_t *nnz;
                     for(i4x4=0; i4x4<4; i4x4++){
                         const int index= i4x4 + 4*i8x8 + p*16;
@@ -693,7 +690,6 @@ static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *
 }
 
 int ff_h264_decode_mb_cavlc(H264Context *h){
-    MpegEncContext * const s = &h->s;
     int mb_xy;
     int partition_count;
     unsigned int mb_type, cbp;
@@ -701,32 +697,32 @@ int ff_h264_decode_mb_cavlc(H264Context *h){
     int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
     const int pixel_shift = h->pixel_shift;
 
-    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
+    mb_xy = h->mb_xy = h->mb_x + h->mb_y*h->mb_stride;
 
-    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);
+    tprintf(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, h->mb_x, h->mb_y);
     cbp = 0; /* avoid warning. FIXME: find a solution without slowing
                 down the code */
     if(h->slice_type_nos != AV_PICTURE_TYPE_I){
-        if(s->mb_skip_run==-1)
-            s->mb_skip_run= get_ue_golomb(&s->gb);
+        if(h->mb_skip_run==-1)
+            h->mb_skip_run= get_ue_golomb(&h->gb);
 
-        if (s->mb_skip_run--) {
-            if(FRAME_MBAFF && (s->mb_y&1) == 0){
-                if(s->mb_skip_run==0)
-                    h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);
+        if (h->mb_skip_run--) {
+            if(FRAME_MBAFF(h) && (h->mb_y&1) == 0){
+                if(h->mb_skip_run==0)
+                    h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&h->gb);
             }
             decode_mb_skip(h);
             return 0;
         }
     }
-    if(FRAME_MBAFF){
-        if( (s->mb_y&1) == 0 )
-            h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);
+    if (FRAME_MBAFF(h)) {
+        if( (h->mb_y&1) == 0 )
+            h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&h->gb);
     }
 
     h->prev_mb_skipped= 0;
 
-    mb_type= get_ue_golomb(&s->gb);
+    mb_type= get_ue_golomb(&h->gb);
     if(h->slice_type_nos == AV_PICTURE_TYPE_B){
         if(mb_type < 23){
             partition_count= b_mb_type_info[mb_type].partition_count;
@@ -749,7 +745,7 @@ int ff_h264_decode_mb_cavlc(H264Context *h){
             mb_type--;
 decode_intra_mb:
         if(mb_type > 25){
-            av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(h->slice_type), s->mb_x, s->mb_y);
+            av_log(h->avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(h->slice_type), h->mb_x, h->mb_y);
             return -1;
         }
         partition_count=0;
@@ -758,30 +754,29 @@ decode_intra_mb:
         mb_type= i_mb_type_info[mb_type].type;
     }
 
-    if(MB_FIELD)
+    if(MB_FIELD(h))
         mb_type |= MB_TYPE_INTERLACED;
 
     h->slice_table[ mb_xy ]= h->slice_num;
 
     if(IS_INTRA_PCM(mb_type)){
-        unsigned int x;
         const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *
-                            h->sps.bit_depth_luma >> 3;
+                            h->sps.bit_depth_luma;
 
         // We assume these blocks are very rare so we do not optimize it.
-        align_get_bits(&s->gb);
-
-        // The pixels are stored in the same order as levels in h->mb array.
-        for(x=0; x < mb_size; x++){
-            ((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8);
+        h->intra_pcm_ptr = align_get_bits(&h->gb);
+        if (get_bits_left(&h->gb) < mb_size) {
+            av_log(h->avctx, AV_LOG_ERROR, "Not enough data for an intra PCM block.\n");
+            return AVERROR_INVALIDDATA;
         }
+        skip_bits_long(&h->gb, mb_size);
 
         // In deblocking, the quantizer is 0
-        s->current_picture.f.qscale_table[mb_xy] = 0;
+        h->cur_pic.qscale_table[mb_xy] = 0;
         // All coeffs are present
         memset(h->non_zero_count[mb_xy], 16, 48);
 
-        s->current_picture.f.mb_type[mb_xy] = mb_type;
+        h->cur_pic.mb_type[mb_xy] = mb_type;
         return 0;
     }
 
@@ -795,7 +790,7 @@ decode_intra_mb:
         if(IS_INTRA4x4(mb_type)){
             int i;
             int di = 1;
-            if(dct8x8_allowed && get_bits1(&s->gb)){
+            if(dct8x8_allowed && get_bits1(&h->gb)){
                 mb_type |= MB_TYPE_8x8DCT;
                 di = 4;
             }
@@ -804,8 +799,8 @@ decode_intra_mb:
             for(i=0; i<16; i+=di){
                 int mode= pred_intra_mode(h, i);
 
-                if(!get_bits1(&s->gb)){
-                    const int rem_mode= get_bits(&s->gb, 3);
+                if(!get_bits1(&h->gb)){
+                    const int rem_mode= get_bits(&h->gb, 3);
                     mode = rem_mode + (rem_mode >= mode);
                 }
 
@@ -823,7 +818,7 @@ decode_intra_mb:
                 return -1;
         }
         if(decode_chroma){
-            pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb), 1);
+            pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&h->gb), 1);
             if(pred_mode < 0)
                 return -1;
             h->chroma_pred_mode= pred_mode;
@@ -835,9 +830,9 @@ decode_intra_mb:
 
         if(h->slice_type_nos == AV_PICTURE_TYPE_B){
             for(i=0; i<4; i++){
-                h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
+                h->sub_mb_type[i]= get_ue_golomb_31(&h->gb);
                 if(h->sub_mb_type[i] >=13){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], h->mb_x, h->mb_y);
                     return -1;
                 }
                 sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
@@ -853,9 +848,9 @@ decode_intra_mb:
         }else{
             assert(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
             for(i=0; i<4; i++){
-                h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);
+                h->sub_mb_type[i]= get_ue_golomb_31(&h->gb);
                 if(h->sub_mb_type[i] >=4){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);
+                    av_log(h->avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], h->mb_x, h->mb_y);
                     return -1;
                 }
                 sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;
@@ -864,7 +859,7 @@ decode_intra_mb:
         }
 
         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 : h->ref_count[list] << MB_MBAFF(h);
             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)){
@@ -872,11 +867,11 @@ decode_intra_mb:
                     if(ref_count == 1){
                         tmp= 0;
                     }else if(ref_count == 2){
-                        tmp= get_bits1(&s->gb)^1;
+                        tmp= get_bits1(&h->gb)^1;
                     }else{
-                        tmp= get_ue_golomb_31(&s->gb);
+                        tmp= get_ue_golomb_31(&h->gb);
                         if(tmp>=ref_count){
-                            av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
+                            av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
                             return -1;
                         }
                     }
@@ -908,9 +903,9 @@ decode_intra_mb:
                         const int index= 4*i + block_width*j;
                         int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];
                         pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         if(IS_SUB_8X8(sub_mb_type)){
                             mv_cache[ 1 ][0]=
@@ -944,15 +939,15 @@ decode_intra_mb:
             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;
+                        int rc = h->ref_count[list] << MB_MBAFF(h);
                         if (rc == 1) {
                             val= 0;
                         } else if (rc == 2) {
-                            val= get_bits1(&s->gb)^1;
+                            val= get_bits1(&h->gb)^1;
                         }else{
-                            val= get_ue_golomb_31(&s->gb);
+                            val= get_ue_golomb_31(&h->gb);
                             if (val >= rc) {
-                                av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                 return -1;
                             }
                         }
@@ -962,9 +957,9 @@ decode_intra_mb:
             for(list=0; list<h->list_count; list++){
                 if(IS_DIR(mb_type, 0, list)){
                     pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);
-                    mx += get_se_golomb(&s->gb);
-                    my += get_se_golomb(&s->gb);
-                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                    mx += get_se_golomb(&h->gb);
+                    my += get_se_golomb(&h->gb);
+                    tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                     fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
                 }
@@ -975,15 +970,15 @@ decode_intra_mb:
                     for(i=0; i<2; i++){
                         unsigned int val;
                         if(IS_DIR(mb_type, i, list)){
-                            int rc = h->ref_count[list] << MB_MBAFF;
+                            int rc = h->ref_count[list] << MB_MBAFF(h);
                             if (rc == 1) {
                                 val= 0;
                             } else if (rc == 2) {
-                                val= get_bits1(&s->gb)^1;
+                                val= get_bits1(&h->gb)^1;
                             }else{
-                                val= get_ue_golomb_31(&s->gb);
+                                val= get_ue_golomb_31(&h->gb);
                                 if (val >= rc) {
-                                    av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                    av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                     return -1;
                                 }
                             }
@@ -997,9 +992,9 @@ decode_intra_mb:
                     unsigned int val;
                     if(IS_DIR(mb_type, i, list)){
                         pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         val= pack16to32(mx,my);
                     }else
@@ -1013,15 +1008,15 @@ decode_intra_mb:
                     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;
+                            int rc = h->ref_count[list] << MB_MBAFF(h);
                             if (rc == 1) {
                                 val= 0;
                             } else if (rc == 2) {
-                                val= get_bits1(&s->gb)^1;
+                                val= get_bits1(&h->gb)^1;
                             }else{
-                                val= get_ue_golomb_31(&s->gb);
+                                val= get_ue_golomb_31(&h->gb);
                                 if (val >= rc) {
-                                    av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+                                    av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                     return -1;
                                 }
                             }
@@ -1035,9 +1030,9 @@ decode_intra_mb:
                     unsigned int val;
                     if(IS_DIR(mb_type, i, list)){
                         pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
-                        mx += get_se_golomb(&s->gb);
-                        my += get_se_golomb(&s->gb);
-                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);
+                        mx += get_se_golomb(&h->gb);
+                        my += get_se_golomb(&h->gb);
+                        tprintf(h->avctx, "final mv:%d %d\n", mx, my);
 
                         val= pack16to32(mx,my);
                     }else
@@ -1052,18 +1047,18 @@ decode_intra_mb:
         write_back_motion(h, mb_type);
 
     if(!IS_INTRA16x16(mb_type)){
-        cbp= get_ue_golomb(&s->gb);
+        cbp= get_ue_golomb(&h->gb);
 
         if(decode_chroma){
             if(cbp > 47){
-                av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
+                av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, h->mb_x, h->mb_y);
                 return -1;
             }
             if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];
             else                     cbp= golomb_to_inter_cbp   [cbp];
         }else{
             if(cbp > 15){
-                av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
+                av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, h->mb_x, h->mb_y);
                 return -1;
             }
             if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
@@ -1072,11 +1067,11 @@ decode_intra_mb:
     }
 
     if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){
-        mb_type |= MB_TYPE_8x8DCT*get_bits1(&s->gb);
+        mb_type |= MB_TYPE_8x8DCT*get_bits1(&h->gb);
     }
     h->cbp=
     h->cbp_table[mb_xy]= cbp;
-    s->current_picture.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.mb_type[mb_xy] = mb_type;
 
     if(cbp || IS_INTRA16x16(mb_type)){
         int i4x4, i8x8, chroma_idx;
@@ -1087,41 +1082,41 @@ decode_intra_mb:
         const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
 
         if(IS_INTERLACED(mb_type)){
-            scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
-            scan= s->qscale ? h->field_scan : h->field_scan_q0;
+            scan8x8= h->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
+            scan= h->qscale ? h->field_scan : h->field_scan_q0;
         }else{
-            scan8x8= s->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
-            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+            scan8x8= h->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
+            scan= h->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
         }
 
-        dquant= get_se_golomb(&s->gb);
+        dquant= get_se_golomb(&h->gb);
 
-        s->qscale += dquant;
+        h->qscale += dquant;
 
-        if(((unsigned)s->qscale) > max_qp){
-            if(s->qscale<0) s->qscale+= max_qp+1;
-            else            s->qscale-= max_qp+1;
-            if(((unsigned)s->qscale) > max_qp){
-                av_log(h->s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s->mb_x, s->mb_y);
+        if(((unsigned)h->qscale) > max_qp){
+            if(h->qscale<0) h->qscale+= max_qp+1;
+            else            h->qscale-= max_qp+1;
+            if(((unsigned)h->qscale) > max_qp){
+                av_log(h->avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, h->mb_x, h->mb_y);
                 return -1;
             }
         }
 
-        h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale);
-        h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale);
+        h->chroma_qp[0]= get_chroma_qp(h, 0, h->qscale);
+        h->chroma_qp[1]= get_chroma_qp(h, 1, h->qscale);
 
         if( (ret = decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ){
             return -1;
         }
         h->cbp_table[mb_xy] |= ret << 12;
-        if(CHROMA444){
+        if (CHROMA444(h)) {
             if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ){
                 return -1;
             }
             if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){
                 return -1;
             }
-        } else if (CHROMA422) {
+        } else if (CHROMA422(h)) {
             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),
@@ -1134,7 +1129,7 @@ decode_intra_mb:
             if(cbp&0x20){
                 for(chroma_idx=0; chroma_idx<2; chroma_idx++){
                     const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
-                    DCTELEM *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
+                    int16_t *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
                     for (i8x8 = 0; i8x8 < 2; i8x8++) {
                         for (i4x4 = 0; i4x4 < 4; i4x4++) {
                             const int index = 16 + 16*chroma_idx + 8*i8x8 + i4x4;
@@ -1176,7 +1171,7 @@ decode_intra_mb:
         fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
         fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
     }
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    h->cur_pic.qscale_table[mb_xy] = h->qscale;
     write_back_non_zero_count(h);
 
     return 0;
diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index 2306b97..85fda31 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -26,14 +26,12 @@
  */
 
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h264.h"
 #include "rectangle.h"
 #include "thread.h"
 
-//#undef NDEBUG
 #include <assert.h>
 
 
@@ -50,14 +48,13 @@ static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){
 }
 
 void ff_h264_direct_dist_scale_factor(H264Context * const h){
-    MpegEncContext * const s = &h->s;
-    const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
+    const int poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];
     const int poc1 = h->ref_list[1][0].poc;
     int i, field;
 
-    if (FRAME_MBAFF)
+    if (FRAME_MBAFF(h))
         for (field = 0; field < 2; field++){
-            const int poc  = h->s.current_picture_ptr->field_poc[field];
+            const int poc  = h->cur_pic_ptr->field_poc[field];
             const int poc1 = h->ref_list[1][0].field_poc[field];
             for (i = 0; i < 2 * h->ref_count[0]; i++)
                 h->dist_scale_factor_field[field][i^field] =
@@ -70,12 +67,11 @@ void ff_h264_direct_dist_scale_factor(H264Context * const h){
 }
 
 static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){
-    MpegEncContext * const s = &h->s;
     Picture * const ref1 = &h->ref_list[1][0];
     int j, old_ref, rfield;
     int start= mbafi ? 16                      : 0;
     int end  = mbafi ? 16+2*h->ref_count[0]    : h->ref_count[0];
-    int interl= mbafi || s->picture_structure != PICT_FRAME;
+    int interl= mbafi || h->picture_structure != PICT_FRAME;
 
     /* bogus; fills in for missing frames */
     memset(map[list], 0, sizeof(map[list]));
@@ -90,7 +86,7 @@ static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field,
                 poc= (poc&~3) + rfield + 1;
 
             for(j=start; j<end; j++){
-                if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].f.reference & 3) == poc) {
+                if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].reference & 3) == poc) {
                     int cur_ref= mbafi ? (j-16)^field : j;
                     if (ref1->mbaff)
                         map[list][2 * old_ref + (rfield^field) + 16] = cur_ref;
@@ -104,34 +100,33 @@ static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field,
 }
 
 void ff_h264_direct_ref_list_init(H264Context * const h){
-    MpegEncContext * const s = &h->s;
     Picture * const ref1 = &h->ref_list[1][0];
-    Picture * const cur = s->current_picture_ptr;
+    Picture * const cur = h->cur_pic_ptr;
     int list, j, field;
-    int sidx= (s->picture_structure&1)^1;
-    int ref1sidx = (ref1->f.reference&1)^1;
+    int sidx= (h->picture_structure&1)^1;
+    int ref1sidx = (ref1->reference&1)^1;
 
     for(list=0; list<2; list++){
         cur->ref_count[sidx][list] = h->ref_count[list];
         for(j=0; j<h->ref_count[list]; j++)
-            cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].f.reference & 3);
+            cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference & 3);
     }
 
-    if(s->picture_structure == PICT_FRAME){
+    if(h->picture_structure == PICT_FRAME){
         memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
         memcpy(cur->ref_poc  [1], cur->ref_poc  [0], sizeof(cur->ref_poc  [0]));
     }
 
-    cur->mbaff= FRAME_MBAFF;
+    cur->mbaff = FRAME_MBAFF(h);
 
     h->col_fieldoff= 0;
-    if(s->picture_structure == PICT_FRAME){
-        int cur_poc = s->current_picture_ptr->poc;
+    if(h->picture_structure == PICT_FRAME){
+        int cur_poc = h->cur_pic_ptr->poc;
         int *col_poc = h->ref_list[1]->field_poc;
         h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc));
         ref1sidx=sidx= h->col_parity;
-    } else if (!(s->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
-        h->col_fieldoff = 2 * h->ref_list[1][0].f.reference - 3;
+    } else if (!(h->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
+        h->col_fieldoff = 2 * h->ref_list[1][0].reference - 3;
     }
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_B || h->direct_spatial_mv_pred)
@@ -139,7 +134,7 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
 
     for(list=0; list<2; list++){
         fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0);
-        if(FRAME_MBAFF)
+        if (FRAME_MBAFF(h))
         for(field=0; field<2; field++)
             fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1);
     }
@@ -147,26 +142,25 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
 
 static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y)
 {
-    int ref_field = ref->f.reference - 1;
+    int ref_field = ref->reference - 1;
     int ref_field_picture = ref->field_picture;
-    int ref_height = 16*h->s.mb_height >> ref_field_picture;
+    int ref_height = 16*h->mb_height >> ref_field_picture;
 
-    if(!HAVE_THREADS || !(h->s.avctx->active_thread_type&FF_THREAD_FRAME))
+    if(!HAVE_THREADS || !(h->avctx->active_thread_type&FF_THREAD_FRAME))
         return;
 
     //FIXME it can be safe to access mb stuff
     //even if pixels aren't deblocked yet
 
-    ff_thread_await_progress(&ref->f,
+    ff_thread_await_progress(&ref->tf,
                              FFMIN(16 * mb_y >> ref_field_picture, ref_height - 1),
                              ref_field_picture && ref_field);
 }
 
 static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
-    MpegEncContext * const s = &h->s;
     int b8_stride = 2;
     int b4_stride = h->b_stride;
-    int mb_xy = h->mb_xy, mb_y = s->mb_y;
+    int mb_xy = h->mb_xy, mb_y = h->mb_y;
     int mb_type_col[2];
     const int16_t (*l1mv0)[2], (*l1mv1)[2];
     const int8_t *l1ref0, *l1ref1;
@@ -177,9 +171,9 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
     int mv[2];
     int list;
 
-    assert(h->ref_list[1][0].f.reference & 3);
+    assert(h->ref_list[1][0].reference & 3);
 
-    await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type));
+    await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type));
 
 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
 
@@ -239,23 +233,23 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
         return;
     }
 
-    if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+    if (IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
         if (!IS_INTERLACED(*mb_type)) {                          //     AFR/FR    -> AFL/FL
-            mb_y = (s->mb_y&~1) + h->col_parity;
-            mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
+            mb_y = (h->mb_y&~1) + h->col_parity;
+            mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride;
             b8_stride = 0;
         }else{
             mb_y  += h->col_fieldoff;
-            mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
+            mb_xy += h->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
         }
         goto single_col;
     }else{                                               // AFL/AFR/FR/FL -> AFR/FR
         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
-            mb_y = s->mb_y&~1;
-            mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
-            mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride];
-            b8_stride = 2+4*s->mb_stride;
+            mb_y = h->mb_y&~1;
+            mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride;
+            mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
+            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + h->mb_stride];
+            b8_stride = 2+4*h->mb_stride;
             b4_stride *= 6;
             if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) {
                 mb_type_col[0] &= ~MB_TYPE_INTERLACED;
@@ -273,7 +267,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
         }else{                                           //     AFR/FR    -> AFR/FR
 single_col:
             mb_type_col[0] =
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy];
+            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
 
             sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
             if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
@@ -293,12 +287,12 @@ single_col:
 
     await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
 
-    l1mv0  = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
-    l1mv1  = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
-    l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
-    l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
+    l1mv0  = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
+    l1mv1  = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];
+    l1ref0 = &h->ref_list[1][0].ref_index [0][4 * mb_xy];
+    l1ref1 = &h->ref_list[1][0].ref_index [1][4 * mb_xy];
     if(!b8_stride){
-        if(s->mb_y&1){
+        if(h->mb_y&1){
             l1ref0 += 2;
             l1ref1 += 2;
             l1mv0  +=  2*b4_stride;
@@ -414,10 +408,9 @@ single_col:
 }
 
 static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
-    MpegEncContext * const s = &h->s;
     int b8_stride = 2;
     int b4_stride = h->b_stride;
-    int mb_xy = h->mb_xy, mb_y = s->mb_y;
+    int mb_xy = h->mb_xy, mb_y = h->mb_y;
     int mb_type_col[2];
     const int16_t (*l1mv0)[2], (*l1mv1)[2];
     const int8_t *l1ref0, *l1ref1;
@@ -425,27 +418,27 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
     unsigned int sub_mb_type;
     int i8, i4;
 
-    assert(h->ref_list[1][0].f.reference & 3);
+    assert(h->ref_list[1][0].reference & 3);
 
-    await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type));
+    await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type));
 
-    if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+    if (IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
         if (!IS_INTERLACED(*mb_type)) {                          //     AFR/FR    -> AFL/FL
-            mb_y = (s->mb_y&~1) + h->col_parity;
-            mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride;
+            mb_y = (h->mb_y&~1) + h->col_parity;
+            mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride;
             b8_stride = 0;
         }else{
             mb_y  += h->col_fieldoff;
-            mb_xy += s->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
+            mb_xy += h->mb_stride*h->col_fieldoff; // non zero for FL -> FL & differ parity
         }
         goto single_col;
     }else{                                               // AFL/AFR/FR/FL -> AFR/FR
         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
-            mb_y = s->mb_y&~1;
-            mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride;
-            mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride];
-            b8_stride = 2+4*s->mb_stride;
+            mb_y = h->mb_y&~1;
+            mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride;
+            mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
+            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + h->mb_stride];
+            b8_stride = 2+4*h->mb_stride;
             b4_stride *= 6;
             if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) {
                 mb_type_col[0] &= ~MB_TYPE_INTERLACED;
@@ -464,7 +457,7 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
         }else{                                           //     AFR/FR    -> AFR/FR
 single_col:
             mb_type_col[0] =
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy];
+            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
 
             sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
             if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
@@ -484,12 +477,12 @@ single_col:
 
     await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
 
-    l1mv0  = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
-    l1mv1  = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
-    l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
-    l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
+    l1mv0  = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
+    l1mv1  = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];
+    l1ref0 = &h->ref_list[1][0].ref_index [0][4 * mb_xy];
+    l1ref1 = &h->ref_list[1][0].ref_index [1][4 * mb_xy];
     if(!b8_stride){
-        if(s->mb_y&1){
+        if(h->mb_y&1){
             l1ref0 += 2;
             l1ref1 += 2;
             l1mv0  +=  2*b4_stride;
@@ -502,10 +495,10 @@ single_col:
         const int *dist_scale_factor = h->dist_scale_factor;
         int ref_offset;
 
-        if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){
-            map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0];
-            map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1];
-            dist_scale_factor   =h->dist_scale_factor_field[s->mb_y&1];
+        if (FRAME_MBAFF(h) && IS_INTERLACED(*mb_type)) {
+            map_col_to_list0[0] = h->map_col_to_list0_field[h->mb_y&1][0];
+            map_col_to_list0[1] = h->map_col_to_list0_field[h->mb_y&1][1];
+            dist_scale_factor   =h->dist_scale_factor_field[h->mb_y&1];
         }
         ref_offset = (h->ref_list[1][0].mbaff<<4) & (mb_type_col[0]>>3); //if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) ref_offset=16 else 0
 
diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c
index b045d23..b8bf555 100644
--- a/libavcodec/h264_loopfilter.c
+++ b/libavcodec/h264_loopfilter.c
@@ -25,16 +25,15 @@
  * @author Michael Niedermayer <michaelni at gmx.at>
  */
 
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h264.h"
 #include "mathops.h"
 #include "rectangle.h"
 
-//#undef NDEBUG
 #include <assert.h>
 
 /* Deblocking filter (p153) */
@@ -244,10 +243,9 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
                                                           unsigned int uvlinesize,
                                                           int pixel_shift)
 {
-    MpegEncContext * const s = &h->s;
-    int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
-    int chroma444 = CHROMA444;
-    int chroma422 = CHROMA422;
+    int chroma = !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
+    int chroma444 = CHROMA444(h);
+    int chroma422 = CHROMA422(h);
 
     int mb_xy = h->mb_xy;
     int left_type= h->left_type[LTOP];
@@ -257,10 +255,10 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
     int a = h->slice_alpha_c0_offset - qp_bd_offset;
     int b = h->slice_beta_offset - qp_bd_offset;
 
-    int mb_type = s->current_picture.f.mb_type[mb_xy];
-    int qp      = s->current_picture.f.qscale_table[mb_xy];
-    int qp0     = s->current_picture.f.qscale_table[mb_xy - 1];
-    int qp1     = s->current_picture.f.qscale_table[h->top_mb_xy];
+    int mb_type = h->cur_pic.mb_type[mb_xy];
+    int qp      = h->cur_pic.qscale_table[mb_xy];
+    int qp0     = h->cur_pic.qscale_table[mb_xy - 1];
+    int qp1     = h->cur_pic.qscale_table[h->top_mb_xy];
     int qpc = get_chroma_qp( h, 0, qp );
     int qpc0 = get_chroma_qp( h, 0, qp0 );
     int qpc1 = get_chroma_qp( h, 0, qp1 );
@@ -272,7 +270,7 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
     if( IS_INTRA(mb_type) ) {
         static const int16_t bS4[4] = {4,4,4,4};
         static const int16_t bS3[4] = {3,3,3,3};
-        const int16_t *bSH = FIELD_PICTURE ? bS3 : bS4;
+        const int16_t *bSH = FIELD_PICTURE(h) ? bS3 : bS4;
         if(left_type)
             filter_mb_edgev( &img_y[4*0<<pixel_shift], linesize, bS4, qp0, a, b, h, 1);
         if( IS_8x8DCT(mb_type) ) {
@@ -373,12 +371,12 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
             int step =  1+(mb_type>>24); //IS_8x8DCT(mb_type) ? 2 : 1;
             edges = 4 - 3*((mb_type>>3) & !(h->cbp & 15)); //(mb_type & MB_TYPE_16x16) && !(h->cbp & 15) ? 1 : 4;
             h->h264dsp.h264_loop_filter_strength( bS, h->non_zero_count_cache, h->ref_cache, h->mv_cache,
-                                              h->list_count==2, edges, step, mask_edge0, mask_edge1, FIELD_PICTURE);
+                                              h->list_count==2, edges, step, mask_edge0, mask_edge1, FIELD_PICTURE(h));
         }
         if( IS_INTRA(left_type) )
             AV_WN64A(bS[0][0], 0x0004000400040004ULL);
         if( IS_INTRA(top_type) )
-            AV_WN64A(bS[1][0], FIELD_PICTURE ? 0x0003000300030003ULL : 0x0004000400040004ULL);
+            AV_WN64A(bS[1][0], FIELD_PICTURE(h) ? 0x0003000300030003ULL : 0x0004000400040004ULL);
 
 #define FILTER(hv,dir,edge,intra)\
         if(AV_RN64A(bS[dir][edge])) {                                   \
@@ -418,7 +416,7 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
 }
 
 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);
+    assert(!FRAME_MBAFF(h));
     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;
@@ -465,11 +463,10 @@ static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
 }
 
 static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int a, int b, int chroma, int dir) {
-    MpegEncContext * const s = &h->s;
     int edge;
     int chroma_qp_avg[2];
-    int chroma444 = CHROMA444;
-    int chroma422 = CHROMA422;
+    int chroma444 = CHROMA444(h);
+    int chroma422 = CHROMA422(h);
     const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
     const int mbm_type = dir == 0 ? h->left_type[LTOP] : h->top_type;
 
@@ -484,7 +481,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
 
     if(mbm_type && !first_vertical_edge_done){
 
-        if (FRAME_MBAFF && (dir == 1) && ((mb_y&1) == 0)
+        if (FRAME_MBAFF(h) && (dir == 1) && ((mb_y&1) == 0)
             && IS_INTERLACED(mbm_type&~mb_type)
             ) {
             // This is a special case in the norm where the filtering must
@@ -493,16 +490,16 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             //
             unsigned int tmp_linesize   = 2 *   linesize;
             unsigned int tmp_uvlinesize = 2 * uvlinesize;
-            int mbn_xy = mb_xy - 2 * s->mb_stride;
+            int mbn_xy = mb_xy - 2 * h->mb_stride;
             int j;
 
-            for(j=0; j<2; j++, mbn_xy += s->mb_stride){
+            for(j=0; j<2; j++, mbn_xy += h->mb_stride){
                 DECLARE_ALIGNED(8, int16_t, bS)[4];
                 int qp;
-                if (IS_INTRA(mb_type | s->current_picture.f.mb_type[mbn_xy])) {
+                if (IS_INTRA(mb_type | h->cur_pic.mb_type[mbn_xy])) {
                     AV_WN64A(bS, 0x0003000300030003ULL);
                 } else {
-                    if (!CABAC && IS_8x8DCT(s->current_picture.f.mb_type[mbn_xy])) {
+                    if (!CABAC(h) && IS_8x8DCT(h->cur_pic.mb_type[mbn_xy])) {
                         bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+0]);
                         bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+1]);
                         bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+2]);
@@ -517,12 +514,12 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
                 }
                 // Do not use s->qscale as luma quantizer because it has not the same
                 // value in IPCM macroblocks.
-                qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbn_xy] + 1) >> 1;
-                tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
-                { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
+                qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbn_xy] + 1) >> 1;
+                tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
+                { int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
                 filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 );
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
                 if (chroma) {
                     if (chroma444) {
                         filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
@@ -540,14 +537,14 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             if( IS_INTRA(mb_type|mbm_type)) {
                 AV_WN64A(bS, 0x0003000300030003ULL);
                 if (   (!IS_INTERLACED(mb_type|mbm_type))
-                    || ((FRAME_MBAFF || (s->picture_structure != PICT_FRAME)) && (dir == 0))
+                    || ((FRAME_MBAFF(h) || (h->picture_structure != PICT_FRAME)) && (dir == 0))
                 )
                     AV_WN64A(bS, 0x0004000400040004ULL);
             } else {
                 int i;
                 int mv_done;
 
-                if( dir && FRAME_MBAFF && IS_INTERLACED(mb_type ^ mbm_type)) {
+                if( dir && FRAME_MBAFF(h) && IS_INTERLACED(mb_type ^ mbm_type)) {
                     AV_WN64A(bS, 0x0001000100010001ULL);
                     mv_done = 1;
                 }
@@ -582,10 +579,10 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             // Do not use s->qscale as luma quantizer because it has not the same
             // value in IPCM macroblocks.
             if(bS[0]+bS[1]+bS[2]+bS[3]){
-                qp = (s->current_picture.f.qscale_table[mb_xy] + s->current_picture.f.qscale_table[mbm_xy] + 1) >> 1;
-                tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, s->current_picture.f.qscale_table[mbm_xy]) + 1) >> 1;
+                qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbm_xy] + 1) >> 1;
+                tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
+                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
                 if( dir == 0 ) {
                     filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
                     if (chroma) {
@@ -665,8 +662,8 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
         /* Filter edge */
         // Do not use s->qscale as luma quantizer because it has not the same
         // value in IPCM macroblocks.
-        qp = s->current_picture.f.qscale_table[mb_xy];
-        tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
+        qp = h->cur_pic.qscale_table[mb_xy];
+        tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
         if( dir == 0 ) {
             filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
             if (chroma) {
@@ -703,18 +700,17 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
 }
 
 void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
-    MpegEncContext * const s = &h->s;
-    const int mb_xy= mb_x + mb_y*s->mb_stride;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_xy= mb_x + mb_y*h->mb_stride;
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
     int first_vertical_edge_done = 0;
     av_unused int dir;
-    int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
+    int chroma = !(CONFIG_GRAY && (h->flags&CODEC_FLAG_GRAY));
     int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
     int a = h->slice_alpha_c0_offset - qp_bd_offset;
     int b = h->slice_beta_offset - qp_bd_offset;
 
-    if (FRAME_MBAFF
+    if (FRAME_MBAFF(h)
             // and current and left pair do not have the same interlaced type
             && IS_INTERLACED(mb_type^h->left_type[LTOP])
             // and left mb is in available to us
@@ -743,9 +739,9 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
                     {3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},
                 }
             };
-            const uint8_t *off= offset[MB_FIELD][mb_y&1];
+            const uint8_t *off= offset[MB_FIELD(h)][mb_y&1];
             for( i = 0; i < 8; i++ ) {
-                int j= MB_FIELD ? i>>2 : i&1;
+                int j= MB_FIELD(h) ? i>>2 : i&1;
                 int mbn_xy = h->left_mb_xy[LEFT(j)];
                 int mbn_type= h->left_type[LEFT(j)];
 
@@ -754,16 +750,16 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
                 else{
                     bS[i] = 1 + !!(h->non_zero_count_cache[12+8*(i>>1)] |
                          ((!h->pps.cabac && IS_8x8DCT(mbn_type)) ?
-                            (h->cbp_table[mbn_xy] & (((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2) << 12))
+                            (h->cbp_table[mbn_xy] & (((MB_FIELD(h) ? (i&2) : (mb_y&1)) ? 8 : 2) << 12))
                                                                        :
                             h->non_zero_count[mbn_xy][ off[i] ]));
                 }
             }
         }
 
-        mb_qp   = s->current_picture.f.qscale_table[mb_xy];
-        mbn0_qp = s->current_picture.f.qscale_table[h->left_mb_xy[0]];
-        mbn1_qp = s->current_picture.f.qscale_table[h->left_mb_xy[1]];
+        mb_qp   = h->cur_pic.qscale_table[mb_xy];
+        mbn0_qp = h->cur_pic.qscale_table[h->left_mb_xy[0]];
+        mbn1_qp = h->cur_pic.qscale_table[h->left_mb_xy[1]];
         qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
         bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +
                    get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;
@@ -776,18 +772,18 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
                    get_chroma_qp( h, 1, mbn1_qp ) + 1 ) >> 1;
 
         /* Filter edge */
-        tprintf(s->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
-        { int i; for (i = 0; i < 8; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
-        if(MB_FIELD){
+        tprintf(h->avctx, "filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], bqp[0], bqp[1], rqp[0], rqp[1], linesize, uvlinesize);
+        { int i; for (i = 0; i < 8; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
+        if (MB_FIELD(h)) {
             filter_mb_mbaff_edgev ( h, img_y                ,   linesize, bS  , 1, qp [0], a, b, 1 );
             filter_mb_mbaff_edgev ( h, img_y  + 8*  linesize,   linesize, bS+4, 1, qp [1], a, b, 1 );
             if (chroma){
-                if (CHROMA444) {
+                if (CHROMA444(h)) {
                     filter_mb_mbaff_edgev ( h, img_cb,                uvlinesize, bS  , 1, bqp[0], a, b, 1 );
                     filter_mb_mbaff_edgev ( h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1 );
                     filter_mb_mbaff_edgev ( h, img_cr,                uvlinesize, bS  , 1, rqp[0], a, b, 1 );
                     filter_mb_mbaff_edgev ( h, img_cr + 8*uvlinesize, uvlinesize, bS+4, 1, rqp[1], a, b, 1 );
-                } else if (CHROMA422) {
+                } else if (CHROMA422(h)) {
                     filter_mb_mbaff_edgecv(h, img_cb,                uvlinesize, bS  , 1, bqp[0], a, b, 1);
                     filter_mb_mbaff_edgecv(h, img_cb + 8*uvlinesize, uvlinesize, bS+4, 1, bqp[1], a, b, 1);
                     filter_mb_mbaff_edgecv(h, img_cr,                uvlinesize, bS  , 1, rqp[0], a, b, 1);
@@ -803,7 +799,7 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
             filter_mb_mbaff_edgev ( h, img_y              , 2*  linesize, bS  , 2, qp [0], a, b, 1 );
             filter_mb_mbaff_edgev ( h, img_y  +   linesize, 2*  linesize, bS+1, 2, qp [1], a, b, 1 );
             if (chroma){
-                if (CHROMA444) {
+                if (CHROMA444(h)) {
                     filter_mb_mbaff_edgev ( h, img_cb,              2*uvlinesize, bS  , 2, bqp[0], a, b, 1 );
                     filter_mb_mbaff_edgev ( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1], a, b, 1 );
                     filter_mb_mbaff_edgev ( h, img_cr,              2*uvlinesize, bS  , 2, rqp[0], a, b, 1 );
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index e27fd13..9b63fef 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -40,61 +40,60 @@
 
 static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_x    = s->mb_x;
-    const int mb_y    = s->mb_y;
+    const int mb_x    = h->mb_x;
+    const int mb_y    = h->mb_y;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize /*dct_offset*/;
     int i, j;
     int *block_offset = &h->block_offset[0];
-    const int transform_bypass = !SIMPLE && (s->qscale == 0 && h->sps.transform_bypass);
+    const int transform_bypass = !SIMPLE && (h->qscale == 0 && h->sps.transform_bypass);
     /* is_h264 should always be true if SVQ3 is disabled. */
-    const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || s->codec_id == AV_CODEC_ID_H264;
-    void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
-    const int block_h   = 16 >> s->chroma_y_shift;
-    const int chroma422 = CHROMA422;
+    const int is_h264 = !CONFIG_SVQ3_DECODER || SIMPLE || h->avctx->codec_id == AV_CODEC_ID_H264;
+    void (*idct_add)(uint8_t *dst, int16_t *block, int stride);
+    const int block_h   = 16 >> h->chroma_y_shift;
+    const int chroma422 = CHROMA422(h);
 
-    dest_y  = s->current_picture.f.data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * s->linesize)  * 16;
-    dest_cb = s->current_picture.f.data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * s->uvlinesize * block_h;
-    dest_cr = s->current_picture.f.data[2] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * s->uvlinesize * block_h;
+    dest_y  = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT)     + mb_y * h->linesize)  * 16;
+    dest_cb = h->cur_pic.f.data[1] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h;
+    dest_cr = h->cur_pic.f.data[2] +  (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h;
 
-    s->vdsp.prefetch(dest_y  + (s->mb_x & 3) * 4 * s->linesize   + (64 << PIXEL_SHIFT), s->linesize,       4);
-    s->vdsp.prefetch(dest_cb + (s->mb_x & 7)     * s->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
+    h->vdsp.prefetch(dest_y  + (h->mb_x & 3) * 4 * h->linesize   + (64 << PIXEL_SHIFT), h->linesize,       4);
+    h->vdsp.prefetch(dest_cb + (h->mb_x & 7)     * h->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2);
 
     h->list_counts[mb_xy] = h->list_count;
 
-    if (!SIMPLE && MB_FIELD) {
-        linesize     = h->mb_linesize = s->linesize * 2;
-        uvlinesize   = h->mb_uvlinesize = s->uvlinesize * 2;
+    if (!SIMPLE && MB_FIELD(h)) {
+        linesize     = h->mb_linesize = h->linesize * 2;
+        uvlinesize   = h->mb_uvlinesize = h->uvlinesize * 2;
         block_offset = &h->block_offset[48];
         if (mb_y & 1) { // FIXME move out of this function?
-            dest_y  -= s->linesize * 15;
-            dest_cb -= s->uvlinesize * (block_h - 1);
-            dest_cr -= s->uvlinesize * (block_h - 1);
+            dest_y  -= h->linesize * 15;
+            dest_cb -= h->uvlinesize * (block_h - 1);
+            dest_cr -= h->uvlinesize * (block_h - 1);
         }
-        if (FRAME_MBAFF) {
+        if (FRAME_MBAFF(h)) {
             int list;
             for (list = 0; list < h->list_count; list++) {
                 if (!USES_LIST(mb_type, list))
                     continue;
                 if (IS_16X16(mb_type)) {
                     int8_t *ref = &h->ref_cache[list][scan8[0]];
-                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
+                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1);
                 } else {
                     for (i = 0; i < 16; i += 4) {
                         int ref = h->ref_cache[list][scan8[i]];
                         if (ref >= 0)
                             fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
-                                           8, (16 + ref) ^ (s->mb_y & 1), 1);
+                                           8, (16 + ref) ^ (h->mb_y & 1), 1);
                     }
                 }
             }
         }
     } else {
-        linesize   = h->mb_linesize   = s->linesize;
-        uvlinesize = h->mb_uvlinesize = s->uvlinesize;
+        linesize   = h->mb_linesize   = h->linesize;
+        uvlinesize = h->mb_uvlinesize = h->uvlinesize;
         // dct_offset = s->linesize * 16;
     }
 
@@ -103,7 +102,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
             const int bit_depth = h->sps.bit_depth_luma;
             int j;
             GetBitContext gb;
-            init_get_bits(&gb, (uint8_t *)h->mb,
+            init_get_bits(&gb, h->intra_pcm_ptr,
                           ff_h264_mb_sizes[h->sps.chroma_format_idc] * bit_depth);
 
             for (i = 0; i < 16; i++) {
@@ -111,7 +110,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                 for (j = 0; j < 16; j++)
                     tmp_y[j] = get_bits(&gb, bit_depth);
             }
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 if (!h->sps.chroma_format_idc) {
                     for (i = 0; i < block_h; i++) {
                         uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
@@ -138,16 +137,16 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
             }
         } else {
             for (i = 0; i < 16; i++)
-                memcpy(dest_y + i * linesize, (uint8_t *)h->mb + i * 16, 16);
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+                memcpy(dest_y + i * linesize, h->intra_pcm_ptr + i * 16, 16);
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 if (!h->sps.chroma_format_idc) {
                     for (i = 0; i < block_h; i++) {
                         memset(dest_cb + i * uvlinesize, 128, 8);
                         memset(dest_cr + i * uvlinesize, 128, 8);
                     }
                 } else {
-                    uint8_t *src_cb = (uint8_t *)h->mb + 256;
-                    uint8_t *src_cr = (uint8_t *)h->mb + 256 + block_h * 8;
+                    const uint8_t *src_cb = h->intra_pcm_ptr + 256;
+                    const uint8_t *src_cr = h->intra_pcm_ptr + 256 + block_h * 8;
                     for (i = 0; i < block_h; i++) {
                         memcpy(dest_cb + i * uvlinesize, src_cb + i * 8, 8);
                         memcpy(dest_cr + i * uvlinesize, src_cr + i * 8, 8);
@@ -161,7 +160,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                 xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
                                uvlinesize, 1, 0, SIMPLE, PIXEL_SHIFT);
 
-            if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+            if (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) {
                 h->hpc.pred8x8[h->chroma_pred_mode](dest_cb, uvlinesize);
                 h->hpc.pred8x8[h->chroma_pred_mode](dest_cr, uvlinesize);
             }
@@ -176,14 +175,14 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
         } else if (is_h264) {
             if (chroma422) {
                 FUNC(hl_motion_422)(h, dest_y, dest_cb, dest_cr,
-                              s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
-                              s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+                              h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                              h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                               h->h264dsp.weight_h264_pixels_tab,
                               h->h264dsp.biweight_h264_pixels_tab);
             } else {
                 FUNC(hl_motion_420)(h, dest_y, dest_cb, dest_cr,
-                              s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
-                              s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+                              h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                              h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                               h->h264dsp.weight_h264_pixels_tab,
                               h->h264dsp.biweight_h264_pixels_tab);
             }
@@ -192,7 +191,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
         hl_decode_mb_idct_luma(h, mb_type, is_h264, SIMPLE, transform_bypass,
                                PIXEL_SHIFT, block_offset, linesize, dest_y, 0);
 
-        if ((SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) &&
+        if ((SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) &&
             (h->cbp & 0x30)) {
             uint8_t *dest[2] = { dest_cb, dest_cr };
             if (transform_bypass) {
@@ -208,7 +207,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                                                             h->mb + (16 * 16 * 2 << PIXEL_SHIFT),
                                                             uvlinesize);
                 } else {
-                    idct_add = s->dsp.add_pixels4;
+                    idct_add = h->h264dsp.h264_add_pixels4_clear;
                     for (j = 1; j < 3; j++) {
                         for (i = j * 16; i < j * 16 + 4; i++)
                             if (h->non_zero_count_cache[scan8[i]] ||
@@ -256,17 +255,13 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
                                 uint8_t *const ptr = dest[j - 1] + block_offset[i];
                                 ff_svq3_add_idct_c(ptr, h->mb + i * 16,
                                                    uvlinesize,
-                                                   ff_h264_chroma_qp[0][s->qscale + 12] - 12, 2);
+                                                   ff_h264_chroma_qp[0][h->qscale + 12] - 12, 2);
                             }
                     }
                 }
             }
         }
     }
-    if (h->cbp || IS_INTRA(mb_type)) {
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
-    }
 }
 
 #if !SIMPLE || BITS == 8
@@ -277,60 +272,59 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
 
 static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
-    const int mb_x    = s->mb_x;
-    const int mb_y    = s->mb_y;
+    const int mb_x    = h->mb_x;
+    const int mb_y    = h->mb_y;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     uint8_t *dest[3];
     int linesize;
     int i, j, p;
     int *block_offset = &h->block_offset[0];
-    const int transform_bypass = !SIMPLE && (s->qscale == 0 && h->sps.transform_bypass);
-    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
+    const int transform_bypass = !SIMPLE && (h->qscale == 0 && h->sps.transform_bypass);
+    const int plane_count      = (SIMPLE || !CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) ? 3 : 1;
 
     for (p = 0; p < plane_count; p++) {
-        dest[p] = s->current_picture.f.data[p] +
-                  ((mb_x << PIXEL_SHIFT) + mb_y * s->linesize) * 16;
-        s->vdsp.prefetch(dest[p] + (s->mb_x & 3) * 4 * s->linesize + (64 << PIXEL_SHIFT),
-                         s->linesize, 4);
+        dest[p] = h->cur_pic.f.data[p] +
+                  ((mb_x << PIXEL_SHIFT) + mb_y * h->linesize) * 16;
+        h->vdsp.prefetch(dest[p] + (h->mb_x & 3) * 4 * h->linesize + (64 << PIXEL_SHIFT),
+                         h->linesize, 4);
     }
 
     h->list_counts[mb_xy] = h->list_count;
 
-    if (!SIMPLE && MB_FIELD) {
-        linesize     = h->mb_linesize = h->mb_uvlinesize = s->linesize * 2;
+    if (!SIMPLE && MB_FIELD(h)) {
+        linesize     = h->mb_linesize = h->mb_uvlinesize = h->linesize * 2;
         block_offset = &h->block_offset[48];
         if (mb_y & 1) // FIXME move out of this function?
             for (p = 0; p < 3; p++)
-                dest[p] -= s->linesize * 15;
-        if (FRAME_MBAFF) {
+                dest[p] -= h->linesize * 15;
+        if (FRAME_MBAFF(h)) {
             int list;
             for (list = 0; list < h->list_count; list++) {
                 if (!USES_LIST(mb_type, list))
                     continue;
                 if (IS_16X16(mb_type)) {
                     int8_t *ref = &h->ref_cache[list][scan8[0]];
-                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (s->mb_y & 1), 1);
+                    fill_rectangle(ref, 4, 4, 8, (16 + *ref) ^ (h->mb_y & 1), 1);
                 } else {
                     for (i = 0; i < 16; i += 4) {
                         int ref = h->ref_cache[list][scan8[i]];
                         if (ref >= 0)
                             fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2,
-                                           8, (16 + ref) ^ (s->mb_y & 1), 1);
+                                           8, (16 + ref) ^ (h->mb_y & 1), 1);
                     }
                 }
             }
         }
     } else {
-        linesize = h->mb_linesize = h->mb_uvlinesize = s->linesize;
+        linesize = h->mb_linesize = h->mb_uvlinesize = h->linesize;
     }
 
     if (!SIMPLE && IS_INTRA_PCM(mb_type)) {
         if (PIXEL_SHIFT) {
             const int bit_depth = h->sps.bit_depth_luma;
             GetBitContext gb;
-            init_get_bits(&gb, (uint8_t *)h->mb, 768 * bit_depth);
+            init_get_bits(&gb, h->intra_pcm_ptr, 768 * bit_depth);
 
             for (p = 0; p < plane_count; p++)
                 for (i = 0; i < 16; i++) {
@@ -342,7 +336,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
             for (p = 0; p < plane_count; p++)
                 for (i = 0; i < 16; i++)
                     memcpy(dest[p] + i * linesize,
-                           (uint8_t *)h->mb + p * 256 + i * 16, 16);
+                           h->intra_pcm_ptr + p * 256 + i * 16, 16);
         }
     } else {
         if (IS_INTRA(mb_type)) {
@@ -360,8 +354,8 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
                                linesize, 0, 1, SIMPLE, PIXEL_SHIFT);
         } else {
             FUNC(hl_motion_444)(h, dest[0], dest[1], dest[2],
-                      s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,
-                      s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,
+                      h->me.qpel_put, h->h264chroma.put_h264_chroma_pixels_tab,
+                      h->me.qpel_avg, h->h264chroma.avg_h264_chroma_pixels_tab,
                       h->h264dsp.weight_h264_pixels_tab,
                       h->h264dsp.biweight_h264_pixels_tab);
         }
@@ -371,10 +365,6 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
                                    PIXEL_SHIFT, block_offset, linesize,
                                    dest[p], p);
     }
-    if (h->cbp || IS_INTRA(mb_type)) {
-        s->dsp.clear_blocks(h->mb);
-        s->dsp.clear_blocks(h->mb + (24 * 16 << PIXEL_SHIFT));
-    }
 }
 
 #endif
diff --git a/libavcodec/h264_mc_template.c b/libavcodec/h264_mc_template.c
index a3af39b..dee02f5 100644
--- a/libavcodec/h264_mc_template.c
+++ b/libavcodec/h264_mc_template.c
@@ -46,7 +46,7 @@ static void mc_part(H264Context *h, int n, int square,
                     int list0, int list1)
 {
     if ((h->use_weight == 2 && list0 && list1 &&
-         (h->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->s.mb_y & 1] != 32)) ||
+         (h->implicit_weight[h->ref_cache[0][scan8[n]]][h->ref_cache[1][scan8[n]]][h->mb_y & 1] != 32)) ||
         h->use_weight == 1)
         mc_part_weighted(h, n, square, height, delta, dest_y, dest_cb, dest_cr,
                          x_offset, y_offset, qpix_put, chroma_put,
@@ -67,13 +67,12 @@ static void MCFUNC(hl_motion)(H264Context *h, uint8_t *dest_y,
                               h264_weight_func *weight_op,
                               h264_biweight_func *weight_avg)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = s->current_picture.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
 
     assert(IS_INTER(mb_type));
 
-    if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+    if (HAVE_THREADS && (h->avctx->active_thread_type & FF_THREAD_FRAME))
         await_references(h);
     prefetch_motion(h, 0, PIXEL_SHIFT, CHROMA_IDC);
 
diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
index 276751e..3b212e5 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -31,118 +31,135 @@ typedef struct H264BSFContext {
     int      extradata_parsed;
 } H264BSFContext;
 
-static int alloc_and_copy(uint8_t **poutbuf,          int *poutbuf_size,
+static int alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *sps_pps, uint32_t sps_pps_size,
-                          const uint8_t *in,      uint32_t in_size) {
-    uint32_t offset = *poutbuf_size;
+                          const uint8_t *in, uint32_t in_size)
+{
+    uint32_t offset         = *poutbuf_size;
     uint8_t nal_header_size = offset ? 3 : 4;
-    void *tmp;
+    int err;
 
-    *poutbuf_size += sps_pps_size+in_size+nal_header_size;
-    tmp = av_realloc(*poutbuf, *poutbuf_size);
-    if (!tmp)
-        return AVERROR(ENOMEM);
-    *poutbuf = tmp;
+    *poutbuf_size += sps_pps_size + in_size + nal_header_size;
+    if ((err = av_reallocp(poutbuf,
+                           *poutbuf_size + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+        *poutbuf_size = 0;
+        return err;
+    }
     if (sps_pps)
-        memcpy(*poutbuf+offset, sps_pps, sps_pps_size);
-    memcpy(*poutbuf+sps_pps_size+nal_header_size+offset, in, in_size);
+        memcpy(*poutbuf + offset, sps_pps, sps_pps_size);
+    memcpy(*poutbuf + sps_pps_size + nal_header_size + offset, in, in_size);
     if (!offset) {
-        AV_WB32(*poutbuf+sps_pps_size, 1);
+        AV_WB32(*poutbuf + sps_pps_size, 1);
     } else {
-        (*poutbuf+offset+sps_pps_size)[0] = (*poutbuf+offset+sps_pps_size)[1] = 0;
-        (*poutbuf+offset+sps_pps_size)[2] = 1;
+        (*poutbuf + offset + sps_pps_size)[0] =
+        (*poutbuf + offset + sps_pps_size)[1] = 0;
+        (*poutbuf + offset + sps_pps_size)[2] = 1;
     }
 
     return 0;
 }
 
+static int h264_extradata_to_annexb(AVCodecContext *avctx, const int padding)
+{
+    uint16_t unit_size;
+    uint64_t total_size                 = 0;
+    uint8_t *out                        = NULL, unit_nb, sps_done = 0,
+             sps_seen                   = 0, pps_seen = 0;
+    const uint8_t *extradata            = avctx->extradata + 4;
+    static const uint8_t nalu_header[4] = { 0, 0, 0, 1 };
+    int length_size = (*extradata++ & 0x3) + 1; // retrieve length coded size
+
+    if (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;
+    } else {
+        sps_seen = 1;
+    }
+
+    while (unit_nb--) {
+        int err;
+
+        unit_size   = AV_RB16(extradata);
+        total_size += unit_size + 4;
+        if (total_size > INT_MAX - padding ||
+            extradata + 2 + unit_size > avctx->extradata +
+            avctx->extradata_size) {
+            av_free(out);
+            return AVERROR(EINVAL);
+        }
+        if ((err = av_reallocp(&out, total_size + padding)) < 0)
+            return err;
+        memcpy(out + total_size - unit_size - 4, nalu_header, 4);
+        memcpy(out + total_size - unit_size, extradata + 2, unit_size);
+        extradata += 2 + unit_size;
+
+        if (!unit_nb && !sps_done++) {
+            unit_nb = *extradata++; /* number of pps unit(s) */
+            if (unit_nb)
+                pps_seen = 1;
+        }
+    }
+
+    if (out)
+        memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+    if (!sps_seen)
+        av_log(avctx, AV_LOG_WARNING,
+               "Warning: SPS NALU missing or invalid. "
+               "The resulting stream may not play.\n");
+
+    if (!pps_seen)
+        av_log(avctx, AV_LOG_WARNING,
+               "Warning: PPS NALU missing or invalid. "
+               "The resulting stream may not play.\n");
+
+    av_free(avctx->extradata);
+    avctx->extradata      = out;
+    avctx->extradata_size = total_size;
+
+    return length_size;
+}
+
 static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
                                    AVCodecContext *avctx, const char *args,
-                                   uint8_t  **poutbuf, int *poutbuf_size,
-                                   const uint8_t *buf, int      buf_size,
-                                   int keyframe) {
+                                   uint8_t **poutbuf, int *poutbuf_size,
+                                   const uint8_t *buf, int buf_size,
+                                   int keyframe)
+{
     H264BSFContext *ctx = bsfc->priv_data;
     uint8_t unit_type;
     int32_t nal_size;
-    uint32_t cumul_size = 0;
+    uint32_t cumul_size    = 0;
     const uint8_t *buf_end = buf + buf_size;
+    int ret = 0;
 
     /* nothing to filter */
     if (!avctx->extradata || avctx->extradata_size < 6) {
-        *poutbuf = (uint8_t*) buf;
+        *poutbuf      = (uint8_t *)buf;
         *poutbuf_size = buf_size;
         return 0;
     }
 
     /* retrieve sps and pps NAL units from extradata */
     if (!ctx->extradata_parsed) {
-        uint16_t unit_size;
-        uint64_t total_size = 0;
-        uint8_t *out = NULL, unit_nb, sps_done = 0, sps_seen = 0, pps_seen = 0;
-        const uint8_t *extradata = avctx->extradata+4;
-        static const uint8_t nalu_header[4] = {0, 0, 0, 1};
-
-        /* retrieve length coded size */
-        ctx->length_size = (*extradata++ & 0x3) + 1;
-        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;
-        } else {
-            sps_seen = 1;
-        }
-
-        while (unit_nb--) {
-            void *tmp;
-
-            unit_size = AV_RB16(extradata);
-            total_size += unit_size+4;
-            if (total_size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE ||
-                extradata+2+unit_size > avctx->extradata+avctx->extradata_size) {
-                av_free(out);
-                return AVERROR(EINVAL);
-            }
-            tmp = av_realloc(out, total_size + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!tmp) {
-                av_free(out);
-                return AVERROR(ENOMEM);
-            }
-            out = tmp;
-            memcpy(out+total_size-unit_size-4, nalu_header, 4);
-            memcpy(out+total_size-unit_size,   extradata+2, unit_size);
-            extradata += 2+unit_size;
-
-            if (!unit_nb && !sps_done++) {
-                unit_nb = *extradata++; /* number of pps unit(s) */
-                if (unit_nb)
-                    pps_seen = 1;
-            }
-        }
-
-        if(out)
-            memset(out + total_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-
-        if (!sps_seen)
-            av_log(avctx, AV_LOG_WARNING, "Warning: SPS NALU missing or invalid. The resulting stream may not play.\n");
-        if (!pps_seen)
-            av_log(avctx, AV_LOG_WARNING, "Warning: PPS NALU missing or invalid. The resulting stream may not play.\n");
-
-        av_free(avctx->extradata);
-        avctx->extradata      = out;
-        avctx->extradata_size = total_size;
+        ret = h264_extradata_to_annexb(avctx, FF_INPUT_BUFFER_PADDING_SIZE);
+        if (ret < 0)
+            return ret;
+        ctx->length_size      = ret;
         ctx->first_idr        = 1;
         ctx->extradata_parsed = 1;
     }
 
     *poutbuf_size = 0;
-    *poutbuf = NULL;
+    *poutbuf      = NULL;
     do {
         if (buf + ctx->length_size > buf_end)
             goto fail;
@@ -154,7 +171,7 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
         } else
             nal_size = AV_RB32(buf);
 
-        buf += ctx->length_size;
+        buf      += ctx->length_size;
         unit_type = *buf & 0x1f;
 
         if (buf + nal_size > buf_end || nal_size < 0)
@@ -169,14 +186,13 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
             ctx->first_idr = 0;
         } else {
             if (alloc_and_copy(poutbuf, poutbuf_size,
-                               NULL, 0,
-                               buf, nal_size) < 0)
+                               NULL, 0, buf, nal_size) < 0)
                 goto fail;
             if (!ctx->first_idr && unit_type == 1)
                 ctx->first_idr = 1;
         }
 
-        buf += nal_size;
+        buf        += nal_size;
         cumul_size += nal_size + ctx->length_size;
     } while (cumul_size < buf_size);
 
diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h
index 5244c29..a7545f0 100644
--- a/libavcodec/h264_mvpred.h
+++ b/libavcodec/h264_mvpred.h
@@ -32,41 +32,39 @@
 #include "avcodec.h"
 #include "h264.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)
 {
     const int topright_ref = h->ref_cache[list][i - 8 + part_width];
-    MpegEncContext *s      = &h->s;
 
     /* there is no consistent mapping of mvs to neighboring locations that will
      * make mbaff happy, so we can't move all this logic to fill_caches */
-    if (FRAME_MBAFF) {
+    if (FRAME_MBAFF(h)) {
 #define SET_DIAG_MV(MV_OP, REF_OP, XY, Y4)                              \
         const int xy = XY, y4 = Y4;                                     \
-        const int mb_type = mb_types[xy + (y4 >> 2) * s->mb_stride];    \
+        const int mb_type = mb_types[xy + (y4 >> 2) * h->mb_stride];    \
         if (!USES_LIST(mb_type, list))                                  \
             return LIST_NOT_USED;                                       \
-        mv = s->current_picture_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
+        mv = h->cur_pic_ptr->motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
         h->mv_cache[list][scan8[0] - 2][0] = mv[0];                     \
         h->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP;               \
-        return s->current_picture_ptr->f.ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
+        return h->cur_pic_ptr->ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
 
         if (topright_ref == PART_NOT_AVAILABLE
             && i >= scan8[0] + 8 && (i & 7) == 4
             && h->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
-            const uint32_t *mb_types = s->current_picture_ptr->f.mb_type;
+            const uint32_t *mb_types = h->cur_pic_ptr->mb_type;
             const int16_t *mv;
             AV_ZERO32(h->mv_cache[list][scan8[0] - 2]);
             *C = h->mv_cache[list][scan8[0] - 2];
 
-            if (!MB_FIELD && IS_INTERLACED(h->left_type[0])) {
-                SET_DIAG_MV(* 2, >> 1, h->left_mb_xy[0] + s->mb_stride,
-                            (s->mb_y & 1) * 2 + (i >> 5));
+            if (!MB_FIELD(h) && IS_INTERLACED(h->left_type[0])) {
+                SET_DIAG_MV(* 2, >> 1, h->left_mb_xy[0] + h->mb_stride,
+                            (h->mb_y & 1) * 2 + (i >> 5));
             }
-            if (MB_FIELD && !IS_INTERLACED(h->left_type[0])) {
+            if (MB_FIELD(h) && !IS_INTERLACED(h->left_type[0])) {
                 // left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK.
                 SET_DIAG_MV(/ 2, << 1, h->left_mb_xy[i >= 36], ((i >> 2)) & 3);
             }
@@ -78,7 +76,7 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C,
         *C = h->mv_cache[list][i - 8 + part_width];
         return topright_ref;
     } else {
-        tprintf(s->avctx, "topright MV not available\n");
+        tprintf(h->avctx, "topright MV not available\n");
 
         *C = h->mv_cache[list][i - 8 - 1];
         return h->ref_cache[list][i - 8 - 1];
@@ -116,7 +114,7 @@ static av_always_inline void pred_motion(H264Context *const h, int n,
 
     diagonal_ref = fetch_diagonal_mv(h, &C, index8, list, part_width);
     match_count  = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref);
-    tprintf(h->s.avctx, "pred_motion match_count=%d\n", match_count);
+    tprintf(h->avctx, "pred_motion match_count=%d\n", match_count);
     if (match_count > 1) { //most common
         *mx = mid_pred(A[0], B[0], C[0]);
         *my = mid_pred(A[1], B[1], C[1]);
@@ -143,10 +141,10 @@ static av_always_inline void pred_motion(H264Context *const h, int n,
         }
     }
 
-    tprintf(h->s.avctx,
+    tprintf(h->avctx,
             "pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n",
             top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref,
-            A[0], A[1], ref, *mx, *my, h->s.mb_x, h->s.mb_y, n, list);
+            A[0], A[1], ref, *mx, *my, h->mb_x, h->mb_y, n, list);
 }
 
 /**
@@ -163,8 +161,8 @@ static av_always_inline void pred_16x8_motion(H264Context *const h,
         const int top_ref      = h->ref_cache[list][scan8[0] - 8];
         const int16_t *const B = h->mv_cache[list][scan8[0] - 8];
 
-        tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                top_ref, B[0], B[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                top_ref, B[0], B[1], h->mb_x, h->mb_y, n, list);
 
         if (top_ref == ref) {
             *mx = B[0];
@@ -175,8 +173,8 @@ static av_always_inline void pred_16x8_motion(H264Context *const h,
         const int left_ref     = h->ref_cache[list][scan8[8] - 1];
         const int16_t *const A = h->mv_cache[list][scan8[8] - 1];
 
-        tprintf(h->s.avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list);
 
         if (left_ref == ref) {
             *mx = A[0];
@@ -203,8 +201,8 @@ static av_always_inline void pred_8x16_motion(H264Context *const h,
         const int left_ref     = h->ref_cache[list][scan8[0] - 1];
         const int16_t *const A = h->mv_cache[list][scan8[0] - 1];
 
-        tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                left_ref, A[0], A[1], h->mb_x, h->mb_y, n, list);
 
         if (left_ref == ref) {
             *mx = A[0];
@@ -217,8 +215,8 @@ static av_always_inline void pred_8x16_motion(H264Context *const h,
 
         diagonal_ref = fetch_diagonal_mv(h, &C, scan8[4], list, 2);
 
-        tprintf(h->s.avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
-                diagonal_ref, C[0], C[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+                diagonal_ref, C[0], C[1], h->mb_x, h->mb_y, n, list);
 
         if (diagonal_ref == ref) {
             *mx = C[0];
@@ -232,8 +230,8 @@ static av_always_inline void pred_8x16_motion(H264Context *const h,
 }
 
 #define FIX_MV_MBAFF(type, refn, mvn, idx)      \
-    if (FRAME_MBAFF) {                          \
-        if (MB_FIELD) {                         \
+    if (FRAME_MBAFF(h)) {                       \
+        if (MB_FIELD(h)) {                      \
             if (!IS_INTERLACED(type)) {         \
                 refn <<= 1;                     \
                 AV_COPY32(mvbuf[idx], mvn);     \
@@ -254,9 +252,8 @@ static av_always_inline void pred_pskip_motion(H264Context *const h)
 {
     DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 };
     DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2];
-    MpegEncContext *const s = &h->s;
-    int8_t *ref     = s->current_picture.f.ref_index[0];
-    int16_t(*mv)[2] = s->current_picture.f.motion_val[0];
+    int8_t *ref     = h->cur_pic.ref_index[0];
+    int16_t(*mv)[2] = h->cur_pic.motion_val[0];
     int top_ref, left_ref, diagonal_ref, match_count, mx, my;
     const int16_t *A, *B, *C;
     int b_stride = h->b_stride;
@@ -294,8 +291,8 @@ static av_always_inline void pred_pskip_motion(H264Context *const h)
         goto zeromv;
     }
 
-    tprintf(h->s.avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
-            top_ref, left_ref, h->s.mb_x, h->s.mb_y);
+    tprintf(h->avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
+            top_ref, left_ref, h->mb_x, h->mb_y);
 
     if (USES_LIST(h->topright_type, 0)) {
         diagonal_ref = ref[4 * h->topright_mb_xy + 2];
@@ -321,7 +318,7 @@ static av_always_inline void pred_pskip_motion(H264Context *const h)
     }
 
     match_count = !diagonal_ref + !top_ref + !left_ref;
-    tprintf(h->s.avctx, "pred_pskip_motion match_count=%d\n", match_count);
+    tprintf(h->avctx, "pred_pskip_motion match_count=%d\n", match_count);
     if (match_count > 1) {
         mx = mid_pred(A[0], B[0], C[0]);
         my = mid_pred(A[1], B[1], C[1]);
@@ -351,7 +348,6 @@ zeromv:
 
 static void fill_decode_neighbors(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
     static const uint8_t left_block_options[4][32] = {
@@ -363,7 +359,7 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
 
     h->topleft_partition = -1;
 
-    top_xy = mb_xy - (s->mb_stride << MB_FIELD);
+    top_xy = mb_xy - (h->mb_stride << MB_FIELD(h));
 
     /* Wow, what a mess, why didn't they simplify the interlacing & intra
      * stuff, I can't imagine that these complex rules are worth it. */
@@ -372,17 +368,17 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
     topright_xy   = top_xy + 1;
     left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
     h->left_block = left_block_options[0];
-    if (FRAME_MBAFF) {
-        const int left_mb_field_flag = IS_INTERLACED(s->current_picture.f.mb_type[mb_xy - 1]);
+    if (FRAME_MBAFF(h)) {
+        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]);
         const int curr_mb_field_flag = IS_INTERLACED(mb_type);
-        if (s->mb_y & 1) {
+        if (h->mb_y & 1) {
             if (left_mb_field_flag != curr_mb_field_flag) {
-                left_xy[LBOT] = left_xy[LTOP] = mb_xy - s->mb_stride - 1;
+                left_xy[LBOT] = left_xy[LTOP] = mb_xy - h->mb_stride - 1;
                 if (curr_mb_field_flag) {
-                    left_xy[LBOT] += s->mb_stride;
+                    left_xy[LBOT] += h->mb_stride;
                     h->left_block  = left_block_options[3];
                 } else {
-                    topleft_xy += s->mb_stride;
+                    topleft_xy += h->mb_stride;
                     /* take top left mv from the middle of the mb, as opposed
                      * to all other modes which use the bottom right partition */
                     h->topleft_partition = 0;
@@ -391,13 +387,13 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
             }
         } else {
             if (curr_mb_field_flag) {
-                topleft_xy  += s->mb_stride & (((s->current_picture.f.mb_type[top_xy - 1] >> 7) & 1) - 1);
-                topright_xy += s->mb_stride & (((s->current_picture.f.mb_type[top_xy + 1] >> 7) & 1) - 1);
-                top_xy      += s->mb_stride & (((s->current_picture.f.mb_type[top_xy]     >> 7) & 1) - 1);
+                topleft_xy  += h->mb_stride & (((h->cur_pic.mb_type[top_xy - 1] >> 7) & 1) - 1);
+                topright_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy + 1] >> 7) & 1) - 1);
+                top_xy      += h->mb_stride & (((h->cur_pic.mb_type[top_xy]     >> 7) & 1) - 1);
             }
             if (left_mb_field_flag != curr_mb_field_flag) {
                 if (curr_mb_field_flag) {
-                    left_xy[LBOT] += s->mb_stride;
+                    left_xy[LBOT] += h->mb_stride;
                     h->left_block  = left_block_options[3];
                 } else {
                     h->left_block = left_block_options[2];
@@ -413,11 +409,11 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
     h->left_mb_xy[LBOT] = left_xy[LBOT];
     //FIXME do we need all in the context?
 
-    h->topleft_type    = s->current_picture.f.mb_type[topleft_xy];
-    h->top_type        = s->current_picture.f.mb_type[top_xy];
-    h->topright_type   = s->current_picture.f.mb_type[topright_xy];
-    h->left_type[LTOP] = s->current_picture.f.mb_type[left_xy[LTOP]];
-    h->left_type[LBOT] = s->current_picture.f.mb_type[left_xy[LBOT]];
+    h->topleft_type    = h->cur_pic.mb_type[topleft_xy];
+    h->top_type        = h->cur_pic.mb_type[top_xy];
+    h->topright_type   = h->cur_pic.mb_type[topright_xy];
+    h->left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]];
+    h->left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]];
 
     if (FMO) {
         if (h->slice_table[topleft_xy] != h->slice_num)
@@ -441,7 +437,6 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
 
 static void fill_decode_caches(H264Context *h, int mb_type)
 {
-    MpegEncContext *const s = &h->s;
     int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
     int topleft_type, top_type, topright_type, left_type[LEFT_MBS];
     const uint8_t *left_block = h->left_block;
@@ -484,7 +479,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
                         h->left_samples_available    &= 0xFF5F;
                     }
                 } else {
-                    int left_typei = s->current_picture.f.mb_type[left_xy[LTOP] + s->mb_stride];
+                    int left_typei = h->cur_pic.mb_type[left_xy[LTOP] + h->mb_stride];
 
                     assert(left_xy[LTOP] == left_xy[LBOT]);
                     if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
@@ -541,7 +536,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
         if (top_type) {
             nnz = h->non_zero_count[top_xy];
             AV_COPY32(&nnz_cache[4 + 8 * 0], &nnz[4 * 3]);
-            if (!s->chroma_y_shift) {
+            if (!h->chroma_y_shift) {
                 AV_COPY32(&nnz_cache[4 + 8 *  5], &nnz[4 *  7]);
                 AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 11]);
             } else {
@@ -549,7 +544,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
                 AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 9]);
             }
         } else {
-            uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;
+            uint32_t top_empty = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 0x40404040;
             AV_WN32A(&nnz_cache[4 + 8 *  0], top_empty);
             AV_WN32A(&nnz_cache[4 + 8 *  5], top_empty);
             AV_WN32A(&nnz_cache[4 + 8 * 10], top_empty);
@@ -560,12 +555,12 @@ static void fill_decode_caches(H264Context *h, int mb_type)
                 nnz = h->non_zero_count[left_xy[LEFT(i)]];
                 nnz_cache[3 + 8 * 1 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i]];
                 nnz_cache[3 + 8 * 2 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i]];
-                if (CHROMA444) {
+                if (CHROMA444(h)) {
                     nnz_cache[3 + 8 *  6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 4 * 4];
                     nnz_cache[3 + 8 *  7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 4 * 4];
                     nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 8 * 4];
                     nnz_cache[3 + 8 * 12 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 8 * 4];
-                } else if (CHROMA422) {
+                } else if (CHROMA422(h)) {
                     nnz_cache[3 + 8 *  6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 4 * 4];
                     nnz_cache[3 + 8 *  7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] - 2 + 4 * 4];
                     nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 8 * 4];
@@ -580,11 +575,11 @@ static void fill_decode_caches(H264Context *h, int mb_type)
                 nnz_cache[3 + 8 *  6 + 2 * 8 * i] =
                 nnz_cache[3 + 8 *  7 + 2 * 8 * i] =
                 nnz_cache[3 + 8 * 11 + 2 * 8 * i] =
-                nnz_cache[3 + 8 * 12 + 2 * 8 * i] = CABAC && !IS_INTRA(mb_type) ? 0 : 64;
+                nnz_cache[3 + 8 * 12 + 2 * 8 * i] = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 64;
             }
         }
 
-        if (CABAC) {
+        if (CABAC(h)) {
             // top_cbp
             if (top_type)
                 h->top_cbp = h->cbp_table[top_xy];
@@ -606,9 +601,9 @@ static void fill_decode_caches(H264Context *h, int mb_type)
         int b_stride = h->b_stride;
         for (list = 0; list < h->list_count; list++) {
             int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
-            int8_t *ref       = s->current_picture.f.ref_index[list];
+            int8_t *ref       = h->cur_pic.ref_index[list];
             int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
-            int16_t(*mv)[2]       = s->current_picture.f.motion_val[list];
+            int16_t(*mv)[2]       = h->cur_pic.motion_val[list];
             if (!USES_LIST(mb_type, list))
                 continue;
             assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
@@ -682,7 +677,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
                 }
             }
 
-            if ((mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2)) && !FRAME_MBAFF)
+            if ((mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2)) && !FRAME_MBAFF(h))
                 continue;
 
             if (!(mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2))) {
@@ -693,7 +688,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
                 AV_ZERO32(mv_cache[2 + 8 * 0]);
                 AV_ZERO32(mv_cache[2 + 8 * 2]);
 
-                if (CABAC) {
+                if (CABAC(h)) {
                     if (USES_LIST(top_type, list)) {
                         const int b_xy = h->mb2br_xy[top_xy];
                         AV_COPY64(mvd_cache[0 - 1 * 8], mvd[b_xy + 0]);
@@ -764,8 +759,8 @@ static void fill_decode_caches(H264Context *h, int mb_type)
     MAP_F2F(scan8[0] - 1 + 2 * 8, left_type[LBOT])                      \
     MAP_F2F(scan8[0] - 1 + 3 * 8, left_type[LBOT])
 
-            if (FRAME_MBAFF) {
-                if (MB_FIELD) {
+            if (FRAME_MBAFF(h)) {
+                if (MB_FIELD(h)) {
 
 #define MAP_F2F(idx, mb_type)                                           \
     if (!IS_INTERLACED(mb_type) && h->ref_cache[list][idx] >= 0) {      \
@@ -800,13 +795,12 @@ static void fill_decode_caches(H264Context *h, int mb_type)
  */
 static void av_unused decode_mb_skip(H264Context *h)
 {
-    MpegEncContext *const s = &h->s;
     const int mb_xy = h->mb_xy;
     int mb_type     = 0;
 
     memset(h->non_zero_count[mb_xy], 0, 48);
 
-    if (MB_FIELD)
+    if (MB_FIELD(h))
         mb_type |= MB_TYPE_INTERLACED;
 
     if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
@@ -826,10 +820,10 @@ static void av_unused decode_mb_skip(H264Context *h)
     }
 
     write_back_motion(h, mb_type);
-    s->current_picture.f.mb_type[mb_xy]      = mb_type;
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
-    h->slice_table[mb_xy]                    = h->slice_num;
-    h->prev_mb_skipped                       = 1;
+    h->cur_pic.mb_type[mb_xy]      = mb_type;
+    h->cur_pic.qscale_table[mb_xy] = h->qscale;
+    h->slice_table[mb_xy]            = h->slice_num;
+    h->prev_mb_skipped               = 1;
 }
 
 #endif /* AVCODEC_H264_MVPRED_H */
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 0464476..05a40c7 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -25,75 +25,135 @@
  * @author Michael Niedermayer <michaelni at gmx.at>
  */
 
+#include "libavutil/attributes.h"
 #include "parser.h"
 #include "h264data.h"
 #include "golomb.h"
+#include "internal.h"
 
 #include <assert.h>
 
 
-static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
+static int h264_find_frame_end(H264Context *h, const uint8_t *buf,
+                               int buf_size)
 {
     int i;
     uint32_t state;
-    ParseContext *pc = &(h->s.parse_context);
+    ParseContext *pc = &h->parse_context;
 //    mb_addr= pc->mb_addr - 1;
-    state= pc->state;
-    if(state>13)
-        state= 7;
-
-    for(i=0; i<buf_size; i++){
-        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))
-                i+=8;
-#    else
-            while(i<buf_size && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
-                i+=4;
-#    endif
-#endif
-            for(; i<buf_size; i++){
-                if(!buf[i]){
-                    state=2;
-                    break;
-                }
-            }
-        }else if(state<=2){
-            if(buf[i]==1)   state^= 5; //2->7, 1->4, 0->5
-            else if(buf[i]) state = 7;
-            else            state>>=1; //2->1, 1->0, 0->0
-        }else if(state<=5){
-            int v= buf[i] & 0x1F;
-            if(v==6 || v==7 || v==8 || v==9){
-                if(pc->frame_start_found){
+    state = pc->state;
+    if (state > 13)
+        state = 7;
+
+    for (i = 0; i < buf_size; i++) {
+        if (state == 7) {
+            i += h->h264dsp.h264_find_start_code_candidate(buf + i, buf_size - i);
+            if (i < buf_size)
+                state = 2;
+        } else if (state <= 2) {
+            if (buf[i] == 1)
+                state ^= 5;            // 2->7, 1->4, 0->5
+            else if (buf[i])
+                state = 7;
+            else
+                state >>= 1;           // 2->1, 1->0, 0->0
+        } else if (state <= 5) {
+            int v = buf[i] & 0x1F;
+            if (v == 6 || v == 7 || v == 8 || v == 9) {
+                if (pc->frame_start_found) {
                     i++;
                     goto found;
                 }
-            }else if(v==1 || v==2 || v==5){
-                if(pc->frame_start_found){
-                    state+=8;
+            } else if (v == 1 || v == 2 || v == 5) {
+                if (pc->frame_start_found) {
+                    state += 8;
                     continue;
-                }else
+                } else
                     pc->frame_start_found = 1;
             }
-            state= 7;
-        }else{
-            if(buf[i] & 0x80)
+            state = 7;
+        } else {
+            if (buf[i] & 0x80)
                 goto found;
-            state= 7;
+            state = 7;
         }
     }
-    pc->state= state;
+    pc->state = state;
     return END_NOT_FOUND;
 
 found:
-    pc->state=7;
-    pc->frame_start_found= 0;
-    return i-(state&5);
+    pc->state             = 7;
+    pc->frame_start_found = 0;
+    return i - (state & 5);
+}
+
+static int scan_mmco_reset(AVCodecParserContext *s)
+{
+    H264Context *h = s->priv_data;
+
+    h->slice_type_nos = s->pict_type & 3;
+
+    if (h->pps.redundant_pic_cnt_present)
+        get_ue_golomb(&h->gb); // redundant_pic_count
+
+    if (ff_set_ref_count(h) < 0)
+        return AVERROR_INVALIDDATA;
+
+    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
+        int list;
+        for (list = 0; list < h->list_count; list++) {
+            if (get_bits1(&h->gb)) {
+                int index;
+                for (index = 0; ; index++) {
+                    unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(&h->gb);
+
+                    if (reordering_of_pic_nums_idc < 3)
+                        get_ue_golomb(&h->gb);
+                    else if (reordering_of_pic_nums_idc > 3) {
+                        av_log(h->avctx, AV_LOG_ERROR,
+                               "illegal reordering_of_pic_nums_idc %d\n",
+                               reordering_of_pic_nums_idc);
+                        return AVERROR_INVALIDDATA;
+                    } else
+                        break;
+
+                    if (index >= h->ref_count[list]) {
+                        av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
+                        return AVERROR_INVALIDDATA;
+                    }
+                }
+            }
+        }
+    }
+
+    if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
+        (h->pps.weighted_bipred_idc == 1 && h->slice_type_nos == AV_PICTURE_TYPE_B))
+        ff_pred_weight_table(h);
+
+    if (get_bits1(&h->gb)) { // adaptive_ref_pic_marking_mode_flag
+        int i;
+        for (i = 0; i < MAX_MMCO_COUNT; i++) {
+            MMCOOpcode opcode = get_ue_golomb_31(&h->gb);
+            if (opcode > (unsigned) MMCO_LONG) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "illegal memory management control operation %d\n",
+                       opcode);
+                return AVERROR_INVALIDDATA;
+            }
+            if (opcode == MMCO_END)
+               return 0;
+            else if (opcode == MMCO_RESET)
+                return 1;
+
+            if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG)
+                get_ue_golomb(&h->gb);
+            if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED ||
+                opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG)
+                get_ue_golomb_31(&h->gb);
+        }
+    }
+
+    return 0;
 }
 
 /**
@@ -108,30 +168,29 @@ static inline int parse_nal_units(AVCodecParserContext *s,
                                   AVCodecContext *avctx,
                                   const uint8_t *buf, int buf_size)
 {
-    H264Context *h = s->priv_data;
+    H264Context *h         = s->priv_data;
     const uint8_t *buf_end = buf + buf_size;
     unsigned int pps_id;
     unsigned int slice_type;
-    int state = -1;
+    int state = -1, got_reset = 0;
     const uint8_t *ptr;
+    int field_poc[2];
 
     /* set some sane default values */
-    s->pict_type = AV_PICTURE_TYPE_I;
-    s->key_frame = 0;
+    s->pict_type         = AV_PICTURE_TYPE_I;
+    s->key_frame         = 0;
+    s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;
 
-    h->s.avctx= avctx;
-    h->sei_recovery_frame_cnt = -1;
-    h->sei_dpb_output_delay         =  0;
-    h->sei_cpb_removal_delay        = -1;
-    h->sei_buffering_period_present =  0;
+    h->avctx = avctx;
+    ff_h264_reset_sei(h);
 
     if (!buf_size)
         return 0;
 
-    for(;;) {
+    for (;;) {
         int src_length, dst_length, consumed;
-        buf = avpriv_mpv_find_start_code(buf, buf_end, &state);
-        if(buf >= buf_end)
+        buf = avpriv_find_start_code(buf, buf_end, &state);
+        if (buf >= buf_end)
             break;
         --buf;
         src_length = buf_end - buf;
@@ -139,93 +198,189 @@ static inline int parse_nal_units(AVCodecParserContext *s,
         case NAL_SLICE:
         case NAL_IDR_SLICE:
             // Do not walk the whole buffer just to decode slice header
-            if (src_length > 20)
-                src_length = 20;
+            if ((state & 0x1f) == NAL_IDR_SLICE || ((state >> 5) & 0x3) == 0) {
+                /* IDR or disposable slice
+                 * No need to decode many bytes because MMCOs shall not be present. */
+                if (src_length > 60)
+                    src_length = 60;
+            } else {
+                /* To decode up to MMCOs */
+                if (src_length > 1000)
+                    src_length = 1000;
+            }
             break;
         }
-        ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length);
-        if (ptr==NULL || dst_length < 0)
+        ptr = ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length);
+        if (ptr == NULL || dst_length < 0)
             break;
 
-        init_get_bits(&h->s.gb, ptr, 8*dst_length);
-        switch(h->nal_unit_type) {
+        init_get_bits(&h->gb, ptr, 8 * dst_length);
+        switch (h->nal_unit_type) {
         case NAL_SPS:
             ff_h264_decode_seq_parameter_set(h);
             break;
         case NAL_PPS:
-            ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits);
+            ff_h264_decode_picture_parameter_set(h, h->gb.size_in_bits);
             break;
         case NAL_SEI:
             ff_h264_decode_sei(h);
             break;
         case NAL_IDR_SLICE:
             s->key_frame = 1;
-            /* fall through */
+
+            h->prev_frame_num        = 0;
+            h->prev_frame_num_offset = 0;
+            h->prev_poc_msb          =
+            h->prev_poc_lsb          = 0;
+        /* fall through */
         case NAL_SLICE:
-            get_ue_golomb(&h->s.gb);  // skip first_mb_in_slice
-            slice_type = get_ue_golomb_31(&h->s.gb);
+            get_ue_golomb(&h->gb);  // skip first_mb_in_slice
+            slice_type   = get_ue_golomb_31(&h->gb);
             s->pict_type = golomb_to_pict_type[slice_type % 5];
             if (h->sei_recovery_frame_cnt >= 0) {
                 /* key frame, since recovery_frame_cnt is set */
                 s->key_frame = 1;
             }
-            pps_id= get_ue_golomb(&h->s.gb);
-            if(pps_id>=MAX_PPS_COUNT) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
+            pps_id = get_ue_golomb(&h->gb);
+            if (pps_id >= MAX_PPS_COUNT) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "pps_id out of range\n");
                 return -1;
             }
-            if(!h->pps_buffers[pps_id]) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");
+            if (!h->pps_buffers[pps_id]) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "non-existing PPS referenced\n");
                 return -1;
             }
-            h->pps= *h->pps_buffers[pps_id];
-            if(!h->sps_buffers[h->pps.sps_id]) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");
+            h->pps = *h->pps_buffers[pps_id];
+            if (!h->sps_buffers[h->pps.sps_id]) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "non-existing SPS referenced\n");
                 return -1;
             }
-            h->sps = *h->sps_buffers[h->pps.sps_id];
-            h->frame_num = get_bits(&h->s.gb, h->sps.log2_max_frame_num);
+            h->sps       = *h->sps_buffers[h->pps.sps_id];
+            h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);
 
             avctx->profile = ff_h264_get_profile(&h->sps);
             avctx->level   = h->sps.level_idc;
 
-            if(h->sps.frame_mbs_only_flag){
-                h->s.picture_structure= PICT_FRAME;
-            }else{
-                if(get_bits1(&h->s.gb)) { //field_pic_flag
-                    h->s.picture_structure= PICT_TOP_FIELD + get_bits1(&h->s.gb); //bottom_field_flag
+            if (h->sps.frame_mbs_only_flag) {
+                h->picture_structure = PICT_FRAME;
+            } else {
+                if (get_bits1(&h->gb)) { // field_pic_flag
+                    h->picture_structure = PICT_TOP_FIELD + get_bits1(&h->gb); // bottom_field_flag
+                } else {
+                    h->picture_structure = PICT_FRAME;
+                }
+            }
+
+            if (h->nal_unit_type == NAL_IDR_SLICE)
+                get_ue_golomb(&h->gb); /* idr_pic_id */
+            if (h->sps.poc_type == 0) {
+                h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);
+
+                if (h->pps.pic_order_present == 1 &&
+                    h->picture_structure == PICT_FRAME)
+                    h->delta_poc_bottom = get_se_golomb(&h->gb);
+            }
+
+            if (h->sps.poc_type == 1 &&
+                !h->sps.delta_pic_order_always_zero_flag) {
+                h->delta_poc[0] = get_se_golomb(&h->gb);
+
+                if (h->pps.pic_order_present == 1 &&
+                    h->picture_structure == PICT_FRAME)
+                    h->delta_poc[1] = get_se_golomb(&h->gb);
+            }
+
+            /* Decode POC of this picture.
+             * The prev_ values needed for decoding POC of the next picture are not set here. */
+            field_poc[0] = field_poc[1] = INT_MAX;
+            ff_init_poc(h, field_poc, &s->output_picture_number);
+
+            /* Continue parsing to check if MMCO_RESET is present.
+             * FIXME: MMCO_RESET could appear in non-first slice.
+             *        Maybe, we should parse all undisposable non-IDR slice of this
+             *        picture until encountering MMCO_RESET in a slice of it. */
+            if (h->nal_ref_idc && h->nal_unit_type != NAL_IDR_SLICE) {
+                got_reset = scan_mmco_reset(s);
+                if (got_reset < 0)
+                    return got_reset;
+            }
+
+            /* Set up the prev_ values for decoding POC of the next picture. */
+            h->prev_frame_num        = got_reset ? 0 : h->frame_num;
+            h->prev_frame_num_offset = got_reset ? 0 : h->frame_num_offset;
+            if (h->nal_ref_idc != 0) {
+                if (!got_reset) {
+                    h->prev_poc_msb = h->poc_msb;
+                    h->prev_poc_lsb = h->poc_lsb;
                 } else {
-                    h->s.picture_structure= PICT_FRAME;
+                    h->prev_poc_msb = 0;
+                    h->prev_poc_lsb =
+                        h->picture_structure == PICT_BOTTOM_FIELD ? 0 : field_poc[0];
                 }
             }
 
-            if(h->sps.pic_struct_present_flag) {
+            if (h->sps.pic_struct_present_flag) {
                 switch (h->sei_pic_struct) {
-                    case SEI_PIC_STRUCT_TOP_FIELD:
-                    case SEI_PIC_STRUCT_BOTTOM_FIELD:
-                        s->repeat_pict = 0;
-                        break;
-                    case SEI_PIC_STRUCT_FRAME:
+                case SEI_PIC_STRUCT_TOP_FIELD:
+                case SEI_PIC_STRUCT_BOTTOM_FIELD:
+                    s->repeat_pict = 0;
+                    break;
+                case SEI_PIC_STRUCT_FRAME:
+                case SEI_PIC_STRUCT_TOP_BOTTOM:
+                case SEI_PIC_STRUCT_BOTTOM_TOP:
+                    s->repeat_pict = 1;
+                    break;
+                case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
+                case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
+                    s->repeat_pict = 2;
+                    break;
+                case SEI_PIC_STRUCT_FRAME_DOUBLING:
+                    s->repeat_pict = 3;
+                    break;
+                case SEI_PIC_STRUCT_FRAME_TRIPLING:
+                    s->repeat_pict = 5;
+                    break;
+                default:
+                    s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
+                    break;
+                }
+            } else {
+                s->repeat_pict = h->picture_structure == PICT_FRAME ? 1 : 0;
+            }
+
+            if (h->picture_structure == PICT_FRAME) {
+                s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;
+                if (h->sps.pic_struct_present_flag) {
+                    switch (h->sei_pic_struct) {
                     case SEI_PIC_STRUCT_TOP_BOTTOM:
-                    case SEI_PIC_STRUCT_BOTTOM_TOP:
-                        s->repeat_pict = 1;
-                        break;
                     case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
-                    case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
-                        s->repeat_pict = 2;
-                        break;
-                    case SEI_PIC_STRUCT_FRAME_DOUBLING:
-                        s->repeat_pict = 3;
+                        s->field_order = AV_FIELD_TT;
                         break;
-                    case SEI_PIC_STRUCT_FRAME_TRIPLING:
-                        s->repeat_pict = 5;
+                    case SEI_PIC_STRUCT_BOTTOM_TOP:
+                    case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
+                        s->field_order = AV_FIELD_BB;
                         break;
                     default:
-                        s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0;
+                        s->field_order = AV_FIELD_PROGRESSIVE;
                         break;
+                    }
+                } else {
+                    if (field_poc[0] < field_poc[1])
+                        s->field_order = AV_FIELD_TT;
+                    else if (field_poc[0] > field_poc[1])
+                        s->field_order = AV_FIELD_BB;
+                    else
+                        s->field_order = AV_FIELD_PROGRESSIVE;
                 }
             } else {
-                s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0;
+                if (h->picture_structure == PICT_TOP_FIELD)
+                    s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD;
+                else
+                    s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
+                s->field_order = AV_FIELD_UNKNOWN;
             }
 
             return 0; /* no need to evaluate the rest */
@@ -233,7 +388,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
         buf += consumed;
     }
     /* didn't find a picture! */
-    av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n");
+    av_log(h->avctx, AV_LOG_ERROR, "missing picture in access unit\n");
     return -1;
 }
 
@@ -242,39 +397,39 @@ static int h264_parse(AVCodecParserContext *s,
                       const uint8_t **poutbuf, int *poutbuf_size,
                       const uint8_t *buf, int buf_size)
 {
-    H264Context *h = s->priv_data;
-    ParseContext *pc = &h->s.parse_context;
+    H264Context *h   = s->priv_data;
+    ParseContext *pc = &h->parse_context;
     int next;
 
     if (!h->got_first) {
         h->got_first = 1;
         if (avctx->extradata_size) {
-            h->s.avctx = avctx;
+            h->avctx = avctx;
             // must be done like in the decoder.
             // otherwise opening the parser, creating 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.
             if (!avctx->has_b_frames)
-                h->s.low_delay = 1;
+                h->low_delay = 1;
             ff_h264_decode_extradata(h);
         }
     }
 
-    if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
-        next= buf_size;
-    }else{
-        next= ff_h264_find_frame_end(h, buf, buf_size);
+    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+        next = buf_size;
+    } else {
+        next = h264_find_frame_end(h, buf, buf_size);
 
         if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
-            *poutbuf = NULL;
+            *poutbuf      = NULL;
             *poutbuf_size = 0;
             return buf_size;
         }
 
-        if(next<0 && next != END_NOT_FOUND){
-            assert(pc->last_index + next >= 0 );
-            ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
+        if (next < 0 && next != END_NOT_FOUND) {
+            assert(pc->last_index + next >= 0);
+            h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); // update state
         }
     }
 
@@ -294,7 +449,7 @@ static int h264_parse(AVCodecParserContext *s,
         s->flags &= PARSER_FLAG_COMPLETE_FRAMES;
     }
 
-    *poutbuf = buf;
+    *poutbuf      = buf;
     *poutbuf_size = buf_size;
     return next;
 }
@@ -304,39 +459,45 @@ static int h264_split(AVCodecContext *avctx,
 {
     int i;
     uint32_t state = -1;
-    int has_sps= 0;
-
-    for(i=0; i<=buf_size; i++){
-        if((state&0xFFFFFF1F) == 0x107)
-            has_sps=1;
-/*        if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
-        }*/
-        if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){
-            if(has_sps){
-                while(i>4 && buf[i-5]==0) i--;
-                return i-4;
+    int has_sps    = 0;
+
+    for (i = 0; i <= buf_size; i++) {
+        if ((state & 0xFFFFFF1F) == 0x107)
+            has_sps = 1;
+        /*  if((state&0xFFFFFF1F) == 0x101 ||
+         *     (state&0xFFFFFF1F) == 0x102 ||
+         *     (state&0xFFFFFF1F) == 0x105) {
+         *  }
+         */
+        if ((state & 0xFFFFFF00) == 0x100 && (state & 0xFFFFFF1F) != 0x107 &&
+            (state & 0xFFFFFF1F) != 0x108 && (state & 0xFFFFFF1F) != 0x109) {
+            if (has_sps) {
+                while (i > 4 && buf[i - 5] == 0)
+                    i--;
+                return i - 4;
             }
         }
-        if (i<buf_size)
-            state= (state<<8) | buf[i];
+        if (i < buf_size)
+            state = (state << 8) | buf[i];
     }
     return 0;
 }
 
 static void close(AVCodecParserContext *s)
 {
-    H264Context *h = s->priv_data;
-    ParseContext *pc = &h->s.parse_context;
+    H264Context *h   = s->priv_data;
+    ParseContext *pc = &h->parse_context;
 
     av_free(pc->buffer);
     ff_h264_free_context(h);
 }
 
-static int init(AVCodecParserContext *s)
+static av_cold int init(AVCodecParserContext *s)
 {
     H264Context *h = s->priv_data;
-    h->thread_context[0] = h;
-    h->s.slice_context_count = 1;
+    h->thread_context[0]   = h;
+    h->slice_context_count = 1;
+    ff_h264dsp_init(&h->h264dsp, 8, 1);
     return 0;
 }
 
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index ff6c077..54b735d 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -27,221 +27,210 @@
 
 #include "libavutil/imgutils.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "h264.h"
 #include "h264data.h" //FIXME FIXME FIXME (just for zigzag_scan)
 #include "golomb.h"
 
-
-//#undef NDEBUG
-#include <assert.h>
-
 #define MAX_LOG2_MAX_FRAME_NUM    (12 + 4)
 #define MIN_LOG2_MAX_FRAME_NUM    4
 
-static const AVRational pixel_aspect[17]={
- {0, 1},
- {1, 1},
- {12, 11},
- {10, 11},
- {16, 11},
- {40, 33},
- {24, 11},
- {20, 11},
- {32, 11},
- {80, 33},
- {18, 11},
- {15, 11},
- {64, 33},
- {160,99},
- {4, 3},
- {3, 2},
- {2, 1},
+static const AVRational pixel_aspect[17] = {
+    {   0,  1 },
+    {   1,  1 },
+    {  12, 11 },
+    {  10, 11 },
+    {  16, 11 },
+    {  40, 33 },
+    {  24, 11 },
+    {  20, 11 },
+    {  32, 11 },
+    {  80, 33 },
+    {  18, 11 },
+    {  15, 11 },
+    {  64, 33 },
+    { 160, 99 },
+    {   4,  3 },
+    {   3,  2 },
+    {   2,  1 },
+};
+
+#define QP(qP, depth) ((qP) + 6 * ((depth) - 8))
+
+#define CHROMA_QP_TABLE_END(d)                                          \
+    QP(0,  d), QP(1,  d), QP(2,  d), QP(3,  d), QP(4,  d), QP(5,  d),   \
+    QP(6,  d), QP(7,  d), QP(8,  d), QP(9,  d), QP(10, d), QP(11, d),   \
+    QP(12, d), QP(13, d), QP(14, d), QP(15, d), QP(16, d), QP(17, d),   \
+    QP(18, d), QP(19, d), QP(20, d), QP(21, d), QP(22, d), QP(23, d),   \
+    QP(24, d), QP(25, d), QP(26, d), QP(27, d), QP(28, d), QP(29, d),   \
+    QP(29, d), QP(30, d), QP(31, d), QP(32, d), QP(32, d), QP(33, d),   \
+    QP(34, d), QP(34, d), QP(35, d), QP(35, d), QP(36, d), QP(36, d),   \
+    QP(37, d), QP(37, d), QP(37, d), QP(38, d), QP(38, d), QP(38, d),   \
+    QP(39, d), QP(39, d), QP(39, d), QP(39, d)
+
+const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM + 1] = {
+    { CHROMA_QP_TABLE_END(8) },
+    { 0, 1, 2, 3, 4, 5,
+      CHROMA_QP_TABLE_END(9) },
+    { 0, 1, 2, 3, 4, 5,
+      6, 7, 8, 9, 10, 11,
+      CHROMA_QP_TABLE_END(10) },
 };
 
-#define QP(qP,depth) ( (qP)+6*((depth)-8) )
-
-#define CHROMA_QP_TABLE_END(d) \
-     QP(0,d),  QP(1,d),  QP(2,d),  QP(3,d),  QP(4,d),  QP(5,d),\
-     QP(6,d),  QP(7,d),  QP(8,d),  QP(9,d), QP(10,d), QP(11,d),\
-    QP(12,d), QP(13,d), QP(14,d), QP(15,d), QP(16,d), QP(17,d),\
-    QP(18,d), QP(19,d), QP(20,d), QP(21,d), QP(22,d), QP(23,d),\
-    QP(24,d), QP(25,d), QP(26,d), QP(27,d), QP(28,d), QP(29,d),\
-    QP(29,d), QP(30,d), QP(31,d), QP(32,d), QP(32,d), QP(33,d),\
-    QP(34,d), QP(34,d), QP(35,d), QP(35,d), QP(36,d), QP(36,d),\
-    QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\
-    QP(39,d), QP(39,d), QP(39,d), QP(39,d)
-
-const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1] = {
-    {
-        CHROMA_QP_TABLE_END(8)
-    },
-    {
-        0, 1, 2, 3, 4, 5,
-        CHROMA_QP_TABLE_END(9)
-    },
-    {
-        0, 1, 2, 3,  4,  5,
-        6, 7, 8, 9, 10, 11,
-        CHROMA_QP_TABLE_END(10)
-    },
+static const uint8_t default_scaling4[2][16] = {
+    {  6, 13, 20, 28, 13, 20, 28, 32,
+      20, 28, 32, 37, 28, 32, 37, 42 },
+    { 10, 14, 20, 24, 14, 20, 24, 27,
+      20, 24, 27, 30, 24, 27, 30, 34 }
 };
 
-static const uint8_t default_scaling4[2][16]={
-{   6,13,20,28,
-   13,20,28,32,
-   20,28,32,37,
-   28,32,37,42
-},{
-   10,14,20,24,
-   14,20,24,27,
-   20,24,27,30,
-   24,27,30,34
-}};
-
-static const uint8_t default_scaling8[2][64]={
-{   6,10,13,16,18,23,25,27,
-   10,11,16,18,23,25,27,29,
-   13,16,18,23,25,27,29,31,
-   16,18,23,25,27,29,31,33,
-   18,23,25,27,29,31,33,36,
-   23,25,27,29,31,33,36,38,
-   25,27,29,31,33,36,38,40,
-   27,29,31,33,36,38,40,42
-},{
-    9,13,15,17,19,21,22,24,
-   13,13,17,19,21,22,24,25,
-   15,17,19,21,22,24,25,27,
-   17,19,21,22,24,25,27,28,
-   19,21,22,24,25,27,28,30,
-   21,22,24,25,27,28,30,32,
-   22,24,25,27,28,30,32,33,
-   24,25,27,28,30,32,33,35
-}};
-
-static inline int decode_hrd_parameters(H264Context *h, SPS *sps){
-    MpegEncContext * const s = &h->s;
+static const uint8_t default_scaling8[2][64] = {
+    {  6, 10, 13, 16, 18, 23, 25, 27,
+      10, 11, 16, 18, 23, 25, 27, 29,
+      13, 16, 18, 23, 25, 27, 29, 31,
+      16, 18, 23, 25, 27, 29, 31, 33,
+      18, 23, 25, 27, 29, 31, 33, 36,
+      23, 25, 27, 29, 31, 33, 36, 38,
+      25, 27, 29, 31, 33, 36, 38, 40,
+      27, 29, 31, 33, 36, 38, 40, 42 },
+    {  9, 13, 15, 17, 19, 21, 22, 24,
+      13, 13, 17, 19, 21, 22, 24, 25,
+      15, 17, 19, 21, 22, 24, 25, 27,
+      17, 19, 21, 22, 24, 25, 27, 28,
+      19, 21, 22, 24, 25, 27, 28, 30,
+      21, 22, 24, 25, 27, 28, 30, 32,
+      22, 24, 25, 27, 28, 30, 32, 33,
+      24, 25, 27, 28, 30, 32, 33, 35 }
+};
+
+static inline int decode_hrd_parameters(H264Context *h, SPS *sps)
+{
     int cpb_count, i;
-    cpb_count = get_ue_golomb_31(&s->gb) + 1;
+    cpb_count = get_ue_golomb_31(&h->gb) + 1;
 
-    if(cpb_count > 32U){
-        av_log(h->s.avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
-        return -1;
+    if (cpb_count > 32U) {
+        av_log(h->avctx, AV_LOG_ERROR, "cpb_count %d invalid\n", cpb_count);
+        return AVERROR_INVALIDDATA;
     }
 
-    get_bits(&s->gb, 4); /* bit_rate_scale */
-    get_bits(&s->gb, 4); /* cpb_size_scale */
-    for(i=0; i<cpb_count; i++){
-        get_ue_golomb_long(&s->gb); /* bit_rate_value_minus1 */
-        get_ue_golomb_long(&s->gb); /* cpb_size_value_minus1 */
-        get_bits1(&s->gb);     /* cbr_flag */
+    get_bits(&h->gb, 4); /* bit_rate_scale */
+    get_bits(&h->gb, 4); /* cpb_size_scale */
+    for (i = 0; i < cpb_count; i++) {
+        get_ue_golomb_long(&h->gb); /* bit_rate_value_minus1 */
+        get_ue_golomb_long(&h->gb); /* cpb_size_value_minus1 */
+        get_bits1(&h->gb);          /* cbr_flag */
     }
-    sps->initial_cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1;
-    sps->time_offset_length = get_bits(&s->gb, 5);
-    sps->cpb_cnt = cpb_count;
+    sps->initial_cpb_removal_delay_length = get_bits(&h->gb, 5) + 1;
+    sps->cpb_removal_delay_length         = get_bits(&h->gb, 5) + 1;
+    sps->dpb_output_delay_length          = get_bits(&h->gb, 5) + 1;
+    sps->time_offset_length               = get_bits(&h->gb, 5);
+    sps->cpb_cnt                          = cpb_count;
     return 0;
 }
 
-static inline int decode_vui_parameters(H264Context *h, SPS *sps){
-    MpegEncContext * const s = &h->s;
+static inline int decode_vui_parameters(H264Context *h, SPS *sps)
+{
     int aspect_ratio_info_present_flag;
     unsigned int aspect_ratio_idc;
 
-    aspect_ratio_info_present_flag= get_bits1(&s->gb);
-
-    if( aspect_ratio_info_present_flag ) {
-        aspect_ratio_idc= get_bits(&s->gb, 8);
-        if( aspect_ratio_idc == EXTENDED_SAR ) {
-            sps->sar.num= get_bits(&s->gb, 16);
-            sps->sar.den= get_bits(&s->gb, 16);
-        }else if(aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)){
-            sps->sar=  pixel_aspect[aspect_ratio_idc];
-        }else{
-            av_log(h->s.avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
-            return -1;
+    aspect_ratio_info_present_flag = get_bits1(&h->gb);
+
+    if (aspect_ratio_info_present_flag) {
+        aspect_ratio_idc = get_bits(&h->gb, 8);
+        if (aspect_ratio_idc == EXTENDED_SAR) {
+            sps->sar.num = get_bits(&h->gb, 16);
+            sps->sar.den = get_bits(&h->gb, 16);
+        } else if (aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)) {
+            sps->sar = pixel_aspect[aspect_ratio_idc];
+        } else {
+            av_log(h->avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
+            return AVERROR_INVALIDDATA;
         }
-    }else{
-        sps->sar.num=
-        sps->sar.den= 0;
+    } else {
+        sps->sar.num =
+        sps->sar.den = 0;
     }
-//            s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height);
 
-    if(get_bits1(&s->gb)){      /* overscan_info_present_flag */
-        get_bits1(&s->gb);      /* overscan_appropriate_flag */
-    }
+    if (get_bits1(&h->gb))      /* overscan_info_present_flag */
+        get_bits1(&h->gb);      /* overscan_appropriate_flag */
 
-    sps->video_signal_type_present_flag = get_bits1(&s->gb);
-    if(sps->video_signal_type_present_flag){
-        get_bits(&s->gb, 3);    /* video_format */
-        sps->full_range = get_bits1(&s->gb); /* video_full_range_flag */
+    sps->video_signal_type_present_flag = get_bits1(&h->gb);
+    if (sps->video_signal_type_present_flag) {
+        get_bits(&h->gb, 3);                 /* video_format */
+        sps->full_range = get_bits1(&h->gb); /* video_full_range_flag */
 
-        sps->colour_description_present_flag = get_bits1(&s->gb);
-        if(sps->colour_description_present_flag){
-            sps->color_primaries = get_bits(&s->gb, 8); /* colour_primaries */
-            sps->color_trc       = get_bits(&s->gb, 8); /* transfer_characteristics */
-            sps->colorspace      = get_bits(&s->gb, 8); /* matrix_coefficients */
+        sps->colour_description_present_flag = get_bits1(&h->gb);
+        if (sps->colour_description_present_flag) {
+            sps->color_primaries = get_bits(&h->gb, 8); /* colour_primaries */
+            sps->color_trc       = get_bits(&h->gb, 8); /* transfer_characteristics */
+            sps->colorspace      = get_bits(&h->gb, 8); /* matrix_coefficients */
             if (sps->color_primaries >= AVCOL_PRI_NB)
-                sps->color_primaries  = AVCOL_PRI_UNSPECIFIED;
+                sps->color_primaries = AVCOL_PRI_UNSPECIFIED;
             if (sps->color_trc >= AVCOL_TRC_NB)
-                sps->color_trc  = AVCOL_TRC_UNSPECIFIED;
+                sps->color_trc = AVCOL_TRC_UNSPECIFIED;
             if (sps->colorspace >= AVCOL_SPC_NB)
-                sps->colorspace  = AVCOL_SPC_UNSPECIFIED;
+                sps->colorspace = AVCOL_SPC_UNSPECIFIED;
         }
     }
 
-    if(get_bits1(&s->gb)){      /* chroma_location_info_present_flag */
-        s->avctx->chroma_sample_location = get_ue_golomb(&s->gb)+1;  /* chroma_sample_location_type_top_field */
-        get_ue_golomb(&s->gb);  /* chroma_sample_location_type_bottom_field */
+    /* chroma_location_info_present_flag */
+    if (get_bits1(&h->gb)) {
+        /* chroma_sample_location_type_top_field */
+        h->avctx->chroma_sample_location = get_ue_golomb(&h->gb) + 1;
+        get_ue_golomb(&h->gb);  /* chroma_sample_location_type_bottom_field */
     }
 
-    sps->timing_info_present_flag = get_bits1(&s->gb);
-    if(sps->timing_info_present_flag){
-        sps->num_units_in_tick = get_bits_long(&s->gb, 32);
-        sps->time_scale = get_bits_long(&s->gb, 32);
-        if(!sps->num_units_in_tick || !sps->time_scale){
-            av_log(h->s.avctx, AV_LOG_ERROR, "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n", sps->time_scale, sps->num_units_in_tick);
-            return -1;
+    sps->timing_info_present_flag = get_bits1(&h->gb);
+    if (sps->timing_info_present_flag) {
+        sps->num_units_in_tick = get_bits_long(&h->gb, 32);
+        sps->time_scale        = get_bits_long(&h->gb, 32);
+        if (!sps->num_units_in_tick || !sps->time_scale) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "time_scale/num_units_in_tick invalid or unsupported (%d/%d)\n",
+                   sps->time_scale, sps->num_units_in_tick);
+            return AVERROR_INVALIDDATA;
         }
-        sps->fixed_frame_rate_flag = get_bits1(&s->gb);
+        sps->fixed_frame_rate_flag = get_bits1(&h->gb);
     }
 
-    sps->nal_hrd_parameters_present_flag = get_bits1(&s->gb);
-    if(sps->nal_hrd_parameters_present_flag)
-        if(decode_hrd_parameters(h, sps) < 0)
-            return -1;
-    sps->vcl_hrd_parameters_present_flag = get_bits1(&s->gb);
-    if(sps->vcl_hrd_parameters_present_flag)
-        if(decode_hrd_parameters(h, sps) < 0)
-            return -1;
-    if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag)
-        get_bits1(&s->gb);     /* low_delay_hrd_flag */
-    sps->pic_struct_present_flag = get_bits1(&s->gb);
-
-    sps->bitstream_restriction_flag = get_bits1(&s->gb);
-    if(sps->bitstream_restriction_flag){
-        get_bits1(&s->gb);     /* motion_vectors_over_pic_boundaries_flag */
-        get_ue_golomb(&s->gb); /* max_bytes_per_pic_denom */
-        get_ue_golomb(&s->gb); /* max_bits_per_mb_denom */
-        get_ue_golomb(&s->gb); /* log2_max_mv_length_horizontal */
-        get_ue_golomb(&s->gb); /* log2_max_mv_length_vertical */
-        sps->num_reorder_frames= get_ue_golomb(&s->gb);
-        get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/
-
-        if (get_bits_left(&s->gb) < 0) {
-            sps->num_reorder_frames=0;
-            sps->bitstream_restriction_flag= 0;
+    sps->nal_hrd_parameters_present_flag = get_bits1(&h->gb);
+    if (sps->nal_hrd_parameters_present_flag)
+        if (decode_hrd_parameters(h, sps) < 0)
+            return AVERROR_INVALIDDATA;
+    sps->vcl_hrd_parameters_present_flag = get_bits1(&h->gb);
+    if (sps->vcl_hrd_parameters_present_flag)
+        if (decode_hrd_parameters(h, sps) < 0)
+            return AVERROR_INVALIDDATA;
+    if (sps->nal_hrd_parameters_present_flag ||
+        sps->vcl_hrd_parameters_present_flag)
+        get_bits1(&h->gb);     /* low_delay_hrd_flag */
+    sps->pic_struct_present_flag = get_bits1(&h->gb);
+
+    sps->bitstream_restriction_flag = get_bits1(&h->gb);
+    if (sps->bitstream_restriction_flag) {
+        get_bits1(&h->gb);     /* motion_vectors_over_pic_boundaries_flag */
+        get_ue_golomb(&h->gb); /* max_bytes_per_pic_denom */
+        get_ue_golomb(&h->gb); /* max_bits_per_mb_denom */
+        get_ue_golomb(&h->gb); /* log2_max_mv_length_horizontal */
+        get_ue_golomb(&h->gb); /* log2_max_mv_length_vertical */
+        sps->num_reorder_frames = get_ue_golomb(&h->gb);
+        get_ue_golomb(&h->gb); /*max_dec_frame_buffering*/
+
+        if (get_bits_left(&h->gb) < 0) {
+            sps->num_reorder_frames         = 0;
+            sps->bitstream_restriction_flag = 0;
         }
 
-        if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){
-            av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames);
-            return -1;
+        if (sps->num_reorder_frames > 16U
+            /* max_dec_frame_buffering || max_dec_frame_buffering > 16 */) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "illegal num_reorder_frames %d\n", sps->num_reorder_frames);
+            return AVERROR_INVALIDDATA;
         }
     }
-    if (get_bits_left(&s->gb) < 0) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&s->gb));
+    if (get_bits_left(&h->gb) < 0) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Overread VUI by %d bits\n", -get_bits_left(&h->gb));
         return AVERROR_INVALIDDATA;
     }
 
@@ -249,27 +238,30 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){
 }
 
 static void decode_scaling_list(H264Context *h, uint8_t *factors, int size,
-                                const uint8_t *jvt_list, const uint8_t *fallback_list){
-    MpegEncContext * const s = &h->s;
+                                const uint8_t *jvt_list,
+                                const uint8_t *fallback_list)
+{
     int i, last = 8, next = 8;
     const uint8_t *scan = size == 16 ? zigzag_scan : ff_zigzag_direct;
-    if(!get_bits1(&s->gb)) /* matrix not written, we use the predicted one */
-        memcpy(factors, fallback_list, size*sizeof(uint8_t));
+    if (!get_bits1(&h->gb)) /* matrix not written, we use the predicted one */
+        memcpy(factors, fallback_list, size * sizeof(uint8_t));
     else
-    for(i=0;i<size;i++){
-        if(next)
-            next = (last + get_se_golomb(&s->gb)) & 0xff;
-        if(!i && !next){ /* matrix not written, we use the preset one */
-            memcpy(factors, jvt_list, size*sizeof(uint8_t));
-            break;
+        for (i = 0; i < size; i++) {
+            if (next)
+                next = (last + get_se_golomb(&h->gb)) & 0xff;
+            if (!i && !next) { /* matrix not written, we use the preset one */
+                memcpy(factors, jvt_list, size * sizeof(uint8_t));
+                break;
+            }
+            last = factors[scan[i]] = next ? next : last;
         }
-        last = factors[scan[i]] = next ? next : last;
-    }
 }
 
-static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_sps,
-                                   uint8_t (*scaling_matrix4)[16], uint8_t (*scaling_matrix8)[64]){
-    MpegEncContext * const s = &h->s;
+static void decode_scaling_matrices(H264Context *h, SPS *sps,
+                                    PPS *pps, int is_sps,
+                                    uint8_t(*scaling_matrix4)[16],
+                                    uint8_t(*scaling_matrix8)[64])
+{
     int fallback_sps = !is_sps && sps->scaling_matrix_present;
     const uint8_t *fallback[4] = {
         fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0],
@@ -277,57 +269,57 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s
         fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0],
         fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1]
     };
-    if(get_bits1(&s->gb)){
+    if (get_bits1(&h->gb)) {
         sps->scaling_matrix_present |= is_sps;
-        decode_scaling_list(h,scaling_matrix4[0],16,default_scaling4[0],fallback[0]); // Intra, Y
-        decode_scaling_list(h,scaling_matrix4[1],16,default_scaling4[0],scaling_matrix4[0]); // Intra, Cr
-        decode_scaling_list(h,scaling_matrix4[2],16,default_scaling4[0],scaling_matrix4[1]); // Intra, Cb
-        decode_scaling_list(h,scaling_matrix4[3],16,default_scaling4[1],fallback[1]); // Inter, Y
-        decode_scaling_list(h,scaling_matrix4[4],16,default_scaling4[1],scaling_matrix4[3]); // Inter, Cr
-        decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb
-        if(is_sps || pps->transform_8x8_mode){
-            decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]);  // Intra, Y
-            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_matrix4[0], 16, default_scaling4[0], fallback[0]);        // Intra, Y
+        decode_scaling_list(h, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr
+        decode_scaling_list(h, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb
+        decode_scaling_list(h, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]);        // Inter, Y
+        decode_scaling_list(h, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr
+        decode_scaling_list(h, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb
+        if (is_sps || pps->transform_8x8_mode) {
+            decode_scaling_list(h, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y
+            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[4],64,default_scaling8[1],scaling_matrix8[3]);  // Inter, Cr
-                decode_scaling_list(h,scaling_matrix8[5],64,default_scaling8[1],scaling_matrix8[4]);  // Inter, 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[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr
+                decode_scaling_list(h, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb
             }
         }
     }
 }
 
-int ff_h264_decode_seq_parameter_set(H264Context *h){
-    MpegEncContext * const s = &h->s;
+int ff_h264_decode_seq_parameter_set(H264Context *h)
+{
     int profile_idc, level_idc, constraint_set_flags = 0;
     unsigned int sps_id;
     int i, log2_max_frame_num_minus4;
     SPS *sps;
 
-    profile_idc= get_bits(&s->gb, 8);
-    constraint_set_flags |= get_bits1(&s->gb) << 0;   //constraint_set0_flag
-    constraint_set_flags |= get_bits1(&s->gb) << 1;   //constraint_set1_flag
-    constraint_set_flags |= get_bits1(&s->gb) << 2;   //constraint_set2_flag
-    constraint_set_flags |= get_bits1(&s->gb) << 3;   //constraint_set3_flag
-    get_bits(&s->gb, 4); // reserved
-    level_idc= get_bits(&s->gb, 8);
-    sps_id= get_ue_golomb_31(&s->gb);
-
-    if(sps_id >= MAX_SPS_COUNT) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id);
-        return -1;
+    profile_idc           = get_bits(&h->gb, 8);
+    constraint_set_flags |= get_bits1(&h->gb) << 0;   // constraint_set0_flag
+    constraint_set_flags |= get_bits1(&h->gb) << 1;   // constraint_set1_flag
+    constraint_set_flags |= get_bits1(&h->gb) << 2;   // constraint_set2_flag
+    constraint_set_flags |= get_bits1(&h->gb) << 3;   // constraint_set3_flag
+    get_bits(&h->gb, 4); // reserved
+    level_idc = get_bits(&h->gb, 8);
+    sps_id    = get_ue_golomb_31(&h->gb);
+
+    if (sps_id >= MAX_SPS_COUNT) {
+        av_log(h->avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id);
+        return AVERROR_INVALIDDATA;
     }
-    sps= av_mallocz(sizeof(SPS));
-    if(sps == NULL)
-        return -1;
+    sps = av_mallocz(sizeof(SPS));
+    if (!sps)
+        return AVERROR(ENOMEM);
 
-    sps->time_offset_length = 24;
-    sps->profile_idc= profile_idc;
+    sps->time_offset_length   = 24;
+    sps->profile_idc          = profile_idc;
     sps->constraint_set_flags = constraint_set_flags;
-    sps->level_idc= level_idc;
+    sps->level_idc            = level_idc;
 
     memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
     memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
@@ -338,117 +330,154 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
         sps->profile_idc ==  44 || sps->profile_idc ==  83 ||
         sps->profile_idc ==  86 || sps->profile_idc == 118 ||
         sps->profile_idc == 128 || sps->profile_idc == 144) {
-        sps->chroma_format_idc= get_ue_golomb_31(&s->gb);
-        if(sps->chroma_format_idc > 3) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc (%u) out of range\n", sps->chroma_format_idc);
+        sps->chroma_format_idc = get_ue_golomb_31(&h->gb);
+        if (sps->chroma_format_idc > 3) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "chroma_format_idc (%u) out of range\n",
+                   sps->chroma_format_idc);
             goto fail;
-        } else if(sps->chroma_format_idc == 3) {
-            sps->residual_color_transform_flag = get_bits1(&s->gb);
+        } else if (sps->chroma_format_idc == 3) {
+            sps->residual_color_transform_flag = get_bits1(&h->gb);
         }
-        sps->bit_depth_luma   = get_ue_golomb(&s->gb) + 8;
-        sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8;
-        sps->transform_bypass = get_bits1(&s->gb);
-        decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
-    }else{
-        sps->chroma_format_idc= 1;
-        sps->bit_depth_luma   = 8;
-        sps->bit_depth_chroma = 8;
+        sps->bit_depth_luma   = get_ue_golomb(&h->gb) + 8;
+        sps->bit_depth_chroma = get_ue_golomb(&h->gb) + 8;
+        sps->transform_bypass = get_bits1(&h->gb);
+        decode_scaling_matrices(h, sps, NULL, 1,
+                                sps->scaling_matrix4, sps->scaling_matrix8);
+    } else {
+        sps->chroma_format_idc = 1;
+        sps->bit_depth_luma    = 8;
+        sps->bit_depth_chroma  = 8;
     }
 
-    log2_max_frame_num_minus4 = get_ue_golomb(&s->gb);
+    log2_max_frame_num_minus4 = get_ue_golomb(&h->gb);
     if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 ||
         log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "log2_max_frame_num_minus4 out of range (0-12): %d\n",
                log2_max_frame_num_minus4);
         goto fail;
     }
     sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4;
 
-    sps->poc_type= get_ue_golomb_31(&s->gb);
+    sps->poc_type = get_ue_golomb_31(&h->gb);
 
-    if(sps->poc_type == 0){ //FIXME #define
-        sps->log2_max_poc_lsb= get_ue_golomb(&s->gb) + 4;
-    } else if(sps->poc_type == 1){//FIXME #define
-        sps->delta_pic_order_always_zero_flag= get_bits1(&s->gb);
-        sps->offset_for_non_ref_pic= get_se_golomb(&s->gb);
-        sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb);
-        sps->poc_cycle_length                = get_ue_golomb(&s->gb);
+    if (sps->poc_type == 0) { // FIXME #define
+        sps->log2_max_poc_lsb = get_ue_golomb(&h->gb) + 4;
+    } else if (sps->poc_type == 1) { // FIXME #define
+        sps->delta_pic_order_always_zero_flag = get_bits1(&h->gb);
+        sps->offset_for_non_ref_pic           = get_se_golomb(&h->gb);
+        sps->offset_for_top_to_bottom_field   = get_se_golomb(&h->gb);
+        sps->poc_cycle_length                 = get_ue_golomb(&h->gb);
 
-        if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){
-            av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length);
+        if ((unsigned)sps->poc_cycle_length >=
+            FF_ARRAY_ELEMS(sps->offset_for_ref_frame)) {
+            av_log(h->avctx, AV_LOG_ERROR,
+                   "poc_cycle_length overflow %u\n", sps->poc_cycle_length);
             goto fail;
         }
 
-        for(i=0; i<sps->poc_cycle_length; i++)
-            sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb);
-    }else if(sps->poc_type != 2){
-        av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
+        for (i = 0; i < sps->poc_cycle_length; i++)
+            sps->offset_for_ref_frame[i] = get_se_golomb(&h->gb);
+    } else if (sps->poc_type != 2) {
+        av_log(h->avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
         goto fail;
     }
 
-    sps->ref_frame_count= get_ue_golomb_31(&s->gb);
-    if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){
-        av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n");
+    sps->ref_frame_count = get_ue_golomb_31(&h->gb);
+    if (sps->ref_frame_count > MAX_PICTURE_COUNT - 2 ||
+        sps->ref_frame_count >= 32U) {
+        av_log(h->avctx, AV_LOG_ERROR, "too many reference frames\n");
         goto fail;
     }
-    sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb);
-    sps->mb_width = get_ue_golomb(&s->gb) + 1;
-    sps->mb_height= get_ue_golomb(&s->gb) + 1;
-    if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 ||
-       av_image_check_size(16*sps->mb_width, 16*sps->mb_height, 0, h->s.avctx)){
-        av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
+    sps->gaps_in_frame_num_allowed_flag = get_bits1(&h->gb);
+    sps->mb_width                       = get_ue_golomb(&h->gb) + 1;
+    sps->mb_height                      = get_ue_golomb(&h->gb) + 1;
+    if ((unsigned)sps->mb_width  >= INT_MAX / 16 ||
+        (unsigned)sps->mb_height >= INT_MAX / 16 ||
+        av_image_check_size(16 * sps->mb_width,
+                            16 * sps->mb_height, 0, h->avctx)) {
+        av_log(h->avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
         goto fail;
     }
 
-    sps->frame_mbs_only_flag= get_bits1(&s->gb);
-    if(!sps->frame_mbs_only_flag)
-        sps->mb_aff= get_bits1(&s->gb);
+    sps->frame_mbs_only_flag = get_bits1(&h->gb);
+    if (!sps->frame_mbs_only_flag)
+        sps->mb_aff = get_bits1(&h->gb);
     else
-        sps->mb_aff= 0;
+        sps->mb_aff = 0;
 
-    sps->direct_8x8_inference_flag= get_bits1(&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");
+    sps->direct_8x8_inference_flag = get_bits1(&h->gb);
+    if (!sps->frame_mbs_only_flag && !sps->direct_8x8_inference_flag) {
+        av_log(h->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)
-        av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n");
+    if (sps->mb_aff)
+        av_log(h->avctx, AV_LOG_ERROR,
+               "MBAFF support not included; enable it at compile-time.\n");
 #endif
-    sps->crop= get_bits1(&s->gb);
-    if(sps->crop){
-        int crop_vertical_limit   = sps->chroma_format_idc  & 2 ? 16 : 8;
-        int crop_horizontal_limit = sps->chroma_format_idc == 3 ? 16 : 8;
-        sps->crop_left  = get_ue_golomb(&s->gb);
-        sps->crop_right = get_ue_golomb(&s->gb);
-        sps->crop_top   = get_ue_golomb(&s->gb);
-        sps->crop_bottom= get_ue_golomb(&s->gb);
-        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");
-        }
-        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");
+    sps->crop = get_bits1(&h->gb);
+    if (sps->crop) {
+        int crop_left   = get_ue_golomb(&h->gb);
+        int crop_right  = get_ue_golomb(&h->gb);
+        int crop_top    = get_ue_golomb(&h->gb);
+        int crop_bottom = get_ue_golomb(&h->gb);
+
+        if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
+            av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
+                                           "values are l:%u r:%u t:%u b:%u\n",
+                   crop_left, crop_right, crop_top, crop_bottom);
+
+            sps->crop_left   =
+            sps->crop_right  =
+            sps->crop_top    =
+            sps->crop_bottom = 0;
+        } else {
+            int vsub   = (sps->chroma_format_idc == 1) ? 1 : 0;
+            int hsub   = (sps->chroma_format_idc == 1 ||
+                          sps->chroma_format_idc == 2) ? 1 : 0;
+            int step_x = 1 << hsub;
+            int step_y = (2 - sps->frame_mbs_only_flag) << vsub;
+
+            if (crop_left & (0x1F >> (sps->bit_depth_luma > 8)) &&
+                !(h->avctx->flags & CODEC_FLAG_UNALIGNED)) {
+                crop_left &= ~(0x1F >> (sps->bit_depth_luma > 8));
+                av_log(h->avctx, AV_LOG_WARNING,
+                       "Reducing left cropping to %d "
+                       "chroma samples to preserve alignment.\n",
+                       crop_left);
+            }
+
+            sps->crop_left   = crop_left   * step_x;
+            sps->crop_right  = crop_right  * step_x;
+            sps->crop_top    = crop_top    * step_y;
+            sps->crop_bottom = crop_bottom * step_y;
         }
-    }else{
-        sps->crop_left  =
-        sps->crop_right =
-        sps->crop_top   =
-        sps->crop_bottom= 0;
+    } else {
+        sps->crop_left   =
+        sps->crop_right  =
+        sps->crop_top    =
+        sps->crop_bottom =
+        sps->crop        = 0;
     }
 
-    sps->vui_parameters_present_flag= get_bits1(&s->gb);
-    if( sps->vui_parameters_present_flag )
-        if (decode_vui_parameters(h, sps) < 0)
+    sps->vui_parameters_present_flag = get_bits1(&h->gb);
+    if (sps->vui_parameters_present_flag) {
+        int ret = decode_vui_parameters(h, sps);
+        if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
             goto fail;
+    }
 
-    if(!sps->sar.den)
-        sps->sar.den= 1;
+    if (!sps->sar.den)
+        sps->sar.den = 1;
 
-    if(s->avctx->debug&FF_DEBUG_PICT_INFO){
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
         static const char csp[4][5] = { "Gray", "420", "422", "444" };
-        av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d\n",
+        av_log(h->avctx, AV_LOG_DEBUG,
+               "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s %s %d/%d\n",
                sps_id, sps->profile_idc, sps->level_idc,
                sps->poc_type,
                sps->ref_frame_count,
@@ -460,8 +489,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
                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->new = 1;
 
@@ -471,122 +499,132 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
     h->current_sps_id      = sps_id;
 
     return 0;
+
 fail:
     av_free(sps);
     return -1;
 }
 
-static void
-build_qp_table(PPS *pps, int t, int index, const int depth)
+static void build_qp_table(PPS *pps, int t, int index, const int depth)
 {
     int i;
-    const int max_qp = 51 + 6*(depth-8);
-    for(i = 0; i < max_qp+1; i++)
-        pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[depth-8][av_clip(i + index, 0, max_qp)];
+    const int max_qp = 51 + 6 * (depth - 8);
+    for (i = 0; i < max_qp + 1; i++)
+        pps->chroma_qp_table[t][i] =
+            ff_h264_chroma_qp[depth - 8][av_clip(i + index, 0, max_qp)];
 }
 
-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);
+int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length)
+{
+    unsigned int pps_id = get_ue_golomb(&h->gb);
     PPS *pps;
-    const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8);
+    const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);
     int bits_left;
 
-    if(pps_id >= MAX_PPS_COUNT) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
-        return -1;
+    if (pps_id >= MAX_PPS_COUNT) {
+        av_log(h->avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
+        return AVERROR_INVALIDDATA;
     } 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);
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Unimplemented luma bit depth=%d (max=10)\n",
+               h->sps.bit_depth_luma);
         return AVERROR_PATCHWELCOME;
     }
 
-    pps= av_mallocz(sizeof(PPS));
-    if(pps == NULL)
-        return -1;
-    pps->sps_id= get_ue_golomb_31(&s->gb);
-    if((unsigned)pps->sps_id>=MAX_SPS_COUNT || h->sps_buffers[pps->sps_id] == NULL){
-        av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n");
+    pps = av_mallocz(sizeof(PPS));
+    if (!pps)
+        return AVERROR(ENOMEM);
+    pps->sps_id = get_ue_golomb_31(&h->gb);
+    if ((unsigned)pps->sps_id >= MAX_SPS_COUNT ||
+        h->sps_buffers[pps->sps_id] == NULL) {
+        av_log(h->avctx, AV_LOG_ERROR, "sps_id out of range\n");
         goto fail;
     }
 
-    pps->cabac= get_bits1(&s->gb);
-    pps->pic_order_present= get_bits1(&s->gb);
-    pps->slice_group_count= get_ue_golomb(&s->gb) + 1;
-    if(pps->slice_group_count > 1 ){
-        pps->mb_slice_group_map_type= get_ue_golomb(&s->gb);
-        av_log(h->s.avctx, AV_LOG_ERROR, "FMO not supported\n");
-        switch(pps->mb_slice_group_map_type){
+    pps->cabac             = get_bits1(&h->gb);
+    pps->pic_order_present = get_bits1(&h->gb);
+    pps->slice_group_count = get_ue_golomb(&h->gb) + 1;
+    if (pps->slice_group_count > 1) {
+        pps->mb_slice_group_map_type = get_ue_golomb(&h->gb);
+        av_log(h->avctx, AV_LOG_ERROR, "FMO not supported\n");
+        switch (pps->mb_slice_group_map_type) {
         case 0:
 #if 0
-|   for( i = 0; i <= num_slice_groups_minus1; i++ ) |   |        |
-|    run_length[ i ]                                |1  |ue(v)   |
+    |       for (i = 0; i <= num_slice_groups_minus1; i++)  |   |      |
+    |           run_length[i]                               |1  |ue(v) |
 #endif
             break;
         case 2:
 #if 0
-|   for( i = 0; i < num_slice_groups_minus1; i++ )  |   |        |
-|{                                                  |   |        |
-|    top_left_mb[ i ]                               |1  |ue(v)   |
-|    bottom_right_mb[ i ]                           |1  |ue(v)   |
-|   }                                               |   |        |
+    |       for (i = 0; i < num_slice_groups_minus1; i++) { |   |      |
+    |           top_left_mb[i]                              |1  |ue(v) |
+    |           bottom_right_mb[i]                          |1  |ue(v) |
+    |       }                                               |   |      |
 #endif
             break;
         case 3:
         case 4:
         case 5:
 #if 0
-|   slice_group_change_direction_flag               |1  |u(1)    |
-|   slice_group_change_rate_minus1                  |1  |ue(v)   |
+    |       slice_group_change_direction_flag               |1  |u(1)  |
+    |       slice_group_change_rate_minus1                  |1  |ue(v) |
 #endif
             break;
         case 6:
 #if 0
-|   slice_group_id_cnt_minus1                       |1  |ue(v)   |
-|   for( i = 0; i <= slice_group_id_cnt_minus1; i++ |   |        |
-|)                                                  |   |        |
-|    slice_group_id[ i ]                            |1  |u(v)    |
+    |       slice_group_id_cnt_minus1                       |1  |ue(v) |
+    |       for (i = 0; i <= slice_group_id_cnt_minus1; i++)|   |      |
+    |           slice_group_id[i]                           |1  |u(v)  |
 #endif
             break;
         }
     }
-    pps->ref_count[0]= get_ue_golomb(&s->gb) + 1;
-    pps->ref_count[1]= get_ue_golomb(&s->gb) + 1;
-    if(pps->ref_count[0]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){
-        av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
+    pps->ref_count[0] = get_ue_golomb(&h->gb) + 1;
+    pps->ref_count[1] = get_ue_golomb(&h->gb) + 1;
+    if (pps->ref_count[0] - 1 > 32 - 1 || pps->ref_count[1] - 1 > 32 - 1) {
+        av_log(h->avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
         goto fail;
     }
 
-    pps->weighted_pred= get_bits1(&s->gb);
-    pps->weighted_bipred_idc= get_bits(&s->gb, 2);
-    pps->init_qp= get_se_golomb(&s->gb) + 26 + qp_bd_offset;
-    pps->init_qs= get_se_golomb(&s->gb) + 26 + qp_bd_offset;
-    pps->chroma_qp_index_offset[0]= get_se_golomb(&s->gb);
-    pps->deblocking_filter_parameters_present= get_bits1(&s->gb);
-    pps->constrained_intra_pred= get_bits1(&s->gb);
-    pps->redundant_pic_cnt_present = get_bits1(&s->gb);
-
-    pps->transform_8x8_mode= 0;
-    h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit
-    memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4));
-    memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8));
-
-    bits_left = bit_length - get_bits_count(&s->gb);
+    pps->weighted_pred                        = get_bits1(&h->gb);
+    pps->weighted_bipred_idc                  = get_bits(&h->gb, 2);
+    pps->init_qp                              = get_se_golomb(&h->gb) + 26 + qp_bd_offset;
+    pps->init_qs                              = get_se_golomb(&h->gb) + 26 + qp_bd_offset;
+    pps->chroma_qp_index_offset[0]            = get_se_golomb(&h->gb);
+    pps->deblocking_filter_parameters_present = get_bits1(&h->gb);
+    pps->constrained_intra_pred               = get_bits1(&h->gb);
+    pps->redundant_pic_cnt_present            = get_bits1(&h->gb);
+
+    pps->transform_8x8_mode = 0;
+    // contents of sps/pps can change even if id doesn't, so reinit
+    h->dequant_coeff_pps = -1;
+    memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4,
+           sizeof(pps->scaling_matrix4));
+    memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8,
+           sizeof(pps->scaling_matrix8));
+
+    bits_left = bit_length - get_bits_count(&h->gb);
     if (bits_left && (bits_left > 8 ||
-                      show_bits(&s->gb, bits_left) != 1 << (bits_left - 1))) {
-        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
+                      show_bits(&h->gb, bits_left) != 1 << (bits_left - 1))) {
+        pps->transform_8x8_mode = get_bits1(&h->gb);
+        decode_scaling_matrices(h, h->sps_buffers[pps->sps_id], pps, 0,
+                                pps->scaling_matrix4, pps->scaling_matrix8);
+        // second_chroma_qp_index_offset
+        pps->chroma_qp_index_offset[1] = get_se_golomb(&h->gb);
     } else {
-        pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0];
+        pps->chroma_qp_index_offset[1] = pps->chroma_qp_index_offset[0];
     }
 
-    build_qp_table(pps, 0, pps->chroma_qp_index_offset[0], h->sps.bit_depth_luma);
-    build_qp_table(pps, 1, pps->chroma_qp_index_offset[1], h->sps.bit_depth_luma);
-    if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
-        pps->chroma_qp_diff= 1;
+    build_qp_table(pps, 0, pps->chroma_qp_index_offset[0],
+                   h->sps.bit_depth_luma);
+    build_qp_table(pps, 1, pps->chroma_qp_index_offset[1],
+                   h->sps.bit_depth_luma);
+    if (pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
+        pps->chroma_qp_diff = 1;
 
-    if(s->avctx->debug&FF_DEBUG_PICT_INFO){
-        av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %s\n",
+    if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
+        av_log(h->avctx, AV_LOG_DEBUG,
+               "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d/%d %s %s %s %s\n",
                pps_id, pps->sps_id,
                pps->cabac ? "CABAC" : "CAVLC",
                pps->slice_group_count,
@@ -596,13 +634,13 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
                pps->deblocking_filter_parameters_present ? "LPAR" : "",
                pps->constrained_intra_pred ? "CONSTR" : "",
                pps->redundant_pic_cnt_present ? "REDU" : "",
-               pps->transform_8x8_mode ? "8x8DCT" : ""
-               );
+               pps->transform_8x8_mode ? "8x8DCT" : "");
     }
 
     av_free(h->pps_buffers[pps_id]);
-    h->pps_buffers[pps_id]= pps;
+    h->pps_buffers[pps_id] = pps;
     return 0;
+
 fail:
     av_free(pps);
     return -1;
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 0e4bd76..bba77d1 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -26,33 +26,38 @@
  */
 
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "h264.h"
 #include "golomb.h"
 
-//#undef NDEBUG
 #include <assert.h>
 
+#define COPY_PICTURE(dst, src) \
+do {\
+    *(dst) = *(src);\
+    (dst)->f.extended_data = (dst)->f.data;\
+    (dst)->tf.f = &(dst)->f;\
+} while (0)
+
 
 static void pic_as_field(Picture *pic, const int parity){
     int i;
     for (i = 0; i < 4; ++i) {
         if (parity == PICT_BOTTOM_FIELD)
             pic->f.data[i] += pic->f.linesize[i];
-        pic->f.reference    = parity;
+        pic->reference      = parity;
         pic->f.linesize[i] *= 2;
     }
     pic->poc= pic->field_poc[parity == PICT_BOTTOM_FIELD];
 }
 
-static int split_field_copy(Picture *dest, Picture *src,
-                            int parity, int id_add){
-    int match = !!(src->f.reference & parity);
+static int split_field_copy(Picture *dest, Picture *src, int parity, int id_add)
+{
+    int match = !!(src->reference & parity);
 
     if (match) {
-        *dest = *src;
-        if(parity != PICT_FRAME){
+        COPY_PICTURE(dest, src);
+        if (parity != PICT_FRAME) {
             pic_as_field(dest, parity);
             dest->pic_id *= 2;
             dest->pic_id += id_add;
@@ -62,95 +67,116 @@ static int split_field_copy(Picture *dest, Picture *src,
     return match;
 }
 
-static int build_def_list(Picture *def, Picture **in, int len, int is_long, int sel){
-    int i[2]={0};
-    int index=0;
+static int build_def_list(Picture *def, int def_len,
+                          Picture **in, int len, int is_long, int sel)
+{
+    int  i[2] = { 0 };
+    int index = 0;
 
-    while(i[0]<len || i[1]<len){
-        while (i[0] < len && !(in[ i[0] ] && (in[ i[0] ]->f.reference & sel)))
+    while ((i[0] < len || i[1] < len) && index < def_len) {
+        while (i[0] < len && !(in[i[0]] && (in[i[0]]->reference & sel)))
             i[0]++;
-        while (i[1] < len && !(in[ i[1] ] && (in[ i[1] ]->f.reference & (sel^3))))
+        while (i[1] < len && !(in[i[1]] && (in[i[1]]->reference & (sel ^ 3))))
             i[1]++;
-        if(i[0] < len){
-            in[ i[0] ]->pic_id= is_long ? i[0] : in[ i[0] ]->frame_num;
-            split_field_copy(&def[index++], in[ i[0]++ ], sel  , 1);
+        if (i[0] < len && index < def_len) {
+            in[i[0]]->pic_id = is_long ? i[0] : in[i[0]]->frame_num;
+            split_field_copy(&def[index++], in[i[0]++], sel, 1);
         }
-        if(i[1] < len){
-            in[ i[1] ]->pic_id= is_long ? i[1] : in[ i[1] ]->frame_num;
-            split_field_copy(&def[index++], in[ i[1]++ ], sel^3, 0);
+        if (i[1] < len && index < def_len) {
+            in[i[1]]->pic_id = is_long ? i[1] : in[i[1]]->frame_num;
+            split_field_copy(&def[index++], in[i[1]++], sel ^ 3, 0);
         }
     }
 
     return index;
 }
 
-static int add_sorted(Picture **sorted, Picture **src, int len, int limit, int dir){
+static int add_sorted(Picture **sorted, Picture **src, int len, int limit, int dir)
+{
     int i, best_poc;
-    int out_i= 0;
+    int out_i = 0;
 
-    for(;;){
-        best_poc= dir ? INT_MIN : INT_MAX;
+    for (;;) {
+        best_poc = dir ? INT_MIN : INT_MAX;
 
-        for(i=0; i<len; i++){
-            const int poc= src[i]->poc;
-            if(((poc > limit) ^ dir) && ((poc < best_poc) ^ dir)){
-                best_poc= poc;
-                sorted[out_i]= src[i];
+        for (i = 0; i < len; i++) {
+            const int poc = src[i]->poc;
+            if (((poc > limit) ^ dir) && ((poc < best_poc) ^ dir)) {
+                best_poc      = poc;
+                sorted[out_i] = src[i];
             }
         }
-        if(best_poc == (dir ? INT_MIN : INT_MAX))
+        if (best_poc == (dir ? INT_MIN : INT_MAX))
             break;
-        limit= sorted[out_i++]->poc - dir;
+        limit = sorted[out_i++]->poc - dir;
     }
     return out_i;
 }
 
-int ff_h264_fill_default_ref_list(H264Context *h){
-    MpegEncContext * const s = &h->s;
+int ff_h264_fill_default_ref_list(H264Context *h)
+{
     int i, len;
 
-    if(h->slice_type_nos==AV_PICTURE_TYPE_B){
+    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
         Picture *sorted[32];
         int cur_poc, list;
         int lens[2];
 
-        if(FIELD_PICTURE)
-            cur_poc= s->current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
+        if (FIELD_PICTURE(h))
+            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];
         else
-            cur_poc= s->current_picture_ptr->poc;
-
-        for(list= 0; list<2; list++){
-            len= add_sorted(sorted    , h->short_ref, h->short_ref_count, cur_poc, 1^list);
-            len+=add_sorted(sorted+len, h->short_ref, h->short_ref_count, cur_poc, 0^list);
-            assert(len<=32);
-            len= build_def_list(h->default_ref_list[list]    , sorted     , len, 0, s->picture_structure);
-            len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, s->picture_structure);
-            assert(len<=32);
-
-            if(len < h->ref_count[list])
-                memset(&h->default_ref_list[list][len], 0, sizeof(Picture)*(h->ref_count[list] - len));
-            lens[list]= len;
+            cur_poc = h->cur_pic_ptr->poc;
+
+        for (list = 0; list < 2; list++) {
+            len  = add_sorted(sorted,       h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);
+            len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);
+            assert(len <= 32);
+
+            len  = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]),
+                                  sorted, len, 0, h->picture_structure);
+            len += build_def_list(h->default_ref_list[list] + len,
+                                  FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
+                                  h->long_ref, 16, 1, h->picture_structure);
+
+            if (len < h->ref_count[list])
+                memset(&h->default_ref_list[list][len], 0, sizeof(Picture) * (h->ref_count[list] - len));
+            lens[list] = len;
         }
 
-        if(lens[0] == lens[1] && lens[1] > 1){
-            for (i = 0; h->default_ref_list[0][i].f.data[0] == h->default_ref_list[1][i].f.data[0] && i < lens[0]; i++);
-            if(i == lens[0])
-                FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]);
+        if (lens[0] == lens[1] && lens[1] > 1) {
+            for (i = 0; i < lens[0] &&
+                        h->default_ref_list[0][i].f.buf[0]->buffer ==
+                        h->default_ref_list[1][i].f.buf[0]->buffer; i++);
+            if (i == lens[0]) {
+                Picture tmp;
+                COPY_PICTURE(&tmp, &h->default_ref_list[1][0]);
+                COPY_PICTURE(&h->default_ref_list[1][0], &h->default_ref_list[1][1]);
+                COPY_PICTURE(&h->default_ref_list[1][1], &tmp);
+            }
         }
-    }else{
-        len = build_def_list(h->default_ref_list[0]    , h->short_ref, h->short_ref_count, 0, s->picture_structure);
-        len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16                , 1, s->picture_structure);
-        assert(len <= 32);
-        if(len < h->ref_count[0])
-            memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len));
+    } else {
+        len  = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]),
+                              h->short_ref, h->short_ref_count, 0, h->picture_structure);
+        len += build_def_list(h->default_ref_list[0] + len,
+                              FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,
+                              h-> long_ref, 16, 1, h->picture_structure);
+
+        if (len < h->ref_count[0])
+            memset(&h->default_ref_list[0][len], 0, sizeof(Picture) * (h->ref_count[0] - len));
     }
 #ifdef TRACE
-    for (i=0; i<h->ref_count[0]; i++) {
-        tprintf(h->s.avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].f.data[0]);
+    for (i = 0; i < h->ref_count[0]; i++) {
+        tprintf(h->avctx, "List0: %s fn:%d 0x%p\n",
+                (h->default_ref_list[0][i].long_ref ? "LT" : "ST"),
+                h->default_ref_list[0][i].pic_id,
+                h->default_ref_list[0][i].f.data[0]);
     }
-    if(h->slice_type_nos==AV_PICTURE_TYPE_B){
-        for (i=0; i<h->ref_count[1]; i++) {
-            tprintf(h->s.avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].f.data[0]);
+    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
+        for (i = 0; i < h->ref_count[1]; i++) {
+            tprintf(h->avctx, "List1: %s fn:%d 0x%p\n",
+                    (h->default_ref_list[1][i].long_ref ? "LT" : "ST"),
+                    h->default_ref_list[1][i].pic_id,
+                    h->default_ref_list[1][i].f.data[0]);
         }
     }
 #endif
@@ -170,11 +196,10 @@ static void print_long_term(H264Context *h);
  * @return frame number (short term) or long term index of picture
  *         described by pic_num
  */
-static int pic_num_extract(H264Context *h, int pic_num, int *structure){
-    MpegEncContext * const s = &h->s;
-
-    *structure = s->picture_structure;
-    if(FIELD_PICTURE){
+static int pic_num_extract(H264Context *h, int pic_num, int *structure)
+{
+    *structure = h->picture_structure;
+    if (FIELD_PICTURE(h)) {
         if (!(pic_num & 1))
             /* opposite field */
             *structure ^= PICT_FRAME;
@@ -184,111 +209,113 @@ static int pic_num_extract(H264Context *h, int pic_num, int *structure){
     return pic_num;
 }
 
-int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
-    MpegEncContext * const s = &h->s;
-    int list, index, pic_structure;
+int ff_h264_decode_ref_pic_list_reordering(H264Context *h)
+{
+    int list, index, pic_structure, i;
 
     print_short_term(h);
     print_long_term(h);
 
-    for(list=0; list<h->list_count; list++){
-        memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]);
+    for (list = 0; list < h->list_count; list++) {
+        for (i = 0; i < h->ref_count[list]; i++)
+            COPY_PICTURE(&h->ref_list[list][i], &h->default_ref_list[list][i]);
 
-        if(get_bits1(&s->gb)){
-            int pred= h->curr_pic_num;
+        if (get_bits1(&h->gb)) {
+            int pred = h->curr_pic_num;
 
-            for(index=0; ; index++){
-                unsigned int reordering_of_pic_nums_idc= get_ue_golomb_31(&s->gb);
+            for (index = 0; ; index++) {
+                unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(&h->gb);
                 unsigned int pic_id;
                 int i;
                 Picture *ref = NULL;
 
-                if(reordering_of_pic_nums_idc==3)
+                if (reordering_of_pic_nums_idc == 3)
                     break;
 
-                if(index >= h->ref_count[list]){
-                    av_log(h->s.avctx, AV_LOG_ERROR, "reference count overflow\n");
+                if (index >= h->ref_count[list]) {
+                    av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n");
                     return -1;
                 }
 
-                if(reordering_of_pic_nums_idc<3){
-                    if(reordering_of_pic_nums_idc<2){
-                        const unsigned int abs_diff_pic_num= get_ue_golomb(&s->gb) + 1;
+                if (reordering_of_pic_nums_idc < 3) {
+                    if (reordering_of_pic_nums_idc < 2) {
+                        const unsigned int abs_diff_pic_num = get_ue_golomb(&h->gb) + 1;
                         int frame_num;
 
-                        if(abs_diff_pic_num > h->max_pic_num){
-                            av_log(h->s.avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n");
+                        if (abs_diff_pic_num > h->max_pic_num) {
+                            av_log(h->avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n");
                             return -1;
                         }
 
-                        if(reordering_of_pic_nums_idc == 0) pred-= abs_diff_pic_num;
-                        else                                pred+= abs_diff_pic_num;
+                        if (reordering_of_pic_nums_idc == 0)
+                            pred -= abs_diff_pic_num;
+                        else
+                            pred += abs_diff_pic_num;
                         pred &= h->max_pic_num - 1;
 
                         frame_num = pic_num_extract(h, pred, &pic_structure);
 
-                        for(i= h->short_ref_count-1; i>=0; i--){
+                        for (i = h->short_ref_count - 1; i >= 0; i--) {
                             ref = h->short_ref[i];
-                            assert(ref->f.reference);
+                            assert(ref->reference);
                             assert(!ref->long_ref);
-                            if(
-                                   ref->frame_num == frame_num &&
-                                   (ref->f.reference & pic_structure)
-                              )
+                            if (ref->frame_num == frame_num &&
+                                (ref->reference & pic_structure))
                                 break;
                         }
-                        if(i>=0)
-                            ref->pic_id= pred;
-                    }else{
+                        if (i >= 0)
+                            ref->pic_id = pred;
+                    } else {
                         int long_idx;
-                        pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx
+                        pic_id = get_ue_golomb(&h->gb); //long_term_pic_idx
 
-                        long_idx= pic_num_extract(h, pic_id, &pic_structure);
+                        long_idx = pic_num_extract(h, pic_id, &pic_structure);
 
-                        if(long_idx>31){
-                            av_log(h->s.avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n");
+                        if (long_idx > 31) {
+                            av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n");
                             return -1;
                         }
                         ref = h->long_ref[long_idx];
-                        assert(!(ref && !ref->f.reference));
-                        if (ref && (ref->f.reference & pic_structure)) {
-                            ref->pic_id= pic_id;
+                        assert(!(ref && !ref->reference));
+                        if (ref && (ref->reference & pic_structure)) {
+                            ref->pic_id = pic_id;
                             assert(ref->long_ref);
-                            i=0;
-                        }else{
-                            i=-1;
+                            i = 0;
+                        } else {
+                            i = -1;
                         }
                     }
 
                     if (i < 0) {
-                        av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n");
+                        av_log(h->avctx, AV_LOG_ERROR, "reference picture missing during reorder\n");
                         memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME
                     } else {
-                        for(i=index; i+1<h->ref_count[list]; i++){
-                            if(ref->long_ref == h->ref_list[list][i].long_ref && ref->pic_id == h->ref_list[list][i].pic_id)
+                        for (i = index; i + 1 < h->ref_count[list]; i++) {
+                            if (ref->long_ref == h->ref_list[list][i].long_ref &&
+                                ref->pic_id   == h->ref_list[list][i].pic_id)
                                 break;
                         }
-                        for(; i > index; i--){
-                            h->ref_list[list][i]= h->ref_list[list][i-1];
+                        for (; i > index; i--) {
+                            COPY_PICTURE(&h->ref_list[list][i], &h->ref_list[list][i - 1]);
                         }
-                        h->ref_list[list][index]= *ref;
-                        if (FIELD_PICTURE){
+                        COPY_PICTURE(&h->ref_list[list][index], ref);
+                        if (FIELD_PICTURE(h)) {
                             pic_as_field(&h->ref_list[list][index], pic_structure);
                         }
                     }
-                }else{
-                    av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n");
+                } else {
+                    av_log(h->avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n");
                     return -1;
                 }
             }
         }
     }
-    for(list=0; list<h->list_count; list++){
-        for(index= 0; index < h->ref_count[list]; index++){
-            if (!h->ref_list[list][index].f.data[0]) {
-                av_log(h->s.avctx, AV_LOG_ERROR, "Missing reference picture\n");
-                if (h->default_ref_list[list][0].f.data[0])
-                    h->ref_list[list][index]= h->default_ref_list[list][0];
+    for (list = 0; list < h->list_count; list++) {
+        for (index = 0; index < h->ref_count[list]; index++) {
+            if (!h->ref_list[list][index].f.buf[0]) {
+                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n");
+                if (h->default_ref_list[list][0].f.buf[0])
+                    COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]);
                 else
                     return -1;
             }
@@ -298,28 +325,29 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
     return 0;
 }
 
-void ff_h264_fill_mbaff_ref_list(H264Context *h){
+void ff_h264_fill_mbaff_ref_list(H264Context *h)
+{
     int list, i, j;
-    for(list=0; list<2; list++){ //FIXME try list_count
-        for(i=0; i<h->ref_count[list]; i++){
+    for (list = 0; list < 2; list++) { //FIXME try list_count
+        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];
-            field[0] = *frame;
-            for(j=0; j<3; j++)
+            Picture *field = &h->ref_list[list][16 + 2 * i];
+            COPY_PICTURE(field, frame);
+            for (j = 0; j < 3; j++)
                 field[0].f.linesize[j] <<= 1;
-            field[0].f.reference = PICT_TOP_FIELD;
-            field[0].poc= field[0].field_poc[0];
-            field[1] = field[0];
-            for(j=0; j<3; j++)
+            field[0].reference = PICT_TOP_FIELD;
+            field[0].poc       = field[0].field_poc[0];
+            COPY_PICTURE(field + 1, field);
+            for (j = 0; j < 3; j++)
                 field[1].f.data[j] += frame->f.linesize[j];
-            field[1].f.reference = PICT_BOTTOM_FIELD;
-            field[1].poc= field[1].field_poc[1];
-
-            h->luma_weight[16+2*i][list][0] = h->luma_weight[16+2*i+1][list][0] = h->luma_weight[i][list][0];
-            h->luma_weight[16+2*i][list][1] = h->luma_weight[16+2*i+1][list][1] = h->luma_weight[i][list][1];
-            for(j=0; j<2; j++){
-                h->chroma_weight[16+2*i][list][j][0] = h->chroma_weight[16+2*i+1][list][j][0] = h->chroma_weight[i][list][j][0];
-                h->chroma_weight[16+2*i][list][j][1] = h->chroma_weight[16+2*i+1][list][j][1] = h->chroma_weight[i][list][j][1];
+            field[1].reference = PICT_BOTTOM_FIELD;
+            field[1].poc       = field[1].field_poc[1];
+
+            h->luma_weight[16 + 2 * i][list][0] = h->luma_weight[16 + 2 * i + 1][list][0] = h->luma_weight[i][list][0];
+            h->luma_weight[16 + 2 * i][list][1] = h->luma_weight[16 + 2 * i + 1][list][1] = h->luma_weight[i][list][1];
+            for (j = 0; j < 2; j++) {
+                h->chroma_weight[16 + 2 * i][list][j][0] = h->chroma_weight[16 + 2 * i + 1][list][j][0] = h->chroma_weight[i][list][j][0];
+                h->chroma_weight[16 + 2 * i][list][j][1] = h->chroma_weight[16 + 2 * i + 1][list][j][1] = h->chroma_weight[i][list][j][1];
             }
         }
     }
@@ -336,14 +364,15 @@ void ff_h264_fill_mbaff_ref_list(H264Context *h){
  *         for display purposes) zero if one of the fields remains in
  *         reference
  */
-static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){
+static inline int unreference_pic(H264Context *h, Picture *pic, int refmask)
+{
     int i;
-    if (pic->f.reference &= refmask) {
+    if (pic->reference &= refmask) {
         return 0;
     } else {
         for(i = 0; h->delayed_pic[i]; i++)
             if(pic == h->delayed_pic[i]){
-                pic->f.reference = DELAYED_PIC_REF;
+                pic->reference = DELAYED_PIC_REF;
                 break;
             }
         return 1;
@@ -358,15 +387,15 @@ static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){
  * @return pointer to the found picture, or NULL if no pic with the provided
  *                 frame number is found
  */
-static Picture * find_short(H264Context *h, int frame_num, int *idx){
-    MpegEncContext * const s = &h->s;
+static Picture *find_short(H264Context *h, int frame_num, int *idx)
+{
     int i;
 
-    for(i=0; i<h->short_ref_count; i++){
-        Picture *pic= h->short_ref[i];
-        if(s->avctx->debug&FF_DEBUG_MMCO)
-            av_log(h->s.avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic);
-        if(pic->frame_num == frame_num) {
+    for (i = 0; i < h->short_ref_count; i++) {
+        Picture *pic = h->short_ref[i];
+        if (h->avctx->debug & FF_DEBUG_MMCO)
+            av_log(h->avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic);
+        if (pic->frame_num == frame_num) {
             *idx = i;
             return pic;
         }
@@ -380,29 +409,31 @@ static Picture * find_short(H264Context *h, int frame_num, int *idx){
  * to be valid. Other list entries are shifted down.
  * @param i index into h->short_ref of picture to remove.
  */
-static void remove_short_at_index(H264Context *h, int i){
+static void remove_short_at_index(H264Context *h, int i)
+{
     assert(i >= 0 && i < h->short_ref_count);
-    h->short_ref[i]= NULL;
+    h->short_ref[i] = NULL;
     if (--h->short_ref_count)
-        memmove(&h->short_ref[i], &h->short_ref[i+1], (h->short_ref_count - i)*sizeof(Picture*));
+        memmove(&h->short_ref[i], &h->short_ref[i + 1],
+                (h->short_ref_count - i) * sizeof(Picture*));
 }
 
 /**
  *
  * @return the removed picture or NULL if an error occurs
  */
-static Picture * remove_short(H264Context *h, int frame_num, int ref_mask){
-    MpegEncContext * const s = &h->s;
+static Picture *remove_short(H264Context *h, int frame_num, int ref_mask)
+{
     Picture *pic;
     int i;
 
-    if(s->avctx->debug&FF_DEBUG_MMCO)
-        av_log(h->s.avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count);
+    if (h->avctx->debug & FF_DEBUG_MMCO)
+        av_log(h->avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count);
 
     pic = find_short(h, frame_num, &i);
-    if (pic){
-        if(unreference_pic(h, pic, ref_mask))
-        remove_short_at_index(h, i);
+    if (pic) {
+        if (unreference_pic(h, pic, ref_mask))
+            remove_short_at_index(h, i);
     }
 
     return pic;
@@ -413,15 +444,16 @@ static Picture * remove_short(H264Context *h, int frame_num, int ref_mask){
  * that list.
  * @return the removed picture or NULL if an error occurs
  */
-static Picture * remove_long(H264Context *h, int i, int ref_mask){
+static Picture *remove_long(H264Context *h, int i, int ref_mask)
+{
     Picture *pic;
 
-    pic= h->long_ref[i];
-    if (pic){
-        if(unreference_pic(h, pic, ref_mask)){
+    pic = h->long_ref[i];
+    if (pic) {
+        if (unreference_pic(h, pic, ref_mask)) {
             assert(h->long_ref[i]->long_ref == 1);
-            h->long_ref[i]->long_ref= 0;
-            h->long_ref[i]= NULL;
+            h->long_ref[i]->long_ref = 0;
+            h->long_ref[i]           = NULL;
             h->long_ref_count--;
         }
     }
@@ -429,31 +461,33 @@ static Picture * remove_long(H264Context *h, int i, int ref_mask){
     return pic;
 }
 
-void ff_h264_remove_all_refs(H264Context *h){
+void ff_h264_remove_all_refs(H264Context *h)
+{
     int i;
 
-    for(i=0; i<16; i++){
+    for (i = 0; i < 16; i++) {
         remove_long(h, i, 0);
     }
-    assert(h->long_ref_count==0);
+    assert(h->long_ref_count == 0);
 
-    for(i=0; i<h->short_ref_count; i++){
+    for (i = 0; i < h->short_ref_count; i++) {
         unreference_pic(h, h->short_ref[i], 0);
-        h->short_ref[i]= NULL;
+        h->short_ref[i] = NULL;
     }
-    h->short_ref_count=0;
+    h->short_ref_count = 0;
 }
 
 /**
  * print short term list
  */
-static void print_short_term(H264Context *h) {
+static void print_short_term(H264Context *h)
+{
     uint32_t i;
-    if(h->s.avctx->debug&FF_DEBUG_MMCO) {
-        av_log(h->s.avctx, AV_LOG_DEBUG, "short term list:\n");
-        for(i=0; i<h->short_ref_count; i++){
-            Picture *pic= h->short_ref[i];
-            av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
+    if (h->avctx->debug & FF_DEBUG_MMCO) {
+        av_log(h->avctx, AV_LOG_DEBUG, "short term list:\n");
+        for (i = 0; i < h->short_ref_count; i++) {
+            Picture *pic = h->short_ref[i];
+            av_log(h->avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
                    i, pic->frame_num, pic->poc, pic->f.data[0]);
         }
     }
@@ -462,14 +496,15 @@ static void print_short_term(H264Context *h) {
 /**
  * print long term list
  */
-static void print_long_term(H264Context *h) {
+static void print_long_term(H264Context *h)
+{
     uint32_t i;
-    if(h->s.avctx->debug&FF_DEBUG_MMCO) {
-        av_log(h->s.avctx, AV_LOG_DEBUG, "long term list:\n");
-        for(i = 0; i < 16; i++){
-            Picture *pic= h->long_ref[i];
+    if (h->avctx->debug & FF_DEBUG_MMCO) {
+        av_log(h->avctx, AV_LOG_DEBUG, "long term list:\n");
+        for (i = 0; i < 16; i++) {
+            Picture *pic = h->long_ref[i];
             if (pic) {
-                av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
+                av_log(h->avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n",
                        i, pic->frame_num, pic->poc, pic->f.data[0]);
             }
         }
@@ -490,7 +525,6 @@ static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos)
 
 int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
 {
-    MpegEncContext * const s = &h->s;
     MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
     int mmco_index = 0, i;
 
@@ -498,16 +532,15 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
 
     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)) {
-        mmco[0].opcode = MMCO_SHORT2UNUSED;
+        !(FIELD_PICTURE(h) && !h->first_field && h->cur_pic_ptr->reference)) {
+        mmco[0].opcode        = MMCO_SHORT2UNUSED;
         mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num;
-        mmco_index = 1;
-        if (FIELD_PICTURE) {
+        mmco_index            = 1;
+        if (FIELD_PICTURE(h)) {
             mmco[0].short_pic_num *= 2;
-            mmco[1].opcode = MMCO_SHORT2UNUSED;
-            mmco[1].short_pic_num = mmco[0].short_pic_num + 1;
-            mmco_index = 2;
+            mmco[1].opcode         = MMCO_SHORT2UNUSED;
+            mmco[1].short_pic_num  = mmco[0].short_pic_num + 1;
+            mmco_index             = 2;
         }
     }
 
@@ -516,7 +549,7 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
     } else if (!first_slice && mmco_index >= 0 &&
                (mmco_index != h->mmco_index ||
                 (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "Inconsistent MMCO state between slices [%d, %d, %d]\n",
                mmco_index, h->mmco_index, i);
         return AVERROR_INVALIDDATA;
@@ -524,38 +557,41 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
     return 0;
 }
 
-int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
-    MpegEncContext * const s = &h->s;
+int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
+{
     int i, av_uninit(j);
-    int current_ref_assigned=0, err=0;
+    int current_ref_assigned = 0, err = 0;
     Picture *av_uninit(pic);
 
-    if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0)
-        av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n");
+    if ((h->avctx->debug & FF_DEBUG_MMCO) && mmco_count == 0)
+        av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n");
 
-    for(i=0; i<mmco_count; i++){
+    for (i = 0; i < mmco_count; i++) {
         int av_uninit(structure), av_uninit(frame_num);
-        if(s->avctx->debug&FF_DEBUG_MMCO)
-            av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg);
+        if (h->avctx->debug & FF_DEBUG_MMCO)
+            av_log(h->avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode,
+                   h->mmco[i].short_pic_num, h->mmco[i].long_arg);
 
-        if(   mmco[i].opcode == MMCO_SHORT2UNUSED
-           || mmco[i].opcode == MMCO_SHORT2LONG){
+        if (mmco[i].opcode == MMCO_SHORT2UNUSED ||
+            mmco[i].opcode == MMCO_SHORT2LONG) {
             frame_num = pic_num_extract(h, mmco[i].short_pic_num, &structure);
-            pic = find_short(h, frame_num, &j);
-            if(!pic){
-                if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg]
-                   || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) {
-                    av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
+            pic       = find_short(h, frame_num, &j);
+            if (!pic) {
+                if (mmco[i].opcode != MMCO_SHORT2LONG ||
+                    !h->long_ref[mmco[i].long_arg]    ||
+                    h->long_ref[mmco[i].long_arg]->frame_num != frame_num) {
+                    av_log(h->avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
                     err = AVERROR_INVALIDDATA;
                 }
                 continue;
             }
         }
 
-        switch(mmco[i].opcode){
+        switch (mmco[i].opcode) {
         case MMCO_SHORT2UNUSED:
-            if(s->avctx->debug&FF_DEBUG_MMCO)
-                av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count);
+            if (h->avctx->debug & FF_DEBUG_MMCO)
+                av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n",
+                       h->mmco[i].short_pic_num, h->short_ref_count);
             remove_short(h, frame_num, structure ^ PICT_FRAME);
             break;
         case MMCO_SHORT2LONG:
@@ -563,19 +599,19 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
                     remove_long(h, mmco[i].long_arg, 0);
 
                 remove_short_at_index(h, j);
-                h->long_ref[ mmco[i].long_arg ]= pic;
-                if (h->long_ref[ mmco[i].long_arg ]){
-                    h->long_ref[ mmco[i].long_arg ]->long_ref=1;
+                h->long_ref[ mmco[i].long_arg ] = pic;
+                if (h->long_ref[mmco[i].long_arg]) {
+                    h->long_ref[mmco[i].long_arg]->long_ref = 1;
                     h->long_ref_count++;
                 }
             break;
         case MMCO_LONG2UNUSED:
-            j = pic_num_extract(h, mmco[i].long_arg, &structure);
+            j   = pic_num_extract(h, mmco[i].long_arg, &structure);
             pic = h->long_ref[j];
             if (pic) {
                 remove_long(h, j, structure ^ PICT_FRAME);
-            } else if(s->avctx->debug&FF_DEBUG_MMCO)
-                av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref long failure\n");
+            } else if (h->avctx->debug & FF_DEBUG_MMCO)
+                av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref long failure\n");
             break;
         case MMCO_LONG:
                     // Comment below left from previous code as it is an interresting note.
@@ -586,35 +622,34 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
                      * and mark this field valid.
                      */
 
-            if (h->long_ref[mmco[i].long_arg] != s->current_picture_ptr) {
+            if (h->long_ref[mmco[i].long_arg] != h->cur_pic_ptr) {
                 remove_long(h, mmco[i].long_arg, 0);
 
-                h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr;
-                h->long_ref[ mmco[i].long_arg ]->long_ref=1;
+                h->long_ref[mmco[i].long_arg]           = h->cur_pic_ptr;
+                h->long_ref[mmco[i].long_arg]->long_ref = 1;
                 h->long_ref_count++;
             }
 
-            s->current_picture_ptr->f.reference |= s->picture_structure;
-            current_ref_assigned=1;
+            h->cur_pic_ptr->reference |= h->picture_structure;
+            current_ref_assigned = 1;
             break;
         case MMCO_SET_MAX_LONG:
             assert(mmco[i].long_arg <= 16);
             // just remove the long term which index is greater than new max
-            for(j = mmco[i].long_arg; j<16; j++){
+            for (j = mmco[i].long_arg; j < 16; j++) {
                 remove_long(h, j, 0);
             }
             break;
         case MMCO_RESET:
-            while(h->short_ref_count){
+            while (h->short_ref_count) {
                 remove_short(h, h->short_ref[0]->frame_num, 0);
             }
-            for(j = 0; j < 16; j++) {
+            for (j = 0; j < 16; j++) {
                 remove_long(h, j, 0);
             }
-            h->frame_num=
-            s->current_picture_ptr->frame_num= 0;
+            h->frame_num  = h->cur_pic_ptr->frame_num = 0;
             h->mmco_reset = 1;
-            s->current_picture_ptr->mmco_reset=1;
+            h->cur_pic_ptr->mmco_reset = 1;
             break;
         default: assert(0);
         }
@@ -627,39 +662,40 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
          * in long_ref; trying to put it on the short list here is an
          * error in the encoded bit stream (ref: 7.4.3.3, NOTE 2 and 3).
          */
-        if (h->short_ref_count && h->short_ref[0] == s->current_picture_ptr) {
+        if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) {
             /* Just mark the second field valid */
-            s->current_picture_ptr->f.reference = PICT_FRAME;
-        } else if (s->current_picture_ptr->long_ref) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term reference "
-                                             "assignment for second field "
-                                             "in complementary field pair "
-                                             "(first field is long term)\n");
+            h->cur_pic_ptr->reference = PICT_FRAME;
+        } else if (h->cur_pic_ptr->long_ref) {
+            av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference "
+                                           "assignment for second field "
+                                           "in complementary field pair "
+                                           "(first field is long term)\n");
             err = AVERROR_INVALIDDATA;
         } else {
-            pic= remove_short(h, s->current_picture_ptr->frame_num, 0);
-            if(pic){
-                av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
+            pic = remove_short(h, h->cur_pic_ptr->frame_num, 0);
+            if (pic) {
+                av_log(h->avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
                 err = AVERROR_INVALIDDATA;
             }
 
-            if(h->short_ref_count)
-                memmove(&h->short_ref[1], &h->short_ref[0], h->short_ref_count*sizeof(Picture*));
+            if (h->short_ref_count)
+                memmove(&h->short_ref[1], &h->short_ref[0],
+                        h->short_ref_count * sizeof(Picture*));
 
-            h->short_ref[0]= s->current_picture_ptr;
+            h->short_ref[0] = h->cur_pic_ptr;
             h->short_ref_count++;
-            s->current_picture_ptr->f.reference |= s->picture_structure;
+            h->cur_pic_ptr->reference |= h->picture_structure;
         }
     }
 
     if (h->long_ref_count + h->short_ref_count -
-            (h->short_ref[0] == s->current_picture_ptr) > h->sps.ref_frame_count){
+        (h->short_ref[0] == h->cur_pic_ptr) > h->sps.ref_frame_count) {
 
         /* We have too many reference frames, probably due to corrupted
          * stream. Need to discard one frame. Prevents overrun of the
          * short_ref and long_ref buffers.
          */
-        av_log(h->s.avctx, AV_LOG_ERROR,
+        av_log(h->avctx, AV_LOG_ERROR,
                "number of reference frames (%d+%d) exceeds max (%d; probably "
                "corrupt input), discarding one\n",
                h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count);
@@ -680,23 +716,22 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
 
     print_short_term(h);
     print_long_term(h);
-    return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
+    return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
 }
 
 int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
                                    int first_slice)
 {
-    MpegEncContext * const s = &h->s;
     int i, ret;
     MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
     int mmco_index = 0;
 
-    if (h->nal_unit_type == NAL_IDR_SLICE){ // FIXME fields
-        s->broken_link = get_bits1(gb) - 1;
-        if (get_bits1(gb)){
-            mmco[0].opcode = MMCO_LONG;
+    if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields
+        skip_bits1(gb); // broken_link
+        if (get_bits1(gb)) {
+            mmco[0].opcode   = MMCO_LONG;
             mmco[0].long_arg = 0;
-            mmco_index = 1;
+            mmco_index       = 1;
         }
     } else {
         if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag
@@ -704,7 +739,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
                 MMCOOpcode opcode = get_ue_golomb_31(gb);
 
                 mmco[i].opcode = opcode;
-                if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG){
+                if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) {
                     mmco[i].short_pic_num =
                         (h->curr_pic_num - get_ue_golomb(gb) - 1) &
                             (h->max_pic_num - 1);
@@ -724,8 +759,8 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
                     if (long_arg >= 32 ||
                         (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG &&
                                              long_arg == 16) &&
-                         !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE))){
-                        av_log(h->s.avctx, AV_LOG_ERROR,
+                         !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(h)))) {
+                        av_log(h->avctx, AV_LOG_ERROR,
                                "illegal long ref in memory management control "
                                "operation %d\n", opcode);
                         return -1;
@@ -733,8 +768,8 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
                     mmco[i].long_arg = long_arg;
                 }
 
-                if (opcode > (unsigned) MMCO_LONG){
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                if (opcode > (unsigned) MMCO_LONG) {
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "illegal memory management control operation %d\n",
                            opcode);
                     return -1;
@@ -746,7 +781,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
         } else {
             if (first_slice) {
                 ret = ff_generate_sliding_window_mmcos(h, first_slice);
-                if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE)
+                if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
                     return ret;
             }
             mmco_index = -1;
@@ -757,10 +792,10 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
         h->mmco_index = mmco_index;
     } else if (!first_slice && mmco_index >= 0 &&
                (mmco_index != h->mmco_index ||
-                (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) {
-        av_log(h->s.avctx, AV_LOG_ERROR,
-               "Inconsistent MMCO state between slices [%d, %d, %d]\n",
-               mmco_index, h->mmco_index, i);
+                check_opcodes(h->mmco, mmco_temp, mmco_index))) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "Inconsistent MMCO state between slices [%d, %d]\n",
+               mmco_index, h->mmco_index);
         return AVERROR_INVALIDDATA;
     }
 
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index 2e5fb65..28e044d 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -30,130 +30,145 @@
 #include "h264.h"
 #include "golomb.h"
 
-//#undef NDEBUG
 #include <assert.h>
 
-static const uint8_t sei_num_clock_ts_table[9]={
-    1,  1,  1,  2,  2,  3,  3,  2,  3
+static const uint8_t sei_num_clock_ts_table[9] = {
+    1, 1, 1, 2, 2, 3, 3, 2, 3
 };
 
-void ff_h264_reset_sei(H264Context *h) {
+void ff_h264_reset_sei(H264Context *h)
+{
     h->sei_recovery_frame_cnt       = -1;
     h->sei_dpb_output_delay         =  0;
     h->sei_cpb_removal_delay        = -1;
     h->sei_buffering_period_present =  0;
+    h->sei_frame_packing_present    =  0;
 }
 
-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);
+static int decode_picture_timing(H264Context *h)
+{
+    if (h->sps.nal_hrd_parameters_present_flag ||
+        h->sps.vcl_hrd_parameters_present_flag) {
+        h->sei_cpb_removal_delay = get_bits(&h->gb,
+                                            h->sps.cpb_removal_delay_length);
+        h->sei_dpb_output_delay  = get_bits(&h->gb,
+                                            h->sps.dpb_output_delay_length);
     }
-    if(h->sps.pic_struct_present_flag){
+    if (h->sps.pic_struct_present_flag) {
         unsigned int i, num_clock_ts;
-        h->sei_pic_struct = get_bits(&s->gb, 4);
+
+        h->sei_pic_struct = get_bits(&h->gb, 4);
         h->sei_ct_type    = 0;
 
         if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING)
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct];
 
-        for (i = 0 ; i < num_clock_ts ; i++){
-            if(get_bits(&s->gb, 1)){                  /* clock_timestamp_flag */
+        for (i = 0; i < num_clock_ts; i++) {
+            if (get_bits(&h->gb, 1)) {                /* clock_timestamp_flag */
                 unsigned int full_timestamp_flag;
-                h->sei_ct_type |= 1<<get_bits(&s->gb, 2);
-                skip_bits(&s->gb, 1);                 /* nuit_field_based_flag */
-                skip_bits(&s->gb, 5);                 /* counting_type */
-                full_timestamp_flag = get_bits(&s->gb, 1);
-                skip_bits(&s->gb, 1);                 /* discontinuity_flag */
-                skip_bits(&s->gb, 1);                 /* cnt_dropped_flag */
-                skip_bits(&s->gb, 8);                 /* n_frames */
-                if(full_timestamp_flag){
-                    skip_bits(&s->gb, 6);             /* seconds_value 0..59 */
-                    skip_bits(&s->gb, 6);             /* minutes_value 0..59 */
-                    skip_bits(&s->gb, 5);             /* hours_value 0..23 */
-                }else{
-                    if(get_bits(&s->gb, 1)){          /* seconds_flag */
-                        skip_bits(&s->gb, 6);         /* seconds_value range 0..59 */
-                        if(get_bits(&s->gb, 1)){      /* minutes_flag */
-                            skip_bits(&s->gb, 6);     /* minutes_value 0..59 */
-                            if(get_bits(&s->gb, 1))   /* hours_flag */
-                                skip_bits(&s->gb, 5); /* hours_value 0..23 */
+
+                h->sei_ct_type |= 1 << get_bits(&h->gb, 2);
+                skip_bits(&h->gb, 1);                 /* nuit_field_based_flag */
+                skip_bits(&h->gb, 5);                 /* counting_type */
+                full_timestamp_flag = get_bits(&h->gb, 1);
+                skip_bits(&h->gb, 1);                 /* discontinuity_flag */
+                skip_bits(&h->gb, 1);                 /* cnt_dropped_flag */
+                skip_bits(&h->gb, 8);                 /* n_frames */
+                if (full_timestamp_flag) {
+                    skip_bits(&h->gb, 6);             /* seconds_value 0..59 */
+                    skip_bits(&h->gb, 6);             /* minutes_value 0..59 */
+                    skip_bits(&h->gb, 5);             /* hours_value 0..23 */
+                } else {
+                    if (get_bits(&h->gb, 1)) {        /* seconds_flag */
+                        skip_bits(&h->gb, 6);         /* seconds_value range 0..59 */
+                        if (get_bits(&h->gb, 1)) {    /* minutes_flag */
+                            skip_bits(&h->gb, 6);     /* minutes_value 0..59 */
+                            if (get_bits(&h->gb, 1))  /* hours_flag */
+                                skip_bits(&h->gb, 5); /* hours_value 0..23 */
                         }
                     }
                 }
-                if(h->sps.time_offset_length > 0)
-                    skip_bits(&s->gb, h->sps.time_offset_length); /* time_offset */
+                if (h->sps.time_offset_length > 0)
+                    skip_bits(&h->gb,
+                              h->sps.time_offset_length); /* time_offset */
             }
         }
 
-        if(s->avctx->debug & FF_DEBUG_PICT_INFO)
-            av_log(s->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", h->sei_ct_type, h->sei_pic_struct);
+        if (h->avctx->debug & FF_DEBUG_PICT_INFO)
+            av_log(h->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n",
+                   h->sei_ct_type, h->sei_pic_struct);
     }
     return 0;
 }
 
-static int decode_unregistered_user_data(H264Context *h, int size){
-    MpegEncContext * const s = &h->s;
-    uint8_t user_data[16+256];
+static int decode_unregistered_user_data(H264Context *h, int size)
+{
+    uint8_t user_data[16 + 256];
     int e, build, i;
 
-    if(size<16)
-        return -1;
+    if (size < 16)
+        return AVERROR_INVALIDDATA;
 
-    for(i=0; i<sizeof(user_data)-1 && i<size; i++){
-        user_data[i]= get_bits(&s->gb, 8);
-    }
+    for (i = 0; i < sizeof(user_data) - 1 && i < size; i++)
+        user_data[i] = get_bits(&h->gb, 8);
 
-    user_data[i]= 0;
-    e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build);
-    if(e==1 && build>0)
-        h->x264_build= build;
+    user_data[i] = 0;
+    e = sscanf(user_data + 16, "x264 - core %d", &build);
+    if (e == 1 && build > 0)
+        h->x264_build = build;
 
-    if(s->avctx->debug & FF_DEBUG_BUGS)
-        av_log(s->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16);
+    if (h->avctx->debug & FF_DEBUG_BUGS)
+        av_log(h->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data + 16);
 
-    for(; i<size; i++)
-        skip_bits(&s->gb, 8);
+    for (; i < size; i++)
+        skip_bits(&h->gb, 8);
 
     return 0;
 }
 
-static int decode_recovery_point(H264Context *h){
-    MpegEncContext * const s = &h->s;
+static int decode_recovery_point(H264Context *h)
+{
+    h->sei_recovery_frame_cnt = get_ue_golomb(&h->gb);
 
-    h->sei_recovery_frame_cnt = get_ue_golomb(&s->gb);
-    skip_bits(&s->gb, 4);       /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */
+    /* 1b exact_match_flag,
+     * 1b broken_link_flag,
+     * 2b changing_slice_group_idc */
+    skip_bits(&h->gb, 4);
 
     return 0;
 }
 
-static int decode_buffering_period(H264Context *h){
-    MpegEncContext * const s = &h->s;
+static int decode_buffering_period(H264Context *h)
+{
     unsigned int sps_id;
     int sched_sel_idx;
     SPS *sps;
 
-    sps_id = get_ue_golomb_31(&s->gb);
-    if(sps_id > 31 || !h->sps_buffers[sps_id]) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id);
-        return -1;
+    sps_id = get_ue_golomb_31(&h->gb);
+    if (sps_id > 31 || !h->sps_buffers[sps_id]) {
+        av_log(h->avctx, AV_LOG_ERROR,
+               "non-existing SPS %d referenced in buffering period\n", sps_id);
+        return AVERROR_INVALIDDATA;
     }
     sps = h->sps_buffers[sps_id];
 
     // NOTE: This is really so duplicated in the standard... See H.264, D.1.1
     if (sps->nal_hrd_parameters_present_flag) {
         for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
-            h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length);
-            skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
+            h->initial_cpb_removal_delay[sched_sel_idx] =
+                get_bits(&h->gb, sps->initial_cpb_removal_delay_length);
+            // initial_cpb_removal_delay_offset
+            skip_bits(&h->gb, sps->initial_cpb_removal_delay_length);
         }
     }
     if (sps->vcl_hrd_parameters_present_flag) {
         for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) {
-            h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length);
-            skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset
+            h->initial_cpb_removal_delay[sched_sel_idx] =
+                get_bits(&h->gb, sps->initial_cpb_removal_delay_length);
+            // initial_cpb_removal_delay_offset
+            skip_bits(&h->gb, sps->initial_cpb_removal_delay_length);
         }
     }
 
@@ -161,45 +176,85 @@ static int decode_buffering_period(H264Context *h){
     return 0;
 }
 
-int ff_h264_decode_sei(H264Context *h){
-    MpegEncContext * const s = &h->s;
+static int decode_frame_packing_arrangement(H264Context *h)
+{
+    get_ue_golomb(&h->gb);              // frame_packing_arrangement_id
+    h->sei_frame_packing_present = !get_bits1(&h->gb);
 
-    while (get_bits_left(&s->gb) > 16) {
-        int size, type;
+    if (h->sei_frame_packing_present) {
+        h->frame_packing_arrangement_type = get_bits(&h->gb, 7);
+        h->quincunx_subsampling           = get_bits1(&h->gb);
+        h->content_interpretation_type    = get_bits(&h->gb, 6);
 
-        type=0;
-        do{
-            type+= show_bits(&s->gb, 8);
-        }while(get_bits(&s->gb, 8) == 255);
+        // the following skips: spatial_flipping_flag, frame0_flipped_flag,
+        // field_views_flag, current_frame_is_frame0_flag,
+        // frame0_self_contained_flag, frame1_self_contained_flag
+        skip_bits(&h->gb, 6);
 
-        size=0;
-        do{
-            size+= show_bits(&s->gb, 8);
-        }while(get_bits(&s->gb, 8) == 255);
+        if (!h->quincunx_subsampling && h->frame_packing_arrangement_type != 5)
+            skip_bits(&h->gb, 16);      // frame[01]_grid_position_[xy]
+        skip_bits(&h->gb, 8);           // frame_packing_arrangement_reserved_byte
+        get_ue_golomb(&h->gb);          // frame_packing_arrangement_repetition_period
+    }
+    skip_bits1(&h->gb);                 // frame_packing_arrangement_extension_flag
+
+    return 0;
+}
 
-        switch(type){
+int ff_h264_decode_sei(H264Context *h)
+{
+    while (get_bits_left(&h->gb) > 16) {
+        int size = 0;
+        int type = 0;
+        int ret  = 0;
+
+        do
+            type += show_bits(&h->gb, 8);
+        while (get_bits(&h->gb, 8) == 255);
+
+        do
+            size += show_bits(&h->gb, 8);
+        while (get_bits(&h->gb, 8) == 255);
+
+        if (size > get_bits_left(&h->gb) / 8) {
+            av_log(h->avctx, AV_LOG_ERROR, "SEI type %d truncated at %d\n",
+                   type, get_bits_left(&h->gb));
+            return AVERROR_INVALIDDATA;
+        }
+
+        switch (type) {
         case SEI_TYPE_PIC_TIMING: // Picture timing SEI
-            if(decode_picture_timing(h) < 0)
-                return -1;
+            ret = decode_picture_timing(h);
+            if (ret < 0)
+                return ret;
             break;
         case SEI_TYPE_USER_DATA_UNREGISTERED:
-            if(decode_unregistered_user_data(h, size) < 0)
-                return -1;
+            ret = decode_unregistered_user_data(h, size);
+            if (ret < 0)
+                return ret;
             break;
         case SEI_TYPE_RECOVERY_POINT:
-            if(decode_recovery_point(h) < 0)
-                return -1;
+            ret = decode_recovery_point(h);
+            if (ret < 0)
+                return ret;
             break;
         case SEI_BUFFERING_PERIOD:
-            if(decode_buffering_period(h) < 0)
-                return -1;
+            ret = decode_buffering_period(h);
+            if (ret < 0)
+                return ret;
+            break;
+        case SEI_TYPE_FRAME_PACKING:
+            ret = decode_frame_packing_arrangement(h);
+            if (ret < 0)
+                return ret;
             break;
         default:
-            skip_bits(&s->gb, 8*size);
+            av_log(h->avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type);
+            skip_bits(&h->gb, 8 * size);
         }
 
-        //FIXME check bits here
-        align_get_bits(&s->gb);
+        // FIXME check bits here
+        align_get_bits(&h->gb);
     }
 
     return 0;
diff --git a/libavcodec/h264addpx_template.c b/libavcodec/h264addpx_template.c
new file mode 100644
index 0000000..cdbfc67
--- /dev/null
+++ b/libavcodec/h264addpx_template.c
@@ -0,0 +1,72 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003-2011 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * H.264 / AVC / MPEG4 part10 DSP functions.
+ * @author Michael Niedermayer <michaelni at gmx.at>
+ */
+
+#include "bit_depth_template.c"
+
+static void FUNCC(ff_h264_add_pixels4)(uint8_t *_dst, int16_t *_src, int stride)
+{
+    int i;
+    pixel *dst = (pixel *) _dst;
+    dctcoef *src = (dctcoef *) _src;
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 4; i++) {
+        dst[0] += src[0];
+        dst[1] += src[1];
+        dst[2] += src[2];
+        dst[3] += src[3];
+
+        dst += stride;
+        src += 4;
+    }
+
+    memset(_src, 0, sizeof(dctcoef) * 16);
+}
+
+static void FUNCC(ff_h264_add_pixels8)(uint8_t *_dst, int16_t *_src, int stride)
+{
+    int i;
+    pixel *dst = (pixel *) _dst;
+    dctcoef *src = (dctcoef *) _src;
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 8; i++) {
+        dst[0] += src[0];
+        dst[1] += src[1];
+        dst[2] += src[2];
+        dst[3] += src[3];
+        dst[4] += src[4];
+        dst[5] += src[5];
+        dst[6] += src[6];
+        dst[7] += src[7];
+
+        dst += stride;
+        src += 8;
+    }
+
+    memset(_src, 0, sizeof(dctcoef) * 64);
+}
diff --git a/libavcodec/h264chroma.c b/libavcodec/h264chroma.c
new file mode 100644
index 0000000..8aa5e93
--- /dev/null
+++ b/libavcodec/h264chroma.c
@@ -0,0 +1,53 @@
+/*
+ * 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 "libavutil/attributes.h"
+#include "h264chroma.h"
+
+#define BIT_DEPTH 8
+#include "h264chroma_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 16
+#include "h264chroma_template.c"
+#undef BIT_DEPTH
+
+#define SET_CHROMA(depth)                                                   \
+    c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_ ## depth ## _c; \
+    c->put_h264_chroma_pixels_tab[1] = put_h264_chroma_mc4_ ## depth ## _c; \
+    c->put_h264_chroma_pixels_tab[2] = put_h264_chroma_mc2_ ## depth ## _c; \
+    c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_ ## depth ## _c; \
+    c->avg_h264_chroma_pixels_tab[1] = avg_h264_chroma_mc4_ ## depth ## _c; \
+    c->avg_h264_chroma_pixels_tab[2] = avg_h264_chroma_mc2_ ## depth ## _c; \
+
+av_cold void ff_h264chroma_init(H264ChromaContext *c, int bit_depth)
+{
+    if (bit_depth > 8 && bit_depth <= 16) {
+        SET_CHROMA(16);
+    } else {
+        SET_CHROMA(8);
+    }
+
+    if (ARCH_ARM)
+        ff_h264chroma_init_arm(c, bit_depth);
+    if (ARCH_PPC)
+        ff_h264chroma_init_ppc(c, bit_depth);
+    if (ARCH_X86)
+        ff_h264chroma_init_x86(c, bit_depth);
+}
diff --git a/libavcodec/h264chroma.h b/libavcodec/h264chroma.h
new file mode 100644
index 0000000..34d9630
--- /dev/null
+++ b/libavcodec/h264chroma.h
@@ -0,0 +1,37 @@
+/*
+ * 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_H264CHROMA_H
+#define AVCODEC_H264CHROMA_H
+
+#include <stdint.h>
+
+typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
+
+typedef struct H264ChromaContext {
+    h264_chroma_mc_func put_h264_chroma_pixels_tab[3];
+    h264_chroma_mc_func avg_h264_chroma_pixels_tab[3];
+} H264ChromaContext;
+
+void ff_h264chroma_init(H264ChromaContext *c, int bit_depth);
+
+void ff_h264chroma_init_arm(H264ChromaContext *c, int bit_depth);
+void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth);
+void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth);
+
+#endif /* AVCODEC_H264CHROMA_H */
diff --git a/libavcodec/h264chroma_template.c b/libavcodec/h264chroma_template.c
new file mode 100644
index 0000000..351d9d2
--- /dev/null
+++ b/libavcodec/h264chroma_template.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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 <assert.h>
+
+#include "bit_depth_template.c"
+
+#define H264_CHROMA_MC(OPNAME, OP)\
+static void FUNCC(OPNAME ## h264_chroma_mc2)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
+    pixel *dst = (pixel*)_dst;\
+    pixel *src = (pixel*)_src;\
+    const int A=(8-x)*(8-y);\
+    const int B=(  x)*(8-y);\
+    const int C=(8-x)*(  y);\
+    const int D=(  x)*(  y);\
+    int i;\
+    stride /= sizeof(pixel);\
+    \
+    assert(x<8 && y<8 && x>=0 && y>=0);\
+\
+    if(D){\
+        for(i=0; i<h; i++){\
+            OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
+            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }else{\
+        const int E= B+C;\
+        const int step= C ? stride : 1;\
+        for(i=0; i<h; i++){\
+            OP(dst[0], (A*src[0] + E*src[step+0]));\
+            OP(dst[1], (A*src[1] + E*src[step+1]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }\
+}\
+\
+static void FUNCC(OPNAME ## h264_chroma_mc4)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
+    pixel *dst = (pixel*)_dst;\
+    pixel *src = (pixel*)_src;\
+    const int A=(8-x)*(8-y);\
+    const int B=(  x)*(8-y);\
+    const int C=(8-x)*(  y);\
+    const int D=(  x)*(  y);\
+    int i;\
+    stride /= sizeof(pixel);\
+    \
+    assert(x<8 && y<8 && x>=0 && y>=0);\
+\
+    if(D){\
+        for(i=0; i<h; i++){\
+            OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
+            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
+            OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
+            OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }else{\
+        const int E= B+C;\
+        const int step= C ? stride : 1;\
+        for(i=0; i<h; i++){\
+            OP(dst[0], (A*src[0] + E*src[step+0]));\
+            OP(dst[1], (A*src[1] + E*src[step+1]));\
+            OP(dst[2], (A*src[2] + E*src[step+2]));\
+            OP(dst[3], (A*src[3] + E*src[step+3]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }\
+}\
+\
+static void FUNCC(OPNAME ## h264_chroma_mc8)(uint8_t *_dst/*align 8*/, uint8_t *_src/*align 1*/, int stride, int h, int x, int y){\
+    pixel *dst = (pixel*)_dst;\
+    pixel *src = (pixel*)_src;\
+    const int A=(8-x)*(8-y);\
+    const int B=(  x)*(8-y);\
+    const int C=(8-x)*(  y);\
+    const int D=(  x)*(  y);\
+    int i;\
+    stride /= sizeof(pixel);\
+    \
+    assert(x<8 && y<8 && x>=0 && y>=0);\
+\
+    if(D){\
+        for(i=0; i<h; i++){\
+            OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));\
+            OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));\
+            OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));\
+            OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));\
+            OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));\
+            OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));\
+            OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));\
+            OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }else{\
+        const int E= B+C;\
+        const int step= C ? stride : 1;\
+        for(i=0; i<h; i++){\
+            OP(dst[0], (A*src[0] + E*src[step+0]));\
+            OP(dst[1], (A*src[1] + E*src[step+1]));\
+            OP(dst[2], (A*src[2] + E*src[step+2]));\
+            OP(dst[3], (A*src[3] + E*src[step+3]));\
+            OP(dst[4], (A*src[4] + E*src[step+4]));\
+            OP(dst[5], (A*src[5] + E*src[step+5]));\
+            OP(dst[6], (A*src[6] + E*src[step+6]));\
+            OP(dst[7], (A*src[7] + E*src[step+7]));\
+            dst+= stride;\
+            src+= stride;\
+        }\
+    }\
+}
+
+#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1)
+#define op_put(a, b) a = (((b) + 32)>>6)
+
+H264_CHROMA_MC(put_       , op_put)
+H264_CHROMA_MC(avg_       , op_avg)
+#undef op_avg
+#undef op_put
diff --git a/libavcodec/h264data.h b/libavcodec/h264data.h
index 5311c21..f90a267 100644
--- a/libavcodec/h264data.h
+++ b/libavcodec/h264data.h
@@ -59,27 +59,6 @@ static const uint8_t zigzag_scan[16] = {
     3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,
 };
 
-static const uint8_t field_scan[16] = {
-    0 + 0 * 4, 0 + 1 * 4, 1 + 0 * 4, 0 + 2 * 4,
-    0 + 3 * 4, 1 + 1 * 4, 1 + 2 * 4, 1 + 3 * 4,
-    2 + 0 * 4, 2 + 1 * 4, 2 + 2 * 4, 2 + 3 * 4,
-    3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4,
-};
-
-static const uint8_t luma_dc_zigzag_scan[16] = {
-    0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64,
-    3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64,
-    1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64,
-    3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64,
-};
-
-static const uint8_t luma_dc_field_scan[16] = {
-    0 * 16 + 0 * 64, 2 * 16 + 0 * 64, 1 * 16 + 0 * 64, 0 * 16 + 2 * 64,
-    2 * 16 + 2 * 64, 3 * 16 + 0 * 64, 1 * 16 + 2 * 64, 3 * 16 + 2 * 64,
-    0 * 16 + 1 * 64, 2 * 16 + 1 * 64, 0 * 16 + 3 * 64, 2 * 16 + 3 * 64,
-    1 * 16 + 1 * 64, 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 3 * 16 + 3 * 64,
-};
-
 static const uint8_t chroma_dc_scan[4] = {
     (0 + 0 * 2) * 16, (1 + 0 * 2) * 16,
     (0 + 1 * 2) * 16, (1 + 1 * 2) * 16,
@@ -92,64 +71,6 @@ static const uint8_t chroma422_dc_scan[8] = {
     (1 + 2 * 2) * 16, (1 + 3 * 2) * 16,
 };
 
-// zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)]
-static const uint8_t zigzag_scan8x8_cavlc[64] = {
-    0 + 0 * 8, 1 + 1 * 8, 1 + 2 * 8, 2 + 2 * 8,
-    4 + 1 * 8, 0 + 5 * 8, 3 + 3 * 8, 7 + 0 * 8,
-    3 + 4 * 8, 1 + 7 * 8, 5 + 3 * 8, 6 + 3 * 8,
-    2 + 7 * 8, 6 + 4 * 8, 5 + 6 * 8, 7 + 5 * 8,
-    1 + 0 * 8, 2 + 0 * 8, 0 + 3 * 8, 3 + 1 * 8,
-    3 + 2 * 8, 0 + 6 * 8, 4 + 2 * 8, 6 + 1 * 8,
-    2 + 5 * 8, 2 + 6 * 8, 6 + 2 * 8, 5 + 4 * 8,
-    3 + 7 * 8, 7 + 3 * 8, 4 + 7 * 8, 7 + 6 * 8,
-    0 + 1 * 8, 3 + 0 * 8, 0 + 4 * 8, 4 + 0 * 8,
-    2 + 3 * 8, 1 + 5 * 8, 5 + 1 * 8, 5 + 2 * 8,
-    1 + 6 * 8, 3 + 5 * 8, 7 + 1 * 8, 4 + 5 * 8,
-    4 + 6 * 8, 7 + 4 * 8, 5 + 7 * 8, 6 + 7 * 8,
-    0 + 2 * 8, 2 + 1 * 8, 1 + 3 * 8, 5 + 0 * 8,
-    1 + 4 * 8, 2 + 4 * 8, 6 + 0 * 8, 4 + 3 * 8,
-    0 + 7 * 8, 4 + 4 * 8, 7 + 2 * 8, 3 + 6 * 8,
-    5 + 5 * 8, 6 + 5 * 8, 6 + 6 * 8, 7 + 7 * 8,
-};
-
-static const uint8_t field_scan8x8[64] = {
-    0 + 0 * 8, 0 + 1 * 8, 0 + 2 * 8, 1 + 0 * 8,
-    1 + 1 * 8, 0 + 3 * 8, 0 + 4 * 8, 1 + 2 * 8,
-    2 + 0 * 8, 1 + 3 * 8, 0 + 5 * 8, 0 + 6 * 8,
-    0 + 7 * 8, 1 + 4 * 8, 2 + 1 * 8, 3 + 0 * 8,
-    2 + 2 * 8, 1 + 5 * 8, 1 + 6 * 8, 1 + 7 * 8,
-    2 + 3 * 8, 3 + 1 * 8, 4 + 0 * 8, 3 + 2 * 8,
-    2 + 4 * 8, 2 + 5 * 8, 2 + 6 * 8, 2 + 7 * 8,
-    3 + 3 * 8, 4 + 1 * 8, 5 + 0 * 8, 4 + 2 * 8,
-    3 + 4 * 8, 3 + 5 * 8, 3 + 6 * 8, 3 + 7 * 8,
-    4 + 3 * 8, 5 + 1 * 8, 6 + 0 * 8, 5 + 2 * 8,
-    4 + 4 * 8, 4 + 5 * 8, 4 + 6 * 8, 4 + 7 * 8,
-    5 + 3 * 8, 6 + 1 * 8, 6 + 2 * 8, 5 + 4 * 8,
-    5 + 5 * 8, 5 + 6 * 8, 5 + 7 * 8, 6 + 3 * 8,
-    7 + 0 * 8, 7 + 1 * 8, 6 + 4 * 8, 6 + 5 * 8,
-    6 + 6 * 8, 6 + 7 * 8, 7 + 2 * 8, 7 + 3 * 8,
-    7 + 4 * 8, 7 + 5 * 8, 7 + 6 * 8, 7 + 7 * 8,
-};
-
-static const uint8_t field_scan8x8_cavlc[64] = {
-    0 + 0 * 8, 1 + 1 * 8, 2 + 0 * 8, 0 + 7 * 8,
-    2 + 2 * 8, 2 + 3 * 8, 2 + 4 * 8, 3 + 3 * 8,
-    3 + 4 * 8, 4 + 3 * 8, 4 + 4 * 8, 5 + 3 * 8,
-    5 + 5 * 8, 7 + 0 * 8, 6 + 6 * 8, 7 + 4 * 8,
-    0 + 1 * 8, 0 + 3 * 8, 1 + 3 * 8, 1 + 4 * 8,
-    1 + 5 * 8, 3 + 1 * 8, 2 + 5 * 8, 4 + 1 * 8,
-    3 + 5 * 8, 5 + 1 * 8, 4 + 5 * 8, 6 + 1 * 8,
-    5 + 6 * 8, 7 + 1 * 8, 6 + 7 * 8, 7 + 5 * 8,
-    0 + 2 * 8, 0 + 4 * 8, 0 + 5 * 8, 2 + 1 * 8,
-    1 + 6 * 8, 4 + 0 * 8, 2 + 6 * 8, 5 + 0 * 8,
-    3 + 6 * 8, 6 + 0 * 8, 4 + 6 * 8, 6 + 2 * 8,
-    5 + 7 * 8, 6 + 4 * 8, 7 + 2 * 8, 7 + 6 * 8,
-    1 + 0 * 8, 1 + 2 * 8, 0 + 6 * 8, 3 + 0 * 8,
-    1 + 7 * 8, 3 + 2 * 8, 2 + 7 * 8, 4 + 2 * 8,
-    3 + 7 * 8, 5 + 2 * 8, 4 + 7 * 8, 5 + 4 * 8,
-    6 + 3 * 8, 6 + 5 * 8, 7 + 3 * 8, 7 + 7 * 8,
-};
-
 typedef struct IMbInfo {
     uint16_t type;
     uint8_t pred_mode;
@@ -247,26 +168,4 @@ static const PMbInfo b_sub_mb_type_info[13] = {
     { MB_TYPE_8x8   | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_P1L0 | MB_TYPE_P1L1, 4, },
 };
 
-static const uint8_t dequant4_coeff_init[6][3] = {
-    { 10, 13, 16 },
-    { 11, 14, 18 },
-    { 13, 16, 20 },
-    { 14, 18, 23 },
-    { 16, 20, 25 },
-    { 18, 23, 29 },
-};
-
-static const uint8_t dequant8_coeff_init_scan[16] = {
-    0, 3, 4, 3, 3, 1, 5, 1, 4, 5, 2, 5, 3, 1, 5, 1
-};
-
-static const uint8_t dequant8_coeff_init[6][6] = {
-    { 20, 18, 32, 19, 25, 24 },
-    { 22, 19, 35, 21, 28, 26 },
-    { 26, 23, 42, 24, 33, 31 },
-    { 28, 25, 45, 26, 35, 33 },
-    { 32, 28, 51, 30, 40, 38 },
-    { 36, 32, 58, 34, 46, 43 },
-};
-
 #endif /* AVCODEC_H264DATA_H */
diff --git a/libavcodec/h264dsp.c b/libavcodec/h264dsp.c
index 1353c1a..a901dbb 100644
--- a/libavcodec/h264dsp.c
+++ b/libavcodec/h264dsp.c
@@ -26,8 +26,11 @@
  */
 
 #include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "h264dsp.h"
+#include "h264idct.h"
 #include "libavutil/common.h"
 
 #define BIT_DEPTH 8
@@ -42,11 +45,58 @@
 #include "h264dsp_template.c"
 #undef BIT_DEPTH
 
-void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
+#define BIT_DEPTH 8
+#include "h264addpx_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 16
+#include "h264addpx_template.c"
+#undef BIT_DEPTH
+
+static int h264_find_start_code_candidate_c(const uint8_t *buf, int size)
+{
+    int i = 0;
+#if HAVE_FAST_UNALIGNED
+    /* we check i < size instead of i + 3 / 7 because it is
+     * simpler and there must be FF_INPUT_BUFFER_PADDING_SIZE
+     * bytes at the end.
+     */
+#if HAVE_FAST_64BIT
+    while (i < size &&
+            !((~*(const uint64_t *)(buf + i) &
+                    (*(const uint64_t *)(buf + i) - 0x0101010101010101ULL)) &
+                    0x8080808080808080ULL))
+        i += 8;
+#else
+    while (i < size &&
+            !((~*(const uint32_t *)(buf + i) &
+                    (*(const uint32_t *)(buf + i) - 0x01010101U)) &
+                    0x80808080U))
+        i += 4;
+#endif
+#endif
+    for (; i < size; i++)
+        if (!buf[i])
+            break;
+    return i;
+}
+
+av_cold void ff_h264dsp_init(H264DSPContext *c, const int bit_depth,
+                             const int chroma_format_idc)
 {
 #undef FUNC
 #define FUNC(a, depth) a ## _ ## depth ## _c
 
+#define ADDPX_DSP(depth) \
+    c->h264_add_pixels4_clear = FUNC(ff_h264_add_pixels4, depth);\
+    c->h264_add_pixels8_clear = FUNC(ff_h264_add_pixels8, depth)
+
+    if (bit_depth > 8 && bit_depth <= 16) {
+        ADDPX_DSP(16);
+    } else {
+        ADDPX_DSP(8);
+    }
+
 #define H264_DSP(depth) \
     c->h264_idct_add= FUNC(ff_h264_idct_add, depth);\
     c->h264_idct8_add= FUNC(ff_h264_idct8_add, depth);\
@@ -111,8 +161,9 @@ void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_fo
         H264_DSP(8);
         break;
     }
+    c->h264_find_start_code_candidate = h264_find_start_code_candidate_c;
 
     if (ARCH_ARM) ff_h264dsp_init_arm(c, bit_depth, chroma_format_idc);
-    if (HAVE_ALTIVEC) ff_h264dsp_init_ppc(c, bit_depth, chroma_format_idc);
+    if (ARCH_PPC) ff_h264dsp_init_ppc(c, bit_depth, chroma_format_idc);
     if (ARCH_X86) ff_h264dsp_init_x86(c, bit_depth, chroma_format_idc);
 }
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index 248c7d0..6249ba7 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -29,8 +29,6 @@
 
 #include <stdint.h>
 
-#include "dsputil.h"
-
 typedef void (*h264_weight_func)(uint8_t *block, int stride, int height,
                                  int log2_denom, int weight, int offset);
 typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src,
@@ -80,29 +78,42 @@ typedef struct H264DSPContext {
 
     /* IDCT */
     void (*h264_idct_add)(uint8_t *dst /*align 4*/,
-                          DCTELEM *block /*align 16*/, int stride);
+                          int16_t *block /*align 16*/, int stride);
     void (*h264_idct8_add)(uint8_t *dst /*align 8*/,
-                           DCTELEM *block /*align 16*/, int stride);
+                           int16_t *block /*align 16*/, int stride);
     void (*h264_idct_dc_add)(uint8_t *dst /*align 4*/,
-                             DCTELEM *block /*align 16*/, int stride);
+                             int16_t *block /*align 16*/, int stride);
     void (*h264_idct8_dc_add)(uint8_t *dst /*align 8*/,
-                              DCTELEM *block /*align 16*/, int stride);
+                              int16_t *block /*align 16*/, int stride);
 
     void (*h264_idct_add16)(uint8_t *dst /*align 16*/, const int *blockoffset,
-                            DCTELEM *block /*align 16*/, int stride,
+                            int16_t *block /*align 16*/, int stride,
                             const uint8_t nnzc[15 * 8]);
     void (*h264_idct8_add4)(uint8_t *dst /*align 16*/, const int *blockoffset,
-                            DCTELEM *block /*align 16*/, int stride,
+                            int16_t *block /*align 16*/, int stride,
                             const uint8_t nnzc[15 * 8]);
     void (*h264_idct_add8)(uint8_t **dst /*align 16*/, const int *blockoffset,
-                           DCTELEM *block /*align 16*/, int stride,
+                           int16_t *block /*align 16*/, int stride,
                            const uint8_t nnzc[15 * 8]);
     void (*h264_idct_add16intra)(uint8_t *dst /*align 16*/, const int *blockoffset,
-                                 DCTELEM *block /*align 16*/,
+                                 int16_t *block /*align 16*/,
                                  int stride, const uint8_t nnzc[15 * 8]);
-    void (*h264_luma_dc_dequant_idct)(DCTELEM *output,
-                                      DCTELEM *input /*align 16*/, int qmul);
-    void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul);
+    void (*h264_luma_dc_dequant_idct)(int16_t *output,
+                                      int16_t *input /*align 16*/, int qmul);
+    void (*h264_chroma_dc_dequant_idct)(int16_t *block, int qmul);
+
+    /* bypass-transform */
+    void (*h264_add_pixels8_clear)(uint8_t *dst, int16_t *block, int stride);
+    void (*h264_add_pixels4_clear)(uint8_t *dst, int16_t *block, int stride);
+
+    /**
+     * Search buf from the start for up to size bytes. Return the index
+     * of a zero byte, or >= size if not found. Ideally, use lookahead
+     * to filter out any zero bytes that are known to not be followed by
+     * one or more further zero bytes and a one byte. Better still, filter
+     * out any bytes that form the trailing_zero_8bits syntax element too.
+     */
+    int (*h264_find_start_code_candidate)(const uint8_t *buf, int size);
 } H264DSPContext;
 
 void ff_h264dsp_init(H264DSPContext *c, const int bit_depth,
diff --git a/libavcodec/h264idct.c b/libavcodec/h264idct.c
index 1634a00..ea08d03 100644
--- a/libavcodec/h264idct.c
+++ b/libavcodec/h264idct.c
@@ -25,6 +25,8 @@
  * @author Michael Niedermayer <michaelni at gmx.at>
  */
 
+#include "h264idct.h"
+
 #define BIT_DEPTH 8
 #include "h264idct_template.c"
 #undef BIT_DEPTH
diff --git a/libavcodec/h264idct.h b/libavcodec/h264idct.h
new file mode 100644
index 0000000..816a825
--- /dev/null
+++ b/libavcodec/h264idct.h
@@ -0,0 +1,42 @@
+/*
+ * 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_H264IDCT_H
+#define AVCODEC_H264IDCT_H
+
+#include <stdint.h>
+
+#define H264_IDCT(depth) \
+void ff_h264_idct8_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
+void ff_h264_idct_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
+void ff_h264_idct8_dc_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
+void ff_h264_idct_dc_add_ ## depth ## _c(uint8_t *dst, int16_t *block, int stride);\
+void ff_h264_idct_add16_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct_add16intra_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct8_add4_ ## depth ## _c(uint8_t *dst, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct_add8_422_ ## depth ## _c(uint8_t **dest, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_idct_add8_ ## depth ## _c(uint8_t **dest, const int *blockoffset, int16_t *block, int stride, const uint8_t nnzc[6*8]);\
+void ff_h264_luma_dc_dequant_idct_ ## depth ## _c(int16_t *output, int16_t *input, int qmul);\
+void ff_h264_chroma422_dc_dequant_idct_ ## depth ## _c(int16_t *block, int qmul);\
+void ff_h264_chroma_dc_dequant_idct_ ## depth ## _c(int16_t *block, int qmul);
+
+H264_IDCT( 8)
+H264_IDCT( 9)
+H264_IDCT(10)
+
+#endif /* AVCODEC_H264IDCT_H */
diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c
index 554483c..aadafad 100644
--- a/libavcodec/h264idct_template.c
+++ b/libavcodec/h264idct_template.c
@@ -27,27 +27,9 @@
 
 #include "bit_depth_template.c"
 #include "libavutil/common.h"
+#include "h264.h"
 
-#ifndef AVCODEC_H264IDCT_INTERNAL_H
-#define AVCODEC_H264IDCT_INTERNAL_H
-//FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split
-static const uint8_t scan8[16*3]={
- 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8,
- 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8,
- 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8,
- 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8,
- 4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8,
- 6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8,
- 4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8,
- 6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8,
- 4+11*8, 5+11*8, 4+12*8, 5+12*8,
- 6+11*8, 7+11*8, 6+12*8, 7+12*8,
- 4+13*8, 5+13*8, 4+14*8, 5+14*8,
- 6+13*8, 7+13*8, 6+14*8, 7+14*8
-};
-#endif
-
-void FUNCC(ff_h264_idct_add)(uint8_t *_dst, DCTELEM *_block, int stride)
+void FUNCC(ff_h264_idct_add)(uint8_t *_dst, int16_t *_block, int stride)
 {
     int i;
     pixel *dst = (pixel*)_dst;
@@ -79,9 +61,11 @@ void FUNCC(ff_h264_idct_add)(uint8_t *_dst, DCTELEM *_block, int stride)
         dst[i + 2*stride]= av_clip_pixel(dst[i + 2*stride] + ((z1 - z2) >> 6));
         dst[i + 3*stride]= av_clip_pixel(dst[i + 3*stride] + ((z0 - z3) >> 6));
     }
+
+    memset(block, 0, 16 * sizeof(dctcoef));
 }
 
-void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){
+void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, int16_t *_block, int stride){
     int i;
     pixel *dst = (pixel*)_dst;
     dctcoef *block = (dctcoef*)_block;
@@ -151,14 +135,18 @@ void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){
         dst[i + 6*stride] = av_clip_pixel( dst[i + 6*stride] + ((b2 - b5) >> 6) );
         dst[i + 7*stride] = av_clip_pixel( dst[i + 7*stride] + ((b0 - b7) >> 6) );
     }
+
+    memset(block, 0, 64 * sizeof(dctcoef));
 }
 
 // assumes all AC coefs are 0
-void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){
+void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, int16_t *_block, int stride){
     int i, j;
-    int dc = (((dctcoef*)block)[0] + 32) >> 6;
     pixel *dst = (pixel*)_dst;
+    dctcoef *block = (dctcoef*)_block;
+    int dc = (block[0] + 32) >> 6;
     stride /= sizeof(pixel);
+    block[0] = 0;
     for( j = 0; j < 4; j++ )
     {
         for( i = 0; i < 4; i++ )
@@ -167,10 +155,12 @@ void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){
     }
 }
 
-void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){
+void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, int16_t *_block, int stride){
     int i, j;
-    int dc = (((dctcoef*)block)[0] + 32) >> 6;
     pixel *dst = (pixel*)_dst;
+    dctcoef *block = (dctcoef*)_block;
+    int dc = (block[0] + 32) >> 6;
+    block[0] = 0;
     stride /= sizeof(pixel);
     for( j = 0; j < 8; j++ )
     {
@@ -180,7 +170,7 @@ void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){
     }
 }
 
-void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
     int i;
     for(i=0; i<16; i++){
         int nnz = nnzc[ scan8[i] ];
@@ -191,7 +181,7 @@ void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *b
     }
 }
 
-void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
     int i;
     for(i=0; i<16; i++){
         if(nnzc[ scan8[i] ])             FUNCC(ff_h264_idct_add   )(dst + block_offset[i], block + i*16*sizeof(pixel), stride);
@@ -199,7 +189,7 @@ void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTEL
     }
 }
 
-void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
     int i;
     for(i=0; i<16; i+=4){
         int nnz = nnzc[ scan8[i] ];
@@ -210,7 +200,7 @@ void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *b
     }
 }
 
-void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
     int i, j;
     for(j=1; j<3; j++){
         for(i=j*16; i<j*16+4; i++){
@@ -222,7 +212,7 @@ void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM *
     }
 }
 
-void FUNCC(ff_h264_idct_add8_422)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
+void FUNCC(ff_h264_idct_add8_422)(uint8_t **dest, const int *block_offset, int16_t *block, int stride, const uint8_t nnzc[15*8]){
     int i, j;
 
     for(j=1; j<3; j++){
@@ -248,7 +238,7 @@ void FUNCC(ff_h264_idct_add8_422)(uint8_t **dest, const int *block_offset, DCTEL
  * 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)(int16_t *_output, int16_t *_input, int qmul){
 #define stride 16
     int i;
     int temp[16];
@@ -283,7 +273,7 @@ void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *_output, DCTELEM *_input, int
 #undef stride
 }
 
-void FUNCC(ff_h264_chroma422_dc_dequant_idct)(DCTELEM *_block, int qmul){
+void FUNCC(ff_h264_chroma422_dc_dequant_idct)(int16_t *_block, int qmul){
     const int stride= 16*2;
     const int xStride= 16;
     int i;
@@ -310,7 +300,7 @@ void FUNCC(ff_h264_chroma422_dc_dequant_idct)(DCTELEM *_block, int qmul){
     }
 }
 
-void FUNCC(ff_h264_chroma_dc_dequant_idct)(DCTELEM *_block, int qmul){
+void FUNCC(ff_h264_chroma_dc_dequant_idct)(int16_t *_block, int qmul){
     const int stride= 16*2;
     const int xStride= 16;
     int a,b,c,d,e;
diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c
index 94cf9d0..2c991fd 100644
--- a/libavcodec/h264pred.c
+++ b/libavcodec/h264pred.c
@@ -25,6 +25,8 @@
  * @author Michael Niedermayer <michaelni at gmx.at>
  */
 
+#include "libavutil/attributes.h"
+#include "dsputil.h"
 #include "h264pred.h"
 
 #define BIT_DEPTH 8
@@ -267,12 +269,12 @@ static void pred4x4_horizontal_up_rv40_nodown_c(uint8_t *src,
 static void pred4x4_tm_vp8_c(uint8_t *src, const uint8_t *topright,
                              ptrdiff_t stride)
 {
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride];
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride];
     uint8_t *top = src-stride;
     int y;
 
     for (y = 0; y < 4; y++) {
-        uint8_t *cm_in = cm + src[-1];
+        const uint8_t *cm_in = cm + src[-1];
         src[0] = cm_in[top[0]];
         src[1] = cm_in[top[1]];
         src[2] = cm_in[top[2]];
@@ -293,12 +295,12 @@ static void pred16x16_plane_rv40_c(uint8_t *src, ptrdiff_t stride)
 
 static void pred16x16_tm_vp8_c(uint8_t *src, ptrdiff_t stride)
 {
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride];
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride];
     uint8_t *top = src-stride;
     int y;
 
     for (y = 0; y < 16; y++) {
-        uint8_t *cm_in = cm + src[-1];
+        const uint8_t *cm_in = cm + src[-1];
         src[0]  = cm_in[top[0]];
         src[1]  = cm_in[top[1]];
         src[2]  = cm_in[top[2]];
@@ -375,12 +377,12 @@ static void pred8x8_dc_rv40_c(uint8_t *src, ptrdiff_t stride)
 
 static void pred8x8_tm_vp8_c(uint8_t *src, ptrdiff_t stride)
 {
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride];
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP - src[-1-stride];
     uint8_t *top = src-stride;
     int y;
 
     for (y = 0; y < 8; y++) {
-        uint8_t *cm_in = cm + src[-1];
+        const uint8_t *cm_in = cm + src[-1];
         src[0] = cm_in[top[0]];
         src[1] = cm_in[top[1]];
         src[2] = cm_in[top[2]];
@@ -396,11 +398,10 @@ static void pred8x8_tm_vp8_c(uint8_t *src, ptrdiff_t stride)
 /**
  * Set the intra prediction function pointers.
  */
-void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth,
-                       const int chroma_format_idc)
+av_cold void ff_h264_pred_init(H264PredContext *h, int codec_id,
+                               const int bit_depth,
+                               const int chroma_format_idc)
 {
-//    MpegEncContext * const s = &h->s;
-
 #undef FUNC
 #undef FUNCC
 #define FUNC(a, depth) a ## _ ## depth
diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
index a8b3dba..62e5b79 100644
--- a/libavcodec/h264pred.h
+++ b/libavcodec/h264pred.h
@@ -28,8 +28,8 @@
 #ifndef AVCODEC_H264PRED_H
 #define AVCODEC_H264PRED_H
 
-#include "libavutil/common.h"
-#include "dsputil.h"
+#include <stddef.h>
+#include <stdint.h>
 
 /**
  * Prediction types
@@ -98,15 +98,15 @@ typedef struct H264PredContext {
     void(*pred16x16[4 + 3 + 2])(uint8_t *src, ptrdiff_t stride);
 
     void(*pred4x4_add[2])(uint8_t *pix /*align  4*/,
-                          const DCTELEM *block /*align 16*/, ptrdiff_t stride);
+                          int16_t *block /*align 16*/, ptrdiff_t stride);
     void(*pred8x8l_add[2])(uint8_t *pix /*align  8*/,
-                           const DCTELEM *block /*align 16*/, ptrdiff_t stride);
+                           int16_t *block /*align 16*/, ptrdiff_t stride);
     void(*pred8x8_add[3])(uint8_t *pix /*align  8*/,
                           const int *block_offset,
-                          const DCTELEM *block /*align 16*/, ptrdiff_t stride);
+                          int16_t *block /*align 16*/, ptrdiff_t stride);
     void(*pred16x16_add[3])(uint8_t *pix /*align 16*/,
                             const int *block_offset,
-                            const DCTELEM *block /*align 16*/, ptrdiff_t stride);
+                            int16_t *block /*align 16*/, ptrdiff_t stride);
 } H264PredContext;
 
 void ff_h264_pred_init(H264PredContext *h, int codec_id,
diff --git a/libavcodec/h264pred_template.c b/libavcodec/h264pred_template.c
index 8ae13b0..e15c76c 100644
--- a/libavcodec/h264pred_template.c
+++ b/libavcodec/h264pred_template.c
@@ -1131,7 +1131,7 @@ static void FUNCC(pred8x8l_horizontal_up)(uint8_t *_src, int has_topleft,
 #undef PL
 #undef SRC
 
-static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, const DCTELEM *_block,
+static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, int16_t *_block,
                                         ptrdiff_t stride)
 {
     int i;
@@ -1148,9 +1148,11 @@ static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, const DCTELEM *_block,
         pix++;
         block++;
     }
+
+    memset(_block, 0, sizeof(dctcoef) * 16);
 }
 
-static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, const DCTELEM *_block,
+static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, int16_t *_block,
                                           ptrdiff_t stride)
 {
     int i;
@@ -1166,9 +1168,11 @@ static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, const DCTELEM *_block,
         pix+= stride;
         block+= 4;
     }
+
+    memset(_block, 0, sizeof(dctcoef) * 16);
 }
 
-static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, const DCTELEM *_block,
+static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, int16_t *_block,
                                          ptrdiff_t stride)
 {
     int i;
@@ -1189,9 +1193,11 @@ static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, const DCTELEM *_block,
         pix++;
         block++;
     }
+
+    memset(_block, 0, sizeof(dctcoef) * 64);
 }
 
-static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, const DCTELEM *_block,
+static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, int16_t *_block,
                                            ptrdiff_t stride)
 {
     int i;
@@ -1211,10 +1217,12 @@ static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, const DCTELEM *_block,
         pix+= stride;
         block+= 8;
     }
+
+    memset(_block, 0, sizeof(dctcoef) * 64);
 }
 
 static void FUNCC(pred16x16_vertical_add)(uint8_t *pix, const int *block_offset,
-                                          const DCTELEM *block,
+                                          int16_t *block,
                                           ptrdiff_t stride)
 {
     int i;
@@ -1224,7 +1232,7 @@ static void FUNCC(pred16x16_vertical_add)(uint8_t *pix, const int *block_offset,
 
 static void FUNCC(pred16x16_horizontal_add)(uint8_t *pix,
                                             const int *block_offset,
-                                            const DCTELEM *block,
+                                            int16_t *block,
                                             ptrdiff_t stride)
 {
     int i;
@@ -1233,7 +1241,7 @@ static void FUNCC(pred16x16_horizontal_add)(uint8_t *pix,
 }
 
 static void FUNCC(pred8x8_vertical_add)(uint8_t *pix, const int *block_offset,
-                                        const DCTELEM *block, ptrdiff_t stride)
+                                        int16_t *block, ptrdiff_t stride)
 {
     int i;
     for(i=0; i<4; i++)
@@ -1241,7 +1249,7 @@ static void FUNCC(pred8x8_vertical_add)(uint8_t *pix, const int *block_offset,
 }
 
 static void FUNCC(pred8x16_vertical_add)(uint8_t *pix, const int *block_offset,
-                                         const DCTELEM *block, ptrdiff_t stride)
+                                         int16_t *block, ptrdiff_t stride)
 {
     int i;
     for(i=0; i<4; i++)
@@ -1251,7 +1259,7 @@ static void FUNCC(pred8x16_vertical_add)(uint8_t *pix, const int *block_offset,
 }
 
 static void FUNCC(pred8x8_horizontal_add)(uint8_t *pix, const int *block_offset,
-                                          const DCTELEM *block,
+                                          int16_t *block,
                                           ptrdiff_t stride)
 {
     int i;
@@ -1261,7 +1269,7 @@ static void FUNCC(pred8x8_horizontal_add)(uint8_t *pix, const int *block_offset,
 
 static void FUNCC(pred8x16_horizontal_add)(uint8_t *pix,
                                            const int *block_offset,
-                                           const DCTELEM *block, ptrdiff_t stride)
+                                           int16_t *block, ptrdiff_t stride)
 {
     int i;
     for(i=0; i<4; i++)
diff --git a/libavcodec/h264qpel.c b/libavcodec/h264qpel.c
new file mode 100644
index 0000000..24c9299
--- /dev/null
+++ b/libavcodec/h264qpel.c
@@ -0,0 +1,87 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003-2010 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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/attributes.h"
+#include "h264qpel.h"
+
+#define BIT_DEPTH 8
+#include "h264qpel_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 9
+#include "h264qpel_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 10
+#include "h264qpel_template.c"
+#undef BIT_DEPTH
+
+av_cold void ff_h264qpel_init(H264QpelContext *c, int bit_depth)
+{
+#undef FUNCC
+#define FUNCC(f, depth) f ## _ ## depth ## _c
+
+#define dspfunc2(PFX, IDX, NUM, depth)                                  \
+    c->PFX ## _pixels_tab[IDX][ 0] = FUNCC(PFX ## NUM ## _mc00, depth); \
+    c->PFX ## _pixels_tab[IDX][ 1] = FUNCC(PFX ## NUM ## _mc10, depth); \
+    c->PFX ## _pixels_tab[IDX][ 2] = FUNCC(PFX ## NUM ## _mc20, depth); \
+    c->PFX ## _pixels_tab[IDX][ 3] = FUNCC(PFX ## NUM ## _mc30, depth); \
+    c->PFX ## _pixels_tab[IDX][ 4] = FUNCC(PFX ## NUM ## _mc01, depth); \
+    c->PFX ## _pixels_tab[IDX][ 5] = FUNCC(PFX ## NUM ## _mc11, depth); \
+    c->PFX ## _pixels_tab[IDX][ 6] = FUNCC(PFX ## NUM ## _mc21, depth); \
+    c->PFX ## _pixels_tab[IDX][ 7] = FUNCC(PFX ## NUM ## _mc31, depth); \
+    c->PFX ## _pixels_tab[IDX][ 8] = FUNCC(PFX ## NUM ## _mc02, depth); \
+    c->PFX ## _pixels_tab[IDX][ 9] = FUNCC(PFX ## NUM ## _mc12, depth); \
+    c->PFX ## _pixels_tab[IDX][10] = FUNCC(PFX ## NUM ## _mc22, depth); \
+    c->PFX ## _pixels_tab[IDX][11] = FUNCC(PFX ## NUM ## _mc32, depth); \
+    c->PFX ## _pixels_tab[IDX][12] = FUNCC(PFX ## NUM ## _mc03, depth); \
+    c->PFX ## _pixels_tab[IDX][13] = FUNCC(PFX ## NUM ## _mc13, depth); \
+    c->PFX ## _pixels_tab[IDX][14] = FUNCC(PFX ## NUM ## _mc23, depth); \
+    c->PFX ## _pixels_tab[IDX][15] = FUNCC(PFX ## NUM ## _mc33, depth)
+
+#define SET_QPEL(depth)                         \
+    dspfunc2(put_h264_qpel, 0, 16, depth);      \
+    dspfunc2(put_h264_qpel, 1,  8, depth);      \
+    dspfunc2(put_h264_qpel, 2,  4, depth);      \
+    dspfunc2(put_h264_qpel, 3,  2, depth);      \
+    dspfunc2(avg_h264_qpel, 0, 16, depth);      \
+    dspfunc2(avg_h264_qpel, 1,  8, depth);      \
+    dspfunc2(avg_h264_qpel, 2,  4, depth)
+
+    switch (bit_depth) {
+    default:
+        SET_QPEL(8);
+        break;
+    case 9:
+        SET_QPEL(9);
+        break;
+    case 10:
+        SET_QPEL(10);
+        break;
+    }
+
+    if (ARCH_ARM)
+        ff_h264qpel_init_arm(c, bit_depth);
+    if (ARCH_PPC)
+        ff_h264qpel_init_ppc(c, bit_depth);
+    if (ARCH_X86)
+        ff_h264qpel_init_x86(c, bit_depth);
+}
diff --git a/libavcodec/h264qpel.h b/libavcodec/h264qpel.h
new file mode 100644
index 0000000..d761775
--- /dev/null
+++ b/libavcodec/h264qpel.h
@@ -0,0 +1,38 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003-2010 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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_H264QPEL_H
+#define AVCODEC_H264QPEL_H
+
+#include "dsputil.h"
+
+typedef struct H264QpelContext {
+    qpel_mc_func put_h264_qpel_pixels_tab[4][16];
+    qpel_mc_func avg_h264_qpel_pixels_tab[4][16];
+} H264QpelContext;
+
+void ff_h264qpel_init(H264QpelContext *c, int bit_depth);
+
+void ff_h264qpel_init_arm(H264QpelContext *c, int bit_depth);
+void ff_h264qpel_init_ppc(H264QpelContext *c, int bit_depth);
+void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth);
+
+#endif /* AVCODEC_H264QPEL_H */
diff --git a/libavcodec/h264qpel_template.c b/libavcodec/h264qpel_template.c
new file mode 100644
index 0000000..027edf5
--- /dev/null
+++ b/libavcodec/h264qpel_template.c
@@ -0,0 +1,549 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
+ * Copyright (c) 2003-2010 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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/common.h"
+#include "bit_depth_template.c"
+#include "hpel_template.c"
+
+static inline void FUNC(copy_block2)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_WN2P(dst   , AV_RN2P(src   ));
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void FUNC(copy_block4)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_WN4P(dst   , AV_RN4P(src   ));
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void FUNC(copy_block8)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_WN4P(dst                , AV_RN4P(src                ));
+        AV_WN4P(dst+4*sizeof(pixel), AV_RN4P(src+4*sizeof(pixel)));
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+static inline void FUNC(copy_block16)(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h)
+{
+    int i;
+    for(i=0; i<h; i++)
+    {
+        AV_WN4P(dst                 , AV_RN4P(src                 ));
+        AV_WN4P(dst+ 4*sizeof(pixel), AV_RN4P(src+ 4*sizeof(pixel)));
+        AV_WN4P(dst+ 8*sizeof(pixel), AV_RN4P(src+ 8*sizeof(pixel)));
+        AV_WN4P(dst+12*sizeof(pixel), AV_RN4P(src+12*sizeof(pixel)));
+        dst+=dstStride;
+        src+=srcStride;
+    }
+}
+
+#define H264_LOWPASS(OPNAME, OP, OP2) \
+static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *_dst, uint8_t *_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);\
+    for(i=0; i<h; i++)\
+    {\
+        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
+        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
+        dst+=dstStride;\
+        src+=srcStride;\
+    }\
+}\
+\
+static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *_dst, uint8_t *_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);\
+    for(i=0; i<w; i++)\
+    {\
+        const int srcB= src[-2*srcStride];\
+        const int srcA= src[-1*srcStride];\
+        const int src0= src[0 *srcStride];\
+        const int src1= src[1 *srcStride];\
+        const int src2= src[2 *srcStride];\
+        const int src3= src[3 *srcStride];\
+        const int src4= src[4 *srcStride];\
+        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
+        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
+        dst++;\
+        src++;\
+    }\
+}\
+\
+static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_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;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)_dst;\
+    pixel *src = (pixel*)_src;\
+    dstStride /= sizeof(pixel);\
+    srcStride /= sizeof(pixel);\
+    src -= 2*srcStride;\
+    for(i=0; i<h+5; i++)\
+    {\
+        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\
+        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\
+        tmp+=tmpStride;\
+        src+=srcStride;\
+    }\
+    tmp -= tmpStride*(h+5-2);\
+    for(i=0; i<w; i++)\
+    {\
+        const int tmpB= tmp[-2*tmpStride] - pad;\
+        const int tmpA= tmp[-1*tmpStride] - pad;\
+        const int tmp0= tmp[0 *tmpStride] - pad;\
+        const int tmp1= tmp[1 *tmpStride] - pad;\
+        const int tmp2= tmp[2 *tmpStride] - pad;\
+        const int tmp3= tmp[3 *tmpStride] - pad;\
+        const int tmp4= tmp[4 *tmpStride] - pad;\
+        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
+        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
+        dst++;\
+        tmp++;\
+    }\
+}\
+static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *_dst, uint8_t *_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);\
+    for(i=0; i<h; i++)\
+    {\
+        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
+        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
+        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]));\
+        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]));\
+        dst+=dstStride;\
+        src+=srcStride;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *_dst, uint8_t *_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);\
+    for(i=0; i<w; i++)\
+    {\
+        const int srcB= src[-2*srcStride];\
+        const int srcA= src[-1*srcStride];\
+        const int src0= src[0 *srcStride];\
+        const int src1= src[1 *srcStride];\
+        const int src2= src[2 *srcStride];\
+        const int src3= src[3 *srcStride];\
+        const int src4= src[4 *srcStride];\
+        const int src5= src[5 *srcStride];\
+        const int src6= src[6 *srcStride];\
+        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
+        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
+        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
+        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
+        dst++;\
+        src++;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_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;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)_dst;\
+    pixel *src = (pixel*)_src;\
+    dstStride /= sizeof(pixel);\
+    srcStride /= sizeof(pixel);\
+    src -= 2*srcStride;\
+    for(i=0; i<h+5; i++)\
+    {\
+        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]) + pad;\
+        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]) + pad;\
+        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]) + pad;\
+        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]) + pad;\
+        tmp+=tmpStride;\
+        src+=srcStride;\
+    }\
+    tmp -= tmpStride*(h+5-2);\
+    for(i=0; i<w; i++)\
+    {\
+        const int tmpB= tmp[-2*tmpStride] - pad;\
+        const int tmpA= tmp[-1*tmpStride] - pad;\
+        const int tmp0= tmp[0 *tmpStride] - pad;\
+        const int tmp1= tmp[1 *tmpStride] - pad;\
+        const int tmp2= tmp[2 *tmpStride] - pad;\
+        const int tmp3= tmp[3 *tmpStride] - pad;\
+        const int tmp4= tmp[4 *tmpStride] - pad;\
+        const int tmp5= tmp[5 *tmpStride] - pad;\
+        const int tmp6= tmp[6 *tmpStride] - pad;\
+        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
+        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
+        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\
+        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\
+        dst++;\
+        tmp++;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *_dst, uint8_t *_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);\
+    for(i=0; i<h; i++)\
+    {\
+        OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]));\
+        OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]));\
+        OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]));\
+        OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]));\
+        OP(dst[4], (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]));\
+        OP(dst[5], (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]));\
+        OP(dst[6], (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]));\
+        OP(dst[7], (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]));\
+        dst+=dstStride;\
+        src+=srcStride;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *_dst, uint8_t *_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);\
+    for(i=0; i<w; i++)\
+    {\
+        const int srcB= src[-2*srcStride];\
+        const int srcA= src[-1*srcStride];\
+        const int src0= src[0 *srcStride];\
+        const int src1= src[1 *srcStride];\
+        const int src2= src[2 *srcStride];\
+        const int src3= src[3 *srcStride];\
+        const int src4= src[4 *srcStride];\
+        const int src5= src[5 *srcStride];\
+        const int src6= src[6 *srcStride];\
+        const int src7= src[7 *srcStride];\
+        const int src8= src[8 *srcStride];\
+        const int src9= src[9 *srcStride];\
+        const int src10=src[10*srcStride];\
+        OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
+        OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
+        OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
+        OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
+        OP(dst[4*dstStride], (src4+src5)*20 - (src3+src6)*5 + (src2+src7));\
+        OP(dst[5*dstStride], (src5+src6)*20 - (src4+src7)*5 + (src3+src8));\
+        OP(dst[6*dstStride], (src6+src7)*20 - (src5+src8)*5 + (src4+src9));\
+        OP(dst[7*dstStride], (src7+src8)*20 - (src6+src9)*5 + (src5+src10));\
+        dst++;\
+        src++;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel8_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_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;\
+    INIT_CLIP\
+    int i;\
+    pixel *dst = (pixel*)_dst;\
+    pixel *src = (pixel*)_src;\
+    dstStride /= sizeof(pixel);\
+    srcStride /= sizeof(pixel);\
+    src -= 2*srcStride;\
+    for(i=0; i<h+5; i++)\
+    {\
+        tmp[0]= (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3 ]) + pad;\
+        tmp[1]= (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4 ]) + pad;\
+        tmp[2]= (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5 ]) + pad;\
+        tmp[3]= (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6 ]) + pad;\
+        tmp[4]= (src[4]+src[5])*20 - (src[3 ]+src[6])*5 + (src[2 ]+src[7 ]) + pad;\
+        tmp[5]= (src[5]+src[6])*20 - (src[4 ]+src[7])*5 + (src[3 ]+src[8 ]) + pad;\
+        tmp[6]= (src[6]+src[7])*20 - (src[5 ]+src[8])*5 + (src[4 ]+src[9 ]) + pad;\
+        tmp[7]= (src[7]+src[8])*20 - (src[6 ]+src[9])*5 + (src[5 ]+src[10]) + pad;\
+        tmp+=tmpStride;\
+        src+=srcStride;\
+    }\
+    tmp -= tmpStride*(h+5-2);\
+    for(i=0; i<w; i++)\
+    {\
+        const int tmpB= tmp[-2*tmpStride] - pad;\
+        const int tmpA= tmp[-1*tmpStride] - pad;\
+        const int tmp0= tmp[0 *tmpStride] - pad;\
+        const int tmp1= tmp[1 *tmpStride] - pad;\
+        const int tmp2= tmp[2 *tmpStride] - pad;\
+        const int tmp3= tmp[3 *tmpStride] - pad;\
+        const int tmp4= tmp[4 *tmpStride] - pad;\
+        const int tmp5= tmp[5 *tmpStride] - pad;\
+        const int tmp6= tmp[6 *tmpStride] - pad;\
+        const int tmp7= tmp[7 *tmpStride] - pad;\
+        const int tmp8= tmp[8 *tmpStride] - pad;\
+        const int tmp9= tmp[9 *tmpStride] - pad;\
+        const int tmp10=tmp[10*tmpStride] - pad;\
+        OP2(dst[0*dstStride], (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));\
+        OP2(dst[1*dstStride], (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));\
+        OP2(dst[2*dstStride], (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));\
+        OP2(dst[3*dstStride], (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));\
+        OP2(dst[4*dstStride], (tmp4+tmp5)*20 - (tmp3+tmp6)*5 + (tmp2+tmp7));\
+        OP2(dst[5*dstStride], (tmp5+tmp6)*20 - (tmp4+tmp7)*5 + (tmp3+tmp8));\
+        OP2(dst[6*dstStride], (tmp6+tmp7)*20 - (tmp5+tmp8)*5 + (tmp4+tmp9));\
+        OP2(dst[7*dstStride], (tmp7+tmp8)*20 - (tmp6+tmp9)*5 + (tmp5+tmp10));\
+        dst++;\
+        tmp++;\
+    }\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel16_v_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
+    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
+    src += 8*srcStride;\
+    dst += 8*dstStride;\
+    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst                , src                , dstStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_v_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel16_h_lowpass)(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
+    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
+    src += 8*srcStride;\
+    dst += 8*dstStride;\
+    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst                , src                , dstStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_h_lowpass)(dst+8*sizeof(pixel), src+8*sizeof(pixel), dstStride, srcStride);\
+}\
+\
+static void FUNC(OPNAME ## h264_qpel16_hv_lowpass)(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
+    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\
+    src += 8*srcStride;\
+    dst += 8*dstStride;\
+    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst                , tmp  , src                , dstStride, tmpStride, srcStride);\
+    FUNC(OPNAME ## h264_qpel8_hv_lowpass)(dst+8*sizeof(pixel), tmp+8, src+8*sizeof(pixel), dstStride, tmpStride, srcStride);\
+}\
+
+#define H264_MC(OPNAME, SIZE) \
+static av_unused void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc00)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    FUNCC(OPNAME ## pixels ## SIZE)(dst, src, stride, SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc10)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src, half, stride, stride, SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc20)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    FUNC(OPNAME ## h264_qpel ## SIZE ## _h_lowpass)(dst, src, stride, stride);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc30)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(half, src, SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, src+sizeof(pixel), half, stride, stride, SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc01)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid, half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc02)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(OPNAME ## h264_qpel ## SIZE ## _v_lowpass)(dst, full_mid, stride, SIZE*sizeof(pixel));\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc03)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t half[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(half, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, full_mid+SIZE*sizeof(pixel), half, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc11)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc31)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc13)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc33)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    uint8_t full[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t * const full_mid= full + SIZE*2*sizeof(pixel);\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
+    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc22)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    int16_t 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, ptrdiff_t stride)\
+{\
+    int16_t tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src, SIZE*sizeof(pixel), stride);\
+    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc23)(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    int16_t tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    uint8_t halfH[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(put_h264_qpel ## SIZE ## _h_lowpass)(halfH, src + stride, SIZE*sizeof(pixel), stride);\
+    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfH, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc12)(uint8_t *dst, uint8_t *src, ptrdiff_t 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)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(copy_block ## SIZE )(full, src - stride*2, SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+\
+static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc32)(uint8_t *dst, uint8_t *src, ptrdiff_t 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)];\
+    uint8_t halfV[SIZE*SIZE*sizeof(pixel)];\
+    uint8_t halfHV[SIZE*SIZE*sizeof(pixel)];\
+    FUNC(copy_block ## SIZE )(full, src - stride*2 + sizeof(pixel), SIZE*sizeof(pixel),  stride, SIZE + 5);\
+    FUNC(put_h264_qpel ## SIZE ## _v_lowpass)(halfV, full_mid, SIZE*sizeof(pixel), SIZE*sizeof(pixel));\
+    FUNC(put_h264_qpel ## SIZE ## _hv_lowpass)(halfHV, tmp, src, SIZE*sizeof(pixel), SIZE*sizeof(pixel), stride);\
+    FUNC(OPNAME ## pixels ## SIZE ## _l2)(dst, halfV, halfHV, stride, SIZE*sizeof(pixel), SIZE*sizeof(pixel), SIZE);\
+}\
+
+#define op_avg(a, b)  a = (((a)+CLIP(((b) + 16)>>5)+1)>>1)
+//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7)
+#define op_put(a, b)  a = CLIP(((b) + 16)>>5)
+#define op2_avg(a, b)  a = (((a)+CLIP(((b) + 512)>>10)+1)>>1)
+#define op2_put(a, b)  a = CLIP(((b) + 512)>>10)
+
+H264_LOWPASS(put_       , op_put, op2_put)
+H264_LOWPASS(avg_       , op_avg, op2_avg)
+H264_MC(put_, 2)
+H264_MC(put_, 4)
+H264_MC(put_, 8)
+H264_MC(put_, 16)
+H264_MC(avg_, 4)
+H264_MC(avg_, 8)
+H264_MC(avg_, 16)
+
+#undef op_avg
+#undef op_put
+#undef op2_avg
+#undef op2_put
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
new file mode 100644
index 0000000..4af5aee
--- /dev/null
+++ b/libavcodec/hevc.c
@@ -0,0 +1,3201 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Mickael Raulet
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2012 - 2013 Wassim Hamidouche
+ *
+ * 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/attributes.h"
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+#include "libavutil/md5.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/stereo3d.h"
+
+#include "bytestream.h"
+#include "cabac_functions.h"
+#include "dsputil.h"
+#include "golomb.h"
+#include "hevc.h"
+
+const uint8_t ff_hevc_qpel_extra_before[4] = { 0, 3, 3, 2 };
+const uint8_t ff_hevc_qpel_extra_after[4]  = { 0, 3, 4, 4 };
+const uint8_t ff_hevc_qpel_extra[4]        = { 0, 6, 7, 6 };
+
+static const uint8_t scan_1x1[1] = { 0 };
+
+static const uint8_t horiz_scan2x2_x[4] = { 0, 1, 0, 1 };
+
+static const uint8_t horiz_scan2x2_y[4] = { 0, 0, 1, 1 };
+
+static const uint8_t horiz_scan4x4_x[16] = {
+    0, 1, 2, 3,
+    0, 1, 2, 3,
+    0, 1, 2, 3,
+    0, 1, 2, 3,
+};
+
+static const uint8_t horiz_scan4x4_y[16] = {
+    0, 0, 0, 0,
+    1, 1, 1, 1,
+    2, 2, 2, 2,
+    3, 3, 3, 3,
+};
+
+static const uint8_t horiz_scan8x8_inv[8][8] = {
+    {  0,  1,  2,  3, 16, 17, 18, 19, },
+    {  4,  5,  6,  7, 20, 21, 22, 23, },
+    {  8,  9, 10, 11, 24, 25, 26, 27, },
+    { 12, 13, 14, 15, 28, 29, 30, 31, },
+    { 32, 33, 34, 35, 48, 49, 50, 51, },
+    { 36, 37, 38, 39, 52, 53, 54, 55, },
+    { 40, 41, 42, 43, 56, 57, 58, 59, },
+    { 44, 45, 46, 47, 60, 61, 62, 63, },
+};
+
+static const uint8_t diag_scan2x2_x[4] = { 0, 0, 1, 1 };
+
+static const uint8_t diag_scan2x2_y[4] = { 0, 1, 0, 1 };
+
+static const uint8_t diag_scan2x2_inv[2][2] = {
+    { 0, 2, },
+    { 1, 3, },
+};
+
+const uint8_t ff_hevc_diag_scan4x4_x[16] = {
+    0, 0, 1, 0,
+    1, 2, 0, 1,
+    2, 3, 1, 2,
+    3, 2, 3, 3,
+};
+
+const uint8_t ff_hevc_diag_scan4x4_y[16] = {
+    0, 1, 0, 2,
+    1, 0, 3, 2,
+    1, 0, 3, 2,
+    1, 3, 2, 3,
+};
+
+static const uint8_t diag_scan4x4_inv[4][4] = {
+    { 0,  2,  5,  9, },
+    { 1,  4,  8, 12, },
+    { 3,  7, 11, 14, },
+    { 6, 10, 13, 15, },
+};
+
+const uint8_t ff_hevc_diag_scan8x8_x[64] = {
+    0, 0, 1, 0,
+    1, 2, 0, 1,
+    2, 3, 0, 1,
+    2, 3, 4, 0,
+    1, 2, 3, 4,
+    5, 0, 1, 2,
+    3, 4, 5, 6,
+    0, 1, 2, 3,
+    4, 5, 6, 7,
+    1, 2, 3, 4,
+    5, 6, 7, 2,
+    3, 4, 5, 6,
+    7, 3, 4, 5,
+    6, 7, 4, 5,
+    6, 7, 5, 6,
+    7, 6, 7, 7,
+};
+
+const uint8_t ff_hevc_diag_scan8x8_y[64] = {
+    0, 1, 0, 2,
+    1, 0, 3, 2,
+    1, 0, 4, 3,
+    2, 1, 0, 5,
+    4, 3, 2, 1,
+    0, 6, 5, 4,
+    3, 2, 1, 0,
+    7, 6, 5, 4,
+    3, 2, 1, 0,
+    7, 6, 5, 4,
+    3, 2, 1, 7,
+    6, 5, 4, 3,
+    2, 7, 6, 5,
+    4, 3, 7, 6,
+    5, 4, 7, 6,
+    5, 7, 6, 7,
+};
+
+static const uint8_t diag_scan8x8_inv[8][8] = {
+    {  0,  2,  5,  9, 14, 20, 27, 35, },
+    {  1,  4,  8, 13, 19, 26, 34, 42, },
+    {  3,  7, 12, 18, 25, 33, 41, 48, },
+    {  6, 11, 17, 24, 32, 40, 47, 53, },
+    { 10, 16, 23, 31, 39, 46, 52, 57, },
+    { 15, 22, 30, 38, 45, 51, 56, 60, },
+    { 21, 29, 37, 44, 50, 55, 59, 62, },
+    { 28, 36, 43, 49, 54, 58, 61, 63, },
+};
+
+/**
+ * NOTE: Each function hls_foo correspond to the function foo in the
+ * specification (HLS stands for High Level Syntax).
+ */
+
+/**
+ * Section 5.7
+ */
+
+/* free everything allocated  by pic_arrays_init() */
+static void pic_arrays_free(HEVCContext *s)
+{
+    av_freep(&s->sao);
+    av_freep(&s->deblock);
+    av_freep(&s->split_cu_flag);
+
+    av_freep(&s->skip_flag);
+    av_freep(&s->tab_ct_depth);
+
+    av_freep(&s->tab_ipm);
+    av_freep(&s->cbf_luma);
+    av_freep(&s->is_pcm);
+
+    av_freep(&s->qp_y_tab);
+    av_freep(&s->tab_slice_address);
+    av_freep(&s->filter_slice_edges);
+
+    av_freep(&s->horizontal_bs);
+    av_freep(&s->vertical_bs);
+
+    av_buffer_pool_uninit(&s->tab_mvf_pool);
+    av_buffer_pool_uninit(&s->rpl_tab_pool);
+}
+
+/* allocate arrays that depend on frame dimensions */
+static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps)
+{
+    int log2_min_cb_size = sps->log2_min_cb_size;
+    int width            = sps->width;
+    int height           = sps->height;
+    int pic_size         = width * height;
+    int pic_size_in_ctb  = ((width  >> log2_min_cb_size) + 1) *
+                           ((height >> log2_min_cb_size) + 1);
+    int ctb_count        = sps->ctb_width * sps->ctb_height;
+    int min_pu_size      = sps->min_pu_width * sps->min_pu_height;
+
+    s->bs_width  = width  >> 3;
+    s->bs_height = height >> 3;
+
+    s->sao           = av_mallocz_array(ctb_count, sizeof(*s->sao));
+    s->deblock       = av_mallocz_array(ctb_count, sizeof(*s->deblock));
+    s->split_cu_flag = av_malloc(pic_size);
+    if (!s->sao || !s->deblock || !s->split_cu_flag)
+        goto fail;
+
+    s->skip_flag    = av_malloc(pic_size_in_ctb);
+    s->tab_ct_depth = av_malloc(sps->min_cb_height * sps->min_cb_width);
+    if (!s->skip_flag || !s->tab_ct_depth)
+        goto fail;
+
+    s->cbf_luma = av_malloc(sps->min_tb_width * sps->min_tb_height);
+    s->tab_ipm  = av_malloc(min_pu_size);
+    s->is_pcm   = av_malloc(min_pu_size);
+    if (!s->tab_ipm || !s->cbf_luma || !s->is_pcm)
+        goto fail;
+
+    s->filter_slice_edges = av_malloc(ctb_count);
+    s->tab_slice_address  = av_malloc(pic_size_in_ctb *
+                                      sizeof(*s->tab_slice_address));
+    s->qp_y_tab           = av_malloc(pic_size_in_ctb *
+                                      sizeof(*s->qp_y_tab));
+    if (!s->qp_y_tab || !s->filter_slice_edges || !s->tab_slice_address)
+        goto fail;
+
+    s->horizontal_bs = av_mallocz(2 * s->bs_width * (s->bs_height + 1));
+    s->vertical_bs   = av_mallocz(2 * s->bs_width * (s->bs_height + 1));
+    if (!s->horizontal_bs || !s->vertical_bs)
+        goto fail;
+
+    s->tab_mvf_pool = av_buffer_pool_init(min_pu_size * sizeof(MvField),
+                                          av_buffer_alloc);
+    s->rpl_tab_pool = av_buffer_pool_init(ctb_count * sizeof(RefPicListTab),
+                                          av_buffer_allocz);
+    if (!s->tab_mvf_pool || !s->rpl_tab_pool)
+        goto fail;
+
+    return 0;
+
+fail:
+    pic_arrays_free(s);
+    return AVERROR(ENOMEM);
+}
+
+static void pred_weight_table(HEVCContext *s, GetBitContext *gb)
+{
+    int i = 0;
+    int j = 0;
+    uint8_t luma_weight_l0_flag[16];
+    uint8_t chroma_weight_l0_flag[16];
+    uint8_t luma_weight_l1_flag[16];
+    uint8_t chroma_weight_l1_flag[16];
+
+    s->sh.luma_log2_weight_denom = get_ue_golomb_long(gb);
+    if (s->sps->chroma_format_idc != 0) {
+        int delta = get_se_golomb(gb);
+        s->sh.chroma_log2_weight_denom = av_clip_c(s->sh.luma_log2_weight_denom + delta, 0, 7);
+    }
+
+    for (i = 0; i < s->sh.nb_refs[L0]; i++) {
+        luma_weight_l0_flag[i] = get_bits1(gb);
+        if (!luma_weight_l0_flag[i]) {
+            s->sh.luma_weight_l0[i] = 1 << s->sh.luma_log2_weight_denom;
+            s->sh.luma_offset_l0[i] = 0;
+        }
+    }
+    if (s->sps->chroma_format_idc != 0) { // FIXME: invert "if" and "for"
+        for (i = 0; i < s->sh.nb_refs[L0]; i++)
+            chroma_weight_l0_flag[i] = get_bits1(gb);
+    } else {
+        for (i = 0; i < s->sh.nb_refs[L0]; i++)
+            chroma_weight_l0_flag[i] = 0;
+    }
+    for (i = 0; i < s->sh.nb_refs[L0]; i++) {
+        if (luma_weight_l0_flag[i]) {
+            int delta_luma_weight_l0 = get_se_golomb(gb);
+            s->sh.luma_weight_l0[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l0;
+            s->sh.luma_offset_l0[i] = get_se_golomb(gb);
+        }
+        if (chroma_weight_l0_flag[i]) {
+            for (j = 0; j < 2; j++) {
+                int delta_chroma_weight_l0 = get_se_golomb(gb);
+                int delta_chroma_offset_l0 = get_se_golomb(gb);
+                s->sh.chroma_weight_l0[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l0;
+                s->sh.chroma_offset_l0[i][j] = av_clip_c((delta_chroma_offset_l0 - ((128 * s->sh.chroma_weight_l0[i][j])
+                                                                                    >> s->sh.chroma_log2_weight_denom) + 128), -128, 127);
+            }
+        } else {
+            s->sh.chroma_weight_l0[i][0] = 1 << s->sh.chroma_log2_weight_denom;
+            s->sh.chroma_offset_l0[i][0] = 0;
+            s->sh.chroma_weight_l0[i][1] = 1 << s->sh.chroma_log2_weight_denom;
+            s->sh.chroma_offset_l0[i][1] = 0;
+        }
+    }
+    if (s->sh.slice_type == B_SLICE) {
+        for (i = 0; i < s->sh.nb_refs[L1]; i++) {
+            luma_weight_l1_flag[i] = get_bits1(gb);
+            if (!luma_weight_l1_flag[i]) {
+                s->sh.luma_weight_l1[i] = 1 << s->sh.luma_log2_weight_denom;
+                s->sh.luma_offset_l1[i] = 0;
+            }
+        }
+        if (s->sps->chroma_format_idc != 0) {
+            for (i = 0; i < s->sh.nb_refs[L1]; i++)
+                chroma_weight_l1_flag[i] = get_bits1(gb);
+        } else {
+            for (i = 0; i < s->sh.nb_refs[L1]; i++)
+                chroma_weight_l1_flag[i] = 0;
+        }
+        for (i = 0; i < s->sh.nb_refs[L1]; i++) {
+            if (luma_weight_l1_flag[i]) {
+                int delta_luma_weight_l1 = get_se_golomb(gb);
+                s->sh.luma_weight_l1[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l1;
+                s->sh.luma_offset_l1[i] = get_se_golomb(gb);
+            }
+            if (chroma_weight_l1_flag[i]) {
+                for (j = 0; j < 2; j++) {
+                    int delta_chroma_weight_l1 = get_se_golomb(gb);
+                    int delta_chroma_offset_l1 = get_se_golomb(gb);
+                    s->sh.chroma_weight_l1[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l1;
+                    s->sh.chroma_offset_l1[i][j] = av_clip_c((delta_chroma_offset_l1 - ((128 * s->sh.chroma_weight_l1[i][j])
+                                                                                        >> s->sh.chroma_log2_weight_denom) + 128), -128, 127);
+                }
+            } else {
+                s->sh.chroma_weight_l1[i][0] = 1 << s->sh.chroma_log2_weight_denom;
+                s->sh.chroma_offset_l1[i][0] = 0;
+                s->sh.chroma_weight_l1[i][1] = 1 << s->sh.chroma_log2_weight_denom;
+                s->sh.chroma_offset_l1[i][1] = 0;
+            }
+        }
+    }
+}
+
+static int decode_lt_rps(HEVCContext *s, LongTermRPS *rps, GetBitContext *gb)
+{
+    const HEVCSPS *sps = s->sps;
+    int max_poc_lsb    = 1 << sps->log2_max_poc_lsb;
+    int prev_delta_msb = 0;
+    int nb_sps = 0, nb_sh;
+    int i;
+
+    rps->nb_refs = 0;
+    if (!sps->long_term_ref_pics_present_flag)
+        return 0;
+
+    if (sps->num_long_term_ref_pics_sps > 0)
+        nb_sps = get_ue_golomb_long(gb);
+    nb_sh = get_ue_golomb_long(gb);
+
+    if (nb_sh + nb_sps > FF_ARRAY_ELEMS(rps->poc))
+        return AVERROR_INVALIDDATA;
+
+    rps->nb_refs = nb_sh + nb_sps;
+
+    for (i = 0; i < rps->nb_refs; i++) {
+        uint8_t delta_poc_msb_present;
+
+        if (i < nb_sps) {
+            uint8_t lt_idx_sps = 0;
+
+            if (sps->num_long_term_ref_pics_sps > 1)
+                lt_idx_sps = get_bits(gb, av_ceil_log2(sps->num_long_term_ref_pics_sps));
+
+            rps->poc[i]  = sps->lt_ref_pic_poc_lsb_sps[lt_idx_sps];
+            rps->used[i] = sps->used_by_curr_pic_lt_sps_flag[lt_idx_sps];
+        } else {
+            rps->poc[i]  = get_bits(gb, sps->log2_max_poc_lsb);
+            rps->used[i] = get_bits1(gb);
+        }
+
+        delta_poc_msb_present = get_bits1(gb);
+        if (delta_poc_msb_present) {
+            int delta = get_ue_golomb_long(gb);
+
+            if (i && i != nb_sps)
+                delta += prev_delta_msb;
+
+            rps->poc[i] += s->poc - delta * max_poc_lsb - s->sh.pic_order_cnt_lsb;
+            prev_delta_msb = delta;
+        }
+    }
+
+    return 0;
+}
+
+static int set_sps(HEVCContext *s, const HEVCSPS *sps)
+{
+    int ret;
+    int num = 0, den = 0;
+
+    pic_arrays_free(s);
+    ret = pic_arrays_init(s, sps);
+    if (ret < 0)
+        goto fail;
+
+    s->avctx->coded_width         = sps->width;
+    s->avctx->coded_height        = sps->height;
+    s->avctx->width               = sps->output_width;
+    s->avctx->height              = sps->output_height;
+    s->avctx->pix_fmt             = sps->pix_fmt;
+    s->avctx->sample_aspect_ratio = sps->vui.sar;
+    s->avctx->has_b_frames        = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics;
+
+    if (sps->vui.video_signal_type_present_flag)
+        s->avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG
+                                                               : AVCOL_RANGE_MPEG;
+    else
+        s->avctx->color_range = AVCOL_RANGE_MPEG;
+
+    if (sps->vui.colour_description_present_flag) {
+        s->avctx->color_primaries = sps->vui.colour_primaries;
+        s->avctx->color_trc       = sps->vui.transfer_characteristic;
+        s->avctx->colorspace      = sps->vui.matrix_coeffs;
+    } else {
+        s->avctx->color_primaries = AVCOL_PRI_UNSPECIFIED;
+        s->avctx->color_trc       = AVCOL_TRC_UNSPECIFIED;
+        s->avctx->colorspace      = AVCOL_SPC_UNSPECIFIED;
+    }
+
+    ff_hevc_pred_init(&s->hpc,     sps->bit_depth);
+    ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth);
+    ff_videodsp_init (&s->vdsp,    sps->bit_depth);
+
+    if (sps->sao_enabled) {
+        av_frame_unref(s->tmp_frame);
+        ret = ff_get_buffer(s->avctx, s->tmp_frame, AV_GET_BUFFER_FLAG_REF);
+        if (ret < 0)
+            goto fail;
+        s->frame = s->tmp_frame;
+    }
+
+    s->sps = sps;
+    s->vps = (HEVCVPS*) s->vps_list[s->sps->vps_id]->data;
+
+    if (s->vps->vps_timing_info_present_flag) {
+        num = s->vps->vps_num_units_in_tick;
+        den = s->vps->vps_time_scale;
+    } else if (sps->vui.vui_timing_info_present_flag) {
+        num = sps->vui.vui_num_units_in_tick;
+        den = sps->vui.vui_time_scale;
+    }
+
+    if (num != 0 && den != 0)
+        av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
+                  num, den, 1 << 30);
+
+    return 0;
+
+fail:
+    pic_arrays_free(s);
+    s->sps = NULL;
+    return ret;
+}
+
+static int hls_slice_header(HEVCContext *s)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+    SliceHeader *sh   = &s->sh;
+    int i, ret;
+
+    // Coded parameters
+    sh->first_slice_in_pic_flag = get_bits1(gb);
+    if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) {
+        s->seq_decode = (s->seq_decode + 1) & 0xff;
+        s->max_ra     = INT_MAX;
+        if (IS_IDR(s))
+            ff_hevc_clear_refs(s);
+    }
+    if (s->nal_unit_type >= 16 && s->nal_unit_type <= 23)
+        sh->no_output_of_prior_pics_flag = get_bits1(gb);
+
+    sh->pps_id = get_ue_golomb_long(gb);
+    if (sh->pps_id >= MAX_PPS_COUNT || !s->pps_list[sh->pps_id]) {
+        av_log(s->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", sh->pps_id);
+        return AVERROR_INVALIDDATA;
+    }
+    if (!sh->first_slice_in_pic_flag &&
+        s->pps != (HEVCPPS*)s->pps_list[sh->pps_id]->data) {
+        av_log(s->avctx, AV_LOG_ERROR, "PPS changed between slices.\n");
+        return AVERROR_INVALIDDATA;
+    }
+    s->pps = (HEVCPPS*)s->pps_list[sh->pps_id]->data;
+
+    if (s->sps != (HEVCSPS*)s->sps_list[s->pps->sps_id]->data) {
+        s->sps = (HEVCSPS*)s->sps_list[s->pps->sps_id]->data;
+
+        ff_hevc_clear_refs(s);
+        ret = set_sps(s, s->sps);
+        if (ret < 0)
+            return ret;
+
+        s->seq_decode = (s->seq_decode + 1) & 0xff;
+        s->max_ra     = INT_MAX;
+    }
+
+    sh->dependent_slice_segment_flag = 0;
+    if (!sh->first_slice_in_pic_flag) {
+        int slice_address_length;
+
+        if (s->pps->dependent_slice_segments_enabled_flag)
+            sh->dependent_slice_segment_flag = get_bits1(gb);
+
+        slice_address_length = av_ceil_log2(s->sps->ctb_width *
+                                            s->sps->ctb_height);
+        sh->slice_segment_addr = get_bits(gb, slice_address_length);
+        if (sh->slice_segment_addr >= s->sps->ctb_width * s->sps->ctb_height) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Invalid slice segment address: %u.\n",
+                   sh->slice_segment_addr);
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (!sh->dependent_slice_segment_flag) {
+            sh->slice_addr = sh->slice_segment_addr;
+            s->slice_idx++;
+        }
+    } else {
+        sh->slice_segment_addr = sh->slice_addr = 0;
+        s->slice_idx           = 0;
+        s->slice_initialized   = 0;
+    }
+
+    if (!sh->dependent_slice_segment_flag) {
+        s->slice_initialized = 0;
+
+        for (i = 0; i < s->pps->num_extra_slice_header_bits; i++)
+            skip_bits(gb, 1);  // slice_reserved_undetermined_flag[]
+
+        sh->slice_type = get_ue_golomb_long(gb);
+        if (!(sh->slice_type == I_SLICE ||
+              sh->slice_type == P_SLICE ||
+              sh->slice_type == B_SLICE)) {
+            av_log(s->avctx, AV_LOG_ERROR, "Unknown slice type: %d.\n",
+                   sh->slice_type);
+            return AVERROR_INVALIDDATA;
+        }
+        if (IS_IRAP(s) && sh->slice_type != I_SLICE) {
+            av_log(s->avctx, AV_LOG_ERROR, "Inter slices in an IRAP frame.\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (s->pps->output_flag_present_flag)
+            sh->pic_output_flag = get_bits1(gb);
+
+        if (s->sps->separate_colour_plane_flag)
+            sh->colour_plane_id = get_bits(gb, 2);
+
+        if (!IS_IDR(s)) {
+            int short_term_ref_pic_set_sps_flag, poc;
+
+            sh->pic_order_cnt_lsb = get_bits(gb, s->sps->log2_max_poc_lsb);
+            poc = ff_hevc_compute_poc(s, sh->pic_order_cnt_lsb);
+            if (!sh->first_slice_in_pic_flag && poc != s->poc) {
+                av_log(s->avctx, AV_LOG_WARNING,
+                       "Ignoring POC change between slices: %d -> %d\n", s->poc, poc);
+                if (s->avctx->err_recognition & AV_EF_EXPLODE)
+                    return AVERROR_INVALIDDATA;
+                poc = s->poc;
+            }
+            s->poc = poc;
+
+            short_term_ref_pic_set_sps_flag = get_bits1(gb);
+            if (!short_term_ref_pic_set_sps_flag) {
+                ret = ff_hevc_decode_short_term_rps(s, &sh->slice_rps, s->sps, 1);
+                if (ret < 0)
+                    return ret;
+
+                sh->short_term_rps = &sh->slice_rps;
+            } else {
+                int numbits, rps_idx;
+
+                if (!s->sps->nb_st_rps) {
+                    av_log(s->avctx, AV_LOG_ERROR, "No ref lists in the SPS.\n");
+                    return AVERROR_INVALIDDATA;
+                }
+
+                numbits = av_ceil_log2(s->sps->nb_st_rps);
+                rps_idx = numbits > 0 ? get_bits(gb, numbits) : 0;
+                sh->short_term_rps = &s->sps->st_rps[rps_idx];
+            }
+
+            ret = decode_lt_rps(s, &sh->long_term_rps, gb);
+            if (ret < 0) {
+                av_log(s->avctx, AV_LOG_WARNING, "Invalid long term RPS.\n");
+                if (s->avctx->err_recognition & AV_EF_EXPLODE)
+                    return AVERROR_INVALIDDATA;
+            }
+
+            if (s->sps->sps_temporal_mvp_enabled_flag)
+                sh->slice_temporal_mvp_enabled_flag = get_bits1(gb);
+            else
+                sh->slice_temporal_mvp_enabled_flag = 0;
+        } else {
+            s->sh.short_term_rps = NULL;
+            s->poc               = 0;
+        }
+
+        /* 8.3.1 */
+        if (s->temporal_id == 0 &&
+            s->nal_unit_type != NAL_TRAIL_N &&
+            s->nal_unit_type != NAL_TSA_N   &&
+            s->nal_unit_type != NAL_STSA_N  &&
+            s->nal_unit_type != NAL_RADL_N  &&
+            s->nal_unit_type != NAL_RADL_R  &&
+            s->nal_unit_type != NAL_RASL_N  &&
+            s->nal_unit_type != NAL_RASL_R)
+            s->pocTid0 = s->poc;
+
+        if (s->sps->sao_enabled) {
+            sh->slice_sample_adaptive_offset_flag[0] = get_bits1(gb);
+            sh->slice_sample_adaptive_offset_flag[1] =
+            sh->slice_sample_adaptive_offset_flag[2] = get_bits1(gb);
+        } else {
+            sh->slice_sample_adaptive_offset_flag[0] = 0;
+            sh->slice_sample_adaptive_offset_flag[1] = 0;
+            sh->slice_sample_adaptive_offset_flag[2] = 0;
+        }
+
+        sh->nb_refs[L0] = sh->nb_refs[L1] = 0;
+        if (sh->slice_type == P_SLICE || sh->slice_type == B_SLICE) {
+            int nb_refs;
+
+            sh->nb_refs[L0] = s->pps->num_ref_idx_l0_default_active;
+            if (sh->slice_type == B_SLICE)
+                sh->nb_refs[L1] = s->pps->num_ref_idx_l1_default_active;
+
+            if (get_bits1(gb)) { // num_ref_idx_active_override_flag
+                sh->nb_refs[L0] = get_ue_golomb_long(gb) + 1;
+                if (sh->slice_type == B_SLICE)
+                    sh->nb_refs[L1] = get_ue_golomb_long(gb) + 1;
+            }
+            if (sh->nb_refs[L0] > MAX_REFS || sh->nb_refs[L1] > MAX_REFS) {
+                av_log(s->avctx, AV_LOG_ERROR, "Too many refs: %d/%d.\n",
+                       sh->nb_refs[L0], sh->nb_refs[L1]);
+                return AVERROR_INVALIDDATA;
+            }
+
+            sh->rpl_modification_flag[0] = 0;
+            sh->rpl_modification_flag[1] = 0;
+            nb_refs = ff_hevc_frame_nb_refs(s);
+            if (!nb_refs) {
+                av_log(s->avctx, AV_LOG_ERROR, "Zero refs for a frame with P or B slices.\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            if (s->pps->lists_modification_present_flag && nb_refs > 1) {
+                sh->rpl_modification_flag[0] = get_bits1(gb);
+                if (sh->rpl_modification_flag[0]) {
+                    for (i = 0; i < sh->nb_refs[L0]; i++)
+                        sh->list_entry_lx[0][i] = get_bits(gb, av_ceil_log2(nb_refs));
+                }
+
+                if (sh->slice_type == B_SLICE) {
+                    sh->rpl_modification_flag[1] = get_bits1(gb);
+                    if (sh->rpl_modification_flag[1] == 1)
+                        for (i = 0; i < sh->nb_refs[L1]; i++)
+                            sh->list_entry_lx[1][i] = get_bits(gb, av_ceil_log2(nb_refs));
+                }
+            }
+
+            if (sh->slice_type == B_SLICE)
+                sh->mvd_l1_zero_flag = get_bits1(gb);
+
+            if (s->pps->cabac_init_present_flag)
+                sh->cabac_init_flag = get_bits1(gb);
+            else
+                sh->cabac_init_flag = 0;
+
+            sh->collocated_ref_idx = 0;
+            if (sh->slice_temporal_mvp_enabled_flag) {
+                sh->collocated_list = L0;
+                if (sh->slice_type == B_SLICE)
+                    sh->collocated_list = !get_bits1(gb);
+
+                if (sh->nb_refs[sh->collocated_list] > 1) {
+                    sh->collocated_ref_idx = get_ue_golomb_long(gb);
+                    if (sh->collocated_ref_idx >= sh->nb_refs[sh->collocated_list]) {
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "Invalid collocated_ref_idx: %d.\n",
+                               sh->collocated_ref_idx);
+                        return AVERROR_INVALIDDATA;
+                    }
+                }
+            }
+
+            if ((s->pps->weighted_pred_flag   && sh->slice_type == P_SLICE) ||
+                (s->pps->weighted_bipred_flag && sh->slice_type == B_SLICE)) {
+                pred_weight_table(s, gb);
+            }
+
+            sh->max_num_merge_cand = 5 - get_ue_golomb_long(gb);
+            if (sh->max_num_merge_cand < 1 || sh->max_num_merge_cand > 5) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "Invalid number of merging MVP candidates: %d.\n",
+                       sh->max_num_merge_cand);
+                return AVERROR_INVALIDDATA;
+            }
+        }
+
+        sh->slice_qp_delta = get_se_golomb(gb);
+        if (s->pps->pic_slice_level_chroma_qp_offsets_present_flag) {
+            sh->slice_cb_qp_offset = get_se_golomb(gb);
+            sh->slice_cr_qp_offset = get_se_golomb(gb);
+        } else {
+            sh->slice_cb_qp_offset = 0;
+            sh->slice_cr_qp_offset = 0;
+        }
+
+        if (s->pps->deblocking_filter_control_present_flag) {
+            int deblocking_filter_override_flag = 0;
+
+            if (s->pps->deblocking_filter_override_enabled_flag)
+                deblocking_filter_override_flag = get_bits1(gb);
+
+            if (deblocking_filter_override_flag) {
+                sh->disable_deblocking_filter_flag = get_bits1(gb);
+                if (!sh->disable_deblocking_filter_flag) {
+                    sh->beta_offset = get_se_golomb(gb) * 2;
+                    sh->tc_offset   = get_se_golomb(gb) * 2;
+                }
+            } else {
+                sh->disable_deblocking_filter_flag = s->pps->disable_dbf;
+                sh->beta_offset                    = s->pps->beta_offset;
+                sh->tc_offset                      = s->pps->tc_offset;
+            }
+        } else {
+            sh->disable_deblocking_filter_flag = 0;
+            sh->beta_offset                    = 0;
+            sh->tc_offset                      = 0;
+        }
+
+        if (s->pps->seq_loop_filter_across_slices_enabled_flag &&
+            (sh->slice_sample_adaptive_offset_flag[0] ||
+             sh->slice_sample_adaptive_offset_flag[1] ||
+             !sh->disable_deblocking_filter_flag)) {
+            sh->slice_loop_filter_across_slices_enabled_flag = get_bits1(gb);
+        } else {
+            sh->slice_loop_filter_across_slices_enabled_flag = s->pps->seq_loop_filter_across_slices_enabled_flag;
+        }
+    } else if (!s->slice_initialized) {
+        av_log(s->avctx, AV_LOG_ERROR, "Independent slice segment missing.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    sh->num_entry_point_offsets = 0;
+    if (s->pps->tiles_enabled_flag || s->pps->entropy_coding_sync_enabled_flag) {
+        sh->num_entry_point_offsets = get_ue_golomb_long(gb);
+        if (sh->num_entry_point_offsets > 0) {
+            int offset_len = get_ue_golomb_long(gb) + 1;
+
+            for (i = 0; i < sh->num_entry_point_offsets; i++)
+                skip_bits(gb, offset_len);
+        }
+    }
+
+    if (s->pps->slice_header_extension_present_flag) {
+        int length = get_ue_golomb_long(gb);
+        for (i = 0; i < length; i++)
+            skip_bits(gb, 8);  // slice_header_extension_data_byte
+    }
+
+    // Inferred parameters
+    sh->slice_qp          = 26 + s->pps->pic_init_qp_minus26 + sh->slice_qp_delta;
+    sh->slice_ctb_addr_rs = sh->slice_segment_addr;
+
+    s->HEVClc.first_qp_group = !s->sh.dependent_slice_segment_flag;
+
+    if (!s->pps->cu_qp_delta_enabled_flag)
+        s->HEVClc.qp_y = ((s->sh.slice_qp + 52 + 2 * s->sps->qp_bd_offset) %
+                          (52 + s->sps->qp_bd_offset)) - s->sps->qp_bd_offset;
+
+    s->slice_initialized = 1;
+
+    return 0;
+}
+
+#define CTB(tab, x, y) ((tab)[(y) * s->sps->ctb_width + (x)])
+
+#define SET_SAO(elem, value)                            \
+do {                                                    \
+    if (!sao_merge_up_flag && !sao_merge_left_flag)     \
+        sao->elem = value;                              \
+    else if (sao_merge_left_flag)                       \
+        sao->elem = CTB(s->sao, rx-1, ry).elem;         \
+    else if (sao_merge_up_flag)                         \
+        sao->elem = CTB(s->sao, rx, ry-1).elem;         \
+    else                                                \
+        sao->elem = 0;                                  \
+} while (0)
+
+static void hls_sao_param(HEVCContext *s, int rx, int ry)
+{
+    HEVCLocalContext *lc    = &s->HEVClc;
+    int sao_merge_left_flag = 0;
+    int sao_merge_up_flag   = 0;
+    int shift               = s->sps->bit_depth - FFMIN(s->sps->bit_depth, 10);
+    SAOParams *sao          = &CTB(s->sao, rx, ry);
+    int c_idx, i;
+
+    if (s->sh.slice_sample_adaptive_offset_flag[0] ||
+        s->sh.slice_sample_adaptive_offset_flag[1]) {
+        if (rx > 0) {
+            if (lc->ctb_left_flag)
+                sao_merge_left_flag = ff_hevc_sao_merge_flag_decode(s);
+        }
+        if (ry > 0 && !sao_merge_left_flag) {
+            if (lc->ctb_up_flag)
+                sao_merge_up_flag = ff_hevc_sao_merge_flag_decode(s);
+        }
+    }
+
+    for (c_idx = 0; c_idx < 3; c_idx++) {
+        if (!s->sh.slice_sample_adaptive_offset_flag[c_idx]) {
+            sao->type_idx[c_idx] = SAO_NOT_APPLIED;
+            continue;
+        }
+
+        if (c_idx == 2) {
+            sao->type_idx[2] = sao->type_idx[1];
+            sao->eo_class[2] = sao->eo_class[1];
+        } else {
+            SET_SAO(type_idx[c_idx], ff_hevc_sao_type_idx_decode(s));
+        }
+
+        if (sao->type_idx[c_idx] == SAO_NOT_APPLIED)
+            continue;
+
+        for (i = 0; i < 4; i++)
+            SET_SAO(offset_abs[c_idx][i], ff_hevc_sao_offset_abs_decode(s));
+
+        if (sao->type_idx[c_idx] == SAO_BAND) {
+            for (i = 0; i < 4; i++) {
+                if (sao->offset_abs[c_idx][i]) {
+                    SET_SAO(offset_sign[c_idx][i],
+                            ff_hevc_sao_offset_sign_decode(s));
+                } else {
+                    sao->offset_sign[c_idx][i] = 0;
+                }
+            }
+            SET_SAO(band_position[c_idx], ff_hevc_sao_band_position_decode(s));
+        } else if (c_idx != 2) {
+            SET_SAO(eo_class[c_idx], ff_hevc_sao_eo_class_decode(s));
+        }
+
+        // Inferred parameters
+        sao->offset_val[c_idx][0] = 0;
+        for (i = 0; i < 4; i++) {
+            sao->offset_val[c_idx][i + 1] = sao->offset_abs[c_idx][i] << shift;
+            if (sao->type_idx[c_idx] == SAO_EDGE) {
+                if (i > 1)
+                    sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
+            } else if (sao->offset_sign[c_idx][i]) {
+                sao->offset_val[c_idx][i + 1] = -sao->offset_val[c_idx][i + 1];
+            }
+        }
+    }
+}
+
+#undef SET_SAO
+#undef CTB
+
+static void hls_residual_coding(HEVCContext *s, int x0, int y0,
+                                int log2_trafo_size, enum ScanType scan_idx,
+                                int c_idx)
+{
+#define GET_COORD(offset, n)                                    \
+    do {                                                        \
+        x_c = (scan_x_cg[offset >> 4] << 2) + scan_x_off[n];    \
+        y_c = (scan_y_cg[offset >> 4] << 2) + scan_y_off[n];    \
+    } while (0)
+    HEVCLocalContext *lc    = &s->HEVClc;
+    int transform_skip_flag = 0;
+
+    int last_significant_coeff_x, last_significant_coeff_y;
+    int last_scan_pos;
+    int n_end;
+    int num_coeff    = 0;
+    int greater1_ctx = 1;
+
+    int num_last_subset;
+    int x_cg_last_sig, y_cg_last_sig;
+
+    const uint8_t *scan_x_cg, *scan_y_cg, *scan_x_off, *scan_y_off;
+
+    ptrdiff_t stride = s->frame->linesize[c_idx];
+    int hshift       = s->sps->hshift[c_idx];
+    int vshift       = s->sps->vshift[c_idx];
+    uint8_t *dst     = &s->frame->data[c_idx][(y0 >> vshift) * stride +
+                                              ((x0 >> hshift) << s->sps->pixel_shift)];
+    DECLARE_ALIGNED(16, int16_t, coeffs[MAX_TB_SIZE * MAX_TB_SIZE]) = { 0 };
+    DECLARE_ALIGNED(8, uint8_t, significant_coeff_group_flag[8][8]) = { { 0 } };
+
+    int trafo_size = 1 << log2_trafo_size;
+    int i, qp, shift, add, scale, scale_m;
+    const uint8_t level_scale[] = { 40, 45, 51, 57, 64, 72 };
+    const uint8_t *scale_matrix;
+    uint8_t dc_scale;
+
+    // Derive QP for dequant
+    if (!lc->cu.cu_transquant_bypass_flag) {
+        static const int qp_c[] = {
+            29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37
+        };
+
+        static const uint8_t rem6[51 + 2 * 6 + 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,
+        };
+
+        static const uint8_t div6[51 + 2 * 6 + 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,
+        };
+        int qp_y = lc->qp_y;
+
+        if (c_idx == 0) {
+            qp = qp_y + s->sps->qp_bd_offset;
+        } else {
+            int qp_i, offset;
+
+            if (c_idx == 1)
+                offset = s->pps->cb_qp_offset + s->sh.slice_cb_qp_offset;
+            else
+                offset = s->pps->cr_qp_offset + s->sh.slice_cr_qp_offset;
+
+            qp_i = av_clip_c(qp_y + offset, -s->sps->qp_bd_offset, 57);
+            if (qp_i < 30)
+                qp = qp_i;
+            else if (qp_i > 43)
+                qp = qp_i - 6;
+            else
+                qp = qp_c[qp_i - 30];
+
+            qp += s->sps->qp_bd_offset;
+        }
+
+        shift    = s->sps->bit_depth + log2_trafo_size - 5;
+        add      = 1 << (shift - 1);
+        scale    = level_scale[rem6[qp]] << (div6[qp]);
+        scale_m  = 16; // default when no custom scaling lists.
+        dc_scale = 16;
+
+        if (s->sps->scaling_list_enable_flag) {
+            const ScalingList *sl = s->pps->scaling_list_data_present_flag ?
+                                    &s->pps->scaling_list : &s->sps->scaling_list;
+            int matrix_id = lc->cu.pred_mode != MODE_INTRA;
+
+            if (log2_trafo_size != 5)
+                matrix_id = 3 * matrix_id + c_idx;
+
+            scale_matrix = sl->sl[log2_trafo_size - 2][matrix_id];
+            if (log2_trafo_size >= 4)
+                dc_scale = sl->sl_dc[log2_trafo_size - 4][matrix_id];
+        }
+    }
+
+    if (s->pps->transform_skip_enabled_flag &&
+        !lc->cu.cu_transquant_bypass_flag   &&
+        log2_trafo_size == 2) {
+        transform_skip_flag = ff_hevc_transform_skip_flag_decode(s, c_idx);
+    }
+
+    last_significant_coeff_x =
+        ff_hevc_last_significant_coeff_x_prefix_decode(s, c_idx, log2_trafo_size);
+    last_significant_coeff_y =
+        ff_hevc_last_significant_coeff_y_prefix_decode(s, c_idx, log2_trafo_size);
+
+    if (last_significant_coeff_x > 3) {
+        int suffix = ff_hevc_last_significant_coeff_suffix_decode(s, last_significant_coeff_x);
+        last_significant_coeff_x = (1 << ((last_significant_coeff_x >> 1) - 1)) *
+                                   (2 + (last_significant_coeff_x & 1)) +
+                                   suffix;
+    }
+
+    if (last_significant_coeff_y > 3) {
+        int suffix = ff_hevc_last_significant_coeff_suffix_decode(s, last_significant_coeff_y);
+        last_significant_coeff_y = (1 << ((last_significant_coeff_y >> 1) - 1)) *
+                                   (2 + (last_significant_coeff_y & 1)) +
+                                   suffix;
+    }
+
+    if (scan_idx == SCAN_VERT)
+        FFSWAP(int, last_significant_coeff_x, last_significant_coeff_y);
+
+    x_cg_last_sig = last_significant_coeff_x >> 2;
+    y_cg_last_sig = last_significant_coeff_y >> 2;
+
+    switch (scan_idx) {
+    case SCAN_DIAG: {
+        int last_x_c = last_significant_coeff_x & 3;
+        int last_y_c = last_significant_coeff_y & 3;
+
+        scan_x_off = ff_hevc_diag_scan4x4_x;
+        scan_y_off = ff_hevc_diag_scan4x4_y;
+        num_coeff  = diag_scan4x4_inv[last_y_c][last_x_c];
+        if (trafo_size == 4) {
+            scan_x_cg = scan_1x1;
+            scan_y_cg = scan_1x1;
+        } else if (trafo_size == 8) {
+            num_coeff += diag_scan2x2_inv[y_cg_last_sig][x_cg_last_sig] << 4;
+            scan_x_cg  = diag_scan2x2_x;
+            scan_y_cg  = diag_scan2x2_y;
+        } else if (trafo_size == 16) {
+            num_coeff += diag_scan4x4_inv[y_cg_last_sig][x_cg_last_sig] << 4;
+            scan_x_cg  = ff_hevc_diag_scan4x4_x;
+            scan_y_cg  = ff_hevc_diag_scan4x4_y;
+        } else { // trafo_size == 32
+            num_coeff += diag_scan8x8_inv[y_cg_last_sig][x_cg_last_sig] << 4;
+            scan_x_cg  = ff_hevc_diag_scan8x8_x;
+            scan_y_cg  = ff_hevc_diag_scan8x8_y;
+        }
+        break;
+    }
+    case SCAN_HORIZ:
+        scan_x_cg  = horiz_scan2x2_x;
+        scan_y_cg  = horiz_scan2x2_y;
+        scan_x_off = horiz_scan4x4_x;
+        scan_y_off = horiz_scan4x4_y;
+        num_coeff  = horiz_scan8x8_inv[last_significant_coeff_y][last_significant_coeff_x];
+        break;
+    default: //SCAN_VERT
+        scan_x_cg  = horiz_scan2x2_y;
+        scan_y_cg  = horiz_scan2x2_x;
+        scan_x_off = horiz_scan4x4_y;
+        scan_y_off = horiz_scan4x4_x;
+        num_coeff  = horiz_scan8x8_inv[last_significant_coeff_x][last_significant_coeff_y];
+        break;
+    }
+    num_coeff++;
+    num_last_subset = (num_coeff - 1) >> 4;
+
+    for (i = num_last_subset; i >= 0; i--) {
+        int n, m;
+        int x_cg, y_cg, x_c, y_c;
+        int implicit_non_zero_coeff = 0;
+        int64_t trans_coeff_level;
+        int prev_sig = 0;
+        int offset   = i << 4;
+
+        uint8_t significant_coeff_flag_idx[16];
+        uint8_t nb_significant_coeff_flag = 0;
+
+        x_cg = scan_x_cg[i];
+        y_cg = scan_y_cg[i];
+
+        if (i < num_last_subset && i > 0) {
+            int ctx_cg = 0;
+            if (x_cg < (1 << (log2_trafo_size - 2)) - 1)
+                ctx_cg += significant_coeff_group_flag[x_cg + 1][y_cg];
+            if (y_cg < (1 << (log2_trafo_size - 2)) - 1)
+                ctx_cg += significant_coeff_group_flag[x_cg][y_cg + 1];
+
+            significant_coeff_group_flag[x_cg][y_cg] =
+                ff_hevc_significant_coeff_group_flag_decode(s, c_idx, ctx_cg);
+            implicit_non_zero_coeff = 1;
+        } else {
+            significant_coeff_group_flag[x_cg][y_cg] =
+                ((x_cg == x_cg_last_sig && y_cg == y_cg_last_sig) ||
+                 (x_cg == 0 && y_cg == 0));
+        }
+
+        last_scan_pos = num_coeff - offset - 1;
+
+        if (i == num_last_subset) {
+            n_end                         = last_scan_pos - 1;
+            significant_coeff_flag_idx[0] = last_scan_pos;
+            nb_significant_coeff_flag     = 1;
+        } else {
+            n_end = 15;
+        }
+
+        if (x_cg < ((1 << log2_trafo_size) - 1) >> 2)
+            prev_sig = significant_coeff_group_flag[x_cg + 1][y_cg];
+        if (y_cg < ((1 << log2_trafo_size) - 1) >> 2)
+            prev_sig += significant_coeff_group_flag[x_cg][y_cg + 1] << 1;
+
+        for (n = n_end; n >= 0; n--) {
+            GET_COORD(offset, n);
+
+            if (significant_coeff_group_flag[x_cg][y_cg] &&
+                (n > 0 || implicit_non_zero_coeff == 0)) {
+                if (ff_hevc_significant_coeff_flag_decode(s, c_idx, x_c, y_c,
+                                                          log2_trafo_size,
+                                                          scan_idx,
+                                                          prev_sig) == 1) {
+                    significant_coeff_flag_idx[nb_significant_coeff_flag] = n;
+                    nb_significant_coeff_flag++;
+                    implicit_non_zero_coeff = 0;
+                }
+            } else {
+                int last_cg = (x_c == (x_cg << 2) && y_c == (y_cg << 2));
+                if (last_cg && implicit_non_zero_coeff && significant_coeff_group_flag[x_cg][y_cg]) {
+                    significant_coeff_flag_idx[nb_significant_coeff_flag] = n;
+                    nb_significant_coeff_flag++;
+                }
+            }
+        }
+
+        n_end = nb_significant_coeff_flag;
+
+        if (n_end) {
+            int first_nz_pos_in_cg = 16;
+            int last_nz_pos_in_cg = -1;
+            int c_rice_param = 0;
+            int first_greater1_coeff_idx = -1;
+            uint8_t coeff_abs_level_greater1_flag[16] = { 0 };
+            uint16_t coeff_sign_flag;
+            int sum_abs = 0;
+            int sign_hidden = 0;
+
+            // initialize first elem of coeff_bas_level_greater1_flag
+            int ctx_set = (i > 0 && c_idx == 0) ? 2 : 0;
+
+            if (!(i == num_last_subset) && greater1_ctx == 0)
+                ctx_set++;
+            greater1_ctx      = 1;
+            last_nz_pos_in_cg = significant_coeff_flag_idx[0];
+
+            for (m = 0; m < (n_end > 8 ? 8 : n_end); m++) {
+                int n_idx = significant_coeff_flag_idx[m];
+                int inc   = (ctx_set << 2) + greater1_ctx;
+                coeff_abs_level_greater1_flag[n_idx] =
+                    ff_hevc_coeff_abs_level_greater1_flag_decode(s, c_idx, inc);
+                if (coeff_abs_level_greater1_flag[n_idx]) {
+                    greater1_ctx = 0;
+                } else if (greater1_ctx > 0 && greater1_ctx < 3) {
+                    greater1_ctx++;
+                }
+
+                if (coeff_abs_level_greater1_flag[n_idx] &&
+                    first_greater1_coeff_idx == -1)
+                    first_greater1_coeff_idx = n_idx;
+            }
+            first_nz_pos_in_cg = significant_coeff_flag_idx[n_end - 1];
+            sign_hidden        = last_nz_pos_in_cg - first_nz_pos_in_cg >= 4 &&
+                                 !lc->cu.cu_transquant_bypass_flag;
+
+            if (first_greater1_coeff_idx != -1) {
+                coeff_abs_level_greater1_flag[first_greater1_coeff_idx] += ff_hevc_coeff_abs_level_greater2_flag_decode(s, c_idx, ctx_set);
+            }
+            if (!s->pps->sign_data_hiding_flag || !sign_hidden) {
+                coeff_sign_flag = ff_hevc_coeff_sign_flag(s, nb_significant_coeff_flag) << (16 - nb_significant_coeff_flag);
+            } else {
+                coeff_sign_flag = ff_hevc_coeff_sign_flag(s, nb_significant_coeff_flag - 1) << (16 - (nb_significant_coeff_flag - 1));
+            }
+
+            for (m = 0; m < n_end; m++) {
+                n = significant_coeff_flag_idx[m];
+                GET_COORD(offset, n);
+                trans_coeff_level = 1 + coeff_abs_level_greater1_flag[n];
+                if (trans_coeff_level == ((m < 8) ?
+                                          ((n == first_greater1_coeff_idx) ? 3 : 2) : 1)) {
+                    int last_coeff_abs_level_remaining = ff_hevc_coeff_abs_level_remaining(s, trans_coeff_level, c_rice_param);
+
+                    trans_coeff_level += last_coeff_abs_level_remaining;
+                    if ((trans_coeff_level) > (3 * (1 << c_rice_param)))
+                        c_rice_param = FFMIN(c_rice_param + 1, 4);
+                }
+                if (s->pps->sign_data_hiding_flag && sign_hidden) {
+                    sum_abs += trans_coeff_level;
+                    if (n == first_nz_pos_in_cg && ((sum_abs & 1) == 1))
+                        trans_coeff_level = -trans_coeff_level;
+                }
+                if (coeff_sign_flag >> 15)
+                    trans_coeff_level = -trans_coeff_level;
+                coeff_sign_flag <<= 1;
+                if (!lc->cu.cu_transquant_bypass_flag) {
+                    if (s->sps->scaling_list_enable_flag) {
+                        if (y_c || x_c || log2_trafo_size < 4) {
+                            int pos;
+                            switch (log2_trafo_size) {
+                            case 3:  pos = (y_c        << 3) +  x_c;       break;
+                            case 4:  pos = ((y_c >> 1) << 3) + (x_c >> 1); break;
+                            case 5:  pos = ((y_c >> 2) << 3) + (x_c >> 2); break;
+                            default: pos = (y_c        << 2) +  x_c;
+                            }
+                            scale_m = scale_matrix[pos];
+                        } else {
+                            scale_m = dc_scale;
+                        }
+                    }
+                    trans_coeff_level = (trans_coeff_level * (int64_t)scale * (int64_t)scale_m + add) >> shift;
+                    if(trans_coeff_level < 0) {
+                        if((~trans_coeff_level) & 0xFffffffffff8000)
+                            trans_coeff_level = -32768;
+                    } else {
+                        if (trans_coeff_level & 0xffffffffffff8000)
+                            trans_coeff_level = 32767;
+                    }
+                }
+                coeffs[y_c * trafo_size + x_c] = trans_coeff_level;
+            }
+        }
+    }
+
+    if (lc->cu.cu_transquant_bypass_flag) {
+        s->hevcdsp.transquant_bypass[log2_trafo_size - 2](dst, coeffs, stride);
+    } else {
+        if (transform_skip_flag)
+            s->hevcdsp.transform_skip(dst, coeffs, stride);
+        else if (lc->cu.pred_mode == MODE_INTRA && c_idx == 0 &&
+                 log2_trafo_size == 2)
+            s->hevcdsp.transform_4x4_luma_add(dst, coeffs, stride);
+        else
+            s->hevcdsp.transform_add[log2_trafo_size - 2](dst, coeffs, stride);
+    }
+}
+
+static void hls_transform_unit(HEVCContext *s, int x0, int y0,
+                               int xBase, int yBase, int cb_xBase, int cb_yBase,
+                               int log2_cb_size, int log2_trafo_size,
+                               int trafo_depth, int blk_idx)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+
+    if (lc->cu.pred_mode == MODE_INTRA) {
+        int trafo_size = 1 << log2_trafo_size;
+        ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
+
+        s->hpc.intra_pred(s, x0, y0, log2_trafo_size, 0);
+        if (log2_trafo_size > 2) {
+            trafo_size = trafo_size << (s->sps->hshift[1] - 1);
+            ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
+            s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 1);
+            s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 2);
+        } else if (blk_idx == 3) {
+            trafo_size = trafo_size << s->sps->hshift[1];
+            ff_hevc_set_neighbour_available(s, xBase, yBase,
+                                            trafo_size, trafo_size);
+            s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 1);
+            s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 2);
+        }
+    }
+
+    if (lc->tt.cbf_luma ||
+        SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
+        SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) {
+        int scan_idx   = SCAN_DIAG;
+        int scan_idx_c = SCAN_DIAG;
+
+        if (s->pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded) {
+            lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(s);
+            if (lc->tu.cu_qp_delta != 0)
+                if (ff_hevc_cu_qp_delta_sign_flag(s) == 1)
+                    lc->tu.cu_qp_delta = -lc->tu.cu_qp_delta;
+            lc->tu.is_cu_qp_delta_coded = 1;
+            ff_hevc_set_qPy(s, x0, y0, cb_xBase, cb_yBase, log2_cb_size);
+        }
+
+        if (lc->cu.pred_mode == MODE_INTRA && log2_trafo_size < 4) {
+            if (lc->tu.cur_intra_pred_mode >= 6 &&
+                lc->tu.cur_intra_pred_mode <= 14) {
+                scan_idx = SCAN_VERT;
+            } else if (lc->tu.cur_intra_pred_mode >= 22 &&
+                       lc->tu.cur_intra_pred_mode <= 30) {
+                scan_idx = SCAN_HORIZ;
+            }
+
+            if (lc->pu.intra_pred_mode_c >=  6 &&
+                lc->pu.intra_pred_mode_c <= 14) {
+                scan_idx_c = SCAN_VERT;
+            } else if (lc->pu.intra_pred_mode_c >= 22 &&
+                       lc->pu.intra_pred_mode_c <= 30) {
+                scan_idx_c = SCAN_HORIZ;
+            }
+        }
+
+        if (lc->tt.cbf_luma)
+            hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0);
+        if (log2_trafo_size > 2) {
+            if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0))
+                hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 1);
+            if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0))
+                hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 2);
+        } else if (blk_idx == 3) {
+            if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], xBase, yBase))
+                hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 1);
+            if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], xBase, yBase))
+                hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 2);
+        }
+    }
+}
+
+static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_size)
+{
+    int cb_size          = 1 << log2_cb_size;
+    int log2_min_pu_size = s->sps->log2_min_pu_size;
+
+    int min_pu_width     = s->sps->min_pu_width;
+    int x_end = FFMIN(x0 + cb_size, s->sps->width);
+    int y_end = FFMIN(y0 + cb_size, s->sps->height);
+    int i, j;
+
+    for (j = (y0 >> log2_min_pu_size); j < (y_end >> log2_min_pu_size); j++)
+        for (i = (x0 >> log2_min_pu_size); i < (x_end >> log2_min_pu_size); i++)
+            s->is_pcm[i + j * min_pu_width] = 2;
+}
+
+static void hls_transform_tree(HEVCContext *s, int x0, int y0,
+                               int xBase, int yBase, int cb_xBase, int cb_yBase,
+                               int log2_cb_size, int log2_trafo_size,
+                               int trafo_depth, int blk_idx)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    uint8_t split_transform_flag;
+
+    if (trafo_depth > 0 && log2_trafo_size == 2) {
+        SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
+            SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase);
+        SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
+            SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase);
+    } else {
+        SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
+        SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) = 0;
+    }
+
+    if (lc->cu.intra_split_flag) {
+        if (trafo_depth == 1)
+            lc->tu.cur_intra_pred_mode = lc->pu.intra_pred_mode[blk_idx];
+    } else {
+        lc->tu.cur_intra_pred_mode = lc->pu.intra_pred_mode[0];
+    }
+
+    lc->tt.cbf_luma = 1;
+
+    lc->tt.inter_split_flag = s->sps->max_transform_hierarchy_depth_inter == 0 &&
+                              lc->cu.pred_mode == MODE_INTER &&
+                              lc->cu.part_mode != PART_2Nx2N &&
+                              trafo_depth == 0;
+
+    if (log2_trafo_size <= s->sps->log2_max_trafo_size &&
+        log2_trafo_size >  s->sps->log2_min_tb_size    &&
+        trafo_depth     < lc->cu.max_trafo_depth       &&
+        !(lc->cu.intra_split_flag && trafo_depth == 0)) {
+        split_transform_flag = ff_hevc_split_transform_flag_decode(s, log2_trafo_size);
+    } else {
+        split_transform_flag = log2_trafo_size > s->sps->log2_max_trafo_size ||
+                               (lc->cu.intra_split_flag && trafo_depth == 0) ||
+                               lc->tt.inter_split_flag;
+    }
+
+    if (log2_trafo_size > 2) {
+        if (trafo_depth == 0 ||
+            SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth - 1], xBase, yBase)) {
+            SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) =
+                ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
+        }
+
+        if (trafo_depth == 0 ||
+            SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth - 1], xBase, yBase)) {
+            SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0) =
+                ff_hevc_cbf_cb_cr_decode(s, trafo_depth);
+        }
+    }
+
+    if (split_transform_flag) {
+        int x1 = x0 + ((1 << log2_trafo_size) >> 1);
+        int y1 = y0 + ((1 << log2_trafo_size) >> 1);
+
+        hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
+                           log2_trafo_size - 1, trafo_depth + 1, 0);
+        hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
+                           log2_trafo_size - 1, trafo_depth + 1, 1);
+        hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
+                           log2_trafo_size - 1, trafo_depth + 1, 2);
+        hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size,
+                           log2_trafo_size - 1, trafo_depth + 1, 3);
+    } else {
+        int min_tu_size      = 1 << s->sps->log2_min_tb_size;
+        int log2_min_tu_size = s->sps->log2_min_tb_size;
+        int min_tu_width     = s->sps->min_tb_width;
+
+        if (lc->cu.pred_mode == MODE_INTRA || trafo_depth != 0 ||
+            SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||
+            SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) {
+            lc->tt.cbf_luma = ff_hevc_cbf_luma_decode(s, trafo_depth);
+        }
+
+        hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase,
+                           log2_cb_size, log2_trafo_size, trafo_depth, blk_idx);
+
+        // TODO: store cbf_luma somewhere else
+        if (lc->tt.cbf_luma) {
+            int i, j;
+            for (i = 0; i < (1 << log2_trafo_size); i += min_tu_size)
+                for (j = 0; j < (1 << log2_trafo_size); j += min_tu_size) {
+                    int x_tu = (x0 + j) >> log2_min_tu_size;
+                    int y_tu = (y0 + i) >> log2_min_tu_size;
+                    s->cbf_luma[y_tu * min_tu_width + x_tu] = 1;
+                }
+        }
+        if (!s->sh.disable_deblocking_filter_flag) {
+            ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_trafo_size,
+                                                  lc->slice_or_tiles_up_boundary,
+                                                  lc->slice_or_tiles_left_boundary);
+            if (s->pps->transquant_bypass_enable_flag &&
+                lc->cu.cu_transquant_bypass_flag)
+                set_deblocking_bypass(s, x0, y0, log2_trafo_size);
+        }
+    }
+}
+
+static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size)
+{
+    //TODO: non-4:2:0 support
+    HEVCLocalContext *lc = &s->HEVClc;
+    GetBitContext gb;
+    int cb_size   = 1 << log2_cb_size;
+    int stride0   = s->frame->linesize[0];
+    uint8_t *dst0 = &s->frame->data[0][y0 * stride0 + (x0 << s->sps->pixel_shift)];
+    int   stride1 = s->frame->linesize[1];
+    uint8_t *dst1 = &s->frame->data[1][(y0 >> s->sps->vshift[1]) * stride1 + ((x0 >> s->sps->hshift[1]) << s->sps->pixel_shift)];
+    int   stride2 = s->frame->linesize[2];
+    uint8_t *dst2 = &s->frame->data[2][(y0 >> s->sps->vshift[2]) * stride2 + ((x0 >> s->sps->hshift[2]) << s->sps->pixel_shift)];
+
+    int length         = cb_size * cb_size * s->sps->pcm.bit_depth + ((cb_size * cb_size) >> 1) * s->sps->pcm.bit_depth;
+    const uint8_t *pcm = skip_bytes(&s->HEVClc.cc, (length + 7) >> 3);
+    int ret;
+
+    ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,
+                                          lc->slice_or_tiles_up_boundary,
+                                          lc->slice_or_tiles_left_boundary);
+
+    ret = init_get_bits(&gb, pcm, length);
+    if (ret < 0)
+        return ret;
+
+    s->hevcdsp.put_pcm(dst0, stride0, cb_size,     &gb, s->sps->pcm.bit_depth);
+    s->hevcdsp.put_pcm(dst1, stride1, cb_size / 2, &gb, s->sps->pcm.bit_depth);
+    s->hevcdsp.put_pcm(dst2, stride2, cb_size / 2, &gb, s->sps->pcm.bit_depth);
+    return 0;
+}
+
+static void hls_mvd_coding(HEVCContext *s, int x0, int y0, int log2_cb_size)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    int x = ff_hevc_abs_mvd_greater0_flag_decode(s);
+    int y = ff_hevc_abs_mvd_greater0_flag_decode(s);
+
+    if (x)
+        x += ff_hevc_abs_mvd_greater1_flag_decode(s);
+    if (y)
+        y += ff_hevc_abs_mvd_greater1_flag_decode(s);
+
+    switch (x) {
+    case 2: lc->pu.mvd.x = ff_hevc_mvd_decode(s);           break;
+    case 1: lc->pu.mvd.x = ff_hevc_mvd_sign_flag_decode(s); break;
+    case 0: lc->pu.mvd.x = 0;                               break;
+    }
+
+    switch (y) {
+    case 2: lc->pu.mvd.y = ff_hevc_mvd_decode(s);           break;
+    case 1: lc->pu.mvd.y = ff_hevc_mvd_sign_flag_decode(s); break;
+    case 0: lc->pu.mvd.y = 0;                               break;
+    }
+}
+
+/**
+ * 8.5.3.2.2.1 Luma sample interpolation process
+ *
+ * @param s HEVC decoding context
+ * @param dst target buffer for block data at block position
+ * @param dststride stride of the dst buffer
+ * @param ref reference picture buffer at origin (0, 0)
+ * @param mv motion vector (relative to block position) to get pixel data from
+ * @param x_off horizontal position of block from origin (0, 0)
+ * @param y_off vertical position of block from origin (0, 0)
+ * @param block_w width of block
+ * @param block_h height of block
+ */
+static void luma_mc(HEVCContext *s, int16_t *dst, ptrdiff_t dststride,
+                    AVFrame *ref, const Mv *mv, int x_off, int y_off,
+                    int block_w, int block_h)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    uint8_t *src         = ref->data[0];
+    ptrdiff_t srcstride  = ref->linesize[0];
+    int pic_width        = s->sps->width;
+    int pic_height       = s->sps->height;
+
+    int mx         = mv->x & 3;
+    int my         = mv->y & 3;
+    int extra_left = ff_hevc_qpel_extra_before[mx];
+    int extra_top  = ff_hevc_qpel_extra_before[my];
+
+    x_off += mv->x >> 2;
+    y_off += mv->y >> 2;
+    src   += y_off * srcstride + (x_off << s->sps->pixel_shift);
+
+    if (x_off < extra_left || y_off < extra_top ||
+        x_off >= pic_width - block_w - ff_hevc_qpel_extra_after[mx] ||
+        y_off >= pic_height - block_h - ff_hevc_qpel_extra_after[my]) {
+        int offset = extra_top * srcstride + (extra_left << s->sps->pixel_shift);
+
+        s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src - offset,
+                                 srcstride, srcstride,
+                                 block_w + ff_hevc_qpel_extra[mx],
+                                 block_h + ff_hevc_qpel_extra[my],
+                                 x_off - extra_left, y_off - extra_top,
+                                 pic_width, pic_height);
+        src = lc->edge_emu_buffer + offset;
+    }
+    s->hevcdsp.put_hevc_qpel[my][mx](dst, dststride, src, srcstride, block_w,
+                                     block_h, lc->mc_buffer);
+}
+
+/**
+ * 8.5.3.2.2.2 Chroma sample interpolation process
+ *
+ * @param s HEVC decoding context
+ * @param dst1 target buffer for block data at block position (U plane)
+ * @param dst2 target buffer for block data at block position (V plane)
+ * @param dststride stride of the dst1 and dst2 buffers
+ * @param ref reference picture buffer at origin (0, 0)
+ * @param mv motion vector (relative to block position) to get pixel data from
+ * @param x_off horizontal position of block from origin (0, 0)
+ * @param y_off vertical position of block from origin (0, 0)
+ * @param block_w width of block
+ * @param block_h height of block
+ */
+static void chroma_mc(HEVCContext *s, int16_t *dst1, int16_t *dst2,
+                      ptrdiff_t dststride, AVFrame *ref, const Mv *mv,
+                      int x_off, int y_off, int block_w, int block_h)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    uint8_t *src1        = ref->data[1];
+    uint8_t *src2        = ref->data[2];
+    ptrdiff_t src1stride = ref->linesize[1];
+    ptrdiff_t src2stride = ref->linesize[2];
+    int pic_width        = s->sps->width >> 1;
+    int pic_height       = s->sps->height >> 1;
+
+    int mx = mv->x & 7;
+    int my = mv->y & 7;
+
+    x_off += mv->x >> 3;
+    y_off += mv->y >> 3;
+    src1  += y_off * src1stride + (x_off << s->sps->pixel_shift);
+    src2  += y_off * src2stride + (x_off << s->sps->pixel_shift);
+
+    if (x_off < EPEL_EXTRA_BEFORE || y_off < EPEL_EXTRA_AFTER ||
+        x_off >= pic_width - block_w - EPEL_EXTRA_AFTER ||
+        y_off >= pic_height - block_h - EPEL_EXTRA_AFTER) {
+        int offset1 = EPEL_EXTRA_BEFORE * (src1stride + (1 << s->sps->pixel_shift));
+        int offset2 = EPEL_EXTRA_BEFORE * (src2stride + (1 << s->sps->pixel_shift));
+
+        s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src1 - offset1,
+                                 src1stride, src1stride,
+                                 block_w + EPEL_EXTRA, block_h + EPEL_EXTRA,
+                                 x_off - EPEL_EXTRA_BEFORE,
+                                 y_off - EPEL_EXTRA_BEFORE,
+                                 pic_width, pic_height);
+
+        src1 = lc->edge_emu_buffer + offset1;
+        s->hevcdsp.put_hevc_epel[!!my][!!mx](dst1, dststride, src1, src1stride,
+                                             block_w, block_h, mx, my, lc->mc_buffer);
+
+        s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src2 - offset2,
+                                 src2stride, src2stride,
+                                 block_w + EPEL_EXTRA, block_h + EPEL_EXTRA,
+                                 x_off - EPEL_EXTRA_BEFORE,
+                                 y_off - EPEL_EXTRA_BEFORE,
+                                 pic_width, pic_height);
+        src2 = lc->edge_emu_buffer + offset2;
+        s->hevcdsp.put_hevc_epel[!!my][!!mx](dst2, dststride, src2, src2stride,
+                                             block_w, block_h, mx, my,
+                                             lc->mc_buffer);
+    } else {
+        s->hevcdsp.put_hevc_epel[!!my][!!mx](dst1, dststride, src1, src1stride,
+                                             block_w, block_h, mx, my,
+                                             lc->mc_buffer);
+        s->hevcdsp.put_hevc_epel[!!my][!!mx](dst2, dststride, src2, src2stride,
+                                             block_w, block_h, mx, my,
+                                             lc->mc_buffer);
+    }
+}
+
+static void hevc_await_progress(HEVCContext *s, HEVCFrame *ref,
+                                const Mv *mv, int y0, int height)
+{
+    int y = (mv->y >> 2) + y0 + height + 9;
+    ff_thread_await_progress(&ref->tf, y, 0);
+}
+
+static void hls_prediction_unit(HEVCContext *s, int x0, int y0,
+                                int nPbW, int nPbH,
+                                int log2_cb_size, int partIdx)
+{
+#define POS(c_idx, x, y)                                                              \
+    &s->frame->data[c_idx][((y) >> s->sps->vshift[c_idx]) * s->frame->linesize[c_idx] + \
+                           (((x) >> s->sps->hshift[c_idx]) << s->sps->pixel_shift)]
+    HEVCLocalContext *lc = &s->HEVClc;
+    int merge_idx = 0;
+    struct MvField current_mv = {{{ 0 }}};
+
+    int min_pu_width = s->sps->min_pu_width;
+
+    MvField *tab_mvf = s->ref->tab_mvf;
+    RefPicList  *refPicList = s->ref->refPicList;
+    HEVCFrame *ref0, *ref1;
+
+    int tmpstride = MAX_PB_SIZE;
+
+    uint8_t *dst0 = POS(0, x0, y0);
+    uint8_t *dst1 = POS(1, x0, y0);
+    uint8_t *dst2 = POS(2, x0, y0);
+    int log2_min_cb_size = s->sps->log2_min_cb_size;
+    int min_cb_width     = s->sps->min_cb_width;
+    int x_cb             = x0 >> log2_min_cb_size;
+    int y_cb             = y0 >> log2_min_cb_size;
+    int ref_idx[2];
+    int mvp_flag[2];
+    int x_pu, y_pu;
+    int i, j;
+
+    if (SAMPLE_CTB(s->skip_flag, x_cb, y_cb)) {
+        if (s->sh.max_num_merge_cand > 1)
+            merge_idx = ff_hevc_merge_idx_decode(s);
+        else
+            merge_idx = 0;
+
+        ff_hevc_luma_mv_merge_mode(s, x0, y0,
+                                   1 << log2_cb_size,
+                                   1 << log2_cb_size,
+                                   log2_cb_size, partIdx,
+                                   merge_idx, &current_mv);
+        x_pu = x0 >> s->sps->log2_min_pu_size;
+        y_pu = y0 >> s->sps->log2_min_pu_size;
+
+        for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
+            for (j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
+                tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
+    } else { /* MODE_INTER */
+        lc->pu.merge_flag = ff_hevc_merge_flag_decode(s);
+        if (lc->pu.merge_flag) {
+            if (s->sh.max_num_merge_cand > 1)
+                merge_idx = ff_hevc_merge_idx_decode(s);
+            else
+                merge_idx = 0;
+
+            ff_hevc_luma_mv_merge_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+                                       partIdx, merge_idx, &current_mv);
+            x_pu = x0 >> s->sps->log2_min_pu_size;
+            y_pu = y0 >> s->sps->log2_min_pu_size;
+
+            for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
+                for (j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
+                    tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
+        } else {
+            enum InterPredIdc inter_pred_idc = PRED_L0;
+            ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
+            if (s->sh.slice_type == B_SLICE)
+                inter_pred_idc = ff_hevc_inter_pred_idc_decode(s, nPbW, nPbH);
+
+            if (inter_pred_idc != PRED_L1) {
+                if (s->sh.nb_refs[L0]) {
+                    ref_idx[0] = ff_hevc_ref_idx_lx_decode(s, s->sh.nb_refs[L0]);
+                    current_mv.ref_idx[0] = ref_idx[0];
+                }
+                current_mv.pred_flag[0] = 1;
+                hls_mvd_coding(s, x0, y0, 0);
+                mvp_flag[0] = ff_hevc_mvp_lx_flag_decode(s);
+                ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+                                         partIdx, merge_idx, &current_mv,
+                                         mvp_flag[0], 0);
+                current_mv.mv[0].x += lc->pu.mvd.x;
+                current_mv.mv[0].y += lc->pu.mvd.y;
+            }
+
+            if (inter_pred_idc != PRED_L0) {
+                if (s->sh.nb_refs[L1]) {
+                    ref_idx[1] = ff_hevc_ref_idx_lx_decode(s, s->sh.nb_refs[L1]);
+                    current_mv.ref_idx[1] = ref_idx[1];
+                }
+
+                if (s->sh.mvd_l1_zero_flag == 1 && inter_pred_idc == PRED_BI) {
+                    lc->pu.mvd.x = 0;
+                    lc->pu.mvd.y = 0;
+                } else {
+                    hls_mvd_coding(s, x0, y0, 1);
+                }
+
+                current_mv.pred_flag[1] = 1;
+                mvp_flag[1] = ff_hevc_mvp_lx_flag_decode(s);
+                ff_hevc_luma_mv_mvp_mode(s, x0, y0, nPbW, nPbH, log2_cb_size,
+                                         partIdx, merge_idx, &current_mv,
+                                         mvp_flag[1], 1);
+                current_mv.mv[1].x += lc->pu.mvd.x;
+                current_mv.mv[1].y += lc->pu.mvd.y;
+            }
+
+            x_pu = x0 >> s->sps->log2_min_pu_size;
+            y_pu = y0 >> s->sps->log2_min_pu_size;
+
+            for (i = 0; i < nPbW >> s->sps->log2_min_pu_size; i++)
+                for(j = 0; j < nPbH >> s->sps->log2_min_pu_size; j++)
+                    tab_mvf[(y_pu + j) * min_pu_width + x_pu + i] = current_mv;
+        }
+    }
+
+    if (current_mv.pred_flag[0]) {
+        ref0 = refPicList[0].ref[current_mv.ref_idx[0]];
+        if (!ref0)
+            return;
+        hevc_await_progress(s, ref0, &current_mv.mv[0], y0, nPbH);
+    }
+    if (current_mv.pred_flag[1]) {
+        ref1 = refPicList[1].ref[current_mv.ref_idx[1]];
+        if (!ref1)
+            return;
+        hevc_await_progress(s, ref1, &current_mv.mv[1], y0, nPbH);
+    }
+
+    if (current_mv.pred_flag[0] && !current_mv.pred_flag[1]) {
+        DECLARE_ALIGNED(16, int16_t,  tmp[MAX_PB_SIZE * MAX_PB_SIZE]);
+        DECLARE_ALIGNED(16, int16_t, tmp2[MAX_PB_SIZE * MAX_PB_SIZE]);
+
+        luma_mc(s, tmp, tmpstride, ref0->frame,
+                &current_mv.mv[0], x0, y0, nPbW, nPbH);
+
+        if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+            (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+            s->hevcdsp.weighted_pred(s->sh.luma_log2_weight_denom,
+                                     s->sh.luma_weight_l0[current_mv.ref_idx[0]],
+                                     s->sh.luma_offset_l0[current_mv.ref_idx[0]],
+                                     dst0, s->frame->linesize[0], tmp,
+                                     tmpstride, nPbW, nPbH);
+        } else {
+            s->hevcdsp.put_unweighted_pred(dst0, s->frame->linesize[0], tmp, tmpstride, nPbW, nPbH);
+        }
+        chroma_mc(s, tmp, tmp2, tmpstride, ref0->frame,
+                  &current_mv.mv[0], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2);
+
+        if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+            (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+            s->hevcdsp.weighted_pred(s->sh.chroma_log2_weight_denom,
+                                     s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0],
+                                     s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0],
+                                     dst1, s->frame->linesize[1], tmp, tmpstride,
+                                     nPbW / 2, nPbH / 2);
+            s->hevcdsp.weighted_pred(s->sh.chroma_log2_weight_denom,
+                                     s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1],
+                                     s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1],
+                                     dst2, s->frame->linesize[2], tmp2, tmpstride,
+                                     nPbW / 2, nPbH / 2);
+        } else {
+            s->hevcdsp.put_unweighted_pred(dst1, s->frame->linesize[1], tmp, tmpstride, nPbW/2, nPbH/2);
+            s->hevcdsp.put_unweighted_pred(dst2, s->frame->linesize[2], tmp2, tmpstride, nPbW/2, nPbH/2);
+        }
+    } else if (!current_mv.pred_flag[0] && current_mv.pred_flag[1]) {
+        DECLARE_ALIGNED(16, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
+        DECLARE_ALIGNED(16, int16_t, tmp2[MAX_PB_SIZE * MAX_PB_SIZE]);
+
+        if (!ref1)
+            return;
+
+        luma_mc(s, tmp, tmpstride, ref1->frame,
+                &current_mv.mv[1], x0, y0, nPbW, nPbH);
+
+        if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+            (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+            s->hevcdsp.weighted_pred(s->sh.luma_log2_weight_denom,
+                                      s->sh.luma_weight_l1[current_mv.ref_idx[1]],
+                                      s->sh.luma_offset_l1[current_mv.ref_idx[1]],
+                                      dst0, s->frame->linesize[0], tmp, tmpstride,
+                                      nPbW, nPbH);
+        } else {
+            s->hevcdsp.put_unweighted_pred(dst0, s->frame->linesize[0], tmp, tmpstride, nPbW, nPbH);
+        }
+
+        chroma_mc(s, tmp, tmp2, tmpstride, ref1->frame,
+                  &current_mv.mv[1], x0/2, y0/2, nPbW/2, nPbH/2);
+
+        if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+            (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+            s->hevcdsp.weighted_pred(s->sh.chroma_log2_weight_denom,
+                                     s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0],
+                                     s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0],
+                                     dst1, s->frame->linesize[1], tmp, tmpstride, nPbW/2, nPbH/2);
+            s->hevcdsp.weighted_pred(s->sh.chroma_log2_weight_denom,
+                                     s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1],
+                                     s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1],
+                                     dst2, s->frame->linesize[2], tmp2, tmpstride, nPbW/2, nPbH/2);
+        } else {
+            s->hevcdsp.put_unweighted_pred(dst1, s->frame->linesize[1], tmp, tmpstride, nPbW/2, nPbH/2);
+            s->hevcdsp.put_unweighted_pred(dst2, s->frame->linesize[2], tmp2, tmpstride, nPbW/2, nPbH/2);
+        }
+    } else if (current_mv.pred_flag[0] && current_mv.pred_flag[1]) {
+        DECLARE_ALIGNED(16, int16_t, tmp [MAX_PB_SIZE * MAX_PB_SIZE]);
+        DECLARE_ALIGNED(16, int16_t, tmp2[MAX_PB_SIZE * MAX_PB_SIZE]);
+        DECLARE_ALIGNED(16, int16_t, tmp3[MAX_PB_SIZE * MAX_PB_SIZE]);
+        DECLARE_ALIGNED(16, int16_t, tmp4[MAX_PB_SIZE * MAX_PB_SIZE]);
+        HEVCFrame *ref0 = refPicList[0].ref[current_mv.ref_idx[0]];
+        HEVCFrame *ref1 = refPicList[1].ref[current_mv.ref_idx[1]];
+
+        if (!ref0 || !ref1)
+            return;
+
+        luma_mc(s, tmp, tmpstride, ref0->frame,
+                &current_mv.mv[0], x0, y0, nPbW, nPbH);
+        luma_mc(s, tmp2, tmpstride, ref1->frame,
+                &current_mv.mv[1], x0, y0, nPbW, nPbH);
+
+        if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+            (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+            s->hevcdsp.weighted_pred_avg(s->sh.luma_log2_weight_denom,
+                                         s->sh.luma_weight_l0[current_mv.ref_idx[0]],
+                                         s->sh.luma_weight_l1[current_mv.ref_idx[1]],
+                                         s->sh.luma_offset_l0[current_mv.ref_idx[0]],
+                                         s->sh.luma_offset_l1[current_mv.ref_idx[1]],
+                                         dst0, s->frame->linesize[0],
+                                         tmp, tmp2, tmpstride, nPbW, nPbH);
+        } else {
+            s->hevcdsp.put_weighted_pred_avg(dst0, s->frame->linesize[0],
+                                             tmp, tmp2, tmpstride, nPbW, nPbH);
+        }
+
+        chroma_mc(s, tmp, tmp2, tmpstride, ref0->frame,
+                  &current_mv.mv[0], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2);
+        chroma_mc(s, tmp3, tmp4, tmpstride, ref1->frame,
+                  &current_mv.mv[1], x0 / 2, y0 / 2, nPbW / 2, nPbH / 2);
+
+        if ((s->sh.slice_type == P_SLICE && s->pps->weighted_pred_flag) ||
+            (s->sh.slice_type == B_SLICE && s->pps->weighted_bipred_flag)) {
+            s->hevcdsp.weighted_pred_avg(s->sh.chroma_log2_weight_denom,
+                                         s->sh.chroma_weight_l0[current_mv.ref_idx[0]][0],
+                                         s->sh.chroma_weight_l1[current_mv.ref_idx[1]][0],
+                                         s->sh.chroma_offset_l0[current_mv.ref_idx[0]][0],
+                                         s->sh.chroma_offset_l1[current_mv.ref_idx[1]][0],
+                                         dst1, s->frame->linesize[1], tmp, tmp3,
+                                         tmpstride, nPbW / 2, nPbH / 2);
+            s->hevcdsp.weighted_pred_avg(s->sh.chroma_log2_weight_denom,
+                                         s->sh.chroma_weight_l0[current_mv.ref_idx[0]][1],
+                                         s->sh.chroma_weight_l1[current_mv.ref_idx[1]][1],
+                                         s->sh.chroma_offset_l0[current_mv.ref_idx[0]][1],
+                                         s->sh.chroma_offset_l1[current_mv.ref_idx[1]][1],
+                                         dst2, s->frame->linesize[2], tmp2, tmp4,
+                                         tmpstride, nPbW / 2, nPbH / 2);
+        } else {
+            s->hevcdsp.put_weighted_pred_avg(dst1, s->frame->linesize[1], tmp, tmp3, tmpstride, nPbW/2, nPbH/2);
+            s->hevcdsp.put_weighted_pred_avg(dst2, s->frame->linesize[2], tmp2, tmp4, tmpstride, nPbW/2, nPbH/2);
+        }
+    }
+}
+
+/**
+ * 8.4.1
+ */
+static int luma_intra_pred_mode(HEVCContext *s, int x0, int y0, int pu_size,
+                                int prev_intra_luma_pred_flag)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    int x_pu             = x0 >> s->sps->log2_min_pu_size;
+    int y_pu             = y0 >> s->sps->log2_min_pu_size;
+    int min_pu_width     = s->sps->min_pu_width;
+    int size_in_pus      = pu_size >> s->sps->log2_min_pu_size;
+    int x0b              = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+    int y0b              = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+    int cand_up   = (lc->ctb_up_flag || y0b) ?
+                    s->tab_ipm[(y_pu - 1) * min_pu_width + x_pu] : INTRA_DC;
+    int cand_left = (lc->ctb_left_flag || x0b) ?
+                    s->tab_ipm[y_pu * min_pu_width + x_pu - 1]   : INTRA_DC;
+
+    int y_ctb = (y0 >> (s->sps->log2_ctb_size)) << (s->sps->log2_ctb_size);
+
+    MvField *tab_mvf = s->ref->tab_mvf;
+    int intra_pred_mode;
+    int candidate[3];
+    int i, j;
+
+    // intra_pred_mode prediction does not cross vertical CTB boundaries
+    if ((y0 - 1) < y_ctb)
+        cand_up = INTRA_DC;
+
+    if (cand_left == cand_up) {
+        if (cand_left < 2) {
+            candidate[0] = INTRA_PLANAR;
+            candidate[1] = INTRA_DC;
+            candidate[2] = INTRA_ANGULAR_26;
+        } else {
+            candidate[0] = cand_left;
+            candidate[1] = 2 + ((cand_left - 2 - 1 + 32) & 31);
+            candidate[2] = 2 + ((cand_left - 2 + 1) & 31);
+        }
+    } else {
+        candidate[0] = cand_left;
+        candidate[1] = cand_up;
+        if (candidate[0] != INTRA_PLANAR && candidate[1] != INTRA_PLANAR) {
+            candidate[2] = INTRA_PLANAR;
+        } else if (candidate[0] != INTRA_DC && candidate[1] != INTRA_DC) {
+            candidate[2] = INTRA_DC;
+        } else {
+            candidate[2] = INTRA_ANGULAR_26;
+        }
+    }
+
+    if (prev_intra_luma_pred_flag) {
+        intra_pred_mode = candidate[lc->pu.mpm_idx];
+    } else {
+        if (candidate[0] > candidate[1])
+            FFSWAP(uint8_t, candidate[0], candidate[1]);
+        if (candidate[0] > candidate[2])
+            FFSWAP(uint8_t, candidate[0], candidate[2]);
+        if (candidate[1] > candidate[2])
+            FFSWAP(uint8_t, candidate[1], candidate[2]);
+
+        intra_pred_mode = lc->pu.rem_intra_luma_pred_mode;
+        for (i = 0; i < 3; i++)
+            if (intra_pred_mode >= candidate[i])
+                intra_pred_mode++;
+    }
+
+    /* write the intra prediction units into the mv array */
+    if (!size_in_pus)
+        size_in_pus = 1;
+    for (i = 0; i < size_in_pus; i++) {
+        memset(&s->tab_ipm[(y_pu + i) * min_pu_width + x_pu],
+               intra_pred_mode, size_in_pus);
+
+        for (j = 0; j < size_in_pus; j++) {
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].is_intra     = 1;
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].pred_flag[0] = 0;
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].pred_flag[1] = 0;
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].ref_idx[0]   = 0;
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].ref_idx[1]   = 0;
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].mv[0].x      = 0;
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].mv[0].y      = 0;
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].mv[1].x      = 0;
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + i].mv[1].y      = 0;
+        }
+    }
+
+    return intra_pred_mode;
+}
+
+static av_always_inline void set_ct_depth(HEVCContext *s, int x0, int y0,
+                                          int log2_cb_size, int ct_depth)
+{
+    int length = (1 << log2_cb_size) >> s->sps->log2_min_cb_size;
+    int x_cb   = x0 >> s->sps->log2_min_cb_size;
+    int y_cb   = y0 >> s->sps->log2_min_cb_size;
+    int y;
+
+    for (y = 0; y < length; y++)
+        memset(&s->tab_ct_depth[(y_cb + y) * s->sps->min_cb_width + x_cb],
+               ct_depth, length);
+}
+
+static void intra_prediction_unit(HEVCContext *s, int x0, int y0,
+                                  int log2_cb_size)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    static const uint8_t intra_chroma_table[4] = { 0, 26, 10, 1 };
+    uint8_t prev_intra_luma_pred_flag[4];
+    int split   = lc->cu.part_mode == PART_NxN;
+    int pb_size = (1 << log2_cb_size) >> split;
+    int side    = split + 1;
+    int chroma_mode;
+    int i, j;
+
+    for (i = 0; i < side; i++)
+        for (j = 0; j < side; j++)
+            prev_intra_luma_pred_flag[2 * i + j] = ff_hevc_prev_intra_luma_pred_flag_decode(s);
+
+    for (i = 0; i < side; i++) {
+        for (j = 0; j < side; j++) {
+            if (prev_intra_luma_pred_flag[2 * i + j])
+                lc->pu.mpm_idx = ff_hevc_mpm_idx_decode(s);
+            else
+                lc->pu.rem_intra_luma_pred_mode = ff_hevc_rem_intra_luma_pred_mode_decode(s);
+
+            lc->pu.intra_pred_mode[2 * i + j] =
+                luma_intra_pred_mode(s, x0 + pb_size * j, y0 + pb_size * i, pb_size,
+                                     prev_intra_luma_pred_flag[2 * i + j]);
+        }
+    }
+
+    chroma_mode = ff_hevc_intra_chroma_pred_mode_decode(s);
+    if (chroma_mode != 4) {
+        if (lc->pu.intra_pred_mode[0] == intra_chroma_table[chroma_mode])
+            lc->pu.intra_pred_mode_c = 34;
+        else
+            lc->pu.intra_pred_mode_c = intra_chroma_table[chroma_mode];
+    } else {
+        lc->pu.intra_pred_mode_c = lc->pu.intra_pred_mode[0];
+    }
+}
+
+static void intra_prediction_unit_default_value(HEVCContext *s,
+                                                int x0, int y0,
+                                                int log2_cb_size)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    int pb_size          = 1 << log2_cb_size;
+    int size_in_pus      = pb_size >> s->sps->log2_min_pu_size;
+    int min_pu_width     = s->sps->min_pu_width;
+    MvField *tab_mvf     = s->ref->tab_mvf;
+    int x_pu             = x0 >> s->sps->log2_min_pu_size;
+    int y_pu             = y0 >> s->sps->log2_min_pu_size;
+    int j, k;
+
+    if (size_in_pus == 0)
+        size_in_pus = 1;
+    for (j = 0; j < size_in_pus; j++) {
+        memset(&s->tab_ipm[(y_pu + j) * min_pu_width + x_pu], INTRA_DC, size_in_pus);
+        for (k = 0; k < size_in_pus; k++)
+            tab_mvf[(y_pu + j) * min_pu_width + x_pu + k].is_intra = lc->cu.pred_mode == MODE_INTRA;
+    }
+}
+
+static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size)
+{
+    int cb_size          = 1 << log2_cb_size;
+    HEVCLocalContext *lc = &s->HEVClc;
+    int log2_min_cb_size = s->sps->log2_min_cb_size;
+    int length           = cb_size >> log2_min_cb_size;
+    int min_cb_width     = s->sps->min_cb_width;
+    int x_cb             = x0 >> log2_min_cb_size;
+    int y_cb             = y0 >> log2_min_cb_size;
+    int x, y;
+
+    lc->cu.x                = x0;
+    lc->cu.y                = y0;
+    lc->cu.rqt_root_cbf     = 1;
+    lc->cu.pred_mode        = MODE_INTRA;
+    lc->cu.part_mode        = PART_2Nx2N;
+    lc->cu.intra_split_flag = 0;
+    lc->cu.pcm_flag         = 0;
+
+    SAMPLE_CTB(s->skip_flag, x_cb, y_cb) = 0;
+    for (x = 0; x < 4; x++)
+        lc->pu.intra_pred_mode[x] = 1;
+    if (s->pps->transquant_bypass_enable_flag) {
+        lc->cu.cu_transquant_bypass_flag = ff_hevc_cu_transquant_bypass_flag_decode(s);
+        if (lc->cu.cu_transquant_bypass_flag)
+            set_deblocking_bypass(s, x0, y0, log2_cb_size);
+    } else
+        lc->cu.cu_transquant_bypass_flag = 0;
+
+    if (s->sh.slice_type != I_SLICE) {
+        uint8_t skip_flag = ff_hevc_skip_flag_decode(s, x0, y0, x_cb, y_cb);
+
+        lc->cu.pred_mode = MODE_SKIP;
+        x = y_cb * min_cb_width + x_cb;
+        for (y = 0; y < length; y++) {
+            memset(&s->skip_flag[x], skip_flag, length);
+            x += min_cb_width;
+        }
+        lc->cu.pred_mode = skip_flag ? MODE_SKIP : MODE_INTER;
+    }
+
+    if (SAMPLE_CTB(s->skip_flag, x_cb, y_cb)) {
+        hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);
+        intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
+
+        if (!s->sh.disable_deblocking_filter_flag)
+            ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,
+                                                  lc->slice_or_tiles_up_boundary,
+                                                  lc->slice_or_tiles_left_boundary);
+    } else {
+        if (s->sh.slice_type != I_SLICE)
+            lc->cu.pred_mode = ff_hevc_pred_mode_decode(s);
+        if (lc->cu.pred_mode != MODE_INTRA ||
+            log2_cb_size == s->sps->log2_min_cb_size) {
+            lc->cu.part_mode        = ff_hevc_part_mode_decode(s, log2_cb_size);
+            lc->cu.intra_split_flag = lc->cu.part_mode == PART_NxN &&
+                                      lc->cu.pred_mode == MODE_INTRA;
+        }
+
+        if (lc->cu.pred_mode == MODE_INTRA) {
+            if (lc->cu.part_mode == PART_2Nx2N && s->sps->pcm_enabled_flag &&
+                log2_cb_size >= s->sps->pcm.log2_min_pcm_cb_size &&
+                log2_cb_size <= s->sps->pcm.log2_max_pcm_cb_size) {
+                lc->cu.pcm_flag = ff_hevc_pcm_flag_decode(s);
+            }
+            if (lc->cu.pcm_flag) {
+                int ret;
+                intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
+                ret = hls_pcm_sample(s, x0, y0, log2_cb_size);
+                if (s->sps->pcm.loop_filter_disable_flag)
+                    set_deblocking_bypass(s, x0, y0, log2_cb_size);
+
+                if (ret < 0)
+                    return ret;
+            } else {
+                intra_prediction_unit(s, x0, y0, log2_cb_size);
+            }
+        } else {
+            intra_prediction_unit_default_value(s, x0, y0, log2_cb_size);
+            switch (lc->cu.part_mode) {
+            case PART_2Nx2N:
+                hls_prediction_unit(s, x0, y0, cb_size, cb_size, log2_cb_size, 0);
+                break;
+            case PART_2NxN:
+                hls_prediction_unit(s, x0, y0,               cb_size, cb_size / 2, log2_cb_size, 0);
+                hls_prediction_unit(s, x0, y0 + cb_size / 2, cb_size, cb_size / 2, log2_cb_size, 1);
+                break;
+            case PART_Nx2N:
+                hls_prediction_unit(s, x0,               y0, cb_size / 2, cb_size, log2_cb_size, 0);
+                hls_prediction_unit(s, x0 + cb_size / 2, y0, cb_size / 2, cb_size, log2_cb_size, 1);
+                break;
+            case PART_2NxnU:
+                hls_prediction_unit(s, x0, y0,               cb_size, cb_size     / 4, log2_cb_size, 0);
+                hls_prediction_unit(s, x0, y0 + cb_size / 4, cb_size, cb_size * 3 / 4, log2_cb_size, 1);
+                break;
+            case PART_2NxnD:
+                hls_prediction_unit(s, x0, y0,                   cb_size, cb_size * 3 / 4, log2_cb_size, 0);
+                hls_prediction_unit(s, x0, y0 + cb_size * 3 / 4, cb_size, cb_size     / 4, log2_cb_size, 1);
+                break;
+            case PART_nLx2N:
+                hls_prediction_unit(s, x0,               y0, cb_size     / 4, cb_size, log2_cb_size, 0);
+                hls_prediction_unit(s, x0 + cb_size / 4, y0, cb_size * 3 / 4, cb_size, log2_cb_size, 1);
+                break;
+            case PART_nRx2N:
+                hls_prediction_unit(s, x0,                   y0, cb_size * 3 / 4, cb_size, log2_cb_size, 0);
+                hls_prediction_unit(s, x0 + cb_size * 3 / 4, y0, cb_size     / 4, cb_size, log2_cb_size, 1);
+                break;
+            case PART_NxN:
+                hls_prediction_unit(s, x0,               y0,               cb_size / 2, cb_size / 2, log2_cb_size, 0);
+                hls_prediction_unit(s, x0 + cb_size / 2, y0,               cb_size / 2, cb_size / 2, log2_cb_size, 1);
+                hls_prediction_unit(s, x0,               y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 2);
+                hls_prediction_unit(s, x0 + cb_size / 2, y0 + cb_size / 2, cb_size / 2, cb_size / 2, log2_cb_size, 3);
+                break;
+            }
+        }
+
+        if (!lc->cu.pcm_flag) {
+            if (lc->cu.pred_mode != MODE_INTRA &&
+                !(lc->cu.part_mode == PART_2Nx2N && lc->pu.merge_flag)) {
+                lc->cu.rqt_root_cbf = ff_hevc_no_residual_syntax_flag_decode(s);
+            }
+            if (lc->cu.rqt_root_cbf) {
+                lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ?
+                                         s->sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag :
+                                         s->sps->max_transform_hierarchy_depth_inter;
+                hls_transform_tree(s, x0, y0, x0, y0, x0, y0, log2_cb_size,
+                                   log2_cb_size, 0, 0);
+            } else {
+                if (!s->sh.disable_deblocking_filter_flag)
+                    ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,
+                                                          lc->slice_or_tiles_up_boundary,
+                                                          lc->slice_or_tiles_left_boundary);
+            }
+        }
+    }
+
+    if (s->pps->cu_qp_delta_enabled_flag && lc->tu.is_cu_qp_delta_coded == 0)
+        ff_hevc_set_qPy(s, x0, y0, x0, y0, log2_cb_size);
+
+    x = y_cb * min_cb_width + x_cb;
+    for (y = 0; y < length; y++) {
+        memset(&s->qp_y_tab[x], lc->qp_y, length);
+        x += min_cb_width;
+    }
+
+    set_ct_depth(s, x0, y0, log2_cb_size, lc->ct.depth);
+
+    return 0;
+}
+
+static int hls_coding_quadtree(HEVCContext *s, int x0, int y0,
+                               int log2_cb_size, int cb_depth)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    const int cb_size    = 1 << log2_cb_size;
+
+    lc->ct.depth = cb_depth;
+    if (x0 + cb_size <= s->sps->width  &&
+        y0 + cb_size <= s->sps->height &&
+        log2_cb_size > s->sps->log2_min_cb_size) {
+        SAMPLE(s->split_cu_flag, x0, y0) =
+            ff_hevc_split_coding_unit_flag_decode(s, cb_depth, x0, y0);
+    } else {
+        SAMPLE(s->split_cu_flag, x0, y0) =
+            (log2_cb_size > s->sps->log2_min_cb_size);
+    }
+    if (s->pps->cu_qp_delta_enabled_flag &&
+        log2_cb_size >= s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth) {
+        lc->tu.is_cu_qp_delta_coded = 0;
+        lc->tu.cu_qp_delta          = 0;
+    }
+
+    if (SAMPLE(s->split_cu_flag, x0, y0)) {
+        const int cb_size_split = cb_size >> 1;
+        const int x1 = x0 + cb_size_split;
+        const int y1 = y0 + cb_size_split;
+
+        log2_cb_size--;
+        cb_depth++;
+
+#define SUBDIVIDE(x, y)                                                \
+do {                                                                   \
+    if (x < s->sps->width && y < s->sps->height) {                     \
+        int ret = hls_coding_quadtree(s, x, y, log2_cb_size, cb_depth);\
+        if (ret < 0)                                                   \
+            return ret;                                                \
+    }                                                                  \
+} while (0)
+
+        SUBDIVIDE(x0, y0);
+        SUBDIVIDE(x1, y0);
+        SUBDIVIDE(x0, y1);
+        SUBDIVIDE(x1, y1);
+    } else {
+        int ret = hls_coding_unit(s, x0, y0, log2_cb_size);
+        if (ret < 0)
+            return ret;
+    }
+
+    return 0;
+}
+
+static void hls_decode_neighbour(HEVCContext *s, int x_ctb, int y_ctb,
+                                 int ctb_addr_ts)
+{
+    HEVCLocalContext *lc  = &s->HEVClc;
+    int ctb_size          = 1 << s->sps->log2_ctb_size;
+    int ctb_addr_rs       = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts];
+    int ctb_addr_in_slice = ctb_addr_rs - s->sh.slice_addr;
+
+    int tile_left_boundary, tile_up_boundary;
+    int slice_left_boundary, slice_up_boundary;
+
+    s->tab_slice_address[ctb_addr_rs] = s->sh.slice_addr;
+
+    if (s->pps->entropy_coding_sync_enabled_flag) {
+        if (x_ctb == 0 && (y_ctb & (ctb_size - 1)) == 0)
+            lc->first_qp_group = 1;
+        lc->end_of_tiles_x = s->sps->width;
+    } else if (s->pps->tiles_enabled_flag) {
+        if (ctb_addr_ts && s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]) {
+            int idxX = s->pps->col_idxX[x_ctb >> s->sps->log2_ctb_size];
+            lc->start_of_tiles_x = x_ctb;
+            lc->end_of_tiles_x   = x_ctb + (s->pps->column_width[idxX] << s->sps->log2_ctb_size);
+            lc->first_qp_group   = 1;
+        }
+    } else {
+        lc->end_of_tiles_x = s->sps->width;
+    }
+
+    lc->end_of_tiles_y = FFMIN(y_ctb + ctb_size, s->sps->height);
+
+    if (s->pps->tiles_enabled_flag) {
+        tile_left_boundary  = x_ctb > 0 &&
+                              s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - 1]];
+        slice_left_boundary = x_ctb > 0 &&
+                              s->tab_slice_address[ctb_addr_rs] == s->tab_slice_address[ctb_addr_rs - 1];
+        tile_up_boundary  = y_ctb > 0 &&
+                            s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - s->sps->ctb_width]];
+        slice_up_boundary = y_ctb > 0 &&
+                            s->tab_slice_address[ctb_addr_rs] == s->tab_slice_address[ctb_addr_rs - s->sps->ctb_width];
+    } else {
+        tile_left_boundary  =
+        tile_up_boundary    = 1;
+        slice_left_boundary = ctb_addr_in_slice > 0;
+        slice_up_boundary   = ctb_addr_in_slice >= s->sps->ctb_width;
+    }
+    lc->slice_or_tiles_left_boundary = (!slice_left_boundary) + (!tile_left_boundary << 1);
+    lc->slice_or_tiles_up_boundary   = (!slice_up_boundary + (!tile_up_boundary << 1));
+    lc->ctb_left_flag = ((x_ctb > 0) && (ctb_addr_in_slice > 0) && tile_left_boundary);
+    lc->ctb_up_flag   = ((y_ctb > 0) && (ctb_addr_in_slice >= s->sps->ctb_width) && tile_up_boundary);
+    lc->ctb_up_right_flag = ((y_ctb > 0)  && (ctb_addr_in_slice+1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs+1 - s->sps->ctb_width]]));
+    lc->ctb_up_left_flag = ((x_ctb > 0) && (y_ctb > 0)  && (ctb_addr_in_slice-1 >= s->sps->ctb_width) && (s->pps->tile_id[ctb_addr_ts] == s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs-1 - s->sps->ctb_width]]));
+}
+
+static int hls_slice_data(HEVCContext *s)
+{
+    int ctb_size    = 1 << s->sps->log2_ctb_size;
+    int more_data   = 1;
+    int x_ctb       = 0;
+    int y_ctb       = 0;
+    int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs];
+    int ret;
+
+    while (more_data && ctb_addr_ts < s->sps->ctb_size) {
+        int ctb_addr_rs = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts];
+
+        x_ctb = (ctb_addr_rs % ((s->sps->width + ctb_size - 1) >> s->sps->log2_ctb_size)) << s->sps->log2_ctb_size;
+        y_ctb = (ctb_addr_rs / ((s->sps->width + ctb_size - 1) >> s->sps->log2_ctb_size)) << s->sps->log2_ctb_size;
+        hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts);
+
+        ff_hevc_cabac_init(s, ctb_addr_ts);
+
+        hls_sao_param(s, x_ctb >> s->sps->log2_ctb_size, y_ctb >> s->sps->log2_ctb_size);
+
+        s->deblock[ctb_addr_rs].beta_offset = s->sh.beta_offset;
+        s->deblock[ctb_addr_rs].tc_offset   = s->sh.tc_offset;
+        s->filter_slice_edges[ctb_addr_rs]  = s->sh.slice_loop_filter_across_slices_enabled_flag;
+
+        ret = hls_coding_quadtree(s, x_ctb, y_ctb, s->sps->log2_ctb_size, 0);
+        if (ret < 0)
+            return ret;
+        more_data = !ff_hevc_end_of_slice_flag_decode(s);
+
+        ctb_addr_ts++;
+        ff_hevc_save_states(s, ctb_addr_ts);
+        ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size);
+    }
+
+    if (x_ctb + ctb_size >= s->sps->width &&
+        y_ctb + ctb_size >= s->sps->height)
+        ff_hevc_hls_filter(s, x_ctb, y_ctb);
+
+    return ctb_addr_ts;
+}
+
+/**
+ * @return AVERROR_INVALIDDATA if the packet is not a valid NAL unit,
+ * 0 if the unit should be skipped, 1 otherwise
+ */
+static int hls_nal_unit(HEVCContext *s)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+    int nuh_layer_id;
+
+    if (get_bits1(gb) != 0)
+        return AVERROR_INVALIDDATA;
+
+    s->nal_unit_type = get_bits(gb, 6);
+
+    nuh_layer_id   = get_bits(gb, 6);
+    s->temporal_id = get_bits(gb, 3) - 1;
+    if (s->temporal_id < 0)
+        return AVERROR_INVALIDDATA;
+
+    av_log(s->avctx, AV_LOG_DEBUG,
+           "nal_unit_type: %d, nuh_layer_id: %dtemporal_id: %d\n",
+           s->nal_unit_type, nuh_layer_id, s->temporal_id);
+
+    return nuh_layer_id == 0;
+}
+
+static void restore_tqb_pixels(HEVCContext *s)
+{
+    int min_pu_size = 1 << s->sps->log2_min_pu_size;
+    int x, y, c_idx;
+
+    for (c_idx = 0; c_idx < 3; c_idx++) {
+        ptrdiff_t stride = s->frame->linesize[c_idx];
+        int hshift       = s->sps->hshift[c_idx];
+        int vshift       = s->sps->vshift[c_idx];
+        for (y = 0; y < s->sps->min_pu_height; y++) {
+            for (x = 0; x < s->sps->min_pu_width; x++) {
+                if (s->is_pcm[y * s->sps->min_pu_width + x]) {
+                    int n;
+                    int len      = min_pu_size >> hshift;
+                    uint8_t *src = &s->frame->data[c_idx][((y << s->sps->log2_min_pu_size) >> vshift) * stride + (((x << s->sps->log2_min_pu_size) >> hshift) << s->sps->pixel_shift)];
+                    uint8_t *dst = &s->sao_frame->data[c_idx][((y << s->sps->log2_min_pu_size) >> vshift) * stride + (((x << s->sps->log2_min_pu_size) >> hshift) << s->sps->pixel_shift)];
+                    for (n = 0; n < (min_pu_size >> vshift); n++) {
+                        memcpy(dst, src, len);
+                        src += stride;
+                        dst += stride;
+                    }
+                }
+            }
+        }
+    }
+}
+
+static int set_side_data(HEVCContext *s)
+{
+    AVFrame *out = s->ref->frame;
+
+    if (s->sei_frame_packing_present &&
+        s->frame_packing_arrangement_type >= 3 &&
+        s->frame_packing_arrangement_type <= 5 &&
+        s->content_interpretation_type > 0 &&
+        s->content_interpretation_type < 3) {
+        AVStereo3D *stereo = av_stereo3d_create_side_data(out);
+        if (!stereo)
+            return AVERROR(ENOMEM);
+
+        switch (s->frame_packing_arrangement_type) {
+        case 3:
+            if (s->quincunx_subsampling)
+                stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+            else
+                stereo->type = AV_STEREO3D_SIDEBYSIDE;
+            break;
+        case 4:
+            stereo->type = AV_STEREO3D_TOPBOTTOM;
+            break;
+        case 5:
+            stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+            break;
+        }
+
+        if (s->content_interpretation_type == 2)
+            stereo->flags = AV_STEREO3D_FLAG_INVERT;
+    }
+
+    return 0;
+}
+
+static int hevc_frame_start(HEVCContext *s)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    int ret;
+
+    memset(s->horizontal_bs, 0, 2 * s->bs_width * (s->bs_height + 1));
+    memset(s->vertical_bs,   0, 2 * s->bs_width * (s->bs_height + 1));
+    memset(s->cbf_luma,      0, s->sps->min_tb_width * s->sps->min_tb_height);
+    memset(s->is_pcm,        0, s->sps->min_pu_width * s->sps->min_pu_height);
+
+    lc->start_of_tiles_x = 0;
+    s->is_decoded        = 0;
+
+    if (s->pps->tiles_enabled_flag)
+        lc->end_of_tiles_x = s->pps->column_width[0] << s->sps->log2_ctb_size;
+
+    ret = ff_hevc_set_new_ref(s, s->sps->sao_enabled ? &s->sao_frame : &s->frame,
+                              s->poc);
+    if (ret < 0)
+        goto fail;
+
+    av_fast_malloc(&lc->edge_emu_buffer, &lc->edge_emu_buffer_size,
+                   (MAX_PB_SIZE + 7) * s->ref->frame->linesize[0]);
+    if (!lc->edge_emu_buffer) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    ret = ff_hevc_frame_rps(s);
+    if (ret < 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "Error constructing the frame RPS.\n");
+        goto fail;
+    }
+
+    ret = set_side_data(s);
+    if (ret < 0)
+        goto fail;
+
+    av_frame_unref(s->output_frame);
+    ret = ff_hevc_output_frame(s, s->output_frame, 0);
+    if (ret < 0)
+        goto fail;
+
+    ff_thread_finish_setup(s->avctx);
+
+    return 0;
+
+fail:
+    if (s->ref)
+        ff_thread_report_progress(&s->ref->tf, INT_MAX, 0);
+    s->ref = NULL;
+    return ret;
+}
+
+static int decode_nal_unit(HEVCContext *s, const uint8_t *nal, int length)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    GetBitContext *gb    = &lc->gb;
+    int ctb_addr_ts, ret;
+
+    ret = init_get_bits8(gb, nal, length);
+    if (ret < 0)
+        return ret;
+
+    ret = hls_nal_unit(s);
+    if (ret < 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n",
+               s->nal_unit_type);
+        if (s->avctx->err_recognition & AV_EF_EXPLODE)
+            return ret;
+        return 0;
+    } else if (!ret)
+        return 0;
+
+    switch (s->nal_unit_type) {
+    case NAL_VPS:
+        ret = ff_hevc_decode_nal_vps(s);
+        if (ret < 0)
+            return ret;
+        break;
+    case NAL_SPS:
+        ret = ff_hevc_decode_nal_sps(s);
+        if (ret < 0)
+            return ret;
+        break;
+    case NAL_PPS:
+        ret = ff_hevc_decode_nal_pps(s);
+        if (ret < 0)
+            return ret;
+        break;
+    case NAL_SEI_PREFIX:
+    case NAL_SEI_SUFFIX:
+        ret = ff_hevc_decode_nal_sei(s);
+        if (ret < 0)
+            return ret;
+        break;
+    case NAL_TRAIL_R:
+    case NAL_TRAIL_N:
+    case NAL_TSA_N:
+    case NAL_TSA_R:
+    case NAL_STSA_N:
+    case NAL_STSA_R:
+    case NAL_BLA_W_LP:
+    case NAL_BLA_W_RADL:
+    case NAL_BLA_N_LP:
+    case NAL_IDR_W_RADL:
+    case NAL_IDR_N_LP:
+    case NAL_CRA_NUT:
+    case NAL_RADL_N:
+    case NAL_RADL_R:
+    case NAL_RASL_N:
+    case NAL_RASL_R:
+        ret = hls_slice_header(s);
+        if (ret < 0)
+            return ret;
+
+        if (s->max_ra == INT_MAX) {
+            if (s->nal_unit_type == NAL_CRA_NUT || IS_BLA(s)) {
+                s->max_ra = s->poc;
+            } else {
+                if (IS_IDR(s))
+                    s->max_ra = INT_MIN;
+            }
+        }
+
+        if ((s->nal_unit_type == NAL_RASL_R || s->nal_unit_type == NAL_RASL_N) &&
+            s->poc <= s->max_ra) {
+            s->is_decoded = 0;
+            break;
+        } else {
+            if (s->nal_unit_type == NAL_RASL_R && s->poc > s->max_ra)
+                s->max_ra = INT_MIN;
+        }
+
+        if (s->sh.first_slice_in_pic_flag) {
+            ret = hevc_frame_start(s);
+            if (ret < 0)
+                return ret;
+        } else if (!s->ref) {
+            av_log(s->avctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (!s->sh.dependent_slice_segment_flag &&
+            s->sh.slice_type != I_SLICE) {
+            ret = ff_hevc_slice_rpl(s);
+            if (ret < 0) {
+                av_log(s->avctx, AV_LOG_WARNING,
+                       "Error constructing the reference lists for the current slice.\n");
+                if (s->avctx->err_recognition & AV_EF_EXPLODE)
+                    return ret;
+            }
+        }
+
+        ctb_addr_ts = hls_slice_data(s);
+        if (ctb_addr_ts >= (s->sps->ctb_width * s->sps->ctb_height)) {
+            s->is_decoded = 1;
+            if ((s->pps->transquant_bypass_enable_flag ||
+                 (s->sps->pcm.loop_filter_disable_flag && s->sps->pcm_enabled_flag)) &&
+                s->sps->sao_enabled)
+                restore_tqb_pixels(s);
+        }
+
+        if (ctb_addr_ts < 0)
+            return ctb_addr_ts;
+        break;
+    case NAL_EOS_NUT:
+    case NAL_EOB_NUT:
+        s->seq_decode = (s->seq_decode + 1) & 0xff;
+        s->max_ra     = INT_MAX;
+        break;
+    case NAL_AUD:
+    case NAL_FD_NUT:
+        break;
+    default:
+        av_log(s->avctx, AV_LOG_INFO,
+               "Skipping NAL unit %d\n", s->nal_unit_type);
+    }
+
+    return 0;
+}
+
+/* FIXME: This is adapted from ff_h264_decode_nal, avoiding duplication
+ * between these functions would be nice. */
+static int extract_rbsp(const uint8_t *src, int length,
+                        HEVCNAL *nal)
+{
+    int i, si, di;
+    uint8_t *dst;
+
+#define STARTCODE_TEST                                                  \
+        if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) {     \
+            if (src[i + 2] != 3) {                                      \
+                /* startcode, so we must be past the end */             \
+                length = i;                                             \
+            }                                                           \
+            break;                                                      \
+        }
+#if HAVE_FAST_UNALIGNED
+#define FIND_FIRST_ZERO                                                 \
+        if (i > 0 && !src[i])                                           \
+            i--;                                                        \
+        while (src[i])                                                  \
+            i++
+#if HAVE_FAST_64BIT
+    for (i = 0; i + 1 < length; i += 9) {
+        if (!((~AV_RN64A(src + i) &
+               (AV_RN64A(src + i) - 0x0100010001000101ULL)) &
+              0x8000800080008080ULL))
+            continue;
+        FIND_FIRST_ZERO;
+        STARTCODE_TEST;
+        i -= 7;
+    }
+#else
+    for (i = 0; i + 1 < length; i += 5) {
+        if (!((~AV_RN32A(src + i) &
+               (AV_RN32A(src + i) - 0x01000101U)) &
+              0x80008080U))
+            continue;
+        FIND_FIRST_ZERO;
+        STARTCODE_TEST;
+        i -= 3;
+    }
+#endif /* HAVE_FAST_64BIT */
+#else
+    for (i = 0; i + 1 < length; i += 2) {
+        if (src[i])
+            continue;
+        if (i > 0 && src[i - 1] == 0)
+            i--;
+        STARTCODE_TEST;
+    }
+#endif /* HAVE_FAST_UNALIGNED */
+
+    if (i >= length - 1) { // no escaped 0
+        nal->data = src;
+        nal->size = length;
+        return length;
+    }
+
+    av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size,
+                   length + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!nal->rbsp_buffer)
+        return AVERROR(ENOMEM);
+
+    dst = nal->rbsp_buffer;
+
+    memcpy(dst, src, i);
+    si = di = i;
+    while (si + 2 < length) {
+        // remove escapes (very rare 1:2^22)
+        if (src[si + 2] > 3) {
+            dst[di++] = src[si++];
+            dst[di++] = src[si++];
+        } else if (src[si] == 0 && src[si + 1] == 0) {
+            if (src[si + 2] == 3) { // escape
+                dst[di++] = 0;
+                dst[di++] = 0;
+                si       += 3;
+
+                continue;
+            } else // next start code
+                goto nsc;
+        }
+
+        dst[di++] = src[si++];
+    }
+    while (si < length)
+        dst[di++] = src[si++];
+
+nsc:
+    memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+    nal->data = dst;
+    nal->size = di;
+    return si;
+}
+
+static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length)
+{
+    int i, consumed, ret = 0;
+
+    s->ref = NULL;
+    s->eos = 0;
+
+    /* split the input packet into NAL units, so we know the upper bound on the
+     * number of slices in the frame */
+    s->nb_nals = 0;
+    while (length >= 4) {
+        HEVCNAL *nal;
+        int extract_length = 0;
+
+        if (s->is_nalff) {
+            int i;
+            for (i = 0; i < s->nal_length_size; i++)
+                extract_length = (extract_length << 8) | buf[i];
+            buf    += s->nal_length_size;
+            length -= s->nal_length_size;
+
+            if (extract_length > length) {
+                av_log(s->avctx, AV_LOG_ERROR, "Invalid NAL unit size.\n");
+                ret = AVERROR_INVALIDDATA;
+                goto fail;
+            }
+        } else {
+            if (buf[2] == 0) {
+                length--;
+                buf++;
+                continue;
+            }
+            if (buf[0] != 0 || buf[1] != 0 || buf[2] != 1) {
+                ret = AVERROR_INVALIDDATA;
+                goto fail;
+            }
+
+            buf           += 3;
+            length        -= 3;
+            extract_length = length;
+        }
+
+        if (s->nals_allocated < s->nb_nals + 1) {
+            int new_size = s->nals_allocated + 1;
+            HEVCNAL *tmp = av_realloc_array(s->nals, new_size, sizeof(*tmp));
+            if (!tmp) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+            s->nals = tmp;
+            memset(s->nals + s->nals_allocated, 0,
+                   (new_size - s->nals_allocated) * sizeof(*tmp));
+            s->nals_allocated = new_size;
+        }
+        nal = &s->nals[s->nb_nals++];
+
+        consumed = extract_rbsp(buf, extract_length, nal);
+        if (consumed < 0) {
+            ret = consumed;
+            goto fail;
+        }
+
+        ret = init_get_bits8(&s->HEVClc.gb, nal->data, nal->size);
+        if (ret < 0)
+            goto fail;
+        hls_nal_unit(s);
+
+        if (s->nal_unit_type == NAL_EOB_NUT ||
+            s->nal_unit_type == NAL_EOS_NUT)
+            s->eos = 1;
+
+        buf    += consumed;
+        length -= consumed;
+    }
+
+    /* parse the NAL units */
+    for (i = 0; i < s->nb_nals; i++) {
+        int ret = decode_nal_unit(s, s->nals[i].data, s->nals[i].size);
+        if (ret < 0) {
+            av_log(s->avctx, AV_LOG_WARNING,
+                   "Error parsing NAL unit #%d.\n", i);
+            if (s->avctx->err_recognition & AV_EF_EXPLODE)
+                goto fail;
+        }
+    }
+
+fail:
+    if (s->ref)
+        ff_thread_report_progress(&s->ref->tf, INT_MAX, 0);
+
+    return ret;
+}
+
+static void print_md5(void *log_ctx, int level, uint8_t md5[16])
+{
+    int i;
+    for (i = 0; i < 16; i++)
+        av_log(log_ctx, level, "%02"PRIx8, md5[i]);
+}
+
+static int verify_md5(HEVCContext *s, AVFrame *frame)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+    int pixel_shift;
+    int i, j;
+
+    if (!desc)
+        return AVERROR(EINVAL);
+
+    pixel_shift = desc->comp[0].depth_minus1 > 7;
+
+    av_log(s->avctx, AV_LOG_DEBUG, "Verifying checksum for frame with POC %d: ",
+           s->poc);
+
+    /* the checksums are LE, so we have to byteswap for >8bpp formats
+     * on BE arches */
+#if HAVE_BIGENDIAN
+    if (pixel_shift && !s->checksum_buf) {
+        av_fast_malloc(&s->checksum_buf, &s->checksum_buf_size,
+                       FFMAX3(frame->linesize[0], frame->linesize[1],
+                              frame->linesize[2]));
+        if (!s->checksum_buf)
+            return AVERROR(ENOMEM);
+    }
+#endif
+
+    for (i = 0; frame->data[i]; i++) {
+        int width  = s->avctx->coded_width;
+        int height = s->avctx->coded_height;
+        int w = (i == 1 || i == 2) ? (width  >> desc->log2_chroma_w) : width;
+        int h = (i == 1 || i == 2) ? (height >> desc->log2_chroma_h) : height;
+        uint8_t md5[16];
+
+        av_md5_init(s->md5_ctx);
+        for (j = 0; j < h; j++) {
+            const uint8_t *src = frame->data[i] + j * frame->linesize[i];
+#if HAVE_BIGENDIAN
+            if (pixel_shift) {
+                s->dsp.bswap16_buf((uint16_t*)s->checksum_buf,
+                                   (const uint16_t*)src, w);
+                src = s->checksum_buf;
+            }
+#endif
+            av_md5_update(s->md5_ctx, src, w << pixel_shift);
+        }
+        av_md5_final(s->md5_ctx, md5);
+
+        if (!memcmp(md5, s->md5[i], 16)) {
+            av_log   (s->avctx, AV_LOG_DEBUG, "plane %d - correct ", i);
+            print_md5(s->avctx, AV_LOG_DEBUG, md5);
+            av_log   (s->avctx, AV_LOG_DEBUG, "; ");
+        } else {
+            av_log   (s->avctx, AV_LOG_ERROR, "mismatching checksum of plane %d - ", i);
+            print_md5(s->avctx, AV_LOG_ERROR, md5);
+            av_log   (s->avctx, AV_LOG_ERROR, " != ");
+            print_md5(s->avctx, AV_LOG_ERROR, s->md5[i]);
+            av_log   (s->avctx, AV_LOG_ERROR, "\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    av_log(s->avctx, AV_LOG_DEBUG, "\n");
+
+    return 0;
+}
+
+static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output,
+                             AVPacket *avpkt)
+{
+    int ret;
+    HEVCContext *s = avctx->priv_data;
+
+    if (!avpkt->size) {
+        ret = ff_hevc_output_frame(s, data, 1);
+        if (ret < 0)
+            return ret;
+
+        *got_output = ret;
+        return 0;
+    }
+
+    s->ref = NULL;
+    ret    = decode_nal_units(s, avpkt->data, avpkt->size);
+    if (ret < 0)
+        return ret;
+
+    /* verify the SEI checksum */
+    if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded &&
+        s->is_md5) {
+        ret = verify_md5(s, s->ref->frame);
+        if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) {
+            ff_hevc_unref_frame(s, s->ref, ~0);
+            return ret;
+        }
+    }
+    s->is_md5 = 0;
+
+    if (s->is_decoded) {
+        av_log(avctx, AV_LOG_DEBUG, "Decoded frame with POC %d.\n", s->poc);
+        s->is_decoded = 0;
+    }
+
+    if (s->output_frame->buf[0]) {
+        av_frame_move_ref(data, s->output_frame);
+        *got_output = 1;
+    }
+
+    return avpkt->size;
+}
+
+static int hevc_ref_frame(HEVCContext *s, HEVCFrame *dst, HEVCFrame *src)
+{
+    int ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+    if (ret < 0)
+        return ret;
+
+    dst->tab_mvf_buf = av_buffer_ref(src->tab_mvf_buf);
+    if (!dst->tab_mvf_buf)
+        goto fail;
+    dst->tab_mvf = src->tab_mvf;
+
+    dst->rpl_tab_buf = av_buffer_ref(src->rpl_tab_buf);
+    if (!dst->rpl_tab_buf)
+        goto fail;
+    dst->rpl_tab = src->rpl_tab;
+
+    dst->rpl_buf = av_buffer_ref(src->rpl_buf);
+    if (!dst->rpl_buf)
+        goto fail;
+
+    dst->poc        = src->poc;
+    dst->ctb_count  = src->ctb_count;
+    dst->window     = src->window;
+    dst->flags      = src->flags;
+    dst->sequence   = src->sequence;
+
+    return 0;
+fail:
+    ff_hevc_unref_frame(s, dst, ~0);
+    return AVERROR(ENOMEM);
+}
+
+static av_cold int hevc_decode_free(AVCodecContext *avctx)
+{
+    HEVCContext       *s = avctx->priv_data;
+    HEVCLocalContext *lc = &s->HEVClc;
+    int i;
+
+    pic_arrays_free(s);
+
+    av_freep(&lc->edge_emu_buffer);
+    av_freep(&s->md5_ctx);
+
+    av_frame_free(&s->tmp_frame);
+    av_frame_free(&s->output_frame);
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        ff_hevc_unref_frame(s, &s->DPB[i], ~0);
+        av_frame_free(&s->DPB[i].frame);
+    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->vps_list); i++)
+        av_buffer_unref(&s->vps_list[i]);
+    for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++)
+        av_buffer_unref(&s->sps_list[i]);
+    for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++)
+        av_buffer_unref(&s->pps_list[i]);
+
+    for (i = 0; i < s->nals_allocated; i++)
+        av_freep(&s->nals[i].rbsp_buffer);
+    av_freep(&s->nals);
+    s->nals_allocated = 0;
+
+    return 0;
+}
+
+static av_cold int hevc_init_context(AVCodecContext *avctx)
+{
+    HEVCContext *s = avctx->priv_data;
+    int i;
+
+    s->avctx = avctx;
+
+    s->tmp_frame = av_frame_alloc();
+    if (!s->tmp_frame)
+        goto fail;
+
+    s->output_frame = av_frame_alloc();
+    if (!s->output_frame)
+        goto fail;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        s->DPB[i].frame = av_frame_alloc();
+        if (!s->DPB[i].frame)
+            goto fail;
+        s->DPB[i].tf.f = s->DPB[i].frame;
+    }
+
+    s->max_ra = INT_MAX;
+
+    s->md5_ctx = av_md5_alloc();
+    if (!s->md5_ctx)
+        goto fail;
+
+    ff_dsputil_init(&s->dsp, avctx);
+
+    s->context_initialized = 1;
+
+    return 0;
+
+fail:
+    hevc_decode_free(avctx);
+    return AVERROR(ENOMEM);
+}
+
+static int hevc_update_thread_context(AVCodecContext *dst,
+                                      const AVCodecContext *src)
+{
+    HEVCContext *s  = dst->priv_data;
+    HEVCContext *s0 = src->priv_data;
+    int i, ret;
+
+    if (!s->context_initialized) {
+        ret = hevc_init_context(dst);
+        if (ret < 0)
+            return ret;
+    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        ff_hevc_unref_frame(s, &s->DPB[i], ~0);
+        if (s0->DPB[i].frame->buf[0]) {
+            ret = hevc_ref_frame(s, &s->DPB[i], &s0->DPB[i]);
+            if (ret < 0)
+                return ret;
+        }
+    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->vps_list); i++) {
+        av_buffer_unref(&s->vps_list[i]);
+        if (s0->vps_list[i]) {
+            s->vps_list[i] = av_buffer_ref(s0->vps_list[i]);
+            if (!s->vps_list[i])
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++) {
+        av_buffer_unref(&s->sps_list[i]);
+        if (s0->sps_list[i]) {
+            s->sps_list[i] = av_buffer_ref(s0->sps_list[i]);
+            if (!s->sps_list[i])
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++) {
+        av_buffer_unref(&s->pps_list[i]);
+        if (s0->pps_list[i]) {
+            s->pps_list[i] = av_buffer_ref(s0->pps_list[i]);
+            if (!s->pps_list[i])
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    if (s->sps != s0->sps)
+        ret = set_sps(s, s0->sps);
+
+    s->seq_decode = s0->seq_decode;
+    s->seq_output = s0->seq_output;
+    s->pocTid0    = s0->pocTid0;
+    s->max_ra     = s0->max_ra;
+
+    s->is_nalff        = s0->is_nalff;
+    s->nal_length_size = s0->nal_length_size;
+
+    if (s0->eos) {
+        s->seq_decode = (s->seq_decode + 1) & 0xff;
+        s->max_ra = INT_MAX;
+    }
+
+    return 0;
+}
+
+static int hevc_decode_extradata(HEVCContext *s)
+{
+    AVCodecContext *avctx = s->avctx;
+    GetByteContext gb;
+    int ret;
+
+    bytestream2_init(&gb, avctx->extradata, avctx->extradata_size);
+
+    if (avctx->extradata_size > 3 &&
+        (avctx->extradata[0] || avctx->extradata[1] ||
+         avctx->extradata[2] > 1)) {
+        /* It seems the extradata is encoded as hvcC format.
+         * Temporarily, we support configurationVersion==0 until 14496-15 3rd
+         * is finalized. When finalized, configurationVersion will be 1 and we
+         * can recognize hvcC by checking if avctx->extradata[0]==1 or not. */
+        int i, j, num_arrays, nal_len_size;
+
+        s->is_nalff = 1;
+
+        bytestream2_skip(&gb, 21);
+        nal_len_size = (bytestream2_get_byte(&gb) & 3) + 1;
+        num_arrays   = bytestream2_get_byte(&gb);
+
+        /* nal units in the hvcC always have length coded with 2 bytes,
+         * so put a fake nal_length_size = 2 while parsing them */
+        s->nal_length_size = 2;
+
+        /* Decode nal units from hvcC. */
+        for (i = 0; i < num_arrays; i++) {
+            int type = bytestream2_get_byte(&gb) & 0x3f;
+            int cnt  = bytestream2_get_be16(&gb);
+
+            for (j = 0; j < cnt; j++) {
+                // +2 for the nal size field
+                int nalsize = bytestream2_peek_be16(&gb) + 2;
+                if (bytestream2_get_bytes_left(&gb) < nalsize) {
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "Invalid NAL unit size in extradata.\n");
+                    return AVERROR_INVALIDDATA;
+                }
+
+                ret = decode_nal_units(s, gb.buffer, nalsize);
+                if (ret < 0) {
+                    av_log(avctx, AV_LOG_ERROR,
+                           "Decoding nal unit %d %d from hvcC failed\n",
+                           type, i);
+                    return ret;
+                }
+                bytestream2_skip(&gb, nalsize);
+            }
+        }
+
+        /* Now store right nal length size, that will be used to parse
+         * all other nals */
+        s->nal_length_size = nal_len_size;
+    } else {
+        s->is_nalff = 0;
+        ret = decode_nal_units(s, avctx->extradata, avctx->extradata_size);
+        if (ret < 0)
+            return ret;
+    }
+    return 0;
+}
+
+static av_cold int hevc_decode_init(AVCodecContext *avctx)
+{
+    HEVCContext *s = avctx->priv_data;
+    int ret;
+
+    ff_init_cabac_states();
+
+    avctx->internal->allocate_progress = 1;
+
+    ret = hevc_init_context(avctx);
+    if (ret < 0)
+        return ret;
+
+    if (avctx->extradata_size > 0 && avctx->extradata) {
+        ret = hevc_decode_extradata(s);
+        if (ret < 0) {
+            hevc_decode_free(avctx);
+            return ret;
+        }
+    }
+
+    return 0;
+}
+
+static av_cold int hevc_init_thread_copy(AVCodecContext *avctx)
+{
+    HEVCContext *s = avctx->priv_data;
+    int ret;
+
+    memset(s, 0, sizeof(*s));
+
+    ret = hevc_init_context(avctx);
+    if (ret < 0)
+        return ret;
+
+    return 0;
+}
+
+static void hevc_decode_flush(AVCodecContext *avctx)
+{
+    HEVCContext *s = avctx->priv_data;
+    ff_hevc_flush_dpb(s);
+    s->max_ra = INT_MAX;
+}
+
+#define OFFSET(x) offsetof(HEVCContext, x)
+#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
+static const AVOption options[] = {
+    { "apply_defdispwin", "Apply default display window from VUI", OFFSET(apply_defdispwin),
+        AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, PAR },
+    { NULL },
+};
+
+static const AVClass hevc_decoder_class = {
+    .class_name = "HEVC decoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_hevc_decoder = {
+    .name                  = "hevc",
+    .long_name             = NULL_IF_CONFIG_SMALL("HEVC (High Efficiency Video Coding)"),
+    .type                  = AVMEDIA_TYPE_VIDEO,
+    .id                    = AV_CODEC_ID_HEVC,
+    .priv_data_size        = sizeof(HEVCContext),
+    .priv_class            = &hevc_decoder_class,
+    .init                  = hevc_decode_init,
+    .close                 = hevc_decode_free,
+    .decode                = hevc_decode_frame,
+    .flush                 = hevc_decode_flush,
+    .update_thread_context = hevc_update_thread_context,
+    .init_thread_copy      = hevc_init_thread_copy,
+    .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_DELAY |
+                             CODEC_CAP_FRAME_THREADS,
+};
diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h
new file mode 100644
index 0000000..bd6f50f
--- /dev/null
+++ b/libavcodec/hevc.h
@@ -0,0 +1,1072 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * 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_HEVC_H
+#define AVCODEC_HEVC_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/buffer.h"
+#include "libavutil/md5.h"
+
+#include "avcodec.h"
+#include "cabac.h"
+#include "dsputil.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "thread.h"
+#include "videodsp.h"
+
+#define MAX_DPB_SIZE 16 // A.4.1
+#define MAX_REFS 16
+
+/**
+ * 7.4.2.1
+ */
+#define MAX_SUB_LAYERS 7
+#define MAX_VPS_COUNT 16
+#define MAX_SPS_COUNT 32
+#define MAX_PPS_COUNT 256
+#define MAX_SHORT_TERM_RPS_COUNT 64
+#define MAX_CU_SIZE 128
+
+//TODO: check if this is really the maximum
+#define MAX_TRANSFORM_DEPTH 5
+
+#define MAX_TB_SIZE 32
+#define MAX_PB_SIZE 64
+#define MAX_LOG2_CTB_SIZE 6
+#define MAX_QP 51
+#define DEFAULT_INTRA_TC_OFFSET 2
+
+#define HEVC_CONTEXTS 183
+
+#define MRG_MAX_NUM_CANDS     5
+
+#define L0 0
+#define L1 1
+
+#define EPEL_EXTRA_BEFORE 1
+#define EPEL_EXTRA_AFTER  2
+#define EPEL_EXTRA        3
+
+/**
+ * Value of the luma sample at position (x, y) in the 2D array tab.
+ */
+#define SAMPLE(tab, x, y) ((tab)[(y) * s->sps->width + (x)])
+#define SAMPLE_CTB(tab, x, y) ((tab)[(y) * min_cb_width + (x)])
+#define SAMPLE_CBF(tab, x, y) ((tab)[((y) & ((1<<log2_trafo_size)-1)) * MAX_CU_SIZE + ((x) & ((1<<log2_trafo_size)-1))])
+
+#define IS_IDR(s) (s->nal_unit_type == NAL_IDR_W_RADL || s->nal_unit_type == NAL_IDR_N_LP)
+#define IS_BLA(s) (s->nal_unit_type == NAL_BLA_W_RADL || s->nal_unit_type == NAL_BLA_W_LP || \
+                   s->nal_unit_type == NAL_BLA_N_LP)
+#define IS_IRAP(s) (s->nal_unit_type >= 16 && s->nal_unit_type <= 23)
+
+/**
+ * Table 7-3: NAL unit type codes
+ */
+enum NALUnitType {
+    NAL_TRAIL_N    = 0,
+    NAL_TRAIL_R    = 1,
+    NAL_TSA_N      = 2,
+    NAL_TSA_R      = 3,
+    NAL_STSA_N     = 4,
+    NAL_STSA_R     = 5,
+    NAL_RADL_N     = 6,
+    NAL_RADL_R     = 7,
+    NAL_RASL_N     = 8,
+    NAL_RASL_R     = 9,
+    NAL_BLA_W_LP   = 16,
+    NAL_BLA_W_RADL = 17,
+    NAL_BLA_N_LP   = 18,
+    NAL_IDR_W_RADL = 19,
+    NAL_IDR_N_LP   = 20,
+    NAL_CRA_NUT    = 21,
+    NAL_VPS        = 32,
+    NAL_SPS        = 33,
+    NAL_PPS        = 34,
+    NAL_AUD        = 35,
+    NAL_EOS_NUT    = 36,
+    NAL_EOB_NUT    = 37,
+    NAL_FD_NUT     = 38,
+    NAL_SEI_PREFIX = 39,
+    NAL_SEI_SUFFIX = 40,
+};
+
+enum RPSType {
+    ST_CURR_BEF = 0,
+    ST_CURR_AFT,
+    ST_FOLL,
+    LT_CURR,
+    LT_FOLL,
+    NB_RPS_TYPE,
+};
+
+enum SliceType {
+    B_SLICE = 0,
+    P_SLICE = 1,
+    I_SLICE = 2,
+};
+
+enum SyntaxElement {
+    SAO_MERGE_FLAG = 0,
+    SAO_TYPE_IDX,
+    SAO_EO_CLASS,
+    SAO_BAND_POSITION,
+    SAO_OFFSET_ABS,
+    SAO_OFFSET_SIGN,
+    END_OF_SLICE_FLAG,
+    SPLIT_CODING_UNIT_FLAG,
+    CU_TRANSQUANT_BYPASS_FLAG,
+    SKIP_FLAG,
+    CU_QP_DELTA,
+    PRED_MODE_FLAG,
+    PART_MODE,
+    PCM_FLAG,
+    PREV_INTRA_LUMA_PRED_FLAG,
+    MPM_IDX,
+    REM_INTRA_LUMA_PRED_MODE,
+    INTRA_CHROMA_PRED_MODE,
+    MERGE_FLAG,
+    MERGE_IDX,
+    INTER_PRED_IDC,
+    REF_IDX_L0,
+    REF_IDX_L1,
+    ABS_MVD_GREATER0_FLAG,
+    ABS_MVD_GREATER1_FLAG,
+    ABS_MVD_MINUS2,
+    MVD_SIGN_FLAG,
+    MVP_LX_FLAG,
+    NO_RESIDUAL_DATA_FLAG,
+    SPLIT_TRANSFORM_FLAG,
+    CBF_LUMA,
+    CBF_CB_CR,
+    TRANSFORM_SKIP_FLAG,
+    LAST_SIGNIFICANT_COEFF_X_PREFIX,
+    LAST_SIGNIFICANT_COEFF_Y_PREFIX,
+    LAST_SIGNIFICANT_COEFF_X_SUFFIX,
+    LAST_SIGNIFICANT_COEFF_Y_SUFFIX,
+    SIGNIFICANT_COEFF_GROUP_FLAG,
+    SIGNIFICANT_COEFF_FLAG,
+    COEFF_ABS_LEVEL_GREATER1_FLAG,
+    COEFF_ABS_LEVEL_GREATER2_FLAG,
+    COEFF_ABS_LEVEL_REMAINING,
+    COEFF_SIGN_FLAG,
+};
+
+enum PartMode {
+    PART_2Nx2N = 0,
+    PART_2NxN  = 1,
+    PART_Nx2N  = 2,
+    PART_NxN   = 3,
+    PART_2NxnU = 4,
+    PART_2NxnD = 5,
+    PART_nLx2N = 6,
+    PART_nRx2N = 7,
+};
+
+enum PredMode {
+    MODE_INTER = 0,
+    MODE_INTRA,
+    MODE_SKIP,
+};
+
+enum InterPredIdc {
+    PRED_L0 = 0,
+    PRED_L1,
+    PRED_BI,
+};
+
+enum IntraPredMode {
+    INTRA_PLANAR = 0,
+    INTRA_DC,
+    INTRA_ANGULAR_2,
+    INTRA_ANGULAR_3,
+    INTRA_ANGULAR_4,
+    INTRA_ANGULAR_5,
+    INTRA_ANGULAR_6,
+    INTRA_ANGULAR_7,
+    INTRA_ANGULAR_8,
+    INTRA_ANGULAR_9,
+    INTRA_ANGULAR_10,
+    INTRA_ANGULAR_11,
+    INTRA_ANGULAR_12,
+    INTRA_ANGULAR_13,
+    INTRA_ANGULAR_14,
+    INTRA_ANGULAR_15,
+    INTRA_ANGULAR_16,
+    INTRA_ANGULAR_17,
+    INTRA_ANGULAR_18,
+    INTRA_ANGULAR_19,
+    INTRA_ANGULAR_20,
+    INTRA_ANGULAR_21,
+    INTRA_ANGULAR_22,
+    INTRA_ANGULAR_23,
+    INTRA_ANGULAR_24,
+    INTRA_ANGULAR_25,
+    INTRA_ANGULAR_26,
+    INTRA_ANGULAR_27,
+    INTRA_ANGULAR_28,
+    INTRA_ANGULAR_29,
+    INTRA_ANGULAR_30,
+    INTRA_ANGULAR_31,
+    INTRA_ANGULAR_32,
+    INTRA_ANGULAR_33,
+    INTRA_ANGULAR_34,
+};
+
+enum SAOType {
+    SAO_NOT_APPLIED = 0,
+    SAO_BAND,
+    SAO_EDGE,
+};
+
+enum SAOEOClass {
+    SAO_EO_HORIZ = 0,
+    SAO_EO_VERT,
+    SAO_EO_135D,
+    SAO_EO_45D,
+};
+
+enum ScanType {
+    SCAN_DIAG = 0,
+    SCAN_HORIZ,
+    SCAN_VERT,
+};
+
+typedef struct ShortTermRPS {
+    int num_negative_pics;
+    int num_delta_pocs;
+    int32_t delta_poc[32];
+    uint8_t used[32];
+} ShortTermRPS;
+
+typedef struct LongTermRPS {
+    int     poc[32];
+    uint8_t used[32];
+    uint8_t nb_refs;
+} LongTermRPS;
+
+typedef struct RefPicList {
+    struct HEVCFrame *ref[MAX_REFS];
+    int list[MAX_REFS];
+    int isLongTerm[MAX_REFS];
+    int nb_refs;
+} RefPicList;
+
+typedef struct RefPicListTab {
+    RefPicList refPicList[2];
+} RefPicListTab;
+
+typedef struct HEVCWindow {
+    int left_offset;
+    int right_offset;
+    int top_offset;
+    int bottom_offset;
+} HEVCWindow;
+
+typedef struct VUI {
+    AVRational sar;
+
+    int overscan_info_present_flag;
+    int overscan_appropriate_flag;
+
+    int video_signal_type_present_flag;
+    int video_format;
+    int video_full_range_flag;
+    int colour_description_present_flag;
+    uint8_t colour_primaries;
+    uint8_t transfer_characteristic;
+    uint8_t matrix_coeffs;
+
+    int chroma_loc_info_present_flag;
+    int chroma_sample_loc_type_top_field;
+    int chroma_sample_loc_type_bottom_field;
+    int neutra_chroma_indication_flag;
+
+    int field_seq_flag;
+    int frame_field_info_present_flag;
+
+    int default_display_window_flag;
+    HEVCWindow def_disp_win;
+
+    int vui_timing_info_present_flag;
+    uint32_t vui_num_units_in_tick;
+    uint32_t vui_time_scale;
+    int vui_poc_proportional_to_timing_flag;
+    int vui_num_ticks_poc_diff_one_minus1;
+    int vui_hrd_parameters_present_flag;
+
+    int bitstream_restriction_flag;
+    int tiles_fixed_structure_flag;
+    int motion_vectors_over_pic_boundaries_flag;
+    int restricted_ref_pic_lists_flag;
+    int min_spatial_segmentation_idc;
+    int max_bytes_per_pic_denom;
+    int max_bits_per_min_cu_denom;
+    int log2_max_mv_length_horizontal;
+    int log2_max_mv_length_vertical;
+} VUI;
+
+typedef struct PTL {
+    int general_profile_space;
+    uint8_t general_tier_flag;
+    int general_profile_idc;
+    int general_profile_compatibility_flag[32];
+    int general_level_idc;
+
+    uint8_t sub_layer_profile_present_flag[MAX_SUB_LAYERS];
+    uint8_t sub_layer_level_present_flag[MAX_SUB_LAYERS];
+
+    int sub_layer_profile_space[MAX_SUB_LAYERS];
+    uint8_t sub_layer_tier_flag[MAX_SUB_LAYERS];
+    int sub_layer_profile_idc[MAX_SUB_LAYERS];
+    uint8_t sub_layer_profile_compatibility_flags[MAX_SUB_LAYERS][32];
+    int sub_layer_level_idc[MAX_SUB_LAYERS];
+} PTL;
+
+typedef struct HEVCVPS {
+    uint8_t vps_temporal_id_nesting_flag;
+    int vps_max_layers;
+    int vps_max_sub_layers; ///< vps_max_temporal_layers_minus1 + 1
+
+    PTL ptl;
+    int vps_sub_layer_ordering_info_present_flag;
+    unsigned int vps_max_dec_pic_buffering[MAX_SUB_LAYERS];
+    unsigned int vps_num_reorder_pics[MAX_SUB_LAYERS];
+    unsigned int vps_max_latency_increase[MAX_SUB_LAYERS];
+    int vps_max_layer_id;
+    int vps_num_layer_sets; ///< vps_num_layer_sets_minus1 + 1
+    uint8_t vps_timing_info_present_flag;
+    uint32_t vps_num_units_in_tick;
+    uint32_t vps_time_scale;
+    uint8_t vps_poc_proportional_to_timing_flag;
+    int vps_num_ticks_poc_diff_one; ///< vps_num_ticks_poc_diff_one_minus1 + 1
+    int vps_num_hrd_parameters;
+} HEVCVPS;
+
+typedef struct ScalingList {
+    /* This is a little wasteful, since sizeID 0 only needs 8 coeffs,
+     * and size ID 3 only has 2 arrays, not 6. */
+    uint8_t sl[4][6][64];
+    uint8_t sl_dc[2][6];
+} ScalingList;
+
+typedef struct HEVCSPS {
+    int vps_id;
+    int chroma_format_idc;
+    uint8_t separate_colour_plane_flag;
+
+    ///< output (i.e. cropped) values
+    int output_width, output_height;
+    HEVCWindow output_window;
+
+    HEVCWindow pic_conf_win;
+
+    int bit_depth;
+    int pixel_shift;
+    enum AVPixelFormat pix_fmt;
+
+    unsigned int log2_max_poc_lsb;
+    int pcm_enabled_flag;
+
+    int max_sub_layers;
+    struct {
+        int max_dec_pic_buffering;
+        int num_reorder_pics;
+        int max_latency_increase;
+    } temporal_layer[MAX_SUB_LAYERS];
+
+    VUI vui;
+    PTL ptl;
+
+    uint8_t scaling_list_enable_flag;
+    ScalingList scaling_list;
+
+    unsigned int nb_st_rps;
+    ShortTermRPS st_rps[MAX_SHORT_TERM_RPS_COUNT];
+
+    uint8_t amp_enabled_flag;
+    uint8_t sao_enabled;
+
+    uint8_t long_term_ref_pics_present_flag;
+    uint16_t lt_ref_pic_poc_lsb_sps[32];
+    uint8_t used_by_curr_pic_lt_sps_flag[32];
+    uint8_t num_long_term_ref_pics_sps;
+
+    struct {
+        uint8_t bit_depth;
+        unsigned int log2_min_pcm_cb_size;
+        unsigned int log2_max_pcm_cb_size;
+        uint8_t loop_filter_disable_flag;
+    } pcm;
+    uint8_t sps_temporal_mvp_enabled_flag;
+    uint8_t sps_strong_intra_smoothing_enable_flag;
+
+    unsigned int log2_min_cb_size;
+    unsigned int log2_diff_max_min_coding_block_size;
+    unsigned int log2_min_tb_size;
+    unsigned int log2_max_trafo_size;
+    unsigned int log2_ctb_size;
+    unsigned int log2_min_pu_size;
+
+    int max_transform_hierarchy_depth_inter;
+    int max_transform_hierarchy_depth_intra;
+
+    ///< coded frame dimension in various units
+    int width;
+    int height;
+    int ctb_width;
+    int ctb_height;
+    int ctb_size;
+    int min_cb_width;
+    int min_cb_height;
+    int min_tb_width;
+    int min_tb_height;
+    int min_pu_width;
+    int min_pu_height;
+
+    int hshift[3];
+    int vshift[3];
+
+    int qp_bd_offset;
+} HEVCSPS;
+
+typedef struct HEVCPPS {
+    int sps_id; ///< seq_parameter_set_id
+
+    uint8_t sign_data_hiding_flag;
+
+    uint8_t cabac_init_present_flag;
+
+    int num_ref_idx_l0_default_active; ///< num_ref_idx_l0_default_active_minus1 + 1
+    int num_ref_idx_l1_default_active; ///< num_ref_idx_l1_default_active_minus1 + 1
+    int pic_init_qp_minus26;
+
+    uint8_t constrained_intra_pred_flag;
+    uint8_t transform_skip_enabled_flag;
+
+    uint8_t cu_qp_delta_enabled_flag;
+    int diff_cu_qp_delta_depth;
+
+    int cb_qp_offset;
+    int cr_qp_offset;
+    uint8_t pic_slice_level_chroma_qp_offsets_present_flag;
+    uint8_t weighted_pred_flag;
+    uint8_t weighted_bipred_flag;
+    uint8_t output_flag_present_flag;
+    uint8_t transquant_bypass_enable_flag;
+
+    uint8_t dependent_slice_segments_enabled_flag;
+    uint8_t tiles_enabled_flag;
+    uint8_t entropy_coding_sync_enabled_flag;
+
+    int num_tile_columns;   ///< num_tile_columns_minus1 + 1
+    int num_tile_rows;      ///< num_tile_rows_minus1 + 1
+    uint8_t uniform_spacing_flag;
+    uint8_t loop_filter_across_tiles_enabled_flag;
+
+    uint8_t seq_loop_filter_across_slices_enabled_flag;
+
+    uint8_t deblocking_filter_control_present_flag;
+    uint8_t deblocking_filter_override_enabled_flag;
+    uint8_t disable_dbf;
+    int beta_offset;    ///< beta_offset_div2 * 2
+    int tc_offset;      ///< tc_offset_div2 * 2
+
+    uint8_t scaling_list_data_present_flag;
+    ScalingList scaling_list;
+
+    uint8_t lists_modification_present_flag;
+    int log2_parallel_merge_level; ///< log2_parallel_merge_level_minus2 + 2
+    int num_extra_slice_header_bits;
+    uint8_t slice_header_extension_present_flag;
+
+    // Inferred parameters
+    int *column_width;  ///< ColumnWidth
+    int *row_height;    ///< RowHeight
+    int *col_bd;        ///< ColBd
+    int *row_bd;        ///< RowBd
+    int *col_idxX;
+
+    int *ctb_addr_rs_to_ts; ///< CtbAddrRSToTS
+    int *ctb_addr_ts_to_rs; ///< CtbAddrTSToRS
+    int *tile_id;           ///< TileId
+    int *tile_pos_rs;       ///< TilePosRS
+    int *min_cb_addr_zs;    ///< MinCbAddrZS
+    int *min_tb_addr_zs;    ///< MinTbAddrZS
+} HEVCPPS;
+
+typedef struct SliceHeader {
+    int pps_id;
+
+    ///< address (in raster order) of the first block in the current slice segment
+    unsigned int   slice_segment_addr;
+    ///< address (in raster order) of the first block in the current slice
+    unsigned int   slice_addr;
+
+    enum SliceType slice_type;
+
+    int pic_order_cnt_lsb;
+
+    uint8_t first_slice_in_pic_flag;
+    uint8_t dependent_slice_segment_flag;
+    uint8_t pic_output_flag;
+    uint8_t colour_plane_id;
+
+    ///< RPS coded in the slice header itself is stored here
+    ShortTermRPS slice_rps;
+    const ShortTermRPS *short_term_rps;
+    LongTermRPS long_term_rps;
+    unsigned int list_entry_lx[2][32];
+
+    uint8_t rpl_modification_flag[2];
+    uint8_t no_output_of_prior_pics_flag;
+    uint8_t slice_temporal_mvp_enabled_flag;
+
+    unsigned int nb_refs[2];
+
+    uint8_t slice_sample_adaptive_offset_flag[3];
+    uint8_t mvd_l1_zero_flag;
+
+    uint8_t cabac_init_flag;
+    uint8_t disable_deblocking_filter_flag; ///< slice_header_disable_deblocking_filter_flag
+    uint8_t slice_loop_filter_across_slices_enabled_flag;
+    uint8_t collocated_list;
+
+    unsigned int collocated_ref_idx;
+
+    int slice_qp_delta;
+    int slice_cb_qp_offset;
+    int slice_cr_qp_offset;
+
+    int beta_offset;    ///< beta_offset_div2 * 2
+    int tc_offset;      ///< tc_offset_div2 * 2
+
+    unsigned int max_num_merge_cand; ///< 5 - 5_minus_max_num_merge_cand
+
+    int num_entry_point_offsets;
+
+    int8_t slice_qp;
+
+    uint8_t luma_log2_weight_denom;
+    int16_t chroma_log2_weight_denom;
+
+    int16_t luma_weight_l0[16];
+    int16_t chroma_weight_l0[16][2];
+    int16_t chroma_weight_l1[16][2];
+    int16_t luma_weight_l1[16];
+
+    int16_t luma_offset_l0[16];
+    int16_t chroma_offset_l0[16][2];
+
+    int16_t luma_offset_l1[16];
+    int16_t chroma_offset_l1[16][2];
+
+    int slice_ctb_addr_rs;
+} SliceHeader;
+
+typedef struct CodingTree {
+    int depth; ///< ctDepth
+} CodingTree;
+
+typedef struct CodingUnit {
+    int x;
+    int y;
+
+    enum PredMode pred_mode;    ///< PredMode
+    enum PartMode part_mode;    ///< PartMode
+
+    uint8_t rqt_root_cbf;
+
+    uint8_t pcm_flag;
+
+    // Inferred parameters
+    uint8_t intra_split_flag;   ///< IntraSplitFlag
+    uint8_t max_trafo_depth;    ///< MaxTrafoDepth
+    uint8_t cu_transquant_bypass_flag;
+} CodingUnit;
+
+typedef struct Mv {
+    int16_t x;  ///< horizontal component of motion vector
+    int16_t y;  ///< vertical component of motion vector
+} Mv;
+
+typedef struct MvField {
+    Mv mv[2];
+    int8_t ref_idx[2];
+    int8_t pred_flag[2];
+    uint8_t is_intra;
+} MvField;
+
+typedef struct NeighbourAvailable {
+    int cand_bottom_left;
+    int cand_left;
+    int cand_up;
+    int cand_up_left;
+    int cand_up_right;
+    int cand_up_right_sap;
+} NeighbourAvailable;
+
+typedef struct PredictionUnit {
+    int mpm_idx;
+    int rem_intra_luma_pred_mode;
+    uint8_t intra_pred_mode[4];
+    Mv mvd;
+    uint8_t merge_flag;
+    uint8_t intra_pred_mode_c;
+} PredictionUnit;
+
+typedef struct TransformTree {
+    uint8_t cbf_cb[MAX_TRANSFORM_DEPTH][MAX_CU_SIZE * MAX_CU_SIZE];
+    uint8_t cbf_cr[MAX_TRANSFORM_DEPTH][MAX_CU_SIZE * MAX_CU_SIZE];
+    uint8_t cbf_luma;
+
+    // Inferred parameters
+    uint8_t inter_split_flag;
+} TransformTree;
+
+typedef struct TransformUnit {
+    int cu_qp_delta;
+
+    // Inferred parameters;
+    int cur_intra_pred_mode;
+    uint8_t is_cu_qp_delta_coded;
+} TransformUnit;
+
+typedef struct SAOParams {
+    int offset_abs[3][4];   ///< sao_offset_abs
+    int offset_sign[3][4];  ///< sao_offset_sign
+
+    int band_position[3];   ///< sao_band_position
+
+    int eo_class[3];        ///< sao_eo_class
+
+    int offset_val[3][5];   ///<SaoOffsetVal
+
+    uint8_t type_idx[3];    ///< sao_type_idx
+} SAOParams;
+
+typedef struct DBParams {
+    int beta_offset;
+    int tc_offset;
+} DBParams;
+
+#define HEVC_FRAME_FLAG_OUTPUT    (1 << 0)
+#define HEVC_FRAME_FLAG_SHORT_REF (1 << 1)
+#define HEVC_FRAME_FLAG_LONG_REF  (1 << 2)
+
+typedef struct HEVCFrame {
+    AVFrame *frame;
+    ThreadFrame tf;
+    MvField *tab_mvf;
+    RefPicList *refPicList;
+    RefPicListTab **rpl_tab;
+    int ctb_count;
+    int poc;
+    struct HEVCFrame *collocated_ref;
+
+    HEVCWindow window;
+
+    AVBufferRef *tab_mvf_buf;
+    AVBufferRef *rpl_tab_buf;
+    AVBufferRef *rpl_buf;
+
+    /**
+     * A sequence counter, so that old frames are output first
+     * after a POC reset
+     */
+    uint16_t sequence;
+
+    /**
+     * A combination of HEVC_FRAME_FLAG_*
+     */
+    uint8_t flags;
+} HEVCFrame;
+
+typedef struct HEVCNAL {
+    uint8_t *rbsp_buffer;
+    int rbsp_buffer_size;
+
+    int size;
+    const uint8_t *data;
+} HEVCNAL;
+
+typedef struct HEVCDSPContext {
+    void (*put_pcm)(uint8_t *dst, ptrdiff_t stride, int size,
+                    GetBitContext *gb, int pcm_bit_depth);
+
+    void (*transquant_bypass[4])(uint8_t *dst, int16_t *coeffs,
+                                 ptrdiff_t stride);
+
+    void (*transform_skip)(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride);
+    void (*transform_4x4_luma_add)(uint8_t *dst, int16_t *coeffs,
+                                   ptrdiff_t stride);
+    void (*transform_add[4])(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride);
+
+    void (*sao_band_filter[4])(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+                               struct SAOParams *sao, int *borders,
+                               int width, int height, int c_idx);
+    void (*sao_edge_filter[4])(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
+                               struct SAOParams *sao, int *borders, int width,
+                               int height, int c_idx, uint8_t vert_edge,
+                               uint8_t horiz_edge, uint8_t diag_edge);
+
+    void (*put_hevc_qpel[4][4])(int16_t *dst, ptrdiff_t dststride, uint8_t *src,
+                                ptrdiff_t srcstride, int width, int height,
+                                int16_t *mcbuffer);
+    void (*put_hevc_epel[2][2])(int16_t *dst, ptrdiff_t dststride, uint8_t *src,
+                                ptrdiff_t srcstride, int width, int height,
+                                int mx, int my, int16_t *mcbuffer);
+
+    void (*put_unweighted_pred)(uint8_t *dst, ptrdiff_t dststride, int16_t *src,
+                                ptrdiff_t srcstride, int width, int height);
+    void (*put_weighted_pred_avg)(uint8_t *dst, ptrdiff_t dststride,
+                                  int16_t *src1, int16_t *src2,
+                                  ptrdiff_t srcstride, int width, int height);
+    void (*weighted_pred)(uint8_t denom, int16_t wlxFlag, int16_t olxFlag,
+                          uint8_t *dst, ptrdiff_t dststride, int16_t *src,
+                          ptrdiff_t srcstride, int width, int height);
+    void (*weighted_pred_avg)(uint8_t denom, int16_t wl0Flag, int16_t wl1Flag,
+                              int16_t ol0Flag, int16_t ol1Flag, uint8_t *dst,
+                              ptrdiff_t dststride, int16_t *src1, int16_t *src2,
+                              ptrdiff_t srcstride, int width, int height);
+
+    void (*hevc_h_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
+                                    int *beta, int *tc,
+                                    uint8_t *no_p, uint8_t *no_q);
+    void (*hevc_v_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
+                                    int *beta, int *tc,
+                                    uint8_t *no_p, uint8_t *no_q);
+    void (*hevc_h_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
+                                      int *tc, uint8_t *no_p, uint8_t *no_q);
+    void (*hevc_v_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
+                                      int *tc, uint8_t *no_p, uint8_t *no_q);
+    void (*hevc_h_loop_filter_luma_c)(uint8_t *pix, ptrdiff_t stride,
+                                      int *beta, int *tc,
+                                      uint8_t *no_p, uint8_t *no_q);
+    void (*hevc_v_loop_filter_luma_c)(uint8_t *pix, ptrdiff_t stride,
+                                      int *beta, int *tc,
+                                      uint8_t *no_p, uint8_t *no_q);
+    void (*hevc_h_loop_filter_chroma_c)(uint8_t *pix, ptrdiff_t stride,
+                                        int *tc, uint8_t *no_p,
+                                        uint8_t *no_q);
+    void (*hevc_v_loop_filter_chroma_c)(uint8_t *pix, ptrdiff_t stride,
+                                        int *tc, uint8_t *no_p,
+                                        uint8_t *no_q);
+} HEVCDSPContext;
+
+struct HEVCContext;
+
+typedef struct HEVCPredContext {
+    void (*intra_pred)(struct HEVCContext *s, int x0, int y0,
+                       int log2_size, int c_idx);
+
+    void (*pred_planar[4])(uint8_t *src, const uint8_t *top,
+                           const uint8_t *left, ptrdiff_t stride);
+    void (*pred_dc)(uint8_t *src, const uint8_t *top, const uint8_t *left,
+                    ptrdiff_t stride, int log2_size, int c_idx);
+    void (*pred_angular[4])(uint8_t *src, const uint8_t *top,
+                            const uint8_t *left, ptrdiff_t stride,
+                            int c_idx, int mode);
+} HEVCPredContext;
+
+typedef struct HEVCLocalContext {
+    DECLARE_ALIGNED(16, int16_t, mc_buffer[(MAX_PB_SIZE + 7) * MAX_PB_SIZE]);
+    uint8_t cabac_state[HEVC_CONTEXTS];
+
+    uint8_t first_qp_group;
+
+    GetBitContext gb;
+    CABACContext cc;
+    TransformTree tt;
+
+    int8_t qp_y;
+    int8_t curr_qp_y;
+
+    TransformUnit tu;
+
+    uint8_t ctb_left_flag;
+    uint8_t ctb_up_flag;
+    uint8_t ctb_up_right_flag;
+    uint8_t ctb_up_left_flag;
+    int     start_of_tiles_x;
+    int     end_of_tiles_x;
+    int     end_of_tiles_y;
+    uint8_t *edge_emu_buffer;
+    int      edge_emu_buffer_size;
+    CodingTree ct;
+    CodingUnit cu;
+    PredictionUnit pu;
+    NeighbourAvailable na;
+
+    uint8_t slice_or_tiles_left_boundary;
+    uint8_t slice_or_tiles_up_boundary;
+} HEVCLocalContext;
+
+typedef struct HEVCContext {
+    const AVClass *c;  // needed by private avoptions
+    AVCodecContext *avctx;
+
+    HEVCLocalContext HEVClc;
+
+    uint8_t cabac_state[HEVC_CONTEXTS];
+
+    /** 1 if the independent slice segment header was successfully parsed */
+    uint8_t slice_initialized;
+
+    AVFrame *frame;
+    AVFrame *sao_frame;
+    AVFrame *tmp_frame;
+    AVFrame *output_frame;
+
+    const HEVCVPS *vps;
+    const HEVCSPS *sps;
+    const HEVCPPS *pps;
+    AVBufferRef *vps_list[MAX_VPS_COUNT];
+    AVBufferRef *sps_list[MAX_SPS_COUNT];
+    AVBufferRef *pps_list[MAX_PPS_COUNT];
+
+    AVBufferPool *tab_mvf_pool;
+    AVBufferPool *rpl_tab_pool;
+
+    ///< candidate references for the current frame
+    RefPicList rps[5];
+
+    SliceHeader sh;
+    SAOParams *sao;
+    DBParams *deblock;
+    enum NALUnitType nal_unit_type;
+    int temporal_id;  ///< temporal_id_plus1 - 1
+    HEVCFrame *ref;
+    HEVCFrame DPB[32];
+    int poc;
+    int pocTid0;
+    int slice_idx; ///< number of the slice being currently decoded
+    int eos;       ///< current packet contains an EOS/EOB NAL
+    int max_ra;
+    int bs_width;
+    int bs_height;
+
+    int is_decoded;
+
+    HEVCPredContext hpc;
+    HEVCDSPContext hevcdsp;
+    VideoDSPContext vdsp;
+    DSPContext dsp;
+    int8_t *qp_y_tab;
+    uint8_t *split_cu_flag;
+    uint8_t *horizontal_bs;
+    uint8_t *vertical_bs;
+
+    int32_t *tab_slice_address;
+
+    //  CU
+    uint8_t *skip_flag;
+    uint8_t *tab_ct_depth;
+    // PU
+    uint8_t *tab_ipm;
+
+    uint8_t *cbf_luma; // cbf_luma of colocated TU
+    uint8_t *is_pcm;
+
+    // CTB-level flags affecting loop filter operation
+    uint8_t *filter_slice_edges;
+
+    /** used on BE to byteswap the lines for checksumming */
+    uint8_t *checksum_buf;
+    int      checksum_buf_size;
+
+    /**
+     * Sequence counters for decoded and output frames, so that old
+     * frames are output first after a POC reset
+     */
+    uint16_t seq_decode;
+    uint16_t seq_output;
+
+    HEVCNAL *nals;
+    int nb_nals;
+    int nals_allocated;
+
+    // for checking the frame checksums
+    struct AVMD5 *md5_ctx;
+    uint8_t       md5[3][16];
+    uint8_t is_md5;
+
+    uint8_t context_initialized;
+    uint8_t is_nalff;       ///< this flag is != 0 if bitstream is encapsulated
+                            ///< as a format defined in 14496-15
+    int apply_defdispwin;
+
+    int nal_length_size;    ///< Number of bytes used for nal length (1, 2 or 4)
+    int nuh_layer_id;
+
+    /** frame packing arrangement variables */
+    int sei_frame_packing_present;
+    int frame_packing_arrangement_type;
+    int content_interpretation_type;
+    int quincunx_subsampling;
+} HEVCContext;
+
+int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
+                                  const HEVCSPS *sps, int is_slice_header);
+int ff_hevc_decode_nal_vps(HEVCContext *s);
+int ff_hevc_decode_nal_sps(HEVCContext *s);
+int ff_hevc_decode_nal_pps(HEVCContext *s);
+int ff_hevc_decode_nal_sei(HEVCContext *s);
+
+/**
+ * Mark all frames in DPB as unused for reference.
+ */
+void ff_hevc_clear_refs(HEVCContext *s);
+
+/**
+ * Drop all frames currently in DPB.
+ */
+void ff_hevc_flush_dpb(HEVCContext *s);
+
+/**
+ * Compute POC of the current frame and return it.
+ */
+int ff_hevc_compute_poc(HEVCContext *s, int poc_lsb);
+
+RefPicList *ff_hevc_get_ref_list(HEVCContext *s, HEVCFrame *frame,
+                                 int x0, int y0);
+
+/**
+ * Construct the reference picture sets for the current frame.
+ */
+int ff_hevc_frame_rps(HEVCContext *s);
+
+/**
+ * Construct the reference picture list(s) for the current slice.
+ */
+int ff_hevc_slice_rpl(HEVCContext *s);
+
+void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts);
+void ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts);
+int ff_hevc_sao_merge_flag_decode(HEVCContext *s);
+int ff_hevc_sao_type_idx_decode(HEVCContext *s);
+int ff_hevc_sao_band_position_decode(HEVCContext *s);
+int ff_hevc_sao_offset_abs_decode(HEVCContext *s);
+int ff_hevc_sao_offset_sign_decode(HEVCContext *s);
+int ff_hevc_sao_eo_class_decode(HEVCContext *s);
+int ff_hevc_end_of_slice_flag_decode(HEVCContext *s);
+int ff_hevc_cu_transquant_bypass_flag_decode(HEVCContext *s);
+int ff_hevc_skip_flag_decode(HEVCContext *s, int x0, int y0,
+                             int x_cb, int y_cb);
+int ff_hevc_pred_mode_decode(HEVCContext *s);
+int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth,
+                                          int x0, int y0);
+int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size);
+int ff_hevc_pcm_flag_decode(HEVCContext *s);
+int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s);
+int ff_hevc_mpm_idx_decode(HEVCContext *s);
+int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCContext *s);
+int ff_hevc_intra_chroma_pred_mode_decode(HEVCContext *s);
+int ff_hevc_merge_idx_decode(HEVCContext *s);
+int ff_hevc_merge_flag_decode(HEVCContext *s);
+int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH);
+int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx);
+int ff_hevc_mvp_lx_flag_decode(HEVCContext *s);
+int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s);
+int ff_hevc_abs_mvd_greater0_flag_decode(HEVCContext *s);
+int ff_hevc_abs_mvd_greater1_flag_decode(HEVCContext *s);
+int ff_hevc_mvd_decode(HEVCContext *s);
+int ff_hevc_mvd_sign_flag_decode(HEVCContext *s);
+int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size);
+int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth);
+int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth);
+int ff_hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx);
+int ff_hevc_last_significant_coeff_x_prefix_decode(HEVCContext *s, int c_idx,
+                                                   int log2_size);
+int ff_hevc_last_significant_coeff_y_prefix_decode(HEVCContext *s, int c_idx,
+                                                   int log2_size);
+int ff_hevc_last_significant_coeff_suffix_decode(HEVCContext *s,
+                                                 int last_significant_coeff_prefix);
+int ff_hevc_significant_coeff_group_flag_decode(HEVCContext *s, int c_idx,
+                                                int ctx_cg);
+int ff_hevc_significant_coeff_flag_decode(HEVCContext *s, int c_idx, int x_c,
+                                          int y_c, int log2_trafo_size,
+                                          int scan_idx, int prev_sig);
+int ff_hevc_coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx,
+                                                 int ctx_set);
+int ff_hevc_coeff_abs_level_greater2_flag_decode(HEVCContext *s, int c_idx,
+                                                 int inc);
+int ff_hevc_coeff_abs_level_remaining(HEVCContext *s, int base_level,
+                                      int rc_rice_param);
+int ff_hevc_coeff_sign_flag(HEVCContext *s, uint8_t nb);
+
+/**
+ * Get the number of candidate references for the current frame.
+ */
+int ff_hevc_frame_nb_refs(HEVCContext *s);
+
+int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc);
+
+/**
+ * Find next frame in output order and put a reference to it in frame.
+ * @return 1 if a frame was output, 0 otherwise
+ */
+int ff_hevc_output_frame(HEVCContext *s, AVFrame *frame, int flush);
+
+void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags);
+
+void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
+                                     int nPbW, int nPbH);
+void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0,
+                                int nPbW, int nPbH, int log2_cb_size,
+                                int part_idx, int merge_idx, MvField *mv);
+void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0,
+                              int nPbW, int nPbH, int log2_cb_size,
+                              int part_idx, int merge_idx,
+                              MvField *mv, int mvp_lx_flag, int LX);
+void ff_hevc_set_qPy(HEVCContext *s, int xC, int yC, int xBase, int yBase,
+                     int log2_cb_size);
+void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
+                                           int log2_trafo_size,
+                                           int slice_or_tiles_up_boundary,
+                                           int slice_or_tiles_left_boundary);
+int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s);
+int ff_hevc_cu_qp_delta_abs(HEVCContext *s);
+void ff_hevc_hls_filter(HEVCContext *s, int x, int y);
+void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size);
+
+void ff_hevc_pps_free(HEVCPPS **ppps);
+
+void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth);
+
+void ff_hevc_dsp_init(HEVCDSPContext *hpc, int bit_depth);
+
+extern const int8_t ff_hevc_epel_filters[7][16];
+
+extern const uint8_t ff_hevc_qpel_extra_before[4];
+extern const uint8_t ff_hevc_qpel_extra_after[4];
+extern const uint8_t ff_hevc_qpel_extra[4];
+
+extern const uint8_t ff_hevc_diag_scan4x4_x[16];
+extern const uint8_t ff_hevc_diag_scan4x4_y[16];
+extern const uint8_t ff_hevc_diag_scan8x8_x[64];
+extern const uint8_t ff_hevc_diag_scan8x8_y[64];
+
+#endif /* AVCODEC_HEVC_H */
diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c
new file mode 100644
index 0000000..f2531d4
--- /dev/null
+++ b/libavcodec/hevc_cabac.c
@@ -0,0 +1,872 @@
+/*
+ * HEVC CABAC decoding
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ *
+ * 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/attributes.h"
+#include "libavutil/common.h"
+
+#include "cabac_functions.h"
+#include "hevc.h"
+
+#define CABAC_MAX_BIN 100
+
+/**
+ * number of bin by SyntaxElement.
+ */
+static const int8_t num_bins_in_se[] = {
+     1, // sao_merge_flag
+     1, // sao_type_idx
+     0, // sao_eo_class
+     0, // sao_band_position
+     0, // sao_offset_abs
+     0, // sao_offset_sign
+     0, // end_of_slice_flag
+     3, // split_coding_unit_flag
+     1, // cu_transquant_bypass_flag
+     3, // skip_flag
+     3, // cu_qp_delta
+     1, // pred_mode
+     4, // part_mode
+     0, // pcm_flag
+     1, // prev_intra_luma_pred_mode
+     0, // mpm_idx
+     0, // rem_intra_luma_pred_mode
+     2, // intra_chroma_pred_mode
+     1, // merge_flag
+     1, // merge_idx
+     5, // inter_pred_idc
+     2, // ref_idx_l0
+     2, // ref_idx_l1
+     2, // abs_mvd_greater0_flag
+     2, // abs_mvd_greater1_flag
+     0, // abs_mvd_minus2
+     0, // mvd_sign_flag
+     1, // mvp_lx_flag
+     1, // no_residual_data_flag
+     3, // split_transform_flag
+     2, // cbf_luma
+     4, // cbf_cb, cbf_cr
+     2, // transform_skip_flag[][]
+    18, // last_significant_coeff_x_prefix
+    18, // last_significant_coeff_y_prefix
+     0, // last_significant_coeff_x_suffix
+     0, // last_significant_coeff_y_suffix
+     4, // significant_coeff_group_flag
+    42, // significant_coeff_flag
+    24, // coeff_abs_level_greater1_flag
+     6, // coeff_abs_level_greater2_flag
+     0, // coeff_abs_level_remaining
+     0, // coeff_sign_flag
+};
+
+/**
+ * Offset to ctxIdx 0 in init_values and states, indexed by SyntaxElement.
+ */
+static const int elem_offset[sizeof(num_bins_in_se)] = {
+      0,
+      1,
+      2,
+      2,
+      2,
+      2,
+      2,
+      2,
+      5,
+      6,
+      9,
+     12,
+     13,
+     17,
+     17,
+     18,
+     18,
+     18,
+     20,
+     21,
+     22,
+     27,
+     29,
+     31,
+     33,
+     35,
+     35,
+     35,
+     36,
+     37,
+     40,
+     42,
+     46,
+     48,
+     66,
+     84,
+     84,
+     84,
+     88,
+    130,
+    154,
+    160,
+    160,
+};
+
+#define CNU 154
+/**
+ * Indexed by init_type
+ */
+static const uint8_t init_values[3][HEVC_CONTEXTS] = {
+    { // sao_merge_flag
+      153,
+      // sao_type_idx
+      200,
+      // split_coding_unit_flag
+      139, 141, 157,
+      // cu_transquant_bypass_flag
+      154,
+      // skip_flag
+      CNU, CNU, CNU,
+      // cu_qp_delta
+      154, 154, 154,
+      // pred_mode
+      CNU,
+      // part_mode
+      184, CNU, CNU, CNU,
+      // prev_intra_luma_pred_mode
+      184,
+      // intra_chroma_pred_mode
+      63, 139,
+      // merge_flag
+      CNU,
+      // merge_idx
+      CNU,
+      // inter_pred_idc
+      CNU, CNU, CNU, CNU, CNU,
+      // ref_idx_l0
+      CNU, CNU,
+      // ref_idx_l1
+      CNU, CNU,
+      // abs_mvd_greater1_flag
+      CNU, CNU,
+      // abs_mvd_greater1_flag
+      CNU, CNU,
+      // mvp_lx_flag
+      CNU,
+      // no_residual_data_flag
+      CNU,
+      // split_transform_flag
+      153, 138, 138,
+      // cbf_luma
+      111, 141,
+      // cbf_cb, cbf_cr
+      94, 138, 182, 154,
+      // transform_skip_flag
+      139, 139,
+      // last_significant_coeff_x_prefix
+      110, 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111,
+       79, 108, 123,  63,
+      // last_significant_coeff_y_prefix
+      110, 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111,
+       79, 108, 123,  63,
+      // significant_coeff_group_flag
+      91, 171, 134, 141,
+      // significant_coeff_flag
+      111, 111, 125, 110, 110,  94, 124, 108, 124, 107, 125, 141, 179, 153,
+      125, 107, 125, 141, 179, 153, 125, 107, 125, 141, 179, 153, 125, 140,
+      139, 182, 182, 152, 136, 152, 136, 153, 136, 139, 111, 136, 139, 111,
+      // coeff_abs_level_greater1_flag
+      140,  92, 137, 138, 140, 152, 138, 139, 153,  74, 149,  92, 139, 107,
+      122, 152, 140, 179, 166, 182, 140, 227, 122, 197,
+      // coeff_abs_level_greater2_flag
+      138, 153, 136, 167, 152, 152, },
+    { // sao_merge_flag
+      153,
+      // sao_type_idx
+      185,
+      // split_coding_unit_flag
+      107, 139, 126,
+      // cu_transquant_bypass_flag
+      154,
+      // skip_flag
+      197, 185, 201,
+      // cu_qp_delta
+      154, 154, 154,
+      // pred_mode
+      149,
+      // part_mode
+      154, 139, 154, 154,
+      // prev_intra_luma_pred_mode
+      154,
+      // intra_chroma_pred_mode
+      152, 139,
+      // merge_flag
+      110,
+      // merge_idx
+      122,
+      // inter_pred_idc
+      95, 79, 63, 31, 31,
+      // ref_idx_l0
+      153, 153,
+      // ref_idx_l1
+      153, 153,
+      // abs_mvd_greater1_flag
+      140, 198,
+      // abs_mvd_greater1_flag
+      140, 198,
+      // mvp_lx_flag
+      168,
+      // no_residual_data_flag
+      79,
+      // split_transform_flag
+      124, 138, 94,
+      // cbf_luma
+      153, 111,
+      // cbf_cb, cbf_cr
+      149, 107, 167, 154,
+      // transform_skip_flag
+      139, 139,
+      // last_significant_coeff_x_prefix
+      125, 110,  94, 110,  95,  79, 125, 111, 110,  78, 110, 111, 111,  95,
+       94, 108, 123, 108,
+      // last_significant_coeff_y_prefix
+      125, 110,  94, 110,  95,  79, 125, 111, 110,  78, 110, 111, 111,  95,
+       94, 108, 123, 108,
+      // significant_coeff_group_flag
+      121, 140, 61, 154,
+      // significant_coeff_flag
+      155, 154, 139, 153, 139, 123, 123,  63, 153, 166, 183, 140, 136, 153,
+      154, 166, 183, 140, 136, 153, 154, 166, 183, 140, 136, 153, 154, 170,
+      153, 123, 123, 107, 121, 107, 121, 167, 151, 183, 140, 151, 183, 140,
+      // coeff_abs_level_greater1_flag
+      154, 196, 196, 167, 154, 152, 167, 182, 182, 134, 149, 136, 153, 121,
+      136, 137, 169, 194, 166, 167, 154, 167, 137, 182,
+      // coeff_abs_level_greater2_flag
+      107, 167, 91, 122, 107, 167, },
+    { // sao_merge_flag
+      153,
+      // sao_type_idx
+      160,
+      // split_coding_unit_flag
+      107, 139, 126,
+      // cu_transquant_bypass_flag
+      154,
+      // skip_flag
+      197, 185, 201,
+      // cu_qp_delta
+      154, 154, 154,
+      // pred_mode
+      134,
+      // part_mode
+      154, 139, 154, 154,
+      // prev_intra_luma_pred_mode
+      183,
+      // intra_chroma_pred_mode
+      152, 139,
+      // merge_flag
+      154,
+      // merge_idx
+      137,
+      // inter_pred_idc
+      95, 79, 63, 31, 31,
+      // ref_idx_l0
+      153, 153,
+      // ref_idx_l1
+      153, 153,
+      // abs_mvd_greater1_flag
+      169, 198,
+      // abs_mvd_greater1_flag
+      169, 198,
+      // mvp_lx_flag
+      168,
+      // no_residual_data_flag
+      79,
+      // split_transform_flag
+      224, 167, 122,
+      // cbf_luma
+      153, 111,
+      // cbf_cb, cbf_cr
+      149, 92, 167, 154,
+      // transform_skip_flag
+      139, 139,
+      // last_significant_coeff_x_prefix
+      125, 110, 124, 110,  95,  94, 125, 111, 111,  79, 125, 126, 111, 111,
+       79, 108, 123,  93,
+      // last_significant_coeff_y_prefix
+      125, 110, 124, 110,  95,  94, 125, 111, 111,  79, 125, 126, 111, 111,
+       79, 108, 123,  93,
+      // significant_coeff_group_flag
+      121, 140, 61, 154,
+      // significant_coeff_flag
+      170, 154, 139, 153, 139, 123, 123,  63, 124, 166, 183, 140, 136, 153,
+      154, 166, 183, 140, 136, 153, 154, 166, 183, 140, 136, 153, 154, 170,
+      153, 138, 138, 122, 121, 122, 121, 167, 151, 183, 140, 151, 183, 140,
+      // coeff_abs_level_greater1_flag
+      154, 196, 167, 167, 154, 152, 167, 182, 182, 134, 149, 136, 153, 121,
+      136, 122, 169, 208, 166, 167, 154, 152, 167, 182,
+      // coeff_abs_level_greater2_flag
+      107, 167, 91, 107, 107, 167, },
+};
+
+void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts)
+{
+    if (s->pps->entropy_coding_sync_enabled_flag &&
+        (ctb_addr_ts % s->sps->ctb_width == 2 ||
+         (s->sps->ctb_width == 2 &&
+          ctb_addr_ts % s->sps->ctb_width == 0))) {
+        memcpy(s->cabac_state, s->HEVClc.cabac_state, HEVC_CONTEXTS);
+    }
+}
+
+static void load_states(HEVCContext *s)
+{
+    memcpy(s->HEVClc.cabac_state, s->cabac_state, HEVC_CONTEXTS);
+}
+
+static void cabac_reinit(HEVCLocalContext *lc)
+{
+    skip_bytes(&lc->cc, 0);
+}
+
+static void cabac_init_decoder(HEVCContext *s)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+    skip_bits(gb, 1);
+    align_get_bits(gb);
+    ff_init_cabac_decoder(&s->HEVClc.cc,
+                          gb->buffer + get_bits_count(gb) / 8,
+                          (get_bits_left(gb) + 7) / 8);
+}
+
+static void cabac_init_state(HEVCContext *s)
+{
+    int init_type = 2 - s->sh.slice_type;
+    int i;
+
+    if (s->sh.cabac_init_flag && s->sh.slice_type != I_SLICE)
+        init_type ^= 3;
+
+    for (i = 0; i < HEVC_CONTEXTS; i++) {
+        int init_value = init_values[init_type][i];
+        int m = (init_value >> 4) * 5 - 45;
+        int n = ((init_value & 15) << 3) - 16;
+        int pre = 2 * (((m * av_clip_c(s->sh.slice_qp, 0, 51)) >> 4) + n) - 127;
+
+        pre ^= pre >> 31;
+        if (pre > 124)
+            pre = 124 + (pre & 1);
+        s->HEVClc.cabac_state[i] = pre;
+    }
+}
+
+void ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts)
+{
+    if (ctb_addr_ts == s->pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]) {
+        cabac_init_decoder(s);
+        if (s->sh.dependent_slice_segment_flag == 0 ||
+            (s->pps->tiles_enabled_flag &&
+             s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]))
+            cabac_init_state(s);
+
+        if (!s->sh.first_slice_in_pic_flag &&
+            s->pps->entropy_coding_sync_enabled_flag) {
+            if (ctb_addr_ts % s->sps->ctb_width == 0) {
+                if (s->sps->ctb_width == 1)
+                    cabac_init_state(s);
+                else if (s->sh.dependent_slice_segment_flag == 1)
+                    load_states(s);
+            }
+        }
+    } else {
+        if (s->pps->tiles_enabled_flag &&
+            s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]) {
+            cabac_reinit(&s->HEVClc);
+            cabac_init_state(s);
+        }
+        if (s->pps->entropy_coding_sync_enabled_flag) {
+            if (ctb_addr_ts % s->sps->ctb_width == 0) {
+                get_cabac_terminate(&s->HEVClc.cc);
+                cabac_reinit(&s->HEVClc);
+
+                if (s->sps->ctb_width == 1)
+                    cabac_init_state(s);
+                else
+                    load_states(s);
+            }
+        }
+    }
+}
+
+#define GET_CABAC(ctx) get_cabac(&s->HEVClc.cc, &s->HEVClc.cabac_state[ctx])
+
+int ff_hevc_sao_merge_flag_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[SAO_MERGE_FLAG]);
+}
+
+int ff_hevc_sao_type_idx_decode(HEVCContext *s)
+{
+    if (!GET_CABAC(elem_offset[SAO_TYPE_IDX]))
+        return 0;
+
+    if (!get_cabac_bypass(&s->HEVClc.cc))
+        return SAO_BAND;
+    return SAO_EDGE;
+}
+
+int ff_hevc_sao_band_position_decode(HEVCContext *s)
+{
+    int i;
+    int value = get_cabac_bypass(&s->HEVClc.cc);
+
+    for (i = 0; i < 4; i++)
+        value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc);
+    return value;
+}
+
+int ff_hevc_sao_offset_abs_decode(HEVCContext *s)
+{
+    int i = 0;
+    int length = (1 << (FFMIN(s->sps->bit_depth, 10) - 5)) - 1;
+
+    while (i < length && get_cabac_bypass(&s->HEVClc.cc))
+        i++;
+    return i;
+}
+
+int ff_hevc_sao_offset_sign_decode(HEVCContext *s)
+{
+    return get_cabac_bypass(&s->HEVClc.cc);
+}
+
+int ff_hevc_sao_eo_class_decode(HEVCContext *s)
+{
+    int ret = get_cabac_bypass(&s->HEVClc.cc) << 1;
+    ret    |= get_cabac_bypass(&s->HEVClc.cc);
+    return ret;
+}
+
+int ff_hevc_end_of_slice_flag_decode(HEVCContext *s)
+{
+    return get_cabac_terminate(&s->HEVClc.cc);
+}
+
+int ff_hevc_cu_transquant_bypass_flag_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[CU_TRANSQUANT_BYPASS_FLAG]);
+}
+
+int ff_hevc_skip_flag_decode(HEVCContext *s, int x0, int y0, int x_cb, int y_cb)
+{
+    int min_cb_width = s->sps->min_cb_width;
+    int inc = 0;
+    int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+    int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+    if (s->HEVClc.ctb_left_flag || x0b)
+        inc = !!SAMPLE_CTB(s->skip_flag, x_cb - 1, y_cb);
+    if (s->HEVClc.ctb_up_flag || y0b)
+        inc += !!SAMPLE_CTB(s->skip_flag, x_cb, y_cb - 1);
+
+    return GET_CABAC(elem_offset[SKIP_FLAG] + inc);
+}
+
+int ff_hevc_cu_qp_delta_abs(HEVCContext *s)
+{
+    int prefix_val = 0;
+    int suffix_val = 0;
+    int inc = 0;
+
+    while (prefix_val < 5 && GET_CABAC(elem_offset[CU_QP_DELTA] + inc)) {
+        prefix_val++;
+        inc = 1;
+    }
+    if (prefix_val >= 5) {
+        int k = 0;
+        while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc)) {
+            suffix_val += 1 << k;
+            k++;
+        }
+        if (k == CABAC_MAX_BIN)
+            av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
+
+        while (k--)
+            suffix_val += get_cabac_bypass(&s->HEVClc.cc) << k;
+    }
+    return prefix_val + suffix_val;
+}
+
+int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s)
+{
+    return get_cabac_bypass(&s->HEVClc.cc);
+}
+
+int ff_hevc_pred_mode_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[PRED_MODE_FLAG]);
+}
+
+int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth, int x0, int y0)
+{
+    int inc = 0, depth_left = 0, depth_top = 0;
+    int x0b  = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+    int y0b  = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+    int x_cb = x0 >> s->sps->log2_min_cb_size;
+    int y_cb = y0 >> s->sps->log2_min_cb_size;
+
+    if (s->HEVClc.ctb_left_flag || x0b)
+        depth_left = s->tab_ct_depth[(y_cb) * s->sps->min_cb_width + x_cb - 1];
+    if (s->HEVClc.ctb_up_flag || y0b)
+        depth_top = s->tab_ct_depth[(y_cb - 1) * s->sps->min_cb_width + x_cb];
+
+    inc += (depth_left > ct_depth);
+    inc += (depth_top  > ct_depth);
+
+    return GET_CABAC(elem_offset[SPLIT_CODING_UNIT_FLAG] + inc);
+}
+
+int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size)
+{
+    if (GET_CABAC(elem_offset[PART_MODE])) // 1
+        return PART_2Nx2N;
+    if (log2_cb_size == s->sps->log2_min_cb_size) {
+        if (s->HEVClc.cu.pred_mode == MODE_INTRA) // 0
+            return PART_NxN;
+        if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01
+            return PART_2NxN;
+        if (log2_cb_size == 3) // 00
+            return PART_Nx2N;
+        if (GET_CABAC(elem_offset[PART_MODE] + 2)) // 001
+            return PART_Nx2N;
+        return PART_NxN; // 000
+    }
+
+    if (!s->sps->amp_enabled_flag) {
+        if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01
+            return PART_2NxN;
+        return PART_Nx2N;
+    }
+
+    if (GET_CABAC(elem_offset[PART_MODE] + 1)) { // 01X, 01XX
+        if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 011
+            return PART_2NxN;
+        if (get_cabac_bypass(&s->HEVClc.cc)) // 0101
+            return PART_2NxnD;
+        return PART_2NxnU; // 0100
+    }
+
+    if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 001
+        return PART_Nx2N;
+    if (get_cabac_bypass(&s->HEVClc.cc)) // 0001
+        return PART_nRx2N;
+    return PART_nLx2N;  // 0000
+}
+
+int ff_hevc_pcm_flag_decode(HEVCContext *s)
+{
+    return get_cabac_terminate(&s->HEVClc.cc);
+}
+
+int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[PREV_INTRA_LUMA_PRED_FLAG]);
+}
+
+int ff_hevc_mpm_idx_decode(HEVCContext *s)
+{
+    int i = 0;
+    while (i < 2 && get_cabac_bypass(&s->HEVClc.cc))
+        i++;
+    return i;
+}
+
+int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCContext *s)
+{
+    int i;
+    int value = get_cabac_bypass(&s->HEVClc.cc);
+
+    for (i = 0; i < 4; i++)
+        value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc);
+    return value;
+}
+
+int ff_hevc_intra_chroma_pred_mode_decode(HEVCContext *s)
+{
+    int ret;
+    if (!GET_CABAC(elem_offset[INTRA_CHROMA_PRED_MODE]))
+        return 4;
+
+    ret  = get_cabac_bypass(&s->HEVClc.cc) << 1;
+    ret |= get_cabac_bypass(&s->HEVClc.cc);
+    return ret;
+}
+
+int ff_hevc_merge_idx_decode(HEVCContext *s)
+{
+    int i = GET_CABAC(elem_offset[MERGE_IDX]);
+
+    if (i != 0) {
+        while (i < s->sh.max_num_merge_cand-1 && get_cabac_bypass(&s->HEVClc.cc))
+            i++;
+    }
+    return i;
+}
+
+int ff_hevc_merge_flag_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[MERGE_FLAG]);
+}
+
+int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH)
+{
+    if (nPbW + nPbH == 12)
+        return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4);
+    if (GET_CABAC(elem_offset[INTER_PRED_IDC] + s->HEVClc.ct.depth))
+        return PRED_BI;
+
+    return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4);
+}
+
+int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx)
+{
+    int i = 0;
+    int max = num_ref_idx_lx - 1;
+    int max_ctx = FFMIN(max, 2);
+
+    while (i < max_ctx && GET_CABAC(elem_offset[REF_IDX_L0] + i))
+        i++;
+    if (i == 2) {
+        while (i < max && get_cabac_bypass(&s->HEVClc.cc))
+            i++;
+    }
+
+    return i;
+}
+
+int ff_hevc_mvp_lx_flag_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[MVP_LX_FLAG]);
+}
+
+int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[NO_RESIDUAL_DATA_FLAG]);
+}
+
+int ff_hevc_abs_mvd_greater0_flag_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[ABS_MVD_GREATER0_FLAG]);
+}
+
+int ff_hevc_abs_mvd_greater1_flag_decode(HEVCContext *s)
+{
+    return GET_CABAC(elem_offset[ABS_MVD_GREATER1_FLAG] + 1);
+}
+
+int ff_hevc_mvd_decode(HEVCContext *s)
+{
+    int ret = 2;
+    int k = 1;
+
+    while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc)) {
+        ret += 1 << k;
+        k++;
+    }
+    if (k == CABAC_MAX_BIN)
+        av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
+    while (k--)
+        ret += get_cabac_bypass(&s->HEVClc.cc) << k;
+    return get_cabac_bypass_sign(&s->HEVClc.cc, -ret);
+}
+
+int ff_hevc_mvd_sign_flag_decode(HEVCContext *s)
+{
+    return get_cabac_bypass_sign(&s->HEVClc.cc, -1);
+}
+
+int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size)
+{
+    return GET_CABAC(elem_offset[SPLIT_TRANSFORM_FLAG] + 5 - log2_trafo_size);
+}
+
+int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth)
+{
+    return GET_CABAC(elem_offset[CBF_CB_CR] + trafo_depth);
+}
+
+int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth)
+{
+    return GET_CABAC(elem_offset[CBF_LUMA] + !trafo_depth);
+}
+
+int ff_hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx)
+{
+    return GET_CABAC(elem_offset[TRANSFORM_SKIP_FLAG] + !!c_idx);
+}
+
+#define LAST_SIG_COEFF(elem)                                                    \
+    int i = 0;                                                                  \
+    int max = (log2_size << 1) - 1;                                             \
+    int ctx_offset, ctx_shift;                                                  \
+                                                                                \
+    if (c_idx == 0) {                                                           \
+        ctx_offset = 3 * (log2_size - 2)  + ((log2_size - 1) >> 2);             \
+        ctx_shift = (log2_size + 1) >> 2;                                       \
+    } else {                                                                    \
+        ctx_offset = 15;                                                        \
+        ctx_shift = log2_size - 2;                                              \
+    }                                                                           \
+    while (i < max &&                                                           \
+           GET_CABAC(elem_offset[elem] + (i >> ctx_shift) + ctx_offset))        \
+        i++;                                                                    \
+    return i;
+
+int ff_hevc_last_significant_coeff_x_prefix_decode(HEVCContext *s, int c_idx,
+                                                   int log2_size)
+{
+    LAST_SIG_COEFF(LAST_SIGNIFICANT_COEFF_X_PREFIX)
+}
+
+int ff_hevc_last_significant_coeff_y_prefix_decode(HEVCContext *s, int c_idx,
+                                                   int log2_size)
+{
+    LAST_SIG_COEFF(LAST_SIGNIFICANT_COEFF_Y_PREFIX)
+}
+
+int ff_hevc_last_significant_coeff_suffix_decode(HEVCContext *s,
+                                                 int last_significant_coeff_prefix)
+{
+    int i;
+    int length = (last_significant_coeff_prefix >> 1) - 1;
+    int value = get_cabac_bypass(&s->HEVClc.cc);
+
+    for (i = 1; i < length; i++)
+        value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc);
+    return value;
+}
+
+int ff_hevc_significant_coeff_group_flag_decode(HEVCContext *s, int c_idx, int ctx_cg)
+{
+    int inc;
+
+    inc = FFMIN(ctx_cg, 1) + (c_idx>0 ? 2 : 0);
+
+    return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_GROUP_FLAG] + inc);
+}
+
+int ff_hevc_significant_coeff_flag_decode(HEVCContext *s, int c_idx, int x_c, int y_c,
+                                          int log2_trafo_size, int scan_idx, int prev_sig)
+{
+    static const uint8_t ctx_idx_map[] = {
+        0, 1, 4, 5, 2, 3, 4, 5, 6, 6, 8, 8, 7, 7, 8, 8
+    };
+    int x_cg = x_c >> 2;
+    int y_cg = y_c >> 2;
+    int sig_ctx, inc;
+
+    if (x_c + y_c == 0) {
+        sig_ctx = 0;
+    } else if (log2_trafo_size == 2) {
+        sig_ctx = ctx_idx_map[(y_c << 2) + x_c];
+    } else {
+        switch (prev_sig) {
+        case 0: {
+                int x_off = x_c & 3;
+                int y_off = y_c & 3;
+                sig_ctx   = ((x_off + y_off) == 0) ? 2 : ((x_off + y_off) <= 2) ? 1 : 0;
+            }
+            break;
+        case 1:
+            sig_ctx = 2 - FFMIN(y_c & 3, 2);
+            break;
+        case 2:
+            sig_ctx = 2 - FFMIN(x_c & 3, 2);
+            break;
+        default:
+            sig_ctx = 2;
+        }
+
+        if (c_idx == 0 && (x_cg > 0 || y_cg > 0))
+            sig_ctx += 3;
+
+        if (log2_trafo_size == 3) {
+            sig_ctx += (scan_idx == SCAN_DIAG) ? 9 : 15;
+        } else {
+            sig_ctx += c_idx ? 12 : 21;
+        }
+    }
+
+    if (c_idx == 0)
+        inc = sig_ctx;
+    else
+        inc = sig_ctx + 27;
+
+    return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_FLAG] + inc);
+}
+
+int ff_hevc_coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx, int inc)
+{
+
+    if (c_idx > 0)
+        inc += 16;
+
+    return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER1_FLAG] + inc);
+}
+
+int ff_hevc_coeff_abs_level_greater2_flag_decode(HEVCContext *s, int c_idx, int inc)
+{
+    if (c_idx > 0)
+        inc += 4;
+
+    return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER2_FLAG] + inc);
+}
+
+int ff_hevc_coeff_abs_level_remaining(HEVCContext *s, int base_level, int rc_rice_param)
+{
+    int prefix = 0;
+    int suffix = 0;
+    int last_coeff_abs_level_remaining;
+    int i;
+
+    while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc))
+        prefix++;
+    if (prefix == CABAC_MAX_BIN)
+        av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix);
+    if (prefix < 3) {
+        for (i = 0; i < rc_rice_param; i++)
+            suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc.cc);
+        last_coeff_abs_level_remaining = (prefix << rc_rice_param) + suffix;
+    } else {
+        int prefix_minus3 = prefix - 3;
+        for (i = 0; i < prefix_minus3 + rc_rice_param; i++)
+            suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc.cc);
+        last_coeff_abs_level_remaining = (((1 << prefix_minus3) + 3 - 1)
+                                              << rc_rice_param) + suffix;
+    }
+    return last_coeff_abs_level_remaining;
+}
+
+int ff_hevc_coeff_sign_flag(HEVCContext *s, uint8_t nb)
+{
+    int i;
+    int ret = 0;
+
+    for (i = 0; i < nb; i++)
+        ret = (ret << 1) | get_cabac_bypass(&s->HEVClc.cc);
+    return ret;
+}
diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c
new file mode 100644
index 0000000..bb1e360
--- /dev/null
+++ b/libavcodec/hevc_filter.c
@@ -0,0 +1,745 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2013 Seppo Tomperi
+ * Copyright (C) 2013 Wassim Hamidouche
+ *
+ * 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/common.h"
+#include "libavutil/internal.h"
+
+#include "cabac_functions.h"
+#include "golomb.h"
+#include "hevc.h"
+
+#define LUMA 0
+#define CB 1
+#define CR 2
+
+static const uint8_t tctable[54] = {
+    0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 0, 0, 1, // QP  0...18
+    1, 1, 1, 1, 1, 1, 1,  1,  2,  2,  2,  2,  3,  3,  3,  3, 4, 4, 4, // QP 19...37
+    5, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 24           // QP 38...53
+};
+
+static const uint8_t betatable[52] = {
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  7,  8, // QP 0...18
+     9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, // QP 19...37
+    38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64                      // QP 38...51
+};
+
+static int chroma_tc(HEVCContext *s, int qp_y, int c_idx, int tc_offset)
+{
+    static const int qp_c[] = {
+        29, 30, 31, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37
+    };
+    int qp, qp_i, offset, idxt;
+
+    // slice qp offset is not used for deblocking
+    if (c_idx == 1)
+        offset = s->pps->cb_qp_offset;
+    else
+        offset = s->pps->cr_qp_offset;
+
+    qp_i = av_clip_c(qp_y + offset, 0, 57);
+    if (qp_i < 30)
+        qp = qp_i;
+    else if (qp_i > 43)
+        qp = qp_i - 6;
+    else
+        qp = qp_c[qp_i - 30];
+
+    idxt = av_clip_c(qp + DEFAULT_INTRA_TC_OFFSET + tc_offset, 0, 53);
+    return tctable[idxt];
+}
+
+static int get_qPy_pred(HEVCContext *s, int xC, int yC,
+                        int xBase, int yBase, int log2_cb_size)
+{
+    HEVCLocalContext *lc     = &s->HEVClc;
+    int ctb_size_mask        = (1 << s->sps->log2_ctb_size) - 1;
+    int MinCuQpDeltaSizeMask = (1 << (s->sps->log2_ctb_size -
+                                      s->pps->diff_cu_qp_delta_depth)) - 1;
+    int xQgBase              = xBase - (xBase & MinCuQpDeltaSizeMask);
+    int yQgBase              = yBase - (yBase & MinCuQpDeltaSizeMask);
+    int min_cb_width         = s->sps->min_cb_width;
+    int min_cb_height        = s->sps->min_cb_height;
+    int x_cb                 = xQgBase >> s->sps->log2_min_cb_size;
+    int y_cb                 = yQgBase >> s->sps->log2_min_cb_size;
+    int availableA           = (xBase   & ctb_size_mask) &&
+                               (xQgBase & ctb_size_mask);
+    int availableB           = (yBase   & ctb_size_mask) &&
+                               (yQgBase & ctb_size_mask);
+    int qPy_pred, qPy_a, qPy_b;
+
+    // qPy_pred
+    if (lc->first_qp_group) {
+        lc->first_qp_group = !lc->tu.is_cu_qp_delta_coded;
+        qPy_pred = s->sh.slice_qp;
+    } else {
+        qPy_pred = lc->qp_y;
+        if (log2_cb_size < s->sps->log2_ctb_size -
+                           s->pps->diff_cu_qp_delta_depth) {
+            static const int offsetX[8][8] = {
+                { -1, 1, 3, 1, 7, 1, 3, 1 },
+                {  0, 0, 0, 0, 0, 0, 0, 0 },
+                {  1, 3, 1, 3, 1, 3, 1, 3 },
+                {  2, 2, 2, 2, 2, 2, 2, 2 },
+                {  3, 5, 7, 5, 3, 5, 7, 5 },
+                {  4, 4, 4, 4, 4, 4, 4, 4 },
+                {  5, 7, 5, 7, 5, 7, 5, 7 },
+                {  6, 6, 6, 6, 6, 6, 6, 6 }
+            };
+            static const int offsetY[8][8] = {
+                { 7, 0, 1, 2, 3, 4, 5, 6 },
+                { 0, 1, 2, 3, 4, 5, 6, 7 },
+                { 1, 0, 3, 2, 5, 4, 7, 6 },
+                { 0, 1, 2, 3, 4, 5, 6, 7 },
+                { 3, 0, 1, 2, 7, 4, 5, 6 },
+                { 0, 1, 2, 3, 4, 5, 6, 7 },
+                { 1, 0, 3, 2, 5, 4, 7, 6 },
+                { 0, 1, 2, 3, 4, 5, 6, 7 }
+            };
+            int xC0b = (xC - (xC & ctb_size_mask)) >> s->sps->log2_min_cb_size;
+            int yC0b = (yC - (yC & ctb_size_mask)) >> s->sps->log2_min_cb_size;
+            int idxX = (xQgBase  & ctb_size_mask)  >> s->sps->log2_min_cb_size;
+            int idxY = (yQgBase  & ctb_size_mask)  >> s->sps->log2_min_cb_size;
+            int idx_mask = ctb_size_mask >> s->sps->log2_min_cb_size;
+            int x, y;
+
+            x = FFMIN(xC0b +  offsetX[idxX][idxY],             min_cb_width  - 1);
+            y = FFMIN(yC0b + (offsetY[idxX][idxY] & idx_mask), min_cb_height - 1);
+
+            if (xC0b == (lc->start_of_tiles_x >> s->sps->log2_min_cb_size) &&
+                offsetX[idxX][idxY] == -1) {
+                x = (lc->end_of_tiles_x >> s->sps->log2_min_cb_size) - 1;
+                y = yC0b - 1;
+            }
+            qPy_pred = s->qp_y_tab[y * min_cb_width + x];
+        }
+    }
+
+    // qPy_a
+    if (availableA == 0)
+        qPy_a = qPy_pred;
+    else
+        qPy_a = s->qp_y_tab[(x_cb - 1) + y_cb * min_cb_width];
+
+    // qPy_b
+    if (availableB == 0)
+        qPy_b = qPy_pred;
+    else
+        qPy_b = s->qp_y_tab[x_cb + (y_cb - 1) * min_cb_width];
+
+    return (qPy_a + qPy_b + 1) >> 1;
+}
+
+void ff_hevc_set_qPy(HEVCContext *s, int xC, int yC,
+                     int xBase, int yBase, int log2_cb_size)
+{
+    int qp_y = get_qPy_pred(s, xC, yC, xBase, yBase, log2_cb_size);
+
+    if (s->HEVClc.tu.cu_qp_delta != 0) {
+        int off = s->sps->qp_bd_offset;
+        s->HEVClc.qp_y = ((qp_y + s->HEVClc.tu.cu_qp_delta + 52 + 2 * off) %
+                          (52 + off)) - off;
+    } else
+        s->HEVClc.qp_y = qp_y;
+}
+
+static int get_qPy(HEVCContext *s, int xC, int yC)
+{
+    int log2_min_cb_size  = s->sps->log2_min_cb_size;
+    int x                 = xC >> log2_min_cb_size;
+    int y                 = yC >> log2_min_cb_size;
+    return s->qp_y_tab[x + y * s->sps->min_cb_width];
+}
+
+static void copy_CTB(uint8_t *dst, uint8_t *src,
+                     int width, int height, int stride)
+{
+    int i;
+
+    for (i = 0; i < height; i++) {
+        memcpy(dst, src, width);
+        dst += stride;
+        src += stride;
+    }
+}
+
+#define CTB(tab, x, y) ((tab)[(y) * s->sps->ctb_width + (x)])
+
+static void sao_filter_CTB(HEVCContext *s, int x, int y)
+{
+    //  TODO: This should be easily parallelizable
+    //  TODO: skip CBs when (cu_transquant_bypass_flag || (pcm_loop_filter_disable_flag && pcm_flag))
+    int c_idx = 0;
+    int class = 1, class_index;
+    int edges[4];  // 0 left 1 top 2 right 3 bottom
+    SAOParams *sao[4];
+    int classes[4];
+    int x_shift = 0, y_shift = 0;
+    int x_ctb = x >> s->sps->log2_ctb_size;
+    int y_ctb = y >> s->sps->log2_ctb_size;
+    int ctb_addr_rs = y_ctb * s->sps->ctb_width + x_ctb;
+    int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[ctb_addr_rs];
+
+    // flags indicating unfilterable edges
+    uint8_t vert_edge[]  = { 0, 0, 0, 0 };
+    uint8_t horiz_edge[] = { 0, 0, 0, 0 };
+    uint8_t diag_edge[]  = { 0, 0, 0, 0 };
+    uint8_t lfase[3]; // current, above, left
+    uint8_t no_tile_filter = s->pps->tiles_enabled_flag &&
+                             !s->pps->loop_filter_across_tiles_enabled_flag;
+    uint8_t left_tile_edge = 0, up_tile_edge = 0;
+
+    sao[0]     = &CTB(s->sao, x_ctb, y_ctb);
+    edges[0]   = x_ctb == 0;
+    edges[1]   = y_ctb == 0;
+    edges[2]   = x_ctb == s->sps->ctb_width  - 1;
+    edges[3]   = y_ctb == s->sps->ctb_height - 1;
+    lfase[0]   = CTB(s->filter_slice_edges, x_ctb, y_ctb);
+    classes[0] = 0;
+
+    if (!edges[0]) {
+        left_tile_edge = no_tile_filter && s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs-1]];
+        sao[class] = &CTB(s->sao, x_ctb - 1, y_ctb);
+        vert_edge[0] = (!lfase[0] && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb)) || left_tile_edge;
+        vert_edge[2] = vert_edge[0];
+        lfase[2]     = CTB(s->filter_slice_edges, x_ctb - 1, y_ctb);
+        classes[class] = 2;
+        class++;
+        x_shift = 8;
+    }
+
+    if (!edges[1]) {
+        up_tile_edge = no_tile_filter && s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[s->pps->ctb_addr_rs_to_ts[ctb_addr_rs - s->sps->ctb_width]];
+        sao[class] = &CTB(s->sao, x_ctb, y_ctb - 1);
+        horiz_edge[0] = (!lfase[0] && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb, y_ctb - 1)) || up_tile_edge;
+        horiz_edge[1] = horiz_edge[0];
+        lfase[1] = CTB(s->filter_slice_edges, x_ctb, y_ctb - 1);
+        classes[class] = 1;
+        class++;
+        y_shift = 4;
+
+        if (!edges[0]) {
+            classes[class] = 3;
+            sao[class] = &CTB(s->sao, x_ctb - 1, y_ctb - 1);
+            class++;
+
+            // Tile check here is done current CTB row/col, not above/left like you'd expect,
+            //but that is because the tile boundary always extends through the whole pic
+            vert_edge[1] = (!lfase[1] && CTB(s->tab_slice_address, x_ctb, y_ctb - 1) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb - 1)) || left_tile_edge;
+            vert_edge[3] = vert_edge[1];
+            horiz_edge[2] = (!lfase[2] && CTB(s->tab_slice_address, x_ctb - 1, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb - 1)) || up_tile_edge;
+            horiz_edge[3] = horiz_edge[2];
+            diag_edge[0] = (!lfase[0] && CTB(s->tab_slice_address, x_ctb, y_ctb) != CTB(s->tab_slice_address, x_ctb - 1, y_ctb - 1)) || left_tile_edge || up_tile_edge;
+            diag_edge[3] = diag_edge[0];
+
+            // Does left CTB comes after above CTB?
+            if (CTB(s->tab_slice_address, x_ctb - 1, y_ctb) >
+                CTB(s->tab_slice_address, x_ctb, y_ctb - 1)) {
+                diag_edge[2] = !lfase[2] || left_tile_edge || up_tile_edge;
+                diag_edge[1] = diag_edge[2];
+            } else if (CTB(s->tab_slice_address, x_ctb - 1, y_ctb) <
+                       CTB(s->tab_slice_address, x_ctb, y_ctb - 1)) {
+                diag_edge[1] = !lfase[1] || left_tile_edge || up_tile_edge;
+                diag_edge[2] = diag_edge[1];
+            } else {
+                // Same slice, only consider tiles
+                diag_edge[2] = left_tile_edge || up_tile_edge;
+                diag_edge[1] = diag_edge[2];
+            }
+        }
+    }
+
+    for (c_idx = 0; c_idx < 3; c_idx++) {
+        int chroma = c_idx ? 1 : 0;
+        int x0 = x >> chroma;
+        int y0 = y >> chroma;
+        int stride = s->frame->linesize[c_idx];
+        int ctb_size = (1 << (s->sps->log2_ctb_size)) >> s->sps->hshift[c_idx];
+        int width = FFMIN(ctb_size,
+                          (s->sps->width >> s->sps->hshift[c_idx]) - x0);
+        int height = FFMIN(ctb_size,
+                           (s->sps->height >> s->sps->vshift[c_idx]) - y0);
+
+        uint8_t *src = &s->frame->data[c_idx][y0 * stride + (x0 << s->sps->pixel_shift)];
+        uint8_t *dst = &s->sao_frame->data[c_idx][y0 * stride + (x0 << s->sps->pixel_shift)];
+        int offset = (y_shift >> chroma) * stride + ((x_shift >> chroma) << s->sps->pixel_shift);
+
+        copy_CTB(dst - offset, src - offset,
+                 (edges[2] ? width  + (x_shift >> chroma) : width)  << s->sps->pixel_shift,
+                 (edges[3] ? height + (y_shift >> chroma) : height), stride);
+
+        for (class_index = 0; class_index < class; class_index++) {
+
+            switch (sao[class_index]->type_idx[c_idx]) {
+            case SAO_BAND:
+                s->hevcdsp.sao_band_filter[classes[class_index]](dst, src,
+                                                                 stride,
+                                                                 sao[class_index],
+                                                                 edges, width,
+                                                                 height, c_idx);
+                break;
+            case SAO_EDGE:
+                s->hevcdsp.sao_edge_filter[classes[class_index]](dst, src,
+                                                                 stride,
+                                                                 sao[class_index],
+                                                                 edges, width,
+                                                                 height, c_idx,
+                                                                 vert_edge[classes[class_index]],
+                                                                 horiz_edge[classes[class_index]],
+                                                                 diag_edge[classes[class_index]]);
+                break;
+            }
+        }
+    }
+}
+
+static int get_pcm(HEVCContext *s, int x, int y)
+{
+    int log2_min_pu_size = s->sps->log2_min_pu_size;
+    int x_pu             = x >> log2_min_pu_size;
+    int y_pu             = y >> log2_min_pu_size;
+
+    if (x < 0 || x_pu >= s->sps->min_pu_width ||
+        y < 0 || y_pu >= s->sps->min_pu_height)
+        return 2;
+    return s->is_pcm[y_pu * s->sps->min_pu_width + x_pu];
+}
+
+#define TC_CALC(qp, bs)                                                 \
+    tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) +       \
+                    (tc_offset >> 1 << 1),                              \
+                    0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
+
+static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
+{
+    uint8_t *src;
+    int x, y, x_end, y_end, chroma;
+    int c_tc[2], beta[2], tc[2];
+    uint8_t no_p[2] = { 0 };
+    uint8_t no_q[2] = { 0 };
+
+    int log2_ctb_size = s->sps->log2_ctb_size;
+    int ctb_size        = 1 << log2_ctb_size;
+    int ctb             = (x0 >> log2_ctb_size) +
+                          (y0 >> log2_ctb_size) * s->sps->ctb_width;
+    int cur_tc_offset   = s->deblock[ctb].tc_offset;
+    int cur_beta_offset = s->deblock[ctb].beta_offset;
+    int tc_offset, left_tc_offset, beta_offset, left_beta_offset;
+    int pcmf = (s->sps->pcm_enabled_flag &&
+                s->sps->pcm.loop_filter_disable_flag) ||
+               s->pps->transquant_bypass_enable_flag;
+
+    if (x0) {
+        left_tc_offset   = s->deblock[ctb - 1].tc_offset;
+        left_beta_offset = s->deblock[ctb - 1].beta_offset;
+    }
+
+    x_end = x0 + ctb_size;
+    if (x_end > s->sps->width)
+        x_end = s->sps->width;
+    y_end = y0 + ctb_size;
+    if (y_end > s->sps->height)
+        y_end = s->sps->height;
+
+    tc_offset   = cur_tc_offset;
+    beta_offset = cur_beta_offset;
+
+    // vertical filtering luma
+    for (y = y0; y < y_end; y += 8) {
+        for (x = x0 ? x0 : 8; x < x_end; x += 8) {
+            const int bs0 = s->vertical_bs[(x >> 3) + (y       >> 2) * s->bs_width];
+            const int bs1 = s->vertical_bs[(x >> 3) + ((y + 4) >> 2) * s->bs_width];
+            if (bs0 || bs1) {
+                const int qp0 = (get_qPy(s, x - 1, y)     + get_qPy(s, x, y)     + 1) >> 1;
+                const int qp1 = (get_qPy(s, x - 1, y + 4) + get_qPy(s, x, y + 4) + 1) >> 1;
+
+                beta[0] = betatable[av_clip(qp0 + (beta_offset >> 1 << 1), 0, MAX_QP)];
+                beta[1] = betatable[av_clip(qp1 + (beta_offset >> 1 << 1), 0, MAX_QP)];
+                tc[0]   = bs0 ? TC_CALC(qp0, bs0) : 0;
+                tc[1]   = bs1 ? TC_CALC(qp1, bs1) : 0;
+                src     = &s->frame->data[LUMA][y * s->frame->linesize[LUMA] + (x << s->sps->pixel_shift)];
+                if (pcmf) {
+                    no_p[0] = get_pcm(s, x - 1, y);
+                    no_p[1] = get_pcm(s, x - 1, y + 4);
+                    no_q[0] = get_pcm(s, x, y);
+                    no_q[1] = get_pcm(s, x, y + 4);
+                    s->hevcdsp.hevc_v_loop_filter_luma_c(src,
+                                                         s->frame->linesize[LUMA],
+                                                         beta, tc, no_p, no_q);
+                } else
+                    s->hevcdsp.hevc_v_loop_filter_luma(src,
+                                                       s->frame->linesize[LUMA],
+                                                       beta, tc, no_p, no_q);
+            }
+        }
+    }
+
+    // vertical filtering chroma
+    for (chroma = 1; chroma <= 2; chroma++) {
+        for (y = y0; y < y_end; y += 16) {
+            for (x = x0 ? x0 : 16; x < x_end; x += 16) {
+                const int bs0 = s->vertical_bs[(x >> 3) + (y       >> 2) * s->bs_width];
+                const int bs1 = s->vertical_bs[(x >> 3) + ((y + 8) >> 2) * s->bs_width];
+                if ((bs0 == 2) || (bs1 == 2)) {
+                    const int qp0 = (get_qPy(s, x - 1, y)     + get_qPy(s, x, y)     + 1) >> 1;
+                    const int qp1 = (get_qPy(s, x - 1, y + 8) + get_qPy(s, x, y + 8) + 1) >> 1;
+
+                    c_tc[0] = (bs0 == 2) ? chroma_tc(s, qp0, chroma, tc_offset) : 0;
+                    c_tc[1] = (bs1 == 2) ? chroma_tc(s, qp1, chroma, tc_offset) : 0;
+                    src     = &s->frame->data[chroma][y / 2 * s->frame->linesize[chroma] + ((x / 2) << s->sps->pixel_shift)];
+                    if (pcmf) {
+                        no_p[0] = get_pcm(s, x - 1, y);
+                        no_p[1] = get_pcm(s, x - 1, y + 8);
+                        no_q[0] = get_pcm(s, x, y);
+                        no_q[1] = get_pcm(s, x, y + 8);
+                        s->hevcdsp.hevc_v_loop_filter_chroma_c(src,
+                                                               s->frame->linesize[chroma],
+                                                               c_tc, no_p, no_q);
+                    } else
+                        s->hevcdsp.hevc_v_loop_filter_chroma(src,
+                                                             s->frame->linesize[chroma],
+                                                             c_tc, no_p, no_q);
+                }
+            }
+        }
+    }
+
+    // horizontal filtering luma
+    if (x_end != s->sps->width)
+        x_end -= 8;
+    for (y = y0 ? y0 : 8; y < y_end; y += 8) {
+        for (x = x0 ? x0 - 8 : 0; x < x_end; x += 8) {
+            const int bs0 = s->horizontal_bs[(x +     y * s->bs_width) >> 2];
+            const int bs1 = s->horizontal_bs[(x + 4 + y * s->bs_width) >> 2];
+            if (bs0 || bs1) {
+                const int qp0 = (get_qPy(s, x, y - 1)     + get_qPy(s, x, y)     + 1) >> 1;
+                const int qp1 = (get_qPy(s, x + 4, y - 1) + get_qPy(s, x + 4, y) + 1) >> 1;
+
+                tc_offset   = x >= x0 ? cur_tc_offset : left_tc_offset;
+                beta_offset = x >= x0 ? cur_beta_offset : left_beta_offset;
+
+                beta[0] = betatable[av_clip(qp0 + (beta_offset >> 1 << 1), 0, MAX_QP)];
+                beta[1] = betatable[av_clip(qp1 + (beta_offset >> 1 << 1), 0, MAX_QP)];
+                tc[0]   = bs0 ? TC_CALC(qp0, bs0) : 0;
+                tc[1]   = bs1 ? TC_CALC(qp1, bs1) : 0;
+                src     = &s->frame->data[LUMA][y * s->frame->linesize[LUMA] + (x << s->sps->pixel_shift)];
+                if (pcmf) {
+                    no_p[0] = get_pcm(s, x, y - 1);
+                    no_p[1] = get_pcm(s, x + 4, y - 1);
+                    no_q[0] = get_pcm(s, x, y);
+                    no_q[1] = get_pcm(s, x + 4, y);
+                    s->hevcdsp.hevc_h_loop_filter_luma_c(src,
+                                                         s->frame->linesize[LUMA],
+                                                         beta, tc, no_p, no_q);
+                } else
+                    s->hevcdsp.hevc_h_loop_filter_luma(src,
+                                                       s->frame->linesize[LUMA],
+                                                       beta, tc, no_p, no_q);
+            }
+        }
+    }
+
+    // horizontal filtering chroma
+    for (chroma = 1; chroma <= 2; chroma++) {
+        for (y = y0 ? y0 : 16; y < y_end; y += 16) {
+            for (x = x0 - 8; x < x_end; x += 16) {
+                int bs0, bs1;
+                // to make sure no memory access over boundary when x = -8
+                // TODO: simplify with row based deblocking
+                if (x < 0) {
+                    bs0 = 0;
+                    bs1 = s->horizontal_bs[(x + 8 + y * s->bs_width) >> 2];
+                } else if (x >= x_end - 8) {
+                    bs0 = s->horizontal_bs[(x +     y * s->bs_width) >> 2];
+                    bs1 = 0;
+                } else {
+                    bs0 = s->horizontal_bs[(x + y     * s->bs_width) >> 2];
+                    bs1 = s->horizontal_bs[(x + 8 + y * s->bs_width) >> 2];
+                }
+
+                if ((bs0 == 2) || (bs1 == 2)) {
+                    const int qp0 = bs0 == 2 ? (get_qPy(s, x,     y - 1) + get_qPy(s, x,     y) + 1) >> 1 : 0;
+                    const int qp1 = bs1 == 2 ? (get_qPy(s, x + 8, y - 1) + get_qPy(s, x + 8, y) + 1) >> 1 : 0;
+
+                    tc_offset = x >= x0 ? cur_tc_offset : left_tc_offset;
+                    c_tc[0]   = bs0 == 2 ? chroma_tc(s, qp0, chroma, tc_offset)     : 0;
+                    c_tc[1]   = bs1 == 2 ? chroma_tc(s, qp1, chroma, cur_tc_offset) : 0;
+                    src       = &s->frame->data[chroma][y / 2 * s->frame->linesize[chroma] + ((x / 2) << s->sps->pixel_shift)];
+                    if (pcmf) {
+                        no_p[0] = get_pcm(s, x, y - 1);
+                        no_p[1] = get_pcm(s, x + 8, y - 1);
+                        no_q[0] = get_pcm(s, x, y);
+                        no_q[1] = get_pcm(s, x + 8, y);
+                        s->hevcdsp.hevc_h_loop_filter_chroma_c(src,
+                                                               s->frame->linesize[chroma],
+                                                               c_tc, no_p, no_q);
+                    } else
+                        s->hevcdsp.hevc_h_loop_filter_chroma(src,
+                                                             s->frame->linesize[chroma],
+                                                             c_tc, no_p, no_q);
+                }
+            }
+        }
+    }
+}
+
+static int boundary_strength(HEVCContext *s, MvField *curr,
+                             uint8_t curr_cbf_luma, MvField *neigh,
+                             uint8_t neigh_cbf_luma,
+                             RefPicList *neigh_refPicList,
+                             int tu_border)
+{
+    int mvs = curr->pred_flag[0] + curr->pred_flag[1];
+
+    if (tu_border) {
+        if (curr->is_intra || neigh->is_intra)
+            return 2;
+        if (curr_cbf_luma || neigh_cbf_luma)
+            return 1;
+    }
+
+    if (mvs == neigh->pred_flag[0] + neigh->pred_flag[1]) {
+        if (mvs == 2) {
+            // same L0 and L1
+            if (s->ref->refPicList[0].list[curr->ref_idx[0]] == neigh_refPicList[0].list[neigh->ref_idx[0]]  &&
+                s->ref->refPicList[0].list[curr->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]] &&
+                neigh_refPicList[0].list[neigh->ref_idx[0]] == neigh_refPicList[1].list[neigh->ref_idx[1]]) {
+                if ((abs(neigh->mv[0].x - curr->mv[0].x) >= 4 || abs(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
+                     abs(neigh->mv[1].x - curr->mv[1].x) >= 4 || abs(neigh->mv[1].y - curr->mv[1].y) >= 4) &&
+                    (abs(neigh->mv[1].x - curr->mv[0].x) >= 4 || abs(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
+                     abs(neigh->mv[0].x - curr->mv[1].x) >= 4 || abs(neigh->mv[0].y - curr->mv[1].y) >= 4))
+                    return 1;
+                else
+                    return 0;
+            } else if (neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
+                       neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
+                if (abs(neigh->mv[0].x - curr->mv[0].x) >= 4 || abs(neigh->mv[0].y - curr->mv[0].y) >= 4 ||
+                    abs(neigh->mv[1].x - curr->mv[1].x) >= 4 || abs(neigh->mv[1].y - curr->mv[1].y) >= 4)
+                    return 1;
+                else
+                    return 0;
+            } else if (neigh_refPicList[1].list[neigh->ref_idx[1]] == s->ref->refPicList[0].list[curr->ref_idx[0]] &&
+                       neigh_refPicList[0].list[neigh->ref_idx[0]] == s->ref->refPicList[1].list[curr->ref_idx[1]]) {
+                if (abs(neigh->mv[1].x - curr->mv[0].x) >= 4 || abs(neigh->mv[1].y - curr->mv[0].y) >= 4 ||
+                    abs(neigh->mv[0].x - curr->mv[1].x) >= 4 || abs(neigh->mv[0].y - curr->mv[1].y) >= 4)
+                    return 1;
+                else
+                    return 0;
+            } else {
+                return 1;
+            }
+        } else { // 1 MV
+            Mv A, B;
+            int ref_A, ref_B;
+
+            if (curr->pred_flag[0]) {
+                A     = curr->mv[0];
+                ref_A = s->ref->refPicList[0].list[curr->ref_idx[0]];
+            } else {
+                A     = curr->mv[1];
+                ref_A = s->ref->refPicList[1].list[curr->ref_idx[1]];
+            }
+
+            if (neigh->pred_flag[0]) {
+                B     = neigh->mv[0];
+                ref_B = neigh_refPicList[0].list[neigh->ref_idx[0]];
+            } else {
+                B     = neigh->mv[1];
+                ref_B = neigh_refPicList[1].list[neigh->ref_idx[1]];
+            }
+
+            if (ref_A == ref_B) {
+                if (abs(A.x - B.x) >= 4 || abs(A.y - B.y) >= 4)
+                    return 1;
+                else
+                    return 0;
+            } else
+                return 1;
+        }
+    }
+
+    return 1;
+}
+
+void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0,
+                                           int log2_trafo_size,
+                                           int slice_or_tiles_up_boundary,
+                                           int slice_or_tiles_left_boundary)
+{
+    MvField *tab_mvf     = s->ref->tab_mvf;
+    int log2_min_pu_size = s->sps->log2_min_pu_size;
+    int log2_min_tu_size = s->sps->log2_min_tb_size;
+    int min_pu_width     = s->sps->min_pu_width;
+    int min_tu_width     = s->sps->min_tb_width;
+    int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
+                           (x0 >> log2_min_pu_size)].is_intra;
+    int i, j, bs;
+
+    if (y0 > 0 && (y0 & 7) == 0) {
+        int yp_pu = (y0 - 1) >> log2_min_pu_size;
+        int yq_pu =  y0      >> log2_min_pu_size;
+        int yp_tu = (y0 - 1) >> log2_min_tu_size;
+        int yq_tu =  y0      >> log2_min_tu_size;
+
+        for (i = 0; i < (1 << log2_trafo_size); i += 4) {
+            int x_pu = (x0 + i) >> log2_min_pu_size;
+            int x_tu = (x0 + i) >> log2_min_tu_size;
+            MvField *top  = &tab_mvf[yp_pu * min_pu_width + x_pu];
+            MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
+            uint8_t top_cbf_luma  = s->cbf_luma[yp_tu * min_tu_width + x_tu];
+            uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
+            RefPicList *top_refPicList = ff_hevc_get_ref_list(s, s->ref,
+                                                              x0 + i, y0 - 1);
+
+            bs = boundary_strength(s, curr, curr_cbf_luma,
+                                   top, top_cbf_luma, top_refPicList, 1);
+            if (!s->sh.slice_loop_filter_across_slices_enabled_flag &&
+                (slice_or_tiles_up_boundary & 1) &&
+                (y0 % (1 << s->sps->log2_ctb_size)) == 0)
+                bs = 0;
+            else if (!s->pps->loop_filter_across_tiles_enabled_flag &&
+                     (slice_or_tiles_up_boundary & 2) &&
+                     (y0 % (1 << s->sps->log2_ctb_size)) == 0)
+                bs = 0;
+            if (y0 == 0 || s->sh.disable_deblocking_filter_flag == 1)
+                bs = 0;
+            if (bs)
+                s->horizontal_bs[((x0 + i) + y0 * s->bs_width) >> 2] = bs;
+        }
+    }
+
+    // bs for TU internal horizontal PU boundaries
+    if (log2_trafo_size > s->sps->log2_min_pu_size && !is_intra)
+        for (j = 8; j < (1 << log2_trafo_size); j += 8) {
+            int yp_pu = (y0 + j - 1) >> log2_min_pu_size;
+            int yq_pu = (y0 + j)     >> log2_min_pu_size;
+            int yp_tu = (y0 + j - 1) >> log2_min_tu_size;
+            int yq_tu = (y0 + j)     >> log2_min_tu_size;
+
+            for (i = 0; i < (1 << log2_trafo_size); i += 4) {
+                int x_pu = (x0 + i) >> log2_min_pu_size;
+                int x_tu = (x0 + i) >> log2_min_tu_size;
+                MvField *top  = &tab_mvf[yp_pu * min_pu_width + x_pu];
+                MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
+                uint8_t top_cbf_luma  = s->cbf_luma[yp_tu * min_tu_width + x_tu];
+                uint8_t curr_cbf_luma = s->cbf_luma[yq_tu * min_tu_width + x_tu];
+                RefPicList *top_refPicList = ff_hevc_get_ref_list(s, s->ref,
+                                                                  x0 + i,
+                                                                  y0 + j - 1);
+
+                bs = boundary_strength(s, curr, curr_cbf_luma,
+                                       top, top_cbf_luma, top_refPicList, 0);
+                if (s->sh.disable_deblocking_filter_flag == 1)
+                    bs = 0;
+                if (bs)
+                    s->horizontal_bs[((x0 + i) + (y0 + j) * s->bs_width) >> 2] = bs;
+            }
+        }
+
+    // bs for vertical TU boundaries
+    if (x0 > 0 && (x0 & 7) == 0) {
+        int xp_pu = (x0 - 1) >> log2_min_pu_size;
+        int xq_pu =  x0      >> log2_min_pu_size;
+        int xp_tu = (x0 - 1) >> log2_min_tu_size;
+        int xq_tu =  x0      >> log2_min_tu_size;
+
+        for (i = 0; i < (1 << log2_trafo_size); i += 4) {
+            int y_pu      = (y0 + i) >> log2_min_pu_size;
+            int y_tu      = (y0 + i) >> log2_min_tu_size;
+            MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
+            MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
+
+            uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
+            uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
+            RefPicList *left_refPicList = ff_hevc_get_ref_list(s, s->ref,
+                                                               x0 - 1, y0 + i);
+
+            bs = boundary_strength(s, curr, curr_cbf_luma,
+                                   left, left_cbf_luma, left_refPicList, 1);
+            if (!s->sh.slice_loop_filter_across_slices_enabled_flag &&
+                (slice_or_tiles_left_boundary & 1) &&
+                (x0 % (1 << s->sps->log2_ctb_size)) == 0)
+                bs = 0;
+            else if (!s->pps->loop_filter_across_tiles_enabled_flag &&
+                     (slice_or_tiles_left_boundary & 2) &&
+                     (x0 % (1 << s->sps->log2_ctb_size)) == 0)
+                bs = 0;
+            if (x0 == 0 || s->sh.disable_deblocking_filter_flag == 1)
+                bs = 0;
+            if (bs)
+                s->vertical_bs[(x0 >> 3) + ((y0 + i) >> 2) * s->bs_width] = bs;
+        }
+    }
+
+    // bs for TU internal vertical PU boundaries
+    if (log2_trafo_size > log2_min_pu_size && !is_intra)
+        for (j = 0; j < (1 << log2_trafo_size); j += 4) {
+            int y_pu = (y0 + j) >> log2_min_pu_size;
+            int y_tu = (y0 + j) >> log2_min_tu_size;
+
+            for (i = 8; i < (1 << log2_trafo_size); i += 8) {
+                int xp_pu = (x0 + i - 1) >> log2_min_pu_size;
+                int xq_pu = (x0 + i)     >> log2_min_pu_size;
+                int xp_tu = (x0 + i - 1) >> log2_min_tu_size;
+                int xq_tu = (x0 + i)     >> log2_min_tu_size;
+                MvField *left = &tab_mvf[y_pu * min_pu_width + xp_pu];
+                MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
+                uint8_t left_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xp_tu];
+                uint8_t curr_cbf_luma = s->cbf_luma[y_tu * min_tu_width + xq_tu];
+                RefPicList *left_refPicList = ff_hevc_get_ref_list(s, s->ref,
+                                                                   x0 + i - 1,
+                                                                   y0 + j);
+
+                bs = boundary_strength(s, curr, curr_cbf_luma,
+                                       left, left_cbf_luma, left_refPicList, 0);
+                if (s->sh.disable_deblocking_filter_flag == 1)
+                    bs = 0;
+                if (bs)
+                    s->vertical_bs[((x0 + i) >> 3) + ((y0 + j) >> 2) * s->bs_width] = bs;
+            }
+        }
+}
+
+#undef LUMA
+#undef CB
+#undef CR
+
+void ff_hevc_hls_filter(HEVCContext *s, int x, int y)
+{
+    deblocking_filter_CTB(s, x, y);
+    if (s->sps->sao_enabled)
+        sao_filter_CTB(s, x, y);
+}
+
+void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size)
+{
+    if (y_ctb && x_ctb)
+        ff_hevc_hls_filter(s, x_ctb - ctb_size, y_ctb - ctb_size);
+    if (y_ctb && x_ctb >= s->sps->width - ctb_size) {
+        ff_hevc_hls_filter(s, x_ctb, y_ctb - ctb_size);
+        ff_thread_report_progress(&s->ref->tf, y_ctb - ctb_size, 0);
+    }
+    if (x_ctb && y_ctb >= s->sps->height - ctb_size)
+        ff_hevc_hls_filter(s, x_ctb - ctb_size, y_ctb);
+}
diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c
new file mode 100644
index 0000000..49d5ff2
--- /dev/null
+++ b/libavcodec/hevc_mvs.c
@@ -0,0 +1,816 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2013 Anand Meher Kotra
+ *
+ * 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 "hevc.h"
+
+static const uint8_t l0_l1_cand_idx[12][2] = {
+    { 0, 1, },
+    { 1, 0, },
+    { 0, 2, },
+    { 2, 0, },
+    { 1, 2, },
+    { 2, 1, },
+    { 0, 3, },
+    { 3, 0, },
+    { 1, 3, },
+    { 3, 1, },
+    { 2, 3, },
+    { 3, 2, },
+};
+
+void ff_hevc_set_neighbour_available(HEVCContext *s, int x0, int y0,
+                                     int nPbW, int nPbH)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+    int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+    lc->na.cand_up       = (lc->ctb_up_flag   || y0b);
+    lc->na.cand_left     = (lc->ctb_left_flag || x0b);
+    lc->na.cand_up_left  = (!x0b && !y0b) ? lc->ctb_up_left_flag : lc->na.cand_left && lc->na.cand_up;
+    lc->na.cand_up_right_sap =
+            ((x0b + nPbW) == (1 << s->sps->log2_ctb_size)) ?
+                    lc->ctb_up_right_flag && !y0b : lc->na.cand_up;
+    lc->na.cand_up_right =
+            ((x0b + nPbW) == (1 << s->sps->log2_ctb_size) ?
+                    lc->ctb_up_right_flag && !y0b : lc->na.cand_up )
+                     && (x0 + nPbW) < lc->end_of_tiles_x;
+    lc->na.cand_bottom_left = ((y0 + nPbH) >= lc->end_of_tiles_y) ? 0 : lc->na.cand_left;
+}
+
+/*
+ * 6.4.1 Derivation process for z-scan order block availability
+ */
+static int z_scan_block_avail(HEVCContext *s, int xCurr, int yCurr,
+                              int xN, int yN)
+{
+#define MIN_TB_ADDR_ZS(x, y)                                            \
+    s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)]
+    int Curr = MIN_TB_ADDR_ZS(xCurr >> s->sps->log2_min_tb_size,
+                              yCurr >> s->sps->log2_min_tb_size);
+    int N;
+
+    if (xN < 0 || yN < 0 ||
+        xN >= s->sps->width ||
+        yN >= s->sps->height)
+        return 0;
+
+    N = MIN_TB_ADDR_ZS(xN >> s->sps->log2_min_tb_size,
+                       yN >> s->sps->log2_min_tb_size);
+
+    return N <= Curr;
+}
+
+static int same_prediction_block(HEVCLocalContext *lc, int log2_cb_size,
+                                 int x0, int y0, int nPbW, int nPbH,
+                                 int xA1, int yA1, int partIdx)
+{
+    return !(nPbW << 1 == 1 << log2_cb_size &&
+             nPbH << 1 == 1 << log2_cb_size && partIdx == 1 &&
+             lc->cu.x + nPbW > xA1 &&
+             lc->cu.y + nPbH <= yA1);
+}
+
+/*
+ * 6.4.2 Derivation process for prediction block availability
+ */
+static int check_prediction_block_available(HEVCContext *s, int log2_cb_size,
+                                            int x0, int y0, int nPbW, int nPbH,
+                                            int xA1, int yA1, int partIdx)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+
+    if (lc->cu.x < xA1 && lc->cu.y < yA1 &&
+        (lc->cu.x + (1 << log2_cb_size)) > xA1 &&
+        (lc->cu.y + (1 << log2_cb_size)) > yA1)
+        return same_prediction_block(lc, log2_cb_size, x0, y0,
+                                     nPbW, nPbH, xA1, yA1, partIdx);
+    else
+        return z_scan_block_avail(s, x0, y0, xA1, yA1);
+}
+
+//check if the two luma locations belong to the same mostion estimation region
+static int isDiffMER(HEVCContext *s, int xN, int yN, int xP, int yP)
+{
+    uint8_t plevel = s->pps->log2_parallel_merge_level;
+
+    return xN >> plevel == xP >> plevel &&
+           yN >> plevel == yP >> plevel;
+}
+
+#define MATCH(x) (A.x == B.x)
+
+// check if the mv's and refidx are the same between A and B
+static int compareMVrefidx(struct MvField A, struct MvField B)
+{
+    if (A.pred_flag[0] && A.pred_flag[1] && B.pred_flag[0] && B.pred_flag[1])
+        return MATCH(ref_idx[0]) && MATCH(mv[0].x) && MATCH(mv[0].y) &&
+               MATCH(ref_idx[1]) && MATCH(mv[1].x) && MATCH(mv[1].y);
+
+    if (A.pred_flag[0] && !A.pred_flag[1] && B.pred_flag[0] && !B.pred_flag[1])
+        return MATCH(ref_idx[0]) && MATCH(mv[0].x) && MATCH(mv[0].y);
+
+    if (!A.pred_flag[0] && A.pred_flag[1] && !B.pred_flag[0] && B.pred_flag[1])
+        return MATCH(ref_idx[1]) && MATCH(mv[1].x) && MATCH(mv[1].y);
+
+    return 0;
+}
+
+static av_always_inline void mv_scale(Mv *dst, Mv *src, int td, int tb)
+{
+    int tx, scale_factor;
+
+    td = av_clip_int8_c(td);
+    tb = av_clip_int8_c(tb);
+    tx = (0x4000 + abs(td / 2)) / td;
+    scale_factor = av_clip_c((tb * tx + 32) >> 6, -4096, 4095);
+    dst->x = av_clip_int16_c((scale_factor * src->x + 127 +
+                             (scale_factor * src->x < 0)) >> 8);
+    dst->y = av_clip_int16_c((scale_factor * src->y + 127 +
+                             (scale_factor * src->y < 0)) >> 8);
+}
+
+static int check_mvset(Mv *mvLXCol, Mv *mvCol,
+                       int colPic, int poc,
+                       RefPicList *refPicList, int X, int refIdxLx,
+                       RefPicList *refPicList_col, int listCol, int refidxCol)
+{
+    int cur_lt = refPicList[X].isLongTerm[refIdxLx];
+    int col_lt = refPicList_col[listCol].isLongTerm[refidxCol];
+    int col_poc_diff, cur_poc_diff;
+
+    if (cur_lt != col_lt) {
+        mvLXCol->x = 0;
+        mvLXCol->y = 0;
+        return 0;
+    }
+
+    col_poc_diff = colPic - refPicList_col[listCol].list[refidxCol];
+    cur_poc_diff = poc    - refPicList[X].list[refIdxLx];
+
+    if (!col_poc_diff)
+        col_poc_diff = 1;  // error resilience
+
+    if (cur_lt || col_poc_diff == cur_poc_diff) {
+        mvLXCol->x = mvCol->x;
+        mvLXCol->y = mvCol->y;
+    } else {
+        mv_scale(mvLXCol, mvCol, col_poc_diff, cur_poc_diff);
+    }
+    return 1;
+}
+
+#define CHECK_MVSET(l)                                          \
+    check_mvset(mvLXCol, temp_col.mv + l,                       \
+                colPic, s->poc,                                 \
+                refPicList, X, refIdxLx,                        \
+                refPicList_col, L ## l, temp_col.ref_idx[l])
+
+// derive the motion vectors section 8.5.3.1.8
+static int derive_temporal_colocated_mvs(HEVCContext *s, MvField temp_col,
+                                         int refIdxLx, Mv *mvLXCol, int X,
+                                         int colPic, RefPicList *refPicList_col)
+{
+    RefPicList *refPicList = s->ref->refPicList;
+
+    if (temp_col.is_intra) {
+        mvLXCol->x = 0;
+        mvLXCol->y = 0;
+        return 0;
+    }
+
+    if (temp_col.pred_flag[0] == 0)
+        return CHECK_MVSET(1);
+    else if (temp_col.pred_flag[0] == 1 && temp_col.pred_flag[1] == 0)
+        return CHECK_MVSET(0);
+    else if (temp_col.pred_flag[0] == 1 && temp_col.pred_flag[1] == 1) {
+        int check_diffpicount = 0;
+        int i = 0;
+        for (i = 0; i < refPicList[0].nb_refs; i++) {
+            if (refPicList[0].list[i] > s->poc)
+                check_diffpicount++;
+        }
+        for (i = 0; i < refPicList[1].nb_refs; i++) {
+            if (refPicList[1].list[i] > s->poc)
+                check_diffpicount++;
+        }
+        if (check_diffpicount == 0 && X == 0)
+            return CHECK_MVSET(0);
+        else if (check_diffpicount == 0 && X == 1)
+            return CHECK_MVSET(1);
+        else {
+            if (s->sh.collocated_list == L1)
+                return CHECK_MVSET(0);
+            else
+                return CHECK_MVSET(1);
+        }
+    }
+
+    return 0;
+}
+
+#define TAB_MVF(x, y)                                                   \
+    tab_mvf[(y) * min_pu_width + x]
+
+#define TAB_MVF_PU(v)                                                   \
+    TAB_MVF(x ## v ## _pu, y ## v ## _pu)
+
+#define DERIVE_TEMPORAL_COLOCATED_MVS                                   \
+    derive_temporal_colocated_mvs(s, temp_col,                          \
+                                  refIdxLx, mvLXCol, X, colPic,         \
+                                  ff_hevc_get_ref_list(s, ref, x, y))
+
+/*
+ * 8.5.3.1.7  temporal luma motion vector prediction
+ */
+static int temporal_luma_motion_vector(HEVCContext *s, int x0, int y0,
+                                       int nPbW, int nPbH, int refIdxLx,
+                                       Mv *mvLXCol, int X)
+{
+    MvField *tab_mvf;
+    MvField temp_col;
+    int x, y, x_pu, y_pu;
+    int min_pu_width = s->sps->min_pu_width;
+    int availableFlagLXCol = 0;
+    int colPic;
+
+    HEVCFrame *ref = s->ref->collocated_ref;
+
+    if (!ref)
+        return 0;
+
+    tab_mvf = ref->tab_mvf;
+    colPic  = ref->poc;
+
+    //bottom right collocated motion vector
+    x = x0 + nPbW;
+    y = y0 + nPbH;
+
+    ff_thread_await_progress(&ref->tf, y, 0);
+    if (tab_mvf &&
+        (y0 >> s->sps->log2_ctb_size) == (y >> s->sps->log2_ctb_size) &&
+        y < s->sps->height &&
+        x < s->sps->width) {
+        x                  = ((x >> 4) << 4);
+        y                  = ((y >> 4) << 4);
+        x_pu               = x >> s->sps->log2_min_pu_size;
+        y_pu               = y >> s->sps->log2_min_pu_size;
+        temp_col           = TAB_MVF(x_pu, y_pu);
+        availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
+    }
+
+    // derive center collocated motion vector
+    if (tab_mvf && !availableFlagLXCol) {
+        x                  = x0 + (nPbW >> 1);
+        y                  = y0 + (nPbH >> 1);
+        x                  = ((x >> 4) << 4);
+        y                  = ((y >> 4) << 4);
+        x_pu               = x >> s->sps->log2_min_pu_size;
+        y_pu               = y >> s->sps->log2_min_pu_size;
+        temp_col           = TAB_MVF(x_pu, y_pu);
+        availableFlagLXCol = DERIVE_TEMPORAL_COLOCATED_MVS;
+    }
+    return availableFlagLXCol;
+}
+
+#define AVAILABLE(cand, v)                                      \
+    (cand && !TAB_MVF_PU(v).is_intra)
+
+#define PRED_BLOCK_AVAILABLE(v)                                 \
+    check_prediction_block_available(s, log2_cb_size,           \
+                                     x0, y0, nPbW, nPbH,        \
+                                     x ## v, y ## v, part_idx)
+
+#define COMPARE_MV_REFIDX(a, b)                                 \
+    compareMVrefidx(TAB_MVF_PU(a), TAB_MVF_PU(b))
+
+/*
+ * 8.5.3.1.2  Derivation process for spatial merging candidates
+ */
+static void derive_spatial_merge_candidates(HEVCContext *s, int x0, int y0,
+                                            int nPbW, int nPbH,
+                                            int log2_cb_size,
+                                            int singleMCLFlag, int part_idx,
+                                            struct MvField mergecandlist[])
+{
+    HEVCLocalContext *lc   = &s->HEVClc;
+    RefPicList *refPicList = s->ref->refPicList;
+    MvField *tab_mvf       = s->ref->tab_mvf;
+
+    const int min_pu_width = s->sps->min_pu_width;
+
+    const int cand_bottom_left = lc->na.cand_bottom_left;
+    const int cand_left        = lc->na.cand_left;
+    const int cand_up_left     = lc->na.cand_up_left;
+    const int cand_up          = lc->na.cand_up;
+    const int cand_up_right    = lc->na.cand_up_right_sap;
+
+    const int xA1    = x0 - 1;
+    const int yA1    = y0 + nPbH - 1;
+    const int xA1_pu = xA1 >> s->sps->log2_min_pu_size;
+    const int yA1_pu = yA1 >> s->sps->log2_min_pu_size;
+
+    const int xB1    = x0 + nPbW - 1;
+    const int yB1    = y0 - 1;
+    const int xB1_pu = xB1 >> s->sps->log2_min_pu_size;
+    const int yB1_pu = yB1 >> s->sps->log2_min_pu_size;
+
+    const int xB0    = x0 + nPbW;
+    const int yB0    = y0 - 1;
+    const int xB0_pu = xB0 >> s->sps->log2_min_pu_size;
+    const int yB0_pu = yB0 >> s->sps->log2_min_pu_size;
+
+    const int xA0    = x0 - 1;
+    const int yA0    = y0 + nPbH;
+    const int xA0_pu = xA0 >> s->sps->log2_min_pu_size;
+    const int yA0_pu = yA0 >> s->sps->log2_min_pu_size;
+
+    const int xB2    = x0 - 1;
+    const int yB2    = y0 - 1;
+    const int xB2_pu = xB2 >> s->sps->log2_min_pu_size;
+    const int yB2_pu = yB2 >> s->sps->log2_min_pu_size;
+
+    const int nb_refs = (s->sh.slice_type == P_SLICE) ?
+                        s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);
+    int check_MER   = 1;
+    int check_MER_1 = 1;
+
+    int zero_idx = 0;
+
+    int nb_merge_cand = 0;
+    int nb_orig_merge_cand = 0;
+
+    int is_available_a0;
+    int is_available_a1;
+    int is_available_b0;
+    int is_available_b1;
+    int is_available_b2;
+    int check_B0;
+    int check_A0;
+
+    //first left spatial merge candidate
+    is_available_a1 = AVAILABLE(cand_left, A1);
+
+    if (!singleMCLFlag && part_idx == 1 &&
+        (lc->cu.part_mode == PART_Nx2N ||
+         lc->cu.part_mode == PART_nLx2N ||
+         lc->cu.part_mode == PART_nRx2N) ||
+        isDiffMER(s, xA1, yA1, x0, y0)) {
+        is_available_a1 = 0;
+    }
+
+    if (is_available_a1)
+        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A1);
+
+    // above spatial merge candidate
+    is_available_b1 = AVAILABLE(cand_up, B1);
+
+    if (!singleMCLFlag && part_idx == 1 &&
+        (lc->cu.part_mode == PART_2NxN ||
+         lc->cu.part_mode == PART_2NxnU ||
+         lc->cu.part_mode == PART_2NxnD) ||
+        isDiffMER(s, xB1, yB1, x0, y0)) {
+        is_available_b1 = 0;
+    }
+
+    if (is_available_a1 && is_available_b1)
+        check_MER = !COMPARE_MV_REFIDX(B1, A1);
+
+    if (is_available_b1 && check_MER)
+        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B1);
+
+    // above right spatial merge candidate
+    check_MER = 1;
+    check_B0  = PRED_BLOCK_AVAILABLE(B0);
+
+    is_available_b0 = check_B0 && AVAILABLE(cand_up_right, B0);
+
+    if (isDiffMER(s, xB0, yB0, x0, y0))
+        is_available_b0 = 0;
+
+    if (is_available_b1 && is_available_b0)
+        check_MER = !COMPARE_MV_REFIDX(B0, B1);
+
+    if (is_available_b0 && check_MER)
+        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B0);
+
+    // left bottom spatial merge candidate
+    check_MER = 1;
+    check_A0  = PRED_BLOCK_AVAILABLE(A0);
+
+    is_available_a0 = check_A0 && AVAILABLE(cand_bottom_left, A0);
+
+    if (isDiffMER(s, xA0, yA0, x0, y0))
+        is_available_a0 = 0;
+
+    if (is_available_a1 && is_available_a0)
+        check_MER = !COMPARE_MV_REFIDX(A0, A1);
+
+    if (is_available_a0 && check_MER)
+        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(A0);
+
+    // above left spatial merge candidate
+    check_MER = 1;
+
+    is_available_b2 = AVAILABLE(cand_up_left, B2);
+
+    if (isDiffMER(s, xB2, yB2, x0, y0))
+        is_available_b2 = 0;
+
+    if (is_available_a1 && is_available_b2)
+        check_MER = !COMPARE_MV_REFIDX(B2, A1);
+
+    if (is_available_b1 && is_available_b2)
+        check_MER_1 = !COMPARE_MV_REFIDX(B2, B1);
+
+    if (is_available_b2 && check_MER && check_MER_1 && nb_merge_cand != 4)
+        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B2);
+
+    // temporal motion vector candidate
+    if (s->sh.slice_temporal_mvp_enabled_flag &&
+        nb_merge_cand < s->sh.max_num_merge_cand) {
+        Mv mv_l0_col, mv_l1_col;
+        int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
+                                                       0, &mv_l0_col, 0);
+        int available_l1 = (s->sh.slice_type == B_SLICE) ?
+                           temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,
+                                                       0, &mv_l1_col, 1) : 0;
+
+        if (available_l0 || available_l1) {
+            mergecandlist[nb_merge_cand].is_intra     = 0;
+            mergecandlist[nb_merge_cand].pred_flag[0] = available_l0;
+            mergecandlist[nb_merge_cand].pred_flag[1] = available_l1;
+            if (available_l0) {
+                mergecandlist[nb_merge_cand].mv[0]      = mv_l0_col;
+                mergecandlist[nb_merge_cand].ref_idx[0] = 0;
+            }
+            if (available_l1) {
+                mergecandlist[nb_merge_cand].mv[1]      = mv_l1_col;
+                mergecandlist[nb_merge_cand].ref_idx[1] = 0;
+            }
+            nb_merge_cand++;
+        }
+    }
+
+    nb_orig_merge_cand = nb_merge_cand;
+
+    // combined bi-predictive merge candidates  (applies for B slices)
+    if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&
+        nb_orig_merge_cand < s->sh.max_num_merge_cand) {
+        int comb_idx;
+
+        for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&
+                           comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {
+            int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];
+            int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];
+            MvField l0_cand = mergecandlist[l0_cand_idx];
+            MvField l1_cand = mergecandlist[l1_cand_idx];
+
+            if (l0_cand.pred_flag[0] && l1_cand.pred_flag[1] &&
+                (refPicList[0].list[l0_cand.ref_idx[0]] !=
+                 refPicList[1].list[l1_cand.ref_idx[1]] ||
+                 l0_cand.mv[0].x != l1_cand.mv[1].x ||
+                 l0_cand.mv[0].y != l1_cand.mv[1].y)) {
+                mergecandlist[nb_merge_cand].ref_idx[0]   = l0_cand.ref_idx[0];
+                mergecandlist[nb_merge_cand].ref_idx[1]   = l1_cand.ref_idx[1];
+                mergecandlist[nb_merge_cand].pred_flag[0] = 1;
+                mergecandlist[nb_merge_cand].pred_flag[1] = 1;
+                mergecandlist[nb_merge_cand].mv[0].x      = l0_cand.mv[0].x;
+                mergecandlist[nb_merge_cand].mv[0].y      = l0_cand.mv[0].y;
+                mergecandlist[nb_merge_cand].mv[1].x      = l1_cand.mv[1].x;
+                mergecandlist[nb_merge_cand].mv[1].y      = l1_cand.mv[1].y;
+                mergecandlist[nb_merge_cand].is_intra     = 0;
+                nb_merge_cand++;
+            }
+        }
+    }
+
+    // append Zero motion vector candidates
+    while (nb_merge_cand < s->sh.max_num_merge_cand) {
+        mergecandlist[nb_merge_cand].pred_flag[0] = 1;
+        mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE;
+        mergecandlist[nb_merge_cand].mv[0].x      = 0;
+        mergecandlist[nb_merge_cand].mv[0].y      = 0;
+        mergecandlist[nb_merge_cand].mv[1].x      = 0;
+        mergecandlist[nb_merge_cand].mv[1].y      = 0;
+        mergecandlist[nb_merge_cand].is_intra     = 0;
+        mergecandlist[nb_merge_cand].ref_idx[0]   = zero_idx < nb_refs ? zero_idx : 0;
+        mergecandlist[nb_merge_cand].ref_idx[1]   = zero_idx < nb_refs ? zero_idx : 0;
+
+        nb_merge_cand++;
+        zero_idx++;
+    }
+}
+
+/*
+ * 8.5.3.1.1 Derivation process of luma Mvs for merge mode
+ */
+void ff_hevc_luma_mv_merge_mode(HEVCContext *s, int x0, int y0, int nPbW,
+                                int nPbH, int log2_cb_size, int part_idx,
+                                int merge_idx, MvField *mv)
+{
+    int singleMCLFlag = 0;
+    int nCS = 1 << log2_cb_size;
+    struct MvField mergecand_list[MRG_MAX_NUM_CANDS] = { { { { 0 } } } };
+    int nPbW2 = nPbW;
+    int nPbH2 = nPbH;
+    HEVCLocalContext *lc = &s->HEVClc;
+
+    if (s->pps->log2_parallel_merge_level > 2 && nCS == 8) {
+        singleMCLFlag = 1;
+        x0            = lc->cu.x;
+        y0            = lc->cu.y;
+        nPbW          = nCS;
+        nPbH          = nCS;
+        part_idx      = 0;
+    }
+
+    ff_hevc_set_neighbour_available(s, x0, y0, nPbW, nPbH);
+    derive_spatial_merge_candidates(s, x0, y0, nPbW, nPbH, log2_cb_size,
+                                    singleMCLFlag, part_idx, mergecand_list);
+
+    if (mergecand_list[merge_idx].pred_flag[0] == 1 &&
+        mergecand_list[merge_idx].pred_flag[1] == 1 &&
+        (nPbW2 + nPbH2) == 12) {
+        mergecand_list[merge_idx].ref_idx[1]   = -1;
+        mergecand_list[merge_idx].pred_flag[1] = 0;
+    }
+
+    *mv = mergecand_list[merge_idx];
+}
+
+static av_always_inline void dist_scale(HEVCContext *s, Mv *mv,
+                                        int min_pu_width, int x, int y,
+                                        int elist, int ref_idx_curr, int ref_idx)
+{
+    RefPicList *refPicList = s->ref->refPicList;
+    MvField *tab_mvf       = s->ref->tab_mvf;
+    int ref_pic_elist      = refPicList[elist].list[TAB_MVF(x, y).ref_idx[elist]];
+    int ref_pic_curr       = refPicList[ref_idx_curr].list[ref_idx];
+
+    if (ref_pic_elist != ref_pic_curr)
+        mv_scale(mv, mv, s->poc - ref_pic_elist, s->poc - ref_pic_curr);
+}
+
+static int mv_mp_mode_mx(HEVCContext *s, int x, int y, int pred_flag_index,
+                         Mv *mv, int ref_idx_curr, int ref_idx)
+{
+    MvField *tab_mvf = s->ref->tab_mvf;
+    int min_pu_width = s->sps->min_pu_width;
+
+    RefPicList *refPicList = s->ref->refPicList;
+
+    if (TAB_MVF(x, y).pred_flag[pred_flag_index] == 1 &&
+        refPicList[pred_flag_index].list[TAB_MVF(x, y).ref_idx[pred_flag_index]] == refPicList[ref_idx_curr].list[ref_idx]) {
+        *mv = TAB_MVF(x, y).mv[pred_flag_index];
+        return 1;
+    }
+    return 0;
+}
+
+static int mv_mp_mode_mx_lt(HEVCContext *s, int x, int y, int pred_flag_index,
+                            Mv *mv, int ref_idx_curr, int ref_idx)
+{
+    MvField *tab_mvf = s->ref->tab_mvf;
+    int min_pu_width = s->sps->min_pu_width;
+
+    RefPicList *refPicList = s->ref->refPicList;
+    int currIsLongTerm     = refPicList[ref_idx_curr].isLongTerm[ref_idx];
+
+    int colIsLongTerm =
+        refPicList[pred_flag_index].isLongTerm[(TAB_MVF(x, y).ref_idx[pred_flag_index])];
+
+    if (TAB_MVF(x, y).pred_flag[pred_flag_index] &&
+        colIsLongTerm == currIsLongTerm) {
+        *mv = TAB_MVF(x, y).mv[pred_flag_index];
+        if (!currIsLongTerm)
+            dist_scale(s, mv, min_pu_width, x, y,
+                       pred_flag_index, ref_idx_curr, ref_idx);
+        return 1;
+    }
+    return 0;
+}
+
+#define MP_MX(v, pred, mx)                                      \
+    mv_mp_mode_mx(s, x ## v ## _pu, y ## v ## _pu, pred,        \
+                  &mx, ref_idx_curr, ref_idx)
+
+#define MP_MX_LT(v, pred, mx)                                   \
+    mv_mp_mode_mx_lt(s, x ## v ## _pu, y ## v ## _pu, pred,     \
+                     &mx, ref_idx_curr, ref_idx)
+
+void ff_hevc_luma_mv_mvp_mode(HEVCContext *s, int x0, int y0, int nPbW,
+                              int nPbH, int log2_cb_size, int part_idx,
+                              int merge_idx, MvField *mv,
+                              int mvp_lx_flag, int LX)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    MvField *tab_mvf = s->ref->tab_mvf;
+    int isScaledFlag_L0 = 0;
+    int availableFlagLXA0 = 0;
+    int availableFlagLXB0 = 0;
+    int numMVPCandLX = 0;
+    int min_pu_width = s->sps->min_pu_width;
+
+    int xA0, yA0;
+    int xA0_pu, yA0_pu;
+    int is_available_a0;
+
+    int xA1, yA1;
+    int xA1_pu, yA1_pu;
+    int is_available_a1;
+
+    int xB0, yB0;
+    int xB0_pu, yB0_pu;
+    int is_available_b0;
+
+    int xB1, yB1;
+    int xB1_pu = 0, yB1_pu = 0;
+    int is_available_b1 = 0;
+
+    int xB2, yB2;
+    int xB2_pu = 0, yB2_pu = 0;
+    int is_available_b2 = 0;
+    Mv mvpcand_list[2] = { { 0 } };
+    Mv mxA = { 0 };
+    Mv mxB = { 0 };
+    int ref_idx_curr = 0;
+    int ref_idx = 0;
+    int pred_flag_index_l0;
+    int pred_flag_index_l1;
+    int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+    int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+    int cand_up = (lc->ctb_up_flag || y0b);
+    int cand_left = (lc->ctb_left_flag || x0b);
+    int cand_up_left =
+            (!x0b && !y0b) ? lc->ctb_up_left_flag : cand_left && cand_up;
+    int cand_up_right =
+            (x0b + nPbW == (1 << s->sps->log2_ctb_size) ||
+             x0  + nPbW >= lc->end_of_tiles_x) ? lc->ctb_up_right_flag && !y0b
+                                               : cand_up;
+    int cand_bottom_left = (y0 + nPbH >= lc->end_of_tiles_y) ? 0 : cand_left;
+
+    ref_idx_curr       = LX;
+    ref_idx            = mv->ref_idx[LX];
+    pred_flag_index_l0 = LX;
+    pred_flag_index_l1 = !LX;
+
+    // left bottom spatial candidate
+    xA0 = x0 - 1;
+    yA0 = y0 + nPbH;
+    xA0_pu = xA0 >> s->sps->log2_min_pu_size;
+    yA0_pu = yA0 >> s->sps->log2_min_pu_size;
+
+    is_available_a0 = PRED_BLOCK_AVAILABLE(A0) && AVAILABLE(cand_bottom_left, A0);
+
+    //left spatial merge candidate
+    xA1    = x0 - 1;
+    yA1    = y0 + nPbH - 1;
+    xA1_pu = xA1 >> s->sps->log2_min_pu_size;
+    yA1_pu = yA1 >> s->sps->log2_min_pu_size;
+
+    is_available_a1 = AVAILABLE(cand_left, A1);
+    if (is_available_a0 || is_available_a1)
+        isScaledFlag_L0 = 1;
+
+    if (is_available_a0) {
+        availableFlagLXA0 = MP_MX(A0, pred_flag_index_l0, mxA);
+        if (!availableFlagLXA0)
+            availableFlagLXA0 = MP_MX(A0, pred_flag_index_l1, mxA);
+    }
+
+    if (is_available_a1 && !availableFlagLXA0) {
+        availableFlagLXA0 = MP_MX(A1, pred_flag_index_l0, mxA);
+        if (!availableFlagLXA0)
+            availableFlagLXA0 = MP_MX(A1, pred_flag_index_l1, mxA);
+    }
+
+    if (is_available_a0 && !availableFlagLXA0) {
+        availableFlagLXA0 = MP_MX_LT(A0, pred_flag_index_l0, mxA);
+        if (!availableFlagLXA0)
+            availableFlagLXA0 = MP_MX_LT(A0, pred_flag_index_l1, mxA);
+    }
+
+    if (is_available_a1 && !availableFlagLXA0) {
+        availableFlagLXA0 = MP_MX_LT(A1, pred_flag_index_l0, mxA);
+        if (!availableFlagLXA0)
+            availableFlagLXA0 = MP_MX_LT(A1, pred_flag_index_l1, mxA);
+    }
+
+    // B candidates
+    // above right spatial merge candidate
+    xB0    = x0 + nPbW;
+    yB0    = y0 - 1;
+    xB0_pu = xB0 >> s->sps->log2_min_pu_size;
+    yB0_pu = yB0 >> s->sps->log2_min_pu_size;
+
+    is_available_b0 = PRED_BLOCK_AVAILABLE(B0) && AVAILABLE(cand_up_right, B0);
+
+    if (is_available_b0) {
+        availableFlagLXB0 = MP_MX(B0, pred_flag_index_l0, mxB);
+        if (!availableFlagLXB0)
+            availableFlagLXB0 = MP_MX(B0, pred_flag_index_l1, mxB);
+    }
+
+    if (!availableFlagLXB0) {
+        // above spatial merge candidate
+        xB1    = x0 + nPbW - 1;
+        yB1    = y0 - 1;
+        xB1_pu = xB1 >> s->sps->log2_min_pu_size;
+        yB1_pu = yB1 >> s->sps->log2_min_pu_size;
+
+        is_available_b1 = AVAILABLE(cand_up, B1);
+
+        if (is_available_b1) {
+            availableFlagLXB0 = MP_MX(B1, pred_flag_index_l0, mxB);
+            if (!availableFlagLXB0)
+                availableFlagLXB0 = MP_MX(B1, pred_flag_index_l1, mxB);
+        }
+    }
+
+    if (!availableFlagLXB0) {
+        // above left spatial merge candidate
+        xB2 = x0 - 1;
+        yB2 = y0 - 1;
+        xB2_pu = xB2 >> s->sps->log2_min_pu_size;
+        yB2_pu = yB2 >> s->sps->log2_min_pu_size;
+        is_available_b2 = AVAILABLE(cand_up_left, B2);
+
+        if (is_available_b2) {
+            availableFlagLXB0 = MP_MX(B2, pred_flag_index_l0, mxB);
+            if (!availableFlagLXB0)
+                availableFlagLXB0 = MP_MX(B2, pred_flag_index_l1, mxB);
+        }
+    }
+
+    if (isScaledFlag_L0 == 0) {
+        if (availableFlagLXB0) {
+            availableFlagLXA0 = 1;
+            mxA = mxB;
+        }
+        availableFlagLXB0 = 0;
+
+        // XB0 and L1
+        if (is_available_b0) {
+            availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l0, mxB);
+            if (!availableFlagLXB0)
+                availableFlagLXB0 = MP_MX_LT(B0, pred_flag_index_l1, mxB);
+        }
+
+        if (is_available_b1 && !availableFlagLXB0) {
+            availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l0, mxB);
+            if (!availableFlagLXB0)
+                availableFlagLXB0 = MP_MX_LT(B1, pred_flag_index_l1, mxB);
+        }
+
+        if (is_available_b2 && !availableFlagLXB0) {
+            availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l0, mxB);
+            if (!availableFlagLXB0)
+                availableFlagLXB0 = MP_MX_LT(B2, pred_flag_index_l1, mxB);
+        }
+    }
+
+    if (availableFlagLXA0)
+        mvpcand_list[numMVPCandLX++] = mxA;
+
+    if (availableFlagLXB0 && (!availableFlagLXA0 || mxA.x != mxB.x || mxA.y != mxB.y))
+        mvpcand_list[numMVPCandLX++] = mxB;
+
+    //temporal motion vector prediction candidate
+    if (numMVPCandLX < 2 && s->sh.slice_temporal_mvp_enabled_flag) {
+        Mv mv_col;
+        int available_col = temporal_luma_motion_vector(s, x0, y0, nPbW,
+                                                        nPbH, ref_idx,
+                                                        &mv_col, LX);
+        if (available_col)
+            mvpcand_list[numMVPCandLX++] = mv_col;
+    }
+
+    // insert zero motion vectors when the number of available candidates are less than 2
+    while (numMVPCandLX < 2)
+        mvpcand_list[numMVPCandLX++] = (Mv){ 0, 0 };
+
+    mv->mv[LX].x = mvpcand_list[mvp_lx_flag].x;
+    mv->mv[LX].y = mvpcand_list[mvp_lx_flag].y;
+}
diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
new file mode 100644
index 0000000..ac2c6f5
--- /dev/null
+++ b/libavcodec/hevc_parser.c
@@ -0,0 +1,125 @@
+/*
+ * HEVC Annex B format parser
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * 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/common.h"
+
+#include "parser.h"
+#include "hevc.h"
+
+#define START_CODE 0x000001 ///< start_code_prefix_one_3bytes
+
+/**
+ * Find the end of the current frame in the bitstream.
+ * @return the position of the first byte of the next frame, or END_NOT_FOUND
+ */
+static int hevc_find_frame_end(AVCodecParserContext *s, const uint8_t *buf,
+                               int buf_size)
+{
+    int i;
+    ParseContext *pc = s->priv_data;
+
+    for (i = 0; i < buf_size; i++) {
+        int nut;
+
+        pc->state64 = (pc->state64 << 8) | buf[i];
+
+        if (((pc->state64 >> 3 * 8) & 0xFFFFFF) != START_CODE)
+            continue;
+
+        nut = (pc->state64 >> 2 * 8 + 1) & 0x3F;
+        // Beginning of access unit
+        if ((nut >= NAL_VPS && nut <= NAL_AUD) || nut == NAL_SEI_PREFIX ||
+            (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {
+            if (pc->frame_start_found) {
+                pc->frame_start_found = 0;
+                return i - 5;
+            }
+        } else if (nut <= NAL_RASL_R ||
+                   (nut >= NAL_BLA_W_LP && nut <= NAL_CRA_NUT)) {
+            int first_slice_segment_in_pic_flag = buf[i] >> 7;
+            if (first_slice_segment_in_pic_flag) {
+                if (!pc->frame_start_found) {
+                    pc->frame_start_found = 1;
+                    s->key_frame = nut >= NAL_BLA_W_LP && nut <= NAL_CRA_NUT;
+                } else { // First slice of next frame found
+                    pc->frame_start_found = 0;
+                    return i - 5;
+                }
+            }
+        }
+    }
+
+    return END_NOT_FOUND;
+}
+
+static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+                      const uint8_t **poutbuf, int *poutbuf_size,
+                      const uint8_t *buf, int buf_size)
+{
+    int next;
+    ParseContext *pc = s->priv_data;
+
+    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+        next = buf_size;
+    } else {
+        next = hevc_find_frame_end(s, 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;
+    return next;
+}
+
+// Split after the parameter sets at the beginning of the stream if they exist.
+static int hevc_split(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
+{
+    int i;
+    uint32_t state = -1;
+    int has_ps = 0;
+
+    for (i = 0; i < buf_size; i++) {
+        state = (state << 8) | buf[i];
+        if (((state >> 8) & 0xFFFFFF) == START_CODE) {
+            int nut = (state >> 1) & 0x3F;
+            if (nut >= NAL_VPS && nut <= NAL_PPS)
+                has_ps = 1;
+            else if (has_ps)
+                return i - 3;
+            else // no parameter set at the beginning of the stream
+                return 0;
+        }
+    }
+    return 0;
+}
+
+AVCodecParser ff_hevc_parser = {
+    .codec_ids      = { AV_CODEC_ID_HEVC },
+    .priv_data_size = sizeof(ParseContext),
+    .parser_parse   = hevc_parse,
+    .parser_close   = ff_parse_close,
+    .split          = hevc_split,
+};
diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
new file mode 100644
index 0000000..d981125
--- /dev/null
+++ b/libavcodec/hevc_ps.c
@@ -0,0 +1,1340 @@
+/*
+ * HEVC Parameter Set decoding
+ *
+ * Copyright (C) 2012 - 2103 Guillaume Martres
+ * Copyright (C) 2012 - 2103 Mickael Raulet
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2013 Vittorio Giovara
+ *
+ * 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/imgutils.h"
+
+#include "golomb.h"
+#include "hevc.h"
+
+static const uint8_t default_scaling_list_intra[] = {
+    16, 16, 16, 16, 17, 18, 21, 24,
+    16, 16, 16, 16, 17, 19, 22, 25,
+    16, 16, 17, 18, 20, 22, 25, 29,
+    16, 16, 18, 21, 24, 27, 31, 36,
+    17, 17, 20, 24, 30, 35, 41, 47,
+    18, 19, 22, 27, 35, 44, 54, 65,
+    21, 22, 25, 31, 41, 54, 70, 88,
+    24, 25, 29, 36, 47, 65, 88, 115
+};
+
+static const uint8_t default_scaling_list_inter[] = {
+    16, 16, 16, 16, 17, 18, 20, 24,
+    16, 16, 16, 17, 18, 20, 24, 25,
+    16, 16, 17, 18, 20, 24, 25, 28,
+    16, 17, 18, 20, 24, 25, 28, 33,
+    17, 18, 20, 24, 25, 28, 33, 41,
+    18, 20, 24, 25, 28, 33, 41, 54,
+    20, 24, 25, 28, 33, 41, 54, 71,
+    24, 25, 28, 33, 41, 54, 71, 91
+};
+
+static const AVRational vui_sar[] = {
+    {  0,   1 },
+    {  1,   1 },
+    { 12,  11 },
+    { 10,  11 },
+    { 16,  11 },
+    { 40,  33 },
+    { 24,  11 },
+    { 20,  11 },
+    { 32,  11 },
+    { 80,  33 },
+    { 18,  11 },
+    { 15,  11 },
+    { 64,  33 },
+    { 160, 99 },
+    {  4,   3 },
+    {  3,   2 },
+    {  2,   1 },
+};
+
+int ff_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
+                                  const HEVCSPS *sps, int is_slice_header)
+{
+    HEVCLocalContext *lc = &s->HEVClc;
+    uint8_t rps_predict = 0;
+    int delta_poc;
+    int k0 = 0;
+    int k1 = 0;
+    int k  = 0;
+    int i;
+
+    GetBitContext *gb = &lc->gb;
+
+    if (rps != sps->st_rps && sps->nb_st_rps)
+        rps_predict = get_bits1(gb);
+
+    if (rps_predict) {
+        const ShortTermRPS *rps_ridx;
+        int delta_rps, abs_delta_rps;
+        uint8_t use_delta_flag = 0;
+        uint8_t delta_rps_sign;
+
+        if (is_slice_header) {
+            int delta_idx = get_ue_golomb_long(gb) + 1;
+            if (delta_idx > sps->nb_st_rps) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "Invalid value of delta_idx in slice header RPS: %d > %d.\n",
+                       delta_idx, sps->nb_st_rps);
+                return AVERROR_INVALIDDATA;
+            }
+            rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];
+        } else
+            rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];
+
+        delta_rps_sign = get_bits1(gb);
+        abs_delta_rps  = get_ue_golomb_long(gb) + 1;
+        delta_rps      = (1 - (delta_rps_sign << 1)) * abs_delta_rps;
+        for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {
+            int used = rps->used[k] = get_bits1(gb);
+
+            if (!used)
+                use_delta_flag = get_bits1(gb);
+
+            if (used || use_delta_flag) {
+                if (i < rps_ridx->num_delta_pocs)
+                    delta_poc = delta_rps + rps_ridx->delta_poc[i];
+                else
+                    delta_poc = delta_rps;
+                rps->delta_poc[k] = delta_poc;
+                if (delta_poc < 0)
+                    k0++;
+                else
+                    k1++;
+                k++;
+            }
+        }
+
+        rps->num_delta_pocs    = k;
+        rps->num_negative_pics = k0;
+        // sort in increasing order (smallest first)
+        if (rps->num_delta_pocs != 0) {
+            int used, tmp;
+            for (i = 1; i < rps->num_delta_pocs; i++) {
+                delta_poc = rps->delta_poc[i];
+                used      = rps->used[i];
+                for (k = i - 1; k >= 0; k--) {
+                    tmp = rps->delta_poc[k];
+                    if (delta_poc < tmp) {
+                        rps->delta_poc[k + 1] = tmp;
+                        rps->used[k + 1]      = rps->used[k];
+                        rps->delta_poc[k]     = delta_poc;
+                        rps->used[k]          = used;
+                    }
+                }
+            }
+        }
+        if ((rps->num_negative_pics >> 1) != 0) {
+            int used;
+            k = rps->num_negative_pics - 1;
+            // flip the negative values to largest first
+            for (i = 0; i < rps->num_negative_pics >> 1; i++) {
+                delta_poc         = rps->delta_poc[i];
+                used              = rps->used[i];
+                rps->delta_poc[i] = rps->delta_poc[k];
+                rps->used[i]      = rps->used[k];
+                rps->delta_poc[k] = delta_poc;
+                rps->used[k]      = used;
+                k--;
+            }
+        }
+    } else {
+        unsigned int prev, nb_positive_pics;
+        rps->num_negative_pics = get_ue_golomb_long(gb);
+        nb_positive_pics       = get_ue_golomb_long(gb);
+
+        if (rps->num_negative_pics >= MAX_REFS ||
+            nb_positive_pics >= MAX_REFS) {
+            av_log(s->avctx, AV_LOG_ERROR, "Too many refs in a short term RPS.\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        rps->num_delta_pocs = rps->num_negative_pics + nb_positive_pics;
+        if (rps->num_delta_pocs) {
+            prev = 0;
+            for (i = 0; i < rps->num_negative_pics; i++) {
+                delta_poc = get_ue_golomb_long(gb) + 1;
+                prev -= delta_poc;
+                rps->delta_poc[i] = prev;
+                rps->used[i]      = get_bits1(gb);
+            }
+            prev = 0;
+            for (i = 0; i < nb_positive_pics; i++) {
+                delta_poc = get_ue_golomb_long(gb) + 1;
+                prev += delta_poc;
+                rps->delta_poc[rps->num_negative_pics + i] = prev;
+                rps->used[rps->num_negative_pics + i]      = get_bits1(gb);
+            }
+        }
+    }
+    return 0;
+}
+
+static int decode_profile_tier_level(HEVCLocalContext *lc, PTL *ptl,
+                                     int max_num_sub_layers)
+{
+    int i, j;
+    GetBitContext *gb = &lc->gb;
+
+    ptl->general_profile_space = get_bits(gb, 2);
+    ptl->general_tier_flag     = get_bits1(gb);
+    ptl->general_profile_idc   = get_bits(gb, 5);
+    for (i = 0; i < 32; i++)
+        ptl->general_profile_compatibility_flag[i] = get_bits1(gb);
+    skip_bits1(gb); // general_progressive_source_flag
+    skip_bits1(gb); // general_interlaced_source_flag
+    skip_bits1(gb); // general_non_packed_constraint_flag
+    skip_bits1(gb); // general_frame_only_constraint_flag
+    if (get_bits(gb, 16) != 0) // XXX_reserved_zero_44bits[0..15]
+        return -1;
+    if (get_bits(gb, 16) != 0) // XXX_reserved_zero_44bits[16..31]
+        return -1;
+    if (get_bits(gb, 12) != 0) // XXX_reserved_zero_44bits[32..43]
+        return -1;
+
+    ptl->general_level_idc = get_bits(gb, 8);
+    for (i = 0; i < max_num_sub_layers - 1; i++) {
+        ptl->sub_layer_profile_present_flag[i] = get_bits1(gb);
+        ptl->sub_layer_level_present_flag[i]   = get_bits1(gb);
+    }
+    if (max_num_sub_layers - 1 > 0)
+        for (i = max_num_sub_layers - 1; i < 8; i++)
+            skip_bits(gb, 2);  // reserved_zero_2bits[i]
+    for (i = 0; i < max_num_sub_layers - 1; i++) {
+        if (ptl->sub_layer_profile_present_flag[i]) {
+            ptl->sub_layer_profile_space[i] = get_bits(gb, 2);
+            ptl->sub_layer_tier_flag[i]     = get_bits(gb, 1);
+            ptl->sub_layer_profile_idc[i]   = get_bits(gb, 5);
+            for (j = 0; j < 32; j++)
+                ptl->sub_layer_profile_compatibility_flags[i][j] = get_bits1(gb);
+            skip_bits1(gb); // sub_layer_progressive_source_flag
+            skip_bits1(gb); // sub_layer_interlaced_source_flag
+            skip_bits1(gb); // sub_layer_non_packed_constraint_flag
+            skip_bits1(gb); // sub_layer_frame_only_constraint_flag
+
+            if (get_bits(gb, 16) != 0) // sub_layer_reserved_zero_44bits[0..15]
+                return -1;
+            if (get_bits(gb, 16) != 0) // sub_layer_reserved_zero_44bits[16..31]
+                return -1;
+            if (get_bits(gb, 12) != 0) // sub_layer_reserved_zero_44bits[32..43]
+                return -1;
+        }
+        if (ptl->sub_layer_level_present_flag[i])
+            ptl->sub_layer_level_idc[i] = get_bits(gb, 8);
+    }
+    return 0;
+}
+
+static void decode_sublayer_hrd(HEVCContext *s, int nb_cpb,
+                                int subpic_params_present)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+    int i;
+
+    for (i = 0; i < nb_cpb; i++) {
+        get_ue_golomb_long(gb); // bit_rate_value_minus1
+        get_ue_golomb_long(gb); // cpb_size_value_minus1
+
+        if (subpic_params_present) {
+            get_ue_golomb_long(gb); // cpb_size_du_value_minus1
+            get_ue_golomb_long(gb); // bit_rate_du_value_minus1
+        }
+        skip_bits1(gb); // cbr_flag
+    }
+}
+
+static void decode_hrd(HEVCContext *s, int common_inf_present,
+                       int max_sublayers)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+    int nal_params_present = 0, vcl_params_present = 0;
+    int subpic_params_present = 0;
+    int i;
+
+    if (common_inf_present) {
+        nal_params_present = get_bits1(gb);
+        vcl_params_present = get_bits1(gb);
+
+        if (nal_params_present || vcl_params_present) {
+            subpic_params_present = get_bits1(gb);
+
+            if (subpic_params_present) {
+                skip_bits(gb, 8); // tick_divisor_minus2
+                skip_bits(gb, 5); // du_cpb_removal_delay_increment_length_minus1
+                skip_bits(gb, 1); // sub_pic_cpb_params_in_pic_timing_sei_flag
+                skip_bits(gb, 5); // dpb_output_delay_du_length_minus1
+            }
+
+            skip_bits(gb, 4); // bit_rate_scale
+            skip_bits(gb, 4); // cpb_size_scale
+
+            if (subpic_params_present)
+                skip_bits(gb, 4);  // cpb_size_du_scale
+
+            skip_bits(gb, 5); // initial_cpb_removal_delay_length_minus1
+            skip_bits(gb, 5); // au_cpb_removal_delay_length_minus1
+            skip_bits(gb, 5); // dpb_output_delay_length_minus1
+        }
+    }
+
+    for (i = 0; i < max_sublayers; i++) {
+        int low_delay = 0;
+        int nb_cpb = 1;
+        int fixed_rate = get_bits1(gb);
+
+        if (!fixed_rate)
+            fixed_rate = get_bits1(gb);
+
+        if (fixed_rate)
+            get_ue_golomb_long(gb);  // elemental_duration_in_tc_minus1
+        else
+            low_delay = get_bits1(gb);
+
+        if (!low_delay)
+            nb_cpb = get_ue_golomb_long(gb) + 1;
+
+        if (nal_params_present)
+            decode_sublayer_hrd(s, nb_cpb, subpic_params_present);
+        if (vcl_params_present)
+            decode_sublayer_hrd(s, nb_cpb, subpic_params_present);
+    }
+}
+
+int ff_hevc_decode_nal_vps(HEVCContext *s)
+{
+    int i,j;
+    GetBitContext *gb = &s->HEVClc.gb;
+    int vps_id = 0;
+    HEVCVPS *vps;
+    AVBufferRef *vps_buf = av_buffer_allocz(sizeof(*vps));
+
+    if (!vps_buf)
+      return AVERROR(ENOMEM);
+    vps = (HEVCVPS*)vps_buf->data;
+
+    av_log(s->avctx, AV_LOG_DEBUG, "Decoding VPS\n");
+
+    vps_id = get_bits(gb, 4);
+    if (vps_id >= MAX_VPS_COUNT) {
+        av_log(s->avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", vps_id);
+        goto err;
+    }
+
+    if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits
+        av_log(s->avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n");
+        goto err;
+    }
+
+    vps->vps_max_layers               = get_bits(gb, 6) + 1;
+    vps->vps_max_sub_layers           = get_bits(gb, 3) + 1;
+    vps->vps_temporal_id_nesting_flag = get_bits1(gb);
+
+    if (get_bits(gb, 16) != 0xffff) { // vps_reserved_ffff_16bits
+        av_log(s->avctx, AV_LOG_ERROR, "vps_reserved_ffff_16bits is not 0xffff\n");
+        goto err;
+    }
+
+    if (vps->vps_max_sub_layers > MAX_SUB_LAYERS) {
+        av_log(s->avctx, AV_LOG_ERROR, "vps_max_sub_layers out of range: %d\n",
+               vps->vps_max_sub_layers);
+        goto err;
+    }
+
+    if (decode_profile_tier_level(&s->HEVClc, &vps->ptl, vps->vps_max_sub_layers) < 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "Error decoding profile tier level.\n");
+        goto err;
+    }
+    vps->vps_sub_layer_ordering_info_present_flag = get_bits1(gb);
+
+    i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers - 1;
+    for (; i < vps->vps_max_sub_layers; i++) {
+        vps->vps_max_dec_pic_buffering[i] = get_ue_golomb_long(gb) + 1;
+        vps->vps_num_reorder_pics[i]      = get_ue_golomb_long(gb);
+        vps->vps_max_latency_increase[i]  = get_ue_golomb_long(gb) - 1;
+
+        if (vps->vps_max_dec_pic_buffering[i] > MAX_DPB_SIZE) {
+            av_log(s->avctx, AV_LOG_ERROR, "vps_max_dec_pic_buffering_minus1 out of range: %d\n",
+                   vps->vps_max_dec_pic_buffering[i] - 1);
+            goto err;
+        }
+        if (vps->vps_num_reorder_pics[i] > vps->vps_max_dec_pic_buffering[i] - 1) {
+            av_log(s->avctx, AV_LOG_ERROR, "vps_max_num_reorder_pics out of range: %d\n",
+                   vps->vps_num_reorder_pics[i]);
+            goto err;
+        }
+    }
+
+    vps->vps_max_layer_id   = get_bits(gb, 6);
+    vps->vps_num_layer_sets = get_ue_golomb_long(gb) + 1;
+    for (i = 1; i < vps->vps_num_layer_sets; i++)
+        for (j = 0; j <= vps->vps_max_layer_id; j++)
+            skip_bits(gb, 1);  // layer_id_included_flag[i][j]
+
+    vps->vps_timing_info_present_flag = get_bits1(gb);
+    if (vps->vps_timing_info_present_flag) {
+        vps->vps_num_units_in_tick               = get_bits_long(gb, 32);
+        vps->vps_time_scale                      = get_bits_long(gb, 32);
+        vps->vps_poc_proportional_to_timing_flag = get_bits1(gb);
+        if (vps->vps_poc_proportional_to_timing_flag)
+            vps->vps_num_ticks_poc_diff_one = get_ue_golomb_long(gb) + 1;
+        vps->vps_num_hrd_parameters = get_ue_golomb_long(gb);
+        for (i = 0; i < vps->vps_num_hrd_parameters; i++) {
+            int common_inf_present = 1;
+
+            get_ue_golomb_long(gb); // hrd_layer_set_idx
+            if (i)
+                common_inf_present = get_bits1(gb);
+            decode_hrd(s, common_inf_present, vps->vps_max_sub_layers);
+        }
+    }
+    get_bits1(gb); /* vps_extension_flag */
+
+    av_buffer_unref(&s->vps_list[vps_id]);
+    s->vps_list[vps_id] = vps_buf;
+    return 0;
+
+err:
+    av_buffer_unref(&vps_buf);
+    return AVERROR_INVALIDDATA;
+}
+
+static void decode_vui(HEVCContext *s, HEVCSPS *sps)
+{
+    VUI *vui          = &sps->vui;
+    GetBitContext *gb = &s->HEVClc.gb;
+    int sar_present;
+
+    av_log(s->avctx, AV_LOG_DEBUG, "Decoding VUI\n");
+
+    sar_present = get_bits1(gb);
+    if (sar_present) {
+        uint8_t sar_idx = get_bits(gb, 8);
+        if (sar_idx < FF_ARRAY_ELEMS(vui_sar))
+            vui->sar = vui_sar[sar_idx];
+        else if (sar_idx == 255) {
+            vui->sar.num = get_bits(gb, 16);
+            vui->sar.den = get_bits(gb, 16);
+        } else
+            av_log(s->avctx, AV_LOG_WARNING,
+                   "Unknown SAR index: %u.\n", sar_idx);
+    }
+
+    vui->overscan_info_present_flag = get_bits1(gb);
+    if (vui->overscan_info_present_flag)
+        vui->overscan_appropriate_flag = get_bits1(gb);
+
+    vui->video_signal_type_present_flag = get_bits1(gb);
+    if (vui->video_signal_type_present_flag) {
+        vui->video_format                    = get_bits(gb, 3);
+        vui->video_full_range_flag           = get_bits1(gb);
+        vui->colour_description_present_flag = get_bits1(gb);
+        if (vui->video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
+            sps->pix_fmt = AV_PIX_FMT_YUVJ420P;
+        if (vui->colour_description_present_flag) {
+            vui->colour_primaries        = get_bits(gb, 8);
+            vui->transfer_characteristic = get_bits(gb, 8);
+            vui->matrix_coeffs           = get_bits(gb, 8);
+
+            // Set invalid values to "unspecified"
+            if (vui->colour_primaries >= AVCOL_PRI_NB)
+                vui->colour_primaries = AVCOL_PRI_UNSPECIFIED;
+            if (vui->transfer_characteristic >= AVCOL_TRC_NB)
+                vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED;
+            if (vui->matrix_coeffs >= AVCOL_SPC_NB)
+                vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
+        }
+    }
+
+    vui->chroma_loc_info_present_flag = get_bits1(gb);
+    if (vui->chroma_loc_info_present_flag) {
+        vui->chroma_sample_loc_type_top_field    = get_ue_golomb_long(gb);
+        vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_long(gb);
+    }
+
+    vui->neutra_chroma_indication_flag = get_bits1(gb);
+    vui->field_seq_flag                = get_bits1(gb);
+    vui->frame_field_info_present_flag = get_bits1(gb);
+
+    vui->default_display_window_flag = get_bits1(gb);
+    if (vui->default_display_window_flag) {
+        //TODO: * 2 is only valid for 420
+        vui->def_disp_win.left_offset   = get_ue_golomb_long(gb) * 2;
+        vui->def_disp_win.right_offset  = get_ue_golomb_long(gb) * 2;
+        vui->def_disp_win.top_offset    = get_ue_golomb_long(gb) * 2;
+        vui->def_disp_win.bottom_offset = get_ue_golomb_long(gb) * 2;
+
+        if (s->apply_defdispwin &&
+            s->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
+            av_log(s->avctx, AV_LOG_DEBUG,
+                   "discarding vui default display window, "
+                   "original values are l:%u r:%u t:%u b:%u\n",
+                   vui->def_disp_win.left_offset,
+                   vui->def_disp_win.right_offset,
+                   vui->def_disp_win.top_offset,
+                   vui->def_disp_win.bottom_offset);
+
+            vui->def_disp_win.left_offset   =
+            vui->def_disp_win.right_offset  =
+            vui->def_disp_win.top_offset    =
+            vui->def_disp_win.bottom_offset = 0;
+        }
+    }
+
+    vui->vui_timing_info_present_flag = get_bits1(gb);
+    if (vui->vui_timing_info_present_flag) {
+        vui->vui_num_units_in_tick               = get_bits(gb, 32);
+        vui->vui_time_scale                      = get_bits(gb, 32);
+        vui->vui_poc_proportional_to_timing_flag = get_bits1(gb);
+        if (vui->vui_poc_proportional_to_timing_flag)
+            vui->vui_num_ticks_poc_diff_one_minus1 = get_ue_golomb_long(gb);
+        vui->vui_hrd_parameters_present_flag = get_bits1(gb);
+        if (vui->vui_hrd_parameters_present_flag)
+            decode_hrd(s, 1, sps->max_sub_layers);
+    }
+
+    vui->bitstream_restriction_flag = get_bits1(gb);
+    if (vui->bitstream_restriction_flag) {
+        vui->tiles_fixed_structure_flag              = get_bits1(gb);
+        vui->motion_vectors_over_pic_boundaries_flag = get_bits1(gb);
+        vui->restricted_ref_pic_lists_flag           = get_bits1(gb);
+        vui->min_spatial_segmentation_idc            = get_ue_golomb_long(gb);
+        vui->max_bytes_per_pic_denom                 = get_ue_golomb_long(gb);
+        vui->max_bits_per_min_cu_denom               = get_ue_golomb_long(gb);
+        vui->log2_max_mv_length_horizontal           = get_ue_golomb_long(gb);
+        vui->log2_max_mv_length_vertical             = get_ue_golomb_long(gb);
+    }
+}
+
+static void set_default_scaling_list_data(ScalingList *sl)
+{
+    int matrixId;
+
+    for (matrixId = 0; matrixId < 6; matrixId++) {
+        // 4x4 default is 16
+        memset(sl->sl[0][matrixId], 16, 16);
+        sl->sl_dc[0][matrixId] = 16; // default for 16x16
+        sl->sl_dc[1][matrixId] = 16; // default for 32x32
+    }
+    memcpy(sl->sl[1][0], default_scaling_list_intra, 64);
+    memcpy(sl->sl[1][1], default_scaling_list_intra, 64);
+    memcpy(sl->sl[1][2], default_scaling_list_intra, 64);
+    memcpy(sl->sl[1][3], default_scaling_list_inter, 64);
+    memcpy(sl->sl[1][4], default_scaling_list_inter, 64);
+    memcpy(sl->sl[1][5], default_scaling_list_inter, 64);
+    memcpy(sl->sl[2][0], default_scaling_list_intra, 64);
+    memcpy(sl->sl[2][1], default_scaling_list_intra, 64);
+    memcpy(sl->sl[2][2], default_scaling_list_intra, 64);
+    memcpy(sl->sl[2][3], default_scaling_list_inter, 64);
+    memcpy(sl->sl[2][4], default_scaling_list_inter, 64);
+    memcpy(sl->sl[2][5], default_scaling_list_inter, 64);
+    memcpy(sl->sl[3][0], default_scaling_list_intra, 64);
+    memcpy(sl->sl[3][1], default_scaling_list_inter, 64);
+}
+
+static int scaling_list_data(HEVCContext *s, ScalingList *sl)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+    uint8_t scaling_list_pred_mode_flag[4][6];
+    int32_t scaling_list_dc_coef[2][6];
+    int size_id, matrix_id, i, pos, delta;
+
+    for (size_id = 0; size_id < 4; size_id++)
+        for (matrix_id = 0; matrix_id < (size_id == 3 ? 2 : 6); matrix_id++) {
+            scaling_list_pred_mode_flag[size_id][matrix_id] = get_bits1(gb);
+            if (!scaling_list_pred_mode_flag[size_id][matrix_id]) {
+                delta = get_ue_golomb_long(gb);
+                /* Only need to handle non-zero delta. Zero means default,
+                 * which should already be in the arrays. */
+                if (delta) {
+                    // Copy from previous array.
+                    if (matrix_id - delta < 0) {
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "Invalid delta in scaling list data: %d.\n", delta);
+                        return AVERROR_INVALIDDATA;
+                    }
+
+                    memcpy(sl->sl[size_id][matrix_id],
+                           sl->sl[size_id][matrix_id - delta],
+                           size_id > 0 ? 64 : 16);
+                    if (size_id > 1)
+                        sl->sl_dc[size_id - 2][matrix_id] = sl->sl_dc[size_id - 2][matrix_id - delta];
+                }
+            } else {
+                int next_coef, coef_num;
+                int32_t scaling_list_delta_coef;
+
+                next_coef = 8;
+                coef_num  = FFMIN(64, 1 << (4 + (size_id << 1)));
+                if (size_id > 1) {
+                    scaling_list_dc_coef[size_id - 2][matrix_id] = get_se_golomb(gb) + 8;
+                    next_coef = scaling_list_dc_coef[size_id - 2][matrix_id];
+                    sl->sl_dc[size_id - 2][matrix_id] = next_coef;
+                }
+                for (i = 0; i < coef_num; i++) {
+                    if (size_id == 0)
+                        pos = 4 * ff_hevc_diag_scan4x4_y[i] +
+                                  ff_hevc_diag_scan4x4_x[i];
+                    else
+                        pos = 8 * ff_hevc_diag_scan8x8_y[i] +
+                                  ff_hevc_diag_scan8x8_x[i];
+
+                    scaling_list_delta_coef = get_se_golomb(gb);
+                    next_coef = (next_coef + scaling_list_delta_coef + 256) % 256;
+                    sl->sl[size_id][matrix_id][pos] = next_coef;
+                }
+            }
+        }
+
+    return 0;
+}
+
+int ff_hevc_decode_nal_sps(HEVCContext *s)
+{
+    const AVPixFmtDescriptor *desc;
+    GetBitContext *gb = &s->HEVClc.gb;
+    int ret    = 0;
+    int sps_id = 0;
+    int log2_diff_max_min_transform_block_size;
+    int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
+    int i;
+
+    HEVCSPS *sps;
+    AVBufferRef *sps_buf = av_buffer_allocz(sizeof(*sps));
+
+    if (!sps_buf)
+        return AVERROR(ENOMEM);
+    sps = (HEVCSPS*)sps_buf->data;
+
+    av_log(s->avctx, AV_LOG_DEBUG, "Decoding SPS\n");
+
+    // Coded parameters
+
+    sps->vps_id = get_bits(gb, 4);
+    if (sps->vps_id >= MAX_VPS_COUNT) {
+        av_log(s->avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", sps->vps_id);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+
+    sps->max_sub_layers = get_bits(gb, 3) + 1;
+    if (sps->max_sub_layers > MAX_SUB_LAYERS) {
+        av_log(s->avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n",
+               sps->max_sub_layers);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+
+    skip_bits1(gb); // temporal_id_nesting_flag
+    if (decode_profile_tier_level(&s->HEVClc, &sps->ptl,
+                                  sps->max_sub_layers) < 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "error decoding profile tier level\n");
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+    sps_id = get_ue_golomb_long(gb);
+    if (sps_id >= MAX_SPS_COUNT) {
+        av_log(s->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", sps_id);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+
+    sps->chroma_format_idc = get_ue_golomb_long(gb);
+    if (sps->chroma_format_idc != 1) {
+        avpriv_report_missing_feature(s->avctx, "chroma_format_idc != 1\n");
+        ret = AVERROR_PATCHWELCOME;
+        goto err;
+    }
+
+    if (sps->chroma_format_idc == 3)
+        sps->separate_colour_plane_flag = get_bits1(gb);
+
+    sps->width  = get_ue_golomb_long(gb);
+    sps->height = get_ue_golomb_long(gb);
+    if ((ret = av_image_check_size(sps->width,
+                                   sps->height, 0, s->avctx)) < 0)
+        goto err;
+
+    if (get_bits1(gb)) { // pic_conformance_flag
+        //TODO: * 2 is only valid for 420
+        sps->pic_conf_win.left_offset   = get_ue_golomb_long(gb) * 2;
+        sps->pic_conf_win.right_offset  = get_ue_golomb_long(gb) * 2;
+        sps->pic_conf_win.top_offset    = get_ue_golomb_long(gb) * 2;
+        sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * 2;
+
+        if (s->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
+            av_log(s->avctx, AV_LOG_DEBUG,
+                   "discarding sps conformance window, "
+                   "original values are l:%u r:%u t:%u b:%u\n",
+                   sps->pic_conf_win.left_offset,
+                   sps->pic_conf_win.right_offset,
+                   sps->pic_conf_win.top_offset,
+                   sps->pic_conf_win.bottom_offset);
+
+            sps->pic_conf_win.left_offset   =
+            sps->pic_conf_win.right_offset  =
+            sps->pic_conf_win.top_offset    =
+            sps->pic_conf_win.bottom_offset = 0;
+        }
+        sps->output_window = sps->pic_conf_win;
+    }
+
+    sps->bit_depth   = get_ue_golomb_long(gb) + 8;
+    bit_depth_chroma = get_ue_golomb_long(gb) + 8;
+    if (bit_depth_chroma != sps->bit_depth) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Luma bit depth (%d) is different from chroma bit depth (%d), "
+               "this is unsupported.\n",
+               sps->bit_depth, bit_depth_chroma);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+
+    if (sps->chroma_format_idc == 1) {
+        switch (sps->bit_depth) {
+        case 8:  sps->pix_fmt = AV_PIX_FMT_YUV420P;   break;
+        case 9:  sps->pix_fmt = AV_PIX_FMT_YUV420P9;  break;
+        case 10: sps->pix_fmt = AV_PIX_FMT_YUV420P10; break;
+        default:
+            av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",
+                   sps->bit_depth);
+            ret = AVERROR_PATCHWELCOME;
+            goto err;
+        }
+    } else {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "non-4:2:0 support is currently unspecified.\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    desc = av_pix_fmt_desc_get(sps->pix_fmt);
+    if (!desc) {
+        ret = AVERROR(EINVAL);
+        goto err;
+    }
+
+    sps->hshift[0] = sps->vshift[0] = 0;
+    sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w;
+    sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h;
+
+    sps->pixel_shift = sps->bit_depth > 8;
+
+    sps->log2_max_poc_lsb = get_ue_golomb_long(gb) + 4;
+    if (sps->log2_max_poc_lsb > 16) {
+        av_log(s->avctx, AV_LOG_ERROR, "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",
+               sps->log2_max_poc_lsb - 4);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+
+    sublayer_ordering_info = get_bits1(gb);
+    start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;
+    for (i = start; i < sps->max_sub_layers; i++) {
+        sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1;
+        sps->temporal_layer[i].num_reorder_pics      = get_ue_golomb_long(gb);
+        sps->temporal_layer[i].max_latency_increase  = get_ue_golomb_long(gb) - 1;
+        if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) {
+            av_log(s->avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n",
+                   sps->temporal_layer[i].max_dec_pic_buffering - 1);
+            ret = AVERROR_INVALIDDATA;
+            goto err;
+        }
+        if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) {
+            av_log(s->avctx, AV_LOG_ERROR, "sps_max_num_reorder_pics out of range: %d\n",
+                   sps->temporal_layer[i].num_reorder_pics);
+            ret = AVERROR_INVALIDDATA;
+            goto err;
+        }
+    }
+
+    if (!sublayer_ordering_info) {
+        for (i = 0; i < start; i++) {
+            sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering;
+            sps->temporal_layer[i].num_reorder_pics      = sps->temporal_layer[start].num_reorder_pics;
+            sps->temporal_layer[i].max_latency_increase  = sps->temporal_layer[start].max_latency_increase;
+        }
+    }
+
+    sps->log2_min_cb_size                    = get_ue_golomb_long(gb) + 3;
+    sps->log2_diff_max_min_coding_block_size = get_ue_golomb_long(gb);
+    sps->log2_min_tb_size                    = get_ue_golomb_long(gb) + 2;
+    log2_diff_max_min_transform_block_size   = get_ue_golomb_long(gb);
+    sps->log2_max_trafo_size                 = log2_diff_max_min_transform_block_size +
+                                               sps->log2_min_tb_size;
+
+    if (sps->log2_min_tb_size >= sps->log2_min_cb_size) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+    sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb);
+    sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb);
+
+    sps->scaling_list_enable_flag = get_bits1(gb);
+    if (sps->scaling_list_enable_flag) {
+        set_default_scaling_list_data(&sps->scaling_list);
+
+        if (get_bits1(gb)) {
+            ret = scaling_list_data(s, &sps->scaling_list);
+            if (ret < 0)
+                goto err;
+        }
+    }
+
+    sps->amp_enabled_flag = get_bits1(gb);
+    sps->sao_enabled      = get_bits1(gb);
+
+    sps->pcm_enabled_flag = get_bits1(gb);
+    if (sps->pcm_enabled_flag) {
+        int pcm_bit_depth_chroma;
+        sps->pcm.bit_depth   = get_bits(gb, 4) + 1;
+        pcm_bit_depth_chroma = get_bits(gb, 4) + 1;
+        if (pcm_bit_depth_chroma != sps->pcm.bit_depth) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "PCM Luma bit depth (%d) is different from PCM chroma"
+                   "bit depth (%d), this is unsupported.\n",
+                   sps->pcm.bit_depth, pcm_bit_depth_chroma);
+            ret = AVERROR_INVALIDDATA;
+            goto err;
+        }
+
+        sps->pcm.log2_min_pcm_cb_size = get_ue_golomb_long(gb) + 3;
+        sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size +
+                                        get_ue_golomb_long(gb);
+        if (sps->pcm.bit_depth > sps->bit_depth) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "PCM bit depth (%d) is greater than normal bit depth (%d)\n",
+                   sps->pcm.bit_depth, sps->bit_depth);
+            ret = AVERROR_INVALIDDATA;
+            goto err;
+        }
+
+        sps->pcm.loop_filter_disable_flag = get_bits1(gb);
+    }
+
+    sps->nb_st_rps = get_ue_golomb_long(gb);
+    if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) {
+        av_log(s->avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n",
+               sps->nb_st_rps);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+    for (i = 0; i < sps->nb_st_rps; i++) {
+        if ((ret = ff_hevc_decode_short_term_rps(s, &sps->st_rps[i],
+                                                 sps, 0)) < 0)
+            goto err;
+    }
+
+    sps->long_term_ref_pics_present_flag = get_bits1(gb);
+    if (sps->long_term_ref_pics_present_flag) {
+        sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb);
+        for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
+            sps->lt_ref_pic_poc_lsb_sps[i]       = get_bits(gb, sps->log2_max_poc_lsb);
+            sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb);
+        }
+    }
+
+    sps->sps_temporal_mvp_enabled_flag          = get_bits1(gb);
+    sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb);
+    sps->vui.sar = (AVRational){0, 1};
+    vui_present = get_bits1(gb);
+    if (vui_present)
+        decode_vui(s, sps);
+    skip_bits1(gb); // sps_extension_flag
+
+    if (s->apply_defdispwin) {
+        sps->output_window.left_offset   += sps->vui.def_disp_win.left_offset;
+        sps->output_window.right_offset  += sps->vui.def_disp_win.right_offset;
+        sps->output_window.top_offset    += sps->vui.def_disp_win.top_offset;
+        sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;
+    }
+    if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) &&
+        !(s->avctx->flags & CODEC_FLAG_UNALIGNED)) {
+        sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift));
+        av_log(s->avctx, AV_LOG_WARNING, "Reducing left output window to %d "
+               "chroma samples to preserve alignment.\n",
+               sps->output_window.left_offset);
+    }
+    sps->output_width  = sps->width -
+                         (sps->output_window.left_offset + sps->output_window.right_offset);
+    sps->output_height = sps->height -
+                         (sps->output_window.top_offset + sps->output_window.bottom_offset);
+    if (sps->output_width <= 0 || sps->output_height <= 0) {
+        av_log(s->avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",
+               sps->output_width, sps->output_height);
+        if (s->avctx->err_recognition & AV_EF_EXPLODE) {
+            ret = AVERROR_INVALIDDATA;
+            goto err;
+        }
+        av_log(s->avctx, AV_LOG_WARNING,
+               "Displaying the whole video surface.\n");
+        sps->pic_conf_win.left_offset   =
+        sps->pic_conf_win.right_offset  =
+        sps->pic_conf_win.top_offset    =
+        sps->pic_conf_win.bottom_offset = 0;
+        sps->output_width               = sps->width;
+        sps->output_height              = sps->height;
+    }
+
+    // Inferred parameters
+    sps->log2_ctb_size = sps->log2_min_cb_size +
+                         sps->log2_diff_max_min_coding_block_size;
+    sps->log2_min_pu_size = sps->log2_min_cb_size - 1;
+
+    sps->ctb_width  = (sps->width  + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
+    sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
+    sps->ctb_size   = sps->ctb_width * sps->ctb_height;
+
+    sps->min_cb_width  = sps->width  >> sps->log2_min_cb_size;
+    sps->min_cb_height = sps->height >> sps->log2_min_cb_size;
+    sps->min_tb_width  = sps->width  >> sps->log2_min_tb_size;
+    sps->min_tb_height = sps->height >> sps->log2_min_tb_size;
+    sps->min_pu_width  = sps->width  >> sps->log2_min_pu_size;
+    sps->min_pu_height = sps->height >> sps->log2_min_pu_size;
+
+    sps->qp_bd_offset = 6 * (sps->bit_depth - 8);
+
+    if (sps->width  & ((1 << sps->log2_min_cb_size) - 1) ||
+        sps->height & ((1 << sps->log2_min_cb_size) - 1)) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");
+        goto err;
+    }
+
+    if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {
+        av_log(s->avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
+        goto err;
+    }
+    if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) {
+        av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n",
+               sps->max_transform_hierarchy_depth_inter);
+        goto err;
+    }
+    if (sps->max_transform_hierarchy_depth_intra > sps->log2_ctb_size - sps->log2_min_tb_size) {
+        av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_intra out of range: %d\n",
+               sps->max_transform_hierarchy_depth_intra);
+        goto err;
+    }
+    if (sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_size, 5)) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "max transform block size out of range: %d\n",
+               sps->log2_max_trafo_size);
+        goto err;
+    }
+
+    if (s->avctx->debug & FF_DEBUG_BITSTREAM) {
+        av_log(s->avctx, AV_LOG_DEBUG,
+               "Parsed SPS: id %d; coded wxh: %dx%d; "
+               "cropped wxh: %dx%d; pix_fmt: %s.\n",
+               sps_id, sps->width, sps->height,
+               sps->output_width, sps->output_height,
+               av_get_pix_fmt_name(sps->pix_fmt));
+    }
+
+    /* check if this is a repeat of an already parsed SPS, then keep the
+     * original one.
+     * otherwise drop all PPSes that depend on it */
+    if (s->sps_list[sps_id] &&
+        !memcmp(s->sps_list[sps_id]->data, sps_buf->data, sps_buf->size)) {
+        av_buffer_unref(&sps_buf);
+    } else {
+        for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++) {
+            if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i]->data)->sps_id == sps_id)
+                av_buffer_unref(&s->pps_list[i]);
+        }
+        av_buffer_unref(&s->sps_list[sps_id]);
+        s->sps_list[sps_id] = sps_buf;
+    }
+
+    return 0;
+
+err:
+    av_buffer_unref(&sps_buf);
+    return ret;
+}
+
+static void hevc_pps_free(void *opaque, uint8_t *data)
+{
+    HEVCPPS *pps = (HEVCPPS*)data;
+
+    av_freep(&pps->column_width);
+    av_freep(&pps->row_height);
+    av_freep(&pps->col_bd);
+    av_freep(&pps->row_bd);
+    av_freep(&pps->col_idxX);
+    av_freep(&pps->ctb_addr_rs_to_ts);
+    av_freep(&pps->ctb_addr_ts_to_rs);
+    av_freep(&pps->tile_pos_rs);
+    av_freep(&pps->tile_id);
+    av_freep(&pps->min_cb_addr_zs);
+    av_freep(&pps->min_tb_addr_zs);
+
+    av_freep(&pps);
+}
+
+int ff_hevc_decode_nal_pps(HEVCContext *s)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+    HEVCSPS      *sps = NULL;
+    int pic_area_in_ctbs, pic_area_in_min_cbs, pic_area_in_min_tbs;
+    int log2_diff_ctb_min_tb_size;
+    int i, j, x, y, ctb_addr_rs, tile_id;
+    int ret    = 0;
+    int pps_id = 0;
+
+    AVBufferRef *pps_buf;
+    HEVCPPS *pps = av_mallocz(sizeof(*pps));
+
+    if (!pps)
+        return AVERROR(ENOMEM);
+
+    pps_buf = av_buffer_create((uint8_t *)pps, sizeof(*pps),
+                               hevc_pps_free, NULL, 0);
+    if (!pps_buf) {
+        av_freep(&pps);
+        return AVERROR(ENOMEM);
+    }
+
+    av_log(s->avctx, AV_LOG_DEBUG, "Decoding PPS\n");
+
+    // Default values
+    pps->loop_filter_across_tiles_enabled_flag = 1;
+    pps->num_tile_columns                      = 1;
+    pps->num_tile_rows                         = 1;
+    pps->uniform_spacing_flag                  = 1;
+    pps->disable_dbf                           = 0;
+    pps->beta_offset                           = 0;
+    pps->tc_offset                             = 0;
+
+    // Coded parameters
+    pps_id = get_ue_golomb_long(gb);
+    if (pps_id >= MAX_PPS_COUNT) {
+        av_log(s->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+    pps->sps_id = get_ue_golomb_long(gb);
+    if (pps->sps_id >= MAX_SPS_COUNT) {
+        av_log(s->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", pps->sps_id);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+    if (!s->sps_list[pps->sps_id]) {
+        av_log(s->avctx, AV_LOG_ERROR, "SPS does not exist \n");
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+    sps = (HEVCSPS *)s->sps_list[pps->sps_id]->data;
+
+    pps->dependent_slice_segments_enabled_flag = get_bits1(gb);
+    pps->output_flag_present_flag              = get_bits1(gb);
+    pps->num_extra_slice_header_bits           = get_bits(gb, 3);
+
+    pps->sign_data_hiding_flag = get_bits1(gb);
+
+    pps->cabac_init_present_flag = get_bits1(gb);
+
+    pps->num_ref_idx_l0_default_active = get_ue_golomb_long(gb) + 1;
+    pps->num_ref_idx_l1_default_active = get_ue_golomb_long(gb) + 1;
+
+    pps->pic_init_qp_minus26 = get_se_golomb(gb);
+
+    pps->constrained_intra_pred_flag = get_bits1(gb);
+    pps->transform_skip_enabled_flag = get_bits1(gb);
+
+    pps->cu_qp_delta_enabled_flag = get_bits1(gb);
+    pps->diff_cu_qp_delta_depth   = 0;
+    if (pps->cu_qp_delta_enabled_flag)
+        pps->diff_cu_qp_delta_depth = get_ue_golomb_long(gb);
+
+    pps->cb_qp_offset = get_se_golomb(gb);
+    if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) {
+        av_log(s->avctx, AV_LOG_ERROR, "pps_cb_qp_offset out of range: %d\n",
+               pps->cb_qp_offset);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+    pps->cr_qp_offset = get_se_golomb(gb);
+    if (pps->cr_qp_offset < -12 || pps->cr_qp_offset > 12) {
+        av_log(s->avctx, AV_LOG_ERROR, "pps_cr_qp_offset out of range: %d\n",
+               pps->cr_qp_offset);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+    pps->pic_slice_level_chroma_qp_offsets_present_flag = get_bits1(gb);
+
+    pps->weighted_pred_flag   = get_bits1(gb);
+    pps->weighted_bipred_flag = get_bits1(gb);
+
+    pps->transquant_bypass_enable_flag    = get_bits1(gb);
+    pps->tiles_enabled_flag               = get_bits1(gb);
+    pps->entropy_coding_sync_enabled_flag = get_bits1(gb);
+
+    if (pps->tiles_enabled_flag) {
+        pps->num_tile_columns = get_ue_golomb_long(gb) + 1;
+        pps->num_tile_rows    = get_ue_golomb_long(gb) + 1;
+        if (pps->num_tile_columns == 0 ||
+            pps->num_tile_columns >= sps->width) {
+            av_log(s->avctx, AV_LOG_ERROR, "num_tile_columns_minus1 out of range: %d\n",
+                   pps->num_tile_columns - 1);
+            ret = AVERROR_INVALIDDATA;
+            goto err;
+        }
+        if (pps->num_tile_rows == 0 ||
+            pps->num_tile_rows >= sps->height) {
+            av_log(s->avctx, AV_LOG_ERROR, "num_tile_rows_minus1 out of range: %d\n",
+                   pps->num_tile_rows - 1);
+            ret = AVERROR_INVALIDDATA;
+            goto err;
+        }
+
+        pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));
+        pps->row_height   = av_malloc_array(pps->num_tile_rows,    sizeof(*pps->row_height));
+        if (!pps->column_width || !pps->row_height) {
+            ret = AVERROR(ENOMEM);
+            goto err;
+        }
+
+        pps->uniform_spacing_flag = get_bits1(gb);
+        if (!pps->uniform_spacing_flag) {
+            int sum = 0;
+            for (i = 0; i < pps->num_tile_columns - 1; i++) {
+                pps->column_width[i] = get_ue_golomb_long(gb) + 1;
+                sum                 += pps->column_width[i];
+            }
+            if (sum >= sps->ctb_width) {
+                av_log(s->avctx, AV_LOG_ERROR, "Invalid tile widths.\n");
+                ret = AVERROR_INVALIDDATA;
+                goto err;
+            }
+            pps->column_width[pps->num_tile_columns - 1] = sps->ctb_width - sum;
+
+            sum = 0;
+            for (i = 0; i < pps->num_tile_rows - 1; i++) {
+                pps->row_height[i] = get_ue_golomb_long(gb) + 1;
+                sum               += pps->row_height[i];
+            }
+            if (sum >= sps->ctb_height) {
+                av_log(s->avctx, AV_LOG_ERROR, "Invalid tile heights.\n");
+                ret = AVERROR_INVALIDDATA;
+                goto err;
+            }
+            pps->row_height[pps->num_tile_rows - 1] = sps->ctb_height - sum;
+        }
+        pps->loop_filter_across_tiles_enabled_flag = get_bits1(gb);
+    }
+
+    pps->seq_loop_filter_across_slices_enabled_flag = get_bits1(gb);
+
+    pps->deblocking_filter_control_present_flag = get_bits1(gb);
+    if (pps->deblocking_filter_control_present_flag) {
+        pps->deblocking_filter_override_enabled_flag = get_bits1(gb);
+        pps->disable_dbf                             = get_bits1(gb);
+        if (!pps->disable_dbf) {
+            pps->beta_offset = get_se_golomb(gb) * 2;
+            pps->tc_offset = get_se_golomb(gb) * 2;
+            if (pps->beta_offset/2 < -6 || pps->beta_offset/2 > 6) {
+                av_log(s->avctx, AV_LOG_ERROR, "pps_beta_offset_div2 out of range: %d\n",
+                       pps->beta_offset/2);
+                ret = AVERROR_INVALIDDATA;
+                goto err;
+            }
+            if (pps->tc_offset/2 < -6 || pps->tc_offset/2 > 6) {
+                av_log(s->avctx, AV_LOG_ERROR, "pps_tc_offset_div2 out of range: %d\n",
+                       pps->tc_offset/2);
+                ret = AVERROR_INVALIDDATA;
+                goto err;
+            }
+        }
+    }
+
+    pps->scaling_list_data_present_flag = get_bits1(gb);
+    if (pps->scaling_list_data_present_flag) {
+        set_default_scaling_list_data(&pps->scaling_list);
+        ret = scaling_list_data(s, &pps->scaling_list);
+        if (ret < 0)
+            goto err;
+    }
+    pps->lists_modification_present_flag = get_bits1(gb);
+    pps->log2_parallel_merge_level       = get_ue_golomb_long(gb) + 2;
+    if (pps->log2_parallel_merge_level > sps->log2_ctb_size) {
+        av_log(s->avctx, AV_LOG_ERROR, "log2_parallel_merge_level_minus2 out of range: %d\n",
+               pps->log2_parallel_merge_level - 2);
+        ret = AVERROR_INVALIDDATA;
+        goto err;
+    }
+
+    pps->slice_header_extension_present_flag = get_bits1(gb);
+    skip_bits1(gb);     // pps_extension_flag
+
+    // Inferred parameters
+    pps->col_bd   = av_malloc_array(pps->num_tile_columns + 1, sizeof(*pps->col_bd));
+    pps->row_bd   = av_malloc_array(pps->num_tile_rows + 1,    sizeof(*pps->row_bd));
+    pps->col_idxX = av_malloc_array(sps->ctb_width,    sizeof(*pps->col_idxX));
+    if (!pps->col_bd || !pps->row_bd || !pps->col_idxX) {
+        ret = AVERROR(ENOMEM);
+        goto err;
+    }
+
+    if (pps->uniform_spacing_flag) {
+        if (!pps->column_width) {
+            pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));
+            pps->row_height   = av_malloc_array(pps->num_tile_rows,    sizeof(*pps->row_height));
+        }
+        if (!pps->column_width || !pps->row_height) {
+            ret = AVERROR(ENOMEM);
+            goto err;
+        }
+
+        for (i = 0; i < pps->num_tile_columns; i++) {
+            pps->column_width[i] = ((i + 1) * sps->ctb_width) / pps->num_tile_columns -
+                                   (i * sps->ctb_width) / pps->num_tile_columns;
+        }
+
+        for (i = 0; i < pps->num_tile_rows; i++) {
+            pps->row_height[i] = ((i + 1) * sps->ctb_height) / pps->num_tile_rows -
+                                 (i * sps->ctb_height) / pps->num_tile_rows;
+        }
+    }
+
+    pps->col_bd[0] = 0;
+    for (i = 0; i < pps->num_tile_columns; i++)
+        pps->col_bd[i + 1] = pps->col_bd[i] + pps->column_width[i];
+
+    pps->row_bd[0] = 0;
+    for (i = 0; i < pps->num_tile_rows; i++)
+        pps->row_bd[i + 1] = pps->row_bd[i] + pps->row_height[i];
+
+    for (i = 0, j = 0; i < sps->ctb_width; i++) {
+        if (i > pps->col_bd[j])
+            j++;
+        pps->col_idxX[i] = j;
+    }
+
+    /**
+     * 6.5
+     */
+    pic_area_in_ctbs     = sps->ctb_width    * sps->ctb_height;
+    pic_area_in_min_cbs  = sps->min_cb_width * sps->min_cb_height;
+    pic_area_in_min_tbs  = sps->min_tb_width * sps->min_tb_height;
+
+    pps->ctb_addr_rs_to_ts = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->ctb_addr_rs_to_ts));
+    pps->ctb_addr_ts_to_rs = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->ctb_addr_ts_to_rs));
+    pps->tile_id           = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->tile_id));
+    pps->min_cb_addr_zs    = av_malloc_array(pic_area_in_min_cbs, sizeof(*pps->min_cb_addr_zs));
+    pps->min_tb_addr_zs    = av_malloc_array(pic_area_in_min_tbs, sizeof(*pps->min_tb_addr_zs));
+    if (!pps->ctb_addr_rs_to_ts || !pps->ctb_addr_ts_to_rs ||
+        !pps->tile_id || !pps->min_cb_addr_zs || !pps->min_tb_addr_zs) {
+        ret = AVERROR(ENOMEM);
+        goto err;
+    }
+
+    for (ctb_addr_rs = 0; ctb_addr_rs < pic_area_in_ctbs; ctb_addr_rs++) {
+        int tb_x   = ctb_addr_rs % sps->ctb_width;
+        int tb_y   = ctb_addr_rs / sps->ctb_width;
+        int tile_x = 0;
+        int tile_y = 0;
+        int val    = 0;
+
+        for (i = 0; i < pps->num_tile_columns; i++) {
+            if (tb_x < pps->col_bd[i + 1]) {
+                tile_x = i;
+                break;
+            }
+        }
+
+        for (i = 0; i < pps->num_tile_rows; i++) {
+            if (tb_y < pps->row_bd[i + 1]) {
+                tile_y = i;
+                break;
+            }
+        }
+
+        for (i = 0; i < tile_x; i++)
+            val += pps->row_height[tile_y] * pps->column_width[i];
+        for (i = 0; i < tile_y; i++)
+            val += sps->ctb_width * pps->row_height[i];
+
+        val += (tb_y - pps->row_bd[tile_y]) * pps->column_width[tile_x] +
+               tb_x - pps->col_bd[tile_x];
+
+        pps->ctb_addr_rs_to_ts[ctb_addr_rs] = val;
+        pps->ctb_addr_ts_to_rs[val]         = ctb_addr_rs;
+    }
+
+    for (j = 0, tile_id = 0; j < pps->num_tile_rows; j++)
+        for (i = 0; i < pps->num_tile_columns; i++, tile_id++)
+            for (y = pps->row_bd[j]; y < pps->row_bd[j + 1]; y++)
+                for (x = pps->col_bd[i]; x < pps->col_bd[i + 1]; x++)
+                    pps->tile_id[pps->ctb_addr_rs_to_ts[y * sps->ctb_width + x]] = tile_id;
+
+    pps->tile_pos_rs = av_malloc_array(tile_id, sizeof(*pps->tile_pos_rs));
+    if (!pps->tile_pos_rs) {
+        ret = AVERROR(ENOMEM);
+        goto err;
+    }
+
+    for (j = 0; j < pps->num_tile_rows; j++)
+        for (i = 0; i < pps->num_tile_columns; i++)
+            pps->tile_pos_rs[j * pps->num_tile_columns + i] = pps->row_bd[j] * sps->ctb_width + pps->col_bd[i];
+
+    for (y = 0; y < sps->min_cb_height; y++) {
+        for (x = 0; x < sps->min_cb_width; x++) {
+            int tb_x        = x >> sps->log2_diff_max_min_coding_block_size;
+            int tb_y        = y >> sps->log2_diff_max_min_coding_block_size;
+            int ctb_addr_rs = sps->ctb_width * tb_y + tb_x;
+            int val         = pps->ctb_addr_rs_to_ts[ctb_addr_rs] <<
+                              (sps->log2_diff_max_min_coding_block_size * 2);
+            for (i = 0; i < sps->log2_diff_max_min_coding_block_size; i++) {
+                int m = 1 << i;
+                val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);
+            }
+            pps->min_cb_addr_zs[y * sps->min_cb_width + x] = val;
+        }
+    }
+
+    log2_diff_ctb_min_tb_size = sps->log2_ctb_size - sps->log2_min_tb_size;
+    for (y = 0; y < sps->min_tb_height; y++) {
+        for (x = 0; x < sps->min_tb_width; x++) {
+            int tb_x        = x >> log2_diff_ctb_min_tb_size;
+            int tb_y        = y >> log2_diff_ctb_min_tb_size;
+            int ctb_addr_rs = sps->ctb_width * tb_y + tb_x;
+            int val         = pps->ctb_addr_rs_to_ts[ctb_addr_rs] <<
+                              (log2_diff_ctb_min_tb_size * 2);
+            for (i = 0; i < log2_diff_ctb_min_tb_size; i++) {
+                int m = 1 << i;
+                val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);
+            }
+            pps->min_tb_addr_zs[y * sps->min_tb_width + x] = val;
+        }
+    }
+
+    av_buffer_unref(&s->pps_list[pps_id]);
+    s->pps_list[pps_id] = pps_buf;
+
+    return 0;
+
+err:
+    av_buffer_unref(&pps_buf);
+    return ret;
+}
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
new file mode 100644
index 0000000..2fbe9e7
--- /dev/null
+++ b/libavcodec/hevc_refs.c
@@ -0,0 +1,489 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ *
+ * 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/pixdesc.h"
+
+#include "internal.h"
+#include "thread.h"
+#include "hevc.h"
+
+void ff_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags)
+{
+    /* frame->frame can be NULL if context init failed */
+    if (!frame->frame || !frame->frame->buf[0])
+        return;
+
+    frame->flags &= ~flags;
+    if (!frame->flags) {
+        ff_thread_release_buffer(s->avctx, &frame->tf);
+
+        av_buffer_unref(&frame->tab_mvf_buf);
+        frame->tab_mvf = NULL;
+
+        av_buffer_unref(&frame->rpl_buf);
+        av_buffer_unref(&frame->rpl_tab_buf);
+        frame->rpl_tab    = NULL;
+        frame->refPicList = NULL;
+
+        frame->collocated_ref = NULL;
+    }
+}
+
+RefPicList *ff_hevc_get_ref_list(HEVCContext *s, HEVCFrame *ref, int x0, int y0)
+{
+    if (x0 < 0 || y0 < 0) {
+        return s->ref->refPicList;
+    } else {
+        int x_cb         = x0 >> s->sps->log2_ctb_size;
+        int y_cb         = y0 >> s->sps->log2_ctb_size;
+        int pic_width_cb = (s->sps->width + (1 << s->sps->log2_ctb_size) - 1) >>
+                           s->sps->log2_ctb_size;
+        int ctb_addr_ts  = s->pps->ctb_addr_rs_to_ts[y_cb * pic_width_cb + x_cb];
+        return (RefPicList *)ref->rpl_tab[ctb_addr_ts];
+    }
+}
+
+void ff_hevc_clear_refs(HEVCContext *s)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++)
+        ff_hevc_unref_frame(s, &s->DPB[i],
+                            HEVC_FRAME_FLAG_SHORT_REF |
+                            HEVC_FRAME_FLAG_LONG_REF);
+}
+
+void ff_hevc_flush_dpb(HEVCContext *s)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++)
+        ff_hevc_unref_frame(s, &s->DPB[i], ~0);
+}
+
+static HEVCFrame *alloc_frame(HEVCContext *s)
+{
+    int i, j, ret;
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        HEVCFrame *frame = &s->DPB[i];
+        if (frame->frame->buf[0])
+            continue;
+
+        ret = ff_thread_get_buffer(s->avctx, &frame->tf,
+                                   AV_GET_BUFFER_FLAG_REF);
+        if (ret < 0)
+            return NULL;
+
+        frame->rpl_buf = av_buffer_allocz(s->nb_nals * sizeof(RefPicListTab));
+        if (!frame->rpl_buf)
+            goto fail;
+
+        frame->tab_mvf_buf = av_buffer_pool_get(s->tab_mvf_pool);
+        if (!frame->tab_mvf_buf)
+            goto fail;
+        frame->tab_mvf = (MvField *)frame->tab_mvf_buf->data;
+
+        frame->rpl_tab_buf = av_buffer_pool_get(s->rpl_tab_pool);
+        if (!frame->rpl_tab_buf)
+            goto fail;
+        frame->rpl_tab   = (RefPicListTab **)frame->rpl_tab_buf->data;
+        frame->ctb_count = s->sps->ctb_width * s->sps->ctb_height;
+        for (j = 0; j < frame->ctb_count; j++)
+            frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data;
+
+        return frame;
+
+fail:
+        ff_hevc_unref_frame(s, frame, ~0);
+        return NULL;
+    }
+    av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n");
+    return NULL;
+}
+
+int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc)
+{
+    HEVCFrame *ref;
+    int i;
+
+    /* check that this POC doesn't already exist */
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        HEVCFrame *frame = &s->DPB[i];
+
+        if (frame->frame->buf[0] && frame->sequence == s->seq_decode &&
+            frame->poc == poc) {
+            av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n",
+                   poc);
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    ref = alloc_frame(s);
+    if (!ref)
+        return AVERROR(ENOMEM);
+
+    *frame = ref->frame;
+    s->ref = ref;
+
+    ref->poc      = poc;
+    ref->flags    = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF;
+    ref->sequence = s->seq_decode;
+    ref->window   = s->sps->output_window;
+
+    return 0;
+}
+
+int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
+{
+    do {
+        int nb_output = 0;
+        int min_poc   = INT_MAX;
+        int i, min_idx, ret;
+
+        for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+            HEVCFrame *frame = &s->DPB[i];
+            if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) &&
+                frame->sequence == s->seq_output) {
+                nb_output++;
+                if (frame->poc < min_poc) {
+                    min_poc = frame->poc;
+                    min_idx = i;
+                }
+            }
+        }
+
+        /* wait for more frames before output */
+        if (!flush && s->seq_output == s->seq_decode && s->sps &&
+            nb_output <= s->sps->temporal_layer[s->sps->max_sub_layers - 1].num_reorder_pics)
+            return 0;
+
+        if (nb_output) {
+            HEVCFrame *frame = &s->DPB[min_idx];
+            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->frame->format);
+            int pixel_shift;
+
+            if (!desc)
+                return AVERROR_BUG;
+
+            pixel_shift = desc->comp[0].depth_minus1 > 7;
+
+            ret = av_frame_ref(out, frame->frame);
+            ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT);
+            if (ret < 0)
+                return ret;
+
+            for (i = 0; i < 3; i++) {
+                int hshift = (i > 0) ? desc->log2_chroma_w : 0;
+                int vshift = (i > 0) ? desc->log2_chroma_h : 0;
+                int off = ((frame->window.left_offset >> hshift) << pixel_shift) +
+                          (frame->window.top_offset   >> vshift) * out->linesize[i];
+                out->data[i] += off;
+            }
+            av_log(s->avctx, AV_LOG_DEBUG,
+                   "Output frame with POC %d.\n", frame->poc);
+            return 1;
+        }
+
+        if (s->seq_output != s->seq_decode)
+            s->seq_output = (s->seq_output + 1) & 0xff;
+        else
+            break;
+    } while (1);
+
+    return 0;
+}
+
+static int init_slice_rpl(HEVCContext *s)
+{
+    HEVCFrame *frame = s->ref;
+    int ctb_count    = frame->ctb_count;
+    int ctb_addr_ts  = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr];
+    int i;
+
+    if (s->slice_idx >= frame->rpl_buf->size / sizeof(RefPicListTab))
+        return AVERROR_INVALIDDATA;
+
+    for (i = ctb_addr_ts; i < ctb_count; i++)
+        frame->rpl_tab[i] = (RefPicListTab *)frame->rpl_buf->data + s->slice_idx;
+
+    frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts];
+
+    return 0;
+}
+
+int ff_hevc_slice_rpl(HEVCContext *s)
+{
+    SliceHeader *sh = &s->sh;
+
+    uint8_t nb_list = sh->slice_type == B_SLICE ? 2 : 1;
+    uint8_t list_idx;
+    int i, j, ret;
+
+    ret = init_slice_rpl(s);
+    if (ret < 0)
+        return ret;
+
+    if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs +
+          s->rps[LT_CURR].nb_refs)) {
+        av_log(s->avctx, AV_LOG_ERROR, "Zero refs in the frame RPS.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    for (list_idx = 0; list_idx < nb_list; list_idx++) {
+        RefPicList  rpl_tmp = { { 0 } };
+        RefPicList *rpl     = &s->ref->refPicList[list_idx];
+
+        /* The order of the elements is
+         * ST_CURR_BEF - ST_CURR_AFT - LT_CURR for the L0 and
+         * ST_CURR_AFT - ST_CURR_BEF - LT_CURR for the L1 */
+        int cand_lists[3] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF,
+                              list_idx ? ST_CURR_BEF : ST_CURR_AFT,
+                              LT_CURR };
+
+        /* concatenate the candidate lists for the current frame */
+        while (rpl_tmp.nb_refs < sh->nb_refs[list_idx]) {
+            for (i = 0; i < FF_ARRAY_ELEMS(cand_lists); i++) {
+                RefPicList *rps = &s->rps[cand_lists[i]];
+                for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < MAX_REFS; j++) {
+                    rpl_tmp.list[rpl_tmp.nb_refs]       = rps->list[j];
+                    rpl_tmp.ref[rpl_tmp.nb_refs]        = rps->ref[j];
+                    rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = i == 2;
+                    rpl_tmp.nb_refs++;
+                }
+            }
+        }
+
+        /* reorder the references if necessary */
+        if (sh->rpl_modification_flag[list_idx]) {
+            for (i = 0; i < sh->nb_refs[list_idx]; i++) {
+                int idx = sh->list_entry_lx[list_idx][i];
+
+                if (idx >= rpl_tmp.nb_refs) {
+                    av_log(s->avctx, AV_LOG_ERROR, "Invalid reference index.\n");
+                    return AVERROR_INVALIDDATA;
+                }
+
+                rpl->list[i]       = rpl_tmp.list[idx];
+                rpl->ref[i]        = rpl_tmp.ref[idx];
+                rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx];
+                rpl->nb_refs++;
+            }
+        } else {
+            memcpy(rpl, &rpl_tmp, sizeof(*rpl));
+            rpl->nb_refs = FFMIN(rpl->nb_refs, sh->nb_refs[list_idx]);
+        }
+
+        if (sh->collocated_list == list_idx &&
+            sh->collocated_ref_idx < rpl->nb_refs)
+            s->ref->collocated_ref = rpl->ref[sh->collocated_ref_idx];
+    }
+
+    return 0;
+}
+
+static HEVCFrame *find_ref_idx(HEVCContext *s, int poc)
+{
+    int i;
+    int LtMask = (1 << s->sps->log2_max_poc_lsb) - 1;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        HEVCFrame *ref = &s->DPB[i];
+        if (ref->frame->buf[0] && (ref->sequence == s->seq_decode)) {
+            if ((ref->poc & LtMask) == poc)
+                return ref;
+        }
+    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        HEVCFrame *ref = &s->DPB[i];
+        if (ref->frame->buf[0] && ref->sequence == s->seq_decode) {
+            if (ref->poc == poc || (ref->poc & LtMask) == poc)
+                return ref;
+        }
+    }
+
+    av_log(s->avctx, AV_LOG_ERROR,
+           "Could not find ref with POC %d\n", poc);
+    return NULL;
+}
+
+static void mark_ref(HEVCFrame *frame, int flag)
+{
+    frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF);
+    frame->flags |= flag;
+}
+
+static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
+{
+    HEVCFrame *frame;
+    int i, x, y;
+
+    frame = alloc_frame(s);
+    if (!frame)
+        return NULL;
+
+    if (!s->sps->pixel_shift) {
+        for (i = 0; frame->frame->buf[i]; i++)
+            memset(frame->frame->buf[i]->data, 1 << (s->sps->bit_depth - 1),
+                   frame->frame->buf[i]->size);
+    } else {
+        for (i = 0; frame->frame->data[i]; i++)
+            for (y = 0; y < (s->sps->height >> s->sps->vshift[i]); y++)
+                for (x = 0; x < (s->sps->width >> s->sps->hshift[i]); x++) {
+                    AV_WN16(frame->frame->data[i] + y * frame->frame->linesize[i] + 2 * x,
+                            1 << (s->sps->bit_depth - 1));
+                }
+    }
+
+    frame->poc      = poc;
+    frame->sequence = s->seq_decode;
+    frame->flags    = 0;
+
+    ff_thread_report_progress(&frame->tf, INT_MAX, 0);
+
+    return frame;
+}
+
+/* add a reference with the given poc to the list and mark it as used in DPB */
+static int add_candidate_ref(HEVCContext *s, RefPicList *list,
+                             int poc, int ref_flag)
+{
+    HEVCFrame *ref = find_ref_idx(s, poc);
+
+    if (ref == s->ref)
+        return AVERROR_INVALIDDATA;
+
+    if (!ref) {
+        ref = generate_missing_ref(s, poc);
+        if (!ref)
+            return AVERROR(ENOMEM);
+    }
+
+    list->list[list->nb_refs] = ref->poc;
+    list->ref[list->nb_refs]  = ref;
+    list->nb_refs++;
+
+    mark_ref(ref, ref_flag);
+    return 0;
+}
+
+int ff_hevc_frame_rps(HEVCContext *s)
+{
+    const ShortTermRPS *short_rps = s->sh.short_term_rps;
+    const LongTermRPS  *long_rps  = &s->sh.long_term_rps;
+    RefPicList               *rps = s->rps;
+    int i, ret;
+
+    if (!short_rps) {
+        rps[0].nb_refs = rps[1].nb_refs = 0;
+        return 0;
+    }
+
+    /* clear the reference flags on all frames except the current one */
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
+        HEVCFrame *frame = &s->DPB[i];
+
+        if (frame == s->ref)
+            continue;
+
+        mark_ref(frame, 0);
+    }
+
+    for (i = 0; i < NB_RPS_TYPE; i++)
+        rps[i].nb_refs = 0;
+
+    /* add the short refs */
+    for (i = 0; i < short_rps->num_delta_pocs; i++) {
+        int poc = s->poc + short_rps->delta_poc[i];
+        int list;
+
+        if (!short_rps->used[i])
+            list = ST_FOLL;
+        else if (i < short_rps->num_negative_pics)
+            list = ST_CURR_BEF;
+        else
+            list = ST_CURR_AFT;
+
+        ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF);
+        if (ret < 0)
+            return ret;
+    }
+
+    /* add the long refs */
+    for (i = 0; i < long_rps->nb_refs; i++) {
+        int poc  = long_rps->poc[i];
+        int list = long_rps->used[i] ? LT_CURR : LT_FOLL;
+
+        ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF);
+        if (ret < 0)
+            return ret;
+    }
+
+    /* release any frames that are now unused */
+    for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++)
+        ff_hevc_unref_frame(s, &s->DPB[i], 0);
+
+    return 0;
+}
+
+int ff_hevc_compute_poc(HEVCContext *s, int poc_lsb)
+{
+    int max_poc_lsb  = 1 << s->sps->log2_max_poc_lsb;
+    int prev_poc_lsb = s->pocTid0 % max_poc_lsb;
+    int prev_poc_msb = s->pocTid0 - prev_poc_lsb;
+    int poc_msb;
+
+    if (poc_lsb < prev_poc_lsb && prev_poc_lsb - poc_lsb >= max_poc_lsb / 2)
+        poc_msb = prev_poc_msb + max_poc_lsb;
+    else if (poc_lsb > prev_poc_lsb && poc_lsb - prev_poc_lsb > max_poc_lsb / 2)
+        poc_msb = prev_poc_msb - max_poc_lsb;
+    else
+        poc_msb = prev_poc_msb;
+
+    // For BLA picture types, POCmsb is set to 0.
+    if (s->nal_unit_type == NAL_BLA_W_LP   ||
+        s->nal_unit_type == NAL_BLA_W_RADL ||
+        s->nal_unit_type == NAL_BLA_N_LP)
+        poc_msb = 0;
+
+    return poc_msb + poc_lsb;
+}
+
+int ff_hevc_frame_nb_refs(HEVCContext *s)
+{
+    int ret = 0;
+    int i;
+    const ShortTermRPS *rps = s->sh.short_term_rps;
+    LongTermRPS *long_rps   = &s->sh.long_term_rps;
+
+    if (rps) {
+        for (i = 0; i < rps->num_negative_pics; i++)
+            ret += !!rps->used[i];
+        for (; i < rps->num_delta_pocs; i++)
+            ret += !!rps->used[i];
+    }
+
+    if (long_rps) {
+        for (i = 0; i < long_rps->nb_refs; i++)
+            ret += !!long_rps->used[i];
+    }
+    return ret;
+}
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
new file mode 100644
index 0000000..b011596
--- /dev/null
+++ b/libavcodec/hevc_sei.c
@@ -0,0 +1,123 @@
+/*
+ * HEVC Supplementary Enhancement Information messages
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2013 Vittorio Giovara
+ *
+ * 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 "golomb.h"
+#include "hevc.h"
+
+static void decode_nal_sei_decoded_picture_hash(HEVCContext *s)
+{
+    int cIdx, i;
+    GetBitContext *gb = &s->HEVClc.gb;
+    uint8_t hash_type = get_bits(gb, 8);
+
+    for (cIdx = 0; cIdx < 3; cIdx++) {
+        if (hash_type == 0) {
+            s->is_md5 = 1;
+            for (i = 0; i < 16; i++)
+                s->md5[cIdx][i] = get_bits(gb, 8);
+        } else if (hash_type == 1) {
+            // picture_crc = get_bits(gb, 16);
+            skip_bits(gb, 16);
+        } else if (hash_type == 2) {
+            // picture_checksum = get_bits(gb, 32);
+            skip_bits(gb, 32);
+        }
+    }
+}
+
+static void decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+
+    get_ue_golomb(gb);                  // frame_packing_arrangement_id
+    s->sei_frame_packing_present = !get_bits1(gb);
+
+    if (s->sei_frame_packing_present) {
+        s->frame_packing_arrangement_type = get_bits(gb, 7);
+        s->quincunx_subsampling           = get_bits1(gb);
+        s->content_interpretation_type    = get_bits(gb, 6);
+
+        // the following skips spatial_flipping_flag frame0_flipped_flag
+        // field_views_flag current_frame_is_frame0_flag
+        // frame0_self_contained_flag frame1_self_contained_flag
+        skip_bits(gb, 6);
+
+        if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5)
+            skip_bits(gb, 16);  // frame[01]_grid_position_[xy]
+        skip_bits(gb, 8);       // frame_packing_arrangement_reserved_byte
+        skip_bits1(gb);         // frame_packing_arrangement_persistance_flag
+    }
+    skip_bits1(gb);             // upsampled_aspect_ratio_flag
+}
+
+static int decode_nal_sei_message(HEVCContext *s)
+{
+    GetBitContext *gb = &s->HEVClc.gb;
+
+    int payload_type = 0;
+    int payload_size = 0;
+    int byte = 0xFF;
+    av_log(s->avctx, AV_LOG_DEBUG, "Decoding SEI\n");
+
+    while (byte == 0xFF) {
+        byte          = get_bits(gb, 8);
+        payload_type += byte;
+    }
+    byte = 0xFF;
+    while (byte == 0xFF) {
+        byte          = get_bits(gb, 8);
+        payload_size += byte;
+    }
+    if (s->nal_unit_type == NAL_SEI_PREFIX) {
+        if (payload_type == 256)
+            decode_nal_sei_decoded_picture_hash(s);
+        else if (payload_type == 45)
+            decode_nal_sei_frame_packing_arrangement(s);
+        else {
+            av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", payload_type);
+            skip_bits(gb, 8 * payload_size);
+        }
+    } else { /* nal_unit_type == NAL_SEI_SUFFIX */
+        if (payload_type == 132)
+            decode_nal_sei_decoded_picture_hash(s);
+        else {
+            av_log(s->avctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", payload_type);
+            skip_bits(gb, 8 * payload_size);
+        }
+    }
+    return 0;
+}
+
+static int more_rbsp_data(GetBitContext *gb)
+{
+    return get_bits_left(gb) > 0 && show_bits(gb, 8) != 0x80;
+}
+
+int ff_hevc_decode_nal_sei(HEVCContext *s)
+{
+    do {
+        decode_nal_sei_message(s);
+    } while (more_rbsp_data(&s->HEVClc.gb));
+    return 0;
+}
diff --git a/libavcodec/hevcdsp.c b/libavcodec/hevcdsp.c
new file mode 100644
index 0000000..70de843
--- /dev/null
+++ b/libavcodec/hevcdsp.c
@@ -0,0 +1,190 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * 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 "hevc.h"
+
+static const int8_t transform[32][32] = {
+    { 64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,
+      64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64 },
+    { 90,  90,  88,  85,  82,  78,  73,  67,  61,  54,  46,  38,  31,  22,  13,   4,
+      -4, -13, -22, -31, -38, -46, -54, -61, -67, -73, -78, -82, -85, -88, -90, -90 },
+    { 90,  87,  80,  70,  57,  43,  25,   9,  -9, -25, -43, -57, -70, -80, -87, -90,
+     -90, -87, -80, -70, -57, -43, -25,  -9,   9,  25,  43,  57,  70,  80,  87,  90 },
+    { 90,  82,  67,  46,  22,  -4, -31, -54, -73, -85, -90, -88, -78, -61, -38, -13,
+      13,  38,  61,  78,  88,  90,  85,  73,  54,  31,   4, -22, -46, -67, -82, -90 },
+    { 89,  75,  50,  18, -18, -50, -75, -89, -89, -75, -50, -18,  18,  50,  75,  89,
+      89,  75,  50,  18, -18, -50, -75, -89, -89, -75, -50, -18,  18,  50,  75,  89 },
+    { 88,  67,  31, -13, -54, -82, -90, -78, -46, -4,   38,  73,  90,  85,  61,  22,
+     -22, -61, -85, -90, -73, -38,   4,  46,  78,  90,  82,  54,  13, -31, -67, -88 },
+    { 87,  57,   9, -43, -80, -90, -70, -25,  25,  70,  90,  80,  43,  -9, -57, -87,
+     -87, -57,  -9,  43,  80,  90,  70,  25, -25, -70, -90, -80, -43,   9,  57,  87 },
+    { 85,  46, -13, -67, -90, -73, -22,  38,  82,  88,  54,  -4, -61, -90, -78, -31,
+      31,  78,  90,  61,   4, -54, -88, -82, -38,  22,  73,  90,  67,  13, -46, -85 },
+    { 83,  36, -36, -83, -83, -36,  36,  83,  83,  36, -36, -83, -83, -36,  36,  83,
+      83,  36, -36, -83, -83, -36,  36,  83,  83,  36, -36, -83, -83, -36,  36,  83 },
+    { 82,  22, -54, -90, -61,  13,  78,  85,  31, -46, -90, -67,   4,  73,  88,  38,
+     -38, -88, -73,  -4,  67,  90,  46, -31, -85, -78, -13,  61,  90,  54, -22, -82 },
+    { 80,   9, -70, -87, -25,  57,  90,  43, -43, -90, -57,  25,  87,  70,  -9, -80,
+     -80,  -9,  70,  87,  25, -57, -90, -43,  43,  90,  57, -25, -87, -70,   9,  80 },
+    { 78,  -4, -82, -73,  13,  85,  67, -22, -88, -61,  31,  90,  54, -38, -90, -46,
+      46,  90,  38, -54, -90, -31,  61,  88,  22, -67, -85, -13,  73,  82,   4, -78 },
+    { 75, -18, -89, -50,  50,  89,  18, -75, -75,  18,  89,  50, -50, -89, -18,  75,
+      75, -18, -89, -50,  50,  89,  18, -75, -75,  18,  89,  50, -50, -89, -18,  75 },
+    { 73, -31, -90, -22,  78,  67, -38, -90, -13,  82,  61, -46, -88,  -4,  85,  54,
+     -54, -85,   4,  88,  46, -61, -82,  13,  90,  38, -67, -78,  22,  90,  31, -73 },
+    { 70, -43, -87,   9,  90,  25, -80, -57,  57,  80, -25, -90,  -9,  87,  43, -70,
+     -70,  43,  87,  -9, -90, -25,  80,  57, -57, -80,  25,  90,   9, -87, -43,  70 },
+    { 67, -54, -78,  38,  85, -22, -90,   4,  90,  13, -88, -31,  82,  46, -73, -61,
+      61,  73, -46, -82,  31,  88, -13, -90,  -4,  90,  22, -85, -38,  78,  54, -67 },
+    { 64, -64, -64,  64,  64, -64, -64,  64,  64, -64, -64,  64,  64, -64, -64,  64,
+      64, -64, -64,  64,  64, -64, -64,  64,  64, -64, -64,  64,  64, -64, -64,  64 },
+    { 61, -73, -46,  82,  31, -88, -13,  90,  -4, -90,  22,  85, -38, -78,  54,  67,
+     -67, -54,  78,  38, -85, -22,  90,   4, -90,  13,  88, -31, -82,  46,  73, -61 },
+    { 57, -80, -25,  90,  -9, -87,  43,  70, -70, -43,  87,   9, -90,  25,  80, -57,
+     -57,  80,  25, -90,   9,  87, -43, -70,  70,  43, -87,  -9,  90, -25, -80,  57 },
+    { 54, -85,  -4,  88, -46, -61,  82,  13, -90,  38,  67, -78, -22,  90, -31, -73,
+      73,  31, -90,  22,  78, -67, -38,  90, -13, -82,  61,  46, -88,   4,  85, -54 },
+    { 50, -89,  18,  75, -75, -18,  89, -50, -50,  89, -18, -75,  75,  18, -89,  50,
+      50, -89,  18,  75, -75, -18,  89, -50, -50,  89, -18, -75,  75,  18, -89,  50 },
+    { 46, -90,  38,  54, -90,  31,  61, -88,  22,  67, -85,  13,  73, -82,   4,  78,
+     -78,  -4,  82, -73, -13,  85, -67, -22,  88, -61, -31,  90, -54, -38,  90, -46 },
+    { 43, -90,  57,  25, -87,  70,   9, -80,  80,  -9, -70,  87, -25, -57,  90, -43,
+     -43,  90, -57, -25,  87, -70,  -9,  80, -80,   9,  70, -87,  25,  57, -90,  43 },
+    { 38, -88,  73,  -4, -67,  90, -46, -31,  85, -78,  13,  61, -90,  54,  22, -82,
+      82, -22, -54,  90, -61, -13,  78, -85,  31,  46, -90,  67,   4, -73,  88, -38 },
+    { 36, -83,  83, -36, -36,  83, -83,  36,  36, -83,  83, -36, -36,  83, -83,  36,
+      36, -83,  83, -36, -36,  83, -83,  36,  36, -83,  83, -36, -36,  83, -83,  36 },
+    { 31, -78,  90, -61,   4,  54, -88,  82, -38, -22,  73, -90,  67, -13, -46,  85,
+     -85,  46,  13, -67,  90, -73,  22,  38, -82,  88, -54,  -4,  61, -90,  78, -31 },
+    { 25, -70,  90, -80,  43,   9, -57,  87, -87,  57,  -9, -43,  80, -90,  70, -25,
+     -25,  70, -90,  80, -43,  -9,  57, -87,  87, -57,   9,  43, -80,  90, -70,  25 },
+    { 22, -61,  85, -90,  73, -38,  -4,  46, -78,  90, -82,  54, -13, -31,  67, -88,
+      88, -67,  31,  13, -54,  82, -90,  78, -46,   4,  38, -73,  90, -85,  61, -22 },
+    { 18, -50,  75, -89,  89, -75,  50, -18, -18,  50, -75,  89, -89,  75, -50,  18,
+      18, -50,  75, -89,  89, -75,  50, -18, -18,  50, -75,  89, -89,  75, -50,  18 },
+    { 13, -38,  61, -78,  88, -90,  85, -73,  54, -31,   4,  22, -46,  67, -82,  90,
+     -90,  82, -67,  46, -22,  -4,  31, -54,  73, -85,  90, -88,  78, -61,  38, -13 },
+    {  9, -25,  43, -57,  70, -80,  87, -90,  90, -87,  80, -70,  57, -43,  25, -9,
+      -9,  25, -43,  57, -70,  80, -87,  90, -90,  87, -80,  70, -57,  43, -25,   9 },
+    {  4, -13,  22, -31,  38, -46,  54, -61,  67, -73,  78, -82,  85, -88,  90, -90,
+      90, -90,  88, -85,  82, -78,  73, -67,  61, -54,  46, -38,  31, -22,  13,  -4 },
+};
+
+DECLARE_ALIGNED(16, const int8_t, ff_hevc_epel_filters[7][16]) = {
+    { -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2 },
+    { -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2 },
+    { -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4 },
+    { -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4 },
+    { -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6 },
+    { -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4 },
+    { -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2 },
+};
+
+#define BIT_DEPTH 8
+#include "hevcdsp_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 9
+#include "hevcdsp_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 10
+#include "hevcdsp_template.c"
+#undef BIT_DEPTH
+
+void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth)
+{
+#undef FUNC
+#define FUNC(a, depth) a ## _ ## depth
+
+#define HEVC_DSP(depth)                                                     \
+    hevcdsp->put_pcm                = FUNC(put_pcm, depth);                 \
+    hevcdsp->transquant_bypass[0]   = FUNC(transquant_bypass4x4, depth);    \
+    hevcdsp->transquant_bypass[1]   = FUNC(transquant_bypass8x8, depth);    \
+    hevcdsp->transquant_bypass[2]   = FUNC(transquant_bypass16x16, depth);  \
+    hevcdsp->transquant_bypass[3]   = FUNC(transquant_bypass32x32, depth);  \
+    hevcdsp->transform_skip         = FUNC(transform_skip, depth);          \
+    hevcdsp->transform_4x4_luma_add = FUNC(transform_4x4_luma_add, depth);  \
+    hevcdsp->transform_add[0]       = FUNC(transform_4x4_add, depth);       \
+    hevcdsp->transform_add[1]       = FUNC(transform_8x8_add, depth);       \
+    hevcdsp->transform_add[2]       = FUNC(transform_16x16_add, depth);     \
+    hevcdsp->transform_add[3]       = FUNC(transform_32x32_add, depth);     \
+                                                                            \
+    hevcdsp->sao_band_filter[0] = FUNC(sao_band_filter_0, depth);           \
+    hevcdsp->sao_band_filter[1] = FUNC(sao_band_filter_1, depth);           \
+    hevcdsp->sao_band_filter[2] = FUNC(sao_band_filter_2, depth);           \
+    hevcdsp->sao_band_filter[3] = FUNC(sao_band_filter_3, depth);           \
+                                                                            \
+    hevcdsp->sao_edge_filter[0] = FUNC(sao_edge_filter_0, depth);           \
+    hevcdsp->sao_edge_filter[1] = FUNC(sao_edge_filter_1, depth);           \
+    hevcdsp->sao_edge_filter[2] = FUNC(sao_edge_filter_2, depth);           \
+    hevcdsp->sao_edge_filter[3] = FUNC(sao_edge_filter_3, depth);           \
+                                                                            \
+    hevcdsp->put_hevc_qpel[0][0] = FUNC(put_hevc_qpel_pixels, depth);       \
+    hevcdsp->put_hevc_qpel[0][1] = FUNC(put_hevc_qpel_h1, depth);           \
+    hevcdsp->put_hevc_qpel[0][2] = FUNC(put_hevc_qpel_h2, depth);           \
+    hevcdsp->put_hevc_qpel[0][3] = FUNC(put_hevc_qpel_h3, depth);           \
+    hevcdsp->put_hevc_qpel[1][0] = FUNC(put_hevc_qpel_v1, depth);           \
+    hevcdsp->put_hevc_qpel[1][1] = FUNC(put_hevc_qpel_h1v1, depth);         \
+    hevcdsp->put_hevc_qpel[1][2] = FUNC(put_hevc_qpel_h2v1, depth);         \
+    hevcdsp->put_hevc_qpel[1][3] = FUNC(put_hevc_qpel_h3v1, depth);         \
+    hevcdsp->put_hevc_qpel[2][0] = FUNC(put_hevc_qpel_v2, depth);           \
+    hevcdsp->put_hevc_qpel[2][1] = FUNC(put_hevc_qpel_h1v2, depth);         \
+    hevcdsp->put_hevc_qpel[2][2] = FUNC(put_hevc_qpel_h2v2, depth);         \
+    hevcdsp->put_hevc_qpel[2][3] = FUNC(put_hevc_qpel_h3v2, depth);         \
+    hevcdsp->put_hevc_qpel[3][0] = FUNC(put_hevc_qpel_v3, depth);           \
+    hevcdsp->put_hevc_qpel[3][1] = FUNC(put_hevc_qpel_h1v3, depth);         \
+    hevcdsp->put_hevc_qpel[3][2] = FUNC(put_hevc_qpel_h2v3, depth);         \
+    hevcdsp->put_hevc_qpel[3][3] = FUNC(put_hevc_qpel_h3v3, depth);         \
+                                                                            \
+    hevcdsp->put_hevc_epel[0][0] = FUNC(put_hevc_epel_pixels, depth);       \
+    hevcdsp->put_hevc_epel[0][1] = FUNC(put_hevc_epel_h, depth);            \
+    hevcdsp->put_hevc_epel[1][0] = FUNC(put_hevc_epel_v, depth);            \
+    hevcdsp->put_hevc_epel[1][1] = FUNC(put_hevc_epel_hv, depth);           \
+                                                                            \
+    hevcdsp->put_unweighted_pred   = FUNC(put_unweighted_pred, depth);      \
+    hevcdsp->put_weighted_pred_avg = FUNC(put_weighted_pred_avg, depth);    \
+                                                                            \
+    hevcdsp->weighted_pred         = FUNC(weighted_pred, depth);            \
+    hevcdsp->weighted_pred_avg     = FUNC(weighted_pred_avg, depth);        \
+                                                                            \
+    hevcdsp->hevc_h_loop_filter_luma     = FUNC(hevc_h_loop_filter_luma, depth);   \
+    hevcdsp->hevc_v_loop_filter_luma     = FUNC(hevc_v_loop_filter_luma, depth);   \
+    hevcdsp->hevc_h_loop_filter_chroma   = FUNC(hevc_h_loop_filter_chroma, depth); \
+    hevcdsp->hevc_v_loop_filter_chroma   = FUNC(hevc_v_loop_filter_chroma, depth); \
+    hevcdsp->hevc_h_loop_filter_luma_c   = FUNC(hevc_h_loop_filter_luma, depth);   \
+    hevcdsp->hevc_v_loop_filter_luma_c   = FUNC(hevc_v_loop_filter_luma, depth);   \
+    hevcdsp->hevc_h_loop_filter_chroma_c = FUNC(hevc_h_loop_filter_chroma, depth); \
+    hevcdsp->hevc_v_loop_filter_chroma_c = FUNC(hevc_v_loop_filter_chroma, depth);
+
+    switch (bit_depth) {
+    case 9:
+        HEVC_DSP(9);
+        break;
+    case 10:
+        HEVC_DSP(10);
+        break;
+    default:
+        HEVC_DSP(8);
+        break;
+    }
+}
diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c
new file mode 100644
index 0000000..027b77c
--- /dev/null
+++ b/libavcodec/hevcdsp_template.c
@@ -0,0 +1,1340 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * 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 "get_bits.h"
+#include "hevc.h"
+
+#include "bit_depth_template.c"
+
+static void FUNC(put_pcm)(uint8_t *_dst, ptrdiff_t stride, int size,
+                          GetBitContext *gb, int pcm_bit_depth)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+
+    stride /= sizeof(pixel);
+
+    for (y = 0; y < size; y++) {
+        for (x = 0; x < size; x++)
+            dst[x] = get_bits(gb, pcm_bit_depth) << (BIT_DEPTH - pcm_bit_depth);
+        dst += stride;
+    }
+}
+
+static void FUNC(transquant_bypass4x4)(uint8_t *_dst, int16_t *coeffs,
+                                       ptrdiff_t stride)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+
+    stride /= sizeof(pixel);
+
+    for (y = 0; y < 4; y++) {
+        for (x = 0; x < 4; x++) {
+            dst[x] += *coeffs;
+            coeffs++;
+        }
+        dst += stride;
+    }
+}
+
+static void FUNC(transquant_bypass8x8)(uint8_t *_dst, int16_t *coeffs,
+                                       ptrdiff_t stride)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+
+    stride /= sizeof(pixel);
+
+    for (y = 0; y < 8; y++) {
+        for (x = 0; x < 8; x++) {
+            dst[x] += *coeffs;
+            coeffs++;
+        }
+        dst += stride;
+    }
+}
+
+static void FUNC(transquant_bypass16x16)(uint8_t *_dst, int16_t *coeffs,
+                                         ptrdiff_t stride)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+
+    stride /= sizeof(pixel);
+
+    for (y = 0; y < 16; y++) {
+        for (x = 0; x < 16; x++) {
+            dst[x] += *coeffs;
+            coeffs++;
+        }
+        dst += stride;
+    }
+}
+
+static void FUNC(transquant_bypass32x32)(uint8_t *_dst, int16_t *coeffs,
+                                         ptrdiff_t stride)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+
+    stride /= sizeof(pixel);
+
+    for (y = 0; y < 32; y++) {
+        for (x = 0; x < 32; x++) {
+            dst[x] += *coeffs;
+            coeffs++;
+        }
+        dst += stride;
+    }
+}
+
+static void FUNC(transform_skip)(uint8_t *_dst, int16_t *coeffs,
+                                 ptrdiff_t stride)
+{
+    pixel *dst = (pixel *)_dst;
+    int shift  = 13 - BIT_DEPTH;
+#if BIT_DEPTH <= 13
+    int offset = 1 << (shift - 1);
+#else
+    int offset = 0;
+#endif
+    int x, y;
+
+    stride /= sizeof(pixel);
+
+    for (y = 0; y < 4 * 4; y += 4) {
+        for (x = 0; x < 4; x++)
+            dst[x] = av_clip_pixel(dst[x] + ((coeffs[y + x] + offset) >> shift));
+        dst += stride;
+    }
+}
+
+#define SET(dst, x)   (dst) = (x)
+#define SCALE(dst, x) (dst) = av_clip_int16(((x) + add) >> shift)
+#define ADD_AND_SCALE(dst, x)                                           \
+    (dst) = av_clip_pixel((dst) + av_clip_int16(((x) + add) >> shift))
+
+#define TR_4x4_LUMA(dst, src, step, assign)                             \
+    do {                                                                \
+        int c0 = src[0 * step] + src[2 * step];                         \
+        int c1 = src[2 * step] + src[3 * step];                         \
+        int c2 = src[0 * step] - src[3 * step];                         \
+        int c3 = 74 * src[1 * step];                                    \
+                                                                        \
+        assign(dst[2 * step], 74 * (src[0 * step] -                     \
+                                    src[2 * step] +                     \
+                                    src[3 * step]));                    \
+        assign(dst[0 * step], 29 * c0 + 55 * c1 + c3);                  \
+        assign(dst[1 * step], 55 * c2 - 29 * c1 + c3);                  \
+        assign(dst[3 * step], 55 * c0 + 29 * c2 - c3);                  \
+    } while (0)
+
+static void FUNC(transform_4x4_luma_add)(uint8_t *_dst, int16_t *coeffs,
+                                         ptrdiff_t stride)
+{
+    int i;
+    pixel *dst   = (pixel *)_dst;
+    int shift    = 7;
+    int add      = 1 << (shift - 1);
+    int16_t *src = coeffs;
+
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 4; i++) {
+        TR_4x4_LUMA(src, src, 4, SCALE);
+        src++;
+    }
+
+    shift = 20 - BIT_DEPTH;
+    add   = 1 << (shift - 1);
+    for (i = 0; i < 4; i++) {
+        TR_4x4_LUMA(dst, coeffs, 1, ADD_AND_SCALE);
+        coeffs += 4;
+        dst    += stride;
+    }
+}
+
+#undef TR_4x4_LUMA
+
+#define TR_4(dst, src, dstep, sstep, assign)                            \
+    do {                                                                \
+        const int e0 = transform[8 * 0][0] * src[0 * sstep] +           \
+                       transform[8 * 2][0] * src[2 * sstep];            \
+        const int e1 = transform[8 * 0][1] * src[0 * sstep] +           \
+                       transform[8 * 2][1] * src[2 * sstep];            \
+        const int o0 = transform[8 * 1][0] * src[1 * sstep] +           \
+                       transform[8 * 3][0] * src[3 * sstep];            \
+        const int o1 = transform[8 * 1][1] * src[1 * sstep] +           \
+                       transform[8 * 3][1] * src[3 * sstep];            \
+                                                                        \
+        assign(dst[0 * dstep], e0 + o0);                                \
+        assign(dst[1 * dstep], e1 + o1);                                \
+        assign(dst[2 * dstep], e1 - o1);                                \
+        assign(dst[3 * dstep], e0 - o0);                                \
+    } while (0)
+
+static void FUNC(transform_4x4_add)(uint8_t *_dst, int16_t *coeffs,
+                                    ptrdiff_t stride)
+{
+    int i;
+    pixel *dst   = (pixel *)_dst;
+    int shift    = 7;
+    int add      = 1 << (shift - 1);
+    int16_t *src = coeffs;
+
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 4; i++) {
+        TR_4(src, src, 4, 4, SCALE);
+        src++;
+    }
+
+    shift = 20 - BIT_DEPTH;
+    add   = 1 << (shift - 1);
+    for (i = 0; i < 4; i++) {
+        TR_4(dst, coeffs, 1, 1, ADD_AND_SCALE);
+        coeffs += 4;
+        dst    += stride;
+    }
+}
+
+#define TR_8(dst, src, dstep, sstep, assign)                      \
+    do {                                                          \
+        int i, j;                                                 \
+        int e_8[4];                                               \
+        int o_8[4] = { 0 };                                       \
+        for (i = 0; i < 4; i++)                                   \
+            for (j = 1; j < 8; j += 2)                            \
+                o_8[i] += transform[4 * j][i] * src[j * sstep];   \
+        TR_4(e_8, src, 1, 2 * sstep, SET);                        \
+                                                                  \
+        for (i = 0; i < 4; i++) {                                 \
+            assign(dst[i * dstep], e_8[i] + o_8[i]);              \
+            assign(dst[(7 - i) * dstep], e_8[i] - o_8[i]);        \
+        }                                                         \
+    } while (0)
+
+#define TR_16(dst, src, dstep, sstep, assign)                     \
+    do {                                                          \
+        int i, j;                                                 \
+        int e_16[8];                                              \
+        int o_16[8] = { 0 };                                      \
+        for (i = 0; i < 8; i++)                                   \
+            for (j = 1; j < 16; j += 2)                           \
+                o_16[i] += transform[2 * j][i] * src[j * sstep];  \
+        TR_8(e_16, src, 1, 2 * sstep, SET);                       \
+                                                                  \
+        for (i = 0; i < 8; i++) {                                 \
+            assign(dst[i * dstep], e_16[i] + o_16[i]);            \
+            assign(dst[(15 - i) * dstep], e_16[i] - o_16[i]);     \
+        }                                                         \
+    } while (0)
+
+#define TR_32(dst, src, dstep, sstep, assign)                     \
+    do {                                                          \
+        int i, j;                                                 \
+        int e_32[16];                                             \
+        int o_32[16] = { 0 };                                     \
+        for (i = 0; i < 16; i++)                                  \
+            for (j = 1; j < 32; j += 2)                           \
+                o_32[i] += transform[j][i] * src[j * sstep];      \
+        TR_16(e_32, src, 1, 2 * sstep, SET);                      \
+                                                                  \
+        for (i = 0; i < 16; i++) {                                \
+            assign(dst[i * dstep], e_32[i] + o_32[i]);            \
+            assign(dst[(31 - i) * dstep], e_32[i] - o_32[i]);     \
+        }                                                         \
+    } while (0)
+
+
+
+static void FUNC(transform_8x8_add)(uint8_t *_dst, int16_t *coeffs,
+                                    ptrdiff_t stride)
+{
+    int i;
+    pixel *dst   = (pixel *)_dst;
+    int shift    = 7;
+    int add      = 1 << (shift - 1);
+    int16_t *src = coeffs;
+
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 8; i++) {
+        TR_8(src, src, 8, 8, SCALE);
+        src++;
+    }
+
+    shift = 20 - BIT_DEPTH;
+    add   = 1 << (shift - 1);
+    for (i = 0; i < 8; i++) {
+        TR_8(dst, coeffs, 1, 1, ADD_AND_SCALE);
+        coeffs += 8;
+        dst    += stride;
+    }
+}
+
+static void FUNC(transform_16x16_add)(uint8_t *_dst, int16_t *coeffs,
+                                      ptrdiff_t stride)
+{
+    int i;
+    pixel *dst   = (pixel *)_dst;
+    int shift    = 7;
+    int add      = 1 << (shift - 1);
+    int16_t *src = coeffs;
+
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 16; i++) {
+        TR_16(src, src, 16, 16, SCALE);
+        src++;
+    }
+
+    shift = 20 - BIT_DEPTH;
+    add   = 1 << (shift - 1);
+    for (i = 0; i < 16; i++) {
+        TR_16(dst, coeffs, 1, 1, ADD_AND_SCALE);
+        coeffs += 16;
+        dst    += stride;
+    }
+}
+
+static void FUNC(transform_32x32_add)(uint8_t *_dst, int16_t *coeffs,
+                                      ptrdiff_t stride)
+{
+    int i;
+    pixel *dst   = (pixel *)_dst;
+    int shift    = 7;
+    int add      = 1 << (shift - 1);
+    int16_t *src = coeffs;
+
+    stride /= sizeof(pixel);
+
+    for (i = 0; i < 32; i++) {
+        TR_32(src, src, 32, 32, SCALE);
+        src++;
+    }
+    src   = coeffs;
+    shift = 20 - BIT_DEPTH;
+    add   = 1 << (shift - 1);
+    for (i = 0; i < 32; i++) {
+        TR_32(dst, coeffs, 1, 1, ADD_AND_SCALE);
+        coeffs += 32;
+        dst    += stride;
+    }
+}
+
+static void FUNC(sao_band_filter)(uint8_t *_dst, uint8_t *_src,
+                                  ptrdiff_t stride, SAOParams *sao,
+                                  int *borders, int width, int height,
+                                  int c_idx, int class)
+{
+    pixel *dst = (pixel *)_dst;
+    pixel *src = (pixel *)_src;
+    int offset_table[32] = { 0 };
+    int k, y, x;
+    int chroma = !!c_idx;
+    int shift  = BIT_DEPTH - 5;
+    int *sao_offset_val = sao->offset_val[c_idx];
+    int sao_left_class  = sao->band_position[c_idx];
+    int init_y = 0, init_x = 0;
+
+    stride /= sizeof(pixel);
+
+    switch (class) {
+    case 0:
+        if (!borders[2])
+            width -= (8 >> chroma) + 2;
+        if (!borders[3])
+            height -= (4 >> chroma) + 2;
+        break;
+    case 1:
+        init_y = -(4 >> chroma) - 2;
+        if (!borders[2])
+            width -= (8 >> chroma) + 2;
+        height = (4 >> chroma) + 2;
+        break;
+    case 2:
+        init_x = -(8 >> chroma) - 2;
+        width  =  (8 >> chroma) + 2;
+        if (!borders[3])
+            height -= (4 >> chroma) + 2;
+        break;
+    case 3:
+        init_y = -(4 >> chroma) - 2;
+        init_x = -(8 >> chroma) - 2;
+        width  =  (8 >> chroma) + 2;
+        height =  (4 >> chroma) + 2;
+        break;
+    }
+
+    dst = dst + (init_y * stride + init_x);
+    src = src + (init_y * stride + init_x);
+    for (k = 0; k < 4; k++)
+        offset_table[(k + sao_left_class) & 31] = sao_offset_val[k + 1];
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = av_clip_pixel(src[x] + offset_table[av_clip_pixel(src[x] >> shift)]);
+        dst += stride;
+        src += stride;
+    }
+}
+
+static void FUNC(sao_band_filter_0)(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride, SAOParams *sao,
+                                    int *borders, int width, int height,
+                                    int c_idx)
+{
+    FUNC(sao_band_filter)(dst, src, stride, sao, borders,
+                          width, height, c_idx, 0);
+}
+
+static void FUNC(sao_band_filter_1)(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride, SAOParams *sao,
+                                    int *borders, int width, int height,
+                                    int c_idx)
+{
+    FUNC(sao_band_filter)(dst, src, stride, sao, borders,
+                          width, height, c_idx, 1);
+}
+
+static void FUNC(sao_band_filter_2)(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride, SAOParams *sao,
+                                    int *borders, int width, int height,
+                                    int c_idx)
+{
+    FUNC(sao_band_filter)(dst, src, stride, sao, borders,
+                          width, height, c_idx, 2);
+}
+
+static void FUNC(sao_band_filter_3)(uint8_t *_dst, uint8_t *_src,
+                                    ptrdiff_t stride, SAOParams *sao,
+                                    int *borders, int width, int height,
+                                    int c_idx)
+{
+    FUNC(sao_band_filter)(_dst, _src, stride, sao, borders,
+                          width, height, c_idx, 3);
+}
+
+static void FUNC(sao_edge_filter_0)(uint8_t *_dst, uint8_t *_src,
+                                    ptrdiff_t stride, SAOParams *sao,
+                                    int *borders, int _width, int _height,
+                                    int c_idx, uint8_t vert_edge,
+                                    uint8_t horiz_edge, uint8_t diag_edge)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+    pixel *src = (pixel *)_src;
+    int chroma = !!c_idx;
+    int *sao_offset_val = sao->offset_val[c_idx];
+    int sao_eo_class    = sao->eo_class[c_idx];
+    int init_x = 0, init_y = 0, width = _width, height = _height;
+
+    static const int8_t pos[4][2][2] = {
+        { { -1,  0 }, {  1, 0 } }, // horizontal
+        { {  0, -1 }, {  0, 1 } }, // vertical
+        { { -1, -1 }, {  1, 1 } }, // 45 degree
+        { {  1, -1 }, { -1, 1 } }, // 135 degree
+    };
+    static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
+
+#define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
+
+    stride /= sizeof(pixel);
+
+    if (!borders[2])
+        width -= (8 >> chroma) + 2;
+    if (!borders[3])
+        height -= (4 >> chroma) + 2;
+
+    dst = dst + (init_y * stride + init_x);
+    src = src + (init_y * stride + init_x);
+    init_y = init_x = 0;
+    if (sao_eo_class != SAO_EO_VERT) {
+        if (borders[0]) {
+            int offset_val = sao_offset_val[0];
+            int y_stride   = 0;
+            for (y = 0; y < height; y++) {
+                dst[y_stride] = av_clip_pixel(src[y_stride] + offset_val);
+                y_stride     += stride;
+            }
+            init_x = 1;
+        }
+        if (borders[2]) {
+            int offset_val = sao_offset_val[0];
+            int x_stride   = width - 1;
+            for (x = 0; x < height; x++) {
+                dst[x_stride] = av_clip_pixel(src[x_stride] + offset_val);
+                x_stride     += stride;
+            }
+            width--;
+        }
+    }
+    if (sao_eo_class != SAO_EO_HORIZ) {
+        if (borders[1]) {
+            int offset_val = sao_offset_val[0];
+            for (x = init_x; x < width; x++)
+                dst[x] = av_clip_pixel(src[x] + offset_val);
+            init_y = 1;
+        }
+        if (borders[3]) {
+            int offset_val = sao_offset_val[0];
+            int y_stride   = stride * (height - 1);
+            for (x = init_x; x < width; x++)
+                dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + offset_val);
+            height--;
+        }
+    }
+    {
+        int y_stride = init_y * stride;
+        int pos_0_0  = pos[sao_eo_class][0][0];
+        int pos_0_1  = pos[sao_eo_class][0][1];
+        int pos_1_0  = pos[sao_eo_class][1][0];
+        int pos_1_1  = pos[sao_eo_class][1][1];
+
+        int y_stride_0_1 = (init_y + pos_0_1) * stride;
+        int y_stride_1_1 = (init_y + pos_1_1) * stride;
+        for (y = init_y; y < height; y++) {
+            for (x = init_x; x < width; x++) {
+                int diff0         = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]);
+                int diff1         = CMP(src[x + y_stride], src[x + pos_1_0 + y_stride_1_1]);
+                int offset_val    = edge_idx[2 + diff0 + diff1];
+                dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + sao_offset_val[offset_val]);
+            }
+            y_stride     += stride;
+            y_stride_0_1 += stride;
+            y_stride_1_1 += stride;
+        }
+    }
+
+    {
+        // Restore pixels that can't be modified
+        int save_upper_left = !diag_edge && sao_eo_class == SAO_EO_135D && !borders[0] && !borders[1];
+        if (vert_edge && sao_eo_class != SAO_EO_VERT)
+            for (y = init_y+save_upper_left; y< height; y++)
+                dst[y*stride] = src[y*stride];
+        if(horiz_edge && sao_eo_class != SAO_EO_HORIZ)
+            for(x = init_x+save_upper_left; x<width; x++)
+                dst[x] = src[x];
+        if(diag_edge && sao_eo_class == SAO_EO_135D)
+            dst[0] = src[0];
+    }
+
+#undef CMP
+}
+
+static void FUNC(sao_edge_filter_1)(uint8_t *_dst, uint8_t *_src,
+                                    ptrdiff_t stride, SAOParams *sao,
+                                    int *borders, int _width, int _height,
+                                    int c_idx, uint8_t vert_edge,
+                                    uint8_t horiz_edge, uint8_t diag_edge)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+    pixel *src = (pixel *)_src;
+    int chroma = !!c_idx;
+    int *sao_offset_val = sao->offset_val[c_idx];
+    int sao_eo_class    = sao->eo_class[c_idx];
+    int init_x = 0, init_y = 0, width = _width, height = _height;
+
+    static const int8_t pos[4][2][2] = {
+        { { -1, 0  }, { 1,  0 } }, // horizontal
+        { { 0,  -1 }, { 0,  1 } }, // vertical
+        { { -1, -1 }, { 1,  1 } }, // 45 degree
+        { { 1,  -1 }, { -1, 1 } }, // 135 degree
+    };
+    static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
+
+#define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
+
+    stride /= sizeof(pixel);
+
+    init_y = -(4 >> chroma) - 2;
+    if (!borders[2])
+        width -= (8 >> chroma) + 2;
+    height = (4 >> chroma) + 2;
+
+    dst = dst + (init_y * stride + init_x);
+    src = src + (init_y * stride + init_x);
+    init_y = init_x = 0;
+    if (sao_eo_class != SAO_EO_VERT) {
+        if (borders[0]) {
+            int offset_val = sao_offset_val[0];
+            int y_stride   = 0;
+            for (y = 0; y < height; y++) {
+                dst[y_stride] = av_clip_pixel(src[y_stride] + offset_val);
+                y_stride     += stride;
+            }
+            init_x = 1;
+        }
+        if (borders[2]) {
+            int offset_val = sao_offset_val[0];
+            int x_stride   = width - 1;
+            for (x = 0; x < height; x++) {
+                dst[x_stride] = av_clip_pixel(src[x_stride] + offset_val);
+                x_stride     += stride;
+            }
+            width--;
+        }
+    }
+    {
+        int y_stride = init_y * stride;
+        int pos_0_0  = pos[sao_eo_class][0][0];
+        int pos_0_1  = pos[sao_eo_class][0][1];
+        int pos_1_0  = pos[sao_eo_class][1][0];
+        int pos_1_1  = pos[sao_eo_class][1][1];
+
+        int y_stride_0_1 = (init_y + pos_0_1) * stride;
+        int y_stride_1_1 = (init_y + pos_1_1) * stride;
+        for (y = init_y; y < height; y++) {
+            for (x = init_x; x < width; x++) {
+                int diff0         = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]);
+                int diff1         = CMP(src[x + y_stride], src[x + pos_1_0 + y_stride_1_1]);
+                int offset_val    = edge_idx[2 + diff0 + diff1];
+                dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + sao_offset_val[offset_val]);
+            }
+            y_stride     += stride;
+            y_stride_0_1 += stride;
+            y_stride_1_1 += stride;
+        }
+    }
+
+    {
+        // Restore pixels that can't be modified
+        int save_lower_left = !diag_edge && sao_eo_class == SAO_EO_45D && !borders[0];
+        if(vert_edge && sao_eo_class != SAO_EO_VERT)
+            for(y = init_y; y< height-save_lower_left; y++)
+                dst[y*stride] = src[y*stride];
+        if(horiz_edge && sao_eo_class != SAO_EO_HORIZ)
+            for(x = init_x+save_lower_left; x<width; x++)
+                dst[(height-1)*stride+x] = src[(height-1)*stride+x];
+        if(diag_edge && sao_eo_class == SAO_EO_45D)
+            dst[stride*(height-1)] = src[stride*(height-1)];
+    }
+
+#undef CMP
+}
+
+static void FUNC(sao_edge_filter_2)(uint8_t *_dst, uint8_t *_src,
+                                    ptrdiff_t stride, SAOParams *sao,
+                                    int *borders, int _width, int _height,
+                                    int c_idx, uint8_t vert_edge,
+                                    uint8_t horiz_edge, uint8_t diag_edge)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+    pixel *src = (pixel *)_src;
+    int chroma = !!c_idx;
+    int *sao_offset_val = sao->offset_val[c_idx];
+    int sao_eo_class    = sao->eo_class[c_idx];
+    int init_x = 0, init_y = 0, width = _width, height = _height;
+
+    static const int8_t pos[4][2][2] = {
+        { { -1,  0 }, {  1, 0 } }, // horizontal
+        { {  0, -1 }, {  0, 1 } }, // vertical
+        { { -1, -1 }, {  1, 1 } }, // 45 degree
+        { {  1, -1 }, { -1, 1 } }, // 135 degree
+    };
+    static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
+
+#define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
+
+    stride /= sizeof(pixel);
+
+    init_x = -(8 >> chroma) - 2;
+    width  =  (8 >> chroma) + 2;
+    if (!borders[3])
+        height -= (4 >> chroma) + 2;
+
+    dst = dst + (init_y * stride + init_x);
+    src = src + (init_y * stride + init_x);
+    init_y = init_x = 0;
+    if (sao_eo_class != SAO_EO_HORIZ) {
+        if (borders[1]) {
+            int offset_val = sao_offset_val[0];
+            for (x = init_x; x < width; x++)
+                dst[x] = av_clip_pixel(src[x] + offset_val);
+            init_y = 1;
+        }
+        if (borders[3]) {
+            int offset_val = sao_offset_val[0];
+            int y_stride   = stride * (height - 1);
+            for (x = init_x; x < width; x++)
+                dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + offset_val);
+            height--;
+        }
+    }
+    {
+        int y_stride = init_y * stride;
+        int pos_0_0  = pos[sao_eo_class][0][0];
+        int pos_0_1  = pos[sao_eo_class][0][1];
+        int pos_1_0  = pos[sao_eo_class][1][0];
+        int pos_1_1  = pos[sao_eo_class][1][1];
+
+        int y_stride_0_1 = (init_y + pos_0_1) * stride;
+        int y_stride_1_1 = (init_y + pos_1_1) * stride;
+        for (y = init_y; y < height; y++) {
+            for (x = init_x; x < width; x++) {
+                int diff0         = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]);
+                int diff1         = CMP(src[x + y_stride], src[x + pos_1_0 + y_stride_1_1]);
+                int offset_val    = edge_idx[2 + diff0 + diff1];
+                dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + sao_offset_val[offset_val]);
+            }
+            y_stride     += stride;
+            y_stride_0_1 += stride;
+            y_stride_1_1 += stride;
+        }
+    }
+
+    {
+        // Restore pixels that can't be modified
+        int save_upper_right = !diag_edge && sao_eo_class == SAO_EO_45D && !borders[1];
+        if(vert_edge && sao_eo_class != SAO_EO_VERT)
+            for(y = init_y+save_upper_right; y< height; y++)
+                dst[y*stride+width-1] = src[y*stride+width-1];
+        if(horiz_edge && sao_eo_class != SAO_EO_HORIZ)
+            for(x = init_x; x<width-save_upper_right; x++)
+                dst[x] = src[x];
+        if(diag_edge && sao_eo_class == SAO_EO_45D)
+            dst[width-1] = src[width-1];
+    }
+#undef CMP
+}
+
+static void FUNC(sao_edge_filter_3)(uint8_t *_dst, uint8_t *_src,
+                                    ptrdiff_t stride, SAOParams *sao,
+                                    int *borders, int _width, int _height,
+                                    int c_idx, uint8_t vert_edge,
+                                    uint8_t horiz_edge, uint8_t diag_edge)
+{
+    int x, y;
+    pixel *dst = (pixel *)_dst;
+    pixel *src = (pixel *)_src;
+    int chroma = !!c_idx;
+    int *sao_offset_val = sao->offset_val[c_idx];
+    int sao_eo_class    = sao->eo_class[c_idx];
+    int init_x = 0, init_y = 0, width = _width, height = _height;
+
+    static const int8_t pos[4][2][2] = {
+        { { -1,  0 }, {  1, 0 } }, // horizontal
+        { {  0, -1 }, {  0, 1 } }, // vertical
+        { { -1, -1 }, {  1, 1 } }, // 45 degree
+        { {  1, -1 }, { -1, 1 } }, // 135 degree
+    };
+    static const uint8_t edge_idx[] = { 1, 2, 0, 3, 4 };
+
+#define CMP(a, b) ((a) > (b) ? 1 : ((a) == (b) ? 0 : -1))
+
+    stride /= sizeof(pixel);
+
+    init_y = -(4 >> chroma) - 2;
+    init_x = -(8 >> chroma) - 2;
+    width  =  (8 >> chroma) + 2;
+    height =  (4 >> chroma) + 2;
+
+
+    dst    = dst + (init_y * stride + init_x);
+    src    = src + (init_y * stride + init_x);
+    init_y = init_x = 0;
+
+    {
+        int y_stride = init_y * stride;
+        int pos_0_0  = pos[sao_eo_class][0][0];
+        int pos_0_1  = pos[sao_eo_class][0][1];
+        int pos_1_0  = pos[sao_eo_class][1][0];
+        int pos_1_1  = pos[sao_eo_class][1][1];
+
+        int y_stride_0_1 = (init_y + pos_0_1) * stride;
+        int y_stride_1_1 = (init_y + pos_1_1) * stride;
+
+        for (y = init_y; y < height; y++) {
+            for (x = init_x; x < width; x++) {
+                int diff0         = CMP(src[x + y_stride], src[x + pos_0_0 + y_stride_0_1]);
+                int diff1         = CMP(src[x + y_stride], src[x + pos_1_0 + y_stride_1_1]);
+                int offset_val    = edge_idx[2 + diff0 + diff1];
+                dst[x + y_stride] = av_clip_pixel(src[x + y_stride] + sao_offset_val[offset_val]);
+            }
+            y_stride     += stride;
+            y_stride_0_1 += stride;
+            y_stride_1_1 += stride;
+        }
+    }
+
+    {
+        // Restore pixels that can't be modified
+        int save_lower_right = !diag_edge && sao_eo_class == SAO_EO_135D;
+        if(vert_edge && sao_eo_class != SAO_EO_VERT)
+            for(y = init_y; y< height-save_lower_right; y++)
+                dst[y*stride+width-1] = src[y*stride+width-1];
+        if(horiz_edge && sao_eo_class != SAO_EO_HORIZ)
+            for(x = init_x; x<width-save_lower_right; x++)
+                dst[(height-1)*stride+x] = src[(height-1)*stride+x];
+        if(diag_edge && sao_eo_class == SAO_EO_135D)
+            dst[stride*(height-1)+width-1] = src[stride*(height-1)+width-1];
+    }
+#undef CMP
+}
+
+#undef SET
+#undef SCALE
+#undef ADD_AND_SCALE
+#undef TR_4
+#undef TR_8
+#undef TR_16
+#undef TR_32
+
+static void FUNC(put_hevc_qpel_pixels)(int16_t *dst, ptrdiff_t dststride,
+                                       uint8_t *_src, ptrdiff_t _srcstride,
+                                       int width, int height, int16_t* mcbuffer)
+{
+    int x, y;
+    pixel *src          = (pixel *)_src;
+    ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = src[x] << (14 - BIT_DEPTH);
+        src += srcstride;
+        dst += dststride;
+    }
+}
+
+#define QPEL_FILTER_1(src, stride)      \
+    (1 * -src[x - 3 * stride] +         \
+     4 *  src[x - 2 * stride] -         \
+    10 *  src[x -     stride] +         \
+    58 *  src[x]              +         \
+    17 *  src[x +     stride] -         \
+     5 *  src[x + 2 * stride] +         \
+     1 *  src[x + 3 * stride])
+
+#define QPEL_FILTER_2(src, stride)      \
+    (1  * -src[x - 3 * stride] +        \
+     4  *  src[x - 2 * stride] -        \
+    11  *  src[x -     stride] +        \
+    40  *  src[x]              +        \
+    40  *  src[x +     stride] -        \
+    11  *  src[x + 2 * stride] +        \
+     4  *  src[x + 3 * stride] -        \
+     1  *  src[x + 4 * stride])
+
+#define QPEL_FILTER_3(src, stride)      \
+    (1  * src[x - 2 * stride] -         \
+     5  * src[x -     stride] +         \
+    17  * src[x]              +         \
+    58  * src[x + stride]     -         \
+    10  * src[x + 2 * stride] +         \
+     4  * src[x + 3 * stride] -         \
+     1  * src[x + 4 * stride])
+
+
+#define PUT_HEVC_QPEL_H(H)                                                     \
+static void FUNC(put_hevc_qpel_h ## H)(int16_t *dst,  ptrdiff_t dststride,     \
+                                       uint8_t *_src, ptrdiff_t _srcstride,    \
+                                       int width, int height,                  \
+                                       int16_t* mcbuffer)                      \
+{                                                                              \
+    int x, y;                                                                  \
+    pixel *src = (pixel*)_src;                                                 \
+    ptrdiff_t srcstride = _srcstride / sizeof(pixel);                          \
+                                                                               \
+    for (y = 0; y < height; y++) {                                             \
+        for (x = 0; x < width; x++)                                            \
+            dst[x] = QPEL_FILTER_ ## H(src, 1) >> (BIT_DEPTH - 8);             \
+        src += srcstride;                                                      \
+        dst += dststride;                                                      \
+    }                                                                          \
+}
+
+#define PUT_HEVC_QPEL_V(V)                                                     \
+static void FUNC(put_hevc_qpel_v ## V)(int16_t *dst,  ptrdiff_t dststride,     \
+                                       uint8_t *_src, ptrdiff_t _srcstride,    \
+                                       int width, int height,                  \
+                                       int16_t* mcbuffer)                      \
+{                                                                              \
+    int x, y;                                                                  \
+    pixel *src = (pixel*)_src;                                                 \
+    ptrdiff_t srcstride = _srcstride / sizeof(pixel);                          \
+                                                                               \
+    for (y = 0; y < height; y++)  {                                            \
+        for (x = 0; x < width; x++)                                            \
+            dst[x] = QPEL_FILTER_ ## V(src, srcstride) >> (BIT_DEPTH - 8);     \
+        src += srcstride;                                                      \
+        dst += dststride;                                                      \
+    }                                                                          \
+}
+
+#define PUT_HEVC_QPEL_HV(H, V)                                                 \
+static void FUNC(put_hevc_qpel_h ## H ## v ## V)(int16_t *dst,                 \
+                                                 ptrdiff_t dststride,          \
+                                                 uint8_t *_src,                \
+                                                 ptrdiff_t _srcstride,         \
+                                                 int width, int height,        \
+                                                 int16_t* mcbuffer)            \
+{                                                                              \
+    int x, y;                                                                  \
+    pixel *src = (pixel*)_src;                                                 \
+    ptrdiff_t srcstride = _srcstride / sizeof(pixel);                          \
+                                                                               \
+    int16_t tmp_array[(MAX_PB_SIZE + 7) * MAX_PB_SIZE];                        \
+    int16_t *tmp = tmp_array;                                                  \
+                                                                               \
+    src -= ff_hevc_qpel_extra_before[V] * srcstride;                           \
+                                                                               \
+    for (y = 0; y < height + ff_hevc_qpel_extra[V]; y++) {                     \
+        for (x = 0; x < width; x++)                                            \
+            tmp[x] = QPEL_FILTER_ ## H(src, 1) >> (BIT_DEPTH - 8);             \
+        src += srcstride;                                                      \
+        tmp += MAX_PB_SIZE;                                                    \
+    }                                                                          \
+                                                                               \
+    tmp = tmp_array + ff_hevc_qpel_extra_before[V] * MAX_PB_SIZE;              \
+                                                                               \
+    for (y = 0; y < height; y++) {                                             \
+        for (x = 0; x < width; x++)                                            \
+            dst[x] = QPEL_FILTER_ ## V(tmp, MAX_PB_SIZE) >> 6;                 \
+        tmp += MAX_PB_SIZE;                                                    \
+        dst += dststride;                                                      \
+    }                                                                          \
+}
+
+PUT_HEVC_QPEL_H(1)
+PUT_HEVC_QPEL_H(2)
+PUT_HEVC_QPEL_H(3)
+PUT_HEVC_QPEL_V(1)
+PUT_HEVC_QPEL_V(2)
+PUT_HEVC_QPEL_V(3)
+PUT_HEVC_QPEL_HV(1, 1)
+PUT_HEVC_QPEL_HV(1, 2)
+PUT_HEVC_QPEL_HV(1, 3)
+PUT_HEVC_QPEL_HV(2, 1)
+PUT_HEVC_QPEL_HV(2, 2)
+PUT_HEVC_QPEL_HV(2, 3)
+PUT_HEVC_QPEL_HV(3, 1)
+PUT_HEVC_QPEL_HV(3, 2)
+PUT_HEVC_QPEL_HV(3, 3)
+
+static void FUNC(put_hevc_epel_pixels)(int16_t *dst, ptrdiff_t dststride,
+                                       uint8_t *_src, ptrdiff_t _srcstride,
+                                       int width, int height, int mx, int my,
+                                       int16_t* mcbuffer)
+{
+    int x, y;
+    pixel *src          = (pixel *)_src;
+    ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = src[x] << (14 - BIT_DEPTH);
+        src += srcstride;
+        dst += dststride;
+    }
+}
+
+#define EPEL_FILTER(src, stride)                \
+    (filter_0 * src[x - stride] +               \
+     filter_1 * src[x]          +               \
+     filter_2 * src[x + stride] +               \
+     filter_3 * src[x + 2 * stride])
+
+static void FUNC(put_hevc_epel_h)(int16_t *dst, ptrdiff_t dststride,
+                                  uint8_t *_src, ptrdiff_t _srcstride,
+                                  int width, int height, int mx, int my,
+                                  int16_t* mcbuffer)
+{
+    int x, y;
+    pixel *src = (pixel *)_src;
+    ptrdiff_t srcstride  = _srcstride / sizeof(pixel);
+    const int8_t *filter = ff_hevc_epel_filters[mx - 1];
+    int8_t filter_0 = filter[0];
+    int8_t filter_1 = filter[1];
+    int8_t filter_2 = filter[2];
+    int8_t filter_3 = filter[3];
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
+        src += srcstride;
+        dst += dststride;
+    }
+}
+
+static void FUNC(put_hevc_epel_v)(int16_t *dst, ptrdiff_t dststride,
+                                  uint8_t *_src, ptrdiff_t _srcstride,
+                                  int width, int height, int mx, int my,
+                                  int16_t* mcbuffer)
+{
+    int x, y;
+    pixel *src = (pixel *)_src;
+    ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+    const int8_t *filter = ff_hevc_epel_filters[my - 1];
+    int8_t filter_0 = filter[0];
+    int8_t filter_1 = filter[1];
+    int8_t filter_2 = filter[2];
+    int8_t filter_3 = filter[3];
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = EPEL_FILTER(src, srcstride) >> (BIT_DEPTH - 8);
+        src += srcstride;
+        dst += dststride;
+    }
+}
+
+static void FUNC(put_hevc_epel_hv)(int16_t *dst, ptrdiff_t dststride,
+                                   uint8_t *_src, ptrdiff_t _srcstride,
+                                   int width, int height, int mx, int my,
+                                   int16_t* mcbuffer)
+{
+    int x, y;
+    pixel *src = (pixel *)_src;
+    ptrdiff_t srcstride = _srcstride / sizeof(pixel);
+    const int8_t *filter_h = ff_hevc_epel_filters[mx - 1];
+    const int8_t *filter_v = ff_hevc_epel_filters[my - 1];
+    int8_t filter_0 = filter_h[0];
+    int8_t filter_1 = filter_h[1];
+    int8_t filter_2 = filter_h[2];
+    int8_t filter_3 = filter_h[3];
+    int16_t tmp_array[(MAX_PB_SIZE + 3) * MAX_PB_SIZE];
+    int16_t *tmp = tmp_array;
+
+    src -= EPEL_EXTRA_BEFORE * srcstride;
+
+    for (y = 0; y < height + EPEL_EXTRA; y++) {
+        for (x = 0; x < width; x++)
+            tmp[x] = EPEL_FILTER(src, 1) >> (BIT_DEPTH - 8);
+        src += srcstride;
+        tmp += MAX_PB_SIZE;
+    }
+
+    tmp      = tmp_array + EPEL_EXTRA_BEFORE * MAX_PB_SIZE;
+    filter_0 = filter_v[0];
+    filter_1 = filter_v[1];
+    filter_2 = filter_v[2];
+    filter_3 = filter_v[3];
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = EPEL_FILTER(tmp, MAX_PB_SIZE) >> 6;
+        tmp += MAX_PB_SIZE;
+        dst += dststride;
+    }
+}
+
+static void FUNC(put_unweighted_pred)(uint8_t *_dst, ptrdiff_t _dststride,
+                                      int16_t *src, ptrdiff_t srcstride,
+                                      int width, int height)
+{
+    int x, y;
+    pixel *dst          = (pixel *)_dst;
+    ptrdiff_t dststride = _dststride / sizeof(pixel);
+
+    int shift = 14 - BIT_DEPTH;
+#if BIT_DEPTH < 14
+    int offset = 1 << (shift - 1);
+#else
+    int offset = 0;
+#endif
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = av_clip_pixel((src[x] + offset) >> shift);
+        dst += dststride;
+        src += srcstride;
+    }
+}
+
+static void FUNC(put_weighted_pred_avg)(uint8_t *_dst, ptrdiff_t _dststride,
+                                        int16_t *src1, int16_t *src2,
+                                        ptrdiff_t srcstride,
+                                        int width, int height)
+{
+    int x, y;
+    pixel *dst          = (pixel *)_dst;
+    ptrdiff_t dststride = _dststride / sizeof(pixel);
+
+    int shift = 14 + 1 - BIT_DEPTH;
+#if BIT_DEPTH < 14
+    int offset = 1 << (shift - 1);
+#else
+    int offset = 0;
+#endif
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = av_clip_pixel((src1[x] + src2[x] + offset) >> shift);
+        dst  += dststride;
+        src1 += srcstride;
+        src2 += srcstride;
+    }
+}
+
+static void FUNC(weighted_pred)(uint8_t denom, int16_t wlxFlag, int16_t olxFlag,
+                                uint8_t *_dst, ptrdiff_t _dststride,
+                                int16_t *src, ptrdiff_t srcstride,
+                                int width, int height)
+{
+    int shift, log2Wd, wx, ox, x, y, offset;
+    pixel *dst          = (pixel *)_dst;
+    ptrdiff_t dststride = _dststride / sizeof(pixel);
+
+    shift  = 14 - BIT_DEPTH;
+    log2Wd = denom + shift;
+    offset = 1 << (log2Wd - 1);
+    wx     = wlxFlag;
+    ox     = olxFlag * (1 << (BIT_DEPTH - 8));
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++) {
+            if (log2Wd >= 1) {
+                dst[x] = av_clip_pixel(((src[x] * wx + offset) >> log2Wd) + ox);
+            } else {
+                dst[x] = av_clip_pixel(src[x] * wx + ox);
+            }
+        }
+        dst += dststride;
+        src += srcstride;
+    }
+}
+
+static void FUNC(weighted_pred_avg)(uint8_t denom,
+                                    int16_t wl0Flag, int16_t wl1Flag,
+                                    int16_t ol0Flag, int16_t ol1Flag,
+                                    uint8_t *_dst, ptrdiff_t _dststride,
+                                    int16_t *src1, int16_t *src2,
+                                    ptrdiff_t srcstride,
+                                    int width, int height)
+{
+    int shift, log2Wd, w0, w1, o0, o1, x, y;
+    pixel *dst = (pixel *)_dst;
+    ptrdiff_t dststride = _dststride / sizeof(pixel);
+
+    shift  = 14 - BIT_DEPTH;
+    log2Wd = denom + shift;
+    w0     = wl0Flag;
+    w1     = wl1Flag;
+    o0     = ol0Flag * (1 << (BIT_DEPTH - 8));
+    o1     = ol1Flag * (1 << (BIT_DEPTH - 8));
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++)
+            dst[x] = av_clip_pixel((src1[x] * w0 + src2[x] * w1 +
+                                    ((o0 + o1 + 1) << log2Wd)) >> (log2Wd + 1));
+        dst  += dststride;
+        src1 += srcstride;
+        src2 += srcstride;
+    }
+}
+
+// line zero
+#define P3 pix[-4 * xstride]
+#define P2 pix[-3 * xstride]
+#define P1 pix[-2 * xstride]
+#define P0 pix[-1 * xstride]
+#define Q0 pix[0 * xstride]
+#define Q1 pix[1 * xstride]
+#define Q2 pix[2 * xstride]
+#define Q3 pix[3 * xstride]
+
+// line three. used only for deblocking decision
+#define TP3 pix[-4 * xstride + 3 * ystride]
+#define TP2 pix[-3 * xstride + 3 * ystride]
+#define TP1 pix[-2 * xstride + 3 * ystride]
+#define TP0 pix[-1 * xstride + 3 * ystride]
+#define TQ0 pix[0  * xstride + 3 * ystride]
+#define TQ1 pix[1  * xstride + 3 * ystride]
+#define TQ2 pix[2  * xstride + 3 * ystride]
+#define TQ3 pix[3  * xstride + 3 * ystride]
+
+static void FUNC(hevc_loop_filter_luma)(uint8_t *_pix,
+                                        ptrdiff_t _xstride, ptrdiff_t _ystride,
+                                        int *_beta, int *_tc,
+                                        uint8_t *_no_p, uint8_t *_no_q)
+{
+    int d, j;
+    pixel *pix        = (pixel *)_pix;
+    ptrdiff_t xstride = _xstride / sizeof(pixel);
+    ptrdiff_t ystride = _ystride / sizeof(pixel);
+
+    for (j = 0; j < 2; j++) {
+        const int dp0  = abs(P2  - 2 * P1  + P0);
+        const int dq0  = abs(Q2  - 2 * Q1  + Q0);
+        const int dp3  = abs(TP2 - 2 * TP1 + TP0);
+        const int dq3  = abs(TQ2 - 2 * TQ1 + TQ0);
+        const int d0   = dp0 + dq0;
+        const int d3   = dp3 + dq3;
+        const int beta = _beta[j] << (BIT_DEPTH - 8);
+        const int tc   = _tc[j]   << (BIT_DEPTH - 8);
+        const int no_p = _no_p[j];
+        const int no_q = _no_q[j];
+
+        if (d0 + d3 >= beta) {
+            pix += 4 * ystride;
+            continue;
+        } else {
+            const int beta_3 = beta >> 3;
+            const int beta_2 = beta >> 2;
+            const int tc25   = ((tc * 5 + 1) >> 1);
+
+            if (abs(P3  -  P0) + abs(Q3  -  Q0) < beta_3 && abs(P0  -  Q0) < tc25 &&
+                abs(TP3 - TP0) + abs(TQ3 - TQ0) < beta_3 && abs(TP0 - TQ0) < tc25 &&
+                                      (d0 << 1) < beta_2 &&      (d3 << 1) < beta_2) {
+                // strong filtering
+                const int tc2 = tc << 1;
+                for (d = 0; d < 4; d++) {
+                    const int p3 = P3;
+                    const int p2 = P2;
+                    const int p1 = P1;
+                    const int p0 = P0;
+                    const int q0 = Q0;
+                    const int q1 = Q1;
+                    const int q2 = Q2;
+                    const int q3 = Q3;
+                    if (!no_p) {
+                        P0 = p0 + av_clip(((p2 + 2 * p1 + 2 * p0 + 2 * q0 + q1 + 4) >> 3) - p0, -tc2, tc2);
+                        P1 = p1 + av_clip(((p2 + p1 + p0 + q0 + 2) >> 2) - p1, -tc2, tc2);
+                        P2 = p2 + av_clip(((2 * p3 + 3 * p2 + p1 + p0 + q0 + 4) >> 3) - p2, -tc2, tc2);
+                    }
+                    if (!no_q) {
+                        Q0 = q0 + av_clip(((p1 + 2 * p0 + 2 * q0 + 2 * q1 + q2 + 4) >> 3) - q0, -tc2, tc2);
+                        Q1 = q1 + av_clip(((p0 + q0 + q1 + q2 + 2) >> 2) - q1, -tc2, tc2);
+                        Q2 = q2 + av_clip(((2 * q3 + 3 * q2 + q1 + q0 + p0 + 4) >> 3) - q2, -tc2, tc2);
+                    }
+                    pix += ystride;
+                }
+            } else { // normal filtering
+                int nd_p = 1;
+                int nd_q = 1;
+                const int tc_2 = tc >> 1;
+                if (dp0 + dp3 < ((beta + (beta >> 1)) >> 3))
+                    nd_p = 2;
+                if (dq0 + dq3 < ((beta + (beta >> 1)) >> 3))
+                    nd_q = 2;
+
+                for (d = 0; d < 4; d++) {
+                    const int p2 = P2;
+                    const int p1 = P1;
+                    const int p0 = P0;
+                    const int q0 = Q0;
+                    const int q1 = Q1;
+                    const int q2 = Q2;
+                    int delta0   = (9 * (q0 - p0) - 3 * (q1 - p1) + 8) >> 4;
+                    if (abs(delta0) < 10 * tc) {
+                        delta0 = av_clip(delta0, -tc, tc);
+                        if (!no_p)
+                            P0 = av_clip_pixel(p0 + delta0);
+                        if (!no_q)
+                            Q0 = av_clip_pixel(q0 - delta0);
+                        if (!no_p && nd_p > 1) {
+                            const int deltap1 = av_clip((((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1, -tc_2, tc_2);
+                            P1 = av_clip_pixel(p1 + deltap1);
+                        }
+                        if (!no_q && nd_q > 1) {
+                            const int deltaq1 = av_clip((((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1, -tc_2, tc_2);
+                            Q1 = av_clip_pixel(q1 + deltaq1);
+                        }
+                    }
+                    pix += ystride;
+                }
+            }
+        }
+    }
+}
+
+static void FUNC(hevc_loop_filter_chroma)(uint8_t *_pix, ptrdiff_t _xstride,
+                                          ptrdiff_t _ystride, int *_tc,
+                                          uint8_t *_no_p, uint8_t *_no_q)
+{
+    int d, j, no_p, no_q;
+    pixel *pix        = (pixel *)_pix;
+    ptrdiff_t xstride = _xstride / sizeof(pixel);
+    ptrdiff_t ystride = _ystride / sizeof(pixel);
+
+    for (j = 0; j < 2; j++) {
+        const int tc = _tc[j] << (BIT_DEPTH - 8);
+        if (tc <= 0) {
+            pix += 4 * ystride;
+            continue;
+        }
+        no_p = _no_p[j];
+        no_q = _no_q[j];
+
+        for (d = 0; d < 4; d++) {
+            int delta0;
+            const int p1 = P1;
+            const int p0 = P0;
+            const int q0 = Q0;
+            const int q1 = Q1;
+            delta0 = av_clip((((q0 - p0) << 2) + p1 - q1 + 4) >> 3, -tc, tc);
+            if (!no_p)
+                P0 = av_clip_pixel(p0 + delta0);
+            if (!no_q)
+                Q0 = av_clip_pixel(q0 - delta0);
+            pix += ystride;
+        }
+    }
+}
+
+static void FUNC(hevc_h_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
+                                            int *tc, uint8_t *no_p,
+                                            uint8_t *no_q)
+{
+    FUNC(hevc_loop_filter_chroma)(pix, stride, sizeof(pixel), tc, no_p, no_q);
+}
+
+static void FUNC(hevc_v_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
+                                            int *tc, uint8_t *no_p,
+                                            uint8_t *no_q)
+{
+    FUNC(hevc_loop_filter_chroma)(pix, sizeof(pixel), stride, tc, no_p, no_q);
+}
+
+static void FUNC(hevc_h_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
+                                          int *beta, int *tc, uint8_t *no_p,
+                                          uint8_t *no_q)
+{
+    FUNC(hevc_loop_filter_luma)(pix, stride, sizeof(pixel),
+                                beta, tc, no_p, no_q);
+}
+
+static void FUNC(hevc_v_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
+                                          int *beta, int *tc, uint8_t *no_p,
+                                          uint8_t *no_q)
+{
+    FUNC(hevc_loop_filter_luma)(pix, sizeof(pixel), stride,
+                                beta, tc, no_p, no_q);
+}
+
+#undef P3
+#undef P2
+#undef P1
+#undef P0
+#undef Q0
+#undef Q1
+#undef Q2
+#undef Q3
+
+#undef TP3
+#undef TP2
+#undef TP1
+#undef TP0
+#undef TQ0
+#undef TQ1
+#undef TQ2
+#undef TQ3
diff --git a/libavcodec/hevcpred.c b/libavcodec/hevcpred.c
new file mode 100644
index 0000000..1121f30
--- /dev/null
+++ b/libavcodec/hevcpred.c
@@ -0,0 +1,65 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * 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 "hevc.h"
+
+#define BIT_DEPTH 8
+#include "hevcpred_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 9
+#include "hevcpred_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 10
+#include "hevcpred_template.c"
+#undef BIT_DEPTH
+
+void ff_hevc_pred_init(HEVCPredContext *hpc, int bit_depth)
+{
+#undef FUNC
+#define FUNC(a, depth) a ## _ ## depth
+
+#define HEVC_PRED(depth)                                \
+    hpc->intra_pred      = FUNC(intra_pred, depth);     \
+    hpc->pred_planar[0]  = FUNC(pred_planar_0, depth);  \
+    hpc->pred_planar[1]  = FUNC(pred_planar_1, depth);  \
+    hpc->pred_planar[2]  = FUNC(pred_planar_2, depth);  \
+    hpc->pred_planar[3]  = FUNC(pred_planar_3, depth);  \
+    hpc->pred_dc         = FUNC(pred_dc, depth);        \
+    hpc->pred_angular[0] = FUNC(pred_angular_0, depth); \
+    hpc->pred_angular[1] = FUNC(pred_angular_1, depth); \
+    hpc->pred_angular[2] = FUNC(pred_angular_2, depth); \
+    hpc->pred_angular[3] = FUNC(pred_angular_3, depth);
+
+    switch (bit_depth) {
+    case 9:
+        HEVC_PRED(9);
+        break;
+    case 10:
+        HEVC_PRED(10);
+        break;
+    default:
+        HEVC_PRED(8);
+        break;
+    }
+}
diff --git a/libavcodec/hevcpred_template.c b/libavcodec/hevcpred_template.c
new file mode 100644
index 0000000..27f4b9e
--- /dev/null
+++ b/libavcodec/hevcpred_template.c
@@ -0,0 +1,560 @@
+/*
+ * HEVC video decoder
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ *
+ * 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/pixdesc.h"
+
+#include "hevc.h"
+
+#include "bit_depth_template.c"
+
+#define POS(x, y) src[(x) + stride * (y)]
+
+static void FUNC(intra_pred)(HEVCContext *s, int x0, int y0, int log2_size, int c_idx)
+{
+#define PU(x) \
+    ((x) >> s->sps->log2_min_pu_size)
+#define MVF(x, y) \
+    (s->ref->tab_mvf[(x) + (y) * min_pu_width])
+#define MVF_PU(x, y) \
+    MVF(PU(x0 + ((x) << hshift)), PU(y0 + ((y) << vshift)))
+#define IS_INTRA(x, y) \
+    MVF_PU(x, y).is_intra
+#define MIN_TB_ADDR_ZS(x, y) \
+    s->pps->min_tb_addr_zs[(y) * s->sps->min_tb_width + (x)]
+#define EXTEND_LEFT(ptr, start, length) \
+        for (i = (start); i > (start) - (length); i--) \
+            ptr[i - 1] = ptr[i]
+#define EXTEND_RIGHT(ptr, start, length) \
+        for (i = (start); i < (start) + (length); i++) \
+            ptr[i] = ptr[i - 1]
+#define EXTEND_UP(ptr, start, length)   EXTEND_LEFT(ptr, start, length)
+#define EXTEND_DOWN(ptr, start, length) EXTEND_RIGHT(ptr, start, length)
+#define EXTEND_LEFT_CIP(ptr, start, length) \
+        for (i = (start); i > (start) - (length); i--) \
+            if (!IS_INTRA(i - 1, -1)) \
+                ptr[i - 1] = ptr[i]
+#define EXTEND_RIGHT_CIP(ptr, start, length) \
+        for (i = (start); i < (start) + (length); i++) \
+            if (!IS_INTRA(i, -1)) \
+                ptr[i] = ptr[i - 1]
+#define EXTEND_UP_CIP(ptr, start, length) \
+        for (i = (start); i > (start) - (length); i--) \
+            if (!IS_INTRA(-1, i - 1)) \
+                ptr[i - 1] = ptr[i]
+#define EXTEND_UP_CIP_0(ptr, start, length) \
+        for (i = (start); i > (start) - (length); i--) \
+            ptr[i - 1] = ptr[i]
+#define EXTEND_DOWN_CIP(ptr, start, length) \
+        for (i = (start); i < (start) + (length); i++) \
+            if (!IS_INTRA(-1, i)) \
+                ptr[i] = ptr[i - 1]
+    HEVCLocalContext *lc = &s->HEVClc;
+    int i;
+    int hshift = s->sps->hshift[c_idx];
+    int vshift = s->sps->vshift[c_idx];
+    int size = (1 << log2_size);
+    int size_in_luma = size << hshift;
+    int size_in_tbs = size_in_luma >> s->sps->log2_min_tb_size;
+    int x = x0 >> hshift;
+    int y = y0 >> vshift;
+    int x_tb = x0 >> s->sps->log2_min_tb_size;
+    int y_tb = y0 >> s->sps->log2_min_tb_size;
+    int cur_tb_addr = MIN_TB_ADDR_ZS(x_tb, y_tb);
+
+    ptrdiff_t stride = s->frame->linesize[c_idx] / sizeof(pixel);
+    pixel *src = (pixel*)s->frame->data[c_idx] + x + y * stride;
+
+    int min_pu_width = s->sps->min_pu_width;
+
+    enum IntraPredMode mode = c_idx ? lc->pu.intra_pred_mode_c :
+                              lc->tu.cur_intra_pred_mode;
+
+    pixel left_array[2 * MAX_TB_SIZE + 1];
+    pixel filtered_left_array[2 * MAX_TB_SIZE + 1];
+    pixel top_array[2 * MAX_TB_SIZE + 1];
+    pixel filtered_top_array[2 * MAX_TB_SIZE + 1];
+
+    pixel *left          = left_array + 1;
+    pixel *top           = top_array  + 1;
+    pixel *filtered_left = filtered_left_array + 1;
+    pixel *filtered_top  = filtered_top_array  + 1;
+
+    int cand_bottom_left = lc->na.cand_bottom_left && cur_tb_addr > MIN_TB_ADDR_ZS(x_tb - 1, y_tb + size_in_tbs);
+    int cand_left        = lc->na.cand_left;
+    int cand_up_left     = lc->na.cand_up_left;
+    int cand_up          = lc->na.cand_up;
+    int cand_up_right    = lc->na.cand_up_right && cur_tb_addr > MIN_TB_ADDR_ZS(x_tb + size_in_tbs, y_tb - 1);
+
+    int bottom_left_size = (FFMIN(y0 + 2 * size_in_luma, s->sps->height) -
+                            (y0 + size_in_luma)) >> vshift;
+    int top_right_size   = (FFMIN(x0 + 2 * size_in_luma, s->sps->width) -
+                            (x0 + size_in_luma)) >> hshift;
+
+    if (s->pps->constrained_intra_pred_flag == 1) {
+        int size_in_luma_pu = PU(size_in_luma);
+        int on_pu_edge_x    = !(x0 & ((1 << s->sps->log2_min_pu_size) - 1));
+        int on_pu_edge_y    = !(y0 & ((1 << s->sps->log2_min_pu_size) - 1));
+        if (!size_in_luma_pu)
+            size_in_luma_pu++;
+        if (cand_bottom_left == 1 && on_pu_edge_x) {
+            int x_left_pu   = PU(x0 - 1);
+            int y_bottom_pu = PU(y0 + size_in_luma);
+            int max = FFMIN(size_in_luma_pu, s->sps->min_pu_height - y_bottom_pu);
+            cand_bottom_left = 0;
+            for (i = 0; i < max; i++)
+                cand_bottom_left |= MVF(x_left_pu, y_bottom_pu + i).is_intra;
+        }
+        if (cand_left == 1 && on_pu_edge_x) {
+            int x_left_pu   = PU(x0 - 1);
+            int y_left_pu   = PU(y0);
+            int max = FFMIN(size_in_luma_pu, s->sps->min_pu_height - y_left_pu);
+            cand_left = 0;
+            for (i = 0; i < max; i++)
+                cand_left |= MVF(x_left_pu, y_left_pu + i).is_intra;
+        }
+        if (cand_up_left == 1) {
+            int x_left_pu   = PU(x0 - 1);
+            int y_top_pu    = PU(y0 - 1);
+            cand_up_left = MVF(x_left_pu, y_top_pu).is_intra;
+        }
+        if (cand_up == 1 && on_pu_edge_y) {
+            int x_top_pu    = PU(x0);
+            int y_top_pu    = PU(y0 - 1);
+            int max = FFMIN(size_in_luma_pu, s->sps->min_pu_width - x_top_pu);
+            cand_up = 0;
+            for (i = 0; i < max; i++)
+                cand_up |= MVF(x_top_pu + i, y_top_pu).is_intra;
+        }
+        if (cand_up_right == 1 && on_pu_edge_y) {
+            int y_top_pu    = PU(y0 - 1);
+            int x_right_pu  = PU(x0 + size_in_luma);
+            int max = FFMIN(size_in_luma_pu, s->sps->min_pu_width - x_right_pu);
+            cand_up_right = 0;
+            for (i = 0; i < max; i++)
+                cand_up_right |= MVF(x_right_pu + i, y_top_pu).is_intra;
+        }
+        for (i = 0; i < 2 * MAX_TB_SIZE; i++) {
+            left[i] = 128;
+            top[i]  = 128;
+        }
+    }
+    if (cand_bottom_left) {
+        for (i = size + bottom_left_size; i < (size << 1); i++)
+            if (IS_INTRA(-1, size + bottom_left_size - 1) ||
+                !s->pps->constrained_intra_pred_flag)
+                left[i] = POS(-1, size + bottom_left_size - 1);
+        for (i = size + bottom_left_size - 1; i >= size; i--)
+            if (IS_INTRA(-1, i) || !s->pps->constrained_intra_pred_flag)
+                left[i] = POS(-1, i);
+    }
+    if (cand_left)
+        for (i = size - 1; i >= 0; i--)
+            if (IS_INTRA(-1, i) || !s->pps->constrained_intra_pred_flag)
+                left[i] = POS(-1, i);
+    if (cand_up_left)
+        if (IS_INTRA(-1, -1) || !s->pps->constrained_intra_pred_flag) {
+            left[-1] = POS(-1, -1);
+            top[-1]  = left[-1];
+        }
+    if (cand_up)
+        for (i = size - 1; i >= 0; i--)
+            if (IS_INTRA(i, -1) || !s->pps->constrained_intra_pred_flag)
+                top[i] = POS(i, -1);
+    if (cand_up_right) {
+        for (i = size + top_right_size; i < (size << 1); i++)
+            if (IS_INTRA(size + top_right_size - 1, -1) ||
+                !s->pps->constrained_intra_pred_flag)
+                top[i] = POS(size + top_right_size - 1, -1);
+        for (i = size + top_right_size - 1; i >= size; i--)
+            if (IS_INTRA(i, -1) || !s->pps->constrained_intra_pred_flag)
+                top[i] = POS(i, -1);
+    }
+
+    if (s->pps->constrained_intra_pred_flag == 1) {
+        if (cand_bottom_left || cand_left || cand_up_left || cand_up || cand_up_right) {
+            int size_max_x = x0 + ((2 * size) << hshift) < s->sps->width ?
+                                    2 * size : (s->sps->width - x0) >> hshift;
+            int size_max_y = y0 + ((2 * size) << vshift) < s->sps->height ?
+                                    2 * size : (s->sps->height - y0) >> vshift;
+            int j = size + (cand_bottom_left? bottom_left_size: 0) -1;
+            if (!cand_up_right) {
+                size_max_x = x0 + ((size) << hshift) < s->sps->width ?
+                                                    size : (s->sps->width - x0) >> hshift;
+            }
+            if (!cand_bottom_left) {
+                size_max_y = y0 + (( size) << vshift) < s->sps->height ?
+                                                     size : (s->sps->height - y0) >> vshift;
+            }
+            if (cand_bottom_left || cand_left || cand_up_left) {
+                while (j > -1 && !IS_INTRA(-1, j))
+                    j--;
+                if (!IS_INTRA(-1, j)) {
+                    j = 0;
+                    while (j < size_max_x && !IS_INTRA(j, -1))
+                        j++;
+                    EXTEND_LEFT_CIP(top, j, j + 1);
+                    left[-1] = top[-1];
+                    j        = 0;
+                }
+            } else {
+                j = 0;
+                while (j < size_max_x && !IS_INTRA(j, -1))
+                    j++;
+                if (j > 0)
+                    if (x0 > 0) {
+                        EXTEND_LEFT_CIP(top, j, j + 1);
+                    } else {
+                        EXTEND_LEFT_CIP(top, j, j);
+                        top[-1] = top[0];
+                    }
+                left[-1] = top[-1];
+                j        = 0;
+            }
+            if (cand_bottom_left || cand_left) {
+                EXTEND_DOWN_CIP(left, j, size_max_y - j);
+            }
+            if (!cand_left) {
+                EXTEND_DOWN(left, 0, size);
+            }
+            if (!cand_bottom_left) {
+                EXTEND_DOWN(left, size, size);
+            }
+            if (x0 != 0 && y0 != 0) {
+                EXTEND_UP_CIP(left, size_max_y - 1, size_max_y);
+            } else if (x0 == 0) {
+                EXTEND_UP_CIP_0(left, size_max_y - 1, size_max_y);
+            } else {
+                EXTEND_UP_CIP(left, size_max_y - 1, size_max_y - 1);
+            }
+            top[-1] = left[-1];
+            if (y0 != 0) {
+                EXTEND_RIGHT_CIP(top, 0, size_max_x);
+            }
+        }
+    }
+    // Infer the unavailable samples
+    if (!cand_bottom_left) {
+        if (cand_left) {
+            EXTEND_DOWN(left, size, size);
+        } else if (cand_up_left) {
+            EXTEND_DOWN(left, 0, 2 * size);
+            cand_left = 1;
+        } else if (cand_up) {
+            left[-1] = top[0];
+            EXTEND_DOWN(left, 0, 2 * size);
+            cand_up_left = 1;
+            cand_left    = 1;
+        } else if (cand_up_right) {
+            EXTEND_LEFT(top, size, size);
+            left[-1] = top[0];
+            EXTEND_DOWN(left, 0, 2 * size);
+            cand_up      = 1;
+            cand_up_left = 1;
+            cand_left    = 1;
+        } else { // No samples available
+            top[0] = left[-1] = (1 << (BIT_DEPTH - 1));
+            EXTEND_RIGHT(top, 1, 2 * size - 1);
+            EXTEND_DOWN(left, 0, 2 * size);
+        }
+    }
+
+    if (!cand_left) {
+        EXTEND_UP(left, size, size);
+    }
+    if (!cand_up_left) {
+        left[-1] = left[0];
+    }
+    if (!cand_up) {
+        top[0] = left[-1];
+        EXTEND_RIGHT(top, 1, size - 1);
+    }
+    if (!cand_up_right) {
+        EXTEND_RIGHT(top, size, size);
+    }
+
+    top[-1] = left[-1];
+
+    // Filtering process
+    if (c_idx == 0 && mode != INTRA_DC && size != 4) {
+        int intra_hor_ver_dist_thresh[] = { 7, 1, 0 };
+        int min_dist_vert_hor = FFMIN(FFABS((int)mode - 26),
+                                      FFABS((int)mode - 10));
+        if (min_dist_vert_hor > intra_hor_ver_dist_thresh[log2_size - 3]) {
+            int threshold = 1 << (BIT_DEPTH - 5);
+            if (s->sps->sps_strong_intra_smoothing_enable_flag &&
+                log2_size == 5 &&
+                FFABS(top[-1]  + top[63]  - 2 * top[31])  < threshold &&
+                FFABS(left[-1] + left[63] - 2 * left[31]) < threshold) {
+                // We can't just overwrite values in top because it could be
+                // a pointer into src
+                filtered_top[-1] = top[-1];
+                filtered_top[63] = top[63];
+                for (i = 0; i < 63; i++)
+                    filtered_top[i] = ((64 - (i + 1)) * top[-1] +
+                                             (i + 1)  * top[63] + 32) >> 6;
+                for (i = 0; i < 63; i++)
+                    left[i] = ((64 - (i + 1)) * left[-1] +
+                                     (i + 1)  * left[63] + 32) >> 6;
+                top = filtered_top;
+            } else {
+                filtered_left[2 * size - 1] = left[2 * size - 1];
+                filtered_top[2 * size - 1]  = top[2 * size - 1];
+                for (i = 2 * size - 2; i >= 0; i--)
+                    filtered_left[i] = (left[i + 1] + 2 * left[i] +
+                                        left[i - 1] + 2) >> 2;
+                filtered_top[-1]  =
+                filtered_left[-1] = (left[0] + 2 * left[-1] + top[0] + 2) >> 2;
+                for (i = 2 * size - 2; i >= 0; i--)
+                    filtered_top[i] = (top[i + 1] + 2 * top[i] +
+                                       top[i - 1] + 2) >> 2;
+                left = filtered_left;
+                top  = filtered_top;
+            }
+        }
+    }
+
+    switch (mode) {
+    case INTRA_PLANAR:
+        s->hpc.pred_planar[log2_size - 2]((uint8_t *)src, (uint8_t *)top,
+                                          (uint8_t *)left, stride);
+        break;
+    case INTRA_DC:
+        s->hpc.pred_dc((uint8_t *)src, (uint8_t *)top,
+                       (uint8_t *)left, stride, log2_size, c_idx);
+        break;
+    default:
+        s->hpc.pred_angular[log2_size - 2]((uint8_t *)src, (uint8_t *)top,
+                                           (uint8_t *)left, stride, c_idx,
+                                           mode);
+        break;
+    }
+}
+
+static void FUNC(pred_planar_0)(uint8_t *_src, const uint8_t *_top,
+                                const uint8_t *_left,
+                                ptrdiff_t stride)
+{
+    int x, y;
+    pixel *src        = (pixel *)_src;
+    const pixel *top  = (const pixel *)_top;
+    const pixel *left = (const pixel *)_left;
+    for (y = 0; y < 4; y++)
+        for (x = 0; x < 4; x++)
+            POS(x, y) = ((3 - x) * left[y] + (x + 1) * top[4]  +
+                         (3 - y) * top[x]  + (y + 1) * left[4] + 4) >> 3;
+}
+
+static void FUNC(pred_planar_1)(uint8_t *_src, const uint8_t *_top,
+                                const uint8_t *_left, ptrdiff_t stride)
+{
+    int x, y;
+    pixel *src        = (pixel *)_src;
+    const pixel *top  = (const pixel *)_top;
+    const pixel *left = (const pixel *)_left;
+    for (y = 0; y < 8; y++)
+        for (x = 0; x < 8; x++)
+            POS(x, y) = ((7 - x) * left[y] + (x + 1) * top[8]  +
+                         (7 - y) * top[x]  + (y + 1) * left[8] + 8) >> 4;
+}
+
+static void FUNC(pred_planar_2)(uint8_t *_src, const uint8_t *_top,
+                                const uint8_t *_left, ptrdiff_t stride)
+{
+    int x, y;
+    pixel *src        = (pixel *)_src;
+    const pixel *top  = (const pixel *)_top;
+    const pixel *left = (const pixel *)_left;
+    for (y = 0; y < 16; y++)
+        for (x = 0; x < 16; x++)
+            POS(x, y) = ((15 - x) * left[y] + (x + 1) * top[16]  +
+                         (15 - y) * top[x]  + (y + 1) * left[16] + 16) >> 5;
+}
+
+static void FUNC(pred_planar_3)(uint8_t *_src, const uint8_t *_top,
+                                const uint8_t *_left, ptrdiff_t stride)
+{
+    int x, y;
+    pixel *src        = (pixel *)_src;
+    const pixel *top  = (const pixel *)_top;
+    const pixel *left = (const pixel *)_left;
+    for (y = 0; y < 32; y++)
+        for (x = 0; x < 32; x++)
+            POS(x, y) = ((31 - x) * left[y] + (x + 1) * top[32]  +
+                         (31 - y) * top[x]  + (y + 1) * left[32] + 32) >> 6;
+}
+
+static void FUNC(pred_dc)(uint8_t *_src, const uint8_t *_top,
+                          const uint8_t *_left,
+                          ptrdiff_t stride, int log2_size, int c_idx)
+{
+    int i, j, x, y;
+    int size          = (1 << log2_size);
+    pixel *src        = (pixel *)_src;
+    const pixel *top  = (const pixel *)_top;
+    const pixel *left = (const pixel *)_left;
+    int dc            = size;
+    pixel4 a;
+    for (i = 0; i < size; i++)
+        dc += left[i] + top[i];
+
+    dc >>= log2_size + 1;
+
+    a = PIXEL_SPLAT_X4(dc);
+
+    for (i = 0; i < size; i++)
+        for (j = 0; j < size / 4; j++)
+            AV_WN4PA(&POS(j * 4, i), a);
+
+    if (c_idx == 0 && size < 32) {
+        POS(0, 0) = (left[0] + 2 * dc + top[0] + 2) >> 2;
+        for (x = 1; x < size; x++)
+            POS(x, 0) = (top[x] + 3 * dc + 2) >> 2;
+        for (y = 1; y < size; y++)
+            POS(0, y) = (left[y] + 3 * dc + 2) >> 2;
+    }
+}
+
+static av_always_inline void FUNC(pred_angular)(uint8_t *_src,
+                                                const uint8_t *_top,
+                                                const uint8_t *_left,
+                                                ptrdiff_t stride, int c_idx,
+                                                int mode, int size)
+{
+    int x, y;
+    pixel *src        = (pixel *)_src;
+    const pixel *top  = (const pixel *)_top;
+    const pixel *left = (const pixel *)_left;
+
+    static const int intra_pred_angle[] = {
+         32,  26,  21,  17, 13,  9,  5, 2, 0, -2, -5, -9, -13, -17, -21, -26, -32,
+        -26, -21, -17, -13, -9, -5, -2, 0, 2,  5,  9, 13,  17,  21,  26,  32
+    };
+    static const int inv_angle[] = {
+        -4096, -1638, -910, -630, -482, -390, -315, -256, -315, -390, -482,
+        -630, -910, -1638, -4096
+    };
+
+    int angle = intra_pred_angle[mode - 2];
+    pixel ref_array[3 * MAX_TB_SIZE + 1];
+    pixel *ref_tmp = ref_array + size;
+    const pixel *ref;
+    int last = (size * angle) >> 5;
+
+    if (mode >= 18) {
+        ref = top - 1;
+        if (angle < 0 && last < -1) {
+            for (x = 0; x <= size; x++)
+                ref_tmp[x] = top[x - 1];
+            for (x = last; x <= -1; x++)
+                ref_tmp[x] = left[-1 + ((x * inv_angle[mode - 11] + 128) >> 8)];
+            ref = ref_tmp;
+        }
+
+        for (y = 0; y < size; y++) {
+            int idx  = ((y + 1) * angle) >> 5;
+            int fact = ((y + 1) * angle) & 31;
+            if (fact) {
+                for (x = 0; x < size; x++) {
+                    POS(x, y) = ((32 - fact) * ref[x + idx + 1] +
+                                       fact  * ref[x + idx + 2] + 16) >> 5;
+                }
+            } else {
+                for (x = 0; x < size; x++)
+                    POS(x, y) = ref[x + idx + 1];
+            }
+        }
+        if (mode == 26 && c_idx == 0 && size < 32) {
+            for (y = 0; y < size; y++)
+                POS(0, y) = av_clip_pixel(top[0] + ((left[y] - left[-1]) >> 1));
+        }
+    } else {
+        ref = left - 1;
+        if (angle < 0 && last < -1) {
+            for (x = 0; x <= size; x++)
+                ref_tmp[x] = left[x - 1];
+            for (x = last; x <= -1; x++)
+                ref_tmp[x] = top[-1 + ((x * inv_angle[mode - 11] + 128) >> 8)];
+            ref = ref_tmp;
+        }
+
+        for (x = 0; x < size; x++) {
+            int idx  = ((x + 1) * angle) >> 5;
+            int fact = ((x + 1) * angle) & 31;
+            if (fact) {
+                for (y = 0; y < size; y++) {
+                    POS(x, y) = ((32 - fact) * ref[y + idx + 1] +
+                                       fact  * ref[y + idx + 2] + 16) >> 5;
+                }
+            } else {
+                for (y = 0; y < size; y++)
+                    POS(x, y) = ref[y + idx + 1];
+            }
+        }
+        if (mode == 10 && c_idx == 0 && size < 32) {
+            for (x = 0; x < size; x++)
+                POS(x, 0) = av_clip_pixel(left[0] + ((top[x] - top[-1]) >> 1));
+        }
+    }
+}
+
+static void FUNC(pred_angular_0)(uint8_t *src, const uint8_t *top,
+                                 const uint8_t *left,
+                                 ptrdiff_t stride, int c_idx, int mode)
+{
+    FUNC(pred_angular)(src, top, left, stride, c_idx, mode, 1 << 2);
+}
+
+static void FUNC(pred_angular_1)(uint8_t *src, const uint8_t *top,
+                                 const uint8_t *left,
+                                 ptrdiff_t stride, int c_idx, int mode)
+{
+    FUNC(pred_angular)(src, top, left, stride, c_idx, mode, 1 << 3);
+}
+
+static void FUNC(pred_angular_2)(uint8_t *src, const uint8_t *top,
+                                 const uint8_t *left,
+                                 ptrdiff_t stride, int c_idx, int mode)
+{
+    FUNC(pred_angular)(src, top, left, stride, c_idx, mode, 1 << 4);
+}
+
+static void FUNC(pred_angular_3)(uint8_t *src, const uint8_t *top,
+                                 const uint8_t *left,
+                                 ptrdiff_t stride, int c_idx, int mode)
+{
+    FUNC(pred_angular)(src, top, left, stride, c_idx, mode, 1 << 5);
+}
+
+#undef EXTEND_LEFT_CIP
+#undef EXTEND_RIGHT_CIP
+#undef EXTEND_UP_CIP
+#undef EXTEND_DOWN_CIP
+#undef IS_INTRA
+#undef MVF_PU
+#undef MVF
+#undef PU
+#undef EXTEND_LEFT
+#undef EXTEND_RIGHT
+#undef EXTEND_UP
+#undef EXTEND_DOWN
+#undef MIN_TB_ADDR_ZS
+#undef POS
diff --git a/libavcodec/hnm4video.c b/libavcodec/hnm4video.c
new file mode 100644
index 0000000..b200e89
--- /dev/null
+++ b/libavcodec/hnm4video.c
@@ -0,0 +1,459 @@
+/*
+ * Cryo Interactive Entertainment HNM4 video decoder
+ *
+ * Copyright (c) 2012 David Kment
+ *
+ * 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 <string.h>
+
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mem.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+#define HNM4_CHUNK_ID_PL 19536
+#define HNM4_CHUNK_ID_IZ 23113
+#define HNM4_CHUNK_ID_IU 21833
+#define HNM4_CHUNK_ID_SD 17491
+
+typedef struct Hnm4VideoContext {
+    uint8_t version;
+    uint16_t width;
+    uint16_t height;
+    uint8_t *current;
+    uint8_t *previous;
+    uint8_t *buffer1;
+    uint8_t *buffer2;
+    uint8_t *processed;
+    uint32_t palette[256];
+} Hnm4VideoContext;
+
+static int getbit(GetByteContext *gb, uint32_t *bitbuf, int *bits)
+{
+    int ret;
+
+    if (!*bits) {
+        *bitbuf = bytestream2_get_le32(gb);
+        *bits = 32;
+    }
+
+    ret = *bitbuf >> 31;
+    *bitbuf <<= 1;
+    (*bits)--;
+
+    return ret;
+}
+
+static void unpack_intraframe(AVCodecContext *avctx, uint8_t *src,
+                              uint32_t size)
+{
+    Hnm4VideoContext *hnm = avctx->priv_data;
+    GetByteContext gb;
+    uint32_t bitbuf = 0, writeoffset = 0, count = 0;
+    uint16_t word;
+    int32_t offset;
+    int bits = 0;
+
+    bytestream2_init(&gb, src, size);
+
+    while (bytestream2_tell(&gb) < size) {
+        if (getbit(&gb, &bitbuf, &bits)) {
+            if (writeoffset >= hnm->width * hnm->height) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Attempting to write out of bounds");
+                break;
+            }
+            hnm->current[writeoffset++] = bytestream2_get_byte(&gb);
+        } else {
+            if (getbit(&gb, &bitbuf, &bits)) {
+                word   = bytestream2_get_le16(&gb);
+                count  = word & 0x07;
+                offset = (word >> 3) - 0x2000;
+                if (!count)
+                    count = bytestream2_get_byte(&gb);
+                if (!count)
+                    return;
+            } else {
+                count  = getbit(&gb, &bitbuf, &bits) * 2;
+                count += getbit(&gb, &bitbuf, &bits);
+                offset = bytestream2_get_byte(&gb) - 0x0100;
+            }
+            count  += 2;
+            offset += writeoffset;
+            if (offset < 0 || offset + count >= hnm->width * hnm->height) {
+                av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds");
+                break;
+            } else if (writeoffset + count >= hnm->width * hnm->height) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Attempting to write out of bounds");
+                break;
+            }
+            while (count--) {
+                hnm->current[writeoffset++] = hnm->current[offset++];
+            }
+        }
+    }
+}
+
+static void postprocess_current_frame(AVCodecContext *avctx)
+{
+    Hnm4VideoContext *hnm = avctx->priv_data;
+    uint32_t x, y, src_x, src_y;
+
+    for (y = 0; y < hnm->height; y++) {
+        src_y = y - (y % 2);
+        src_x = src_y * hnm->width + (y % 2);
+        for (x = 0; x < hnm->width; x++) {
+            hnm->processed[(y * hnm->width) + x] = hnm->current[src_x];
+            src_x += 2;
+        }
+    }
+}
+
+static void copy_processed_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+    Hnm4VideoContext *hnm = avctx->priv_data;
+    uint8_t *src = hnm->processed;
+    uint8_t *dst = frame->data[0];
+    int y;
+
+    for (y = 0; y < hnm->height; y++) {
+        memcpy(dst, src, hnm->width);
+        src += hnm->width;
+        dst += frame->linesize[0];
+    }
+}
+
+static void decode_interframe_v4(AVCodecContext *avctx, uint8_t *src, uint32_t size)
+{
+    Hnm4VideoContext *hnm = avctx->priv_data;
+    GetByteContext gb;
+    uint32_t writeoffset = 0, count, left, offset;
+    uint8_t tag, previous, backline, backward, swap;
+
+    bytestream2_init(&gb, src, size);
+
+    while (bytestream2_tell(&gb) < size) {
+        count = bytestream2_peek_byte(&gb) & 0x1F;
+        if (count == 0) {
+            tag = bytestream2_get_byte(&gb) & 0xE0;
+            tag = tag >> 5;
+            if (tag == 0) {
+                hnm->current[writeoffset++] = bytestream2_get_byte(&gb);
+                hnm->current[writeoffset++] = bytestream2_get_byte(&gb);
+            } else if (tag == 1) {
+                writeoffset += bytestream2_get_byte(&gb) * 2;
+            } else if (tag == 2) {
+                count = bytestream2_get_le16(&gb);
+                count *= 2;
+                writeoffset += count;
+            } else if (tag == 3) {
+                count = bytestream2_get_byte(&gb) * 2;
+                while (count > 0) {
+                    hnm->current[writeoffset++] = bytestream2_peek_byte(&gb);
+                    count--;
+                }
+                bytestream2_skip(&gb, 1);
+            } else {
+                break;
+            }
+        } else {
+            previous = bytestream2_peek_byte(&gb) & 0x20;
+            backline = bytestream2_peek_byte(&gb) & 0x40;
+            backward = bytestream2_peek_byte(&gb) & 0x80;
+            bytestream2_skip(&gb, 1);
+            swap   = bytestream2_peek_byte(&gb) & 0x01;
+            offset = bytestream2_get_le16(&gb);
+            offset = (offset >> 1) & 0x7FFF;
+            offset = writeoffset + (offset * 2) - 0x8000;
+
+            left = count;
+
+            if (!backward && offset + count >= hnm->width * hnm->height) {
+                av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds");
+                break;
+            } else if (backward && offset >= hnm->width * hnm->height) {
+                av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds");
+                break;
+            } else if (writeoffset + count >= hnm->width * hnm->height) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Attempting to write out of bounds");
+                break;
+            }
+
+            if (previous) {
+                while (left > 0) {
+                    if (backline) {
+                        hnm->current[writeoffset++] = hnm->previous[offset - (2 * hnm->width) + 1];
+                        hnm->current[writeoffset++] = hnm->previous[offset++];
+                        offset++;
+                    } else {
+                        hnm->current[writeoffset++] = hnm->previous[offset++];
+                        hnm->current[writeoffset++] = hnm->previous[offset++];
+                    }
+                    if (backward)
+                        offset -= 4;
+                    left--;
+                }
+            } else {
+                while (left > 0) {
+                    if (backline) {
+                        hnm->current[writeoffset++] = hnm->current[offset - (2 * hnm->width) + 1];
+                        hnm->current[writeoffset++] = hnm->current[offset++];
+                        offset++;
+                    } else {
+                        hnm->current[writeoffset++] = hnm->current[offset++];
+                        hnm->current[writeoffset++] = hnm->current[offset++];
+                    }
+                    if (backward)
+                        offset -= 4;
+                    left--;
+                }
+            }
+
+            if (swap) {
+                left         = count;
+                writeoffset -= count * 2;
+                while (left > 0) {
+                    swap = hnm->current[writeoffset];
+                    hnm->current[writeoffset] = hnm->current[writeoffset + 1];
+                    hnm->current[writeoffset + 1] = swap;
+                    left--;
+                    writeoffset += 2;
+                }
+            }
+        }
+    }
+}
+
+static void decode_interframe_v4a(AVCodecContext *avctx, uint8_t *src,
+                                  uint32_t size)
+{
+    Hnm4VideoContext *hnm = avctx->priv_data;
+    GetByteContext gb;
+    uint32_t writeoffset = 0, offset;
+    uint8_t tag, count, previous, delta;
+
+    bytestream2_init(&gb, src, size);
+
+    while (bytestream2_tell(&gb) < size) {
+        count = bytestream2_peek_byte(&gb) & 0x3F;
+        if (count == 0) {
+            tag = bytestream2_get_byte(&gb) & 0xC0;
+            tag = tag >> 6;
+            if (tag == 0) {
+                writeoffset += bytestream2_get_byte(&gb);
+            } else if (tag == 1) {
+                hnm->current[writeoffset]              = bytestream2_get_byte(&gb);
+                hnm->current[writeoffset + hnm->width] = bytestream2_get_byte(&gb);
+                writeoffset++;
+            } else if (tag == 2) {
+                writeoffset += hnm->width;
+            } else if (tag == 3) {
+                break;
+            }
+        } else {
+            delta    = bytestream2_peek_byte(&gb) & 0x80;
+            previous = bytestream2_peek_byte(&gb) & 0x40;
+            bytestream2_skip(&gb, 1);
+
+            offset  = writeoffset;
+            offset += bytestream2_get_le16(&gb);
+
+            if (delta)
+                offset -= 0x10000;
+
+            if (offset + hnm->width + count >= hnm->width * hnm->height) {
+                av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds");
+                break;
+            } else if (writeoffset + hnm->width + count >= hnm->width * hnm->height) {
+                av_log(avctx, AV_LOG_ERROR, "Attempting to write out of bounds");
+                break;
+            }
+
+            if (previous) {
+                while (count > 0) {
+                    hnm->current[writeoffset]              = hnm->previous[offset];
+                    hnm->current[writeoffset + hnm->width] = hnm->previous[offset + hnm->width];
+                    writeoffset++;
+                    offset++;
+                    count--;
+                }
+            } else {
+                while (count > 0) {
+                    hnm->current[writeoffset]              = hnm->current[offset];
+                    hnm->current[writeoffset + hnm->width] = hnm->current[offset + hnm->width];
+                    writeoffset++;
+                    offset++;
+                    count--;
+                }
+            }
+        }
+    }
+}
+
+static void hnm_update_palette(AVCodecContext *avctx, uint8_t *src,
+                               uint32_t size)
+{
+    Hnm4VideoContext *hnm = avctx->priv_data;
+    GetByteContext gb;
+    uint8_t start, writeoffset;
+    uint16_t count;
+    int eight_bit_colors;
+
+    eight_bit_colors = src[7] & 0x80 && hnm->version == 0x4a;
+
+    // skip first 8 bytes
+    bytestream2_init(&gb, src + 8, size - 8);
+
+    while (bytestream2_tell(&gb) < size - 8) {
+        start = bytestream2_get_byte(&gb);
+        count = bytestream2_get_byte(&gb);
+        if (start == 255 && count == 255)
+            break;
+        if (count == 0)
+            count = 256;
+        writeoffset = start;
+        while (count > 0) {
+            hnm->palette[writeoffset] = bytestream2_get_be24(&gb);
+            if (!eight_bit_colors)
+                hnm->palette[writeoffset] <<= 2;
+            count--;
+            writeoffset++;
+        }
+    }
+}
+
+static void hnm_flip_buffers(Hnm4VideoContext *hnm)
+{
+    uint8_t *temp;
+
+    temp          = hnm->current;
+    hnm->current  = hnm->previous;
+    hnm->previous = temp;
+}
+
+static int hnm_decode_frame(AVCodecContext *avctx, void *data,
+                            int *got_frame, AVPacket *avpkt)
+{
+    AVFrame *frame = data;
+    Hnm4VideoContext *hnm = avctx->priv_data;
+    int ret;
+    uint16_t chunk_id;
+
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+
+    chunk_id = AV_RL16(avpkt->data + 4);
+
+    if (chunk_id == HNM4_CHUNK_ID_PL) {
+        hnm_update_palette(avctx, avpkt->data, avpkt->size);
+        frame->palette_has_changed = 1;
+    } else if (chunk_id == HNM4_CHUNK_ID_IZ) {
+        unpack_intraframe(avctx, avpkt->data + 12, avpkt->size - 12);
+        memcpy(hnm->previous, hnm->current, hnm->width * hnm->height);
+        if (hnm->version == 0x4a)
+            memcpy(hnm->processed, hnm->current, hnm->width * hnm->height);
+        else
+            postprocess_current_frame(avctx);
+        copy_processed_frame(avctx, frame);
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        frame->key_frame = 1;
+        memcpy(frame->data[1], hnm->palette, 256 * 4);
+        *got_frame = 1;
+    } else if (chunk_id == HNM4_CHUNK_ID_IU) {
+        if (hnm->version == 0x4a) {
+            decode_interframe_v4a(avctx, avpkt->data + 8, avpkt->size - 8);
+            memcpy(hnm->processed, hnm->current, hnm->width * hnm->height);
+        } else {
+            decode_interframe_v4(avctx, avpkt->data + 8, avpkt->size - 8);
+            postprocess_current_frame(avctx);
+        }
+        copy_processed_frame(avctx, frame);
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
+        memcpy(frame->data[1], hnm->palette, 256 * 4);
+        *got_frame = 1;
+        hnm_flip_buffers(hnm);
+    } else {
+        av_log(avctx, AV_LOG_ERROR, "invalid chunk id: %d\n", chunk_id);
+        return AVERROR_INVALIDDATA;
+    }
+
+    return avpkt->size;
+}
+
+static av_cold int hnm_decode_init(AVCodecContext *avctx)
+{
+    Hnm4VideoContext *hnm = avctx->priv_data;
+
+    if (avctx->extradata_size < 1) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Extradata missing, decoder requires version number\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    hnm->version   = avctx->extradata[0];
+    avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    hnm->width     = avctx->width;
+    hnm->height    = avctx->height;
+    hnm->buffer1   = av_mallocz(avctx->width * avctx->height);
+    hnm->buffer2   = av_mallocz(avctx->width * avctx->height);
+    hnm->processed = av_mallocz(avctx->width * avctx->height);
+
+    if (!hnm->buffer1 || !hnm->buffer2 || !hnm->processed) {
+        av_log(avctx, AV_LOG_ERROR, "av_mallocz() failed\n");
+        av_freep(&hnm->buffer1);
+        av_freep(&hnm->buffer2);
+        av_freep(&hnm->processed);
+        return AVERROR(ENOMEM);
+    }
+
+    hnm->current  = hnm->buffer1;
+    hnm->previous = hnm->buffer2;
+
+    return 0;
+}
+
+static av_cold int hnm_decode_end(AVCodecContext *avctx)
+{
+    Hnm4VideoContext *hnm = avctx->priv_data;
+
+    av_freep(&hnm->buffer1);
+    av_freep(&hnm->buffer2);
+    av_freep(&hnm->processed);
+
+    return 0;
+}
+
+AVCodec ff_hnm4_video_decoder = {
+    .name           = "hnm4video",
+    .long_name      = NULL_IF_CONFIG_SMALL("HNM 4 video"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_HNM4_VIDEO,
+    .priv_data_size = sizeof(Hnm4VideoContext),
+    .init           = hnm_decode_init,
+    .close          = hnm_decode_end,
+    .decode         = hnm_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+};
diff --git a/libavcodec/hpel_template.c b/libavcodec/hpel_template.c
new file mode 100644
index 0000000..0c1f756
--- /dev/null
+++ b/libavcodec/hpel_template.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ */
+
+#define DEF_HPEL(OPNAME, OP) \
+static inline void FUNCC(OPNAME ## _pixels2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        OP(*((pixel2*)(block  )), AV_RN2P(pixels  ));\
+        pixels+=line_size;\
+        block +=line_size;\
+    }\
+}\
+static inline void FUNCC(OPNAME ## _pixels4)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        OP(*((pixel4*)(block  )), AV_RN4P(pixels  ));\
+        pixels+=line_size;\
+        block +=line_size;\
+    }\
+}\
+static inline void FUNCC(OPNAME ## _pixels8)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        OP(*((pixel4*)(block                )), AV_RN4P(pixels                ));\
+        OP(*((pixel4*)(block+4*sizeof(pixel))), AV_RN4P(pixels+4*sizeof(pixel)));\
+        pixels+=line_size;\
+        block +=line_size;\
+    }\
+}\
+\
+static inline void FUNC(OPNAME ## _pixels8_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        pixel4 a,b;\
+        a= AV_RN4P(&src1[i*src_stride1  ]);\
+        b= AV_RN4P(&src2[i*src_stride2  ]);\
+        OP(*((pixel4*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
+        a= AV_RN4P(&src1[i*src_stride1+4*sizeof(pixel)]);\
+        b= AV_RN4P(&src2[i*src_stride2+4*sizeof(pixel)]);\
+        OP(*((pixel4*)&dst[i*dst_stride+4*sizeof(pixel)]), rnd_avg_pixel4(a, b));\
+    }\
+}\
+\
+static inline void FUNC(OPNAME ## _pixels4_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        pixel4 a,b;\
+        a= AV_RN4P(&src1[i*src_stride1  ]);\
+        b= AV_RN4P(&src2[i*src_stride2  ]);\
+        OP(*((pixel4*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
+    }\
+}\
+\
+static inline void FUNC(OPNAME ## _pixels2_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        pixel4 a,b;\
+        a= AV_RN2P(&src1[i*src_stride1  ]);\
+        b= AV_RN2P(&src2[i*src_stride2  ]);\
+        OP(*((pixel2*)&dst[i*dst_stride  ]), rnd_avg_pixel4(a, b));\
+    }\
+}\
+\
+static inline void FUNC(OPNAME ## _pixels16_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    FUNC(OPNAME ## _pixels8_l2)(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
+    FUNC(OPNAME ## _pixels8_l2)(dst+8*sizeof(pixel), src1+8*sizeof(pixel), src2+8*sizeof(pixel), dst_stride, src_stride1, src_stride2, h);\
+}\
+\
+CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16)    , FUNCC(OPNAME ## _pixels8)    , 8*sizeof(pixel))
+
+
+#define op_avg(a, b) a = rnd_avg_pixel4(a, b)
+#define op_put(a, b) a = b
+
+DEF_HPEL(avg, op_avg)
+DEF_HPEL(put, op_put)
+#undef op_avg
+#undef op_put
diff --git a/libavcodec/hpeldsp.c b/libavcodec/hpeldsp.c
new file mode 100644
index 0000000..598f956
--- /dev/null
+++ b/libavcodec/hpeldsp.c
@@ -0,0 +1,67 @@
+/*
+ * Half-pel DSP functions.
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * Half-pel DSP functions.
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/intreadwrite.h"
+#include "hpeldsp.h"
+
+#define BIT_DEPTH 8
+#include "hpeldsp_template.c"
+
+av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags)
+{
+#define hpel_funcs(prefix, idx, num) \
+    c->prefix ## _pixels_tab idx [0] = prefix ## _pixels ## num ## _8_c; \
+    c->prefix ## _pixels_tab idx [1] = prefix ## _pixels ## num ## _x2_8_c; \
+    c->prefix ## _pixels_tab idx [2] = prefix ## _pixels ## num ## _y2_8_c; \
+    c->prefix ## _pixels_tab idx [3] = prefix ## _pixels ## num ## _xy2_8_c
+
+    hpel_funcs(put, [0], 16);
+    hpel_funcs(put, [1],  8);
+    hpel_funcs(put, [2],  4);
+    hpel_funcs(put, [3],  2);
+    hpel_funcs(put_no_rnd, [0], 16);
+    hpel_funcs(put_no_rnd, [1],  8);
+    hpel_funcs(avg, [0], 16);
+    hpel_funcs(avg, [1],  8);
+    hpel_funcs(avg, [2],  4);
+    hpel_funcs(avg, [3],  2);
+    hpel_funcs(avg_no_rnd,, 16);
+
+    if (ARCH_ARM)
+        ff_hpeldsp_init_arm(c, flags);
+    if (ARCH_BFIN)
+        ff_hpeldsp_init_bfin(c, flags);
+    if (ARCH_PPC)
+        ff_hpeldsp_init_ppc(c, flags);
+    if (HAVE_VIS)
+        ff_hpeldsp_init_vis(c, flags);
+    if (ARCH_X86)
+        ff_hpeldsp_init_x86(c, flags);
+}
diff --git a/libavcodec/hpeldsp.h b/libavcodec/hpeldsp.h
new file mode 100644
index 0000000..8501e3d
--- /dev/null
+++ b/libavcodec/hpeldsp.h
@@ -0,0 +1,103 @@
+/*
+ * Half-pel DSP functions.
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * Half-pel DSP functions.
+ */
+
+#ifndef AVCODEC_HPELDSP_H
+#define AVCODEC_HPELDSP_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+/* add and put pixel (decoding) */
+// blocksizes for hpel_pixels_func are 8x4,8x8 16x8 16x16
+// h for hpel_pixels_func is limited to {width/2, width} but never larger
+// than 16 and never smaller than 4
+typedef void (*op_pixels_func)(uint8_t *block /*align width (8 or 16)*/,
+                               const uint8_t *pixels /*align 1*/,
+                               ptrdiff_t line_size, int h);
+
+/**
+ * Half-pel DSP context.
+ */
+typedef struct HpelDSPContext {
+    /**
+     * Halfpel motion compensation with rounding (a+b+1)>>1.
+     * this is an array[4][4] of motion compensation functions for 4
+     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
+     * @param block destination where the result is stored
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+     */
+    op_pixels_func put_pixels_tab[4][4];
+
+    /**
+     * Halfpel motion compensation with rounding (a+b+1)>>1.
+     * This is an array[4][4] of motion compensation functions for 4
+     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
+     * @param block destination into which the result is averaged (a+b+1)>>1
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+     */
+    op_pixels_func avg_pixels_tab[4][4];
+
+    /**
+     * Halfpel motion compensation with no rounding (a+b)>>1.
+     * this is an array[2][4] of motion compensation functions for 2
+     * horizontal blocksizes (8,16) and the 4 halfpel positions<br>
+     * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
+     * @param block destination where the result is stored
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+     */
+    op_pixels_func put_no_rnd_pixels_tab[2][4];
+
+    /**
+     * Halfpel motion compensation with no rounding (a+b)>>1.
+     * this is an array[4] of motion compensation functions for 1
+     * horizontal blocksize (16) and the 4 halfpel positions<br>
+     * *pixels_tab[0][ xhalfpel + 2*yhalfpel ]
+     * @param block destination into which the result is averaged (a+b)>>1
+     * @param pixels source
+     * @param line_size number of bytes in a horizontal line of block
+     * @param h height
+     */
+    op_pixels_func avg_no_rnd_pixels_tab[4];
+} HpelDSPContext;
+
+void ff_hpeldsp_init(HpelDSPContext *c, int flags);
+
+void ff_hpeldsp_init_arm(HpelDSPContext *c, int flags);
+void ff_hpeldsp_init_bfin(HpelDSPContext *c, int flags);
+void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags);
+void ff_hpeldsp_init_vis(HpelDSPContext *c, int flags);
+void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags);
+
+#endif /* AVCODEC_HPELDSP_H */
diff --git a/libavcodec/hpeldsp_template.c b/libavcodec/hpeldsp_template.c
new file mode 100644
index 0000000..6518941
--- /dev/null
+++ b/libavcodec/hpeldsp_template.c
@@ -0,0 +1,254 @@
+/*
+ * Half-pel DSP functions.
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * Half-pel DSP functions.
+ */
+
+#include "bit_depth_template.c"
+
+#include "hpel_template.c"
+
+#define PIXOP2(OPNAME, OP) \
+static inline void FUNC(OPNAME ## _no_rnd_pixels8_l2)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
+                                                int src_stride1, int src_stride2, int h){\
+    int i;\
+    for(i=0; i<h; i++){\
+        pixel4 a,b;\
+        a= AV_RN4P(&src1[i*src_stride1  ]);\
+        b= AV_RN4P(&src2[i*src_stride2  ]);\
+        OP(*((pixel4*)&dst[i*dst_stride  ]), no_rnd_avg_pixel4(a, b));\
+        a= AV_RN4P(&src1[i*src_stride1+4*sizeof(pixel)]);\
+        b= AV_RN4P(&src2[i*src_stride2+4*sizeof(pixel)]);\
+        OP(*((pixel4*)&dst[i*dst_stride+4*sizeof(pixel)]), no_rnd_avg_pixel4(a, b));\
+    }\
+}\
+\
+static inline void FUNCC(OPNAME ## _no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
+}\
+\
+static inline void FUNCC(OPNAME ## _no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    FUNC(OPNAME ## _no_rnd_pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    FUNC(OPNAME ## _pixels8_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels4_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels4_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    FUNC(OPNAME ## _pixels4_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels2_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+sizeof(pixel), line_size, line_size, line_size, h);\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels2_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    FUNC(OPNAME ## _pixels2_l2)(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels2_xy2)(uint8_t *_block, const uint8_t *_pixels, ptrdiff_t line_size, int h)\
+{\
+        int i, a0, b0, a1, b1;\
+        pixel *block = (pixel*)_block;\
+        const pixel *pixels = (const pixel*)_pixels;\
+        line_size /= sizeof(pixel);\
+        a0= pixels[0];\
+        b0= pixels[1] + 2;\
+        a0 += b0;\
+        b0 += pixels[2];\
+\
+        pixels+=line_size;\
+        for(i=0; i<h; i+=2){\
+            a1= pixels[0];\
+            b1= pixels[1];\
+            a1 += b1;\
+            b1 += pixels[2];\
+\
+            block[0]= (a1+a0)>>2; /* FIXME non put */\
+            block[1]= (b1+b0)>>2;\
+\
+            pixels+=line_size;\
+            block +=line_size;\
+\
+            a0= pixels[0];\
+            b0= pixels[1] + 2;\
+            a0 += b0;\
+            b0 += pixels[2];\
+\
+            block[0]= (a1+a0)>>2;\
+            block[1]= (b1+b0)>>2;\
+            pixels+=line_size;\
+            block +=line_size;\
+        }\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels4_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
+{\
+        /* FIXME HIGH BIT DEPTH */\
+        int i;\
+        const uint32_t a= AV_RN32(pixels  );\
+        const uint32_t b= AV_RN32(pixels+1);\
+        uint32_t l0=  (a&0x03030303UL)\
+                    + (b&0x03030303UL)\
+                    + 0x02020202UL;\
+        uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\
+                   + ((b&0xFCFCFCFCUL)>>2);\
+        uint32_t l1,h1;\
+\
+        pixels+=line_size;\
+        for(i=0; i<h; i+=2){\
+            uint32_t a= AV_RN32(pixels  );\
+            uint32_t b= AV_RN32(pixels+1);\
+            l1=  (a&0x03030303UL)\
+               + (b&0x03030303UL);\
+            h1= ((a&0xFCFCFCFCUL)>>2)\
+              + ((b&0xFCFCFCFCUL)>>2);\
+            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
+            pixels+=line_size;\
+            block +=line_size;\
+            a= AV_RN32(pixels  );\
+            b= AV_RN32(pixels+1);\
+            l0=  (a&0x03030303UL)\
+               + (b&0x03030303UL)\
+               + 0x02020202UL;\
+            h0= ((a&0xFCFCFCFCUL)>>2)\
+              + ((b&0xFCFCFCFCUL)>>2);\
+            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
+            pixels+=line_size;\
+            block +=line_size;\
+        }\
+}\
+\
+static inline void FUNCC(OPNAME ## _pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
+{\
+    /* FIXME HIGH BIT DEPTH */\
+    int j;\
+    for(j=0; j<2; j++){\
+        int i;\
+        const uint32_t a= AV_RN32(pixels  );\
+        const uint32_t b= AV_RN32(pixels+1);\
+        uint32_t l0=  (a&0x03030303UL)\
+                    + (b&0x03030303UL)\
+                    + 0x02020202UL;\
+        uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\
+                   + ((b&0xFCFCFCFCUL)>>2);\
+        uint32_t l1,h1;\
+\
+        pixels+=line_size;\
+        for(i=0; i<h; i+=2){\
+            uint32_t a= AV_RN32(pixels  );\
+            uint32_t b= AV_RN32(pixels+1);\
+            l1=  (a&0x03030303UL)\
+               + (b&0x03030303UL);\
+            h1= ((a&0xFCFCFCFCUL)>>2)\
+              + ((b&0xFCFCFCFCUL)>>2);\
+            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
+            pixels+=line_size;\
+            block +=line_size;\
+            a= AV_RN32(pixels  );\
+            b= AV_RN32(pixels+1);\
+            l0=  (a&0x03030303UL)\
+               + (b&0x03030303UL)\
+               + 0x02020202UL;\
+            h0= ((a&0xFCFCFCFCUL)>>2)\
+              + ((b&0xFCFCFCFCUL)>>2);\
+            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
+            pixels+=line_size;\
+            block +=line_size;\
+        }\
+        pixels+=4-line_size*(h+1);\
+        block +=4-line_size*h;\
+    }\
+}\
+\
+static inline void FUNCC(OPNAME ## _no_rnd_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)\
+{\
+    /* FIXME HIGH BIT DEPTH */\
+    int j;\
+    for(j=0; j<2; j++){\
+        int i;\
+        const uint32_t a= AV_RN32(pixels  );\
+        const uint32_t b= AV_RN32(pixels+1);\
+        uint32_t l0=  (a&0x03030303UL)\
+                    + (b&0x03030303UL)\
+                    + 0x01010101UL;\
+        uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\
+                   + ((b&0xFCFCFCFCUL)>>2);\
+        uint32_t l1,h1;\
+\
+        pixels+=line_size;\
+        for(i=0; i<h; i+=2){\
+            uint32_t a= AV_RN32(pixels  );\
+            uint32_t b= AV_RN32(pixels+1);\
+            l1=  (a&0x03030303UL)\
+               + (b&0x03030303UL);\
+            h1= ((a&0xFCFCFCFCUL)>>2)\
+              + ((b&0xFCFCFCFCUL)>>2);\
+            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
+            pixels+=line_size;\
+            block +=line_size;\
+            a= AV_RN32(pixels  );\
+            b= AV_RN32(pixels+1);\
+            l0=  (a&0x03030303UL)\
+               + (b&0x03030303UL)\
+               + 0x01010101UL;\
+            h0= ((a&0xFCFCFCFCUL)>>2)\
+              + ((b&0xFCFCFCFCUL)>>2);\
+            OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\
+            pixels+=line_size;\
+            block +=line_size;\
+        }\
+        pixels+=4-line_size*(h+1);\
+        block +=4-line_size*h;\
+    }\
+}\
+\
+CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_x2) , FUNCC(OPNAME ## _pixels8_x2) , 8*sizeof(pixel))\
+CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_y2) , FUNCC(OPNAME ## _pixels8_y2) , 8*sizeof(pixel))\
+CALL_2X_PIXELS(FUNCC(OPNAME ## _pixels16_xy2), FUNCC(OPNAME ## _pixels8_xy2), 8*sizeof(pixel))\
+av_unused CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16)    , FUNCC(OPNAME ## _pixels8) , 8*sizeof(pixel))\
+CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_x2) , FUNCC(OPNAME ## _no_rnd_pixels8_x2) , 8*sizeof(pixel))\
+CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_y2) , FUNCC(OPNAME ## _no_rnd_pixels8_y2) , 8*sizeof(pixel))\
+CALL_2X_PIXELS(FUNCC(OPNAME ## _no_rnd_pixels16_xy2), FUNCC(OPNAME ## _no_rnd_pixels8_xy2), 8*sizeof(pixel))\
+
+#define op_avg(a, b) a = rnd_avg_pixel4(a, b)
+#define op_put(a, b) a = b
+#if BIT_DEPTH == 8
+#define put_no_rnd_pixels8_8_c put_pixels8_8_c
+PIXOP2(avg, op_avg)
+PIXOP2(put, op_put)
+#endif
+#undef op_avg
+#undef op_put
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c
index aef4929..dec2197 100644
--- a/libavcodec/huffman.c
+++ b/libavcodec/huffman.c
@@ -24,6 +24,8 @@
  * huffman tree builder and VLC generator
  */
 
+#include <stdint.h>
+
 #include "avcodec.h"
 #include "get_bits.h"
 #include "huffman.h"
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index 58559f1..d4cf6fa 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -33,7 +33,6 @@
 #include "libavutil/mem.h"
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "huffyuv.h"
 
 int ff_huffyuv_generate_bits_table(uint32_t *dst, const uint8_t *len_table)
diff --git a/libavcodec/huffyuv.h b/libavcodec/huffyuv.h
index c464d83..9c875d5 100644
--- a/libavcodec/huffyuv.h
+++ b/libavcodec/huffyuv.h
@@ -78,7 +78,6 @@ typedef struct HYuvContext {
     uint32_t bits[3][256];
     uint32_t pix_bgr_map[1<<VLC_BITS];
     VLC vlc[6];                             //Y,U,V,YY,YU,YV
-    AVFrame picture;
     uint8_t *bitstream_buffer;
     unsigned int bitstream_buffer_size;
     DSPContext dsp;
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c
index 0946d3d..ed490d4 100644
--- a/libavcodec/huffyuvdec.c
+++ b/libavcodec/huffyuvdec.c
@@ -29,7 +29,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
 #include "huffyuv.h"
 #include "thread.h"
@@ -242,7 +241,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     ff_huffyuv_common_init(avctx);
     memset(s->vlc, 0, 3 * sizeof(VLC));
 
-    avctx->coded_frame = &s->picture;
     s->interlaced = s->height > 288;
 
     s->bgr32 = 1;
@@ -338,7 +336,6 @@ static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
     HYuvContext *s = avctx->priv_data;
     int i;
 
-    avctx->coded_frame= &s->picture;
     ff_huffyuv_alloc_temp(s);
 
     for (i = 0; i < 6; i++)
@@ -444,7 +441,7 @@ static void decode_bgr_bitstream(HYuvContext *s, int count)
     }
 }
 
-static void draw_slice(HYuvContext *s, int y)
+static void draw_slice(HYuvContext *s, AVFrame *frame, int y)
 {
     int h, cy, i;
     int offset[AV_NUM_DATA_POINTERS];
@@ -461,14 +458,14 @@ static void draw_slice(HYuvContext *s, int y)
         cy = y;
     }
 
-    offset[0] = s->picture.linesize[0]*y;
-    offset[1] = s->picture.linesize[1]*cy;
-    offset[2] = s->picture.linesize[2]*cy;
+    offset[0] = frame->linesize[0] * y;
+    offset[1] = frame->linesize[1] * cy;
+    offset[2] = frame->linesize[2] * cy;
     for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
         offset[i] = 0;
     emms_c();
 
-    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
+    s->avctx->draw_horiz_band(s->avctx, frame, offset, y, 3, h);
 
     s->last_slice_end = y + h;
 }
@@ -483,11 +480,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     const int width2 = s->width>>1;
     const int height = s->height;
     int fake_ystride, fake_ustride, fake_vstride;
-    AVFrame * const p = &s->picture;
+    ThreadFrame frame = { .f = data };
+    AVFrame * const p = data;
     int table_size = 0;
 
-    AVFrame *picture = data;
-
     av_fast_malloc(&s->bitstream_buffer,
                    &s->bitstream_buffer_size,
                    buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -498,11 +494,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer,
                      (const uint32_t*)buf, buf_size / 4);
 
-    if (p->data[0])
-        ff_thread_release_buffer(avctx, p);
-
-    p->reference = 0;
-    if (ff_thread_get_buffer(avctx, p) < 0) {
+    if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -573,7 +565,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         if (y >= s->height) break;
                     }
 
-                    draw_slice(s, y);
+                    draw_slice(s, p, y);
 
                     ydst = p->data[0] + p->linesize[0]*y;
                     udst = p->data[1] + p->linesize[1]*cy;
@@ -595,7 +587,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         }
                     }
                 }
-                draw_slice(s, height);
+                draw_slice(s, p, height);
 
                 break;
             case MEDIAN:
@@ -652,7 +644,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         }
                         if (y >= height) break;
                     }
-                    draw_slice(s, y);
+                    draw_slice(s, p, y);
 
                     decode_422_bitstream(s, width);
 
@@ -667,7 +659,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                     }
                 }
 
-                draw_slice(s, height);
+                draw_slice(s, p, height);
                 break;
             }
         }
@@ -711,7 +703,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                     }
                 }
                 // just 1 large slice as this is not possible in reverse order
-                draw_slice(s, height);
+                draw_slice(s, p, height);
                 break;
             default:
                 av_log(avctx, AV_LOG_ERROR,
@@ -725,7 +717,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
     emms_c();
 
-    *picture = *p;
     *got_frame = 1;
 
     return (get_bits_count(&s->gb) + 31) / 32 * 4 + table_size;
@@ -736,9 +727,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
     HYuvContext *s = avctx->priv_data;
     int i;
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
     ff_huffyuv_common_end(s);
     av_freep(&s->bitstream_buffer);
 
@@ -752,6 +740,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 #if CONFIG_HUFFYUV_DECODER
 AVCodec ff_huffyuv_decoder = {
     .name             = "huffyuv",
+    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
     .type             = AVMEDIA_TYPE_VIDEO,
     .id               = AV_CODEC_ID_HUFFYUV,
     .priv_data_size   = sizeof(HYuvContext),
@@ -761,13 +750,13 @@ AVCodec ff_huffyuv_decoder = {
     .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
                         CODEC_CAP_FRAME_THREADS,
     .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
-    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
 };
 #endif
 
 #if CONFIG_FFVHUFF_DECODER
 AVCodec ff_ffvhuff_decoder = {
     .name             = "ffvhuff",
+    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
     .type             = AVMEDIA_TYPE_VIDEO,
     .id               = AV_CODEC_ID_FFVHUFF,
     .priv_data_size   = sizeof(HYuvContext),
@@ -777,6 +766,5 @@ AVCodec ff_ffvhuff_decoder = {
     .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
                         CODEC_CAP_FRAME_THREADS,
     .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
-    .long_name        = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
 };
 #endif
diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c
index 13c0a79..ec07abd 100644
--- a/libavcodec/huffyuvenc.c
+++ b/libavcodec/huffyuvenc.c
@@ -55,24 +55,29 @@ static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst,
 
 static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst,
                                              uint8_t *src, int w,
-                                             int *red, int *green, int *blue)
+                                             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);
@@ -80,6 +85,35 @@ static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst,
     *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,
+                                             uint8_t *src, int w,
+                                             int *red, int *green, int *blue)
+{
+    int i;
+    int r, g, b;
+    r = *red;
+    g = *green;
+    b = *blue;
+    for (i = 0; i < FFMIN(w, 16); i++) {
+        const int rt = src[i * 3 + 0];
+        const int gt = src[i * 3 + 1];
+        const int bt = src[i * 3 + 2];
+        dst[i * 3 + 0] = rt - r;
+        dst[i * 3 + 1] = gt - g;
+        dst[i * 3 + 2] = bt - b;
+        r = rt;
+        g = gt;
+        b = bt;
+    }
+
+    s->dsp.diff_bytes(dst + 48, src + 48, src + 48 - 3, w * 3 - 48);
+
+    *red   = src[(w - 1) * 3 + 0];
+    *green = src[(w - 1) * 3 + 1];
+    *blue  = src[(w - 1) * 3 + 2];
 }
 
 static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
@@ -117,16 +151,26 @@ static av_cold int encode_init(AVCodecContext *avctx)
     avctx->stats_out = av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
     s->version = 2;
 
-    avctx->coded_frame = &s->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
 
     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 -1;
+        }
+        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:
@@ -338,44 +382,52 @@ static int encode_gray_bitstream(HYuvContext *s, int count)
     return 0;
 }
 
-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;
-#define STAT3\
-            s->stats[0][b]++;\
-            s->stats[1][g]++;\
-            s->stats[2][r]++;
-#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]);
+#define LOAD_GBRA                                                       \
+    int g = s->temp[0][planes == 3 ? 3 * i + 1 : 4 * i + G];            \
+    int b = s->temp[0][planes == 3 ? 3 * i + 2 : 4 * i + B] - g & 0xFF; \
+    int r = s->temp[0][planes == 3 ? 3 * i + 0 : 4 * i + R] - g & 0xFF; \
+    int a = s->temp[0][planes * i + A];
+
+#define STAT_BGRA                                                       \
+    s->stats[0][b]++;                                                   \
+    s->stats[1][g]++;                                                   \
+    s->stats[2][r]++;                                                   \
+    if (planes == 4)                                                    \
+        s->stats[2][a]++;
+
+#define WRITE_GBRA                                                      \
+    put_bits(&s->pb, s->len[1][g], s->bits[1][g]);                      \
+    put_bits(&s->pb, s->len[0][b], s->bits[0][b]);                      \
+    put_bits(&s->pb, s->len[2][r], s->bits[2][r]);                      \
+    if (planes == 4)                                                    \
+        put_bits(&s->pb, s->len[2][a], s->bits[2][a]);
 
     if ((s->flags & CODEC_FLAG_PASS1) &&
         (s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)) {
         for (i = 0; i < count; i++) {
-            LOAD3;
-            STAT3;
+            LOAD_GBRA;
+            STAT_BGRA;
         }
     } else if (s->context || (s->flags & CODEC_FLAG_PASS1)) {
         for (i = 0; i < count; i++) {
-            LOAD3;
-            STAT3;
-            WRITE3;
+            LOAD_GBRA;
+            STAT_BGRA;
+            WRITE_GBRA;
         }
     } else {
         for (i = 0; i < count; i++) {
-            LOAD3;
-            WRITE3;
+            LOAD_GBRA;
+            WRITE_GBRA;
         }
     }
     return 0;
@@ -391,7 +443,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     const int fake_ystride = s->interlaced ? pict->linesize[0]*2  : pict->linesize[0];
     const int fake_ustride = s->interlaced ? pict->linesize[1]*2  : pict->linesize[1];
     const int fake_vstride = s->interlaced ? pict->linesize[2]*2  : pict->linesize[2];
-    AVFrame * const p = &s->picture;
+    const AVFrame * const p = pict;
     int i, j, size = 0, ret;
 
     if (!pkt->data &&
@@ -400,10 +452,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         return ret;
     }
 
-    *p = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
-
     if (s->context) {
         for (i = 0; i < 3; i++) {
             ff_huff_gen_len_table(s->len[i], s->stats[i]);
@@ -529,25 +577,57 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         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");
@@ -597,12 +677,15 @@ static av_cold int encode_end(AVCodecContext *avctx)
     av_freep(&avctx->extradata);
     av_freep(&avctx->stats_out);
 
+    av_frame_free(&avctx->coded_frame);
+
     return 0;
 }
 
 #if CONFIG_HUFFYUV_ENCODER
 AVCodec ff_huffyuv_encoder = {
     .name           = "huffyuv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_HUFFYUV,
     .priv_data_size = sizeof(HYuvContext),
@@ -610,15 +693,16 @@ AVCodec ff_huffyuv_encoder = {
     .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"),
 };
 #endif
 
 #if CONFIG_FFVHUFF_ENCODER
 AVCodec ff_ffvhuff_encoder = {
     .name           = "ffvhuff",
+    .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FFVHUFF,
     .priv_data_size = sizeof(HYuvContext),
@@ -626,8 +710,8 @@ AVCodec ff_ffvhuff_encoder = {
     .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"),
 };
 #endif
diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c
index 273eca6..70c98d6 100644
--- a/libavcodec/idcinvideo.c
+++ b/libavcodec/idcinvideo.c
@@ -66,7 +66,6 @@ typedef struct
 typedef struct IdcinContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
 
     const unsigned char *buf;
     int size;
@@ -168,12 +167,10 @@ static av_cold int idcin_decode_init(AVCodecContext *avctx)
         huff_build_tree(s, i);
     }
 
-    s->frame.data[0] = NULL;
-
     return 0;
 }
 
-static void idcin_decode_vlcs(IdcinContext *s)
+static void idcin_decode_vlcs(IdcinContext *s, AVFrame *frame)
 {
     hnode *hnodes;
     long x, y;
@@ -182,8 +179,8 @@ static void idcin_decode_vlcs(IdcinContext *s)
     int bit_pos, node_num, dat_pos;
 
     prev = bit_pos = dat_pos = 0;
-    for (y = 0; y < (s->frame.linesize[0] * s->avctx->height);
-        y += s->frame.linesize[0]) {
+    for (y = 0; y < (frame->linesize[0] * s->avctx->height);
+        y += frame->linesize[0]) {
         for (x = y; x < y + s->avctx->width; x++) {
             node_num = s->num_huff_nodes[prev];
             hnodes = s->huff_nodes[prev];
@@ -203,7 +200,7 @@ static void idcin_decode_vlcs(IdcinContext *s)
                 bit_pos--;
             }
 
-            s->frame.data[0][x] = node_num;
+            frame->data[0][x] = node_num;
             prev = node_num;
         }
     }
@@ -217,52 +214,39 @@ static int idcin_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     IdcinContext *s = avctx->priv_data;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
+    AVFrame *frame = data;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    if (ff_get_buffer(avctx, &s->frame)) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "  id CIN Video: get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    idcin_decode_vlcs(s);
+    idcin_decode_vlcs(s, frame);
 
     if (pal) {
-        s->frame.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
         memcpy(s->pal, pal, AVPALETTE_SIZE);
     }
     /* make the palette available on the way out */
-    memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+    memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
 }
 
-static av_cold int idcin_decode_end(AVCodecContext *avctx)
-{
-    IdcinContext *s = avctx->priv_data;
-
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    return 0;
-}
-
 AVCodec ff_idcin_decoder = {
     .name           = "idcinvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("id Quake II CIN video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_IDCIN,
     .priv_data_size = sizeof(IdcinContext),
     .init           = idcin_decode_init,
-    .close          = idcin_decode_end,
     .decode         = idcin_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("id Quake II CIN video"),
 };
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index b7a7bb3..112c2ca 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -25,6 +25,8 @@
  * IFF PBM/ILBM bitmap decoder
  */
 
+#include <stdint.h>
+
 #include "libavutil/imgutils.h"
 #include "bytestream.h"
 #include "avcodec.h"
@@ -32,7 +34,7 @@
 #include "internal.h"
 
 typedef struct {
-    AVFrame frame;
+    AVFrame *frame;
     int planesize;
     uint8_t * planebuf;
     int init; // 1 if buffer and palette data already initialized, 0 otherwise
@@ -120,7 +122,7 @@ static av_always_inline uint32_t gray2rgb(const uint32_t x) {
 /**
  * Convert CMAP buffer (stored in extradata) to lavc palette format
  */
-static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
+static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
 {
     int count, i;
 
@@ -133,19 +135,25 @@ static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
     // If extradata is smaller than actually needed, fill the remaining with black.
     count = FFMIN(avctx->extradata_size / 3, count);
     if (count) {
-        for (i=0; i < count; i++) {
-            pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
-        }
+        for (i = 0; i < count; i++)
+            pal[i] = 0xFF000000 | AV_RB24(avctx->extradata + i * 3);
     } else { // Create gray-scale color palette for bps < 8
         count = 1 << avctx->bits_per_coded_sample;
 
-        for (i=0; i < count; i++) {
+        for (i = 0; i < count; i++)
             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
-        }
     }
     return 0;
 }
 
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+    IffContext *s = avctx->priv_data;
+    av_frame_free(&s->frame);
+    av_freep(&s->planebuf);
+    return 0;
+}
+
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     IffContext *s = avctx->priv_data;
@@ -164,11 +172,15 @@ static av_cold int decode_init(AVCodecContext *avctx)
     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
         return err;
     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
-    s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
+    s->planebuf  = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!s->planebuf)
         return AVERROR(ENOMEM);
 
-    s->frame.reference = 1;
+    s->frame = av_frame_alloc();
+    if (!s->frame) {
+        decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
     return 0;
 }
@@ -206,12 +218,12 @@ static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int p
         dst[1] |= lut[mask++];
         dst[2] |= lut[mask++];
         dst[3] |= lut[mask];
-        mask = (*buf++ << 2) & 0x3F;
+        mask    = (*buf++ << 2) & 0x3F;
         dst[4] |= lut[mask++];
         dst[5] |= lut[mask++];
         dst[6] |= lut[mask++];
         dst[7] |= lut[mask];
-        dst += 8;
+        dst    += 8;
     } while (--buf_size);
 }
 
@@ -223,9 +235,10 @@ static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int p
  * @param buf the source byterun1 compressed bitstream
  * @param buf_end the EOF of source byterun1 compressed bitstream
  * @return number of consumed bytes in byterun1 compressed bitstream
-*/
+ */
 static int decode_byterun(uint8_t *dst, int dst_size,
-                          const uint8_t *buf, const uint8_t *const buf_end) {
+                          const uint8_t *buf, const uint8_t *const buf_end)
+{
     const uint8_t *const buf_start = buf;
     unsigned x;
     for (x = 0; x < dst_size && buf < buf_end;) {
@@ -247,129 +260,122 @@ static int decode_byterun(uint8_t *dst, int dst_size,
 }
 
 static int decode_frame_ilbm(AVCodecContext *avctx,
-                            void *data, int *got_frame,
-                            AVPacket *avpkt)
+                             void *data, int *got_frame,
+                             AVPacket *avpkt)
 {
-    IffContext *s = avctx->priv_data;
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    const uint8_t *buf_end = buf+buf_size;
+    IffContext *s          = avctx->priv_data;
+    const uint8_t *buf     = avpkt->data;
+    int buf_size           = avpkt->size;
+    const uint8_t *buf_end = buf + buf_size;
     int y, plane, res;
 
-    if (s->init) {
-        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return res;
-        }
-    } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+    if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
         return res;
-    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
-        if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
+
+    if (!s->init && avctx->bits_per_coded_sample <= 8 &&
+        avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
+        if ((res = 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('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 && buf < buf_end; y++ ) {
-                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+            for (y = 0; y < avctx->height; y++) {
+                uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                 memset(row, 0, avctx->width);
-                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
+                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end;
+                     plane++) {
                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
                     buf += s->planesize;
                 }
             }
         } else { // AV_PIX_FMT_BGR32
-            for(y = 0; y < avctx->height; y++ ) {
-                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+            for (y = 0; y < avctx->height; y++) {
+                uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                 memset(row, 0, avctx->width << 2);
-                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
-                    decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
+                for (plane = 0; plane < avctx->bits_per_coded_sample && 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]];
+        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(avctx->width, buf_end - buf));
             buf += avctx->width + (avctx->width % 2); // padding if odd
         }
     }
 
+    if ((res = av_frame_ref(data, s->frame)) < 0)
+        return res;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+
     return buf_size;
 }
 
 static int decode_frame_byterun1(AVCodecContext *avctx,
-                            void *data, int *got_frame,
-                            AVPacket *avpkt)
+                                 void *data, int *got_frame,
+                                 AVPacket *avpkt)
 {
-    IffContext *s = avctx->priv_data;
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    const uint8_t *buf_end = buf+buf_size;
+    IffContext *s          = avctx->priv_data;
+    const uint8_t *buf     = avpkt->data;
+    int buf_size           = avpkt->size;
+    const uint8_t *buf_end = buf + buf_size;
     int y, plane, res;
 
-    if (s->init) {
-        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return res;
-        }
-    } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+    if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
         return res;
-    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
-        if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
+
+    if (!s->init && avctx->bits_per_coded_sample <= 8 &&
+        avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
+        if ((res = 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('I', 'L', 'B', 'M')) { // interleaved
         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
-            for(y = 0; y < avctx->height ; y++ ) {
-                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+            for (y = 0; y < avctx->height; y++) {
+                uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                 memset(row, 0, avctx->width);
                 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
                     decodeplane8(row, s->planebuf, s->planesize, plane);
                 }
             }
-        } else { //AV_PIX_FMT_BGR32
-            for(y = 0; y < avctx->height ; y++ ) {
-                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+        } else { // AV_PIX_FMT_BGR32
+            for (y = 0; y < avctx->height; y++) {
+                uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                 memset(row, 0, avctx->width << 2);
                 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
-                    decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
+                    decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
                 }
             }
         }
     } else {
-        for(y = 0; y < avctx->height ; y++ ) {
-            uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+        for (y = 0; y < avctx->height; y++) {
+            uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
             buf += decode_byterun(row, avctx->width, buf, buf_end);
         }
     }
 
+    if ((res = av_frame_ref(data, s->frame)) < 0)
+        return res;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
-    return buf_size;
-}
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    IffContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-    av_freep(&s->planebuf);
-    return 0;
+    return buf_size;
 }
 
 AVCodec ff_iff_ilbm_decoder = {
     .name           = "iff_ilbm",
+    .long_name      = NULL_IF_CONFIG_SMALL("IFF ILBM"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_IFF_ILBM,
     .priv_data_size = sizeof(IffContext),
@@ -377,11 +383,11 @@ AVCodec ff_iff_ilbm_decoder = {
     .close          = decode_end,
     .decode         = decode_frame_ilbm,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("IFF ILBM"),
 };
 
 AVCodec ff_iff_byterun1_decoder = {
     .name           = "iff_byterun1",
+    .long_name      = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_IFF_BYTERUN1,
     .priv_data_size = sizeof(IffContext),
@@ -389,5 +395,4 @@ AVCodec ff_iff_byterun1_decoder = {
     .close          = decode_end,
     .decode         = decode_frame_byterun1,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
 };
diff --git a/libavcodec/iirfilter.c b/libavcodec/iirfilter.c
index acfa904..40a543d 100644
--- a/libavcodec/iirfilter.c
+++ b/libavcodec/iirfilter.c
@@ -26,6 +26,7 @@
 
 #include "iirfilter.h"
 #include <math.h>
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 
 /**
@@ -48,10 +49,11 @@ typedef struct FFIIRFilterState{
 /// maximum supported filter order
 #define MAXORDER 30
 
-static int butterworth_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c,
-                                   enum IIRFilterMode filt_mode,
-                                   int order, float cutoff_ratio,
-                                   float stopband)
+static av_cold int butterworth_init_coeffs(void *avc,
+                                           struct FFIIRFilterCoeffs *c,
+                                           enum IIRFilterMode filt_mode,
+                                           int order, float cutoff_ratio,
+                                           float stopband)
 {
     int i, j;
     double wa;
@@ -113,9 +115,9 @@ static int butterworth_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c,
     return 0;
 }
 
-static int biquad_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c,
-                              enum IIRFilterMode filt_mode, int order,
-                              float cutoff_ratio, float stopband)
+static av_cold int biquad_init_coeffs(void *avc, struct FFIIRFilterCoeffs *c,
+                                      enum IIRFilterMode filt_mode, int order,
+                                      float cutoff_ratio, float stopband)
 {
     double cos_w0, sin_w0;
     double a0, x0, x1;
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index 316dd77..c1fbd76 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -36,6 +36,8 @@
 #include <stdio.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
@@ -78,8 +80,6 @@ typedef struct IMCChannel {
 } IMCChannel;
 
 typedef struct {
-    AVFrame frame;
-
     IMCChannel chctx[2];
 
     /** MDCT tables */
@@ -95,10 +95,13 @@ typedef struct {
     GetBitContext gb;
 
     DSPContext dsp;
+    AVFloatDSPContext fdsp;
     FFTContext fft;
     DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2];
     float *out_samples;
 
+    int coef0_pos;
+
     int8_t cyclTab[32], cyclTab2[32];
     float  weights1[31], weights2[31];
 } IMCContext;
@@ -180,7 +183,7 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
         avctx->channels = 1;
 
     if (avctx->channels > 2) {
-        av_log_ask_for_sample(avctx, "Number of channels is not supported\n");
+        avpriv_request_sample(avctx, "Number of channels > 2");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -244,13 +247,11 @@ static av_cold int imc_decode_init(AVCodecContext *avctx)
         return ret;
     }
     ff_dsputil_init(&q->dsp, avctx);
+    avpriv_float_dsp_init(&q->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLTP;
     avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
                                                  : AV_CH_LAYOUT_STEREO;
 
-    avcodec_get_frame_defaults(&q->frame);
-    avctx->coded_frame = &q->frame;
-
     return 0;
 }
 
@@ -337,6 +338,17 @@ static void imc_read_level_coeffs(IMCContext *q, int stream_format_code,
     }
 }
 
+static void imc_read_level_coeffs_raw(IMCContext *q, int stream_format_code,
+                                      int *levlCoeffs)
+{
+    int i;
+
+    q->coef0_pos  = get_bits(&q->gb, 5);
+    levlCoeffs[0] = get_bits(&q->gb, 7);
+    for (i = 1; i < BANDS; i++)
+        levlCoeffs[i] = get_bits(&q->gb, 4);
+}
+
 static void imc_decode_level_coefficients(IMCContext *q, int *levlCoeffBuf,
                                           float *flcoeffs1, float *flcoeffs2)
 {
@@ -391,6 +403,28 @@ static void imc_decode_level_coefficients2(IMCContext *q, int *levlCoeffBuf,
     }
 }
 
+static void imc_decode_level_coefficients_raw(IMCContext *q, int *levlCoeffBuf,
+                                              float *flcoeffs1, float *flcoeffs2)
+{
+    int i, level, pos;
+    float tmp, tmp2;
+
+    pos = q->coef0_pos;
+    flcoeffs1[pos] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
+    flcoeffs2[pos] = log2f(flcoeffs1[0]);
+    tmp  = flcoeffs1[pos];
+    tmp2 = flcoeffs2[pos];
+
+    levlCoeffBuf++;
+    for (i = 0; i < BANDS; i++) {
+        if (i == pos)
+            continue;
+        level = *levlCoeffBuf++;
+        flcoeffs1[i] = tmp  * powf(10.0, -level * 0.4375); //todo tab
+        flcoeffs2[i] = tmp2 - 1.4533435415 * level; // 1.4533435415 = log2(10) * 0.4375
+    }
+}
+
 /**
  * Perform bit allocation depending on bits available
  */
@@ -763,12 +797,56 @@ static int imc_get_coeffs(IMCContext *q, IMCChannel *chctx)
     return 0;
 }
 
+static void imc_refine_bit_allocation(IMCContext *q, IMCChannel *chctx)
+{
+    int i, j;
+    int bits, summer;
+
+    for (i = 0; i < BANDS; i++) {
+        chctx->sumLenArr[i]   = 0;
+        chctx->skipFlagRaw[i] = 0;
+        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
+            chctx->sumLenArr[i] += chctx->CWlengthT[j];
+        if (chctx->bandFlagsBuf[i])
+            if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
+                chctx->skipFlagRaw[i] = 1;
+    }
+
+    imc_get_skip_coeff(q, chctx);
+
+    for (i = 0; i < BANDS; i++) {
+        chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
+        /* band has flag set and at least one coded coefficient */
+        if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
+            chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
+                                   q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
+        }
+    }
+
+    /* calculate bits left, bits needed and adjust bit allocation */
+    bits = summer = 0;
+
+    for (i = 0; i < BANDS; i++) {
+        if (chctx->bandFlagsBuf[i]) {
+            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
+                if (chctx->skipFlags[j]) {
+                    summer += chctx->CWlengthT[j];
+                    chctx->CWlengthT[j] = 0;
+                }
+            }
+            bits   += chctx->skipFlagBits[i];
+            summer -= chctx->skipFlagBits[i];
+        }
+    }
+    imc_adjust_bit_allocation(q, chctx, summer);
+}
+
 static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
 {
     int stream_format_code;
     int imc_hdr, i, j, ret;
     int flag;
-    int bits, summer;
+    int bits;
     int counter, bitscount;
     IMCChannel *chctx = q->chctx + ch;
 
@@ -782,12 +860,6 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
     }
     stream_format_code = get_bits(&q->gb, 3);
 
-    if (stream_format_code & 1) {
-        av_log_ask_for_sample(avctx, "Stream format %X is not supported\n",
-                              stream_format_code);
-        return AVERROR_PATCHWELCOME;
-    }
-
     if (stream_format_code & 0x04)
         chctx->decoder_reset = 1;
 
@@ -800,7 +872,13 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
     }
 
     flag = get_bits1(&q->gb);
-    imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
+    if (stream_format_code & 0x1)
+        imc_decode_level_coefficients_raw(q, chctx->levlCoeffBuf,
+                                          chctx->flcoeffs1, chctx->flcoeffs2);
+    else if (stream_format_code & 0x1)
+        imc_read_level_coeffs_raw(q, stream_format_code, chctx->levlCoeffBuf);
+    else
+        imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
 
     if (stream_format_code & 0x4)
         imc_decode_level_coefficients(q, chctx->levlCoeffBuf,
@@ -812,20 +890,31 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
     memcpy(chctx->old_floor, chctx->flcoeffs1, 32 * sizeof(float));
 
     counter = 0;
-    for (i = 0; i < BANDS; i++) {
-        if (chctx->levlCoeffBuf[i] == 16) {
-            chctx->bandWidthT[i] = 0;
-            counter++;
-        } else
-            chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
-    }
-    memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
-    for (i = 0; i < BANDS - 1; i++) {
-        if (chctx->bandWidthT[i])
-            chctx->bandFlagsBuf[i] = get_bits1(&q->gb);
-    }
+    if (stream_format_code & 0x1) {
+        for (i = 0; i < BANDS; i++) {
+            chctx->bandWidthT[i]   = band_tab[i + 1] - band_tab[i];
+            chctx->bandFlagsBuf[i] = 0;
+            chctx->flcoeffs3[i]    = chctx->flcoeffs2[i] * 2;
+            chctx->flcoeffs5[i]    = 1.0;
+        }
+    } else {
+        for (i = 0; i < BANDS; i++) {
+            if (chctx->levlCoeffBuf[i] == 16) {
+                chctx->bandWidthT[i] = 0;
+                counter++;
+            } else
+                chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
+        }
+
+        memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
+        for (i = 0; i < BANDS - 1; i++)
+            if (chctx->bandWidthT[i])
+                chctx->bandFlagsBuf[i] = get_bits1(&q->gb);
 
-    imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, chctx->bandWidthT, chctx->flcoeffs3, chctx->flcoeffs5);
+        imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2,
+                             chctx->bandWidthT, chctx->flcoeffs3,
+                             chctx->flcoeffs5);
+    }
 
     bitscount = 0;
     /* first 4 bands will be assigned 5 bits per coefficient */
@@ -837,7 +926,10 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
         chctx->CWlengthT[1] = 5;
         chctx->CWlengthT[2] = 5;
         for (i = 1; i < 4; i++) {
-            bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
+            if (stream_format_code & 0x1)
+                bits = 5;
+            else
+                bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
             chctx->bitsBandT[i] = bits;
             for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
                 chctx->CWlengthT[j] = bits;
@@ -859,43 +951,12 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
         return ret;
     }
 
-    for (i = 0; i < BANDS; i++) {
-        chctx->sumLenArr[i]   = 0;
-        chctx->skipFlagRaw[i] = 0;
-        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
-            chctx->sumLenArr[i] += chctx->CWlengthT[j];
-        if (chctx->bandFlagsBuf[i])
-            if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
-                chctx->skipFlagRaw[i] = 1;
-    }
-
-    imc_get_skip_coeff(q, chctx);
-
-    for (i = 0; i < BANDS; i++) {
-        chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
-        /* band has flag set and at least one coded coefficient */
-        if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
-            chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
-                                   q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
-        }
-    }
-
-    /* calculate bits left, bits needed and adjust bit allocation */
-    bits = summer = 0;
-
-    for (i = 0; i < BANDS; i++) {
-        if (chctx->bandFlagsBuf[i]) {
-            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
-                if (chctx->skipFlags[j]) {
-                    summer += chctx->CWlengthT[j];
-                    chctx->CWlengthT[j] = 0;
-                }
-            }
-            bits   += chctx->skipFlagBits[i];
-            summer -= chctx->skipFlagBits[i];
-        }
+    if (stream_format_code & 0x1) {
+        for (i = 0; i < BANDS; i++)
+            chctx->skipFlags[i] = 0;
+    } else {
+        imc_refine_bit_allocation(q, chctx);
     }
-    imc_adjust_bit_allocation(q, chctx, summer);
 
     for (i = 0; i < BANDS; i++) {
         chctx->sumLenArr[i] = 0;
@@ -929,6 +990,7 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
 static int imc_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     int ret, i;
@@ -943,14 +1005,14 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    q->frame.nb_samples = COEFFS;
-    if ((ret = ff_get_buffer(avctx, &q->frame)) < 0) {
+    frame->nb_samples = COEFFS;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     for (i = 0; i < avctx->channels; i++) {
-        q->out_samples = (float *)q->frame.extended_data[i];
+        q->out_samples = (float *)frame->extended_data[i];
 
         q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2);
 
@@ -963,12 +1025,11 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     if (avctx->channels == 2) {
-        q->dsp.butterflies_float((float *)q->frame.extended_data[0],
-                                 (float *)q->frame.extended_data[1], COEFFS);
+        q->fdsp.butterflies_float((float *)frame->extended_data[0],
+                                  (float *)frame->extended_data[1], COEFFS);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = q->frame;
+    *got_frame_ptr = 1;
 
     return IMC_BLOCK_SIZE * avctx->channels;
 }
@@ -986,6 +1047,7 @@ static av_cold int imc_decode_close(AVCodecContext * avctx)
 
 AVCodec ff_imc_decoder = {
     .name           = "imc",
+    .long_name      = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_IMC,
     .priv_data_size = sizeof(IMCContext),
@@ -993,13 +1055,13 @@ AVCodec ff_imc_decoder = {
     .close          = imc_decode_close,
     .decode         = imc_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
 
 AVCodec ff_iac_decoder = {
     .name           = "iac",
+    .long_name      = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_IAC,
     .priv_data_size = sizeof(IMCContext),
@@ -1007,7 +1069,6 @@ AVCodec ff_iac_decoder = {
     .close          = imc_decode_close,
     .decode         = imc_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index ff4236e..4eb049f 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -32,6 +32,7 @@
 
 #include "avcodec.h"
 #include "dsputil.h"
+#include "imgconvert.h"
 #include "internal.h"
 #include "libavutil/colorspace.h"
 #include "libavutil/common.h"
@@ -39,7 +40,7 @@
 #include "libavutil/imgutils.h"
 
 #if HAVE_MMX_EXTERNAL
-#include "x86/dsputil_mmx.h"
+#include "x86/dsputil_x86.h"
 #endif
 
 #if HAVE_MMX_EXTERNAL
@@ -59,7 +60,7 @@ void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int
 
 static int is_gray(const AVPixFmtDescriptor *desc)
 {
-    return desc->nb_components - (desc->flags & PIX_FMT_ALPHA) == 1;
+    return desc->nb_components - (desc->flags & AV_PIX_FMT_FLAG_ALPHA) == 1;
 }
 
 int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
@@ -85,11 +86,11 @@ int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt,
         dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
         loss |= FF_LOSS_RESOLUTION;
 
-    if ((src_desc->flags & PIX_FMT_RGB) != (dst_desc->flags & PIX_FMT_RGB))
+    if ((src_desc->flags & AV_PIX_FMT_FLAG_RGB) != (dst_desc->flags & AV_PIX_FMT_FLAG_RGB))
         loss |= FF_LOSS_COLORSPACE;
 
-    if (has_alpha && !(dst_desc->flags & PIX_FMT_ALPHA) &&
-         (dst_desc->flags & PIX_FMT_ALPHA))
+    if (has_alpha && !(dst_desc->flags & AV_PIX_FMT_FLAG_ALPHA) &&
+         (dst_desc->flags & AV_PIX_FMT_FLAG_ALPHA))
         loss |= FF_LOSS_ALPHA;
 
     if (dst_pix_fmt == AV_PIX_FMT_PAL8 && !is_gray(src_desc))
@@ -136,24 +137,6 @@ static enum AVPixelFormat avcodec_find_best_pix_fmt1(enum AVPixelFormat *pix_fmt
     return dst_pix_fmt;
 }
 
-#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)
@@ -277,8 +260,8 @@ void ff_shrink88(uint8_t *dst, int dst_wrap,
 /* return true if yuv planar */
 static inline int is_yuv_planar(const AVPixFmtDescriptor *desc)
 {
-    return (!(desc->flags & PIX_FMT_RGB) &&
-             (desc->flags & PIX_FMT_PLANAR));
+    return (!(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
+             (desc->flags & AV_PIX_FMT_FLAG_PLANAR));
 }
 
 int av_picture_crop(AVPicture *dst, const AVPicture *src,
@@ -365,6 +348,8 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width,
     return 0;
 }
 
+#if FF_API_DEINTERLACE
+
 #if !HAVE_MMX_EXTERNAL
 /* filter parameters: [-1 4 2 4 -1] // 8 */
 static void deinterlace_line_c(uint8_t *dst,
@@ -373,7 +358,7 @@ static void deinterlace_line_c(uint8_t *dst,
                              const uint8_t *lum,
                              int size)
 {
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     int sum;
 
     for(;size > 0;size--) {
@@ -396,7 +381,7 @@ static void deinterlace_line_inplace_c(uint8_t *lum_m4, uint8_t *lum_m3,
                                        uint8_t *lum_m2, uint8_t *lum_m1,
                                        uint8_t *lum, int size)
 {
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     int sum;
 
     for(;size > 0;size--) {
@@ -523,3 +508,5 @@ int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
     emms_c();
     return 0;
 }
+
+#endif /* FF_API_DEINTERLACE */
diff --git a/libavcodec/imgconvert.h b/libavcodec/imgconvert.h
new file mode 100644
index 0000000..91e9f91
--- /dev/null
+++ b/libavcodec/imgconvert.h
@@ -0,0 +1,29 @@
+/*
+ * 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_IMGCONVERT_H
+#define AVCODEC_IMGCONVERT_H
+
+#include <stdint.h>
+
+/* 1/2^n downscaling functions */
+void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
+void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
+void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
+
+#endif /* AVCODEC_IMGCONVERT_H */
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index 1dd151d..7df6e69 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -29,11 +29,12 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "indeo2data.h"
+#include "internal.h"
 #include "mathops.h"
 
 typedef struct Ir2Context{
     AVCodecContext *avctx;
-    AVFrame picture;
+    AVFrame *picture;
     GetBitContext gb;
     int decode_delta;
 } Ir2Context;
@@ -47,8 +48,8 @@ static inline int ir2_get_code(GetBitContext *gb)
     return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1;
 }
 
-static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
-                             const uint8_t *table)
+static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst,
+                            int stride, const uint8_t *table)
 {
     int i;
     int j;
@@ -56,16 +57,16 @@ static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst
     int c;
     int t;
 
-    if(width&1)
-        return -1;
+    if (width & 1)
+        return AVERROR_INVALIDDATA;
 
     /* first line contain absolute values, other lines contain deltas */
-    while (out < width){
+    while (out < width) {
         c = ir2_get_code(&ctx->gb);
-        if(c >= 0x80) { /* we have a run */
+        if (c >= 0x80) { /* we have a run */
             c -= 0x7F;
-            if(out + c*2 > width)
-                return -1;
+            if (out + c*2 > width)
+                return AVERROR_INVALIDDATA;
             for (i = 0; i < c * 2; i++)
                 dst[out++] = 0x80;
         } else { /* copy two values from table */
@@ -75,25 +76,25 @@ static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst
     }
     dst += stride;
 
-    for (j = 1; j < height; j++){
+    for (j = 1; j < height; j++) {
         out = 0;
-        while (out < width){
+        while (out < width) {
             c = ir2_get_code(&ctx->gb);
-            if(c >= 0x80) { /* we have a skip */
+            if (c >= 0x80) { /* we have a skip */
                 c -= 0x7F;
-                if(out + c*2 > width)
-                    return -1;
+                if (out + c*2 > width)
+                    return AVERROR_INVALIDDATA;
                 for (i = 0; i < c * 2; i++) {
                     dst[out] = dst[out - stride];
                     out++;
                 }
             } else { /* add two deltas from table */
-                t = dst[out - stride] + (table[c * 2] - 128);
-                t= av_clip_uint8(t);
+                t        = dst[out - stride] + (table[c * 2] - 128);
+                t        = av_clip_uint8(t);
                 dst[out] = t;
                 out++;
-                t = dst[out - stride] + (table[(c * 2) + 1] - 128);
-                t= av_clip_uint8(t);
+                t        = dst[out - stride] + (table[(c * 2) + 1] - 128);
+                t        = av_clip_uint8(t);
                 dst[out] = t;
                 out++;
             }
@@ -103,31 +104,31 @@ static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst
     return 0;
 }
 
-static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride,
-                             const uint8_t *table)
+static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst,
+                                  int stride, const uint8_t *table)
 {
     int j;
     int out = 0;
     int c;
     int t;
 
-    if(width&1)
-        return -1;
+    if (width & 1)
+        return AVERROR_INVALIDDATA;
 
-    for (j = 0; j < height; j++){
+    for (j = 0; j < height; j++) {
         out = 0;
-        while (out < width){
+        while (out < width) {
             c = ir2_get_code(&ctx->gb);
-            if(c >= 0x80) { /* we have a skip */
-                c -= 0x7F;
+            if (c >= 0x80) { /* we have a skip */
+                c   -= 0x7F;
                 out += c * 2;
             } else { /* add two deltas from table */
-                t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
-                t= av_clip_uint8(t);
+                t        = dst[out] + (((table[c * 2] - 128)*3) >> 2);
+                t        = av_clip_uint8(t);
                 dst[out] = t;
                 out++;
-                t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
-                t= av_clip_uint8(t);
+                t        = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
+                t        = av_clip_uint8(t);
                 dst[out] = t;
                 out++;
             }
@@ -141,21 +142,16 @@ static int ir2_decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     Ir2Context * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
-    int start;
+    const uint8_t *buf   = avpkt->data;
+    int buf_size         = avpkt->size;
+    AVFrame *picture     = data;
+    AVFrame * const p    = s->picture;
+    int start, ret;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 1;
-    p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, p)) {
+    if ((ret = ff_reget_buffer(avctx, p)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     start = 48; /* hardcoded for now */
@@ -176,30 +172,46 @@ static int ir2_decode_frame(AVCodecContext *avctx,
     init_get_bits(&s->gb, buf + start, (buf_size - start) * 8);
 
     if (s->decode_delta) { /* intraframe */
-        ir2_decode_plane(s, avctx->width, avctx->height,
-                         s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
+        if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
+                                    p->data[0], p->linesize[0],
+                                    ir2_luma_table)) < 0)
+            return ret;
+
         /* swapped U and V */
-        ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
-                         s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
-        ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
-                         s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
+        if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
+                                    p->data[2], p->linesize[2],
+                                    ir2_luma_table)) < 0)
+            return ret;
+        if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
+                                    p->data[1], p->linesize[1],
+                                    ir2_luma_table)) < 0)
+            return ret;
     } else { /* interframe */
-        ir2_decode_plane_inter(s, avctx->width, avctx->height,
-                         s->picture.data[0], s->picture.linesize[0], ir2_luma_table);
+        if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
+                                          p->data[0], p->linesize[0],
+                                          ir2_luma_table)) < 0)
+            return ret;
         /* swapped U and V */
-        ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
-                         s->picture.data[2], s->picture.linesize[2], ir2_luma_table);
-        ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
-                         s->picture.data[1], s->picture.linesize[1], ir2_luma_table);
+        if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
+                                          p->data[2], p->linesize[2],
+                                          ir2_luma_table)) < 0)
+            return ret;
+        if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
+                                          p->data[1], p->linesize[1],
+                                          ir2_luma_table)) < 0)
+            return ret;
     }
 
-    *picture   = s->picture;
+    if ((ret = av_frame_ref(picture, p)) < 0)
+        return ret;
+
     *got_frame = 1;
 
     return buf_size;
 }
 
-static av_cold int ir2_decode_init(AVCodecContext *avctx){
+static av_cold int ir2_decode_init(AVCodecContext *avctx)
+{
     Ir2Context * const ic = avctx->priv_data;
     static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
 
@@ -207,6 +219,10 @@ static av_cold int ir2_decode_init(AVCodecContext *avctx){
 
     avctx->pix_fmt= AV_PIX_FMT_YUV410P;
 
+    ic->picture = av_frame_alloc();
+    if (!ic->picture)
+        return AVERROR(ENOMEM);
+
     ir2_vlc.table = vlc_tables;
     ir2_vlc.table_allocated = 1 << CODE_VLC_BITS;
 #ifdef BITSTREAM_READER_LE
@@ -222,18 +238,18 @@ static av_cold int ir2_decode_init(AVCodecContext *avctx){
     return 0;
 }
 
-static av_cold int ir2_decode_end(AVCodecContext *avctx){
+static av_cold int ir2_decode_end(AVCodecContext *avctx)
+{
     Ir2Context * const ic = avctx->priv_data;
-    AVFrame *pic = &ic->picture;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
+    av_frame_free(&ic->picture);
 
     return 0;
 }
 
 AVCodec ff_indeo2_decoder = {
     .name           = "indeo2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_INDEO2,
     .priv_data_size = sizeof(Ir2Context),
@@ -241,5 +257,4 @@ AVCodec ff_indeo2_decoder = {
     .close          = ir2_decode_end,
     .decode         = ir2_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
 };
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index 81bf0a9..a9c02b2 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -32,9 +32,9 @@
 #include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "bytestream.h"
 #include "get_bits.h"
+#include "hpeldsp.h"
 #include "internal.h"
 
 #include "indeo3data.h"
@@ -81,8 +81,7 @@ typedef struct Cell {
 
 typedef struct Indeo3DecodeContext {
     AVCodecContext *avctx;
-    AVFrame         frame;
-    DSPContext      dsp;
+    HpelDSPContext  hdsp;
 
     GetBitContext   gb;
     int             need_resync;
@@ -252,19 +251,17 @@ static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
         /* copy using 16xH blocks */
         if (!((cell->xpos << 2) & 15) && w >= 4) {
             for (; w >= 4; src += 16, dst += 16, w -= 4)
-                ctx->dsp.put_no_rnd_pixels_tab[0][0](dst, src, plane->pitch, h);
+                ctx->hdsp.put_pixels_tab[0][0](dst, src, plane->pitch, h);
         }
 
         /* copy using 8xH blocks */
         if (!((cell->xpos << 2) & 7) && w >= 2) {
-            ctx->dsp.put_no_rnd_pixels_tab[1][0](dst, src, plane->pitch, h);
+            ctx->hdsp.put_pixels_tab[1][0](dst, src, plane->pitch, h);
             w -= 2;
             src += 8;
             dst += 8;
-        }
-
-        if (w >= 1) {
-            copy_block4(dst, src, plane->pitch, plane->pitch, h);
+        } else if (w >= 1) {
+            ctx->hdsp.put_pixels_tab[2][0](dst, src, plane->pitch, h);
             w--;
             src += 4;
             dst += 4;
@@ -336,7 +333,7 @@ if (*data_ptr >= last_ptr) \
 
 #define RLE_BLOCK_COPY \
     if (cell->mv_ptr || !skip_flag) \
-        copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom)
+        ctx->hdsp.put_pixels_tab[2][0](dst, ref, row_offset, 4 << v_zoom)
 
 #define RLE_BLOCK_COPY_8 \
     pix64 = AV_RN64(ref);\
@@ -348,7 +345,7 @@ if (*data_ptr >= last_ptr) \
         fill_64(dst, pix64, 8, row_offset)
 
 #define RLE_LINES_COPY \
-    copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom)
+    ctx->hdsp.put_pixels_tab[2][0](dst, ref, row_offset, num_lines << v_zoom)
 
 #define RLE_LINES_COPY_M10 \
     pix64 = AV_RN64(ref);\
@@ -416,7 +413,8 @@ if (*data_ptr >= last_ptr) \
     }
 
 
-static int decode_cell_data(Cell *cell, uint8_t *block, uint8_t *ref_block,
+static int decode_cell_data(Indeo3DecodeContext *ctx, Cell *cell,
+                            uint8_t *block, uint8_t *ref_block,
                             int pitch, int h_zoom, int v_zoom, int mode,
                             const vqEntry *delta[2], int swap_quads[2],
                             const uint8_t **data_ptr, const uint8_t *last_ptr)
@@ -661,14 +659,16 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
         }
 
         zoom_fac = mode >= 3;
-        error = decode_cell_data(cell, block, ref_block, plane->pitch, 0, zoom_fac,
-                                 mode, delta, swap_quads, &data_ptr, last_ptr);
+        error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
+                                 0, zoom_fac, mode, delta, swap_quads,
+                                 &data_ptr, last_ptr);
         break;
     case 10: /*-------------------- MODE 10 (8x8 block processing) ---------------------*/
     case 11: /*----------------- MODE 11 (4x8 INTER block processing) ------------------*/
         if (mode == 10 && !cell->mv_ptr) { /* MODE 10 INTRA processing */
-            error = decode_cell_data(cell, block, ref_block, plane->pitch, 1, 1,
-                                     mode, delta, swap_quads, &data_ptr, last_ptr);
+            error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
+                                     1, 1, mode, delta, swap_quads,
+                                     &data_ptr, last_ptr);
         } else { /* mode 10 and 11 INTER processing */
             if (mode == 11 && !cell->mv_ptr) {
                av_log(avctx, AV_LOG_ERROR, "Attempt to use Mode 11 for an INTRA cell!\n");
@@ -676,7 +676,7 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
             }
 
             zoom_fac = mode == 10;
-            error = decode_cell_data(cell, block, ref_block, plane->pitch,
+            error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
                                      zoom_fac, 1, mode, delta, swap_quads,
                                      &data_ptr, last_ptr);
         }
@@ -944,7 +944,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
         free_frame_buffers(ctx);
         if ((res = allocate_frame_buffers(ctx, avctx)) < 0)
              return res;
-        avcodec_set_dimensions(avctx, width, height);
+        ff_set_dimensions(avctx, width, height);
     }
 
     y_offset = bytestream2_get_le32(&gb);
@@ -986,12 +986,12 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
     }
 
     if (ctx->frame_flags & BS_8BIT_PEL) {
-        av_log_ask_for_sample(avctx, "8-bit pixel format\n");
+        avpriv_request_sample(avctx, "8-bit pixel format");
         return AVERROR_PATCHWELCOME;
     }
 
     if (ctx->frame_flags & BS_MV_X_HALF || ctx->frame_flags & BS_MV_Y_HALF) {
-        av_log_ask_for_sample(avctx, "halfpel motion vectors\n");
+        avpriv_request_sample(avctx, "Halfpel motion vectors");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -1045,7 +1045,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     build_requant_tab();
 
-    ff_dsputil_init(&ctx->dsp, avctx);
+    ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
 
     allocate_frame_buffers(ctx, avctx);
 
@@ -1059,6 +1059,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     Indeo3DecodeContext *ctx = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
+    AVFrame *frame     = data;
     int res;
 
     res = decode_frame_headers(ctx, avctx, buf, buf_size);
@@ -1095,27 +1096,22 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if ((res = decode_plane(ctx, avctx, &ctx->planes[2], ctx->v_data_ptr, ctx->v_data_size, 10)))
         return res;
 
-    if (ctx->frame.data[0])
-        avctx->release_buffer(avctx, &ctx->frame);
-
-    ctx->frame.reference = 0;
-    if ((res = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
 
     output_plane(&ctx->planes[0], ctx->buf_sel,
-                 ctx->frame.data[0], ctx->frame.linesize[0],
+                 frame->data[0], frame->linesize[0],
                  avctx->height);
     output_plane(&ctx->planes[1], ctx->buf_sel,
-                 ctx->frame.data[1], ctx->frame.linesize[1],
+                 frame->data[1], frame->linesize[1],
                  (avctx->height + 3) >> 2);
     output_plane(&ctx->planes[2], ctx->buf_sel,
-                 ctx->frame.data[2], ctx->frame.linesize[2],
+                 frame->data[2], frame->linesize[2],
                  (avctx->height + 3) >> 2);
 
     *got_frame = 1;
-    *(AVFrame*)data = ctx->frame;
 
     return buf_size;
 }
@@ -1123,18 +1119,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
 static av_cold int decode_close(AVCodecContext *avctx)
 {
-    Indeo3DecodeContext *ctx = avctx->priv_data;
-
     free_frame_buffers(avctx->priv_data);
 
-    if (ctx->frame.data[0])
-        avctx->release_buffer(avctx, &ctx->frame);
-
     return 0;
 }
 
 AVCodec ff_indeo3_decoder = {
     .name           = "indeo3",
+    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_INDEO3,
     .priv_data_size = sizeof(Indeo3DecodeContext),
@@ -1142,5 +1134,4 @@ AVCodec ff_indeo3_decoder = {
     .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
 };
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index 42b1130..6a19955 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -30,7 +30,6 @@
 #define BITSTREAM_READER_LE
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "ivi_dsp.h"
 #include "ivi_common.h"
 #include "indeo4data.h"
@@ -57,8 +56,8 @@ static const struct {
     int             is_2d_trans;
 } transforms[18] = {
     { ff_ivi_inverse_haar_8x8,  ff_ivi_dc_haar_2d,       1 },
-    { NULL, NULL, 0 }, /* inverse Haar 8x1 */
-    { NULL, NULL, 0 }, /* inverse Haar 1x8 */
+    { ff_ivi_row_haar8,         ff_ivi_dc_haar_2d,       0 },
+    { ff_ivi_col_haar8,         ff_ivi_dc_haar_2d,       0 },
     { ff_ivi_put_pixels_8x8,    ff_ivi_put_dc_pixel_8x8, 1 },
     { ff_ivi_inverse_slant_8x8, ff_ivi_dc_slant_2d,      1 },
     { ff_ivi_row_slant8,        ff_ivi_dc_row_slant,     1 },
@@ -66,13 +65,13 @@ static const struct {
     { NULL, NULL, 0 }, /* inverse DCT 8x8 */
     { NULL, NULL, 0 }, /* inverse DCT 8x1 */
     { NULL, NULL, 0 }, /* inverse DCT 1x8 */
-    { NULL, NULL, 0 }, /* inverse Haar 4x4 */
+    { ff_ivi_inverse_haar_4x4,  ff_ivi_dc_haar_2d,       1 },
     { ff_ivi_inverse_slant_4x4, ff_ivi_dc_slant_2d,      1 },
     { NULL, NULL, 0 }, /* no transform 4x4 */
-    { NULL, NULL, 0 }, /* inverse Haar 1x4 */
-    { NULL, NULL, 0 }, /* inverse Haar 4x1 */
-    { NULL, NULL, 0 }, /* inverse slant 1x4 */
-    { NULL, NULL, 0 }, /* inverse slant 4x1 */
+    { ff_ivi_row_haar4,         ff_ivi_dc_haar_2d,       0 },
+    { ff_ivi_col_haar4,         ff_ivi_dc_haar_2d,       0 },
+    { ff_ivi_row_slant4,        ff_ivi_dc_row_slant,     0 },
+    { ff_ivi_col_slant4,        ff_ivi_dc_col_slant,     0 },
     { NULL, NULL, 0 }, /* inverse DCT 4x4 */
 };
 
@@ -294,6 +293,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
 
     band->is_empty = get_bits1(&ctx->gb);
     if (!band->is_empty) {
+        int old_blk_size = band->blk_size;
         /* skip header size
          * If header size is not given, header size is 4 bytes. */
         if (get_bits1(&ctx->gb))
@@ -331,12 +331,12 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
             transform_id = get_bits(&ctx->gb, 5);
             if (transform_id >= FF_ARRAY_ELEMS(transforms) ||
                 !transforms[transform_id].inv_trans) {
-                av_log_ask_for_sample(avctx, "Unimplemented transform: %d!\n", transform_id);
+                avpriv_request_sample(avctx, "Transform %d", transform_id);
                 return AVERROR_PATCHWELCOME;
             }
             if ((transform_id >= 7 && transform_id <= 9) ||
                  transform_id == 17) {
-                av_log_ask_for_sample(avctx, "DCT transform not supported yet!\n");
+                avpriv_request_sample(avctx, "DCT transform");
                 return AVERROR_PATCHWELCOME;
             }
 
@@ -370,21 +370,37 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
             band->scan = scan_index_to_tab[scan_indx];
 
             band->quant_mat = get_bits(&ctx->gb, 5);
-            if (band->quant_mat == 31) {
-                av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
+            if (band->quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) {
+
+                if (band->quant_mat == 31)
+                    av_log(avctx, AV_LOG_ERROR,
+                           "Custom quant matrix encountered!\n");
+                else
+                    avpriv_request_sample(avctx, "Quantization matrix %d",
+                                          band->quant_mat);
+                band->quant_mat = -1;
                 return AVERROR_INVALIDDATA;
             }
-            if (band->quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) {
-                av_log_ask_for_sample(avctx, "Quantization matrix %d",
-                                      band->quant_mat);
+        } else {
+            if (old_blk_size != band->blk_size) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "The band block size does not match the configuration "
+                       "inherited\n");
+                return AVERROR_INVALIDDATA;
+            }
+            if (band->quant_mat < 0) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid quant_mat inherited\n");
                 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))
-            return AVERROR_INVALIDDATA;
+        if (!get_bits1(&ctx->gb))
+            band->blk_vlc.tab = ctx->blk_vlc.tab;
+        else
+            if (ff_ivi_dec_huff_desc(&ctx->gb, 1, IVI_BLK_HUFF,
+                                     &band->blk_vlc, avctx))
+                return AVERROR_INVALIDDATA;
 
         /* select appropriate rvmap table for this band */
         band->rvmap_sel = get_bits1(&ctx->gb) ? get_bits(&ctx->gb, 3) : 8;
@@ -623,12 +639,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
 AVCodec ff_indeo4_decoder = {
     .name           = "indeo4",
+    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_INDEO4,
     .priv_data_size = sizeof(IVI45DecContext),
     .init           = decode_init,
     .close          = ff_ivi_decode_close,
     .decode         = ff_ivi_decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index b7cfc5f..83bbcbb 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -98,7 +98,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx)
     }
 
     if (ctx->gop_flags & 2) {
-        av_log_missing_feature(avctx, "YV12 picture format", 0);
+        avpriv_report_missing_feature(avctx, "YV12 picture format");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -140,7 +140,7 @@ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx)
             }
 
             if (get_bits1(&ctx->gb)) {
-                av_log_missing_feature(avctx, "Extended transform info", 0);
+                avpriv_report_missing_feature(avctx, "Extended transform info");
                 return AVERROR_PATCHWELCOME;
             }
 
@@ -649,12 +649,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
 AVCodec ff_indeo5_decoder = {
     .name           = "indeo5",
+    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_INDEO5,
     .priv_data_size = sizeof(IVI45DecContext),
     .init           = decode_init,
     .close          = ff_ivi_decode_close,
     .decode         = ff_ivi_decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"),
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c
index 0701cde..78e3d52 100644
--- a/libavcodec/intelh263dec.c
+++ b/libavcodec/intelh263dec.c
@@ -126,6 +126,7 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s)
 
 AVCodec ff_h263i_decoder = {
     .name           = "h263i",
+    .long_name      = NULL_IF_CONFIG_SMALL("Intel H.263"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H263I,
     .priv_data_size = sizeof(MpegEncContext),
@@ -133,6 +134,5 @@ AVCodec ff_h263i_decoder = {
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Intel H.263"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 069a855..c4f0981 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -26,34 +26,34 @@
 
 #include <stdint.h>
 
+#include "libavutil/buffer.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixfmt.h"
 #include "avcodec.h"
+#include "config.h"
 
-#define FF_SANE_NB_CHANNELS 128U
+#define FF_SANE_NB_CHANNELS 63U
 
-typedef struct InternalBuffer {
-    uint8_t *base[AV_NUM_DATA_POINTERS];
-    uint8_t *data[AV_NUM_DATA_POINTERS];
-    int linesize[AV_NUM_DATA_POINTERS];
-    int width;
-    int height;
-    enum AVPixelFormat pix_fmt;
-} InternalBuffer;
-
-typedef struct AVCodecInternal {
+typedef struct FramePool {
     /**
-     * internal buffer count
-     * used by default get/release/reget_buffer().
+     * Pools for each data plane. For audio all the planes have the same size,
+     * so only pools[0] is used.
      */
-    int buffer_count;
+    AVBufferPool *pools[4];
 
-    /**
-     * internal buffers
-     * used by default get/release/reget_buffer().
+    /*
+     * Pool parameters
      */
-    InternalBuffer *buffer;
+    int format;
+    int width, height;
+    int stride_align[AV_NUM_DATA_POINTERS];
+    int linesize[4];
+    int planes;
+    int channels;
+    int samples;
+} FramePool;
 
+typedef struct AVCodecInternal {
     /**
      * Whether the parent AVCodecContext is a copy of the context which had
      * init() called on it.
@@ -62,13 +62,20 @@ typedef struct AVCodecInternal {
      */
     int is_copy;
 
-#if FF_API_OLD_DECODE_AUDIO
     /**
-     * Internal sample count used by avcodec_encode_audio() to fabricate pts.
-     * Can be removed along with avcodec_encode_audio().
+     * Whether to allocate progress for frame threading.
+     *
+     * The codec must set it to 1 if it uses ff_thread_await/report_progress(),
+     * then progress will be allocated in ff_thread_get_buffer(). The frames
+     * then MUST be freed with ff_thread_release_buffer().
+     *
+     * If the codec does not need to call the progress functions (there are no
+     * dependencies between the frames), it should leave this at 0. Then it can
+     * decode straight to the user-provided frames (which the user will then
+     * free with av_frame_unref()), there is no need to call
+     * ff_thread_release_buffer().
      */
-    int sample_count;
-#endif
+    int allocate_progress;
 
     /**
      * An audio frame with less than required samples has been submitted and
@@ -76,11 +83,17 @@ typedef struct AVCodecInternal {
      */
     int last_audio_frame;
 
+    AVFrame *to_free;
+
+    FramePool *pool;
+
+    void *thread_ctx;
+
     /**
-     * The data for the last allocated audio frame.
-     * Stored here so we can free it.
+     * Current packet as passed into the decoder, to avoid having to pass the
+     * packet into every function.
      */
-    uint8_t *audio_data;
+    AVPacket *pkt;
 } AVCodecInternal;
 
 struct AVCodecDefault {
@@ -92,11 +105,10 @@ struct AVCodecDefault {
  * Return the hardware accelerated codec for codec codec_id and
  * pixel format pix_fmt.
  *
- * @param codec_id the codec to match
- * @param pix_fmt the pixel format to match
+ * @param avctx The codec context containing the codec_id and pixel format.
  * @return the hardware accelerated codec, or NULL if none was found.
  */
-AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt);
+AVHWAccel *ff_find_hwaccel(AVCodecContext *avctx);
 
 /**
  * Return the index into tab at which {a,b} match elements {[0],[1]} of tab.
@@ -149,6 +161,22 @@ static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx,
  * AVCodecContext.get_buffer() and should be used instead calling get_buffer()
  * directly.
  */
-int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame);
+int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags);
+
+/**
+ * Identical in function to av_frame_make_writable(), except it uses
+ * ff_get_buffer() to allocate the buffer when needed.
+ */
+int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame);
+
+const uint8_t *avpriv_find_start_code(const uint8_t *restrict p,
+                                      const uint8_t *end,
+                                      uint32_t *restrict state);
+
+/**
+ * Check that the provided frame dimensions are valid and set them on the codec
+ * context.
+ */
+int ff_set_dimensions(AVCodecContext *s, int width, int height);
 
 #endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index 3f098ac..7d785e3 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -40,7 +40,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
-#include "dsputil.h"
+#include "hpeldsp.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
 #include "internal.h"
@@ -50,10 +50,9 @@
 typedef struct IpvideoContext {
 
     AVCodecContext *avctx;
-    DSPContext dsp;
-    AVFrame second_last_frame;
-    AVFrame last_frame;
-    AVFrame current_frame;
+    HpelDSPContext hdsp;
+    AVFrame *second_last_frame;
+    AVFrame *last_frame;
     const unsigned char *decoding_map;
     int decoding_map_size;
 
@@ -67,39 +66,39 @@ typedef struct IpvideoContext {
     uint32_t pal[256];
 } IpvideoContext;
 
-static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y)
+static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y)
 {
-    int current_offset = s->pixel_ptr - s->current_frame.data[0];
-    int motion_offset = current_offset + delta_y * s->current_frame.linesize[0]
+    int current_offset = s->pixel_ptr - dst->data[0];
+    int motion_offset = current_offset + delta_y * dst->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);
-        return -1;
+        return AVERROR_INVALIDDATA;
     } 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",
             motion_offset, s->upper_motion_limit_offset);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (src->data[0] == NULL) {
         av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
         return AVERROR(EINVAL);
     }
-    s->dsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
-                                           s->current_frame.linesize[0], 8);
+    s->hdsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
+                                            dst->linesize[0], 8);
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s, AVFrame *frame)
 {
-    return copy_from(s, &s->last_frame, 0, 0);
+    return copy_from(s, s->last_frame, frame, 0, 0);
 }
 
-static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s, AVFrame *frame)
 {
-    return copy_from(s, &s->second_last_frame, 0, 0);
+    return copy_from(s, s->second_last_frame, frame, 0, 0);
 }
 
-static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s, AVFrame *frame)
 {
     unsigned char B;
     int x, y;
@@ -120,10 +119,10 @@ static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s)
     }
 
     av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
-    return copy_from(s, &s->second_last_frame, x, y);
+    return copy_from(s, s->second_last_frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s, AVFrame *frame)
 {
     unsigned char B;
     int x, y;
@@ -146,10 +145,10 @@ static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s)
     }
 
     av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
-    return copy_from(s, &s->current_frame, x, y);
+    return copy_from(s, frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char B, BL, BH;
@@ -167,10 +166,10 @@ static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s)
     y = -8 + BH;
 
     av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
-    return copy_from(s, &s->last_frame, x, y);
+    return copy_from(s, s->last_frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s, AVFrame *frame)
 {
     signed char x, y;
 
@@ -180,10 +179,10 @@ static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s)
     y = bytestream2_get_byte(&s->stream_ptr);
 
     av_dlog(NULL, "    motion bytes = %d, %d\n", x, y);
-    return copy_from(s, &s->last_frame, x, y);
+    return copy_from(s, s->last_frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s, AVFrame *frame)
 {
     /* mystery opcode? skip multiple blocks? */
     av_log(s->avctx, AV_LOG_ERROR, "  Interplay video: Help! Mystery opcode 0x6 seen\n");
@@ -192,7 +191,7 @@ static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char P[2];
@@ -231,7 +230,7 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char P[4];
@@ -304,7 +303,7 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char P[4];
@@ -369,7 +368,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char P[8];
@@ -430,7 +429,7 @@ static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s, AVFrame *frame)
 {
     int y;
 
@@ -444,7 +443,7 @@ static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
 
@@ -463,7 +462,7 @@ static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame)
 {
     int y;
     unsigned char P[2];
@@ -483,7 +482,7 @@ static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s, AVFrame *frame)
 {
     int y;
     unsigned char pix;
@@ -500,7 +499,7 @@ static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char sample[2];
@@ -521,7 +520,7 @@ static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s, AVFrame *frame)
 {
     signed char x, y;
 
@@ -530,10 +529,10 @@ static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s)
     y = bytestream2_get_byte(&s->stream_ptr);
 
     av_dlog(NULL, "    motion bytes = %d, %d\n", x, y);
-    return copy_from(s, &s->second_last_frame, x, y);
+    return copy_from(s, s->second_last_frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[2];
@@ -570,7 +569,7 @@ static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[4];
@@ -646,7 +645,7 @@ static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[4];
@@ -713,7 +712,7 @@ static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[8];
@@ -779,7 +778,7 @@ static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
@@ -795,7 +794,7 @@ static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
@@ -815,7 +814,7 @@ static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[2];
@@ -836,7 +835,7 @@ static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t pix;
@@ -855,7 +854,7 @@ static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s)
     return 0;
 }
 
-static int (* const ipvideo_decode_block[])(IpvideoContext *s) = {
+static int (* const ipvideo_decode_block[])(IpvideoContext *s, AVFrame *frame) = {
     ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1,
     ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3,
     ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5,
@@ -866,7 +865,7 @@ static int (* const ipvideo_decode_block[])(IpvideoContext *s) = {
     ipvideo_decode_block_opcode_0xE, ipvideo_decode_block_opcode_0xF,
 };
 
-static int (* const ipvideo_decode_block16[])(IpvideoContext *s) = {
+static int (* const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame) = {
     ipvideo_decode_block_opcode_0x0,    ipvideo_decode_block_opcode_0x1,
     ipvideo_decode_block_opcode_0x2,    ipvideo_decode_block_opcode_0x3,
     ipvideo_decode_block_opcode_0x4,    ipvideo_decode_block_opcode_0x5,
@@ -877,30 +876,26 @@ static int (* const ipvideo_decode_block16[])(IpvideoContext *s) = {
     ipvideo_decode_block_opcode_0xE_16, ipvideo_decode_block_opcode_0x1,
 };
 
-static void ipvideo_decode_opcodes(IpvideoContext *s)
+static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char opcode;
     int ret;
-    static int frame = 0;
     GetBitContext gb;
 
-    av_dlog(NULL, "------------------ frame %d\n", frame);
-    frame++;
-
     bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
     if (!s->is_16bpp) {
         /* this is PAL8, so make the palette available */
-        memcpy(s->current_frame.data[1], s->pal, AVPALETTE_SIZE);
+        memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
 
-        s->stride = s->current_frame.linesize[0];
+        s->stride = frame->linesize[0];
     } else {
-        s->stride = s->current_frame.linesize[0] >> 1;
+        s->stride = frame->linesize[0] >> 1;
         s->mv_ptr = s->stream_ptr;
         bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr));
     }
     s->line_inc = s->stride - 8;
-    s->upper_motion_limit_offset = (s->avctx->height - 8) * s->current_frame.linesize[0]
+    s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
                                   + (s->avctx->width - 8) * (1 + s->is_16bpp);
 
     init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8);
@@ -913,17 +908,17 @@ static void ipvideo_decode_opcodes(IpvideoContext *s)
                     x, y, opcode, bytestream2_tell(&s->stream_ptr));
 
             if (!s->is_16bpp) {
-                s->pixel_ptr = s->current_frame.data[0] + x
-                              + y*s->current_frame.linesize[0];
-                ret = ipvideo_decode_block[opcode](s);
+                s->pixel_ptr = frame->data[0] + x
+                              + y*frame->linesize[0];
+                ret = ipvideo_decode_block[opcode](s, frame);
             } else {
-                s->pixel_ptr = s->current_frame.data[0] + x*2
-                              + y*s->current_frame.linesize[0];
-                ret = ipvideo_decode_block16[opcode](s);
+                s->pixel_ptr = frame->data[0] + x*2
+                              + y*frame->linesize[0];
+                ret = ipvideo_decode_block16[opcode](s, frame);
             }
             if (ret != 0) {
                 av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode problem on frame %d, @ block (%d, %d)\n",
-                       frame, x, y);
+                       s->avctx->frame_number, x, y);
                 return;
             }
         }
@@ -944,10 +939,15 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
     s->is_16bpp = avctx->bits_per_coded_sample == 16;
     avctx->pix_fmt = s->is_16bpp ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_PAL8;
 
-    ff_dsputil_init(&s->dsp, avctx);
+    ff_hpeldsp_init(&s->hdsp, avctx->flags);
 
-    s->current_frame.data[0] = s->last_frame.data[0] =
-    s->second_last_frame.data[0] = NULL;
+    s->last_frame        = av_frame_alloc();
+    s->second_last_frame = av_frame_alloc();
+    if (!s->last_frame || !s->second_last_frame) {
+        av_frame_free(&s->last_frame);
+        av_frame_free(&s->second_last_frame);
+        return AVERROR(ENOMEM);
+    }
 
     return 0;
 }
@@ -959,6 +959,8 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     IpvideoContext *s = avctx->priv_data;
+    AVFrame *frame = data;
+    int ret;
 
     /* decoding map contains 4 bits of information per 8x8 block */
     s->decoding_map_size = avctx->width * avctx->height / (8 * 8 * 2);
@@ -972,31 +974,28 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
     bytestream2_init(&s->stream_ptr, buf + s->decoding_map_size,
                      buf_size - s->decoding_map_size);
 
-    s->current_frame.reference = 3;
-    if (ff_get_buffer(avctx, &s->current_frame)) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "  Interplay Video: get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (!s->is_16bpp) {
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
         if (pal) {
-            s->current_frame.palette_has_changed = 1;
+            frame->palette_has_changed = 1;
             memcpy(s->pal, pal, AVPALETTE_SIZE);
         }
     }
 
-    ipvideo_decode_opcodes(s);
+    ipvideo_decode_opcodes(s, frame);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->current_frame;
 
     /* shuffle frames */
-    if (s->second_last_frame.data[0])
-        avctx->release_buffer(avctx, &s->second_last_frame);
-    s->second_last_frame = s->last_frame;
-    s->last_frame = s->current_frame;
-    s->current_frame.data[0] = NULL;  /* catch any access attempts */
+    av_frame_unref(s->second_last_frame);
+    FFSWAP(AVFrame*, s->second_last_frame, s->last_frame);
+    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
+        return ret;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -1006,17 +1005,15 @@ static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
 {
     IpvideoContext *s = avctx->priv_data;
 
-    /* release the last frame */
-    if (s->last_frame.data[0])
-        avctx->release_buffer(avctx, &s->last_frame);
-    if (s->second_last_frame.data[0])
-        avctx->release_buffer(avctx, &s->second_last_frame);
+    av_frame_free(&s->last_frame);
+    av_frame_free(&s->second_last_frame);
 
     return 0;
 }
 
 AVCodec ff_interplay_video_decoder = {
     .name           = "interplayvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_INTERPLAY_VIDEO,
     .priv_data_size = sizeof(IpvideoContext),
@@ -1024,5 +1021,4 @@ AVCodec ff_interplay_video_decoder = {
     .close          = ipvideo_decode_end,
     .decode         = ipvideo_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_PARAM_CHANGE,
-    .long_name      = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
 };
diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c
index fad7ffe..0cad9da 100644
--- a/libavcodec/intrax8.c
+++ b/libavcodec/intrax8.c
@@ -22,6 +22,7 @@
  */
 
 #include "avcodec.h"
+#include "error_resilience.h"
 #include "get_bits.h"
 #include "mpegvideo.h"
 #include "msmpeg4data.h"
@@ -723,7 +724,6 @@ av_cold void ff_intrax8_common_end(IntraX8Context * w)
  * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
  * @param quant_offset offset away from zero
  */
-//FIXME extern uint8_t ff_wmv3_dc_scale_table[32];
 int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
     MpegEncContext * const s= w->s;
     int mb_xy;
@@ -773,18 +773,18 @@ int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_of
                 /*emulate MB info in the relevant tables*/
                 s->mbskip_table [mb_xy]=0;
                 s->mbintra_table[mb_xy]=1;
-                s->current_picture.f.qscale_table[mb_xy] = w->quant;
+                s->current_picture.qscale_table[mb_xy] = w->quant;
                 mb_xy++;
             }
             s->dest[0]+= 8;
         }
         if(s->mb_y&1){
-            ff_draw_horiz_band(s, (s->mb_y-1)*8, 16);
+            ff_mpeg_draw_horiz_band(s, (s->mb_y-1)*8, 16);
         }
     }
 
 error:
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y,
+    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
                         (s->mb_x>>1)-1, (s->mb_y>>1)-1,
                         ER_MB_END );
     return 0;
diff --git a/libavcodec/intrax8dsp.c b/libavcodec/intrax8dsp.c
index ddceb2c..1115945 100644
--- a/libavcodec/intrax8dsp.c
+++ b/libavcodec/intrax8dsp.c
@@ -21,7 +21,6 @@
  *@brief IntraX8 frame subdecoder image manipulation routines
  */
 
-#include "dsputil.h"
 #include "intrax8dsp.h"
 #include "libavutil/common.h"
 
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index cb26be2..e365210 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -27,11 +27,11 @@
  * h263 decoder.
  */
 
-//#define DEBUG
 #include <limits.h>
 
+#include "libavutil/attributes.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -40,9 +40,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
@@ -101,7 +98,7 @@ static VLC cbpc_b_vlc;
 /* init vlcs */
 
 /* XXX: find a better solution to handle static init */
-void ff_h263_decode_init_vlc(MpegEncContext *s)
+av_cold void ff_h263_decode_init_vlc(void)
 {
     static int done = 0;
 
@@ -238,7 +235,7 @@ int ff_h263_resync(MpegEncContext *s){
     if(show_bits(&s->gb, 16)==0){
         pos= get_bits_count(&s->gb);
         if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4)
-            ret= ff_mpeg4_decode_video_packet_header(s);
+            ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data);
         else
             ret= h263_decode_gob_header(s);
         if(ret>=0)
@@ -255,7 +252,7 @@ int ff_h263_resync(MpegEncContext *s){
 
             pos= get_bits_count(&s->gb);
             if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4)
-                ret= ff_mpeg4_decode_video_packet_header(s);
+                ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data);
             else
                 ret= h263_decode_gob_header(s);
             if(ret>=0)
@@ -352,20 +349,20 @@ static void preview_obmc(MpegEncContext *s){
     do{
         if (get_bits1(&s->gb)) {
             /* skip mb */
-            mot_val = s->current_picture.f.motion_val[0][s->block_index[0]];
+            mot_val = s->current_picture.motion_val[0][s->block_index[0]];
             mot_val[0       ]= mot_val[2       ]=
             mot_val[0+stride]= mot_val[2+stride]= 0;
             mot_val[1       ]= mot_val[3       ]=
             mot_val[1+stride]= mot_val[3+stride]= 0;
 
-            s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
             goto end;
         }
         cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
     }while(cbpc == 20);
 
     if(cbpc & 4){
-        s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+        s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
     }else{
         get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
         if (cbpc & 8) {
@@ -377,7 +374,7 @@ static void preview_obmc(MpegEncContext *s){
         }
 
         if ((cbpc & 16) == 0) {
-                s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+                s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
                 /* 16x16 motion prediction */
                 mot_val= ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
                 if (s->umvplus)
@@ -395,7 +392,7 @@ static void preview_obmc(MpegEncContext *s){
                 mot_val[1       ]= mot_val[3       ]=
                 mot_val[1+stride]= mot_val[3+stride]= my;
         } else {
-            s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
             for(i=0;i<4;i++) {
                 mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
                 if (s->umvplus)
@@ -438,7 +435,7 @@ static void h263_decode_dquant(MpegEncContext *s){
     ff_set_qscale(s, s->qscale);
 }
 
-static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
+static int h263_decode_block(MpegEncContext * s, int16_t * block,
                              int n, int coded)
 {
     int code, level, i, j, last, run;
@@ -563,7 +560,7 @@ not_coded:
 
 static int h263_skip_b_part(MpegEncContext *s, int cbp)
 {
-    LOCAL_ALIGNED_16(DCTELEM, dblock, [64]);
+    LOCAL_ALIGNED_16(int16_t, dblock, [64]);
     int i, mbi;
 
     /* we have to set s->mb_intra to zero to decode B-part of PB-frame correctly
@@ -599,7 +596,7 @@ static int h263_get_modb(GetBitContext *gb, int pb_frame, int *cbpb)
 }
 
 int ff_h263_decode_mb(MpegEncContext *s,
-                      DCTELEM block[6][64])
+                      int16_t block[6][64])
 {
     int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
     int16_t *mot_val;
@@ -617,7 +614,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
                     s->block_last_index[i] = -1;
                 s->mv_dir = MV_DIR_FORWARD;
                 s->mv_type = MV_TYPE_16X16;
-                s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+                s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
                 s->mv[0][0][0] = 0;
                 s->mv[0][0][1] = 0;
                 s->mb_skipped = !(s->obmc | s->loop_filter);
@@ -650,7 +647,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
 
         s->mv_dir = MV_DIR_FORWARD;
         if ((cbpc & 16) == 0) {
-            s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
             /* 16x16 motion prediction */
             s->mv_type = MV_TYPE_16X16;
             ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
@@ -675,7 +672,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
             if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
                skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
         } else {
-            s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
             s->mv_type = MV_TYPE_8X8;
             for(i=0;i<4;i++) {
                 mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
@@ -703,8 +700,8 @@ int ff_h263_decode_mb(MpegEncContext *s,
     } else if(s->pict_type==AV_PICTURE_TYPE_B) {
         int mb_type;
         const int stride= s->b8_stride;
-        int16_t *mot_val0 = s->current_picture.f.motion_val[0][2 * (s->mb_x + s->mb_y * stride)];
-        int16_t *mot_val1 = s->current_picture.f.motion_val[1][2 * (s->mb_x + s->mb_y * stride)];
+        int16_t *mot_val0 = s->current_picture.motion_val[0][2 * (s->mb_x + s->mb_y * stride)];
+        int16_t *mot_val1 = s->current_picture.motion_val[1][2 * (s->mb_x + s->mb_y * stride)];
 //        const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
 
         //FIXME ugly
@@ -787,7 +784,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
             }
         }
 
-        s->current_picture.f.mb_type[xy] = mb_type;
+        s->current_picture.mb_type[xy] = mb_type;
     } else { /* I-Frame */
         do{
             cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
@@ -802,11 +799,11 @@ int ff_h263_decode_mb(MpegEncContext *s,
         dquant = cbpc & 4;
         s->mb_intra = 1;
 intra:
-        s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+        s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
         if (s->h263_aic) {
             s->ac_pred = get_bits1(&s->gb);
             if(s->ac_pred){
-                s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
+                s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
 
                 s->h263_aic_dir = get_bits1(&s->gb);
             }
@@ -888,7 +885,6 @@ int ff_h263_decode_picture_header(MpegEncContext *s)
     i = get_bits(&s->gb, 8); /* picture timestamp */
     if( (s->picture_number&~0xFF)+i < s->picture_number)
         i+= 256;
-    s->current_picture_ptr->f.pts =
     s->picture_number= (s->picture_number&~0xFF) + i;
 
     /* PTYPE starts here */
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index f95b1cd..0f59944 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -27,10 +27,9 @@
  * h263 bitstream encoder.
  */
 
-//#define DEBUG
 #include <limits.h>
 
-#include "dsputil.h"
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h263.h"
@@ -40,9 +39,6 @@
 #include "mpeg4video.h"
 #include "internal.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
 /**
  * Table of number of bits a motion vector component needs.
  */
@@ -275,7 +271,7 @@ void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line)
  */
 void ff_clean_h263_qscales(MpegEncContext *s){
     int i;
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t * const qscale_table = s->current_picture.qscale_table;
 
     ff_init_qscale_tab(s);
 
@@ -306,7 +302,7 @@ static const int dquant_code[5]= {1,0,9,2,3};
  * @param block the 8x8 block
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
+static void h263_encode_block(MpegEncContext * s, int16_t * block, int n)
 {
     int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code;
     RLTable *rl;
@@ -455,7 +451,7 @@ static void h263p_encode_umotion(MpegEncContext * s, int val)
 }
 
 void ff_h263_encode_mb(MpegEncContext * s,
-                       DCTELEM block[6][64],
+                       int16_t block[6][64],
                        int motion_x, int motion_y)
 {
     int cbpc, cbpy, i, cbp, pred_x, pred_y;
@@ -529,8 +525,8 @@ void ff_h263_encode_mb(MpegEncContext * s,
                 /* motion vectors: 8x8 mode*/
                 ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
 
-                motion_x = s->current_picture.f.motion_val[0][s->block_index[i]][0];
-                motion_y = s->current_picture.f.motion_val[0][s->block_index[i]][1];
+                motion_x = s->current_picture.motion_val[0][s->block_index[i]][0];
+                motion_y = s->current_picture.motion_val[0][s->block_index[i]][1];
                 if (!s->umvplus) {
                     ff_h263_encode_motion_vector(s, motion_x - pred_x,
                                                     motion_y - pred_y, 1);
@@ -683,7 +679,7 @@ void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code)
     }
 }
 
-static void init_mv_penalty_and_fcode(MpegEncContext *s)
+static av_cold void init_mv_penalty_and_fcode(MpegEncContext *s)
 {
     int f_code;
     int mv;
@@ -725,7 +721,9 @@ static void init_mv_penalty_and_fcode(MpegEncContext *s)
     }
 }
 
-static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){
+static av_cold void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab,
+                                         uint8_t *len_tab)
+{
     int slevel, run, last;
 
     assert(MAX_LEVEL >= 64);
@@ -768,7 +766,7 @@ static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_t
     }
 }
 
-void ff_h263_encode_init(MpegEncContext *s)
+av_cold void ff_h263_encode_init(MpegEncContext *s)
 {
     static int done = 0;
 
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index 152e9c4..8c5d7f3 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -35,8 +35,35 @@
 #include "ivi_common.h"
 #include "ivi_dsp.h"
 
-extern const IVIHuffDesc ff_ivi_mb_huff_desc[8];  ///< static macroblock huffman tables
-extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tables
+/**
+ * These are 2x8 predefined Huffman codebooks for coding macroblock/block
+ * signals. They are specified using "huffman descriptors" in order to
+ * avoid huge static tables. The decoding tables will be generated at
+ * startup from these descriptors.
+ */
+/** static macroblock huffman tables */
+static const IVIHuffDesc ivi_mb_huff_desc[8] = {
+    {8,  {0, 4, 5, 4, 4, 4, 6, 6}},
+    {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
+    {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
+    {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
+    {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
+    {9,  {0, 4, 4, 4, 4, 3, 3, 3, 2}},
+    {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
+    {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
+};
+
+/** static block huffman tables */
+static const IVIHuffDesc ivi_blk_huff_desc[8] = {
+    {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
+    {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
+    {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
+    {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
+    {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
+    {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
+    {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
+    {9,  {3, 4, 4, 5, 5, 5, 6, 5, 5}}
+};
 
 static VLC ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables
 static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables
@@ -124,7 +151,7 @@ static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag)
                     (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_LE);
 }
 
-void ff_ivi_init_static_vlc(void)
+av_cold void ff_ivi_init_static_vlc(void)
 {
     int i;
     static VLC_TYPE table_data[8192 * 16][2];
@@ -135,11 +162,11 @@ void ff_ivi_init_static_vlc(void)
     for (i = 0; i < 8; i++) {
         ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192;
         ivi_mb_vlc_tabs[i].table_allocated = 8192;
-        ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i],
+        ivi_create_huff_from_desc(&ivi_mb_huff_desc[i],
                                   &ivi_mb_vlc_tabs[i], 1);
         ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192;
         ivi_blk_vlc_tabs[i].table_allocated = 8192;
-        ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i],
+        ivi_create_huff_from_desc(&ivi_blk_huff_desc[i],
                                   &ivi_blk_vlc_tabs[i], 1);
     }
     initialized_vlcs = 1;
@@ -570,7 +597,11 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band,
         cbp      = mb->cbp;
         buf_offs = mb->buf_offs;
 
-        quant = av_clip(band->glob_quant + mb->q_delta, 0, 23);
+        quant = band->glob_quant + mb->q_delta;
+        if (avctx->codec_id == AV_CODEC_ID_INDEO4)
+            quant = av_clip(quant, 0, 31);
+        else
+            quant = av_clip(quant, 0, 23);
 
         scale_tab = is_intra ? band->intra_scale : band->inter_scale;
         if (scale_tab)
@@ -917,6 +948,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 {
     IVI45DecContext *ctx = avctx->priv_data;
     const uint8_t   *buf = avpkt->data;
+    AVFrame       *frame = data;
     int             buf_size = avpkt->size;
     int             result, p, b;
 
@@ -934,7 +966,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
 
     if (ctx->gop_flags & IVI5_IS_PROTECTED) {
-        av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
+        avpriv_report_missing_feature(avctx, "Password-protected clip!\n");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -983,30 +1015,28 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
     }
 
-    if (ctx->frame.data[0])
-        avctx->release_buffer(avctx, &ctx->frame);
+    result = ff_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
+    if (result < 0)
+        return result;
 
-    ctx->frame.reference = 0;
-    avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
-    if ((result = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    if ((result = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return result;
     }
 
     if (ctx->is_scalable) {
         if (avctx->codec_id == AV_CODEC_ID_INDEO4)
-            ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+            ff_ivi_recompose_haar(&ctx->planes[0], frame->data[0], frame->linesize[0]);
         else
-            ff_ivi_recompose53   (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+            ff_ivi_recompose53   (&ctx->planes[0], frame->data[0], frame->linesize[0]);
     } else {
-        ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+        ivi_output_plane(&ctx->planes[0], frame->data[0], frame->linesize[0]);
     }
 
-    ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
-    ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
+    ivi_output_plane(&ctx->planes[2], frame->data[1], frame->linesize[1]);
+    ivi_output_plane(&ctx->planes[1], frame->data[2], frame->linesize[2]);
 
     *got_frame = 1;
-    *(AVFrame*)data = ctx->frame;
 
     return buf_size;
 }
@@ -1023,9 +1053,6 @@ av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
     if (ctx->mb_vlc.cust_tab.table)
         ff_free_vlc(&ctx->mb_vlc.cust_tab);
 
-    if (ctx->frame.data[0])
-        avctx->release_buffer(avctx, &ctx->frame);
-
 #if IVI4_STREAM_ANALYSER
     if (avctx->codec_id == AV_CODEC_ID_INDEO4) {
     if (ctx->is_scalable)
@@ -1048,35 +1075,6 @@ av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
 
 
 /**
- * These are 2x8 predefined Huffman codebooks for coding macroblock/block
- * signals. They are specified using "huffman descriptors" in order to
- * avoid huge static tables. The decoding tables will be generated at
- * startup from these descriptors.
- */
-const IVIHuffDesc ff_ivi_mb_huff_desc[8] = {
-    {8,  {0, 4, 5, 4, 4, 4, 6, 6}},
-    {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
-    {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
-    {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
-    {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
-    {9,  {0, 4, 4, 4, 4, 3, 3, 3, 2}},
-    {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
-    {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
-};
-
-const IVIHuffDesc ff_ivi_blk_huff_desc[8] = {
-    {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
-    {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
-    {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
-    {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
-    {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
-    {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
-    {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
-    {9,  {3, 4, 4, 5, 5, 5, 6, 5, 5}}
-};
-
-
-/**
  *  Scan patterns shared between indeo4 and indeo5
  */
 const uint8_t ff_ivi_vertical_scan_8x8[64] = {
diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h
index fb25374..fb97c8d 100644
--- a/libavcodec/ivi_common.h
+++ b/libavcodec/ivi_common.h
@@ -196,7 +196,6 @@ typedef struct IVIPicConfig {
 
 typedef struct IVI45DecContext {
     GetBitContext   gb;
-    AVFrame         frame;
     RVMapDesc       rvmap_tabs[9];   ///< local corrected copy of the static rvmap tables
 
     uint32_t        frame_num;
@@ -315,6 +314,6 @@ int  ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height);
 
 int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt);
-av_cold int ff_ivi_decode_close(AVCodecContext *avctx);
+int ff_ivi_decode_close(AVCodecContext *avctx);
 
 #endif /* AVCODEC_IVI_COMMON_H */
diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c
index 3ffe84a..bd1f523 100644
--- a/libavcodec/ivi_dsp.c
+++ b/libavcodec/ivi_dsp.c
@@ -27,8 +27,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
-#include "dwt.h"
 #include "ivi_common.h"
 #include "ivi_dsp.h"
 
@@ -40,7 +38,7 @@ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
     int32_t         b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6;
     int32_t         b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9;
     int32_t         pitch, back_pitch;
-    const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+    const short    *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
     const int       num_bands = 4;
 
     /* all bands should have the same pitch */
@@ -183,7 +181,7 @@ void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
                            const int dst_pitch)
 {
     int             x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;
-    const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+    const short    *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
     int32_t         pitch;
 
     /* all bands should have the same pitch */
@@ -250,12 +248,14 @@ void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
     d8 = COMPENSATE(t8); }
 
 /** inverse 4-point Haar transform */
-#define INV_HAAR4(s1, s3, s5, s7) {\
-    HAAR_BFLY(s1, s5);  HAAR_BFLY(s1, s3);  HAAR_BFLY(s5, s7);\
-    s1 = COMPENSATE(s1);\
-    s3 = COMPENSATE(s3);\
-    s5 = COMPENSATE(s5);\
-    s7 = COMPENSATE(s7); }
+#define INV_HAAR4(s1, s3, s5, s7, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\
+    IVI_HAAR_BFLY(s1, s3, t0, t1, t4);\
+    IVI_HAAR_BFLY(t0, s5, t2, t3, t4);\
+    d1 = COMPENSATE(t2);\
+    d2 = COMPENSATE(t3);\
+    IVI_HAAR_BFLY(t1, s7, t2, t3, t4);\
+    d3 = COMPENSATE(t2);\
+    d4 = COMPENSATE(t3); }
 
 void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
                              const uint8_t *flags)
@@ -312,6 +312,153 @@ void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
 #undef  COMPENSATE
 }
 
+void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags)
+{
+    int     i;
+    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+    /* apply the InvHaar8 to all rows */
+#define COMPENSATE(x) (x)
+    for (i = 0; i < 8; i++) {
+        if (   !in[0] && !in[1] && !in[2] && !in[3]
+            && !in[4] && !in[5] && !in[6] && !in[7]) {
+            memset(out, 0, 8 * sizeof(out[0]));
+        } else {
+            INV_HAAR8(in[0],  in[1],  in[2],  in[3],
+                      in[4],  in[5],  in[6],  in[7],
+                      out[0], out[1], out[2], out[3],
+                      out[4], out[5], out[6], out[7],
+                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
+        }
+        in  += 8;
+        out += pitch;
+    }
+#undef  COMPENSATE
+}
+
+void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags)
+{
+    int     i;
+    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+    /* apply the InvHaar8 to all columns */
+#define COMPENSATE(x) (x)
+    for (i = 0; i < 8; i++) {
+        if (flags[i]) {
+            INV_HAAR8(in[ 0], in[ 8], in[16], in[24],
+                      in[32], in[40], in[48], in[56],
+                      out[0 * pitch], out[1 * pitch],
+                      out[2 * pitch], out[3 * pitch],
+                      out[4 * pitch], out[5 * pitch],
+                      out[6 * pitch], out[7 * pitch],
+                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
+        } else
+            out[0 * pitch] = out[1 * pitch] =
+            out[2 * pitch] = out[3 * pitch] =
+            out[4 * pitch] = out[5 * pitch] =
+            out[6 * pitch] = out[7 * pitch] = 0;
+
+        in++;
+        out++;
+    }
+#undef  COMPENSATE
+}
+
+void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch,
+                             const uint8_t *flags)
+{
+    int     i, shift, sp1, sp2;
+    const int32_t *src;
+    int32_t *dst;
+    int     tmp[16];
+    int     t0, t1, t2, t3, t4;
+
+    /* apply the InvHaar4 to all columns */
+#define COMPENSATE(x) (x)
+    src = in;
+    dst = tmp;
+    for (i = 0; i < 4; i++) {
+        if (flags[i]) {
+            /* pre-scaling */
+            shift = !(i & 2);
+            sp1 = src[0] << shift;
+            sp2 = src[4] << shift;
+            INV_HAAR4(   sp1,    sp2, src[8], src[12],
+                      dst[0], dst[4], dst[8], dst[12],
+                      t0, t1, t2, t3, t4);
+        } else
+            dst[0] = dst[4] = dst[8] = dst[12] = 0;
+
+        src++;
+        dst++;
+    }
+#undef  COMPENSATE
+
+    /* apply the InvHaar8 to all rows */
+#define COMPENSATE(x) (x)
+    src = tmp;
+    for (i = 0; i < 4; i++) {
+        if (!src[0] && !src[1] && !src[2] && !src[3]) {
+            memset(out, 0, 4 * sizeof(out[0]));
+        } else {
+            INV_HAAR4(src[0], src[1], src[2], src[3],
+                      out[0], out[1], out[2], out[3],
+                      t0, t1, t2, t3, t4);
+        }
+        src += 4;
+        out += pitch;
+    }
+#undef  COMPENSATE
+}
+
+void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags)
+{
+    int     i;
+    int     t0, t1, t2, t3, t4;
+
+    /* apply the InvHaar4 to all rows */
+#define COMPENSATE(x) (x)
+    for (i = 0; i < 4; i++) {
+        if (!in[0] && !in[1] && !in[2] && !in[3]) {
+            memset(out, 0, 4 * sizeof(out[0]));
+        } else {
+            INV_HAAR4(in[0], in[1], in[2], in[3],
+                      out[0], out[1], out[2], out[3],
+                      t0, t1, t2, t3, t4);
+        }
+        in  += 4;
+        out += pitch;
+    }
+#undef  COMPENSATE
+}
+
+void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags)
+{
+    int     i;
+    int     t0, t1, t2, t3, t4;
+
+    /* apply the InvHaar8 to all columns */
+#define COMPENSATE(x) (x)
+    for (i = 0; i < 4; i++) {
+        if (flags[i]) {
+            INV_HAAR4(in[0], in[4], in[8], in[12],
+                      out[0 * pitch], out[1 * pitch],
+                      out[2 * pitch], out[3 * pitch],
+                      t0, t1, t2, t3, t4);
+        } else
+            out[0 * pitch] = out[1 * pitch] =
+            out[2 * pitch] = out[3 * pitch] = 0;
+
+        in++;
+        out++;
+    }
+#undef  COMPENSATE
+}
+
 void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
                        int blk_size)
 {
@@ -548,6 +695,49 @@ void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int bl
     }
 }
 
+void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+    int     i;
+    int     t0, t1, t2, t3, t4;
+
+#define COMPENSATE(x) ((x + 1)>>1)
+    for (i = 0; i < 4; i++) {
+        if (!in[0] && !in[1] && !in[2] && !in[3]) {
+            memset(out, 0, 4*sizeof(out[0]));
+        } else {
+            IVI_INV_SLANT4( in[0],  in[1],  in[2],  in[3],
+                           out[0], out[1], out[2], out[3],
+                           t0, t1, t2, t3, t4);
+        }
+        in  += 4;
+        out += pitch;
+    }
+#undef COMPENSATE
+}
+
+void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+    int     i, row2;
+    int     t0, t1, t2, t3, t4;
+
+    row2 = pitch << 1;
+
+#define COMPENSATE(x) ((x + 1)>>1)
+    for (i = 0; i < 4; i++) {
+        if (flags[i]) {
+            IVI_INV_SLANT4(in[0], in[4], in[8], in[12],
+                           out[0], out[pitch], out[row2], out[row2 + pitch],
+                           t0, t1, t2, t3, t4);
+        } else {
+            out[0] = out[pitch] = out[row2] = out[row2 + pitch] = 0;
+        }
+
+        in++;
+        out++;
+    }
+#undef COMPENSATE
+}
+
 void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
                            const uint8_t *flags)
 {
diff --git a/libavcodec/ivi_dsp.h b/libavcodec/ivi_dsp.h
index c46f8b2..31d37e3 100644
--- a/libavcodec/ivi_dsp.h
+++ b/libavcodec/ivi_dsp.h
@@ -66,6 +66,71 @@ void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
                              const uint8_t *flags);
 
 /**
+ *  one-dimensional inverse 8-point Haar transform on rows for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags);
+
+/**
+ *  one-dimensional inverse 8-point Haar transform on columns for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags);
+
+/**
+ *  two-dimensional inverse Haar 4x4 transform for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch,
+                             const uint8_t *flags);
+
+/**
+ *  one-dimensional inverse 4-point Haar transform on rows for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags);
+
+/**
+ *  one-dimensional inverse 4-point Haar transform on columns for Indeo 4
+ *
+ *  @param[in]  in        pointer to the vector of transform coefficients
+ *  @param[out] out       pointer to the output buffer (frame)
+ *  @param[in]  pitch     pitch to move to the next y line
+ *  @param[in]  flags     pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+                      const uint8_t *flags);
+
+/**
  *  DC-only two-dimensional inverse Haar transform for Indeo 4.
  *  Performing the inverse transform in this case is equivalent to
  *  spreading DC_coeff >> 3 over the whole block.
@@ -142,6 +207,30 @@ void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch,
                        const uint8_t *flags);
 
 /**
+ *  inverse 1D row slant transform
+ *
+ *  @param[in]    in      pointer to the vector of transform coefficients
+ *  @param[out]   out     pointer to the output buffer (frame)
+ *  @param[in]    pitch   pitch to move to the next y line
+ *  @param[in]    flags   pointer to the array of column flags (unused here)
+ */
+void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch,
+                       const uint8_t *flags);
+
+/**
+ *  inverse 1D column slant transform
+ *
+ *  @param[in]    in      pointer to the vector of transform coefficients
+ *  @param[out]   out     pointer to the output buffer (frame)
+ *  @param[in]    pitch   pitch to move to the next y line
+ *  @param[in]    flags   pointer to the array of column flags:
+ *                        != 0 - non_empty column, 0 - empty one
+ *                        (this array must be filled by caller)
+ */
+void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch,
+                       const uint8_t *flags);
+
+/**
  *  DC-only inverse row slant transform
  */
 void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size);
diff --git a/libavcodec/jfdctfst.c b/libavcodec/jfdctfst.c
index 3e30e5d..bbcf598 100644
--- a/libavcodec/jfdctfst.c
+++ b/libavcodec/jfdctfst.c
@@ -69,7 +69,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include "libavutil/common.h"
-#include "dsputil.h"
+#include "dct.h"
 
 #define DCTSIZE 8
 #define GLOBAL(x) x
@@ -136,17 +136,17 @@
 #endif
 
 
-/* Multiply a DCTELEM variable by an int32_t constant, and immediately
- * descale to yield a DCTELEM result.
+/* Multiply a int16_t variable by an int32_t constant, and immediately
+ * descale to yield a int16_t result.
  */
 
-#define MULTIPLY(var,const)  ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+#define MULTIPLY(var,const)  ((int16_t) DESCALE((var) * (const), CONST_BITS))
 
-static av_always_inline void row_fdct(DCTELEM * data){
+static av_always_inline void row_fdct(int16_t * data){
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1, z2, z3, z4, z5, z11, z13;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   /* Pass 1: process rows. */
@@ -205,12 +205,12 @@ static av_always_inline void row_fdct(DCTELEM * data){
  */
 
 GLOBAL(void)
-ff_fdct_ifast (DCTELEM * data)
+ff_fdct_ifast (int16_t * data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1, z2, z3, z4, z5, z11, z13;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   row_fdct(data);
@@ -271,12 +271,12 @@ ff_fdct_ifast (DCTELEM * data)
  */
 
 GLOBAL(void)
-ff_fdct_ifast248 (DCTELEM * data)
+ff_fdct_ifast248 (int16_t * data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   row_fdct(data);
diff --git a/libavcodec/jfdctint_template.c b/libavcodec/jfdctint_template.c
index 5175390..c6a1638 100644
--- a/libavcodec/jfdctint_template.c
+++ b/libavcodec/jfdctint_template.c
@@ -60,7 +60,7 @@
  */
 
 #include "libavutil/common.h"
-#include "dsputil.h"
+#include "dct.h"
 
 #include "bit_depth_template.c"
 
@@ -184,12 +184,12 @@
 #endif
 
 
-static av_always_inline void FUNC(row_fdct)(DCTELEM *data)
+static av_always_inline void FUNC(row_fdct)(int16_t *data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1, z2, z3, z4, z5;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   /* Pass 1: process rows. */
@@ -216,13 +216,13 @@ static av_always_inline void FUNC(row_fdct)(DCTELEM *data)
     tmp11 = tmp1 + tmp2;
     tmp12 = tmp1 - tmp2;
 
-    dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
-    dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
+    dataptr[0] = (int16_t) ((tmp10 + tmp11) << PASS1_BITS);
+    dataptr[4] = (int16_t) ((tmp10 - tmp11) << PASS1_BITS);
 
     z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
-    dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+    dataptr[2] = (int16_t) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
                                    CONST_BITS-PASS1_BITS);
-    dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+    dataptr[6] = (int16_t) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
                                    CONST_BITS-PASS1_BITS);
 
     /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
@@ -248,10 +248,10 @@ static av_always_inline void FUNC(row_fdct)(DCTELEM *data)
     z3 += z5;
     z4 += z5;
 
-    dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
-    dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
-    dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
-    dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
+    dataptr[7] = (int16_t) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
+    dataptr[5] = (int16_t) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
+    dataptr[3] = (int16_t) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
+    dataptr[1] = (int16_t) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
 
     dataptr += DCTSIZE;         /* advance pointer to next row */
   }
@@ -262,12 +262,12 @@ static av_always_inline void FUNC(row_fdct)(DCTELEM *data)
  */
 
 GLOBAL(void)
-FUNC(ff_jpeg_fdct_islow)(DCTELEM *data)
+FUNC(ff_jpeg_fdct_islow)(int16_t *data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1, z2, z3, z4, z5;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   FUNC(row_fdct)(data);
@@ -344,12 +344,12 @@ FUNC(ff_jpeg_fdct_islow)(DCTELEM *data)
  * you do even part two times.
  */
 GLOBAL(void)
-FUNC(ff_fdct248_islow)(DCTELEM *data)
+FUNC(ff_fdct248_islow)(int16_t *data)
 {
   int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
   int tmp10, tmp11, tmp12, tmp13;
   int z1;
-  DCTELEM *dataptr;
+  int16_t *dataptr;
   int ctr;
 
   FUNC(row_fdct)(data);
diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c
new file mode 100644
index 0000000..bf46398
--- /dev/null
+++ b/libavcodec/jpeg2000.c
@@ -0,0 +1,510 @@
+/*
+ * JPEG 2000 encoder and decoder common functions
+ * Copyright (c) 2007 Kamil Nowosad
+ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * JPEG 2000 image encoder and decoder common functions
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/mem.h"
+#include "avcodec.h"
+#include "jpeg2000.h"
+
+#define SHL(a, n) ((n) >= 0 ? (a) << (n) : (a) >> -(n))
+
+/* tag tree routines */
+
+/* allocate the memory for tag tree */
+static int32_t tag_tree_size(uint16_t w, uint16_t h)
+{
+    uint32_t res = 0;
+    while (w > 1 || h > 1) {
+        res += w * h;
+        if (res + 1 >= INT32_MAX)
+            return -1;
+        w = (w + 1) >> 1;
+        h = (h + 1) >> 1;
+    }
+    return (int32_t)(res + 1);
+}
+
+static Jpeg2000TgtNode *ff_jpeg2000_tag_tree_init(int w, int h)
+{
+    int pw = w, ph = h;
+    Jpeg2000TgtNode *res, *t, *t2;
+    int32_t tt_size;
+
+    tt_size = tag_tree_size(w, h);
+    if (tt_size == -1)
+        return NULL;
+
+    t = res = av_mallocz_array(tt_size, sizeof(*t));
+    if (!res)
+        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;
+}
+
+uint8_t ff_jpeg2000_sigctxno_lut[256][4];
+
+static int getsigctxno(int flag, int bandno)
+{
+    int h, v, d;
+
+    h = ((flag & JPEG2000_T1_SIG_E)  ? 1 : 0) +
+        ((flag & JPEG2000_T1_SIG_W)  ? 1 : 0);
+    v = ((flag & JPEG2000_T1_SIG_N)  ? 1 : 0) +
+        ((flag & JPEG2000_T1_SIG_S)  ? 1 : 0);
+    d = ((flag & JPEG2000_T1_SIG_NE) ? 1 : 0) +
+        ((flag & JPEG2000_T1_SIG_NW) ? 1 : 0) +
+        ((flag & JPEG2000_T1_SIG_SE) ? 1 : 0) +
+        ((flag & JPEG2000_T1_SIG_SW) ? 1 : 0);
+    if (bandno < 3) {
+        if (bandno == 1)
+            FFSWAP(int, h, v);
+        if (h == 2)
+            return 8;
+        if (h == 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;
+    } 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_jpeg2000_sgnctxno_lut[16][16], ff_jpeg2000_xorbit_lut[16][16];
+
+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 } };
+
+static int getsgnctxno(int flag, uint8_t *xorbit)
+{
+    int vcontrib, hcontrib;
+
+    hcontrib = contribtab[flag & JPEG2000_T1_SIG_E ? flag & JPEG2000_T1_SGN_E ? 1 : 2 : 0]
+                         [flag & JPEG2000_T1_SIG_W ? flag & JPEG2000_T1_SGN_W ? 1 : 2 : 0] + 1;
+    vcontrib = contribtab[flag & JPEG2000_T1_SIG_S ? flag & JPEG2000_T1_SGN_S ? 1 : 2 : 0]
+                         [flag & JPEG2000_T1_SIG_N ? flag & JPEG2000_T1_SGN_N ? 1 : 2 : 0] + 1;
+    *xorbit = xorbittab[hcontrib][vcontrib];
+
+    return ctxlbltab[hcontrib][vcontrib];
+}
+
+void ff_jpeg2000_init_tier1_luts(void)
+{
+    int i, j;
+    for (i = 0; i < 256; i++)
+        for (j = 0; j < 4; j++)
+            ff_jpeg2000_sigctxno_lut[i][j] = getsigctxno(i, j);
+    for (i = 0; i < 16; i++)
+        for (j = 0; j < 16; j++)
+            ff_jpeg2000_sgnctxno_lut[i][j] =
+                getsgnctxno(i + (j << 8), &ff_jpeg2000_xorbit_lut[i][j]);
+}
+
+void ff_jpeg2000_set_significance(Jpeg2000T1Context *t1, int x, int y,
+                                  int negative)
+{
+    x++;
+    y++;
+    t1->flags[y][x] |= JPEG2000_T1_SIG;
+    if (negative) {
+        t1->flags[y][x + 1] |= JPEG2000_T1_SIG_W | JPEG2000_T1_SGN_W;
+        t1->flags[y][x - 1] |= JPEG2000_T1_SIG_E | JPEG2000_T1_SGN_E;
+        t1->flags[y + 1][x] |= JPEG2000_T1_SIG_N | JPEG2000_T1_SGN_N;
+        t1->flags[y - 1][x] |= JPEG2000_T1_SIG_S | JPEG2000_T1_SGN_S;
+    } else {
+        t1->flags[y][x + 1] |= JPEG2000_T1_SIG_W;
+        t1->flags[y][x - 1] |= JPEG2000_T1_SIG_E;
+        t1->flags[y + 1][x] |= JPEG2000_T1_SIG_N;
+        t1->flags[y - 1][x] |= JPEG2000_T1_SIG_S;
+    }
+    t1->flags[y + 1][x + 1] |= JPEG2000_T1_SIG_NW;
+    t1->flags[y + 1][x - 1] |= JPEG2000_T1_SIG_NE;
+    t1->flags[y - 1][x + 1] |= JPEG2000_T1_SIG_SW;
+    t1->flags[y - 1][x - 1] |= JPEG2000_T1_SIG_SE;
+}
+
+static const uint8_t lut_gain[2][4] = { { 0, 0, 0, 0 }, { 0, 1, 1, 2 } };
+
+int ff_jpeg2000_init_component(Jpeg2000Component *comp,
+                               Jpeg2000CodingStyle *codsty,
+                               Jpeg2000QuantStyle *qntsty,
+                               int cbps, int dx, int dy,
+                               AVCodecContext *avctx)
+{
+    uint8_t log2_band_prec_width, log2_band_prec_height;
+    int reslevelno, bandno, gbandno = 0, ret, i, j;
+    uint32_t csize;
+
+    if (!codsty->nreslevels2decode) {
+        av_log(avctx, AV_LOG_ERROR, "nreslevels2decode uninitialized\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (ret = ff_jpeg2000_dwt_init(&comp->dwt, comp->coord,
+                                   codsty->nreslevels2decode - 1,
+                                   codsty->transform))
+        return ret;
+    // component size comp->coord is uint16_t so ir cannot overflow
+    csize = (comp->coord[0][1] - comp->coord[0][0]) *
+            (comp->coord[1][1] - comp->coord[1][0]);
+
+    if (codsty->transform == FF_DWT97) {
+        comp->i_data = NULL;
+        comp->f_data = av_malloc_array(csize, sizeof(*comp->f_data));
+        if (!comp->f_data)
+            return AVERROR(ENOMEM);
+    } else {
+        comp->f_data = NULL;
+        comp->i_data = av_malloc_array(csize, sizeof(*comp->i_data));
+        if (!comp->i_data)
+            return AVERROR(ENOMEM);
+    }
+    comp->reslevel = av_malloc_array(codsty->nreslevels, sizeof(*comp->reslevel));
+    if (!comp->reslevel)
+        return AVERROR(ENOMEM);
+    /* LOOP on resolution levels */
+    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) {
+        int declvl = codsty->nreslevels - reslevelno;    // N_L -r see  ISO/IEC 15444-1:2002 B.5
+        Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno;
+
+        /* Compute borders for each resolution level.
+         * Computation of trx_0, trx_1, try_0 and try_1.
+         * see ISO/IEC 15444-1:2002 eq. B.5 and B-14 */
+        for (i = 0; i < 2; i++)
+            for (j = 0; j < 2; j++)
+                reslevel->coord[i][j] =
+                    ff_jpeg2000_ceildivpow2(comp->coord_o[i][j], declvl - 1);
+        // update precincts size: 2^n value
+        reslevel->log2_prec_width  = codsty->log2_prec_widths[reslevelno];
+        reslevel->log2_prec_height = codsty->log2_prec_heights[reslevelno];
+
+        /* Number of bands for each resolution level */
+        if (reslevelno == 0)
+            reslevel->nbands = 1;
+        else
+            reslevel->nbands = 3;
+
+        /* Number of precincts wich span the tile for resolution level reslevelno
+         * see B.6 in ISO/IEC 15444-1:2002 eq. B-16
+         * num_precincts_x = |- trx_1 / 2 ^ log2_prec_width) -| - (trx_0 / 2 ^ log2_prec_width)
+         * num_precincts_y = |- try_1 / 2 ^ log2_prec_width) -| - (try_0 / 2 ^ log2_prec_width)
+         * for Dcinema profiles in JPEG 2000
+         * num_precincts_x = |- trx_1 / 2 ^ log2_prec_width) -|
+         * num_precincts_y = |- try_1 / 2 ^ log2_prec_width) -| */
+        if (reslevel->coord[0][1] == reslevel->coord[0][0])
+            reslevel->num_precincts_x = 0;
+        else
+            reslevel->num_precincts_x =
+                ff_jpeg2000_ceildivpow2(reslevel->coord[0][1],
+                                        reslevel->log2_prec_width) -
+                (reslevel->coord[0][0] >> reslevel->log2_prec_width);
+
+        if (reslevel->coord[1][1] == reslevel->coord[1][0])
+            reslevel->num_precincts_y = 0;
+        else
+            reslevel->num_precincts_y =
+                ff_jpeg2000_ceildivpow2(reslevel->coord[1][1],
+                                        reslevel->log2_prec_height) -
+                (reslevel->coord[1][0] >> reslevel->log2_prec_height);
+
+        reslevel->band = av_malloc_array(reslevel->nbands, sizeof(*reslevel->band));
+        if (!reslevel->band)
+            return AVERROR(ENOMEM);
+
+        for (bandno = 0; bandno < reslevel->nbands; bandno++, gbandno++) {
+            Jpeg2000Band *band = reslevel->band + bandno;
+            int cblkno, precno;
+            int nb_precincts;
+
+            /* TODO: Implementation of quantization step not finished,
+             * see ISO/IEC 15444-1:2002 E.1 and A.6.4. */
+            switch (qntsty->quantsty) {
+                uint8_t gain;
+                int numbps;
+            case JPEG2000_QSTY_NONE:
+                /* TODO: to verify. No quantization in this case */
+                band->f_stepsize = 1;
+                break;
+            case JPEG2000_QSTY_SI:
+                /*TODO: Compute formula to implement. */
+                numbps = cbps +
+                         lut_gain[codsty->transform == FF_DWT53][bandno + (reslevelno > 0)];
+                band->f_stepsize = SHL(2048 + qntsty->mant[gbandno],
+                                       2 + numbps - qntsty->expn[gbandno]);
+                break;
+            case JPEG2000_QSTY_SE:
+                /* Exponent quantization step.
+                 * Formula:
+                 * delta_b = 2 ^ (R_b - expn_b) * (1 + (mant_b / 2 ^ 11))
+                 * R_b = R_I + log2 (gain_b )
+                 * see ISO/IEC 15444-1:2002 E.1.1 eqn. E-3 and E-4 */
+                /* TODO/WARN: value of log2 (gain_b ) not taken into account
+                 * but it works (compared to OpenJPEG). Why?
+                 * Further investigation needed. */
+                gain            = cbps;
+                band->f_stepsize  = pow(2.0, gain - qntsty->expn[gbandno]);
+                band->f_stepsize *= qntsty->mant[gbandno] / 2048.0 + 1.0;
+                break;
+            default:
+                band->f_stepsize = 0;
+                av_log(avctx, AV_LOG_ERROR, "Unknown quantization format\n");
+                break;
+            }
+            /* FIXME: In openjepg code stespize = stepsize * 0.5. Why?
+             * If not set output of entropic decoder is not correct. */
+            if (!av_codec_is_encoder(avctx->codec))
+                band->f_stepsize *= 0.5;
+
+            band->i_stepsize = band->f_stepsize * (1 << 16);
+
+            /* computation of tbx_0, tbx_1, tby_0, tby_1
+             * see ISO/IEC 15444-1:2002 B.5 eq. B-15 and tbl B.1
+             * codeblock width and height is computed for
+             * DCI JPEG 2000 codeblock_width = codeblock_width = 32 = 2 ^ 5 */
+            if (reslevelno == 0) {
+                /* for reslevelno = 0, only one band, x0_b = y0_b = 0 */
+                for (i = 0; i < 2; i++)
+                    for (j = 0; j < 2; j++)
+                        band->coord[i][j] =
+                            ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0],
+                                                    declvl - 1);
+                log2_band_prec_width  = reslevel->log2_prec_width;
+                log2_band_prec_height = reslevel->log2_prec_height;
+                /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */
+                band->log2_cblk_width  = FFMIN(codsty->log2_cblk_width,
+                                               reslevel->log2_prec_width);
+                band->log2_cblk_height = FFMIN(codsty->log2_cblk_height,
+                                               reslevel->log2_prec_height);
+            } else {
+                /* 3 bands x0_b = 1 y0_b = 0; x0_b = 0 y0_b = 1; x0_b = y0_b = 1 */
+                /* x0_b and y0_b are computed with ((bandno + 1 >> i) & 1) */
+                for (i = 0; i < 2; i++)
+                    for (j = 0; j < 2; j++)
+                        /* Formula example for tbx_0 = ceildiv((tcx_0 - 2 ^ (declvl - 1) * x0_b) / declvl) */
+                        band->coord[i][j] =
+                            ff_jpeg2000_ceildivpow2(comp->coord_o[i][j] - comp->coord_o[i][0] -
+                                                    (((bandno + 1 >> i) & 1) << declvl - 1),
+                                                    declvl);
+                /* TODO: Manage case of 3 band offsets here or
+                 * in coding/decoding function? */
+
+                /* see ISO/IEC 15444-1:2002 eq. B-17 and eq. B-15 */
+                band->log2_cblk_width  = FFMIN(codsty->log2_cblk_width,
+                                               reslevel->log2_prec_width - 1);
+                band->log2_cblk_height = FFMIN(codsty->log2_cblk_height,
+                                               reslevel->log2_prec_height - 1);
+
+                log2_band_prec_width  = reslevel->log2_prec_width  - 1;
+                log2_band_prec_height = reslevel->log2_prec_height - 1;
+            }
+
+            for (j = 0; j < 2; j++)
+                band->coord[0][j] = ff_jpeg2000_ceildiv(band->coord[0][j], dx);
+            for (j = 0; j < 2; j++)
+                band->coord[1][j] = ff_jpeg2000_ceildiv(band->coord[1][j], dy);
+
+            band->prec = av_malloc_array(reslevel->num_precincts_x *
+                                         reslevel->num_precincts_y,
+                                         sizeof(*band->prec));
+            if (!band->prec)
+                return AVERROR(ENOMEM);
+
+            nb_precincts = reslevel->num_precincts_x * reslevel->num_precincts_y;
+
+            for (precno = 0; precno < nb_precincts; precno++) {
+                Jpeg2000Prec *prec = band->prec + precno;
+
+                /* TODO: Explain formula for JPEG200 DCINEMA. */
+                /* TODO: Verify with previous count of codeblocks per band */
+
+                /* Compute P_x0 */
+                prec->coord[0][0] = (precno % reslevel->num_precincts_x) *
+                                    (1 << log2_band_prec_width);
+                prec->coord[0][0] = FFMAX(prec->coord[0][0], band->coord[0][0]);
+
+                /* Compute P_y0 */
+                prec->coord[1][0] = (precno / reslevel->num_precincts_x) *
+                                    (1 << log2_band_prec_height);
+                prec->coord[1][0] = FFMAX(prec->coord[1][0], band->coord[1][0]);
+
+                /* Compute P_x1 */
+                prec->coord[0][1] = prec->coord[0][0] +
+                                    (1 << log2_band_prec_width);
+                prec->coord[0][1] = FFMIN(prec->coord[0][1], band->coord[0][1]);
+
+                /* Compute P_y1 */
+                prec->coord[1][1] = prec->coord[1][0] +
+                                    (1 << log2_band_prec_height);
+                prec->coord[1][1] = FFMIN(prec->coord[1][1], band->coord[1][1]);
+
+                prec->nb_codeblocks_width =
+                    ff_jpeg2000_ceildivpow2(prec->coord[0][1] -
+                                            prec->coord[0][0],
+                                            band->log2_cblk_width);
+                prec->nb_codeblocks_height =
+                    ff_jpeg2000_ceildivpow2(prec->coord[1][1] -
+                                            prec->coord[1][0],
+                                            band->log2_cblk_height);
+
+                /* Tag trees initialization */
+                prec->cblkincl =
+                    ff_jpeg2000_tag_tree_init(prec->nb_codeblocks_width,
+                                              prec->nb_codeblocks_height);
+                if (!prec->cblkincl)
+                    return AVERROR(ENOMEM);
+
+                prec->zerobits =
+                    ff_jpeg2000_tag_tree_init(prec->nb_codeblocks_width,
+                                              prec->nb_codeblocks_height);
+                if (!prec->zerobits)
+                    return AVERROR(ENOMEM);
+
+                prec->cblk = av_mallocz_array(prec->nb_codeblocks_width *
+                                              prec->nb_codeblocks_height,
+                                              sizeof(*prec->cblk));
+                if (!prec->cblk)
+                    return AVERROR(ENOMEM);
+                for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
+                    Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+                    uint16_t Cx0, Cy0;
+
+                    /* Compute coordinates of codeblocks */
+                    /* Compute Cx0*/
+                    Cx0 = (prec->coord[0][0] >> band->log2_cblk_width) << band->log2_cblk_width;
+                    Cx0 = Cx0 + ((cblkno % prec->nb_codeblocks_width)  << band->log2_cblk_width);
+                    cblk->coord[0][0] = FFMAX(Cx0, prec->coord[0][0]);
+
+                    /* Compute Cy0*/
+                    Cy0 = (prec->coord[1][0] >> band->log2_cblk_height) << band->log2_cblk_height;
+                    Cy0 = Cy0 + ((cblkno / prec->nb_codeblocks_width)   << band->log2_cblk_height);
+                    cblk->coord[1][0] = FFMAX(Cy0, prec->coord[1][0]);
+
+                    /* Compute Cx1 */
+                    cblk->coord[0][1] = FFMIN(Cx0 + (1 << band->log2_cblk_width),
+                                              prec->coord[0][1]);
+
+                    /* Compute Cy1 */
+                    cblk->coord[1][1] = FFMIN(Cy0 + (1 << band->log2_cblk_height),
+                                              prec->coord[1][1]);
+                    /* Update code-blocks coordinates according sub-band position */
+                    if ((bandno + !!reslevelno) & 1) {
+                        cblk->coord[0][0] += comp->reslevel[reslevelno-1].coord[0][1] -
+                                             comp->reslevel[reslevelno-1].coord[0][0];
+                        cblk->coord[0][1] += comp->reslevel[reslevelno-1].coord[0][1] -
+                                             comp->reslevel[reslevelno-1].coord[0][0];
+                    }
+                    if ((bandno + !!reslevelno) & 2) {
+                        cblk->coord[1][0] += comp->reslevel[reslevelno-1].coord[1][1] -
+                                             comp->reslevel[reslevelno-1].coord[1][0];
+                        cblk->coord[1][1] += comp->reslevel[reslevelno-1].coord[1][1] -
+                                             comp->reslevel[reslevelno-1].coord[1][0];
+                    }
+
+                    cblk->zero      = 0;
+                    cblk->lblock    = 3;
+                    cblk->length    = 0;
+                    cblk->lengthinc = 0;
+                    cblk->npasses   = 0;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty)
+{
+    int reslevelno, bandno, precno;
+    for (reslevelno = 0;
+         comp->reslevel && reslevelno < codsty->nreslevels;
+         reslevelno++) {
+        Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno;
+
+        for (bandno = 0; bandno < reslevel->nbands; bandno++) {
+            Jpeg2000Band *band = reslevel->band + bandno;
+            for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++) {
+                Jpeg2000Prec *prec = band->prec + precno;
+                av_freep(&prec->zerobits);
+                av_freep(&prec->cblkincl);
+                av_freep(&prec->cblk);
+            }
+
+            av_freep(&band->prec);
+        }
+        av_freep(&reslevel->band);
+    }
+
+    ff_dwt_destroy(&comp->dwt);
+    av_freep(&comp->reslevel);
+    av_freep(&comp->i_data);
+    av_freep(&comp->f_data);
+}
diff --git a/libavcodec/jpeg2000.h b/libavcodec/jpeg2000.h
new file mode 100644
index 0000000..b96b7e2
--- /dev/null
+++ b/libavcodec/jpeg2000.h
@@ -0,0 +1,257 @@
+/*
+ * JPEG 2000 common defines, structures and functions
+ * Copyright (c) 2007 Kamil Nowosad
+ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_JPEG2000_H
+#define AVCODEC_JPEG2000_H
+
+/**
+ * @file
+ * JPEG 2000 structures and defines common
+ * to encoder and decoder
+ */
+
+#include <stdint.h>
+
+#include "avcodec.h"
+#include "mqc.h"
+#include "jpeg2000dwt.h"
+
+enum Jpeg2000Markers {
+    JPEG2000_SOC = 0xff4f, // start of codestream
+    JPEG2000_SIZ = 0xff51, // image and tile size
+    JPEG2000_COD,          // coding style default
+    JPEG2000_COC,          // coding style component
+    JPEG2000_TLM = 0xff55, // packed packet headers, tile-part header
+    JPEG2000_PLM = 0xff57, // tile-part lengths
+    JPEG2000_PLT,          // packet length, main header
+    JPEG2000_QCD = 0xff5c, // quantization default
+    JPEG2000_QCC,          // quantization component
+    JPEG2000_RGN,          // region of interest
+    JPEG2000_POC,          // progression order change
+    JPEG2000_PPM,          // packet length, tile-part header
+    JPEG2000_PPT,          // packed packet headers, main header
+    JPEG2000_CRG = 0xff63, // component registration
+    JPEG2000_COM,          // comment
+    JPEG2000_SOT = 0xff90, // start of tile-part
+    JPEG2000_SOP,          // start of packet
+    JPEG2000_EPH,          // end of packet header
+    JPEG2000_SOD,          // start of data
+    JPEG2000_EOC = 0xffd9, // end of codestream
+};
+
+enum Jpeg2000Quantsty { // quantization style
+    JPEG2000_QSTY_NONE, // no quantization
+    JPEG2000_QSTY_SI,   // scalar derived
+    JPEG2000_QSTY_SE    // scalar expounded
+};
+
+#define JPEG2000_MAX_CBLKW 64
+#define JPEG2000_MAX_CBLKH 64
+
+
+#define JPEG2000_MAX_DECLEVELS 32
+#define JPEG2000_MAX_RESLEVELS (JPEG2000_MAX_DECLEVELS + 1)
+
+// T1 flags
+// flags determining significance of neighbor coefficients
+#define JPEG2000_T1_SIG_N  0x0001
+#define JPEG2000_T1_SIG_E  0x0002
+#define JPEG2000_T1_SIG_W  0x0004
+#define JPEG2000_T1_SIG_S  0x0008
+#define JPEG2000_T1_SIG_NE 0x0010
+#define JPEG2000_T1_SIG_NW 0x0020
+#define JPEG2000_T1_SIG_SE 0x0040
+#define JPEG2000_T1_SIG_SW 0x0080
+#define JPEG2000_T1_SIG_NB (JPEG2000_T1_SIG_N  | JPEG2000_T1_SIG_E  |   \
+                            JPEG2000_T1_SIG_S  | JPEG2000_T1_SIG_W  |   \
+                            JPEG2000_T1_SIG_NE | JPEG2000_T1_SIG_NW |   \
+                            JPEG2000_T1_SIG_SE | JPEG2000_T1_SIG_SW)
+// flags determining sign bit of neighbor coefficients
+#define JPEG2000_T1_SGN_N  0x0100
+#define JPEG2000_T1_SGN_S  0x0200
+#define JPEG2000_T1_SGN_W  0x0400
+#define JPEG2000_T1_SGN_E  0x0800
+
+#define JPEG2000_T1_VIS    0x1000
+#define JPEG2000_T1_SIG    0x2000
+#define JPEG2000_T1_REF    0x4000
+
+#define JPEG2000_T1_SGN    0x8000
+
+// Codeblock coding styles
+#define JPEG2000_CBLK_BYPASS    0x01 // Selective arithmetic coding bypass
+#define JPEG2000_CBLK_RESET     0x02 // Reset context probabilities
+#define JPEG2000_CBLK_TERMALL   0x04 // Terminate after each coding pass
+#define JPEG2000_CBLK_VSC       0x08 // Vertical stripe causal context formation
+#define JPEG2000_CBLK_PREDTERM  0x10 // Predictable termination
+#define JPEG2000_CBLK_SEGSYM    0x20 // Segmentation symbols present
+
+// Coding styles
+#define JPEG2000_CSTY_PREC      0x01 // Precincts defined in coding style
+#define JPEG2000_CSTY_SOP       0x02 // SOP marker present
+#define JPEG2000_CSTY_EPH       0x04 // EPH marker present
+
+// Progression orders
+#define JPEG2000_PGOD_LRCP      0x00  // Layer-resolution level-component-position progression
+#define JPEG2000_PGOD_RLCP      0x01  // Resolution level-layer-component-position progression
+#define JPEG2000_PGOD_RPCL      0x02  // Resolution level-position-component-layer progression
+#define JPEG2000_PGOD_PCRL      0x03  // Position-component-resolution level-layer progression
+#define JPEG2000_PGOD_CPRL      0x04  // Component-position-resolution level-layer progression
+
+typedef struct Jpeg2000T1Context {
+    int data[JPEG2000_MAX_CBLKW][JPEG2000_MAX_CBLKH];
+    int flags[JPEG2000_MAX_CBLKW + 2][JPEG2000_MAX_CBLKH + 2];
+    MqcState mqc;
+} Jpeg2000T1Context;
+
+typedef struct Jpeg2000TgtNode {
+    uint8_t val;
+    uint8_t vis;
+    struct Jpeg2000TgtNode *parent;
+} Jpeg2000TgtNode;
+
+typedef struct Jpeg2000CodingStyle {
+    uint8_t nreslevels;       // number of resolution levels
+    uint8_t nreslevels2decode; // number of resolution levels to decode
+    uint8_t log2_cblk_width,
+            log2_cblk_height; // exponent of codeblock size
+    uint8_t transform;        // DWT type
+    uint8_t csty;             // coding style
+    uint8_t nlayers;          // number of layers
+    uint8_t mct;              // multiple component transformation
+    uint8_t cblk_style;       // codeblock coding style
+    uint8_t prog_order;       // progression order
+    uint8_t log2_prec_widths[JPEG2000_MAX_RESLEVELS];  // precincts size according resolution levels
+    uint8_t log2_prec_heights[JPEG2000_MAX_RESLEVELS]; // TODO: initialize prec_size array with 0?
+} Jpeg2000CodingStyle;
+
+typedef struct Jpeg2000QuantStyle {
+    uint8_t expn[JPEG2000_MAX_DECLEVELS * 3];  // quantization exponent
+    uint32_t mant[JPEG2000_MAX_DECLEVELS * 3]; // quantization mantissa
+    uint8_t quantsty;      // quantization style
+    uint8_t nguardbits;    // number of guard bits
+} Jpeg2000QuantStyle;
+
+typedef struct Jpeg2000Cblk {
+    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];
+    uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
+} Jpeg2000Cblk; // code block
+
+typedef struct Jpeg2000Prec {
+    uint16_t nb_codeblocks_width;
+    uint16_t nb_codeblocks_height;
+    Jpeg2000TgtNode *zerobits;
+    Jpeg2000TgtNode *cblkincl;
+    Jpeg2000Cblk *cblk;
+    uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
+} Jpeg2000Prec; // precinct
+
+typedef struct Jpeg2000Band {
+    uint16_t coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
+    uint16_t log2_cblk_width, log2_cblk_height;
+    int i_stepsize; // quantization stepsize
+    float f_stepsize; // quantization stepsize
+    Jpeg2000Prec *prec;
+} Jpeg2000Band; // subband
+
+typedef struct Jpeg2000ResLevel {
+    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
+    Jpeg2000Band *band;
+} Jpeg2000ResLevel; // resolution level
+
+typedef struct Jpeg2000Component {
+    Jpeg2000ResLevel *reslevel;
+    DWTContext dwt;
+    float *f_data;
+    int *i_data;
+    uint16_t coord[2][2];   // border coordinates {{x0, x1}, {y0, y1}} -- can be reduced with lowres option
+    uint16_t coord_o[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- original values from jpeg2000 headers
+} Jpeg2000Component;
+
+/* misc tools */
+static inline int ff_jpeg2000_ceildivpow2(int a, int b)
+{
+    return (a + (1 << b) - 1) >> b;
+}
+
+static inline int ff_jpeg2000_ceildiv(int a, int b)
+{
+    return (a + b - 1) / b;
+}
+
+/* TIER-1 routines */
+
+/* Set up lookup tables used in TIER-1. */
+void ff_jpeg2000_init_tier1_luts(void);
+
+/* Update significance of a coefficient at current position (x,y) and
+ * for neighbors. */
+void ff_jpeg2000_set_significance(Jpeg2000T1Context *t1,
+                                  int x, int y, int negative);
+
+extern uint8_t ff_jpeg2000_sigctxno_lut[256][4];
+
+/* Get context label (number in range[0..8]) of a coefficient for significance
+ * propagation and cleanup coding passes. */
+static inline int ff_jpeg2000_getsigctxno(int flag, int bandno)
+{
+    return ff_jpeg2000_sigctxno_lut[flag & 255][bandno];
+}
+
+static const uint8_t refctxno_lut[2][2] = { { 14, 15 }, { 16, 16 } };
+
+/* Get context label (number in range[14..16]) of a coefficient for magnitude
+ * refinement pass. */
+static inline int ff_jpeg2000_getrefctxno(int flag)
+{
+    return refctxno_lut[(flag >> 14) & 1][(flag & 255) != 0];
+}
+
+extern uint8_t ff_jpeg2000_sgnctxno_lut[16][16];
+extern uint8_t ff_jpeg2000_xorbit_lut[16][16];
+
+/* Get context label (number in range[9..13]) for sign decoding. */
+static inline int ff_jpeg2000_getsgnctxno(int flag, int *xorbit)
+{
+    *xorbit = ff_jpeg2000_xorbit_lut[flag & 15][(flag >> 8) & 15];
+    return ff_jpeg2000_sgnctxno_lut[flag & 15][(flag >> 8) & 15];
+}
+
+int ff_jpeg2000_init_component(Jpeg2000Component *comp,
+                               Jpeg2000CodingStyle *codsty,
+                               Jpeg2000QuantStyle *qntsty,
+                               int cbps, int dx, int dy,
+                               AVCodecContext *ctx);
+
+void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty);
+
+#endif /* AVCODEC_JPEG2000_H */
diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c
new file mode 100644
index 0000000..cc154c3
--- /dev/null
+++ b/libavcodec/jpeg2000dec.c
@@ -0,0 +1,1512 @@
+/*
+ * JPEG 2000 image decoder
+ * Copyright (c) 2007 Kamil Nowosad
+ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * JPEG 2000 image decoder
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "thread.h"
+#include "jpeg2000.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 Jpeg2000TilePart {
+    uint8_t tile_index;                 // Tile index who refers the tile-part
+    const uint8_t *tp_end;
+    GetByteContext tpg;                 // bit stream in tile-part
+} Jpeg2000TilePart;
+
+/* RMK: For JPEG2000 DCINEMA 3 tile-parts in a tile
+ * one per component, so tile_part elements have a size of 3 */
+typedef struct Jpeg2000Tile {
+    Jpeg2000Component   *comp;
+    uint8_t             properties[4];
+    Jpeg2000CodingStyle codsty[4];
+    Jpeg2000QuantStyle  qntsty[4];
+    Jpeg2000TilePart    tile_part[3];
+    uint16_t tp_idx;                    // Tile-part index
+} Jpeg2000Tile;
+
+typedef struct Jpeg2000DecoderContext {
+    AVClass         *class;
+    AVCodecContext  *avctx;
+    GetByteContext g;
+
+    int             width, height;
+    int             image_offset_x, image_offset_y;
+    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;
+    unsigned        numXtiles, numYtiles;
+    int             maxtilelen;
+
+    Jpeg2000CodingStyle codsty[4];
+    Jpeg2000QuantStyle  qntsty[4];
+
+    int             bit_index;
+
+    int16_t         curtileno;
+    Jpeg2000Tile    *tile;
+
+    /*options parameters*/
+    int             reduction_factor;
+} Jpeg2000DecoderContext;
+
+/* get_bits functions for JPEG2000 packet bitstream
+ * It is a get_bit function with a bit-stuffing routine. If the value of the
+ * byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB.
+ * cf. ISO-15444-1:2002 / B.10.1 Bit-stuffing routine */
+static int get_bits(Jpeg2000DecoderContext *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 jpeg2000_flush(Jpeg2000DecoderContext *s)
+{
+    if (bytestream2_get_byte(&s->g) == 0xff)
+        bytestream2_skip(&s->g, 1);
+    s->bit_index = 8;
+}
+
+/* decode the value stored in node */
+static int tag_tree_decode(Jpeg2000DecoderContext *s, Jpeg2000TgtNode *node,
+                           int threshold)
+{
+    Jpeg2000TgtNode *stack[30];
+    int sp = -1, curval = 0;
+
+    if (!node)
+        return AVERROR_INVALIDDATA;
+
+    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(Jpeg2000DecoderContext *s)
+{
+    int i;
+    int ncomponents;
+
+    if (bytestream2_get_bytes_left(&s->g) < 36)
+        return AVERROR_INVALIDDATA;
+
+    s->avctx->profile = bytestream2_get_be16u(&s->g); // Rsiz
+    s->width          = bytestream2_get_be32u(&s->g); // Width
+    s->height         = bytestream2_get_be32u(&s->g); // Height
+    s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz
+    s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz
+    s->tile_width     = bytestream2_get_be32u(&s->g); // XTSiz
+    s->tile_height    = bytestream2_get_be32u(&s->g); // YTSiz
+    s->tile_offset_x  = bytestream2_get_be32u(&s->g); // XT0Siz
+    s->tile_offset_y  = bytestream2_get_be32u(&s->g); // YT0Siz
+    ncomponents       = bytestream2_get_be16u(&s->g); // CSiz
+
+    if (ncomponents <= 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid number of components: %d\n",
+               s->ncomponents);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (ncomponents > 3) {
+        avpriv_request_sample(s->avctx, "Support for %d components",
+                              s->ncomponents);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    s->ncomponents = ncomponents;
+
+    if (s->tile_width <= 0 || s->tile_height <= 0 ||
+        s->tile_width > s->width || s->tile_height > s->height) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid tile dimension %dx%d.\n",
+               s->tile_width, s->tile_height);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents)
+        return AVERROR_INVALIDDATA;
+
+    for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i
+        uint8_t x    = 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);
+
+        if (s->cdx[i] != 1 || s->cdy[i] != 1) {
+            avpriv_request_sample(s->avctx,
+                                  "CDxy values %d %d for component %d",
+                                  s->cdx[i], s->cdy[i], i);
+            if (!s->cdx[i] || !s->cdy[i])
+                return AVERROR_INVALIDDATA;
+            else
+                return AVERROR_PATCHWELCOME;
+        }
+    }
+
+    s->numXtiles = ff_jpeg2000_ceildiv(s->width  - s->tile_offset_x, s->tile_width);
+    s->numYtiles = ff_jpeg2000_ceildiv(s->height - s->tile_offset_y, s->tile_height);
+
+    s->tile = av_mallocz_array(s->numXtiles * s->numYtiles, sizeof(*s->tile));
+    if (!s->tile) {
+        s->numXtiles = s->numYtiles = 0;
+        return AVERROR(ENOMEM);
+    }
+
+    for (i = 0; i < s->numXtiles * s->numYtiles; i++) {
+        Jpeg2000Tile *tile = s->tile + i;
+
+        tile->comp = av_mallocz(s->ncomponents * sizeof(*tile->comp));
+        if (!tile->comp)
+            return AVERROR(ENOMEM);
+    }
+
+    /* compute image size with reduction factor */
+    s->avctx->width  = ff_jpeg2000_ceildivpow2(s->width  - s->image_offset_x,
+                                               s->reduction_factor);
+    s->avctx->height = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
+                                               s->reduction_factor);
+
+    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:
+        switch (s->avctx->profile) {
+        case FF_PROFILE_JPEG2000_DCINEMA_2K:
+        case FF_PROFILE_JPEG2000_DCINEMA_4K:
+            /* XYZ color-space for digital cinema profiles */
+            s->avctx->pix_fmt = AV_PIX_FMT_XYZ12;
+            break;
+        default:
+            if (s->precision > 8)
+                s->avctx->pix_fmt = AV_PIX_FMT_RGB48;
+            else
+                s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
+            break;
+        }
+        break;
+    case 4:
+        s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
+        break;
+    default:
+        /* pixel format can not be identified */
+        s->avctx->pix_fmt = AV_PIX_FMT_NONE;
+        break;
+    }
+    return 0;
+}
+
+/* get common part for COD and COC segments */
+static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
+{
+    uint8_t byte;
+
+    if (bytestream2_get_bytes_left(&s->g) < 5)
+        return AVERROR_INVALIDDATA;
+
+    /*  nreslevels = number of resolution levels
+                   = number of decomposition level +1 */
+    c->nreslevels = bytestream2_get_byteu(&s->g) + 1;
+
+    if (c->nreslevels > JPEG2000_MAX_RESLEVELS)
+        return AVERROR_INVALIDDATA;
+
+    /* compute number of resolution levels to decode */
+    if (c->nreslevels < s->reduction_factor)
+        c->nreslevels2decode = 1;
+    else
+        c->nreslevels2decode = c->nreslevels - s->reduction_factor;
+
+    c->log2_cblk_width  = bytestream2_get_byteu(&s->g) + 2; // cblk width
+    c->log2_cblk_height = bytestream2_get_byteu(&s->g) + 2; // cblk height
+
+    if (c->log2_cblk_width > 10 || c->log2_cblk_height > 10 ||
+        c->log2_cblk_width + c->log2_cblk_height > 12) {
+        av_log(s->avctx, AV_LOG_ERROR, "cblk size invalid\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    c->cblk_style = bytestream2_get_byteu(&s->g);
+    if (c->cblk_style != 0) { // cblk style
+        avpriv_request_sample(s->avctx, "Support for extra cblk styles");
+        return AVERROR_PATCHWELCOME;
+    }
+    c->transform = bytestream2_get_byteu(&s->g); // DWT transformation type
+    /* set integer 9/7 DWT in case of BITEXACT flag */
+    if ((s->avctx->flags & CODEC_FLAG_BITEXACT) && (c->transform == FF_DWT97))
+        c->transform = FF_DWT97_INT;
+
+    if (c->csty & JPEG2000_CSTY_PREC) {
+        int i;
+        for (i = 0; i < c->nreslevels; i++) {
+            byte = bytestream2_get_byte(&s->g);
+            c->log2_prec_widths[i]  =  byte       & 0x0F;    // precinct PPx
+            c->log2_prec_heights[i] = (byte >> 4) & 0x0F;    // precinct PPy
+        }
+    } else {
+        memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths ));
+        memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights));
+    }
+    return 0;
+}
+
+/* get coding parameters for a particular tile or whole image*/
+static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
+                   uint8_t *properties)
+{
+    Jpeg2000CodingStyle tmp;
+    int compno, ret;
+
+    if (bytestream2_get_bytes_left(&s->g) < 5)
+        return AVERROR_INVALIDDATA;
+
+    tmp.csty = bytestream2_get_byteu(&s->g);
+
+    // get progression order
+    tmp.prog_order = bytestream2_get_byteu(&s->g);
+
+    tmp.nlayers    = bytestream2_get_be16u(&s->g);
+    tmp.mct        = bytestream2_get_byteu(&s->g); // multiple component transformation
+
+    if (tmp.mct && s->ncomponents < 3) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "MCT %d with too few components (%d)\n",
+               tmp.mct, s->ncomponents);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((ret = get_cox(s, &tmp)) < 0)
+        return ret;
+
+    for (compno = 0; compno < s->ncomponents; compno++)
+        if (!(properties[compno] & HAD_COC))
+            memcpy(c + compno, &tmp, sizeof(tmp));
+    return 0;
+}
+
+/* Get coding parameters for a component in the whole image or a
+ * particular tile. */
+static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
+                   uint8_t *properties)
+{
+    int compno, ret;
+
+    if (bytestream2_get_bytes_left(&s->g) < 2)
+        return AVERROR_INVALIDDATA;
+
+    compno = bytestream2_get_byteu(&s->g);
+
+    if (compno >= s->ncomponents) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Invalid compno %d. There are %d components in the image.\n",
+               compno, s->ncomponents);
+        return AVERROR_INVALIDDATA;
+    }
+
+    c      += compno;
+    c->csty = bytestream2_get_byteu(&s->g);
+
+    if ((ret = get_cox(s, c)) < 0)
+        return ret;
+
+    properties[compno] |= HAD_COC;
+    return 0;
+}
+
+/* Get common part for QCD and QCC segments. */
+static int get_qcx(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q)
+{
+    int i, x;
+
+    if (bytestream2_get_bytes_left(&s->g) < 1)
+        return AVERROR_INVALIDDATA;
+
+    x = bytestream2_get_byteu(&s->g); // Sqcd
+
+    q->nguardbits = x >> 5;
+    q->quantsty   = x & 0x1f;
+
+    if (q->quantsty == JPEG2000_QSTY_NONE) {
+        n -= 3;
+        if (bytestream2_get_bytes_left(&s->g) < n ||
+            n > JPEG2000_MAX_DECLEVELS)
+            return AVERROR_INVALIDDATA;
+        for (i = 0; i < n; i++)
+            q->expn[i] = bytestream2_get_byteu(&s->g) >> 3;
+    } else if (q->quantsty == JPEG2000_QSTY_SI) {
+        if (bytestream2_get_bytes_left(&s->g) < 2)
+            return AVERROR_INVALIDDATA;
+        x          = bytestream2_get_be16u(&s->g);
+        q->expn[0] = x >> 11;
+        q->mant[0] = x & 0x7ff;
+        for (i = 1; i < JPEG2000_MAX_DECLEVELS * 3; i++) {
+            int curexpn = FFMAX(0, q->expn[0] - (i - 1) / 3);
+            q->expn[i] = curexpn;
+            q->mant[i] = q->mant[0];
+        }
+    } else {
+        n = (n - 3) >> 1;
+        if (bytestream2_get_bytes_left(&s->g) < 2 * n ||
+            n > JPEG2000_MAX_DECLEVELS)
+            return AVERROR_INVALIDDATA;
+        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(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
+                   uint8_t *properties)
+{
+    Jpeg2000QuantStyle tmp;
+    int compno, ret;
+
+    if ((ret = get_qcx(s, n, &tmp)) < 0)
+        return ret;
+    for (compno = 0; compno < s->ncomponents; compno++)
+        if (!(properties[compno] & HAD_QCC))
+            memcpy(q + compno, &tmp, sizeof(tmp));
+    return 0;
+}
+
+/* Get quantization parameters for a component in the whole image
+ * on in a particular tile. */
+static int get_qcc(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
+                   uint8_t *properties)
+{
+    int compno;
+
+    if (bytestream2_get_bytes_left(&s->g) < 1)
+        return AVERROR_INVALIDDATA;
+
+    compno = bytestream2_get_byteu(&s->g);
+
+    if (compno >= s->ncomponents) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Invalid compno %d. There are %d components in the image.\n",
+               compno, s->ncomponents);
+        return AVERROR_INVALIDDATA;
+    }
+
+    properties[compno] |= HAD_QCC;
+    return get_qcx(s, n - 1, q + compno);
+}
+
+/* Get start of tile segment. */
+static int get_sot(Jpeg2000DecoderContext *s, int n)
+{
+    Jpeg2000TilePart *tp;
+    uint16_t Isot;
+    uint32_t Psot;
+    uint8_t TPsot;
+
+    if (bytestream2_get_bytes_left(&s->g) < 8)
+        return AVERROR_INVALIDDATA;
+
+    Isot = bytestream2_get_be16u(&s->g);        // Isot
+    if (Isot >= s->numXtiles * s->numYtiles)
+        return AVERROR_INVALIDDATA;
+
+    if (Isot) {
+        avpriv_request_sample(s->avctx, "Support for more than one tile");
+        return AVERROR_PATCHWELCOME;
+    }
+    Psot  = bytestream2_get_be32u(&s->g);       // Psot
+    TPsot = bytestream2_get_byteu(&s->g);       // TPsot
+
+    /* Read TNSot but not used */
+    bytestream2_get_byteu(&s->g);               // TNsot
+
+    if (Psot > bytestream2_get_bytes_left(&s->g) + n + 2) {
+        av_log(s->avctx, AV_LOG_ERROR, "Psot %d too big\n", Psot);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (TPsot >= FF_ARRAY_ELEMS(s->tile[Isot].tile_part)) {
+        avpriv_request_sample(s->avctx, "Support for %d components", TPsot);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    s->tile[Isot].tp_idx = TPsot;
+    tp             = s->tile[Isot].tile_part + TPsot;
+    tp->tile_index = Isot;
+    tp->tp_end     = s->g.buffer + Psot - n - 2;
+
+    if (!TPsot) {
+        Jpeg2000Tile *tile = s->tile + s->curtileno;
+
+        /* copy defaults */
+        memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(Jpeg2000CodingStyle));
+        memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(Jpeg2000QuantStyle));
+    }
+
+    return 0;
+}
+
+/* Tile-part lengths: see ISO 15444-1:2002, section A.7.1
+ * Used to know the number of tile parts and lengths.
+ * There may be multiple TLMs in the header.
+ * TODO: The function is not used for tile-parts management, nor anywhere else.
+ * It can be useful to allocate memory for tile parts, before managing the SOT
+ * markers. Parsing the TLM header is needed to increment the input header
+ * buffer.
+ * This marker is mandatory for DCI. */
+static uint8_t get_tlm(Jpeg2000DecoderContext *s, int n)
+{
+    uint8_t Stlm, ST, SP, tile_tlm, i;
+    bytestream2_get_byte(&s->g);               /* Ztlm: skipped */
+    Stlm = bytestream2_get_byte(&s->g);
+
+    // too complex ? ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
+    ST = (Stlm >> 4) & 0x03;
+    // TODO: Manage case of ST = 0b11 --> raise error
+    SP       = (Stlm >> 6) & 0x01;
+    tile_tlm = (n - 4) / ((SP + 1) * 2 + ST);
+    for (i = 0; i < tile_tlm; i++) {
+        switch (ST) {
+        case 0:
+            break;
+        case 1:
+            bytestream2_get_byte(&s->g);
+            break;
+        case 2:
+            bytestream2_get_be16(&s->g);
+            break;
+        case 3:
+            bytestream2_get_be32(&s->g);
+            break;
+        }
+        if (SP == 0) {
+            bytestream2_get_be16(&s->g);
+        } else {
+            bytestream2_get_be32(&s->g);
+        }
+    }
+    return 0;
+}
+
+static int init_tile(Jpeg2000DecoderContext *s, int tileno)
+{
+    int compno;
+    int tilex = tileno % s->numXtiles;
+    int tiley = tileno / s->numXtiles;
+    Jpeg2000Tile *tile = s->tile + tileno;
+
+    if (!tile->comp)
+        return AVERROR(ENOMEM);
+
+    for (compno = 0; compno < s->ncomponents; compno++) {
+        Jpeg2000Component *comp = tile->comp + compno;
+        Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+        Jpeg2000QuantStyle  *qntsty = tile->qntsty + compno;
+        int ret; // global bandno
+
+        comp->coord_o[0][0] = FFMAX(tilex       * s->tile_width  + s->tile_offset_x, s->image_offset_x);
+        comp->coord_o[0][1] = FFMIN((tilex + 1) * s->tile_width  + s->tile_offset_x, s->width);
+        comp->coord_o[1][0] = FFMAX(tiley       * s->tile_height + s->tile_offset_y, s->image_offset_y);
+        comp->coord_o[1][1] = FFMIN((tiley + 1) * s->tile_height + s->tile_offset_y, s->height);
+
+        comp->coord[0][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], s->reduction_factor);
+        comp->coord[0][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][1], s->reduction_factor);
+        comp->coord[1][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], s->reduction_factor);
+        comp->coord[1][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][1], s->reduction_factor);
+
+        if (ret = ff_jpeg2000_init_component(comp, codsty, qntsty,
+                                             s->cbps[compno], s->cdx[compno],
+                                             s->cdy[compno], s->avctx))
+            return ret;
+    }
+    return 0;
+}
+
+/* Read the number of coding passes. */
+static int getnpasses(Jpeg2000DecoderContext *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(Jpeg2000DecoderContext *s)
+{
+    int res = 0, ret;
+    while (ret = get_bits(s, 1)) {
+        if (ret < 0)
+            return ret;
+        res++;
+    }
+    return res;
+}
+
+static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s,
+                                  Jpeg2000CodingStyle *codsty,
+                                  Jpeg2000ResLevel *rlevel, int precno,
+                                  int layno, uint8_t *expn, int numgbits)
+{
+    int bandno, cblkno, ret, nb_code_blocks;
+
+    if (!(ret = get_bits(s, 1))) {
+        jpeg2000_flush(s);
+        return 0;
+    } else if (ret < 0)
+        return ret;
+
+    for (bandno = 0; bandno < rlevel->nbands; bandno++) {
+        Jpeg2000Band *band = rlevel->band + bandno;
+        Jpeg2000Prec *prec = band->prec + precno;
+
+        if (band->coord[0][0] == band->coord[0][1] ||
+            band->coord[1][0] == band->coord[1][1])
+            continue;
+        nb_code_blocks =  prec->nb_codeblocks_height *
+                          prec->nb_codeblocks_width;
+        for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
+            Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+            int incl, newpasses, llen;
+
+            if (cblk->npasses)
+                incl = get_bits(s, 1);
+            else
+                incl = tag_tree_decode(s, prec->cblkincl + cblkno, layno + 1) == layno;
+            if (!incl)
+                continue;
+            else if (incl < 0)
+                return incl;
+
+            if (!cblk->npasses) {
+                int v = expn[bandno] + numgbits - 1 -
+                        tag_tree_decode(s, prec->zerobits + cblkno, 100);
+                if (v < 0) {
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "nonzerobits %d invalid\n", v);
+                    return AVERROR_INVALIDDATA;
+                }
+                cblk->nonzerobits = v;
+            }
+            if ((newpasses = getnpasses(s)) < 0)
+                return newpasses;
+            if ((llen = getlblockinc(s)) < 0)
+                return llen;
+            cblk->lblock += llen;
+            if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0)
+                return ret;
+            if (ret > sizeof(cblk->data)) {
+                avpriv_request_sample(s->avctx,
+                                      "Block with lengthinc greater than %zu",
+                                      sizeof(cblk->data));
+                return AVERROR_PATCHWELCOME;
+            }
+            cblk->lengthinc = ret;
+            cblk->npasses  += newpasses;
+        }
+    }
+    jpeg2000_flush(s);
+
+    if (codsty->csty & JPEG2000_CSTY_EPH) {
+        if (bytestream2_peek_be16(&s->g) == JPEG2000_EPH)
+            bytestream2_skip(&s->g, 2);
+        else
+            av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n");
+    }
+
+    for (bandno = 0; bandno < rlevel->nbands; bandno++) {
+        Jpeg2000Band *band = rlevel->band + bandno;
+        Jpeg2000Prec *prec = band->prec + precno;
+
+        nb_code_blocks = prec->nb_codeblocks_height * prec->nb_codeblocks_width;
+        for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
+            Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+            if (bytestream2_get_bytes_left(&s->g) < cblk->lengthinc)
+                return AVERROR_INVALIDDATA;
+            /* Code-block data can be empty. In that case initialize data
+             * with 0xFFFF. */
+            if (cblk->lengthinc > 0) {
+                bytestream2_get_bufferu(&s->g, cblk->data, cblk->lengthinc);
+            } else {
+                cblk->data[0] = 0xFF;
+                cblk->data[1] = 0xFF;
+            }
+            cblk->length   += cblk->lengthinc;
+            cblk->lengthinc = 0;
+
+            if (cblk->length > sizeof(cblk->data)) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "Block length %d > data size %zd\n",
+                       cblk->length, sizeof(cblk->data));
+                return AVERROR_INVALIDDATA;
+            }
+        }
+    }
+    return 0;
+}
+
+static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+{
+    int ret = 0;
+    int layno, reslevelno, compno, precno, ok_reslevel;
+    int x, y;
+
+    s->bit_index = 8;
+    switch (tile->codsty[0].prog_order) {
+    case JPEG2000_PGOD_LRCP:
+        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++) {
+                    Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+                    Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
+                    if (reslevelno < codsty->nreslevels) {
+                        Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
+                                                   reslevelno;
+                        ok_reslevel = 1;
+                        for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
+                            if ((ret = jpeg2000_decode_packet(s,
+                                                              codsty, rlevel,
+                                                              precno, layno,
+                                                              qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+                                                              qntsty->nguardbits)) < 0)
+                                return ret;
+                    }
+                }
+            }
+        }
+        break;
+
+    case JPEG2000_PGOD_CPRL:
+        for (compno = 0; compno < s->ncomponents; compno++) {
+            Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+            Jpeg2000QuantStyle *qntsty  = tile->qntsty + compno;
+
+            /* Set bit stream buffer address according to tile-part.
+             * For DCinema one tile-part per component, so can be
+             * indexed by component. */
+            s->g = tile->tile_part[compno].tpg;
+
+            /* Position loop (y axis)
+             * TODO: Automate computing of step 256.
+             * Fixed here, but to be computed before entering here. */
+            for (y = 0; y < s->height; y += 256) {
+                /* Position loop (y axis)
+                 * TODO: automate computing of step 256.
+                 * Fixed here, but to be computed before entering here. */
+                for (x = 0; x < s->width; x += 256) {
+                    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++) {
+                        uint16_t prcx, prcy;
+                        uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; //  ==> N_L - r
+                        Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel + reslevelno;
+
+                        if (!((y % (1 << (rlevel->log2_prec_height + reducedresno)) == 0) ||
+                              (y == 0))) // TODO: 2nd condition simplified as try0 always =0 for dcinema
+                            continue;
+
+                        if (!((x % (1 << (rlevel->log2_prec_width + reducedresno)) == 0) ||
+                              (x == 0))) // TODO: 2nd condition simplified as try0 always =0 for dcinema
+                            continue;
+
+                        // check if a precinct exists
+                        prcx   = ff_jpeg2000_ceildivpow2(x, reducedresno) >> rlevel->log2_prec_width;
+                        prcy   = ff_jpeg2000_ceildivpow2(y, reducedresno) >> rlevel->log2_prec_height;
+                        precno = prcx + rlevel->num_precincts_x * prcy;
+                        for (layno = 0; layno < tile->codsty[0].nlayers; layno++) {
+                            if ((ret = jpeg2000_decode_packet(s, codsty, rlevel,
+                                                              precno, layno,
+                                                              qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+                                                              qntsty->nguardbits)) < 0)
+                                return ret;
+                        }
+                    }
+                }
+            }
+        }
+        break;
+
+    case JPEG2000_PGOD_RLCP:
+        avpriv_request_sample(s->avctx, "Progression order RLCP");
+        ret = AVERROR_PATCHWELCOME;
+        break;
+
+    case JPEG2000_PGOD_RPCL:
+        avpriv_request_sample(s->avctx, "Progression order RPCL");
+        ret = AVERROR_PATCHWELCOME;
+        break;
+
+    case JPEG2000_PGOD_PCRL:
+        avpriv_request_sample(s->avctx, "Progression order PCRL");
+        ret = AVERROR_PATCHWELCOME;
+        break;
+
+    default:
+        break;
+    }
+
+    /* EOC marker reached */
+    bytestream2_skip(&s->g, 2);
+
+    return ret;
+}
+
+/* TIER-1 routines */
+static void decode_sigpass(Jpeg2000T1Context *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] & JPEG2000_T1_SIG_NB)
+                && !(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
+                    int flags_mask = -1;
+                    if (vert_causal_ctx_csty_symbol && y == y0 + 3)
+                        flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE);
+                    if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask, bandno))) {
+                        int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                        if (bpass_csty_symbol)
+                             t1->data[y][x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask;
+                        else
+                             t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ?
+                                               -mask : mask;
+
+                        ff_jpeg2000_set_significance(t1, x, y,
+                                                     t1->data[y][x] < 0);
+                    }
+                    t1->flags[y + 1][x + 1] |= JPEG2000_T1_VIS;
+                }
+            }
+}
+
+static void decode_refpass(Jpeg2000T1Context *t1, int width, int height,
+                           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] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG) {
+                    int ctxno = ff_jpeg2000_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] |= JPEG2000_T1_REF;
+                }
+}
+
+static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
+                           int width, int height, int bpno, int bandno,
+                           int seg_symbols, int vert_causal_ctx_csty_symbol)
+{
+    int mask = 3 << (bpno - 1), y0, x, y, runlen, dec;
+
+    for (y0 = 0; y0 < height; y0 += 4) {
+        for (x = 0; x < width; x++) {
+            if (y0 + 3 < height &&
+                !((t1->flags[y0 + 1][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+                  (t1->flags[y0 + 2][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+                  (t1->flags[y0 + 3][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+                  (t1->flags[y0 + 4][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)))) {
+                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] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
+                        int flags_mask = -1;
+                        if (vert_causal_ctx_csty_symbol && y == y0 + 3)
+                            flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE);
+                        dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask,
+                                                                                             bandno));
+                    }
+                }
+                if (dec) {
+                    int xorbit;
+                    int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y + 1][x + 1],
+                                                        &xorbit);
+                    t1->data[y][x] = (ff_mqc_decode(&t1->mqc,
+                                                    t1->mqc.cx_states + ctxno) ^
+                                      xorbit)
+                                     ? -mask : mask;
+                    ff_jpeg2000_set_significance(t1, x, y, t1->data[y][x] < 0);
+                }
+                dec = 0;
+                t1->flags[y + 1][x + 1] &= ~JPEG2000_T1_VIS;
+            }
+        }
+    }
+    if (seg_symbols) {
+        int val;
+        val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+        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(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
+                       Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,
+                       int width, int height, int bandpos)
+{
+    int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1, y;
+    int clnpass_cnt = 0;
+    int bpass_csty_symbol           = codsty->cblk_style & JPEG2000_CBLK_BYPASS;
+    int vert_causal_ctx_csty_symbol = codsty->cblk_style & JPEG2000_CBLK_VSC;
+
+    for (y = 0; y < height; y++)
+        memset(t1->data[y], 0, width * sizeof(**t1->data));
+
+    /* If code-block contains no compressed data: nothing to do. */
+    if (!cblk->length)
+        return 0;
+    for (y = 0; y < height + 2; y++)
+        memset(t1->flags[y], 0, (width + 2) * sizeof(**t1->flags));
+
+    ff_mqc_initdec(&t1->mqc, cblk->data);
+    cblk->data[cblk->length]     = 0xff;
+    cblk->data[cblk->length + 1] = 0xff;
+
+    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 & JPEG2000_CBLK_SEGSYM,
+                           vert_causal_ctx_csty_symbol);
+            clnpass_cnt = clnpass_cnt + 1;
+            if (bpass_csty_symbol && clnpass_cnt >= 4)
+                ff_mqc_initdec(&t1->mqc, cblk->data);
+            break;
+        }
+
+        pass_t++;
+        if (pass_t == 3) {
+            bpno--;
+            pass_t = 0;
+        }
+    }
+    return 0;
+}
+
+/* TODO: Verify dequantization for lossless case
+ * comp->data can be float or int
+ * band->stepsize can be float or int
+ * depending on the type of DWT transformation.
+ * see ISO/IEC 15444-1:2002 A.6.1 */
+
+/* Float dequantization of a codeblock.*/
+static void dequantization_float(int x, int y, Jpeg2000Cblk *cblk,
+                                 Jpeg2000Component *comp,
+                                 Jpeg2000T1Context *t1, Jpeg2000Band *band)
+{
+    int i, j;
+    int w = cblk->coord[0][1] - cblk->coord[0][0];
+    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
+        float *datap = &comp->f_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
+        int *src = t1->data[j];
+        for (i = 0; i < w; ++i)
+            datap[i] = src[i] * band->f_stepsize;
+    }
+}
+
+/* Integer dequantization of a codeblock.*/
+static void dequantization_int(int x, int y, Jpeg2000Cblk *cblk,
+                               Jpeg2000Component *comp,
+                               Jpeg2000T1Context *t1, Jpeg2000Band *band)
+{
+    int i, j;
+    int w = cblk->coord[0][1] - cblk->coord[0][0];
+    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
+        int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
+        int *src = t1->data[j];
+        for (i = 0; i < w; ++i)
+            datap[i] = (src[i] * band->i_stepsize + (1 << 15)) >> 16;
+    }
+}
+
+/* Inverse ICT parameters in float and integer.
+ * int value = (float value) * (1<<16) */
+static const float f_ict_params[4] = {
+    1.402f,
+    0.34413f,
+    0.71414f,
+    1.772f
+};
+static const int   i_ict_params[4] = {
+     91881,
+     22553,
+     46802,
+    116130
+};
+
+static void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+{
+    int i, csize = 1;
+    int32_t *src[3],  i0,  i1,  i2;
+    float   *srcf[3], i0f, i1f, i2f;
+
+    for (i = 0; i < 3; i++)
+        if (tile->codsty[0].transform == FF_DWT97)
+            srcf[i] = tile->comp[i].f_data;
+        else
+            src [i] = tile->comp[i].i_data;
+
+    for (i = 0; i < 2; i++)
+        csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
+    switch (tile->codsty[0].transform) {
+    case FF_DWT97:
+        for (i = 0; i < csize; i++) {
+            i0f = *srcf[0] + (f_ict_params[0] * *srcf[2]);
+            i1f = *srcf[0] - (f_ict_params[1] * *srcf[1])
+                           - (f_ict_params[2] * *srcf[2]);
+            i2f = *srcf[0] + (f_ict_params[3] * *srcf[1]);
+            *srcf[0]++ = i0f;
+            *srcf[1]++ = i1f;
+            *srcf[2]++ = i2f;
+        }
+        break;
+    case FF_DWT97_INT:
+        for (i = 0; i < csize; i++) {
+            i0 = *src[0] + (((i_ict_params[0] * *src[2]) + (1 << 15)) >> 16);
+            i1 = *src[0] - (((i_ict_params[1] * *src[1]) + (1 << 15)) >> 16)
+                         - (((i_ict_params[2] * *src[2]) + (1 << 15)) >> 16);
+            i2 = *src[0] + (((i_ict_params[3] * *src[1]) + (1 << 15)) >> 16);
+            *src[0]++ = i0;
+            *src[1]++ = i1;
+            *src[2]++ = i2;
+        }
+        break;
+    case FF_DWT53:
+        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;
+        }
+        break;
+    }
+}
+
+static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
+                                AVFrame *picture)
+{
+    int compno, reslevelno, bandno;
+    int x, y;
+
+    uint8_t *line;
+    Jpeg2000T1Context t1;
+    /* Loop on tile components */
+
+    for (compno = 0; compno < s->ncomponents; compno++) {
+        Jpeg2000Component *comp     = tile->comp + compno;
+        Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+        /* Loop on resolution levels */
+        for (reslevelno = 0; reslevelno < codsty->nreslevels2decode; reslevelno++) {
+            Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
+            /* Loop on bands */
+            for (bandno = 0; bandno < rlevel->nbands; bandno++) {
+                uint16_t nb_precincts, precno;
+                Jpeg2000Band *band = rlevel->band + bandno;
+                int cblkno = 0, bandpos;
+                bandpos = bandno + (reslevelno > 0);
+
+                if (band->coord[0][0] == band->coord[0][1] ||
+                    band->coord[1][0] == band->coord[1][1])
+                    continue;
+
+                nb_precincts = rlevel->num_precincts_x * rlevel->num_precincts_y;
+                /* Loop on precincts */
+                for (precno = 0; precno < nb_precincts; precno++) {
+                    Jpeg2000Prec *prec = band->prec + precno;
+
+                    /* Loop on codeblocks */
+                    for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
+                        int x, y;
+                        Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+                        decode_cblk(s, codsty, &t1, cblk,
+                                    cblk->coord[0][1] - cblk->coord[0][0],
+                                    cblk->coord[1][1] - cblk->coord[1][0],
+                                    bandpos);
+
+                        x = cblk->coord[0][0];
+                        y = cblk->coord[1][0];
+
+                        if (codsty->transform == FF_DWT97)
+                            dequantization_float(x, y, cblk, comp, &t1, band);
+                        else
+                            dequantization_int(x, y, cblk, comp, &t1, band);
+                   } /* end cblk */
+                } /*end prec */
+            } /* end band */
+        } /* end reslevel */
+
+        /* inverse DWT */
+        ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data);
+    } /*end comp */
+
+    /* inverse MCT transformation */
+    if (tile->codsty[0].mct)
+        mct_decode(s, tile);
+
+    if (s->precision <= 8) {
+        for (compno = 0; compno < s->ncomponents; compno++) {
+            Jpeg2000Component *comp = tile->comp + compno;
+            Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+            float *datap = comp->f_data;
+            int32_t *i_datap = comp->i_data;
+            int cbps = s->cbps[compno];
+            int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
+
+            y    = tile->comp[compno].coord[1][0] - s->image_offset_y;
+            line = picture->data[0] + y * 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;
+
+                if (codsty->transform == FF_DWT97) {
+                    for (; x < w; x += s->cdx[compno]) {
+                        int val = lrintf(*datap) + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        *dst = val << (8 - cbps);
+                        datap++;
+                        dst += s->ncomponents;
+                    }
+                } else {
+                    for (; x < w; x += s->cdx[compno]) {
+                        int val = *i_datap + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        *dst = val << (8 - cbps);
+                        i_datap++;
+                        dst += s->ncomponents;
+                    }
+                }
+                line += picture->linesize[0];
+            }
+        }
+    } else {
+        for (compno = 0; compno < s->ncomponents; compno++) {
+            Jpeg2000Component *comp = tile->comp + compno;
+            Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+            float *datap = comp->f_data;
+            int32_t *i_datap = comp->i_data;
+            uint16_t *linel;
+            int cbps = s->cbps[compno];
+            int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
+
+            y     = tile->comp[compno].coord[1][0] - s->image_offset_y;
+            linel = (uint16_t *)picture->data[0] + y * (picture->linesize[0] >> 1);
+            for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
+                uint16_t *dst;
+                x   = tile->comp[compno].coord[0][0] - s->image_offset_x;
+                dst = linel + (x * s->ncomponents + compno);
+                if (codsty->transform == FF_DWT97) {
+                    for (; x < w; x += s-> cdx[compno]) {
+                        int  val = lrintf(*datap) + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        /* align 12 bit values in little-endian mode */
+                        *dst = val << (16 - cbps);
+                        datap++;
+                        dst += s->ncomponents;
+                    }
+                } else {
+                    for (; x < w; x += s-> cdx[compno]) {
+                        int val = *i_datap + (1 << (cbps - 1));
+                        /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+                        val = av_clip(val, 0, (1 << cbps) - 1);
+                        /* align 12 bit values in little-endian mode */
+                        *dst = val << (16 - cbps);
+                        i_datap++;
+                        dst += s->ncomponents;
+                    }
+                }
+                linel += picture->linesize[0] >> 1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s)
+{
+    int tileno, compno;
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
+        for (compno = 0; compno < s->ncomponents; compno++) {
+            Jpeg2000Component *comp     = s->tile[tileno].comp   + compno;
+            Jpeg2000CodingStyle *codsty = s->tile[tileno].codsty + compno;
+
+            ff_jpeg2000_cleanup(comp, codsty);
+        }
+        av_freep(&s->tile[tileno].comp);
+    }
+    av_freep(&s->tile);
+    s->numXtiles = s->numYtiles = 0;
+}
+
+static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
+{
+    Jpeg2000CodingStyle *codsty = s->codsty;
+    Jpeg2000QuantStyle *qntsty  = s->qntsty;
+    uint8_t *properties         = s->properties;
+
+    for (;;) {
+        int len, ret = 0;
+        uint16_t marker;
+        int oldpos;
+
+        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);
+        oldpos = bytestream2_tell(&s->g);
+
+        if (marker == JPEG2000_SOD) {
+            Jpeg2000Tile *tile;
+            Jpeg2000TilePart *tp;
+
+            if (s->curtileno < 0) {
+                av_log(s->avctx, AV_LOG_ERROR, "Missing SOT\n");
+                return AVERROR_INVALIDDATA;
+            }
+            if (!s->tile) {
+                av_log(s->avctx, AV_LOG_ERROR, "Missing SIZ\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            tile = s->tile + s->curtileno;
+            tp = tile->tile_part + tile->tp_idx;
+            bytestream2_init(&tp->tpg, s->g.buffer, tp->tp_end - s->g.buffer);
+            bytestream2_skip(&s->g, tp->tp_end - s->g.buffer);
+
+            continue;
+        }
+        if (marker == JPEG2000_EOC)
+            break;
+
+        len = bytestream2_get_be16u(&s->g);
+        if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2)
+            return AVERROR_INVALIDDATA;
+
+        switch (marker) {
+        case JPEG2000_SIZ:
+            ret = get_siz(s);
+            break;
+        case JPEG2000_COC:
+            ret = get_coc(s, codsty, properties);
+            break;
+        case JPEG2000_COD:
+            ret = get_cod(s, codsty, properties);
+            break;
+        case JPEG2000_QCC:
+            ret = get_qcc(s, len, qntsty, properties);
+            break;
+        case JPEG2000_QCD:
+            ret = get_qcd(s, len, qntsty, properties);
+            break;
+        case JPEG2000_SOT:
+            if (!(ret = get_sot(s, len))) {
+                codsty = s->tile[s->curtileno].codsty;
+                qntsty = s->tile[s->curtileno].qntsty;
+                properties = s->tile[s->curtileno].properties;
+            }
+            break;
+        case JPEG2000_COM:
+            // the comment is ignored
+            bytestream2_skip(&s->g, len - 2);
+            break;
+        case JPEG2000_TLM:
+            // Tile-part lengths
+            ret = get_tlm(s, len);
+            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;
+}
+
+/* Read bit stream packets --> T2 operation. */
+static int jpeg2000_read_bitstream_packets(Jpeg2000DecoderContext *s)
+{
+    int ret = 0;
+    int tileno;
+
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
+        Jpeg2000Tile *tile = s->tile + tileno;
+
+        if (ret = init_tile(s, tileno))
+            return ret;
+
+        s->g = tile->tile_part[0].tpg;
+        if (ret = jpeg2000_decode_packets(s, tile))
+            return ret;
+    }
+
+    return 0;
+}
+
+static int jp2_find_codestream(Jpeg2000DecoderContext *s)
+{
+    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 jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
+                                 int *got_frame, AVPacket *avpkt)
+{
+    Jpeg2000DecoderContext *s = avctx->priv_data;
+    ThreadFrame frame = { .f = data };
+    AVFrame *picture = data;
+    int tileno, ret;
+
+    s->avctx     = avctx;
+    bytestream2_init(&s->g, avpkt->data, avpkt->size);
+    s->curtileno = 0; // TODO: only one tile in DCI JP2K. to implement for more tiles
+
+    if (bytestream2_get_bytes_left(&s->g) < 2) {
+        ret = AVERROR_INVALIDDATA;
+        goto end;
+    }
+
+    // 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,
+                   "Could not find Jpeg2000 codestream atom.\n");
+            ret = AVERROR_INVALIDDATA;
+            goto end;
+        }
+    } else {
+        bytestream2_seek(&s->g, 0, SEEK_SET);
+    }
+
+    if (bytestream2_get_be16u(&s->g) != JPEG2000_SOC) {
+        av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n");
+        ret = AVERROR_INVALIDDATA;
+        goto end;
+    }
+    if (ret = jpeg2000_read_main_headers(s))
+        goto end;
+
+    /* get picture buffer */
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed.\n");
+        goto end;
+    }
+    picture->pict_type = AV_PICTURE_TYPE_I;
+    picture->key_frame = 1;
+
+    if (ret = jpeg2000_read_bitstream_packets(s))
+        goto end;
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++)
+        if (ret = jpeg2000_decode_tile(s, s->tile + tileno, picture))
+            goto end;
+
+    jpeg2000_dec_cleanup(s);
+
+    *got_frame = 1;
+
+    return bytestream2_tell(&s->g);
+
+end:
+    jpeg2000_dec_cleanup(s);
+    return ret;
+}
+
+static void jpeg2000_init_static_data(AVCodec *codec)
+{
+    ff_jpeg2000_init_tier1_luts();
+    ff_mqc_init_context_tables();
+}
+
+#define OFFSET(x) offsetof(Jpeg2000DecoderContext, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+    { "lowres",  "Lower the decoding resolution by a power of two",
+        OFFSET(reduction_factor), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, JPEG2000_MAX_RESLEVELS - 1, VD },
+    { NULL },
+};
+
+static const AVProfile profiles[] = {
+    { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0,  "JPEG 2000 codestream restriction 0"   },
+    { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1,  "JPEG 2000 codestream restriction 1"   },
+    { FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION, "JPEG 2000 no codestream restrictions" },
+    { FF_PROFILE_JPEG2000_DCINEMA_2K,             "JPEG 2000 digital cinema 2K"          },
+    { FF_PROFILE_JPEG2000_DCINEMA_4K,             "JPEG 2000 digital cinema 4K"          },
+    { FF_PROFILE_UNKNOWN },
+};
+
+static const AVClass class = {
+    .class_name = "jpeg2000",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_jpeg2000_decoder = {
+    .name             = "jpeg2000",
+    .long_name        = NULL_IF_CONFIG_SMALL("JPEG 2000"),
+    .type             = AVMEDIA_TYPE_VIDEO,
+    .id               = AV_CODEC_ID_JPEG2000,
+    .capabilities     = CODEC_CAP_FRAME_THREADS,
+    .priv_data_size   = sizeof(Jpeg2000DecoderContext),
+    .init_static_data = jpeg2000_init_static_data,
+    .decode           = jpeg2000_decode_frame,
+    .priv_class       = &class,
+    .profiles         = NULL_IF_CONFIG_SMALL(profiles)
+};
diff --git a/libavcodec/jpeg2000dwt.c b/libavcodec/jpeg2000dwt.c
new file mode 100644
index 0000000..6642a53
--- /dev/null
+++ b/libavcodec/jpeg2000dwt.c
@@ -0,0 +1,357 @@
+/*
+ * Discrete wavelet transform
+ * Copyright (c) 2007 Kamil Nowosad
+ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Discrete wavelet transform
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/mem.h"
+#include "jpeg2000dwt.h"
+#include "internal.h"
+
+/* Defines for 9/7 DWT lifting parameters.
+ * Parameters are in float. */
+#define F_LFTG_ALPHA  1.586134342059924f
+#define F_LFTG_BETA   0.052980118572961f
+#define F_LFTG_GAMMA  0.882911075530934f
+#define F_LFTG_DELTA  0.443506852043971f
+#define F_LFTG_K      1.230174104914001f
+#define F_LFTG_X      1.625732422f
+/* FIXME: Why use 1.625732422 instead of 1/F_LFTG_K?
+ * Incorrect value in JPEG2000 norm.
+ * see (ISO/IEC 15444:1 (version 2002) F.3.8.2 */
+
+/* Lifting parameters in integer format.
+ * Computed as param = (float param) * (1 << 16) */
+#define I_LFTG_ALPHA  103949
+#define I_LFTG_BETA     3472
+#define I_LFTG_GAMMA   57862
+#define I_LFTG_DELTA   29066
+#define I_LFTG_K       80621
+#define I_LFTG_X      106544
+
+
+static inline void extend53(int *p, int i0, int i1)
+{
+    p[i0 - 1] = p[i0 + 1];
+    p[i1]     = p[i1 - 2];
+    p[i0 - 2] = p[i0 + 2];
+    p[i1 + 1] = p[i1 - 3];
+}
+
+static inline void extend97_float(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 inline void extend97_int(int32_t *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 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;
+    int w     = s->linelen[s->ndeclevels - 1][0];
+    int32_t *line = s->i_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(float *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend97_float(p, i0, i1);
+
+    for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
+        p[2 * i]     -= F_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]);
+    /* step 4 */
+    for (i = i0 / 2 - 1; i < i1 / 2 + 1; i++)
+        p[2 * i + 1] -= F_LFTG_GAMMA * (p[2 * i]     + p[2 * i + 2]);
+    /*step 5*/
+    for (i = i0 / 2; i < i1 / 2 + 1; i++)
+        p[2 * i]     += F_LFTG_BETA  * (p[2 * i - 1] + p[2 * i + 1]);
+    /* step 6 */
+    for (i = i0 / 2; i < i1 / 2; i++)
+        p[2 * i + 1] += F_LFTG_ALPHA * (p[2 * i]     + p[2 * i + 2]);
+}
+
+static void dwt_decode97_float(DWTContext *s, float *t)
+{
+    int lev;
+    int w       = s->linelen[s->ndeclevels - 1][0];
+    float *line = s->f_linebuf;
+    float *data = t;
+    /* position at index O of line range [0-5,w+5] cf. extend function */
+    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] = data[w * lp + j] * F_LFTG_K;
+            for (i = 1 - mh; i < lh; i += 2, j++)
+                l[i] = data[w * lp + j] * F_LFTG_X;
+
+            sr_1d97_float(line, mh, mh + lh);
+
+            for (i = 0; i < lh; i++)
+                data[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] = data[w * j + lp] * F_LFTG_K;
+            for (i = 1 - mv; i < lv; i += 2, j++)
+                l[i] = data[w * j + lp] * F_LFTG_X;
+
+            sr_1d97_float(line, mv, mv + lv);
+
+            for (i = 0; i < lv; i++)
+                data[w * i + lp] = l[i];
+        }
+    }
+}
+
+static void sr_1d97_int(int32_t *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend97_int(p, i0, i1);
+
+    for (i = i0 / 2 - 1; i < i1 / 2 + 2; i++)
+        p[2 * i]     -= (I_LFTG_DELTA * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
+    /* step 4 */
+    for (i = i0 / 2 - 1; i < i1 / 2 + 1; i++)
+        p[2 * i + 1] -= (I_LFTG_GAMMA * (p[2 * i]     + p[2 * i + 2]) + (1 << 15)) >> 16;
+    /*step 5*/
+    for (i = i0 / 2; i < i1 / 2 + 1; i++)
+        p[2 * i]     += (I_LFTG_BETA  * (p[2 * i - 1] + p[2 * i + 1]) + (1 << 15)) >> 16;
+    /* step 6 */
+    for (i = i0 / 2; i < i1 / 2; i++)
+        p[2 * i + 1] += (I_LFTG_ALPHA * (p[2 * i]     + p[2 * i + 2]) + (1 << 15)) >> 16;
+}
+
+static void dwt_decode97_int(DWTContext *s, int32_t *t)
+{
+    int lev;
+    int w       = s->linelen[s->ndeclevels - 1][0];
+    int32_t *line = s->i_linebuf;
+    int32_t *data = t;
+    /* position at index O of line range [0-5,w+5] cf. extend function */
+    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;
+        int32_t *l;
+        // HOR_SD
+        l = line + mh;
+        for (lp = 0; lp < lv; lp++) {
+            int i, j = 0;
+            // rescale with interleaving
+            for (i = mh; i < lh; i += 2, j++)
+                l[i] = ((data[w * lp + j] * I_LFTG_K) + (1 << 15)) >> 16;
+            for (i = 1 - mh; i < lh; i += 2, j++)
+                l[i] = ((data[w * lp + j] * I_LFTG_X) + (1 << 15)) >> 16;
+
+            sr_1d97_int(line, mh, mh + lh);
+
+            for (i = 0; i < lh; i++)
+                data[w * lp + i] = l[i];
+        }
+
+        // VER_SD
+        l = line + mv;
+        for (lp = 0; lp < lh; lp++) {
+            int i, j = 0;
+            // rescale with interleaving
+            for (i = mv; i < lv; i += 2, j++)
+                l[i] = ((data[w * j + lp] * I_LFTG_K) + (1 << 15)) >> 16;
+            for (i = 1 - mv; i < lv; i += 2, j++)
+                l[i] = ((data[w * j + lp] * I_LFTG_X) + (1 << 15)) >> 16;
+
+            sr_1d97_int(line, mv, mv + lv);
+
+            for (i = 0; i < lv; i++)
+                data[w * i + lp] = l[i];
+        }
+    }
+}
+
+int ff_jpeg2000_dwt_init(DWTContext *s, uint16_t border[2][2],
+                         int decomp_levels, int type)
+{
+    int i, j, lev = decomp_levels, maxlen,
+        b[2][2];
+
+    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;
+        }
+    switch (type) {
+    case FF_DWT97:
+        s->f_linebuf = av_malloc((maxlen + 12) * sizeof(*s->f_linebuf));
+        if (!s->f_linebuf)
+            return AVERROR(ENOMEM);
+        break;
+     case FF_DWT97_INT:
+        s->i_linebuf = av_malloc((maxlen + 12) * sizeof(*s->i_linebuf));
+        if (!s->i_linebuf)
+            return AVERROR(ENOMEM);
+        break;
+    case FF_DWT53:
+        s->i_linebuf = av_malloc((maxlen +  6) * sizeof(*s->i_linebuf));
+        if (!s->i_linebuf)
+            return AVERROR(ENOMEM);
+        break;
+    default:
+        return -1;
+    }
+    return 0;
+}
+
+int ff_dwt_decode(DWTContext *s, void *t)
+{
+    switch (s->type) {
+    case FF_DWT97:
+        dwt_decode97_float(s, t);
+        break;
+    case FF_DWT97_INT:
+        dwt_decode97_int(s, t);
+        break;
+    case FF_DWT53:
+        dwt_decode53(s, t);
+        break;
+    default:
+        return -1;
+    }
+    return 0;
+}
+
+void ff_dwt_destroy(DWTContext *s)
+{
+    av_freep(&s->f_linebuf);
+    av_freep(&s->i_linebuf);
+}
diff --git a/libavcodec/jpeg2000dwt.h b/libavcodec/jpeg2000dwt.h
new file mode 100644
index 0000000..9aaa18b
--- /dev/null
+++ b/libavcodec/jpeg2000dwt.h
@@ -0,0 +1,64 @@
+/*
+ * Discrete wavelet transform
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * 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_JPEG2000DWT_H
+#define AVCODEC_JPEG2000DWT_H
+
+/**
+ * @file
+ * Discrete wavelet transform
+ */
+
+#include <stdint.h>
+
+#define FF_DWT_MAX_DECLVLS 32 ///< max number of decomposition levels
+
+enum DWTType {
+    FF_DWT97,
+    FF_DWT53,
+    FF_DWT97_INT
+};
+
+typedef struct DWTContext {
+    /// 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
+    int32_t *i_linebuf;                  ///< int buffer used by transform
+    float   *f_linebuf;                  ///< float buffer used by transform
+} 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_jpeg2000_dwt_init(DWTContext *s, uint16_t border[2][2],
+                         int decomp_levels, int type);
+
+int ff_dwt_decode(DWTContext *s, void *t);
+
+void ff_dwt_destroy(DWTContext *s);
+
+#endif /* AVCODEC_JPEG2000DWT_H */
diff --git a/libavcodec/jpegls.c b/libavcodec/jpegls.c
index 4740f11..52a4500 100644
--- a/libavcodec/jpegls.c
+++ b/libavcodec/jpegls.c
@@ -27,63 +27,76 @@
 
 #include "jpegls.h"
 
-void ff_jpegls_init_state(JLSState *state){
+void ff_jpegls_init_state(JLSState *state)
+{
     int i;
 
     state->twonear = state->near * 2 + 1;
-    state->range = ((state->maxval + state->twonear - 1) / state->twonear) + 1;
+    state->range   = (state->maxval + state->twonear - 1) / state->twonear + 1;
 
     // QBPP = ceil(log2(RANGE))
-    for(state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++);
+    for (state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++)
+        ;
 
-    if(state->bpp < 8)
-        state->limit = 16 + 2 * state->bpp - state->qbpp;
+    if (state->bpp < 8)
+        state->limit = 2 * state->bpp - state->qbpp + 16;
     else
-        state->limit = (4 * state->bpp) - state->qbpp;
+        state->limit = 4 * state->bpp - state->qbpp;
 
-    for(i = 0; i < 367; i++) {
-        state->A[i] = FFMAX((state->range + 32) >> 6, 2);
+    for (i = 0; i < 367; i++) {
+        state->A[i] = FFMAX(state->range + 32 >> 6, 2);
         state->N[i] = 1;
     }
-
 }
 
 /**
  * Custom value clipping function used in T1, T2, T3 calculation
  */
-static inline int iso_clip(int v, int vmin, int vmax){
-    if(v > vmax || v < vmin) return vmin;
-    else                     return v;
+static inline int iso_clip(int v, int vmin, int vmax)
+{
+    if (v > vmax || v < vmin)
+        return vmin;
+    else
+        return v;
 }
 
-void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all){
-    const int basic_t1= 3;
-    const int basic_t2= 7;
-    const int basic_t3= 21;
+void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all)
+{
+    const int basic_t1 = 3;
+    const int basic_t2 = 7;
+    const int basic_t3 = 21;
     int factor;
 
-    if(s->maxval==0 || reset_all) s->maxval= (1 << s->bpp) - 1;
+    if (s->maxval == 0 || reset_all)
+        s->maxval = (1 << s->bpp) - 1;
 
-    if(s->maxval >=128){
-        factor= (FFMIN(s->maxval, 4095) + 128)>>8;
+    if (s->maxval >= 128) {
+        factor = FFMIN(s->maxval, 4095) + 128 >> 8;
 
-        if(s->T1==0     || reset_all)
-            s->T1= iso_clip(factor*(basic_t1-2) + 2 + 3*s->near, s->near+1, s->maxval);
-        if(s->T2==0     || reset_all)
-            s->T2= iso_clip(factor*(basic_t2-3) + 3 + 5*s->near, s->T1, s->maxval);
-        if(s->T3==0     || reset_all)
-            s->T3= iso_clip(factor*(basic_t3-4) + 4 + 7*s->near, s->T2, s->maxval);
-    }else{
-        factor= 256 / (s->maxval + 1);
+        if (s->T1 == 0 || reset_all)
+            s->T1 = iso_clip(factor * (basic_t1 - 2) + 2 + 3 * s->near,
+                             s->near + 1, s->maxval);
+        if (s->T2 == 0 || reset_all)
+            s->T2 = iso_clip(factor * (basic_t2 - 3) + 3 + 5 * s->near,
+                             s->T1, s->maxval);
+        if (s->T3 == 0 || reset_all)
+            s->T3 = iso_clip(factor * (basic_t3 - 4) + 4 + 7 * s->near,
+                             s->T2, s->maxval);
+    } else {
+        factor = 256 / (s->maxval + 1);
 
-        if(s->T1==0     || reset_all)
-            s->T1= iso_clip(FFMAX(2, basic_t1/factor + 3*s->near), s->near+1, s->maxval);
-        if(s->T2==0     || reset_all)
-            s->T2= iso_clip(FFMAX(3, basic_t2/factor + 5*s->near), s->T1, s->maxval);
-        if(s->T3==0     || reset_all)
-            s->T3= iso_clip(FFMAX(4, basic_t3/factor + 7*s->near), s->T2, s->maxval);
+        if (s->T1 == 0 || reset_all)
+            s->T1 = iso_clip(FFMAX(2, basic_t1 / factor + 3 * s->near),
+                             s->near + 1, s->maxval);
+        if (s->T2 == 0 || reset_all)
+            s->T2 = iso_clip(FFMAX(3, basic_t2 / factor + 5 * s->near),
+                             s->T1, s->maxval);
+        if (s->T3 == 0 || reset_all)
+            s->T3 = iso_clip(FFMAX(4, basic_t3 / factor + 7 * s->near),
+                             s->T2, s->maxval);
     }
 
-    if(s->reset==0  || reset_all) s->reset= 64;
+    if (s->reset == 0 || reset_all)
+        s->reset = 64;
     av_dlog(NULL, "[JPEG-LS RESET] T=%i,%i,%i\n", s->T1, s->T2, s->T3);
 }
diff --git a/libavcodec/jpegls.h b/libavcodec/jpegls.h
index 18c71a8..eae3943 100644
--- a/libavcodec/jpegls.h
+++ b/libavcodec/jpegls.h
@@ -28,21 +28,20 @@
 #ifndef AVCODEC_JPEGLS_H
 #define AVCODEC_JPEGLS_H
 
-#include "avcodec.h"
 #include "libavutil/common.h"
+#include "avcodec.h"
 
-typedef struct JpeglsContext{
+typedef struct JpeglsContext {
     AVCodecContext *avctx;
-    AVFrame picture;
-}JpeglsContext;
+} JpeglsContext;
 
-typedef struct JLSState{
+typedef struct JLSState {
     int T1, T2, T3;
     int A[367], B[367], C[365], N[367];
     int limit, reset, bpp, qbpp, maxval, range;
     int near, twonear;
     int run_index[3];
-}JLSState;
+} JLSState;
 
 extern const uint8_t ff_log2_run[32];
 
@@ -54,19 +53,29 @@ void ff_jpegls_init_state(JLSState *state);
 /**
  * Calculate quantized gradient value, used for context determination
  */
-static inline int ff_jpegls_quantize(JLSState *s, int v){ //FIXME optimize
-    if(v==0) return 0;
-    if(v < 0){
-        if(v <= -s->T3) return -4;
-        if(v <= -s->T2) return -3;
-        if(v <= -s->T1) return -2;
-        if(v <  -s->near) return -1;
+static inline int ff_jpegls_quantize(JLSState *s, int v)
+{
+    if (v == 0)
         return 0;
-    }else{
-        if(v <= s->near) return 0;
-        if(v <  s->T1) return 1;
-        if(v <  s->T2) return 2;
-        if(v <  s->T3) return 3;
+    if (v < 0) {
+        if (v <= -s->T3)
+            return -4;
+        if (v <= -s->T2)
+            return -3;
+        if (v <= -s->T1)
+            return -2;
+        if (v < -s->near)
+            return -1;
+        return 0;
+    } else {
+        if (v <= s->near)
+            return 0;
+        if (v < s->T1)
+            return 1;
+        if (v < s->T2)
+            return 2;
+        if (v < s->T3)
+            return 3;
         return 4;
     }
 }
@@ -76,37 +85,39 @@ static inline int ff_jpegls_quantize(JLSState *s, int v){ //FIXME optimize
  */
 void ff_jpegls_reset_coding_parameters(JLSState *s, int reset_all);
 
-
-static inline void ff_jpegls_downscale_state(JLSState *state, int Q){
-    if(state->N[Q] == state->reset){
-        state->A[Q] >>=1;
-        state->B[Q] >>=1;
-        state->N[Q] >>=1;
+static inline void ff_jpegls_downscale_state(JLSState *state, int Q)
+{
+    if (state->N[Q] == state->reset) {
+        state->A[Q] >>= 1;
+        state->B[Q] >>= 1;
+        state->N[Q] >>= 1;
     }
     state->N[Q]++;
 }
 
-static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err){
+static inline int ff_jpegls_update_state_regular(JLSState *state,
+                                                 int Q, int err)
+{
     state->A[Q] += FFABS(err);
-    err *= state->twonear;
+    err         *= state->twonear;
     state->B[Q] += err;
 
     ff_jpegls_downscale_state(state, Q);
 
-    if(state->B[Q] <= -state->N[Q]) {
-        state->B[Q]= FFMAX(state->B[Q] + state->N[Q], 1-state->N[Q]);
-        if(state->C[Q] > -128)
+    if (state->B[Q] <= -state->N[Q]) {
+        state->B[Q] = FFMAX(state->B[Q] + state->N[Q], 1 - state->N[Q]);
+        if (state->C[Q] > -128)
             state->C[Q]--;
-    }else if(state->B[Q] > 0){
-        state->B[Q]= FFMIN(state->B[Q] - state->N[Q], 0);
-        if(state->C[Q] < 127)
+    } else if (state->B[Q] > 0) {
+        state->B[Q] = FFMIN(state->B[Q] - state->N[Q], 0);
+        if (state->C[Q] < 127)
             state->C[Q]++;
     }
 
     return err;
 }
 
-#define R(a, i   ) (bits == 8 ?  ((uint8_t*)(a))[i]    :  ((uint16_t*)(a))[i]  )
-#define W(a, i, v) (bits == 8 ? (((uint8_t*)(a))[i]=v) : (((uint16_t*)(a))[i]=v))
+#define R(a, i)    (bits == 8 ?  ((uint8_t *)(a))[i]      :  ((uint16_t *)(a))[i])
+#define W(a, i, v) (bits == 8 ? (((uint8_t *)(a))[i] = v) : (((uint16_t *)(a))[i] = v))
 
 #endif /* AVCODEC_JPEGLS_H */
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index f851ec0..df72ca3 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -34,18 +34,16 @@
 #include "jpegls.h"
 #include "jpeglsdec.h"
 
-
 /*
-* Uncomment this to significantly speed up decoding of broken JPEG-LS
-* (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit.
-*
-* There is no Golomb code with length >= 32 bits possible, so check and
-* avoid situation of 32 zeros, Libav Golomb decoder is painfully slow
-* on this errors.
-*/
+ * Uncomment this to significantly speed up decoding of broken JPEG-LS
+ * (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit.
+ *
+ * There is no Golomb code with length >= 32 bits possible, so check and
+ * avoid situation of 32 zeros, Libav Golomb decoder is painfully slow
+ * on this errors.
+ */
 //#define JLS_BROKEN
 
-
 /**
  * Decode LSE block with initialization parameters
  */
@@ -56,13 +54,13 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
     skip_bits(&s->gb, 16);  /* length: FIXME: verify field validity */
     id = get_bits(&s->gb, 8);
 
-    switch(id){
+    switch (id) {
     case 1:
-        s->maxval= get_bits(&s->gb, 16);
-        s->t1= get_bits(&s->gb, 16);
-        s->t2= get_bits(&s->gb, 16);
-        s->t3= get_bits(&s->gb, 16);
-        s->reset= get_bits(&s->gb, 16);
+        s->maxval = get_bits(&s->gb, 16);
+        s->t1     = get_bits(&s->gb, 16);
+        s->t2     = get_bits(&s->gb, 16);
+        s->t3     = get_bits(&s->gb, 16);
+        s->reset  = get_bits(&s->gb, 16);
 
 //        ff_jpegls_reset_coding_parameters(s, 0);
         //FIXME quant table?
@@ -86,27 +84,30 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s)
 /**
  * Get context-dependent Golomb code, decode it and update context
  */
-static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q){
+static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q)
+{
     int k, ret;
 
-    for(k = 0; (state->N[Q] << k) < state->A[Q]; k++);
+    for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
+        ;
 
 #ifdef JLS_BROKEN
-    if(!show_bits_long(gb, 32))return -1;
+    if (!show_bits_long(gb, 32))
+        return -1;
 #endif
     ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp);
 
     /* decode mapped error */
-    if(ret & 1)
-        ret = -((ret + 1) >> 1);
+    if (ret & 1)
+        ret = -(ret + 1 >> 1);
     else
         ret >>= 1;
 
     /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */
-    if(!state->near && !k && (2 * state->B[Q] <= -state->N[Q]))
+    if (!state->near && !k && (2 * state->B[Q] <= -state->N[Q]))
         ret = -(ret + 1);
 
-    ret= ff_jpegls_update_state_regular(state, Q, ret);
+    ret = ff_jpegls_update_state_regular(state, Q, ret);
 
     return ret;
 }
@@ -114,29 +115,34 @@ static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q)
 /**
  * Get Golomb code, decode it and update state for run termination
  */
-static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RItype, int limit_add){
+static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state,
+                                      int RItype, int limit_add)
+{
     int k, ret, temp, map;
     int Q = 365 + RItype;
 
-    temp=  state->A[Q];
-    if(RItype)
+    temp = state->A[Q];
+    if (RItype)
         temp += state->N[Q] >> 1;
 
-    for(k = 0; (state->N[Q] << k) < temp; k++);
+    for (k = 0; (state->N[Q] << k) < temp; k++)
+        ;
 
 #ifdef JLS_BROKEN
-    if(!show_bits_long(gb, 32))return -1;
+    if (!show_bits_long(gb, 32))
+        return -1;
 #endif
-    ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp);
+    ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1,
+                               state->qbpp);
 
     /* decode mapped error */
     map = 0;
-    if(!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q]))
+    if (!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q]))
         map = 1;
     ret += RItype + map;
 
-    if(ret & 1){
-        ret = map - ((ret + 1) >> 1);
+    if (ret & 1) {
+        ret = map - (ret + 1 >> 1);
         state->B[Q]++;
     } else {
         ret = ret >> 1;
@@ -144,7 +150,7 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RI
 
     /* update state */
     state->A[Q] += FFABS(ret) - RItype;
-    ret *= state->twonear;
+    ret         *= state->twonear;
     ff_jpegls_downscale_state(state, Q);
 
     return ret;
@@ -153,12 +159,15 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RI
 /**
  * Decode one line of image
  */
-static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *last, void *dst, int last2, int w, int stride, int comp, int bits){
+static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s,
+                                  void *last, void *dst, int last2, int w,
+                                  int stride, int comp, int bits)
+{
     int i, x = 0;
     int Ra, Rb, Rc, Rd;
     int D0, D1, D2;
 
-    while(x < w) {
+    while (x < w) {
         int err, pred;
 
         /* compute gradients */
@@ -170,49 +179,51 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *
         D1 = Rb - Rc;
         D2 = Rc - Ra;
         /* run mode */
-        if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) {
+        if ((FFABS(D0) <= state->near) &&
+            (FFABS(D1) <= state->near) &&
+            (FFABS(D2) <= state->near)) {
             int r;
             int RItype;
 
             /* decode full runs while available */
-            while(get_bits1(&s->gb)) {
+            while (get_bits1(&s->gb)) {
                 int r;
                 r = 1 << ff_log2_run[state->run_index[comp]];
-                if(x + r * stride > w) {
+                if (x + r * stride > w)
                     r = (w - x) / stride;
-                }
-                for(i = 0; i < r; i++) {
+                for (i = 0; i < r; i++) {
                     W(dst, x, Ra);
                     x += stride;
                 }
                 /* if EOL reached, we stop decoding */
-                if(r != (1 << ff_log2_run[state->run_index[comp]]))
+                if (r != 1 << ff_log2_run[state->run_index[comp]])
                     return;
-                if(state->run_index[comp] < 31)
+                if (state->run_index[comp] < 31)
                     state->run_index[comp]++;
-                if(x + stride > w)
+                if (x + stride > w)
                     return;
             }
             /* decode aborted run */
             r = ff_log2_run[state->run_index[comp]];
-            if(r)
+            if (r)
                 r = get_bits_long(&s->gb, r);
-            for(i = 0; i < r; i++) {
+            for (i = 0; i < r; i++) {
                 W(dst, x, Ra);
                 x += stride;
             }
 
             /* decode run termination value */
-            Rb = R(last, x);
+            Rb     = R(last, x);
             RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0;
-            err = ls_get_code_runterm(&s->gb, state, RItype, ff_log2_run[state->run_index[comp]]);
-            if(state->run_index[comp])
+            err    = ls_get_code_runterm(&s->gb, state, RItype,
+                                         ff_log2_run[state->run_index[comp]]);
+            if (state->run_index[comp])
                 state->run_index[comp]--;
 
-            if(state->near && RItype){
+            if (state->near && RItype) {
                 pred = Ra + err;
             } else {
-                if(Rb < Ra)
+                if (Rb < Ra)
                     pred = Rb - err;
                 else
                     pred = Rb + err;
@@ -220,31 +231,33 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *
         } else { /* regular mode */
             int context, sign;
 
-            context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2);
-            pred = mid_pred(Ra, Ra + Rb - Rc, Rb);
+            context = ff_jpegls_quantize(state, D0) * 81 +
+                      ff_jpegls_quantize(state, D1) *  9 +
+                      ff_jpegls_quantize(state, D2);
+            pred    = mid_pred(Ra, Ra + Rb - Rc, Rb);
 
-            if(context < 0){
+            if (context < 0) {
                 context = -context;
-                sign = 1;
-            }else{
+                sign    = 1;
+            } else {
                 sign = 0;
             }
 
-            if(sign){
+            if (sign) {
                 pred = av_clip(pred - state->C[context], 0, state->maxval);
-                err = -ls_get_code_regular(&s->gb, state, context);
+                err  = -ls_get_code_regular(&s->gb, state, context);
             } else {
                 pred = av_clip(pred + state->C[context], 0, state->maxval);
-                err = ls_get_code_regular(&s->gb, state, context);
+                err  = ls_get_code_regular(&s->gb, state, context);
             }
 
             /* we have to do something more for near-lossless coding */
             pred += err;
         }
-        if(state->near){
-            if(pred < -state->near)
+        if (state->near) {
+            if (pred < -state->near)
                 pred += state->range * state->twonear;
-            else if(pred > state->maxval + state->near)
+            else if (pred > state->maxval + state->near)
                 pred -= state->range * state->twonear;
             pred = av_clip(pred, 0, state->maxval);
         }
@@ -255,7 +268,9 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void *
     }
 }
 
-int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){
+int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
+                             int point_transform, int ilv)
+{
     int i, t = 0;
     uint8_t *zero, *last, *cur;
     JLSState *state;
@@ -263,47 +278,49 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor
 
     zero = av_mallocz(s->picture_ptr->linesize[0]);
     last = zero;
-    cur = s->picture_ptr->data[0];
+    cur  = s->picture_ptr->data[0];
 
     state = av_mallocz(sizeof(JLSState));
     /* initialize JPEG-LS state from JPEG parameters */
-    state->near = near;
-    state->bpp = (s->bits < 2) ? 2 : s->bits;
+    state->near   = near;
+    state->bpp    = (s->bits < 2) ? 2 : s->bits;
     state->maxval = s->maxval;
-    state->T1 = s->t1;
-    state->T2 = s->t2;
-    state->T3 = s->t3;
-    state->reset = s->reset;
+    state->T1     = s->t1;
+    state->T2     = s->t2;
+    state->T3     = s->t3;
+    state->reset  = s->reset;
     ff_jpegls_reset_coding_parameters(state, 0);
     ff_jpegls_init_state(state);
 
-    if(s->bits <= 8)
+    if (s->bits <= 8)
         shift = point_transform + (8 - s->bits);
     else
         shift = point_transform + (16 - s->bits);
 
-    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",
+    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(ilv == 0) { /* separate planes */
+    if (ilv == 0) { /* separate planes */
         if (s->cur_scan > s->nb_components) {
             ret = AVERROR_INVALIDDATA;
             goto end;
         }
-        off = s->cur_scan - 1;
+        off    = s->cur_scan - 1;
         stride = (s->nb_components > 1) ? 3 : 1;
-        width = s->width * stride;
-        cur += off;
-        for(i = 0; i < s->height; i++) {
-            if(s->bits <= 8){
-                ls_decode_line(state, s, last, cur, t, width, stride, off,  8);
+        width  = s->width * stride;
+        cur   += off;
+        for (i = 0; i < s->height; i++) {
+            if (s->bits <= 8) {
+                ls_decode_line(state, s, last, cur, t, width, stride, off, 8);
                 t = last[0];
-            }else{
+            } else {
                 ls_decode_line(state, s, last, cur, t, width, stride, off, 16);
-                t = *((uint16_t*)last);
+                t = *((uint16_t *)last);
             }
             last = cur;
             cur += s->picture_ptr->linesize[0];
@@ -313,14 +330,15 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor
                 skip_bits(&s->gb, 16); /* skip RSTn */
             }
         }
-    } else if(ilv == 1) { /* line interleaving */
+    } else if (ilv == 1) { /* line interleaving */
         int j;
-        int Rc[3] = {0, 0, 0};
+        int Rc[3] = { 0, 0, 0 };
         memset(cur, 0, s->picture_ptr->linesize[0]);
         width = s->width * 3;
-        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 (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);
                 Rc[j] = last[j];
 
                 if (s->restart_interval && !--s->restart_count) {
@@ -332,33 +350,31 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor
             cur += s->picture_ptr->linesize[0];
         }
     } else if (ilv == 2) { /* sample interleaving */
-        av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n");
+        avpriv_report_missing_feature(s->avctx, "Sample interleaved images");
         ret = AVERROR_PATCHWELCOME;
         goto end;
     }
 
-    if(shift){ /* we need to do point transform or normalize samples */
+    if (shift) { /* we need to do point transform or normalize samples */
         int x, w;
 
         w = s->width * s->nb_components;
 
-        if(s->bits <= 8){
+        if (s->bits <= 8) {
             uint8_t *src = s->picture_ptr->data[0];
 
-            for(i = 0; i < s->height; i++){
-                for(x = off; x < w; x+= stride){
+            for (i = 0; i < s->height; i++) {
+                for (x = off; x < w; x += stride)
                     src[x] <<= shift;
-                }
                 src += s->picture_ptr->linesize[0];
             }
-        }else{
-            uint16_t *src = (uint16_t*) s->picture_ptr->data[0];
+        } else {
+            uint16_t *src = (uint16_t *)s->picture_ptr->data[0];
 
-            for(i = 0; i < s->height; i++){
-                for(x = 0; x < w; x++){
+            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_ptr->linesize[0] / 2;
             }
         }
     }
@@ -370,9 +386,9 @@ end:
     return ret;
 }
 
-
 AVCodec ff_jpegls_decoder = {
     .name           = "jpegls",
+    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_JPEGLS,
     .priv_data_size = sizeof(MJpegDecodeContext),
@@ -380,5 +396,4 @@ AVCodec ff_jpegls_decoder = {
     .close          = ff_mjpeg_decode_end,
     .decode         = ff_mjpeg_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
 };
diff --git a/libavcodec/jpeglsdec.h b/libavcodec/jpeglsdec.h
index 4732822..d60a87b 100644
--- a/libavcodec/jpeglsdec.h
+++ b/libavcodec/jpeglsdec.h
@@ -36,6 +36,7 @@
  */
 int ff_jpegls_decode_lse(MJpegDecodeContext *s);
 
-int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv);
+int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
+                             int point_transform, int ilv);
 
 #endif /* AVCODEC_JPEGLSDEC_H */
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index fea2a5b..3af6412 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -30,28 +30,29 @@
 #include "golomb.h"
 #include "internal.h"
 #include "mathops.h"
-#include "dsputil.h"
 #include "mjpeg.h"
 #include "jpegls.h"
 
-
 /**
  * Encode error from regular symbol
  */
-static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, int err){
+static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q,
+                                     int err)
+{
     int k;
     int val;
     int map;
 
-    for(k = 0; (state->N[Q] << k) < state->A[Q]; k++);
+    for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
+        ;
 
     map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]);
 
-    if(err < 0)
+    if (err < 0)
         err += state->range;
-    if(err >= ((state->range + 1) >> 1)) {
+    if (err >= (state->range + 1 >> 1)) {
         err -= state->range;
-        val = 2 * FFABS(err) - 1 - map;
+        val  = 2 * FFABS(err) - 1 - map;
     } else
         val = 2 * err + map;
 
@@ -63,27 +64,30 @@ static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q,
 /**
  * Encode error from run termination
  */
-static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RItype, int err, int limit_add){
+static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb,
+                                     int RItype, int err, int limit_add)
+{
     int k;
     int val, map;
     int Q = 365 + RItype;
     int temp;
 
     temp = state->A[Q];
-    if(RItype)
+    if (RItype)
         temp += state->N[Q] >> 1;
-    for(k = 0; (state->N[Q] << k) < temp; k++);
+    for (k = 0; (state->N[Q] << k) < temp; k++)
+        ;
     map = 0;
-    if(!k && err && (2 * state->B[Q] < state->N[Q]))
+    if (!k && err && (2 * state->B[Q] < state->N[Q]))
         map = 1;
 
-    if(err < 0)
-        val = - (2 * err) - 1 - RItype + map;
+    if (err < 0)
+        val = -(2 * err) - 1 - RItype + map;
     else
         val = 2 * err - RItype - map;
     set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp);
 
-    if(err < 0)
+    if (err < 0)
         state->B[Q]++;
     state->A[Q] += (val + 1 - RItype) >> 1;
 
@@ -93,19 +97,21 @@ static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RIt
 /**
  * Encode run value as specified by JPEG-LS standard
  */
-static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, int comp, int trail){
-    while(run >= (1 << ff_log2_run[state->run_index[comp]])){
+static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run,
+                                 int comp, int trail)
+{
+    while (run >= (1 << ff_log2_run[state->run_index[comp]])) {
         put_bits(pb, 1, 1);
         run -= 1 << ff_log2_run[state->run_index[comp]];
-        if(state->run_index[comp] < 31)
+        if (state->run_index[comp] < 31)
             state->run_index[comp]++;
     }
     /* if hit EOL, encode another full run, else encode aborted run */
-    if(!trail && run) {
+    if (!trail && run) {
         put_bits(pb, 1, 1);
-    }else if(trail){
+    } else if (trail) {
         put_bits(pb, 1, 0);
-        if(ff_log2_run[state->run_index[comp]])
+        if (ff_log2_run[state->run_index[comp]])
             put_bits(pb, ff_log2_run[state->run_index[comp]], run);
     }
 }
@@ -113,12 +119,15 @@ static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, in
 /**
  * Encode one line of image
  */
-static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last, void *cur, int last2, int w, int stride, int comp, int bits){
+static inline void ls_encode_line(JLSState *state, PutBitContext *pb,
+                                  void *last, void *cur, int last2, int w,
+                                  int stride, int comp, int bits)
+{
     int x = 0;
     int Ra, Rb, Rc, Rd;
     int D0, D1, D2;
 
-    while(x < w) {
+    while (x < w) {
         int err, pred, sign;
 
         /* compute gradients */
@@ -131,71 +140,76 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last
         D2 = Rc - Ra;
 
         /* run mode */
-        if((FFABS(D0) <= state->near) && (FFABS(D1) <= state->near) && (FFABS(D2) <= state->near)) {
+        if ((FFABS(D0) <= state->near) &&
+            (FFABS(D1) <= state->near) &&
+            (FFABS(D2) <= state->near)) {
             int RUNval, RItype, run;
 
-            run = 0;
+            run    = 0;
             RUNval = Ra;
-            while(x < w && (FFABS(R(cur, x) - RUNval) <= state->near)){
+            while (x < w && (FFABS(R(cur, x) - RUNval) <= state->near)) {
                 run++;
                 W(cur, x, Ra);
                 x += stride;
             }
             ls_encode_run(state, pb, run, comp, x < w);
-            if(x >= w)
+            if (x >= w)
                 return;
-            Rb = R(last, x);
-            RItype = (FFABS(Ra - Rb) <= state->near);
-            pred = RItype ? Ra : Rb;
-            err = R(cur, x) - pred;
+            Rb     = R(last, x);
+            RItype = FFABS(Ra - Rb) <= state->near;
+            pred   = RItype ? Ra : Rb;
+            err    = R(cur, x) - pred;
 
-            if(!RItype && Ra > Rb)
+            if (!RItype && Ra > Rb)
                 err = -err;
 
-            if(state->near){
-                if(err > 0)
-                    err = (state->near + err) / state->twonear;
+            if (state->near) {
+                if (err > 0)
+                    err =  (state->near + err) / state->twonear;
                 else
                     err = -(state->near - err) / state->twonear;
 
-                if(RItype || (Rb >= Ra))
+                if (RItype || (Rb >= Ra))
                     Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
                 else
                     Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
                 W(cur, x, Ra);
             }
-            if(err < 0)
+            if (err < 0)
                 err += state->range;
-            if(err >= ((state->range + 1) >> 1))
+            if (err >= state->range + 1 >> 1)
                 err -= state->range;
 
-            ls_encode_runterm(state, pb, RItype, err, ff_log2_run[state->run_index[comp]]);
+            ls_encode_runterm(state, pb, RItype, err,
+                              ff_log2_run[state->run_index[comp]]);
 
-            if(state->run_index[comp] > 0)
+            if (state->run_index[comp] > 0)
                 state->run_index[comp]--;
         } else { /* regular mode */
             int context;
 
-            context = ff_jpegls_quantize(state, D0) * 81 + ff_jpegls_quantize(state, D1) * 9 + ff_jpegls_quantize(state, D2);
-            pred = mid_pred(Ra, Ra + Rb - Rc, Rb);
+            context = ff_jpegls_quantize(state, D0) * 81 +
+                      ff_jpegls_quantize(state, D1) *  9 +
+                      ff_jpegls_quantize(state, D2);
+            pred    = mid_pred(Ra, Ra + Rb - Rc, Rb);
 
-            if(context < 0){
+            if (context < 0) {
                 context = -context;
-                sign = 1;
-                pred = av_clip(pred - state->C[context], 0, state->maxval);
-                err = pred - R(cur, x);
-            }else{
+                sign    = 1;
+                pred    = av_clip(pred - state->C[context], 0, state->maxval);
+                err     = pred - R(cur, x);
+            } else {
                 sign = 0;
                 pred = av_clip(pred + state->C[context], 0, state->maxval);
-                err = R(cur, x) - pred;
+                err  = R(cur, x) - pred;
             }
 
-            if(state->near){
-                if(err > 0)
-                    err = (state->near + err) / state->twonear;
+            if (state->near) {
+                if (err > 0)
+                    err =  (state->near + err) / state->twonear;
                 else
                     err = -(state->near - err) / state->twonear;
-                if(!sign)
+                if (!sign)
                     Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
                 else
                     Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
@@ -208,18 +222,22 @@ static inline void ls_encode_line(JLSState *state, PutBitContext *pb, void *last
     }
 }
 
-static void ls_store_lse(JLSState *state, PutBitContext *pb){
+static void ls_store_lse(JLSState *state, PutBitContext *pb)
+{
     /* Test if we have default params and don't need to store LSE */
     JLSState state2 = { 0 };
-    state2.bpp = state->bpp;
+    state2.bpp  = state->bpp;
     state2.near = state->near;
     ff_jpegls_reset_coding_parameters(&state2, 1);
-    if(state->T1 == state2.T1 && state->T2 == state2.T2 && state->T3 == state2.T3 && state->reset == state2.reset)
+    if (state->T1 == state2.T1 &&
+        state->T2 == state2.T2 &&
+        state->T3 == state2.T3 &&
+        state->reset == state2.reset)
         return;
     /* store LSE type 1 */
     put_marker(pb, LSE);
     put_bits(pb, 16, 13);
-    put_bits(pb, 8,   1);
+    put_bits(pb, 8, 1);
     put_bits(pb, 16, state->maxval);
     put_bits(pb, 16, state->T1);
     put_bits(pb, 16, state->T2);
@@ -230,9 +248,8 @@ static void ls_store_lse(JLSState *state, PutBitContext *pb){
 static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
                              const AVFrame *pict, int *got_packet)
 {
-    JpeglsContext * const s = avctx->priv_data;
-    AVFrame * const p = &s->picture;
-    const int near = avctx->prediction_method;
+    const AVFrame *const p = pict;
+    const int near         = avctx->prediction_method;
     PutBitContext pb, pb2;
     GetBitContext gb;
     uint8_t *buf2, *zero, *cur, *last;
@@ -240,17 +257,14 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
     int i, size, ret;
     int comps;
 
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
-
-    if(avctx->pix_fmt == AV_PIX_FMT_GRAY8 || avctx->pix_fmt == AV_PIX_FMT_GRAY16)
+    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||
+        avctx->pix_fmt == AV_PIX_FMT_GRAY16)
         comps = 1;
     else
         comps = 3;
 
-    if ((ret = ff_alloc_packet(pkt, avctx->width*avctx->height*comps*4 +
-                                    FF_MIN_BUFFER_SIZE)) < 0) {
+    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");
         return ret;
     }
@@ -264,31 +278,31 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
     put_marker(&pb, SOI);
     put_marker(&pb, SOF48);
     put_bits(&pb, 16, 8 + comps * 3); // header size depends on components
-    put_bits(&pb,  8, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8); // bpp
+    put_bits(&pb, 8, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8);  // bpp
     put_bits(&pb, 16, avctx->height);
     put_bits(&pb, 16, avctx->width);
-    put_bits(&pb,  8, comps);         // components
-    for(i = 1; i <= comps; i++) {
-        put_bits(&pb,  8, i);    // component ID
-        put_bits(&pb,  8, 0x11); // subsampling: none
-        put_bits(&pb,  8, 0);    // Tiq, used by JPEG-LS ext
+    put_bits(&pb, 8, comps);          // components
+    for (i = 1; i <= comps; i++) {
+        put_bits(&pb, 8, i);     // component ID
+        put_bits(&pb, 8, 0x11);  // subsampling: none
+        put_bits(&pb, 8, 0);     // Tiq, used by JPEG-LS ext
     }
 
     put_marker(&pb, SOS);
     put_bits(&pb, 16, 6 + comps * 2);
-    put_bits(&pb,  8, comps);
-    for(i = 1; i <= comps; i++) {
-        put_bits(&pb,  8, i);  // component ID
-        put_bits(&pb,  8, 0);  // mapping index: none
+    put_bits(&pb, 8, comps);
+    for (i = 1; i <= comps; i++) {
+        put_bits(&pb, 8, i);   // component ID
+        put_bits(&pb, 8, 0);   // mapping index: none
     }
-    put_bits(&pb,  8, near);
-    put_bits(&pb,  8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line
-    put_bits(&pb,  8, 0); // point transform: none
+    put_bits(&pb, 8, near);
+    put_bits(&pb, 8, (comps > 1) ? 1 : 0);  // interleaving: 0 - plane, 1 - line
+    put_bits(&pb, 8, 0);  // point transform: none
 
     state = av_mallocz(sizeof(JLSState));
     /* initialize JPEG-LS state from JPEG parameters */
     state->near = near;
-    state->bpp = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8;
+    state->bpp  = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8;
     ff_jpegls_reset_coding_parameters(state, 0);
     ff_jpegls_init_state(state);
 
@@ -296,70 +310,72 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
 
     zero = av_mallocz(p->linesize[0]);
     last = zero;
-    cur = p->data[0];
-    if(avctx->pix_fmt == AV_PIX_FMT_GRAY8){
+    cur  = p->data[0];
+    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
         int t = 0;
 
-        for(i = 0; i < avctx->height; i++) {
-            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0,  8);
-            t = last[0];
+        for (i = 0; i < avctx->height; i++) {
+            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 8);
+            t    = last[0];
             last = cur;
             cur += p->linesize[0];
         }
-    }else if(avctx->pix_fmt == AV_PIX_FMT_GRAY16){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY16) {
         int t = 0;
 
-        for(i = 0; i < avctx->height; i++) {
+        for (i = 0; i < avctx->height; i++) {
             ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16);
-            t = *((uint16_t*)last);
+            t    = *((uint16_t *)last);
             last = cur;
             cur += p->linesize[0];
         }
-    }else if(avctx->pix_fmt == AV_PIX_FMT_RGB24){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
         int j, width;
-        int Rc[3] = {0, 0, 0};
+        int Rc[3] = { 0, 0, 0 };
 
         width = avctx->width * 3;
-        for(i = 0; i < avctx->height; i++) {
-            for(j = 0; j < 3; j++) {
-                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8);
+        for (i = 0; i < avctx->height; i++) {
+            for (j = 0; j < 3; j++) {
+                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],
+                               width, 3, j, 8);
                 Rc[j] = last[j];
             }
             last = cur;
-            cur += s->picture.linesize[0];
+            cur += p->linesize[0];
         }
-    }else if(avctx->pix_fmt == AV_PIX_FMT_BGR24){
+    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
         int j, width;
-        int Rc[3] = {0, 0, 0};
+        int Rc[3] = { 0, 0, 0 };
 
         width = avctx->width * 3;
-        for(i = 0; i < avctx->height; i++) {
-            for(j = 2; j >= 0; j--) {
-                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j, 8);
+        for (i = 0; i < avctx->height; i++) {
+            for (j = 2; j >= 0; j--) {
+                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],
+                               width, 3, j, 8);
                 Rc[j] = last[j];
             }
             last = cur;
-            cur += s->picture.linesize[0];
+            cur += p->linesize[0];
         }
     }
 
     av_free(zero);
     av_free(state);
 
-    // the specification says that after doing 0xff escaping unused bits in the
-    // last byte must be set to 0, so just append 7 "optional" zero-bits to
-    // avoid special-casing.
+    /* the specification says that after doing 0xff escaping unused bits in
+     * the last byte must be set to 0, so just append 7 "optional" zero-bits
+     * to avoid special-casing. */
     put_bits(&pb2, 7, 0);
     size = put_bits_count(&pb2);
     flush_put_bits(&pb2);
     /* do escape coding */
     init_get_bits(&gb, buf2, size);
     size -= 7;
-    while(get_bits_count(&gb) < size){
+    while (get_bits_count(&gb) < size) {
         int v;
         v = get_bits(&gb, 8);
         put_bits(&pb, 8, v);
-        if(v == 0xFF){
+        if (v == 0xFF) {
             v = get_bits(&gb, 7);
             put_bits(&pb, 8, v);
         }
@@ -379,29 +395,43 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
-static av_cold int encode_init_ls(AVCodecContext *ctx) {
-    JpeglsContext *c = (JpeglsContext*)ctx->priv_data;
-
-    c->avctx = ctx;
-    ctx->coded_frame = &c->picture;
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
 
-    if(ctx->pix_fmt != AV_PIX_FMT_GRAY8 && ctx->pix_fmt != AV_PIX_FMT_GRAY16 && ctx->pix_fmt != AV_PIX_FMT_RGB24 && ctx->pix_fmt != AV_PIX_FMT_BGR24){
-        av_log(ctx, AV_LOG_ERROR, "Only grayscale and RGB24/BGR24 images are supported\n");
+static av_cold int encode_init_ls(AVCodecContext *ctx)
+{
+    ctx->coded_frame = av_frame_alloc();
+    if (!ctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    ctx->coded_frame->key_frame = 1;
+
+    if (ctx->pix_fmt != AV_PIX_FMT_GRAY8  &&
+        ctx->pix_fmt != AV_PIX_FMT_GRAY16 &&
+        ctx->pix_fmt != AV_PIX_FMT_RGB24  &&
+        ctx->pix_fmt != AV_PIX_FMT_BGR24) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Only grayscale and RGB24/BGR24 images are supported\n");
         return -1;
     }
     return 0;
 }
 
-AVCodec ff_jpegls_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them
+AVCodec ff_jpegls_encoder = {
     .name           = "jpegls",
+    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_JPEGLS,
-    .priv_data_size = sizeof(JpeglsContext),
     .init           = encode_init_ls,
+    .close          = encode_close,
     .encode2        = encode_picture_ls,
-    .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
+    .pix_fmts       = (const enum AVPixelFormat[]) {
+        AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24,
+        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
         AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
 };
diff --git a/libavcodec/jrevdct.c b/libavcodec/jrevdct.c
index e33558f..e6846a1 100644
--- a/libavcodec/jrevdct.c
+++ b/libavcodec/jrevdct.c
@@ -63,7 +63,7 @@
  */
 
 #include "libavutil/common.h"
-#include "dsputil.h"
+#include "dct.h"
 
 #define EIGHT_BIT_SAMPLES
 
@@ -74,7 +74,7 @@
 
 #define RIGHT_SHIFT(x, n) ((x) >> (n))
 
-typedef DCTELEM DCTBLOCK[DCTSIZE2];
+typedef int16_t DCTBLOCK[DCTSIZE2];
 
 #define CONST_BITS 13
 
@@ -213,7 +213,7 @@ void ff_j_rev_dct(DCTBLOCK data)
   int32_t tmp10, tmp11, tmp12, tmp13;
   int32_t z1, z2, z3, z4, z5;
   int32_t d0, d1, d2, d3, d4, d5, d6, d7;
-  register DCTELEM *dataptr;
+  register int16_t *dataptr;
   int rowctr;
 
   /* Pass 1: process rows. */
@@ -249,7 +249,7 @@ void ff_j_rev_dct(DCTBLOCK data)
       /* AC terms all zero */
       if (d0) {
           /* Compute a 32 bit value to assign. */
-          DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS);
+          int16_t dcval = (int16_t) (d0 << PASS1_BITS);
           register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000);
 
           idataptr[0] = v;
@@ -574,14 +574,14 @@ void ff_j_rev_dct(DCTBLOCK data)
 }
     /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
 
-    dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
-    dataptr[7] = (DCTELEM) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
-    dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
-    dataptr[6] = (DCTELEM) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
-    dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
-    dataptr[5] = (DCTELEM) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
-    dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
-    dataptr[4] = (DCTELEM) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
+    dataptr[0] = (int16_t) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
+    dataptr[7] = (int16_t) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
+    dataptr[1] = (int16_t) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
+    dataptr[6] = (int16_t) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
+    dataptr[2] = (int16_t) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
+    dataptr[5] = (int16_t) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
+    dataptr[3] = (int16_t) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
+    dataptr[4] = (int16_t) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
 
     dataptr += DCTSIZE;         /* advance pointer to next row */
   }
@@ -920,21 +920,21 @@ void ff_j_rev_dct(DCTBLOCK data)
 
     /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
 
-    dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp3,
+    dataptr[DCTSIZE*0] = (int16_t) DESCALE(tmp10 + tmp3,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp10 - tmp3,
+    dataptr[DCTSIZE*7] = (int16_t) DESCALE(tmp10 - tmp3,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp11 + tmp2,
+    dataptr[DCTSIZE*1] = (int16_t) DESCALE(tmp11 + tmp2,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(tmp11 - tmp2,
+    dataptr[DCTSIZE*6] = (int16_t) DESCALE(tmp11 - tmp2,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(tmp12 + tmp1,
+    dataptr[DCTSIZE*2] = (int16_t) DESCALE(tmp12 + tmp1,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp12 - tmp1,
+    dataptr[DCTSIZE*5] = (int16_t) DESCALE(tmp12 - tmp1,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp13 + tmp0,
+    dataptr[DCTSIZE*3] = (int16_t) DESCALE(tmp13 + tmp0,
                                            CONST_BITS+PASS1_BITS+3);
-    dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp13 - tmp0,
+    dataptr[DCTSIZE*4] = (int16_t) DESCALE(tmp13 - tmp0,
                                            CONST_BITS+PASS1_BITS+3);
 
     dataptr++;                  /* advance pointer to next column */
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index 8c919d2..5c86cb5 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -28,11 +28,12 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "libavutil/intreadwrite.h"
 
 typedef struct JvContext {
     DSPContext dsp;
-    AVFrame    frame;
+    AVFrame   *frame;
     uint32_t   palette[AVPALETTE_COUNT];
     int        palette_has_changed;
 } JvContext;
@@ -40,6 +41,11 @@ typedef struct JvContext {
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     JvContext *s = avctx->priv_data;
+
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
     ff_dsputil_init(&s->dsp, avctx);
     return 0;
@@ -136,16 +142,16 @@ static int decode_frame(AVCodecContext *avctx,
     int buf_size           = avpkt->size;
     const uint8_t *buf     = avpkt->data;
     const uint8_t *buf_end = buf + buf_size;
-    int video_size, video_type, i, j;
+    int video_size, video_type, i, j, ret;
 
     video_size = AV_RL32(buf);
     video_type = buf[4];
     buf += 5;
 
     if (video_size) {
-        if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+        if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
 
         if (video_type == 0 || video_type == 1) {
@@ -154,15 +160,15 @@ static int decode_frame(AVCodecContext *avctx,
 
             for (j = 0; j < avctx->height; j += 8)
                 for (i = 0; i < avctx->width; i += 8)
-                    decode8x8(&gb, s->frame.data[0] + j*s->frame.linesize[0] + i,
-                              s->frame.linesize[0], &s->dsp);
+                    decode8x8(&gb, s->frame->data[0] + j*s->frame->linesize[0] + i,
+                              s->frame->linesize[0], &s->dsp);
 
             buf += video_size;
         } else if (video_type == 2) {
             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);
+                    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);
@@ -179,14 +185,15 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     if (video_size) {
-        s->frame.key_frame           = 1;
-        s->frame.pict_type           = AV_PICTURE_TYPE_I;
-        s->frame.palette_has_changed = s->palette_has_changed;
+        s->frame->key_frame           = 1;
+        s->frame->pict_type           = AV_PICTURE_TYPE_I;
+        s->frame->palette_has_changed = s->palette_has_changed;
         s->palette_has_changed       = 0;
-        memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+        memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
 
+        if ((ret = av_frame_ref(data, s->frame)) < 0)
+            return ret;
         *got_frame = 1;
-        *(AVFrame*)data = s->frame;
     }
 
     return buf_size;
@@ -196,8 +203,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
 {
     JvContext *s = avctx->priv_data;
 
-    if(s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
diff --git a/libavcodec/kbdwin.c b/libavcodec/kbdwin.c
index 3b590b3..1b7313d 100644
--- a/libavcodec/kbdwin.c
+++ b/libavcodec/kbdwin.c
@@ -17,7 +17,7 @@
  */
 
 #include <assert.h>
-#include <libavutil/mathematics.h>
+#include "libavutil/mathematics.h"
 #include "libavutil/attributes.h"
 #include "kbdwin.h"
 
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index fc99b21..1436ccb 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -32,20 +32,20 @@
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame prev, cur;
+    AVFrame *prev;
 } KgvContext;
 
 static void decode_flush(AVCodecContext *avctx)
 {
     KgvContext * const c = avctx->priv_data;
 
-    if (c->prev.data[0])
-        avctx->release_buffer(avctx, &c->prev);
+    av_frame_free(&c->prev);
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = buf + avpkt->size;
     KgvContext * const c = avctx->priv_data;
@@ -55,29 +55,25 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int w, h, i, res;
 
     if (avpkt->size < 2)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     w = (buf[0] + 1) * 8;
     h = (buf[1] + 1) * 8;
     buf += 2;
 
-    if (av_image_check_size(w, h, 0, avctx))
-        return -1;
-
     if (w != avctx->width || h != avctx->height) {
-        if (c->prev.data[0])
-            avctx->release_buffer(avctx, &c->prev);
-        avcodec_set_dimensions(avctx, w, h);
+        av_frame_unref(c->prev);
+        if ((res = ff_set_dimensions(avctx, w, h)) < 0)
+            return res;
     }
 
     maxcnt = w * h;
 
-    c->cur.reference = 3;
-    if ((res = ff_get_buffer(avctx, &c->cur)) < 0)
+    if ((res = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
         return res;
-    out  = (uint16_t *) c->cur.data[0];
-    if (c->prev.data[0]) {
-        prev = (uint16_t *) c->prev.data[0];
+    out  = (uint16_t *) frame->data[0];
+    if (c->prev->data[0]) {
+        prev = (uint16_t *) c->prev->data[0];
     } else {
         prev = NULL;
     }
@@ -156,12 +152,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (outcnt - maxcnt)
         av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt);
 
-    *got_frame = 1;
-    *(AVFrame*)data = c->cur;
+    av_frame_unref(c->prev);
+    if ((res = av_frame_ref(c->prev, frame)) < 0)
+        return res;
 
-    if (c->prev.data[0])
-        avctx->release_buffer(avctx, &c->prev);
-    FFSWAP(AVFrame, c->cur, c->prev);
+    *got_frame = 1;
 
     return avpkt->size;
 }
@@ -170,6 +165,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
 {
     KgvContext * const c = avctx->priv_data;
 
+    c->prev = av_frame_alloc();
+    if (!c->prev)
+        return AVERROR(ENOMEM);
+
     c->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_RGB555;
     avctx->flags  |= CODEC_FLAG_EMU_EDGE;
@@ -185,6 +184,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
 AVCodec ff_kgv1_decoder = {
     .name           = "kgv1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Kega Game Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_KGV1,
     .priv_data_size = sizeof(KgvContext),
@@ -192,6 +192,5 @@ AVCodec ff_kgv1_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .flush          = decode_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("Kega Game Video"),
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index e3dcd07..5da8bb2 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -42,7 +42,6 @@
  */
 typedef struct KmvcContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int setpal;
     int palsize;
@@ -248,21 +247,18 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     KmvcContext *const ctx = avctx->priv_data;
+    AVFrame *frame = data;
     uint8_t *out, *src;
-    int i;
+    int i, ret;
     int header;
     int blocksize;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
     bytestream2_init(&ctx->g, avpkt->data, avpkt->size);
-    if (ctx->pic.data[0])
-        avctx->release_buffer(avctx, &ctx->pic);
 
-    ctx->pic.reference = 1;
-    ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if (ff_get_buffer(avctx, &ctx->pic) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     header = bytestream2_get_byte(&ctx->g);
@@ -278,15 +274,15 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
     }
 
     if (header & KMVC_KEYFRAME) {
-        ctx->pic.key_frame = 1;
-        ctx->pic.pict_type = AV_PICTURE_TYPE_I;
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
     } else {
-        ctx->pic.key_frame = 0;
-        ctx->pic.pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
     }
 
     if (header & KMVC_PALETTE) {
-        ctx->pic.palette_has_changed = 1;
+        frame->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);
@@ -294,23 +290,23 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
     }
 
     if (pal) {
-        ctx->pic.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
         memcpy(ctx->pal, pal, AVPALETTE_SIZE);
     }
 
     if (ctx->setpal) {
         ctx->setpal = 0;
-        ctx->pic.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
     }
 
     /* make the palette available on the way out */
-    memcpy(ctx->pic.data[1], ctx->pal, 1024);
+    memcpy(frame->data[1], ctx->pal, 1024);
 
     blocksize = bytestream2_get_byte(&ctx->g);
 
     if (blocksize != 8 && blocksize != 127) {
         av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     memset(ctx->cur, 0, 320 * 200);
     switch (header & KMVC_METHOD) {
@@ -326,15 +322,15 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    out = ctx->pic.data[0];
+    out = frame->data[0];
     src = ctx->cur;
     for (i = 0; i < avctx->height; i++) {
         memcpy(out, src, avctx->width);
         src += 320;
-        out += ctx->pic.linesize[0];
+        out += frame->linesize[0];
     }
 
     /* flip buffers */
@@ -347,7 +343,6 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
     }
 
     *got_frame = 1;
-    *(AVFrame *) data = ctx->pic;
 
     /* always report that the buffer was completely consumed */
     return avpkt->size;
@@ -367,7 +362,7 @@ static av_cold int decode_init(AVCodecContext * avctx)
 
     if (avctx->width > 320 || avctx->height > 200) {
         av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n");
-        return -1;
+        return AVERROR(EINVAL);
     }
 
     c->cur = c->frm0;
@@ -405,11 +400,11 @@ static av_cold int decode_init(AVCodecContext * avctx)
 
 AVCodec ff_kmvc_decoder = {
     .name           = "kmvc",
+    .long_name      = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_KMVC,
     .priv_data_size = sizeof(KmvcContext),
     .init           = decode_init,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
 };
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index 33dd8b0..ce2942a 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -48,7 +48,6 @@ enum LagarithFrameType {
 
 typedef struct LagarithContext {
     AVCodecContext *avctx;
-    AVFrame picture;
     DSPContext dsp;
     int zeros;                  /**< number of consecutive zero bytes encountered */
     int zeros_rem;              /**< number of zero bytes remaining to output */
@@ -502,19 +501,14 @@ static int lag_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LagarithContext *l = avctx->priv_data;
-    AVFrame *const p = &l->picture;
+    ThreadFrame frame = { .f = data };
+    AVFrame *const p  = data;
     uint8_t frametype = 0;
     uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
     uint32_t offs[4];
     uint8_t *srcs[4], *dst;
     int i, j, planes = 3;
 
-    AVFrame *picture = data;
-
-    if (p->data[0])
-        ff_thread_release_buffer(avctx, p);
-
-    p->reference = 0;
     p->key_frame = 1;
 
     frametype = buf[0];
@@ -526,7 +520,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_SOLID_RGBA:
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -548,7 +542,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
         if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
             avctx->pix_fmt = AV_PIX_FMT_RGB24;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -608,7 +602,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_ARITH_YUY2:
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -634,7 +628,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_ARITH_YV12:
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -663,7 +657,6 @@ static int lag_decode_frame(AVCodecContext *avctx,
         return -1;
     }
 
-    *picture = *p;
     *got_frame = 1;
 
     return buf_size;
@@ -683,8 +676,6 @@ static av_cold int lag_decode_end(AVCodecContext *avctx)
 {
     LagarithContext *l = avctx->priv_data;
 
-    if (l->picture.data[0])
-        ff_thread_release_buffer(avctx, &l->picture);
     av_freep(&l->rgb_planes);
 
     return 0;
@@ -692,6 +683,7 @@ static av_cold int lag_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_lagarith_decoder = {
     .name           = "lagarith",
+    .long_name      = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_LAGARITH,
     .priv_data_size = sizeof(LagarithContext),
@@ -699,5 +691,4 @@ AVCodec ff_lagarith_decoder = {
     .close          = lag_decode_end,
     .decode         = lag_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
-    .long_name      = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
 };
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index f78401d..4d97948 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -55,8 +55,6 @@
  * Decoder context
  */
 typedef struct LclDecContext {
-    AVFrame pic;
-
     // Image type
     int imgtype;
     // Compression type
@@ -132,7 +130,7 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i
     int zret = inflateReset(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
     c->zstream.next_in = src;
     c->zstream.avail_in = src_len;
@@ -141,12 +139,12 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i
     zret = inflate(&c->zstream, Z_FINISH);
     if (zret != Z_OK && zret != Z_STREAM_END) {
         av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
     if (expected != (unsigned int)c->zstream.total_out) {
         av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
                expected, c->zstream.total_out);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
     return c->zstream.total_out;
 }
@@ -160,6 +158,7 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i
  */
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LclDecContext * const c = avctx->priv_data;
@@ -172,21 +171,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     unsigned int height = avctx->height; // Real image height
     unsigned int mszh_dlen;
     unsigned char yq, y1q, uq, vq;
-    int uqvq;
+    int uqvq, ret;
     unsigned int mthread_inlen, mthread_outlen;
     unsigned int len = buf_size;
 
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 0;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if(ff_get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    outptr = c->pic.data[0]; // Output image pointer
+    outptr = frame->data[0]; // Output image pointer
 
     /* Decompress frame */
     switch (avctx->codec_id) {
@@ -202,14 +196,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 if (mthread_outlen != mszh_dlen) {
                     av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
                            mthread_outlen, mszh_dlen);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - 8 - mthread_inlen,
                                         c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
                 if (mthread_outlen != mszh_dlen) {
                     av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
                            mthread_outlen, mszh_dlen);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 encoded = c->decomp_buf;
                 len = c->decomp_size;
@@ -218,7 +212,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 if (c->decomp_size != mszh_dlen) {
                     av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
                            c->decomp_size, mszh_dlen);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 encoded = c->decomp_buf;
                 len = mszh_dlen;
@@ -249,7 +243,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         }
         default:
             av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
 #if CONFIG_ZLIB_DECODER
@@ -266,7 +260,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 break;
             }
         } else if (c->flags & FLAG_MULTITHREAD) {
-            int ret;
             mthread_inlen = AV_RL32(encoded);
             mthread_inlen = FFMIN(mthread_inlen, len - 8);
             mthread_outlen = AV_RL32(encoded+4);
@@ -286,7 +279,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
 #endif
     default:
         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
 
@@ -370,14 +363,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
     /* Convert colorspace */
-    y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0];
-    u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1];
-    v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2];
+    y_out = frame->data[0] + (height - 1) * frame->linesize[0];
+    u_out = frame->data[1] + (height - 1) * frame->linesize[1];
+    v_out = frame->data[2] + (height - 1) * frame->linesize[2];
     switch (c->imgtype) {
     case IMGTYPE_YUV111:
         for (row = 0; row < height; row++) {
@@ -386,9 +379,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 u_out[col] = *encoded++ + 128;
                 v_out[col] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0];
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0];
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     case IMGTYPE_YUV422:
@@ -401,14 +394,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 v_out[ col >> 1     ] = *encoded++ + 128;
                 v_out[(col >> 1) + 1] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0];
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0];
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     case IMGTYPE_RGB24:
         for (row = height - 1; row >= 0; row--) {
-            pixel_ptr = row * c->pic.linesize[0];
+            pixel_ptr = row * frame->linesize[0];
             memcpy(outptr + pixel_ptr, encoded, 3 * width);
             encoded += 3 * width;
         }
@@ -421,9 +414,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 u_out[col >> 2] = *encoded++ + 128;
                 v_out[col >> 2] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0];
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0];
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     case IMGTYPE_YUV211:
@@ -434,35 +427,34 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 u_out[col >> 1] = *encoded++ + 128;
                 v_out[col >> 1] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0];
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0];
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     case IMGTYPE_YUV420:
-        u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1];
-        v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2];
+        u_out = frame->data[1] + ((height >> 1) - 1) * frame->linesize[1];
+        v_out = frame->data[2] + ((height >> 1) - 1) * frame->linesize[2];
         for (row = 0; row < height - 1; row += 2) {
             for (col = 0; col < width - 1; col += 2) {
                 memcpy(y_out + col, encoded, 2);
                 encoded += 2;
-                memcpy(y_out + col - c->pic.linesize[0], encoded, 2);
+                memcpy(y_out + col - frame->linesize[0], encoded, 2);
                 encoded += 2;
                 u_out[col >> 1] = *encoded++ + 128;
                 v_out[col >> 1] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0] << 1;
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0] << 1;
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -626,8 +618,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
     LclDecContext * const c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
 #if CONFIG_ZLIB_DECODER
     if (avctx->codec_id == AV_CODEC_ID_ZLIB)
         inflateEnd(&c->zstream);
@@ -639,6 +629,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 #if CONFIG_MSZH_DECODER
 AVCodec ff_mszh_decoder = {
     .name           = "mszh",
+    .long_name      = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MSZH,
     .priv_data_size = sizeof(LclDecContext),
@@ -646,13 +637,13 @@ AVCodec ff_mszh_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"),
 };
 #endif
 
 #if CONFIG_ZLIB_DECODER
 AVCodec ff_zlib_decoder = {
     .name           = "zlib",
+    .long_name      = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ZLIB,
     .priv_data_size = sizeof(LclDecContext),
@@ -660,6 +651,5 @@ AVCodec ff_zlib_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
 };
 #endif
diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c
index 0fb303c..878d1e1 100644
--- a/libavcodec/lclenc.c
+++ b/libavcodec/lclenc.c
@@ -54,7 +54,6 @@
 typedef struct LclEncContext {
 
     AVCodecContext *avctx;
-    AVFrame pic;
 
     // Image type
     int imgtype;
@@ -74,7 +73,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *pict, int *got_packet)
 {
     LclEncContext *c = avctx->priv_data;
-    AVFrame * const p = &c->pic;
+    const AVFrame * const p = pict;
     int i, ret;
     int zret; // Zlib return code
     int max_size = deflateBound(&c->zstream, avctx->width * avctx->height * 3);
@@ -85,10 +84,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
             return ret;
     }
 
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
-
     if(avctx->pix_fmt != AV_PIX_FMT_BGR24){
         av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
         return -1;
@@ -139,7 +134,13 @@ static av_cold int encode_init(AVCodecContext *avctx)
     assert(avctx->width && avctx->height);
 
     avctx->extradata= av_mallocz(8);
-    avctx->coded_frame= &c->pic;
+
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
 
     // Will be user settable someday
     c->compression = 6;
@@ -181,11 +182,14 @@ static av_cold int encode_end(AVCodecContext *avctx)
     av_freep(&avctx->extradata);
     deflateEnd(&c->zstream);
 
+    av_frame_free(&avctx->coded_frame);
+
     return 0;
 }
 
 AVCodec ff_zlib_encoder = {
     .name           = "zlib",
+    .long_name      = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ZLIB,
     .priv_data_size = sizeof(LclEncContext),
@@ -193,5 +197,4 @@ AVCodec ff_zlib_encoder = {
     .encode2        = encode_frame,
     .close          = encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
 };
diff --git a/libavcodec/libavcodec.v b/libavcodec/libavcodec.v
index 0e1c2e1..bf14807 100644
--- a/libavcodec/libavcodec.v
+++ b/libavcodec/libavcodec.v
@@ -1,6 +1,4 @@
 LIBAVCODEC_$MAJOR {
         global: av*;
-                audio_resample;
-                audio_resample_close;
         local:  *;
 };
diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c
index d32e776..9b5b11a 100644
--- a/libavcodec/libfaac.c
+++ b/libavcodec/libfaac.c
@@ -46,9 +46,6 @@ static av_cold int Faac_encode_close(AVCodecContext *avctx)
 {
     FaacAudioContext *s = avctx->priv_data;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     av_freep(&avctx->extradata);
     ff_af_queue_close(&s->afq);
 
@@ -133,14 +130,6 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx)
 
     avctx->frame_size = samples_input / avctx->channels;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame= avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        ret = AVERROR(ENOMEM);
-        goto error;
-    }
-#endif
-
     /* Set decoder specific info */
     avctx->extradata_size = 0;
     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
@@ -236,6 +225,7 @@ static const uint64_t faac_channel_layouts[] = {
 
 AVCodec ff_libfaac_encoder = {
     .name           = "libfaac",
+    .long_name      = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Coding)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AAC,
     .priv_data_size = sizeof(FaacAudioContext),
@@ -245,7 +235,6 @@ AVCodec ff_libfaac_encoder = {
     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Coding)"),
     .profiles       = NULL_IF_CONFIG_SMALL(profiles),
     .channel_layouts = faac_channel_layouts,
 };
diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c
new file mode 100644
index 0000000..e459733
--- /dev/null
+++ b/libavcodec/libfdk-aacdec.c
@@ -0,0 +1,309 @@
+/*
+ * AAC decoder wrapper
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * 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 <fdk-aac/aacdecoder_lib.h>
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/common.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+
+enum ConcealMethod {
+    CONCEAL_METHOD_DEFAULT              = -1,
+    CONCEAL_METHOD_SPECTRAL_MUTING      =  0,
+    CONCEAL_METHOD_NOISE_SUBSTITUTION   =  1,
+    CONCEAL_METHOD_ENERGY_INTERPOLATION =  2,
+    CONCEAL_METHOD_NB,
+};
+
+typedef struct FDKAACDecContext {
+    const AVClass *class;
+    HANDLE_AACDECODER handle;
+    int initialized;
+    enum ConcealMethod conceal_method;
+} FDKAACDecContext;
+
+#define OFFSET(x) offsetof(FDKAACDecContext, x)
+#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption fdk_aac_dec_options[] = {
+    { "conceal", "Error concealment method", OFFSET(conceal_method), AV_OPT_TYPE_INT, { .i64 = CONCEAL_METHOD_DEFAULT }, CONCEAL_METHOD_DEFAULT, CONCEAL_METHOD_NB - 1, AD, "conceal" },
+    { "default",  "Default",              0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_DEFAULT },              INT_MIN, INT_MAX, AD, "conceal" },
+    { "spectral", "Spectral muting",      0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING },      INT_MIN, INT_MAX, AD, "conceal" },
+    { "noise",    "Noise Substitution",   0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION },   INT_MIN, INT_MAX, AD, "conceal" },
+    { "energy",   "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
+    { NULL }
+};
+
+static const AVClass fdk_aac_dec_class = {
+    "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
+};
+
+static int get_stream_info(AVCodecContext *avctx)
+{
+    FDKAACDecContext *s   = avctx->priv_data;
+    CStreamInfo *info     = aacDecoder_GetStreamInfo(s->handle);
+    int channel_counts[9] = { 0 };
+    int i, ch_error       = 0;
+    uint64_t ch_layout    = 0;
+
+    if (!info) {
+        av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    if (info->sampleRate <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
+        return AVERROR_UNKNOWN;
+    }
+    avctx->sample_rate = info->sampleRate;
+    avctx->frame_size  = info->frameSize;
+
+    for (i = 0; i < info->numChannels; i++) {
+        AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
+        if (ctype <= ACT_NONE || ctype > ACT_TOP) {
+            av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
+            break;
+        }
+        channel_counts[ctype]++;
+    }
+    av_log(avctx, AV_LOG_DEBUG,
+           "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
+           info->numChannels,
+           channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
+           channel_counts[ACT_BACK],  channel_counts[ACT_LFE],
+           channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
+           channel_counts[ACT_BACK_TOP]  + channel_counts[ACT_TOP]);
+
+    switch (channel_counts[ACT_FRONT]) {
+    case 4:
+        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |
+                     AV_CH_FRONT_RIGHT_OF_CENTER;
+        break;
+    case 3:
+        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
+        break;
+    case 2:
+        ch_layout |= AV_CH_LAYOUT_STEREO;
+        break;
+    case 1:
+        ch_layout |= AV_CH_FRONT_CENTER;
+        break;
+    default:
+        av_log(avctx, AV_LOG_WARNING,
+               "unsupported number of front channels: %d\n",
+               channel_counts[ACT_FRONT]);
+        ch_error = 1;
+        break;
+    }
+    if (channel_counts[ACT_SIDE] > 0) {
+        if (channel_counts[ACT_SIDE] == 2) {
+            ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
+        } else {
+            av_log(avctx, AV_LOG_WARNING,
+                   "unsupported number of side channels: %d\n",
+                   channel_counts[ACT_SIDE]);
+            ch_error = 1;
+        }
+    }
+    if (channel_counts[ACT_BACK] > 0) {
+        switch (channel_counts[ACT_BACK]) {
+        case 3:
+            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
+            break;
+        case 2:
+            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
+            break;
+        case 1:
+            ch_layout |= AV_CH_BACK_CENTER;
+            break;
+        default:
+            av_log(avctx, AV_LOG_WARNING,
+                   "unsupported number of back channels: %d\n",
+                   channel_counts[ACT_BACK]);
+            ch_error = 1;
+            break;
+        }
+    }
+    if (channel_counts[ACT_LFE] > 0) {
+        if (channel_counts[ACT_LFE] == 1) {
+            ch_layout |= AV_CH_LOW_FREQUENCY;
+        } else {
+            av_log(avctx, AV_LOG_WARNING,
+                   "unsupported number of LFE channels: %d\n",
+                   channel_counts[ACT_LFE]);
+            ch_error = 1;
+        }
+    }
+    if (!ch_error &&
+        av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {
+        av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
+        ch_error = 1;
+    }
+    if (ch_error)
+        avctx->channel_layout = 0;
+    else
+        avctx->channel_layout = ch_layout;
+
+    avctx->channels = info->numChannels;
+
+    return 0;
+}
+
+static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
+{
+    FDKAACDecContext *s = avctx->priv_data;
+
+    if (s->handle)
+        aacDecoder_Close(s->handle);
+
+    return 0;
+}
+
+static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
+{
+    FDKAACDecContext *s = avctx->priv_data;
+    AAC_DECODER_ERROR err;
+
+    s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
+    if (!s->handle) {
+        av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
+        return AVERROR_UNKNOWN;
+    }
+
+    if (avctx->extradata_size) {
+        if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata,
+                                        &avctx->extradata_size)) != AAC_DEC_OK) {
+            av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    if (s->conceal_method != CONCEAL_METHOD_DEFAULT) {
+        if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD,
+                                       s->conceal_method)) != AAC_DEC_OK) {
+            av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
+            return AVERROR_UNKNOWN;
+        }
+    }
+
+    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+    return 0;
+}
+
+static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
+                                int *got_frame_ptr, AVPacket *avpkt)
+{
+    FDKAACDecContext *s = avctx->priv_data;
+    AVFrame *frame = data;
+    int ret;
+    AAC_DECODER_ERROR err;
+    UINT valid = avpkt->size;
+    uint8_t *buf, *tmpptr = NULL;
+    int buf_size;
+
+    err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
+    if (err != AAC_DEC_OK) {
+        av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (s->initialized) {
+        frame->nb_samples = avctx->frame_size;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "ff_get_buffer() failed\n");
+            return ret;
+        }
+        buf = frame->extended_data[0];
+        buf_size = avctx->channels * frame->nb_samples *
+                   av_get_bytes_per_sample(avctx->sample_fmt);
+    } else {
+        buf_size = 50 * 1024;
+        buf = tmpptr = av_malloc(buf_size);
+        if (!buf)
+            return AVERROR(ENOMEM);
+    }
+
+    err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) buf, buf_size, 0);
+    if (err == AAC_DEC_NOT_ENOUGH_BITS) {
+        ret = avpkt->size - valid;
+        goto end;
+    }
+    if (err != AAC_DEC_OK) {
+        av_log(avctx, AV_LOG_ERROR,
+               "aacDecoder_DecodeFrame() failed: %x\n", err);
+        ret = AVERROR_UNKNOWN;
+        goto end;
+    }
+
+    if (!s->initialized) {
+        if ((ret = get_stream_info(avctx)) < 0)
+            goto end;
+        s->initialized = 1;
+        frame->nb_samples = avctx->frame_size;
+    }
+
+    if (tmpptr) {
+        frame->nb_samples = avctx->frame_size;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "ff_get_buffer() failed\n");
+            goto end;
+        }
+        memcpy(frame->extended_data[0], tmpptr,
+               avctx->channels * avctx->frame_size *
+               av_get_bytes_per_sample(avctx->sample_fmt));
+    }
+
+    *got_frame_ptr = 1;
+    ret = avpkt->size - valid;
+
+end:
+    av_free(tmpptr);
+    return ret;
+}
+
+static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
+{
+    FDKAACDecContext *s = avctx->priv_data;
+    AAC_DECODER_ERROR err;
+
+    if (!s->handle)
+        return;
+
+    if ((err = aacDecoder_SetParam(s->handle,
+                                   AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
+        av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
+}
+
+AVCodec ff_libfdk_aac_decoder = {
+    .name           = "libfdk_aac",
+    .long_name      = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_AAC,
+    .priv_data_size = sizeof(FDKAACDecContext),
+    .init           = fdk_aac_decode_init,
+    .decode         = fdk_aac_decode_frame,
+    .close          = fdk_aac_decode_close,
+    .flush          = fdk_aac_decode_flush,
+    .capabilities   = CODEC_CAP_DR1,
+    .priv_class     = &fdk_aac_dec_class,
+};
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
index c40bced..4827169 100644
--- a/libavcodec/libfdk-aacenc.c
+++ b/libavcodec/libfdk-aacenc.c
@@ -97,9 +97,6 @@ static int aac_encode_close(AVCodecContext *avctx)
 
     if (s->handle)
         aacEncClose(&s->handle);
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     av_freep(&avctx->extradata);
     ff_af_queue_close(&s->afq);
 
@@ -200,6 +197,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
             avctx->bit_rate = (96*sce + 128*cpe) * avctx->sample_rate / 44;
             if (avctx->profile == FF_PROFILE_AAC_HE ||
                 avctx->profile == FF_PROFILE_AAC_HE_V2 ||
+                avctx->profile == FF_PROFILE_MPEG2_AAC_HE ||
                 s->eld_sbr)
                 avctx->bit_rate /= 2;
         }
@@ -250,7 +248,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
     }
 
     if (avctx->cutoff > 0) {
-        if (avctx->cutoff < (avctx->sample_rate + 255) >> 8) {
+        if (avctx->cutoff < (avctx->sample_rate + 255) >> 8 || avctx->cutoff > 20000) {
             av_log(avctx, AV_LOG_ERROR, "cutoff valid range is %d-20000\n",
                    (avctx->sample_rate + 255) >> 8);
             goto error;
@@ -275,13 +273,6 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
         goto error;
     }
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        ret = AVERROR(ENOMEM);
-        goto error;
-    }
-#endif
     avctx->frame_size = info.frameLength;
     avctx->delay      = info.encoderDelay;
     ff_af_queue_init(avctx, &s->afq);
@@ -405,6 +396,7 @@ static const int aac_sample_rates[] = {
 
 AVCodec ff_libfdk_aac_encoder = {
     .name                  = "libfdk_aac",
+    .long_name             = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
     .type                  = AVMEDIA_TYPE_AUDIO,
     .id                    = AV_CODEC_ID_AAC,
     .priv_data_size        = sizeof(AACContext),
@@ -414,7 +406,6 @@ AVCodec ff_libfdk_aac_encoder = {
     .capabilities          = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
     .sample_fmts           = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                             AV_SAMPLE_FMT_NONE },
-    .long_name             = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
     .priv_class            = &aac_enc_class,
     .defaults              = aac_encode_defaults,
     .profiles              = profiles,
diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c
index b4d1c74..dfab005 100644
--- a/libavcodec/libgsm.c
+++ b/libavcodec/libgsm.c
@@ -27,7 +27,12 @@
 
 // The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html
 
+#include "config.h"
+#if HAVE_GSM_H
+#include <gsm.h>
+#else
 #include <gsm/gsm.h>
+#endif
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
@@ -72,21 +77,10 @@ static av_cold int libgsm_encode_init(AVCodecContext *avctx) {
         }
     }
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame= avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        gsm_destroy(avctx->priv_data);
-        return AVERROR(ENOMEM);
-    }
-#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;
@@ -120,6 +114,7 @@ static int libgsm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_libgsm_encoder = {
     .name           = "libgsm",
+    .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_GSM,
     .init           = libgsm_encode_init,
@@ -127,11 +122,11 @@ AVCodec ff_libgsm_encoder = {
     .close          = libgsm_encode_close,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM"),
 };
 
 AVCodec ff_libgsm_ms_encoder = {
     .name           = "libgsm_ms",
+    .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_GSM_MS,
     .init           = libgsm_encode_init,
@@ -139,11 +134,9 @@ AVCodec ff_libgsm_ms_encoder = {
     .close          = libgsm_encode_close,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
 };
 
 typedef struct LibGSMDecodeContext {
-    AVFrame frame;
     struct gsm_state *state;
 } LibGSMDecodeContext;
 
@@ -170,9 +163,6 @@ static av_cold int libgsm_decode_init(AVCodecContext *avctx) {
         }
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -189,6 +179,7 @@ static int libgsm_decode_frame(AVCodecContext *avctx, void *data,
 {
     int i, ret;
     LibGSMDecodeContext *s = avctx->priv_data;
+    AVFrame *frame         = data;
     uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     int16_t *samples;
@@ -199,12 +190,12 @@ static int libgsm_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    s->frame.nb_samples = avctx->frame_size;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = avctx->frame_size;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)s->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     for (i = 0; i < avctx->frame_size / GSM_FRAME_SIZE; i++) {
         if ((ret = gsm_decode(s->state, buf, samples)) < 0)
@@ -213,8 +204,7 @@ static int libgsm_decode_frame(AVCodecContext *avctx, void *data,
         samples += GSM_FRAME_SIZE;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
@@ -231,6 +221,7 @@ static void libgsm_flush(AVCodecContext *avctx) {
 
 AVCodec ff_libgsm_decoder = {
     .name           = "libgsm",
+    .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_GSM,
     .priv_data_size = sizeof(LibGSMDecodeContext),
@@ -239,11 +230,11 @@ AVCodec ff_libgsm_decoder = {
     .decode         = libgsm_decode_frame,
     .flush          = libgsm_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM"),
 };
 
 AVCodec ff_libgsm_ms_decoder = {
     .name           = "libgsm_ms",
+    .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_GSM_MS,
     .priv_data_size = sizeof(LibGSMDecodeContext),
@@ -252,5 +243,4 @@ AVCodec ff_libgsm_ms_decoder = {
     .decode         = libgsm_decode_frame,
     .flush          = libgsm_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
 };
diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
index 9acaa40..af693bd 100644
--- a/libavcodec/libilbc.c
+++ b/libavcodec/libilbc.c
@@ -41,7 +41,6 @@ static int get_mode(AVCodecContext *avctx)
 
 typedef struct ILBCDecContext {
     const AVClass *class;
-    AVFrame frame;
     iLBC_Dec_Inst_t decoder;
     int enhance;
 } ILBCDecContext;
@@ -66,8 +65,6 @@ static av_cold int ilbc_decode_init(AVCodecContext *avctx)
     }
 
     WebRtcIlbcfix_InitDecode(&s->decoder, mode, s->enhance);
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
 
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
@@ -83,6 +80,7 @@ static int ilbc_decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     ILBCDecContext *s  = avctx->priv_data;
+    AVFrame *frame     = data;
     int ret;
 
     if (s->decoder.no_of_bytes > buf_size) {
@@ -91,30 +89,29 @@ static int ilbc_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    s->frame.nb_samples = s->decoder.blockl;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->decoder.blockl;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) s->frame.data[0],
+    WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) frame->data[0],
                              (const WebRtc_UWord16*) buf, &s->decoder, 1);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return s->decoder.no_of_bytes;
 }
 
 AVCodec ff_libilbc_decoder = {
     .name           = "libilbc",
+    .long_name      = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ILBC,
     .priv_data_size = sizeof(ILBCDecContext),
     .init           = ilbc_decode_init,
     .decode         = ilbc_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"),
     .priv_class     = &ilbc_dec_class,
 };
 
@@ -156,20 +153,7 @@ static av_cold int ilbc_encode_init(AVCodecContext *avctx)
 
     avctx->block_align = s->encoder.no_of_bytes;
     avctx->frame_size  = s->encoder.blockl;
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-#endif
-
-    return 0;
-}
 
-static av_cold int ilbc_encode_close(AVCodecContext *avctx)
-{
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     return 0;
 }
 
@@ -198,15 +182,14 @@ static const AVCodecDefault ilbc_encode_defaults[] = {
 
 AVCodec ff_libilbc_encoder = {
     .name           = "libilbc",
+    .long_name      = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ILBC,
     .priv_data_size = sizeof(ILBCEncContext),
     .init           = ilbc_encode_init,
     .encode2        = ilbc_encode_frame,
-    .close          = ilbc_encode_close,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("iLBC (Internet Low Bitrate Codec)"),
     .defaults       = ilbc_encode_defaults,
     .priv_class     = &ilbc_enc_class,
 };
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index 2e501ca..ee76ff8 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -57,18 +57,14 @@ typedef struct LAMEContext {
 static int realloc_buffer(LAMEContext *s)
 {
     if (!s->buffer || s->buffer_size - s->buffer_index < BUFFER_SIZE) {
-        uint8_t *tmp;
-        int new_size = s->buffer_index + 2 * BUFFER_SIZE;
+        int new_size = s->buffer_index + 2 * BUFFER_SIZE, err;
 
         av_dlog(s->avctx, "resizing output buffer: %d -> %d\n", s->buffer_size,
                 new_size);
-        tmp = av_realloc(s->buffer, new_size);
-        if (!tmp) {
-            av_freep(&s->buffer);
+        if ((err = av_reallocp(&s->buffer, new_size)) < 0) {
             s->buffer_size = s->buffer_index = 0;
-            return AVERROR(ENOMEM);
+            return err;
         }
-        s->buffer      = tmp;
         s->buffer_size = new_size;
     }
     return 0;
@@ -78,9 +74,6 @@ static av_cold int mp3lame_encode_close(AVCodecContext *avctx)
 {
     LAMEContext *s = avctx->priv_data;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     av_freep(&s->samples_flt[0]);
     av_freep(&s->samples_flt[1]);
     av_freep(&s->buffer);
@@ -142,14 +135,6 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx)
 
     avctx->frame_size  = lame_get_framesize(s->gfp);
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        ret = AVERROR(ENOMEM);
-        goto error;
-    }
-#endif
-
     /* allocate float sample buffers */
     if (avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
         int ch;
@@ -296,6 +281,7 @@ static const int libmp3lame_sample_rates[] = {
 
 AVCodec ff_libmp3lame_encoder = {
     .name                  = "libmp3lame",
+    .long_name             = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
     .type                  = AVMEDIA_TYPE_AUDIO,
     .id                    = AV_CODEC_ID_MP3,
     .priv_data_size        = sizeof(LAMEContext),
@@ -311,7 +297,6 @@ AVCodec ff_libmp3lame_encoder = {
     .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
                                                   AV_CH_LAYOUT_STEREO,
                                                   0 },
-    .long_name             = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
     .priv_class            = &libmp3lame_class,
     .defaults              = libmp3lame_defaults,
 };
diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c
index be98b1f..6b45959 100644
--- a/libavcodec/libopencore-amr.c
+++ b/libavcodec/libopencore-amr.c
@@ -34,7 +34,7 @@ static int amr_decode_fix_avctx(AVCodecContext *avctx)
     avctx->sample_rate = 8000 * is_amr_wb;
 
     if (avctx->channels > 1) {
-        av_log_missing_feature(avctx, "multi-channel AMR", 0);
+        avpriv_report_missing_feature(avctx, "multi-channel AMR");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -51,7 +51,6 @@ static int amr_decode_fix_avctx(AVCodecContext *avctx)
 
 typedef struct AMRContext {
     AVClass *av_class;
-    AVFrame frame;
     void *dec_state;
     void *enc_state;
     int   enc_bitrate;
@@ -76,9 +75,6 @@ static av_cold int amr_nb_decode_init(AVCodecContext *avctx)
         return -1;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -94,6 +90,7 @@ static av_cold int amr_nb_decode_close(AVCodecContext *avctx)
 static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     AMRContext *s      = avctx->priv_data;
@@ -105,8 +102,8 @@ static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
             buf, buf_size, avctx->frame_number);
 
     /* get output buffer */
-    s->frame.nb_samples = 160;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 160;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -123,16 +120,16 @@ static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
     av_dlog(avctx, "packet_size=%d buf= 0x%X %X %X %X\n",
               packet_size, buf[0], buf[1], buf[2], buf[3]);
     /* call decoder */
-    Decoder_Interface_Decode(s->dec_state, buf, (short *)s->frame.data[0], 0);
+    Decoder_Interface_Decode(s->dec_state, buf, (short *)frame->data[0], 0);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return packet_size;
 }
 
 AVCodec ff_libopencore_amrnb_decoder = {
     .name           = "libopencore_amrnb",
+    .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AMR_NB,
     .priv_data_size = sizeof(AMRContext),
@@ -140,7 +137,6 @@ AVCodec ff_libopencore_amrnb_decoder = {
     .close          = amr_nb_decode_close,
     .decode         = amr_nb_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
 };
 #endif /* CONFIG_LIBOPENCORE_AMRNB_DECODER */
 
@@ -206,11 +202,6 @@ static av_cold int amr_nb_encode_init(AVCodecContext *avctx)
     avctx->frame_size  = 160;
     avctx->delay       =  50;
     ff_af_queue_init(avctx, &s->afq);
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-#endif
 
     s->enc_state = Encoder_Interface_init(s->enc_dtx);
     if (!s->enc_state) {
@@ -231,9 +222,6 @@ static av_cold int amr_nb_encode_close(AVCodecContext *avctx)
 
     Encoder_Interface_exit(s->enc_state);
     ff_af_queue_close(&s->afq);
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     return 0;
 }
 
@@ -296,6 +284,7 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_libopencore_amrnb_encoder = {
     .name           = "libopencore_amrnb",
+    .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AMR_NB,
     .priv_data_size = sizeof(AMRContext),
@@ -305,7 +294,6 @@ AVCodec ff_libopencore_amrnb_encoder = {
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-NB (Adaptive Multi-Rate Narrow-Band)"),
     .priv_class     = &class,
 };
 #endif /* CONFIG_LIBOPENCORE_AMRNB_ENCODER */
@@ -319,7 +307,6 @@ AVCodec ff_libopencore_amrnb_encoder = {
 #include <opencore-amrwb/if_rom.h>
 
 typedef struct AMRWBContext {
-    AVFrame frame;
     void  *state;
 } AMRWBContext;
 
@@ -333,15 +320,13 @@ static av_cold int amr_wb_decode_init(AVCodecContext *avctx)
 
     s->state        = D_IF_init();
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     AMRWBContext *s    = avctx->priv_data;
@@ -350,8 +335,8 @@ static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
     static const uint8_t block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
 
     /* get output buffer */
-    s->frame.nb_samples = 320;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 320;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -365,10 +350,9 @@ static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    D_IF_decode(s->state, buf, (short *)s->frame.data[0], _good_frame);
+    D_IF_decode(s->state, buf, (short *)frame->data[0], _good_frame);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return packet_size;
 }
@@ -383,6 +367,7 @@ static int amr_wb_decode_close(AVCodecContext *avctx)
 
 AVCodec ff_libopencore_amrwb_decoder = {
     .name           = "libopencore_amrwb",
+    .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AMR_WB,
     .priv_data_size = sizeof(AMRWBContext),
@@ -390,7 +375,6 @@ AVCodec ff_libopencore_amrwb_decoder = {
     .close          = amr_wb_decode_close,
     .decode         = amr_wb_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("OpenCORE AMR-WB (Adaptive Multi-Rate Wide-Band)"),
 };
 
 #endif /* CONFIG_LIBOPENCORE_AMRWB_DECODER */
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index 8f956f4..d6fca33 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -33,6 +33,7 @@
 #include "libavutil/pixfmt.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "thread.h"
 
 #define JP2_SIG_TYPE    0x6A502020
@@ -57,17 +58,19 @@
                            AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, \
                            AV_PIX_FMT_YUV444P16
 
+#define XYZ_PIXEL_FORMATS  AV_PIX_FMT_XYZ12
+
 static const enum AVPixelFormat rgb_pix_fmts[]  = {RGB_PIXEL_FORMATS};
 static const enum AVPixelFormat gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
 static const enum AVPixelFormat yuv_pix_fmts[]  = {YUV_PIXEL_FORMATS};
 static const enum AVPixelFormat any_pix_fmts[]  = {RGB_PIXEL_FORMATS,
                                                  GRAY_PIXEL_FORMATS,
-                                                 YUV_PIXEL_FORMATS};
+                                                 YUV_PIXEL_FORMATS,
+                                                 XYZ_PIXEL_FORMATS};
 
 typedef struct {
     AVClass *class;
     opj_dparameters_t dec_params;
-    AVFrame image;
     int lowres;
     int lowqual;
 } LibOpenJPEGContext;
@@ -239,16 +242,6 @@ static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
     LibOpenJPEGContext *ctx = avctx->priv_data;
 
     opj_set_default_decoder_parameters(&ctx->dec_params);
-    avcodec_get_frame_defaults(&ctx->image);
-    avctx->coded_frame = &ctx->image;
-    return 0;
-}
-
-static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx)
-{
-    LibOpenJPEGContext *ctx = avctx->priv_data;
-
-    avctx->coded_frame = &ctx->image;
     return 0;
 }
 
@@ -259,12 +252,13 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
     uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LibOpenJPEGContext *ctx = avctx->priv_data;
-    AVFrame *picture = &ctx->image, *output = data;
+    ThreadFrame frame = { .f = data };
+    AVFrame *picture  = data;
     const AVPixFmtDescriptor *desc;
     opj_dinfo_t *dec;
     opj_cio_t *stream;
     opj_image_t *image;
-    int width, height, ret = -1;
+    int width, height, ret;
     int pixel_size = 0;
     int ispacked = 0;
     int i;
@@ -286,7 +280,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
 
     if (!dec) {
         av_log(avctx, AV_LOG_ERROR, "Error initializing decoder.\n");
-        return -1;
+        return AVERROR_UNKNOWN;
     }
     opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
 
@@ -301,7 +295,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR,
                "Codestream could not be opened for reading.\n");
         opj_destroy_decompress(dec);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
 
     // Decode the header only.
@@ -311,7 +305,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
     if (!image) {
         av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
         opj_destroy_decompress(dec);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
 
     width  = image->x1 - image->x0;
@@ -322,13 +316,9 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
         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);
+    ret = ff_set_dimensions(avctx, width, height);
+    if (ret < 0)
         goto done;
-    }
-
-    avcodec_set_dimensions(avctx, width, height);
 
     if (avctx->pix_fmt != AV_PIX_FMT_NONE)
         if (!libopenjpeg_matches_pix_fmt(image, avctx->pix_fmt))
@@ -347,10 +337,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
         if (image->comps[i].prec > avctx->bits_per_raw_sample)
             avctx->bits_per_raw_sample = image->comps[i].prec;
 
-    if (picture->data[0])
-        ff_thread_release_buffer(avctx, picture);
-
-    if (ff_thread_get_buffer(avctx, picture) < 0) {
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n");
         goto done;
     }
@@ -362,6 +349,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
     if (!stream) {
         av_log(avctx, AV_LOG_ERROR,
                "Codestream could not be opened for reading.\n");
+        ret = AVERROR_UNKNOWN;
         goto done;
     }
 
@@ -372,6 +360,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
 
     if (!image) {
         av_log(avctx, AV_LOG_ERROR, "Error decoding codestream.\n");
+        ret = AVERROR_UNKNOWN;
         goto done;
     }
 
@@ -408,10 +397,10 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "unsupported pixel size %d\n", pixel_size);
+        ret = AVERROR_PATCHWELCOME;
         goto done;
     }
 
-    *output    = ctx->image;
     *got_frame = 1;
     ret        = buf_size;
 
@@ -421,15 +410,6 @@ done:
     return ret;
 }
 
-static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx)
-{
-    LibOpenJPEGContext *ctx = avctx->priv_data;
-
-    if (ctx->image.data[0])
-        ff_thread_release_buffer(avctx, &ctx->image);
-    return 0;
-}
-
 #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
 
@@ -448,14 +428,12 @@ static const AVClass class = {
 
 AVCodec ff_libopenjpeg_decoder = {
     .name             = "libopenjpeg",
+    .long_name        = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
     .type             = AVMEDIA_TYPE_VIDEO,
     .id               = AV_CODEC_ID_JPEG2000,
     .priv_data_size   = sizeof(LibOpenJPEGContext),
     .init             = libopenjpeg_decode_init,
-    .close            = libopenjpeg_decode_close,
     .decode           = libopenjpeg_decode_frame,
     .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
-    .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..b84e6a4 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -168,7 +168,7 @@ static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame) {
         av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
         goto fail;
@@ -413,6 +413,7 @@ static const AVClass class = {
 
 AVCodec ff_libopenjpeg_encoder = {
     .name           = "libopenjpeg",
+    .long_name      = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_JPEG2000,
     .priv_data_size = sizeof(LibOpenJPEGContext),
@@ -431,6 +432,5 @@ AVCodec ff_libopenjpeg_encoder = {
         AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
         AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
     .priv_class     = &class,
 };
diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c
index 15fa493..398450f 100644
--- a/libavcodec/libopusdec.c
+++ b/libavcodec/libopusdec.c
@@ -32,7 +32,6 @@
 
 struct libopus_context {
     OpusMSDecoder *dec;
-    AVFrame frame;
 };
 
 #define OPUS_HEAD_SIZE 19
@@ -95,8 +94,7 @@ static av_cold int libopus_decode_init(AVCodecContext *avc)
                opus_strerror(ret));
 
     avc->delay = 3840;  /* Decoder delay (in samples) at 48kHz */
-    avcodec_get_frame_defaults(&opus->frame);
-    avc->coded_frame = &opus->frame;
+
     return 0;
 }
 
@@ -110,14 +108,15 @@ static av_cold int libopus_decode_close(AVCodecContext *avc)
 
 #define MAX_FRAME_SIZE (960 * 6)
 
-static int libopus_decode(AVCodecContext *avc, void *frame,
+static int libopus_decode(AVCodecContext *avc, void *data,
                           int *got_frame_ptr, AVPacket *pkt)
 {
     struct libopus_context *opus = avc->priv_data;
+    AVFrame *frame               = data;
     int ret, nb_samples;
 
-    opus->frame.nb_samples = MAX_FRAME_SIZE;
-    ret = ff_get_buffer(avc, &opus->frame);
+    frame->nb_samples = MAX_FRAME_SIZE;
+    ret = ff_get_buffer(avc, frame, 0);
     if (ret < 0) {
         av_log(avc, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
@@ -125,12 +124,12 @@ static int libopus_decode(AVCodecContext *avc, void *frame,
 
     if (avc->sample_fmt == AV_SAMPLE_FMT_S16)
         nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size,
-                                             (opus_int16 *)opus->frame.data[0],
-                                             opus->frame.nb_samples, 0);
+                                             (opus_int16 *)frame->data[0],
+                                             frame->nb_samples, 0);
     else
         nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size,
-                                                   (float *)opus->frame.data[0],
-                                                   opus->frame.nb_samples, 0);
+                                                   (float *)frame->data[0],
+                                                   frame->nb_samples, 0);
 
     if (nb_samples < 0) {
         av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n",
@@ -138,9 +137,9 @@ static int libopus_decode(AVCodecContext *avc, void *frame,
         return ff_opus_error_to_averror(nb_samples);
     }
 
-    opus->frame.nb_samples = nb_samples;
-    *(AVFrame *)frame = opus->frame;
-    *got_frame_ptr = 1;
+    frame->nb_samples = nb_samples;
+    *got_frame_ptr    = 1;
+
     return pkt->size;
 }
 
@@ -153,6 +152,7 @@ static void libopus_flush(AVCodecContext *avc)
 
 AVCodec ff_libopus_decoder = {
     .name           = "libopus",
+    .long_name      = NULL_IF_CONFIG_SMALL("libopus Opus"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_OPUS,
     .priv_data_size = sizeof(struct libopus_context),
@@ -161,7 +161,6 @@ AVCodec ff_libopus_decoder = {
     .decode         = libopus_decode,
     .flush          = libopus_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("libopus Opus"),
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c
index f124e19..592b8ca 100644
--- a/libavcodec/libopusenc.c
+++ b/libavcodec/libopusenc.c
@@ -403,6 +403,7 @@ static const int libopus_sample_rates[] = {
 
 AVCodec ff_libopus_encoder = {
     .name            = "libopus",
+    .long_name       = NULL_IF_CONFIG_SMALL("libopus Opus"),
     .type            = AVMEDIA_TYPE_AUDIO,
     .id              = AV_CODEC_ID_OPUS,
     .priv_data_size  = sizeof(LibopusEncContext),
@@ -415,7 +416,6 @@ AVCodec ff_libopus_encoder = {
                                                       AV_SAMPLE_FMT_NONE },
     .channel_layouts = ff_vorbis_channel_layouts,
     .supported_samplerates = libopus_sample_rates,
-    .long_name       = NULL_IF_CONFIG_SMALL("libopus Opus"),
     .priv_class      = &libopus_class,
     .defaults        = libopus_defaults,
 };
diff --git a/libavcodec/libschroedinger.c b/libavcodec/libschroedinger.c
index 68e925c..fc9188c 100644
--- a/libavcodec/libschroedinger.c
+++ b/libavcodec/libschroedinger.c
@@ -23,8 +23,9 @@
 * function definitions common to libschroedinger decoder and encoder
 */
 
-#include "libschroedinger.h"
+#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
+#include "libschroedinger.h"
 
 static const SchroVideoFormatInfo ff_schro_video_format_info[] = {
     { 640,  480,  24000, 1001},
@@ -46,7 +47,7 @@ static const SchroVideoFormatInfo ff_schro_video_format_info[] = {
     { 4096, 2160, 24,    1   },
 };
 
-static unsigned int get_video_format_idx(AVCodecContext *avccontext)
+static unsigned int get_video_format_idx(AVCodecContext *avctx)
 {
     unsigned int ret_idx = 0;
     unsigned int idx;
@@ -55,18 +56,18 @@ static unsigned int get_video_format_idx(AVCodecContext *avccontext)
 
     for (idx = 1; idx < num_formats; ++idx) {
         const SchroVideoFormatInfo *vf = &ff_schro_video_format_info[idx];
-        if (avccontext->width  == vf->width &&
-            avccontext->height == vf->height) {
+        if (avctx->width  == vf->width &&
+            avctx->height == vf->height) {
             ret_idx = idx;
-            if (avccontext->time_base.den == vf->frame_rate_num &&
-                avccontext->time_base.num == vf->frame_rate_denom)
+            if (avctx->time_base.den == vf->frame_rate_num &&
+                avctx->time_base.num == vf->frame_rate_denom)
                 return idx;
         }
     }
     return ret_idx;
 }
 
-void ff_schro_queue_init(FFSchroQueue *queue)
+av_cold void ff_schro_queue_init(FFSchroQueue *queue)
 {
     queue->p_head = queue->p_tail = NULL;
     queue->size = 0;
@@ -136,12 +137,12 @@ static const SchroVideoFormatEnum ff_schro_video_formats[]={
     SCHRO_VIDEO_FORMAT_DC4K_24    ,
 };
 
-SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avccontext)
+SchroVideoFormatEnum ff_get_schro_video_format_preset(AVCodecContext *avctx)
 {
     unsigned int num_formats = sizeof(ff_schro_video_formats) /
                                sizeof(ff_schro_video_formats[0]);
 
-    unsigned int idx = get_video_format_idx(avccontext);
+    unsigned int idx = get_video_format_idx(avctx);
 
     return (idx < num_formats) ? ff_schro_video_formats[idx] :
                                  SCHRO_VIDEO_FORMAT_CUSTOM;
@@ -175,7 +176,7 @@ static void free_schro_frame(SchroFrame *frame, void *priv)
     av_freep(&p_pic);
 }
 
-SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
+SchroFrame *ff_create_schro_frame(AVCodecContext *avctx,
                                   SchroFrameFormat schro_frame_fmt)
 {
     AVPicture *p_pic;
@@ -184,13 +185,13 @@ SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
     int y_height, uv_height;
     int i;
 
-    y_width   = avccontext->width;
-    y_height  = avccontext->height;
+    y_width   = avctx->width;
+    y_height  = avctx->height;
     uv_width  = y_width  >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt));
     uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt));
 
     p_pic = av_mallocz(sizeof(AVPicture));
-    avpicture_alloc(p_pic, avccontext->pix_fmt, y_width, y_height);
+    avpicture_alloc(p_pic, avctx->pix_fmt, y_width, y_height);
 
     p_frame         = schro_frame_new();
     p_frame->format = schro_frame_fmt;
diff --git a/libavcodec/libschroedinger.h b/libavcodec/libschroedinger.h
index bf179d2..5481f92 100644
--- a/libavcodec/libschroedinger.h
+++ b/libavcodec/libschroedinger.h
@@ -114,7 +114,7 @@ static const struct {
 * Returns the video format preset matching the input video dimensions and
 * time base.
 */
-SchroVideoFormatEnum ff_get_schro_video_format_preset (AVCodecContext *avccontext);
+SchroVideoFormatEnum ff_get_schro_video_format_preset (AVCodecContext *avctx);
 
 /**
 * Sets the Schroedinger frame format corresponding to the Schro chroma format
@@ -127,7 +127,7 @@ int ff_get_schro_frame_format(SchroChromaFormat schro_chroma_fmt,
 * Create a Schro frame based on the dimensions and frame format
 * passed. Returns a pointer to a frame on success, NULL on failure.
 */
-SchroFrame *ff_create_schro_frame(AVCodecContext *avccontext,
+SchroFrame *ff_create_schro_frame(AVCodecContext *avctx,
                                   SchroFrameFormat schro_frame_fmt);
 
 #endif /* AVCODEC_LIBSCHROEDINGER_H */
diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c
index 2411fe6..7e258e3 100644
--- a/libavcodec/libschroedingerdec.c
+++ b/libavcodec/libschroedingerdec.c
@@ -70,9 +70,6 @@ typedef struct SchroDecoderParams {
 
     /** end of sequence pulled */
     int eos_pulled;
-
-    /** decoded picture */
-    AVFrame dec_frame;
 } SchroDecoderParams;
 
 typedef struct SchroParseUnitContext {
@@ -151,14 +148,14 @@ static enum AVPixelFormat get_chroma_format(SchroChromaFormat schro_pix_fmt)
     return AV_PIX_FMT_NONE;
 }
 
-static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext)
+static av_cold int libschroedinger_decode_init(AVCodecContext *avctx)
 {
 
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
     /* First of all, initialize our supporting libraries. */
     schro_init();
 
-    schro_debug_set_level(avccontext->debug);
+    schro_debug_set_level(avctx->debug);
     p_schro_params->decoder = schro_decoder_new();
     schro_decoder_set_skip_ratio(p_schro_params->decoder, 1);
 
@@ -175,38 +172,38 @@ static void libschroedinger_decode_frame_free(void *frame)
     schro_frame_unref(frame);
 }
 
-static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
+static void libschroedinger_handle_first_access_unit(AVCodecContext *avctx)
 {
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
     SchroDecoder *decoder = p_schro_params->decoder;
 
     p_schro_params->format = schro_decoder_get_video_format(decoder);
 
     /* Tell Libav about sequence details. */
     if (av_image_check_size(p_schro_params->format->width,
-                            p_schro_params->format->height, 0, avccontext) < 0) {
-        av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
+                            p_schro_params->format->height, 0, avctx) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
                p_schro_params->format->width, p_schro_params->format->height);
-        avccontext->height = avccontext->width = 0;
+        avctx->height = avctx->width = 0;
         return;
     }
-    avccontext->height  = p_schro_params->format->height;
-    avccontext->width   = p_schro_params->format->width;
-    avccontext->pix_fmt = get_chroma_format(p_schro_params->format->chroma_format);
+    avctx->height  = p_schro_params->format->height;
+    avctx->width   = p_schro_params->format->width;
+    avctx->pix_fmt = get_chroma_format(p_schro_params->format->chroma_format);
 
     if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,
                                   &p_schro_params->frame_format) == -1) {
-        av_log(avccontext, AV_LOG_ERROR,
+        av_log(avctx, AV_LOG_ERROR,
                "This codec currently only supports planar YUV 4:2:0, 4:2:2 "
                "and 4:4:4 formats.\n");
         return;
     }
 
-    avccontext->time_base.den = p_schro_params->format->frame_rate_numerator;
-    avccontext->time_base.num = p_schro_params->format->frame_rate_denominator;
+    avctx->time_base.den = p_schro_params->format->frame_rate_numerator;
+    avctx->time_base.num = p_schro_params->format->frame_rate_denominator;
 }
 
-static int libschroedinger_decode_frame(AVCodecContext *avccontext,
+static int libschroedinger_decode_frame(AVCodecContext *avctx,
                                         void *data, int *got_frame,
                                         AVPacket *avpkt)
 {
@@ -215,10 +212,11 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
     int64_t pts  = avpkt->pts;
     SchroTag *tag;
 
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
     SchroDecoder *decoder = p_schro_params->decoder;
     SchroBuffer *enc_buf;
     SchroFrame* frame;
+    AVFrame *avframe = data;
     int state;
     int go = 1;
     int outer = 1;
@@ -241,17 +239,17 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
             /* Set Schrotag with the pts to be recovered after decoding*/
             enc_buf->tag = schro_tag_new(av_malloc(sizeof(int64_t)), av_free);
             if (!enc_buf->tag->value) {
-                av_log(avccontext, AV_LOG_ERROR, "Unable to allocate SchroTag\n");
+                av_log(avctx, AV_LOG_ERROR, "Unable to allocate SchroTag\n");
                 return AVERROR(ENOMEM);
             }
             AV_WN(64, enc_buf->tag->value, pts);
             /* Push buffer into decoder. */
             if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
                 SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
-                avccontext->has_b_frames = 1;
+                avctx->has_b_frames = 1;
             state = schro_decoder_push(decoder, enc_buf);
             if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
-                libschroedinger_handle_first_access_unit(avccontext);
+                libschroedinger_handle_first_access_unit(avctx);
             go = 1;
         } else
             outer = 0;
@@ -261,7 +259,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
             state = schro_decoder_wait(decoder);
             switch (state) {
             case SCHRO_DECODER_FIRST_ACCESS_UNIT:
-                libschroedinger_handle_first_access_unit(avccontext);
+                libschroedinger_handle_first_access_unit(avctx);
                 break;
 
             case SCHRO_DECODER_NEED_BITS:
@@ -271,7 +269,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
 
             case SCHRO_DECODER_NEED_FRAME:
                 /* Decoder needs a frame - create one and push it in. */
-                frame = ff_create_schro_frame(avccontext,
+                frame = ff_create_schro_frame(avctx,
                                               p_schro_params->frame_format);
                 schro_decoder_add_output_picture(decoder, frame);
                 break;
@@ -285,7 +283,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
                     /* Add relation between schroframe and pts. */
                     framewithpts = av_malloc(sizeof(LibSchroFrameContext));
                     if (!framewithpts) {
-                        av_log(avccontext, AV_LOG_ERROR, "Unable to allocate FrameWithPts\n");
+                        av_log(avctx, AV_LOG_ERROR, "Unable to allocate FrameWithPts\n");
                         return AVERROR(ENOMEM);
                     }
                     framewithpts->frame = frame;
@@ -312,35 +310,29 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
     framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue);
 
     if (framewithpts && framewithpts->frame) {
-        if (p_schro_params->dec_frame.data[0])
-            avccontext->release_buffer(avccontext, &p_schro_params->dec_frame);
-        if (ff_get_buffer(avccontext, &p_schro_params->dec_frame) < 0) {
-            av_log(avccontext, AV_LOG_ERROR, "Unable to allocate buffer\n");
+        if (ff_get_buffer(avctx, avframe, 0) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n");
             return AVERROR(ENOMEM);
         }
 
-        memcpy(p_schro_params->dec_frame.data[0],
+        memcpy(avframe->data[0],
                framewithpts->frame->components[0].data,
                framewithpts->frame->components[0].length);
 
-        memcpy(p_schro_params->dec_frame.data[1],
+        memcpy(avframe->data[1],
                framewithpts->frame->components[1].data,
                framewithpts->frame->components[1].length);
 
-        memcpy(p_schro_params->dec_frame.data[2],
+        memcpy(avframe->data[2],
                framewithpts->frame->components[2].data,
                framewithpts->frame->components[2].length);
 
         /* Fill frame with current buffer data from Schroedinger. */
-        p_schro_params->dec_frame.format  = -1; /* Unknown -1 */
-        p_schro_params->dec_frame.width   = framewithpts->frame->width;
-        p_schro_params->dec_frame.height  = framewithpts->frame->height;
-        p_schro_params->dec_frame.pkt_pts = framewithpts->pts;
-        p_schro_params->dec_frame.linesize[0] = framewithpts->frame->components[0].stride;
-        p_schro_params->dec_frame.linesize[1] = framewithpts->frame->components[1].stride;
-        p_schro_params->dec_frame.linesize[2] = framewithpts->frame->components[2].stride;
-
-        *(AVFrame*)data = p_schro_params->dec_frame;
+        avframe->pkt_pts = framewithpts->pts;
+        avframe->linesize[0] = framewithpts->frame->components[0].stride;
+        avframe->linesize[1] = framewithpts->frame->components[1].stride;
+        avframe->linesize[2] = framewithpts->frame->components[2].stride;
+
         *got_frame      = 1;
 
         /* Now free the frame resources. */
@@ -354,16 +346,13 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext,
 }
 
 
-static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext)
+static av_cold int libschroedinger_decode_close(AVCodecContext *avctx)
 {
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
     /* Free the decoder. */
     schro_decoder_free(p_schro_params->decoder);
     av_freep(&p_schro_params->format);
 
-    if (p_schro_params->dec_frame.data[0])
-        avccontext->release_buffer(avccontext, &p_schro_params->dec_frame);
-
     /* Free data in the output frame queue. */
     ff_schro_queue_free(&p_schro_params->dec_frame_queue,
                         libschroedinger_decode_frame_free);
@@ -371,11 +360,11 @@ static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext)
     return 0;
 }
 
-static void libschroedinger_flush(AVCodecContext *avccontext)
+static void libschroedinger_flush(AVCodecContext *avctx)
 {
     /* Got a seek request. Free the decoded frames queue and then reset
      * the decoder */
-    SchroDecoderParams *p_schro_params = avccontext->priv_data;
+    SchroDecoderParams *p_schro_params = avctx->priv_data;
 
     /* Free data in the output frame queue. */
     ff_schro_queue_free(&p_schro_params->dec_frame_queue,
@@ -389,6 +378,7 @@ static void libschroedinger_flush(AVCodecContext *avccontext)
 
 AVCodec ff_libschroedinger_decoder = {
     .name           = "libschroedinger",
+    .long_name      = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DIRAC,
     .priv_data_size = sizeof(SchroDecoderParams),
@@ -397,5 +387,4 @@ AVCodec ff_libschroedinger_decoder = {
     .decode         = libschroedinger_decode_frame,
     .capabilities   = CODEC_CAP_DELAY,
     .flush          = libschroedinger_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
 };
diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c
index 4002286..3dc1481 100644
--- a/libavcodec/libschroedingerenc.c
+++ b/libavcodec/libschroedingerenc.c
@@ -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/attributes.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "libschroedinger.h"
@@ -48,9 +46,6 @@ typedef struct SchroEncoderParams {
     /** Schroedinger frame format */
     SchroFrameFormat frame_format;
 
-    /** frame being encoded */
-    AVFrame picture;
-
     /** frame size */
     int frame_size;
 
@@ -79,33 +74,32 @@ typedef struct SchroEncoderParams {
 /**
 * Works out Schro-compatible chroma format.
 */
-static int set_chroma_format(AVCodecContext *avccontext)
+static int set_chroma_format(AVCodecContext *avctx)
 {
     int num_formats = sizeof(schro_pixel_format_map) /
                       sizeof(schro_pixel_format_map[0]);
     int idx;
 
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
 
     for (idx = 0; idx < num_formats; ++idx) {
-        if (schro_pixel_format_map[idx].ff_pix_fmt ==
-            avccontext->pix_fmt) {
+        if (schro_pixel_format_map[idx].ff_pix_fmt == avctx->pix_fmt) {
             p_schro_params->format->chroma_format =
                             schro_pixel_format_map[idx].schro_pix_fmt;
             return 0;
         }
     }
 
-    av_log(avccontext, AV_LOG_ERROR,
+    av_log(avctx, AV_LOG_ERROR,
            "This codec currently only supports planar YUV 4:2:0, 4:2:2"
            " and 4:4:4 formats.\n");
 
     return -1;
 }
 
-static int libschroedinger_encode_init(AVCodecContext *avccontext)
+static av_cold int libschroedinger_encode_init(AVCodecContext *avctx)
 {
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
     SchroVideoFormatEnum preset;
 
     /* Initialize the libraries that libschroedinger depends on. */
@@ -115,75 +109,77 @@ static int libschroedinger_encode_init(AVCodecContext *avccontext)
     p_schro_params->encoder = schro_encoder_new();
 
     if (!p_schro_params->encoder) {
-        av_log(avccontext, AV_LOG_ERROR,
+        av_log(avctx, AV_LOG_ERROR,
                "Unrecoverable Error: schro_encoder_new failed. ");
         return -1;
     }
 
     /* Initialize the format. */
-    preset = ff_get_schro_video_format_preset(avccontext);
+    preset = ff_get_schro_video_format_preset(avctx);
     p_schro_params->format =
                     schro_encoder_get_video_format(p_schro_params->encoder);
     schro_video_format_set_std_video_format(p_schro_params->format, preset);
-    p_schro_params->format->width  = avccontext->width;
-    p_schro_params->format->height = avccontext->height;
+    p_schro_params->format->width  = avctx->width;
+    p_schro_params->format->height = avctx->height;
 
-    if (set_chroma_format(avccontext) == -1)
+    if (set_chroma_format(avctx) == -1)
         return -1;
 
-    if (avccontext->color_primaries == AVCOL_PRI_BT709) {
+    if (avctx->color_primaries == AVCOL_PRI_BT709) {
         p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_HDTV;
-    } else if (avccontext->color_primaries == AVCOL_PRI_BT470BG) {
+    } else if (avctx->color_primaries == AVCOL_PRI_BT470BG) {
         p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_625;
-    } else if (avccontext->color_primaries == AVCOL_PRI_SMPTE170M) {
+    } else if (avctx->color_primaries == AVCOL_PRI_SMPTE170M) {
         p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_525;
     }
 
-    if (avccontext->colorspace == AVCOL_SPC_BT709) {
+    if (avctx->colorspace == AVCOL_SPC_BT709) {
         p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_HDTV;
-    } else if (avccontext->colorspace == AVCOL_SPC_BT470BG) {
+    } else if (avctx->colorspace == AVCOL_SPC_BT470BG) {
         p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_SDTV;
     }
 
-    if (avccontext->color_trc == AVCOL_TRC_BT709) {
+    if (avctx->color_trc == AVCOL_TRC_BT709) {
         p_schro_params->format->transfer_function = SCHRO_TRANSFER_CHAR_TV_GAMMA;
     }
 
     if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,
                                   &p_schro_params->frame_format) == -1) {
-        av_log(avccontext, AV_LOG_ERROR,
+        av_log(avctx, AV_LOG_ERROR,
                "This codec currently supports only planar YUV 4:2:0, 4:2:2"
                " and 4:4:4 formats.\n");
         return -1;
     }
 
-    p_schro_params->format->frame_rate_numerator   = avccontext->time_base.den;
-    p_schro_params->format->frame_rate_denominator = avccontext->time_base.num;
+    p_schro_params->format->frame_rate_numerator   = avctx->time_base.den;
+    p_schro_params->format->frame_rate_denominator = avctx->time_base.num;
 
-    p_schro_params->frame_size = avpicture_get_size(avccontext->pix_fmt,
-                                                    avccontext->width,
-                                                    avccontext->height);
+    p_schro_params->frame_size = avpicture_get_size(avctx->pix_fmt,
+                                                    avctx->width,
+                                                    avctx->height);
 
-    avccontext->coded_frame = &p_schro_params->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
 
-    if (!avccontext->gop_size) {
+    if (!avctx->gop_size) {
         schro_encoder_setting_set_double(p_schro_params->encoder,
                                          "gop_structure",
                                          SCHRO_ENCODER_GOP_INTRA_ONLY);
 
-        if (avccontext->coder_type == FF_CODER_TYPE_VLC)
+        if (avctx->coder_type == FF_CODER_TYPE_VLC)
             schro_encoder_setting_set_double(p_schro_params->encoder,
                                              "enable_noarith", 1);
     } else {
         schro_encoder_setting_set_double(p_schro_params->encoder,
-                                         "au_distance", avccontext->gop_size);
-        avccontext->has_b_frames = 1;
+                                         "au_distance", avctx->gop_size);
+        avctx->has_b_frames = 1;
         p_schro_params->dts = -1;
     }
 
     /* FIXME - Need to handle SCHRO_ENCODER_RATE_CONTROL_LOW_DELAY. */
-    if (avccontext->flags & CODEC_FLAG_QSCALE) {
-        if (!avccontext->global_quality) {
+    if (avctx->flags & CODEC_FLAG_QSCALE) {
+        if (!avctx->global_quality) {
             /* lossless coding */
             schro_encoder_setting_set_double(p_schro_params->encoder,
                                              "rate_control",
@@ -194,7 +190,7 @@ static int libschroedinger_encode_init(AVCodecContext *avccontext)
                                              "rate_control",
                                              SCHRO_ENCODER_RATE_CONTROL_CONSTANT_QUALITY);
 
-            quality = avccontext->global_quality / FF_QP2LAMBDA;
+            quality = avctx->global_quality / FF_QP2LAMBDA;
             if (quality > 10)
                 quality = 10;
             schro_encoder_setting_set_double(p_schro_params->encoder,
@@ -206,19 +202,17 @@ static int libschroedinger_encode_init(AVCodecContext *avccontext)
                                          SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE);
 
         schro_encoder_setting_set_double(p_schro_params->encoder,
-                                         "bitrate",
-                                         avccontext->bit_rate);
-
+                                         "bitrate", avctx->bit_rate);
     }
 
-    if (avccontext->flags & CODEC_FLAG_INTERLACED_ME)
+    if (avctx->flags & CODEC_FLAG_INTERLACED_ME)
         /* All material can be coded as interlaced or progressive
            irrespective of the type of source material. */
         schro_encoder_setting_set_double(p_schro_params->encoder,
                                          "interlaced_coding", 1);
 
     schro_encoder_setting_set_double(p_schro_params->encoder, "open_gop",
-                                     !(avccontext->flags & CODEC_FLAG_CLOSED_GOP));
+                                     !(avctx->flags & CODEC_FLAG_CLOSED_GOP));
 
     /* FIXME: Signal range hardcoded to 8-bit data until both libschroedinger
      * and libdirac support other bit-depth data. */
@@ -230,7 +224,7 @@ static int libschroedinger_encode_init(AVCodecContext *avccontext)
                                    p_schro_params->format);
 
     /* Set the debug level. */
-    schro_debug_set_level(avccontext->debug);
+    schro_debug_set_level(avctx->debug);
 
     schro_encoder_start(p_schro_params->encoder);
 
@@ -239,19 +233,19 @@ static int libschroedinger_encode_init(AVCodecContext *avccontext)
     return 0;
 }
 
-static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avccontext,
+static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avctx,
                                                    const AVFrame *frame)
 {
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
     SchroFrame *in_frame;
     /* Input line size may differ from what the codec supports. Especially
      * when transcoding from one format to another. So use avpicture_layout
      * to copy the frame. */
-    in_frame = ff_create_schro_frame(avccontext, p_schro_params->frame_format);
+    in_frame = ff_create_schro_frame(avctx, p_schro_params->frame_format);
 
     if (in_frame)
-        avpicture_layout((const AVPicture *)frame, avccontext->pix_fmt,
-                          avccontext->width, avccontext->height,
+        avpicture_layout((const AVPicture *)frame, avctx->pix_fmt,
+                          avctx->width, avctx->height,
                           in_frame->components[0].data,
                           p_schro_params->frame_size);
 
@@ -266,11 +260,11 @@ static void libschroedinger_free_frame(void *data)
     av_free(enc_frame);
 }
 
-static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pkt,
+static int libschroedinger_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                         const AVFrame *frame, int *got_packet)
 {
     int enc_size = 0;
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
     SchroEncoder *encoder = p_schro_params->encoder;
     struct FFSchroEncodedFrame *p_frame_output = NULL;
     int go = 1;
@@ -288,8 +282,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
         }
     } else {
         /* Allocate frame data to schro input buffer. */
-        SchroFrame *in_frame = libschroedinger_frame_from_data(avccontext,
-                                                               frame);
+        SchroFrame *in_frame = libschroedinger_frame_from_data(avctx, frame);
         /* Load next frame. */
         schro_encoder_push_frame(encoder, in_frame);
     }
@@ -299,22 +292,27 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
 
     /* Now check to see if we have any output from the encoder. */
     while (go) {
+        int err;
         SchroStateEnum state;
         state = schro_encoder_wait(encoder);
         switch (state) {
         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);
+            if (enc_buf->length <= 0)
+                return AVERROR_BUG;
             parse_code = enc_buf->data[4];
 
             /* All non-frame data is prepended to actual frame data to
              * be able to set the pts correctly. So we don't write data
              * to the frame output queue until we actually have a frame
              */
-            p_schro_params->enc_buf = av_realloc(p_schro_params->enc_buf,
-                                                 p_schro_params->enc_buf_size + enc_buf->length);
+            if ((err = av_reallocp(&p_schro_params->enc_buf,
+                                   p_schro_params->enc_buf_size +
+                                   enc_buf->length)) < 0) {
+                p_schro_params->enc_buf_size = 0;
+                return err;
+            }
 
             memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size,
                    enc_buf->data, enc_buf->length);
@@ -361,7 +359,7 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
             break;
 
         default:
-            av_log(avccontext, AV_LOG_ERROR, "Unknown Schro Encoder state\n");
+            av_log(avctx, AV_LOG_ERROR, "Unknown Schro Encoder state\n");
             return -1;
         }
     }
@@ -381,17 +379,17 @@ static int libschroedinger_encode_frame(AVCodecContext *avccontext, AVPacket *pk
     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);
+        av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", pkt_size);
         goto error;
     }
 
     memcpy(pkt->data, p_frame_output->p_encbuf, p_frame_output->size);
-    avccontext->coded_frame->key_frame = p_frame_output->key_frame;
+    avctx->coded_frame->key_frame = p_frame_output->key_frame;
     /* Use the frame number of the encoded frame as the pts. It is OK to
      * do so since Dirac is a constant frame rate codec. It expects input
      * to be of constant frame rate. */
     pkt->pts =
-    avccontext->coded_frame->pts = p_frame_output->frame_num;
+    avctx->coded_frame->pts = p_frame_output->frame_num;
     pkt->dts = p_schro_params->dts++;
     enc_size = p_frame_output->size;
 
@@ -416,9 +414,9 @@ error:
 }
 
 
-static int libschroedinger_encode_close(AVCodecContext *avccontext)
+static int libschroedinger_encode_close(AVCodecContext *avctx)
 {
-    SchroEncoderParams *p_schro_params = avccontext->priv_data;
+    SchroEncoderParams *p_schro_params = avctx->priv_data;
 
     /* Close the encoder. */
     schro_encoder_free(p_schro_params->encoder);
@@ -435,12 +433,15 @@ static int libschroedinger_encode_close(AVCodecContext *avccontext)
     /* Free the video format structure. */
     av_freep(&p_schro_params->format);
 
+    av_frame_free(&avctx->coded_frame);
+
     return 0;
 }
 
 
 AVCodec ff_libschroedinger_encoder = {
     .name           = "libschroedinger",
+    .long_name      = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DIRAC,
     .priv_data_size = sizeof(SchroEncoderParams),
@@ -451,5 +452,4 @@ AVCodec ff_libschroedinger_encoder = {
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
 };
diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c
index 8aa82ca..d00696e 100644
--- a/libavcodec/libspeexdec.c
+++ b/libavcodec/libspeexdec.c
@@ -29,7 +29,6 @@
 #include "internal.h"
 
 typedef struct {
-    AVFrame frame;
     SpeexBits bits;
     SpeexStereoState stereo;
     void *dec_state;
@@ -102,9 +101,6 @@ static av_cold int libspeex_decode_init(AVCodecContext *avctx)
         speex_decoder_ctl(s->dec_state, SPEEX_SET_HANDLER, &callback);
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -114,23 +110,24 @@ static int libspeex_decode_frame(AVCodecContext *avctx, void *data,
     uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LibSpeexContext *s = avctx->priv_data;
+    AVFrame *frame     = data;
     int16_t *output;
     int ret, consumed = 0;
 
     /* get output buffer */
-    s->frame.nb_samples = s->frame_size;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->frame_size;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output = (int16_t *)s->frame.data[0];
+    output = (int16_t *)frame->data[0];
 
     /* if there is not enough data left for the smallest possible frame or the
        next 5 bits are a terminator code, reset the libspeex buffer using the
        current packet, otherwise ignore the current packet and keep decoding
        frames from the libspeex buffer. */
     if (speex_bits_remaining(&s->bits) < 5 ||
-        speex_bits_peek_unsigned(&s->bits, 5) == 0x1F) {
+        speex_bits_peek_unsigned(&s->bits, 5) == 0xF) {
         /* check for flush packet */
         if (!buf || !buf_size) {
             *got_frame_ptr = 0;
@@ -150,8 +147,7 @@ static int libspeex_decode_frame(AVCodecContext *avctx, void *data,
     if (avctx->channels == 2)
         speex_decode_stereo_int(output, s->frame_size, &s->stereo);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return consumed;
 }
@@ -174,6 +170,7 @@ static av_cold void libspeex_decode_flush(AVCodecContext *avctx)
 
 AVCodec ff_libspeex_decoder = {
     .name           = "libspeex",
+    .long_name      = NULL_IF_CONFIG_SMALL("libspeex Speex"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_SPEEX,
     .priv_data_size = sizeof(LibSpeexContext),
@@ -182,5 +179,4 @@ AVCodec ff_libspeex_decoder = {
     .decode         = libspeex_decode_frame,
     .flush          = libspeex_decode_flush,
     .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("libspeex Speex"),
 };
diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c
index 4277e62..651d7ac 100644
--- a/libavcodec/libspeexenc.c
+++ b/libavcodec/libspeexenc.c
@@ -251,16 +251,6 @@ static av_cold int encode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_ERROR, "memory allocation error\n");
         return AVERROR(ENOMEM);
     }
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        av_freep(&avctx->extradata);
-        speex_header_free(header_data);
-        speex_encoder_destroy(s->enc_state);
-        av_log(avctx, AV_LOG_ERROR, "memory allocation error\n");
-        return AVERROR(ENOMEM);
-    }
-#endif
 
     /* copy header packet to extradata */
     memcpy(avctx->extradata, header_data, header_size);
@@ -329,9 +319,6 @@ static av_cold int encode_close(AVCodecContext *avctx)
     speex_encoder_destroy(s->enc_state);
 
     ff_af_queue_close(&s->afq);
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     av_freep(&avctx->extradata);
 
     return 0;
@@ -363,6 +350,7 @@ static const AVCodecDefault defaults[] = {
 
 AVCodec ff_libspeex_encoder = {
     .name           = "libspeex",
+    .long_name      = NULL_IF_CONFIG_SMALL("libspeex Speex"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_SPEEX,
     .priv_data_size = sizeof(LibSpeexEncContext),
@@ -376,7 +364,6 @@ AVCodec ff_libspeex_encoder = {
                                            AV_CH_LAYOUT_STEREO,
                                            0 },
     .supported_samplerates = (const int[]){ 8000, 16000, 32000, 0 },
-    .long_name      = NULL_IF_CONFIG_SMALL("libspeex Speex"),
     .priv_class     = &class,
     .defaults       = defaults,
 };
diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index f20fabb..75b0a16 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -58,8 +58,8 @@ static int concatenate_packet(unsigned int* offset,
                               const ogg_packet* packet)
 {
     const char* message = NULL;
-    uint8_t* newdata    = NULL;
     int newsize = avc_context->extradata_size + 2 + packet->bytes;
+    int err = AVERROR_INVALIDDATA;
 
     if (packet->bytes < 0) {
         message = "ogg_packet has negative size";
@@ -68,16 +68,16 @@ static int concatenate_packet(unsigned int* offset,
     } else if (newsize < avc_context->extradata_size) {
         message = "extradata_size would overflow";
     } else {
-        newdata = av_realloc(avc_context->extradata, newsize);
-        if (!newdata)
+        if ((err = av_reallocp(&avc_context->extradata, newsize)) < 0) {
+            avc_context->extradata_size = 0;
             message = "av_realloc failed";
+        }
     }
     if (message) {
         av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message);
-        return -1;
+        return err;
     }
 
-    avc_context->extradata      = newdata;
     avc_context->extradata_size = newsize;
     AV_WB16(avc_context->extradata + (*offset), packet->bytes);
     *offset += 2;
@@ -207,7 +207,7 @@ static av_cold int encode_init(AVCodecContext* avc_context)
                 * 0 <= p <=63
                 * an int value
          */
-        t_info.quality        = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
+        t_info.quality        = av_clipf(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
         t_info.target_bitrate = 0;
     } else {
         t_info.target_bitrate = avc_context->bit_rate;
@@ -259,7 +259,7 @@ static av_cold int encode_init(AVCodecContext* avc_context)
     th_comment_clear(&t_comment);
 
     /* Set up the output AVFrame */
-    avc_context->coded_frame= avcodec_alloc_frame();
+    avc_context->coded_frame = av_frame_alloc();
 
     return 0;
 }
@@ -365,6 +365,7 @@ static av_cold int encode_close(AVCodecContext* avc_context)
 /** AVCodec struct exposed to libavcodec */
 AVCodec ff_libtheora_encoder = {
     .name           = "libtheora",
+    .long_name      = NULL_IF_CONFIG_SMALL("libtheora Theora"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_THEORA,
     .priv_data_size = sizeof(TheoraContext),
@@ -375,5 +376,4 @@ AVCodec ff_libtheora_encoder = {
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("libtheora Theora"),
 };
diff --git a/libavcodec/libvo-aacenc.c b/libavcodec/libvo-aacenc.c
index 31822b5..9450792 100644
--- a/libavcodec/libvo-aacenc.c
+++ b/libavcodec/libvo-aacenc.c
@@ -47,9 +47,6 @@ static int aac_encode_close(AVCodecContext *avctx)
     AACContext *s = avctx->priv_data;
 
     s->codec_api.Uninit(s->handle);
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     av_freep(&avctx->extradata);
     ff_af_queue_close(&s->afq);
     av_freep(&s->end_buffer);
@@ -63,11 +60,6 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
     AACENC_PARAM params = { 0 };
     int index, ret;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-#endif
     avctx->frame_size = FRAME_SIZE;
     avctx->delay      = ENC_DELAY;
     s->last_frame     = 2;
@@ -189,6 +181,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_libvo_aacenc_encoder = {
     .name           = "libvo_aacenc",
+    .long_name      = NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AAC,
     .priv_data_size = sizeof(AACContext),
@@ -198,5 +191,4 @@ AVCodec ff_libvo_aacenc_encoder = {
     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"),
 };
diff --git a/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c
index 6502456..b255ba5 100644
--- a/libavcodec/libvo-amrwbenc.c
+++ b/libavcodec/libvo-amrwbenc.c
@@ -94,11 +94,6 @@ static av_cold int amr_wb_encode_init(AVCodecContext *avctx)
 
     avctx->frame_size  = 320;
     avctx->delay       =  80;
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-#endif
 
     s->state     = E_IF_init();
 
@@ -110,7 +105,6 @@ static int amr_wb_encode_close(AVCodecContext *avctx)
     AMRWBContext *s = avctx->priv_data;
 
     E_IF_exit(s->state);
-    av_freep(&avctx->coded_frame);
     return 0;
 }
 
@@ -146,6 +140,8 @@ static int amr_wb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_libvo_amrwbenc_encoder = {
     .name           = "libvo_amrwbenc",
+    .long_name      = NULL_IF_CONFIG_SMALL("Android VisualOn AMR-WB "
+                                           "(Adaptive Multi-Rate Wide-Band)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_AMR_WB,
     .priv_data_size = sizeof(AMRWBContext),
@@ -154,7 +150,5 @@ AVCodec ff_libvo_amrwbenc_encoder = {
     .close          = amr_wb_encode_close,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Android VisualOn AMR-WB "
-                                           "(Adaptive Multi-Rate Wide-Band)"),
     .priv_class     = &class,
 };
diff --git a/libavcodec/libvorbis.c b/libavcodec/libvorbis.c
index 092cbbc..a635db3 100644
--- a/libavcodec/libvorbis.c
+++ b/libavcodec/libvorbis.c
@@ -162,9 +162,6 @@ static av_cold int oggvorbis_encode_close(AVCodecContext *avctx)
 
     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;
@@ -241,14 +238,6 @@ static av_cold int oggvorbis_encode_init(AVCodecContext *avctx)
         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);
@@ -348,6 +337,7 @@ static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_libvorbis_encoder = {
     .name           = "libvorbis",
+    .long_name      = NULL_IF_CONFIG_SMALL("libvorbis Vorbis"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_VORBIS,
     .priv_data_size = sizeof(OggVorbisContext),
@@ -357,7 +347,6 @@ AVCodec ff_libvorbis_encoder = {
     .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/libvpx.c b/libavcodec/libvpx.c
new file mode 100644
index 0000000..20f4484
--- /dev/null
+++ b/libavcodec/libvpx.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013 Guillaume Martres <smarter at ubuntu.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 <vpx/vpx_codec.h>
+
+#include "libvpx.h"
+
+int ff_vp9_check_experimental(AVCodecContext *avctx)
+{
+    if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL &&
+        (vpx_codec_version_major() < 1 ||
+         (vpx_codec_version_major() == 1 && vpx_codec_version_minor() < 3))) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Non-experimental support of VP9 requires libvpx >= 1.3.0\n");
+        return AVERROR_EXPERIMENTAL;
+    }
+    return 0;
+}
diff --git a/libavcodec/libvpx.h b/libavcodec/libvpx.h
new file mode 100644
index 0000000..cb1ed09
--- /dev/null
+++ b/libavcodec/libvpx.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Guillaume Martres <smarter at ubuntu.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_LIBVPX_H
+#define AVCODEC_LIBVPX_H
+
+#include "avcodec.h"
+
+int ff_vp9_check_experimental(AVCodecContext *avctx);
+
+#endif /* AVCODEC_LIBVPX_H */
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 6419e28..6052207 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -30,15 +30,17 @@
 #include "libavutil/common.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
+#include "internal.h"
+#include "libvpx.h"
 
 typedef struct VP8DecoderContext {
     struct vpx_codec_ctx decoder;
 } VP8Context;
 
-static av_cold int vp8_init(AVCodecContext *avctx)
+static av_cold int vpx_init(AVCodecContext *avctx,
+                            const struct vpx_codec_iface *iface)
 {
     VP8Context *ctx = avctx->priv_data;
-    const struct vpx_codec_iface *iface = &vpx_codec_vp8_dx_algo;
     struct vpx_codec_dec_cfg deccfg = {
         /* token partitions+1 would be a decent choice */
         .threads = FFMIN(avctx->thread_count, 16)
@@ -65,6 +67,7 @@ static int vp8_decode(AVCodecContext *avctx,
     AVFrame *picture = data;
     const void *iter = NULL;
     struct vpx_image *img;
+    int ret;
 
     if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) !=
         VPX_CODEC_OK) {
@@ -88,18 +91,14 @@ static int vp8_decode(AVCodecContext *avctx,
         if ((int) img->d_w != avctx->width || (int) img->d_h != avctx->height) {
             av_log(avctx, AV_LOG_INFO, "dimension change! %dx%d -> %dx%d\n",
                    avctx->width, avctx->height, img->d_w, img->d_h);
-            if (av_image_check_size(img->d_w, img->d_h, 0, avctx))
-                return AVERROR_INVALIDDATA;
-            avcodec_set_dimensions(avctx, img->d_w, img->d_h);
+            ret = ff_set_dimensions(avctx, img->d_w, img->d_h);
+            if (ret < 0)
+                return ret;
         }
-        picture->data[0]     = img->planes[0];
-        picture->data[1]     = img->planes[1];
-        picture->data[2]     = img->planes[2];
-        picture->data[3]     = NULL;
-        picture->linesize[0] = img->stride[0];
-        picture->linesize[1] = img->stride[1];
-        picture->linesize[2] = img->stride[2];
-        picture->linesize[3] = 0;
+        if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
+            return ret;
+        av_image_copy(picture->data, picture->linesize, img->planes,
+                      img->stride, avctx->pix_fmt, img->d_w, img->d_h);
         *got_frame           = 1;
     }
     return avpkt->size;
@@ -112,14 +111,43 @@ static av_cold int vp8_free(AVCodecContext *avctx)
     return 0;
 }
 
-AVCodec ff_libvpx_decoder = {
+#if CONFIG_LIBVPX_VP8_DECODER
+static av_cold int vp8_init(AVCodecContext *avctx)
+{
+    return vpx_init(avctx, &vpx_codec_vp8_dx_algo);
+}
+
+AVCodec ff_libvpx_vp8_decoder = {
     .name           = "libvpx",
+    .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP8"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VP8,
     .priv_data_size = sizeof(VP8Context),
     .init           = vp8_init,
     .close          = vp8_free,
     .decode         = vp8_decode,
+    .capabilities   = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1,
+};
+#endif /* CONFIG_LIBVPX_VP8_DECODER */
+
+#if CONFIG_LIBVPX_VP9_DECODER
+static av_cold int vp9_init(AVCodecContext *avctx)
+{
+    int ret;
+    if ((ret = ff_vp9_check_experimental(avctx)))
+        return ret;
+    return vpx_init(avctx, &vpx_codec_vp9_dx_algo);
+}
+
+AVCodec ff_libvpx_vp9_decoder = {
+    .name           = "libvpx-vp9",
+    .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP9"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VP9,
+    .priv_data_size = sizeof(VP8Context),
+    .init           = vp9_init,
+    .close          = vp8_free,
+    .decode         = vp8_decode,
     .capabilities   = CODEC_CAP_AUTO_THREADS,
-    .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP8"),
 };
+#endif /* CONFIG_LIBVPX_VP9_DECODER */
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index 17b9800..dc1ddc3 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -30,6 +30,7 @@
 
 #include "avcodec.h"
 #include "internal.h"
+#include "libvpx.h"
 #include "libavutil/base64.h"
 #include "libavutil/common.h"
 #include "libavutil/mathematics.h"
@@ -214,10 +215,10 @@ static av_cold int vp8_free(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int vp8_init(AVCodecContext *avctx)
+static av_cold int vpx_init(AVCodecContext *avctx,
+                            const struct vpx_codec_iface *iface)
 {
     VP8Context *ctx = avctx->priv_data;
-    const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo;
     struct vpx_codec_enc_cfg enccfg;
     int res;
 
@@ -353,7 +354,7 @@ static av_cold int vp8_init(AVCodecContext *avctx)
     vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
                  (unsigned char*)1);
 
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame) {
         av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
         vp8_free(avctx);
@@ -467,11 +468,13 @@ static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out,
             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);
-            if (!stats->buf) {
+            int err;
+            if ((err = av_reallocp(&stats->buf,
+                                   stats->sz +
+                                   pkt->data.twopass_stats.sz)) < 0) {
+                stats->sz = 0;
                 av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
-                return AVERROR(ENOMEM);
+                return err;
             }
             memcpy((uint8_t*)stats->buf + stats->sz,
                    pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
@@ -565,13 +568,6 @@ static const AVOption options[] = {
     { NULL }
 };
 
-static const AVClass class = {
-    .class_name = "libvpx encoder",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
-
 static const AVCodecDefault defaults[] = {
     { "qmin",             "-1" },
     { "qmax",             "-1" },
@@ -580,8 +576,22 @@ static const AVCodecDefault defaults[] = {
     { NULL },
 };
 
-AVCodec ff_libvpx_encoder = {
+#if CONFIG_LIBVPX_VP8_ENCODER
+static av_cold int vp8_init(AVCodecContext *avctx)
+{
+    return vpx_init(avctx, &vpx_codec_vp8_cx_algo);
+}
+
+static const AVClass class_vp8 = {
+    .class_name = "libvpx encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_libvpx_vp8_encoder = {
     .name           = "libvpx",
+    .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP8"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VP8,
     .priv_data_size = sizeof(VP8Context),
@@ -590,7 +600,39 @@ AVCodec ff_libvpx_encoder = {
     .close          = vp8_free,
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP8"),
-    .priv_class     = &class,
+    .priv_class     = &class_vp8,
+    .defaults       = defaults,
+};
+#endif /* CONFIG_LIBVPX_VP8_ENCODER */
+
+#if CONFIG_LIBVPX_VP9_ENCODER
+static av_cold int vp9_init(AVCodecContext *avctx)
+{
+    int ret;
+    if ((ret = ff_vp9_check_experimental(avctx)))
+        return ret;
+    return vpx_init(avctx, &vpx_codec_vp9_cx_algo);
+}
+
+static const AVClass class_vp9 = {
+    .class_name = "libvpx encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_libvpx_vp9_encoder = {
+    .name           = "libvpx-vp9",
+    .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP9"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VP9,
+    .priv_data_size = sizeof(VP8Context),
+    .init           = vp9_init,
+    .encode2        = vp8_encode,
+    .close          = vp8_free,
+    .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
+    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+    .priv_class     = &class_vp9,
     .defaults       = defaults,
 };
+#endif /* CONFIG_LIBVPX_VP9_ENCODER */
diff --git a/libavcodec/libwavpackenc.c b/libavcodec/libwavpackenc.c
new file mode 100644
index 0000000..34ec013
--- /dev/null
+++ b/libavcodec/libwavpackenc.c
@@ -0,0 +1,194 @@
+/*
+ * 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 <wavpack/wavpack.h>
+#include <string.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+#include "audio_frame_queue.h"
+#include "avcodec.h"
+#include "internal.h"
+
+#define WV_DEFAULT_BLOCK_SIZE 32768
+
+typedef struct LibWavpackContext {
+    const AVClass *class;
+    WavpackContext *wv;
+    AudioFrameQueue afq;
+
+    AVPacket *pkt;
+    int user_size;
+
+    int got_output;
+} LibWavpackContext;
+
+static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                                const AVFrame *frame, int *got_output)
+{
+    LibWavpackContext *s = avctx->priv_data;
+    int ret;
+
+    s->got_output = 0;
+    s->pkt        = pkt;
+    s->user_size  = pkt->size;
+
+    if (frame) {
+        ret = ff_af_queue_add(&s->afq, frame);
+        if (ret < 0)
+            return ret;
+
+        ret = WavpackPackSamples(s->wv, (int32_t*)frame->data[0], frame->nb_samples);
+        if (!ret) {
+            av_log(avctx, AV_LOG_ERROR, "Error encoding a frame: %s\n",
+                   WavpackGetErrorMessage(s->wv));
+            return AVERROR_UNKNOWN;
+        }
+    }
+
+    if (!s->got_output &&
+        (!frame || frame->nb_samples < avctx->frame_size)) {
+        ret = WavpackFlushSamples(s->wv);
+        if (!ret) {
+            av_log(avctx, AV_LOG_ERROR, "Error flushing the encoder: %s\n",
+                   WavpackGetErrorMessage(s->wv));
+            return AVERROR_UNKNOWN;
+        }
+    }
+
+    if (s->got_output) {
+        ff_af_queue_remove(&s->afq, avctx->frame_size, &pkt->pts, &pkt->duration);
+        *got_output = 1;
+    }
+
+    return 0;
+}
+
+static int encode_callback(void *id, void *data, int32_t count)
+{
+    AVCodecContext *avctx = id;
+    LibWavpackContext *s  = avctx->priv_data;
+    int ret, offset = s->pkt->size;
+
+    if (s->user_size) {
+        if (s->user_size - count < s->pkt->size) {
+            av_log(avctx, AV_LOG_ERROR, "Provided packet too small.\n");
+            return 0;
+        }
+        s->pkt->size += count;
+    } else {
+        ret = av_grow_packet(s->pkt, count);
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Error allocating output packet.\n");
+            return 0;
+        }
+    }
+
+    memcpy(s->pkt->data + offset, data, count);
+
+    s->got_output = 1;
+
+    return 1;
+}
+
+static av_cold int wavpack_encode_init(AVCodecContext *avctx)
+{
+    LibWavpackContext *s = avctx->priv_data;
+    WavpackConfig config = { 0 };
+    int ret;
+
+    s->wv = WavpackOpenFileOutput(encode_callback, avctx, NULL);
+    if (!s->wv) {
+        av_log(avctx, AV_LOG_ERROR, "Error allocating the encoder.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    if (!avctx->frame_size)
+        avctx->frame_size = WV_DEFAULT_BLOCK_SIZE;
+
+    config.bytes_per_sample = 4;
+    config.bits_per_sample  = 32;
+    config.block_samples    = avctx->frame_size;
+    config.channel_mask     = avctx->channel_layout;
+    config.num_channels     = avctx->channels;
+    config.sample_rate      = avctx->sample_rate;
+
+    if (avctx->compression_level != FF_COMPRESSION_DEFAULT) {
+        if (avctx->compression_level >= 3) {
+            config.flags |= CONFIG_VERY_HIGH_FLAG;
+
+            if      (avctx->compression_level >= 8)
+                config.xmode = 6;
+            else if (avctx->compression_level >= 7)
+                config.xmode = 5;
+            else if (avctx->compression_level >= 6)
+                config.xmode = 4;
+            else if (avctx->compression_level >= 5)
+                config.xmode = 3;
+            else if (avctx->compression_level >= 4)
+                config.xmode = 2;
+        } else if (avctx->compression_level >= 2)
+            config.flags |= CONFIG_HIGH_FLAG;
+        else if (avctx->compression_level < 1)
+            config.flags |= CONFIG_FAST_FLAG;
+    }
+
+    ret = WavpackSetConfiguration(s->wv, &config, -1);
+    if (!ret)
+        goto fail;
+
+    ret = WavpackPackInit(s->wv);
+    if (!ret)
+        goto fail;
+
+    ff_af_queue_init(avctx, &s->afq);
+
+    return 0;
+
+fail:
+    av_log(avctx, AV_LOG_ERROR, "Error configuring the encoder: %s.\n",
+           WavpackGetErrorMessage(s->wv));
+    WavpackCloseFile(s->wv);
+    return AVERROR_UNKNOWN;
+}
+
+static av_cold int wavpack_encode_close(AVCodecContext *avctx)
+{
+    LibWavpackContext *s = avctx->priv_data;
+
+    WavpackCloseFile(s->wv);
+
+    ff_af_queue_close(&s->afq);
+
+    return 0;
+}
+
+AVCodec ff_libwavpack_encoder = {
+    .name           = "libwavpack",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_WAVPACK,
+    .priv_data_size = sizeof(LibWavpackContext),
+    .init           = wavpack_encode_init,
+    .encode2        = wavpack_encode_frame,
+    .close          = wavpack_encode_close,
+    .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME,
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
+                                                     AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index e9cbbad..abf0a3e 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -23,8 +23,14 @@
 #include "libavutil/opt.h"
 #include "libavutil/mem.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/stereo3d.h"
 #include "avcodec.h"
 #include "internal.h"
+
+#if defined(_MSC_VER)
+#define X264_API_IMPORTS 1
+#endif
+
 #include <x264.h>
 #include <float.h>
 #include <math.h>
@@ -39,7 +45,6 @@ typedef struct X264Context {
     x264_picture_t  pic;
     uint8_t        *sei;
     int             sei_size;
-    AVFrame         out_pic;
     char *preset;
     char *tune;
     char *profile;
@@ -56,6 +61,7 @@ typedef struct X264Context {
     int weightb;
     int ssim;
     int intra_refresh;
+    int bluray_compat;
     int b_bias;
     int b_pyramid;
     int mixed_refs;
@@ -70,6 +76,7 @@ typedef struct X264Context {
     int slice_max_size;
     char *stats;
     int nal_hrd;
+    char *x264_params;
 } X264Context;
 
 static void X264_log(void *p, int level, const char *fmt, va_list args)
@@ -128,6 +135,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
     x264_nal_t *nal;
     int nnal, i, ret;
     x264_picture_t pic_out;
+    AVFrameSideData *side_data;
 
     x264_picture_init( &x4->pic );
     x4->pic.img.i_csp   = x4->params.i_csp;
@@ -157,8 +165,42 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
             x4->params.vui.i_sar_width  = ctx->sample_aspect_ratio.num;
             x264_encoder_reconfig(x4->enc, &x4->params);
         }
-    }
 
+        side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_STEREO3D);
+        if (side_data) {
+            AVStereo3D *stereo = (AVStereo3D *)side_data->data;
+            int fpa_type;
+
+            switch (stereo->type) {
+            case AV_STEREO3D_CHECKERBOARD:
+                fpa_type = 0;
+                break;
+            case AV_STEREO3D_LINES:
+                fpa_type = 1;
+                break;
+            case AV_STEREO3D_COLUMNS:
+                fpa_type = 2;
+                break;
+            case AV_STEREO3D_SIDEBYSIDE:
+                fpa_type = 3;
+                break;
+            case AV_STEREO3D_TOPBOTTOM:
+                fpa_type = 4;
+                break;
+            case AV_STEREO3D_FRAMESEQUENCE:
+                fpa_type = 5;
+                break;
+            default:
+                fpa_type = -1;
+                break;
+            }
+
+            if (fpa_type != x4->params.i_frame_packing) {
+                x4->params.i_frame_packing = fpa_type;
+                x264_encoder_reconfig(x4->enc, &x4->params);
+            }
+        }
+    }
     do {
         if (x264_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0)
             return -1;
@@ -174,20 +216,20 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
     switch (pic_out.i_type) {
     case X264_TYPE_IDR:
     case X264_TYPE_I:
-        x4->out_pic.pict_type = AV_PICTURE_TYPE_I;
+        ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
         break;
     case X264_TYPE_P:
-        x4->out_pic.pict_type = AV_PICTURE_TYPE_P;
+        ctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
         break;
     case X264_TYPE_B:
     case X264_TYPE_BREF:
-        x4->out_pic.pict_type = AV_PICTURE_TYPE_B;
+        ctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
         break;
     }
 
     pkt->flags |= AV_PKT_FLAG_KEY*pic_out.b_keyframe;
     if (ret)
-        x4->out_pic.quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
+        ctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
 
     *got_packet = ret;
     return 0;
@@ -203,6 +245,8 @@ static av_cold int X264_close(AVCodecContext *avctx)
     if (x4->enc)
         x264_encoder_close(x4->enc);
 
+    av_frame_free(&avctx->coded_frame);
+
     return 0;
 }
 
@@ -218,6 +262,9 @@ static int convert_pix_fmt(enum AVPixelFormat pix_fmt)
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUV444P9:
     case AV_PIX_FMT_YUV444P10: return X264_CSP_I444;
+    case AV_PIX_FMT_NV12:      return X264_CSP_NV12;
+    case AV_PIX_FMT_NV16:
+    case AV_PIX_FMT_NV20:      return X264_CSP_NV16;
     };
     return 0;
 }
@@ -278,7 +325,8 @@ static av_cold int X264_init(AVCodecContext *avctx)
             (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size;
     }
 
-    x4->params.rc.f_ip_factor             = 1 / fabs(avctx->i_quant_factor);
+    if (avctx->i_quant_factor > 0)
+        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;
 
@@ -351,6 +399,10 @@ static av_cold int X264_init(AVCodecContext *avctx)
         x4->params.analyse.b_ssim = x4->ssim;
     if (x4->intra_refresh >= 0)
         x4->params.b_intra_refresh = x4->intra_refresh;
+    if (x4->bluray_compat >= 0) {
+        x4->params.b_bluray_compat = x4->bluray_compat;
+        x4->params.b_vfr_input = 0;
+    }
     if (x4->b_bias != INT_MIN)
         x4->params.i_bframe_bias              = x4->b_bias;
     if (x4->b_pyramid >= 0)
@@ -407,6 +459,22 @@ static av_cold int X264_init(AVCodecContext *avctx)
     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER)
         x4->params.b_repeat_headers = 0;
 
+    if (x4->x264_params) {
+        AVDictionary *dict    = NULL;
+        AVDictionaryEntry *en = NULL;
+
+        if (!av_dict_parse_string(&dict, x4->x264_params, "=", ":", 0)) {
+            while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) {
+                if (x264_param_parse(&x4->params, en->key, en->value) < 0)
+                    av_log(avctx, AV_LOG_WARNING,
+                           "Error parsing option '%s = %s'.\n",
+                            en->key, en->value);
+            }
+
+            av_dict_free(&dict);
+        }
+    }
+
     // update AVCodecContext with x264 parameters
     avctx->has_b_frames = x4->params.i_bframe ?
         x4->params.i_bframe_pyramid ? 2 : 1 : 0;
@@ -419,7 +487,9 @@ static av_cold int X264_init(AVCodecContext *avctx)
     if (!x4->enc)
         return -1;
 
-    avctx->coded_frame = &x4->out_pic;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
 
     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
         x264_nal_t *nal;
@@ -452,6 +522,8 @@ static const enum AVPixelFormat pix_fmts_8bit[] = {
     AV_PIX_FMT_YUVJ420P,
     AV_PIX_FMT_YUV422P,
     AV_PIX_FMT_YUV444P,
+    AV_PIX_FMT_NV12,
+    AV_PIX_FMT_NV16,
     AV_PIX_FMT_NONE
 };
 static const enum AVPixelFormat pix_fmts_9bit[] = {
@@ -463,6 +535,7 @@ static const enum AVPixelFormat pix_fmts_10bit[] = {
     AV_PIX_FMT_YUV420P10,
     AV_PIX_FMT_YUV422P10,
     AV_PIX_FMT_YUV444P10,
+    AV_PIX_FMT_NV20,
     AV_PIX_FMT_NONE
 };
 
@@ -501,6 +574,7 @@ static const AVOption options[] = {
     { "smart",         NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_WEIGHTP_SMART},  INT_MIN, INT_MAX, VE, "weightp" },
     { "ssim",          "Calculate and print SSIM stats.",                 OFFSET(ssim),          AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
     { "intra-refresh", "Use Periodic Intra Refresh instead of IDR frames.",OFFSET(intra_refresh),AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
+    { "bluray-compat", "Bluray compatibility workarounds.",               OFFSET(bluray_compat) ,AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, 1, VE },
     { "b-bias",        "Influences how often B-frames are used",          OFFSET(b_bias),        AV_OPT_TYPE_INT,    { .i64 = INT_MIN}, INT_MIN, INT_MAX, VE },
     { "b-pyramid",     "Keep some B-frames as references.",               OFFSET(b_pyramid),     AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE, "b_pyramid" },
     { "none",          NULL,                                  0, AV_OPT_TYPE_CONST, {.i64 = X264_B_PYRAMID_NONE},   INT_MIN, INT_MAX, VE, "b_pyramid" },
@@ -527,6 +601,7 @@ static const AVOption options[] = {
     { "none",          NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_NONE}, INT_MIN, INT_MAX, VE, "nal-hrd" },
     { "vbr",           NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_VBR},  INT_MIN, INT_MAX, VE, "nal-hrd" },
     { "cbr",           NULL, 0, AV_OPT_TYPE_CONST, {.i64 = X264_NAL_HRD_CBR},  INT_MIN, INT_MAX, VE, "nal-hrd" },
+    { "x264-params",  "Override the x264 configuration using a :-separated list of key=value parameters", OFFSET(x264_params), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
     { NULL },
 };
 
@@ -541,6 +616,7 @@ static const AVCodecDefault x264_defaults[] = {
     { "b",                "0" },
     { "bf",               "-1" },
     { "g",                "-1" },
+    { "i_qfactor",        "-1" },
     { "qmin",             "-1" },
     { "qmax",             "-1" },
     { "qdiff",            "-1" },
@@ -566,6 +642,7 @@ static const AVCodecDefault x264_defaults[] = {
 
 AVCodec ff_libx264_encoder = {
     .name             = "libx264",
+    .long_name        = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
     .type             = AVMEDIA_TYPE_VIDEO,
     .id               = AV_CODEC_ID_H264,
     .priv_data_size   = sizeof(X264Context),
@@ -573,7 +650,6 @@ AVCodec ff_libx264_encoder = {
     .encode2          = X264_frame,
     .close            = X264_close,
     .capabilities     = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
-    .long_name        = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
     .priv_class       = &class,
     .defaults         = x264_defaults,
     .init_static_data = X264_init_static,
diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
index 16026ac..7a74e36 100644
--- a/libavcodec/libxavs.c
+++ b/libavcodec/libxavs.c
@@ -45,7 +45,6 @@ typedef struct XavsContext {
     xavs_picture_t  pic;
     uint8_t        *sei;
     int             sei_size;
-    AVFrame         out_pic;
     int             end_of_stream;
     float crf;
     int cqp;
@@ -113,10 +112,10 @@ static int encode_nals(AVCodecContext *ctx, AVPacket *pkt,
     return 1;
 }
 
-static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt,
+static int XAVS_frame(AVCodecContext *avctx, AVPacket *pkt,
                       const AVFrame *frame, int *got_packet)
 {
-    XavsContext *x4 = ctx->priv_data;
+    XavsContext *x4 = avctx->priv_data;
     xavs_nal_t *nal;
     int nnal, i, ret;
     xavs_picture_t pic_out;
@@ -132,14 +131,14 @@ static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt,
 
         x4->pic.i_pts  = frame->pts;
         x4->pic.i_type = XAVS_TYPE_AUTO;
-        x4->pts_buffer[ctx->frame_number % (ctx->max_b_frames+1)] = frame->pts;
+        x4->pts_buffer[avctx->frame_number % (avctx->max_b_frames+1)] = frame->pts;
     }
 
     if (xavs_encoder_encode(x4->enc, &nal, &nnal,
                             frame? &x4->pic: NULL, &pic_out) < 0)
     return -1;
 
-    ret = encode_nals(ctx, pkt, nal, nnal);
+    ret = encode_nals(avctx, pkt, nal, nnal);
 
     if (ret < 0)
         return -1;
@@ -153,46 +152,46 @@ static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt,
             pkt->data[1] = 0x0;
             pkt->data[2] = 0x01;
             pkt->data[3] = 0xb1;
-            pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)] -
-                       x4->pts_buffer[(x4->out_frame_count-2)%(ctx->max_b_frames+1)];
+            pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(avctx->max_b_frames+1)] -
+                       x4->pts_buffer[(x4->out_frame_count-2)%(avctx->max_b_frames+1)];
             x4->end_of_stream = END_OF_STREAM;
             *got_packet = 1;
         }
         return 0;
     }
 
-    x4->out_pic.pts = pic_out.i_pts;
+    avctx->coded_frame->pts = pic_out.i_pts;
     pkt->pts = pic_out.i_pts;
-    if (ctx->has_b_frames) {
+    if (avctx->has_b_frames) {
         if (!x4->out_frame_count)
             pkt->dts = pkt->pts - (x4->pts_buffer[1] - x4->pts_buffer[0]);
         else
-            pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)];
+            pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(avctx->max_b_frames+1)];
     } else
         pkt->dts = pkt->pts;
 
     switch (pic_out.i_type) {
     case XAVS_TYPE_IDR:
     case XAVS_TYPE_I:
-        x4->out_pic.pict_type = AV_PICTURE_TYPE_I;
+        avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
         break;
     case XAVS_TYPE_P:
-        x4->out_pic.pict_type = AV_PICTURE_TYPE_P;
+        avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
         break;
     case XAVS_TYPE_B:
     case XAVS_TYPE_BREF:
-        x4->out_pic.pict_type = AV_PICTURE_TYPE_B;
+        avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B;
         break;
     }
 
     /* There is no IDR frame in AVS JiZhun */
     /* Sequence header is used as a flag */
     if (pic_out.i_type == XAVS_TYPE_I) {
-        x4->out_pic.key_frame = 1;
+        avctx->coded_frame->key_frame = 1;
         pkt->flags |= AV_PKT_FLAG_KEY;
     }
 
-    x4->out_pic.quality   = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
+    avctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
 
     x4->out_frame_count++;
     *got_packet = ret;
@@ -210,6 +209,8 @@ static av_cold int XAVS_close(AVCodecContext *avctx)
     if (x4->enc)
         xavs_encoder_close(x4->enc);
 
+    av_frame_free(&avctx->coded_frame);
+
     return 0;
 }
 
@@ -357,7 +358,10 @@ static av_cold int XAVS_init(AVCodecContext *avctx)
     if (!(x4->pts_buffer = av_mallocz((avctx->max_b_frames+1) * sizeof(*x4->pts_buffer))))
         return AVERROR(ENOMEM);
 
-    avctx->coded_frame = &x4->out_pic;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
     /* TAG: Do we have GLOBAL HEADER in AVS */
     /* We Have PPS and SPS in AVS */
     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
@@ -420,6 +424,7 @@ static const AVCodecDefault xavs_defaults[] = {
 
 AVCodec ff_libxavs_encoder = {
     .name           = "libxavs",
+    .long_name      = NULL_IF_CONFIG_SMALL("libxavs Chinese AVS (Audio Video Standard)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CAVS,
     .priv_data_size = sizeof(XavsContext),
@@ -428,7 +433,6 @@ AVCodec ff_libxavs_encoder = {
     .close          = XAVS_close,
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("libxavs Chinese AVS (Audio Video Standard)"),
     .priv_class     = &class,
     .defaults       = xavs_defaults,
 };
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index dd1e3e3..fe68c8e 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -54,7 +54,6 @@ struct xvid_context {
     int me_flags;                  /**< Motion Estimation flags */
     int qscale;                    /**< Do we use constant scale? */
     int quicktime_format;          /**< Are we in a QT-based format? */
-    AVFrame encoded_picture;       /**< Encoded frame information */
     char *twopassbuffer;           /**< Character buffer for two-pass */
     char *old_twopassbuffer;       /**< Old character buffer (two-pass) */
     char *twopassfile;             /**< second pass temp file name */
@@ -606,7 +605,9 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx)  {
     }
 
     x->encoder_handle = xvid_enc_create.handle;
-    avctx->coded_frame = &x->encoded_picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -617,7 +618,7 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     int xerr, i, ret, user_packet = !!pkt->data;
     char *tmp;
     struct xvid_context *x = avctx->priv_data;
-    AVFrame *p = &x->encoded_picture;
+    AVFrame *p = avctx->coded_frame;
     int mb_width   = (avctx->width  + 15) / 16;
     int mb_height  = (avctx->height + 15) / 16;
 
@@ -633,7 +634,6 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     /* Start setting up the frame */
     xvid_enc_frame.version = XVID_VERSION;
     xvid_enc_stats.version = XVID_VERSION;
-    *p = *picture;
 
     /* Let Xvid know where to put the frame. */
     xvid_enc_frame.bitstream = pkt->data;
@@ -750,6 +750,7 @@ static av_cold int xvid_encode_close(AVCodecContext *avctx) {
 
 AVCodec ff_libxvid_encoder = {
     .name           = "libxvid",
+    .long_name      = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MPEG4,
     .priv_data_size = sizeof(struct xvid_context),
@@ -757,5 +758,4 @@ AVCodec ff_libxvid_encoder = {
     .encode2        = xvid_encode_frame,
     .close          = xvid_encode_close,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("libxvidcore MPEG-4 part 2"),
 };
diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c
index bf9f6f0..7f4a89d 100644
--- a/libavcodec/libxvid_rc.c
+++ b/libavcodec/libxvid_rc.c
@@ -27,9 +27,10 @@
 #include <fcntl.h>
 #endif
 
+#include "libavutil/attributes.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "libxvid.h"
-//#include "dsputil.h"
 #include "mpegvideo.h"
 
 #undef NDEBUG
@@ -54,7 +55,7 @@ int ff_tempfile(const char *prefix, char **filename) {
         return -1;
     }
 #if !HAVE_MKSTEMP
-    fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444);
+    fd = avpriv_open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444);
 #else
     snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
     fd = mkstemp(*filename);
@@ -71,7 +72,8 @@ int ff_tempfile(const char *prefix, char **filename) {
     return fd; /* success */
 }
 
-int ff_xvid_rate_control_init(MpegEncContext *s){
+av_cold int ff_xvid_rate_control_init(MpegEncContext *s)
+{
     char *tmp_name;
     int fd, i;
     xvid_plg_create_t xvid_plg_create = { 0 };
@@ -169,7 +171,8 @@ float ff_xvid_rate_estimate_qscale(MpegEncContext *s, int dry_run){
         return xvid_plg_data.quant * FF_QP2LAMBDA;
 }
 
-void ff_xvid_rate_control_uninit(MpegEncContext *s){
+av_cold void ff_xvid_rate_control_uninit(MpegEncContext *s)
+{
     xvid_plg_destroy_t xvid_plg_destroy;
 
     xvid_plugin_2pass2(s->rc_context.non_lavc_opaque, XVID_PLG_DESTROY, &xvid_plg_destroy, NULL);
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index 78ba2c9..7eb4675 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -30,6 +30,10 @@
  * lossless JPEG encoder.
  */
 
+#include "libavutil/frame.h"
+#include "libavutil/mem.h"
+#include "libavutil/pixdesc.h"
+
 #include "avcodec.h"
 #include "dsputil.h"
 #include "internal.h"
@@ -37,179 +41,294 @@
 #include "mjpeg.h"
 #include "mjpegenc.h"
 
+typedef struct LJpegEncContext {
+    DSPContext dsp;
+    ScanTable scantable;
+    uint16_t matrix[64];
 
-static int encode_picture_lossless(AVCodecContext *avctx, AVPacket *pkt,
-                                   const AVFrame *pict, int *got_packet)
-{
-    MpegEncContext * const s = avctx->priv_data;
-    MJpegContext * const m = s->mjpeg_ctx;
-    const int width= s->width;
-    const int height= s->height;
-    AVFrame * const p = &s->current_picture.f;
-    const int predictor= avctx->prediction_method+1;
-    const int mb_width  = (width  + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0];
-    const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0];
-    int ret, max_pkt_size = FF_MIN_BUFFER_SIZE;
-
-    if (avctx->pix_fmt == AV_PIX_FMT_BGRA)
-        max_pkt_size += width * height * 3 * 4;
-    else {
-        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);
-        return ret;
-    }
-
-    init_put_bits(&s->pb, pkt->data, pkt->size);
+    int vsample[3];
+    int hsample[3];
 
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+    uint16_t huff_code_dc_luminance[12];
+    uint16_t huff_code_dc_chrominance[12];
+    uint8_t  huff_size_dc_luminance[12];
+    uint8_t  huff_size_dc_chrominance[12];
 
-    ff_mjpeg_encode_picture_header(s);
+    uint16_t (*scratch)[4];
+} LJpegEncContext;
 
-    s->header_bits= put_bits_count(&s->pb);
+static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb,
+                            const AVFrame *frame)
+{
+    LJpegEncContext *s    = avctx->priv_data;
+    const int width       = frame->width;
+    const int height      = frame->height;
+    const int linesize    = frame->linesize[0];
+    uint16_t (*buffer)[4] = s->scratch;
+    const int predictor   = avctx->prediction_method+1;
+    int left[3], top[3], topleft[3];
+    int x, y, i;
+
+    for (i = 0; i < 3; i++)
+        buffer[0][i] = 1 << (9 - 1);
+
+    for (y = 0; y < height; y++) {
+        const int modified_predictor = y ? predictor : 1;
+        uint8_t *ptr = frame->data[0] + (linesize * y);
+
+        if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < width * 3 * 3) {
+            av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
+            return -1;
+        }
 
-    if(avctx->pix_fmt == AV_PIX_FMT_BGRA){
-        int x, y, i;
-        const int linesize= p->linesize[0];
-        uint16_t (*buffer)[4]= (void *) s->rd_scratchpad;
-        int left[3], top[3], topleft[3];
+        for (i = 0; i < 3; i++)
+            top[i]= left[i]= topleft[i]= buffer[0][i];
 
-        for(i=0; i<3; i++){
-            buffer[0][i]= 1 << (9 - 1);
-        }
+        for (x = 0; x < width; x++) {
+            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;
 
-        for(y = 0; y < height; y++) {
-            const int modified_predictor= y ? predictor : 1;
-            uint8_t *ptr = p->data[0] + (linesize * y);
+            for (i = 0; i < 3; i++) {
+                int pred, diff;
 
-            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < width*3*4){
-                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
-                return -1;
-            }
+                PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
 
-            for(i=0; i<3; i++){
-                top[i]= left[i]= topleft[i]= buffer[0][i];
-            }
-            for(x = 0; x < width; x++) {
-                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;
+                topleft[i] = top[i];
+                top[i]     = buffer[x+1][i];
 
-                for(i=0;i<3;i++) {
-                    int pred, diff;
+                left[i]    = buffer[x][i];
 
-                    PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
+                diff       = ((left[i] - pred + 0x100) & 0x1FF) - 0x100;
 
-                    topleft[i]= top[i];
-                    top[i]= buffer[x+1][i];
+                if (i == 0)
+                    ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
+                else
+                    ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
+            }
+        }
+    }
 
-                    left[i]= buffer[x][i];
+    return 0;
+}
 
-                    diff= ((left[i] - pred + 0x100)&0x1FF) - 0x100;
+static inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb,
+                                       const AVFrame *frame, int predictor,
+                                       int mb_x, int mb_y)
+{
+    int i;
+
+    if (mb_x == 0 || mb_y == 0) {
+        for (i = 0; i < 3; i++) {
+            uint8_t *ptr;
+            int x, y, h, v, linesize;
+            h = s->hsample[i];
+            v = s->vsample[i];
+            linesize = frame->linesize[i];
+
+            for (y = 0; y < v; y++) {
+                for (x = 0; x < h; x++) {
+                    int pred;
+
+                    ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
+                    if (y == 0 && mb_y == 0) {
+                        if (x == 0 && mb_x == 0)
+                            pred = 128;
+                        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(i==0)
-                        ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
+                    if (i == 0)
+                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
                     else
-                        ff_mjpeg_encode_dc(s, diff, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
+                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
                 }
             }
         }
-    }else{
-        int mb_x, mb_y, i;
-
-        for(mb_y = 0; mb_y < mb_height; mb_y++) {
-            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < mb_width * 4 * 3 * s->mjpeg_hsample[0] * s->mjpeg_vsample[0]){
-                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
-                return -1;
-            }
-            for(mb_x = 0; mb_x < mb_width; mb_x++) {
-                if(mb_x==0 || mb_y==0){
-                    for(i=0;i<3;i++) {
-                        uint8_t *ptr;
-                        int x, y, h, v, linesize;
-                        h = s->mjpeg_hsample[i];
-                        v = s->mjpeg_vsample[i];
-                        linesize= p->linesize[i];
-
-                        for(y=0; y<v; y++){
-                            for(x=0; x<h; x++){
-                                int pred;
-
-                                ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
-                                if(y==0 && mb_y==0){
-                                    if(x==0 && mb_x==0){
-                                        pred= 128;
-                                    }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(i==0)
-                                    ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
-                                else
-                                    ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
-                            }
-                        }
-                    }
-                }else{
-                    for(i=0;i<3;i++) {
-                        uint8_t *ptr;
-                        int x, y, h, v, linesize;
-                        h = s->mjpeg_hsample[i];
-                        v = s->mjpeg_vsample[i];
-                        linesize= p->linesize[i];
-
-                        for(y=0; y<v; y++){
-                            for(x=0; x<h; x++){
-                                int pred;
-
-                                ptr = p->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
-                                PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
-
-                                if(i==0)
-                                    ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_luminance, m->huff_code_dc_luminance); //FIXME ugly
-                                else
-                                    ff_mjpeg_encode_dc(s, *ptr - pred, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
-                            }
-                        }
-                    }
+    } else {
+        for (i = 0; i < 3; i++) {
+            uint8_t *ptr;
+            int x, y, h, v, linesize;
+            h = s->hsample[i];
+            v = s->vsample[i];
+            linesize = frame->linesize[i];
+
+            for (y = 0; y < v; y++) {
+                for (x = 0; x < h; x++) {
+                    int pred;
+
+                    ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
+                    PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], ptr[-1], predictor);
+
+                    if (i == 0)
+                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly
+                    else
+                        ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance);
                 }
             }
         }
     }
+}
+
+static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb,
+                            const AVFrame *frame)
+{
+    const int predictor = avctx->prediction_method + 1;
+    LJpegEncContext *s  = avctx->priv_data;
+    const int mb_width  = (avctx->width  + s->hsample[0] - 1) / s->hsample[0];
+    const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0];
+    int mb_x, mb_y;
+
+    for (mb_y = 0; mb_y < mb_height; mb_y++) {
+        if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) <
+            mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) {
+            av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
+            return -1;
+        }
+
+        for (mb_x = 0; mb_x < mb_width; mb_x++)
+            ljpeg_encode_yuv_mb(s, pb, frame, predictor, mb_x, mb_y);
+    }
+
+    return 0;
+}
+
+static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                              const AVFrame *pict, int *got_packet)
+{
+    LJpegEncContext *s = avctx->priv_data;
+    PutBitContext pb;
+    const int width  = avctx->width;
+    const int height = avctx->height;
+    const int mb_width  = (width  + s->hsample[0] - 1) / s->hsample[0];
+    const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0];
+    int max_pkt_size = FF_MIN_BUFFER_SIZE;
+    int ret, header_bits;
+
+    if (avctx->pix_fmt == AV_PIX_FMT_BGR24)
+        max_pkt_size += width * height * 3 * 3;
+    else {
+        max_pkt_size += mb_width * mb_height * 3 * 4
+                        * s->hsample[0] * s->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);
+        return ret;
+    }
+
+    init_put_bits(&pb, pkt->data, pkt->size);
+
+    ff_mjpeg_encode_picture_header(avctx, &pb, &s->scantable,
+                                   s->matrix);
+
+    header_bits = put_bits_count(&pb);
+
+    if (avctx->pix_fmt == AV_PIX_FMT_BGR24)
+        ret = ljpeg_encode_bgr(avctx, &pb, pict);
+    else
+        ret = ljpeg_encode_yuv(avctx, &pb, pict);
+    if (ret < 0)
+        return ret;
 
     emms_c();
 
-    ff_mjpeg_encode_picture_trailer(s);
-    s->picture_number++;
+    ff_mjpeg_encode_picture_trailer(&pb, header_bits);
 
-    flush_put_bits(&s->pb);
-    pkt->size   = put_bits_ptr(&s->pb) - s->pb.buf;
+    flush_put_bits(&pb);
+    pkt->size   = put_bits_ptr(&pb) - pb.buf;
     pkt->flags |= AV_PKT_FLAG_KEY;
     *got_packet = 1;
 
     return 0;
-//    return (put_bits_count(&f->pb)+7)/8;
 }
 
+static av_cold int ljpeg_encode_close(AVCodecContext *avctx)
+{
+    LJpegEncContext *s = avctx->priv_data;
+
+    av_frame_free(&avctx->coded_frame);
+    av_freep(&s->scratch);
 
-AVCodec ff_ljpeg_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them
+    return 0;
+}
+
+static av_cold int ljpeg_encode_init(AVCodecContext *avctx)
+{
+    LJpegEncContext *s = avctx->priv_data;
+    int chroma_v_shift, chroma_h_shift;
+
+    if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+         avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
+         avctx->pix_fmt == AV_PIX_FMT_YUV444P) &&
+        avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Limited range YUV is non-standard, set strict_std_compliance to "
+               "at least unofficial to use it.\n");
+        return AVERROR(EINVAL);
+    }
+
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+
+    s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch));
+
+    ff_dsputil_init(&s->dsp, avctx);
+    ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
+
+    av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift,
+                                     &chroma_v_shift);
+
+    if (avctx->pix_fmt   == AV_PIX_FMT_BGR24) {
+        s->vsample[0] = s->hsample[0] =
+        s->vsample[1] = s->hsample[1] =
+        s->vsample[2] = s->hsample[2] = 1;
+    } else {
+        s->vsample[0] = 2;
+        s->vsample[1] = 2 >> chroma_v_shift;
+        s->vsample[2] = 2 >> chroma_v_shift;
+        s->hsample[0] = 2;
+        s->hsample[1] = 2 >> chroma_h_shift;
+        s->hsample[2] = 2 >> chroma_h_shift;
+    }
+
+    ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance,
+                                 s->huff_code_dc_luminance,
+                                 avpriv_mjpeg_bits_dc_luminance,
+                                 avpriv_mjpeg_val_dc);
+    ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance,
+                                 s->huff_code_dc_chrominance,
+                                 avpriv_mjpeg_bits_dc_chrominance,
+                                 avpriv_mjpeg_val_dc);
+
+    return 0;
+}
+
+AVCodec ff_ljpeg_encoder = {
     .name           = "ljpeg",
+    .long_name      = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_LJPEG,
-    .priv_data_size = sizeof(MpegEncContext),
-    .init           = ff_MPV_encode_init,
-    .encode2        = encode_picture_lossless,
-    .close          = ff_MPV_encode_end,
-    .long_name      = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
+    .priv_data_size = sizeof(LJpegEncContext),
+    .init           = ljpeg_encode_init,
+    .encode2        = ljpeg_encode_frame,
+    .close          = ljpeg_encode_close,
+    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVJ420P,
+                                                    AV_PIX_FMT_YUVJ422P,
+                                                    AV_PIX_FMT_YUVJ444P,
+                                                    AV_PIX_FMT_BGR24,
+                                                    AV_PIX_FMT_YUV420P,
+                                                    AV_PIX_FMT_YUV422P,
+                                                    AV_PIX_FMT_YUVJ444P,
+                                                    AV_PIX_FMT_NONE },
 };
diff --git a/libavcodec/loco.c b/libavcodec/loco.c
index f783636..6be081d 100644
--- a/libavcodec/loco.c
+++ b/libavcodec/loco.c
@@ -30,29 +30,38 @@
 #include "internal.h"
 #include "mathops.h"
 
-enum LOCO_MODE {LOCO_UNKN=0, LOCO_CYUY2=-1, LOCO_CRGB=-2, LOCO_CRGBA=-3, LOCO_CYV12=-4,
- LOCO_YUY2=1, LOCO_UYVY=2, LOCO_RGB=3, LOCO_RGBA=4, LOCO_YV12=5};
+enum LOCO_MODE {
+    LOCO_UNKN  =  0,
+    LOCO_CYUY2 = -1,
+    LOCO_CRGB  = -2,
+    LOCO_CRGBA = -3,
+    LOCO_CYV12 = -4,
+    LOCO_YUY2  =  1,
+    LOCO_UYVY  =  2,
+    LOCO_RGB   =  3,
+    LOCO_RGBA  =  4,
+    LOCO_YV12  =  5,
+};
 
-typedef struct LOCOContext{
+typedef struct LOCOContext {
     AVCodecContext *avctx;
-    AVFrame pic;
     int lossy;
     int mode;
 } LOCOContext;
 
-typedef struct RICEContext{
+typedef struct RICEContext {
     GetBitContext gb;
     int save, run, run2; /* internal rice decoder state */
     int sum, count; /* sum and count for getting rice parameter */
     int lossy;
-}RICEContext;
+} RICEContext;
 
 static int loco_get_rice_param(RICEContext *r)
 {
     int cnt = 0;
     int val = r->count;
 
-    while(r->sum > val && cnt < 9) {
+    while (r->sum > val && cnt < 9) {
         val <<= 1;
         cnt++;
     }
@@ -65,8 +74,8 @@ static inline void loco_update_rice_param(RICEContext *r, int val)
     r->sum += val;
     r->count++;
 
-    if(r->count == 16) {
-        r->sum >>= 1;
+    if (r->count == 16) {
+        r->sum   >>= 1;
         r->count >>= 1;
     }
 }
@@ -80,19 +89,18 @@ static inline int loco_get_rice(RICEContext *r)
         return 0;
     }
     v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0);
-    loco_update_rice_param(r, (v+1)>>1);
+    loco_update_rice_param(r, (v + 1) >> 1);
     if (!v) {
         if (r->save >= 0) {
             r->run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0);
-            if(r->run > 1)
+            if (r->run > 1)
                 r->save += r->run + 1;
             else
                 r->save -= 3;
-        }
-        else
+        } else
             r->run2++;
     } else {
-        v = ((v>>1) + r->lossy) ^ -(v&1);
+        v = ((v >> 1) + r->lossy) ^ -(v & 1);
         if (r->run2 > 0) {
             if (r->run2 > 2)
                 r->save += r->run2;
@@ -125,16 +133,16 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh
     int i, j;
 
     init_get_bits(&rc.gb, buf, buf_size*8);
-    rc.save = 0;
-    rc.run = 0;
-    rc.run2 = 0;
+    rc.save  = 0;
+    rc.run   = 0;
+    rc.run2  = 0;
     rc.lossy = l->lossy;
 
-    rc.sum = 8;
+    rc.sum   = 8;
     rc.count = 1;
 
     /* restore top left pixel */
-    val = loco_get_rice(&rc);
+    val     = loco_get_rice(&rc);
     data[0] = 128 + val;
     /* restore top line */
     for (i = 1; i < width; i++) {
@@ -161,19 +169,15 @@ static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     LOCOContext * const l = avctx->priv_data;
-    AVFrame * const p = &l->pic;
-    int decoded;
-
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
+    const uint8_t *buf    = avpkt->data;
+    int buf_size          = avpkt->size;
+    AVFrame * const p     = data;
+    int decoded, ret;
 
-    p->reference = 0;
-    if(ff_get_buffer(avctx, p) < 0){
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->key_frame = 1;
 
@@ -251,7 +255,6 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
 
     return buf_size;
 buf_too_small:
@@ -259,7 +262,8 @@ buf_too_small:
     return AVERROR(EINVAL);
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     LOCOContext * const l = avctx->priv_data;
     int version;
 
@@ -267,10 +271,10 @@ static av_cold int decode_init(AVCodecContext *avctx){
     if (avctx->extradata_size < 12) {
         av_log(avctx, AV_LOG_ERROR, "Extradata size must be >= 12 instead of %i\n",
                avctx->extradata_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     version = AV_RL32(avctx->extradata);
-    switch(version) {
+    switch (version) {
     case 1:
         l->lossy = 0;
         break;
@@ -279,51 +283,45 @@ static av_cold int decode_init(AVCodecContext *avctx){
         break;
     default:
         l->lossy = AV_RL32(avctx->extradata + 8);
-        av_log_ask_for_sample(avctx, "This is LOCO codec version %i.\n", version);
+        avpriv_request_sample(avctx, "LOCO codec version %i", version);
     }
 
     l->mode = AV_RL32(avctx->extradata + 4);
-    switch(l->mode) {
-    case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY:
+    switch (l->mode) {
+    case LOCO_CYUY2:
+    case LOCO_YUY2:
+    case LOCO_UYVY:
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
         break;
-    case LOCO_CRGB: case LOCO_RGB:
+    case LOCO_CRGB:
+    case LOCO_RGB:
         avctx->pix_fmt = AV_PIX_FMT_BGR24;
         break;
-    case LOCO_CYV12: case LOCO_YV12:
+    case LOCO_CYV12:
+    case LOCO_YV12:
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
         break;
-    case LOCO_CRGBA: case LOCO_RGBA:
+    case LOCO_CRGBA:
+    case LOCO_RGBA:
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
         break;
     default:
         av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
-    if(avctx->debug & FF_DEBUG_PICT_INFO)
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode);
 
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
-    LOCOContext * const l = avctx->priv_data;
-    AVFrame *pic = &l->pic;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    return 0;
-}
-
 AVCodec ff_loco_decoder = {
     .name           = "loco",
+    .long_name      = NULL_IF_CONFIG_SMALL("LOCO"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_LOCO,
     .priv_data_size = sizeof(LOCOContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("LOCO"),
 };
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 2093e7e..fbd1bdf 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -176,7 +176,7 @@ int ff_lpc_calc_coefs(LPCContext *s,
     double autoc[MAX_LPC_ORDER+1];
     double ref[MAX_LPC_ORDER];
     double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
-    int i, j, pass;
+    int i, j, pass = 0;
     int opt_order;
 
     assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER &&
@@ -189,7 +189,7 @@ int ff_lpc_calc_coefs(LPCContext *s,
         ff_lpc_init(s, blocksize, max_order, lpc_type);
     }
 
-    if (lpc_type == FF_LPC_TYPE_LEVINSON) {
+    if (lpc_type == FF_LPC_TYPE_LEVINSON || (lpc_type == FF_LPC_TYPE_CHOLESKY && lpc_passes > 1)) {
         s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples);
 
         s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc);
@@ -198,12 +198,21 @@ int ff_lpc_calc_coefs(LPCContext *s,
 
         for(i=0; i<max_order; i++)
             ref[i] = fabs(lpc[i][i]);
-    } else if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
+
+        pass++;
+    }
+
+    if (lpc_type == FF_LPC_TYPE_CHOLESKY) {
         LLSModel m[2];
-        double var[MAX_LPC_ORDER+1], av_uninit(weight);
+        LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]);
+        double av_uninit(weight);
+        memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var));
 
-        for(pass=0; pass<lpc_passes; pass++){
-            av_init_lls(&m[pass&1], max_order);
+        for(j=0; j<max_order; j++)
+            m[0].coeff[max_order-1][j] = -lpc[max_order-1][j];
+
+        for(; pass<lpc_passes; pass++){
+            avpriv_init_lls(&m[pass&1], max_order);
 
             weight=0;
             for(i=max_order; i<blocksize; i++){
@@ -212,7 +221,7 @@ int ff_lpc_calc_coefs(LPCContext *s,
 
                 if(pass){
                     double eval, inv, rinv;
-                    eval= av_evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
+                    eval= m[pass&1].evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
                     eval= (512>>pass) + fabs(eval - var[0]);
                     inv = 1/eval;
                     rinv = sqrt(inv);
@@ -222,9 +231,9 @@ int ff_lpc_calc_coefs(LPCContext *s,
                 }else
                     weight++;
 
-                av_update_lls(&m[pass&1], var, 1.0);
+                m[pass&1].update_lls(&m[pass&1], var);
             }
-            av_solve_lls(&m[pass&1], 0.001, 0);
+            avpriv_solve_lls(&m[pass&1], 0.001, 0);
         }
 
         for(i=0; i<max_order; i++){
@@ -257,15 +266,11 @@ av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order,
     s->max_order = max_order;
     s->lpc_type  = lpc_type;
 
-    if (lpc_type == FF_LPC_TYPE_LEVINSON) {
-        s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) *
-                                        sizeof(*s->windowed_samples));
-        if (!s->windowed_buffer)
-            return AVERROR(ENOMEM);
-        s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4);
-    } else {
-        s->windowed_samples = NULL;
-    }
+    s->windowed_buffer = av_mallocz((blocksize + 2 + FFALIGN(max_order, 4)) *
+                                    sizeof(*s->windowed_samples));
+    if (!s->windowed_buffer)
+        return AVERROR(ENOMEM);
+    s->windowed_samples = s->windowed_buffer + FFALIGN(max_order, 4);
 
     s->lpc_apply_welch_window = lpc_apply_welch_window_c;
     s->lpc_compute_autocorr   = lpc_compute_autocorr_c;
diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
index 6590608..c41a1f8 100644
--- a/libavcodec/lpc.h
+++ b/libavcodec/lpc.h
@@ -23,7 +23,6 @@
 #define AVCODEC_LPC_H
 
 #include <stdint.h>
-#include "dsputil.h"
 
 #define ORDER_METHOD_EST     0
 #define ORDER_METHOD_2LEVEL  1
diff --git a/libavcodec/lzw.c b/libavcodec/lzw.c
index 2c99014..0167140 100644
--- a/libavcodec/lzw.c
+++ b/libavcodec/lzw.c
@@ -43,7 +43,7 @@ static const uint16_t mask[17] =
 };
 
 struct LZWState {
-    const uint8_t *pbuf, *ebuf;
+    const uint8_t *buf_start, *pbuf, *ebuf;
     int bbits;
     unsigned int bbuf;
 
@@ -92,9 +92,10 @@ static int lzw_get_code(struct LZWState * s)
     return c & s->curmask;
 }
 
-const uint8_t* ff_lzw_cur_ptr(LZWState *p)
+int ff_lzw_size_read(LZWState *p)
 {
-    return ((struct LZWState*)p)->pbuf;
+    struct LZWState *s = p;
+    return s->pbuf - s->buf_start;
 }
 
 void ff_lzw_decode_tail(LZWState *p)
diff --git a/libavcodec/lzw.h b/libavcodec/lzw.h
index ab782f5..d925d35 100644
--- a/libavcodec/lzw.h
+++ b/libavcodec/lzw.h
@@ -47,7 +47,7 @@ void ff_lzw_decode_open(LZWState **p);
 void ff_lzw_decode_close(LZWState **p);
 int ff_lzw_decode_init(LZWState *s, int csize, const uint8_t *buf, int buf_size, int mode);
 int ff_lzw_decode(LZWState *s, uint8_t *buf, int len);
-const uint8_t* ff_lzw_cur_ptr(LZWState *lzw);
+int ff_lzw_size_read(LZWState *lzw);
 void ff_lzw_decode_tail(LZWState *lzw);
 
 /** LZW encode state */
diff --git a/libavcodec/mace.c b/libavcodec/mace.c
index 5074e4b..25c6b70 100644
--- a/libavcodec/mace.c
+++ b/libavcodec/mace.c
@@ -155,7 +155,6 @@ typedef struct ChannelData {
 } ChannelData;
 
 typedef struct MACEContext {
-    AVFrame frame;
     ChannelData chd[2];
 } MACEContext;
 
@@ -227,21 +226,17 @@ static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, int tab_idx)
 
 static av_cold int mace_decode_init(AVCodecContext * avctx)
 {
-    MACEContext *ctx = avctx->priv_data;
-
     if (avctx->channels > 2 || avctx->channels < 1)
         return AVERROR(EINVAL);
     avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
 
-    avcodec_get_frame_defaults(&ctx->frame);
-    avctx->coded_frame = &ctx->frame;
-
     return 0;
 }
 
 static int mace_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     int16_t **samples;
@@ -250,12 +245,12 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data,
     int is_mace3 = (avctx->codec_id == AV_CODEC_ID_MACE3);
 
     /* get output buffer */
-    ctx->frame.nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    frame->nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t **)ctx->frame.extended_data;
+    samples = (int16_t **)frame->extended_data;
 
     for(i = 0; i < avctx->channels; i++) {
         int16_t *output = samples[i];
@@ -279,34 +274,33 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data,
             }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ctx->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
 
 AVCodec ff_mace3_decoder = {
     .name           = "mace3",
+    .long_name      = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MACE3,
     .priv_data_size = sizeof(MACEContext),
     .init           = mace_decode_init,
     .decode         = mace_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
 };
 
 AVCodec ff_mace6_decoder = {
     .name           = "mace6",
+    .long_name      = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MACE6,
     .priv_data_size = sizeof(MACEContext),
     .init           = mace_decode_init,
     .decode         = mace_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/mathops.h b/libavcodec/mathops.h
index 551017e..6c216c2 100644
--- a/libavcodec/mathops.h
+++ b/libavcodec/mathops.h
@@ -195,6 +195,15 @@ if ((y) < (x)) {\
 #   define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32))
 #endif /* FASTDIV */
 
+#ifndef MOD_UNLIKELY
+#   define MOD_UNLIKELY(modulus, dividend, divisor, prev_dividend) \
+    do { \
+        if ((prev_dividend) == 0 || (dividend) - (prev_dividend) != (divisor)) \
+            (modulus) = (dividend) % (divisor); \
+        (prev_dividend) = (dividend); \
+    } while (0)
+#endif
+
 static inline av_const unsigned int ff_sqrt(unsigned int a)
 {
     unsigned int b;
@@ -215,4 +224,14 @@ static inline av_const unsigned int ff_sqrt(unsigned int a)
     return b - (a < b * b);
 }
 
+static inline int8_t ff_u8_to_s8(uint8_t a)
+{
+    union {
+        uint8_t u8;
+        int8_t  s8;
+    } b;
+    b.u8 = a;
+    return b.s8;
+}
+
 #endif /* AVCODEC_MATHOPS_H */
diff --git a/libavcodec/mathtables.c b/libavcodec/mathtables.c
index 141aa78..8a3934b 100644
--- a/libavcodec/mathtables.c
+++ b/libavcodec/mathtables.c
@@ -85,3 +85,38 @@ const uint8_t ff_reverse[256] = {
 0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
 0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF,
 };
+
+#define times4(x) x, x, x, x
+#define times256(x) times4(times4(times4(times4(times4(x)))))
+
+const uint8_t ff_cropTbl[256 + 2 * 1024] = {
+times256(0x00),
+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,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,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
+0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
+0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
+0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
+0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
+0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
+0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
+0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
+0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
+0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
+0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
+0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
+0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
+times256(0xFF)
+};
+
+const uint8_t ff_zigzag_direct[64] = {
+    0,   1,  8, 16,  9,  2,  3, 10,
+    17, 24, 32, 25, 18, 11,  4,  5,
+    12, 19, 26, 33, 40, 48, 41, 34,
+    27, 20, 13,  6,  7, 14, 21, 28,
+    35, 42, 49, 56, 57, 50, 43, 36,
+    29, 22, 15, 23, 30, 37, 44, 51,
+    58, 59, 52, 45, 38, 31, 39, 46,
+    53, 60, 61, 54, 47, 55, 62, 63
+};
diff --git a/libavcodec/mdct_fixed.c b/libavcodec/mdct_fixed.c
index 94527f9..15dfcd4 100644
--- a/libavcodec/mdct_fixed.c
+++ b/libavcodec/mdct_fixed.c
@@ -17,7 +17,7 @@
  */
 
 #define CONFIG_FFT_FLOAT 0
-#include "mdct.c"
+#include "mdct_template.c"
 
 /* same as ff_mdct_calcw_c with double-width unscaled output */
 void ff_mdct_calcw_c(FFTContext *s, FFTDouble *out, const FFTSample *input)
diff --git a/libavcodec/mdct_float.c b/libavcodec/mdct_float.c
index e4f5549..f8955f6 100644
--- a/libavcodec/mdct_float.c
+++ b/libavcodec/mdct_float.c
@@ -17,4 +17,4 @@
  */
 
 #define CONFIG_FFT_FLOAT 1
-#include "mdct.c"
+#include "mdct_template.c"
diff --git a/libavcodec/mdct.c b/libavcodec/mdct_template.c
similarity index 100%
rename from libavcodec/mdct.c
rename to libavcodec/mdct_template.c
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index b5a9d57..b9ffca6 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -28,15 +28,14 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "mpeg12.h"
 #include "thread.h"
 
-typedef struct MDECContext{
+typedef struct MDECContext {
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame picture;
+    ThreadFrame frame;
     GetBitContext gb;
     ScanTable scantable;
     int version;
@@ -45,48 +44,48 @@ typedef struct MDECContext{
     int mb_width;
     int mb_height;
     int mb_x, mb_y;
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block)[6][64];
     uint8_t *bitstream_buffer;
     unsigned int bitstream_buffer_size;
     int block_last_index[6];
 } MDECContext;
 
 //very similar to MPEG-1
-static inline int mdec_decode_block_intra(MDECContext *a, DCTELEM *block, int n)
+static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n)
 {
     int level, diff, i, j, run;
     int component;
     RLTable *rl = &ff_rl_mpeg1;
-    uint8_t * const scantable= a->scantable.permutated;
-    const uint16_t *quant_matrix= ff_mpeg1_default_intra_matrix;
-    const int qscale= a->qscale;
+    uint8_t * const scantable = a->scantable.permutated;
+    const uint16_t *quant_matrix = ff_mpeg1_default_intra_matrix;
+    const int qscale = a->qscale;
 
     /* DC coefficient */
-    if(a->version==2){
-        block[0]= 2*get_sbits(&a->gb, 10) + 1024;
-    }else{
+    if (a->version == 2) {
+        block[0] = 2 * get_sbits(&a->gb, 10) + 1024;
+    } else {
         component = (n <= 3 ? 0 : n - 4 + 1);
         diff = decode_dc(&a->gb, component);
         if (diff >= 0xffff)
-            return -1;
-        a->last_dc[component]+= diff;
-        block[0] = a->last_dc[component]<<3;
+            return AVERROR_INVALIDDATA;
+        a->last_dc[component] += diff;
+        block[0] = a->last_dc[component] << 3;
     }
 
     i = 0;
     {
         OPEN_READER(re, &a->gb);
         /* now quantify & encode AC coefficients */
-        for(;;) {
+        for (;;) {
             UPDATE_CACHE(re, &a->gb);
             GET_RL_VLC(level, run, re, &a->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
 
-            if(level == 127){
+            if (level == 127) {
                 break;
-            } else if(level != 0) {
-                i += run;
-                j = scantable[i];
-                level= (level*qscale*quant_matrix[j])>>3;
+            } else if (level != 0) {
+                i    += run;
+                j     = scantable[i];
+                level = (level * qscale * quant_matrix[j]) >> 3;
                 level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1);
                 LAST_SKIP_BITS(re, &a->gb, 1);
             } else {
@@ -94,21 +93,21 @@ static inline int mdec_decode_block_intra(MDECContext *a, DCTELEM *block, int n)
                 run = SHOW_UBITS(re, &a->gb, 6)+1; LAST_SKIP_BITS(re, &a->gb, 6);
                 UPDATE_CACHE(re, &a->gb);
                 level = SHOW_SBITS(re, &a->gb, 10); SKIP_BITS(re, &a->gb, 10);
-                i += run;
-                j = scantable[i];
-                if(level<0){
-                    level= -level;
-                    level= (level*qscale*quant_matrix[j])>>3;
-                    level= (level-1)|1;
-                    level= -level;
-                }else{
-                    level= (level*qscale*quant_matrix[j])>>3;
-                    level= (level-1)|1;
+                i    += run;
+                j     = scantable[i];
+                if (level < 0) {
+                    level = -level;
+                    level = (level * qscale * quant_matrix[j]) >> 3;
+                    level = (level - 1) | 1;
+                    level = -level;
+                } else {
+                    level = (level * qscale * quant_matrix[j]) >> 3;
+                    level = (level - 1) | 1;
                 }
             }
-            if (i > 63){
+            if (i > 63) {
                 av_log(a->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
             block[j] = level;
@@ -119,36 +118,40 @@ static inline int mdec_decode_block_intra(MDECContext *a, DCTELEM *block, int n)
     return 0;
 }
 
-static inline int decode_mb(MDECContext *a, DCTELEM block[6][64]){
-    int i;
-    const int block_index[6]= {5,4,0,1,2,3};
+static inline int decode_mb(MDECContext *a, int16_t block[6][64])
+{
+    int i, ret;
+    const int block_index[6] = { 5, 4, 0, 1, 2, 3 };
 
     a->dsp.clear_blocks(block[0]);
 
-    for(i=0; i<6; i++){
-        if( mdec_decode_block_intra(a, block[ block_index[i] ], block_index[i]) < 0 ||
-            get_bits_left(&a->gb) < 0)
-            return -1;
+    for (i = 0; i < 6; i++) {
+        if ((ret = mdec_decode_block_intra(a, block[block_index[i]],
+                                           block_index[i])) < 0)
+            return ret;
+        if (get_bits_left(&a->gb) < 0)
+            return AVERROR_INVALIDDATA;
     }
     return 0;
 }
 
-static inline void idct_put(MDECContext *a, int mb_x, int mb_y){
-    DCTELEM (*block)[64]= a->block;
-    int linesize= a->picture.linesize[0];
+static inline void idct_put(MDECContext *a, AVFrame *frame, int mb_x, int mb_y)
+{
+    int16_t (*block)[64] = a->block;
+    int linesize = frame->linesize[0];
 
-    uint8_t *dest_y  = a->picture.data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
-    uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
+    uint8_t *dest_y  = frame->data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
 
-    a->dsp.idct_put(dest_y                 , linesize, block[0]);
-    a->dsp.idct_put(dest_y              + 8, linesize, block[1]);
-    a->dsp.idct_put(dest_y + 8*linesize    , linesize, block[2]);
-    a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
+    a->dsp.idct_put(dest_y,                    linesize, block[0]);
+    a->dsp.idct_put(dest_y                + 8, linesize, block[1]);
+    a->dsp.idct_put(dest_y + 8 * linesize,     linesize, block[2]);
+    a->dsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]);
 
-    if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
-        a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
-        a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
+    if (!(a->avctx->flags & CODEC_FLAG_GRAY)) {
+        a->dsp.idct_put(dest_cb, frame->linesize[1], block[4]);
+        a->dsp.idct_put(dest_cr, frame->linesize[2], block[5]);
     }
 }
 
@@ -156,116 +159,92 @@ static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     MDECContext * const a = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p= &a->picture;
-    int i;
+    const uint8_t *buf    = avpkt->data;
+    int buf_size          = avpkt->size;
+    ThreadFrame frame     = { .f = data };
+    int i, ret;
 
-    if(p->data[0])
-        ff_thread_release_buffer(avctx, p);
-
-    p->reference= 0;
-    if(ff_thread_get_buffer(avctx, p) < 0){
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+    frame.f->pict_type = AV_PICTURE_TYPE_I;
+    frame.f->key_frame = 1;
 
     av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!a->bitstream_buffer)
         return AVERROR(ENOMEM);
-    for(i=0; i<buf_size; i+=2){
-        a->bitstream_buffer[i]  = buf[i+1];
-        a->bitstream_buffer[i+1]= buf[i  ];
+    for (i = 0; i < buf_size; i += 2) {
+        a->bitstream_buffer[i]     = buf[i + 1];
+        a->bitstream_buffer[i + 1] = buf[i];
     }
-    init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8);
+    init_get_bits(&a->gb, a->bitstream_buffer, buf_size * 8);
 
     /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */
     skip_bits(&a->gb, 32);
 
-    a->qscale=  get_bits(&a->gb, 16);
-    a->version= get_bits(&a->gb, 16);
+    a->qscale  = get_bits(&a->gb, 16);
+    a->version = get_bits(&a->gb, 16);
 
-    a->last_dc[0]=
-    a->last_dc[1]=
-    a->last_dc[2]= 128;
+    a->last_dc[0] = a->last_dc[1] = a->last_dc[2] = 128;
 
-    for(a->mb_x=0; a->mb_x<a->mb_width; a->mb_x++){
-        for(a->mb_y=0; a->mb_y<a->mb_height; a->mb_y++){
-            if( decode_mb(a, a->block) <0)
-                return -1;
+    for (a->mb_x = 0; a->mb_x < a->mb_width; a->mb_x++) {
+        for (a->mb_y = 0; a->mb_y < a->mb_height; a->mb_y++) {
+            if ((ret = decode_mb(a, a->block)) < 0)
+                return ret;
 
-            idct_put(a, a->mb_x, a->mb_y);
+            idct_put(a, frame.f, a->mb_x, a->mb_y);
         }
     }
 
-    p->quality= a->qscale * FF_QP2LAMBDA;
-    memset(p->qscale_table, a->qscale, a->mb_width);
-
-    *picture   = a->picture;
     *got_frame = 1;
 
-    return (get_bits_count(&a->gb)+31)/32*4;
+    return (get_bits_count(&a->gb) + 31) / 32 * 4;
 }
 
-static av_cold void mdec_common_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     MDECContext * const a = avctx->priv_data;
 
-    ff_dsputil_init(&a->dsp, avctx);
-
-    a->mb_width   = (avctx->coded_width  + 15) / 16;
-    a->mb_height  = (avctx->coded_height + 15) / 16;
-
-    avctx->coded_frame= &a->picture;
-    a->avctx= avctx;
-}
+    a->mb_width  = (avctx->coded_width  + 15) / 16;
+    a->mb_height = (avctx->coded_height + 15) / 16;
 
-static av_cold int decode_init(AVCodecContext *avctx){
-    MDECContext * const a = avctx->priv_data;
-    AVFrame *p= &a->picture;
+    a->avctx           = avctx;
 
-    mdec_common_init(avctx);
+    ff_dsputil_init(&a->dsp, avctx);
     ff_mpeg12_init_vlcs();
     ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_zigzag_direct);
 
-    if( avctx->idct_algo == FF_IDCT_AUTO )
+    if (avctx->idct_algo == FF_IDCT_AUTO)
         avctx->idct_algo = FF_IDCT_SIMPLE;
-    p->qstride= 0;
-    p->qscale_table= av_mallocz(a->mb_width);
-    avctx->pix_fmt= AV_PIX_FMT_YUVJ420P;
+    avctx->pix_fmt  = AV_PIX_FMT_YUVJ420P;
 
     return 0;
 }
 
-static av_cold int decode_init_thread_copy(AVCodecContext *avctx){
+static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
+{
     MDECContext * const a = avctx->priv_data;
-    AVFrame *p = &a->picture;
 
-    avctx->coded_frame = p;
-    a->avctx= avctx;
-
-    p->qscale_table = av_mallocz( a->mb_width);
+    a->avctx           = avctx;
 
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     MDECContext * const a = avctx->priv_data;
 
-    if(a->picture.data[0])
-        avctx->release_buffer(avctx, &a->picture);
     av_freep(&a->bitstream_buffer);
-    av_freep(&a->picture.qscale_table);
-    a->bitstream_buffer_size=0;
+    a->bitstream_buffer_size = 0;
 
     return 0;
 }
 
 AVCodec ff_mdec_decoder = {
     .name             = "mdec",
+    .long_name        = NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"),
     .type             = AVMEDIA_TYPE_VIDEO,
     .id               = AV_CODEC_ID_MDEC,
     .priv_data_size   = sizeof(MDECContext),
@@ -273,6 +252,5 @@ AVCodec ff_mdec_decoder = {
     .close            = decode_end,
     .decode           = decode_frame,
     .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
-    .long_name        = NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"),
     .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy)
 };
diff --git a/libavcodec/metasound.c b/libavcodec/metasound.c
new file mode 100644
index 0000000..ae16ad0
--- /dev/null
+++ b/libavcodec/metasound.c
@@ -0,0 +1,388 @@
+/*
+ * Voxware MetaSound decoder
+ * Copyright (c) 2013 Konstantin Shishkov
+ * based on TwinVQ decoder
+ * Copyright (c) 2009 Vitor Sessak
+ *
+ * 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 <math.h>
+#include <stdint.h>
+
+#define BITSTREAM_READER_LE
+#include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "fft.h"
+#include "internal.h"
+#include "lsp.h"
+#include "sinewin.h"
+
+#include "twinvq.h"
+#include "metasound_data.h"
+
+static void add_peak(float period, int width, const float *shape,
+                     float ppc_gain, float *speech, int len)
+{
+    int i, j, center;
+    const float *shape_end = shape + len;
+
+    // First peak centered around zero
+    for (i = 0; i < width / 2; i++)
+        speech[i] += ppc_gain * *shape++;
+
+    for (i = 1; i < ROUNDED_DIV(len, width); i++) {
+        center = (int)(i * period + 0.5);
+        for (j = -width / 2; j < (width + 1) / 2; j++)
+            speech[j + center] += ppc_gain * *shape++;
+    }
+
+    // For the last block, be careful not to go beyond the end of the buffer
+    center = (int)(i * period + 0.5);
+    for (j = -width / 2; j < (width + 1) / 2 && shape < shape_end; j++)
+        speech[j + center] += ppc_gain * *shape++;
+}
+
+static void decode_ppc(TwinVQContext *tctx, int period_coef, int g_coef,
+                       const float *shape, float *speech)
+{
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int isampf       = tctx->avctx->sample_rate / 1000;
+    int ibps         = tctx->avctx->bit_rate / (1000 * tctx->avctx->channels);
+    int width;
+
+    float ratio = (float)mtab->size / isampf;
+    float min_period, max_period, period_range, period;
+    float some_mult;
+
+    float pgain_base, pgain_step, ppc_gain;
+
+    if (tctx->avctx->channels == 1) {
+        min_period = log2(ratio * 0.2);
+        max_period = min_period + log2(6);
+    } else {
+        min_period = (int)(ratio * 0.2 * 400     + 0.5) / 400.0;
+        max_period = (int)(ratio * 0.2 * 400 * 6 + 0.5) / 400.0;
+    }
+    period_range = max_period - min_period;
+    period       = min_period + period_coef * period_range /
+                   ((1 << mtab->ppc_period_bit) - 1);
+    if (tctx->avctx->channels == 1)
+        period = powf(2.0, period);
+    else
+        period = (int)(period * 400 + 0.5) / 400.0;
+
+    switch (isampf) {
+    case  8: some_mult = 2.0; break;
+    case 11: some_mult = 3.0; break;
+    case 16: some_mult = 3.0; break;
+    case 22: some_mult = ibps == 32 ? 2.0 : 4.0; break;
+    case 44: some_mult = 8.0; break;
+    default: some_mult = 4.0;
+    }
+
+    width = (int)(some_mult / (mtab->size / period) * mtab->ppc_shape_len);
+    if (isampf == 22 && ibps == 32)
+        width = (int)((2.0 / period + 1) * width + 0.5);
+
+    pgain_base = tctx->avctx->channels == 2 ? 25000.0 : 20000.0;
+    pgain_step = pgain_base / ((1 << mtab->pgain_bit) - 1);
+    ppc_gain   = 1.0 / 8192 *
+                 twinvq_mulawinv(pgain_step * g_coef + pgain_step / 2,
+                                 pgain_base, TWINVQ_PGAIN_MU);
+
+    add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len);
+}
+
+static void dec_bark_env(TwinVQContext *tctx, const uint8_t *in, int use_hist,
+                         int ch, float *out, float gain,
+                         enum TwinVQFrameType ftype)
+{
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int i, j;
+    float *hist     = tctx->bark_hist[ftype][ch];
+    float val       = ((const float []) { 0.4, 0.35, 0.28 })[ftype];
+    int bark_n_coef = mtab->fmode[ftype].bark_n_coef;
+    int fw_cb_len   = mtab->fmode[ftype].bark_env_size / bark_n_coef;
+    int idx         = 0;
+
+    if (tctx->avctx->channels == 1)
+        val = 0.5;
+    for (i = 0; i < fw_cb_len; i++)
+        for (j = 0; j < bark_n_coef; j++, idx++) {
+            float tmp2 = mtab->fmode[ftype].bark_cb[fw_cb_len * in[j] + i] *
+                         (1.0 / 2048);
+            float st;
+
+            if (tctx->avctx->channels == 1)
+                st = use_hist ?
+                    tmp2 + val * hist[idx] + 1.0 : tmp2 + 1.0;
+            else
+                st = use_hist ? (1.0 - val) * tmp2 + val * hist[idx] + 1.0
+                              : tmp2 + 1.0;
+
+            hist[idx] = tmp2;
+            if (st < 0.1)
+                st = 0.1;
+
+            twinvq_memset_float(out, st * gain,
+                                mtab->fmode[ftype].bark_tab[idx]);
+            out += mtab->fmode[ftype].bark_tab[idx];
+        }
+}
+
+static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb,
+                         uint8_t *dst, enum TwinVQFrameType ftype)
+{
+    int i;
+
+    for (i = 0; i < tctx->n_div[ftype]; i++) {
+        int bs_second_part = (i >= tctx->bits_main_spec_change[ftype]);
+
+        *dst++ = get_bits(gb, tctx->bits_main_spec[0][ftype][bs_second_part]);
+        *dst++ = get_bits(gb, tctx->bits_main_spec[1][ftype][bs_second_part]);
+    }
+}
+
+static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,
+                                    const uint8_t *buf, int buf_size)
+{
+    TwinVQFrameData     *bits;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int channels              = tctx->avctx->channels;
+    int sub;
+    GetBitContext gb;
+    int i, j, k;
+
+    init_get_bits(&gb, buf, buf_size * 8);
+
+    for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet;
+         tctx->cur_frame++) {
+        bits = tctx->bits + tctx->cur_frame;
+
+        bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
+
+        if (bits->window_type > 8) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits[tctx->cur_frame].window_type];
+
+        sub = mtab->fmode[bits->ftype].sub;
+
+        if (bits->ftype != TWINVQ_FT_SHORT && !tctx->is_6kbps)
+            get_bits(&gb, 2);
+
+        read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
+
+        for (i = 0; i < channels; i++)
+            for (j = 0; j < sub; j++)
+                for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
+                    bits->bark1[i][j][k] =
+                        get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
+
+        for (i = 0; i < channels; i++)
+            for (j = 0; j < sub; j++)
+                bits->bark_use_hist[i][j] = get_bits1(&gb);
+
+        if (bits->ftype == TWINVQ_FT_LONG) {
+            for (i = 0; i < channels; i++)
+                bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+        } else {
+            for (i = 0; i < channels; i++) {
+                bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+                for (j = 0; j < sub; j++)
+                    bits->sub_gain_bits[i * sub + j] =
+                        get_bits(&gb, TWINVQ_SUB_GAIN_BITS);
+            }
+        }
+
+        for (i = 0; i < channels; i++) {
+            bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
+            bits->lpc_idx1[i]     = get_bits(&gb, mtab->lsp_bit1);
+
+            for (j = 0; j < mtab->lsp_split; j++)
+                bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
+        }
+
+        if (bits->ftype == TWINVQ_FT_LONG) {
+            read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
+            for (i = 0; i < channels; i++) {
+                bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
+                bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+            }
+        }
+
+        // subframes are aligned to nibbles
+        if (get_bits_count(&gb) & 3)
+            skip_bits(&gb, 4 - (get_bits_count(&gb) & 3));
+    }
+
+    return 0;
+}
+
+typedef struct MetasoundProps {
+    uint32_t tag;
+    int      bit_rate;
+    int      channels;
+    int      sample_rate;
+} MetasoundProps;
+
+static const MetasoundProps codec_props[] = {
+    { MKTAG('V','X','0','3'),  6, 1,  8000 },
+    { MKTAG('V','X','0','4'), 12, 2,  8000 },
+
+    { MKTAG('V','O','X','i'),  8, 1,  8000 },
+    { MKTAG('V','O','X','j'), 10, 1, 11025 },
+    { MKTAG('V','O','X','k'), 16, 1, 16000 },
+    { MKTAG('V','O','X','L'), 24, 1, 22050 },
+    { MKTAG('V','O','X','q'), 32, 1, 44100 },
+    { MKTAG('V','O','X','r'), 40, 1, 44100 },
+    { MKTAG('V','O','X','s'), 48, 1, 44100 },
+    { MKTAG('V','O','X','t'), 16, 2,  8000 },
+    { MKTAG('V','O','X','u'), 20, 2, 11025 },
+    { MKTAG('V','O','X','v'), 32, 2, 16000 },
+    { MKTAG('V','O','X','w'), 48, 2, 22050 },
+    { MKTAG('V','O','X','x'), 64, 2, 44100 },
+    { MKTAG('V','O','X','y'), 80, 2, 44100 },
+    { MKTAG('V','O','X','z'), 96, 2, 44100 },
+
+    { 0, 0, 0, 0 }
+};
+
+static av_cold int metasound_decode_init(AVCodecContext *avctx)
+{
+    int isampf, ibps;
+    TwinVQContext *tctx = avctx->priv_data;
+    uint32_t tag;
+    const MetasoundProps *props = codec_props;
+
+    if (!avctx->extradata || avctx->extradata_size < 16) {
+        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    tag = AV_RL32(avctx->extradata + 12);
+
+    for (;;) {
+        if (!props->tag) {
+            av_log(avctx, AV_LOG_ERROR, "Could not find tag %08X\n", tag);
+            return AVERROR_INVALIDDATA;
+        }
+        if (props->tag == tag) {
+            avctx->sample_rate = props->sample_rate;
+            avctx->channels    = props->channels;
+            avctx->bit_rate    = props->bit_rate * 1000;
+            isampf             = avctx->sample_rate / 1000;
+            break;
+        }
+        props++;
+    }
+
+    if (avctx->channels <= 0 || avctx->channels > TWINVQ_CHANNELS_MAX) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
+               avctx->channels);
+        return AVERROR_INVALIDDATA;
+    }
+    avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
+                                                 : AV_CH_LAYOUT_STEREO;
+
+    ibps = avctx->bit_rate / (1000 * avctx->channels);
+
+    switch ((avctx->channels << 16) + (isampf << 8) + ibps) {
+    case (1 << 16) + ( 8 << 8) +  6:
+        tctx->mtab = &ff_metasound_mode0806;
+        break;
+    case (2 << 16) + ( 8 << 8) +  6:
+        tctx->mtab = &ff_metasound_mode0806s;
+        break;
+    case (1 << 16) + ( 8 << 8) +  8:
+        tctx->mtab = &ff_metasound_mode0808;
+        break;
+    case (2 << 16) + ( 8 << 8) +  8:
+        tctx->mtab = &ff_metasound_mode0808s;
+        break;
+    case (1 << 16) + (11 << 8) + 10:
+        tctx->mtab = &ff_metasound_mode1110;
+        break;
+    case (2 << 16) + (11 << 8) + 10:
+        tctx->mtab = &ff_metasound_mode1110s;
+        break;
+    case (1 << 16) + (16 << 8) + 16:
+        tctx->mtab = &ff_metasound_mode1616;
+        break;
+    case (2 << 16) + (16 << 8) + 16:
+        tctx->mtab = &ff_metasound_mode1616s;
+        break;
+    case (1 << 16) + (22 << 8) + 24:
+        tctx->mtab = &ff_metasound_mode2224;
+        break;
+    case (2 << 16) + (22 << 8) + 24:
+        tctx->mtab = &ff_metasound_mode2224s;
+        break;
+    case (1 << 16) + (44 << 8) + 32:
+        tctx->mtab = &ff_metasound_mode4432;
+        break;
+    case (2 << 16) + (44 << 8) + 32:
+        tctx->mtab = &ff_metasound_mode4432s;
+        break;
+    case (1 << 16) + (44 << 8) + 40:
+        tctx->mtab = &ff_metasound_mode4440;
+        break;
+    case (2 << 16) + (44 << 8) + 40:
+        tctx->mtab = &ff_metasound_mode4440s;
+        break;
+    case (1 << 16) + (44 << 8) + 48:
+        tctx->mtab = &ff_metasound_mode4448;
+        break;
+    case (2 << 16) + (44 << 8) + 48:
+        tctx->mtab = &ff_metasound_mode4448s;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR,
+               "This version does not support %d kHz - %d kbit/s/ch mode.\n",
+               isampf, ibps);
+        return AVERROR(ENOSYS);
+    }
+
+    tctx->codec          = TWINVQ_CODEC_METASOUND;
+    tctx->read_bitstream = metasound_read_bitstream;
+    tctx->dec_bark_env   = dec_bark_env;
+    tctx->decode_ppc     = decode_ppc;
+    tctx->frame_size     = avctx->bit_rate * tctx->mtab->size
+                                           / avctx->sample_rate;
+    tctx->is_6kbps       = ibps == 6;
+
+    return ff_twinvq_decode_init(avctx);
+}
+
+AVCodec ff_metasound_decoder = {
+    .name           = "metasound",
+    .long_name      = NULL_IF_CONFIG_SMALL("Voxware MetaSound"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_METASOUND,
+    .priv_data_size = sizeof(TwinVQContext),
+    .init           = metasound_decode_init,
+    .close          = ff_twinvq_decode_close,
+    .decode         = ff_twinvq_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+                                                      AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/metasound_data.c b/libavcodec/metasound_data.c
new file mode 100644
index 0000000..8aa53e5
--- /dev/null
+++ b/libavcodec/metasound_data.c
@@ -0,0 +1,15335 @@
+/*
+ * MetaSound decoder
+ * Copyright (c) 2013 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 "metasound_data.h"
+
+static const int16_t cb0806sl0[] = {
+      -417,   -225,    -84,     16,   -106,    -34,   -246,   -164,
+       112,     48,    -47,     36,    -65,    -68,   -172,  -1655,
+       -36,    140,     -3,     -2,     -2,      2,      0,      0,
+       178,      7,   -181,   -177,    120,    -64,   -129,     80,
+     -6826,    -38,    -25,    147,    148,    -13,    -25,    110,
+        21,     21,     -1,      0,      0,      0,      0,      0,
+      3319,    632,   -734,   -187,     40,   -249,   -155,     -1,
+      -173,     95,     28,     -2,     20,    -44,     35,    120,
+       -47,   -221,     -5,      2,     -7,      1,      0,      0,
+        63,    268,   -260,   -419,    187,    -75,   -228,    296,
+      -470,    177,   -515,    318,    124,    308,     92,    371,
+      3046,    362,     -1,     -1,    -10,      1,      0,      0,
+      -356,    -16,   -199,    117,    -75,     46,   -108,    -14,
+      -124,   -173,   4914,    -75,   -474,    105,     87,    190,
+      -183,   -208,      0,      0,      1,      1,      0,     -1,
+       162,     89,     49,   -314,  -2788,    265,   -263,     -3,
+     -3156,    316,    112,    128,   -333,   -138,   -114,   -141,
+      -287,   -234,     -1,      0,      0,      0,      0,      1,
+       733,    126,   -424,   -389,    642,    432,    134,   -251,
+       407,    -51,   -151,   -491,   -308,     91,     50,   3836,
+        87,    100,     -5,     -6,      0,      1,      0,      0,
+       304,   1727,     83,     -8,    216,    -81,   -189,    152,
+       -67,     15,    310,    -93,      6,    -37,     54,   -110,
+       -15,     78,      0,      0,      1,     12,      0,     -1,
+       129,   -198,      1,    -48,    -66,   -147,     30,    264,
+       -84,    102,     42,    126,      1,  -6451,    225,    -51,
+         8,    123,      0,     -1,      0,     -1,      0,      0,
+      -374,     66,   -256,    -80,  -1139,    303,   2002,   -199,
+       -98,    -98,    -39,    -76,    180,     15,   -456,    148,
+      -183,    118,     -2,      1,      0,      0,      0,      0,
+       151,     13,   -114,     65,   6156,     76,    -82,    -30,
+       -26,    163,     81,    167,    -83,   -101,     55,    -40,
+       161,   -793,     -8,      0,      0,     -1,     -1,      0,
+      -102,    -33,     55,   -131,    434,    108,     70,     68,
+        62,   1913,   -109,    235,    110,    124,    -25,    -58,
+       -76,     18,     -1,     -1,      0,      0,      0,      0,
+      -105,  -7322,     -9,     82,     53,    -43,     -5,     18,
+        90,     91,     20,    -34,     26,    -93,    -50,    -46,
+       -77,    105,      0,      6,    -12,     -6,      1,      0,
+     -1334,    980,   -163,   -351,   -514,    537,     62,   -300,
+        80,   -318,     14,  -3570,    -52,   -116,   -280,    540,
+       250,   -775,     -7,      0,      0,      0,      0,      0,
+       507,    317,   -417,   -236,  -2438,    -72,   -346,   2507,
+       302,   -185,     30,   1539,    205,     87,   -112,   -482,
+      -296,    132,     -1,      0,     -1,      1,      0,      0,
+       -64,   -208,   -159,      1,    336,    -62,    -14,     13,
+        81,    101,    382,     32,    116,     -5,    -41,     25,
+      -175,  -7829,      1,      0,      1,      0,      0,      0,
+      7551,     -7,     86,   -165,    -57,    -17,    183,   -207,
+        69,     54,    -99,    -25,    167,    -58,    107,    -81,
+       165,    172,      2,     -2,      0,      1,      0,     -9,
+        26,     28,     86,   -183,   -320,    -32,    116,    -53,
+       -49,    -15,    133,   -283,   -152,    576,   6630,    185,
+        44,     25,     20,      1,    -12,      1,     -1,      0,
+      -145,    -51,   -114,    -29,   -228,     78,   -409,    235,
+       147,     45,   -192,    177,    -91,     68,  -2572,    -52,
+        81,    181,     -5,     13,     -1,     -1,    -17,      0,
+       -65,    -23,    -28,      9,    242,     14,    -35,     88,
+        77,    -20,     37,  -7097,    -58,     51,    137,    126,
+       -90,    136,      0,      4,     -1,      0,      0,      0,
+      -266,    -82,   -205,    816,   -309,   3267,   1053,    369,
+      -216,   -302,     18,    168,    395,    273,    343,    243,
+       -98,    -53,      1,      0,      0,      1,      0,      0,
+       -65,    -76,   1850,   -991,   -454,   -535,   2927,   -145,
+       101,     23,     20,    234,    -74,     77,    114,      4,
+      -106,    527,    -11,      4,      0,      1,     -1,      0,
+       573,    -46,    207,   2640,   -956,     47,     26,    -10,
+       317,   -217,     -5,   -867,     -3,    213,     52,     53,
+      -428,   -175,      0,      0,     -1,     -1,      0,     -1,
+      -223,    -55,    135,    184,    313,      0,   2868,    245,
+     -3187,   -721,   -291,      9,   -265,   -120,   -105,    -36,
+       454,     55,     -1,     49,      0,      1,     -1,      0,
+      -291,     41,     84,    557,   -201,  -2300,    429,    283,
+        21,     -2,    132,    286,   -124,    149,    -14,    146,
+       320,   -298,      0,     -1,      1,     -2,      0,      0,
+       -86,  -3493,    131,  -3581,    185,     26,   -197,    -65,
+       -96,    147,    -53,   -150,    -35,    -35,    179,     68,
+      -157,      0,      0,      2,      0,      1,      2,     -1,
+       -22,   -218,     13,  -1447,   -400,    288,  -1295,      0,
+      -119,     69,    -56,   -139,    157,    -26,   -122,    -61,
+       -38,   -108,     -1,      1,      0,      0,      0,      0,
+      -229,   3335,    103,   -108,     10,   3008,   -712,     50,
+        27,    152,   -307,   -106,    148,    -77,   -178,    -46,
+         7,   -114,      0,     -9,      0,      0,      1,      0,
+       932,   -443,    311,    -75,     62,    -80,   -179,    459,
+      -232,   -160,      2,    169,    134,   -260,     41,   -149,
+        23,     92,     -2,      0,     11,      1,      0,      0,
+        16,    -90,   -574,   -171,    163,    261,   -299,   2994,
+        74,  -3818,   -396,   -171,     13,    -29,    -45,   -168,
+      -287,   -390,      1,      0,      0,     -4,      0,     -1,
+        89,   -702,   2223,    101,   -249,   2983,     36,   -333,
+      -382,    410,   -262,    185,   -146,     98,     -8,   -317,
+      -279,   -879,      0,      0,      0,      0,      4,      0,
+       -98,   -325,     75,   -229,    -13,    112,  -5743,    -34,
+       -89,    263,   -155,     80,    140,    -50,     33,    143,
+       -60,    -77,      1,     -2,      0,     -1,      1,      0,
+        52,   -576,   -543,  -1142,   -947,   -184,    449,    -71,
+       -75,   -156,  -3412,    -50,   -487,    307,    663,  -1000,
+      -415,  -2348,     -7,     -1,     -1,      0,      0,      0,
+        64,      3,    -35,     11,     14,   -198,     -2,  -8042,
+       140,    -11,    -93,     29,    -65,    330,     34,    110,
+       -19,   -137,      2,      0,      0,      0,      0,      0,
+      1236,    303,   2681,    234,   -217,   -406,   -395,   -380,
+       247,    349,   -101,    -33,    370,    -39,    139,     59,
+        18,     24,      0,      0,      0,      0,      0,      0,
+       166,    -21,  -5392,   -117,   -296,    114,    230,   -255,
+       131,    -53,     13,    -45,    200,      7,    -56,     87,
+        46,    223,    -59,      0,     -1,      0,      0,     -1,
+       214,   -511,    175,    204,   -123,    -47,   -440,      6,
+        23,     92,   -355,     80,  -4885,   -238,    -37,     78,
+      -218,    175,      0,      2,      0,      0,      0,      0,
+      -146,     74,    -13,     -4,     27,    -45,     51,     81,
+       -80,     53,    -18,    173,   -146,    -64,     -8,   8192,
+        79,     15,      0,     -3,      0,      1,      0,      0,
+        -3,    -16,    -28,    288,    -61,      4,   -187,      6,
+        -5,    -14,     77,    -12,    -53,     16,    -41,     -7,
+       -10,     -2,      7,     -1,     -9,      1,      0,      0,
+      -285,    -35,     -8,    221,    -68,    114,    135,     -8,
+      -203,   -181,    -91,   2043,    -58,    127,    201,    111,
+        46,   -344,    -11,    -49,      0,      1,      0,     -1,
+      -160,   -186,     58,   4761,    289,     51,   -145,     51,
+       -32,     71,     62,    175,    -13,    181,    203,    141,
+      -200,    106,     -1,      4,     -2,      0,      0,      0,
+       803,    -76,    -96,   -940,    300,   3429,    -84,   3037,
+       262,     -9,    -39,    120,   -629,   -309,    233,   -374,
+       398,    894,    -12,      1,      1,      1,      0,      0,
+      -282,   2525,    -31,   -176,  -2473,     53,    102,   -610,
+       180,   -145,     42,    -51,    223,     27,    -69,    727,
+       -14,    -51,      0,      0,      0,     -3,      0,    -40,
+       214,     72,     41,      1,    190,     78,   -228,   -235,
+       105,  -4619,   -140,    -46,     -7,     49,      9,    -19,
+       137,     -2,      9,      1,      0,      0,      0,      0,
+      -142,   -262,     29,   -142,     39,    -39,    -92,     95,
+        50,   -282,      2,   -106,    114,      8,     35,     78,
+      -121,   2589,      1,     -4,    -10,      1,      1,      0,
+      -192,     59,    287,    400,    -67,  -6989,   -301,    446,
+       115,      7,     33,    -60,    111,    102,      8,    206,
+        46,    -31,     -1,     -1,     -2,      0,      0,      0,
+      -104,    332,   -223,   1066,   -188,   1270,   -222,    309,
+      -296,    259,    780,   -460,  -1914,    218,   -556,    210,
+      2962,    130,      1,     -2,      2,      0,      1,      0,
+      -320,   -365,   -266,    822,   -119,    824,   -312,     58,
+     -1857,    235,     48,  -3985,    118,   -307,   -703,   -931,
+      -560,    105,     -2,     -3,      0,      0,      0,      1,
+       156,    -48,    187,    214,   -212,    180,    342,    373,
+      1973,    128,     -5,    146,    -40,    -11,     71,    -60,
+        76,     17,      0,      0,     -1,      2,      0,      7,
+       214,     63,    274,   2876,    -65,    314,    400,    344,
+       140,     39,    193,   -226,    124,  -3177,     68,     46,
+       -60,   -317,      2,      0,     -1,      0,      7,      0,
+      -160,    118,    233,    239,   -465,     96,    253,   3178,
+       -88,    299,    368,   -220,    197,    397,   -353,   -463,
+      -202,   -103,     -4,      0,      0,      0,      0,      0,
+       687,   -448,   -749,     87,    -35,    112,    309,    -33,
+       -16,     88,    141,     63,    -51,    274,   -113,    -76,
+        46,   -273,     -1,      1,      0,      1,      0,      1,
+      -298,   -206,    670,    303,   -451,   -277,   -493,    404,
+      -173,    284,    148,    626,   -322,   -296,    -68,   3044,
+      -442,   1138,     -7,      2,      0,      1,      0,      0,
+     -1338,     18,   2862,    223,    250,    260,    144,    259,
+       -38,   -647,    602,   -160,     75,     -5,     -8,     34,
+       237,     50,      2,      0,      1,     -1,     -1,      0,
+      -412,   2153,    933,    478,    768,    186,   -424,   -657,
+     -3458,   -443,    294,    224,   -468,    -58,   -120,  -1565,
+       211,   -420,      0,      0,      1,     -1,      0,      0,
+       198,    227,   -112,    350,    297,   -303,    108,   -192,
+       153,     32,  -2717,   -111,  -1093,   -200,    476,    326,
+      -271,    627,      0,     -4,      0,      0,      0,     -1,
+       462,   -616,    126,    316,  -2413,    204,   -350,  -3549,
+      -263,   -386,   -112,    483,  -1339,    636,     70,   -531,
+        96,     38,      8,     -1,      0,     -3,      0,      0,
+      -310,  -1128,    616,   -339,   -168,   -124,   -905,   -151,
+      -383,     76,    137,    -44,   3689,   -388,    184,   1799,
+      -102,   -930,      6,     -1,     -1,     -1,      0,      0,
+      -284,    280,     39,   -728,    143,     15,    181,    798,
+       382,     10,   2267,    -12,  -3582,    -27,    357,    514,
+      -565,   -121,      0,     -1,      0,     -9,     -1,      0,
+       429,    -16,   2993,  -2903,     47,   -136,     30,    792,
+      -327,   -347,    -69,    -50,    -93,   -223,   -438,    158,
+       203,   -475,      0,     -4,     -1,      2,      0,      0,
+     -3465,    415,   -963,    252,    397,   -945,   -448,   -231,
+      -130,    673,    504,     55,   -355,    221,     29,    167,
+       -19,    134,     -1,     -1,     -4,      0,    -14,     -2,
+        44,    433,   -535,   -216,   2485,     33,     19,   -100,
+      -185,   -171,     91,    336,   -208,    140,     -3,     46,
+       -67,   -116,     32,      0,      5,      3,      0,      0,
+       220,     91,    -65,    -15,   -169,    217,   -183,   -169,
+       -47,    181,   -272,    138,   -166,    110,     -9,     41,
+     -6957,     33,     -5,     -2,      1,      1,      0,     -1,
+       164,  -4062,   -109,    230,   -220,   1748,  -1338,   -246,
+      -242,    -98,    300,    217,   -202,   -130,    157,     -3,
+       -19,   -453,      0,      2,      0,      0,      0,      0,
+};
+
+static const int16_t cb0806sl1[] = {
+        75,     87,    -31,    607,   -132,   5963,   -262,    494,
+       134,     -4,    141,     19,    225,    229,    239,     93,
+       -20,   -189,      2,      0,     -3,     -1,     -1,      0,
+       214,   -206,    877,     83,   -588,     83,    132,     78,
+         5,    -85,     66,    -24,     47,    -11,     25,     26,
+        -3,     46,      2,     -5,      0,      1,     -1,      0,
+      -113,    295,    -81,     74,    223,    -50,    -93,  -5671,
+       -28,    115,    256,   -228,    -31,   -539,    300,   -278,
+       -59,    426,   -110,     -1,      1,      1,      0,      0,
+       -95,   -116,    266,    176,    761,     -3,     90,    -91,
+        98,   -209,   -414,    -27,    -56,     26,    -76,      6,
+       -32,   4634,      1,      0,     -4,      0,      0,      0,
+       177,    147,   -236,    -93,  -7925,     11,   -111,    -74,
+        36,    176,    352,     88,    112,     16,    144,   -110,
+        91,    329,     -1,      2,      0,      1,      0,      1,
+       119,    304,    -94,   -422,    113,    129,    -70,    155,
+       247,   -116,   -139,    327,   -355,     77,    143,  -5362,
+        27,   -377,     -1,      7,      2,      1,      0,      0,
+       179,    127,   1500,   -324,    -15,    673,    184,  -1382,
+       167,   1833,  -3058,    200,  -1203,    459,  -1905,   1020,
+      -259,   -120,     10,     -4,      0,      1,      0,      0,
+       995,   -112,     37,   -160,    -21,  -4011,    172,    228,
+      -210,     80,   -131,      1,     20,   -128,   -252,   -288,
+      -132,    337,     -1,      0,     -1,      0,      1,     -1,
+       -60,     61,    197,   -185,    -40,  -2951,   -592,    -57,
+       210,  -3248,   -226,    -44,    391,   -167,     -7,    219,
+       -15,    172,      0,     -1,      1,      0,      0,      0,
+       106,    -70,   -291,    192,     45,    162,     37,    143,
+        91,     21,  -7032,     12,   -173,    -30,      1,    259,
+      -286,    387,    -36,      0,      0,      0,      0,      0,
+     -1593,   -210,     83,     47,    194,     61,     85,   -182,
+       -23,     40,    -74,     22,     12,    216,     59,   -165,
+      -163,   -159,     -8,      0,      0,      2,      0,      0,
+        -3,    182,    -80,   2068,    702,    115,   -164,    -85,
+        21,   -124,   -191,   -113,    263,    138,   4235,     37,
+       204,   -436,      0,     24,      1,     -1,      0,      0,
+       147,     83,   -177,   -168,   -609,     -9,    -16,    -46,
+       127,    120,    -25,   3435,     51,     31,     49,    366,
+        31,   -129,      1,    -32,      0,     -1,      0,     -2,
+       295,    158,    116,     11,   -280,    471,    169,     29,
+     -2589,    338,     32,    299,    172,   -187,    -32,    437,
+       -38,    359,     -1,     -1,      1,      0,      0,      0,
+       243,    413,    -29,  -4774,    187,     12,   -117,    168,
+      -114,   -208,    -55,      5,      0,    -31,    436,    545,
+       -45,    272,      0,     -4,      0,      0,      1,      0,
+       127,     38,   6620,    -33,   -103,     34,     84,    -35,
+        30,   -131,     -8,    -79,   -126,    -98,     17,    -75,
+       -31,   -176,     14,     -1,      0,      0,     -1,     -1,
+       273,   -219,    176,    -83,    187,    -36,      1,   2639,
+       158,   3812,    127,   -233,    175,    310,    148,    387,
+       -14,    308,      0,     -3,      0,      0,      0,      0,
+      3321,   -447,    153,   -128,    254,   -275,     79,   -181,
+        17,    146,     61,     46,    -48,    253,     51,    -17,
+         1,      1,      0,      1,     -1,     -2,      0,    -13,
+       791,   -130,     40,     78,    -64,   -179,     42,   -455,
+       422,    112,    -19,  -4499,   -113,   -341,     52,     69,
+        67,    254,     -6,     -1,      4,      0,      0,      1,
+       -98,   -976,     68,   1563,    228,   1018,    458,  -1020,
+       411,    249,   -627,   2321,    738,   -460,  -1469,    362,
+       884,   -261,      0,     -1,      1,      1,      0,      0,
+      -601,    378,    -71,     61,   -160,    800,   -386,   -773,
+       303,    -53,    248,    -22,     59,  -3809,    -61,    102,
+       -45,    395,      0,      0,     28,      0,    -12,      0,
+       717,   -424,    499,    296,    -15,     11,   2732,   -103,
+      -119,   -116,    107,    -50,    462,     73,    -82,     75,
+        41,    131,      0,      3,      1,     -1,      0,      0,
+      -134,    109,     48,  -1847,   -205,     -6,     20,   -203,
+       136,    197,    113,    -77,   -124,    -50,    184,    225,
+      -175,   -295,     -1,     -1,     -6,     -1,     -1,      0,
+       -59,  -2017,   -193,   -237,    226,    630,   1950,     -2,
+       179,  -3666,    -34,    140,     88,    157,     51,     81,
+      -263,   -169,      1,      0,      0,      0,      0,      0,
+       229,    -14,  -1590,   -123,    162,     63,   -224,   -332,
+       119,   2931,     21,    -48,    406,     15,    320,    -51,
+        64,   -228,     -9,     -1,      0,     -1,      0,      0,
+      -453,     84,   -320,   -654,     -4,    -91,    -61,    558,
+       -61,   -233,     31,   -224,   -105,     63,     86,   3771,
+       162,  -1535,      3,     -3,      1,      1,      0,      1,
+     -1992,   -279,    -59,  -3048,  -1696,    102,   -168,    194,
+       172,   -142,     55,    134,    116,   -146,    -29,   -287,
+       102,    265,     -3,      1,      0,      1,      0,      0,
+       -96,     46,    -16,   2474,    -58,   -712,    -25,   -294,
+       187,     22,    -39,   -102,     62,   2666,   -237,     -1,
+        32,    -41,      0,      0,      0,      0,      0,      0,
+      -282,    -25,   -198,   -862,   -127,   -379,   -210,    -20,
+        45,    -79,  -2805,   -364,    575,    106,    215,   -410,
+       -76,    511,     15,    -44,     -1,      1,      0,      0,
+       329,    224,    130,     43,     -1,   -255,    -51,   -297,
+      4529,     52,    186,    757,    -68,    -89,     46,    250,
+        46,    -79,      5,      1,      0,      1,      0,    -19,
+        79,     74,     65,    256,    260,    492,   -106,   -217,
+      -357,     20,    166,    233,    132,    165,     18,     -1,
+      4445,    -22,      5,      3,     -7,      0,      0,     -6,
+      -922,   2156,    269,   1385,    235,   -206,    -94,    130,
+       112,    145,   -126,    166,      1,     45,     83,     36,
+      -153,   -255,      0,     -1,      0,      0,      1,      0,
+       241,   -237,   -117,   -510,     85,      7,  -4418,     30,
+        94,    -92,     99,    -71,    140,   -265,    149,     69,
+       286,    104,      0,     -2,      1,      0,      0,      0,
+      -165,     22,   -245,     29,     50,    145,    -53,   1641,
+       -40,   -128,   -112,   -190,     47,     53,   -247,    -50,
+        88,     39,      1,     -1,      0,      0,      0,      0,
+      -288,    130,     88,   -132,   4055,     -7,     55,   -105,
+       277,     81,     69,    -66,    -53,     52,    -56,     90,
+       160,    386,      1,     -4,      0,     -2,      0,      0,
+       107,    124,    -39,     40,     25,     -6,   -248,    -81,
+        70,    -13,     46,      5,     20,     24,     -5,     -2,
+       -41,    -34,      1,      1,     -8,      0,     -4,      0,
+       -61,      1,    457,    454,    768,     89,    640,     61,
+        66,   -360,  -2727,   -155,   -370,    -44,   -292,    570,
+        34,  -3209,     -5,     -1,      1,      0,     -1,      0,
+        22,    -82,    -20,   -125,    -91,     98,   7843,     25,
+        -2,    -31,      2,    -52,    -73,    -25,     31,    -35,
+        -6,   -114,      1,     -1,      2,      0,      0,      0,
+       217,  -5202,     86,    -76,    -76,    109,    389,    -95,
+      -253,    124,    130,     58,    190,    -44,    -67,   -142,
+        54,      6,     -1,      1,      1,      1,      0,      0,
+      -183,    547,   -200,    348,    372,    437,    425,    547,
+      -457,    388,     87,     38,   -522,   -210,   -556,     41,
+     -2979,    -17,      7,     -4,      6,      0,      0,      0,
+       189,    196,    240,    -75,     46,    -50,    101,   -160,
+       -16,   -223,     92,     71,  -7633,     78,     90,     69,
+       190,    -75,      2,      1,     -2,     -1,      0,      1,
+       205,   -433,   -267,   -175,   3068,   -210,   -514,    330,
+     -3099,   -273,    155,    132,   -306,    361,    316,    -53,
+      -421,   -125,     -3,      0,    -11,      0,      0,      0,
+       179,    -38,    151,    -36,    215,   -102,   -145,    139,
+        50,    200,    383,     37,   3102,    -27,      9,   -157,
+       -68,    367,      1,      1,      0,      0,      1,      0,
+       -50,    177,    -24,     24,    119,      4,     76,     99,
+      -111,  -7367,     26,     51,    -11,   -146,   -125,    -48,
+        54,     50,      1,      0,      0,      0,     -1,      0,
+       -71,    -16,   -184,    -61,    -36,   -151,     79,   -128,
+      -102,    135,   -228,    190,    -79,    -10,   -176,   -113,
+      1008,   -856,    -13,     -4,      8,     28,      0,      1,
+     -4909,    -93,   -167,   -141,     51,   -203,     71,   -199,
+       -49,    106,   -142,    -94,    126,   -225,    158,     36,
+       269,    159,      0,      1,      1,      0,      0,     -5,
+       -61,    -79,    -20,    306,     67,   -621,   1774,    346,
+      -442,    125,    305,   -170,     55,  -2537,   -103,    118,
+        87,    505,     16,     -7,     -2,      0,     20,      0,
+        35,   -154,   -158,    224,    -36,   -344,     79,   4232,
+       234,   -219,    -71,    204,   -484,   -131,   1153,     23,
+       111,    499,      5,      0,    -17,      0,      0,      1,
+      1135,  -3469,   -489,   2572,   -450,   -432,   -358,    -34,
+       -78,    -10,   -775,     17,   -131,   -154,    218,     82,
+      -312,    279,      1,      0,      1,      0,      0,      0,
+        96,    230,     18,     47,     -5,   -102,    646,   -122,
+        35,    -81,    183,    171,  -1479,    201,     84,    -24,
+       143,    302,      1,      5,      0,      0,      0,      0,
+       -34,    -48,     89,   7789,    -85,    -27,    -56,     46,
+        39,     30,     98,    -40,    138,   -147,    104,    -35,
+       -41,   -151,      1,      9,      1,      0,      0,      0,
+      -140,  -1970,   -170,    273,    226,     33,   -324,    -38,
+        11,    188,    603,    188,   -183,     98,    -58,    -67,
+       -63,      7,      0,      0,      0,      0,      1,      0,
+       384,    899,    493,    765,  -1062,    646,    275,  -2699,
+        93,    796,    120,    -25,    177,    -85,    721,   -189,
+      -295,   -436,      0,     -1,      0,      0,     -1,      0,
+      -358,    117,  -2435,    325,  -3137,   -158,     23,     97,
+         6,    204,    288,   -426,    156,     22,   -101,    171,
+       -56,    235,      0,     -1,      0,     -1,      0,      0,
+       656,   3878,   -286,   -383,     75,    -50,    114,   -377,
+      -105,    106,    154,    -30,   -204,   -105,    171,    -56,
+       230,   -587,      0,      1,      0,      8,      1,     -1,
+       -58,    177,     -7,     45,   -159,    405,     45,     84,
+      -206,     77,    277,   -259,    121,   3719,    140,     79,
+      -202,    843,     -8,      0,     -1,      1,     -2,      0,
+      -248,    560,   2651,    -49,   -625,   -147,  -2416,    119,
+       -70,     87,    137,     18,   -401,   -147,   -598,   -150,
+       239,  -1004,      7,      3,     13,      1,      1,      1,
+       276,    342,     97,    600,    230,     95,    213,    159,
+      -259,    -25,   -176,   3360,   -283,   -325,    -37,  -2626,
+      -151,    178,     -1,    -18,      0,      0,      0,      0,
+      -233,    237,    -78,    290,   -284,    141,    -20,    146,
+        58,    -21,     73,    -35,   -101,    -23,  -4068,   -116,
+        49,   -196,     -5,     -2,      0,      1,     -1,      0,
+      -292,   -195,     51,   -714,    172,     44,   -119,    134,
+       168,    107,    -74,  -2379,    308,    173,   -252,  -3470,
+      -135,    641,    -10,      0,      0,      1,      0,      0,
+       146,   2060,    -84,   -164,   -247,     26,  -1724,    216,
+       226,  -2499,    312,    -66,    850,     41,     -1,     20,
+     -1339,    411,      0,      0,     -1,    -12,      0,      0,
+       921,     17,  -3510,   -119,    325,     34,    -97,   -205,
+         3,   -188,    252,     91,      0,   -135,    -76,    208,
+       199,   -202,     -1,      1,      1,      2,      0,     -1,
+       -88,   -461,    319,   -963,    266,   1540,    643,  -3424,
+        76,  -1058,    501,    342,    297,    268,   -158,   -103,
+        26,    -30,      0,     -1,     -1,      0,      0,      0,
+       211,    245,    183,   1579,    106,     26,  -3450,    -22,
+     -1053,   -266,   -736,    113,    475,   -241,    117,    -85,
+      -492,    372,      0,      1,      1,      0,      0,      0,
+};
+
+static const int16_t cb0806ss0[] = {
+      -381,  -1638,  -8192,      5,    983,  -1481,    -20,   -719,
+      -238,    767,    571,   -200,    754,    460,   1678,   1376,
+      -155,  -1998,    294,   -455,     80,      2,     26,      3,
+        10,     25,   -931,  -1098,  -1166,  -3221,  -1995,    702,
+       104,  -2429,  -2270,   1372,   2326,    -37,  -1492,   1692,
+       644,  -1283,    363,    624,   -483,    -15,    346,     -6,
+         2,      0,      1,      3,      2,  -2429,  -8192,   -956,
+      1190,    706,   -955,    367,    959,   -194,   -723,  -1104,
+       375,    554,   -962,   -229,     66,    368,     18,   -150,
+        56,    968,    -15,      0,     -1,     -5,      0,      9,
+      -250,   -720,   1910,    827,    198,   -645,   2021,     32,
+     -1972,   -705,    441,    373,    800,  -2293,   1747,   1504,
+      -537,  -1731,  -1192,   1597,  -4031,     24,      0,     -2,
+         1,      1,      1,   -131,   1594,   -153,   1127,   2732,
+       469,   -558,    -11,   1190,    115,   -933,   1988,   1841,
+     -4530,   1385,    571,   2399,   1709,    -63,  -3663,  -2681,
+        57,     -4,     11,     -4,      0,     -3,    426,  -4257,
+      2755,    -76,  -1667,   2450,   -373,   3375,    -91,   -232,
+       511,    648,    886,   1182,   1667,     65,  -3029,   -579,
+       865,   2186,   2911,    537,      0,      2,     -3,      0,
+         7,    585,   8192,  -2855,   8192,   5527,  -5491,  -1926,
+     -4231,  -1204,   1953,  -1193,    191,   3278,  -1726,    259,
+     -2794,   4205,   4315,  -6121,   -606,  -1922,   3666,   -324,
+      -238,   -313,   -720,  -1447,   -539,   -794,   3151,  -1726,
+      3444,    876,    584,   -671,   -497,    407,    909,  -2183,
+      2575,    246,   -673,    270,    824,   1784,   -201,   7329,
+       589,    -70,     -1,      4,     -5,     -3,     -8,   -417,
+       382,   2786,   -972,    520,   1154,    886,    521,   6032,
+      -687,   3791,   -522,  -1226,    608,    428,    891,  -1524,
+     -1015,   1147,   1278,    559,     -6,      3,      0,      6,
+         2,     -3,    115,   3586,  -2847,     95,    460,   2832,
+      2326,  -1665,   1720,    453,    965,   1154,    452,  -1721,
+     -1375,   -269,   2138,  -2032,     55,   -674,   -870,   -124,
+         0,      5,      0,     -5,     -3,   -283,   1077,   2604,
+      1270,  -1082,  -1753,   6840,  -2502,    988,  -1790,   1378,
+      1231,    438,  -1188,    286,    540,   -138,   1054,   -111,
+     -2321,     74,     56,     -3,     -2,      0,    -32,      5,
+      1539,  -1399,   7413,   -903,  -1698,   1781,   -255,   -466,
+     -1436,   3419,   1916,    852,    590,  -1126,  -1617,  -1309,
+     -5560,   -241,   3363,  -1225,   2682,    620,     -6,     58,
+         2,   -186,    -17,  -2959,    619,   2228,  -2627,  -3119,
+       730,   3716,   -538,   -101,  -1863,   -516,    142,  -2384,
+     -1514,  -5506,   -825,    514,    714,    746,  -2790,    569,
+      -425,      4,    -68,     70,     24,     12,    817,   -276,
+     -3363,  -2942,    103,   -581,   -925,    651,    561,     43,
+       434,    712,   -541,  -2042,  -1291,   -453,   -443,  -4312,
+     -1344,   1277,    605,     -4,      0,     -1,     -1,      1,
+         2,   -930,    276,   3219,   -404,   -944,   -497,    840,
+       278,    -98,  -1432,  -1136,  -1975,  -1863,  -1102,  -1446,
+       938,    693,  -5186,     -1,   1085,  -2275,      1,      1,
+        -1,     -1,     -2,      3,  -1194,   -312,  -1257,   1973,
+      1570,  -1703,  -1637,    639,   -855,   1925,    970,    604,
+      1313,    780,  -5170,   -603,    220,   -731,   2952,   -872,
+       166,     30,      0,     -2,     -1,      3,     -1,   -743,
+       504,   1363,   1436,   1632,   -634,   -709,  -2346,     87,
+      1149,   3468,   2132,   3028,  -1039,    -92,   2087,   -990,
+      -301,    966,   -773,  -1057,     42,      0,     -2,      0,
+         2,      2,    252,    217,   3625,  -2323,    212,   -381,
+     -1121,   1664,   -307,   1680,   2193,  -1854,   -187,  -3100,
+       254,   -673,    595,   1995,    669,   -687,   -509,     13,
+         0,      8,     -3,     11,     -3,   -552,    -87,      6,
+      2933,   -267,  -1392,     40,    644,     32,   2966,  -1386,
+     -2480,   -956,   1160,   1399,   1049,   3902,  -2092,   -525,
+      1724,     69,    -33,      0,     -2,      0,      2,      2,
+      -452,  -4739,  -3237,   -510,   -598,  -1397,    855,   1573,
+      2143,    -79,  -1546,    -17,   -973,  -2400,   1689,    133,
+     -1213,    784,    726,    916,   -388,   -390,      1,     -1,
+        -3,     -1,      0,    170,   -205,  -2905,   8192,   -465,
+      3119,   4407,   -709,   -403,    859,   -373,  -1301,  -1397,
+      -750,    -88,    277,  -2097,   -222,   -134,    -88,  -1189,
+       974,    -56,    -57,    -83,    -21,    102,    626,   -114,
+     -2304,    979,  -1836,   -868,   1261,   2226,   -261,    579,
+       983,    655,  -2578,   1803,    117,  -1128,    365,   3971,
+      3539,    -21,   -790,    -62,      2,      3,     23,     -3,
+        31,   1273,   3212,  -1617,   4116,   -281,    725,   -284,
+      1079,    293,  -3759,   2581,  -1617,   -259,    -19,  -1999,
+      3040,  -3077,  -1522,   1056,    -92,    897,    243,     -1,
+        36,    -19,    -10,    -46,    231,   1129,    363,  -1978,
+      -882,  -1788,    319,   4807,  -1707,  -1379,  -1465,   2327,
+      -827,   -681,    410,  -1816,  -2507,   1036,    740,    730,
+      -687,    100,     -1,     -1,     -1,      1,     -4,   -276,
+       303,  -2331,  -2912,  -1864,  -3694,    412,  -1218,   1642,
+      4448,    658,   -213,    872,   2867,    227,    868,   -590,
+      2293,   1759,  -1666,  -1585,   -140,      1,     -3,     -1,
+        26,    -10,   -287,    898,  -2442,   3997,  -1655,  -1341,
+       -56,    689,  -1869,    572,  -2044,    616,  -2603,   -278,
+      2987,   2397,  -2055,    247,    128,    598,   1732,   -146,
+         0,      3,     -1,     -3,      5,    842,    597,    779,
+     -1529,   -802,   2142,  -1668,   2339,  -3550,  -2651,   1733,
+     -1531,    -46,    600,    618,   -867,   -665,   1524,    392,
+     -1386,  -3279,     45,      0,      9,     -7,     -3,     -8,
+      -224,  -2632,   -147,   -505,   2223,   1773,   1799,  -1696,
+       194,  -1186,   -543,    775,  -1171,   5491,  -2319,  -3193,
+      -313,   -355,   -133,  -1097,    125,    -22,     -2,      2,
+         1,     -3,    -10,   -354,  -1447,   -662,   -313,  -4302,
+      3888,   -121,   -323,   1112,   -801,  -1513,   -814,  -1646,
+      -616,  -1207,    347,    483,    670,    900,    -35,   -885,
+        14,      1,      0,      1,     -2,      7,   -432,   -486,
+     -1539,    785,   4853,    904,    925,    895,  -1223,  -2464,
+      3395,   -506,   -808,    207,    197,    874,   -928,   1347,
+      -107,   1512,   1063,   -182,      1,     -4,     -1,     -6,
+         3,  -1236,  -1047,    774,     26,   -630,    863,   1055,
+     -2632,  -1187,   -534,   -619,  -1079,  -2574,  -2037,    658,
+      1229,   -262,   2702,  -3393,  -2187,   1764,     66,      0,
+         7,      0,      7,     -3,    677,   -444,  -2111,  -5256,
+     -4485,  -1667,   2077,   1613,   1483,  -1520,   1600,   1767,
+      1148,   2054,   1676,   1866,    783,  -2199,    765,    568,
+      2779,   -683,      4,     17,      0,    -32,     15,     45,
+       228,  -2445,    752,   2510,  -1657,  -1039,    113,   1107,
+     -1054,  -1765,  -1245,  -2527,    589,    455,    328,    640,
+      -579,   2370,   1313,   -540,     31,      1,     -1,     -4,
+         2,     -3,   -235,   -560,    455,   3809,    102,    403,
+       -21,   1844,    402,    148,    -32,   5573,  -3765,   -265,
+      -718,   -399,   -349,    366,  -1105,     91,   1881,     34,
+         1,      1,      5,      0,      9,    289,  -1146,    795,
+     -2504,    412,   1156,   -302,   -946,   2063,  -2569,   -273,
+     -1434,    141,    642,   -631,   4856,  -1008,    169,    -40,
+       191,  -2293,    -86,      6,      1,     -2,      0,      1,
+       139,   1955,  -1111,   -944,    140,  -1074,   1071,  -1312,
+      -541,    664,   1801,   -892,   1605,  -1750,   -654,   -680,
+     -8102,    120,    -24,   1014,   -351,   -120,      0,     -2,
+         1,     -1,     -1,   1038,   5199,    779,  -1195,    128,
+       462,    184,   3705,  -1292,  -2247,  -2481,   2610,   4396,
+      4161,   4039,   1111,    838,    188,   -571,   2811,  -1915,
+     -1909,     13,     99,    -20,     -2,     11,    395,    155,
+      2667,   -202,  -2639,   1303,   -912,  -1734,   1097,   -583,
+      3532,   -218,  -1514,  -3881,    378,    -46,  -1189,   -957,
+     -3010,   -743,   -648,     15,      1,      3,      3,      4,
+        -4,    330,    198,   -275,   -677,  -8192,   -629,   1953,
+      -783,    592,    926,   1487,    -39,  -1002,   1134,   1560,
+       -27,   -118,  -1363,   -360,   2163,    442,     92,      1,
+         1,     -2,      5,      1,   -670,    326,   2773,   1346,
+       -26,    327,    184,  -1091,   -121,    576,  -1324,    212,
+      -645,    860,  -2111,   -493,  -2119,    316,   -688,    475,
+      -652,    -33,      0,      1,      2,      0,     -3,     92,
+       170,   6224,   2162,    761,  -1994,   2176,   1692,  -1773,
+       561,   -966,   3406,    -20,   -593,    574,   -681,   1121,
+      -335,   -412,  -2651,  -4712,    -79,      1,      2,     -1,
+         4,     -6,    932,  -2579,    344,  -2614,   1119,   6623,
+      -314,  -1068,    338,   1977,  -1375,  -1338,  -1996,   1310,
+       118,   -500,   -393,    622,  -1798,  -1232,      3,    -75,
+         0,     17,      0,     -2,     -9,    715,   8135,    400,
+      3748,   2156,   1882,    772,   2728,   -403,   -775,   2110,
+      1603,   -766,  -2592,    767,   -618,   4727,    668,   2280,
+     -1157,   1246,   -794,    -14,     -2,      2,      5,     16,
+      -107,    642,  -1806,   -158,  -2447,    309,   -764,   2313,
+      -101,   -766,    209,   -691,   2001,    268,   -273,    615,
+       803,   6062,   -434,   1287,   -543,     -3,      0,      0,
+         1,      1,      0,    503,   -598,  -2043,  -1160,   1074,
+      1255,   3269,   1405,   1182,    197,   3098,   -138,   2326,
+      -244,   -772,    901,   -225,    337,    -65,   -536,   -331,
+        15,      2,     13,      8,     -3,     20,    -32,    -52,
+     -1012,    232,   1502,    -17,  -1574,   -741,    -57,    164,
+       -22,     74,   -181,   1616,    296,  -1483,   1387,   -357,
+     -5380,   -322,  -1346,      6,     -3,      2,     -3,      1,
+         0,   -392,   -811,   -650,   -485,   3038,   2750,   -776,
+      -503,  -1664,   -323,    253,   -280,  -3459,  -1313,    541,
+      2182,   1287,   -782,   1785,   -695,    -49,     72,     -4,
+         0,    -15,      3,    -21,   -211,   1382,   -149,    684,
+      2210,   2654,  -1440,  -1209,    152,   1080,  -3078,   -694,
+      4738,    985,  -1337,    819,   -518,   1799,   -671,   3201,
+      2636,      7,      1,     -6,     14,    -31,      0,    -34,
+      4296,    -23,    194,   1976,   -993,   1353,    709,   -342,
+     -1142,   -140,   -271,   2291,   -709,   1734,    818,  -3571,
+      1125,    912,   -590,    784,   -275,     -2,     -1,     -5,
+        -1,      0,   -381,   2754,   1545,  -2270,   3608,   2308,
+     -1899,    178,    391,   1826,   -127,  -1417,   -822,   -712,
+      1682,   2225,   2247,    446,    994,     56,    734,    196,
+         7,      3,      8,      0,      7,    639,    833,  -3313,
+       675,   -263,   -648,   3016,   -701,    235,  -1304,   -582,
+     -2930,   -210,  -1243,    374,  -3095,  -2013,    354,    599,
+     -1469,    140,    -17,     -1,     -3,      2,      0,     -2,
+      -183,    399,   -603,    796,  -1424,   2685,  -3929,    416,
+     -2291,   1737,   1906,   1667,    810,   -222,   3242,  -3636,
+      5196,  -1542,    940,   -124,   2047,    -67,     -4,      6,
+        -1,     13,      2,   -161,    417,   4132,    492,  -1068,
+      -817,   2732,   -250,  -1457,   1723,   2104,   1121,  -1276,
+      1147,    990,   -523,  -1533,    297,   1219,   3901,  -2549,
+       -22,      0,      0,      0,      0,      2,  -1632,    172,
+       829,   -747,  -1229,  -1990,  -1070,   1134,   1623,    228,
+      3689,    625,   -757,   8192,    -82,    738,    213,   1900,
+     -1200,     91,    892,    -45,     15,     -1,      5,     -4,
+         5,    392,  -3067,  -1903,    139,    661,     43,   2174,
+     -1919,   -270,  -1490,   -569,      2,     85,  -1091,   6740,
+       886,     85,  -1052,   -647,   -563,  -2971,   -145,     -1,
+        39,     -5,     -6,     -7,  -1023,  -1104,  -1774,  -3154,
+     -1058,   3488,  -2551,   3547,   -253,   -204,   -235,  -1544,
+       -73,   -584,   -302,  -3118,  -2314,   -308,   1790,    916,
+       152,   -155,    -11,      6,    -26,     -1,    -31,     21,
+       919,  -1856,   -456,  -1050,    663,   1454,  -1515,  -2606,
+     -4287,   1553,   3564,   1334,   1797,   1540,   -392,   -701,
+      -971,  -3442,    281,   -271,    133,      1,      5,      4,
+        32,      3,   -521,  -1530,  -1368,   1787,   -515,   -913,
+     -2391,     93,   2690,   -578,   -576,  -1656,    554,    649,
+     -1509,   -258,   -605,   1233,  -2258,    640,    837,    -43,
+         1,     -3,      0,      5,      3,    148,  -4761,   1783,
+      3244,   -277,  -1139,   1539,  -2016,   1898,  -1276,   -776,
+     -1725,  -1900,    -51,    559,    311,   1737,   -928,   3687,
+     -1087,   1329,    134,      2,     -2,     -7,      9,      5,
+       -77,  -1116,   4986,   -940,   -905,  -3229,   -773,   3335,
+       -23,    578,  -2376,    386,    122,   1253,    363,  -2748,
+      -512,  -4612,   1690,    848,  -1116,    195,      5,      2,
+        11,      1,     18,    659,  -1282,    562,   1170,   4701,
+       903,    490,  -3508,   3468,    -39,    654,  -1196,   -909,
+      -268,    980,    283,   3221,    348,   1121,   -897,  -1011,
+      -103,    -11,     -2,     -9,     16,     -8,   -274,  -4100,
+     -2312,  -2379,    617,   1629,   2154,   3026,  -1737,   -603,
+      -803,   -366,    977,   1035,  -1835,   -255,   -275,  -1245,
+      1274,   -161,  -4476,   -181,     -4,      0,     -2,      1,
+         2,    156,    551,   -832,   -630,   3740,  -2115,    344,
+       229,   1295,     65,    290,  -1462,  -1794,   3297,  -1049,
+      2451,    322,  -2642,  -2810,  -1246,    613,     90,     -1,
+        -1,      0,      0,      0,   -277,    854,   1259,   1542,
+      -433,   3601,   -453,   1091,   -113,   1438,    994,  -2746,
+      -786,    867,   1422,   1093,  -1723,  -1167,  -1389,  -1062,
+      -436,    -81,      2,      1,     11,      1,     26,   -197,
+};
+
+static const int16_t cb0806ss1[] = {
+      1760,  -4335,   6384,  -2036,   2874,  -2504,  -1529,    102,
+      6995,  -1267,  -3141,   1050,    -59,   1556,  -1002,   1536,
+      1024,   1867,     40,  -1156,  -2627,   -213,  -1034,   -660,
+       291,   -963,   -323,    462,   -804,   2219,   -859,   1709,
+       550,  -3390,    319,     24,    644,   3154,   4503,  -1961,
+       744,    194,   -151,  -1255,  -1318,   3033,   -899,    -18,
+         1,      0,      2,      0,     28,  -1213,  -3725,  -2525,
+      -177,  -1164,    361,   -357,   -649,   -459,   1324,   2463,
+     -3108,  -3323,   -575,  -2744,   -108,   -121,   -508,   -564,
+      -849,   -773,   -288,      0,      8,      0,     -2,      5,
+       691,   -602,   2269,   2373,  -2027,    786,   3011,   3234,
+     -1387,   -310,    659,   -358,   1058,  -1554,   1031,    795,
+      2254,   -549,    334,    325,    599,    -36,     -1,     -1,
+        -2,      3,      4,   -450,   -533,  -1657,  -1928,  -1034,
+      -636,  -1446,   -320,   2695,   1184,    697,   1126,   1159,
+      2970,    449,    -30,  -2058,  -1171,   -684,    -66,    905,
+       -43,      1,      0,      3,      0,      3,    228,    272,
+       -79,   -718,   1978,    667,  -2760,   1507,  -1893,   -796,
+      1164,     35,  -4440,  -4492,  -1667,   4189,   6485,   -495,
+      1721,  -1639,   -526,    458,      0,    385,   -183,    511,
+      -153,  -2025,   -376,   2948,  -2606,   -910,   -741,   -427,
+     -1080,   2128,    565,   -483,   1791,  -2222,    -45,  -1204,
+       799,    512,  -4790,   1462,    511,  -1906,     15,      0,
+         0,      1,      3,      8,   -867,   -685,   -140,   5299,
+       376,   -891,   1657,   1843,  -1465,  -1297,    518,  -4640,
+       303,   -277,   -650,    -97,   2308,   -679,    720,   -171,
+      -475,   -269,      0,     -5,      4,     -1,      9,  -1155,
+     -4954,   1684,  -2045,    939,    819,   -751,   -165,    -93,
+     -2327,    306,    965,   4999,    557,    -55,   -999,     30,
+       -36,    989,  -1680,  -1594,    318,     -3,     -8,     -4,
+         1,     -9,   -402,   8192,    475,   2080,   -418,  -1739,
+      -273,    -55,   -441,    794,    -79,    272,  -2039,    789,
+      2266,    874,   2495,    627,   2203,   1212,  -1052,    389,
+        14,    -24,    -59,     10,    133,   -535,  -1160,  -1139,
+      -146,    180,   1064,   3718,  -1412,   1153,   1873,   -549,
+     -1698,  -1479,    209,    725,   -940,   2152,   1848,    678,
+      2493,   4608,    -11,      0,     -1,     -3,     -3,      2,
+       334,    681,    673,  -8192,   3958,  -3111,   1641,   1500,
+      1184,   -268,  -3147,    571,    958,   -663,  -1031,   -870,
+      -674,  -1098,   -529,     78,   1212,    120,     -8,    -13,
+        -5,    -42,    -37,   -498,   1304,  -2541,   1730,   -355,
+      1462,   2315,   2017,   -403,  -2010,    555,   1391,    887,
+      2039,    366,    135,     85,    371,   1291,   -225,    335,
+       -45,      0,      1,      2,     -1,      2,  -1095,   -261,
+      3249,   3212,  -1877,    934,  -1671,  -1289,   1398,  -2287,
+      -205,   1659,    642,   1105,    751,   2864,   1171,  -1001,
+       318,   -290,     60,    -54,      5,      3,      5,      2,
+         1,   -105,    590,     36,   -194,   1832,   -639,    777,
+      3243,    578,   2820,    428,   2020,    623,  -2104,    -52,
+      -331,  -1015,   3064,   -347,   -303,  -1100,     61,     -1,
+        -1,      0,      2,     -1,    592,    127,    887,  -1094,
+     -2819,   2573,  -2670,  -1693,  -2775,     48,   -266,   -961,
+      1220,   -472,    167,   3201,   1118,   -173,   1304,    -26,
+      -899,     76,      0,      3,      0,      1,     -1,   -718,
+      -746,    947,   -524,    142,    958,  -1609,   -777,  -1362,
+       385,   -578,  -6947,    157,   -290,   1357,  -1703,    484,
+       117,  -2224,  -3736,   -838,    -96,     -1,     11,      5,
+         4,      2,    475,   -426,    500,   -767,  -2304,   1248,
+      2200,  -1829,   -992,   -225,   -573,  -1107,   -832,   2555,
+     -2866,   3453,   4335,    -88,  -1160,  -1666,    -94,    -33,
+         0,      0,      1,     -2,     -7,   -147,  -8192,   1204,
+     -1181,   -702,   -604,   -770,   1032,   -173,    770,    861,
+       611,   -509,    802,   -467,    839,    491,   -785,    523,
+      -669,     73,    -34,      0,      0,     -2,     -3,     -3,
+       286,  -2183,  -1238,   1743,    387,  -2228,  -1404,  -3439,
+     -1701,  -2371,   -451,   2294,   2061,   3062,  -1122,  -1489,
+     -1274,     51,   5649,   -170,   2197,    365,     -1,    -13,
+         4,      3,     -5,    -15,  -4099,    789,   4132,   4982,
+     -1996,    784,    748,   2123,   3535,  -1493,  -1454,   -344,
+      -867,     40,    831,  -1198,     66,    542,   1633,  -2402,
+       117,   -119,    -18,     49,     18,     40,   -500,    808,
+      -726,   1192,   3623,   1526,   -484,   1080,  -2502,   -579,
+      1315,  -1887,     84,   1771,  -2902,   1387,  -1098,   1559,
+     -1126,    652,   -896,     32,     -1,      3,      1,      3,
+        -2,    233,    782,   8192,    566,   -701,   -352,   1047,
+       581,  -1070,   3159,  -1157,  -1585,   1599,   -978,   -663,
+      -931,  -2581,   5074,    781,   -551,   -590,   -247,    -63,
+       -54,    -50,    253,   -138,   -313,    387,  -3004,  -1136,
+       654,  -1283,   1318,    434,     80,  -1486,    694,   -512,
+       393,   -238,   -700,   -232,    706,   1478,  -8192,    377,
+       601,     18,     -1,     -3,      0,     -6,     -3,   2221,
+      3531,   -862,   1792,   -242,  -3686,    420,   1891,    918,
+      1324,    234,   -819,   -601,   2363,  -1097,   2355,    754,
+      -125,    245,   -615,   3285,    204,      0,      6,     -4,
+        -3,     -1,   -637,    673,   1233,   2886,    265,   -195,
+      -226,   2521,    281,   -210,   1809,  -2733,  -3865,  -2287,
+       641,  -2604,  -4235,    107,    789,   1163,  -2600,   -463,
+        -5,     10,      2,    -10,     39,   1380,    754,  -5077,
+      4061,  -1633,  -1738,  -1604,   1937,   1815,   1039,   3696,
+      -593,   2218,  -1061,   1081,  -1217,   2062,   -637,  -1580,
+       149,   -626,   -253,     -3,    -17,      2,     33,      1,
+       118,    525,    158,   1213,    910,   -105,  -1437,  -1311,
+      2255,   -419,  -2394,   1542,  -3830,  -1167,   -998,  -1099,
+      1635,   1678,  -1112,   -275,    122,    -50,      0,      3,
+         0,     -1,     -1,    998,  -4020,  -1913,  -1083,   -159,
+      1853,   -436,   -683,    298,    211,    711,   4128,  -1977,
+      -958,   1048,    642,   -420,    329,  -1150,    459,   2161,
+        29,     -4,      0,     -1,     -6,      1,   1365,   1053,
+      1032,    952,    854,   2405,   5106,   1863,   3049,    981,
+      -863,   -397,    508,  -1283,   -631,     17,    532,  -1453,
+     -1056,     66,    501,    -27,     -1,      3,     -1,    -13,
+        -2,   -273,  -2924,    839,   -433,   -395,   -252,   1945,
+       195,   -307,  -1297,  -1474,   -985,   4412,  -1017,   1074,
+      2711,    996,    919,    183,    -10,   -605,     38,      1,
+        -1,     -1,      2,      1,   2115,   -422,   3655,  -1972,
+      1473,  -2033,   2461,  -1112,  -1267,    179,   -394,   -906,
+     -1273,   -432,   1082,    367,   -720,   1746,   -657,    595,
+       701,     16,     -1,      0,      0,      2,     -3,   -255,
+       443,  -1840,  -2379,    296,    258,   -675,   -221,    406,
+      -216,  -6295,  -1041,   1062,    199,   1705,  -1032,  -1627,
+     -2399,    198,  -1097,   -271,    -99,      0,      1,     -2,
+         2,    -13,    343,   -219,  -1447,   1779,    630,  -1944,
+     -1093,  -1578,    -62,  -1334,   2811,   -815,   1311,  -3102,
+      -300,     67,     24,     98,    764,  -1246,    203,      6,
+         0,     -4,      0,      1,      0,    -18,  -1704,  -1427,
+      -352,  -2665,   -588,    287,    715,   -454,    688,   -424,
+      1736,  -1124,   1028,  -7581,   -752,   -482,   -363,    -75,
+      -720,   -619,    449,      0,      3,      0,     16,     -3,
+     -1211,   2484,   3490,   -547,   -705,   1776,   -286,  -1580,
+      2896,  -2257,   -214,  -1784,  -1266,   -562,  -1170,   -542,
+       785,   1606,    535,     51,  -1405,     -7,     -1,     -1,
+         0,     -1,      2,   -428,   -579,  -1091,  -2627,   2287,
+      -757,   1445,   -411,   -160,    567,    108,  -1305,  -4356,
+      -390,   -917,    345,  -2169,   -896,   3772,   1224,    691,
+       -25,      1,      1,      1,     -2,      1,    281,   1365,
+     -1628,   -585,   3485,    169,    746,   -395,   1072,   1569,
+     -1073,    744,   1274,  -3472,   1035,   -906,  -3394,  -1537,
+      -869,   2841,    401,      4,     -1,     -3,     -3,     -1,
+        -3,    -37,  -1628,   -888,    785,   3328,   1105,   3551,
+      6946,  -1688,   2690,  -2051,  -2212,  -3750,  -1903,   -497,
+      1251,   1187,  -6198,   3930,     85,  -1077,     16,    -23,
+       -80,   -130,     43,     66,   -974,    579,  -2047,  -3607,
+      -666,  -2248,   4619,   6846,     88,   -649,   1129,   -255,
+      3567,   -124,     41,     58,    634,  -1252,    696,   2536,
+     -1590,    209,     12,   -102,   -275,     27,    216,   1110,
+       259,  -2091,   1775,  -3768,    598,    441,  -1809,   -431,
+        22,   -991,   -621,     84,  -1803,   1585,    559,  -1101,
+        42,    456,   -392,   -874,     -4,      0,      0,      1,
+        -1,      0,   -371,   -211,   -339,  -1232,    438,  -2683,
+     -1007,   1250,   5343,    861,  -1305,   -577,   2107,  -2649,
+     -3227,   1020,   -127,    562,   5495,  -3136,   -414,   -529,
+        12,    -53,    -34,    151,    106,  -2946,   -575,  -1796,
+      3095,   -257,   -591,    126,    967,   -547,   -271,    560,
+       974,  -3335,  -2110,  -1403,   5915,  -1108,    388,  -1266,
+      -522,    336,    167,      1,     -3,     -2,      2,     -3,
+      -312,     19,   3356,   1123,   -676,   -247,    697,    548,
+      1768,   1174,   -525,   -253,   -423,    546,  -2373,  -2940,
+     -1055,  -2304,    203,   1309,   -574,     -8,      0,     -3,
+         4,      0,      4,   -215,   8192,   -670,  -1289,  -1547,
+      -304,   1498,   -967,   -529,   -582,  -2205,   1752,    321,
+       573,  -1096,     64,   1152,    -87,    574,   -250,    539,
+        62,      7,      2,     -1,     -3,      3,   -465,    243,
+     -1179,    828,  -2501,   -223,    198,   -883,   -740,   1113,
+     -1821,  -2068,  -3234,   1715,   1989,   1817,    727,   1640,
+      3386,  -1538,   -864,     45,      0,     -4,      0,      0,
+         2,    608,  -1495,   1259,   -132,   1311,    350,    537,
+      2735,   1428,    151,   1324,    547,  -3983,  -1892,    104,
+      2023,   1908,  -1042,   1130,   1252,   -701,      9,      0,
+        -2,     -1,      1,      1,    602,  -8192,  -2776,   -661,
+      1640,    443,   3452,   -738,    829,    637,    292,    232,
+      1352,   4879,   1429,    912,    649,   1593,    308,   -330,
+        68,     63,     -3,      4,    -57,     26,     25,   1250,
+       400,  -4839,    211,  -2748,   -664,    996,    341,  -1053,
+       321,   2458,    764,    743,   -729,     12,   -283,   -346,
+       118,   -249,   -153,  -2329,    -37,      0,     -1,      0,
+         1,      1,    352,   -878,   2336,   -634,  -2690,  -3415,
+     -2949,   -531,   1259,    394,    163,   -994,    845,   1259,
+       890,   1400,    279,   1908,    161,  -2174,   1876,     76,
+         1,     -1,     -1,     10,      0,     47,  -1123,   1611,
+       489,    618,   -816,     -7,   2001,  -1190,   1857,  -2749,
+      -311,   -331,    733,   1412,   1390,  -1525,   1262,  -1393,
+      -263,   3124,    -98,      0,      1,      0,      1,     -2,
+       514,  -3533,  -2394,   3623,    249,  -1056,    515,   1279,
+      2821,    477,    183,    689,   1182,   1378,   1287,   -711,
+      1264,   -713,   -278,    217,   -664,   -225,     -1,      0,
+         6,      2,      9,  -1171,   3119,   1340,  -1229,  -1929,
+      1984,  -1333,   1018,     10,   1205,     63,    358,  -1108,
+      -455,   -413,    854,  -1550,   -423,   -180,   2529,  -8192,
+       -18,      0,     -2,     -1,      0,      0,   -678,   3819,
+     -1316,   1159,    590,   -231,   2203,  -1533,    986,   4289,
+      1114,   1135,  -1162,   -921,    -58,    691,     11,  -1718,
+      -270,   -531,    530,     65,      0,     -1,      1,      4,
+         0,  -1184,  -1359,   7230,   -533,  -2077,  -1188,    113,
+     -1472,    490,   1518,   1476,  -1885,    934,    244,   1840,
+      -696,   -480,  -2476,   3324,  -2433,   1102,    120,      1,
+       -11,     -2,     18,     -3,  -1016,    189,  -3835,  -1659,
+       -46,   -180,  -2659,   1998,  -1437,   1107,  -2248,    165,
+      -657,  -5079,   -224,   1246,    469,    421,   1145,   1148,
+        84,    -18,      3,      0,      0,     -6,      0,    -66,
+      -206,   2279,   -220,   1606,   -421,  -1482,   -413,  -1237,
+       374,   3691,    491,   -774,    410,    791,    380,   3385,
+       615,   -950,   -620,   -197,     65,     -1,      3,     -3,
+         2,     -1,   -484,   1396,    273,  -3591,   1317,  -1013,
+      1563,   -134,    602,  -1069,    733,  -1167,    233,    319,
+      -262,    350,    780,   -407,   -496,  -1285,   1326,    -13,
+         0,      2,     -1,      0,     -1,   -328,   -626,   -848,
+       745,  -1047,   4048,   -380,   -456,  -1894,    869,  -1085,
+      -373,   2829,    622,    473,    394,    237,  -2175,   1167,
+     -4942,    246,    100,     -1,      1,     -6,      1,     -6,
+       -70,     35,   1613,   2597,   1307,   1756,  -1184,   1082,
+       971,  -2004,  -1459,   -494,    -40,    745,   2788,   -830,
+        76,    536,  -2002,    401,    -57,    -20,      0,      0,
+         0,      0,      0,     -8,    244,   1927,   1162,  -2416,
+     -1414,    463,    -89,   1217,   -798,    394,  -1527,   -719,
+      -666,    998,   1518,  -2455,  -3049,  -1174,  -2696,  -3119,
+         2,      0,     -2,      2,      2,      3,   1093,   -623,
+      1660,  -1635,   1457,   2560,    763,  -2750,    931,   1798,
+      2550,   1402,    914,   -919,   1931,   -383,   -435,   -583,
+       439,      9,  -1106,    -12,     -1,      0,      0,      0,
+        -2,   -335,   -730,  -2102,  -1414,   2576,  -3869,   1025,
+     -1657,     -2,    857,   -336,  -3011,    205,   1108,    364,
+      -789,   -179,    171,    331,   2204,    527,    -13,      1,
+        -3,      2,      1,     -4,   -565,   -211,   -139,   1799,
+       195,   -877,   -632,    358,   -244,  -1459,   1398,   2271,
+       550,   1987,   2206,   -337,    199,  -7036,    589,    195,
+      -466,     72,     -1,      2,      1,      0,      0,    -27,
+};
+
+static const int16_t cb0806sm0[] = {
+     -8192,    389,    245,    -67,    -42,     79,    503,   -488,
+      -310,    107,    -13,   -431,   -203,     96,    510,    151,
+       270,      0,      0,      0,      0,      0,   -463,    -23,
+       -72,   -322,     74,   1589,   -152,   -198,     81,   1120,
+      -125,   -434,  -3275,  -2210,   -348,   -344,     91,      0,
+         0,      0,      0,      0,   -254,   -224,     46,   -154,
+      -131,   -465,    -57,   8192,    345,    112,   -725,    -49,
+       183,   -191,    246,    263,    370,      0,      0,      0,
+         0,      0,     39,   -739,  -6603,  -2454,    -95,    312,
+       -53,   -392,     63,   -165,     31,   -505,    111,    484,
+      -535,    179,    143,      0,      0,      0,      0,      0,
+      1279,   -139,  -1769,    244,     59,   -135,   -429,    707,
+       809,  -4355,   -354,    428,   -300,    108,   -799,  -1421,
+       599,      0,      0,      0,      0,      0,      4,     -5,
+         7,     75,     49,   8192,    276,    200,    191,   -167,
+       -14,     82,    222,   -277,   -483,   -216,   -441,      0,
+         0,      0,      0,      0,    171,   -423,    174,    401,
+      -517,   -377,   -234,   -644,   -829,   -350,   -976,   -146,
+      -928,    296,   3003,   3545,    -30,      0,      0,      0,
+         0,      0,    161,  -6753,   1138,   -855,   -132,   -242,
+       559,   -225,   -346,   -168,     10,   -481,     -6,  -1208,
+       252,   -323,   -191,      0,      0,      0,      0,      0,
+      -262,    574,    433,   -145,    622,    329,  -2634,   -439,
+     -1178,    351,   -433,   -842,   4125,    296,    305,    359,
+       -22,      0,      0,      0,      0,      0,    -34,    -56,
+     -1019,   -247,   -163,    305,    574,    -51,   -179,     24,
+     -1097,    248,   -166,    -18,    303,    252,   -555,      0,
+         0,      0,      0,      0,   -400,   -254,   -256,   2783,
+      -296,  -1904,    552,   1284,   -336,  -2371,   3396,  -1092,
+       102,    176,    140,    640,   -359,      0,      0,      0,
+         0,      0,    373,    473,  -2167,   -774,   -388,    405,
+     -1402,  -1391,  -1319,   -155,   1104,   -533,    382,   1561,
+     -2958,    406,    787,      0,      0,      0,      0,      0,
+     -3800,    -58,   2098,   -181,   -570,    385,  -4125,    759,
+     -1584,      9,   -278,    201,   -528,   -527,   -435,    436,
+       681,      0,      0,      0,      0,      0,     30,    -80,
+       -60,  -4031,    -70,  -3367,    316,   -861,     67,   -169,
+      -144,   1598,    966,     32,  -1263,   -434,   -738,      0,
+         0,      0,      0,      0,    181,     12,    115,     91,
+       253,    518,    517,    216,    830,    336,   -568,  -3125,
+      -796,   -847,   1627,     58,   -158,      0,      0,      0,
+         0,      0,     48,   -851,   -286,    393,    390,    707,
+       595,    427,   -235,   -116,    814,   -198,   6145,  -1590,
+       647,     15,   -259,      0,      0,      0,      0,      0,
+      -621,    152,    590,    -16,    215,   -633,   -784,   -140,
+      1087,    723,  -4191,   2701,    951,   -972,    273,   -554,
+       387,      0,      0,      0,      0,      0,   -124,  -2939,
+       -38,    383,    234,    687,  -2873,   -466,     61,   -472,
+       854,   -396,    305,   -233,     82,  -2677,   -206,      0,
+         0,      0,      0,      0,   -120,   -246,   -614,   -394,
+      8192,     75,   -450,    177,   -251,     45,   -142,     65,
+     -1248,    -14,    389,    375,    114,      0,      0,      0,
+         0,      0,   2870,    158,   -473,   -166,    928,   -618,
+     -1909,    224,   -931,   1898,    -16,    427,    447,  -1044,
+        85,   -333,    197,      0,      0,      0,      0,      0,
+        78,    114,   -167,     73,  -1070,    -80,   3512,  -3004,
+     -1553,    769,    213,    851,   -377,    978,   1097,     71,
+        66,      0,      0,      0,      0,      0,   -129,    248,
+       455,   -376,    344,    128,    -60,    546,   -321,  -7898,
+      -719,    -55,   -941,   1242,    207,    215,    323,      0,
+         0,      0,      0,      0,    -24,   -225,    136,    142,
+      -739,   -117,      2,    242,   -152,    -20,  -1775,   -484,
+       -36,   -408,  -2767,   -471,    251,      0,      0,      0,
+         0,      0,     22,    111,   -180,  -7417,    365,    293,
+      -313,   1031,   -191,    154,   -210,   -239,    121,   -333,
+     -1504,    209,    146,      0,      0,      0,      0,      0,
+       898,   -643,   3080,    528,    -91,   -718,   -512,    275,
+     -3564,    396,    160,   -850,    346,   -595,   1558,    684,
+      -310,      0,      0,      0,      0,      0,    234,   -419,
+      -724,   -433,    292,  -1003,    682,   -117,  -1318,   -914,
+     -5137,    128,     53,    291,    408,   1269,   -284,      0,
+         0,      0,      0,      0,   -252,    190,  -2911,    130,
+       255,   -172,  -4331,     26,   -267,    280,   -133,   -613,
+     -1063,  -1135,    759,  -1290,    216,      0,      0,      0,
+         0,      0,    133,   -177,   4069,   -311,   -197,   3260,
+       341,    201,   -117,   -515,    105,   -658,    975,     81,
+      -333,   -333,    262,      0,      0,      0,      0,      0,
+       273,    -87,    321,    190,   1385,    274,    182,  -2553,
+      -150,    164,   -830,     89,   -459,  -5279,   -624,   -336,
+       399,      0,      0,      0,      0,      0,   -172,   -232,
+        11,     45,    121,   -254,   -457,    196,  -3487,   -838,
+       512,   -310,  -2831,    -85,     98,   -145,   -331,      0,
+         0,      0,      0,      0,    -55,   -149,   2068,    -61,
+      3087,   -143,   1574,  -1381,   2853,   1899,   -453,   -580,
+      -137,   1211,  -1413,    171,    125,      0,      0,      0,
+         0,      0,   -228,     30,   -956,   5569,    209,    -89,
+        25,    573,  -1669,    507,    182,   -132,    697,   -132,
+     -2964,   -637,    139,      0,      0,      0,      0,      0,
+     -3078,  -3278,   -771,    928,    -38,   -463,    820,   1141,
+     -1234,    620,    652,  -1710,   -382,  -1618,   -409,    179,
+       483,      0,      0,      0,      0,      0,   -102,   4256,
+       -20,   -162,   2021,    730,   1439,   2776,    459,    498,
+      -152,    482,     35,   -271,    810,  -1345,   -249,      0,
+         0,      0,      0,      0,    131,      5,   -281,    431,
+     -2498,  -1046,    482,    842,    297,   -311,  -1260,    148,
+      -906,  -4217,  -1411,   -102,   -361,      0,      0,      0,
+         0,      0,    116,  -3083,    235,  -1195,    -19,   -646,
+        42,    487,    309,   1654,   1051,  -1643,    689,   -823,
+      2279,   1488,    571,      0,      0,      0,      0,      0,
+        42,    -95,     -3,     36,   -170,   -114,   8104,    217,
+       140,   -217,    599,   -774,    -64,   -675,   -211,    166,
+       204,      0,      0,      0,      0,      0,     99,    594,
+       -48,    224,     52,  -1499,    271,   2224,   -219,   3184,
+      -165,    828,  -1345,   -785,    181,    133,    124,      0,
+         0,      0,      0,      0,   -235,   -286,    254,   -171,
+     -4980,   -453,  -1432,     12,    734,   -391,   -640,    339,
+       537,    313,   -700,   1016,    148,      0,      0,      0,
+         0,      0,    -49,    -19,    803,    935,    520,    -90,
+       641,   1053,   -454,   2338,  -6071,   -478,    616,   -559,
+      -339,    445,  -1464,      0,      0,      0,      0,      0,
+      -175,    111,   -132,     65,   -264,    732,    221,    231,
+     -1972,   -305,    325,   -859,    583,   1272,   -441,   2651,
+       229,      0,      0,      0,      0,      0,   -286,  -4646,
+      -262,    593,    613,    936,    310,   -615,     83,    223,
+      -816,   1910,   2041,    281,   -190,   -434,    114,      0,
+         0,      0,      0,      0,   -123,    684,   -208,    524,
+      -606,  -1223,    264,   -983,   -109,  -1057,    696,    195,
+      -521,    945,  -7503,    193,   -120,      0,      0,      0,
+         0,      0,     98,   -358,  -2165,    244,    277,    393,
+       771,   3360,   -258,  -1218,   -122,  -1253,  -2297,    806,
+      -198,    540,      7,      0,      0,      0,      0,      0,
+        78,   -281,   -368,   2809,    159,   2611,    833,   -120,
+     -3987,    933,    360,    -49,   -515,   -106,   -360,    650,
+      -125,      0,      0,      0,      0,      0,    203,   1369,
+       749,   -502,  -2295,   -326,    448,   -309,    630,    -84,
+       345,   -520,     -4,   -623,   1066,  -3915,    373,      0,
+         0,      0,      0,      0,  -4603,   -794,   -625,   -355,
+      1071,   -601,   -553,    593,   -296,    626,   -328,    621,
+        85,   1348,     92,   -288,    204,      0,      0,      0,
+         0,      0,     -9,    602,   -162,   -749,   -104,    464,
+      -372,  -1375,  -1905,   2200,     61,  -3308,   -897,    634,
+      1036,  -2112,   -182,      0,      0,      0,      0,      0,
+       -76,   2341,   -675,    -72,    -29,    704,   -536,   1656,
+      -541,   -736,  -1420,  -1539,   2458,   -228,    674,  -1258,
+        -3,      0,      0,      0,      0,      0,   -133,   1111,
+        63,    327,    470,   1226,    541,   -276,  -3042,  -1594,
+     -3192,    357,   -617,    658,   -315,   -978,    631,      0,
+         0,      0,      0,      0,    111,   -188,    619,    236,
+       104,     54,    545,    424,   5912,   -332,    711,  -1249,
+      -533,    291,  -1544,   -216,    113,      0,      0,      0,
+         0,      0,   -199,    267,    152,   -301,   -172,   1294,
+      2311,   -482,  -2451,    -82,   1833,    214,    130,  -1183,
+     -2212,    403,   -625,      0,      0,      0,      0,      0,
+      -106,    662,    -48,   -131,    324,   2337,    445,    462,
+      -349,   -189,    669,   4945,  -1797,     16,    268,   -602,
+         2,      0,      0,      0,      0,      0,     55,    154,
+       892,    -35,   -145,    357,    562,     42,     -9,   -284,
+       177,     84,    422,   -181,   -358,   7618,     29,      0,
+         0,      0,      0,      0,   -353,     68,    -41,  -4096,
+       177,    -20,   -267,    782,    954,   -430,   1573,   -696,
+      1785,  -3611,     89,   -243,    683,      0,      0,      0,
+         0,      0,   -220,   1983,   -891,    614,    226,   -202,
+        67,    761,   1904,    179,    226,    416,   -657,  -3409,
+      1026,   2834,   -438,      0,      0,      0,      0,      0,
+      -551,   -229,   -304,   -462,  -2277,   -419,    451,   -122,
+      -108,    258,    784,   1105,    382,    137,   5695,   -241,
+      -491,      0,      0,      0,      0,      0,     34,   -272,
+     -1687,   1769,   -332,    365,     33,  -2594,   3729,    325,
+        85,   -295,   -290,   -152,   2238,   -611,    -41,      0,
+         0,      0,      0,      0,    102,    166,    241,   1098,
+      -107,    775,   -414,   4256,   -277,    935,   -200,    495,
+       255,   1144,    468,   -184,    -59,      0,      0,      0,
+         0,      0,     94,   -282,    -57,     12,   -390,    245,
+      1872,   -620,   1089,   3754,    432,    947,   -509,   -284,
+     -3836,     26,    482,      0,      0,      0,      0,      0,
+         9,    971,   -373,   1111,   -480,   2342,   -182,    528,
+       802,   1196,  -1017,   -879,    499,   2800,   -830,   -230,
+        -4,      0,      0,      0,      0,      0,   -382,   -815,
+     -1669,  -2437,   -593,    193,   -688,    632,    479,   2883,
+       565,    540,      5,   1598,   1618,   -640,   -246,      0,
+         0,      0,      0,      0,   -421,   -103,   1482,  -3026,
+       -65,   -101,      4,   3921,    688,   -941,   -234,     49,
+       202,   1905,    935,  -1155,     -4,      0,      0,      0,
+         0,      0,    210,   -625,   -118,  -3215,    344,    978,
+       -10,    773,   -126,   -804,  -1534,    182,  -1146,   -646,
+      -146,   2011,    463,      0,      0,      0,      0,      0,
+};
+
+static const int16_t cb0806sm1[] = {
+        35,   -237,    547,    705,     -9,   1612,    382,    195,
+      -191,   -250,   -101,   -357,    709,    153,    850,  -5091,
+      -100,      0,      0,      0,      0,      0,  -6406,   -158,
+      -527,    137,   -330,    580,   -484,     63,    541,  -1245,
+      -205,    138,    247,   -489,   -147,   -132,   -863,      0,
+         0,      0,      0,      0,     53,    -38,    283,    -22,
+     -1506,   -467,   -418,    117,    133,  -2152,    -48,   -991,
+       808,  -1047,   2402,    261,    423,      0,      0,      0,
+         0,      0,    -14,    500,   4697,   -174,   -544,     87,
+      -379,   -243,    577,    682,    258,  -1190,  -1984,    599,
+       607,   -123,   -290,      0,      0,      0,      0,      0,
+        60,   4254,    194,    888,    -81,   -395,    422,  -1786,
+       916,    288,   1191,   -658,    502,   2177,   -977,   -301,
+       587,      0,      0,      0,      0,      0,    232,    204,
+      -452,   -853,  -4266,   -219,   1164,     92,     91,   1561,
+       950,   -705,  -1217,   -734,   1617,    120,   -324,      0,
+         0,      0,      0,      0,  -3442,   -456,   -667,    987,
+       -89,   1383,   -704,   -187,   -280,   -583,    341,   -732,
+       649,  -2129,  -3505,   -175,   -215,      0,      0,      0,
+         0,      0,    200,   -635,   -471,  -1221,    215,   2844,
+      1633,    522,   -720,   1722,   -272,    473,    198,   -604,
+       480,    -88,    169,      0,      0,      0,      0,      0,
+      -160,   -268,    130,    284,   -612,     95,     43,     42,
+       641,   -258,  -6884,   -167,   -689,    123,    276,   -592,
+       717,      0,      0,      0,      0,      0,    313,    -90,
+     -4310,   2706,  -1708,    648,   -796,    791,    998,   -468,
+       632,   1893,     43,   1937,  -1279,    -22,    -64,      0,
+         0,      0,      0,      0,   -106,    135,   -287,    335,
+     -7999,     51,   -250,   -388,     16,    285,   -101,    685,
+      -944,    604,   -624,   -792,    209,      0,      0,      0,
+         0,      0,    496,   -205,    422,     49,    274,   -229,
+       220,     73,   -734,    381,   -394,  -8192,   -405,    755,
+        -9,     46,    116,      0,      0,      0,      0,      0,
+       -28,    332,   1152,   -129,    244,     84,  -2193,    632,
+     -1854,   -384,    110,   -302,   -270,    435,  -1689,   -797,
+       686,      0,      0,      0,      0,      0,  -1660,    624,
+      -664,   2611,     30,  -1155,   -419,  -3539,   -568,   1719,
+     -1374,   -676,    -55,  -1934,    863,   1391,    433,      0,
+         0,      0,      0,      0,  -1012,    290,   2302,   -330,
+       -95,  -2355,    -55,   -763,  -1995,   -298,   -680,    715,
+       -85,   1615,   1011,  -1989,  -1028,      0,      0,      0,
+         0,      0,     21,  -5001,    507,    -58,    229,    -37,
+      -113,    632,   1809,    -62,    334,  -1201,   -893,   -344,
+        98,    438,    -65,      0,      0,      0,      0,      0,
+         0,    143,    131,    -18,   -135,   -306,    392,    232,
+       265,    543,    376,   -562,    362,   2458,    785,   3653,
+      -456,      0,      0,      0,      0,      0,    855,  -4009,
+     -1207,    118,    -86,   -223,    266,    154,  -1886,  -1145,
+       241,   -397,    246,    244,   -776,    808,   -132,      0,
+         0,      0,      0,      0,      2,   -633,    113,    -94,
+      -154,   -173,   -162,   -168,    439,  -6548,    778,   -392,
+       -60,     99,  -1901,    171,   -130,      0,      0,      0,
+         0,      0,    -11,   -324,    711,   -903,    560,  -1654,
+      1473,   -300,   1048,    137,  -1140,  -1115,  -1302,  -1008,
+      -792,  -3264,   -540,      0,      0,      0,      0,      0,
+      -347,     78,   -103,     -7,     -3,    437,   6053,    299,
+      -435,    323,    664,    477,   1097,    158,    656,    273,
+       200,      0,      0,      0,      0,      0,   -101,     80,
+      -153,    144,   -235,    492,   -399,     -3,   4958,    699,
+      -586,   -162,    153,   -860,    161,    665,      4,      0,
+         0,      0,      0,      0,    -87,   -189,   1744,   -350,
+     -1840,    325,  -2354,   1193,   1386,  -1589,     80,   1055,
+      -188,    273,    807,   2038,   -419,      0,      0,      0,
+         0,      0,     50,   -185,     68,    -59,     -9,     78,
+      -585,   -121,  -7888,    771,   -908,   -284,    349,    158,
+     -1122,   -139,   -189,      0,      0,      0,      0,      0,
+       310,   -286,    235,   -687,   -919,   -364,   -697,   -253,
+       492,    300,   -238,    272,    518,   -525,  -5863,   -190,
+       -59,      0,      0,      0,      0,      0,    151,    616,
+     -4420,    227,    240,   -252,    516,   -250,     68,    411,
+      -192,    -87,   -607,    671,   1281,   -317,   -305,      0,
+         0,      0,      0,      0,     -9,    817,   -451,  -1079,
+        86,   5060,  -1157,  -1159,   -421,    302,   1636,   -316,
+       -66,   -518,   1010,   1068,     96,      0,      0,      0,
+         0,      0,   -576,   -362,    107,   3516,    303,   -364,
+      -402,    805,    574,    993,   -554,    298,   -925,    410,
+      1898,     13,    138,      0,      0,      0,      0,      0,
+      -340,   -150,    528,    142,   -464,   1034,   -397,   3944,
+      -697,    962,    902,   1393,   2212,  -1021,  -1034,   -961,
+      -319,      0,      0,      0,      0,      0,     58,     38,
+       382,    221,   -212,    826,  -1373,  -4559,   1329,   -123,
+       216,    -23,   -736,     95,   -300,   -418,     -4,      0,
+         0,      0,      0,      0,    -58,   7814,    218,    141,
+       -90,   -124,    455,    -27,     49,   -311,   -364,     80,
+      -136,  -1257,     96,    332,   -287,      0,      0,      0,
+         0,      0,     -8,    624,    127,   1857,   -480,   -869,
+      -575,  -1461,   -493,   -261,     97,     32,   -328,   -467,
+       173,  -2588,    132,      0,      0,      0,      0,      0,
+      5257,  -1037,    191,   -844,    247,    130,   -571,   -548,
+      -496,    216,   -161,    336,     62,    990,    130,    517,
+       -65,      0,      0,      0,      0,      0,    -89,      9,
+      -138,    405,   -701,   -479,   3605,    699,   -629,   -102,
+        27,  -1374,  -1059,    -18,  -2707,   -172,   -557,      0,
+         0,      0,      0,      0,    -67,    209,    571,    -93,
+      -405,   -172,   -260,    -19,     86,     22,    659,   -630,
+       222,  -8192,    106,    -34,     60,      0,      0,      0,
+         0,      0,    -10,  -3386,    336,    651,  -1377,    681,
+       -16,    -45,   -382,   1102,   -280,    169,   -822,    522,
+       434,  -1111,   -299,      0,      0,      0,      0,      0,
+       194,   -445,   -231,   -532,   -438,   -180,   -591,  -1680,
+       179,   5921,   -184,   -685,   -467,    875,   -573,    282,
+       235,      0,      0,      0,      0,      0,    339,    139,
+      -745,    -68,   -201,    467,   -743,    477,    -23,  -1177,
+      1384,   -357,  -1254,  -3760,    454,   1175,    252,      0,
+         0,      0,      0,      0,    109,   -252,   8027,   -765,
+       136,    111,    -86,   -593,    -84,   -750,   -121,    782,
+       739,   -296,    284,    213,  -1196,      0,      0,      0,
+         0,      0,    -40,     69,   1992,    452,    -75,    -84,
+       683,   1678,  -1350,  -1846,   3068,   -749,  -1410,   -271,
+       536,   1120,    117,      0,      0,      0,      0,      0,
+      4053,    340,    108,    -88,    411,    990,    217,   3675,
+       755,    752,   -206,    205,   -297,   -573,    188,    127,
+      -313,      0,      0,      0,      0,      0,     47,  -2870,
+     -3417,    216,   1730,    -83,    189,  -1615,   1016,    -44,
+      -502,   2151,      6,  -1057,    550,    194,   -498,      0,
+         0,      0,      0,      0,   -133,      1,   -387,   -497,
+       586,    173,    923,  -4078,  -1232,    329,  -2086,   -185,
+       592,    681,   3320,   -914,   -327,      0,      0,      0,
+         0,      0,   -132,    493,   -179,    220,    142,  -4345,
+       422,   -173,    357,   1317,    240,   -525,   1613,   -178,
+     -1584,   -734,    549,      0,      0,      0,      0,      0,
+      -337,    111,  -1238,    116,    302,    325,    189,    610,
+     -3180,   -284,   -817,   1383,   1559,   -802,    422,    438,
+       460,      0,      0,      0,      0,      0,    -96,    372,
+       335,   -843,   3967,    221,    380,    227,    309,    447,
+      -199,   -257,    372,   -397,   -534,    736,   -152,      0,
+         0,      0,      0,      0,   -144,    463,    -54,   -288,
+       -83,    115,   -574,   -229,    485,  -2643,     58,   4312,
+     -1155,    642,   -647,   1122,    118,      0,      0,      0,
+         0,      0,    157,      6,  -1017,  -1155,    687,   -288,
+       918,   -212,   -332,  -2486,   -197,  -1025,   -546,   4099,
+       155,   -731,   -333,      0,      0,      0,      0,      0,
+       -43,   -496,   -546,   -541,    283,   -521,    -47,    -18,
+       208,   -552,   1899,   2107,    588,    818,   -911,  -1104,
+       -84,      0,      0,      0,      0,      0,    -71,     40,
+      -326,     92,    216,   -106,   -255,     28,    120,    -58,
+     -2720,   -133,   -288,    -28,  -1157,   1563,    400,      0,
+         0,      0,      0,      0,     40,     -4,    559,   1350,
+        30,   3905,   -675,  -1092,   -587,  -1524,  -1987,  -1031,
+      1892,   -679,   -623,   1051,    -33,      0,      0,      0,
+         0,      0,    -98,    106,    105,  -5887,   -463,    424,
+       -42,   -506,   -589,    376,    840,    140,   -640,    771,
+        23,   -441,     -6,      0,      0,      0,      0,      0,
+        22,    203,  -3452,   -635,   -605,   1668,    422,   2973,
+       394,  -1605,   -968,   -739,    344,  -1438,    820,  -1318,
+       -26,      0,      0,      0,      0,      0,    258,    -32,
+      1061,    643,   -152,     92,   -454,  -1305,   1621,    554,
+       344,     82,   -404,   5222,   -344,    286,    177,      0,
+         0,      0,      0,      0,     63,   -360,   -127,    814,
+      3639,  -3322,    390,     12,   -515,   -493,   1515,   1706,
+      -727,    394,   1164,    357,   -208,      0,      0,      0,
+         0,      0,    -27,    648,   -342,   -125,   -327,    194,
+     -3639,    598,     29,    244,    898,   -493,    372,   -635,
+       567,     31,   -237,      0,      0,      0,      0,      0,
+      -160,   2798,  -1768,  -2186,    493,    517,    -82,   -468,
+      -290,   2890,   -460,    450,    414,   -265,  -1121,    219,
+     -1115,      0,      0,      0,      0,      0,     14,     76,
+     -2806,    338,  -1429,   -402,    253,   -130,   -235,   -799,
+       309,   -525,   3823,    175,     36,    113,    247,      0,
+         0,      0,      0,      0,    352,    521,    213,   -107,
+       -71,   -762,    790,   -856,   -252,   -246,   -729,   -631,
+      1258,  -3276,   1534,   -436,   -635,      0,      0,      0,
+         0,      0,    -54,    118,   -453,   -124,    -32,    539,
+       356,   -169,   -202,   -590,    721,   -444,  -6260,   -275,
+      -239,   -105,    -52,      0,      0,      0,      0,      0,
+      -464,    507,   -796,   1273,   2297,    790,    652,    392,
+      3364,  -1949,   2154,   -701,   -229,     99,     88,    471,
+      -524,      0,      0,      0,      0,      0,     71,   -914,
+      1835,   -156,   -242,   -196,    513,    431,   -481,    -84,
+      -734,   4501,   -510,    115,    461,   -428,     83,      0,
+         0,      0,      0,      0,  -3987,   1063,   -717,  -2640,
+      -963,   -667,   -147,    536,    -68,    422,    341,  -1916,
+      -616,    996,    522,    568,   1174,      0,      0,      0,
+         0,      0,      8,    112,    693,    392,    445,   5309,
+       259,    121,   1670,    343,    176,    472,    197,    419,
+      -240,  -1178,   -107,      0,      0,      0,      0,      0,
+};
+
+static const int16_t cb0808l0[] = {
+       164,  -3637,  -3563,   -243,   -123,    -47,    -87,    -32,
+        62,    129,     -2,    131,    -36,   -202,   -197,     37,
+       -35,   -442,   -139,    -69,    -59,     29,    -62,    -67,
+       -17,    -42,     74,     10,    107,     74,   -109,     40,
+    -10210,    -33,  -3210,   -410,   -106,    512,     40,    -17,
+       109,     67,     99,    170,     53,     34,    -68,    -16,
+      3895,    -71,   -116,      1,    608,     66,   -215,     34,
+        77,     50,    -45,    -73,      3,     11,    -33,     18,
+       -34,     58,     25,   4420,     96,     77,    -67,     23,
+       -83,  -6724,    226,    -32,   -150,   -154,     30,    -12,
+        -8,     -7,     89,     42,    173,    -51,     38,  -1852,
+        40,    -48,    -40,     81,     34,     81,     66,     16,
+        20,      3,     99,     41,    123,     52,    154,     20,
+       -38,      6,  10889,    -44,     22,    -39,     55,    -34,
+        25,    -45,    -22,    139,     19,    -20,    -64,  -2242,
+      -473,   -113,    316,    127,    -31,    128,   -363,   -124,
+       196,    259,    -60,  -3792,    -41,   -103,    104,    -80,
+      -389,    179,    110,     83,   3174,     60,   -197,    101,
+        66,    -47,   -107,     96,    -27,     45,    -21,      6,
+       116,    -51,     -8,   -594,    377,   -279,    158,   -159,
+      4595,   -163,   -210,     19,      3,   -292,    -67,     14,
+       115,    -41,   -125,   -154,   -263,   -101,      4,    -11,
+       -89,    130,     58,     32,     92,     16,    126,    -93,
+       -99,  -4239,    -69,     88,      5,   -113,    -18,     35,
+        31,    -48,    -16,     35,     62,  -2839,     14,    121,
+        19,     41,    125,   -102,     26, -13144,      6,    -30,
+        -7,     60,      4,     36,    -40,    -26,     54,    -57,
+        -9,    -30,     13,     -1,     73,   -131,     29,    256,
+        39,    -51,    -12,   1788,      4,     10,    -58,     17,
+       -36,     -2,     13,     59,    -20,    -21,    173,    129,
+      -435,   -107,   -214,     33,   3078,     13,     31,    148,
+     -2975,   -311,     38,     25,   -247,   -542,     34,    106,
+      -392,     85,   -203,    182,   -232,    423,    629,   -183,
+       800,   -466,   3145,  -2498,   -305,     39,     22,     41,
+         0,    -14,    671,   -181,   3197,    109,   2900,     72,
+       -64,      8,    414,    133,    244,   -263,     53,    -69,
+        70, -13756,    -13,     21,     50,     12,    -14,    -12,
+        -7,     97,    -32,     24,     51,    -24,    -29,     53,
+        34,    -19,  -2341,    976,     25,    -58,     18,    -48,
+     -2490,    -55,    -31,   -165,    -36,     28,    -26,     92,
+        60,    137,     69,  -5341,   -125,   1966,   -154,    -66,
+       -13,    -84,    -13,     81,    -46,    -96,     50,    -50,
+      -114,     15,     30,   -211,   -147,   -555,   3998,     88,
+       358,   -159,   -105,    -51,   -109,    -16,     70,     91,
+       268,    125,    -95,    -62,     38,  -3227,   3591,    -15,
+        92,    -72,    115,    144,    -40,    142,    172,     72,
+       -17,     23,      1,     28,    -38,   -135,    220,    -80,
+      -179,      9,    -32,     -6,     37,    -33,     -3,    -89,
+      7314,      5,    194,    -13,     23,     31,     42,     84,
+       197,   -163,   -251,   -273,    193,    206,   -613,    394,
+      3469,   2587,   -701,     62,    301,   -104,    200,    164,
+      -201,   -473,     52,   -473,    128,   -381,    404,    -69,
+      -230,   -537,    157,    389,     -7,   2783,   3058,     95,
+       -59,   1618,      1,      4,     53,     -6,     28,     10,
+         2,     82,     28,     -8,    -14,     25,     59,     10,
+        -4,     36,   -777,  -4984,     29,      8,     85,    -43,
+      -137,    -34,     53,    -58,      1,    -27,     91,     15,
+        80,    -19,   -186,    467,     94,   -382,    129,    327,
+      3053,   -221,    399,  -2821,   1090,    278,     -2,   -163,
+      -398,    126,   -266,    180,   -235,     70,    -18,    -34,
+       -45,    159,    -32,     66,     11,   3177,   -188,     27,
+        35,    -52,    114,    -28,   -136,    186,   2146,    100,
+        92,      6,     58,    -70,    159,    -14,    -32,      9,
+         6,    -27,    -73,     28,     23,    -24,    101,    148,
+        80,    -52,    -27,    -53,    -36,      4,    -74,     47,
+       -30,   -108,     34,   7213,     12,     31,    -17,   -185,
+      3318,    199,    192,   3450,    -87,      3,     47,     46,
+      -141,     49,     83,    -82,   -132,    -82,     68,    138,
+     -1031,   -236,    390,    -37,     23,    -94,     -7,      9,
+     -2958,  -1846,    -43,     23,     25,    -79,   -193,    -77,
+     -3332,  -3355,   -139,     56,    163,  -3302,    -82,    -25,
+        35,     96,     73,    166,   -154,    174,   -121,     14,
+       -89,    101,  -3751,   -344,   -240,    -35,    401,    -14,
+        47,    -49,     24,    -78,     24,      6,     68,     51,
+      -145,     20,     83,     57,    147,   -100,     60,     33,
+       -53,     11,     37,  -5793,    -93,    -67,     -9,    117,
+       112,    -51,     60,     48,     49,    328,    293,    127,
+      -314,  -3022,    374,   3283,    -86,    588,   -346,    436,
+        -7,    -26,    -88,    104,    205,    150,    147,     34,
+       126,     85,     46,   -125,   -119,     75,     13,    144,
+      3721,    275,    -71,     43,    163,    -73,   -292,   -381,
+       -79,     33,     79,    -79,     34,    -94,     18,    229,
+        63,     28,    -44,     97,  -3606,     77,    -95,   -162,
+       163,     62,   6180,     81,    -51,    -19,     -5,    109,
+        71,      7,    -37,   -100,    -31,    -94,    188,    169,
+       -14,   2606,   -417,     18,  -4371,    -25,    180,    108,
+        17,     33,     48,    -46,    -93,    -77,     32,    -37,
+       -71,   -271,    -48,   -273,    -14,    115,    -59,   -312,
+     -3334,  -3046,     71,   -166,    379,    209,   -142,     22,
+        89,    -41,    -40,     -7,    -50,      8,    -15,     12,
+       -70,    -27,    -27,     25,    -31,     38,     -5,   2831,
+       -89,     -8,    -50,   -110,   1368,    -59,  -2307,      6,
+       179,     75,    189,    170,    -55,    330,    -70,    172,
+        67,   -492,    -57,  -3408,      9,    -93, -11400,     14,
+        -1,    -21,     65,    -15,     45,    -22,     40,    -10,
+       -41,     23,    -29,    -96,    -55,    -66,    -57,    -61,
+       -29,    -15,   -101,  -9831,     33,     42,    -35,     42,
+       -44,    -58,     11,    -40,     27,     21,    715,   -315,
+      -255,   -115,   1736,      4,     41,    -70,    -51,   -108,
+       160,     -9,     87,     -6,     36,    -20,    -68,     10,
+        82,    -33,    -42,     15,    -57,    -40,    -31,     21,
+     10023,     62,    -41,    -10,     85,    -65,    -12,    -61,
+       -72,   -610,    128,    -76,    198,    367,  -4564,     60,
+       158,    -13,   -134,    -45,    -33,    -11,    -51,    -72,
+       111,   -188,    232,   -494,    -27,     42,     46,    -23,
+       137,   3174,  -3598,    211,    152,    155,   -299,     56,
+       -23,   -123,    132,     50,     28,    -64,     28,      9,
+       -17,     31,    112,    -19,      4,     45,  -7175,     54,
+       -61,     -7,     87,    164,    195,    -29,    -48,     28,
+       -60,     70,    -69,    112,   -295,      5,    -89,     38,
+        36, -11501,     17,    -26,    -64,   -222,     91,    -23,
+       -89,      0,    -94,   2191,    -74,    -84,    -61,    -41,
+        57,     24,    -35,    -28,    -37,    486,    131,   3699,
+      -277,     64,   -125,   -243,    270,    313,   -112,    145,
+        47,  -2862,   -254,   -110,    -27,    -69,   -342,   -120,
+       216,     35,     24,     62,    -39,    -29,   2402,     -7,
+        -3,     14,    -47,    -27,      4,     27,     20,     81,
+       138,     75,    178,    421,  -2943,  -3080,    -84,    -40,
+       -58,   -195,   -182,    101,   -187,      6,    -83,    269,
+       -32,    -99,     51,    -38,     44,     82,    -14,    -35,
+         0,      8,    -23,  10754,    -73,    -57,     68,    107,
+        85,     77,    101,      1,    -28,    103,    -10,     48,
+        55,     33,    -93,    -18,      8,     28,    -14,   -575,
+        28, -11712,     90,   -186,     58,     38,    -42,   2156,
+       -82,     28,    -23,     43,     43,      8,     25,     65,
+         0,    -53,     28,    -88,    388,    -36,    363,     64,
+      3068,     56,    320,   -202,  -3433,     73,   -339,   -157,
+       373,   -216,    -43,    171,    140,   -437,   -143,  -2820,
+      -101,     53,   -111,     65,    -39,     65,    -30,     69,
+       -55,     49,     45,    126,    174,    220,     73,   -101,
+       -60,   -151,    -13,    -41,    -48,     -9,     25,   -122,
+       -80,  -2450,     19,     94,     14,    -18,    -19,     60,
+     -3252,    -10,   3390,    -15,   -365,    -15,    -73,   -222,
+       307,     70,    -95,    237,   -142,   -163,    -44,   -138,
+        -7,      6,    -36,    -67,      9,    -22,  10235,    -56,
+        -8,     44,   -155,   -117,    -22,    -32,    -74,    -14,
+};
+
+static const int16_t cb0808l1[] = {
+       -58,    222,   -154,    -74,    -53,   4939,    421,     67,
+        26,    132,     60,    -97,     -1,    -43,    328,      2,
+       460,    -66,    -11,    -45,    -56,    -86, -10569,   -129,
+        58,    -25,     39,     28,     26,     45,    -61,   -139,
+       -22,   -135,   -282,   -517,   -368,     55,    -47,     30,
+      -110,     47,     75,    -13,     65,    -41,    104,   4745,
+      -149,    -99,     28,    421,    517,    -56,     81,   -309,
+        67,    -42,     -6,     17,    -60,   -151,     50,    -84,
+        -9,     29,    -72,  -3019,     82,   -195,     41,    -14,
+      -206,    -34,    -58,    -18,     30,   2154,    -20,      2,
+        -1,     41,    -10,      7,     86,    494,    123,    328,
+        73,    213,    -29,     17,     43,    -92,    -61,     -9,
+      -130,   -113,     33,    -28,  -6677,   -198,   -185,   -236,
+       183,   -108,    739,     60,     98,   -314,     66,     10,
+     -3161,   -159,  -2850,    118,     37,    -41,   -119,   3087,
+        43,    -36,     42,    106,   -174,  -3379,    -92,   -142,
+      -237,     94,    -59,   -123,   -117,    144,    -75,    146,
+      -268,    561,  -1160,    336,   1477,    207,     89,    130,
+       127,   3763,   -372,     48,     99,    204,     84,    209,
+       103,    118,    125,    326,    -29,   -206,    139,    -61,
+        94,     77,   6624,   -163,     23,     27,   -104,    150,
+       -76,   -205,   -186,    -30,   -227,    -58,     17,     25,
+     -6536,    -19,    -66,    -45,    -72,     41,     49,    -79,
+       105,     -4,   -117,    -37,   -183,    216,    -27,    -23,
+       -31,  -2720,     53,    -23,    -46,     -9,    -10,     50,
+       -12,    -50,    -56,     35,   5498,   -110,     -2,     44,
+        -1,     13,     52,    -18,    -61,    -80,    -29,     25,
+        61,    -37,     93,    -19,     67,     75,    -41,    254,
+       161,    118,  -3379,    398,     -9,   -208,   -143,    207,
+      -135,    -32,    171,    187,   -194,    466,    -55,    158,
+        34,    105,   4986,     27,    -41,     20,     87,   -110,
+        39,     80,    -37,      8,    -25,    -44,   -108,   -171,
+      -366,    208,   -225,      1,   -124,     21,     81, -10349,
+       -51,     33,    -51,    141,    -36,    106,   -100,    320,
+       122,      3,    266,     72,     -8,   -112,     55,   -107,
+     -4154,    -69,      0,     71,   -153,    -80,    -50,     20,
+      -112,    225,  -1982,    273,    -19,   -127,    109,    -25,
+        47,     57,    -98,    -10,     42,    -25,     10,     24,
+        41,    -73,     45,  -3523,   -370,   3213,     54,    -87,
+        67,   -185,    100,    -33,    -41,      3,    -38,     70,
+      -108,   -120,    -67,   -144,   -181,    -33,   -104,    429,
+        89,    849,   3022,  -2765,   -341,    184,   -248,    610,
+       408,   -222,    184,     84,    -64,    479,   -146,     47,
+      -100,     13,     17,     -7,     58,    -13,    -36,    -23,
+        -1,    -25,     10,   2666,   -113,    -41,   -140,   3064,
+       105,     31,   3042,    -75,   -132,   -113,     80,   -100,
+       -39,    216,     -4,      7,    -43,    242,     19,  -1031,
+       731,  -3659,    -24,    -20,    109,    126,   2980,     19,
+       -11,    -48,     57,   -138,    -11,   -211,   -151,    540,
+      -113,   -110,      0,   -415,    150,    -80,    -80,    209,
+       -82,  -5212,   -125,    376,      8,    131,   -138,     30,
+      -922,   -320,    181,    -75,    138,   -112,    146,    -72,
+        64,    -75,   -262,   4872,    -11,    -61,     37,   -205,
+        48,  -2257,     82,    106,     93,    -66,     48,     71,
+        29,     72,     32,     29,     17,      5,     34,     29,
+       -29,    -72,     50,  -7702,   -114,   -117,     47,     11,
+        19,    100,     48,    -28,     -8,     53,     21,     80,
+       -43,     37,    164,     22,    -15,  -5258,    -23,    -32,
+       108,     52,      7,   -161,     11,     84,    141,     -8,
+       -12,    -25,    111,    146,    -96,     66,   7388,     54,
+        17,    -54,     62,     44,    -66,    -13,     26,     13,
+        85,    -79,    -21,     98,    156,    181,   -103,   -188,
+       -35,   -179,     83,    117,    -92,     49,   -185,   3800,
+       -90,     14,     42,     94,    -83,   -178,   -156,     -8,
+        33,     42,    204,     42,      1,    -85,     47,     10,
+     10804,     36,      8,     26,    -47,    -51,   -189,     83,
+       -47,    -23,    104,  -7142,    -67,     55,     21,     68,
+         8,    -84,    -60,    -43,    142,    -41,     27,    -72,
+       -70,   -170,   -141,    202,   -198,   -105,     41,  -3553,
+       -34,   -148,     34,    -62,   -161,    -20,    -73,    128,
+       162,  -8343,      4,    -71,    -46,     12,     27,     48,
+       -41,     50,    -19,    -88,      7,     79,     29,    -19,
+       -31,    -49,   -147,  -1886,   -103,   -213,     28,   -183,
+      4119,     87,      6,     -6,     51,   -190,   -167,   -116,
+        23,    -26,      7,    -38,   5442,  -1869,    -81,    197,
+       105,   -122,     65,    220,     32,    -57,    -39,    -15,
+         4,    112,    -55,   -139,   -825,    985,   -109,   2558,
+       218,     94,     65,   -184,   3269,    101,    -65,     42,
+       372,    -38,     58,      8,   -143,   -544,   -268,    121,
+        38,     61,    -63,    -10,    -30,    -52,    -76,    -74,
+     -6690,     -5,   -160,     76,    -77,     74,    374,   -917,
+       239,   -203,    550,    -84,   -305,    292,    -51,     36,
+       135,    -79,     27,    -69,   -309,   4561,    -67,     11,
+       -60,     43,     18,     -2,      8,    -15,     20,     22,
+        -2,    -41,  -2396,     37,    -79,     67,     27,    -84,
+       353,   -213,  -2336,     58,     39,    126,    -78,    -98,
+       -90,     -3,     -9,    -43,     -2,    -29,     -5,   -149,
+        42,     98,   -109,    137,     58,    -83,    -38,     51,
+      6525,     50,     97,    -31,      8,    132,    -71,    -55,
+        11,    120,      2,    -43,    136,    -37,    -85,    150,
+       133,     67,    -41,   -452,   -104,      4,    126,    100,
+     -2660,   -108,   -109,    -64,    615,    -75,     45,     10,
+       -57,    -57,   -108,    167,   -218,    -10,   -331,    -26,
+       -21,   6561,     73,   -599,    126,    -23,    250,   -103,
+        -4,    -28,    -20,    -35,    -19,     51,      9,    -25,
+       -40, -11220,     -2,     28,    -12,     23,   3481,    169,
+       159,   -217,    -48,    114,    -93,    -34,   -191,    -63,
+        31,    182,     79,     90,     55,     67,   -145,    409,
+       190,  -7791,    -26,     18,     71,   -113,    -80,     69,
+       -21,    -27,   -121,     51,   -148,    103,    196,   2726,
+       -67,   3022,    -28,     26,    -99,     51,     24,     61,
+       104,     89,    -57,    -23,   -112,     43,      6,     13,
+      -184,   -168,    117,    -29,   1865,     -3,     20,      8,
+        30,     32,    -81,     80,    -20,    -59,     37,     19,
+      -107,  -3920,   -259,     44,     23,   -129,     24,    -66,
+       -27,  -3071,    116,      9,    -76,     56,    -83,     25,
+        54,    -20,      2,    230,     56,    -41,    131,    -15,
+       -62,     61,     56,     74,    -34,    110,   4606,     -4,
+        18,    -47,    331,   -106,    -78,     70,     53,     70,
+       -22,     77,    -71,    -60,   -101,     70,      7,    104,
+        -7,     39,    -27,   7210,    253,    -15,      0,    -96,
+        32,     50,    -10,     33,   2058,     11,    -15,     42,
+       -14,     51,      4,     -3,    -11,    -86,     10,     33,
+        21,    -18,    -31,     -7,     53,     -7,     95,      7,
+        75, -11314,      7,     17,    -16,    -83,   -475,   -887,
+     -1141,      1,   -101,      5,    -46,    110,    -90,    -47,
+       -15,     19,     66,  -4078,    104,     43,    105,   -126,
+       181,     43,  -1655,    -81,    -11,     33,    -33,     33,
+        28,    -44,     35,     -6,    -38,     68,    -40,     67,
+        73,    -29,    171,  11982,     42,     -8,    -66,    -66,
+        40,    -19,     14,     33,    -63,     24,     94,    -94,
+      -106,    584,    330,   -108,  -3841,    782,   -300,    -11,
+      -303,   -174,   -217,     -3,     24,    168,    187,   -166,
+        54,    238,   -269,    -27,    182,     -4,    -72,    -47,
+        32,     39,   7622,    -46,    -67,    -53,     56,    123,
+       -50,     69,    -36,   -275,    628,    -55,    195,    -56,
+      -265,   -132,    -39,     -4,    169,    113,   -180,    -19,
+        88,  -6427,     42,   -257,   1180,    359,    335,   3821,
+       116,     79,      3,    -93,     67,    -44,     58,    -16,
+       265,    172,    -39,    -44,     18,     92,      4,    218,
+       122,  -2993,    150,    138,    618,     66,   -618,    402,
+      2227,     10,     38,    308,    338,    -70,    265,   1047,
+      -104,   -182,    305,   -162,    -99,    510,    -20,   -114,
+       529,    -42,  -3569,     52,    -80,   -314,    716,    -31,
+       259,     59,    -73,   -117,     38,    -44,    -16,    -74,
+     -5060,     35,     10,    -30,     54,    217,     36,   -205,
+};
+
+static const int16_t cb0808s0[] = {
+     -2191,   -865,  -1906,   -251,    274,    594,  -1214,    677,
+       482,  -1176,     43,  -1098,   -203,   -537,   1834,   1332,
+       308,    432,   -191,   3091,   1892,    926,   -446,  -1206,
+      -613,    198,    575,    -38,    264,    375,    278,   -691,
+      -107,     17,   -239,    261,    848,   -620,    183,    624,
+       122,   -358,    -50,   1017,  -1075,   -705,   -346,    337,
+      -121,    100,   -218,  -1051,   -463,  -4728,   -513,  -1151,
+       737,   4356,    684,  -1374,   1630,    521,   -520,    -52,
+        90,    119,    -43,   -131,     24,     -2,   -184,    -65,
+       614,    371,   -448,   -414,   1415,   -687,   -224,    584,
+      -768,  -1210,   2941,  -3057,    132,    406,   -952,    291,
+       295,   -798,    608,  -1476,   -516,     21,   -302,   2085,
+     -1700,  -2655,   -355,    175,   -409,    662,     46,   -247,
+      -201,   -580,    179,    -54,    458,    836,   1543,   1829,
+      -282,   -278,    412,   2422,   2077,    197,   -897,    451,
+       595,   1547,    538,    825,    563,    443,   -576,   -854,
+      -572,    241,   -471,    201,   -311,   -529,    112,  -5128,
+      -173,   -233,   -435,    340,    158,    -41,    273,   -224,
+       919,  -1570,   1075,    265,   -282,   1256,   1007,    231,
+       720,    417,   -401,  -4589,   -747,   -453,  -1112,     54,
+       156,   -561,   2746,   -422,    -83,    -91,   -381,   -270,
+     -1226,    987,   -965,    625,   -474,    565,   2890,    -85,
+      1291,   -280,    626,    -26,    840,   1122,  -1915,    780,
+      -702,    792,   -578,   -122,     -9,   1175,   -194,   -571,
+      2940,    540,     31,   1817,   -352,    264,    953,  -2035,
+       238,   3250,  -1561,    653,   -331,   -393,    827,   -382,
+       323,    281,  -1339,   -819,    545,    207,     14,    338,
+       432,    860,   1691,    142,    711,    381,  -1151,   4164,
+      -867,   -241,    111,   -513,   -863,     78,   1453,   -363,
+      -128,   -232,  -1853,   2373,  -1156,    210,    698,   1134,
+      -869,   -177,   -352,   1514,  -1370,   -789,  -1193,    819,
+       348,     80,    492,    179,   -909,    591,   -600,   -377,
+     -1709,     59,   -539,    557,    -45,   -362,    778,  -4919,
+      -647,    203,    865,   -313,   -257,    173,  -2415,   1005,
+     -1771,    843,   -474,   1619,   1193,   -186,    305,    636,
+      -662,   1976,    546,    -82,   -108,   -751,    850,    521,
+     -1625,  -3135,   -388,     64,    249,  -1189,  -1552,   2629,
+         2,   -221,   -105,    754,    251,    219,   -270,   -202,
+       545,    147,   1019,    108,  -1358,  -1317,   1362,  -1323,
+     -3322,   -405,   -371,   -554,   -334,    296,    493,    248,
+        -4,   1340,    123,   -584,   -804,   -766,   -164,   -470,
+       295,    218,     -3,     62,   -194,   -657,   5016,    280,
+        -4,    -69,   -281,   -994,    209,    307,   8648,    -37,
+      -138,     45,   -329,   -101,    -65,     98,     58,    714,
+        56,   -170,     60,   -203,   -248,    103,    107,   -408,
+       596,    170,     61,    584,    727,   -434,   -181,  -5116,
+      -502,    494,     52,     83,   -105,    325,     68,   -561,
+      -274,    371,  -1833,    -78,  -2990,    320,    141,   -748,
+      1764,   1157,   -538,   -276,  -1594,   -152,    838,    -45,
+      1137,     13,   -803,   -162,   -838,  -1199,   2003,    580,
+      3687,   -844,   -552,   -271,   -462,  -1034,    -29,    273,
+       862,    269,     95,    186,   -222,   -124,     79,    -34,
+      -684,    808,  -1061,   -916,    610,    539,   1289,    782,
+      1216,   3213,    -38,   -546,  -1209,   -398,     98,    -39,
+        58,  -1271,   -611,    573,    499,  -2170,   -157,   -943,
+      -595,    436,   1203,    487,  -1419,   -570,   1468,    711,
+      -589,   -101,   3299,    -45,  -1432,   -453,   1820,    677,
+      1052,  -1793,   1071,   -400,    268,   -464,    443,    508,
+      -273,   -736,   -233,    270,  -1187,  -1931,  -1208,   -519,
+      -879,    325,   1032,    280,    565,    294,   2588,   -303,
+       640,  -1398,   1070,    674,     57,   -165,    -46,    512,
+       757,  -3471,   -812,   -854,     45,    101,   3195,   -786,
+       -61,    122,  -1234,    -74,    119,   -389,    254,    -84,
+       829,   1465,   -930,    171,   -248,    201,    939,      1,
+        52,  -3517,  -1854,    147,   -843,    310,    502,    729,
+       191,    525,    333,   -669,  -3358,    215,    552,    156,
+     -1771,    982,   -746,    523,   -187,   -684,    456,    123,
+     -1544,   -145,     58,  -1083,  -1646,  -1309,    775,   1436,
+      1409,  -1114,   -171,     26,  -1775,   1103,   -392,  -2053,
+     -1221,    100,  -1120,     25,   -295,    306,   -105,   -514,
+     -4362,    156,  -2172,   -191,    -90,      7,    -62,    244,
+      -107,    521,    309,     22,   -663,    239,   -213,   -226,
+       100,   2228,   -330,   -197,  -1247,   -876,   1561,     -1,
+      -354,    439,   -163,   -318,    -61,  -1184,  -3022,   1434,
+        65,     87,    806,  -2093,   3016,   1022,   -779,   -391,
+       -18,  -1371,   -548,    910,   -910,   -438,    673,     48,
+      1028,    548,    153,   -337,    554,    353,   1686,    468,
+      -190,   -113,   -560,    542,     94,   -140,   -194,    -58,
+       165,   -154,   -311,   4744,   -148,     49,   -253,    180,
+       -65,   -125,   -139,    -49,   -115,   -270,    439,    139,
+       210,    202,   -207,    -65,   -477,    168,  -4720,    -96,
+     -1091,  -2071,   -567,  -1330,    237,    411,   -123,   1197,
+      2625,   1348,   -230,    362,   -147,   -139,   -699,   1210,
+      -299,     92,   2835,    -36,   -296,    287,   2426,  -1171,
+      -218,    884,   -320,   1130,  -1085,   1177,   -953,   -776,
+       609,    827,    -90,    131,  -2757,    567,    885,  -2359,
+       955,   -200,  -1883,    131,    282,    -80,    141,     -8,
+       -33,    333,    809,    357,    -13,    499,    597,    923,
+     -1725,  -1533,    465,    -93,   2187,   -841,    751,     74,
+     -2158,     99,  -1078,   -459,    648,   -258,    349,   -917,
+      1200,    374,  -1741,  -1013,    724,    -61,    182,   4032,
+      -581,   1123,   -400,   -459,   -443,   -316,      3,   -271,
+      -248,    -17,    595,    206,  -1188,   2869,   1338,   -253,
+       316,   -474,   1680,   -856,  -1487,    547,    679,    425,
+      -258,     92,     -4,    -24,    117,   -157,    385,   -257,
+      -332,  -5597,    -68,   -329,    -65,   -108,   -277,    202,
+      -400,    124,    -51,      5,     71,     90,   -927,    966,
+       780,    305,    703,    802,  -1661,  -1415,    -66,    437,
+      -610,    317,    795,    599,   -189,    322,   -519,  -4010,
+       729,   -620,  -2127,    351,    506,    -68,    162,   -983,
+      -288,   3167,   -140,    991,   -599,    128,   1868,     64,
+       -63,     -1,   2047,    155,   -871,   -130,    226,    508,
+       499,    882,   3762,   -383,    -23,      0,   -345,   -488,
+       167,    648,    395,    114,   1121,    343,    232,   -538,
+        15,    342,   -820,     38,    435,   -468,   -282,   -415,
+     -5021,   -293,    147,    533,   -128,    -70,    503,    844,
+       -86,   1836,  -2103,  -1143,    -70,   -510,    576,   -689,
+       410,  -2101,    433,    339,   -417,    820,    157,    173,
+       454,   -586,   1219,    -73,  -5123,    344,    397,     53,
+       105,    501,    -59,    515,    194,    356,     78,    706,
+       303,    332,   4532,    739,    961,   -521,   -392,     20,
+      -697,    823,    607,   -243,    332,    365,   -330,    307,
+       429,   -865,     -8,    545,     -3,   6041,   -310,    272,
+       464,     22,   -156,    142,    -63,    -87,    297,    -24,
+       562,     -9,    147,    341,    -21,    119,   1386,    947,
+     -1738,   -500,   -655,     95,     32,     32,    187,    518,
+      1330,     95,   -324,   3620,    737,    -54,     55,    670,
+     -1252,    995,    484,   1347,   -745,    244,    262,    -83,
+      -122,   1194,   -653,  -1111,   -327,   -325,   3579,   -214,
+       -37,   -412,   -267,   -377,    -62,    131,    360,    203,
+     -5713,    -42,     94,    279,    406,   -355,     34,   -144,
+       156,   -256,    -48,    -98,  -1392,   1273,    202,  -1249,
+     -3457,   -710,   1007,     37,  -1788,     86,   -570,    535,
+        17,   -369,   1640,    816,   -117,    128,   -969,  -1381,
+       224,   1519,   -996,   -833,    931,    185,    804,    465,
+        82,     69,   -247,   3312,   -430,    -23,    173,   -223,
+      3080,   1848,  -1187,  -1494,   -485,  -1131,    496,   -517,
+      -596,    320,   -853,  -1303,    240,   -298,    159,    527,
+      -257,    412,    839,  -1020,    706,  -3499,   -175,  -1089,
+      -717,   -325,    261,    310,  -1740,  -1035,   -403,   -229,
+      -861,   -970,    -62,   -192,    535,  -2154,   -364,  -1133,
+       979,  -3299,    353,    982,   -517,   1144,   -563,    675,
+       285,     63,     17,  -1957,     82,     28,   -513,    501,
+     -1183,   1476,   -813,   -254,  -1584,  -1181,   -426,    -56,
+      -916,    203,  -2693,    209,  -1066,  -1174,    279,    439,
+       201,   1179,    797,    407,    851,    927,    316,   -640,
+      1398,   -128,   2741,    563,  -1789,    989,    932,    247,
+         6,   -617,    268,   -691,   1112,   -569,    883,    298,
+        37,   -362,   -661,    -17,   -154,   -574,    721,   4578,
+       205,    507,     77,    -90,   -433,  -1613,    270,   -500,
+     -1061,   1634,   -388,   -432,   -648,  -1985,    629,   2887,
+      -201,    -32,    223,    621,    143,    446,   1384,   1109,
+       299,    329,  -1002,   -356,   1504,    -77,     49,    952,
+      4166,   -544,    -85,   -412,   -249,    474,     27,   -107,
+};
+
+static const int16_t cb0808s1[] = {
+      2632,   1511,    944,   -180,  -2377,     54,   -470,   -187,
+      -710,   -998,   -516,   -916,   -440,   -842,    285,     22,
+      -282,   -459,   -299,  -2769,  -2285,   -380,  -2194,    801,
+      -595,   -252,    504,    -69,   -752,    972,    639,    277,
+       502,    117,  -1072,   -145,   1462,   -528,   2165,    880,
+      -182,  -2953,    750,  -1090,    596,    105,    187,    555,
+      -153,   -113,    830,    161,    308,    -44,   -250,    -58,
+      -507,   -406,   -626,   1453,   1357,    116,   -456,   3242,
+      -607,     94,    390,    393,    114,   1069,     -2,      2,
+      2497,   1405,   -755,   1353,    192,   1288,   -187,    262,
+      1722,     91,    885,   -622,   -321,    246,  -1835,     17,
+       213,    -80,   -658,  -1940,    275,    845,   -365,    276,
+      2142,   -216,  -3402,   -646,    549,    -78,   -176,    -52,
+       785,  -1335,     44,    163,   -409,   1273,    679,   -377,
+       788,  -1355,  -1721,    332,    223,   1409,   -104,    165,
+       354,    322,   2414,  -1611,    216,     -6,   -232,  -1770,
+     -1931,   2496,   -530,    228,   -924,   -173,   -329,   -575,
+     -1709,   -900,    199,    223,    690,   -636,     73,   -367,
+       460,   -823,  -5105,    435,    957,    224,    246,    406,
+      -673,    752,    412,   -158,   -267,      4,    694,     10,
+       -45,    219,   1040,    778,  -1910,   1886,   -691,    674,
+      1085,   -537,    376,   1048,    858,   -161,    613,    376,
+       535,  -1349,  -1913,   -518,   -850,    665,    772,  -2985,
+       -66,    -42,   2142,   -848,  -1151,    237,   -211,   -161,
+     -2753,    603,    507,     39,   -575,    -61,  -1053,   -273,
+       290,   -258,   -162,    139,     95,    -12,   -201,   -236,
+       709,   -328,   -314,   -130,  -5337,    100,    -18,    -97,
+      -206,   1827,   1722,    302,    924,   -203,    761,   -715,
+       -24,    372,   -600,   2115,   1197,  -1406,    676,  -2068,
+      -167,   -221,   -936,   1419,    353,   -317,    245,  -2890,
+       623,    265,   -622,    204,   2549,    596,    239,    -25,
+      -672,    583,    117,    -13,  -2251,  -1325,   1984,   1431,
+     -1335,  -1268,    735,    245,    105,    593,   -193,   -614,
+       909,   -339,  -1033,    383,    102,    363,    732,   1439,
+      1028,   1275,    442,    987,  -3901,   -257,    -36,    224,
+      -116,   -402,    200,   -596,   -125,    372,   -572,    398,
+      -543,   1024,   1746,   -736,  -1056,  -1736,    953,   1026,
+      -965,    442,  -1565,   -448,    -96,   1498,     30,   -231,
+      -483,     73,  -3185,   1765,   1313,   -100,    477,   -198,
+       782,    316,    364,   -107,   -431,  -1795,   -244,    122,
+      -423,   -385,    457,   -872,   -535,  -1098,     80,   -110,
+      1420,    646,     33,  -3226,    648,    861,    328,  -1269,
+      -558,    495,    881,    112,    479,    170,   -309,   1904,
+     -1412,   -768,  -1220,    -34,    995,   -649,    162,      1,
+       153,    985,    762,   -263,   -188,     77,    760,  -2346,
+      3430,   -450,   1677,   1090,   1771,   2109,    -14,   -119,
+      -995,    268,    141,     33,     35,     31,    537,     65,
+      -345,     69,    192,    763,    -18,   1078,   3829,    274,
+       442,   -173,   -412,    434,   -695,    924,      2,   1551,
+       566,    -85,    217,    976,   2196,   -503,  -1401,    759,
+       922,  -3024,   -963,     -3,    600,   -452,   -193,   -787,
+         7,    186,    828,    515,    148,   -225,  -1250,   -985,
+       443,   -511,   2037,   1560,   3230,    647,   1418,   -165,
+      -261,   -369,    224,    450,   -100,   -271,   -122,   -511,
+      -691,  -1444,    906,   -144,    248,    452,    957,    -70,
+      -517,    116,  -3559,   -877,   -399,    418,  -1300,   -415,
+      -177,    770,  -2566,   -371,  -1673,  -1042,   -500,   -290,
+      -708,   -631,    193,   2494,    319,    545,    767,    102,
+       231,    -43,   -139,    -97,   -700,  -1592,    282,   1325,
+     -1419,   -647,    449,   1995,   -737,    661,   1617,    725,
+     -1464,    615,    906,    202,   -154,   -228,  -2194,   -231,
+       299,    110,   1318,   1053,   -312,    843,   -937,  -1697,
+      -592,  -1224,   -633,    -50,    792,   1600,  -1187,   -171,
+       211,   -744,   -306,    186,   1914,  -3119,   -904,   -159,
+       178,   -596,   -654,    817,     94,   -242,  -2376,   -218,
+      -421,   -365,   -699,    177,   -427,    -32,    265,    -33,
+       245,    -34,   5309,   -307,   -262,   -299,     86,    278,
+        33,   -200,   -180,    -56,    337,   1034,   -229,   4952,
+       306,   -609,    189,    -22,    280,   -160,   -507,    135,
+     -1265,   -252,    434,   -427,    158,   -546,   -130,  -2500,
+       597,    908,    918,    706,   1227,   3390,    995,    298,
+      -558,   1307,    765,   -144,    -37,   -286,    122,    215,
+     -1251,   1090,     85,   -914,    522,    316,   1829,   -701,
+      -365,  -3311,    312,     22,    680,  -1351,    220,    243,
+       166,    -36,    780,   2395,    -64,    836,   1037,    735,
+       966,    173,   1114,    192,    510,  -1054,   1341,   -616,
+      1559,    897,    338,     -3,   -194,   -214,   -573,   -265,
+       328,   -365,    433,   -505,    -86,     33,   -156,   -129,
+      -137,    119,    143,   5773,    -76,     68,    820,   1215,
+      1315,    713,     12,   1590,    131,   -193,   -881,   -227,
+       736,    581,    736,    -37,   -434,   -449,   -348,   4189,
+      2180,  -1360,  -1663,    -74,   1215,    278,   2092,    -66,
+       313,    388,  -1373,     25,    599,    888,    -87,    293,
+        30,    367,   1010,   -883,    818,   -910,  -1918,    864,
+       482,   -968,  -1249,    222,   1100,     23,    -87,   2493,
+      -248,   -622,    240,    151,    873,  -2735,   1325,   -700,
+      -411,    282,  -2361,  -1843,   -631,   -208,    103,   -411,
+       831,   -446,   -292,    450,    184,   -158,    484,  -1964,
+      4663,    123,     18,    174,    621,    158,   -788,    233,
+       302,    441,   -339,    200,    -62,   -197,     -9,   -236,
+       984,    584,   -521,   -373,   -205,    910,    392,    850,
+     -2968,     68,   -727,   1330,    578,     36,   -385,    754,
+      -538,    -36,    271,    418,   -548,   1775,  -1045,   -879,
+     -1407,    524,  -1085,  -1479,    371,     19,    873,    171,
+      2932,   -216,     42,     71,  -1187,   -570,   -524,    344,
+      -770,  -4086,   -735,   -515,   1055,   -551,    945,  -1408,
+       913,  -1005,   -222,   -443,     60,   -194,   -734,   1908,
+      -534,  -1351,     72,   -938,    -66,  -2756,   1313,   -169,
+     -1550,    450,   -610,    893,   1100,   -583,     87,   -145,
+      -210,    281,   1402,    674,      0,    -38,    874,   -363,
+      2436,   2156,  -1659,   -481,   -130,    -63,   -669,   -316,
+      -761,   -413,    108,   2362,    354,     76,  -1725,   -924,
+     -1443,   1251,    871,  -2058,    518,    955,   -283,    680,
+       -85,   -560,   -464,    127,   -216,  -1382,   1908,    238,
+      -182,    459,  -1227,   1144,   2266,    -96,    595,   -750,
+       912,   -198,   1786,  -1423,   -618,   -450,    185,  -1212,
+       706,   -689,   -154,   -365,   -681,  -1378,    914,  -1200,
+      -253,   -532,   3244,    444,      1,    -96,   -404,    -64,
+      -412,  -1400,  -2830,   -785,    940,   -217,    358,    618,
+       208,  -2974,   -365,    -32,    -63,   -233,   -868,   -413,
+       358,   -451,   1310,   -751,  -1329,  -2480,     63,    458,
+      -273,   1270,    316,     93,   -453,   -463,  -1258,    -57,
+     -1073,  -2037,     46,   -160,   4609,  -1193,    192,   -355,
+      -963,    -92,    752,    593,    102,    -80,   -121,    166,
+      -606,   -274,     28,    258,     45,    -45,    928,   -949,
+      -134,   -268,    -77,    242,   1623,  -1290,    739,    109,
+       285,    175,    -92,  -4053,   -482,    366,    217,   -126,
+      -843,    950,  -1068,    777,   1818,    550,   -891,    -34,
+      -995,   1976,   2677,   -764,     45,    -40,  -1800,    569,
+      -323,   -102,  -1064,   4000,   -109,   -423,   -289,    738,
+      -872,    808,   -977,    504,   -901,     41,    -45,   -287,
+      -140,   -444,    477,   -271,   -876,    301,  -2421,   1633,
+      -918,   -660,   -149,  -2542,   -503,   -265,   -107,   -623,
+      -447,   -782,   -858,   -535,   -220,    442,    661,   -209,
+       878,  -1601,   3610,    149,   -331,    190,    102,    270,
+      1451,    237,     13,  -1026,    178,   1290,   -281,   -217,
+        11,  -1728,   1043,  -2992,   -718,   -776,    357,   -615,
+      -231,    813,   -473,   1634,    539,   -513,    240,   1158,
+       144,     57,   1249,   1479,   -481,   -733,   1663,   -757,
+       641,    680,   -468,  -2697,    -29,    -62,   1253,   1142,
+       292,    245,    -96,    295,   -664,   -264,   -308,   -670,
+      -705,    155,  -4024,    330,    191,    -77,  -1502,    326,
+         9,    295,   -567,     34,   -104,   -123,   -320,   -255,
+      1124,    320,     98,   1299,   -436,   1491,   -341,    908,
+        11,      8,    988,  -1921,      5,  -1391,    859,  -1291,
+      -581,    546,    -95,    272,   -441,    185,   -256,    313,
+       466,   -393,    -50,   4430,   -940,     87,   -224,    390,
+      -539,   -290,  -1046,    531,  -2329,   1275,   -586,  -1046,
+     -1682,   1159,    908,   2023,    951,   -273,    -68,    713,
+      -556,    770,    783,    223,     60,   -881,    -97,    760,
+       556,   -237,   -263,   -246,   -240,    165,    526,    832,
+     -4761,    432,   -339,    186,    492,     81,   -136,   -827,
+      -390,  -1026,   -371,   -292,    937,   -243,   -136,      6,
+        49,   -223,   -600,   -355,   5306,    140,     34,    -84,
+};
+
+static const int16_t cb0808m0[] = {
+     -3555,   -106,   -131,    -53,   -156,    196,   -206,   -104,
+        18,  -2948,    122,    146,   -520,      2,    294,   -419,
+        -1,    -25,   -257,   9334,     87,    -55,    -42,     30,
+        92,     35,    195,     31,     59,     88,     47,     47,
+      -220,    564,  -1686,    426,    106,    396,     97,   1315,
+      2331,    167,  -1261,   1003,    732,   -300,   -342,    418,
+        87,    236,   -245,   2235,     11,    725,    -24,   -169,
+      -480,   2845,     96,    -34,     67,    857,     28,     50,
+        92,   2100,    -84,   -600,  -1990,  -2208,   -163,    299,
+       431,   -825,   -283,    299,    -98,    391,    -65,    -92,
+      -200,   -689,   2236,    -82,    -81,    -52,    127,     86,
+      -137,   -319,  -2561,    -90,    547,   -198,     10,    195,
+      -366,  -2688,    -77,   -234,   -112,   -245,    270,    199,
+      2674,    -57,   -673,     -9,   1029,    -31,    311,    -50,
+      -160,   -175,   2371,   2711,    409,    -19,     22,   -244,
+       312,   -158,    270,   -125,   -247,    118,    -91,   -602,
+        86,    174,   -216,     18,   3048,  -1953,    171,  -1985,
+      -297,    295,    -38,   -198,   -229,    363,    -13,    127,
+        13,   -202,   -117,     65,     74,     63,    125,    -62,
+        -2,   -543,   -680,  -4269,   -130,    325,    -49,   -245,
+       -50,   -509,   -151,    -19,      3,    152,   -980,   -129,
+      -234,    399,    349,    171,   -196,   4952,     -2,     36,
+       288,    771,   2313,    231,    -39,    572,  -3012,     77,
+      -501,   -215,   -228,   -444,    830,    200,   -188,   -157,
+      3248,    279,  -3319,      0,     76,     10,    160,    -80,
+       135,    102,   -349,    174,    -30,    -88,   -145,   -205,
+        10,   -185,    177,    -34,     25,     31,    218,     -4,
+       191,    172,    228,   -136,   -178,    268,    638,   3559,
+        55,    198,    145,    342,    -25,  -1940,   2866,   -334,
+      -921,   1941,   -464,    273,   -181,   -506,    -21,   -410,
+       116,   -179,    -49,   -273,    -22,    -36,  -1298,    274,
+     -1831,    321,   -382,    238,  -3464,    -68,   -194,     32,
+       -95,   -506,     72,     64,   -329,     19,    -39,    347,
+      -302,    204,    145,    -72,    855,   -112,  -3596,    989,
+     -2801,    386,  -2623,   -471,    101,   -155,    257,    291,
+        30,   -153,    185,    172,    511,     20,    166,    274,
+        29,  -3023,    129,     33,   -219,   -205,      6,     47,
+      -407,    137,    563,   -106,  -2065,     76,    201,    -99,
+      -170,    -77,    170,  -4536,   -440,    -96,   -940,  -1066,
+        81,    205,    358,    435,    -78,   -148,   -201,    -85,
+      -307,   -306,     14,    -47,   -101,   -187,   -136,    380,
+        -4,    -32,    -34,    -54,    528,    -58,   6389,    302,
+       -79,     52,    -28,    -65,    -77,    -12,   9024,   -100,
+       262,     20,    -67,    -31,     50,    -33,    -30,   -140,
+       326,  -1170,   -304,   -136,   -233,    170,     60,    314,
+      -166,   -208,   -105,   -245,   -169,    -72,    137,  -7173,
+        -2,    375,    152,    226,   -206,   -341,    303,     47,
+      1010,   -188,    577,   -292,  -3581,    -12,   -195,     20,
+      2165,   -206,    -88,    -83,   -132,    -40,   -443,    236,
+      -333,    179,   -211,    -56,    318,   -409,   3106,     95,
+     11636,    340,    204,   -323,    167,     76,     61,     65,
+      -157,     71,    -21,     38,     66,    391,    -52,     20,
+       -17,     11,    259,     45,   -194,    440,   3432,    122,
+       468,   -595,  -1856,     94,   -427,   -133,    149,   -273,
+        61,  -6622,     48,     97,   -162,     93,    402,   -104,
+      -207,     64,   -278,     92,    387,      3,     96,     -2,
+       -27,    -30,     84,     64,     35,    -65,     98,     85,
+       -16,   -248,   7930,     74,      4,   -104,     83,    -48,
+        40,  -2104,    -86,    -89,     99,   -142,     65,  -2713,
+        63,   -431,    523,    687,    212,  -1515,      3,     59,
+        55,     -6,     22,     -8,   -148,    180,     78,   7833,
+       -63,    -83,     13,   -187,   -116,    156,    -29,   -186,
+      -160,    148,    -82,   -303,   -166,    112,   -103,    -39,
+      -165,   2827,    -54,    -26,     24,  -3055,     78,     21,
+       128,    -81,    -25,   -122,     51,    -54,    -19,    188,
+       -18,     -1,   -140,    -18,  -8085,    124,    -46,     45,
+      -574,     12,   -150,    147,     65,   -209,   -396,   -444,
+     -3882,   -291,   -231,    296,    244,     76,    180,     36,
+     -2575,    659,    -63,   3277,    -85,     48,   -518,   -353,
+       130,     50,     13,    338,   -343,   -276,    -16,    353,
+     -6036,    -77,     18,    139,     43,    335,    294,     99,
+       219,    442,    -25,    -53,     40,    271,    175,   -282,
+       -91,    430,  -4428,    -15,  -2857,    -62,    -27,   -170,
+        33,   -681,   -110,    -76,    153,     42,   -134,   -145,
+       222,   -177,    -39,    314,   2270,    526,    500,   2417,
+       339,   1808,    -17,    464,   -525,    -97,    124,    -32,
+       370,     48,  -1675,    -62,   -169,   2642,   2511,    -43,
+     -1037,   -184,     54,   -569,   -504,   -247,    -40,    327,
+         7,     82,   -197,   2774,    -34,  -2931,   -204,   -112,
+       194,   -362,    187,     65,   -166,    115,   -125,     14,
+       210,    144,    -75,     57,   -255,   -151,  -3566,   -153,
+       182,     89,  -2530,     98,   -265,   -173,   -133,    260,
+       -25,  -1292,     35,    131,    -98,    -85,   -237,     82,
+      1353,     47,   3842,    148,    171,    183,    234,     89,
+       -93,     47,    102,     -4,     90,   2980,    289,   -231,
+       353,    497,   -109,    190,  -2869,    697,    136,     90,
+      -244,    298,   -119,   -519,    -50,    207,    -43,  -1376,
+       356,   1934,    701,  -2323,    671,     71,    -56,   -167,
+     -3793,  -3749,   -103,    134,   -228,    -13,     27,    -45,
+      -105,    172,    -77,    -23,     53,    110,   -118,    -80,
+      -164,   -192,   -563,    393,    -58,   -428,   -360,   3696,
+       162,   -173,   1683,   -430,    452,    -92,    107,    -41,
+        28,    -85,    421,    -66,    354,    -88,    723,   2751,
+     -2955,   -481,   -134,   -231,   -145,      3,     65,    -88,
+       189,    187,    151,    174,    -36,    240,   -253,   -235,
+      -194,  -5410,    -47,    -98,    338,   -487,    -81,    -35,
+       -82,   -440,     31,    109,    217,    276,  -1805,    278,
+       273,   -369,    629,   -293,   -525,  -3832,     73,    -56,
+      -363,   1709,    177,  -2813,    796,   -162,   -341,   1176,
+       -75,    533,    854,    719,    242,   -194,     90,   -147,
+       203,   -136,   -138,   -764,      6,  -2787,    -13,   1104,
+      1497,   1097,     90,   -867,   -718,   -317,    119,    180,
+       160,    257,   2532,   -557,    -62,     14,    665,   1520,
+       456,    826,    394,   -605,    908,    222,   -140,    121,
+       121,    232,    124,     96,    -87,     48,    -51,     41,
+     -7821,    -37,    130,    -11,    -33,   -137,     16,     42,
+      1509,     -8,    119,    -83,    -18,     64,     41,   -178,
+       -28,    182,    532,    678,    -75,    277,   -230,    -70,
+       -71,     -8,   -150,    321,  -6298,    -20,   -131,    -65,
+       139,   -215,   -155,    -27,   -110,   -257,     32,    201,
+       215,    184,   8932,   -106,    -50,     66,     15,    -44,
+       203,    -38,     19,    -78,     65,    135,   -123,    166,
+       117,     76,      4,     34,    -90,   5984,     59,    -72,
+       356,    -64,      6,    -62,     43,    -86,   -175,   -106,
+        10,     25,   3812,   -135,  -3313,    142,    348,   -101,
+       -35,    378,   -250,   -106,   -299,    237,     40,    -32,
+       236,   -521,     63,   -143,    538,   -256,     43,    -45,
+      1642,    726,  -3225,    109,   -997,      3,   -256,    -27,
+      -182,    -78,  -4092,     -9,    231,     34,      9,     -6,
+       155,   2842,     53,   -130,   -390,   -146,    168,    -74,
+     -2023,   -955,    576,   -629,    -76,     70,    140,   -287,
+      -401,    966,    359,   1185,   -226,    713,    753,   -739,
+     -4238,   3364,     75,   -213,     27,   -172,    -34,    171,
+      -118,    -46,   -164,    -13,    -54,   -203,   -154,    -12,
+        65,  -3777,  -3452,    297,   -104,    -93,    -81,     69,
+      -179,   -321,     51,     47,    242,    -15,   -144,    -43,
+      2827,     67,   -305,     54,  -3044,     57,    -15,   -427,
+       311,   -205,    226,   -490,     37,    363,    -88,   -408,
+};
+
+static const int16_t cb0808m1[] = {
+      3329,     59,    195,    -91,    -70,   3262,   -132,    360,
+       157,   -410,    184,    -99,   -138,    337,    289,    317,
+       156,   -589,   -127,   -204,     37,   -175,  -5661,    -52,
+       942,    156,     -1,   -197,    353,     90,     57,   -287,
+      -218,    438,     -4,   -262,      9,    322,   -167,   2904,
+       -12,  -2647,   -248,   -203,   -267,   -116,   -135,    333,
+      -220,   -200,     40,    228,   2677,   -462,   -183,   -129,
+      2898,   -728,    793,    422,    541,   -350,     28,    222,
+      2790,   -231,   -195,   -191,   3002,    182,   -610,    145,
+      -226,   -102,    285,    344,   -357,    217,   -146,    -98,
+        18,   -255,     96,   -151,    266,    208,   -459,   -132,
+      -345,   4059,   -371,     79,     44,    -63,   -233,    334,
+        44,   3884,     49,  -3303,     88,    -23,   -287,   -461,
+        57,     94,    -53,   -129,    104,    167,    -25,    -79,
+      -125,   -630,  -2352,    150,   -419,     40,    -63,    603,
+        67,    209,    321,  -1765,   -200,     68,    473,    622,
+         5,  -2883,    112,    188,   -189,  -2765,    169,    397,
+      -330,   -642,   -798,    129,   -110,   -164,    -20,    176,
+      -213,  -5415,     39,     31,     13,    270,   -477,    166,
+       167,      4,    216,    -12,   -528,    -75,   -291,    396,
+      -499,  -2011,   -172,   -265,     96,     83,   -279,    114,
+      -166,    833,     30,   2493,     94,    130,   -183,   -659,
+         1,   -227,     75,    349,  -2757,     82,   -116,      9,
+       952,   -112,  -2444,   -333,   -206,   -406,    201,     15,
+      -768,     88,   1390,    -33,   -558,     97,   -201,     29,
+      3470,     50,    -40,   -271,   -171,    -26,     47,    485,
+      -250,   3318,    112,    639,  -2911,    123,   -264,      3,
+         8,    379,     73,     54,     88,    227,     73,     58,
+      -572,    782,   -183,    305,     49,    -23,  -2968,    -41,
+       291,    -25,    157,    295,  -2118,    125,      5,   -193,
+      -159,   -543,    -75,   1181,   -191,   -547,    -93,    117,
+     -1831,    265,   -607,    -30,    194,  -3929,    -70,    159,
+        79,  -1519,     38,    201,     14,    -24,    -76,   -366,
+        14,  -2748,      0,   -372,    405,     39,   -170,    320,
+      -257,   2153,    -12,    158,    322,  -4013,     22,   -101,
+       217,    637,    273,   -430,    228,   -428,    102,   -356,
+      -266,     82,    -31,     14,   -223,  -2595,   -360,   2094,
+      -379,    624,   -192,    245,    294,   1484,   -117,    156,
+       -53,   3668,  -3573,   -118,   -213,    257,   -211,     66,
+       -62,   -173,   -166,   -123,    163,    -81,    -39,    -74,
+       -21,    126,    722,   -136,   2050,   -206,     86,    275,
+        76,   -249,     55,  -2508,     95,    -60,    -34,   -360,
+        -9,    187,     34,    -87,    -30,    137,     48,   4761,
+       109,    511,   -496,    104,    399,   -361,    162,     78,
+       -29,    159,   -112,    182,    246,     52,    255,    338,
+       -35,     -1,    -68,      5,    182,   7675,   -119,    -14,
+     -1901,   -111,   -106,     22,    -16,     81,    159,  -2423,
+       -71,    -24,   -153,   -520,    126,    370,   -186,    230,
+       -51,   -401,    206,    -32,     52,    -71,    -79,    503,
+      -239,   -231,     55,   -133,   5226,    -45,   -165,     57,
+      2314,   -209,    302,     78,    154,  -3092,   -605,   -498,
+       410,    159,    336,   -147,   -120,    143,     36,    587,
+      -182,   -182,   1457,   1008,   2524,   -446,   2333,   -497,
+      -761,   -162,    125,    420,    225,   -117,   -324,    437,
+       -50,    190,    129,    259,     33,     -2,     -9,     32,
+       -24,     91,     97,    201,     19,    169,   3535,    485,
+      -144,    330,   -193,  -2715,    603,    303,   1124,    107,
+     -1386,  -1437,   -203,    180,    -81,    303,    209,    -21,
+       -65,     26,     91,     98,  -1349,    196,   2103,    917,
+      -732,    834,   1456,    -92,   -455,   -130,   -732,   -288,
+        39,    -85,   -557,    -39,   3213,    297,    392,   -378,
+      -520,    795,  -2407,      6,      7,    406,    203,    -73,
+      -247,    317,  -3336,   3166,    206,    -36,    159,   -279,
+       442,     54,   -324,    -18,    544,   -250,    142,   -440,
+       100,   -145,  -3772,   -199,    139,   -156,    -11,     34,
+      -178,   -233,   -370,    601,    -58,   1679,   -170,     76,
+       684,    -35,    -73,    -52,    -33,     -3,    -89,     -5,
+       -82,     73,    -11,     51,    -48,    -12,   -376,   4348,
+      -203,   -432,    189,    -35,    144,     31,    181,   -106,
+     -5112,    552,    480,      0,     63,     31,     33,    504,
+      1055,  -3007,   -214,    154,   -100,    246,    269,   -423,
+       579,     63,   1668,   -296,    390,    109,     21,     -6,
+        71,   3321,    246,    197,    355,   -198,    472,    135,
+       437,  -1734,   1299,    227,   -618,    -48,   -199,    217,
+      -230,     70,     99,   2632,   -203,   3105,    -87,    149,
+       303,    124,    362,   -322,    -44,     38,    104,    -28,
+        48,   -175,   -468,   -410,  -4451,   -152,   2157,     26,
+      -281,   -581,     36,   -205,    101,    230,    192,   -129,
+       319,     20,     65,   4879,    123,   -236,   -178,   -128,
+      -387,   -124,    528,    142,   -775,   -301,    -88,   -380,
+       120,    -42,    -17,     64,  -1074,  -3350,   1335,  -1078,
+       -14,   -462,   -113,    253,    450,     36,     -8,   -346,
+       -54,     -7,     52,   -100,     74,   8266,   -193,    -36,
+       -51,     12,     59,    -68,    190,    -36,     89,     38,
+       -59,     13,    269,    109,    -15,   -141,    -64,    -60,
+       238,      6,  -4338,    381,   1252,    354,    -41,     41,
+       191,   -236,    122,  -2712,    352,   -117,   -121,   -284,
+      1516,    473,   -332,   -277,  -1792,   -335,     84,     64,
+      9595,   -246,   -278,    446,    -95,    -32,     60,   -146,
+       104,    -84,     -3,    107,   -116,   -377,    101,   -149,
+       -45,    364,    104,   -193,   -254,   2929,   -164,    -93,
+       324,    749,   -928,    435,   2357,    350,    -40,   -153,
+       -48,   -626,    390,    -48,  -4248,   -458,   -930,   -218,
+      -486,   1769,    335,    152,    165,    111,    118,   -407,
+       -87,   -373,   -333,   -134,     86,    -32,   -144,    -18,
+       -16,  -7549,   -146,     49,   -184,    116,    -28,    -51,
+       190,    115,     80,     68,    129,    206,    294,    331,
+       179,   -270,    174,   2444,     55,  -3271,     70,   -124,
+       228,    330,    -21,   -419,     62,   -140,  -2388,      7,
+     -2683,   -129,  -1050,   -548,    811,    189,    359,   -385,
+       -82,   9031,     95,     77,    -69,    164,    261,     61,
+       -73,    230,   -163,    141,    -38,    -43,   -150,    164,
+        28,    164,     59,    -58,   -312,   -134,    102,    -67,
+       166,   -163,     63,  -6795,   -103,   -147,     81,    273,
+       133,    122,   -162,   -207,    127,    -60,   4628,     -1,
+      1315,    518,   -163,   -246,     54,    239,    154,   -154,
+       265,   2000,     25,    227,     42,    179,     88,  -3446,
+      -214,    182,    438,     90,    196,    -69,    134,    -56,
+      -451,    716,  -1120,   -287,    118,    230,    -37,    145,
+       284,   -250,    139,   -947,    203,  -3176,    -57,    151,
+      3201,    818,    -87,    347,   -486,   -201,   1176,   -325,
+      -966,   -263,   -184,    238,   -156,   -396,    152,    959,
+       -59,    -33,   -159,     -3,   9394,   -119,    -81,    -50,
+        67,      9,     27,    -62,   -121,   -210,     48,   -211,
+         5,    396,    633,     34,    -16,     67,   -247,    -77,
+       128,    441,   3896,    251,    970,    119,   -387,    -35,
+       124,    -64,   -664,  -6550,    101,    -52,     19,     44,
+      -132,     79,    731,   -155,   -262,   -140,    -31,   -191,
+      -110,    276,   -162,    -49,     81,   -117,     15,   -570,
+       420,  -1232,   -125,   3737,    -95,    544,   -149,    463,
+      -129,   -345,    350,    183,    173,    197,    464,    180,
+      -249,   -365,   -785,     -9,  -3411,   -235,   -124,    225,
+     -4516,    196,   -150,    -89,    -89,     54,   -110,    137,
+      -431,    272,    -12,     -7,    114,   -201,    166,   1570,
+       -74,    -88,   6019,    350,    -75,     68,    -29,    -81,
+       -50,     57,    -62,    103,     61,    276,     22,   -131,
+      -134,  -3347,    -60,  -3397,   -311,   -105,     90,   -159,
+      -222,    151,    224,   -210,    264,    192,     29,    -84,
+};
+
+static const int16_t cb0808sl0[] = {
+        24,  -3148,  -3111,    106,     45,   -114,    -85,   -211,
+       154,    172,    246,    368,   -130,     58,   -135,     70,
+       102,   -150,    -76,     -7,     13,     -1,    -29,     20,
+        -7,    112,   -234,   -115,   -138,    -40,    106,    178,
+     -7276,   -537,     25,    856,    460,   3107,    146,   -520,
+      -631,   -118,    393,    179,    144,    -86,     47,     82,
+      3031,     28,    164,   -308,   -411,     72,    138,    378,
+       242,    253,     12,    158,    -28,    -60,    -29,    -46,
+        -5,    -11,     84,   2753,   -113,    -65,      3,      5,
+        13,  -5110,    -74,   -126,   -129,    -82,    -58,    116,
+        15,     68,    243,    -32,    126,    -48,     11,     -7,
+        75,     10,    166,   -153,      8,    -43,    -38,     81,
+       -41,     13,    100,     27,     46,   -441,    -56,     35,
+         4,     51,   7528,     52,   -141,   -153,     39,    -36,
+       -86,     80,    -35,     50,    -46,     23,    178,  -3986,
+     -3350,     59,   -278,     37,     -2,     14,   -157,   -208,
+      -317,    218,     15,   -296,    -32,    -51,     36,    -27,
+     -2062,     28,    -37,    322,   2286,    214,   -196,   -171,
+       -64,   -163,    265,    -50,      3,   -177,    -22,     68,
+       124,     37,    -15,  -2202,     60,    133,      4,    371,
+      2753,   -111,    480,   -446,    484,     43,    150,   -331,
+      1410,   -791,    123,   -136,   -192,    267,      0,    -89,
+      -105,    421,     68,   -126,     79,    279,    202,   -132,
+      -208,  -3345,   -105,     59,    118,   -647,    -48,    -12,
+       145,   -403,    200,      7,     -4,  -3192,   -223,     64,
+         0,    415,    366,    136,     49,  -7611,     79,   -105,
+       127,    -69,    -43,    103,    -95,    -93,    -10,    -30,
+        94,    108,   -109,      0,    -87,    -70,    300,    -93,
+       113,     25,    -17,   2263,     41,    192,     18,     73,
+       179,    129,    149,    -81,     -1,      0,    201,    184,
+       651,      8,     18,    114,   2820,    383,    -71,    376,
+     -2281,  -1190,   -143,    121,    -45,  -2157,   -410,     81,
+       -14,   1537,   -833,     29,   1150,   -494,     -8,    -14,
+       210,    188,   3073,  -1775,   -123,     80,   -103,    227,
+       296,    111,   1637,   -197,   1349,    174,   3276,     49,
+       -98,     74,    660,      3,   -252,   -356,     -9,    527,
+       -63,  -7995,    -16,     85,    249,     74,     26,      2,
+         3,     26,   -124,    -61,    -26,   -144,      4,    -52,
+         6,   -517,    -95,   2566,    -26,   -190,   -196,   -509,
+     -2982,      4,   -178,     -9,    -67,    -25,      1,    193,
+       -68,    -46,    -82,  -3734,    -14,   -339,    -44,   -151,
+        55,    230,     -3,    100,    -47,    -69,     35,    107,
+       127,   -175,    -11,    -10,   -158,   -140,   2934,   -132,
+      2571,   -158,   -217,    106,    137,   -222,     74,    -42,
+        64,    559,    122,     73,   -112,  -2964,   2502,     13,
+       301,    -41,    203,   -382,   -151,   -221,   -147,    -24,
+        83,     37,    -45,     56,     89,     71,    109,    -14,
+       -43,   -130,   -108,    -18,     74,    -23,    -34,     79,
+      7662,    -88,     70,     21,   -110,    147,     26,    250,
+        74,    165,     49,     43,     45,    -22,    -14,    293,
+      5275,     57,    -72,     93,     40,    115,   -139,   -332,
+        95,     92,    -26,     26,    169,    -94,    332,     71,
+      -482,    137,    190,    114,     14,    151,   3125,      6,
+       109,      6,      7,   1543,    282,    -24,     24,    142,
+        33,    123,     41,    -72,   -253,    -33,    309,   -107,
+       -64,   -131,     56,  -3528,     82,    -17,    417,    -47,
+      -588,    274,    155,    158,   -245,    186,    147,     -7,
+       -50,   -218,     12,    118,    -62,    652,    145,     64,
+      2473,   -146,    220,  -2973,     97,    284,     29,    268,
+        29,   -208,    -40,   -251,   -175,    -16,    -58,    -65,
+        28,     26,     55,     74,    -12,   1911,     43,    -82,
+      -150,    -13,   -119,      8,    119,    156,   1550,    -88,
+      -102,     46,    226,   -132,     95,    100,     87,      7,
+       -46,      8,    -32,    -16,    -12,    317,    -33,    -27,
+       291,    -88,    169,      1,   -101,    -61,    161,    162,
+       -33,     -1,     11,   5097,    -34,    142,     31,     94,
+      3619,    -94,     67,   3379,    -65,     28,    254,    189,
+       110,    138,    -41,     52,     32,   -104,    154,    172,
+     -2365,   -464,    281,    207,    -66,   -190,    399,   -158,
+        13,   -155,   -223,     92,   -108,    -25,    468,    189,
+     -4359,     42,   -135,    138,     36,  -1403,   -264,   -336,
+      -164,    -49,     54,   -125,    -61,     62,     16,    172,
+       182,   3134,  -1373,     63,   -227,   -106,   -133,   -165,
+       -69,    -57,   -184,    -46,      9,    -57,     50,     -3,
+       -62,    -15,   -123,    108,    111,     91,   -161,     23,
+       -81,      7,    208,  -5385,   -244,     24,     95,     12,
+      -264,     62,    -44,     21,   -240,   -299,    -12,    117,
+       -61,  -2551,    389,   2816,   -179,    203,   -421,    899,
+        -7,    174,   -200,     98,   1036,   -166,     11,   -137,
+        78,     -7,   -121,    245,    -77,    124,    102,     51,
+      3136,     74,   -310,     40,    212,   -239,   -373,   -154,
+       398,   2967,    654,    488,    103,   -230,   -330,    831,
+       -63,   -473,    152,   -556,  -2186,   -371,      4,     86,
+       -12,   -141,   5503,    -87,   -123,    -17,    -15,    154,
+       192,    -86,     97,    165,    352,     56,    154,     43,
+      -331,   1004,    -52,   -131,  -3311,      3,    110,   -153,
+       -70,    137,   -168,    -20,    115,    140,    -25,    -54,
+       -13,   -300,     57,   -131,    214,    261,    -92,    618,
+     -2752,  -3146,     61,    -51,    210,   -230,     87,   -184,
+       330,     22,    -19,   -107,   -477,    -39,      1,    127,
+       178,    -73,    425,     56,    -25,    -41,    135,   2423,
+        59,    -46,    -10,     49,   -116,    -51,  -2239,   -228,
+       -75,     48,      3,    181,    161,   -133,   -355,     81,
+         5,     84,   -222,    -83,     92,     33,  -7558,    -38,
+        -3,    159,     33,    -58,    -37,   -107,     16,    -61,
+       -94,     93,     97,     49,   -275,     29,   -198,     -4,
+       -68,     87,    116,  -7039,     46,     81,    -25,      0,
+        -7,    -46,    152,     64,    -40,   -143,    -56,    147,
+       403,    257,   2380,   -538,   -400,   -132,    -89,    -29,
+     -2878,    457,   -552,    -12,   -189,   -370,   -357,  -3679,
+       422,     63,    200,    116,     -9,   -229,    -72,   -100,
+      3346,     88,    -18,     28,    -47,    159,    108,   -160,
+       253,     58,   2938,     55,    366,    -33,  -3209,     31,
+      -148,    -10,    -40,   -443,    127,    120,    106,      9,
+         4,   -240,    200,    129,    328,   -102,    187,    182,
+       112,   2757,  -3260,    314,   -163,     -3,   -185,    354,
+       -97,    -69,   -199,     41,   -143,     19,    108,    -22,
+       -32,    -18,   -149,     35,     31,     -5,  -5083,     52,
+         9,      5,    -44,    -52,     76,      7,   -100,      7,
+       -79,      0,    -33,    110,   -208,     20,   -159,    -76,
+         2,  -8192,    156,    118,   -306,    -88,    136,   -293,
+      -176,    163,      8,   1871,   -112,    229,    311,    -95,
+       -75,     17,    217,    152,     62,     17,   -246,   3579,
+         5,    -87,    -21,     92,    114,   -185,    118,      8,
+       196,   -124,   -220,    175,    104,     54,    104,    -40,
+       -45,   -152,    392,    216,    -24,    -28,   2024,     -6,
+        42,    -91,   -201,     -9,   -192,     35,    -43,   1661,
+      -356,   1207,  -1322,    340,  -2937,    -16,    163,   -801,
+      -423,    197,   -512,    -70,    229,   -412,    291,    511,
+       -36,   -179,    -98,    -54,     93,     87,    263,    -44,
+       167,     77,     -4,   7278,   -101,   -193,     91,   -251,
+      -131,    269,     15,   -168,    -22,    -26,     44,     24,
+       154,    115,    -11,   -124,     28,     37,    -14,    -46,
+       -67,  -8192,    -51,   -169,     41,   -302,    -81,   1991,
+       -11,    136,   -175,     71,   -104,     89,     60,    137,
+        17,    106,     96,   -238,    -83,    -52,   -113,     53,
+      2903,    -47,      9,   -227,  -2784,   -245,    146,   -196,
+      -216,     41,     -6,   -128,    -53,      1,   -128,   -145,
+       149,     32,     25,    -57,    -14,     72,   -135,     10,
+     -1946,    -67,     74,   -127,    141,   -299,     55,      8,
+       947,  -2239,   -271,     74,   -227,    -81,     31,    291,
+       -86,  -2914,     22,     -7,    293,      2,    -25,      9,
+     -2997,     89,   3158,    192,    -46,   -246,   -140,     46,
+       287,    133,   -110,    308,   -114,    -33,   -106,      9,
+       -89,    105,    364,   -172,    185,    -61,   4464,    -92,
+      -264,    -66,   -161,    102,   -178,   -264,    -21,    114,
+};
+
+static const int16_t cb0808sl1[] = {
+       246,     -6,   -180,     90,    127,   3322,    598,    182,
+        81,     82,     67,    -39,     87,    -60,     -8,    -89,
+       185,     99,    -25,     27,      9,    -59,  -7421,     49,
+       -17,    116,    -85,      6,   -305,     88,   -164,     99,
+        61,   -415,   -114,   -288,      1,   -165,    -12,      5,
+      -143,   -142,   -521,   -245,    -53,     38,    -99,   3709,
+       -52,      0,    -41,   -135,    147,   -217,     62,  -2144,
+       255,    132,    264,     65,    -37,    204,   -338,   -280,
+       192,   -184,   -158,  -3685,    -26,    203,    430,    -29,
+       -16,     77,    230,   -311,    597,   2553,  -1126,    -63,
+       154,   -431,   -161,    315,    286,   -147,    177,     -3,
+        93,    449,    253,    -37,    101,   -244,    -77,     42,
+      -384,     22,     36,    235,  -4973,    243,   -120,   -105,
+      -226,   -114,   -455,   -404,    164,   -505,    476,   -124,
+     -2837,    -82,  -2920,     -3,      0,    134,    -94,    264,
+       -53,    -53,    108,     -3,   -845,  -2813,    228,   -179,
+       -60,     -2,     65,     33,   -153,    -16,   -149,  -2135,
+       209,   -929,   -288,    227,   2656,   -125,    -42,     17,
+        30,   3375,   -367,     53,   -262,   -351,    108,   -270,
+        11,    -57,   -182,    -51,   -149,   -287,   -115,    -24,
+        99,    -76,   6954,    -75,     -4,     38,   -168,    138,
+       109,   -239,    -45,     49,     28,  -1376,     49,     66,
+       -83,   -129,    -61,    -99,    135,     14,    -93,    111,
+        37,    -16,      2,    -76,    360,    -77,     82,    161,
+       149,  -1660,     18,     98,    -34,    -12,    -36,    -65,
+       126,    -57,     28,    519,   2044,    297,     73,   -218,
+        51,     17,     21,    -70,    -32,    -73,    -39,    -38,
+       -11,     60,     38,   -129,   -105,   -173,    200,      7,
+       124,    -74,  -2780,   2608,    -57,   -213,     54,   -200,
+       134,    208,    -34,    236,    143,    101,    327,    558,
+        75,    317,   3090,   -188,    544,   -186,     15,    116,
+       237,     76,   -105,     29,   -300,    -27,   -211,     71,
+      -144,    183,    -77,     38,    -16,     39,     56,  -7308,
+      -113,   -116,    -32,    222,     60,     76,    -21,     59,
+        52,    104,    383,     73,    149,     88,    127,     34,
+     -1819,    -46,     50,     11,   -159,   -223,   -163,   -149,
+        95,   -163,  -2168,    -19,   -937,   -183,     66,   -465,
+      -257,    341,    -70,    111,    228,     52,     83,     63,
+       -52,   -187,     16,  -2539,    -51,   3240,    -81,     87,
+      -116,   -183,   -182,     96,    -22,   -191,   -107,    217,
+       -10,   -215,      9,     -7,    -97,   -331,    -55,    513,
+      -398,   1378,   2627,  -2129,    563,   1462,   -369,    498,
+      1176,   -469,    220,   -953,   -122,   -236,   -306,   -276,
+        31,     35,   -167,    558,   -134,     45,    -54,     16,
+        36,     18,    300,   2438,     62,   -177,     77,   2638,
+      -108,   -115,   3392,    274,   -123,    -66,    201,   -400,
+       170,    142,    151,    332,     53,   -507,     81,   -653,
+       -93,  -3204,     -5,     10,    -43,     79,   3879,     77,
+       191,     24,     23,   -208,      6,   -109,    -97,    126,
+      -306,    629,     26,   -516,     79,     21,    131,     43,
+      -253,  -3463,    840,    653,    -95,    -48,    300,  -1026,
+      -324,   -909,   -383,    195,    342,   -136,   -192,    422,
+       262,    -13,    534,   3125,      8,   1672,    176,   -293,
+       211,  -1213,    537,    637,    -10,   -116,   -149,     44,
+        53,    105,      7,    -97,      3,     17,      8,    -21,
+        -7,    -41,    -38,  -4959,    -81,      1,    165,    196,
+        98,     35,    -35,      8,    -28,    113,    -20,    108,
+      -130,    -65,    172,   2858,     41,  -3295,    138,     10,
+       -95,    -30,   -173,     85,     42,     30,   -119,    161,
+       195,    125,    -32,    136,    319,    -33,   5142,     50,
+       100,    128,    -90,    -53,    -67,   -203,     28,     19,
+        37,   -137,   -124,   -105,    -25,  -3405,   -250,    294,
+       409,    -99,  -1072,   -383,    -12,    212,   -276,   3389,
+      -101,    171,    -41,   -554,   -295,   -437,     86,    158,
+      -242,    167,    135,      7,   -149,     48,     -4,    -84,
+      4911,    283,      5,    -14,    105,   -107,   -384,    102,
+       183,     47,     67,  -5105,     -5,     16,   -155,    181,
+       110,     24,    -77,    -32,    120,      1,     22,    167,
+       -90,   -150,     -5,    163,    -44,    -28,     54,  -3058,
+      -174,     58,    152,    -31,   -179,   -122,    -57,    232,
+      -395,  -4961,     61,   -115,     31,     14,     82,   -109,
+       -39,     59,    -49,   -133,     52,     17,     57,     52,
+       -63,    275,    146,    104,     53,     47,    -55,    311,
+      4871,    -26,     48,    -94,    -11,    -58,     63,    140,
+       -74,    -94,   -269,    -77,   3372,  -3116,     16,    -47,
+       -74,   -161,    115,     58,   -247,   -119,    399,     42,
+      -181,    154,   -218,    -24,   -237,     58,   -275,   2979,
+       187,   -124,    312,    301,   2767,     -8,     40,    -23,
+        -6,    -38,    -52,   -363,   -265,    -78,   -230,    286,
+      -135,   -337,    -81,    170,    -13,    -58,   -117,    519,
+     -4784,    157,   -193,      9,     62,    -21,    180,    128,
+       326,    213,   2440,     62,   -601,    -55,      2,    -18,
+      -342,    142,    358,   -632,   -377,   3590,   -248,   -278,
+      -235,    -28,    242,   -133,    144,     26,   -261,    113,
+        45,    -23,  -1984,    -77,    128,    249,     -8,   -266,
+       -38,     -6,  -1672,    -45,    -84,   -377,    154,     17,
+       -83,    -44,    156,   -137,     43,     91,    253,     17,
+       -71,    -92,    178,     12,     18,     -8,   -105,    101,
+      7068,     71,    -81,     84,    -33,     79,     53,     -7,
+       -85,   -265,    117,    317,    114,     72,   -482,   -418,
+      -185,    -97,    268,  -1543,    -79,   -146,    -48,    -45,
+     -3259,   -212,   1149,   -165,    177,   -158,    -77,    100,
+        86,    -69,    107,    219,   -512,   -253,   -418,    -45,
+        16,   5501,   -184,    207,     67,     46,    109,    -28,
+        -9,     33,     63,    -16,     39,     92,     27,     23,
+       -10,  -8192,      0,     50,    -57,     68,   -444,   1082,
+       247,   -138,    120,    472,   -692,    212,  -1576,     66,
+      3061,    402,   -160,    337,   -685,   -519,    227,   -279,
+        92,  -4135,   -393,    -44,      6,   -129,     59,    239,
+       151,    153,    -39,    116,    134,    -40,    171,    118,
+       207,   2615,     38,   -167,  -1671,     85,   -135,   -182,
+       -88,    246,     53,     29,     -2,     16,    232,    544,
+       -46,   -138,    122,    -52,   1312,      9,     92,     13,
+         4,     66,    -35,   -134,    -56,     85,    -43,    -31,
+        28,  -3187,    100,   -103,     70,     -3,    186,    -43,
+       122,  -3040,    -27,    -46,   -121,      1,     37,      0,
+       -60,      2,   -100,   -152,   -218,    175,   -406,    175,
+      -193,     68,   -208,    -23,   -230,    221,   3397,     45,
+        48,     37,    337,     11,     15,    -69,     -4,    -82,
+        53,     33,    -56,     75,    -98,    -69,    -11,    -19,
+       -12,     81,    -52,   5428,    121,     82,    465,     10,
+      -229,    126,     32,    119,    439,    126,   1996,    -85,
+       -81,    -57,     88,    232,    108,    -22,    -24,     27,
+      -136,     91,    -32,     18,    226,    -33,     15,    117,
+       145,  -7737,      9,     58,   -102,   -113,     26,  -2174,
+        28,   -421,    -11,    -70,    -23,    -70,   -119,    -96,
+      -133,    208,     20,  -3750,    -14,     23,     41,   -180,
+      2097,   -103,   -599,    146,    251,    -77,   -557,    -76,
+       -96,     69,    266,    316,     74,    -17,   -227,    223,
+        33,   -261,    135,   8126,    250,     -5,    -57,     35,
+       382,    -44,    136,     81,     42,    -80,    179,    -73,
+       -75,    -57,    274,    -15,  -3140,   3236,    196,    150,
+       -51,    222,   -190,     13,     83,   -313,   -149,     89,
+      -281,    -12,    -42,    293,    567,     19,    -43,    146,
+       102,    -39,   3666,     95,     76,     -1,     12,     27,
+         7,     -5,    261,    132,   -215,   -295,    -51,    496,
+        77,    100,     16,   -285,    649,    -95,    280,     77,
+       121,  -2676,     25,  -1148,   2912,   -341,    -91,   2380,
+       -80,     -6,    269,    -34,   -686,   -208,     19,    228,
+        24,     -5,   -150,     11,    214,   -316,   1187,    599,
+       -62,  -2274,   -240,     48,    -86,     87,     86,    477,
+      3832,     67,    135,     68,    747,    339,    385,   -255,
+      -224,    184,     70,    171,   -134,   2604,   -231,     72,
+       170,     51,  -2785,   -580,    -86,   -393,    -63,    -79,
+      -151,    334,     78,    329,   -278,    102,    -26,    -55,
+     -3531,   -378,   -247,    176,   -202,    147,    169,     87,
+};
+
+static const int16_t cb0808ss0[] = {
+     -1872,   -332,  -1311,   -512,   -934,    -11,    112,    389,
+      -189,  -1513,   1508,  -1081,    185,    -87,   3092,    529,
+      -166,   -171,  -1648,   2544,   2144,   -259,   -688,  -1113,
+       -71,    387,   1194,   -733,    175,    856,   -976,    268,
+       589,  -1773,   -426,   -109,   1210,   -486,    297,    195,
+      -991,  -1543,   -432,   1190,  -1089,   -531,   -421,     80,
+      -225,    354,   -231,   -670,   -299,  -3694,   -510,   -882,
+        31,   2804,    476,   -478,   1897,    686,  -1066,  -1222,
+      -882,   -374,   -427,  -1464,    957,    549,  -1211,   -204,
+      -218,  -1412,   -545,   -968,    943,   -342,     80,   -281,
+      -249,   -968,   3424,  -2342,   -212,    949,   -167,   -271,
+       607,   -838,   -418,   -891,   -398,   -877,    138,   1653,
+     -1034,  -2515,  -1363,  -1535,   -364,    432,   -324,  -1120,
+      1531,    407,   -698,    396,    325,   1432,    646,   2777,
+       174,   -836,   -605,   2257,   1086,   -888,    348,     36,
+       513,   2229,   1543,   1293,     94,   2444,   -574,  -1030,
+       933,     -9,   -668,    555,    346,    511,    715,  -4033,
+       409,   -299,   -166,    700,   -560,    950,  -1265,   -245,
+      1418,  -1362,    -20,    870,    152,    942,   -331,    -66,
+       227,   -186,    251,  -3632,  -1057,   -989,  -1798,    923,
+       542,   -630,   2889,   -128,   1475,    -97,   -964,   -860,
+       534,   -217,   -746,    181,    321,  -1007,   2595,   -411,
+      1298,    635,    310,   1955,    -17,    846,   -824,    -11,
+      -952,    208,    328,   -547,  -1086,   1481,   -264,  -1574,
+      3579,    500,    242,   1038,  -1030,    353,    -75,  -2100,
+      -347,   2662,  -2378,    261,    210,  -1151,    525,    291,
+       368,   -200,   -702,    105,   -140,    -81,    663,   -716,
+       334,   1220,    239,     21,    114,    301,  -1898,   3647,
+      -302,    550,   -489,   -484,   -853,   -274,   1509,   -419,
+      -330,  -1121,  -2666,   2507,   -621,   -818,   1188,    -69,
+      -885,    231,    316,   1837,   -740,   -187,   -102,   1148,
+      1219,   -123,    852,   1154,     27,    139,   -344,   -404,
+     -1133,    425,    353,    145,   -123,    179,     49,  -5836,
+      -571,     39,    274,    -38,   -457,    172,    -80,    593,
+     -1977,   -331,   -421,   1965,   1768,   -113,     64,   2272,
+       475,   2165,    210,    873,   -819,    757,   -119,   -530,
+     -1431,  -2167,  -1517,   -864,   1060,   -752,  -1366,   2349,
+      -671,   1180,   -179,     10,   -450,    781,   -799,  -1303,
+      -393,    -61,   -113,   2053,   -550,   -843,   1028,  -2044,
+     -2631,  -1388,   1078,    171,    517,    496,   -928,  -1695,
+       298,    708,   -557,    122,   -917,   -197,   -423,   1142,
+       116,   -528,   -585,   -470,    480,    400,   4605,    384,
+      -142,     57,  -2340,  -1507,    -67,    907,   8192,    356,
+       -18,   -704,    528,    -32,   -379,   -611,    418,    703,
+      -396,    531,    155,    642,    678,   -427,     85,    814,
+       212,    845,   -579,   -590,   -456,    103,   -624,  -4541,
+      -306,    638,   -760,     36,   -149,   1929,   1229,   -717,
+      -543,    530,   -694,    169,  -2996,    423,   -346,   -897,
+      1077,    255,  -1054,    -63,  -1773,   -479,    479,   -701,
+      1547,  -1683,   -342,   -926,    112,   -663,   1638,     -9,
+      2587,    311,   -561,   -932,   -539,   -335,    589,    779,
+      2345,   -432,    788,   -967,    319,     -4,    192,   -588,
+      -103,    357,  -3508,   -257,    707,   -473,   1521,     -9,
+       130,   3290,    274,   -296,   -802,   -139,   -814,    -19,
+       971,    849,    253,    486,     40,  -1216,   1179,  -1772,
+      -996,   1400,    838,   1955,  -1432,  -1925,   2324,    767,
+       896,   1314,   3407,  -1003,   -552,   -967,   -166,    -26,
+      1099,  -1965,      9,    239,    -10,   -243,    864,   1251,
+        91,  -2279,   -691,   -542,   -473,  -1908,  -1208,  -1447,
+      -891,   -311,  -1136,   1638,   1150,    586,   1656,    260,
+       538,  -1746,   1460,   -478,   -860,    297,   -605,   -139,
+       822,  -3718,   -194,    307,    609,     30,   3418,    226,
+      -338,    161,   -387,   -344,   -472,    354,   -170,   -421,
+       433,    601,  -1446,    821,    -48,    -31,    493,    916,
+      -347,  -3740,   -899,   1389,   -355,     71,    382,   -644,
+       485,    218,    975,   -542,  -3191,    742,   -102,   -783,
+     -1607,    473,    196,   1692,    -71,    258,   2446,   1507,
+      -968,  -1025,  -1087,    637,   -921,  -1405,   1192,    -88,
+      2044,  -1813,    922,    156,  -1096,   1007,   -695,   -485,
+     -1015,   -468,   -316,   1825,    190,   2132,   -205,   -218,
+     -3556,   -286,  -1350,   -212,   -634,    120,    417,   -311,
+       -90,    219,    870,   -334,  -1304,    523,    999,   -144,
+        98,   2157,    205,     45,   -247,   1401,   2423,    278,
+      -766,    -66,    309,   -121,    316,   -543,  -3418,    932,
+      -803,    637,    436,  -2341,   2016,    928,   -836,  -1212,
+       702,  -1179,   -544,      6,  -1429,   1014,    464,   1166,
+       581,   -291,    136,      0,    983,   -799,    693,   -230,
+      -727,   -186,   -310,    -76,    698,     -6,   -660,    762,
+       814,    451,   -328,   4469,   -454,     14,   -423,   -116,
+      -134,   -568,   1535,   -562,   -629,   -269,    826,    380,
+        68,    282,   -409,    640,   -384,    218,  -5702,   -280,
+      -638,  -2586,   -557,   -877,     49,    648,    434,   1178,
+      3442,    883,    -78,   2024,   -253,   -210,  -1090,    198,
+       -67,    -52,   3226,   -671,  -1606,     49,   1775,   -422,
+      -173,    309,   -720,   -667,   -505,   2073,   -678,  -1152,
+      -231,   -519,   -719,    422,  -2614,   -394,    543,   -993,
+      1449,    437,   -463,  -1286,   1191,  -1274,   -710,   -463,
+       659,   1493,     45,   -832,   -414,    306,     94,   1284,
+      -669,  -1312,   1082,   -917,   2489,   -494,    547,    738,
+     -1696,   -174,    282,  -1442,  -1455,   1633,    912,   -428,
+       964,     12,  -2404,   -485,    631,   -311,   1810,   2912,
+       -16,    576,     50,   -927,   -175,     37,    673,   -201,
+       995,    684,   -244,   -251,  -1444,   3195,   1863,    -88,
+     -1183,   -966,   1769,     36,   -825,    766,    489,    -86,
+      -365,   -106,  -1477,   -330,    125,   -253,   -250,   -523,
+      -731,  -5130,    653,    395,     99,   -845,   -721,    127,
+      -287,    850,    479,     25,    -30,     36,   -782,    611,
+       448,     99,    933,    -20,   -853,   -949,   -286,   -379,
+      -654,   -385,   1298,    547,    235,   1242,   -583,  -4147,
+        81,   -547,  -1142,   1280,   -223,  -1712,  -1501,    458,
+      -142,   2065,    208,    855,  -1115,   -187,    861,   1090,
+      -760,  -2551,   2326,   -378,  -1205,    488,   -241,    893,
+       113,    176,   4060,   -225,    -41,   -717,    -26,   -442,
+      -445,   -312,    813,    494,    314,   -210,    -98,   -788,
+       255,    632,   -506,    166,   -704,   -334,   -214,   -860,
+     -5281,     60,    -34,   -238,   -147,    643,    520,   2038,
+        28,   2433,  -1694,  -1316,   -615,    572,   -150,   -107,
+       349,  -1763,   -307,     78,  -1124,   -631,   1162,   -326,
+      -277,   -591,    558,   1016,  -4668,   -324,   -815,   -251,
+     -1284,     52,    294,  -1283,    598,    630,   -345,    641,
+       -34,   1085,   4247,    637,   1695,   -858,    212,   -243,
+       -64,    327,    557,    426,   -321,    363,   -652,    372,
+       777,   -567,   -749,  -1704,    414,   5299,    389,    242,
+        39,     31,   -315,    179,   -102,     11,     62,    248,
+       557,    706,    359,    -85,    303,   -403,   1531,    409,
+     -2092,    144,  -1354,     54,    -48,     51,  -1787,   1278,
+       942,   1264,  -1495,   1671,     92,   -899,  -1149,   1908,
+      -903,   -596,    342,   1749,   -825,    -13,    509,  -1163,
+      1065,   2405,   -253,   -741,   1099,   -528,   2971,   -412,
+      -235,   -869,   -136,   -352,   -489,   -384,    745,   -398,
+     -4197,     84,   1152,   -497,    955,   -161,    461,    -16,
+      -871,    801,    -93,    -15,   -352,   1826,   -490,   -536,
+     -2853,   -633,    128,  -1537,  -1670,    538,    788,   1276,
+       554,   -340,    565,   1216,  -1758,    384,  -1313,   -628,
+        24,    835,   -862,   -927,   1792,  -1042,    209,   -784,
+       807,   -383,  -1399,   3531,     52,   -537,    205,   -271,
+      3071,   1678,   -694,  -2313,  -1279,  -1656,   -428,  -1063,
+     -1576,   -323,   -342,   -257,   -227,   -716,   -458,   1161,
+      -180,    -71,    -40,  -1276,   1778,  -3123,   -378,  -1363,
+      -827,    880,    275,   -274,   -581,   -186,     -8,    661,
+     -1114,   -199,   -171,    379,    429,  -1551,   1645,   -857,
+      -163,  -2623,   1217,   1458,   -596,    -68,    383,    973,
+      -485,   -354,   -597,  -2875,   -516,    234,    -83,    340,
+      -396,   1365,   -574,   -816,  -2086,  -1059,  -1589,   -593,
+      -779,    334,   -546,     49,  -1065,  -1959,   1736,   1134,
+       187,   1833,     17,    -82,     68,    803,   -456,    -89,
+      1760,    836,   1570,    122,   -985,   2549,   1616,     82,
+      1102,    227,    222,  -1236,   -155,  -1012,    633,    467,
+       163,    445,    166,    766,   -253,   -347,   1041,   5121,
+       -21,    792,     81,   -478,    128,   -158,    316,  -1180,
+      -372,   1692,   -828,    -31,   1122,  -2583,   1346,   2483,
+       195,     72,    549,    424,    947,   -470,   1940,    -75,
+       505,   1377,    550,     58,   1785,    343,   -817,    874,
+      3483,   -307,   -576,    240,     35,    837,   -717,   -247,
+};
+
+static const int16_t cb0808ss1[] = {
+      2328,    183,   1652,   -907,  -3005,   1329,    -61,   -465,
+         0,   -453,  -1621,    223,    232,    -59,    254,   -312,
+      -117,    -59,   -477,  -2648,  -1176,   -227,  -1937,    962,
+       141,  -1489,    849,     93,  -1284,   1000,    295,    192,
+      -139,   -468,   -736,   -436,   2155,    371,   2475,   -348,
+       856,  -1985,     38,     94,    496,    758,    954,   -243,
+       134,  -1759,    491,  -1406,   1114,  -2554,   -447,   -692,
+     -2128,     44,   -923,   1610,    787,    150,   -500,   3442,
+      -698,    276,   -517,  -1555,    379,    -72,    810,  -1373,
+      2897,    936,   -586,   -438,    925,   1881,   -419,    211,
+      1724,    721,    885,    614,    253,    613,  -1440,    509,
+       842,  -2407,   -216,  -1765,    451,   1419,    599,    689,
+      1473,   -175,  -2974,  -1015,   1983,    -68,    640,     21,
+       140,  -1295,   -556,    -89,   -836,    718,   -343,  -1903,
+       443,    502,  -1064,   1328,     86,   2049,   1235,    130,
+       892,   1105,    692,  -2968,   -755,    473,    423,  -1371,
+     -2032,   1885,    -29,   -516,  -1118,    285,    482,    164,
+     -1932,   -685,   -819,    695,    715,  -1520,   1300,  -1188,
+      -121,   -197,  -4233,   -141,   1279,    299,    208,   1071,
+        20,    772,    692,    531,    257,    428,     78,    202,
+      -399,    -27,    793,   1150,   -736,    388,  -1922,    155,
+      -410,     85,   1135,    835,    133,    -88,     65,     62,
+      -534,   -136,  -4590,   -162,   -968,   1378,   -445,  -2825,
+       -93,   -519,    402,     12,  -1110,   -637,   -765,    210,
+     -2305,    654,    447,     26,   -265,    -91,     71,   -886,
+       126,   -109,      7,    346,     19,   -713,   -257,    774,
+      1080,   -579,    185,    200,  -5691,    541,    228,    424,
+        37,    512,    -78,   -201,    848,   -369,   1099,  -1001,
+       214,   -336,    266,   2502,   1583,  -2131,   -654,  -2476,
+       -97,   -787,   -738,   1056,   1385,    124,    944,  -3421,
+      1172,   -547,   -226,   1249,   1552,   1194,   -308,    489,
+     -1152,    751,    -92,   -168,  -3112,  -1451,   2038,     35,
+       371,  -1585,    535,    308,      5,    -53,    523,   -169,
+       591,   -175,  -1028,     91,    743,   -144,    230,   1831,
+      -177,    509,   1291,   1808,  -3322,   -815,   -227,   -475,
+     -1064,   -647,     79,   1223,    174,    -10,   -412,    393,
+      -305,   1224,   1310,     12,   -521,  -1267,   1911,   2245,
+       407,    724,  -1232,  -2017,    566,    506,   -467,    813,
+       660,   -196,  -3643,   2495,    870,   -561,    289,    662,
+       654,   -508,   -734,   -325,    622,    220,   -309,   -307,
+      -181,   -445,    131,  -1655,   -835,   -631,    883,    211,
+       737,    552,   -881,  -3103,   -766,    595,    112,    151,
+     -1177,    601,    479,    -14,     37,   -926,   -505,   1062,
+     -1755,   -799,   -178,   -555,   2509,   -694,   -792,    662,
+       737,    847,   1611,    397,    -67,   -134,    474,  -2251,
+      2698,   -245,   2054,   1603,   1291,   1188,     40,    763,
+      -216,   1554,   -297,  -1769,    410,   1270,   1089,    440,
+      -967,    294,    -37,    270,    471,   1287,   3773,   -108,
+      -610,   -275,   -298,    270,   -384,   2072,   -675,   1002,
+       174,     18,    171,    704,   3311,   -105,  -1774,    108,
+       511,  -3001,    -69,    543,   -227,  -1196,   1431,    -63,
+         6,   1279,     -1,    671,    239,  -2127,  -1924,   -934,
+       168,   -300,   1075,   1071,   3088,   -590,   1439,    329,
+      1073,    127,    762,   -131,    274,    837,   -134,   -610,
+      -399,  -1415,   1047,   -156,    415,    765,    698,    428,
+      -748,    241,  -4226,    152,   -829,   1040,   -937,    145,
+      -852,    -85,  -2957,   -130,   -406,    726,    168,    -37,
+     -1321,  -1069,  -1255,   1159,   1575,    552,    649,  -1953,
+       -17,   1027,   1078,   -385,  -2761,   -553,   -201,     58,
+     -1900,    -24,    283,   1248,    -90,    419,   1122,    902,
+     -1548,    -32,     34,   -360,    707,     45,  -3458,   -246,
+       287,    308,    397,    393,    822,   1323,   -565,    505,
+     -1553,  -1902,   -677,    625,   1079,   -135,  -2132,   -187,
+      -163,  -1001,  -1479,   -932,   1131,  -2588,   -316,     53,
+      1270,   -747,   -966,    980,    242,   -266,  -1575,  -1146,
+      -605,   -523,   -221,    585,   -787,   1365,   -286,   -183,
+       411,    546,   4779,   -286,   -578,   -101,    309,    896,
+        34,    451,  -1022,   -699,    170,    935,    458,   4143,
+       229,   -572,   -912,   -397,    -40,   -132,   -198,     98,
+     -1858,    612,    101,    -98,    -18,   -349,    322,  -1626,
+      1304,    273,   -235,    418,   -509,   3961,   -493,   1040,
+      -416,   1808,    161,   1443,   1052,   -460,     55,    -67,
+        41,    514,   1305,   -836,  -1636,   1353,    379,    147,
+       398,  -3814,   -679,    235,    327,  -2293,   -716,   1234,
+      -728,   -323,    698,   1992,      4,   -275,    944,    895,
+       212,    334,    285,   -710,   -891,  -1325,   3107,      3,
+       367,  -1779,    300,   -868,    -59,   -644,   -326,    111,
+       267,    -43,    421,    976,     57,   1461,   -172,    245,
+      -188,    296,   -215,   5269,    -46,    177,    199,   -539,
+        92,   -542,    251,    951,   -231,    117,   -580,   -898,
+       402,    847,      4,    384,   -215,    161,  -1991,   4422,
+      2461,  -1219,   -751,   1843,   1483,   1072,   2621,    -16,
+     -1157,    243,   -557,    651,    953,    476,   -417,   -533,
+       505,   -590,    713,    153,   1268,   -312,   -217,   -124,
+       870,   -484,   -751,   -161,    897,    755,   -823,   4117,
+     -1311,   -729,    447,   -642,    929,  -2408,   -338,   -967,
+      -104,  -1048,  -2216,  -1722,   -124,   -204,   -196,  -1156,
+      1460,    391,   -543,    120,     70,    204,   1185,  -2490,
+      2950,   -507,   -615,   1243,   -150,   -363,   -475,   -531,
+       783,    671,   -205,   -591,    217,   -523,    263,    -14,
+        71,    958,  -1185,  -1029,   -330,    327,   -705,   1229,
+     -2925,    131,   -495,   1756,   2101,    441,    -11,    133,
+      1274,   1253,   -154,    772,    522,   1725,   -277,  -1012,
+      -726,   1339,  -1200,   -241,   1676,    974,   2256,    347,
+      2743,   1482,   -738,   -241,   -868,  -1294,   -664,    855,
+     -1329,  -4174,  -1647,   -104,    101,    307,   -647,   -823,
+       347,      4,   -120,  -1112,    334,     27,    265,    990,
+       319,  -1414,    313,   -603,     52,  -3138,   1552,   -612,
+      -854,    626,    212,    773,   2334,    662,    614,    560,
+       589,   -533,   1337,    229,    557,    -26,   1458,   -626,
+      1890,   2392,  -1525,   1023,    667,   -431,     72,   1691,
+      1015,    -97,   -515,   1380,    796,   1192,    -39,    162,
+     -2821,   2960,   1558,  -1058,   1327,    793,   1231,   -743,
+     -1190,   -245,     29,    486,   -494,  -1371,   1633,    -66,
+     -1806,    231,   -664,   -147,   2402,   -584,    473,   -527,
+      1272,    464,   1991,  -1007,   -235,    357,    201,  -1176,
+      -341,    223,    -47,  -2089,    815,     49,    192,   -719,
+     -1041,   -248,   3046,    -40,   -501,   -346,  -1347,   -401,
+        57,  -1588,  -1039,    443,    590,  -1089,   -182,  -1365,
+     -1013,  -3917,   -382,    -98,   1025,    -51,    698,   -197,
+       848,    -75,   1596,   -408,  -1796,  -3191,   1155,    234,
+      -100,    698,    571,  -1233,   -315,  -1502,   -647,   -571,
+      -322,    842,  -1048,  -1115,   8192,   -784,   -472,     17,
+      -718,     37,   1190,   -393,    146,   -547,     90,   -433,
+      -321,  -1143,   -501,    468,    235,   -486,    -64,  -2214,
+      -330,   -837,   1214,   -127,    709,     -3,    623,   -384,
+       221,    297,   -783,  -3802,   -408,    -11,   -707,     92,
+      -275,   -268,   -117,   1580,   1466,    710,  -1300,    142,
+      -746,   1647,   2399,  -1231,    114,   1220,  -1112,    882,
+       467,   -973,   -976,   3855,   -647,   -150,  -1244,    973,
+      -364,   -154,    473,   -675,   -817,   -346,   -266,   -769,
+      -613,   -476,   1181,     -8,  -1054,    405,   -768,   1385,
+     -1598,   -892,    672,  -2185,     83,    -27,    582,   -434,
+      -944,     99,   -888,  -1658,  -1516,   2392,    726,   -222,
+       284,    324,   4848,    -67,   -782,    -45,    424,   -203,
+      -194,  -1229,   -114,   -189,   -216,    275,   -935,    -93,
+       117,  -1725,    360,  -2561,  -1555,  -1199,   -769,   -285,
+        74,   1267,   -387,   1368,    179,   -113,    952,   1025,
+       725,   -542,   -186,   1258,  -1396,   -747,    572,    603,
+      1965,   -668,    -12,  -2512,   1337,   -255,    254,   2285,
+      1136,   1397,    557,   -671,  -1149,   -614,   -462,   -913,
+      -452,   1206,  -2922,    485,   -882,    270,  -1309,   -605,
+       -21,   -580,  -1284,   -194,    169,  -2314,   -216,   -229,
+      1124,    103,  -1205,   1500,   1118,   1456,  -1149,    780,
+      -467,   -385,    585,  -1062,    289,  -3356,    198,   -309,
+      -310,     91,     44,   -377,   -632,   -737,   -516,     30,
+      -779,     73,   -482,   4661,   -275,     38,   -632,    479,
+      -345,   -406,     76,   -208,   -230,     80,   -220,   -313,
+       203,     -3,   1740,   -131,    773,    -30,    372,    767,
+      1673,   -770,   3326,   1586,    234,    408,   -257,    474,
+      -584,   -990,   1378,    696,     47,   -612,   -313,    189,
+     -3964,    795,   -289,    202,   -437,  -1648,    373,   -780,
+       -24,   -952,    123,    438,    797,    539,   -481,    191,
+       291,     37,   -790,   -321,   4520,    -49,   -281,    211,
+};
+
+static const int16_t cb0808sm0[] = {
+     -4664,   -115,     59,   -280,   -199,    -25,    213,   -937,
+       344,  -2137,   -841,   -370,    256,    512,   1098,   -130,
+        58,   -121,   -414,   8192,    489,   -296,    -33,     98,
+        49,   -217,    721,    -42,   -418,   -227,     -8,    205,
+      -276,    407,  -1218,   -146,   -292,   -143,    113,    978,
+      2693,     -9,  -1032,   1781,   1777,   -215,   -978,   -824,
+        68,   -162,     55,   2991,   -844,    682,    497,    406,
+      -922,   2471,    599,    774,   -129,   1292,  -1004,    777,
+        42,    314,   -102,   -963,  -2794,  -2620,    510,    355,
+       372,   -248,   -391,   -163,   -298,    561,    117,   1183,
+        38,    182,   1811,     -4,    328,    -13,   -456,    305,
+       368,  -1691,  -2818,  -1074,   1029,    261,  -1446,    343,
+        12,  -2757,   1021,   -375,     -3,   -155,    116,    195,
+      3420,     64,    139,    780,    187,   -464,    261,   -313,
+      -128,    185,   3703,   3160,    960,    706,     41,    405,
+        10,   1191,    353,   -549,    131,    164,    105,      1,
+        23,    386,     73,   -509,   2651,  -1441,   -834,  -1657,
+      -645,   1005,   -777,    695,    212,   1420,     65,    701,
+        25,    335,    136,    359,   -112,   -150,    191,    392,
+      -258,  -1140,    651,  -4551,    411,    251,   -169,    804,
+       -83,   -208,   -363,     81,    152,     75,  -1194,   -203,
+        -9,    157,    413,    -62,   -210,   5393,    -22,   -407,
+       132,   -288,   2360,    131,  -1535,    553,  -2524,   -140,
+       250,   1259,    -30,     -1,   1766,     99,   -529,     91,
+      3948,   -262,  -3752,   -382,   -339,   -701,   -140,   -787,
+        67,    -11,    331,   -828,   -443,    596,     47,   1634,
+        31,   -318,     39,    147,   -670,   -776,    707,   -921,
+       172,    971,   1163,     48,    -81,  -1357,   -181,   2872,
+      -152,    898,   1075,    529,     91,  -2279,   2925,   -848,
+       589,   1910,    549,   1088,    743,   -631,     42,  -1528,
+        23,    380,     -5,    389,  -1147,   -209,  -2041,    224,
+     -1998,    520,   -776,    193,  -2648,    -78,    -34,   -131,
+        22,   -200,    -28,     18,    328,    215,     67,     61,
+        50,    -72,    301,   -207,    413,    720,  -6194,    967,
+     -3275,    149,  -2444,   -521,   -772,   -278,    137,   -159,
+       932,   -111,   1219,    525,     17,   -684,  -1229,  -1776,
+        66,  -2307,   -195,   -527,    272,   -470,   -356,     -7,
+      -338,    146,   1021,   -893,  -2980,    591,    129,   -257,
+       209,    -58,    538,  -3973,    576,   -905,   -642,  -2092,
+       153,    737,   -596,    573,    236,   -887,  -1692,   -370,
+      -189,   -216,    -58,    714,     10,   -582,    517,    -86,
+       450,   -147,   -310,    162,   1747,   -656,   3577,    700,
+       190,   -685,   -170,    241,     91,   -126,   5567,    441,
+       -50,   -688,    -73,    938,    320,   -130,   -839,   1154,
+       149,   -446,    -10,    -11,     12,   -659,   -138,    637,
+      -470,    933,   -431,    235,    -86,     -2,   -407,  -5851,
+      -250,   1414,    525,    110,    421,    255,   -149,     86,
+       378,   -321,   1380,    118,  -2849,  -1138,    180,   1175,
+      1932,     32,   -488,   -121,   -412,   -441,    397,    249,
+      -172,    -95,    420,    375,   -132,   -215,   -167,   -206,
+      8192,   -116,    -61,   -311,    269,    615,   -353,   -115,
+      -383,    366,   -651,   -196,    -98,     85,    861,    543,
+      -231,    237,    493,    380,   -766,   -168,   3227,    659,
+       701,    181,  -3004,     -7,    154,    298,    298,   -257,
+       -32,  -5713,     48,    102,   -776,   -148,   -110,    316,
+      -645,    212,    213,    575,    -69,     31,    553,   -673,
+        -5,    -48,   -148,   -133,     11,    143,     10,    159,
+       319,     43,   7462,    162,    228,    -90,     75,    151,
+       103,  -2542,    -13,   -338,     11,   -442,    123,  -3039,
+      -452,      7,    106,    502,    227,  -2034,     90,    500,
+       -28,   -646,   -262,    -62,    -78,     40,    419,   6761,
+       -11,     40,    209,     61,   -151,    -68,   -245,   -401,
+        26,   -123,    189,    -57,    611,      6,  -1285,    -99,
+      -890,   3609,   -302,   -808,    639,  -3245,   -226,    107,
+        54,   -108,   -316,    -61,    -56,    228,    -16,    195,
+       275,    214,    -60,     77,  -7157,    130,      8,    244,
+     -2160,   -760,    450,   -186,   -378,     32,   -797,    214,
+     -3569,   -450,    307,    -17,   -141,     16,   1024,    404,
+     -2063,   -288,   -160,   4056,    877,   -346,   -970,    -87,
+       336,    961,    666,    585,   -465,  -1329,    350,   -338,
+     -5421,   -173,   -295,     72,   -201,    533,    462,   -133,
+      -937,   1891,    264,     71,   -935,    640,    687,    852,
+      -386,    -85,  -5644,    306,    240,    640,     67,     94,
+      -902,   -351,   -417,     -3,    284,     38,   -156,    359,
+        53,    139,    185,    274,   2613,    213,   1282,   2867,
+        30,   1234,   -911,    343,    -93,  -1671,     57,   -814,
+       -19,    326,   -256,   -113,     72,   3177,   3393,   -125,
+       460,   -261,   -503,  -1019,   -681,   -253,   -957,   -157,
+      -117,   -231,   -212,   1446,    225,  -3009,    313,   -435,
+       387,   -928,    696,   -857,   -452,     66,  -2063,    782,
+        14,    -94,     51,    242,   -422,    236,  -3825,   -666,
+       348,    196,  -2770,    429,   -416,   -266,  -1215,   -586,
+        84,    328,   -302,    219,   -457,   -532,   -764,     85,
+      2008,   -806,   2906,  -1405,    367,    835,    715,   -986,
+      -217,     88,   -328,    569,   -586,   3096,    249,   -615,
+       453,    176,   -540,    792,  -2472,   2189,    876,   -353,
+       111,    212,     -7,    597,   -154,    818,   -401,  -1408,
+       748,   2502,   1426,  -2897,   1069,    326,   -605,    120,
+     -4149,  -3087,    729,     82,    224,    320,    353,    -77,
+      -163,   -322,    220,  -1073,     10,    545,   -518,   -453,
+        50,   -386,  -2002,    614,   -705,   -806,   -928,   2941,
+      -520,    -35,   1208,    413,    900,    138,   -414,   -289,
+       -15,    -75,    185,   -373,    649,   -251,    666,   2708,
+     -2817,   -749,   -159,   -112,    454,   -385,   1037,    -46,
+       -25,    -14,     66,    552,    160,    -40,   -552,   -156,
+       151,  -5287,    541,   -242,    -82,  -1164,    849,   -773,
+      -136,   -162,    -76,     23,   -371,   -222,  -2245,    468,
+       425,   -356,    418,     -3,   -322,  -3573,    148,    260,
+      -155,   3301,   -165,  -3186,   -709,   -458,    870,    386,
+        59,   -161,    533,   -150,    598,    384,    900,  -1233,
+       -74,   -464,   -519,   -661,    -55,  -2562,    290,   1489,
+      1739,   2277,    874,  -1483,   -447,     93,    309,    311,
+      -203,    -19,   2271,  -1280,   -125,   -443,   -538,   2650,
+       -42,    290,    245,   -149,     24,     38,   -133,   1638,
+       210,   -239,   -180,    516,    -12,   -719,    -19,   -517,
+     -6190,   -181,    -89,    318,    485,    631,     11,   -205,
+       -57,    257,    573,    -72,    273,   -579,    107,     -5,
+       112,    425,   2449,   2741,    758,    656,   -663,   -282,
+       -48,    -45,   -294,   -448,  -5562,     61,     -1,   -464,
+      -263,   -688,   -115,    -15,   -108,   -569,   -448,    -48,
+      -180,   -105,     14,   -180,    490,    274,    625,   -588,
+      -120,   -196,   -305,   -126,    435,  -2490,  -2693,  -3414,
+        31,     97,   -167,   -114,    247,   7695,   -189,   -580,
+       219,    241,    188,    327,    179,   -193,    135,   -176,
+       127,    479,    529,    234,    112,    234,   -358,   -286,
+      1109,   2940,   -610,    -13,  -2650,    495,   1355,   -574,
+       -43,  -1497,   -292,   -503,    564,   -363,     24,   -313,
+      1387,    221,  -3612,    783,    637,     43,   1351,    217,
+       -21,    149,  -3104,    190,   -259,   -201,   -342,   -201,
+       166,   2411,  -1082,    283,   -382,   -725,    157,    155,
+     -1609,   -592,    527,  -2959,      9,    216,    526,     79,
+        54,   -132,    202,    785,    929,   1755,   -663,    366,
+     -3735,   3282,    305,    572,    -36,   -111,   -231,    119,
+       603,   1357,   -153,    553,    363,   -760,  -1188,    890,
+       147,  -3844,  -3788,    150,    257,   -588,   -234,    497,
+       361,   -543,    255,   -175,   -377,     49,   -616,   -200,
+      4115,   -541,    130,    678,  -3458,   -506,   -218,  -1317,
+       889,     29,   -104,     -2,    532,   -393,    513,   -792,
+};
+
+static const int16_t cb0808sm1[] = {
+      4123,    -74,    639,    326,   -110,   1896,    826,   -855,
+      -299,   -452,    536,   -323,    262,     79,    486,    144,
+       270,    -64,    277,    154,    399,     50,  -7270,    -61,
+        14,     -8,     19,   -104,    333,    119,    374,    389,
+      -196,     77,   -322,    261,     75,    386,    162,   2360,
+       644,  -2785,    355,    277,   -121,   -148,    156,   2136,
+       112,   -453,    429,    171,   2405,  -1245,   -775,   -181,
+      2110,   -583,    127,    889,   -290,   -550,   -165,   1027,
+      2155,   -351,   -936,    432,   2689,    217,    -20,    646,
+      -785,    908,    654,    970,   -294,    -41,    466,   -245,
+       138,     50,   -108,   -366,    177,    481,  -2118,    968,
+      -594,   3892,    528,    188,   -613,     18,    283,    733,
+       -35,   1598,    387,      1,    156,   -206,   -437,    203,
+      -244,   -347,    325,    296,    100,   1171,     49,    920,
+      -418,    -54,  -2756,     24,    123,   1018,    303,   -501,
+       901,   -447,    322,  -2361,   1039,  -1067,    877,   1329,
+      -143,  -2773,    269,   1560,    398,  -3193,    102,    990,
+       279,    379,   -204,   -144,   -174,    139,    411,   -234,
+        21,  -5064,   -188,    365,    278,    353,   -189,     94,
+       593,   -402,   -353,   -257,   -788,    383,  -1036,    569,
+       -72,  -1764,    571,   1003,    629,    670,  -1400,      0,
+      -435,     64,    189,   2874,    239,   1128,    992,   1213,
+        69,   -128,    207,    713,  -2436,   -931,   -387,   -111,
+      1064,   -170,  -2853,  -1072,   -367,  -1048,   -238,    -60,
+       -49,    340,   2382,    370,   -245,    351,    248,    -64,
+      2331,    458,   -484,    -34,    281,    689,    483,    636,
+       199,   3153,    607,   -124,  -3296,    953,   -407,     49,
+       455,   1083,    690,   -169,   -725,    311,   -493,  -1761,
+     -3054,    376,   -544,    479,     91,    159,  -2837,  -1257,
+      -830,   -948,   -254,    289,  -1039,    856,     86,   1123,
+       203,   -768,   1089,     73,   -866,    308,    437,    674,
+     -2067,   -240,  -1079,     33,  -1069,  -3502,    756,   -676,
+        45,  -2544,    378,   -365,   -275,   -293,   -394,   -649,
+      -507,  -2850,    672,    370,    186,   -417,    682,    185,
+       -15,   2863,     21,   -165,    356,  -3776,   -103,    535,
+      -416,   -345,    -31,     24,    -90,   -205,     96,   -966,
+        94,    424,     -5,   -188,    149,  -2193,   -183,   2342,
+       425,   -647,  -1697,   -627,   -444,   1248,   -967,   -702,
+       -48,   3616,  -3484,    774,   -299,     94,    421,    472,
+        71,   -144,   -523,    114,   -172,    349,   -285,   -106,
+       101,     59,    429,    512,   3362,    -38,    -62,     50,
+      -225,  -1408,    780,  -2747,   -404,    489,   -975,    840,
+       357,    982,    488,   -275,   -109,    393,    375,   4794,
+       183,   -110,    922,   -760,     61,  -1067,     -8,    322,
+        74,   -101,    554,   -350,   -486,     66,    384,    748,
+        14,    223,    -45,   -386,     69,   6231,    247,    325,
+      -320,    -47,    -50,   -165,    153,   -380,    589,  -3243,
+      -173,   -140,    341,   -747,  -1559,    639,  -1658,    356,
+       110,   -150,   -273,     76,   -632,   -425,   -227,    640,
+       211,    192,   -747,   -165,   4608,    290,   -160,   1268,
+      2754,     -3,    578,    189,   -485,  -2747,   -123,  -1309,
+       662,    601,     43,   -136,     84,   1625,  -1113,   1400,
+        75,   -126,   3581,   -243,   2339,   -514,   2203,   -400,
+      -483,    521,     30,   -246,    -76,    359,    101,    663,
+       -40,     57,     52,    360,   -447,   -290,    254,    104,
+       102,    113,    215,   -163,   -388,    299,   4570,     31,
+       108,    -41,     41,  -2633,   2891,   1188,   -505,   1061,
+      -349,   -604,   -449,   -374,   -320,    969,   -304,   -192,
+       246,   -152,    441,    -46,  -1416,    137,   1987,    495,
+       -63,   1087,    875,    699,    201,    211,  -3157,   -273,
+       -60,    195,  -2813,   -239,   2486,    -55,    294,    315,
+      -133,    448,  -1849,    363,   1063,     76,   -928,   -574,
+       -72,    -57,    168,   5673,   -156,   -116,    400,   -124,
+        82,    218,   -487,     37,    112,     53,   -544,    178,
+        99,    480,  -7179,   -196,    271,   -160,    308,    -62,
+       393,    394,   -220,   -740,    -14,     92,    408,   -364,
+       299,   -305,     76,   -239,     26,   -312,   -234,     34,
+      -189,    871,   -297,    364,    282,   -321,   -927,   4511,
+         2,      6,    308,    -82,     87,   -128,    518,     82,
+     -4509,   1145,    960,   -109,   -186,     83,   -144,    752,
+        84,  -2876,   -162,    877,   -249,    317,    510,    338,
+       298,    744,   2892,   -791,    363,   1088,    630,  -2506,
+        -1,   3150,    219,    130,    119,    313,   -822,   -668,
+      1201,  -2948,   -237,   -106,   -711,    405,    276,   -255,
+         0,    440,    161,   2587,   -734,   3376,    276,    154,
+       287,   -200,    594,    -29,    198,   -237,   -608,   -445,
+      -286,    202,   -783,    112,  -3879,     78,   2809,   -337,
+      -606,   -684,   -434,    559,    273,    201,    331,    903,
+       -53,    346,    700,   2599,    302,   -590,  -2551,   -498,
+       -26,   -667,    576,   -546,    457,   -289,  -1408,  -1021,
+       -63,     78,    153,    -83,   -696,  -3105,   2498,  -1502,
+     -1249,   -238,    254,   -287,    215,    313,    279,   -517,
+        67,    -58,   -148,  -1111,     58,   5151,    346,    283,
+      -367,   -900,    542,    209,   -438,   -128,   -135,     54,
+         7,    869,    291,  -1073,    775,    -61,   -145,    457,
+       562,   1332,  -4589,     99,   1366,    184,    980,   -920,
+        80,   -266,   -152,  -1877,   -266,    364,  -1432,    272,
+      2275,    567,     60,     50,  -2504,   -386,   -700,    373,
+      6775,    -15,   -434,    347,    215,   -369,    -20,   -281,
+      -243,   -325,    227,   -283,   -665,    -74,    336,   -674,
+      -112,   -369,    -53,   -396,    328,   3588,   -541,   -557,
+      -164,   1305,   -817,   -462,   1986,   1249,   -574,    130,
+       152,  -2375,   -425,    442,  -3827,    322,   -728,    563,
+      -179,    534,    620,   -937,    590,     -1,    -59,    584,
+       175,   -193,   -168,     -5,   -150,    156,   -175,   -178,
+      -245,  -7481,   -273,    212,    -35,    318,   -178,    446,
+       -55,    -26,     42,    -46,   -265,    767,    330,    295,
+       910,    -54,    490,   2952,    598,  -2578,   -644,    403,
+       149,    -88,    549,   -510,    596,   -225,  -2341,   -286,
+     -2724,      5,  -1960,   -262,    922,    537,    646,    -62,
+       -18,   8192,    484,    112,   -222,   -211,   -224,    317,
+       112,     82,   -853,      1,    176,   -475,   -162,    200,
+      -193,    166,   -228,   -214,     72,    417,    -27,    -16,
+         4,    395,   -515,  -6832,     28,    -47,    626,   -173,
+        63,     90,    141,    217,   1037,    335,   4520,   -896,
+       111,     91,   -656,   -103,   -729,    -29,    653,   -599,
+       -11,   2734,   -378,   -291,     60,    228,     47,  -3670,
+      -192,    653,    733,   -597,    898,   -420,   1572,   -133,
+      -154,    329,   -259,   -225,    218,    -82,    117,    300,
+      -479,    277,    787,  -1719,    136,  -3603,    702,   1357,
+      3340,    362,   -438,    131,  -1463,    367,   -467,   1722,
+     -2186,    343,   -379,   1221,   -562,   -260,   1157,   2692,
+        37,    -89,   -322,   -322,   8192,   -284,    235,   -528,
+       113,   -359,     44,     74,    119,   -917,    403,    410,
+      -150,    157,    514,    168,    407,   -246,    -31,    510,
+       105,    449,   4612,    635,    -90,  -1260,    774,   -284,
+       -80,    456,      7,  -3000,   -324,   -212,   -104,   -374,
+      -440,   1268,   2736,     53,  -1178,   -403,   -438,   -534,
+       121,    261,   -497,    -73,     10,   -262,     17,  -1870,
+       178,  -1339,    224,   3115,   -436,   -448,    385,    894,
+        -1,    105,    -18,    268,    342,    270,    891,    367,
+       121,   -325,  -1610,    -75,  -3233,   -189,  -1050,    961,
+     -2833,   -304,    -51,    400,   -284,   -810,    824,    -71,
+      -135,    194,    297,   -297,   1129,    660,    518,   2426,
+      -225,    251,   4677,   -176,   -464,    296,  -1208,   -423,
+      -875,   -581,   -707,  -1150,    499,   -778,     28,     29,
+       101,  -4213,   -127,  -3681,    425,    481,   -529,   -679,
+        11,    266,    127,   -445,    527,   -577,    310,   1465,
+};
+
+static const int16_t cb1110l0[] = {
+     -3748,  -3820,   -105,     16,    -22,     -7,    112,    -14,
+        52,     28,    -42,   -113,    132,    -81,     -8,   -112,
+        19,     33,   -251,    117,    -33,     -9,    -13,    -28,
+        60,    -30,     29,     27,    -58,     -7,      4,     43,
+    -10108,    -38,     -3,     48,      3,    -23,    202,   -175,
+      -202,     71,  -2143,      3,    -82,    -38,   -113,    141,
+        38,    -66,   -118,    -38,    -14,    148,   -264,    143,
+       -13,    -56,     -9,    -21,    -28,   8930,    -23,     53,
+       -40,     30,     72,    -46,     26,     66,     22,     32,
+        44,     22,    -50,    -66,   -115,   -141,     24,  -3013,
+     -3460,    492,    207,    -62,   -567,    134,    -26,    -64,
+       287,    343,   -213,     42,   -274,   -144,   -144,    -77,
+       -26,    -39,      4,     -4,     42,     43,     30,    -16,
+        34,    113,   9291,   -171,    -17,     24,    -53,    -27,
+        45,     42,    533,    146,    -65,     32,    156,   -144,
+      2821,    889,     -7,    614,     11,      1,   -473,    434,
+       659,   -323,  -2448,     23,   -138,   -582,    436,   -152,
+       -30,     29,   -290,   -302,   3127,    496,     14,   -346,
+       -70,    457,  -1976,   -229,     53,  -2077,   -313,     58,
+        33,    -91,   -175,    141,   2728,   3232,  -2150,    245,
+      -142,     13,   -318,     70,   -152,    -64,    132,   -322,
+        44,     30,    -70,   -184,    433,    -25,    -97,  -2035,
+       145,     47,    640,    179,   -441,     48,   -108,   1742,
+      -280,     33,  -3259,     79,   -147,    324,    -80,     65,
+        48,     90,     -7,    -21,     22,      3,     56,    -30,
+        14,     -2,   -111,     22,     -8,  -8252,   -103,    -36,
+        57,   -203,    287,  -2761,   -220,    143,     11,  -3597,
+        21,    -81,     62,    -99,     41,   -172,    108,     29,
+       351,   -370,     15,   -122,   -207,    275,    -93,  -2760,
+       400,   -212,    225,    230,   -239,  -3530,    -73,    211,
+       288,     85,     -6,   -634,     57,    -78,    361,   -149,
+     -1843,    -23,     17,    -37,    -71,   -174,   -237,     42,
+       -22,   -243,     63,   -101,    131,     35,    136,  -4025,
+        41,   -262,    -57,    197,   -290,    307,     35,    -16,
+         3,     -5,     45,     -7,      1,    -47,     41,    -19,
+        79,     78,     42,    -85,     74,   -414,   1696,    703,
+       297,  -3296,    108,   -546,   1129,     44,    447,   -433,
+       315,  -1012,    133,    141,   1051,    601,    -18,   -532,
+       -30,    712,   -127,   -210,     10,   2442,    -95,    -46,
+       -14,     77,     32,    -11,     10,   -103,    -15,    637,
+       -60,    352,    694,   -202,    284,  -5524,     92,    -82,
+         5,    140,    -54,   -115,     45,    287,    -14,   -307,
+      -342,     10,   -181,     50,    -30,     -6,  10144,     77,
+        42,     13,     26,    -20,     34,     10,     37,    -37,
+       -47,     90,     -5,    -44,    -85,    -64,    -51,     -1,
+        16,   -152,    -91,    212,      4,    -25,   -237,  -6124,
+        22,   -120,     -1,    171,    -17,    -43,    141,    -13,
+       -57,   -185,     80,    273,   -493,    178,     45,     11,
+       -57,     16,    -23,    -30,    -37,     82,      4,    -13,
+      -130,     98,    272,   -450,   -161,    133,   5104,     14,
+      4576,   -193,     11,     55,    -30,      1,    123,   -265,
+       -84,   -340,    -18,    152,    -24,   -266,     33,    -90,
+      -108,   -639,   1662,    299,    -14,   -389,   4679,   -226,
+        21,    311,   -294,    159,   -209,    172,    184,    292,
+      -373,    169,     84,     55,   -269,   1453,    -50,     41,
+        68,     -9,    -62,     35,     23,   -132,     96,     58,
+      -122,  -3956,   -318,    210,   -117,    678,   -104,    378,
+      -842,     61,   2549,     37,    149,   -512,     70,  -2971,
+       225,   -411,    230,   -214,    697,    -58,   -871,   -281,
+      -128,   -204,    -37,   -128,     51,   -174,   -405,    497,
+     -4455,   -219,    124,   -120,     63,    135,    201,   -122,
+      -435,   -677,    221,    138,    486,    535,   3153,    165,
+        11,   -275,     94,   -100,     69,     52,    -67,   -742,
+       212,     16,    -93,   -428,    863,    -17,  -2465,    767,
+       -35,   -130,     97,   1387,     34,     72,    -23,    -17,
+      2845,    -90,    -71,    213,    291,     87,    826,    -63,
+       189,    641,   -256,    832,   2087,   -199,   -170,   -193,
+       -62,     -7,     37,    -60,  -4277,    -43,     24,    -69,
+       574,   -163,   -113,    263,    -86,     45,    171,   1075,
+      -154,    -39,    121,     74,   -132,    182,     34,     13,
+      -278,    -41,     96,    716,   -221,   -626,   1205,    244,
+      -351,   3914,    -78,    -32,   2833,   -150,    -37,     95,
+      -227,    -84,  -3432,     57,    238,   -143,   -365,     39,
+        27,   -238,   -307,   -170,    124,     66,   -133,     40,
+        62,    -19,     42,    -66,      2,    -80,     -2,     60,
+         7,     10,    263,  -4987,    -69,   -389,     62,    -53,
+       -66,     24,    -87,     13,     34,    -15,    -25,    -20,
+       197,      9,    101,    -83,    -79,   -156,   -100,      2,
+      -108,   5687,   -157,    878,  -1728,     32,     72,    -66,
+        70,     -2,    -46,   -163,    206,     17,    247,   2974,
+       -66,   1354,    335,    238,   -249,   -410,   -553,    354,
+       -41,    132,    -96,     68,   2174,   -329,    -58,    -76,
+         6,   3089,    284,   -274,   -398,    471,    283,    427,
+      -220,     81,   2676,     40,    -23,    -46,    251,    109,
+     -3059,     50,    -25,   -551,    124,   -389,    228,     95,
+        56,  -1320,    -79,   1027,  -4938,   -105,    -82,     13,
+      -159,     52,   -101,     23,   -220,    -77,   -153,    113,
+      -282,     42,    185,   -144,   -402,     46,   -144,    -99,
+     -2862,  -3432,     -2,     16,    -32,     23,    -25,   -145,
+       181,     49,      6,   -236,   -226,    -28,    234,    -26,
+       -89,    -14,   -355,    146,    117,    -50,     76,    -10,
+       441,    -95,     -2,    346,   -242,  -3745,    884,   -305,
+      -184,    350,     18,   -293,   -328,    257,    109,     49,
+       157,    -44,    -70,     35,      6,     89,  -4085,   -167,
+      -263,    -59,     35,    -13,    430,   -212,     17,   -618,
+        -5,  -8968,    114,     41,     73,    -85,    122,      5,
+        38,     19,    -60,     14,    -36,    -42,    -89,     20,
+        85,    -17,     20,    282,  -3396,    -25,   3722,    151,
+      -183,    100,   -150,     19,   -221,    126,     34,    -21,
+        72,     28,    138,    -90,     30,    162,     46,     40,
+        27,     15,    -55,    -21,     38,     55,     32,     83,
+      9675,     31,     26,     -2,      4,     96,    -51,    120,
+      -132,    213,   2106,     39,   -251,     98,  -2572,   -429,
+      -331,   1436,   2078,    335,   -381,    371,    299,    339,
+       300,   -141,    -99,   -303,   2952,     49,     93,     40,
+     -3949,    -45,     50,   -215,     73,    -39,   -165,   -283,
+        46,   -123,   -347,     23,   -158,     41,     20,     41,
+       -46,     19,     34,     86,  -8770,     40,     20,    -32,
+       -30,    -16,     77,     72,     -4,     92,    -34,    103,
+       -77,    128,   -532,   -314,     24,    728,     49,    -36,
+      -178,     76,     22,    -14,   -164,   -194,     69,   3133,
+      1007,   -130,   -280,   2502,    482,     -2,     45,    -62,
+        -7,    -94,     17,     23,     -4,   9516,    -27,     11,
+        22,     54,    -13,      2,     -2,      6,    -22,    -63,
+        67,   -686,    130,  -2180,   -124,     57,    -61,   -158,
+      3364,    518,      4,    315,   -367,   -103,   -295,    259,
+      -597,     56,     -6,     72,    -86,    -45,    -13,    -47,
+       -13,    -27,     -3,     48,    -12,    -52,     -6,    -14,
+       -26,    -16,    -34,   9554,     80,     91,   -270,      1,
+      -121,    117,     33,      8,     40,    -99,    -79,     43,
+     -3451,    -92,    -70,    -57,     43,     68,     64,    284,
+      -639,    458,    118,    -54,  -2755,    370,    -66,     54,
+        27,   -198,    331,    115,    -40,   -209,   -312,     82,
+       -16,      8,    230,    212,   1853,    -94,   1957,   -118,
+       153,    -13,    -73,     71,    116,    -72,  -3285,    106,
+        19,   -121,    177,   -300,    455,    -29,     94,    190,
+       -21,     -8,    201,     16,      2,     83,  -6280,     32,
+       -18,     59,    -18,    -41,   -132,     22,      1,    -39,
+      -212,   -198,    186,   3154,   -102,   3463,   -280,   -118,
+      -132,   -132,     63,    -19,    353,    -24,    -77,    224,
+        82,    143,    -65,    165,    -16,  -3774,   3543,    -28,
+       -44,     93,    -45,    -13,    -24,     -5,    -40,     58,
+         3,     89,     71,    113,     46,     62,     44,    160,
+       -77,     -8,    -59,  -6505,    134,    -42,    -73,      0,
+        85,      2,     16,     34,    157,    -34,    -60,     78,
+        24,     64,     96,    478,    231,   -125,   -217,     13,
+        21,     44,     83,    198,    -69,     21,   -167,    -52,
+      4085,   -234,   -393,     17,   -446,   -354,    -28,     42,
+        53,    -37,     28,     15,    -16,    -10,    -85,   9471,
+       -16,    -89,    -87,    -56,     52,    -97,     86,     -7,
+      -103,    -12,     71,    -39,     17,    -40,     23,     63,
+        65,    -19,    -14,   -106,     29,   9707,     -1,    -12,
+         1,    -86,    100,      7,   1097,    266,    252,    197,
+       -64,   -214,   -197,    -28,   3843,  -1577,    310,   -117,
+       594,     13,     90,   -309,   -384,    134,    -90,   -194,
+      -316,   2884,    156,   -185,    196,   -103,     75,   1009,
+        69,    768,    -75,   -605,  -1488,    389,    242,    368,
+       278,   -122,  -2500,    121,      7,   -303,     91,    -10,
+      3642,     23,   -109,    -13,    138,   -405,     18,    -43,
+         3,     42,    194,   -112,    237,  -2241,     23,    296,
+       -83,    -14,    -58,   -163,     -8,   -174,   -239,     85,
+      -108,    -82,    -79,    344,    236,   -427,    127,     52,
+};
+
+static const int16_t cb1110l1[] = {
+       -64,     11,    -74,    -96,     39,   6072,     16,     46,
+      -215,    137,     77,    128,   -195,   -192,    -87,     96,
+       379,    -73,    367,    437,   -366,     84,   -155,    -29,
+       -69,    -61,    -34,   -129,    260,   -177,   3738,    739,
+      -221,    -14,    -40,      2,   -483,   -269,   2664,    166,
+        29,   -256,     30,     92,     51,    111,    -45,   3893,
+        90,    -30,    -99,     12,     74,    201,    -52,    -96,
+      -196,    -85,    -36,    123,    -44,    -68,      2,   8666,
+        33,    -41,     24,    -12,    -52,     69,     59,    -27,
+        38,   -148,    -55,    -20,    -60,     50,   3363,     30,
+      3749,    -92,    228,    173,   -239,   -167,    -75,    -79,
+       -86,   -217,     32,     34,   -137,    -13,     17,   -128,
+     -1462,   -170,   -224,   -393,  -3383,  -1243,    -47,     24,
+      -223,     26,    311,   -343,    -47,    784,    459,   -548,
+       558,    983,    103,    269,     32,     13,     19,    -84,
+       -37,    -29,    -47,  -6286,      7,     48,   -100,     13,
+        11,   -271,    -86,    115,    -17,    183,   3247,  -3336,
+        57,    -67,   -117,    -87,     19,     74,   -271,    237,
+       -24,    242,     49,   -179,    298,     85,    -69,    328,
+      -238,    -34,    103,    -50,     79,      2,    -27,    -16,
+      -103,    -61,   5868,   -105,   -262,     74,    -74,   -158,
+       263,   -110,    154,    212,     -3,    -84,   -126,     25,
+       -67,  -2501,    -12,    -35,    139,    259,    -95,   -141,
+       137,     90,     12,   -244,   -142,    314,     15,   -124,
+         1,    -25,    -27,     -2,     -6,     28,    -48,    -17,
+        -2,     43,     67,     42,   9023,    -25,     19,    -13,
+       -23,    -43,     73,    -30,    143,     -1,   2884,   -142,
+        -4,   3549,    -49,   -366,    110,    314,     19,    -55,
+       363,    204,    469,    189,    217,   -181,    119,     41,
+      -133,     29,    -55,    -94,     71,    -49,     41,     85,
+       -14,   6140,     71,   -142,     10,     18,    169,    136,
+       282,    -49,     36,    446,    -99,    263,     92,   2201,
+      -127,     43,   -143,   -350,     36,    389,   -208,     15,
+     -3610,   -275,    383,   1599,   -179,   -177,  -1100,     -4,
+        67,    -38,      2,    278,     39,    107,   -120,    465,
+       204,   -397,    305,    416,      7,   -262,     68,   2341,
+       189,    -75,    -23,     25,    -20,    -74,     56,    -43,
+      -125,    170,    509,     63,     26,    263,   -741,    -31,
+         8,   -296,    101,     20,   -149,   2846,   -218,    379,
+      -310,    151,    901,     84,    -85,    -83,   -387,    161,
+     -3102,   -158,   -438,     38,    191,    -58,   -202,    127,
+       126,    -88,   -430,  -3077,  -1829,   -332,     61,   -152,
+       -14,    -32,   -156,     -5,   -375,  -1083,  -5130,    110,
+        77,   -201,    -15,      4,     13,     86,    119,     67,
+       149,     80,    264,   -253,   -121,     63,    193,   -103,
+      -129,     63,    120,   -226,   -100,   3196,     72,    -11,
+         8,    -56,    279,    -73,   -192,     47,    -87,    125,
+       -43,   -108,    277,    188,   -107,    289,   5966,    -20,
+      -303,    -78,    -21,     40,   -139,     44,     28,      6,
+      -254,   -244,     47,     -1,   -151,     29,   -344,  -2318,
+        30,  -3767,    114,     84,   -155,     85,    -90,    155,
+       111,   -506,      6,    453,   -241,    215,    131,   -802,
+        15,   -343,    176,   -430,    251,    -74,      6,    -41,
+       -44,   -131,   -105,   -248,    346,     39,  -4524,     93,
+      -120,    -79,   -777,   -416,   -570,   -221,     21,     28,
+       -52,     56,     71,   -187,   2949,  -2531,    666,    799,
+      -137,    970,    243,   -695,   -148,   -281,    326,    450,
+      -734,    -99,  -2078,    112,    -83,    -90,    -78,    262,
+      -138,    -31,     -5,    -74,   -171,    -99,    344,    143,
+      4035,     56,   -121,   -921,     -8,     46,   4576,     97,
+      -219,    -34,    123,    -44,     -1,     85,    -36,    399,
+      -260,   -231,    132,   -318,     55,   -181,    156,  -3093,
+       142,     -9,  -3418,    -31,     43,    126,    136,    309,
+       -50,    -20,    170,    -90,    188,   -173,    175,     50,
+       144,   -244,     22,     64,   -476,    -22,    -66,    272,
+      3839,    715,   -188,    -82,   -250,   -587,     10,    368,
+      -507,    242,    -40,   -531,    451,     35,    560,   -107,
+       138,     15,    113,     56,    242,     33,    -23,    -27,
+        81,   -157,    301,   -327,    359,   3648,     62,  -1489,
+      -167,    136,    -39,    183,     53,   -151,    -16,    -60,
+       -65,  -5182,    -17,   -257,    -10,     56,   -104,    713,
+        -2,    328,     72,    353,     43,    -51,  -5949,     40,
+        32,    -82,    -36,    -22,     57,     56,     55,    112,
+      -104,     76,      5,     80,    -29,    173,   -360,   -113,
+        42,   -119,    180,    -26,    120,    250,  -3024,    198,
+       115,   -140,     22,    136,    275,    698,   -149,    699,
+       426,   -220,    279,     63,     55,    -63,   -108,    -51,
+       -70,    -70,    419,   -156,   5870,     33,    -57,   -114,
+      -388,   -213,   -164,   1543,    117,    165,   1944,    223,
+       -83,     46,    201,     12,   -103,    228,    139,   -207,
+       136,  -1218,   -544,   -723,     90,   -652,    793,     -1,
+      -100,    -32,   -236,     49,    164,    138,     16,     82,
+     -3221,    -62,   -168,     62,   -313,     98,   -652,   -484,
+       684,    -91,     33,  -2926,  -3453,    566,     34,     35,
+       104,     13,    189,    235,    -49,   -324,    126,    226,
+      -102,    123,   -253,   -403,     38,    160,     -5,    100,
+       -30,     16,    -19,    -44,      2,    -70,    -30,     82,
+       118,      6,    132,    -15,    -36,     59,  -8835,   -448,
+      3707,    324,     87,     67,   -110,    114,    -76,    294,
+       354,      7,    140,     11,    340,   -117,   -559,     67,
+       129,    201,   -314,    328,   -209,    102,   -121,    378,
+     -5010,    140,     53,     15,   -253,    -14,    414,   -183,
+       -70,    -25,    -51,     34,   -347,   -171,    146,    -98,
+      -101,     -3,    -99,     96,     66,     50,     -5,   -115,
+       -23,    -45,   -351,  -4202,    143,    480,    -46,    140,
+        17,  -6312,   -110,    -23,    150,     60,    -39,     -9,
+       -48,    -60,     -8,    -20,     37,     57,   -162,     60,
+      -137,     55,   -101,     65,    100,  -8952,      3,    -49,
+        -3,     -9,     28,     15,    -89,   -136,     59,    125,
+       -73,    -35,   -111,    -69,    -28,    111,    -16,     48,
+        27,   9272,     55,     34,    -92,     66,      3,      3,
+       -38,     12,     59,     95,   -100,      3,     51,    121,
+       146,   -200,    142,   -254,     65,      3,   -169,     -8,
+       -65,     44,     10,     15,    -99,     56,     -6,   -108,
+       -20,  -5461,    -89,    395,   2085,    486,    -48,    324,
+       422,  -3703,    468,    198,    239,      0,   -277,   -115,
+      -227,    227,    -29,    159,   -128,   -447,   -291,  -1953,
+      -110,     25,   2274,    141,    177,    204,     38,   -258,
+        90,     -8,   -131,  -2636,     55,    561,    -99,   -220,
+       -33,    142,   -334,   -160,   -117,    -12,    -33,      6,
+        72,     -3,    -11,     50,      1,    -45,      8,     23,
+       -15,    -33,    -15,     30,    -32,    107,    145,     14,
+        60,    114,     45,     24,   8811,     -9,     61,    192,
+        16,    124,     46,    -54,    -31,     89,   -147,   -112,
+      3341,   -395,     91,   -323,     45,   -156,     25,    -18,
+        34,   -534,    118,     83,   -187,    -92,    180,     34,
+       659,    135,    103,  -2342,     54,      6,    179,     40,
+       143,    232,  -3858,   -201,    179,     32,    -56,    406,
+      -236,    541,    -70,    -88,   -121,    447,   3028,   -223,
+       138,   -557,    230,   3457,     96,     -4,    -22,    -13,
+      -136,    -45,   -123,     -8,    107,    270,    132,    -64,
+       -32,    464,    -33,    -44,  -2544,   -251,   -246,    -71,
+     -4063,     40,    107,    384,    -22,   -197,     64,    166,
+      -137,    -44,     98,    -35,    193,      4,  -2103,     57,
+      -109,    245,   3487,    -55,    -60,     21,    187,   -267,
+       279,      3,    166,    -78,    108,   -135,    126,   -122,
+       171,   -133,    -21,   -134,    183,     25,    -56,  -6210,
+       107,    109,     22,    -93,     39,     95,     43,    -11,
+       -44,     -5,    -82,      6,    -54,    -27,   -116,    -16,
+        84,     44,     22,    -68,     -1,    -57,     78,     35,
+        83,   4664,     46,      1,   -164,   3301,   -358,  -3757,
+       236,    104,    -81,   -121,   -278,   -112,    -20,     89,
+      -123,     35,    113,     17,   -331,    273,   -172,    125,
+       -73,     77,   2515,  -3944,   -170,    -87,    174,     84,
+       142,    138,     13,    227,    127,    146,    141,    196,
+        38,    -40,   -112,    136,   2311,    328,     87,    -22,
+       -77,    -34,   -195,     58,   -333,    337,   -159,    626,
+     -3008,    408,    523,   -316,    539,   -587,    -81,  -2824,
+        98,    200,    613,   -107,   -170,  -1190,   1121,    521,
+       229,   -217,    143,    144,  -1248,   -384,   1535,    470,
+      -655,    492,   -429,    -26,   -132,   -180,     52,     97,
+        10,    -35,    -60,      7,  -5422,    -26,    154,   -132,
+      -221,    124,    136,    -17,    -68,     25,     29,      4,
+         5,    -15,      9,     69,    -16,    -47,    -76,      5,
+        41,      6,    -22,     63,     -8,   9709,    -33,    650,
+      -545,   -159,     81,    -75,     54,    -92,    -49,    -80,
+        14,    -78,   -145,   -399,  -3935,    186,  -1144,    207,
+        60,    286,   2642,     44,    117,   3758,   -154,    426,
+       331,   -615,   -216,    271,   -121,   -109,    495,     42,
+       813,    -19,    545,   -149,    633,  -2424,  -2089,    265,
+      -136,    -58,      4,    -28,    147,      2,   -123,    -93,
+        14,    -50,    317,    131,   -130,   -152,    322,   1023,
+};
+
+static const int16_t cb1110s0[] = {
+     -6433,    495,   -277,   -630,    411,   1241,   -326,   -425,
+       523,    114,   -225,    -53,   -538,   -702,   -260,   -417,
+      -401,   -222,   -263,   -416,    163,  -1256,    590,  -1176,
+      1865,   1483,   -927,    -65,   -674,   1303,   -147,   -750,
+      -132,    407,   -283,    852,   1788,  -2257,    210,   -450,
+       303,   -272,  -2536,     94,   2010,    428,   -921,     -3,
+       -71,   -875,    156,   -681,    521,     49,     51,   -523,
+      1532,   1619,   -690,    402,   -923,    318,    865,    193,
+     -2187,   -662,    553,  -1104,    -70,  -1313,    462,  -1045,
+       320,    937,  -1453,   -514,    404,   -231,  -1748,  -1592,
+     -2039,   -217,   -364,  -1313,   -428,   2419,   1257,  -1292,
+        19,   2867,   -278,  -1832,   -239,   -691,   -383,     62,
+       185,   -455,  -1589,    116,    419,   -319,   -418,    537,
+      -280,  -1834,   2681,   -857,   -210,   -156,  -1143,   -104,
+     -1774,   1702,    184,   1017,   -135,   -610,    525,    335,
+      -355,   -494,   -231,   -154,    986,    434,   1134,   1213,
+       914,   1457,   -258,  -1086,    477,  -2247,    498,  -1741,
+      -975,   -262,    812,    108,    834,   -412,    120,  -1032,
+      -533,   -456,    139,   -301,   -387,   -690,    798,      3,
+     -1556,   1261,    745,  -4486,      8,    213,    977,   -151,
+      -269,   -344,     13,    544,   -270,   -166,   -706,    672,
+       184,   -943,  -1714,   1510,   -739,   1891,   -477,    528,
+      1847,  -1572,    420,    103,    -85,    508,    231,   2024,
+     -1343,     20,    238,   -655,    668,  -1561,   -743,   -651,
+       709,  -1136,   -208,    979,    258,   -693,   -535,  -1126,
+      -283,   -944,   -209,    603,  -1797,  -2998,    253,   -296,
+       842,     63,   -203,   -468,    675,    337,   1458,    114,
+       259,   3202,    145,    419,    631,    352,   2309,   1337,
+       815,    -99,   -824,   -779,  -1839,  -1455,    166,  -2092,
+      1299,    162,  -1026,   -914,    128,   1321,    896,   -209,
+       255,  -1144,    807,  -2870,   -632,   -588,    866,     81,
+       453,    154,  -1258,   -499,   -452,    -98,   2599,   3070,
+       540,   -834,   -228,  -1268,   -313,   1269,    -65,    -56,
+      1035,   -499,   -507,   -657,    447,     26,     96,   -175,
+       133,   -291,   -538,   -259,      7,   -206,    411,    145,
+        25,    215,    267,  -4354,   -442,    250,   -814,   -143,
+      -459,   -182,   -640,  -1258,    169,    379,  -1196,    429,
+      -128,  -1971,   2681,    -45,   1641,    152,   -556,    909,
+       365,   -618,   -417,   -363,   -434,    270,  -1388,   -473,
+        62,     58,    509,  -3909,   1327,   1571,    482,   1081,
+      -896,    459,    480,   -557,   -267,    390,    -15,    484,
+       248,     52,     49,    702,    -10,    162,    245,   -416,
+      1397,     23,    183,    325,    591,   -816,   4429,    674,
+      -332,  -1243,     68,    285,    235,    759,   -315,    799,
+       313,   -331,   -182,   -629,    394,  -1079,   3879,    -81,
+       651,   -774,    -21,   -297,    231,  -1826,     47,    104,
+       284,   -171,   -198,   -110,   -193,    881,   -715,    294,
+      -490,    395,  -1261,   2859,  -3175,  -1477,    668,   -215,
+       310,     10,    762,   -837,    101,    142,    201,   -940,
+       453,    -82,    493,   -983,     23,   -211,    990,   1327,
+      4664,    -27,    821,    809,    500,    243,     41,    568,
+        44,   -320,    105,    461,    306,   -408,   -793,    -35,
+       -18,    229,    -12,   -416,    577,   -301,   4870,   -520,
+       499,     57,   -544,    -21,    611,    226,    -20,   -412,
+       440,   -680,    448,    430,    226,   -610,   -310,   -218,
+      1161,    523,   -400,   -148,    783,    395,   -126,    370,
+       686,   -497,   -301,    161,     -5,    238,    375,    357,
+      -126,    954,   5952,    -53,    121,   -405,   1571,    435,
+       461,  -1166,  -1163,   1347,   1394,    170,   2035,  -1580,
+      -958,    276,   -680,   -968,    275,   -323,    524,     48,
+     -1896,     46,   -495,    548,   -929,   -859,    224,   1079,
+       863,   3080,  -1594,   -379,    302,   -403,    710,    655,
+      -293,   -719,   -683,   -944,    228,   -341,    563,   -495,
+       920,    738,   -614,    552,   -249,   -402,   -164,   -262,
+      -425,  -4025,    164,   -984,   -518,    157,  -1156,   -729,
+      1024,   -768,   1003,    481,   -116,    319,   -918,   1563,
+      -662,   4852,    617,   -250,    549,   -265,    -93,    680,
+       470,    925,   -293,    629,    142,    231,     44,    133,
+        12,     40,   -867,    269,    -77,    445,  -1132,   -985,
+     -1304,    728,    424,    530,   -258,   -625,    377,  -1400,
+     -2538,   -470,  -1711,    413,  -1603,    -81,   -393,  -1013,
+      1130,    906,    287,    640,   3785,   -463,   -159,     43,
+      -165,   -441,   -513,   -287,   -554,   1547,    848,   -275,
+       936,    653,    769,    -58,  -1007,   -698,   -792,   2175,
+       398,   1382,   -122,    459,     -7,    281,   2785,   -637,
+       632,   -279,    293,  -1078,   -996,     96,   -293,  -1335,
+       -74,   -587,   -286,   -565,   -977,   -228,   5080,      3,
+       171,    111,    -34,   -177,   -619,    577,    448,   -280,
+       189,   1033,   -579,    134,   -713,   -947,   -249,  -1897,
+       364,   1748,  -2098,     21,    859,    -73,  -1881,    116,
+        36,   1591,   1386,  -1128,   -346,  -1015,    -25,    -90,
+      -691,   -984,   -120,     29,   -635,   -236,     26,   -691,
+      -742,   -203,    294,   -472,   -901,   2582,   -171,   -357,
+       406,    162,   1561,   -913,    308,  -3319,    461,    779,
+      -305,   -927,    290,   -941,    615,   -688,   -508,    222,
+      -432,    387,    170,   -115,  -5338,    508,   -212,    150,
+        26,    -38,    306,    -15,     50,   2008,  -1112,   -187,
+        44,    591,   -280,   1187,    934,   -228,    554,     65,
+     -1387,  -1999,   -805,   2555,  -1225,   -283,   -435,   -430,
+       -50,   -655,   -103,    248,   -234,     32,   -826,   -708,
+      -704,  -1006,    176,    784,    274,    626,  -2353,    707,
+      1852,   -132,   -196,   -169,   -463,  -2117,     56,    413,
+      -141,   -818,   -365,    921,   -816,   -126,   -135,    438,
+      -948,   -145,   -349,    700,    205,   1001,  -3626,    314,
+      -493,  -1182,    131,    733,   2404,  -1244,    564,   -960,
+       328,  -1137,   -108,   -755,   -168,   -995,    966,  -1706,
+      -565,    806,   -693,   1369,   -269,   -428,    675,    768,
+       341,   -794,   2265,   -208,  -1883,   -801,  -1889,    961,
+       182,   -504,   -595,    871,  -1280,    952,   1351,    665,
+       474,   1032,     58,    451,   -198,    345,    176,   -853,
+     -2891,   2250,    624,   -616,    183,    144,    736,      0,
+      -198,   -138,  -1218,   -501,   -658,    -24,   1232,   -286,
+      -233,   -937,   2150,  -1035,    449,   -623,  -2748,  -2176,
+       918,   -170,    421,   1376,     93,    153,    627,    493,
+        28,    549,   -292,   -175,   1066,   1037,   -475,    413,
+     -2006,  -2022,   -334,    365,    901,    945,   -663,    515,
+      -351,   -597,    155,   1318,   -153,    417,   -425,     44,
+       338,  -1958,   -355,   -596,  -2134,    360,    341,   2501,
+       824,  -2106,   -282,  -1723,   -735,   -550,   -743,    113,
+      1027,   -479,  -2114,    -16,   -631,   -282,  -1054,   1320,
+      -158,   -234,   3479,     28,   1818,    627,   1464,   -795,
+       -22,    897,     -6,    392,   -234,   -170,    714,   -382,
+      1262,     67,   -618,    145,     25,   -710,   -247,   -545,
+     -1386,  -1797,   -995,    865,    465,   -364,    830,    -53,
+     -1108,   -383,   -538,     85,    731,   -188,   -813,      2,
+     -1667,   3379,    289,    425,   1319,   -259,   -592,   -212,
+       271,   -268,   -126,   1282,    306,   3859,  -1423,    607,
+        20,    755,    174,   -782,     72,   -234,    675,  -1177,
+      1101,   -635,  -1641,   2574,   -978,  -1390,  -1743,   2183,
+        53,     75,    650,    -97,   -456,   -126,   -719,   -675,
+       557,   -375,    643,    853,    -81,   -192,  -1174,  -1288,
+      -954,   -883,   -806,  -2182,  -2111,  -1426,    180,   -266,
+      -301,    626,   -443,     61,   -149,   -443,   -935,    -48,
+       642,    250,     17,    596,   1342,  -2127,    323,  -1456,
+      1995,    837,  -1456,  -1683,    945,   -722,  -1445,    452,
+       178,   -441,   -250,   -137,   -128,    -50,   -311,   -600,
+      2237,    922,    139,   -107,   -637,   1770,  -2503,    413,
+      -803,    496,    209,   -391,    401,    412,   -552,    605,
+       -37,   -667,  -1609,    -19,  -1073,   1522,   -705,    670,
+      -992,    882,  -1213,   -854,   2150,   -371,     73,  -1167,
+      -592,   -153,   -509,   -584,   -495,    -83,   2075,  -1489,
+       719,   1245,  -1138,     72,    950,   -950,    542,   -590,
+       988,   1646,    -64,    562,   -223,     73,    583,   -151,
+       215,    914,   1391,  -2997,    161,    436,     49,   2225,
+       271,   -283,   3844,   -578,    335,    -90,   -698,   -162,
+      1236,   -117,    470,    383,   -718,    520,    295,     29,
+       292,   -179,    774,    204,    372,   -251,   -824,   -487,
+     -1822,   -312,   -731,    568,  -1008,   -255,    189,  -1195,
+       657,   -227,   3422,    651,   -220,  -1204,   -590,    713,
+       365,   -977,    204,   3118,    321,    922,   -347,   1505,
+       375,    -77,  -1520,  -1411,   -680,   -507,    543,   -492,
+     -1844,    135,    689,    384,   -408,    140,    633,  -1192,
+       475,    220,  -1711,  -1318,    606,   -103,   -712,  -1734,
+      -218,   -855,   -835,  -3071,   -109,   1391,     62,     21,
+       -75,    -77,    369,    216,  -1484,   2057,    661,    314,
+       275,   1048,    175,   1842,    743,    808,   -594,    338,
+     -1217,   1606,   -531,  -1360,  -1073,    452,   -531,   -798,
+      -771,  -1292,   -918,    606,  -1776,   -509,    178,   1422,
+      3424,    634,    722,   -257,    525,    437,   -197,   -130,
+       291,   -411,   -259,   -890,    -84,    368,   1117,  -1321,
+      -324,  -2122,    515,   1158,   1749,   -963,    681,     39,
+       268,    549,    324,   -601,    151,   -200,    829,   3881,
+       797,    660,   -572,   -693,    633,   1023,   -147,   -581,
+       102,   -207,   -163,   -511,    -30,   -102,    379,    776,
+       494,   -510,     55,  -1811,   1073,   4384,   -318,   3277,
+      1958,   -209,   -539,   1823,   1200,   -182,   -186,    213,
+       123,    506,   -471,   -431,   -698,   -331,  -1168,     88,
+       276,   -184,    733,   -295,  -1053,   -717,    862,  -1453,
+     -4235,   1063,   1049,   -621,   -429,    372,   1043,    599,
+       271,   -693,   -689,    122,    466,   -323,    332,   -533,
+       645,    516,   -371,   -207,  -2046,     72,  -1125,   -229,
+     -2769,   -330,   1387,    -89,    342,   2786,   -730,    152,
+       629,    809,   -459,   -248,   -266,    111,    380,    724,
+      -411,    640,    -72,    323,     34,   -277,    443,    289,
+       151,  -4816,    402,   -171,   -731,    635,    -84,   -133,
+      -310,    397,    904,   1193,  -1512,    -25,  -1306,    587,
+       322,  -3762,    537,   -306,   -981,    917,    190,    787,
+      -613,    149,    301,   -376,    366,    350,     18,    893,
+};
+
+static const int16_t cb1110s1[] = {
+      -332,   1306,   1626,   1555,  -3510,   -225,    418,   1520,
+      -969,    -74,   -286,    233,   -313,    -97,    375,    181,
+      -309,   1348,    969,   -504,   -141,    789,  -1224,   -137,
+      -704,     98,   1003,    466,   2259,   1485,   -225,     61,
+       272,   -223,   -347,    -23,   -368,     96,   2345,    112,
+       363,   -552,     -6,   -806,  -1637,  -1703,   1597,  -2114,
+      -196,    293,  -1173,   -630,   -863,  -1224,    784,   -722,
+       744,    885,    798,   -384,     92,    298,   -873,   1808,
+      1389,    488,  -1569,  -1541,  -3064,   -734,      3,    467,
+      -987,    346,   1915,   -683,    205,   -487,    341,   -330,
+       274,    -25,     49,    -83,   1246,   -405,   -777,    266,
+       121,   -250,    466,  -1232,  -3197,   -871,   -638,   -332,
+      1563,   1900,   -470,    556,   -465,   -412,    901,    -86,
+      -683,   -577,  -1033,    808,   -863,   1212,   -724,   2222,
+       429,   2733,    413,    891,   1669,    515,   -439,    187,
+      -359,    414,    176,   -706,    679,    -63,   1247,  -1721,
+       779,  -2770,   -484,   -633,   -993,   -243,   1442,   -312,
+      -324,   -370,    392,   -407,    229,     97,   1267,    -18,
+        46,   -303,   -684,    515,   -166,   4212,   -775,    -23,
+       -53,     23,   1966,   -465,    231,   1195,    252,  -1036,
+        16,   -824,   -116,   -582,   -286,    470,   -159,    217,
+      -456,    549,    648,     60,  -1119,    221,   -747,    354,
+      -628,   -486,    894,   1280,  -2631,    247,    430,  -1703,
+        69,   -236,    147,   1445,    540,   -936,    181,   -163,
+       931,  -1044,    669,   2457,    519,    597,  -2031,     11,
+     -1319,     -4,  -1190,     85,    254,  -1494,    230,   1583,
+      -547,    277,  -2006,   -103,   1195,  -2522,   1301,   -633,
+      -104,   -511,    573,   1628,   -451,  -1022,    564,   -692,
+       255,   1029,   -408,    757,    172,   -395,   -472,  -1703,
+     -1856,   -379,    289,    509,   -628,  -1349,   -207,    404,
+      -399,   1671,    392,   -935,   -190,    952,  -1267,   1150,
+      1562,   -609,    491,   -346,   -270,   -483,    310,   1420,
+     -1017,   1714,   -645,    897,  -1327,   3154,  -1046,   -857,
+      -499,   -496,  -1348,    399,     63,   -653,   -315,    820,
+      1645,    614,   2202,    779,   3001,   1382,    387,   -843,
+     -1840,    422,  -1017,    246,   -219,   -550,    105,   -608,
+       426,   -346,   -224,    375,     22,   -448,   -270,  -1150,
+      -897,   4298,   -882,     49,    633,   -937,   -694,    675,
+      -322,   -793,   -516,   -360,   -248,   1190,    575,   -843,
+       -13,     50,   -801,   1181,    452,   -335,   -495,   -102,
+     -1057,    506,   -206,     66,   -647,    991,    259,    259,
+      -468,    197,    373,  -4216,   -750,    224,   -182,    520,
+      -530,   1888,  -2018,  -1492,    656,  -1447,    993,   -790,
+      -785,    792,   1658,    373,    131,   -460,   -703,   1080,
+      -875,   -212,   -694,    747,   -639,  -2267,   1263,   -415,
+      -749,  -1278,    591,   -745,   -225,  -1677,     69,    625,
+      -146,    212,    345,    728,   -553,   1117,    471,    550,
+      -498,   -729,  -2070,   1006,   -330,    939,   3636,     34,
+       349,    761,   -131,    372,    610,   -399,     10,     86,
+       110,    931,  -1159,   -175,    633,    568,    140,    712,
+      2800,  -1558,   2343,      3,   -974,   -673,    233,   1436,
+      -783,    599,   -442,    852,    639,    447,   -976,   -564,
+      1511,     36,    529,    433,    677,   1971,   2777,   -820,
+      -655,  -1463,  -1392,  -1142,   -352,    432,    730,    439,
+      -273,    844,    108,    115,    408,   -361,    504,    337,
+        58,   1074,  -1645,  -1623,   -493,    -70,  -1585,   2878,
+      -741,    636,   -224,   -974,    722,   -147,    149,    135,
+      -107,   -154,  -1027,    -18,   -989,    282,   3173,   1123,
+      -778,   1389,   -591,    337,   1660,   -288,   1162,    -65,
+       660,    326,    141,    358,    679,   -222,    460,    105,
+       512,     36,   -854,   -477,   -942,  -2362,    265,   2252,
+      -164,  -2059,    106,    666,   -420,    521,   -178,    396,
+     -1836,    475,     82,    356,    207,    433,  -1005,     97,
+       385,   -304,   -853,   1282,   -239,  -2134,     83,     84,
+       201,  -1894,  -1603,    683,  -1957,   -113,    839,   1187,
+      -313,    774,   -754,    941,   -739,    748,    116,    716,
+      1134,   -530,  -2178,     71,   -611,   1544,   3527,     -3,
+       283,    527,    457,    399,    762,     17,   -279,    196,
+      -518,   -160,  -1204,   -289,  -1354,    132,   -315,   -290,
+     -2179,    676,  -1474,  -1010,  -1397,    363,    -45,    783,
+      1326,    -33,   -109,   -617,   -271,   -967,   -103,   1867,
+       769,    740,   -818,   1011,   1411,   -693,  -2458,    808,
+       806,   -213,    468,     31,    -70,    166,    230,   -405,
+       163,     70,    652,   1077,   -190,   -622,   2343,  -1328,
+       601,    928,  -1661,    174,    429,  -2479,    501,    503,
+       -41,   1365,    671,   1006,  -1968,      7,    103,   -399,
+      -382,    573,    -27,    554,  -2263,  -3174,    277,    177,
+       807,   -328,   -816,    453,  -1548,    828,   -327,    187,
+      -393,   -745,    -76,   -808,    575,     -8,   -326,  -2062,
+       601,    566,    755,    775,    595,    419,  -3925,   -226,
+       272,    368,    395,     59,   1117,    548,   -649,   -429,
+       321,    549,   -744,    319,     82,    135,     73,     14,
+       374,     93,   -270,   -453,    177,   4991,    569,    169,
+       111,   -246,   -362,    -88,    -49,    583,    -35,     60,
+      -759,   1327,   1768,    766,   -350,   -880,   -106,   -449,
+      -113,   -683,   -418,   -999,    992,    559,   -290,   -147,
+      -324,     93,   -947,  -3932,    -37,    307,   1087,   -314,
+      -293,    432,    830,   -130,   -208,     59,    719,   -348,
+      4511,    224,    488,   -174,    588,    795,   -301,   -246,
+      -447,    682,    917,  -1207,   -503,   -450,    575,   -116,
+      -126,    594,    -22,   -101,      5,  -1188,   -431,   1146,
+     -3869,    -72,    402,   -417,   -390,    350,   1141,   -138,
+       697,     77,  -3255,   -268,   -786,   -106,  -1386,    400,
+      -856,   -691,   -438,  -1550,   -228,   2162,    236,     64,
+      -382,      1,   1032,    153,   -659,   1563,   -410,   1280,
+      1573,  -3675,  -1041,    240,    401,    215,   -353,  -1140,
+       265,   -103,   -824,    -93,   -319,   -849,    253,   -477,
+      -463,    153,  -1017,    538,   1233,  -1041,     11,    998,
+      -437,   -569,   -970,   2118,  -1577,      1,    321,   1784,
+      -298,   2315,     72,    -20,     83,    905,  -1289,   -246,
+       731,   4076,  -1477,    602,   -911,    978,    698,   -239,
+       391,   -729,   -276,    225,    143,   -417,   -500,    -27,
+     -1220,     89,   -403,  -1453,  -2546,   1015,     70,     78,
+      2364,   -159,   -775,     29,     37,   -231,     73,    433,
+       426,   -529,    420,   -613,   -100,   -605,   1463,   1001,
+      1159,  -4082,   -553,    348,   -806,    624,   -162,  -1121,
+       -25,    919,    -62,     90,   -275,    233,    203,     32,
+       745,   -221,    458,    529,    901,   1088,     38,   1209,
+       450,    451,   2250,   -411,   -205,    761,    249,  -1226,
+      -266,  -3195,   -801,    -31,   1015,   -324,   -596,    -42,
+       150,    207,   2597,   1041,  -1045,  -2254,  -1428,    250,
+       217,     69,   -933,   1424,    280,    446,    524,    540,
+       639,  -1027,     23,    412,     36,    -67,    475,  -1126,
+      -739,   1160,    514,   -157,  -2832,  -1432,    559,     77,
+       740,   -888,    134,   1304,   -267,   -267,    329,      8,
+      1721,   1488,    -29,  -1760,  -1904,  -2634,  -1342,   -528,
+      2233,   -219,   -194,  -2919,    128,   1203,   -623,   -127,
+       488,   -386,   -133,   -329,     62,     85,   1271,   -185,
+      -479,   -588,  -2964,    546,   1651,   1526,   -830,   1046,
+       347,     63,  -1048,    239,   1402,    -22,    307,  -1606,
+       768,    999,    304,   -512,   -175,   -246,   -373,    529,
+        93,   -521,   1310,   -508,  -4366,     27,   -768,   -358,
+      -575,     -2,   -593,    -21,   -838,    635,    197,    634,
+       321,   -263,   -377,   -549,     20,    739,    395,     -9,
+      -392,     70,   5679,   -133,   -130,   -240,   -678,    421,
+      -101,    412,    143,    209,    194,    216,    200,    -22,
+      -748,   -399,   2863,    284,    231,    691,    571,  -3460,
+      -200,    312,    480,  -1338,   -603,    435,   -308,   -615,
+       520,    178,     68,   -716,     45,   -593,    -32,  -1393,
+      -554,  -1000,   -867,    613,    288,    507,    202,   -113,
+        17,     93,   -141,    -47,    665,    559,   -808,  -4091,
+      -575,   -193,   -873,   -790,    673,   -608,   -941,    745,
+      1562,  -1060,    988,   1192,     29,  -1207,    207,    653,
+      -622,   -132,    370,   1435,   1977,  -1878,   -119,    101,
+      -100,   -154,   -869,  -2375,   1254,    122,    188,    877,
+       188,   -838,   -355,    667,   3813,   1076,    369,   -771,
+      -712,   -669,    -14,    107,   1027,    112,   2306,   1418,
+       133,   1055,    377,    249,   1023,   -927,     12,  -1983,
+      1174,    223,    385,    827,   1425,  -1694,  -1178,    -94,
+      -593,   -286,   1263,   -671,   -425,   2002,    701,   1546,
+       547,    182,   1013,    128,    351,   -243,    407,   2349,
+      -376,    445,    -93,    968,   -337,   -601,   1342,    987,
+     -1499,   -644,    521,    327,   -557,   1800,     12,    285,
+       127,   -269,  -1989,   -449,     87,  -1042,    184,   -499,
+      1231,  -1664,   -352,      4,   1253,    403,  -1064,    837,
+     -1702,    133,   1687,  -1300,   2248,    179,   -847,   -617,
+       460,    450,   -260,     94,   -780,   -675,   1209,     38,
+       453,    857,   -631,    317,    535,   1086,   -196,    638,
+      -288,   -389,    688,    -93,   1271,  -4290,    -96,    445,
+        64,   -211,    148,    -74,    486,  -1873,   1214,   1836,
+      -708,   1800,   1644,    576,  -1088,  -1212,   1147,   -456,
+       173,   -911,    489,   -443,    644,    534,    846,  -1522,
+      -786,    497,   -401,  -1087,   1410,   1391,    837,   -253,
+       124,   -598,   -254,  -3945,  -1169,    103,   -193,     50,
+       846,  -1014,    353,    455,    784,   1343,   3055,    178,
+      -628,   -148,   -266,   -324,    -96,   -190,   -930,    115,
+       475,   -651,   -314,    -82,   -236,    -88,  -3753,  -1048,
+      -283,   -178,    351,   -671,    325,   1054,     28,    540,
+       113,    -73,    763,    844,    543,     -6,    799,    245,
+       176,    124,    262,   -112,   1010,    361,   -843,   3290,
+     -3741,    914,  -1835,   -259,   2467,    297,  -1205,    168,
+     -1917,    156,     87,    637,   -677,   -955,    312,   1246,
+      -219,     92,   1090,   -292,   -773,    343,   -523,    299,
+      -513,   1321,   -536,    586,  -1324,   2345,   2384,   -719,
+      -936,   1389,    -27,    880,    338,   -127,   -666,   -441,
+      1603,    143,   -218,   2167,  -1335,    469,  -1224,   2489,
+      1365,    568,     19,  -1322,   -736,    208,   -494,   -454,
+       990,   -250,    305,   -575,    206,   -168,  -1177,    282,
+};
+
+static const int16_t cb1110m0[] = {
+       429,   -104,   -210,    216,    361,  -2586,    253,  -1350,
+       145,   2795,     -5,    663,   -262,     37,   -122,    205,
+       270,    321,   2623,    256,      4,    -42,    -37,    112,
+      -346,     20,    -51,      9,    -90,  -3342,     78,     52,
+      -239,   -454,   -207,    355,   -136,    -19,    394,   -212,
+      -166,    -73,    -68,   1049,  -2945,    385,   -545,   -211,
+       116,    -15,    687,   -232,   1824,    -66,    133,   -403,
+       -63,      3,     46,   -104,   -101,    136,    -61,    420,
+       149,    -24,     -9,   4277,   -149,   -166,     96,    -35,
+      1786,  -1044,    115,  -1326,   3381,   -520,     70,   -134,
+      -433,   -198,    146,   -615,   -143,    201,    342,    412,
+      -162,     22,    111,     16,    -85,     14,   -120,     79,
+       -30,    -84,     56,    -34,    -52,   -147,     19,    155,
+        17,   -120,   5853,     96,    767,    262,   -194,    124,
+      -180,     13,   3081,     39,    402,     90,    292,     84,
+      1999,    -16,    866,    292,    416,   -314,    177,     -1,
+        68,      3,    -28,    -56,    -54,     10,     -5,    -63,
+        89,    -69,   -251,     70,   7523,    -83,     67,     62,
+       178,  -1723,    -76,    101,    369,   -139,     58,    135,
+       -32,    138,   3393,   -575,    586,    292,   -296,   -505,
+      -634,     52,    280,     78,     14,    117,    -39,     77,
+       231,    136,     14,     51,    173,    -96,      5,    378,
+       -52,  -4340,   -263,     61,     22,  -2896,    -20,    180,
+        21,   3636,   -138,    104,   -279,     56,   -407,     -8,
+      -123,    134,    -95,   -500,    266,    -64,    -43,      1,
+      -170,     31,    110,     53,     56,  -5938,    151,     49,
+       -76,   -166,     34,     -8,    193,    198,   -118,     -4,
+       -44,    249,    -28,   -102,  -3614,     49,    464,   -388,
+      -744,   -500,    603,    -88,    -19,   1606,    325,   -227,
+      -277,   -142,    232,  -1835,    150,    -89,     29,      9,
+        76,    425,   -320,    179,    231,   1720,    424,  -2730,
+      -298,    666,     72,   -428,  -1243,   -299,     93,    -12,
+       -20,    -96,   -123,     18,    188,     -1,   -235,     -2,
+      3328,    107,  -1489,    199,    893,    -63,     46,   3799,
+        22,   -118,   -127,    283,    254,  -2091,    293,    331,
+       857,    -92,     46,     13,   -457,    169,    851,    -19,
+      -231,  -8735,    -62,     69,   -190,   -103,    -31,    108,
+        66,     95,     53,     -6,     12,     19,    -73,    105,
+       -40,    -29,     60,   -263,   -107,   2233,   -246,    485,
+       342,   1732,     76,   2489,     40,     44,   -300,    280,
+      -109,   -107,   -990,    -45,   1014,  -5073,      1,   -169,
+        25,    -55,   -340,   -427,    603,    206,    151,    360,
+       312,    -44,   -106,    514,    683,     98,   3331,     19,
+      -106,    106,  -3383,     85,   -161,    -88,      8,     12,
+      -163,    183,   -393,    117,   -243,   -498,    -60,    292,
+      -322,  -2105,    920,    301,     41,    -19,   -142,  -2485,
+       631,   -289,   -849,    132,    800,   -255,   -390,    137,
+      -850,   -411,     41,    -93,  -8653,      9,    -25,    134,
+       -66,    222,    152,     59,     29,   -193,   -129,   -105,
+        39,    -21,    188,    111,     25,     -3,      0,    -79,
+      8907,    -24,    -18,     37,    -33,    -42,     87,    -44,
+        56,    -79,    -67,    -52,     18,   -132,   1925,    309,
+       145,   -443,   1279,    200,   1215,    281,   3343,    311,
+       390,   -154,   -119,   -523,     19,   -529,    190,    272,
+       541,   -393,    278,    161,     13,    161,    891,    -65,
+      -199,  -1376,   -350,  -1409,    340,   2115,   -209,   2459,
+        30,   -509,    141,     11,   -557,  -1560,  -1912,   -234,
+        76,    787,   2781,     45,   -158,    330,   -623,    655,
+      -845,   -463,   -119,   -252,   -299,  -1940,    145,     17,
+      -183,    -71,     98,     67,    145,   -134,    -88,     -5,
+     -3636,      3,     34,    231,    981,     33,   -953,   -403,
+       129,    215,    -11,    109,   -188,     51,   5176,    -89,
+      -113,     60,   -138,    -94,    142,    216,    322,    -33,
+       350,   -285,    182,     92,    -16,     12,     15,    126,
+       -27,      5,  -5220,   -154,     13,    109,     18,   -326,
+      -257,    118,    313,    342,   2289,    -35,    -22,    115,
+      -256,  -2908,     68,   1211,    203,   -735,   -380,   -134,
+       249,    522,    109,    -48,  -5114,     32,    -42,     85,
+       -99,    265,   -187,    -93,    373,    341,   -254,     16,
+      -121,    -92,   -260,    -80,     -2,   -322,    234,    -96,
+     -2834,    230,    146,   -264,  -3287,   -153,     41,   -349,
+      -149,    -98,    140,   -115,    628,    -11,    292,      4,
+      -166,     82,  -4548,    116,    -23,   -311,    612,   -334,
+       451,    259,    559,    320,   -267,    517,   -139,   -166,
+       126,     27,    -89,   -156,     14,     63,     -3,     31,
+       109,    -43,     10,  -7682,     36,    -23,     73,    129,
+         0,   -116,     66,      5,    137,    -17,   2523,    203,
+       431,  -2729,    175,    540,    454,   -175,   -297,    -60,
+       348,     53,    688,    -49,    133,    -72,    200,   -348,
+       136,   -142,  -2259,  -3047,    -60,   -737,     48,   -331,
+        85,   -134,    218,   -962,   -278,   -148,  -1077,   -131,
+        53,   -127,  -2265,     82,    -31,   -262,    226,   -385,
+        83,    756,  -2715,   -492,   -115,    663,   -312,    240,
+      -318,   -819,   3040,   -181,    148,    165,    376,     92,
+      -233,    188,   -100,    902,   -401,   1005,    -52,    162,
+       219,   1831,    -68,    -66, -10023,    -90,    -23,     39,
+       -91,   -231,     23,    174,     42,     79,    -57,    -58,
+        18,    175,     32,    122,   -185,    266,    162,    300,
+     -3158,  -3381,     -3,   -312,    178,    -24,   -234,    248,
+        68,    293,    360,   -146,    -30,     -2,    177,    113,
+     -1215,   -538,   -274,     79,     -2,    -17,   2791,     71,
+     -1300,     93,   -818,   -558,   -331,    115,    215,   -603,
+      -202,    113,    -87,     39,   -277,   3564,     75,   -444,
+       201,    111,   -369,  -1072,    212,   -276,   -322,   -484,
+      -700,     37,   -302,    177,     86,     10,    -87,     56,
+        76,  -8941,    -27,    -73,   -133,    -51,   -106,    -28,
+       -52,     49,     68,     26,     16,    -81,   -423,   2834,
+         7,    -54,   -107,    144,  -3812,     17,   -355,      3,
+       -32,    -24,     14,     76,    169,   -260,    349,   -159,
+      3691,   -184,   4345,    -46,    146,    -14,    143,   -384,
+       -75,     12,    144,    105,     47,    141,    -32,    -31,
+        48,    187,     74,    139,    132,     86,    -15,   -317,
+      -267,   3112,   1821,   -363,   -125,  -1152,   -294,   -449,
+       277,   1151,   -341,     12,    -41,    210,    -51,      6,
+        18,     53,     11,     37,    -36,    -70,     65,     44,
+     -7302,     15,   -133,     56,    150,     63,    515,    271,
+       -32,     47,     41,   -130,    168,   -158,   -239,    -60,
+       226,    247,   -593,   -237,  -3559,     65,    623,     16,
+      -212,     26,   -181,     81,     83,     26,    -25,    -92,
+        -5,     36,    -31,    277,   -263,    135,     78,   -173,
+       220,  -5260,   2239,    -96,    -19,    -95,     75,    -25,
+       -64,    244,   -154,  -2646,   -446,    980,    512,    392,
+      -402,  -1050,    276,   -456,  -1334,   1863,    636,  -1512,
+       234,    199,    237,    363,     66,    284,    198,   -277,
+      -267,   -540,   -329,    856,   -482,   -645,    178,   -240,
+      -178,   6633,     -5,    127,    -80,   -167,    307,      7,
+       248,     13,     53,    124,    215,   -310,    255,   -194,
+     -3066,    -22,   3524,     51,    193,    165,     82,    -80,
+        54,   -191,   -278,    -19,    379,    285,    -58,   -157,
+      -168,   -183,    388,   -198,    191,    107,     10,     -2,
+     -6148,     45,    -58,     48,   -150,    -72,    112,   -124,
+       -41,   -129,     36,    -66,  -3311,  -4092,     15,    -11,
+        93,    -54,     72,   -105,    131,     66,     29,    -54,
+       201,   -210,    221,     47,     55,    -99,     31,  -3626,
+     -3623,   -175,     91,    -53,     40,    -98,    -76,    224,
+        15,    172,     85,    103,   -147,   -135,   -214,   -313,
+      1304,    143,    190,     19,  -2526,    -91,   -168,    875,
+       -27,    789,    791,   -462,    912,   -580,     70,   1523,
+       787,   -150,    567,   2717,     -5,   2943,   -107,    155,
+        32,     65,    158,    133,   -191,    -44,    141,   -149,
+       199,    177,    270,    -14,    -57,  -3669,   3891,   -158,
+       239,    -17,     52,    244,   -343,   -118,    186,    -54,
+      -134,    106,   -133,   -116,    186,   -149,   -894,    -22,
+      -399,      1,    288,  -3988,   -260,    113,     66,   -276,
+       179,   -226,    119,    420,     51,   -483,    551,    129,
+       245,   2013,    639,    -87,   5058,     41,    -53,   -116,
+      -130,   -223,   -104,   -760,    276,    117,    338,   -137,
+      -233,    -65,    119,    100,  -3245,      2,   3877,    126,
+       172,     -2,    -72,   -153,    200,   -109,    -62,    135,
+       194,    -82,   -150,     98,    550,   -251,   -274,     71,
+       160,    121,    -13,   -365,    356,   -212,   -271,   5067,
+      -203,   -251,    222,     75,   -131,     17,    103,   -911,
+      -348,    -26,      6,    110,    120,   -645,    355,   -649,
+      -132,  -3416,     65,  -1478,    461,   -109,    258,    -15,
+};
+
+static const int16_t cb1110m1[] = {
+      -110,   2743,    -31,     86,    -11,   3705,    192,    -89,
+        57,   -252,    -11,   -212,    163,      0,   -137,    405,
+       -99,   -124,   -137,   -407,    125,    106,   -922,   1567,
+        85,    165,    241,    110,   2918,    598,   -443,    812,
+       159,    518,    555,  -1886,    -65,    -52,     -3,    -27,
+        56,    -30,   -126,    126,     23,     74,    157,   6990,
+       -34,     56,   -257,   -172,    115,    -23,   -616,   -243,
+      -441,     34,    159,      6,     78,   -119,     49,     34,
+      -133,    988,  -1007,    474,     77,   -274,    354,   4907,
+       222,    -16,     69,     -4,    924,    -18,   3535,   -299,
+       -38,    -83,   -111,    977,   -138,  -1075,   -444,    540,
+       199,    202,   -502,   -194,   -198,    249,    101,    276,
+       -89,     96,   -301,      6,  -4023,    -70,    174,     93,
+       192,   -120,    755,   -560,    -22,     78,     56,     29,
+        28,    -44,     65,     -4,      0,     49,   -250,     87,
+        46,     44,    -41,  -7035,     14,    288,    632,   -259,
+       -64,     20,   -178,   -343,   -274,    106,   2842,    336,
+      -283,    245,   -612,     -5,    500,     77,   2492,   -250,
+        64,    171,   -988,      4,    -51,    -34,   -555,   -171,
+     -2629,    272,   2852,   -162,    -98,   -237,   -278,   -489,
+       641,    -96,   7815,   -139,   -116,   -137,   -121,   -314,
+      -161,    211,     76,    136,    -35,   -124,    -27,     76,
+       -98,    133,     85,    332,  -4352,    507,    -14,   -275,
+      -212,    308,    258,    129,   -165,   -197,   -104,   -150,
+      -104,     60,    125,    568,     -3,   1694,     62,    -70,
+       109,    122,    -57,    -18,   8642,    100,     50,     92,
+        17,    -86,    -93,    -68,   -121,    -61,    -32,     27,
+      -188,    502,    123,    -81,     37,     48,    187,     75,
+       -30,    -22,   -224,   -292,     99,    -49,   4273,     10,
+       834,    -25,    225,   2773,     78,  -3281,   -181,    234,
+      -130,    -74,    101,    214,    -26,   -113,   -268,   -168,
+       -90,   -435,    -26,     38,   -569,  -4009,     -1,     11,
+        69,      3,    249,     98,    178,    131,    300,   -826,
+        48,    337,   -828,   -371,     96,    312,    712,   -667,
+       -70,  -2070,   -242,    519,   -676,    143,   -613,    893,
+     -2193,    471,   1071,    213,  -1231,   -196,   -580,    155,
+       401,     78,    -64,     27,   -238,     22,    -73,    -19,
+       194,     60,    -87,   -210,   -155,    244,   -123,   -169,
+     -4442,    169,   3132,   -181,     65,   3950,   -396,    209,
+        39,    -52,    -26,    166,      1,   -164,    143,    -66,
+       169,     46,    -16,   -295,     39,     42,     40,     67,
+        25,     17,     -1,  -8920,    -82,    -42,     49,     81,
+       -61,      1,     39,    -40,     18,     74,    206,   -131,
+       -71,    106,      7,     88,    -13,     69,   -113,    -89,
+       212,     -4,   4373,    -34,    283,    105,    252,     59,
+     -2578,   -298,   1846,   -110,   -105,   -310,   -143,   -127,
+       274,    225,    861,    262,   -815,   -311,    -26,   -685,
+       243,   -620,   -374,   2992,   -112,    -35,   2903,    -94,
+       -56,   -213,     65,    383,     41,    508,   -258,   -103,
+      -440,   -237,    428,    132,   2793,    -77,   -113,    -58,
+       -19,  -3857,    -25,     40,   -167,   -243,   -233,    -41,
+      -279,    213,    -22,      8,    120,    126,    159,   -212,
+      -244,    183,   1605,     62,    -12,   -244,    519,    780,
+       116,  -3197,   -992,    341,    222,    681,   -357,   -669,
+        55,   1213,    100,    441,      1,    -57,    232,     10,
+      -114,    318,   -147,     89,    188,    448,   -327,   3735,
+      -292,    875,   -216,    211,    111,    160,    172,    286,
+     -3513,   -849,   -185,     -9,     31,    442,    747,  -1045,
+       187,    704,   -219,    509,     48,     69,    -25,    -10,
+        75,     23,     10,     23,    -32,     89,   8628,    -77,
+       -19,     27,      0,   -232,     22,    -50,  -1904,   -137,
+      -169,    128,    138,     78,   -443,    243,    157,  -3809,
+       231,    277,   -341,     73,    -70,    596,    259,    157,
+      2197,    575,   2445,     11,    -53,    118,   -115,    562,
+       108,     30,   -241,     30,   -394,   -155,   -186,   -344,
+      -237,   -319,  -2258,    343,   -311,     14,    169,     59,
+       -15,    233,    732,    365,   -692,   -108,   1416,   -463,
+      -279,   -248,  -1731,   -406,   -278,    298,    209,   5333,
+      -198,   -167,     50,    439,    142,     91,   -523,    226,
+       262,   -130,    -15,    573,     -4,    271,     -2,    -47,
+         7,  -9106,    -69,    -44,   -144,    -98,    199,   -181,
+         6,     45,     47,     37,    -51,    -68,    -50,   -116,
+      -105,     49,    376,   -420,    187,   2894,     29,   -471,
+      -221,    455,     -1,   -858,     55,   -197,    359,  -1972,
+      -188,    921,   -134,    186,   -843,  -2542,    322,     -1,
+      -158,   -352,   -307,   -578,    -60,    143,  -1302,    333,
+       681,   1373,  -1021,     18,    284,    -28,      8,    -57,
+       -16,     15,     58,     31,   8389,    -35,     18,     77,
+       -78,     15,     36,     17,   -134,    -17,    316,   -680,
+       491,     38,   -217,   -278,    276,   -299,    -75,  -4030,
+      -293,   -507,    -62,   -344,     64,   -438,   -344,   -256,
+       341,    199,    -66,     28,    -17,    -17,      2,    142,
+         6,    -48,   -169,    -27,   -117,   6739,     42,    -61,
+       140,    246,   3357,  -3243,     48,    -55,     49,     27,
+         4,    172,   -169,      6,     69,   -265,     70,     25,
+       223,     28,    129,    231,     57,  -1608,   2640,    -28,
+      -197,     29,    -11,    138,    621,    427,     20,    514,
+       663,    562,    447,   -158,   -909,    343,   -321,   -257,
+      6641,     -1,    -20,    -70,     62,    241,     51,    -83,
+       -48,   -156,   -266,   -335,    -43,    421,    350,    306,
+       165,   -541,     47,      5,    -40,    364,     21,    190,
+     -4584,   -125,   -441,    489,   -571,    -47,    -10,    205,
+        60,    -73,   -584,    417,    233,    -34,   -109,     85,
+        41,    134,    485,   -171,   -183,  -1522,    202,    390,
+     -3112,    144,   1675,    651,    402,   1953,    120,     93,
+      -276,  -1930,   -197,    -61,    100,     81,   -250,   -155,
+       -19,    336,   -178,  -2340,     88,   -543,    226,  -2507,
+       -60,    -62,    218,     -9,    158,  -3617,    -66,     32,
+       314,   -192,   -121,    372,    334,    516,    412,    247,
+      -609,  -1237,    312,   -120,    -39,     47,     61,    -63,
+       -90,   4500,   -191,   -353,     10,     54,   -163,   -345,
+       121,   -318,   -235,    190,    -99,    181,  -3369,      4,
+      -188,    -87,    128,    167,   -507,  -1132,   -666,   -354,
+       121,     43,   -546,    601,   -409,    181,    -47,   -315,
+       127,  -2845,    487,    186,  -2724,    343,    177,   -837,
+       387,    -84,    259,    122,   -159,     88,    117,    137,
+        79,    126,   1584,   -521,  -2448,   2648,   -246,    -75,
+       567,    114,    244,    653,   -551,   -196,   -623,    205,
+       816,     48,   -326,     66,    -94,    -33,    133,    412,
+      -241,    491,    -32,   -712,   -249,  -3756,   -185,   -229,
+       248,    268,    557,     73,    164,     24,    -70,    -27,
+        54,   -156,    -51,    -47,    -26,     43,    187,    179,
+       -38,   -137,    218,   1916,   4614,    435,    -15,     21,
+       145,   1868,    241,    240,    299,   -204,     73,    -24,
+      -118,   -372,    -89,     23,   -298,    479,   2837,    959,
+       -76,    -85,     -2,     28,     94,  -3245,     28,   -130,
+       159,    295,    264,   -419,    -98,    -16,   -159,    349,
+       202,   -158,  -2680,   -210,   -390,    -18,     -8,    364,
+      1367,   -110,    932,   -232,   1348,    -80,    865,   -291,
+      -408,    406,   -118,   6462,    -55,     10,   -152,   -161,
+      -132,    231,    258,    135,    -13,   -104,    247,    207,
+      -238,    212,    -19,    -31,  -3303,   -160,    -24,   3402,
+        50,    116,   -191,     97,   -139,   -100,     71,    -49,
+      -293,    133,   -120,    -10,    197,    196,   -516,   -686,
+        79,    -52,   6002,    -47,     88,   -201,    146,    136,
+        54,    162,   -180,    287,     67,     70,    -55,    210,
+     -1938,    635,   -162,     82,   -120,   -456,    -75,  -3753,
+       -83,    176,    137,     18,     -6,   -281,    232,    137,
+      -167,    373,     78,  -2622,    -38,   -293,     89,     69,
+     -3476,      8,    152,    136,     32,    -15,   -140,     11,
+         6,     13,    481,   -175,   -228,   -254,    158,  -3423,
+       206,     22,    900,   2025,    266,   -402,    132,   -356,
+       558,   -592,   -262,   -419,   1002,     73,   -246,    -24,
+     -3145,   3220,    -33,    283,    398,    -31,    -25,     -7,
+       103,    -93,   -143,      1,     32,   -497,    206,    -35,
+      1424,    114,    140,   2393,   3245,   -218,   -163,    113,
+       191,   -164,   -215,    504,   -256,    140,   -364,   -226,
+      -340,     91,   -464,     32,    188,      4,     15,  -6068,
+        69,    109,    219,     75,    196,    -24,    -84,   -218,
+        27,     57,    -97,      8,   -338,     -4,    358,     23,
+       -52,    -68,    552,   4023,   -255,    684,    144,    188,
+       100,   -293,    462,    553,      9,    665,     12,   -640,
+     -5099,   -158,   -245,    -74,   -168,    263,   -355,   -370,
+      -653,   -163,   -473,   -394,   -233,    750,     17,    -31,
+};
+
+static const int16_t cb1110sl0[] = {
+     -3736,  -3737,    -18,   -285,    383,   -144,   -155,   -204,
+       296,   -399,   -663,    356,   -364,    329,   -330,     -5,
+       -52,    -88,    -41,    228,    -21,    -45,   -136,   -280,
+      -109,    -86,     57,     91,   -212,    158,   -106,    -90,
+     -8192,     70,   -255,     78,     -8,    -89,   -110,    -58,
+       104,    -51,  -2598,    411,    -94,   -567,    209,   -464,
+       139,   -234,   -336,    754,    863,    399,    345,    117,
+     -3435,   -219,    369,     59,   -325,   2439,   -148,      6,
+       -48,     84,    -14,     71,     94,     10,      6,     73,
+       106,   -490,   -200,    186,    345,     -8,     99,  -3687,
+     -1571,   1836,  -1593,   1111,  -3700,    470,     -6,    401,
+      -182,   -119,    438,   -263,    228,    785,   -361,    -56,
+      -492,    465,    333,     61,     53,    234,    -23,    -87,
+        39,    105,   7282,     59,    -47,    -57,    -77,    -45,
+      -172,     12,    179,   -134,     37,   -157,    -19,   -206,
+         9,   1186,   -264,    600,    350,    374,    115,    -55,
+       727,   -164,  -3903,   -735,    586,    -24,    145,   -786,
+      -118,    943,    514,    396,   3435,    -35,     83,    294,
+       107,     16,  -3636,    -93,    360,   -307,   -105,   -172,
+       204,    320,   -148,    410,    175,    335,      0,   -178,
+        12,     94,    -47,    -91,    -49,   -159,   -155,    -65,
+       -17,   -159,   -316,     64,    155,   -260,     81,  -4766,
+      -150,   -116,   -332,    128,    675,   -105,   -479,    563,
+      -101,    101,   -379,     33,     37,      1,    106,    151,
+        69,    140,     -6,    -74,    157,   -125,   -120,    -33,
+      -178,   -286,     60,   -158,     43,  -7291,   -295,    -68,
+       -34,    -68,    -58,      8,    176,    -42,   -212,    176,
+      -533,    -62,    -27,    167,    291,     59,    311,  -3050,
+       552,   -493,   -207,   2576,   -991,   -375,   -102,   -980,
+      1130,   -565,   -199,    559,  -1390,   -428,   -618,     70,
+      -437,   -245,  -1132,  -1302,   -453,     83,    222,  -1555,
+      -178,  -1396,  -1176,   -228,    730,  -3121,  -1085,     84,
+      -326,     71,   -185,   -315,    889,    803,  -2910,  -3609,
+      -639,   -199,    187,    137,   -622,    473,    121,    181,
+        85,    395,    523,    589,     71,    703,    123,    361,
+        47,   -675,    299,   -446,    307,    591,   3341,     64,
+       526,  -1541,    -50,  -1369,    701,   -144,   1720,   -713,
+       562,    297,    146,    -34,   1315,    956,    761,   -415,
+     -1311,    637,  -1263,  -1096,   -385,   3228,   -395,    317,
+      -354,   -503,    255,   -526,    245,    598,    853,   -269,
+      -110,   1354,    333,    110,    855,  -3346,    635,    636,
+      -917,   -577,    260,    147,   1041,   1273,    385,   -862,
+      1751,  -1099,     80,   -148,    120,   -118,   5565,   -484,
+       -74,    326,    291,    234,    -41,    212,    192,    207,
+      -108,    198,    118,   -389,    178,   -151,   -252,    -69,
+      -243,   -800,   2640,   -531,     84,   -301,    157,  -3428,
+         3,   -418,   -173,   -166,   -722,    207,    448,   -387,
+      -504,    202,    453,    210,   -203,    304,    190,   -264,
+       101,    -23,     36,     74,   -146,     26,     29,    -33,
+        59,   -127,     22,    213,   -167,    103,   8192,    183,
+      2709,   -125,    324,   -964,   -259,   -400,    -41,   -430,
+       367,    127,    266,    369,   1081,   -190,   -220,  -1083,
+       641,  -2733,    750,    525,   -623,    -18,   3159,    686,
+      -278,  -2083,   1680,    587,    123,     -6,   -266,    376,
+       522,   -433,   -499,    169,    106,   2041,    174,    571,
+      -108,    129,   -116,    -87,   -252,     89,    -14,     14,
+       120,  -7874,   -204,     15,     19,   -110,    -82,    -54,
+        66,     31,    210,     55,    339,     61,   -219,  -3205,
+      1292,     80,    344,   -733,   3172,    -21,    -55,    712,
+      -192,     38,    408,    489,    388,   -343,   -763,    438,
+     -1812,     -6,   -129,  -1392,   -382,    -28,    105,   -284,
+      -168,   -462,   -284,     22,    113,   1203,   3253,   -589,
+      -619,    348,    113,    847,      3,   -557,    460,   -636,
+      -601,   -742,     46,   -111,     51,    -66,  -2867,    551,
+       455,    898,     17,   2205,   1004,    -46,  -1475,   -367,
+      2849,    766,    -32,   -119,    624,   -722,   3371,    172,
+      -330,     93,   -221,    457,   -453,     84,   -281,   -360,
+       108,    487,   -301,    166,  -2611,    577,    192,     34,
+      1105,    705,     34,     29,  -3041,   -898,    172,    578,
+       307,    483,   -439,   -327,    360,   -935,    -76,    387,
+     -2485,    800,    333,    601,   -712,   -973,    -65,   -442,
+       220,   3577,   -428,   -210,    565,    757,   -382,    289,
+       726,    -19,   -182,    384,    -32,     38,   -810,   -181,
+     -2978,    259,   -213,   -473,   -187,   -823,   -279,   1518,
+        26,   -385,   1143,   -409,   1310,    676,  -2472,     64,
+      -391,   -102,    455,  -5751,    278,     30,     64,   -177,
+      -113,   -170,     94,   -234,   -167,    101,     -2,   -149,
+      -131,    351,   -254,   -138,    149,    -42,    631,    -21,
+       237,   2893,   -291,   2917,  -1240,    211,   -215,     22,
+      -827,   -160,    140,   -213,    156,   -250,  -1233,    691,
+       498,    -30,    350,    -28,    -12,    217,     34,   -348,
+       -70,   -140,    103,    -60,    353,   -200,   -314,    -74,
+       112,   4435,    -80,   -287,    413,    -99,   1407,   1519,
+     -2230,    114,   3179,   -523,     39,    340,   -379,    373,
+     -1552,   -138,   -446,   -106,   -762,  -1017,   -297,   -183,
+       498,   -481,    374,    271,  -5609,    297,     98,   -378,
+       187,    -78,   -125,    333,    114,    -81,     62,   -145,
+        14,    362,    518,    134,    195,    130,    -34,    -72,
+     -3088,  -2965,   -114,    585,    -78,      6,    552,   -633,
+       -98,   -224,    980,    338,    -83,  -1064,     42,    106,
+      -119,    644,   -293,    496,     67,    128,   -129,    620,
+        20,    526,   -177,     68,    351,  -3703,   1465,    905,
+      -245,     86,    511,     39,   -512,   -150,    239,     86,
+        60,     39,    -79,     -9,    -65,     77,  -7993,     57,
+       -19,     56,    -38,    161,   -221,   -129,      8,     93,
+        52,  -5622,   -114,    133,     26,     64,   -194,   -316,
+      -143,    225,    -66,    -81,    -74,    240,    130,    137,
+      -549,     11,    352,    -53,  -4029,    513,   3164,   -205,
+       127,     80,   -193,   -197,    -36,   -885,    223,   -858,
+         5,   -458,    290,    459,    247,   -284,   -176,   -748,
+       173,    191,    114,    406,    126,      3,     91,     84,
+      8027,    379,    -56,     47,     35,    246,   -143,     65,
+       -36,      8,     59,     67,    -69,   -421,  -3492,    312,
+      -252,    261,   3367,    319,    -67,     77,   -346,    386,
+        34,    237,     18,    111,    348,   -547,    186,    -93,
+     -3558,   -178,  -3801,   -133,    -27,   -561,   -308,    112,
+      -224,    272,   -195,   -270,   -179,   -165,    199,   -524,
+       681,   -117,   -429,     37,  -5891,     94,    -55,   -433,
+      -354,    122,    -60,     67,   -200,    -80,    267,   -136,
+       -42,    130,   -324,    -25,    156,    167,    -47,    178,
+         8,    289,    157,     88,    -28,    -39,   -262,    -11,
+         9,   -113,     76,   8192,     89,    115,   -298,    137,
+        34,      0,    261,    -30,     49,    274,    130,    824,
+      -944,    -56,   1074,   -314,    -76,    527,     75,  -3321,
+       733,   -798,   -352,  -1038,   1049,     72,   -233,    312,
+      3363,     69,    104,   -149,     22,    283,    -20,   -101,
+     -3350,    164,   -328,   -362,   -993,    430,     78,    125,
+       269,    -29,    362,    -73,    -30,  -1189,   1396,     59,
+     -1285,   -216,   -121,   3893,     84,   -464,    -38,   -113,
+      -369,   -181,   -930,  -1012,    394,    120,    274,   -552,
+      -800,    105,   -141,    -12,    241,   -667,    543,   -416,
+        28,   -182,     51,    905,  -3964,  -1213,     12,   -271,
+       378,   -234,    838,   -113,     56,    567,     35,     48,
+       490,   -180,   1097,    170,   2596,    -28,   3098,   -220,
+       424,    885,    -42,    783,    -30,    907,     63,     46,
+      -131,     28,    -55,     54,    -46,    -25,     30,     58,
+       -15,   -200,     -6,     11,    -70,     66,  -8089,     86,
+      -136,     96,    -56,   -101,    300,   -661,    -41,   -201,
+       760,   -252,    955,    189,   1459,   3562,   -457,     35,
+       -54,   -164,   -329,  -1245,   -830,   -365,   -399,    -23,
+       616,   -238,  -1301,   -198,    335,  -3400,    149,    175,
+       -97,   -279,   -594,    -92,   -915,   -830,    468,    628,
+       728,   1024,   -549,   1073,    222,   -142,    296,    -75,
+      -168,     -5,    -67,  -7311,    -50,   -256,   -321,    121,
+       358,   -272,     30,    258,    105,   -161,   -291,    462,
+        -7,   -211,   -227,   -104,   -151,   -152,    -72,    -98,
+       -59,    -23,    -98,   -203,    103,     89,    239,   -484,
+      7749,    110,     35,    345,    282,   -578,    140,    -51,
+       -62,   -238,    102,    454,     64,   -107,   -223,   -174,
+       285,    110,   -190,    -16,   1624,    142,   3813,   -849,
+        43,    234,     84,      0,   -132,    131,   -135,    -70,
+        -1,    125,    -83,    171,    109,   8044,     97,    -38,
+       143,     64,     13,      4,   -225,    181,    712,    626,
+        20,    167,   -467,    186,   3801,  -2179,   -647,   -119,
+      -112,   -183,   -223,    295,   -438,   -407,    -29,     36,
+       -34,   2536,    -47,   -402,    -33,    -62,   -136,   2444,
+      -152,   -717,   -868,     86,  -2323,    931,    659,  -1281,
+       -98,    638,   -162,    195,     -5,    -40,    -88,   3019,
+      3466,   -323,    316,   -784,   -715,      5,    188,     42,
+       155,   -608,    500,    185,    475,    100,    -51,    879,
+      -891,   -158,     18,   -453,    380,   -207,   -143,    401,
+      -153,    926,   -184,   2775,   3176,   -797,   -198,   -888,
+       405,    460,    309,    304,   -114,   2386,   2319,    658,
+     -2200,    216,    435,  -1210,   -655,    154,     81,    538,
+       908,    220,   -118,    482,   -864,   -526,   -241,    857,
+      -473,    774,   -288,   -886,     46,    250,    -96,    301,
+       120,   -488,   -128,   -233,    422,     38,  -3416,   -974,
+      -243,   -226,    381,   2394,    652,   3124,   -205,  -1303,
+      1484,   -159,   -152,  -1037,   -105,   -121,   -466,    -76,
+       605,    181,    -55,   -326,   -527,   -126,   1691,   1316,
+};
+
+static const int16_t cb1110sl1[] = {
+      -743,   -300,   -347,   -441,     85,   5282,   -250,     32,
+        28,   -306,   -434,     78,   -178,   -112,    -28,   -162,
+      -188,    -43,     17,     94,   -242,   -258,  -2691,   -471,
+      -556,   -815,    120,    -57,    -36,   -325,   3282,   -765,
+       355,      2,   -162,   -454,    -72,    192,     86,    219,
+      -123,    237,    135,    -42,    492,   -471,   -114,   5146,
+      -164,     28,     77,     70,    276,   -148,    333,     64,
+       -89,    -46,   -135,    474,   -218,   -119,    351,   7619,
+        93,    -80,    -84,    -51,   -110,   -223,    -13,   -116,
+      -160,   -102,    -64,   -140,   -376,    156,   -143,   -421,
+       105,    102,    519,   1256,    786,   -284,  -3029,  -3021,
+      -365,   -515,  -1358,   -273,    394,    489,   -242,     31,
+       239,  -1328,    169,   -488,  -3069,   -398,    303,   -274,
+       498,  -2758,   -748,   -208,   -324,   -285,     78,   -386,
+     -1063,    298,      5,    693,    160,   -629,   1656,    186,
+       457,    742,    422,  -3723,   1997,   1025,    -24,    291,
+      -588,     16,   -327,    459,   -521,    421,   1279,   -408,
+        -2,  -1320,    101,   -372,    -66,    100,   -605,   3214,
+      -374,   -660,   -371,    207,    175,   -553,   -574,   2962,
+       119,   -551,   -140,    -62,     50,   -608,   -237,   -100,
+       108,    101,   3258,    -31,    -45,    375,   -161,    132,
+      2842,   1458,    235,    800,   -113,    719,   -291,    -29,
+      -512,   -267,     53,    780,    -59,   3387,   -175,     88,
+       -78,   -475,   -536,    584,  -3025,    -19,   -105,     91,
+       875,    -55,   -771,    143,    384,    810,   -372,   -253,
+       160,   -128,    232,     98,   7755,    181,    -19,   -177,
+        46,    -39,    -30,   -212,   -289,     75,    127,   -114,
+        80,     79,    325,   -128,   -436,   2547,    -73,    -29,
+      1046,    344,   3340,   -335,    458,    637,   -175,   -695,
+      -366,    294,   -322,    564,    542,    209,    524,    -62,
+       444,   2827,    -53,     66,   -959,     84,    484,   -147,
+       158,    259,   -479,   3216,    232,    -68,    583,   -810,
+       107,     93,    629,   -168,    143,   -552,     96,    -71,
+     -3903,   -438,    335,   -133,   -186,   -278,     73,   -575,
+      -253,   -733,    -91,     -8,  -1149,    350,    140,     12,
+      3935,   -236,    103,    469,    610,   -536,   -305,   3112,
+        13,   -182,   -686,    637,    525,    327,    102,    -49,
+      -450,    -16,   -480,    233,    -82,   -132,  -3979,    426,
+       757,     54,    152,   -701,    513,   2330,    148,    242,
+      1709,    162,   -168,    146,      0,    891,   -644,    109,
+      -549,    104,    -50,    275,   -193,    -55,   -144,   -117,
+        31,   -234,     68,  -5369,     72,     54,     54,    119,
+      -140,    192,    286,    -42,   -278,  -3524,  -3609,    692,
+      -366,    -15,    343,   -885,   -267,    294,   -387,   -215,
+       -83,   -469,    790,     85,    428,   -613,    114,    634,
+       279,   -570,    616,   -813,   -117,   3073,   3121,   -717,
+      -200,    285,  -1061,    -44,    945,    386,   -166,    494,
+       776,     36,    -25,   -444,   -260,    407,   3885,   1049,
+      1348,    185,    454,   -136,  -2275,   1064,   -271,   -316,
+       645,  -1050,    483,    430,     32,    569,   -676,   -335,
+      -328,  -2982,   -370,     50,    189,    155,   1058,   -119,
+      -407,   -310,    461,   3293,   -604,    195,     48,     68,
+       196,    194,    547,   -210,    785,   -383,   -410,   -268,
+      -149,    192,    -88,    -13,     20,    -80,  -5146,    -86,
+      -111,     40,    -36,   -138,     12,    239,    -36,    -84,
+      -512,    149,   -237,   -672,   3477,  -3446,   1198,    220,
+       146,   -747,    242,     48,   -146,   -196,   -335,   -777,
+      -405,    620,   -340,   -367,   -389,   -108,    -27,   -184,
+     -2024,    518,    241,   -104,    417,  -1356,  -1961,    134,
+      3221,   -423,    286,    -60,   -110,   -568,     14,     76,
+      -144,    159,    704,   -410,    542,    -43,    223,    105,
+      -154,   -141,    -84,   -132,   -271,   -235,   -285,   -248,
+       480,    430,  -4711,   -487,    -86,    482,     80,     46,
+      -239,    -93,   -115,    -54,     -1,      7,     97,    -12,
+       151,   -180,    159,    -63,     65,   -215,     54,   5712,
+      2886,   -115,   -236,    113,    -25,   -301,   -450,   -276,
+       -78,    197,    -55,   -278,   -511,    163,   3442,   -910,
+       -74,   -225,   -103,     63,   -204,    -43,   -126,   -334,
+       223,    192,   -131,    202,    -83,   5000,    -66,    441,
+        33,      0,   -116,    237,   -238,    -37,    445,    -48,
+         7,  -1855,  -1154,   -251,   -117,   -185,    125,   1877,
+       375,    388,   -904,    202,    649,    376,  -3231,    897,
+       101,   -637,    376,     16,      1,    845,   -550,   -610,
+      -380,  -1363,   -955,     71,   1303,    296,   -264,   -584,
+       247,   3247,     98,   1035,   -670,    416,  -2008,   -448,
+       -56,   -169,  -1787,   3314,    408,   2541,   -833,     -2,
+      -169,   -184,    193,   -575,    -81,    410,   -293,   -478,
+        21,    194,    223,   -111,   4648,     60,    354,   -593,
+     -2429,   -671,    150,   -350,    151,   -448,     -5,    386,
+      -441,    131,   -339,     87,    815,    279,     51,    131,
+        56,  -3194,   -170,  -3899,   -297,    270,     21,   -215,
+         7,    205,   -305,    141,    577,     83,   -289,   -502,
+       -66,    -96,    433,   -106,   -685,   -194,    -82,     33,
+        98,    315,    258,  -2453,  -2957,    608,    672,    152,
+      -681,   1804,    -74,   -459,   -423,    114,  -1183,   -100,
+      -798,    357,    -79,  -3418,   -676,    580,  -1637,   -506,
+       306,    437,   1001,    731,   -885,  -1276,   -583,   -359,
+       650,     15,   -189,    190,     86,     39,  -7987,   -133,
+       324,    174,     22,     86,   -144,   -125,    -43,    -81,
+       -49,     68,     39,   -204,   -159,   -291,   -217,    -68,
+       264,    193,    406,    247,     27,   -272,   -168,    536,
+     -5740,   -141,     38,     18,     -7,    258,   -111,    125,
+       476,   -364,      5,     72,  -2668,   -197,   -605,   -671,
+       -82,    201,   -752,    227,    240,    345,    -11,   -138,
+       551,   -351,   -228,  -2774,   -132,   1115,  -1038,    -18,
+       791,  -3136,     81,    219,    357,    755,    579,     26,
+     -3129,   -398,   -719,    193,    495,    290,  -1123,    854,
+      -381,   -535,     33,    232,   2340,  -4577,    -94,   1023,
+      -117,     39,    -54,     15,   -161,   -860,     64,   -209,
+      -597,    415,   -135,   -407,   1068,    894,   -784,    108,
+       267,   7506,    140,     67,    198,     74,     52,   -388,
+      -184,    -24,    -54,    -24,    172,    172,    -50,   -184,
+      -113,    164,    128,    -39,    252,     90,    356,   -313,
+       -90,   -313,   -355,    -73,     19,    139,    141,   -122,
+      -231,  -4548,   -157,   -227,     47,    231,   -421,     60,
+       -80,  -3619,   4252,   -354,     69,    148,    336,    446,
+      -183,     86,    248,     35,     73,    120,    157,    156,
+      -291,   -523,     35,   -264,   3434,    189,    495,    -59,
+       533,   -343,   -554,  -3014,   -415,     17,    436,    552,
+      -240,   -394,   -761,     43,   -766,     46,  -1119,   -254,
+      1540,    195,   -298,   -833,     45,    -93,     61,     40,
+      -171,    167,     82,    107,     16,     40,   -166,    -46,
+       120,   -185,     13,    151,   8151,   -235,     92,    -23,
+       214,    206,    260,     93,    163,     78,    184,    -60,
+       -12,   -171,   -499,   -151,   -219,     11,   -221,    221,
+      3253,   -376,  -1079,   -481,    763,   -257,   -120,    -10,
+        34,   -640,    341,  -2953,    528,    567,   -672,   -335,
+      -175,    -61,    581,   -260,   1159,   -802,   1070,     12,
+       168,   2305,    291,    203,    -15,   -569,   3247,   -179,
+       620,    339,    224,    710,   -416,    512,    -86,    571,
+       439,   -167,    571,    -72,   -144,    236,   -382,     11,
+       268,   -176,   -136,   -337,    220,     64,    341,    361,
+     -4474,     25,    385,    453,   -153,     89,   -572,    245,
+      -197,     33,     75,    588,     51,   -199,    -74,   -149,
+       224,    210,   4689,    282,     20,    -47,    129,    221,
+       -72,     27,     76,     93,    331,    215,     -5,    -20,
+        74,    -80,    169,    126,    -40,   -137,    -24,  -8101,
+       -23,    165,    271,    403,    -34,    -19,    290,   -199,
+       -14,    205,    657,    301,   -885,   2457,  -1965,  -2266,
+     -1004,   -224,   -554,    182,   -220,   -467,   -611,   1012,
+      -122,   3303,    -73,   -205,     93,   3549,    217,   -223,
+        55,   -459,    541,    286,    -46,    128,    354,    137,
+       824,   -313,     32,    301,    139,   -492,    170,    136,
+       -35,   -752,   4613,   -830,    -34,     41,    344,    279,
+       643,   -394,   -461,    163,   -330,    199,   -215,     83,
+      1096,    613,   -473,    816,   3534,    210,   -772,    935,
+      -275,   -600,   -341,    602,    104,   -598,   -217,   -789,
+     -2428,    870,   -351,    474,     50,    321,   -148,  -2929,
+        25,   -135,    -46,     11,   -566,  -3057,   -664,    700,
+      -300,    256,   -960,    350,   -480,    414,    431,     24,
+       -51,   -228,    407,    142,   -321,    316,   -290,    149,
+        56,    -84,   -359,   -118,  -4948,    138,    373,    -49,
+       142,     71,   -163,    -13,   -279,     38,   -121,     35,
+       -47,    -70,    -43,    116,      3,   -159,    -11,     97,
+      -116,    -62,    156,    307,   -173,   7294,   -143,    288,
+       -34,    671,    613,     16,   -240,   -229,   -414,   -494,
+       -43,   -169,   -854,    336,   -991,    719,   -353,   -163,
+      -750,   2685,   2837,   -558,    129,   2076,    -47,    641,
+       -37,    -93,    226,    -69,    598,   -284,    127,    106,
+      -426,   -555,   -947,    485,     54,  -3175,    622,   -341,
+      -544,    278,   -205,   -689,    391,    238,      9,    152,
+      -233,   -392,     28,     36,   -394,  -1059,    132,   3761,
+      -480,     87,   -656,   1304,    478,   -272,     65,   -147,
+        91,    520,   -896,    166,     62,    -30,    -28,    194,
+       542,      3,    625,   1795,   3613,   1097,   1030,    906,
+       400,    133,   -127,    219,    958,     93,   -546,   -702,
+      2937,   -524,   -270,   -767,   -192,    725,   -897,   -643,
+      2502,    141,  -1147,    257,    279,    470,  -3001,   -104,
+        79,    508,    450,    265,    -21,    -74,   -437,    647,
+     -2755,   -407,   -816,    620,     24,    537,   -668,    604,
+};
+
+static const int16_t cb1110ss0[] = {
+     -8187,     90,   -694,   -168,   -452,     -4,   -259,   -332,
+       352,   -554,     43,    389,    236,    508,   -175,    461,
+      -277,    118,    651,   -245,    696,  -1423,    368,  -1417,
+      1782,   1650,   -540,     27,   -461,    516,   -599,   -185,
+       422,    -11,   -181,     19,   1809,  -3226,   -839,   -191,
+       468,    180,   -550,    198,   2487,   -923,  -1335,  -1008,
+      1029,   1716,    588,    371,    902,  -1214,    179,   1026,
+      1560,   1815,  -1714,   1230,   -712,   1675,   1867,   -154,
+     -2860,   -484,   2289,  -1018,     33,  -1494,    614,  -2340,
+      -724,  -1088,  -1930,   -775,   -876,    642,  -1358,   -144,
+     -2518,     62,    543,  -1049,  -1081,    672,   1305,  -1506,
+       -86,   2920,    518,  -1836,   -546,   -132,    -45,   -642,
+       381,   -404,  -2206,  -1211,    698,   -703,   -667,   -606,
+      -677,  -2246,    526,  -1157,    177,    510,  -1420,   -617,
+     -1819,   1710,   1631,   1049,  -1697,   -495,    961,  -1250,
+        39,    482,    445,   -956,    -71,    977,    426,   1826,
+       286,     36,    295,   1786,    794,  -3456,   1645,   -766,
+     -1580,  -2435,   1108,   -286,    731,   -659,    960,  -1759,
+      -978,    316,   -350,     91,    -35,   -222,  -1417,    -53,
+      -529,   -679,    681,  -4700,   -524,    -39,   -350,    196,
+       199,    191,    653,   1344,   -942,   -428,    156,    173,
+       636,  -1538,   1795,   1709,   -190,   1265,    164,    650,
+      2302,  -1757,   1762,    413,   -851,     44,  -1371,    343,
+     -3845,   -122,   1864,   -489,    601,   -748,   -402,    590,
+      -124,  -1988,  -1536,   -999,    399,   -753,    295,   -384,
+     -1316,     55,   -669,    262,  -1157,  -3766,    992,   -111,
+     -2928,  -1424,    -98,    -62,   -334,  -1848,    377,   1560,
+       947,   1568,   1554,    206,    664,   2014,   2098,   -164,
+      -640,  -2897,   -647,  -1675,  -2307,   -254,   -555,  -2426,
+      1497,    465,  -1525,  -1148,     55,    632,    554,   2068,
+       451,  -1532,   -715,  -2065,  -1177,   -623,    478,    -88,
+     -1140,    -72,   -450,   -248,  -1111,   -250,   1356,   2717,
+     -1841,    420,  -1299,  -1715,    746,   -101,    600,   1130,
+      -903,   -473,   1225,   -876,    193,    694,   -193,   -482,
+     -1838,     94,    157,   1131,    267,   -242,   2021,    -39,
+       795,   -285,    438,  -4322,   1097,   -621,   -518,   -338,
+      -289,   -114,   -671,   1700,   -477,    449,  -1664,   -693,
+      1403,  -3629,   1480,   -991,   -234,   -213,    354,   -269,
+     -1140,    -40,   1455,   -758,   1273,    497,   -686,   -945,
+        59,    -66,   -769,  -2930,   2343,   2452,  -1576,    995,
+      -734,   1009,     98,   -350,  -1116,    545,    189,     99,
+       566,   -916,     20,    117,   -807,    986,   -428,    177,
+      1247,    485,   -680,   1139,  -1263,   -256,   4828,     89,
+        27,  -1339,  -1091,    149,   -641,   -703,   -570,   -112,
+       346,    -93,   -641,    -97,   -991,  -2247,   2284,    847,
+      2110,  -1393,   -315,  -1468,    514,  -1493,    -46,   1135,
+     -1231,     39,   -913,   -278,   -762,   1775,   -684,    735,
+     -1676,    386,  -2030,   2534,  -2371,  -1661,   1204,   -111,
+        -8,   -607,   1233,  -1532,  -1263,   1530,   -537,  -1728,
+      -335,    269,   -614,     12,  -1187,   -770,    471,    373,
+      4743,     12,    197,    610,   -101,    417,   -350,    551,
+       544,   -898,    387,   -682,  -1216,    126,     96,     94,
+      -268,    535,    126,   -778,   1595,  -1379,   3366,     49,
+       460,   1772,    198,   -896,     75,    253,  -1376,     68,
+       838,  -1121,   -578,   -630,   -718,   -975,   -565,   1303,
+       354,   -769,    -38,   -246,   -193,   -408,     41,    165,
+       374,    -87,   -155,     -8,   -746,   -430,   -869,  -1842,
+      -385,    281,   5119,    432,   1119,   -807,   1756,    816,
+       131,   -548,   -528,   1347,    478,   1482,   2942,   -290,
+       650,   1012,    163,    840,   -804,     94,   2507,   1514,
+      -953,   -289,     23,   1128,   -895,  -1009,   1871,   -370,
+       699,    659,  -3069,   -695,  -1559,   1435,    672,     94,
+      1496,   -637,  -2208,   1083,    688,    485,    251,   -828,
+      1313,    -21,  -1948,    230,   -603,    783,   -829,    524,
+     -1142,  -3845,  -1383,    323,   1295,    732,    759,    591,
+        68,  -1869,   -756,   1727,    339,  -1565,   -510,   2623,
+       358,   3071,    281,   -790,   1129,    243,   -588,   -431,
+       492,    372,     96,    890,   -935,   -727,   -236,   -416,
+       171,    226,  -1090,   1257,  -1063,   -303,   -817,  -1506,
+      -947,   2282,   -659,   -406,     79,    772,   -816,  -2610,
+     -1802,  -1019,   -816,  -1886,  -1306,   1365,    624,  -2314,
+       -57,   1012,    215,   -130,   3404,   -864,    959,    202,
+       -26,  -1015,  -1212,    -34,   -408,   3494,   -284,    845,
+       275,  -1005,    458,    840,  -2258,    -13,   -129,   2536,
+      1269,   1216,   2071,   -243,    624,    584,   2192,    720,
+       604,  -1397,    766,    984,  -1050,    157,   -246,    438,
+       240,   -587,   1251,   -649,    -22,     33,   5818,    608,
+      -996,    474,   -523,   -454,   1252,   -791,    631,   -465,
+       663,    452,   1793,    853,     39,   3732,    758,  -1329,
+        11,   2217,   -136,   -540,   1335,     65,  -2047,    943,
+       701,   1886,   2085,   -890,    -16,   -184,    325,  -1077,
+      -271,  -1246,    391,  -1686,   -651,    -77,    319,    292,
+      -160,   1204,   1093,    776,   -310,   1512,  -1196,    149,
+        46,    593,   1738,   -566,     97,  -3667,   -485,   -683,
+      -121,   -216,   -149,   -344,    406,   -989,   -311,    383,
+       979,   -828,    394,    -22,  -5143,  -1368,    -18,   -433,
+       359,    607,    996,  -1144,   -229,   1365,  -1243,    413,
+      -591,   -621,    803,   1356,   -625,   1149,   -234,    182,
+     -1285,  -2487,    359,   2640,  -1426,    -66,   -688,    237,
+      1307,   -361,    108,    207,   1026,   -500,  -1156,  -1043,
+     -2192,  -2232,   1790,   1135,   1742,   1494,  -1156,   -698,
+      2520,  -2596,   -620,    431,    748,     88,    912,    832,
+      1122,   -483,   1837,   1821,   -826,   1112,   -424,   -306,
+      -750,   1085,    260,    152,   -114,  -1065,  -4518,   -300,
+      -976,    143,   1452,   1395,   1677,     59,    -51,  -1072,
+       868,   -171,    -26,   -914,   -109,  -2420,    -48,     69,
+      -230,    630,   -522,   2274,   1265,  -1612,   2570,    836,
+     -2042,  -1922,   2970,    775,   -320,  -2486,  -2935,    553,
+       178,    994,  -1054,  -1321,    699,    749,   1002,    513,
+       586,   1550,     35,    654,   -995,   1743,  -1049,   -405,
+     -3431,   1943,    700,    555,    111,    -67,   1007,    111,
+       -57,    661,    404,   -628,    425,   2185,    860,   -516,
+      -523,    452,    238,  -1778,   -378,   -721,  -2197,    218,
+       864,  -1031,   -832,    135,  -2543,   -447,    789,   1117,
+     -1491,    120,   1294,   -702,    627,   -412,   -902,    404,
+     -1843,   -786,   -597,    900,   1963,     22,   -843,   1168,
+     -1045,   -797,    764,   -423,    329,   2308,  -1950,    331,
+     -1090,  -2466,   -483,   2023,  -3363,   2126,    495,   2812,
+      1922,  -1488,  -1041,   -798,    135,    408,     33,    563,
+      1333,    -36,  -2181,   -787,    709,    287,   -971,     93,
+      -459,   -975,   2412,    280,   2555,     32,   2217,  -1825,
+       650,    313,    585,   -947,   1170,     45,   1108,   -435,
+      1092,    220,   -155,    512,    460,    211,   -231,   -627,
+      -836,  -2205,   -181,   -113,    130,    226,   -321,   -765,
+     -1327,  -1190,   -676,   -357,    691,    232,   -365,  -1818,
+     -3007,   2210,    997,    601,   2156,   -782,   1626,  -1081,
+       -49,   -616,    685,    -12,     40,   3480,    563,    515,
+       245,     51,    290,   1227,    171,  -1078,    520,   -483,
+       280,  -1517,  -1331,   2132,  -1176,  -1381,  -1546,   1436,
+      -852,   -505,    672,   -807,    623,   -244,   -125,  -1958,
+       516,    798,   1185,    922,    441,    651,   -610,  -1430,
+     -1887,    114,   -869,  -2024,  -1627,  -2276,   2008,  -1224,
+       125,   -609,    371,  -1104,   -506,   -942,   -624,   -478,
+       197,    141,   -242,  -1051,   1532,  -1269,    666,  -1055,
+      1689,    444,   1720,     16,    301,  -2311,   1196,   1108,
+      1298,   -564,  -1197,  -1858,    439,   -198,    324,  -1884,
+      3193,   2281,    201,    587,  -2028,   1969,  -1087,   -352,
+       -87,   -632,    144,    165,     68,   1150,    173,    478,
+      -837,   -470,   -464,   -195,   -205,   2111,     15,    643,
+      -453,   -339,  -1128,  -1368,   1182,    822,    654,  -2331,
+     -1668,   -215,   -678,  -2460,   1169,   -664,    777,   -348,
+      2570,   -767,   -563,    254,    562,   -557,      4,    -97,
+      1990,    373,   -780,   -677,   1996,  -1527,   -365,   -416,
+      -325,    587,    910,  -3780,   -553,    104,   1705,    240,
+      -719,  -1717,   2765,   -582,    -76,    399,  -1152,   2379,
+      3169,  -1153,   -725,    -35,  -1214,    362,   1600,   -724,
+       424,   -722,    472,    872,    694,   -126,  -1649,  -1314,
+     -1814,    -95,   -312,    -34,    780,   -884,    824,   -864,
+       526,   -100,   3820,    -56,   -452,     43,    564,    487,
+       177,    890,  -1423,    894,   -552,   1438,    204,   1015,
+        -4,    327,  -3327,   -433,   -335,   -869,   1312,   -488,
+     -1287,   -169,   2018,    435,     73,    508,   1160,  -1060,
+      -134,  -1304,   -341,    623,    125,    -15,  -1120,    108,
+       -71,  -1487,   -189,  -3640,   1424,   1740,   1116,    579,
+      1603,  -3294,   1241,   -225,   1481,   2775,   1326,   -242,
+      -632,  -1560,    563,    559,    138,    115,   -557,   2004,
+     -1771,    717,  -1052,  -1115,  -1634,    889,   -441,   1954,
+      -164,  -1507,  -1312,   -407,    662,   -867,   -896,    225,
+      2576,   -224,   -107,    237,   -694,    859,    192,  -1033,
+      2255,  -1225,   -891,  -1994,    -90,    339,   -382,   -774,
+      1460,  -1553,    648,   -521,   2370,    160,    714,     54,
+      -906,   1435,  -1752,   -274,   -523,    -36,   1208,   1553,
+      -339,   1000,   -178,    209,  -1001,    916,    495,    310,
+       726,    127,   -391,    107,   -513,  -1052,   -376,    297,
+      -307,    933,   -233,   -253,   1196,   4619,  -1278,    762,
+       -13,   -387,   -973,   2153,     68,    362,   -887,  -1922,
+      -106,    298,  -1127,  -2601,  -2184,   -111,    111,  -1588,
+      1002,   -365,  -2226,   -290,   -599,    610,    551,  -1368,
+     -4344,    618,   -172,    349,   -914,   -530,   -192,    718,
+       348,   -675,   -884,    913,    -94,    215,   -834,    353,
+       753,   -811,    -84,   -905,   -128,   -483,  -1782,  -1255,
+     -2333,  -1110,    477,   -566,    346,   2018,  -1644,   -325,
+      1365,  -1223,    158,  -1786,    566,    203,    742,    281,
+      -555,    573,   -978,   -459,  -1671,    378,   -689,    349,
+       606,  -5961,    562,    -13,   -223,   -419,   -442,   -447,
+       125,  -1052,     53,   2594,  -1377,    209,  -1549,    533,
+      -118,  -2538,   1808,   -364,    -37,   1221,    607,    593,
+       309,   -240,   1574,    254,    434,   -141,   -220,  -2018,
+};
+
+static const int16_t cb1110ss1[] = {
+       631,   3041,   1215,   2376,  -1843,   -103,    750,    144,
+       -87,   -249,    715,   -201,    758,    202,   -197,   -135,
+      -523,   1243,    457,   -717,   -700,   1662,    918,    -48,
+     -1008,    180,    411,    948,   2192,   2607,   -826,   -962,
+     -1130,    -59,  -1047,   -305,   -325,  -1032,   2096,   -287,
+       395,  -1543,   -268,  -1218,  -2045,  -1674,    951,  -1846,
+      -636,    263,   -138,   -287,   -327,  -2208,   -664,    496,
+      2179,   1645,    340,   -601,    473,    670,    950,   2774,
+       364,    613,  -1896,  -1876,  -3177,   -105,    506,   -164,
+       281,    718,   2419,  -1077,    -50,    365,  -1631,   -134,
+      -384,    231,    767,   -285,   1268,    321,  -1408,    217,
+      -409,   -725,   1225,  -2551,  -2622,   -274,    473,   2752,
+       -11,    342,   -495,   1627,     79,    240,      2,  -1021,
+       640,   -508,   -269,    648,   -116,  -1283,   -217,     13,
+     -1674,   2402,   -879,   1791,   2753,   2386,   1195,   -700,
+      -282,   -428,   -671,    -92,   1187,   -672,   1037,  -1913,
+       246,   -816,    -69,  -2284,   -712,   -996,   2498,    902,
+       809,   -149,     66,    775,    -44,   -566,    955,  -1073,
+     -1438,   -894,   -978,    274,   -390,   5528,   1153,     17,
+      -750,     63,    545,   -725,   -301,   -323,    661,   -813,
+      -347,    739,    335,    136,    203,    342,    802,   -199,
+      -818,   -679,   -282,   2195,  -1714,   -757,   -154,    182,
+       132,  -1737,    405,   2394,  -3727,   1349,    213,   -193,
+     -2495,  -1354,   -629,  -1171,   1429,    -16,    834,  -1260,
+       160,  -1892,    874,   1754,   -567,    344,  -3499,   1612,
+      -987,   -424,   -997,  -1640,    594,   1058,   -783,    511,
+      -604,  -1480,  -1754,   -424,   2262,  -1991,   1297,   -638,
+       350,   -588,    -55,   1483,   -456,   -567,    146,   -946,
+       731,   1541,   -759,    592,   1231,   -270,    171,  -1975,
+     -2707,   -456,   -227,    392,   -891,   1008,  -1066,   -487,
+       231,   1372,    -51,   -599,   -227,    696,   -820,    354,
+      1928,    -48,  -1302,   -570,    316,   -283,   -848,   2563,
+      -266,   2821,    540,    553,  -1272,   1120,  -1164,   -451,
+       384,  -1058,  -1018,   1735,    992,  -1220,    -83,   1490,
+      2304,    122,   1630,   1108,   1997,   2346,   -647,    301,
+     -1746,   -218,    313,    462,   1486,   -536,   -508,   -463,
+       104,    930,    605,   2116,    793,   2881,   -724,  -1379,
+       -53,   4458,    793,    275,   -180,   -516,   -489,   -774,
+      -265,    704,    112,    175,    112,   -121,    652,    310,
+       564,   -440,    773,   1885,    927,   -672,   -773,   1726,
+      -614,    818,   1589,   -372,   -207,    499,   -894,    987,
+       796,    652,  -1228,  -4010,  -2208,    458,    645,    498,
+      -279,   -852,  -1897,  -1820,    -35,    674,    201,    474,
+        77,     94,   2327,    723,  -1081,    261,    209,   1179,
+     -1175,    623,  -1293,   2154,   -117,  -3707,    940,    813,
+     -1059,   -335,   1306,    525,   -191,  -2066,   -425,     19,
+      -366,    529,   -145,    822,   -913,    254,    424,   -354,
+      -167,  -2437,  -1433,    603,   -318,  -1517,   4250,    541,
+     -1360,    450,   -531,    200,    534,   1200,   -222,   -535,
+      -162,  -1211,   -116,   -144,   -462,   -139,   -482,    511,
+      2068,  -2100,    971,  -1487,  -1050,  -3150,   -701,    119,
+        16,   1535,    272,  -1184,   2242,    488,   -492,   -915,
+      1660,    212,   -826,   -444,   1003,   2705,   3591,   -174,
+      -333,   -431,    -59,   -903,     61,    751,   1087,    -45,
+     -1031,    617,    686,    -15,    848,   -348,    947,    396,
+       931,   1785,   -552,   -920,   -669,    -63,  -1869,   2357,
+     -1549,    807,    889,  -1581,  -1071,   1587,  -1108,   1300,
+      -658,   -625,    300,   -285,   -977,   1656,   4183,   1487,
+      -191,    658,   -300,    497,   1378,   -300,   1031,    322,
+       114,   -449,    666,   1250,    264,    125,   -109,    748,
+      -503,    -40,    199,  -1212,  -1643,  -2522,    151,    121,
+     -1128,  -3200,    876,   -446,    878,   -989,   1510,   2261,
+     -1507,   1793,   -402,     30,    228,    -50,    985,  -1568,
+       755,   1559,   -688,   1342,   -423,  -1507,     96,   -501,
+       474,  -2926,  -2493,   -131,   -656,    450,   1035,    812,
+       -14,   -933,    941,   1396,   -957,   -621,   -516,    379,
+      -225,  -2063,  -2048,    669,    287,   1688,   1727,    299,
+      -658,    852,    745,   -260,    993,    158,  -1236,  -1422,
+        33,    611,   -112,   -323,   -194,    839,  -1407,  -1505,
+     -2010,   1267,   -355,   -675,  -3779,    768,   -228,   -643,
+       661,   1313,   -529,    962,   -948,   -212,   1043,   1560,
+      -174,   1744,   -938,    289,   1942,  -2228,  -1932,   1056,
+      -590,   -940,    922,    601,   -853,   -791,   -637,     -2,
+       -52,    -83,   -209,   1422,    856,  -1141,   2500,  -1195,
+       773,   1087,  -1389,    409,    439,  -3674,    453,   1637,
+       -15,   1013,   2635,   1530,  -1104,    440,    895,   -210,
+      1118,     -6,     45,     65,  -1110,  -3307,   -331,    478,
+      -155,   -410,   -721,  -1234,    129,   -971,  -1117,    -27,
+     -1132,  -1289,   1888,  -1112,    203,  -1091,    442,  -2207,
+       501,   -343,    468,    -52,    385,    269,  -3102,   -366,
+      -469,    391,    505,    176,    356,    -69,   -929,   1155,
+      -280,  -1264,   -897,   1006,   -494,    155,     36,   -627,
+       924,   -816,    154,   -750,   -837,   5263,  -1099,     91,
+      -481,     71,   -681,   -574,   1229,    675,   1217,   1073,
+      -695,    274,   -381,   -140,   1372,   -524,   1164,    341,
+      -149,   -856,    793,  -1294,    981,   -961,    371,   1178,
+      1463,    373,   1375,  -4384,    239,    136,     67,  -1196,
+      -126,  -1001,   -228,    150,    437,  -1830,    477,    498,
+      4246,    793,   -661,    260,  -1810,   1405,     76,    902,
+      -844,    908,   1830,     27,   -124,    257,    765,    -98,
+       592,    487,   -132,    202,    675,   -669,   -679,   1309,
+     -4002,   -206,    -66,   -390,   -253,   -190,   -921,    -83,
+      1411,   -417,  -2560,   -646,   1853,   -148,    548,   -370,
+      -723,    959,   -906,  -3058,   -276,    467,  -1280,    970,
+       687,    484,    506,   1143,  -1509,    828,  -2169,   2931,
+      1322,   -579,   1033,    209,   -979,    217,   -434,  -1438,
+       314,   2384,   -906,    -29,  -1478,    -31,    574,   -373,
+      1478,   -124,   -680,    330,    794,   -753,   -977,   1151,
+     -1190,  -1479,   -642,   1658,  -2201,  -1469,   1589,    587,
+        52,   1298,   2092,  -1483,    678,   1988,    918,   -648,
+       328,   2096,  -1090,   2153,  -1416,    295,    537,    261,
+       398,  -1389,   -399,   1105,     10,   -395,   1169,   -431,
+      -423,  -1617,    766,  -1900,  -3205,    131,   -746,   -852,
+      2215,   -317,   -232,   1079,    293,   -727,     50,   -446,
+      -713,   -897,    768,   -896,   -667,   -281,    377,    115,
+      1695,  -4870,    713,   -393,    251,   1268,    477,   -497,
+       294,     18,   -359,    556,    308,   -752,   -863,   -216,
+       151,   -163,    695,    587,    810,   2107,   -107,    921,
+      1203,   -472,   1280,    372,    110,   -581,   -225,   -714,
+       -58,  -2587,  -1980,   -186,   -372,  -1410,  -1504,  -1020,
+      -745,    -88,   2373,   -568,  -2841,  -2041,  -1841,   2065,
+       389,   -430,   1163,   -208,    569,    375,    650,    317,
+      1114,  -1036,   -959,   -896,   1060,   1014,   -599,  -1743,
+      1121,    808,   1556,    326,  -2876,  -1556,  -1283,    384,
+     -1102,    378,   1433,    702,   1454,  -1243,   -725,    224,
+      -610,   -455,   1413,  -1747,  -2516,   -572,  -1455,   -313,
+       231,    780,   1531,  -2475,    -34,    921,  -1650,    269,
+       818,      5,    835,   -209,   -911,   -432,  -1104,    165,
+     -1638,    -46,  -2031,   -445,   1308,   1519,  -1992,   1606,
+       956,    757,   1139,    116,    829,  -1376,    209,   -893,
+       963,   -569,   -466,   -185,  -1345,   1524,   1714,    269,
+       219,   -161,    482,  -1178,  -3621,   -831,   -668,   1871,
+      -529,   -983,    558,   -818,     81,    555,     33,   -473,
+      -187,    113,    899,   -577,  -1093,   1408,    902,   -258,
+      -111,   -648,   4340,   -780,   -651,    789,    -92,   2310,
+      -401,    669,   -213,    369,   -104,   -820,   -290,     48,
+      -917,     71,   1070,   -239,   -744,    891,     23,  -5130,
+      -761,    312,    319,    842,    280,     78,   -149,    352,
+      -594,   -361,    354,   -906,     42,  -1610,    835,    157,
+      -631,   1100,   -297,   1081,    -96,    484,   -825,  -2132,
+       549,   1305,    128,   -314,  -1733,   -265,   1285,  -4061,
+      -348,   -136,   -940,   -507,   -232,  -1511,   -876,     78,
+      2120,    175,   2216,   1179,    497,    335,    350,    -18,
+     -1307,   -387,  -2207,    587,   3209,   -370,   1155,   1501,
+     -1687,   -796,  -1417,   -733,   -269,    801,     83,   1173,
+       718,  -2702,     19,   -315,   4501,   1025,   -365,    348,
+      -417,   -510,   -172,  -1201,   1478,    671,   1933,   1759,
+       676,    416,     30,    400,    531,    351,  -1176,  -2807,
+      1969,  -1398,   1159,   -568,    754,   -149,  -1880,   -274,
+     -1203,    -43,   1391,    383,    702,   2116,   1299,   1952,
+       646,   -719,   1735,   -986,    100,   -956,   1040,   2287,
+     -1606,    612,   1760,    733,  -2453,    531,    -14,     -1,
+     -3214,  -1993,    371,    227,     45,   2011,   -531,   1089,
+     -1029,    282,  -2426,   -525,    989,   -469,    285,   1787,
+       927,   -335,   1127,   -305,   1143,   -412,  -1626,   1759,
+     -2567,    -82,   1170,  -3051,   1266,   1522,   -124,  -1935,
+       552,   1122,    -51,    347,   -674,   -360,   1183,    223,
+      3015,    955,   -826,   1108,   2325,    868,   1152,   1079,
+       223,    217,   -428,    382,    642,  -2849,   -767,    -70,
+       407,    147,   -392,   -407,    -55,   -508,   1785,   -683,
+      -885,    851,   3879,    471,   -674,   -231,   1493,   1621,
+     -1698,    528,    623,    300,   1367,   -588,    816,    -24,
+       600,   -182,   -841,    854,    370,    715,    116,    714,
+     -1308,   1435,   1802,  -2627,   -814,    363,   -318,    -73,
+       850,  -1744,   2509,   -303,   1077,    660,   2145,   2130,
+      -730,    -88,   -115,   -517,   -154,    160,   -337,     27,
+      1502,    509,    -70,    502,    820,   -309,  -3740,  -1294,
+      -610,    241,   -662,   -524,   1319,    456,    926,    958,
+      -111,  -1004,   1795,   -604,   1086,    462,   -127,   -125,
+       264,  -1093,   1427,    334,    838,   1979,   -576,   3052,
+     -3590,   1607,    356,    728,   1619,   -400,    279,    570,
+      -434,    777,  -1448,   -888,    156,   -277,  -1529,   1122,
+      2235,   -794,   3417,   -830,    -82,   -664,  -1837,    946,
+      -370,   1434,    -50,    742,  -2368,   1438,   1264,   1172,
+     -1338,   -108,   -226,   -958,  -2130,     -2,    917,    896,
+      1563,   2181,   2684,   2343,    237,   -407,  -2685,   1447,
+      1028,   -728,    109,   -620,    478,     46,   -542,   -789,
+      -879,   -438,   1244,   1075,  -1730,    119,   -694,    137,
+};
+
+static const int16_t cb1110sm0[] = {
+       916,   -269,    -44,    343,    623,  -2512,   -171,  -1904,
+      1001,   2776,    226,   1487,    705,    763,   -616,    288,
+      -212,   -535,   3080,   -352,   -367,    512,   -673,    620,
+      -874,    769,   -956,    460,   -601,  -2793,   -102,   -765,
+      -431,  -1369,    149,    481,    -49,    109,   -412,    670,
+      -615,    287,    150,    321,  -3293,   -237,  -1627,    188,
+      1867,   1481,    353,   -134,   2706,    147,     74,    -77,
+      -148,   -224,    196,    -60,    179,    125,    -13,   1011,
+      -189,   -172,    658,   4441,   -540,    531,    239,   -329,
+      2782,    392,     97,   -660,   3488,    -78,   1308,   -574,
+      -903,   -170,   -279,    173,    -70,    601,   -385,    123,
+      -423,   -512,   -193,   -233,    106,    175,    210,    185,
+       489,   -236,    153,   -670,     25,     61,   -196,    213,
+        67,    339,   5443,    116,   -647,    149,   -130,    197,
+       -11,    305,   2669,   1212,    298,     84,    219,    -26,
+      2661,    650,   1348,    -65,    574,  -1482,   -268,    -30,
+       626,    328,    279,   -245,     87,     94,   -202,      2,
+       366,   -505,   -592,      2,   5666,    384,     22,    227,
+       208,  -1221,     78,    155,    260,  -1111,    165,    396,
+      -678,   -739,   2503,  -2395,   2025,   1424,   -343,   -759,
+      -837,    101,     55,    274,   -481,     22,   -568,   1044,
+      -271,   -124,   -609,   -833,   -206,     53,   -591,   1150,
+     -1950,  -2875,   1949,     59,   -334,  -3230,    176,   1133,
+      -372,   2937,   -803,   -663,    631,   -659,    -32,    -82,
+       851,    113,    -60,   -625,    556,    177,    112,   -753,
+       -33,    313,    -33,   -208,   -177,  -5496,     55,   -533,
+      -815,    123,   -755,   -215,    638,    223,   -156,   -917,
+      -166,    -33,    504,    704,  -3001,    124,   -153,  -1809,
+      -977,   -717,   1718,    476,    212,   1661,    953,  -1422,
+     -1014,    -94,   -524,  -2562,   -267,    371,    104,    -63,
+      -546,    262,    193,  -1714,    261,   1867,    738,  -1878,
+       400,   1754,   -445,   -405,   -841,   -439,    709,     44,
+       675,    248,    640,   -138,   1217,    393,  -1402,    653,
+      3110,   -938,  -2491,   -688,   1214,   -649,  -1356,   2506,
+       203,    172,    679,   1003,    772,  -3010,     82,   -998,
+      1011,   -980,    -28,   -138,   -430,    614,    427,   -341,
+       201,  -8082,   -118,    224,  -1167,    195,   -920,   -352,
+      -657,      5,     46,    -39,    -72,    698,   -136,    -40,
+       391,    287,    157,  -1197,    -60,   2808,   -123,    489,
+       152,   2318,   -805,    958,     98,  -1496,   -835,   -846,
+       589,    455,   -868,    245,    -10,  -5047,     12,    -50,
+      1277,    -95,    456,    -49,    570,    608,   -658,   -352,
+      -277,   -268,    214,    388,   1865,      2,   3033,   -269,
+       259,    -75,  -3437,    800,   -190,    668,   -263,   -111,
+       229,    -43,   -139,    659,   -290,    782,    -18,   -854,
+       271,  -2223,     30,   -162,     71,     47,    756,  -1269,
+       336,    863,  -1998,    -16,   1172,    236,    929,   -477,
+     -2446,    -92,   -425,   -193,  -8192,    321,   -102,     85,
+       -85,    108,    318,    149,    -27,   -182,     69,   -237,
+        35,    451,   -263,   -890,   -348,   -295,     64,    410,
+      6427,    569,    604,    543,     38,     31,    -15,    148,
+       249,    -83,    -67,    457,    -76,   -560,    694,   -797,
+       190,   -113,   2006,    136,   1705,   -428,   3549,   -550,
+        70,     -3,   -147,   -288,   1142,   -919,    493,  -1305,
+      -460,   -151,    831,    623,   -768,   -211,     31,   -296,
+       167,  -2721,    -16,   -654,    243,   2555,   -311,   1845,
+      -531,   -576,    143,   -574,    490,  -1089,  -2302,   1080,
+       701,    472,   2782,    320,  -1455,   -632,   -218,    281,
+     -1492,   -661,  -1379,   -538,   -236,  -1928,   -502,   -565,
+      -480,    525,    -81,     38,    263,      3,    366,    163,
+     -3140,    882,    189,   1123,    382,  -1748,  -1210,    371,
+      -602,    696,   -413,   -207,    358,   -616,   4725,   -473,
+      -784,    249,    621,    764,   -265,  -1004,   -570,    339,
+      -643,   -123,    302,    284,      1,   -159,   -321,    250,
+      -297,    -43,  -3512,  -1064,   -493,    556,  -1184,   -263,
+      1314,   2028,   1074,      9,   2941,   -998,   -271,    966,
+      -754,  -2589,     88,    741,   -307,    134,    152,    -86,
+       311,    904,   -917,   1199,  -5090,    118,    181,   -311,
+      -412,    475,   -647,   -717,   -637,   -221,   -291,   -469,
+        77,    946,  -1196,   -119,   -175,    530,   -465,    383,
+     -1253,    589,    826,    835,  -3578,   -319,    -80,    488,
+      -238,   -497,    360,    839,   1870,    762,  -1669,   -769,
+       429,    778,  -3121,   -325,    -55,   -128,   2606,   -874,
+      1043,   -902,   1746,   -725,    115,    167,    142,    604,
+      -101,   -725,    -11,   -458,    -27,    450,    293,      2,
+      -383,     23,    172,  -6725,    400,   -205,    165,     45,
+       -38,     86,    372,    354,    -68,    390,   2444,    521,
+         4,  -3586,    357,    129,    665,   -328,    524,    113,
+      -446,   -514,   1132,    289,   -560,    239,    167,   -349,
+      -724,    101,  -3165,  -3139,   -163,   -147,    865,   -617,
+         0,   -789,    797,  -1026,    432,    359,   -460,   -105,
+      1119,    486,   -233,   -360,   -175,   -349,    837,    469,
+      -250,   -521,  -4470,   -108,   1009,   -575,    283,     22,
+      -555,   -682,   -234,   -249,    -33,   -106,    521,    515,
+      -283,    -78,    101,   -135,   -648,    506,    181,    392,
+      -517,   5405,    442,   -106,  -8168,     51,   -310,   -813,
+        49,   -314,    586,   -479,    376,    113,    337,   -151,
+       245,    270,     -1,    619,   -312,    -37,   -215,   -482,
+     -3055,  -3261,   -346,   -493,   -357,    306,   -160,    -21,
+       258,    872,   -577,   -141,     18,    -84,    693,    151,
+       218,   -533,    -37,    540,     61,     40,   3150,    157,
+     -2549,   -324,    267,   -456,  -1236,    798,    517,   -224,
+      -196,    587,   -495,     18,    258,   3147,    -15,   -568,
+       957,   -444,    637,   -354,    828,   1182,   -769,   -137,
+     -2130,    408,  -1667,    252,    282,    201,    239,    154,
+       125,  -7882,   -332,    198,    -47,    265,   -289,    358,
+        -4,    103,   -795,    207,     82,    229,    429,    361,
+       263,   -409,   -451,  -1036,  -3419,    899,   -568,  -1480,
+       898,    284,    -53,    179,    975,  -1283,    759,   -150,
+      3244,    408,   2579,   -418,   -117,    226,    583,    210,
+       -62,  -1513,   -148,   -820,   1073,   1290,   -263,   -454,
+       653,    555,    286,    218,   -105,   -135,    231,   -892,
+      -284,   2513,   2715,  -1530,   -165,  -1419,   -223,    -66,
+       525,   1556,    -18,   -664,    -19,    856,    179,    535,
+      -339,   -245,    498,    193,    235,    328,   -491,    231,
+     -5629,     65,    -85,    313,   -395,      6,    344,    267,
+       672,   -991,    178,  -1335,    -64,      9,  -1508,    -69,
+        57,   -310,  -1793,   -850,  -3669,    427,    -79,   -720,
+       219,    366,    131,    523,    141,  -1055,    -66,     13,
+      -843,    -55,   -794,    661,    112,   -407,   -496,    550,
+       931,  -3938,   1780,   -509,   -543,   -157,   -270,  -1015,
+       564,   -231,   -854,  -3372,   -327,    869,   -196,   -981,
+      -205,   -215,    605,    746,  -2188,   2250,     74,  -2979,
+      -242,    832,   -190,    365,  -1327,    453,     95,     76,
+       158,   -683,    628,    297,   -867,   -542,   -143,   -568,
+      -414,   6018,    -40,    -35,   -456,   -632,   -779,   -226,
+      -442,   -295,    310,   -766,    578,   -197,     84,   -961,
+     -3346,   -106,   3266,     -3,   -477,     -8,    652,    122,
+      -606,     49,     34,    686,    385,   -258,    214,   -572,
+       -72,   -193,    124,    440,     48,     45,     75,      9,
+     -7724,    200,   -364,    578,    318,   -461,     84,   -233,
+        46,   -404,    185,    470,  -3387,  -3397,    374,   -519,
+      -320,   -378,     27,    921,   -280,    188,   -245,    -69,
+      -322,    504,    -72,    460,    -80,    -35,   -220,  -3098,
+     -3678,    477,    248,   -801,    580,    187,    468,   -636,
+      -364,   -432,    183,    -82,    -79,    266,   -787,   -740,
+       552,    228,    238,    482,  -2229,    275,    149,   -360,
+      -350,   2774,    871,   -118,     55,   -961,   -165,   2429,
+       982,    313,   -502,   3094,   -431,   3485,    473,   -347,
+       171,    544,    253,   -324,    -50,    464,    116,    650,
+      1102,    495,    420,   -404,     -1,  -2991,   4055,    207,
+       374,   -187,   -121,    130,   -451,   -953,    822,    526,
+       287,    120,   -979,    376,    594,    -79,   -130,   -362,
+      -979,    166,    693,  -4108,     84,   -135,   -195,   -703,
+     -1506,  -1098,   -611,    870,    935,   -156,    974,    286,
+       -86,     83,   2975,   -681,   3218,   -286,   -452,    -70,
+      -113,   -395,    137,  -1295,   -503,    853,    297,   -352,
+     -1004,   -117,    476,   -431,  -2848,     -7,   3601,    402,
+      -534,    312,     86,   1524,   -358,   -164,    -43,    913,
+      1003,    239,   -364,    -88,   -468,   -672,    220,   -211,
+      -326,   -431,    438,   -297,    380,    125,   -146,   4550,
+      -271,   -831,    768,  -1360,    -45,    266,   -278,   -246,
+       625,   -132,    153,    514,    115,  -1311,    707,   -361,
+      -601,  -3224,    376,  -2107,   -259,  -1155,    426,   -646,
+};
+
+static const int16_t cb1110sm1[] = {
+       360,   3106,   -518,    185,   -906,   3245,    508,    -91,
+       938,  -1270,   -492,     36,    168,   -997,   -208,    991,
+        99,   1553,   -294,    204,    -22,   -108,  -2405,   2893,
+        49,     72,   -490,   -529,   -218,   1343,   -786,    903,
+       411,    207,    131,   -636,   -129,   -134,    621,   -253,
+       319,    135,   -234,    -75,   -293,     46,    207,   5985,
+       280,    -86,    -78,    690,    984,   -770,   -565,   -226,
+      -242,    374,     26,   -696,     81,   -277,     -9,    639,
+      -730,    250,   -232,   -488,   -284,    460,   -398,   4336,
+      -303,   -266,    546,   -292,   2936,     70,   2077,    373,
+      -141,    292,   2102,    340,   -312,   -523,   -341,   1017,
+       457,    224,    315,    271,   1080,    152,    192,    568,
+      1014,    155,     85,    329,  -5235,    137,   -503,    141,
+       275,     -7,    752,    282,   -267,    321,   -735,    746,
+       489,    450,    478,    432,   -152,    451,  -1192,   1267,
+      -341,   1136,    100,  -3538,  -1551,   1547,   -551,    294,
+      -473,   -821,    -51,    718,   -655,    -11,   2817,    -26,
+        73,   -459,  -1569,    181,    516,   -151,   2846,   -112,
+       186,    714,   -228,   -210,   -451,    920,    -99,   -132,
+     -2662,    589,   3040,    376,    662,   -834,    782,    542,
+      1485,    538,   3531,    107,     47,     62,    398,    -11,
+       -15,   -733,    471,   -231,    668,   -212,     38,   -536,
+     -1905,   2769,   -149,   1623,  -3418,    237,     55,   -328,
+      -770,    335,   2755,    340,     62,   -466,    267,   -946,
+       427,    266,     80,   1134,     34,    949,    366,   -339,
+      -112,      3,   -105,    442,   5117,    545,    -93,    611,
+      -186,    566,    -39,   -172,    -59,  -1120,    388,    703,
+       619,   -359,   -117,    -68,    569,    148,   -214,   -245,
+       281,    617,  -2337,    -88,   -255,    124,   3292,    443,
+       434,    -17,  -1157,   3090,   -205,   -245,   -983,    250,
+     -1086,    643,   1392,    831,    733,    -59,  -1199,   1747,
+      -415,   1073,    279,    428,   -512,  -3392,      0,     -6,
+       526,    275,    -79,    477,    411,     85,   1485,    795,
+      -209,    495,  -2628,    367,  -1734,    900,    301,    239,
+       -53,  -2068,    403,   1333,  -1304,   -566,  -1420,   -771,
+     -2300,    -15,    842,    342,  -2373,     61,  -1379,    303,
+       733,   -108,   -316,     94,   -477,   -254,   -211,    807,
+       273,   -792,    159,    -66,   -857,   1092,  -1001,    -69,
+     -3770,    999,   2418,    854,    173,   2281,   -681,    485,
+       578,    145,  -1245,    845,   -375,    219,   -259,    374,
+       751,    226,  -1347,   -825,     66,    319,   -173,    191,
+       445,    284,     62,  -8150,    -71,     53,    637,    -96,
+       227,     75,     73,    -88,    654,    -24,   -466,    477,
+       671,   -125,   -942,    104,    248,   -151,   -383,     11,
+       322,    332,   4160,    108,   -301,    463,   -402,    352,
+     -1799,    580,   1443,    396,    287,   -158,   -421,    340,
+      -349,    109,     61,     47,  -2816,   -298,   -947,   -817,
+       673,    189,     36,   4069,   -584,   -335,   2608,     10,
+      -378,   -630,   -801,    228,    946,   -405,  -1186,    473,
+       625,     -2,   -741,    523,   3747,    318,    733,    171,
+       268,  -2554,    402,   -252,   -205,    292,   -351,     64,
+       289,    801,    989,    435,   -100,   -163,  -1215,   -467,
+       661,   -714,    165,   -228,   -637,   1357,   -498,    -52,
+       488,  -3882,    130,  -1053,    796,   1040,    381,   -729,
+       147,    803,    169,     46,   -157,    167,   -209,    126,
+     -1016,     88,  -1018,   -458,   -527,   1259,    621,   3847,
+      -525,   1247,     18,    253,    642,    340,   -705,    838,
+     -2769,   -672,    153,    115,    453,    773,      9,  -2285,
+      -291,      6,   -219,    628,    284,   -330,    568,   -240,
+      -206,   -127,    273,    373,    367,   -494,   8192,   -595,
+      -255,   -158,   -326,    -60,    513,    334,   -667,   -549,
+      -110,      2,    573,   1086,   -610,   -368,    259,  -3611,
+      -455,   1577,   -524,     11,    904,    390,    313,    707,
+      2670,   -223,   2710,    593,    -25,    228,    540,    663,
+       740,  -1108,    298,   1223,   -531,  -1978,    248,   -661,
+      -341,   -910,  -2434,    111,    217,    748,    231,   -305,
+      -419,   1873,   1094,   -936,  -1741,   1133,   1881,   -671,
+        41,    268,  -1826,    466,    135,     37,   -200,   4623,
+     -1212,   -969,    541,   1278,    652,   1061,   -759,   -747,
+      -427,   -107,  -1329,   -583,   -255,    -67,   -311,    -10,
+      -421,  -8192,    322,   -181,   -442,     76,    176,   -742,
+      -175,    147,    385,   -275,    -87,   -704,   -545,   -315,
+      -414,    569,     81,   -387,    628,   2954,   -604,  -1459,
+       -29,   1693,    840,  -1024,    -66,   -317,    266,  -2465,
+      -917,    -14,    151,   -369,    366,  -2388,      1,   -773,
+      1333,    -99,    223,   -694,  -1169,    917,  -2496,  -1290,
+      -286,  -1007,   -508,    734,    451,   -256,    266,   -105,
+      -143,    439,   -120,   -146,   7690,   -183,    188,     68,
+      -385,      7,   -278,    -24,    -66,    292,    137,    143,
+        21,   -495,   -527,   -284,     89,  -1584,    -64,  -3664,
+       286,  -2258,     80,   -932,   -771,   -338,   -830,  -1029,
+       -99,    -32,   -800,    351,    -87,    600,    -93,    133,
+       389,   -690,    269,    201,   -328,   5489,    558,   -702,
+      -487,    210,   3107,  -3628,    -96,   -388,   -169,   -221,
+       339,    403,   -816,    -24,    469,   -112,    560,    844,
+      -441,    698,    169,   -378,   -283,   -924,   2842,   -479,
+      -694,   -117,    -94,    523,    974,   1356,   -638,    590,
+       820,   2164,    247,   -532,    648,   -243,   -599,    -67,
+      5686,    174,     78,   -608,    230,   -172,    369,    342,
+      -113,    111,   -345,   -311,    594,    350,   -260,  -1423,
+      -425,   -407,  -1017,   -298,   -180,   -738,   -891,     66,
+     -3312,  -1157,      1,    811,  -1431,    612,    797,  -1344,
+      -890,   -959,    318,    392,   -190,    735,    196,   -347,
+        61,   -116,    344,    243,   -411,   -446,     62,   -128,
+     -3386,    476,   2695,   -193,    -39,   1960,     -7,    909,
+      -118,  -2275,    -28,   -997,   -210,    374,   -586,    -82,
+       914,    323,    -73,  -2743,    858,    -65,     43,  -2444,
+      -246,    145,     78,   -638,    844,  -2079,    352,   -332,
+       615,   -779,    270,   1799,    680,    500,    686,   1168,
+      -397,  -2233,    -31,   -163,    -18,    602,   -232,   -915,
+      -941,   3708,   -337,   -559,    315,   -401,     42,     26,
+       316,   -100,   -191,     36,    206,    214,  -3336,   -407,
+       494,    749,   -491,   -162,    -55,  -2902,  -1515,   -198,
+      -311,   -359,    439,    359,   -935,    203,   -214,  -2401,
+      -607,  -2843,    818,   -579,  -2066,    388,   -514,   -912,
+       787,    564,    149,   -103,   -757,    389,    173,   -303,
+       154,    814,   1631,   -393,  -2264,   1664,   -802,    904,
+       541,    784,   1063,   1152,  -2510,    297,     84,   -154,
+       160,   -497,    -78,   1503,   -598,   -543,     86,   1683,
+      -330,     46,    -24,   -892,    747,  -3336,   -393,  -2268,
+       107,    710,   1682,   -277,   -278,   -276,   1253,    327,
+      -986,    802,    191,   -732,    286,   -761,   1008,    461,
+      1615,  -1041,   2127,   2456,   3927,   -160,    187,     31,
+      -101,   3258,    202,    -75,    330,    375,   -301,   -275,
+      -782,    949,     12,   -621,   -617,    572,   1007,    414,
+       -91,   -428,   -392,   -985,   -692,  -3422,    199,    845,
+        91,    418,    290,   -983,    721,  -1265,    208,   1200,
+        91,   -758,  -2649,   -451,   -814,   -623,   -458,    272,
+      2777,    809,   1282,    763,   1122,     21,    520,     50,
+     -1018,    428,    385,   6149,   -255,      8,    -12,     21,
+        20,    293,   -315,   -446,   -423,    549,    428,    -56,
+      -497,    101,    653,   -177,  -3975,     56,   -127,   3214,
+       291,   -384,   -721,    478,   -314,   -231,   -469,   -362,
+      -682,    765,   -308,    420,    456,    322,    -54,     -2,
+        10,   -239,   6916,   -461,   -482,   -211,   -286,   -110,
+      -877,   -711,   -470,    159,    260,     59,    252,    -97,
+     -2978,   -646,    -35,    156,   -123,    360,    556,  -3254,
+      -475,   -313,   -268,  -1771,   -538,    203,    967,    283,
+      -653,   -565,    387,  -3097,   -255,     25,    295,    264,
+     -3716,    505,   1024,   -315,   -215,   -222,   -780,    660,
+       431,   -341,   -521,     46,    127,   -244,   -772,  -3741,
+       190,   -335,    -17,   2135,    744,    -35,    627,  -1115,
+       681,   -343,    123,  -1534,    -86,   -542,   -297,    -82,
+     -2772,   3914,    -75,    526,    124,   -523,   -112,    500,
+       863,    371,    190,   1036,    141,  -1011,    373,    796,
+       421,   -682,    403,   2924,   3730,      6,    211,   -691,
+      -167,   -391,   -655,    162,    348,    216,   -227,   -535,
+      -147,    367,   -189,    331,   -191,    159,     49,  -4905,
+      -252,   -290,    609,   -452,   1042,   1027,   -645,   -159,
+      -633,   -542,   -925,   -262,    -91,    192,   1266,     -2,
+      -164,    587,    188,   3434,  -1014,      2,   1373,   1832,
+     -1224,   -965,    831,   -987,   1180,   1389,   -925,     48,
+     -3239,    263,   -329,   -660,   -733,    262,   -988,    598,
+     -2421,    630,    720,   -925,   -455,    208,   1092,   -294,
+};
+
+static const int16_t cb1616l0[] = {
+       -15,  -7707,    115,     30,    -36,    -27,    -22,    -43,
+         2,      5,     31,     -1,     87,      2,     41,     21,
+       270,     16,   3747,   -773,   3027,    224,     92,   -168,
+        -7,    -62,    -79,    -44,     -9,     -4,    -58,    -78,
+      1063,    203,     -2,     76,    289,    -36,     92,    -29,
+       -78,   -148,  -5176,    137,    219,    299,     89,   -233,
+        62,   -129,     33,    123,    -30,    197,   4018,    -37,
+       -38,    139,     41,    153,     71,    -26,     27,     53,
+        72,   3358,    -68,   -122,    293,    -19,   -355,    104,
+        34,   3121,     16,     29,   -344,     37,    174,    -28,
+       -43,   -102,    -59,  -1661,     14,      5,    -62,     -1,
+        14,     15,    -42,      4,    -31,     -2,     13,     23,
+       957,   -419,     20,     31,    -14,     51,     24,    -46,
+         8,    -16,     27,    -75,    -27,    -33,    -28,     18,
+       -67,   -152,    -48,     47,     90,     48,    -74,   -103,
+       -18,   4863,      3,    132,    414,    -86,    -60,    285,
+        16,     32,    -44,      0,     22,   -163,     23,     -3,
+        23,    -61,  13224,     52,   -139,    -13,    171,    215,
+       -51,    -21,    -48,     33,    -10,    -17,    -21,  -7662,
+       -57,    -44,    -51,     35,     35,     34,    105,    178,
+       -77,     77,    147,     67,   -816,   2913,  -3087,    516,
+      -112,   -296,     21,    133,    211,    162,     87,    -25,
+      -535,   -830,    -12,     46,    -59,    -10,     -4,     42,
+         0,    -91,     -9,     47,    -90,    -29,     74,    322,
+      -106,     83,     44,   4693,   -788,    -73,    -85,   -105,
+       -76,  -1031,     34,      6,     78,    -34,    160,    -48,
+      -707,    -12,     -9,     39,     14,     23,     88,  -2286,
+        21,    -25,     42,    130,     39,    251,     16,    -50,
+       397,   -226,  -2570,     88,   -129,   -347,    159,     92,
+         0,    -44,    -49,    235,   -196,    -24,    -36,    113,
+     13387,     45,     22,     54,    -20,     29,     27,    -27,
+        54,     38,    -63,    -12,    -74,     45,     -8,   -115,
+       591,     46,      5,   -234,     57,    124,     86,  -3794,
+       -51,    292,   -160,   -152,     96,   -334,    348,     96,
+      -186,  -3870,  -3715,     54,      0,    -29,    -65,    -68,
+         6,    132,     47,   -155,     62,     26,     66,    -10,
+       -46,  -3093,     66,   3633,    183,   -171,   -132,    -24,
+       154,    157,    129,   -185,     12,    -26,     96,    -12,
+        88,    -34,     42,    -15,     37,  -6625,    -27,     13,
+        41,    -30,     62,    142,    -93,   -168,     84,    -22,
+       139,    -19,     18,  10590,   -111,     36,     13,    -44,
+         4,    -45,     -3,     -3,     28,    -25,     -4,    115,
+       119,    -49,     41,     33,     87,    -85,  12444,     73,
+        71,   -111,     61,    -15,    117,     23,    -24,     -5,
+       131,    -31,     -1,    -22,    -57,    -12,     50,     35,
+     -1555,    -20,     38,     82,    -52,     27,   -128, -14106,
+       808,    190,     89,    595,     63,   -291,    282,    -48,
+        32,   -706,   -433,   -673,   3285,   1311,    830,   3745,
+      -204,  -1185,   -584,    -51,    952,   1005,   -566,   1764,
+       186,   1211,   -495,   -112,   1213,    192,   2320,    -43,
+       -30,     24,  -1152,      2,      2,     32,    -55,    -25,
+        -2,    -17,    -14,     -6,     22,    -54,     32,     45,
+        10,    -85,    -26,    -16,    -66,    -60,   -210,   -104,
+       208,   -248,     62,    -28, -14552,    -11,    -44,   1601,
+        47,   -138,     46,    -35,   2647,    -81,     -3,    -38,
+       -66,    -59,    -33,    -19,     43,    -17,    -79,     53,
+      1821,  -1572,   2582,     85,     48,   -140,     78,   -155,
+      -173,     96,    -32,    121,    -58,    201,   -174,    -54,
+        74,  -2442,   -282,   -771,     37,  -2930,     15,   1762,
+       154,    263,    -15,    -19,    139,    246,   -243,    -31,
+        84,    145,      8,    152,     43,    128,    679,   1828,
+      3476,     17,     92,    102,    258,    -29,   -275,    -39,
+      -187,     88,     70,     28,      2,   2143,    274,    202,
+       -67,    -13,    -22,     68,    -35,    135,    114,    108,
+        27,      1, -11248,   -100,     14,     26,     59,     10,
+       -24,     30,      1,    -38,     -9,     21,     18,     -1,
+      2029,    -83,   -342,   3443,    -25,      7,      0,     54,
+        78,    198,     45,    233,     -6,      0,   -109,   -172,
+     -2250,     41,    -79,   2820,     44,    216,     39,     59,
+       -41,     52,     79,    -52,     12,     23,    -72,   -125,
+        83,     17,    -28,    -32,     13,      2,     28,      0,
+       -26,     75,    -81,     66,     25,    -81,   6516,      9,
+       -93,     49,  -4036,  -2484,    -42,    -71,    178,     99,
+      -133,     79,    -41,   -112,     57,     66,    -28,     13,
+        39,     64,   -123,   3174,   3061,    259,     55,    123,
+      -123,    246,   -138,    139,     75,     31,   -215,   -154,
+      -218,     26,     16,     21,    126,     26,    -33,    -10,
+       -15,     16,    -20,    -53,     21,  15526,    -35,    -59,
+       -50,    -11,    -58,     67,    -11,    107,    -24,    -37,
+      8155,     31,   -111,    -62,    138,    -60,    -10,     84,
+      -128,     37,     24,    -45,    -10,    129,    -68,    -37,
+        42,    -80,   -205,    -79,   5994,    -93,   -270,   -400,
+        20,    -89,    -39,   -200,    230,    197,    325,   -305,
+      -294,     94,   3207,    128,   3119,    226,     28,    -49,
+       264,    186,      8,    -29,    -13,     27,     22,    -63,
+        43,     84,    -19,     57,  -2605,    316,    259,    -43,
+        50,  -2241,    105,    -12,    -23,    -36,     89,     41,
+       -15,    145,     10,    -81,      7,    -50,     70,     60,
+       -23,     55,    -62,      0,     52,    -77,    180,     74,
+        79, -14297,      6,     24,    299,   -107,      4,    -29,
+     -3252,    -51,     40,   -143,   3550,    -28,    102,     24,
+       215,    147,   -169,    -60,    -43,   -486,      5,     -1,
+        62,   -116,  -2917,    430,     50,   2927,    139,    127,
+        63,    -53,    141,   -255,    -85,     95,   -101,   -176,
+       195,    104,  -3066,    -56,   3239,   -161,   -214,     57,
+        24,   -375,   -181,      0,   -259,    130,   -120,     -2,
+        -6,    175,   -147,   -185,     68,    219,    425,   2685,
+     -3120,    266,    246,   -270,    -70,    273,    168,    121,
+      -143,   2641,   -553,   -547,    638,    113,   2965,   -161,
+        29,   -374,    105,   -869,    108,     70,     15,    230,
+       -54,   -106,    -21,     -4,     86,     85,    155,   -120,
+       -17,    -21,  -2534,     57,    149,   -129,     21,   -169,
+     -2289,   -127,    -19,    -26,      3,     60,     35,      1,
+       -28,     -7,     36,   -180,    -13,     87,    -68,     56,
+        80,     64,     -8,    -73,   6691,    -32,     47,     48,
+        -6,     61,     36,     -8,    -41,     -1,     13,     68,
+       140,    -51,     25,     12,      3,     57,    -54,    -33,
+       -19,     12,     28,    -60,    -56,  -2399,    -14,    127,
+      1935,     84,    127,   -193,     -3,   3307,    -56,     15,
+        31,   -116,   -187,    236,   -289,    261,     69,    144,
+      1723,     79,    -68,    102,    727,     69,    654,    -60,
+        21,    124,   3497,    248,   -684,   1469,    368,   -254,
+      -211,  -2600,    771,   -138,    368,   3089,     52,   -206,
+       147,    200,    -15,   -136,    194,   -164,   -352,   -152,
+     -4870,      5,    191,     -3,    -97,     28,    -41,    107,
+         2,     11,     60,    -76,    -35,    -42,    129,    -77,
+     -2610,   -295,   -218,   -369,     10,    253,     15,   -125,
+        74,    -87,    -70,   3366,    115,    240,   -106,    -93,
+       121,     10,     36,      9,    -18,    -66,    -77,      7,
+        37,    -76,    -22,   2913,    242,     22,    172,    102,
+       186,   -231,     90,    -11,    -57,     45,    -10,    -44,
+       -84,     44,   -117,    -43,     49,   5585,     18,   -166,
+       -43,     64,     28,     -9,     26,   -160,     31,    -28,
+        29,     56,     29,    -57,    109,    -25,   3140,   -131,
+        57,    -20,     27,    -27,     -5,    -42,    -52,     18,
+        23,    -56,    -38,    -14,    213,    -33,    -86,  -4741,
+      -151,    -46,      1,    -17,     46,      7,    -13,      0,
+        50,     28,    -57,  -7291,    -20,     12,     66,    214,
+};
+
+static const int16_t cb1616l1[] = {
+       -81,      5,    -16,     34,     19,  10938,    141,    -21,
+        27,   -105,   -110,     32,    -67,    -75,     19,   -138,
+         3,    -14,   -408,   -302,     36,  -4612,     23,   -579,
+       -35,     19,   -312,     35,    120,     97,     82,   -109,
+        41,  -1745,   -158,    299,  -3069,     84,     18,   -447,
+       -33,     65,    -32,     45,     -7,    144,     86,    100,
+     -1738,    250,   -226,   -137,    159,    -45,    134,    438,
+       102,     37,    -15,   -161,    -23,   4221,    174,     47,
+      -264,   -182,   -182,    686,   -248,     89,    -41,     80,
+     -2687,   -194,   2552,    407,  -1106,   -970,   -181,   -228,
+      4395,    118,   1027,   -255,    136,    100,    -43,    246,
+        80,     15,     34,     82,    -54,   -367,    698,    232,
+      -177,     45,    -67,     49,    138,   -158,    168,    202,
+        43,    -70,   -101,     20,    -97,  -3465,   -342,   -255,
+       127,     25,    -52,     -5,      7,     76,     -3,     19,
+       -19,     42,     10,    -63,     16,    121,    732,  -3127,
+       -43,    116,     36,  -2519,     23,     18,    181,     41,
+       -32,    -11,     22,     51,     35,     16,    -34,    -62,
+      1744,     94,    173,  -1243,   -262,     11,   3218,    239,
+       149,   -219,     29,    118,   -382,   -289,    -42,    161,
+        17,     -1,   2551,    -83,     90,   -128,    138,   3238,
+        43,    -29,   -112,    110,   -268,    293,     23,   -117,
+       -64,   -137,     79,    -70, -10747,    -66,     73,     90,
+        35,     90,    -29,    -78,   -111,     75,     48,      8,
+      -169,   2944,     16,     89,    186,    -34,     82,    241,
+       -46,    257,   -243,     93,   2966,    178,   -256,    -18,
+       -33,    103,   -320,   -271,   3088,   2893,   -250,    102,
+       696,    124,   -211,     18,   -143,     97,    216,    -99,
+       195,     40,    -35,    144,     26,    135,   -152,   -215,
+       120,     25,   -254,  -1875,    657,    197,  -3527,   -332,
+       310,    -11,   1958,    102,    -12,    -45,      2,   -127,
+         4,      1,    -19,     47,    -20,    -52,     97,    -30,
+     -7738,     51,     26,      5,    -21,     18,     15,     15,
+        66,     30,     -8,     -7,    -31,     -1,    -33,     38,
+       164,     90,   6798,    -33,    -90,    -17,     -5,     14,
+       -42,     21,    -20,    -41,     48,     -6,    -36,      6,
+      -207,  -4363,   5075,     31,      6,    100,     65,     86,
+        19,   -158,     28,   -134,    -91,    -68,      9,    -26,
+       -37,   2588,    307,   3467,   -451,    101,   -441,    323,
+        62,    188,   -132,   -294,     98,    -22,    152,    -46,
+        65,    -39,    -37,    -82,     -9,     18,     43,     17,
+         8,     56,     97, -11564,     21,     15,     75,     85,
+       155,     15,     32,      0,     20,    -45,   7412,     48,
+         3,     38,     72,     30,     23,     42,    -20,   -110,
+      -454,   -233,    653,   -325,   -276,    504,   -481,    583,
+       270,   -649,    481,  -3166,   1619,    164,    -90,    150,
+        32,    -96,    -47,     49,    -13,    115,   -183,     75,
+        62,  -9026,     12,    -93,   -715,      6,    137,   -338,
+       810,    -39,   -277,   -108,    -20,    315,    572,     -3,
+     -4570,   1053,   -132,     13,    388,   -223,   -355,     31,
+       -47,     61,   -113,      5,    -38,     43,    -47,    -80,
+      2550,     27,    247,    277,    -86,    336,    139,    146,
+      -111,    -73,    187,   -312,     68,   -276,     72,    638,
+        73,    792,   -170,   1383,    421,   -703,  -3813,    112,
+       391,   -195,   -162,    -28,    -25,    317,    228,    -83,
+      4611,    654,    353,   -380,   -283,   -627,   -301,    161,
+      -156,    -81,      5,    -15,    -13,    -17,     53,    -50,
+        36,    -66,  -7921,     -2,    -54,    -41,    -26,     47,
+        -3,     22,     -6,     11,     63,      2,     42,     71,
+       -50,    -87,    -39,      2,    -56,     -2,  11165,     44,
+      -119,    -74,    131,    134,      5,    115,    -39,    144,
+       -23,      0,    186,   4648,    351,     36,    -70,    -71,
+      1706,   2131,   -228,     42,      6,      8,      4,    -43,
+       -12,    -40,    -44,     -7,    -14,     11,     83,    -93,
+      -144,    186,    -46,     -9,     13,    -87,   -120,     70,
+      -209,    115,  -3513,    139,    -46,    133,     96,     25,
+       215,    -35,   -437,    126,    403,   -115,    145,    203,
+       -69,   -334,     37,    934,   -481,   3163,  -2528,    -49,
+        57,    100,     76,     82,    251,    288,   -114,     46,
+      -201,   -161,   -161,   -716,  -4080,    378,   -830,   -254,
+        12,  -2110,   -300,     78,    288,     48,    -90,    -99,
+       -31,   -110,    201,     66,    327,    119,   -180,    148,
+       633,     71,  -4100,     33,     57,     -9,    -48,    151,
+       -20,     72,     71,    -11,     39,    -67,    176,     27,
+       143,    198,    383,    155,   3182,   -128,   -152,  -3209,
+      -172,   -262,    -13,    129,   -167,   -128,     55,     46,
+       -37,     70,    107,      7,    -23,  -2082,    241,    236,
+       -47,    -85,    105,    -47,   -202,    208,    201,     30,
+      -106,    -14,    -38,     14,    -45,     24,    -24,  12083,
+        22,    151,    -58,     -9,     59,    170,    113,    -82,
+       369,   -155,     53,     97,   -185,    -57,    203,    311,
+       236,   4789,    -24,   -591,  -1463,    118,     94,   -274,
+      3188,   -145,   -406,    183,      0,    -54,     17,    -22,
+        37,    -55,    -34,     63,   -340,    175,   -300,    106,
+      -190,    -38,     67,     -2,     19,    -46,    -42,     11,
+       -33,    -33,    -28,    -10,    -27,  -9235,     29,     62,
+      -927,   1285,     49,     72,     65,     89,     57,    -44,
+        -9,    -15,     85,     -1,     74,     81,   -123,    160,
+        69,  -2803,    -22,     47,   -467,    -74,    748,    168,
+        -9,    235,  -3155,   -154,     48,    483,   -341,     74,
+      2403,     97,     93,   -106,    219,    136,   -191,    -50,
+         7,     71,   -103,    261,   3283,   -124,   -624,  -2570,
+        73,    -31,     10,    -73,     30,    -15,  -2256,     -2,
+       -73,     55,     73,     14,    -74,    -81,     38,    352,
+       108,    -18,     25,     61,     54,      1,     -5,    109,
+        25,  -2676,    -25,    -52,   -316,      2,     36,    -36,
+      -355,     40,    -19,    120,     27,     -4,    -51,     -8,
+        42,    -10,    -28,    -90,   -143,     29,    -10,  -8442,
+       -22,   -566,     59,    -39,     -1,     27,     29,    -20,
+         6,     19,      0,    -36,     38,     68,    -43,     35,
+        22,    -47,   -146,   3567,     13,     12,   3230,    -18,
+       -32,     75,   -112,     -8,   -157,    -23,    101,    165,
+       198,     93,    383,   1236,   1077,  -3592,  -1401,   1135,
+       844,   -266,    -74,    -70,   -280,    -98,     67,   -109,
+        38,  -5109,    -66,    -57,     89,    -21,      6,     19,
+       -21,     70,     60,     76,     35,     18,     44,     51,
+        45,     40,     54,  -6685,    -67,      9,    113,    -29,
+       -10,    -96,     80,     98,    103,    -40,     -8,    -20,
+      -131,     15,    262,     47,   -253,   -116,    -12,  -4807,
+         2,    -81,     76,    -46,     37,    353,   -130,   -191,
+      -127,    -10,    -35,     91,   -122,    173,   -165,     -8,
+    -15179,     86,   -186,    123,   -295,    -25,     21,     63,
+       -93,    730,     20,   -120,  -4624,    340,   -253,   -473,
+        44,    -18,    -99,    -37,    -54,   -317,     65,    -52,
+      2167,     68,   -245,    224,    117,   -180,  -4695,   -276,
+       118,    142,   -101,    202,   -301,    -33,   -129,   -303,
+       -90,    -75,     50,     98,    -56,    -68,   -153,    -38,
+       168,   -278,    -22,    -64,   9757,    -91,    -23,   1284,
+        53,     56,    -11,    -46,  -1645,     11,     15,     12,
+         8,    -40,     -2,     84,    -56,     17,     -7,    -30,
+     -4010,  -3557,   -252,     56,    -79,    -87,     -7,      8,
+        79,     16,     21,     51,    -63,    -22,    118,    228,
+     -1525,    -78,    -22,     -2,     16,    -49,     17,    -37,
+        -3,    -14,     10,     31,     17,   -111,     32,   -144,
+     -3612,   3473,     79,     23,    -89,     74,     33,    -29,
+        11,    -42,    -42,   -129,    -41,    155,     52,     31,
+      -162,  12609,    147,     17,     68,      2,     15,    -12,
+       -39,     50,   -108,    -66,    121,     69,    -27,     94,
+};
+
+static const int16_t cb1616s0[] = {
+      1213,  -1302,  -1130,     90,    -69,     22,   -360,    360,
+       -55,    453,   -705,   4416,    227,    173,     -8,    149,
+       210,   -118,     51,  -3759,    949,   2418,   -238,    201,
+      -597,     94,   -253,     24,    225,   -497,    -59,    273,
+       576,    651,    608,   -483,    335,   -125,    256,  -2873,
+       318,   -146,   -650,   -306,  -2021,   1044,     41,   -455,
+     -1120,    832,    978,    212,   -463,   -209,     12,   -275,
+       -20,    118,     31,    639,   5933,   -180,   -121,   -285,
+        65,    212,    439,   -135,    538,    116,   -302,   -245,
+      2534,   -623,   1549,    -34,    727,  -1750,   1477,     79,
+      1669,   -828,    618,   -856,    773,   -286,    343,    -94,
+       107,   -320,  -3144,   -380,    694,    -80,    843,    103,
+      -700,   -269,    452,  -6847,    -12,   -527,     97,    -21,
+       -76,   -246,      2,   -104,    -68,     98,    312,    117,
+      -342,   1025,    207,    838,    -71,   2463,     60,  -1294,
+      1549,  -1310,   -202,  -1585,    682,    327,    608,    649,
+       664,   -801,    588,    137,   -468,    286,    234,  -6726,
+      -107,    177,   -147,    278,    118,    -81,   -242,     97,
+      -235,   1599,   -877,   1985,    448,   -319,   -745,   -504,
+      -433,  -1859,    -35,    286,   -665,  -1449,   -124,    -97,
+       930,   2622,    682,    698,   1898,   1120,   -323,   -142,
+      -679,    294,   -162,   -539,  -1649,    152,     23,   -414,
+      1493,    602,    913,   1428,  -3212,   -103,   -330,    557,
+       463,     92,    251,    339,     16,    936,   -116,    229,
+      -827,   -504,   2015,   1553,   -503,   -350,    214,    386,
+       295,   2697,    429,     72,   -705,   -120,    427,   -139,
+      -334,   -318,  -6613,   -468,     10,   -122,     59,   -322,
+      -165,   -144,     45,   -427,    -12,    -79,   -202,   -266,
+       981,   -273,    240,   -454,    -30,   -119,    340,     92,
+      -251,    247,    189,     71,    243,  -5648,   -601,   -434,
+      -674,    867,   -713,   -428,   -101,   -231,   1144,    -89,
+       -10,     57,    302,    154,    362,   -425,   2014,   2577,
+     -8659,    389,    -90,     76,     15,    147,     30,   -202,
+       -99,   -255,   -242,   -165,    257,     97,     41,    -72,
+       263,    613,    272,    400,   5020,   -199,   -196,   -177,
+      -276,    -25,     28,     97,   -155,    119,    763,     33,
+     -3540,  -1447,     16,   -169,    148,   -143,    707,  -2483,
+       178,     83,    -83,    154,    -75,    -15,    153,    283,
+      -323,   -139,  -1390,     69,    725,  -1744,    331,  -3665,
+       415,   -514,   -366,    124,    660,   -295,    180,     77,
+      -228,    192,    684,   -193,      4,   4409,    298,    427,
+       591,    290,   -159,   -166,   -372,   -514,  -1840,   -562,
+       795,  -1765,   -349,   1178,  -1619,   -391,    615,   -784,
+      1353,    746,   -871,   -994,    182,   -464,   -498,    -96,
+      -306,   -729,    743,    270,    223,   -731,     73,   2692,
+      1110,  -2354,   -328,    -21,   -172,   -339,   -528,     93,
+      -338,    548,   1498,    309,   -134,    160,   -247,   -619,
+      1127,    783,  -1557,    400,   1035,   -445,   -155,  -2443,
+       590,   -790,    137,    388,   1188,    844,   -395,   1005,
+        55,   1141,   -122,  -3174,    138,    155,   -506,    306,
+     -3255,   2432,   -116,  -1289,   -744,   -350,      3,    192,
+      -156,     95,   -552,    -57,    329,   -405,    737,    138,
+      -835,   4096,  -1037,    797,   -417,   -418,   -507,   -694,
+      -256,     78,    -94,    -63,    -93,    754,   -555,    -90,
+     -1518,   -878,    167,   -392,   -100,    -78,    -80,    -45,
+      4774,    114,   -284,   -560,    -21,    275,     15,   -195,
+     -1692,   -711,  -1057,    167,  -1555,   -690,   -263,   -267,
+       310,   -229,    -14,   -880,    426,  -2826,    320,    -49,
+     -1223,   -725,   3538,   -270,   -606,  -1812,    481,   -703,
+       176,   -284,   -173,    271,    847,    711,    239,    314,
+      1233,    -61,    477,    429,   -691,   -156,   6712,    850,
+       365,    229,   -197,   -355,    298,    250,    207,   -437,
+     -1647,   -261,    165,    114,    165,   1165,    -58,   -597,
+     -3290,   -517,   -478,   -842,   -187,   -448,   -302,   -204,
+       410,    544,    669,  -2012,    476,    434,    214,    698,
+       302,    100,     61,     63,   -386,    918,   4434,   -230,
+       157,  -1019,  -1487,   2239,   -774,   -234,   -378,    772,
+      -190,    270,    -61,    -19,    322,    488,    937,  -3582,
+      -415,   2091,   1862,     81,   -134,   1285,  -2732,    221,
+      -235,    388,   -216,    -63,    664,   -105,    -37,    165,
+       899,   -373,    284,   -375,    286,   -263,   -295,    276,
+      -246,    188,   5285,   -303,    290,    -60,     -1,     95,
+      -703,   -288,     74,   -717,   -127,    -53,   -422,   -452,
+       166,    -54,    -15,    268,    238,    -31,   -279,  -5872,
+       863,   -907,   -101,    885,    552,    442,  -2336,  -2142,
+      -804,   -147,   -791,   1000,     96,    250,   -306,    134,
+       743,  -1648,   -867,    673,   1594,   3725,    527,   -676,
+      -661,    238,    262,    560,    277,    -58,    444,    166,
+     -1039,   -702,    558,   -970,  -1763,  -1198,    580,    378,
+      -421,   -972,    630,   -279,  -2456,  -1222,   -232,   -749,
+     -3325,    174,    789,    729,   -487,    583,   -157,   1503,
+      -801,    -38,    -11,    556,     81,   1508,   -140,     74,
+      1373,    912,   1471,      4,  -1080,   -105,    -58,   -104,
+       -54,   -544,  -2392,   1550,    318,   -506,    -11,   -180,
+     -1891,   -230,   -259,  -1182,   -154,    524,   -568,   1972,
+       546,    469,   -720,   1089,  -1530,   -680,   1349,    429,
+        82,  -1524,   1894,    -90,    188,   -145,     15,  -1113,
+        15,     53,    282,   2212,   -736,   -941,  -1148,   -344,
+      1473,    344,    392,   -333,   -556,   -480,  -3833,     35,
+      -160,   -525,    151,   -534,   -782,     38,    520,   -416,
+      -384,   7582,   -158,    -29,     74,    -57,    -23,     73,
+      -393,   -245,    -12,   -260,   -154,   -319,    357,    247,
+      -306,    351,    273,    755,    227,     89,    283,   -152,
+        17,   5129,    191,   -213,   -531,    255,   -468,   -209,
+      1128,     72,   -807,    225,   -319,   1638,     42,     20,
+       935,    -52,   -326,    541,  -1174,    130,    284,   -112,
+       444,   3959,    262,   -631,   -262,    275,   1025,    190,
+      1125,   -265,    -95,    265,     35,    270,    -92,    -30,
+      -141,    325,   -435,     45,   -659,    149,   3648,    339,
+     -1701,  -1338,   -144,   -989,   -604,     84,   -394,    168,
+      -302,  -1294,   -433,   -921,   1271,     77,    374,   -604,
+      -230,     97,    206,   -138,   2909,    478,    707,      0,
+      1242,   -340,  -1659,    349,   2751,  -1175,   -146,   1038,
+        65,   -775,   -423,     14,     22,     41,   -905,    287,
+       280,   -933,    195,  -1817,    540,  -2374,   -661,  -1102,
+       879,   1232,     29,  -1683,    286,   -136,    658,   -395,
+     -1782,  -2823,   -624,   -223,   -299,   2859,   -103,    -45,
+       544,     82,    -21,   -263,   -666,   -362,   -732,    249,
+      1087,   -242,     30,    663,   -386,   -350,   1240,   -492,
+      -868,     69,    -41,     35,     30,  -1791,   3870,   -455,
+      1355,   1098,   2933,    347,    361,     79,   2855,    -26,
+       -66,   -598,    -43,     21,   -386,   -802,    -81,   -436,
+       846,   -673,    377,   -326,  -1217,   1465,   -480,   -205,
+     -2168,  -1689,    690,    355,   1192,    734,   -113,     39,
+      -486,   -644,    438,   1096,   -723,   -524,  -1634,   -621,
+      -394,    226,    167,   -625,   -709,    854,   3005,   -910,
+        13,   -793,  -1517,  -1254,     18,   -440,   -836,    651,
+       -31,    229,  -1081,   -126,   -191,  -3612,    487,    451,
+      -292,    943,  -2018,   -618,   -259,   -649,   -723,   -447,
+      -238,   1096,  -2228,    675,    563,   -316,  -1248,     32,
+       -28,    293,  -1817,    226,    267,   1291,    624,  -2279,
+       143,    650,      5,   -563,   -504,  -2124,    -94,  -1613,
+     -3050,    708,  -3458,    442,     30,     65,    -80,     89,
+       204,   -245,     94,     28,     -2,   -231,    623,   -189,
+      -405,  -2147,   1147,   3124,    806,   1048,   1145,    653,
+        47,     86,     -4,     46,    437,    229,   -190,    310,
+      1995,    -48,  -1015,  -1806,   -266,   -941,    361,    179,
+       172,    397,    182,    323,   -516,   3435,      7,     -5,
+};
+
+static const int16_t cb1616s1[] = {
+     -2521,   -518,   1830,    985,   -500,    109,   -807,   -197,
+       543,  -1036,    104,   1989,    428,    740,   1110,   -366,
+      1482,    899,  -1828,    159,  -3015,   -311,   -792,    -42,
+         3,   -412,   -157,    -13,    863,   -248,    261,   -187,
+      -409,    156,    772,    271,    318,   -262,     78,   -571,
+        28,    370,    119,    302,  -4794,    106,   -123,   -153,
+      1857,   -702,   1090,   -319,    415,   -327,   2124,   -170,
+      -411,    174,     62,     -7,    921,   -128,    735,   -127,
+       972,   1678,    166,  -1471,   -208,   -224,    871,   -900,
+      -223,   -817,    288,   -472,     10,     31,   -401,  -3201,
+     -1290,     -3,   -301,    183,    730,    473,    438,    -81,
+       882,    -64,   2898,   -242,    408,   -211,   -333,   -254,
+      -820,    612,  -1128,    -60,    -73,  -2516,     45,    637,
+      -130,    459,   -312,   -223,   -629,   1490,   1792,   -199,
+       -21,   -545,   1772,  -1084,   -173,    381,    380,   1289,
+      -117,    483,    138,  -1200,   -519,    598,  -3453,    349,
+     -3102,   1260,   -170,    238,   -684,     48,   -483,   -883,
+      -879,    139,    298,   -110,   -203,   -955,    195,     57,
+      -550,   1945,   -711,   -688,  -1470,   1527,     58,    317,
+       656,    310,     57,    162,   2006,   1387,    845,   -127,
+      -398,    318,   2520,   2002,   -906,   -323,   -194,    907,
+       588,   -228,   -357,   -316,    557,   -596,  -1559,     -3,
+      1614,   1317,  -1701,    936,    -89,  -2270,   1327,   1046,
+       400,   -233,     18,   -730,    -23,   -181,   -593,     74,
+      -570,   -969,    432,   -261,   -833,    -90,  -4675,    786,
+      -566,   -183,   -859,   -554,    346,   -493,   -201,   -220,
+       241,   -919,  -1896,    265,   -802,   1380,   -718,  -1103,
+      -574,    307,    138,  -1260,    175,   2540,    -82,     58,
+      1046,  -1381,   2486,    582,    455,    485,   -824,   -150,
+        57,    -45,   -155,   -490,  -1108,  -2191,    833,    423,
+     -2011,    267,    779,    140,    -28,     57,     94,      6,
+      -301,      5,   -833,  -1226,   -193,   1110,    -63,     79,
+      -492,  -1465,  -2733,    444,     56,  -1116,   -601,     20,
+      -618,  -1315,   -695,   1146,    -66,    336,   -166,    158,
+       530,    -53,   -371,   -594,   -685,    114,   -146,    373,
+       174,     -1,     47,    119,   -124,   -121,  -6697,    -94,
+     -3544,   1506,   1221,   -101,   2160,    558,   -254,   -728,
+       511,    378,   -383,     12,    626,    172,    183,    354,
+        49,   1669,   1188,   3810,    409,    152,    694,  -2520,
+       342,     61,    -85,    -38,   -170,      5,    305,    154,
+      -348,    699,    332,   2542,    673,  -1130,  -2601,    554,
+      1483,    466,    271,    490,   -644,    822,    -96,    477,
+       131,  -2051,   -111,     43,    -31,    -62,   -767,  -3257,
+       663,    488,   1823,    522,   -525,   -249,    481,     -7,
+     -1298,   -941,   -335,   -566,    305,    534,   -735,    207,
+       709,  -3170,     19,    -20,  -1888,    271,  -1697,    117,
+      1837,   2690,    305,   -483,   -463,    407,   -706,    467,
+       518,   1806,    244,    -80,   -453,   -505,    882,    843,
+      1328,   -280,    175,    319,   -842,    192,   -680,   -469,
+      5440,   -205,   -187,     53,    332,    204,   -184,     96,
+      1026,   -525,     20,    975,    125,  -1562,  -1873,   -757,
+      -137,    133,    -10,   -340,   -783,  -1484,  -2206,   1238,
+     -5212,   -466,    129,   -224,     17,    497,    -41,    846,
+        88,    -41,    285,    284,   -155,     21,   -225,    150,
+       223,   -807,   -444,  -1141,   -908,    292,   -326,    559,
+      -446,   -283,    -41,   -277,  -3479,   -667,    532,     83,
+       257,    383,  -2986,   1685,    697,    777,   1551,   -142,
+      1786,    579,   -531,    787,    712,   -984,    603,   -174,
+      -459,   1303,   -943,    741,   1103,    -73,    600,   -403,
+       -42,   -169,    -90,    220,    208,    105,  -4083,  -1069,
+       981,   -926,    124,    273,   -145,   -133,    307,   4720,
+       209,    324,    -79,     12,    -41,   -220,    211,   -184,
+       435,    307,  -1544,     83,   1565,   -445,   -217,   -648,
+      -379,  -1270,  -1590,  -2337,   -860,    348,    648,   -157,
+      -785,   3318,   -123,   -138,   -412,   -876,    358,   -173,
+      -280,    -81,   -149,   -167,   -160,  -2113,     20,    -40,
+      1022,    432,   -721,     55,   -651,     17,  -1135,   -380,
+      -542,  -1128,   2919,   -475,   -143,    -53,    176,   -152,
+         7,    -29,   -172,    174,    195,  -8005,    277,    105,
+        35,    115,   -314,    137,   -253,     75,   -278,     90,
+     -1508,     79,   -153,   -560,   1027,   -349,   -292,   -466,
+     -1101,   -324,    -84,   4251,    822,   -420,     55,     43,
+      1886,    281,    964,   2408,    425,   1187,    -27,    -84,
+     -1277,     63,   -978,   -143,    506,    727,   -155,   -384,
+      3434,    592,   -262,   -438,    -30,   2849,    -69,    -58,
+      -181,    -87,     20,    299,    412,   -263,    702,    131,
+      -271,    -10,    736,    121,  -6299,   -132,   -116,     26,
+      -253,   -586,     32,   -145,   -251,    -12,    471,    135,
+       585,    604,     29,    873,    363,     -2,  -1595,     41,
+     -1147,   -142,    665,  -2752,   1302,   -358,   -134,     29,
+      -691,    -12,   -702,   -459,    100,    278,      9,     54,
+        66,   -458,     53,    213,    193,     14,   -400,   4870,
+      -950,   -209,     50,    470,    449,      3,   -118,   2287,
+      -469,    -58,    126,   1011,   -826,    386,  -1019,  -2390,
+      -586,  -1401,    137,    760,    141,    -89,    117,   -252,
+      3106,   -936,   -198,    390,    463,   -245,   -509,   -123,
+      3057,   1200,   3451,    282,   -332,   -585,   -662,   -955,
+       165,   -276,     73,    373,    202,    506,    356,    125,
+       141,   -613,   -670,    446,   2031,   1521,   -446,   1339,
+       198,   -112,    214,     70,    265,  -1310,   2492,   -133,
+     -1880,   -347,   -961,    312,  -3714,   -475,    102,    391,
+        64,   1091,   -686,   -101,    144,    447,    173,     66,
+      -374,    342,     69,  -3379,  -1331,   1160,   -889,   -858,
+       982,  -1613,   -223,     57,    186,    428,    226,   -477,
+       449,  -1052,   -661,   -382,    459,    277,   -277,   -250,
+        12,   4077,   -260,   -161,   -163,     38,    159,    243,
+       131,    457,  -2253,   -301,  -1626,     37,    806,    104,
+       191,   1899,    346,    398,  -1108,   -623,   -391,   1092,
+      1252,   1126,     81,   -116,   1192,    674,  -1321,    -32,
+      1739,   -708,   -230,   -844,   -507,    415,    261,    211,
+      -619,   -191,   5460,      8,    139,    197,    392,   -556,
+      -215,     66,     64,   -808,      0,   -136,    151,    156,
+       260,     94,    418,  -1446,   1815,   -540,   -793,    451,
+      -477,   1788,   -124,    330,   1638,    342,   -503,   -384,
+     -1201,   -762,    929,  -2886,    888,    -63,    318,    598,
+        42,  -1226,   -400,   -462,   -136,    321,   1872,    376,
+      1260,    142,    -79,   4377,      9,    294,    -71,   -190,
+       -21,  -2612,   -240,     26,    -18,   -227,    864,     79,
+      2588,   -882,     87,  -2976,      9,    480,  -1573,   -170,
+      -429,    201,   -124,    171,    632,    -60,   -447,     64,
+       -37,  -1182,    -86,   -105,   2901,  -3557,   -134,    486,
+       141,   -259,    239,    465,    467,   1009,   -409,     34,
+       254,   2469,   1002,    834,    557,   -845,    149,   -747,
+      -504,    494,   1382,   1067,    353,    191,  -1105,   1705,
+      -586,   1472,   -444,  -1303,    198,    602,    471,    468,
+      4855,    127,   -141,    487,   -454,   -138,   -392,   -118,
+      -491,   -948,     58,   -290,     -7,   -662,    229,   -268,
+        -2,   -537,   -620,  -4770,   1152,   -173,    166,    -69,
+        32,  -2555,    433,   -583,  -2219,   1107,   1082,   -942,
+      -173,    399,   -601,    250,    423,    125,   -448,    352,
+      -571,   -406,      0,   4735,   -264,   -174,  -1020,   1105,
+     -1149,   -171,   -252,   -130,   -202,    -74,    601,    601,
+       570,  -2742,  -1403,   3129,   -349,    194,    309,    130,
+       261,     93,    154,   -117,   -418,   -657,    270,   -160,
+      1660,   -818,    613,  -1458,   -653,  -3763,   -232,     90,
+      -265,    -99,    -28,    -13,   -281,   -553,     11,   -142,
+     -1764,  -4548,    936,    -21,   -683,    -88,   -806,   -187,
+        28,     78,    -70,    -99,     -2,   -493,    -16,     48,
+};
+
+static const int16_t cb1616m0[] = {
+     -3821,  -3397,    203,    -25,    -22,     68,    189,    -13,
+      -286,     94,     18,    288,     29,     -5,      3,   -414,
+      1483,   -172,  -1275,   -180,  -3792,    360,    145,   -143,
+       444,   -139,   -198,     70,    -17,   -353,   -121,     -6,
+        76,    -50,   2987,    173,  -3070,   -229,    -16,    192,
+       134,    -55,    -86,   -200,    128,  -2052,    -59,    -11,
+        -4,    309,    179,    494,   -138,   -363,   -336,    119,
+      -127,   2497,   -169,   -316,    -87,   -538,     42,   -534,
+       315,   2364,     61,    269,    -87,    -94,     82,  -2069,
+        18,   1238,     -7,     79,     -9,     41,     70,     50,
+       209,   -158,   -136,     28,   -275,     62,    296,     77,
+      6269,   -184,     73,    -19,    -25,    -57,    134,    -52,
+      8569,   -176,     -8,     17,     15,     79,     36,   -137,
+        12,     44,   -270,   2335,    111,    517,    -83,    207,
+      -276,   2577,   -198,     83,    376,    -75,   -273,     62,
+       109,      4,    -48,    122,    -41,     99,    -87,     14,
+     -7696,   -118,    -66,    171,     96,    -31,    123,   -217,
+      -676,   -439,    407,     97,   -281,   1873,    626,   -148,
+      -548,   1634,    704,     97,  -2076,   -336,    632,   -371,
+       113,    544,    -88,    184,  -2200,   -420,   -592,   -168,
+       759,    291,   2215,    704,   -140,   -145,  -4088,    295,
+       186,   -270,    283,    294,    -42,     76,     69,     41,
+      -140,   1635,   -200,   -682,    302,   -192,    902,   -540,
+      -843,   -494,   -529,    102,   -759,   -165,   3160,   -180,
+     -1450,   -424,    -16,      6,   -548,    296,  -3056,    219,
+     -1883,   -109,   -566,   -431,     95,   -422,   -532,    -26,
+       120,    -46,     23,    174,    175,   -369,    110,     -2,
+        25,    132,     -1,  -3338,    -67,   2140,    -25,    566,
+      -129,     35,   1187,    337,   1999,   2712,    -71,     45,
+      -177,     94,   -321,   -197,   -573,     98,    225,     46,
+        53,     78,    -40,     82,     23,   2718,   2534,     89,
+       -65,     77,    206,    343,    527,    102,   -191,     94,
+       463,    111,  -4529,     97,    876,   -205,   -944,    181,
+      -132,    467,    366,     85,   -302,   -100,    -33,    -76,
+     -3087,  -2546,    215,    277,    -52,    352,    137,    -45,
+       162,    590,    406,    382,     85,  -2824,    141,    219,
+     -3790,     40,    126,     32,     30,    100,    121,   -210,
+       196,   -268,    178,    102,   1229,    -80,   -750,    -11,
+       -57,     84,    238,   3571,    274,   -254,     55,  -1616,
+      -176,   -755,     46,  -1306,   -201,   -228,    101,    197,
+       -93,   -156,    319,     82,   -385,    -17,  -4660,    180,
+      1278,   -113,   -215,    103,    832,   -233,    412,    249,
+      -900,   -132,  -3427,     52,    416,    267,    317,   -384,
+       130,     78,     91,   -360,     75,    386,   2219,   -360,
+     -2975,     17,    286,   -294,   -213,    231,    131,    821,
+      -358,    222,   -230,    -44,    -93,  -1151,    294,   -316,
+        -8,    129,    231,   -993,    -58,   3319,     48,  -2546,
+      -213,    -14,   3208,    162,   -240,   -176,    307,   -165,
+       -20,    348,   -113,    -78,    -91,     -8,   -261,   8033,
+      -179,     64,     -7,   -113,    -59,    -32,   -170,     52,
+        55,    -80,    140,     64,    -39,    915,     28,    416,
+        38,  -2328,    206,    115,    366,    -92,    652,    110,
+     -2838,    -59,    613,     23,    109,   -151,   -198,    185,
+      3033,   -122,   2863,   -273,     86,     41,    114,    -99,
+       315,    372,     14,   2191,   -171,    531,    -18,    -34,
+      -352,    130,   -360,    117,  -2896,      2,   -564,     51,
+       223,     57,   -257,   3161,   3130,   -384,    126,    -40,
+      -160,   -232,   -138,     81,    -34,    -96,     82,      9,
+        62,   -161,    344,    100,    790,   -243,   -344,   -393,
+      -531,    401,     90,    171,    144,   -329,      7,  -4639,
+      -135,     -6,    351,    -21,   -195,    224,    -25,   6027,
+       224,    -14,    344,    170,   -169,    -97,    252,   -488,
+      -379,    -73,    629,     -9,    266,    152,    -64,    330,
+        -8,   2080,    -91,  -3315,    229,     25,     45,   -528,
+      -123,   2951,     40,    -85,     -4,  -2695,    -38,   -112,
+        84,    -30,     79,    762,    151,  -4089,    -95,   -151,
+         9,    138,   -206,     -3,  -2114,     99,   -100,    116,
+      -403,    -56,     -8,    -36,    115,    -18,   -195,    -38,
+      -240,      8,    -32,    122,    125,  -7406,     45,   -210,
+       111,   -152,   -152,    -35,    -72,     28,   -154,    303,
+     -3147,    459,  -2881,    -14,    -13,    -56,   -126,    -69,
+      -213,    -97,    202,    -88,   -277,   -557,    451,   -376,
+       -91,    319,    141,   2728,     23,   2506,   -101,    632,
+        62,   -314,    159,     44,   1231,    -65,    -37,    192,
+      3118,   -186,   -396,   -108,     71,   2111,    586,     95,
+        15,    -28,    176,     20,    -67,      3,   -265,    101,
+      -182,    -21,   -455,    -15,  -6225,    -45,   -353,   -384,
+       -22,    113,    -40,    -47,     57,    -73,   -503,    134,
+       736,    -70,   -125,     -5,   -250,     62,    165,    182,
+       185,   -132,    426,   -276,    100,   -497,    -23,     81,
+      -112,  -3528,  -1997,   -234,   -154,    -91,   -125,    -26,
+       179,   -611,    655,    767,  -1064,    130,   -264,    107,
+      2811,  -1391,    298,    -20,     37,    -74,    -12,   -157,
+      -270,   -106,   2559,    -89,  -3107,     55,    187,   -265,
+       195,    140,      1,   -484,    713,    171,  -1123,   -226,
+      3666,   -367,   -516,   -249,     38,    195,    236,   -378,
+      -383,   -205,    -72,     -7,     15,  -9329,     -6,    -26,
+        56,    141,     48,      6,   -141,    -95,    -69,    -40,
+       -99,    -80,     73,   -253,    456,   -174,     51,   -250,
+       -48,  -2115,    -63,  -2555,    -25,  -2058,    -58,     66,
+       176,     14, -10053,    -23,    -39,    -37,    -15,     38,
+        82,     11,     97,    169,      5,    -67,     57,     61,
+     -2248,    108,    -19,    256,   -169,   -122,   -336,   -431,
+       -77,   -250,   -156,   -745,    184,    684,  10559,   -199,
+       -34,    -37,     96,    -82,    -17,     60,     65,     21,
+       -67,   -337,     62,     35,     74,   -214,     38,     47,
+      -129,   6139,   -139,    -57,   -154,    261,      7,   -127,
+       109,     40,    179,    -99,    198,    -51,     48,    -36,
+     -2377,   -194,   -334,  -2826,    103,   -220,    -57,     41,
+       979,   -895,     68,   -217,  -1712,   -430,    -98,     91,
+      -107,  -1755,   2615,     84,   -500,    231,    480,    -31,
+       146,   -157,   -120,    152,   2342,    -36,  -1969,     57,
+      -109,    476,   -243,    261,    -58,   1998,      4,   1388,
+       -98,     45,   -140,    400,    -76,   -321,    -22,     -9,
+       210,    517,      5,  -4708,     66,   -330,   -405,    -19,
+      2158,    -65,  -2163,    244,    -16,   -192,    494,   -381,
+      -194,    413,     89,    220,    455,    -54,      4,    206,
+       221,  -4998,     63,   -365,    354,    364,    677,    207,
+       -66,    -27,   -477,   -182,    841,     85,    -40,    166,
+      -185,    321,   -293,   -181,   -429,   -231,   1401,   -122,
+       938,     67,   -185,     51,   3188,   -802,    421,  -3230,
+      1432,   -432,   -658,   -587,   -843,    421,    177,    446,
+       510,   -140,    -90,   -127,    -78,      2,   1089,   -185,
+       301,   -393,   4100,   -152,    265,    224,     25,     95,
+       534,    280,   -254,    -45,     -5,   -207,     49,   -126,
+      8922,     43,      9,     21,     28,     21,    -42,    -84,
+        38,     90,  -2014,     61,   -149,    188,  -3350,   -120,
+       -43,     10,     14,    155,   -225,   -351,   -114,     28,
+       -23,  -4400,    367,    -51,     76,    -89,   -113,    122,
+      2007,     25,   -348,   -227,   -370,    -61,    135,    -79,
+};
+
+static const int16_t cb1616m1[] = {
+      -321,     -7,  -6725,    -36,     77,    -20,   -101,   -529,
+      -166,     97,    -76,   -232,    -70,     16,     13,     93,
+       -50,    222,   -258,  -4424,   -125,    125,     83,    313,
+      -246,   -325,    108,   -331,    484,   -188,    192,   -964,
+      2603,    -38,  -2236,     58,    337,   -254,    -17,    -90,
+       -88,     40,   -141,  -1293,    -56,   -811,    247,    -78,
+       -34,    144,    112,     43,    142,   -137,   -147,     56,
+      -406,     12,    210,    132,   3707,    109,   -896,   -268,
+     -2295,   -509,     32,   -219,    113,   -104,    141,    273,
+        18,   -358,     16,  -3354,   3474,   -167,    220,     10,
+       104,   -175,     -8,    -71,    -77,    -48,    277,     82,
+        86,     35,   -712,    -32,     36,    -65,    213,    121,
+       -76,   -742,    291,  -4587,   -169,   -122,    -77,   -285,
+        54,   -120,     89,     71,     12,   -133,     54,   -215,
+     -1906,   -115,   3220,   -194,   -391,     87,    415,   -212,
+      -210,   -138,    182,    590,    713,    944,    320,    142,
+     -1970,    197,    -79,   -548,    458,   2836,     33,    -62,
+      -183,   -149,   -640,    147,   -427,   -113,   -178,  -1631,
+      -108,   2666,    -58,   2210,   -251,    288,     16,    382,
+      2123,    636,     -4,   1118,    232,    335,    -33,   -114,
+        24,    -68,   1309,    -38,   2080,    534,    288,   -162,
+      -630,   -360,   -643,     10,     62,  -2229,    263,     19,
+       310,    -44,    419,   2846,  -2579,   -159,   -246,    685,
+       -67,    394,    314,   -356,   -158,     19,     90,    116,
+     -2261,    163,    664,    163,   -191,    -49,    -18,   -308,
+       -15,   2508,   -370,    693,    -62,    818,   -307,   -658,
+       133,   1858,  -4900,     53,  -2485,    -48,     -9,    126,
+       159,      6,    -71,    291,    102,   -367,    -62,     27,
+        88,     -6,    204,    -65,   -725,     31,   -159,     -1,
+        -5,     45,   -133,   -146,    261,  -4481,    -19,    694,
+      -261,   -478,   -177,     88,    214,   -836,    -14,   -762,
+      -111,    501,      0,    254,   1971,  -1024,   2678,   -141,
+     -6064,     76,    430,    160,   -195,   -582,    280,    580,
+       183,   -315,    -13,    665,    -53,    315,   -199,    438,
+       220,   3267,    194,      2,   2808,    -88,     42,    150,
+      -179,    237,   -155,    143,     46,     99,     27,     30,
+     -6137,    -51,    -89,    201,    145,   -179,     13,   -358,
+        55,     71,     -3,     28,     -9,    -16,    125,    160,
+       159,    -21,  -5407,   -485,     -4,    -88,    -89,     44,
+         3,    166,     22,   -413,    993,     80,    485,   -107,
+       446,   -943,   1025,    261,     -3,   2991,    547,   -268,
+      -109,    536,    -10,    187,     17,    388,   -120,    -71,
+      -343,   -416,    162,     69,     -9,     46,   -477,     83,
+      6134,    146,   -236,   -125,    -94,    -55,   -274,   -231,
+      1120,    171,   -139,  -2714,     80,   -111,     20,   2475,
+      -135,  -1710,    317,   -762,    155,   1222,     68,   1192,
+       -15,   1825,    -36,    -45,   -120,   -484,   -131,   -162,
+      -128,    163,   -407,     72,   -222,    -46,   -222,  -5319,
+       278,   -373,   -436,    284,    138,   -243,   -104,     28,
+       -77,   3022,     93,    -15,   -581,   -498,    292,   -165,
+     -1740,    121,    195,  -1368,   -134,    -68,    -20,    -75,
+       -10,    113,    128,   -381,   -507,   -237,   -709,     13,
+       -22,    155,  -5065,    -95,    246,   -226,    193,    687,
+      1839,    246,   -232,   -359,    475,    106,    297,    205,
+     -2702,   -378,   -219,    -20,    140,  -3198,    192,  -3077,
+      -135,    -38,    -23,    213,    -72,    255,    -90,   -130,
+      -150,     62,   -484,    -94,  -2625,    -89,    344,   -129,
+      2655,    369,    -35,     17,   -697,    251,   -343,     68,
+        53,    176,   3104,    237,    -75,  -3020,    178,     45,
+       -86,     45,   -115,    183,     49,     26,    140,     77,
+        40,  -2315,    249,   1791,     48,   -755,    -12,    201,
+      -455,   -250,    -62,   1729,   -113,   -959,    238,   -114,
+       289,   -135,  -2208,   2748,     65,    306,    -83,      3,
+      -513,   -481,    -49,   -163,   -568,    -88,    668,    -51,
+     -2586,    106,    -22,    584,   -453,   -350,    333,   -177,
+      -236,   -657,    536,   -349,    394,    -56,     14,    133,
+       -55,    -84,    210,    -19,  -8647,    154,     80,     27,
+        -7,    -76,   -117,    100,   -201,      1,    296,   -101,
+        -6,   5642,    137,    -59,    -93,     95,   -110,   -280,
+       -61,   -300,     25,    887,     43,    -30,   2493,     76,
+       -22,   -343,    489,    266,    308,    163,    132,   -349,
+      2021,     18,  15536,     61,     11,    -41,    -42,     41,
+        -4,   -183,    -40,    -24,     26,    241,   -102,   -115,
+      -164,   2044,    -35,   -217,   -226,    734,   -228,  -2546,
+       218,      0,    122,   -150,   -528,   -188,  -1273,    155,
+       107,    -33,    -37,   -293,      6,    112,   -155,   -228,
+       192,  -2378,    153,  -1045,    213,   2975,     39,   -159,
+       -10,    -41,     34,   -125,      4,    -30,   3907,    -41,
+       848,   -346,    191,   -195,   -292,   -126,   3421,    -24,
+      -244,     92,    693,     64,   -193,    192,    121,    -33,
+      -141,    523,   -162,   2754,     71,     59,     40,    -63,
+      -142,   -100,   -338,    379,   -136,    -64,   -196,     11,
+      3198,    162,   2097,   -132,  -2359,   -193,   -398,   -318,
+       842,   -635,   -168,    425,   2001,   -136,    290,    206,
+       562,    -96,     -8,   -214,    -45,    -11,      4,     52,
+       177,   -148,    229,     33,    -48,    -46,   6538,   -106,
+       -27,    -22,   6527,     20,   -405,    157,     87,    208,
+      -117,     -4,     30,     87,     28,   -356,    -76,   -108,
+       -33,   -568,   -270,    177,     49,   -457,  -3210,    119,
+       103,    256,   -180,    211,  -1209,   -369,   -256,     37,
+       -47,   4976,     84,    207,    225,    224,   -425,    396,
+       921,     58,   -150,    104,   1509,     15,    -58,   1724,
+        47,    -24,     21,    376,    353,    482,   -236,    634,
+       306,   3179,     73,    -33,    -54,   -169,   -214,    146,
+      4322,   -216,   -644,    305,    305,   -453,     53,    143,
+        -9,  -1472,   -141,   1314,     57,     40,    -55,    -80,
+        67,   9264,     57,     86,     22,   -147,      1,     -6,
+         0,     39,      7,    114,    -51,   -137,    155,    -15,
+      -122,      5,    137,    125,    213,     -6,   7158,     36,
+       -52,    -54,    149,    901,    859,    703,    366,    673,
+       -13,   1186,    588,   -202,   -451,     18,   -585,   -250,
+     -2632,   -134,     61,  -3038,   1022,     78,   -672,   -276,
+        96,    838,    533,   -254,   -525,   -106,   -378,   1627,
+        12,     31,    317,   -118,     81,    313,   -186,    197,
+       452,  -2971,     83,   1326,    419,  -2366,   -328,    -87,
+      -103,   -243,   -280,     25,   -240,    590,   -232,    105,
+     -2966,  -2391,   -326,    338,     80,   -392,   -243,    271,
+        -7,   1127,      1,   1901,  -2279,   -207,     32,    -99,
+       560,   -193,    371,    494,    506,    255,    332,  10737,
+        48,      8,    -33,    -33,     32,    -33,     45,   -104,
+      -259,    -99,    -37,   -134,     72,    -50,    138,    428,
+     -2258,     77,    744,      5,     96,   3020,   -269,     49,
+       112,   -223,    186,     48,    224,   2571,    340,   -129,
+       -39,  -1900,    -45,   1978,   -261,    223,    294,     22,
+      -108,    -58,    109,    -31,  -3252,   -138,  -2969,    -19,
+      -133,    190,    -36,    132,   -136,     63,   -175,    351,
+       -76,    232,  -2708,    -17,    -24,   -130,   -474,     74,
+     -2978,     45,   -139,    -23,    227,    -42,   -141,    278,
+        81,      8,  -2491,   -446,    315,    -64,   -167,   -643,
+      -275,    100,      0,   2484,   -482,   -128,   -144,   -206,
+};
+
+static const int16_t cb1616sl0[] = {
+       -46,  -5073,    119,    -68,      8,   -160,    201,    -15,
+        55,     44,     44,   -197,   -110,    -83,    -90,    -66,
+       -29,   -128,   2449,   -182,   2226,    298,    -69,    189,
+      -167,    199,    -78,     60,   -154,   -169,   -242,    189,
+       214,    132,    -41,    169,    222,   -130,    209,     20,
+      -154,   -327,  -3458,    186,   1356,    672,    133,    100,
+       375,   -491,    -52,    -87,    153,    537,   2513,   -349,
+        47,    -27,    118,   -301,    250,     45,    191,   -150,
+       279,   2367,    -70,    191,   -301,   -206,     -5,    -40,
+      -201,   3680,    -67,     36,   -341,   -133,   -197,   -383,
+      -101,     21,    -68,  -1240,     69,     -8,     -7,    -16,
+        28,    -47,   -145,   -169,     32,    170,    246,    149,
+      3039,  -2617,    -42,    -95,    184,    -74,     71,    -56,
+       -22,    -85,   -203,    129,     97,   -105,    -91,   -304,
+         4,     93,     89,   2724,   2809,   -178,     52,   -155,
+      -152,    149,     47,    182,    124,    -75,     24,    256,
+       -38,     53,   -135,     63,     70,     59,    -59,      7,
+         6,     46,   8192,   -157,    142,     81,    121,    136,
+       -87,   -147,    -71,     59,     57,    119,     21,  -1938,
+        46,    186,    100,   -158,    -52,     34,     95,     22,
+        20,    179,    112,    116,    234,   2551,  -3012,   -167,
+       -93,   -379,    -90,     24,    208,    257,    253,     23,
+     -1361,    209,     75,    191,    -23,   -115,   2024,    264,
+        77,   -159,     77,   -219,   -237,   -154,     13,    273,
+     -3338,    122,   -205,   3796,    -96,    103,   -136,    -60,
+       115,    -81,     19,     69,    396,    225,   -280,     86,
+       329,    284,    505,    403,    -37,    203,    310,  -2587,
+     -2374,   -241,    -17,    492,    -42,    -32,    261,    112,
+       123,    -33,  -1271,   -112,    -41,     12,     82,     67,
+       -71,     56,    -10,    -83,    -28,     15,    -12,     42,
+      2292,    297,   -235,     -3,    528,    -57,    159,   -185,
+       -54,    -84,   -152,    775,     15,     54,    451,   -294,
+        53,     -2,    141,     39,    -65,     75,    149,  -5460,
+        17,    -58,   -126,   -281,    264,    151,    362,    -98,
+        62,  -2361,  -2560,    173,     42,   -290,   -161,    -96,
+       -52,     82,    130,    -86,   -150,     48,     20,    -57,
+        52,  -2263,    -96,   2662,    -66,     21,     74,    -37,
+        22,    323,     64,    270,   -141,   -599,   -300,   -121,
+       -12,   -128,    -96,     -3,   -129,  -4339,   -293,    -55,
+        31,    -82,      8,     82,    -20,     58,     15,   -238,
+       140,   -125,    -98,   7632,    -14,     96,   -129,    -12,
+       -39,     85,      0,   -104,   -225,     24,      3,     95,
+       -87,    115,    168,     19,     22,     95,   8056,     36,
+       -12,    106,    -99,    -15,    -87,    112,   -122,     55,
+        14,    282,    -31,     80,     42,     -4,     81,    -73,
+        74,    -10,     82,     35,    173,    -20,    -40,  -8192,
+       -35,   -386,    270,    263,   -231,   -142,     42,   -445,
+       204,    177,   -330,   -859,    715,   2731,     59,   2578,
+       220,   -478,      3,    410,    -47,     61,   -214,   2765,
+      -206,    174,     56,    427,    442,    118,   2708,    -66,
+       -40,     41,    119,    -65,    -71,    -21,    124,    106,
+       -18,  -2586,    -35,    106,   -364,    286,    -16,   -178,
+      -146,    -82,    157,     92,     -4,   -437,   -131,    -85,
+       -27,    -90,     23,    -58,  -5332,    115,    -69,    -25,
+       -14,     13,     52,     14,   -286,    -13,    -60,     16,
+        19,     53,     35,      7,    -21,      7,    231,     48,
+      2495,    -82,   2836,     44,   -134,    -76,     33,   -394,
+        47,   -124,   -175,     95,    103,    161,     57,    -37,
+       174,   -499,    131,   -394,   2007,  -2596,   -481,    294,
+       152,    601,    144,   -438,    109,   -204,    317,     37,
+       362,   -153,    216,    269,    -39,   1250,    505,    505,
+      2571,   -115,   -595,   -806,   -998,   1226,    -71,     26,
+       -67,    262,     51,   -161,    183,   1622,    -32,    233,
+         3,   -217,     19,    -16,    209,     51,     40,    -40,
+       -43,    -27,  -7227,     13,   -128,    -18,     82,    154,
+       133,   -121,     33,    -66,      8,   -102,     71,      8,
+      2780,    -43,     79,   3212,   -282,   -165,    125,     78,
+      -101,    -59,     59,   -136,    308,    -61,   -295,   -241,
+       -29,     27,   -326,   2932,   -563,    308,   -269,    -34,
+      -158,    -26,    -64,   -411,    -75,    420,   -294,   -239,
+       -11,    429,     44,     36,     69,   -200,    -56,    279,
+        80,   -218,   -294,   -294,    252,     64,   7793,      7,
+      -155,    -56,  -3118,  -2749,   -178,     62,    441,    105,
+       -45,     23,     23,   -101,   -109,    -26,   -149,    566,
+       -29,   -394,   -850,   1699,   1986,    243,   -665,    565,
+       155,  -1746,     96,   -344,   -651,    387,   -363,    283,
+       241,    101,     71,    -18,     -9,     43,    114,    -22,
+         9,   -109,   -119,    -92,    117,   8192,    -67,     87,
+       174,    -42,   -195,    527,   -155,   -195,   -167,  -1619,
+      2638,   -824,    121,     44,    138,   -808,    407,    584,
+      -217,    -90,   -278,    549,   -118,  -1278,    837,    220,
+       142,   -956,   -294,     89,   2627,    269,   -129,    253,
+        10,     15,    167,    163,     87,   -262,     89,     48,
+        14,     24,   2967,   -175,   2550,     51,     11,   -152,
+      -111,    230,   -267,    -79,    321,   -641,    507,    -32,
+       -20,   -238,     23,   -322,  -2506,    173,   2205,    -91,
+       -21,  -1594,    420,   -157,     97,     64,    126,    -38,
+       -84,     10,    -85,     93,    -21,    272,   -427,     30,
+       -60,     61,    -81,    -40,     27,     18,    -29,   -208,
+       -70,  -8192,     16,     15,     53,     34,     49,    -26,
+     -2512,   -152,     23,    -77,   3015,     87,   -164,    247,
+       119,     91,    444,    -43,   -166,    -26,    253,    -93,
+        50,    408,  -3274,    913,    104,    119,     17,    -54,
+        42,     19,   -294,   -298,   -416,    -82,     38,   -263,
+       137,    132,  -2609,    -44,   2783,    -34,     -9,    266,
+         8,     18,   -183,    520,    515,    -93,   -159,    -21,
+       186,     27,    -89,    137,     77,    -60,    -33,     34,
+     -5115,    -44,   -172,   -122,     -9,   -104,     69,     16,
+        94,   2813,   -200,   -142,    -50,    375,   3276,   -272,
+       -44,     47,    -41,   -188,    263,   -237,    -24,    312,
+       120,   -326,    823,    193,    410,    -95,    356,    565,
+       296,   1202,  -2737,   -968,     87,   -204,  -1329,   -826,
+      -827,    584,    194,    -31,    -12,   -109,    -39,     -7,
+        73,     29,     24,    -12,    256,    -98,    -46,     63,
+       207,     -8,     73,   -342,   4578,    -37,     60,    -66,
+         8,    -39,   -176,   -125,    -34,     57,   -141,    -52,
+       -39,   -128,    -50,   -143,    -85,   -107,     19,    -38,
+        74,    -40,   -161,    -54,    -63,  -3452,    176,    116,
+      5274,     19,    -42,    198,      3,     33,     80,    -99,
+      -111,     11,    -90,     97,     -6,     -3,    -52,    301,
+      2335,    148,   -171,    -88,     44,   -404,    124,      4,
+       -80,    189,   2838,     62,   -247,    394,   -230,    -91,
+        92,  -2587,     84,   -139,    -31,   3014,     25,    201,
+      -137,    -64,    383,      2,    -70,   -115,   -210,     43,
+     -1111,   -403,   -379,     -9,    243,     77,   -220,    -60,
+       -38,    -15,      7,    109,     41,    143,     56,   -211,
+     -2492,    -48,   -218,   -115,   -321,   -358,    388,    -10,
+      -172,    -52,    177,   2996,    -96,    480,    -23,    -15,
+       177,   -225,    217,     10,    367,    129,    -45,   -114,
+        23,    257,    -48,   2497,    236,     12,    197,    245,
+        19,   -173,   -321,    310,    406,   -280,    -72,   -279,
+        73,   3307,    245,     78,   -186,   2928,    264,    263,
+      -227,     50,    172,     91,    293,     24,   -148,   -245,
+       -61,    219,    -88,    169,    220,    -99,   3222,      3,
+         0,    103,     19,    116,     69,   -180,     -7,    -49,
+        26,    -59,    -93,    -68,    123,    357,    241,  -3308,
+      -297,    198,     40,    -80,    285,    161,     90,    -46,
+      -165,    -32,     87,  -5676,    254,    -37,      7,    -20,
+};
+
+static const int16_t cb1616sl1[] = {
+        73,     78,    -64,     76,     17,   6250,     -4,   -167,
+        52,      4,     -3,     11,   -189,    -19,   -136,   -220,
+        15,      6,   -420,  -2205,     38,  -2944,     16,    118,
+      -116,     61,    119,   -390,    217,    548,     24,    161,
+       -24,  -2342,   -148,   -159,  -2783,    225,    401,   -226,
+       210,    643,   -366,    240,    264,    167,    115,    827,
+       -39,   -161,     30,   -173,     42,     29,     98,    377,
+       -58,   -163,    -41,     27,     25,   4368,     87,  -2836,
+      -175,    -71,    -62,    -84,   -476,      4,   2466,    113,
+     -2830,   -916,    593,    276,   -356,   -427,   -686,   -215,
+      2752,    395,     -9,   -345,    117,   -122,   -327,     92,
+       107,   -106,     32,    270,    271,    171,   3138,    198,
+       -46,    -70,     46,    502,     91,     77,    -19,    216,
+        94,    122,    -64,   -392,    -31,  -2696,   -364,   -131,
+      -315,    129,   -461,    229,    192,    236,    185,   -263,
+      -173,     44,     24,   -267,    -40,   -177,   -149,  -2471,
+        26,    113,   -183,  -1693,   -188,     48,     22,    -73,
+        50,   -133,     58,    -70,   -173,   -308,   -442,   -188,
+        92,    389,    -35,    167,    235,     66,   2593,   2435,
+       244,    630,    -22,    235,    112,    -32,    533,   -158,
+        81,     71,     44,    -59,   -158,    -23,     28,   8192,
+       -58,   -181,     39,    220,    -54,   -124,    -59,   -277,
+        71,     41,    -82,   -157,  -6860,     -4,     44,    -84,
+       -48,    134,   -193,    159,    -45,    218,    -47,   -133,
+       147,   1749,    765,    -84,    184,   -317,   -286,    -17,
+      -340,   -262,   -244,    -21,   3122,    290,   -127,   -119,
+       179,   -128,   -125,   -439,   2766,   1917,     85,     57,
+       -32,    373,    -16,    170,    -74,     31,    425,    626,
+         1,   -511,     64,    387,    142,   -621,    183,   -224,
+       220,   1195,    386,  -3360,    332,    484,  -1112,    -96,
+       187,     43,   1838,     39,    -36,     13,   -132,     -8,
+        -1,    -43,     29,   -132,    -19,     10,     10,   -218,
+     -3659,    119,   -103,    -27,    -29,   -108,     13,    181,
+        39,   -117,     92,     37,    -17,   -198,    330,    538,
+        17,    113,   4758,      1,     28,    -10,     87,     22,
+        96,    -14,    -99,    -56,   -130,      0,    -55,     45,
+       -63,  -2845,   2751,    464,    -31,    -62,     76,   -154,
+        88,     81,    125,    373,   -348,    587,   -314,   -278,
+       -53,   2039,   -516,   2437,    191,   -212,     87,     -2,
+       181,   -242,    117,     23,    -63,    334,    145,    454,
+       343,   -235,     91,     69,     -8,      2,   -106,   -108,
+        -5,    137,   -168,  -7818,   -231,     25,     37,     75,
+      -138,     56,    142,   -596,    130,   -114,   3293,   -366,
+       290,    160,     -2,   -219,     83,    843,    -18,   1289,
+      -177,    226,    667,    252,   -683,    816,     26,    157,
+       168,   -487,    -49,  -3282,    432,    184,   1207,     23,
+       164,    544,    965,     -1,     61,   -118,     92,   1359,
+        89,  -3234,     15,    496,    244,    177,   -613,   -160,
+       -23,   -195,   -111,   -372,   -115,    278,     96,     77,
+     -2567,     49,   -423,   -468,     13,   -484,   1345,   -298,
+       194,   -123,   -248,   -139,    738,    102,   1154,   -335,
+      2694,   1326,    213,    758,     17,    154,    609,   -518,
+      -367,    201,   -144,     61,     66,   2288,     50,   2688,
+       -87,     45,    -13,   -101,    127,   -190,    -40,   -286,
+         6,    121,     32,     31,    119,    -85,     28,     93,
+      8192,    273,    169,     44,     37,    255,   -224,    219,
+       -34,   -127,   -134,    165,    169,    126,   -188,    -52,
+        98,     15,  -5820,   -193,   -331,   -395,     -1,     49,
+      -187,     55,   -121,   -196,    114,     10,    258,   -145,
+       -14,   -385,    105,   -187,     59,    383,   5322,    147,
+      -110,    -69,    378,    138,   -352,    -69,     15,   -267,
+        75,    162,     -6,   3148,    515,    231,    -74,   -436,
+      1288,   1234,   -105,     68,    -96,   -166,    -49,    -64,
+       144,    -67,    135,    258,    -71,   -162,    156,   -366,
+        -7,    -67,   -133,    -20,   -119,     71,    -84,     31,
+        26,    116,  -2237,    212,     43,    380,    -74,     13,
+        -7,    774,  -1276,   -103,   -124,    -48,   -178,   -319,
+        26,    435,   -111,    858,    295,   1601,  -2727,   -242,
+         8,     36,    -61,    -20,    -19,    -19,     31,    258,
+        21,    -14,    381,   -153,  -8192,    -99,    327,     72,
+       175,  -1181,   -271,    104,    -30,   -135,   -169,     21,
+        29,   -182,    -25,    125,    165,    -82,     73,    -26,
+      2311,    -85,  -2983,   -125,     85,   -206,   -100,   -100,
+        36,     -3,    -77,   -180,     35,      0,   -170,    123,
+       168,   -302,    366,   -334,   2936,    -70,    404,  -2870,
+        13,     79,    226,   -163,   -242,   -124,    -40,   -171,
+      -109,    189,     20,    -52,    144,  -1869,    -88,    230,
+        -8,    -27,     45,    131,    -11,   -188,     93,   -227,
+      -452,   -229,    158,    377,     -9,  -1736,     16,   3268,
+      -164,     41,    305,   -414,   -642,   -111,   -100,    118,
+      -155,   -236,    936,   -114,     51,     31,     60,   1299,
+         5,   3048,    274,    273,   -197,   -289,   -245,   -288,
+      1927,     -7,     27,    307,    174,   -243,    -95,   -134,
+        14,     24,   -119,   -132,  -2811,   -254,     35,     95,
+        22,    135,     21,   -155,    -80,   -143,    -60,     -6,
+       182,     77,     11,   -197,     -8,  -6080,     28,    155,
+        11,    -27,     22,    -48,     -8,    -50,   -122,     11,
+       -34,    342,     -1,     40,   -208,    117,    -35,    -69,
+       150,  -3944,   -425,     46,    456,    182,   -451,   -219,
+        38,     15,   -203,    766,   -232,    243,    -70,    179,
+      2107,   -222,    346,   -166,    143,    239,    245,     59,
+      -137,     17,    475,    -68,   2679,   -423,     20,   -313,
+        74,    152,    171,   -269,     68,     39,  -4743,     94,
+        -3,    110,    134,   -168,     73,    180,   -116,    276,
+       -74,   -203,      2,    -83,     17,    170,     96,    169,
+        75,  -5541,     46,     20,   -168,    -22,     35,    -74,
+       104,   -153,    264,      4,    -57,     94,   -192,    161,
+        15,      7,     45,   -186,     15,   -125,    121,  -4981,
+      -254,    179,    282,     72,    543,    -97,    363,     -5,
+       -67,   -389,    -66,    178,    427,   -276,  -2675,    447,
+        -2,   -125,   -223,   2869,   -502,    117,   2017,    -71,
+        41,      9,    124,     19,    357,   -562,     25,   -385,
+        80,    -53,   -175,   2532,    -73,  -2990,   -164,     57,
+      -128,   -254,     53,   -150,   -180,     16,    -45,    322,
+       266,  -2418,   -264,    317,    371,      5,    197,      7,
+     -2476,    -93,    152,     90,   -165,     11,   -259,    -24,
+       -55,    -16,     98,  -4904,   -116,     53,    205,    -45,
+       -57,    116,     75,    161,    -55,     97,   -292,     27,
+     -1396,    105,   -127,    133,   -265,    -33,      5,  -3622,
+        25,     -3,   -104,      8,   -283,   -229,    236,   -208,
+       145,    627,   -240,    118,    296,    108,   -309,     48,
+     -3345,    582,    498,    259,     20,    785,   -138,    421,
+        97,    370,    161,    141,  -2793,    106,   -246,   -140,
+      -172,     42,   -194,   -202,   -319,   -107,    -24,    423,
+      7293,   -109,    -13,   -242,     55,    171,     13,    -93,
+       131,   -141,     88,    132,     76,    176,     78,    153,
+       -63,    -55,   -410,    -39,      6,     27,   -223,   -174,
+        61,    645,    167,    -35,   3079,   -173,    950,      1,
+      -109,   -118,   -106,     15,  -1345,    -14,     50,    -70,
+       -69,     24,    109,    182,     84,     31,   -179,    -93,
+     -3152,  -3013,    -60,     56,    -60,     58,    166,   -161,
+        24,    129,      1,    181,    128,    -12,    273,    -43,
+     -1256,    134,    159,    -36,    175,     43,    -49,     41,
+        48,    -38,    -45,     59,    -36,    -82,     48,    -74,
+      -104,   2944,   -124,    -24,     98,    248,   -146,   -231,
+      -241,     72,   -114,    776,   -498,    242,   -357,    250,
+      -102,   7121,    109,     11,     94,    -53,     37,    -37,
+      -133,     24,   -157,     47,    -46,    -69,     62,    -79,
+};
+
+static const int16_t cb1616ss0[] = {
+      1401,    373,   -516,    330,   -711,   -752,   -475,   -224,
+       139,    492,   -556,   4629,   1039,    333,    872,   -542,
+       474,   -360,   -378,  -3459,    254,   1199,    113,   -525,
+     -1705,    231,     46,    188,    -50,  -1038,     32,   -198,
+      -109,    619,   1071,  -1601,   1002,   -411,   -189,  -3276,
+       615,   -468,   -467,   -275,  -1286,    736,    541,  -1107,
+       423,    191,    439,   -205,     17,    -87,    500,    176,
+       262,   -341,   -142,    268,   8164,     -2,    112,   -190,
+       227,    -50,   -143,   -326,    647,    601,    482,    443,
+      2761,   -497,    979,   -298,    454,  -2927,    746,   -735,
+      3921,    480,   -167,   -317,   1303,    111,    216,   -961,
+       110,   -595,    244,    246,   -222,   -205,     46,     61,
+      -798,    258,    360,  -7038,   -654,    -95,     75,    498,
+       -24,   -250,     71,    138,    527,    240,   -215,    250,
+      -408,    552,   -325,    333,   -989,   2648,   -483,  -1121,
+      2344,  -1647,   -116,   -901,    615,    327,      1,    497,
+       411,   -138,    332,    281,   -145,    337,    163,  -7379,
+        70,    265,    365,    238,    604,     99,   -149,    233,
+       109,    827,   -704,   1367,   1208,   -717,    -17,   -223,
+        15,  -3259,     53,   -485,   -631,    285,    511,     -8,
+       242,    547,    129,    145,   2046,    520,     44,   -177,
+       382,    283,   -169,   -346,  -2737,    294,  -1311,    145,
+      1873,    815,   1078,    677,  -3419,   -434,    484,    144,
+       -27,    669,    153,   -242,   -242,    814,    350,    361,
+      -462,    -63,   2317,   1259,   -373,   -489,   -534,    300,
+       867,   2621,   -117,   -168,   -414,   -239,    812,    840,
+       112,   -463,  -6286,   -693,   -830,    140,   -168,    448,
+       549,   -149,    418,   -105,    137,     31,    -40,    -43,
+       422,    -99,    297,      3,   -220,    -15,     81,     45,
+      -647,   -535,   -448,   -731,    250,  -6742,   -320,   -350,
+      -192,   1540,  -1112,  -1043,   1317,  -1203,   1035,   -506,
+       673,    721,    854,  -1487,    780,   -294,   1173,   2142,
+     -8192,   -170,   -138,    -54,    -54,   -233,   -127,    145,
+      -233,   -185,     87,     20,    530,   -305,    141,   -394,
+       310,     40,    645,    809,   4801,   -186,   -432,   -451,
+       312,   -144,    -65,     65,    135,    -64,    -15,   -357,
+     -3546,  -1299,    216,    249,    261,   -207,    117,  -3138,
+       527,     14,   -142,    286,    100,    340,    581,    157,
+       234,    739,  -2521,     -3,    639,  -1440,    131,  -3796,
+       159,     39,     41,   -659,    284,    165,   1100,   -346,
+      -481,    295,    806,   -227,   -288,   4520,    253,    487,
+      -252,     88,    -43,  -1612,     -5,    -57,    -66,     18,
+        19,    557,   -337,   1526,  -2897,    144,    844,   -404,
+      1976,    787,    246,    264,   -406,    778,   -918,     51,
+      -113,   -235,    518,    602,   -307,  -2046,   -692,   2775,
+       400,  -2165,   -184,    139,    403,  -1855,  -1317,    289,
+       710,   1124,   1888,   -517,    276,    190,    637,   -441,
+       717,    972,   -370,    478,    626,   -354,    241,  -3651,
+       145,      7,   -738,    397,    991,   -343,   -826,    142,
+       672,   2425,   -616,  -3278,    751,   -193,   -944,    -35,
+     -1061,   1258,    631,   -721,    145,   -112,    -69,    828,
+       -39,   -196,   -237,    -73,    771,   -195,    239,   -533,
+     -1673,   3477,   -559,    104,   -647,   -798,    167,   -497,
+      -559,    591,    259,    300,    -25,    422,     93,     39,
+       -63,    233,    144,  -1170,    142,   -456,     73,    411,
+      6920,   -338,   -307,    436,    143,    420,    152,     -9,
+     -1788,  -1096,  -2998,   -727,   -524,    128,    460,    782,
+      -102,   -576,   -138,   -976,   1035,  -3196,   -436,    -27,
+     -1047,  -1389,   3244,   -143,   -883,  -1012,      4,    327,
+        16,    411,   -497,   1444,    516,   1183,    252,    510,
+      -698,   -676,    569,    -70,   -397,   -227,   7829,    312,
+      -410,     20,     41,    -65,   -219,    175,    297,     40,
+     -1534,   -498,    194,    871,    409,    280,   1098,  -1471,
+     -2825,    931,   -105,   -545,   -801,   -795,   -372,     73,
+       331,    100,    488,  -2101,    560,     44,    885,   1065,
+       380,   -195,    276,    124,    -87,    193,   3979,     30,
+        95,   -509,   -931,   2737,   -457,    805,     10,     53,
+       -73,   -203,   -587,   -177,    242,    238,    656,  -3403,
+      -380,   2364,   2902,   -226,    204,   1559,  -2219,    -40,
+      -442,    111,   -703,   -424,   -252,   -241,    461,    749,
+       658,   -481,    125,   -366,    601,   -246,   -286,    132,
+       297,   -232,   5231,   -141,    196,   -121,   -235,    406,
+      -199,   -174,     87,   -107,    363,    272,   -563,   -620,
+       235,    223,   -627,   -339,   -467,    349,  -1596,  -5496,
+       644,    -96,    -81,   1938,    749,   -160,  -1976,  -1436,
+     -1056,  -1045,  -1098,   2327,    976,    -57,   -124,   1139,
+       275,   -209,   -636,    298,   2484,   2764,    962,    -39,
+       108,   -718,   -442,      9,    797,   1123,   1092,   1179,
+     -1170,   -701,   -381,   -237,  -1266,  -1045,   -337,   -351,
+      -274,   -981,   -272,   -111,  -3409,   -387,    421,   -406,
+     -2123,    623,    -18,   2473,    617,    176,     26,   1402,
+     -1351,    212,     23,   -172,    296,   1572,    -63,   -402,
+       837,   -521,   2209,   -613,   -329,   -309,   -180,  -1152,
+      -535,  -1380,  -2617,    475,    385,   -672,    182,     92,
+     -2211,    320,    109,   -633,   -582,   1208,  -1536,   1009,
+       896,   1991,   -374,   1750,  -1259,   -341,   1774,   1063,
+       678,  -2084,    987,   -337,     48,   -205,    -82,   -288,
+       388,    217,   1263,   2427,  -1472,  -1073,   -964,   -836,
+      2086,   -161,    438,   -449,    -37,   -926,  -3706,    164,
+      -372,   -616,    160,   -572,   -725,    727,     11,     53,
+       -84,   7494,    -74,    523,   -172,    464,    452,   -426,
+       803,    106,   -262,     32,    298,   -491,   -181,   -760,
+      -908,    303,    747,   1316,    272,    906,    767,    105,
+       247,   6120,    948,   -557,   -928,   -595,   -342,   -450,
+       686,   -815,  -1243,   -157,    572,   1414,    166,   -229,
+      3317,   1940,   -283,    623,   -781,    717,   -212,   -707,
+        30,   3635,   1147,   -696,   -928,   -637,    925,    797,
+       843,  -1359,    214,   1096,   1031,    852,    -84,   -228,
+       -34,   1067,  -1109,    392,    292,   -755,   3495,    -40,
+     -1806,   -637,   -236,   -602,   -264,   -147,    -68,   -233,
+       -55,  -2005,   -271,   -647,    963,    309,     -5,     56,
+      -275,   -398,     34,   -496,   2556,   1249,    -87,   -112,
+      1663,   -554,  -1926,    627,   2515,  -1128,   -566,   1539,
+       740,     38,   -614,    272,   -232,   -152,   -782,   -420,
+      -304,  -2313,    -33,   -944,    -77,  -3468,    -69,  -1730,
+       -21,    665,   -314,  -1640,    660,    661,    106,    -21,
+     -1505,  -2888,   -427,   -866,   -666,   3128,    786,    -55,
+       739,    112,      8,    567,   -602,   -350,    165,    108,
+       767,     64,   -715,    980,    673,   -186,    768,   -545,
+      -298,   -233,   -524,    -70,    511,  -2051,   3816,  -1104,
+       529,   1012,   2577,    777,    342,   -387,   2730,    247,
+       -20,   -227,   -432,   -263,   -885,  -1192,   -644,   -259,
+      2314,     38,    108,    614,   -386,    470,    -78,    681,
+     -3334,  -1049,   -300,    177,   -174,   -422,    110,   -641,
+      -406,   -472,    468,    885,   -730,   -877,  -1972,  -1372,
+      -410,    545,    543,   -800,  -1156,    279,   3290,  -1305,
+      -213,   -262,   -832,   -994,  -1110,    718,   -364,   1416,
+        -7,    963,    452,    680,    165,  -3815,    903,    806,
+       149,     11,  -1332,   -622,   -451,    152,   -618,   -309,
+       246,    435,  -2098,    487,    469,   -451,  -1574,   -204,
+      -187,    552,   -333,    515,   -331,   1452,    278,  -2691,
+      -146,   1009,    353,   -839,      6,  -3206,  -1080,   -572,
+     -2698,    752,  -1726,   -318,    397,   -152,   -128,    -77,
+       -36,   -506,    456,   1094,    281,   -158,    -19,   -149,
+        48,  -2831,   2042,   2545,   -161,    619,   1129,    274,
+        24,      1,    313,   -164,    655,    157,    770,    182,
+      1942,    241,   -898,  -1748,   -589,    256,    322,    683,
+       -65,    -73,    621,     74,   -317,   2585,    185,   -465,
+};
+
+static const int16_t cb1616ss1[] = {
+     -3218,   -607,   1665,   1100,   -563,    421,    377,    445,
+      -270,     -3,  -1503,    224,   -593,   -316,     31,    362,
+      1186,    389,  -1817,    589,  -2842,    289,  -1925,   -356,
+      -228,   -148,    618,    135,    358,    238,      1,   -767,
+      -266,      1,    101,    245,    231,   -167,    408,      1,
+       162,    -35,    241,    215,  -4702,    486,    546,   -339,
+       349,   -292,   1342,   -881,    184,   -675,   2639,   -284,
+      -995,    346,   -499,   1499,   1616,    578,    445,    -78,
+       844,   1800,   -686,   -414,  -1425,    795,    754,  -1418,
+      -178,  -2226,    515,   -143,     43,    569,    967,  -2333,
+     -1991,    282,    528,   1410,   -377,    736,    394,   -230,
+      -365,   -242,   2773,    136,   -738,    -36,  -1171,    -76,
+      -132,   -300,   -223,   -680,   -416,  -2738,     93,    414,
+       490,   -346,     75,  -1089,  -1132,   2237,   1844,    395,
+       325,  -1514,   1913,  -1850,   1162,   -442,    689,    -66,
+       -71,    -83,    342,   -197,   -940,    206,  -3381,  -1275,
+      -423,    -87,   -455,    498,    865,    355,   1225,   -115,
+     -3333,   -404,   -588,   1021,  -2180,  -1470,   1225,    728,
+        59,   2592,   -335,    194,   -649,   3586,   -951,   -142,
+      -947,    898,    -99,   -269,    977,   1520,    488,   -364,
+      -253,    127,   2524,    849,  -1166,   -191,    627,    372,
+       772,    145,    -21,    279,    402,   -863,  -2695,   1217,
+      1543,   1005,  -1419,   1712,    110,  -2191,    969,   1563,
+       183,    811,   -218,  -1078,   -220,  -1092,   -322,    803,
+      -533,   -359,    405,    -70,   -771,   -267,  -4730,    235,
+      -607,   -387,   -285,    -68,     48,    -60,   -222,    229,
+     -1087,  -1261,  -2249,   1265,  -1624,    864,    -65,    223,
+      -322,    337,   -262,  -3170,    -12,   4571,     19,    198,
+       458,  -1029,   2560,     -3,   -115,    619,   -645,   -836,
+      -399,    246,    -81,    -12,  -1057,  -2119,   2780,     25,
+     -1559,    291,    592,   -513,     62,    157,    553,    570,
+      -657,     72,   -118,   -284,   -454,   3853,    145,    259,
+     -1709,  -2161,  -3167,    189,   -233,  -1099,    141,    114,
+      -506,  -1012,   -775,    474,    331,    798,    469,   1915,
+        96,   -266,   -385,   -329,   -658,    192,     16,     97,
+       -47,    284,   -163,    200,    189,     18,  -7453,    160,
+     -2988,   2725,    520,   -132,   2593,    627,   -694,    -26,
+      -558,     44,   -209,     40,    377,    491,    -68,    384,
+       271,   2117,    642,   3166,   -569,    702,    513,  -1858,
+       108,    944,    248,    166,    681,    408,   -908,    525,
+      -145,   1035,    189,   2812,    135,   -356,  -2551,    401,
+       150,   -508,   -265,    244,    461,    958,   -233,   -204,
+       744,  -1603,    397,   -229,   -174,    539,   -139,  -4473,
+       837,   -310,    253,   -635,    397,    -80,    601,   -371,
+     -2015,   -261,   -364,     50,    331,     89,   -938,    709,
+      1444,  -2910,   -228,   -162,    419,     62,   -319,   -266,
+       584,   3728,     57,    220,   -543,    768,   -630,    361,
+       361,    642,   -313,    182,   -488,    -48,   3001,   -397,
+       640,    179,      8,   1081,  -1161,    -58,    -70,    -64,
+      4456,    323,    883,   -191,    -16,     61,    419,    429,
+       627,   -898,   -883,    750,    499,  -1335,   -467,  -1410,
+        -5,    283,   -301,    276,  -1636,    310,    114,   -428,
+     -8192,     12,   -114,     74,    215,    511,    317,   -314,
+       -86,    198,    138,    315,   -271,    246,   -363,    426,
+       608,   -714,    367,  -1356,  -2217,   1178,   -385,   1442,
+        28,   -642,   -371,    -87,  -2895,   -710,    303,   -150,
+      -398,   -868,  -1727,   1548,    982,   1177,    332,   -377,
+      1580,    962,  -1028,   1922,   1494,   -824,     93,  -1362,
+      -552,   1641,  -1729,    228,   1054,    421,   -185,   -536,
+        51,     87,   -204,     88,   -847,   -754,  -3761,  -2706,
+      -138,  -1242,     35,     64,    418,   -460,    713,   3960,
+       733,    468,   -150,   -823,   -211,   -674,    366,   -269,
+       180,   -294,   -384,    604,   1829,   -121,    271,    241,
+       192,   -211,  -2672,  -1483,  -1102,    960,     90,     49,
+     -1144,   2552,   -887,    -32,   -301,     62,   -183,    193,
+        78,   -781,    193,   -606,   -285,  -3082,    240,    392,
+       704,     20,  -1103,   -195,    166,    577,   -105,    -45,
+      -310,   -106,   3035,     28,   -369,    725,     53,     87,
+      -232,   -191,      7,   -282,   -572,  -8192,    325,     99,
+       162,   -113,   -237,   -209,    412,   -573,    295,   -389,
+     -1603,    -66,   -485,   -867,    466,   -882,    862,   -216,
+       221,     50,    -51,   3927,    557,    441,    223,    234,
+      4048,   -173,    420,   1670,    436,    341,    175,   -441,
+      -201,     75,   -549,    315,    172,    418,   -159,      7,
+      2973,     -3,   -220,  -1360,     26,   2781,    132,    295,
+       -15,    217,   -166,    187,   -282,    357,   -121,    480,
+      -216,    294,    263,     95,  -7367,    589,    -63,   -412,
+      -103,   -201,    335,    -96,   -203,    240,    223,   -435,
+       366,   -467,    118,    528,   -472,   -559,   -417,   -189,
+      -641,    339,   1546,  -2741,   1413,   -265,    637,  -1556,
+       -49,    422,   -195,    392,    -21,      3,     -2,    282,
+      -130,   -272,   -483,   -860,   -675,    762,  -1455,   5212,
+       178,    197,   -468,    270,   -310,   1038,    406,   2699,
+      -537,    -33,    272,    225,  -1986,   1295,   -857,  -2906,
+      -904,  -1861,   -206,    866,   -145,   -207,    252,   -825,
+      3051,  -1361,   -441,     85,   -186,   -127,    139,    285,
+      3067,   -332,   1163,    248,   -483,   -177,    268,    691,
+       733,   -104,    -54,   2541,  -1042,   -226,    165,    250,
+         7,   -259,   -383,    327,   2164,   2272,   -750,   2482,
+      -930,   -139,   1203,    766,    150,    320,    970,     28,
+     -1351,    467,    544,    521,  -2908,    -75,   -902,    611,
+       575,   1216,   -209,     -7,    541,    330,    528,    347,
+      -185,   -306,   -432,  -3384,  -1844,   -380,    155,  -1230,
+       629,  -1085,   -413,    119,    114,   1093,    198,    806,
+       491,   -137,   -518,    536,    -64,    387,  -1712,    608,
+       -24,   4961,    149,    299,   -342,    505,    503,   -387,
+      -944,   -297,  -2423,    -98,  -1027,   -432,   -259,    736,
+       127,   3561,   -473,   -623,   -751,    114,   -438,    657,
+      2448,    863,   -413,    -81,   2066,    988,   -539,   -528,
+      -111,    314,    390,  -1228,   -863,     19,    763,   2227,
+      -844,    -24,   4164,    139,    130,   -111,   -630,   -428,
+       538,   -606,    940,   -877,    122,    526,    194,   -104,
+       127,    117,    907,   -789,   2865,    526,   -548,   -253,
+       289,   2329,    176,    -70,    775,    681,     21,     38,
+     -1481,    766,   2093,  -2974,   -289,   -571,   -445,   1833,
+       333,    -84,   -243,   -413,    188,   -492,    -22,   -867,
+       605,   -333,    904,   3192,    -29,    491,   -411,    370,
+      -556,  -2671,   -294,    132,   -243,   -233,    180,    181,
+       383,    -79,     26,  -3539,    642,   1127,  -2125,   -170,
+      -386,   -135,   -703,   -290,   -157,   -444,   -885,   -341,
+      -920,    460,   -407,   -176,   3153,  -3084,   -505,    543,
+         7,     79,   1191,   1148,   -401,    -17,    289,   -735,
+       300,   1971,    626,   -146,    110,  -1281,   -613,   -649,
+      -206,   1850,    701,   1138,   -803,    742,  -1392,    147,
+       554,   1861,   -658,  -1481,    108,    856,   1021,    574,
+      3314,    518,  -1156,   -307,     42,    -92,   -132,    278,
+      -352,    -37,     35,    146,    -93,   -662,    216,    125,
+       823,   -876,   -170,  -5027,    444,   -182,    844,    189,
+      -490,  -1441,   -335,   -907,   -173,   1138,   -472,  -1505,
+     -1641,    648,     66,    627,     64,  -1096,   -620,   1588,
+      -506,    309,   -100,   5702,   -555,   -157,   -179,    -85,
+      -299,   -114,    -20,    178,    415,    118,   -581,   -132,
+      1025,  -2631,  -1154,   2623,   -286,    201,    340,    949,
+       235,    171,    649,    328,    397,   -142,   1369,     -7,
+      2305,   -373,    658,  -1681,   -744,  -3574,     34,   -183,
+      -504,    165,     81,     21,    635,   -307,    428,   -520,
+       164,  -4701,    744,    249,   -844,     -7,   -334,     38,
+       539,    267,   -213,     73,    134,   -251,   -248,   -923,
+};
+
+static const int16_t cb1616sm0[] = {
+     -4119,  -2861,    -76,    -49,   -192,   -542,      0,     94,
+      -550,      6,    601,    236,   -446,   -202,    167,    238,
+      2609,   -688,   -406,    265,  -3078,    321,     59,   -601,
+       157,    200,   -265,     78,   -699,   -679,     18,    -54,
+       203,   -687,   2683,   -111,  -3037,   -627,   -493,    413,
+      -480,     54,     75,    276,    206,  -1861,     17,   -420,
+      -169,    312,    361,   -277,    -12,   -363,   -592,    758,
+      -123,   3267,     78,   -862,     81,   -356,    596,   -536,
+       729,   2239,    -49,    553,    112,    444,    652,  -2990,
+       -70,   1084,   -436,     34,     53,    -10,    -23,     41,
+        -3,   -126,    207,   -130,   -208,     63,    480,    191,
+      6229,    -45,    -33,    -82,     35,     56,    259,      1,
+      8034,    -97,     52,   -159,   -334,    -41,     50,    -57,
+        56,   -194,   -567,   2050,    146,    987,   -383,    416,
+      -258,   2846,     51,      8,    690,   -126,   -704,    316,
+        16,     -4,    -90,    159,     34,    126,     65,    218,
+     -7037,   -261,    -87,    -21,   -185,     14,    112,     42,
+      -164,    274,   -269,   1138,   -208,    574,    589,   -143,
+      -479,   2745,    782,    -13,  -2492,   -132,    498,   -406,
+       260,    828,   -580,    558,  -2861,   -600,   -447,   -313,
+      1316,    800,   1772,   1131,    323,    -48,  -3972,    697,
+         5,   -403,     46,     95,    130,     84,    -39,    219,
+       117,   1629,   -189,  -1371,     25,   -116,   2311,   -681,
+      -411,   -685,  -1340,   -409,    223,   -462,   2530,   -816,
+     -1118,    314,   -893,   -109,   -262,    376,  -2795,    -48,
+     -2878,     -6,    180,     53,   -500,   -181,    125,   -291,
+      -265,   -154,    -23,   -184,    185,   -563,  -1159,    675,
+        24,   -213,    273,  -2905,   -242,   2373,     -6,   -166,
+        92,    276,   1375,    -28,   1879,   2572,    205,   -121,
+        51,    356,   -873,   -308,  -1060,    952,    719,    456,
+       106,    116,   -107,   -211,    -21,   3319,   2109,   -172,
+      -172,    143,   -718,   -138,   1135,    232,  -1361,    157,
+       -99,    522,  -4367,     84,    605,    319,   -937,   -397,
+       117,   -434,     82,    633,    274,  -1555,   -221,    -59,
+     -2419,  -2486,   -112,    136,   -182,   -480,     27,   -548,
+      -237,    817,    530,    656,    252,  -2685,    -26,    703,
+     -3268,    381,   -383,   -323,    105,   -500,     66,   -299,
+     -1056,   -363,    -69,     21,    292,    398,   -379,   -106,
+      -356,     38,    169,   2866,    206,   -523,   -277,  -2875,
+      -582,    -69,    649,     -3,    198,    -30,     98,    145,
+      -125,   -186,    -19,   -107,   -102,   -173,  -7299,    -62,
+      -503,   -231,     24,    145,   1367,   -355,   -175,    373,
+      -953,   -704,  -3454,    170,    899,    386,    592,   -754,
+       620,     81,     86,    -65,     84,    683,   3054,   -280,
+     -2825,   -757,     53,    -10,    441,   -145,    138,   1364,
+        -2,    -92,   -300,    225,   -199,  -2087,   1095,   -363,
+       -75,    288,    765,   -869,     -7,   3261,      9,  -2860,
+      -330,   -382,   3309,     28,    629,    244,   -143,   -298,
+      -512,   -409,   -241,    104,     -6,   -271,     -2,   8192,
+      -137,    139,   -304,    -14,     81,    262,    -36,     51,
+       380,     11,    101,    100,   -153,   2167,   -271,    267,
+       306,  -3008,    579,   -277,    316,    327,   1168,     71,
+     -1401,    389,    -25,   -265,    101,    -53,   -170,   -226,
+      2861,    145,   3040,   -159,     77,    -16,    233,   -570,
+       490,    661,    452,   1986,   -522,    212,   -107,    196,
+      -247,    308,   -353,    186,  -2689,    486,    -46,    813,
+       -24,    233,   -166,   3305,   2832,   -343,    -82,    475,
+       267,   -385,     26,    -35,   -226,     27,    416,    231,
+        12,     88,   -209,   -139,    404,   -239,   -109,   -182,
+      -851,    260,    242,    109,     11,  -1096,     85,  -4226,
+      -124,     12,   -139,   -100,   -604,    -87,     89,   5820,
+        59,    -43,    -84,    264,   -543,      0,    428,    -16,
+      -146,   -556,   -195,   -159,    875,     27,    261,    207,
+      -182,   2367,   -622,  -3193,    481,   -289,     52,     12,
+        34,   3014,     10,   -345,    -94,  -2883,    -62,    400,
+       249,     51,   -178,   1190,   -128,  -3940,     41,   -296,
+       -48,     13,    -26,    223,  -2392,    516,   -384,     33,
+       -46,   -161,    -43,   -224,    -89,     -4,   -349,    135,
+       540,   -120,   -276,   -198,    129,  -5113,    175,    -45,
+       -34,   -109,    419,    -45,   -104,   -185,   -393,    416,
+     -3514,    149,  -3088,   -115,    -78,    431,   -172,     21,
+      -290,   -162,    216,     41,    -56,   -487,    705,   -194,
+     -1003,    100,    172,   2793,    -83,   2584,   -189,   1198,
+       551,   -119,    -73,    -91,   2103,   -619,    124,    128,
+      2628,    192,    160,   -110,    270,   1739,   1062,   -568,
+       -73,    -56,    328,    100,    384,   -173,     83,     39,
+      -236,    -25,   -457,     53,  -6413,    345,   -459,   -110,
+        28,   -127,   -109,   -593,     32,    141,   -879,    254,
+      2132,   -410,   -623,   1103,  -2302,    528,    156,     28,
+        81,    613,    602,    171,    500,  -2356,    620,     17,
+      -523,  -2961,   -921,   -107,   -405,   -230,   -129,     18,
+       363,   -881,   1282,   1427,   -363,    658,    205,    -51,
+      2835,  -2003,    188,    -26,     73,   -231,    352,     74,
+      -490,   -222,   2423,   -341,  -2762,    -14,    -56,   -260,
+       -41,     33,    169,   -190,   1248,    -77,  -2322,   -607,
+      3610,   -104,   -200,    -90,    -81,    719,    -52,   -359,
+       394,   -301,     66,    -39,    -56,  -8192,     87,     56,
+      -291,     50,    231,    284,   -211,    -16,    -86,    -84,
+       -28,     52,      3,    -51,    304,   -224,    228,   -374,
+       458,  -1958,   -210,  -2613,    401,  -2128,   -119,    -12,
+       -60,    -14,  -8192,     53,     27,    113,    289,     -7,
+        22,     60,   -192,    333,     72,   -344,    238,    147,
+     -2235,    324,    124,    176,   -415,    450,   -476,   -558,
+      -429,   -246,   -551,   -287,    672,   2145,   8192,    161,
+      -165,    -34,    193,   -108,   -137,    -96,    -68,    156,
+       308,   -182,      5,    438,    -71,    -27,   -164,    187,
+      -110,   5786,    -82,   -130,   -126,    197,   -262,   -182,
+      -118,   -110,    121,    -93,    235,    -56,    -99,   -212,
+     -3013,   -193,    -10,  -2944,     58,   -135,   -624,   -170,
+        84,    339,    115,    -85,  -1886,    250,    123,   -104,
+      -374,  -2241,   2454,   -438,   -168,    632,   -136,   -725,
+      -329,   -394,    -60,     19,   2795,    438,   -796,    141,
+      -143,    132,    251,     37,    286,   1858,     39,   2381,
+        -9,    -85,   -110,    149,   -415,    355,   -172,     -9,
+      -149,    554,   -324,  -4931,   -537,   -261,   -585,   -291,
+       764,    -92,   -139,     -8,    -80,     65,     -6,    -26,
+       -81,     37,    -14,     45,    115,    171,   -321,    313,
+       308,  -4637,   -128,   -120,   -174,    148,    768,    490,
+        81,   -175,   -261,   -136,   1501,    345,     25,    -56,
+      -212,   -324,   -836,    207,   -652,   -752,   2406,   -332,
+       489,   -275,   -932,    284,   3103,   -315,    614,  -2711,
+      1706,  -1072,   -163,    -75,  -1104,    163,   -421,   1532,
+       -92,   -163,   -811,   -118,    -38,   -754,    466,   -314,
+       232,   -595,   3613,    -30,    570,    -62,    785,   1626,
+      1080,    553,   -407,     32,   -105,     82,   -156,    -75,
+      8063,    -67,    114,    -65,    -65,   -242,     98,   -124,
+        38,    441,  -2645,    -92,     69,     17,  -3284,   -278,
+      -278,    116,    567,   -742,    182,   -304,    432,    261,
+        86,  -4109,    389,    795,   -138,    151,    111,   -223,
+      2392,    399,   -135,   -545,    182,   -226,     61,    234,
+};
+
+static const int16_t cb1616sm1[] = {
+       -29,    -13,  -6217,   -136,   -196,     24,   -228,   -301,
+      -155,    -37,    -54,    -91,     -4,   -130,   -424,    -89,
+      -181,    657,    110,  -4526,   -391,    762,   1033,   -310,
+      -808,   -282,   -721,   -690,    258,   -259,     16,   -555,
+      2675,   -379,  -2580,    356,    198,   -455,     95,   -194,
+      -754,    383,   -263,   -873,    271,   -107,   -191,    -28,
+        11,    -66,     91,     25,   -215,      9,    152,     11,
+      -124,     66,    422,    521,   5401,    103,   -179,   -291,
+      -821,  -1265,   -396,    150,    -69,    -15,    154,   1504,
+      -445,    116,   -136,  -3528,   2819,     -5,    174,    166,
+       289,    -60,    158,   -701,     83,   -636,   -407,    194,
+      -240,   -138,    124,    -94,    132,   -105,   -106,     72,
+       139,    101,     97,  -7928,      6,    112,    164,    -83,
+      -329,     41,    124,    389,    -22,   -194,    157,   -378,
+     -2255,   -431,   3176,   -199,   -310,     49,    483,   -208,
+      -235,     11,     45,    637,   1220,   2309,     93,    514,
+     -1939,    136,    276,   -165,    137,   2496,     56,     31,
+       238,   -538,   -433,    690,   -318,    -44,    834,  -1684,
+      -132,   2619,   -157,   1959,   -566,    119,    183,    227,
+      2066,    401,    -48,   1257,    604,   1306,    149,    273,
+       586,   -199,   2166,    257,   2047,    -46,   -377,   -761,
+       -25,   -454,  -1592,    -42,    432,  -2312,    222,   -528,
+       -87,   -287,    532,   2906,  -2011,    720,    554,    423,
+      -576,    425,    280,   -894,   -232,   -179,    485,    628,
+     -2918,    405,    229,     -2,   -146,    127,   -329,   -243,
+       194,   2443,   -531,    592,    -14,   1679,    292,   -914,
+      -332,   2382,  -3040,    297,  -2856,    -88,    236,   -485,
+       438,    241,   -283,    448,    579,   -660,    277,    233,
+       201,    126,     15,   -411,   -560,   -582,   -389,   -392,
+        -7,    238,      1,    344,   -216,  -4601,   -457,   1027,
+      -114,     13,   -301,    288,    172,   -488,   -124,  -2721,
+       100,   -105,    434,    -13,   2791,   -827,   1600,   -219,
+     -4992,   -100,    411,    326,   -608,   -779,     94,    974,
+       453,  -1326,   -236,    429,   -189,    830,     32,    187,
+       459,   2489,    476,    165,   3261,   -445,    169,    179,
+      -113,    168,   -393,     52,   -383,    -33,     73,    137,
+     -6021,   -259,   -121,    -29,    -46,   -156,     68,   -225,
+       217,    152,   -280,      7,     62,      3,     17,    295,
+       221,   -158,  -5406,   -335,    232,   -454,   -320,    467,
+       -45,     96,   -170,   -267,   1273,    287,    258,    536,
+      -695,   -953,   1134,    428,    251,   3331,    717,   -804,
+       627,   1099,    120,      4,     42,    191,     -9,    259,
+      -335,   -337,    -25,    -56,    116,   -228,   -351,   -463,
+      5942,    193,   -114,    -64,   -268,    300,    146,    -15,
+       657,    367,     -2,  -2911,    838,   -251,     -1,   2897,
+       -78,   -609,   -545,   -588,    488,   1383,    486,   1820,
+       126,   2971,   -151,     11,     10,   -349,   -279,   -260,
+      -265,    142,   -683,   -191,    172,     30,   -293,  -5103,
+       -61,   -247,    -38,    722,    275,   -326,    -34,    132,
+       297,   3305,    -46,    227,  -1052,  -1114,    562,     62,
+     -1618,    699,    362,  -1624,   -455,    150,   -110,     61,
+      -266,   -168,   -168,   -391,    136,   -569,   -772,   -203,
+       467,     20,  -4747,   -170,    142,   -138,    129,   1719,
+      1896,    210,  -1008,    206,    585,   -325,    295,    175,
+     -2542,   -489,    121,    -94,    -38,  -2766,   -115,  -3206,
+      -305,    320,   -179,    503,     83,    -72,   -122,    -52,
+      -181,     98,     39,   -506,  -2751,    -93,     -1,    -59,
+      2645,    248,   -309,   -203,    138,    324,   -567,    696,
+      -493,    170,   2440,    919,   -420,  -3029,   -335,   -593,
+       -72,    536,    -82,    202,     78,    510,    184,     -2,
+       227,  -2830,     19,   1590,   -281,    387,    -46,    408,
+      -463,   -536,    262,   2214,   -115,  -1614,   -385,    203,
+        32,   -885,  -2606,   2338,     97,    292,   -449,    449,
+     -1038,   -582,      0,    -68,    211,   -160,     62,   -286,
+     -2466,   -421,    -48,   1903,  -1037,   -173,   1339,   -591,
+       152,  -1231,    792,    524,    214,    -92,     29,    181,
+      -225,   -150,     -1,    139,  -8135,    238,   -119,    189,
+        34,   -140,   -188,    141,   -112,     56,   -176,    154,
+        91,   5653,    298,   -316,    -23,    232,    -74,   -317,
+        -4,   -630,   -506,    105,  -1655,   -126,   2417,    113,
+       -95,   -472,    134,    290,   -755,    152,  -1222,    -58,
+       981,   -236,   8192,   -154,     75,    218,   -185,    107,
+       -10,     39,    265,   -225,    -87,      9,    123,   -906,
+      -382,   2544,     44,  -1985,   -102,    407,    -91,  -1835,
+      -108,    122,    142,    169,    134,   -721,  -1530,     -4,
+      -133,     45,    374,  -1049,    -76,     16,   -357,    277,
+       158,  -2596,     -4,  -1484,    -13,   2660,   -198,      9,
+      -218,    408,    -63,    177,    -71,   -195,   4293,     -8,
+       228,     34,   -421,    695,  -1409,     85,   2740,    350,
+        44,    473,    141,    -93,    144,    -59,   -220,   -154,
+      -148,   -168,   -205,   3049,    229,    194,   -107,     90,
+      -353,    508,   -343,    473,   -446,    457,   -452,   -116,
+      3493,    504,   2152,   -228,  -1832,   -463,   -657,    555,
+       657,    540,    546,    604,   2214,    -68,    254,    563,
+       267,    227,     92,   -107,    143,    260,     23,     42,
+        64,    -67,    138,   -167,     72,    457,   4958,     61,
+      -933,      1,   5341,    -32,     89,    161,    504,    823,
+       311,     11,   -184,   -574,    -79,  -1654,    -74,   -366,
+       164,   -363,    117,     53,    706,   -701,  -2966,    233,
+        11,    165,    394,    462,  -2632,    703,   -291,    -65,
+       -49,   4080,   -862,    -65,    -19,   -110,   -872,    323,
+       833,   -154,    369,    475,   2211,     20,   -212,   1711,
+       -24,    -28,    -58,     32,   1746,     41,   -779,    614,
+       508,   3050,    687,    423,   -182,   -484,    -60,    242,
+      3895,   -565,   -453,    110,    547,   -961,    320,    -34,
+      -347,  -1963,   -116,    730,   -435,    -34,     41,     26,
+       -51,   8192,   -115,    312,    184,   -148,   -199,    157,
+       153,     82,     99,    138,    -32,    -19,    -64,   -139,
+       107,     43,    133,    -87,     42,   -148,   7080,   -158,
+      -335,   -249,    -64,     81,    157,    813,   -279,   2226,
+       -16,   1191,   -705,    607,    205,    -11,  -1341,   -548,
+     -2251,   -326,   -149,  -2536,    139,   -750,     73,   -394,
+      -218,    -35,    181,    925,   -557,    226,    -63,   2582,
+      -737,    164,    181,   -167,   -230,    413,    328,    406,
+      -287,  -2992,    539,   1133,    -85,  -2162,   -154,   -357,
+      -245,     -8,    162,   -118,    111,   1275,     47,   -314,
+     -2043,  -2732,  -1052,    -28,    625,   -810,   -487,     40,
+      -131,    273,    105,   2605,  -2974,    268,    -19,   -257,
+       842,   -662,    855,    505,    590,   -243,     68,   6978,
+       118,   -101,    349,   -232,   -258,   -318,    212,     55,
+      -686,   -177,   -173,   -102,    480,     35,    149,    263,
+     -2838,   -198,    942,    392,    135,   2980,     34,     92,
+      -237,   -672,    224,   -298,    298,   2128,    359,    254,
+       150,   -839,   1001,   3234,   -169,    261,   -302,     74,
+      -277,    498,    321,    194,  -3275,   -152,  -2786,     33,
+        70,    236,   -222,     88,   -393,     47,   -636,    869,
+      -754,    842,  -2326,   -460,    133,      0,    264,    172,
+     -2955,   -286,   -243,    399,    882,   -722,   -382,    872,
+      -119,    -65,  -2403,   -119,   -246,   -890,   -185,    102,
+       -32,   -573,    225,   3044,   -484,    -40,   -809,    403,
+};
+
+static const int16_t cb2224l0[] = {
+     -3546,   -433,    -76,     46,     24,   -641,    214,    114,
+      -779,   -930,    -57,   -462,   -569,   -848,   -413,     53,
+        45,  -3172,   2915,   -734,    152,    487,   -113,    246,
+      -196,   -187,   -136,    469,    475,    382,    213,   -886,
+      -275,    313,   3148,    -62,   -773,    785,    -24,  -1499,
+       -65,   -175,  -1942,   -325,     78,    -15,    -38,      2,
+         6,    -29,    -16,   9690,    -15,    -49,    -13,     12,
+       -21,     11,    -45,    -63,   -528,    192,   -137,    201,
+       138,   -154,     57,    -88,  -1695,    155,    105,    121,
+      4249,    -59,    467,   -439,   4483,   -130,    -39,    262,
+       -21,   -377,    441,   -353,   -768,    366,     23,    841,
+       529,    195,   2722,   2892,   -255,    -67,    628,   -498,
+        33,    241,    212,  -1020,    -97,   -723,    594,     35,
+       -31,   1459,     19,    -75,    -27,     -1,     48,     28,
+       267,   -275,   3780,   -515,   -467,     36,   -405,   -272,
+     -1968,     60,     44,    449,  -2877,   -124,  -1524,   1195,
+      1042,    117,    115,   -305,    225,    215,   -357,    144,
+        35,    -23,     89,   2133,      2,     65,    -27,    -48,
+      -243,   -216,   -807,    700,   1258,      6,   -140,      4,
+       -31,    -21,     42,     67,     97,     -2,    104,    -10,
+     -7734,    134,    -50,    -95,    -88,   -269,    105,    -18,
+      -229,    453,   1038,  -2609,  -2944,    -57,     27,    372,
+        59,   -556,    -87,   -242,    114,   1083,   -119,   -139,
+       175,    146,    -55,   1689,    342,    501,   2722,  -1273,
+      1626,    868,   -290,   -145,     62,    194,    -23,   -179,
+      1540,    -85,    360,    254,    339,   -681,   2081,   2730,
+       838,   -128,     31,  -2133,   -173,    483,   -138,   2706,
+      2007,     91,    293,   -642,     35,    280,   -132,    454,
+       -66,  -6263,    -24,     82,    -31,    -39,      5,     41,
+        66,    239,     18,    -57,     61,   -117,    103,     16,
+     -1231,   1384,   -164,    104,    370,  -1891,   2237,   -440,
+     -1399,  -1394,      3,    274,    223,    -30,    -70,    579,
+       361,    423,    355,   -176,   -164,   -443,   -306,  -2382,
+       713,  -2987,   -340,   -691,   1407,     -5,    439,   -264,
+       -86,   1964,    -17,     88,    175,     56,   -119,     31,
+       466,   1980,    176,    513,   1809,     17,   3000,   1861,
+       -71,    314,   -255,   2041,    576,    203,    443,   -392,
+      -539,   -380,   -685,   -204,   -161,    287,    378,   -502,
+      1898,   1540,   1073,   2282,    573,    867,    122,   1064,
+      -628,   -564,     97,    280,    -36,   1601,    -90,   -174,
+       -10,     45,    -57,    159,   -496,    641,   -959,    -91,
+       -90,   3057,   1680,    -83,     80,     19,     63,   -119,
+         1,    -72,    466,   -335,    453,   -177,   3930,    -21,
+       327,   -199,   -651,    -38,     -6,    -13,      7,    -77,
+         1,      8,     40,   -125,     36,   -136,    272,   6266,
+     -3299,   3331,     24,     18,    -71,      9,    -79,   -374,
+      -277,    128,   -233,   -175,   -350,   -216,     81,   -693,
+       -49,     33,    -44,    -37,  -4260,    -70,     96,    177,
+      -319,    133,    178,   -377,    -45,    182,    156,   -155,
+       -34,     10,     22,     53,   -211,      4,   5740,     48,
+       -42,    114,    149,    -30,    122,   -106,   -309,   -148,
+       -82,     20,    130,   2734,    -40,   -596,   1309,   1163,
+     -1470,    396,   -264,    884,    142,  -1818,     67,     -1,
+        38,    -52,    -73,      1,    279,    143,    278,    -45,
+      1541,   -886,   -677,  -2609,    -88,  -3766,   -201,    237,
+       -40,    195,    -50,   -366,     88,    166,    403,    236,
+      -130,    205,    -45,  -8636,    -13,    -27,    -50,      8,
+        40,     21,     41,    -36,    -25,    -40,    -14,    -14,
+        42,    296,   2495,    372,   -361,   -501,   1951,  -2141,
+       220,   -847,     98,    228,   -250,    563,  -1121,    -29,
+      2888,   -196,    151,    -19,   -287,  -2298,     65,   -482,
+      -124,   -186,   1215,    468,   -781,   -227,    621,    298,
+       -42,    -44,   -115,      0,     50,    179,     23,      9,
+       -65,     -8,     10,   -101,  -4998,     77,   1181,   -304,
+       139,    250,  -2257,    -97,    847,    433,    385,  -2411,
+       800,   -852,   -528,    435,   -953,    -23,      4,    928,
+      -108,   -634,   -273,   -879,   2566,  -2609,    621,    807,
+       295,    -77,    627,  -1114,   -297,   -109,   2103,    -53,
+        -9,     44,     32,    339,    679,     77,  -3186,   -416,
+      1234,   -801,    472,    408,    153,    465,   1703,    879,
+     -2411,   -553,    440,   2099,   -899,   -288,    310,    665,
+       -47,   -148,   1457,   3932,   -213,    243,  -1763,     -2,
+       288,   -425,   -972,    478,   -302,    552,   -377,   -352,
+       179,   -480,   1466,   2019,   2817,      5,    824,     13,
+      -384,   -582,   -297,  -1165,    689,   -120,    703,   -118,
+       663,    206,    -49,  -2853,    -76,     32,    170,     11,
+        42,   -503,  -1139,   1548,   -287,  -1112,    765,   -455,
+       -35,   2452,     22,   -134,    144,   1867,   -149,   2771,
+        19,    264,    700,    -48,    286,   -593,  -2637,    408,
+      2304,    -14,    187,   -135,   -210,    745,    282,    724,
+       861,     21,   -414,    606,    836,   -564,    212,    203,
+        64,   4706,    -30,    -43,    -85,    -61,    -90,    644,
+      -281,    287,   -122,   -340,   -137,     36,     -4,    -22,
+         8,   9486,     -3,      4,     10,      4,     86,     58,
+        -8,      6,   -105,    -15,     15,    -63,    -58,    -30,
+        15,      0,    -19,     78,  -8267,   -134,     -8,    -45,
+       163,    -19,    149,   -298,   -167,     34,    190,    -39,
+     -2229,   2821,    126,    185,   -791,  -1229,   1003,   -331,
+       980,    659,    -60,    -60,    -48,     20,     12,   -167,
+       -60,    -39,     66,    180,    -22,    -20,     84,   -108,
+       131,    -10,  -8493,     -1,    -18,     -4,    -53,     25,
+       -63,    -14,     20,     25,    -41,     40,     -5,  -2330,
+       -74,     59,     -7,   -154,   -293,    -64,  -2702,    819,
+        75,    977,   -602,   1138,    160,    262,     26,    -81,
+        18,   5558,    118,   -167,     98,    110,     -5,    -44,
+       -27,     72,     51,   -189,      0,   1868,    743,   -275,
+      2530,      6,    180,  -1019,  -1307,    710,    303,   -152,
+      -115,  -1498,   -501,   -495,   -103,    -76,     78,     -7,
+     -9337,     -6,     31,    -21,     16,    -14,     57,     36,
+       -81,    -67,    -30,   -535,    216,    313,    310,   -157,
+      2830,   -914,    122,   1353,  -1842,    298,  -1165,    -13,
+      -253,   -100,   -560,    -61,     40,     24,      3,     56,
+       -18,   5709,     41,     13,    -23,    -55,    -98,    214,
+       109,   -205,    -45,     27,    -26,    177,   -290,     89,
+         8,   1315,   3102,   1657,    210,  -1032,    774,   -211,
+      -581,    -51,    896,    852,    331,    349,   -474,   -119,
+      -865,   -145,   2270,    703,  -1967,  -2088,    610,   -700,
+       113,   -231,   2062,   -152,   -599,   -474,    -38,   -601,
+       432,   -983,   -731,    744,  -2880,    156,   -240,  -1903,
+      2497,    -89,   -963,  -2179,  -1208,    189,    318,    150,
+       204,     29,   -167,   -138,    -93,     73,    292,  -3225,
+      -310,   -510,    173,    -90,    154,   1831,    380,  -1191,
+      -976,  -1460,   -514,    235,     13,  -2950,     22,    -95,
+       228,     85,     10,    264,  -3165,     46,   -184,   -782,
+       143,     -9,     37,     12,    108,    -65,    -64,    115,
+        86,   5039,    -55,   -203,   -163,   -462,     77,    -92,
+       423,    139,    239,     -5,   1887,    426,    729,    118,
+      -159,  -2821,   -124,   2147,   -167,  -1023,     92,    -23,
+       162,   -159,    -47,     -3,     14,    -34,     37,    -29,
+       -97,     41,    -92,    -75,  -6983,   -224,    250,    -80,
+};
+
+static const int16_t cb2224l1[] = {
+     -2888,   -183,   3606,      0,     33,     99,    -76,   -264,
+      -351,   -508,   -546,   -103,    252,    -49,     46,    -32,
+        48,   -245,     67,  -2408,    340,   3153,   -154,   -280,
+      -440,    374,   -224,    -39,   -720,   -289,   -136,  -3095,
+       -98,    -37,    -86,    145,     51,    132,    773,  -1158,
+      -330,   -449,   -141,  -1831,    666,  -2680,   -110,   -906,
+      -307,  -3299,    287,     55,   -521,   -173,   -431,   -383,
+        67,    -28,     34,    247,   2814,   1479,     32,  -2196,
+     -1625,    135,     72,      3,    634,     76,    502,   -306,
+      -366,   -120,   -219,   1934,    372,   -130,   -113,    255,
+       -14,     30,   -687,   -576,    797,    306,  -2360,   -242,
+      2062,     69,   2273,     26,    -20,    -21,    -68,    -69,
+     -4618,     60,   -171,   -235,   -271,    175,   -110,    147,
+       100,   1628,   -197,     -2,  -4002,    520,  -1236,    -21,
+        62,   -396,    513,   -369,   -168,    285,    561,    131,
+      1347,     83,   -101,     89,    206,      5,   4556,    -23,
+      1191,     39,    352,   -158,     99,   -195,    -33,    481,
+      -446,   -125,    181,   2678,   2860,   -524,   -239,     55,
+      -360,   -358,   -560,     93,    307,    285,     77,   -295,
+       -90,    114,    -45,     54,   -328,     94,   -222,    -30,
+     -5004,   -164,    100,    379,    208,    424,    -11,     26,
+        10,    -26,    -32,    114,     30,     18,    -44,   -221,
+      -184,    -32,      0,    -99,  -9001,     -7,    -33,      1,
+        41,     -3,     13,      9,    -46,    -86,     47,     56,
+        72,     -7,      5,  -1162,    101,    456,   -217,   3440,
+      -220,    400,    100,   1503,    365,    655,   -230,     42,
+      1129,    767,    192,    -16,  -3440,    -79,   -236,      3,
+       -80,     51,    -11,   -984,   -142,     29,    554,    339,
+      1851,    105,   -279,  -2915,    116,   3090,   -431,    233,
+       337,     61,    927,     32,   -174,    237,    255,   -250,
+       604,    115,   2036,     78,    -79,    -50,   -349,    338,
+       285,    169,    394,    -49,   1194,  -2966,    447,     57,
+     -2591,    415,   -586,  -2616,   -197,    -61,    596,  -1159,
+       130,   -441,    356,     47,   1192,    496,  -1801,    -15,
+      -142,    -23,    132,     21,     84,    234,   -137,     23,
+      -147,  -3254,    407,    107,   1132,    130,     74,    153,
+      3148,   2184,   -464,   1294,    222,    589,    457,   -397,
+       -87,   -605,   -631,    311,   -703,    110,     20,    -23,
+       -75,     18,    -43,   -182,      8,    -94,    151,   4989,
+      -619,    662,     82,      8,     69,     -4,    126,    -35,
+       -99,   -277,   -227,  -2212,   3188,   1115,   -467,   -618,
+      -989,    681,    218,    -25,    -37,     -9,     32,    -46,
+        97,     15,    -23,    -95,     -6,     55,     19,   7904,
+       -14,   -508,      3,     14,    -12,    -58,     28,    154,
+        11,    271,   -593,    344,   -336,   3489,    -41,  -2998,
+       622,  -2739,   2796,   1536,    310,    176,   -318,    399,
+       -70,   -298,   -509,    256,   -381,   -158,    322,   -197,
+         3,    -53,     37,     98,  -6136,    -25,    -54,     57,
+       138,    -74,    239,    -46,    -18,     29,   -265,  -2278,
+        22,    110,    -21,   -147,    266,     85,   -286,    137,
+      3434,   -485,     68,    475,     -3,    159,   -181,   -237,
+      1595,    759,    786,   1490,    926,  -2841,   -160,   1092,
+        -7,    130,    895,   -345,    -95,    -31,    -35,    139,
+       -98,   2106,    305,    672,    -66,    349,    229,  -1561,
+     -1694,  -1786,   -743,    -76,    -67,   1666,     76,     10,
+       -22,     60,    -45,      5,    409,   -458,    583,   -405,
+      2586,   -264,    175,    633,    842,   3208,  -1488,   -802,
+        40,   -119,   -197,    -84,   1645,    328,    823,   -175,
+       342,     12,   -217,     67,    124,   -180,   -106,  -2877,
+      -336,    171,    185,    132,  -2263,    -75,   -622,   -631,
+     -2404,    176,   -132,     35,    179,  -1498,    182,     68,
+       699,    597,  -2728,    325,     52,    421,   -863,    609,
+        53,   -159,    258,   -307,   2919,     44,   -826,   -467,
+        91,    542,   1883,    815,   -682,    548,   -419,    593,
+        82,  -2108,   -158,    -75,   -524,   2440,   -528,   -469,
+       723,    -14,  -1817,   -487,    448,      4,   -155,    -70,
+     -1715,     34,    -55,    134,      0,     19,    107,    419,
+       334,     74,    446,   1241,  -4288,     61,    -65,     21,
+        71,    133,      2,    -88,   -238,    322,   -283,     -6,
+       404,     98,     78,  -1951,    412,  -1942,    418,    257,
+       -42,  -2444,    -97,   1491,    464,    346,    229,   -154,
+        96,    261,     29,    302,     39,   -201,    -40,    -98,
+      -157,    335,  -3624,   -349,   -573,    633,   -116,   -312,
+       -82,    263,     -2,   -101,    -57,   1817,   -424,      3,
+      -245,    386,     74,    609,   2171,    -77,  -2604,  -1036,
+      -117,   1585,     -2,      9,    -23,     31,    -12,     48,
+       215,     84,     13,    219,    419,   -275,   4373,    -91,
+        -6,     18,   2228,    -46,    157,   -408,   2288,    654,
+      -725,   -245,    -10,  -1182,   1726,    324,    367,   3013,
+      3429,   -140,    360,   -122,   -574,   -165,    109,   -330,
+       -82,    340,   -133,    210,    355,     -8,     47,    -52,
+      8064,      5,     60,    -42,    -95,     -3,     91,    -69,
+       -47,    -42,    101,    118,    -44,    -16,    -14,     -9,
+        27,      8,    -33,     -3,  -9302,     27,     49,     -6,
+        61,     74,    204,    430,    252,   -259,     73,    125,
+       366,   -458,  -2846,     89,  -2694,   -106,   -344,   -702,
+       809,    451,     69,    585,  -1897,    608,  -1138,     52,
+       618,    106,    771,   2992,    266,   1007,    184,   -486,
+        36,   3317,   -311,     38,    105,    -89,     16,     97,
+       -88,     28,    183,  -2834,    -44,    387,    -49,    467,
+     -2524,     77,    -56,  -3727,     81,   -308,     63,   -137,
+       203,    -77,    139,    254,    -65,   -264,    -58,    631,
+     -2559,    739,  -1343,    595,   -117,   -193,  -2572,    322,
+       267,    185,    669,   -110,    641,    212,     45,    -16,
+        12,     14,     -3,    -12,     78,    -48,   -196,   -128,
+       179,    146,  -7348,    177,   -138,    -48,    142,    -33,
+        34,  -6037,     15,   -105,    103,    136,    -48,    217,
+      -169,     88,    -31,      9,     24,     41,   1733,  -2757,
+      -335,   1783,    988,   -161,   1014,    633,    -66,  -1114,
+       525,   -266,    461,   1137,    -26,   -173,     89,     82,
+     -3365,     67,   -198,   -107,     44,    352,   -793,    867,
+      -807,   -166,    107,      4,     71,     61,    124,     27,
+     -2477,    178,    -32,   -172,   2895,   1301,    798,    707,
+       267,   -720,   -403,    167,   -157,   2572,   -210,    527,
+      -312,  -1664,   -214,  -1556,   -332,    595,  -1634,    -58,
+       203,  -1777,   -469,     24,    188,    -59,   -860,    879,
+        15,    855,  -1534,   2910,    534,    -71,    276,    471,
+        41,    -25,    105,    -37,   -150,    110,    226,   -277,
+     -4687,    574,    139,   -152,   -586,     67,  -1082,    261,
+       -68,     25,   -216,    110,     46,  -3703,    281,    355,
+      -506,     80,   -218,    164,   -398,     75,    -97,   5782,
+        39,    -68,     26,     76,     74,     38,   -103,    105,
+        44,    116,    187,    288,     90,   5847,    -41,     28,
+       -19,     20,    129,    -99,    258,     22,    -28,   -120,
+      -101,   -121,     79,   -180,    -23,     22,     -5,    -60,
+        63,     35,  -8987,    -11,      2,    -15,     -3,    -28,
+        47,     29,    241,    132,   -166,   -259,    -48,    102,
+        70,   2830,   3163,    285,   -813,      0,    105,    176,
+      -455,    141,   1382,   -481,  -2282,   2971,   -200,   -473,
+        37,   -930,  -1162,    930,    890,    412,    190,   -160,
+};
+
+static const int16_t cb2224s0[] = {
+     -5789,   1229,   -138,   1010,    823,   -602,   -987,   -237,
+        47,    -29,    428,    210,     87,    -11,    -20,   -261,
+     -3148,   1219,  -2074,   -132,   -258,    707,   -634,    878,
+      -486,    989,   -276,   -137,   -263,    592,   1248,    474,
+      -293,   -981,   2125,   -653,  -1451,   -833,  -1522,    387,
+      -269,    349,    698,    295,    870,    661,   1532,    202,
+       654,    362,  -1265,   3972,   -651,    224,    213,   -728,
+       -83,    575,   -503,   -766,    559,   -657,     86,    941,
+      1498,    -72,   2297,   1413,   -376,    697,   -738,    384,
+      -807,   -354,   1141,    374,   1186,   -597,    222,    630,
+      -717,  -1653,    106,  -1377,   -929,    982,  -3469,   -321,
+      -201,  -1185,   -147,    -13,    268,    103,   2967,  -2083,
+      -416,    702,    377,  -1126,     92,    963,   -494,    -94,
+      -436,   1893,   1401,    -40,  -1464,  -1608,   1980,     44,
+       254,    676,    529,   -891,    -95,      9,   -172,   -129,
+       158,   -403,  -1147,   1026,   -410,     86,   2593,  -1060,
+      -621,    480,    254,   -780,    691,  -1020,     79,   -192,
+     -2264,  -1219,   -748,    602,    243,    338,    550,   -444,
+      -130,     79,     24,   3396,    124,   -572,    749,    976,
+        33,   -883,   -368,   -609,    694,   -569,   -560,    192,
+       868,    644,    173,     86,  -4302,    633,   7899,   -360,
+       478,    493,   -306,     14,    244,     96,     71,   -169,
+       336,    346,     74,    -52,   1779,    828,   -252,    739,
+     -1005,   -755,     31,    -46,    200,    581,    -11,    802,
+      1104,   3252,  -1053,    723,   -491,  -2492,  -2330,   -245,
+       308,  -1021,   -312,    563,    -85,    991,    -16,    224,
+       -85,   -957,   2262,  -4585,  -1475,    102,    310,    298,
+      -875,     -6,   -268,      8,   -284,    324,   -471,   -224,
+       133,   1502,  -1714,  -1095,   -104,    809,   2584,   -273,
+     -1014,   -296,    130,    732,   -259,   -335,   -745,   -619,
+      -716,    247,    503,    862,   -277,   -137,   -224,  -4897,
+       124,    277,    298,    -40,    169,    678,    557,   4379,
+       677,  -2016,   -506,   -108,    -47,     49,   -115,   -260,
+      -300,    206,   1196,    -17,    202,    365,   -808,   -473,
+      -160,   -609,    526,  -1124,   1629,  -2924,    713,   -487,
+      -109,    540,   -511,    221,   -394,  -1420,   1023,   -460,
+       424,    -86,   -875,  -1557,    -88,   -244,  -1597,  -3015,
+       355,    166,    330,   -334,   -325,    505,   3632,  -1760,
+      1626,   -427,    573,   1197,   -317,   -566,   -663,    460,
+       338,   -442,   -597,   1565,   -854,   -534,   -219,   -128,
+     -2175,    739,   1064,   2050,    -61,   -349,    361,   -375,
+      1111,   -122,   -121,   -164,  -2573,    938,   1758,    -15,
+       884,    865,   -630,   -573,    994,   1112,    -26,      9,
+       -30,   3893,    -38,   1386,    605,    568,   -680,    117,
+        37,    572,    245,    -53,  -1030,   -241,    397,    363,
+     -1632,   -567,    -26,   -698,  -2109,  -1033,  -1389,   1381,
+      -418,    402,   -534,      9,   1143,    991,    693,   2557,
+     -1268,   1273,   -192,   1225,    876,    472,    835,    509,
+      -452,  -1519,    482,   1103,   -626,   -299,   1580,  -1532,
+       599,   2245,    503,   -110,  -1879,    978,  -1158,   -130,
+      -665,    448,  -1247,    604,   -528,   -677,   -711,     78,
+      -563,   -349,    -53,    261,    952,   -338,   -534,     43,
+        -2,  -2555,   1976,   2393,   1715,    996,   5628,   1036,
+       171,    -28,   -199,    -83,   -126,    -35,   -248,   -393,
+        36,    209,     77,  -1793,    244,   -108,   -130,    -41,
+      -578,  -2347,   -687,   1650,    131,   -138,    407,   -228,
+     -1348,   -209,   -841,   1332,   -542,    220,   -193,    843,
+      -103,    853,    261,   -653,    217,   -107,   -113,    -54,
+     -4151,  -1303,   -287,   4065,   -376,    -71,     43,  -1481,
+      -359,   -481,     78,    529,    689,   -194,    178,     60,
+      -997,  -1555,   1687,    345,    169,    266,   2894,     83,
+      -500,   -425,   -396,   -245,      6,    517,    112,    129,
+       725,   -121,   -404,    234,     47,    -61,   -122,    710,
+     -4283,    985,     56,   -105,    -45,   1043,    720,     73,
+       321,   4452,  -1614,     91,   -620,   -299,    506,    766,
+      -882,    650,   -138,    123,   -608,    210,  -1582,   -538,
+       -62,    246,    464,   -332,  -1560,   2271,   1559,   -199,
+      -832,  -1133,   -797,    341,   1860,   1628,  -1133,   -607,
+       637,   -404,    437,  -1148,    542,   -474,   -882,   -610,
+     -1340,   -159,   1524,   1424,    169,     -6,     52,    447,
+     -5513,   -592,    244,   -294,     44,    164,    -51,    147,
+       202,    -48,    139,    113,   -399,    -17,   -173,   -199,
+         1,     17,   -166,     15,   -258,     -7,    238,  -5748,
+      -394,   -852,   -248,    -46,    192,    -32,  -1033,   -349,
+       151,    483,    130,  -1628,  -3391,   1527,    694,   -305,
+       740,   -357,   -491,   -186,  -1649,  -1394,   -873,    213,
+       652,  -1975,    319,  -1131,   -103,    -48,    673,    155,
+      -627,   1115,    469,  -1122,   1901,   -184,   -237,   -296,
+     -2887,   -120,    211,    835,     57,   -826,   1272,   -255,
+      -937,    242,   -525,    836,   -334,    393,   -624,    111,
+      -347,   -178,  -3441,    219,   -352,   1831,   -296,    587,
+      -357,  -1099,      5,    313,  -3806,   -394,    814,   -118,
+      -233,    -23,   -125,    -21,  -1414,    813,   -403,   2482,
+       442,   -184,    934,    340,    472,    374,   1073,   -283,
+     -2348,    477,   -387,   -713,   1071,   -899,    252,  -1299,
+      -502,   -375,   -410,  -1785,    686,   -605,   -141,   -871,
+     -1777,   2780,     53,   -237,   -237,   2701,    944,     44,
+       595,      3,   1263,  -1558,  -2267,   -998,    221,    355,
+      -319,   -739,  -1160,   -594,   2977,    191,    -41,   -284,
+        83,    484,    481,    -73,    -13,    138,  -2761,   -909,
+      -578,   -139,  -1056,    189,   -645,   -147,    -61,   -168,
+       368,    130,    390,   4187,    101,     79,    -45,    451,
+     -1374,  -1941,   -534,   -301,   -979,   -668,   -533,  -2978,
+       386,    574,   -454,     -4,    554,   -120,    366,     83,
+      1079,   -351,    156,    389,   7724,     83,    102,   -191,
+     -1059,   -255,    -86,    451,   -211,    175,    774,    306,
+      -253,   2386,   1166,  -2025,    223,    438,   1279,   1721,
+       -23,    -91,    606,  -1285,   -775,  -3228,   -536,    543,
+       877,   1140,  -1616,   -603,    550,   -678,   -462,    248,
+       209,   -515,   -310,  -2538,  -2002,    231,   -495,    319,
+       538,    509,   -113,    -17,    143,  -3062,    -29,    -52,
+       299,    681,    595,    390,    530,   -398,   -969,    472,
+     -1145,    860,   4113,    329,  -1183,   -691,   -605,    859,
+       305,    986,    -81,   2029,    408,      2,  -2442,     59,
+       -85,   -911,   -285,   -532,     28,    434,  -2295,    -76,
+     -2977,     51,    824,  -1786,   2301,    622,   -593,     -9,
+       643,    246,    427,    193,     51,    118,      4,    234,
+       459,     31,   -408,    710,   -264,    144,   -404,   -476,
+       278,  -4836,   -113,    382,    -29,    177,    345,    -33,
+       -17,    -85,   6027,     72,   -165,    544,   -198,     75,
+      -278,   -262,    155,    501,   -305,   -279,   -439,   1506,
+       827,   -875,  -2592,  -1196,  -1201,    149,     16,    547,
+      1020,   -616,    374,   -193,   -155,  -3627,    231,    264,
+     -2143,     90,    419,    574,   -795,    177,    328,    752,
+      -295,    210,   -360,  -1250,   2639,  -3172,    -13,    -34,
+       489,    484,   -390,   -159,   -285,     27,    444,   -252,
+       265,    530,  -2714,   -340,  -1543,   2330,  -1152,   -114,
+       452,    304,   -224,   -451,   -317,   -579,    301,   -567,
+      1214,   -594,   -621,  -2718,     59,    257,    410,     -3,
+       145,     70,    877,  -3103,    244,  -1134,    236,  -1148,
+};
+
+static const int16_t cb2224s1[] = {
+      8488,    277,     63,    173,    224,    -30,   -158,     64,
+       133,   -133,    234,    205,    -65,    408,    249,   -546,
+       -30,     -1,   -430,     80,    102,   -450,   -160,  -5634,
+       145,   -406,   -351,     37,    282,    232,   -898,    430,
+      3301,  -1175,   -559,    495,   2685,    -21,   -215,    -87,
+       728,    -55,    235,    430,   -250,   -505,    506,   -128,
+       -72,   3288,   1588,    291,      7,    -39,   -944,    478,
+      1719,    168,  -1085,    225,    330,   1480,   -183,   -597,
+     -6131,    668,   -387,    672,   -173,    -55,    113,     40,
+      -113,    -44,    341,   -340,   -594,  -1001,   1757,    127,
+       -59,    537,  -1834,   1401,    856,  -1153,   -234,   1232,
+      -562,    476,    110,   2188,    146,    119,   2119,   -872,
+       450,    597,   -371,  -1350,   -996,   -120,   -495,    829,
+       111,   -897,  -5445,   -670,    390,   -118,      4,    109,
+       772,    495,    196,    410,   -125,    812,    426,    900,
+       436,   1155,   -553,  -1223,    275,    266,   -891,     63,
+     -1267,    523,   -548,  -2445,    239,   1163,     72,    -68,
+     -1576,   2212,   -340,   1499,    494,   -671,    -73,   -281,
+       598,   1901,  -1652,   -845,    266,    795,   -545,   -574,
+        19,   -461,    371,    288,  -3959,    421,    299,   -121,
+     -2561,    -65,    118,    181,   -227,    719,    -92,  -2334,
+     -3178,  -2497,   -198,     58,   1279,   -309,    152,   -715,
+       466,   -316,     10,     98,   1568,  -1015,    -18,   -435,
+       -42,   2606,   1971,   -119,    705,    254,    443,     36,
+       788,   1135,   1234,   2281,    942,    115,    581,   -113,
+      -194,   -694,    434,    -30,   2835,   -423,    436,    522,
+       406,   1329,   1191,  -2628,    421,  -2601,    646,   -202,
+       637,    610,   -584,    357,  -1586,   -499,  -1230,    134,
+       -83,  -1264,   2434,    -58,  -2924,    641,   -285,    172,
+      -478,   -402,    584,  -1180,   -137,   -238,   -151,   -679,
+      -619,   -495,   1044,   1281,  -1180,   -444,    376,   1969,
+      -693,   -283,    618,    128,  -2622,    -90,   -115,    672,
+      1738,   -459,    519,   -924,   2582,    937,   -555,    672,
+       131,     31,    775,    307,   -282,   -527,  -1299,   -516,
+        10,    239,  -4069,    118,     10,   -665,    -15,   -484,
+       472,    262,    279,    677,   -755,   1288,  -1278,    403,
+       666,   -394,  -1230,  -2819,   -221,    109,    603,    754,
+       951,    488,   -147,   -107,   -426,   1875,   2056,   -129,
+       239,   -561,     81,   -324,    243,    349,    197,   -811,
+      -146,   -929,   1193,   1433,   -776,   3209,    434,     -6,
+      2465,   -231,    -57,    312,    899,   -396,   -170,   -549,
+       346,    135,     17,   -596,    401,    269,    499,    -64,
+      -321,   -342,   -132,   -312,   5845,    276,   -104,     -9,
+       -50,   -678,   -478,  -1125,  -1477,   2058,    156,    538,
+       451,   2572,    495,    101,     74,   -753,     98,    685,
+      2424,  -1999,   1050,   -280,  -1030,     29,   -178,   -244,
+      -134,    130,   -137,   -103,   -245,   2161,   -446,  -1016,
+       464,    573,   -473,    446,  -3822,    942,  -1261,   -334,
+       568,   -528,   -301,    415,   -740,    661,   -813,    849,
+      1491,    774,   -774,   1637,   -977,   -246,    647,   -572,
+      -140,  -2946,   -654,   -650,   -311,    339,   -165,    757,
+       803,   -958,    704,    171,    380,    763,    159,   2721,
+     -1599,   1006,   -118,   -597,   2985,   2699,     69,    395,
+       523,    657,    438,    190,     72,    164,   -268,   -145,
+       506,   -550,    222,  -3641,      5,   -173,     60,   -194,
+       677,    686,    724,   -107,    882,   -339,     14,    -54,
+       555,    483,   1523,    119,   -142,   -394,  -1683,   -984,
+        18,   -108,   -190,    141,    540,    281,  -1238,  -2195,
+      -341,   -327,  -1014,   -990,   4694,     46,  -1018,    360,
+      -671,    -83,    218,    857,    144,   -188,    463,   -379,
+      -571,   -865,  -1345,   -447,    -18,    -64,   5201,    132,
+        90,   -158,   -132,    381,    -85,   -107,   -103,    970,
+      -555,  -1204,   1802,   1230,    253,    540,   -372,  -2347,
+      -386,    835,   -705,   -437,    941,    795,   -182,   -368,
+      1088,    168,    256,    210,   -667,    290,   1783,   -636,
+       165,   -363,    638,  -3527,   1872,   1997,   1503,   -189,
+     -2587,   -359,    384,    493,   -384,   -658,  -1758,    993,
+      -306,    148,    198,    163,    430,   -313,   -149,   -337,
+       352,   -354,    484,    358,   -264,  -4525,   -560,    -55,
+       154,    374,   -317,   -426,   1446,   -161,   -285,   -110,
+       209,    299,   2329,     99,   1406,   1374,    993,   1178,
+      -413,   -642,   -103,   3678,  -1829,   -754,  -1358,   -349,
+       648,   -492,    755,    188,    114,   -444,   -930,   -224,
+       319,    212,   1223,   -648,    593,   1293,  -1289,     24,
+      -712,   2591,   -494,   1503,     -9,    534,    923,   1490,
+       985,    491,    272,    988,    348,   -503,   -454,    893,
+       409,   -422,  -1187,   3097,    602,   -402,    462,   1598,
+      -219,    982,    319,    125,    558,   -100,   -261,    108,
+       -59,  -3435,     76,  -1065,   -150,  -1758,  -1997,   1921,
+      1239,    426,    507,    173,   -856,   -829,   -538,    247,
+     -1203,    488,  -1094,    453,  -1104,   1021,   2185,  -2855,
+       427,    177,   -778,   -182,    641,   -670,     91,    569,
+        50,    -90,    571,    108,   -374,    174,   1997,    964,
+       644,   -428,  -1868,    668,    171,    320,    676,    121,
+      -218,   1901,   -857,   -721,   -194,  -2433,    -34,  -1671,
+       352,   -644,    295,    571,    253,   -288,  -1786,     32,
+        74,    -73,   -902,  -1954,  -1126,  -3427,    168,   -318,
+        23,   -755,   -441,    201,    -84,    499,    367,   -153,
+      -426,    716,    650,   -457,     80,   -709,    859,  -2098,
+      -723,   -197,  -1030,   -253,    283,  -1187,   -899,   1403,
+      -117,    -25,   7617,    -63,   -355,   -283,   -560,    -85,
+      -358,    -45,     63,    179,   -193,    130,   -294,   -676,
+      -525,   -907,   -430,   -627,  -5267,   -539,    257,    594,
+      -173,    890,    203,    -33,   -136,   -803,    479,    -56,
+      -634,    464,   -919,   -146,    306,      5,    198,    -90,
+      -138,   -337,   4826,   -310,    259,   1651,   -687,  -1676,
+       424,   2729,   -966,    -61,    386,     60,    769,    -72,
+     -1652,     49,    106,    503,  -1462,  -1056,    892,    359,
+       209,   -129,    260,   -130,  -2081,    798,    488,    846,
+      -836,   -366,   1786,  -2237,   -484,     72,  -2680,   -828,
+      -857,    920,    560,    930,   -197,     56,   -872,    -34,
+      -355,    929,     35,   -449,    514,     70,  -1277,    208,
+       353,   3654,   -256,    134,   -895,   -184,    375,    402,
+      1576,   1515,   -100,   -438,   -679,    384,   1143,    -24,
+       100,  -2818,    554,   -219,    105,    652,  -2778,   -108,
+        44,    306,    445,   -470,  -1151,  -1170,   1305,   -741,
+      1223,   -443,   -838,    374,  -3000,     72,   -590,   -587,
+      3686,     76,   -493,    246,   1348,  -1215,    473,   -244,
+      -304,   1937,    -68,   -626,    278,    392,   1167,  -1899,
+      -309,    474,    226,   -421,    -95,   -483,    105,   -148,
+       749,   -430,  -3057,   -789,  -1793,  -1857,   -158,   -489,
+      -676,   -204,    806,   -930,  -3192,   -204,   -106,   -812,
+      1159,    648,    119,    -93,   -205,   -139,    280,  -7786,
+      -388,   -132,    -12,   -332,     32,   -174,    100,    153,
+        -7,    289,    -29,   -984,   -329,   -592,   2568,    704,
+       544,     66,    521,   -661,  -1632,   -868,   -310,    313,
+      -466,   -347,   -146,    197,    266,    765,   -240,   -201,
+      -265,  -1129,    -35,   -563,   -356,    172,    862,   3831,
+      1547,  -1618,  -1445,  -3726,    388,    548,   -457,    143,
+       -38,    402,    255,    840,   -703,   -154,    776,  -1038,
+};
+
+static const int16_t cb2224m0[] = {
+     -7078,   2846,     79,   -111,    -20,    330,    227,    -36,
+       305,     45,     81,    148,    -13,     68,    364,   -317,
+       -72,   2021,     28,     93,    328,   -256,   -181,   2547,
+       235,  -1102,    130,   -577,   -164,   1290,   1885,   -171,
+      -147,  -3247,    324,    -72,   -313,    -62,     32,    284,
+      -138,     -9,   -146,   1709,   -390,   1833,    289,    125,
+      2369,     60,    223,   -137,    642,   -113,    204,    288,
+     -1516,   -138,    228,    368,    219,   -622,    273,   3211,
+      -215,   -423,    139,     65,     85,   -203,   -953,     11,
+       193,    294,    279,   3267,    246,  -2377,    -59,   -324,
+       136,   -492,     23,    -56,     79,    307,    115,   -146,
+      2229,    325,  -1680,   -597,   -423,   2200,    -44,     48,
+       386,    396,   -122,    -36,     35,   9763,     33,    -67,
+        19,    -34,     15,     41,    -25,    -30,    -61,     20,
+      -121,    117,   -155,    -28,    -65,    -27,     40,    137,
+       188,   -211,   -240,     71,    -33,  -4873,   1992,     56,
+     -2701,     -1,    151,    -96,    286,   -398,   -418,   -221,
+       295,   -394,   -119,   -182,   -124,     77,      7,    -44,
+       168,    -34,   -154,    257,      4,   -114,    634,    131,
+      4930,   -118,  -2364,     46,   -204,   -129,  -3168,   -138,
+      -489,    454,    -96,    120,   -447,      9,   -230,    174,
+     11359,    456,   -261,    -74,   -249,    -28,    149,    -79,
+       -36,    211,    -10,    213,   -110,    337,  -3800,      4,
+      -223,    -18,    136,   -290,   -155,   -235,     57,    447,
+      -495,   -231,    -15,  -1036,    -85,   -154,  -4421,    -19,
+      -237,  -1191,     12,    -19,      2,    -88,    -84,    269,
+        -7,    431,    -26,  -2676,   -100,    287,    -31,  -2916,
+      -160,    -83,   -198,      9,    183,   -279,    -68,    -23,
+       -55,   2955,   -121,    -71,    183,   -702,   -323,   1689,
+      -132,    309,    136,  -1217,    440,   -125,  -1671,   1569,
+      -161,   -108,    232,    269,   -516,     37,     21,   -260,
+      -230,    564,   -375,    224,    129,   4332,   -120,   3306,
+       153,    -25,   -260,    -84,    123,     21,      5,    -17,
+      -145,    -44,      7,     -1,    290,  -2394,   -182,     51,
+       933,   1037,     26,    211,    187,  -1783,     68,   -749,
+       -52,   1428,  -1571,   -261,     34,   -199,    722,   -127,
+      -118,   -114,  -2385,    146,  -1042,    -71,  -1475,   -150,
+     -2195,    151,    -29,      6,     96,  -1213,    282,    219,
+       466,    144,   -300,    109,    -74,    125,   2863,      2,
+     -2963,   -218,    235,      3,    359,    319,    372,   -500,
+      -271,    494,   2695,    -65,    -29,     47,     74,    -34,
+       -95,    -48,    -76,    -71,  -2985,    -30,    -11,     26,
+      -176,    107,     96,     22,    -60,    114,    -70,   -147,
+       -43,   6981,    110,    -86,     33,     66,      8,    -61,
+        52,   -169,     82,    233,     56,   -115,   -295,    241,
+     -1053,  -3914,    -79,    361,   -869,   -144,   -144,   -805,
+       158,   -278,    515,      4,   -317,    917,   -669,   3314,
+       253,   1316,    259,     12,   8170,     15,    129,   -200,
+       120,    -11,     34,    -77,    -13,    257,     79,      9,
+        23,     54,     73,      0,  -9972,      5,      7,     43,
+        29,      4,   -104,     43,    -36,     76,   -228,      1,
+       -77,   -156,    -69,   -209,     84,  -2826,    242,  -1461,
+      -718,    -14,   1784,    527,    226,   9852,     83,    -15,
+      -389,     34,     51,    -16,    -46,     -1,    232,    115,
+        26,    -42,   -124,    -78,     58,   3092,  -2757,   -111,
+       223,   -286,     23,   -170,   -166,   -264,    331,   -172,
+       -49,    -26,    166,   2616,    128,   3118,     59,    844,
+      -121,   -504,   -193,    -53,    -95,    282,    -21,     -8,
+       -11,     58,    -48,   9830,     25,    -26,     53,    113,
+        96,    125,     12,    -64,    185,    -31,     19,   -251,
+      -307,   -136,   1383,    -37,   -128,     56,   4303,   -232,
+      -272,     44,   -192,    531,   -143,   -697,  -2291,     70,
+       229,   -432,   -592,   1262,    906,   -207,   1522,    261,
+     -7848,    -39,   -976,    150,    115,   -139,     61,    -26,
+      -211,    807,    -25,    311,    -98,   -297,    133,    461,
+      -109,     -6,  -1031,    236,  -2851,     86,   2184,   -254,
+       -83,   -119,    878,   -107,    -25,   1636,   1696,   1517,
+       249,    -41,   -283,    -66,    741,    704,   -898,    302,
+       470,    360,     -7,  -6002,     26,    268,   -109,    150,
+       202,    196,   -262,    -57,    160,    155,      7,      9,
+     -5770,     28,    127,    112,    -76,   -790,     45,   -118,
+       201,   -831,     67,    -81,    199,    296,   1692,    -30,
+      -126,   -121,     29,    387,    215,    269,   -518,   -232,
+       155,   2735,   -235,    -82,    -33,   3089,  -3696,    -39,
+       -51,    124,   -220,     37,     51,   -129,    194,    -80,
+        81,      0,   -239,  -1924,   -244,    107,    372,    111,
+       206,    418,     39,   -118,  -2059,   -446,   1378,    661,
+     -2135,    122,   -105,     60,    272,    -91,   -227,     48,
+     -3226,    -88,   -109,    199,    566,    158,   2412,  -4380,
+      -177,    153,    252,     24,   -323,    264,   -116,    -12,
+      -333,     99,   -181,   -124,    256,   -131,    -39,    -45,
+       -88,     69,    -26,   -173,  -4820,    286,   -171,    -82,
+       431,     18,   -827,   -107,    142,     60,    300,    422,
+       263,     61,    350,     85,   1088,   -133,  -1284,     70,
+     -4577,      5,    114,    -23,     23,   2907,    174,     43,
+        18,     33,    -31,    320,     -9,    290,      2,     -7,
+        39,    -11,     52,     32,     -4,   8454,     18,     10,
+        67,     20,     22,     -3,   -209,   -103,   -212,   -101,
+      -101,   -420,  -2837,    -28,    398,    140,   1027,   -187,
+     -2338,    406,   -152,   -288,    723,   -412,  -1851,    185,
+       641,   -190,    107,     -7,  -3194,   -128,   -382,    165,
+      -256,     85,     96,    155,   -144,    431,   -356,    342,
+     -2508,  -2190,   -265,   -320,  -1345,     27,  -1981,  -1949,
+        95,    -78,   -456,   -359,    382,   -218,   -102,    164,
+       382,    907,    599,    665,   2843,   4275,     17,   -156,
+      -264,     73,    104,    -25,   -120,     91,     84,    325,
+       170,    -65,   -245,    -23,     89,     52,   4651,    124,
+       185,     30,    321,    145,    111,  -1265,    128,   -156,
+        64,     24,  -1934,    133,    -84,    -10,     34,    801,
+      -148,    -88,    169,  -1687,    419,   1739,   -204,    -70,
+       185,    117,    379,   -420,    145,  -3650,   -264,   1118,
+       331,   -818,   -665,   -420,     74,     32,   -152,   -226,
+         6,    216,   4173,     23,   1230,    239,      2,    -57,
+      -690,    516,     90,     58,    -24,    -61,    175,  -2796,
+      -113,   -270,     94,  -2319,   -158,  -1075,   -275,   -647,
+     -3839,     37,   4267,     20,    -49,    -88,     72,   -171,
+      -195,     45,    -23,   -159,    -64,    110,   -211,     42,
+      -211,   1591,    276,  -3662,    213,     54,   -180,    786,
+       -92,   -329,    382,    344,    165,    -63,     14,     -7,
+        66,     29,   8875,     43,    -50,     65,     13,     15,
+        48,    -40,    114,    125,    -27,    158,      3,    843,
+         8,   -646,    100,  -3121,   1720,     88,    898,    346,
+};
+
+static const int16_t cb2224m1[] = {
+      9581,   -198,   -100,    -22,    237,    -15,   -101,    -23,
+        46,    129,     63,   -143,      5,   -307,   -143,     -9,
+        27,     50,     40,   6048,     25,     58,    -16,   -161,
+      -109,   -157,    137,    115,    121,    164,      4,    -54,
+      6477,    -68,   -120,    -29,     45,     -8,    -13,    334,
+       -87,    105,  -1460,     28,   -334,   -163,    -64,  -3629,
+       -71,    176,   -195,     53,     -1,    -96,   -560,    -21,
+       135,    178,    -77,  -4202,     20,   2544,   -205,     85,
+      -332,    158,     61,   -105,    398,    -88,     14,    241,
+      -149,     62,   -124,   -136,   -153,     27,    190,   2595,
+        25,  -2499,   -530,   1809,   -104,  -2753,    298,    145,
+      -771,    139,    165,   2462,   -502,    860,   -174,    199,
+        74,    163,   -686,    -25,     57,   -103,   -309,   -360,
+        39,   -296,  -2765,   -319,   -950,   -678,  -1159,  -1743,
+      1499,   1776,   -176,      9,     44,   -581,     69,     39,
+       162,    326,    -96,    329,     -9,   1274,  -2443,   -105,
+       -50,   4212,    -23,    146,   -231,    -22,    -50,   -128,
+        11,     28,    116,   -215,     46,    217,    204,    153,
+       -73,   -156,   -100,    -31,   2632,   -190,  -2258,    199,
+     -1757,    194,     53,     38,  -5723,     66,    169,    352,
+       -39,   -150,     -1,   -462,     41,    -98,   -110,    -40,
+     -5763,   -190,   -158,  -1380,    205,   -227,   -402,     81,
+      -171,    407,   -125,   -320,   -456,   -317,    489,    698,
+      -308,   3989,   -172,    402,    196,   -457,  -1238,   -192,
+      -581,    -63,   -235,    153,  -1094,    -53,    -45,    -86,
+       240,   -192,  -2660,   2356,    153,    -60,    277,     33,
+       198,    -57,   1221,  -2984,   -327,   -326,    -48,     61,
+        93,    -34,   -167,   -311,    904,    348,    415,     57,
+      2000,    -77,    238,     40,  -3072,    -36,    283,    -54,
+      -655,   -250,    -22,   -569,   -584,    -18,    733,   -251,
+       -72,    -28,     80,   -306,    211,    188,   -149,   4596,
+       305,    372,    351,    -82,   -184,    -79,    -65,   2688,
+      2670,    -54,    -81,   -170,     19,    -88,    122,   -117,
+        33,     51,    -29,   -113,  -2973,     46,  -3294,     90,
+         8,   -180,   -227,    -62,     43,    -25,    187,   -380,
+       -29,    -89,    138,   -352,    231,   2632,    158,   1993,
+       -15,    350,    107,   -982,    -16,  -1120,    136,   -171,
+       -42,   2605,   -186,    110,    167,   1673,   1140,    -29,
+      -689,     81,    909,   -455,   2979,     44,      1,   -260,
+        26,     28,    -90,   -568,   -123,   -175,    232,    -38,
+      2372,    111,    312,    529,    -65,    331,    100,    488,
+        12,   -596,   -497,   2311,  -1097,   1242,    -94,  -2290,
+      -158,  -2651,     16,   -232,   3352,     24,    -53,    -83,
+        -5,    -52,    205,   -104,   -294,    217,   -196,    -37,
+        -7,      0,    -28,    -45,     60,     13,     41,    111,
+       142,  -7331,    -40,   -200,     18,   -166,  -1266,    -47,
+      -250,   -592,   -604,     33,     83,   -204,  -1131,   -166,
+      1348,  -1337,    184,     50, -10066,     30,     24,   -184,
+       137,     53,     32,     87,    -27,    151,    100,     10,
+       -47,     28,   -138,     12,  -2977,   -376,     58,    168,
+      1642,    144,   1039,   -399,   -807,      5,  -1715,     12,
+      -142,    -77,   -306,    758,    674,    -82,   3216,   -369,
+        60,    480,    276,   -423,   5102,   3325,    169,     47,
+       235,     37,     81,    -86,    -28,    -56,    -59,   -205,
+      -126,     28,    279,  -8433,    137,    -26,   -409,    -19,
+       106,   -163,    -76,    -57,    235,      7,    131,    -81,
+      -197,   -318,   1281,    310,  -2934,    972,  -1335,     35,
+      -308,    -93,   -128,    433,    527,   -193,  -1303,    162,
+       -34,    -87,   -157,    262,   4999,     25,   -311,   -349,
+        94,   -262,      0,   -219,     57,     12,     -4,     10,
+       -17,     38,   -320,     48,    156,     80,   5880,     48,
+        45,     31,  -1022,     31,    227,   -727,   -135,    261,
+       -21,   -688,    307,   3196,    565,    627,   -546,    237,
+     -2367,    -33,   1622,    -87,   1722,   -201,    720,   -539,
+      -288,  -1012,    141,   -388,    -72,    -20,    -59,  -2042,
+       -53,   -101,    208,   -233,   -835,    -16,   3092,      2,
+       310,     94,   -362,   -163,   -128,     30,    -22,   -145,
+       420,     -1,    322,   -524,   2742,   -276,    206,  -2475,
+       575,   -653,   -342,   1412,      1,     75,    -14,     54,
+       170,     66,    342,   -261,    709,    -75,   2240,   -134,
+        32,    665,    171,   -134,   1822,    109,    569,   3129,
+       168,   -356,     53,   1259,    -67,     43,    120,   -124,
+      2185,   2461,    -17,   -255,   -349,   -167,   -158,    -19,
+        84,   -732,   -972,    286,     87,   4603,   -160,      7,
+       141,      1,    286,    310,   -315,    -99,    282,    384,
+        68,     93,  -1815,     63,    -86,    121,   -293,    210,
+       115,     63,   -174,    616,  -1848,   -124,   1275,    298,
+       185,   -267,   3516,   -105,   -162,   -253,   -434,   -674,
+       -90,  -2232,     38,    168,   -261,    289,     70,   3714,
+      4096,    -81,     17,     56,     57,     68,    -20,   -146,
+        28,   -152,    -17,    -97,   -131,   2648,     71,  -3359,
+        40,   -277,    313,     85,    -26,     41,   -202,     76,
+         8,    -80,   -160,   -102,    -17,    155,    189,   1552,
+     -3498,   -446,   -103,   -232,   -205,   -574,   -132,    169,
+       206,   1689,   1043,   -736,   -178,    -93,  -2969,     26,
+      -251,   -148,    139,     70,   -325,    117,  -3073,      9,
+        43,    -11,   -380,   -190,   -314,  -3012,     50,   -330,
+       -26,    710,    153,     19,  -2943,     58,  -3052,    -56,
+         7,     40,      9,    321,    -37,   -461,    -22,   -374,
+        57,   -203,     16,    -15,    -25,    -16,    -37,     -8,
+       -41,   -116,   7964,     70,    -59,     77,    200,      0,
+       -43,    118,    -72,    -67,    104,     -6,     78,    171,
+        13,   -103,    793,     98,  -4738,   -204,     11,     30,
+       -72,     33,    -62,     47,    157,    236,   -147,   -416,
+      -726,    578,      5,   4038,    162,     -2,   2367,   -138,
+      -185,    470,   3121,     70,    185,    -22,   -205,     37,
+       -63,   -335,   -397,     43,     10,  -6557,   -112,   -254,
+       106,   -129,   -236,      0,   -250,     42,   -128,     84,
+      -531,    -27,   2259,   -282,    -21,    -70,   -408,     19,
+      -664,    945,   -196,  -1074,   1369,    -40,  -3233,     28,
+        20,  -2133,    125,    343,    113,    584,    -14,     50,
+      -130,   -464,    513,    807,  -4474,    -63,     57,   1120,
+        64,    -30,    346,    462,    129,    219,    -30,    287,
+       448,    384,    198,   -359,   1097,   -256,    828,  -2635,
+      -314,    336,    506,   -144,    194,    167,   1323,   -273,
+     -4168,   2805,   -118,     -8,    136,    -82,   -212,     53,
+      -259,    -61,     94,    214,     11,     29,   -262,    -69,
+        24,    102,     45,    -31,   -186,     58,    641,    659,
+      -172,   3628,   -192,   -423,     34,      3,     45,     19,
+       349,    117,     -5,  -4923,     99,   -148,    180,    631,
+        50,   -204,    641,    -92,    156,  -1985,   1077,    201,
+        56,   -405,    710,   -220,  -1917,   -273,   -234,    100,
+};
+
+static const int16_t cb2224sl0[] = {
+     -3113,     97,    229,    309,   -156,   -226,   -469,    582,
+     -3202,   -336,    102,     20,     96,   -960,    297,   -227,
+       592,  -3352,   2798,   -637,   -133,    191,   -407,    170,
+      -576,   -203,   -280,    808,    853,   -502,   -113,  -1704,
+     -1025,    411,   2802,    233,   -568,    360,   -616,  -1715,
+        47,    391,  -2117,   -458,   -291,   -149,    -82,     26,
+       -29,    -88,   -156,   7905,     32,    -75,   -154,    -78,
+       -44,    155,     -1,   -338,   -891,    170,    -75,    155,
+       226,   -192,   -328,   -239,   -574,    -91,     95,   -600,
+      4271,     25,    990,   -207,   4676,     59,   -324,    884,
+       363,     65,    423,   -776,   -906,    -79,     -4,   1475,
+       549,   -252,   3584,   3543,   -409,    282,    278,    125,
+      -379,    125,   -180,   -123,   -252,   -316,   -193,    347,
+        53,   2009,    195,    152,   -104,    233,    -75,   -546,
+       564,   -177,   3243,   -865,   -924,    518,   -692,   -381,
+     -1885,   -110,   -188,   1140,  -2043,   -438,  -1721,   1019,
+      1678,     13,    273,   -751,    922,   -291,    -15,     75,
+       232,   -112,     60,   2702,     88,    175,   -119,     43,
+      -549,  -1094,  -1879,    401,   1587,   1287,    -41,     41,
+      -116,    -23,    313,    168,    147,   -101,    -57,   -115,
+     -6990,     54,    -14,   -240,   -164,    127,     25,   -703,
+      -361,    769,   1555,  -2440,  -2616,   -192,     86,    769,
+       -29,   -721,    554,   -663,    327,    659,    -31,    -79,
+        91,    365,    -74,   1268,    115,    480,   3054,  -1758,
+      1704,    759,   -657,   -272,   -329,     31,   -145,   -534,
+      1265,     73,    435,    -54,    480,   -867,   2724,   2373,
+       890,   -314,   -112,  -2576,   -598,    473,    121,   2764,
+      1659,    105,    579,   -416,    -87,    158,    300,    447,
+      -281,  -6109,     35,    217,    185,     56,   -357,    151,
+       108,    -49,   -282,   -484,   -220,    -78,   -141,    256,
+     -1095,   1812,   -985,   1115,    555,  -2116,   2317,  -1141,
+      -792,   -866,   -119,    187,    615,   -194,     73,    -43,
+       268,    437,    250,    -52,    477,   -249,   -475,  -2621,
+       590,  -2987,   -603,   -652,    971,   -684,    337,   -140,
+      -336,   2342,    390,   -204,    295,     85,    -44,    321,
+       754,   2660,     61,    782,   1654,    -76,   2727,   1590,
+     -1099,    354,     49,   2784,    443,   -762,    828,   -308,
+      -493,   -755,   -370,   -336,   -207,    388,    630,   -127,
+      1955,   1929,   1270,   2054,    525,    388,    562,    942,
+      -789,   -453,    158,    995,    -99,   2258,   -317,   -493,
+       385,    -90,    -79,    199,  -1187,    519,   -254,    179,
+       573,   2803,   2341,    407,     95,    515,    332,      1,
+        -6,   -337,    142,   -316,    418,    542,   3281,     10,
+       604,   -542,  -1595,     43,     79,     10,     75,   -122,
+       100,    -55,    212,   -223,   -353,   -557,    490,   4870,
+     -3689,   3594,   -145,   -192,    -47,   -252,   -380,   -180,
+      -221,    656,     78,   -188,    120,    135,   -253,   -437,
+      -208,   -151,   -504,    217,  -3715,   -150,    528,    121,
+     -1468,    383,    823,    -55,  -1167,     -8,   -198,   -515,
+      -296,    -24,     84,    129,   -472,      7,   5071,   -114,
+      -200,    -16,   -271,     59,   -430,   -142,   -315,     90,
+       273,    -56,    370,   3342,   -159,    235,    934,   1605,
+     -1499,    207,  -1650,   1137,    396,  -2250,    276,   -320,
+      -317,    -23,    276,   -519,    163,    566,    366,     -6,
+      2262,  -2035,   -662,  -3300,   -133,  -3811,   -362,   -348,
+       113,    146,    -79,   -298,    238,    221,     99,    194,
+       326,    325,   -112,  -8160,    -59,    -15,      8,    -41,
+      -261,    -20,     -6,    -68,   -140,    -41,    167,   -125,
+       129,    337,   2404,    281,   -336,   -475,   2085,  -2646,
+       572,  -1308,    376,    114,   -506,   1062,   -575,   -529,
+      3347,   -212,    520,    274,   -163,  -3058,    -93,   -203,
+      -932,   -207,    -36,    303,   -117,    278,    287,    204,
+       205,   -228,   -242,    227,      3,    611,   -190,   -458,
+       -44,   -209,    122,   -390,  -4561,   -139,   1378,   -329,
+       440,    989,  -1782,   -348,   1241,    967,   -477,  -2312,
+       554,   -970,  -1103,    473,   -771,    -50,    150,    327,
+       394,   -267,   -648,   -680,   2376,  -2543,    276,   1220,
+       552,     10,   1399,  -1498,   -801,      9,   2351,    -55,
+       155,    327,     88,    864,    428,    179,  -3234,      6,
+       544,   -647,   -306,    132,    329,   1147,   1920,   1436,
+     -2107,  -1122,    341,   2020,   -432,    -97,    117,    793,
+       100,   -693,    174,   3639,   -570,    910,  -2771,    231,
+      -148,   -960,  -1085,     57,    188,    744,   -709,   -441,
+       533,   -295,   1287,   2939,   2987,    885,    611,    700,
+       364,   -205,   -855,   -617,     48,   -162,   -244,   -318,
+       208,    772,   -124,  -2505,    454,    330,   -220,    335,
+      -362,   -899,   -827,   2188,    -40,  -1638,    356,   -160,
+      -127,   2886,    -69,    -41,    209,   1847,   -236,   2752,
+       -24,    387,    354,   -111,    526,   -237,  -2169,   1319,
+      2211,    144,   -348,   -434,   -319,   1373,     78,    906,
+       701,    539,   -134,    414,    496,   -325,    -36,    116,
+       124,   4198,    -35,   -439,   -208,   -531,   -100,   1453,
+      -175,    723,   -908,   -461,     87,    127,    -91,   -125,
+      -140,   8012,   -186,     23,    -93,    107,    176,    218,
+        35,    193,    174,    -27,     -4,     77,   -103,   -199,
+       116,    -41,    -80,    186,  -6965,   -188,    125,    -54,
+        43,      9,    -49,   -192,     69,   -136,    -24,   -117,
+     -2244,   2289,    145,    226,  -1161,  -1950,    881,   -152,
+      1611,   1015,   -174,   -277,   -158,    369,     49,   -233,
+       221,    275,     69,    108,    136,   -124,      1,   -470,
+       376,    149,  -7596,     55,     53,    213,   -247,     80,
+      -217,    -11,    189,    125,    -17,   -141,    165,  -2890,
+        14,    201,    106,    242,   -254,   -306,  -3157,    459,
+       -10,     24,   -271,    877,    437,   -438,     18,   -126,
+        -9,   5553,     63,     22,     55,    172,     21,   -335,
+       127,    160,    208,    121,     13,   1989,    676,   -294,
+      2208,    -78,    634,  -1518,  -1037,   1309,    124,    -39,
+      -322,  -1420,   -404,    377,    -35,    -14,    178,    110,
+     -8146,     26,    -98,   -153,   -243,    145,    280,     -8,
+        29,    -57,     85,   -309,    281,    282,    -47,    -27,
+      2827,   -947,    141,    856,  -2481,    406,   -638,   -362,
+     -1031,    230,   -341,   -119,    -17,      1,    190,     41,
+       -15,   5111,     59,     74,    123,   -282,    -25,   -300,
+         4,   -460,   -216,    295,   -217,     26,    227,     62,
+       385,    748,   2923,   1946,    391,  -1676,    599,    148,
+      -456,    -96,   1066,    478,    117,    255,   -169,   -669,
+     -1939,   -656,   2676,    677,  -2020,  -1314,    425,   -525,
+       -89,   -522,   2707,    153,      5,   -207,    244,  -1045,
+       331,  -1315,    -82,    449,  -2444,    326,   -484,  -2232,
+      2380,   -591,   -999,  -2552,  -1581,    349,   -440,    217,
+       298,   -729,     -6,   -396,    -74,    110,    -70,  -3543,
+      -388,    -51,    596,    126,    295,   2075,   -123,   -693,
+     -1072,  -1779,   -420,    127,    432,  -3241,   -231,   -246,
+       105,   -437,    -67,   -119,  -2941,   -257,     47,   -969,
+       379,    618,    -93,      7,    202,   -425,    -38,    140,
+       458,   3599,    242,    -24,   -811,   -624,    -19,    524,
+      2398,   -300,    111,    376,   2015,    431,    125,    231,
+      -293,  -2379,   -634,   1842,     -1,  -1326,   -610,    -88,
+       128,     80,     75,     30,    172,   -235,     34,    206,
+       -79,    328,    128,   -283,  -6862,   -101,    260,     68,
+};
+
+static const int16_t cb2224sl1[] = {
+     -3710,   -340,   3183,    200,   -124,    423,   -417,   -432,
+       232,   -808,     85,   -145,     39,    196,   -197,    -60,
+      -154,   -213,   -320,  -2941,    993,   3044,   -508,     61,
+      -853,     75,     40,    873,   -765,   -365,   -621,  -2670,
+       188,     57,   -403,   -230,   -137,     40,    565,  -1910,
+     -1120,  -1019,   -603,  -1927,    150,  -3089,     23,   -416,
+      -199,  -3265,     15,    128,   -525,   -531,     91,    -39,
+       578,   -388,    315,     40,   2376,   1762,      2,  -1475,
+     -1774,    111,    934,   -459,    777,   -582,    114,   -218,
+       -82,   -195,    165,   2171,    632,    -67,    239,    345,
+      -257,    104,    -34,   -879,    488,   -422,  -2156,   -823,
+      1940,    699,   2911,   -233,   -125,   -218,   -111,   -335,
+     -3475,    -61,    -71,   -445,    249,   -330,    102,    376,
+      -116,   2667,   -453,     19,  -4129,     90,   -507,    236,
+       418,     43,     79,     61,    296,    181,    190,    408,
+       216,    198,     32,    -81,    245,   -157,   5555,   -162,
+       318,    179,    339,   -463,   -448,   -254,   -526,   -192,
+      -427,    575,    588,   2792,   2683,   -853,   -566,     19,
+       -26,    106,   -220,    518,    734,   -233,     68,   -604,
+      -231,    256,   -187,    -59,   -405,    206,    331,    -25,
+     -4837,   -323,    146,    541,    723,    915,   -144,    450,
+       102,   -371,     27,     88,    -80,    276,    239,    101,
+       157,    -69,    -14,    234,  -8192,    -18,   -110,    -52,
+        -8,     48,     79,    -43,    153,    187,    211,   -118,
+      -111,    238,     11,  -2006,    680,    478,   -695,   3078,
+       -30,    892,    -23,   1512,   -194,    423,    -16,   -318,
+       895,    406,    634,     47,  -3277,   -205,   -764,    297,
+      -357,    -61,   -188,  -1547,   -868,   -174,    342,    261,
+      1926,     88,    -35,  -3250,    -20,   3168,   -368,    778,
+       376,    167,    598,    442,    134,    487,    164,    -32,
+       245,    436,   2067,    595,   -578,     49,   -163,    633,
+       138,   -279,    -99,    118,   1141,  -3168,    580,    -90,
+     -3192,    551,   -663,  -2673,    -55,    147,   1307,      9,
+        15,    432,    307,    527,   1002,   -469,  -2380,   -342,
+      -293,    -73,   -259,    410,    309,     76,   -320,   -161,
+       282,  -3300,     -7,    160,    732,    484,    -65,    147,
+      2923,   2321,   -840,   1933,    268,    684,   1172,   -377,
+      -365,   -568,   -283,    492,   -538,    409,   -194,     17,
+      -297,    -52,   -123,   -270,    161,    -94,     92,   4495,
+      -396,    540,    229,    -30,   -108,     29,      1,    198,
+       492,   -572,   -394,  -2386,   2787,    885,  -1175,   -129,
+     -1137,    220,    148,    261,    -65,   -244,      1,     58,
+       195,    -49,   -290,    -94,    -21,    105,     71,   6641,
+      -200,   -407,   -496,    -75,    233,    222,    549,    363,
+       188,    739,   -869,    122,   -355,   3326,    323,  -2366,
+       115,  -3207,   2783,   2015,    148,    924,   -153,   -133,
+      -175,   -287,    400,     73,   -181,   -174,     72,     45,
+       219,    -92,    -11,     59,  -5407,   -362,   -188,   -120,
+       239,    249,    133,   -229,    158,    180,   -575,  -2386,
+      -354,    248,    532,   -590,    615,    -85,    -69,    394,
+      3052,   -877,   -320,    484,    218,   -463,   -202,   -841,
+      1729,    284,   1253,   2193,    526,  -2444,   -351,   1287,
+      -373,    387,    440,   -203,    163,   -153,    206,    -57,
+       -96,   2616,    -84,    552,     33,    705,   -731,   -843,
+     -2197,  -2138,   -570,     22,   -264,   2143,    725,   -132,
+      -392,    471,   -245,     51,    739,  -1057,   1049,   -760,
+      2701,    456,     20,    484,    595,   3248,  -1415,   -862,
+       332,   -417,    323,   -431,   2082,     78,    684,   -169,
+       596,   -228,   -219,    172,    160,   -180,   -228,  -3193,
+      -520,   -100,   -447,   -629,  -2178,   -259,   -246,  -1788,
+     -2264,    223,    115,    -74,    230,  -2515,    212,   -179,
+       456,    209,  -2379,   -246,   -345,   -102,   -559,    259,
+      -270,   -426,    333,   -358,   2866,   -589,  -1494,   -418,
+      -160,   -138,   2088,    683,  -1313,   1061,    -88,    916,
+      -148,  -2329,   -301,   -271,   -249,   2822,   -525,   -405,
+       592,   -322,  -1328,    -16,    135,   -582,   -676,   -503,
+     -2162,   -327,   -237,    361,    166,    600,   1176,   1015,
+        97,     -5,    465,   2321,  -4544,    202,   -350,    313,
+       149,    544,   -420,    552,    183,    351,  -1663,    688,
+       238,    587,    907,  -1719,   1267,  -2325,    368,    236,
+       296,  -2608,    240,    997,    496,    105,     75,   -179,
+       235,    125,    -40,     57,    -22,   -412,   -464,   -494,
+       -81,    576,  -3461,  -1037,   -744,   1358,   -856,   -284,
+      -536,    387,   -358,    184,    -85,   2150,  -1142,   -124,
+       119,   1242,    648,    711,   2161,   -591,  -1864,   -672,
+        62,   1879,    -13,     55,    285,   -167,    142,   -130,
+       322,      8,    -35,   -230,    632,   -699,   4114,   -500,
+      -189,    -48,   2746,     47,    421,  -1200,   2418,    460,
+      -306,    331,    164,  -1358,    802,    453,    458,   3594,
+      3065,    -24,   -134,   -437,   -892,   -110,    241,   -368,
+       336,    673,   -147,    130,    154,     89,     81,   -341,
+      7151,    175,    118,   -227,   -282,    262,    276,   -118,
+      -118,   -245,      7,    144,    -87,   -136,   -146,   -484,
+        70,    221,   -220,    -13,  -7638,     93,    -38,   -319,
+      -478,     26,    -28,    281,   -180,    182,   -186,     90,
+       192,     50,  -2919,    153,  -2651,    289,     47,   -783,
+       768,    384,     39,    194,  -2358,   1242,  -1679,     80,
+      1292,     28,    682,   2807,    342,    466,    299,   -380,
+       376,   4466,     12,    553,    153,   -447,    733,     99,
+         8,   -142,    606,  -2364,    168,    167,    -62,    404,
+     -3144,    352,    115,  -3734,    360,   -202,   -462,   -196,
+       464,   -412,    192,   -363,   -413,   -405,    254,    357,
+     -2801,   1054,  -1602,    642,   -254,   -430,  -2259,    -97,
+        16,   -311,    757,    -64,    412,    339,   -227,   -216,
+       -29,    219,     67,     63,     26,   -232,   -138,   -301,
+       241,    -52,  -6118,    223,   -379,   -157,   -221,   -201,
+       -93,  -5630,   -286,   -194,    133,     46,    151,    444,
+      -472,    103,   -115,   -259,    -53,    673,   1744,  -2374,
+       359,   2541,    613,   -393,   1235,    221,   -117,   -842,
+      1166,    105,   -142,   1426,      3,   -423,     36,    398,
+     -2742,    723,   -740,    985,    498,    431,  -1312,    832,
+     -1644,    146,    -69,   -110,    420,   -130,    335,    269,
+     -2865,    -67,    -88,     50,   2735,   1038,    973,    371,
+       654,   -169,   -112,    579,   -319,   2434,   -760,    710,
+       241,  -1889,     39,  -1807,    -30,   1383,  -1080,    449,
+       639,  -2478,   -760,    559,    298,     56,   -421,    818,
+      -442,   1558,  -1610,   2136,    -12,    -11,    592,     73,
+        77,   -172,     77,     92,   -113,    281,    581,   -584,
+     -4448,    507,   -195,    183,   -508,    312,   -724,   1043,
+       -18,    -10,   -776,   -534,    249,  -3178,    904,   1234,
+      -482,    382,  -1040,   -448,   -579,    227,    -82,   5628,
+      -165,    255,    109,   -141,      7,    -28,     63,     93,
+      -211,      0,    162,    581,   -153,   5844,    -66,    122,
+      -102,    -90,   -205,   -181,    243,    312,    111,   -435,
+      -105,   -343,    272,   -141,      6,    -98,    -16,    -73,
+       -26,   -125,  -7627,    -73,    -66,    108,   -175,    186,
+      -189,   -102,   -240,    -37,   -354,   -260,   -120,     30,
+        87,   2560,   3157,    369,   -662,    338,   -503,    -66,
+     -1405,    178,   1100,   -683,  -2618,   2459,  -1291,   -248,
+      -139,   -683,   -865,   1445,    165,    368,    507,   -585,
+};
+
+static const int16_t cb2224ss0[] = {
+     -6880,    657,   -621,     69,    219,   -588,    681,    229,
+       248,   -302,   -110,    734,     12,    253,   -454,   -890,
+     -3596,    778,  -2600,   -256,    529,    332,    -69,    295,
+      -455,    982,   -265,    -70,   -332,   -367,   1494,    586,
+      -158,  -1054,   2529,   -313,   -661,  -1302,  -2486,    476,
+         5,    126,    581,    361,   1618,    650,   2033,    202,
+        76,   -265,   -161,   3659,   -800,   1069,   -167,  -1792,
+       389,   -580,    597,   -268,    621,  -1035,    710,    854,
+      2004,   -785,   2714,   1659,    785,    800,    -80,      9,
+      -341,  -1032,    789,    651,   1068,   -609,    661,    747,
+      -928,   -999,  -1369,  -1173,   -416,   1596,  -2800,    330,
+       546,  -1275,   -746,   -392,   -529,   -378,   3571,  -2795,
+      -731,   -183,   -330,  -1591,    371,    866,    323,   -516,
+       -89,   2277,   1593,    960,  -1726,  -2229,    727,   -415,
+       189,    500,   -145,   -177,    550,    467,    240,   1131,
+       474,   -419,  -1236,    674,   -616,   -519,   2439,  -1213,
+      -650,    867,    974,   -908,   1229,   -512,    932,   -495,
+     -2521,   -865,   -466,      8,   -426,    912,    -77,   -236,
+      -407,    433,    128,   3653,    854,    243,    770,    191,
+       224,    -68,   -453,   -383,    279,   -701,   -691,    282,
+      -449,   1148,   -783,    241,  -5021,    643,   8113,   -345,
+        13,     90,    -57,    475,     64,   -268,   -163,   -100,
+       -95,    518,    577,    541,   2055,    358,   -157,    360,
+       280,   -840,  -1161,    500,     95,    302,   -662,   1134,
+       827,   3300,    695,    775,   -798,  -2651,  -2891,  -1123,
+       555,  -1125,    156,    328,    671,    751,   -347,   -972,
+      -392,  -1216,   2725,  -5152,   -402,    -15,    150,     31,
+      -182,   -278,    245,     81,     -3,    -46,    310,    -72,
+      -138,   1511,  -1762,  -1840,   -364,    123,   2801,    -16,
+      -543,  -1312,    562,   -262,    148,    521,   -711,     61,
+      -863,    145,    329,    761,     76,   -155,    101,  -4986,
+       192,    269,   -364,   -174,    640,   -261,    629,   3638,
+       397,  -1757,  -1177,    342,    388,   1089,    824,    115,
+       150,    125,    806,   1271,   -198,    800,   -175,   -897,
+      -649,   -837,    690,   -755,   1416,  -2347,   1179,   -781,
+       826,   1567,   -148,   -156,  -1036,  -1572,   1248,   -187,
+       464,   -260,   -749,  -1070,     85,   -466,  -2160,  -2802,
+       233,   -181,    447,   -482,    113,    548,   2957,  -1600,
+      1341,   -559,    803,   2085,   -807,   -711,  -1169,   -456,
+       657,    -76,   -147,   1932,  -1054,   -967,  -1100,    -49,
+     -2829,   1412,    929,   1207,     58,   -146,     77,   -458,
+       538,   -627,    -12,    214,  -2397,    692,   1284,    366,
+      1286,   1997,   -856,    267,   1866,   1236,     25,    254,
+     -1187,   3456,    283,    584,   2348,    604,  -1130,      7,
+       500,    232,    -51,    120,   -695,   -930,    317,     67,
+     -1346,   -500,    312,  -1060,  -2338,  -1860,  -1491,   1539,
+     -1707,    778,   -653,    -41,    401,    311,    -13,   2155,
+     -1011,   1163,    712,   2090,   1336,   -726,    574,   1200,
+     -1254,  -1567,    723,    683,   -877,   -653,   1137,  -1594,
+      1127,   2641,    465,    259,  -2095,    696,   -405,     40,
+      -259,   -808,   -942,    395,   -180,  -1119,   -966,   -230,
+      -534,   -114,     88,   -661,    757,     75,   -286,   -119,
+       924,  -2925,   2483,   1662,   1823,    590,   4307,    810,
+       447,    165,    243,   -184,   -162,    436,   -126,   -194,
+       365,    601,   -354,  -1983,   -211,   -663,    276,    155,
+      -696,  -2542,   -830,   2374,   -235,   -585,   -469,   -478,
+        21,    867,  -1633,   1949,   -949,   -330,   -546,    328,
+      -224,   1236,    266,  -1117,     36,    -61,    221,    153,
+     -3491,  -1463,   -237,   4676,   -241,    273,    268,    347,
+      -393,   -277,    168,    426,    155,    -65,   -605,   -569,
+     -1416,  -1303,   1248,    595,   -148,    512,   3622,    291,
+      -444,   -523,    616,    105,    101,   1357,    772,   -337,
+       494,    570,     15,    150,   -400,    572,    590,   1674,
+     -4106,    940,    167,   -327,   -336,    696,    591,    362,
+       279,   4489,  -1325,    608,    294,    -41,    549,    982,
+       -31,   -184,    367,     77,   -466,    398,  -1928,   -607,
+       239,     55,     15,   1031,   -486,   2788,   2151,   -519,
+     -1197,  -1144,    274,    671,   1620,   2079,  -1555,   -961,
+       543,    -11,     26,   -627,    777,   -581,  -1060,  -1177,
+      -808,    807,   2863,    607,    144,    195,   -274,     18,
+     -5656,   -355,  -1026,     56,    116,   -431,   -493,    517,
+       286,    353,    353,    199,   -651,   -863,   -276,   -556,
+      -562,   -867,   -143,   -355,   -323,    -14,    -54,  -5354,
+       -43,  -1592,      8,   -543,     24,     94,   -731,   -545,
+       705,   -171,    504,  -1078,  -3367,   1349,    452,   -148,
+      1183,  -1650,  -1400,   -246,  -1032,   -119,   -309,   -566,
+       998,  -3240,   -444,   -658,   -605,   -186,    491,    439,
+      -190,    688,    -29,   -965,   2562,   -112,   -329,    -25,
+     -2593,    355,    -53,    692,     12,   -593,   1930,   -804,
+       -82,    386,   -632,    927,   1006,   -229,  -1147,   -181,
+     -1075,   -245,  -3678,    904,   -298,   2263,     50,    563,
+       337,  -1051,    173,    310,  -3540,   -615,   -504,    749,
+       192,    -90,   -113,   -730,  -1994,    802,    -45,   2234,
+       167,    289,   1722,   -562,    682,    453,   1571,    171,
+     -2429,   -441,   -230,  -1144,    985,  -1602,    358,   -685,
+       -23,   -523,   -529,  -2438,    700,   -624,     37,  -1475,
+     -1318,   3292,    702,    394,   -798,   2563,   1057,   -335,
+       614,    270,   3135,  -1281,  -2089,   -250,   -140,     45,
+      -517,   -470,  -1429,   -172,   2637,    267,     55,  -1037,
+      -174,    912,   -865,   -786,   -406,    537,  -2805,   -642,
+     -1599,    888,  -1044,   -175,    312,     28,  -1157,   -240,
+      -181,    298,    521,   3802,    -87,     93,     48,   1336,
+     -1071,  -1870,    339,  -1106,   -944,  -1036,    361,  -3719,
+      -147,    625,    326,   -122,    407,   -217,    396,    273,
+        -2,   -315,   -262,    632,   6868,    228,   -267,    207,
+       -29,   -274,    192,     63,   -353,    588,    550,     -3,
+       156,   2115,   1580,  -2366,    306,    633,   1354,   2313,
+      -360,   -345,    270,   -499,   -976,  -3685,  -1305,    907,
+      1431,   1545,  -1334,     18,   1159,    229,   -124,    157,
+       470,   -105,    700,  -1786,  -1895,    795,  -1052,   -278,
+       745,   -111,    -45,    694,    599,  -3469,    552,    -70,
+      -222,     45,    896,   -251,      1,    250,   -769,    301,
+     -1151,   1313,   4314,    710,    680,   -169,   -663,     40,
+       399,   1171,    581,    775,    936,   -488,  -2918,    155,
+      -169,  -1560,   -862,   -473,    783,    -72,  -1791,    567,
+     -2109,   -156,   1250,  -1486,   3253,     61,    -50,   -374,
+      -277,    942,    111,    607,   -316,    197,   -748,    871,
+       612,   -242,   -296,     53,   -193,   1233,     11,   -962,
+       505,  -4492,     21,    754,   -150,    451,    183,    881,
+      -652,   -159,   6384,    170,    271,   1035,    401,     48,
+      -463,   -240,    -95,   -625,    613,    -91,  -1138,   1172,
+       542,  -1483,  -2638,  -1396,  -1173,    612,    512,   1355,
+       977,   -362,    -22,    -17,    124,  -3178,   -532,    352,
+     -2691,    610,    569,    740,  -1603,     -5,   -492,    704,
+      -436,    -96,   -595,  -1495,   2730,  -3089,   -164,    565,
+      1300,   -477,   -569,   1069,    294,   -233,   -133,    708,
+       150,    388,  -2108,  -1042,  -1603,   2275,  -1722,    561,
+       140,    507,   -899,   -281,    162,  -1297,   1504,   -158,
+       193,   -730,   -944,  -2484,    615,    -30,     32,   -354,
+      -383,     86,    329,  -3434,   -382,  -1604,   -299,    208,
+};
+
+static const int16_t cb2224ss1[] = {
+      8192,   -187,   -471,   -201,    185,   -465,    976,    257,
+        83,   -530,    310,    676,    341,     48,    265,   -351,
+       306,    280,    302,     48,    496,   -339,    424,  -5250,
+      -253,    604,   -317,   -289,    278,    573,   -579,     79,
+      3218,   -574,   -377,    276,   2831,   -287,   -254,    332,
+      -225,     42,    162,   -457,   -959,  -1421,    683,    -59,
+       -33,   3362,    393,    606,    249,   -873,   -930,   1224,
+      1469,     37,  -1592,   1665,   -582,   1729,    284,    106,
+     -4753,   -120,   -475,    867,   -444,   -203,    431,    -11,
+      -526,   -324,    732,  -1070,   -160,   -611,   1808,   -297,
+      -536,   -194,   -822,   1224,   2220,  -2330,     72,   1004,
+      -787,   -149,    557,   2925,     29,    809,   2397,  -1143,
+       648,    904,   -568,   -707,   -839,   -274,  -1322,   1177,
+      -467,   -482,  -5181,    234,    223,    354,    386,    737,
+      1273,    234,   -353,     31,     -8,   -392,     85,   -234,
+      1366,   1449,    120,   -695,    838,   -622,    -96,    382,
+     -1421,    612,   -173,  -3199,   -150,    474,   -394,   -561,
+     -1171,   2541,   -271,   2513,    670,    285,    636,   -452,
+      -202,   1319,  -2182,   -935,   -586,    243,   -813,    -41,
+       -53,  -1041,    212,     58,  -3424,    111,    268,    964,
+     -3231,   -500,    867,   -191,    207,    543,    383,  -1509,
+     -2712,  -2752,    201,    428,    721,    498,     19,   -747,
+        67,     87,    500,   1200,   2244,  -1158,    466,  -1032,
+      -153,   1197,   2737,   -324,   2002,   -338,     89,   -428,
+        78,    575,    330,   2013,    175,    305,    567,   -539,
+        17,    384,    485,    860,   3330,    173,    586,    649,
+       388,    963,   1820,  -2610,    251,  -2966,   1383,   -153,
+      -146,    564,   -718,    998,  -1283,   -566,   -619,    394,
+       459,  -1233,   2566,   -357,  -2601,     98,   -929,   -367,
+      -501,     96,   1217,  -1695,   -324,    393,    261,   1745,
+     -1095,   -751,    924,   1044,   -337,  -1243,    393,   2454,
+     -1499,   -245,    902,    925,  -2126,    167,    838,    638,
+      2296,   -294,    306,   -715,   2794,   1522,   -339,     21,
+       318,    -95,   1334,     75,   -173,    -91,  -2012,   -920,
+      -801,    334,  -3363,   -348,    550,   -911,   -261,  -1073,
+       185,   -425,    431,    515,   -339,   1817,  -1589,    241,
+       548,   -337,   -471,  -3532,  -1166,    888,    141,   -277,
+      1353,    310,   -654,    198,   -516,   2951,   2251,   -534,
+       701,    237,     20,   -597,   -301,      3,    410,   -456,
+      -581,  -1254,   1052,   1321,    165,   3108,    477,    196,
+      2716,     85,      5,    -34,    721,   -562,      4,     84,
+      -793,    744,    243,    134,   -385,   -129,   -122,   -128,
+      -333,   -483,   -604,    269,   6209,      3,    515,    -63,
+      -634,   -551,   -795,  -1696,  -2210,   2184,    348,     30,
+       413,   2531,    214,    214,   -186,    -72,   -552,    958,
+      1727,  -1639,    618,    -61,   -432,    365,   -753,     15,
+       -14,     33,    976,   -940,   -355,   3318,    677,  -1938,
+        21,    881,   -326,    -83,  -3355,   1483,  -1211,   -674,
+       166,    139,   -276,    158,   -736,   1038,  -1005,   1129,
+      1219,   1115,   -392,    558,     96,   -188,    314,    536,
+      -423,  -3262,    395,   -130,   1099,    304,   -181,    853,
+      -160,  -1272,    428,   -179,    634,    608,   -173,   2690,
+     -2191,   1385,   -518,   -416,   3239,   3250,    313,    -23,
+       200,    643,   -639,    -17,   -208,     27,   -182,    262,
+      -203,   -671,    157,  -4131,    383,   -404,    337,     51,
+       431,     92,    138,   -438,     29,    337,    488,   -252,
+       656,    509,   2037,   -635,  -1074,  -1115,  -2135,   -772,
+      -386,   -214,   -654,   -441,   1661,    542,   -383,  -1720,
+        22,   -103,  -1474,  -1288,   4361,    282,  -1252,    734,
+      -858,   -556,    294,    243,    293,    133,    848,     65,
+      -727,   -887,  -1314,    443,    -96,   -422,   4268,    672,
+       142,    608,   -442,    843,    365,   -866,   -157,    780,
+       107,   -888,   2089,   1769,     73,    739,    -15,  -1730,
+     -1235,    920,  -1713,    163,    552,   1479,   -692,   -755,
+      1430,   -193,   -276,   -264,   -690,    772,   1403,    -40,
+       679,   -260,    642,  -3562,    962,   2053,   1348,     36,
+     -2974,    155,    303,    821,   -944,   -179,   -967,    632,
+      -725,    411,   -447,   -463,    694,   -337,   -146,     59,
+        -1,   -416,     12,    524,   -497,  -4682,   -745,    625,
+      1011,     20,   -462,   -503,   2012,   -475,    -27,     85,
+     -1190,    534,   2250,     87,   2591,   1195,   1665,    423,
+      -813,   -571,   -372,   2601,  -2013,   -853,   -734,   -403,
+       793,   -549,   1243,    312,    722,  -1013,  -1434,   -749,
+      -571,    494,    -88,   -129,   1331,    806,  -1227,    326,
+     -1164,   2487,    -59,   2346,    583,    519,    368,    793,
+      1178,    661,    140,   1226,    378,   -429,  -1214,   1438,
+      -319,    -77,  -1495,   3598,    361,     21,     39,   1930,
+       198,   1050,    531,    274,     32,   -499,   -349,     -5,
+      -133,  -3324,   -379,   -742,   -250,  -1618,  -1536,   2084,
+      1369,    765,   -132,   -324,    406,  -2198,    314,    502,
+     -1431,    759,   -729,    320,  -2120,   1484,   2468,  -3283,
+         4,    272,     -2,    492,     91,   -803,     48,    691,
+       375,     87,   -508,   -725,   -632,    268,   2929,   1302,
+       -11,   -628,  -2225,    723,    533,    909,    934,    682,
+       350,   1509,   -707,  -1142,    106,  -2174,    342,   -965,
+       456,   -655,   1137,   -553,    415,   -418,  -2631,   -121,
+       237,      3,  -1123,  -1555,  -1413,  -3333,    717,    115,
+     -1030,  -1007,   -819,    130,   -851,    281,    -43,   -473,
+     -1091,    326,    869,   -377,    278,   -148,    418,  -2104,
+      -422,    623,  -1777,    633,   1033,  -2031,  -1221,   4126,
+       -60,    -16,   8025,    243,   -340,   -599,   -501,   -289,
+      -219,   -104,   -230,    464,    191,     18,    345,    -65,
+       -68,   -481,    625,   -822,  -4011,   -516,    741,    734,
+      -316,    530,    122,    945,    371,   -298,   1194,   -250,
+      -167,    392,    -95,   -151,     -1,   -486,    189,     90,
+      -140,     30,   4485,    581,     54,   1905,   -895,  -2032,
+      -174,   2473,   -688,   -104,   -315,   -376,    830,    296,
+      -548,    754,    195,   -901,  -1548,  -1931,    792,    510,
+       294,    153,    619,  -1034,  -3038,   1134,    142,    -29,
+      -806,   -118,    -29,  -2314,   -159,    770,  -2899,     23,
+     -1045,   1037,   1496,   1104,   -527,    135,   -281,   -310,
+       -59,    202,   -346,   -612,    206,     27,   -456,    758,
+        67,   3547,    867,    227,     -3,    573,   1440,    421,
+       170,   1491,   -691,    -43,     -8,    784,    307,    557,
+       618,  -2387,    566,   -396,    182,    877,  -2666,   -163,
+       553,   -155,    691,   -188,  -1584,  -1085,   1033,   -308,
+      1356,   -570,   -721,   -232,  -3145,    104,    511,   -964,
+      2783,   -685,   -168,    -51,   1554,  -1816,   2431,    327,
+      -440,   1174,   -265,    -36,    120,   -397,   1094,  -1254,
+      -973,    574,   1085,   -139,   -751,   -529,   -240,     25,
+      1137,   -467,  -3471,    338,   -806,  -2028,     94,    -98,
+      -336,   -537,   1189,   -880,  -3607,   -168,    -59,    100,
+       309,   1097,    295,    262,    106,     -8,    210,  -7461,
+       395,   -248,    461,    490,   -326,    264,    105,     13,
+      -160,    608,   -443,  -1331,    835,  -1342,   3507,    763,
+       966,    101,   1047,   -469,  -1455,  -1080,     28,     99,
+       -44,    270,   -752,    130,      2,     57,    358,   -409,
+         2,   -658,   -812,   -899,    155,    141,   2101,   3616,
+        40,  -1957,  -1028,  -4137,    212,   1580,    578,   1019,
+      -512,    167,    366,   -580,    448,    216,     79,   -149,
+};
+
+static const int16_t cb2224sm0[] = {
+     -4334,   1434,   -228,   1477,  -1329,    230,    686,   -558,
+       486,   -188,    424,   -454,   -568,   -141,   -326,   -132,
+       -39,   2488,      9,    631,    513,    460,   -417,   2656,
+       633,  -1404,    -81,   -283,   -287,    480,   2558,    -19,
+      -158,  -2699,    405,    276,   -639,   -151,    529,    241,
+      -941,   -796,   -213,   1125,   -391,   2515,     78,   -177,
+      2677,    217,    955,   -687,    867,   -485,   -121,   1023,
+     -1572,   -591,    139,    798,   1262,   -467,    722,   2643,
+      -237,  -1048,    386,   -432,    180,   -788,   -178,    234,
+       403,    267,    312,   2661,    585,  -2775,   -686,    -88,
+       -16,  -1243,   -445,   -259,    303,    298,    285,    277,
+      2355,    163,  -2399,   -416,    115,   2277,   -707,    194,
+       283,   1183,     23,    119,     97,   8192,    -40,     67,
+      -101,    151,    169,     21,   -147,   -160,     55,   -207,
+       550,    -36,   -500,    -32,    225,    206,     72,    179,
+       464,   -406,     52,    696,    -18,  -4827,   1547,   -516,
+     -2275,    855,    430,   -523,     83,  -1633,  -1898,    285,
+       202,   -645,   -167,    102,   -124,    382,     24,    236,
+       830,    324,    -84,    491,    -95,   -154,    767,     25,
+      4741,   -574,  -2576,   -297,   -250,   -346,  -2867,    -64,
+     -1119,   1007,   -883,    457,   -328,   -854,   -981,    -55,
+      6922,    569,   -307,    261,   -100,   -832,    129,    416,
+      -154,    681,   -136,   1152,   -144,    -26,  -2266,   -320,
+      -141,   -897,    544,   -206,    845,   -590,     88,    211,
+     -1761,   -574,   -653,  -2788,    252,   -266,  -4252,    295,
+        97,  -2112,    209,   -144,    655,    -89,   -369,    591,
+       205,   1137,     30,  -2907,     88,     92,   -240,  -3106,
+       -16,   -398,   -576,   -720,    421,    427,   -423,   -195,
+       -18,   2503,   -133,   -918,    104,   -512,   -489,   2623,
+      -314,    215,   -103,  -1014,    761,    382,  -1456,   1719,
+      -980,    248,     55,    644,  -1945,     42,   -162,    -35,
+      -852,   1993,   -189,    664,   -149,   3132,    -50,   3438,
+       550,   -234,   -566,    434,     64,    379,   -169,   -291,
+      -718,   -608,     31,   -207,    651,  -2567,   -790,    906,
+       518,   1740,    373,   1158,    114,  -2044,    285,  -1136,
+      -373,    932,  -2185,   -488,    148,      3,    724,    623,
+      -568,   -359,  -2748,    751,  -1098,   -858,  -1140,   -253,
+     -2377,   -402,   -312,   -398,    -47,  -2618,    816,   -568,
+      1274,   -158,    118,    107,    181,    394,   2758,     80,
+     -3057,     20,   -279,    110,    482,   1010,   -162,  -1081,
+       -56,    685,   2207,    -10,     82,    440,    593,     43,
+      1010,   -853,   -624,    288,  -3045,   -426,      9,    132,
+       104,    157,    466,   -118,    116,    226,   -214,   -219,
+       299,   6093,    122,      7,    174,    444,    200,    -42,
+        -4,   -313,     99,    218,    292,   -159,   -409,    523,
+     -1357,  -4098,    -96,    968,      8,   -172,   -444,  -1040,
+       755,   -476,    967,    175,   -100,   1689,   -813,   3175,
+       369,   1828,    248,   -161,   6693,    631,    536,   -125,
+       274,   -467,    259,   -427,    130,   -523,    361,    584,
+        27,     60,    -57,    -30,  -8192,    148,    -64,    217,
+      -308,    163,   -116,     89,    108,    191,   -129,   -149,
+       128,     60,    575,    253,   -385,  -2937,    888,  -1402,
+      -543,   -607,   2639,    156,    251,   6966,   -147,   -382,
+      -388,     39,    476,    260,  -1048,    575,    401,   -245,
+      -441,    121,    389,   -666,     95,   2919,  -2212,   -765,
+       169,   -161,    184,   -320,   -315,   -497,    136,   -470,
+       479,   -541,    712,   2966,    519,   2595,    -77,   1089,
+        18,   -697,   -616,    241,    -54,    388,    461,    368,
+       144,   -149,    181,   7699,     11,      3,   -368,     65,
+       304,    358,    -29,    255,   -162,   -169,   -470,    -16,
+       198,     92,   2137,    233,    273,    255,   4078,   -279,
+      -194,   -274,    101,     45,   -225,   -716,  -2522,   -188,
+        10,   -590,   -745,    894,   1976,    -48,   2302,     -4,
+     -4691,    -67,  -1325,   -506,    605,   -297,    317,   -271,
+      -176,   1706,    541,      1,     31,   -580,    103,    148,
+      -122,   -141,   -849,     76,  -3094,    -67,   2775,    -38,
+      -598,   -314,    793,     40,    324,   1474,   1986,   1505,
+       832,   -504,    739,  -1233,   1201,    695,  -1363,    670,
+       805,    696,   -137,  -4977,   -306,    137,   -885,    455,
+      1021,    600,  -1711,    536,    235,   -149,     31,     -5,
+     -3747,   -405,    394,    140,    102,  -1576,    190,    408,
+       663,  -2075,   -747,    466,    631,    807,   1867,   -655,
+       102,    341,    435,    551,    500,    426,   -650,    -88,
+       -26,   2672,  -1791,     34,    -86,   2963,  -3330,   -793,
+      -307,    277,   -584,   -240,   -141,    258,    708,   -242,
+      -499,    808,   -104,  -2061,   -518,    684,    889,    406,
+       259,    211,    462,    428,  -2597,  -1147,   1729,    683,
+     -2173,   -167,    392,    440,    599,   -815,   -624,   -368,
+     -2962,   -172,    845,    423,    362,    711,   2131,  -3899,
+        84,    147,    826,   -399,   -637,   1132,    108,   -480,
+       230,    265,   -423,     48,     11,    239,   -599,   -281,
+        10,    541,   -397,    142,  -4322,   1172,   -257,   -101,
+       292,   -321,   -401,     60,   -309,    468,    267,    611,
+       438,   -638,   2194,    346,   1421,  -1192,  -3109,   -170,
+     -3336,    -49,    -69,    -75,    184,   3094,    591,     82,
+      -373,    140,    -22,    848,    124,    589,    157,     -4,
+       260,   -177,    147,     73,   -284,   6253,    111,    302,
+       -74,    356,    381,   -547,    -16,   -275,   -500,     93,
+       344,   -346,  -2837,    364,    -43,   -592,   1741,   -702,
+     -2247,    848,   -203,    168,    758,   -849,  -2454,    562,
+      1104,   -169,    463,   -398,  -2759,   -299,   -903,    647,
+       -62,   -124,    301,    337,   -201,    463,    -86,   -139,
+     -2189,  -2424,   -942,   -376,  -2043,    -80,  -1791,  -1580,
+       513,     29,  -1115,   -582,   1214,   -642,    355,    240,
+       285,   1759,   1209,    862,   1707,   3353,   -223,    245,
+      -515,   -928,    794,   -190,   -282,   1097,    -32,   1675,
+       857,   -730,    -15,    102,    356,   -309,   3867,     24,
+        93,    899,   -608,   -497,   -215,  -2244,    735,   -194,
+       102,    -51,  -1939,    846,     74,   -116,      7,   1981,
+       512,    233,    574,  -2508,     83,   1966,   -251,    -96,
+       532,     97,    897,  -1120,    390,  -3192,   -652,   2045,
+       193,   -880,   -398,   -148,    548,   -281,    -19,   -987,
+       467,   -326,   2777,    195,   1560,   1034,   -828,    102,
+     -1531,   1292,   -126,    539,   -247,     36,     55,  -2487,
+      -297,   -362,    482,  -2241,  -1021,  -1535,   -244,     38,
+     -3416,    141,   3408,     35,    -67,     95,    333,   -427,
+      -235,   -128,    304,   -548,    337,   -349,   -330,     23,
+      -450,   1657,    327,  -3087,    695,   -273,  -1090,   1262,
+      -111,   -868,   1516,    269,    119,    192,     14,    200,
+       141,   -395,   7145,     48,    334,    143,   -139,    154,
+      -102,   -312,     -2,    283,    238,    -30,    626,   1328,
+       242,   -416,    442,  -3050,   1388,   -100,   1215,    817,
+};
+
+static const int16_t cb2224sm1[] = {
+      8192,    -13,    346,    -52,      5,    131,   -294,   -167,
+       -65,   -347,   -438,   -559,     57,    -86,   -223,   -224,
+      -251,    629,    -58,   5249,    127,   -464,    644,    210,
+      -154,   -480,    165,    211,     13,    318,    152,   -173,
+      5451,    235,    170,   -100,     -6,   -460,   -249,    390,
+        54,    993,  -1637,   -288,   -978,   -197,    234,  -2877,
+      -570,   -151,    -82,    772,    199,   -385,  -1899,    345,
+       -25,    527,   -477,  -2918,    385,   2784,     78,   -524,
+      -759,    795,    433,    511,    856,   -275,    511,    136,
+      -444,    151,    233,    208,   -589,   -375,    282,   2886,
+        30,  -2749,   -930,   1079,     86,  -2285,    980,   -229,
+     -1369,     93,    -80,   2314,   -170,   1224,    397,    405,
+       463,   1014,   -377,    -90,   -269,    -82,   -376,   -773,
+       684,    -94,  -2893,   -323,   -644,   -849,  -1892,  -2244,
+       417,   2165,   -164,    221,    454,  -2337,    142,     99,
+       418,    486,    -49,     97,    138,   2221,  -2301,   -156,
+      -578,   3963,    196,    140,   -374,    180,    451,    354,
+      -952,    946,   -479,   -874,   -159,    145,    290,    240,
+      -240,   -233,   -418,    226,   2878,   -571,  -2491,    741,
+     -1438,    557,    197,   -370,  -4720,    379,     32,    821,
+        39,   -545,   -141,  -1507,    192,  -1150,    905,  -1095,
+     -5028,   -169,    533,    -23,    371,    162,  -1198,    465,
+      -369,    -14,   -861,   -656,   -701,   -296,     31,    450,
+      -387,   3060,   -696,    597,     14,  -1019,  -2741,   -208,
+     -1186,   -338,    712,    -64,   -344,     41,    327,      9,
+       576,   -349,  -2808,   2428,    433,   -566,    908,   -108,
+      -145,  -1011,    201,  -3042,   -327,    210,   -368,    230,
+      -310,   -400,     12,  -1034,   1734,    992,   1842,   1022,
+      2162,    588,    366,    154,  -3078,   -587,   1096,    215,
+     -1072,   -784,    472,  -1089,     94,    487,     18,     72,
+        34,    -15,   -374,   -607,    316,    830,   -146,   4377,
+      -301,    390,    838,    121,   -110,   -143,    -93,   2988,
+      2914,   -352,   -353,   -744,   -115,     99,    495,   -343,
+       309,   1261,   -519,    101,  -2662,    -44,  -3139,   -491,
+      1142,   -323,    -50,    776,     86,    187,    480,    271,
+      -167,      1,   -267,    -99,    991,   2492,   -152,   2423,
+      -225,     34,    576,  -1486,   -236,   -375,    160,   -176,
+      -145,   2525,   -131,    194,    317,   1215,   1553,    295,
+     -1408,    130,   2279,  -1185,   2671,   -137,   -324,    -23,
+        26,   -779,   -431,     -4,    488,   -186,    174,   -119,
+      3062,   -149,   -168,    191,    169,   1124,    301,   1471,
+      -409,   -999,   -166,   2174,  -1405,    992,   -179,  -2606,
+       -71,  -3151,     92,   -976,   3091,   -322,    310,   -374,
+      -779,    599,    -55,    425,   -697,     63,     27,    -38,
+        86,    170,    -11,   -616,    -97,    525,     78,     14,
+       684,  -5556,   -308,   -444,    266,   -396,  -1665,     86,
+      -722,  -1087,   -921,   -525,      3,   -439,  -1600,    -37,
+      2038,  -2672,   -187,    361,  -8192,    425,    365,     54,
+       343,   -703,    253,    284,    -57,   -327,   -154,    392,
+        99,   -181,    213,    395,  -2412,   -303,    182,     82,
+      2311,     45,   1801,   -209,   -988,     42,  -1430,     38,
+      -721,    118,   -163,   1279,   2184,    -18,   2851,    274,
+      -363,    297,    150,   -220,   3653,   3135,   -381,    335,
+       254,    378,    -52,     52,    328,   -383,    -61,   -802,
+      -409,    -49,     49,  -8192,    362,    -48,   -430,    -54,
+       255,    243,   -525,     14,    152,     10,   -392,   -301,
+      -594,   -539,   1200,    626,  -2979,    233,  -1504,    664,
+      -728,  -1293,   -491,    394,   1317,    298,    169,    214,
+      -429,  -1083,     42,    389,   4751,    510,    299,   -542,
+       456,   -852,     30,    208,    -63,   -131,     72,   -425,
+        73,    213,   -287,   -277,     43,    128,   5528,    165,
+      -316,   -135,   -576,   -583,    217,  -1298,     47,    134,
+       103,  -1894,    148,   3406,    880,    964,   -697,    -94,
+     -1626,    223,   1256,   -514,   2079,   -529,   1917,  -1452,
+      -616,   -605,    385,   -963,    395,    105,   -154,  -1627,
+      -214,     40,    969,   -708,  -1492,   -824,   2457,    275,
+       404,    876,   -781,  -1029,     34,     72,    229,   -137,
+       264,   -387,    305,    -57,   2908,   -143,   -249,  -2473,
+       202,  -1467,   -364,   2094,   -521,    -70,    260,    132,
+       465,     71,    982,    -36,   1792,    306,   2907,    -55,
+       254,    421,    231,    140,   1727,    474,    761,   3153,
+       -18,   -356,    414,   2218,    564,   -247,   -510,     67,
+      2390,   2531,    240,    117,   -487,   -310,    261,    222,
+      -286,   -861,  -2180,    480,    -75,   4769,   -407,    248,
+       227,   -224,    302,    901,  -1200,   -728,   1025,    734,
+      -336,    115,  -1726,   -179,    131,     43,   -357,    364,
+      -681,    283,   -189,    715,  -2793,   -692,   1367,    916,
+        28,   -500,   3094,   -543,   -627,   -709,   -506,  -1094,
+        34,  -2464,    434,    257,    357,     10,   -390,   3206,
+      3483,    137,    147,    180,    231,   -260,   -707,   -818,
+       476,   -528,    656,    824,     -8,   3073,    362,  -3034,
+      -199,     47,    694,   -252,    819,   -147,   -479,    -32,
+       530,   -141,    -91,    251,   -154,    376,   -603,   2305,
+     -2853,   -622,    316,   -680,    402,   -819,    323,    471,
+       -47,   1772,   1507,  -1052,   -685,     18,  -2509,   -418,
+       377,    -31,   -412,    105,   -906,   -267,  -2806,   -189,
+       -97,    198,   -802,    -82,   -658,  -2980,    795,   -447,
+       646,   1037,    486,   -689,  -2654,     55,  -3534,    540,
+       -68,    502,    -90,    277,    -87,   -497,     24,   -246,
+       400,    392,    348,     76,   -345,   -231,    -71,    155,
+        -7,   -226,   6553,    371,    261,   -290,     88,    -44,
+       311,    470,     -5,    182,   -105,     56,   -324,    267,
+       241,    327,    966,    218,  -4695,   -968,     27,   -352,
+      -315,    202,   -204,    435,    360,   -539,   -375,   -527,
+     -1157,   1010,   -241,   4171,   -292,     66,   2343,    310,
+      -682,    595,   3040,    539,   -118,   -573,   -128,    952,
+      -172,   -547,   -285,     -1,    345,  -5701,    345,   -153,
+        77,    349,   -225,   -364,   -655,   -270,   -716,   -825,
+        27,     55,   2179,   -154,   -275,    359,   -501,   -992,
+      -665,   1538,   -218,  -1159,   2176,   -845,  -3018,    105,
+      -459,  -3146,     67,   -197,   -293,    539,    115,    -74,
+       119,   -158,    -89,   1449,  -3006,    104,    651,    886,
+      -310,   -242,   1219,   1805,    176,   2235,    579,    294,
+       634,   1345,     -1,   -454,    755,  -1030,   1760,  -2404,
+      -406,    894,    614,    -74,    113,  -1325,   1843,   -392,
+     -3239,   2440,    -54,    222,   1349,   -695,  -1009,    434,
+      -468,   -509,   -280,    462,    228,    573,    213,     55,
+       325,    557,    100,   -721,   -674,    600,    795,   1567,
+       407,   3273,    -58,  -1330,    349,   -181,    417,   -503,
+       911,    350,   -681,  -4502,   -127,    -26,    330,    618,
+       241,   -147,    284,   -226,   -127,  -2692,    484,   -146,
+       -18,   -416,    755,     85,  -3119,   -404,      0,   -478,
+};
+
+static const int16_t cb4432l0[] = {
+     -3764,   -227,    184,   -258,  -1713,    122,    410,    -32,
+      -244,  -1337,   -328,    -20,   -236,   -359,    -13,    -52,
+       -75,   -260,    426,    -96,    -37,    -38,    117,   -938,
+       487,     60,    286,    571,    368,   -551,    198,   -102,
+        15,    -11,   4535,   -127,   -241,    114,    -77,   -316,
+       302,    195,   -149,    -73,    357,   -128,    -23,     34,
+       319,    -97,    189,   5918,    -20,   -134,    -47,   -249,
+         7,      3,    116,      7,     48,     47,     92,     19,
+        14,     31,   -388,   -329,  -1878,   -944,    958,    632,
+      1973,    182,   -130,   -193,   2309,   -868,     63,    260,
+       -12,    -89,    -88,   -208,    127,   -168,    237,     74,
+      1153,    925,   2292,   2992,    -35,    204,    766,   -930,
+       -87,    341,   -101,    501,     35,   -182,    112,     91,
+       -28,     79,    193,    -73,    -71,     52,     82,   -427,
+      -147,    -69,   4722,    468,   -187,     98,   -295,    292,
+      -991,     43,     98,    225,   -555,   -595,    -66,   -181,
+        91,   -152,     -3,     89,   -219,    356,   -375,   -114,
+     -1546,   -620,    648,   1946,     39,   -608,   -942,    103,
+       179,    170,  -2350,    157,   1132,   -944,   -283,     64,
+      -393,     15,    -90,    761,   -185,    644,   -360,      5,
+     -5212,    106,   -136,    -40,   -159,    -40,   -120,    -43,
+        -8,   -195,    208,   -179,   -295,    -63,     19,     32,
+      -104,    -23,    132,    660,   -460,    237,    523,   -676,
+      -378,    -81,   -184,   2718,     64,    531,   2119,  -1564,
+       614,    933,      6,     65,    -50,     55,    243,   -539,
+      1168,    953,   -283,     45,    476,   -346,   2285,   1892,
+       615,   -521,     23,  -2079,     57,    -11,    208,   1029,
+       371,     28,    170,    -63,   -167,    184,   -217,     76,
+      -320,  -2747,    542,  -2098,   -407,    -10,   -876,  -1477,
+      -306,    565,     57,    -49,   -111,    185,   -250,    120,
+      -186,    214,   -520,    463,    792,  -2420,   2760,   -383,
+      -783,  -1097,   -441,   -535,   1070,     78,     96,    122,
+      -193,    516,    114,    100,   -413,    100,    -23,   -153,
+      1267,  -4210,   -742,    228,    659,    399,   -169,    412,
+       -81,   1056,      4,   -254,    173,    109,   -218,    196,
+        64,     26,   -113,    -60,     -8,     15,   5497,    -76,
+       169,   -294,   -394,    596,    379,     12,    -64,   -203,
+      -138,     41,   -249,    -53,    -44,    -19,     55,    -34,
+        99,     36,    -70,      8,     46,   2787,    842,   1917,
+      -693,   -424,    151,    464,  -1162,   1027,    148,  -1027,
+      -173,    328,     23,    792,   -184,    395,   -684,    229,
+      -139,     -7,   2788,    404,     43,  -1508,   -590,      6,
+      -184,    904,    475,    -37,    276,   -361,   1924,   -188,
+      -113,  -1334,   -176,     11,    -34,    -70,    -68,     95,
+      -433,    225,    437,   -451,    471,   -272,   -385,   2793,
+     -2685,    544,    881,    409,   -789,    700,     -5,   -144,
+        66,    -17,    504,   -397,    264,     74,    -81,  -1803,
+       444,   -573,    633,   -391,  -3339,    192,    484,   1126,
+      -306,    153,    303,     61,   -253,   -255,    -57,   -277,
+       -88,   -100,     32,     79,  -1320,   -857,   3080,   1178,
+       323,    353,   -149,   1316,   -399,    236,   -129,    231,
+       323,    696,     59,   1217,   -567,   -268,    642,    384,
+      -327,    -47,    466,   1530,   1092,  -1176,    612,    257,
+      -143,   -270,    487,    -62,    332,   1089,    961,   -706,
+       938,     78,     97,  -2805,  -1088,   -871,   -273,     87,
+      -345,    148,    113,    167,     97,     31,     68,    -47,
+       -53,     53,     29,  -5723,    -53,    -12,    241,     92,
+       131,    139,     48,    102,    -26,    -47,    664,   -580,
+        -7,   1287,   2531,   1061,   -710,     24,   1389,  -1742,
+       254,  -1147,    539,   -150,    -24,    495,   -204,   -171,
+       955,    202,   -111,    147,  -1458,  -3973,    421,   -416,
+      -544,    392,   1419,   -178,   -168,    -53,     50,   -537,
+        -7,   -346,   -289,    -52,    -38,   -259,   -115,   -136,
+      -138,    -89,   -205,   -661,  -4429,   -110,    380,   -721,
+      -180,    127,  -1371,    -78,    276,    319,    229,   -934,
+       267,   -353,     44,     65,    449,    -32,    159,    -11,
+       -22,   -571,    100,   -676,   2892,  -2740,    907,    511,
+       248,    441,    -62,   -517,   -347,   -235,    319,     -8,
+      -140,    309,    258,   -106,    215,      1,  -3252,    426,
+       455,  -2213,   1031,    430,    746,    367,    602,    187,
+      -147,   -200,     97,    555,   -107,   -249,    -71,    101,
+        59,    -94,    -64,    -33,    221,    184,   -791,    671,
+      -191,    284,  -1311,    402,    -29,    250,   -190,   -503,
+        38,    106,    586,   4767,    526,    147,   -182,    249,
+       146,     17,    293,  -1095,   1079,   -161,    141,     -2,
+       681,   -275,   -171,  -4504,     61,   -105,   -306,    -66,
+       229,     20,   -102,    -93,    334,   -189,      5,     -6,
+       417,   2551,    -63,   -852,   1608,   1820,    670,   1592,
+       102,    203,    147,   -767,   -147,    310,   -718,    175,
+       551,    -98,   -202,    309,     70,     81,    -55,   1518,
+       222,    338,   -356,    349,     97,     86,    495,   -233,
+      -121,   2936,    200,    935,   -381,   2474,     53,    494,
+       248,   -139,    -45,    100,  -1287,   -181,   -370,    311,
+       287,   3016,    -96,   -128,   2146,    567,   -383,   -551,
+       -96,    144,    495,    428,    -32,    137,     27,   -272,
+      -149,      9,    -61,    177,  -5236,     91,   -837,    611,
+      -279,    -74,    652,     14,   -178,    -82,    -89,    347,
+      -245,    647,    -62,     49,   -215,     29,    -55,    -27,
+       178,     79,    -19,    -59,    177,   -152,      0,    189,
+       -10,    128,   -115,     33,     61,   -106,     56,    -13,
+       135,    116,  -5772,    157,     43,     26,    -11,    102,
+        -4,    -52,    208,   -186,    198,     99,     81,    -29,
+      -103,    193,    -35,    -84,     -4,   -111,  -5251,     84,
+        71,    -85,    -77,     55,    234,     38,      0,    -35,
+        60,   5875,     98,     36,   -219,    -17,   -419,   -136,
+        47,     34,     55,    -21,    -17,     -1,     72,     94,
+        52,     -3,   -703,  -1437,   -518,    557,    121,    356,
+      -345,   -717,   -438,   -279,     13,     70,    -95,     -2,
+     -4170,     40,    136,     17,   -153,      8,   -149,    -27,
+      -559,    268,   -237,    -82,   -220,   -921,   -588,   -150,
+      3481,  -1906,    647,    675,   -455,    598,   -386,    -52,
+        -7,    222,   -201,     90,     54,     75,   -283,    118,
+      -375,   5768,     20,   -126,   -141,    -99,     64,    116,
+        16,    -58,      0,    -31,    -15,    250,   -104,    -30,
+      -144,    115,     12,    117,   -482,  -1709,   -436,    122,
+      -246,     -7,    271,   1961,    154,    149,    -86,    147,
+       258,    531,   1760,    914,  -1196,  -1800,    812,   -621,
+       125,   -161,   1361,     50,   -651,  -1307,    360,   -785,
+       205,   -156,    294,     21,  -3484,    -18,    -79,   -266,
+       770,    307,     29,   -765,   -250,    183,     55,    131,
+      1452,    260,    224,    221,   -347,    360,   -352,  -2188,
+      -664,   -503,    313,    406,   -251,   3268,    210,    -46,
+       129,   -276,    343,   -143,    104,    -55,    461,     17,
+      -576,   -287,   -289,     33,  -2500,    -85,   -428,  -1137,
+       918,   -245,   -490,   -260,   -270,   -133,   -591,    199,
+      -294,   2784,    102,     19,   -109,   -745,     91,   -524,
+       -44,     28,    252,   -511,    -80,   -146,    271,    519,
+      -216,  -2280,   -411,   3699,   -368,   -538,    427,   -158,
+       114,    -50,   -589,   -340,   -180,    703,   -186,    487,
+      -649,    668,   -916,   -436,  -3684,  -1016,    877,    -65,
+      -153,    -62,   -148,    -17,   -106,    142,    -73,     -1,
+       -68,    567,   -658,    815,   2270,   -563,   -519,   -226,
+      -223,   -282,    584,    240,  -1522,  -1935,   1169,    880,
+       127,  -1276,   -127,    399,     63,     25,  -1297,   2131,
+       592,   1652,   2609,     69,   -581,   -179,    947,    597,
+       150,     35,      0,   -255,   -232,   -728,    239,     91,
+       130,   -234,    231,     56,  -2181,   1774,  -2196,   1633,
+     -1065,   -662,    777,   -175,   -128,    267,     -7,     51,
+        27,   -133,     95,   -500,    188,   -167,     94,   -176,
+       -29,    -65,   -161,   -141,   -694,   -968,    594,   -269,
+      -422,   -472,   -731,   1210,   -816,   2142,  -1321,  -1746,
+      -149,   -983,   1310,   -839,    762,    284,     99,    -31,
+     -1169,    -84,  -1119,    -55,   -720,   -944,  -1115,   -271,
+     -1032,   1064,    187,  -1013,   2987,     26,   -209,    516,
+        -8,    107,    -24,    188,    278,    -53,    624,    460,
+      -275,  -1881,  -2001,    851,  -1740,   -407,   1643,   -352,
+       -17,   -528,   -538,   -175,    179,    416,   -297,     54,
+       132,   -491,    -76,     34,   -440,    175,   2065,  -2006,
+      -164,     38,   -403,    902,   -129,    215,   1545,   -414,
+     -1183,   -532,    578,    248,   -308,    189,   -563,   -345,
+      -949,   -279,   1693,   -959,    101,    783,      9,   1641,
+      1494,    167,   -294,   -538,    951,    115,    590,    105,
+      -847,  -1003,    464,   -368,  -1268,    641,    254,    243,
+       488,   2636,  -1209,   -272,    437,    445,    781,   -463,
+      -415,    538,   -811,    588,   1083,    206,   -547,    171,
+      -585,   -744,    343,   -604,    395,    -76,    910,   -523,
+      -108,   -449,    625,   -325,  -1079,    273,  -1473,  -1096,
+      -137,   -565,   2077,   -623,    214,   -342,   -273,    769,
+      1137,   -879,   -731,     56,  -1098,    211,    822,    579,
+      -839,    164,   -600,    -80,     61,    316,    644,   1445,
+       891,  -1796,  -1798,   -162,  -1631,   -492,   -626,    593,
+       544,     66,     63,   -857,  -1273,    406,   1665,    899,
+      -467,     87,   -117,   -469,    126,     30,   -931,   1446,
+      -190,    388,  -1608,   -316,  -2199,   -127,    484,    -51,
+        56,   -524,   1524,   -103,   1231,   -740,    717,   -861,
+       823,   -665,  -1790,    411,   -690,    303,  -1615,     63,
+      -232,     19,   1090,    -96,    137,     80,  -1027,    581,
+       -61,    672,    133,    444,   -767,    766,    -42,  -3174,
+      -270,    -23,   -126,  -1111,     67,  -1367,      4,    315,
+       -53,    -90,   -165,     48,  -1657,   -117,    392,    356,
+       792,   -610,   -618,   -219,    446,    102,    374,    207,
+      1026,   2480,   -461,   -782,   1161,  -1351,   1032,    486,
+      -308,    290,   -272,    899,   1912,     36,   -624,    286,
+      -428,   -623,   -665,     12,   -621,  -1985,    -34,    468,
+       318,   -467,    127,   -972,    -39,   -663,   2307,    -26,
+       406,   -468,   -657,  -1404,   -342,   2356,   -395,  -1422,
+     -1243,    465,     90,   -665,   -280,   -290,    -21,  -1752,
+       280,    271,    395,    240,   -402,     55,   1077,    148,
+      -309,   1818,    483,  -1293,     43,    261,    566,   -131,
+       947,   -815,   -872,  -1021,  -1001,   -395,    263,   -555,
+        78,  -2193,   -360,    -76,  -1029,   -493,   -464,   1339,
+       -53,    750,   -671,  -1349,    133,    -70,    114,    501,
+       766,   -816,    703,   -992,   -122,   -520,  -1323,  -2539,
+      -365,    -35,   -555,   -888,   1515,   -191,   1322,   1633,
+      -674,    451,  -1246,    270,   -868,    703,   -394,    106,
+      -779,    754,    650,   1066,   -417,  -1305,    149,   -165,
+};
+
+static const int16_t cb4432l1[] = {
+     -3867,   -448,   2202,    129,   -100,    393,     37,   -267,
+      -156,     23,   -274,    222,     33,   -191,    104,   -140,
+       -50,    -28,   -148,   -181,    -22,      6,    489,    993,
+     -2764,   1191,   -773,    781,   -460,    843,    -77,  -1417,
+       390,    124,   -203,    205,    662,    -16,    569,   -963,
+       609,   -155,     64,   -293,   2649,  -2533,     70,   -472,
+      -482,  -1732,    235,     -5,   -485,    116,   -177,   -104,
+       314,   -355,    118,     25,    921,    285,    130,    -94,
+        77,    121,   1068,   -435,   1407,    447,   -427,  -1096,
+      -757,    258,     19,   3236,    702,    362,   -928,   -348,
+      -150,   -784,   -687,   -388,   -176,    -38,     16,    -14,
+      1017,    879,    935,   1280,   1014,    -85,   -256,   -103,
+     -3384,   -928,   -200,   -406,   -175,    304,    -54,    195,
+       -78,    676,   -356,   -167,   -165,    -56,  -3133,    156,
+      -171,   -684,   -698,   -135,    230,    -30,     32,    542,
+      1959,   -124,    -76,    162,    182,   -174,   1011,    -97,
+       678,     10,    188,     30,   1086,   -262,   -157,    250,
+       241,    233,   -584,   3276,   2126,    -50,   -207,    637,
+      -440,    331,   -434,    251,   -267,    269,   -392,     68,
+      -244,      8,    928,    827,  -1096,   -309,   -356,   -375,
+     -3204,    422,    695,      2,    240,    595,    641,    582,
+       342,     42,      7,    539,    -64,   -116,     82,     16,
+        26,   -136,   -122,   -114,  -5814,     22,   -272,     10,
+       113,    186,   -422,    -95,    309,    308,   -118,   -208,
+        52,   -175,     12,   -106,     -6,     20,     58,   6053,
+      -101,    -20,     10,     70,    189,     57,    -11,    210,
+        83,    239,     -6,    -79,   -233,    -59,     31,    -30,
+       -62,     64,    -38,     25,    -78,   -202,   -215,   -115,
+      1477,    255,    101,  -2575,    186,   3140,    -46,    -45,
+        53,   -183,    -89,   -412,    183,   -222,     50,   -237,
+        96,     35,   1684,   -521,   -169,   -436,   -295,   1390,
+       261,     27,    163,    352,     68,  -3677,     12,    310,
+      -599,    331,    138,   -333,   -269,   -130,    -44,    -14,
+       265,   -626,    258,    -59,     31,    -17,    222,    -10,
+      -364,    280,   -183,   -235,   -217,     73,    -67,    114,
+       196,  -5132,    269,    159,     -6,    -36,   -248,    274,
+      -328,   2712,   -393,   2763,    507,   -110,   -166,    -84,
+       -72,  -1111,    -19,    370,     25,      5,    156,    -32,
+       237,    -57,   -106,    -22,    370,   -229,   1099,   4297,
+       152,     72,    -56,    347,     64,   -501,    -57,    178,
+       175,    -14,    -84,   -626,    555,    155,     20,    -75,
+        20,    -33,   -254,   -125,     -9,    150,     91,     -7,
+       -45,    239,   -109,     72,    -66,   -172,   -211,   6063,
+      -205,    171,    -75,     50,    -75,     22,    109,     21,
+       -58,     58,   -105,   -432,    310,   3782,    -18,  -1071,
+        19,     20,   1455,    337,   -257,   -288,    -52,    519,
+        43,     80,   -175,   -218,      9,    176,    -28,   -418,
+       200,   -514,    351,    119,  -5920,    -96,    -33,   -289,
+        74,     26,    120,    -37,    113,     47,   -145,    -17,
+       334,     46,     47,     19,    274,    172,    159,   -404,
+      3151,   -408,   -559,    987,   -178,    253,    -90,   -498,
+      1454,   1183,    392,    762,    220,  -1207,   -220,    -69,
+       -85,     22,   1644,   1858,    725,   1084,      0,   -257,
+       290,   1712,   -151,   -188,   -390,    638,   -327,  -2185,
+      -322,  -1116,   -150,    120,   -140,    198,    162,    -83,
+      1321,    232,    242,    -52,   -456,    778,   -288,     65,
+      2431,     37,     85,   -489,    862,   2776,    260,    -72,
+       792,    100,     17,   -210,    588,     49,    600,    246,
+      -258,    128,    -51,   -492,   -395,   -489,     50,  -5308,
+       -67,    314,    124,     46,   -188,    -64,   -101,     51,
+      -535,    108,     56,     -4,   -191,   -923,    485,    578,
+      1320,    228,   -535,    310,    227,    395,  -1441,   2660,
+       226,   -392,    221,   -686,   1749,   -175,   -904,   -571,
+      -129,    154,   2622,    609,   -247,   -240,   -893,     98,
+       291,  -2277,    411,    260,   -160,   2061,   -203,   -437,
+       359,     21,   -101,     19,     49,     15,    -98,     82,
+         3,   -555,    164,   -152,    -58,     38,    175,   -439,
+       -37,     68,    -21,   -181,  -5556,    -27,      8,     48,
+        21,   -151,    381,      3,   -152,    -74,    202,    -29,
+      1863,   1713,   -922,  -1976,    551,  -1522,    525,   -116,
+       146,  -1730,   -238,    -72,   -183,    126,    234,   -240,
+        82,    138,    -60,   -131,  -2226,    226,   -702,    183,
+       -81,    462,  -2851,  -1419,  -1005,    124,    -81,   -252,
+       -65,    147,    -58,   -179,    306,    154,    122,    -69,
+        69,     11,    115,    296,   3340,   -501,  -2580,   -804,
+         9,    591,    -86,     88,    127,    588,    183,     48,
+        79,    -38,   -199,     63,   -140,     29,     88,    -28,
+       259,     69,   1743,   -531,    110,    -18,    776,    -18,
+      -177,    112,     36,   -243,   -208,    528,    -47,   4709,
+       107,   -125,    140,     -1,     22,     15,    416,   -194,
+      -267,    -49,     43,     -3,   -308,    214,   -128,    140,
+      5372,   -123,     70,    275,    210,    182,   -147,   -131,
+       -84,     69,    116,     29,   -401,   -162,   -236,   -173,
+       378,     45,    -12,    -77,  -6209,   -103,    126,     54,
+       -19,    -20,     43,     64,     92,     -8,    -12,    118,
+      -123,     58,  -3628,   -414,  -2147,     76,     95,    -99,
+       357,    -10,    278,      4,   -608,    504,    105,    -72,
+      -109,    -92,    -55,    367,   -167,     40,    -34,     76,
+       220,   3434,   -366,    191,    248,     29,    187,   -177,
+       155,   -348,   -341,  -2466,    272,   -136,    510,    139,
+        81,    184,     33,   -299,     92,    -44,   -402,   -583,
+      -725,   -400,   -159,    751,   -225,    377,   -160,   1556,
+     -2652,    685,  -1077,   1276,    332,   -257,  -1449,   -282,
+      -231,   -145,     58,    173,    421,    271,    401,   -186,
+        79,   -258,    127,    252,    214,     96,    157,    195,
+       205,    118,  -4771,    -95,   -164,    217,    477,    -51,
+        -4,      8,   1450,    -51,    -52,    952,    675,    929,
+      -273,    475,      9,    282,   -249,    236,    746,  -1407,
+      -272,   1845,    692,   -105,   2690,    168,      1,     -1,
+       157,   -599,    305,    255,  -2252,     45,   -199,    119,
+     -3489,   -161,      6,   -263,   -259,    338,   -251,     61,
+       153,   -124,    432,     -7,    131,      5,    305,   -322,
+     -3283,    -32,   -336,   -273,   2243,    863,     -1,    681,
+      -365,   -246,   -152,    375,   -133,    -15,   -208,   -104,
+        89,    128,   -135,     44,   -255,    549,  -2751,    -48,
+       270,  -2584,   -549,   -631,    445,    182,   -198,    743,
+      -215,    -60,   -400,   1383,    167,    -65,    250,    146,
+       185,     22,   -484,   -161,     86,   1758,    964,    404,
+     -2574,   1026,      6,   -516,   -724,    315,  -1891,    311,
+         2,    339,    -39,    324,    299,   -497,    -12,    179,
+     -1242,    364,   -185,   -197,  -1474,    232,   -490,   4042,
+      -105,    887,     31,    539,    235,     75,   -112,   -200,
+       -31,     74,    -76,    -16,    -20,     38,   -159,   -143,
+       114,    -77,   -110,     28,    -18,    -84,    -27,    -53,
+       -82,   -224,     75,      0,    -46,    -64,     44,   -112,
+        84,    -85,  -6030,    -24,    661,   -474,   -178,      8,
+     -1023,   -396,    199,    -19,    -50,    -93,    385,    209,
+     -1227,   2492,   2163,    986,  -1359,    399,    848,    681,
+      -829,    211,    696,   -599,  -1398,   1951,   -113,    374,
+       -17,  -1113,  -1708,   1294,    666,   1774,    623,    259,
+       105,    961,    -87,     43,   -463,     65,    155,    -26,
+       -31,  -1477,   -508,   1091,  -1463,   -524,  -1853,   1354,
+       434,     86,    893,   -871,    151,  -1887,    205,    423,
+       857,    -55,    -11,    -39,    341,     61,   1158,   2650,
+       899,  -2491,   -593,   -843,  -1399,    -15,   -713,   -171,
+      -195,   -523,    -46,    243,    117,    241,     -8,    140,
+      -149,   -191,     70,    134,  -1158,   1933,   1135,  -2284,
+     -1049,   1717,    378,   -155,    -37,    171,   -692,   -280,
+       918,   -786,   -123,    558,    571,     39,   -315,     62,
+        27,     59,    708,   -134,   -200,   -168,   -134,    148,
+      -142,     25,    164,   -282,    284,    -95,    -35,    376,
+       165,    367,   -335,    271,    249,  -4520,    176,    -36,
+      -216,  -1303,    375,     92,    602,   -889,   -390,    284,
+        78,  -1318,   1259,   1865,   1498,   2063,   -234,   -840,
+      -391,     88,    168,   -235,    -74,     31,   -239,   1221,
+        71,  -1637,   1513,     68,   2201,   1513,  -1099,   -622,
+       426,    343,   -330,   -648,    381,   -156,     27,    -31,
+       -92,    133,    210,    103,   -155,   2061,   -366,  -1173,
+       -31,   -274,   -713,   -471,    509,   1044,    208,    403,
+       486,    -66,   -521,  -1883,   -180,   -537,   1283,    -98,
+     -1464,   -456,    508,   -619,   -546,    685,    944,    -85,
+       311,   1172,   -194,   1406,    -99,   -827,   1506,    396,
+       196,  -1534,  -1181,   1588,   1250,     47,   1034,   -171,
+     -1247,    -98,   -120,   1181,  -2195,   -384,    945,    627,
+        26,   -248,   1372,   -671,    214,   -649,    -17,    -44,
+      -500,   -559,    577,   -601,     32,    421,    531,    344,
+     -1233,    145,    348,    614,   -560,   -244,   -357,   -202,
+       814,   -494,  -2320,    308,  -2277,   -481,   -518,   -431,
+      -851,     43,   -204,    -26,   -742,   1083,   -130,   2002,
+      1642,  -1156,   1746,   -529,    937,   -544,    416,   -741,
+       763,   -232,    509,    243,   -458,     78,   -130,    143,
+      -123,     71,   -666,   -105,     31,  -1061,    441,    -48,
+       411,  -1547,    155,   -730,    439,   1624,    873,   -611,
+      -470,   2348,   -157,   1184,    678,   -174,    542,    -95,
+       -12,   -405,    237,    322,  -1194,   1903,   1496,    357,
+       -34,   -661,  -1024,   2236,    860,   -256,    617,    756,
+      -485,   -273,   -589,    536,    214,   -286,    782,    418,
+       346,   -462,    443,   1056,   -914,   -304,   -564,   -332,
+      1823,   2079,     93,   -975,   -891,  -1089,   -720,  -1127,
+       702,    300,    787,    374,    -78,   1070,    691,   1339,
+      -797,     57,    482,    432,    748,   1538,    673,   1885,
+      -504,   1913,   -190,   -135,    881,   -139,     84,    379,
+      -176,   -129,   -331,    -34,   -690,    282,   -563,     51,
+        71,   -714,   -103,   1074,   -651,   -582,   1388,   -320,
+     -1115,   1547,  -1088,    -65,  -2634,   -201,   -653,    116,
+      -238,   -218,    476,   1417,   1671,   1135,  -1025,    614,
+      -662,    127,    863,   -117,    726,   -971,   1382,   -286,
+       465,   1195,   -715,    862,  -1256,    105,     37,  -1190,
+      -442,  -1777,     50,    162,   1577,    580,    762,    253,
+        92,   -308,  -1238,   -161,    295,   -150,   1733,   1831,
+      -527,   -527,    -28,     70,   -359,  -1590,    860,   -221,
+        47,  -1201,   -254,     39,    780,   -326,   1097,  -1019,
+       834,    362,    357,     41,    693,  -1099,  -2687,    614,
+       270,   -128,   -322,  -1149,    631,    -46,   -343,   1495,
+      -896,   -864,   1545,    200,   -922,  -1133,   -637,  -1231,
+       484,   -796,   -743,   -371,    999,   1300,    173,    -19,
+};
+
+static const int16_t cb4432s0[] = {
+     -2558,   2751,   -440,   1200,   1067,   -725,   -492,    588,
+       234,   -209,   -108,   -230,    223,   -231,   -235,   -132,
+       -51,     88,   -290,   -214,    -99,    -60,    175,   2546,
+      -991,    907,    446,    635,    284,    707,    238,    220,
+      -308,    259,      8,   -435,  -2207,  -1487,  -1579,     46,
+       285,   -249,    154,   -370,     37,     42,   1524,  -1853,
+      1393,   1204,    126,   1751,     82,    136,    363,  -2411,
+      -782,   -128,   -818,   -232,    765,   -173,   -127,    732,
+       260,   -101,    868,   -249,    290,     32,    645,     55,
+     -1742,  -1077,    392,   -568,    629,   -920,   -243,    791,
+      -604,   -363,    117,  -1360,    -15,   -245,  -3655,     54,
+      -297,     10,    124,     11,  -1114,   -567,   3882,  -2042,
+     -1120,    -42,   -114,   -914,    419,    307,     44,    277,
+      -101,    429,    170,    187,   -528,   -705,    348,    -19,
+       180,    -76,     91,  -1861,   -181,   -171,    804,   -730,
+       222,   -184,    349,    191,   -125,     14,   4270,   -467,
+      -272,     29,   -216,    212,    426,   -222,     11,    -16,
+      -852,    101,    576,    178,    351,    647,     90,    179,
+      -681,   -187,     77,   4115,   -976,   -726,    711,    763,
+       572,  -1166,    -46,   -445,   -103,    135,    294,    300,
+        10,    737,    386,   -399,   -349,    -52,   5393,   -107,
+       -32,   -229,   -154,   -181,     82,    -68,    -13,    -77,
+        48,     75,    117,    -50,    254,    233,     98,     75,
+     -2218,  -2214,   1491,    832,    225,  -1057,    267,    539,
+      1963,   -245,   -353,    454,   -430,    -54,   -747,    -58,
+      -438,    -90,    -64,    277,    214,   -105,    -47,  -1301,
+      -404,  -1179,    682,  -4093,    764,   -270,   -342,   -367,
+     -1378,      6,    -83,    429,    398,     61,   -149,    180,
+        31,    169,   -218,    152,    -71,    -38,   2605,    679,
+      -175,   -533,   1787,    611,    484,   -322,    158,   -561,
+       125,    -35,    -42,   -190,    529,    449,    157,  -3105,
+       106,    168,     -8,    -66,    -80,   1463,   1136,   4793,
+       -98,   -432,    538,   -145,    241,   -158,    105,   -372,
+        39,   -160,     92,   -223,     81,    245,   -142,   -162,
+      -167,   -297,    -49,    -98,    582,  -5178,   1130,   -271,
+       567,   -251,     55,    487,   -303,     31,    -25,     87,
+       -70,    154,    -23,   -221,     70,    208,     48,   -137,
+        46,     59,     -9,  -1397,   -970,    224,    714,    161,
+        24,   -307,   1295,   1467,   -155,   -505,   -521,   -244,
+       503,    -25,   -989,   3664,   -148,     12,   -135,    218,
+      -159,   -156,   -769,   -421,    553,    715,    697,   -181,
+      1426,    425,    -39,   -103,  -4558,    171,    347,    161,
+       170,    128,   -210,    -35,     31,    125,   -264,   -135,
+      -100,   2685,   -230,   2062,   1618,    -99,   -874,    926,
+       757,    380,    404,    -73,     30,     29,    462,    725,
+      -389,   -246,     20,    150,   -234,    -58,   -183,     10,
+       156,    482,   -232,    124,    115,    180,   -615,   -395,
+       330,    -85,   -435,   3279,   1493,    686,   1157,    245,
+     -1067,  -1953,     23,    796,   -540,    175,     56,  -1931,
+        89,    705,   -342,    551,  -1999,   1951,  -2305,   -497,
+      -266,    275,  -1503,    351,   -355,   -353,    236,   -358,
+      -271,    -40,    136,    217,    -13,    -45,  -2091,   1141,
+       730,  -1888,   1131,    660,   1271,    439,   2597,     92,
+       319,    -91,     62,    316,    287,   -260,    121,    -33,
+      -117,    -22,    -79,   -170,   -164,   1486,    134,    -62,
+       -36,  -3367,   -235,   1221,   1239,     78,    -54,   -489,
+       268,   -560,   -774,    851,   -973,    -62,   -174,   -138,
+      -459,    390,    -22,    -42,     83,   1339,   1307,    462,
+     -3768,    511,    300,   -525,   -787,    -89,    675,  -2074,
+        37,    -48,    252,    598,   -332,     67,   -187,      2,
+      -106,    -35,   -148,   -186,   -542,    799,   2363,   -155,
+      -665,  -2867,   -209,   -200,    -80,   1682,   1082,      2,
+       516,   -481,    276,     -1,   -220,     54,    -12,    259,
+       161,   -148,    566,  -1489,   -731,   1262,    499,   -816,
+       115,   4057,    -71,    701,     39,   -132,   -223,    -16,
+       229,     -2,    -40,    -61,    234,    405,    108,    304,
+       -62,   -396,   1369,  -1438,  -2045,   1954,    759,    969,
+      -166,   -235,   -115,    -68,   1923,   1815,   -776,   -855,
+        34,    -63,     17,     87,    223,   -145,   -130,    -16,
+      -313,  -1704,   -458,   -332,    420,   1332,    676,    878,
+     -3847,   -360,    427,    537,    651,   -167,   -451,   -197,
+       277,    136,   -201,    517,     10,   -156,     35,   -927,
+      1250,   -173,   1004,   -169,    322,   -140,   -559,  -4656,
+      -343,   -264,    -61,    -12,    195,    -10,   -123,    -23,
+       -20,     -6,   -367,   -102,   -215,     41,    838,   1513,
+       552,  -1609,   -753,   -763,   -656,   -633,     14,     35,
+       141,    117,   -121,    857,  -1494,    578,   2546,   1034,
+      -676,    571,    817,   -218,   -111,   1424,    -51,    878,
+     -2860,   -257,    104,   -526,    782,    708,   2350,   -500,
+      -342,    219,   -406,    836,   -117,    288,   -415,    798,
+        14,   -311,   -455,      3,   -410,   -144,    -30,   -977,
+      -145,  -2466,   -957,   1370,  -3201,   -327,    -85,    149,
+      -580,    198,    350,    140,   -104,    327,   -128,   -178,
+        58,    294,     50,   1814,    581,   -909,    287,   -267,
+     -3992,     61,   -860,    258,   -271,   -223,    237,   -291,
+        -3,     66,    110,   -620,    319,    -62,    177,    364,
+       110,   -163,   -921,   -863,    251,   4922,    280,    121,
+       128,    209,   -126,    578,    -56,     41,    124,    350,
+       245,   -465,    -67,      5,    651,    147,    200,      0,
+        21,   -609,   -332,     -3,    247,   -412,    128,     42,
+     -1405,   -301,   -341,   -484,   -491,    -55,    361,   -100,
+       -30,   -405,    643,   4249,    -31,    -91,    -10,      6,
+       425,   -350,  -1501,    817,  -1348,   -201,   -345,  -3643,
+       235,    691,    332,    219,    199,   -398,    130,    -50,
+      -190,     89,    -23,    100,   1327,   -200,    146,    482,
+      -624,   -479,   -391,    188,    129,    614,   -335,   -564,
+      1021,   -107,   -199,    145,    201,    571,   1276,   4253,
+        58,    121,    295,     38,     26,     47,  -1333,   1138,
+      3125,    357,    -72,    347,    276,   -272,    120,    -77,
+       535,    247,    -71,  -2054,  -1860,    -73,    -62,    266,
+       -30,    183,     17,    -46,     -7,   -140,    997,    526,
+       -47,    -59,   1540,    373,    162,   -150,   -107,    -74,
+      -278,    -37,   4268,    -21,   -269,    359,    111,   -115,
+        -5,   -206,    -87,    -44,   -517,     54,  -2859,    189,
+      -297,   -863,   -918,   -929,   -543,     25,  -2866,    -79,
+     -1101,   -275,   -410,   -458,    -75,   -211,   -420,     96,
+       467,    -66,    -15,   -580,   -420,   -586,     -7,    109,
+       236,    227,   -488,    106,    258,     76,     78,     -8,
+      -199,  -4888,   -134,   -205,    -33,   -243,    -19,    -10,
+       157,    129,    120,   -928,    604,   -345,    -47,   -430,
+      -257,    273,     81,   1949,    490,    272,   -205,   2460,
+       -54,    103,  -2924,   -529,   -211,    -60,    279,    220,
+       -57,    342,    209,    984,  -1410,  -3363,  -1028,  -1301,
+     -1293,    227,   1142,  -1068,   -512,    758,    364,     46,
+      -358,     16,    257,   -158,   -253,   -182,     -2,    181,
+      1475,   1574,    215,   -968,    246,    369,   -273,   -717,
+       546,     74,  -3872,    293,     98,    130,   -244,     41,
+       143,    699,    -56,   -126,     67,     54,     -2,   -878,
+      2334,    883,    215,  -1979,    246,   -759,    499,    248,
+       751,   -202,    580,  -3018,    359,   -139,    210,    -47,
+      -168,     89,   -659,    259,    -54,    -40,   -490,   -169,
+      -769,    569,   -171,     64,   -845,    519,   1251,    -71,
+      -459,  -4436,    257,   -334,   -826,   -183,    115,   -408,
+       -77,    544,    173,   -258,     48,    331,   1735,   1035,
+      2793,   1154,  -1901,    275,   -109,  -1185,   -403,   1332,
+      -282,     36,   -367,     21,     27,    362,   -425,    217,
+       150,   -304,    192,     53,  -1100,     27,    628,    698,
+      -634,    -25,     84,      8,   -103,    533,   -301,    218,
+      4350,    119,   -109,    309,     24,   -352,   -147,   -274,
+       156,     85,      9,   1706,   -854,   2012,  -1573,    112,
+      -673,  -1538,    -91,    415,  -1525,    866,   1493,   -621,
+      -396,    277,   -604,   -363,    114,   -360,   -252,    -18,
+       -31,    -77,   -591,   2483,    535,  -1520,  -1057,  -2189,
+       -51,    798,    276,  -1426,     72,   -303,    402,    111,
+       327,    272,     -8,   -216,    189,   1282,    152,    -45,
+       -33,   1524,   2301,   -341,   1992,    939,   1678,   1011,
+       114,    167,    586,   -500,     40,   -473,   -274,    596,
+      1237,   -126,    205,    254,   -284,   -367,   -119,     64,
+      1915,    437,   -585,      1,    402,   -271,   -984,    530,
+       267,   3634,    495,   -219,   -728,    -67,  -1340,    983,
+       122,      6,    110,   -166,    111,    102,   -139,  -2499,
+       753,   1011,   1755,  -1252,    872,   -510,  -1844,   1388,
+      -782,    287,    461,     36,     77,    437,   -361,   -216,
+      -415,    158,    -77,   -123,     57,    -93,   3408,    504,
+      -942,    434,   -648,   -251,   -420,   -387,   1373,   -229,
+       236,   -191,      3,    204,    612,    393,   -285,    560,
+      -164,   -199,    303,    146,     93,   1248,   2425,   1001,
+      1261,   -239,   1085,  -1878,   -375,   -544,   -995,   -192,
+      -319,    542,    280,   -716,  -1323,    -67,    -34,    252,
+       -36,    206,   -126,    -28,     26,  -1135,   2799,    527,
+       -47,  -2008,    509,   -232,   -953,    332,   -386,   -108,
+       290,    507,    578,   -809,    375,    850,  -1413,    831,
+      -137,    259,     25,  -1075,    407,   1784,  -1539,   1658,
+      1450,   -969,    467,      4,    785,   -595,    912,     34,
+        91,    286,   1035,   -524,    276,   -322,     11,    651,
+       733,    243,     45,   -145,    357,    524,   -697,   -259,
+      -757,  -1057,    181,   1324,    148,   -502,    -64,   -379,
+      -746,   1385,    395,    184,   -749,   -197,  -3375,   -546,
+        -4,    532,   -270,    687,    501,    285,    401,    431,
+     -1888,   -639,    655,   -325,   1896,  -1883,     53,  -1018,
+     -1475,    802,   -486,    -68,    232,   1337,    428,    232,
+      1754,  -1687,   -518,   -372,    508,  -1269,    327,   -900,
+      -468,   1127,   1397,   1597,    837,    659,   -617,     99,
+       264,   -460,    296,     44,   -295,   -209,   -174,   1105,
+       896,   1065,   -174,      5,    845,   1311,   1370,  -2548,
+       351,   -660,    -24,  -1089,   -787,  -1312,    -22,   -585,
+      -197,    749,    293,   -112,   -169,    -23,      3,   1151,
+       529,   1173,    224,  -1517,    930,    -52,    268,  -1282,
+      -559,    466,   -528,   1506,   -231,   -337,    993,  -1314,
+      -250,  -3042,     57,     19,     15,   1812,    697,   -389,
+      -201,    647,   -723,  -1098,   -177,   -225,  -2694,   -495,
+      -431,   -238,    388,  -1731,    997,    227,   -765,   -222,
+        94,   -611,     35,    187,   -935,  -1470,   1013,   1051,
+      -378,    311,   -710,   -566,   -532,   -369,  -1599,    553,
+       167,    450,  -1068,   2834,   -125,    601,   -113,   -503,
+        40,     14,    -36,   -220,  -1543,    867,   -612,  -1834,
+       888,  -1791,   1296,   -229,   -593,   -760,   -197,    428,
+     -1290,    892,    -62,   1113,  -1228,   -965,    -90,   -300,
+       288,   -133,    779,  -1211,   -627,    268,    180,    913,
+      2230,   -413,   -146,   -217,    170,  -1157,  -1551,    877,
+        75,   1784,   -174,   -230,   -757,   1243,    625,    -49,
+       114,   -218,   -409,    195,  -1165,   1492,    213,   1100,
+      -101,   -957,   1016,    663,   -704,    817,     94,   -279,
+      -256,    469,    -75,   -123,  -2954,    948,   -407,    275,
+};
+
+static const int16_t cb4432s1[] = {
+      5416,   -223,   -123,    156,    -33,    185,   -144,   -108,
+      -199,    -68,    -36,     11,     37,    124,   -301,     58,
+       -21,    155,     99,    -10,    -78,    -26,    -70,  -3160,
+     -1037,     98,    155,   -373,    834,    652,   -277,   -429,
+      -529,   -103,   -358,    187,   1161,   -157,    147,   -400,
+       461,    156,    237,    481,    -67,     99,    939,   1179,
+      -659,   1337,    578,   -489,   -481,   -427,   -622,    131,
+      1826,   -734,   -995,     -5,   -461,    514,    -83,   -271,
+     -2928,    -86,   -382,   -205,   -133,   -386,   -195,    -67,
+       508,    586,    607,   -910,   -181,  -2046,   1212,   -179,
+        23,    408,  -1929,   2044,   2160,   -879,     74,    179,
+        72,   -164,     47,    162,   1497,    826,   2978,   -912,
+       454,   -618,  -1907,   -501,   -494,   -299,     96,   -138,
+      -114,    -51,   -171,    445,   1144,   -187,    217,    224,
+       402,     13,     42,    -58,  -1692,   4162,   1272,    970,
+      -278,    327,     88,    -31,   -182,    279,   -610,     78,
+      -432,   -147,   -142,   -725,    -17,    -95,    388,    133,
+       -61,     28,  -1365,   1441,    606,    411,    923,   -332,
+      1843,   1934,  -1451,   -514,   -283,    768,    940,   -428,
+        31,   1105,    248,    -78,  -1477,   -367,    404,     68,
+      -178,     17,    691,   -265,   -105,   1681,   -476,  -1307,
+     -3434,  -1700,   -524,   -871,    472,   -171,    237,    104,
+      -142,   -231,   -292,   -285,    266,   -259,   -166,    -97,
+      -432,   4003,   1220,   -356,   2110,   -220,   -465,    -48,
+       117,   -178,    290,    -21,    205,    -19,    321,   -343,
+      -328,    -57,    215,   -345,    304,      2,     10,  -2071,
+       185,    433,    212,  -1165,    112,    242,   -294,   -162,
+      1107,   1176,   -396,   1400,  -2600,   -434,   -640,    457,
+       100,   -268,    809,    128,   -236,    -66,    -94,   -842,
+        82,    163,    227,  -2641,   -485,    291,   -326,     42,
+       234,   -648,   1355,   3016,  -1403,    -71,    188,    792,
+        15,    -16,   -522,    -75,    106,   -824,   1133,    947,
+       477,   -642,   -531,   -808,   4100,    -34,   -407,    133,
+        33,     15,     63,     72,   -223,    -15,   -491,     38,
+        47,    258,   -236,    192,   1628,    173,  -2116,    687,
+       295,    -74,   -183,     95,    529,    149,   -372,    182,
+      1317,     21,  -1424,  -3156,   -111,    -96,    580,    284,
+      -274,     41,    145,   1314,     79,   1830,    262,   -325,
+       -16,    169,   -245,  -2038,   1959,    892,    946,    303,
+      -171,   -432,    883,     34,   -238,   2463,   -294,     25,
+        24,   -106,    -45,    509,   -154,    496,    109,    115,
+       169,    702,    396,    -97,    657,   -251,   -112,   -114,
+      -144,   -230,    517,   -190,   4885,    -45,   -152,     -9,
+      -170,  -2021,    541,   -905,  -2015,   2588,   -936,    -20,
+      -300,    384,    433,   -123,    119,   -505,   -126,    295,
+       526,  -1352,    450,    142,   -126,   -115,      1,   -140,
+      -734,    672,   -147,   -660,   -747,    652,    161,   -163,
+        51,   -616,  -1974,   1413,  -3145,    922,  -1289,    215,
+       182,   -838,   -171,    107,   -333,     34,    216,   -307,
+      -359,    496,   -343,   -325,  -2552,  -1573,    588,   -441,
+      1296,  -3075,    119,   -131,     54,    206,    278,    106,
+      -100,    112,    220,    -49,    -80,   -229,   1051,   3271,
+     -1300,    324,    -31,  -1025,   1659,   1526,   -161,    669,
+       -56,    430,    201,   -535,   -126,     -9,   -380,    222,
+       212,   -345,   -282,    195,    -41,  -1235,   -593,   -593,
+      1557,     71,   1023,   -831,    545,   -875,    161,   -772,
+        99,   -190,   1616,    338,   -251,   -201,  -3104,   -774,
+         4,   -121,    178,    -80,    652,  -1018,   -441,   -343,
+      -236,   -240,   -244,    -26,   2192,     75,  -1348,   3771,
+       -22,   -850,   -251,    316,    132,    -21,     63,    104,
+       152,    185,    -40,    275,  -1356,    482,   3081,    571,
+      -481,  -1387,    815,   1285,   -352,    -98,    -41,    573,
+      -307,  -1879,    427,    196,    169,    -26,   -232,    -98,
+      -411,   -231,  -2034,   -969,    271,   1421,  -1485,   -407,
+      1404,   -343,    861,    888,    -11,    202,   -245,   -397,
+       104,    229,    309,  -2757,    315,    416,    393,    194,
+      -176,   -663,   -166,   -229,    244,   -152,    183,     24,
+      -205,     97,   -255,   -299,    123,    -12,     53,    102,
+      -362,    371,    223,     46,    132,  -5177,    157,    -92,
+     -1114,    -28,    135,   -831,    627,   -428,  -1116,    421,
+       761,    458,   3256,   -167,    355,   2045,    113,    234,
+      -154,     20,    -39,     61,    -81,     63,     98,   -171,
+      1727,  -1193,   2103,    416,   -421,   -575,   -636,   -114,
+       700,   -260,   1610,   -336,    521,   2591,   -738,     43,
+       103,    -63,   -335,    168,    110,     41,   1995,   3554,
+      1443,    -53,   -206,    992,    767,   -372,    141,    -24,
+       173,     60,   -237,     69,   -173,    -73,    137,    167,
+      -164,   -159,    312,   -151,    -78,    619,   -192,    689,
+       -69,  -2805,   -259,   -288,   -231,     28,  -1682,   2316,
+      2298,   -336,   -131,     59,    542,   -218,   -281,   -214,
+       -41,    116,    138,      8,   -297,    -45,   -215,   -167,
+      1587,  -1061,  -1976,   -445,    401,  -2392,    -42,    581,
+      -519,   -230,   1461,    542,    113,   -634,   1776,    332,
+       191,      5,    174,   1939,    -26,   -242,    120,    230,
+      -986,   3501,  -1125,    -89,      3,   -580,   -219,   -255,
+        37,   -119,     94,    -17,   -297,   -176,   -434,   -234,
+        55,    -63,  -1167,   -492,  -1753,  -3397,    185,   -794,
+       689,    819,    -32,   -836,    335,   -133,    724,   -299,
+      -318,    424,    558,   -654,    119,   -447,    140,   -100,
+        72,   -872,  -1432,   -203,    -40,    -14,    -59,    550,
+        85,    -53,   5007,    258,    401,   -184,   -313,   -170,
+        66,   -185,    -82,    -61,    210,     48,   -204,    -96,
+       130,   -562,  -1700,  -1037,  -3926,   -884,   1115,     -6,
+      -100,    842,   -450,    877,     76,    568,   -623,     27,
+        73,   -195,    328,     41,    -24,    124,    -77,   1499,
+       540,  -1064,   4517,    -22,    -35,    839,    -48,    253,
+      -259,     96,    409,     90,     26,   -177,    365,    -48,
+      -324,    -26,    -23,    -83,    -77,    -80,   1599,   1486,
+       266,    659,    236,    231,    -16,    359,   -163,    455,
+      -999,  -1169,   2453,   -599,   -945,      4,  -2110,   -174,
+      -736,    344,    232,    142,     32,    -99,    763,    133,
+      -325,    -56,   1635,   -439,    843,      2,  -1704,    -13,
+       771,   3680,    -89,    182,      4,     42,    394,    404,
+        82,    312,     91,    141,  -1577,   1765,   3141,    625,
+      -271,  -2122,    423,    353,    489,    606,   -290,   -190,
+       486,   -131,    118,    236,    248,   -209,     -2,   -162,
+       -95,     95,    170,    278,  -2233,    549,     34,   -846,
+      3595,    445,   -400,    -65,    131,    -14,    -16,    611,
+      -116,   1293,     98,   -680,    189,    217,    -15,   -549,
+       131,      8,   -768,  -1082,    841,   -346,    129,    -33,
+      -778,    322,  -2508,  -2128,  -1895,  -2021,    -27,    -42,
+       -51,   -536,    239,     -1,     78,    105,     48,     79,
+       207,    422,   -181,     18,    -94,   -152,   -181,  -5012,
+      -187,     -3,   -118,   -397,    -84,    -49,    129,   -276,
+       188,     45,   -146,   -235,   -109,     83,     32,    -79,
+      2039,   -616,    257,  -1575,  -1756,  -2364,    222,    195,
+     -1138,   -290,     58,   -641,   -252,    -11,    402,    -31,
+     -1040,   -592,    676,   -118,   -231,     94,   -123,   1642,
+      1404,   -334,   -728,  -3425,    382,    111,   -194,    677,
+       177,   -182,    434,    860,  -1022,     84,   1214,   -733,
+       300,     -2,   -259,    140,     35,     96,   1164,  -1476,
+      -757,    -74,    239,   -203,   1796,   1207,   1732,  -3029,
+      -610,    658,    490,   -465,    136,     56,   -614,   -612,
+      -123,     93,   -151,    162,     56,    502,   1634,  -1825,
+        45,   1033,   1554,  -2380,   1615,   1317,    786,    387,
+      -255,   -423,    -44,   -246,   -213,   -149,    107,    -74,
+       -94,     45,   -204,     13,  -1959,    936,   2023,   1000,
+      1031,    112,    574,    323,    163,    947,   -657,    492,
+     -2624,    -44,    739,   -305,    -31,    247,    270,    213,
+       -46,    -90,     43,  -1504,    931,    -61,   4045,   -863,
+       389,   -386,   -130,   -374,   -583,   -800,   -900,    158,
+      -455,    169,    134,   -164,     54,   -117,   -185,    -90,
+      -203,    -41,   -811,  -2082,    169,    287,   -378,    -15,
+       231,     83,     89,   -187,    198,     18,    178,    -18,
+       527,    -40,     94,     54,     79,  -4356,    248,    162,
+       -94,  -1431,    -31,  -2048,    651,   1231,   -508,  -1089,
+     -1255,    766,   1673,    357,     13,   -813,  -2403,    179,
+      -470,     65,   -339,    154,      9,     56,    246,     66,
+     -2308,   1443,   -947,   -744,  -2473,  -1248,   -113,   1017,
+      -608,    149,   -182,     41,   -524,     16,    285,   -268,
+      -781,    -57,   -346,    194,    256,    -51,    107,   -484,
+      -190,   -125,   -645,    487,    314,     74,   -555,  -1012,
+       325,     76,    233,   -205,   -189,    -48,  -4593,   -122,
+        10,    121,    -91,    108,    -49,    254,  -1662,   2500,
+        87,  -1540,   -200,    287,   -329,    -50,   -401,    182,
+     -1300,    689,    915,   -224,   -768,    471,   -339,    133,
+       407,   -344,     99,     96,    111,   1224,  -1431,   2069,
+      -282,    127,    397,   -119,   1332,  -1299,    744,   -535,
+       800,    327,    874,    700,   -424,  -1596,   1365,   -651,
+      -151,    113,    102,    -24,    464,    125,    911,  -1583,
+      -372,    747,      2,    429,    -47,    -64,     34,   1700,
+      -741,    343,    728,   -226,   1889,     78,   -515,   2827,
+        77,    -66,    108,    515,     90,   2227,   -678,   1301,
+      -974,    122,   -983,   2357,     64,  -1479,    186,   1436,
+      -245,    204,    460,    191,   -677,   -335,   -200,   -135,
+      -106,   -101,   1112,  -2733,   -641,     73,   1265,  -1281,
+     -1332,   -743,    675,    129,  -1144,  -1169,    331,   -143,
+       -87,    809,   -891,   -848,    246,    243,     97,   -170,
+        36,  -1109,    102,   1055,  -1395,   1384,   1155,    439,
+     -1549,   -300,  -2069,   1014,    187,   -782,    980,   -971,
+      -345,   -583,    -66,   -138,   -317,   -124,     48,   -152,
+       -98,     92,   2446,    128,  -1232,   2148,   -337,   -615,
+       467,   1573,   -613,    857,    303,    422,  -1340,   -420,
+       305,   -626,     94,   -496,   -386,   -129,    243,     27,
+      -200,  -1373,   1468,  -2040,    151,   -675,     65,   1464,
+      -432,    545,    269,   -510,    584,  -1935,    970,   -319,
+      1465,    490,    263,    555,   -256,    -49,    315,   -242,
+      -394,   -312,    -88,    201,   -121,   -302,    172,     49,
+       234,     59,    327,    155,    199,   -187,    -41,    -74,
+        52,    -31,    -59,  -5574,   -121,    282,    343,   -125,
+      -200,   -575,   1328,    155,  -1928,    250,    702,     21,
+     -2718,   -153,   -102,   2131,    612,    432,  -1072,   -457,
+       222,    427,    144,    149,   -433,  -1573,   1337,   -650,
+       176,     13,  -1273,    280,   -751,   -236,    453,    204,
+     -1595,  -2896,   -272,    233,    485,     82,   -139,   -528,
+      -140,   -399,    -56,   -274,   -335,    176,   -756,    243,
+      2250,   -305,    721,   1711,      7,  -1230,  -1590,  -1872,
+      -137,   -714,    263,  -1643,    362,   -266,   -176,     64,
+       -36,    -63,    687,   -483,  -1488,    709,    929,   1349,
+     -1245,    645,  -1619,    735,   -651,   1850,   1031,    159,
+      -625,    838,    242,   -396,   -397,    -41,   1237,    304,
+        81,    -94,   -736,    578,   1279,   1064,     81,   1900,
+      -179,    224,    266,   -429,    734,    500,    995,   -882,
+      1563,   1813,   -519,    758,    532,    -27,     27,    453,
+};
+
+static const int16_t cb4432m0[] = {
+     -6132,   -262,   -273,  -1250,   -577,    984,   -430,   -410,
+      -464,    577,   -578,   -178,    -32,    369,   -624,    267,
+       -68,    474,   -480,   -225,    166,   -409,    437,   4633,
+        98,  -1560,   -464,   -869,    103,    193,    461,     72,
+       292,   -245,   1102,    417,   -325,    461,     74,     43,
+      -120,   -213,    333,    160,   -468,   -212,     31,    -81,
+      6516,    182,    201,   -212,    -66,    -49,   -266,    148,
+      -108,     98,    -46,    -11,    -59,    -20,    -20,   2332,
+      -294,   -560,    198,   -647,    -47,   -638,  -3877,     11,
+       834,    547,     47,   2541,   -126,     -5,   -366,    339,
+         3,      2,    -66,     60,   -526,    914,    321,   -658,
+      3605,     59,  -2392,   -655,    384,    775,    366,    327,
+       356,    386,    751,   -375,     38,   -205,    -15,   -442,
+      -212,  -1241,   1913,   -421,   -755,     45,  -1637,    -36,
+     -2435,   1504,  -1248,   -763,   -664,    133,   -123,    814,
+       241,   -243,   -446,     66,   -131,   -213,   2036,   1294,
+     -2138,    677,  -1042,   -771,    294,    371,    474,     85,
+      1403,  -2618,   -478,   -537,    275,   -826,    349,     84,
+       264,   -272,    -61,   -705,    175,   -972,    868,     25,
+      4183,    881,   -639,   -833,   -757,  -1063,   -991,   -257,
+      -137,   -619,   -285,   -454,     77,   -169,    316,    -45,
+      4362,   -203,  -2132,   -424,   -820,   -503,    340,    340,
+      -612,    648,      2,   -342,     81,    630,  -1518,    235,
+       216,    210,    665,    231,    130,   -879,     38,    675,
+      -136,    -48,    540,   -234,   -152,   -169,  -5745,   -294,
+       -24,      8,   -129,     -8,    308,    -14,    -16,    147,
+        62,     70,    248,  -2014,     76,   -190,   -328,  -1899,
+      -353,   -140,    836,   -365,   -112,  -3945,   -736,    467,
+      -258,    601,    617,     74,     62,    394,    180,   1151,
+      -810,     36,    457,    406,     75,     -8,  -5004,   2335,
+      -108,   -123,    299,   -335,    112,   -499,   -268,   -185,
+       461,    208,    -38,   -164,    764,   -504,    272,   4853,
+       396,    265,  -1133,   -433,    769,   -458,   1005,    645,
+        81,   -172,    385,    -56,   -130,   -393,    128,    -73,
+        31,   2038,    127,   -436,    123,  -2525,    282,   -448,
+      -489,   -295,    -14,     85,   -462,    -49,    262,    -93,
+       238,   -148,  -3953,   -414,   -259,     33,   -892,    459,
+     -2186,     60,    444,   -610,    844,   -486,   -299,    219,
+      -433,     19,  -1183,    276,    -29,    388,   3327,    102,
+      -914,   -221,    486,   -892,   -550,    190,    151,   -141,
+      -336,    194,   -242,   -224,    405,    879,   1600,    349,
+     -2082,    -38,   -514,     18,  -3574,    161,   -142,    -38,
+     -1815,    540,    228,     33,    164,   1074,      4,   -278,
+       -58,   4085,   -295,   -795,     31,    494,    555,   -250,
+        22,   -202,   -312,     92,    109,   -238,   -448,   -622,
+     -1511,  -4346,   -417,   -706,     37,   1157,    -96,   -199,
+       -59,    285,    -43,   -217,    -22,    -95,    103,   2242,
+       244,     45,    -74,     -7,    366,    -79,   -359,   -286,
+       188,    -14,     34,     49,    245,   -108,    -84,     88,
+      -333,   -216,    -79,     15,  -5710,    -36,   -102,   -552,
+      -213,     -8,   -356,    515,    212,   -265,     80,    316,
+     -1163,   -561,   -517,   -714,   -375,  -4176,     73,   -666,
+      -363,    -28,   1248,    -68,    478,   2648,    642,   -710,
+      -555,   -744,   -166,   -744,   -596,    138,    499,     59,
+       453,   -583,   -290,    -11,    -48,   4174,   -252,    -74,
+       -78,    -62,    449,   -265,   -818,   -357,    171,   -513,
+        72,    106,    -45,    649,    145,   5558,    -60,   -136,
+        69,   -172,   -134,    -66,    -68,    100,    683,   -427,
+       795,   -407,    345,   4930,   -838,    361,    279,   -190,
+       173,   -341,     -9,    722,    383,   -140,    123,   -269,
+       154,     31,    335,   -465,    311,     46,   4535,   -131,
+        90,    151,    287,    -11,   -526,   -614,  -2253,   -321,
+       -93,   -550,   -128,     25,    303,   -139,     19,      0,
+     -3255,   -161,    276,    103,   -245,   -515,    816,  -1042,
+     -1449,   1693,   -627,   1287,   -837,   -727,    -80,   -478,
+      -337,    116,      1,   -270,   -567,   -311,   -407,  -1656,
+      -216,    196,   3004,   -285,   -521,   1510,   1818,   1392,
+        42,    -44,   -244,   -349,    959,   -183,     25,     58,
+        43,   -345,   -310,  -8192,    -84,    311,    -60,   -348,
+       125,     33,    -79,   -138,     88,    138,   -121,    -37,
+      -211,   -118,   -142,    -37,   -132,    181,    162,  -1423,
+      1781,  -3453,   1261,    134,    670,   1218,    761,    292,
+      -146,   -825,    672,    737,    293,    433,    245,   -392,
+        46,    598,    257,   -234,  -1201,    718,  -4549,   -573,
+      -696,   -224,    -85,     75,   -268,    244,   1817,    341,
+      -166,    436,   -386,  -1247,     22,   -112,    -55,   -451,
+       106,    388,    -32,   -254,  -2400,   -373,    892,    334,
+     -4114,   -307,   -107,   -316,     41,   -214,   -403,    -56,
+      -469,   -246,    120,   -237,    266,     43,   3257,  -3925,
+       291,    239,    752,   -411,    162,    437,    159,    256,
+        37,     71,    -79,   -136,   -475,    124,   -208,   -216,
+      -245,     16,     40,   -459,  -4320,    340,  -1462,    914,
+        10,    490,    436,    162,    271,   -238,    -38,   2219,
+        25,   -141,    405,    107,    235,    282,    -55,     -7,
+     -3429,    565,  -1095,   -678,   1979,    233,   -874,    592,
+      -474,    680,    402,   -738,     21,    274,   -321,    655,
+      -348,   -546,    510,     62,     23,   4722,    572,    423,
+      -256,    473,   1240,   -997,   -899,    -53,    -73,    332,
+      -902,   -771,   -335,      0,    769,   -587,    592,   -703,
+      -600,    -77,    -94,   -207,    792,   -133,   -758,    500,
+       -14,    330,     22,   -281,  -5460,    152,    607,    337,
+       -39,   -118,    -80,    -51,    228,     65,     -6,    540,
+     -3515,  -1712,   -449,   -157,   -164,   -195,  -1655,  -1285,
+        90,   -517,   -116,     11,   1402,   -162,    -64,   -103,
+        46,    302,     37,     71,   2903,   2952,    780,   -487,
+      -297,   -426,   -369,    150,   -129,   -233,    813,   1639,
+       190,    310,   -311,    320,     94,   -247,   1484,    -32,
+        70,   -220,    560,    372,     54,    205,     96,  -3567,
+      -680,   1683,  -2377,     17,    548,   -266,    257,    656,
+       331,    205,   -121,   -814,    139,    326,   -370,    625,
+      2035,    818,    775,  -1165,    -41,  -4258,     41,   1109,
+       984,   -885,    -43,   -314,    204,    204,     95,    407,
+      -351,    101,    133,   -929,    899,     -6,    384,   -177,
+      -330,    240,     90,     78,   -318,   -455,     -5,   -365,
+       -61,    -80,    -72,  -4850,   -338,   -384,     30,    181,
+     -2721,   -767,   3217,    453,   -226,   -582,    283,    135,
+      -103,    265,    494,  -1444,   -120,     70,   -976,    -67,
+       -90,    660,    366,   -609,     32,    205,     73,     51,
+       346,     -6,   -120,    -10,    300,     32,    270,    139,
+       -55,    453,   5712,    353,   -145,    176,   -168,    216,
+       205,    -30,   -304,   1085,    221,    464,   -426,   1662,
+     -1397,  -1114,    301,  -1058,   3553,   -388,    743,    696,
+      -893,   -296,    -57,   -254,   -251,   -178,    417,     82,
+      -988,  -3566,   2171,  -1312,   -954,    -23,  -1349,    480,
+       566,     24,   -643,   -292,    -68,    303,     73,    -81,
+       296,      7,    371,     94,   1718,    498,   -774,    857,
+      1014,    358,    436,    210,  -3481,   -202,   -416,     59,
+      1987,    137,   -476,     32,   -627,    193,    368,     -3,
+      -290,  -3035,   -352,   -455,   -609,   -175,     -5,   -600,
+      -181,   -249,  -2551,    226,    105,   -249,   1851,    -86,
+     -1203,    214,    -57,   -505,   -522,   -247,   -154,    -40,
+       -17,   -523,    333,  -1777,   -354,  -1568,  -3492,   1032,
+      1577,     90,    153,    534,   -106,   -538,    102,      3,
+      -198,    -99,    -23,    835,   3495,  -1099,     44,    732,
+      -350,    926,   -472,    533,   1529,     54,   -844,   1295,
+       573,    414,    -23,    -71,    279,   -891,    287,    126,
+      1456,    973,    456,   1608,   -646,  -1244,    452,    651,
+       694,    855,   -235,   -503,    745,   -544,  -3512,   -138,
+       678,    473,    220,   -273,     -9,    265,  -1874,    397,
+      1196,    284,   -963,    298,    318,  -2309,   -162,    322,
+     -1250,    -16,  -1004,     -5,   2800,    -64,     72,   -482,
+      -162,   -412,  -2922,    774,   -335,    238,  -1144,   -134,
+      1428,    558,   1969,   -659,    902,  -1698,    793,   -858,
+      -613,    998,    253,   -336,   -348,    -80,   -117,   -264,
+       355,    808,    784,   -559,   2030,   1952,   -244,  -1130,
+      -986,   1883,   1171,   -493,   -326,   -880,   2588,   -243,
+      -204,    194,   -172,    -65,   2026,    424,    587,   -317,
+      2550,   -601,    203,   -669,    475,   -676,  -1492,     27,
+        41,  -1078,   -299,   -630,    177,   -164,   -429,   -246,
+      -357,   1191,   -867,  -1363,   1621,   -110,    916,    217,
+     -1269,    622,   -434,  -1113,    888,    -41,   1020,  -1774,
+        46,     80,   -483,   -892,    -61,   -472,    193,   -192,
+      2000,   -103,    740,   -223,   2493,    422,   2508,   -331,
+       470,  -1233,     47,    595,    795,   -465,   -320,   -163,
+       128,      6,   -209,    603,    536,   -416,  -1455,    -87,
+     -1191,    -98,   -281,   1003,   1421,    388,   1163,  -1146,
+       -81,   -299,   2518,  -1072,    207,   -443,    506,   -220,
+      -346,     98,   2119,   -416,  -2268,   -498,    109,  -1342,
+      -335,   1125,   -712,    156,  -1088,  -2092,   1164,   -500,
+       113,    -17,    551,   -199,    262,    -27,   -692,   -629,
+       204,  -1448,  -1606,  -1554,    289,    382,   -691,   1229,
+       414,  -1746,  -1198,   1113,   -386,    310,   1354,    -12,
+      -284,   -569,     46,   -558,   1495,    172,   -899,    617,
+       827,   -365,    100,   1008,    136,   2111,     10,   2320,
+      -291,    364,   -401,   -408,   -528,   -612,    127,   1218,
+      -384,    129,  -1603,    438,   1029,   2536,   -150,  -1432,
+      -856,   1068,    773,   -762,   -808,    676,   -693,    404,
+       145,      4,     27,   -148,   -318,  -1019,   -277,   1404,
+       880,  -1135,    861,    903,    739,    303,    139,   1918,
+      -952,    801,   -306,  -2439,     -3,    442,   -590,  -1034,
+       178,    430,    153,   1853,   1997,    742,   1745,   -608,
+      -237,    160,    523,    950,     82,  -1468,  -1592,    807,
+       719,    618,    319,     57,    235,    287,   1344,    -50,
+       324,   -182,   -365,   -381,   -377,   1989,    147,   -573,
+      1246,   1769,   -473,   -178,    961,  -1297,   -750,  -1428,
+     -1246,    789,    158,    612,     17,   -292,   -227,   -142,
+        64,     51,    -16,   -301,   -287,    -60,   -404,   -267,
+       109,   -108,    189,   -438,     48,     95,  -5059,    -42,
+};
+
+static const int16_t cb4432m1[] = {
+      7567,    273,    268,    -74,    201,    274,   -149,   -146,
+      -262,    243,   -273,     63,   -127,    135,   -160,    231,
+       120,    209,    -91,   -218,    -38,  -1206,   -468,   -159,
+       278,    536,   -995,    -60,     22,   1041,   -550,   -121,
+      -241,   -664,    427,   -416,  -1395,   -732,    152,   3247,
+       -67,   -154,  -2430,    421,   -405,   -558,    -73,  -2887,
+      -272,    -60,    365,    745,    287,   -622,  -1103,    412,
+       266,     82,     61,  -2172,   -379,    529,   -125,  -1482,
+       319,    643,    222,   -508,   2451,   -970,     71,    237,
+      -280,    202,    983,   -223,   -307,   -130,    217,   3209,
+        49,    -30,    275,    -12,   -260,  -3959,   1219,   -104,
+     -2700,   -201,     54,    851,   -590,    691,   -254,    408,
+       296,    -48,   -364,    216,     16,    220,   -415,    218,
+        83,     43,  -4032,  -1359,     25,     15,   -279,  -2092,
+       794,   -433,   -195,   -162,    606,    166,     87,   -316,
+       508,    242,   -359,    687,   -178,     14,  -2969,   -500,
+     -1041,   3234,    679,    170,   -791,   -127,   -630,    -16,
+       -19,    181,     -2,   -185,   -172,    -88,   -118,   -167,
+       128,    121,    239,    321,   -125,    217,  -7260,   -157,
+      -161,   -347,   -257,    102,  -1181,     71,   -379,   -205,
+      -268,    144,   -174,   -106,    305,     23,    -47,    202,
+      -110,    660,     54,  -2963,   -119,  -1371,  -2823,   1171,
+      -726,    690,    534,    161,   -435,    753,     58,    227,
+       241,    138,    -76,    473,    193,  -1926,  -2183,  -2526,
+     -1428,    284,  -1270,    336,  -1458,    208,     41,   -356,
+       345,    153,   -273,   -166,    500,     42,    120,    -35,
+       -81,     56,   1747,  -3050,  -2029,   -764,   -947,    888,
+       422,    374,    143,   -318,   -225,    604,    343,    -91,
+      1626,     75,   -211,    160,   -667,   -195,     38,   -446,
+     -1269,   -108,   -959,   -616,   -530,    554,   2865,   -156,
+      -358,   -429,   -261,     23,    511,    340,   -548,   2347,
+       105,     12,    -32,    164,    170,   -168,    268,   2587,
+      3511,    612,    329,    159,    456,    273,   -452,    168,
+      -394,    799,    -58,    160,   -480,   -257,    242,    167,
+        46,  -1433,  -1631,     50,    852,    509,    864,   -381,
+      -306,   -698,    261,   -702,    -19,   4113,    -38,   -153,
+       -11,    405,   -441,   -120,    139,   -265,    225,    342,
+       199,   2085,    237,    278,    252,   1537,    119,    182,
+      -174,   -193,   2486,     87,   2903,   -311,   -304,    273,
+      -217,   -256,   -264,   -675,   -819,   -188,   -615,  -1183,
+       495,   -154,   -687,   2423,    197,    -63,   -146,   1151,
+       896,  -1129,    -58,   1114,  -1644,   1219,   -648,    -71,
+      -130,  -2643,    533,   -218,   3942,    -83,    208,   -724,
+       198,   -643,    590,   -944,    -56,   -420,    115,     23,
+      -414,   -144,    295,    219,    -36,    393,   -174,     91,
+       290,  -7066,    158,   -275,    -70,   -119,     -1,    302,
+      -262,    -73,    -61,    110,   -196,    -25,     87,   -446,
+      -159,     -6,   -107,    115,  -7562,      5,    -33,    284,
+      -106,     34,   -140,    160,   -304,   -272,   -169,     25,
+        93,   -205,     28,    169,   -165,    -34,    -50,    343,
+      2204,   1440,    817,  -1921,   -590,   -527,     81,   -364,
+      -354,    163,  -1058,   1977,    244,    -75,   1201,   -207,
+       293,   -289,   -105,   -121,   3588,    925,     -2,   -201,
+      -860,    917,    100,    265,   -200,    -44,   -529,    351,
+      -579,   -103,    186,  -3622,     52,    181,   -259,   -411,
+        -4,   -328,    380,    517,    306,     57,    340,    -65,
+      -263,   -311,    494,    326,  -6136,    747,   -141,    296,
+       217,     -2,   -125,      8,    -88,    254,  -2934,   -259,
+       946,   -905,    653,    436,   3393,   -147,   -157,     27,
+       166,    299,      8,    -16,    643,    114,    217,     57,
+       -21,   -298,     19,    129,   1721,   -134,   2337,    781,
+      -483,   -748,    118,   -330,   -226,  -3762,    222,   -417,
+      -154,    -24,    -13,   1138,    210,    357,   -122,    257,
+      -369,    863,     13,   -320,   -439,   -433,   3469,   -869,
+       116,  -2772,    202,   1065,   -130,   -287,    142,   -288,
+        54,    318,    131,    -16,     84,    238,   -361,    934,
+      1341,     37,    130,   -412,    146,   -724,     -3,   -823,
+      2555,  -1263,     11,   -147,   3164,    -83,    -39,   -127,
+       258,     26,  -1181,   3339,   -676,    -30,    -56,    691,
+       867,    715,   -903,    293,   -205,   -392,    -22,    529,
+       -76,   2201,    433,    134,   1338,    -18,     85,   3128,
+        33,    924,    257,   1662,   -769,    321,   -449,   -374,
+       -58,   -597,  -1670,     97,    222,   -998,    404,   -155,
+       133,    358,   -250,   -125,    163,   6027,   -228,   -116,
+       -61,   -878,   -693,    710,   -516,   -191,    -27,    443,
+        83,   -174,   -695,   -117,   -107,    -53,   -142,     92,
+      -145,   -114,    -62,   -710,  -3192,   -872,   3284,   -521,
+       -36,   -948,    252,   -253,   -143,    260,    109,    -24,
+       262,   -169,   -196,    195,    105,     27,   -135,   1722,
+      1862,   -513,   -270,   -144,   -414,    -59,     91,   -288,
+       -96,    -56,   -204,    273,    170,   -171,    -62,  -4993,
+      -125,    -67,    -50,    226,   -275,    600,    105,   -217,
+      -450,    -87,    -20,   -353,     24,    -74,    167,   1881,
+     -4260,   -144,     48,     92,    187,    319,    341,     22,
+        -4,    405,    147,    237,   -120,    122,   -237,     56,
+      -515,   -153,    333,    834,    401,    210,  -5516,      7,
+       127,    147,   -140,   -479,    -26,  -1669,    -21,   -147,
+        60,    387,    565,   -140,  -5827,   -269,  -1119,   -324,
+       118,   -199,    -11,    105,    -49,    150,   -148,    178,
+       182,    162,    150,     68,   -227,      3,    221,   -330,
+       -23,     65,   6262,     71,     48,    -41,    -10,     -1,
+       -44,   -255,    -50,   -138,   -109,    -54,    -31,    492,
+      -214,    239,   -194,     35,  -6348,   -148,      9,     25,
+      -123,     84,   -448,    241,    148,    -35,     52,     35,
+         7,     99,    -16,     57,    -43,   -256,   3336,    373,
+       211,   -513,   2328,     86,   -274,    386,     74,   -174,
+       624,  -1037,  -1154,     36,   -209,  -1028,   -101,   -412,
+      -103,   -267,   -107,   -126,    163,   -394,  -1097,   -100,
+     -1575,   -542,   3326,  -2149,    547,    626,   -278,   -414,
+      -781,    486,   -186,   -159,    138,   -187,   -821,    419,
+       393,  -4266,    828,    431,     86,    745,   1313,   1484,
+       260,     52,    163,   -455,  -1071,    186,    522,    288,
+       421,     18,     97,   1267,    200,   2637,   -189,    729,
+       746,    203,   -639,   -843,   2164,    671,     84,  -2384,
+       430,   -161,    404,    166,    -33,    -17,    591,   -227,
+     -3849,   1579,    175,   -718,     99,   -410,   -844,   -239,
+        32,    212,    163,    480,    843,   -379,   -621,   -317,
+      -424,    113,   -262,     44,    -93,    529,    144,   -218,
+       140,   3257,   -575,  -2697,    144,    -83,   -186,    -44,
+       977,    153,   -230,  -1530,    234,    212,    212,    331,
+       412,   -125,     -3,    422,   -329,  -2181,   1406,    363,
+       -90,    -86,    329,   -267,  -4462,   -189,    -87,    154,
+        66,   -200,     37,     80,   -109,   -199,    125,   1983,
+       260,   -438,  -2417,   3259,   -974,    453,     41,    -77,
+      -538,   1123,    119,    120,    254,   -239,   -134,     33,
+      -384,   -407,     27,    465,   1810,   -910,    980,    -15,
+     -1307,   -919,   1880,   -327,   -303,   -198,    149,    413,
+      2176,   2269,   -707,    343,    360,    169,    148,    182,
+       104,    163,    857,    291,   -153,    303,   -679,   -386,
+      -868,   2283,   -320,    167,   3257,   1741,    338,    467,
+       209,    207,    834,   -226,   -479,   -120,   1674,    -61,
+       696,    -93,  -1327,   2176,    716,    402,   1688,   2219,
+      -339,    779,    366,    358,    241,   -695,   -272,   -136,
+       -48,     36,   -269,    862,   -616,   -118,  -2028,   1678,
+      1971,    115,    290,     71,   -765,     31,  -2874,    122,
+        13,   -424,   -281,   -320,    233,  -1032,     40,   -186,
+      1208,    274,  -2310,  -1594,    289,    230,   1264,    962,
+      -310,     23,   -548,     12,    -38,  -2734,    664,     37,
+       346,   -620,    266,    -98,     82,   2369,    963,  -1391,
+      -451,    833,     82,    175,    448,   1874,    345,   -440,
+       155,    130,     94,    326,   3223,    234,   -163,   -384,
+      -354,   -539,    827,     -9,    530,   -226,    -21,    332,
+     -2298,   3221,   1470,   -282,   -800,    231,    314,   -998,
+     -1051,   -648,   -434,    743,    -72,    119,     91,    414,
+       379,   1370,   -637,   -998,    851,  -2904,   -266,  -1652,
+     -1356,  -1339,  -1679,   -181,    245,    731,   -231,     -2,
+       221,   -182,   -325,   -411,    346,    246,  -2629,   1736,
+      -361,     24,    229,   1168,    747,    309,    425,   -128,
+      -320,   -496,    109,   1496,    -70,   -797,     37,   -271,
+       -39,    906,    -62,   -194,   1753,    311,    689,   1354,
+     -1035,   -973,   -438,   1166,   2197,    -99,   -380,   -274,
+     -1565,    447,    100,    349,    485,    653,    744,     50,
+      -582,   -123,  -1396,    156,    -27,    349,  -1067,  -1382,
+      1388,  -1061,   -554,    894,    -80,   -783,  -1500,   -736,
+       897,   1158,  -1386,    -40,   -280,   -819,   -672,   -895,
+       994,   -308,   -466,   -578,    455,  -1536,    879,   -448,
+       542,   1508,    850,  -2465,    816,    641,   -427,    310,
+      -168,    -41,   -908,   -302,   1513,    -29,  -1144,    588,
+     -1703,   1144,   2623,     90,    284,    866,    335,   -351,
+       419,   -745,    879,   -183,   -824,  -1713,    -34,    -15,
+      -913,     37,   -460,    778,   2130,   -145,   -153,   1761,
+      1420,   -243,    -32,   -877,    140,   -700,    612,  -2053,
+       321,    -78,   -165,    200,    526,  -1002,   2176,  -1022,
+      1436,    298,    -21,  -1378,    515,    304,    974,   1722,
+      2054,    661,    425,    282,    471,    438,     70,    169,
+      1587,  -2076,    -40,   -702,    264,   -146,  -1499,   -863,
+     -1775,  -1059,   -490,     92,    631,  -1194,  -1031,    335,
+       257,  -1299,    241,   -270,   -325,   -322,    -37,      0,
+      -685,    897,    984,   -909,   1556,   1281,   1367,  -1269,
+     -1591,    415,  -1156,   -374,   -110,   1552,   -695,     74,
+      -167,   -473,   1421,   -611,    175,   1521,   1322,    436,
+      1969,   -787,   1041,   -730,   -598,    188,   -794,   -531,
+     -2198,   -317,    -11,     -8,   -407,    198,  -1180,  -1675,
+       174,    981,    467,   -149,   -890,    263,   1030,   -121,
+      2147,   -135,   1975,   -634,    431,   -238,   -695,   1338,
+      -172,    110,    147,   -334,   -726,     65,   -873,    667,
+       997,  -1118,   -339,    144,   -700,   1303,   -207,   -609,
+     -1617,   -765,    839,    505,    -36,    -58,  -2894,    226,
+};
+
+static const int16_t cb4440sl0[] = {
+     -3624,   -495,    158,   -246,   -529,   -813,    689,    504,
+      -527,  -2216,   -198,   -323,   -690,   -591,    175,    262,
+       243,  -3676,   2648,   -986,    166,    243,    301,   -700,
+       324,   -324,     13,    362,    222,   -470,     30,     20,
+       -46,   -147,   4050,    -97,   -560,    284,    317,  -1611,
+       655,   -416,  -1582,   -675,    389,   -124,    150,    -27,
+       325,    -84,     48,   7474,     97,    105,     19,     38,
+       133,     19,     28,     25,     40,     34,    -59,     22,
+        11,     27,     21,      5,  -1596,   -428,    439,    353,
+      2288,    -18,    357,   -274,   2582,   -126,    -90,     71,
+        -9,   -704,    205,     22,     44,   -120,    -43,    517,
+       817,   1370,   2151,   2818,   -470,     90,    395,  -1243,
+      -345,    959,     19,     -1,    123,   -108,    347,     25,
+      -138,     15,    119,   -117,   -146,    142,    183,   -254,
+      -276,   -174,   5980,    283,   -317,     70,     51,    -15,
+     -2447,    -79,    234,    736,  -2600,   -641,  -1162,    376,
+       959,   -250,    701,    -40,   -102,    204,    -38,    -24,
+      -893,   -387,    339,   1338,    -91,   -655,   -864,     78,
+       299,    228,  -2732,    234,   1995,  -1321,   -139,    500,
+      -316,   -140,      2,    -80,    186,     11,     16,    -69,
+     -7534,     85,   -263,    189,     -7,     -1,    -67,    -68,
+         3,     24,    391,  -3299,  -2952,   -121,   -393,    103,
+       -60,   -113,    141,    185,   -119,    240,    270,   -392,
+      -105,      9,    -39,   2529,    -17,    353,   2966,   -855,
+      1042,   1294,    132,   -257,   -257,   -496,    112,   -179,
+       424,    486,    -63,     77,    275,   -198,   2026,   1657,
+       913,   -255,   -147,  -1748,     -5,    418,    356,   2022,
+       927,   -295,    194,    165,     28,    109,     13,    209,
+      -133,  -2802,    420,  -1873,   -648,    309,  -1172,  -1825,
+       -36,    840,    280,     44,   -118,    128,     34,    241,
+     -1005,   1160,   -303,    318,    726,  -1716,   2625,   -950,
+      -839,  -1257,   -901,   -238,   1123,    131,    252,      1,
+       440,   1455,    -14,   -274,   -461,     87,   -515,  -2299,
+       928,  -2867,   -804,   -215,    680,    147,     80,    215,
+        15,   1339,    141,    -95,    134,    -35,    122,     53,
+       429,    168,    476,    -45,    745,    236,   4229,    318,
+       247,   -201,   -372,   2289,    161,    431,    337,   -707,
+     -1024,    121,  -1773,   -795,  -1187,   -401,    394,  -1431,
+      1526,    -35,    432,   2929,     90,   1880,    628,   1298,
+      -552,   -498,    207,    -97,  -1431,   1105,     29,   -739,
+       -56,     62,     94,    537,   -732,   1255,   -766,    200,
+      -365,   2846,   2139,    435,     92,   -710,   -512,    360,
+      -339,   1021,    474,   -132,    405,   -440,   3435,     75,
+      -254,  -2443,   -880,    325,    343,    285,    230,   -431,
+      -191,    215,    201,   -443,     93,    -81,   -131,   2981,
+     -2986,   1003,    437,    434,   -386,     17,    222,     70,
+       173,   -550,    267,   -121,    -43,    114,    -11,   -795,
+       561,   -147,    187,   -198,  -4969,     50,     59,    674,
+      -853,    163,     71,   -205,   -284,    -50,    -28,  -1412,
+      -105,    262,    272,    565,   -824,   -541,   3381,    430,
+       -81,    228,   -426,    978,   -294,    422,   -538,     13,
+         9,    430,    180,   2329,   -564,  -1082,   1740,   1108,
+     -2011,     11,    343,    868,    723,   -806,    342,    339,
+      -141,   -173,    186,     50,    297,    705,    783,   -593,
+      1609,    212,    528,  -2547,   -863,  -2457,   -876,    164,
+       162,    365,     68,     30,     11,     48,     47,   -285,
+       -64,    166,    -21,  -6880,   -191,   -226,     89,     -1,
+        22,    -93,     -6,     44,    282,     52,    294,   -690,
+      -147,    372,   2247,    804,   -637,     54,   2385,  -1799,
+       315,   -929,    692,    -65,    -54,    218,   -752,   -519,
+      2171,    177,    907,     22,   -778,  -2656,     62,   -418,
+      -434,    307,   1906,   -280,    196,     76,     58,    -46,
+        70,   -367,    -67,     50,    125,     77,   -547,   -287,
+       -97,    -10,    -84,   -271,  -4856,     10,    490,   -560,
+       -21,     66,  -2469,   -322,   1021,    936,    625,  -2520,
+      1144,   -373,    270,    804,    603,    -91,    262,    659,
+         9,   -324,     50,   -712,   2705,  -3016,    594,     87,
+       -88,    697,   -205,   -799,   -128,     37,    504,     59,
+      -274,    655,    672,    -20,   1294,   -221,  -2954,    198,
+       674,  -1676,    863,    324,    968,    731,   1125,    -41,
+      -149,   -303,    223,   1370,    -67,   -194,     -1,   -194,
+       251,   -459,    -39,   4477,    113,    -74,   -386,    214,
+       -72,    -77,  -1593,    511,   -461,    752,   -559,   -476,
+       204,   -722,   1050,   2080,   2468,   -154,   -208,    964,
+       103,    -58,    390,  -1863,    910,   -307,    209,    -32,
+       663,    103,   -133,  -3137,   -423,    259,   -605,   -242,
+       139,   -391,   -488,     77,   -266,  -1694,    397,   -659,
+       237,   2068,     -3,   -867,    870,   1647,    645,   1848,
+        68,    382,    455,   -551,    -87,    -99,  -2926,    372,
+      2438,  -1166,     -6,    521,   -195,   1259,   -162,    917,
+       140,    275,   -273,    133,    318,    -25,    252,   -119,
+      -132,   3120,    397,    398,   -420,   1756,    666,   2176,
+      -141,    271,    -51,     22,   -494,    -36,     57,    308,
+       222,   3585,     16,   -265,   2628,    -24,    162,     13,
+      -240,    -96,    620,    331,   -449,    710,   -123,   -105,
+        23,   -170,     20,    256,  -5228,    398,   -186,    272,
+       129,    175,    598,    -16,   -502,     11,   -215,     28,
+      -110,   3570,     68,    199,  -2535,   -933,    781,   -762,
+       325,     18,   -438,   -319,    473,   -677,    176,    290,
+         0,     67,     -6,   -156,     31,     35,   -131,   -127,
+        24,   -100,  -6826,   -117,    -53,    -40,     99,    -50,
+       -93,     31,     34,   -251,    186,    487,   -203,   -662,
+      -182,    -96,    239,    308,    338,    -86,  -4871,    264,
+       -48,    314,    -66,    100,   -188,    151,     24,    198,
+         4,   5046,    -47,   -654,    -43,     41,    109,    103,
+      -262,     93,   -118,    -63,     58,   2088,    336,   -320,
+      2326,    548,   -810,  -1315,   -864,    461,    171,     76,
+     -1109,  -1510,   -874,   -620,     97,     88,     40,     -4,
+     -7295,   -128,    -39,     23,   -100,     -9,    -74,    112,
+      -151,     67,     21,     53,      2,    -29,    -33,     52,
+      3287,  -2178,    626,    339,   -817,    349,  -1187,   -550,
+      -390,     57,    -41,    295,    756,    185,   -215,     17,
+         3,   7502,   -134,   -122,    -31,    -53,     91,   -170,
+       -71,    133,    -34,     57,   -112,     -5,    -66,     17,
+         1,   2328,   3714,    214,   -123,   -839,      9,    -62,
+        54,     70,    -18,    817,    186,    -61,   -252,     37,
+        98,      9,   2010,    738,  -1651,  -1924,   1106,   -624,
+       143,   -548,    847,   -198,   -140,   -691,    478,   -758,
+        56,     54,     -7,    209,  -2665,    109,   -127,   -134,
+      2099,    333,   -602,  -2217,   -743,    346,     74,    216,
+       579,    223,     61,    -30,     57,     94,    224,  -2595,
+      -566,   -851,    246,    314,     65,   2857,    114,   -760,
+        77,   -611,    119,    181,      4,  -2556,    127,    138,
+      -164,   -219,   -116,    157,  -3143,    197,    -98,  -1040,
+       235,   -332,   -424,   -152,   -338,    -33,   -220,    207,
+       254,   5469,   -102,   -390,   -125,   -420,    113,   -233,
+       329,    -34,    109,   -171,    103,     50,     58,     96,
+      -500,  -2317,   -259,   2178,    109,  -2030,    759,   -780,
+       448,    678,   -384,   -271,    213,    334,   -271,     23,
+     -1121,    636,  -1103,   -482,  -3059,  -1200,   1160,    109,
+      -232,    541,   -788,    130,   -166,   -300,    664,    233,
+       -97,    -29,   -286,     33,   1272,   -298,   -382,   -242,
+      -199,     47,    479,    224,  -1761,  -1904,   1780,   1439,
+      -681,  -1973,   -118,    -90,   -148,    247,   -758,   1936,
+       182,   1373,   2346,    120,   -758,   -476,   1789,   1177,
+       611,   -394,    -14,    -39,   -994,   -674,   1049,    -41,
+       836,   -391,    942,  -1040,  -1437,   1376,  -1916,   1129,
+     -1018,   -653,   1284,    -72,   -166,    321,    194,   -142,
+      -151,    -77,    251,   -162,    732,   -790,    107,   -292,
+      -675,  -4248,    -51,    -86,   -299,   -495,    413,   -128,
+      -455,   -105,   -842,    881,   -492,   1241,  -1432,  -1296,
+       -52,   -430,   2533,  -1765,    838,     84,    -24,   -798,
+      -428,   -154,   -658,     37,   -388,   -591,   -931,   -433,
+     -1837,   1363,   -683,   -717,   3115,    104,      0,   1104,
+       208,    148,    404,    101,     18,    217,     58,     49,
+         4,    -49,   -195,    187,   -239,    -21,    294,   -138,
+};
+
+static const int16_t cb4440sl1[] = {
+     -3057,   -853,   3212,   -334,      5,    224,     63,   -250,
+      -345,   -102,   -289,   -115,     75,    -99,    206,     -8,
+        19,     96,   -254,  -2566,    334,   2773,    136,    199,
+     -1076,    347,   -187,    481,    -64,    654,     -9,  -1094,
+       196,     40,    -95,      5,    163,   -135,    253,  -1053,
+       316,   -231,     24,  -2307,   1480,  -2052,    -18,   -459,
+      -550,  -1860,    -15,     98,  -1406,    -66,   -250,     21,
+       497,   -404,    -54,   -228,   2477,   2011,   -145,  -1957,
+      -426,   -906,    608,     15,   1453,    218,    -79,   -636,
+     -1005,   -332,    304,   2338,   1356,     81,  -1201,   -170,
+      -126,  -1177,  -1644,  -1046,     16,    182,   -328,   -347,
+       346,    591,    418,    623,   -110,   -342,   -227,     10,
+     -5055,   -411,    128,   -103,     87,    -28,   -133,    196,
+       333,   1785,   -479,   -442,  -2892,    453,  -2292,    -19,
+      -383,    -44,   -435,   -193,    503,    130,      4,    144,
+      2184,   -245,     -7,    458,     82,    -76,   3052,   -375,
+      1299,    -76,    364,   -145,    372,     36,     59,    -39,
+        48,    385,   -230,   2764,   2956,   -741,   -372,    428,
+      -504,   -220,   -821,    -47,    -49,    609,    -62,     56,
+         6,    216,    376,    519,   -512,     54,   -318,   -183,
+     -4563,    297,    795,   -182,    108,    234,    404,    218,
+      -123,    -17,   -192,    170,    349,    134,    -91,     43,
+      -135,    -24,     -6,    -32,  -6681,     50,   -138,    -89,
+       -18,     15,     24,   -416,    356,    311,     83,   -267,
+        81,    209,   -155,   -368,    396,    358,    232,   4696,
+      -347,    724,    112,     10,    331,    358,    197,     54,
+       824,    646,   -214,    113,  -4425,    184,    -11,    101,
+      -313,    186,    253,    169,     78,     52,    -70,   -108,
+      1669,    -22,    -18,  -2600,    -27,   2806,    288,   -106,
+       506,    176,    616,   -299,     58,    -30,      1,   -220,
+       400,   -177,    874,     70,    -36,   -274,   -139,   1148,
+       372,     40,    236,    505,    619,  -4002,    -95,    -48,
+     -2854,    114,    -69,  -2805,   -401,     -9,    203,  -1011,
+       472,  -1066,    412,   -220,    245,   -183,    -27,     35,
+      -762,    312,   -137,   -292,   -242,    896,    172,   -345,
+       106,  -4490,    506,    569,    -11,   -352,   -108,    334,
+      -165,   2389,   -895,   2761,    467,    201,    150,   -516,
+        39,  -1105,      4,    587,   -152,   -764,   -184,    -15,
+      -137,    -30,    -12,      7,    382,   -461,   1577,   3519,
+      -173,   1370,     80,    499,    344,   -771,    123,    -13,
+       288,    233,    111,  -2472,   3952,    771,    216,   -505,
+      -446,    531,   -230,    103,    -72,     34,     61,    249,
+      -175,    353,     83,     51,    169,    -97,    -60,   7827,
+        95,     75,    -13,    201,    -27,    103,    -11,      1,
+         3,    121,    -73,    -28,      7,   2908,   -209,   -987,
+      -129,   -341,   2840,    889,   -147,   -521,    123,     95,
+      -239,    552,   -738,    279,    -66,      0,     16,    116,
+       -45,    -28,    -43,    -38,  -7627,     30,    -52,   -209,
+       281,    -46,     23,    -24,     56,    -25,    -23,  -2534,
+      -107,    -46,    -93,    -49,    238,    -25,     96,   -356,
+      3483,   -459,   -414,    205,    102,    202,   -150,   -116,
+      1785,   1399,    793,    543,    685,  -2837,    255,    362,
+       -96,    410,    926,   1068,    416,    558,   -169,    246,
+       138,   2136,     39,    -96,   -605,    279,   -130,  -2741,
+     -1101,   -935,    -20,   -227,    453,   1261,    103,    275,
+       358,     43,    197,    -23,   -251,    322,    -22,    233,
+      2560,   -214,      2,   -101,    645,   2864,    287,   -479,
+       904,    -65,     73,    224,   2418,    -95,    428,   -678,
+      -278,     71,   -545,   -571,   -566,   -181,   -212,  -2947,
+       222,    780,   -365,    124,  -2703,   -198,    -69,   -246,
+     -3056,   -184,   -598,    -75,   -145,   -690,    380,    194,
+       485,    214,   -484,     54,    163,    363,   -924,   1684,
+       201,     34,    236,   -539,   2374,   -150,   -490,  -1313,
+       -61,    317,   2123,    315,   -551,    -26,   -328,    207,
+       253,  -3015,    166,    109,   -662,   2466,   -157,   -740,
+       751,    254,   -788,   -369,     -6,    100,   -211,    107,
+      -309,    -39,    -47,    279,   -126,    -91,     97,   -705,
+       235,   -231,    182,    283,  -5097,    -68,    285,     49,
+        50,    637,    111,     39,   -386,    923,    223,    115,
+      1638,   1214,   -640,  -2168,    482,  -2228,    857,    172,
+        15,  -2207,    -89,    335,    -18,    295,    718,   -956,
+        26,    604,   -436,   2856,  -1131,     98,   -754,    243,
+         9,     29,  -4028,  -1725,  -1741,    432,   -211,    -60,
+      -535,    201,   -273,    111,    444,    607,   -250,    122,
+        98,    159,     97,    281,   3071,   -412,  -2849,   -721,
+       -14,    960,    -43,    794,   -427,    297,    478,    379,
+       -47,    -22,     69,    -60,    -30,   -732,   2456,    170,
+       142,      6,   2520,   -644,   -201,    -16,   1602,    -20,
+      -293,    542,   -451,   -167,     -9,     14,   1052,   2707,
+      2980,   -117,    479,   -202,    -92,     36,    904,    -66,
+     -1088,    -31,     75,    -62,   -110,    -29,    112,   -102,
+      5217,    -85,     14,   -191,   -202,   -175,    -71,    182,
+      -231,    275,    144,     -1,   -202,    -13,    -29,    -19,
+        70,     39,     46,     56,  -7608,    -53,   -104,    -61,
+        44,     23,      1,   -157,     42,     12,     38,     37,
+       331,   -609,  -2516,   -174,  -2491,    258,   -256,   -926,
+       983,    100,     83,    173,   -965,    650,   -304,    -97,
+        98,   -166,    534,   2570,   -611,    493,    103,    -98,
+       148,   3081,   -131,    285,     13,   -367,    205,    -53,
+        41,     29,   -154,  -2657,    -51,   -312,    134,     50,
+     -1514,    634,    411,  -2885,   -391,    365,   -373,    -54,
+       -74,   -151,     80,    152,    -91,    -64,   -209,   1134,
+     -2921,    316,   -951,   1124,    713,      2,  -2212,     31,
+       164,   -260,    103,     36,    229,    111,    -23,    -65,
+       -37,   -220,   -108,    -30,     86,     17,     87,    205,
+       163,     63,  -5763,    254,    178,    -18,   1760,   -380,
+      1453,  -3151,    710,    106,     66,    387,    235,    463,
+      -295,    688,   -124,    322,   -193,     82,   1012,  -2033,
+      -656,   1362,    805,   -747,   2527,    470,     43,  -1001,
+       100,    -83,    161,     74,  -1128,   -307,    -82,   -197,
+     -5470,    226,   -327,    137,   -131,    471,   -432,    -16,
+       243,    224,    168,   -164,    -58,    125,     23,     -2,
+     -2752,    268,    -92,   -466,   2876,    874,    182,    540,
+      -407,   -338,   -396,    562,   -376,    536,   -225,    160,
+        44,  -1501,   -246,  -1062,   -378,    446,  -2448,   -124,
+       499,  -2297,   -353,   -637,    395,    598,   -747,    418,
+      -495,      5,  -1014,   2138,    289,    -75,    301,    944,
+        66,   -457,   -459,   -253,     -2,    678,    367,    116,
+     -2901,    436,   -239,   -303,   -973,    384,  -2574,      6,
+      -225,   -164,   -440,    627,    388,  -3074,   -263,    156,
+      -805,    381,     -9,   -112,  -1481,    536,   -711,   3770,
+      -496,    908,    483,    474,    298,   -424,   -793,   -203,
+      -334,    134,    -91,    208,    -73,   5440,   -316,   -304,
+       249,     -1,    -98,   -214,    190,    242,    -57,    -38,
+       244,   -219,     30,   -224,     66,    -30,     22,     24,
+        24,   -109,  -7594,   -115,     90,   -147,    -83,     21,
+      -257,    -52,    134,    -49,     92,   -117,     30,     -8,
+      -636,   1551,   2207,    -66,  -1962,    212,    567,    969,
+     -1595,   -562,    355,   -467,   -861,    937,   -148,     15,
+       -68,  -1516,  -2118,   1477,    777,   1458,    976,    522,
+       325,    957,   -130,   -132,   -918,    448,   1088,    102,
+       142,   -644,   -284,    687,   -665,   -132,  -1870,   1387,
+       733,    -84,    920,   -508,     53,  -2183,    254,    565,
+      2056,     97,     57,    219,    688,   -344,    659,   2033,
+       963,  -1717,   -290,   -934,  -2119,     57,  -1452,     24,
+      -639,   -739,   -232,    170,     28,    359,   -312,    310,
+      -103,  -1067,   -953,   1081,   -857,   1926,   1364,  -1719,
+      -863,   1832,    786,     55,    166,    383,  -1373,   -347,
+      1710,   -908,     91,   1257,   2013,   -592,  -1337,   1431,
+       -90,    617,    549,   -356,    -68,    134,    -48,   -133,
+      -176,    -18,    -65,     23,     84,    -23,    -36,     -4,
+       230,    297,   -204,   -150,     86,  -4965,    742,     40,
+        32,  -1070,    149,     38,    302,   -329,   -386,    -57,
+        45,  -1622,   1425,   1817,   1568,   2202,      7,  -1192,
+      -201,    -42,    -62,   -170,    -32,   -117,    -38,    229,
+        44,   -226,    155,     70,    747,    259,   -261,   -120,
+};
+
+static const int16_t cb4440ss0[] = {
+     -3021,   2048,   -450,   1147,   1487,   -796,   -657,    459,
+       609,     63,   -153,  -1174,   -144,     37,   -176,   -160,
+        43,    -31,  -2577,     88,   -797,   1179,   -707,   3154,
+      -543,    875,    116,    -40,   -150,    326,    293,   -112,
+       -73,    -34,     61,      8,  -2251,  -1551,  -2507,      6,
+       -52,     -5,   -323,   -313,   1076,    920,   1116,  -1100,
+      1103,    310,   -144,    904,    149,    -59,    636,  -1508,
+      -378,    381,   -917,   -868,   1388,  -1225,    -68,   1491,
+       685,   -220,   3253,     48,   -504,    192,    114,    -11,
+     -1718,   -916,    660,   -240,    767,  -1061,    332,    591,
+      -477,   -278,     25,  -1485,     55,    216,  -3238,    -19,
+      -320,   -148,    273,   -876,     22,   -529,   3263,  -2535,
+      -756,   -133,   -481,  -1024,     34,    418,   -415,    412,
+       -92,    -90,    161,    -49,  -1699,  -2737,   2923,   -243,
+       122,     87,    984,   -377,    -37,    128,    350,   -444,
+       -98,    -52,     14,    -14,    -86,    255,   1997,  -1239,
+        42,    247,    -15,     16,    405,    302,    -17,     84,
+     -4033,    -12,    254,   -365,   -205,   -162,    329,     31,
+     -1158,   -210,   -376,   3958,  -1601,  -1128,    737,    731,
+       300,   -785,   -777,   -403,    463,   -226,   -109,   -277,
+       -70,    -53,   -856,   -785,   -997,     71,   5565,    317,
+       447,   -279,   -357,    254,     93,    -47,   -206,    133,
+        88,    272,      7,     44,   2229,   1666,    234,    519,
+     -1996,  -1195,    549,    449,    174,  -1010,    622,    425,
+      2288,     -9,   -390,    612,    -40,     32,  -1867,   -673,
+       -70,  -1174,    106,    134,    354,     61,   -144,   -290,
+        82,   -604,    202,  -3954,    248,    -76,      7,    224,
+     -1844,     99,   -146,    206,   -335,    243,     25,     60,
+       186,    117,     67,   -137,    119,     46,   4563,     45,
+       -46,     -2,    874,    533,    216,    -38,    185,   -540,
+      -191,   -163,   -126,   -108,   -184,    193,    -39,  -4768,
+       111,    -89,    -61,     17,   1064,   1678,    894,   4334,
+       139,   -892,    317,   -351,    417,    -87,    -22,    195,
+        20,    140,    234,   -197,   -268,     -5,  -1618,   -756,
+      -119,  -1749,   -704,   -943,    421,  -3488,    871,   -468,
+       656,    266,    -79,    325,   -303,     45,     -3,    -31,
+      1140,   -707,  -1578,  -1434,    290,    327,  -1365,  -2913,
+      1048,     38,   -136,   -871,   -572,    -30,    186,    343,
+       -30,   -157,   1301,   1913,   -515,   -842,   -723,    -84,
+      -340,    270,   -918,   3213,  -1530,   -394,   -184,    -60,
+      -391,    -27,   -110,     84,    104,    419,   1201,   -810,
+      1546,     39,   -914,   -334,  -4257,    427,    -95,   -426,
+       -94,    256,   -148,    246,    -80,      9,   -462,  -1125,
+       644,   3541,   -140,   2346,   1045,   -335,   -867,    809,
+       432,    386,     -6,    159,     70,    -10,    218,     43,
+     -2229,   -607,    537,   -924,  -3038,   -943,   -968,   1261,
+        28,    197,   -285,     61,    137,     69,     -2,   -251,
+       111,    -19,   -314,   2064,    960,   1529,   1056,    926,
+      -319,  -1617,   1305,   1473,   -867,    684,   1357,   -834,
+       -66,    477,     74,    -15,  -1769,   1925,  -2448,  -1777,
+      -507,    264,  -1740,    176,   -518,    -58,     32,   -108,
+       165,    -68,    189,     35,     40,    -85,  -1152,    255,
+        36,  -1922,   1500,   1415,    841,    -92,   3305,   -110,
+         3,   -219,    167,    573,    219,    310,     27,    195,
+       359,   -244,    538,  -2042,    355,    656,     51,   -199,
+      -204,  -3611,   -396,    839,    743,   -241,    -80,   -210,
+      -101,     28,  -1399,   1062,   -955,     54,   -630,   -178,
+      -376,    212,    237,   -219,     47,    805,    216,     26,
+     -4334,    455,      4,      4,  -1587,     95,   1186,  -3101,
+      -140,   -862,    916,   2063,    211,     96,    337,   -185,
+      -195,    424,   1207,    -31,   -162,    206,   2485,    -46,
+      -451,  -1778,    -40,    144,   -155,   2884,    803,    396,
+      1196,   -635,    297,    -76,   -121,   -162,   -206,   -149,
+     -2204,   1035,    232,   -815,    -49,   1006,    553,   -407,
+       161,   3650,   -264,    370,   -418,    -28,    141,   -177,
+      -113,    -90,   -315,    626,     62,   1392,  -1815,    336,
+     -1276,   -402,    486,  -1060,  -1848,   2610,    826,    485,
+      -250,     39,    208,     14,   2555,   2869,   -813,  -2074,
+       337,    601,    855,   -655,    566,   -707,    189,    -77,
+       137,   -510,   -282,     79,     42,     73,     62,    650,
+     -4732,   -486,    354,    420,    828,   -645,   -492,    388,
+       753,     18,      2,    766,   -212,    126,    -43,     45,
+       447,   -283,    607,    251,   -166,    -10,     48,  -5850,
+      -251,    128,   -205,    -95,     90,     90,     67,     24,
+       -50,    -48,   -167,  -3231,  -2926,   1831,    199,    484,
+       169,   -614,   -135,   -374,   -418,   -239,    -89,   -121,
+        45,     75,    -11,     16,  -1058,    354,   1633,    589,
+     -1223,   1218,    842,  -1146,   2186,    374,   -363,    216,
+     -2153,   -429,    429,   -597,     93,    148,   1849,   -797,
+      -162,     31,   -325,    343,   -323,    161,   -373,    684,
+      -367,   -452,  -4306,    -88,     28,    -56,    -59,     43,
+       -49,  -1998,   -956,   1331,  -4214,   -129,     30,     79,
+       -90,   -129,    109,    130,   -160,    409,    105,    298,
+       208,    178,   1724,    731,    773,    128,    817,   -425,
+     -4046,    180,   -782,   -116,    191,   -259,    181,    -31,
+       162,     43,    -41,    -69,   1463,  -1769,     -2,   -442,
+      -636,   1495,   -218,   -123,    -58,   3616,    454,   -475,
+       247,   -383,    304,    185,    155,     40,   1104,   1046,
+        -8,   -736,  -1155,   -115,   3925,   -257,    -35,   -599,
+      -437,   -135,   -256,     55,    214,    -88,    215,    -57,
+     -1097,    183,   -501,   -608,   -135,    148,    405,    295,
+        96,   -513,   1013,   4350,   -162,    -61,    427,    315,
+        24,    -77,  -1278,   -167,  -1774,   -133,   -323,  -4339,
+       732,    597,    -30,   -103,     79,   -241,    177,   -388,
+         7,     44,    175,   -143,   5030,    277,     58,     42,
+      -222,   -133,   -319,      6,    240,    217,   -238,   -198,
+       218,    -43,    439,     49,     37,    106,   1123,   2196,
+       158,    171,    458,   -932,   -435,  -2783,   -300,    444,
+      2317,   -146,   -339,   -162,    157,   -216,      1,     66,
+       987,   -190,   -728,  -3188,  -3167,    378,     -1,    158,
+       459,     78,    -42,    386,   -133,    155,    294,    359,
+       -29,     78,   1763,    780,   1019,   -330,    179,    -51,
+      -393,    338,   4422,   -296,   -392,    170,      2,     52,
+       253,    150,   -191,    139,   -371,    161,  -2202,    156,
+        37,  -1004,   -384,   -466,     23,    183,  -3701,     97,
+     -1293,   -355,    -83,    -63,    -26,     69,  -1817,    641,
+      2996,    -16,   2011,   -406,   -647,   -652,    332,    788,
+       484,    918,   -440,   1246,    165,     52,   -260,     31,
+      -255,  -7237,     14,     90,   -135,    122,     14,    154,
+         5,    -78,    111,   -254,    154,    -23,    -24,    -83,
+        -9,     49,   -426,   1657,     99,    -36,   -191,   2625,
+       655,    -20,  -2723,   -977,   -222,    -48,    155,     41,
+        20,    194,    -73,    -26,  -1206,  -3517,   -471,   -815,
+     -1144,   -371,   1353,  -1069,  -1238,    829,   -227,    487,
+      -297,   -101,    914,    100,    -17,    115,   -806,   -798,
+       585,   1097,     -1,   -792,    818,     29,   -256,   -417,
+       942,     68,  -4165,     34,   -408,   -252,     55,    -77,
+       246,   2055,     -4,   -313,   -661,   -836,    559,   -393,
+      2043,    153,    286,  -2700,     98,   -177,   1201,     99,
+       308,    -73,   1441,  -3902,    730,  -1610,    886,   -599,
+      -126,    473,     43,   -252,     45,     95,   -291,    101,
+      -307,    259,   -149,     26,   -510,    498,   1403,    -78,
+     -1039,  -2551,    773,  -1176,  -1525,   -405,   -259,   -283,
+       398,   2080,   -199,     62,    239,    -26,    960,    582,
+      2516,    799,  -2127,    325,   -253,  -1652,   -965,   1413,
+         8,   -119,    396,   -342,    277,    541,    186,   -142,
+      1210,   -732,    798,    -47,   -557,    -12,     63,    537,
+       148,   -128,    328,    290,    203,    361,   -328,    -64,
+      4004,    197,   -640,    996,    -93,  -2314,     76,   -914,
+      1437,   -964,  -1735,    984,   -578,   1389,  -1025,    -66,
+      -120,  -1211,    -32,      5,  -1215,    771,   1621,   -934,
+      -984,    148,  -1592,   -446,     19,   -976,  -1709,  -1113,
+      -218,    191,   -279,   2183,     10,    -37,   -842,  -1582,
+       -92,    558,    227,   -702,   -365,   -576,   -100,    670,
+      -305,    285,     48,   -329,    253,   3878,    156,     70,
+     -1008,    641,   1541,   -234,   1440,    421,   1088,    735,
+      -206,    -83,    460,   -139,    107,  -1160,     -6,   2087,
+      1894,   -117,    962,    113,   -990,     93,    -29,    579,
+      1217,    -52,   -342,   -451,    670,    202,  -1070,    837,
+      -132,   3507,    -59,   -114,   -691,    208,  -1170,   1089,
+       305,   -200,    603,  -1301,   -942,  -1631,   1291,  -2727,
+       414,     80,    815,   -443,     54,    -34,  -1141,   1301,
+     -1199,    372,    102,   -257,     70,    450,    -55,     80,
+      -227,    218,    264,    739,    -52,   -200,   3873,     83,
+};
+
+static const int16_t cb4440ss1[] = {
+      6875,   -104,    -66,    161,     57,     24,     -4,     76,
+      -122,   -100,     31,    188,   -119,    -50,   -244,     49,
+         1,   -100,    555,    253,    433,    633,   -163,  -5345,
+      -170,   -217,    -49,    -29,    331,    633,    -87,    -46,
+       -29,     44,   -174,    -74,   2188,    434,    660,   -593,
+      1548,    379,   1443,   1676,    -63,  -2125,    246,    534,
+      -463,    872,   -169,    -12,     33,    211,   -409,    408,
+      1514,   -189,   -277,    391,   -361,    -35,    145,   -362,
+     -4669,    212,    -97,    -65,    387,    -81,     70,     36,
+       448,    303,    332,  -1077,   -258,  -1353,   1185,    -50,
+       -12,    -74,  -2101,   2429,   1817,   -939,    393,    169,
+       -22,    -36,   1219,   3237,    816,    452,   1807,   -646,
+       407,   -447,  -1778,   -370,   -528,   -127,    104,    416,
+      -121,   -134,    -62,     20,   1751,   -640,   -222,    950,
+      1603,    555,      9,    219,  -1272,   2724,   1004,   1237,
+      -395,    356,   -453,    -98,    -24,     80,  -1621,    474,
+     -1947,   -237,  -1059,  -2091,    780,   1211,    939,    268,
+      -412,   1923,   -419,    851,    230,    567,    143,     48,
+      1506,   2228,  -1226,   -453,    246,    469,    540,   -538,
+       -96,    977,    508,    105,  -3150,   -142,    -37,    395,
+         9,    -38,      1,   -135,   -391,   1702,   -179,  -1566,
+     -3181,  -1679,    203,   -151,    387,    250,    563,    203,
+       443,   -168,     82,     61,   1604,  -1878,    229,    -82,
+       208,   2965,   1093,    251,   1592,   -432,   -532,    153,
+       407,    157,    191,   -216,     52,    -58,    935,  -2161,
+      -409,   -513,    977,   -113,   3247,  -1207,   -743,  -1178,
+       136,    206,    184,   -885,    -64,     16,    -23,    -24,
+       731,   1769,   -941,   1543,  -2386,   -669,   -958,    233,
+       105,  -1124,    948,     97,  -1949,     59,   -152,    -65,
+       114,     82,    387,  -1908,   -492,    129,   -624,     93,
+       658,   -753,   1032,   2480,  -1776,    360,    -38,   1924,
+       168,    -12,    -10,   -128,  -1712,   -446,    939,    465,
+       605,   -586,   -299,   -393,   3878,    111,   -379,    146,
+       186,    -50,   -279,    -30,     -3,     35,  -1941,    360,
+       -79,   -111,  -4287,     -6,    671,   -214,   -792,    277,
+        77,     58,      8,     16,    133,    161,     21,     33,
+      1535,   -296,  -2668,  -3198,    -28,   -386,   1156,    144,
+      -201,    256,   -411,    298,     67,    670,     11,   -227,
+        -4,   -104,     12,  -1000,   1192,    860,    813,    360,
+        25,     93,    792,   -350,     81,   4046,   -178,    122,
+       332,     28,   -112,     -8,    288,    539,    -17,    -63,
+         8,    231,     55,   -514,    105,   -344,    252,   -153,
+        59,    -10,    -21,     51,   6793,     45,    259,    384,
+       209,  -2010,    311,   -769,  -1957,   2791,   -463,   -293,
+      -218,   1026,    897,   -798,     47,   -525,     31,    -42,
+      2018,  -2767,   1658,    685,  -1947,     46,  -1468,    340,
+      -272,    318,     21,   -421,   -396,    244,    -51,    290,
+        45,      3,  -1530,   1359,  -3681,   1487,  -1689,    209,
+       438,   -785,   -220,      2,    -55,   -483,    -35,     40,
+         6,    189,   -200,      2,  -2026,  -1747,    838,   -880,
+      1128,  -3108,    184,   -671,   -261,      8,    296,   -130,
+       -78,   -268,   -100,     18,   -105,     -9,    448,   3184,
+      -570,    656,   -376,   -969,   1682,   2635,   -277,    577,
+       217,    281,    219,   -351,     31,     64,    101,     82,
+       957,  -1885,    774,  -3536,   -168,   -431,   -106,   -479,
+      1041,   -103,    774,   -142,    894,   -724,    -94,   -766,
+       -58,    112,   2028,    566,   -346,   -139,  -2671,  -1907,
+      1039,    189,    -33,   1690,    263,   -514,   -225,   -237,
+       145,   -319,     38,    116,   2891,    -77,  -2065,   2559,
+      -327,   -763,     86,   -172,   -283,   -147,    137,    245,
+      -333,    220,     92,    194,   -176,    105,   3108,    329,
+      -372,  -1188,    670,    773,   -235,     34,   -146,    876,
+      -259,  -1580,    876,    105,    582,    259,    -63,    -99,
+     -1558,   1122,  -1541,   -438,    227,   1221,  -1297,   -746,
+      2698,    -29,   1169,    995,     -2,    201,    392,   -405,
+       -22,    -36,    757,  -4039,    725,   1960,   1478,   -107,
+        67,   -367,    -97,    -88,    154,    -80,      0,   -265,
+      -163,     14,   -109,     33,    597,    115,    543,    468,
+      -757,    826,    509,   -176,   -305,  -4959,   -118,   -464,
+      -421,    -72,      1,   -187,    123,    -88,  -1086,     26,
+       368,    610,   3394,   -337,    364,   2594,    491,    759,
+      -309,    395,    152,    338,    249,    303,   -122,     63,
+      1019,   -864,   1546,    196,     75,   -633,    -93,   -631,
+       777,    -74,   1235,   -745,    377,   3113,   -174,   -282,
+       -24,     89,   -920,   2124,    620,    566,   1290,   2977,
+      1180,    278,    188,    750,    981,   -357,     80,     69,
+        77,   -151,    150,    -15,    834,   -893,    818,   1655,
+      -500,    237,    133,    243,    405,    239,     16,   -152,
+       -70,  -3692,   -110,    145,     58,    -57,  -2527,   3072,
+      2226,    218,   -824,    384,    -96,    119,   -228,   -194,
+       136,    111,   -251,   -109,   -179,    -34,    143,    109,
+      1157,   -216,  -1429,   -702,    323,  -1199,    -60,    632,
+      -585,   -340,   1040,    471,    -32,   -380,   3432,    455,
+      -138,    -39,  -2416,    652,   -253,    145,    281,    393,
+      -671,   2841,  -1616,    -46,   -385,  -1417,   -273,   -168,
+       318,   -263,     -2,    -69,   -638,   -137,  -2668,   -359,
+       -86,     79,   -777,   -404,   -560,  -3533,    122,   -113,
+       617,    497,    117,   -268,    110,     73,    752,  -1105,
+      -521,    762,    695,   -587,   -147,  -1235,   1866,  -2250,
+      -671,   -511,  -2178,   -820,   -619,    162,    -37,    102,
+      -342,   -278,   6837,   -278,    185,     10,    361,    -52,
+      -171,    246,    184,   -175,     19,    166,    -48,    -41,
+        92,   -152,  -1227,   -983,  -3985,   -703,   1143,    204,
+      -523,   1053,   -623,   1002,    231,     53,   -277,   -409,
+       -67,    -56,    -90,    -47,    448,    754,    554,    972,
+       505,   -331,   4946,   -193,     89,    530,    -24,   -172,
+       254,    244,    140,    -10,     40,    -77,   1655,   -438,
+     -2776,     51,   -553,    592,  -2902,    280,    804,    776,
+       131,     69,   -207,    131,      7,    209,     93,    -19,
+     -1148,   -733,   2674,  -1628,  -1243,   -506,  -2346,   -857,
+     -1028,    666,    365,   -353,    105,    120,    210,    -85,
+        37,    -40,   1027,     11,   1234,     -5,  -1976,    515,
+       289,   3815,   -142,   -188,   -248,   -273,   -265,    593,
+       205,    164,    -65,     70,   -992,   1586,   2130,    779,
+        92,  -3067,    421,      1,   1172,    496,   -917,   -760,
+       169,    -64,     14,    -40,   -247,    -95,   1769,   -145,
+       712,   -794,   -571,    240,  -1774,    -38,   -129,   -836,
+      3372,    887,   -451,     73,   -107,    182,    100,     14,
+      -703,   2559,    490,   -839,   -333,    134,    804,  -3549,
+        50,   -199,   -215,   -370,    453,    -86,    151,    -98,
+       -58,    128,  -2624,  -1507,  -1623,  -2186,    -89,    -55,
+      -472,   -667,      2,   -439,  -1453,   -262,    565,     56,
+      -118,    288,    -56,     87,   -398,    729,     40,  -6015,
+       219,   -212,    287,   -250,   -211,    -29,    -61,    -55,
+      -120,    -92,     30,    129,   -122,    111,   2037,   1260,
+       943,   -252,    -13,   -794,  -2570,  -1117,    297,    374,
+     -1629,     -1,   -407,   -597,   -324,   -179,    408,     58,
+      -902,  -1672,    611,   -198,    -61,    103,    366,    915,
+       811,   -280,   -401,  -3849,   -111,    221,    353,    232,
+         4,    -18,    673,   1792,  -2350,    132,   1979,  -2318,
+      -417,   -689,    326,    768,   -377,   -522,    373,   -389,
+      -105,   -103,     33,    -48,   1497,   1125,   1893,  -2744,
+     -1219,    921,    472,   -165,   -438,   -129,   -682,   -783,
+      -685,    167,   -715,    156,     64,     61,   1147,   -892,
+       -72,    579,   1191,  -2759,   1831,   1895,    663,    816,
+       -98,    -61,   -223,   -366,   -429,     31,   -129,   -121,
+      -255,   1804,    138,    180,  -1063,    598,    763,    720,
+       385,   -526,    143,     80,    168,    976,   -714,    236,
+     -3204,     93,    874,    238,   -359,   1595,    191,    568,
+      -182,     20,   -608,   -288,    602,   -224,   3874,   -308,
+       -70,   -826,   -109,    -42,   -882,  -1421,  -1603,    625,
+     -1206,     31,    782,   -106,   -700,   -246,   -571,   -124,
+      -848,   -390,   -523,  -2903,     -9,     39,   -109,   -199,
+       497,    -11,    377,      5,     25,   -115,    -61,    283,
+        27,   -131,   -193,    280,    178,  -5439,     44,    -52,
+     -1210,   -617,   -162,  -1097,     -3,    748,    -45,  -1197,
+     -1058,    909,   1607,    693,     42,   -749,  -3001,    407,
+       -62,     45,    214,   -312,  -1054,    498,   1291,   1189,
+     -1268,   1083,   -757,   -319,  -2796,   -716,    310,   1583,
+      -608,    319,    -84,   -119,  -1415,   -602,    628,    463,
+     -1213,   -794,   -474,   2682,    931,    240,   2491,     76,
+      -234,   -161,   -690,    359,     28,    -19,   -774,  -1023,
+       738,    675,    248,     52,   -348,   -545,  -2715,   -599,
+      -252,    660,   -387,   -104,   2316,    456,    -90,    100,
+};
+
+static const int16_t cb4440sm0[] = {
+     -6448,    -59,    298,   -659,    -59,    329,   -569,    397,
+      -224,    128,   -216,    153,   -100,    319,    -53,    -90,
+        50,   3313,      4,   -215,    405,   -256,     78,   2890,
+      -187,   -969,    195,  -1022,   -119,    214,    254,   -360,
+      -222,     39,   2139,     91,   -290,    529,    -73,    -16,
+      -318,    128,   -348,    565,  -1190,    202,   -185,   -234,
+      3498,     48,     68,  -1917,   1694,    212,   -477,    239,
+     -3301,   -489,    424,    418,    -82,    -61,    599,   1530,
+      -200,   -252,    162,   -243,     43,   -534,  -2695,    255,
+       317,    489,    279,   3337,    246,   -349,   -149,   -128,
+      -146,    256,   -455,    137,    -75,    836,    209,   -349,
+      3494,    255,  -1948,   -732,    367,   1373,   -211,    608,
+       345,    -17,     43,    102,     19,   -219,    173,  -2361,
+       130,   -862,    637,   -103,   -589,    219,  -1261,   -238,
+     -2528,   1643,  -1587,   -690,   -166,      7,    -57,   1221,
+       326,    103,   -830,    608,    196,  -3705,   1103,    568,
+     -1602,    543,   -153,   -416,     74,    185,    156,     34,
+      1329,   -798,   -214,   -515,    121,   -797,    749,    346,
+       629,   -609,   -877,    -60,    184,   -157,    250,    193,
+      4385,    369,   -181,   -191,   -308,   -314,   -395,   -173,
+       -88,   -388,    -43,     46,      9,   -167,    189,   -192,
+      6086,   -226,  -1795,    126,   -941,   -423,    397,    380,
+       461,    319,    364,   -194,    433,   1214,  -3715,   -274,
+         9,   -327,    212,   -375,    130,   -917,    -63,   1120,
+      -651,   -211,    149,  -1128,    265,    -73,  -4630,    493,
+       -83,    -20,   -314,    -91,    910,   -109,     -3,   -417,
+      -109,    374,    357,  -2773,    253,   -234,   -306,  -3060,
+      -762,     53,    476,   -299,    -89,  -2440,   -658,    -83,
+      -854,   3770,    374,    552,    450,     51,    346,    887,
+      -463,    189,    254,    182,     15,    -37,  -3263,   2594,
+      -647,    -83,    404,    770,    691,   -654,   -301,     81,
+       -13,    742,    371,     54,     31,    -83,    -59,   4196,
+       653,    256,  -1075,   -539,   1084,  -1077,   1238,    259,
+        20,   -191,    854,    179,    -47,  -1025,   -189,    281,
+      2556,   1765,    106,    -79,    320,  -3066,    228,   -500,
+         1,   -183,    -46,    220,   -233,    -50,    -98,   -261,
+       -84,    -25,  -4378,   -428,  -1395,   -582,   -619,    443,
+     -1456,    375,    144,    -32,    356,   -454,     28,    136,
+         5,    247,  -1057,    709,   -362,    293,   3084,    545,
+     -2804,   -625,     16,   -228,   -238,    164,   -201,   -114,
+      -149,     58,    -74,    203,    271,    462,   1037,    159,
+     -1652,   -591,   -846,   -166,  -3272,    710,    773,    824,
+     -1138,    630,    -14,    209,    348,   1476,    322,   -371,
+       241,   4133,   -877,   -476,   -391,    602,   1259,  -1204,
+       352,     90,   -473,     43,   -152,   -439,   -131,   -217,
+     -1559,  -5029,   -186,   -239,    -44,    750,     33,   -167,
+      -211,    -67,    -91,   -143,    124,     32,    -16,   8192,
+        68,   -102,    163,    -31,    458,     38,    249,     21,
+       157,    -63,     36,     49,    -22,     89,      9,    153,
+        46,     60,   -146,    -13,  -7506,   -104,    101,   -141,
+        25,    165,    -84,    219,     53,   -182,    -94,     46,
+     -1314,   -371,   -298,   -527,      6,  -1955,     52,   -714,
+      -461,    174,   1450,   -298,    107,   2965,    250,    -65,
+        46,   -171,    296,   -785,   -784,     35,     36,     29,
+       915,   -891,   -391,    168,    509,   3763,  -1267,   -138,
+       132,    424,    -53,   -669,  -1491,   -927,    712,   -638,
+      -440,   -299,    522,   1593,    445,   3234,    547,    498,
+       440,    145,   -135,   -188,   -296,   1080,    468,     77,
+       176,   -315,    221,   4784,   -666,    274,    762,    -42,
+       218,    -86,   -273,    116,    814,    -21,    402,   -266,
+      -392,   -425,   1126,    -68,    142,    357,   5143,    363,
+      -224,   -198,    115,   -221,   -262,   -736,  -2774,   -196,
+      -208,   -613,    163,    696,    789,    132,    114,    121,
+     -3138,    164,    172,   -189,    232,     53,    310,    -50,
+      -407,   1207,   -474,    249,   -806,     21,     20,     72,
+      -534,    101,    -47,   -223,  -4568,   -128,    -29,   -910,
+      -254,    105,   3163,   -119,   -135,   1745,   1744,   1105,
+       291,   -333,   -278,   -441,    660,    141,   -291,    314,
+       149,    142,   -121,  -7878,   -240,   -204,    189,    376,
+         3,   -129,     59,     46,    170,     82,   -150,    -34,
+        67,   -110,    635,    148,    256,  -2939,    157,   -509,
+      1439,  -2470,    794,   -298,    407,    980,    805,    349,
+       208,    -35,   1009,   1180,   -114,    776,   -339,   -776,
+       250,   1951,   -557,    172,   -395,    795,  -3075,   -348,
+      -106,    122,    -47,     -9,     55,     40,   3002,    421,
+       538,     -1,   -277,  -3062,    -15,    168,    461,    521,
+      -525,    413,   -196,    159,  -3314,    -85,    983,    565,
+     -3113,     38,     79,   -172,     20,   -228,   -520,    346,
+        47,    485,   -177,     51,    175,    444,   3475,  -3416,
+       -81,    118,    264,   -162,     20,   -192,   -219,   -111,
+       -57,   -225,    159,   -218,    117,    -28,   -150,  -1100,
+      -681,    444,    -54,    -11,  -4669,   -216,  -1151,    858,
+       168,    -39,     52,    387,     74,    -39,   -154,   2767,
+       307,   -132,    531,    175,    906,     14,   -129,     49,
+     -3389,    476,   -127,   -329,    479,    118,    -85,    209,
+         4,    227,    154,     -2,   -238,    263,    -24,    553,
+      -231,     78,      2,   -183,     31,   5933,    117,     86,
+       386,    359,    153,    101,   -784,   -553,    -13,    256,
+      -347,  -1311,   -936,    -64,   1718,   -444,    168,   -590,
+     -3252,   -194,   -243,   -269,   2096,   -994,  -1081,    309,
+      1003,    290,    -66,    306,  -3239,    -25,    700,    365,
+      -770,    144,      4,    259,   -185,   1493,   -158,    726,
+     -3180,  -1683,   -119,     45,   -493,   -205,  -1728,  -1226,
+      -235,    -87,    -88,    -87,   1966,      8,    142,    496,
+       239,    828,     30,   -517,   3150,   2266,    402,   -315,
+        74,   -312,   -414,    -16,    458,    381,    376,   1287,
+      1093,   -410,   -967,     80,    382,   -106,   4419,    445,
+       293,   -283,    282,    324,    -80,    -25,    115,  -1667,
+      -756,   1893,  -2772,    395,      3,   -349,    138,   1094,
+       406,    432,    214,  -1328,    632,   -132,   -100,    135,
+      1627,   1062,   1026,  -1341,     24,  -3352,   -173,   1265,
+       861,   -821,    -87,   -367,    278,    151,   -101,    -32,
+       161,    387,   5778,   -564,    492,     83,    324,     29,
+      -423,     91,   -132,    190,   -310,   -457,    -62,    -99,
+       171,   -214,   -159,  -2500,   -693,  -1538,   -311,   -784,
+     -2422,   -498,   1781,    342,   -467,    -78,    466,   -252,
+       241,    197,    186,  -1039,   -190,    346,  -1881,   -240,
+       -65,   1438,   1001,  -3009,    -52,    221,   -490,   1224,
+       -63,    -39,     53,    169,    130,     86,    -56,    -90,
+       116,      4,   7098,     -5,     61,   -172,    -65,    160,
+       -94,    -30,   -111,    270,   -653,    521,   -426,   1084,
+     -1169,  -1158,    584,  -2499,   2494,   -321,    695,    823,
+      -429,     35,    529,   -280,    -45,   -286,   2997,    207,
+      -633,  -2207,   1708,   -298,   -413,    673,  -1017,    292,
+       493,     76,   -136,   -365,    -65,    266,    852,    512,
+       791,   -129,   1364,  -1065,   1371,    383,   -524,    505,
+       943,    147,    229,     39,  -2969,     70,   -295,     66,
+      2759,    -16,   -435,   -474,  -1058,    762,     54,   -257,
+       560,  -3167,   -572,   -418,   -478,    370,     72,    -20,
+       296,     54,  -2683,    550,    -15,   -155,   2146,   -143,
+     -1144,    463,   -117,  -1690,  -1917,     42,    249,   -278,
+      -319,   -513,    544,  -2033,   -317,  -1955,  -2646,   1345,
+       759,    268,    207,   1243,    256,    -32,    -45,   -750,
+      -211,   -184,   2397,    473,   2572,   -489,    260,    389,
+      -237,    602,   -463,    569,   1673,   -176,   -227,    964,
+       203,    130,   -269,   -190,   1339,   -978,    973,   1986,
+      1145,   1258,    272,   1779,   -436,  -1306,    652,    807,
+       574,   1401,     53,   -183,   1612,   -828,  -3094,    -82,
+      1061,   1042,   -200,   -891,   -126,    181,  -1324,    549,
+       555,     -4,   -868,     79,    157,  -1533,     18,    230,
+     -1096,   -335,   -669,   -166,   1853,   -310,   -340,    249,
+      -954,   -594,  -2929,    415,      5,    135,  -1315,   -237,
+      1868,    787,   1912,  -1100,   1139,  -1103,   -217,   -382,
+      -654,   2078,    528,    133,   -115,    -56,    -41,   -207,
+        69,    461,    465,   -396,   1725,   1306,   -443,   -720,
+     -1600,   1176,    652,   -997,   -306,  -1040,   2258,    -75,
+};
+
+static const int16_t cb4440sm1[] = {
+      8192,     96,    214,   -395,   -106,    291,   -401,    305,
+      -102,    194,    -73,     31,     71,    -19,   -349,     65,
+      -183,     26,    -21,   8154,    107,   -136,    -37,    -35,
+        85,    127,   -202,     43,   -195,    225,    -51,    -69,
+       -57,   -107,    141,   -120,   -284,   -227,     28,    680,
+       218,     29,  -1800,    488,   -207,   -453,    -99,  -3680,
+      -210,     39,    279,   1406,    278,    -37,  -1596,    232,
+       376,     90,    234,  -3348,    242,   1765,    555,   -883,
+       118,    115,     48,   -116,   2166,   -292,    136,    527,
+      -236,    -18,    411,    -20,   -190,   -480,    665,   3332,
+       378,   -287,    337,    199,     -5,  -3904,    311,   -297,
+     -2720,   -193,    -17,    911,   -224,    457,    -48,    254,
+       271,    -24,    -77,    165,     23,    182,  -1122,    122,
+      -520,    309,  -3604,  -1013,   -405,   -647,   -145,  -1162,
+      1019,   -190,   -278,     69,    362,   -185,    -78,   -245,
+       472,    670,   -493,    620,     76,    717,  -2296,   -111,
+      -454,   3224,     27,     47,   -351,   -154,   -293,    187,
+       -93,     96,     87,   -453,   -132,      9,    125,   -209,
+       -26,    284,   -552,    255,     87,    227,  -5445,    112,
+       172,    -15,   -448,    475,  -5747,    367,    149,   -228,
+      -797,    371,     67,   -102,   -118,   -418,    332,     38,
+      -100,     90,   -183,  -3302,     15,  -1049,  -1560,   1299,
+      -710,   1257,    698,    316,   -283,    955,    240,    182,
+       269,     12,    -37,   1817,    649,  -1273,  -2071,  -1719,
+      -765,    977,  -1159,    351,  -1583,    -85,   -771,   -215,
+       123,    314,   -158,     32,    560,    208,    265,   -451,
+      -413,     32,   1954,  -3598,  -1680,   -832,   -646,    761,
+       272,    394,    213,    -35,    -44,    343,    309,    244,
+      3041,   -399,    -50,   -126,  -2755,   -146,    243,   -367,
+      -600,   -166,   -832,   -537,    269,    -48,   2419,   -526,
+      -309,    -17,   -235,     73,    341,    351,   -840,   3241,
+       -94,   -432,    404,   -588,    158,   -127,    -49,   3259,
+      3543,    134,   -256,   -106,    622,    -45,   -170,   -109,
+        68,    377,    -84,    210,   -250,   -267,    257,    -77,
+         6,  -1109,  -1498,   -327,   1063,    992,    632,   -245,
+      -656,  -1100,    -60,   -456,   -170,   3208,     -6,     13,
+       -95,    606,   -594,  -2039,   -369,  -1743,    275,    -93,
+       117,   2828,   -138,   -108,    206,   1819,     98,    -45,
+        45,   -163,   2962,   -398,   3536,   -183,   -259,   -581,
+        65,   -498,   -288,   -357,   -339,    -13,    -71,   -409,
+        36,    -15,   -545,   1433,    135,   -220,     99,    752,
+       177,   -455,   -251,   1172,  -1274,   1062,   -774,   -999,
+       -63,  -2756,     99,    -86,   4695,   -171,   -129,   -856,
+        26,   -543,    610,  -1350,     -2,    271,    455,   -150,
+       358,    101,    536,    125,    101,     88,    -16,    -12,
+       488,  -7479,    110,    264,    140,   -302,    110,    232,
+         0,     15,     70,    -28,    -27,   -110,    -99,    201,
+        78,    215,   -108,   -267,  -7548,     34,    312,    -86,
+       197,    125,     80,    -75,   -117,     -2,    128,   -207,
+      -131,   -513,    614,     33,  -4844,   -302,   -323,    160,
+       808,    645,    243,   -603,     68,    -70,    158,   -131,
+      -212,    -34,   -247,    625,    134,    -42,    525,    -89,
+        31,    116,     -1,    508,   5021,    395,    111,    -86,
+      -172,   1433,   -114,   -126,   -148,   -337,   -260,    233,
+      -479,    275,   -247,  -5672,    386,   -110,    -99,   -142,
+      -171,   -154,   -358,     30,   1028,    -78,    575,    523,
+      -586,   -739,   1586,   1076,  -2519,   1572,  -1448,   -201,
+       166,    -54,    137,   1268,   1157,   -411,  -2905,    195,
+       489,   -740,    154,    522,   2276,   -604,    194,  -1112,
+       192,    400,   -271,    250,    413,    273,    158,   -299,
+      -874,   -228,  -2454,    162,    819,    457,   3401,    689,
+      -208,   -298,   -461,   -360,    -70,  -2133,   -114,   -124,
+        81,   -228,    625,   3525,    909,    254,   -234,   1316,
+      -773,    531,    -30,    -16,   -164,    -84,   2360,  -1900,
+       351,  -2979,    545,    653,    416,    273,    -79,   -825,
+      -107,     71,    495,    223,   -176,    129,     40,    424,
+      1627,    207,     47,     -8,   -273,   -715,     60,  -1253,
+      1501,  -1199,   -248,     39,   2859,   -432,     89,    299,
+       948,  -2608,   -896,   3468,     84,    511,     55,    151,
+       733,    270,   -354,    470,   -219,   -115,   -105,     91,
+      -259,   1941,    775,     12,   2764,    484,    557,   2288,
+      -118,    294,    -32,    719,    -62,    -64,   -295,    -82,
+      -145,   -285,   -492,     87,   -135,    -98,    194,   -288,
+        -8,    263,   -475,    -53,   -388,   5621,     41,    -28,
+        34,   -323,    138,   1935,  -1806,   -185,    340,   1380,
+        48,   -542,  -2965,   -339,     88,    554,     41,      4,
+      -151,    182,    -39,   -193,  -3355,   -312,   3106,   -203,
+       442,   -110,    317,   -269,    225,     31,    -62,   -277,
+       163,   -766,   -408,    210,    -58,    128,    161,   3308,
+      3321,   -138,   -278,   -149,    216,    134,   -253,   -135,
+      -154,   -123,    254,    200,     -2,    133,   -307,  -6253,
+       310,     -6,    959,     26,    191,    315,    528,    -75,
+      -230,   -203,    153,   -265,    -94,    -61,     -2,   2761,
+     -4623,   -353,    -19,    102,   -139,     54,    438,    267,
+       -73,    447,    226,     71,    -19,     75,    -40,    -32,
+      -850,   -500,    422,   1237,   -688,    357,  -3158,   -468,
+      -450,   -279,   -694,  -1109,    734,  -1602,   -117,    122,
+       261,    979,    -20,    385,  -2929,    342,  -3164,   -146,
+       252,   -104,     62,    469,    289,    249,   -214,    -38,
+        73,     83,     -7,     18,   -394,     -5,   -140,   -267,
+       331,   -147,   6540,    395,   -103,   -147,   -271,    -20,
+       191,     73,   -155,    197,     71,    503,     19,    138,
+      -129,    335,    209,     75,  -6207,    140,   -176,     -5,
+        35,    -40,    -61,   -146,   1080,     58,    327,    -49,
+      -842,   1431,    595,   3461,      1,    142,   2001,    297,
+       -16,   -425,   1156,   -101,    -54,   1060,   -222,   -295,
+       938,  -1212,  -2374,     73,   -272,  -3318,     -8,   -718,
+       114,   -154,     85,     -9,     72,     86,  -1330,    226,
+     -1414,   -521,   3161,  -1856,    133,    240,   -499,   -371,
+      -745,    779,   -463,   -506,    463,   -229,   -226,    389,
+       135,  -4137,    360,    735,   -318,    777,    593,    977,
+      -174,    286,    187,    -95,  -1626,    245,     97,      9,
+       277,    299,   1568,   1066,    375,   1342,   -390,    884,
+       271,    185,   -258,  -1100,   2113,   -107,   -447,  -1917,
+       -58,    -29,   1081,   -455,   -524,   -196,   1869,   -677,
+     -3564,   1443,     29,   -425,    -28,   -370,   -342,    -28,
+        30,   -118,     58,    607,    454,     45,   -120,    232,
+        20,     21,   -175,   -112,   -236,    492,    411,     42,
+       -42,   4041,     39,  -2579,    235,   -146,    122,     24,
+      1301,    123,   -461,  -3264,    316,    -88,   -209,    140,
+       387,   -430,     78,    508,    149,  -3588,   1107,    820,
+      -140,    654,    812,   -566,  -2578,   -403,    -72,    120,
+       355,   -136,   -121,    209,    240,    116,    231,   1630,
+       208,   -178,  -3160,   2203,    -52,    451,     84,   -310,
+     -1199,    596,     69,    285,    242,     15,     49,    341,
+      -154,  -2286,   1206,   -109,   1048,   -647,   1127,     98,
+     -1264,   -808,   1744,  -1597,     13,     26,   -216,    263,
+      3276,   3192,   -105,   -390,    -31,    676,     73,    265,
+        31,    101,    479,    -69,    123,    -24,    -49,     32,
+      -653,   2253,     49,   -346,   1476,   1820,    396,    639,
+      -219,    792,   1728,    147,   -765,   -140,   1181,     98,
+       153,    -98,   -755,   2473,    452,    231,   2031,   2468,
+      -416,    587,    724,    148,    500,   -933,   -229,     55,
+       102,     74,   -164,    652,   -425,    100,  -2684,   1358,
+      1626,   -350,    544,   -301,  -1589,   -305,  -1266,     11,
+       243,   -125,   -330,    294,   1471,  -2922,   1581,   -546,
+       582,    231,  -1407,   -877,    602,    219,    350,   1130,
+       -86,    214,    -56,    201,   -181,  -2140,   1108,    493,
+       456,   -542,   -113,   -852,   1647,   1897,    840,  -1178,
+      -369,    788,    488,    256,    366,   2298,   1167,   -205,
+       256,    585,   -555,    292,   2615,    748,   -247,  -1102,
+     -1682,    226,    415,     20,     27,    100,      9,    436,
+     -1746,   2621,   1583,   -211,   -833,    441,     54,  -1183,
+      -826,   -916,   -707,    564,   -232,    -14,    147,    453,
+        70,   1094,   -903,   -337,    450,  -1546,   -662,  -1047,
+     -2345,   -811,  -1037,     96,    560,   1381,   -119,   -383,
+};
+
+static const int16_t cb4448sl0[] = {
+     -3850,  -1289,   -449,    -36,  -1178,  -1175,    705,    -97,
+        37,   -650,    426,   -477,   -145,    124,      6,    207,
+       -96,  -3145,   2917,   -260,    349,    668,    -72,      6,
+       157,    -62,   -128,     20,    -82,  -1357,   -707,   -619,
+      -313,   -229,   3010,   -169,    -27,    738,    971,  -1450,
+       246,    154,   -163,    -15,    -93,      5,    -35,    -42,
+        24,     31,    -25,   6803,     33,    -32,    -68,    -68,
+       -44,    317,     43,   -106,    608,   -999,   -699,    582,
+        46,   1631,    830,  -1570,  -2645,    992,   2126,    132,
+      2377,   1551,    247,   -247,   1508,    -34,    162,   -275,
+       -81,   -654,   -625,    125,    -33,   -210,    309,    900,
+       571,    726,   2691,   2821,   -698,     60,     46,   -483,
+        14,   -210,   -295,    102,    214,    226,   2622,    -82,
+      -390,   1436,    107,    554,    381,   1307,   2283,   -190,
+        27,    -35,   5557,    283,    103,    180,    104,    -89,
+      -186,   -319,   -225,   -141,     92,      1,  -1942,   1025,
+       906,     32,     -3,  -1089,    182,   -799,    483,   -368,
+     -1734,   -103,   1680,    474,   -133,  -1067,   -545,   -219,
+      -118,   -635,  -2559,   1002,   2554,   -640,   -505,    179,
+      -344,    -81,    107,    -61,     79,    -12,    -29,    -37,
+     -7574,    -92,     64,     92,   -164,    -20,    -61,    -35,
+      -312,   -159,    333,  -3401,  -2596,   -344,     88,    604,
+       535,    -87,    365,    -13,    -77,    131,    127,    588,
+       302,    -94,   -506,   2427,     99,    304,   2653,  -1104,
+      1380,    976,   -530,   -120,   -105,    293,      9,   -826,
+       388,    -66,    421,   -202,    605,    675,   4060,    978,
+       143,    -94,     21,  -2444,    -30,    554,    695,   2878,
+       657,   -104,   -435,   -326,    307,     20,     20,    159,
+       106,  -3473,    326,  -1029,   -304,    670,  -2109,   -431,
+       573,    704,    293,    -45,   -169,   -119,   -191,    599,
+      -910,   1976,   -165,    581,   1209,  -1689,   2365,   -370,
+      -601,   -696,    374,    202,   -114,    -61,      3,    -63,
+        30,    369,   -158,   -128,    198,     52,    -98,    -44,
+      -323,  -5118,  -1100,   -669,   2256,     32,    -66,    206,
+        65,   2801,    783,   -470,   -973,    471,   -211,    -27,
+      1879,    302,   -388,   -249,    301,    537,   2761,    321,
+       571,     20,    337,   1336,    522,    231,    368,   -363,
+     -2065,    -57,  -2565,   -584,   -611,     56,    814,   -382,
+      1671,    408,    492,     12,   1201,   1513,    247,   2165,
+      -592,  -1246,   -493,  -1012,  -1330,   1251,     75,   -100,
+       182,     52,    -47,    710,  -1137,   2420,   -559,    266,
+      -801,   2523,   1229,    736,   -409,    -49,    269,   -174,
+      -179,    -24,    348,   -661,    251,  -1039,   2647,    283,
+       728,  -1850,  -2088,    196,     39,    -72,    -35,    -94,
+      -540,    266,    340,   -450,    763,     -5,    113,   2618,
+     -2737,   1047,   -246,   -522,   -182,    376,   1068,    203,
+      1238,   -938,    211,   -308,   -395,   -629,    596,  -2634,
+      1452,  -1155,     83,    -89,  -3121,    419,     40,   2691,
+      -306,   -343,      4,   -347,   -725,   -117,   -315,    115,
+      -215,     26,    429,   1074,  -1831,  -1850,   2609,     72,
+       467,    191,    432,    857,   -186,      0,   -443,    -24,
+       500,    541,     30,   2324,  -1160,  -1153,   1783,   1282,
+     -1992,    101,   -108,   -108,    556,  -2012,    506,    691,
+       -65,   -610,    402,    610,   1941,   -121,    942,    589,
+      1879,     58,    312,  -2218,  -2056,  -2284,   -350,   -453,
+       306,     38,   -579,   -185,   -101,   -196,   -150,    156,
+       126,    -44,   -143,  -7923,    126,   -120,   -138,   -233,
+        97,    -20,   -121,   -175,     -8,    -13,   -123,   -365,
+       251,    730,   2883,    667,   -418,   -208,   2170,  -1442,
+       196,   -389,   -516,    252,    -98,    525,  -1819,   -647,
+      1575,    768,   1124,   -428,  -1010,  -2027,    411,   -473,
+       863,    210,    908,     40,    145,     37,    192,    189,
+        52,   -217,   -168,     63,     -7,    -53,   -121,     13,
+      -145,      0,    -37,     61,  -7979,   -142,     32,    118,
+       190,     -7,    -13,    113,     36,     31,   1461,  -2088,
+      2391,   -939,    -66,    822,    280,    246,   -157,   -183,
+      -433,   -356,     88,   -101,   3969,  -3388,    -84,     84,
+       130,     35,     74,     37,    181,   -195,    219,    -29,
+       -23,    -32,     69,    625,   2328,   -192,  -2617,    287,
+       543,  -1604,    823,   -547,   -277,    764,    276,    156,
+       198,     17,     84,    346,    -27,   -129,    143,    217,
+       212,   -249,     20,   6449,      7,     51,   -889,    -88,
+       265,    282,  -1956,   1327,  -1025,   1338,  -1709,  -1008,
+       372,     57,   1404,    234,   2621,    -18,    663,    301,
+         0,    167,   -372,  -2534,   1945,   -191,    198,    359,
+       -43,     92,     24,  -5498,    -63,    189,     36,   -369,
+       352,    381,   -205,   -144,   -119,   -267,    -60,    -10,
+       387,   2388,   -155,   -450,    465,   1529,   -216,   2673,
+      -146,    118,     50,    290,    147,     11,  -2912,    863,
+      2184,   -689,    -44,     59,   -663,    663,    675,    295,
+      1331,   -115,    -10,    -54,     -1,     31,   1699,    127,
+       215,   2966,    163,    416,  -1053,   1216,    356,   1428,
+      -166,   -172,     -2,   -355,   -169,   -331,    -94,    -78,
+      -123,   4875,    311,     67,   1145,    397,   -288,    212,
+      -344,   -290,    126,     16,    176,    485,    551,   -526,
+        11,    120,   -274,     83,  -5399,   -154,  -1611,    887,
+       321,   -446,   1166,   -333,    652,    310,   -895,     62,
+      -219,   2840,   -753,    -34,  -3203,  -3600,    464,   -249,
+       336,    297,    -85,    316,    144,    306,   -249,    149,
+       112,     73,    192,    -89,     18,    197,    116,     51,
+        37,    212,  -7248,    163,     31,    -52,    -31,   -101,
+     -1366,   -353,   -325,  -1335,   -440,   1193,    670,  -2635,
+       872,   1400,    733,    395,    122,    130,  -4146,      0,
+      -382,   1486,    308,   1179,   -412,    288,    701,    161,
+       147,    959,     60,     77,   -123,     17,    193,    204,
+      -226,    388,    272,   -588,   -157,   2823,    735,   -745,
+      2368,    359,  -1088,  -2004,  -1293,   2018,    483,    320,
+     -1014,   -806,   -479,    -68,    -51,    168,    873,     27,
+     -7906,     57,     19,    -23,     27,     43,    -13,    -50,
+        93,     16,     29,     31,    -26,     32,    -22,    453,
+      2922,  -2560,    138,    923,  -1245,   -405,     10,    228,
+      -270,    145,   -192,     83,     48,    101,     77,   -226,
+        36,   7792,    126,   -275,    -37,    -36,      9,     45,
+       -89,     13,    148,    125,     24,   -442,    111,    -12,
+       540,   1794,   3008,   1620,   -185,  -1394,   -161,    -25,
+      -313,   -317,    591,   2507,    134,   -369,     77,    527,
+      -619,   -236,   2681,     87,  -1060,    -34,   1894,  -1123,
+       373,   -628,   1934,  -1279,  -1689,   -609,   -472,   -598,
+       405,    229,    414,     12,  -2923,    -33,   -435,    -49,
+      2380,    -34,   -344,  -2171,   -284,    274,    226,   -287,
+       -84,    -57,     -1,   -169,    -50,    479,    707,  -2774,
+      -532,   -640,   -244,     44,    458,   2519,   -590,   -472,
+};
+
+static const int16_t cb4448sl1[] = {
+     -2878,   -714,   3098,    -76,    -51,    232,    118,   -780,
+      -691,   -267,   -309,    105,   -179,     -5,    -84,    -11,
+      -120,   -379,    458,  -3161,     65,   2994,     64,    374,
+      -440,     62,   -183,     28,   -561,     73,     59,  -2565,
+       445,   -451,  -1026,    437,     10,   -173,   1243,  -2278,
+      -481,   -395,   -154,  -2402,    945,  -2789,    117,  -1184,
+        75,   -704,    527,    478,   -589,     17,    131,   -110,
+       574,  -1055,   -628,   -277,   2798,   1483,   -657,  -1996,
+      -248,    194,   -284,    822,    225,   -170,    -10,   -302,
+      -427,  -1700,    -90,   2756,   2124,    -49,   -964,    372,
+      -637,    443,     13,    -69,    -71,    196,  -1971,    110,
+      1147,    698,   1333,   1369,    527,    165,    903,    577,
+     -2134,     56,    -33,     34,    183,    247,   -342,    974,
+      1079,   2478,    -26,     80,  -2377,    430,  -1422,    428,
+     -2187,   -469,  -1280,   -326,    -40,    188,    911,    405,
+      2772,    279,   -493,    265,    768,     45,   5778,     44,
+       121,   -257,   -135,    124,    263,     15,    197,   -114,
+         5,    -14,     -8,    -82,   3989,   -511,    197,   2446,
+      -292,   -205,   -919,    162,   -121,    145,    -40,     71,
+      -105,     72,   2035,    960,   -145,   -467,   -518,    167,
+     -2988,    421,    860,    320,     40,   -446,    319,    160,
+       140,    511,    -55,    213,   -148,   -527,   -666,    687,
+         9,     23,    344,   -156,  -4646,   -125,   -220,      9,
+       134,    -25,     16,  -1319,    763,     58,  -1586,   -438,
+       301,   -411,   -337,  -3398,    358,    -68,   -111,   5483,
+       -36,   -456,    -94,   -116,    204,     95,     84,    -73,
+      -163,     69,   -190,     64,  -3716,   -326,   1815,   -843,
+       312,   -498,    684,   -641,   -766,   -104,    606,     70,
+      2630,     51,   -170,  -3584,    167,    461,   -162,    132,
+       496,     91,    171,    255,     48,      2,   -120,  -1196,
+       534,   -431,   2669,   -403,      8,    287,   -391,   2557,
+       849,    167,   -275,   -184,    605,  -3570,    113,     22,
+     -2586,    668,    294,   -910,     67,   -141,      0,    418,
+       271,     75,     90,   -124,    446,   -142,   -635,    631,
+      -956,   1566,     25,  -1982,    790,   2770,     33,   -520,
+        23,  -7488,     67,    -73,     60,     64,    -46,    -36,
+        76,      3,     22,    149,     61,     34,    255,   -380,
+      -284,  -2531,  -1423,   1507,   -926,  -1074,   -929,  -1430,
+      -141,    165,    -80,   -268,     21,   -767,   1542,   3197,
+      -191,   2014,   -304,    595,    536,   -906,   -126,   -354,
+       -76,   -162,   -125,  -3139,   3197,    934,    366,   -923,
+      -330,    277,   -284,   -163,    -12,    402,     15,   -146,
+        20,     83,    111,    196,     23,     71,     77,   7287,
+      -175,    -13,   -227,    -59,    -56,    -28,      1,    163,
+       -50,     59,    635,    150,     95,   2750,    775,  -2057,
+       423,  -1078,   1749,     -3,   -655,   -365,   -357,    145,
+       -76,      5,    -93,    224,    150,    108,    -34,    173,
+       148,   -371,     34,     48,  -8037,     65,     50,    103,
+       -42,    -10,    -96,    -90,     -3,     60,     92,    -79,
+       -76,    386,    114,  -1947,    833,  -1279,   -484,    217,
+      3156,    226,    485,   1191,    425,     88,    -59,   -243,
+      2292,   1681,    671,     62,    899,  -2453,   -100,   1039,
+       713,   -104,    554,    219,    356,    963,    741,   -102,
+       455,   2067,   -324,    172,     28,    772,    752,  -2351,
+     -1438,   -865,  -1668,    105,   1034,   1195,     14,   -350,
+      -425,   -648,   2086,   -532,    634,   1537,    -33,   -598,
+      2888,    -85,    184,    158,   -164,   3339,    237,   -284,
+       -54,   -246,     46,   -254,    365,     55,   1928,   -346,
+      -357,    331,    139,     16,    674,   -384,    -67,  -3399,
+       165,     76,    215,    137,  -3187,   -146,   -264,   -165,
+     -3039,    235,   -541,   -630,    -32,    -33,   -211,    160,
+      -121,   -111,  -1296,    -47,   -128,    292,  -1523,   1540,
+       771,   -166,   -509,    212,   2758,   -327,   -418,   -305,
+        -9,    465,   2513,    195,    -70,   -209,    -66,    127,
+      -147,  -3161,   -192,   -541,   -555,    131,   -858,  -1609,
+       973,   -156,  -1877,     60,   1011,     66,   -348,    912,
+     -1731,  -1296,    305,   -369,   -560,    470,     46,   -863,
+      -124,    -37,     40,   -395,  -4886,    -20,    221,    228,
+       177,    182,     98,   -151,   -195,    854,   -194,   -374,
+       301,    586,     58,   -908,    -19,  -4198,   -171,    330,
+        48,  -3312,   -164,   1913,   1183,    -42,   1287,   -353,
+       757,    620,   -547,    251,   -520,     59,     43,   -179,
+      -191,   -131,  -2951,   -944,  -2479,    344,   -813,    104,
+      -697,    -44,   -270,    198,    245,   2866,    208,    178,
+      -248,     38,     19,    577,   2812,   -765,   -855,   -439,
+       -60,    -30,   -352,   1521,  -1069,    457,    415,    572,
+      -749,   -144,    100,    515,   -794,  -1554,   2507,   -270,
+        10,     62,   2507,  -1550,    -75,     70,   2530,    562,
+       132,   -141,    251,    156,    835,    102,    717,   3226,
+      3327,    172,     84,   -205,    -11,    208,   -310,    164,
+       -27,     11,    281,     37,   -518,     20,    -76,     82,
+      5436,   -543,   -301,    112,    359,   -140,    -94,     78,
+       -18,     38,   -196,    -92,     13,   -111,    -23,     30,
+       -15,    -94,    101,    142,  -6455,    321,    322,     50,
+      -216,   -321,    -10,   -465,    101,     45,   -585,   -969,
+      1248,   -456,  -2523,   -852,  -2129,   -889,     33,  -1424,
+      1462,    583,    749,    527,  -1737,   1262,   -594,    414,
+      -215,  -1184,    412,   1758,  -1836,   1248,    440,   -178,
+       784,   3591,   -227,     43,   -493,   -766,   -270,    150,
+       151,    -56,   -110,  -2832,    -73,   -166,    470,   -179,
+      -681,     71,   -114,  -2743,   -806,   -560,     63,   -244,
+       -90,    182,   -143,    995,    404,    -13,  -1343,   1524,
+     -2472,   1718,   -957,   1229,    458,   -395,  -2817,   -579,
+       -99,    340,   1538,    684,   -492,   1156,    -45,    -65,
+      -305,  -1408,   -325,   -270,   -358,   -127,     92,    -97,
+       415,     85,  -4749,    173,   -296,   -203,    331,    315,
+       184,    -46,   1315,   -146,    -55,    427,     37,    255,
+      -209,    272,    735,    506,    105,    103,    902,  -3449,
+       116,   2304,    616,  -1564,   1508,    478,    320,  -2418,
+       244,   -176,    -32,    238,     92,    290,   -168,    -78,
+     -3464,    270,  -1902,      2,    696,     92,  -1610,   -206,
+       -49,    178,    121,     27,    119,     72,   -253,   -398,
+     -2720,    -81,   -162,   -550,   2595,   1445,    249,   -104,
+       218,   -310,    -95,     18,   -473,   1908,    432,   -227,
+      -168,  -2725,   -240,  -1830,    199,    437,  -1392,    304,
+      1461,  -2394,   -603,   -540,    769,    340,   -104,   1569,
+       -21,    338,   -874,   1533,    281,    -59,    487,   2120,
+       179,   -140,   -328,    -57,     63,   -110,  -1330,   -485,
+     -2427,   1159,    355,    -26,  -2055,    154,   -563,   -132,
+        49,   -329,   -187,    -24,    -71,  -3970,    276,    158,
+        92,   -202,      7,   -422,   -578,    186,   -407,   4960,
+      -595,   1027,    417,    691,     69,    133,    123,   -147,
+};
+
+static const int16_t cb4448ss0[] = {
+     -2680,   2499,   -328,   2212,   1288,    -57,   -727,     76,
+      -210,   -218,     41,   -343,    -26,    -38,     43,    606,
+      -619,   -531,  -2082,     87,  -1127,   1282,    -23,   2272,
+     -1816,    104,    -31,     85,    -22,     60,   1293,    138,
+       382,    432,    489,   -372,  -1649,  -2809,  -2556,    -98,
+      -232,   -233,    169,    186,     79,   1157,   2113,   -942,
+       636,    877,   -601,   2277,   1411,   1165,   1029,   -613,
+      -348,    -38,    -19,     45,   1318,  -1980,     12,   2762,
+      1519,    184,   1980,    -49,   -270,    361,   -172,   -601,
+      -196,    186,    -67,   -124,   1503,  -1011,    263,    223,
+      -384,    153,    -21,  -1063,   -239,   1171,  -3501,    512,
+      -162,   -180,    139,   -680,    609,  -1919,   2969,  -2321,
+      -183,    194,   -558,     26,     91,    340,    -25,    -31,
+       127,    662,    182,    191,  -2201,  -2603,   2252,   -523,
+       277,     50,    355,    295,    -65,    355,    207,     82,
+      -489,   -143,   -218,     89,    666,   -359,   2716,  -2310,
+     -1912,    417,    400,     43,    110,    -93,   -142,     61,
+     -3000,    454,   -153,      0,   -413,    469,    339,    318,
+      -197,     75,    -80,   2894,   -129,     82,   1431,   1183,
+       429,  -1556,  -1339,  -1573,    -92,   -911,   -230,    -12,
+        -4,   -145,   -388,   -419,     -5,   -241,   7120,    165,
+      -125,   -122,    126,   -150,    109,   -146,    -61,    -49,
+        47,     70,    -43,     40,   1867,   1473,  -1278,   1229,
+     -2256,    -90,     10,   -744,   1196,   -109,    402,    258,
+       690,    -74,     26,   1294,  -1079,    142,  -2384,   -324,
+     -1696,  -2741,    321,     66,     83,   -127,   -131,    156,
+       166,    135,   1812,  -3445,     10,    535,   -547,    481,
+     -2243,    287,   -335,    218,    195,     -1,    -25,    -94,
+       195,   1433,  -1428,  -1444,    520,    219,   3363,   -388,
+      -807,   -454,    -29,    316,    125,    159,   -144,   -156,
+      -317,    752,    256,    216,    340,    488,    147,  -5662,
+        55,   -110,    387,   -102,   -211,    -66,    -26,   3688,
+      -172,  -2366,   -244,     -5,    353,     11,    503,     88,
+       227,     69,   -240,   -187,    -58,   -389,  -1783,  -1427,
+        20,   -618,    544,  -1337,    628,  -3180,    708,   -538,
+      -423,    115,     49,   -161,    184,   -682,   -223,    689,
+      1299,   -891,  -1073,  -1228,   -305,     47,  -2221,  -1559,
+       598,   -380,    166,    143,   -366,    287,   2122,    509,
+       629,    235,   1523,   2900,   -640,   -425,   -462,   -231,
+       -53,    -27,   -263,   2090,  -1892,  -1147,    -42,    866,
+     -2301,    461,  -1082,   -625,    -85,    148,    229,    -25,
+        85,     53,    259,    -81,  -4072,   2577,    -12,     -7,
+       335,   -151,   -691,   -137,     98,    372,    -37,   -192,
+       -17,   3318,   -558,   2064,    396,    258,  -1067,    229,
+      1122,    298,    -25,     40,     27,   -134,   -166,   -247,
+     -2010,   -440,   1066,  -1400,  -3454,   -289,    428,    629,
+      -158,    126,    129,    183,    -12,   -171,   -120,    421,
+      -445,     66,   -900,   3680,   1583,   1985,     25,    229,
+      -535,     -1,     45,    207,    -54,    -30,   1581,   -938,
+      -703,    405,    878,   -398,  -1069,   1748,  -2587,  -1419,
+      -375,   -441,   -487,    109,     21,  -1399,    648,   -271,
+      -701,    635,    115,   -138,   -458,   -600,  -1891,    585,
+       420,  -1916,   1135,      7,   1584,    910,   4267,   1328,
+       279,    395,    -35,    -99,   -168,    503,    216,   -126,
+       211,    212,    193,  -2205,    491,    696,     41,    283,
+       649,  -3425,   -999,    200,    625,   -261,   -378,    -47,
+       -15,    -30,  -1262,   1700,  -2191,    196,  -1773,   -251,
+        84,    498,   -261,    150,    451,     41,    336,     27,
+       -56,    562,    -86,     -1,  -1073,   1461,   2148,  -2961,
+      -326,   -257,    440,    -42,    -48,   -320,    122,     94,
+     -1267,   -830,   2810,    -94,   -201,    990,   2415,   -740,
+      -166,   -267,   -157,     68,    301,    290,     65,    931,
+      1969,   -170,      6,    149,   -272,   -105,    542,    -11,
+     -3888,    105,    305,    333,    -14,    -39,   1944,  -1164,
+        88,   3829,  -1190,   -535,   -644,   -330,    509,    -93,
+      -314,   -228,   -294,   -342,    -26,   1143,  -2371,   -400,
+        74,    101,    -68,   -583,  -1091,   3367,   1146,   -638,
+      -436,    136,     41,    -92,   1518,   2818,  -2214,  -2044,
+       636,     -2,     79,   -508,    676,   -439,   -358,   -198,
+       -69,    271,     59,   1638,    468,     97,    264,     -8,
+     -5152,   -152,    152,    252,    401,   -375,    -17,   -132,
+        51,     63,    633,   -180,    367,    111,    -18,     15,
+       -52,    128,    -54,     11,     96,   -122,    -26,  -7257,
+       -42,  -1221,   -688,    197,   -107,   -217,    141,   -289,
+       141,    269,    439,   -747,  -3743,   2098,    226,    137,
+        26,  -1645,  -1735,    -80,     43,   -216,    245,    544,
+       157,     40,    238,    237,   -989,    379,     88,    639,
+     -1335,   1542,   1147,   -510,   1008,   -134,   -626,    696,
+     -3034,    334,   -689,    115,   -168,     39,   1750,   -649,
+      -233,    -99,   -231,    515,    112,    -11,   -162,   -133,
+      -138,   -486,  -4137,    204,   -102,    867,  -1030,    219,
+      -254,  -2787,   -128,    961,  -2837,   -482,   -195,    691,
+      -170,   -178,    164,    -54,  -2008,   -116,     74,    398,
+       -96,   -472,    407,     27,    287,    628,     97,  -1425,
+     -3923,      6,    117,  -1081,    930,    396,    452,     87,
+      -441,   -155,   -738,   1089,   2128,  -3133,    -21,   -622,
+       -48,   -127,    506,    985,   -200,   3361,    184,   -522,
+        41,    503,    209,     14,    -96,    791,   1263,    289,
+      -101,  -1728,  -1073,   -517,   4156,   -685,    214,   -721,
+      -608,   -102,   -295,   -114,    126,   -340,    109,     88,
+     -1588,     82,   -549,   -376,     76,     84,   -210,     59,
+      -130,    321,    678,   4704,    564,     -1,    100,    325,
+      -296,    256,   -936,   -886,  -1088,   -191,    476,  -3684,
+      1359,     12,   -397,    -70,    -17,     58,    569,    353,
+       821,    -77,    253,    153,   5697,   -171,    181,      3,
+       -90,   -413,   -265,    142,     62,    959,    151,   -103,
+       845,   -340,   -280,   -733,   -592,   -244,   2534,   3089,
+       935,   -393,   -105,    145,   -666,  -2865,  -1532,    717,
+      2867,    206,   -800,   -125,    -34,   -189,   -138,     42,
+       189,   -141,    107,  -3030,  -3795,   -494,    108,   -149,
+       382,    760,   -142,    337,   -844,    228,    124,    232,
+       -23,     -1,   2298,    750,    636,   -353,    157,    676,
+      -191,    812,   3434,    759,    543,    -17,   -213,    -95,
+       316,   -693,   -604,  -1059,     32,   -496,  -3334,   -272,
+      -104,   -495,   -130,    627,   -376,     74,   -599,     55,
+     -2185,   -968,    517,   -343,     21,   -249,   -963,    268,
+      3339,    239,    771,   -134,     42,    231,     75,   1633,
+       331,   -125,   -414,    457,   -316,    111,   -475,    363,
+      -687,  -4105,    469,    443,    113,     72,   1498,    406,
+       915,   -229,    564,   -377,     89,    137,     39,      2,
+       -29,   -416,   -149,   3598,   -253,     12,  -1015,   3016,
+       916,   -726,  -2286,    -99,  -1085,   -238,    690,    -44,
+       -51,   -115,     25,     56,   -905,  -3050,  -1121,    -24,
+     -2160,  -1424,   1009,   -180,   -424,    188,   -417,    -66,
+       -86,     74,    -28,   -225,   -937,    -90,    251,  -1850,
+      1939,   1843,    833,  -1879,   -192,   -318,    103,   -363,
+       -22,    -57,  -2833,   -118,   -277,    -98,    -85,   -495,
+      -874,   3027,   -141,  -1490,   -172,   -266,    -32,    190,
+       -12,   -364,   -380,  -2107,    249,   -217,    662,   -584,
+        89,   -563,   1153,  -3091,   -656,    463,    144,    -26,
+};
+
+static const int16_t cb4448ss1[] = {
+      6475,    -60,    162,     42,    -71,     50,    -85,   -278,
+       -14,    -60,    -53,    132,     28,    -65,    -71,    -62,
+         6,    119,    195,   -140,     28,     37,   -603,  -4956,
+      -290,    700,   -241,     11,   -301,    297,  -1009,    468,
+       885,    192,     40,    495,    846,    -28,    201,   -255,
+       927,   -644,   2424,   2882,    -82,  -1764,   1077,    315,
+       946,    843,    399,    176,    567,    546,    377,    283,
+      2469,  -1815,    -65,     12,    422,   -368,   -639,   -493,
+     -5606,     84,    122,    241,    267,     -8,   -257,    -23,
+      -220,   -118,    139,  -1582,   -218,  -2436,   2539,   -270,
+       146,   -262,   -489,   1551,    604,   -225,    363,    234,
+      -110,   -166,   1058,   2342,   1950,     43,   2362,  -1189,
+       492,    172,   -296,    159,   -430,   -311,   -135,   -182,
+        77,   -444,  -1995,   -855,   2080,   -457,    389,    872,
+      2549,    935,   -128,    519,   -374,    310,     96,    119,
+      -263,   1981,  -1019,   -628,    212,   -173,  -2292,   1066,
+     -1985,   -426,    115,   -746,    147,      3,     94,    195,
+     -1762,   1713,   -337,   1884,   -123,   -480,     95,    777,
+      1073,   2117,   -969,     16,     11,    123,    374,   -394,
+     -1419,    829,   1657,   1294,  -2770,    286,    813,   -290,
+      -115,    111,    312,     53,     44,    896,     34,  -2288,
+     -3443,  -2053,     98,    293,    429,   -168,     74,    -58,
+       221,   -383,    100,     63,   1925,  -1207,    199,     94,
+       -94,   3060,   1825,    611,    292,   -141,    382,    141,
+       105,   -151,      0,   1448,   -267,    206,    932,   -682,
+       251,   -183,   1080,    161,   4334,   -397,    525,    -91,
+       127,   -104,    921,  -2282,   -274,  -1070,    387,   -312,
+      1380,   2769,   -554,   1501,   -921,    102,   -183,   -104,
+       -66,  -1656,   2049,    122,  -2271,     84,   -276,   -204,
+       353,    380,   -414,  -1757,  -1035,   -318,   -130,    -10,
+       163,   -471,   2425,   2864,  -1892,    294,    817,    754,
+       277,    -29,   -214,    -39,   -312,    -57,    -54,    986,
+      2286,   -574,     34,   -641,   3783,    214,   -399,   -155,
+        38,   -148,    -42,    -89,     97,    -17,  -2192,    729,
+       272,   1168,  -3593,    150,     96,   -473,    211,    -60,
+       136,    -26,    142,   -285,     93,    666,   -465,   -181,
+      2016,   -338,  -2186,  -2608,   -449,    107,    -18,     45,
+        24,    245,   -119,    244,    442,   1509,    158,    242,
+       169,    -16,   -221,    104,    115,     16,   -217,     23,
+       -25,    130,   4076,    662,   -315,   3068,    -35,     36,
+      2785,   -223,   -528,   -157,     43,    186,   -514,   -240,
+        15,   -245,    520,   -110,   -781,   -641,    294,    -20,
+        64,    -44,    400,   -109,   4756,   1334,   -421,   -195,
+       130,  -2182,     64,   -897,  -1423,   3081,   -523,    378,
+      -164,    968,    593,   -192,     71,    114,   -143,    -10,
+      1961,  -3141,   3173,    -39,   -110,    -57,    144,    -68,
+      -429,     30,    -10,    467,    159,     40,     67,    260,
+       814,   -168,   -836,   1073,  -3562,   1786,  -1205,   -148,
+      -105,     94,      5,    143,    138,     18,  -1384,     20,
+       635,   -126,    -71,    -87,   -320,   -407,    559,   -151,
+      1312,  -4395,   -755,   -263,    -77,   1657,    699,    426,
+       469,   -469,    253,    -80,    317,    -71,    268,   3592,
+     -2051,    304,    157,     43,   1872,   3794,  -1537,   1226,
+      -159,   -335,    340,   -385,   -253,   -195,     21,    106,
+       -31,   -187,    -63,  -2771,    446,   -708,    202,   -186,
+       548,    832,   1757,  -1274,   1234,   -756,   -160,     76,
+       -82,     64,   2169,     13,   -849,    244,  -2486,  -2138,
+       844,   -178,    270,    297,    150,    202,    -41,   -188,
+       121,  -1272,    371,   -319,   2848,   -469,  -2059,   1290,
+      -457,   -380,    690,    148,    -51,   -340,    113,     57,
+     -1259,   -396,  -1404,    336,   -511,    576,   4441,    124,
+       143,   -483,     85,    138,    196,     38,   -188,   1177,
+      -764,  -2067,    820,   -264,    218,   -300,   -501,   -230,
+     -2529,   1349,  -1606,   -199,     92,    -55,  -1324,   -702,
+      2078,  -1269,    414,    -50,     29,     12,     87,   -593,
+       217,    -82,     94,  -2392,    308,   2315,   2188,    768,
+     -1103,    -77,    579,   1706,   -826,   -224,   -297,    145,
+      -640,    570,    146,   -199,   1187,   -872,    327,   -310,
+      -122,    -23,    -13,    808,   -139,  -4425,   -670,    412,
+        -4,    -70,   -162,  -1056,    685,   -312,   -957,    339,
+       893,   -252,   4040,   -105,     76,    993,    281,    -79,
+      -139,    168,   -298,    795,  -1107,    395,    386,   -524,
+      1052,  -2341,   2537,    474,    726,  -1028,   -357,    -52,
+       115,     -9,   1349,  -2240,    785,   2751,     77,    922,
+       385,   -539,   -148,    410,    251,    -70,    199,     51,
+      1728,   -206,   1181,   1182,   1388,   -791,    121,     -3,
+         8,   -147,    -95,    101,    886,  -2412,     19,   2401,
+      -116,    718,   -592,   -221,    724,    -33,    690,   -180,
+       868,  -3330,    377,   -336,    128,    267,  -2075,   2848,
+      2994,   -300,      3,   -153,     41,   -456,     38,    -31,
+       309,   -106,    -92,    -14,     96,    672,    634,    207,
+      1556,    438,  -2147,    282,   2443,  -1662,    511,    457,
+      -259,   -505,    173,   -204,   -858,   -117,   2751,    852,
+       220,   -512,  -2576,   1542,    357,    -77,     -4,    165,
+       -63,    189,    302,   -699,   -764,  -1559,     25,   -233,
+       405,    173,    698,    -73,   -300,  -1442,  -2923,  -1326,
+       -25,     98,   -196,  -2915,  -1169,  -3392,    691,    353,
+      -196,     96,     41,    180,    198,    280,    207,   -158,
+       -19,   1556,    991,   -523,   -280,  -1599,   1368,  -3247,
+      -996,    159,   -136,   -469,    -48,      0,     30,     95,
+      -765,     33,   6580,   -180,    316,   -176,    105,    -21,
+        -9,    166,    148,    -52,    -49,     42,      2,    318,
+       -55,    -91,  -1461,  -1474,  -3086,   -756,   1479,    -29,
+      -668,   -255,    -51,    241,    249,   -212,    132,   -129,
+      -410,    113,     17,    301,    185,     96,     10,    188,
+        38,   -772,   5152,    -13,    -10,   1527,    806,    -23,
+       -79,   1102,    -77,    329,    -99,   -404,   2276,   -873,
+     -2681,   -765,     71,     20,  -2448,   -803,   1827,   1115,
+      -160,    -15,    288,    -46,    573,    100,   -726,   -694,
+      -406,    288,     61,  -2216,   -904,     77,  -2983,   -962,
+     -1438,    809,    -38,    -79,     95,     52,   -231,    518,
+       115,     41,    908,    780,    805,   -207,  -2161,    554,
+       968,   3111,    133,   -158,    -13,    -34,   -182,    -60,
+       105,    718,  -1245,    227,   -818,   1184,    903,    603,
+      -988,  -2647,   1847,    141,    817,   -337,    131,    393,
+      1653,    839,   -261,    466,    465,   -297,   1440,   -431,
+      2058,  -1857,  -1416,    310,   -722,    -54,    203,   -266,
+      3770,    172,   -593,    -73,   -508,    -61,   1110,   1261,
+       275,   1681,    447,   -147,    -95,     33,   1281,  -3119,
+        24,   -308,    366,   -468,    232,    358,    667,   -942,
+       696,   -924,  -2059,    -62,    151,  -2102,    332,    258,
+      -186,   -636,    685,    214,  -3174,  -1243,    573,   -276,
+         9,   -262,    -20,    158,   -174,    -21,    593,  -6198,
+      -266,   -270,    -63,   -203,     63,   -396,   -100,    191,
+       212,     85,    120,   -791,     37,    -47,   2108,    652,
+       519,    346,    106,  -1840,  -2566,   -563,     14,    266,
+        10,    214,    504,  -1269,     50,    164,    120,   -105,
+      -546,   -212,    -79,     41,   -171,    675,   -252,   4373,
+       -16,  -1697,  -1491,  -3588,   -587,    623,     67,    269,
+       484,    -25,   1067,    580,   -598,    195,     47,    -17,
+};
+
+static const int16_t cb4448sm0[] = {
+     -5114,    166,   -785,    635,   -528,   -102,    269,    492,
+      -185,   -614,    122,   -124,     85,    145,    270,   -154,
+        39,   2524,     58,    -57,    119,      5,    343,   2873,
+      -278,   -787,    137,     62,   -169,   2049,   1476,   -325,
+       130,   -702,   2882,    -19,    310,   -258,   -135,     88,
+      -268,     69,     69,    695,  -1935,    815,    678,     44,
+      3085,    278,   -587,  -1326,    360,    145,    -17,     66,
+     -2475,   -594,    132,    358,    406,   -369,   -237,   3363,
+       329,   -424,     52,     49,    291,   -236,  -2332,   -261,
+        49,    -27,    170,   3656,   -214,   -603,    264,     60,
+       -87,    145,    116,    179,    190,    679,    339,   -340,
+      3272,    641,  -2631,    484,    159,    305,    290,    208,
+       226,     68,    102,   -145,   -356,    153,    647,  -2046,
+       937,  -1666,   1093,    -29,  -1161,    749,  -2360,    171,
+     -2185,    841,  -1406,  -1057,  -1764,   -300,   -205,    452,
+      2168,   -214,   -153,    291,   -106,     79,   1717,    -20,
+     -1771,    286,   -466,    686,    167,    137,      5,     43,
+      1075,  -2601,    261,    -86,   -333,   -724,    162,    186,
+         4,   -334,   -412,   -309,    888,   -114,    531,    297,
+      4284,    297,  -1695,   -212,     75,   -263,  -2313,    102,
+      -434,    352,  -1813,   -472,    114,   -185,      6,     66,
+      8061,    414,   -577,    672,   -152,    152,      1,     38,
+       -66,     48,    -35,     62,    -98,    -19,  -3762,     98,
+       242,    114,    359,   -162,    115,  -3038,    340,    253,
+      -526,   -144,     14,   -147,     28,   -352,  -5858,     46,
+      -597,   -392,    226,    -54,    -70,    -47,    -45,     16,
+        53,    137,    172,  -3017,    -22,   -163,   -267,  -3289,
+       -31,   -174,    110,    794,    425,     67,     58,    -72,
+      -156,   3937,   -585,   2116,     99,  -1115,   -257,    801,
+       270,   -329,   -257,    -18,    122,   -369,  -2196,   1746,
+      -305,    599,    800,    749,   1466,   -299,  -1519,   -255,
+      -233,    217,   -117,   -256,    301,   -249,   -327,   5530,
+        86,    135,   -784,   -137,    610,     -7,     55,     93,
+      -106,    -50,    267,   -229,    -26,  -1070,     13,    -75,
+      1733,   2929,   -130,   -713,     15,  -2144,    104,   -318,
+       282,     -8,   -285,   -468,   -124,     59,    520,    -78,
+      -332,   -654,  -5048,    212,   -388,     97,  -1523,    227,
+     -2545,   2159,   -127,   1020,     79,   -664,    403,    -31,
+      -356,     -1,   -436,    -86,     75,    610,   3048,    235,
+     -3133,  -1189,    -44,    -23,   -324,    260,    469,   -113,
+        22,     53,    525,    427,    469,   1016,    420,    493,
+     -1229,   -238,  -2671,    361,  -2745,    193,   -253,    -59,
+        15,     53,    -57,     36,   -144,    127,     25,     11,
+       -34,   6560,    -12,    -80,    -72,     70,    654,  -1135,
+       158,    279,    298,    746,   -190,  -1382,    138,    527,
+     -1504,  -2753,   -106,    -55,    225,     54,    136,     53,
+       506,    174,    268,   -533,    -43,   -416,   -196,   6266,
+       -81,     22,   -158,    350,   1177,   -728,    594,     34,
+      -368,   -226,   -584,    247,    804,  -1141,     78,   3923,
+       -53,    309,     58,    -45,  -7634,    -73,     39,   -152,
+        55,    -77,    -45,    -62,    -25,   -247,   -161,     28,
+     -2629,   -401,   -295,   -687,    298,  -3240,      0,   -251,
+         7,    -49,    494,   -198,    202,   2201,   -301,     83,
+        45,   -964,    256,  -1499,  -2394,     24,   -267,   -599,
+        46,    161,   -370,     81,    636,   3146,  -2077,   -964,
+       322,    400,   -635,   -688,   -630,    -92,   -235,    104,
+       -77,   -541,    511,   2722,    441,   2757,    952,    739,
+      -257,   -254,   -438,   -122,   -151,     12,    578,    -92,
+      -440,    -63,     93,   4971,   -499,    419,   1374,   -165,
+      -417,     64,    -13,   -235,   1080,    -77,    536,     68,
+      -842,   -772,   1627,   -471,  -1350,   -144,   2849,    219,
+       114,     68,    -55,    350,    -11,  -1334,  -3042,   1166,
+      -147,   -891,   -483,   1461,    339,    808,    362,   -101,
+     -2807,    -24,   -377,    518,   -438,    194,   -110,    194,
+      -826,   3380,    -81,    -30,    -43,    103,    -99,   1539,
+      -614,    -13,  -1154,    196,  -3122,   -521,   1454,   -319,
+       159,   -428,    722,   -208,    162,   1871,   2534,   2287,
+       946,    261,   -483,   -645,     26,   -170,    -31,     17,
+       164,    104,    -44,  -8192,    -20,     94,   -235,     56,
+        68,    -58,    380,    -25,   -170,     17,     16,   -154,
+        63,    477,   1280,    614,   -529,  -2347,   -360,    159,
+      1967,  -2085,    485,    335,    378,    178,   1633,   -437,
+       -46,     23,    640,   1465,    -91,   1279,  -1025,  -1007,
+      -236,   2632,   -257,    262,    177,   3029,  -3149,  -1001,
+       231,   -262,     87,   -243,    -68,   -597,    109,     62,
+      -264,     37,   -463,  -3105,   -633,    881,   1026,    -86,
+       417,    705,  -1144,    -68,  -2084,     46,    124,    -36,
+     -2461,    -73,   -126,   -303,   1079,   -358,  -2764,   -761,
+     -1454,   -245,    203,      0,   -179,   -117,   2571,  -4751,
+       -20,    194,    298,    258,    390,    270,    -36,    182,
+       152,    -56,    -97,    -47,    138,   -233,   -111,  -1490,
+      -490,   -329,    662,   -320,  -4697,    443,     66,    352,
+       203,   -114,   -119,    186,    649,   -106,     -5,   2280,
+      1132,   -376,   1168,    919,   1858,    271,  -1741,   -130,
+     -3388,    264,    618,  -2375,    260,   1279,    110,    732,
+       128,   -373,     54,   -182,     99,   -131,      9,     30,
+       -83,     27,    204,    109,   -306,   6903,    130,     -7,
+      -115,     92,   -241,    119,   -640,   -871,    -40,    372,
+       -68,   -147,  -1503,    -58,    920,   -466,    311,    144,
+     -3648,   -121,   -357,      5,   1968,   -737,  -1491,    596,
+       818,    122,    688,   -137,  -2415,   -368,    236,     71,
+      -597,   -193,   -395,    795,    855,    657,    -49,    844,
+     -3320,  -1921,    846,     17,   -293,    -17,  -1676,  -1826,
+      -138,    897,   -207,     -3,   1838,   -901,     86,    275,
+       964,    230,    510,    -10,   2879,   3949,    332,    289,
+       109,   -229,     18,    238,    244,    287,     44,    103,
+       367,     21,  -1134,   -378,   1338,   -828,   3500,      5,
+      1027,    475,    208,    654,    589,    -92,    236,    -85,
+      -115,   1095,  -2504,    827,   -885,   -806,   -155,   2112,
+      -346,   1120,   -350,   -911,   -234,    231,     55,     87,
+      1957,    601,    755,  -1248,    753,  -2726,   -481,   2038,
+        96,   -363,    309,    150,    299,   -561,   -698,  -1030,
+       118,   1224,   3240,  -1523,   1476,    342,   -688,    -76,
+       192,     -8,   -319,    350,    149,   -331,    155,   -436,
+       286,   -994,    160,  -2696,   -423,  -2798,   -135,   -108,
+     -2846,   -254,   3590,    350,    130,   -810,    463,   -123,
+        59,   -256,    251,   -750,    -76,     -8,  -1633,    150,
+      -931,   1958,   1523,  -2527,    239,   -287,    172,    332,
+       -13,    486,    247,    -26,    149,     59,    130,    265,
+        19,    209,   7220,    -23,    -99,    -69,    -66,    -70,
+       -54,    -75,     60,   -264,   -102,   1079,   -535,   1587,
+      -557,  -1499,    241,  -2596,   1157,   -140,    270,     33,
+};
+
+static const int16_t cb4448sm1[] = {
+      7894,   -331,    383,   -556,     63,   -371,    -23,     73,
+        46,   -145,    105,     43,   -199,    -52,    -85,    -85,
+        13,    -21,   -230,   7379,    268,   -243,   -460,    251,
+        73,     12,    115,    -18,   -247,    433,    -90,   -518,
+       962,      0,   -960,    184,   -305,  -2003,    276,   1696,
+      2418,    270,  -2140,   -215,   -534,   -389,   -403,  -3500,
+       416,    567,   -393,   -183,    253,   -100,   -285,   -107,
+       100,    281,   -527,  -2944,    -86,   2652,    311,   -785,
+      -811,   -283,    425,    -77,    393,    136,    170,   1290,
+      -765,    108,    676,   -213,  -1226,   -470,    427,   3499,
+       616,  -1211,   -226,    -37,     88,  -2792,    351,     78,
+     -2975,     99,    192,   1390,   -338,     47,     -8,     58,
+      -255,     50,    221,    -49,   -788,   -207,  -2122,   -167,
+      -692,    379,  -3239,   -965,   -698,   -463,    -45,     34,
+      1785,   1026,  -1107,    113,    124,   -258,   -277,   -714,
+      2764,   -178,   -200,    907,    -45,   -213,  -2575,   -530,
+      -112,   3616,   -128,     76,   -366,   -135,    -22,    -51,
+       125,   -100,    -79,    142,     54,    107,     87,    493,
+       -34,   -221,   -448,   -243,    994,    845,  -4656,   -105,
+      -487,     41,   -112,    349,  -4328,    -72,    513,   -112,
+      -685,   -470,   -138,   -541,    340,  -1505,    -24,     37,
+       169,   -405,   -434,  -2994,    -42,   -416,  -1927,   1551,
+     -1488,    420,    179,    -66,     14,     92,    147,    141,
+       497,    404,   -412,   2301,    336,  -2877,  -1845,   -948,
+      -784,    262,   -211,      6,  -1678,   -434,  -1433,   -727,
+      1254,    542,  -1430,   -302,   1558,    107,    617,   -833,
+      -369,   -178,   1682,  -2569,  -1232,  -1556,    -87,   -178,
+       400,   -178,   -427,   -124,    -63,    142,   -221,     33,
+      2880,   -227,   -356,   -466,  -3362,   -398,   -167,    164,
+       126,     59,     -1,      5,    212,     25,   2062,   -462,
+       -33,    -46,     45,   -201,    823,   -268,   -302,   3623,
+       389,    382,    136,    -30,    -64,      2,   -600,   3114,
+      2720,    273,   -588,   -235,   -313,   -141,     37,    -28,
+       355,    184,   -433,   -110,   -576,    -56,    134,   -623,
+      -271,  -2529,  -2753,    947,   1319,     -2,    620,     36,
+      -412,  -1986,    221,   -404,    514,   3223,   -106,   1497,
+      -368,   -167,   -142,   -366,   -125,     16,    142,   -435,
+      -160,   2845,   -153,    470,    387,   3117,    -75,   -375,
+       658,    259,    755,     -3,   3744,   -517,  -1446,   -667,
+      1372,  -1692,    117,    -96,    195,   -201,   -134,    -76,
+       179,     97,     71,   1887,    161,    365,    228,   1177,
+       235,   -834,    -48,   1667,  -1123,   2217,   -209,    100,
+      -219,  -2778,     81,   -579,   3421,   -326,   -492,   -233,
+        78,     32,    117,    -74,    -80,     85,   -282,    453,
+       500,    721,    800,     83,   -624,   1000,    165,    -20,
+      -516,  -4193,   -334,    107,   1221,  -1507,    -10,    523,
+        85,    -44,     21,     34,    199,   -106,  -2233,    525,
+      2138,     40,    -55,    -63,  -8179,    326,    333,   -152,
+       -27,    137,    212,    130,    -10,     76,    -61,   -113,
+      -544,   -179,   -187,      0,  -5308,    322,   -326,    513,
+       415,    375,    -92,   -354,     69,     77,     65,     93,
+      -352,   -165,  -1837,   1790,    914,   -276,   2215,  -1418,
+       343,    281,      4,    283,   4398,   1695,   -248,    153,
+      -166,    751,    822,   -406,   -456,   -251,    185,   -251,
+      -222,   -169,   -266,  -6323,    249,    -40,    -45,   -203,
+        47,    -83,   -621,   -174,    327,     30,    114,    -29,
+      -505,   -224,   1804,   1582,  -2292,   2102,   -746,   -421,
+       170,    438,   -171,    153,     84,   -157,  -2937,   -123,
+       -81,   -227,    -98,    263,   3531,     36,    105,   -479,
+       -94,   -357,    -22,   -124,    279,   -116,    543,    201,
+      -393,   -226,  -2255,   -133,   1613,   -123,   2687,     70,
+       191,    240,   -996,   -676,    606,  -1245,   -306,    413,
+      -272,   -539,    485,   3583,   -224,    432,    389,     31,
+      -888,    318,   -149,   -228,    764,   -426,   1608,  -2656,
+       254,  -2193,    252,    484,    -90,   -117,   -257,  -2210,
+      -156,    553,    559,    680,    298,    -16,   -519,   1172,
+      2172,   1288,   -113,    186,   -199,  -1415,    -83,  -1984,
+       667,  -1013,    344,   -399,   2889,  -1175,   -908,    186,
+       185,    -22,   -328,   3132,  -1166,    209,   -213,    386,
+      2140,    552,   1023,    719,    529,   -169,    421,    196,
+        76,   1995,    532,    -75,   2060,   -526,    396,   2974,
+      -264,   -348,    149,    586,     22,     97,   -337,   -252,
+       357,    103,  -2308,  -2578,  -1836,   -277,    346,   -314,
+      -989,    185,   -314,    102,     56,   3779,   -265,  -1029,
+       -12,   -126,   -431,    356,  -2493,    -86,    172,    116,
+        61,   -146,  -2220,    211,   -165,    233,   -327,     73,
+        -7,   -104,   -546,    253,  -2406,    361,   2252,    486,
+       675,   -177,   2643,    603,    300,   1123,   -642,    361,
+       684,  -2151,    569,  -1014,    120,    -50,    321,   3174,
+      3080,   -733,   -427,    299,    169,   -123,   -140,    -13,
+      -315,     21,   -120,    -24,    174,   -191,   -350,  -7842,
+      -145,   -169,   -419,    -15,    150,   -130,    -73,    162,
+        -9,     38,   -287,    109,    390,    147,    151,   1907,
+     -4243,      7,   -207,   -147,   -230,   -343,   -117,   -111,
+       107,    132,   1457,    -88,     -8,   -445,   -176,   -172,
+     -1799,   -813,    486,   1150,  -3026,   -168,  -2620,   -584,
+       178,   -543,  -1868,   -359,   -113,  -1783,    214,   -663,
+       473,    866,   -136,    169,  -3324,   -129,  -3404,   -249,
+       234,    422,    251,    340,   -343,    231,    134,    -42,
+        32,     64,   -209,     12,    236,   -267,   -419,      1,
+       260,   -109,   6508,    105,      7,   -273,   -123,   -107,
+      -152,   -274,   -157,     75,     74,   -201,     46,     37,
+       338,    -21,   -180,    208,  -6417,    794,    250,    -81,
+      -585,      4,   -119,   -314,    529,    219,    159,   -132,
+      -277,     76,   -613,   4933,     15,    213,   2461,    286,
+       542,    177,   2767,    389,    136,    750,    559,   -994,
+       684,    -12,  -2081,   -546,    -89,  -3733,    548,   -620,
+       675,    118,   -121,    190,    -52,     19,    -19,     25,
+     -1224,    344,   3094,  -2067,      7,    273,  -1268,   -375,
+      -297,   -201,    271,   -191,    123,      6,   -260,   2284,
+      -308,  -3062,    242,    668,   -221,   1146,   1218,    473,
+      -133,     82,     57,    112,  -1677,     78,   -229,    354,
+      -463,    763,   1628,   2243,   1386,   1630,   -145,    255,
+       -60,    228,    195,   -864,   2539,   -466,    985,  -3075,
+         2,    118,    221,   -395,   -450,   -256,   -158,    -32,
+     -3829,   2012,    -50,   -465,    146,  -1091,   -318,    271,
+       -12,    596,    160,    120,     92,   -209,   -335,    104,
+       -28,    689,    305,   -548,   -849,   1617,    605,    185,
+      -414,   3899,   -273,     51,    182,   -192,    121,    616,
+      1219,    414,   -959,  -4219,   1319,     60,    246,   -468,
+       -32,    225,    338,    -39,   1235,  -2079,   2250,    626,
+       121,    296,   -137,   -339,  -1870,    -47,   -397,    124,
+};
+
+static const int16_t fcb8l[] = {
+     -1239,  -1310,  -1240,  -1146,  -1337,   1303,   -482,   2215,
+      2026,   2222,  -1144,  -1188,  -1209,   2535,  -1111,   -844,
+      1485,    625,   1254,   1204,   5932,  -1116,  -1235,  -1208,
+      -801,  -1020,   -558,   1387,   1513,  -1079,   3220,   -896,
+     -1083,  -1166,   2246,  -1210,   -838,   -950,   -960,    764,
+     13941,  -1307,   -817,  -1253,   1850,  -1320,  -1361,  -1218,
+      -671,    780,   -839,  -1068,   -776,   2977,   -714,   -944,
+      -823,   -580,    357,    591,    302,  -1078,   -895,  -1020,
+      3116,  -1144,   1438,   -891,    -71,   1528,   -238,  -1297,
+     -1020,   4616,  -1185,   -514,  -1154,  -1157,   1901,   2372,
+     -1131,  -1289,  -1273,  -1289,  -1311,  -1331,  -1340,    439,
+       455,   2395,   -537,  -1180,   2409,  -1084,   -580,   1937,
+       846,    -51,    615,   1099,   3854,  -1177,   -912,  -1095,
+       656,   -995,   -647,   3298,   -976,   -436,  12323,  -1291,
+     -1187,  -1341,   4779,  -1368,  -1357,  -1317,   -985,   1407,
+      -513,  -1387,  -1224,  -1069,  -1218,  -1117,   -181,  -1209,
+      5376,   4256,    -22,  -1232,  -1173,   -834,  -1054,   -947,
+      -611,   -822,   -206,   5572,   -988,   1067,   -837,    738,
+      -332,    -38,    -59,    143,    248,    386,   -447,  -1233,
+     -1258,  -1169,   3653,  -1045,   -657,   -926,   2004,   2201,
+     -1164,   7042,  -1302,  -1313,   -812,    150,   -129,    305,
+       442,    742,  -1185,  -1293,  -1220,   -872,  -1304,  -1260,
+      -853,  -1293,   2962,   3011,   -178,  -1187,  -1087,   -896,
+      -895,  -1053,   3788,     59,   -169,   1632,  -1201,  -1289,
+      5263,   -896,    331,   -852,    218,    825,   1129,   1024,
+       -39,  -1186,  -1054,   1862,  -1198,   2010,  -1075,  -1005,
+       702,   1550,   4491,  -1055,   -890,   -645,   -987,   2465,
+       529,    194,    -72,    370,   1547,   -968,   -849,  -1153,
+      6459,  -1164,  -1061,  -1020,   -838,    125,   3698,  -1168,
+     -1066,   1882,  -1159,   -439,  -1017,   -759,    744,   1302,
+      -812,   -985,  -1002,  -1029,   -871,   3690,   -170,    604,
+       623,   1272,   6135,  -1012,  -1231,  -1066,   -927,  -1082,
+      2393,   -843,   1537,   1240,   -866,  -1161,   -866,   6639,
+      -994,   -860,   -264,   -298,    469,   1184,   -868,  -1262,
+      2167,  -1177,   2132,   -987,   -563,    969,   1145,   1508,
+      -735,  -1232,  -1090,  -1204,   1507,  -1101,   -393,    755,
+       975,   1246,   1944,  -1068,  -1169,  -1040,   -987,  -1301,
+      5488,  -1057,   3150,   1890,  -1133,   2725,  -1123,   -963,
+      1901,    260,   -484,    449,    564,   1144,    679,  -1118,
+      -989,   -702,   -556,    162,    689,    712,    673,    443,
+      -695,  -1247,  -1019,  -1065,   -406,  -1143,   1750,   -743,
+      2644,   2402,  -1171,  -1157,  -1059,   -823,   -688,   1314,
+      1458,    629,    857,    856,   -875,  -1316,   3470,  -1061,
+      -846,   -761,   -712,   -955,    978,   1967,   -980,   3517,
+      -994,   -953,   -903,     56,    228,    -30,    359,    560,
+      9926,  -1178,  -1056,   -627,   -952,   -481,  -1168,   -268,
+      -701,   -555,   -887,  -1212,   1768,  -1156,   -396,   -755,
+      -119,   1594,    949,   1201,   -844,   1734,   1312,   -331,
+      -500,   -280,   -125,   -219,   -139,    496,  -1121,  -1227,
+     -1145,   -215,  -1123,   -765,   -173,   4055,   1086,   1465,
+      -714,   -904,   -901,   -713,  -1073,   1233,   -797,    645,
+        58,    897,   -518,   -624,   -441,   -554,   1139,    549,
+       147,     72,    127,    428,  -1104,   -979,   2433,   1867,
+      -237,   -745,   -280,    110,    794,    631,  -1049,   1141,
+      -974,   -920,   -849,   -392,    634,    414,    614,    797,
+     -1162,  -1344,  -1192,  -1259,  -1079,   -912,   2717,   2548,
+      1847,   1920,  -1004,  -1091,  -1006,   -692,    -85,    -24,
+      1014,   1427,    751,   -584,   6057,  -1206,  -1072,   -795,
+      -921,  -1103,  -1157,   -623,   -818,   2641,   3121,  -1084,
+     -1095,   -939,   -664,   -694,    884,    555,    144,    593,
+      -874,  -1074,    417,  -1027,     -6,   -790,   1687,     80,
+      1018,    738,   -527,   -958,   -701,   -377,     -4,    155,
+       304,   -348,   -947,   -342,   2269,  -1040,   1124,   -494,
+       -76,     76,      2,    114,   -194,    348,    904,    466,
+      -577,   -717,    107,    -39,    -29,    158,    101,    149,
+      -968,   -921,    558,   -264,   -445,    138,   -121,    -33,
+       105,    243,   -478,  -1047,   -937,   -751,   -609,   -822,
+      -709,   -976,  -1006,   2800,  -1108,  -1292,  -1055,  -1272,
+     -1295,  -1152,    305,  -1144,    635,   2067,   -584,  -1135,
+      -663,  -1130,   -754,  -1009,   -937,   -515,   1473,    841,
+     -1235,  -1338,  -1305,  -1141,  -1109,  -1217,   -238,   1915,
+      3550,   2306,   -963,   -985,   -874,    763,   -826,   -694,
+        19,    391,    379,    776,   -582,  -1216,  -1285,  -1164,
+     -1276,  -1305,  -1273,   2631,   -579,   2487,   1058,   -655,
+      -808,   -878,   -910,  -1006,  -1122,   -590,   -663,    428,
+      2185,  -1125,  -1032,  -1076,   -873,  -1139,  -1029,   -477,
+      1720,   1238,  -1111,  -1311,  -1343,   1074,  -1328,  -1181,
+      -970,   -386,   2359,   1777,  -1045,  -1189,  -1117,  -1053,
+      -942,   -329,    501,   1237,    808,   1022,   -866,  -1048,
+      -678,   1597,   1528,   -262,   -256,    231,    418,    728,
+};
+
+static const int16_t fcb8s[] = {
+     -1022,   -858,   -773,    304,   -881,   -771,   -341,    937,
+       270,    420,   -684,  -1000,   -795,   -903,   -671,   -575,
+        14,   3327,    528,    893,    965,   -541,   -947,  -1027,
+      4008,  -1081,   -743,   -991,   -808,    933,  -1406,  -1173,
+      7513,   -824,   -213,   -797,   -648,    -40,    176,    217,
+     -1298,   6743,   -755,   -232,   -440,   -680,   -269,    -60,
+       -80,    -85,   -893,  -1044,   -726,   -733,   -834,   -641,
+       231,   -779,   -501,   1832,  -1296,   2548,   2754,     19,
+      -210,   -708,   -205,    -74,     18,     55,  -1225,  -1123,
+     -1239,   6991,   -689,    272,   -290,     56,    356,    675,
+      1623,  -1134,   -607,   1426,   -872,    511,  -1060,    408,
+       253,    423,   1960,  -1337,  -1152,   -985,   -924,   2020,
+      -398,    348,   4188,   1044,   -650,   -831,   2909,   2083,
+      -457,     -5,  -1037,   -964,   -128,    -40,   6019,   -858,
+      -937,   -559,   -624,   -601,   -411,    120,   -289,    412,
+     -1271,  -1351,   3858,  -1214,   2224,   -325,   -165,    535,
+       559,    386,   1868,    649,    269,    245,   -708,   -778,
+      -179,    -12,    101,    -12,  -1235,   -892,   -829,   2570,
+      -574,   -431,    170,    167,    492,    531,   -930,  -1093,
+     -1037,  -1177,  -1151,   -912,   -466,    303,   1601,   4089,
+     -1234,   3160,   -631,  -1090,   -741,   -274,    103,     13,
+       356,    289,   2709,  -1115,  -1011,   -965,   -948,   -563,
+      1939,    870,   1187,    550,  -1028,  -1217,   -726,   -954,
+      -694,   -753,   3729,    141,    518,    854,  -1102,   1138,
+      -947,   -620,   -379,   -436,     72,    449,    432,    428,
+     -1112,   1276,    544,   -334,   -445,    179,    -32,    -37,
+         9,     28,  -1252,   2983,   -963,   1256,    419,    -10,
+        17,    211,    218,    191,    126,   -942,   -691,   -529,
+      -533,   -193,   1216,    150,    389,    152,  -1191,   -987,
+      -942,   -860,   -463,   -705,   -159,    184,   1893,   1080,
+      1753,   -694,   -609,   -699,     61,    269,   -126,     93,
+       236,    380,   -527,   -966,   -334,    163,   -662,   3295,
+      -477,    591,    259,    638,    397,    181,   -598,   -129,
+        35,    -51,   -122,     64,    -32,    -98,  -1351,  -1140,
+      3372,   -753,   -776,    718,    513,    134,    420,    354,
+     -1128,   -546,   -743,    297,   1819,    -77,    179,     17,
+       181,    206,  -1028,  -1027,   -757,   -755,   -389,   1035,
+       227,    249,    315,    395,   -931,   -881,   1207,   -777,
+      -165,   -531,   -375,     73,    346,    332,  -1159,   -788,
+      1196,    959,   -432,   -337,    243,    176,    321,     -7,
+};
+
+static const int16_t fcb8m[] = {
+     -1379,  -1331,  -1277,  -1266,   -927,      0,   2552,   2575,
+       425,     48,   2568,    -26,   -841,   -762,   -679,   -562,
+      -420,    186,     68,     69,   -743,   -193,    266,     92,
+      1714,   -241,   -357,    -93,   -252,   -222,   -884,   -385,
+      2436,   -446,   -150,   -533,   -192,    -33,    226,      8,
+      -756,  -1180,  -1238,  -1258,  -1250,  -1147,   -764,    141,
+      3075,   4136,  -1255,  -1288,  -1202,  -1188,  -1222,  -1257,
+      -500,   1989,   4062,   1328,   -300,   -186,   -399,   -329,
+      -330,   -533,   -313,   2030,    193,   -128,   -933,  -1016,
+        66,   1648,   -228,   -321,    236,    114,    356,    212,
+      -677,   -826,   -784,   -670,   -484,   -423,   -188,    215,
+      2476,    652,   3424,   1991,    940,   -576,   -942,  -1038,
+     -1097,  -1161,  -1120,   -956,   -763,   -416,   2824,   1429,
+      -693,   -755,   -455,   -670,   -535,   -225,   4814,    116,
+      -940,   -953,  -1008,   -856,   -797,   -582,   -531,   -213,
+      -412,   2479,   -156,   -218,   -319,   -168,   -236,   -248,
+      -305,   -515,   -224,   -382,   -501,   -759,    139,   1789,
+      -258,   -343,   -167,    721,  -1014,  -1092,   -975,  -1070,
+     -1126,   -778,   -178,     36,    522,   5371,   -402,  -1351,
+     -1577,  -1662,  -1642,  -1560,  -1249,   -870,    602,   8968,
+     -1126,  -1102,  -1118,  -1072,   -946,   -511,    482,   1635,
+      1108,   2471,   -935,   -748,   -302,   -445,   -810,   -359,
+      1433,    -83,    336,   1834,   -712,   -773,   -752,   -609,
+      -391,    625,   2550,    403,   -447,    -18,   -261,     91,
+      5096,   -199,   -887,  -1018,   -728,   -930,   -921,   -684,
+       -22,   2422,   2118,   -417,   -757,   -789,   -732,   -794,
+      -785,   -664,   -627,    885,    471,    798,   -429,   -684,
+      -454,   -185,    185,    -26,   -990,   -369,   1048,    -25,
+       -98,    720,     41,    -60,     -3,    -92,   -790,   -147,
+       846,   4007,   -346,   -907,   -849,   -730,   -639,   -842,
+      9096,    617,  -1164,  -1275,  -1380,  -1396,  -1391,  -1364,
+     -1342,  -1080,    655,   5687,    505,   -818,  -1134,  -1125,
+     -1136,  -1123,  -1088,   -996,      3,     36,    -48,    -28,
+       121,    -55,    172,    -43,     21,    -74,   1537,    -69,
+       378,    -38,   -113,    159,   -149,   -609,   -693,   -796,
+      -715,    588,    376,   -744,   -659,   -316,    145,    448,
+       659,    320,    787,   -315,   -956,   -682,   -595,   -327,
+       146,    348,    837,    577,  -1011,  -1014,   -647,   -159,
+       679,    158,    294,    670,    507,    540,    418,    558,
+        12,   -674,   -901,   -897,   -827,   -682,    323,   2580,
+};
+
+static const int16_t fcb8sl[] = {
+     -1269,  -1637,  -1349,  -1672,  -1421,   2750,    212,   3563,
+       -74,   1555,  -1495,  -1148,  -1172,   1351,   -484,   -473,
+      1418,    557,    899,    635,   6124,  -1140,  -1154,    783,
+     -1444,  -1509,  -1041,   1793,   4459,   1325,   2055,   -921,
+      -794,   -713,   1625,    -50,     78,   -159,    361,    855,
+     10282,  -1533,  -1105,  -1582,  -1704,  -1697,  -1440,  -1001,
+       864,   2038,  -1347,   -847,  -1419,   1474,  -1369,  -1189,
+     -1125,   -655,   -134,    950,  -1398,   -222,  -1498,  -1262,
+      2597,    729,   2521,   -544,    457,   2058,   3821,  -1568,
+     -1577,   2013,  -1717,  -1620,  -1292,   2771,   2559,   4942,
+     -1497,  -1576,  -1724,  -1550,  -1775,  -1734,  -1097,   -635,
+      1934,   2706,  -1399,   -994,   1685,  -1142,   -511,   1595,
+      -275,    861,    484,    958,  -1374,   -764,  -1105,  -1493,
+     -1678,  -1630,   -521,   5138,     53,   1331,   4909,  -1376,
+      2134,  -1638,   1562,  -1565,  -1487,  -1625,   3232,   4742,
+     -1017,  -1353,  -1212,  -1585,  -1309,  -1139,    -71,   -820,
+      5928,   2987,   -641,  -1314,  -1198,  -1182,  -1005,   -542,
+     -1287,  -1210,  -1103,   6865,  -1130,   1375,   -884,   1241,
+      -532,   -173,    -68,     15,    309,    192,  -1128,  -1107,
+      -849,  -1343,   2233,  -1281,   -535,   -679,   3878,   1865,
+     -1427,   4508,  -1022,   -747,  -1117,  -1104,    -33,    669,
+      1216,   1482,  -1360,  -1075,  -1483,  -1390,  -1366,   -754,
+     -1042,   -766,   3467,   -624,   -968,  -1101,   -393,   -890,
+      -447,   -995,   2346,   -909,   -784,    977,  -1141,  -1201,
+      5256,  -1552,   -536,  -1419,      0,    596,    556,   1654,
+     -1124,  -1225,   -830,   1267,   -719,   1791,   -546,   -297,
+       978,    378,   2674,  -1261,  -1159,   -951,  -1027,   2537,
+      -470,   -360,   -268,   1098,  -1154,  -1513,   -729,  -1455,
+      5671,  -1236,   -800,   -874,   1630,   1273,   1909,   -623,
+      -724,   1417,   -559,   -326,   -257,   -189,    265,    220,
+      -284,  -1302,  -1272,  -1223,   -842,   4338,   -934,  -1001,
+      -495,   2944,   4295,   -924,  -1004,  -1097,  -1024,   -328,
+      1736,    106,    452,    158,  -1024,   -541,  -1296,   4376,
+     -1117,  -1224,   -843,   1097,   1121,   1251,   -829,  -1374,
+      2292,  -1505,   1850,  -1153,   -943,   -979,   -534,   1444,
+     -1510,  -1494,  -1147,  -1397,   1535,   -794,    -21,   1313,
+       638,   1015,  -1072,  -1275,  -1166,  -1602,  -1618,  -1379,
+      4541,   -226,   2169,    888,  -1369,   2392,  -1087,   -948,
+      1074,    674,    384,    124,    500,    749,    398,  -1091,
+      -721,   -114,    -15,    413,    200,    135,    290,    189,
+     -1185,  -1188,  -1339,  -1549,   -871,   -574,   2333,   -346,
+       554,   3773,  -1247,  -1531,  -1408,  -1310,  -1007,   2861,
+      2465,    608,   1080,   1224,  -1103,  -1477,   1884,  -1412,
+      -904,  -1473,   -846,   -188,    782,   2049,  -1473,   1531,
+     -1530,  -1459,  -1546,  -1260,   -856,   1191,    652,    933,
+      5072,  -1456,  -1653,   3759,  -1751,   -531,  -1391,   4297,
+      -374,   -751,  -1570,  -1242,   1461,  -1286,   -913,   -621,
+      1768,   1246,   1291,    779,  -1360,   1641,   1122,   -629,
+      -328,   -197,    241,    359,    560,    536,  -1474,   -506,
+     -1523,    298,  -1551,  -1254,   -985,   3603,   4317,    958,
+      -885,   -241,  -1159,   -930,  -1249,   1490,   -825,    274,
+       347,    307,  -1060,  -1027,   -809,  -1063,   1554,   1708,
+      -242,    -23,    424,    804,  -1317,   -853,   1571,   1898,
+       239,   -556,    298,   -161,    777,    765,  -1464,   1053,
+     -1198,  -1156,   -917,      0,   1460,    447,   1178,    629,
+     -1455,  -1591,    296,  -1785,  -1694,  -1631,   3669,   3819,
+      3437,   3274,   -956,   -666,   -874,   -284,   -858,   -202,
+      -687,   1728,   -512,   -951,   4692,  -1360,  -1242,  -1188,
+     -1513,   -449,  -1566,  -1515,  -1226,   3857,   1246,  -1225,
+      -860,  -1068,   -748,    -27,    380,   1190,    591,    552,
+     -1391,    194,   -763,   -463,    331,   -265,    702,    181,
+       290,   -145,   -838,  -1359,  -1381,  -1569,  -1399,  -1088,
+     -1357,  -1295,   -486,   -612,   1638,   -586,   1458,   -774,
+      -223,   -620,   -104,    189,    344,    269,   1555,   1428,
+      -867,   -621,   -294,   -206,     32,    235,    261,    161,
+     -1021,   -105,    654,   -235,   -282,     -7,    189,   -159,
+      -218,    113,  -1096,  -1318,  -1256,  -1335,   -931,   -476,
+     -1041,  -1199,  -1134,   2781,  -1479,  -1222,  -1397,   -867,
+      -815,   -661,    740,   -240,   1158,    735,  -1435,  -1003,
+       351,   -990,   -245,    -72,   -347,    -72,   1408,    634,
+     -1697,  -1727,  -1534,  -1716,  -1436,   -102,    402,   1518,
+      1903,   1311,  -1477,   -930,   -355,    508,   -162,     21,
+       -46,    454,    387,    173,  -1312,  -1284,  -1486,  -1172,
+     -1356,   -965,  -1106,   1760,   -670,   2163,    -70,    417,
+      -559,   -667,   -545,   -945,   -429,   -363,    157,   1280,
+      2059,  -1319,  -1291,   -975,  -1354,  -1249,   -780,   -476,
+      1410,   1252,  -1193,   -927,  -1462,    871,  -1281,  -1327,
+      -900,   1540,   1531,   1227,  -1651,  -1334,  -1073,   -752,
+      -154,    710,    830,    773,    279,    307,  -1294,   -796,
+      -761,   1012,   1583,   -420,   -177,   -323,    154,    582,
+};
+
+static const int16_t fcb8ss[] = {
+     -1481,  -1069,  -1082,   -726,   -818,   -550,   -417,    343,
+       489,    275,   -814,   -510,   -712,   -933,   -558,   -236,
+        32,   3051,    451,    301,   -414,   -237,   -683,   -599,
+      3627,   -445,   -232,     56,     58,    112,  -1226,   -639,
+      4096,   -644,   -226,    -23,     90,    162,    313,    104,
+     -1385,   5607,   -428,   -860,   -447,   -265,   -145,   -132,
+       115,   -200,  -1349,  -1280,  -1216,  -1046,   -657,     43,
+      1333,    831,    675,   1174,  -1394,   2288,   1840,   -682,
+      -497,   -256,     22,     22,    261,     70,  -1369,   -826,
+      -975,   2286,   -329,   -267,    142,     36,    437,    313,
+      1570,     52,   -470,    622,   -244,   -247,   -114,     22,
+      -117,   -541,  -1167,   -596,   -809,   -929,   -669,   -327,
+       102,    516,   2790,    597,  -1317,   -870,   1327,    987,
+       -25,    391,    -48,    -82,    209,   -242,   4424,   -311,
+      -396,   -765,   -382,   -336,   -365,   -414,    -74,    -13,
+      1127,   -588,   1363,   -714,    368,   -450,   -390,   -364,
+        84,    139,   1864,   1881,    -15,   -790,   -281,   -286,
+        38,   -186,    -31,   -238,  -1249,    262,   -841,    731,
+      -414,    -61,   -274,    280,    100,    557,   -841,   -775,
+     -1007,  -1063,   -687,   -374,   -360,     31,   1048,   3471,
+     -1385,   2464,   -840,  -1105,   -714,   -400,     56,    445,
+       588,    427,   1785,  -1093,   -783,   -847,     41,    -23,
+       465,    392,    382,    428,   -518,   -249,    -58,   -791,
+      -689,   -581,   3146,   -183,    296,     66,  -1243,   1059,
+     -1076,   -874,    416,    544,    253,     66,    168,    211,
+     -1388,   1253,    138,   -727,   -509,    905,    319,   -297,
+        67,   -525,  -1470,   2237,    -87,    547,    556,   -239,
+        90,   -147,   -114,   -302,  -1017,   -824,   -585,     25,
+         0,     62,   1422,   -155,    -41,   -320,  -1125,  -1069,
+     -1134,   -783,   1129,     45,    183,     47,    716,    672,
+       409,  -1169,   -910,   -447,    -34,     79,     95,    455,
+       504,    381,    342,   -877,   -506,   -812,   -805,   3031,
+      -249,   -518,    -69,    564,    243,    261,   -332,   -434,
+      -173,    -37,     61,     45,     -5,      6,  -1433,  -1009,
+      1428,   -951,   -582,    154,    143,    625,    383,    387,
+     -1392,  -1222,   -578,    229,   1294,    218,   -142,    355,
+      -149,    201,  -1341,  -1135,   -857,   -767,   -273,   2059,
+       255,    578,    350,    315,  -1041,   -617,    254,   -504,
+      -255,    -96,   -537,   -396,    363,   1074,  -1361,    484,
+       538,   -789,   -704,   -447,    200,    521,    213,     90,
+};
+
+static const int16_t fcb8sm[] = {
+     -1183,  -1170,   -867,   -948,   -746,    492,   1531,   1412,
+       524,     82,    590,   -994,   -916,   -859,   -680,     12,
+       742,    961,    230,    255,     34,     38,   -176,     -1,
+      1880,   -240,   -769,   -531,    269,    -32,   -772,   -494,
+       757,   -583,   -677,   -281,    717,    440,    561,     91,
+     -1121,  -1054,  -1189,  -1100,   -745,   -417,    -61,    302,
+      3079,   1817,  -1384,  -1479,  -1477,  -1509,  -1077,   -323,
+       902,   2348,   1464,   1038,   -487,   -179,   -447,   -311,
+      -296,   -439,   -172,   2166,    245,    -28,  -1050,   -390,
+      -238,    633,    302,   -335,    843,    -52,    185,    230,
+      -110,   -433,   -690,    148,     63,   -289,   -404,   -469,
+      1948,    245,   2016,   1337,   -341,   -554,   -617,   -457,
+      -436,   -459,   -400,   -520,   -661,     -7,   1078,    971,
+      -326,   -332,    -23,   -749,     83,   -104,   2106,   -947,
+      -867,   -883,   -705,   -433,    -35,    164,    427,    646,
+      -924,   2196,   -656,   -798,   -282,    217,   -227,    134,
+       446,    -15,   -584,     33,    185,   -571,   -159,   1852,
+      -405,    -94,    -61,    -83,   -329,   -516,   -394,   -450,
+      -173,   -140,    -54,   -156,    226,   1850,   -752,  -1304,
+     -1378,  -1275,  -1017,   -680,   -337,    356,   1131,   4143,
+     -1120,  -1253,  -1269,   -860,     90,    973,    152,    886,
+       609,   1454,    -29,     36,   -117,   -815,   -651,   -346,
+      2085,   -414,     24,    -93,   -235,  -1103,  -1132,   -758,
+       -98,   1497,   1285,   -289,    -34,    402,   -646,    637,
+      2147,   -677,   -350,   -266,   -232,    -61,   -199,   -359,
+       167,   1546,    816,   -453,    -35,   -251,   -468,   -491,
+      -371,   -593,   -878,   1445,   -795,    651,    108,   -155,
+      -201,    -14,    250,   -271,   -732,    793,    154,   -288,
+       -86,     16,    557,    642,   -592,   -587,    -87,   -365,
+      -309,   1753,    -40,     95,   -529,    -87,   -214,   -234,
+      4999,   -466,   -755,   -800,   -785,   -722,   -532,   -703,
+      -526,   -465,    591,   3937,   -229,   -804,   -808,   -698,
+      -576,   -613,   -506,   -725,     10,     13,   -117,    -55,
+       101,     52,    125,    -76,    -25,    -28,   1469,   -245,
+         8,    -25,     65,    -53,   -262,   -282,   -411,   -588,
+      -667,   1374,    304,   -787,   -661,   -675,     55,    320,
+       720,     -4,    366,   -103,   -136,   -332,   -314,   -293,
+       -38,    127,    151,    380,  -1330,  -1338,   -618,    -40,
+      1284,   1500,    466,   -515,    105,   -161,     19,    697,
+      -417,   -559,   -317,   -712,   -756,   -567,    754,   1481,
+};
+
+static const int16_t fcb11l[] = {
+     -1291,  -1237,  -1175,  -1186,  -1139,    524,   1225,   1464,
+     -1042,   -721,   -901,     41,   -728,    822,   -657,   1078,
+      -483,   1530,   -489,   1253,    926,   -326,    404,     89,
+     -1191,  -1170,  -1237,   1633,   1493,   -465,    986,   1184,
+      -857,   -832,   -300,   -811,   -936,   -667,   -254,    492,
+      4044,  -1136,   -983,   -855,   -592,   -199,    383,    876,
+      2076,  -1042,  -1019,   -729,   1435,    -25,     64,    845,
+      -991,   -921,   -861,    916,   -402,   -551,    236,    429,
+      5253,  -1233,  -1268,   -414,   1793,   -463,   -569,   1693,
+     -1197,   6322,   -887,   -211,   -945,   -540,    626,    903,
+      -993,   1500,   -490,   1445,   -764,   -136,    321,    548,
+       462,   -228,    127,   -322,    481,   -183,     88,    155,
+      -809,   -844,   -959,   4011,   -581,   -232,    330,    986,
+      -900,   -916,  -1069,   -866,   -979,   -439,   4016,   1558,
+     -1023,   2121,   1717,   -612,   -588,   -446,    223,    430,
+      2567,   -972,   2118,  -1030,   -900,   -664,    180,    858,
+      3232,   -991,  -1132,   2119,   -446,   -548,   -258,    895,
+      -962,   -184,   2639,   1081,   -661,   -222,    292,    530,
+      -952,   1767,   -213,   -701,   1079,     37,    131,    489,
+      -875,   -749,   3167,   -776,   1247,   -109,    -83,    636,
+     -1146,  -1070,  -1001,  -1064,   -942,   2891,   1137,   1585,
+     -1314,   -632,  -1179,  -1105,   1101,     51,   2038,   2036,
+      -926,   -727,    180,   1515,   -566,   1191,    101,    595,
+      2247,   -364,   -315,   -105,   -130,    -79,    121,    210,
+      7994,  -1302,   -898,   -785,   -758,   -777,     31,    415,
+       744,   -652,    688,   1226,   -649,   -605,   -268,    314,
+       611,    662,   -240,   -411,   -698,   -434,    377,    339,
+       953,   -810,   -931,   1054,   -484,   -298,    721,    522,
+       922,  -1046,   -952,   -871,   -618,   -270,    419,    635,
+      1006,    129,   -838,   -724,    220,    481,    253,    329,
+       205,   -456,   -724,    675,    598,    332,    -14,    291,
+     -1016,   -695,    542,   1270,    498,   -456,   -113,    362,
+      -547,  -1068,  -1178,  -1261,  -1161,   -905,    390,   2204,
+     -1056,  -1102,   5611,  -1100,  -1076,   -902,    360,    978,
+      -538,   -286,   1253,   -430,   -457,   -148,     -1,    -60,
+     -1116,   -955,   2869,   -926,   -680,   1111,    706,    842,
+     -1311,  -1275,  -1150,   -236,    675,    897,    758,    912,
+      1886,  -1115,   -999,    -84,   -588,   2190,   -171,    739,
+      -737,    150,   -902,   -854,   -917,    334,    557,    534,
+      -851,    -39,    -25,    214,   -136,    -73,    263,    234,
+     -1021,   1332,   -543,   -655,   -712,   -651,     80,    479,
+      1555,   1933,   -707,   -485,   -206,    139,    312,    405,
+      2472,  -1172,   -945,   -939,   -713,    568,   1421,    684,
+        70,  -1263,  -1235,    586,   -195,  -1065,   -449,   3182,
+     -1143,    529,   -926,   -558,    419,    390,    375,    563,
+     -1090,   3370,   -688,   -528,   -346,    136,    317,    615,
+      -803,   -977,  -1082,   -806,   3607,   -443,   -156,   1130,
+     -1288,   1585,  -1218,  -1226,   -979,    359,   1555,   1402,
+      -341,   -416,   -480,   -360,   -415,    542,   -148,   -322,
+     -1095,  -1074,    762,   -864,   -634,   1770,    340,    466,
+     -1040,   -834,   1508,   -707,    143,     74,   1418,    905,
+     -1094,   -710,   -549,   -860,    373,   1492,   2024,    741,
+      -938,   -910,   2661,  -1087,  -1105,   -901,    383,    906,
+       755,   -819,    581,   -612,   -420,    305,    344,    363,
+      -356,   -991,   -845,  -1051,   2112,   1738,    554,    954,
+     -1028,   -943,   -892,   -896,   -236,   -674,   1076,    679,
+      -611,  -1099,   -859,   -914,   -444,    910,    491,    709,
+     -1063,    775,    496,   -669,   -304,    672,    261,    496,
+     -1086,   -963,   1037,   -639,   -134,   -577,     33,    607,
+     -1070,   -649,    730,   -748,   1884,    -18,    346,    627,
+     -1089,  -1118,   -955,    751,   -690,    606,   1204,   1037,
+     -1016,  -1095,    473,   -919,  -1036,   -685,   1744,   1216,
+      -834,   -916,   -920,   -634,   1086,   -474,    161,    620,
+      -997,   -899,    -25,   -499,    399,    405,    163,    401,
+};
+
+static const int16_t fcb11s[] = {
+     -1148,  -1134,  -1000,   -585,    715,    774,    626,    650,
+      2109,   -898,   -729,   -239,   -213,    847,     77,    371,
+      -902,   -790,   1853,   -871,   -816,    163,    295,    377,
+      1718,  -1070,   -840,   -791,   1612,   -129,    144,    450,
+      -830,   1909,   -539,    803,   -411,   -188,    122,    148,
+      1202,    705,   -696,   -578,   -213,    -25,    126,    142,
+      3309,  -1083,   -865,   -771,   -470,   -237,    980,    521,
+       428,   -995,  -1003,   3088,  -1000,   -455,    320,    503,
+      -615,   1746,   -751,   -734,   1092,     31,     97,    225,
+     -1175,   2287,   1278,   -421,   -315,     91,    130,    120,
+     -1203,   4211,   -970,   -878,   -228,     71,    327,    288,
+     -1012,   -850,   1471,   -732,   1228,    201,    146,    271,
+      -868,   -528,   1196,    744,   -186,     85,     38,    153,
+     -1081,   -895,   -742,   1014,   1110,     66,    237,    335,
+     -1012,  -1137,   4357,  -1062,   -569,    377,    268,    445,
+      1203,   -717,   1070,   -541,    -72,    -29,     91,    104,
+      6448,  -1148,  -1069,   -810,   -659,    118,   -284,    300,
+     -1085,   -940,   -214,   -621,   -781,   -622,   1789,    711,
+     -1165,   1643,   -890,   -809,   -533,    148,    384,    373,
+      -910,   -986,   -855,  -1032,   3647,   -478,   -132,    713,
+        -3,   -674,  -1036,   -956,   -899,   2698,    629,    665,
+      -764,  -1066,  -1173,  -1058,   -692,   -144,   1114,   3195,
+     -1012,   -643,   -670,   1547,   -576,    351,    251,    273,
+      -950,    563,   -742,    248,   -149,    514,    100,    185,
+      -193,   -616,   -655,    255,   -364,   -323,    172,    256,
+       308,    228,     16,   -187,   -243,    219,     88,     53,
+     -1024,    664,    450,   -416,   -189,   -239,     43,    102,
+       -64,   -499,   -159,   -400,    905,    -64,    -68,     46,
+     -1055,    -77,   -813,   -661,     59,    -77,    226,    321,
+      1224,   -553,   -436,    793,   -155,    -83,     -5,     72,
+      -652,   -897,   -157,   -579,   -539,    846,    181,    318,
+       782,   -967,   -802,   -569,     -6,    364,    540,    513,
+};
+
+static const int16_t fcb11m[] = {
+      -453,  -1087,  -1133,  -1125,   -852,   -158,   1152,   3313,
+      1015,   -444,   1085,   -465,   -317,   -298,   -471,   -238,
+      -647,   1426,   -241,    149,   -300,   -169,    -19,   -228,
+      3282,   -269,  -1025,  -1069,  -1097,  -1071,   -539,   1303,
+      1111,   -933,   -741,   -801,   -553,     98,    393,   1031,
+      -786,   -729,   -835,   -810,    -78,   1569,    631,    944,
+      1031,    651,   -409,   -397,   -346,   -221,    -99,   -216,
+       -88,   -211,   -419,    193,   1298,    196,   -221,   -879,
+     -1036,  -1303,  -1282,  -1052,   -575,    283,   3110,   1337,
+       489,   -463,   -640,    112,    341,   -322,    261,    266,
+      1646,   -817,  -1256,  -1273,  -1217,  -1031,   -142,   3691,
+      3012,   1564,   -289,   -830,   -970,  -1032,  -1075,   -989,
+       556,     52,   -588,   -589,   -613,   -748,   -352,   2054,
+       -69,   -785,   -718,   -499,   -141,    192,   1396,    446,
+        -3,   -514,   -612,      3,    171,   1067,   -114,   -109,
+      -812,   -893,   -776,   -342,   1428,    421,    438,    552,
+      -933,  -1143,   -207,   1312,    791,    166,   -198,    -79,
+      -632,   1122,   -537,   -620,    450,     97,    -85,    174,
+      1760,    123,   -168,    485,    -77,   -567,   -776,   -952,
+      -758,  -1176,  -1322,  -1355,  -1207,   -928,   -177,   6229,
+      -413,    261,   -327,   -848,   -725,   -395,    849,   1533,
+      -201,   -124,   2976,   -335,   -703,   -674,   -727,   -949,
+      -521,    209,   1004,    838,     56,   -477,   -751,   -603,
+      -922,   -615,   1832,   -448,   -329,   -148,     73,    467,
+      4991,    -86,   -809,   -928,   -951,   -956,   -819,   -751,
+      1841,   -790,   -712,   -116,   -113,    -91,      0,   -388,
+      -729,   -196,    758,   -377,     68,     85,    428,    -35,
+        -5,      2,     -9,     18,    -31,     53,    -23,     26,
+      -896,   -445,   -188,    818,   -347,    -44,    502,    578,
+       101,   2968,    269,   -724,   -702,   -747,   -719,   -673,
+      7587,     68,  -1171,  -1377,  -1441,  -1455,  -1473,  -1178,
+       699,    585,     15,   2257,   -503,   -940,  -1085,  -1288,
+};
+
+static const int16_t fcb11sl[] = {
+     -1502,  -1463,  -1336,  -1177,   -367,     89,    475,    867,
+       550,    820,   -805,   -580,   -803,    -89,   -817,   1691,
+      -304,    120,     36,    564,    409,   -525,   -820,    362,
+      -969,   -870,   -605,   1983,    993,    722,   1505,   1101,
+      -842,   -848,   -918,   -379,    -71,    257,    499,    607,
+      1619,   -956,  -1024,   -869,   -744,    -74,    795,    684,
+       532,    634,  -1360,   -818,     49,   -981,    111,   -473,
+      -718,   -477,    377,    710,  -1399,  -1105,  -1152,  -1024,
+      2426,   -356,   -191,   1079,    911,   1164,   -809,   -791,
+      -919,   2731,   -851,   -400,   -113,    242,    508,    847,
+     -1229,   1199,   -910,   1127,   -686,   -383,     26,    352,
+       536,    646,   -790,  -1243,  -1103,  -1170,  -1132,  -1065,
+      -788,   -521,    161,   3842,  -1098,   -883,  -1052,      8,
+     -1103,   -747,   -552,   -480,   -241,    820,   3392,   -770,
+      -770,   -724,   -588,   -426,   -153,    426,    639,    724,
+      1626,   -713,   1157,   -736,   -492,   -512,   -160,    461,
+       569,    583,  -1351,   1332,  -1222,  -1358,    240,   1541,
+      -724,    612,   1583,   1194,  -1061,   -990,   -671,   -969,
+      -952,   2368,   -442,   -413,   1933,   1023,   -144,   -283,
+      -992,   -940,    983,   -232,    818,    341,    502,    549,
+     -1420,  -1268,  -1279,  -1213,   -621,   2019,    685,   1948,
+      1264,   1200,  -1293,   -664,    392,   -848,    866,   1191,
+      -220,     95,    450,    640,  -1334,   1098,   -751,   -701,
+      1296,   -347,    -92,    233,    532,    599,   -952,   -694,
+      3085,   -908,   -256,   -494,   -177,    123,    809,    941,
+        18,  -1089,   -801,    303,   -761,     11,    632,    288,
+       476,    518,   -241,  -1138,  -1068,   -869,    292,    121,
+       -26,    -96,    457,    548,   -106,   -784,    930,   -700,
+      1842,   -812,   -617,   -307,    430,    655,   -698,   1157,
+       947,   -803,   -662,   -743,    -49,   1120,    348,    578,
+       855,  -1049,   -753,    -67,    710,   -347,    -28,    694,
+       411,    468,    -61,    239,     23,  -1072,   -757,    477,
+      -658,   -362,    239,    576,  -1479,  -1279,  -1286,   -677,
+      -939,   -722,   3217,    338,   1562,   1566,    925,    917,
+      -697,   -708,    645,   -447,   -280,    714,    503,    552,
+     -1050,  -1021,    889,   -956,   -934,    705,    457,    616,
+       556,    667,  -1331,    -51,   -256,    -48,   -234,    240,
+       757,    -74,    148,    356,  -1278,   1538,    234,   -372,
+      -472,   -221,   -424,   -494,    170,    551,    216,    294,
+      -885,    231,   -263,    334,    -64,    -54,    291,    350,
+     -1140,  -1074,  -1199,  -1374,  -1278,   -845,   -547,    667,
+      4544,   1922,   -899,   -930,   -954,  -1120,  -1092,   1156,
+      1889,   -404,    259,   1114,   -956,   -836,    881,   -316,
+      -977,   -860,    202,   -249,    121,    816,  -1188,   3644,
+      -829,   -876,   -670,   -473,   -161,    420,    851,    886,
+     -1014,   1191,   -938,   -958,   -864,    741,    241,    957,
+       288,    629,  -1155,   -898,   1104,   -789,     28,   -867,
+      -580,   2588,    836,   1234,   -953,   -749,    934,   1137,
+      -310,   -177,   -113,    244,    532,    424,   -341,   -602,
+      -880,  -1105,   -303,   -381,   -527,   1943,    126,    759,
+     -1277,  -1037,     59,   -783,    485,   -589,   1341,    737,
+       488,    709,  -1473,  -1208,  -1082,    589,    791,    735,
+       447,    322,    835,    731,  -1116,   -681,   -592,    704,
+       520,   -545,   -104,    -24,    263,    458,    632,   -721,
+     -1086,  -1223,  -1150,   -866,   1537,   2815,    123,   1097,
+     -1238,   -861,  -1217,  -1238,  -1261,   -914,   1165,    422,
+       711,    883,  -1196,   -972,   -428,   -230,    171,      8,
+      -448,   1195,    445,    440,   -413,   -139,   -375,   -568,
+      -781,   -520,    611,   -586,    881,    589,   -724,    972,
+      -907,   -794,   -819,   -641,   1650,     66,    254,    703,
+     -1380,  -1168,   -967,    676,   -765,   -537,    578,   1542,
+       687,    833,   1151,   -811,   -948,   -995,   -246,   1301,
+      -377,    262,    632,    652,   1530,   -679,   -682,    993,
+      -666,   -457,    -72,    -20,    317,    516,    861,   -528,
+        24,   -579,   -386,     53,    526,    -76,     66,    345,
+       -59,   -612,    165,   -181,    -98,    -34,    -66,    286,
+        95,    108,  -1118,   -147,    643,  -1055,   -768,   -502,
+      -587,     27,   2113,    811,  -1219,   -947,   -811,  -1188,
+      1143,   -609,   -753,     88,   2844,   1424,  -1428,  -1082,
+     -1273,   1086,  -1206,  -1171,    279,   -510,   2325,   1757,
+     -1437,    654,  -1278,  -1267,  -1117,   -950,    779,   2205,
+      1150,   1101,  -1484,  -1009,  -1199,  -1416,  -1215,    657,
+      -737,    634,   1266,   1742,  -1445,  -1193,  -1358,  -1158,
+     -1015,   -995,   -655,   4035,   1966,   1903,  -1069,    954,
+     -1099,  -1171,  -1029,   -818,   -576,   -104,   1390,   1069,
+       559,   -914,  -1034,  -1152,   -987,   -582,   -222,    394,
+      1204,    775,  -1464,    -51,   -959,  -1005,   -452,    347,
+       -94,      1,    525,    595,  -1324,  -1226,  -1102,   -825,
+      -927,   -776,   -582,    175,   1675,    632,   -859,     28,
+      -914,   -209,   -468,   -625,   -230,    646,    579,    446,
+};
+
+static const int16_t fcb11ss[] = {
+     -1351,  -1229,  -1174,   -767,   1403,    182,    532,    445,
+       415,    610,  -1095,   -771,  -1142,   3221,   -803,   -680,
+      -302,    318,    441,    438,  -1188,   1145,   1552,   -528,
+       887,   -547,   -429,    124,     99,    128,   -768,   1049,
+      -562,   1121,   -593,    -96,   -105,    105,    251,    154,
+      1684,   1598,   -635,   -685,   -177,   -211,   -268,    234,
+      -118,    -49,   -719,   -873,  -1092,   -985,   -678,   -406,
+      -234,    407,    653,   3195,    991,   -584,   -874,    -14,
+      -683,   2964,   -769,   -450,    287,    350,    853,   -803,
+      -574,   1761,   -410,    -60,   -230,    -78,    -21,     19,
+     -1271,   4435,   -673,   -790,    110,   -243,    -81,    147,
+       191,    145,   5571,   -611,   -634,   -699,   -195,   -281,
+      -249,   -302,   -272,    -67,   -893,   -656,   -745,   -697,
+      -550,   -639,   -409,   3085,    383,    798,   -311,   -340,
+      -564,   -787,   3628,   -332,   -510,   -219,    465,    351,
+      -747,  -1084,   -972,   -727,   -404,   -630,   -176,    437,
+      3352,    978,   -886,   -751,   -767,   -580,   -693,   -942,
+      -803,   -158,    -36,     -3,   -966,   -674,   3075,   -926,
+      -172,     -9,    -40,    111,    169,    212,    181,   -811,
+      -715,   -986,   -521,   -686,   3915,     18,    -58,    499,
+       210,  -1187,   -903,   -915,   -522,   1038,    477,    788,
+       290,    412,  -1010,   -791,   -700,   -710,     34,   1774,
+      -256,     96,    131,    241,  -1251,   2086,     -5,   -765,
+      -446,    141,     93,    160,     88,    129,  -1153,   1171,
+     -1192,  -1073,   -391,   -187,    206,    416,    444,    648,
+       707,   -542,   -504,   -750,   -623,   -648,    776,    692,
+       165,    330,   1112,  -1199,   -876,   -428,    949,     65,
+       250,    104,    108,    173,   2147,   -905,   -846,   -540,
+      -376,   -131,   -113,    124,    314,    485,   1253,   -515,
+      1435,   -527,     21,   -100,   -368,    -84,   -119,   -144,
+     -1375,  -1189,  -1189,   -999,   -723,   -190,    796,    639,
+       699,    816,  -1188,   -919,    683,    842,    177,    -62,
+       -25,     71,     15,     16,    157,     80,   -331,   -343,
+        12,    193,   -133,    -94,    -94,    -64,  -1306,    531,
+      -917,   -142,   1274,    102,    -15,    184,    159,    148,
+       -43,  -1103,   -581,   -419,    447,   -132,   -204,    187,
+       631,    461,  -1302,  -1162,   -927,    896,    203,    164,
+       -55,    287,    544,    485,  -1258,   -791,    677,   -945,
+      -244,   -101,    423,    362,    298,    389,   -825,   -640,
+      -646,    274,    -73,   -274,   1473,    -13,    132,    169,
+};
+
+static const int16_t fcb11sm[] = {
+      -767,  -1179,  -1188,  -1069,   -690,   -172,    787,   1389,
+      1623,    844,   -169,   -894,   -919,     51,     15,    426,
+      -326,   1579,    182,     77,    202,   -417,   -357,    -17,
+      2154,    -77,   -607,   -589,   -375,   -261,   -376,    175,
+      -829,   -801,   -579,   -290,   -244,    533,   1307,    873,
+      -877,  -1175,  -1157,   -726,    461,   1729,    433,    219,
+       246,    606,   -791,   -827,    649,    891,    820,    720,
+       407,   -641,   -727,   -708,   2498,    961,    -99,   -542,
+      -530,   -507,   -536,   -608,   -642,   -622,    316,    195,
+      -721,   -549,   -253,   1520,    171,    -81,   -372,   -333,
+      1166,  -1072,  -1230,  -1123,  -1031,   -868,   -370,    209,
+      1561,   1751,    113,   -367,    399,   -663,    -10,   -271,
+       950,    118,   -335,   -272,   -863,     60,   -875,   1850,
+      -242,   -276,    -38,   -106,    471,     30,    823,   -344,
+      -752,   -714,   -309,   -419,     86,   1604,   -250,   -185,
+      -839,   -703,   -561,   -281,   1813,    -57,    255,    266,
+       -32,     99,    400,   2520,    315,   -372,   -306,   -511,
+      -549,   -659,   -760,   -729,   -559,   -137,   -610,    174,
+       924,   -310,   -705,   -307,    885,    512,   -611,  -1097,
+     -1172,  -1072,   -758,   -527,   -192,    278,    740,   3398,
+     -1136,    409,   -230,   -353,   -137,    322,    326,    365,
+       133,    173,   2291,   -644,   -725,   -596,   -535,   -340,
+       -88,    -65,    -53,    273,   -760,   -390,   -649,    119,
+      -243,   -222,   1726,   -113,     44,    326,   -618,    311,
+      2345,   -241,   -398,   -399,   -382,   -322,   -444,   -457,
+      1873,   -454,   -505,     42,    481,    187,    -49,   -505,
+      -634,   -754,   1052,   -597,   1315,    297,   -412,   -110,
+      -205,   -552,   -682,   -524,  -1055,   -431,    971,   -363,
+      -539,   -366,     39,    995,    181,    476,    662,    229,
+      -445,   1682,   -205,   -181,   -273,   -497,   -685,   -628,
+      6135,    -21,   -834,   -934,  -1002,  -1066,   -931,   -974,
+      -902,   -643,   -820,   1891,   -706,   -288,   -252,   -231,
+       -79,    126,     35,     37,     10,    -10,    -36,     -6,
+        -9,    -47,     -7,      1,     11,     -2,    644,    315,
+       145,   -353,   -396,   -428,   -357,    -60,    275,    109,
+     -1179,   -952,   -698,    138,    286,    171,    394,    263,
+       814,    495,   -490,    110,    369,    599,      9,    599,
+      -431,   -233,   -328,    -69,    410,  -1002,   -462,     77,
+        97,    196,    133,    -91,    512,     49,    621,   -436,
+      -352,   -390,   -211,   -188,   -454,   -318,     44,   1424,
+};
+
+static const int16_t fcb16l[] = {
+       -13,   -798,   -772,    235,    515,   -181,   -120,   -509,
+      -392,  -1159,   -844,  -1041,   -881,  -1193,   1103,  -1080,
+       214,   1615,   1819,   1510,   -914,  -1190,   -273,  -1099,
+      -522,   -996,   -206,   3946,    996,   1678,  -1220,  -1201,
+      2850,  -1022,   1101,   -814,   -188,    879,   1549,   1279,
+     -1129,   1928,   1550,     38,   -356,   -574,   -157,    286,
+       481,    475,  -1079,  -1176,   -861,   -548,   -657,   -381,
+       538,    948,   -838,    779,  -1149,   -962,   1788,   -779,
+      -742,   -311,    205,    299,    472,    715,    702,   -843,
+      -931,   -790,   -624,   -332,    324,    778,    785,    670,
+     -1137,  -1205,   -103,  -1182,  -1071,   -950,    101,    527,
+      1596,   1004,    682,   -564,  -1053,   -844,  -1184,   1732,
+      -862,   1994,   -988,   1131,  -1069,  -1276,  -1053,   6414,
+     -1259,   -186,   -930,    118,    375,   1092,   6215,   -900,
+      -920,   -935,   -981,   -970,   -766,   -902,   -334,   1629,
+     -1094,  -1142,  -1155,   -779,  -1092,   1011,   -490,   1063,
+      1569,   1340,   2242,  -1313,   6027,  -1319,  -1337,   -789,
+     -1296,   -457,    819,   2276,  -1071,  -1065,   -715,    802,
+      -996,    397,   2396,    -27,   1225,    935,   1400,   -862,
+      -802,   1846,   -513,   -249,   -704,    515,    872,    662,
+     -1141,   5876,   -691,   -404,   -603,   -148,    -57,    187,
+       649,    788,  -1116,   -915,   -551,   3843,   -737,   -133,
+       498,    155,    227,    718,   1798,   1397,   -868,   -716,
+      -586,   -580,    -71,    -67,    311,    536,   2465,   -524,
+      1837,   -231,   -210,    263,    231,    -10,   -164,   -324,
+      -951,  -1130,   5206,   -525,   -603,   -401,    223,    438,
+      1011,   1077,   -726,  -1102,  -1013,   -386,   -786,   4281,
+      -329,    262,    550,   1292,   -629,   -943,   -976,    773,
+      -867,    908,   -680,   -154,    362,   1056,  -1051,   -703,
+     -1333,  -1424,  -1026,   -793,   -859,   -882,   -148,   9958,
+     -1193,  -1156,  -1077,   1241,  -1013,   -726,   -139,    551,
+      1150,   1019,   -733,   -997,   -651,   -625,    -54,    722,
+        73,    -14,    361,    435,   4013,  -1260,  -1195,   1452,
+     -1105,   1273,   -670,   1546,   1038,   1680,   -812,  -1060,
+      -853,  -1058,   2094,   -801,   -457,   -320,    683,    960,
+     -1019,  -1158,  -1118,  -1034,   -617,    404,   1376,    847,
+      1014,    951,    -12,  -1004,  -1221,  -1131,    649,  -1052,
+       442,   -167,   -859,   3868,  -1216,  -1298,  -1311,   2866,
+     -1310,   -639,  -1079,   1576,   1760,   1837,    118,  -1080,
+      -862,   -845,  -1065,  -1069,   2199,   -766,    495,   1309,
+      -996,  -1040,   -741,   1357,   1726,    382,    264,     92,
+       659,    665,   -781,  -1356,   2055,  -1198,     15,   2143,
+       631,    569,    918,   1120,   -948,  -1253,  -1234,   2442,
+     -1062,   2206,     48,    660,   1822,   1480,   -639,    627,
+      -432,   -477,    845,    216,    228,    152,    157,    295,
+      2444,   -908,   -465,   -768,    109,    251,     72,    -59,
+       169,    405,   4395,   -837,   -931,   -839,   -215,   -564,
+       655,    359,    503,    296,   3514,  -1082,  -1185,   -827,
+      2879,  -1224,   -811,   -970,    804,    911,   3028,  -1284,
+      -688,  -1226,  -1251,   -551,  -1247,   -275,   3441,   2322,
+      -630,  -1213,   -108,  -1191,   1129,   -854,   2848,   1609,
+      1048,   1535,   2784,  -1245,    772,  -1230,  -1298,   -686,
+     -1293,   -639,    278,   2455,   9975,  -1077,  -1233,  -1055,
+      -139,   -853,    -48,     24,   -720,    533,  -1191,   2809,
+     -1015,   -899,    -28,   -765,   -147,    146,    592,    814,
+     12493,  -1274,  -1072,  -1297,    877,  -1068,  -1179,  -1032,
+      1023,  -1178,   -840,    930,   -660,   1216,   -366,   -406,
+       -97,     77,    179,    340,   -973,   -993,   2280,   1775,
+      -631,    -17,   -186,    507,    459,    645,   2095,  -1019,
+     -1067,   -949,   -857,  -1202,   -904,    -48,   1156,   1273,
+     -1230,  -1245,  -1203,  -1036,  -1150,   -955,   1193,   1943,
+      1437,   1329,   -618,  -1055,   -730,  -1014,   4953,  -1125,
+      1089,   1085,   1047,   1045,    813,  -1036,   1270,   -715,
+      -684,    -96,   -131,    289,    782,    628,   -979,   1060,
+      -975,   -964,   -811,    -14,    223,    422,    563,    696,
+      -901,   -633,    496,   -136,     22,    -83,    -52,    264,
+        24,    147,   -446,  -1197,  -1258,   -687,  -1239,   -795,
+     -1066,  -1196,    147,   2653,  -1231,  -1275,  -1240,  -1041,
+     -1260,  -1159,   1961,    -34,   2937,   2128,  -1318,  -1355,
+     -1326,  -1300,  -1345,  -1326,   -870,   -298,   2014,   3890,
+      -933,  -1014,   -859,  -1074,   -506,  -1163,   -954,   -819,
+       440,    732,   -582,  -1268,  -1206,  -1037,  -1081,  -1255,
+     -1150,   -835,   2360,   1469,  -1232,  -1384,  -1388,    542,
+     -1359,   -606,  -1335,   1852,   2142,   3722,  -1218,  -1321,
+     -1268,  -1207,  -1203,  -1316,   -954,   -696,   4730,   2920,
+     -1225,  -1306,  -1131,  -1273,  -1276,  -1238,  -1040,   2079,
+      2652,   1931,  -1167,  -1302,    659,   -532,   -650,   -560,
+     -1028,    186,   1224,   2811,   -896,   -449,   -999,   -823,
+       -81,   -876,    502,   -293,    680,    733,   -836,  -1111,
+     -1132,   -865,  -1141,   -938,   -980,   1287,    581,   1438,
+};
+
+static const int16_t fcb16s[] = {
+      1260,  -1427,  -1400,   -996,   -958,  -1195,   6261,     31,
+       967,    752,   3776,   -975,   -840,   -707,   -696,   -555,
+        45,   1159,      4,    358,   4718,  -1471,  -1464,  -1291,
+     -1364,   -934,   -878,   5198,   -273,   1555,  -1438,  -1729,
+     -1579,  -1470,  -1820,  -1436,  -1255,   -631,   4287,   4025,
+      1233,   -684,   -748,   -742,   -547,   -229,    321,    126,
+       794,    670,   6689,  -1041,  -1160,   -861,  -1002,   -976,
+       147,   -668,    521,    940,  -1186,   2097,   -570,   1759,
+      -251,   -442,    -92,     46,     99,     12,  -1336,  -1061,
+      4427,   -945,   -861,   -460,   -306,    494,    481,    536,
+     -1101,  -1105,   2695,    316,   -801,   -159,   1042,   -577,
+       -78,    340,   2347,   1448,    135,   -381,   -688,   -493,
+      -254,   -234,    -74,    -80,  -1047,  -1246,   -729,   -985,
+      5399,  -1018,    643,    822,    889,    432,   -328,  -1386,
+     -1420,   -702,  -1450,   6927,  -1107,    465,   1625,   1116,
+     -1258,   2847,   -893,   -895,   -521,   -263,    112,    157,
+       556,    500,    182,   -652,   -226,    258,   -638,   -566,
+      -419,   -669,   -224,   -221,  -1197,   -227,   -582,     92,
+      1914,   -184,    -11,    -18,    270,    166,  -1294,    -62,
+      1536,   2470,   -413,   -619,   -399,     24,    106,     54,
+     -1223,   2672,   2400,    -54,   -577,   -692,   -301,     -3,
+       206,     89,  -1424,  -1491,   8425,  -1072,   -242,   -420,
+      -194,     -1,    489,    331,   -938,  -1319,   2493,  -1355,
+       551,   2297,    197,     -9,    717,    434,  -1237,   -773,
+     -1021,   3945,   -566,    116,    246,    150,    510,    370,
+     11804,   -457,  -1006,  -1231,  -1175,  -1086,  -1221,    589,
+      -679,   -757,  -1183,   6502,   -584,   -454,   -629,   -570,
+      -413,   -352,   -279,    -32,  -1236,   -946,   -760,   1535,
+      -865,   -712,   -224,    343,    647,    613,  -1348,   -938,
+      -961,   8273,  -1130,   -591,   -225,    210,    420,    140,
+     -1247,  -1166,   -966,   -986,  -1120,   -907,   -181,    470,
+      1888,   1161,  -1076,  -1298,   3479,  -1151,   2410,   -396,
+         1,    -44,    357,    594,   -896,    745,    -33,   -422,
+      -332,   -259,      0,     48,    143,    190,  -1009,   -837,
+      -876,   -371,   -370,   1520,   -150,    251,    240,    448,
+     -1024,  -1008,   -568,   -450,   -611,   -536,   1763,    -34,
+       355,    454,   -769,   -599,   -639,   -737,   -912,   -725,
+      -504,   -230,    532,   3294,  -1077,   -289,   -875,   -542,
+      -574,   -604,   -339,   2511,    479,    742,  -1218,   -946,
+      1321,   -522,   -544,   -950,   -765,    632,    639,    497,
+};
+
+static const int16_t fcb16m[] = {
+      -940,  -1197,  -1190,  -1200,  -1192,   -960,   -718,    610,
+      3300,   3253,  -1515,  -1689,  -1798,  -1798,  -1793,  -1764,
+     -1616,     33,   2377,   7778,   -668,   1745,   1501,    785,
+      -336,   -823,   -708,   -446,   -455,   -812,   8862,    159,
+     -1141,  -1261,  -1323,  -1299,  -1261,  -1227,  -1214,  -1090,
+      3584,   2092,    688,   -531,   -848,  -1000,  -1047,  -1192,
+     -1104,   -887,   5163,   -347,  -1129,  -1285,  -1336,  -1291,
+     -1249,  -1109,   -498,   2511,   -611,   -703,   -516,   -240,
+       -68,    399,   1570,    252,     -5,     43,  -1163,  -1168,
+     -1008,   -921,   -995,   -569,    925,   1511,   1001,   2023,
+     12926,    135,  -1598,  -1778,  -1847,  -1850,  -1836,  -1734,
+     -1695,  -1690,    621,   4647,    588,   -752,   -973,   -996,
+      -953,  -1081,  -1060,   -672,   -868,    259,   4940,   -117,
+      -718,   -907,   -828,   -776,   -606,   -981,  -1002,   -526,
+      -385,    527,   1501,   -239,     38,     25,    112,    -77,
+      1122,   -250,   -352,  -1113,  -1101,   -942,   -681,   5156,
+      -800,   -636,   5814,   -160,   -777,   -825,   -844,   -747,
+      -697,   -645,   -668,   -492,   -936,    491,   -280,   2573,
+      -269,   -736,   -375,   -265,    -98,   -243,   -920,   -236,
+       446,   1095,   -666,   -600,   -246,    783,    282,      0,
+     -1064,   -116,   2271,   -118,   -482,   -240,   -187,   -271,
+        36,     91,   -695,   -254,   -383,   -948,    745,   2722,
+      -129,   -799,    238,   -379,   2872,   -516,   -868,   -623,
+      -551,   -275,     22,    379,   -185,   -230,   1524,   -672,
+     -1062,  -1164,  -1177,  -1137,  -1058,   -790,      6,   4928,
+      -551,   -389,   -460,   -394,   -674,   -586,   -327,   -178,
+       615,   2868,  -1467,  -1203,  -1316,  -1120,   -996,    747,
+      -219,   2023,   1875,    254,   -871,   -992,  -1062,  -1110,
+     -1149,   -992,   -492,     40,    528,   5374,     83,   -559,
+      -862,   -760,   -541,     28,    207,    629,    502,   1260,
+      -473,  -1110,  -1336,  -1390,  -1412,  -1379,  -1329,  -1081,
+      -238,   9844,  -1332,  -1306,  -1275,   -881,  -1267,  -1249,
+      -237,   2882,   3535,    584,    -13,     52,    -50,     -4,
+         7,      5,     20,    -55,      5,     45,   1587,    350,
+       191,    617,    153,   -236,   -336,   -649,   -798,  -1063,
+      1451,    707,    253,   -733,   -923,   -859,   -621,   -738,
+      -555,   1623,   1727,   -411,   -724,   -772,   -746,   -675,
+      -688,   -209,    915,    622,  -1038,   -474,   -343,    -91,
+      -173,   -104,    255,     96,   1547,    773,   -625,   2272,
+       -90,   -509,   -527,   -247,   -147,   -234,    -45,    166,
+};
+
+static const int16_t fcb16sl[] = {
+     -1337,  -1122,  -1559,  -1452,  -1353,   -973,   3858,   1145,
+      1225,   2103,   -607,   -181,    557,   -429,     15,   -496,
+      -444,   -523,  -1866,  -1134,  -1270,   3029,  -1110,   -798,
+      -824,   -659,     44,    614,   1059,   1173,    714,   -932,
+     -1095,  -1061,   -921,  -1034,   -873,      7,   -872,    660,
+     -1335,  -1496,  -1623,  -1405,  -1070,   -680,    943,    134,
+      -190,   2837,  -1034,   -221,   -337,   -540,   -571,   -173,
+      -411,   2314,   -111,    970,  -1220,  -1036,  -1096,   -147,
+      1087,    604,   -367,     83,    461,    679,  -1333,    194,
+     -1292,  -1139,  -1097,   -570,   -508,   -109,     54,    962,
+      2592,  -1112,   -944,   -636,   -521,     12,    230,    442,
+       562,    624,  -1107,  -1190,   1554,   -981,   1507,  -1013,
+      -394,    595,    823,   1094,  -1453,  -1298,    242,  -1185,
+      -686,   -541,    858,    331,    695,   1197,  -1259,    968,
+     -1180,  -1254,   -752,   1473,    222,    342,    973,   1029,
+     -1631,  -1500,  -1619,  -1517,  -1299,   1683,   2203,   1163,
+      1225,   1497,  -1189,   -937,   -931,   3193,   -977,   -708,
+      -262,    549,    917,   1465,    704,   -565,   -708,    846,
+      -130,   -322,   -257,    221,    367,    309,  -1416,  -1123,
+     -1323,  -1260,   -405,   3303,   -210,    785,   1007,   1616,
+     -1043,   -717,     44,    824,    419,   -492,   -579,   -604,
+       -15,    676,  -1067,  -1079,   3897,  -1211,   -474,  -1020,
+      -589,    114,    593,   1504,  -1481,  -1249,  -1036,  -1012,
+      -719,    846,   -189,   -297,    -31,   1209,  -1761,  -1566,
+     -1449,  -1645,  -1464,   1422,     24,   2153,   1377,   1948,
+     -1480,    652,   -929,   -415,   -689,   -386,   1628,    489,
+       487,    756,  -1424,   -805,   1241,    228,   -697,   -316,
+       423,    660,    557,    587,   1248,   -777,   1088,   -848,
+      -498,   -399,    -60,    169,    497,    689,   5679,   -778,
+     -1109,  -1118,   -895,  -1042,   -504,    390,   1670,    469,
+       977,   -929,  -1173,  -1058,   -999,   -696,   1912,     52,
+      1297,   1081,  -1469,  -1243,  -1055,    385,   -529,    910,
+        79,    508,   1225,    753,    656,  -1307,  -1239,  -1470,
+     -1110,  -1255,   -362,   2351,    889,   1687,  -1566,  -1331,
+     -1410,  -1385,    779,   -499,   -217,    936,   2064,   1493,
+     -1499,  -1345,  -1162,    790,  -1115,   -673,   2083,   1010,
+       588,   1265,  -1439,  -1168,  -1294,    752,  -1421,  -1234,
+      -169,   -529,   1606,   2131,  -1556,  -1442,  -1444,    487,
+     -1260,  -1139,    360,   2528,   1994,   1686,  -1548,  -1473,
+      -563,  -1125,    967,   1490,   1503,    487,    991,   1024,
+     -1430,  -1151,  -1215,   -729,   -746,   -762,   -472,    778,
+       889,    774,  -1329,  -1129,   1383,  -1230,   -723,   1478,
+       379,    161,   1266,   1238,  -1467,   -843,  -1277,  -1323,
+      -715,     58,   -182,   5140,    762,   1723,  -1285,   1134,
+     -1175,  -1057,   1294,     -4,   -417,    557,    939,   1182,
+        39,    565,   -809,   -703,   -783,   -883,   -112,    412,
+      1056,    691,   -273,  -1334,   -898,  -1345,  -1069,  -1247,
+      -105,    638,   6811,   1157,    982,   -856,   -805,  -1093,
+      1267,   -747,   -650,    311,    281,   1076,   1371,   1614,
+      -891,   -886,   -396,   -246,    -65,     77,    472,    605,
+      -943,    178,   -509,    112,   -142,    512,    -66,    109,
+       144,     76,   2934,  -1203,  -1428,  -1525,  -1269,  -1618,
+     -1129,   -184,   -225,   3157,   -249,  -1276,  -1055,   -439,
+      -161,   -268,    284,    614,    778,    670,  -1243,   1682,
+       919,   -468,   -479,   -341,     31,    468,    325,    606,
+     -1081,   -723,     83,   -399,   -275,   -658,    240,    149,
+      2746,    679,  -1573,  -1287,   -494,    775,    975,   -751,
+       -47,   1758,    652,   1155,  -1465,  -1073,  -1087,  -1026,
+       289,    340,    448,   1348,    351,    682,   2065,  -1183,
+     -1313,  -1562,   -466,  -1546,  -1077,   -477,   3012,   2512,
+     -1560,  -1532,  -1441,  -1229,    861,   -421,   1515,   2195,
+      1163,   1418,  -1268,  -1103,   -804,  -1094,   3254,   -711,
+      -558,    713,   1414,   1684,    542,   -781,   -827,   -814,
+      -245,   1129,   -160,    210,    386,    618,  -1633,    488,
+     -1584,  -1571,  -1349,   -662,    711,   1516,   1661,   1673,
+     -1510,  -1530,   1013,  -1172,    425,  -1415,   -856,   2963,
+      2258,   1919,   -744,  -1208,   -863,   -634,   -729,  -1068,
+      -857,   -289,    701,   6703,  -1502,  -1353,  -1531,  -1372,
+     -1388,  -1067,   1392,    100,   2570,   1703,  -1551,  -1500,
+     -1587,  -1693,  -1753,  -1431,  -1048,   1162,   1308,   3073,
+      -998,  -1575,   -517,  -1346,  -1293,  -1493,  -1375,  -1109,
+      -803,   2972,  -1446,  -1316,  -1114,  -1405,  -1240,  -1057,
+     -1109,   -589,   2623,   1626,  -1555,  -1026,  -1346,  -1467,
+      -902,   1291,    176,    630,   4293,   1949,  -1233,  -1362,
+      -930,  -1175,  -1118,  -1375,  -1172,   -967,   4896,   4195,
+     -1744,  -1562,  -1797,  -1815,  -1577,  -1194,    371,   3326,
+      3183,   3071,  -1425,  -1773,  -1562,  -1358,   -547,   -246,
+        24,   -526,  -1502,  29376,   -860,   -614,   -857,   -795,
+       793,   -616,   1691,   -125,    156,    559,  -1643,  -1462,
+     -1523,  -1413,  -1251,   -592,   1014,   1888,    243,   1041,
+};
+
+static const int16_t fcb16ss[] = {
+       308,   -532,   -811,   -974,   -641,   -431,   3409,    258,
+       567,    641,   1315,   -723,   -738,   -502,    142,    678,
+       -67,   -170,     73,    -65,   2717,   -804,   -958,   -878,
+      -532,   -562,    238,    497,    548,    718,   -868,   -669,
+      -932,  -1004,   -518,   -502,   -286,    405,   2987,   1420,
+       174,   -779,   -748,   -575,   -153,    -40,    340,    413,
+       275,    387,    965,     82,   -550,   -744,   -592,   -591,
+      -604,   -163,    428,    843,  -1280,   1756,   -368,    777,
+       -29,   -453,    -61,     43,     50,    137,    950,   -229,
+      1504,   -491,   -353,   -167,   -285,   -158,    -94,   -185,
+     -1431,    303,    673,   -758,   -610,   -308,   1247,    348,
+        95,     31,   1631,   1963,   -624,   -770,   -466,   -150,
+      -122,   -123,     34,   -141,   -883,   -374,   -948,   -629,
+      3420,   -772,   -392,    -31,    603,    646,   -760,   -871,
+      -936,   -948,   -727,   3563,   -376,    858,    699,    561,
+     -1370,   2366,   -775,  -1241,  -1105,   -247,    177,    432,
+       414,    379,  -1360,  -1057,   -945,   -848,   -568,   -779,
+      -632,   -328,   -295,    425,   -349,    630,   -275,   -527,
+       438,     47,   -194,    -96,   -239,   -545,  -1381,   -689,
+      1644,   1165,   -437,   -153,   -193,    307,    183,     66,
+     -1335,   2590,   2169,   -447,   -435,   -317,    -82,    204,
+        45,   -145,  -1324,   -205,   4019,   -973,   -578,     28,
+       175,    506,    235,    -98,   -908,   -294,   1443,   -850,
+      -556,   1707,   -277,     58,    241,   -188,   -853,   -572,
+      -577,   1258,   1007,   -190,      1,     -3,    103,    -49,
+      5385,    137,   -707,   -834,   -510,   -517,   -392,   -390,
+      -231,   -275,  -1249,   5229,   -812,   -893,   -353,   -663,
+       -29,    187,     45,     10,  -1388,  -1171,  -1051,    412,
+      -379,   -411,    240,    574,    632,    284,   -838,   -912,
+      -924,   3062,   -695,   -409,   -224,    422,    293,    267,
+     -1436,  -1237,  -1303,  -1305,   -914,   -243,    821,    839,
+      1043,   1284,  -1178,   -496,   1594,   -736,   1752,   -601,
+      -396,    330,    231,     48,  -1253,    808,   -896,   -967,
+      -653,    -84,      4,    442,    363,    589,  -1005,   -672,
+      -687,    -93,   -274,   1376,   -232,    -52,    399,    255,
+     -1085,  -1214,  -1088,   -748,   1036,    414,    220,    509,
+       436,    499,   -648,   -765,   -931,   -983,   -758,   -543,
+      -379,   -115,    780,   3327,  -1086,   -893,   -773,   -881,
+      -683,    -11,   -322,   3418,    739,    961,  -1363,   -929,
+       899,  -1005,   -792,   -338,   -185,    702,    627,    638,
+};
+
+static const int16_t fcb16sm[] = {
+     -1125,  -1385,  -1439,  -1387,  -1120,   -681,   -135,    616,
+      3086,   2537,  -1440,  -1209,  -1027,  -1209,   -626,    173,
+       662,    899,    861,   2180,    387,   1032,    936,    140,
+      -353,   -302,   -290,   -330,   -551,  -1019,   3555,    -68,
+      -441,   -539,   -500,    -27,   -423,   -506,   -522,   -415,
+      2347,   1890,   -312,   -742,   -679,   -679,   -653,   -609,
+      -433,   -472,   2709,   -755,  -1153,  -1066,  -1028,   -862,
+      -826,   -315,     78,   1699,   -363,   -429,   -690,   -190,
+      -358,   -667,   1909,     39,     -1,    138,  -1592,  -1559,
+     -1357,  -1554,   -750,    813,   1676,   1537,    977,   -269,
+      8320,   -602,  -1140,  -1153,  -1136,  -1174,  -1004,  -1091,
+     -1388,  -1187,   -507,   3103,   -200,   -665,   -590,   -381,
+      -365,    -40,   -295,   -591,   -963,    271,   2231,   -547,
+       -65,   -270,    -64,    243,   -183,   -548,   -796,   -277,
+        -7,   -168,   1575,   -361,     35,    -19,    192,   -154,
+      -384,    144,   -426,   -528,   -598,   -778,   -297,   1847,
+       564,    218,    864,   -654,   -485,   -435,     45,    709,
+       630,    -11,   -691,   -111,   -775,   -356,   -522,   2247,
+       -79,   -433,   -620,    594,     79,     60,   -828,   -475,
+       768,    -79,   -655,    550,   -201,     77,    858,    -11,
+      -803,   1173,   1027,   -971,   -656,   -648,    -40,     17,
+       720,    176,  -1055,   -936,   -258,    550,   1086,   1065,
+         0,   -473,   -364,     30,     53,     -6,    -54,    -24,
+        21,    -81,    -88,    -45,    -14,     81,    674,  -1189,
+     -1049,   -846,   -489,    -24,    -47,    165,    658,   1909,
+      -241,   -390,   -387,   -454,   -319,   -549,   -307,   -112,
+       778,   1486,   -314,     34,    -93,   -799,   -538,   2219,
+      -445,     39,    -38,   -258,   -427,   -943,   -760,   -602,
+      -575,   -450,    376,    668,    879,   1215,  -1216,   -784,
+      -646,   -291,    275,   1019,    -77,    124,    256,   1166,
+      -410,   -993,  -1145,  -1118,   -940,   -825,   -560,   -131,
+      1006,   4878,  -1401,  -1286,  -1316,  -1394,    177,   -919,
+       162,   2292,   1792,   1242,   -762,    937,   -168,   -900,
+      -829,    203,   1225,    626,   -122,   -515,    992,   -198,
+      -782,    -25,     74,   1019,   -606,   -364,   -350,     -5,
+       451,    324,    265,  -1143,   -820,    382,   -362,     85,
+      -797,    693,   1594,   -335,   -229,   -396,   -211,   -356,
+       -97,   -115,     92,     49,   -476,  -1124,  -1084,   -594,
+      -228,    728,     16,    589,   1213,    841,   -829,   1874,
+      -907,  -1000,   1411,   -621,   -707,    356,    437,     37,
+};
+
+static const int16_t fcb22l[] = {
+      2735,  -1224,  -1198,  -1073,  -1115,  -1054,   -713,   1693,
+     -1106,  -1259,    722,  -1256,  -1223,   1686,   1589,   2003,
+      -906,   2529,   2141,   -396,   -338,    -36,     52,    476,
+       319,   -420,    561,   -492,   -526,   -359,   -221,   -254,
+      -752,  -1136,   -690,   -896,   4307,   -363,    -42,   1363,
+      -717,  -1036,   -874,   2315,   -952,   -872,    262,   1418,
+       737,   1374,   -506,   -470,   -275,   -126,    242,    428,
+      -678,   -681,   -581,   1016,   -553,   -509,   -485,   -408,
+      9595,  -1015,  -1168,   -932,   -812,   -690,   -167,    753,
+      -935,   -439,   2105,   -526,   -710,   -570,      9,    548,
+       530,  -1308,  -1060,   -351,   -974,  -1038,     93,   5579,
+      -737,  -1282,   1386,  -1284,  -1243,  -1105,    790,   2169,
+      -701,   -660,   -555,   1317,   2805,    792,   2209,   -490,
+      -758,  -1262,  -1083,  -1073,    930,   -810,   -170,   2326,
+     -1213,  -1286,   3435,  -1135,  -1051,    220,   3040,   1999,
+      -933,   -663,   -714,   -855,   -372,   -599,   -437,    373,
+      5873,   -987,  -1081,  -1003,   -747,   -271,    582,   1069,
+      -917,   -754,   5676,   -565,   -616,   -396,    177,    908,
+      3106,   1459,   -678,   -543,   -340,     47,    336,    493,
+     -1060,   1427,   -560,   -763,   -710,   -661,    193,    595,
+      -996,   2488,   -588,   -752,   1306,    114,    292,    689,
+     -1202,   2334,  -1173,  -1167,   -755,    353,   1711,   1572,
+      -932,   -751,   2099,   2025,   -417,     62,    458,    611,
+      -981,   4387,   -639,   -560,   -520,   -152,    262,    748,
+      -828,   -818,   -682,   5250,   -640,   -270,    385,   1049,
+     -1072,   -774,   1870,   -668,   1514,   -158,    283,    793,
+     -1087,  -1150,   -899,   -875,   -188,   -184,   6656,   2311,
+      -906,   1654,   -446,   1677,   -654,   -101,    364,    721,
+     -1272,   7928,   -812,   -576,   -708,   -347,    397,   1128,
+      3830,  -1034,  -1055,   2244,   -759,   -706,     79,    893,
+      -922,  -1067,   2740,   -868,   -858,   1129,     34,   1096,
+      2455,   -694,   1970,   -650,   -674,   -131,    370,    697,
+     -1069,  -1137,   -948,  -1045,  -1087,   -964,    367,   1091,
+      4096,   -960,   -921,   -870,   1397,   -511,   -190,    545,
+      -657,  -1194,   -536,   -951,  -1094,    117,   -720,   2532,
+     -1098,  -1147,  -1177,   1764,   -757,   -121,   2372,   2010,
+      3662,   -952,   -995,   -894,   -625,    464,    731,    863,
+      -607,   -505,    401,   -423,   -540,   2144,    755,   -430,
+     -1499,  -1242,  -1202,  -1190,   -626,   1249,   3388,   2379,
+      -983,  -1090,   -907,  -1021,  -1012,   -870,   2723,   1589,
+      -913,    332,   -102,     99,    226,      6,    176,    354,
+       156,    -36,   -829,   -774,   -685,    -15,    498,    503,
+      2030,   -409,   -599,   -572,   -341,     -2,    111,    302,
+       788,  -1002,   -978,   -929,  -1001,   -886,    578,    995,
+      1237,   -747,   -696,   -653,   1143,     62,    506,    571,
+       994,   -993,   -902,   -871,   -662,   1527,    370,    979,
+       980,   -466,   -484,    787,   -261,     61,    250,    377,
+      -112,   -676,   -535,   -344,    274,    363,    185,    334,
+       -48,  -1144,  -1095,  -1011,   -552,    445,   1355,   1207,
+     -1108,  -1128,  -1085,   -826,    -83,   2001,   1265,   1429,
+     -1024,   1199,   -671,   -701,   -444,   1192,    187,    673,
+     -1039,  -1056,   -953,   -732,    359,    714,    787,    935,
+     -1187,  -1133,  -1112,   -971,   2158,   1720,    801,   2016,
+     -1056,  -1068,   -889,   1808,    503,    892,    358,   1041,
+     -1180,  -1184,  -1068,   -788,   1423,   -573,   2141,   1949,
+     -1042,   -924,   -849,    512,   -629,   -272,    779,    815,
+      1939,  -1069,  -1092,  -1027,   -770,     48,   1554,   1285,
+     -1109,  -1148,  -1157,  -1033,   -934,    779,   1358,   1560,
+     -1053,    222,  -1095,  -1001,   -681,    -26,   1112,   1035,
+     -1168,  -1285,  -1169,  -1180,  -1085,  -1097,   1313,   3112,
+      -928,   -655,   -811,   -618,   1555,   -480,     71,    467,
+     -1220,  -1123,  -1008,   -577,   -845,   3854,    491,   1878,
+     -1051,   -761,    617,   -650,   -453,     51,    784,    757,
+      -993,   -883,   -905,   -708,   -869,    969,    -64,    655,
+};
+
+static const int16_t fcb22s[] = {
+      9854,   -479,  -1163,  -1147,  -1316,  -1137,   -991,   -942,
+       522,    739,  -1042,  -1306,  -1040,   -126,   1147,   3526,
+      1880,   -477,   -483,   -328,   -899,   1063,   1243,   -610,
+      -721,   -527,   -372,    171,     90,    196,   6615,  -1167,
+     -1189,  -1079,   -954,   -817,   -833,   2246,    439,   1038,
+     -1053,  -1136,   -938,   -805,  -1022,  -1041,   -717,   2021,
+       341,    935,  -1164,  -1230,   -573,   1768,  11111,  -1113,
+      -874,   -631,   -367,      7,  -1077,   -925,   1558,   -850,
+      -918,   -755,   -512,    452,    260,    400,   -787,   -966,
+      -690,   -584,   -843,   -802,   2092,    120,    103,    580,
+      -746,   -512,   -241,   -621,   2771,   -486,   -268,    258,
+       171,    232,  -1265,  -1253,  15128,  -1123,  -1037,   -885,
+     -1109,   -664,   -659,   -240,   1558,   -909,  -1160,  -1247,
+     -1223,  -1031,   -989,   -415,   3504,   1569,   -651,  -1241,
+     -1145,  -1014,  -1322,  -1000,   -354,     59,    709,   4206,
+     -1124,   -986,   -633,   -976,   -907,   -636,   -371,    255,
+      1195,    876,   -145,  -1146,  -1018,   -992,   -480,   -762,
+      6904,   -703,   -431,   1043,  -1048,   -638,   -142,    394,
+      -852,   -730,   -533,   -361,    234,    221,  -1070,   -930,
+      -764,   3210,   -780,   -256,   1777,    258,    307,    382,
+     -1224,    987,   4894,   3525,   -412,   -558,   -819,   -863,
+      -572,   -497,  -1175,  -1197,   7637,  -1109,   -748,   -116,
+      -306,     27,    386,    630,  -1334,  -1378,  -1302,  12592,
+     -1327,   -971,     89,   -731,    259,    201,  -1135,   -951,
+      -585,    -64,   3489,   2765,     43,     75,   -527,   -162,
+      2865,  -1344,  -1394,  -1391,  -1231,   -748,   -962,   5403,
+       719,   1418,   -724,  -1101,   -955,   -743,   -937,  -1064,
+     -1095,   -601,    -60,    411,  -1113,   -873,   -603,   2913,
+      2512,   -339,    -36,     26,    -39,     78,   -757,   -998,
+      -522,   -838,   5507,   -973,    796,    536,    250,    312,
+     -1363,   -944,   6021,    -58,   5313,   -690,   -549,   -485,
+       -66,   -133,  -1257,   6004,   6374,   1487,   -976,   -987,
+      -969,   -803,  -1027,   -624,   -967,   1744,   3504,      6,
+      -659,   -691,   -326,   -129,    -49,    148,  -1032,   -683,
+      1819,   1804,   -491,   -452,   -295,     33,    -20,     42,
+     -1226,  -1086,   -792,   6412,   -657,   -278,   -103,    -25,
+       -82,    207,   2450,     -6,   2417,    251,   -622,   -593,
+      -409,   -193,   -339,   -304,   -862,   -667,   2457,   -500,
+      -438,   -504,   1408,    143,    203,    265,  -1128,  -1148,
+      2791,   -373,   -951,   2129,   -842,   -278,     81,    307,
+      -787,   -822,   2655,   -604,   2028,   -787,      4,    335,
+       170,    219,    649,   -457,    972,   -607,   -359,   -470,
+      -238,     68,    -57,    107,   2285,   -526,   -490,   -604,
+       179,    -41,    230,     64,     20,     50,   -802,   1168,
+      -235,   -264,   -316,   1469,   -499,    108,    183,    150,
+     -1068,   -806,   -399,   1244,   -355,    487,    -57,    450,
+       195,    248,  -1122,  -1096,   3327,   -956,   1084,   1306,
+       247,    442,    169,    283,   3416,   -609,   -891,   -879,
+      -853,   -573,   -285,   -147,    380,    608,   1271,   -874,
+      -931,     40,   -989,   1432,   1981,    -34,    285,    190,
+      -902,   -974,   4117,   -868,   -784,   -584,   -358,    200,
+       261,    521,   -945,   -981,   -773,   3517,   -961,   2420,
+         9,    318,    187,    322,  -1006,   -779,   -526,   2972,
+      -712,   -578,   -576,    167,    156,    270,    460,    -74,
+      -237,    939,   -440,   -515,    126,     63,     82,     67,
+     -1069,  -1104,   -923,   -634,   -190,   1151,    526,   2920,
+       125,    566,  -1144,   4199,   1314,   -458,   -568,   -336,
+      -515,   -332,   -352,   -143,   -770,    283,   -770,   -785,
+      -807,   -348,     93,    427,    181,    334,   -798,   -830,
+      -300,   -509,   1257,   -554,   1341,      6,    242,    272,
+     -1030,     62,   1293,    340,    752,   -493,     -6,    -34,
+        33,     85,   -893,  -1202,    244,   -131,   -306,   7590,
+      -832,    420,     80,    423,   -799,   -870,   -930,   -720,
+      -640,   2390,   -409,   -177,     91,    370,   -864,   -949,
+       838,   -574,   -234,    555,     46,     -9,    -83,    146,
+      -825,   -478,   -664,    -57,    867,   -296,   -380,    -73,
+        70,    171,  -1124,  10522,   -228,   -609,   -958,  -1025,
+      -548,   -384,   -257,     55,   5414,    436,   -651,   -748,
+      -671,   -525,    -25,   -273,   -264,     57,  -1129,   1974,
+      -145,   1650,   -317,   -514,   -305,    -78,   -154,     59,
+      1269,   1008,   -510,   -711,   -534,   -358,    194,    117,
+       102,     57,   -837,   1260,   -126,   -494,     47,   -162,
+       924,    -72,    130,     97,    742,   -803,   -711,   -755,
+      -402,   -188,     24,    309,    187,    379,  -1092,   5862,
+      -647,   -807,   -715,   -696,   -408,    -29,    104,    353,
+      3298,   2193,   -263,   -772,   -908,   -754,   -449,   -164,
+      -157,    -44,   -986,   2313,   -596,     56,   2057,   -478,
+        74,    -51,     51,    121,   -899,   1793,   -595,   -669,
+      -743,   -689,   -546,     71,    201,    382,  -1061,   3375,
+      -776,   -876,   -648,   -407,    -44,    260,    258,    393,
+};
+
+static const int16_t fcb22m[] = {
+     11522,    868,  -1444,  -1572,  -1674,  -1745,  -1844,  -1616,
+     -1723,  -1508,     27,   -321,   -693,   -597,   -374,   -380,
+       327,    209,    611,   1182,   -548,    176,   -544,   -485,
+      -341,   -376,   -383,   1024,   1316,     -4,    192,   -649,
+      -979,   -945,   -802,   -183,   3749,    812,   -416,   -527,
+      -734,   1059,   -521,    924,   -462,   -631,    -76,    182,
+       126,    100,   -653,   -643,  -1189,  -1264,  -1312,  -1311,
+     -1212,  -1016,   -218,   8415,  -1005,    734,   1303,   -272,
+      -397,   -521,   -245,    389,    242,   -234,    458,   -912,
+     -1215,  -1228,  -1288,  -1131,   -845,   -404,    912,   5497,
+       413,   3161,   -432,   -148,   1704,   -663,   -996,  -1009,
+     -1419,   -929,    -36,   -471,   -640,   -571,   -197,   -573,
+      -462,   2586,   -179,   -382,   -757,   -895,  -1096,  -1140,
+     -1216,  -1051,   -688,    -44,   3311,   3518,   -474,   2530,
+      1475,   -676,   -702,   -777,   -380,   -316,   -538,   -468,
+      -708,    542,   -213,   -713,   -911,   -482,   -696,   -135,
+      1282,   2006,   5707,    476,   -707,   -771,   -650,   -788,
+      -778,   -853,   -962,   -926,     10,    -11,      3,      1,
+       -12,    -14,     21,      7,    -13,    -10,  -1410,  -1712,
+      1379,   5757,    218,  -1232,   -563,   -929,   -684,   -827,
+      -261,   1040,   -154,   -309,    -99,     62,    856,    199,
+      -614,   -926,   -626,   1568,   -258,    374,   1071,   -140,
+      -250,   -332,   -832,   -706,   -863,   -714,   -749,   3081,
+       498,   -695,   -395,   -600,   -279,    588,    245,   3122,
+      -329,   -677,   -262,     67,     19,   -530,   -882,   -862,
+     -1033,   -160,   1542,   1916,   -416,   -600,   -553,   -219,
+      -130,   -497,   -699,   1719,    160,   3293,   -212,   -923,
+     -1045,   -761,  -1238,  -1038,   1543,    738,   -548,   -541,
+      -403,   -281,   -115,    -95,   -313,    -19,   -292,   1136,
+      3592,    696,   -654,   -856,   -726,   -693,  -1057,  -1267,
+      -722,   -381,   -683,   1364,    -30,    589,    454,    262,
+       -57,  -1018,   -312,    846,   -139,   -587,   -127,   2482,
+      -178,   -233,   -977,   -796,     -6,    250,    220,   1577,
+      1141,   -251,   -649,   -809,  -1051,   -873,   -762,   -990,
+     -1010,   -890,   -897,   -639,   -671,   1964,    788,   2310,
+      6001,     20,  -1008,  -1159,  -1208,  -1208,  -1318,  -1227,
+      -829,   1680,  -1023,   -998,  -1224,   -945,   -769,    -41,
+      2033,    196,    917,   1615,   2026,   -654,  -1014,   -918,
+      -750,   -675,   -839,   1541,    282,    430,  -1059,   -708,
+      -507,   -522,   -169,    438,    196,    835,    778,    897,
+       420,    526,   1239,    198,   -736,   -953,   -835,   -229,
+      -348,    726,   -767,   1311,    248,   -353,   -550,   1017,
+      -250,   -732,    256,   -175,   -638,    763,   -761,   -957,
+      -554,    539,    252,    299,    431,    613,   4398,   -378,
+     -1022,  -1020,   -990,   -757,   -621,    -83,    -34,    122,
+      -476,     77,   -799,   -116,   4546,   -787,   -735,   -462,
+      -875,   -907,  -1373,  -1354,  -1355,  -1220,  -1024,    -88,
+      1298,   2844,    940,   1135,   2261,   2142,    181,   -735,
+      -924,   -941,   -799,   -715,   -662,     86,   -719,   -521,
+       115,   -576,   -699,   1052,   1295,    -57,     42,    230,
+      2876,    501,   -294,   -158,    104,   -157,   -515,   -662,
+      -987,  -1069,   -703,   -985,  -1061,   -946,   -878,   -267,
+       397,    132,    534,   3642,   1298,   -560,   -701,   -526,
+      -294,    197,    310,     75,     -3,    267,   -342,   2058,
+      -328,   -427,   -709,   -688,     14,    -43,    237,    506,
+      2822,   -337,   -900,   -818,   -638,   -192,    883,    -14,
+      -271,   -559,   2822,   -165,   -988,   -933,   -917,   -603,
+      -583,   -397,    467,   1092,  -1044,   -479,   2478,   -386,
+      -535,   -253,     63,    -49,     79,     27,   -182,   -100,
+       362,   -628,   -661,   -707,   1557,    136,    335,     89,
+      -197,   5697,    220,   -473,   -472,  -1053,  -1023,  -1087,
+     -1203,   -756,   -377,   -917,   -925,   -568,   -237,   1422,
+       197,    -98,    614,    867,   -831,   -829,   -969,   -720,
+       414,   1080,   1707,    828,   -121,   -757,  -1044,   -289,
+       816,    284,    809,    -84,    -22,   -552,     -9,    193,
+      -359,     66,   -582,   -674,   1992,    -31,     58,    427,
+      -515,   -299,    932,   -608,  -1103,  -1068,  -1016,   -770,
+       200,   1031,   1112,   1026,   -598,   -818,   -891,   -635,
+      -828,   -866,   -650,   4795,   -407,    215,   -853,    373,
+      -696,    159,    995,    465,   -509,    109,     60,     10,
+      8455,    198,   -999,  -1131,  -1111,  -1195,  -1246,  -1192,
+     -1181,   -934,   -365,   -764,   -689,   -589,   -734,   2479,
+      -960,   1279,    104,   -209,  -1012,   -824,  -1059,   -921,
+      -812,   -204,    199,    601,   3136,    637,   3021,   3851,
+      -490,    -18,   -930,  -1081,  -1133,  -1182,  -1268,   -980,
+      -864,   -945,   -278,    961,   -514,   -123,    562,    874,
+      -130,    336,   3314,   -331,  -1112,  -1162,  -1227,  -1230,
+     -1172,   -988,   -319,   3582,    890,     50,   -681,   -788,
+      -906,   -876,   -829,   -827,    -41,   3416,   -740,   -913,
+      -893,    404,   2059,   -651,   -474,    302,    516,    578,
+};
+
+static const int16_t fcb22sl[] = {
+      1098,  -1107,  -1125,   -983,   -770,   -233,    201,    823,
+     -1433,  -1294,    -17,  -1156,   -301,   1185,   1307,   1108,
+     -1247,   1829,   1353,   -537,   -457,    116,    574,    712,
+       159,   -489,    511,   -340,     54,    119,    213,    351,
+     -1489,  -1256,  -1324,  -1132,   3710,    262,   1087,   1465,
+     -1434,  -1027,  -1116,    825,   -662,   -428,   -109,   1045,
+       229,    753,   -604,   -422,    122,   -220,    279,    375,
+      -349,   -684,   -197,    490,   -160,   -116,   -120,    146,
+      5195,   -895,   -974,   -758,   -524,     21,    761,   1016,
+     -1216,    151,    864,   -602,   -715,   -591,   -347,    592,
+     -1265,  -1328,  -1375,   -878,   -660,   -549,    143,   4302,
+     -1433,  -1277,    360,  -1032,   -835,   -385,    337,   1111,
+     -1345,  -1250,  -1156,    914,   1594,     22,    912,   1012,
+     -1576,  -1411,  -1364,  -1153,    842,   -184,    240,   1302,
+     -1486,  -1162,   1246,   -880,   -830,     14,   2487,   1607,
+     -1384,   -158,   -572,   -977,     43,    -30,   -184,    572,
+      2759,   -892,   -768,   -522,   -289,    -44,    351,    575,
+     -1292,   -546,   3736,   -609,   -538,    -25,    514,    924,
+      1772,   1639,   -903,   -595,   -263,    340,    579,    670,
+     -1425,    770,  -1179,   -920,  -1158,   -675,    496,   1208,
+     -1337,   1240,  -1030,  -1044,   1840,    312,    809,    908,
+     -1457,   1410,  -1240,  -1083,   -541,    568,   2768,   1432,
+     -1249,   -890,   1078,   1278,   -558,     63,    573,    778,
+     -1285,   1932,  -1004,   -902,   -339,     59,     17,    659,
+     -1352,   -935,   -877,   3421,   -455,    160,    820,   1230,
+     -1326,   -978,    986,   -790,   1541,     41,    542,    743,
+     -1491,  -1162,  -1389,  -1265,   -928,   -139,   5045,   2259,
+     -1182,   1358,   -953,   1338,   -502,    122,    749,    839,
+     -1284,   4389,  -1001,   -813,   -421,     44,    855,   1072,
+      1658,   -881,   -821,   1409,   -299,      4,    453,    700,
+     -1144,  -1112,   1230,   -790,   -421,   1250,    -12,    655,
+      1545,   -872,   1199,   -632,   -365,     56,    415,    663,
+     -1401,  -1189,  -1403,  -1189,  -1145,   -687,   -116,   1120,
+      1768,  -1068,  -1024,   -629,   1440,     88,    578,    711,
+     -1651,  -1561,  -1564,  -1430,  -1037,   1264,    -21,   1944,
+     -1552,  -1336,  -1277,    916,   -412,     27,   2454,   1661,
+      1996,  -1087,  -1223,   -924,   -393,   1673,    794,   1017,
+     -1362,   -132,    151,    537,   -992,   1830,    777,    991,
+     -1591,  -1355,  -1494,  -1420,   -666,   2407,   3210,   2092,
+     -1114,   -624,  -1087,   -903,   -808,   -438,   1881,    654,
+     -1140,    254,   -105,    212,    386,     49,    256,    314,
+        83,     98,  -1128,   -901,   -578,    362,    702,    691,
+      1191,   -204,   -335,   -226,   -102,    -44,     -5,    120,
+        57,  -1110,   -403,   -651,   -806,   -202,    567,    690,
+       349,   -908,  -1075,   -941,   1487,    464,    763,    782,
+       387,  -1070,   -990,   -765,   -295,   1669,    341,    881,
+       232,  -1013,  -1043,    723,   -311,    294,    646,    574,
+        72,  -1191,   -546,   -183,    493,    161,    201,    465,
+      -185,  -1434,  -1368,  -1051,     64,    385,    748,    986,
+      -740,   -530,  -1199,   -562,    142,   1388,   1487,    715,
+     -1359,    873,  -1187,   -923,   -455,   1914,    403,   1016,
+     -1245,  -1223,   -624,   -495,    724,    652,    433,    585,
+     -1499,  -1277,  -1381,  -1148,   1679,   2138,    995,   1424,
+     -1345,  -1319,  -1296,    906,   -228,   1534,    506,   1024,
+     -1628,  -1410,  -1422,  -1197,   1393,    -22,   2728,   1784,
+     -1245,  -1056,   -942,      2,   -165,   -115,    840,    569,
+      1016,  -1191,  -1091,   -862,   -457,     95,   2087,   1029,
+     -1460,  -1486,  -1459,  -1104,   -571,    925,   1234,    935,
+     -1568,    -49,  -1325,  -1255,    -64,    315,    838,    962,
+     -1651,  -1562,  -1606,  -1571,  -1308,   -380,   1988,   2117,
+      -848,   -412,   -987,   -370,   1224,   -304,     10,    498,
+     -1523,  -1348,  -1373,   -959,   -772,   3767,    621,   1773,
+      -931,   -628,    169,   -513,     61,   -306,    994,    476,
+     -1116,   -879,   -875,   -484,   -795,    958,   -162,    444,
+};
+
+static const int16_t fcb22ss[] = {
+      6765,   -638,  -1108,   -977,   -679,   -446,   -325,   -432,
+      -127,     96,   -569,   -621,  -1050,   -841,   -800,   1474,
+      1170,     60,    330,    223,  -1317,    855,    307,   -931,
+      -648,   -549,   -148,    535,    642,    445,   3666,  -1146,
+     -1167,   -944,   -584,    942,   -284,     25,    573,    472,
+     -1041,  -1096,  -1209,  -1082,   -770,   -737,   -139,   2073,
+       753,    832,    507,   -828,  -1112,  -1130,   4284,   -722,
+      -261,    -57,    499,    300,  -1380,  -1130,    135,   -898,
+      -816,   -395,    195,    453,    650,    537,   -953,  -1109,
+     -1221,   -981,   -747,   -647,   2360,    467,    845,    684,
+     -1177,   -792,  -1254,  -1148,   1344,   -745,   -323,    180,
+       729,    739,  -1020,    183,   5226,   -638,   -358,    -86,
+      -268,   -143,     84,   -115,    480,   -543,  -1229,  -1097,
+      -594,   -983,   -792,   -391,   2637,   1405,   -761,   -866,
+     -1186,   -973,   -792,   -640,   -220,   -102,   1165,   3159,
+     -1241,  -1057,  -1322,  -1007,   -731,     44,    264,    668,
+      2645,   1592,   2885,  -1155,  -1347,  -1209,   -309,  -1161,
+      4216,    -64,    830,    616,   -688,   -638,   -596,    202,
+      -665,   -623,   -499,   -248,    512,    749,  -1395,   -708,
+     -1086,   1209,   -745,   -367,   1397,    279,    374,    259,
+     -1357,   -254,   2310,   1839,   -147,     36,   -402,    300,
+       -49,     47,  -1328,   -992,   3453,   -889,   -621,    135,
+       437,     70,    663,    346,  -1339,  -1136,  -1275,   6675,
+     -1309,   2285,   -869,   1154,    640,    617,   -505,  -1042,
+      -984,   -702,   1283,   1573,   -168,    135,    249,    253,
+      -783,  -1119,  -1342,   -975,  -1127,   1391,   -705,   4439,
+      1160,    845,  -1283,  -1224,  -1286,  -1142,  -1019,   -901,
+      -658,   -157,    231,    611,   -994,   -463,  -1017,   1082,
+      1831,   -459,   -164,    114,      0,    108,  -1386,  -1079,
+     -1318,  -1091,   2540,   -717,    762,   1414,    849,    576,
+     -1405,   -566,   2704,   -996,   2133,   -678,    404,    281,
+         4,    -32,  -1474,   3530,   2301,   -711,   -919,   -305,
+      -125,    184,    450,     73,  -1132,   1567,   1620,   -551,
+      -198,   -645,     19,      8,    190,    191,   -741,   -728,
+       410,   1067,   -322,   -239,     86,     11,   -137,   -220,
+      -489,   -607,   -963,   3630,   -624,   -478,    -12,    124,
+       219,     63,   2040,     75,   1338,   -293,   -333,   -336,
+      -330,   -246,   -360,   -344,   -953,   -393,   1550,   -701,
+      -616,   -254,   1908,    211,    328,    -43,  -1089,   -299,
+      1070,   -723,   -923,   2170,   -400,    -13,    -28,    108,
+      -812,   -400,    876,   -650,   1308,   -772,   -256,   -200,
+       117,    329,    649,   -639,    437,   -704,   -567,    -20,
+      -211,    197,    330,    342,   1670,   -468,   -920,   -588,
+       972,   -310,      9,    -46,     70,    -29,  -1313,   1684,
+      -794,   -979,   -752,   1864,   -173,    108,    248,    292,
+     -1247,  -1226,  -1059,    288,   -112,    189,     20,    540,
+       454,    380,  -1035,   -803,   1267,   -767,    746,   1331,
+       107,    317,    158,   -116,   2093,   -723,  -1064,   -906,
+      -713,   -789,   -518,     48,    494,   1018,   1835,  -1353,
+     -1303,  -1098,   -559,    800,    520,    662,    615,    574,
+     -1282,   -526,   1829,  -1086,   -885,   -356,   -539,    -50,
+       493,    402,   -777,   -374,   -754,   1721,   -701,   2086,
+      -348,    218,    138,    109,  -1367,  -1226,  -1041,   1949,
+      -433,   -291,   -363,    567,    613,    560,   1166,   -481,
+      -737,   1193,   -479,   -163,    -69,      2,    133,    239,
+     -1444,  -1448,  -1350,   -987,   -296,    606,    755,    543,
+       741,    806,   -851,   2437,     23,   -681,   -670,   -271,
+      -439,   -227,   -243,   -198,  -1307,    424,  -1212,   -987,
+      -745,   -369,    162,    641,    915,    611,    -24,   -728,
+     -1061,   -659,    808,   -532,   1241,   -233,    266,    353,
+       175,    210,   -262,   -328,    101,   -238,     66,   -339,
+      -472,   -415,    952,  -1490,  -1302,   -955,  -1270,   5776,
+      -792,    777,   1097,    807,  -1334,  -1172,  -1211,   -924,
+      -877,   2458,   -355,    593,    936,    699,   -336,   -700,
+      -762,   -569,   -337,    642,     97,    441,   -188,   -533,
+     -1062,    188,   -873,   -801,    418,   -167,    -57,    -29,
+        79,    241,  -1110,   6430,   -816,   -807,   -462,   -601,
+       -56,    -45,    188,     74,   2869,     43,  -1122,   -799,
+      -772,   -847,   1394,    -36,    294,     13,  -1304,   2155,
+      -534,   1545,   -315,   -325,    183,     31,    372,    187,
+       873,   1376,  -1037,   -810,   -516,   -235,    485,     99,
+       287,    327,  -1074,   1203,  -1089,   -882,   -515,   -544,
+      2041,    -40,    208,    191,    597,  -1141,  -1274,   -885,
+      -386,    106,    593,    394,    671,    678,  -1292,   3861,
+     -1085,  -1150,   -748,   -218,    500,     55,    335,    469,
+      3217,   2888,   -882,   -643,   -590,   -506,     43,   -459,
+      -210,   -222,   -965,   2453,   -830,   -779,   1808,   -588,
+       130,      4,    130,    -23,  -1269,   1374,  -1238,  -1148,
+      -523,   -659,   -170,   -302,   1055,   1389,  -1467,   2505,
+      -930,  -1181,   -842,   -516,    399,    886,    849,    738,
+};
+
+static const int16_t fcb22sm[] = {
+      5761,   -398,   -743,   -948,   -944,   -845,   -883,   -896,
+      -811,   -604,  -1142,  -1388,  -1190,   -685,   -118,   1498,
+      1590,    293,    564,    352,    124,    851,   -131,   -652,
+      -573,   -279,   -756,   -478,    833,    670,   2609,  -1138,
+     -1107,  -1024,   -739,   -646,   -387,     33,    635,   1037,
+      -717,   -990,  -1161,   -948,   -660,   -230,     69,   2510,
+      1274,    841,    -49,   -872,   -764,   -211,   3046,    -30,
+      -143,   -311,   -324,   -413,   -760,     67,    619,   -699,
+      -725,    305,   -484,   1292,    472,   -156,   -568,  -1243,
+     -1256,   -994,   -803,   -386,   1692,    596,   1325,   1290,
+      -492,  -1007,   -732,   -788,   1136,   -610,     45,   1307,
+       420,    649,   -534,  -1075,   -949,   -367,    219,    444,
+      -120,    251,    476,   1806,    902,   -927,  -1151,   -879,
+      -659,   -741,     -5,    298,   1861,    995,   -244,  -1031,
+     -1142,  -1085,   -952,   -773,   -468,     -9,   1637,   3592,
+      -971,  -1150,  -1199,   -985,   -689,   -317,    150,    540,
+      2727,   1678,   -223,   -403,    102,   -902,   -773,   -223,
+      3182,   -457,     75,   -188,   -291,   -428,   -101,   -365,
+      -442,   -336,   -128,    -33,    781,   1242,    501,   -753,
+      -846,    757,   -444,   -311,   1182,      4,     -8,   -122,
+      1866,   -528,   -142,   1598,    -15,   -219,   -557,   -804,
+      -916,   -965,    114,    130,   3672,    -19,   -873,   -280,
+      -777,   -919,   -824,   -654,   1078,     39,    -50,    119,
+      -411,   -311,   -359,    -57,   -137,      7,   -780,   -892,
+      -767,   -167,   1302,   1693,   -205,    -51,   -174,    -71,
+       838,   -220,  -1133,   -993,   -710,   -340,    650,   1341,
+       191,     -5,    743,   -543,   -125,   -567,     70,    -42,
+      -501,   -448,     47,   1151,    400,   -774,   -781,   1324,
+      1089,     32,   -256,   -415,   -352,   -214,    912,  -1141,
+      -988,   -638,   1349,    251,    124,     -4,     89,    -16,
+      -678,   -569,   1502,    146,    114,    816,    -98,   -269,
+      -622,   -808,   -634,   3319,   1218,   -323,   -750,   -548,
+      -525,   -575,   -591,   -730,     35,    764,   1423,    574,
+      -352,   -672,   -802,   -314,   -308,    -29,  -1040,   -717,
+       469,    421,   -527,   -420,    589,    195,    556,    472,
+      -626,   -864,   -133,   3531,   -667,   -460,   -523,    103,
+        23,   -309,   2381,    136,   1197,   -399,   -399,   -501,
+      -638,   -899,   -813,   -707,   -249,    719,    821,   -989,
+      -629,   -568,    642,     -4,    297,     70,  -1105,    454,
+       400,   -235,   -562,   1607,   -116,   -205,      1,   -490,
+         7,   -523,    764,    329,    992,   -240,   -249,   -275,
+      -366,   -265,    662,   -803,    393,   -567,   -501,    -32,
+       178,    371,    126,   -146,   1748,   -516,   -634,   -395,
+       268,    893,    154,    -36,   -620,   -999,    304,   1490,
+      -512,   -821,   -479,   1922,   -610,   -481,   -482,   -805,
+      -996,    -16,   -567,    542,    -22,    589,   -114,     69,
+       322,    358,   -848,   1205,    509,   -527,     25,    111,
+      -243,   -197,    -20,     62,   1500,   -977,   -974,   -391,
+      -555,    448,   -256,     79,    392,    547,   1472,  -1276,
+     -1203,   -987,   -315,    515,    855,    183,    231,     62,
+     -1176,   -397,   2831,   -527,   -575,   -435,    174,   -337,
+       723,    107,   -502,   -765,   -455,   1124,   -218,   1444,
+        53,   -201,   -135,   -267,   -510,  -1058,   -869,   1130,
+      -128,   -394,     16,    873,    597,    455,     16,      0,
+       -11,     14,    -12,      9,      6,    -14,    -11,    -23,
+      -453,  -1056,   -988,   -713,   -267,    794,    954,   1361,
+       822,   -448,    379,   1163,    336,   -724,     55,    109,
+       237,    -80,   -732,  -1017,   -264,    654,  -1043,  -1015,
+      -654,     91,     17,    548,    504,    932,  -1057,  -1151,
+      -964,   -130,   1171,   -146,    740,    134,    790,    539,
+      -591,   -577,   -388,    154,    609,    341,    657,    838,
+      -379,   -872,    711,   -665,   -818,   -549,   -151,   2501,
+       -28,   -189,   -255,   -378,   -363,  -1157,   -929,   -887,
+      -338,   1926,    -33,    -26,   1009,    765,    -79,    -98,
+       -37,   -967,   -566,   1012,    905,   -245,     41,    322,
+       194,   -148,   -220,   -171,   -239,   -242,   -147,    -14,
+       221,    575,   1754,   3059,   -246,   -713,   -696,   -636,
+      -640,   -843,   -841,   -755,   2554,   -504,   -568,   -318,
+      -324,   -171,   -294,   -238,   -288,   -174,   -289,   1273,
+      -231,   1053,   -284,   -338,   -394,   -227,   -303,   -226,
+       966,    742,   -873,   -503,   -586,   -286,    119,    -59,
+       339,    -38,   -843,    977,   -448,   -238,    227,    -77,
+       729,      6,     45,   -493,    277,  -1385,  -1289,   -846,
+      -117,    376,    763,    553,    769,    670,   -652,   3280,
+      -762,   -882,   -396,   -299,    124,   -270,    -31,   -210,
+      2413,    644,   -790,   -912,   -581,   -507,   -110,   -408,
+       -54,    -30,    632,    969,   -632,   -206,    955,    -95,
+      -578,   -337,   -377,   -467,   1264,     67,   -854,   -863,
+      -909,   -751,   -616,   -479,    563,   2070,   -972,   1478,
+      -450,   -715,   -859,   -689,    190,    736,    617,    530,
+};
+
+static const int16_t fcb44sl[] = {
+      2433,   -925,  -1015,  -1009,   -875,   -276,    378,    464,
+       694,    795,  -1044,   -601,   -658,    257,   -898,   -509,
+      -346,   2160,    694,    952,  -1302,   -619,    502,   -378,
+      -624,   -178,    349,   -100,    204,    546,  -1450,  -1127,
+     -1302,  -1297,  -1051,   -840,   3426,   1346,   1577,   1723,
+     -1267,   -710,   -872,    448,  -1023,   -728,   -521,   -134,
+       874,    936,  -1134,   -549,    203,   -932,  -1051,    755,
+      -608,   -199,    858,   1008,   1819,   -842,   -773,   -739,
+       818,   -371,    289,    293,    656,    704,    308,  -1009,
+      -959,  -1089,    466,   -468,    279,    897,    764,    797,
+     -1433,  -1276,  -1253,  -1326,  -1182,   -992,    -85,   4339,
+      2135,   2136,   1131,   -917,   -966,   -859,   -889,   1178,
+        62,    659,    771,    882,   1844,   -607,   1184,   -766,
+      -805,   -385,    -61,    502,    648,    732,  -1245,   1315,
+      -818,   -827,    621,   -588,    193,    480,    649,    776,
+     -1178,  -1202,  -1152,  -1088,   -857,   -191,    -49,    129,
+      1950,   1237,  -1461,  -1290,  -1342,  -1401,  -1338,  -1213,
+      -623,    224,   4086,   2517,  -1150,   -814,   -747,    916,
+       807,   -288,    319,    436,    560,    718,    392,   -973,
+      -988,    411,   -954,   -502,    214,    621,    856,    831,
+     -1268,   4012,   -852,  -1002,  -1014,   -577,     32,    552,
+       987,   1138,  -1205,  -1319,  -1145,   -928,     80,    371,
+       277,    779,    859,    902,  -1141,   -991,   -957,    707,
+      -892,   1098,    126,    381,    668,    870,  -1254,   -995,
+     -1163,   -926,  -1149,   2572,    -17,    747,   1456,   1509,
+     -1004,   -867,   1205,   -797,    938,   -657,    346,    520,
+       782,    872,  -1328,  -1080,  -1111,  -1067,   2227,   -892,
+       665,   1604,   1425,   1477,   1869,   -668,   -712,   1044,
+      -800,   -139,      0,    355,    609,    717,  -1192,   -632,
+      3546,   -780,   -870,   -501,    141,    504,    921,   1027,
+     -1125,  -1087,   1154,   -660,   -987,    937,     82,   1390,
+      1360,   1243,   1259,   -550,   -769,   -787,   -743,   -362,
+       -12,    177,    321,    505,  -1147,   -899,   -947,   -849,
+      1371,   -462,   -127,     16,    752,    954,  -1405,    448,
+     -1181,  -1259,  -1204,   -868,   -468,    110,   1293,   1263,
+     -1267,  -1180,  -1238,   -930,   -940,    916,   1793,    653,
+      1070,   1137,   -216,   -997,   -845,   -659,   -699,   -174,
+       758,    961,    417,    630,  -1123,   1691,   1229,   -732,
+      -937,   -491,    -78,    265,    744,    864,   4771,   -856,
+     -1005,  -1007,   -934,   -484,    -17,    579,    861,    959,
+     -1264,     70,   -961,   -864,   -860,   -302,    314,    788,
+       487,    686,  -1133,   -790,   -466,    561,   -812,   -256,
+      2078,    -58,    757,    953,  -1133,   -286,   -655,   -476,
+       -23,   -629,      7,    182,    426,    504,  -1110,    314,
+       497,   -822,   -662,   -754,   1179,   1726,    696,    955,
+      1793,  -1143,  -1268,  -1279,  -1207,   -873,   -183,   1546,
+      1440,   1305,  -1278,   1396,   -779,    558,   -840,    -32,
+       -18,    257,    616,    757,    265,   -906,    499,   -897,
+      -846,   -435,    362,    434,    752,    732,    453,    150,
+     -1029,  -1182,  -1195,   -940,   -297,    876,   1084,   1051,
+     -1377,   1354,  -1148,  -1313,  -1211,   -937,   -366,   1942,
+      1323,   1410,    311,   -270,    -81,   -159,     42,     42,
+         7,    357,    255,    285,   1973,   1386,   -752,   -873,
+      -916,   -466,    -39,    493,    638,    759,  -1338,   1107,
+     -1081,  -1165,  -1038,   -484,   1722,    534,   1038,   1102,
+     -1446,  -1212,  -1337,  -1452,  -1422,  -1291,   -690,   1634,
+      1348,   1640,  -1044,   -184,   -757,   -683,   -100,   1044,
+       369,    349,    432,    584,  -1137,   -528,   1425,   1294,
+      -842,   -257,    -32,    289,    639,    796,  -1418,  -1229,
+     -1282,  -1391,  -1421,  -1234,   -852,   -765,    737,   2076,
+     -1104,   -928,   -936,  -1088,    378,   -765,   1603,    581,
+       753,    925,  -1191,   -841,   -919,   2886,   -907,   -232,
+       180,    543,    956,   1070,  -1314,   -843,    804,  -1094,
+     -1209,  -1031,   -626,    698,   1049,   1152,    256,    831,
+      -841,   -814,   -841,    -54,    134,    347,    535,    658,
+       104,   -801,   -959,   -519,   -406,    156,     12,     13,
+       380,    494,  -1144,  -1112,   -973,   -965,   -916,   -474,
+      -225,    460,    402,    734,  -1448,  -1316,  -1278,    231,
+     -1086,   -578,    584,   1115,   1275,   1260,  -1321,   -963,
+     -1127,  -1288,     41,  -1102,    -31,   1331,   1003,   1145,
+       112,  -1270,  -1343,  -1376,  -1114,   -778,    392,   1918,
+      1165,   1246,  -1247,   -870,  -1232,  -1147,  -1075,    570,
+       181,   1983,    971,   1216,  -1309,  -1199,    260,  -1136,
+      -950,   -742,   1067,    703,   1150,   1144,  -1405,  -1533,
+     -1564,  -1549,  -1264,   -737,   1085,   1706,   1806,   1785,
+       282,  -1173,  -1128,  -1188,   -971,   -885,   -291,    254,
+       841,    987,   -142,  -1068,  -1264,  -1232,  -1058,    138,
+       546,    521,   1096,    987,    890,   -936,  -1020,  -1051,
+      -871,   -521,   1686,    625,    930,    936,  -1343,   -924,
+     -1231,  -1247,  -1052,   -951,   1110,    125,    826,   1116,
+};
+
+static const int16_t fcb44ss[] = {
+      6575,   -881,  -1291,  -1258,  -1090,   -517,   -268,    -56,
+       106,    295,   -303,  -1134,  -1113,   -650,   -508,   1843,
+      -235,   -141,    454,    832,  -1212,    856,   -404,   -620,
+      -682,   -487,    -69,    865,    341,     95,   3626,  -1037,
+     -1366,  -1349,  -1126,   -558,    187,    343,    657,    765,
+      -410,   -735,  -1046,  -1023,   -897,   -673,   -366,   3174,
+      1264,    720,   -730,   -922,   -523,   -821,   4042,   -463,
+        45,    329,    213,    -93,    301,  -1011,    277,   -840,
+      -820,   -451,    417,    470,    739,    953,  -1219,  -1286,
+     -1545,  -1426,  -1209,   -803,   1156,   1311,   1329,   1329,
+      -643,  -1136,  -1200,   -912,   1221,   -695,    342,    910,
+       905,    812,   -996,   -365,   4868,   -738,   -591,   -621,
+        17,    -42,      0,    100,   2085,  -1214,  -1434,  -1432,
+     -1243,   -577,   -626,    140,   1357,   1821,  -1064,  -1261,
+     -1629,  -1525,  -1488,  -1101,   -631,    551,   3556,   3974,
+      -635,   -846,  -1005,   -646,   -803,    123,   -151,    357,
+      2137,    953,  -1168,  -1055,  -1115,  -1061,   -823,   -651,
+      3842,    606,    491,    491,  -1297,  -1063,   -990,  -1051,
+     -1202,   -983,   -468,    -47,    163,    336,  -1131,   -446,
+      -683,    644,   -660,   -675,   1251,    373,    195,   -123,
+     -1109,   -430,   1820,   1883,   -862,   -743,   -265,    119,
+        66,    -41,  -1281,   -768,   1941,   -955,  -1054,   -856,
+       528,    363,    488,    545,   -936,   -682,   -814,   5534,
+      -826,   -347,     58,    -38,    168,     14,   1224,   -719,
+      -300,   -766,   -407,    630,    269,     39,   -230,   -701,
+      1601,   -958,   -945,   -955,   -734,   -487,    -20,   1392,
+       544,    282,   -118,  -1133,  -1161,  -1065,   -939,   -213,
+      -129,   -271,    451,   2570,   -895,   -805,   -536,   1455,
+      1496,   -647,   -199,    114,     95,    -42,   2230,   -855,
+      -715,   -819,   1762,   -699,    -50,   -109,    163,    207,
+      -334,   -759,   3297,   -645,   2561,     77,   -239,   -259,
+      -275,   -445,  -1304,   3536,   1610,   -526,   -926,   -582,
+       -12,     44,   -180,    -69,   -804,   1107,   1451,   -868,
+      -851,   -589,   -354,    -85,     88,    336,   -537,   -444,
+        40,    231,   -715,   -523,   -351,   -379,   -123,    171,
+      1223,   -328,   -567,   2182,   -291,   -352,     20,   -157,
+      -338,   -635,   2194,   -476,   1624,   -802,   -762,   -585,
+      -245,     48,     63,    -45,    -32,   -646,    847,   -556,
+      -727,   -259,   1309,    239,   -128,   -755,  -1018,   -640,
+       876,   -642,   -906,   1394,    -26,    338,    204,    148,
+      -988,   -521,    135,   -807,   1065,   -525,    -80,   -248,
+       383,    836,    521,     13,   -553,   -865,   -928,   -631,
+      -137,    -83,    446,    221,   1924,     48,   -621,   -845,
+      -782,   -544,   -531,   -418,    -79,    915,   -711,   1247,
+      -938,   -766,   -995,   1459,     31,    199,    261,    190,
+      -670,  -1207,  -1013,    108,   -670,    204,    407,    266,
+       473,    998,   -606,   -923,   1845,  -1061,    910,   -774,
+       268,    493,    178,     61,   1938,  -1237,  -1010,  -1097,
+      -780,   -368,   1125,    354,    398,    550,   1032,  -1128,
+     -1196,   -908,   -767,    529,   2326,    728,    227,    -13,
+     -1113,   -367,    382,   -939,  -1094,   -896,   -463,    446,
+       896,   1128,   -591,   -823,   -894,   3052,   -968,   2157,
+      -153,    -71,    111,    118,  -1106,   -930,   -911,   1663,
+      -905,   -691,   -226,    503,    665,    702,   2067,  -1149,
+      -828,    990,   -850,   -426,   -159,    148,    379,    512,
+     -1268,  -1390,  -1492,  -1343,  -1419,   2246,   -224,   2124,
+      1523,   1338,    522,   1613,   -344,   -694,   -487,   -325,
+       293,     96,   -374,   -679,   -364,    124,  -1201,  -1274,
+     -1078,   -513,     15,   1045,    529,    680,    131,  -1067,
+     -1030,   -888,   -806,   -122,   1002,   1302,    757,   -473,
+      -530,   -538,   -821,   -373,     72,    797,    864,    265,
+      -542,  -1090,   -241,  -1095,  -1205,   -991,  -1172,   5025,
+      -420,    728,    461,    103,   2325,   -915,  -1012,   -854,
+     -1117,   2018,   -377,    -35,    266,    443,   -949,  -1163,
+     -1064,  -1057,   -802,    721,   1278,    470,    308,    263,
+       474,   -773,  -1033,   -892,    227,    -30,     39,    101,
+       456,    476,  -1263,   7275,   -946,  -1157,  -1304,   -922,
+       248,    143,    -98,    312,   3419,   -402,   -649,   -629,
+      -554,    -48,    487,     72,   -171,   -687,  -1167,   1869,
+      -524,   1490,   -869,   -236,    111,     68,     77,    -85,
+      1481,    906,  -1189,  -1321,  -1124,   -554,    429,    321,
+       814,    699,  -1048,    486,   -858,  -1096,  -1072,   -744,
+      1676,    -73,    593,    632,    779,  -1265,  -1470,  -1379,
+     -1050,   -548,    781,    524,   1022,   1079,  -1149,   3719,
+     -1064,  -1180,  -1159,   -775,   -211,    241,    492,    555,
+      3025,   2828,   -849,  -1133,  -1063,   -567,    -70,   -142,
+      -176,    -62,   -614,   1745,   -684,   -610,   1478,   -619,
+      -235,   -361,    -84,    -44,  -1155,   1494,  -1183,  -1210,
+     -1294,  -1017,   -330,    210,    931,   1368,  -1306,   2714,
+     -1052,  -1128,  -1220,   -908,   2409,    441,    310,    318,
+};
+
+static const int16_t fcb44sm[] = {
+      5619,   -163,  -1005,   -856,   -831,   -644,   -612,   -759,
+      -770,   -456,    199,   -551,  -1348,    -80,    131,   -481,
+       334,    202,    366,   1246,  -1245,    499,  -1454,   -396,
+      -675,   -257,    525,   1001,    878,   1075,  -1004,  -1010,
+     -1127,   -947,   -976,    332,   3533,   1315,    265,   -683,
+     -1114,   1056,  -1009,   1154,   -728,   -212,    620,    169,
+       102,   -110,   -658,   -902,  -1238,  -1213,  -1238,   -926,
+      -735,   -455,   1130,   5139,  -1184,    190,   1590,   -604,
+      -800,   -373,   -366,    251,    720,    571,     -6,    304,
+     -1228,   -369,   -659,   -506,    -25,   -234,    313,   2366,
+       623,   1473,   -315,    780,   1048,   -416,   -586,   -737,
+     -1029,  -1094,    483,   -725,   -771,   -379,   -268,    -15,
+       697,   1774,     -1,   -999,   -987,   -867,  -1339,  -1255,
+     -1018,   -652,   -125,    643,   3006,   2417,   -543,   1629,
+      1557,   -684,   -568,   -474,   -132,   -291,   -338,   -321,
+     -1250,    641,   -158,   -935,   -575,   -575,    154,    415,
+       798,   1421,   3147,   1903,   -335,   -767,   -729,   -627,
+      -611,   -752,   -836,   -735,    678,    502,   -946,    556,
+      -821,    -51,   -256,     94,    151,     70,   -808,   -324,
+      -359,   3637,    286,    -90,   -365,   -613,   -782,   -871,
+        75,   1051,   -780,   -487,     47,    273,   1768,   -102,
+      -828,  -1267,  -1093,   1420,   -624,    225,   1307,     85,
+       239,   -152,   -649,   -853,  -1072,   -796,   -644,   1383,
+      1143,   -199,     94,    -25,     70,     52,  -1064,   2487,
+      -844,   -607,   -587,    148,    726,    224,   -238,   -484,
+      -957,   -729,   1517,   1334,   -475,   -317,   -253,   -186,
+         1,     17,   -832,   1450,    423,   1408,   -576,   -825,
+      -630,   -579,   -312,    314,    788,    382,  -1000,  -1060,
+      -763,    968,   -135,     56,    143,    477,   -736,     30,
+      4023,     68,   -266,   -420,   -538,   -751,   -893,   -879,
+      -935,     59,    465,    887,   -351,   1396,    176,   -250,
+      -684,  -1019,   -515,   -815,   -957,   -439,    188,   3794,
+        86,    -98,   -245,   -829,   1894,   -386,   -865,   1513,
+        24,   -506,   -281,   -615,   -476,   -364,  -1283,   -963,
+      -339,   -133,   -161,   -480,     25,    230,   1364,   1815,
+      1766,   -844,  -1423,  -1185,   -972,   -458,   -275,    138,
+      1317,   1778,  -1295,   -874,  -1211,   -792,   -601,   -500,
+      2301,    901,   1336,    842,   1355,   -426,  -1160,   -959,
+      -801,   -433,   1852,    144,    284,    169,  -1122,   -851,
+      -957,    272,   -393,    817,    862,    262,    333,    802,
+       320,   -576,   1615,   -615,   -886,   -311,    108,     13,
+         1,    320,  -1205,    962,   -483,   -791,   -749,   1158,
+       677,    -57,    166,    279,   -860,   1237,   -971,  -1057,
+      -598,   -285,    884,   1174,    657,   -303,   2254,   -706,
+     -1113,   -655,    719,    234,   -124,   -199,   -135,   -360,
+      -758,   -623,   -385,    -18,   3243,    470,   -139,   -286,
+      -520,   -953,  -1193,  -1140,  -1297,  -1137,   -764,     25,
+       235,   2217,   1501,   1369,   2024,    781,  -1353,   -835,
+      -824,   -601,   -259,   -140,    387,    671,      3,   -974,
+      -760,   -884,   -485,    709,   1505,    -95,    321,    739,
+      1610,   -156,   1515,    -76,   -420,   -369,   -189,   -506,
+      -705,   -907,  -1052,   -516,  -1048,   -996,   -471,   1195,
+       212,    184,    800,   1665,    747,  -1029,  -1013,    789,
+      -703,    559,   -139,    -98,    380,    523,   -355,   2047,
+      -766,   -991,   -809,   -566,   -257,   -242,    485,   1322,
+      1989,   -330,   -945,   -559,   -448,   1241,    811,     10,
+      -767,  -1218,   1600,   -755,    428,   -729,   -355,   -665,
+      -416,   -120,    381,    548,   -717,    -14,   1587,   -886,
+        -9,    353,    839,    201,   -454,  -1112,  -1334,   -309,
+       660,   -375,   -661,   -511,   1437,    540,    492,      0,
+        95,   3911,   -237,   -301,   -562,   -483,   -569,   -799,
+      -883,   -580,   -670,   -980,  -1056,   -896,   -797,   1551,
+       267,   1000,   1617,     75,  -1132,   -403,   -988,   -830,
+      -627,   1164,   1315,   1594,    310,   -564,  -1091,   -563,
+      1195,   -442,   1086,   -344,   -176,   -258,    175,    476,
+       923,    -37,   -629,   -919,   1278,   -610,    113,   -314,
+       -81,    192,    731,   -944,  -1297,  -1108,   -934,   -259,
+       640,   1164,   1326,    558,   -767,   -519,   -875,   -930,
+      -817,   -533,    496,   2605,   1359,   -131,  -1010,    912,
+     -1055,   -309,    768,   -198,   -166,    -76,    429,    640,
+      3283,   -895,  -1229,   -853,   -853,   -399,    147,     44,
+       237,    495,   -833,   -909,  -1004,   -811,   1039,   1627,
+      -194,    295,    738,    290,   -771,    237,   -912,   -479,
+      -648,   -518,   -226,    573,   2346,    419,   1013,   1510,
+      -865,   -873,   -982,   -557,    598,     50,     81,    -81,
+     -1150,   -640,  -1011,   1991,   -561,   -140,     42,    175,
+       521,    799,   3231,    -46,  -1004,   -994,  -1140,  -1094,
+      -957,   -860,      8,   2346,    212,   -499,    -55,   -997,
+      -623,   -588,     38,    -58,    975,   1529,   -986,   -891,
+     -1121,   -619,   1967,   -463,     -7,    632,    768,    953,
+};
+
+static const float lsp8[] = {
+     0.2702,  0.5096,  0.6437,  0.7672,  0.9639,  1.0696,  1.2625,  1.5789,
+     1.9285,  2.2383,  2.5129,  2.8470,  0.1740,  0.3677,  0.6082,  0.8387,
+     1.1084,  1.3721,  1.6362,  1.8733,  2.0640,  2.3442,  2.6087,  2.8548,
+     0.1536,  0.3279,  0.5143,  0.6859,  0.9763,  1.2744,  1.5605,  1.8566,
+     2.1007,  2.3450,  2.6075,  2.8850,  0.2075,  0.4533,  0.7709,  1.0377,
+     1.2953,  1.5132,  1.7826,  2.0351,  2.2590,  2.4996,  2.6795,  2.8748,
+     0.1393,  0.2453,  0.3754,  0.5453,  0.8148,  1.1289,  1.4389,  1.7592,
+     2.0353,  2.3215,  2.5934,  2.8588,  0.1250,  0.3627,  0.7613,  1.1380,
+     1.4163,  1.5565,  1.6920,  1.8130,  1.8678,  2.0427,  2.4318,  2.8544,
+     0.2256,  0.4223,  0.6452,  0.8599,  1.0673,  1.3118,  1.5486,  1.8366,
+     2.0759,  2.3026,  2.5284,  2.8030,  0.2304,  0.4404,  0.6891,  0.8964,
+     1.1510,  1.4202,  1.6483,  1.8580,  2.1181,  2.3686,  2.6078,  2.9128,
+     0.2230,  0.3816,  0.5520,  0.6062,  0.7909,  1.0988,  1.4330,  1.7846,
+     2.0713,  2.3457,  2.6048,  2.8708,  0.2447,  0.5800,  0.8249,  0.9905,
+     1.1721,  1.3990,  1.6694,  1.9064,  2.1307,  2.4255,  2.6815,  2.9117,
+     0.1974,  0.3812,  0.5802,  0.7759,  0.9280,  1.1547,  1.4170,  1.6369,
+     1.8890,  2.2587,  2.5626,  2.8239,  0.1209,  0.2510,  0.4841,  0.8048,
+     1.1197,  1.3563,  1.6073,  1.8926,  2.1350,  2.3669,  2.6291,  2.8985,
+     0.2352,  0.4347,  0.6582,  0.8178,  0.9548,  1.1654,  1.4942,  1.8812,
+     2.1703,  2.3779,  2.6412,  2.8871,  0.2091,  0.4084,  0.6730,  0.9151,
+     1.1259,  1.3262,  1.5937,  1.8129,  2.0237,  2.3317,  2.5778,  2.8620,
+     0.1167,  0.2406,  0.4520,  0.7298,  0.9848,  1.2448,  1.5137,  1.7874,
+     2.0280,  2.3020,  2.5914,  2.8794,  0.3003,  0.4966,  0.6520,  0.8505,
+     1.1600,  1.3981,  1.5805,  1.8346,  2.0757,  2.3102,  2.5760,  2.8499,
+     0.2451,  0.4163,  0.5960,  0.7805,  0.9507,  1.2438,  1.5587,  1.8581,
+     2.0735,  2.3198,  2.5704,  2.8220,  0.3112,  0.5517,  0.7032,  0.8528,
+     1.1489,  1.4257,  1.6848,  1.9388,  2.1577,  2.4265,  2.6678,  2.9051,
+     0.2249,  0.3897,  0.5559,  0.7473,  1.0158,  1.3581,  1.6914,  1.9930,
+     2.1843,  2.3534,  2.5512,  2.8065,  0.2600,  0.4574,  0.7349,  0.9691,
+     1.1696,  1.3848,  1.6335,  1.9021,  2.1174,  2.3481,  2.5902,  2.8390,
+     0.2246,  0.3372,  0.4560,  0.5249,  0.7056,  1.0273,  1.3810,  1.7132,
+     1.9819,  2.2574,  2.5410,  2.8491,  0.1419,  0.4834,  0.8835,  1.1453,
+     1.2839,  1.4224,  1.5593,  1.7877,  2.1285,  2.4070,  2.6043,  2.8511,
+     0.1886,  0.3677,  0.5617,  0.8099,  1.1277,  1.3841,  1.5804,  1.8136,
+     2.0307,  2.2805,  2.5399,  2.8322,  0.2351,  0.4151,  0.6675,  0.8713,
+     1.0464,  1.3292,  1.6586,  1.9281,  2.1355,  2.3495,  2.6222,  2.8782,
+     0.2700,  0.4489,  0.6206,  0.7121,  0.7737,  0.9848,  1.3658,  1.7433,
+     2.0139,  2.2243,  2.4806,  2.8175,  0.2479,  0.4425,  0.6490,  0.8745,
+     1.1161,  1.3849,  1.6773,  1.9566,  2.1491,  2.3624,  2.5685,  2.8114,
+     0.2035,  0.3701,  0.5567,  0.7953,  1.0082,  1.2758,  1.5373,  1.7822,
+     2.0175,  2.2601,  2.4759,  2.7771,  0.1856,  0.3461,  0.5998,  0.9041,
+     1.2383,  1.4612,  1.6667,  1.9305,  2.1617,  2.4107,  2.6477,  2.8656,
+     0.2107,  0.3715,  0.5289,  0.6651,  0.8420,  1.1168,  1.4401,  1.7230,
+     1.9901,  2.2687,  2.5452,  2.8655,  0.1218,  0.2999,  0.6348,  0.9482,
+     1.2745,  1.5876,  1.9129,  2.2348,  2.4020,  2.4922,  2.6351,  2.8357,
+     0.1617,  0.3483,  0.5869,  0.8163,  1.0366,  1.2344,  1.4609,  1.7029,
+     1.9476,  2.2337,  2.5258,  2.8442,  0.2505,  0.4894,  0.7510,  0.9152,
+     1.0845,  1.3657,  1.6528,  1.8346,  2.0160,  2.2811,  2.5338,  2.8136,
+     0.0947,  0.1158,  0.0578, -0.0337, -0.0066,  0.0104, -0.0447, -0.0505,
+    -0.0778, -0.0293,  0.0251, -0.0143,  0.0349, -0.0227, -0.0909,  0.0523,
+     0.0325, -0.0410, -0.1045, -0.0899, -0.0009,  0.0075, -0.0575, -0.0855,
+    -0.0129,  0.0575,  0.0597,  0.0391,  0.0371, -0.0184, -0.0083,  0.0287,
+     0.0143,  0.0167,  0.0120, -0.0168,  0.0452,  0.0223, -0.0352,  0.0119,
+    -0.0496, -0.0965, -0.0661, -0.0072,  0.1099,  0.0843, -0.0087, -0.0478,
+    -0.0128, -0.0120, -0.0004,  0.0731,  0.1047,  0.0630,  0.0196, -0.0103,
+    -0.0399, -0.0986, -0.0912, -0.0390, -0.0247, -0.0694, -0.0749, -0.0066,
+     0.0223,  0.0634,  0.0343, -0.0134,  0.0727,  0.0241,  0.0066,  0.0437,
+     0.0610,  0.0364,  0.0248, -0.0358, -0.0686, -0.0104,  0.0426,  0.0088,
+    -0.0137, -0.0165,  0.0671,  0.0815, -0.0863, -0.0644, -0.0088,  0.0023,
+     0.0482,  0.1174,  0.1270,  0.0594,  0.0165,  0.0949,  0.1098,  0.0137,
+     0.4951,  0.4999,  0.4958,  0.4907,  0.4984,  0.4965,  0.4958,  0.4996,
+     0.4987,  0.4958,  0.4986,  0.4977,  0.2841,  0.2186,  0.1474,  0.1687,
+     0.2217,  0.2632,  0.2706,  0.2624,  0.2162,  0.2453,  0.2460,  0.2531,
+};
+
+static const float lsp8s[] = {
+     0.2702,  0.5096,  0.6437,  0.7672,  0.9639,  1.0696,  1.2625,  1.5789,
+     1.9285,  2.2383,  2.5129,  2.8470,  0.1740,  0.3677,  0.6082,  0.8387,
+     1.1084,  1.3721,  1.6362,  1.8733,  2.0640,  2.3442,  2.6087,  2.8548,
+     0.1536,  0.3279,  0.5143,  0.6859,  0.9763,  1.2744,  1.5605,  1.8566,
+     2.1007,  2.3450,  2.6075,  2.8850,  0.2075,  0.4533,  0.7709,  1.0377,
+     1.2953,  1.5132,  1.7826,  2.0351,  2.2590,  2.4996,  2.6795,  2.8748,
+     0.1393,  0.2453,  0.3754,  0.5453,  0.8148,  1.1289,  1.4389,  1.7592,
+     2.0353,  2.3215,  2.5934,  2.8588,  0.1250,  0.3627,  0.7613,  1.1380,
+     1.4163,  1.5565,  1.6920,  1.8130,  1.8678,  2.0427,  2.4318,  2.8544,
+     0.2256,  0.4223,  0.6452,  0.8599,  1.0673,  1.3118,  1.5486,  1.8366,
+     2.0759,  2.3026,  2.5284,  2.8030,  0.2304,  0.4404,  0.6891,  0.8964,
+     1.1510,  1.4202,  1.6483,  1.8580,  2.1181,  2.3686,  2.6078,  2.9128,
+     0.2230,  0.3816,  0.5520,  0.6062,  0.7909,  1.0988,  1.4330,  1.7846,
+     2.0713,  2.3457,  2.6048,  2.8708,  0.2447,  0.5800,  0.8249,  0.9905,
+     1.1721,  1.3990,  1.6694,  1.9064,  2.1307,  2.4255,  2.6815,  2.9117,
+     0.1974,  0.3812,  0.5802,  0.7759,  0.9280,  1.1547,  1.4170,  1.6369,
+     1.8890,  2.2587,  2.5626,  2.8239,  0.1209,  0.2510,  0.4841,  0.8048,
+     1.1197,  1.3563,  1.6073,  1.8926,  2.1350,  2.3669,  2.6291,  2.8985,
+     0.2352,  0.4347,  0.6582,  0.8178,  0.9548,  1.1654,  1.4942,  1.8812,
+     2.1703,  2.3779,  2.6412,  2.8871,  0.2091,  0.4084,  0.6730,  0.9151,
+     1.1259,  1.3262,  1.5937,  1.8129,  2.0237,  2.3317,  2.5778,  2.8620,
+     0.1167,  0.2406,  0.4520,  0.7298,  0.9848,  1.2448,  1.5137,  1.7874,
+     2.0280,  2.3020,  2.5914,  2.8794,  0.3003,  0.4966,  0.6520,  0.8505,
+     1.1600,  1.3981,  1.5805,  1.8346,  2.0757,  2.3102,  2.5760,  2.8499,
+     0.2451,  0.4163,  0.5960,  0.7805,  0.9507,  1.2438,  1.5587,  1.8581,
+     2.0735,  2.3198,  2.5704,  2.8220,  0.3112,  0.5517,  0.7032,  0.8528,
+     1.1489,  1.4257,  1.6848,  1.9388,  2.1577,  2.4265,  2.6678,  2.9051,
+     0.2249,  0.3897,  0.5559,  0.7473,  1.0158,  1.3581,  1.6914,  1.9930,
+     2.1843,  2.3534,  2.5512,  2.8065,  0.2600,  0.4574,  0.7349,  0.9691,
+     1.1696,  1.3848,  1.6335,  1.9021,  2.1174,  2.3481,  2.5902,  2.8390,
+     0.2246,  0.3372,  0.4560,  0.5249,  0.7056,  1.0273,  1.3810,  1.7132,
+     1.9819,  2.2574,  2.5410,  2.8491,  0.1419,  0.4834,  0.8835,  1.1453,
+     1.2839,  1.4224,  1.5593,  1.7877,  2.1285,  2.4070,  2.6043,  2.8511,
+     0.1886,  0.3677,  0.5617,  0.8099,  1.1277,  1.3841,  1.5804,  1.8136,
+     2.0307,  2.2805,  2.5399,  2.8322,  0.2351,  0.4151,  0.6675,  0.8713,
+     1.0464,  1.3292,  1.6586,  1.9281,  2.1355,  2.3495,  2.6222,  2.8782,
+     0.2700,  0.4489,  0.6206,  0.7121,  0.7737,  0.9848,  1.3658,  1.7433,
+     2.0139,  2.2243,  2.4806,  2.8175,  0.2479,  0.4425,  0.6490,  0.8745,
+     1.1161,  1.3849,  1.6773,  1.9566,  2.1491,  2.3624,  2.5685,  2.8114,
+     0.2035,  0.3701,  0.5567,  0.7953,  1.0082,  1.2758,  1.5373,  1.7822,
+     2.0175,  2.2601,  2.4759,  2.7771,  0.1856,  0.3461,  0.5998,  0.9041,
+     1.2383,  1.4612,  1.6667,  1.9305,  2.1617,  2.4107,  2.6477,  2.8656,
+     0.2107,  0.3715,  0.5289,  0.6651,  0.8420,  1.1168,  1.4401,  1.7230,
+     1.9901,  2.2687,  2.5452,  2.8655,  0.1218,  0.2999,  0.6348,  0.9482,
+     1.2745,  1.5876,  1.9129,  2.2348,  2.4020,  2.4922,  2.6351,  2.8357,
+     0.1617,  0.3483,  0.5869,  0.8163,  1.0366,  1.2344,  1.4609,  1.7029,
+     1.9476,  2.2337,  2.5258,  2.8442,  0.2505,  0.4894,  0.7510,  0.9152,
+     1.0845,  1.3657,  1.6528,  1.8346,  2.0160,  2.2811,  2.5338,  2.8136,
+     0.0947,  0.1158,  0.0578, -0.0337, -0.0066,  0.0104, -0.0447, -0.0505,
+    -0.0778, -0.0293,  0.0251, -0.0143,  0.0349, -0.0227, -0.0909,  0.0523,
+     0.0325, -0.0410, -0.1045, -0.0899, -0.0009,  0.0075, -0.0575, -0.0855,
+    -0.0129,  0.0575,  0.0597,  0.0391,  0.0371, -0.0184, -0.0083,  0.0287,
+     0.0143,  0.0167,  0.0120, -0.0168,  0.0452,  0.0223, -0.0352,  0.0119,
+    -0.0496, -0.0965, -0.0661, -0.0072,  0.1099,  0.0843, -0.0087, -0.0478,
+    -0.0128, -0.0120, -0.0004,  0.0731,  0.1047,  0.0630,  0.0196, -0.0103,
+    -0.0399, -0.0986, -0.0912, -0.0390, -0.0247, -0.0694, -0.0749, -0.0066,
+     0.0223,  0.0634,  0.0343, -0.0134,  0.0727,  0.0241,  0.0066,  0.0437,
+     0.0610,  0.0364,  0.0248, -0.0358, -0.0686, -0.0104,  0.0426,  0.0088,
+    -0.0137, -0.0165,  0.0671,  0.0815, -0.0863, -0.0644, -0.0088,  0.0023,
+     0.0482,  0.1174,  0.1270,  0.0594,  0.0165,  0.0949,  0.1098,  0.0137,
+     0.4951,  0.4999,  0.4958,  0.4907,  0.4984,  0.4965,  0.4958,  0.4996,
+     0.4987,  0.4958,  0.4986,  0.4977,  0.2841,  0.2186,  0.1474,  0.1687,
+     0.2217,  0.2632,  0.2706,  0.2624,  0.2162,  0.2453,  0.2460,  0.2531,
+};
+
+static const float lsp11[] = {
+     0.1103,  0.3862,  0.6863,  0.8447,  0.9231,  1.0261,  1.1248,  1.4057,
+     1.6621,  1.8010,  1.8692,  2.0704,  2.3490,  2.6060,  2.7539,  2.8977,
+     0.1273,  0.2407,  0.3812,  0.6004,  0.7767,  0.9383,  1.1344,  1.3351,
+     1.5233,  1.7262,  1.9466,  2.1739,  2.3495,  2.5162,  2.7164,  2.9202,
+     0.2010,  0.3330,  0.4488,  0.6465,  0.8046,  0.9889,  1.1479,  1.2964,
+     1.4770,  1.6606,  1.8789,  2.1155,  2.3287,  2.5199,  2.7101,  2.9119,
+     0.1168,  0.2197,  0.3279,  0.4691,  0.6268,  0.8251,  1.0533,  1.2714,
+     1.4712,  1.6762,  1.8831,  2.1114,  2.3230,  2.5297,  2.7365,  2.9270,
+     0.1405,  0.3109,  0.4986,  0.6891,  0.8634,  1.0583,  1.2594,  1.4349,
+     1.6232,  1.8116,  1.9905,  2.1935,  2.3799,  2.5656,  2.7661,  2.9486,
+     0.1703,  0.3057,  0.4403,  0.5225,  0.5969,  0.8110,  1.0729,  1.3215,
+     1.5407,  1.7381,  1.9477,  2.1680,  2.3586,  2.5612,  2.7630,  2.9410,
+     0.1128,  0.2628,  0.4523,  0.6495,  0.8176,  0.9816,  1.1746,  1.3710,
+     1.5568,  1.7518,  1.9497,  2.1452,  2.3346,  2.5389,  2.7362,  2.9264,
+     0.1809,  0.3287,  0.5205,  0.7264,  0.9298,  1.1217,  1.2970,  1.4894,
+     1.6874,  1.8493,  2.0576,  2.2382,  2.4097,  2.6041,  2.7796,  2.9389,
+     0.2502,  0.4709,  0.6892,  0.8346,  0.9209,  1.0455,  1.2399,  1.4616,
+     1.6463,  1.8380,  2.0475,  2.2397,  2.4665,  2.6550,  2.7701,  2.8895,
+     0.1040,  0.2340,  0.3964,  0.5740,  0.7764,  0.9941,  1.2000,  1.4014,
+     1.6024,  1.7974,  1.9939,  2.1959,  2.3783,  2.5663,  2.7613,  2.9484,
+     0.1912,  0.3393,  0.4743,  0.6313,  0.8014,  0.9879,  1.1855,  1.3922,
+     1.5678,  1.7289,  1.9271,  2.1165,  2.3089,  2.5414,  2.7448,  2.9269,
+     0.0965,  0.2025,  0.3398,  0.4990,  0.6934,  0.9386,  1.1730,  1.3766,
+     1.5783,  1.7783,  1.9790,  2.1831,  2.3670,  2.5578,  2.7641,  2.9516,
+     0.2126,  0.3652,  0.5545,  0.7170,  0.8674,  1.0640,  1.2558,  1.4061,
+     1.5904,  1.8095,  1.9760,  2.1505,  2.3549,  2.5575,  2.7023,  2.8877,
+     0.1827,  0.3426,  0.4894,  0.6488,  0.7960,  0.9535,  1.1217,  1.2798,
+     1.4566,  1.6453,  1.8044,  2.0042,  2.2379,  2.4611,  2.6697,  2.8966,
+     0.2034,  0.3822,  0.5231,  0.6960,  0.9200,  1.0394,  1.1616,  1.3772,
+     1.5493,  1.7330,  1.9646,  2.1233,  2.3334,  2.5361,  2.7087,  2.9470,
+     0.1050,  0.2060,  0.3705,  0.5998,  0.8337,  1.0577,  1.2559,  1.4327,
+     1.6334,  1.8165,  1.9853,  2.2058,  2.4063,  2.5818,  2.7625,  2.9458,
+     0.1419,  0.4053,  0.6660,  0.8911,  1.0405,  1.1547,  1.2506,  1.3926,
+     1.5669,  1.7527,  1.9694,  2.2054,  2.3889,  2.5743,  2.7586,  2.9174,
+     0.1514,  0.2825,  0.4309,  0.5772,  0.7470,  0.9703,  1.1462,  1.3316,
+     1.5321,  1.7259,  1.9282,  2.1266,  2.3106,  2.5064,  2.7067,  2.9094,
+     0.1693,  0.3156,  0.4878,  0.6635,  0.8206,  0.9569,  1.1154,  1.3064,
+     1.5109,  1.7184,  1.9179,  2.1036,  2.2763,  2.4820,  2.6949,  2.9105,
+     0.1432,  0.2718,  0.4241,  0.5564,  0.6939,  0.9011,  1.1582,  1.3948,
+     1.6181,  1.8024,  1.9814,  2.1740,  2.3459,  2.5456,  2.7491,  2.9307,
+     0.2294,  0.3857,  0.5590,  0.7434,  0.9189,  1.0941,  1.2740,  1.4456,
+     1.6178,  1.7994,  1.9689,  2.1644,  2.3525,  2.5385,  2.7468,  2.9405,
+     0.1667,  0.3109,  0.4612,  0.6032,  0.7375,  0.8866,  1.0840,  1.3053,
+     1.4982,  1.7044,  1.9146,  2.1117,  2.2942,  2.4983,  2.7084,  2.9132,
+     0.1810,  0.3205,  0.4696,  0.6231,  0.7641,  0.9959,  1.2427,  1.4361,
+     1.5889,  1.7544,  1.9083,  2.0733,  2.2457,  2.4461,  2.6793,  2.9098,
+     0.1164,  0.3753,  0.6068,  0.7503,  1.0100,  1.2131,  1.3793,  1.5302,
+     1.6300,  1.7950,  1.9057,  2.1031,  2.3830,  2.5745,  2.6949,  2.8779,
+     0.1571,  0.4378,  0.6735,  0.8312,  0.8944,  0.9818,  1.1622,  1.4094,
+     1.6423,  1.8066,  1.9258,  2.1838,  2.4363,  2.6279,  2.7358,  2.8790,
+     0.1398,  0.2686,  0.4248,  0.6156,  0.7870,  1.0035,  1.2012,  1.3689,
+     1.5363,  1.7398,  1.9604,  2.1619,  2.3345,  2.5097,  2.7271,  2.9368,
+     0.1913,  0.3338,  0.4987,  0.6446,  0.7852,  1.0163,  1.1886,  1.3610,
+     1.5379,  1.7230,  1.8880,  2.0862,  2.2960,  2.4928,  2.7122,  2.9151,
+     0.0908,  0.1752,  0.2899,  0.5365,  0.7761,  1.0100,  1.2124,  1.4060,
+     1.6019,  1.8010,  1.9774,  2.1905,  2.3733,  2.5623,  2.7660,  2.9565,
+     0.1773,  0.3179,  0.4925,  0.6864,  0.8452,  0.9897,  1.1860,  1.3722,
+     1.5515,  1.7658,  1.9802,  2.1819,  2.3620,  2.5442,  2.7250,  2.9220,
+     0.1286,  0.2341,  0.3689,  0.5364,  0.7176,  0.9350,  1.1083,  1.2943,
+     1.4974,  1.7059,  1.9047,  2.1145,  2.3242,  2.5361,  2.7453,  2.9329,
+     0.2273,  0.3834,  0.5565,  0.7192,  0.8431,  0.9962,  1.1763,  1.3571,
+     1.5774,  1.7419,  1.9202,  2.1131,  2.2919,  2.4898,  2.6895,  2.9180,
+     0.1775,  0.3058,  0.4274,  0.6023,  0.8151,  1.0734,  1.3211,  1.5178,
+     1.6706,  1.8154,  1.9686,  2.1537,  2.3461,  2.5276,  2.7181,  2.9121,
+     0.1653,  0.4304,  0.6361,  0.7824,  0.9183,  1.0452,  1.2071,  1.4077,
+     1.6206,  1.8299,  2.0089,  2.1948,  2.3900,  2.5982,  2.7844,  2.9487,
+     0.1492,  0.2609,  0.3820,  0.5485,  0.7243,  0.9319,  1.1538,  1.3579,
+     1.5266,  1.7002,  1.8873,  2.1016,  2.3175,  2.5221,  2.7241,  2.9243,
+     0.2074,  0.3781,  0.5209,  0.6869,  0.8577,  0.9875,  1.1849,  1.3568,
+     1.4907,  1.7335,  1.8902,  2.1224,  2.3099,  2.4918,  2.7023,  2.8765,
+     0.1359,  0.2254,  0.3286,  0.4432,  0.6586,  0.8964,  1.1125,  1.3523,
+     1.5626,  1.7579,  1.9846,  2.1905,  2.3548,  2.5542,  2.7663,  2.9346,
+     0.1430,  0.2966,  0.4685,  0.6493,  0.8315,  1.0304,  1.2220,  1.4082,
+     1.5995,  1.7888,  1.9774,  2.1737,  2.3607,  2.5577,  2.7558,  2.9405,
+     0.1477,  0.2694,  0.4056,  0.5626,  0.7051,  0.8647,  1.0491,  1.2488,
+     1.4814,  1.7072,  1.9150,  2.1147,  2.3038,  2.5144,  2.7184,  2.9202,
+     0.1690,  0.3033,  0.4580,  0.6686,  0.8536,  1.0293,  1.2124,  1.3998,
+     1.5718,  1.7607,  1.9580,  2.1245,  2.2971,  2.4762,  2.6896,  2.9177,
+     0.1092,  0.2779,  0.4853,  0.6880,  0.9011,  1.0953,  1.2752,  1.4618,
+     1.6623,  1.8484,  2.0264,  2.2152,  2.4017,  2.5835,  2.7671,  2.9436,
+     0.1497,  0.3637,  0.6014,  0.8032,  0.9963,  1.1835,  1.3741,  1.5698,
+     1.7382,  1.9094,  2.0710,  2.2392,  2.4082,  2.5926,  2.7762,  2.9536,
+     0.1434,  0.2492,  0.3966,  0.5934,  0.8033,  1.0657,  1.2796,  1.4276,
+     1.5745,  1.7833,  1.9288,  2.1247,  2.3543,  2.5412,  2.7049,  2.8872,
+     0.1612,  0.2926,  0.4574,  0.6387,  0.8265,  1.0180,  1.1808,  1.3526,
+     1.5564,  1.7536,  1.9187,  2.1192,  2.3149,  2.5006,  2.7101,  2.9217,
+     0.0828,  0.1863,  0.3235,  0.5050,  0.7250,  0.9867,  1.2093,  1.3941,
+     1.5980,  1.7932,  1.9809,  2.1894,  2.3918,  2.5773,  2.7540,  2.9329,
+     0.2001,  0.3655,  0.5290,  0.6761,  0.8027,  0.9972,  1.2090,  1.4255,
+     1.6085,  1.7825,  1.9804,  2.1681,  2.3457,  2.5325,  2.7319,  2.9196,
+     0.1505,  0.2767,  0.4254,  0.6054,  0.7821,  0.9567,  1.1294,  1.3080,
+     1.4984,  1.6954,  1.8666,  2.0736,  2.2875,  2.4969,  2.7072,  2.9163,
+     0.1589,  0.4151,  0.5749,  0.6651,  0.8061,  1.0470,  1.2616,  1.3690,
+     1.4985,  1.7808,  1.9825,  2.1068,  2.2751,  2.5448,  2.7133,  2.8689,
+     0.0916,  0.1846,  0.3788,  0.6329,  0.8774,  1.0687,  1.2653,  1.4561,
+     1.6573,  1.8449,  2.0402,  2.2254,  2.3968,  2.5861,  2.7792,  2.9508,
+     0.2282,  0.4159,  0.5834,  0.6899,  0.8108,  1.0321,  1.2795,  1.5262,
+     1.6936,  1.8469,  2.0922,  2.2607,  2.3795,  2.5301,  2.7386,  2.9530,
+     0.1651,  0.3004,  0.4555,  0.6179,  0.7891,  0.9584,  1.1372,  1.3707,
+     1.5951,  1.7880,  1.9434,  2.1465,  2.3311,  2.5081,  2.6977,  2.8970,
+     0.1279,  0.3828,  0.6330,  0.8323,  0.9652,  1.1175,  1.2319,  1.3511,
+     1.5115,  1.6392,  1.7835,  1.9558,  2.2008,  2.4635,  2.6910,  2.9058,
+     0.1193,  0.2185,  0.3521,  0.5311,  0.7378,  0.9239,  1.1105,  1.3217,
+     1.5362,  1.7504,  1.9536,  2.1627,  2.3560,  2.5506,  2.7548,  2.9453,
+     0.1806,  0.3432,  0.4981,  0.6948,  0.8928,  1.0527,  1.2467,  1.4140,
+     1.6326,  1.7950,  1.9935,  2.1969,  2.3512,  2.5682,  2.7445,  2.9277,
+     0.1846,  0.3112,  0.4568,  0.5891,  0.7317,  0.8493,  1.0204,  1.2022,
+     1.3688,  1.6020,  1.8428,  2.0710,  2.2725,  2.4879,  2.7057,  2.9160,
+     0.0880,  0.2514,  0.5332,  0.7272,  0.8906,  1.1354,  1.3199,  1.4941,
+     1.6010,  1.7151,  1.8712,  2.0643,  2.2755,  2.5375,  2.7054,  2.8891,
+     0.1382,  0.2833,  0.4658,  0.6897,  0.9071,  1.0716,  1.2469,  1.4143,
+     1.5910,  1.7947,  1.9805,  2.1581,  2.3338,  2.5215,  2.7292,  2.9211,
+     0.1061,  0.3494,  0.6327,  0.8570,  0.9748,  1.0560,  1.1529,  1.3250,
+     1.6032,  1.8340,  1.9711,  2.1157,  2.3011,  2.5464,  2.8078,  2.9803,
+     0.1603,  0.2839,  0.4307,  0.5980,  0.7980,  1.0399,  1.1971,  1.3524,
+     1.5715,  1.7838,  1.9468,  2.1498,  2.3627,  2.5514,  2.7327,  2.9148,
+     0.1691,  0.3117,  0.4796,  0.6895,  0.8732,  1.0164,  1.1916,  1.3707,
+     1.5384,  1.7202,  1.8857,  2.0672,  2.2487,  2.4593,  2.6789,  2.8940,
+     0.0965,  0.1702,  0.3191,  0.5721,  0.8100,  1.0241,  1.2272,  1.4196,
+     1.6093,  1.8057,  1.9884,  2.2037,  2.3925,  2.5805,  2.7578,  2.9366,
+     0.1950,  0.3519,  0.5272,  0.6973,  0.8732,  1.0656,  1.2112,  1.3959,
+     1.6116,  1.7821,  1.9445,  2.1592,  2.3348,  2.5142,  2.7440,  2.9297,
+     0.1388,  0.2557,  0.4120,  0.5727,  0.7354,  0.9196,  1.0985,  1.2805,
+     1.4643,  1.6535,  1.8340,  2.0546,  2.2758,  2.4778,  2.6921,  2.9122,
+     0.1823,  0.3336,  0.4957,  0.6771,  0.8563,  1.0137,  1.2299,  1.3849,
+     1.5718,  1.7667,  1.9193,  2.1326,  2.3135,  2.5268,  2.7133,  2.8998,
+     0.0790,  0.1901,  0.4083,  0.6456,  0.8463,  1.0285,  1.2297,  1.4181,
+     1.6159,  1.8056,  1.9971,  2.1912,  2.3816,  2.5746,  2.7692,  2.9497,
+     0.0049,  0.0116,  0.0045,  0.0039, -0.0010, -0.0122, -0.0205, -0.0034,
+    -0.0140, -0.0041,  0.0191, -0.0322,  0.0002, -0.0124, -0.0269,  0.0059,
+     0.0586,  0.0339, -0.0389, -0.0319, -0.0079, -0.0205, -0.0363, -0.0211,
+     0.0241,  0.0595,  0.0469,  0.0283,  0.0176, -0.0183, -0.0173, -0.0004,
+     0.0024,  0.0145,  0.0534,  0.0197, -0.0065, -0.0067,  0.0133,  0.0358,
+    -0.0104, -0.0386, -0.0109, -0.0078,  0.0275,  0.0565,  0.0251, -0.0027,
+    -0.0053,  0.0171,  0.0088,  0.0495,  0.0141,  0.0039, -0.0445, -0.0426,
+    -0.0184, -0.0280, -0.0223,  0.0039, -0.0171, -0.0606, -0.0786, -0.0430,
+     0.0544,  0.0595,  0.0320, -0.0012,  0.0108,  0.0185,  0.0066,  0.0408,
+     0.0552, -0.0073, -0.0247, -0.0480, -0.0288,  0.0186,  0.0212, -0.0013,
+     0.0403,  0.0598,  0.0690,  0.0516, -0.0298, -0.0177,  0.0278,  0.0168,
+    -0.0106,  0.0251,  0.0386,  0.0331, -0.0052,  0.0133,  0.0291, -0.0158,
+    -0.0329, -0.0367,  0.0287,  0.0462, -0.0176,  0.0049,  0.0242, -0.0034,
+     0.0135,  0.0086, -0.0149,  0.0241,  0.0504,  0.0246, -0.0273, -0.0369,
+    -0.0108, -0.0449, -0.0625, -0.0414, -0.0292, -0.0571, -0.0440, -0.0088,
+     0.0098,  0.0009, -0.0004,  0.0007, -0.0314, -0.0208, -0.0138, -0.0277,
+    -0.0044,  0.0522,  0.0315, -0.0270, -0.0277, -0.0256, -0.0103, -0.0201,
+    -0.0287, -0.0279, -0.0182,  0.0472,  0.0613,  0.0450,  0.0413,  0.0333,
+     0.0444,  0.0223,  0.0061,  0.0316,  0.0321,  0.0501,  0.0460,  0.0250,
+     0.0227,  0.0235,  0.0099,  0.0185, -0.0347, -0.0684, -0.0189,  0.0242,
+    -0.0190, -0.0273, -0.0012, -0.0253,  0.0293, -0.0231, -0.0219, -0.0010,
+     0.0153,  0.0128, -0.0166, -0.0435, -0.0417, -0.0121, -0.0351, -0.0390,
+     0.0077, -0.0278, -0.0355,  0.0092, -0.0063,  0.0005,  0.0216,  0.0461,
+     0.0538,  0.0451,  0.0298, -0.0130,  0.0058,  0.0206,  0.0471,  0.0499,
+     0.0280,  0.0086, -0.0007, -0.0317,  0.0259,  0.0176,  0.0043,  0.0212,
+     0.0138,  0.0106,  0.0220, -0.0025,  0.0050,  0.0122, -0.0051, -0.0086,
+    -0.0472, -0.0005,  0.0193,  0.0032,  0.0246,  0.0222,  0.0090, -0.0320,
+    -0.0713, -0.0526, -0.0151, -0.0440, -0.0648, -0.0466, -0.0092,  0.0115,
+    -0.0129,  0.0053, -0.0344, -0.0385,  0.0392,  0.0599,  0.0414,  0.0165,
+    -0.0098, -0.0320, -0.0261, -0.0055, -0.0139, -0.0110,  0.0084,  0.0172,
+    -0.0492, -0.0537, -0.0320, -0.0036,  0.0265,  0.0385,  0.0064, -0.0280,
+    -0.0230,  0.0134,  0.0241,  0.0106,  0.0387,  0.0105,  0.0068,  0.0260,
+     0.4940,  0.4911,  0.4849,  0.4820,  0.4837,  0.4839,  0.4824,  0.4799,
+     0.4812,  0.4782,  0.4788,  0.4711,  0.4706,  0.4671,  0.4601,  0.4578,
+     0.2954,  0.2121,  0.1859,  0.1958,  0.1474,  0.1086,  0.1351,  0.1362,
+     0.1486,  0.1342,  0.1215,  0.1423,  0.1634,  0.1588,  0.1539,  0.1857,
+};
+
+static const float lsp11s[] = {
+     0.1103,  0.3862,  0.6863,  0.8447,  0.9231,  1.0261,  1.1248,  1.4057,
+     1.6621,  1.8010,  1.8692,  2.0704,  2.3490,  2.6060,  2.7539,  2.8977,
+     0.1273,  0.2407,  0.3812,  0.6004,  0.7767,  0.9383,  1.1344,  1.3351,
+     1.5233,  1.7262,  1.9466,  2.1739,  2.3495,  2.5162,  2.7164,  2.9202,
+     0.2010,  0.3330,  0.4488,  0.6465,  0.8046,  0.9889,  1.1479,  1.2964,
+     1.4770,  1.6606,  1.8789,  2.1155,  2.3287,  2.5199,  2.7101,  2.9119,
+     0.1168,  0.2197,  0.3279,  0.4691,  0.6268,  0.8251,  1.0533,  1.2714,
+     1.4712,  1.6762,  1.8831,  2.1114,  2.3230,  2.5297,  2.7365,  2.9270,
+     0.1405,  0.3109,  0.4986,  0.6891,  0.8634,  1.0583,  1.2594,  1.4349,
+     1.6232,  1.8116,  1.9905,  2.1935,  2.3799,  2.5656,  2.7661,  2.9486,
+     0.1703,  0.3057,  0.4403,  0.5225,  0.5969,  0.8110,  1.0729,  1.3215,
+     1.5407,  1.7381,  1.9477,  2.1680,  2.3586,  2.5612,  2.7630,  2.9410,
+     0.1128,  0.2628,  0.4523,  0.6495,  0.8176,  0.9816,  1.1746,  1.3710,
+     1.5568,  1.7518,  1.9497,  2.1452,  2.3346,  2.5389,  2.7362,  2.9264,
+     0.1809,  0.3287,  0.5205,  0.7264,  0.9298,  1.1217,  1.2970,  1.4894,
+     1.6874,  1.8493,  2.0576,  2.2382,  2.4097,  2.6041,  2.7796,  2.9389,
+     0.2502,  0.4709,  0.6892,  0.8346,  0.9209,  1.0455,  1.2399,  1.4616,
+     1.6463,  1.8380,  2.0475,  2.2397,  2.4665,  2.6550,  2.7701,  2.8895,
+     0.1040,  0.2340,  0.3964,  0.5740,  0.7764,  0.9941,  1.2000,  1.4014,
+     1.6024,  1.7974,  1.9939,  2.1959,  2.3783,  2.5663,  2.7613,  2.9484,
+     0.1912,  0.3393,  0.4743,  0.6313,  0.8014,  0.9879,  1.1855,  1.3922,
+     1.5678,  1.7289,  1.9271,  2.1165,  2.3089,  2.5414,  2.7448,  2.9269,
+     0.0965,  0.2025,  0.3398,  0.4990,  0.6934,  0.9386,  1.1730,  1.3766,
+     1.5783,  1.7783,  1.9790,  2.1831,  2.3670,  2.5578,  2.7641,  2.9516,
+     0.2126,  0.3652,  0.5545,  0.7170,  0.8674,  1.0640,  1.2558,  1.4061,
+     1.5904,  1.8095,  1.9760,  2.1505,  2.3549,  2.5575,  2.7023,  2.8877,
+     0.1827,  0.3426,  0.4894,  0.6488,  0.7960,  0.9535,  1.1217,  1.2798,
+     1.4566,  1.6453,  1.8044,  2.0042,  2.2379,  2.4611,  2.6697,  2.8966,
+     0.2034,  0.3822,  0.5231,  0.6960,  0.9200,  1.0394,  1.1616,  1.3772,
+     1.5493,  1.7330,  1.9646,  2.1233,  2.3334,  2.5361,  2.7087,  2.9470,
+     0.1050,  0.2060,  0.3705,  0.5998,  0.8337,  1.0577,  1.2559,  1.4327,
+     1.6334,  1.8165,  1.9853,  2.2058,  2.4063,  2.5818,  2.7625,  2.9458,
+     0.1419,  0.4053,  0.6660,  0.8911,  1.0405,  1.1547,  1.2506,  1.3926,
+     1.5669,  1.7527,  1.9694,  2.2054,  2.3889,  2.5743,  2.7586,  2.9174,
+     0.1514,  0.2825,  0.4309,  0.5772,  0.7470,  0.9703,  1.1462,  1.3316,
+     1.5321,  1.7259,  1.9282,  2.1266,  2.3106,  2.5064,  2.7067,  2.9094,
+     0.1693,  0.3156,  0.4878,  0.6635,  0.8206,  0.9569,  1.1154,  1.3064,
+     1.5109,  1.7184,  1.9179,  2.1036,  2.2763,  2.4820,  2.6949,  2.9105,
+     0.1432,  0.2718,  0.4241,  0.5564,  0.6939,  0.9011,  1.1582,  1.3948,
+     1.6181,  1.8024,  1.9814,  2.1740,  2.3459,  2.5456,  2.7491,  2.9307,
+     0.2294,  0.3857,  0.5590,  0.7434,  0.9189,  1.0941,  1.2740,  1.4456,
+     1.6178,  1.7994,  1.9689,  2.1644,  2.3525,  2.5385,  2.7468,  2.9405,
+     0.1667,  0.3109,  0.4612,  0.6032,  0.7375,  0.8866,  1.0840,  1.3053,
+     1.4982,  1.7044,  1.9146,  2.1117,  2.2942,  2.4983,  2.7084,  2.9132,
+     0.1810,  0.3205,  0.4696,  0.6231,  0.7641,  0.9959,  1.2427,  1.4361,
+     1.5889,  1.7544,  1.9083,  2.0733,  2.2457,  2.4461,  2.6793,  2.9098,
+     0.1164,  0.3753,  0.6068,  0.7503,  1.0100,  1.2131,  1.3793,  1.5302,
+     1.6300,  1.7950,  1.9057,  2.1031,  2.3830,  2.5745,  2.6949,  2.8779,
+     0.1571,  0.4378,  0.6735,  0.8312,  0.8944,  0.9818,  1.1622,  1.4094,
+     1.6423,  1.8066,  1.9258,  2.1838,  2.4363,  2.6279,  2.7358,  2.8790,
+     0.1398,  0.2686,  0.4248,  0.6156,  0.7870,  1.0035,  1.2012,  1.3689,
+     1.5363,  1.7398,  1.9604,  2.1619,  2.3345,  2.5097,  2.7271,  2.9368,
+     0.1913,  0.3338,  0.4987,  0.6446,  0.7852,  1.0163,  1.1886,  1.3610,
+     1.5379,  1.7230,  1.8880,  2.0862,  2.2960,  2.4928,  2.7122,  2.9151,
+     0.0908,  0.1752,  0.2899,  0.5365,  0.7761,  1.0100,  1.2124,  1.4060,
+     1.6019,  1.8010,  1.9774,  2.1905,  2.3733,  2.5623,  2.7660,  2.9565,
+     0.1773,  0.3179,  0.4925,  0.6864,  0.8452,  0.9897,  1.1860,  1.3722,
+     1.5515,  1.7658,  1.9802,  2.1819,  2.3620,  2.5442,  2.7250,  2.9220,
+     0.1286,  0.2341,  0.3689,  0.5364,  0.7176,  0.9350,  1.1083,  1.2943,
+     1.4974,  1.7059,  1.9047,  2.1145,  2.3242,  2.5361,  2.7453,  2.9329,
+     0.2273,  0.3834,  0.5565,  0.7192,  0.8431,  0.9962,  1.1763,  1.3571,
+     1.5774,  1.7419,  1.9202,  2.1131,  2.2919,  2.4898,  2.6895,  2.9180,
+     0.1775,  0.3058,  0.4274,  0.6023,  0.8151,  1.0734,  1.3211,  1.5178,
+     1.6706,  1.8154,  1.9686,  2.1537,  2.3461,  2.5276,  2.7181,  2.9121,
+     0.1653,  0.4304,  0.6361,  0.7824,  0.9183,  1.0452,  1.2071,  1.4077,
+     1.6206,  1.8299,  2.0089,  2.1948,  2.3900,  2.5982,  2.7844,  2.9487,
+     0.1492,  0.2609,  0.3820,  0.5485,  0.7243,  0.9319,  1.1538,  1.3579,
+     1.5266,  1.7002,  1.8873,  2.1016,  2.3175,  2.5221,  2.7241,  2.9243,
+     0.2074,  0.3781,  0.5209,  0.6869,  0.8577,  0.9875,  1.1849,  1.3568,
+     1.4907,  1.7335,  1.8902,  2.1224,  2.3099,  2.4918,  2.7023,  2.8765,
+     0.1359,  0.2254,  0.3286,  0.4432,  0.6586,  0.8964,  1.1125,  1.3523,
+     1.5626,  1.7579,  1.9846,  2.1905,  2.3548,  2.5542,  2.7663,  2.9346,
+     0.1430,  0.2966,  0.4685,  0.6493,  0.8315,  1.0304,  1.2220,  1.4082,
+     1.5995,  1.7888,  1.9774,  2.1737,  2.3607,  2.5577,  2.7558,  2.9405,
+     0.1477,  0.2694,  0.4056,  0.5626,  0.7051,  0.8647,  1.0491,  1.2488,
+     1.4814,  1.7072,  1.9150,  2.1147,  2.3038,  2.5144,  2.7184,  2.9202,
+     0.1690,  0.3033,  0.4580,  0.6686,  0.8536,  1.0293,  1.2124,  1.3998,
+     1.5718,  1.7607,  1.9580,  2.1245,  2.2971,  2.4762,  2.6896,  2.9177,
+     0.1092,  0.2779,  0.4853,  0.6880,  0.9011,  1.0953,  1.2752,  1.4618,
+     1.6623,  1.8484,  2.0264,  2.2152,  2.4017,  2.5835,  2.7671,  2.9436,
+     0.1497,  0.3637,  0.6014,  0.8032,  0.9963,  1.1835,  1.3741,  1.5698,
+     1.7382,  1.9094,  2.0710,  2.2392,  2.4082,  2.5926,  2.7762,  2.9536,
+     0.1434,  0.2492,  0.3966,  0.5934,  0.8033,  1.0657,  1.2796,  1.4276,
+     1.5745,  1.7833,  1.9288,  2.1247,  2.3543,  2.5412,  2.7049,  2.8872,
+     0.1612,  0.2926,  0.4574,  0.6387,  0.8265,  1.0180,  1.1808,  1.3526,
+     1.5564,  1.7536,  1.9187,  2.1192,  2.3149,  2.5006,  2.7101,  2.9217,
+     0.0828,  0.1863,  0.3235,  0.5050,  0.7250,  0.9867,  1.2093,  1.3941,
+     1.5980,  1.7932,  1.9809,  2.1894,  2.3918,  2.5773,  2.7540,  2.9329,
+     0.2001,  0.3655,  0.5290,  0.6761,  0.8027,  0.9972,  1.2090,  1.4255,
+     1.6085,  1.7825,  1.9804,  2.1681,  2.3457,  2.5325,  2.7319,  2.9196,
+     0.1505,  0.2767,  0.4254,  0.6054,  0.7821,  0.9567,  1.1294,  1.3080,
+     1.4984,  1.6954,  1.8666,  2.0736,  2.2875,  2.4969,  2.7072,  2.9163,
+     0.1589,  0.4151,  0.5749,  0.6651,  0.8061,  1.0470,  1.2616,  1.3690,
+     1.4985,  1.7808,  1.9825,  2.1068,  2.2751,  2.5448,  2.7133,  2.8689,
+     0.0916,  0.1846,  0.3788,  0.6329,  0.8774,  1.0687,  1.2653,  1.4561,
+     1.6573,  1.8449,  2.0402,  2.2254,  2.3968,  2.5861,  2.7792,  2.9508,
+     0.2282,  0.4159,  0.5834,  0.6899,  0.8108,  1.0321,  1.2795,  1.5262,
+     1.6936,  1.8469,  2.0922,  2.2607,  2.3795,  2.5301,  2.7386,  2.9530,
+     0.1651,  0.3004,  0.4555,  0.6179,  0.7891,  0.9584,  1.1372,  1.3707,
+     1.5951,  1.7880,  1.9434,  2.1465,  2.3311,  2.5081,  2.6977,  2.8970,
+     0.1279,  0.3828,  0.6330,  0.8323,  0.9652,  1.1175,  1.2319,  1.3511,
+     1.5115,  1.6392,  1.7835,  1.9558,  2.2008,  2.4635,  2.6910,  2.9058,
+     0.1193,  0.2185,  0.3521,  0.5311,  0.7378,  0.9239,  1.1105,  1.3217,
+     1.5362,  1.7504,  1.9536,  2.1627,  2.3560,  2.5506,  2.7548,  2.9453,
+     0.1806,  0.3432,  0.4981,  0.6948,  0.8928,  1.0527,  1.2467,  1.4140,
+     1.6326,  1.7950,  1.9935,  2.1969,  2.3512,  2.5682,  2.7445,  2.9277,
+     0.1846,  0.3112,  0.4568,  0.5891,  0.7317,  0.8493,  1.0204,  1.2022,
+     1.3688,  1.6020,  1.8428,  2.0710,  2.2725,  2.4879,  2.7057,  2.9160,
+     0.0880,  0.2514,  0.5332,  0.7272,  0.8906,  1.1354,  1.3199,  1.4941,
+     1.6010,  1.7151,  1.8712,  2.0643,  2.2755,  2.5375,  2.7054,  2.8891,
+     0.1382,  0.2833,  0.4658,  0.6897,  0.9071,  1.0716,  1.2469,  1.4143,
+     1.5910,  1.7947,  1.9805,  2.1581,  2.3338,  2.5215,  2.7292,  2.9211,
+     0.1061,  0.3494,  0.6327,  0.8570,  0.9748,  1.0560,  1.1529,  1.3250,
+     1.6032,  1.8340,  1.9711,  2.1157,  2.3011,  2.5464,  2.8078,  2.9803,
+     0.1603,  0.2839,  0.4307,  0.5980,  0.7980,  1.0399,  1.1971,  1.3524,
+     1.5715,  1.7838,  1.9468,  2.1498,  2.3627,  2.5514,  2.7327,  2.9148,
+     0.1691,  0.3117,  0.4796,  0.6895,  0.8732,  1.0164,  1.1916,  1.3707,
+     1.5384,  1.7202,  1.8857,  2.0672,  2.2487,  2.4593,  2.6789,  2.8940,
+     0.0965,  0.1702,  0.3191,  0.5721,  0.8100,  1.0241,  1.2272,  1.4196,
+     1.6093,  1.8057,  1.9884,  2.2037,  2.3925,  2.5805,  2.7578,  2.9366,
+     0.1950,  0.3519,  0.5272,  0.6973,  0.8732,  1.0656,  1.2112,  1.3959,
+     1.6116,  1.7821,  1.9445,  2.1592,  2.3348,  2.5142,  2.7440,  2.9297,
+     0.1388,  0.2557,  0.4120,  0.5727,  0.7354,  0.9196,  1.0985,  1.2805,
+     1.4643,  1.6535,  1.8340,  2.0546,  2.2758,  2.4778,  2.6921,  2.9122,
+     0.1823,  0.3336,  0.4957,  0.6771,  0.8563,  1.0137,  1.2299,  1.3849,
+     1.5718,  1.7667,  1.9193,  2.1326,  2.3135,  2.5268,  2.7133,  2.8998,
+     0.0790,  0.1901,  0.4083,  0.6456,  0.8463,  1.0285,  1.2297,  1.4181,
+     1.6159,  1.8056,  1.9971,  2.1912,  2.3816,  2.5746,  2.7692,  2.9497,
+     0.0049,  0.0116,  0.0045,  0.0039, -0.0010, -0.0122, -0.0205, -0.0034,
+    -0.0140, -0.0041,  0.0191, -0.0322,  0.0002, -0.0124, -0.0269,  0.0059,
+     0.0586,  0.0339, -0.0389, -0.0319, -0.0079, -0.0205, -0.0363, -0.0211,
+     0.0241,  0.0595,  0.0469,  0.0283,  0.0176, -0.0183, -0.0173, -0.0004,
+     0.0024,  0.0145,  0.0534,  0.0197, -0.0065, -0.0067,  0.0133,  0.0358,
+    -0.0104, -0.0386, -0.0109, -0.0078,  0.0275,  0.0565,  0.0251, -0.0027,
+    -0.0053,  0.0171,  0.0088,  0.0495,  0.0141,  0.0039, -0.0445, -0.0426,
+    -0.0184, -0.0280, -0.0223,  0.0039, -0.0171, -0.0606, -0.0786, -0.0430,
+     0.0544,  0.0595,  0.0320, -0.0012,  0.0108,  0.0185,  0.0066,  0.0408,
+     0.0552, -0.0073, -0.0247, -0.0480, -0.0288,  0.0186,  0.0212, -0.0013,
+     0.0403,  0.0598,  0.0690,  0.0516, -0.0298, -0.0177,  0.0278,  0.0168,
+    -0.0106,  0.0251,  0.0386,  0.0331, -0.0052,  0.0133,  0.0291, -0.0158,
+    -0.0329, -0.0367,  0.0287,  0.0462, -0.0176,  0.0049,  0.0242, -0.0034,
+     0.0135,  0.0086, -0.0149,  0.0241,  0.0504,  0.0246, -0.0273, -0.0369,
+    -0.0108, -0.0449, -0.0625, -0.0414, -0.0292, -0.0571, -0.0440, -0.0088,
+     0.0098,  0.0009, -0.0004,  0.0007, -0.0314, -0.0208, -0.0138, -0.0277,
+    -0.0044,  0.0522,  0.0315, -0.0270, -0.0277, -0.0256, -0.0103, -0.0201,
+    -0.0287, -0.0279, -0.0182,  0.0472,  0.0613,  0.0450,  0.0413,  0.0333,
+     0.0444,  0.0223,  0.0061,  0.0316,  0.0321,  0.0501,  0.0460,  0.0250,
+     0.0227,  0.0235,  0.0099,  0.0185, -0.0347, -0.0684, -0.0189,  0.0242,
+    -0.0190, -0.0273, -0.0012, -0.0253,  0.0293, -0.0231, -0.0219, -0.0010,
+     0.0153,  0.0128, -0.0166, -0.0435, -0.0417, -0.0121, -0.0351, -0.0390,
+     0.0077, -0.0278, -0.0355,  0.0092, -0.0063,  0.0005,  0.0216,  0.0461,
+     0.0538,  0.0451,  0.0298, -0.0130,  0.0058,  0.0206,  0.0471,  0.0499,
+     0.0280,  0.0086, -0.0007, -0.0317,  0.0259,  0.0176,  0.0043,  0.0212,
+     0.0138,  0.0106,  0.0220, -0.0025,  0.0050,  0.0122, -0.0051, -0.0086,
+    -0.0472, -0.0005,  0.0193,  0.0032,  0.0246,  0.0222,  0.0090, -0.0320,
+    -0.0713, -0.0526, -0.0151, -0.0440, -0.0648, -0.0466, -0.0092,  0.0115,
+    -0.0129,  0.0053, -0.0344, -0.0385,  0.0392,  0.0599,  0.0414,  0.0165,
+    -0.0098, -0.0320, -0.0261, -0.0055, -0.0139, -0.0110,  0.0084,  0.0172,
+    -0.0492, -0.0537, -0.0320, -0.0036,  0.0265,  0.0385,  0.0064, -0.0280,
+    -0.0230,  0.0134,  0.0241,  0.0106,  0.0387,  0.0105,  0.0068,  0.0260,
+     0.4940,  0.4911,  0.4849,  0.4820,  0.4837,  0.4839,  0.4824,  0.4799,
+     0.4812,  0.4782,  0.4788,  0.4711,  0.4706,  0.4671,  0.4601,  0.4578,
+     0.2954,  0.2121,  0.1859,  0.1958,  0.1474,  0.1086,  0.1351,  0.1362,
+     0.1486,  0.1342,  0.1215,  0.1423,  0.1634,  0.1588,  0.1539,  0.1857,
+};
+
+static const float lsp16[] = {
+     0.1813,  0.3911,  0.6301,  0.8012,  1.0057,  1.2041,  1.4271,  1.6943,
+     1.9402,  2.1733,  2.3521,  2.4989,  2.5839,  2.6846,  2.7634,  2.8950,
+     0.1311,  0.3183,  0.4659,  0.5601,  0.6658,  0.7828,  1.0065,  1.2717,
+     1.5185,  1.7339,  1.9530,  2.2189,  2.3739,  2.4991,  2.6984,  2.9256,
+     0.1627,  0.4519,  0.6323,  0.7012,  0.7848,  0.9801,  1.1810,  1.3222,
+     1.5413,  1.8129,  1.9338,  2.0809,  2.3180,  2.5189,  2.7066,  2.9514,
+     0.1475,  0.2447,  0.4240,  0.5669,  0.7872,  0.9838,  1.1823,  1.3814,
+     1.5358,  1.6820,  1.8794,  2.1419,  2.4132,  2.6112,  2.7911,  2.9511,
+     0.1224,  0.2876,  0.5013,  0.6985,  0.8902,  1.0901,  1.2835,  1.4768,
+     1.6596,  1.8538,  2.0467,  2.2304,  2.4124,  2.5942,  2.7729,  2.9531,
+     0.1741,  0.3034,  0.4677,  0.5879,  0.7258,  0.9648,  1.1417,  1.3220,
+     1.5081,  1.7151,  1.9212,  2.1286,  2.3208,  2.4938,  2.6765,  2.8891,
+     0.1657,  0.3174,  0.4907,  0.6559,  0.8295,  1.0254,  1.2071,  1.3880,
+     1.5737,  1.7845,  1.9027,  2.1139,  2.3323,  2.5157,  2.7323,  2.9015,
+     0.1592,  0.2758,  0.4417,  0.6315,  0.8257,  0.9873,  1.1277,  1.2830,
+     1.4337,  1.6315,  1.8899,  2.1356,  2.3572,  2.5632,  2.7468,  2.9420,
+     0.1524,  0.4325,  0.5931,  0.7036,  0.7696,  0.8923,  1.1739,  1.4773,
+     1.6609,  1.7911,  1.9666,  2.1972,  2.3754,  2.5045,  2.6613,  2.8882,
+     0.2130,  0.3013,  0.3721,  0.4257,  0.5079,  0.7015,  0.9815,  1.2554,
+     1.4648,  1.6966,  1.9138,  2.1075,  2.3318,  2.5292,  2.7453,  2.9347,
+     0.1142,  0.3748,  0.6205,  0.7642,  0.8121,  0.9022,  0.9843,  1.1558,
+     1.4467,  1.7422,  1.9574,  2.1302,  2.3812,  2.5898,  2.7720,  2.9583,
+     0.1255,  0.2339,  0.3570,  0.5323,  0.7458,  1.0003,  1.1729,  1.3567,
+     1.5217,  1.6977,  1.8924,  2.0942,  2.3145,  2.5408,  2.7553,  2.9337,
+     0.1316,  0.2289,  0.4327,  0.6663,  0.8509,  0.9994,  1.1697,  1.3804,
+     1.5609,  1.6903,  1.8572,  2.1019,  2.3687,  2.5789,  2.7715,  2.9472,
+     0.1502,  0.2546,  0.3883,  0.5333,  0.6976,  0.9163,  1.1071,  1.3364,
+     1.5420,  1.7525,  1.8948,  2.0839,  2.2819,  2.4651,  2.6875,  2.8987,
+     0.1593,  0.3014,  0.4573,  0.6354,  0.8157,  0.9805,  1.1783,  1.3747,
+     1.5678,  1.7326,  1.9286,  2.1340,  2.3253,  2.5280,  2.7180,  2.9298,
+     0.1811,  0.3167,  0.4655,  0.6507,  0.8198,  1.0075,  1.1892,  1.3743,
+     1.5227,  1.7090,  1.8849,  2.0743,  2.2750,  2.4830,  2.6896,  2.8953,
+     0.1846,  0.3577,  0.5315,  0.7290,  0.9176,  1.1016,  1.2654,  1.4525,
+     1.6315,  1.8268,  2.0238,  2.1934,  2.3868,  2.5753,  2.7682,  2.9469,
+     0.0876,  0.1439,  0.2048,  0.3654,  0.6281,  0.8853,  1.0907,  1.2992,
+     1.5227,  1.7373,  1.9395,  2.1419,  2.3488,  2.5486,  2.7466,  2.9348,
+     0.1391,  0.4170,  0.6561,  0.7953,  0.8734,  0.9986,  1.1870,  1.4520,
+     1.6042,  1.7910,  2.0135,  2.1870,  2.3358,  2.5066,  2.7409,  2.9955,
+     0.0804,  0.1355,  0.2599,  0.4998,  0.7408,  0.9474,  1.1276,  1.3428,
+     1.5556,  1.7712,  1.9699,  2.1535,  2.3605,  2.5548,  2.7489,  2.9325,
+     0.1304,  0.3087,  0.4979,  0.6584,  0.8414,  1.0329,  1.2244,  1.4189,
+     1.6118,  1.8200,  1.9985,  2.1893,  2.3915,  2.5794,  2.7647,  2.9344,
+     0.1895,  0.2849,  0.3705,  0.4126,  0.6265,  0.9207,  1.1774,  1.3762,
+     1.5757,  1.7728,  1.9568,  2.1662,  2.3615,  2.5575,  2.7561,  2.9416,
+     0.1800,  0.3078,  0.4805,  0.6796,  0.8503,  1.0046,  1.1703,  1.3269,
+     1.4862,  1.6502,  1.8454,  2.0873,  2.3175,  2.5356,  2.7516,  2.9469,
+     0.1950,  0.3233,  0.4568,  0.5940,  0.7589,  0.9978,  1.1701,  1.3383,
+     1.5017,  1.6565,  1.8243,  2.0605,  2.2938,  2.5147,  2.7419,  2.9396,
+     0.2531,  0.4391,  0.5790,  0.7170,  0.8998,  1.1430,  1.3577,  1.5326,
+     1.6328,  1.7627,  1.9726,  2.1762,  2.3563,  2.5478,  2.7385,  2.9067,
+     0.1805,  0.2788,  0.3591,  0.3881,  0.5441,  0.8055,  1.0766,  1.3165,
+     1.5316,  1.7508,  1.9477,  2.1374,  2.3438,  2.5484,  2.7501,  2.9410,
+     0.2044,  0.3671,  0.5396,  0.7042,  0.8582,  0.9831,  1.1261,  1.3194,
+     1.4769,  1.6979,  1.8717,  2.0463,  2.2620,  2.4739,  2.7054,  2.9208,
+     0.1048,  0.2175,  0.4206,  0.5923,  0.7483,  0.9400,  1.1356,  1.3799,
+     1.5958,  1.7320,  1.8984,  2.1296,  2.3594,  2.5492,  2.7387,  2.9305,
+     0.0842,  0.1729,  0.3951,  0.6447,  0.8688,  1.0605,  1.2472,  1.4330,
+     1.6232,  1.8144,  2.0216,  2.1915,  2.3878,  2.5763,  2.7685,  2.9464,
+     0.1461,  0.2593,  0.4105,  0.5677,  0.7328,  0.8919,  1.0484,  1.2302,
+     1.4386,  1.6635,  1.8873,  2.1024,  2.3116,  2.5268,  2.7273,  2.9269,
+     0.1503,  0.3108,  0.4756,  0.6731,  0.8600,  1.0233,  1.2115,  1.3971,
+     1.5915,  1.7892,  1.9517,  2.1603,  2.3487,  2.5460,  2.7308,  2.8998,
+     0.2163,  0.3669,  0.5125,  0.6709,  0.8143,  0.9930,  1.2095,  1.4205,
+     1.6176,  1.7112,  1.8398,  2.0896,  2.3513,  2.5290,  2.6667,  2.8960,
+     0.2133,  0.4382,  0.6287,  0.8702,  1.1088,  1.3749,  1.6062,  1.7446,
+     1.8333,  1.9122,  1.9614,  2.0669,  2.1789,  2.3449,  2.6038,  2.8849,
+     0.1598,  0.2719,  0.3877,  0.4815,  0.5926,  0.7795,  1.0449,  1.3045,
+     1.5210,  1.7391,  1.9462,  2.1397,  2.3553,  2.5458,  2.7540,  2.9392,
+     0.2918,  0.5607,  0.6801,  0.7404,  0.8285,  0.9431,  1.1579,  1.4080,
+     1.6332,  1.8472,  1.9738,  2.0771,  2.2890,  2.5178,  2.7445,  2.9830,
+     0.1664,  0.2842,  0.3965,  0.5463,  0.8162,  1.0346,  1.1849,  1.3446,
+     1.5122,  1.7563,  1.9960,  2.2002,  2.3796,  2.5689,  2.7712,  2.9550,
+     0.0911,  0.2397,  0.5052,  0.7868,  1.0299,  1.1311,  1.2244,  1.3333,
+     1.4395,  1.6790,  1.9369,  2.1717,  2.3689,  2.5538,  2.7340,  2.9326,
+     0.1647,  0.2931,  0.3836,  0.4978,  0.6255,  0.9243,  1.1339,  1.3001,
+     1.5269,  1.8010,  1.9715,  2.1419,  2.3784,  2.5503,  2.6719,  2.8745,
+     0.2440,  0.3802,  0.4756,  0.6613,  0.8627,  1.0292,  1.2291,  1.4060,
+     1.5198,  1.7354,  1.9044,  2.1010,  2.3147,  2.4996,  2.7171,  2.9041,
+     0.1590,  0.2876,  0.4572,  0.5996,  0.7713,  0.9490,  1.1205,  1.2815,
+     1.4516,  1.6385,  1.8179,  2.0457,  2.2759,  2.4785,  2.6861,  2.9080,
+     0.2297,  0.4309,  0.5712,  0.6717,  0.8138,  1.0463,  1.2492,  1.4560,
+     1.6796,  1.8458,  1.9642,  2.1452,  2.3636,  2.5395,  2.7456,  2.9495,
+     0.2975,  0.4678,  0.4996,  0.5809,  0.6279,  0.6884,  0.8606,  1.1386,
+     1.4412,  1.6876,  1.8760,  2.0932,  2.3178,  2.5166,  2.7345,  2.9280,
+     0.1278,  0.3737,  0.6004,  0.7069,  0.8147,  1.0180,  1.2581,  1.3812,
+     1.4855,  1.7268,  1.9970,  2.1258,  2.2936,  2.5702,  2.7563,  2.8983,
+     0.1314,  0.2508,  0.3999,  0.5680,  0.7424,  0.9367,  1.1286,  1.3175,
+     1.5336,  1.7404,  1.9317,  2.1404,  2.3514,  2.5562,  2.7510,  2.9402,
+     0.1043,  0.2367,  0.4293,  0.6376,  0.8160,  0.9836,  1.1779,  1.3850,
+     1.5835,  1.7875,  1.9765,  2.1593,  2.3654,  2.5577,  2.7465,  2.9398,
+     0.1529,  0.2515,  0.3454,  0.4374,  0.7011,  0.9015,  1.0744,  1.3532,
+     1.5699,  1.7545,  2.0021,  2.1259,  2.2278,  2.4546,  2.7264,  2.9425,
+     0.1429,  0.2808,  0.4395,  0.6334,  0.8069,  0.9705,  1.1520,  1.3250,
+     1.5109,  1.7285,  1.9356,  2.1469,  2.3479,  2.5554,  2.7512,  2.9348,
+     0.1625,  0.3022,  0.4756,  0.6315,  0.8032,  0.9924,  1.1596,  1.3204,
+     1.4994,  1.6929,  1.8955,  2.1090,  2.3025,  2.5018,  2.6908,  2.8980,
+     0.1692,  0.3427,  0.5228,  0.7756,  0.9688,  1.0950,  1.3056,  1.4360,
+     1.5675,  1.8049,  1.9376,  2.1151,  2.3407,  2.5012,  2.7192,  2.9258,
+     0.0474,  0.1251,  0.1939,  0.3841,  0.6501,  0.9231,  1.1153,  1.3240,
+     1.5478,  1.7599,  1.9651,  2.1510,  2.3645,  2.5552,  2.7542,  2.9393,
+     0.2196,  0.4656,  0.7492,  0.9922,  1.1678,  1.2489,  1.3112,  1.3657,
+     1.4223,  1.5302,  1.7212,  1.9996,  2.2523,  2.4844,  2.7036,  2.9145,
+     0.1128,  0.2368,  0.3704,  0.5476,  0.7723,  0.9968,  1.1930,  1.3992,
+     1.6013,  1.7957,  1.9888,  2.1857,  2.3825,  2.5705,  2.7616,  2.9434,
+     0.1341,  0.2768,  0.4510,  0.6359,  0.8332,  1.0335,  1.2004,  1.3952,
+     1.5762,  1.7681,  1.9815,  2.1735,  2.3657,  2.5552,  2.7514,  2.9498,
+     0.1247,  0.2559,  0.3516,  0.4726,  0.6861,  0.9483,  1.1852,  1.3858,
+     1.5851,  1.7815,  1.9778,  2.1737,  2.3729,  2.5664,  2.7620,  2.9429,
+     0.1988,  0.3320,  0.4777,  0.6737,  0.8425,  1.0265,  1.1694,  1.3655,
+     1.5463,  1.7135,  1.9385,  2.1650,  2.3529,  2.5367,  2.7545,  2.9585,
+     0.1376,  0.2620,  0.4273,  0.6169,  0.7755,  0.9441,  1.1169,  1.3157,
+     1.5179,  1.7020,  1.8931,  2.1059,  2.3112,  2.5136,  2.7169,  2.9198,
+     0.2112,  0.4385,  0.6091,  0.7618,  0.9553,  1.1543,  1.3445,  1.5396,
+     1.7153,  1.9192,  2.1263,  2.3593,  2.5958,  2.8171,  2.9394,  3.0409,
+     0.1347,  0.2099,  0.2646,  0.3453,  0.5266,  0.7869,  1.0513,  1.2795,
+     1.4880,  1.7181,  1.9294,  2.1332,  2.3362,  2.5442,  2.7433,  2.9362,
+     0.3141,  0.5935,  0.7517,  0.8313,  0.8568,  0.9570,  1.0250,  1.1275,
+     1.3422,  1.6303,  1.8577,  2.0705,  2.2957,  2.5095,  2.7244,  2.9262,
+     0.0962,  0.2116,  0.3961,  0.5641,  0.7122,  0.8883,  1.1023,  1.3481,
+     1.5623,  1.7554,  1.9618,  2.1675,  2.3706,  2.5556,  2.7430,  2.9337,
+     0.0898,  0.1510,  0.3060,  0.5820,  0.8221,  1.0388,  1.2261,  1.4289,
+     1.6054,  1.8103,  1.9941,  2.1844,  2.3742,  2.5711,  2.7632,  2.9474,
+     0.1326,  0.2316,  0.3761,  0.5177,  0.6782,  0.8761,  1.0952,  1.3175,
+     1.5078,  1.7034,  1.9051,  2.1245,  2.3424,  2.5484,  2.7444,  2.9389,
+     0.1740,  0.3293,  0.5174,  0.6824,  0.8394,  1.0372,  1.2046,  1.3723,
+     1.5656,  1.7444,  1.9442,  2.1386,  2.3139,  2.4960,  2.7071,  2.9297,
+     0.2304,  0.3775,  0.4865,  0.6182,  0.7842,  0.9208,  1.1151,  1.2843,
+     1.4641,  1.6988,  1.9209,  2.1260,  2.3099,  2.5229,  2.7414,  2.9276,
+     0.0094,  0.0261, -0.0037,  0.0041, -0.0092, -0.0044, -0.0232, -0.0073,
+    -0.0047, -0.0021,  0.0250, -0.0580, -0.0140, -0.0342, -0.0586,  0.0020,
+     0.0449,  0.0155, -0.0523, -0.0279,  0.0299, -0.0183, -0.0736, -0.0639,
+    -0.0017,  0.0336,  0.0209,  0.0046,  0.0077, -0.0148, -0.0114, -0.0120,
+     0.0115, -0.0050,  0.0445,  0.0048,  0.0188, -0.0137, -0.0080,  0.0239,
+    -0.0184, -0.0524, -0.0195, -0.0126,  0.0284,  0.0632,  0.0141, -0.0093,
+    -0.0096,  0.0196,  0.0230,  0.0379,  0.0308,  0.0237, -0.0224, -0.0600,
+    -0.0755, -0.1074, -0.0988, -0.0606, -0.1038, -0.1552, -0.1480, -0.0672,
+     0.0504,  0.0676,  0.0336, -0.0042,  0.0729,  0.1013,  0.0868,  0.0846,
+     0.0954,  0.0515, -0.0066, -0.0851, -0.0485,  0.0294,  0.0395,  0.0087,
+     0.0078,  0.0446,  0.0881,  0.0672, -0.0384, -0.0025,  0.0415,  0.0353,
+     0.0080,  0.0052,  0.0190,  0.0182,  0.0069,  0.0168,  0.0374,  0.0037,
+    -0.0292, -0.0429,  0.0302,  0.0681, -0.0233, -0.0238, -0.0003, -0.0043,
+     0.0054, -0.0029, -0.0149,  0.0642,  0.0622,  0.0341, -0.0232, -0.0461,
+    -0.0082, -0.0469, -0.0618, -0.0326, -0.0452, -0.0649, -0.0597, -0.0398,
+    -0.0318, -0.0116,  0.0011,  0.0009, -0.0384, -0.0384, -0.0156, -0.0260,
+    -0.0007,  0.0473,  0.0111, -0.0358, -0.0484, -0.0204, -0.0029, -0.0090,
+    -0.0285, -0.0495, -0.0376,  0.0917,  0.1192,  0.1026,  0.0745,  0.0397,
+     0.0463,  0.0253,  0.0025,  0.0465,  0.0100,  0.0488,  0.0416,  0.0223,
+     0.0263,  0.0072, -0.0053,  0.0595,  0.0060, -0.0518, -0.0316, -0.0043,
+    -0.0133, -0.0233, -0.0075, -0.0251,  0.0277, -0.0067, -0.0136, -0.0004,
+     0.0235,  0.0112, -0.0182, -0.0324, -0.0210, -0.0035, -0.0395, -0.0384,
+     0.0005, -0.0150, -0.0356,  0.0127, -0.0033, -0.0034,  0.0205,  0.0747,
+     0.1138,  0.1015,  0.0995, -0.0161, -0.0045,  0.0129,  0.0472,  0.0575,
+     0.0222,  0.0091,  0.0037, -0.0471,  0.0371,  0.0132,  0.0208,  0.0247,
+     0.0117,  0.0164,  0.0225,  0.0124, -0.0023,  0.0088, -0.0046,  0.0047,
+    -0.0393,  0.0018,  0.0148,  0.0020,  0.0044,  0.0165,  0.0229, -0.0208,
+    -0.0477, -0.0310, -0.0164, -0.0390, -0.0764, -0.0525, -0.0094,  0.0075,
+    -0.0102, -0.0045, -0.0504, -0.0709,  0.0822,  0.0710,  0.0426,  0.0014,
+    -0.0371, -0.0400, -0.0157, -0.0155, -0.0173, -0.0138, -0.0015,  0.0134,
+    -0.0418, -0.0682, -0.0256,  0.0050,  0.0360,  0.0354,  0.0074, -0.0396,
+    -0.0235,  0.0284,  0.0494,  0.0153,  0.0448,  0.0025, -0.0061,  0.0252,
+     0.1000,  0.2260,  0.2158,  0.2116,  0.2198,  0.2055,  0.2110,  0.1873,
+     0.1907,  0.2071,  0.2164,  0.2009,  0.2059,  0.2124,  0.2141,  0.2093,
+     0.0875,  0.0981,  0.1177,  0.1071,  0.1033,  0.1248,  0.1048,  0.1238,
+     0.1166,  0.1008,  0.1062,  0.0992,  0.0994,  0.1067,  0.0999,  0.1187,
+     0.0750,  0.0794,  0.0828,  0.0854,  0.0859,  0.0801,  0.0891,  0.0933,
+     0.0969,  0.0920,  0.0915,  0.0862,  0.0868,  0.0891,  0.0842,  0.0824,
+     0.0625,  0.0930,  0.0815,  0.0853,  0.0898,  0.0828,  0.0822,  0.0910,
+     0.0873,  0.0906,  0.0856,  0.0840,  0.0774,  0.0785,  0.0684,  0.0711,
+     0.3319,  0.4219,  0.4588,  0.4090,  0.4092,  0.4014,  0.3548,  0.3353,
+     0.3708,  0.3352,  0.3720,  0.3538,  0.4084,  0.4289,  0.4060,  0.4210,
+     0.0588,  0.0209, -0.0082, -0.0115, -0.0343, -0.0621, -0.0541, -0.0346,
+    -0.0346, -0.0366, -0.0220, -0.0265, -0.0102,  0.0374,  0.0306,  0.0404,
+     0.0306,  0.0090, -0.0054,  0.0333,  0.0047,  0.0238,  0.0141,  0.0165,
+     0.0306,  0.0420,  0.0159,  0.0124,  0.0414,  0.0158, -0.0237,  0.0141,
+     0.0765,  0.0057, -0.0260, -0.0426, -0.0395, -0.0126, -0.0579, -0.0417,
+    -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238,
+};
+
+static const float lsp16s[] = {
+     0.1813,  0.3911,  0.6301,  0.8012,  1.0057,  1.2041,  1.4271,  1.6943,
+     1.9402,  2.1733,  2.3521,  2.4989,  2.5839,  2.6846,  2.7634,  2.8950,
+     0.1311,  0.3183,  0.4659,  0.5601,  0.6658,  0.7828,  1.0065,  1.2717,
+     1.5185,  1.7339,  1.9530,  2.2189,  2.3739,  2.4991,  2.6984,  2.9256,
+     0.1627,  0.4519,  0.6323,  0.7012,  0.7848,  0.9801,  1.1810,  1.3222,
+     1.5413,  1.8129,  1.9338,  2.0809,  2.3180,  2.5189,  2.7066,  2.9514,
+     0.1475,  0.2447,  0.4240,  0.5669,  0.7872,  0.9838,  1.1823,  1.3814,
+     1.5358,  1.6820,  1.8794,  2.1419,  2.4132,  2.6112,  2.7911,  2.9511,
+     0.1224,  0.2876,  0.5013,  0.6985,  0.8902,  1.0901,  1.2835,  1.4768,
+     1.6596,  1.8538,  2.0467,  2.2304,  2.4124,  2.5942,  2.7729,  2.9531,
+     0.1741,  0.3034,  0.4677,  0.5879,  0.7258,  0.9648,  1.1417,  1.3220,
+     1.5081,  1.7151,  1.9212,  2.1286,  2.3208,  2.4938,  2.6765,  2.8891,
+     0.1657,  0.3174,  0.4907,  0.6559,  0.8295,  1.0254,  1.2071,  1.3880,
+     1.5737,  1.7845,  1.9027,  2.1139,  2.3323,  2.5157,  2.7323,  2.9015,
+     0.1592,  0.2758,  0.4417,  0.6315,  0.8257,  0.9873,  1.1277,  1.2830,
+     1.4337,  1.6315,  1.8899,  2.1356,  2.3572,  2.5632,  2.7468,  2.9420,
+     0.1524,  0.4325,  0.5931,  0.7036,  0.7696,  0.8923,  1.1739,  1.4773,
+     1.6609,  1.7911,  1.9666,  2.1972,  2.3754,  2.5045,  2.6613,  2.8882,
+     0.2130,  0.3013,  0.3721,  0.4257,  0.5079,  0.7015,  0.9815,  1.2554,
+     1.4648,  1.6966,  1.9138,  2.1075,  2.3318,  2.5292,  2.7453,  2.9347,
+     0.1142,  0.3748,  0.6205,  0.7642,  0.8121,  0.9022,  0.9843,  1.1558,
+     1.4467,  1.7422,  1.9574,  2.1302,  2.3812,  2.5898,  2.7720,  2.9583,
+     0.1255,  0.2339,  0.3570,  0.5323,  0.7458,  1.0003,  1.1729,  1.3567,
+     1.5217,  1.6977,  1.8924,  2.0942,  2.3145,  2.5408,  2.7553,  2.9337,
+     0.1316,  0.2289,  0.4327,  0.6663,  0.8509,  0.9994,  1.1697,  1.3804,
+     1.5609,  1.6903,  1.8572,  2.1019,  2.3687,  2.5789,  2.7715,  2.9472,
+     0.1502,  0.2546,  0.3883,  0.5333,  0.6976,  0.9163,  1.1071,  1.3364,
+     1.5420,  1.7525,  1.8948,  2.0839,  2.2819,  2.4651,  2.6875,  2.8987,
+     0.1593,  0.3014,  0.4573,  0.6354,  0.8157,  0.9805,  1.1783,  1.3747,
+     1.5678,  1.7326,  1.9286,  2.1340,  2.3253,  2.5280,  2.7180,  2.9298,
+     0.1811,  0.3167,  0.4655,  0.6507,  0.8198,  1.0075,  1.1892,  1.3743,
+     1.5227,  1.7090,  1.8849,  2.0743,  2.2750,  2.4830,  2.6896,  2.8953,
+     0.1846,  0.3577,  0.5315,  0.7290,  0.9176,  1.1016,  1.2654,  1.4525,
+     1.6315,  1.8268,  2.0238,  2.1934,  2.3868,  2.5753,  2.7682,  2.9469,
+     0.0876,  0.1439,  0.2048,  0.3654,  0.6281,  0.8853,  1.0907,  1.2992,
+     1.5227,  1.7373,  1.9395,  2.1419,  2.3488,  2.5486,  2.7466,  2.9348,
+     0.1391,  0.4170,  0.6561,  0.7953,  0.8734,  0.9986,  1.1870,  1.4520,
+     1.6042,  1.7910,  2.0135,  2.1870,  2.3358,  2.5066,  2.7409,  2.9955,
+     0.0804,  0.1355,  0.2599,  0.4998,  0.7408,  0.9474,  1.1276,  1.3428,
+     1.5556,  1.7712,  1.9699,  2.1535,  2.3605,  2.5548,  2.7489,  2.9325,
+     0.1304,  0.3087,  0.4979,  0.6584,  0.8414,  1.0329,  1.2244,  1.4189,
+     1.6118,  1.8200,  1.9985,  2.1893,  2.3915,  2.5794,  2.7647,  2.9344,
+     0.1895,  0.2849,  0.3705,  0.4126,  0.6265,  0.9207,  1.1774,  1.3762,
+     1.5757,  1.7728,  1.9568,  2.1662,  2.3615,  2.5575,  2.7561,  2.9416,
+     0.1800,  0.3078,  0.4805,  0.6796,  0.8503,  1.0046,  1.1703,  1.3269,
+     1.4862,  1.6502,  1.8454,  2.0873,  2.3175,  2.5356,  2.7516,  2.9469,
+     0.1950,  0.3233,  0.4568,  0.5940,  0.7589,  0.9978,  1.1701,  1.3383,
+     1.5017,  1.6565,  1.8243,  2.0605,  2.2938,  2.5147,  2.7419,  2.9396,
+     0.2531,  0.4391,  0.5790,  0.7170,  0.8998,  1.1430,  1.3577,  1.5326,
+     1.6328,  1.7627,  1.9726,  2.1762,  2.3563,  2.5478,  2.7385,  2.9067,
+     0.1805,  0.2788,  0.3591,  0.3881,  0.5441,  0.8055,  1.0766,  1.3165,
+     1.5316,  1.7508,  1.9477,  2.1374,  2.3438,  2.5484,  2.7501,  2.9410,
+     0.2044,  0.3671,  0.5396,  0.7042,  0.8582,  0.9831,  1.1261,  1.3194,
+     1.4769,  1.6979,  1.8717,  2.0463,  2.2620,  2.4739,  2.7054,  2.9208,
+     0.1048,  0.2175,  0.4206,  0.5923,  0.7483,  0.9400,  1.1356,  1.3799,
+     1.5958,  1.7320,  1.8984,  2.1296,  2.3594,  2.5492,  2.7387,  2.9305,
+     0.0842,  0.1729,  0.3951,  0.6447,  0.8688,  1.0605,  1.2472,  1.4330,
+     1.6232,  1.8144,  2.0216,  2.1915,  2.3878,  2.5763,  2.7685,  2.9464,
+     0.1461,  0.2593,  0.4105,  0.5677,  0.7328,  0.8919,  1.0484,  1.2302,
+     1.4386,  1.6635,  1.8873,  2.1024,  2.3116,  2.5268,  2.7273,  2.9269,
+     0.1503,  0.3108,  0.4756,  0.6731,  0.8600,  1.0233,  1.2115,  1.3971,
+     1.5915,  1.7892,  1.9517,  2.1603,  2.3487,  2.5460,  2.7308,  2.8998,
+     0.2163,  0.3669,  0.5125,  0.6709,  0.8143,  0.9930,  1.2095,  1.4205,
+     1.6176,  1.7112,  1.8398,  2.0896,  2.3513,  2.5290,  2.6667,  2.8960,
+     0.2133,  0.4382,  0.6287,  0.8702,  1.1088,  1.3749,  1.6062,  1.7446,
+     1.8333,  1.9122,  1.9614,  2.0669,  2.1789,  2.3449,  2.6038,  2.8849,
+     0.1598,  0.2719,  0.3877,  0.4815,  0.5926,  0.7795,  1.0449,  1.3045,
+     1.5210,  1.7391,  1.9462,  2.1397,  2.3553,  2.5458,  2.7540,  2.9392,
+     0.2918,  0.5607,  0.6801,  0.7404,  0.8285,  0.9431,  1.1579,  1.4080,
+     1.6332,  1.8472,  1.9738,  2.0771,  2.2890,  2.5178,  2.7445,  2.9830,
+     0.1664,  0.2842,  0.3965,  0.5463,  0.8162,  1.0346,  1.1849,  1.3446,
+     1.5122,  1.7563,  1.9960,  2.2002,  2.3796,  2.5689,  2.7712,  2.9550,
+     0.0911,  0.2397,  0.5052,  0.7868,  1.0299,  1.1311,  1.2244,  1.3333,
+     1.4395,  1.6790,  1.9369,  2.1717,  2.3689,  2.5538,  2.7340,  2.9326,
+     0.1647,  0.2931,  0.3836,  0.4978,  0.6255,  0.9243,  1.1339,  1.3001,
+     1.5269,  1.8010,  1.9715,  2.1419,  2.3784,  2.5503,  2.6719,  2.8745,
+     0.2440,  0.3802,  0.4756,  0.6613,  0.8627,  1.0292,  1.2291,  1.4060,
+     1.5198,  1.7354,  1.9044,  2.1010,  2.3147,  2.4996,  2.7171,  2.9041,
+     0.1590,  0.2876,  0.4572,  0.5996,  0.7713,  0.9490,  1.1205,  1.2815,
+     1.4516,  1.6385,  1.8179,  2.0457,  2.2759,  2.4785,  2.6861,  2.9080,
+     0.2297,  0.4309,  0.5712,  0.6717,  0.8138,  1.0463,  1.2492,  1.4560,
+     1.6796,  1.8458,  1.9642,  2.1452,  2.3636,  2.5395,  2.7456,  2.9495,
+     0.2975,  0.4678,  0.4996,  0.5809,  0.6279,  0.6884,  0.8606,  1.1386,
+     1.4412,  1.6876,  1.8760,  2.0932,  2.3178,  2.5166,  2.7345,  2.9280,
+     0.1278,  0.3737,  0.6004,  0.7069,  0.8147,  1.0180,  1.2581,  1.3812,
+     1.4855,  1.7268,  1.9970,  2.1258,  2.2936,  2.5702,  2.7563,  2.8983,
+     0.1314,  0.2508,  0.3999,  0.5680,  0.7424,  0.9367,  1.1286,  1.3175,
+     1.5336,  1.7404,  1.9317,  2.1404,  2.3514,  2.5562,  2.7510,  2.9402,
+     0.1043,  0.2367,  0.4293,  0.6376,  0.8160,  0.9836,  1.1779,  1.3850,
+     1.5835,  1.7875,  1.9765,  2.1593,  2.3654,  2.5577,  2.7465,  2.9398,
+     0.1529,  0.2515,  0.3454,  0.4374,  0.7011,  0.9015,  1.0744,  1.3532,
+     1.5699,  1.7545,  2.0021,  2.1259,  2.2278,  2.4546,  2.7264,  2.9425,
+     0.1429,  0.2808,  0.4395,  0.6334,  0.8069,  0.9705,  1.1520,  1.3250,
+     1.5109,  1.7285,  1.9356,  2.1469,  2.3479,  2.5554,  2.7512,  2.9348,
+     0.1625,  0.3022,  0.4756,  0.6315,  0.8032,  0.9924,  1.1596,  1.3204,
+     1.4994,  1.6929,  1.8955,  2.1090,  2.3025,  2.5018,  2.6908,  2.8980,
+     0.1692,  0.3427,  0.5228,  0.7756,  0.9688,  1.0950,  1.3056,  1.4360,
+     1.5675,  1.8049,  1.9376,  2.1151,  2.3407,  2.5012,  2.7192,  2.9258,
+     0.0474,  0.1251,  0.1939,  0.3841,  0.6501,  0.9231,  1.1153,  1.3240,
+     1.5478,  1.7599,  1.9651,  2.1510,  2.3645,  2.5552,  2.7542,  2.9393,
+     0.2196,  0.4656,  0.7492,  0.9922,  1.1678,  1.2489,  1.3112,  1.3657,
+     1.4223,  1.5302,  1.7212,  1.9996,  2.2523,  2.4844,  2.7036,  2.9145,
+     0.1128,  0.2368,  0.3704,  0.5476,  0.7723,  0.9968,  1.1930,  1.3992,
+     1.6013,  1.7957,  1.9888,  2.1857,  2.3825,  2.5705,  2.7616,  2.9434,
+     0.1341,  0.2768,  0.4510,  0.6359,  0.8332,  1.0335,  1.2004,  1.3952,
+     1.5762,  1.7681,  1.9815,  2.1735,  2.3657,  2.5552,  2.7514,  2.9498,
+     0.1247,  0.2559,  0.3516,  0.4726,  0.6861,  0.9483,  1.1852,  1.3858,
+     1.5851,  1.7815,  1.9778,  2.1737,  2.3729,  2.5664,  2.7620,  2.9429,
+     0.1988,  0.3320,  0.4777,  0.6737,  0.8425,  1.0265,  1.1694,  1.3655,
+     1.5463,  1.7135,  1.9385,  2.1650,  2.3529,  2.5367,  2.7545,  2.9585,
+     0.1376,  0.2620,  0.4273,  0.6169,  0.7755,  0.9441,  1.1169,  1.3157,
+     1.5179,  1.7020,  1.8931,  2.1059,  2.3112,  2.5136,  2.7169,  2.9198,
+     0.2112,  0.4385,  0.6091,  0.7618,  0.9553,  1.1543,  1.3445,  1.5396,
+     1.7153,  1.9192,  2.1263,  2.3593,  2.5958,  2.8171,  2.9394,  3.0409,
+     0.1347,  0.2099,  0.2646,  0.3453,  0.5266,  0.7869,  1.0513,  1.2795,
+     1.4880,  1.7181,  1.9294,  2.1332,  2.3362,  2.5442,  2.7433,  2.9362,
+     0.3141,  0.5935,  0.7517,  0.8313,  0.8568,  0.9570,  1.0250,  1.1275,
+     1.3422,  1.6303,  1.8577,  2.0705,  2.2957,  2.5095,  2.7244,  2.9262,
+     0.0962,  0.2116,  0.3961,  0.5641,  0.7122,  0.8883,  1.1023,  1.3481,
+     1.5623,  1.7554,  1.9618,  2.1675,  2.3706,  2.5556,  2.7430,  2.9337,
+     0.0898,  0.1510,  0.3060,  0.5820,  0.8221,  1.0388,  1.2261,  1.4289,
+     1.6054,  1.8103,  1.9941,  2.1844,  2.3742,  2.5711,  2.7632,  2.9474,
+     0.1326,  0.2316,  0.3761,  0.5177,  0.6782,  0.8761,  1.0952,  1.3175,
+     1.5078,  1.7034,  1.9051,  2.1245,  2.3424,  2.5484,  2.7444,  2.9389,
+     0.1740,  0.3293,  0.5174,  0.6824,  0.8394,  1.0372,  1.2046,  1.3723,
+     1.5656,  1.7444,  1.9442,  2.1386,  2.3139,  2.4960,  2.7071,  2.9297,
+     0.2304,  0.3775,  0.4865,  0.6182,  0.7842,  0.9208,  1.1151,  1.2843,
+     1.4641,  1.6988,  1.9209,  2.1260,  2.3099,  2.5229,  2.7414,  2.9276,
+     0.0094,  0.0261, -0.0037,  0.0041, -0.0092, -0.0044, -0.0232, -0.0073,
+    -0.0047, -0.0021,  0.0250, -0.0580, -0.0140, -0.0342, -0.0586,  0.0020,
+     0.0449,  0.0155, -0.0523, -0.0279,  0.0299, -0.0183, -0.0736, -0.0639,
+    -0.0017,  0.0336,  0.0209,  0.0046,  0.0077, -0.0148, -0.0114, -0.0120,
+     0.0115, -0.0050,  0.0445,  0.0048,  0.0188, -0.0137, -0.0080,  0.0239,
+    -0.0184, -0.0524, -0.0195, -0.0126,  0.0284,  0.0632,  0.0141, -0.0093,
+    -0.0096,  0.0196,  0.0230,  0.0379,  0.0308,  0.0237, -0.0224, -0.0600,
+    -0.0755, -0.1074, -0.0988, -0.0606, -0.1038, -0.1552, -0.1480, -0.0672,
+     0.0504,  0.0676,  0.0336, -0.0042,  0.0729,  0.1013,  0.0868,  0.0846,
+     0.0954,  0.0515, -0.0066, -0.0851, -0.0485,  0.0294,  0.0395,  0.0087,
+     0.0078,  0.0446,  0.0881,  0.0672, -0.0384, -0.0025,  0.0415,  0.0353,
+     0.0080,  0.0052,  0.0190,  0.0182,  0.0069,  0.0168,  0.0374,  0.0037,
+    -0.0292, -0.0429,  0.0302,  0.0681, -0.0233, -0.0238, -0.0003, -0.0043,
+     0.0054, -0.0029, -0.0149,  0.0642,  0.0622,  0.0341, -0.0232, -0.0461,
+    -0.0082, -0.0469, -0.0618, -0.0326, -0.0452, -0.0649, -0.0597, -0.0398,
+    -0.0318, -0.0116,  0.0011,  0.0009, -0.0384, -0.0384, -0.0156, -0.0260,
+    -0.0007,  0.0473,  0.0111, -0.0358, -0.0484, -0.0204, -0.0029, -0.0090,
+    -0.0285, -0.0495, -0.0376,  0.0917,  0.1192,  0.1026,  0.0745,  0.0397,
+     0.0463,  0.0253,  0.0025,  0.0465,  0.0100,  0.0488,  0.0416,  0.0223,
+     0.0263,  0.0072, -0.0053,  0.0595,  0.0060, -0.0518, -0.0316, -0.0043,
+    -0.0133, -0.0233, -0.0075, -0.0251,  0.0277, -0.0067, -0.0136, -0.0004,
+     0.0235,  0.0112, -0.0182, -0.0324, -0.0210, -0.0035, -0.0395, -0.0384,
+     0.0005, -0.0150, -0.0356,  0.0127, -0.0033, -0.0034,  0.0205,  0.0747,
+     0.1138,  0.1015,  0.0995, -0.0161, -0.0045,  0.0129,  0.0472,  0.0575,
+     0.0222,  0.0091,  0.0037, -0.0471,  0.0371,  0.0132,  0.0208,  0.0247,
+     0.0117,  0.0164,  0.0225,  0.0124, -0.0023,  0.0088, -0.0046,  0.0047,
+    -0.0393,  0.0018,  0.0148,  0.0020,  0.0044,  0.0165,  0.0229, -0.0208,
+    -0.0477, -0.0310, -0.0164, -0.0390, -0.0764, -0.0525, -0.0094,  0.0075,
+    -0.0102, -0.0045, -0.0504, -0.0709,  0.0822,  0.0710,  0.0426,  0.0014,
+    -0.0371, -0.0400, -0.0157, -0.0155, -0.0173, -0.0138, -0.0015,  0.0134,
+    -0.0418, -0.0682, -0.0256,  0.0050,  0.0360,  0.0354,  0.0074, -0.0396,
+    -0.0235,  0.0284,  0.0494,  0.0153,  0.0448,  0.0025, -0.0061,  0.0252,
+     0.1000,  0.2260,  0.2158,  0.2116,  0.2198,  0.2055,  0.2110,  0.1873,
+     0.1907,  0.2071,  0.2164,  0.2009,  0.2059,  0.2124,  0.2141,  0.2093,
+     0.0875,  0.0981,  0.1177,  0.1071,  0.1033,  0.1248,  0.1048,  0.1238,
+     0.1166,  0.1008,  0.1062,  0.0992,  0.0994,  0.1067,  0.0999,  0.1187,
+     0.0750,  0.0794,  0.0828,  0.0854,  0.0859,  0.0801,  0.0891,  0.0933,
+     0.0969,  0.0920,  0.0915,  0.0862,  0.0868,  0.0891,  0.0842,  0.0824,
+     0.0625,  0.0930,  0.0815,  0.0853,  0.0898,  0.0828,  0.0822,  0.0910,
+     0.0873,  0.0906,  0.0856,  0.0840,  0.0774,  0.0785,  0.0684,  0.0711,
+     0.3319,  0.4219,  0.4588,  0.4090,  0.4092,  0.4014,  0.3548,  0.3353,
+     0.3708,  0.3352,  0.3720,  0.3538,  0.4084,  0.4289,  0.4060,  0.4210,
+     0.0588,  0.0209, -0.0082, -0.0115, -0.0343, -0.0621, -0.0541, -0.0346,
+    -0.0346, -0.0366, -0.0220, -0.0265, -0.0102,  0.0374,  0.0306,  0.0404,
+     0.0306,  0.0090, -0.0054,  0.0333,  0.0047,  0.0238,  0.0141,  0.0165,
+     0.0306,  0.0420,  0.0159,  0.0124,  0.0414,  0.0158, -0.0237,  0.0141,
+     0.0765,  0.0057, -0.0260, -0.0426, -0.0395, -0.0126, -0.0579, -0.0417,
+    -0.0429, -0.0615, -0.0893, -0.0618, -0.0384, -0.0134, -0.0232, -0.0238,
+};
+
+static const float lsp22[] = {
+     0.0664,  0.1875,  0.4300,  0.6730,  0.8793,  1.0640,  1.2563,  1.4433,
+     1.6394,  1.8176,  2.0029,  2.1921,  2.3796,  2.5671,  2.7595,  2.9536,
+     0.2128,  0.4052,  0.5311,  0.6404,  0.7875,  0.8775,  1.0974,  1.3261,
+     1.5563,  1.6790,  1.8339,  2.1195,  2.3226,  2.4609,  2.6440,  2.8947,
+     0.2024,  0.3362,  0.4834,  0.6784,  0.9088,  1.0850,  1.2188,  1.4054,
+     1.6102,  1.7767,  1.9679,  2.1436,  2.3445,  2.5467,  2.7429,  2.9320,
+     0.1181,  0.2279,  0.4413,  0.6114,  0.7710,  0.9427,  1.1142,  1.2707,
+     1.4892,  1.7416,  1.9526,  2.1466,  2.3629,  2.5445,  2.7293,  2.9205,
+     0.1155,  0.2720,  0.4886,  0.6812,  0.8594,  1.0422,  1.2315,  1.4116,
+     1.6137,  1.8020,  1.9758,  2.1743,  2.3602,  2.5568,  2.7472,  2.9374,
+     0.1110,  0.3312,  0.4735,  0.5612,  0.7129,  0.8146,  1.0233,  1.3155,
+     1.5765,  1.7746,  1.9574,  2.1416,  2.3220,  2.5384,  2.7334,  2.9318,
+     0.1656,  0.3350,  0.4215,  0.5609,  0.6759,  0.8503,  1.1405,  1.4094,
+     1.6057,  1.6860,  1.7639,  2.0031,  2.2680,  2.5076,  2.7263,  2.9368,
+     0.1466,  0.3638,  0.4587,  0.5674,  0.7381,  0.8669,  0.9619,  1.1658,
+     1.4667,  1.7440,  1.9335,  2.1018,  2.3022,  2.5281,  2.7359,  2.9261,
+     0.1061,  0.2566,  0.4739,  0.6751,  0.8711,  1.0704,  1.2720,  1.4655,
+     1.6605,  1.8494,  2.0290,  2.2197,  2.4008,  2.5912,  2.7772,  2.9513,
+     0.1116,  0.2364,  0.3971,  0.6316,  0.8583,  1.0335,  1.1686,  1.3302,
+     1.5612,  1.7877,  1.9829,  2.2052,  2.3596,  2.5460,  2.7341,  2.9290,
+     0.2661,  0.4186,  0.5126,  0.6477,  0.8818,  1.1045,  1.2852,  1.4128,
+     1.5851,  1.7593,  1.9399,  2.1757,  2.3684,  2.5136,  2.6927,  2.9064,
+     0.1495,  0.2749,  0.4391,  0.6304,  0.8239,  1.0181,  1.1995,  1.3759,
+     1.5669,  1.7722,  1.9671,  2.1635,  2.3586,  2.5528,  2.7445,  2.9311,
+     0.0912,  0.1759,  0.3066,  0.5660,  0.8005,  0.9568,  1.1832,  1.4504,
+     1.6259,  1.7948,  2.0113,  2.2002,  2.3654,  2.5583,  2.7929,  2.9735,
+     0.1353,  0.2747,  0.4078,  0.5977,  0.7658,  0.9124,  1.1081,  1.3630,
+     1.5875,  1.7847,  1.9323,  2.1181,  2.3321,  2.5046,  2.7183,  2.9225,
+     0.1938,  0.4063,  0.4982,  0.6002,  0.7702,  0.9071,  1.1631,  1.3885,
+     1.6043,  1.8118,  1.9306,  2.0893,  2.2724,  2.4609,  2.6283,  2.8802,
+     0.1857,  0.3351,  0.4381,  0.6101,  0.7561,  0.8555,  1.0384,  1.3171,
+     1.5667,  1.6904,  1.7552,  1.9689,  2.2597,  2.5260,  2.7272,  2.9337,
+     0.1037,  0.2159,  0.4188,  0.6174,  0.8035,  1.0285,  1.2256,  1.4230,
+     1.6400,  1.8322,  2.0144,  2.1988,  2.3810,  2.5682,  2.7613,  2.9438,
+     0.1625,  0.2776,  0.4225,  0.6001,  0.7879,  0.9087,  1.0801,  1.2759,
+     1.4899,  1.7448,  1.9911,  2.1770,  2.3723,  2.5777,  2.7971,  2.9444,
+     0.2111,  0.3640,  0.5839,  0.7290,  0.8051,  1.0023,  1.2315,  1.4143,
+     1.5878,  1.7755,  1.9804,  2.1498,  2.3312,  2.5350,  2.7613,  2.9472,
+     0.1423,  0.2646,  0.4136,  0.6350,  0.8070,  0.9514,  1.1168,  1.3213,
+     1.5776,  1.7721,  1.9404,  2.1545,  2.3385,  2.5137,  2.7396,  2.9553,
+     0.1132,  0.2386,  0.4103,  0.5931,  0.7808,  0.9881,  1.1840,  1.3860,
+     1.6021,  1.7990,  1.9922,  2.1885,  2.3852,  2.5717,  2.7640,  2.9510,
+     0.1267,  0.2602,  0.3913,  0.5944,  0.7598,  0.9198,  1.0781,  1.2715,
+     1.5299,  1.7573,  1.9308,  2.1346,  2.3267,  2.5419,  2.7466,  2.9320,
+     0.2023,  0.3417,  0.4392,  0.6141,  0.7439,  0.8593,  1.1096,  1.3543,
+     1.5185,  1.6553,  1.7862,  2.0341,  2.2718,  2.4834,  2.7103,  2.9466,
+     0.1113,  0.2470,  0.3677,  0.5686,  0.7700,  0.9356,  1.0806,  1.2452,
+     1.4830,  1.7344,  1.9268,  2.1404,  2.3371,  2.5169,  2.7329,  2.9012,
+     0.1664,  0.3554,  0.5573,  0.7471,  0.9245,  1.0998,  1.2787,  1.4655,
+     1.6654,  1.8346,  2.0179,  2.2159,  2.4096,  2.5946,  2.7790,  2.9530,
+     0.1313,  0.2625,  0.4731,  0.6444,  0.8110,  0.9878,  1.1493,  1.3212,
+     1.5719,  1.8138,  1.9861,  2.1943,  2.3714,  2.5578,  2.7346,  2.9296,
+     0.1186,  0.3035,  0.5049,  0.6860,  0.8670,  0.9975,  1.1364,  1.3471,
+     1.5695,  1.7412,  1.9346,  2.1506,  2.3413,  2.5531,  2.7794,  2.9627,
+     0.1108,  0.2697,  0.4787,  0.6344,  0.7909,  0.9586,  1.1440,  1.3511,
+     1.5686,  1.7601,  1.9246,  2.1241,  2.3293,  2.5390,  2.7315,  2.9333,
+     0.0985,  0.2302,  0.3544,  0.5759,  0.7620,  0.9651,  1.1497,  1.3080,
+     1.5500,  1.7845,  1.9518,  2.1734,  2.3565,  2.5665,  2.7605,  2.9102,
+     0.1208,  0.2727,  0.4381,  0.5736,  0.7382,  0.8390,  1.0102,  1.2648,
+     1.5100,  1.7440,  1.9619,  2.1430,  2.3307,  2.5159,  2.7264,  2.9211,
+     0.1582,  0.2777,  0.4475,  0.6551,  0.8591,  1.0084,  1.1414,  1.3291,
+     1.5902,  1.7826,  1.9543,  2.1659,  2.3233,  2.5044,  2.6935,  2.9199,
+     0.1360,  0.2873,  0.4585,  0.6295,  0.7592,  0.9089,  1.0492,  1.2733,
+     1.5391,  1.7768,  1.9372,  2.1329,  2.3168,  2.5015,  2.6857,  2.8837,
+     0.0886,  0.1829,  0.3696,  0.6126,  0.8334,  1.0135,  1.2303,  1.4674,
+     1.6743,  1.8564,  2.0530,  2.2370,  2.3960,  2.5787,  2.7756,  2.9377,
+     0.2005,  0.3537,  0.4700,  0.6249,  0.7385,  0.9097,  1.1759,  1.3811,
+     1.5314,  1.6705,  1.8546,  2.1229,  2.3292,  2.5251,  2.7951,  2.9646,
+     0.1999,  0.3112,  0.4722,  0.7146,  0.8908,  1.0028,  1.1831,  1.3903,
+     1.6125,  1.7514,  1.9083,  2.1248,  2.3271,  2.5339,  2.6945,  2.8918,
+     0.1243,  0.2606,  0.4382,  0.5850,  0.7705,  0.9727,  1.1214,  1.3059,
+     1.5218,  1.7406,  1.9137,  2.1353,  2.3354,  2.5299,  2.7287,  2.9068,
+     0.1039,  0.2426,  0.4265,  0.6284,  0.8152,  0.9941,  1.2004,  1.4038,
+     1.5912,  1.7763,  1.9650,  2.1598,  2.3474,  2.5488,  2.7419,  2.9322,
+     0.1364,  0.2420,  0.3886,  0.5864,  0.7663,  0.8844,  1.0860,  1.3242,
+     1.5518,  1.7893,  2.0004,  2.1562,  2.3619,  2.5516,  2.7687,  2.9181,
+     0.1483,  0.2851,  0.4479,  0.6312,  0.7924,  0.9821,  1.1705,  1.3386,
+     1.5375,  1.7226,  1.9053,  2.0991,  2.2898,  2.4953,  2.7000,  2.9146,
+     0.2332,  0.4561,  0.5407,  0.6212,  0.7524,  0.8215,  0.9522,  1.1685,
+     1.5216,  1.7132,  1.8291,  2.0647,  2.2811,  2.4857,  2.7071,  2.9281,
+     0.1348,  0.3126,  0.5179,  0.7192,  0.9227,  1.1363,  1.3223,  1.4756,
+     1.6509,  1.8191,  1.9991,  2.1976,  2.3877,  2.5768,  2.7590,  2.9386,
+     0.1093,  0.2211,  0.4763,  0.6703,  0.8282,  0.9536,  1.1202,  1.3796,
+     1.6043,  1.8031,  1.9832,  2.1604,  2.3578,  2.5856,  2.7650,  2.9291,
+     0.1865,  0.3027,  0.4580,  0.6719,  0.8400,  1.0082,  1.1901,  1.3782,
+     1.5448,  1.6885,  1.9477,  2.1381,  2.2797,  2.5113,  2.7465,  2.9414,
+     0.1575,  0.3124,  0.4649,  0.6262,  0.8095,  0.9858,  1.1676,  1.3602,
+     1.5646,  1.7582,  1.9550,  2.1671,  2.3628,  2.5734,  2.7670,  2.9519,
+     0.1174,  0.2777,  0.4663,  0.6333,  0.8169,  1.0096,  1.1885,  1.3847,
+     1.5803,  1.7571,  1.9380,  2.1398,  2.3414,  2.5407,  2.7360,  2.9375,
+     0.1073,  0.2264,  0.4083,  0.5973,  0.7474,  0.9514,  1.1349,  1.3337,
+     1.5433,  1.7348,  1.9380,  2.1436,  2.3441,  2.5438,  2.7457,  2.9383,
+     0.1472,  0.2880,  0.4793,  0.6268,  0.8015,  1.0063,  1.1715,  1.3644,
+     1.5525,  1.7410,  1.9258,  2.1227,  2.3214,  2.5149,  2.7148,  2.9196,
+     0.1414,  0.2565,  0.4349,  0.6111,  0.7695,  0.9496,  1.1212,  1.3265,
+     1.5218,  1.7209,  1.9015,  2.0887,  2.3158,  2.5077,  2.7233,  2.9421,
+     0.1252,  0.2667,  0.4454,  0.6431,  0.8371,  1.0124,  1.2110,  1.4160,
+     1.6240,  1.8242,  2.0047,  2.1974,  2.3902,  2.5778,  2.7637,  2.9481,
+     0.1321,  0.2565,  0.3846,  0.5847,  0.7578,  0.9259,  1.0637,  1.2239,
+     1.4690,  1.7346,  1.9750,  2.1882,  2.3712,  2.5509,  2.7280,  2.8885,
+     0.1437,  0.2930,  0.4428,  0.6156,  0.8045,  0.9638,  1.1450,  1.3138,
+     1.5144,  1.7355,  1.9469,  2.1534,  2.3414,  2.5452,  2.7353,  2.9334,
+     0.1692,  0.2770,  0.3831,  0.6100,  0.7825,  0.9302,  1.0690,  1.2481,
+     1.4615,  1.6799,  1.9165,  2.1739,  2.3435,  2.5349,  2.7520,  2.9163,
+     0.1235,  0.2489,  0.4354,  0.6343,  0.8236,  1.0066,  1.1908,  1.3474,
+     1.5656,  1.8275,  2.0620,  2.2548,  2.4135,  2.5913,  2.7639,  2.9334,
+     0.1090,  0.1961,  0.3854,  0.5701,  0.7024,  0.8843,  1.1393,  1.3785,
+     1.5940,  1.7797,  1.9442,  2.1740,  2.3853,  2.5773,  2.7727,  2.9406,
+     0.1560,  0.3477,  0.5011,  0.6287,  0.7612,  0.9896,  1.1510,  1.3420,
+     1.5435,  1.6816,  1.8731,  2.0651,  2.2613,  2.4999,  2.7027,  2.8971,
+     0.1459,  0.2416,  0.3833,  0.5450,  0.7916,  0.9223,  1.0662,  1.1953,
+     1.4029,  1.6616,  1.9320,  2.1459,  2.3386,  2.5081,  2.6799,  2.9195,
+     0.1546,  0.3854,  0.6184,  0.8460,  1.0599,  1.2428,  1.3906,  1.5550,
+     1.7388,  1.8945,  2.0757,  2.2386,  2.4014,  2.5705,  2.7574,  2.9400,
+     0.1080,  0.2307,  0.4112,  0.6067,  0.7725,  0.9467,  1.1285,  1.3205,
+     1.5348,  1.7609,  1.9937,  2.1878,  2.3583,  2.5515,  2.7199,  2.9049,
+     0.1482,  0.3178,  0.4983,  0.6342,  0.7783,  0.9880,  1.2019,  1.3404,
+     1.5223,  1.7296,  1.9211,  2.0943,  2.2928,  2.5008,  2.7136,  2.9224,
+     0.1145,  0.2910,  0.4891,  0.6492,  0.8126,  0.9530,  1.1180,  1.3155,
+     1.5054,  1.6893,  1.8899,  2.1188,  2.3389,  2.5512,  2.7313,  2.9224,
+     0.0939,  0.1689,  0.3250,  0.5792,  0.7698,  0.9245,  1.1574,  1.3865,
+     1.5959,  1.7977,  1.9821,  2.1528,  2.3326,  2.5540,  2.7553,  2.9179,
+     0.1243,  0.2474,  0.3923,  0.6199,  0.7908,  0.9379,  1.1497,  1.3734,
+     1.5582,  1.7420,  1.9539,  2.1385,  2.3240,  2.5277,  2.7311,  2.9178,
+     0.1961,  0.3748,  0.5176,  0.6387,  0.8169,  1.0477,  1.2124,  1.3869,
+     1.5604,  1.7225,  1.8770,  2.0837,  2.2960,  2.5103,  2.6945,  2.8862,
+     0.1295,  0.2403,  0.4149,  0.6189,  0.7913,  0.9130,  1.0832,  1.2787,
+     1.4860,  1.7112,  1.9502,  2.1348,  2.2776,  2.4982,  2.7431,  2.9522,
+     0.0160,  0.0362,  0.0097,  0.0057, -0.0014, -0.0073, -0.0046, -0.0064,
+    -0.0121,  0.0019,  0.0149, -0.0440, -0.0479, -0.0382, -0.0480, -0.0182,
+     0.0170,  0.0114, -0.0298, -0.0175, -0.0033, -0.0354, -0.0510, -0.0025,
+     0.0307,  0.0351,  0.0338,  0.0420,  0.0138, -0.0175, -0.0102,  0.0053,
+     0.0084, -0.0003,  0.0412, -0.0027,  0.0145, -0.0039,  0.0083,  0.0400,
+     0.0001, -0.0262,  0.0055, -0.0082,  0.0348,  0.0433,  0.0137, -0.0024,
+    -0.0055,  0.0262,  0.0521,  0.0349,  0.0185,  0.0076, -0.0319, -0.0561,
+    -0.0460, -0.0253, -0.0097,  0.0163,  0.0184, -0.0037, -0.0480, -0.0371,
+     0.0628,  0.0665,  0.0296, -0.0057,  0.0253,  0.0227,  0.0350,  0.0692,
+     0.0545,  0.0218,  0.0094, -0.0449, -0.0372,  0.0005,  0.0258,  0.0118,
+     0.0285,  0.0760,  0.0822,  0.0527, -0.0299, -0.0049,  0.0170,  0.0195,
+     0.0136,  0.0286,  0.0289,  0.0139,  0.0054,  0.0152,  0.0244,  0.0028,
+    -0.0056, -0.0260,  0.0307,  0.0572, -0.0087,  0.0088,  0.0062,  0.0000,
+     0.0125,  0.0000, -0.0292,  0.0820,  0.0872,  0.0646,  0.0346,  0.0076,
+    -0.0022, -0.0253, -0.0567, -0.0188, -0.0336, -0.0673, -0.0549, -0.0166,
+    -0.0259, -0.0140,  0.0040, -0.0029, -0.0430, -0.0531, -0.0253, -0.0019,
+    -0.0071,  0.0393,  0.0072, -0.0327, -0.0236, -0.0235, -0.0177, -0.0186,
+    -0.0280, -0.0201, -0.0077,  0.0383,  0.0418,  0.0321,  0.0294,  0.0169,
+     0.0468,  0.0301,  0.0133,  0.0363,  0.0516,  0.0937,  0.1240,  0.1404,
+     0.1325,  0.1178,  0.0999,  0.0251, -0.0037, -0.0495, -0.0703, -0.0219,
+    -0.0261, -0.0304, -0.0204, -0.0372,  0.0355,  0.0131, -0.0093, -0.0099,
+    -0.0069, -0.0034, -0.0065, -0.0208, -0.0231, -0.0117, -0.0211, -0.0243,
+     0.0046, -0.0107, -0.0070,  0.0123,  0.0230,  0.0152,  0.0164,  0.0412,
+     0.0619,  0.0858,  0.0862, -0.0056,  0.0125,  0.0182,  0.0347,  0.0388,
+     0.0456,  0.0407, -0.0249, -0.0460,  0.0206,  0.0299,  0.0253,  0.0207,
+     0.0177,  0.0238,  0.0253,  0.0030,  0.0042,  0.0020, -0.0081, -0.0136,
+    -0.0290, -0.0042,  0.0122,  0.0051,  0.0107,  0.0228,  0.0211, -0.0068,
+    -0.0436, -0.0299, -0.0078, -0.0779, -0.1157, -0.0679,  0.0172,  0.0150,
+    -0.0051,  0.0081, -0.0512, -0.0616,  0.0576,  0.0799,  0.0803,  0.0336,
+     0.0001, -0.0298, -0.0747, -0.0115, -0.0101, -0.0170, -0.0050,  0.0174,
+    -0.0290, -0.0601, -0.0150,  0.0121,  0.0165,  0.0230,  0.0028, -0.0317,
+    -0.0165,  0.0356,  0.0451,  0.0120,  0.0321,  0.0084, -0.0058,  0.0122,
+     0.1935,  0.1802,  0.2195,  0.2410,  0.2201,  0.1915,  0.1840,  0.1935,
+     0.2213,  0.2079,  0.1858,  0.1974,  0.2239,  0.2173,  0.1840,  0.2120,
+     0.4912,  0.4777,  0.4607,  0.4395,  0.4426,  0.4388,  0.4416,  0.4345,
+     0.4239,  0.4331,  0.4522,  0.4423,  0.4475,  0.4387,  0.4525,  0.4446,
+};
+
+static const float lsp22s[] = {
+     0.0664,  0.1875,  0.4300,  0.6730,  0.8793,  1.0640,  1.2563,  1.4433,
+     1.6394,  1.8176,  2.0029,  2.1921,  2.3796,  2.5671,  2.7595,  2.9536,
+     0.2128,  0.4052,  0.5311,  0.6404,  0.7875,  0.8775,  1.0974,  1.3261,
+     1.5563,  1.6790,  1.8339,  2.1195,  2.3226,  2.4609,  2.6440,  2.8947,
+     0.2024,  0.3362,  0.4834,  0.6784,  0.9088,  1.0850,  1.2188,  1.4054,
+     1.6102,  1.7767,  1.9679,  2.1436,  2.3445,  2.5467,  2.7429,  2.9320,
+     0.1181,  0.2279,  0.4413,  0.6114,  0.7710,  0.9427,  1.1142,  1.2707,
+     1.4892,  1.7416,  1.9526,  2.1466,  2.3629,  2.5445,  2.7293,  2.9205,
+     0.1155,  0.2720,  0.4886,  0.6812,  0.8594,  1.0422,  1.2315,  1.4116,
+     1.6137,  1.8020,  1.9758,  2.1743,  2.3602,  2.5568,  2.7472,  2.9374,
+     0.1110,  0.3312,  0.4735,  0.5612,  0.7129,  0.8146,  1.0233,  1.3155,
+     1.5765,  1.7746,  1.9574,  2.1416,  2.3220,  2.5384,  2.7334,  2.9318,
+     0.1656,  0.3350,  0.4215,  0.5609,  0.6759,  0.8503,  1.1405,  1.4094,
+     1.6057,  1.6860,  1.7639,  2.0031,  2.2680,  2.5076,  2.7263,  2.9368,
+     0.1466,  0.3638,  0.4587,  0.5674,  0.7381,  0.8669,  0.9619,  1.1658,
+     1.4667,  1.7440,  1.9335,  2.1018,  2.3022,  2.5281,  2.7359,  2.9261,
+     0.1061,  0.2566,  0.4739,  0.6751,  0.8711,  1.0704,  1.2720,  1.4655,
+     1.6605,  1.8494,  2.0290,  2.2197,  2.4008,  2.5912,  2.7772,  2.9513,
+     0.1116,  0.2364,  0.3971,  0.6316,  0.8583,  1.0335,  1.1686,  1.3302,
+     1.5612,  1.7877,  1.9829,  2.2052,  2.3596,  2.5460,  2.7341,  2.9290,
+     0.2661,  0.4186,  0.5126,  0.6477,  0.8818,  1.1045,  1.2852,  1.4128,
+     1.5851,  1.7593,  1.9399,  2.1757,  2.3684,  2.5136,  2.6927,  2.9064,
+     0.1495,  0.2749,  0.4391,  0.6304,  0.8239,  1.0181,  1.1995,  1.3759,
+     1.5669,  1.7722,  1.9671,  2.1635,  2.3586,  2.5528,  2.7445,  2.9311,
+     0.0912,  0.1759,  0.3066,  0.5660,  0.8005,  0.9568,  1.1832,  1.4504,
+     1.6259,  1.7948,  2.0113,  2.2002,  2.3654,  2.5583,  2.7929,  2.9735,
+     0.1353,  0.2747,  0.4078,  0.5977,  0.7658,  0.9124,  1.1081,  1.3630,
+     1.5875,  1.7847,  1.9323,  2.1181,  2.3321,  2.5046,  2.7183,  2.9225,
+     0.1938,  0.4063,  0.4982,  0.6002,  0.7702,  0.9071,  1.1631,  1.3885,
+     1.6043,  1.8118,  1.9306,  2.0893,  2.2724,  2.4609,  2.6283,  2.8802,
+     0.1857,  0.3351,  0.4381,  0.6101,  0.7561,  0.8555,  1.0384,  1.3171,
+     1.5667,  1.6904,  1.7552,  1.9689,  2.2597,  2.5260,  2.7272,  2.9337,
+     0.1037,  0.2159,  0.4188,  0.6174,  0.8035,  1.0285,  1.2256,  1.4230,
+     1.6400,  1.8322,  2.0144,  2.1988,  2.3810,  2.5682,  2.7613,  2.9438,
+     0.1625,  0.2776,  0.4225,  0.6001,  0.7879,  0.9087,  1.0801,  1.2759,
+     1.4899,  1.7448,  1.9911,  2.1770,  2.3723,  2.5777,  2.7971,  2.9444,
+     0.2111,  0.3640,  0.5839,  0.7290,  0.8051,  1.0023,  1.2315,  1.4143,
+     1.5878,  1.7755,  1.9804,  2.1498,  2.3312,  2.5350,  2.7613,  2.9472,
+     0.1423,  0.2646,  0.4136,  0.6350,  0.8070,  0.9514,  1.1168,  1.3213,
+     1.5776,  1.7721,  1.9404,  2.1545,  2.3385,  2.5137,  2.7396,  2.9553,
+     0.1132,  0.2386,  0.4103,  0.5931,  0.7808,  0.9881,  1.1840,  1.3860,
+     1.6021,  1.7990,  1.9922,  2.1885,  2.3852,  2.5717,  2.7640,  2.9510,
+     0.1267,  0.2602,  0.3913,  0.5944,  0.7598,  0.9198,  1.0781,  1.2715,
+     1.5299,  1.7573,  1.9308,  2.1346,  2.3267,  2.5419,  2.7466,  2.9320,
+     0.2023,  0.3417,  0.4392,  0.6141,  0.7439,  0.8593,  1.1096,  1.3543,
+     1.5185,  1.6553,  1.7862,  2.0341,  2.2718,  2.4834,  2.7103,  2.9466,
+     0.1113,  0.2470,  0.3677,  0.5686,  0.7700,  0.9356,  1.0806,  1.2452,
+     1.4830,  1.7344,  1.9268,  2.1404,  2.3371,  2.5169,  2.7329,  2.9012,
+     0.1664,  0.3554,  0.5573,  0.7471,  0.9245,  1.0998,  1.2787,  1.4655,
+     1.6654,  1.8346,  2.0179,  2.2159,  2.4096,  2.5946,  2.7790,  2.9530,
+     0.1313,  0.2625,  0.4731,  0.6444,  0.8110,  0.9878,  1.1493,  1.3212,
+     1.5719,  1.8138,  1.9861,  2.1943,  2.3714,  2.5578,  2.7346,  2.9296,
+     0.1186,  0.3035,  0.5049,  0.6860,  0.8670,  0.9975,  1.1364,  1.3471,
+     1.5695,  1.7412,  1.9346,  2.1506,  2.3413,  2.5531,  2.7794,  2.9627,
+     0.1108,  0.2697,  0.4787,  0.6344,  0.7909,  0.9586,  1.1440,  1.3511,
+     1.5686,  1.7601,  1.9246,  2.1241,  2.3293,  2.5390,  2.7315,  2.9333,
+     0.0985,  0.2302,  0.3544,  0.5759,  0.7620,  0.9651,  1.1497,  1.3080,
+     1.5500,  1.7845,  1.9518,  2.1734,  2.3565,  2.5665,  2.7605,  2.9102,
+     0.1208,  0.2727,  0.4381,  0.5736,  0.7382,  0.8390,  1.0102,  1.2648,
+     1.5100,  1.7440,  1.9619,  2.1430,  2.3307,  2.5159,  2.7264,  2.9211,
+     0.1582,  0.2777,  0.4475,  0.6551,  0.8591,  1.0084,  1.1414,  1.3291,
+     1.5902,  1.7826,  1.9543,  2.1659,  2.3233,  2.5044,  2.6935,  2.9199,
+     0.1360,  0.2873,  0.4585,  0.6295,  0.7592,  0.9089,  1.0492,  1.2733,
+     1.5391,  1.7768,  1.9372,  2.1329,  2.3168,  2.5015,  2.6857,  2.8837,
+     0.0886,  0.1829,  0.3696,  0.6126,  0.8334,  1.0135,  1.2303,  1.4674,
+     1.6743,  1.8564,  2.0530,  2.2370,  2.3960,  2.5787,  2.7756,  2.9377,
+     0.2005,  0.3537,  0.4700,  0.6249,  0.7385,  0.9097,  1.1759,  1.3811,
+     1.5314,  1.6705,  1.8546,  2.1229,  2.3292,  2.5251,  2.7951,  2.9646,
+     0.1999,  0.3112,  0.4722,  0.7146,  0.8908,  1.0028,  1.1831,  1.3903,
+     1.6125,  1.7514,  1.9083,  2.1248,  2.3271,  2.5339,  2.6945,  2.8918,
+     0.1243,  0.2606,  0.4382,  0.5850,  0.7705,  0.9727,  1.1214,  1.3059,
+     1.5218,  1.7406,  1.9137,  2.1353,  2.3354,  2.5299,  2.7287,  2.9068,
+     0.1039,  0.2426,  0.4265,  0.6284,  0.8152,  0.9941,  1.2004,  1.4038,
+     1.5912,  1.7763,  1.9650,  2.1598,  2.3474,  2.5488,  2.7419,  2.9322,
+     0.1364,  0.2420,  0.3886,  0.5864,  0.7663,  0.8844,  1.0860,  1.3242,
+     1.5518,  1.7893,  2.0004,  2.1562,  2.3619,  2.5516,  2.7687,  2.9181,
+     0.1483,  0.2851,  0.4479,  0.6312,  0.7924,  0.9821,  1.1705,  1.3386,
+     1.5375,  1.7226,  1.9053,  2.0991,  2.2898,  2.4953,  2.7000,  2.9146,
+     0.2332,  0.4561,  0.5407,  0.6212,  0.7524,  0.8215,  0.9522,  1.1685,
+     1.5216,  1.7132,  1.8291,  2.0647,  2.2811,  2.4857,  2.7071,  2.9281,
+     0.1348,  0.3126,  0.5179,  0.7192,  0.9227,  1.1363,  1.3223,  1.4756,
+     1.6509,  1.8191,  1.9991,  2.1976,  2.3877,  2.5768,  2.7590,  2.9386,
+     0.1093,  0.2211,  0.4763,  0.6703,  0.8282,  0.9536,  1.1202,  1.3796,
+     1.6043,  1.8031,  1.9832,  2.1604,  2.3578,  2.5856,  2.7650,  2.9291,
+     0.1865,  0.3027,  0.4580,  0.6719,  0.8400,  1.0082,  1.1901,  1.3782,
+     1.5448,  1.6885,  1.9477,  2.1381,  2.2797,  2.5113,  2.7465,  2.9414,
+     0.1575,  0.3124,  0.4649,  0.6262,  0.8095,  0.9858,  1.1676,  1.3602,
+     1.5646,  1.7582,  1.9550,  2.1671,  2.3628,  2.5734,  2.7670,  2.9519,
+     0.1174,  0.2777,  0.4663,  0.6333,  0.8169,  1.0096,  1.1885,  1.3847,
+     1.5803,  1.7571,  1.9380,  2.1398,  2.3414,  2.5407,  2.7360,  2.9375,
+     0.1073,  0.2264,  0.4083,  0.5973,  0.7474,  0.9514,  1.1349,  1.3337,
+     1.5433,  1.7348,  1.9380,  2.1436,  2.3441,  2.5438,  2.7457,  2.9383,
+     0.1472,  0.2880,  0.4793,  0.6268,  0.8015,  1.0063,  1.1715,  1.3644,
+     1.5525,  1.7410,  1.9258,  2.1227,  2.3214,  2.5149,  2.7148,  2.9196,
+     0.1414,  0.2565,  0.4349,  0.6111,  0.7695,  0.9496,  1.1212,  1.3265,
+     1.5218,  1.7209,  1.9015,  2.0887,  2.3158,  2.5077,  2.7233,  2.9421,
+     0.1252,  0.2667,  0.4454,  0.6431,  0.8371,  1.0124,  1.2110,  1.4160,
+     1.6240,  1.8242,  2.0047,  2.1974,  2.3902,  2.5778,  2.7637,  2.9481,
+     0.1321,  0.2565,  0.3846,  0.5847,  0.7578,  0.9259,  1.0637,  1.2239,
+     1.4690,  1.7346,  1.9750,  2.1882,  2.3712,  2.5509,  2.7280,  2.8885,
+     0.1437,  0.2930,  0.4428,  0.6156,  0.8045,  0.9638,  1.1450,  1.3138,
+     1.5144,  1.7355,  1.9469,  2.1534,  2.3414,  2.5452,  2.7353,  2.9334,
+     0.1692,  0.2770,  0.3831,  0.6100,  0.7825,  0.9302,  1.0690,  1.2481,
+     1.4615,  1.6799,  1.9165,  2.1739,  2.3435,  2.5349,  2.7520,  2.9163,
+     0.1235,  0.2489,  0.4354,  0.6343,  0.8236,  1.0066,  1.1908,  1.3474,
+     1.5656,  1.8275,  2.0620,  2.2548,  2.4135,  2.5913,  2.7639,  2.9334,
+     0.1090,  0.1961,  0.3854,  0.5701,  0.7024,  0.8843,  1.1393,  1.3785,
+     1.5940,  1.7797,  1.9442,  2.1740,  2.3853,  2.5773,  2.7727,  2.9406,
+     0.1560,  0.3477,  0.5011,  0.6287,  0.7612,  0.9896,  1.1510,  1.3420,
+     1.5435,  1.6816,  1.8731,  2.0651,  2.2613,  2.4999,  2.7027,  2.8971,
+     0.1459,  0.2416,  0.3833,  0.5450,  0.7916,  0.9223,  1.0662,  1.1953,
+     1.4029,  1.6616,  1.9320,  2.1459,  2.3386,  2.5081,  2.6799,  2.9195,
+     0.1546,  0.3854,  0.6184,  0.8460,  1.0599,  1.2428,  1.3906,  1.5550,
+     1.7388,  1.8945,  2.0757,  2.2386,  2.4014,  2.5705,  2.7574,  2.9400,
+     0.1080,  0.2307,  0.4112,  0.6067,  0.7725,  0.9467,  1.1285,  1.3205,
+     1.5348,  1.7609,  1.9937,  2.1878,  2.3583,  2.5515,  2.7199,  2.9049,
+     0.1482,  0.3178,  0.4983,  0.6342,  0.7783,  0.9880,  1.2019,  1.3404,
+     1.5223,  1.7296,  1.9211,  2.0943,  2.2928,  2.5008,  2.7136,  2.9224,
+     0.1145,  0.2910,  0.4891,  0.6492,  0.8126,  0.9530,  1.1180,  1.3155,
+     1.5054,  1.6893,  1.8899,  2.1188,  2.3389,  2.5512,  2.7313,  2.9224,
+     0.0939,  0.1689,  0.3250,  0.5792,  0.7698,  0.9245,  1.1574,  1.3865,
+     1.5959,  1.7977,  1.9821,  2.1528,  2.3326,  2.5540,  2.7553,  2.9179,
+     0.1243,  0.2474,  0.3923,  0.6199,  0.7908,  0.9379,  1.1497,  1.3734,
+     1.5582,  1.7420,  1.9539,  2.1385,  2.3240,  2.5277,  2.7311,  2.9178,
+     0.1961,  0.3748,  0.5176,  0.6387,  0.8169,  1.0477,  1.2124,  1.3869,
+     1.5604,  1.7225,  1.8770,  2.0837,  2.2960,  2.5103,  2.6945,  2.8862,
+     0.1295,  0.2403,  0.4149,  0.6189,  0.7913,  0.9130,  1.0832,  1.2787,
+     1.4860,  1.7112,  1.9502,  2.1348,  2.2776,  2.4982,  2.7431,  2.9522,
+     0.0160,  0.0362,  0.0097,  0.0057, -0.0014, -0.0073, -0.0046, -0.0064,
+    -0.0121,  0.0019,  0.0149, -0.0440, -0.0479, -0.0382, -0.0480, -0.0182,
+     0.0170,  0.0114, -0.0298, -0.0175, -0.0033, -0.0354, -0.0510, -0.0025,
+     0.0307,  0.0351,  0.0338,  0.0420,  0.0138, -0.0175, -0.0102,  0.0053,
+     0.0084, -0.0003,  0.0412, -0.0027,  0.0145, -0.0039,  0.0083,  0.0400,
+     0.0001, -0.0262,  0.0055, -0.0082,  0.0348,  0.0433,  0.0137, -0.0024,
+    -0.0055,  0.0262,  0.0521,  0.0349,  0.0185,  0.0076, -0.0319, -0.0561,
+    -0.0460, -0.0253, -0.0097,  0.0163,  0.0184, -0.0037, -0.0480, -0.0371,
+     0.0628,  0.0665,  0.0296, -0.0057,  0.0253,  0.0227,  0.0350,  0.0692,
+     0.0545,  0.0218,  0.0094, -0.0449, -0.0372,  0.0005,  0.0258,  0.0118,
+     0.0285,  0.0760,  0.0822,  0.0527, -0.0299, -0.0049,  0.0170,  0.0195,
+     0.0136,  0.0286,  0.0289,  0.0139,  0.0054,  0.0152,  0.0244,  0.0028,
+    -0.0056, -0.0260,  0.0307,  0.0572, -0.0087,  0.0088,  0.0062,  0.0000,
+     0.0125,  0.0000, -0.0292,  0.0820,  0.0872,  0.0646,  0.0346,  0.0076,
+    -0.0022, -0.0253, -0.0567, -0.0188, -0.0336, -0.0673, -0.0549, -0.0166,
+    -0.0259, -0.0140,  0.0040, -0.0029, -0.0430, -0.0531, -0.0253, -0.0019,
+    -0.0071,  0.0393,  0.0072, -0.0327, -0.0236, -0.0235, -0.0177, -0.0186,
+    -0.0280, -0.0201, -0.0077,  0.0383,  0.0418,  0.0321,  0.0294,  0.0169,
+     0.0468,  0.0301,  0.0133,  0.0363,  0.0516,  0.0937,  0.1240,  0.1404,
+     0.1325,  0.1178,  0.0999,  0.0251, -0.0037, -0.0495, -0.0703, -0.0219,
+    -0.0261, -0.0304, -0.0204, -0.0372,  0.0355,  0.0131, -0.0093, -0.0099,
+    -0.0069, -0.0034, -0.0065, -0.0208, -0.0231, -0.0117, -0.0211, -0.0243,
+     0.0046, -0.0107, -0.0070,  0.0123,  0.0230,  0.0152,  0.0164,  0.0412,
+     0.0619,  0.0858,  0.0862, -0.0056,  0.0125,  0.0182,  0.0347,  0.0388,
+     0.0456,  0.0407, -0.0249, -0.0460,  0.0206,  0.0299,  0.0253,  0.0207,
+     0.0177,  0.0238,  0.0253,  0.0030,  0.0042,  0.0020, -0.0081, -0.0136,
+    -0.0290, -0.0042,  0.0122,  0.0051,  0.0107,  0.0228,  0.0211, -0.0068,
+    -0.0436, -0.0299, -0.0078, -0.0779, -0.1157, -0.0679,  0.0172,  0.0150,
+    -0.0051,  0.0081, -0.0512, -0.0616,  0.0576,  0.0799,  0.0803,  0.0336,
+     0.0001, -0.0298, -0.0747, -0.0115, -0.0101, -0.0170, -0.0050,  0.0174,
+    -0.0290, -0.0601, -0.0150,  0.0121,  0.0165,  0.0230,  0.0028, -0.0317,
+    -0.0165,  0.0356,  0.0451,  0.0120,  0.0321,  0.0084, -0.0058,  0.0122,
+     0.1935,  0.1802,  0.2195,  0.2410,  0.2201,  0.1915,  0.1840,  0.1935,
+     0.2213,  0.2079,  0.1858,  0.1974,  0.2239,  0.2173,  0.1840,  0.2120,
+     0.4912,  0.4777,  0.4607,  0.4395,  0.4426,  0.4388,  0.4416,  0.4345,
+     0.4239,  0.4331,  0.4522,  0.4423,  0.4475,  0.4387,  0.4525,  0.4446,
+};
+
+static const float lsp44s[] = {
+     0.0927,  0.2291,  0.4059,  0.5779,  0.7288,  0.8821,  1.0377,  1.1915,
+     1.3433,  1.4931,  1.6475,  1.7989,  1.9381,  2.0858,  2.2321,  2.3765,
+     2.5187,  2.6530,  2.7895,  2.9354,  0.0944,  0.1974,  0.3046,  0.4714,
+     0.6116,  0.7829,  0.9027,  1.0375,  1.1869,  1.3488,  1.5036,  1.6781,
+     1.8276,  1.9983,  2.1449,  2.3089,  2.4534,  2.6113,  2.7553,  2.9062,
+     0.1168,  0.2843,  0.4907,  0.6706,  0.8100,  0.9417,  1.0753,  1.2014,
+     1.3151,  1.4496,  1.5832,  1.7379,  1.8642,  2.0230,  2.1681,  2.3250,
+     2.4676,  2.6242,  2.7602,  2.9066,  0.1353,  0.2335,  0.3370,  0.4380,
+     0.5819,  0.7353,  0.8671,  1.0160,  1.1435,  1.2977,  1.4860,  1.6739,
+     1.8412,  2.0028,  2.1537,  2.3124,  2.4741,  2.6272,  2.7862,  2.9536,
+     0.1003,  0.2226,  0.3584,  0.4971,  0.6291,  0.7710,  0.9157,  1.0669,
+     1.2143,  1.3624,  1.5104,  1.6681,  1.8164,  1.9823,  2.1394,  2.3082,
+     2.4677,  2.6306,  2.7909,  2.9382,  0.1056,  0.2027,  0.2956,  0.4005,
+     0.5215,  0.6708,  0.8545,  1.0557,  1.2344,  1.4023,  1.5676,  1.7278,
+     1.8808,  2.0381,  2.1846,  2.3376,  2.4887,  2.6377,  2.7878,  2.9504,
+     0.1015,  0.2462,  0.4122,  0.5783,  0.7233,  0.8833,  1.0377,  1.1903,
+     1.3341,  1.4727,  1.6138,  1.7582,  1.8912,  2.0370,  2.1701,  2.3125,
+     2.4500,  2.6006,  2.7507,  2.9166,  0.1787,  0.2418,  0.3265,  0.5379,
+     0.6584,  0.7681,  0.9545,  1.1050,  1.2125,  1.3528,  1.4763,  1.6705,
+     1.8136,  1.9594,  2.0936,  2.2724,  2.4394,  2.5919,  2.7037,  2.8747,
+     0.0859,  0.1600,  0.2980,  0.4933,  0.6696,  0.8285,  0.9958,  1.1545,
+     1.3107,  1.4591,  1.6127,  1.7652,  1.9143,  2.0680,  2.2171,  2.3643,
+     2.5141,  2.6611,  2.8143,  2.9691,  0.0910,  0.2110,  0.3364,  0.4718,
+     0.5856,  0.7298,  0.8910,  1.0514,  1.1988,  1.3572,  1.5178,  1.6861,
+     1.8399,  2.0099,  2.1639,  2.3225,  2.4774,  2.6321,  2.7863,  2.9412,
+     0.1904,  0.2874,  0.3681,  0.4981,  0.6248,  0.7880,  0.9121,  1.0750,
+     1.2185,  1.3809,  1.5296,  1.7007,  1.8592,  2.0470,  2.1913,  2.3250,
+     2.4519,  2.5984,  2.7408,  2.9023,  0.0917,  0.2067,  0.3246,  0.4961,
+     0.6310,  0.8024,  0.9438,  1.1008,  1.2362,  1.3892,  1.5407,  1.7033,
+     1.8427,  2.0061,  2.1498,  2.3117,  2.4550,  2.6053,  2.7462,  2.9029,
+     0.0989,  0.2193,  0.3756,  0.5410,  0.6929,  0.8368,  0.9801,  1.1250,
+     1.2677,  1.4184,  1.5677,  1.7292,  1.8770,  2.0311,  2.1803,  2.3306,
+     2.4836,  2.6339,  2.7943,  2.9549,  0.0861,  0.1943,  0.3057,  0.4867,
+     0.6194,  0.7592,  0.9184,  1.1052,  1.2486,  1.4064,  1.5609,  1.7273,
+     1.8703,  2.0291,  2.1686,  2.3225,  2.4628,  2.6115,  2.7471,  2.9005,
+     0.0932,  0.2110,  0.3737,  0.5479,  0.7120,  0.8570,  0.9975,  1.1364,
+     1.2772,  1.4220,  1.5612,  1.7089,  1.8410,  1.9827,  2.1263,  2.2859,
+     2.4459,  2.6172,  2.7788,  2.9395,  0.1193,  0.2341,  0.3523,  0.5029,
+     0.6437,  0.7803,  0.9367,  1.1007,  1.2392,  1.3869,  1.5425,  1.7168,
+     1.8709,  2.0248,  2.1584,  2.2949,  2.4308,  2.5823,  2.7235,  2.9034,
+     0.0834,  0.1988,  0.3557,  0.5261,  0.6767,  0.8427,  1.0029,  1.1683,
+     1.3138,  1.4527,  1.6046,  1.7583,  1.9011,  2.0517,  2.1928,  2.3397,
+     2.4839,  2.6291,  2.7771,  2.9329,  0.0938,  0.1967,  0.3213,  0.4675,
+     0.6068,  0.7664,  0.9418,  1.1120,  1.2535,  1.3932,  1.5243,  1.6801,
+     1.8346,  1.9931,  2.1376,  2.3035,  2.4636,  2.6244,  2.7829,  2.9371,
+     0.1017,  0.2552,  0.4327,  0.6017,  0.7467,  0.8797,  1.0097,  1.1442,
+     1.2628,  1.4049,  1.5541,  1.7090,  1.8461,  1.9982,  2.1486,  2.3029,
+     2.4513,  2.6075,  2.7594,  2.9209,  0.1031,  0.2295,  0.3747,  0.5122,
+     0.6596,  0.7935,  0.9345,  1.1050,  1.2384,  1.3543,  1.4739,  1.6136,
+     1.7447,  1.8914,  2.0434,  2.1916,  2.3557,  2.5396,  2.7419,  2.9401,
+     0.1007,  0.2374,  0.3715,  0.5173,  0.6465,  0.8069,  0.9553,  1.1145,
+     1.2594,  1.4143,  1.5617,  1.7166,  1.8457,  2.0012,  2.1462,  2.2864,
+     2.4258,  2.5910,  2.7372,  2.9018,  0.0808,  0.1726,  0.2849,  0.4592,
+     0.6118,  0.7853,  0.9588,  1.1256,  1.2751,  1.4392,  1.5898,  1.7514,
+     1.8977,  2.0554,  2.1937,  2.3430,  2.4831,  2.6249,  2.7601,  2.9155,
+     0.1669,  0.2574,  0.3694,  0.5569,  0.6773,  0.8061,  1.0160,  1.1667,
+     1.2791,  1.4041,  1.5452,  1.7207,  1.8524,  2.0038,  2.1414,  2.3338,
+     2.4747,  2.6157,  2.7303,  2.8848,  0.1598,  0.2521,  0.3416,  0.5149,
+     0.6703,  0.7941,  0.9408,  1.1164,  1.2017,  1.3293,  1.4908,  1.6783,
+     1.8438,  1.9927,  2.1149,  2.2698,  2.4420,  2.6193,  2.7583,  2.9103,
+     0.0902,  0.1978,  0.3265,  0.4578,  0.5878,  0.7439,  0.9110,  1.0906,
+     1.2556,  1.4125,  1.5688,  1.7295,  1.8829,  2.0472,  2.2058,  2.3537,
+     2.5075,  2.6548,  2.8058,  2.9538,  0.0818,  0.1695,  0.2794,  0.4470,
+     0.6069,  0.7641,  0.9313,  1.0946,  1.2411,  1.4072,  1.5640,  1.7186,
+     1.8651,  2.0254,  2.1726,  2.3286,  2.4784,  2.6287,  2.7750,  2.9339,
+     0.1980,  0.3134,  0.4099,  0.4975,  0.6491,  0.8376,  0.9441,  1.0298,
+     1.1795,  1.3866,  1.5784,  1.7209,  1.8137,  1.9271,  2.0863,  2.2930,
+     2.4696,  2.6184,  2.7587,  2.9251,  0.1338,  0.2341,  0.3566,  0.4797,
+     0.6129,  0.7580,  0.9093,  1.0491,  1.1911,  1.3313,  1.4841,  1.6503,
+     1.8035,  1.9685,  2.1128,  2.2694,  2.4093,  2.5728,  2.7206,  2.8994,
+     0.0937,  0.2034,  0.3447,  0.5032,  0.6370,  0.7993,  0.9674,  1.1323,
+     1.2830,  1.4199,  1.5492,  1.7010,  1.8513,  2.0087,  2.1550,  2.3115,
+     2.4643,  2.6237,  2.7812,  2.9392,  0.1085,  0.2152,  0.3126,  0.4569,
+     0.5718,  0.7213,  0.8837,  1.0604,  1.2053,  1.3755,  1.5397,  1.7001,
+     1.8409,  2.0039,  2.1498,  2.3080,  2.4535,  2.6063,  2.7505,  2.9110,
+     0.0562,  0.2066,  0.4034,  0.5490,  0.6682,  0.7924,  0.9495,  1.0800,
+     1.1869,  1.3156,  1.4834,  1.6619,  1.8404,  2.0199,  2.1509,  2.2755,
+     2.4072,  2.5580,  2.6993,  2.8913,  0.0939,  0.2303,  0.3742,  0.5260,
+     0.6662,  0.8294,  0.9769,  1.1315,  1.2792,  1.4153,  1.5436,  1.6701,
+     1.8215,  1.9920,  2.1310,  2.3005,  2.4534,  2.5786,  2.7204,  2.9068,
+     0.1005,  0.2442,  0.3898,  0.5398,  0.6958,  0.8474,  1.0008,  1.1556,
+     1.3020,  1.4456,  1.5954,  1.7470,  1.8922,  2.0500,  2.2019,  2.3492,
+     2.4963,  2.6412,  2.7890,  2.9423,  0.1022,  0.2031,  0.3213,  0.4402,
+     0.5637,  0.7117,  0.8673,  1.0242,  1.1727,  1.3206,  1.4846,  1.6465,
+     1.8015,  1.9655,  2.1233,  2.2873,  2.4464,  2.6074,  2.7685,  2.9409,
+     0.1985,  0.3497,  0.4622,  0.5982,  0.7489,  0.8752,  0.9925,  1.1679,
+     1.3288,  1.4606,  1.5820,  1.7492,  1.8922,  2.0511,  2.1780,  2.3373,
+     2.4760,  2.6233,  2.7466,  2.8978,  0.1284,  0.2433,  0.3630,  0.4852,
+     0.6117,  0.7460,  0.8904,  1.0360,  1.1738,  1.3142,  1.4696,  1.6185,
+     1.7719,  1.9318,  2.0961,  2.2697,  2.4408,  2.6046,  2.7681,  2.9451,
+     0.1042,  0.2286,  0.3598,  0.5064,  0.6438,  0.7899,  0.9350,  1.0891,
+     1.2323,  1.3807,  1.5225,  1.6747,  1.8153,  1.9669,  2.1145,  2.2832,
+     2.4430,  2.6085,  2.7748,  2.9346,  0.0780,  0.1724,  0.2440,  0.3489,
+     0.5280,  0.7426,  0.9272,  1.0914,  1.2562,  1.4188,  1.5804,  1.7376,
+     1.8909,  2.0473,  2.1946,  2.3457,  2.4950,  2.6424,  2.7926,  2.9549,
+     0.1103,  0.2608,  0.4087,  0.5538,  0.6923,  0.8418,  0.9940,  1.1507,
+     1.2919,  1.4406,  1.5802,  1.7262,  1.8638,  2.0085,  2.1572,  2.2975,
+     2.4329,  2.5866,  2.7380,  2.9107,  0.1297,  0.2532,  0.4003,  0.5329,
+     0.6733,  0.7950,  0.9557,  1.0859,  1.2235,  1.3538,  1.5037,  1.6389,
+     1.7964,  1.9285,  2.0898,  2.2541,  2.4231,  2.5711,  2.6875,  2.8947,
+     0.0871,  0.1968,  0.3425,  0.4949,  0.6424,  0.7959,  0.9534,  1.1132,
+     1.2656,  1.4229,  1.5785,  1.7271,  1.8729,  2.0355,  2.1998,  2.3562,
+     2.5151,  2.6663,  2.8145,  2.9534,  0.1038,  0.2204,  0.3248,  0.4566,
+     0.5947,  0.7443,  0.8811,  1.0379,  1.2031,  1.3772,  1.5430,  1.7092,
+     1.8625,  2.0322,  2.1904,  2.3417,  2.4960,  2.6458,  2.7979,  2.9485,
+     0.1329,  0.2763,  0.3943,  0.5147,  0.6512,  0.8071,  0.9410,  1.0879,
+     1.2298,  1.3850,  1.5282,  1.6674,  1.8137,  1.9993,  2.1344,  2.2749,
+     2.4257,  2.5863,  2.7410,  2.9184,  0.1052,  0.2142,  0.3584,  0.5033,
+     0.6387,  0.7804,  0.9320,  1.0780,  1.2172,  1.3764,  1.5421,  1.6887,
+     1.8246,  1.9833,  2.1245,  2.2797,  2.4237,  2.5779,  2.7257,  2.9097,
+     0.1092,  0.2676,  0.4071,  0.5355,  0.6661,  0.8142,  0.9621,  1.1173,
+     1.2628,  1.4185,  1.5696,  1.7220,  1.8595,  2.0178,  2.1720,  2.3221,
+     2.4718,  2.6259,  2.7775,  2.9334,  0.0929,  0.2017,  0.3073,  0.4570,
+     0.5775,  0.7635,  0.9299,  1.0832,  1.2334,  1.3935,  1.5420,  1.7112,
+     1.8601,  2.0309,  2.1735,  2.3230,  2.4543,  2.6034,  2.7418,  2.8988,
+     0.0775,  0.2005,  0.3490,  0.5200,  0.6747,  0.8383,  0.9885,  1.1738,
+     1.3141,  1.4236,  1.5892,  1.7402,  1.8474,  2.0210,  2.1593,  2.2730,
+     2.4235,  2.5604,  2.7128,  2.9005,  0.1104,  0.2292,  0.3353,  0.4732,
+     0.6152,  0.7675,  0.9164,  1.0907,  1.2594,  1.4064,  1.5218,  1.6426,
+     1.8018,  1.9937,  2.1362,  2.2961,  2.4523,  2.6083,  2.7613,  2.9202,
+     0.0826,  0.2000,  0.3384,  0.5144,  0.6694,  0.8377,  0.9870,  1.1461,
+     1.2950,  1.4495,  1.5872,  1.7387,  1.8793,  2.0329,  2.1723,  2.3114,
+     2.4415,  2.5908,  2.7354,  2.9028,  0.1063,  0.2268,  0.3442,  0.4735,
+     0.6116,  0.7507,  0.9028,  1.0768,  1.2426,  1.4052,  1.5566,  1.7015,
+     1.8243,  1.9742,  2.1276,  2.2824,  2.4262,  2.5953,  2.7627,  2.9290,
+     0.1150,  0.2814,  0.4543,  0.6095,  0.7373,  0.8592,  0.9908,  1.1108,
+     1.2339,  1.3590,  1.4864,  1.6168,  1.7392,  1.8752,  2.0212,  2.1688,
+     2.3128,  2.4869,  2.7019,  2.9239,  0.0948,  0.2074,  0.3433,  0.4943,
+     0.6346,  0.7645,  0.8809,  1.0610,  1.2307,  1.3487,  1.4655,  1.6186,
+     1.7534,  1.8859,  2.0486,  2.2200,  2.3835,  2.5581,  2.7565,  2.9502,
+     0.1062,  0.2239,  0.3683,  0.5197,  0.6704,  0.8184,  0.9642,  1.1127,
+     1.2556,  1.3976,  1.5405,  1.6940,  1.8375,  1.9888,  2.1377,  2.2980,
+     2.4555,  2.6184,  2.7849,  2.9452,  0.0888,  0.2005,  0.2847,  0.4322,
+     0.5763,  0.7577,  0.9262,  1.1095,  1.2719,  1.4331,  1.5843,  1.7452,
+     1.8845,  2.0385,  2.1805,  2.3345,  2.4750,  2.6217,  2.7555,  2.9013,
+     0.1713,  0.2617,  0.3868,  0.5859,  0.7073,  0.8535,  1.0593,  1.1778,
+     1.3109,  1.4508,  1.5910,  1.7463,  1.8911,  2.0651,  2.2035,  2.3355,
+     2.4947,  2.6440,  2.7424,  2.8943,  0.1346,  0.2549,  0.4089,  0.5488,
+     0.6949,  0.8394,  0.9810,  1.1145,  1.2528,  1.4044,  1.5423,  1.6872,
+     1.8274,  1.9726,  2.1403,  2.2809,  2.4128,  2.5564,  2.6887,  2.8895,
+     0.0776,  0.1621,  0.2553,  0.4191,  0.5988,  0.7921,  0.9651,  1.1350,
+     1.2930,  1.4475,  1.6011,  1.7585,  1.9068,  2.0638,  2.2102,  2.3594,
+     2.5096,  2.6581,  2.8099,  2.9654,  0.0864,  0.1778,  0.2854,  0.4235,
+     0.5568,  0.7220,  0.8963,  1.0609,  1.2217,  1.3830,  1.5422,  1.7018,
+     1.8551,  2.0206,  2.1783,  2.3328,  2.4869,  2.6366,  2.7923,  2.9539,
+     0.1144,  0.2576,  0.4186,  0.5594,  0.6875,  0.8221,  0.9598,  1.0944,
+     1.2273,  1.3713,  1.5152,  1.6628,  1.8070,  1.9525,  2.0965,  2.2535,
+     2.4132,  2.5725,  2.7250,  2.9150,  0.1079,  0.2221,  0.3334,  0.4845,
+     0.6083,  0.7516,  0.9018,  1.0594,  1.2060,  1.3673,  1.5212,  1.6880,
+     1.8208,  1.9831,  2.1269,  2.2909,  2.4366,  2.6027,  2.7339,  2.8924,
+     0.0994,  0.2233,  0.3634,  0.5145,  0.6568,  0.8131,  0.9746,  1.1296,
+     1.2666,  1.4116,  1.5748,  1.7264,  1.8649,  2.0217,  2.1716,  2.3293,
+     2.4900,  2.6455,  2.7818,  2.9362,  0.1120,  0.2079,  0.3128,  0.4124,
+     0.5291,  0.6816,  0.8478,  1.0150,  1.1772,  1.3456,  1.5208,  1.6882,
+     1.8458,  2.0078,  2.1627,  2.3198,  2.4733,  2.6251,  2.7796,  2.9489,
+     0.0853,  0.2030,  0.3669,  0.5326,  0.6678,  0.8086,  0.9526,  1.1142,
+     1.2551,  1.4158,  1.5694,  1.7073,  1.8431,  1.9686,  2.1153,  2.2376,
+     2.3686,  2.5591,  2.7320,  2.9104,  0.0905,  0.2166,  0.3539,  0.5201,
+     0.6700,  0.8346,  0.9883,  1.1457,  1.2714,  1.3845,  1.5172,  1.6688,
+     1.8008,  1.9535,  2.1019,  2.2708,  2.4135,  2.5974,  2.7486,  2.9033,
+     0.0084,  0.0374,  0.0164, -0.0153,  0.0288,  0.0107, -0.0255, -0.0242,
+     0.0000, -0.0055, -0.0081, -0.0075, -0.0022, -0.0052, -0.0069, -0.0017,
+     0.0003,  0.0091,  0.0028, -0.0027,  0.0085,  0.0043, -0.0235, -0.0411,
+     0.0202,  0.0359,  0.0376,  0.0321,  0.0306, -0.0358, -0.0276, -0.0090,
+     0.0032,  0.0048,  0.0309,  0.0332,  0.0284,  0.0237,  0.0051, -0.0101,
+    -0.0233, -0.0428, -0.0585, -0.0387,  0.0039,  0.0081,  0.0029, -0.0017,
+    -0.0006, -0.0068,  0.0044,  0.0182,  0.0376,  0.0387, -0.0334, -0.0269,
+    -0.0182, -0.0069, -0.0026,  0.0035, -0.0049, -0.0212, -0.0408, -0.0245,
+     0.0186,  0.0189,  0.0153,  0.0120,  0.0157,  0.0055, -0.0046,  0.0179,
+     0.0284, -0.0032, -0.0261, -0.0205, -0.0039,  0.0174,  0.0299,  0.0207,
+     0.0012, -0.0056,  0.0010,  0.0141, -0.0119,  0.0190,  0.0315,  0.0033,
+    -0.0128,  0.0300,  0.0328,  0.0308,  0.0353,  0.0266,  0.0066, -0.0328,
+    -0.0273,  0.0054,  0.0145,  0.0175,  0.0015, -0.0171,  0.0062, -0.0164,
+     0.0045, -0.0071,  0.0025,  0.0278,  0.0283,  0.0117, -0.0026, -0.0285,
+    -0.0408, -0.0366, -0.0059, -0.0208, -0.0354, -0.0334, -0.0263, -0.0064,
+     0.0072, -0.0006, -0.0235, -0.0037, -0.0307, -0.0294, -0.0163, -0.0197,
+    -0.0235,  0.0192,  0.0013, -0.0219, -0.0123, -0.0004, -0.0081, -0.0096,
+    -0.0123, -0.0101,  0.0021,  0.0151,  0.0106,  0.0151,  0.0292,  0.0033,
+     0.0283,  0.0124,  0.0058, -0.0017, -0.0038,  0.0152,  0.0141,  0.0132,
+     0.0178,  0.0157,  0.0073,  0.0176,  0.0141,  0.0097, -0.0092, -0.0163,
+    -0.0230, -0.0134, -0.0099, -0.0147,  0.0040, -0.0183, -0.0175, -0.0080,
+    -0.0083, -0.0290, -0.0417, -0.0398, -0.0269, -0.0199, -0.0143, -0.0053,
+    -0.0099, -0.0054, -0.0199, -0.0219, -0.0170,  0.0107,  0.0194,  0.0035,
+     0.0437,  0.0406,  0.0215,  0.0120,  0.0053, -0.0028,  0.0238,  0.0337,
+     0.0217,  0.0011,  0.0227,  0.0244,  0.0327,  0.0378,  0.0437,  0.0356,
+    -0.0033,  0.0113,  0.0407,  0.0334, -0.0125, -0.0003, -0.0141, -0.0273,
+    -0.0137, -0.0079, -0.0145, -0.0071,  0.0114,  0.0181,  0.0150,  0.0085,
+    -0.0077, -0.0038, -0.0219, -0.0263, -0.0187, -0.0233,  0.0133,  0.0265,
+    -0.0156, -0.0091, -0.0110, -0.0016,  0.0143,  0.0177,  0.0240,  0.0082,
+    -0.0143, -0.0257, -0.0014,  0.0002,  0.0082,  0.0180,  0.0325,  0.0340,
+    -0.0153, -0.0389, -0.0240,  0.0082,  0.0140,  0.0046, -0.0138, -0.0378,
+    -0.0366,  0.0297,  0.0252,  0.0078,  0.0063,  0.0006,  0.0044,  0.0074,
+     0.0094,  0.0113,  0.0105,  0.0137,  0.0438,  0.0262, -0.0078, -0.0185,
+    -0.0215, -0.0407, -0.0435, -0.0208, -0.0004, -0.0144, -0.0205, -0.0248,
+    -0.0159, -0.0069, -0.0153,  0.0132,  0.0355,  0.0298,  0.0120,  0.0072,
+     0.0236,  0.0526,  0.0479,  0.0233, -0.0133, -0.0283, -0.0468, -0.0549,
+    -0.0370,  0.0032,  0.0056,  0.0023,  0.0050,  0.0024,  0.0279,  0.0116,
+    -0.0045, -0.0012,  0.0107,  0.0190,  0.0253,  0.0191,  0.0043,  0.0193,
+    -0.0348, -0.0246,  0.0123,  0.0210,  0.0135, -0.0096, -0.0109, -0.0076,
+    -0.0156, -0.0290,  0.0160,  0.0194,  0.0219,  0.0259,  0.0250,  0.0195,
+     0.4948,  0.4961,  0.4940,  0.4878,  0.4849,  0.4727,  0.4571,  0.4551,
+     0.4534,  0.4468,  0.4412,  0.4354,  0.4298,  0.4272,  0.4498,  0.4506,
+     0.4560,  0.4592,  0.4758,  0.4941,  0.2476,  0.1771,  0.1974,  0.1881,
+     0.1667,  0.1826,  0.2067,  0.2031,  0.1734,  0.1534,  0.1415,  0.1761,
+     0.1897,  0.1772,  0.1651,  0.1247,  0.1041,  0.1231,  0.1809,  0.2234,
+};
+
+static const int16_t shape8[] = {
+      2765,   1262,   6624,    867,    688,   1884,   3245,   1248,
+     -2160,    593,    182,  -1004,  -1067,    687,   1021,   -920,
+      1396,   -242,  -2817,  -1838,  -3351,   1000,   5995,   2459,
+      -283,   1909,   1452,  -4569,    556,  -2004,    -42,  -3393,
+       -50,   -385,    597,    983,    420,   6311,  -1572,  -1665,
+      6128,  -1688,  -5191,   -337,  -4199,    371,   1032,    -84,
+      2169,    931,   -392,   -250,    137,    831,   8194,   -489,
+       -92,    209,    115,   1453,    246,   -647,    936,   1097,
+      -400,    597,    392,     93,  -7709,   -711,   -724,   2051,
+       497,   1919,   -876,   -769,   -172,   2972,    952,    555,
+       151,   -617,    773,   4840,  -3671,    841,    244,   -661,
+     -3424,    958,     81,    532,   -315,    796,   5491,   -516,
+        -1,  -1371,   -531,  -5538,    313,  -1749,   2413,   -835,
+     -3143,   -244,  -3470,   -850,  -4241,   -859,    -74,   2141,
+     -1005,   4643,   -339,   4089,   -861,  -6612,    483,  -2888,
+      -580,    -45,   3662,    918,   -317,   3596,   -741,    897,
+     -2578,   -654,  -1628,  -1865,    629,   3219,    214,  -1898,
+      1173,  -4509,   1682,  -2161,    697,   -147,   9839,    751,
+     -1094,   -341,   -669,  -1322,    649,   -832,   -382,  -5467,
+       -44,   3510,   1312,   3104,   -202,   1870,   -155,    601,
+       719,    -22,   -350,    394,     81,    397,  -9185,   -174,
+       351,  -4717,  -4450,   3672,   1163,   2351,   1720,   1048,
+     -1221,   -280,    -18,    -15,    678,  -3931,   4707,    -99,
+      1823,   -535,  -1836,    138,   1166,  -3031,   5515,   1362,
+      1235,    455,    595,  -3671,   1102,   -163,     62,   1104,
+       813,    870,   -295,  -1088,   -299,  -3976,    805,  -7468,
+      -412,  -2109,    236,     46,  -5764,    615,  -1475,    853,
+       790,  -6197,    312,    637,  -3923,   -422,  -1086,  -5647,
+       878,  -1410,   2085,    -51,  -2941,   -769,    -63,    838,
+       823,    741,   2785,    450,  -7003,   -121,   -915,     60,
+       -41,      0,    -39,   8774,    647,   -521,    379,   -342,
+      -344,    818,   1316,   1056,    182,   2765,   -467,   7886,
+        45,    791,   -415,   3864,  -2428,   2255,   -661,    -64,
+      1693,    144,   1784,  -1194,    -46,  -1856,   1208,   4131,
+       914,   8028,    -17,   1939,  -1415,    533,    291,   -466,
+       186,   -705,    668,   -614,   -253,  -2190,    287,   3929,
+      1472,  -1561,      5,    889,  -2020,    158,    -14,  -1419,
+      1338,   -353,    622,    -54,     87,  -1104,  -2911,    513,
+      -632,   1533,   -267,     22,   6567,    295,    325,   6883,
+       963,   -373,   -349,    183,    896,   1845,  -1157,    351,
+      -367,   1171,   4362,    508,   5632,    704,  -1420,  -1886,
+       686,   5230,     -9,   2422,    230,    264,   3738,   -270,
+      -344,   -528,   -936,   2286,   -540,   4274,    337,   -665,
+       737,   1639,  -1307,   5827,    592,  -1372,   -412,   1419,
+      4579,    335,    223,  -1067,   -112,   -446,    149,   1375,
+      -155,   -392,  -1980,    561,    -67,    341,   6957,    475,
+     11449,     39,     81,    766,  -1880,    558,   -134,  -7940,
+      -489,    249,   -886,   -358,   6850,   2794,  -2217,   1111,
+     -1222,  -1130,   -818,   1076,  -1823,    865,  -2220,   1179,
+      4492,    224,  -2073,   -338,  -5351,   -390,    133,    496,
+       -42,    -16,     46,    437,    322,   -275,    -72,     48,
+      -325,    313,   1108,  -1044,   -851,  -5030,   1035,   4316,
+     -1281,   -913,  -1419,   -941,   1914,    960,   1242,    202,
+      5109,    475,   1254,   1725,  -1504,     -4,   -269,   -421,
+      -150,  -4409,   -610,  -1548,  -1684,   -817,   -210,     72,
+      -679,   -106,  -3809,  -1137,      4,   7220,    -95,    810,
+      2432,   -331,    492,    -81,    138,    -62,   -613,   -636,
+       106,  10908,    912,    144,    192,   1251,  -3970,   -954,
+      1145,   1175,  -1721,   5326,  -1721,   -569,  -3661,  -1166,
+      6605,   -744,  -1494,    853,    134,   3259,   -504,  -1740,
+       180,   -207,   -659,    196,    179,   -106,    118,    789,
+      -834,  10339,   -420,  -3002,   -456,    113,   6435,    949,
+       721,  -2709,  -1599,   -684,  -8068,    174,  -1416,    -58,
+       974,    308,   -726,   1237,  -1594,    519,   -131,   -198,
+     -1395,   1180,   -173,    338,  -5584,   -279,   -236,   6817,
+        89,   -220,   3967,   -107,     65,   2479,    -22,    642,
+      7179,   1179,   -229,   -202,   4948,  -5465,   1632,  -1285,
+      2188,  -2037,   1763,    636,   4247,    995,   1176,      2,
+     -2398,   1236,   -661,    382,  -1075,    130,    103,   -187,
+       604,   -306,  -2635,  -2185,    157,    775,   6373,   -924,
+      1758,  -3043,   1707,   2852,  -2148,   6779,    376,  -1018,
+     -2374,   -989,    249,  -5393,    -32,    538,   -416,  -5108,
+      -658,   1839,    419,   1153,  -3956,   -617,  -1925,   5434,
+       626,   1488,  -3824,    140,    370,  -2230,  -7031,   1989,
+      -581,    639,  -4249,   -216,   1225,   -776,   -973,   -542,
+     -2922,  -1783,  -2430,  -3251,    958,   3313,    636,  -6277,
+       119,   -866,   -406,   -156,  -4839,    966,   -469,   5559,
+       193,    376,  -4810,   -870,    163,   4130,   2596,   2203,
+      -114,   2423,   -622,   -424,   2935,    749,   2500,   4230,
+      -162,  -1489,   2169,  -5156,    751,   2748,   2240,  -1549,
+      4821,    175,   2274,    854,   2993,    838,    322,  -2663,
+      -794,   -283,    -98,   1393,   -709,    362,    285,  -1085,
+      1075,    374,   1062,   6512,  -3375,  -3138,   3939,   3628,
+      3926,  -2442,   1989,   -583,  -1282,  -1882,  -3920,  -4593,
+       540,   2667,   -155,    156,  -2428,   1229,   -436,   1754,
+      2815,  -1634,  -2299,   1155,    990,   3689,  -1242,   3145,
+      3951,     45,    186,  -1110,    257,   -335,   8929,    533,
+      -173,    813,     21,   1584,    541,    -44,   1349,    108,
+     -5163,   -684,   5522,   -868,  -5795,    769,    583,   2827,
+      -818,  -5551,   1485,     37,   -631,   -262,  -4352,   -532,
+        61,    434,   1775,   8974,   -112,   -852,  -1227,  -1645,
+       260,    298,   -430,    863,  -3860,    -97,   6467,   -328,
+     -2418,    -61,  -1253,   1575,     30,  -5683,   2113,    973,
+      -371,    -51,   5355,    471,   -584,   -492,  -2187,   2799,
+      -506,   4435,   1950,  -3415,   -363,   -404,    941,   2628,
+      -146,    434,   2853,    889,    634,   5749,    -54,    126,
+       189,  -1384,   -379,  -3205,   -540,   1720,    942,  -6300,
+      -286,    -58,  -1083,   3782,    251,   -334,   4172,    631,
+        17,     83,    707,   1322,   3273,   -573,   1024,  -6112,
+      -540,   4916,    155,  -1209,    308,   -738,  -2150,    786,
+      -168,     68,   -201,    -64,   -752,  -1595,  -9188,    320,
+      -426,    111,  -2183,    886,   -737,    193,   -837,   3219,
+      5936,   4022,    764,    -82,   3344,   -855,   3705,  -2652,
+      1533,   -206,  -3673,   1235,   1163,  -1217,   3183,   1313,
+      -745,   6554,   7019,   1302,   2129,    268,    -70,    110,
+       412,   -155,  -1703,  -4945,    105,  -1705,    412,  -6588,
+      2905,   1279,     73,  -2446,  -5635,   1168,   2974,    404,
+      -650,    265,  -1773,  -1857,   -108,   -651,    657,   -824,
+      3352,    177,    155,   1275,   2012,     31,     -7,  -1065,
+      2062,    411,  -2325,   -208,  -6306,    683,   1037,  -1060,
+       191,   -187,   -585,   6103,   -459,    571,   1640,   -693,
+       922,  -2291,    537,   1934,    263,   3847,   -202,   7060,
+       136,   4368,   2963,  -1032,     18,   1836,   -144,  -3853,
+       474,   2005,   1298,   2396,    825,  -2274,     12,   3759,
+      -394,    907,    490,   2997,   2180,  -1570,  -1000,   5982,
+      -129,   -820,  -3001,   2684,  -1132,  -2908,   1101,   5044,
+       393,  -1637,    393,   1343,  -1231,    404,   1817,   1463,
+      -443,   1053,   -584,  -7756,     45,    499,  -4109,    214,
+       535,  -3348,     54,  -1594,   6913,      0,    -94,   8772,
+       500,     13,    734,      5,    798,  -1521,    853,    -82,
+      -263,   -619,   1558,    456,   5911,  -1376,   1054,   -971,
+     -1275,   -147,   -111,   4964,    321,     67,   7024,   -525,
+       620,    883,  -1058,  -1132,  -3313,    630,    226,  -6201,
+     -1011,   1111,   -820,   -295,    580,    636,   2452,   -638,
+      6840,   -285,    655,   1502,  -1049,   -567,    329,    -33,
+      -249,    570,    186,    167,    780,   1104,     42,    197,
+     10034,  -1295,   -208,     32,  -1473,    716,    159,  -6672,
+       -45,    519,  -4300,   -246,   3692,   5062,   4305,   -748,
+      -548,    181,   -382,   -881,  -1968,    580,    964,   -420,
+      -327,  -3397,  -1584,   2770,  -3501,   1659,  -1252,   2352,
+         6,     30,      0,   -273,     27,   -204,   -485,   -432,
+        -6,    176,   -428,   1562,    104,  -6511,  -1084,   2205,
+       -11,  -5254,   -132,   -508,    -69,    373,  -1503,    208,
+       -58,   5311,     92,   -966,  -6563,   -480,    -24,   1424,
+     -1498,   -165,   4594,   -903,  -1787,   -353,  -7284,    142,
+      1008,    875,  -6109,    -16,    162,   4895,     30,   -188,
+      2099,   1581,    300,   -259,   -921,   -386,   -488,    140,
+      -482,   7135,    -77,    494,   -196,   3207,   -250,   -102,
+       318,    978,    161,   7292,     55,  -1347,  -2605,    898,
+      1833,    602,  -1988,    630,   -145,   -102,   -414,   -133,
+       417,   -603,    156,  -1151,   -395,    625,  -1676,     86,
+       680,  13321,    322,  -5816,   -292,   -223,   4205,   -361,
+       903,   -224,   1745,     95,  -6598,     79,   2323,    -24,
+       263,    778,    146,   -939,   1814,   1945,    720,    367,
+     -2987,    899,  -4409,    136,  -3185,   -342,  -3304,   1016,
+       284,   -345,   2313,   -403,    389,  -1403,   1835,    151,
+      -132,  -1702,   -339,  -5679,   2026,  -2990,     47,   -564,
+       399,  -2167,   1392,   1384,   5094,  -2954,   4467,    -22,
+       -23,    408,   1620,   1381,   2380,    805,    380,    -36,
+      -803,    765,   -778,    905,   -200,   -669,   3942,    289,
+       176,  -4767,   2015,  -3554,   1206,   6071,    180,   2057,
+       -48,    365,    -48,  -2423,    585,   -109,  -1298,   2519,
+      -525,   -589,    374,    976,   3667,   2091,  -2890,   1371,
+      -726,   -216,  -1027,   -116,   2122,   -619,  -3826,   4649,
+      1167,      0,   1237,   1538,   2505,   -548,  -3093,   1344,
+      -558,  -1927,    199,   2462,   1327,   4597,    833,  -3660,
+      -341,  -1010,    428,    148,  -1682,    130,   1569,   8785,
+      -752,  -1032,  -2407,    353,   -379,   3311,    892,    893,
+     -2596,   -217,   -835,  -2291,   1137,  -4339,    -58,   2759,
+       991,   3527,   -281,  -6050,  -1251,   1802,      8,  -3916,
+};
+
+static const int16_t shape8s[] = {
+      2639,    550,   6487,   2812,   1014,   1926,   2959,    757,
+     -1452,   -111,    -45,   -409,    401,    545,   1545,  -1677,
+        75,   -607,  -3658,   -368,  -4486,    272,   6017,   -468,
+      1108,   1056,    606,  -3288,   1003,   -830,   -336,  -2940,
+       247,    227,   1700,    338,   -161,   5694,    317,   -584,
+      6278,  -2902,  -3862,    293,  -3400,    540,    177,   -840,
+      -471,    963,   -243,   -289,     77,     39,   7626,    333,
+       577,    327,   -359,    999,   -392,    107,   1410,    509,
+      -983,     36,   -193,    -68,  -7612,   -775,   -178,   1415,
+      1069,   1534,  -1276,   1204,    615,   2065,    499,    124,
+       265,   -454,   1974,   6428,  -4028,   1102,  -1418,    -85,
+      -816,    -64,    -46,    926,   -960,     78,   4823,    -41,
+       -74,   -682,   -761,  -6598,   3084,  -1597,   2945,   -861,
+     -3203,   -669,  -3717,   -310,  -2865,  -1447,     72,   1987,
+       364,   4919,   -247,   3678,   -196,  -6807,   -127,   -965,
+       233,   -133,   4000,    -76,   -182,   3825,     67,    700,
+     -1934,    545,  -2467,  -1441,    629,   3409,    512,  -3333,
+       539,  -4896,   3413,  -2083,    554,    574,   9430,    296,
+       -88,   -533,   -321,  -1082,   2363,     42,    -50,  -5402,
+      -123,   4458,   1130,   2737,    378,   1509,  -3267,    970,
+       179,  -2114,    602,    479,   -438,    277,  -9389,   1144,
+      2453,  -3705,  -3842,   3965,    482,   1230,   2211,   -281,
+     -1833,  -1741,   1653,   -868,    485,  -3740,   5371,    989,
+      1182,     10,  -1812,    233,   1028,  -3300,   4698,   1572,
+      1580,    928,   -314,  -3452,    830,  -1511,  -1079,    554,
+       641,   1383,    105,  -1101,   1549,  -3944,    902,  -6557,
+       493,  -3117,    782,   -699,  -4806,    910,   -259,    -28,
+      1713,  -7012,    570,  -1270,  -4698,     -8,    220,  -4295,
+      1135,  -3905,    945,   -467,  -2164,   -651,    181,    212,
+       159,    587,   1587,   1101,  -7153,   -309,  -1470,  -1135,
+      -265,   -326,    172,   8840,    726,   -780,    170,  -1038,
+       466,    216,    764,    231,   -547,   2456,   -420,   8132,
+       486,    866,   -359,   3351,  -1829,   2018,   -352,  -1353,
+       711,    645,   1149,     74,   -466,   -669,   1009,   3086,
+       240,   7468,   -182,   1947,   -221,    496,   -448,    189,
+      -113,   -752,    133,   -214,  -1310,   -144,  -1034,   5235,
+     -1939,  -2664,    192,   1526,  -2320,    762,   -778,    357,
+      1251,    424,   -225,  -1008,   -229,   -352,  -3559,   -271,
+     -1069,   1274,   -175,    368,   6453,   -505,     31,   7678,
+       165,   -418,   -112,   -649,   1421,    667,   -334,   1041,
+      -353,    585,   4109,   1095,   5283,    685,   -687,  -1459,
+      1054,   5048,   -194,   2220,     81,    244,   3789,     12,
+      -923,  -1459,    319,   2378,    -53,   4097,   -662,  -1156,
+       223,   2589,   -547,   4951,   -346,  -1812,   -111,    344,
+      5247,    387,   -459,   -810,   1022,    234,    726,   1840,
+      -545,   -888,    728,    106,   1027,   -497,    349,   -248,
+     11173,   -311,    126,    479,  -2036,    265,  -1286,  -7196,
+      -511,    128,  -1833,    496,   7620,   2539,  -1809,    962,
+      -614,   -876,    857,   2178,    642,  -1180,  -2294,    911,
+      3932,    711,  -1073,  -1381,  -5317,    237,   -414,    579,
+       -78,    -27,    -78,    -14,    100,   -191,    142,     -1,
+       430,   -182,    207,    -61,    -72,  -4866,    583,   5099,
+      -704,  -1496,   1065,   -206,   2371,   1496,   1777,   -308,
+      4802,  -1415,   1178,   2650,    312,   -338,   -250,    -64,
+       -27,  -3163,   -561,  -1283,    952,   -902,    354,   1597,
+       -74,   -685,  -3266,   -873,   -744,   7079,    732,    697,
+       550,  -1362,    251,     34,   -742,      0,    105,   -608,
+        -1,  10459,    854,   -103,   -419,   2286,  -3041,  -3278,
+       -51,   -491,   -187,   4204,    857,  -1085,  -2501,  -1647,
+      6740,    605,  -2079,   1748,    519,   3462,    106,   -699,
+       220,   -615,   -406,    420,    786,    572,    679,    218,
+      -888,  10283,    129,  -2286,   -705,    -78,   5072,    634,
+       702,  -6315,   -551,   -307,  -7946,    177,  -1897,   -579,
+      1620,    125,    116,    -89,   -308,  -1018,    142,   -506,
+      -624,    917,   -779,    632,  -5103,    314,   -155,   5687,
+        77,   -144,   2957,   -176,     30,   1347,   -426,    -51,
+      7829,   1201,   -592,      1,   4617,  -5476,   2216,    414,
+      1281,    -81,   -423,   -322,   3623,    447,    863,   -375,
+      -489,    526,   -485,    159,   1090,    463,    401,   -131,
+       223,   1630,  -2462,  -2261,    623,   1019,   6385,   -595,
+      -654,  -2787,   2381,    328,  -2069,   5410,   -402,   -554,
+     -1594,   -860,     83,  -5011,   -938,   1061,    163,  -3523,
+     -1064,   1215,    761,   1604,  -4224,    904,  -2706,   4907,
+     -1838,   3287,  -3118,   -464,   -217,  -1187,  -6792,   1748,
+      -569,    613,  -3177,   -253,    164,   -845,    539,   -440,
+     -1871,  -2010,  -2322,  -3026,    478,   2297,   -560,  -5813,
+       768,  -1709,   -620,     66,  -4667,    805,   -215,   5366,
+      -442,   -233,  -6732,    345,    106,   4483,   1720,   2725,
+      -109,   2746,   -188,    204,   1905,   1225,    253,   3270,
+      1912,  -1852,   -256,  -4131,    768,   3984,    473,  -1434,
+      4380,    208,   2547,   1051,   3347,   -171,    629,  -2389,
+      -722,   -759,    166,   2192,    325,   -193,   -289,   -945,
+      -436,    931,   1352,   6918,  -2707,   -987,   2940,   3574,
+      4135,  -3205,    351,    927,    128,  -1873,  -4894,  -4816,
+      -461,    696,  -1618,    129,    -28,   2195,   2450,    585,
+      2557,  -1308,  -2204,   -590,   2345,   3699,   -312,   4436,
+      3422,   -611,   -106,  -2647,  -1752,    -73,   8914,   -673,
+      1625,    850,    720,  -1182,   -245,   -113,    882,   -223,
+     -4873,  -1009,   5643,    -97,  -4779,   -155,    444,   2894,
+      -876,  -5534,   1268,   -132,   -881,   -389,  -4250,   -153,
+       -44,    986,   1820,   8671,    662,   -344,   -198,  -1909,
+      1083,    114,   -318,   1070,  -3293,   -375,   6621,    232,
+     -2973,   -100,   -483,   -529,   -120,  -5312,   1702,    651,
+      -631,    485,   5675,     50,   1132,   -465,  -1053,   2675,
+     -1592,   5565,   1036,  -2808,    325,    999,    524,   2813,
+      -265,    337,   4226,    514,    576,   6047,    175,    204,
+      -514,   -617,    -94,  -2862,   -294,   1774,    978,  -7040,
+      -169,    835,   -829,   2258,    -37,   -319,   2750,    138,
+      -289,  -1092,     78,   1032,   4316,  -1201,    808,  -6243,
+      -940,   4136,     89,  -1076,   -647,   -255,   -207,    227,
+       -70,    -62,   -202,     66,     24,   -988,  -9542,   -225,
+      -739,    161,  -2698,    117,   -608,    173,   -629,   1770,
+      5037,   5145,   2530,  -1028,   3077,   -496,   4671,  -1859,
+      2148,    447,  -4231,    170,    713,    323,    746,   1447,
+     -1880,   5069,   7765,   -492,   -775,   -659,   -770,    -59,
+      -258,    -92,  -1683,  -4639,  -1727,  -2128,    545,  -5060,
+      2536,   1549,    492,  -1280,  -6034,    965,   3244,    475,
+     -1208,    680,   -283,    295,   -357,   -257,   1753,   -362,
+      3159,    106,   -181,   1805,    947,  -1002,   -136,    756,
+      1189,    237,  -2427,   -263,  -5746,     13,   2171,  -1197,
+      -319,   -372,  -1300,   5458,    955,   1224,    618,  -1087,
+      2661,  -2026,    -20,   2137,    342,   4076,    482,   5441,
+        -6,   2126,   -143,  -1596,    274,   1009,     94,  -3446,
+       398,   1079,    289,   2042,    883,  -2005,   -320,   3848,
+       395,    472,    615,   3245,    753,  -1881,   -216,   5670,
+       -64,   -565,  -2560,   1574,    772,  -3824,    932,   4830,
+      1182,  -1054,    390,    -40,   1833,   -350,    151,    149,
+      -966,    -62,   -713,  -8794,   -593,     87,  -3523,   -243,
+       560,  -3296,    244,   -775,   7174,    749,   -271,   8566,
+        99,   1258,   1239,   -489,   -107,  -1699,   -611,   1046,
+        65,   -509,    524,   -354,   6400,   -248,    148,   -682,
+       -93,  -1584,    -61,   4509,    479,    110,   7116,   -295,
+       480,   1545,      3,    127,  -2292,    894,   1261,  -6288,
+       -45,   -410,   -402,   -356,   2649,    649,   1652,   -643,
+      6587,    117,    876,    -33,    956,   -302,   1619,  -1023,
+       -99,    386,    -86,   -498,    684,   1189,    146,    381,
+      9832,    -97,    264,     91,  -1197,    461,    374,  -6788,
+       427,    294,  -4776,      0,   2868,   5199,   4573,   -827,
+     -1867,    623,  -1214,   -573,  -1099,  -1476,    306,   -701,
+      -224,  -4261,  -1135,   2500,  -4758,   1469,   -101,   1812,
+      -129,     15,    760,   -149,   -892,  -1417,    761,   1213,
+      -417,   1569,    -98,   1675,   -139,  -7382,   -633,   2584,
+      -519,  -5483,     29,    320,   -383,   -596,   -295,   -357,
+      -416,   4054,   -457,   -355,  -5213,   -840,   -319,   1321,
+      -424,   -129,   5225,    181,  -2696,   -174,  -7363,   -327,
+       519,    860,  -5132,    275,   -141,   4943,    204,   -200,
+      2989,    939,    390,   -461,   -333,   -394,   -174,    312,
+      -129,   7257,   -402,    860,     -1,   2677,    901,    609,
+       248,    935,   -493,   8147,   2081,  -1171,  -2145,   1560,
+      1634,     55,  -1746,    561,   -747,    931,   -712,   -544,
+       798,    -98,    580,   -829,   -546,    238,  -2052,   -197,
+       802,  13067,    373,  -6438,   1159,   -845,   4313,     19,
+       670,   -627,   -944,   1277,  -6997,   -609,   1913,    607,
+      -454,    -89,    859,    -43,    -71,    494,    169,   -713,
+     -2014,   1570,  -4712,    233,  -4113,    210,  -3689,   1019,
+       200,     49,   1800,   -611,   -472,   1234,    579,    363,
+      -134,    233,    101,  -5539,   1924,  -1734,   -982,   -928,
+      -707,  -1238,   1586,   3676,   4741,  -2770,   3105,    942,
+     -1933,   1363,    288,  -2528,    160,    485,    -38,     23,
+       113,    -19,   -518,   -110,   -173,   -170,    589,   -473,
+       296,  -3742,   1109,  -2977,   1349,   5899,     98,   3130,
+       855,    499,      3,  -3111,   -592,    572,   -890,    687,
+       697,    194,   -344,   1139,   3255,   1270,  -2451,   1958,
+      -395,    267,   -951,  -2224,   2108,    -11,  -3357,   2602,
+      2403,   1596,   -532,   2701,   2251,  -1217,  -2148,    691,
+      -757,  -2051,    373,   1964,   1493,   4756,   1246,  -4345,
+      -496,  -1333,    -20,    -84,  -1558,    305,   1183,   8148,
+      -628,   -702,  -1730,    232,   -261,   2732,    245,    353,
+     -3745,   1013,    186,  -2042,    810,  -3894,    351,   2501,
+       852,   4162,   -425,  -4941,  -1536,   2237,   1348,  -4274,
+};
+
+static const int16_t shape11[] = {
+       347,  -5391,    106,    156,   -182,    -36,    177,    401,
+       700,    524,  -1343,   -402,  -6982,     63,    194,    -14,
+        82,    -36,   -677,   -393,    187,   7364,   -507,  -1173,
+      -759,  -3759,   -728,   2970,   1334,     32,  -1322,  -2965,
+       156,   -839,    382,  -6382,   -149,    874,   1352,    -35,
+      -499,     99,   -425,  -3118,    -32,  -1596,   5608,   -822,
+       -41,   2974,   -592,    615,   1777,   2364,   5189,  -4171,
+      -581,    936,   -527,    318,  -1606,   -551,   5350,   -448,
+       -40,   7476,    189,    319,  -1390,     10,   -921,  10016,
+       573,  -1065,    829,  -1190,    -22,  -4263,     87,  -1742,
+      -325,    313,   -188,    540,  -5542,   -188,    511,   -168,
+      -518,     17,    152,   1966,  -2568,   -860,   2735,  -1210,
+       404,   -144,  -6873,   -129,    434,  -2978,   2829,    -48,
+     -9196,  -1829, -11261,   1492,  -4938,   1802,     93,    384,
+      1340,    236,  10066,    731,    861,   -195,  -7571,    -77,
+      -481,   -700,   4694,   -734,  -6317,    281,   1773,    175,
+     -5535,    532,     31,   7012,   -637,  -3586,   1096,   3596,
+      -197,  -7837,   -611,   1825,    -26,   -259,   2307,     12,
+       729,  -1958,    156,    262,   5494,     26,  -5792,  -3146,
+       450,  -1075,    297,    509,    154,    668,    191,   -268,
+     -1585,    369,   1314,   -693,    677,   1482,    198,    378,
+     11088,    -83,   2321,   -193,  -1082,  -3053,     20,   -271,
+     12975,    272,   1114,    476,   -798,   -309,   -159,   5406,
+      -109,   -675,    621,  -2564,  11190,  -1342,    -88,    428,
+      -465,  -4633,   -503,    106,  -9448,   -454,    -28,   -402,
+      1271,  -7972,    754,   -207,  -2491,    518,  -3701,   -542,
+     -1268,   -617,   -177,    467,   -130,    990,   4087,    857,
+      -524,  -5822,    145,    217,  -7703,   -275,   6647,    -81,
+       550,    887,   -433,   -802,    532,    643,    188,   1965,
+      -920,   -284,   3711,   1196,  -8896,   -357,   -626,    908,
+      -284,   -706,  -1582,    182,   7705,   -138,  -2372,   -158,
+      -888,   4247,   4381,  -6722,  -1619,  -1810,    632,  -1176,
+       -62,   4261,    -89,    265,   1405,  -1449,   -389,  -7068,
+       258,   -244,   -272,  -8149,     37,   -457,  -8839,   3243,
+     -4291,   -396,  -3935,    907,    -58,   2388,   -908,  -1209,
+      -635,   -487,  -1717,   6989,  -4834,   2136,   -822,   -699,
+      2187,    -96,  -9775,  -3464,    795,    634,   -823,   -669,
+       146,   -843,     15,   -227,    671,   -707, -10004,    198,
+        81,  -1611,    -34,  -2127,  -2385,   -689,    622,   1834,
+       -63,  -4925,   -215,  -1181,   -514,   7701,    607,   2030,
+      -264,   2479,    913,    178,   3625,   -194,    613,    877,
+      -384,  -7732,   1008,   2117,    528,   -301,    540,    -80,
+       559,     28,   7542,   -496,   1146,  -6573,  -1457,   7789,
+      -227,  -1671,    -76,   -371,   -865,   -141,     42,     96,
+       277,   -410,  -5606,    328,  -8954,   -222,  -1792,    981,
+      -120,   -650,   2269,  -1412,   1038,   -186,  -8530,   -264,
+      2284,   -727,   1511,  -4611,  -1653,   1985,    -50,  -8985,
+      -245,  -3315,    407,   -915,    -23,    -70,     30,   -669,
+      -303,    902,     84,    433,    217,  -8303,   7847,  -1865,
+      -680,    254,    -38,    364,     16,     50,     90,   -534,
+     -4649,   -800,    969,  -1081,    454,    147,    -62,   8797,
+        84,   -912,   -518,   -351,     76,   -560,  -1438,    629,
+     16384,    656,    151,    880,    396,    -90,    752,   -138,
+      -861,   9605,    258,   -440,  -6441,    434,   5765,    282,
+      1494,   -260,   -180,   -769,   7867,    -86,    536,   -262,
+      -230,  -8956,   5857,   -591,   1533,    418,   -505,   -156,
+      1165,    415,   -168,  -1504,   -336,   -667,    527,   5725,
+        42,    429,   1691,      1,     85,   -196,   3681,     36,
+       469,   -364,    559,    910,  -1848,    259,    249,  -1688,
+       261,    -36,   -592,   -156,    -69,  -5938,   -180,   -294,
+        22,   -903,   1389,   4853,    121,   5185,    970,   1210,
+       561,    926,    472,   -183,   6623,    357,    -78,  -5877,
+        91,   -188,  -6746,   -146,    342,  -5648,   3697,   1336,
+       728,    -69,    398,   2667,  -2103,   1901,   -807,    258,
+        72,   -137,    341,     71,   -169,   -104,    -83,    206,
+      -420,   1187,    744,    120,  -5151,   -574,     72,  -8553,
+      -312,    140,    -69,   6067,   5229,    202,  -1722,   -164,
+        73,   1695,  -1064,    234,     24,   4881,   -849,   -460,
+      8641,   -328,  -1217,   1666,   -283,    -76,   2772,    401,
+       843,  -4756,    297,   8593,    367,   -732,   -225,   -198,
+     -3936,    248,   -436,    473,    -19,   -441,    164,    220,
+      -266,      3,    106,   -244,  -5814,    597,   -666,   -245,
+     -9298,   -867,   -480,    280,    -40,   -139,  -6378,  -4972,
+      -886,   3062,    747,  -1991,  -1668,   -423,    534,    866,
+       -73,  -6501,   -195,    324,    -51,   -123,    298,    500,
+       193,    278,  -8503,   -297,   1034,    -16,   -209,   7451,
+       521,   -305,   -297,  -1537,  -3025,    689,    248,    319,
+      5393,   1497,   2228,   -773,   -141,   2184,   1024,  -4535,
+     -9160,   -600,   -932,  -2145,   -539,    460,  -1943,   4265,
+     -2512,   4416,   -304,   1744,    489,   -362,    898,   2236,
+     -2224,     49,   -192,    332,    366,   -143,    329,  -7747,
+        -4,   1075,    116,    551,     19,     -7,   7090,   -169,
+       837,    -71,   -371,    451,    -31,    474,    867,   -421,
+     -4544,     78,   3208,   -549,   1984,   1386,  -2208,  -1402,
+      1616,    189,    -37,  -6953,  -5733,   1589,  -1314,   1040,
+     -1480,  -5608,   2627,   3517,    250,   7930,     94,   4687,
+      1522,   5543,   -130,   -462,   7613,   -654,    647,  -6187,
+       139,    342,   5069,   -729,    128,     17,    -49,    176,
+       122,    826,    503,     76,   -196,  15583,  12884,    746,
+     -3942,    814,  -1744,   1774,   -338,   3089,  -1694,    559,
+     -5355,   2834,  -1448,    108,   -329,   -711,    350,    171,
+       297,   -123,    672,    625,  -5884,   6822,    842,    276,
+       242,  -2254,   -623,   -846,   2441,    887,  -2066,  -1019,
+      1329,    107,    -83,    826,    -67,   -352,    549,    137,
+     -1023,   -184,    -11,  13790,     48,    883,   3538,   -533,
+     -5553,    861,    738,   -436,  -5259,    -66,   -405,   3777,
+      -574,    738,    253,    363,    -76,    288,    324,   -337,
+       157,   -119,    -97,    171,    514,  -1932,  -5171,    579,
+       249,   1072,   -204,   -194,   -311,    655,  -6728,    186,
+      -178,     99,   5749,   -329,    419,    924,  -1131,    598,
+       -15,   -103,  -2277,    186,   -716,   -542,    153,   -226,
+      5689,    219,     52,   3706,   -917,    140, -10576,   -151,
+      1060,    645,    404,   1310,    331,    216,  -1413,  -6030,
+     -5069,  -3992,   1366,    932,   1559,    -87,   7799,   3854,
+      3762,  -1043,    474,   1184,    102,  -2775,  -1199,  -1079,
+       358,    -63,   9784,    141,   3947,    194,   -132,   -332,
+      -512,   -212,  -5839,   -227,   7759,    807,   -597,  -1782,
+      -148,   -352,  -1225,   -692,    147,  -1970,   3508,   -947,
+      3463,   -197,   4737,   -698,    578,   -172,   -775,   8167,
+      3102,    883,   -914,     16,    827,    114,  -1916,   -909,
+      -606,     87,   1036,   -435,    102,     96,   -370,   -204,
+    -11952,     21,    477,   1285,   6281,    855,  -7717,   1155,
+      -501,   -597,   5943,    145,   -630,  -3406,     13,  -4211,
+       679,   6570,   -231,  -6042,   -503,   -194,   1437,   5640,
+     -1222,   8181,    386,   -986,   -503,   1221,    839,    763,
+      -277,  -1787,  -1491,      5,   -206,     42,   2800,   -332,
+     -2841,   -143,   -456,    646,   -668,   -117,    883,     86,
+      7111,   -270,    624,  -1133,   -308,   -479,  -9149,  -1424,
+       242, -12048,      8,   2307,  -6530,   -529,    462,  -1346,
+      -153,   4315,   -182,   -675,    -78,   -480,    -49,    398,
+      -408,  -1440,   8196,    436,   -561,   -184,    175,   1799,
+      -154,   -439,   -721,   2170,    322,   6555,   -539,  -1672,
+      -629,  -2985,    239,    -37,   7544,  -1048,  -1241,   7241,
+      -636,   2044,   -750,   1206,   1363,   -530,  -5960,    342,
+     -7440,    616,    372,   4572,   -118,    343,   1086,    570,
+      -164,    553,   -433,    562,     33,   8225,   -235,   -234,
+      1230,    234,    906,    563,    -73,  10464,   -353,   -644,
+     -1453,   1119,    237,    670,   -112,   7083,   -451,   3410,
+      -105,   3244,  -1331,    102,    738,  -3602,     76,    413,
+      -318,     10,  -5471,   1024,   -335,    246,  -7820,   -164,
+      2515,  -1411,    673,   6022,     50,  -6715,    268,   2152,
+      -951,    -60,    234,  -2085,    342,   3002,   -169,   2473,
+      -667,  -6846,    870,   5467,    150,    -66,  -4294,   -299,
+      -612,  -3859,    177,    353,  -4726,    547,    340,  -5646,
+     -2022,    117,  -4949,   -303,    280,   -266,   -361,    673,
+      -139,     -5,  -7123,   -264,    243,  -5245,    351,    656,
+      5005,    682,   -107,    298,    -79,   1407,   -449,   -797,
+      -669,   -552,   -242,  -8013,     56,   4092,   1583,  -3981,
+       -49,  -7972,    390,    366,    -31,   1126,    272,   5120,
+       -10,   1147,  -3682,   -155,    252,    163,    455,    358,
+      -746,  -2719,   -431,    444,   -433,    432,   -357,   5370,
+       328,     -3,   1748,    514,   7198,   -527,    172,    401,
+       -59,  -3586,   1443,    534,   1029,    539,   3723,   5392,
+     -6619,  -2559,   2344,    282,   -980,     97,   -317,   -786,
+       475,  -8646,    307,    447,  -3107,    211,    -56,   3344,
+     -1549,  -9223,    454,    352,    -27,    205,    503,    260,
+      -372,   -631,  -1165,  -6543,    444,   1535,    404,  -1752,
+       -43,  -9381,    754,    -94,  -7134,   2064,    170,   8222,
+      -280,  -1250,   -347,   1688,  -1203,    239,  -1048,  -4570,
+     -4720,   -434,  -1008,  -4151,  -2211,  -1414,   -506,  -5411,
+      5379,    984,   4587,    -63,    143,    968,   -203,   5315,
+       591,   -756,   1228,   -372,    703,   6829,    -76,   6935,
+       467,   3119,     -2,  -3825,    175,  -4000,  -3012,  -7745,
+      -832,  -2582,    173,   1992,   3768,    275,     39,    603,
+      -536,   5851,    474,    254,    -72,   1286,   -836,   5576,
+      1357,   3524,    406,  -9214,   -554,   3974,   -352,   1763,
+      -482,    658,   1628,   3885,   1938,   6172,   1693,  -5183,
+       150,  -6729,   1238,   1062, -10035,   -428,     48,    421,
+      -185,    659,   -426,   -633,    131,   -741,    462,   -463,
+      -391,   -193,   -270,   -682,   -343, -12130,    -86,   -148,
+};
+
+static const int16_t shape11s[] = {
+        22,  -5296,   -415,   -206,    306,    265,    189,    376,
+       721,  -1503,   -429,   -538,  -6008,    -97,   -385,   -570,
+      -313,  -1469,   -219,  -1661,     10,   6256,  -1230,   -635,
+       -28,  -4208,   -344,    394,    138,   1174,   -170,   -822,
+       114,  -1087,   -101,  -7362,     84,    862,   1514,    341,
+      -115,    320,   -120,  -1625,     55,   -719,   1443,   -733,
+      -577,   7197,    148,     26,    120,   1969,   4940,  -3777,
+      -607,   1675,     64,   -634,    -84,    334,   6882,   -644,
+      -232,   5008,   -316,   -164,   -138,    -16,     15,   9441,
+       -74,    -65,    262,    834,   1143,   -101,    434,   -329,
+       123,   -204,    -45,    147,  -4586,   -742,    464,   1412,
+       548,  -1602,    -56,   1356,   -771,    263,    709,   -481,
+      -193,    345,  -8395,    -41,     36,  -1900,   -178,    816,
+     -7590,     31,  -3011,   -371,  -2698,   2234,    -99,      0,
+       714,   -845,   9357,    701,  -1269,   -187,  -4227,   -450,
+       -73,  -1637,   4679,   -138,  -4470,    356,   1416,   1462,
+     -3162,    453,    -61,   5243,   -241,  -2385,    438,   4919,
+      -252,  -3781,    150,    335,     58,   -185,   1870,    179,
+       192,  -2572,   -454,     77,   4819,   1891,  -4843,  -2106,
+      -472,  -3842,    167,   1092,   -671,    194,   -870,    139,
+      -115,   -455,    452,   -519,    299,   1024,    330,    -99,
+     11189,     82,     57,   -849,    167,  -4190,    639,    768,
+      7477,    626,     94,  -1259,   -303,    181,   -280,   2873,
+      -589,   -461,   1591,    -29,   6940,  -1264,    120,   -282,
+      -159,  -3755,     -4,    -61, -10172,    152,    -12,   -200,
+       111,  -8471,   -243,    400,   -842,   1661,  -3099,    500,
+      -451,   -423,   -193,    230,    423,    263,   5011,   1010,
+      1044,  -4781,    707,     84,  -6091,   -213,   5193,    434,
+       534,   1100,   -520,  -1590,     75,   -322,      2,   2008,
+      -534,    153,   2641,   1510,  -6830,   -246,      4,    271,
+        75,  -1308,  -1934,   -257,   6748,    589,   -301,    627,
+      1197,   3708,   4450,  -5582,  -1312,  -2859,    881,    429,
+       552,    738,   -882,    984,    488,   -868,   -464,  -6969,
+       721,  -2078,    417,  -6121,   -184,   -128,  -7840,   2659,
+     -2584,   -254,    176,   -790,   -727,    482,    357,    104,
+      -441,   -158,   -980,   4563,  -4098,   1086,  -1217,   -562,
+      2033,    512,  -8331,  -3506,    -73,    808,   -372,  -1602,
+       748,    911,   -599,  -1499,     58,    309, -10000,   -115,
+        70,   1603,    280,   -146,   -817,    517,     18,   1355,
+      -121,  -4134,    152,  -1300,    247,   7258,    415,    130,
+       -27,   2108,    337,   -816,   2480,    396,    533,     66,
+      -171,  -6213,     47,   3081,   -648,   -930,   1810,   -233,
+      -433,   -588,   5526,     58,    -18,  -3498,   -381,   8009,
+         7,   1229,    152,   -410,   -567,    423,   -354,    463,
+       -82,   -146,  -2868,    271,  -5773,   2694,  -1006,    150,
+      -113,   -521,   2553,   -278,    593,    -69,  -6517,   -785,
+       369,  -2483,   -216,  -3144,   -889,   1724,   -168,  -6303,
+       171,  -1895,   -798,   -137,   -172,   -746,    -54,    162,
+      -607,    409,    201,   -284,   -143, -10681,   7747,  -1148,
+       303,     58,      4,    -96,   -485,   -146,   -286,   -577,
+      -644,   -512,    236,    576,    421,     93,    293,  10284,
+        -2,   -117,   -590,   -546,    350,    445,   -301,   -300,
+     10823,   -224,    -96,   -551,   -148,   1042,   -125,    224,
+      -706,   8583,   -195,     52,  -2732,    200,   4419,    390,
+       870,    100,   -184,    233,   6179,   -317,   -472,   1964,
+      -302,  -8722,   2509,   -644,    488,  -3101,    891,   -253,
+       -38,    133,    -15,  -1365,   -779,   -612,    673,   5587,
+       834,    377,    835,  -2018,     75,   -185,   3641,    121,
+       693,     63,    503,    646,     -7,    348,    141,  -1311,
+       532,   -513,     95,   -315,    -65,  -6478,    -16,   -848,
+      -210,   -120,    676,   5125,    533,   4147,   -622,     -4,
+      -150,  -1507,   -124,   -185,   5365,    267,   1073,  -4479,
+       173,   -204,  -4164,   -952,    -23,  -4088,   1391,    205,
+       712,   -473,   -373,    547,   -685,   4542,    -49,    -71,
+        33,   -271,    132,    246,   -188,      6,   -309,    118,
+        96,   1774,    158,    -83,  -3573,   1175,   -122,  -6619,
+     -1677,  -1161,   -266,   4776,   3453,     62,   -346,   -450,
+     -1380,    103,   -457,  -1260,    -71,   4271,   -338,  -1394,
+      6462,    395,    647,   2430,   -735,    444,   1837,    403,
+       144,  -5573,    211,   4608,    -15,    804,     70,   1969,
+     -3451,   -138,   -352,   1176,   -171,   -518,   -114,    -88,
+       335,   -308,    -64,   -428,  -4115,    318,   -205,   -126,
+     -7854,   -609,    105,    144,    270,    266,  -4543,  -5246,
+      -311,    587,    305,   -115,    372,    727,   -294,    414,
+       877,  -7899,    411,   -538,    394,    535,    233,   -826,
+       329,    491,  -4848,   -650,    331,   1026,   -140,   6474,
+       194,   -457,     98,   -871,  -2293,    873,    353,    812,
+      4510,   1102,    379,    651,   -214,   -110,     20,  -2749,
+     -8040,    -96,    221,    221,    -39,    444,   -280,   2814,
+      -536,   3509,    111,    830,    594,    553,     47,   2812,
+     -1898,    203,   -353,    -60,    371,    181,    824,  -5448,
+       297,    476,     42,   -133,     97,    425,   8586,   -317,
+       121,    453,   1014,   -350,    175,    747,    -78,   -287,
+     -5832,    625,   4170,   -308,   1853,   2846,     -3,   -876,
+       535,    431,   -411,  -2139,  -6021,    374,    298,   1572,
+        19,  -4069,   1567,    144,      3,   5541,   -438,    920,
+        87,   1728,    230,    807,   5848,   -413,      7,  -6241,
+       214,    205,   1312,   -675,     70,    264,    114,    -24,
+      -482,    -72,   -296,    327,    249,  11047,  11070,     18,
+      -937,    350,     22,    362,    555,    815,    130,   -125,
+     -4545,   2662,    203,   -318,   -305,    323,    633,    416,
+      -254,    301,     99,    407,  -4951,   4766,   -790,   1334,
+       912,  -1046,   -350,   -135,   3744,     22,  -1647,   -422,
+      -151,   -113,   -130,   -345,     -2,   -263,     18,    -24,
+      -771,    -34,   -543,  10259,    183,      0,   1743,   1267,
+     -2554,    320,    611,  -1064,  -1446,    875,   -808,   4865,
+      -816,   3452,     68,    326,   -178,    177,    -10,   -138,
+       -33,    -93,     65,    264,    185,   -157,  -5749,    110,
+       407,   1240,   -698,    -61,    176,   1557,  -6012,   -606,
+      -555,    458,   3226,   -939,    933,    153,    -32,    928,
+        69,   -490,  -1543,    -87,    -20,   -196,   -327,    423,
+      7911,   -189,    178,    335,   -194,    459, -10572,   -196,
+       174,   -286,    502,  -1041,     12,     39,   -101,  -3983,
+     -1650,  -2902,    386,   -151,   1051,   -619,   6854,   3408,
+      1140,  -1854,   -755,    -40,  -1108,  -1502,    221,   -397,
+       375,   1081,  10375,    389,    270,   -239,    311,   -212,
+       384,   1237,  -2951,    199,   5281,    -56,     34,   -704,
+       942,   1169,     33,   -310,     97,  -1216,   3023,   -836,
+      3256,    404,   3951,   -257,   2139,    111,    179,   8255,
+       611,   -240,   -252,   -367,   -251,   -296,  -2282,    957,
+        61,   -265,    720,    232,     34,    146,    204,   -290,
+     -9923,    529,     65,    696,   2958,    352,  -3852,   1248,
+      -743,   -395,   5969,     92,   -132,  -1206,    314,  -4013,
+       717,   5157,   -770,  -1878,  -1201,   -958,    525,   4028,
+       116,   6772,    -45,  -1086,   -335,   5815,     51,     57,
+       -85,  -2301,   -133,   -300,      7,    227,   3429,  -1075,
+     -4353,   -832,     30,   1259,   -484,    451,    604,   -717,
+      6765,    294,    118,   -410,    299,    592,  -3845,     66,
+      -502,  -9088,    -74,    259,    450,    475,    202,  -1792,
+        23,   4719,    709,   -398,  -1676,   -351,   -898,   -622,
+       145,  -1392,   7305,   1014,    -80,    519,  -2065,   1531,
+       860,  -1448,    134,   1683,    689,   7179,   -345,   -327,
+      1004,  -2467,   -340,  -1302,   5825,    373,     50,   6796,
+       314,     13,   -270,   -426,    702,    279,  -4392,   -508,
+     -6521,     60,   -278,   2479,    847,   -360,    -68,  -1948,
+        91,    969,    421,    459,   -341,   6020,   -550,    -77,
+      -687,   -754,      5,    109,    410,  10860,   -183,   -317,
+      -734,    -87,    501,   -601,    158,   5836,  -1057,   1236,
+      -850,   2965,   -330,    547,   1249,  -2804,    127,    218,
+      -455,   -805,  -4002,    108,   -569,    660,  -5356,  -1091,
+       581,   -445,   -311,   6409,    510,  -6789,    519,   1607,
+       296,    342,    368,  -1440,   -846,   1997,   -227,   2332,
+     -2062,  -4657,   1030,   5322,    135,    131,  -3414,    320,
+      1030,  -3341,   -256,   -373,  -4565,   1222,    171,  -4972,
+     -1444,    303,  -5427,    435,    208,    251,    467,    539,
+       136,    199,  -8876,   -195,   -771,  -3096,    740,    368,
+      1047,   -490,     83,    485,    168,    531,   -635,   -801,
+      -953,      4,    -95,  -7603,    -59,   2023,    739,   -702,
+       263,  -9230,   -313,   -997,   -510,   -772,    156,   3986,
+      -113,    398,  -2602,  -1079,    195,   -211,    128,   1917,
+       221,   -965,     11,     71,   -101,    180,    -36,   7839,
+      -144,   -722,    288,    429,   5704,   -984,   -510,    775,
+       440,  -1849,  -1348,   1989,    300,     43,   1928,   4341,
+     -3840,  -2427,   2025,   -660,   -293,     23,   -249,   -177,
+      -327,  -7858,     33,    245,  -1334,    237,   -687,   2800,
+        30,  -8807,   -404,     43,    183,    289,    528,    510,
+      -197,    590,    -94,  -5423,    381,   1317,    141,  -1639,
+      -432,  -7628,   -224,     56,  -7788,    113,    134,   6981,
+      -636,    756,   -743,     97,    159,   1263,   -143,  -2941,
+     -2680,   -479,   1395,  -1667,   -472,   -992,   -451,  -5708,
+      4262,    334,   3053,     76,   -584,   -599,   -276,   3518,
+       264,  -2118,    358,   -106,    911,   5053,    480,   4538,
+       949,   5203,   -103,    -14,    177,  -3397,     55,  -6813,
+       680,  -1788,    145,   2267,   1104,   -789,     54,    261,
+       228,   5494,     15,   -224,    192,    740,      0,   7632,
+       398,   2879,    430,  -8212,   -657,    815,   -228,   -488,
+       -90,  -1296,    595,   2979,    -15,   4055,   -252,  -3883,
+      -935,  -7654,    330,     97, -10200,    462,    223,  -1017,
+      -309,   -342,   -124,  -1258,    211,    351,    316,    414,
+       -91,    -18,   -202,    -74,    410, -11127,    326,    261,
+};
+
+static const int16_t shape16[] = {
+      -855,   1549,  -4841,    629,    932,  -5896,    840,  -2041,
+      -305,  -2574,    343,    -31,   -780,   -773,   -353,    403,
+     -1907,  -2371,   -555,   -324,   -479,   6961,   -286,  -4290,
+       626,   -953,    -14,  -1681,   -443,   1504,   -366,    513,
+     -1206,    870,   9239,    112,   -213,    425,    381,   1802,
+       750,    594,     61,   -152,  -2060,  -8997,   -752,    197,
+      -493,   -176,   -389,   -591,   2988,    654,   2404,   -204,
+       304,   -279,    202,     66,   -185,    415,    159,  -1514,
+     -6775,    -37,  -2617,  -1246,  -4012,   1208,   -554,   3240,
+      -655,   -394,  -1464,  -4448,    388,   1058,   -364,  -1760,
+      1081,   -558,   -116,   -108,     99,   -925,    763,  -1301,
+      -251,    258,    -33,    311,    555,    227,   -279,   -601,
+      -135,   -675, -10615,   -937,    158,    503,  -2044,   1075,
+      -114,   4278,  -9040,     67,  -1076,   -705,   -122,   -533,
+      3299,  -1826,  -1316,    708,  -3840,   -740,   -370,  -1074,
+        87,   -462,   2177,  -1177,     57,  -6311,   -170,   -777,
+      -256,    435,    291,  10371,    -82,   -425,  -1757,   -196,
+      3824,  -6289,     62,   4506,   -519,   -783,   1155,    878,
+       295,  -2044,    305,    186,    263,  -1716,   -482,  -5678,
+       415,   2709,    213,   7531,   1376,    813,   1803,    190,
+       398,   6483,   1425,    235,   2713,    520,  -2892,  -1191,
+      6074,    654,  -6535,    320,   -736,   -478,   2563,   -309,
+     -3477,   -155,    275,   1024,    390,   -386,   -331,  14043,
+       251,   -410,   1496,     24,   1272,   -816,    549,   -238,
+     -2489,    158,    194,      1,   -306,  -3088,   -264,    200,
+       -30,   -520,   -472,    -30,   -464,   -764,    440,   -659,
+        88,    778,    -31,  -1794,  -3817,   -344,    887,   -551,
+       115,   -763,  -5338,   2906,     50,    736,   5536,  -1101,
+       330,   -405,    416,   1022,    -93,     71,  10034,   -200,
+     -1258,  -3405,    480,    141,    399,    500,    311,   -503,
+       301,   4398,    454,   -922,    975,   -101,   -775,    -81,
+     -1723,   1077,    857,  -1682,    813,    847,    342,   -276,
+      3582,   2991,   5571,    713,   1280,    596,  -1325,  -1087,
+      -681,   1411,    391,  -1728,    492,    544,   1512,   -724,
+     -7445,   -426,      6,   -534,  -3643,  -1598,   2650,   -834,
+      2096,   -333,     67,   1746,  -1584,  -1003,   1272,   1710,
+      1666,    176, -11716,    329,  -1829,    385,    802,   -382,
+      2244,     -8,   -222,  -2351,    369,  -1067,  -9354,    293,
+       -51,  -1849,   -500,  -2350,  -1824,   -826,   -450,  -2155,
+       456,    245,   1796,    320,    -73,   -306,   -122,    290,
+       118,   -298,   -675,   -180,   -828,     86,    -44,    165,
+       435,  -8249,    769,    630,  -1670,   -762,    453,   5893,
+       259,    -92,  -1003,   -358,    -32,  -1350,   -535,   -289,
+       409,   -558,   -344,   -752,   6037,   -680,   2471,    581,
+      -351,   1251,  -5827,    194,   -104,    815,   1257,   -619,
+       243,    410,   4455,   -969,     50,   1286,  -1013,   -293,
+     -7740,     73,    615,    523,   -149,   -824,   2235,   1571,
+       970,    944,   4778,   -132,  -5082,     83,    129,   -820,
+      -803,    694,   1615,   1163,    517,   -402,    -80,    762,
+      -107,   -419,    142,   -294,  11298,    301,    484,   -513,
+       105,    547,   1130,  -4253,   -742,    376,  -1545,   1076,
+      4372,   2338,  -2847,    495,   -190,  -2444,    931,   6487,
+       117,  -1273,   1488,    -75,   -322,   -487,  -2614,   -251,
+      1233,   4111,   -321,   -219,  -7961,    -11,    107,   -808,
+       450,    111,   4395,     89,    772,  -1878,  -1894,   1075,
+      -544,  -9467,   -459,    637,    842,   -956,   -738,   4452,
+       777,    -75,   -209,   -302,   -796,    785,  -7413,    321,
+       649,    -55,    114,     43,  -1026,   -223,   -611,    209,
+     -5543,   8206,    907,  -3358,   1452,   -543,  -3173,    525,
+       -95,     35,   -475,   -525,   -705,   -569,    350,    206,
+      -108,  -1523,   -680,   -283,  -2583,  -4992,    -59,   -968,
+     -1719,  -2750,   5884,    455,     29,    436,    784,   -101,
+      -216,    110,    612,   -511,    -12,     98,    -67,    177,
+     -1210,    222,   -345,    243, -12670,   -472,    282,  -2149,
+       687,  -2631,   4434,     77,   -521,   -404,   -934,    212,
+      -695,   -369,   1138,   1348,   -905,    501,    299, -10467,
+      1018,    818,   1941,     31,    257,   1219,    944,   -157,
+      1968,  -1649,   -126,   -440,   -599,     -1,   6190,   2574,
+      -332,    753,    195,   -131,   5972,   -297,    672,    -86,
+      -143,   -303,      5,   -121,   -154,   -613,   5541,  -1516,
+      -304,    962,     69,  -1857,   4142,   -134,    706,    896,
+     -1226,   -135,   -310,  -9261,   1135,  -3437,    620,    802,
+       -33,   -582,   1909,   1407,    242,   2599,  -1533,   -279,
+       836,   8070,  -1207,   5745,    200,    -77,    162,    781,
+      -466,  -1555,   3297,   -957,    225,   1290,      7,    677,
+        41,   -549,  -2778,   1400,    379,  -3367,    369,    615,
+     -6402,    527,     58,   5679,   -114,   -180,   2842,     88,
+     -2611,    -50,    371,    161,   -444,   2062,    -38,    272,
+     -8562,    769,     18,  -2593,   -226,   -503,   -959,  -1295,
+       189,   -371,   -675,  -1528,    -98,    514,  -1236,    116,
+       202,  13662,   1596,   -328,     61,   3567,   -486,  -3316,
+     -8473,   -317,   2868,   -419,    -17,    535,   -965,   -503,
+     -3848,   2222,    620,  -1740,      2,   6505,    473,   -297,
+       -70,   3043,    -51,  -1520,    993,   1046,   1965,   3240,
+      1971,    -60,   -650,    -53,   -248,  -4428,   -365,  -3723,
+      1122,  -1681,   1629,   1358,    -17,   1136,   -256,   2344,
+      -282,    156,    127,   -155,    318,  -1281,  -1066,     57,
+      -889,   -253,  -1396,   -579,   -920,  -1006,  -9202,   -703,
+       195,   5186,    241,   1742,    996,    118,   1431,   4415,
+     -2452,   6837,  -1272,   -569,   3485,    328,    441,    832,
+       553,     94,    648,     92,   -378,  11167,    775,    457,
+      1712,    -24,    941,   5433,  -1645,   2166,    249,    -55,
+     -1816,    383,    735,   -876,    443,   -568,    293,  -1266,
+      6963,   -178,   -174,  -1186,   1119,   -208,    821,   1499,
+     -1496,  -2171,   1434,    874,    133,  -7466,   -545,   2193,
+      -775,  -1405,  -1205,   -575,  -1996,   -645,   -552,   -263,
+      8861,   -517,     76,   -992,    278,   2417,  -1369,     35,
+     -1461,  -1399,    517,    185,  -2895,    347,  -3871,   3644,
+       284,   3284,    -12,   -169,  -1981,   1196,    -67,   2868,
+       910,    134,   -530,    150,  -1328,   1902,   -746,    351,
+      -222,    522,  -5702,    797,  -1900,    241,   2270,    764,
+      -335,   1348,   -349,    784,  -1586,   -537,    148,   3211,
+     -1692,     56,   1678,   -321,   -290,   7902,     69,     52,
+       310,    337,    250,    596,   9998,    336,   1037,    163,
+        64,   -441,   2894,  -1033,    730,   -718,  -1252,    459,
+      -131,   7840,   -922,   -555,   5671,    299,    689,   1115,
+      -646,   -505,   -263,    608,   -494,      0,    442,  -1802,
+      -598,   -701,  -4184,     70,  -1319,    -90,   9155,   -339,
+         0,    121,    462,    735,   -639,    481,    125,   6924,
+      3379,    683,   3053,  -1219,   -499,   1067,   -148,  -2705,
+       -11,    795,   1675,    898,    226,   1232,     49,   -572,
+     -9309,   2223,    949,    767,   -821,    -91,   1075,   -352,
+     -7829,    554,   -593,   1284,   -245,   1239,   1166,  -1157,
+     -5274,    808,    871,  -1446,   7575,   -397,   -755,    752,
+      4193,    179,   -205,    -37,   -750,  -2675,   -407,   -700,
+       220,    -77,   1604,     63,    461,  -9994,   -645,  -1629,
+       103,    576,    132,  10005,    -49,  -1005,     97,  -1608,
+       515,    -10,   -146,  -1878,    880,    429,  -1271,    996,
+      -365,     76,   -409,   2461,     29,   1159,    217,  -6240,
+      -200,   -746,    118,  -1884,    457,   -816,   -608,   3215,
+       244,    749,   2268,   -236,  -1276,   -278,   1392,  -1767,
+      1255,  -1474,  -8136,   1388,   -770,    225,   -443,     10,
+      -392,    659,  -1118,  -1651,   -514,   -935,   -111,   1112,
+       973,   -247,   -235, -13010,   -737,     40,   -141,   5167,
+      -910,    279,   -467,  -3762,    847,  -3935,   1018,   1922,
+       830,    190,    253,  -1130,   -415,    371,    718,   3833,
+      1036,  -5358,   -928,    866,   -514,   2724,   2354,    449,
+       210,   1462,    680,  -1880,    -62,  10988,    809,   -602,
+       145,   -536,    114,   -147,   -568,   3193,   -322,    892,
+      -637,  -1381,    -65,    761,   1615,   5025,   -327,   4941,
+      -631,  -5225,   1204,   3042,    998,  -1047,   -959,   -106,
+      1610,   -151,    120,  -1152,    191,     30,  11963,    101,
+        18,   -410,  -1288,    370,   -771,   1337,   -544,   -613,
+       289,   -117,   1625,  -4506,   2582,  -1690,   -105,  -5324,
+       -93,    285,  -1167,  -3564,   -729,  -4790,    595,    275,
+      -216,   -217,  -6000,    682,   -171,   -875,    224,   -164,
+      2919,    796,    -81,   1434,    186,   -375,  -4113,   -179,
+       277,   1363,   -453,   2505,    388,  -1840,   -165,  -4800,
+       -42,  -6632,     54,   -735,   -553,  -1679,    917,     -2,
+      -632,    417,   -478,   -494,   -265,     73,   -372,   -360,
+       179,   -448,    265,    299,   -152,   -211,  12730,    -77,
+      1954,   -534,    773,    524,    438,   1901,  -4413,   -358,
+      1552,   -248,  -1588,   -122,   -127,   5405,    226,   -849,
+     -7495,   -357,    -89,    185,    746,    851,    669,    305,
+      -247,   3457,   -193,   -161,    638,    600,    610,    855,
+     -1292,    398,   1528,   2250,   1651,  -8414,    763,   1529,
+      -346,   3769,   -111,  -6494,    347,   -742,   1941,   1967,
+       582,  -5499,   -765,   -818,   1850,  -1604,   -243,   -943,
+       -11,    884,  -2996,  -2375,   1010,   -374,   6605,   -287,
+     -5073,    211,   -758,    703,  -2607,    747,   -130,   -429,
+     -2481,   4894,   -457,   3225,    958,   8533,    542,   6177,
+     -1069,  -1210,   -963,  -5943,    -86,   1424,   -567,    827,
+      -510,  -6577,   -258,     -4,  -4430,    115,   5401,   1390,
+       354,   1755,   -998,    852,    993,   -481,    218,   -987,
+       779,   -417,    591,   6011,    528,    289,   -336,   -558,
+        60,   9124,   -174,    235,   -239,   -144,   -260,  -3472,
+       746,   4781,    652,  -4831,   -739,    -21,    864,  -2310,
+       652,   7147,    116,   -318,    -50,  -3485,   -325,   -345,
+     -5784,   1144,   2399,  -1443,    991,  -2318,   -785,   -281,
+      -207,  -1448,    309,   1001,    952,   1472,  -5901,   -780,
+     -2459,   1518,   9878,  -1229,    670,   -523,   1217,   -164,
+       -55,    -95,    243,   7909,     86,  -4380,   -859,   -599,
+      -183,  -2339,    774,  -1210,   -502,   -899,     53,   1039,
+        34,  -7753,   -296,  -1951,  -4559,   1182,   -150,   2878,
+     -4910,   2761,  -1481,   2048,   2600,   1808,  -2953,  -2257,
+        62,    162,   1115,    214,  -4510,    926,  -6669,   1443,
+      -124,    193,   -314,    302,    699,    -18,    745,    341,
+       895,   -615,   -295,   -181,    143,   -427,   6528,   1074,
+     -1126,    374,   -298,  -1274,     22,    887,   -511,  -1057,
+      3228,    722,    607,    624,    -95,  11085,   1006,   -788,
+      -285,    -92,   1342,   -325,   -828,     42,  -3588,   -631,
+      -576,   4559,   -668,  -1294,   1739,   1697,   -647,   2336,
+       376,   -120,   1350,    646,   -325,     95,   5974,    775,
+       199,  -8557,    931,   -336,   -651,   -561,   -433,  -2266,
+      -129,   -657,  -1184,     67,    577,    617,   1880,    552,
+        90,   -617,   -273,  -1571,  -7481,    261,    -26,    -20,
+      -459,  -1028,     57,  -8516,    -43,   2774,      1,  -4238,
+       680,  -3310,    -56,   -152,    548,  -1983,    920,    899,
+      2180,   -307,  -2230,  -1685,   -998,   2091,   -112,     21,
+     -1551,   1182,   6649,   -326,    792,   1818,  -7596,    563,
+      1076,   7422,   -908,   1524,   -223,   5798,   1318,  -3376,
+       517,   4162,    756,  -4142,   1776,    390,    334,    -44,
+       218,   5290,    792,     39,   1692,    542,    -62,   -595,
+       590,     27,   8922,    989,    182,    725,    112,    458,
+     -9170,  -1000,   1176,  -1290,  -1403,   -726,   5990,   -297,
+      1234,  -1724,   -601,    528,   1072,    184,   -146,     61,
+       685,   1208,    -88,   -211,    356,   9569,   -363,   -135,
+      -159,  -1061,   -105,   -410,    -58,    335,  -9986,   -300,
+      -211,    607,    443,   -410,  -1730,   -328,    275,    579,
+       805,    899,   -464,    -18,    296,   -446,   2396,    -13,
+       414,  -9662,   -385,   -808,  -1867,    154,   -572,   3351,
+     -1839,    -80,   1157,   -326,    481,   8815,  -1039,   1065,
+      2110,   1223,   -960,    -33,   -464,  -5660,    490,   -314,
+       346,    730,   -387,  -1102,   6656,   -719,  -1173,    -57,
+     -1186,   2394,  -1300,   -665,   -586,    -39,    -71,    155,
+      1184,      4,  -3269,   -333,   -747,    580,    279,   -583,
+      7164,   -185,    110,   2465,    428,    507,   4462,  -4461,
+       199,    337,  -3597,   -249,    -70,   -680,  -5549,   1533,
+       917,   -303,  -9230,   -431,   -124,  -1019,    369,    139,
+      1367,    151,  -1047,   6820,   -151,    222,  -2934,   -817,
+       971,  -7325,    556,   1035,  -1240,   3115,  -1326,   4012,
+      2812,   1057,   2580,   -261,   3989,   1999,   1624,   2402,
+      -310,    779,   -354,   -377,   -149,   1035,  -2363,    358,
+      3666,   -246,  -1896,    375,   3919,  -1392,    683,    624,
+     -5872,    644,    391,    288,   -198,   -237,     68,   -284,
+        88,  -1016,    250,     32,   1188,   -243,   -608,   -320,
+      -219, -11087,    543,    156,   1034,   -169,   -183,   -549,
+       -66,    716,    996,   -928,   -309,   5577,    229,    125,
+     -1328,   9027,   -698,   -485,  -1694,    839,    343,    449,
+      1655,   1005,   1053,   -408,   9106,    186,    670,    774,
+       314,    573,   3888,   -882,     26,   2518,   -533,   -195,
+       555,    337,   -246, -10779,   -231,     31,   -314,   -941,
+      1129,    333,  -7503,    168,   -551,    237,   -159,   4399,
+       421,    693,    198,   -196,   -561,   1035,   -548,   1058,
+       527,   3617,   -361,   1317,  -1975,  -2638,  -1966,   -120,
+      -324,   5678,  -2252,   -663,    181,   -273,  -3073,   -282,
+      -622,    363,     71,    184,   -776,    284,  -1516,   -430,
+         3,    937,   8587,    258,  -1060,  -1555,   -830,   -338,
+       318,  -9130,   -110,    459,   -572,     70,     93,    120,
+      -534,   1296,   -168,     29,   -914,   -332,   -997,   -818,
+       270,   -243,    523,     56, -11847,   -448,     11,   -154,
+       164,   2115,    -13,   -635,    708,   -663,     43,   -248,
+     -3244,    254,     19,  -1125,    508,    154,   8697,    191,
+       595,   4393,  -2806,   -168,  -1916,    393,   3976,    897,
+     -1716,    -35,   -180,    605,  -1057,  -1194,    100,   -384,
+       -37,   -107,   2739,   -207,   6899,    176,     81,   -901,
+      1280,  -1670,   -101,    281,   1147,     48,     21,   -151,
+     -1236,    210,     98,   -114,   -573,   7940,   -153,   -302,
+     -1331,    337,   -322,   6598,    477,    147,   -999,  -3166,
+      -232,  -5104,   -799,  -1866,    -58,  -4213,   1376,    181,
+       675,    562,    126,    235,   2260,  -5152,   -243,   -699,
+     -1476,   4135,    569,    567,    737,  -4163,    613,  -1057,
+      1778,    546,   -450,    -24,    325,    366,   2406,  -1319,
+        60,  -5126,     49,    657,  -5937,   -194,    882,   3267,
+       178,   -298,   1873,  12422,    459,    272,    195,  -1827,
+       212,   -802,    730,    471,   1556,    422,    640,    236,
+        71,    597,   5783,   5378,   -649,   1524,    829,    437,
+      -351,   -122,  -1400,   2119,   -128,     75,  -1677,   -633,
+      -322,  -6382,   -573,   -974,   1672,   -378,   -242,   3708,
+        79,  -1325,    397,   -150,   1977,    442,    747,   -127,
+};
+
+static const int16_t shape16s[] = {
+      -392,     96,  -7720,     99,    524,  -8272,    -20,    164,
+      -434,    -85,   -428,   1362,    108,    223,   1053,    -11,
+      -193,  -5140,   -191,   -159,    193,   8005,    -39,   -483,
+      1764,  -1061,   -268,   -318,   -880,    474,     49,     -8,
+      -223,    130,  11263,    165,     12,    -43,   -103,  -1145,
+      -588,    -81,    299,     73,    444,  -7243,  -1411,   -640,
+      -946,     16,   -881,    496,   2403,   -476,   1090,   -294,
+        29,   -148,    109,    145,    -52,    247,   -545,   1115,
+     -7451,   -491,  -1459,    397,  -8603,  -1022,   1494,    298,
+     -5156,   -358,  -1097,  -2911,    423,    652,   -378,  -2357,
+       -74,    415,   -367,    402,   2173,   -154,    122,    283,
+      1352,    302,   -373,   -431,   -283,   -109,    -64,   -343,
+      -108,     55, -14644,    241,     37,   -723,    -71,   -208,
+      -126,   4061,  -9887,    494,   2273,   -505,  -4040,     66,
+      -806,  -1121,  -1894,    783,  -1445,    426,   -820,  -1739,
+       -11,    650,   -282,   -518,    124,  -7266,    -21,    160,
+      -339,      5,   -208,  11712,    198,    -53,    921,     89,
+      5987,  -4806,    176,   1884,     64,   -517,   2169,    108,
+       297,   -111,   -389,   -840,    663,     75,   -485,  -4862,
+      -177,   2663,   -229,   8120,   -219,    462,   3104,    955,
+       384,   1310,    -73,   -504,    258,    170,  -1796,   -482,
+      5691,   -437,  -8474,    583,  -1685,   -827,    292,    -65,
+      1994,   -384,    105,    123,    256,    -82,   -367,  15204,
+      -128,   -260,    -10,    169,    249,  -1286,   1055,    136,
+       678,     61,   1420,   -159,    -15,   -221,   -250,    107,
+       -21,    297,     54,    242,   -111,    468,    237,    -36,
+      -159,     37,   -102,   -488,  -4577,     72,   1009,     -1,
+      1218,   2023,   -640,   -437,    766,   -299,   6144,    184,
+     -1023,    171,   -388,    884,  -1294,   -320,   8718,    896,
+      -295,   -976,   -803,   3092,   1720,   -255,  -1354,   -665,
+       -63,   4382,     41,   -121,   -157,    354,    127,    587,
+      -599,   -231,    484,   -150,   -284,   -498,   -511,     79,
+      5503,     13,   6537,    761,  -1619,   1164,  -2403,   3057,
+     -4966,    724,   1076,  -1555,    889,   -365,     60,   -440,
+     -7144,   -132,    283,   -305,   -126,  -1482,    125,    -52,
+       -33,   1284,   -961,   1355,    953,  -1012,   -227,     86,
+       731,    -14, -15977,    -56,   -875,  -1676,    127,    500,
+      3390,    -14,   -319,   -644,    143,    249, -10752,     23,
+        54,  -1075,   -111,    680,  -1714,    328,  -2092,   -852,
+       622,    949,     61,      6,    -17,    144,    190,    216,
+       130,    -65,     27,   -322,   -139,     43,     89,     76,
+       -84, -10120,    -47,    367,   -261,     38,     50,   4233,
+      -210,     14,     -1,     25,    762,   -299,   -132,    177,
+       974,   -492,   -145,    -43,   5105,   -394,   -196,    -91,
+       -25,    473,  -8358,   -476,    589,  -1372,   -254,  -2387,
+      -293,   -304,   3828,   -254,   -193,    493,     54,   -108,
+     -8789,   -262,   -233,   -821,   -222,    714,   1270,    -61,
+       892,     13,   3952,    -36,  -1567,   -620,   -126,  -1056,
+       587,    390,    -24,   2027,    267,    218,     15,    -56,
+      -130,     40,    551,    -29,  14594,    -23,    106,    -14,
+      -172,    279,    427,   -241,    303,    -20,   -748,     55,
+      5187,    598,   -217,   2026,    643,    118,    911,   8023,
+       296,    791,     39,  -2621,    655,    228,   -671,   -272,
+      -176,   6644,   -166,   -264, -10429,     91,    -83,   -684,
+      -169,   -344,   2123,   -102,   -333,   -317,   -826,    586,
+       116,  -9311,    445,    141,  -1315,   -758,    144,   5620,
+       363,     66,    142,   -161,   -684,    454,  -6584,   -205,
+       577,    205,    305,  -1536,  -4109,   -318,    121,   -323,
+     -1036,   8020,   1146,  -4004,    175,  -1568,  -1537,   -525,
+      2284,     62,     11,    640,   1243,    260,   -104,   -344,
+       102,   -624,    122,   -300,    266,  -6104,  -1149,    412,
+     -1380,     22,   7561,    360,    564,    398,   -338,    174,
+       -76,    131,     44,   -426,    -12,   -175,   -113,     78,
+       293,   -120,    -92,    331, -16163,    -74,   -101,  -1198,
+      -298,   -171,   4052,   -139,   -187,    131,    323,    370,
+      -144,   -160,    131,   -284,   -190,     83,    878, -14817,
+        14,    196,    198,    294,   -120,     40,    800,   1841,
+       393,   -168,    337,   -540,   -356,    130,   9210,    880,
+       304,  -2304,   -275,   1394,   9903,    673,    -62,  -4706,
+      -130,    274,    528,     89,   -458,    -90,   6318,   -133,
+       310,  -5953,    682,     37,   2937,   -371,    197,     77,
+      -184,   1240,     22,  -7695,   -171,  -4874,   -676,  -1121,
+      -842,   -642,   1160,  -1088,   -864,    352,   -790,    794,
+       801,  10564,  -1777,   1095,   -441,   1718,    116,    982,
+      -268,    199,  -2408,  -2042,    279,   -146,    645,  -1350,
+         5,   -150,   -932,    113,     25,   -672,    153,    158,
+     -6140,   -262,    142,   4815,     -1,   -424,    810,     63,
+        88,   -510,   -236,   3964,    -66,   1229,    -16,   -758,
+    -11023,  -1149,     48,  -1756,    167,   2308,    -96,   -654,
+      -639,    369,   -221,     47,    202,    329,   -352,    -26,
+       -19,  13198,   -383,    124,  -1211,   3879,   -344,  -1954,
+     -8702,     32,    924,    472,   7953,    692,   -216,   -415,
+     -3174,  -1959,    935,   4048,    155,   7521,    854,   -157,
+       643,   3760,   -107,  -2536,    622,   -742,   1881,   2262,
+       758,   -968,   -271,   -131,    385,  -5107,   -212,  -2548,
+        29,   -132,   -506,   -190,  -1065,    314,    202,    332,
+     -2274,    701,      4,    -22,   -439,    198,   -265,    -92,
+      -143,    460,    -32,    189,    334,     87,  -7639,     45,
+      -387,   4240,   1231,     92,   1032,   -333,   -280,   2061,
+       296,    365,   2003,   -426,    -35,     96,    -62,    882,
+      -784,    483,   -128,   -143,    474,  13740,   -166,    184,
+      -714,    142,    278,   5622,    -67,    282,    647,   -130,
+       -31,    300,    727,    728,    409,    178,   -601,     84,
+      8305,   -446,    179,    115,    209,   -273,    -47,   1932,
+      -255,  -3171,   -102,    461,   -119,  -8102,   -809,    108,
+     -1680,  -3171,   -775,    324,   -246,    132,    -27,     84,
+      8495,    -45,    153,     21,  -1384,    290,   -869,     38,
+      -440,    133,   -257,    -22,  -3046,     12,  -2797,   4517,
+       142,   1605,    423,    579,   -558,   -301,   -257,    701,
+      -246,   -468,  -1946,    120,    321,    710,   -217,   -203,
+       -50,    -44,  -5866,     80,    259,    488,    754,    124,
+      -517,    703,   -197,    146,    576,   -717,    247,   4121,
+        10,   -422,  -2686,    329,   1183,  14573,     72,    301,
+      2043,   -125,  -1420,  -1263,  10340,   -678,  -1226,    330,
+       -62,    173,   5885,    -56,   -178,  -1090,   -616,    953,
+      -216,   8277,   -124,    411,   7758,    -78,   -326,    786,
+        46,  -1365,   -555,    479,   -774,   -576,      8,    304,
+       390,   -186,   -820,     72,    -67,   -585,  11070,   -213,
+       -12,    344,   -399,   -748,   -150,   2719,    195,   5652,
+      4626,    549,   2782,     -4,   1928,    482,   1008,  -6398,
+       843,    457,   1843,    269,   1247,    350,   -661,    -35,
+     -6477,   3727,   2313,   -424,   -907,    415,   1075,   3960,
+     -1499,     61,    594,   -744,    110,   2486,    967,     27,
+     -5263,   -618,   -578,    313,   7055,  -1081,    739,   -492,
+     -2051,    317,    112,   -155,   -304,   -507,    150,    253,
+       -42,    221,     92,   -275,   -355,  -8494,   -663,    109,
+       282,   -836,   -271,   9316,    165,     63,   -171,     10,
+       -38,   -180,   -219,   -250,   -924,   -573,   -241,    566,
+      -175,     20,    454,    251,   -328,    236,   -215,  -5673,
+         0,   -265,    225,    354,    113,   -488,    174,   -132,
+       134,   -188,   1255,    -94,    -55,   -193,    404,    504,
+       784,   -377,  -5731,    333,   -447,    222,    138,     72,
+      -256,    -58,   -230,   -169,    728,   -481,     95,   -394,
+       -74,   -489,   -253, -13770,     61,    184,    -36,   5025,
+      -232,    321,    253,  -3414,    120,  -2512,    799,   -586,
+      1186,  -1135,   -955,    -54,      7,     83,      0,   5259,
+       466,  -6358,    254,    388,   -211,    207,   2449,    379,
+       430,   -219,   -442,    228,    151,  11819,     67,   -101,
+       239,   -282,    121,   -270,   1209,   -386,    553,   -108,
+       789,   -518,    237,    -48,    497,   8986,     80,   8232,
+       -89,   -359,   -803,    473,    995,   1132,    624,   1353,
+      -305,    711,    -71,    -26,     18,    254,  13079,    -72,
+       178,    -18,   -116,    293,    155,   -254,   -819,   -166,
+      -808,   -190,    150,  -4328,    -33,    -14,    272,  -6417,
+        78,     78,     67,    310,   -177,   -435,    225,    610,
+       -15,      1,  -6706,     30,      1,   -189,    270,    -21,
+       276,   -182,     77,   -231,     30,   -116,  -7713,    158,
+       344,    560,   1466,   3575,    -84,  -4583,  -1260,    372,
+      1395,  -5223,    284,  -1911,    315,  -2312,    -47,   -207,
+       414,    129,     36,     85,    317,   -125,    -63,   -212,
+       -76,    130,   -385,    157,    117,     12,  16140,   -171,
+       375,   -721,    161,   -342,    950,   -667,   1011,     15,
+       536,  -1203,   1039,   -242,   -159,   7664,   -429,   -264,
+     -8221,   -109,    867,    -74,    -79,   -414,    544,    206,
+       120,   1859,    -44,     73,    554,    121,   -160,   -127,
+       -33,     44,    -24,    285,    589, -12514,     51,    464,
+        17,    264,     58,  -6861,    367,   -672,    227,   2793,
+       782,  -6286,   -420,   -808,  -1247,    895,    950,   1533,
+     -1079,   -207,  -1927,  -4947,   -803,   -328,   7677,   -386,
+     -4608,   -329,   -485,   2365,  -1492,  -1738,   -378,   -707,
+     -1850,   9044,    314,   3530,     61,   2921,     79,   9508,
+     -1102,  -3487,    814,  -2828,    550,   -929,   -712,   -274,
+      -566,  -2521,    536,   -296,    -97,    951,  11352,   -614,
+       106,   -342,  -1017,  -1183,   -157,   -457,    266,    109,
+       545,   -313,   1015,   6961,     52,   -224,   2247,   -248,
+      -180,  12367,    311,    514,   1218,   -561,  -2546,  -3275,
+       218,   8281,    187,  -6550,    -96,  -1001,   1777,     89,
+       916,   1042,    399,   -267,    -97,  -3552,    397,   1984,
+     -6134,    784,   2136,  -1346,    619,  -1450,  -1022,  -1226,
+       185,    306,   -274,   -122,    343,    129,  -4481,   -749,
+      -759,   -496,   8785,   -178,    457,   -601,    875,   1040,
+      -268,  -1592,   -531,   9667,    360,  -4978,    525,   -436,
+       123,  -1566,    227,    820,     74,     -5,   1477,    154,
+     -1589,  -9411,    248,   -485,  -3293,   -690,    175,     53,
+       -21,    303,  -2376,    106,    515,   2688,   -401,  -1278,
+       425,    540,   -353,    662,  -7461,   -397,  -7029,   -976,
+       445,  -1648,    164,   -254,   -563,    556,    876,   -205,
+       884,    214,    -92,   -509,     96,    -53,   5734,   -295,
+      -136,    211,    168,    261,    -74,    411,     25,    -59,
+      3596,    400,    320,    -69,    -21,  14062,   -510,    142,
+      -232,   1597,     34,    240,   -476,    131,  -3836,   -186,
+      2579,   2812,  -1501,    274,   2685,   2809,  -1100,   2696,
+      -402,     67,    650,  -1804,    -11,   -216,   6751,    112,
+       455,  -7210,   -251,  -1075,   -833,   -966,   1443,   -138,
+       273,   -494,   1557,    -15,   -339,    -82,    402,    206,
+        31,    -77,    -94,     78,  -5468,   -179,    -44,    421,
+       163,   -386,   -133,  -6334,    427,    747,   -121,   -292,
+       368,  -1087,   -338,  -1534,   3740,   -881,  -2012,  -1284,
+       902,     97,  -3407,   -567,   -118,   1340,    -77,   -445,
+       642,    184,    901,   -341,    -81,    595,  -6531,   -248,
+      -167,   8740,    373,    408,     23,  10709,   -299,   -876,
+      -584,  -1067,     20,  -4556,    295,  -1956,    990,   -132,
+      -152,   4068,    -92,    142,  -1512,     23,   -815,    454,
+       330,   -331,   9042,    120,   -100,     34,     96,    152,
+    -11083,    345,   -567,   -498,    198,    -37,   9276,   -479,
+       611,  -2788,    253,   -176,    617,   -224,    248,    390,
+        39,     25,   -110,    127,    -13,   6675,    -84,    115,
+       294,     84,   -366,   -405,    -32,   -109, -10469,     99,
+        17,    -88,   -226,    316,   -133,   -203,    -60,    311,
+       -87,   -331,    357,    -11,    158,     74,    562,      8,
+       354, -10843,   -114,   -206,    699,   -617,   -141,    807,
+        87,   -149,    174,    199,    -55,  10880,   -332,    182,
+       544,    651,    -27,    261,   -190,   -655,     24,   -443,
+      -630,    204,    207,  -4174,   3557,     89,   -386,   1754,
+      -485,   -127,    -97,     40,  -1336,   -488,   -177,   -750,
+        88,  -1040,  -2215,   -507,    169,   2908,     69,    -52,
+      8458,    601,    174,   1635,    480,    181,   3004,  -3021,
+      1868,   -364,  -2100,   -256,  -3065,    -33,  -7467,   -890,
+     -1949,    -20,  -9472,   -230,   -847,   -634,   -377,    -40,
+      1184,    242,    265,   7056,     42,     16,  -5070,    -71,
+       300,  -1186,    187,    337,  -1331,     77,   -473,   3213,
+      5738,    626,   2524,    531,   1001,   -803,   1231,  -1083,
+      -564,    539,    191,   -498,    184,    603,  -1777,   -479,
+      2298,   -604,  -2077,    634,   4682,  -1387,   -875,    498,
+    -10011,   -173,    752,    109,    -70,    171,    -64,   -261,
+       -79,     37,   -233,    128,    -66,    -70,    356,   -310,
+       214, -14792,      6,    200,   -227,     59,   -241,    560,
+      -230,    479,    403,    -22,    148,   7428,    110,   -177,
+       110,   7518,  -2372,  -1277,    223,   -708,    731,    695,
+      -702,  -2906,    256,  -1160,   4941,    121,  -1148,    -68,
+      -424,  -1590,   4697,    705,    525,    684,   -451,   -246,
+      -115,    556,    543,  -6658,    384,   -589,  -1505,     12,
+       114,     82,  -5084,    164,    154,   -295,    106,   -271,
+       -40,   -394,   -437,    397,   -279,  -3825,   -286,    632,
+     -1041,   1137,    -93,     48,    192,  -5914,    -92,   -235,
+       682,   5817,   -702,    180,   -243,   -219,   -910,   -174,
+      -146,    142,     12,    -69,   -207,   -269,    -53,    567,
+      -336,    114,   9601,   -272,   -270,    459,    610,   -258,
+        97, -10950,    397,     57,     -7,    229,   1669,   -173,
+      -173,    -92,   -347,   -133,   -357,     92,    132,   -609,
+        60,   -124,    116,    -54, -15205,    142,    109,   1127,
+       268,   -220,    336,   -743,   -238,    -29,   -902,     91,
+     -3597,   -288,   1114,  -3797,  -1615,     32,  11481,     55,
+       194,   3567,  -1857,  -2561,   -237,    -15,    -48,   -232,
+       -58,    -21,     37,   -535,   -450,    857,   2001,     12,
+        48,    840,    211,    126,   4833,    275,    176,   -111,
+         9,   -112,   -403,    182,    296,    181,   -425,    -14,
+       276,    118,   -240,    384,    139,   9183,   -230,    143,
+      2412,    -70,    250,  10191,    809,    -15,   -257,  -1242,
+      -163,  -4253,   -352,   -436,    264,  -4998,    -17,   -215,
+      1412,   1592,    856,   -159,   4756,  -5032,    307,   -251,
+       194,   6414,    -56,     -7,   -503,   -261,   -646,  -1050,
+      -271,   -578,   -291,    614,    130,   -336,   -923,   -120,
+       149,  -6012,    273,   -295,  -4586,    137,    206,   1246,
+       498,    614,    991,  13776,    122,     52,   -660,    -76,
+      -211,   -477,   -224,    196,    411,    398,   -590,    820,
+      -441,    -35,   4394,   5010,   -902,    509,     45,    747,
+      1035,   -455,   -579,    105,   1103,   -496,  -1249,   -248,
+        46,  -5771,   -198,   -386,    736,     15,   -335,    -85,
+      -624,   -124,    580,   -327,   -102,    -18,    866,    381,
+};
+
+static const int16_t shape22[] = {
+      2560,   -127,   -137,   -385,  -1875,     90,   -240,    140,
+      1290,    200,  -6762,    374,   1871,   8730,   -111,   -555,
+     -1524,  -2175,  -4689,    521,   -179,    166,  -1573,   1056,
+      -346,    247,    -92,   5713,    561,    233,   -360,    480,
+      -741,  -7552,  -1508,    259,  -8746,   1604,   1385,    723,
+      5678,   2243,    403,  12370,   3526,    574,   4982,    563,
+      1713,  -1337,   1336,    -60,   -890,  -2184,   -563,   9347,
+       775,   6318,   -883,   1476,   -335,    736,   -564,    635,
+     -5557,    617,     54,    257,   -325,    -66,  -5689,   1061,
+      -897,     90,   8394,   2004,   9456,   -222,  -2026,   -969,
+        93,     -5,   -922,  -6491,   1496,  -1537,    651,   -277,
+     -1038,   6072,  -8534,  -2526,   1645,   1459,    547,   2347,
+       -85,   -761,  -7210,   -153,    414,   6096,    383,    320,
+       370,   -902,    823,   3071,    499,   -731,     38,    473,
+      1693,  -9456,    946,   1218,  -1054,     70,    367,   -469,
+     -7861,   -913,    401,    198,    -83,    877,   -308,   8633,
+       253,  -2025,   1925,   1412,   1351,   -360,   -948,  -7526,
+      1089,  -7449,   1652,    141,    -43,  -2082,     44,    130,
+     -7525, -15049,  -1345,    180,  -3009,  -4581,   -267,   2309,
+     -1397,   -112,    -63,    307,   -746,    -13,     35,  -8800,
+     -1947,  -1143,  -1096,  -2582,  -1210,   7683,   -743,  -1589,
+      5699,    -80,  -1375,    -93,   -483,    129,   6076,  -6099,
+       374,   -176,  -1150,   -416,    137,  -4309,  -1926,   3099,
+        82,   -836,    392,   -655,    108,    428,   3361,    313,
+       363,   7534,   1153,    334,   2262,   -367,    -69,   -813,
+     -9702,   3074,  -5461,      0,  -1889,   1303,  -8306,   -113,
+      -677,    692,  -2752,   1292,   -171,    430,   4609,  -2238,
+       196,   1661,    -25,   -164,  -2590,  -4919,   -615,     -7,
+      -753,   5104,   5197,    -66,   -310,    827,   -126,    615,
+        70,   -456,    238,    682,   -639,   -561,    369,    183,
+       113,    430,   -840,   -792,  -7282,  -7537,    619,   -445,
+       588,     19,  -1061,    652,     46,    861,   9641,  -1251,
+       -41,   -699,   -605,  -1389,    240, -10798,    733,    194,
+     -1230,  -1092,   -520,   -219,      7,    518,   -181, -12062,
+       651,    -40,   1128,   -390,   -220,   -438,    471,    510,
+       632,   -321,   1393,   8827,  -3241,  -6683,    350,   1953,
+      -246,   -582,  -5486,  -7576,   -157,    888,   2965,    -23,
+       762,   6867,   3697,    -43,  -7905,   -938,   2119,    377,
+       -25,    691,    136,   -725,   7643,   -730,   2024,  -6932,
+       804,     53,    392,    440,    336,   6235,  -7037,  -5584,
+     -1579,   1115,   1757,   1001,     32,   -294,   -592,    300,
+      -764,  -8879,  -1612,   -845,   1722,   6968,    384,    267,
+       862,  10830,   -364,  -1138,    -49,   1041,   -908, -14960,
+       809,    628,  -1150,  -1348,   -437,    805,    877,    -64,
+      1041,   5253,   -270,   2022,   1253,   -992,  11015,   2686,
+        17,     80,  -1463,   4229,     80,   -834,  -9286,   1179,
+        66,    -39,    -64,  -4057,   -423,    116,  -1441,  -1733,
+       752,   1674,   1443,    757,  -3149,   9057,  -3522,   4007,
+      -893,   1179,   -388,   6368,   -478,   4397,  13868,  -2996,
+       790,    704,  -2299,  -6003,    449,  -5410,   1999,    181,
+     -1807,   -362,    -57,    454,  -2371,   3658,   -485,   -212,
+     11551,   1535,    478,  -1570,   -278,    584,    608,  -5211,
+      6965,   1042,   -168,   -337,  -1071,     72,    451,   -204,
+     -1000,  -1044,    689,    186,   -166,   -375,   9426,    363,
+        93,   -717,    304,    107,   7853,  -1251,   1093,    692,
+      -742,     33,    576,    447,    678,    452,    408,  -4813,
+       711,   -595,   -516,  -1108,   1941,   3056,   -219,  -3413,
+     10946,   1513,  -2375,     48,   -408,     49,   -399,  -5608,
+       -58,    161,   4808,    436,     68,  -5675,    230,    832,
+     -1228,   6382,   -588,  -1312,    772,   4337,   -405,  -5467,
+      -222,   1382,   2158,    620,   -840,    810,  -3830,     48,
+      -101,    529,  -2670,   -249,   1035,  -7620,  -1081,  -6646,
+      1469,   1043,    743,   1553,   -556,   -274,     68,    238,
+      1078,   -110,  -5163,    562,    735,  -8317,   1202,  -1325,
+      -962,     61,   4280,    570,   7450,    265,  -1516,    696,
+     -1567,   -681,      0,  -4064,   1548,  -2521,    657,    567,
+     -8343,   1691,  -1430,   4827,    807,    905,  -2601,  -7415,
+       921,  -1741,    363,    309,    211,   -521,   3013,   -797,
+       648,  -3709,    961,    662,    403,   -386,   -719,  -5752,
+      1355,   6717,    191,    591,   -371,  -1225,  -5125,    800,
+      -252,  -5769,   1101,    657,   -141,   2377,  -1365,   -218,
+      -114,    148,    276,    358,   -354,     18,    -31,  -9413,
+     -5514,  -1458,   -220,    298,    666,    659,    359,    980,
+     -1389,    101,   1500,   4661,    472,    264,  -7590,  -1469,
+        41,     38,   -259,   -346,   -486,  -9949,    812,    422,
+     -1354,  -2461,  -2057,   -253,   1806,   -107,    -41,  16384,
+      -140,   -684,   5421,   1907,    -10,   -889,  -1877,  -6815,
+      -818,  -5854,  -3196,   -895,  -1706,   -186,   7944,    100,
+    -11260,  -4573,   -415,   4685,    395,  -6035,   5789,  -4566,
+       624,  -2146,    570,    130,   -892,   1385,   -262,   6638,
+     -2324,    348,   -288,    607,  -1574,   7119,  -1037,    -40,
+     -4955,   -946,  -5215,  -1013,  -1232,   -875,    -78,   -399,
+       231,   -173,  -5860,    189,   -755,  -8265,    745,    966,
+       202,  -1858,    -26,   -658,     55,   1131,    -56,   3030,
+       158,   3742,  -1261,    317,   6397,    521,   -508,   -522,
+     -2040,   -747,  -6906,   -868,   -110,   -719,   2602,   2570,
+     -1106,   -787,   -352,   9212,   -545,   7339, -10183,   -726,
+      1104,  -1118,  -1655,    383,   1370,   1412,    528,  -4689,
+      -398,  -3802,   -682, -11004,  -2310,   8011,   2301,  -5941,
+      -512,   3813,    210,   1379, -15209,   1143,  -2344,   2459,
+      2368,  -6484,  -2078,   -246,    383,   -204,   1449,   -453,
+     -1539,    416,    508,  -7168,  -1930,   4279,    453,   -215,
+      -296,   -346,   5691,   -200,   -855,    552,   5921,   -109,
+       588,  -3049,   1312,   6767,    -78,  -7204,   1187,   -754,
+     -1043,   -455,    412,   -490,   3124,   -273,   1468,   -546,
+       552,   -306,    835,   -263,  -7234,    324,    318,  -1224,
+       240,    198,    193,   -550,   -684, -12416,     85,  -1469,
+      -463,   -301,    180,    290,   -928,  -6399,   -931,    176,
+       310,   -692,   7964,   -204,    512,    975,  -6415,   -394,
+       -30,   -120,   1638,  -1474,   -381,   5912,    156,   -830,
+      -575,   -225,  -4079,   -787,   -957,   -801,    181,    575,
+      1116,   -795,   -743,   -981,    434,   -365,  -9780,  -1814,
+      1447,   1081,    153,    884,   8697,    259,    881,   -661,
+     -1232,   -547,    464,    898,  -3988,   -476,    790,   7589,
+      -525,   -809,  -2900,  -1271,    170,    223,  -5050,  -2554,
+      1458,   -666,    537,  -6733,    212,    448,  -1556,   1459,
+       802,  -2716,  -8785,  11020,   -258,   1229,   1138,    843,
+       508,    103,   -657,   1273,   8140,    368,   -605,   6856,
+       110,   -423,   5458,   -417,    993,    257,   5552,    -47,
+      1401,   -119,  -1320,   6193,  -1196,     56,    -93,  -1604,
+     -1491,   -897,    238,    823,   4213,    104,    145,  -1049,
+     -9286,    -26,   -813,   -139,    499, -10351,   -466,   -515,
+     -1166,   -412,   -746,    503,   1872,     17, -11941,  -3350,
+      -108,  -7296,   -411,   4811,  -1870,    162,   5595,   -658,
+       339,   -904,   6911,   -715,   -240,    -71,    377,   4747,
+       -57,  -8920,    521,    753,   -375,  -1185,   1322,   -328,
+         5,    525,   -610,    127,   1519,    791,    784, -16384,
+       116,  -1007,   -352,    486,  -7871,    202,  -3684,   -387,
+       676,  -8942,   -713,   -447,   -557,   1159,    974,   -380,
+     -1183,   1049,     -9,    838,   -932,   -139,    371,   1688,
+     -7617,   1192,   2350,   -220,  -4558,   2681,   1568,    102,
+      1274,   -446,   -351,   1551,   1101,  -8995,  -5276,  -4416,
+      3411,    221,   -429,    412,   1625,  -4575,    254,   -631,
+       310,   -378,   9743,    859,    934,    142,  -1400,  -6921,
+      6466,  -4068,   2664,    418,     70,    284,   -903,    -23,
+      -502,   4354,  -5993,    125,    -34,  -1246,  -1946,   -204,
+      1002,  -7454,    -88,  -8628,   2449,  13715,    318,  -8759,
+       294,  -2212,    138,   -761,    285,  -1686,    291,    606,
+       180,    761,   -359,  -1467,    299,   -417,   -361,   -895,
+     -5692,    127,   -951,    165,      1,    396,   -819,  -5508,
+       280,    760,   -411,  -1025,   -649,  -1688,  -6290,    272,
+       -17,  -7595,      9,    307,    128,  -3995,   -119,    481,
+     -3100,   -255,    651,    139,  -3492,     -6,  -4471,    452,
+       -71,    139,   1255,  -6128,   1191,    326,     28,   -238,
+      1374,   -334,   -457,   -836, -10390,    185,   -616,   3366,
+       -39,    183,    -21,   6240,   1141,    341,   -348,    738,
+       121,    -65,   -386,    -27,   -548,    337,     -4,   -126,
+       571,   2263,   4936,  -1093,   -397,    961,  -5886,   -734,
+      1509,   -660,    -61,    170,   -783,  -4197,  -1459,    906,
+       -31,    400,   -481,    561,      6,    489,  -5397,  -1666,
+        41,   -536,   -116,   6713,   1288,   -157,   -116,   4256,
+      1895,   6671,   1837,   -544,   1276,   2031,    345,   6471,
+       -84,   1868,  -2006,  -1304,  -7792,    702,  -1189,    105,
+     -4869,   -282,   -790,   7083,   -628,  -1273,    252,   -179,
+};
+
+static const int16_t shape22s[] = {
+       493,     -2,   -310,   -109,  -1218,   -193,   -267,    -11,
+      -466,    -34,  -2492,    287,    241,   3621,   -537,    458,
+       869,   -915,   -290,    782,     65,    -90,   -635,   1836,
+        80,    519,    868,   1359,    550,    -92,   -704,    110,
+      -210,  -4337,   -376,   -200,  -2693,      6,    381,    688,
+       556,    883,    -88,   1698,   1081,    133,   1130,    -78,
+       853,   -424,    -39,   -909,  -1579,  -2774,   -372,   3604,
+      -519,   3777,    -66,   1330,  -1055,   1135,   -995,    220,
+     -3124,    122,     83,   1045,   -701,   -120,  -6800,   -269,
+       195,   1197,   5500,   -490,   5453,   -201,    411,    823,
+      -146,     46,    252,  -2724,    606,   -924,  -1538,    394,
+      -420,   6405,  -5632,   -941,   -402,   -137,    984,    -24,
+       594,    -40,   -140,    -20,    204,   1211,    290,   -680,
+       103,   -434,   -294,   1646,   -159,  -2296,   -237,    507,
+       -67,  -8999,    -97,    403,  -1473,   -111,     22,   -257,
+     -2203,   -600,    577,   -117,     48,   2216,   -170,   1192,
+       700,   -477,   1678,    979,   2395,    -69,  -1746,  -2139,
+      -294,  -4210,    181,   -372,    320,   -180,   -503,   -550,
+     -3994,  -6315,    502,   -804,   -432,   -112,   -457,  -1016,
+       637,    297,    932,    533,    798,    229,  -1001,  -2780,
+     -4009,   1176,    189,  -1575,     21,   3512,   -348,  -1450,
+      2488,    463,    611,    -46,     85,     94,   3319,  -3041,
+      -362,   -261,  -1534,  -1900,      7,   -519,    -52,   1166,
+      -174,   -152,   -189,   -415,    641,     27,   1764,    280,
+      -301,   2976,    146,   -632,   4022,  -1994,    -84,    -61,
+     -1633,    285,   -439,    781,   -592,    399,  -4794,    203,
+      -295,     32,  -1423,    216,  -2773,     -9,   3589,  -3952,
+      -195,    161,   -223,  -2240,  -1886,  -2643,    978,    113,
+     -1019,   1645,   1493,   -851,   1417,    -74,    717,    411,
+       887,  -1384,     73,    117,    -65,     -7,    133,     18,
+        69,     11,    -98,     45,  -1751,  -2710,     11,   -140,
+        29,    185,    327,    705,     56,    152,   8202,   -117,
+       157,   -478,     36,   -564,    996,  -9359,   -707,    674,
+      1169,    270,    156,   -679,     15,    720,    -38,  -4952,
+      -196,    183,   -356,  -1004,    185,   -148,    -61,    151,
+      -229,   -161,     23,   4350,   -650,  -4384,    -21,    909,
+       105,   -271,  -2538,  -4018,  -1268,    351,    396,   -190,
+      -135,    970,   3159,   -935,  -6968,   -131,  -1031,     53,
+      -430,    242,   -219,    384,   2832,   -151,    152,  -6891,
+      1444,    -63,    -46,     72,    653,   3955,  -4187,   -321,
+      -298,    678,   -471,    664,    -42,    -30,    825,    195,
+     -1147,  -2728,   -178,  -2305,    680,   1980,   -147,    320,
+      -348,   4307,    806,   -263,    -60,   -102,      8, -10085,
+       626,   -130,    267,   -621,     45,   -157,    438,    190,
+        78,   1608,   -246,   -386,    256,   -255,   5651,   -449,
+       -13,    198,  -3193,    329,   -500,  -1368,  -6647,    609,
+      -507,    -96,    222,  -1196,    171,    -12,   -299,  -1423,
+       442,     47,     -5,   -282,    -18,   4969,  -1764,    231,
+      -471,   5044,    412,   1496,   -146,     35,   5083,   -228,
+       355,   -482,  -1063,   1265,     80,  -1278,   1225,    826,
+     -1914,    779,    439,   -511,  -4177,    425,    -38,    -55,
+      9786,   1005,   -538,   -664,   -641,    638,    125,  -2811,
+      2308,     28,  -1157,   -229,   -624,     45,    354,   -368,
+     -1661,     90,    778,   -328,    272,   -223,   9558,    822,
+      -167,    -12,  -1020,   2962,   2372,   -932,   1961,   1398,
+      2660,      3,    235,    421,    114,   -283,    371,  -1652,
+       329,   -435,   -113,  -1296,   -501,   -686,    297,   -384,
+     10328,    472,    614,    139,   -765,   -309,    180,  -2009,
+      -171,   -175,   3571,    146,     46,  -1356,   -134,    -15,
+      -166,   2046,    108,    119,   -281,    971,   -471,  -1134,
+        34,   -104,    219,    746,   -223,    245,   -181,     12,
+      -165,    216,   -792,     86,    562,  -1807,   -116,  -1324,
+       590,   -320,    -80,   1863,   -420,  -1066,   -698,  -2879,
+        -6,    182,  -2325,    575,     97,  -2616,   2938,   -673,
+      -693,   -116,   1905,   -430,   4739,    -12,  -3307,    693,
+      -227,    223,   -111,  -1498,      5,   1751,    -36,    234,
+     -4584,    838,   -370,   -296,   -818,    337,    -46,  -8921,
+       875,   -423,    496,  -1196,    -24,  -1014,    969,    294,
+       237,  -1733,     27,   2543,   1494,    190,    457,  -1391,
+      1209,   5651,    548,    504,    686,  -2889,   -151,    725,
+       486,  -3716,   -285,    830,     31,   5132,    770,    -24,
+      -482,   -369,   -126,  -1552,   -347,   -272,   -387,  -9485,
+     -1547,  -1189,    369,    812,    311,    536,    391,    361,
+     -1708,   -288,    -94,   2053,    557,   -611,  -4551,  -2368,
+       173,    472,    160,  -1849,     96,  -7569,    183,    484,
+      -393,   -346,   -309,    -13,     -7,      2,   -239,  10395,
+      -587,   -115,   1282,   -634,     81,     90,   -725,  -2685,
+     -1214,  -4455,  -1897,  -2903,   -827,    124,   2215,    696,
+     -1225,  -1353,   -371,    343,    421,   -640,   1480,  -1174,
+        76,   -835,   -716,   -625,   -547,   1250,  -2696,   2132,
+      -548,    439,   -607,    408,   -221,   5026,    352,   -344,
+     -1339,   -602,  -1650,   -404,   -458,   -502,     61,   -164,
+        53,    -26,  -2652,   -209,     64,  -4068,    713,    193,
+      -117,  -1290,     95,    -86,   -515,   1336,   -492,   1654,
+     -2963,   3663,  -4231,     -1,   3017,    371,    276,     -7,
+      -289,    -33,  -5942,    237,     30,    586,   -264,   -493,
+       435,   -388,   -165,  10434,    192,   3897,  -5414,    361,
+       845,   -259,    481,    331,    650,   -232,     23,  -1789,
+        27,  -4065,   1020,  -4261,   -651,   3174,    951,  -3363,
+       577,   -112,    642,  -1177,  -1707,    492,   -250,  -1236,
+        24,  -1394,  -1807,   -853,   1681,    -69,    851,   -959,
+     -5759,   -202,     30,  -3466,   -593,   5414,     65,    141,
+      -319,    674,   1183,   -155,   -312,    372,   2829,    -75,
+       -60,  -2618,   -240,   2944,   -631,  -4221,    -16,    467,
+       211,    -58,     55,   -527,    -51,   -160,    642,   -305,
+       388,    413,    210,    -81,  -3383,   -120,    144,   -220,
+      -672,   1352,   -630,  -2324,   -423,  -8053,   -131,   -912,
+      -260,   -380,    470,    154,  -1346,  -2417,   -426,   -403,
+      -137,   -160,   2823,    609,   -216,   -173,   -585,   -514,
+        95,   -202,    222,     16,    136,   1751,    237,  -1089,
+       957,   -144,   -518,    416,   -347,    -60,    207,    277,
+       512,  -1133,    166,   1423,   -883,   -194,  -7016,  -1938,
+       417,   2302,   -992,   -179,    738,    -74,    411,   -462,
+      -413,     67,    234,   -322,   -164,    -47,    -89,   1409,
+       390,  -1180,  -2888,    655,   1958,      0,  -1826,   -471,
+     -1247,    307,    104,  -8502,   -198,   -222,    191,    281,
+      -868,     47,  -4553,   2434,    174,    263,   2844,    -72,
+      -597,  -1183,   -374,    -93,   3348,     13,    173,   6285,
+       -32,   -213,   1882,    411,   -608,   -562,   2998,    293,
+        54,   -147,   -120,    822,    -93,    679,    206,  -3229,
+      -767,  -1603,   -259,   -310,   4306,    548,     -9,    -99,
+     -5722,   -328,   -176,    453,    338,  -9687,    -63,    844,
+       322,    615,  -1075,   -370,    159,    -33,  -6213,  -1375,
+       741,   -801,  -1319,   1513,   1331,    -69,   2702,   -458,
+      -203,    103,   4696,   -284,    465,    -62,    -40,   3184,
+       238,  -6131,    546,   1713,   -365,    -24,    116,    -33,
+       304,    807,   -231,    291,    903,    749,   -254, -12215,
+       115,    -35,    -95,   -166,  -3776,   -170,  -4517,   -151,
+        67,  -7725,    666,   -573,   -744,   -719,     37,     31,
+       373,    148,   -125,     15,   -150,   -905,    -42,    272,
+     -5223,    650,   5233,    109,  -1235,    991,    211,   1522,
+      -555,   -328,    -52,   5335,    -22,  -5476,  -3102,   -637,
+       986,    468,    -37,   -164,   -264,  -1290,    754,   -940,
+      -685,   -862,   7270,   -279,   -441,    472,   -153,  -2515,
+      3899,    -95,    360,    762,     14,    434,    619,    185,
+      -230,   1233,  -1330,   1360,   -756,    361,  -1391,   -247,
+       120,  -3573,    293,    375,    806,   5526,    536,    137,
+       486,   -484,     13,    -37,     12,     -4,     81,     43,
+        10,     43,    -38,   -371,    -64,  -1167,   -117,   -371,
+     -1958,   -166,    543,    -97,    -83,    391,    -59,  -1631,
+       302,   1077,   -128,   -641,    -64,     21,  -2562,   -235,
+       342,  -7121,   -646,    -49,   -961,   -141,   -210,   -555,
+     -1596,   -988,    723,   -209,  -3585,     10,    -35,   1051,
+         0,    138,    941,  -5002,    805,   3009,     35,    -70,
+       513,    -21,   -432,   -224, -10628,   -167,  -1045,   2603,
+       336,    360,    515,    683,    981,   3028,    492,   -543,
+     -1844,     23,    -30,     52,    -40,    447,     11,    363,
+       -95,   1609,   2613,    -13,   -400,    719,  -4513,   -676,
+      -290,    456,   -332,    -11,   -261,   -455,     89,   -301,
+       285,    287,    202,    281,     87,   -202,  -1482,   -535,
+       874,   -478,   -201,   4715,    824,   -204,    145,   2882,
+       404,   3376,    363,    -18,   -127,    764,    106,   1626,
+       178,    185,     22,   -637,  -6216,   1399,   -961,    -88,
+      -553,    -91,     98,   1831,      9,   -583,   1253,  -1741,
+};
+
+static const int16_t shape44s[] = {
+       -20,   -140,    683,   -586,  -1742,    177,   -538,   1900,
+      2193,    -17,  -2096,    261,    645,    339,     77,   1136,
+      -521,    537,   -924,   -156,   -261,    195,   1049,    -39,
+       236,   -137,      0,   3199,    225,     46,     86,   -215,
+       557,  -5394,     17,    911,  -1690,    -48,    -48,   -175,
+       -11,   -631,   -153,   4474,   -347,    -39,   1759,    154,
+       170,   -180,   -273,    603,   -590,  -5195,    -74,   1789,
+       240,   -212,    431,   2447,    368,    -76,   -313,     11,
+     -2926,     19,    -71,    208,    -51,   -728,  -6412,    -61,
+       141,   -112,   5280,    -76,   4435,   -402,    -25,     46,
+       210,   -104,    172,  -3830,   -366,    -23,    239,   -112,
+       137,   6692,  -6288,   -720,   -132,   -136,    552,  -1688,
+      -345,   -289,   -485,    149,    174,    180,    361,   -236,
+        92,    407,      6,   2373,    380,   -167,    845,    444,
+      -834,  -9358,    413,  -1302,    460,     77,     34,     56,
+     -1516,   -143,    207,    -43,    -31,   -106,    -52,    403,
+      -309,    298,    -88,   1552,   -240,   -776,    624,  -4181,
+      -342,  -4804,     57,    -23,    160,    -44,    469,    -17,
+     -3997,  -5079,   -263,     72,    181,   1085,    538,   -611,
+      -368,     59,   -204,   -195,    -40,   -201,   -803,  -5093,
+     -3216,    480,     46,   -729,    244,   3320,    185,    503,
+      2979,   -416,    110,     25,    140,   -502,   2236,  -4420,
+       -36,   -238,   -278,     60,    -82,   -597,    218,     69,
+       -95,  -2102,  -2138,  -2308,  -3796,     20,   -211,   -229,
+       297,   3665,     81,    148,   1315,  -4537,    -38,    186,
+     -3106,   -526,     90,    -35,   -193,   -302,  -5860,    276,
+      -308,    206,    645,      1,   -242,    580,   3025,  -2583,
+       -90,    511,   -315,   -137,  -2033,  -4313,    693,    485,
+      -211,   1486,   1180,    181,   -136,    204,     23,    383,
+      1479,   -213,     42,     32,    -64,   -136,    -91,   -146,
+       434,    231,     36,    -58,  -3254,  -2647,    -18,    345,
+       171,    -60,     84,    209,    246,   -587,   9447,    -67,
+      -187,   -108,   -226,   -458,   -519, -11089,   -422,   -502,
+       132,     79,    298,   -475,   -412,    196,   -164,  -7347,
+       185,   -131,    369,     18,   -500,    644,   -334,     93,
+       -77,     71,    341,   3566,   -281,  -4191,   -145,     87,
+        37,    306,  -3482,  -5739,    161,   -245,    293,    208,
+       380,   2888,     31,    -23,  -2061,   -597,    -56,    350,
+      -105,   1167,     64,    342,   3638,    -79,   -106,    148,
+      5422,   -719,   -232,      8,   -395,   3249,  -5093,   -222,
+      -707,    241,    318,    735,    376,     78,   -166,  -1614,
+        -9,  -3373,    330,  -1540,   2028,   3400,     -9,    317,
+         9,   4903,    262,     62,    222,    -95,   -208, -13376,
+      -101,    121,    298,      5,    172,    406,   -164,     79,
+       172,   1993,    235,    229,   1193,   -274,   5944,   -918,
+       -15,   1304,    307,   1150,   -385,   -794,  -3467,    660,
+      2143,    147,   -279,   -751,   -305,   1052,    205,   -108,
+       572,   -212,     29,    -50,      6,   3749,    238,  -2016,
+     -1118,  -1329,   -971,   2633,    519,    194,   3545,    -11,
+        77,    -92,   1215,   -439,    152,   -863,   1604,    180,
+      -514,    252,    308,   -131,   -938,    133,    378,     11,
+     12153,     51,    486,     71,   -476,   -599,     57,   -127,
+      2685,   -173,   -182,    468,  -3469,   -594,   -380,    265,
+      -879,   -352,   -278,   -309,    575,    124,  10814,   -765,
+       -64,    710,   -105,    296,   2562,     98,   -358,    556,
+      2921,   -133,     -5,   -406,     42,    496,  -1053,  -1957,
+       701,    266,    260,   -441,     43,   -192,     -1,  -2174,
+      9894,    -90,   -181,     29,     50,   -858,     59,   -190,
+        49,   -282,   1632,   1525,    100,  -3659,     13,    173,
+      -240,   5304,   -383,    263,   -311,   1747,    169,  -2203,
+       -29,   -106,    342,   -301,     66,     49,     23,    857,
+      -607,    698,  -1198,   -191,   -450,  -1875,   -329,  -2156,
+       156,     95,    145,    129,   -321,     88,   1049,   3980,
+       -14,    321,  -1484,    895,    -30,  -2174,    289,    933,
+      -933,     15,   2631,     68,   3054,    221,    -87,    175,
+       200,    937,    -87,  -2032,    348,    146,   -372,     60,
+     -2566,   3497,    -98,    313,    536,   -299,    -58,  -8949,
+       323,   -524,   -331,    713,    -47,    360,    155,    168,
+       687,  -1391,   1973,    670,    788,   -202,   -129,  -5113,
+        54,   1178,   1218,    172,    630,   -154,  -1047,    840,
+        71,   -337,     91,    214,   -474,    624,   -773,     16,
+      -126,    340,   -631,   -482,   -155,    419,     50, -10976,
+      -742,   -781,    169,    149,     33,   -169,     44,    354,
+        26,    129,   -179,   1401,    776,   -155,  -3996,   -813,
+       594,    238,    -61,    168,   -383,  -9261,    294,    470,
+      -322,   -190,   -956,   -290,     27,   -438,   -254,  12571,
+       344,   -393,   -568,     56,     81,    171,   -115,  -4370,
+        49,   -322,   -237,   -692,    -55,    -49,   4317,     -6,
+     -4837,   -156,    179,    247,   -338,    -48,    952,  -1061,
+       -33,   -934,    250,   -256,  -1622,   1039,   -738,   2719,
+       -20,   -190,    249,   -119,   -235,   6080,    123,   -502,
+     -1443,     86,  -1684,   -177,   -128,    -58,   -237,   -641,
+      -177,     64,  -2416,     15,   -116,  -6465,   -412,    161,
+       419,    768,     36,    113,   -944,   -241,  -1424,    -95,
+       635,   1798,  -2257,    -18,   3046,    173,    -33,   -207,
+       -52,   -831,  -5730,    -54,   -199,    194,   -255,    467,
+      -211,   -853,   -512,  11619,    148,   3681,  -4603,   -282,
+       129,   -205,   -606,    167,    306,    464,    485,   -959,
+      -203,    254,    151,  -6880,   -262,   5180,    658,  -1378,
+      1174,    -53,    -59,    -33,  -3077,   -127,   -223,    -17,
+       -31,  -2190,     23,    317,   -169,    203,   -223,   -222,
+     -5295,    116,     80,  -2757,   -666,   3377,   -476,     85,
+      -630,   -147,   1740,   -175,   -115,    207,    240,   -248,
+       -95,  -1016,   3966,   3998,   -343,  -4751,    187,   -113,
+      -250,    111,   -510,   -203,    130,     89,    311,    608,
+      -221,   -381,   -253,   -359,  -2254,     45,    224,   -141,
+        45,    -19,    480,  -5074,    797,  -4580,   -163,    110,
+      -234,    337,      6,    707,    492,  -5493,  -2750,    -94,
+      -363,    113,   2345,    344,    379,    464,  -3222,    -56,
+      -269,   -262,    -10,   -609,    324,   3043,    209,   3092,
+      -600,     42,   -615,    -17,    -53,     30,   1123,    224,
+       593,    632,    -90,    428,   1117,  -1429,  -6741,    -95,
+      -293,   -103,  -2784,    251,   1688,    621,   -349,   1059,
+     -1093,   -148,    447,    149,     88,     92,    687,   1249,
+        80,    289,  -1841,    221,    -10,    -92,  -1736,    118,
+       136,    138,   -162,  -4162,   -111,     62,     95,    166,
+      -172,   -695,  -3685,   5694,   -527,   2032,   -549,     43,
+      -101,    221,    181,   -479,   7697,   2007,   -127,    805,
+       -83,   -535,   1354,   -383,    253,   -622,   2910,   1249,
+       782,     13,     42,    994,   -545,     75,   -485,    330,
+       -16,    343,    272,   -781,    360,    -97,    -25,   -875,
+    -12689,   -623,   -307,    195,   -256, -11644,    229,    180,
+       -42,   -361,   -124,    -81,    -23,   -460,  -1993,    212,
+      -634,   -847,   1616,   -546,   -583,     99,   3800,     10,
+       177,    366,   6106,   -173,    265,   -213,     10,   1108,
+      -288,  -1690,   -237,   -312,     38,  -2272,    431,    -26,
+      -178,   -764,    507,    355,    677,   -214,   -816, -12411,
+        47,     12,    294,   -295,  -3916,   -677,  -4885,   -250,
+      -453,  -7716,    478,    231,     17,   -248,    147,   1064,
+       637,    -80,    -41,    265,   -383,    142,    116,   2991,
+     -3060,    809,   2056,   -119,   -866,    -22,   -660,    233,
+       306,  -1873,  -1141,   6995,    186,  -8678,   -109,    -39,
+      -105,    730,     18,   -846,    273,  -2922,    210,     26,
+      -174,   -142,    990,    131,   -436,   1422,   -217,  -3152,
+      3224,     35,    315,    -47,     48,   -221,    568,     44,
+       182,   1696,  -1755,   -193,    527,    158,   -555,  -3485,
+       171,  -4552,    -47,  -4680,     95,   -112,    184,     80,
+       -36,   -915,     87,     24,   -259,  -1743,     68,   -117,
+       405,     11,     40,   -320,    -17,   -158,   -134,   -186,
+     -1206,   -466,   1262,    133,   -254,   -100,    210,  -1735,
+      -636,    319,   -978,     69,    197,   -521,  -5503,    -78,
+      -544,  -1011,    101,   -489,   -371,    -79,   -196,    -18,
+      -839,   1091,    682,  -1441,  -2375,  -1127,     54,    829,
+      -306,   -255,    641,  -3665,    473,   3504,  -1035,   -160,
+      -467,   -275,   -437,     79, -13513,    326,    132,     82,
+       188,    362,    -74,   1406,    -46,   2864,    351,   -558,
+     -1277,    108,    -92,    -53,     72,    -41,    -31,    -97,
+       353,     73,   1864,   -207,    106,    -81,  -3930,    173,
+        41,   -539,   -497,    135,   -526,   -823,     69,    -10,
+       176,    648,  -1710,    564,     80,    237,  -1956,    234,
+        11,    142,   -849,   4116,   -473,    110,    129,   2137,
+      -170,   3193,     10,    245,   -953,   -827,    -30,   1235,
+       366,    -67,     54,   -567,  -7377,   2461,    582,     74,
+     -1988,    -33,   -296,   3090,    -54,    145,    564,   -295,
+};
+
+static const uint16_t bark_tab_l8_512[] = {
+    4,  5,  4,  5,  4,  5,  5,  5,  5,  6,  6,  6,  6,  8,  7,  9,
+    9, 11, 11, 14, 15, 17, 20, 24, 28, 34, 41, 51, 64, 83,
+};
+
+static const uint16_t bark_tab_m8_256[] = {
+    3, 4, 3, 4, 3, 4, 4, 5, 5, 6, 6, 8, 9, 11, 13, 17, 23, 29, 41, 58
+};
+
+static const uint16_t bark_tab_s8_64[] = {
+    2, 1, 2, 2, 3, 4, 5, 7, 13, 25
+};
+
+static const uint16_t bark_tab_l8s_512[] = {
+      7,   8,   7,   8,   8,   8,   8,   8,
+      8,   9,   9,  10,  10,  11,  11,  12,
+     12,  14,  15,  16,  18,  19,  21,  24,
+     27,  30,  35,  40,  46,  53,
+};
+
+static const uint16_t bark_tab_s8s_64[] = {
+      3,   3,   3,   3,   4,   5,   6,   8,
+     12,  17,
+};
+
+static const uint16_t bark_tab_m8s_256[] = {
+      6,   5,   6,   6,   6,   6,   7,   7,
+      8,   8,   9,  10,  11,  13,  15,  18,
+     20,  25,  31,  39,
+};
+
+static const uint16_t bark_tab_l11_512[] = {
+      4,   4,   5,   4,   5,   4,   5,   6,
+      6,   6,   7,   8,   9,  10,  12,  14,
+     17,  21,  27,  33,  44,  58,  82, 121,
+};
+
+static const uint16_t bark_tab_s11_64[] = {
+      2,   1,   2,   3,   4,   6,  13,  33,
+};
+
+static const uint16_t bark_tab_m11_256[] = {
+      3,   3,   4,   3,   4,   4,   5,   6,
+      7,   9,  11,  15,  21,  30,  48,  83,
+};
+
+static const uint16_t bark_tab_l11s_512[] = {
+      6,   6,   6,   6,   6,   6,   7,   6,
+      7,   7,   8,   8,   8,   9,  10,  10,
+     11,  13,  13,  15,  17,  18,  21,  25,
+     27,  33,  38,  45,  54,  66,
+};
+
+static const uint16_t bark_tab_s11s_64[] = {
+      2,   3,   2,   3,   3,   4,   6,   8,
+     12,  21,
+};
+
+static const uint16_t bark_tab_m11s_256[] = {
+      4,   5,   4,   5,   5,   5,   6,   5,
+      7,   7,   8,   9,  10,  12,  15,  17,
+     22,  28,  35,  47,
+};
+
+static const uint16_t bark_tab_l16_1024[] = {
+     5,  5,  5,  5,  5,  5,  5,  6,  6,  7,  7,   7,   8,   9, 10, 11,
+    12, 14, 17, 19, 22, 27, 33, 40, 51, 64, 84, 114, 164, 257
+};
+
+static const uint16_t bark_tab_m16_512[] = {
+     3,  3,  3,  3,  4,  3,  4,   4,  4,  5,  5,  6,  7,  8, 10, 12,
+    14, 18, 24, 30, 42, 59, 89, 152
+};
+
+static const uint16_t bark_tab_s16_128[] = {
+    2, 2, 2, 3, 3, 5, 7, 12, 25, 67
+};
+
+static const uint16_t bark_tab_s16_64[] = {
+    1, 1, 2, 2, 3, 6, 11, 38
+};
+
+static const uint16_t bark_tab_l16s_1024[] = {
+      9,   9,   8,   9,  10,   9,  10,  10,
+     10,  12,  11,  13,  13,  14,  16,  17,
+     19,  20,  24,  26,  30,  35,  40,  48,
+     56,  68,  83, 102, 128, 165,
+};
+
+static const uint16_t bark_tab_s16s_128[] = {
+      3,   4,   4,   4,   5,   7,  10,  16,
+     26,  49,
+};
+
+static const uint16_t bark_tab_m16s_512[] = {
+      7,   6,   7,   7,   7,   8,   9,   9,
+     10,  11,  14,  15,  18,  22,  27,  34,
+     44,  59,  81, 117,
+};
+
+static const uint16_t bark_tab_l22_1024[] = {
+      3,   4,   3,   4,   3,   4,   4,   4,
+      4,   4,   5,   5,   5,   6,   7,   7,
+      8,   9,  11,  12,  14,  16,  20,  24,
+     29,  36,  45,  60,  80, 113, 173, 302,
+};
+
+static const uint16_t bark_tab_s22_128[] = {
+      1,   2,   1,   2,   3,   4,   6,  10,
+     23,  76,
+};
+
+static const uint16_t bark_tab_m22_512[] = {
+      3,   2,   3,   3,   3,   4,   3,   5,
+      4,   6,   7,   8,  10,  14,  18,  25,
+     36,  55,  95, 208,
+};
+
+static const uint16_t bark_tab_l22s_1024[] = {
+      6,   7,   6,   6,   7,   7,   7,   7,
+      7,   8,   9,   8,  10,  10,  11,  12,
+     13,  15,  16,  18,  21,  24,  27,  33,
+     38,  46,  55,  68,  84, 107, 140, 191,
+};
+
+static const uint16_t bark_tab_s22s_128[] = {
+      3,   2,   3,   4,   4,   6,   9,  14,
+     26,  57,
+};
+
+static const uint16_t bark_tab_m22s_512[] = {
+      5,   5,   5,   6,   5,   7,   6,   7,
+      9,   9,  11,  13,  15,  20,  24,  33,
+     43,  61,  88, 140,
+};
+
+static const uint16_t bark_tab_l44_2048[] = {
+     5,  6,  5,   6,   5,   6,   6,   6,  6,  6,  7,  7,  7,  8,  8,  9,
+     9, 10, 11,  11,  13,  14,  16,  17, 19, 22, 25, 29, 33, 39, 46, 54,
+    64, 79, 98, 123, 161, 220, 320, 512,
+};
+
+static const uint16_t bark_tab_m44_512[] = {
+     3,  2,  3,   3,  3,  4,  3,  5,  4,  6,  7,  8, 10, 14, 18, 25,
+    36, 55, 95, 208,
+};
+
+static const uint16_t bark_tab_s44_128[] = {
+    1, 2, 1, 2, 3, 4, 6, 10, 23, 76
+};
+
+const TwinVQModeTab ff_metasound_mode0806 = {
+    {
+        {  8, bark_tab_s8_64,  10, fcb8s, 1, 5, cb0806ss0, cb0806ss1, 27 },
+        {  2, bark_tab_m8_256, 20, fcb8m, 2, 5, cb0806sm0, cb0806sm1, 22 },
+        {  1, bark_tab_l8_512, 30, fcb8l, 3, 6, cb0806sl0, cb0806sl1, 24 }
+    },
+    512, 12, lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200
+};
+
+const TwinVQModeTab ff_metasound_mode0806s = {
+    {
+        {  8, bark_tab_s8s_64,  10, fcb8ss, 1, 5, cb0806ss0, cb0806ss1, 27 },
+        {  2, bark_tab_m8s_256, 20, fcb8sm, 2, 5, cb0806sm0, cb0806sm1, 22 },
+        {  1, bark_tab_l8s_512, 30, fcb8sl, 3, 6, cb0806sl0, cb0806sl1, 24 }
+    },
+    512, 12, lsp8s, 1, 5, 3, 3, shape8s, 8, 28, 20, 6, 200
+};
+
+const TwinVQModeTab ff_metasound_mode0808 = {
+    {
+        { 8, bark_tab_s8_64,  10, fcb8s, 1, 5, cb0808s0, cb0808s1, 18 },
+        { 2, bark_tab_m8_256, 20, fcb8m, 2, 5, cb0808m0, cb0808m1, 16 },
+        { 1, bark_tab_l8_512, 30, fcb8l, 3, 6, cb0808l0, cb0808l1, 17 }
+    },
+    512, 12, lsp8, 1, 5, 3, 3, shape8, 8, 28, 20, 6, 200
+};
+
+const TwinVQModeTab ff_metasound_mode0808s = {
+    {
+        {  8, bark_tab_s8s_64,  10, fcb8ss, 1, 5, cb0808ss0, cb0808ss1, 18 },
+        {  2, bark_tab_m8s_256, 20, fcb8sm, 2, 5, cb0808sm0, cb0808sm1, 16 },
+        {  1, bark_tab_l8s_512, 30, fcb8sl, 3, 6, cb0808sl0, cb0808sl1, 17 }
+    },
+    512, 12, lsp8s, 1, 5, 3, 3, shape8s, 8, 28, 20, 6, 200
+};
+
+const TwinVQModeTab ff_metasound_mode1110 = {
+    {
+        {  8, bark_tab_s11_64,   8, fcb11s, 1, 5, cb1110s0, cb1110s1, 21 },
+        {  2, bark_tab_m11_256, 16, fcb11m, 2, 5, cb1110m0, cb1110m1, 18 },
+        {  1, bark_tab_l11_512, 24, fcb11l, 3, 6, cb1110l0, cb1110l1, 19 }
+    },
+    512, 16, lsp11, 1, 6, 4, 3, shape11, 9, 28, 20, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode1110s = {
+    {
+        {  8, bark_tab_s11s_64,  10, fcb11ss, 1, 5, cb1110ss0, cb1110ss1, 21 },
+        {  2, bark_tab_m11s_256, 20, fcb11sm, 2, 5, cb1110sm0, cb1110sm1, 18 },
+        {  1, bark_tab_l11s_512, 30, fcb11sl, 3, 6, cb1110sl0, cb1110sl1, 20 }
+    },
+    512, 16, lsp11s, 1, 6, 4, 3, shape11s, 9, 36, 30, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode1616 = {
+    {
+        { 8, bark_tab_s16_128,  10, fcb16s, 1, 5, cb1616s0, cb1616s1, 16 },
+        { 2, bark_tab_m16_512,  24, fcb16m, 2, 5, cb1616m0, cb1616m1, 15 },
+        { 1, bark_tab_l16_1024, 30, fcb16l, 3, 6, cb1616l0, cb1616l1, 16 }
+    },
+    1024, 16, lsp16, 1, 6, 4, 3, shape16, 9, 28, 30, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode1616s = {
+    {
+        { 8, bark_tab_s16s_128,  10, fcb16ss, 1, 5, cb1616ss0, cb1616ss1, 16 },
+        { 2, bark_tab_m16s_512,  20, fcb16sm, 2, 5, cb1616sm0, cb1616sm1, 15 },
+        { 1, bark_tab_l16s_1024, 30, fcb16sl, 3, 6, cb1616sl0, cb1616sl1, 16 }
+    },
+    1024, 16, lsp16, 1, 6, 4, 3, shape16s, 9, 56, 60, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode2224 = {
+    {
+        { 8, bark_tab_s22_128,  10, fcb22s, 1, 6, cb2224s0, cb2224s1, 15 },
+        { 2, bark_tab_m22_512,  20, fcb22m, 2, 6, cb2224m0, cb2224m1, 14 },
+        { 1, bark_tab_l22_1024, 32, fcb22l, 4, 6, cb2224l0, cb2224l1, 15 }
+    },
+    1024, 16, lsp22, 1, 6, 4, 3, shape22, 9, 56, 36, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode2224s = {
+    {
+        { 8, bark_tab_s22s_128,  10, fcb22ss, 1, 6, cb2224ss0, cb2224ss1, 15 },
+        { 2, bark_tab_m22s_512,  20, fcb22sm, 2, 6, cb2224sm0, cb2224sm1, 14 },
+        { 1, bark_tab_l22s_1024, 32, fcb22sl, 4, 6, cb2224sl0, cb2224sl1, 15 }
+    },
+    1024, 16, lsp22s, 1, 6, 4, 3, shape22s, 9, 56, 36, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode4432 = {
+    {
+        { 16, bark_tab_s44_128,  10, fcb44ss, 1, 6, cb4432s0, cb4432s1, 23 },
+        {  4, bark_tab_m44_512,  20, fcb44sm, 2, 6, cb4432m0, cb4432m1, 21 },
+        {  1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4432l0, cb4432l1, 22 }
+    },
+    2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200,
+};
+
+const TwinVQModeTab ff_metasound_mode4432s = {
+    {
+        { 16, bark_tab_s44_128,  10, fcb44ss, 1, 6, cb4432s0, cb4432s1, 23 },
+        {  4, bark_tab_m44_512,  20, fcb44sm, 2, 6, cb4432m0, cb4432m1, 21 },
+        {  1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4432l0, cb4432l1, 22 }
+    },
+    2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200,
+};
+
+const TwinVQModeTab ff_metasound_mode4440 = {
+    {
+        { 16, bark_tab_s44_128,  10, fcb44ss, 1, 6, cb4440ss0, cb4440ss1, 18 },
+        {  4, bark_tab_m44_512,  20, fcb44sm, 2, 6, cb4440sm0, cb4440sm1, 17 },
+        {  1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4440sl0, cb4440sl1, 17 }
+    },
+    2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode4440s = {
+    {
+        { 16, bark_tab_s44_128,  10, fcb44ss, 1, 6, cb4440ss0, cb4440ss1, 18 },
+        {  4, bark_tab_m44_512,  20, fcb44sm, 2, 6, cb4440sm0, cb4440sm1, 17 },
+        {  1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4440sl0, cb4440sl1, 17 }
+    },
+    2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode4448 = {
+    {
+        { 16, bark_tab_s44_128,  10, fcb44ss, 1, 6, cb4448ss0, cb4448ss1, 15 },
+        {  4, bark_tab_m44_512,  20, fcb44sm, 2, 6, cb4448sm0, cb4448sm1, 14 },
+        {  1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4448sl0, cb4448sl1, 14 }
+    },
+    2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200
+};
+
+const TwinVQModeTab ff_metasound_mode4448s = {
+    {
+        { 16, bark_tab_s44_128,  10, fcb44ss, 1, 6, cb4448ss0, cb4448ss1, 15 },
+        {  4, bark_tab_m44_512,  20, fcb44sm, 2, 6, cb4448sm0, cb4448sm1, 14 },
+        {  1, bark_tab_l44_2048, 40, fcb44sl, 4, 6, cb4448sl0, cb4448sl1, 14 }
+    },
+    2048, 20, lsp44s, 1, 6, 4, 4, shape44s, 9, 84, 54, 7, 200
+};
diff --git a/libavcodec/metasound_data.h b/libavcodec/metasound_data.h
new file mode 100644
index 0000000..4925516
--- /dev/null
+++ b/libavcodec/metasound_data.h
@@ -0,0 +1,49 @@
+/*
+ * MetaSound decoder
+ * Copyright (c) 2013 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
+ */
+
+#ifndef AVCODEC_METASOUND_DATA_H
+#define AVCODEC_METASOUND_DATA_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "twinvq.h"
+
+extern const TwinVQModeTab ff_metasound_mode0806;
+extern const TwinVQModeTab ff_metasound_mode0806s;
+extern const TwinVQModeTab ff_metasound_mode0808;
+extern const TwinVQModeTab ff_metasound_mode0808s;
+extern const TwinVQModeTab ff_metasound_mode1110;
+extern const TwinVQModeTab ff_metasound_mode1110s;
+extern const TwinVQModeTab ff_metasound_mode1616;
+extern const TwinVQModeTab ff_metasound_mode1616s;
+extern const TwinVQModeTab ff_metasound_mode2224;
+extern const TwinVQModeTab ff_metasound_mode2224s;
+extern const TwinVQModeTab ff_metasound_mode2232;
+extern const TwinVQModeTab ff_metasound_mode2232s;
+extern const TwinVQModeTab ff_metasound_mode4432;
+extern const TwinVQModeTab ff_metasound_mode4432s;
+extern const TwinVQModeTab ff_metasound_mode4440;
+extern const TwinVQModeTab ff_metasound_mode4440s;
+extern const TwinVQModeTab ff_metasound_mode4448;
+extern const TwinVQModeTab ff_metasound_mode4448s;
+
+#endif /* AVCODEC_METASOUND_DATA_H */
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 95695de..264c74a 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -28,6 +28,7 @@
 #include "get_bits.h"
 #include "bytestream.h"
 #include "dsputil.h"
+#include "hpeldsp.h"
 #include "thread.h"
 
 #define MIMIC_HEADER_SIZE   20
@@ -44,14 +45,15 @@ typedef struct {
     int             cur_index;
     int             prev_index;
 
-    AVFrame         buf_ptrs    [16];
+    ThreadFrame     frames     [16];
     AVPicture       flipped_ptrs[16];
 
-    DECLARE_ALIGNED(16, DCTELEM, dct_block)[64];
+    DECLARE_ALIGNED(16, int16_t, dct_block)[64];
 
     GetBitContext   gb;
     ScanTable       scantable;
     DSPContext      dsp;
+    HpelDSPContext  hdsp;
     VLC             vlc;
 
     /* Kept in the context so multithreading can have a constant to read from */
@@ -109,37 +111,76 @@ static const uint8_t col_zag[64] = {
     53, 60, 61, 54, 47, 55, 62, 63,
 };
 
+static av_cold int mimic_decode_end(AVCodecContext *avctx)
+{
+    MimicContext *ctx = avctx->priv_data;
+    int i;
+
+    av_free(ctx->swap_buf);
+
+    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
+        if (ctx->frames[i].f)
+            ff_thread_release_buffer(avctx, &ctx->frames[i]);
+        av_frame_free(&ctx->frames[i].f);
+    }
+
+    if (!avctx->internal->is_copy)
+        ff_free_vlc(&ctx->vlc);
+
+    return 0;
+}
+
 static av_cold int mimic_decode_init(AVCodecContext *avctx)
 {
     MimicContext *ctx = avctx->priv_data;
+    int ret, i;
+
+    avctx->internal->allocate_progress = 1;
 
     ctx->prev_index = 0;
-    ctx->cur_index = 15;
+    ctx->cur_index  = 15;
 
-    if(init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
-                 huffbits, 1, 1, huffcodes, 4, 4, 0)) {
+    if ((ret = init_vlc(&ctx->vlc, 11, FF_ARRAY_ELEMS(huffbits),
+                        huffbits, 1, 1, huffcodes, 4, 4, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "error initializing vlc table\n");
-        return -1;
+        return ret;
     }
     ff_dsputil_init(&ctx->dsp, avctx);
+    ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
     ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
 
+    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
+        ctx->frames[i].f = av_frame_alloc();
+        if (!ctx->frames[i].f) {
+            mimic_decode_end(avctx);
+            return AVERROR(ENOMEM);
+        }
+    }
+
     return 0;
 }
 
 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
 {
     MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
+    int i, ret;
 
-    if (avctx == avctx_from) return 0;
+    if (avctx == avctx_from)
+        return 0;
 
     dst->cur_index  = src->next_cur_index;
     dst->prev_index = src->next_prev_index;
 
-    memcpy(dst->buf_ptrs, src->buf_ptrs, sizeof(src->buf_ptrs));
     memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
 
-    memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(AVFrame));
+    for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
+        ff_thread_release_buffer(avctx, &dst->frames[i]);
+        if (src->frames[i].f->data[0]) {
+            ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
+            if (ret < 0)
+                return ret;
+        }
+    }
 
     return 0;
 }
@@ -183,30 +224,30 @@ static const int8_t vlcdec_lookup[9][64] = {
 
 static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
 {
-    DCTELEM *block = ctx->dct_block;
+    int16_t *block = ctx->dct_block;
     unsigned int pos;
 
     ctx->dsp.clear_block(block);
 
     block[0] = get_bits(&ctx->gb, 8) << 3;
 
-    for(pos = 1; pos < num_coeffs; pos++) {
+    for (pos = 1; pos < num_coeffs; pos++) {
         uint32_t vlc, num_bits;
         int value;
         int coeff;
 
         vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
-        if(!vlc) /* end-of-block code */
-            return 1;
-        if(vlc == -1)
+        if (!vlc) /* end-of-block code */
             return 0;
+        if (vlc == -1)
+            return AVERROR_INVALIDDATA;
 
         /* pos_add and num_bits are coded in the vlc code */
-        pos +=     vlc&15; // pos_add
-        num_bits = vlc>>4; // num_bits
+        pos     += vlc & 15; // pos_add
+        num_bits = vlc >> 4; // num_bits
 
-        if(pos >= 64)
-            return 0;
+        if (pos >= 64)
+            return AVERROR_INVALIDDATA;
 
         value = get_bits(&ctx->gb, num_bits);
 
@@ -214,7 +255,7 @@ static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
          * a factor of 4 was added to the input */
 
         coeff = vlcdec_lookup[num_bits][value];
-        if(pos<3)
+        if (pos < 3)
             coeff <<= 4;
         else /* TODO Use >> 10 instead of / 1001 */
             coeff = (coeff * qscale) / 1001;
@@ -222,81 +263,86 @@ static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
         block[ctx->scantable.permutated[pos]] = coeff;
     }
 
-    return 1;
+    return 0;
 }
 
 static int decode(MimicContext *ctx, int quality, int num_coeffs,
                   int is_iframe)
 {
-    int y, x, plane, cur_row = 0;
+    int ret, y, x, plane, cur_row = 0;
 
-    for(plane = 0; plane < 3; plane++) {
+    for (plane = 0; plane < 3; plane++) {
         const int is_chroma = !!plane;
-        const int qscale = av_clip(10000-quality,is_chroma?1000:2000,10000)<<2;
-        const int stride = ctx->flipped_ptrs[ctx->cur_index].linesize[plane];
-        const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
-        uint8_t       *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
-
-        for(y = 0; y < ctx->num_vblocks[plane]; y++) {
-            for(x = 0; x < ctx->num_hblocks[plane]; x++) {
-
+        const int qscale    = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
+                                      10000) << 2;
+        const int stride    = ctx->flipped_ptrs[ctx->cur_index ].linesize[plane];
+        const uint8_t *src  = ctx->flipped_ptrs[ctx->prev_index].data[plane];
+        uint8_t       *dst  = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
+
+        for (y = 0; y < ctx->num_vblocks[plane]; y++) {
+            for (x = 0; x < ctx->num_hblocks[plane]; x++) {
                 /* Check for a change condition in the current block.
                  * - iframes always change.
                  * - Luma plane changes on get_bits1 == 0
                  * - Chroma planes change on get_bits1 == 1 */
-                if(is_iframe || get_bits1(&ctx->gb) == is_chroma) {
-
+                if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
                     /* Luma planes may use a backreference from the 15 last
                      * frames preceding the previous. (get_bits1 == 1)
                      * Chroma planes don't use backreferences. */
-                    if(is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
-
-                        if(!vlc_decode_block(ctx, num_coeffs, qscale))
-                            return 0;
+                    if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
+                        if ((ret = vlc_decode_block(ctx, num_coeffs,
+                                                    qscale)) < 0) {
+                            av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
+                                   "block.\n");
+                            return ret;
+                        }
                         ctx->dsp.idct_put(dst, stride, ctx->dct_block);
                     } else {
                         unsigned int backref = get_bits(&ctx->gb, 4);
-                        int index = (ctx->cur_index+backref)&15;
-                        uint8_t *p = ctx->flipped_ptrs[index].data[0];
+                        int index            = (ctx->cur_index + backref) & 15;
+                        uint8_t *p           = ctx->flipped_ptrs[index].data[0];
 
                         if (index != ctx->cur_index && p) {
-                            ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0);
+                            ff_thread_await_progress(&ctx->frames[index],
+                                                     cur_row, 0);
                             p += src -
-                                ctx->flipped_ptrs[ctx->prev_index].data[plane];
-                            ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8);
+                                 ctx->flipped_ptrs[ctx->prev_index].data[plane];
+                            ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
                         } else {
                             av_log(ctx->avctx, AV_LOG_ERROR,
                                      "No such backreference! Buggy sample.\n");
                         }
                     }
                 } else {
-                    ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index], cur_row, 0);
-                    ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
+                    ff_thread_await_progress(&ctx->frames[ctx->prev_index],
+                                             cur_row, 0);
+                    ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
                 }
                 src += 8;
                 dst += 8;
             }
-            src += (stride - ctx->num_hblocks[plane])<<3;
-            dst += (stride - ctx->num_hblocks[plane])<<3;
+            src += (stride - ctx->num_hblocks[plane]) << 3;
+            dst += (stride - ctx->num_hblocks[plane]) << 3;
 
-            ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], cur_row++, 0);
+            ff_thread_report_progress(&ctx->frames[ctx->cur_index],
+                                      cur_row++, 0);
         }
     }
 
-    return 1;
+    return 0;
 }
 
 /**
  * Flip the buffer upside-down and put it in the YVU order to match the
  * way Mimic encodes frames.
  */
-static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVPicture *src)
+static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
 {
     int i;
-    dst->data[0] = src->data[0]+( ctx->avctx->height    -1)*src->linesize[0];
-    dst->data[1] = src->data[2]+((ctx->avctx->height>>1)-1)*src->linesize[2];
-    dst->data[2] = src->data[1]+((ctx->avctx->height>>1)-1)*src->linesize[1];
-    for(i = 0; i < 3; i++)
+    dst->data[0] = src->data[0] + ( ctx->avctx->height       - 1) * src->linesize[0];
+    dst->data[1] = src->data[2] + ((ctx->avctx->height >> 1) - 1) * src->linesize[2];
+    dst->data[2] = src->data[1] + ((ctx->avctx->height >> 1) - 1) * src->linesize[1];
+    for (i = 0; i < 3; i++)
         dst->linesize[i] = -src->linesize[i];
 }
 
@@ -304,18 +350,18 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
                               int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    MimicContext *ctx = avctx->priv_data;
+    int buf_size       = avpkt->size;
+    int swap_buf_size  = buf_size - MIMIC_HEADER_SIZE;
+    MimicContext *ctx  = avctx->priv_data;
     GetByteContext gb;
     int is_pframe;
     int width, height;
     int quality, num_coeffs;
-    int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
     int res;
 
     if (buf_size <= MIMIC_HEADER_SIZE) {
         av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
@@ -328,99 +374,100 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
     num_coeffs = bytestream2_get_byteu(&gb);
     bytestream2_skip(&gb, 3); /* some constant */
 
-    if(!ctx->avctx) {
+    if (!ctx->avctx) {
         int i;
 
-        if(!(width == 160 && height == 120) &&
-           !(width == 320 && height == 240)) {
+        if (!(width == 160 && height == 120) &&
+            !(width == 320 && height == 240)) {
             av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
 
         ctx->avctx     = avctx;
         avctx->width   = width;
         avctx->height  = height;
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-        for(i = 0; i < 3; i++) {
+        for (i = 0; i < 3; i++) {
             ctx->num_vblocks[i] = -((-height) >> (3 + !!i));
-            ctx->num_hblocks[i] =     width   >> (3 + !!i) ;
+            ctx->num_hblocks[i] =     width   >> (3 + !!i);
         }
-    } else if(width != ctx->avctx->width || height != ctx->avctx->height) {
-        av_log(avctx, AV_LOG_ERROR, "resolution changing is not supported\n");
-        return -1;
+    } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
+        avpriv_request_sample(avctx, "Resolution changing");
+        return AVERROR_PATCHWELCOME;
     }
 
-    if(is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
+    if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
         av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    ctx->buf_ptrs[ctx->cur_index].reference = 1;
-    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])) {
+    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
+    ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
+                                                           AV_PICTURE_TYPE_I;
+    if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
+                                    AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return res;
     }
 
     ctx->next_prev_index = ctx->cur_index;
     ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
 
     prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
-                  (AVPicture*) &ctx->buf_ptrs[ctx->cur_index]);
+                  ctx->frames[ctx->cur_index].f);
 
     ff_thread_finish_setup(avctx);
 
     av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
-    if(!ctx->swap_buf)
+    if (!ctx->swap_buf)
         return AVERROR(ENOMEM);
 
     ctx->dsp.bswap_buf(ctx->swap_buf,
-                        (const uint32_t*) (buf + MIMIC_HEADER_SIZE),
-                        swap_buf_size>>2);
+                       (const uint32_t*) (buf + MIMIC_HEADER_SIZE),
+                       swap_buf_size >> 2);
     init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
 
     res = decode(ctx, quality, num_coeffs, !is_pframe);
-    ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
-    if (!res) {
+    ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
+    if (res < 0) {
         if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
-            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
-            return -1;
+            ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
+            return res;
         }
     }
 
-    *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
+    if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
+        return res;
     *got_frame      = 1;
 
     ctx->prev_index = ctx->next_prev_index;
     ctx->cur_index  = ctx->next_cur_index;
 
     /* Only release frames that aren't used for backreferences anymore */
-    if(ctx->buf_ptrs[ctx->cur_index].data[0])
-        ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
+    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
 
     return buf_size;
 }
 
-static av_cold int mimic_decode_end(AVCodecContext *avctx)
+static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
 {
     MimicContext *ctx = avctx->priv_data;
     int i;
 
-    av_free(ctx->swap_buf);
-
-    if (avctx->internal->is_copy)
-        return 0;
-
-    for(i = 0; i < 16; i++)
-        if(ctx->buf_ptrs[i].data[0])
-            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]);
-    ff_free_vlc(&ctx->vlc);
+    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
+        ctx->frames[i].f = av_frame_alloc();
+        if (!ctx->frames[i].f) {
+            mimic_decode_end(avctx);
+            return AVERROR(ENOMEM);
+        }
+    }
 
     return 0;
 }
 
 AVCodec ff_mimic_decoder = {
     .name                  = "mimic",
+    .long_name             = NULL_IF_CONFIG_SMALL("Mimic"),
     .type                  = AVMEDIA_TYPE_VIDEO,
     .id                    = AV_CODEC_ID_MIMIC,
     .priv_data_size        = sizeof(MimicContext),
@@ -428,6 +475,6 @@ AVCodec ff_mimic_decoder = {
     .close                 = mimic_decode_end,
     .decode                = mimic_decode_frame,
     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
-    .long_name             = NULL_IF_CONFIG_SMALL("Mimic"),
-    .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
+    .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
+    .init_thread_copy      = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
 };
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index 9d5a8f3..a5f32a6 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -45,10 +45,10 @@ static int mjpegb_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     MJpegDecodeContext *s = avctx->priv_data;
     const uint8_t *buf_end, *buf_ptr;
-    AVFrame *picture = data;
     GetBitContext hgb; /* for the header */
     uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;
     uint32_t field_size, sod_offs;
+    int ret;
 
     buf_ptr = buf;
     buf_end = buf + buf_size;
@@ -136,17 +136,13 @@ read_header:
 
     //XXX FIXME factorize, this looks very similar to the EOI code
 
-    *picture= *s->picture_ptr;
+    if ((ret = av_frame_ref(data, s->picture_ptr)) < 0)
+        return ret;
     *got_frame = 1;
 
-    if(!s->lossless){
-        picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]);
-        picture->qstride= 0;
-        picture->qscale_table= s->qscale_table;
-        memset(picture->qscale_table, picture->quality, (s->width+15)/16);
-        if(avctx->debug & FF_DEBUG_QP)
-            av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);
-        picture->quality*= FF_QP2LAMBDA;
+    if (!s->lossless && avctx->debug & FF_DEBUG_QP) {
+        av_log(avctx, AV_LOG_DEBUG, "QP: %d\n",
+               FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]));
     }
 
     return buf_size;
@@ -154,6 +150,7 @@ read_header:
 
 AVCodec ff_mjpegb_decoder = {
     .name           = "mjpegb",
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MJPEGB,
     .priv_data_size = sizeof(MJpegDecodeContext),
@@ -161,5 +158,4 @@ AVCodec ff_mjpegb_decoder = {
     .close          = ff_mjpeg_decode_end,
     .decode         = mjpegb_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"),
 };
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 74bbfa6..839d3c5 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -30,13 +30,11 @@
  * MJPEG decoder.
  */
 
-// #define DEBUG
 #include <assert.h>
 
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "mjpeg.h"
 #include "mjpegdec.h"
@@ -86,10 +84,15 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
 {
     MJpegDecodeContext *s = avctx->priv_data;
 
-    if (!s->picture_ptr)
-        s->picture_ptr = &s->picture;
+    if (!s->picture_ptr) {
+        s->picture = av_frame_alloc();
+        if (!s->picture)
+            return AVERROR(ENOMEM);
+        s->picture_ptr = s->picture;
+    }
 
     s->avctx = avctx;
+    ff_hpeldsp_init(&s->hdsp, avctx->flags);
     ff_dsputil_init(&s->dsp, avctx);
     ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
     s->buffer_size   = 0;
@@ -212,7 +215,7 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
 
 int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 {
-    int len, nb_components, i, width, height, pix_fmt_id;
+    int len, nb_components, i, width, height, pix_fmt_id, ret;
 
     /* XXX: verify len field validity */
     len     = get_bits(&s->gb, 16);
@@ -251,9 +254,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
         }
     }
     if (s->ls && !(s->bits <= 8 || nb_components == 1)) {
-        av_log_missing_feature(s->avctx,
-                               "For JPEG-LS anything except <= 8 bits/component"
-                               " or 16-bit gray", 0);
+        avpriv_report_missing_feature(s->avctx,
+                                      "JPEG-LS that is not <= 8 "
+                                      "bits/component or 16-bit gray");
         return AVERROR_PATCHWELCOME;
     }
     s->nb_components = nb_components;
@@ -285,7 +288,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
     }
 
     if (s->ls && (s->h_max > 1 || s->v_max > 1)) {
-        av_log_missing_feature(s->avctx, "Subsampling in JPEG-LS", 0);
+        avpriv_report_missing_feature(s->avctx, "Subsampling in JPEG-LS");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -295,8 +298,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
     /* if different size, realloc/alloc picture */
     /* XXX: also check h_count and v_count */
     if (width != s->width || height != s->height) {
-        av_freep(&s->qscale_table);
-
         s->width      = width;
         s->height     = height;
         s->interlaced = 0;
@@ -312,9 +313,10 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
             height *= 2;
         }
 
-        avcodec_set_dimensions(s->avctx, width, height);
+        ret = ff_set_dimensions(s->avctx, width, height);
+        if (ret < 0)
+            return ret;
 
-        s->qscale_table  = av_mallocz((s->width + 15) / 16);
         s->first_picture = 0;
     }
 
@@ -365,10 +367,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
             s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
     }
 
-    if (s->picture_ptr->data[0])
-        s->avctx->release_buffer(s->avctx, s->picture_ptr);
-
-    if (ff_get_buffer(s->avctx, s->picture_ptr) < 0) {
+    av_frame_unref(s->picture_ptr);
+    if (ff_get_buffer(s->avctx, s->picture_ptr, AV_GET_BUFFER_FLAG_REF) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -422,7 +422,7 @@ static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index)
 }
 
 /* decode block and dequantize */
-static int decode_block(MJpegDecodeContext *s, DCTELEM *block, int component,
+static int decode_block(MJpegDecodeContext *s, int16_t *block, int component,
                         int dc_index, int ac_index, int16_t *quant_matrix)
 {
     int code, i, j, level, val;
@@ -470,7 +470,7 @@ static int decode_block(MJpegDecodeContext *s, DCTELEM *block, int component,
     return 0;
 }
 
-static int decode_dc_progressive(MJpegDecodeContext *s, DCTELEM *block,
+static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block,
                                  int component, int dc_index,
                                  int16_t *quant_matrix, int Al)
 {
@@ -488,7 +488,7 @@ static int decode_dc_progressive(MJpegDecodeContext *s, DCTELEM *block,
 }
 
 /* decode block and dequantize - progressive JPEG version */
-static int decode_block_progressive(MJpegDecodeContext *s, DCTELEM *block,
+static int decode_block_progressive(MJpegDecodeContext *s, int16_t *block,
                                     uint8_t *last_nnz, int ac_index,
                                     int16_t *quant_matrix,
                                     int ss, int se, int Al, int *EOBRUN)
@@ -586,7 +586,7 @@ for (; ; i++) {                                                     \
 }
 
 /* decode block and dequantize - progressive JPEG refinement pass */
-static int decode_block_refinement(MJpegDecodeContext *s, DCTELEM *block,
+static int decode_block_refinement(MJpegDecodeContext *s, int16_t *block,
                                    uint8_t *last_nnz,
                                    int ac_index, int16_t *quant_matrix,
                                    int ss, int se, int Al, int *EOBRUN)
@@ -877,8 +877,9 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
                     ptr = data[c] + block_offset;
                     if (!s->progressive) {
                         if (copy_mb)
-                            copy_block8(ptr, reference_data[c] + block_offset,
-                                        linesize[c], linesize[c], 8);
+                            s->hdsp.put_pixels_tab[1][0](ptr,
+                                reference_data[c] + block_offset,
+                                linesize[c], 8);
                         else {
                             s->dsp.clear_block(s->block);
                             if (decode_block(s, s->block, i,
@@ -893,7 +894,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
                     } else {
                         int block_idx  = s->block_stride[c] * (v * mb_y + y) +
                                          (h * mb_x + x);
-                        DCTELEM *block = s->blocks[c][block_idx];
+                        int16_t *block = s->blocks[c][block_idx];
                         if (Ah)
                             block[0] += get_bits1(&s->gb) *
                                         s->quant_matrixes[s->quant_index[c]][0] << Al;
@@ -975,7 +976,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
         int block_offset = mb_y * linesize * 8;
         uint8_t *ptr     = data + block_offset;
         int block_idx    = mb_y * s->block_stride[c];
-        DCTELEM (*block)[64] = &s->blocks[c][block_idx];
+        int16_t (*block)[64] = &s->blocks[c][block_idx];
         uint8_t *last_nnz    = &s->last_nnz[c][block_idx];
         for (mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) {
             const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb);
@@ -997,8 +998,9 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
 
             if (last_scan) {
                 if (copy_mb) {
-                    copy_block8(ptr, reference_data + block_offset,
-                                linesize, linesize, 8);
+                    s->hdsp.put_pixels_tab[1][0](ptr,
+                                                 reference_data + block_offset,
+                                                 linesize, 8);
                 } else {
                     s->dsp.idct_put(ptr, linesize, *block);
                     ptr += 8;
@@ -1470,7 +1472,6 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int unescaped_buf_size;
     int start_code;
     int ret = 0;
-    AVFrame *picture = data;
 
     s->got_picture = 0; // picture from previous image can not be reused
     buf_ptr = buf;
@@ -1488,159 +1489,153 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                    "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n",
                    start_code, unescaped_buf_size, buf_size);
             return AVERROR_INVALIDDATA;
-        } else {
-            av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n",
-                   start_code, buf_end - buf_ptr);
+        }
 
-            ret = init_get_bits(&s->gb, unescaped_buf_ptr,
-                                unescaped_buf_size * 8);
+        av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n",
+               start_code, buf_end - buf_ptr);
 
-            if (ret < 0)
-                return ret;
+        ret = init_get_bits(&s->gb, unescaped_buf_ptr,
+                            unescaped_buf_size * 8);
+        if (ret < 0)
+            return ret;
 
-            s->start_code = start_code;
-            if (s->avctx->debug & FF_DEBUG_STARTCODE)
-                av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);
+        s->start_code = start_code;
+        if (s->avctx->debug & FF_DEBUG_STARTCODE)
+            av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);
 
-            /* process markers */
-            if (start_code >= 0xd0 && start_code <= 0xd7)
-                av_log(avctx, AV_LOG_DEBUG,
-                       "restart marker: %d\n", start_code & 0x0f);
-                /* APP fields */
-            else if (start_code >= APP0 && start_code <= APP15)
-                mjpeg_decode_app(s);
-                /* Comment */
-            else if (start_code == COM)
-                mjpeg_decode_com(s);
-
-            if (!CONFIG_JPEGLS_DECODER &&
-                (start_code == SOF48 || start_code == LSE)) {
-                av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n");
-                return AVERROR(ENOSYS);
-            }
+        /* process markers */
+        if (start_code >= 0xd0 && start_code <= 0xd7)
+            av_log(avctx, AV_LOG_DEBUG,
+                   "restart marker: %d\n", start_code & 0x0f);
+            /* APP fields */
+        else if (start_code >= APP0 && start_code <= APP15)
+            mjpeg_decode_app(s);
+            /* Comment */
+        else if (start_code == COM)
+            mjpeg_decode_com(s);
+
+        if (!CONFIG_JPEGLS_DECODER &&
+            (start_code == SOF48 || start_code == LSE)) {
+            av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n");
+            return AVERROR(ENOSYS);
+        }
 
-            switch (start_code) {
-            case SOI:
-                s->restart_interval = 0;
-                s->restart_count    = 0;
-                /* nothing to do on SOI */
-                break;
-            case DQT:
-                ff_mjpeg_decode_dqt(s);
-                break;
-            case DHT:
-                if ((ret = ff_mjpeg_decode_dht(s)) < 0) {
-                    av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");
-                    return ret;
-                }
-                break;
-            case SOF0:
-            case SOF1:
-                s->lossless    = 0;
-                s->ls          = 0;
-                s->progressive = 0;
-                if ((ret = ff_mjpeg_decode_sof(s)) < 0)
-                    return ret;
-                break;
-            case SOF2:
-                s->lossless    = 0;
-                s->ls          = 0;
-                s->progressive = 1;
-                if ((ret = ff_mjpeg_decode_sof(s)) < 0)
-                    return ret;
-                break;
-            case SOF3:
-                s->lossless    = 1;
-                s->ls          = 0;
-                s->progressive = 0;
-                if ((ret = ff_mjpeg_decode_sof(s)) < 0)
-                    return ret;
-                break;
-            case SOF48:
-                s->lossless    = 1;
-                s->ls          = 1;
-                s->progressive = 0;
-                if ((ret = ff_mjpeg_decode_sof(s)) < 0)
-                    return ret;
-                break;
-            case LSE:
-                if (!CONFIG_JPEGLS_DECODER ||
-                    (ret = ff_jpegls_decode_lse(s)) < 0)
-                    return ret;
+        switch (start_code) {
+        case SOI:
+            s->restart_interval = 0;
+            s->restart_count    = 0;
+            /* nothing to do on SOI */
+            break;
+        case DQT:
+            ff_mjpeg_decode_dqt(s);
+            break;
+        case DHT:
+            if ((ret = ff_mjpeg_decode_dht(s)) < 0) {
+                av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");
+                return ret;
+            }
+            break;
+        case SOF0:
+        case SOF1:
+            s->lossless    = 0;
+            s->ls          = 0;
+            s->progressive = 0;
+            if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+                return ret;
+            break;
+        case SOF2:
+            s->lossless    = 0;
+            s->ls          = 0;
+            s->progressive = 1;
+            if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+                return ret;
+            break;
+        case SOF3:
+            s->lossless    = 1;
+            s->ls          = 0;
+            s->progressive = 0;
+            if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+                return ret;
+            break;
+        case SOF48:
+            s->lossless    = 1;
+            s->ls          = 1;
+            s->progressive = 0;
+            if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+                return ret;
+            break;
+        case LSE:
+            if (!CONFIG_JPEGLS_DECODER ||
+                (ret = ff_jpegls_decode_lse(s)) < 0)
+                return ret;
+            break;
+        case EOI:
+            s->cur_scan = 0;
+            if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
                 break;
-            case EOI:
-                s->cur_scan = 0;
-                if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
-                    break;
 eoi_parser:
-                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;
-                    }
-                    *picture   = *s->picture_ptr;
-                    *got_frame = 1;
-
-                    if (!s->lossless) {
-                        picture->quality      = FFMAX3(s->qscale[0],
-                                                       s->qscale[1],
-                                                       s->qscale[2]);
-                        picture->qstride      = 0;
-                        picture->qscale_table = s->qscale_table;
-                        memset(picture->qscale_table, picture->quality,
-                               (s->width + 15) / 16);
-                        if (avctx->debug & FF_DEBUG_QP)
-                            av_log(avctx, AV_LOG_DEBUG,
-                                   "QP: %d\n", picture->quality);
-                        picture->quality *= FF_QP2LAMBDA;
-                    }
-
-                goto the_end;
-            case SOS:
-                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);
-                break;
-            case SOF5:
-            case SOF6:
-            case SOF7:
-            case SOF9:
-            case SOF10:
-            case SOF11:
-            case SOF13:
-            case SOF14:
-            case SOF15:
-            case JPG:
-                av_log(avctx, AV_LOG_ERROR,
-                       "mjpeg: unsupported coding type (%x)\n", start_code);
+            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;
+            }
+            if ((ret = av_frame_ref(data, s->picture_ptr)) < 0)
+                return ret;
+            *got_frame = 1;
 
-not_the_end:
-            /* eof process start code */
-            buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
-            av_log(avctx, AV_LOG_DEBUG,
-                   "marker parser used %d bytes (%d bits)\n",
-                   (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb));
+            if (!s->lossless &&
+                avctx->debug & FF_DEBUG_QP) {
+                av_log(avctx, AV_LOG_DEBUG,
+                       "QP: %d\n", FFMAX3(s->qscale[0],
+                                          s->qscale[1],
+                                          s->qscale[2]));
+            }
+
+            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);
+            break;
+        case SOF5:
+        case SOF6:
+        case SOF7:
+        case SOF9:
+        case SOF10:
+        case SOF11:
+        case SOF13:
+        case SOF14:
+        case SOF15:
+        case JPG:
+            av_log(avctx, AV_LOG_ERROR,
+                   "mjpeg: unsupported coding type (%x)\n", start_code);
+            break;
         }
+
+not_the_end:
+        /* eof process start code */
+        buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
+        av_log(avctx, AV_LOG_DEBUG,
+               "marker parser used %d bytes (%d bits)\n",
+               (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb));
     }
     if (s->got_picture) {
         av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n");
@@ -1660,11 +1655,13 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
     MJpegDecodeContext *s = avctx->priv_data;
     int i, j;
 
-    if (s->picture_ptr && s->picture_ptr->data[0])
-        avctx->release_buffer(avctx, s->picture_ptr);
+    if (s->picture) {
+        av_frame_free(&s->picture);
+        s->picture_ptr = NULL;
+    } else if (s->picture_ptr)
+        av_frame_unref(s->picture_ptr);
 
     av_free(s->buffer);
-    av_free(s->qscale_table);
     av_freep(&s->ljpeg_buffer);
     s->ljpeg_buffer_size = 0;
 
@@ -1696,6 +1693,7 @@ static const AVClass mjpegdec_class = {
 
 AVCodec ff_mjpeg_decoder = {
     .name           = "mjpeg",
+    .long_name      = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MJPEG,
     .priv_data_size = sizeof(MJpegDecodeContext),
@@ -1703,12 +1701,12 @@ AVCodec ff_mjpeg_decoder = {
     .close          = ff_mjpeg_decode_end,
     .decode         = ff_mjpeg_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
     .priv_class     = &mjpegdec_class,
 };
 
 AVCodec ff_thp_decoder = {
     .name           = "thp",
+    .long_name      = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_THP,
     .priv_data_size = sizeof(MJpegDecodeContext),
@@ -1716,5 +1714,4 @@ AVCodec ff_thp_decoder = {
     .close          = ff_mjpeg_decode_end,
     .decode         = ff_mjpeg_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"),
 };
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index 89325ba..e3adc58 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -34,6 +34,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "hpeldsp.h"
 
 #define MAX_COMPONENTS 4
 
@@ -83,17 +84,18 @@ typedef struct MJpegDecodeContext {
     int h_max, v_max; /* maximum h and v counts */
     int quant_index[4];   /* quant table index for each component */
     int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */
-    AVFrame picture; /* picture structure */
+    AVFrame *picture; /* picture structure */
     AVFrame *picture_ptr; /* pointer to picture structure */
     int got_picture;                                ///< we found a SOF and picture is valid, too.
     int linesize[MAX_COMPONENTS];                   ///< linesize << interlaced
     int8_t *qscale_table;
-    DECLARE_ALIGNED(16, DCTELEM, block)[64];
-    DCTELEM (*blocks[MAX_COMPONENTS])[64]; ///< intermediate sums (progressive mode)
+    DECLARE_ALIGNED(16, int16_t, block)[64];
+    int16_t (*blocks[MAX_COMPONENTS])[64]; ///< intermediate sums (progressive mode)
     uint8_t *last_nnz[MAX_COMPONENTS];
     uint64_t coefs_finished[MAX_COMPONENTS]; ///< bitmask of which coefs have been completely decoded (progressive mode)
     ScanTable scantable;
     DSPContext dsp;
+    HpelDSPContext hdsp;
 
     int restart_interval;
     int restart_count;
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 64e6f25..30433c3 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -30,20 +30,15 @@
  * MJPEG encoder.
  */
 
-//#define DEBUG
 #include <assert.h>
 
+#include "libavutil/pixdesc.h"
+
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "mjpeg.h"
 #include "mjpegenc.h"
 
-/* use two quantizer tables (one for luminance and one for chrominance) */
-/* not yet working */
-#undef TWOMATRIXES
-
-
 av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
 {
     MJpegContext *m;
@@ -83,10 +78,9 @@ void ff_mjpeg_encode_close(MpegEncContext *s)
 }
 
 /* table_class: 0 = DC coef, 1 = AC coefs */
-static int put_huffman_table(MpegEncContext *s, int table_class, int table_id,
+static int put_huffman_table(PutBitContext *p, int table_class, int table_id,
                              const uint8_t *bits_table, const uint8_t *value_table)
 {
-    PutBitContext *p = &s->pb;
     int n, i;
 
     put_bits(p, 4, table_class);
@@ -104,33 +98,21 @@ static int put_huffman_table(MpegEncContext *s, int table_class, int table_id,
     return n + 17;
 }
 
-static void jpeg_table_header(MpegEncContext *s)
+static void jpeg_table_header(PutBitContext *p, ScanTable *intra_scantable,
+                              uint16_t intra_matrix[64])
 {
-    PutBitContext *p = &s->pb;
     int i, j, size;
     uint8_t *ptr;
 
     /* quant matrixes */
     put_marker(p, DQT);
-#ifdef TWOMATRIXES
-    put_bits(p, 16, 2 + 2 * (1 + 64));
-#else
     put_bits(p, 16, 2 + 1 * (1 + 64));
-#endif
     put_bits(p, 4, 0); /* 8 bit precision */
     put_bits(p, 4, 0); /* table 0 */
     for(i=0;i<64;i++) {
-        j = s->intra_scantable.permutated[i];
-        put_bits(p, 8, s->intra_matrix[j]);
-    }
-#ifdef TWOMATRIXES
-    put_bits(p, 4, 0); /* 8 bit precision */
-    put_bits(p, 4, 1); /* table 1 */
-    for(i=0;i<64;i++) {
-        j = s->intra_scantable.permutated[i];
-        put_bits(p, 8, s->chroma_intra_matrix[j]);
+        j = intra_scantable->permutated[i];
+        put_bits(p, 8, intra_matrix[j]);
     }
-#endif
 
     /* huffman table */
     put_marker(p, DHT);
@@ -138,40 +120,38 @@ static void jpeg_table_header(MpegEncContext *s)
     ptr = put_bits_ptr(p);
     put_bits(p, 16, 0); /* patched later */
     size = 2;
-    size += put_huffman_table(s, 0, 0, avpriv_mjpeg_bits_dc_luminance,
+    size += put_huffman_table(p, 0, 0, avpriv_mjpeg_bits_dc_luminance,
                               avpriv_mjpeg_val_dc);
-    size += put_huffman_table(s, 0, 1, avpriv_mjpeg_bits_dc_chrominance,
+    size += put_huffman_table(p, 0, 1, avpriv_mjpeg_bits_dc_chrominance,
                               avpriv_mjpeg_val_dc);
 
-    size += put_huffman_table(s, 1, 0, avpriv_mjpeg_bits_ac_luminance,
+    size += put_huffman_table(p, 1, 0, avpriv_mjpeg_bits_ac_luminance,
                               avpriv_mjpeg_val_ac_luminance);
-    size += put_huffman_table(s, 1, 1, avpriv_mjpeg_bits_ac_chrominance,
+    size += put_huffman_table(p, 1, 1, avpriv_mjpeg_bits_ac_chrominance,
                               avpriv_mjpeg_val_ac_chrominance);
     AV_WB16(ptr, size);
 }
 
-static void jpeg_put_comments(MpegEncContext *s)
+static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p)
 {
-    PutBitContext *p = &s->pb;
     int size;
     uint8_t *ptr;
 
-    if (s->aspect_ratio_info /* && !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, 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);
-    put_bits(p, 8, 0); /* thumbnail width */
-    put_bits(p, 8, 0); /* thumbnail height */
+    if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) {
+        /* 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,  8, 0);              /* units type: 0 - aspect ratio */
+        put_bits(p, 16, avctx->sample_aspect_ratio.num);
+        put_bits(p, 16, avctx->sample_aspect_ratio.den);
+        put_bits(p, 8, 0); /* thumbnail width */
+        put_bits(p, 8, 0); /* thumbnail height */
     }
 
     /* comment */
-    if(!(s->flags & CODEC_FLAG_BITEXACT)){
+    if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
         put_marker(p, COM);
         flush_put_bits(p);
         ptr = put_bits_ptr(p);
@@ -181,9 +161,9 @@ static void jpeg_put_comments(MpegEncContext *s)
         AV_WB16(ptr, size);
     }
 
-    if(  s->avctx->pix_fmt == AV_PIX_FMT_YUV420P
-       ||s->avctx->pix_fmt == AV_PIX_FMT_YUV422P
-       ||s->avctx->pix_fmt == AV_PIX_FMT_YUV444P){
+    if (avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+        avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
+        avctx->pix_fmt == AV_PIX_FMT_YUV444P) {
         put_marker(p, COM);
         flush_put_bits(p);
         ptr = put_bits_ptr(p);
@@ -194,93 +174,106 @@ static void jpeg_put_comments(MpegEncContext *s)
     }
 }
 
-void ff_mjpeg_encode_picture_header(MpegEncContext *s)
+void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb,
+                                    ScanTable *intra_scantable,
+                                    uint16_t intra_matrix[64])
 {
-    const int lossless= s->avctx->codec_id != AV_CODEC_ID_MJPEG;
+    int chroma_h_shift, chroma_v_shift;
+    const int lossless = avctx->codec_id != AV_CODEC_ID_MJPEG;
+    int hsample[3], vsample[3];
+
+    av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift,
+                                     &chroma_v_shift);
+
+    if (avctx->codec->id == AV_CODEC_ID_LJPEG &&
+        avctx->pix_fmt   == AV_PIX_FMT_BGR24) {
+        vsample[0] = hsample[0] =
+        vsample[1] = hsample[1] =
+        vsample[2] = hsample[2] = 1;
+    } else {
+        vsample[0] = 2;
+        vsample[1] = 2 >> chroma_v_shift;
+        vsample[2] = 2 >> chroma_v_shift;
+        hsample[0] = 2;
+        hsample[1] = 2 >> chroma_h_shift;
+        hsample[2] = 2 >> chroma_h_shift;
+    }
 
-    put_marker(&s->pb, SOI);
+    put_marker(pb, SOI);
 
-    jpeg_put_comments(s);
+    jpeg_put_comments(avctx, pb);
 
-    jpeg_table_header(s);
+    jpeg_table_header(pb, intra_scantable, intra_matrix);
 
-    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;
+    switch (avctx->codec_id) {
+    case AV_CODEC_ID_MJPEG:  put_marker(pb, SOF0 ); break;
+    case AV_CODEC_ID_LJPEG:  put_marker(pb, SOF3 ); break;
     default: assert(0);
     }
 
-    put_bits(&s->pb, 16, 17);
-    if(lossless && s->avctx->pix_fmt == AV_PIX_FMT_BGRA)
-        put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */
+    put_bits(pb, 16, 17);
+    if (lossless && avctx->pix_fmt == AV_PIX_FMT_BGR24)
+        put_bits(pb, 8, 9); /* 9 bits/component RCT */
     else
-        put_bits(&s->pb, 8, 8); /* 8 bits/component */
-    put_bits(&s->pb, 16, s->height);
-    put_bits(&s->pb, 16, s->width);
-    put_bits(&s->pb, 8, 3); /* 3 components */
+        put_bits(pb, 8, 8); /* 8 bits/component */
+    put_bits(pb, 16, avctx->height);
+    put_bits(pb, 16, avctx->width);
+    put_bits(pb, 8, 3); /* 3 components */
 
     /* Y component */
-    put_bits(&s->pb, 8, 1); /* component number */
-    put_bits(&s->pb, 4, s->mjpeg_hsample[0]); /* H factor */
-    put_bits(&s->pb, 4, s->mjpeg_vsample[0]); /* V factor */
-    put_bits(&s->pb, 8, 0); /* select matrix */
+    put_bits(pb, 8, 1); /* component number */
+    put_bits(pb, 4, hsample[0]); /* H factor */
+    put_bits(pb, 4, vsample[0]); /* V factor */
+    put_bits(pb, 8, 0); /* select matrix */
 
     /* Cb component */
-    put_bits(&s->pb, 8, 2); /* component number */
-    put_bits(&s->pb, 4, s->mjpeg_hsample[1]); /* H factor */
-    put_bits(&s->pb, 4, s->mjpeg_vsample[1]); /* V factor */
-#ifdef TWOMATRIXES
-    put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */
-#else
-    put_bits(&s->pb, 8, 0); /* select matrix */
-#endif
+    put_bits(pb, 8, 2); /* component number */
+    put_bits(pb, 4, hsample[1]); /* H factor */
+    put_bits(pb, 4, vsample[1]); /* V factor */
+    put_bits(pb, 8, 0); /* select matrix */
 
     /* Cr component */
-    put_bits(&s->pb, 8, 3); /* component number */
-    put_bits(&s->pb, 4, s->mjpeg_hsample[2]); /* H factor */
-    put_bits(&s->pb, 4, s->mjpeg_vsample[2]); /* V factor */
-#ifdef TWOMATRIXES
-    put_bits(&s->pb, 8, lossless ? 0 : 1); /* select matrix */
-#else
-    put_bits(&s->pb, 8, 0); /* select matrix */
-#endif
+    put_bits(pb, 8, 3); /* component number */
+    put_bits(pb, 4, hsample[2]); /* H factor */
+    put_bits(pb, 4, vsample[2]); /* V factor */
+    put_bits(pb, 8, 0); /* select matrix */
 
     /* scan header */
-    put_marker(&s->pb, SOS);
-    put_bits(&s->pb, 16, 12); /* length */
-    put_bits(&s->pb, 8, 3); /* 3 components */
+    put_marker(pb, SOS);
+    put_bits(pb, 16, 12); /* length */
+    put_bits(pb, 8, 3); /* 3 components */
 
     /* Y component */
-    put_bits(&s->pb, 8, 1); /* index */
-    put_bits(&s->pb, 4, 0); /* DC huffman table index */
-    put_bits(&s->pb, 4, 0); /* AC huffman table index */
+    put_bits(pb, 8, 1); /* index */
+    put_bits(pb, 4, 0); /* DC huffman table index */
+    put_bits(pb, 4, 0); /* AC huffman table index */
 
     /* Cb component */
-    put_bits(&s->pb, 8, 2); /* index */
-    put_bits(&s->pb, 4, 1); /* DC huffman table index */
-    put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */
+    put_bits(pb, 8, 2); /* index */
+    put_bits(pb, 4, 1); /* DC huffman table index */
+    put_bits(pb, 4, lossless ? 0 : 1); /* AC huffman table index */
 
     /* Cr component */
-    put_bits(&s->pb, 8, 3); /* index */
-    put_bits(&s->pb, 4, 1); /* DC huffman table index */
-    put_bits(&s->pb, 4, lossless ? 0 : 1); /* AC huffman table index */
+    put_bits(pb, 8, 3); /* index */
+    put_bits(pb, 4, 1); /* DC huffman table index */
+    put_bits(pb, 4, lossless ? 0 : 1); /* AC huffman table index */
 
-    put_bits(&s->pb, 8, lossless ? s->avctx->prediction_method+1 : 0); /* Ss (not used) */
+    put_bits(pb, 8, lossless ? avctx->prediction_method + 1 : 0); /* Ss (not used) */
 
-    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 */
+    switch (avctx->codec_id) {
+    case AV_CODEC_ID_MJPEG:  put_bits(pb, 8, 63); break; /* Se (not used) */
+    case AV_CODEC_ID_LJPEG:  put_bits(pb, 8,  0); break; /* not used */
     default: assert(0);
     }
 
-    put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */
+    put_bits(pb, 8, 0); /* Ah/Al (not used) */
 }
 
-static void escape_FF(MpegEncContext *s, int start)
+static void escape_FF(PutBitContext *pb, int start)
 {
-    int size= put_bits_count(&s->pb) - start*8;
+    int size = put_bits_count(pb) - start * 8;
     int i, ff_count;
-    uint8_t *buf= s->pb.buf + start;
+    uint8_t *buf = pb->buf + start;
     int align= (-(size_t)(buf))&3;
 
     assert((size&7) == 0);
@@ -313,8 +306,8 @@ static void escape_FF(MpegEncContext *s, int start)
 
     if(ff_count==0) return;
 
-    flush_put_bits(&s->pb);
-    skip_put_bytes(&s->pb, ff_count);
+    flush_put_bits(pb);
+    skip_put_bytes(pb, ff_count);
 
     for(i=size-1; ff_count; i--){
         int v= buf[i];
@@ -335,25 +328,25 @@ void ff_mjpeg_encode_stuffing(PutBitContext * pbc)
     if(length) put_bits(pbc, length, (1<<length)-1);
 }
 
-void ff_mjpeg_encode_picture_trailer(MpegEncContext *s)
+void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits)
 {
-    ff_mjpeg_encode_stuffing(&s->pb);
-    flush_put_bits(&s->pb);
+    ff_mjpeg_encode_stuffing(pb);
+    flush_put_bits(pb);
 
-    assert((s->header_bits&7)==0);
+    assert((header_bits & 7) == 0);
 
-    escape_FF(s, s->header_bits>>3);
+    escape_FF(pb, header_bits >> 3);
 
-    put_marker(&s->pb, EOI);
+    put_marker(pb, EOI);
 }
 
-void ff_mjpeg_encode_dc(MpegEncContext *s, int val,
+void ff_mjpeg_encode_dc(PutBitContext *pb, int val,
                         uint8_t *huff_size, uint16_t *huff_code)
 {
     int mant, nbits;
 
     if (val == 0) {
-        put_bits(&s->pb, huff_size[0], huff_code[0]);
+        put_bits(pb, huff_size[0], huff_code[0]);
     } else {
         mant = val;
         if (val < 0) {
@@ -363,13 +356,13 @@ void ff_mjpeg_encode_dc(MpegEncContext *s, int val,
 
         nbits= av_log2_16bit(val) + 1;
 
-        put_bits(&s->pb, huff_size[nbits], huff_code[nbits]);
+        put_bits(pb, huff_size[nbits], huff_code[nbits]);
 
-        put_sbits(&s->pb, nbits, mant);
+        put_sbits(pb, nbits, mant);
     }
 }
 
-static void encode_block(MpegEncContext *s, DCTELEM *block, int n)
+static void encode_block(MpegEncContext *s, int16_t *block, int n)
 {
     int mant, nbits, code, i, j;
     int component, dc, run, last_index, val;
@@ -382,11 +375,11 @@ static void encode_block(MpegEncContext *s, DCTELEM *block, int n)
     dc = block[0]; /* overflow is impossible */
     val = dc - s->last_dc[component];
     if (n < 4) {
-        ff_mjpeg_encode_dc(s, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
+        ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_luminance, m->huff_code_dc_luminance);
         huff_size_ac = m->huff_size_ac_luminance;
         huff_code_ac = m->huff_code_ac_luminance;
     } else {
-        ff_mjpeg_encode_dc(s, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
+        ff_mjpeg_encode_dc(&s->pb, val, m->huff_size_dc_chrominance, m->huff_code_dc_chrominance);
         huff_size_ac = m->huff_size_ac_chrominance;
         huff_code_ac = m->huff_code_ac_chrominance;
     }
@@ -427,7 +420,7 @@ static void encode_block(MpegEncContext *s, DCTELEM *block, int n)
         put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]);
 }
 
-void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64])
+void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[6][64])
 {
     int i;
     for(i=0;i<5;i++) {
@@ -446,6 +439,7 @@ void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64])
 
 AVCodec ff_mjpeg_encoder = {
     .name           = "mjpeg",
+    .long_name      = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MJPEG,
     .priv_data_size = sizeof(MpegEncContext),
@@ -455,5 +449,4 @@ AVCodec ff_mjpeg_encoder = {
     .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)"),
 };
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index 12ff540..2ad55f2 100644
--- a/libavcodec/mjpegenc.h
+++ b/libavcodec/mjpegenc.h
@@ -33,7 +33,8 @@
 #ifndef AVCODEC_MJPEGENC_H
 #define AVCODEC_MJPEGENC_H
 
-#include "dsputil.h"
+#include <stdint.h>
+
 #include "mpegvideo.h"
 
 typedef struct MJpegContext {
@@ -50,11 +51,13 @@ typedef struct MJpegContext {
 
 int  ff_mjpeg_encode_init(MpegEncContext *s);
 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_picture_header(AVCodecContext *avctx, PutBitContext *pb,
+                                    ScanTable *intra_scantable,
+                                    uint16_t intra_matrix[64]);
+void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits);
 void ff_mjpeg_encode_stuffing(PutBitContext *pbc);
-void ff_mjpeg_encode_dc(MpegEncContext *s, int val,
+void ff_mjpeg_encode_dc(PutBitContext *pb, int val,
                         uint8_t *huff_size, uint16_t *huff_code);
-void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]);
+void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[6][64]);
 
 #endif /* AVCODEC_MJPEGENC_H */
diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c
index 31c79c9..1a68014 100644
--- a/libavcodec/mlp_parser.c
+++ b/libavcodec/mlp_parser.c
@@ -28,6 +28,7 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
+#include "libavutil/internal.h"
 #include "get_bits.h"
 #include "parser.h"
 #include "mlp_parser.h"
@@ -322,16 +323,49 @@ static int mlp_parse(AVCodecParserContext *s,
 
         if (mh.stream_type == 0xbb) {
             /* MLP stream */
-            avctx->channels       = mh.channels_mlp;
-            avctx->channel_layout = mh.channel_layout_mlp;
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+            if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
+                mh.num_substreams > 1) {
+                avctx->channels       = 2;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+            if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO &&
+                mh.num_substreams > 1) {
+                avctx->channels       = 2;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else {
+                avctx->channels       = mh.channels_mlp;
+                avctx->channel_layout = mh.channel_layout_mlp;
+            }
         } else { /* mh.stream_type == 0xba */
             /* TrueHD stream */
-            if (mh.channels_thd_stream2) {
-                avctx->channels       = mh.channels_thd_stream2;
-                avctx->channel_layout = mh.channel_layout_thd_stream2;
-            } else {
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+            if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
+                mh.num_substreams > 1) {
+                avctx->channels       = 2;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else if (avctx->request_channels > 0 &&
+                       avctx->request_channels <= mh.channels_thd_stream1) {
                 avctx->channels       = mh.channels_thd_stream1;
                 avctx->channel_layout = mh.channel_layout_thd_stream1;
+            } else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+            if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO &&
+                mh.num_substreams > 1) {
+                avctx->channels       = 2;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            } else if (avctx->request_channel_layout == mh.channel_layout_thd_stream1 ||
+                       !mh.channels_thd_stream2) {
+                avctx->channels       = mh.channels_thd_stream1;
+                avctx->channel_layout = mh.channel_layout_thd_stream1;
+            } else {
+                avctx->channels       = mh.channels_thd_stream2;
+                avctx->channel_layout = mh.channel_layout_thd_stream2;
             }
         }
 
diff --git a/libavcodec/mlp_parser.h b/libavcodec/mlp_parser.h
index 24b4169..e874426 100644
--- a/libavcodec/mlp_parser.h
+++ b/libavcodec/mlp_parser.h
@@ -31,13 +31,13 @@
 
 typedef struct MLPHeaderInfo
 {
-    int stream_type;            ///< 0xBB for MLP, 0xBA for TrueHD
+    int stream_type;                        ///< 0xBB for MLP, 0xBA for TrueHD
 
-    int group1_bits;            ///< The bit depth of the first substream
-    int group2_bits;            ///< Bit depth of the second substream (MLP only)
+    int group1_bits;                        ///< The bit depth of the first substream
+    int group2_bits;                        ///< Bit depth of the second substream (MLP only)
 
-    int group1_samplerate;      ///< Sample rate of first substream
-    int group2_samplerate;      ///< Sample rate of second substream (MLP only)
+    int group1_samplerate;                  ///< Sample rate of first substream
+    int group2_samplerate;                  ///< Sample rate of second substream (MLP only)
 
     int channels_mlp;                       ///< Channel count for MLP streams
     int channels_thd_stream1;               ///< Channel count for substream 1 of TrueHD streams ("6-channel presentation")
@@ -46,13 +46,13 @@ typedef struct MLPHeaderInfo
     uint64_t channel_layout_thd_stream1;    ///< Channel layout for substream 1 of TrueHD streams ("6-channel presentation")
     uint64_t channel_layout_thd_stream2;    ///< Channel layout for substream 2 of TrueHD streams ("8-channel presentation")
 
-    int access_unit_size;       ///< Number of samples per coded frame
-    int access_unit_size_pow2;  ///< Next power of two above number of samples per frame
+    int access_unit_size;                   ///< Number of samples per coded frame
+    int access_unit_size_pow2;              ///< Next power of two above number of samples per frame
 
-    int is_vbr;                 ///< Stream is VBR instead of CBR
-    int peak_bitrate;           ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR
+    int is_vbr;                             ///< Stream is VBR instead of CBR
+    int peak_bitrate;                       ///< Peak bitrate for VBR, actual bitrate (==peak) for CBR
 
-    int num_substreams;         ///< Number of substreams within stream
+    int num_substreams;                     ///< Number of substreams within stream
 } MLPHeaderInfo;
 
 
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index d999495..4339b9d 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -27,6 +27,7 @@
 #include <stdint.h>
 
 #include "avcodec.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/channel_layout.h"
 #include "get_bits.h"
@@ -118,7 +119,6 @@ typedef struct SubStream {
 
 typedef struct MLPDecodeContext {
     AVCodecContext *avctx;
-    AVFrame     frame;
 
     /// Current access unit being read has a major sync.
     int         is_major_sync_unit;
@@ -268,9 +268,6 @@ static av_cold int mlp_decode_init(AVCodecContext *avctx)
         m->substream[substr].lossless_check_data = 0xffffffff;
     ff_mlpdsp_init(&m->dsp);
 
-    avcodec_get_frame_defaults(&m->frame);
-    avctx->coded_frame = &m->frame;
-
     return 0;
 }
 
@@ -333,9 +330,10 @@ static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
         return AVERROR_INVALIDDATA;
     }
     if (mh.num_substreams > MAX_SUBSTREAMS) {
-        av_log_ask_for_sample(m->avctx,
-               "Number of substreams %d is larger than the maximum supported "
-               "by the decoder.\n", mh.num_substreams);
+        avpriv_request_sample(m->avctx,
+                              "%d substreams (more than the "
+                              "maximum supported by the decoder)",
+                              mh.num_substreams);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -434,9 +432,10 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
     /* 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) {
-        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);
+        avpriv_request_sample(m->avctx,
+                              "%d channels (more than the "
+                              "maximum supported by the decoder)",
+                              s->max_channel + 2);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -446,19 +445,30 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
         return AVERROR_INVALIDDATA;
     }
 
-
     s->min_channel        = min_channel;
     s->max_channel        = max_channel;
     s->max_matrix_channel = max_matrix_channel;
 
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
     if (m->avctx->request_channels > 0 &&
         m->avctx->request_channels <= s->max_channel + 1 &&
         m->max_decoded_substream > substr) {
         av_log(m->avctx, AV_LOG_DEBUG,
-               "Extracting %d channel downmix from substream %d. "
+               "Extracting %d-channel downmix from substream %d. "
                "Further substreams will be skipped.\n",
                s->max_channel + 1, substr);
         m->max_decoded_substream = substr;
+    } else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    if (m->avctx->request_channel_layout == s->ch_layout &&
+        m->max_decoded_substream > substr) {
+        av_log(m->avctx, AV_LOG_DEBUG,
+               "Extracting %d-channel downmix (0x%"PRIx64") from substream %d. "
+               "Further substreams will be skipped.\n",
+               s->max_channel + 1, s->ch_layout, substr);
+        m->max_decoded_substream = substr;
     }
 
     s->noise_shift   = get_bits(gbp,  4);
@@ -490,9 +500,9 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
                                                             channel);
         }
         if (ch_assign > s->max_matrix_channel) {
-            av_log_ask_for_sample(m->avctx,
-                   "Assignment of matrix channel %d to invalid output channel %d.\n",
-                   ch, ch_assign);
+            avpriv_request_sample(m->avctx,
+                                  "Assignment of matrix channel %d to invalid output channel %d",
+                                  ch, ch_assign);
             return AVERROR_PATCHWELCOME;
         }
         s->ch_assign[ch_assign] = ch;
@@ -823,8 +833,8 @@ static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp,
     if (s->data_check_present) {
         expected_stream_pos  = get_bits_count(gbp);
         expected_stream_pos += get_bits(gbp, 16);
-        av_log_ask_for_sample(m->avctx, "This file contains some features "
-                              "we have not tested yet.\n");
+        avpriv_request_sample(m->avctx,
+                              "Substreams with VLC block size check info");
     }
 
     if (s->blockpos + s->blocksize > m->access_unit_size) {
@@ -969,7 +979,7 @@ static void rematrix_channels(MLPDecodeContext *m, unsigned int substr)
 /** Write the audio data into the output buffer. */
 
 static int output_data(MLPDecodeContext *m, unsigned int substr,
-                       void *data, int *got_frame_ptr)
+                       AVFrame *frame, int *got_frame_ptr)
 {
     AVCodecContext *avctx = m->avctx;
     SubStream *s = &m->substream[substr];
@@ -990,13 +1000,13 @@ static int output_data(MLPDecodeContext *m, unsigned int substr,
     }
 
     /* get output buffer */
-    m->frame.nb_samples = s->blockpos;
-    if ((ret = ff_get_buffer(avctx, &m->frame)) < 0) {
+    frame->nb_samples = s->blockpos;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    data_32 = (int32_t *)m->frame.data[0];
-    data_16 = (int16_t *)m->frame.data[0];
+    data_32 = (int32_t *)frame->data[0];
+    data_16 = (int16_t *)frame->data[0];
 
     for (i = 0; i < s->blockpos; i++) {
         for (out_ch = 0; out_ch <= s->max_matrix_channel; out_ch++) {
@@ -1009,8 +1019,7 @@ static int output_data(MLPDecodeContext *m, unsigned int substr,
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = m->frame;
+    *got_frame_ptr = 1;
 
     return 0;
 }
@@ -1217,24 +1226,24 @@ error:
 
 AVCodec ff_mlp_decoder = {
     .name           = "mlp",
+    .long_name      = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MLP,
     .priv_data_size = sizeof(MLPDecodeContext),
     .init           = mlp_decode_init,
     .decode         = read_access_unit,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"),
 };
 
 #if CONFIG_TRUEHD_DECODER
 AVCodec ff_truehd_decoder = {
     .name           = "truehd",
+    .long_name      = NULL_IF_CONFIG_SMALL("TrueHD"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_TRUEHD,
     .priv_data_size = sizeof(MLPDecodeContext),
     .init           = mlp_decode_init,
     .decode         = read_access_unit,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("TrueHD"),
 };
 #endif /* CONFIG_TRUEHD_DECODER */
diff --git a/libavcodec/mlpdsp.c b/libavcodec/mlpdsp.c
index 2944ce8..b96200e 100644
--- a/libavcodec/mlpdsp.c
+++ b/libavcodec/mlpdsp.c
@@ -20,13 +20,14 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "mlpdsp.h"
 #include "mlp.h"
 
-static void ff_mlp_filter_channel(int32_t *state, const int32_t *coeff,
-                                  int firorder, int iirorder,
-                                  unsigned int filter_shift, int32_t mask, int blocksize,
-                                  int32_t *sample_buffer)
+static void mlp_filter_channel(int32_t *state, const int32_t *coeff,
+                               int firorder, int iirorder,
+                               unsigned int filter_shift, int32_t mask,
+                               int blocksize, int32_t *sample_buffer)
 {
     int32_t *firbuf = state;
     int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER;
@@ -56,9 +57,9 @@ static void ff_mlp_filter_channel(int32_t *state, const int32_t *coeff,
     }
 }
 
-void ff_mlpdsp_init(MLPDSPContext *c)
+av_cold void ff_mlpdsp_init(MLPDSPContext *c)
 {
-    c->mlp_filter_channel = ff_mlp_filter_channel;
+    c->mlp_filter_channel = mlp_filter_channel;
     if (ARCH_X86)
         ff_mlpdsp_init_x86(c);
 }
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index 784b939..abec2e8 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -34,6 +34,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #define MM_PREAMBLE_SIZE    6
 
@@ -47,7 +48,7 @@
 
 typedef struct MmContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
     int palette[AVPALETTE_COUNT];
     GetByteContext gb;
 } MmContext;
@@ -60,7 +61,9 @@ static av_cold int mm_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    s->frame.reference = 1;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -104,9 +107,9 @@ static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert)
             run_length *=2;
 
         if (color) {
-            memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length);
+            memset(s->frame->data[0] + y*s->frame->linesize[0] + x, color, run_length);
             if (half_vert)
-                memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length);
+                memset(s->frame->data[0] + (y+1)*s->frame->linesize[0] + x, color, run_length);
         }
         x+= run_length;
 
@@ -125,7 +128,8 @@ static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert)
  */
 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);
+    int y = 0;
     GetByteContext data_ptr;
 
     if (bytestream2_get_bytes_left(&s->gb) < data_off)
@@ -152,13 +156,13 @@ static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert)
                 int replace = (replace_array >> (7-j)) & 1;
                 if (replace) {
                     int color = bytestream2_get_byte(&data_ptr);
-                    s->frame.data[0][y*s->frame.linesize[0] + x] = color;
+                    s->frame->data[0][y*s->frame->linesize[0] + x] = color;
                     if (half_horiz)
-                        s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color;
+                        s->frame->data[0][y*s->frame->linesize[0] + x + 1] = color;
                     if (half_vert) {
-                        s->frame.data[0][(y+1)*s->frame.linesize[0] + x] = color;
+                        s->frame->data[0][(y+1)*s->frame->linesize[0] + x] = color;
                         if (half_horiz)
-                            s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color;
+                            s->frame->data[0][(y+1)*s->frame->linesize[0] + x + 1] = color;
                     }
                 }
                 x += 1 + half_horiz;
@@ -187,9 +191,9 @@ static int mm_decode_frame(AVCodecContext *avctx,
     buf_size -= MM_PREAMBLE_SIZE;
     bytestream2_init(&s->gb, buf, buf_size);
 
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((res = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return res;
     }
 
     switch(type) {
@@ -207,10 +211,12 @@ static int mm_decode_frame(AVCodecContext *avctx,
     if (res < 0)
         return res;
 
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
+
+    if ((res = av_frame_ref(data, s->frame)) < 0)
+        return res;
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
@@ -219,14 +225,14 @@ static av_cold int mm_decode_end(AVCodecContext *avctx)
 {
     MmContext *s = avctx->priv_data;
 
-    if(s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_mmvideo_decoder = {
     .name           = "mmvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("American Laser Games MM Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MMVIDEO,
     .priv_data_size = sizeof(MmContext),
@@ -234,5 +240,4 @@ AVCodec ff_mmvideo_decoder = {
     .close          = mm_decode_end,
     .decode         = mm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("American Laser Games MM Video"),
 };
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 3577ada..04ae49e 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -32,7 +32,6 @@
 #include <limits.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mathops.h"
 #include "mpegvideo.h"
 
@@ -290,7 +289,7 @@ static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){
     return 0;
 }
 
-static void zero_hpel(uint8_t *a, const uint8_t *b, int stride, int h){
+static void zero_hpel(uint8_t *a, const uint8_t *b, ptrdiff_t stride, int h){
 }
 
 int ff_init_me(MpegEncContext *s){
@@ -302,8 +301,9 @@ int ff_init_me(MpegEncContext *s){
         av_log(s->avctx, AV_LOG_ERROR, "ME_MAP size is too small for SAB diamond\n");
         return -1;
     }
-    //special case of snow is needed because snow uses its own iterative ME code
-    if(s->me_method!=ME_ZERO && s->me_method!=ME_EPZS && s->me_method!=ME_X1 && s->avctx->codec_id != AV_CODEC_ID_SNOW){
+    if (s->me_method != ME_ZERO &&
+        s->me_method != ME_EPZS &&
+        s->me_method != ME_X1) {
         av_log(s->avctx, AV_LOG_ERROR, "me_method is only allowed to be set to zero and epzs; for hex,umh,full and others see dia_size\n");
         return -1;
     }
@@ -339,9 +339,11 @@ int ff_init_me(MpegEncContext *s){
         else
             c->sub_motion_search= hpel_motion_search;
     }
-    c->hpel_avg= s->dsp.avg_pixels_tab;
-    if(s->no_rounding) c->hpel_put= s->dsp.put_no_rnd_pixels_tab;
-    else               c->hpel_put= s->dsp.put_pixels_tab;
+    c->hpel_avg = s->hdsp.avg_pixels_tab;
+    if (s->no_rounding)
+        c->hpel_put = s->hdsp.put_no_rnd_pixels_tab;
+    else
+        c->hpel_put = s->hdsp.put_pixels_tab;
 
     if(s->linesize){
         c->stride  = s->linesize;
@@ -354,16 +356,14 @@ int ff_init_me(MpegEncContext *s){
     /* 8x8 fullpel search would need a 4x4 chroma compare, which we do
      * not have yet, and even if we had, the motion estimation code
      * does not expect it. */
-    if(s->codec_id != AV_CODEC_ID_SNOW){
-        if((c->avctx->me_cmp&FF_CMP_CHROMA)/* && !s->dsp.me_cmp[2]*/){
-            s->dsp.me_cmp[2]= zero_cmp;
-        }
-        if((c->avctx->me_sub_cmp&FF_CMP_CHROMA) && !s->dsp.me_sub_cmp[2]){
-            s->dsp.me_sub_cmp[2]= zero_cmp;
-        }
-        c->hpel_put[2][0]= c->hpel_put[2][1]=
-        c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel;
+    if((c->avctx->me_cmp&FF_CMP_CHROMA)/* && !s->dsp.me_cmp[2]*/){
+        s->dsp.me_cmp[2]= zero_cmp;
+    }
+    if((c->avctx->me_sub_cmp&FF_CMP_CHROMA) && !s->dsp.me_sub_cmp[2]){
+        s->dsp.me_sub_cmp[2]= zero_cmp;
     }
+    c->hpel_put[2][0]= c->hpel_put[2][1]=
+    c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel;
 
     if(s->codec_id == AV_CODEC_ID_H261){
         c->sub_motion_search= no_sub_motion_search;
@@ -496,16 +496,16 @@ static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4)
     if(mv4){
         int mot_xy= s->block_index[0];
 
-        s->current_picture.f.motion_val[0][mot_xy    ][0] = mx;
-        s->current_picture.f.motion_val[0][mot_xy    ][1] = my;
-        s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx;
-        s->current_picture.f.motion_val[0][mot_xy + 1][1] = my;
+        s->current_picture.motion_val[0][mot_xy    ][0] = mx;
+        s->current_picture.motion_val[0][mot_xy    ][1] = my;
+        s->current_picture.motion_val[0][mot_xy + 1][0] = mx;
+        s->current_picture.motion_val[0][mot_xy + 1][1] = my;
 
         mot_xy += s->b8_stride;
-        s->current_picture.f.motion_val[0][mot_xy    ][0] = mx;
-        s->current_picture.f.motion_val[0][mot_xy    ][1] = my;
-        s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx;
-        s->current_picture.f.motion_val[0][mot_xy + 1][1] = my;
+        s->current_picture.motion_val[0][mot_xy    ][0] = mx;
+        s->current_picture.motion_val[0][mot_xy    ][1] = my;
+        s->current_picture.motion_val[0][mot_xy + 1][0] = mx;
+        s->current_picture.motion_val[0][mot_xy + 1][1] = my;
     }
 }
 
@@ -578,8 +578,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
         const int mot_stride = s->b8_stride;
         const int mot_xy = s->block_index[block];
 
-        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];
+        P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
+        P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
 
         if(P_LEFT[0]       > (c->xmax<<shift)) P_LEFT[0]       = (c->xmax<<shift);
 
@@ -588,10 +588,10 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
             c->pred_x= pred_x4= P_LEFT[0];
             c->pred_y= pred_y4= P_LEFT[1];
         } else {
-            P_TOP[0]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride             ][0];
-            P_TOP[1]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride             ][1];
-            P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][0];
-            P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][1];
+            P_TOP[0]      = s->current_picture.motion_val[0][mot_xy - mot_stride             ][0];
+            P_TOP[1]      = s->current_picture.motion_val[0][mot_xy - mot_stride             ][1];
+            P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0];
+            P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1];
             if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);
             if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
             if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
@@ -627,9 +627,9 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
                 dxy = ((my4 & 1) << 1) | (mx4 & 1);
 
                 if(s->no_rounding)
-                    s->dsp.put_no_rnd_pixels_tab[1][dxy](dest_y    , ref    , stride, h);
+                    s->hdsp.put_no_rnd_pixels_tab[1][dxy](dest_y    , ref    , stride, h);
                 else
-                    s->dsp.put_pixels_tab       [1][dxy](dest_y    , ref    , stride, h);
+                    s->hdsp.put_pixels_tab       [1][dxy](dest_y    , ref    , stride, h);
             }
             dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*c->mb_penalty_factor;
         }else
@@ -643,8 +643,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
             my4_sum+= my4;
         }
 
-        s->current_picture.f.motion_val[0][s->block_index[block]][0] = mx4;
-        s->current_picture.f.motion_val[0][s->block_index[block]][1] = my4;
+        s->current_picture.motion_val[0][s->block_index[block]][0] = mx4;
+        s->current_picture.motion_val[0][s->block_index[block]][1] = my4;
 
         if(mx4 != mx || my4 != my) same=0;
     }
@@ -668,11 +668,11 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
         offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;
 
         if(s->no_rounding){
-            s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad    , s->last_picture.f.data[1] + offset, s->uvlinesize, 8);
-            s->dsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad + 8, s->last_picture.f.data[2] + offset, s->uvlinesize, 8);
+            s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad    , s->last_picture.f.data[1] + offset, s->uvlinesize, 8);
+            s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad + 8, s->last_picture.f.data[2] + offset, s->uvlinesize, 8);
         }else{
-            s->dsp.put_pixels_tab       [1][dxy](c->scratchpad    , s->last_picture.f.data[1] + offset, s->uvlinesize, 8);
-            s->dsp.put_pixels_tab       [1][dxy](c->scratchpad + 8, s->last_picture.f.data[2] + offset, s->uvlinesize, 8);
+            s->hdsp.put_pixels_tab       [1][dxy](c->scratchpad    , s->last_picture.f.data[1] + offset, s->uvlinesize, 8);
+            s->hdsp.put_pixels_tab       [1][dxy](c->scratchpad + 8, s->last_picture.f.data[2] + offset, s->uvlinesize, 8);
         }
 
         dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.f.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad  , s->uvlinesize, 8);
@@ -780,9 +780,9 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
                 dxy = ((my_i & 1) << 1) | (mx_i & 1);
 
                 if(s->no_rounding){
-                    s->dsp.put_no_rnd_pixels_tab[size][dxy](c->scratchpad, ref    , stride, h);
+                    s->hdsp.put_no_rnd_pixels_tab[size][dxy](c->scratchpad, ref    , stride, h);
                 }else{
-                    s->dsp.put_pixels_tab       [size][dxy](c->scratchpad, ref    , stride, h);
+                    s->hdsp.put_pixels_tab       [size][dxy](c->scratchpad, ref    , stride, h);
                 }
                 dmin= s->dsp.mb_cmp[size](s, c->src[block][0], c->scratchpad, stride, h);
                 dmin+= (mv_penalty[mx_i-c->pred_x] + mv_penalty[my_i-c->pred_y] + 1)*c->mb_penalty_factor;
@@ -827,150 +827,24 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
     }
 }
 
-static void clip_input_mv(MpegEncContext * s, int16_t *mv, int interlaced){
-    int ymax= s->me.ymax>>interlaced;
-    int ymin= s->me.ymin>>interlaced;
-
-    if(mv[0] < s->me.xmin) mv[0] = s->me.xmin;
-    if(mv[0] > s->me.xmax) mv[0] = s->me.xmax;
-    if(mv[1] <       ymin) mv[1] =       ymin;
-    if(mv[1] >       ymax) mv[1] =       ymax;
-}
-
-static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int p_type){
-    MotionEstContext * const c= &s->me;
-    Picture *p= s->current_picture_ptr;
-    int mb_xy= mb_x + mb_y*s->mb_stride;
-    int xy= 2*mb_x + 2*mb_y*s->b8_stride;
-    int mb_type= s->current_picture.f.mb_type[mb_xy];
-    int flags= c->flags;
-    int shift= (flags&FLAG_QPEL) + 1;
-    int mask= (1<<shift)-1;
-    int x, y, i;
-    int d=0;
-    me_cmp_func cmpf= s->dsp.sse[0];
-    me_cmp_func chroma_cmpf= s->dsp.sse[1];
-
-    if(p_type && USES_LIST(mb_type, 1)){
-        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));
-
-    for(i=0; i<4; i++){
-        int xy= s->block_index[i];
-        clip_input_mv(s, p->f.motion_val[0][xy], !!IS_INTERLACED(mb_type));
-        clip_input_mv(s, p->f.motion_val[1][xy], !!IS_INTERLACED(mb_type));
-    }
-
-    if(IS_INTERLACED(mb_type)){
-        int xy2= xy  + s->b8_stride;
-        s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;
-        c->stride<<=1;
-        c->uvstride<<=1;
-
-        if(!(s->flags & CODEC_FLAG_INTERLACED_ME)){
-            av_log(c->avctx, AV_LOG_ERROR, "Interlaced macroblock selected but interlaced motion estimation disabled\n");
-            return INT_MAX/2;
-        }
-
-        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);
-            init_interlaced_ref(s, 0);
-
-            if(p_type){
-                s->p_field_select_table[0][mb_xy]= field_select0;
-                s->p_field_select_table[1][mb_xy]= field_select1;
-                *(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy ];
-                *(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy2];
-                s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER_I;
-            }else{
-                s->b_field_select_table[0][0][mb_xy]= field_select0;
-                s->b_field_select_table[0][1][mb_xy]= field_select1;
-                *(uint32_t*)s->b_field_mv_table[0][0][field_select0][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy ];
-                *(uint32_t*)s->b_field_mv_table[0][1][field_select1][mb_xy] = *(uint32_t*)p->f.motion_val[0][xy2];
-                s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_FORWARD_I;
-            }
-
-            x = p->f.motion_val[0][xy ][0];
-            y = p->f.motion_val[0][xy ][1];
-            d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0, 0, cmpf, chroma_cmpf, flags);
-            x = p->f.motion_val[0][xy2][0];
-            y = p->f.motion_val[0][xy2][1];
-            d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1, 1, cmpf, chroma_cmpf, flags);
-        }
-        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);
-            init_interlaced_ref(s, 2);
-
-            s->b_field_select_table[1][0][mb_xy]= field_select0;
-            s->b_field_select_table[1][1][mb_xy]= field_select1;
-            *(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy] = *(uint32_t*)p->f.motion_val[1][xy ];
-            *(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy] = *(uint32_t*)p->f.motion_val[1][xy2];
-            if(USES_LIST(mb_type, 0)){
-                s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BIDIR_I;
-            }else{
-                s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BACKWARD_I;
-            }
-
-            x = p->f.motion_val[1][xy ][0];
-            y = p->f.motion_val[1][xy ][1];
-            d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0+2, 0, cmpf, chroma_cmpf, flags);
-            x = p->f.motion_val[1][xy2][0];
-            y = p->f.motion_val[1][xy2][1];
-            d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1+2, 1, cmpf, chroma_cmpf, flags);
-            //FIXME bidir scores
-        }
-        c->stride>>=1;
-        c->uvstride>>=1;
-    }else if(IS_8X8(mb_type)){
-        if(!(s->flags & CODEC_FLAG_4MV)){
-            av_log(c->avctx, AV_LOG_ERROR, "4MV macroblock selected but 4MV encoding disabled\n");
-            return INT_MAX/2;
-        }
-        cmpf= s->dsp.sse[1];
-        chroma_cmpf= s->dsp.sse[1];
-        init_mv4_ref(c);
-        for(i=0; i<4; i++){
-            xy= s->block_index[i];
-            x= p->f.motion_val[0][xy][0];
-            y= p->f.motion_val[0][xy][1];
-            d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 1, 8, i, i, cmpf, chroma_cmpf, flags);
-        }
-        s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER4V;
-    }else{
-        if(USES_LIST(mb_type, 0)){
-            if(p_type){
-                *(uint32_t*)s->p_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[0][xy];
-                s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER;
-            }else if(USES_LIST(mb_type, 1)){
-                *(uint32_t*)s->b_bidir_forw_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[0][xy];
-                *(uint32_t*)s->b_bidir_back_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[1][xy];
-                s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BIDIR;
-            }else{
-                *(uint32_t*)s->b_forw_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[0][xy];
-                s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_FORWARD;
-            }
-            x = p->f.motion_val[0][xy][0];
-            y = p->f.motion_val[0][xy][1];
-            d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 0, 0, cmpf, chroma_cmpf, flags);
-        }else if(USES_LIST(mb_type, 1)){
-            *(uint32_t*)s->b_back_mv_table[mb_xy] = *(uint32_t*)p->f.motion_val[1][xy];
-            s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BACKWARD;
-
-            x = p->f.motion_val[1][xy][0];
-            y = p->f.motion_val[1][xy][1];
-            d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 2, 0, cmpf, chroma_cmpf, flags);
-        }else
-            s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA;
+static inline int get_penalty_factor(int lambda, int lambda2, int type){
+    switch(type&0xFF){
+    default:
+    case FF_CMP_SAD:
+        return lambda>>FF_LAMBDA_SHIFT;
+    case FF_CMP_DCT:
+        return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
+    case FF_CMP_SATD:
+    case FF_CMP_DCT264:
+        return (2*lambda)>>FF_LAMBDA_SHIFT;
+    case FF_CMP_RD:
+    case FF_CMP_PSNR:
+    case FF_CMP_SSE:
+    case FF_CMP_NSSE:
+        return lambda2>>FF_LAMBDA_SHIFT;
+    case FF_CMP_BIT:
+        return 1;
     }
-    return d;
 }
 
 void ff_estimate_p_frame_motion(MpegEncContext * s,
@@ -1009,21 +883,6 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
     pic->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;
     c->mb_var_sum_temp += (varc+128)>>8;
 
-    if(c->avctx->me_threshold){
-        vard= check_input_motion(s, mb_x, mb_y, 1);
-
-        if((vard+128)>>8 < c->avctx->me_threshold){
-            int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
-            int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;
-            pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;
-            c->mc_mb_var_sum_temp += (vard+128)>>8;
-            c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);
-            return;
-        }
-        if((vard+128)>>8 < c->avctx->mb_threshold)
-            mb_type= s->mb_type[mb_x + mb_y*s->mb_stride];
-    }
-
     switch(s->me_method) {
     case ME_ZERO:
     default:
@@ -1037,16 +896,16 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             const int mot_stride = s->b8_stride;
             const int mot_xy = s->block_index[0];
 
-            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];
+            P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
+            P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
 
             if(P_LEFT[0]       > (c->xmax<<shift)) P_LEFT[0]       = (c->xmax<<shift);
 
             if(!s->first_slice_line) {
-                P_TOP[0]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride    ][0];
-                P_TOP[1]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride    ][1];
-                P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][0];
-                P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][1];
+                P_TOP[0]      = s->current_picture.motion_val[0][mot_xy - mot_stride    ][0];
+                P_TOP[1]      = s->current_picture.motion_val[0][mot_xy - mot_stride    ][1];
+                P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0];
+                P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1];
                 if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);
                 if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
                 if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
@@ -1078,7 +937,6 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
     vard = s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16);
 
     pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;
-//    pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;
     c->mc_mb_var_sum_temp += (vard+128)>>8;
 
     if(mb_type){
@@ -1157,7 +1015,6 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             }
         }
 
-//        pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;
         set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V);
 
         /* get intra luma score */
@@ -1180,9 +1037,9 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
 
         if(intra_score < dmin){
             mb_type= CANDIDATE_MB_TYPE_INTRA;
-            s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
+            s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
         }else
-            s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = 0;
+            s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = 0;
 
         {
             int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
@@ -1247,8 +1104,8 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
     return dmin;
 }
 
-static int ff_estimate_motion_b(MpegEncContext * s,
-                       int mb_x, int mb_y, int16_t (*mv_table)[2], int ref_index, int f_code)
+static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y,
+                             int16_t (*mv_table)[2], int ref_index, int f_code)
 {
     MotionEstContext * const c= &s->me;
     int mx, my, dmin;
@@ -1362,14 +1219,14 @@ static inline int check_bidir_mv(MpegEncContext * s,
         src_y = motion_fy >> 1;
 
         ptr = ref_data[0] + (src_y * stride) + src_x;
-        s->dsp.put_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);
+        s->hdsp.put_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);
 
         dxy = ((motion_by & 1) << 1) | (motion_bx & 1);
         src_x = motion_bx >> 1;
         src_y = motion_by >> 1;
 
         ptr = ref2_data[0] + (src_y * stride) + src_x;
-        s->dsp.avg_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);
+        s->hdsp.avg_pixels_tab[size][dxy](dest_y    , ptr    , stride, h);
     }
 
     fbmin = (mv_penalty_f[motion_fx-pred_fx] + mv_penalty_f[motion_fy-pred_fy])*c->mb_penalty_factor
@@ -1548,7 +1405,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
     ymin= xmin=(-32)>>shift;
     ymax= xmax=   31>>shift;
 
-    if (IS_8X8(s->next_picture.f.mb_type[mot_xy])) {
+    if (IS_8X8(s->next_picture.mb_type[mot_xy])) {
         s->mv_type= MV_TYPE_8X8;
     }else{
         s->mv_type= MV_TYPE_16X16;
@@ -1558,8 +1415,8 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
         int index= s->block_index[i];
         int min, max;
 
-        c->co_located_mv[i][0] = s->next_picture.f.motion_val[0][index][0];
-        c->co_located_mv[i][1] = s->next_picture.f.motion_val[0][index][1];
+        c->co_located_mv[i][0] = s->next_picture.motion_val[0][index][0];
+        c->co_located_mv[i][1] = s->next_picture.motion_val[0][index][1];
         c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));
         c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));
 //        c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);
@@ -1648,7 +1505,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
 
     c->skip=0;
 
-    if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.f.mbskip_table[xy]) {
+    if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]) {
         int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0
 
         score= ((unsigned)(score*score + 128*256))>>16;
@@ -1659,67 +1516,18 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
         return;
     }
 
-    if(c->avctx->me_threshold){
-        int vard= check_input_motion(s, mb_x, mb_y, 0);
-
-        if((vard+128)>>8 < c->avctx->me_threshold){
-//            pix = c->src[0][0];
-//            sum = s->dsp.pix_sum(pix, s->linesize);
-//            varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500;
-
-//            pic->mb_var   [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;
-             s->current_picture.mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;
-/*            pic->mb_mean  [s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
-            c->mb_var_sum_temp    += (varc+128)>>8;*/
-            c->mc_mb_var_sum_temp += (vard+128)>>8;
-/*            if (vard <= 64<<8 || vard < varc) {
-                c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
-            }else{
-                c->scene_change_score+= s->qscale * s->avctx->scenechange_factor;
-            }*/
-            return;
-        }
-        if((vard+128)>>8 < c->avctx->mb_threshold){
-            type= s->mb_type[mb_y*s->mb_stride + mb_x];
-            if(type == CANDIDATE_MB_TYPE_DIRECT){
-                direct_search(s, mb_x, mb_y);
-            }
-            if(type == CANDIDATE_MB_TYPE_FORWARD || type == CANDIDATE_MB_TYPE_BIDIR){
-                c->skip=0;
-                ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code);
-            }
-            if(type == CANDIDATE_MB_TYPE_BACKWARD || type == CANDIDATE_MB_TYPE_BIDIR){
-                c->skip=0;
-                ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code);
-            }
-            if(type == CANDIDATE_MB_TYPE_FORWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){
-                c->skip=0;
-                c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;
-                interlaced_search(s, 0,
-                                        s->b_field_mv_table[0], s->b_field_select_table[0],
-                                        s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 1);
-            }
-            if(type == CANDIDATE_MB_TYPE_BACKWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){
-                c->skip=0;
-                c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_MV;
-                interlaced_search(s, 2,
-                                        s->b_field_mv_table[1], s->b_field_select_table[1],
-                                        s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 1);
-            }
-            return;
-        }
-    }
-
     if (s->codec_id == AV_CODEC_ID_MPEG4)
         dmin= direct_search(s, mb_x, mb_y);
     else
         dmin= INT_MAX;
 //FIXME penalty stuff for non mpeg4
     c->skip=0;
-    fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) + 3*penalty_factor;
+    fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) +
+           3 * penalty_factor;
 
     c->skip=0;
-    bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) + 2*penalty_factor;
+    bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) +
+           2 * penalty_factor;
     av_dlog(s, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);
 
     c->skip=0;
@@ -1870,14 +1678,14 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
                     int block;
                     for(block=0; block<4; block++){
                         int off= (block& 1) + (block>>1)*wrap;
-                        int mx = s->current_picture.f.motion_val[0][ xy + off ][0];
-                        int my = s->current_picture.f.motion_val[0][ xy + off ][1];
+                        int mx = s->current_picture.motion_val[0][ xy + off ][0];
+                        int my = s->current_picture.motion_val[0][ xy + off ][1];
 
                         if(   mx >=range || mx <-range
                            || my >=range || my <-range){
                             s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V;
                             s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA;
-                            s->current_picture.f.mb_type[i] = CANDIDATE_MB_TYPE_INTRA;
+                            s->current_picture.mb_type[i] = CANDIDATE_MB_TYPE_INTRA;
                         }
                     }
                 }
diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c
index c2bd0f4..6c1efad 100644
--- a/libavcodec/motionpixels.c
+++ b/libavcodec/motionpixels.c
@@ -22,6 +22,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
 
 #define MAX_HUFF_CODES 16
 
@@ -35,7 +36,7 @@ typedef struct HuffCode {
 
 typedef struct MotionPixelsContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
     DSPContext dsp;
     uint8_t *changes_map;
     int offset_bits_len;
@@ -49,6 +50,19 @@ typedef struct MotionPixelsContext {
     int bswapbuf_size;
 } MotionPixelsContext;
 
+static av_cold int mp_decode_end(AVCodecContext *avctx)
+{
+    MotionPixelsContext *mp = avctx->priv_data;
+
+    av_freep(&mp->changes_map);
+    av_freep(&mp->vpt);
+    av_freep(&mp->hpt);
+    av_freep(&mp->bswapbuf);
+    av_frame_free(&mp->frame);
+
+    return 0;
+}
+
 static av_cold int mp_decode_init(AVCodecContext *avctx)
 {
     MotionPixelsContext *mp = avctx->priv_data;
@@ -63,6 +77,13 @@ static av_cold int mp_decode_init(AVCodecContext *avctx)
     mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel));
     mp->hpt = av_mallocz(h4 * w4 / 16 * sizeof(YuvPixel));
     avctx->pix_fmt = AV_PIX_FMT_RGB555;
+
+    mp->frame = av_frame_alloc();
+    if (!mp->frame) {
+        mp_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
@@ -83,14 +104,14 @@ static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int
             continue;
         w = FFMIN(w, mp->avctx->width  - x);
         h = FFMIN(h, mp->avctx->height - y);
-        pixels = (uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2];
+        pixels = (uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2];
         while (h--) {
             mp->changes_map[offset] = w;
             if (read_color)
                 for (i = 0; i < w; ++i)
                     pixels[i] = color;
             offset += mp->avctx->width;
-            pixels += mp->frame.linesize[0] / 2;
+            pixels += mp->frame->linesize[0] / 2;
         }
     }
 }
@@ -142,7 +163,7 @@ static YuvPixel mp_get_yuv_from_rgb(MotionPixelsContext *mp, int x, int y)
 {
     int color;
 
-    color = *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2];
+    color = *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2];
     return mp_rgb_yuv_table[color];
 }
 
@@ -151,7 +172,7 @@ static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const Yuv
     int color;
 
     color = mp_yuv_to_rgb(p->y, p->v, p->u, 1);
-    *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2] = color;
+    *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2] = color;
 }
 
 static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb)
@@ -159,6 +180,7 @@ static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb)
     int i;
 
     i = (mp->codes_count == 1) ? 0 : get_vlc2(gb, mp->vlc.table, mp->max_codes_bits, 1);
+    i = FFMIN(i, FF_ARRAY_ELEMS(mp->codes) - 1);
     return mp->codes[i].delta;
 }
 
@@ -244,13 +266,11 @@ static int mp_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     MotionPixelsContext *mp = avctx->priv_data;
     GetBitContext gb;
-    int i, count1, count2, sz;
+    int i, count1, count2, sz, ret;
 
-    mp->frame.reference = 1;
-    mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &mp->frame)) {
+    if ((ret = ff_reget_buffer(avctx, mp->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* le32 bitstream msb first */
@@ -276,7 +296,7 @@ static int mp_decode_frame(AVCodecContext *avctx,
         goto end;
 
     if (mp->changes_map[0] == 0) {
-        *(uint16_t *)mp->frame.data[0] = get_bits(&gb, 15);
+        *(uint16_t *)mp->frame->data[0] = get_bits(&gb, 15);
         mp->changes_map[0] = 1;
     }
     mp_read_codes_table(mp, &gb);
@@ -295,27 +315,15 @@ static int mp_decode_frame(AVCodecContext *avctx,
     ff_free_vlc(&mp->vlc);
 
 end:
+    if ((ret = av_frame_ref(data, mp->frame)) < 0)
+        return ret;
     *got_frame       = 1;
-    *(AVFrame *)data = mp->frame;
     return buf_size;
 }
 
-static av_cold int mp_decode_end(AVCodecContext *avctx)
-{
-    MotionPixelsContext *mp = avctx->priv_data;
-
-    av_freep(&mp->changes_map);
-    av_freep(&mp->vpt);
-    av_freep(&mp->hpt);
-    av_freep(&mp->bswapbuf);
-    if (mp->frame.data[0])
-        avctx->release_buffer(avctx, &mp->frame);
-
-    return 0;
-}
-
 AVCodec ff_motionpixels_decoder = {
     .name           = "motionpixels",
+    .long_name      = NULL_IF_CONFIG_SMALL("Motion Pixels video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MOTIONPIXELS,
     .priv_data_size = sizeof(MotionPixelsContext),
@@ -323,5 +331,4 @@ AVCodec ff_motionpixels_decoder = {
     .close          = mp_decode_end,
     .decode         = mp_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Motion Pixels video"),
 };
diff --git a/libavcodec/mp3_header_compress_bsf.c b/libavcodec/mp3_header_compress_bsf.c
deleted file mode 100644
index 06a7ebe..0000000
--- a/libavcodec/mp3_header_compress_bsf.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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/common.h"
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "mpegaudiodecheader.h"
-
-
-static int mp3_header_compress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
-                     uint8_t **poutbuf, int *poutbuf_size,
-                     const uint8_t *buf, int buf_size, int keyframe){
-    uint32_t header, extraheader;
-    int mode_extension, header_size;
-
-    if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
-        av_log(avctx, AV_LOG_ERROR, "not standards compliant\n");
-        return -1;
-    }
-
-    header = AV_RB32(buf);
-    mode_extension= (header>>4)&3;
-
-    if(ff_mpa_check_header(header) < 0 || (header&0x60000) != 0x20000){
-output_unchanged:
-        *poutbuf= (uint8_t *) buf;
-        *poutbuf_size= buf_size;
-
-        av_log(avctx, AV_LOG_INFO, "cannot compress %08X\n", header);
-        return 0;
-    }
-
-    if(avctx->extradata_size == 0){
-        avctx->extradata_size=15;
-        avctx->extradata= av_malloc(avctx->extradata_size);
-        strcpy(avctx->extradata, "FFCMP3 0.0");
-        memcpy(avctx->extradata+11, buf, 4);
-    }
-    if(avctx->extradata_size != 15){
-        av_log(avctx, AV_LOG_ERROR, "Extradata invalid\n");
-        return -1;
-    }
-    extraheader = AV_RB32(avctx->extradata+11);
-    if((extraheader&MP3_MASK) != (header&MP3_MASK))
-        goto output_unchanged;
-
-    header_size= (header&0x10000) ? 4 : 6;
-
-    *poutbuf_size= buf_size - header_size;
-    *poutbuf= av_malloc(buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    memcpy(*poutbuf, buf + header_size, buf_size - header_size + FF_INPUT_BUFFER_PADDING_SIZE);
-
-    if(avctx->channels==2){
-        if((header & (3<<19)) != 3<<19){
-            (*poutbuf)[1] &= 0x3F;
-            (*poutbuf)[1] |= mode_extension<<6;
-            FFSWAP(int, (*poutbuf)[1], (*poutbuf)[2]);
-        }else{
-            (*poutbuf)[1] &= 0x8F;
-            (*poutbuf)[1] |= mode_extension<<4;
-        }
-    }
-
-    return 1;
-}
-
-AVBitStreamFilter ff_mp3_header_compress_bsf={
-    "mp3comp",
-    0,
-    mp3_header_compress,
-};
diff --git a/libavcodec/mp3_header_decompress_bsf.c b/libavcodec/mp3_header_decompress_bsf.c
deleted file mode 100644
index 8e086a1..0000000
--- a/libavcodec/mp3_header_decompress_bsf.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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/common.h"
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "mpegaudiodecheader.h"
-#include "mpegaudiodata.h"
-
-
-static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
-                     uint8_t **poutbuf, int *poutbuf_size,
-                     const uint8_t *buf, int buf_size, int keyframe){
-    uint32_t header;
-    int sample_rate= avctx->sample_rate;
-    int sample_rate_index=0;
-    int lsf, mpeg25, bitrate_index, frame_size;
-
-    header = AV_RB32(buf);
-    if(ff_mpa_check_header(header) >= 0){
-        *poutbuf= (uint8_t *) buf;
-        *poutbuf_size= buf_size;
-
-        return 0;
-    }
-
-    if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){
-        av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size);
-        return -1;
-    }
-
-    header= AV_RB32(avctx->extradata+11) & MP3_MASK;
-
-    lsf     = sample_rate < (24000+32000)/2;
-    mpeg25  = sample_rate < (12000+16000)/2;
-    sample_rate_index= (header>>10)&3;
-    sample_rate= avpriv_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off
-
-    for(bitrate_index=2; bitrate_index<30; bitrate_index++){
-        frame_size = avpriv_mpa_bitrate_tab[lsf][2][bitrate_index>>1];
-        frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);
-        if(frame_size == buf_size + 4)
-            break;
-        if(frame_size == buf_size + 6)
-            break;
-    }
-    if(bitrate_index == 30){
-        av_log(avctx, AV_LOG_ERROR, "Could not find bitrate_index.\n");
-        return -1;
-    }
-
-    header |= (bitrate_index&1)<<9;
-    header |= (bitrate_index>>1)<<12;
-    header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0
-
-    *poutbuf_size= frame_size;
-    *poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
-
-    if(avctx->channels==2){
-        uint8_t *p= *poutbuf + frame_size - buf_size;
-        if(lsf){
-            FFSWAP(int, p[1], p[2]);
-            header |= (p[1] & 0xC0)>>2;
-            p[1] &= 0x3F;
-        }else{
-            header |= p[1] & 0x30;
-            p[1] &= 0xCF;
-        }
-    }
-
-    AV_WB32(*poutbuf, header);
-
-    return 1;
-}
-
-AVBitStreamFilter ff_mp3_header_decompress_bsf={
-    "mp3decomp",
-    0,
-    mp3_header_decompress,
-};
diff --git a/libavcodec/mpc.c b/libavcodec/mpc.c
index 5a54a9b..763ea2c 100644
--- a/libavcodec/mpc.c
+++ b/libavcodec/mpc.c
@@ -26,16 +26,16 @@
  * divided into 32 subbands.
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "mpegaudiodsp.h"
 #include "mpegaudio.h"
 
 #include "mpc.h"
 #include "mpcdata.h"
 
-void ff_mpc_init(void)
+av_cold void ff_mpc_init(void)
 {
     ff_mpa_synth_init_fixed(ff_mpa_synth_window_fixed);
 }
diff --git a/libavcodec/mpc.h b/libavcodec/mpc.h
index 86d4b6d..cbb121e 100644
--- a/libavcodec/mpc.h
+++ b/libavcodec/mpc.h
@@ -50,7 +50,6 @@ typedef struct Band {
 }Band;
 
 typedef struct MPCContext {
-    AVFrame frame;
     DSPContext dsp;
     MPADSPContext mpadsp;
     GetBitContext gb;
diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c
index ab6fd9f..a38b0ea 100644
--- a/libavcodec/mpc7.c
+++ b/libavcodec/mpc7.c
@@ -26,6 +26,7 @@
  */
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/lfg.h"
 #include "avcodec.h"
 #include "get_bits.h"
@@ -64,8 +65,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx)
 
     /* Musepack SV7 is always stereo */
     if (avctx->channels != 2) {
-        av_log_ask_for_sample(avctx, "Unsupported number of channels: %d\n",
-                              avctx->channels);
+        avpriv_request_sample(avctx, "%d channels", avctx->channels);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -138,9 +138,6 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx)
     }
     vlc_initialized = 1;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -200,6 +197,7 @@ static int get_scale_idx(GetBitContext *gb, int ref)
 static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size;
     MPCContext *c = avctx->priv_data;
@@ -229,8 +227,8 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
     buf_size  -= 4;
 
     /* get output buffer */
-    c->frame.nb_samples = last_frame ? c->lastframelen : MPC_FRAME_SIZE;
-    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = last_frame ? c->lastframelen : MPC_FRAME_SIZE;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -294,7 +292,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
         for(ch = 0; ch < 2; ch++)
             idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off);
 
-    ff_mpc_dequantize_and_synth(c, mb, (int16_t **)c->frame.extended_data, 2);
+    ff_mpc_dequantize_and_synth(c, mb, (int16_t **)frame->extended_data, 2);
 
     bits_used = get_bits_count(&gb);
     bits_avail = buf_size * 8;
@@ -308,8 +306,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
         return avpkt->size;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
@@ -332,6 +329,7 @@ static av_cold int mpc7_decode_close(AVCodecContext *avctx)
 
 AVCodec ff_mpc7_decoder = {
     .name           = "mpc7",
+    .long_name      = NULL_IF_CONFIG_SMALL("Musepack SV7"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MUSEPACK7,
     .priv_data_size = sizeof(MPCContext),
@@ -340,7 +338,6 @@ AVCodec ff_mpc7_decoder = {
     .decode         = mpc7_decode_frame,
     .flush          = mpc7_decode_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Musepack SV7"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c
index a270be3..b6e0cfd 100644
--- a/libavcodec/mpc8.c
+++ b/libavcodec/mpc8.c
@@ -130,7 +130,7 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx)
     c->maxbands = get_bits(&gb, 5) + 1;
     channels = get_bits(&gb, 4) + 1;
     if (channels > 2) {
-        av_log_missing_feature(avctx, "Multichannel MPC SV8", 1);
+        avpriv_request_sample(avctx, "Multichannel MPC SV8");
         return AVERROR_PATCHWELCOME;
     }
     c->MSS = get_bits1(&gb);
@@ -230,15 +230,13 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx)
     }
     vlc_initialized = 1;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
 static int mpc8_decode_frame(AVCodecContext * avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     MPCContext *c = avctx->priv_data;
@@ -250,8 +248,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data,
     int last[2];
 
     /* get output buffer */
-    c->frame.nb_samples = MPC_FRAME_SIZE;
-    if ((res = ff_get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = MPC_FRAME_SIZE;
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
@@ -407,7 +405,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data,
     }
 
     ff_mpc_dequantize_and_synth(c, maxband - 1,
-                                (int16_t **)c->frame.extended_data,
+                                (int16_t **)frame->extended_data,
                                 avctx->channels);
 
     c->cur_frame++;
@@ -418,8 +416,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data,
     if(c->cur_frame >= c->frames)
         c->cur_frame = 0;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return c->cur_frame ? c->last_bits_used >> 3 : buf_size;
 }
@@ -432,6 +429,7 @@ static av_cold void mpc8_decode_flush(AVCodecContext *avctx)
 
 AVCodec ff_mpc8_decoder = {
     .name           = "mpc8",
+    .long_name      = NULL_IF_CONFIG_SMALL("Musepack SV8"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MUSEPACK8,
     .priv_data_size = sizeof(MPCContext),
@@ -439,7 +437,6 @@ AVCodec ff_mpc8_decoder = {
     .decode         = mpc8_decode_frame,
     .flush          = mpc8_decode_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Musepack SV8"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 7a9b54a..5797d27 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -25,572 +25,42 @@
  * MPEG-1/2 decoder
  */
 
-//#define DEBUG
+#include "libavutil/attributes.h"
 #include "internal.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
-
+#include "error_resilience.h"
 #include "mpeg12.h"
 #include "mpeg12data.h"
-#include "mpeg12decdata.h"
 #include "bytestream.h"
-#include "vdpau_internal.h"
-#include "xvmc_internal.h"
 #include "thread.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
-
-#define MV_VLC_BITS 9
-#define MBINCR_VLC_BITS 9
-#define MB_PAT_VLC_BITS 9
-#define MB_PTYPE_VLC_BITS 6
-#define MB_BTYPE_VLC_BITS 6
-
-static VLC mv_vlc;
-
-/* as H.263, but only 17 codes */
-static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
-{
-    int code, sign, val, shift;
-
-    code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2);
-    if (code == 0) {
-        return pred;
-    }
-    if (code < 0) {
-        return 0xffff;
-    }
-
-    sign  = get_bits1(&s->gb);
-    shift = fcode - 1;
-    val   = code;
-    if (shift) {
-        val  = (val - 1) << shift;
-        val |= get_bits(&s->gb, shift);
-        val++;
-    }
-    if (sign)
-        val = -val;
-    val += pred;
-
-    /* modulo decoding */
-    return sign_extend(val, 5 + shift);
-}
-
-static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
-{
-    int level, dc, diff, i, j, run;
-    int component;
-    RLTable *rl = &ff_rl_mpeg1;
-    uint8_t * const scantable    = s->intra_scantable.permutated;
-    const uint16_t *quant_matrix = s->intra_matrix;
-    const int qscale             = s->qscale;
-
-    /* DC coefficient */
-    component = (n <= 3 ? 0 : n - 4 + 1);
-    diff = decode_dc(&s->gb, component);
-    if (diff >= 0xffff)
-        return -1;
-    dc  = s->last_dc[component];
-    dc += diff;
-    s->last_dc[component] = dc;
-    block[0] = dc * quant_matrix[0];
-    av_dlog(s->avctx, "dc=%d diff=%d\n", dc, diff);
-    i = 0;
-    {
-        OPEN_READER(re, &s->gb);
-        /* now quantify & encode AC coefficients */
-        for (;;) {
-            UPDATE_CACHE(re, &s->gb);
-            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
-            if (level == 127) {
-                break;
-            } else if (level != 0) {
-                i += run;
-                j = scantable[i];
-                level = (level * qscale * quant_matrix[j]) >> 4;
-                level = (level - 1) | 1;
-                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                LAST_SKIP_BITS(re, &s->gb, 1);
-            } else {
-                /* escape */
-                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
-                UPDATE_CACHE(re, &s->gb);
-                level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
-                if (level == -128) {
-                    level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8);
-                } else if (level == 0) {
-                    level = SHOW_UBITS(re, &s->gb, 8)      ; LAST_SKIP_BITS(re, &s->gb, 8);
-                }
-                i += run;
-                j = scantable[i];
-                if (level < 0) {
-                    level = -level;
-                    level = (level * qscale * quant_matrix[j]) >> 4;
-                    level = (level - 1) | 1;
-                    level = -level;
-                } else {
-                    level = (level * qscale * quant_matrix[j]) >> 4;
-                    level = (level - 1) | 1;
-                }
-            }
-            if (i > 63) {
-                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
-                return -1;
-            }
-
-            block[j] = level;
-        }
-        CLOSE_READER(re, &s->gb);
-    }
-    s->block_last_index[n] = i;
-   return 0;
-}
-
-int ff_mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
-{
-    return mpeg1_decode_block_intra(s, block, n);
-}
-
-static inline int mpeg1_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n)
-{
-    int level, i, j, run;
-    RLTable *rl = &ff_rl_mpeg1;
-    uint8_t * const scantable    = s->intra_scantable.permutated;
-    const uint16_t *quant_matrix = s->inter_matrix;
-    const int qscale             = s->qscale;
-
-    {
-        OPEN_READER(re, &s->gb);
-        i = -1;
-        // special case for first coefficient, no need to add second VLC table
-        UPDATE_CACHE(re, &s->gb);
-        if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
-            level = (3 * qscale * quant_matrix[0]) >> 5;
-            level = (level - 1) | 1;
-            if (GET_CACHE(re, &s->gb) & 0x40000000)
-                level = -level;
-            block[0] = level;
-            i++;
-            SKIP_BITS(re, &s->gb, 2);
-            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
-                goto end;
-        }
-        /* now quantify & encode AC coefficients */
-        for (;;) {
-            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
-            if (level != 0) {
-                i += run;
-                j = scantable[i];
-                level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
-                level = (level - 1) | 1;
-                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                SKIP_BITS(re, &s->gb, 1);
-            } else {
-                /* escape */
-                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
-                UPDATE_CACHE(re, &s->gb);
-                level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
-                if (level == -128) {
-                    level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
-                } else if (level == 0) {
-                    level = SHOW_UBITS(re, &s->gb, 8)      ; SKIP_BITS(re, &s->gb, 8);
-                }
-                i += run;
-                j = scantable[i];
-                if (level < 0) {
-                    level = -level;
-                    level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
-                    level = (level - 1) | 1;
-                    level = -level;
-                } else {
-                    level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
-                    level = (level - 1) | 1;
-                }
-            }
-            if (i > 63) {
-                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
-                return -1;
-            }
-
-            block[j] = level;
-            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
-                break;
-            UPDATE_CACHE(re, &s->gb);
-        }
-end:
-        LAST_SKIP_BITS(re, &s->gb, 2);
-        CLOSE_READER(re, &s->gb);
-    }
-    s->block_last_index[n] = i;
-    return 0;
-}
-
-static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *block, int n)
-{
-    int level, i, j, run;
-    RLTable *rl = &ff_rl_mpeg1;
-    uint8_t * const scantable = s->intra_scantable.permutated;
-    const int qscale          = s->qscale;
-
-    {
-        OPEN_READER(re, &s->gb);
-        i = -1;
-        // special case for first coefficient, no need to add second VLC table
-        UPDATE_CACHE(re, &s->gb);
-        if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
-            level = (3 * qscale) >> 1;
-            level = (level - 1) | 1;
-            if (GET_CACHE(re, &s->gb) & 0x40000000)
-                level = -level;
-            block[0] = level;
-            i++;
-            SKIP_BITS(re, &s->gb, 2);
-            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
-                goto end;
-        }
-
-        /* now quantify & encode AC coefficients */
-        for (;;) {
-            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
-            if (level != 0) {
-                i += run;
-                j = scantable[i];
-                level = ((level * 2 + 1) * qscale) >> 1;
-                level = (level - 1) | 1;
-                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                SKIP_BITS(re, &s->gb, 1);
-            } else {
-                /* escape */
-                run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
-                UPDATE_CACHE(re, &s->gb);
-                level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
-                if (level == -128) {
-                    level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
-                } else if (level == 0) {
-                    level = SHOW_UBITS(re, &s->gb, 8)      ; SKIP_BITS(re, &s->gb, 8);
-                }
-                i += run;
-                j = scantable[i];
-                if (level < 0) {
-                    level = -level;
-                    level = ((level * 2 + 1) * qscale) >> 1;
-                    level = (level - 1) | 1;
-                    level = -level;
-                } else {
-                    level = ((level * 2 + 1) * qscale) >> 1;
-                    level = (level - 1) | 1;
-                }
-            }
-
-            block[j] = level;
-            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
-                break;
-            UPDATE_CACHE(re, &s->gb);
-        }
-end:
-        LAST_SKIP_BITS(re, &s->gb, 2);
-        CLOSE_READER(re, &s->gb);
-    }
-    s->block_last_index[n] = i;
-    return 0;
-}
-
-
-static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block, int n)
-{
-    int level, i, j, run;
-    RLTable *rl = &ff_rl_mpeg1;
-    uint8_t * const scantable = s->intra_scantable.permutated;
-    const uint16_t *quant_matrix;
-    const int qscale = s->qscale;
-    int mismatch;
-
-    mismatch = 1;
-
-    {
-        OPEN_READER(re, &s->gb);
-        i = -1;
-        if (n < 4)
-            quant_matrix = s->inter_matrix;
-        else
-            quant_matrix = s->chroma_inter_matrix;
-
-        // special case for first coefficient, no need to add second VLC table
-        UPDATE_CACHE(re, &s->gb);
-        if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
-            level= (3 * qscale * quant_matrix[0]) >> 5;
-            if (GET_CACHE(re, &s->gb) & 0x40000000)
-                level = -level;
-            block[0]  = level;
-            mismatch ^= level;
-            i++;
-            SKIP_BITS(re, &s->gb, 2);
-            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
-                goto end;
-        }
-
-        /* now quantify & encode AC coefficients */
-        for (;;) {
-            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
-            if (level != 0) {
-                i += run;
-                j = scantable[i];
-                level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
-                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                SKIP_BITS(re, &s->gb, 1);
-            } else {
-                /* escape */
-                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
-                UPDATE_CACHE(re, &s->gb);
-                level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
-
-                i += run;
-                j = scantable[i];
-                if (level < 0) {
-                    level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
-                    level = -level;
-                } else {
-                    level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
-                }
-            }
-            if (i > 63) {
-                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
-                return -1;
-            }
-
-            mismatch ^= level;
-            block[j]  = level;
-            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
-                break;
-            UPDATE_CACHE(re, &s->gb);
-        }
-end:
-        LAST_SKIP_BITS(re, &s->gb, 2);
-        CLOSE_READER(re, &s->gb);
-    }
-    block[63] ^= (mismatch & 1);
-
-    s->block_last_index[n] = i;
-    return 0;
-}
-
-static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
-                                                    DCTELEM *block, int n)
-{
-    int level, i, j, run;
-    RLTable *rl = &ff_rl_mpeg1;
-    uint8_t * const scantable = s->intra_scantable.permutated;
-    const int qscale          = s->qscale;
-    OPEN_READER(re, &s->gb);
-    i = -1;
-
-    // special case for first coefficient, no need to add second VLC table
-    UPDATE_CACHE(re, &s->gb);
-    if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
-        level = (3 * qscale) >> 1;
-        if (GET_CACHE(re, &s->gb) & 0x40000000)
-            level = -level;
-        block[0] = level;
-        i++;
-        SKIP_BITS(re, &s->gb, 2);
-        if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
-            goto end;
-    }
-
-    /* now quantify & encode AC coefficients */
-    for (;;) {
-        GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
-        if (level != 0) {
-            i += run;
-            j  = scantable[i];
-            level = ((level * 2 + 1) * qscale) >> 1;
-            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-            SKIP_BITS(re, &s->gb, 1);
-        } else {
-            /* escape */
-            run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
-            UPDATE_CACHE(re, &s->gb);
-            level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
-
-            i += run;
-            j  = scantable[i];
-            if (level < 0) {
-                level = ((-level * 2 + 1) * qscale) >> 1;
-                level = -level;
-            } else {
-                level = ((level * 2 + 1) * qscale) >> 1;
-            }
-        }
-
-        block[j] = level;
-        if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
-            break;
-        UPDATE_CACHE(re, &s->gb);
-    }
-end:
-    LAST_SKIP_BITS(re, &s->gb, 2);
-    CLOSE_READER(re, &s->gb);
-    s->block_last_index[n] = i;
-    return 0;
-}
-
-
-static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
-{
-    int level, dc, diff, i, j, run;
-    int component;
-    RLTable *rl;
-    uint8_t * const scantable = s->intra_scantable.permutated;
-    const uint16_t *quant_matrix;
-    const int qscale = s->qscale;
-    int mismatch;
-
-    /* DC coefficient */
-    if (n < 4) {
-        quant_matrix = s->intra_matrix;
-        component = 0;
-    } else {
-        quant_matrix = s->chroma_intra_matrix;
-        component = (n & 1) + 1;
-    }
-    diff = decode_dc(&s->gb, component);
-    if (diff >= 0xffff)
-        return -1;
-    dc  = s->last_dc[component];
-    dc += diff;
-    s->last_dc[component] = dc;
-    block[0] = dc << (3 - s->intra_dc_precision);
-    av_dlog(s->avctx, "dc=%d\n", block[0]);
-    mismatch = block[0] ^ 1;
-    i = 0;
-    if (s->intra_vlc_format)
-        rl = &ff_rl_mpeg2;
-    else
-        rl = &ff_rl_mpeg1;
-
-    {
-        OPEN_READER(re, &s->gb);
-        /* now quantify & encode AC coefficients */
-        for (;;) {
-            UPDATE_CACHE(re, &s->gb);
-            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
-            if (level == 127) {
-                break;
-            } else if (level != 0) {
-                i += run;
-                j  = scantable[i];
-                level = (level * qscale * quant_matrix[j]) >> 4;
-                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                LAST_SKIP_BITS(re, &s->gb, 1);
-            } else {
-                /* escape */
-                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
-                UPDATE_CACHE(re, &s->gb);
-                level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
-                i += run;
-                j  = scantable[i];
-                if (level < 0) {
-                    level = (-level * qscale * quant_matrix[j]) >> 4;
-                    level = -level;
-                } else {
-                    level = (level * qscale * quant_matrix[j]) >> 4;
-                }
-            }
-            if (i > 63) {
-                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
-                return -1;
-            }
-
-            mismatch ^= level;
-            block[j]  = level;
-        }
-        CLOSE_READER(re, &s->gb);
-    }
-    block[63] ^= mismatch & 1;
-
-    s->block_last_index[n] = i;
-    return 0;
-}
-
-static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n)
-{
-    int level, dc, diff, j, run;
-    int component;
-    RLTable *rl;
-    uint8_t * scantable = s->intra_scantable.permutated;
-    const uint16_t *quant_matrix;
-    const int qscale = s->qscale;
-
-    /* DC coefficient */
-    if (n < 4) {
-        quant_matrix = s->intra_matrix;
-        component = 0;
-    } else {
-        quant_matrix = s->chroma_intra_matrix;
-        component = (n & 1) + 1;
-    }
-    diff = decode_dc(&s->gb, component);
-    if (diff >= 0xffff)
-        return -1;
-    dc = s->last_dc[component];
-    dc += diff;
-    s->last_dc[component] = dc;
-    block[0] = dc << (3 - s->intra_dc_precision);
-    if (s->intra_vlc_format)
-        rl = &ff_rl_mpeg2;
-    else
-        rl = &ff_rl_mpeg1;
-
-    {
-        OPEN_READER(re, &s->gb);
-        /* now quantify & encode AC coefficients */
-        for (;;) {
-            UPDATE_CACHE(re, &s->gb);
-            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
-            if (level == 127) {
-                break;
-            } else if (level != 0) {
-                scantable += run;
-                j = *scantable;
-                level = (level * qscale * quant_matrix[j]) >> 4;
-                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                LAST_SKIP_BITS(re, &s->gb, 1);
-            } else {
-                /* escape */
-                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
-                UPDATE_CACHE(re, &s->gb);
-                level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
-                scantable += run;
-                j = *scantable;
-                if (level < 0) {
-                    level = (-level * qscale * quant_matrix[j]) >> 4;
-                    level = -level;
-                } else {
-                    level = (level * qscale * quant_matrix[j]) >> 4;
-                }
-            }
-
-            block[j] = level;
-        }
-        CLOSE_READER(re, &s->gb);
-    }
+uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
 
-    s->block_last_index[n] = scantable - s->intra_scantable.permutated;
-    return 0;
-}
+static const uint8_t table_mb_ptype[7][2] = {
+    { 3, 5 }, // 0x01 MB_INTRA
+    { 1, 2 }, // 0x02 MB_PAT
+    { 1, 3 }, // 0x08 MB_FOR
+    { 1, 1 }, // 0x0A MB_FOR|MB_PAT
+    { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
+    { 1, 5 }, // 0x12 MB_QUANT|MB_PAT
+    { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
+};
 
-uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
+static const uint8_t table_mb_btype[11][2] = {
+    { 3, 5 }, // 0x01 MB_INTRA
+    { 2, 3 }, // 0x04 MB_BACK
+    { 3, 3 }, // 0x06 MB_BACK|MB_PAT
+    { 2, 4 }, // 0x08 MB_FOR
+    { 3, 4 }, // 0x0A MB_FOR|MB_PAT
+    { 2, 2 }, // 0x0C MB_FOR|MB_BACK
+    { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT
+    { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
+    { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT
+    { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
+    { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT
+};
 
 #define INIT_2D_VLC_RL(rl, static_size)\
 {\
@@ -603,7 +73,7 @@ uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
     init_2d_vlc_rl(&rl);\
 }
 
-static void init_2d_vlc_rl(RLTable *rl)
+static av_cold void init_2d_vlc_rl(RLTable *rl)
 {
     int i;
 
@@ -636,7 +106,7 @@ static void init_2d_vlc_rl(RLTable *rl)
     }
 }
 
-void ff_mpeg12_common_init(MpegEncContext *s)
+av_cold void ff_mpeg12_common_init(MpegEncContext *s)
 {
 
     s->y_dc_scale_table =
@@ -656,13 +126,15 @@ void ff_mpeg1_clean_buffers(MpegEncContext *s)
 /******************************************/
 /* decoding */
 
+VLC ff_mv_vlc;
+
 VLC ff_dc_lum_vlc;
 VLC ff_dc_chroma_vlc;
 
-static VLC mbincr_vlc;
-static VLC mb_ptype_vlc;
-static VLC mb_btype_vlc;
-static VLC mb_pat_vlc;
+VLC ff_mbincr_vlc;
+VLC ff_mb_ptype_vlc;
+VLC ff_mb_btype_vlc;
+VLC ff_mb_pat_vlc;
 
 av_cold void ff_mpeg12_init_vlcs(void)
 {
@@ -677,20 +149,20 @@ av_cold void ff_mpeg12_init_vlcs(void)
         INIT_VLC_STATIC(&ff_dc_chroma_vlc,  DC_VLC_BITS, 12,
                         ff_mpeg12_vlc_dc_chroma_bits, 1, 1,
                         ff_mpeg12_vlc_dc_chroma_code, 2, 2, 514);
-        INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 17,
+        INIT_VLC_STATIC(&ff_mv_vlc, MV_VLC_BITS, 17,
                         &ff_mpeg12_mbMotionVectorTable[0][1], 2, 1,
                         &ff_mpeg12_mbMotionVectorTable[0][0], 2, 1, 518);
-        INIT_VLC_STATIC(&mbincr_vlc, MBINCR_VLC_BITS, 36,
+        INIT_VLC_STATIC(&ff_mbincr_vlc, MBINCR_VLC_BITS, 36,
                         &ff_mpeg12_mbAddrIncrTable[0][1], 2, 1,
                         &ff_mpeg12_mbAddrIncrTable[0][0], 2, 1, 538);
-        INIT_VLC_STATIC(&mb_pat_vlc, MB_PAT_VLC_BITS, 64,
+        INIT_VLC_STATIC(&ff_mb_pat_vlc, MB_PAT_VLC_BITS, 64,
                         &ff_mpeg12_mbPatTable[0][1], 2, 1,
                         &ff_mpeg12_mbPatTable[0][0], 2, 1, 512);
 
-        INIT_VLC_STATIC(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7,
+        INIT_VLC_STATIC(&ff_mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7,
                         &table_mb_ptype[0][1], 2, 1,
                         &table_mb_ptype[0][0], 2, 1, 64);
-        INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11,
+        INIT_VLC_STATIC(&ff_mb_btype_vlc, MB_BTYPE_VLC_BITS, 11,
                         &table_mb_btype[0][1], 2, 1,
                         &table_mb_btype[0][0], 2, 1, 64);
         ff_init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);
@@ -701,1898 +173,66 @@ av_cold void ff_mpeg12_init_vlcs(void)
     }
 }
 
-static inline int get_dmv(MpegEncContext *s)
-{
-    if (get_bits1(&s->gb))
-        return 1 - (get_bits1(&s->gb) << 1);
-    else
-        return 0;
-}
-
-static inline int get_qscale(MpegEncContext *s)
-{
-    int qscale = get_bits(&s->gb, 5);
-    if (s->q_scale_type) {
-        return non_linear_qscale[qscale];
-    } else {
-        return qscale << 1;
-    }
-}
-
-static void exchange_uv(MpegEncContext *s)
-{
-    DCTELEM (*tmp)[64];
-
-    tmp           = s->pblocks[4];
-    s->pblocks[4] = s->pblocks[5];
-    s->pblocks[5] = tmp;
-}
-
-/* motion type (for MPEG-2) */
-#define MT_FIELD 1
-#define MT_FRAME 2
-#define MT_16X8  2
-#define MT_DMV   3
-
-static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64])
+/**
+ * Find the end of the current frame in the bitstream.
+ * @return the position of the first byte of the next frame, or -1
+ */
+int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s)
 {
-    int i, j, k, cbp, val, mb_type, motion_type;
-    const int mb_block_count = 4 + (1 << s->chroma_format);
-
-    av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
-
-    assert(s->mb_skipped == 0);
-
-    if (s->mb_skip_run-- != 0) {
-        if (s->pict_type == AV_PICTURE_TYPE_P) {
-            s->mb_skipped = 1;
-            s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
-        } else {
-            int mb_type;
-
-            if (s->mb_x)
-                mb_type = s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
-            else
-                mb_type = s->current_picture.f.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
-            if (IS_INTRA(mb_type))
-                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));
-
-            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;
-        }
+    int i;
+    uint32_t state = pc->state;
 
+    /* EOF considered as end of frame */
+    if (buf_size == 0)
         return 0;
-    }
-
-    switch (s->pict_type) {
-    default:
-    case AV_PICTURE_TYPE_I:
-        if (get_bits1(&s->gb) == 0) {
-            if (get_bits1(&s->gb) == 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);
-                return -1;
-            }
-            mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
-        } else {
-            mb_type = MB_TYPE_INTRA;
-        }
-        break;
-    case AV_PICTURE_TYPE_P:
-        mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
-        if (mb_type < 0) {
-            av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
-            return -1;
-        }
-        mb_type = ptype2mb_type[mb_type];
-        break;
-    case AV_PICTURE_TYPE_B:
-        mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
-        if (mb_type < 0) {
-            av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
-            return -1;
-        }
-        mb_type = btype2mb_type[mb_type];
-        break;
-    }
-    av_dlog(s->avctx, "mb_type=%x\n", mb_type);
-//    motion_type = 0; /* avoid warning */
-    if (IS_INTRA(mb_type)) {
-        s->dsp.clear_blocks(s->block[0]);
-
-        if (!s->chroma_y_shift) {
-            s->dsp.clear_blocks(s->block[6]);
-        }
-
-        /* compute DCT type */
-        if (s->picture_structure == PICT_FRAME && // FIXME add an interlaced_dct coded var?
-            !s->frame_pred_frame_dct) {
-            s->interlaced_dct = get_bits1(&s->gb);
-        }
-
-        if (IS_QUANT(mb_type))
-            s->qscale = get_qscale(s);
-
-        if (s->concealment_motion_vectors) {
-            /* just parse them */
-            if (s->picture_structure != PICT_FRAME)
-                skip_bits1(&s->gb); /* field select */
-
-            s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =
-                mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);
-            s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =
-                mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);
 
-            skip_bits1(&s->gb); /* marker */
-        } else
-            memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
-        s->mb_intra = 1;
-        // if 1, we memcpy blocks in xvmcvideo
-        if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
-            ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
-            if (s->swap_uv) {
-                exchange_uv(s);
-            }
-        }
-
-        if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
-            if (s->flags2 & CODEC_FLAG2_FAST) {
-                for (i = 0; i < 6; i++) {
-                    mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
-                }
-            } else {
-                for (i = 0; i < mb_block_count; i++) {
-                    if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
-                        return -1;
-                }
-            }
-        } else {
-            for (i = 0; i < 6; i++) {
-                if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
-                    return -1;
-            }
-        }
-    } else {
-        if (mb_type & MB_TYPE_ZERO_MV) {
-            assert(mb_type & MB_TYPE_CBP);
+/*
+ 0  frame start         -> 1/4
+ 1  first_SEQEXT        -> 0/2
+ 2  first field start   -> 3/0
+ 3  second_SEQEXT       -> 2/0
+ 4  searching end
+*/
 
-            s->mv_dir = MV_DIR_FORWARD;
-            if (s->picture_structure == PICT_FRAME) {
-                if (!s->frame_pred_frame_dct)
-                    s->interlaced_dct = get_bits1(&s->gb);
-                s->mv_type = MV_TYPE_16X16;
-            } else {
-                s->mv_type = MV_TYPE_FIELD;
-                mb_type |= MB_TYPE_INTERLACED;
-                s->field_select[0][0] = s->picture_structure - 1;
+    for (i = 0; i < buf_size; i++) {
+        assert(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--;
+            else if (state == EXT_START_CODE + 2) {
+                if ((buf[i] & 3) == 3)
+                    pc->frame_start_found = 0;
+                else
+                    pc->frame_start_found = (pc->frame_start_found + 1) & 3;
             }
-
-            if (IS_QUANT(mb_type))
-                s->qscale = get_qscale(s);
-
-            s->last_mv[0][0][0] = 0;
-            s->last_mv[0][0][1] = 0;
-            s->last_mv[0][1][0] = 0;
-            s->last_mv[0][1][1] = 0;
-            s->mv[0][0][0] = 0;
-            s->mv[0][0][1] = 0;
+            state++;
         } else {
-            assert(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)
-                motion_type = MT_FRAME;
-            else {
-                motion_type = get_bits(&s->gb, 2);
-                if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
-                    s->interlaced_dct = get_bits1(&s->gb);
-            }
-
-            if (IS_QUANT(mb_type))
-                s->qscale = get_qscale(s);
-
-            /* motion vectors */
-            s->mv_dir = (mb_type >> 13) & 3;
-            av_dlog(s->avctx, "motion_type=%d\n", motion_type);
-            switch (motion_type) {
-            case MT_FRAME: /* or MT_16X8 */
-                if (s->picture_structure == PICT_FRAME) {
-                    mb_type |= MB_TYPE_16x16;
-                    s->mv_type = MV_TYPE_16X16;
-                    for (i = 0; i < 2; i++) {
-                        if (USES_LIST(mb_type, i)) {
-                            /* MT_FRAME */
-                            s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] =
-                                mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]);
-                            s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] =
-                                mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]);
-                            /* full_pel: only for MPEG-1 */
-                            if (s->full_pel[i]) {
-                                s->mv[i][0][0] <<= 1;
-                                s->mv[i][0][1] <<= 1;
-                            }
-                        }
-                    }
-                } else {
-                    mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
-                    s->mv_type = MV_TYPE_16X8;
-                    for (i = 0; i < 2; i++) {
-                        if (USES_LIST(mb_type, i)) {
-                            /* MT_16X8 */
-                            for (j = 0; j < 2; j++) {
-                                s->field_select[i][j] = get_bits1(&s->gb);
-                                for (k = 0; k < 2; k++) {
-                                    val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
-                                                             s->last_mv[i][j][k]);
-                                    s->last_mv[i][j][k] = val;
-                                    s->mv[i][j][k]      = val;
-                                }
-                            }
-                        }
-                    }
-                }
-                break;
-            case MT_FIELD:
-                s->mv_type = MV_TYPE_FIELD;
-                if (s->picture_structure == PICT_FRAME) {
-                    mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
-                    for (i = 0; i < 2; i++) {
-                        if (USES_LIST(mb_type, i)) {
-                            for (j = 0; j < 2; j++) {
-                                s->field_select[i][j] = get_bits1(&s->gb);
-                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
-                                                         s->last_mv[i][j][0]);
-                                s->last_mv[i][j][0] = val;
-                                s->mv[i][j][0]      = val;
-                                av_dlog(s->avctx, "fmx=%d\n", val);
-                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
-                                                         s->last_mv[i][j][1] >> 1);
-                                s->last_mv[i][j][1] = val << 1;
-                                s->mv[i][j][1]      = val;
-                                av_dlog(s->avctx, "fmy=%d\n", val);
-                            }
-                        }
-                    }
-                } else {
-                    mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
-                    for (i = 0; i < 2; i++) {
-                        if (USES_LIST(mb_type, i)) {
-                            s->field_select[i][0] = get_bits1(&s->gb);
-                            for (k = 0; k < 2; k++) {
-                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
-                                                         s->last_mv[i][0][k]);
-                                s->last_mv[i][0][k] = val;
-                                s->last_mv[i][1][k] = val;
-                                s->mv[i][0][k]      = val;
-                            }
-                        }
-                    }
-                }
-                break;
-            case MT_DMV:
-                s->mv_type = MV_TYPE_DMV;
-                for (i = 0; i < 2; i++) {
-                    if (USES_LIST(mb_type, i)) {
-                        int dmx, dmy, mx, my, m;
-                        const int my_shift = s->picture_structure == PICT_FRAME;
-
-                        mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
-                                                s->last_mv[i][0][0]);
-                        s->last_mv[i][0][0] = mx;
-                        s->last_mv[i][1][0] = mx;
-                        dmx = get_dmv(s);
-                        my  = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
-                                                 s->last_mv[i][0][1] >> my_shift);
-                        dmy = get_dmv(s);
-
-
-                        s->last_mv[i][0][1] = my << my_shift;
-                        s->last_mv[i][1][1] = my << my_shift;
-
-                        s->mv[i][0][0] = mx;
-                        s->mv[i][0][1] = my;
-                        s->mv[i][1][0] = mx; // not used
-                        s->mv[i][1][1] = my; // not used
-
-                        if (s->picture_structure == PICT_FRAME) {
-                            mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
-
-                            // m = 1 + 2 * s->top_field_first;
-                            m = s->top_field_first ? 1 : 3;
-
-                            /* top -> top pred */
-                            s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
-                            s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
-                            m = 4 - m;
-                            s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
-                            s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
-                        } else {
-                            mb_type |= MB_TYPE_16x16;
-
-                            s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
-                            s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
-                            if (s->picture_structure == PICT_TOP_FIELD)
-                                s->mv[i][2][1]--;
-                            else
-                                s->mv[i][2][1]++;
-                        }
-                    }
-                }
-                break;
-            default:
-                av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
-                return -1;
-            }
-        }
-
-        s->mb_intra = 0;
-        if (HAS_CBP(mb_type)) {
-            s->dsp.clear_blocks(s->block[0]);
-
-            cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
-            if (mb_block_count > 6) {
-                 cbp <<= mb_block_count - 6;
-                 cbp  |= get_bits(&s->gb, mb_block_count - 6);
-                 s->dsp.clear_blocks(s->block[6]);
+            i = avpriv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1;
+            if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) {
+                i++;
+                pc->frame_start_found = 4;
             }
-            if (cbp <= 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
-                return -1;
+            if (state == SEQ_END_CODE) {
+                pc->frame_start_found = 0;
+                pc->state=-1;
+                return i+1;
             }
-
-            //if 1, we memcpy blocks in xvmcvideo
-            if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
-                ff_xvmc_pack_pblocks(s, cbp);
-                if (s->swap_uv) {
-                    exchange_uv(s);
+            if (pc->frame_start_found == 2 && state == SEQ_START_CODE)
+                pc->frame_start_found = 0;
+            if (pc->frame_start_found  < 4 && state == EXT_START_CODE)
+                pc->frame_start_found++;
+            if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) {
+                if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) {
+                    pc->frame_start_found = 0;
+                    pc->state             = -1;
+                    return i - 3;
                 }
             }
-
-            if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
-                if (s->flags2 & CODEC_FLAG2_FAST) {
-                    for (i = 0; i < 6; i++) {
-                        if (cbp & 32) {
-                            mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
-                        } else {
-                            s->block_last_index[i] = -1;
-                        }
-                        cbp += cbp;
-                    }
-                } else {
-                    cbp <<= 12-mb_block_count;
-
-                    for (i = 0; i < mb_block_count; i++) {
-                        if (cbp & (1 << 11)) {
-                            if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
-                                return -1;
-                        } else {
-                            s->block_last_index[i] = -1;
-                        }
-                        cbp += cbp;
-                    }
-                }
-            } else {
-                if (s->flags2 & CODEC_FLAG2_FAST) {
-                    for (i = 0; i < 6; i++) {
-                        if (cbp & 32) {
-                            mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
-                        } else {
-                            s->block_last_index[i] = -1;
-                        }
-                        cbp += cbp;
-                    }
-                } else {
-                    for (i = 0; i < 6; i++) {
-                        if (cbp & 32) {
-                            if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
-                                return -1;
-                        } else {
-                            s->block_last_index[i] = -1;
-                        }
-                        cbp += cbp;
-                    }
-                }
+            if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) {
+                ff_fetch_timestamp(s, i - 3, 1);
             }
-        } else {
-            for (i = 0; i < 12; i++)
-                s->block_last_index[i] = -1;
         }
     }
-
-    s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
-
-    return 0;
-}
-
-static av_cold int mpeg_decode_init(AVCodecContext *avctx)
-{
-    Mpeg1Context *s = avctx->priv_data;
-    MpegEncContext *s2 = &s->mpeg_enc_ctx;
-    int i;
-
-    /* we need some permutation to store matrices,
-     * until MPV_common_init() sets the real permutation. */
-    for (i = 0; i < 64; i++)
-       s2->dsp.idct_permutation[i]=i;
-
-    ff_MPV_decode_defaults(s2);
-
-    s->mpeg_enc_ctx.avctx  = avctx;
-    s->mpeg_enc_ctx.flags  = avctx->flags;
-    s->mpeg_enc_ctx.flags2 = avctx->flags2;
-    ff_mpeg12_common_init(&s->mpeg_enc_ctx);
-    ff_mpeg12_init_vlcs();
-
-    s->mpeg_enc_ctx_allocated      = 0;
-    s->mpeg_enc_ctx.picture_number = 0;
-    s->repeat_field                = 0;
-    s->mpeg_enc_ctx.codec_id       = avctx->codec->id;
-    avctx->color_range = AVCOL_RANGE_MPEG;
-    if (avctx->codec->id == AV_CODEC_ID_MPEG1VIDEO)
-        avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
-    else
-        avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
-    return 0;
+    pc->state = state;
+    return END_NOT_FOUND;
 }
-
-static int mpeg_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
-{
-    Mpeg1Context *ctx = avctx->priv_data, *ctx_from = avctx_from->priv_data;
-    MpegEncContext *s = &ctx->mpeg_enc_ctx, *s1 = &ctx_from->mpeg_enc_ctx;
-    int err;
-
-    if (avctx == avctx_from || !ctx_from->mpeg_enc_ctx_allocated || !s1->context_initialized)
-        return 0;
-
-    err = ff_mpeg_update_thread_context(avctx, avctx_from);
-    if (err) return err;
-
-    if (!ctx->mpeg_enc_ctx_allocated)
-        memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext));
-
-    if (!(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay))
-        s->picture_number++;
-
-    return 0;
-}
-
-static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm,
-                                 const uint8_t *new_perm)
-{
-    uint16_t temp_matrix[64];
-    int i;
-
-    memcpy(temp_matrix, matrix, 64 * sizeof(uint16_t));
-
-    for (i = 0; i < 64; i++) {
-        matrix[new_perm[i]] = temp_matrix[old_perm[i]];
-    }
-}
-
-static const enum AVPixelFormat pixfmt_xvmc_mpg2_420[] = {
-    AV_PIX_FMT_XVMC_MPEG2_IDCT,
-    AV_PIX_FMT_XVMC_MPEG2_MC,
-    AV_PIX_FMT_NONE };
-
-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;
-    }
-}
-
-/* Call this function when we know all parameters.
- * It may be called in different places for MPEG-1 and MPEG-2. */
-static int mpeg_decode_postinit(AVCodecContext *avctx)
-{
-    Mpeg1Context *s1 = avctx->priv_data;
-    MpegEncContext *s = &s1->mpeg_enc_ctx;
-    uint8_t old_permutation[64];
-
-    if ((s1->mpeg_enc_ctx_allocated == 0) ||
-        avctx->coded_width  != s->width   ||
-        avctx->coded_height != s->height  ||
-        s1->save_width           != s->width                ||
-        s1->save_height          != s->height               ||
-        s1->save_aspect_info     != s->aspect_ratio_info    ||
-        s1->save_progressive_seq != s->progressive_sequence ||
-        0)
-    {
-
-        if (s1->mpeg_enc_ctx_allocated) {
-            ParseContext pc = s->parse_context;
-            s->parse_context.buffer = 0;
-            ff_MPV_common_end(s);
-            s->parse_context = pc;
-        }
-
-        if ((s->width == 0) || (s->height == 0))
-            return -2;
-
-        avcodec_set_dimensions(avctx, s->width, s->height);
-        avctx->bit_rate          = s->bit_rate;
-        s1->save_aspect_info     = s->aspect_ratio_info;
-        s1->save_width           = s->width;
-        s1->save_height          = s->height;
-        s1->save_progressive_seq = s->progressive_sequence;
-
-        /* low_delay may be forced, in this case we will have B-frames
-         * that behave like P-frames. */
-        avctx->has_b_frames = !s->low_delay;
-
-        if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
-            //MPEG-1 fps
-            avctx->time_base.den = ff_mpeg12_frame_rate_tab[s->frame_rate_index].num;
-            avctx->time_base.num = ff_mpeg12_frame_rate_tab[s->frame_rate_index].den;
-            //MPEG-1 aspect
-            avctx->sample_aspect_ratio = av_d2q(1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255);
-            avctx->ticks_per_frame=1;
-        } else {//MPEG-2
-        //MPEG-2 fps
-            av_reduce(&s->avctx->time_base.den,
-                      &s->avctx->time_base.num,
-                      ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2,
-                      ff_mpeg12_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
-                      1 << 30);
-            avctx->ticks_per_frame = 2;
-            //MPEG-2 aspect
-            if (s->aspect_ratio_info > 1) {
-                AVRational dar =
-                    av_mul_q(av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
-                                      (AVRational) {s1->pan_scan.width, s1->pan_scan.height}),
-                             (AVRational) {s->width, s->height});
-
-                // we ignore the spec here and guess a bit as reality does not match the spec, see for example
-                // res_change_ffmpeg_aspect.ts and sequence-display-aspect.mpg
-                // issue1613, 621, 562
-                if ((s1->pan_scan.width == 0) || (s1->pan_scan.height == 0) ||
-                   (av_cmp_q(dar, (AVRational) {4, 3}) && av_cmp_q(dar, (AVRational) {16, 9}))) {
-                    s->avctx->sample_aspect_ratio =
-                        av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
-                                 (AVRational) {s->width, s->height});
-                } else {
-                    s->avctx->sample_aspect_ratio =
-                        av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
-                                 (AVRational) {s1->pan_scan.width, s1->pan_scan.height});
-//issue1613 4/3 16/9 -> 16/9
-//res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3
-//widescreen-issue562.mpg 4/3 16/9 -> 16/9
-//                    s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height});
-                    av_dlog(avctx, "A %d/%d\n",
-                            ff_mpeg2_aspect[s->aspect_ratio_info].num, ff_mpeg2_aspect[s->aspect_ratio_info].den);
-                    av_dlog(avctx, "B %d/%d\n", s->avctx->sample_aspect_ratio.num,
-                            s->avctx->sample_aspect_ratio.den);
-                }
-            } else {
-                s->avctx->sample_aspect_ratio =
-                    ff_mpeg2_aspect[s->aspect_ratio_info];
-            }
-        } // MPEG-2
-
-        avctx->pix_fmt = mpeg_get_pixelformat(avctx);
-        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)
-            if (avctx->idct_algo == FF_IDCT_AUTO)
-                avctx->idct_algo = FF_IDCT_SIMPLE;
-
-        /* Quantization matrices may need reordering
-         * if DCT permutation is changed. */
-        memcpy(old_permutation, s->dsp.idct_permutation, 64 * sizeof(uint8_t));
-
-        if (ff_MPV_common_init(s) < 0)
-            return -2;
-
-        quant_matrix_rebuild(s->intra_matrix,        old_permutation, s->dsp.idct_permutation);
-        quant_matrix_rebuild(s->inter_matrix,        old_permutation, s->dsp.idct_permutation);
-        quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->dsp.idct_permutation);
-        quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->dsp.idct_permutation);
-
-        s1->mpeg_enc_ctx_allocated = 1;
-    }
-    return 0;
-}
-
-static int mpeg1_decode_picture(AVCodecContext *avctx,
-                                const uint8_t *buf, int buf_size)
-{
-    Mpeg1Context *s1 = avctx->priv_data;
-    MpegEncContext *s = &s1->mpeg_enc_ctx;
-    int ref, f_code, vbv_delay;
-
-    init_get_bits(&s->gb, buf, buf_size*8);
-
-    ref = get_bits(&s->gb, 10); /* temporal ref */
-    s->pict_type = get_bits(&s->gb, 3);
-    if (s->pict_type == 0 || s->pict_type > 3)
-        return -1;
-
-    vbv_delay = get_bits(&s->gb, 16);
-    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))
-            return -1;
-        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))
-            return -1;
-        s->mpeg_f_code[1][0] = f_code;
-        s->mpeg_f_code[1][1] = f_code;
-    }
-    s->current_picture.f.pict_type = s->pict_type;
-    s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
-
-    if (avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(avctx, AV_LOG_DEBUG, "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type);
-
-    s->y_dc_scale = 8;
-    s->c_dc_scale = 8;
-    return 0;
-}
-
-static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
-{
-    MpegEncContext *s= &s1->mpeg_enc_ctx;
-    int horiz_size_ext, vert_size_ext;
-    int bit_rate_ext;
-
-    skip_bits(&s->gb, 1); /* profile and level esc*/
-    s->avctx->profile       = get_bits(&s->gb, 3);
-    s->avctx->level         = get_bits(&s->gb, 4);
-    s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */
-    s->chroma_format        = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
-    horiz_size_ext          = get_bits(&s->gb, 2);
-    vert_size_ext           = get_bits(&s->gb, 2);
-    s->width  |= (horiz_size_ext << 12);
-    s->height |= (vert_size_ext  << 12);
-    bit_rate_ext = get_bits(&s->gb, 12);  /* XXX: handle it */
-    s->bit_rate += (bit_rate_ext << 18) * 400;
-    skip_bits1(&s->gb); /* marker */
-    s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10;
-
-    s->low_delay = get_bits1(&s->gb);
-    if (s->flags & CODEC_FLAG_LOW_DELAY)
-        s->low_delay = 1;
-
-    s1->frame_rate_ext.num = get_bits(&s->gb, 2) + 1;
-    s1->frame_rate_ext.den = get_bits(&s->gb, 5) + 1;
-
-    av_dlog(s->avctx, "sequence extension\n");
-    s->codec_id      = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
-
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n",
-               s->avctx->profile, s->avctx->level, s->avctx->rc_buffer_size, s->bit_rate);
-
-}
-
-static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
-{
-    MpegEncContext *s = &s1->mpeg_enc_ctx;
-    int color_description, w, h;
-
-    skip_bits(&s->gb, 3); /* video format */
-    color_description = get_bits1(&s->gb);
-    if (color_description) {
-        s->avctx->color_primaries = get_bits(&s->gb, 8);
-        s->avctx->color_trc       = get_bits(&s->gb, 8);
-        s->avctx->colorspace      = get_bits(&s->gb, 8);
-    }
-    w = get_bits(&s->gb, 14);
-    skip_bits(&s->gb, 1); //marker
-    h = get_bits(&s->gb, 14);
-    // remaining 3 bits are zero padding
-
-    s1->pan_scan.width  = 16 * w;
-    s1->pan_scan.height = 16 * h;
-
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h);
-}
-
-static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
-{
-    MpegEncContext *s = &s1->mpeg_enc_ctx;
-    int i, nofco;
-
-    nofco = 1;
-    if (s->progressive_sequence) {
-        if (s->repeat_first_field) {
-            nofco++;
-            if (s->top_field_first)
-                nofco++;
-        }
-    } else {
-        if (s->picture_structure == PICT_FRAME) {
-            nofco++;
-            if (s->repeat_first_field)
-                nofco++;
-        }
-    }
-    for (i = 0; i < nofco; i++) {
-        s1->pan_scan.position[i][0] = get_sbits(&s->gb, 16);
-        skip_bits(&s->gb, 1); // marker
-        s1->pan_scan.position[i][1] = get_sbits(&s->gb, 16);
-        skip_bits(&s->gb, 1); // marker
-    }
-
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(s->avctx, AV_LOG_DEBUG, "pde (%d,%d) (%d,%d) (%d,%d)\n",
-               s1->pan_scan.position[0][0], s1->pan_scan.position[0][1],
-               s1->pan_scan.position[1][0], s1->pan_scan.position[1][1],
-               s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]);
-}
-
-static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra)
-{
-    int i;
-
-    for (i = 0; i < 64; i++) {
-        int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
-        int v = get_bits(&s->gb, 8);
-        if (v == 0) {
-            av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
-            return -1;
-        }
-        if (intra && i == 0 && v != 8) {
-            av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n");
-            v = 8; // needed by pink.mpg / issue1046
-        }
-        matrix0[j] = v;
-        if (matrix1)
-            matrix1[j] = v;
-    }
-    return 0;
-}
-
-static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
-{
-    av_dlog(s->avctx, "matrix extension\n");
-
-    if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
-    if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
-    if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL           , 1);
-    if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL           , 0);
-}
-
-static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
-{
-    MpegEncContext *s = &s1->mpeg_enc_ctx;
-
-    s->full_pel[0] = s->full_pel[1] = 0;
-    s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);
-    s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);
-    s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);
-    s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);
-    if (!s->pict_type && s1->mpeg_enc_ctx_allocated) {
-        av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n");
-        if (s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1] == 15) {
-            if (s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)
-                s->pict_type = AV_PICTURE_TYPE_I;
-            else
-                s->pict_type = AV_PICTURE_TYPE_P;
-        } else
-            s->pict_type = AV_PICTURE_TYPE_B;
-        s->current_picture.f.pict_type = s->pict_type;
-        s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
-    }
-    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);
-    s->frame_pred_frame_dct       = get_bits1(&s->gb);
-    s->concealment_motion_vectors = get_bits1(&s->gb);
-    s->q_scale_type               = get_bits1(&s->gb);
-    s->intra_vlc_format           = get_bits1(&s->gb);
-    s->alternate_scan             = get_bits1(&s->gb);
-    s->repeat_first_field         = get_bits1(&s->gb);
-    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);
-        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
-    } else {
-        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
-        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
-    }
-
-    /* composite display not parsed */
-    av_dlog(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision);
-    av_dlog(s->avctx, "picture_structure=%d\n", s->picture_structure);
-    av_dlog(s->avctx, "top field first=%d\n", s->top_field_first);
-    av_dlog(s->avctx, "repeat first field=%d\n", s->repeat_first_field);
-    av_dlog(s->avctx, "conceal=%d\n", s->concealment_motion_vectors);
-    av_dlog(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format);
-    av_dlog(s->avctx, "alternate_scan=%d\n", s->alternate_scan);
-    av_dlog(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);
-    av_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame);
-}
-
-static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
-{
-    AVCodecContext *avctx = s->avctx;
-    Mpeg1Context *s1 = (Mpeg1Context*)s;
-
-    /* start frame decoding */
-    if (s->first_field || s->picture_structure == PICT_FRAME) {
-        if (ff_MPV_frame_start(s, avctx) < 0)
-            return -1;
-
-        ff_er_frame_start(s);
-
-        /* first check if we must repeat the frame */
-        s->current_picture_ptr->f.repeat_pict = 0;
-        if (s->repeat_first_field) {
-            if (s->progressive_sequence) {
-                if (s->top_field_first)
-                    s->current_picture_ptr->f.repeat_pict = 4;
-                else
-                    s->current_picture_ptr->f.repeat_pict = 2;
-            } else if (s->progressive_frame) {
-                s->current_picture_ptr->f.repeat_pict = 1;
-            }
-        }
-
-        *s->current_picture_ptr->f.pan_scan = s1->pan_scan;
-
-        if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
-            ff_thread_finish_setup(avctx);
-    } else { // second field
-        int i;
-
-        if (!s->current_picture_ptr) {
-            av_log(s->avctx, AV_LOG_ERROR, "first field missing\n");
-            return -1;
-        }
-
-        if (s->avctx->hwaccel &&
-            (s->avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
-            if (s->avctx->hwaccel->end_frame(s->avctx) < 0)
-                av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode first field\n");
-        }
-
-        for (i = 0; i < 4; i++) {
-            s->current_picture.f.data[i] = s->current_picture_ptr->f.data[i];
-            if (s->picture_structure == PICT_BOTTOM_FIELD) {
-                s->current_picture.f.data[i] += s->current_picture_ptr->f.linesize[i];
-            }
-        }
-    }
-
-    if (avctx->hwaccel) {
-        if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
-            return -1;
-    }
-
-// MPV_frame_start will call this function too,
-// but we need to call it on every field
-    if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
-        if (ff_xvmc_field_start(s, avctx) < 0)
-            return -1;
-
-    return 0;
-}
-
-#define DECODE_SLICE_ERROR -1
-#define DECODE_SLICE_OK     0
-
-/**
- * Decode a slice.
- * MpegEncContext.mb_y must be set to the MB row from the startcode.
- * @return DECODE_SLICE_ERROR if the slice is damaged,
- *         DECODE_SLICE_OK if this slice is OK
- */
-static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
-                             const uint8_t **buf, int buf_size)
-{
-    AVCodecContext *avctx = s->avctx;
-    const int field_pic   = s->picture_structure != PICT_FRAME;
-
-    s->resync_mb_x =
-    s->resync_mb_y = -1;
-
-    assert(mb_y < s->mb_height);
-
-    init_get_bits(&s->gb, *buf, buf_size * 8);
-
-    ff_mpeg1_clean_buffers(s);
-    s->interlaced_dct = 0;
-
-    s->qscale = get_qscale(s);
-
-    if (s->qscale == 0) {
-        av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");
-        return -1;
-    }
-
-    /* extra slice info */
-    while (get_bits1(&s->gb) != 0) {
-        skip_bits(&s->gb, 8);
-    }
-
-    s->mb_x = 0;
-
-    if (mb_y == 0 && s->codec_tag == AV_RL32("SLIF")) {
-        skip_bits1(&s->gb);
-    } else {
-        while (get_bits_left(&s->gb) > 0) {
-            int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
-            if (code < 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
-                return -1;
-            }
-            if (code >= 33) {
-                if (code == 33) {
-                    s->mb_x += 33;
-                }
-                /* otherwise, stuffing, nothing to do */
-            } else {
-                s->mb_x += code;
-                break;
-            }
-        }
-    }
-
-    if (s->mb_x >= (unsigned)s->mb_width) {
-        av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");
-        return -1;
-    }
-
-    if (avctx->hwaccel) {
-        const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */
-        int start_code = -1;
-        buf_end = avpriv_mpv_find_start_code(buf_start + 2, *buf + buf_size, &start_code);
-        if (buf_end < *buf + buf_size)
-            buf_end -= 4;
-        s->mb_y = mb_y;
-        if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0)
-            return DECODE_SLICE_ERROR;
-        *buf = buf_end;
-        return DECODE_SLICE_OK;
-    }
-
-    s->resync_mb_x = s->mb_x;
-    s->resync_mb_y = s->mb_y = mb_y;
-    s->mb_skip_run = 0;
-    ff_init_block_index(s);
-
-    if (s->mb_y == 0 && s->mb_x == 0 && (s->first_field || s->picture_structure == PICT_FRAME)) {
-        if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
-             av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",
-                    s->qscale, s->mpeg_f_code[0][0], s->mpeg_f_code[0][1], s->mpeg_f_code[1][0], s->mpeg_f_code[1][1],
-                    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")),
-                    s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",
-                    s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors,
-                    s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :"");
-        }
-    }
-
-    for (;;) {
-        // If 1, we memcpy blocks in xvmcvideo.
-        if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1)
-            ff_xvmc_init_block(s); // set s->block
-
-        if (mpeg_decode_mb(s, s->block) < 0)
-            return -1;
-
-        if (s->current_picture.f.motion_val[0] && !s->encoding) { // note motion_val is normally NULL unless we want to extract the MVs
-            const int wrap = s->b8_stride;
-            int xy         = s->mb_x * 2 + s->mb_y * 2 * wrap;
-            int b8_xy      = 4 * (s->mb_x + s->mb_y * s->mb_stride);
-            int motion_x, motion_y, dir, i;
-
-            for (i = 0; i < 2; i++) {
-                for (dir = 0; dir < 2; dir++) {
-                    if (s->mb_intra || (dir == 1 && s->pict_type != AV_PICTURE_TYPE_B)) {
-                        motion_x = motion_y = 0;
-                    } else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)) {
-                        motion_x = s->mv[dir][0][0];
-                        motion_y = s->mv[dir][0][1];
-                    } else /*if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8))*/ {
-                        motion_x = s->mv[dir][i][0];
-                        motion_y = s->mv[dir][i][1];
-                    }
-
-                    s->current_picture.f.motion_val[dir][xy    ][0] = motion_x;
-                    s->current_picture.f.motion_val[dir][xy    ][1] = motion_y;
-                    s->current_picture.f.motion_val[dir][xy + 1][0] = motion_x;
-                    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);
-                }
-                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;
-
-        ff_MPV_decode_mb(s, s->block);
-
-        if (++s->mb_x >= s->mb_width) {
-            const int mb_size = 16;
-
-            ff_draw_horiz_band(s, mb_size*(s->mb_y >> field_pic), mb_size);
-            ff_MPV_report_decode_progress(s);
-
-            s->mb_x = 0;
-            s->mb_y += 1 << field_pic;
-
-            if (s->mb_y >= s->mb_height) {
-                int left   = get_bits_left(&s->gb);
-                int is_d10 = s->chroma_format == 2 && s->pict_type == AV_PICTURE_TYPE_I && avctx->profile == 0 && avctx->level == 5
-                             && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0
-                             && 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)) {
-                    av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23)));
-                    return -1;
-                } else
-                    goto eos;
-            }
-
-            ff_init_block_index(s);
-        }
-
-        /* skip mb handling */
-        if (s->mb_skip_run == -1) {
-            /* read increment again */
-            s->mb_skip_run = 0;
-            for (;;) {
-                int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);
-                if (code < 0) {
-                    av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n");
-                    return -1;
-                }
-                if (code >= 33) {
-                    if (code == 33) {
-                        s->mb_skip_run += 33;
-                    } else if (code == 35) {
-                        if (s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0) {
-                            av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n");
-                            return -1;
-                        }
-                        goto eos; /* end of slice */
-                    }
-                    /* otherwise, stuffing, nothing to do */
-                } else {
-                    s->mb_skip_run += code;
-                    break;
-                }
-            }
-            if (s->mb_skip_run) {
-                int i;
-                if (s->pict_type == AV_PICTURE_TYPE_I) {
-                    av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y);
-                    return -1;
-                }
-
-                /* skip mb */
-                s->mb_intra = 0;
-                for (i = 0; i < 12; i++)
-                    s->block_last_index[i] = -1;
-                if (s->picture_structure == PICT_FRAME)
-                    s->mv_type = MV_TYPE_16X16;
-                else
-                    s->mv_type = MV_TYPE_FIELD;
-                if (s->pict_type == AV_PICTURE_TYPE_P) {
-                    /* if P type, zero motion vector is implied */
-                    s->mv_dir             = MV_DIR_FORWARD;
-                    s->mv[0][0][0]        = s->mv[0][0][1]      = 0;
-                    s->last_mv[0][0][0]   = s->last_mv[0][0][1] = 0;
-                    s->last_mv[0][1][0]   = s->last_mv[0][1][1] = 0;
-                    s->field_select[0][0] = (s->picture_structure - 1) & 1;
-                } else {
-                    /* if B type, reuse previous vectors and directions */
-                    s->mv[0][0][0] = s->last_mv[0][0][0];
-                    s->mv[0][0][1] = s->last_mv[0][0][1];
-                    s->mv[1][0][0] = s->last_mv[1][0][0];
-                    s->mv[1][0][1] = s->last_mv[1][0][1];
-                }
-            }
-        }
-    }
-eos: // end of slice
-    *buf += (get_bits_count(&s->gb)-1)/8;
-    av_dlog(s, "y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y);
-    return 0;
-}
-
-static int slice_decode_thread(AVCodecContext *c, void *arg)
-{
-    MpegEncContext *s   = *(void**)arg;
-    const uint8_t *buf  = s->gb.buffer;
-    int mb_y            = s->start_mb_y;
-    const int field_pic = s->picture_structure != PICT_FRAME;
-
-    s->error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width) >> field_pic;
-
-    for (;;) {
-        uint32_t start_code;
-        int ret;
-
-        ret = mpeg_decode_slice(s, mb_y, &buf, s->gb.buffer_end - buf);
-        emms_c();
-        av_dlog(c, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n",
-                ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y,
-                s->start_mb_y, s->end_mb_y, s->error_count);
-        if (ret < 0) {
-            if (c->err_recognition & AV_EF_EXPLODE)
-                return ret;
-            if (s->resync_mb_x >= 0 && s->resync_mb_y >= 0)
-                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
-        } else {
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
-        }
-
-        if (s->mb_y == s->end_mb_y)
-            return 0;
-
-        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;
-        if (s->picture_structure == PICT_BOTTOM_FIELD)
-            mb_y++;
-        if (mb_y < 0 || mb_y >= s->end_mb_y)
-            return -1;
-    }
-}
-
-/**
- * Handle slice ends.
- * @return 1 if it seems to be the last slice
- */
-static int slice_end(AVCodecContext *avctx, AVFrame *pict)
-{
-    Mpeg1Context *s1 = avctx->priv_data;
-    MpegEncContext *s = &s1->mpeg_enc_ctx;
-
-    if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr)
-        return 0;
-
-    if (s->avctx->hwaccel) {
-        if (s->avctx->hwaccel->end_frame(s->avctx) < 0)
-            av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
-    }
-
-    if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
-        ff_xvmc_field_end(s);
-
-    /* end of slice reached */
-    if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) {
-        /* end of image */
-
-        s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_MPEG2;
-
-        ff_er_frame_end(s);
-
-        ff_MPV_frame_end(s);
-
-        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            *pict = s->current_picture_ptr->f;
-            ff_print_debug_info(s, pict);
-        } else {
-            if (avctx->active_thread_type & FF_THREAD_FRAME)
-                s->picture_number++;
-            /* latency of 1 frame for I- and P-frames */
-            /* XXX: use another variable than picture_number */
-            if (s->last_picture_ptr != NULL) {
-                *pict = s->last_picture_ptr->f;
-                 ff_print_debug_info(s, pict);
-            }
-        }
-
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-static int mpeg1_decode_sequence(AVCodecContext *avctx,
-                                 const uint8_t *buf, int buf_size)
-{
-    Mpeg1Context *s1 = avctx->priv_data;
-    MpegEncContext *s = &s1->mpeg_enc_ctx;
-    int width, height;
-    int i, v, j;
-
-    init_get_bits(&s->gb, buf, buf_size*8);
-
-    width  = get_bits(&s->gb, 12);
-    height = get_bits(&s->gb, 12);
-    if (width <= 0 || height <= 0)
-        return -1;
-    s->aspect_ratio_info = get_bits(&s->gb, 4);
-    if (s->aspect_ratio_info == 0) {
-        av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n");
-        if (avctx->err_recognition & AV_EF_BITSTREAM)
-            return -1;
-    }
-    s->frame_rate_index = get_bits(&s->gb, 4);
-    if (s->frame_rate_index == 0 || s->frame_rate_index > 13)
-        return -1;
-    s->bit_rate = get_bits(&s->gb, 18) * 400;
-    if (get_bits1(&s->gb) == 0) /* marker */
-        return -1;
-    s->width  = width;
-    s->height = height;
-
-    s->avctx->rc_buffer_size = get_bits(&s->gb, 10) * 1024 * 16;
-    skip_bits(&s->gb, 1);
-
-    /* get matrix */
-    if (get_bits1(&s->gb)) {
-        load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
-    } else {
-        for (i = 0; i < 64; i++) {
-            j = s->dsp.idct_permutation[i];
-            v = ff_mpeg1_default_intra_matrix[i];
-            s->intra_matrix[j]        = v;
-            s->chroma_intra_matrix[j] = v;
-        }
-    }
-    if (get_bits1(&s->gb)) {
-        load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
-    } else {
-        for (i = 0; i < 64; i++) {
-            int j = s->dsp.idct_permutation[i];
-            v = ff_mpeg1_default_non_intra_matrix[i];
-            s->inter_matrix[j]        = v;
-            s->chroma_inter_matrix[j] = v;
-        }
-    }
-
-    if (show_bits(&s->gb, 23) != 0) {
-        av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n");
-        return -1;
-    }
-
-    /* we set MPEG-2 parameters so that it emulates MPEG-1 */
-    s->progressive_sequence = 1;
-    s->progressive_frame    = 1;
-    s->picture_structure    = PICT_FRAME;
-    s->frame_pred_frame_dct = 1;
-    s->chroma_format        = 1;
-    s->codec_id             = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
-    s->out_format           = FMT_MPEG1;
-    s->swap_uv              = 0; // AFAIK VCR2 does not have SEQ_HEADER
-    if (s->flags & CODEC_FLAG_LOW_DELAY)
-        s->low_delay = 1;
-
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%d\n",
-               s->avctx->rc_buffer_size, s->bit_rate);
-
-    return 0;
-}
-
-static int vcr2_init_sequence(AVCodecContext *avctx)
-{
-    Mpeg1Context *s1 = avctx->priv_data;
-    MpegEncContext *s = &s1->mpeg_enc_ctx;
-    int i, v;
-
-    /* start new MPEG-1 context decoding */
-    s->out_format = FMT_MPEG1;
-    if (s1->mpeg_enc_ctx_allocated) {
-        ff_MPV_common_end(s);
-    }
-    s->width  = avctx->coded_width;
-    s->height = avctx->coded_height;
-    avctx->has_b_frames = 0; // true?
-    s->low_delay = 1;
-
-    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->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++) {
-        int j = s->dsp.idct_permutation[i];
-        v = ff_mpeg1_default_intra_matrix[i];
-        s->intra_matrix[j]        = v;
-        s->chroma_intra_matrix[j] = v;
-
-        v = ff_mpeg1_default_non_intra_matrix[i];
-        s->inter_matrix[j]        = v;
-        s->chroma_inter_matrix[j] = v;
-    }
-
-    s->progressive_sequence  = 1;
-    s->progressive_frame     = 1;
-    s->picture_structure     = PICT_FRAME;
-    s->frame_pred_frame_dct  = 1;
-    s->chroma_format         = 1;
-    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;
-    return 0;
-}
-
-
-static void mpeg_decode_user_data(AVCodecContext *avctx,
-                                  const uint8_t *p, int buf_size)
-{
-    const uint8_t *buf_end = p + buf_size;
-
-    /* we parse the DTG active format information */
-    if (buf_end - p >= 5 &&
-        p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') {
-        int flags = p[4];
-        p += 5;
-        if (flags & 0x80) {
-            /* skip event id */
-            p += 2;
-        }
-        if (flags & 0x40) {
-            if (buf_end - p < 1)
-                return;
-            avctx->dtg_active_format = p[0] & 0x0f;
-        }
-    }
-}
-
-static void mpeg_decode_gop(AVCodecContext *avctx,
-                            const uint8_t *buf, int buf_size)
-{
-    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;
-
-    init_get_bits(&s->gb, buf, buf_size*8);
-
-    skip_bits1(&s->gb); /* drop_frame_flag */
-
-    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);
-    /*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);
-}
-/**
- * Find the end of the current frame in the bitstream.
- * @return the position of the first byte of the next frame, or -1
- */
-int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s)
-{
-    int i;
-    uint32_t state = pc->state;
-
-    /* EOF considered as end of frame */
-    if (buf_size == 0)
-        return 0;
-
-/*
- 0  frame start         -> 1/4
- 1  first_SEQEXT        -> 0/2
- 2  first field start   -> 3/0
- 3  second_SEQEXT       -> 2/0
- 4  searching end
-*/
-
-    for (i = 0; i < buf_size; i++) {
-        assert(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--;
-            else if (state == EXT_START_CODE + 2) {
-                if ((buf[i] & 3) == 3)
-                    pc->frame_start_found = 0;
-                else
-                    pc->frame_start_found = (pc->frame_start_found + 1) & 3;
-            }
-            state++;
-        } else {
-            i = avpriv_mpv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1;
-            if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) {
-                i++;
-                pc->frame_start_found = 4;
-            }
-            if (state == SEQ_END_CODE) {
-                pc->frame_start_found = 0;
-                pc->state=-1;
-                return i+1;
-            }
-            if (pc->frame_start_found == 2 && state == SEQ_START_CODE)
-                pc->frame_start_found = 0;
-            if (pc->frame_start_found  < 4 && state == EXT_START_CODE)
-                pc->frame_start_found++;
-            if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) {
-                if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) {
-                    pc->frame_start_found = 0;
-                    pc->state             = -1;
-                    return i - 3;
-                }
-            }
-            if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) {
-                ff_fetch_timestamp(s, i - 3, 1);
-            }
-        }
-    }
-    pc->state = state;
-    return END_NOT_FOUND;
-}
-
-static int decode_chunks(AVCodecContext *avctx,
-                         AVFrame *picture, int *got_output,
-                         const uint8_t *buf, int buf_size)
-{
-    Mpeg1Context *s = avctx->priv_data;
-    MpegEncContext *s2 = &s->mpeg_enc_ctx;
-    const uint8_t *buf_ptr = buf;
-    const uint8_t *buf_end = buf + buf_size;
-    int ret, input_size;
-    int last_code = 0;
-
-    for (;;) {
-        /* find next start code */
-        uint32_t start_code = -1;
-        buf_ptr = avpriv_mpv_find_start_code(buf_ptr, buf_end, &start_code);
-        if (start_code > 0x1ff) {
-            if (s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT) {
-                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
-                    int i;
-
-                    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)
-                    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;
-                }
-            }
-            s2->pict_type = 0;
-            return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
-        }
-
-        input_size = buf_end - buf_ptr;
-
-        if (avctx->debug & FF_DEBUG_STARTCODE) {
-            av_log(avctx, AV_LOG_DEBUG, "%3X at %td left %d\n", start_code, buf_ptr-buf, input_size);
-        }
-
-        /* prepare data for next start code */
-        switch (start_code) {
-        case SEQ_START_CODE:
-            if (last_code == 0) {
-                mpeg1_decode_sequence(avctx, buf_ptr, input_size);
-                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)
-                    return AVERROR_INVALIDDATA;
-            }
-            break;
-
-        case PICTURE_START_CODE:
-            if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) && s->slice_count) {
-                int i;
-
-                avctx->execute(avctx, slice_decode_thread,
-                               s2->thread_context, NULL,
-                               s->slice_count, sizeof(void*));
-                for (i = 0; i < s->slice_count; i++)
-                    s2->error_count += s2->thread_context[i]->error_count;
-                s->slice_count = 0;
-            }
-            if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
-                ret = mpeg_decode_postinit(avctx);
-                if (ret < 0) {
-                    av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n");
-                    return ret;
-                }
-
-                /* we have a complete image: we try to decompress it */
-                if (mpeg1_decode_picture(avctx, buf_ptr, input_size) < 0)
-                    s2->pict_type = 0;
-                s2->first_slice = 1;
-                last_code = PICTURE_START_CODE;
-            } else {
-                av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code);
-                if (avctx->err_recognition & AV_EF_EXPLODE)
-                    return AVERROR_INVALIDDATA;
-            }
-            break;
-        case EXT_START_CODE:
-            init_get_bits(&s2->gb, buf_ptr, input_size*8);
-
-            switch (get_bits(&s2->gb, 4)) {
-            case 0x1:
-                if (last_code == 0) {
-                mpeg_decode_sequence_extension(s);
-                } else {
-                    av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code);
-                    if (avctx->err_recognition & AV_EF_EXPLODE)
-                        return AVERROR_INVALIDDATA;
-                }
-                break;
-            case 0x2:
-                mpeg_decode_sequence_display_extension(s);
-                break;
-            case 0x3:
-                mpeg_decode_quant_matrix_extension(s2);
-                break;
-            case 0x7:
-                mpeg_decode_picture_display_extension(s);
-                break;
-            case 0x8:
-                if (last_code == PICTURE_START_CODE) {
-                    mpeg_decode_picture_coding_extension(s);
-                } else {
-                    av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code);
-                    if (avctx->err_recognition & AV_EF_EXPLODE)
-                        return AVERROR_INVALIDDATA;
-                }
-                break;
-            }
-            break;
-        case USER_START_CODE:
-            mpeg_decode_user_data(avctx, buf_ptr, input_size);
-            break;
-        case GOP_START_CODE:
-            if (last_code == 0) {
-                s2->first_field=0;
-                mpeg_decode_gop(avctx, buf_ptr, input_size);
-                s->sync=1;
-            } else {
-                av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code);
-                if (avctx->err_recognition & AV_EF_EXPLODE)
-                    return AVERROR_INVALIDDATA;
-            }
-            break;
-        default:
-            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;
-                last_code = SLICE_MIN_START_CODE;
-
-                if (s2->picture_structure == PICT_BOTTOM_FIELD)
-                    mb_y++;
-
-                if (mb_y >= s2->mb_height) {
-                    av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
-                    return -1;
-                }
-
-                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)
-                            break;
-                    }
-                }
-                if (s2->pict_type == AV_PICTURE_TYPE_I)
-                    s->sync=1;
-                if (s2->next_picture_ptr == NULL) {
-                /* Skip P-frames if we do not have a reference frame or we have an invalid header. */
-                    if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) break;
-                }
-                if ((avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type == AV_PICTURE_TYPE_B) ||
-                    (avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type != AV_PICTURE_TYPE_I) ||
-                     avctx->skip_frame >= AVDISCARD_ALL)
-                    break;
-
-                if (!s->mpeg_enc_ctx_allocated)
-                    break;
-
-                if (s2->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
-                    if (mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom)
-                        break;
-                }
-
-                if (!s2->pict_type) {
-                    av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n");
-                    if (avctx->err_recognition & AV_EF_EXPLODE)
-                        return AVERROR_INVALIDDATA;
-                    break;
-                }
-
-                if (s2->first_slice) {
-                    s2->first_slice = 0;
-                    if (mpeg_field_start(s2, buf, buf_size) < 0)
-                        return -1;
-                }
-                if (!s2->current_picture_ptr) {
-                    av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n");
-                    return AVERROR_INVALIDDATA;
-                }
-
-                if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
-                    s->slice_count++;
-                    break;
-                }
-
-                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
-                    int threshold = (s2->mb_height * s->slice_count +
-                                     s2->slice_context_count / 2) /
-                                    s2->slice_context_count;
-                    if (threshold <= mb_y) {
-                        MpegEncContext *thread_context = s2->thread_context[s->slice_count];
-
-                        thread_context->start_mb_y = mb_y;
-                        thread_context->end_mb_y   = s2->mb_height;
-                        if (s->slice_count) {
-                            s2->thread_context[s->slice_count-1]->end_mb_y = mb_y;
-                            ret = ff_update_duplicate_context(thread_context,
-                                                              s2);
-                            if (ret < 0)
-                                return ret;
-                        }
-                        init_get_bits(&thread_context->gb, buf_ptr, input_size*8);
-                        s->slice_count++;
-                    }
-                    buf_ptr += 2; // FIXME add minimum number of bytes per slice
-                } else {
-                    ret = mpeg_decode_slice(s2, mb_y, &buf_ptr, input_size);
-                    emms_c();
-
-                    if (ret < 0) {
-                        if (avctx->err_recognition & AV_EF_EXPLODE)
-                            return ret;
-                        if (s2->resync_mb_x >= 0 && s2->resync_mb_y >= 0)
-                            ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
-                    } else {
-                        ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
-                    }
-                }
-            }
-            break;
-        }
-    }
-}
-
-static int mpeg_decode_frame(AVCodecContext *avctx,
-                             void *data, int *got_output,
-                             AVPacket *avpkt)
-{
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    Mpeg1Context *s = avctx->priv_data;
-    AVFrame *picture = data;
-    MpegEncContext *s2 = &s->mpeg_enc_ctx;
-    av_dlog(avctx, "fill_buffer\n");
-
-    if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {
-        /* special case for last picture */
-        if (s2->low_delay == 0 && s2->next_picture_ptr) {
-            *picture = s2->next_picture_ptr->f;
-            s2->next_picture_ptr = NULL;
-
-            *got_output = 1;
-        }
-        return buf_size;
-    }
-
-    if (s2->flags & CODEC_FLAG_TRUNCATED) {
-        int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL);
-
-        if (ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0)
-            return buf_size;
-    }
-
-    if (s->mpeg_enc_ctx_allocated == 0 && avctx->codec_tag == AV_RL32("VCR2"))
-        vcr2_init_sequence(avctx);
-
-    s->slice_count = 0;
-
-    if (avctx->extradata && !s->extradata_decoded) {
-        int ret = decode_chunks(avctx, picture, got_output, avctx->extradata, avctx->extradata_size);
-        s->extradata_decoded = 1;
-        if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
-            return ret;
-    }
-
-    return decode_chunks(avctx, picture, got_output, buf, buf_size);
-}
-
-
-static void flush(AVCodecContext *avctx)
-{
-    Mpeg1Context *s = avctx->priv_data;
-
-    s->sync=0;
-    s->closed_gop = 0;
-
-    ff_mpeg_flush(avctx);
-}
-
-static int mpeg_decode_end(AVCodecContext *avctx)
-{
-    Mpeg1Context *s = avctx->priv_data;
-
-    if (s->mpeg_enc_ctx_allocated)
-        ff_MPV_common_end(&s->mpeg_enc_ctx);
-    return 0;
-}
-
-static const AVProfile mpeg2_video_profiles[] = {
-    { FF_PROFILE_MPEG2_422,          "4:2:2"              },
-    { FF_PROFILE_MPEG2_HIGH,         "High"               },
-    { FF_PROFILE_MPEG2_SS,           "Spatially Scalable" },
-    { FF_PROFILE_MPEG2_SNR_SCALABLE, "SNR Scalable"       },
-    { FF_PROFILE_MPEG2_MAIN,         "Main"               },
-    { FF_PROFILE_MPEG2_SIMPLE,       "Simple"             },
-    { FF_PROFILE_RESERVED,           "Reserved"           },
-    { FF_PROFILE_RESERVED,           "Reserved"           },
-    { FF_PROFILE_UNKNOWN },
-};
-
-
-AVCodec ff_mpeg1video_decoder = {
-    .name                  = "mpeg1video",
-    .type                  = AVMEDIA_TYPE_VIDEO,
-    .id                    = AV_CODEC_ID_MPEG1VIDEO,
-    .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,
-    .long_name             = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
-    .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
-};
-
-AVCodec ff_mpeg2video_decoder = {
-    .name           = "mpeg2video",
-    .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,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
-    .profiles       = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
-};
-
-#if CONFIG_MPEG_XVMC_DECODER
-static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
-{
-    if (avctx->active_thread_type & FF_THREAD_SLICE)
-        return -1;
-    if (!(avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
-        return -1;
-    if (!(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
-        av_dlog(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n");
-    }
-    mpeg_decode_init(avctx);
-
-    avctx->pix_fmt           = AV_PIX_FMT_XVMC_MPEG2_IDCT;
-    avctx->xvmc_acceleration = 2; // 2 - the blocks are packed!
-
-    return 0;
-}
-
-AVCodec ff_mpeg_xvmc_decoder = {
-    .name           = "mpegvideo_xvmc",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MPEG2VIDEO_XVMC,
-    .priv_data_size = sizeof(Mpeg1Context),
-    .init           = mpeg_mc_decode_init,
-    .close          = mpeg_decode_end,
-    .decode         = mpeg_decode_frame,
-    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 |
-                      CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY,
-    .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
-};
-
-#endif
-
-#if CONFIG_MPEG_VDPAU_DECODER
-AVCodec ff_mpeg_vdpau_decoder = {
-    .name           = "mpegvideo_vdpau",
-    .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_DR1 | CODEC_CAP_TRUNCATED |
-                      CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
-    .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
-};
-#endif
-
-#if CONFIG_MPEG1_VDPAU_DECODER
-AVCodec ff_mpeg1_vdpau_decoder = {
-    .name           = "mpeg1video_vdpau",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MPEG1VIDEO,
-    .priv_data_size = sizeof(Mpeg1Context),
-    .init           = mpeg_decode_init,
-    .close          = mpeg_decode_end,
-    .decode         = mpeg_decode_frame,
-    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED |
-                      CODEC_CAP_HWACCEL_VDPAU | CODEC_CAP_DELAY,
-    .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"),
-};
-#endif
diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h
index 0f9faaf..9132dc3 100644
--- a/libavcodec/mpeg12.h
+++ b/libavcodec/mpeg12.h
@@ -25,25 +25,21 @@
 #include "mpegvideo.h"
 
 #define DC_VLC_BITS 9
+#define MV_VLC_BITS 9
 #define TEX_VLC_BITS 9
 
+#define MBINCR_VLC_BITS 9
+#define MB_PAT_VLC_BITS 9
+#define MB_PTYPE_VLC_BITS 6
+#define MB_BTYPE_VLC_BITS 6
+
 extern VLC ff_dc_lum_vlc;
 extern VLC ff_dc_chroma_vlc;
-
-typedef struct Mpeg1Context {
-    MpegEncContext mpeg_enc_ctx;
-    int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
-    int repeat_field; /* true if we must repeat the field */
-    AVPanScan pan_scan;              /**< some temporary storage for the panscan */
-    int slice_count;
-    int swap_uv;//indicate VCR2
-    int save_aspect_info;
-    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 extradata_decoded;
-} Mpeg1Context;
+extern VLC ff_mbincr_vlc;
+extern VLC ff_mb_ptype_vlc;
+extern VLC ff_mb_btype_vlc;
+extern VLC ff_mb_pat_vlc;
+extern VLC ff_mv_vlc;
 
 extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
 
@@ -71,6 +67,8 @@ static inline int decode_dc(GetBitContext *gb, int component)
     return diff;
 }
 
-extern int ff_mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n);
+int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n);
+void ff_mpeg1_clean_buffers(MpegEncContext *s);
+int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s);
 
 #endif /* AVCODEC_MPEG12_H */
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
new file mode 100644
index 0000000..49b7d1e
--- /dev/null
+++ b/libavcodec/mpeg12dec.c
@@ -0,0 +1,2587 @@
+/*
+ * MPEG-1/2 decoder
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * MPEG-1/2 decoder
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/internal.h"
+#include "libavutil/stereo3d.h"
+#include "internal.h"
+#include "avcodec.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+#include "error_resilience.h"
+#include "mpeg12.h"
+#include "mpeg12data.h"
+#include "bytestream.h"
+#include "xvmc_internal.h"
+#include "thread.h"
+#include "version.h"
+
+typedef struct Mpeg1Context {
+    MpegEncContext mpeg_enc_ctx;
+    int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
+    int repeat_field; /* true if we must repeat the field */
+    AVPanScan pan_scan;              /**< some temporary storage for the panscan */
+    uint8_t *a53_caption;
+    int a53_caption_size;
+    int slice_count;
+    int save_aspect_info;
+    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 first_slice;
+    int extradata_decoded;
+} Mpeg1Context;
+
+#define MB_TYPE_ZERO_MV   0x20000000
+
+static const uint32_t ptype2mb_type[7] = {
+                    MB_TYPE_INTRA,
+                    MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
+                    MB_TYPE_L0,
+                    MB_TYPE_L0 | MB_TYPE_CBP,
+    MB_TYPE_QUANT | MB_TYPE_INTRA,
+    MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
+    MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
+};
+
+static const uint32_t btype2mb_type[11] = {
+                    MB_TYPE_INTRA,
+                    MB_TYPE_L1,
+                    MB_TYPE_L1   | MB_TYPE_CBP,
+                    MB_TYPE_L0,
+                    MB_TYPE_L0   | MB_TYPE_CBP,
+                    MB_TYPE_L0L1,
+                    MB_TYPE_L0L1 | MB_TYPE_CBP,
+    MB_TYPE_QUANT | MB_TYPE_INTRA,
+    MB_TYPE_QUANT | MB_TYPE_L1   | MB_TYPE_CBP,
+    MB_TYPE_QUANT | MB_TYPE_L0   | MB_TYPE_CBP,
+    MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
+};
+
+static const uint8_t non_linear_qscale[32] = {
+    0, 1, 2, 3, 4, 5, 6, 7,
+    8,10,12,14,16,18,20,22,
+    24,28,32,36,40,44,48,52,
+    56,64,72,80,88,96,104,112,
+};
+
+/* as H.263, but only 17 codes */
+static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
+{
+    int code, sign, val, shift;
+
+    code = get_vlc2(&s->gb, ff_mv_vlc.table, MV_VLC_BITS, 2);
+    if (code == 0) {
+        return pred;
+    }
+    if (code < 0) {
+        return 0xffff;
+    }
+
+    sign  = get_bits1(&s->gb);
+    shift = fcode - 1;
+    val   = code;
+    if (shift) {
+        val  = (val - 1) << shift;
+        val |= get_bits(&s->gb, shift);
+        val++;
+    }
+    if (sign)
+        val = -val;
+    val += pred;
+
+    /* modulo decoding */
+    return sign_extend(val, 5 + shift);
+}
+
+static inline int mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
+{
+    int level, dc, diff, i, j, run;
+    int component;
+    RLTable *rl = &ff_rl_mpeg1;
+    uint8_t * const scantable    = s->intra_scantable.permutated;
+    const uint16_t *quant_matrix = s->intra_matrix;
+    const int qscale             = s->qscale;
+
+    /* DC coefficient */
+    component = (n <= 3 ? 0 : n - 4 + 1);
+    diff = decode_dc(&s->gb, component);
+    if (diff >= 0xffff)
+        return -1;
+    dc  = s->last_dc[component];
+    dc += diff;
+    s->last_dc[component] = dc;
+    block[0] = dc * quant_matrix[0];
+    av_dlog(s->avctx, "dc=%d diff=%d\n", dc, diff);
+    i = 0;
+    {
+        OPEN_READER(re, &s->gb);
+        /* now quantify & encode AC coefficients */
+        for (;;) {
+            UPDATE_CACHE(re, &s->gb);
+            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+            if (level == 127) {
+                break;
+            } else if (level != 0) {
+                i += run;
+                j = scantable[i];
+                level = (level * qscale * quant_matrix[j]) >> 4;
+                level = (level - 1) | 1;
+                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                LAST_SKIP_BITS(re, &s->gb, 1);
+            } else {
+                /* escape */
+                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+                UPDATE_CACHE(re, &s->gb);
+                level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
+                if (level == -128) {
+                    level = SHOW_UBITS(re, &s->gb, 8) - 256; LAST_SKIP_BITS(re, &s->gb, 8);
+                } else if (level == 0) {
+                    level = SHOW_UBITS(re, &s->gb, 8)      ; LAST_SKIP_BITS(re, &s->gb, 8);
+                }
+                i += run;
+                j = scantable[i];
+                if (level < 0) {
+                    level = -level;
+                    level = (level * qscale * quant_matrix[j]) >> 4;
+                    level = (level - 1) | 1;
+                    level = -level;
+                } else {
+                    level = (level * qscale * quant_matrix[j]) >> 4;
+                    level = (level - 1) | 1;
+                }
+            }
+            if (i > 63) {
+                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+
+            block[j] = level;
+        }
+        CLOSE_READER(re, &s->gb);
+    }
+    s->block_last_index[n] = i;
+   return 0;
+}
+
+int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
+{
+    return mpeg1_decode_block_intra(s, block, n);
+}
+
+static inline int mpeg1_decode_block_inter(MpegEncContext *s, int16_t *block, int n)
+{
+    int level, i, j, run;
+    RLTable *rl = &ff_rl_mpeg1;
+    uint8_t * const scantable    = s->intra_scantable.permutated;
+    const uint16_t *quant_matrix = s->inter_matrix;
+    const int qscale             = s->qscale;
+
+    {
+        OPEN_READER(re, &s->gb);
+        i = -1;
+        // special case for first coefficient, no need to add second VLC table
+        UPDATE_CACHE(re, &s->gb);
+        if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
+            level = (3 * qscale * quant_matrix[0]) >> 5;
+            level = (level - 1) | 1;
+            if (GET_CACHE(re, &s->gb) & 0x40000000)
+                level = -level;
+            block[0] = level;
+            i++;
+            SKIP_BITS(re, &s->gb, 2);
+            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+                goto end;
+        }
+        /* now quantify & encode AC coefficients */
+        for (;;) {
+            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+            if (level != 0) {
+                i += run;
+                j = scantable[i];
+                level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+                level = (level - 1) | 1;
+                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                SKIP_BITS(re, &s->gb, 1);
+            } else {
+                /* escape */
+                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+                UPDATE_CACHE(re, &s->gb);
+                level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
+                if (level == -128) {
+                    level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
+                } else if (level == 0) {
+                    level = SHOW_UBITS(re, &s->gb, 8)      ; SKIP_BITS(re, &s->gb, 8);
+                }
+                i += run;
+                j = scantable[i];
+                if (level < 0) {
+                    level = -level;
+                    level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+                    level = (level - 1) | 1;
+                    level = -level;
+                } else {
+                    level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+                    level = (level - 1) | 1;
+                }
+            }
+            if (i > 63) {
+                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+
+            block[j] = level;
+            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+                break;
+            UPDATE_CACHE(re, &s->gb);
+        }
+end:
+        LAST_SKIP_BITS(re, &s->gb, 2);
+        CLOSE_READER(re, &s->gb);
+    }
+    s->block_last_index[n] = i;
+    return 0;
+}
+
+static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, int16_t *block, int n)
+{
+    int level, i, j, run;
+    RLTable *rl = &ff_rl_mpeg1;
+    uint8_t * const scantable = s->intra_scantable.permutated;
+    const int qscale          = s->qscale;
+
+    {
+        OPEN_READER(re, &s->gb);
+        i = -1;
+        // special case for first coefficient, no need to add second VLC table
+        UPDATE_CACHE(re, &s->gb);
+        if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
+            level = (3 * qscale) >> 1;
+            level = (level - 1) | 1;
+            if (GET_CACHE(re, &s->gb) & 0x40000000)
+                level = -level;
+            block[0] = level;
+            i++;
+            SKIP_BITS(re, &s->gb, 2);
+            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+                goto end;
+        }
+
+        /* now quantify & encode AC coefficients */
+        for (;;) {
+            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+            if (level != 0) {
+                i += run;
+                j = scantable[i];
+                level = ((level * 2 + 1) * qscale) >> 1;
+                level = (level - 1) | 1;
+                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                SKIP_BITS(re, &s->gb, 1);
+            } else {
+                /* escape */
+                run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
+                UPDATE_CACHE(re, &s->gb);
+                level = SHOW_SBITS(re, &s->gb, 8); SKIP_BITS(re, &s->gb, 8);
+                if (level == -128) {
+                    level = SHOW_UBITS(re, &s->gb, 8) - 256; SKIP_BITS(re, &s->gb, 8);
+                } else if (level == 0) {
+                    level = SHOW_UBITS(re, &s->gb, 8)      ; SKIP_BITS(re, &s->gb, 8);
+                }
+                i += run;
+                j = scantable[i];
+                if (level < 0) {
+                    level = -level;
+                    level = ((level * 2 + 1) * qscale) >> 1;
+                    level = (level - 1) | 1;
+                    level = -level;
+                } else {
+                    level = ((level * 2 + 1) * qscale) >> 1;
+                    level = (level - 1) | 1;
+                }
+            }
+
+            block[j] = level;
+            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+                break;
+            UPDATE_CACHE(re, &s->gb);
+        }
+end:
+        LAST_SKIP_BITS(re, &s->gb, 2);
+        CLOSE_READER(re, &s->gb);
+    }
+    s->block_last_index[n] = i;
+    return 0;
+}
+
+
+static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, int16_t *block, int n)
+{
+    int level, i, j, run;
+    RLTable *rl = &ff_rl_mpeg1;
+    uint8_t * const scantable = s->intra_scantable.permutated;
+    const uint16_t *quant_matrix;
+    const int qscale = s->qscale;
+    int mismatch;
+
+    mismatch = 1;
+
+    {
+        OPEN_READER(re, &s->gb);
+        i = -1;
+        if (n < 4)
+            quant_matrix = s->inter_matrix;
+        else
+            quant_matrix = s->chroma_inter_matrix;
+
+        // special case for first coefficient, no need to add second VLC table
+        UPDATE_CACHE(re, &s->gb);
+        if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
+            level= (3 * qscale * quant_matrix[0]) >> 5;
+            if (GET_CACHE(re, &s->gb) & 0x40000000)
+                level = -level;
+            block[0]  = level;
+            mismatch ^= level;
+            i++;
+            SKIP_BITS(re, &s->gb, 2);
+            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+                goto end;
+        }
+
+        /* now quantify & encode AC coefficients */
+        for (;;) {
+            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+            if (level != 0) {
+                i += run;
+                j = scantable[i];
+                level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                SKIP_BITS(re, &s->gb, 1);
+            } else {
+                /* escape */
+                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+                UPDATE_CACHE(re, &s->gb);
+                level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+
+                i += run;
+                j = scantable[i];
+                if (level < 0) {
+                    level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+                    level = -level;
+                } else {
+                    level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+                }
+            }
+            if (i > 63) {
+                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+
+            mismatch ^= level;
+            block[j]  = level;
+            if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+                break;
+            UPDATE_CACHE(re, &s->gb);
+        }
+end:
+        LAST_SKIP_BITS(re, &s->gb, 2);
+        CLOSE_READER(re, &s->gb);
+    }
+    block[63] ^= (mismatch & 1);
+
+    s->block_last_index[n] = i;
+    return 0;
+}
+
+static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
+                                                    int16_t *block, int n)
+{
+    int level, i, j, run;
+    RLTable *rl = &ff_rl_mpeg1;
+    uint8_t * const scantable = s->intra_scantable.permutated;
+    const int qscale          = s->qscale;
+    OPEN_READER(re, &s->gb);
+    i = -1;
+
+    // special case for first coefficient, no need to add second VLC table
+    UPDATE_CACHE(re, &s->gb);
+    if (((int32_t)GET_CACHE(re, &s->gb)) < 0) {
+        level = (3 * qscale) >> 1;
+        if (GET_CACHE(re, &s->gb) & 0x40000000)
+            level = -level;
+        block[0] = level;
+        i++;
+        SKIP_BITS(re, &s->gb, 2);
+        if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+            goto end;
+    }
+
+    /* now quantify & encode AC coefficients */
+    for (;;) {
+        GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+        if (level != 0) {
+            i += run;
+            j  = scantable[i];
+            level = ((level * 2 + 1) * qscale) >> 1;
+            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+            SKIP_BITS(re, &s->gb, 1);
+        } else {
+            /* escape */
+            run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+            UPDATE_CACHE(re, &s->gb);
+            level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+
+            i += run;
+            j  = scantable[i];
+            if (level < 0) {
+                level = ((-level * 2 + 1) * qscale) >> 1;
+                level = -level;
+            } else {
+                level = ((level * 2 + 1) * qscale) >> 1;
+            }
+        }
+
+        block[j] = level;
+        if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+            break;
+        UPDATE_CACHE(re, &s->gb);
+    }
+end:
+    LAST_SKIP_BITS(re, &s->gb, 2);
+    CLOSE_READER(re, &s->gb);
+    s->block_last_index[n] = i;
+    return 0;
+}
+
+
+static inline int mpeg2_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
+{
+    int level, dc, diff, i, j, run;
+    int component;
+    RLTable *rl;
+    uint8_t * const scantable = s->intra_scantable.permutated;
+    const uint16_t *quant_matrix;
+    const int qscale = s->qscale;
+    int mismatch;
+
+    /* DC coefficient */
+    if (n < 4) {
+        quant_matrix = s->intra_matrix;
+        component = 0;
+    } else {
+        quant_matrix = s->chroma_intra_matrix;
+        component = (n & 1) + 1;
+    }
+    diff = decode_dc(&s->gb, component);
+    if (diff >= 0xffff)
+        return -1;
+    dc  = s->last_dc[component];
+    dc += diff;
+    s->last_dc[component] = dc;
+    block[0] = dc << (3 - s->intra_dc_precision);
+    av_dlog(s->avctx, "dc=%d\n", block[0]);
+    mismatch = block[0] ^ 1;
+    i = 0;
+    if (s->intra_vlc_format)
+        rl = &ff_rl_mpeg2;
+    else
+        rl = &ff_rl_mpeg1;
+
+    {
+        OPEN_READER(re, &s->gb);
+        /* now quantify & encode AC coefficients */
+        for (;;) {
+            UPDATE_CACHE(re, &s->gb);
+            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+            if (level == 127) {
+                break;
+            } else if (level != 0) {
+                i += run;
+                j  = scantable[i];
+                level = (level * qscale * quant_matrix[j]) >> 4;
+                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                LAST_SKIP_BITS(re, &s->gb, 1);
+            } else {
+                /* escape */
+                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+                UPDATE_CACHE(re, &s->gb);
+                level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+                i += run;
+                j  = scantable[i];
+                if (level < 0) {
+                    level = (-level * qscale * quant_matrix[j]) >> 4;
+                    level = -level;
+                } else {
+                    level = (level * qscale * quant_matrix[j]) >> 4;
+                }
+            }
+            if (i > 63) {
+                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+
+            mismatch ^= level;
+            block[j]  = level;
+        }
+        CLOSE_READER(re, &s->gb);
+    }
+    block[63] ^= mismatch & 1;
+
+    s->block_last_index[n] = i;
+    return 0;
+}
+
+static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
+{
+    int level, dc, diff, j, run;
+    int component;
+    RLTable *rl;
+    uint8_t * scantable = s->intra_scantable.permutated;
+    const uint16_t *quant_matrix;
+    const int qscale = s->qscale;
+
+    /* DC coefficient */
+    if (n < 4) {
+        quant_matrix = s->intra_matrix;
+        component = 0;
+    } else {
+        quant_matrix = s->chroma_intra_matrix;
+        component = (n & 1) + 1;
+    }
+    diff = decode_dc(&s->gb, component);
+    if (diff >= 0xffff)
+        return -1;
+    dc = s->last_dc[component];
+    dc += diff;
+    s->last_dc[component] = dc;
+    block[0] = dc << (3 - s->intra_dc_precision);
+    if (s->intra_vlc_format)
+        rl = &ff_rl_mpeg2;
+    else
+        rl = &ff_rl_mpeg1;
+
+    {
+        OPEN_READER(re, &s->gb);
+        /* now quantify & encode AC coefficients */
+        for (;;) {
+            UPDATE_CACHE(re, &s->gb);
+            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+            if (level == 127) {
+                break;
+            } else if (level != 0) {
+                scantable += run;
+                j = *scantable;
+                level = (level * qscale * quant_matrix[j]) >> 4;
+                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                LAST_SKIP_BITS(re, &s->gb, 1);
+            } else {
+                /* escape */
+                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);
+                UPDATE_CACHE(re, &s->gb);
+                level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);
+                scantable += run;
+                j = *scantable;
+                if (level < 0) {
+                    level = (-level * qscale * quant_matrix[j]) >> 4;
+                    level = -level;
+                } else {
+                    level = (level * qscale * quant_matrix[j]) >> 4;
+                }
+            }
+
+            block[j] = level;
+        }
+        CLOSE_READER(re, &s->gb);
+    }
+
+    s->block_last_index[n] = scantable - s->intra_scantable.permutated;
+    return 0;
+}
+
+/******************************************/
+/* decoding */
+
+static inline int get_dmv(MpegEncContext *s)
+{
+    if (get_bits1(&s->gb))
+        return 1 - (get_bits1(&s->gb) << 1);
+    else
+        return 0;
+}
+
+static inline int get_qscale(MpegEncContext *s)
+{
+    int qscale = get_bits(&s->gb, 5);
+    if (s->q_scale_type) {
+        return non_linear_qscale[qscale];
+    } else {
+        return qscale << 1;
+    }
+}
+
+/* motion type (for MPEG-2) */
+#define MT_FIELD 1
+#define MT_FRAME 2
+#define MT_16X8  2
+#define MT_DMV   3
+
+static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
+{
+    int i, j, k, cbp, val, mb_type, motion_type;
+    const int mb_block_count = 4 + (1 << s->chroma_format);
+
+    av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
+
+    assert(s->mb_skipped == 0);
+
+    if (s->mb_skip_run-- != 0) {
+        if (s->pict_type == AV_PICTURE_TYPE_P) {
+            s->mb_skipped = 1;
+            s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
+        } else {
+            int mb_type;
+
+            if (s->mb_x)
+                mb_type = s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
+            else
+                mb_type = s->current_picture.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
+            if (IS_INTRA(mb_type))
+                return -1;
+            s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
+                mb_type | MB_TYPE_SKIP;
+//            assert(s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
+
+            if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
+                s->mb_skipped = 1;
+        }
+
+        return 0;
+    }
+
+    switch (s->pict_type) {
+    default:
+    case AV_PICTURE_TYPE_I:
+        if (get_bits1(&s->gb) == 0) {
+            if (get_bits1(&s->gb) == 0) {
+                av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+            mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
+        } else {
+            mb_type = MB_TYPE_INTRA;
+        }
+        break;
+    case AV_PICTURE_TYPE_P:
+        mb_type = get_vlc2(&s->gb, ff_mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
+        if (mb_type < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
+            return -1;
+        }
+        mb_type = ptype2mb_type[mb_type];
+        break;
+    case AV_PICTURE_TYPE_B:
+        mb_type = get_vlc2(&s->gb, ff_mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
+        if (mb_type < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
+            return -1;
+        }
+        mb_type = btype2mb_type[mb_type];
+        break;
+    }
+    av_dlog(s->avctx, "mb_type=%x\n", mb_type);
+//    motion_type = 0; /* avoid warning */
+    if (IS_INTRA(mb_type)) {
+        s->dsp.clear_blocks(s->block[0]);
+
+        if (!s->chroma_y_shift) {
+            s->dsp.clear_blocks(s->block[6]);
+        }
+
+        /* compute DCT type */
+        if (s->picture_structure == PICT_FRAME && // FIXME add an interlaced_dct coded var?
+            !s->frame_pred_frame_dct) {
+            s->interlaced_dct = get_bits1(&s->gb);
+        }
+
+        if (IS_QUANT(mb_type))
+            s->qscale = get_qscale(s);
+
+        if (s->concealment_motion_vectors) {
+            /* just parse them */
+            if (s->picture_structure != PICT_FRAME)
+                skip_bits1(&s->gb); /* field select */
+
+            s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =
+                mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);
+            s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =
+                mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);
+
+            skip_bits1(&s->gb); /* marker */
+        } else
+            memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
+        s->mb_intra = 1;
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
+        // if 1, we memcpy blocks in xvmcvideo
+        if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
+            ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
+        }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+
+        if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+            if (s->flags2 & CODEC_FLAG2_FAST) {
+                for (i = 0; i < 6; i++) {
+                    mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
+                }
+            } else {
+                for (i = 0; i < mb_block_count; i++) {
+                    if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)
+                        return -1;
+                }
+            }
+        } else {
+            for (i = 0; i < 6; i++) {
+                if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)
+                    return -1;
+            }
+        }
+    } else {
+        if (mb_type & MB_TYPE_ZERO_MV) {
+            assert(mb_type & MB_TYPE_CBP);
+
+            s->mv_dir = MV_DIR_FORWARD;
+            if (s->picture_structure == PICT_FRAME) {
+                if (!s->frame_pred_frame_dct)
+                    s->interlaced_dct = get_bits1(&s->gb);
+                s->mv_type = MV_TYPE_16X16;
+            } else {
+                s->mv_type = MV_TYPE_FIELD;
+                mb_type |= MB_TYPE_INTERLACED;
+                s->field_select[0][0] = s->picture_structure - 1;
+            }
+
+            if (IS_QUANT(mb_type))
+                s->qscale = get_qscale(s);
+
+            s->last_mv[0][0][0] = 0;
+            s->last_mv[0][0][1] = 0;
+            s->last_mv[0][1][0] = 0;
+            s->last_mv[0][1][1] = 0;
+            s->mv[0][0][0] = 0;
+            s->mv[0][0][1] = 0;
+        } else {
+            assert(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)
+                motion_type = MT_FRAME;
+            else {
+                motion_type = get_bits(&s->gb, 2);
+                if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
+                    s->interlaced_dct = get_bits1(&s->gb);
+            }
+
+            if (IS_QUANT(mb_type))
+                s->qscale = get_qscale(s);
+
+            /* motion vectors */
+            s->mv_dir = (mb_type >> 13) & 3;
+            av_dlog(s->avctx, "motion_type=%d\n", motion_type);
+            switch (motion_type) {
+            case MT_FRAME: /* or MT_16X8 */
+                if (s->picture_structure == PICT_FRAME) {
+                    mb_type |= MB_TYPE_16x16;
+                    s->mv_type = MV_TYPE_16X16;
+                    for (i = 0; i < 2; i++) {
+                        if (USES_LIST(mb_type, i)) {
+                            /* MT_FRAME */
+                            s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] =
+                                mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]);
+                            s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] =
+                                mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]);
+                            /* full_pel: only for MPEG-1 */
+                            if (s->full_pel[i]) {
+                                s->mv[i][0][0] <<= 1;
+                                s->mv[i][0][1] <<= 1;
+                            }
+                        }
+                    }
+                } else {
+                    mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
+                    s->mv_type = MV_TYPE_16X8;
+                    for (i = 0; i < 2; i++) {
+                        if (USES_LIST(mb_type, i)) {
+                            /* MT_16X8 */
+                            for (j = 0; j < 2; j++) {
+                                s->field_select[i][j] = get_bits1(&s->gb);
+                                for (k = 0; k < 2; k++) {
+                                    val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+                                                             s->last_mv[i][j][k]);
+                                    s->last_mv[i][j][k] = val;
+                                    s->mv[i][j][k]      = val;
+                                }
+                            }
+                        }
+                    }
+                }
+                break;
+            case MT_FIELD:
+                s->mv_type = MV_TYPE_FIELD;
+                if (s->picture_structure == PICT_FRAME) {
+                    mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
+                    for (i = 0; i < 2; i++) {
+                        if (USES_LIST(mb_type, i)) {
+                            for (j = 0; j < 2; j++) {
+                                s->field_select[i][j] = get_bits1(&s->gb);
+                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+                                                         s->last_mv[i][j][0]);
+                                s->last_mv[i][j][0] = val;
+                                s->mv[i][j][0]      = val;
+                                av_dlog(s->avctx, "fmx=%d\n", val);
+                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+                                                         s->last_mv[i][j][1] >> 1);
+                                s->last_mv[i][j][1] = val << 1;
+                                s->mv[i][j][1]      = val;
+                                av_dlog(s->avctx, "fmy=%d\n", val);
+                            }
+                        }
+                    }
+                } else {
+                    mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
+                    for (i = 0; i < 2; i++) {
+                        if (USES_LIST(mb_type, i)) {
+                            s->field_select[i][0] = get_bits1(&s->gb);
+                            for (k = 0; k < 2; k++) {
+                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+                                                         s->last_mv[i][0][k]);
+                                s->last_mv[i][0][k] = val;
+                                s->last_mv[i][1][k] = val;
+                                s->mv[i][0][k]      = val;
+                            }
+                        }
+                    }
+                }
+                break;
+            case MT_DMV:
+                s->mv_type = MV_TYPE_DMV;
+                for (i = 0; i < 2; i++) {
+                    if (USES_LIST(mb_type, i)) {
+                        int dmx, dmy, mx, my, m;
+                        const int my_shift = s->picture_structure == PICT_FRAME;
+
+                        mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+                                                s->last_mv[i][0][0]);
+                        s->last_mv[i][0][0] = mx;
+                        s->last_mv[i][1][0] = mx;
+                        dmx = get_dmv(s);
+                        my  = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+                                                 s->last_mv[i][0][1] >> my_shift);
+                        dmy = get_dmv(s);
+
+
+                        s->last_mv[i][0][1] = my << my_shift;
+                        s->last_mv[i][1][1] = my << my_shift;
+
+                        s->mv[i][0][0] = mx;
+                        s->mv[i][0][1] = my;
+                        s->mv[i][1][0] = mx; // not used
+                        s->mv[i][1][1] = my; // not used
+
+                        if (s->picture_structure == PICT_FRAME) {
+                            mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
+
+                            // m = 1 + 2 * s->top_field_first;
+                            m = s->top_field_first ? 1 : 3;
+
+                            /* top -> top pred */
+                            s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+                            s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
+                            m = 4 - m;
+                            s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+                            s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
+                        } else {
+                            mb_type |= MB_TYPE_16x16;
+
+                            s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
+                            s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
+                            if (s->picture_structure == PICT_TOP_FIELD)
+                                s->mv[i][2][1]--;
+                            else
+                                s->mv[i][2][1]++;
+                        }
+                    }
+                }
+                break;
+            default:
+                av_log(s->avctx, AV_LOG_ERROR, "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+        }
+
+        s->mb_intra = 0;
+        if (HAS_CBP(mb_type)) {
+            s->dsp.clear_blocks(s->block[0]);
+
+            cbp = get_vlc2(&s->gb, ff_mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
+            if (mb_block_count > 6) {
+                 cbp <<= mb_block_count - 6;
+                 cbp  |= get_bits(&s->gb, mb_block_count - 6);
+                 s->dsp.clear_blocks(s->block[6]);
+            }
+            if (cbp <= 0) {
+                av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
+                return -1;
+            }
+
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
+            //if 1, we memcpy blocks in xvmcvideo
+            if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
+                ff_xvmc_pack_pblocks(s, cbp);
+            }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+
+            if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+                if (s->flags2 & CODEC_FLAG2_FAST) {
+                    for (i = 0; i < 6; i++) {
+                        if (cbp & 32) {
+                            mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
+                        } else {
+                            s->block_last_index[i] = -1;
+                        }
+                        cbp += cbp;
+                    }
+                } else {
+                    cbp <<= 12-mb_block_count;
+
+                    for (i = 0; i < mb_block_count; i++) {
+                        if (cbp & (1 << 11)) {
+                            if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)
+                                return -1;
+                        } else {
+                            s->block_last_index[i] = -1;
+                        }
+                        cbp += cbp;
+                    }
+                }
+            } else {
+                if (s->flags2 & CODEC_FLAG2_FAST) {
+                    for (i = 0; i < 6; i++) {
+                        if (cbp & 32) {
+                            mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
+                        } else {
+                            s->block_last_index[i] = -1;
+                        }
+                        cbp += cbp;
+                    }
+                } else {
+                    for (i = 0; i < 6; i++) {
+                        if (cbp & 32) {
+                            if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)
+                                return -1;
+                        } else {
+                            s->block_last_index[i] = -1;
+                        }
+                        cbp += cbp;
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < 12; i++)
+                s->block_last_index[i] = -1;
+        }
+    }
+
+    s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
+
+    return 0;
+}
+
+static av_cold int mpeg_decode_init(AVCodecContext *avctx)
+{
+    Mpeg1Context *s = avctx->priv_data;
+    MpegEncContext *s2 = &s->mpeg_enc_ctx;
+    int i;
+
+    /* we need some permutation to store matrices,
+     * until MPV_common_init() sets the real permutation. */
+    for (i = 0; i < 64; i++)
+       s2->dsp.idct_permutation[i]=i;
+
+    ff_MPV_decode_defaults(s2);
+
+    s->mpeg_enc_ctx.avctx  = avctx;
+    s->mpeg_enc_ctx.flags  = avctx->flags;
+    s->mpeg_enc_ctx.flags2 = avctx->flags2;
+    ff_mpeg12_common_init(&s->mpeg_enc_ctx);
+    ff_mpeg12_init_vlcs();
+
+    s->mpeg_enc_ctx_allocated      = 0;
+    s->mpeg_enc_ctx.picture_number = 0;
+    s->repeat_field                = 0;
+    s->mpeg_enc_ctx.codec_id       = avctx->codec->id;
+    avctx->color_range = AVCOL_RANGE_MPEG;
+    if (avctx->codec->id == AV_CODEC_ID_MPEG1VIDEO)
+        avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
+    else
+        avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
+    return 0;
+}
+
+static int mpeg_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
+{
+    Mpeg1Context *ctx = avctx->priv_data, *ctx_from = avctx_from->priv_data;
+    MpegEncContext *s = &ctx->mpeg_enc_ctx, *s1 = &ctx_from->mpeg_enc_ctx;
+    int err;
+
+    if (avctx == avctx_from || !ctx_from->mpeg_enc_ctx_allocated || !s1->context_initialized)
+        return 0;
+
+    err = ff_mpeg_update_thread_context(avctx, avctx_from);
+    if (err) return err;
+
+    if (!ctx->mpeg_enc_ctx_allocated)
+        memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext));
+
+    if (!(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay))
+        s->picture_number++;
+
+    return 0;
+}
+
+static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm,
+                                 const uint8_t *new_perm)
+{
+    uint16_t temp_matrix[64];
+    int i;
+
+    memcpy(temp_matrix, matrix, 64 * sizeof(uint16_t));
+
+    for (i = 0; i < 64; i++) {
+        matrix[new_perm[i]] = temp_matrix[old_perm[i]];
+    }
+}
+
+#if FF_API_XVMC
+static const enum AVPixelFormat pixfmt_xvmc_mpg2_420[] = {
+    AV_PIX_FMT_XVMC_MPEG2_IDCT,
+    AV_PIX_FMT_XVMC_MPEG2_MC,
+    AV_PIX_FMT_NONE };
+#endif /* FF_API_XVMC */
+
+static const enum AVPixelFormat mpeg12_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_MPEG2_DXVA2_HWACCEL
+    AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_MPEG2_VAAPI_HWACCEL
+    AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_MPEG1_VDPAU_HWACCEL | CONFIG_MPEG2_VDPAU_HWACCEL
+    AV_PIX_FMT_VDPAU,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
+static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
+{
+    Mpeg1Context *s1 = avctx->priv_data;
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->xvmc_acceleration)
+        return avctx->get_format(avctx, pixfmt_xvmc_mpg2_420);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+
+    if (s->chroma_format <  2)
+        return avctx->get_format(avctx, mpeg12_hwaccel_pixfmt_list_420);
+    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.
+ * It may be called in different places for MPEG-1 and MPEG-2. */
+static int mpeg_decode_postinit(AVCodecContext *avctx)
+{
+    Mpeg1Context *s1 = avctx->priv_data;
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+    uint8_t old_permutation[64];
+    int ret;
+
+    if ((s1->mpeg_enc_ctx_allocated == 0) ||
+        avctx->coded_width  != s->width   ||
+        avctx->coded_height != s->height  ||
+        s1->save_width           != s->width                ||
+        s1->save_height          != s->height               ||
+        s1->save_aspect_info     != s->aspect_ratio_info    ||
+        s1->save_progressive_seq != s->progressive_sequence ||
+        0)
+    {
+
+        if (s1->mpeg_enc_ctx_allocated) {
+            ParseContext pc = s->parse_context;
+            s->parse_context.buffer = 0;
+            ff_MPV_common_end(s);
+            s->parse_context = pc;
+        }
+
+        if ((s->width == 0) || (s->height == 0))
+            return -2;
+
+        ret = ff_set_dimensions(avctx, s->width, s->height);
+        if (ret < 0)
+            return ret;
+
+        avctx->bit_rate          = s->bit_rate;
+        s1->save_aspect_info     = s->aspect_ratio_info;
+        s1->save_width           = s->width;
+        s1->save_height          = s->height;
+        s1->save_progressive_seq = s->progressive_sequence;
+
+        /* low_delay may be forced, in this case we will have B-frames
+         * that behave like P-frames. */
+        avctx->has_b_frames = !s->low_delay;
+
+        if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+            //MPEG-1 fps
+            avctx->time_base.den = ff_mpeg12_frame_rate_tab[s->frame_rate_index].num;
+            avctx->time_base.num = ff_mpeg12_frame_rate_tab[s->frame_rate_index].den;
+            //MPEG-1 aspect
+            avctx->sample_aspect_ratio = av_d2q(1.0/ff_mpeg1_aspect[s->aspect_ratio_info], 255);
+            avctx->ticks_per_frame=1;
+        } else {//MPEG-2
+        //MPEG-2 fps
+            av_reduce(&s->avctx->time_base.den,
+                      &s->avctx->time_base.num,
+                      ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num*2,
+                      ff_mpeg12_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
+                      1 << 30);
+            avctx->ticks_per_frame = 2;
+            //MPEG-2 aspect
+            if (s->aspect_ratio_info > 1) {
+                AVRational dar =
+                    av_mul_q(av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+                                      (AVRational) {s1->pan_scan.width, s1->pan_scan.height}),
+                             (AVRational) {s->width, s->height});
+
+                // we ignore the spec here and guess a bit as reality does not match the spec, see for example
+                // res_change_ffmpeg_aspect.ts and sequence-display-aspect.mpg
+                // issue1613, 621, 562
+                if ((s1->pan_scan.width == 0) || (s1->pan_scan.height == 0) ||
+                   (av_cmp_q(dar, (AVRational) {4, 3}) && av_cmp_q(dar, (AVRational) {16, 9}))) {
+                    s->avctx->sample_aspect_ratio =
+                        av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+                                 (AVRational) {s->width, s->height});
+                } else {
+                    s->avctx->sample_aspect_ratio =
+                        av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+                                 (AVRational) {s1->pan_scan.width, s1->pan_scan.height});
+//issue1613 4/3 16/9 -> 16/9
+//res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3
+//widescreen-issue562.mpg 4/3 16/9 -> 16/9
+//                    s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height});
+                    av_dlog(avctx, "A %d/%d\n",
+                            ff_mpeg2_aspect[s->aspect_ratio_info].num, ff_mpeg2_aspect[s->aspect_ratio_info].den);
+                    av_dlog(avctx, "B %d/%d\n", s->avctx->sample_aspect_ratio.num,
+                            s->avctx->sample_aspect_ratio.den);
+                }
+            } else {
+                s->avctx->sample_aspect_ratio =
+                    ff_mpeg2_aspect[s->aspect_ratio_info];
+            }
+        } // MPEG-2
+
+        avctx->pix_fmt = mpeg_get_pixelformat(avctx);
+        avctx->hwaccel = ff_find_hwaccel(avctx);
+        // until then pix_fmt may be changed right after codec init
+#if FF_API_XVMC
+        if ((avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT ||
+            avctx->hwaccel) && avctx->idct_algo == FF_IDCT_AUTO)
+#else
+        if (avctx->hwaccel && avctx->idct_algo == FF_IDCT_AUTO)
+#endif /* FF_API_XVMC */
+            avctx->idct_algo = FF_IDCT_SIMPLE;
+
+        /* Quantization matrices may need reordering
+         * if DCT permutation is changed. */
+        memcpy(old_permutation, s->dsp.idct_permutation, 64 * sizeof(uint8_t));
+
+        if (ff_MPV_common_init(s) < 0)
+            return -2;
+
+        quant_matrix_rebuild(s->intra_matrix,        old_permutation, s->dsp.idct_permutation);
+        quant_matrix_rebuild(s->inter_matrix,        old_permutation, s->dsp.idct_permutation);
+        quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->dsp.idct_permutation);
+        quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->dsp.idct_permutation);
+
+        s1->mpeg_enc_ctx_allocated = 1;
+    }
+    return 0;
+}
+
+static int mpeg1_decode_picture(AVCodecContext *avctx,
+                                const uint8_t *buf, int buf_size)
+{
+    Mpeg1Context *s1 = avctx->priv_data;
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+    int ref, f_code, vbv_delay;
+
+    init_get_bits(&s->gb, buf, buf_size*8);
+
+    ref = get_bits(&s->gb, 10); /* temporal ref */
+    s->pict_type = get_bits(&s->gb, 3);
+    if (s->pict_type == 0 || s->pict_type > 3)
+        return -1;
+
+    vbv_delay = get_bits(&s->gb, 16);
+    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))
+            return -1;
+        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))
+            return -1;
+        s->mpeg_f_code[1][0] = f_code;
+        s->mpeg_f_code[1][1] = f_code;
+    }
+    s->current_picture.f.pict_type = s->pict_type;
+    s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
+
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(avctx, AV_LOG_DEBUG, "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type);
+
+    s->y_dc_scale = 8;
+    s->c_dc_scale = 8;
+    return 0;
+}
+
+static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
+{
+    MpegEncContext *s= &s1->mpeg_enc_ctx;
+    int horiz_size_ext, vert_size_ext;
+    int bit_rate_ext;
+
+    skip_bits(&s->gb, 1); /* profile and level esc*/
+    s->avctx->profile       = get_bits(&s->gb, 3);
+    s->avctx->level         = get_bits(&s->gb, 4);
+    s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */
+    s->chroma_format        = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
+    horiz_size_ext          = get_bits(&s->gb, 2);
+    vert_size_ext           = get_bits(&s->gb, 2);
+    s->width  |= (horiz_size_ext << 12);
+    s->height |= (vert_size_ext  << 12);
+    bit_rate_ext = get_bits(&s->gb, 12);  /* XXX: handle it */
+    s->bit_rate += (bit_rate_ext << 18) * 400;
+    skip_bits1(&s->gb); /* marker */
+    s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10;
+
+    s->low_delay = get_bits1(&s->gb);
+    if (s->flags & CODEC_FLAG_LOW_DELAY)
+        s->low_delay = 1;
+
+    s1->frame_rate_ext.num = get_bits(&s->gb, 2) + 1;
+    s1->frame_rate_ext.den = get_bits(&s->gb, 5) + 1;
+
+    av_dlog(s->avctx, "sequence extension\n");
+    s->codec_id      = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
+
+    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n",
+               s->avctx->profile, s->avctx->level, s->avctx->rc_buffer_size, s->bit_rate);
+
+}
+
+static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
+{
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+    int color_description, w, h;
+
+    skip_bits(&s->gb, 3); /* video format */
+    color_description = get_bits1(&s->gb);
+    if (color_description) {
+        s->avctx->color_primaries = get_bits(&s->gb, 8);
+        s->avctx->color_trc       = get_bits(&s->gb, 8);
+        s->avctx->colorspace      = get_bits(&s->gb, 8);
+    }
+    w = get_bits(&s->gb, 14);
+    skip_bits(&s->gb, 1); //marker
+    h = get_bits(&s->gb, 14);
+    // remaining 3 bits are zero padding
+
+    s1->pan_scan.width  = 16 * w;
+    s1->pan_scan.height = 16 * h;
+
+    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h);
+}
+
+static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
+{
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+    int i, nofco;
+
+    nofco = 1;
+    if (s->progressive_sequence) {
+        if (s->repeat_first_field) {
+            nofco++;
+            if (s->top_field_first)
+                nofco++;
+        }
+    } else {
+        if (s->picture_structure == PICT_FRAME) {
+            nofco++;
+            if (s->repeat_first_field)
+                nofco++;
+        }
+    }
+    for (i = 0; i < nofco; i++) {
+        s1->pan_scan.position[i][0] = get_sbits(&s->gb, 16);
+        skip_bits(&s->gb, 1); // marker
+        s1->pan_scan.position[i][1] = get_sbits(&s->gb, 16);
+        skip_bits(&s->gb, 1); // marker
+    }
+
+    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(s->avctx, AV_LOG_DEBUG, "pde (%d,%d) (%d,%d) (%d,%d)\n",
+               s1->pan_scan.position[0][0], s1->pan_scan.position[0][1],
+               s1->pan_scan.position[1][0], s1->pan_scan.position[1][1],
+               s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]);
+}
+
+static int load_matrix(MpegEncContext *s, uint16_t matrix0[64], uint16_t matrix1[64], int intra)
+{
+    int i;
+
+    for (i = 0; i < 64; i++) {
+        int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+        int v = get_bits(&s->gb, 8);
+        if (v == 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
+            return -1;
+        }
+        if (intra && i == 0 && v != 8) {
+            av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n");
+            v = 8; // needed by pink.mpg / issue1046
+        }
+        matrix0[j] = v;
+        if (matrix1)
+            matrix1[j] = v;
+    }
+    return 0;
+}
+
+static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
+{
+    av_dlog(s->avctx, "matrix extension\n");
+
+    if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
+    if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
+    if (get_bits1(&s->gb)) load_matrix(s, s->chroma_intra_matrix, NULL           , 1);
+    if (get_bits1(&s->gb)) load_matrix(s, s->chroma_inter_matrix, NULL           , 0);
+}
+
+static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
+{
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+
+    s->full_pel[0] = s->full_pel[1] = 0;
+    s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);
+    s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);
+    s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);
+    s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);
+    if (!s->pict_type && s1->mpeg_enc_ctx_allocated) {
+        av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n");
+        if (s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1] == 15) {
+            if (s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)
+                s->pict_type = AV_PICTURE_TYPE_I;
+            else
+                s->pict_type = AV_PICTURE_TYPE_P;
+        } else
+            s->pict_type = AV_PICTURE_TYPE_B;
+        s->current_picture.f.pict_type = s->pict_type;
+        s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
+    }
+    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);
+    s->frame_pred_frame_dct       = get_bits1(&s->gb);
+    s->concealment_motion_vectors = get_bits1(&s->gb);
+    s->q_scale_type               = get_bits1(&s->gb);
+    s->intra_vlc_format           = get_bits1(&s->gb);
+    s->alternate_scan             = get_bits1(&s->gb);
+    s->repeat_first_field         = get_bits1(&s->gb);
+    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);
+        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
+    } else {
+        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
+        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
+    }
+
+    /* composite display not parsed */
+    av_dlog(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision);
+    av_dlog(s->avctx, "picture_structure=%d\n", s->picture_structure);
+    av_dlog(s->avctx, "top field first=%d\n", s->top_field_first);
+    av_dlog(s->avctx, "repeat first field=%d\n", s->repeat_first_field);
+    av_dlog(s->avctx, "conceal=%d\n", s->concealment_motion_vectors);
+    av_dlog(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format);
+    av_dlog(s->avctx, "alternate_scan=%d\n", s->alternate_scan);
+    av_dlog(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);
+    av_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame);
+}
+
+static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
+{
+    AVCodecContext *avctx = s->avctx;
+    Mpeg1Context *s1 = (Mpeg1Context*)s;
+
+    /* start frame decoding */
+    if (s->first_field || s->picture_structure == PICT_FRAME) {
+        AVFrameSideData *pan_scan;
+
+        if (ff_MPV_frame_start(s, avctx) < 0)
+            return -1;
+
+        ff_mpeg_er_frame_start(s);
+
+        /* first check if we must repeat the frame */
+        s->current_picture_ptr->f.repeat_pict = 0;
+        if (s->repeat_first_field) {
+            if (s->progressive_sequence) {
+                if (s->top_field_first)
+                    s->current_picture_ptr->f.repeat_pict = 4;
+                else
+                    s->current_picture_ptr->f.repeat_pict = 2;
+            } else if (s->progressive_frame) {
+                s->current_picture_ptr->f.repeat_pict = 1;
+            }
+        }
+
+        pan_scan = av_frame_new_side_data(&s->current_picture_ptr->f,
+                                          AV_FRAME_DATA_PANSCAN,
+                                          sizeof(s1->pan_scan));
+        if (!pan_scan)
+            return AVERROR(ENOMEM);
+        memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));
+
+        if (s1->a53_caption) {
+            AVFrameSideData *sd = av_frame_new_side_data(
+                &s->current_picture_ptr->f, AV_FRAME_DATA_A53_CC,
+                s1->a53_caption_size);
+            if (sd)
+                memcpy(sd->data, s1->a53_caption, s1->a53_caption_size);
+            av_freep(&s1->a53_caption);
+        }
+        if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
+            ff_thread_finish_setup(avctx);
+    } else { // second field
+        int i;
+
+        if (!s->current_picture_ptr) {
+            av_log(s->avctx, AV_LOG_ERROR, "first field missing\n");
+            return -1;
+        }
+
+        if (s->avctx->hwaccel &&
+            (s->avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
+            if (s->avctx->hwaccel->end_frame(s->avctx) < 0)
+                av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode first field\n");
+        }
+
+        for (i = 0; i < 4; i++) {
+            s->current_picture.f.data[i] = s->current_picture_ptr->f.data[i];
+            if (s->picture_structure == PICT_BOTTOM_FIELD) {
+                s->current_picture.f.data[i] += s->current_picture_ptr->f.linesize[i];
+            }
+        }
+    }
+
+    if (avctx->hwaccel) {
+        if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
+            return -1;
+    }
+
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
+// MPV_frame_start will call this function too,
+// but we need to call it on every field
+    if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
+        if (ff_xvmc_field_start(s, avctx) < 0)
+            return -1;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+
+    return 0;
+}
+
+#define DECODE_SLICE_ERROR -1
+#define DECODE_SLICE_OK     0
+
+/**
+ * Decode a slice.
+ * MpegEncContext.mb_y must be set to the MB row from the startcode.
+ * @return DECODE_SLICE_ERROR if the slice is damaged,
+ *         DECODE_SLICE_OK if this slice is OK
+ */
+static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
+                             const uint8_t **buf, int buf_size)
+{
+    AVCodecContext *avctx = s->avctx;
+    const int field_pic   = s->picture_structure != PICT_FRAME;
+
+    s->resync_mb_x =
+    s->resync_mb_y = -1;
+
+    assert(mb_y < s->mb_height);
+
+    init_get_bits(&s->gb, *buf, buf_size * 8);
+
+    ff_mpeg1_clean_buffers(s);
+    s->interlaced_dct = 0;
+
+    s->qscale = get_qscale(s);
+
+    if (s->qscale == 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");
+        return -1;
+    }
+
+    /* extra slice info */
+    while (get_bits1(&s->gb) != 0) {
+        skip_bits(&s->gb, 8);
+    }
+
+    s->mb_x = 0;
+
+    if (mb_y == 0 && s->codec_tag == AV_RL32("SLIF")) {
+        skip_bits1(&s->gb);
+    } else {
+        while (get_bits_left(&s->gb) > 0) {
+            int code = get_vlc2(&s->gb, ff_mbincr_vlc.table,
+                                MBINCR_VLC_BITS, 2);
+            if (code < 0) {
+                av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
+                return -1;
+            }
+            if (code >= 33) {
+                if (code == 33) {
+                    s->mb_x += 33;
+                }
+                /* otherwise, stuffing, nothing to do */
+            } else {
+                s->mb_x += code;
+                break;
+            }
+        }
+    }
+
+    if (s->mb_x >= (unsigned)s->mb_width) {
+        av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");
+        return -1;
+    }
+
+    if (avctx->hwaccel) {
+        const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */
+        int start_code = -1;
+        buf_end = avpriv_find_start_code(buf_start + 2, *buf + buf_size, &start_code);
+        if (buf_end < *buf + buf_size)
+            buf_end -= 4;
+        s->mb_y = mb_y;
+        if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0)
+            return DECODE_SLICE_ERROR;
+        *buf = buf_end;
+        return DECODE_SLICE_OK;
+    }
+
+    s->resync_mb_x = s->mb_x;
+    s->resync_mb_y = s->mb_y = mb_y;
+    s->mb_skip_run = 0;
+    ff_init_block_index(s);
+
+    if (s->mb_y == 0 && s->mb_x == 0 && (s->first_field || s->picture_structure == PICT_FRAME)) {
+        if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+             av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",
+                    s->qscale, s->mpeg_f_code[0][0], s->mpeg_f_code[0][1], s->mpeg_f_code[1][0], s->mpeg_f_code[1][1],
+                    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")),
+                    s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",
+                    s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors,
+                    s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :"");
+        }
+    }
+
+    for (;;) {
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
+        // If 1, we memcpy blocks in xvmcvideo.
+        if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1)
+            ff_xvmc_init_block(s); // set s->block
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+
+        if (mpeg_decode_mb(s, s->block) < 0)
+            return -1;
+
+        if (s->current_picture.motion_val[0] && !s->encoding) { // note motion_val is normally NULL unless we want to extract the MVs
+            const int wrap = s->b8_stride;
+            int xy         = s->mb_x * 2 + s->mb_y * 2 * wrap;
+            int b8_xy      = 4 * (s->mb_x + s->mb_y * s->mb_stride);
+            int motion_x, motion_y, dir, i;
+
+            for (i = 0; i < 2; i++) {
+                for (dir = 0; dir < 2; dir++) {
+                    if (s->mb_intra || (dir == 1 && s->pict_type != AV_PICTURE_TYPE_B)) {
+                        motion_x = motion_y = 0;
+                    } else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)) {
+                        motion_x = s->mv[dir][0][0];
+                        motion_y = s->mv[dir][0][1];
+                    } else /*if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8))*/ {
+                        motion_x = s->mv[dir][i][0];
+                        motion_y = s->mv[dir][i][1];
+                    }
+
+                    s->current_picture.motion_val[dir][xy    ][0] = motion_x;
+                    s->current_picture.motion_val[dir][xy    ][1] = motion_y;
+                    s->current_picture.motion_val[dir][xy + 1][0] = motion_x;
+                    s->current_picture.motion_val[dir][xy + 1][1] = motion_y;
+                    s->current_picture.ref_index [dir][b8_xy    ] =
+                    s->current_picture.ref_index [dir][b8_xy + 1] = s->field_select[dir][i];
+                    assert(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;
+
+        ff_MPV_decode_mb(s, s->block);
+
+        if (++s->mb_x >= s->mb_width) {
+            const int mb_size = 16;
+
+            ff_mpeg_draw_horiz_band(s, mb_size*(s->mb_y >> field_pic), mb_size);
+            ff_MPV_report_decode_progress(s);
+
+            s->mb_x = 0;
+            s->mb_y += 1 << field_pic;
+
+            if (s->mb_y >= s->mb_height) {
+                int left   = get_bits_left(&s->gb);
+                int is_d10 = s->chroma_format == 2 && s->pict_type == AV_PICTURE_TYPE_I && avctx->profile == 0 && avctx->level == 5
+                             && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0
+                             && 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)) {
+                    av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23)));
+                    return -1;
+                } else
+                    goto eos;
+            }
+
+            ff_init_block_index(s);
+        }
+
+        /* skip mb handling */
+        if (s->mb_skip_run == -1) {
+            /* read increment again */
+            s->mb_skip_run = 0;
+            for (;;) {
+                int code = get_vlc2(&s->gb, ff_mbincr_vlc.table,
+                                    MBINCR_VLC_BITS, 2);
+                if (code < 0) {
+                    av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n");
+                    return -1;
+                }
+                if (code >= 33) {
+                    if (code == 33) {
+                        s->mb_skip_run += 33;
+                    } else if (code == 35) {
+                        if (s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0) {
+                            av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n");
+                            return -1;
+                        }
+                        goto eos; /* end of slice */
+                    }
+                    /* otherwise, stuffing, nothing to do */
+                } else {
+                    s->mb_skip_run += code;
+                    break;
+                }
+            }
+            if (s->mb_skip_run) {
+                int i;
+                if (s->pict_type == AV_PICTURE_TYPE_I) {
+                    av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y);
+                    return -1;
+                }
+
+                /* skip mb */
+                s->mb_intra = 0;
+                for (i = 0; i < 12; i++)
+                    s->block_last_index[i] = -1;
+                if (s->picture_structure == PICT_FRAME)
+                    s->mv_type = MV_TYPE_16X16;
+                else
+                    s->mv_type = MV_TYPE_FIELD;
+                if (s->pict_type == AV_PICTURE_TYPE_P) {
+                    /* if P type, zero motion vector is implied */
+                    s->mv_dir             = MV_DIR_FORWARD;
+                    s->mv[0][0][0]        = s->mv[0][0][1]      = 0;
+                    s->last_mv[0][0][0]   = s->last_mv[0][0][1] = 0;
+                    s->last_mv[0][1][0]   = s->last_mv[0][1][1] = 0;
+                    s->field_select[0][0] = (s->picture_structure - 1) & 1;
+                } else {
+                    /* if B type, reuse previous vectors and directions */
+                    s->mv[0][0][0] = s->last_mv[0][0][0];
+                    s->mv[0][0][1] = s->last_mv[0][0][1];
+                    s->mv[1][0][0] = s->last_mv[1][0][0];
+                    s->mv[1][0][1] = s->last_mv[1][0][1];
+                }
+            }
+        }
+    }
+eos: // end of slice
+    *buf += (get_bits_count(&s->gb)-1)/8;
+    av_dlog(s, "y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y);
+    return 0;
+}
+
+static int slice_decode_thread(AVCodecContext *c, void *arg)
+{
+    MpegEncContext *s   = *(void**)arg;
+    const uint8_t *buf  = s->gb.buffer;
+    int mb_y            = s->start_mb_y;
+    const int field_pic = s->picture_structure != PICT_FRAME;
+
+    s->er.error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width) >> field_pic;
+
+    for (;;) {
+        uint32_t start_code;
+        int ret;
+
+        ret = mpeg_decode_slice(s, mb_y, &buf, s->gb.buffer_end - buf);
+        emms_c();
+        av_dlog(c, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n",
+                ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y,
+                s->start_mb_y, s->end_mb_y, s->er.error_count);
+        if (ret < 0) {
+            if (c->err_recognition & AV_EF_EXPLODE)
+                return ret;
+            if (s->resync_mb_x >= 0 && s->resync_mb_y >= 0)
+                ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
+        } else {
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
+        }
+
+        if (s->mb_y == s->end_mb_y)
+            return 0;
+
+        start_code = -1;
+        buf = avpriv_find_start_code(buf, s->gb.buffer_end, &start_code);
+        mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic;
+        if (s->picture_structure == PICT_BOTTOM_FIELD)
+            mb_y++;
+        if (mb_y < 0 || mb_y >= s->end_mb_y)
+            return -1;
+    }
+}
+
+/**
+ * Handle slice ends.
+ * @return 1 if it seems to be the last slice
+ */
+static int slice_end(AVCodecContext *avctx, AVFrame *pict)
+{
+    Mpeg1Context *s1 = avctx->priv_data;
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+
+    if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr)
+        return 0;
+
+    if (s->avctx->hwaccel) {
+        if (s->avctx->hwaccel->end_frame(s->avctx) < 0)
+            av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
+    }
+
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
+        ff_xvmc_field_end(s);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+
+    /* end of slice reached */
+    if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) {
+        /* end of image */
+
+        ff_er_frame_end(&s->er);
+
+        ff_MPV_frame_end(s);
+
+        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
+            int ret = av_frame_ref(pict, &s->current_picture_ptr->f);
+            if (ret < 0)
+                return ret;
+            ff_print_debug_info(s, s->current_picture_ptr);
+        } else {
+            if (avctx->active_thread_type & FF_THREAD_FRAME)
+                s->picture_number++;
+            /* latency of 1 frame for I- and P-frames */
+            /* XXX: use another variable than picture_number */
+            if (s->last_picture_ptr != NULL) {
+                int ret = av_frame_ref(pict, &s->last_picture_ptr->f);
+                if (ret < 0)
+                    return ret;
+                ff_print_debug_info(s, s->last_picture_ptr);
+            }
+        }
+
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static int mpeg1_decode_sequence(AVCodecContext *avctx,
+                                 const uint8_t *buf, int buf_size)
+{
+    Mpeg1Context *s1 = avctx->priv_data;
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+    int width, height;
+    int i, v, j;
+
+    init_get_bits(&s->gb, buf, buf_size*8);
+
+    width  = get_bits(&s->gb, 12);
+    height = get_bits(&s->gb, 12);
+    if (width == 0 || height == 0) {
+        av_log(avctx, AV_LOG_WARNING, "Invalid horizontal or vertical size "
+               "value.\n");
+        if (avctx->err_recognition & AV_EF_BITSTREAM)
+            return AVERROR_INVALIDDATA;
+    }
+    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)
+            return -1;
+    }
+    s->frame_rate_index = get_bits(&s->gb, 4);
+    if (s->frame_rate_index == 0 || s->frame_rate_index > 13)
+        return -1;
+    s->bit_rate = get_bits(&s->gb, 18) * 400;
+    if (get_bits1(&s->gb) == 0) /* marker */
+        return -1;
+    s->width  = width;
+    s->height = height;
+
+    s->avctx->rc_buffer_size = get_bits(&s->gb, 10) * 1024 * 16;
+    skip_bits(&s->gb, 1);
+
+    /* get matrix */
+    if (get_bits1(&s->gb)) {
+        load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
+    } else {
+        for (i = 0; i < 64; i++) {
+            j = s->dsp.idct_permutation[i];
+            v = ff_mpeg1_default_intra_matrix[i];
+            s->intra_matrix[j]        = v;
+            s->chroma_intra_matrix[j] = v;
+        }
+    }
+    if (get_bits1(&s->gb)) {
+        load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
+    } else {
+        for (i = 0; i < 64; i++) {
+            int j = s->dsp.idct_permutation[i];
+            v = ff_mpeg1_default_non_intra_matrix[i];
+            s->inter_matrix[j]        = v;
+            s->chroma_inter_matrix[j] = v;
+        }
+    }
+
+    if (show_bits(&s->gb, 23) != 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n");
+        return -1;
+    }
+
+    /* we set MPEG-2 parameters so that it emulates MPEG-1 */
+    s->progressive_sequence = 1;
+    s->progressive_frame    = 1;
+    s->picture_structure    = PICT_FRAME;
+    s->frame_pred_frame_dct = 1;
+    s->chroma_format        = 1;
+    s->codec_id             = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
+    s->out_format           = FMT_MPEG1;
+    if (s->flags & CODEC_FLAG_LOW_DELAY)
+        s->low_delay = 1;
+
+    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%d\n",
+               s->avctx->rc_buffer_size, s->bit_rate);
+
+    return 0;
+}
+
+static int vcr2_init_sequence(AVCodecContext *avctx)
+{
+    Mpeg1Context *s1 = avctx->priv_data;
+    MpegEncContext *s = &s1->mpeg_enc_ctx;
+    int i, v;
+
+    /* start new MPEG-1 context decoding */
+    s->out_format = FMT_MPEG1;
+    if (s1->mpeg_enc_ctx_allocated) {
+        ff_MPV_common_end(s);
+    }
+    s->width  = avctx->coded_width;
+    s->height = avctx->coded_height;
+    avctx->has_b_frames = 0; // true?
+    s->low_delay = 1;
+
+    avctx->pix_fmt = mpeg_get_pixelformat(avctx);
+    avctx->hwaccel = ff_find_hwaccel(avctx);
+
+#if FF_API_XVMC
+    if ((avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel) &&
+        avctx->idct_algo == FF_IDCT_AUTO)
+#else
+    if (avctx->hwaccel && avctx->idct_algo == FF_IDCT_AUTO)
+#endif /* FF_API_XVMC */
+        avctx->idct_algo = FF_IDCT_SIMPLE;
+
+    if (ff_MPV_common_init(s) < 0)
+        return -1;
+    s1->mpeg_enc_ctx_allocated = 1;
+
+    for (i = 0; i < 64; i++) {
+        int j = s->dsp.idct_permutation[i];
+        v = ff_mpeg1_default_intra_matrix[i];
+        s->intra_matrix[j]        = v;
+        s->chroma_intra_matrix[j] = v;
+
+        v = ff_mpeg1_default_non_intra_matrix[i];
+        s->inter_matrix[j]        = v;
+        s->chroma_inter_matrix[j] = v;
+    }
+
+    s->progressive_sequence  = 1;
+    s->progressive_frame     = 1;
+    s->picture_structure     = PICT_FRAME;
+    s->frame_pred_frame_dct  = 1;
+    s->chroma_format         = 1;
+    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;
+    return 0;
+}
+
+
+static int mpeg_decode_a53_cc(AVCodecContext *avctx,
+                              const uint8_t *p, int buf_size)
+{
+    Mpeg1Context *s1 = avctx->priv_data;
+
+    if (buf_size >= 6 &&
+        p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' &&
+        p[4] == 3 && (p[5] & 0x40)) {
+        /* extract A53 Part 4 CC data */
+        int cc_count = p[5] & 0x1f;
+        if (cc_count > 0 && buf_size >= 7 + cc_count * 3) {
+            av_freep(&s1->a53_caption);
+            s1->a53_caption_size = cc_count * 3;
+            s1->a53_caption = av_malloc(s1->a53_caption_size);
+            if (s1->a53_caption) {
+                memcpy(s1->a53_caption, p + 7, s1->a53_caption_size);
+            }
+        }
+        return 1;
+    } else if (buf_size >= 11 &&
+        p[0] == 'C' && p[1] == 'C' && p[2] == 0x01 && p[3] == 0xf8) {
+        /* extract DVD CC data */
+        int cc_count = 0;
+        int i;
+        // There is a caption count field in the data, but it is often
+        // incorect.  So count the number of captions present.
+        for (i = 5; i + 6 <= buf_size && ((p[i] & 0xfe) == 0xfe); i += 6)
+            cc_count++;
+        // Transform the DVD format into A53 Part 4 format
+        if (cc_count > 0) {
+            av_freep(&s1->a53_caption);
+            s1->a53_caption_size = cc_count * 6;
+            s1->a53_caption = av_malloc(s1->a53_caption_size);
+            if (s1->a53_caption) {
+                uint8_t field1 = !!(p[4] & 0x80);
+                uint8_t *cap = s1->a53_caption;
+                p += 5;
+                for (i = 0; i < cc_count; i++) {
+                    cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd;
+                    cap[1] = p[1];
+                    cap[2] = p[2];
+                    cap[3] = (p[3] == 0xff && !field1) ? 0xfc : 0xfd;
+                    cap[4] = p[4];
+                    cap[5] = p[5];
+                    cap += 6;
+                    p += 6;
+                }
+            }
+        }
+        return 1;
+    }
+    return 0;
+}
+
+static void mpeg_decode_user_data(AVCodecContext *avctx,
+                                  const uint8_t *p, int buf_size)
+{
+    const uint8_t *buf_end = p + buf_size;
+
+    /* we parse the DTG active format information */
+    if (buf_end - p >= 5 &&
+        p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') {
+        int flags = p[4];
+        p += 5;
+        if (flags & 0x80) {
+            /* skip event id */
+            p += 2;
+        }
+        if (flags & 0x40) {
+            if (buf_end - p < 1)
+                return;
+            avctx->dtg_active_format = p[0] & 0x0f;
+        }
+    } else if (buf_end - p >= 6 &&
+               p[0] == 'J' && p[1] == 'P' && p[2] == '3' && p[3] == 'D' &&
+               p[4] == 0x03) { // S3D_video_format_length
+        // the 0x7F mask ignores the reserved_bit value
+        const uint8_t S3D_video_format_type = p[5] & 0x7F;
+
+        if (S3D_video_format_type == 0x03 ||
+            S3D_video_format_type == 0x04 ||
+            S3D_video_format_type == 0x08 ||
+            S3D_video_format_type == 0x23) {
+            Mpeg1Context *s1   = avctx->priv_data;
+            MpegEncContext *s  = &s1->mpeg_enc_ctx;
+            AVStereo3D *stereo = av_stereo3d_create_side_data(&s->current_picture_ptr->f);
+            if (!stereo)
+                return;
+
+            switch (S3D_video_format_type) {
+            case 0x03:
+                stereo->type = AV_STEREO3D_SIDEBYSIDE;
+                break;
+            case 0x04:
+                stereo->type = AV_STEREO3D_TOPBOTTOM;
+                break;
+            case 0x08:
+                stereo->type = AV_STEREO3D_2D;
+                break;
+            case 0x23:
+                stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+                break;
+            }
+        }
+    } else if (mpeg_decode_a53_cc(avctx, p, buf_size)) {
+        return;
+    }
+}
+
+static void mpeg_decode_gop(AVCodecContext *avctx,
+                            const uint8_t *buf, int buf_size)
+{
+    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;
+
+    init_get_bits(&s->gb, buf, buf_size*8);
+
+    skip_bits1(&s->gb); /* drop_frame_flag */
+
+    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);
+    /*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);
+}
+
+static int decode_chunks(AVCodecContext *avctx,
+                         AVFrame *picture, int *got_output,
+                         const uint8_t *buf, int buf_size)
+{
+    Mpeg1Context *s = avctx->priv_data;
+    MpegEncContext *s2 = &s->mpeg_enc_ctx;
+    const uint8_t *buf_ptr = buf;
+    const uint8_t *buf_end = buf + buf_size;
+    int ret, input_size;
+    int last_code = 0, skip_frame = 0;
+
+    for (;;) {
+        /* find next start code */
+        uint32_t start_code = -1;
+        buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code);
+        if (start_code > 0x1ff) {
+            if (!skip_frame) {
+                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
+                    !avctx->hwaccel) {
+                    int i;
+
+                    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->er.error_count += s2->thread_context[i]->er.error_count;
+                }
+
+                ret = slice_end(avctx, picture);
+                if (ret < 0)
+                    return ret;
+                else if (ret) {
+                    if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
+                        *got_output = 1;
+                }
+            }
+            s2->pict_type = 0;
+            return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
+        }
+
+        input_size = buf_end - buf_ptr;
+
+        if (avctx->debug & FF_DEBUG_STARTCODE) {
+            av_log(avctx, AV_LOG_DEBUG, "%3X at %td left %d\n", start_code, buf_ptr-buf, input_size);
+        }
+
+        /* prepare data for next start code */
+        switch (start_code) {
+        case SEQ_START_CODE:
+            if (last_code == 0) {
+                mpeg1_decode_sequence(avctx, buf_ptr, input_size);
+                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)
+                    return AVERROR_INVALIDDATA;
+            }
+            break;
+
+        case PICTURE_START_CODE:
+            if (s2->width <= 0 || s2->height <= 0) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d.\n",
+                       s2->width, s2->height);
+                return AVERROR_INVALIDDATA;
+            }
+
+            if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
+                !avctx->hwaccel && s->slice_count) {
+                int i;
+
+                avctx->execute(avctx, slice_decode_thread,
+                               s2->thread_context, NULL,
+                               s->slice_count, sizeof(void*));
+                for (i = 0; i < s->slice_count; i++)
+                    s2->er.error_count += s2->thread_context[i]->er.error_count;
+                s->slice_count = 0;
+            }
+            if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
+                ret = mpeg_decode_postinit(avctx);
+                if (ret < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n");
+                    return ret;
+                }
+
+                /* we have a complete image: we try to decompress it */
+                if (mpeg1_decode_picture(avctx, buf_ptr, input_size) < 0)
+                    s2->pict_type = 0;
+                s->first_slice = 1;
+                last_code = PICTURE_START_CODE;
+            } else {
+                av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code);
+                if (avctx->err_recognition & AV_EF_EXPLODE)
+                    return AVERROR_INVALIDDATA;
+            }
+            break;
+        case EXT_START_CODE:
+            init_get_bits(&s2->gb, buf_ptr, input_size*8);
+
+            switch (get_bits(&s2->gb, 4)) {
+            case 0x1:
+                if (last_code == 0) {
+                mpeg_decode_sequence_extension(s);
+                } else {
+                    av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code);
+                    if (avctx->err_recognition & AV_EF_EXPLODE)
+                        return AVERROR_INVALIDDATA;
+                }
+                break;
+            case 0x2:
+                mpeg_decode_sequence_display_extension(s);
+                break;
+            case 0x3:
+                mpeg_decode_quant_matrix_extension(s2);
+                break;
+            case 0x7:
+                mpeg_decode_picture_display_extension(s);
+                break;
+            case 0x8:
+                if (last_code == PICTURE_START_CODE) {
+                    mpeg_decode_picture_coding_extension(s);
+                } else {
+                    av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code);
+                    if (avctx->err_recognition & AV_EF_EXPLODE)
+                        return AVERROR_INVALIDDATA;
+                }
+                break;
+            }
+            break;
+        case USER_START_CODE:
+            mpeg_decode_user_data(avctx, buf_ptr, input_size);
+            break;
+        case GOP_START_CODE:
+            if (last_code == 0) {
+                s2->first_field=0;
+                mpeg_decode_gop(avctx, buf_ptr, input_size);
+                s->sync=1;
+            } else {
+                av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code);
+                if (avctx->err_recognition & AV_EF_EXPLODE)
+                    return AVERROR_INVALIDDATA;
+            }
+            break;
+        default:
+            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;
+                last_code = SLICE_MIN_START_CODE;
+
+                if (s2->picture_structure == PICT_BOTTOM_FIELD)
+                    mb_y++;
+
+                if (mb_y >= s2->mb_height) {
+                    av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
+                    return -1;
+                }
+
+                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) {
+                            skip_frame = 1;
+                            break;
+                        }
+                    }
+                }
+                if (s2->pict_type == AV_PICTURE_TYPE_I)
+                    s->sync=1;
+                if (s2->next_picture_ptr == NULL) {
+                /* Skip P-frames if we do not have a reference frame or we have an invalid header. */
+                    if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) {
+                        skip_frame = 1;
+                        break;
+                    }
+                }
+                if ((avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type == AV_PICTURE_TYPE_B) ||
+                    (avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type != AV_PICTURE_TYPE_I) ||
+                     avctx->skip_frame >= AVDISCARD_ALL) {
+                    skip_frame = 1;
+                    break;
+                }
+
+                if (!s->mpeg_enc_ctx_allocated)
+                    break;
+
+                if (s2->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+                    if (mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom)
+                        break;
+                }
+
+                if (!s2->pict_type) {
+                    av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n");
+                    if (avctx->err_recognition & AV_EF_EXPLODE)
+                        return AVERROR_INVALIDDATA;
+                    break;
+                }
+
+                if (s->first_slice) {
+                    skip_frame = 0;
+                    s->first_slice = 0;
+                    if (mpeg_field_start(s2, buf, buf_size) < 0)
+                        return -1;
+                }
+                if (!s2->current_picture_ptr) {
+                    av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n");
+                    return AVERROR_INVALIDDATA;
+                }
+
+                if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
+                    !avctx->hwaccel) {
+                    int threshold = (s2->mb_height * s->slice_count +
+                                     s2->slice_context_count / 2) /
+                                    s2->slice_context_count;
+                    if (threshold <= mb_y) {
+                        MpegEncContext *thread_context = s2->thread_context[s->slice_count];
+
+                        thread_context->start_mb_y = mb_y;
+                        thread_context->end_mb_y   = s2->mb_height;
+                        if (s->slice_count) {
+                            s2->thread_context[s->slice_count-1]->end_mb_y = mb_y;
+                            ret = ff_update_duplicate_context(thread_context,
+                                                              s2);
+                            if (ret < 0)
+                                return ret;
+                        }
+                        init_get_bits(&thread_context->gb, buf_ptr, input_size*8);
+                        s->slice_count++;
+                    }
+                    buf_ptr += 2; // FIXME add minimum number of bytes per slice
+                } else {
+                    ret = mpeg_decode_slice(s2, mb_y, &buf_ptr, input_size);
+                    emms_c();
+
+                    if (ret < 0) {
+                        if (avctx->err_recognition & AV_EF_EXPLODE)
+                            return ret;
+                        if (s2->resync_mb_x >= 0 && s2->resync_mb_y >= 0)
+                            ff_er_add_slice(&s2->er, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
+                    } else {
+                        ff_er_add_slice(&s2->er, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, ER_AC_END | ER_DC_END | ER_MV_END);
+                    }
+                }
+            }
+            break;
+        }
+    }
+}
+
+static int mpeg_decode_frame(AVCodecContext *avctx,
+                             void *data, int *got_output,
+                             AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
+    Mpeg1Context *s = avctx->priv_data;
+    AVFrame *picture = data;
+    MpegEncContext *s2 = &s->mpeg_enc_ctx;
+    av_dlog(avctx, "fill_buffer\n");
+
+    if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {
+        /* special case for last picture */
+        if (s2->low_delay == 0 && s2->next_picture_ptr) {
+            int ret = av_frame_ref(picture, &s2->next_picture_ptr->f);
+            if (ret < 0)
+                return ret;
+
+            s2->next_picture_ptr = NULL;
+
+            *got_output = 1;
+        }
+        return buf_size;
+    }
+
+    if (s2->flags & CODEC_FLAG_TRUNCATED) {
+        int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL);
+
+        if (ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0)
+            return buf_size;
+    }
+
+    if (s->mpeg_enc_ctx_allocated == 0 && avctx->codec_tag == AV_RL32("VCR2"))
+        vcr2_init_sequence(avctx);
+
+    s->slice_count = 0;
+
+    if (avctx->extradata && !s->extradata_decoded) {
+        int ret = decode_chunks(avctx, picture, got_output, avctx->extradata, avctx->extradata_size);
+        s->extradata_decoded = 1;
+        if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
+            return ret;
+    }
+
+    return decode_chunks(avctx, picture, got_output, buf, buf_size);
+}
+
+
+static void flush(AVCodecContext *avctx)
+{
+    Mpeg1Context *s = avctx->priv_data;
+
+    s->sync=0;
+    s->closed_gop = 0;
+
+    ff_mpeg_flush(avctx);
+}
+
+static av_cold int mpeg_decode_end(AVCodecContext *avctx)
+{
+    Mpeg1Context *s = avctx->priv_data;
+
+    if (s->mpeg_enc_ctx_allocated)
+        ff_MPV_common_end(&s->mpeg_enc_ctx);
+    av_freep(&s->a53_caption);
+    return 0;
+}
+
+static const AVProfile mpeg2_video_profiles[] = {
+    { FF_PROFILE_MPEG2_422,          "4:2:2"              },
+    { FF_PROFILE_MPEG2_HIGH,         "High"               },
+    { FF_PROFILE_MPEG2_SS,           "Spatially Scalable" },
+    { FF_PROFILE_MPEG2_SNR_SCALABLE, "SNR Scalable"       },
+    { FF_PROFILE_MPEG2_MAIN,         "Main"               },
+    { FF_PROFILE_MPEG2_SIMPLE,       "Simple"             },
+    { FF_PROFILE_RESERVED,           "Reserved"           },
+    { FF_PROFILE_RESERVED,           "Reserved"           },
+    { FF_PROFILE_UNKNOWN },
+};
+
+
+AVCodec ff_mpeg1video_decoder = {
+    .name                  = "mpeg1video",
+    .long_name             = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
+    .type                  = AVMEDIA_TYPE_VIDEO,
+    .id                    = AV_CODEC_ID_MPEG1VIDEO,
+    .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,
+    .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
+};
+
+AVCodec ff_mpeg2video_decoder = {
+    .name           = "mpeg2video",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
+    .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,
+    .profiles       = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
+};
+
+#if FF_API_XVMC
+#if CONFIG_MPEG_XVMC_DECODER
+static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
+{
+    if (avctx->active_thread_type & FF_THREAD_SLICE)
+        return -1;
+    if (!(avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
+        return -1;
+    if (!(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
+        av_dlog(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n");
+    }
+    mpeg_decode_init(avctx);
+
+    avctx->pix_fmt           = AV_PIX_FMT_XVMC_MPEG2_IDCT;
+    avctx->xvmc_acceleration = 2; // 2 - the blocks are packed!
+
+    return 0;
+}
+
+AVCodec ff_mpeg_xvmc_decoder = {
+    .name           = "mpegvideo_xvmc",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG2VIDEO_XVMC,
+    .priv_data_size = sizeof(Mpeg1Context),
+    .init           = mpeg_mc_decode_init,
+    .close          = mpeg_decode_end,
+    .decode         = mpeg_decode_frame,
+    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 |
+                      CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL | CODEC_CAP_DELAY,
+    .flush          = flush,
+};
+
+#endif
+#endif /* FF_API_XVMC */
diff --git a/libavcodec/mpeg12decdata.h b/libavcodec/mpeg12decdata.h
deleted file mode 100644
index 323a902..0000000
--- a/libavcodec/mpeg12decdata.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * MPEG1/2 decoder tables
- * copyright (c) 2000,2001 Fabrice Bellard
- * copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- * MPEG1/2 decoder tables.
- */
-
-#ifndef AVCODEC_MPEG12DECDATA_H
-#define AVCODEC_MPEG12DECDATA_H
-
-#include <stdint.h>
-#include "mpegvideo.h"
-
-
-#define MB_TYPE_ZERO_MV   0x20000000
-#define IS_ZERO_MV(a)   ((a)&MB_TYPE_ZERO_MV)
-
-static const uint8_t table_mb_ptype[7][2] = {
-    { 3, 5 }, // 0x01 MB_INTRA
-    { 1, 2 }, // 0x02 MB_PAT
-    { 1, 3 }, // 0x08 MB_FOR
-    { 1, 1 }, // 0x0A MB_FOR|MB_PAT
-    { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
-    { 1, 5 }, // 0x12 MB_QUANT|MB_PAT
-    { 2, 5 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
-};
-
-static const uint32_t ptype2mb_type[7] = {
-                    MB_TYPE_INTRA,
-                    MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
-                    MB_TYPE_L0,
-                    MB_TYPE_L0 | MB_TYPE_CBP,
-    MB_TYPE_QUANT | MB_TYPE_INTRA,
-    MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
-    MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
-};
-
-static const uint8_t table_mb_btype[11][2] = {
-    { 3, 5 }, // 0x01 MB_INTRA
-    { 2, 3 }, // 0x04 MB_BACK
-    { 3, 3 }, // 0x06 MB_BACK|MB_PAT
-    { 2, 4 }, // 0x08 MB_FOR
-    { 3, 4 }, // 0x0A MB_FOR|MB_PAT
-    { 2, 2 }, // 0x0C MB_FOR|MB_BACK
-    { 3, 2 }, // 0x0E MB_FOR|MB_BACK|MB_PAT
-    { 1, 6 }, // 0x11 MB_QUANT|MB_INTRA
-    { 2, 6 }, // 0x16 MB_QUANT|MB_BACK|MB_PAT
-    { 3, 6 }, // 0x1A MB_QUANT|MB_FOR|MB_PAT
-    { 2, 5 }, // 0x1E MB_QUANT|MB_FOR|MB_BACK|MB_PAT
-};
-
-static const uint32_t btype2mb_type[11] = {
-                    MB_TYPE_INTRA,
-                    MB_TYPE_L1,
-                    MB_TYPE_L1   | MB_TYPE_CBP,
-                    MB_TYPE_L0,
-                    MB_TYPE_L0   | MB_TYPE_CBP,
-                    MB_TYPE_L0L1,
-                    MB_TYPE_L0L1 | MB_TYPE_CBP,
-    MB_TYPE_QUANT | MB_TYPE_INTRA,
-    MB_TYPE_QUANT | MB_TYPE_L1   | MB_TYPE_CBP,
-    MB_TYPE_QUANT | MB_TYPE_L0   | MB_TYPE_CBP,
-    MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
-};
-
-static const uint8_t non_linear_qscale[32] = {
-    0, 1, 2, 3, 4, 5, 6, 7,
-    8,10,12,14,16,18,20,22,
-    24,28,32,36,40,44,48,52,
-    56,64,72,80,88,96,104,112,
-};
-
-#endif /* AVCODEC_MPEG12DECDATA_H */
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index ceb31e0..6c4ef6d 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -25,103 +25,102 @@
  * MPEG1/2 encoder
  */
 
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/stereo3d.h"
+
 #include "avcodec.h"
-#include "dsputil.h"
+#include "bytestream.h"
 #include "mathops.h"
-#include "mpegvideo.h"
-
 #include "mpeg12.h"
 #include "mpeg12data.h"
-#include "bytestream.h"
+#include "mpegvideo.h"
 
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
 
-static const uint8_t inv_non_linear_qscale[13] = {
-    0, 2, 4, 6, 8,
-    9,10,11,12,13,14,15,16,
+static const uint8_t inv_non_linear_qscale[] = {
+    0, 2, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16,
 };
 
-static const uint8_t svcd_scan_offset_placeholder[14] = {
-    0x10, 0x0E,
-    0x00, 0x80, 0x81,
-    0x00, 0x80, 0x81,
-    0xff, 0xff, 0xff,
-    0xff, 0xff, 0xff,
+static const uint8_t svcd_scan_offset_placeholder[] = {
+    0x10, 0x0E, 0x00, 0x80, 0x81, 0x00, 0x80,
+    0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 };
 
-static void mpeg1_encode_block(MpegEncContext *s,
-                         DCTELEM *block,
-                         int component);
-static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code);    // RAL: f_code parameter added
-
-static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1];
-static uint8_t fcode_tab[MAX_MV*2+1];
+static uint8_t mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1];
+static uint8_t fcode_tab[MAX_MV * 2 + 1];
 
-static uint8_t  uni_mpeg1_ac_vlc_len [64*64*2];
-static uint8_t  uni_mpeg2_ac_vlc_len [64*64*2];
+static uint8_t uni_mpeg1_ac_vlc_len[64 * 64 * 2];
+static uint8_t uni_mpeg2_ac_vlc_len[64 * 64 * 2];
 
-/* simple include everything table for dc, first byte is bits number next 3 are code*/
+/* simple include everything table for dc, first byte is bits
+ * number next 3 are code */
 static uint32_t mpeg1_lum_dc_uni[512];
 static uint32_t mpeg1_chr_dc_uni[512];
 
 static uint8_t mpeg1_index_run[2][64];
-static int8_t mpeg1_max_level[2][64];
+static int8_t  mpeg1_max_level[2][64];
 
-static void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len){
+static av_cold void init_uni_ac_vlc(RLTable *rl, uint8_t *uni_ac_vlc_len)
+{
     int i;
 
-    for(i=0; i<128; i++){
-        int level= i-64;
+    for (i = 0; i < 128; i++) {
+        int level = i - 64;
         int run;
         if (!level)
             continue;
-        for(run=0; run<64; run++){
+        for (run = 0; run < 64; run++) {
             int len, code;
-
-            int alevel= FFABS(level);
+            int alevel = FFABS(level);
 
             if (alevel > rl->max_level[0][run])
-                code= 111; /*rl->n*/
+                code = 111;                         /* rl->n */
             else
-                code= rl->index_run[0][run] + alevel - 1;
+                code = rl->index_run[0][run] + alevel - 1;
 
-            if (code < 111 /* rl->n */) {
-                /* length of vlc and sign */
-                len=   rl->table_vlc[code][1]+1;
+            if (code < 111) {                       /* rl->n */
+                /* length of VLC and sign */
+                len = rl->table_vlc[code][1] + 1;
             } else {
-                len=  rl->table_vlc[111/*rl->n*/][1]+6;
+                len = rl->table_vlc[111][1] + 6;    /* rl->n */
 
-                if (alevel < 128) {
+                if (alevel < 128)
                     len += 8;
-                } else {
+                else
                     len += 16;
-                }
             }
 
-            uni_ac_vlc_len [UNI_AC_ENC_INDEX(run, i)]= len;
+            uni_ac_vlc_len[UNI_AC_ENC_INDEX(run, i)] = len;
         }
     }
 }
 
-
-static int find_frame_rate_index(MpegEncContext *s){
+static int find_frame_rate_index(MpegEncContext *s)
+{
     int i;
-    int64_t dmin= INT64_MAX;
+    int64_t dmin = INT64_MAX;
     int64_t d;
 
-    for(i=1;i<14;i++) {
-        int64_t n0 = 1001LL / ff_mpeg12_frame_rate_tab[i].den * ff_mpeg12_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;
+    for (i = 1; i < 14; i++) {
+        int64_t n0 = 1001LL / ff_mpeg12_frame_rate_tab[i].den *
+                     ff_mpeg12_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;
+        if (d < dmin) {
+            dmin                = d;
+            s->frame_rate_index = i;
         }
     }
-    if(dmin)
+
+    if (dmin)
         return -1;
     else
         return 0;
@@ -131,43 +130,54 @@ static av_cold int encode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
 
-    if(ff_MPV_encode_init(avctx) < 0)
+    if (ff_MPV_encode_init(avctx) < 0)
         return -1;
 
-    if(find_frame_rate_index(s) < 0){
-        if(s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
-            av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n", avctx->time_base.den, avctx->time_base.num);
+    if (find_frame_rate_index(s) < 0) {
+        if (s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+            av_log(avctx, AV_LOG_ERROR, "MPEG1/2 does not support %d/%d fps\n",
+                   avctx->time_base.den, avctx->time_base.num);
             return -1;
-        }else{
-            av_log(avctx, AV_LOG_INFO, "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n", avctx->time_base.den, avctx->time_base.num);
+        } else {
+            av_log(avctx, AV_LOG_INFO,
+                   "MPEG1/2 does not support %d/%d fps, there may be AV sync issues\n",
+                   avctx->time_base.den, avctx->time_base.num);
         }
     }
 
-    if(avctx->profile == FF_PROFILE_UNKNOWN){
-        if(avctx->level != FF_LEVEL_UNKNOWN){
+    if (avctx->profile == FF_PROFILE_UNKNOWN) {
+        if (avctx->level != FF_LEVEL_UNKNOWN) {
             av_log(avctx, AV_LOG_ERROR, "Set profile and level\n");
             return -1;
         }
-        avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0; /* Main or 4:2:2 */
+        /* Main or 4:2:2 */
+        avctx->profile = s->chroma_format == CHROMA_420 ? 4 : 0;
     }
 
-    if(avctx->level == FF_LEVEL_UNKNOWN){
-        if(avctx->profile == 0){ /* 4:2:2 */
-            if(avctx->width <= 720 && avctx->height <= 608) avctx->level = 5; /* Main */
-            else                                            avctx->level = 2; /* High */
-        }else{
-            if(avctx->profile != 1 && s->chroma_format != CHROMA_420){
-                av_log(avctx, AV_LOG_ERROR, "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n");
+    if (avctx->level == FF_LEVEL_UNKNOWN) {
+        if (avctx->profile == 0) {                  /* 4:2:2 */
+            if (avctx->width <= 720 && avctx->height <= 608)
+                avctx->level = 5;                   /* Main */
+            else
+                avctx->level = 2;                   /* High */
+        } else {
+            if (avctx->profile != 1 && s->chroma_format != CHROMA_420) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Only High(1) and 4:2:2(0) profiles support 4:2:2 color sampling\n");
                 return -1;
             }
-            if(avctx->width <= 720 && avctx->height <= 576) avctx->level = 8; /* Main */
-            else if(avctx->width <= 1440)                   avctx->level = 6; /* High 1440 */
-            else                                            avctx->level = 4; /* High */
+            if (avctx->width <= 720 && avctx->height <= 576)
+                avctx->level = 8;                   /* Main */
+            else if (avctx->width <= 1440)
+                avctx->level = 6;                   /* High 1440 */
+            else
+                avctx->level = 4;                   /* High */
         }
     }
 
     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");
+        av_log(avctx, AV_LOG_ERROR,
+               "Drop frame time code only allowed with 1001/30000 fps\n");
         return -1;
     }
 
@@ -177,131 +187,137 @@ static av_cold int encode_init(AVCodecContext *avctx)
 static void put_header(MpegEncContext *s, int header)
 {
     avpriv_align_put_bits(&s->pb);
-    put_bits(&s->pb, 16, header>>16);
+    put_bits(&s->pb, 16, header >> 16);
     put_sbits(&s->pb, 16, header);
 }
 
 /* put sequence header if needed */
 static void mpeg1_encode_sequence_header(MpegEncContext *s)
 {
-        unsigned int vbv_buffer_size;
-        unsigned int fps, v;
-        int i;
-        uint64_t time_code;
-        float best_aspect_error= 1E10;
-        float aspect_ratio= av_q2d(s->avctx->sample_aspect_ratio);
-        int constraint_parameter_flag;
+    unsigned int vbv_buffer_size, fps, v;
+    int i, constraint_parameter_flag;
+    uint64_t time_code;
+    float best_aspect_error = 1E10;
+    float aspect_ratio      = av_q2d(s->avctx->sample_aspect_ratio);
 
-        if(aspect_ratio==0.0) aspect_ratio= 1.0; //pixel aspect 1:1 (VGA)
+    if (aspect_ratio == 0.0)
+        aspect_ratio = 1.0;             // pixel aspect 1.1 (VGA)
 
-        if (s->current_picture.f.key_frame) {
-            AVRational framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index];
+    if (s->current_picture.f.key_frame) {
+        AVRational framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index];
 
-            /* mpeg1 header repeated every gop */
-            put_header(s, SEQ_START_CODE);
+        /* mpeg1 header repeated every gop */
+        put_header(s, SEQ_START_CODE);
 
-            put_sbits(&s->pb, 12, s->width );
-            put_sbits(&s->pb, 12, s->height);
+        put_sbits(&s->pb, 12, s->width);
+        put_sbits(&s->pb, 12, s->height);
 
-            for(i=1; i<15; i++){
-                float error= aspect_ratio;
-                if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO || i <=1)
-                    error-= 1.0/ff_mpeg1_aspect[i];
-                else
-                    error-= av_q2d(ff_mpeg2_aspect[i])*s->height/s->width;
+        for (i = 1; i < 15; i++) {
+            float error = aspect_ratio;
+            if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO || i <= 1)
+                error -= 1.0 / ff_mpeg1_aspect[i];
+            else
+                error -= av_q2d(ff_mpeg2_aspect[i]) * s->height / s->width;
 
-                error= FFABS(error);
+            error = FFABS(error);
 
-                if(error < best_aspect_error){
-                    best_aspect_error= error;
-                    s->aspect_ratio_info= i;
-                }
+            if (error < best_aspect_error) {
+                best_aspect_error    = error;
+                s->aspect_ratio_info = i;
             }
+        }
 
-            put_bits(&s->pb, 4, s->aspect_ratio_info);
-            put_bits(&s->pb, 4, s->frame_rate_index);
+        put_bits(&s->pb, 4, s->aspect_ratio_info);
+        put_bits(&s->pb, 4, s->frame_rate_index);
 
-            if(s->avctx->rc_max_rate){
-                v = (s->avctx->rc_max_rate + 399) / 400;
-                if (v > 0x3ffff && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
-                    v = 0x3ffff;
-            }else{
-                v= 0x3FFFF;
-            }
+        if (s->avctx->rc_max_rate) {
+            v = (s->avctx->rc_max_rate + 399) / 400;
+            if (v > 0x3ffff && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
+                v = 0x3ffff;
+        } else {
+            v = 0x3FFFF;
+        }
 
-            if(s->avctx->rc_buffer_size)
-                vbv_buffer_size = s->avctx->rc_buffer_size;
-            else
-                /* VBV calculation: Scaled so that a VCD has the proper VBV size of 40 kilobytes */
-                vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024;
-            vbv_buffer_size= (vbv_buffer_size + 16383) / 16384;
-
-            put_sbits(&s->pb, 18, v);
-            put_bits(&s->pb, 1, 1); /* marker */
-            put_sbits(&s->pb, 10, vbv_buffer_size);
-
-            constraint_parameter_flag=
-                s->width <= 768 && s->height <= 576 &&
-                s->mb_width * s->mb_height <= 396 &&
-                s->mb_width * s->mb_height * framerate.num <= framerate.den*396*25 &&
-                framerate.num <= framerate.den*30 &&
-                s->avctx->me_range && s->avctx->me_range < 128 &&
-                vbv_buffer_size <= 20 &&
-                v <= 1856000/400 &&
-                s->codec_id == AV_CODEC_ID_MPEG1VIDEO;
-
-            put_bits(&s->pb, 1, constraint_parameter_flag);
-
-            ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix);
-            ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix);
-
-            if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO){
-                put_header(s, EXT_START_CODE);
-                put_bits(&s->pb, 4, 1); //seq ext
-
-                put_bits(&s->pb, 1, s->avctx->profile == 0); //escx 1 for 4:2:2 profile */
-
-                put_bits(&s->pb, 3, s->avctx->profile); //profile
-                put_bits(&s->pb, 4, s->avctx->level); //level
-
-                put_bits(&s->pb, 1, s->progressive_sequence);
-                put_bits(&s->pb, 2, s->chroma_format);
-                put_bits(&s->pb, 2, s->width >>12);
-                put_bits(&s->pb, 2, s->height>>12);
-                put_bits(&s->pb, 12, v>>18); //bitrate ext
-                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
-            }
+        if (s->avctx->rc_buffer_size)
+            vbv_buffer_size = s->avctx->rc_buffer_size;
+        else
+            /* VBV calculation: Scaled so that a VCD has the proper
+             * VBV size of 40 kilobytes */
+            vbv_buffer_size = ((20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024;
+        vbv_buffer_size = (vbv_buffer_size + 16383) / 16384;
+
+        put_sbits(&s->pb, 18, v);
+        put_bits(&s->pb, 1, 1);         // marker
+        put_sbits(&s->pb, 10, vbv_buffer_size);
+
+        constraint_parameter_flag =
+            s->width  <= 768                                    &&
+            s->height <= 576                                    &&
+            s->mb_width * s->mb_height                 <= 396   &&
+            s->mb_width * s->mb_height * framerate.num <= 396 * 25 * framerate.den &&
+            framerate.num <= framerate.den * 30                 &&
+            s->avctx->me_range                                  &&
+            s->avctx->me_range < 128                            &&
+            vbv_buffer_size <= 20                               &&
+            v <= 1856000 / 400                                  &&
+            s->codec_id == AV_CODEC_ID_MPEG1VIDEO;
+
+        put_bits(&s->pb, 1, constraint_parameter_flag);
+
+        ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix);
+        ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix);
+
+        if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+            put_header(s, EXT_START_CODE);
+            put_bits(&s->pb, 4, 1);                 // seq ext
+
+            put_bits(&s->pb, 1, s->avctx->profile == 0); // escx 1 for 4:2:2 profile
+
+            put_bits(&s->pb, 3, s->avctx->profile); // profile
+            put_bits(&s->pb, 4, s->avctx->level);   // level
+
+            put_bits(&s->pb, 1, s->progressive_sequence);
+            put_bits(&s->pb, 2, s->chroma_format);
+            put_bits(&s->pb, 2, s->width  >> 12);
+            put_bits(&s->pb, 2, s->height >> 12);
+            put_bits(&s->pb, 12, v >> 18);          // bitrate ext
+            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_header(s, GOP_START_CODE);
-            put_bits(&s->pb, 1, s->drop_frame_timecode); /* drop frame flag */
-            /* time code : we must convert from the real frame rate to a
-               fake mpeg frame rate in case of low frame rate */
-            fps = (framerate.num + framerate.den/2)/ framerate.den;
-            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);
-            }
-            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);
-            put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60));
-            put_bits(&s->pb, 6, (uint32_t)((time_code % fps)));
-            put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP));
-            put_bits(&s->pb, 1, 0); /* broken link */
+        put_header(s, GOP_START_CODE);
+        put_bits(&s->pb, 1, s->drop_frame_timecode);    // drop frame flag
+        /* time code: we must convert from the real frame rate to a
+         * fake MPEG frame rate in case of low frame rate */
+        fps       = (framerate.num + framerate.den / 2) / framerate.den;
+        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;
+            /* not needed since -2,-1 / 1798 in C returns 0 */
+            // if (m < 2)
+            //     m += 2;
+            time_code += 18 * d + 2 * ((m - 2) / 1798);
         }
+        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);
+        put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60));
+        put_bits(&s->pb, 6, (uint32_t)((time_code % fps)));
+        put_bits(&s->pb, 1, !!(s->flags & CODEC_FLAG_CLOSED_GOP));
+        put_bits(&s->pb, 1, 0);                     // broken link
+    }
 }
 
-static inline void encode_mb_skip_run(MpegEncContext *s, int run){
+static inline void encode_mb_skip_run(MpegEncContext *s, int run)
+{
     while (run >= 33) {
         put_bits(&s->pb, 11, 0x008);
         run -= 33;
@@ -312,27 +328,31 @@ static inline void encode_mb_skip_run(MpegEncContext *s, int run){
 
 static av_always_inline void put_qscale(MpegEncContext *s)
 {
-    if(s->q_scale_type){
-        assert(s->qscale>=1 && s->qscale <=12);
+    if (s->q_scale_type) {
+        assert(s->qscale >= 1 && s->qscale <= 12);
         put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]);
-    }else{
+    } else {
         put_bits(&s->pb, 5, s->qscale);
     }
 }
 
-void ff_mpeg1_encode_slice_header(MpegEncContext *s){
+void ff_mpeg1_encode_slice_header(MpegEncContext *s)
+{
     if (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 */
+        /* slice_vertical_position_extension */
+        put_bits(&s->pb, 3, s->mb_y >> 7);
     } else {
         put_header(s, SLICE_MIN_START_CODE + s->mb_y);
     }
     put_qscale(s);
-    put_bits(&s->pb, 1, 0); /* slice extra information */
+    /* slice extra information */
+    put_bits(&s->pb, 1, 0);
 }
 
 void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
 {
+    AVFrameSideData *side_data;
     mpeg1_encode_sequence_header(s);
 
     /* mpeg1 picture header */
@@ -340,60 +360,60 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
     /* temporal reference */
 
     // RAL: s->picture_number instead of s->fake_picture_number
-    put_bits(&s->pb, 10, (s->picture_number -
-                          s->gop_picture_number) & 0x3ff);
+    put_bits(&s->pb, 10,
+             (s->picture_number - s->gop_picture_number) & 0x3ff);
     put_bits(&s->pb, 3, s->pict_type);
 
-    s->vbv_delay_ptr= s->pb.buf + put_bits_count(&s->pb)/8;
-    put_bits(&s->pb, 16, 0xFFFF); /* vbv_delay */
+    s->vbv_delay_ptr = s->pb.buf + put_bits_count(&s->pb) / 8;
+    put_bits(&s->pb, 16, 0xFFFF);               /* vbv_delay */
 
-    // RAL: Forward f_code also needed for B frames
-    if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) {
-        put_bits(&s->pb, 1, 0); /* half pel coordinates */
-        if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
-            put_bits(&s->pb, 3, s->f_code); /* forward_f_code */
+    // RAL: Forward f_code also needed for B-frames
+    if (s->pict_type == AV_PICTURE_TYPE_P ||
+        s->pict_type == AV_PICTURE_TYPE_B) {
+        put_bits(&s->pb, 1, 0);                 /* half pel coordinates */
+        if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
+            put_bits(&s->pb, 3, s->f_code);     /* forward_f_code */
         else
-            put_bits(&s->pb, 3, 7); /* forward_f_code */
+            put_bits(&s->pb, 3, 7);             /* forward_f_code */
     }
 
-    // RAL: Backward f_code necessary for B frames
+    // RAL: Backward f_code necessary for B-frames
     if (s->pict_type == AV_PICTURE_TYPE_B) {
-        put_bits(&s->pb, 1, 0); /* half pel coordinates */
-        if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
-            put_bits(&s->pb, 3, s->b_code); /* backward_f_code */
+        put_bits(&s->pb, 1, 0);                 /* half pel coordinates */
+        if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO)
+            put_bits(&s->pb, 3, s->b_code);     /* backward_f_code */
         else
-            put_bits(&s->pb, 3, 7); /* backward_f_code */
+            put_bits(&s->pb, 3, 7);             /* backward_f_code */
     }
 
-    put_bits(&s->pb, 1, 0); /* extra bit picture */
+    put_bits(&s->pb, 1, 0);                     /* extra bit picture */
 
     s->frame_pred_frame_dct = 1;
-    if(s->codec_id == AV_CODEC_ID_MPEG2VIDEO){
+    if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
         put_header(s, EXT_START_CODE);
-        put_bits(&s->pb, 4, 8); //pic ext
-        if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) {
+        put_bits(&s->pb, 4, 8);                 /* pic ext */
+        if (s->pict_type == AV_PICTURE_TYPE_P ||
+            s->pict_type == AV_PICTURE_TYPE_B) {
             put_bits(&s->pb, 4, s->f_code);
             put_bits(&s->pb, 4, s->f_code);
-        }else{
+        } else {
             put_bits(&s->pb, 8, 255);
         }
         if (s->pict_type == AV_PICTURE_TYPE_B) {
             put_bits(&s->pb, 4, s->b_code);
             put_bits(&s->pb, 4, s->b_code);
-        }else{
+        } else {
             put_bits(&s->pb, 8, 255);
         }
         put_bits(&s->pb, 2, s->intra_dc_precision);
 
         assert(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 */
-        } else {
+        if (s->progressive_sequence)
+            put_bits(&s->pb, 1, 0);             /* no repeat */
+        else
             put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first);
-        }
-        /* XXX: optimize the generation of this flag with entropy
-           measures */
+        /* XXX: optimize the generation of this flag with entropy measures */
         s->frame_pred_frame_dct = s->progressive_sequence;
 
         put_bits(&s->pb, 1, s->frame_pred_frame_dct);
@@ -403,20 +423,59 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number)
         put_bits(&s->pb, 1, s->alternate_scan);
         put_bits(&s->pb, 1, s->repeat_first_field);
         s->progressive_frame = s->progressive_sequence;
-        put_bits(&s->pb, 1, s->chroma_format == CHROMA_420 ? s->progressive_frame : 0); /* chroma_420_type */
+        /* chroma_420_type */
+        put_bits(&s->pb, 1, s->chroma_format ==
+                            CHROMA_420 ? s->progressive_frame : 0);
         put_bits(&s->pb, 1, s->progressive_frame);
-        put_bits(&s->pb, 1, 0); //composite_display_flag
+        put_bits(&s->pb, 1, 0);                 /* composite_display_flag */
     }
     if (s->scan_offset) {
         int i;
 
         put_header(s, USER_START_CODE);
-        for(i=0; i<sizeof(svcd_scan_offset_placeholder); i++){
+        for (i = 0; i < sizeof(svcd_scan_offset_placeholder); i++)
             put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]);
+    }
+    side_data = av_frame_get_side_data(&s->current_picture_ptr->f,
+                                       AV_FRAME_DATA_STEREO3D);
+    if (side_data) {
+        AVStereo3D *stereo = (AVStereo3D *)side_data->data;
+        uint8_t fpa_type;
+
+        switch (stereo->type) {
+        case AV_STEREO3D_SIDEBYSIDE:
+            fpa_type = 0x03;
+            break;
+        case AV_STEREO3D_TOPBOTTOM:
+            fpa_type = 0x04;
+            break;
+        case AV_STEREO3D_2D:
+            fpa_type = 0x08;
+            break;
+        case AV_STEREO3D_SIDEBYSIDE_QUINCUNX:
+            fpa_type = 0x23;
+            break;
+        default:
+            fpa_type = 0;
+            break;
+        }
+
+        if (fpa_type != 0) {
+            put_header(s, USER_START_CODE);
+            put_bits(&s->pb, 8, 'J');   // S3D_video_format_signaling_identifier
+            put_bits(&s->pb, 8, 'P');
+            put_bits(&s->pb, 8, '3');
+            put_bits(&s->pb, 8, 'D');
+            put_bits(&s->pb, 8, 0x03);  // S3D_video_format_length
+
+            put_bits(&s->pb, 1, 1);     // reserved_bit
+            put_bits(&s->pb, 7, fpa_type); // S3D_video_format_type
+            put_bits(&s->pb, 8, 0x04);  // reserved_data[0]
+            put_bits(&s->pb, 8, 0xFF);  // reserved_data[1]
         }
     }
 
-    s->mb_y=0;
+    s->mb_y = 0;
     ff_mpeg1_encode_slice_header(s);
 }
 
@@ -426,504 +485,558 @@ static inline void put_mb_modes(MpegEncContext *s, int n, int bits,
     put_bits(&s->pb, n, bits);
     if (!s->frame_pred_frame_dct) {
         if (has_mv)
-            put_bits(&s->pb, 2, 2 - field_motion); /* motion_type: frame/field */
+            /* motion_type: frame/field */
+            put_bits(&s->pb, 2, 2 - field_motion);
         put_bits(&s->pb, 1, s->interlaced_dct);
     }
 }
 
+// RAL: Parameter added: f_or_b_code
+static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code)
+{
+    if (val == 0) {
+        /* zero vector */
+        put_bits(&s->pb,
+                 ff_mpeg12_mbMotionVectorTable[0][1],
+                 ff_mpeg12_mbMotionVectorTable[0][0]);
+    } else {
+        int code, sign, bits;
+        int bit_size = f_or_b_code - 1;
+        int range    = 1 << bit_size;
+        /* modulo encoding */
+        val = sign_extend(val, 5 + bit_size);
+
+        if (val >= 0) {
+            val--;
+            code = (val >> bit_size) + 1;
+            bits = val & (range - 1);
+            sign = 0;
+        } else {
+            val = -val;
+            val--;
+            code = (val >> bit_size) + 1;
+            bits = val & (range - 1);
+            sign = 1;
+        }
+
+        assert(code > 0 && code <= 16);
+
+        put_bits(&s->pb,
+                 ff_mpeg12_mbMotionVectorTable[code][1],
+                 ff_mpeg12_mbMotionVectorTable[code][0]);
+
+        put_bits(&s->pb, 1, sign);
+        if (bit_size > 0)
+            put_bits(&s->pb, bit_size, bits);
+    }
+}
+
+static inline void encode_dc(MpegEncContext *s, int diff, int component)
+{
+    if (((unsigned) (diff + 255)) >= 511) {
+        int index;
+
+        if (diff < 0) {
+            index = av_log2_16bit(-2 * diff);
+            diff--;
+        } else {
+            index = av_log2_16bit(2 * diff);
+        }
+        if (component == 0)
+            put_bits(&s->pb,
+                     ff_mpeg12_vlc_dc_lum_bits[index] + index,
+                     (ff_mpeg12_vlc_dc_lum_code[index] << index) +
+                     (diff & ((1 << index) - 1)));
+        else
+            put_bits(&s->pb,
+                     ff_mpeg12_vlc_dc_chroma_bits[index] + index,
+                     (ff_mpeg12_vlc_dc_chroma_code[index] << index) +
+                     (diff & ((1 << index) - 1)));
+    } else {
+        if (component == 0)
+            put_bits(&s->pb,
+                     mpeg1_lum_dc_uni[diff + 255] & 0xFF,
+                     mpeg1_lum_dc_uni[diff + 255] >> 8);
+        else
+            put_bits(&s->pb,
+                     mpeg1_chr_dc_uni[diff + 255] & 0xFF,
+                     mpeg1_chr_dc_uni[diff + 255] >> 8);
+    }
+}
+
+static void mpeg1_encode_block(MpegEncContext *s, int16_t *block, int n)
+{
+    int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign;
+    int code, component;
+    const uint16_t (*table_vlc)[2] = ff_rl_mpeg1.table_vlc;
+
+    last_index = s->block_last_index[n];
+
+    /* DC coef */
+    if (s->mb_intra) {
+        component = (n <= 3 ? 0 : (n & 1) + 1);
+        dc        = block[0];                   /* overflow is impossible */
+        diff      = dc - s->last_dc[component];
+        encode_dc(s, diff, component);
+        s->last_dc[component] = dc;
+        i = 1;
+        if (s->intra_vlc_format)
+            table_vlc = ff_rl_mpeg2.table_vlc;
+    } else {
+        /* encode the first coefficient: needs to be done here because
+         * it is handled slightly differently */
+        level = block[0];
+        if (abs(level) == 1) {
+            code = ((uint32_t)level >> 31);     /* the sign bit */
+            put_bits(&s->pb, 2, code | 0x02);
+            i = 1;
+        } else {
+            i             = 0;
+            last_non_zero = -1;
+            goto next_coef;
+        }
+    }
+
+    /* now quantify & encode AC coefs */
+    last_non_zero = i - 1;
+
+    for (; i <= last_index; i++) {
+        j     = s->intra_scantable.permutated[i];
+        level = block[j];
+
+next_coef:
+        /* encode using VLC */
+        if (level != 0) {
+            run = i - last_non_zero - 1;
+
+            alevel = level;
+            MASK_ABS(sign, alevel);
+            sign &= 1;
+
+            if (alevel <= mpeg1_max_level[0][run]) {
+                code = mpeg1_index_run[0][run] + alevel - 1;
+                /* store the VLC & sign at once */
+                put_bits(&s->pb, table_vlc[code][1] + 1,
+                         (table_vlc[code][0] << 1) + sign);
+            } else {
+                /* escape seems to be pretty rare <5% so I do not optimize it */
+                put_bits(&s->pb, table_vlc[111][1], table_vlc[111][0]);
+                /* escape: only clip in this case */
+                put_bits(&s->pb, 6, run);
+                if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+                    if (alevel < 128) {
+                        put_sbits(&s->pb, 8, level);
+                    } else {
+                        if (level < 0)
+                            put_bits(&s->pb, 16, 0x8001 + level + 255);
+                        else
+                            put_sbits(&s->pb, 16, level);
+                    }
+                } else {
+                    put_sbits(&s->pb, 12, level);
+                }
+            }
+            last_non_zero = i;
+        }
+    }
+    /* end of block */
+    put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]);
+}
+
 static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s,
-                                                   DCTELEM block[6][64],
-                                                   int motion_x, int motion_y,
-                                                   int mb_block_count)
+                                                      int16_t block[6][64],
+                                                      int motion_x, int motion_y,
+                                                      int mb_block_count)
 {
     int i, cbp;
-    const int mb_x = s->mb_x;
-    const int mb_y = s->mb_y;
-    const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y;
+    const int mb_x     = s->mb_x;
+    const int mb_y     = s->mb_y;
+    const int first_mb = mb_x == s->resync_mb_x && mb_y == s->resync_mb_y;
 
     /* compute cbp */
     cbp = 0;
-    for(i=0;i<mb_block_count;i++) {
+    for (i = 0; i < mb_block_count; i++)
         if (s->block_last_index[i] >= 0)
             cbp |= 1 << (mb_block_count - 1 - i);
-    }
 
     if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 &&
-        (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)) &&
+        (mb_x != s->mb_width - 1 ||
+         (mb_y != s->mb_height - 1 && s->codec_id == AV_CODEC_ID_MPEG1VIDEO)) &&
         ((s->pict_type == AV_PICTURE_TYPE_P && (motion_x | motion_y) == 0) ||
-        (s->pict_type == AV_PICTURE_TYPE_B && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
-        ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {
+         (s->pict_type == AV_PICTURE_TYPE_B && s->mv_dir == s->last_mv_dir &&
+          (((s->mv_dir & MV_DIR_FORWARD)
+            ? ((s->mv[0][0][0] - s->last_mv[0][0][0]) |
+               (s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |
+           ((s->mv_dir & MV_DIR_BACKWARD)
+            ? ((s->mv[1][0][0] - s->last_mv[1][0][0]) |
+               (s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {
         s->mb_skip_run++;
         s->qscale -= s->dquant;
         s->skip_count++;
         s->misc_bits++;
         s->last_bits++;
-        if(s->pict_type == AV_PICTURE_TYPE_P){
-            s->last_mv[0][1][0]= s->last_mv[0][0][0]=
-            s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0;
+        if (s->pict_type == AV_PICTURE_TYPE_P) {
+            s->last_mv[0][0][0] =
+            s->last_mv[0][0][1] =
+            s->last_mv[0][1][0] =
+            s->last_mv[0][1][1] = 0;
         }
     } else {
-        if(first_mb){
+        if (first_mb) {
             assert(s->mb_skip_run == 0);
             encode_mb_skip_run(s, s->mb_x);
-        }else{
+        } else {
             encode_mb_skip_run(s, s->mb_skip_run);
         }
 
         if (s->pict_type == AV_PICTURE_TYPE_I) {
-            if(s->dquant && cbp){
-                put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */
+            if (s->dquant && cbp) {
+                /* macroblock_type: macroblock_quant = 1 */
+                put_mb_modes(s, 2, 1, 0, 0);
                 put_qscale(s);
-            }else{
-                put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */
+            } else {
+                /* macroblock_type: macroblock_quant = 0 */
+                put_mb_modes(s, 1, 1, 0, 0);
                 s->qscale -= s->dquant;
             }
-            s->misc_bits+= get_bits_diff(s);
+            s->misc_bits += get_bits_diff(s);
             s->i_count++;
         } else if (s->mb_intra) {
-            if(s->dquant && cbp){
+            if (s->dquant && cbp) {
                 put_mb_modes(s, 6, 0x01, 0, 0);
                 put_qscale(s);
-            }else{
+            } else {
                 put_mb_modes(s, 5, 0x03, 0, 0);
                 s->qscale -= s->dquant;
             }
-            s->misc_bits+= get_bits_diff(s);
+            s->misc_bits += get_bits_diff(s);
             s->i_count++;
             memset(s->last_mv, 0, sizeof(s->last_mv));
         } else if (s->pict_type == AV_PICTURE_TYPE_P) {
-            if(s->mv_type == MV_TYPE_16X16){
+            if (s->mv_type == MV_TYPE_16X16) {
                 if (cbp != 0) {
-                    if ((motion_x|motion_y) == 0) {
-                        if(s->dquant){
-                            put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */
+                    if ((motion_x | motion_y) == 0) {
+                        if (s->dquant) {
+                            /* macroblock_pattern & quant */
+                            put_mb_modes(s, 5, 1, 0, 0);
                             put_qscale(s);
-                        }else{
-                            put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */
+                        } else {
+                            /* macroblock_pattern only */
+                            put_mb_modes(s, 2, 1, 0, 0);
                         }
-                        s->misc_bits+= get_bits_diff(s);
+                        s->misc_bits += get_bits_diff(s);
                     } else {
-                        if(s->dquant){
-                            put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */
+                        if (s->dquant) {
+                            put_mb_modes(s, 5, 2, 1, 0);    /* motion + cbp */
                             put_qscale(s);
-                        }else{
-                            put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */
+                        } else {
+                            put_mb_modes(s, 1, 1, 1, 0);    /* motion + cbp */
                         }
-                        s->misc_bits+= get_bits_diff(s);
-                        mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);    // RAL: f_code parameter added
-                        mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);    // RAL: f_code parameter added
-                        s->mv_bits+= get_bits_diff(s);
+                        s->misc_bits += get_bits_diff(s);
+                        // RAL: f_code parameter added
+                        mpeg1_encode_motion(s,
+                                            motion_x - s->last_mv[0][0][0],
+                                            s->f_code);
+                        // RAL: f_code parameter added
+                        mpeg1_encode_motion(s,
+                                            motion_y - s->last_mv[0][0][1],
+                                            s->f_code);
+                        s->mv_bits += get_bits_diff(s);
                     }
                 } else {
-                    put_bits(&s->pb, 3, 1); /* motion only */
+                    put_bits(&s->pb, 3, 1);         /* motion only */
                     if (!s->frame_pred_frame_dct)
-                        put_bits(&s->pb, 2, 2); /* motion_type: frame */
-                    s->misc_bits+= get_bits_diff(s);
-                    mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);    // RAL: f_code parameter added
-                    mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);    // RAL: f_code parameter added
-                    s->qscale -= s->dquant;
-                    s->mv_bits+= get_bits_diff(s);
+                        put_bits(&s->pb, 2, 2);     /* motion_type: frame */
+                    s->misc_bits += get_bits_diff(s);
+                    // RAL: f_code parameter added
+                    mpeg1_encode_motion(s,
+                                        motion_x - s->last_mv[0][0][0],
+                                        s->f_code);
+                    // RAL: f_code parameter added
+                    mpeg1_encode_motion(s,
+                                        motion_y - s->last_mv[0][0][1],
+                                        s->f_code);
+                    s->qscale  -= s->dquant;
+                    s->mv_bits += get_bits_diff(s);
                 }
-                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{
+                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);
 
                 if (cbp) {
-                    if(s->dquant){
-                        put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */
+                    if (s->dquant) {
+                        put_mb_modes(s, 5, 2, 1, 1);    /* motion + cbp */
                         put_qscale(s);
-                    }else{
-                        put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */
+                    } else {
+                        put_mb_modes(s, 1, 1, 1, 1);    /* motion + cbp */
                     }
                 } else {
-                    put_bits(&s->pb, 3, 1); /* motion only */
-                    put_bits(&s->pb, 2, 1); /* motion_type: field */
+                    put_bits(&s->pb, 3, 1);             /* motion only */
+                    put_bits(&s->pb, 2, 1);             /* motion_type: field */
                     s->qscale -= s->dquant;
                 }
-                s->misc_bits+= get_bits_diff(s);
-                for(i=0; i<2; i++){
+                s->misc_bits += get_bits_diff(s);
+                for (i = 0; i < 2; i++) {
                     put_bits(&s->pb, 1, s->field_select[0][i]);
-                    mpeg1_encode_motion(s, s->mv[0][i][0] -  s->last_mv[0][i][0]    , s->f_code);
-                    mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
-                    s->last_mv[0][i][0]=   s->mv[0][i][0];
-                    s->last_mv[0][i][1]= 2*s->mv[0][i][1];
+                    mpeg1_encode_motion(s,
+                                        s->mv[0][i][0] - s->last_mv[0][i][0],
+                                        s->f_code);
+                    mpeg1_encode_motion(s,
+                                        s->mv[0][i][1] - (s->last_mv[0][i][1] >> 1),
+                                        s->f_code);
+                    s->last_mv[0][i][0] = s->mv[0][i][0];
+                    s->last_mv[0][i][1] = 2 * s->mv[0][i][1];
                 }
-                s->mv_bits+= get_bits_diff(s);
+                s->mv_bits += get_bits_diff(s);
             }
-            if(cbp) {
+            if (cbp) {
                 if (s->chroma_y_shift) {
-                    put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]);
+                    put_bits(&s->pb,
+                             ff_mpeg12_mbPatTable[cbp][1],
+                             ff_mpeg12_mbPatTable[cbp][0]);
                 } else {
-                    put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]);
+                    put_bits(&s->pb,
+                             ff_mpeg12_mbPatTable[cbp >> 2][1],
+                             ff_mpeg12_mbPatTable[cbp >> 2][0]);
                     put_sbits(&s->pb, 2, cbp);
                 }
             }
             s->f_count++;
-        } else{
-            if(s->mv_type == MV_TYPE_16X16){
-                if (cbp){    // With coded bloc pattern
+        } else {
+            if (s->mv_type == MV_TYPE_16X16) {
+                if (cbp) {                      // With coded bloc pattern
                     if (s->dquant) {
-                        if(s->mv_dir == MV_DIR_FORWARD)
+                        if (s->mv_dir == MV_DIR_FORWARD)
                             put_mb_modes(s, 6, 3, 1, 0);
                         else
-                            put_mb_modes(s, 8-s->mv_dir, 2, 1, 0);
+                            put_mb_modes(s, 8 - s->mv_dir, 2, 1, 0);
                         put_qscale(s);
                     } else {
-                        put_mb_modes(s, 5-s->mv_dir, 3, 1, 0);
+                        put_mb_modes(s, 5 - s->mv_dir, 3, 1, 0);
                     }
-                }else{    // No coded bloc pattern
-                    put_bits(&s->pb, 5-s->mv_dir, 2);
+                } else {                        // No coded bloc pattern
+                    put_bits(&s->pb, 5 - s->mv_dir, 2);
                     if (!s->frame_pred_frame_dct)
                         put_bits(&s->pb, 2, 2); /* motion_type: frame */
                     s->qscale -= s->dquant;
                 }
                 s->misc_bits += get_bits_diff(s);
-                if (s->mv_dir&MV_DIR_FORWARD){
-                    mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);
-                    mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
-                    s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0];
-                    s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1];
+                if (s->mv_dir & MV_DIR_FORWARD) {
+                    mpeg1_encode_motion(s,
+                                        s->mv[0][0][0] - s->last_mv[0][0][0],
+                                        s->f_code);
+                    mpeg1_encode_motion(s,
+                                        s->mv[0][0][1] - s->last_mv[0][0][1],
+                                        s->f_code);
+                    s->last_mv[0][0][0] =
+                    s->last_mv[0][1][0] = s->mv[0][0][0];
+                    s->last_mv[0][0][1] =
+                    s->last_mv[0][1][1] = s->mv[0][0][1];
                     s->f_count++;
                 }
-                if (s->mv_dir&MV_DIR_BACKWARD){
-                    mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);
-                    mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
-                    s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0];
-                    s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1];
+                if (s->mv_dir & MV_DIR_BACKWARD) {
+                    mpeg1_encode_motion(s,
+                                        s->mv[1][0][0] - s->last_mv[1][0][0],
+                                        s->b_code);
+                    mpeg1_encode_motion(s,
+                                        s->mv[1][0][1] - s->last_mv[1][0][1],
+                                        s->b_code);
+                    s->last_mv[1][0][0] =
+                    s->last_mv[1][1][0] = s->mv[1][0][0];
+                    s->last_mv[1][0][1] =
+                    s->last_mv[1][1][1] = s->mv[1][0][1];
                     s->b_count++;
                 }
-            }else{
+            } else {
                 assert(s->mv_type == MV_TYPE_FIELD);
                 assert(!s->frame_pred_frame_dct);
-                if (cbp){    // With coded bloc pattern
+                if (cbp) {                      // With coded bloc pattern
                     if (s->dquant) {
-                        if(s->mv_dir == MV_DIR_FORWARD)
+                        if (s->mv_dir == MV_DIR_FORWARD)
                             put_mb_modes(s, 6, 3, 1, 1);
                         else
-                            put_mb_modes(s, 8-s->mv_dir, 2, 1, 1);
+                            put_mb_modes(s, 8 - s->mv_dir, 2, 1, 1);
                         put_qscale(s);
                     } else {
-                        put_mb_modes(s, 5-s->mv_dir, 3, 1, 1);
+                        put_mb_modes(s, 5 - s->mv_dir, 3, 1, 1);
                     }
-                }else{    // No coded bloc pattern
-                    put_bits(&s->pb, 5-s->mv_dir, 2);
-                    put_bits(&s->pb, 2, 1); /* motion_type: field */
+                } else {                        // No coded bloc pattern
+                    put_bits(&s->pb, 5 - s->mv_dir, 2);
+                    put_bits(&s->pb, 2, 1);     /* motion_type: field */
                     s->qscale -= s->dquant;
                 }
                 s->misc_bits += get_bits_diff(s);
-                if (s->mv_dir&MV_DIR_FORWARD){
-                    for(i=0; i<2; i++){
+                if (s->mv_dir & MV_DIR_FORWARD) {
+                    for (i = 0; i < 2; i++) {
                         put_bits(&s->pb, 1, s->field_select[0][i]);
-                        mpeg1_encode_motion(s, s->mv[0][i][0] -  s->last_mv[0][i][0]    , s->f_code);
-                        mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);
-                        s->last_mv[0][i][0]=   s->mv[0][i][0];
-                        s->last_mv[0][i][1]= 2*s->mv[0][i][1];
+                        mpeg1_encode_motion(s,
+                                            s->mv[0][i][0] - s->last_mv[0][i][0],
+                                            s->f_code);
+                        mpeg1_encode_motion(s,
+                                            s->mv[0][i][1] - (s->last_mv[0][i][1] >> 1),
+                                            s->f_code);
+                        s->last_mv[0][i][0] = s->mv[0][i][0];
+                        s->last_mv[0][i][1] = s->mv[0][i][1] * 2;
                     }
                     s->f_count++;
                 }
-                if (s->mv_dir&MV_DIR_BACKWARD){
-                    for(i=0; i<2; i++){
+                if (s->mv_dir & MV_DIR_BACKWARD) {
+                    for (i = 0; i < 2; i++) {
                         put_bits(&s->pb, 1, s->field_select[1][i]);
-                        mpeg1_encode_motion(s, s->mv[1][i][0] -  s->last_mv[1][i][0]    , s->b_code);
-                        mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code);
-                        s->last_mv[1][i][0]=   s->mv[1][i][0];
-                        s->last_mv[1][i][1]= 2*s->mv[1][i][1];
+                        mpeg1_encode_motion(s,
+                                            s->mv[1][i][0] - s->last_mv[1][i][0],
+                                            s->b_code);
+                        mpeg1_encode_motion(s,
+                                            s->mv[1][i][1] - (s->last_mv[1][i][1] >> 1),
+                                            s->b_code);
+                        s->last_mv[1][i][0] = s->mv[1][i][0];
+                        s->last_mv[1][i][1] = s->mv[1][i][1] * 2;
                     }
                     s->b_count++;
                 }
             }
             s->mv_bits += get_bits_diff(s);
-            if(cbp) {
+            if (cbp) {
                 if (s->chroma_y_shift) {
-                    put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp][1], ff_mpeg12_mbPatTable[cbp][0]);
+                    put_bits(&s->pb,
+                             ff_mpeg12_mbPatTable[cbp][1],
+                             ff_mpeg12_mbPatTable[cbp][0]);
                 } else {
-                    put_bits(&s->pb, ff_mpeg12_mbPatTable[cbp>>2][1], ff_mpeg12_mbPatTable[cbp>>2][0]);
+                    put_bits(&s->pb,
+                             ff_mpeg12_mbPatTable[cbp >> 2][1],
+                             ff_mpeg12_mbPatTable[cbp >> 2][0]);
                     put_sbits(&s->pb, 2, cbp);
                 }
             }
         }
-        for(i=0;i<mb_block_count;i++) {
-            if (cbp & (1 << (mb_block_count - 1 - i))) {
+        for (i = 0; i < mb_block_count; i++)
+            if (cbp & (1 << (mb_block_count - 1 - i)))
                 mpeg1_encode_block(s, block[i], i);
-            }
-        }
         s->mb_skip_run = 0;
-        if(s->mb_intra)
-            s->i_tex_bits+= get_bits_diff(s);
+        if (s->mb_intra)
+            s->i_tex_bits += get_bits_diff(s);
         else
-            s->p_tex_bits+= get_bits_diff(s);
+            s->p_tex_bits += get_bits_diff(s);
     }
 }
 
-void ff_mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y)
+void ff_mpeg1_encode_mb(MpegEncContext *s, int16_t block[6][64],
+                        int motion_x, int motion_y)
 {
-    if (s->chroma_format == CHROMA_420) mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6);
-    else                                mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8);
-}
-
-// RAL: Parameter added: f_or_b_code
-static void mpeg1_encode_motion(MpegEncContext *s, int val, int f_or_b_code)
-{
-    if (val == 0) {
-        /* zero vector */
-        put_bits(&s->pb,
-                 ff_mpeg12_mbMotionVectorTable[0][1],
-                 ff_mpeg12_mbMotionVectorTable[0][0]);
-    } else {
-        int code, sign, bits;
-        int bit_size = f_or_b_code - 1;
-        int range = 1 << bit_size;
-        /* modulo encoding */
-        val = sign_extend(val, 5 + bit_size);
-
-        if (val >= 0) {
-            val--;
-            code = (val >> bit_size) + 1;
-            bits = val & (range - 1);
-            sign = 0;
-        } else {
-            val = -val;
-            val--;
-            code = (val >> bit_size) + 1;
-            bits = val & (range - 1);
-            sign = 1;
-        }
-
-        assert(code > 0 && code <= 16);
-
-        put_bits(&s->pb,
-                 ff_mpeg12_mbMotionVectorTable[code][1],
-                 ff_mpeg12_mbMotionVectorTable[code][0]);
-
-        put_bits(&s->pb, 1, sign);
-        if (bit_size > 0) {
-            put_bits(&s->pb, bit_size, bits);
-        }
-    }
+    if (s->chroma_format == CHROMA_420)
+        mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 6);
+    else
+        mpeg1_encode_mb_internal(s, block, motion_x, motion_y, 8);
 }
 
-void ff_mpeg1_encode_init(MpegEncContext *s)
+av_cold void ff_mpeg1_encode_init(MpegEncContext *s)
 {
-    static int done=0;
+    static int done = 0;
 
     ff_mpeg12_common_init(s);
 
-    if(!done){
+    if (!done) {
         int f_code;
         int mv;
         int i;
 
-        done=1;
+        done = 1;
         ff_init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]);
         ff_init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]);
 
-        for(i=0; i<64; i++)
-        {
-                mpeg1_max_level[0][i]= ff_rl_mpeg1.max_level[0][i];
-                mpeg1_index_run[0][i]= ff_rl_mpeg1.index_run[0][i];
+        for (i = 0; i < 64; i++) {
+            mpeg1_max_level[0][i] = ff_rl_mpeg1.max_level[0][i];
+            mpeg1_index_run[0][i] = ff_rl_mpeg1.index_run[0][i];
         }
 
         init_uni_ac_vlc(&ff_rl_mpeg1, uni_mpeg1_ac_vlc_len);
-        if(s->intra_vlc_format)
+        if (s->intra_vlc_format)
             init_uni_ac_vlc(&ff_rl_mpeg2, uni_mpeg2_ac_vlc_len);
 
         /* build unified dc encoding tables */
-        for(i=-255; i<256; i++)
-        {
-                int adiff, index;
-                int bits, code;
-                int diff=i;
-
-                adiff = FFABS(diff);
-                if(diff<0) diff--;
-                index = av_log2(2*adiff);
-
-                bits= ff_mpeg12_vlc_dc_lum_bits[index] + index;
-                code= (ff_mpeg12_vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1));
-                mpeg1_lum_dc_uni[i+255]= bits + (code<<8);
-
-                bits= ff_mpeg12_vlc_dc_chroma_bits[index] + index;
-                code= (ff_mpeg12_vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1));
-                mpeg1_chr_dc_uni[i+255]= bits + (code<<8);
+        for (i = -255; i < 256; i++) {
+            int adiff, index;
+            int bits, code;
+            int diff = i;
+
+            adiff = FFABS(diff);
+            if (diff < 0)
+                diff--;
+            index = av_log2(2 * adiff);
+
+            bits = ff_mpeg12_vlc_dc_lum_bits[index] + index;
+            code = (ff_mpeg12_vlc_dc_lum_code[index] << index) +
+                   (diff & ((1 << index) - 1));
+            mpeg1_lum_dc_uni[i + 255] = bits + (code << 8);
+
+            bits = ff_mpeg12_vlc_dc_chroma_bits[index] + index;
+            code = (ff_mpeg12_vlc_dc_chroma_code[index] << index) +
+                   (diff & ((1 << index) - 1));
+            mpeg1_chr_dc_uni[i + 255] = bits + (code << 8);
         }
 
-        for(f_code=1; f_code<=MAX_FCODE; f_code++){
-            for(mv=-MAX_MV; mv<=MAX_MV; mv++){
+        for (f_code = 1; f_code <= MAX_FCODE; f_code++)
+            for (mv = -MAX_MV; mv <= MAX_MV; mv++) {
                 int len;
 
-                if(mv==0) len= ff_mpeg12_mbMotionVectorTable[0][1];
-                else{
+                if (mv == 0) {
+                    len = ff_mpeg12_mbMotionVectorTable[0][1];
+                } else {
                     int val, bit_size, code;
 
                     bit_size = f_code - 1;
 
-                    val=mv;
+                    val = mv;
                     if (val < 0)
                         val = -val;
                     val--;
                     code = (val >> bit_size) + 1;
-                    if(code<17){
-                        len= ff_mpeg12_mbMotionVectorTable[code][1] + 1 + bit_size;
-                    }else{
-                        len= ff_mpeg12_mbMotionVectorTable[16][1] + 2 + bit_size;
-                    }
+                    if (code < 17)
+                        len = ff_mpeg12_mbMotionVectorTable[code][1] +
+                              1 + bit_size;
+                    else
+                        len = ff_mpeg12_mbMotionVectorTable[16][1] +
+                              2 + bit_size;
                 }
 
-                mv_penalty[f_code][mv+MAX_MV]= len;
+                mv_penalty[f_code][mv + MAX_MV] = len;
             }
-        }
 
 
-        for(f_code=MAX_FCODE; f_code>0; f_code--){
-            for(mv=-(8<<f_code); mv<(8<<f_code); mv++){
-                fcode_tab[mv+MAX_MV]= f_code;
-            }
-        }
-    }
-    s->me.mv_penalty= mv_penalty;
-    s->fcode_tab= fcode_tab;
-    if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO){
-        s->min_qcoeff=-255;
-        s->max_qcoeff= 255;
-    }else{
-        s->min_qcoeff=-2047;
-        s->max_qcoeff= 2047;
+        for (f_code = MAX_FCODE; f_code > 0; f_code--)
+            for (mv = -(8 << f_code); mv < (8 << f_code); mv++)
+                fcode_tab[mv + MAX_MV] = f_code;
     }
-    if (s->intra_vlc_format) {
-        s->intra_ac_vlc_length=
-        s->intra_ac_vlc_last_length= uni_mpeg2_ac_vlc_len;
+    s->me.mv_penalty = mv_penalty;
+    s->fcode_tab     = fcode_tab;
+    if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+        s->min_qcoeff = -255;
+        s->max_qcoeff = 255;
     } else {
-        s->intra_ac_vlc_length=
-        s->intra_ac_vlc_last_length= uni_mpeg1_ac_vlc_len;
+        s->min_qcoeff = -2047;
+        s->max_qcoeff = 2047;
     }
-    s->inter_ac_vlc_length=
-    s->inter_ac_vlc_last_length= uni_mpeg1_ac_vlc_len;
-}
-
-static inline void encode_dc(MpegEncContext *s, int diff, int component)
-{
-  if(((unsigned) (diff+255)) >= 511){
-        int index;
-
-        if(diff<0){
-            index= av_log2_16bit(-2*diff);
-            diff--;
-        }else{
-            index= av_log2_16bit(2*diff);
-        }
-        if (component == 0) {
-            put_bits(
-                &s->pb,
-                ff_mpeg12_vlc_dc_lum_bits[index] + index,
-                (ff_mpeg12_vlc_dc_lum_code[index]<<index) + (diff & ((1 << index) - 1)));
-        }else{
-            put_bits(
-                &s->pb,
-                ff_mpeg12_vlc_dc_chroma_bits[index] + index,
-                (ff_mpeg12_vlc_dc_chroma_code[index]<<index) + (diff & ((1 << index) - 1)));
-        }
-  }else{
-    if (component == 0) {
-        put_bits(
-            &s->pb,
-            mpeg1_lum_dc_uni[diff+255]&0xFF,
-            mpeg1_lum_dc_uni[diff+255]>>8);
+    if (s->intra_vlc_format) {
+        s->intra_ac_vlc_length      =
+        s->intra_ac_vlc_last_length = uni_mpeg2_ac_vlc_len;
     } else {
-        put_bits(
-            &s->pb,
-            mpeg1_chr_dc_uni[diff+255]&0xFF,
-            mpeg1_chr_dc_uni[diff+255]>>8);
+        s->intra_ac_vlc_length      =
+        s->intra_ac_vlc_last_length = uni_mpeg1_ac_vlc_len;
     }
-  }
-}
-
-static void mpeg1_encode_block(MpegEncContext *s,
-                               DCTELEM *block,
-                               int n)
-{
-    int alevel, level, last_non_zero, dc, diff, i, j, run, last_index, sign;
-    int code, component;
-    const uint16_t (*table_vlc)[2] = ff_rl_mpeg1.table_vlc;
-
-    last_index = s->block_last_index[n];
-
-    /* DC coef */
-    if (s->mb_intra) {
-        component = (n <= 3 ? 0 : (n&1) + 1);
-        dc = block[0]; /* overflow is impossible */
-        diff = dc - s->last_dc[component];
-        encode_dc(s, diff, component);
-        s->last_dc[component] = dc;
-        i = 1;
-        if (s->intra_vlc_format)
-            table_vlc = ff_rl_mpeg2.table_vlc;
-    } else {
-        /* encode the first coefficient : needs to be done here because
-           it is handled slightly differently */
-        level = block[0];
-        if (abs(level) == 1) {
-                code = ((uint32_t)level >> 31); /* the sign bit */
-                put_bits(&s->pb, 2, code | 0x02);
-                i = 1;
-        } else {
-            i = 0;
-            last_non_zero = -1;
-            goto next_coef;
-        }
-    }
-
-    /* now quantify & encode AC coefs */
-    last_non_zero = i - 1;
-
-    for(;i<=last_index;i++) {
-        j = s->intra_scantable.permutated[i];
-        level = block[j];
-    next_coef:
-        /* encode using VLC */
-        if (level != 0) {
-            run = i - last_non_zero - 1;
-
-            alevel= level;
-            MASK_ABS(sign, alevel);
-            sign&=1;
-
-            if (alevel <= mpeg1_max_level[0][run]){
-                code= mpeg1_index_run[0][run] + alevel - 1;
-                /* store the vlc & sign at once */
-                put_bits(&s->pb, table_vlc[code][1]+1, (table_vlc[code][0]<<1) + sign);
-            } else {
-                /* escape seems to be pretty rare <5% so I do not optimize it */
-                put_bits(&s->pb, table_vlc[111][1], table_vlc[111][0]);
-                /* escape: only clip in this case */
-                put_bits(&s->pb, 6, run);
-                if(s->codec_id == AV_CODEC_ID_MPEG1VIDEO){
-                    if (alevel < 128) {
-                        put_sbits(&s->pb, 8, level);
-                    } else {
-                        if (level < 0) {
-                            put_bits(&s->pb, 16, 0x8001 + level + 255);
-                        } else {
-                            put_sbits(&s->pb, 16, level);
-                        }
-                    }
-                }else{
-                    put_sbits(&s->pb, 12, level);
-                }
-            }
-            last_non_zero = i;
-        }
-    }
-    /* end of block */
-    put_bits(&s->pb, table_vlc[112][1], table_vlc[112][0]);
+    s->inter_ac_vlc_length      =
+    s->inter_ac_vlc_last_length = uni_mpeg1_ac_vlc_len;
 }
 
 #define OFFSET(x) offsetof(MpegEncContext, x)
 #define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
-#define COMMON_OPTS\
-    { "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 },
+#define COMMON_OPTS                                                           \
+    { "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 },
 
 static const AVOption mpeg1_options[] = {
     COMMON_OPTS
@@ -933,18 +1046,18 @@ static const AVOption mpeg1_options[] = {
 
 static const AVOption mpeg2_options[] = {
     COMMON_OPTS
-    { "non_linear_quant",    "Use nonlinear quantizer.",          OFFSET(q_scale_type),         AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
-    { "alternate_scan",      "Enable alternate scantable.",       OFFSET(alternate_scan),       AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "non_linear_quant", "Use nonlinear quantizer.",    OFFSET(q_scale_type),   AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "alternate_scan",   "Enable alternate scantable.", OFFSET(alternate_scan), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
     FF_MPV_COMMON_OPTS
     { NULL },
 };
 
-#define mpeg12_class(x)\
-static const AVClass mpeg## x ##_class = {\
-    .class_name   = "mpeg" #x "video encoder",\
-    .item_name    = av_default_item_name,\
-    .option       = mpeg## x ##_options,\
-    .version      = LIBAVUTIL_VERSION_INT,\
+#define mpeg12_class(x)                                 \
+static const AVClass mpeg ## x ## _class = {            \
+    .class_name = "mpeg" # x "video encoder",           \
+    .item_name  = av_default_item_name,                 \
+    .option     = mpeg ## x ## _options,                \
+    .version    = LIBAVUTIL_VERSION_INT,                \
 };
 
 mpeg12_class(1)
@@ -952,6 +1065,7 @@ mpeg12_class(2)
 
 AVCodec ff_mpeg1video_encoder = {
     .name                 = "mpeg1video",
+    .long_name            = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
     .type                 = AVMEDIA_TYPE_VIDEO,
     .id                   = AV_CODEC_ID_MPEG1VIDEO,
     .priv_data_size       = sizeof(MpegEncContext),
@@ -959,15 +1073,15 @@ AVCodec ff_mpeg1video_encoder = {
     .encode2              = ff_MPV_encode_picture,
     .close                = ff_MPV_encode_end,
     .supported_framerates = ff_mpeg12_frame_rate_tab + 1,
-    .pix_fmts             = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
-                                                        AV_PIX_FMT_NONE },
+    .pix_fmts             = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
+                                                           AV_PIX_FMT_NONE },
     .capabilities         = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
-    .long_name            = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
     .priv_class           = &mpeg1_class,
 };
 
 AVCodec ff_mpeg2video_encoder = {
     .name                 = "mpeg2video",
+    .long_name            = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
     .type                 = AVMEDIA_TYPE_VIDEO,
     .id                   = AV_CODEC_ID_MPEG2VIDEO,
     .priv_data_size       = sizeof(MpegEncContext),
@@ -975,10 +1089,9 @@ AVCodec ff_mpeg2video_encoder = {
     .encode2              = ff_MPV_encode_picture,
     .close                = ff_MPV_encode_end,
     .supported_framerates = ff_mpeg12_frame_rate_tab + 1,
-    .pix_fmts             = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE
-    },
+    .pix_fmts             = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P,
+                                                           AV_PIX_FMT_YUV422P,
+                                                           AV_PIX_FMT_NONE },
     .capabilities         = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
-    .long_name            = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
     .priv_class           = &mpeg2_class,
 };
diff --git a/libavcodec/mpeg4video.c b/libavcodec/mpeg4video.c
index d7c928d..979904f 100644
--- a/libavcodec/mpeg4video.c
+++ b/libavcodec/mpeg4video.c
@@ -24,19 +24,20 @@
 #include "mpeg4video.h"
 #include "mpeg4data.h"
 
-uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3];
-
-int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s){
-    switch(s->pict_type){
-        case AV_PICTURE_TYPE_I:
-            return 16;
-        case AV_PICTURE_TYPE_P:
-        case AV_PICTURE_TYPE_S:
-            return s->f_code+15;
-        case AV_PICTURE_TYPE_B:
-            return FFMAX3(s->f_code, s->b_code, 2) + 15;
-        default:
-            return -1;
+uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3];
+
+int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s)
+{
+    switch (s->pict_type) {
+    case AV_PICTURE_TYPE_I:
+        return 16;
+    case AV_PICTURE_TYPE_P:
+    case AV_PICTURE_TYPE_S:
+        return s->f_code + 15;
+    case AV_PICTURE_TYPE_B:
+        return FFMAX3(s->f_code, s->b_code, 2) + 15;
+    default:
+        return -1;
     }
 }
 
@@ -44,70 +45,75 @@ void ff_mpeg4_clean_buffers(MpegEncContext *s)
 {
     int c_wrap, c_xy, l_wrap, l_xy;
 
-    l_wrap= s->b8_stride;
-    l_xy= (2*s->mb_y-1)*l_wrap + s->mb_x*2 - 1;
-    c_wrap= s->mb_stride;
-    c_xy= (s->mb_y-1)*c_wrap + s->mb_x - 1;
+    l_wrap = s->b8_stride;
+    l_xy   = (2 * s->mb_y - 1) * l_wrap + s->mb_x * 2 - 1;
+    c_wrap = s->mb_stride;
+    c_xy   = (s->mb_y - 1) * c_wrap + s->mb_x - 1;
 
 #if 0
     /* clean DC */
-    memsetw(s->dc_val[0] + l_xy, 1024, l_wrap*2+1);
-    memsetw(s->dc_val[1] + c_xy, 1024, c_wrap+1);
-    memsetw(s->dc_val[2] + c_xy, 1024, c_wrap+1);
+    memsetw(s->dc_val[0] + l_xy, 1024, l_wrap * 2 + 1);
+    memsetw(s->dc_val[1] + c_xy, 1024, c_wrap + 1);
+    memsetw(s->dc_val[2] + c_xy, 1024, c_wrap + 1);
 #endif
 
     /* clean AC */
-    memset(s->ac_val[0] + l_xy, 0, (l_wrap*2+1)*16*sizeof(int16_t));
-    memset(s->ac_val[1] + c_xy, 0, (c_wrap  +1)*16*sizeof(int16_t));
-    memset(s->ac_val[2] + c_xy, 0, (c_wrap  +1)*16*sizeof(int16_t));
+    memset(s->ac_val[0] + l_xy, 0, (l_wrap * 2 + 1) * 16 * sizeof(int16_t));
+    memset(s->ac_val[1] + c_xy, 0, (c_wrap     + 1) * 16 * sizeof(int16_t));
+    memset(s->ac_val[2] + c_xy, 0, (c_wrap     + 1) * 16 * sizeof(int16_t));
 
     /* clean MV */
     // we can't clear the MVs as they might be needed by a b frame
-//    memset(s->motion_val + l_xy, 0, (l_wrap*2+1)*2*sizeof(int16_t));
-//    memset(s->motion_val, 0, 2*sizeof(int16_t)*(2 + s->mb_width*2)*(2 + s->mb_height*2));
-    s->last_mv[0][0][0]=
-    s->last_mv[0][0][1]=
-    s->last_mv[1][0][0]=
-    s->last_mv[1][0][1]= 0;
+//    memset(s->motion_val + l_xy, 0, (l_wrap * 2 + 1) * 2 * sizeof(int16_t));
+//    memset(s->motion_val, 0, 2 * sizeof(int16_t) * (2 + s->mb_width * 2) *
+//           (2 + s->mb_height * 2));
+    s->last_mv[0][0][0] =
+    s->last_mv[0][0][1] =
+    s->last_mv[1][0][0] =
+    s->last_mv[1][0][1] = 0;
 }
 
 #define tab_size ((signed)FF_ARRAY_ELEMS(s->direct_scale_mv[0]))
-#define tab_bias (tab_size/2)
+#define tab_bias (tab_size / 2)
 
-//used by mpeg4 and rv10 decoder
-void ff_mpeg4_init_direct_mv(MpegEncContext *s){
+// used by mpeg4 and rv10 decoder
+void ff_mpeg4_init_direct_mv(MpegEncContext *s)
+{
     int i;
-    for(i=0; i<tab_size; i++){
-        s->direct_scale_mv[0][i] = (i-tab_bias)*s->pb_time/s->pp_time;
-        s->direct_scale_mv[1][i] = (i-tab_bias)*(s->pb_time-s->pp_time)/s->pp_time;
+    for (i = 0; i < tab_size; i++) {
+        s->direct_scale_mv[0][i] = (i - tab_bias) * s->pb_time / s->pp_time;
+        s->direct_scale_mv[1][i] = (i - tab_bias) * (s->pb_time - s->pp_time) /
+                                   s->pp_time;
     }
 }
 
-static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, int i){
-    int xy= s->block_index[i];
-    uint16_t time_pp= s->pp_time;
-    uint16_t time_pb= s->pb_time;
+static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx,
+                                              int my, int i)
+{
+    int xy           = s->block_index[i];
+    uint16_t time_pp = s->pp_time;
+    uint16_t time_pb = s->pb_time;
     int p_mx, p_my;
 
-    p_mx = s->next_picture.f.motion_val[0][xy][0];
-    if((unsigned)(p_mx + tab_bias) < tab_size){
+    p_mx = s->next_picture.motion_val[0][xy][0];
+    if ((unsigned)(p_mx + tab_bias) < tab_size) {
         s->mv[0][i][0] = s->direct_scale_mv[0][p_mx + tab_bias] + mx;
         s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx
                             : s->direct_scale_mv[1][p_mx + tab_bias];
-    }else{
-        s->mv[0][i][0] = p_mx*time_pb/time_pp + mx;
+    } else {
+        s->mv[0][i][0] = p_mx * time_pb / time_pp + mx;
         s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx
-                            : p_mx*(time_pb - time_pp)/time_pp;
+                            : p_mx * (time_pb - time_pp) / time_pp;
     }
-    p_my = s->next_picture.f.motion_val[0][xy][1];
-    if((unsigned)(p_my + tab_bias) < tab_size){
+    p_my = s->next_picture.motion_val[0][xy][1];
+    if ((unsigned)(p_my + tab_bias) < tab_size) {
         s->mv[0][i][1] = s->direct_scale_mv[0][p_my + tab_bias] + my;
         s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my
                             : s->direct_scale_mv[1][p_my + tab_bias];
-    }else{
-        s->mv[0][i][1] = p_my*time_pb/time_pp + my;
+    } else {
+        s->mv[0][i][1] = p_my * time_pb / time_pp + my;
         s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my
-                            : p_my*(time_pb - time_pp)/time_pp;
+                            : p_my * (time_pb - time_pp) / time_pp;
     }
 }
 
@@ -115,56 +121,72 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my,
 #undef tab_bias
 
 /**
- *
  * @return the mb_type
  */
-int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){
-    const int mb_index= s->mb_x + s->mb_y*s->mb_stride;
-    const int colocated_mb_type = s->next_picture.f.mb_type[mb_index];
+int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my)
+{
+    const int mb_index          = s->mb_x + s->mb_y * s->mb_stride;
+    const int colocated_mb_type = s->next_picture.mb_type[mb_index];
     uint16_t time_pp;
     uint16_t time_pb;
     int i;
 
-    //FIXME avoid divides
+    // FIXME avoid divides
     // try special case with shifts for 1 and 3 B-frames?
 
-    if(IS_8X8(colocated_mb_type)){
+    if (IS_8X8(colocated_mb_type)) {
         s->mv_type = MV_TYPE_8X8;
-        for(i=0; i<4; i++){
+        for (i = 0; i < 4; i++)
             ff_mpeg4_set_one_direct_mv(s, mx, my, i);
-        }
         return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1;
-    } else if(IS_INTERLACED(colocated_mb_type)){
+    } else if (IS_INTERLACED(colocated_mb_type)) {
         s->mv_type = MV_TYPE_FIELD;
-        for(i=0; i<2; i++){
-            int field_select = s->next_picture.f.ref_index[0][4 * mb_index + 2 * i];
-            s->field_select[0][i]= field_select;
-            s->field_select[1][i]= i;
-            if(s->top_field_first){
-                time_pp= s->pp_field_time - field_select + i;
-                time_pb= s->pb_field_time - field_select + i;
-            }else{
-                time_pp= s->pp_field_time + field_select - i;
-                time_pb= s->pb_field_time + field_select - i;
+        for (i = 0; i < 2; i++) {
+            int field_select = s->next_picture.ref_index[0][4 * mb_index + 2 * i];
+            s->field_select[0][i] = field_select;
+            s->field_select[1][i] = i;
+            if (s->top_field_first) {
+                time_pp = s->pp_field_time - field_select + i;
+                time_pb = s->pb_field_time - field_select + i;
+            } else {
+                time_pp = s->pp_field_time + field_select - i;
+                time_pb = s->pb_field_time + field_select - i;
             }
-            s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx;
-            s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1]*time_pb/time_pp + my;
-            s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->p_field_mv_table[i][0][mb_index][0]
-                                : s->p_field_mv_table[i][0][mb_index][0]*(time_pb - time_pp)/time_pp;
-            s->mv[1][i][1] = my ? s->mv[0][i][1] - s->p_field_mv_table[i][0][mb_index][1]
-                                : s->p_field_mv_table[i][0][mb_index][1]*(time_pb - time_pp)/time_pp;
+            s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0] *
+                             time_pb / time_pp + mx;
+            s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1] *
+                             time_pb / time_pp + my;
+            s->mv[1][i][0] = mx ? s->mv[0][i][0] -
+                                  s->p_field_mv_table[i][0][mb_index][0]
+                                : s->p_field_mv_table[i][0][mb_index][0] *
+                                  (time_pb - time_pp) / time_pp;
+            s->mv[1][i][1] = my ? s->mv[0][i][1] -
+                                  s->p_field_mv_table[i][0][mb_index][1]
+                                : s->p_field_mv_table[i][0][mb_index][1] *
+                                  (time_pb - time_pp) / time_pp;
         }
-        return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED;
-    }else{
+        return MB_TYPE_DIRECT2 | MB_TYPE_16x8 |
+               MB_TYPE_L0L1    | MB_TYPE_INTERLACED;
+    } else {
         ff_mpeg4_set_one_direct_mv(s, mx, my, 0);
-        s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->mv[0][0][0];
-        s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->mv[0][0][1];
-        s->mv[1][1][0] = s->mv[1][2][0] = s->mv[1][3][0] = s->mv[1][0][0];
-        s->mv[1][1][1] = s->mv[1][2][1] = s->mv[1][3][1] = s->mv[1][0][1];
-        if((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || !s->quarter_sample)
-            s->mv_type= MV_TYPE_16X16;
+        s->mv[0][1][0] =
+        s->mv[0][2][0] =
+        s->mv[0][3][0] = s->mv[0][0][0];
+        s->mv[0][1][1] =
+        s->mv[0][2][1] =
+        s->mv[0][3][1] = s->mv[0][0][1];
+        s->mv[1][1][0] =
+        s->mv[1][2][0] =
+        s->mv[1][3][0] = s->mv[1][0][0];
+        s->mv[1][1][1] =
+        s->mv[1][2][1] =
+        s->mv[1][3][1] = s->mv[1][0][1];
+        if ((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) ||
+            !s->quarter_sample)
+            s->mv_type = MV_TYPE_16X16;
         else
-            s->mv_type= MV_TYPE_8X8;
-        return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1; //Note see prev line
+            s->mv_type = MV_TYPE_8X8;
+        // Note see prev line
+        return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1;
     }
 }
diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index 64c0243..59358eb 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -24,6 +24,7 @@
 #define AVCODEC_MPEG4VIDEO_H
 
 #include <stdint.h>
+
 #include "get_bits.h"
 #include "mpegvideo.h"
 #include "rl.h"
@@ -34,13 +35,13 @@
 #define BIN_ONLY_SHAPE   2
 #define GRAY_SHAPE       3
 
-#define SIMPLE_VO_TYPE             1
-#define CORE_VO_TYPE               3
-#define MAIN_VO_TYPE               4
-#define NBIT_VO_TYPE               5
-#define ARTS_VO_TYPE               10
-#define ACE_VO_TYPE                12
-#define ADV_SIMPLE_VO_TYPE         17
+#define SIMPLE_VO_TYPE           1
+#define CORE_VO_TYPE             3
+#define MAIN_VO_TYPE             4
+#define NBIT_VO_TYPE             5
+#define ARTS_VO_TYPE            10
+#define ACE_VO_TYPE             12
+#define ADV_SIMPLE_VO_TYPE      17
 
 // aspect_ratio_info
 #define EXTENDED_PAR 15
@@ -58,11 +59,55 @@
 #define VISUAL_OBJ_STARTCODE 0x1B5
 #define VOP_STARTCODE        0x1B6
 
+typedef struct Mpeg4DecContext {
+    MpegEncContext m;
+
+    ///< number of bits to represent the fractional part of time
+    int time_increment_bits;
+    int shape;
+    int vol_sprite_usage;
+    int sprite_brightness_change;
+    int num_sprite_warping_points;
+    ///< sprite trajectory points
+    uint16_t sprite_traj[4][2];
+    ///< sprite shift [isChroma]
+    int sprite_shift[2];
+
+    // reversible vlc
+    int rvlc;
+    ///< could this stream contain resync markers
+    int resync_marker;
+    ///< time distance of first I -> B, used for interlaced b frames
+    int t_frame;
+
+    int new_pred;
+    int enhancement_type;
+    int scalability;
+    int use_intra_dc_vlc;
+    ///< QP above whch the ac VLC should be used for intra dc
+    int intra_dc_threshold;
+
+    /* bug workarounds */
+    int divx_version;
+    int divx_build;
+    int xvid_build;
+    int lavc_build;
+    ///< flag for having shown the warning about divxs invalid b frames
+    int showed_packed_warning;
+
+    int cplx_estimation_trash_i;
+    int cplx_estimation_trash_p;
+    int cplx_estimation_trash_b;
+} Mpeg4DecContext;
+
 /* dc encoding for mpeg4 */
 extern const uint8_t ff_mpeg4_DCtab_lum[13][2];
 extern const uint8_t ff_mpeg4_DCtab_chrom[13][2];
 
 extern const uint16_t ff_mpeg4_intra_vlc[103][2];
+extern const int8_t ff_mpeg4_intra_level[102];
+extern const int8_t ff_mpeg4_intra_run[102];
+
 extern RLTable ff_mpeg4_rl_intra;
 
 /* Note this is identical to the intra rvlc except that it is reordered. */
@@ -83,24 +128,25 @@ extern const uint16_t ff_mpeg4_resync_prefix[8];
 extern const uint8_t ff_mpeg4_dc_threshold[8];
 
 void ff_mpeg4_encode_mb(MpegEncContext *s,
-                        DCTELEM block[6][64],
+                        int16_t block[6][64],
                         int motion_x, int motion_y);
-void ff_mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n,
+void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n,
                       int dir);
-void ff_set_mpeg4_time(MpegEncContext * s);
+void ff_set_mpeg4_time(MpegEncContext *s);
 void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number);
 
-int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb);
+int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb);
 void ff_mpeg4_encode_video_packet_header(MpegEncContext *s);
 void ff_mpeg4_clean_buffers(MpegEncContext *s);
-void ff_mpeg4_stuffing(PutBitContext * pbc);
+void ff_mpeg4_stuffing(PutBitContext *pbc);
 void ff_mpeg4_init_partitions(MpegEncContext *s);
 void ff_mpeg4_merge_partitions(MpegEncContext *s);
 void ff_clean_mpeg4_qscales(MpegEncContext *s);
-int ff_mpeg4_decode_partitions(MpegEncContext *s);
+int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx);
 int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s);
-int ff_mpeg4_decode_video_packet_header(MpegEncContext *s);
+int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx);
 void ff_mpeg4_init_direct_mv(MpegEncContext *s);
+int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
 
 /**
  *
@@ -108,8 +154,7 @@ void ff_mpeg4_init_direct_mv(MpegEncContext *s);
  */
 int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my);
 
-extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3];
-
+extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2 * MAX_RUN + MAX_LEVEL + 3];
 
 #if 0 //3IV1 is quite rare and it slows things down a tiny bit
 #define IS_3IV1 s->codec_tag == AV_RL32("3IV1")
@@ -117,7 +162,6 @@ extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3];
 #define IS_3IV1 0
 #endif
 
-
 /**
  * Predict the dc.
  * encoding quantized level -> quantized diff
@@ -125,75 +169,81 @@ extern uint8_t ff_mpeg4_static_rl_table_store[3][2][2*MAX_RUN + MAX_LEVEL + 3];
  * @param n block index (0-3 are luma, 4-5 are chroma)
  * @param dir_ptr pointer to an integer where the prediction direction will be stored
  */
-static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding)
+static inline int ff_mpeg4_pred_dc(MpegEncContext *s, int n, int level,
+                                   int *dir_ptr, int encoding)
 {
     int a, b, c, wrap, pred, scale, ret;
     int16_t *dc_val;
 
     /* find prediction */
-    if (n < 4) {
+    if (n < 4)
         scale = s->y_dc_scale;
-    } else {
+    else
         scale = s->c_dc_scale;
-    }
-    if(IS_3IV1)
-        scale= 8;
+    if (IS_3IV1)
+        scale = 8;
 
-    wrap= s->block_wrap[n];
+    wrap   = s->block_wrap[n];
     dc_val = s->dc_val[0] + s->block_index[n];
 
     /* B C
      * A X
      */
-    a = dc_val[ - 1];
-    b = dc_val[ - 1 - wrap];
-    c = dc_val[ - wrap];
-
-    /* outside slice handling (we can't do that by memset as we need the dc for error resilience) */
-    if(s->first_slice_line && n!=3){
-        if(n!=2) b=c= 1024;
-        if(n!=1 && s->mb_x == s->resync_mb_x) b=a= 1024;
+    a = dc_val[-1];
+    b = dc_val[-1 - wrap];
+    c = dc_val[-wrap];
+
+    /* outside slice handling (we can't do that by memset as we need the
+     * dc for error resilience) */
+    if (s->first_slice_line && n != 3) {
+        if (n != 2)
+            b = c = 1024;
+        if (n != 1 && s->mb_x == s->resync_mb_x)
+            b = a = 1024;
     }
-    if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1){
-        if(n==0 || n==4 || n==5)
-            b=1024;
+    if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1) {
+        if (n == 0 || n == 4 || n == 5)
+            b = 1024;
     }
 
     if (abs(a - b) < abs(b - c)) {
-        pred = c;
+        pred     = c;
         *dir_ptr = 1; /* top */
     } else {
-        pred = a;
+        pred     = a;
         *dir_ptr = 0; /* left */
     }
     /* we assume pred is positive */
     pred = FASTDIV((pred + (scale >> 1)), scale);
 
-    if(encoding){
+    if (encoding) {
         ret = level - pred;
-    }else{
+    } else {
         level += pred;
-        ret= level;
-        if(s->err_recognition&AV_EF_BITSTREAM){
-            if(level<0){
-                av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
+        ret    = level;
+        if (s->err_recognition & AV_EF_BITSTREAM) {
+            if (level < 0) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
                 return -1;
             }
-            if(level*scale > 2048 + scale){
-                av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
+            if (level * scale > 2048 + scale) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "dc overflow at %dx%d\n", s->mb_x, s->mb_y);
                 return -1;
             }
         }
     }
-    level *=scale;
-    if(level&(~2047)){
-        if(level<0)
-            level=0;
-        else if(!(s->workaround_bugs&FF_BUG_DC_CLIP))
-            level=2047;
+    level *= scale;
+    if (level & (~2047)) {
+        if (level < 0)
+            level = 0;
+        else if (!(s->workaround_bugs & FF_BUG_DC_CLIP))
+            level = 2047;
     }
-    dc_val[0]= level;
+    dc_val[0] = level;
 
     return ret;
 }
+
 #endif /* AVCODEC_MPEG4VIDEO_H */
diff --git a/libavcodec/mpeg4video_parser.c b/libavcodec/mpeg4video_parser.c
index e291262..a5689aa 100644
--- a/libavcodec/mpeg4video_parser.c
+++ b/libavcodec/mpeg4video_parser.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "internal.h"
 #include "parser.h"
 #include "mpegvideo.h"
 #include "mpeg4video.h"
@@ -27,44 +28,45 @@
 
 struct Mp4vParseContext {
     ParseContext pc;
-    struct MpegEncContext enc;
+    Mpeg4DecContext dec_ctx;
     int first_picture;
 };
 
-int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
+int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
+{
     int vop_found, i;
     uint32_t state;
 
-    vop_found= pc->frame_start_found;
-    state= pc->state;
+    vop_found = pc->frame_start_found;
+    state     = pc->state;
 
-    i=0;
-    if(!vop_found){
-        for(i=0; i<buf_size; i++){
-            state= (state<<8) | buf[i];
-            if(state == 0x1B6){
+    i = 0;
+    if (!vop_found) {
+        for (i = 0; i < buf_size; i++) {
+            state = (state << 8) | buf[i];
+            if (state == 0x1B6) {
                 i++;
-                vop_found=1;
+                vop_found = 1;
                 break;
             }
         }
     }
 
-    if(vop_found){
+    if (vop_found) {
         /* EOF considered as end of frame */
         if (buf_size == 0)
             return 0;
-        for(; i<buf_size; i++){
-            state= (state<<8) | buf[i];
-            if((state&0xFFFFFF00) == 0x100){
-                pc->frame_start_found=0;
-                pc->state=-1;
-                return i-3;
+        for (; i < buf_size; i++) {
+            state = (state << 8) | buf[i];
+            if ((state & 0xFFFFFF00) == 0x100) {
+                pc->frame_start_found = 0;
+                pc->state             = -1;
+                return i - 3;
             }
         }
     }
-    pc->frame_start_found= vop_found;
-    pc->state= state;
+    pc->frame_start_found = vop_found;
+    pc->state             = state;
     return END_NOT_FOUND;
 }
 
@@ -74,24 +76,28 @@ static int av_mpeg4_decode_header(AVCodecParserContext *s1,
                                   const uint8_t *buf, int buf_size)
 {
     struct Mp4vParseContext *pc = s1->priv_data;
-    MpegEncContext *s = &pc->enc;
+    Mpeg4DecContext *dec_ctx = &pc->dec_ctx;
+    MpegEncContext *s = &dec_ctx->m;
     GetBitContext gb1, *gb = &gb1;
     int ret;
 
-    s->avctx = avctx;
+    s->avctx               = avctx;
     s->current_picture_ptr = &s->current_picture;
 
-    if (avctx->extradata_size && pc->first_picture){
-        init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
-        ret = ff_mpeg4_decode_picture_header(s, gb);
+    if (avctx->extradata_size && pc->first_picture) {
+        init_get_bits(gb, avctx->extradata, avctx->extradata_size * 8);
+        ret = ff_mpeg4_decode_picture_header(dec_ctx, gb);
     }
 
     init_get_bits(gb, buf, 8 * buf_size);
-    ret = ff_mpeg4_decode_picture_header(s, gb);
-    if (s->width && (!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height)) {
-        avcodec_set_dimensions(avctx, s->width, s->height);
+    ret = ff_mpeg4_decode_picture_header(dec_ctx, gb);
+    if (s->width && (!avctx->width || !avctx->height ||
+                     !avctx->coded_width || !avctx->coded_height)) {
+        ret = ff_set_dimensions(avctx, s->width, s->height);
+        if (ret < 0)
+            return ret;
     }
-    s1->pict_type= s->pict_type;
+    s1->pict_type     = s->pict_type;
     pc->first_picture = 0;
     return ret;
 }
@@ -100,38 +106,37 @@ static av_cold int mpeg4video_parse_init(AVCodecParserContext *s)
 {
     struct Mp4vParseContext *pc = s->priv_data;
 
-    pc->first_picture = 1;
-    pc->enc.slice_context_count = 1;
+    pc->first_picture           = 1;
+    pc->dec_ctx.m.slice_context_count = 1;
     return 0;
 }
 
 static int mpeg4video_parse(AVCodecParserContext *s,
-                           AVCodecContext *avctx,
-                           const uint8_t **poutbuf, int *poutbuf_size,
-                           const uint8_t *buf, int buf_size)
+                            AVCodecContext *avctx,
+                            const uint8_t **poutbuf, int *poutbuf_size,
+                            const uint8_t *buf, int buf_size)
 {
     ParseContext *pc = s->priv_data;
     int next;
 
-    if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
-        next= buf_size;
-    }else{
-        next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
+    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+        next = buf_size;
+    } else {
+        next = ff_mpeg4_find_frame_end(pc, buf, buf_size);
 
         if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
-            *poutbuf = NULL;
+            *poutbuf      = NULL;
             *poutbuf_size = 0;
             return buf_size;
         }
     }
     av_mpeg4_decode_header(s, avctx, buf, buf_size);
 
-    *poutbuf = buf;
+    *poutbuf      = buf;
     *poutbuf_size = buf_size;
     return next;
 }
 
-
 AVCodecParser ff_mpeg4video_parser = {
     .codec_ids      = { AV_CODEC_ID_MPEG4 },
     .priv_data_size = sizeof(struct Mp4vParseContext),
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 7ff290c..0e41548 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -20,29 +20,30 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "error_resilience.h"
+#include "internal.h"
 #include "mpegvideo.h"
 #include "mpeg4video.h"
 #include "h263.h"
 #include "thread.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
-// passed to get_vlc* to be increased.
+/* 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
+ * passed to get_vlc* to be increased. */
 #define SPRITE_TRAJ_VLC_BITS 6
 #define DC_VLC_BITS 9
 #define MB_TYPE_B_VLC_BITS 4
 
-
 static VLC dc_lum, dc_chrom;
 static VLC sprite_trajectory;
 static VLC mb_type_b_vlc;
 
-static const int mb_type_b_map[4]= {
+static const int mb_type_b_map[4] = {
     MB_TYPE_DIRECT2 | MB_TYPE_L0L1,
-    MB_TYPE_L0L1 | MB_TYPE_16x16,
-    MB_TYPE_L1 | MB_TYPE_16x16,
-    MB_TYPE_L0 | MB_TYPE_16x16,
+    MB_TYPE_L0L1    | MB_TYPE_16x16,
+    MB_TYPE_L1      | MB_TYPE_16x16,
+    MB_TYPE_L0      | MB_TYPE_16x16,
 };
 
 /**
@@ -50,299 +51,317 @@ static const int mb_type_b_map[4]= {
  * @param n block index (0-3 are luma, 4-5 are chroma)
  * @param dir the ac prediction direction
  */
-void ff_mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n,
-                      int dir)
+void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir)
 {
     int i;
     int16_t *ac_val, *ac_val1;
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t *const qscale_table = s->current_picture.qscale_table;
 
     /* find prediction */
-    ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+    ac_val  = s->ac_val[0][0] + s->block_index[n] * 16;
     ac_val1 = ac_val;
     if (s->ac_pred) {
         if (dir == 0) {
-            const int xy= s->mb_x-1 + s->mb_y*s->mb_stride;
+            const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride;
             /* left prediction */
             ac_val -= 16;
 
-            if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
+            if (s->mb_x == 0 || s->qscale == qscale_table[xy] ||
+                n == 1 || n == 3) {
                 /* same qscale */
-                for(i=1;i<8;i++) {
-                    block[s->dsp.idct_permutation[i<<3]] += ac_val[i];
-                }
-            }else{
+                for (i = 1; i < 8; i++)
+                    block[s->dsp.idct_permutation[i << 3]] += ac_val[i];
+            } else {
                 /* different qscale, we must rescale */
-                for(i=1;i<8;i++) {
-                    block[s->dsp.idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
-                }
+                for (i = 1; i < 8; i++)
+                    block[s->dsp.idct_permutation[i << 3]] += ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
             }
         } else {
-            const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride;
+            const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;
             /* top prediction */
             ac_val -= 16 * s->block_wrap[n];
 
-            if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
+            if (s->mb_y == 0 || s->qscale == qscale_table[xy] ||
+                n == 2 || n == 3) {
                 /* same qscale */
-                for(i=1;i<8;i++) {
+                for (i = 1; i < 8; i++)
                     block[s->dsp.idct_permutation[i]] += ac_val[i + 8];
-                }
-            }else{
+            } else {
                 /* different qscale, we must rescale */
-                for(i=1;i<8;i++) {
-                    block[s->dsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
-                }
+                for (i = 1; i < 8; i++)
+                    block[s->dsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
             }
         }
     }
     /* left copy */
-    for(i=1;i<8;i++)
-        ac_val1[i    ] = block[s->dsp.idct_permutation[i<<3]];
+    for (i = 1; i < 8; i++)
+        ac_val1[i] = block[s->dsp.idct_permutation[i << 3]];
 
     /* top copy */
-    for(i=1;i<8;i++)
-        ac_val1[8 + i] = block[s->dsp.idct_permutation[i   ]];
-
+    for (i = 1; i < 8; i++)
+        ac_val1[8 + i] = block[s->dsp.idct_permutation[i]];
 }
 
 /**
  * check if the next stuff is a resync marker or the end.
  * @return 0 if not
  */
-static inline int mpeg4_is_resync(MpegEncContext *s){
-    int bits_count= get_bits_count(&s->gb);
-    int v= show_bits(&s->gb, 16);
+static inline int mpeg4_is_resync(MpegEncContext *s)
+{
+    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)
         return 0;
-    }
 
-    while(v<=0xFF){
-        if(s->pict_type==AV_PICTURE_TYPE_B || (v>>(8-s->pict_type)!=1) || s->partitioned_frame)
+    while (v <= 0xFF) {
+        if (s->pict_type == AV_PICTURE_TYPE_B ||
+            (v >> (8 - s->pict_type) != 1) || s->partitioned_frame)
             break;
-        skip_bits(&s->gb, 8+s->pict_type);
-        bits_count+= 8+s->pict_type;
-        v= show_bits(&s->gb, 16);
+        skip_bits(&s->gb, 8 + s->pict_type);
+        bits_count += 8 + s->pict_type;
+        v = show_bits(&s->gb, 16);
     }
 
-    if(bits_count + 8 >= s->gb.size_in_bits){
-        v>>=8;
-        v|= 0x7F >> (7-(bits_count&7));
+    if (bits_count + 8 >= s->gb.size_in_bits) {
+        v >>= 8;
+        v  |= 0x7F >> (7 - (bits_count & 7));
 
-        if(v==0x7F)
+        if (v == 0x7F)
             return 1;
-    }else{
-        if(v == ff_mpeg4_resync_prefix[bits_count&7]){
+    } else {
+        if (v == ff_mpeg4_resync_prefix[bits_count & 7]) {
             int len;
-            GetBitContext gb= s->gb;
+            GetBitContext gb = s->gb;
 
             skip_bits(&s->gb, 1);
             align_get_bits(&s->gb);
 
-            for(len=0; len<32; len++){
-                if(get_bits1(&s->gb)) break;
-            }
+            for (len = 0; len < 32; len++)
+                if (get_bits1(&s->gb))
+                    break;
 
-            s->gb= gb;
+            s->gb = gb;
 
-            if(len>=ff_mpeg4_get_video_packet_prefix_length(s))
+            if (len >= ff_mpeg4_get_video_packet_prefix_length(s))
                 return 1;
         }
     }
     return 0;
 }
 
-static int mpeg4_decode_sprite_trajectory(MpegEncContext *s, GetBitContext *gb)
+static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *gb)
 {
-    int i;
-    int a= 2<<s->sprite_warping_accuracy;
-    int rho= 3-s->sprite_warping_accuracy;
-    int r=16/a;
-    const int vop_ref[4][2]= {{0,0}, {s->width,0}, {0, s->height}, {s->width, s->height}}; // only true for rectangle shapes
-    int d[4][2]={{0,0}, {0,0}, {0,0}, {0,0}};
+    MpegEncContext *s = &ctx->m;
+    int a     = 2 << s->sprite_warping_accuracy;
+    int rho   = 3  - s->sprite_warping_accuracy;
+    int r     = 16 / a;
+    int alpha = 0;
+    int beta  = 0;
+    int w     = s->width;
+    int h     = s->height;
+    int min_ab, i, w2, h2, w3, h3;
     int sprite_ref[4][2];
     int virtual_ref[2][2];
-    int w2, h2, w3, h3;
-    int alpha=0, beta=0;
-    int w= s->width;
-    int h= s->height;
-    int min_ab;
+
+    // only true for rectangle shapes
+    const int vop_ref[4][2] = { { 0, 0 },         { s->width, 0 },
+                                { 0, s->height }, { s->width, s->height } };
+    int d[4][2]             = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
 
     if (w <= 0 || h <= 0)
         return AVERROR_INVALIDDATA;
 
-    for(i=0; i<s->num_sprite_warping_points; i++){
+    for (i = 0; i < ctx->num_sprite_warping_points; i++) {
         int length;
-        int x=0, y=0;
+        int x = 0, y = 0;
 
-        length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
-        if(length){
-            x= get_xbits(gb, length);
-        }
-        if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(gb); /* marker bit */
+        length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
+        if (length)
+            x = get_xbits(gb, length);
 
-        length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
-        if(length){
-            y=get_xbits(gb, length);
-        }
-        skip_bits1(gb); /* marker bit */
-        s->sprite_traj[i][0]= d[i][0]= x;
-        s->sprite_traj[i][1]= d[i][1]= y;
+        if (!(ctx->divx_version == 500 && ctx->divx_build == 413))
+            skip_bits1(gb);     /* marker bit */
+
+        length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
+        if (length)
+            y = get_xbits(gb, length);
+
+        skip_bits1(gb);         /* marker bit */
+        ctx->sprite_traj[i][0] = d[i][0] = x;
+        ctx->sprite_traj[i][1] = d[i][1] = y;
     }
-    for(; i<4; i++)
-        s->sprite_traj[i][0]= s->sprite_traj[i][1]= 0;
-
-    while((1<<alpha)<w) alpha++;
-    while((1<<beta )<h) beta++; // there seems to be a typo in the mpeg4 std for the definition of w' and h'
-    w2= 1<<alpha;
-    h2= 1<<beta;
-
-// Note, the 4th point isn't used for GMC
-    if(s->divx_version==500 && s->divx_build==413){
-        sprite_ref[0][0]= a*vop_ref[0][0] + d[0][0];
-        sprite_ref[0][1]= a*vop_ref[0][1] + d[0][1];
-        sprite_ref[1][0]= a*vop_ref[1][0] + d[0][0] + d[1][0];
-        sprite_ref[1][1]= a*vop_ref[1][1] + d[0][1] + d[1][1];
-        sprite_ref[2][0]= a*vop_ref[2][0] + d[0][0] + d[2][0];
-        sprite_ref[2][1]= a*vop_ref[2][1] + d[0][1] + d[2][1];
+    for (; i < 4; i++)
+        ctx->sprite_traj[i][0] = ctx->sprite_traj[i][1] = 0;
+
+    while ((1 << alpha) < w)
+        alpha++;
+    while ((1 << beta) < h)
+        beta++;  /* typo in the mpeg4 std for the definition of w' and h' */
+    w2 = 1 << alpha;
+    h2 = 1 << beta;
+
+    // Note, the 4th point isn't used for GMC
+    if (ctx->divx_version == 500 && ctx->divx_build == 413) {
+        sprite_ref[0][0] = a * vop_ref[0][0] + d[0][0];
+        sprite_ref[0][1] = a * vop_ref[0][1] + d[0][1];
+        sprite_ref[1][0] = a * vop_ref[1][0] + d[0][0] + d[1][0];
+        sprite_ref[1][1] = a * vop_ref[1][1] + d[0][1] + d[1][1];
+        sprite_ref[2][0] = a * vop_ref[2][0] + d[0][0] + d[2][0];
+        sprite_ref[2][1] = a * vop_ref[2][1] + d[0][1] + d[2][1];
     } else {
-        sprite_ref[0][0]= (a>>1)*(2*vop_ref[0][0] + d[0][0]);
-        sprite_ref[0][1]= (a>>1)*(2*vop_ref[0][1] + d[0][1]);
-        sprite_ref[1][0]= (a>>1)*(2*vop_ref[1][0] + d[0][0] + d[1][0]);
-        sprite_ref[1][1]= (a>>1)*(2*vop_ref[1][1] + d[0][1] + d[1][1]);
-        sprite_ref[2][0]= (a>>1)*(2*vop_ref[2][0] + d[0][0] + d[2][0]);
-        sprite_ref[2][1]= (a>>1)*(2*vop_ref[2][1] + d[0][1] + d[2][1]);
+        sprite_ref[0][0] = (a >> 1) * (2 * vop_ref[0][0] + d[0][0]);
+        sprite_ref[0][1] = (a >> 1) * (2 * vop_ref[0][1] + d[0][1]);
+        sprite_ref[1][0] = (a >> 1) * (2 * vop_ref[1][0] + d[0][0] + d[1][0]);
+        sprite_ref[1][1] = (a >> 1) * (2 * vop_ref[1][1] + d[0][1] + d[1][1]);
+        sprite_ref[2][0] = (a >> 1) * (2 * vop_ref[2][0] + d[0][0] + d[2][0]);
+        sprite_ref[2][1] = (a >> 1) * (2 * vop_ref[2][1] + d[0][1] + d[2][1]);
     }
-/*    sprite_ref[3][0]= (a>>1)*(2*vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]);
-    sprite_ref[3][1]= (a>>1)*(2*vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */
-
-// this is mostly identical to the mpeg4 std (and is totally unreadable because of that ...)
-// perhaps it should be reordered to be more readable ...
-// the idea behind this virtual_ref mess is to be able to use shifts later per pixel instead of divides
-// so the distance between points is converted from w&h based to w2&h2 based which are of the 2^x form
-    virtual_ref[0][0]= 16*(vop_ref[0][0] + w2)
-        + ROUNDED_DIV(((w - w2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + w2*(r*sprite_ref[1][0] - 16*vop_ref[1][0])),w);
-    virtual_ref[0][1]= 16*vop_ref[0][1]
-        + ROUNDED_DIV(((w - w2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + w2*(r*sprite_ref[1][1] - 16*vop_ref[1][1])),w);
-    virtual_ref[1][0]= 16*vop_ref[0][0]
-        + ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + h2*(r*sprite_ref[2][0] - 16*vop_ref[2][0])),h);
-    virtual_ref[1][1]= 16*(vop_ref[0][1] + h2)
-        + ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + h2*(r*sprite_ref[2][1] - 16*vop_ref[2][1])),h);
-
-    switch(s->num_sprite_warping_points)
-    {
-        case 0:
-            s->sprite_offset[0][0]= 0;
-            s->sprite_offset[0][1]= 0;
-            s->sprite_offset[1][0]= 0;
-            s->sprite_offset[1][1]= 0;
-            s->sprite_delta[0][0]= a;
-            s->sprite_delta[0][1]= 0;
-            s->sprite_delta[1][0]= 0;
-            s->sprite_delta[1][1]= a;
-            s->sprite_shift[0]= 0;
-            s->sprite_shift[1]= 0;
-            break;
-        case 1: //GMC only
-            s->sprite_offset[0][0]= sprite_ref[0][0] - a*vop_ref[0][0];
-            s->sprite_offset[0][1]= sprite_ref[0][1] - a*vop_ref[0][1];
-            s->sprite_offset[1][0]= ((sprite_ref[0][0]>>1)|(sprite_ref[0][0]&1)) - a*(vop_ref[0][0]/2);
-            s->sprite_offset[1][1]= ((sprite_ref[0][1]>>1)|(sprite_ref[0][1]&1)) - a*(vop_ref[0][1]/2);
-            s->sprite_delta[0][0]= a;
-            s->sprite_delta[0][1]= 0;
-            s->sprite_delta[1][0]= 0;
-            s->sprite_delta[1][1]= a;
-            s->sprite_shift[0]= 0;
-            s->sprite_shift[1]= 0;
-            break;
-        case 2:
-            s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+rho))
-                                                  + (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][0])
-                                                  + ( r*sprite_ref[0][1] - virtual_ref[0][1])*(-vop_ref[0][1])
-                                                  + (1<<(alpha+rho-1));
-            s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+rho))
-                                                  + (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-vop_ref[0][0])
-                                                  + (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][1])
-                                                  + (1<<(alpha+rho-1));
-            s->sprite_offset[1][0]= ( (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][0] + 1)
-                                     +( r*sprite_ref[0][1] - virtual_ref[0][1])*(-2*vop_ref[0][1] + 1)
-                                     +2*w2*r*sprite_ref[0][0]
-                                     - 16*w2
-                                     + (1<<(alpha+rho+1)));
-            s->sprite_offset[1][1]= ( (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-2*vop_ref[0][0] + 1)
-                                     +(-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][1] + 1)
-                                     +2*w2*r*sprite_ref[0][1]
-                                     - 16*w2
-                                     + (1<<(alpha+rho+1)));
-            s->sprite_delta[0][0]=   (-r*sprite_ref[0][0] + virtual_ref[0][0]);
-            s->sprite_delta[0][1]=   (+r*sprite_ref[0][1] - virtual_ref[0][1]);
-            s->sprite_delta[1][0]=   (-r*sprite_ref[0][1] + virtual_ref[0][1]);
-            s->sprite_delta[1][1]=   (-r*sprite_ref[0][0] + virtual_ref[0][0]);
-
-            s->sprite_shift[0]= alpha+rho;
-            s->sprite_shift[1]= alpha+rho+2;
-            break;
-        case 3:
-            min_ab= FFMIN(alpha, beta);
-            w3= w2>>min_ab;
-            h3= h2>>min_ab;
-            s->sprite_offset[0][0]=  (sprite_ref[0][0]<<(alpha+beta+rho-min_ab))
-                                   + (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-vop_ref[0][0])
-                                   + (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-vop_ref[0][1])
-                                   + (1<<(alpha+beta+rho-min_ab-1));
-            s->sprite_offset[0][1]=  (sprite_ref[0][1]<<(alpha+beta+rho-min_ab))
-                                   + (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-vop_ref[0][0])
-                                   + (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-vop_ref[0][1])
-                                   + (1<<(alpha+beta+rho-min_ab-1));
-            s->sprite_offset[1][0]=  (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-2*vop_ref[0][0] + 1)
-                                   + (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-2*vop_ref[0][1] + 1)
-                                   + 2*w2*h3*r*sprite_ref[0][0]
-                                   - 16*w2*h3
-                                   + (1<<(alpha+beta+rho-min_ab+1));
-            s->sprite_offset[1][1]=  (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-2*vop_ref[0][0] + 1)
-                                   + (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-2*vop_ref[0][1] + 1)
-                                   + 2*w2*h3*r*sprite_ref[0][1]
-                                   - 16*w2*h3
-                                   + (1<<(alpha+beta+rho-min_ab+1));
-            s->sprite_delta[0][0]=   (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3;
-            s->sprite_delta[0][1]=   (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3;
-            s->sprite_delta[1][0]=   (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3;
-            s->sprite_delta[1][1]=   (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3;
-
-            s->sprite_shift[0]= alpha + beta + rho - min_ab;
-            s->sprite_shift[1]= alpha + beta + rho - min_ab + 2;
-            break;
+    /* sprite_ref[3][0] = (a >> 1) * (2 * vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]);
+     * sprite_ref[3][1] = (a >> 1) * (2 * vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */
+
+    /* this is mostly identical to the mpeg4 std (and is totally unreadable
+     * because of that...). Perhaps it should be reordered to be more readable.
+     * The idea behind this virtual_ref mess is to be able to use shifts later
+     * per pixel instead of divides so the distance between points is converted
+     * from w&h based to w2&h2 based which are of the 2^x form. */
+    virtual_ref[0][0] = 16 * (vop_ref[0][0] + w2) +
+                         ROUNDED_DIV(((w - w2) *
+                                      (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) +
+                                      w2 * (r * sprite_ref[1][0] - 16 * vop_ref[1][0])), w);
+    virtual_ref[0][1] = 16 * vop_ref[0][1] +
+                        ROUNDED_DIV(((w - w2) *
+                                     (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
+                                     w2 * (r * sprite_ref[1][1] - 16 * vop_ref[1][1])), w);
+    virtual_ref[1][0] = 16 * vop_ref[0][0] +
+                        ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) +
+                                     h2 * (r * sprite_ref[2][0] - 16 * vop_ref[2][0])), h);
+    virtual_ref[1][1] = 16 * (vop_ref[0][1] + h2) +
+                        ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
+                                     h2 * (r * sprite_ref[2][1] - 16 * vop_ref[2][1])), h);
+
+    switch (ctx->num_sprite_warping_points) {
+    case 0:
+        s->sprite_offset[0][0] =
+        s->sprite_offset[0][1] =
+        s->sprite_offset[1][0] =
+        s->sprite_offset[1][1] = 0;
+        s->sprite_delta[0][0]  = a;
+        s->sprite_delta[0][1]  =
+        s->sprite_delta[1][0]  = 0;
+        s->sprite_delta[1][1]  = a;
+        ctx->sprite_shift[0]   =
+        ctx->sprite_shift[1]   = 0;
+        break;
+    case 1:     // GMC only
+        s->sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0];
+        s->sprite_offset[0][1] = sprite_ref[0][1] - a * vop_ref[0][1];
+        s->sprite_offset[1][0] = ((sprite_ref[0][0] >> 1) | (sprite_ref[0][0] & 1)) -
+                                 a * (vop_ref[0][0] / 2);
+        s->sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) -
+                                 a * (vop_ref[0][1] / 2);
+        s->sprite_delta[0][0]  = a;
+        s->sprite_delta[0][1]  =
+        s->sprite_delta[1][0]  = 0;
+        s->sprite_delta[1][1]  = a;
+        ctx->sprite_shift[0]   =
+        ctx->sprite_shift[1]   = 0;
+        break;
+    case 2:
+        s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + rho)) +
+                                 (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+                                 (-vop_ref[0][0]) +
+                                 (r * sprite_ref[0][1] - virtual_ref[0][1]) *
+                                 (-vop_ref[0][1]) + (1 << (alpha + rho - 1));
+        s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + rho)) +
+                                 (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+                                 (-vop_ref[0][0]) +
+                                 (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+                                 (-vop_ref[0][1]) + (1 << (alpha + rho - 1));
+        s->sprite_offset[1][0] = ((-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+                                  (-2 * vop_ref[0][0] + 1) +
+                                  (r * sprite_ref[0][1] - virtual_ref[0][1]) *
+                                  (-2 * vop_ref[0][1] + 1) + 2 * w2 * r *
+                                  sprite_ref[0][0] - 16 * w2 + (1 << (alpha + rho + 1)));
+        s->sprite_offset[1][1] = ((-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+                                  (-2 * vop_ref[0][0] + 1) +
+                                  (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+                                  (-2 * vop_ref[0][1] + 1) + 2 * w2 * r *
+                                  sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1)));
+        s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
+        s->sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]);
+        s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]);
+        s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
+
+        ctx->sprite_shift[0]  = alpha + rho;
+        ctx->sprite_shift[1]  = alpha + rho + 2;
+        break;
+    case 3:
+        min_ab = FFMIN(alpha, beta);
+        w3     = w2 >> min_ab;
+        h3     = h2 >> min_ab;
+        s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + beta + rho - min_ab)) +
+                                 (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+                                 h3 * (-vop_ref[0][0]) +
+                                 (-r * sprite_ref[0][0] + virtual_ref[1][0]) *
+                                 w3 * (-vop_ref[0][1]) +
+                                 (1 << (alpha + beta + rho - min_ab - 1));
+        s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + beta + rho - min_ab)) +
+                                 (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+                                 h3 * (-vop_ref[0][0]) +
+                                 (-r * sprite_ref[0][1] + virtual_ref[1][1]) *
+                                 w3 * (-vop_ref[0][1]) +
+                                 (1 << (alpha + beta + rho - min_ab - 1));
+        s->sprite_offset[1][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+                                 h3 * (-2 * vop_ref[0][0] + 1) +
+                                 (-r * sprite_ref[0][0] + virtual_ref[1][0]) *
+                                 w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 *
+                                 r * sprite_ref[0][0] - 16 * w2 * h3 +
+                                 (1 << (alpha + beta + rho - min_ab + 1));
+        s->sprite_offset[1][1] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+                                 h3 * (-2 * vop_ref[0][0] + 1) +
+                                 (-r * sprite_ref[0][1] + virtual_ref[1][1]) *
+                                 w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 *
+                                 r * sprite_ref[0][1] - 16 * w2 * h3 +
+                                 (1 << (alpha + beta + rho - min_ab + 1));
+        s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3;
+        s->sprite_delta[0][1] = (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3;
+        s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3;
+        s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3;
+
+        ctx->sprite_shift[0]  = alpha + beta + rho - min_ab;
+        ctx->sprite_shift[1]  = alpha + beta + rho - min_ab + 2;
+        break;
     }
     /* try to simplify the situation */
-    if(   s->sprite_delta[0][0] == a<<s->sprite_shift[0]
-       && s->sprite_delta[0][1] == 0
-       && s->sprite_delta[1][0] == 0
-       && s->sprite_delta[1][1] == a<<s->sprite_shift[0])
-    {
-        s->sprite_offset[0][0]>>=s->sprite_shift[0];
-        s->sprite_offset[0][1]>>=s->sprite_shift[0];
-        s->sprite_offset[1][0]>>=s->sprite_shift[1];
-        s->sprite_offset[1][1]>>=s->sprite_shift[1];
-        s->sprite_delta[0][0]= a;
-        s->sprite_delta[0][1]= 0;
-        s->sprite_delta[1][0]= 0;
-        s->sprite_delta[1][1]= a;
-        s->sprite_shift[0]= 0;
-        s->sprite_shift[1]= 0;
-        s->real_sprite_warping_points=1;
-    }
-    else{
-        int shift_y= 16 - s->sprite_shift[0];
-        int shift_c= 16 - s->sprite_shift[1];
-        for(i=0; i<2; i++){
-            s->sprite_offset[0][i]<<= shift_y;
-            s->sprite_offset[1][i]<<= shift_c;
-            s->sprite_delta[0][i]<<= shift_y;
-            s->sprite_delta[1][i]<<= shift_y;
-            s->sprite_shift[i]= 16;
+    if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] &&
+        s->sprite_delta[0][1] == 0 &&
+        s->sprite_delta[1][0] == 0 &&
+        s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) {
+        s->sprite_offset[0][0] >>= ctx->sprite_shift[0];
+        s->sprite_offset[0][1] >>= ctx->sprite_shift[0];
+        s->sprite_offset[1][0] >>= ctx->sprite_shift[1];
+        s->sprite_offset[1][1] >>= ctx->sprite_shift[1];
+        s->sprite_delta[0][0] = a;
+        s->sprite_delta[0][1] = 0;
+        s->sprite_delta[1][0] = 0;
+        s->sprite_delta[1][1] = a;
+        ctx->sprite_shift[0] = 0;
+        ctx->sprite_shift[1] = 0;
+        s->real_sprite_warping_points = 1;
+    } else {
+        int shift_y = 16 - ctx->sprite_shift[0];
+        int shift_c = 16 - ctx->sprite_shift[1];
+        for (i = 0; i < 2; i++) {
+            s->sprite_offset[0][i] <<= shift_y;
+            s->sprite_offset[1][i] <<= shift_c;
+            s->sprite_delta[0][i]  <<= shift_y;
+            s->sprite_delta[1][i]  <<= shift_y;
+            ctx->sprite_shift[i]     = 16;
         }
-        s->real_sprite_warping_points= s->num_sprite_warping_points;
+        s->real_sprite_warping_points = ctx->num_sprite_warping_points;
     }
+
     return 0;
 }
 
@@ -350,96 +369,103 @@ static int mpeg4_decode_sprite_trajectory(MpegEncContext *s, GetBitContext *gb)
  * Decode the next video packet.
  * @return <0 if something went wrong
  */
-int ff_mpeg4_decode_video_packet_header(MpegEncContext *s)
+int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx)
 {
-    int mb_num_bits= av_log2(s->mb_num - 1) + 1;
-    int header_extension=0, mb_num, len;
+    MpegEncContext *s = &ctx->m;
+
+    int mb_num_bits      = av_log2(s->mb_num - 1) + 1;
+    int header_extension = 0, mb_num, len;
 
     /* is there enough space left for a video packet + header */
-    if( get_bits_count(&s->gb) > s->gb.size_in_bits-20) return -1;
+    if (get_bits_count(&s->gb) > s->gb.size_in_bits - 20)
+        return -1;
 
-    for(len=0; len<32; len++){
-        if(get_bits1(&s->gb)) break;
-    }
+    for (len = 0; len < 32; len++)
+        if (get_bits1(&s->gb))
+            break;
 
-    if(len!=ff_mpeg4_get_video_packet_prefix_length(s)){
+    if (len != ff_mpeg4_get_video_packet_prefix_length(s)) {
         av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n");
         return -1;
     }
 
-    if(s->shape != RECT_SHAPE){
-        header_extension= get_bits1(&s->gb);
-        //FIXME more stuff here
+    if (ctx->shape != RECT_SHAPE) {
+        header_extension = get_bits1(&s->gb);
+        // FIXME more stuff here
     }
 
-    mb_num= get_bits(&s->gb, mb_num_bits);
-    if(mb_num>=s->mb_num){
-        av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);
+    mb_num = get_bits(&s->gb, mb_num_bits);
+    if (mb_num >= s->mb_num) {
+        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){
+    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]]) {
+        while (s->next_picture.mbskip_table[s->mb_index2xy[mb_num]]) {
             if (!mb_x)
-                ff_thread_await_progress(&s->next_picture_ptr->f, mb_y++, 0);
+                ff_thread_await_progress(&s->next_picture_ptr->tf, mb_y++, 0);
             mb_num++;
-            if (++mb_x == s->mb_width) mb_x = 0;
+            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
+        if (mb_num >= s->mb_num)
+            return -1;  // slice contains just skipped MBs (already decoded)
     }
 
-    s->mb_x= mb_num % s->mb_width;
-    s->mb_y= mb_num / s->mb_width;
+    s->mb_x = mb_num % s->mb_width;
+    s->mb_y = mb_num / s->mb_width;
 
-    if(s->shape != BIN_ONLY_SHAPE){
-        int qscale= get_bits(&s->gb, s->quant_precision);
-        if(qscale)
-            s->chroma_qscale=s->qscale= qscale;
+    if (ctx->shape != BIN_ONLY_SHAPE) {
+        int qscale = get_bits(&s->gb, s->quant_precision);
+        if (qscale)
+            s->chroma_qscale = s->qscale = qscale;
     }
 
-    if(s->shape == RECT_SHAPE){
-        header_extension= get_bits1(&s->gb);
-    }
-    if(header_extension){
-        int time_incr=0;
+    if (ctx->shape == RECT_SHAPE)
+        header_extension = get_bits1(&s->gb);
+
+    if (header_extension) {
+        int time_incr = 0;
 
         while (get_bits1(&s->gb) != 0)
             time_incr++;
 
         check_marker(&s->gb, "before time_increment in video packed header");
-        skip_bits(&s->gb, s->time_increment_bits); /* time_increment */
+        skip_bits(&s->gb, ctx->time_increment_bits);      /* time_increment */
         check_marker(&s->gb, "before vop_coding_type in video packed header");
 
         skip_bits(&s->gb, 2); /* vop coding type */
-        //FIXME not rect stuff here
+        // FIXME not rect stuff here
 
-        if(s->shape != BIN_ONLY_SHAPE){
+        if (ctx->shape != BIN_ONLY_SHAPE) {
             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){
-                if (mpeg4_decode_sprite_trajectory(s, &s->gb) < 0)
+            // FIXME don't just ignore everything
+            if (s->pict_type == AV_PICTURE_TYPE_S &&
+                ctx->vol_sprite_usage == GMC_SPRITE) {
+                if (mpeg4_decode_sprite_trajectory(ctx, &s->gb) < 0)
                     return AVERROR_INVALIDDATA;
                 av_log(s->avctx, AV_LOG_ERROR, "untested\n");
             }
 
-            //FIXME reduced res stuff here
+            // FIXME reduced res stuff here
 
             if (s->pict_type != AV_PICTURE_TYPE_I) {
                 int f_code = get_bits(&s->gb, 3);       /* fcode_for */
-                if(f_code==0){
-                    av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (f_code=0)\n");
-                }
+                if (f_code == 0)
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "Error, video packet header damaged (f_code=0)\n");
             }
             if (s->pict_type == AV_PICTURE_TYPE_B) {
                 int b_code = get_bits(&s->gb, 3);
-                if(b_code==0){
-                    av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (b_code=0)\n");
-                }
+                if (b_code == 0)
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "Error, video packet header damaged (b_code=0)\n");
             }
         }
     }
-    //FIXME new-pred stuff
+    // FIXME new-pred stuff
 
     return 0;
 }
@@ -449,43 +475,49 @@ int ff_mpeg4_decode_video_packet_header(MpegEncContext *s)
  * @param n either 0 for the x component or 1 for y
  * @return the average MV for a GMC MB
  */
-static inline int get_amv(MpegEncContext *s, int n){
+static inline int get_amv(Mpeg4DecContext *ctx, int n)
+{
+    MpegEncContext *s = &ctx->m;
     int x, y, mb_v, sum, dx, dy, shift;
-    int len = 1 << (s->f_code + 4);
-    const int a= s->sprite_warping_accuracy;
+    int len     = 1 << (s->f_code + 4);
+    const int a = s->sprite_warping_accuracy;
 
-    if(s->workaround_bugs & FF_BUG_AMV)
+    if (s->workaround_bugs & FF_BUG_AMV)
         len >>= s->quarter_sample;
 
-    if(s->real_sprite_warping_points==1){
-        if(s->divx_version==500 && s->divx_build==413)
-            sum= s->sprite_offset[0][n] / (1<<(a - s->quarter_sample));
+    if (s->real_sprite_warping_points == 1) {
+        if (ctx->divx_version == 500 && ctx->divx_build == 413)
+            sum = s->sprite_offset[0][n] / (1 << (a - s->quarter_sample));
         else
-            sum= RSHIFT(s->sprite_offset[0][n]<<s->quarter_sample, a);
-    }else{
-        dx= s->sprite_delta[n][0];
-        dy= s->sprite_delta[n][1];
-        shift= s->sprite_shift[0];
-        if(n) dy -= 1<<(shift + a + 1);
-        else  dx -= 1<<(shift + a + 1);
-        mb_v= s->sprite_offset[0][n] + dx*s->mb_x*16 + dy*s->mb_y*16;
-
-        sum=0;
-        for(y=0; y<16; y++){
+            sum = RSHIFT(s->sprite_offset[0][n] << s->quarter_sample, a);
+    } else {
+        dx    = s->sprite_delta[n][0];
+        dy    = s->sprite_delta[n][1];
+        shift = ctx->sprite_shift[0];
+        if (n)
+            dy -= 1 << (shift + a + 1);
+        else
+            dx -= 1 << (shift + a + 1);
+        mb_v = s->sprite_offset[0][n] + dx * s->mb_x * 16 + dy * s->mb_y * 16;
+
+        sum = 0;
+        for (y = 0; y < 16; y++) {
             int v;
 
-            v= mb_v + dy*y;
-            //XXX FIXME optimize
-            for(x=0; x<16; x++){
-                sum+= v>>shift;
-                v+= dx;
+            v = mb_v + dy * y;
+            // FIXME optimize
+            for (x = 0; x < 16; x++) {
+                sum += v >> shift;
+                v   += dx;
             }
         }
-        sum= RSHIFT(sum, a+8-s->quarter_sample);
+        sum = RSHIFT(sum, a + 8 - s->quarter_sample);
     }
 
-    if      (sum < -len) sum= -len;
-    else if (sum >= len) sum= len-1;
+    if (sum < -len)
+        sum = -len;
+    else if (sum >= len)
+        sum = len - 1;
 
     return sum;
 }
@@ -496,7 +528,7 @@ static inline int get_amv(MpegEncContext *s, int n){
  * @param dir_ptr the prediction direction will be stored here
  * @return the quantized dc
  */
-static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
+static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr)
 {
     int level, code;
 
@@ -504,29 +536,31 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
         code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1);
     else
         code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1);
-    if (code < 0 || code > 9 /* && s->nbit<9 */){
+
+    if (code < 0 || code > 9 /* && s->nbit < 9 */) {
         av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
         return -1;
     }
+
     if (code == 0) {
         level = 0;
     } else {
-        if(IS_3IV1){
-            if(code==1)
-                level= 2*get_bits1(&s->gb)-1;
-            else{
-                if(get_bits1(&s->gb))
-                    level = get_bits(&s->gb, code-1) + (1<<(code-1));
+        if (IS_3IV1) {
+            if (code == 1)
+                level = 2 * get_bits1(&s->gb) - 1;
+            else {
+                if (get_bits1(&s->gb))
+                    level = get_bits(&s->gb, code - 1) + (1 << (code - 1));
                 else
-                    level = -get_bits(&s->gb, code-1) - (1<<(code-1));
+                    level = -get_bits(&s->gb, code - 1) - (1 << (code - 1));
             }
-        }else{
+        } else {
             level = get_xbits(&s->gb, code);
         }
 
-        if (code > 8){
-            if(get_bits1(&s->gb)==0){ /* marker */
-                if(s->err_recognition&AV_EF_BITSTREAM){
+        if (code > 8) {
+            if (get_bits1(&s->gb) == 0) { /* marker */
+                if (s->err_recognition & AV_EF_BITSTREAM) {
                     av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n");
                     return -1;
                 }
@@ -541,124 +575,145 @@ static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
  * Decode first partition.
  * @return number of MBs decoded or <0 if an error occurred
  */
-static int mpeg4_decode_partition_a(MpegEncContext *s){
-    int mb_num;
+static int mpeg4_decode_partition_a(Mpeg4DecContext *ctx)
+{
+    MpegEncContext *s = &ctx->m;
+    int mb_num = 0;
     static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
 
     /* decode first partition */
-    mb_num=0;
-    s->first_slice_line=1;
-    for(; s->mb_y<s->mb_height; s->mb_y++){
+    s->first_slice_line = 1;
+    for (; s->mb_y < s->mb_height; s->mb_y++) {
         ff_init_block_index(s);
-        for(; s->mb_x<s->mb_width; s->mb_x++){
-            const int xy= s->mb_x + s->mb_y*s->mb_stride;
+        for (; s->mb_x < s->mb_width; s->mb_x++) {
+            const int xy = s->mb_x + s->mb_y * s->mb_stride;
             int cbpc;
-            int dir=0;
+            int dir = 0;
 
             mb_num++;
             ff_update_block_index(s);
-            if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1)
-                s->first_slice_line=0;
+            if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1)
+                s->first_slice_line = 0;
 
-            if(s->pict_type==AV_PICTURE_TYPE_I){
+            if (s->pict_type == AV_PICTURE_TYPE_I) {
                 int i;
 
-                do{
-                    if(show_bits_long(&s->gb, 19)==DC_MARKER){
-                        return mb_num-1;
-                    }
+                do {
+                    if (show_bits_long(&s->gb, 19) == DC_MARKER)
+                        return mb_num - 1;
 
                     cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
-                    if (cbpc < 0){
-                        av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
+                    if (cbpc < 0) {
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
                         return -1;
                     }
-                }while(cbpc == 8);
+                } while (cbpc == 8);
 
-                s->cbp_table[xy]= cbpc & 3;
-                s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
-                s->mb_intra = 1;
+                s->cbp_table[xy]               = cbpc & 3;
+                s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
+                s->mb_intra                    = 1;
 
-                if(cbpc & 4) {
+                if (cbpc & 4)
                     ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
-                }
-                s->current_picture.f.qscale_table[xy]= s->qscale;
 
-                s->mbintra_table[xy]= 1;
-                for(i=0; i<6; i++){
+                s->current_picture.qscale_table[xy] = s->qscale;
+
+                s->mbintra_table[xy] = 1;
+                for (i = 0; i < 6; i++) {
                     int dc_pred_dir;
-                    int dc= mpeg4_decode_dc(s, i, &dc_pred_dir);
-                    if(dc < 0){
-                        av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
+                    int dc = mpeg4_decode_dc(s, i, &dc_pred_dir);
+                    if (dc < 0) {
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
                         return -1;
                     }
-                    dir<<=1;
-                    if(dc_pred_dir) dir|=1;
+                    dir <<= 1;
+                    if (dc_pred_dir)
+                        dir |= 1;
                 }
-                s->pred_dir_table[xy]= dir;
-            }else{ /* P/S_TYPE */
+                s->pred_dir_table[xy] = dir;
+            } else { /* P/S_TYPE */
                 int mx, my, pred_x, pred_y, bits;
-                int16_t * const mot_val = s->current_picture.f.motion_val[0][s->block_index[0]];
-                const int stride= s->b8_stride*2;
+                int16_t *const mot_val = s->current_picture.motion_val[0][s->block_index[0]];
+                const int stride       = s->b8_stride * 2;
 
 try_again:
-                bits= show_bits(&s->gb, 17);
-                if(bits==MOTION_MARKER){
-                    return mb_num-1;
-                }
+                bits = show_bits(&s->gb, 17);
+                if (bits == MOTION_MARKER)
+                    return mb_num - 1;
+
                 skip_bits1(&s->gb);
-                if(bits&0x10000){
+                if (bits & 0x10000) {
                     /* skip mb */
-                    if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
-                        s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
-                        mx= get_amv(s, 0);
-                        my= get_amv(s, 1);
-                    }else{
-                        s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
-                        mx=my=0;
+                    if (s->pict_type == AV_PICTURE_TYPE_S &&
+                        ctx->vol_sprite_usage == GMC_SPRITE) {
+                        s->current_picture.mb_type[xy] = MB_TYPE_SKIP  |
+                                                         MB_TYPE_16x16 |
+                                                         MB_TYPE_GMC   |
+                                                         MB_TYPE_L0;
+                        mx = get_amv(ctx, 0);
+                        my = get_amv(ctx, 1);
+                    } else {
+                        s->current_picture.mb_type[xy] = MB_TYPE_SKIP  |
+                                                         MB_TYPE_16x16 |
+                                                         MB_TYPE_L0;
+                        mx = my = 0;
                     }
-                    mot_val[0       ]= mot_val[2       ]=
-                    mot_val[0+stride]= mot_val[2+stride]= mx;
-                    mot_val[1       ]= mot_val[3       ]=
-                    mot_val[1+stride]= mot_val[3+stride]= my;
-
-                    if(s->mbintra_table[xy])
+                    mot_val[0]          =
+                    mot_val[2]          =
+                    mot_val[0 + stride] =
+                    mot_val[2 + stride] = mx;
+                    mot_val[1]          =
+                    mot_val[3]          =
+                    mot_val[1 + stride] =
+                    mot_val[3 + stride] = my;
+
+                    if (s->mbintra_table[xy])
                         ff_clean_intra_table_entries(s);
                     continue;
                 }
 
                 cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
-                if (cbpc < 0){
-                    av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
+                if (cbpc < 0) {
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
                     return -1;
                 }
-                if(cbpc == 20)
+                if (cbpc == 20)
                     goto try_again;
 
-                s->cbp_table[xy]= cbpc&(8+3); //8 is dquant
+                s->cbp_table[xy] = cbpc & (8 + 3);  // 8 is dquant
 
                 s->mb_intra = ((cbpc & 4) != 0);
 
-                if(s->mb_intra){
-                    s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
-                    s->mbintra_table[xy]= 1;
-                    mot_val[0       ]= mot_val[2       ]=
-                    mot_val[0+stride]= mot_val[2+stride]= 0;
-                    mot_val[1       ]= mot_val[3       ]=
-                    mot_val[1+stride]= mot_val[3+stride]= 0;
-                }else{
-                    if(s->mbintra_table[xy])
+                if (s->mb_intra) {
+                    s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
+                    s->mbintra_table[xy] = 1;
+                    mot_val[0]          =
+                    mot_val[2]          =
+                    mot_val[0 + stride] =
+                    mot_val[2 + stride] = 0;
+                    mot_val[1]          =
+                    mot_val[3]          =
+                    mot_val[1 + stride] =
+                    mot_val[3 + stride] = 0;
+                } else {
+                    if (s->mbintra_table[xy])
                         ff_clean_intra_table_entries(s);
 
-                    if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0)
-                        s->mcsel= get_bits1(&s->gb);
-                    else s->mcsel= 0;
+                    if (s->pict_type == AV_PICTURE_TYPE_S &&
+                        ctx->vol_sprite_usage == GMC_SPRITE &&
+                        (cbpc & 16) == 0)
+                        s->mcsel = get_bits1(&s->gb);
+                    else
+                        s->mcsel = 0;
 
                     if ((cbpc & 16) == 0) {
                         /* 16x16 motion prediction */
 
                         ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
-                        if(!s->mcsel){
+                        if (!s->mcsel) {
                             mx = ff_h263_decode_motion(s, pred_x, s->f_code);
                             if (mx >= 0xffff)
                                 return -1;
@@ -666,22 +721,30 @@ try_again:
                             my = ff_h263_decode_motion(s, pred_y, s->f_code);
                             if (my >= 0xffff)
                                 return -1;
-                            s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+                            s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
+                                                             MB_TYPE_L0;
                         } else {
-                            mx = get_amv(s, 0);
-                            my = get_amv(s, 1);
-                            s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
+                            mx = get_amv(ctx, 0);
+                            my = get_amv(ctx, 1);
+                            s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
+                                                             MB_TYPE_GMC   |
+                                                             MB_TYPE_L0;
                         }
 
-                        mot_val[0       ]= mot_val[2       ] =
-                        mot_val[0+stride]= mot_val[2+stride]= mx;
-                        mot_val[1       ]= mot_val[3       ]=
-                        mot_val[1+stride]= mot_val[3+stride]= my;
+                        mot_val[0]          =
+                        mot_val[2]          =
+                        mot_val[0 + stride] =
+                        mot_val[2 + stride] = mx;
+                        mot_val[1]          =
+                        mot_val[3]          =
+                        mot_val[1 + stride] =
+                        mot_val[3 + stride] = my;
                     } else {
                         int i;
-                        s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
-                        for(i=0;i<4;i++) {
-                            int16_t *mot_val= ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
+                        s->current_picture.mb_type[xy] = MB_TYPE_8x8 |
+                                                         MB_TYPE_L0;
+                        for (i = 0; i < 4; i++) {
+                            int16_t *mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
                             mx = ff_h263_decode_motion(s, pred_x, s->f_code);
                             if (mx >= 0xffff)
                                 return -1;
@@ -696,7 +759,7 @@ try_again:
                 }
             }
         }
-        s->mb_x= 0;
+        s->mb_x = 0;
     }
 
     return mb_num;
@@ -706,85 +769,91 @@ try_again:
  * decode second partition.
  * @return <0 if an error occurred
  */
-static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
-    int mb_num=0;
+static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count)
+{
+    int mb_num = 0;
     static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
 
-    s->mb_x= s->resync_mb_x;
-    s->first_slice_line=1;
-    for(s->mb_y= s->resync_mb_y; mb_num < mb_count; s->mb_y++){
+    s->mb_x = s->resync_mb_x;
+    s->first_slice_line = 1;
+    for (s->mb_y = s->resync_mb_y; mb_num < mb_count; s->mb_y++) {
         ff_init_block_index(s);
-        for(; mb_num < mb_count && s->mb_x<s->mb_width; s->mb_x++){
-            const int xy= s->mb_x + s->mb_y*s->mb_stride;
+        for (; mb_num < mb_count && s->mb_x < s->mb_width; s->mb_x++) {
+            const int xy = s->mb_x + s->mb_y * s->mb_stride;
 
             mb_num++;
             ff_update_block_index(s);
-            if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1)
-                s->first_slice_line=0;
-
-            if(s->pict_type==AV_PICTURE_TYPE_I){
-                int ac_pred= get_bits1(&s->gb);
-                int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
-                if(cbpy<0){
-                    av_log(s->avctx, AV_LOG_ERROR, "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+            if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1)
+                s->first_slice_line = 0;
+
+            if (s->pict_type == AV_PICTURE_TYPE_I) {
+                int ac_pred = get_bits1(&s->gb);
+                int cbpy    = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+                if (cbpy < 0) {
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
                     return -1;
                 }
 
-                s->cbp_table[xy]|= cbpy<<2;
-                s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
-            }else{ /* P || S_TYPE */
-                if (IS_INTRA(s->current_picture.f.mb_type[xy])) {
-                    int dir=0,i;
+                s->cbp_table[xy]               |= cbpy << 2;
+                s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED;
+            } else { /* P || S_TYPE */
+                if (IS_INTRA(s->current_picture.mb_type[xy])) {
+                    int i;
+                    int dir     = 0;
                     int ac_pred = get_bits1(&s->gb);
-                    int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+                    int cbpy    = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
 
-                    if(cbpy<0){
-                        av_log(s->avctx, AV_LOG_ERROR, "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+                    if (cbpy < 0) {
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
                         return -1;
                     }
 
-                    if(s->cbp_table[xy] & 8) {
+                    if (s->cbp_table[xy] & 8)
                         ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
-                    }
-                    s->current_picture.f.qscale_table[xy] = s->qscale;
+                    s->current_picture.qscale_table[xy] = s->qscale;
 
-                    for(i=0; i<6; i++){
+                    for (i = 0; i < 6; i++) {
                         int dc_pred_dir;
-                        int dc= mpeg4_decode_dc(s, i, &dc_pred_dir);
-                        if(dc < 0){
-                            av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
+                        int dc = mpeg4_decode_dc(s, i, &dc_pred_dir);
+                        if (dc < 0) {
+                            av_log(s->avctx, AV_LOG_ERROR,
+                                   "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
                             return -1;
                         }
-                        dir<<=1;
-                        if(dc_pred_dir) dir|=1;
+                        dir <<= 1;
+                        if (dc_pred_dir)
+                            dir |= 1;
                     }
-                    s->cbp_table[xy]&= 3; //remove dquant
-                    s->cbp_table[xy]|= cbpy<<2;
-                    s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
-                    s->pred_dir_table[xy]= dir;
-                } else if (IS_SKIP(s->current_picture.f.mb_type[xy])) {
-                    s->current_picture.f.qscale_table[xy] = s->qscale;
-                    s->cbp_table[xy]= 0;
-                }else{
+                    s->cbp_table[xy]               &= 3;  // remove dquant
+                    s->cbp_table[xy]               |= cbpy << 2;
+                    s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED;
+                    s->pred_dir_table[xy]           = dir;
+                } else if (IS_SKIP(s->current_picture.mb_type[xy])) {
+                    s->current_picture.qscale_table[xy] = s->qscale;
+                    s->cbp_table[xy]                    = 0;
+                } else {
                     int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
 
-                    if(cbpy<0){
-                        av_log(s->avctx, AV_LOG_ERROR, "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+                    if (cbpy < 0) {
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
                         return -1;
                     }
 
-                    if(s->cbp_table[xy] & 8) {
+                    if (s->cbp_table[xy] & 8)
                         ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
-                    }
-                    s->current_picture.f.qscale_table[xy] = s->qscale;
+                    s->current_picture.qscale_table[xy] = s->qscale;
 
-                    s->cbp_table[xy]&= 3; //remove dquant
-                    s->cbp_table[xy]|= (cbpy^0xf)<<2;
+                    s->cbp_table[xy] &= 3;  // remove dquant
+                    s->cbp_table[xy] |= (cbpy ^ 0xf) << 2;
                 }
             }
         }
-        if(mb_num >= mb_count) return 0;
-        s->mb_x= 0;
+        if (mb_num >= mb_count)
+            return 0;
+        s->mb_x = 0;
     }
     return 0;
 }
@@ -793,50 +862,60 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
  * Decode the first and second partition.
  * @return <0 if error (and sets error type in the error_status_table)
  */
-int ff_mpeg4_decode_partitions(MpegEncContext *s)
+int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx)
 {
+    MpegEncContext *s = &ctx->m;
     int mb_num;
-    const int part_a_error= s->pict_type==AV_PICTURE_TYPE_I ? (ER_DC_ERROR|ER_MV_ERROR) : ER_MV_ERROR;
-    const int part_a_end  = s->pict_type==AV_PICTURE_TYPE_I ? (ER_DC_END  |ER_MV_END)   : ER_MV_END;
+    const int part_a_error = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_ERROR | ER_MV_ERROR) : ER_MV_ERROR;
+    const int part_a_end   = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_END   | ER_MV_END)   : ER_MV_END;
 
-    mb_num= mpeg4_decode_partition_a(s);
-    if(mb_num<0){
-        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
+    mb_num = mpeg4_decode_partition_a(ctx);
+    if (mb_num < 0) {
+        ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                        s->mb_x, s->mb_y, part_a_error);
         return -1;
     }
 
-    if(s->resync_mb_x + s->resync_mb_y*s->mb_width + mb_num > s->mb_num){
+    if (s->resync_mb_x + s->resync_mb_y * s->mb_width + mb_num > s->mb_num) {
         av_log(s->avctx, AV_LOG_ERROR, "slice below monitor ...\n");
-        ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error);
+        ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                        s->mb_x, s->mb_y, part_a_error);
         return -1;
     }
 
-    s->mb_num_left= mb_num;
+    s->mb_num_left = mb_num;
 
-    if(s->pict_type==AV_PICTURE_TYPE_I){
-        while(show_bits(&s->gb, 9) == 1)
+    if (s->pict_type == AV_PICTURE_TYPE_I) {
+        while (show_bits(&s->gb, 9) == 1)
             skip_bits(&s->gb, 9);
-        if(get_bits_long(&s->gb, 19)!=DC_MARKER){
-            av_log(s->avctx, AV_LOG_ERROR, "marker missing after first I partition at %d %d\n", s->mb_x, s->mb_y);
+        if (get_bits_long(&s->gb, 19) != DC_MARKER) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "marker missing after first I partition at %d %d\n",
+                   s->mb_x, s->mb_y);
             return -1;
         }
-    }else{
-        while(show_bits(&s->gb, 10) == 1)
+    } else {
+        while (show_bits(&s->gb, 10) == 1)
             skip_bits(&s->gb, 10);
-        if(get_bits(&s->gb, 17)!=MOTION_MARKER){
-            av_log(s->avctx, AV_LOG_ERROR, "marker missing after first P partition at %d %d\n", s->mb_x, s->mb_y);
+        if (get_bits(&s->gb, 17) != MOTION_MARKER) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "marker missing after first P partition at %d %d\n",
+                   s->mb_x, s->mb_y);
             return -1;
         }
     }
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, part_a_end);
+    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                    s->mb_x - 1, s->mb_y, part_a_end);
 
-    if( mpeg4_decode_partition_b(s, mb_num) < 0){
-        if(s->pict_type==AV_PICTURE_TYPE_P)
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_DC_ERROR);
+    if (mpeg4_decode_partition_b(s, mb_num) < 0) {
+        if (s->pict_type == AV_PICTURE_TYPE_P)
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                            s->mb_x, s->mb_y, ER_DC_ERROR);
         return -1;
-    }else{
-        if(s->pict_type==AV_PICTURE_TYPE_P)
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_DC_END);
+    } else {
+        if (s->pict_type == AV_PICTURE_TYPE_P)
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+                            s->mb_x - 1, s->mb_y, ER_DC_END);
     }
 
     return 0;
@@ -846,221 +925,242 @@ int ff_mpeg4_decode_partitions(MpegEncContext *s)
  * Decode a block.
  * @return <0 if an error occurred
  */
-static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
-                              int n, int coded, int intra, int rvlc)
+static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
+                                     int n, int coded, int intra, int rvlc)
 {
-    int level, i, last, run;
-    int dc_pred_dir;
-    RLTable * rl;
-    RL_VLC_ELEM * rl_vlc;
-    const uint8_t * scan_table;
-    int qmul, qadd;
-
-    //Note intra & rvlc should be optimized away if this is inlined
-
-    if(intra) {
-      if(s->use_intra_dc_vlc){
-        /* DC coef */
-        if(s->partitioned_frame){
-            level = s->dc_val[0][ s->block_index[n] ];
-            if(n<4) level= FASTDIV((level + (s->y_dc_scale>>1)), s->y_dc_scale);
-            else    level= FASTDIV((level + (s->c_dc_scale>>1)), s->c_dc_scale);
-            dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_stride]<<n)&32;
-        }else{
-            level = mpeg4_decode_dc(s, n, &dc_pred_dir);
-            if (level < 0)
-                return -1;
-        }
-        block[0] = level;
-        i = 0;
-      }else{
+    MpegEncContext *s = &ctx->m;
+    int level, i, last, run, qmul, qadd, dc_pred_dir;
+    RLTable *rl;
+    RL_VLC_ELEM *rl_vlc;
+    const uint8_t *scan_table;
+
+    // Note intra & rvlc should be optimized away if this is inlined
+
+    if (intra) {
+        if (ctx->use_intra_dc_vlc) {
+            /* DC coef */
+            if (s->partitioned_frame) {
+                level = s->dc_val[0][s->block_index[n]];
+                if (n < 4)
+                    level = FASTDIV((level + (s->y_dc_scale >> 1)), s->y_dc_scale);
+                else
+                    level = FASTDIV((level + (s->c_dc_scale >> 1)), s->c_dc_scale);
+                dc_pred_dir = (s->pred_dir_table[s->mb_x + s->mb_y * s->mb_stride] << n) & 32;
+            } else {
+                level = mpeg4_decode_dc(s, n, &dc_pred_dir);
+                if (level < 0)
+                    return -1;
+            }
+            block[0] = level;
+            i        = 0;
+        } else {
             i = -1;
             ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0);
-      }
-      if (!coded)
-          goto not_coded;
-
-      if(rvlc){
-          rl = &ff_rvlc_rl_intra;
-          rl_vlc = ff_rvlc_rl_intra.rl_vlc[0];
-      }else{
-          rl = &ff_mpeg4_rl_intra;
-          rl_vlc = ff_mpeg4_rl_intra.rl_vlc[0];
-      }
-      if (s->ac_pred) {
-          if (dc_pred_dir == 0)
-              scan_table = s->intra_v_scantable.permutated; /* left */
-          else
-              scan_table = s->intra_h_scantable.permutated; /* top */
-      } else {
+        }
+        if (!coded)
+            goto not_coded;
+
+        if (rvlc) {
+            rl     = &ff_rvlc_rl_intra;
+            rl_vlc = ff_rvlc_rl_intra.rl_vlc[0];
+        } else {
+            rl     = &ff_mpeg4_rl_intra;
+            rl_vlc = ff_mpeg4_rl_intra.rl_vlc[0];
+        }
+        if (s->ac_pred) {
+            if (dc_pred_dir == 0)
+                scan_table = s->intra_v_scantable.permutated;  /* left */
+            else
+                scan_table = s->intra_h_scantable.permutated;  /* top */
+        } else {
             scan_table = s->intra_scantable.permutated;
-      }
-      qmul=1;
-      qadd=0;
+        }
+        qmul = 1;
+        qadd = 0;
     } else {
         i = -1;
         if (!coded) {
             s->block_last_index[n] = i;
             return 0;
         }
-        if(rvlc) rl = &ff_rvlc_rl_inter;
-        else     rl = &ff_h263_rl_inter;
+        if (rvlc)
+            rl = &ff_rvlc_rl_inter;
+        else
+            rl = &ff_h263_rl_inter;
 
         scan_table = s->intra_scantable.permutated;
 
-        if(s->mpeg_quant){
-            qmul=1;
-            qadd=0;
-            if(rvlc){
+        if (s->mpeg_quant) {
+            qmul = 1;
+            qadd = 0;
+            if (rvlc)
                 rl_vlc = ff_rvlc_rl_inter.rl_vlc[0];
-            }else{
+            else
                 rl_vlc = ff_h263_rl_inter.rl_vlc[0];
-            }
-        }else{
+        } else {
             qmul = s->qscale << 1;
             qadd = (s->qscale - 1) | 1;
-            if(rvlc){
+            if (rvlc)
                 rl_vlc = ff_rvlc_rl_inter.rl_vlc[s->qscale];
-            }else{
+            else
                 rl_vlc = ff_h263_rl_inter.rl_vlc[s->qscale];
-            }
         }
     }
-  {
-    OPEN_READER(re, &s->gb);
-    for(;;) {
-        UPDATE_CACHE(re, &s->gb);
-        GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
-        if (level==0) {
-          /* escape */
-          if(rvlc){
-                if(SHOW_UBITS(re, &s->gb, 1)==0){
-                    av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in rvlc esc\n");
-                    return -1;
-                }; SKIP_CACHE(re, &s->gb, 1);
-
-                last=  SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
-                run=   SHOW_UBITS(re, &s->gb, 6);
-                SKIP_COUNTER(re, &s->gb, 1+1+6);
-                UPDATE_CACHE(re, &s->gb);
-
-                if(SHOW_UBITS(re, &s->gb, 1)==0){
-                    av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in rvlc esc\n");
-                    return -1;
-                }; SKIP_CACHE(re, &s->gb, 1);
-
-                level= SHOW_UBITS(re, &s->gb, 11); SKIP_CACHE(re, &s->gb, 11);
-
-                if(SHOW_UBITS(re, &s->gb, 5)!=0x10){
-                    av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n");
-                    return -1;
-                }; SKIP_CACHE(re, &s->gb, 5);
+    {
+        OPEN_READER(re, &s->gb);
+        for (;;) {
+            UPDATE_CACHE(re, &s->gb);
+            GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
+            if (level == 0) {
+                /* escape */
+                if (rvlc) {
+                    if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "1. marker bit missing in rvlc esc\n");
+                        return -1;
+                    }
+                    SKIP_CACHE(re, &s->gb, 1);
 
-                level=  level * qmul + qadd;
-                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                SKIP_COUNTER(re, &s->gb, 1+11+5+1);
-
-                i+= run + 1;
-                if(last) i+=192;
-          }else{
-            int cache;
-            cache= GET_CACHE(re, &s->gb);
-
-            if(IS_3IV1)
-                cache ^= 0xC0000000;
-
-            if (cache&0x80000000) {
-                if (cache&0x40000000) {
-                    /* third escape */
-                    SKIP_CACHE(re, &s->gb, 2);
-                    last=  SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
-                    run=   SHOW_UBITS(re, &s->gb, 6);
-                    SKIP_COUNTER(re, &s->gb, 2+1+6);
+                    last = SHOW_UBITS(re, &s->gb, 1);
+                    SKIP_CACHE(re, &s->gb, 1);
+                    run = SHOW_UBITS(re, &s->gb, 6);
+                    SKIP_COUNTER(re, &s->gb, 1 + 1 + 6);
                     UPDATE_CACHE(re, &s->gb);
 
-                    if(IS_3IV1){
-                        level= SHOW_SBITS(re, &s->gb, 12); LAST_SKIP_BITS(re, &s->gb, 12);
-                    }else{
-                        if(SHOW_UBITS(re, &s->gb, 1)==0){
-                            av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in 3. esc\n");
-                            return -1;
-                        }; SKIP_CACHE(re, &s->gb, 1);
-
-                        level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12);
+                    if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+                        av_log(s->avctx, AV_LOG_ERROR,
+                               "2. marker bit missing in rvlc esc\n");
+                        return -1;
+                    }
+                    SKIP_CACHE(re, &s->gb, 1);
 
-                        if(SHOW_UBITS(re, &s->gb, 1)==0){
-                            av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in 3. esc\n");
-                            return -1;
-                        }
+                    level = SHOW_UBITS(re, &s->gb, 11);
+                    SKIP_CACHE(re, &s->gb, 11);
 
-                        SKIP_COUNTER(re, &s->gb, 1+12+1);
+                    if (SHOW_UBITS(re, &s->gb, 5) != 0x10) {
+                        av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n");
+                        return -1;
                     }
+                    SKIP_CACHE(re, &s->gb, 5);
 
-                    if (level>0) level= level * qmul + qadd;
-                    else         level= level * qmul - qadd;
+                    level = level * qmul + qadd;
+                    level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                    SKIP_COUNTER(re, &s->gb, 1 + 11 + 5 + 1);
 
-                    if((unsigned)(level + 2048) > 4095){
-                        if(s->err_recognition & AV_EF_BITSTREAM){
-                            if(level > 2560 || level<-2560){
-                                av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale);
-                                return -1;
+                    i += run + 1;
+                    if (last)
+                        i += 192;
+                } else {
+                    int cache;
+                    cache = GET_CACHE(re, &s->gb);
+
+                    if (IS_3IV1)
+                        cache ^= 0xC0000000;
+
+                    if (cache & 0x80000000) {
+                        if (cache & 0x40000000) {
+                            /* third escape */
+                            SKIP_CACHE(re, &s->gb, 2);
+                            last = SHOW_UBITS(re, &s->gb, 1);
+                            SKIP_CACHE(re, &s->gb, 1);
+                            run = SHOW_UBITS(re, &s->gb, 6);
+                            SKIP_COUNTER(re, &s->gb, 2 + 1 + 6);
+                            UPDATE_CACHE(re, &s->gb);
+
+                            if (IS_3IV1) {
+                                level = SHOW_SBITS(re, &s->gb, 12);
+                                LAST_SKIP_BITS(re, &s->gb, 12);
+                            } else {
+                                if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+                                    av_log(s->avctx, AV_LOG_ERROR,
+                                           "1. marker bit missing in 3. esc\n");
+                                    return -1;
+                                }
+                                SKIP_CACHE(re, &s->gb, 1);
+
+                                level = SHOW_SBITS(re, &s->gb, 12);
+                                SKIP_CACHE(re, &s->gb, 12);
+
+                                if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+                                    av_log(s->avctx, AV_LOG_ERROR,
+                                           "2. marker bit missing in 3. esc\n");
+                                    return -1;
+                                }
+
+                                SKIP_COUNTER(re, &s->gb, 1 + 12 + 1);
                             }
+
+                            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 (level > 2560 || level < -2560) {
+                                        av_log(s->avctx, AV_LOG_ERROR,
+                                               "|level| overflow in 3. esc, qp=%d\n",
+                                               s->qscale);
+                                        return -1;
+                                    }
+                                }
+                                level = level < 0 ? -2048 : 2047;
+                            }
+
+                            i += run + 1;
+                            if (last)
+                                i += 192;
+                        } else {
+                            /* second escape */
+                            SKIP_BITS(re, &s->gb, 2);
+                            GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+                            i    += run + rl->max_run[run >> 7][level / qmul] + 1;  // FIXME opt indexing
+                            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                            LAST_SKIP_BITS(re, &s->gb, 1);
                         }
-                        level= level<0 ? -2048 : 2047;
+                    } else {
+                        /* first escape */
+                        SKIP_BITS(re, &s->gb, 1);
+                        GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+                        i    += run;
+                        level = level + rl->max_level[run >> 7][(run - 1) & 63] * qmul;  // FIXME opt indexing
+                        level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                        LAST_SKIP_BITS(re, &s->gb, 1);
                     }
-
-                    i+= run + 1;
-                    if(last) i+=192;
-                } else {
-                    /* second escape */
-                    SKIP_BITS(re, &s->gb, 2);
-                    GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
-                    i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing
-                    level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                    LAST_SKIP_BITS(re, &s->gb, 1);
                 }
             } else {
-                /* first escape */
-                SKIP_BITS(re, &s->gb, 1);
-                GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
-                i+= run;
-                level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
+                i    += run;
                 level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
                 LAST_SKIP_BITS(re, &s->gb, 1);
             }
-          }
-        } else {
-            i+= run;
-            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-            LAST_SKIP_BITS(re, &s->gb, 1);
-        }
-        if (i > 62){
-            i-= 192;
-            if(i&(~63)){
-                av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
-                return -1;
+            if (i > 62) {
+                i -= 192;
+                if (i & (~63)) {
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                    return -1;
+                }
+
+                block[scan_table[i]] = level;
+                break;
             }
 
             block[scan_table[i]] = level;
-            break;
         }
-
-        block[scan_table[i]] = level;
+        CLOSE_READER(re, &s->gb);
     }
-    CLOSE_READER(re, &s->gb);
-  }
- not_coded:
+
+not_coded:
     if (intra) {
-        if(!s->use_intra_dc_vlc){
+        if (!ctx->use_intra_dc_vlc) {
             block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0);
 
-            i -= i>>31; //if(i == -1) i=0;
+            i -= i >> 31;  // if (i == -1) i = 0;
         }
 
         ff_mpeg4_pred_ac(s, block, n, dc_pred_dir);
-        if (s->ac_pred) {
-            i = 63; /* XXX: not optimal */
-        }
+        if (s->ac_pred)
+            i = 63;  // FIXME not optimal
     }
     s->block_last_index[n] = i;
     return 0;
@@ -1070,45 +1170,47 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
  * decode partition C of one MB.
  * @return <0 if an error occurred
  */
-static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64])
+static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64])
 {
+    Mpeg4DecContext *ctx = (Mpeg4DecContext *)s;
     int cbp, mb_type;
-    const int xy= s->mb_x + s->mb_y*s->mb_stride;
+    const int xy = s->mb_x + s->mb_y * s->mb_stride;
 
-    mb_type = s->current_picture.f.mb_type[xy];
-    cbp = s->cbp_table[xy];
+    mb_type = s->current_picture.mb_type[xy];
+    cbp     = s->cbp_table[xy];
 
-    s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold;
+    ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
 
-    if (s->current_picture.f.qscale_table[xy] != s->qscale) {
-        ff_set_qscale(s, s->current_picture.f.qscale_table[xy]);
-    }
+    if (s->current_picture.qscale_table[xy] != s->qscale)
+        ff_set_qscale(s, s->current_picture.qscale_table[xy]);
 
-    if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
+    if (s->pict_type == AV_PICTURE_TYPE_P ||
+        s->pict_type == AV_PICTURE_TYPE_S) {
         int i;
-        for(i=0; i<4; i++){
-            s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
-            s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
+        for (i = 0; i < 4; i++) {
+            s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
+            s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
         }
         s->mb_intra = IS_INTRA(mb_type);
 
         if (IS_SKIP(mb_type)) {
             /* skip mb */
-            for(i=0;i<6;i++)
+            for (i = 0; i < 6; i++)
                 s->block_last_index[i] = -1;
-            s->mv_dir = MV_DIR_FORWARD;
+            s->mv_dir  = MV_DIR_FORWARD;
             s->mv_type = MV_TYPE_16X16;
-            if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
-                s->mcsel=1;
+            if (s->pict_type == AV_PICTURE_TYPE_S
+                && ctx->vol_sprite_usage == GMC_SPRITE) {
+                s->mcsel      = 1;
                 s->mb_skipped = 0;
-            }else{
-                s->mcsel=0;
+            } else {
+                s->mcsel      = 0;
                 s->mb_skipped = 1;
             }
-        }else if(s->mb_intra){
-            s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]);
-        }else if(!s->mb_intra){
-//            s->mcsel= 0; //FIXME do we need to init that
+        } else if (s->mb_intra) {
+            s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
+        } else if (!s->mb_intra) {
+            // s->mcsel = 0;  // FIXME do we need to init that?
 
             s->mv_dir = MV_DIR_FORWARD;
             if (IS_8X8(mb_type)) {
@@ -1119,7 +1221,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64])
         }
     } else { /* I-Frame */
         s->mb_intra = 1;
-        s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]);
+        s->ac_pred  = IS_ACPRED(s->current_picture.mb_type[xy]);
     }
 
     if (!IS_SKIP(mb_type)) {
@@ -1127,124 +1229,139 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64])
         s->dsp.clear_blocks(s->block[0]);
         /* decode each block */
         for (i = 0; i < 6; i++) {
-            if(mpeg4_decode_block(s, block[i], i, cbp&32, s->mb_intra, s->rvlc) < 0){
-                av_log(s->avctx, AV_LOG_ERROR, "texture corrupted at %d %d %d\n", s->mb_x, s->mb_y, s->mb_intra);
+            if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, s->mb_intra, ctx->rvlc) < 0) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "texture corrupted at %d %d %d\n",
+                       s->mb_x, s->mb_y, s->mb_intra);
                 return -1;
             }
-            cbp+=cbp;
+            cbp += cbp;
         }
     }
 
     /* per-MB end of slice check */
-
-    if(--s->mb_num_left <= 0){
-        if(mpeg4_is_resync(s))
+    if (--s->mb_num_left <= 0) {
+        if (mpeg4_is_resync(s))
             return SLICE_END;
         else
             return SLICE_NOEND;
-    }else{
-        if(mpeg4_is_resync(s)){
-            const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
-            if(s->cbp_table[xy+delta])
+    } else {
+        if (mpeg4_is_resync(s)) {
+            const int delta = s->mb_x + 1 == s->mb_width ? 2 : 1;
+            if (s->cbp_table[xy + delta])
                 return SLICE_END;
         }
         return SLICE_OK;
     }
 }
 
-static int mpeg4_decode_mb(MpegEncContext *s,
-                      DCTELEM block[6][64])
+static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
+    Mpeg4DecContext *ctx = (Mpeg4DecContext *)s;
     int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
     int16_t *mot_val;
     static int8_t quant_tab[4] = { -1, -2, 1, 2 };
-    const int xy= s->mb_x + s->mb_y * s->mb_stride;
+    const int xy = s->mb_x + s->mb_y * s->mb_stride;
 
     assert(s->h263_pred);
 
-    if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
-        do{
+    if (s->pict_type == AV_PICTURE_TYPE_P ||
+        s->pict_type == AV_PICTURE_TYPE_S) {
+        do {
             if (get_bits1(&s->gb)) {
                 /* skip mb */
                 s->mb_intra = 0;
-                for(i=0;i<6;i++)
+                for (i = 0; i < 6; i++)
                     s->block_last_index[i] = -1;
-                s->mv_dir = MV_DIR_FORWARD;
+                s->mv_dir  = MV_DIR_FORWARD;
                 s->mv_type = MV_TYPE_16X16;
-                if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
-                    s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
-                    s->mcsel=1;
-                    s->mv[0][0][0]= get_amv(s, 0);
-                    s->mv[0][0][1]= get_amv(s, 1);
-
-                    s->mb_skipped = 0;
-                }else{
-                    s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
-                    s->mcsel=0;
+                if (s->pict_type == AV_PICTURE_TYPE_S &&
+                    ctx->vol_sprite_usage == GMC_SPRITE) {
+                    s->current_picture.mb_type[xy] = MB_TYPE_SKIP  |
+                                                     MB_TYPE_GMC   |
+                                                     MB_TYPE_16x16 |
+                                                     MB_TYPE_L0;
+                    s->mcsel       = 1;
+                    s->mv[0][0][0] = get_amv(ctx, 0);
+                    s->mv[0][0][1] = get_amv(ctx, 1);
+                    s->mb_skipped  = 0;
+                } else {
+                    s->current_picture.mb_type[xy] = MB_TYPE_SKIP  |
+                                                     MB_TYPE_16x16 |
+                                                     MB_TYPE_L0;
+                    s->mcsel       = 0;
                     s->mv[0][0][0] = 0;
                     s->mv[0][0][1] = 0;
-                    s->mb_skipped = 1;
+                    s->mb_skipped  = 1;
                 }
                 goto end;
             }
             cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
-            if (cbpc < 0){
-                av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
+            if (cbpc < 0) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
                 return -1;
             }
-        }while(cbpc == 20);
+        } while (cbpc == 20);
 
         s->dsp.clear_blocks(s->block[0]);
-        dquant = cbpc & 8;
+        dquant      = cbpc & 8;
         s->mb_intra = ((cbpc & 4) != 0);
-        if (s->mb_intra) goto intra;
+        if (s->mb_intra)
+            goto intra;
 
-        if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0)
-            s->mcsel= get_bits1(&s->gb);
-        else s->mcsel= 0;
+        if (s->pict_type == AV_PICTURE_TYPE_S &&
+            ctx->vol_sprite_usage == GMC_SPRITE && (cbpc & 16) == 0)
+            s->mcsel = get_bits1(&s->gb);
+        else
+            s->mcsel = 0;
         cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F;
 
         cbp = (cbpc & 3) | (cbpy << 2);
-        if (dquant) {
+        if (dquant)
             ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
-        }
-        if((!s->progressive_sequence) && (cbp || (s->workaround_bugs&FF_BUG_XVID_ILACE)))
-            s->interlaced_dct= get_bits1(&s->gb);
+        if ((!s->progressive_sequence) &&
+            (cbp || (s->workaround_bugs & FF_BUG_XVID_ILACE)))
+            s->interlaced_dct = get_bits1(&s->gb);
 
         s->mv_dir = MV_DIR_FORWARD;
         if ((cbpc & 16) == 0) {
-            if(s->mcsel){
-                s->current_picture.f.mb_type[xy] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
+            if (s->mcsel) {
+                s->current_picture.mb_type[xy] = MB_TYPE_GMC   |
+                                                 MB_TYPE_16x16 |
+                                                 MB_TYPE_L0;
                 /* 16x16 global motion prediction */
-                s->mv_type = MV_TYPE_16X16;
-                mx= get_amv(s, 0);
-                my= get_amv(s, 1);
+                s->mv_type     = MV_TYPE_16X16;
+                mx             = get_amv(ctx, 0);
+                my             = get_amv(ctx, 1);
                 s->mv[0][0][0] = mx;
                 s->mv[0][0][1] = my;
-            }else if((!s->progressive_sequence) && get_bits1(&s->gb)){
-                s->current_picture.f.mb_type[xy] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED;
+            } else if ((!s->progressive_sequence) && get_bits1(&s->gb)) {
+                s->current_picture.mb_type[xy] = MB_TYPE_16x8 |
+                                                 MB_TYPE_L0   |
+                                                 MB_TYPE_INTERLACED;
                 /* 16x8 field motion prediction */
-                s->mv_type= MV_TYPE_FIELD;
+                s->mv_type = MV_TYPE_FIELD;
 
-                s->field_select[0][0]= get_bits1(&s->gb);
-                s->field_select[0][1]= get_bits1(&s->gb);
+                s->field_select[0][0] = get_bits1(&s->gb);
+                s->field_select[0][1] = get_bits1(&s->gb);
 
                 ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
 
-                for(i=0; i<2; i++){
+                for (i = 0; i < 2; i++) {
                     mx = ff_h263_decode_motion(s, pred_x, s->f_code);
                     if (mx >= 0xffff)
                         return -1;
 
-                    my = ff_h263_decode_motion(s, pred_y/2, s->f_code);
+                    my = ff_h263_decode_motion(s, pred_y / 2, s->f_code);
                     if (my >= 0xffff)
                         return -1;
 
                     s->mv[0][i][0] = mx;
                     s->mv[0][i][1] = my;
                 }
-            }else{
-                s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+            } else {
+                s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
                 /* 16x16 motion prediction */
                 s->mv_type = MV_TYPE_16X16;
                 ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
@@ -1261,11 +1378,11 @@ static int mpeg4_decode_mb(MpegEncContext *s,
                 s->mv[0][0][1] = my;
             }
         } else {
-            s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
-            s->mv_type = MV_TYPE_8X8;
-            for(i=0;i<4;i++) {
+            s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+            s->mv_type                     = MV_TYPE_8X8;
+            for (i = 0; i < 4; i++) {
                 mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
-                mx = ff_h263_decode_motion(s, pred_x, s->f_code);
+                mx      = ff_h263_decode_motion(s, pred_x, s->f_code);
                 if (mx >= 0xffff)
                     return -1;
 
@@ -1274,213 +1391,233 @@ static int mpeg4_decode_mb(MpegEncContext *s,
                     return -1;
                 s->mv[0][i][0] = mx;
                 s->mv[0][i][1] = my;
-                mot_val[0] = mx;
-                mot_val[1] = my;
+                mot_val[0]     = mx;
+                mot_val[1]     = my;
             }
         }
-    } else if(s->pict_type==AV_PICTURE_TYPE_B) {
-        int modb1; // first bit of modb
-        int modb2; // second bit of modb
+    } else if (s->pict_type == AV_PICTURE_TYPE_B) {
+        int modb1;   // first bit of modb
+        int modb2;   // second bit of modb
         int mb_type;
 
-        s->mb_intra = 0; //B-frames never contain intra blocks
-        s->mcsel=0;      //     ...               true gmc blocks
+        s->mb_intra = 0;  // B-frames never contain intra blocks
+        s->mcsel    = 0;  //      ...               true gmc blocks
 
-        if(s->mb_x==0){
-            for(i=0; i<2; i++){
-                s->last_mv[i][0][0]=
-                s->last_mv[i][0][1]=
-                s->last_mv[i][1][0]=
-                s->last_mv[i][1][1]= 0;
+        if (s->mb_x == 0) {
+            for (i = 0; i < 2; i++) {
+                s->last_mv[i][0][0] =
+                s->last_mv[i][0][1] =
+                s->last_mv[i][1][0] =
+                s->last_mv[i][1][1] = 0;
             }
 
-            ff_thread_await_progress(&s->next_picture_ptr->f, s->mb_y, 0);
+            ff_thread_await_progress(&s->next_picture_ptr->tf, s->mb_y, 0);
         }
 
         /* if we skipped it in the future P Frame than skip it now too */
-        s->mb_skipped = s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC
+        s->mb_skipped = s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x];  // Note, skiptab=0 if last was GMC
 
-        if(s->mb_skipped){
-                /* skip mb */
-            for(i=0;i<6;i++)
+        if (s->mb_skipped) {
+            /* skip mb */
+            for (i = 0; i < 6; i++)
                 s->block_last_index[i] = -1;
 
-            s->mv_dir = MV_DIR_FORWARD;
-            s->mv_type = MV_TYPE_16X16;
-            s->mv[0][0][0] = 0;
-            s->mv[0][0][1] = 0;
-            s->mv[1][0][0] = 0;
+            s->mv_dir      = MV_DIR_FORWARD;
+            s->mv_type     = MV_TYPE_16X16;
+            s->mv[0][0][0] =
+            s->mv[0][0][1] =
+            s->mv[1][0][0] =
             s->mv[1][0][1] = 0;
-            s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_SKIP  |
+                                             MB_TYPE_16x16 |
+                                             MB_TYPE_L0;
             goto end;
         }
 
-        modb1= get_bits1(&s->gb);
-        if(modb1){
-            mb_type= MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1; //like MB_TYPE_B_DIRECT but no vectors coded
-            cbp=0;
-        }else{
-            modb2= get_bits1(&s->gb);
-            mb_type= get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1);
-            if(mb_type<0){
+        modb1 = get_bits1(&s->gb);
+        if (modb1) {
+            // like MB_TYPE_B_DIRECT but no vectors coded
+            mb_type = MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1;
+            cbp     = 0;
+        } else {
+            modb2   = get_bits1(&s->gb);
+            mb_type = get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1);
+            if (mb_type < 0) {
                 av_log(s->avctx, AV_LOG_ERROR, "illegal MB_type\n");
                 return -1;
             }
-            mb_type= mb_type_b_map[ mb_type ];
-            if(modb2) cbp= 0;
-            else{
+            mb_type = mb_type_b_map[mb_type];
+            if (modb2) {
+                cbp = 0;
+            } else {
                 s->dsp.clear_blocks(s->block[0]);
-                cbp= get_bits(&s->gb, 6);
+                cbp = get_bits(&s->gb, 6);
             }
 
             if ((!IS_DIRECT(mb_type)) && cbp) {
-                if(get_bits1(&s->gb)){
-                    ff_set_qscale(s, s->qscale + get_bits1(&s->gb)*4 - 2);
-                }
+                if (get_bits1(&s->gb))
+                    ff_set_qscale(s, s->qscale + get_bits1(&s->gb) * 4 - 2);
             }
 
-            if(!s->progressive_sequence){
-                if(cbp)
-                    s->interlaced_dct= get_bits1(&s->gb);
+            if (!s->progressive_sequence) {
+                if (cbp)
+                    s->interlaced_dct = get_bits1(&s->gb);
 
-                if(!IS_DIRECT(mb_type) && get_bits1(&s->gb)){
+                if (!IS_DIRECT(mb_type) && get_bits1(&s->gb)) {
                     mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
                     mb_type &= ~MB_TYPE_16x16;
 
-                    if(USES_LIST(mb_type, 0)){
-                        s->field_select[0][0]= get_bits1(&s->gb);
-                        s->field_select[0][1]= get_bits1(&s->gb);
+                    if (USES_LIST(mb_type, 0)) {
+                        s->field_select[0][0] = get_bits1(&s->gb);
+                        s->field_select[0][1] = get_bits1(&s->gb);
                     }
-                    if(USES_LIST(mb_type, 1)){
-                        s->field_select[1][0]= get_bits1(&s->gb);
-                        s->field_select[1][1]= get_bits1(&s->gb);
+                    if (USES_LIST(mb_type, 1)) {
+                        s->field_select[1][0] = get_bits1(&s->gb);
+                        s->field_select[1][1] = get_bits1(&s->gb);
                     }
                 }
             }
 
             s->mv_dir = 0;
-            if((mb_type & (MB_TYPE_DIRECT2|MB_TYPE_INTERLACED)) == 0){
-                s->mv_type= MV_TYPE_16X16;
+            if ((mb_type & (MB_TYPE_DIRECT2 | MB_TYPE_INTERLACED)) == 0) {
+                s->mv_type = MV_TYPE_16X16;
 
-                if(USES_LIST(mb_type, 0)){
+                if (USES_LIST(mb_type, 0)) {
                     s->mv_dir = MV_DIR_FORWARD;
 
                     mx = ff_h263_decode_motion(s, s->last_mv[0][0][0], s->f_code);
                     my = ff_h263_decode_motion(s, s->last_mv[0][0][1], s->f_code);
-                    s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->mv[0][0][0] = mx;
-                    s->last_mv[0][1][1]= s->last_mv[0][0][1]= s->mv[0][0][1] = my;
+                    s->last_mv[0][1][0] =
+                    s->last_mv[0][0][0] =
+                    s->mv[0][0][0]      = mx;
+                    s->last_mv[0][1][1] =
+                    s->last_mv[0][0][1] =
+                    s->mv[0][0][1]      = my;
                 }
 
-                if(USES_LIST(mb_type, 1)){
+                if (USES_LIST(mb_type, 1)) {
                     s->mv_dir |= MV_DIR_BACKWARD;
 
                     mx = ff_h263_decode_motion(s, s->last_mv[1][0][0], s->b_code);
                     my = ff_h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);
-                    s->last_mv[1][1][0]= s->last_mv[1][0][0]= s->mv[1][0][0] = mx;
-                    s->last_mv[1][1][1]= s->last_mv[1][0][1]= s->mv[1][0][1] = my;
+                    s->last_mv[1][1][0] =
+                    s->last_mv[1][0][0] =
+                    s->mv[1][0][0]      = mx;
+                    s->last_mv[1][1][1] =
+                    s->last_mv[1][0][1] =
+                    s->mv[1][0][1]      = my;
                 }
-            }else if(!IS_DIRECT(mb_type)){
-                s->mv_type= MV_TYPE_FIELD;
+            } else if (!IS_DIRECT(mb_type)) {
+                s->mv_type = MV_TYPE_FIELD;
 
-                if(USES_LIST(mb_type, 0)){
+                if (USES_LIST(mb_type, 0)) {
                     s->mv_dir = MV_DIR_FORWARD;
 
-                    for(i=0; i<2; i++){
-                        mx = ff_h263_decode_motion(s, s->last_mv[0][i][0]  , s->f_code);
-                        my = ff_h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code);
-                        s->last_mv[0][i][0]=  s->mv[0][i][0] = mx;
-                        s->last_mv[0][i][1]= (s->mv[0][i][1] = my)*2;
+                    for (i = 0; i < 2; i++) {
+                        mx = ff_h263_decode_motion(s, s->last_mv[0][i][0], s->f_code);
+                        my = ff_h263_decode_motion(s, s->last_mv[0][i][1] / 2, s->f_code);
+                        s->last_mv[0][i][0] =
+                        s->mv[0][i][0]      = mx;
+                        s->last_mv[0][i][1] = (s->mv[0][i][1] = my) * 2;
                     }
                 }
 
-                if(USES_LIST(mb_type, 1)){
+                if (USES_LIST(mb_type, 1)) {
                     s->mv_dir |= MV_DIR_BACKWARD;
 
-                    for(i=0; i<2; i++){
-                        mx = ff_h263_decode_motion(s, s->last_mv[1][i][0]  , s->b_code);
-                        my = ff_h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code);
-                        s->last_mv[1][i][0]=  s->mv[1][i][0] = mx;
-                        s->last_mv[1][i][1]= (s->mv[1][i][1] = my)*2;
+                    for (i = 0; i < 2; i++) {
+                        mx = ff_h263_decode_motion(s, s->last_mv[1][i][0], s->b_code);
+                        my = ff_h263_decode_motion(s, s->last_mv[1][i][1] / 2, s->b_code);
+                        s->last_mv[1][i][0] =
+                        s->mv[1][i][0]      = mx;
+                        s->last_mv[1][i][1] = (s->mv[1][i][1] = my) * 2;
                     }
                 }
             }
         }
 
-        if(IS_DIRECT(mb_type)){
-            if(IS_SKIP(mb_type))
-                mx=my=0;
-            else{
+        if (IS_DIRECT(mb_type)) {
+            if (IS_SKIP(mb_type)) {
+                mx =
+                my = 0;
+            } else {
                 mx = ff_h263_decode_motion(s, 0, 1);
                 my = ff_h263_decode_motion(s, 0, 1);
             }
 
             s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
-            mb_type |= ff_mpeg4_set_direct_mv(s, mx, my);
+            mb_type  |= ff_mpeg4_set_direct_mv(s, mx, my);
         }
-        s->current_picture.f.mb_type[xy] = mb_type;
+        s->current_picture.mb_type[xy] = mb_type;
     } else { /* I-Frame */
-        do{
+        do {
             cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
-            if (cbpc < 0){
-                av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
+            if (cbpc < 0) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
                 return -1;
             }
-        }while(cbpc == 8);
+        } while (cbpc == 8);
 
         dquant = cbpc & 4;
         s->mb_intra = 1;
+
 intra:
         s->ac_pred = get_bits1(&s->gb);
-        if(s->ac_pred)
-            s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
+        if (s->ac_pred)
+            s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
         else
-            s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+            s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
 
         cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
-        if(cbpy<0){
-            av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
+        if (cbpy < 0) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
             return -1;
         }
         cbp = (cbpc & 3) | (cbpy << 2);
 
-        s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold;
+        ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
 
-        if (dquant) {
+        if (dquant)
             ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
-        }
 
-        if(!s->progressive_sequence)
-            s->interlaced_dct= get_bits1(&s->gb);
+        if (!s->progressive_sequence)
+            s->interlaced_dct = get_bits1(&s->gb);
 
         s->dsp.clear_blocks(s->block[0]);
         /* decode each block */
         for (i = 0; i < 6; i++) {
-            if (mpeg4_decode_block(s, block[i], i, cbp&32, 1, 0) < 0)
+            if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 1, 0) < 0)
                 return -1;
-            cbp+=cbp;
+            cbp += cbp;
         }
         goto end;
     }
 
     /* decode each block */
     for (i = 0; i < 6; i++) {
-        if (mpeg4_decode_block(s, block[i], i, cbp&32, 0, 0) < 0)
+        if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 0, 0) < 0)
             return -1;
-        cbp+=cbp;
+        cbp += cbp;
     }
-end:
 
-        /* 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;
-
-            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) {
-                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);
+end:
+    /* 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;
+
+            if (s->pict_type == AV_PICTURE_TYPE_B &&
+                s->next_picture.mbskip_table[xy + delta]) {
+                ff_thread_await_progress(&s->next_picture_ptr->tf,
+                                         (s->mb_x + delta >= s->mb_width)
+                                         ? FFMIN(s->mb_y + 1, s->mb_height - 1)
+                                         : s->mb_y, 0);
             }
 
-            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta])
+            if (s->pict_type == AV_PICTURE_TYPE_B &&
+                s->next_picture.mbskip_table[xy + delta])
                 return SLICE_OK;
             return SLICE_END;
         }
@@ -1489,16 +1626,16 @@ end:
     return SLICE_OK;
 }
 
-
-static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){
+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);
+        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");
@@ -1507,49 +1644,52 @@ static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){
     return 0;
 }
 
-static int mpeg4_decode_profile_level(MpegEncContext * s, GetBitContext *gb){
-  int profile_and_level_indication;
+static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb)
+{
+    int profile_and_level_indication;
 
-  profile_and_level_indication = get_bits(gb, 8);
+    profile_and_level_indication = get_bits(gb, 8);
 
-  s->avctx->profile = (profile_and_level_indication & 0xf0) >> 4;
-  s->avctx->level   = (profile_and_level_indication & 0x0f);
+    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){
+static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+    MpegEncContext *s = &ctx->m;
     int width, height, vo_ver_id;
 
     /* vol header */
-    skip_bits(gb, 1); /* random access */
-    s->vo_type= get_bits(gb, 8);
-    if (get_bits1(gb) != 0) { /* is_ol_id */
-        vo_ver_id = get_bits(gb, 4); /* vo_ver_id */
-        skip_bits(gb, 3); /* vo_priority */
+    skip_bits(gb, 1);                   /* random access */
+    s->vo_type = get_bits(gb, 8);
+    if (get_bits1(gb) != 0) {           /* is_ol_id */
+        vo_ver_id = get_bits(gb, 4);    /* vo_ver_id */
+        skip_bits(gb, 3);               /* vo_priority */
     } else {
         vo_ver_id = 1;
     }
-    s->aspect_ratio_info= get_bits(gb, 4);
-    if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){
-        s->avctx->sample_aspect_ratio.num= get_bits(gb, 8); // par_width
-        s->avctx->sample_aspect_ratio.den= get_bits(gb, 8); // par_height
-    }else{
-        s->avctx->sample_aspect_ratio= ff_h263_pixel_aspect[s->aspect_ratio_info];
+    s->aspect_ratio_info = get_bits(gb, 4);
+    if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
+        s->avctx->sample_aspect_ratio.num = get_bits(gb, 8);  // par_width
+        s->avctx->sample_aspect_ratio.den = get_bits(gb, 8);  // par_height
+    } else {
+        s->avctx->sample_aspect_ratio = ff_h263_pixel_aspect[s->aspect_ratio_info];
     }
 
-    if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */
-        int chroma_format= get_bits(gb, 2);
-        if(chroma_format!=CHROMA_420){
+    if ((s->vol_control_parameters = get_bits1(gb))) { /* vol control parameter */
+        int chroma_format = get_bits(gb, 2);
+        if (chroma_format != CHROMA_420)
             av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n");
-        }
-        s->low_delay= get_bits1(gb);
-        if(get_bits1(gb)){ /* vbv parameters */
+
+        s->low_delay = get_bits1(gb);
+        if (get_bits1(gb)) {    /* vbv parameters */
             get_bits(gb, 15);   /* first_half_bitrate */
             skip_bits1(gb);     /* marker */
             get_bits(gb, 15);   /* latter_half_bitrate */
@@ -1562,273 +1702,289 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
             get_bits(gb, 15);   /* latter_half_vbv_occupancy */
             skip_bits1(gb);     /* marker */
         }
-    }else{
-        // set low delay flag only once the smartest? low delay detection won't be overriden
-        if(s->picture_number==0)
-            s->low_delay=0;
+    } else {
+        /* is setting low delay flag only once the smartest thing to do?
+         * low delay detection won't be overriden. */
+        if (s->picture_number == 0)
+            s->low_delay = 0;
     }
 
-    s->shape = get_bits(gb, 2); /* vol shape */
-    if(s->shape != RECT_SHAPE) av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n");
-    if(s->shape == GRAY_SHAPE && vo_ver_id != 1){
+    ctx->shape = get_bits(gb, 2); /* vol shape */
+    if (ctx->shape != RECT_SHAPE)
+        av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n");
+    if (ctx->shape == GRAY_SHAPE && vo_ver_id != 1) {
         av_log(s->avctx, AV_LOG_ERROR, "Gray shape not supported\n");
-        skip_bits(gb, 4);  //video_object_layer_shape_extension
+        skip_bits(gb, 4);  /* video_object_layer_shape_extension */
     }
 
     check_marker(gb, "before time_increment_resolution");
 
     s->avctx->time_base.den = get_bits(gb, 16);
-    if(!s->avctx->time_base.den){
+    if (!s->avctx->time_base.den) {
         av_log(s->avctx, AV_LOG_ERROR, "time_base.den==0\n");
         s->avctx->time_base.num = 0;
         return -1;
     }
 
-    s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
-    if (s->time_increment_bits < 1)
-        s->time_increment_bits = 1;
+    ctx->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
+    if (ctx->time_increment_bits < 1)
+        ctx->time_increment_bits = 1;
 
     check_marker(gb, "before fixed_vop_rate");
 
-    if (get_bits1(gb) != 0) {   /* fixed_vop_rate  */
-        s->avctx->time_base.num = get_bits(gb, s->time_increment_bits);
-    }else
+    if (get_bits1(gb) != 0)     /* fixed_vop_rate  */
+        s->avctx->time_base.num = get_bits(gb, ctx->time_increment_bits);
+    else
         s->avctx->time_base.num = 1;
 
-    s->t_frame=0;
+    ctx->t_frame = 0;
 
-    if (s->shape != BIN_ONLY_SHAPE) {
-        if (s->shape == RECT_SHAPE) {
+    if (ctx->shape != BIN_ONLY_SHAPE) {
+        if (ctx->shape == RECT_SHAPE) {
             skip_bits1(gb);   /* marker */
             width = get_bits(gb, 13);
             skip_bits1(gb);   /* marker */
             height = get_bits(gb, 13);
             skip_bits1(gb);   /* marker */
-            if(width && height && !(s->width && s->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */
+            if (width && height &&  /* they should be non zero but who knows */
+                !(s->width && s->codec_tag == AV_RL32("MP4S"))) {
                 if (s->width && s->height &&
                     (s->width != width || s->height != height))
                     s->context_reinit = 1;
-                s->width = width;
+                s->width  = width;
                 s->height = height;
             }
         }
 
-        s->progressive_sequence=
-        s->progressive_frame= get_bits1(gb)^1;
-        s->interlaced_dct=0;
-        if(!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO))
-            av_log(s->avctx, AV_LOG_INFO, "MPEG4 OBMC not supported (very likely buggy encoder)\n");   /* OBMC Disable */
-        if (vo_ver_id == 1) {
-            s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */
-        } else {
-            s->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */
-        }
-        if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n");
-        if(s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE){
-            if(s->vol_sprite_usage==STATIC_SPRITE){
-                s->sprite_width = get_bits(gb, 13);
+        s->progressive_sequence  =
+        s->progressive_frame     = get_bits1(gb) ^ 1;
+        s->interlaced_dct        = 0;
+        if (!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO))
+            av_log(s->avctx, AV_LOG_INFO,           /* OBMC Disable */
+                   "MPEG4 OBMC not supported (very likely buggy encoder)\n");
+        if (vo_ver_id == 1)
+            ctx->vol_sprite_usage = get_bits1(gb);    /* vol_sprite_usage */
+        else
+            ctx->vol_sprite_usage = get_bits(gb, 2);  /* vol_sprite_usage */
+
+        if (ctx->vol_sprite_usage == STATIC_SPRITE)
+            av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n");
+        if (ctx->vol_sprite_usage == STATIC_SPRITE ||
+            ctx->vol_sprite_usage == GMC_SPRITE) {
+            if (ctx->vol_sprite_usage == STATIC_SPRITE) {
+                skip_bits(gb, 13); // sprite_width
                 skip_bits1(gb); /* marker */
-                s->sprite_height= get_bits(gb, 13);
+                skip_bits(gb, 13); // sprite_height
                 skip_bits1(gb); /* marker */
-                s->sprite_left  = get_bits(gb, 13);
+                skip_bits(gb, 13); // sprite_left
                 skip_bits1(gb); /* marker */
-                s->sprite_top   = get_bits(gb, 13);
+                skip_bits(gb, 13); // sprite_top
                 skip_bits1(gb); /* marker */
             }
-            s->num_sprite_warping_points= get_bits(gb, 6);
-            if(s->num_sprite_warping_points > 3){
-                av_log(s->avctx, AV_LOG_ERROR, "%d sprite_warping_points\n", s->num_sprite_warping_points);
-                s->num_sprite_warping_points= 0;
+            ctx->num_sprite_warping_points = get_bits(gb, 6);
+            if (ctx->num_sprite_warping_points > 3) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "%d sprite_warping_points\n",
+                       ctx->num_sprite_warping_points);
+                ctx->num_sprite_warping_points = 0;
                 return -1;
             }
-            s->sprite_warping_accuracy = get_bits(gb, 2);
-            s->sprite_brightness_change= get_bits1(gb);
-            if(s->vol_sprite_usage==STATIC_SPRITE)
-                s->low_latency_sprite= get_bits1(gb);
+            s->sprite_warping_accuracy  = get_bits(gb, 2);
+            ctx->sprite_brightness_change = get_bits1(gb);
+            if (ctx->vol_sprite_usage == STATIC_SPRITE)
+                skip_bits1(gb); // low_latency_sprite
         }
         // FIXME sadct disable bit if verid!=1 && shape not rect
 
-        if (get_bits1(gb) == 1) {   /* not_8_bit */
-            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 (get_bits1(gb) == 1) {                   /* not_8_bit */
+            s->quant_precision = get_bits(gb, 4);   /* quant_precision */
+            if (get_bits(gb, 4) != 8)               /* bits_per_pixel */
+                av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n");
+            if (s->quant_precision != 5)
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "quant precision %d\n", s->quant_precision);
         } else {
             s->quant_precision = 5;
         }
 
         // FIXME a bunch of grayscale shape things
 
-        if((s->mpeg_quant=get_bits1(gb))){ /* vol_quant_type */
+        if ((s->mpeg_quant = get_bits1(gb))) { /* vol_quant_type */
             int i, v;
 
             /* load default matrixes */
-            for(i=0; i<64; i++){
-                int j= s->dsp.idct_permutation[i];
-                v= ff_mpeg4_default_intra_matrix[i];
-                s->intra_matrix[j]= v;
-                s->chroma_intra_matrix[j]= v;
-
-                v= ff_mpeg4_default_non_intra_matrix[i];
-                s->inter_matrix[j]= v;
-                s->chroma_inter_matrix[j]= v;
+            for (i = 0; i < 64; i++) {
+                int j = s->dsp.idct_permutation[i];
+                v = ff_mpeg4_default_intra_matrix[i];
+                s->intra_matrix[j]        = v;
+                s->chroma_intra_matrix[j] = v;
+
+                v = ff_mpeg4_default_non_intra_matrix[i];
+                s->inter_matrix[j]        = v;
+                s->chroma_inter_matrix[j] = v;
             }
 
             /* load custom intra matrix */
-            if(get_bits1(gb)){
-                int last=0;
-                for(i=0; i<64; i++){
+            if (get_bits1(gb)) {
+                int last = 0;
+                for (i = 0; i < 64; i++) {
                     int j;
-                    v= get_bits(gb, 8);
-                    if(v==0) break;
-
-                    last= v;
-                    j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
-                    s->intra_matrix[j]= v;
-                    s->chroma_intra_matrix[j]= v;
+                    v = get_bits(gb, 8);
+                    if (v == 0)
+                        break;
+
+                    last = v;
+                    j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+                    s->intra_matrix[j]        = last;
+                    s->chroma_intra_matrix[j] = last;
                 }
 
                 /* replicate last value */
-                for(; i<64; i++){
-                    int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
-                    s->intra_matrix[j]= last;
-                    s->chroma_intra_matrix[j]= last;
+                for (; i < 64; i++) {
+                    int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+                    s->intra_matrix[j]        = last;
+                    s->chroma_intra_matrix[j] = last;
                 }
             }
 
             /* load custom non intra matrix */
-            if(get_bits1(gb)){
-                int last=0;
-                for(i=0; i<64; i++){
+            if (get_bits1(gb)) {
+                int last = 0;
+                for (i = 0; i < 64; i++) {
                     int j;
-                    v= get_bits(gb, 8);
-                    if(v==0) break;
-
-                    last= v;
-                    j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
-                    s->inter_matrix[j]= v;
-                    s->chroma_inter_matrix[j]= v;
+                    v = get_bits(gb, 8);
+                    if (v == 0)
+                        break;
+
+                    last = v;
+                    j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+                    s->inter_matrix[j]        = v;
+                    s->chroma_inter_matrix[j] = v;
                 }
 
                 /* replicate last value */
-                for(; i<64; i++){
-                    int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ];
-                    s->inter_matrix[j]= last;
-                    s->chroma_inter_matrix[j]= last;
+                for (; i < 64; i++) {
+                    int j = s->dsp.idct_permutation[ff_zigzag_direct[i]];
+                    s->inter_matrix[j]        = last;
+                    s->chroma_inter_matrix[j] = last;
                 }
             }
 
             // FIXME a bunch of grayscale shape things
         }
 
-        if(vo_ver_id != 1)
-             s->quarter_sample= get_bits1(gb);
-        else s->quarter_sample=0;
-
-        if(!get_bits1(gb)){
-            int pos= get_bits_count(gb);
-            int estimation_method= get_bits(gb, 2);
-            if(estimation_method<2){
-                if(!get_bits1(gb)){
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //opaque
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //transparent
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_cae
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //inter_cae
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //no_update
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //upampling
+        if (vo_ver_id != 1)
+            s->quarter_sample = get_bits1(gb);
+        else
+            s->quarter_sample = 0;
+
+        if (!get_bits1(gb)) {
+            int pos               = get_bits_count(gb);
+            int estimation_method = get_bits(gb, 2);
+            if (estimation_method < 2) {
+                if (!get_bits1(gb)) {
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* opaque */
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* transparent */
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* intra_cae */
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* inter_cae */
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* no_update */
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* upampling */
                 }
-                if(!get_bits1(gb)){
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //intra_blocks
-                    s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter_blocks
-                    s->cplx_estimation_trash_p += 8*get_bits1(gb); //inter4v_blocks
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //not coded blocks
+                if (!get_bits1(gb)) {
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* intra_blocks */
+                    ctx->cplx_estimation_trash_p += 8 * get_bits1(gb);  /* inter_blocks */
+                    ctx->cplx_estimation_trash_p += 8 * get_bits1(gb);  /* inter4v_blocks */
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* not coded blocks */
                 }
-                if(!check_marker(gb, "in complexity estimation part 1")){
+                if (!check_marker(gb, "in complexity estimation part 1")) {
                     skip_bits_long(gb, pos - get_bits_count(gb));
                     goto no_cplx_est;
                 }
-                if(!get_bits1(gb)){
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_coeffs
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //dct_lines
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //vlc_syms
-                    s->cplx_estimation_trash_i += 4*get_bits1(gb); //vlc_bits
+                if (!get_bits1(gb)) {
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* dct_coeffs */
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* dct_lines */
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* vlc_syms */
+                    ctx->cplx_estimation_trash_i += 4 * get_bits1(gb);  /* vlc_bits */
                 }
-                if(!get_bits1(gb)){
-                    s->cplx_estimation_trash_p += 8*get_bits1(gb); //apm
-                    s->cplx_estimation_trash_p += 8*get_bits1(gb); //npm
-                    s->cplx_estimation_trash_b += 8*get_bits1(gb); //interpolate_mc_q
-                    s->cplx_estimation_trash_p += 8*get_bits1(gb); //forwback_mc_q
-                    s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel2
-                    s->cplx_estimation_trash_p += 8*get_bits1(gb); //halfpel4
+                if (!get_bits1(gb)) {
+                    ctx->cplx_estimation_trash_p += 8 * get_bits1(gb);  /* apm */
+                    ctx->cplx_estimation_trash_p += 8 * get_bits1(gb);  /* npm */
+                    ctx->cplx_estimation_trash_b += 8 * get_bits1(gb);  /* interpolate_mc_q */
+                    ctx->cplx_estimation_trash_p += 8 * get_bits1(gb);  /* forwback_mc_q */
+                    ctx->cplx_estimation_trash_p += 8 * get_bits1(gb);  /* halfpel2 */
+                    ctx->cplx_estimation_trash_p += 8 * get_bits1(gb);  /* halfpel4 */
                 }
-                if(!check_marker(gb, "in complexity estimation part 2")){
+                if (!check_marker(gb, "in complexity estimation part 2")) {
                     skip_bits_long(gb, pos - get_bits_count(gb));
                     goto no_cplx_est;
                 }
-                if(estimation_method==1){
-                    s->cplx_estimation_trash_i += 8*get_bits1(gb); //sadct
-                    s->cplx_estimation_trash_p += 8*get_bits1(gb); //qpel
+                if (estimation_method == 1) {
+                    ctx->cplx_estimation_trash_i += 8 * get_bits1(gb);  /* sadct */
+                    ctx->cplx_estimation_trash_p += 8 * get_bits1(gb);  /* qpel */
                 }
-            }else
-                av_log(s->avctx, AV_LOG_ERROR, "Invalid Complexity estimation method %d\n", estimation_method);
-        }else{
+            } else
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "Invalid Complexity estimation method %d\n",
+                       estimation_method);
+        } else {
+
 no_cplx_est:
-            s->cplx_estimation_trash_i=
-            s->cplx_estimation_trash_p=
-            s->cplx_estimation_trash_b= 0;
+            ctx->cplx_estimation_trash_i =
+            ctx->cplx_estimation_trash_p =
+            ctx->cplx_estimation_trash_b = 0;
         }
 
-        s->resync_marker= !get_bits1(gb); /* resync_marker_disabled */
+        ctx->resync_marker = !get_bits1(gb); /* resync_marker_disabled */
 
-        s->data_partitioning= get_bits1(gb);
-        if(s->data_partitioning){
-            s->rvlc= get_bits1(gb);
-        }
+        s->data_partitioning = get_bits1(gb);
+        if (s->data_partitioning)
+            ctx->rvlc = get_bits1(gb);
 
-        if(vo_ver_id != 1) {
-            s->new_pred= get_bits1(gb);
-            if(s->new_pred){
+        if (vo_ver_id != 1) {
+            ctx->new_pred = get_bits1(gb);
+            if (ctx->new_pred) {
                 av_log(s->avctx, AV_LOG_ERROR, "new pred not supported\n");
                 skip_bits(gb, 2); /* requested upstream message type */
-                skip_bits1(gb); /* newpred segment type */
+                skip_bits1(gb);   /* newpred segment type */
             }
-            s->reduced_res_vop= get_bits1(gb);
-            if(s->reduced_res_vop) av_log(s->avctx, AV_LOG_ERROR, "reduced resolution VOP not supported\n");
-        }
-        else{
-            s->new_pred=0;
-            s->reduced_res_vop= 0;
+            if (get_bits1(gb)) // reduced_res_vop
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "reduced resolution VOP not supported\n");
+        } else {
+            ctx->new_pred = 0;
         }
 
-        s->scalability= get_bits1(gb);
+        ctx->scalability = get_bits1(gb);
 
-        if (s->scalability) {
-            GetBitContext bak= *gb;
+        if (ctx->scalability) {
+            GetBitContext bak = *gb;
             int h_sampling_factor_n;
             int h_sampling_factor_m;
             int v_sampling_factor_n;
             int v_sampling_factor_m;
 
-            s->hierachy_type= get_bits1(gb);
+            skip_bits1(gb);    // hierarchy_type
             skip_bits(gb, 4);  /* ref_layer_id */
             skip_bits1(gb);    /* ref_layer_sampling_dir */
-            h_sampling_factor_n= get_bits(gb, 5);
-            h_sampling_factor_m= get_bits(gb, 5);
-            v_sampling_factor_n= get_bits(gb, 5);
-            v_sampling_factor_m= get_bits(gb, 5);
-            s->enhancement_type= get_bits1(gb);
-
-            if(   h_sampling_factor_n==0 || h_sampling_factor_m==0
-               || v_sampling_factor_n==0 || v_sampling_factor_m==0){
+            h_sampling_factor_n = get_bits(gb, 5);
+            h_sampling_factor_m = get_bits(gb, 5);
+            v_sampling_factor_n = get_bits(gb, 5);
+            v_sampling_factor_m = get_bits(gb, 5);
+            ctx->enhancement_type = get_bits1(gb);
+
+            if (h_sampling_factor_n == 0 || h_sampling_factor_m == 0 ||
+                v_sampling_factor_n == 0 || v_sampling_factor_m == 0) {
                 /* illegal scalability header (VERY broken encoder),
                  * trying to workaround */
-                s->scalability=0;
-                *gb= bak;
-            }else
+                ctx->scalability = 0;
+                *gb            = bak;
+            } else
                 av_log(s->avctx, AV_LOG_ERROR, "scalability not supported\n");
 
             // bin shape stuff FIXME
         }
     }
+
     return 0;
 }
 
@@ -1836,271 +1992,298 @@ no_cplx_est:
  * Decode the user data stuff in the header.
  * Also initializes divx/xvid/lavc_version/build.
  */
-static int decode_user_data(MpegEncContext *s, GetBitContext *gb){
+static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+    MpegEncContext *s = &ctx->m;
     char buf[256];
     int i;
     int e;
     int ver = 0, build = 0, ver2 = 0, ver3 = 0;
     char last;
 
-    for(i=0; i<255 && get_bits_count(gb) < gb->size_in_bits; i++){
-        if(show_bits(gb, 23) == 0) break;
-        buf[i]= get_bits(gb, 8);
+    for (i = 0; i < 255 && get_bits_count(gb) < gb->size_in_bits; i++) {
+        if (show_bits(gb, 23) == 0)
+            break;
+        buf[i] = get_bits(gb, 8);
     }
-    buf[i]=0;
+    buf[i] = 0;
 
     /* divx detection */
-    e=sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last);
-    if(e<2)
-        e=sscanf(buf, "DivX%db%d%c", &ver, &build, &last);
-    if(e>=2){
-        s->divx_version= ver;
-        s->divx_build= build;
-        s->divx_packed= e==3 && last=='p';
-        if(s->divx_packed && !s->showed_packed_warning) {
-            av_log(s->avctx, AV_LOG_WARNING, "Invalid and inefficient vfw-avi packed B frames detected\n");
-            s->showed_packed_warning=1;
+    e = sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last);
+    if (e < 2)
+        e = sscanf(buf, "DivX%db%d%c", &ver, &build, &last);
+    if (e >= 2) {
+        ctx->divx_version = ver;
+        ctx->divx_build   = build;
+        s->divx_packed  = e == 3 && last == 'p';
+        if (s->divx_packed && !ctx->showed_packed_warning) {
+            av_log(s->avctx, AV_LOG_WARNING,
+                   "Invalid and inefficient vfw-avi packed B frames detected\n");
+            ctx->showed_packed_warning = 1;
         }
     }
 
     /* libavcodec detection */
-    e=sscanf(buf, "FFmpe%*[^b]b%d", &build)+3;
-    if(e!=4)
-        e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build);
-    if(e!=4){
-        e=sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3)+1;
-        if (e>1)
-            build= (ver<<16) + (ver2<<8) + ver3;
-    }
-    if(e!=4){
-        if(strcmp(buf, "ffmpeg")==0){
-            s->lavc_build= 4600;
-        }
+    e = sscanf(buf, "FFmpe%*[^b]b%d", &build) + 3;
+    if (e != 4)
+        e = sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build);
+    if (e != 4) {
+        e = sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3) + 1;
+        if (e > 1)
+            build = (ver << 16) + (ver2 << 8) + ver3;
     }
-    if(e==4){
-        s->lavc_build= build;
+    if (e != 4) {
+        if (strcmp(buf, "ffmpeg") == 0)
+            ctx->lavc_build = 4600;
     }
+    if (e == 4)
+        ctx->lavc_build = build;
 
     /* Xvid detection */
-    e=sscanf(buf, "XviD%d", &build);
-    if(e==1){
-        s->xvid_build= build;
-    }
+    e = sscanf(buf, "XviD%d", &build);
+    if (e == 1)
+        ctx->xvid_build = build;
 
     return 0;
 }
 
-static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
+static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+    MpegEncContext *s = &ctx->m;
     int time_incr, time_increment;
 
     s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I;        /* pict type: I = 0 , P = 1 */
-    if(s->pict_type==AV_PICTURE_TYPE_B && s->low_delay && s->vol_control_parameters==0 && !(s->flags & CODEC_FLAG_LOW_DELAY)){
+    if (s->pict_type == AV_PICTURE_TYPE_B && s->low_delay &&
+        s->vol_control_parameters == 0 && !(s->flags & CODEC_FLAG_LOW_DELAY)) {
         av_log(s->avctx, AV_LOG_ERROR, "low_delay flag incorrectly, clearing it\n");
-        s->low_delay=0;
+        s->low_delay = 0;
     }
 
-    s->partitioned_frame= s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B;
-    if(s->partitioned_frame)
-        s->decode_mb= mpeg4_decode_partitioned_mb;
+    s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;
+    if (s->partitioned_frame)
+        s->decode_mb = mpeg4_decode_partitioned_mb;
     else
-        s->decode_mb= mpeg4_decode_mb;
+        s->decode_mb = mpeg4_decode_mb;
 
-    time_incr=0;
+    time_incr = 0;
     while (get_bits1(gb) != 0)
         time_incr++;
 
     check_marker(gb, "before time_increment");
 
-    if(s->time_increment_bits==0 || !(show_bits(gb, s->time_increment_bits+1)&1)){
-        av_log(s->avctx, AV_LOG_ERROR, "hmm, seems the headers are not complete, trying to guess time_increment_bits\n");
-
-        for(s->time_increment_bits=1 ;s->time_increment_bits<16; s->time_increment_bits++){
-            if (    s->pict_type == AV_PICTURE_TYPE_P
-                || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE)) {
-                if((show_bits(gb, s->time_increment_bits+6)&0x37) == 0x30) break;
-            }else
-                if((show_bits(gb, s->time_increment_bits+5)&0x1F) == 0x18) break;
+    if (ctx->time_increment_bits == 0 ||
+        !(show_bits(gb, ctx->time_increment_bits + 1) & 1)) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "hmm, seems the headers are not complete, trying to guess time_increment_bits\n");
+
+        for (ctx->time_increment_bits = 1;
+             ctx->time_increment_bits < 16;
+             ctx->time_increment_bits++) {
+            if (s->pict_type == AV_PICTURE_TYPE_P ||
+                (s->pict_type == AV_PICTURE_TYPE_S &&
+                 ctx->vol_sprite_usage == GMC_SPRITE)) {
+                if ((show_bits(gb, ctx->time_increment_bits + 6) & 0x37) == 0x30)
+                    break;
+            } else if ((show_bits(gb, ctx->time_increment_bits + 5) & 0x1F) == 0x18)
+                break;
         }
 
-        av_log(s->avctx, AV_LOG_ERROR, "my guess is %d bits ;)\n",s->time_increment_bits);
+        av_log(s->avctx, AV_LOG_ERROR,
+               "my guess is %d bits ;)\n", ctx->time_increment_bits);
     }
 
-    if(IS_3IV1) time_increment= get_bits1(gb); //FIXME investigate further
-    else time_increment= get_bits(gb, s->time_increment_bits);
-
-    if(s->pict_type!=AV_PICTURE_TYPE_B){
-        s->last_time_base= s->time_base;
-        s->time_base+= time_incr;
-        s->time= s->time_base*s->avctx->time_base.den + time_increment;
-        if(s->workaround_bugs&FF_BUG_UMP4){
-            if(s->time < s->last_non_b_time){
+    if (IS_3IV1)
+        time_increment = get_bits1(gb);        // FIXME investigate further
+    else
+        time_increment = get_bits(gb, ctx->time_increment_bits);
+
+    if (s->pict_type != AV_PICTURE_TYPE_B) {
+        s->last_time_base = s->time_base;
+        s->time_base     += time_incr;
+        s->time = s->time_base * s->avctx->time_base.den + time_increment;
+        if (s->workaround_bugs & FF_BUG_UMP4) {
+            if (s->time < s->last_non_b_time) {
                 /* header is not mpeg-4-compatible, broken encoder,
                  * trying to workaround */
                 s->time_base++;
-                s->time+= s->avctx->time_base.den;
+                s->time += s->avctx->time_base.den;
             }
         }
-        s->pp_time= s->time - s->last_non_b_time;
-        s->last_non_b_time= s->time;
-    }else{
-        s->time= (s->last_time_base + time_incr)*s->avctx->time_base.den + time_increment;
-        s->pb_time= s->pp_time - (s->last_non_b_time - s->time);
-        if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){
+        s->pp_time         = s->time - s->last_non_b_time;
+        s->last_non_b_time = s->time;
+    } else {
+        s->time    = (s->last_time_base + time_incr) * s->avctx->time_base.den + time_increment;
+        s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
+        if (s->pp_time <= s->pb_time ||
+            s->pp_time <= s->pp_time - s->pb_time ||
+            s->pp_time <= 0) {
             /* messed up order, maybe after seeking? skipping current b-frame */
             return FRAME_SKIPPED;
         }
         ff_mpeg4_init_direct_mv(s);
 
-        if(s->t_frame==0) s->t_frame= s->pb_time;
-        if(s->t_frame==0) s->t_frame=1; // 1/0 protection
-        s->pp_field_time= (  ROUNDED_DIV(s->last_non_b_time, s->t_frame)
-                           - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2;
-        s->pb_field_time= (  ROUNDED_DIV(s->time, s->t_frame)
-                           - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2;
-        if(!s->progressive_sequence){
-            if(s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1)
+        if (ctx->t_frame == 0)
+            ctx->t_frame = s->pb_time;
+        if (ctx->t_frame == 0)
+            ctx->t_frame = 1;  // 1/0 protection
+        s->pp_field_time = (ROUNDED_DIV(s->last_non_b_time, ctx->t_frame) -
+                            ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
+        s->pb_field_time = (ROUNDED_DIV(s->time, ctx->t_frame) -
+                            ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
+        if (!s->progressive_sequence) {
+            if (s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1)
                 return FRAME_SKIPPED;
         }
     }
 
-    if(s->avctx->time_base.num)
-        s->current_picture_ptr->f.pts = (s->time + s->avctx->time_base.num / 2) / s->avctx->time_base.num;
-    else
-        s->current_picture_ptr->f.pts = AV_NOPTS_VALUE;
-    if(s->avctx->debug&FF_DEBUG_PTS)
-        av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %"PRId64"\n",
-               s->current_picture_ptr->f.pts);
-
     check_marker(gb, "before vop_coded");
 
     /* vop coded */
-    if (get_bits1(gb) != 1){
-        if(s->avctx->debug&FF_DEBUG_PICT_INFO)
+    if (get_bits1(gb) != 1) {
+        if (s->avctx->debug & FF_DEBUG_PICT_INFO)
             av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n");
         return FRAME_SKIPPED;
     }
-    if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == AV_PICTURE_TYPE_P
-                          || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE))) {
+    if (ctx->shape != BIN_ONLY_SHAPE &&
+                    (s->pict_type == AV_PICTURE_TYPE_P ||
+                     (s->pict_type == AV_PICTURE_TYPE_S &&
+                      ctx->vol_sprite_usage == GMC_SPRITE))) {
         /* rounding type for motion estimation */
         s->no_rounding = get_bits1(gb);
     } else {
         s->no_rounding = 0;
     }
-//FIXME reduced res stuff
-
-     if (s->shape != RECT_SHAPE) {
-         if (s->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) {
-             skip_bits(gb, 13); /* width */
-             skip_bits1(gb);   /* marker */
-             skip_bits(gb, 13); /* height */
-             skip_bits1(gb);   /* marker */
-             skip_bits(gb, 13); /* hor_spat_ref */
-             skip_bits1(gb);   /* marker */
-             skip_bits(gb, 13); /* ver_spat_ref */
-         }
-         skip_bits1(gb); /* change_CR_disable */
-
-         if (get_bits1(gb) != 0) {
-             skip_bits(gb, 8); /* constant_alpha_value */
-         }
-     }
-//FIXME complexity estimation stuff
-
-     if (s->shape != BIN_ONLY_SHAPE) {
-         skip_bits_long(gb, s->cplx_estimation_trash_i);
-         if(s->pict_type != AV_PICTURE_TYPE_I)
-            skip_bits_long(gb, s->cplx_estimation_trash_p);
-         if(s->pict_type == AV_PICTURE_TYPE_B)
-            skip_bits_long(gb, s->cplx_estimation_trash_b);
-
-         s->intra_dc_threshold= ff_mpeg4_dc_threshold[ get_bits(gb, 3) ];
-         if(!s->progressive_sequence){
-             s->top_field_first= get_bits1(gb);
-             s->alternate_scan= get_bits1(gb);
-         }else
-             s->alternate_scan= 0;
-     }
-
-     if(s->alternate_scan){
-         ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_alternate_vertical_scan);
-         ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_alternate_vertical_scan);
-         ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
-         ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
-     } else{
-         ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_zigzag_direct);
-         ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_zigzag_direct);
-         ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
-         ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
-     }
-
-     if(s->pict_type == AV_PICTURE_TYPE_S && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){
-         if (mpeg4_decode_sprite_trajectory(s, gb) < 0)
-             return AVERROR_INVALIDDATA;
-         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");
-     }
-
-     if (s->shape != BIN_ONLY_SHAPE) {
-         s->chroma_qscale= s->qscale = get_bits(gb, s->quant_precision);
-         if(s->qscale==0){
-             av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (qscale=0)\n");
-             return -1; // makes no sense to continue, as there is nothing left from the image then
-         }
-
-         if (s->pict_type != AV_PICTURE_TYPE_I) {
-             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");
-                 return -1; // makes no sense to continue, as the MV decoding will break very quickly
-             }
-         }else
-             s->f_code=1;
-
-         if (s->pict_type == AV_PICTURE_TYPE_B) {
-             s->b_code = get_bits(gb, 3);
-         }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",
-                 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);
-         }
-
-         if(!s->scalability){
-             if (s->shape!=RECT_SHAPE && s->pict_type!=AV_PICTURE_TYPE_I) {
-                 skip_bits1(gb); // vop shape coding type
-             }
-         }else{
-             if(s->enhancement_type){
-                 int load_backward_shape= get_bits1(gb);
-                 if(load_backward_shape){
-                     av_log(s->avctx, AV_LOG_ERROR, "load backward shape isn't supported\n");
-                 }
-             }
-             skip_bits(gb, 2); //ref_select_code
-         }
-     }
-     /* detect buggy encoders which don't set the low_delay flag (divx4/xvid/opendivx)*/
-     // note we cannot detect divx5 without b-frames easily (although it's buggy too)
-     if(s->vo_type==0 && s->vol_control_parameters==0 && s->divx_version==-1 && s->picture_number==0){
-         av_log(s->avctx, AV_LOG_WARNING, "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n");
-         s->low_delay=1;
-     }
-
-     s->picture_number++; // better than pic number==0 always ;)
-
-     s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support
-     s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
-
-     if(s->workaround_bugs&FF_BUG_EDGE){
-         s->h_edge_pos= s->width;
-         s->v_edge_pos= s->height;
-     }
-     return 0;
+    // FIXME reduced res stuff
+
+    if (ctx->shape != RECT_SHAPE) {
+        if (ctx->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) {
+            skip_bits(gb, 13);  /* width */
+            skip_bits1(gb);     /* marker */
+            skip_bits(gb, 13);  /* height */
+            skip_bits1(gb);     /* marker */
+            skip_bits(gb, 13);  /* hor_spat_ref */
+            skip_bits1(gb);     /* marker */
+            skip_bits(gb, 13);  /* ver_spat_ref */
+        }
+        skip_bits1(gb);         /* change_CR_disable */
+
+        if (get_bits1(gb) != 0)
+            skip_bits(gb, 8);   /* constant_alpha_value */
+    }
+
+    // FIXME complexity estimation stuff
+
+    if (ctx->shape != BIN_ONLY_SHAPE) {
+        skip_bits_long(gb, ctx->cplx_estimation_trash_i);
+        if (s->pict_type != AV_PICTURE_TYPE_I)
+            skip_bits_long(gb, ctx->cplx_estimation_trash_p);
+        if (s->pict_type == AV_PICTURE_TYPE_B)
+            skip_bits_long(gb, ctx->cplx_estimation_trash_b);
+
+        ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)];
+        if (!s->progressive_sequence) {
+            s->top_field_first = get_bits1(gb);
+            s->alternate_scan  = get_bits1(gb);
+        } else
+            s->alternate_scan = 0;
+    }
+
+    if (s->alternate_scan) {
+        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable,   ff_alternate_vertical_scan);
+        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable,   ff_alternate_vertical_scan);
+        ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
+        ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
+    } else {
+        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable,   ff_zigzag_direct);
+        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable,   ff_zigzag_direct);
+        ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
+        ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
+    }
+
+    if (s->pict_type == AV_PICTURE_TYPE_S &&
+        (ctx->vol_sprite_usage == STATIC_SPRITE ||
+         ctx->vol_sprite_usage == GMC_SPRITE)) {
+        if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0)
+            return AVERROR_INVALIDDATA;
+        if (ctx->sprite_brightness_change)
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "sprite_brightness_change not supported\n");
+        if (ctx->vol_sprite_usage == STATIC_SPRITE)
+            av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n");
+    }
+
+    if (ctx->shape != BIN_ONLY_SHAPE) {
+        s->chroma_qscale = s->qscale = get_bits(gb, s->quant_precision);
+        if (s->qscale == 0) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Error, header damaged or not MPEG4 header (qscale=0)\n");
+            return -1;  // makes no sense to continue, as there is nothing left from the image then
+        }
+
+        if (s->pict_type != AV_PICTURE_TYPE_I) {
+            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");
+                return -1;  // makes no sense to continue, as there is nothing left from the image then
+            }
+        } else
+            s->f_code = 1;
+
+        if (s->pict_type == AV_PICTURE_TYPE_B) {
+            s->b_code = get_bits(gb, 3);
+        } 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",
+                   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, ctx->resync_marker,
+                   ctx->num_sprite_warping_points, s->sprite_warping_accuracy,
+                   1 - s->no_rounding, s->vo_type,
+                   s->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold,
+                   ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p,
+                   ctx->cplx_estimation_trash_b);
+        }
+
+        if (!ctx->scalability) {
+            if (ctx->shape != RECT_SHAPE && s->pict_type != AV_PICTURE_TYPE_I)
+                skip_bits1(gb);  // vop shape coding type
+        } else {
+            if (ctx->enhancement_type) {
+                int load_backward_shape = get_bits1(gb);
+                if (load_backward_shape)
+                    av_log(s->avctx, AV_LOG_ERROR,
+                           "load backward shape isn't supported\n");
+            }
+            skip_bits(gb, 2);  // ref_select_code
+        }
+    }
+    /* detect buggy encoders which don't set the low_delay flag
+     * (divx4/xvid/opendivx). Note we cannot detect divx5 without b-frames
+     * easily (although it's buggy too) */
+    if (s->vo_type == 0 && s->vol_control_parameters == 0 &&
+        ctx->divx_version == -1 && s->picture_number == 0) {
+        av_log(s->avctx, AV_LOG_WARNING,
+               "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n");
+        s->low_delay = 1;
+    }
+
+    s->picture_number++;  // better than pic number==0 always ;)
+
+    // FIXME add short header support
+    s->y_dc_scale_table = ff_mpeg4_y_dc_scale_table;
+    s->c_dc_scale_table = ff_mpeg4_c_dc_scale_table;
+
+    if (s->workaround_bugs & FF_BUG_EDGE) {
+        s->h_edge_pos = s->width;
+        s->v_edge_pos = s->height;
+    }
+    return 0;
 }
 
 /**
@@ -2109,107 +2292,281 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){
  *         FRAME_SKIPPED if a not coded VOP is found
  *         0 if a VOP is found
  */
-int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb)
+int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb)
 {
+    MpegEncContext *s = &ctx->m;
     unsigned startcode, v;
 
     /* search next start code */
     align_get_bits(gb);
 
-    if(s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630){
+    if (s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630) {
         skip_bits(gb, 24);
-        if(get_bits(gb, 8) == 0xF0)
+        if (get_bits(gb, 8) == 0xF0)
             goto end;
     }
 
     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)){
+    for (;;) {
+        if (get_bits_count(gb) >= gb->size_in_bits) {
+            if (gb->size_in_bits == 8 &&
+                (ctx->divx_version >= 0 || ctx->xvid_build >= 0)) {
                 av_log(s->avctx, AV_LOG_WARNING, "frame skip %d\n", gb->size_in_bits);
-                return FRAME_SKIPPED; //divx bug
-            }else
-                return -1; //end of stream
+                return FRAME_SKIPPED;  // divx bug
+            } else
+                return -1;  // end of stream
         }
 
         /* use the bits after the test */
         v = get_bits(gb, 8);
         startcode = ((startcode << 8) | v) & 0xffffffff;
 
-        if((startcode&0xFFFFFF00) != 0x100)
-            continue; //no startcode
+        if ((startcode & 0xFFFFFF00) != 0x100)
+            continue;  // no startcode
 
-        if(s->avctx->debug&FF_DEBUG_STARTCODE){
+        if (s->avctx->debug & FF_DEBUG_STARTCODE) {
             av_log(s->avctx, AV_LOG_DEBUG, "startcode: %3X ", startcode);
-            if     (startcode<=0x11F) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start");
-            else if(startcode<=0x12F) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start");
-            else if(startcode<=0x13F) av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
-            else if(startcode<=0x15F) av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start");
-            else if(startcode<=0x1AF) av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
-            else if(startcode==0x1B0) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start");
-            else if(startcode==0x1B1) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End");
-            else if(startcode==0x1B2) av_log(s->avctx, AV_LOG_DEBUG, "User Data");
-            else if(startcode==0x1B3) av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start");
-            else if(startcode==0x1B4) av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error");
-            else if(startcode==0x1B5) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start");
-            else if(startcode==0x1B6) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start");
-            else if(startcode==0x1B7) av_log(s->avctx, AV_LOG_DEBUG, "slice start");
-            else if(startcode==0x1B8) av_log(s->avctx, AV_LOG_DEBUG, "extension start");
-            else if(startcode==0x1B9) av_log(s->avctx, AV_LOG_DEBUG, "fgs start");
-            else if(startcode==0x1BA) av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start");
-            else if(startcode==0x1BB) av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start");
-            else if(startcode==0x1BC) av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start");
-            else if(startcode==0x1BD) av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start");
-            else if(startcode==0x1BE) av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start");
-            else if(startcode==0x1BF) av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start");
-            else if(startcode==0x1C0) av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start");
-            else if(startcode==0x1C1) av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start");
-            else if(startcode==0x1C2) av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start");
-            else if(startcode==0x1C3) av_log(s->avctx, AV_LOG_DEBUG, "stuffing start");
-            else if(startcode<=0x1C5) av_log(s->avctx, AV_LOG_DEBUG, "reserved");
-            else if(startcode<=0x1FF) av_log(s->avctx, AV_LOG_DEBUG, "System start");
+            if (startcode <= 0x11F)
+                av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start");
+            else if (startcode <= 0x12F)
+                av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start");
+            else if (startcode <= 0x13F)
+                av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
+            else if (startcode <= 0x15F)
+                av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start");
+            else if (startcode <= 0x1AF)
+                av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
+            else if (startcode == 0x1B0)
+                av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start");
+            else if (startcode == 0x1B1)
+                av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End");
+            else if (startcode == 0x1B2)
+                av_log(s->avctx, AV_LOG_DEBUG, "User Data");
+            else if (startcode == 0x1B3)
+                av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start");
+            else if (startcode == 0x1B4)
+                av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error");
+            else if (startcode == 0x1B5)
+                av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start");
+            else if (startcode == 0x1B6)
+                av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start");
+            else if (startcode == 0x1B7)
+                av_log(s->avctx, AV_LOG_DEBUG, "slice start");
+            else if (startcode == 0x1B8)
+                av_log(s->avctx, AV_LOG_DEBUG, "extension start");
+            else if (startcode == 0x1B9)
+                av_log(s->avctx, AV_LOG_DEBUG, "fgs start");
+            else if (startcode == 0x1BA)
+                av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start");
+            else if (startcode == 0x1BB)
+                av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start");
+            else if (startcode == 0x1BC)
+                av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start");
+            else if (startcode == 0x1BD)
+                av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start");
+            else if (startcode == 0x1BE)
+                av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start");
+            else if (startcode == 0x1BF)
+                av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start");
+            else if (startcode == 0x1C0)
+                av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start");
+            else if (startcode == 0x1C1)
+                av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start");
+            else if (startcode == 0x1C2)
+                av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start");
+            else if (startcode == 0x1C3)
+                av_log(s->avctx, AV_LOG_DEBUG, "stuffing start");
+            else if (startcode <= 0x1C5)
+                av_log(s->avctx, AV_LOG_DEBUG, "reserved");
+            else if (startcode <= 0x1FF)
+                av_log(s->avctx, AV_LOG_DEBUG, "System start");
             av_log(s->avctx, AV_LOG_DEBUG, " at %d\n", get_bits_count(gb));
         }
 
-        if(startcode >= 0x120 && startcode <= 0x12F){
-            if(decode_vol_header(s, gb) < 0)
+        if (startcode >= 0x120 && startcode <= 0x12F) {
+            if (decode_vol_header(ctx, gb) < 0)
                 return -1;
-        }
-        else if(startcode == USER_DATA_STARTCODE){
-            decode_user_data(s, gb);
-        }
-        else if(startcode == GOP_STARTCODE){
+        } else if (startcode == USER_DATA_STARTCODE) {
+            decode_user_data(ctx, gb);
+        } else if (startcode == GOP_STARTCODE) {
             mpeg4_decode_gop_header(s, gb);
-        }
-        else if(startcode == VOS_STARTCODE){
+        } else if (startcode == VOS_STARTCODE) {
             mpeg4_decode_profile_level(s, gb);
-        }
-        else if(startcode == VOP_STARTCODE){
+        } else if (startcode == VOP_STARTCODE) {
             break;
         }
 
         align_get_bits(gb);
         startcode = 0xff;
     }
+
 end:
-    if(s->flags& CODEC_FLAG_LOW_DELAY)
-        s->low_delay=1;
-    s->avctx->has_b_frames= !s->low_delay;
-    return decode_vop_header(s, gb);
+    if (s->flags & CODEC_FLAG_LOW_DELAY)
+        s->low_delay = 1;
+    s->avctx->has_b_frames = !s->low_delay;
+
+    if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1) {
+        if (s->stream_codec_tag == AV_RL32("XVID") ||
+            s->codec_tag        == AV_RL32("XVID") ||
+            s->codec_tag        == AV_RL32("XVIX") ||
+            s->codec_tag        == AV_RL32("RMP4") ||
+            s->codec_tag        == AV_RL32("ZMP4") ||
+            s->codec_tag        == AV_RL32("SIPP"))
+            ctx->xvid_build = 0;
+    }
+
+    if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1)
+        if (s->codec_tag == AV_RL32("DIVX") && s->vo_type == 0 &&
+            s->vol_control_parameters == 0)
+            ctx->divx_version = 400;  // divx 4
+
+    if (ctx->xvid_build >= 0 && ctx->divx_version >= 0) {
+        ctx->divx_version =
+        ctx->divx_build   = -1;
+    }
+
+    if (s->workaround_bugs & FF_BUG_AUTODETECT) {
+        if (s->codec_tag == AV_RL32("XVIX"))
+            s->workaround_bugs |= FF_BUG_XVID_ILACE;
+
+        if (s->codec_tag == AV_RL32("UMP4"))
+            s->workaround_bugs |= FF_BUG_UMP4;
+
+        if (ctx->divx_version >= 500 && ctx->divx_build < 1814)
+            s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
+        if (ctx->divx_version > 502 && ctx->divx_build < 1814)
+            s->workaround_bugs |= FF_BUG_QPEL_CHROMA2;
+
+        if (ctx->xvid_build <= 3U)
+            s->padding_bug_score = 256 * 256 * 256 * 64;
+
+        if (ctx->xvid_build <= 1U)
+            s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
+        if (ctx->xvid_build <= 12U)
+            s->workaround_bugs |= FF_BUG_EDGE;
+
+        if (ctx->xvid_build <= 32U)
+            s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+        if (ctx->lavc_build < 4653U)
+            s->workaround_bugs |= FF_BUG_STD_QPEL;
+
+        if (ctx->lavc_build < 4655U)
+            s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+
+        if (ctx->lavc_build < 4670U)
+            s->workaround_bugs |= FF_BUG_EDGE;
+
+        if (ctx->lavc_build <= 4712U)
+            s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+        if (ctx->divx_version >= 0)
+            s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+
+        if (ctx->divx_version == 501 && ctx->divx_build == 20020416)
+            s->padding_bug_score = 256 * 256 * 256 * 64;
+
+        if (ctx->divx_version < 500U)
+            s->workaround_bugs |= FF_BUG_EDGE;
+
+        if (ctx->divx_version >= 0)
+            s->workaround_bugs |= FF_BUG_HPEL_CHROMA;
+    }
+
+#if HAVE_MMX
+    if (s->codec_id == AV_CODEC_ID_MPEG4 && ctx->xvid_build >= 0 &&
+        s->avctx->idct_algo == FF_IDCT_AUTO &&
+        (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
+        s->avctx->idct_algo = FF_IDCT_XVIDMMX;
+        ff_dct_common_init(s);
+        s->picture_number = 0;
+    }
+#endif
+
+    if (s->avctx->debug & FF_DEBUG_BUGS)
+        av_log(s->avctx, AV_LOG_DEBUG,
+               "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
+               s->workaround_bugs, ctx->lavc_build, ctx->xvid_build,
+               ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : "");
+
+    return decode_vop_header(ctx, gb);
+}
+
+int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
+{
+    Mpeg4DecContext *ctx = avctx->priv_data;
+    MpegEncContext    *s = &ctx->m;
+
+    /* divx 5.01+ bistream reorder stuff */
+    if (s->divx_packed) {
+        int current_pos     = get_bits_count(&s->gb) >> 3;
+        int startcode_found = 0;
+
+        if (buf_size - current_pos > 5) {
+            int i;
+            for (i = current_pos; i < buf_size - 3; i++)
+                if (buf[i]     == 0 &&
+                    buf[i + 1] == 0 &&
+                    buf[i + 2] == 1 &&
+                    buf[i + 3] == 0xB6) {
+                    startcode_found = 1;
+                    break;
+                }
+        }
+        if (s->gb.buffer == s->bitstream_buffer && buf_size > 7 &&
+            ctx->xvid_build >= 0) {       // xvid style
+            startcode_found = 1;
+            current_pos     = 0;
+        }
+
+        if (startcode_found) {
+            av_fast_malloc(&s->bitstream_buffer,
+                           &s->allocated_bitstream_buffer_size,
+                           buf_size - current_pos +
+                           FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!s->bitstream_buffer)
+                return AVERROR(ENOMEM);
+            memcpy(s->bitstream_buffer, buf + current_pos,
+                   buf_size - current_pos);
+            s->bitstream_buffer_size = buf_size - current_pos;
+        }
+    }
+
+    return 0;
+}
+
+static int mpeg4_update_thread_context(AVCodecContext *dst,
+                                       const AVCodecContext *src)
+{
+    Mpeg4DecContext *s = dst->priv_data;
+    const Mpeg4DecContext *s1 = src->priv_data;
+
+    int ret = ff_mpeg_update_thread_context(dst, src);
+
+    if (ret < 0)
+        return ret;
+
+    s->shape               = s1->shape;
+    s->time_increment_bits = s1->time_increment_bits;
+
+    return 0;
 }
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
-    MpegEncContext *s = avctx->priv_data;
+    Mpeg4DecContext *ctx = avctx->priv_data;
+    MpegEncContext *s = &ctx->m;
     int ret;
     static int done = 0;
 
-    s->divx_version=
-    s->divx_build=
-    s->xvid_build=
-    s->lavc_build= -1;
+    ctx->divx_version =
+    ctx->divx_build   =
+    ctx->xvid_build   =
+    ctx->lavc_build   = -1;
 
-    if((ret=ff_h263_decode_init(avctx)) < 0)
+    if ((ret = ff_h263_decode_init(avctx)) < 0)
         return ret;
 
     if (!done) {
@@ -2222,24 +2579,26 @@ static av_cold int decode_init(AVCodecContext *avctx)
         INIT_VLC_RL(ff_rvlc_rl_inter, 1072);
         INIT_VLC_RL(ff_rvlc_rl_intra, 1072);
         INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */,
-                 &ff_mpeg4_DCtab_lum[0][1], 2, 1,
-                 &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512);
+                        &ff_mpeg4_DCtab_lum[0][1], 2, 1,
+                        &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512);
         INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */,
-                 &ff_mpeg4_DCtab_chrom[0][1], 2, 1,
-                 &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512);
+                        &ff_mpeg4_DCtab_chrom[0][1], 2, 1,
+                        &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512);
         INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15,
-                 &ff_sprite_trajectory_tab[0][1], 4, 2,
-                 &ff_sprite_trajectory_tab[0][0], 4, 2, 128);
+                        &ff_sprite_trajectory_tab[0][1], 4, 2,
+                        &ff_sprite_trajectory_tab[0][0], 4, 2, 128);
         INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4,
-                 &ff_mb_type_b_tab[0][1], 2, 1,
-                 &ff_mb_type_b_tab[0][0], 2, 1, 16);
+                        &ff_mb_type_b_tab[0][1], 2, 1,
+                        &ff_mb_type_b_tab[0][0], 2, 1, 16);
     }
 
     s->h263_pred = 1;
-    s->low_delay = 0; //default, might be overriden in the vol header during header parsing
-    s->decode_mb= mpeg4_decode_mb;
-    s->time_increment_bits = 4; /* default value for broken headers */
+    s->low_delay = 0; /* default, might be overriden in the vol header during header parsing */
+    s->decode_mb = mpeg4_decode_mb;
+    ctx->time_increment_bits = 4; /* default value for broken headers */
+
     avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
+    avctx->internal->allocate_progress = 1;
 
     return 0;
 }
@@ -2265,9 +2624,10 @@ static const AVProfile mpeg4_video_profiles[] = {
 
 AVCodec ff_mpeg4_decoder = {
     .name                  = "mpeg4",
+    .long_name             = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
     .type                  = AVMEDIA_TYPE_VIDEO,
     .id                    = AV_CODEC_ID_MPEG4,
-    .priv_data_size        = sizeof(MpegEncContext),
+    .priv_data_size        = sizeof(Mpeg4DecContext),
     .init                  = decode_init,
     .close                 = ff_h263_decode_end,
     .decode                = ff_h263_decode_frame,
@@ -2275,26 +2635,7 @@ AVCodec ff_mpeg4_decoder = {
                              CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
                              CODEC_CAP_FRAME_THREADS,
     .flush                 = ff_mpeg_flush,
-    .long_name             = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
-    .pix_fmts              = ff_hwaccel_pixfmt_list_420,
+    .pix_fmts              = ff_h263_hwaccel_pixfmt_list_420,
     .profiles              = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles),
-    .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context),
+    .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context),
 };
-
-
-#if CONFIG_MPEG4_VDPAU_DECODER
-AVCodec ff_mpeg4_vdpau_decoder = {
-    .name           = "mpeg4_vdpau",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MPEG4,
-    .priv_data_size = sizeof(MpegEncContext),
-    .init           = decode_init,
-    .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
-    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
-                      CODEC_CAP_HWACCEL_VDPAU,
-    .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 },
-};
-#endif
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 986cba6..0063f58 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -20,69 +20,73 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "mpegvideo.h"
 #include "h263.h"
 #include "mpeg4video.h"
 
-//The uni_DCtab_* tables below contain unified bits+length tables to encode DC
-//differences in mpeg4. Unified in the sense that the specification specifies
-//this encoding in several steps.
-static uint8_t uni_DCtab_lum_len[512];
-static uint8_t uni_DCtab_chrom_len[512];
+/* The uni_DCtab_* tables below contain unified bits+length tables to encode DC
+ * differences in mpeg4. Unified in the sense that the specification specifies
+ * this encoding in several steps. */
+static uint8_t  uni_DCtab_lum_len[512];
+static uint8_t  uni_DCtab_chrom_len[512];
 static uint16_t uni_DCtab_lum_bits[512];
 static uint16_t uni_DCtab_chrom_bits[512];
 
-//unified encoding tables for run length encoding of coefficients
-//unified in the sense that the specification specifies the encoding in several steps.
-static uint32_t uni_mpeg4_intra_rl_bits[64*64*2*2];
-static uint8_t  uni_mpeg4_intra_rl_len [64*64*2*2];
-static uint32_t uni_mpeg4_inter_rl_bits[64*64*2*2];
-static uint8_t  uni_mpeg4_inter_rl_len [64*64*2*2];
-//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level))
-//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64)
-#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level))
+/* Unified encoding tables for run length encoding of coefficients.
+ * Unified in the sense that the specification specifies the encoding in several steps. */
+static uint32_t uni_mpeg4_intra_rl_bits[64 * 64 * 2 * 2];
+static uint8_t  uni_mpeg4_intra_rl_len[64 * 64 * 2 * 2];
+static uint32_t uni_mpeg4_inter_rl_bits[64 * 64 * 2 * 2];
+static uint8_t  uni_mpeg4_inter_rl_len[64 * 64 * 2 * 2];
 
-/* mpeg4
-inter
-max level: 24/6
-max run: 53/63
-
-intra
-max level: 53/16
-max run: 29/41
-*/
+//#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 + (run) * 256 + (level))
+//#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 * 64 + (run) + (level) * 64)
+#define UNI_MPEG4_ENC_INDEX(last, run, level) ((last) * 128 * 64 + (run) * 128 + (level))
 
+/* mpeg4
+ * inter
+ * max level: 24/6
+ * max run: 53/63
+ *
+ * intra
+ * max level: 53/16
+ * max run: 29/41
+ */
 
 /**
  * Return the number of bits that encoding the 8x8 block in block would need.
  * @param[in]  block_last_index last index in scantable order that refers to a non zero element in block.
  */
-static inline int get_block_rate(MpegEncContext * s, DCTELEM block[64], int block_last_index, uint8_t scantable[64]){
-    int last=0;
+static inline int get_block_rate(MpegEncContext *s, int16_t block[64],
+                                 int block_last_index, uint8_t scantable[64])
+{
+    int last = 0;
     int j;
-    int rate=0;
-
-    for(j=1; j<=block_last_index; j++){
-        const int index= scantable[j];
-        int level= block[index];
-        if(level){
-            level+= 64;
-            if((level&(~127)) == 0){
-                if(j<block_last_index) rate+= s->intra_ac_vlc_length     [UNI_AC_ENC_INDEX(j-last-1, level)];
-                else                   rate+= s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j-last-1, level)];
-            }else
+    int rate = 0;
+
+    for (j = 1; j <= block_last_index; j++) {
+        const int index = scantable[j];
+        int level = block[index];
+        if (level) {
+            level += 64;
+            if ((level & (~127)) == 0) {
+                if (j < block_last_index)
+                    rate += s->intra_ac_vlc_length[UNI_AC_ENC_INDEX(j - last - 1, level)];
+                else
+                    rate += s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j - last - 1, level)];
+            } else
                 rate += s->ac_esc_length;
 
-            last= j;
+            last = j;
         }
     }
 
     return rate;
 }
 
-
 /**
  * Restore the ac coefficients in block that have been changed by decide_ac_pred().
  * This function also restores s->block_last_index.
@@ -91,25 +95,25 @@ static inline int get_block_rate(MpegEncContext * s, DCTELEM block[64], int bloc
  * @param[out] st scantable for each 8x8 block
  * @param[in] zigzag_last_index index referring to the last non zero coefficient in zigzag order
  */
-static inline void restore_ac_coeffs(MpegEncContext * s, DCTELEM block[6][64], const int dir[6], uint8_t *st[6], const int zigzag_last_index[6])
+static inline void restore_ac_coeffs(MpegEncContext *s, int16_t block[6][64],
+                                     const int dir[6], uint8_t *st[6],
+                                     const int zigzag_last_index[6])
 {
     int i, n;
-    memcpy(s->block_last_index, zigzag_last_index, sizeof(int)*6);
+    memcpy(s->block_last_index, zigzag_last_index, sizeof(int) * 6);
 
-    for(n=0; n<6; n++){
+    for (n = 0; n < 6; n++) {
         int16_t *ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
 
-        st[n]= s->intra_scantable.permutated;
-        if(dir[n]){
+        st[n] = s->intra_scantable.permutated;
+        if (dir[n]) {
             /* top prediction */
-            for(i=1; i<8; i++){
-                block[n][s->dsp.idct_permutation[i   ]] = ac_val[i+8];
-            }
-        }else{
+            for (i = 1; i < 8; i++)
+                block[n][s->dsp.idct_permutation[i]] = ac_val[i + 8];
+        } else {
             /* left prediction */
-            for(i=1; i<8; i++){
-                block[n][s->dsp.idct_permutation[i<<3]]= ac_val[i  ];
-            }
+            for (i = 1; i < 8; i++)
+                block[n][s->dsp.idct_permutation[i << 3]] = ac_val[i];
         }
     }
 }
@@ -122,77 +126,81 @@ static inline void restore_ac_coeffs(MpegEncContext * s, DCTELEM block[6][64], c
  * @param[out] st scantable for each 8x8 block
  * @param[out] zigzag_last_index index referring to the last non zero coefficient in zigzag order
  */
-static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], const int dir[6], uint8_t *st[6], int zigzag_last_index[6])
+static inline int decide_ac_pred(MpegEncContext *s, int16_t block[6][64],
+                                 const int dir[6], uint8_t *st[6],
+                                 int zigzag_last_index[6])
 {
-    int score= 0;
+    int score = 0;
     int i, n;
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t *const qscale_table = s->current_picture.qscale_table;
 
-    memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6);
+    memcpy(zigzag_last_index, s->block_last_index, sizeof(int) * 6);
 
-    for(n=0; n<6; n++){
+    for (n = 0; n < 6; n++) {
         int16_t *ac_val, *ac_val1;
 
-        score -= get_block_rate(s, block[n], s->block_last_index[n], s->intra_scantable.permutated);
+        score -= get_block_rate(s, block[n], s->block_last_index[n],
+                                s->intra_scantable.permutated);
 
-        ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
-        ac_val1= ac_val;
-        if(dir[n]){
-            const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride;
+        ac_val  = s->ac_val[0][0] + s->block_index[n] * 16;
+        ac_val1 = ac_val;
+        if (dir[n]) {
+            const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;
             /* top prediction */
-            ac_val-= s->block_wrap[n]*16;
-            if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){
+            ac_val -= s->block_wrap[n] * 16;
+            if (s->mb_y == 0 || s->qscale == qscale_table[xy] || n == 2 || n == 3) {
                 /* same qscale */
-                for(i=1; i<8; i++){
-                    const int level= block[n][s->dsp.idct_permutation[i   ]];
-                    block[n][s->dsp.idct_permutation[i   ]] = level - ac_val[i+8];
-                    ac_val1[i  ]=    block[n][s->dsp.idct_permutation[i<<3]];
-                    ac_val1[i+8]= level;
+                for (i = 1; i < 8; i++) {
+                    const int level = block[n][s->dsp.idct_permutation[i]];
+                    block[n][s->dsp.idct_permutation[i]] = level - ac_val[i + 8];
+                    ac_val1[i]     = block[n][s->dsp.idct_permutation[i << 3]];
+                    ac_val1[i + 8] = level;
                 }
-            }else{
+            } else {
                 /* different qscale, we must rescale */
-                for(i=1; i<8; i++){
-                    const int level= block[n][s->dsp.idct_permutation[i   ]];
-                    block[n][s->dsp.idct_permutation[i   ]] = level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale);
-                    ac_val1[i  ]=    block[n][s->dsp.idct_permutation[i<<3]];
-                    ac_val1[i+8]= level;
+                for (i = 1; i < 8; i++) {
+                    const int level = block[n][s->dsp.idct_permutation[i]];
+                    block[n][s->dsp.idct_permutation[i]] = level - ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
+                    ac_val1[i]     = block[n][s->dsp.idct_permutation[i << 3]];
+                    ac_val1[i + 8] = level;
                 }
             }
-            st[n]= s->intra_h_scantable.permutated;
-        }else{
-            const int xy= s->mb_x-1 + s->mb_y*s->mb_stride;
+            st[n] = s->intra_h_scantable.permutated;
+        } else {
+            const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride;
             /* left prediction */
-            ac_val-= 16;
-            if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){
+            ac_val -= 16;
+            if (s->mb_x == 0 || s->qscale == qscale_table[xy] || n == 1 || n == 3) {
                 /* same qscale */
-                for(i=1; i<8; i++){
-                    const int level= block[n][s->dsp.idct_permutation[i<<3]];
-                    block[n][s->dsp.idct_permutation[i<<3]]= level - ac_val[i];
-                    ac_val1[i  ]= level;
-                    ac_val1[i+8]=    block[n][s->dsp.idct_permutation[i   ]];
+                for (i = 1; i < 8; i++) {
+                    const int level = block[n][s->dsp.idct_permutation[i << 3]];
+                    block[n][s->dsp.idct_permutation[i << 3]] = level - ac_val[i];
+                    ac_val1[i]     = level;
+                    ac_val1[i + 8] = block[n][s->dsp.idct_permutation[i]];
                 }
-            }else{
+            } else {
                 /* different qscale, we must rescale */
-                for(i=1; i<8; i++){
-                    const int level= block[n][s->dsp.idct_permutation[i<<3]];
-                    block[n][s->dsp.idct_permutation[i<<3]]= level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale);
-                    ac_val1[i  ]= level;
-                    ac_val1[i+8]=    block[n][s->dsp.idct_permutation[i   ]];
+                for (i = 1; i < 8; i++) {
+                    const int level = block[n][s->dsp.idct_permutation[i << 3]];
+                    block[n][s->dsp.idct_permutation[i << 3]] = level - ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
+                    ac_val1[i]     = level;
+                    ac_val1[i + 8] = block[n][s->dsp.idct_permutation[i]];
                 }
             }
-            st[n]= s->intra_v_scantable.permutated;
+            st[n] = s->intra_v_scantable.permutated;
         }
 
-        for(i=63; i>0; i--) //FIXME optimize
-            if(block[n][ st[n][i] ]) break;
-        s->block_last_index[n]= i;
+        for (i = 63; i > 0; i--)  // FIXME optimize
+            if (block[n][st[n][i]])
+                break;
+        s->block_last_index[n] = i;
 
         score += get_block_rate(s, block[n], s->block_last_index[n], st[n]);
     }
 
-    if(score < 0){
+    if (score < 0) {
         return 1;
-    }else{
+    } else {
         restore_ac_coeffs(s, block, dir, st, zigzag_last_index);
         return 0;
     }
@@ -201,51 +209,55 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], const
 /**
  * modify mb_type & qscale so that encoding is acually possible in mpeg4
  */
-void ff_clean_mpeg4_qscales(MpegEncContext *s){
+void ff_clean_mpeg4_qscales(MpegEncContext *s)
+{
     int i;
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t *const qscale_table = s->current_picture.qscale_table;
 
     ff_clean_h263_qscales(s);
 
-    if(s->pict_type== AV_PICTURE_TYPE_B){
-        int odd=0;
-        /* ok, come on, this isn't funny anymore, there's more code for handling this mpeg4 mess than for the actual adaptive quantization */
+    if (s->pict_type == AV_PICTURE_TYPE_B) {
+        int odd = 0;
+        /* ok, come on, this isn't funny anymore, there's more code for
+         * handling this mpeg4 mess than for the actual adaptive quantization */
 
-        for(i=0; i<s->mb_num; i++){
-            int mb_xy= s->mb_index2xy[i];
-            odd += qscale_table[mb_xy]&1;
+        for (i = 0; i < s->mb_num; i++) {
+            int mb_xy = s->mb_index2xy[i];
+            odd += qscale_table[mb_xy] & 1;
         }
 
-        if(2*odd > s->mb_num) odd=1;
-        else                  odd=0;
+        if (2 * odd > s->mb_num)
+            odd = 1;
+        else
+            odd = 0;
 
-        for(i=0; i<s->mb_num; i++){
-            int mb_xy= s->mb_index2xy[i];
-            if((qscale_table[mb_xy]&1) != odd)
+        for (i = 0; i < s->mb_num; i++) {
+            int mb_xy = s->mb_index2xy[i];
+            if ((qscale_table[mb_xy] & 1) != odd)
                 qscale_table[mb_xy]++;
-            if(qscale_table[mb_xy] > 31)
-                qscale_table[mb_xy]= 31;
+            if (qscale_table[mb_xy] > 31)
+                qscale_table[mb_xy] = 31;
         }
 
-        for(i=1; i<s->mb_num; i++){
-            int mb_xy= s->mb_index2xy[i];
-            if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){
-                s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR;
+        for (i = 1; i < s->mb_num; i++) {
+            int mb_xy = s->mb_index2xy[i];
+            if (qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i - 1]] &&
+                (s->mb_type[mb_xy] & CANDIDATE_MB_TYPE_DIRECT)) {
+                s->mb_type[mb_xy] |= CANDIDATE_MB_TYPE_BIDIR;
             }
         }
     }
 }
 
-
 /**
  * Encode the dc value.
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n)
+static inline void mpeg4_encode_dc(PutBitContext *s, int level, int n)
 {
 #if 1
     /* DC will overflow if level is outside the [-255,255] range. */
-    level+=256;
+    level += 256;
     if (n < 4) {
         /* luminance */
         put_bits(s, uni_DCtab_lum_len[level], uni_DCtab_lum_bits[level]);
@@ -257,7 +269,7 @@ static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n)
     int size, v;
     /* find number of bits */
     size = 0;
-    v = abs(level);
+    v    = abs(level);
     while (v) {
         v >>= 1;
         size++;
@@ -282,85 +294,98 @@ static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n)
 #endif
 }
 
-static inline int mpeg4_get_dc_length(int level, int n){
-    if (n < 4) {
+static inline int mpeg4_get_dc_length(int level, int n)
+{
+    if (n < 4)
         return uni_DCtab_lum_len[level + 256];
-    } else {
+    else
         return uni_DCtab_chrom_len[level + 256];
-    }
 }
 
 /**
  * Encode an 8x8 block.
  * @param n block index (0-3 are luma, 4-5 are chroma)
  */
-static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc,
-                               uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb)
+static inline void mpeg4_encode_block(MpegEncContext *s,
+                                      int16_t *block, int n, int intra_dc,
+                                      uint8_t *scan_table, PutBitContext *dc_pb,
+                                      PutBitContext *ac_pb)
 {
     int i, last_non_zero;
     uint32_t *bits_tab;
     uint8_t *len_tab;
     const int last_index = s->block_last_index[n];
 
-    if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away
+    if (s->mb_intra) {  // Note gcc (3.2.1 at least) will optimize this away
         /* mpeg4 based DC predictor */
         mpeg4_encode_dc(dc_pb, intra_dc, n);
-        if(last_index<1) return;
+        if (last_index < 1)
+            return;
         i = 1;
-        bits_tab= uni_mpeg4_intra_rl_bits;
-        len_tab = uni_mpeg4_intra_rl_len;
+        bits_tab = uni_mpeg4_intra_rl_bits;
+        len_tab  = uni_mpeg4_intra_rl_len;
     } else {
-        if(last_index<0) return;
+        if (last_index < 0)
+            return;
         i = 0;
-        bits_tab= uni_mpeg4_inter_rl_bits;
-        len_tab = uni_mpeg4_inter_rl_len;
+        bits_tab = uni_mpeg4_inter_rl_bits;
+        len_tab  = uni_mpeg4_inter_rl_len;
     }
 
     /* AC coefs */
     last_non_zero = i - 1;
     for (; i < last_index; i++) {
-        int level = block[ scan_table[i] ];
+        int level = block[scan_table[i]];
         if (level) {
             int run = i - last_non_zero - 1;
-            level+=64;
-            if((level&(~127)) == 0){
-                const int index= UNI_MPEG4_ENC_INDEX(0, run, level);
+            level += 64;
+            if ((level & (~127)) == 0) {
+                const int index = UNI_MPEG4_ENC_INDEX(0, run, level);
                 put_bits(ac_pb, len_tab[index], bits_tab[index]);
-            }else{ //ESC3
-                put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1);
+            } else {  // ESC3
+                put_bits(ac_pb,
+                         7 + 2 + 1 + 6 + 1 + 12 + 1,
+                         (3 << 23) + (3 << 21) + (0 << 20) + (run << 14) +
+                         (1 << 13) + (((level - 64) & 0xfff) << 1) + 1);
             }
             last_non_zero = i;
         }
     }
-    /*if(i<=last_index)*/{
-        int level = block[ scan_table[i] ];
-        int run = i - last_non_zero - 1;
-        level+=64;
-        if((level&(~127)) == 0){
-            const int index= UNI_MPEG4_ENC_INDEX(1, run, level);
+    /* if (i <= last_index) */ {
+        int level = block[scan_table[i]];
+        int run   = i - last_non_zero - 1;
+        level += 64;
+        if ((level & (~127)) == 0) {
+            const int index = UNI_MPEG4_ENC_INDEX(1, run, level);
             put_bits(ac_pb, len_tab[index], bits_tab[index]);
-        }else{ //ESC3
-            put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1);
+        } else {  // ESC3
+            put_bits(ac_pb,
+                     7 + 2 + 1 + 6 + 1 + 12 + 1,
+                     (3 << 23) + (3 << 21) + (1 << 20) + (run << 14) +
+                     (1 << 13) + (((level - 64) & 0xfff) << 1) + 1);
         }
     }
 }
 
-static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc,
-                               uint8_t *scan_table)
+static int mpeg4_get_block_length(MpegEncContext *s,
+                                  int16_t *block, int n,
+                                  int intra_dc, uint8_t *scan_table)
 {
     int i, last_non_zero;
     uint8_t *len_tab;
     const int last_index = s->block_last_index[n];
-    int len=0;
+    int len = 0;
 
-    if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away
+    if (s->mb_intra) {  // Note gcc (3.2.1 at least) will optimize this away
         /* mpeg4 based DC predictor */
         len += mpeg4_get_dc_length(intra_dc, n);
-        if(last_index<1) return len;
+        if (last_index < 1)
+            return len;
         i = 1;
         len_tab = uni_mpeg4_intra_rl_len;
     } else {
-        if(last_index<0) return 0;
+        if (last_index < 0)
+            return 0;
         i = 0;
         len_tab = uni_mpeg4_inter_rl_len;
     }
@@ -368,82 +393,88 @@ static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, in
     /* AC coefs */
     last_non_zero = i - 1;
     for (; i < last_index; i++) {
-        int level = block[ scan_table[i] ];
+        int level = block[scan_table[i]];
         if (level) {
             int run = i - last_non_zero - 1;
-            level+=64;
-            if((level&(~127)) == 0){
-                const int index= UNI_MPEG4_ENC_INDEX(0, run, level);
+            level += 64;
+            if ((level & (~127)) == 0) {
+                const int index = UNI_MPEG4_ENC_INDEX(0, run, level);
                 len += len_tab[index];
-            }else{ //ESC3
-                len += 7+2+1+6+1+12+1;
+            } else {  // ESC3
+                len += 7 + 2 + 1 + 6 + 1 + 12 + 1;
             }
             last_non_zero = i;
         }
     }
-    /*if(i<=last_index)*/{
-        int level = block[ scan_table[i] ];
-        int run = i - last_non_zero - 1;
-        level+=64;
-        if((level&(~127)) == 0){
-            const int index= UNI_MPEG4_ENC_INDEX(1, run, level);
+    /* if (i <= last_index) */ {
+        int level = block[scan_table[i]];
+        int run   = i - last_non_zero - 1;
+        level += 64;
+        if ((level & (~127)) == 0) {
+            const int index = UNI_MPEG4_ENC_INDEX(1, run, level);
             len += len_tab[index];
-        }else{ //ESC3
-            len += 7+2+1+6+1+12+1;
+        } else {  // ESC3
+            len += 7 + 2 + 1 + 6 + 1 + 12 + 1;
         }
     }
 
     return len;
 }
 
-static inline void mpeg4_encode_blocks(MpegEncContext * s, DCTELEM block[6][64], int intra_dc[6],
-                               uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){
+static inline void mpeg4_encode_blocks(MpegEncContext *s, int16_t block[6][64],
+                                       int intra_dc[6], uint8_t **scan_table,
+                                       PutBitContext *dc_pb,
+                                       PutBitContext *ac_pb)
+{
     int i;
 
-    if(scan_table){
-        if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){
-            for (i = 0; i < 6; i++) {
-                skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, intra_dc[i], scan_table[i]));
-            }
-        }else{
+    if (scan_table) {
+        if (s->flags2 & CODEC_FLAG2_NO_OUTPUT) {
+            for (i = 0; i < 6; i++)
+                skip_put_bits(&s->pb,
+                              mpeg4_get_block_length(s, block[i], i,
+                                                     intra_dc[i], scan_table[i]));
+        } else {
             /* encode each block */
-            for (i = 0; i < 6; i++) {
-                mpeg4_encode_block(s, block[i], i, intra_dc[i], scan_table[i], dc_pb, ac_pb);
-            }
+            for (i = 0; i < 6; i++)
+                mpeg4_encode_block(s, block[i], i,
+                                   intra_dc[i], scan_table[i], dc_pb, ac_pb);
         }
-    }else{
-        if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){
-            for (i = 0; i < 6; i++) {
-                skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, 0, s->intra_scantable.permutated));
-            }
-        }else{
+    } else {
+        if (s->flags2 & CODEC_FLAG2_NO_OUTPUT) {
+            for (i = 0; i < 6; i++)
+                skip_put_bits(&s->pb,
+                              mpeg4_get_block_length(s, block[i], i, 0,
+                                                     s->intra_scantable.permutated));
+        } else {
             /* encode each block */
-            for (i = 0; i < 6; i++) {
-                mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, dc_pb, ac_pb);
-            }
+            for (i = 0; i < 6; i++)
+                mpeg4_encode_block(s, block[i], i, 0,
+                                   s->intra_scantable.permutated, dc_pb, ac_pb);
         }
     }
 }
 
-static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64],
+static inline int get_b_cbp(MpegEncContext *s, int16_t block[6][64],
                             int motion_x, int motion_y, int mb_type)
 {
     int cbp = 0, i;
 
     if (s->mpv_flags & FF_MPV_FLAG_CBP_RD) {
-        int score = 0;
+        int score        = 0;
         const int lambda = s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
 
-        for (i = 0; i < 6; i++)
+        for (i = 0; i < 6; i++) {
             if (s->coded_score[i] < 0) {
                 score += s->coded_score[i];
                 cbp   |= 1 << (5 - i);
             }
+        }
 
         if (cbp) {
             int zero_score = -6;
             if ((motion_x | motion_y | s->dquant | mb_type) == 0)
-                zero_score -= 4; //2*MV + mb_type + cbp bit
+                zero_score -= 4;  // 2 * MV + mb_type + cbp bit
 
             zero_score *= lambda;
             if (zero_score <= score)
@@ -465,62 +496,61 @@ static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64],
     return cbp;
 }
 
-//FIXME this is duplicated to h263.c
-static const int dquant_code[5]= {1,0,9,2,3};
+// FIXME this is duplicated to h263.c
+static const int dquant_code[5] = { 1, 0, 9, 2, 3 };
 
-void ff_mpeg4_encode_mb(MpegEncContext * s,
-                        DCTELEM block[6][64],
+void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64],
                         int motion_x, int motion_y)
 {
     int cbpc, cbpy, pred_x, pred_y;
-    PutBitContext * const pb2    = s->data_partitioning                         ? &s->pb2    : &s->pb;
-    PutBitContext * const tex_pb = s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B ? &s->tex_pb : &s->pb;
-    PutBitContext * const dc_pb  = s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_I ? &s->pb2    : &s->pb;
-    const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0;
+    PutBitContext *const pb2    = s->data_partitioning ? &s->pb2 : &s->pb;
+    PutBitContext *const tex_pb = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B ? &s->tex_pb : &s->pb;
+    PutBitContext *const dc_pb  = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_I ? &s->pb2 : &s->pb;
+    const int interleaved_stats = (s->flags & CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0;
 
     if (!s->mb_intra) {
         int i, cbp;
 
-        if(s->pict_type==AV_PICTURE_TYPE_B){
-            static const int mb_type_table[8]= {-1, 3, 2, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */
-            int mb_type=  mb_type_table[s->mv_dir];
-
-            if(s->mb_x==0){
-                for(i=0; i<2; i++){
-                    s->last_mv[i][0][0]=
-                    s->last_mv[i][0][1]=
-                    s->last_mv[i][1][0]=
-                    s->last_mv[i][1][1]= 0;
-                }
+        if (s->pict_type == AV_PICTURE_TYPE_B) {
+            /* convert from mv_dir to type */
+            static const int mb_type_table[8] = { -1, 3, 2, 1, -1, -1, -1, 0 };
+            int mb_type = mb_type_table[s->mv_dir];
+
+            if (s->mb_x == 0) {
+                for (i = 0; i < 2; i++)
+                    s->last_mv[i][0][0] =
+                    s->last_mv[i][0][1] =
+                    s->last_mv[i][1][0] =
+                    s->last_mv[i][1][1] = 0;
             }
 
-            assert(s->dquant>=-2 && s->dquant<=2);
-            assert((s->dquant&1)==0);
-            assert(mb_type>=0);
+            assert(s->dquant >= -2 && s->dquant <= 2);
+            assert((s->dquant & 1) == 0);
+            assert(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 & ...
+            if (s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) {  // FIXME avoid DCT & ...
                 s->skip_count++;
-                s->mv[0][0][0]=
-                s->mv[0][0][1]=
-                s->mv[1][0][0]=
-                s->mv[1][0][1]= 0;
-                s->mv_dir= MV_DIR_FORWARD; //doesn't matter
+                s->mv[0][0][0] =
+                s->mv[0][0][1] =
+                s->mv[1][0][0] =
+                s->mv[1][0][1] = 0;
+                s->mv_dir  = MV_DIR_FORWARD;  // doesn't matter
                 s->qscale -= s->dquant;
-//                s->mb_skipped=1;
+//                s->mb_skipped = 1;
 
                 return;
             }
 
-            cbp= get_b_cbp(s, block, motion_x, motion_y, mb_type);
+            cbp = get_b_cbp(s, block, motion_x, motion_y, mb_type);
 
-            if ((cbp | motion_x | motion_y | mb_type) ==0) {
+            if ((cbp | motion_x | motion_y | mb_type) == 0) {
                 /* direct MB with MV={0,0} */
-                assert(s->dquant==0);
+                assert(s->dquant == 0);
 
                 put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */
 
-                if(interleaved_stats){
+                if (interleaved_stats) {
                     s->misc_bits++;
                     s->last_bits++;
                 }
@@ -528,137 +558,150 @@ void ff_mpeg4_encode_mb(MpegEncContext * s,
                 return;
             }
 
-            put_bits(&s->pb, 1, 0);     /* mb coded modb1=0 */
-            put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge
-            put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we don't need it :)
-            if(cbp) put_bits(&s->pb, 6, cbp);
+            put_bits(&s->pb, 1, 0);            /* mb coded modb1=0 */
+            put_bits(&s->pb, 1, cbp ? 0 : 1);  /* modb2 */ // FIXME merge
+            put_bits(&s->pb, mb_type + 1, 1);  // this table is so simple that we don't need it :)
+            if (cbp)
+                put_bits(&s->pb, 6, cbp);
 
-            if(cbp && mb_type){
-                if(s->dquant)
-                    put_bits(&s->pb, 2, (s->dquant>>2)+3);
+            if (cbp && mb_type) {
+                if (s->dquant)
+                    put_bits(&s->pb, 2, (s->dquant >> 2) + 3);
                 else
                     put_bits(&s->pb, 1, 0);
-            }else
+            } else
                 s->qscale -= s->dquant;
 
-            if(!s->progressive_sequence){
-                if(cbp)
+            if (!s->progressive_sequence) {
+                if (cbp)
                     put_bits(&s->pb, 1, s->interlaced_dct);
-                if(mb_type) // not direct mode
+                if (mb_type)                  // not direct mode
                     put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD);
             }
 
-            if(interleaved_stats){
-                s->misc_bits+= get_bits_diff(s);
-            }
+            if (interleaved_stats)
+                s->misc_bits += get_bits_diff(s);
 
-            if(mb_type == 0){
+            if (!mb_type) {
                 assert(s->mv_dir & MV_DIRECT);
                 ff_h263_encode_motion_vector(s, motion_x, motion_y, 1);
                 s->b_count++;
                 s->f_count++;
-            }else{
+            } else {
                 assert(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],
-                                                        s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);
-                        s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0];
-                        s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1];
+                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],
+                                                     s->mv[0][0][1] - s->last_mv[0][0][1],
+                                                     s->f_code);
+                        s->last_mv[0][0][0] =
+                        s->last_mv[0][1][0] = s->mv[0][0][0];
+                        s->last_mv[0][0][1] =
+                        s->last_mv[0][1][1] = s->mv[0][0][1];
                         s->f_count++;
                     }
-                    if(s->mv_dir & MV_DIR_BACKWARD){
-                        ff_h263_encode_motion_vector(s, s->mv[1][0][0] - s->last_mv[1][0][0],
-                                                        s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);
-                        s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0];
-                        s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1];
+                    if (s->mv_dir & MV_DIR_BACKWARD) {
+                        ff_h263_encode_motion_vector(s,
+                                                     s->mv[1][0][0] - s->last_mv[1][0][0],
+                                                     s->mv[1][0][1] - s->last_mv[1][0][1],
+                                                     s->b_code);
+                        s->last_mv[1][0][0] =
+                        s->last_mv[1][1][0] = s->mv[1][0][0];
+                        s->last_mv[1][0][1] =
+                        s->last_mv[1][1][1] = s->mv[1][0][1];
                         s->b_count++;
                     }
-                }else{
-                    if(s->mv_dir & MV_DIR_FORWARD){
+                } else {
+                    if (s->mv_dir & MV_DIR_FORWARD) {
                         put_bits(&s->pb, 1, s->field_select[0][0]);
                         put_bits(&s->pb, 1, s->field_select[0][1]);
                     }
-                    if(s->mv_dir & MV_DIR_BACKWARD){
+                    if (s->mv_dir & MV_DIR_BACKWARD) {
                         put_bits(&s->pb, 1, s->field_select[1][0]);
                         put_bits(&s->pb, 1, s->field_select[1][1]);
                     }
-                    if(s->mv_dir & MV_DIR_FORWARD){
-                        for(i=0; i<2; i++){
-                            ff_h263_encode_motion_vector(s, s->mv[0][i][0] - s->last_mv[0][i][0]  ,
-                                                            s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code);
-                            s->last_mv[0][i][0]= s->mv[0][i][0];
-                            s->last_mv[0][i][1]= s->mv[0][i][1]*2;
+                    if (s->mv_dir & MV_DIR_FORWARD) {
+                        for (i = 0; i < 2; i++) {
+                            ff_h263_encode_motion_vector(s,
+                                                         s->mv[0][i][0] - s->last_mv[0][i][0],
+                                                         s->mv[0][i][1] - s->last_mv[0][i][1] / 2,
+                                                         s->f_code);
+                            s->last_mv[0][i][0] = s->mv[0][i][0];
+                            s->last_mv[0][i][1] = s->mv[0][i][1] * 2;
                         }
                         s->f_count++;
                     }
-                    if(s->mv_dir & MV_DIR_BACKWARD){
-                        for(i=0; i<2; i++){
-                            ff_h263_encode_motion_vector(s, s->mv[1][i][0] - s->last_mv[1][i][0]  ,
-                                                            s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code);
-                            s->last_mv[1][i][0]= s->mv[1][i][0];
-                            s->last_mv[1][i][1]= s->mv[1][i][1]*2;
+                    if (s->mv_dir & MV_DIR_BACKWARD) {
+                        for (i = 0; i < 2; i++) {
+                            ff_h263_encode_motion_vector(s,
+                                                         s->mv[1][i][0] - s->last_mv[1][i][0],
+                                                         s->mv[1][i][1] - s->last_mv[1][i][1] / 2,
+                                                         s->b_code);
+                            s->last_mv[1][i][0] = s->mv[1][i][0];
+                            s->last_mv[1][i][1] = s->mv[1][i][1] * 2;
                         }
                         s->b_count++;
                     }
                 }
             }
 
-            if(interleaved_stats){
-                s->mv_bits+= get_bits_diff(s);
-            }
+            if (interleaved_stats)
+                s->mv_bits += get_bits_diff(s);
 
             mpeg4_encode_blocks(s, block, NULL, NULL, NULL, &s->pb);
 
-            if(interleaved_stats){
-                s->p_tex_bits+= get_bits_diff(s);
-            }
-
-        }else{ /* s->pict_type==AV_PICTURE_TYPE_B */
-            cbp= get_p_cbp(s, block, motion_x, motion_y);
-
-            if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) {
-                /* check if the B frames can skip it too, as we must skip it if we skip here
-                   why didn't they just compress the skip-mb bits instead of reusing them ?! */
-                if(s->max_b_frames>0){
+            if (interleaved_stats)
+                s->p_tex_bits += get_bits_diff(s);
+        } else { /* s->pict_type==AV_PICTURE_TYPE_B */
+            cbp = get_p_cbp(s, block, motion_x, motion_y);
+
+            if ((cbp | motion_x | motion_y | s->dquant) == 0 &&
+                s->mv_type == MV_TYPE_16X16) {
+                /* check if the B frames can skip it too, as we must skip it
+                 * if we skip here why didn't they just compress
+                 * the skip-mb bits instead of reusing them ?! */
+                if (s->max_b_frames > 0) {
                     int i;
-                    int x,y, offset;
+                    int x, y, offset;
                     uint8_t *p_pic;
 
-                    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;
+                    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;
+                    offset = x + y * s->linesize;
+                    p_pic  = s->new_picture.f.data[0] + offset;
 
-                    s->mb_skipped=1;
-                    for(i=0; i<s->max_b_frames; i++){
+                    s->mb_skipped = 1;
+                    for (i = 0; i < s->max_b_frames; i++) {
                         uint8_t *b_pic;
                         int diff;
-                        Picture *pic= s->reordered_input_picture[i+1];
+                        Picture *pic = s->reordered_input_picture[i + 1];
 
-                        if (pic == NULL || pic->f.pict_type != AV_PICTURE_TYPE_B)
+                        if (!pic || pic->f.pict_type != AV_PICTURE_TYPE_B)
                             break;
 
                         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(diff>s->qscale*70){ //FIXME check that 70 is optimal
-                            s->mb_skipped=0;
+                        if (!pic->shared)
+                            b_pic += INPLACE_OFFSET;
+                        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;
                         }
                     }
-                }else
-                    s->mb_skipped=1;
+                } else
+                    s->mb_skipped = 1;
 
-                if(s->mb_skipped==1){
+                if (s->mb_skipped == 1) {
                     /* skip macroblock */
                     put_bits(&s->pb, 1, 1);
 
-                    if(interleaved_stats){
+                    if (interleaved_stats) {
                         s->misc_bits++;
                         s->last_bits++;
                     }
@@ -669,162 +712,164 @@ void ff_mpeg4_encode_mb(MpegEncContext * s,
             }
 
             put_bits(&s->pb, 1, 0);     /* mb coded */
-            cbpc = cbp & 3;
-            cbpy = cbp >> 2;
+            cbpc  = cbp & 3;
+            cbpy  = cbp >> 2;
             cbpy ^= 0xf;
-            if(s->mv_type==MV_TYPE_16X16){
-                if(s->dquant) cbpc+= 8;
+            if (s->mv_type == MV_TYPE_16X16) {
+                if (s->dquant)
+                    cbpc += 8;
                 put_bits(&s->pb,
-                        ff_h263_inter_MCBPC_bits[cbpc],
-                        ff_h263_inter_MCBPC_code[cbpc]);
+                         ff_h263_inter_MCBPC_bits[cbpc],
+                         ff_h263_inter_MCBPC_code[cbpc]);
 
                 put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
-                if(s->dquant)
-                    put_bits(pb2, 2, dquant_code[s->dquant+2]);
+                if (s->dquant)
+                    put_bits(pb2, 2, dquant_code[s->dquant + 2]);
 
-                if(!s->progressive_sequence){
-                    if(cbp)
+                if (!s->progressive_sequence) {
+                    if (cbp)
                         put_bits(pb2, 1, s->interlaced_dct);
                     put_bits(pb2, 1, 0);
                 }
 
-                if(interleaved_stats){
-                    s->misc_bits+= get_bits_diff(s);
-                }
+                if (interleaved_stats)
+                    s->misc_bits += get_bits_diff(s);
 
                 /* motion vectors: 16x16 mode */
                 ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
 
-                ff_h263_encode_motion_vector(s, motion_x - pred_x,
-                                                motion_y - pred_y, s->f_code);
-            }else if(s->mv_type==MV_TYPE_FIELD){
-                if(s->dquant) cbpc+= 8;
+                ff_h263_encode_motion_vector(s,
+                                             motion_x - pred_x,
+                                             motion_y - pred_y,
+                                             s->f_code);
+            } else if (s->mv_type == MV_TYPE_FIELD) {
+                if (s->dquant)
+                    cbpc += 8;
                 put_bits(&s->pb,
-                        ff_h263_inter_MCBPC_bits[cbpc],
-                        ff_h263_inter_MCBPC_code[cbpc]);
+                         ff_h263_inter_MCBPC_bits[cbpc],
+                         ff_h263_inter_MCBPC_code[cbpc]);
 
                 put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
-                if(s->dquant)
-                    put_bits(pb2, 2, dquant_code[s->dquant+2]);
+                if (s->dquant)
+                    put_bits(pb2, 2, dquant_code[s->dquant + 2]);
 
                 assert(!s->progressive_sequence);
-                if(cbp)
+                if (cbp)
                     put_bits(pb2, 1, s->interlaced_dct);
                 put_bits(pb2, 1, 1);
 
-                if(interleaved_stats){
-                    s->misc_bits+= get_bits_diff(s);
-                }
+                if (interleaved_stats)
+                    s->misc_bits += get_bits_diff(s);
 
                 /* motion vectors: 16x8 interlaced mode */
                 ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
-                pred_y /=2;
+                pred_y /= 2;
 
                 put_bits(&s->pb, 1, s->field_select[0][0]);
                 put_bits(&s->pb, 1, s->field_select[0][1]);
 
-                ff_h263_encode_motion_vector(s, s->mv[0][0][0] - pred_x,
-                                                s->mv[0][0][1] - pred_y, s->f_code);
-                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);
+                ff_h263_encode_motion_vector(s,
+                                             s->mv[0][0][0] - pred_x,
+                                             s->mv[0][0][1] - pred_y,
+                                             s->f_code);
+                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);
                 put_bits(&s->pb,
-                        ff_h263_inter_MCBPC_bits[cbpc+16],
-                        ff_h263_inter_MCBPC_code[cbpc+16]);
+                         ff_h263_inter_MCBPC_bits[cbpc + 16],
+                         ff_h263_inter_MCBPC_code[cbpc + 16]);
                 put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
 
-                if(!s->progressive_sequence){
-                    if(cbp)
-                        put_bits(pb2, 1, s->interlaced_dct);
-                }
+                if (!s->progressive_sequence && cbp)
+                    put_bits(pb2, 1, s->interlaced_dct);
 
-                if(interleaved_stats){
-                    s->misc_bits+= get_bits_diff(s);
-                }
+                if (interleaved_stats)
+                    s->misc_bits += get_bits_diff(s);
 
-                for(i=0; i<4; i++){
+                for (i = 0; i < 4; i++) {
                     /* motion vectors: 8x8 mode*/
                     ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
 
-                    ff_h263_encode_motion_vector(s, s->current_picture.f.motion_val[0][ s->block_index[i] ][0] - pred_x,
-                                                    s->current_picture.f.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code);
+                    ff_h263_encode_motion_vector(s,
+                                                 s->current_picture.motion_val[0][s->block_index[i]][0] - pred_x,
+                                                 s->current_picture.motion_val[0][s->block_index[i]][1] - pred_y,
+                                                 s->f_code);
                 }
             }
 
-            if(interleaved_stats){
-                s->mv_bits+= get_bits_diff(s);
-            }
+            if (interleaved_stats)
+                s->mv_bits += get_bits_diff(s);
 
             mpeg4_encode_blocks(s, block, NULL, NULL, NULL, tex_pb);
 
-            if(interleaved_stats){
-                s->p_tex_bits+= get_bits_diff(s);
-            }
+            if (interleaved_stats)
+                s->p_tex_bits += get_bits_diff(s);
+
             s->f_count++;
         }
     } else {
         int cbp;
-        int dc_diff[6];   //dc values with the dc prediction subtracted
-        int dir[6];  //prediction direction
+        int dc_diff[6];  // dc values with the dc prediction subtracted
+        int dir[6];      // prediction direction
         int zigzag_last_index[6];
         uint8_t *scan_table[6];
         int i;
 
-        for(i=0; i<6; i++){
-            dc_diff[i]= ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1);
-        }
+        for (i = 0; i < 6; i++)
+            dc_diff[i] = ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1);
 
-        if(s->flags & CODEC_FLAG_AC_PRED){
-            s->ac_pred= decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);
-        }else{
-            for(i=0; i<6; i++)
-                scan_table[i]= s->intra_scantable.permutated;
+        if (s->flags & CODEC_FLAG_AC_PRED) {
+            s->ac_pred = decide_ac_pred(s, block, dir, scan_table, zigzag_last_index);
+        } else {
+            for (i = 0; i < 6; i++)
+                scan_table[i] = s->intra_scantable.permutated;
         }
 
         /* compute cbp */
         cbp = 0;
-        for (i = 0; i < 6; i++) {
+        for (i = 0; i < 6; i++)
             if (s->block_last_index[i] >= 1)
                 cbp |= 1 << (5 - i);
-        }
 
         cbpc = cbp & 3;
         if (s->pict_type == AV_PICTURE_TYPE_I) {
-            if(s->dquant) cbpc+=4;
+            if (s->dquant)
+                cbpc += 4;
             put_bits(&s->pb,
-                ff_h263_intra_MCBPC_bits[cbpc],
-                ff_h263_intra_MCBPC_code[cbpc]);
+                     ff_h263_intra_MCBPC_bits[cbpc],
+                     ff_h263_intra_MCBPC_code[cbpc]);
         } else {
-            if(s->dquant) cbpc+=8;
+            if (s->dquant)
+                cbpc += 8;
             put_bits(&s->pb, 1, 0);     /* mb coded */
             put_bits(&s->pb,
-                ff_h263_inter_MCBPC_bits[cbpc + 4],
-                ff_h263_inter_MCBPC_code[cbpc + 4]);
+                     ff_h263_inter_MCBPC_bits[cbpc + 4],
+                     ff_h263_inter_MCBPC_code[cbpc + 4]);
         }
         put_bits(pb2, 1, s->ac_pred);
         cbpy = cbp >> 2;
         put_bits(pb2, ff_h263_cbpy_tab[cbpy][1], ff_h263_cbpy_tab[cbpy][0]);
-        if(s->dquant)
-            put_bits(dc_pb, 2, dquant_code[s->dquant+2]);
+        if (s->dquant)
+            put_bits(dc_pb, 2, dquant_code[s->dquant + 2]);
 
-        if(!s->progressive_sequence){
+        if (!s->progressive_sequence)
             put_bits(dc_pb, 1, s->interlaced_dct);
-        }
 
-        if(interleaved_stats){
-            s->misc_bits+= get_bits_diff(s);
-        }
+        if (interleaved_stats)
+            s->misc_bits += get_bits_diff(s);
 
         mpeg4_encode_blocks(s, block, dc_diff, scan_table, dc_pb, tex_pb);
 
-        if(interleaved_stats){
-            s->i_tex_bits+= get_bits_diff(s);
-        }
+        if (interleaved_stats)
+            s->i_tex_bits += get_bits_diff(s);
         s->i_count++;
 
-        /* restore ac coeffs & last_index stuff if we messed them up with the prediction */
-        if(s->ac_pred)
+        /* restore ac coeffs & last_index stuff
+         * if we messed them up with the prediction */
+        if (s->ac_pred)
             restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index);
     }
 }
@@ -832,25 +877,28 @@ void ff_mpeg4_encode_mb(MpegEncContext * s,
 /**
  * add mpeg4 stuffing bits (01...1)
  */
-void ff_mpeg4_stuffing(PutBitContext * pbc)
+void ff_mpeg4_stuffing(PutBitContext *pbc)
 {
     int length;
     put_bits(pbc, 1, 0);
-    length= (-put_bits_count(pbc))&7;
-    if(length) put_bits(pbc, length, (1<<length)-1);
+    length = (-put_bits_count(pbc)) & 7;
+    if (length)
+        put_bits(pbc, length, (1 << length) - 1);
 }
 
 /* must be called before writing the header */
-void ff_set_mpeg4_time(MpegEncContext * s){
-    if(s->pict_type==AV_PICTURE_TYPE_B){
+void ff_set_mpeg4_time(MpegEncContext *s)
+{
+    if (s->pict_type == AV_PICTURE_TYPE_B) {
         ff_mpeg4_init_direct_mv(s);
-    }else{
-        s->last_time_base= s->time_base;
-        s->time_base= s->time/s->avctx->time_base.den;
+    } else {
+        s->last_time_base = s->time_base;
+        s->time_base      = s->time / s->avctx->time_base.den;
     }
 }
 
-static void mpeg4_encode_gop_header(MpegEncContext * s){
+static void mpeg4_encode_gop_header(MpegEncContext *s)
+{
     int hours, minutes, seconds;
     int64_t time;
 
@@ -858,53 +906,54 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){
     put_bits(&s->pb, 16, GOP_STARTCODE);
 
     time = s->current_picture_ptr->f.pts;
-    if(s->reordered_input_picture[1])
+    if (s->reordered_input_picture[1])
         time = FFMIN(time, s->reordered_input_picture[1]->f.pts);
-    time= time*s->avctx->time_base.num;
+    time = time * s->avctx->time_base.num;
 
-    seconds= time/s->avctx->time_base.den;
-    minutes= seconds/60; seconds %= 60;
-    hours= minutes/60; minutes %= 60;
-    hours%=24;
+    seconds  = time / s->avctx->time_base.den;
+    minutes  = seconds / 60;
+    seconds %= 60;
+    hours    = minutes / 60;
+    minutes %= 60;
+    hours   %= 24;
 
     put_bits(&s->pb, 5, hours);
     put_bits(&s->pb, 6, minutes);
     put_bits(&s->pb, 1, 1);
     put_bits(&s->pb, 6, seconds);
 
-    put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP));
-    put_bits(&s->pb, 1, 0); //broken link == NO
+    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;
+    s->last_time_base = time / s->avctx->time_base.den;
 
     ff_mpeg4_stuffing(&s->pb);
 }
 
-static void mpeg4_encode_visual_object_header(MpegEncContext * s){
+static void mpeg4_encode_visual_object_header(MpegEncContext *s)
+{
     int profile_and_level_indication;
     int vo_ver_id;
 
-    if(s->avctx->profile != FF_PROFILE_UNKNOWN){
+    if (s->avctx->profile != FF_PROFILE_UNKNOWN) {
         profile_and_level_indication = s->avctx->profile << 4;
-    }else if(s->max_b_frames || s->quarter_sample){
-        profile_and_level_indication= 0xF0; // adv simple
-    }else{
-        profile_and_level_indication= 0x00; // simple
+    } else if (s->max_b_frames || s->quarter_sample) {
+        profile_and_level_indication = 0xF0;  // adv simple
+    } else {
+        profile_and_level_indication = 0x00;  // simple
     }
 
-    if(s->avctx->level != FF_LEVEL_UNKNOWN){
+    if (s->avctx->level != FF_LEVEL_UNKNOWN)
         profile_and_level_indication |= s->avctx->level;
-    }else{
-        profile_and_level_indication |= 1; //level 1
-    }
+    else
+        profile_and_level_indication |= 1;   // level 1
 
-    if(profile_and_level_indication>>4 == 0xF){
-        vo_ver_id= 5;
-    }else{
-        vo_ver_id= 1;
-    }
+    if (profile_and_level_indication >> 4 == 0xF)
+        vo_ver_id = 5;
+    else
+        vo_ver_id = 1;
 
-    //FIXME levels
+    // FIXME levels
 
     put_bits(&s->pb, 16, 0);
     put_bits(&s->pb, 16, VOS_STARTCODE);
@@ -915,28 +964,31 @@ static void mpeg4_encode_visual_object_header(MpegEncContext * s){
     put_bits(&s->pb, 16, VISUAL_OBJ_STARTCODE);
 
     put_bits(&s->pb, 1, 1);
-        put_bits(&s->pb, 4, vo_ver_id);
-        put_bits(&s->pb, 3, 1); //priority
+    put_bits(&s->pb, 4, vo_ver_id);
+    put_bits(&s->pb, 3, 1);     // priority
 
-    put_bits(&s->pb, 4, 1); //visual obj type== video obj
+    put_bits(&s->pb, 4, 1);     // visual obj type== video obj
 
-    put_bits(&s->pb, 1, 0); //video signal type == no clue //FIXME
+    put_bits(&s->pb, 1, 0);     // video signal type == no clue // FIXME
 
     ff_mpeg4_stuffing(&s->pb);
 }
 
-static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number)
+static void mpeg4_encode_vol_header(MpegEncContext *s,
+                                    int vo_number,
+                                    int vol_number)
 {
     int vo_ver_id;
 
-    if (!CONFIG_MPEG4_ENCODER)  return;
+    if (!CONFIG_MPEG4_ENCODER)
+        return;
 
-    if(s->max_b_frames || s->quarter_sample){
-        vo_ver_id= 5;
-        s->vo_type= ADV_SIMPLE_VO_TYPE;
-    }else{
-        vo_ver_id= 1;
-        s->vo_type= SIMPLE_VO_TYPE;
+    if (s->max_b_frames || s->quarter_sample) {
+        vo_ver_id  = 5;
+        s->vo_type = ADV_SIMPLE_VO_TYPE;
+    } else {
+        vo_ver_id  = 1;
+        s->vo_type = SIMPLE_VO_TYPE;
     }
 
     put_bits(&s->pb, 16, 0);
@@ -946,7 +998,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n
 
     put_bits(&s->pb, 1, 0);             /* random access vol */
     put_bits(&s->pb, 8, s->vo_type);    /* video obj type indication */
-    if(s->workaround_bugs & FF_BUG_MS) {
+    if (s->workaround_bugs & FF_BUG_MS) {
         put_bits(&s->pb, 1, 0);         /* is obj layer id= no */
     } else {
         put_bits(&s->pb, 1, 1);         /* is obj layer id= yes */
@@ -954,15 +1006,15 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n
         put_bits(&s->pb, 3, 1);         /* is obj layer priority */
     }
 
-    s->aspect_ratio_info= ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio);
+    s->aspect_ratio_info = ff_h263_aspect_to_info(s->avctx->sample_aspect_ratio);
 
-    put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */
-    if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){
+    put_bits(&s->pb, 4, s->aspect_ratio_info); /* aspect ratio info */
+    if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
         put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num);
         put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den);
     }
 
-    if(s->workaround_bugs & FF_BUG_MS) { //
+    if (s->workaround_bugs & FF_BUG_MS) {
         put_bits(&s->pb, 1, 0);         /* vol control parameters= no @@@ */
     } else {
         put_bits(&s->pb, 1, 1);         /* vol control parameters= yes */
@@ -986,16 +1038,15 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n
     put_bits(&s->pb, 1, 1);             /* marker bit */
     put_bits(&s->pb, 1, s->progressive_sequence ? 0 : 1);
     put_bits(&s->pb, 1, 1);             /* obmc disable */
-    if (vo_ver_id == 1) {
-        put_bits(&s->pb, 1, s->vol_sprite_usage);       /* sprite enable */
-    }else{
-        put_bits(&s->pb, 2, s->vol_sprite_usage);       /* sprite enable */
-    }
+    if (vo_ver_id == 1)
+        put_bits(&s->pb, 1, 0);       /* sprite enable */
+    else
+        put_bits(&s->pb, 2, 0);       /* sprite enable */
 
     put_bits(&s->pb, 1, 0);             /* not 8 bit == false */
     put_bits(&s->pb, 1, s->mpeg_quant); /* quant type= (0=h263 style)*/
 
-    if(s->mpeg_quant){
+    if (s->mpeg_quant) {
         ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix);
         ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix);
     }
@@ -1003,14 +1054,12 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n
     if (vo_ver_id != 1)
         put_bits(&s->pb, 1, s->quarter_sample);
     put_bits(&s->pb, 1, 1);             /* complexity estimation disable */
-    s->resync_marker= s->rtp_mode;
-    put_bits(&s->pb, 1, s->resync_marker ? 0 : 1);/* resync marker disable */
+    put_bits(&s->pb, 1, s->rtp_mode ? 0 : 1); /* resync marker disable */
     put_bits(&s->pb, 1, s->data_partitioning ? 1 : 0);
-    if(s->data_partitioning){
+    if (s->data_partitioning)
         put_bits(&s->pb, 1, 0);         /* no rvlc */
-    }
 
-    if (vo_ver_id != 1){
+    if (vo_ver_id != 1) {
         put_bits(&s->pb, 1, 0);         /* newpred */
         put_bits(&s->pb, 1, 0);         /* reduced res vop */
     }
@@ -1019,7 +1068,7 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n
     ff_mpeg4_stuffing(&s->pb);
 
     /* user data */
-    if(!(s->flags & CODEC_FLAG_BITEXACT)){
+    if (!(s->flags & CODEC_FLAG_BITEXACT)) {
         put_bits(&s->pb, 16, 0);
         put_bits(&s->pb, 16, 0x1B2);    /* user_data */
         avpriv_put_string(&s->pb, LIBAVCODEC_IDENT, 0);
@@ -1027,34 +1076,34 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n
 }
 
 /* write mpeg4 VOP header */
-void ff_mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
+void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number)
 {
     int time_incr;
     int time_div, time_mod;
 
-    if(s->pict_type==AV_PICTURE_TYPE_I){
-        if(!(s->flags&CODEC_FLAG_GLOBAL_HEADER)){
-            if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) //HACK, the reference sw is buggy
+    if (s->pict_type == AV_PICTURE_TYPE_I) {
+        if (!(s->flags & CODEC_FLAG_GLOBAL_HEADER)) {
+            if (s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT)  // HACK, the reference sw is buggy
                 mpeg4_encode_visual_object_header(s);
-            if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number==0) //HACK, the reference sw is buggy
+            if (s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number == 0)  // HACK, the reference sw is buggy
                 mpeg4_encode_vol_header(s, 0, 0);
         }
-        if(!(s->workaround_bugs & FF_BUG_MS))
+        if (!(s->workaround_bugs & FF_BUG_MS))
             mpeg4_encode_gop_header(s);
     }
 
-    s->partitioned_frame= s->data_partitioning && s->pict_type!=AV_PICTURE_TYPE_B;
+    s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;
 
     put_bits(&s->pb, 16, 0);                /* vop header */
     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_incr= time_div - s->last_time_base;
+    assert(s->time >= 0);
+    time_div  = s->time / s->avctx->time_base.den;
+    time_mod  = s->time % s->avctx->time_base.den;
+    time_incr = time_div - s->last_time_base;
     assert(time_incr >= 0);
-    while(time_incr--)
+    while (time_incr--)
         put_bits(&s->pb, 1, 1);
 
     put_bits(&s->pb, 1, 0);
@@ -1063,153 +1112,168 @@ void ff_mpeg4_encode_picture_header(MpegEncContext * s, int picture_number)
     put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */
     put_bits(&s->pb, 1, 1);                             /* marker */
     put_bits(&s->pb, 1, 1);                             /* vop coded */
-    if (    s->pict_type == AV_PICTURE_TYPE_P
-        || (s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE)) {
+    if (s->pict_type == AV_PICTURE_TYPE_P) {
         put_bits(&s->pb, 1, s->no_rounding);    /* rounding type */
     }
     put_bits(&s->pb, 3, 0);     /* intra dc VLC threshold */
-    if(!s->progressive_sequence){
-         put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first);
-         put_bits(&s->pb, 1, s->alternate_scan);
+    if (!s->progressive_sequence) {
+        put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first);
+        put_bits(&s->pb, 1, s->alternate_scan);
     }
-    //FIXME sprite stuff
+    // FIXME sprite stuff
 
     put_bits(&s->pb, 5, s->qscale);
 
     if (s->pict_type != AV_PICTURE_TYPE_I)
-        put_bits(&s->pb, 3, s->f_code); /* fcode_for */
+        put_bits(&s->pb, 3, s->f_code);  /* fcode_for */
     if (s->pict_type == AV_PICTURE_TYPE_B)
-        put_bits(&s->pb, 3, s->b_code); /* fcode_back */
+        put_bits(&s->pb, 3, s->b_code);  /* fcode_back */
 }
 
-
-static void init_uni_dc_tab(void)
+static av_cold void init_uni_dc_tab(void)
 {
     int level, uni_code, uni_len;
 
-    for(level=-256; level<256; level++){
+    for (level = -256; level < 256; level++) {
         int size, v, l;
         /* find number of bits */
         size = 0;
-        v = abs(level);
+        v    = abs(level);
         while (v) {
             v >>= 1;
             size++;
         }
 
         if (level < 0)
-            l= (-level) ^ ((1 << size) - 1);
+            l = (-level) ^ ((1 << size) - 1);
         else
-            l= level;
+            l = level;
 
         /* luminance */
-        uni_code= ff_mpeg4_DCtab_lum[size][0];
-        uni_len = ff_mpeg4_DCtab_lum[size][1];
+        uni_code = ff_mpeg4_DCtab_lum[size][0];
+        uni_len  = ff_mpeg4_DCtab_lum[size][1];
 
         if (size > 0) {
-            uni_code<<=size; uni_code|=l;
-            uni_len+=size;
-            if (size > 8){
-                uni_code<<=1; uni_code|=1;
+            uni_code <<= size;
+            uni_code  |= l;
+            uni_len   += size;
+            if (size > 8) {
+                uni_code <<= 1;
+                uni_code  |= 1;
                 uni_len++;
             }
         }
-        uni_DCtab_lum_bits[level+256]= uni_code;
-        uni_DCtab_lum_len [level+256]= uni_len;
+        uni_DCtab_lum_bits[level + 256] = uni_code;
+        uni_DCtab_lum_len[level + 256]  = uni_len;
 
         /* chrominance */
-        uni_code= ff_mpeg4_DCtab_chrom[size][0];
-        uni_len = ff_mpeg4_DCtab_chrom[size][1];
+        uni_code = ff_mpeg4_DCtab_chrom[size][0];
+        uni_len  = ff_mpeg4_DCtab_chrom[size][1];
 
         if (size > 0) {
-            uni_code<<=size; uni_code|=l;
-            uni_len+=size;
-            if (size > 8){
-                uni_code<<=1; uni_code|=1;
+            uni_code <<= size;
+            uni_code  |= l;
+            uni_len   += size;
+            if (size > 8) {
+                uni_code <<= 1;
+                uni_code  |= 1;
                 uni_len++;
             }
         }
-        uni_DCtab_chrom_bits[level+256]= uni_code;
-        uni_DCtab_chrom_len [level+256]= uni_len;
-
+        uni_DCtab_chrom_bits[level + 256] = uni_code;
+        uni_DCtab_chrom_len[level + 256]  = uni_len;
     }
 }
 
-static void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){
+static av_cold void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab,
+                                          uint8_t *len_tab)
+{
     int slevel, run, last;
 
     assert(MAX_LEVEL >= 64);
-    assert(MAX_RUN   >= 63);
-
-    for(slevel=-64; slevel<64; slevel++){
-        if(slevel==0) continue;
-        for(run=0; run<64; run++){
-            for(last=0; last<=1; last++){
-                const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64);
-                int level= slevel < 0 ? -slevel : slevel;
-                int sign= slevel < 0 ? 1 : 0;
+    assert(MAX_RUN >= 63);
+
+    for (slevel = -64; slevel < 64; slevel++) {
+        if (slevel == 0)
+            continue;
+        for (run = 0; run < 64; run++) {
+            for (last = 0; last <= 1; last++) {
+                const int index = UNI_MPEG4_ENC_INDEX(last, run, slevel + 64);
+                int level       = slevel < 0 ? -slevel : slevel;
+                int sign        = slevel < 0 ? 1 : 0;
                 int bits, len, code;
                 int level1, run1;
 
-                len_tab[index]= 100;
+                len_tab[index] = 100;
 
                 /* ESC0 */
-                code= get_rl_index(rl, last, run, level);
-                bits= rl->table_vlc[code][0];
-                len=  rl->table_vlc[code][1];
-                bits=bits*2+sign; len++;
-
-                if(code!=rl->n && len < len_tab[index]){
-                    bits_tab[index]= bits;
-                    len_tab [index]= len;
+                code = get_rl_index(rl, last, run, level);
+                bits = rl->table_vlc[code][0];
+                len  = rl->table_vlc[code][1];
+                bits = bits * 2 + sign;
+                len++;
+
+                if (code != rl->n && len < len_tab[index]) {
+                    bits_tab[index] = bits;
+                    len_tab[index]  = len;
                 }
                 /* ESC1 */
-                bits= rl->table_vlc[rl->n][0];
-                len=  rl->table_vlc[rl->n][1];
-                bits=bits*2;    len++; //esc1
-                level1= level - rl->max_level[last][run];
-                if(level1>0){
-                    code= get_rl_index(rl, last, run, level1);
-                    bits<<= rl->table_vlc[code][1];
-                    len  += rl->table_vlc[code][1];
-                    bits += rl->table_vlc[code][0];
-                    bits=bits*2+sign; len++;
-
-                    if(code!=rl->n && len < len_tab[index]){
-                        bits_tab[index]= bits;
-                        len_tab [index]= len;
+                bits = rl->table_vlc[rl->n][0];
+                len  = rl->table_vlc[rl->n][1];
+                bits = bits * 2;
+                len++;                 // esc1
+                level1 = level - rl->max_level[last][run];
+                if (level1 > 0) {
+                    code   = get_rl_index(rl, last, run, level1);
+                    bits <<= rl->table_vlc[code][1];
+                    len   += rl->table_vlc[code][1];
+                    bits  += rl->table_vlc[code][0];
+                    bits   = bits * 2 + sign;
+                    len++;
+
+                    if (code != rl->n && len < len_tab[index]) {
+                        bits_tab[index] = bits;
+                        len_tab[index]  = len;
                     }
                 }
                 /* ESC2 */
-                bits= rl->table_vlc[rl->n][0];
-                len=  rl->table_vlc[rl->n][1];
-                bits=bits*4+2;    len+=2; //esc2
+                bits = rl->table_vlc[rl->n][0];
+                len  = rl->table_vlc[rl->n][1];
+                bits = bits * 4 + 2;
+                len += 2;                 // esc2
                 run1 = run - rl->max_run[last][level] - 1;
-                if(run1>=0){
-                    code= get_rl_index(rl, last, run1, level);
-                    bits<<= rl->table_vlc[code][1];
-                    len  += rl->table_vlc[code][1];
-                    bits += rl->table_vlc[code][0];
-                    bits=bits*2+sign; len++;
-
-                    if(code!=rl->n && len < len_tab[index]){
-                        bits_tab[index]= bits;
-                        len_tab [index]= len;
+                if (run1 >= 0) {
+                    code   = get_rl_index(rl, last, run1, level);
+                    bits <<= rl->table_vlc[code][1];
+                    len   += rl->table_vlc[code][1];
+                    bits  += rl->table_vlc[code][0];
+                    bits   = bits * 2 + sign;
+                    len++;
+
+                    if (code != rl->n && len < len_tab[index]) {
+                        bits_tab[index] = bits;
+                        len_tab[index]  = len;
                     }
                 }
                 /* ESC3 */
-                bits= rl->table_vlc[rl->n][0];
-                len = rl->table_vlc[rl->n][1];
-                bits=bits*4+3;    len+=2; //esc3
-                bits=bits*2+last; len++;
-                bits=bits*64+run; len+=6;
-                bits=bits*2+1;    len++;  //marker
-                bits=bits*4096+(slevel&0xfff); len+=12;
-                bits=bits*2+1;    len++;  //marker
-
-                if(len < len_tab[index]){
-                    bits_tab[index]= bits;
-                    len_tab [index]= len;
+                bits = rl->table_vlc[rl->n][0];
+                len  = rl->table_vlc[rl->n][1];
+                bits = bits * 4 + 3;
+                len += 2;                 // esc3
+                bits = bits * 2 + last;
+                len++;
+                bits = bits * 64 + run;
+                len += 6;
+                bits = bits * 2 + 1;
+                len++;                    // marker
+                bits = bits * 4096 + (slevel & 0xfff);
+                len += 12;
+                bits = bits * 2 + 1;
+                len++;                    // marker
+
+                if (len < len_tab[index]) {
+                    bits_tab[index] = bits;
+                    len_tab[index]  = len;
                 }
             }
         }
@@ -1222,7 +1286,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     int ret;
     static int done = 0;
 
-    if((ret=ff_MPV_encode_init(avctx)) < 0)
+    if ((ret = ff_MPV_encode_init(avctx)) < 0)
         return ret;
 
     if (!done) {
@@ -1236,81 +1300,79 @@ static av_cold int encode_init(AVCodecContext *avctx)
         init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len);
     }
 
-    s->min_qcoeff= -2048;
-    s->max_qcoeff=  2047;
-    s->intra_ac_vlc_length     = uni_mpeg4_intra_rl_len;
-    s->intra_ac_vlc_last_length= uni_mpeg4_intra_rl_len + 128*64;
-    s->inter_ac_vlc_length     = uni_mpeg4_inter_rl_len;
-    s->inter_ac_vlc_last_length= uni_mpeg4_inter_rl_len + 128*64;
-    s->luma_dc_vlc_length= uni_DCtab_lum_len;
-    s->ac_esc_length= 7+2+1+6+1+12+1;
-    s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;
-    s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;
-
-    if(s->flags & CODEC_FLAG_GLOBAL_HEADER){
-
-        s->avctx->extradata= av_malloc(1024);
+    s->min_qcoeff               = -2048;
+    s->max_qcoeff               = 2047;
+    s->intra_ac_vlc_length      = uni_mpeg4_intra_rl_len;
+    s->intra_ac_vlc_last_length = uni_mpeg4_intra_rl_len + 128 * 64;
+    s->inter_ac_vlc_length      = uni_mpeg4_inter_rl_len;
+    s->inter_ac_vlc_last_length = uni_mpeg4_inter_rl_len + 128 * 64;
+    s->luma_dc_vlc_length       = uni_DCtab_lum_len;
+    s->ac_esc_length            = 7 + 2 + 1 + 6 + 1 + 12 + 1;
+    s->y_dc_scale_table         = ff_mpeg4_y_dc_scale_table;
+    s->c_dc_scale_table         = ff_mpeg4_c_dc_scale_table;
+
+    if (s->flags & CODEC_FLAG_GLOBAL_HEADER) {
+        s->avctx->extradata = av_malloc(1024);
         init_put_bits(&s->pb, s->avctx->extradata, 1024);
 
-        if(!(s->workaround_bugs & FF_BUG_MS))
+        if (!(s->workaround_bugs & FF_BUG_MS))
             mpeg4_encode_visual_object_header(s);
         mpeg4_encode_vol_header(s, 0, 0);
 
 //            ff_mpeg4_stuffing(&s->pb); ?
         flush_put_bits(&s->pb);
-        s->avctx->extradata_size= (put_bits_count(&s->pb)+7)>>3;
+        s->avctx->extradata_size = (put_bits_count(&s->pb) + 7) >> 3;
     }
     return 0;
 }
 
 void ff_mpeg4_init_partitions(MpegEncContext *s)
 {
-    uint8_t *start= put_bits_ptr(&s->pb);
-    uint8_t *end= s->pb.buf_end;
-    int size= end - start;
-    int pb_size = (((intptr_t)start + size/3)&(~3)) - (intptr_t)start;
-    int tex_size= (size - 2*pb_size)&(~3);
+    uint8_t *start = put_bits_ptr(&s->pb);
+    uint8_t *end   = s->pb.buf_end;
+    int size       = end - start;
+    int pb_size    = (((intptr_t)start + size / 3) & (~3)) - (intptr_t)start;
+    int tex_size   = (size - 2 * pb_size) & (~3);
 
     set_put_bits_buffer_size(&s->pb, pb_size);
-    init_put_bits(&s->tex_pb, start + pb_size           , tex_size);
-    init_put_bits(&s->pb2   , start + pb_size + tex_size, pb_size);
+    init_put_bits(&s->tex_pb, start + pb_size, tex_size);
+    init_put_bits(&s->pb2, start + pb_size + tex_size, pb_size);
 }
 
 void ff_mpeg4_merge_partitions(MpegEncContext *s)
 {
-    const int pb2_len   = put_bits_count(&s->pb2   );
-    const int tex_pb_len= put_bits_count(&s->tex_pb);
-    const int bits= put_bits_count(&s->pb);
+    const int pb2_len    = put_bits_count(&s->pb2);
+    const int tex_pb_len = put_bits_count(&s->tex_pb);
+    const int bits       = put_bits_count(&s->pb);
 
-    if(s->pict_type==AV_PICTURE_TYPE_I){
+    if (s->pict_type == AV_PICTURE_TYPE_I) {
         put_bits(&s->pb, 19, DC_MARKER);
-        s->misc_bits+=19 + pb2_len + bits - s->last_bits;
-        s->i_tex_bits+= tex_pb_len;
-    }else{
+        s->misc_bits  += 19 + pb2_len + bits - s->last_bits;
+        s->i_tex_bits += tex_pb_len;
+    } else {
         put_bits(&s->pb, 17, MOTION_MARKER);
-        s->misc_bits+=17 + pb2_len;
-        s->mv_bits+= bits - s->last_bits;
-        s->p_tex_bits+= tex_pb_len;
+        s->misc_bits  += 17 + pb2_len;
+        s->mv_bits    += bits - s->last_bits;
+        s->p_tex_bits += tex_pb_len;
     }
 
     flush_put_bits(&s->pb2);
     flush_put_bits(&s->tex_pb);
 
     set_put_bits_buffer_size(&s->pb, s->pb2.buf_end - s->pb.buf);
-    avpriv_copy_bits(&s->pb, s->pb2.buf   , pb2_len);
+    avpriv_copy_bits(&s->pb, s->pb2.buf, pb2_len);
     avpriv_copy_bits(&s->pb, s->tex_pb.buf, tex_pb_len);
-    s->last_bits= put_bits_count(&s->pb);
+    s->last_bits = put_bits_count(&s->pb);
 }
 
-
 void ff_mpeg4_encode_video_packet_header(MpegEncContext *s)
 {
-    int mb_num_bits= av_log2(s->mb_num - 1) + 1;
+    int mb_num_bits = av_log2(s->mb_num - 1) + 1;
 
     put_bits(&s->pb, ff_mpeg4_get_video_packet_prefix_length(s), 0);
     put_bits(&s->pb, 1, 1);
 
-    put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y*s->mb_width);
+    put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y * s->mb_width);
     put_bits(&s->pb, s->quant_precision, s->qscale);
     put_bits(&s->pb, 1, 0); /* no HEC */
 }
@@ -1318,8 +1380,8 @@ void ff_mpeg4_encode_video_packet_header(MpegEncContext *s)
 #define OFFSET(x) offsetof(MpegEncContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "data_partitioning",       "Use data partitioning.",      OFFSET(data_partitioning), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
-    { "alternate_scan",          "Enable alternate scantable.", OFFSET(alternate_scan),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "data_partitioning", "Use data partitioning.",      OFFSET(data_partitioning), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "alternate_scan",    "Enable alternate scantable.", OFFSET(alternate_scan),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
     FF_MPV_COMMON_OPTS
     { NULL },
 };
@@ -1333,14 +1395,14 @@ static const AVClass mpeg4enc_class = {
 
 AVCodec ff_mpeg4_encoder = {
     .name           = "mpeg4",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MPEG4,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = encode_init,
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
     .priv_class     = &mpeg4enc_class,
 };
diff --git a/libavcodec/mpegaudio_tablegen.h b/libavcodec/mpegaudio_tablegen.h
index a222f2c..8a3e51a 100644
--- a/libavcodec/mpegaudio_tablegen.h
+++ b/libavcodec/mpegaudio_tablegen.h
@@ -47,7 +47,8 @@ static void mpegaudio_tableinit(void)
         double value = i / 4;
         double f, fm;
         int e, m;
-        f  = value * cbrtf(value) * pow(2, (i & 3) * 0.25);
+        /* cbrtf() isn't available on all systems, so we use powf(). */
+        f  = value * powf(value, 1.0 / 3.0) * 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,8 +59,10 @@ static void mpegaudio_tableinit(void)
     }
     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);
-            expval_table_fixed[exponent][value] = llrint(f);
+            /* cbrtf() isn't available on all systems, so we use powf(). */
+            double f = (double)value * powf(value, 1.0 / 3.0) * pow(2, (exponent - 400) * 0.25 + FRAC_BITS + 5);
+            /* llrint() isn't always available, so round and cast manually. */
+            expval_table_fixed[exponent][value] = (long long int) (f >= 0 ? floor(f + 0.5) : ceil(f - 0.5));
             expval_table_float[exponent][value] = f;
         }
         exp_table_fixed[exponent] = expval_table_fixed[exponent][1];
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
deleted file mode 100644
index bd096df..0000000
--- a/libavcodec/mpegaudiodec.c
+++ /dev/null
@@ -1,2053 +0,0 @@
-/*
- * MPEG Audio decoder
- * Copyright (c) 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
- */
-
-/**
- * @file
- * MPEG Audio decoder
- */
-
-#include "libavutil/channel_layout.h"
-#include "avcodec.h"
-#include "get_bits.h"
-#include "internal.h"
-#include "mathops.h"
-#include "mpegaudiodsp.h"
-#include "dsputil.h"
-
-/*
- * TODO:
- *  - test lsf / mpeg25 extensively.
- */
-
-#include "mpegaudio.h"
-#include "mpegaudiodecheader.h"
-
-#define BACKSTEP_SIZE 512
-#define EXTRABYTES 24
-#define LAST_BUF_SIZE 2 * BACKSTEP_SIZE + EXTRABYTES
-
-/* layer 3 "granule" */
-typedef struct GranuleDef {
-    uint8_t scfsi;
-    int part2_3_length;
-    int big_values;
-    int global_gain;
-    int scalefac_compress;
-    uint8_t block_type;
-    uint8_t switch_point;
-    int table_select[3];
-    int subblock_gain[3];
-    uint8_t scalefac_scale;
-    uint8_t count1table_select;
-    int region_size[3]; /* number of huffman codes in each region */
-    int preflag;
-    int short_start, long_end; /* long/short band indexes */
-    uint8_t scale_factors[40];
-    DECLARE_ALIGNED(16, INTFLOAT, sb_hybrid)[SBLIMIT * 18]; /* 576 samples */
-} GranuleDef;
-
-typedef struct MPADecodeContext {
-    MPA_DECODE_HEADER
-    uint8_t last_buf[LAST_BUF_SIZE];
-    int last_buf_size;
-    /* next header (used in free format parsing) */
-    uint32_t free_format_next_header;
-    GetBitContext gb;
-    GetBitContext in_gb;
-    DECLARE_ALIGNED(32, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512 * 2];
-    int synth_buf_offset[MPA_MAX_CHANNELS];
-    DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT];
-    INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
-    GranuleDef granules[2][2]; /* Used in Layer 3 */
-    int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
-    int dither_state;
-    int err_recognition;
-    AVCodecContext* avctx;
-    MPADSPContext mpadsp;
-    DSPContext dsp;
-    AVFrame frame;
-} MPADecodeContext;
-
-#if CONFIG_FLOAT
-#   define SHR(a,b)       ((a)*(1.0f/(1<<(b))))
-#   define FIXR_OLD(a)    ((int)((a) * FRAC_ONE + 0.5))
-#   define FIXR(x)        ((float)(x))
-#   define FIXHR(x)       ((float)(x))
-#   define MULH3(x, y, s) ((s)*(y)*(x))
-#   define MULLx(x, y, s) ((y)*(x))
-#   define RENAME(a) a ## _float
-#   define OUT_FMT   AV_SAMPLE_FMT_FLT
-#   define OUT_FMT_P AV_SAMPLE_FMT_FLTP
-#else
-#   define SHR(a,b)       ((a)>>(b))
-/* WARNING: only correct for positive numbers */
-#   define FIXR_OLD(a)    ((int)((a) * FRAC_ONE + 0.5))
-#   define FIXR(a)        ((int)((a) * FRAC_ONE + 0.5))
-#   define FIXHR(a)       ((int)((a) * (1LL<<32) + 0.5))
-#   define MULH3(x, y, s) MULH((s)*(x), y)
-#   define MULLx(x, y, s) MULL(x,y,s)
-#   define RENAME(a)      a ## _fixed
-#   define OUT_FMT   AV_SAMPLE_FMT_S16
-#   define OUT_FMT_P AV_SAMPLE_FMT_S16P
-#endif
-
-/****************/
-
-#define HEADER_SIZE 4
-
-#include "mpegaudiodata.h"
-#include "mpegaudiodectab.h"
-
-/* vlc structure for decoding layer 3 huffman tables */
-static VLC huff_vlc[16];
-static VLC_TYPE huff_vlc_tables[
-    0 + 128 + 128 + 128 + 130 + 128 + 154 + 166 +
-  142 + 204 + 190 + 170 + 542 + 460 + 662 + 414
-  ][2];
-static const int huff_vlc_tables_sizes[16] = {
-    0,  128,  128,  128,  130,  128,  154,  166,
-  142,  204,  190,  170,  542,  460,  662,  414
-};
-static VLC huff_quad_vlc[2];
-static VLC_TYPE  huff_quad_vlc_tables[128+16][2];
-static const int huff_quad_vlc_tables_sizes[2] = { 128, 16 };
-/* computed from band_size_long */
-static uint16_t band_index_long[9][23];
-#include "mpegaudio_tablegen.h"
-/* intensity stereo coef table */
-static INTFLOAT is_table[2][16];
-static INTFLOAT is_table_lsf[2][2][16];
-static INTFLOAT csa_table[8][4];
-
-static int16_t division_tab3[1<<6 ];
-static int16_t division_tab5[1<<8 ];
-static int16_t division_tab9[1<<11];
-
-static int16_t * const division_tabs[4] = {
-    division_tab3, division_tab5, NULL, division_tab9
-};
-
-/* lower 2 bits: modulo 3, higher bits: shift */
-static uint16_t scale_factor_modshift[64];
-/* [i][j]:  2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
-static int32_t scale_factor_mult[15][3];
-/* mult table for layer 2 group quantization */
-
-#define SCALE_GEN(v) \
-{ FIXR_OLD(1.0 * (v)), FIXR_OLD(0.7937005259 * (v)), FIXR_OLD(0.6299605249 * (v)) }
-
-static const int32_t scale_factor_mult2[3][3] = {
-    SCALE_GEN(4.0 / 3.0), /* 3 steps */
-    SCALE_GEN(4.0 / 5.0), /* 5 steps */
-    SCALE_GEN(4.0 / 9.0), /* 9 steps */
-};
-
-/**
- * Convert region offsets to region sizes and truncate
- * size to big_values.
- */
-static void ff_region_offset2size(GranuleDef *g)
-{
-    int i, k, j = 0;
-    g->region_size[2] = 576 / 2;
-    for (i = 0; i < 3; i++) {
-        k = FFMIN(g->region_size[i], g->big_values);
-        g->region_size[i] = k - j;
-        j = k;
-    }
-}
-
-static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g)
-{
-    if (g->block_type == 2) {
-        if (s->sample_rate_index != 8)
-            g->region_size[0] = (36 / 2);
-        else
-            g->region_size[0] = (72 / 2);
-    } else {
-        if (s->sample_rate_index <= 2)
-            g->region_size[0] = (36 / 2);
-        else if (s->sample_rate_index != 8)
-            g->region_size[0] = (54 / 2);
-        else
-            g->region_size[0] = (108 / 2);
-    }
-    g->region_size[1] = (576 / 2);
-}
-
-static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2)
-{
-    int l;
-    g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
-    /* should not overflow */
-    l = FFMIN(ra1 + ra2 + 2, 22);
-    g->region_size[1] = band_index_long[s->sample_rate_index][      l] >> 1;
-}
-
-static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
-{
-    if (g->block_type == 2) {
-        if (g->switch_point) {
-            /* if switched mode, we handle the 36 first samples as
-                long blocks.  For 8000Hz, we handle the 72 first
-                exponents as long blocks */
-            if (s->sample_rate_index <= 2)
-                g->long_end = 8;
-            else
-                g->long_end = 6;
-
-            g->short_start = 3;
-        } else {
-            g->long_end    = 0;
-            g->short_start = 0;
-        }
-    } else {
-        g->short_start = 13;
-        g->long_end    = 22;
-    }
-}
-
-/* layer 1 unscaling */
-/* n = number of bits of the mantissa minus 1 */
-static inline int l1_unscale(int n, int mant, int scale_factor)
-{
-    int shift, mod;
-    int64_t val;
-
-    shift   = scale_factor_modshift[scale_factor];
-    mod     = shift & 3;
-    shift >>= 2;
-    val     = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]);
-    shift  += n;
-    /* NOTE: at this point, 1 <= shift >= 21 + 15 */
-    return (int)((val + (1LL << (shift - 1))) >> shift);
-}
-
-static inline int l2_unscale_group(int steps, int mant, int scale_factor)
-{
-    int shift, mod, val;
-
-    shift   = scale_factor_modshift[scale_factor];
-    mod     = shift & 3;
-    shift >>= 2;
-
-    val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod];
-    /* NOTE: at this point, 0 <= shift <= 21 */
-    if (shift > 0)
-        val = (val + (1 << (shift - 1))) >> shift;
-    return val;
-}
-
-/* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */
-static inline int l3_unscale(int value, int exponent)
-{
-    unsigned int m;
-    int e;
-
-    e  = table_4_3_exp  [4 * value + (exponent & 3)];
-    m  = table_4_3_value[4 * value + (exponent & 3)];
-    e -= exponent >> 2;
-    assert(e >= 1);
-    if (e > 31)
-        return 0;
-    m = (m + (1 << (e - 1))) >> e;
-
-    return m;
-}
-
-static av_cold void decode_init_static(void)
-{
-    int i, j, k;
-    int offset;
-
-    /* scale factors table for layer 1/2 */
-    for (i = 0; i < 64; i++) {
-        int shift, mod;
-        /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */
-        shift = i / 3;
-        mod   = i % 3;
-        scale_factor_modshift[i] = mod | (shift << 2);
-    }
-
-    /* scale factor multiply for layer 1 */
-    for (i = 0; i < 15; i++) {
-        int n, norm;
-        n = i + 2;
-        norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
-        scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0          * 2.0), FRAC_BITS);
-        scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
-        scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
-        av_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm,
-                scale_factor_mult[i][0],
-                scale_factor_mult[i][1],
-                scale_factor_mult[i][2]);
-    }
-
-    RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
-
-    /* huffman decode tables */
-    offset = 0;
-    for (i = 1; i < 16; i++) {
-        const HuffTable *h = &mpa_huff_tables[i];
-        int xsize, x, y;
-        uint8_t  tmp_bits [512] = { 0 };
-        uint16_t tmp_codes[512] = { 0 };
-
-        xsize = h->xsize;
-
-        j = 0;
-        for (x = 0; x < xsize; x++) {
-            for (y = 0; y < xsize; y++) {
-                tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j  ];
-                tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
-            }
-        }
-
-        /* XXX: fail test */
-        huff_vlc[i].table = huff_vlc_tables+offset;
-        huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
-        init_vlc(&huff_vlc[i], 7, 512,
-                 tmp_bits, 1, 1, tmp_codes, 2, 2,
-                 INIT_VLC_USE_NEW_STATIC);
-        offset += huff_vlc_tables_sizes[i];
-    }
-    assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
-
-    offset = 0;
-    for (i = 0; i < 2; i++) {
-        huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
-        huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
-        init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
-                 mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
-                 INIT_VLC_USE_NEW_STATIC);
-        offset += huff_quad_vlc_tables_sizes[i];
-    }
-    assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
-
-    for (i = 0; i < 9; i++) {
-        k = 0;
-        for (j = 0; j < 22; j++) {
-            band_index_long[i][j] = k;
-            k += band_size_long[i][j];
-        }
-        band_index_long[i][22] = k;
-    }
-
-    /* compute n ^ (4/3) and store it in mantissa/exp format */
-
-    mpegaudio_tableinit();
-
-    for (i = 0; i < 4; i++) {
-        if (ff_mpa_quant_bits[i] < 0) {
-            for (j = 0; j < (1 << (-ff_mpa_quant_bits[i]+1)); j++) {
-                int val1, val2, val3, steps;
-                int val = j;
-                steps   = ff_mpa_quant_steps[i];
-                val1    = val % steps;
-                val    /= steps;
-                val2    = val % steps;
-                val3    = val / steps;
-                division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8);
-            }
-        }
-    }
-
-
-    for (i = 0; i < 7; i++) {
-        float f;
-        INTFLOAT v;
-        if (i != 6) {
-            f = tan((double)i * M_PI / 12.0);
-            v = FIXR(f / (1.0 + f));
-        } else {
-            v = FIXR(1.0);
-        }
-        is_table[0][    i] = v;
-        is_table[1][6 - i] = v;
-    }
-    /* invalid values */
-    for (i = 7; i < 16; i++)
-        is_table[0][i] = is_table[1][i] = 0.0;
-
-    for (i = 0; i < 16; i++) {
-        double f;
-        int e, k;
-
-        for (j = 0; j < 2; j++) {
-            e = -(j + 1) * ((i + 1) >> 1);
-            f = pow(2.0, e / 4.0);
-            k = i & 1;
-            is_table_lsf[j][k ^ 1][i] = FIXR(f);
-            is_table_lsf[j][k    ][i] = FIXR(1.0);
-            av_dlog(NULL, "is_table_lsf %d %d: %f %f\n",
-                    i, j, (float) is_table_lsf[j][0][i],
-                    (float) is_table_lsf[j][1][i]);
-        }
-    }
-
-    for (i = 0; i < 8; i++) {
-        float ci, cs, ca;
-        ci = ci_table[i];
-        cs = 1.0 / sqrt(1.0 + ci * ci);
-        ca = cs * ci;
-#if !CONFIG_FLOAT
-        csa_table[i][0] = FIXHR(cs/4);
-        csa_table[i][1] = FIXHR(ca/4);
-        csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4);
-        csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4);
-#else
-        csa_table[i][0] = cs;
-        csa_table[i][1] = ca;
-        csa_table[i][2] = ca + cs;
-        csa_table[i][3] = ca - cs;
-#endif
-    }
-}
-
-static av_cold int decode_init(AVCodecContext * avctx)
-{
-    static int initialized_tables = 0;
-    MPADecodeContext *s = avctx->priv_data;
-
-    if (!initialized_tables) {
-        decode_init_static();
-        initialized_tables = 1;
-    }
-
-    s->avctx = avctx;
-
-    ff_mpadsp_init(&s->mpadsp);
-    ff_dsputil_init(&s->dsp, avctx);
-
-    if (avctx->request_sample_fmt == OUT_FMT &&
-        avctx->codec_id != AV_CODEC_ID_MP3ON4)
-        avctx->sample_fmt = OUT_FMT;
-    else
-        avctx->sample_fmt = OUT_FMT_P;
-    s->err_recognition = avctx->err_recognition;
-
-    if (avctx->codec_id == AV_CODEC_ID_MP3ADU)
-        s->adu_mode = 1;
-
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
-    return 0;
-}
-
-#define C3 FIXHR(0.86602540378443864676/2)
-#define C4 FIXHR(0.70710678118654752439/2) //0.5 / cos(pi*(9)/36)
-#define C5 FIXHR(0.51763809020504152469/2) //0.5 / cos(pi*(5)/36)
-#define C6 FIXHR(1.93185165257813657349/4) //0.5 / cos(pi*(15)/36)
-
-/* 12 points IMDCT. We compute it "by hand" by factorizing obvious
-   cases. */
-static void imdct12(INTFLOAT *out, INTFLOAT *in)
-{
-    INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2;
-
-    in0  = in[0*3];
-    in1  = in[1*3] + in[0*3];
-    in2  = in[2*3] + in[1*3];
-    in3  = in[3*3] + in[2*3];
-    in4  = in[4*3] + in[3*3];
-    in5  = in[5*3] + in[4*3];
-    in5 += in3;
-    in3 += in1;
-
-    in2  = MULH3(in2, C3, 2);
-    in3  = MULH3(in3, C3, 4);
-
-    t1   = in0 - in4;
-    t2   = MULH3(in1 - in5, C4, 2);
-
-    out[ 7] =
-    out[10] = t1 + t2;
-    out[ 1] =
-    out[ 4] = t1 - t2;
-
-    in0    += SHR(in4, 1);
-    in4     = in0 + in2;
-    in5    += 2*in1;
-    in1     = MULH3(in5 + in3, C5, 1);
-    out[ 8] =
-    out[ 9] = in4 + in1;
-    out[ 2] =
-    out[ 3] = in4 - in1;
-
-    in0    -= in2;
-    in5     = MULH3(in5 - in3, C6, 2);
-    out[ 0] =
-    out[ 5] = in0 - in5;
-    out[ 6] =
-    out[11] = in0 + in5;
-}
-
-/* return the number of decoded frames */
-static int mp_decode_layer1(MPADecodeContext *s)
-{
-    int bound, i, v, n, ch, j, mant;
-    uint8_t allocation[MPA_MAX_CHANNELS][SBLIMIT];
-    uint8_t scale_factors[MPA_MAX_CHANNELS][SBLIMIT];
-
-    if (s->mode == MPA_JSTEREO)
-        bound = (s->mode_ext + 1) * 4;
-    else
-        bound = SBLIMIT;
-
-    /* allocation bits */
-    for (i = 0; i < bound; i++) {
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            allocation[ch][i] = get_bits(&s->gb, 4);
-        }
-    }
-    for (i = bound; i < SBLIMIT; i++)
-        allocation[0][i] = get_bits(&s->gb, 4);
-
-    /* scale factors */
-    for (i = 0; i < bound; i++) {
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            if (allocation[ch][i])
-                scale_factors[ch][i] = get_bits(&s->gb, 6);
-        }
-    }
-    for (i = bound; i < SBLIMIT; i++) {
-        if (allocation[0][i]) {
-            scale_factors[0][i] = get_bits(&s->gb, 6);
-            scale_factors[1][i] = get_bits(&s->gb, 6);
-        }
-    }
-
-    /* compute samples */
-    for (j = 0; j < 12; j++) {
-        for (i = 0; i < bound; i++) {
-            for (ch = 0; ch < s->nb_channels; ch++) {
-                n = allocation[ch][i];
-                if (n) {
-                    mant = get_bits(&s->gb, n + 1);
-                    v = l1_unscale(n, mant, scale_factors[ch][i]);
-                } else {
-                    v = 0;
-                }
-                s->sb_samples[ch][j][i] = v;
-            }
-        }
-        for (i = bound; i < SBLIMIT; i++) {
-            n = allocation[0][i];
-            if (n) {
-                mant = get_bits(&s->gb, n + 1);
-                v = l1_unscale(n, mant, scale_factors[0][i]);
-                s->sb_samples[0][j][i] = v;
-                v = l1_unscale(n, mant, scale_factors[1][i]);
-                s->sb_samples[1][j][i] = v;
-            } else {
-                s->sb_samples[0][j][i] = 0;
-                s->sb_samples[1][j][i] = 0;
-            }
-        }
-    }
-    return 12;
-}
-
-static int mp_decode_layer2(MPADecodeContext *s)
-{
-    int sblimit; /* number of used subbands */
-    const unsigned char *alloc_table;
-    int table, bit_alloc_bits, i, j, ch, bound, v;
-    unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
-    unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
-    unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3], *sf;
-    int scale, qindex, bits, steps, k, l, m, b;
-
-    /* select decoding table */
-    table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels,
-                                   s->sample_rate, s->lsf);
-    sblimit     = ff_mpa_sblimit_table[table];
-    alloc_table = ff_mpa_alloc_tables[table];
-
-    if (s->mode == MPA_JSTEREO)
-        bound = (s->mode_ext + 1) * 4;
-    else
-        bound = sblimit;
-
-    av_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit);
-
-    /* sanity check */
-    if (bound > sblimit)
-        bound = sblimit;
-
-    /* parse bit allocation */
-    j = 0;
-    for (i = 0; i < bound; i++) {
-        bit_alloc_bits = alloc_table[j];
-        for (ch = 0; ch < s->nb_channels; ch++)
-            bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits);
-        j += 1 << bit_alloc_bits;
-    }
-    for (i = bound; i < sblimit; i++) {
-        bit_alloc_bits = alloc_table[j];
-        v = get_bits(&s->gb, bit_alloc_bits);
-        bit_alloc[0][i] = v;
-        bit_alloc[1][i] = v;
-        j += 1 << bit_alloc_bits;
-    }
-
-    /* scale codes */
-    for (i = 0; i < sblimit; i++) {
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            if (bit_alloc[ch][i])
-                scale_code[ch][i] = get_bits(&s->gb, 2);
-        }
-    }
-
-    /* scale factors */
-    for (i = 0; i < sblimit; i++) {
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            if (bit_alloc[ch][i]) {
-                sf = scale_factors[ch][i];
-                switch (scale_code[ch][i]) {
-                default:
-                case 0:
-                    sf[0] = get_bits(&s->gb, 6);
-                    sf[1] = get_bits(&s->gb, 6);
-                    sf[2] = get_bits(&s->gb, 6);
-                    break;
-                case 2:
-                    sf[0] = get_bits(&s->gb, 6);
-                    sf[1] = sf[0];
-                    sf[2] = sf[0];
-                    break;
-                case 1:
-                    sf[0] = get_bits(&s->gb, 6);
-                    sf[2] = get_bits(&s->gb, 6);
-                    sf[1] = sf[0];
-                    break;
-                case 3:
-                    sf[0] = get_bits(&s->gb, 6);
-                    sf[2] = get_bits(&s->gb, 6);
-                    sf[1] = sf[2];
-                    break;
-                }
-            }
-        }
-    }
-
-    /* samples */
-    for (k = 0; k < 3; k++) {
-        for (l = 0; l < 12; l += 3) {
-            j = 0;
-            for (i = 0; i < bound; i++) {
-                bit_alloc_bits = alloc_table[j];
-                for (ch = 0; ch < s->nb_channels; ch++) {
-                    b = bit_alloc[ch][i];
-                    if (b) {
-                        scale = scale_factors[ch][i][k];
-                        qindex = alloc_table[j+b];
-                        bits = ff_mpa_quant_bits[qindex];
-                        if (bits < 0) {
-                            int v2;
-                            /* 3 values at the same time */
-                            v = get_bits(&s->gb, -bits);
-                            v2 = division_tabs[qindex][v];
-                            steps  = ff_mpa_quant_steps[qindex];
-
-                            s->sb_samples[ch][k * 12 + l + 0][i] =
-                                l2_unscale_group(steps,  v2       & 15, scale);
-                            s->sb_samples[ch][k * 12 + l + 1][i] =
-                                l2_unscale_group(steps, (v2 >> 4) & 15, scale);
-                            s->sb_samples[ch][k * 12 + l + 2][i] =
-                                l2_unscale_group(steps,  v2 >> 8      , scale);
-                        } else {
-                            for (m = 0; m < 3; m++) {
-                                v = get_bits(&s->gb, bits);
-                                v = l1_unscale(bits - 1, v, scale);
-                                s->sb_samples[ch][k * 12 + l + m][i] = v;
-                            }
-                        }
-                    } else {
-                        s->sb_samples[ch][k * 12 + l + 0][i] = 0;
-                        s->sb_samples[ch][k * 12 + l + 1][i] = 0;
-                        s->sb_samples[ch][k * 12 + l + 2][i] = 0;
-                    }
-                }
-                /* next subband in alloc table */
-                j += 1 << bit_alloc_bits;
-            }
-            /* XXX: find a way to avoid this duplication of code */
-            for (i = bound; i < sblimit; i++) {
-                bit_alloc_bits = alloc_table[j];
-                b = bit_alloc[0][i];
-                if (b) {
-                    int mant, scale0, scale1;
-                    scale0 = scale_factors[0][i][k];
-                    scale1 = scale_factors[1][i][k];
-                    qindex = alloc_table[j+b];
-                    bits = ff_mpa_quant_bits[qindex];
-                    if (bits < 0) {
-                        /* 3 values at the same time */
-                        v = get_bits(&s->gb, -bits);
-                        steps = ff_mpa_quant_steps[qindex];
-                        mant = v % steps;
-                        v = v / steps;
-                        s->sb_samples[0][k * 12 + l + 0][i] =
-                            l2_unscale_group(steps, mant, scale0);
-                        s->sb_samples[1][k * 12 + l + 0][i] =
-                            l2_unscale_group(steps, mant, scale1);
-                        mant = v % steps;
-                        v = v / steps;
-                        s->sb_samples[0][k * 12 + l + 1][i] =
-                            l2_unscale_group(steps, mant, scale0);
-                        s->sb_samples[1][k * 12 + l + 1][i] =
-                            l2_unscale_group(steps, mant, scale1);
-                        s->sb_samples[0][k * 12 + l + 2][i] =
-                            l2_unscale_group(steps, v, scale0);
-                        s->sb_samples[1][k * 12 + l + 2][i] =
-                            l2_unscale_group(steps, v, scale1);
-                    } else {
-                        for (m = 0; m < 3; m++) {
-                            mant = get_bits(&s->gb, bits);
-                            s->sb_samples[0][k * 12 + l + m][i] =
-                                l1_unscale(bits - 1, mant, scale0);
-                            s->sb_samples[1][k * 12 + l + m][i] =
-                                l1_unscale(bits - 1, mant, scale1);
-                        }
-                    }
-                } else {
-                    s->sb_samples[0][k * 12 + l + 0][i] = 0;
-                    s->sb_samples[0][k * 12 + l + 1][i] = 0;
-                    s->sb_samples[0][k * 12 + l + 2][i] = 0;
-                    s->sb_samples[1][k * 12 + l + 0][i] = 0;
-                    s->sb_samples[1][k * 12 + l + 1][i] = 0;
-                    s->sb_samples[1][k * 12 + l + 2][i] = 0;
-                }
-                /* next subband in alloc table */
-                j += 1 << bit_alloc_bits;
-            }
-            /* fill remaining samples to zero */
-            for (i = sblimit; i < SBLIMIT; i++) {
-                for (ch = 0; ch < s->nb_channels; ch++) {
-                    s->sb_samples[ch][k * 12 + l + 0][i] = 0;
-                    s->sb_samples[ch][k * 12 + l + 1][i] = 0;
-                    s->sb_samples[ch][k * 12 + l + 2][i] = 0;
-                }
-            }
-        }
-    }
-    return 3 * 12;
-}
-
-#define SPLIT(dst,sf,n)             \
-    if (n == 3) {                   \
-        int m = (sf * 171) >> 9;    \
-        dst   = sf - 3 * m;         \
-        sf    = m;                  \
-    } else if (n == 4) {            \
-        dst  = sf & 3;              \
-        sf >>= 2;                   \
-    } else if (n == 5) {            \
-        int m = (sf * 205) >> 10;   \
-        dst   = sf - 5 * m;         \
-        sf    = m;                  \
-    } else if (n == 6) {            \
-        int m = (sf * 171) >> 10;   \
-        dst   = sf - 6 * m;         \
-        sf    = m;                  \
-    } else {                        \
-        dst = 0;                    \
-    }
-
-static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2,
-                                           int n3)
-{
-    SPLIT(slen[3], sf, n3)
-    SPLIT(slen[2], sf, n2)
-    SPLIT(slen[1], sf, n1)
-    slen[0] = sf;
-}
-
-static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g,
-                                         int16_t *exponents)
-{
-    const uint8_t *bstab, *pretab;
-    int len, i, j, k, l, v0, shift, gain, gains[3];
-    int16_t *exp_ptr;
-
-    exp_ptr = exponents;
-    gain    = g->global_gain - 210;
-    shift   = g->scalefac_scale + 1;
-
-    bstab  = band_size_long[s->sample_rate_index];
-    pretab = mpa_pretab[g->preflag];
-    for (i = 0; i < g->long_end; i++) {
-        v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400;
-        len = bstab[i];
-        for (j = len; j > 0; j--)
-            *exp_ptr++ = v0;
-    }
-
-    if (g->short_start < 13) {
-        bstab    = band_size_short[s->sample_rate_index];
-        gains[0] = gain - (g->subblock_gain[0] << 3);
-        gains[1] = gain - (g->subblock_gain[1] << 3);
-        gains[2] = gain - (g->subblock_gain[2] << 3);
-        k        = g->long_end;
-        for (i = g->short_start; i < 13; i++) {
-            len = bstab[i];
-            for (l = 0; l < 3; l++) {
-                v0 = gains[l] - (g->scale_factors[k++] << shift) + 400;
-                for (j = len; j > 0; j--)
-                    *exp_ptr++ = v0;
-            }
-        }
-    }
-}
-
-/* handle n = 0 too */
-static inline int get_bitsz(GetBitContext *s, int n)
-{
-    return n ? get_bits(s, n) : 0;
-}
-
-
-static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos,
-                          int *end_pos2)
-{
-    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);
-        skip_bits_long(&s->gb, *pos - *end_pos);
-        *end_pos2 =
-        *end_pos  = *end_pos2 + get_bits_count(&s->gb) - *pos;
-        *pos      = get_bits_count(&s->gb);
-    }
-}
-
-/* Following is a optimized code for
-            INTFLOAT v = *src
-            if(get_bits1(&s->gb))
-                v = -v;
-            *dst = v;
-*/
-#if CONFIG_FLOAT
-#define READ_FLIP_SIGN(dst,src)                     \
-    v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31);  \
-    AV_WN32A(dst, v);
-#else
-#define READ_FLIP_SIGN(dst,src)     \
-    v      = -get_bits1(&s->gb);    \
-    *(dst) = (*(src) ^ v) - v;
-#endif
-
-static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
-                          int16_t *exponents, int end_pos2)
-{
-    int s_index;
-    int i;
-    int last_pos, bits_left;
-    VLC *vlc;
-    int end_pos = FFMIN(end_pos2, s->gb.size_in_bits);
-
-    /* low frequencies (called big values) */
-    s_index = 0;
-    for (i = 0; i < 3; i++) {
-        int j, k, l, linbits;
-        j = g->region_size[i];
-        if (j == 0)
-            continue;
-        /* select vlc table */
-        k       = g->table_select[i];
-        l       = mpa_huff_data[k][0];
-        linbits = mpa_huff_data[k][1];
-        vlc     = &huff_vlc[l];
-
-        if (!l) {
-            memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j);
-            s_index += 2 * j;
-            continue;
-        }
-
-        /* read huffcode and compute each couple */
-        for (; j > 0; j--) {
-            int exponent, x, y;
-            int v;
-            int pos = get_bits_count(&s->gb);
-
-            if (pos >= end_pos){
-                switch_buffer(s, &pos, &end_pos, &end_pos2);
-                if (pos >= end_pos)
-                    break;
-            }
-            y = get_vlc2(&s->gb, vlc->table, 7, 3);
-
-            if (!y) {
-                g->sb_hybrid[s_index  ] =
-                g->sb_hybrid[s_index+1] = 0;
-                s_index += 2;
-                continue;
-            }
-
-            exponent= exponents[s_index];
-
-            av_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n",
-                    i, g->region_size[i] - j, x, y, exponent);
-            if (y & 16) {
-                x = y >> 5;
-                y = y & 0x0f;
-                if (x < 15) {
-                    READ_FLIP_SIGN(g->sb_hybrid + s_index, RENAME(expval_table)[exponent] + x)
-                } else {
-                    x += get_bitsz(&s->gb, linbits);
-                    v  = l3_unscale(x, exponent);
-                    if (get_bits1(&s->gb))
-                        v = -v;
-                    g->sb_hybrid[s_index] = v;
-                }
-                if (y < 15) {
-                    READ_FLIP_SIGN(g->sb_hybrid + s_index + 1, RENAME(expval_table)[exponent] + y)
-                } else {
-                    y += get_bitsz(&s->gb, linbits);
-                    v  = l3_unscale(y, exponent);
-                    if (get_bits1(&s->gb))
-                        v = -v;
-                    g->sb_hybrid[s_index+1] = v;
-                }
-            } else {
-                x = y >> 5;
-                y = y & 0x0f;
-                x += y;
-                if (x < 15) {
-                    READ_FLIP_SIGN(g->sb_hybrid + s_index + !!y, RENAME(expval_table)[exponent] + x)
-                } else {
-                    x += get_bitsz(&s->gb, linbits);
-                    v  = l3_unscale(x, exponent);
-                    if (get_bits1(&s->gb))
-                        v = -v;
-                    g->sb_hybrid[s_index+!!y] = v;
-                }
-                g->sb_hybrid[s_index + !y] = 0;
-            }
-            s_index += 2;
-        }
-    }
-
-    /* high frequencies */
-    vlc = &huff_quad_vlc[g->count1table_select];
-    last_pos = 0;
-    while (s_index <= 572) {
-        int pos, code;
-        pos = get_bits_count(&s->gb);
-        if (pos >= end_pos) {
-            if (pos > end_pos2 && last_pos) {
-                /* some encoders generate an incorrect size for this
-                   part. We must go back into the data */
-                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)
-                    s_index=0;
-                break;
-            }
-            switch_buffer(s, &pos, &end_pos, &end_pos2);
-            if (pos >= end_pos)
-                break;
-        }
-        last_pos = pos;
-
-        code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1);
-        av_dlog(s->avctx, "t=%d code=%d\n", g->count1table_select, code);
-        g->sb_hybrid[s_index+0] =
-        g->sb_hybrid[s_index+1] =
-        g->sb_hybrid[s_index+2] =
-        g->sb_hybrid[s_index+3] = 0;
-        while (code) {
-            static const int idxtab[16] = { 3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 };
-            int v;
-            int pos = s_index + idxtab[code];
-            code   ^= 8 >> idxtab[code];
-            READ_FLIP_SIGN(g->sb_hybrid + pos, RENAME(exp_table)+exponents[pos])
-        }
-        s_index += 4;
-    }
-    /* skip extension bits */
-    bits_left = end_pos2 - get_bits_count(&s->gb);
-    if (bits_left < 0 && (s->err_recognition & AV_EF_BUFFER)) {
-        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)) {
-        av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
-        s_index = 0;
-    }
-    memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * (576 - s_index));
-    skip_bits_long(&s->gb, bits_left);
-
-    i = get_bits_count(&s->gb);
-    switch_buffer(s, &i, &end_pos, &end_pos2);
-
-    return 0;
-}
-
-/* Reorder short blocks from bitstream order to interleaved order. It
-   would be faster to do it in parsing, but the code would be far more
-   complicated */
-static void reorder_block(MPADecodeContext *s, GranuleDef *g)
-{
-    int i, j, len;
-    INTFLOAT *ptr, *dst, *ptr1;
-    INTFLOAT tmp[576];
-
-    if (g->block_type != 2)
-        return;
-
-    if (g->switch_point) {
-        if (s->sample_rate_index != 8)
-            ptr = g->sb_hybrid + 36;
-        else
-            ptr = g->sb_hybrid + 72;
-    } else {
-        ptr = g->sb_hybrid;
-    }
-
-    for (i = g->short_start; i < 13; i++) {
-        len  = band_size_short[s->sample_rate_index][i];
-        ptr1 = ptr;
-        dst  = tmp;
-        for (j = len; j > 0; j--) {
-            *dst++ = ptr[0*len];
-            *dst++ = ptr[1*len];
-            *dst++ = ptr[2*len];
-            ptr++;
-        }
-        ptr += 2 * len;
-        memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1));
-    }
-}
-
-#define ISQRT2 FIXR(0.70710678118654752440)
-
-static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1)
-{
-    int i, j, k, l;
-    int sf_max, sf, len, non_zero_found;
-    INTFLOAT (*is_tab)[16], *tab0, *tab1, tmp0, tmp1, v1, v2;
-    int non_zero_found_short[3];
-
-    /* intensity stereo */
-    if (s->mode_ext & MODE_EXT_I_STEREO) {
-        if (!s->lsf) {
-            is_tab = is_table;
-            sf_max = 7;
-        } else {
-            is_tab = is_table_lsf[g1->scalefac_compress & 1];
-            sf_max = 16;
-        }
-
-        tab0 = g0->sb_hybrid + 576;
-        tab1 = g1->sb_hybrid + 576;
-
-        non_zero_found_short[0] = 0;
-        non_zero_found_short[1] = 0;
-        non_zero_found_short[2] = 0;
-        k = (13 - g1->short_start) * 3 + g1->long_end - 3;
-        for (i = 12; i >= g1->short_start; i--) {
-            /* for last band, use previous scale factor */
-            if (i != 11)
-                k -= 3;
-            len = band_size_short[s->sample_rate_index][i];
-            for (l = 2; l >= 0; l--) {
-                tab0 -= len;
-                tab1 -= len;
-                if (!non_zero_found_short[l]) {
-                    /* test if non zero band. if so, stop doing i-stereo */
-                    for (j = 0; j < len; j++) {
-                        if (tab1[j] != 0) {
-                            non_zero_found_short[l] = 1;
-                            goto found1;
-                        }
-                    }
-                    sf = g1->scale_factors[k + l];
-                    if (sf >= sf_max)
-                        goto found1;
-
-                    v1 = is_tab[0][sf];
-                    v2 = is_tab[1][sf];
-                    for (j = 0; j < len; j++) {
-                        tmp0    = tab0[j];
-                        tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
-                        tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
-                    }
-                } else {
-found1:
-                    if (s->mode_ext & MODE_EXT_MS_STEREO) {
-                        /* lower part of the spectrum : do ms stereo
-                           if enabled */
-                        for (j = 0; j < len; j++) {
-                            tmp0    = tab0[j];
-                            tmp1    = tab1[j];
-                            tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
-                            tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
-                        }
-                    }
-                }
-            }
-        }
-
-        non_zero_found = non_zero_found_short[0] |
-                         non_zero_found_short[1] |
-                         non_zero_found_short[2];
-
-        for (i = g1->long_end - 1;i >= 0;i--) {
-            len   = band_size_long[s->sample_rate_index][i];
-            tab0 -= len;
-            tab1 -= len;
-            /* test if non zero band. if so, stop doing i-stereo */
-            if (!non_zero_found) {
-                for (j = 0; j < len; j++) {
-                    if (tab1[j] != 0) {
-                        non_zero_found = 1;
-                        goto found2;
-                    }
-                }
-                /* for last band, use previous scale factor */
-                k  = (i == 21) ? 20 : i;
-                sf = g1->scale_factors[k];
-                if (sf >= sf_max)
-                    goto found2;
-                v1 = is_tab[0][sf];
-                v2 = is_tab[1][sf];
-                for (j = 0; j < len; j++) {
-                    tmp0    = tab0[j];
-                    tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
-                    tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
-                }
-            } else {
-found2:
-                if (s->mode_ext & MODE_EXT_MS_STEREO) {
-                    /* lower part of the spectrum : do ms stereo
-                       if enabled */
-                    for (j = 0; j < len; j++) {
-                        tmp0    = tab0[j];
-                        tmp1    = tab1[j];
-                        tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
-                        tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
-                    }
-                }
-            }
-        }
-    } else if (s->mode_ext & MODE_EXT_MS_STEREO) {
-        /* ms stereo ONLY */
-        /* NOTE: the 1/sqrt(2) normalization factor is included in the
-           global gain */
-#if CONFIG_FLOAT
-       s-> dsp.butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
-#else
-        tab0 = g0->sb_hybrid;
-        tab1 = g1->sb_hybrid;
-        for (i = 0; i < 576; i++) {
-            tmp0    = tab0[i];
-            tmp1    = tab1[i];
-            tab0[i] = tmp0 + tmp1;
-            tab1[i] = tmp0 - tmp1;
-        }
-#endif
-    }
-}
-
-#if CONFIG_FLOAT
-#define AA(j) do {                                                      \
-        float tmp0 = ptr[-1-j];                                         \
-        float tmp1 = ptr[   j];                                         \
-        ptr[-1-j] = tmp0 * csa_table[j][0] - tmp1 * csa_table[j][1];    \
-        ptr[   j] = tmp0 * csa_table[j][1] + tmp1 * csa_table[j][0];    \
-    } while (0)
-#else
-#define AA(j) do {                                              \
-        int tmp0 = ptr[-1-j];                                   \
-        int tmp1 = ptr[   j];                                   \
-        int tmp2 = MULH(tmp0 + tmp1, csa_table[j][0]);          \
-        ptr[-1-j] = 4 * (tmp2 - MULH(tmp1, csa_table[j][2]));   \
-        ptr[   j] = 4 * (tmp2 + MULH(tmp0, csa_table[j][3]));   \
-    } while (0)
-#endif
-
-static void compute_antialias(MPADecodeContext *s, GranuleDef *g)
-{
-    INTFLOAT *ptr;
-    int n, i;
-
-    /* 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--) {
-        AA(0);
-        AA(1);
-        AA(2);
-        AA(3);
-        AA(4);
-        AA(5);
-        AA(6);
-        AA(7);
-
-        ptr += 18;
-    }
-}
-
-static void compute_imdct(MPADecodeContext *s, GranuleDef *g,
-                          INTFLOAT *sb_samples, INTFLOAT *mdct_buf)
-{
-    INTFLOAT *win, *out_ptr, *ptr, *buf, *ptr1;
-    INTFLOAT out2[12];
-    int i, j, mdct_long_end, sblimit;
-
-    /* find last non zero block */
-    ptr  = g->sb_hybrid + 576;
-    ptr1 = g->sb_hybrid + 2 * 18;
-    while (ptr >= ptr1) {
-        int32_t *p;
-        ptr -= 6;
-        p    = (int32_t*)ptr;
-        if (p[0] | p[1] | p[2] | p[3] | p[4] | p[5])
-            break;
-    }
-    sblimit = ((ptr - g->sb_hybrid) / 18) + 1;
-
-    if (g->block_type == 2) {
-        /* XXX: check for 8000 Hz */
-        if (g->switch_point)
-            mdct_long_end = 2;
-        else
-            mdct_long_end = 0;
-    } else {
-        mdct_long_end = sblimit;
-    }
-
-    s->mpadsp.RENAME(imdct36_blocks)(sb_samples, mdct_buf, g->sb_hybrid,
-                                     mdct_long_end, g->switch_point,
-                                     g->block_type);
-
-    buf = mdct_buf + 4*18*(mdct_long_end >> 2) + (mdct_long_end & 3);
-    ptr = g->sb_hybrid + 18 * mdct_long_end;
-
-    for (j = mdct_long_end; j < sblimit; j++) {
-        /* select frequency inversion */
-        win     = RENAME(ff_mdct_win)[2 + (4  & -(j & 1))];
-        out_ptr = sb_samples + j;
-
-        for (i = 0; i < 6; i++) {
-            *out_ptr = buf[4*i];
-            out_ptr += SBLIMIT;
-        }
-        imdct12(out2, ptr + 0);
-        for (i = 0; i < 6; i++) {
-            *out_ptr     = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*1)];
-            buf[4*(i + 6*2)] = MULH3(out2[i + 6], win[i + 6], 1);
-            out_ptr += SBLIMIT;
-        }
-        imdct12(out2, ptr + 1);
-        for (i = 0; i < 6; i++) {
-            *out_ptr     = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*2)];
-            buf[4*(i + 6*0)] = MULH3(out2[i + 6], win[i + 6], 1);
-            out_ptr += SBLIMIT;
-        }
-        imdct12(out2, ptr + 2);
-        for (i = 0; i < 6; i++) {
-            buf[4*(i + 6*0)] = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*0)];
-            buf[4*(i + 6*1)] = MULH3(out2[i + 6], win[i + 6], 1);
-            buf[4*(i + 6*2)] = 0;
-        }
-        ptr += 18;
-        buf += (j&3) != 3 ? 1 : (4*18-3);
-    }
-    /* zero bands */
-    for (j = sblimit; j < SBLIMIT; j++) {
-        /* overlap */
-        out_ptr = sb_samples + j;
-        for (i = 0; i < 18; i++) {
-            *out_ptr = buf[4*i];
-            buf[4*i]   = 0;
-            out_ptr += SBLIMIT;
-        }
-        buf += (j&3) != 3 ? 1 : (4*18-3);
-    }
-}
-
-/* main layer3 decoding function */
-static int mp_decode_layer3(MPADecodeContext *s)
-{
-    int nb_granules, main_data_begin;
-    int gr, ch, blocksplit_flag, i, j, k, n, bits_pos;
-    GranuleDef *g;
-    int16_t exponents[576]; //FIXME try INTFLOAT
-
-    /* read side info */
-    if (s->lsf) {
-        main_data_begin = get_bits(&s->gb, 8);
-        skip_bits(&s->gb, s->nb_channels);
-        nb_granules = 1;
-    } else {
-        main_data_begin = get_bits(&s->gb, 9);
-        if (s->nb_channels == 2)
-            skip_bits(&s->gb, 3);
-        else
-            skip_bits(&s->gb, 5);
-        nb_granules = 2;
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */
-            s->granules[ch][1].scfsi = get_bits(&s->gb, 4);
-        }
-    }
-
-    for (gr = 0; gr < nb_granules; gr++) {
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            av_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);
-            g = &s->granules[ch][gr];
-            g->part2_3_length = get_bits(&s->gb, 12);
-            g->big_values     = get_bits(&s->gb,  9);
-            if (g->big_values > 288) {
-                av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n");
-                return AVERROR_INVALIDDATA;
-            }
-
-            g->global_gain = get_bits(&s->gb, 8);
-            /* if MS stereo only is selected, we precompute the
-               1/sqrt(2) renormalization factor */
-            if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) ==
-                MODE_EXT_MS_STEREO)
-                g->global_gain -= 2;
-            if (s->lsf)
-                g->scalefac_compress = get_bits(&s->gb, 9);
-            else
-                g->scalefac_compress = get_bits(&s->gb, 4);
-            blocksplit_flag = get_bits1(&s->gb);
-            if (blocksplit_flag) {
-                g->block_type = get_bits(&s->gb, 2);
-                if (g->block_type == 0) {
-                    av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n");
-                    return AVERROR_INVALIDDATA;
-                }
-                g->switch_point = get_bits1(&s->gb);
-                for (i = 0; i < 2; i++)
-                    g->table_select[i] = get_bits(&s->gb, 5);
-                for (i = 0; i < 3; i++)
-                    g->subblock_gain[i] = get_bits(&s->gb, 3);
-                ff_init_short_region(s, g);
-            } else {
-                int region_address1, region_address2;
-                g->block_type = 0;
-                g->switch_point = 0;
-                for (i = 0; i < 3; i++)
-                    g->table_select[i] = get_bits(&s->gb, 5);
-                /* compute huffman coded region sizes */
-                region_address1 = get_bits(&s->gb, 4);
-                region_address2 = get_bits(&s->gb, 3);
-                av_dlog(s->avctx, "region1=%d region2=%d\n",
-                        region_address1, region_address2);
-                ff_init_long_region(s, g, region_address1, region_address2);
-            }
-            ff_region_offset2size(g);
-            ff_compute_band_indexes(s, g);
-
-            g->preflag = 0;
-            if (!s->lsf)
-                g->preflag = get_bits1(&s->gb);
-            g->scalefac_scale     = get_bits1(&s->gb);
-            g->count1table_select = get_bits1(&s->gb);
-            av_dlog(s->avctx, "block_type=%d switch_point=%d\n",
-                    g->block_type, g->switch_point);
-        }
-    }
-
-    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);
-        /* 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);
-
-        memcpy(s->last_buf + s->last_buf_size, ptr, extrasize);
-        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;
-#endif
-        s->last_buf_size <<= 3;
-        for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) {
-            for (ch = 0; ch < s->nb_channels; ch++) {
-                g = &s->granules[ch][gr];
-                s->last_buf_size += g->part2_3_length;
-                memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
-                compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
-            }
-        }
-        skip = s->last_buf_size - 8 * main_data_begin;
-        if (skip >= s->gb.size_in_bits && s->in_gb.buffer) {
-            skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits);
-            s->gb           = s->in_gb;
-            s->in_gb.buffer = NULL;
-        } else {
-            skip_bits_long(&s->gb, skip);
-        }
-    } else {
-        gr = 0;
-    }
-
-    for (; gr < nb_granules; gr++) {
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            g = &s->granules[ch][gr];
-            bits_pos = get_bits_count(&s->gb);
-
-            if (!s->lsf) {
-                uint8_t *sc;
-                int slen, slen1, slen2;
-
-                /* MPEG1 scale factors */
-                slen1 = slen_table[0][g->scalefac_compress];
-                slen2 = slen_table[1][g->scalefac_compress];
-                av_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2);
-                if (g->block_type == 2) {
-                    n = g->switch_point ? 17 : 18;
-                    j = 0;
-                    if (slen1) {
-                        for (i = 0; i < n; i++)
-                            g->scale_factors[j++] = get_bits(&s->gb, slen1);
-                    } else {
-                        for (i = 0; i < n; i++)
-                            g->scale_factors[j++] = 0;
-                    }
-                    if (slen2) {
-                        for (i = 0; i < 18; i++)
-                            g->scale_factors[j++] = get_bits(&s->gb, slen2);
-                        for (i = 0; i < 3; i++)
-                            g->scale_factors[j++] = 0;
-                    } else {
-                        for (i = 0; i < 21; i++)
-                            g->scale_factors[j++] = 0;
-                    }
-                } else {
-                    sc = s->granules[ch][0].scale_factors;
-                    j = 0;
-                    for (k = 0; k < 4; k++) {
-                        n = k == 0 ? 6 : 5;
-                        if ((g->scfsi & (0x8 >> k)) == 0) {
-                            slen = (k < 2) ? slen1 : slen2;
-                            if (slen) {
-                                for (i = 0; i < n; i++)
-                                    g->scale_factors[j++] = get_bits(&s->gb, slen);
-                            } else {
-                                for (i = 0; i < n; i++)
-                                    g->scale_factors[j++] = 0;
-                            }
-                        } else {
-                            /* simply copy from last granule */
-                            for (i = 0; i < n; i++) {
-                                g->scale_factors[j] = sc[j];
-                                j++;
-                            }
-                        }
-                    }
-                    g->scale_factors[j++] = 0;
-                }
-            } else {
-                int tindex, tindex2, slen[4], sl, sf;
-
-                /* LSF scale factors */
-                if (g->block_type == 2)
-                    tindex = g->switch_point ? 2 : 1;
-                else
-                    tindex = 0;
-
-                sf = g->scalefac_compress;
-                if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) {
-                    /* intensity stereo case */
-                    sf >>= 1;
-                    if (sf < 180) {
-                        lsf_sf_expand(slen, sf, 6, 6, 0);
-                        tindex2 = 3;
-                    } else if (sf < 244) {
-                        lsf_sf_expand(slen, sf - 180, 4, 4, 0);
-                        tindex2 = 4;
-                    } else {
-                        lsf_sf_expand(slen, sf - 244, 3, 0, 0);
-                        tindex2 = 5;
-                    }
-                } else {
-                    /* normal case */
-                    if (sf < 400) {
-                        lsf_sf_expand(slen, sf, 5, 4, 4);
-                        tindex2 = 0;
-                    } else if (sf < 500) {
-                        lsf_sf_expand(slen, sf - 400, 5, 4, 0);
-                        tindex2 = 1;
-                    } else {
-                        lsf_sf_expand(slen, sf - 500, 3, 0, 0);
-                        tindex2 = 2;
-                        g->preflag = 1;
-                    }
-                }
-
-                j = 0;
-                for (k = 0; k < 4; k++) {
-                    n  = lsf_nsf_table[tindex2][tindex][k];
-                    sl = slen[k];
-                    if (sl) {
-                        for (i = 0; i < n; i++)
-                            g->scale_factors[j++] = get_bits(&s->gb, sl);
-                    } else {
-                        for (i = 0; i < n; i++)
-                            g->scale_factors[j++] = 0;
-                    }
-                }
-                /* XXX: should compute exact size */
-                for (; j < 40; j++)
-                    g->scale_factors[j] = 0;
-            }
-
-            exponents_from_scale_factors(s, g, exponents);
-
-            /* read Huffman coded residue */
-            huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);
-        } /* ch */
-
-        if (s->mode == MPA_JSTEREO)
-            compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]);
-
-        for (ch = 0; ch < s->nb_channels; ch++) {
-            g = &s->granules[ch][gr];
-
-            reorder_block(s, g);
-            compute_antialias(s, g);
-            compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
-        }
-    } /* gr */
-    if (get_bits_count(&s->gb) < 0)
-        skip_bits_long(&s->gb, -get_bits_count(&s->gb));
-    return nb_granules * 18;
-}
-
-static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples,
-                           const uint8_t *buf, int buf_size)
-{
-    int i, nb_frames, ch, ret;
-    OUT_INT *samples_ptr;
-
-    init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
-
-    /* skip error protection field */
-    if (s->error_protection)
-        skip_bits(&s->gb, 16);
-
-    switch(s->layer) {
-    case 1:
-        s->avctx->frame_size = 384;
-        nb_frames = mp_decode_layer1(s);
-        break;
-    case 2:
-        s->avctx->frame_size = 1152;
-        nb_frames = mp_decode_layer2(s);
-        break;
-    case 3:
-        s->avctx->frame_size = s->lsf ? 576 : 1152;
-    default:
-        nb_frames = mp_decode_layer3(s);
-
-        if (nb_frames < 0)
-            return nb_frames;
-
-        s->last_buf_size=0;
-        if (s->in_gb.buffer) {
-            align_get_bits(&s->gb);
-            i = get_bits_left(&s->gb)>>3;
-            if (i >= 0 && i <= BACKSTEP_SIZE) {
-                memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i);
-                s->last_buf_size=i;
-            } else
-                av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i);
-            s->gb           = s->in_gb;
-            s->in_gb.buffer = NULL;
-        }
-
-        align_get_bits(&s->gb);
-        assert((get_bits_count(&s->gb) & 7) == 0);
-        i = get_bits_left(&s->gb) >> 3;
-
-        if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) {
-            if (i < 0)
-                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);
-        memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i);
-        s->last_buf_size += i;
-    }
-
-    /* get output buffer */
-    if (!samples) {
-        s->frame.nb_samples = s->avctx->frame_size;
-        if ((ret = ff_get_buffer(s->avctx, &s->frame)) < 0) {
-            av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return ret;
-        }
-        samples = (OUT_INT **)s->frame.extended_data;
-    }
-
-    /* apply the synthesis filter */
-    for (ch = 0; ch < s->nb_channels; ch++) {
-        int sample_stride;
-        if (s->avctx->sample_fmt == OUT_FMT_P) {
-            samples_ptr   = samples[ch];
-            sample_stride = 1;
-        } else {
-            samples_ptr   = samples[0] + ch;
-            sample_stride = s->nb_channels;
-        }
-        for (i = 0; i < nb_frames; i++) {
-            RENAME(ff_mpa_synth_filter)(&s->mpadsp, s->synth_buf[ch],
-                                        &(s->synth_buf_offset[ch]),
-                                        RENAME(ff_mpa_synth_window),
-                                        &s->dither_state, samples_ptr,
-                                        sample_stride, s->sb_samples[ch][i]);
-            samples_ptr += 32 * sample_stride;
-        }
-    }
-
-    return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels;
-}
-
-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;
-    MPADecodeContext *s = avctx->priv_data;
-    uint32_t header;
-    int ret;
-
-    if (buf_size < HEADER_SIZE)
-        return AVERROR_INVALIDDATA;
-
-    header = AV_RB32(buf);
-    if (ff_mpa_check_header(header) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Header missing\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
-        /* free format: prepare to compute frame size */
-        s->frame_size = -1;
-        return AVERROR_INVALIDDATA;
-    }
-    /* update codec info */
-    avctx->channels       = s->nb_channels;
-    avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
-    if (!avctx->bit_rate)
-        avctx->bit_rate = s->bit_rate;
-
-    if (s->frame_size <= 0 || s->frame_size > buf_size) {
-        av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
-        return AVERROR_INVALIDDATA;
-    } else if (s->frame_size < buf_size) {
-        buf_size= s->frame_size;
-    }
-
-    ret = mp_decode_frame(s, NULL, buf, buf_size);
-    if (ret >= 0) {
-        *got_frame_ptr   = 1;
-        *(AVFrame *)data = s->frame;
-        avctx->sample_rate = s->sample_rate;
-        //FIXME maybe move the other codec info stuff from above here too
-    } else {
-        av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
-        /* Only return an error if the bad frame makes up the whole packet or
-         * the error is related to buffer management.
-         * If there is more data in the packet, just consume the bad frame
-         * instead of returning an error, which would discard the whole
-         * packet. */
-        *got_frame_ptr = 0;
-        if (buf_size == avpkt->size || ret != AVERROR_INVALIDDATA)
-            return ret;
-    }
-    s->frame_size = 0;
-    return buf_size;
-}
-
-static void mp_flush(MPADecodeContext *ctx)
-{
-    memset(ctx->synth_buf, 0, sizeof(ctx->synth_buf));
-    ctx->last_buf_size = 0;
-}
-
-static void flush(AVCodecContext *avctx)
-{
-    mp_flush(avctx->priv_data);
-}
-
-#if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER
-static int decode_frame_adu(AVCodecContext *avctx, void *data,
-                            int *got_frame_ptr, AVPacket *avpkt)
-{
-    const uint8_t *buf  = avpkt->data;
-    int buf_size        = avpkt->size;
-    MPADecodeContext *s = avctx->priv_data;
-    uint32_t header;
-    int len, ret;
-
-    len = buf_size;
-
-    // Discard too short frames
-    if (buf_size < HEADER_SIZE) {
-        av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-
-    if (len > MPA_MAX_CODED_FRAME_SIZE)
-        len = MPA_MAX_CODED_FRAME_SIZE;
-
-    // Get header and restore sync word
-    header = AV_RB32(buf) | 0xffe00000;
-
-    if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame
-        av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
-    /* update codec info */
-    avctx->sample_rate = s->sample_rate;
-    avctx->channels    = s->nb_channels;
-    if (!avctx->bit_rate)
-        avctx->bit_rate = s->bit_rate;
-
-    s->frame_size = len;
-
-    ret = mp_decode_frame(s, NULL, buf, buf_size);
-    if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
-        return ret;
-    }
-
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
-
-    return buf_size;
-}
-#endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */
-
-#if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
-
-/**
- * Context for MP3On4 decoder
- */
-typedef struct MP3On4DecodeContext {
-    AVFrame *frame;
-    int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
-    int syncword;                   ///< syncword patch
-    const uint8_t *coff;            ///< channel offsets in output buffer
-    MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
-} MP3On4DecodeContext;
-
-#include "mpeg4audio.h"
-
-/* Next 3 arrays are indexed by channel config number (passed via codecdata) */
-
-/* number of mp3 decoder instances */
-static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 };
-
-/* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */
-static const uint8_t chan_offset[8][5] = {
-    { 0             },
-    { 0             },  // C
-    { 0             },  // FLR
-    { 2, 0          },  // C FLR
-    { 2, 0, 3       },  // C FLR BS
-    { 2, 0, 3       },  // C FLR BLRS
-    { 2, 0, 4, 3    },  // C FLR BLRS LFE
-    { 2, 0, 6, 4, 3 },  // C FLR BLRS BLR LFE
-};
-
-/* mp3on4 channel layouts */
-static const int16_t chan_layout[8] = {
-    0,
-    AV_CH_LAYOUT_MONO,
-    AV_CH_LAYOUT_STEREO,
-    AV_CH_LAYOUT_SURROUND,
-    AV_CH_LAYOUT_4POINT0,
-    AV_CH_LAYOUT_5POINT0,
-    AV_CH_LAYOUT_5POINT1,
-    AV_CH_LAYOUT_7POINT1
-};
-
-static av_cold int decode_close_mp3on4(AVCodecContext * avctx)
-{
-    MP3On4DecodeContext *s = avctx->priv_data;
-    int i;
-
-    for (i = 0; i < s->frames; i++)
-        av_free(s->mp3decctx[i]);
-
-    return 0;
-}
-
-
-static int decode_init_mp3on4(AVCodecContext * avctx)
-{
-    MP3On4DecodeContext *s = avctx->priv_data;
-    MPEG4AudioConfig cfg;
-    int i;
-
-    if ((avctx->extradata_size < 2) || (avctx->extradata == NULL)) {
-        av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    avpriv_mpeg4audio_get_config(&cfg, avctx->extradata,
-                                 avctx->extradata_size * 8, 1);
-    if (!cfg.chan_config || cfg.chan_config > 7) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
-        return AVERROR_INVALIDDATA;
-    }
-    s->frames             = mp3Frames[cfg.chan_config];
-    s->coff               = chan_offset[cfg.chan_config];
-    avctx->channels       = ff_mpeg4audio_channels[cfg.chan_config];
-    avctx->channel_layout = chan_layout[cfg.chan_config];
-
-    if (cfg.sample_rate < 16000)
-        s->syncword = 0xffe00000;
-    else
-        s->syncword = 0xfff00000;
-
-    /* Init the first mp3 decoder in standard way, so that all tables get builded
-     * We replace avctx->priv_data with the context of the first decoder so that
-     * decode_init() does not have to be changed.
-     * Other decoders will be initialized here copying data from the first context
-     */
-    // Allocate zeroed memory for the first decoder context
-    s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext));
-    if (!s->mp3decctx[0])
-        goto alloc_fail;
-    // Put decoder context in place to make init_decode() happy
-    avctx->priv_data = s->mp3decctx[0];
-    decode_init(avctx);
-    s->frame = avctx->coded_frame;
-    // Restore mp3on4 context pointer
-    avctx->priv_data = s;
-    s->mp3decctx[0]->adu_mode = 1; // Set adu mode
-
-    /* Create a separate codec/context for each frame (first is already ok).
-     * Each frame is 1 or 2 channels - up to 5 frames allowed
-     */
-    for (i = 1; i < s->frames; i++) {
-        s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext));
-        if (!s->mp3decctx[i])
-            goto alloc_fail;
-        s->mp3decctx[i]->adu_mode = 1;
-        s->mp3decctx[i]->avctx = avctx;
-        s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;
-    }
-
-    return 0;
-alloc_fail:
-    decode_close_mp3on4(avctx);
-    return AVERROR(ENOMEM);
-}
-
-
-static void flush_mp3on4(AVCodecContext *avctx)
-{
-    int i;
-    MP3On4DecodeContext *s = avctx->priv_data;
-
-    for (i = 0; i < s->frames; i++)
-        mp_flush(s->mp3decctx[i]);
-}
-
-
-static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
-                               int *got_frame_ptr, AVPacket *avpkt)
-{
-    const uint8_t *buf     = avpkt->data;
-    int buf_size           = avpkt->size;
-    MP3On4DecodeContext *s = avctx->priv_data;
-    MPADecodeContext *m;
-    int fsize, len = buf_size, out_size = 0;
-    uint32_t header;
-    OUT_INT **out_samples;
-    OUT_INT *outptr[2];
-    int fr, ch, ret;
-
-    /* get output buffer */
-    s->frame->nb_samples = MPA_FRAME_SIZE;
-    if ((ret = ff_get_buffer(avctx, s->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return ret;
-    }
-    out_samples = (OUT_INT **)s->frame->extended_data;
-
-    // Discard too short frames
-    if (buf_size < HEADER_SIZE)
-        return AVERROR_INVALIDDATA;
-
-    avctx->bit_rate = 0;
-
-    ch = 0;
-    for (fr = 0; fr < s->frames; fr++) {
-        fsize = AV_RB16(buf) >> 4;
-        fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);
-        m     = s->mp3decctx[fr];
-        assert(m != NULL);
-
-        if (fsize < HEADER_SIZE) {
-            av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
-            return AVERROR_INVALIDDATA;
-        }
-        header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
-
-        if (ff_mpa_check_header(header) < 0) // Bad header, discard block
-            break;
-
-        avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
-
-        if (ch + m->nb_channels > avctx->channels ||
-            s->coff[fr] + m->nb_channels > avctx->channels) {
-            av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
-                                        "channel count\n");
-            return AVERROR_INVALIDDATA;
-        }
-        ch += m->nb_channels;
-
-        outptr[0] = out_samples[s->coff[fr]];
-        if (m->nb_channels > 1)
-            outptr[1] = out_samples[s->coff[fr] + 1];
-
-        if ((ret = mp_decode_frame(m, outptr, buf, fsize)) < 0)
-            return ret;
-
-        out_size += ret;
-        buf      += fsize;
-        len      -= fsize;
-
-        avctx->bit_rate += m->bit_rate;
-    }
-
-    /* update codec info */
-    avctx->sample_rate = s->mp3decctx[0]->sample_rate;
-
-    s->frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = *s->frame;
-
-    return buf_size;
-}
-#endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */
-
-#if !CONFIG_FLOAT
-#if CONFIG_MP1_DECODER
-AVCodec ff_mp1_decoder = {
-    .name           = "mp1",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_MP1,
-    .priv_data_size = sizeof(MPADecodeContext),
-    .init           = decode_init,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
-                                                      AV_SAMPLE_FMT_S16,
-                                                      AV_SAMPLE_FMT_NONE },
-};
-#endif
-#if CONFIG_MP2_DECODER
-AVCodec ff_mp2_decoder = {
-    .name           = "mp2",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_MP2,
-    .priv_data_size = sizeof(MPADecodeContext),
-    .init           = decode_init,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
-                                                      AV_SAMPLE_FMT_S16,
-                                                      AV_SAMPLE_FMT_NONE },
-};
-#endif
-#if CONFIG_MP3_DECODER
-AVCodec ff_mp3_decoder = {
-    .name           = "mp3",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_MP3,
-    .priv_data_size = sizeof(MPADecodeContext),
-    .init           = decode_init,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
-                                                      AV_SAMPLE_FMT_S16,
-                                                      AV_SAMPLE_FMT_NONE },
-};
-#endif
-#if CONFIG_MP3ADU_DECODER
-AVCodec ff_mp3adu_decoder = {
-    .name           = "mp3adu",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_MP3ADU,
-    .priv_data_size = sizeof(MPADecodeContext),
-    .init           = decode_init,
-    .decode         = decode_frame_adu,
-    .capabilities   = CODEC_CAP_DR1,
-    .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
-                                                      AV_SAMPLE_FMT_S16,
-                                                      AV_SAMPLE_FMT_NONE },
-};
-#endif
-#if CONFIG_MP3ON4_DECODER
-AVCodec ff_mp3on4_decoder = {
-    .name           = "mp3on4",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_MP3ON4,
-    .priv_data_size = sizeof(MP3On4DecodeContext),
-    .init           = decode_init_mp3on4,
-    .close          = decode_close_mp3on4,
-    .decode         = decode_frame_mp3on4,
-    .capabilities   = CODEC_CAP_DR1,
-    .flush          = flush_mp3on4,
-    .long_name      = NULL_IF_CONFIG_SMALL("MP3onMP4"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
-                                                      AV_SAMPLE_FMT_NONE },
-};
-#endif
-#endif
diff --git a/libavcodec/mpegaudiodec_fixed.c b/libavcodec/mpegaudiodec_fixed.c
new file mode 100644
index 0000000..6f21b0c
--- /dev/null
+++ b/libavcodec/mpegaudiodec_fixed.c
@@ -0,0 +1,120 @@
+/*
+ * Fixed-point MPEG audio decoder
+ *
+ * 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 "libavutil/samplefmt.h"
+
+#define CONFIG_FLOAT 0
+
+#include "mpegaudio.h"
+
+#define SHR(a,b)       ((a)>>(b))
+/* WARNING: only correct for positive numbers */
+#define FIXR_OLD(a)    ((int)((a) * FRAC_ONE + 0.5))
+#define FIXR(a)        ((int)((a) * FRAC_ONE + 0.5))
+#define FIXHR(a)       ((int)((a) * (1LL<<32) + 0.5))
+#define MULH3(x, y, s) MULH((s)*(x), y)
+#define MULLx(x, y, s) MULL(x,y,s)
+#define RENAME(a)      a ## _fixed
+#define OUT_FMT   AV_SAMPLE_FMT_S16
+#define OUT_FMT_P AV_SAMPLE_FMT_S16P
+
+#include "mpegaudiodec_template.c"
+
+#if CONFIG_MP1_DECODER
+AVCodec ff_mp1_decoder = {
+    .name           = "mp1",
+    .long_name      = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_MP1,
+    .priv_data_size = sizeof(MPADecodeContext),
+    .init           = decode_init,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .flush          = flush,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+                                                      AV_SAMPLE_FMT_S16,
+                                                      AV_SAMPLE_FMT_NONE },
+};
+#endif
+#if CONFIG_MP2_DECODER
+AVCodec ff_mp2_decoder = {
+    .name           = "mp2",
+    .long_name      = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_MP2,
+    .priv_data_size = sizeof(MPADecodeContext),
+    .init           = decode_init,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .flush          = flush,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+                                                      AV_SAMPLE_FMT_S16,
+                                                      AV_SAMPLE_FMT_NONE },
+};
+#endif
+#if CONFIG_MP3_DECODER
+AVCodec ff_mp3_decoder = {
+    .name           = "mp3",
+    .long_name      = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_MP3,
+    .priv_data_size = sizeof(MPADecodeContext),
+    .init           = decode_init,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .flush          = flush,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+                                                      AV_SAMPLE_FMT_S16,
+                                                      AV_SAMPLE_FMT_NONE },
+};
+#endif
+#if CONFIG_MP3ADU_DECODER
+AVCodec ff_mp3adu_decoder = {
+    .name           = "mp3adu",
+    .long_name      = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_MP3ADU,
+    .priv_data_size = sizeof(MPADecodeContext),
+    .init           = decode_init,
+    .decode         = decode_frame_adu,
+    .capabilities   = CODEC_CAP_DR1,
+    .flush          = flush,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+                                                      AV_SAMPLE_FMT_S16,
+                                                      AV_SAMPLE_FMT_NONE },
+};
+#endif
+#if CONFIG_MP3ON4_DECODER
+AVCodec ff_mp3on4_decoder = {
+    .name           = "mp3on4",
+    .long_name      = NULL_IF_CONFIG_SMALL("MP3onMP4"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_MP3ON4,
+    .priv_data_size = sizeof(MP3On4DecodeContext),
+    .init           = decode_init_mp3on4,
+    .close          = decode_close_mp3on4,
+    .decode         = decode_frame_mp3on4,
+    .capabilities   = CODEC_CAP_DR1,
+    .flush          = flush_mp3on4,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+                                                      AV_SAMPLE_FMT_NONE },
+};
+#endif
diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c
index ac8df32..3a76055 100644
--- a/libavcodec/mpegaudiodec_float.c
+++ b/libavcodec/mpegaudiodec_float.c
@@ -19,12 +19,29 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
+#include "libavutil/samplefmt.h"
+
 #define CONFIG_FLOAT 1
-#include "mpegaudiodec.c"
+
+#include "mpegaudio.h"
+
+#define SHR(a,b)       ((a)*(1.0f/(1<<(b))))
+#define FIXR_OLD(a)    ((int)((a) * FRAC_ONE + 0.5))
+#define FIXR(x)        ((float)(x))
+#define FIXHR(x)       ((float)(x))
+#define MULH3(x, y, s) ((s)*(y)*(x))
+#define MULLx(x, y, s) ((y)*(x))
+#define RENAME(a) a ## _float
+#define OUT_FMT   AV_SAMPLE_FMT_FLT
+#define OUT_FMT_P AV_SAMPLE_FMT_FLTP
+
+#include "mpegaudiodec_template.c"
 
 #if CONFIG_MP1FLOAT_DECODER
 AVCodec ff_mp1float_decoder = {
     .name           = "mp1float",
+    .long_name      = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MP1,
     .priv_data_size = sizeof(MPADecodeContext),
@@ -32,7 +49,6 @@ AVCodec ff_mp1float_decoder = {
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_FLT,
                                                       AV_SAMPLE_FMT_NONE },
@@ -41,6 +57,7 @@ AVCodec ff_mp1float_decoder = {
 #if CONFIG_MP2FLOAT_DECODER
 AVCodec ff_mp2float_decoder = {
     .name           = "mp2float",
+    .long_name      = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MP2,
     .priv_data_size = sizeof(MPADecodeContext),
@@ -48,7 +65,6 @@ AVCodec ff_mp2float_decoder = {
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_FLT,
                                                       AV_SAMPLE_FMT_NONE },
@@ -57,6 +73,7 @@ AVCodec ff_mp2float_decoder = {
 #if CONFIG_MP3FLOAT_DECODER
 AVCodec ff_mp3float_decoder = {
     .name           = "mp3float",
+    .long_name      = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MP3,
     .priv_data_size = sizeof(MPADecodeContext),
@@ -64,7 +81,6 @@ AVCodec ff_mp3float_decoder = {
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_FLT,
                                                       AV_SAMPLE_FMT_NONE },
@@ -73,6 +89,7 @@ AVCodec ff_mp3float_decoder = {
 #if CONFIG_MP3ADUFLOAT_DECODER
 AVCodec ff_mp3adufloat_decoder = {
     .name           = "mp3adufloat",
+    .long_name      = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MP3ADU,
     .priv_data_size = sizeof(MPADecodeContext),
@@ -80,7 +97,6 @@ AVCodec ff_mp3adufloat_decoder = {
     .decode         = decode_frame_adu,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_FLT,
                                                       AV_SAMPLE_FMT_NONE },
@@ -89,6 +105,7 @@ AVCodec ff_mp3adufloat_decoder = {
 #if CONFIG_MP3ON4FLOAT_DECODER
 AVCodec ff_mp3on4float_decoder = {
     .name           = "mp3on4float",
+    .long_name      = NULL_IF_CONFIG_SMALL("MP3onMP4"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_MP3ON4,
     .priv_data_size = sizeof(MP3On4DecodeContext),
@@ -97,7 +114,6 @@ AVCodec ff_mp3on4float_decoder = {
     .decode         = decode_frame_mp3on4,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = flush_mp3on4,
-    .long_name      = NULL_IF_CONFIG_SMALL("MP3onMP4"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c
new file mode 100644
index 0000000..9ce03ef
--- /dev/null
+++ b/libavcodec/mpegaudiodec_template.c
@@ -0,0 +1,1948 @@
+/*
+ * MPEG Audio decoder
+ * Copyright (c) 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
+ */
+
+/**
+ * @file
+ * MPEG Audio decoder
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "mathops.h"
+#include "mpegaudiodsp.h"
+
+/*
+ * TODO:
+ *  - test lsf / mpeg25 extensively.
+ */
+
+#include "mpegaudio.h"
+#include "mpegaudiodecheader.h"
+
+#define BACKSTEP_SIZE 512
+#define EXTRABYTES 24
+#define LAST_BUF_SIZE 2 * BACKSTEP_SIZE + EXTRABYTES
+
+/* layer 3 "granule" */
+typedef struct GranuleDef {
+    uint8_t scfsi;
+    int part2_3_length;
+    int big_values;
+    int global_gain;
+    int scalefac_compress;
+    uint8_t block_type;
+    uint8_t switch_point;
+    int table_select[3];
+    int subblock_gain[3];
+    uint8_t scalefac_scale;
+    uint8_t count1table_select;
+    int region_size[3]; /* number of huffman codes in each region */
+    int preflag;
+    int short_start, long_end; /* long/short band indexes */
+    uint8_t scale_factors[40];
+    DECLARE_ALIGNED(16, INTFLOAT, sb_hybrid)[SBLIMIT * 18]; /* 576 samples */
+} GranuleDef;
+
+typedef struct MPADecodeContext {
+    MPA_DECODE_HEADER
+    uint8_t last_buf[LAST_BUF_SIZE];
+    int last_buf_size;
+    /* next header (used in free format parsing) */
+    uint32_t free_format_next_header;
+    GetBitContext gb;
+    GetBitContext in_gb;
+    DECLARE_ALIGNED(32, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512 * 2];
+    int synth_buf_offset[MPA_MAX_CHANNELS];
+    DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT];
+    INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
+    GranuleDef granules[2][2]; /* Used in Layer 3 */
+    int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
+    int dither_state;
+    int err_recognition;
+    AVCodecContext* avctx;
+    MPADSPContext mpadsp;
+    AVFloatDSPContext fdsp;
+    AVFrame *frame;
+} MPADecodeContext;
+
+#define HEADER_SIZE 4
+
+#include "mpegaudiodata.h"
+#include "mpegaudiodectab.h"
+
+/* vlc structure for decoding layer 3 huffman tables */
+static VLC huff_vlc[16];
+static VLC_TYPE huff_vlc_tables[
+    0 + 128 + 128 + 128 + 130 + 128 + 154 + 166 +
+  142 + 204 + 190 + 170 + 542 + 460 + 662 + 414
+  ][2];
+static const int huff_vlc_tables_sizes[16] = {
+    0,  128,  128,  128,  130,  128,  154,  166,
+  142,  204,  190,  170,  542,  460,  662,  414
+};
+static VLC huff_quad_vlc[2];
+static VLC_TYPE  huff_quad_vlc_tables[128+16][2];
+static const int huff_quad_vlc_tables_sizes[2] = { 128, 16 };
+/* computed from band_size_long */
+static uint16_t band_index_long[9][23];
+#include "mpegaudio_tablegen.h"
+/* intensity stereo coef table */
+static INTFLOAT is_table[2][16];
+static INTFLOAT is_table_lsf[2][2][16];
+static INTFLOAT csa_table[8][4];
+
+static int16_t division_tab3[1<<6 ];
+static int16_t division_tab5[1<<8 ];
+static int16_t division_tab9[1<<11];
+
+static int16_t * const division_tabs[4] = {
+    division_tab3, division_tab5, NULL, division_tab9
+};
+
+/* lower 2 bits: modulo 3, higher bits: shift */
+static uint16_t scale_factor_modshift[64];
+/* [i][j]:  2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
+static int32_t scale_factor_mult[15][3];
+/* mult table for layer 2 group quantization */
+
+#define SCALE_GEN(v) \
+{ FIXR_OLD(1.0 * (v)), FIXR_OLD(0.7937005259 * (v)), FIXR_OLD(0.6299605249 * (v)) }
+
+static const int32_t scale_factor_mult2[3][3] = {
+    SCALE_GEN(4.0 / 3.0), /* 3 steps */
+    SCALE_GEN(4.0 / 5.0), /* 5 steps */
+    SCALE_GEN(4.0 / 9.0), /* 9 steps */
+};
+
+/**
+ * Convert region offsets to region sizes and truncate
+ * size to big_values.
+ */
+static void region_offset2size(GranuleDef *g)
+{
+    int i, k, j = 0;
+    g->region_size[2] = 576 / 2;
+    for (i = 0; i < 3; i++) {
+        k = FFMIN(g->region_size[i], g->big_values);
+        g->region_size[i] = k - j;
+        j = k;
+    }
+}
+
+static void init_short_region(MPADecodeContext *s, GranuleDef *g)
+{
+    if (g->block_type == 2) {
+        if (s->sample_rate_index != 8)
+            g->region_size[0] = (36 / 2);
+        else
+            g->region_size[0] = (72 / 2);
+    } else {
+        if (s->sample_rate_index <= 2)
+            g->region_size[0] = (36 / 2);
+        else if (s->sample_rate_index != 8)
+            g->region_size[0] = (54 / 2);
+        else
+            g->region_size[0] = (108 / 2);
+    }
+    g->region_size[1] = (576 / 2);
+}
+
+static void init_long_region(MPADecodeContext *s, GranuleDef *g,
+                             int ra1, int ra2)
+{
+    int l;
+    g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
+    /* should not overflow */
+    l = FFMIN(ra1 + ra2 + 2, 22);
+    g->region_size[1] = band_index_long[s->sample_rate_index][      l] >> 1;
+}
+
+static void compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
+{
+    if (g->block_type == 2) {
+        if (g->switch_point) {
+            /* if switched mode, we handle the 36 first samples as
+                long blocks.  For 8000Hz, we handle the 72 first
+                exponents as long blocks */
+            if (s->sample_rate_index <= 2)
+                g->long_end = 8;
+            else
+                g->long_end = 6;
+
+            g->short_start = 3;
+        } else {
+            g->long_end    = 0;
+            g->short_start = 0;
+        }
+    } else {
+        g->short_start = 13;
+        g->long_end    = 22;
+    }
+}
+
+/* layer 1 unscaling */
+/* n = number of bits of the mantissa minus 1 */
+static inline int l1_unscale(int n, int mant, int scale_factor)
+{
+    int shift, mod;
+    int64_t val;
+
+    shift   = scale_factor_modshift[scale_factor];
+    mod     = shift & 3;
+    shift >>= 2;
+    val     = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]);
+    shift  += n;
+    /* NOTE: at this point, 1 <= shift >= 21 + 15 */
+    return (int)((val + (1LL << (shift - 1))) >> shift);
+}
+
+static inline int l2_unscale_group(int steps, int mant, int scale_factor)
+{
+    int shift, mod, val;
+
+    shift   = scale_factor_modshift[scale_factor];
+    mod     = shift & 3;
+    shift >>= 2;
+
+    val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod];
+    /* NOTE: at this point, 0 <= shift <= 21 */
+    if (shift > 0)
+        val = (val + (1 << (shift - 1))) >> shift;
+    return val;
+}
+
+/* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */
+static inline int l3_unscale(int value, int exponent)
+{
+    unsigned int m;
+    int e;
+
+    e  = table_4_3_exp  [4 * value + (exponent & 3)];
+    m  = table_4_3_value[4 * value + (exponent & 3)];
+    e -= exponent >> 2;
+    assert(e >= 1);
+    if (e > 31)
+        return 0;
+    m = (m + (1 << (e - 1))) >> e;
+
+    return m;
+}
+
+static av_cold void decode_init_static(void)
+{
+    int i, j, k;
+    int offset;
+
+    /* scale factors table for layer 1/2 */
+    for (i = 0; i < 64; i++) {
+        int shift, mod;
+        /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */
+        shift = i / 3;
+        mod   = i % 3;
+        scale_factor_modshift[i] = mod | (shift << 2);
+    }
+
+    /* scale factor multiply for layer 1 */
+    for (i = 0; i < 15; i++) {
+        int n, norm;
+        n = i + 2;
+        norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
+        scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0          * 2.0), FRAC_BITS);
+        scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
+        scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
+        av_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm,
+                scale_factor_mult[i][0],
+                scale_factor_mult[i][1],
+                scale_factor_mult[i][2]);
+    }
+
+    RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
+
+    /* huffman decode tables */
+    offset = 0;
+    for (i = 1; i < 16; i++) {
+        const HuffTable *h = &mpa_huff_tables[i];
+        int xsize, x, y;
+        uint8_t  tmp_bits [512] = { 0 };
+        uint16_t tmp_codes[512] = { 0 };
+
+        xsize = h->xsize;
+
+        j = 0;
+        for (x = 0; x < xsize; x++) {
+            for (y = 0; y < xsize; y++) {
+                tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j  ];
+                tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
+            }
+        }
+
+        /* XXX: fail test */
+        huff_vlc[i].table = huff_vlc_tables+offset;
+        huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
+        init_vlc(&huff_vlc[i], 7, 512,
+                 tmp_bits, 1, 1, tmp_codes, 2, 2,
+                 INIT_VLC_USE_NEW_STATIC);
+        offset += huff_vlc_tables_sizes[i];
+    }
+    assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
+
+    offset = 0;
+    for (i = 0; i < 2; i++) {
+        huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
+        huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
+        init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
+                 mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
+                 INIT_VLC_USE_NEW_STATIC);
+        offset += huff_quad_vlc_tables_sizes[i];
+    }
+    assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
+
+    for (i = 0; i < 9; i++) {
+        k = 0;
+        for (j = 0; j < 22; j++) {
+            band_index_long[i][j] = k;
+            k += band_size_long[i][j];
+        }
+        band_index_long[i][22] = k;
+    }
+
+    /* compute n ^ (4/3) and store it in mantissa/exp format */
+
+    mpegaudio_tableinit();
+
+    for (i = 0; i < 4; i++) {
+        if (ff_mpa_quant_bits[i] < 0) {
+            for (j = 0; j < (1 << (-ff_mpa_quant_bits[i]+1)); j++) {
+                int val1, val2, val3, steps;
+                int val = j;
+                steps   = ff_mpa_quant_steps[i];
+                val1    = val % steps;
+                val    /= steps;
+                val2    = val % steps;
+                val3    = val / steps;
+                division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8);
+            }
+        }
+    }
+
+
+    for (i = 0; i < 7; i++) {
+        float f;
+        INTFLOAT v;
+        if (i != 6) {
+            f = tan((double)i * M_PI / 12.0);
+            v = FIXR(f / (1.0 + f));
+        } else {
+            v = FIXR(1.0);
+        }
+        is_table[0][    i] = v;
+        is_table[1][6 - i] = v;
+    }
+    /* invalid values */
+    for (i = 7; i < 16; i++)
+        is_table[0][i] = is_table[1][i] = 0.0;
+
+    for (i = 0; i < 16; i++) {
+        double f;
+        int e, k;
+
+        for (j = 0; j < 2; j++) {
+            e = -(j + 1) * ((i + 1) >> 1);
+            f = pow(2.0, e / 4.0);
+            k = i & 1;
+            is_table_lsf[j][k ^ 1][i] = FIXR(f);
+            is_table_lsf[j][k    ][i] = FIXR(1.0);
+            av_dlog(NULL, "is_table_lsf %d %d: %f %f\n",
+                    i, j, (float) is_table_lsf[j][0][i],
+                    (float) is_table_lsf[j][1][i]);
+        }
+    }
+
+    for (i = 0; i < 8; i++) {
+        float ci, cs, ca;
+        ci = ci_table[i];
+        cs = 1.0 / sqrt(1.0 + ci * ci);
+        ca = cs * ci;
+#if !CONFIG_FLOAT
+        csa_table[i][0] = FIXHR(cs/4);
+        csa_table[i][1] = FIXHR(ca/4);
+        csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4);
+        csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4);
+#else
+        csa_table[i][0] = cs;
+        csa_table[i][1] = ca;
+        csa_table[i][2] = ca + cs;
+        csa_table[i][3] = ca - cs;
+#endif
+    }
+}
+
+static av_cold int decode_init(AVCodecContext * avctx)
+{
+    static int initialized_tables = 0;
+    MPADecodeContext *s = avctx->priv_data;
+
+    if (!initialized_tables) {
+        decode_init_static();
+        initialized_tables = 1;
+    }
+
+    s->avctx = avctx;
+
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+    ff_mpadsp_init(&s->mpadsp);
+
+    if (avctx->request_sample_fmt == OUT_FMT &&
+        avctx->codec_id != AV_CODEC_ID_MP3ON4)
+        avctx->sample_fmt = OUT_FMT;
+    else
+        avctx->sample_fmt = OUT_FMT_P;
+    s->err_recognition = avctx->err_recognition;
+
+    if (avctx->codec_id == AV_CODEC_ID_MP3ADU)
+        s->adu_mode = 1;
+
+    return 0;
+}
+
+#define C3 FIXHR(0.86602540378443864676/2)
+#define C4 FIXHR(0.70710678118654752439/2) //0.5 / cos(pi*(9)/36)
+#define C5 FIXHR(0.51763809020504152469/2) //0.5 / cos(pi*(5)/36)
+#define C6 FIXHR(1.93185165257813657349/4) //0.5 / cos(pi*(15)/36)
+
+/* 12 points IMDCT. We compute it "by hand" by factorizing obvious
+   cases. */
+static void imdct12(INTFLOAT *out, INTFLOAT *in)
+{
+    INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2;
+
+    in0  = in[0*3];
+    in1  = in[1*3] + in[0*3];
+    in2  = in[2*3] + in[1*3];
+    in3  = in[3*3] + in[2*3];
+    in4  = in[4*3] + in[3*3];
+    in5  = in[5*3] + in[4*3];
+    in5 += in3;
+    in3 += in1;
+
+    in2  = MULH3(in2, C3, 2);
+    in3  = MULH3(in3, C3, 4);
+
+    t1   = in0 - in4;
+    t2   = MULH3(in1 - in5, C4, 2);
+
+    out[ 7] =
+    out[10] = t1 + t2;
+    out[ 1] =
+    out[ 4] = t1 - t2;
+
+    in0    += SHR(in4, 1);
+    in4     = in0 + in2;
+    in5    += 2*in1;
+    in1     = MULH3(in5 + in3, C5, 1);
+    out[ 8] =
+    out[ 9] = in4 + in1;
+    out[ 2] =
+    out[ 3] = in4 - in1;
+
+    in0    -= in2;
+    in5     = MULH3(in5 - in3, C6, 2);
+    out[ 0] =
+    out[ 5] = in0 - in5;
+    out[ 6] =
+    out[11] = in0 + in5;
+}
+
+/* return the number of decoded frames */
+static int mp_decode_layer1(MPADecodeContext *s)
+{
+    int bound, i, v, n, ch, j, mant;
+    uint8_t allocation[MPA_MAX_CHANNELS][SBLIMIT];
+    uint8_t scale_factors[MPA_MAX_CHANNELS][SBLIMIT];
+
+    if (s->mode == MPA_JSTEREO)
+        bound = (s->mode_ext + 1) * 4;
+    else
+        bound = SBLIMIT;
+
+    /* allocation bits */
+    for (i = 0; i < bound; i++) {
+        for (ch = 0; ch < s->nb_channels; ch++) {
+            allocation[ch][i] = get_bits(&s->gb, 4);
+        }
+    }
+    for (i = bound; i < SBLIMIT; i++)
+        allocation[0][i] = get_bits(&s->gb, 4);
+
+    /* scale factors */
+    for (i = 0; i < bound; i++) {
+        for (ch = 0; ch < s->nb_channels; ch++) {
+            if (allocation[ch][i])
+                scale_factors[ch][i] = get_bits(&s->gb, 6);
+        }
+    }
+    for (i = bound; i < SBLIMIT; i++) {
+        if (allocation[0][i]) {
+            scale_factors[0][i] = get_bits(&s->gb, 6);
+            scale_factors[1][i] = get_bits(&s->gb, 6);
+        }
+    }
+
+    /* compute samples */
+    for (j = 0; j < 12; j++) {
+        for (i = 0; i < bound; i++) {
+            for (ch = 0; ch < s->nb_channels; ch++) {
+                n = allocation[ch][i];
+                if (n) {
+                    mant = get_bits(&s->gb, n + 1);
+                    v = l1_unscale(n, mant, scale_factors[ch][i]);
+                } else {
+                    v = 0;
+                }
+                s->sb_samples[ch][j][i] = v;
+            }
+        }
+        for (i = bound; i < SBLIMIT; i++) {
+            n = allocation[0][i];
+            if (n) {
+                mant = get_bits(&s->gb, n + 1);
+                v = l1_unscale(n, mant, scale_factors[0][i]);
+                s->sb_samples[0][j][i] = v;
+                v = l1_unscale(n, mant, scale_factors[1][i]);
+                s->sb_samples[1][j][i] = v;
+            } else {
+                s->sb_samples[0][j][i] = 0;
+                s->sb_samples[1][j][i] = 0;
+            }
+        }
+    }
+    return 12;
+}
+
+static int mp_decode_layer2(MPADecodeContext *s)
+{
+    int sblimit; /* number of used subbands */
+    const unsigned char *alloc_table;
+    int table, bit_alloc_bits, i, j, ch, bound, v;
+    unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
+    unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
+    unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3], *sf;
+    int scale, qindex, bits, steps, k, l, m, b;
+
+    /* select decoding table */
+    table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels,
+                                   s->sample_rate, s->lsf);
+    sblimit     = ff_mpa_sblimit_table[table];
+    alloc_table = ff_mpa_alloc_tables[table];
+
+    if (s->mode == MPA_JSTEREO)
+        bound = (s->mode_ext + 1) * 4;
+    else
+        bound = sblimit;
+
+    av_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit);
+
+    /* sanity check */
+    if (bound > sblimit)
+        bound = sblimit;
+
+    /* parse bit allocation */
+    j = 0;
+    for (i = 0; i < bound; i++) {
+        bit_alloc_bits = alloc_table[j];
+        for (ch = 0; ch < s->nb_channels; ch++)
+            bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits);
+        j += 1 << bit_alloc_bits;
+    }
+    for (i = bound; i < sblimit; i++) {
+        bit_alloc_bits = alloc_table[j];
+        v = get_bits(&s->gb, bit_alloc_bits);
+        bit_alloc[0][i] = v;
+        bit_alloc[1][i] = v;
+        j += 1 << bit_alloc_bits;
+    }
+
+    /* scale codes */
+    for (i = 0; i < sblimit; i++) {
+        for (ch = 0; ch < s->nb_channels; ch++) {
+            if (bit_alloc[ch][i])
+                scale_code[ch][i] = get_bits(&s->gb, 2);
+        }
+    }
+
+    /* scale factors */
+    for (i = 0; i < sblimit; i++) {
+        for (ch = 0; ch < s->nb_channels; ch++) {
+            if (bit_alloc[ch][i]) {
+                sf = scale_factors[ch][i];
+                switch (scale_code[ch][i]) {
+                default:
+                case 0:
+                    sf[0] = get_bits(&s->gb, 6);
+                    sf[1] = get_bits(&s->gb, 6);
+                    sf[2] = get_bits(&s->gb, 6);
+                    break;
+                case 2:
+                    sf[0] = get_bits(&s->gb, 6);
+                    sf[1] = sf[0];
+                    sf[2] = sf[0];
+                    break;
+                case 1:
+                    sf[0] = get_bits(&s->gb, 6);
+                    sf[2] = get_bits(&s->gb, 6);
+                    sf[1] = sf[0];
+                    break;
+                case 3:
+                    sf[0] = get_bits(&s->gb, 6);
+                    sf[2] = get_bits(&s->gb, 6);
+                    sf[1] = sf[2];
+                    break;
+                }
+            }
+        }
+    }
+
+    /* samples */
+    for (k = 0; k < 3; k++) {
+        for (l = 0; l < 12; l += 3) {
+            j = 0;
+            for (i = 0; i < bound; i++) {
+                bit_alloc_bits = alloc_table[j];
+                for (ch = 0; ch < s->nb_channels; ch++) {
+                    b = bit_alloc[ch][i];
+                    if (b) {
+                        scale = scale_factors[ch][i][k];
+                        qindex = alloc_table[j+b];
+                        bits = ff_mpa_quant_bits[qindex];
+                        if (bits < 0) {
+                            int v2;
+                            /* 3 values at the same time */
+                            v = get_bits(&s->gb, -bits);
+                            v2 = division_tabs[qindex][v];
+                            steps  = ff_mpa_quant_steps[qindex];
+
+                            s->sb_samples[ch][k * 12 + l + 0][i] =
+                                l2_unscale_group(steps,  v2       & 15, scale);
+                            s->sb_samples[ch][k * 12 + l + 1][i] =
+                                l2_unscale_group(steps, (v2 >> 4) & 15, scale);
+                            s->sb_samples[ch][k * 12 + l + 2][i] =
+                                l2_unscale_group(steps,  v2 >> 8      , scale);
+                        } else {
+                            for (m = 0; m < 3; m++) {
+                                v = get_bits(&s->gb, bits);
+                                v = l1_unscale(bits - 1, v, scale);
+                                s->sb_samples[ch][k * 12 + l + m][i] = v;
+                            }
+                        }
+                    } else {
+                        s->sb_samples[ch][k * 12 + l + 0][i] = 0;
+                        s->sb_samples[ch][k * 12 + l + 1][i] = 0;
+                        s->sb_samples[ch][k * 12 + l + 2][i] = 0;
+                    }
+                }
+                /* next subband in alloc table */
+                j += 1 << bit_alloc_bits;
+            }
+            /* XXX: find a way to avoid this duplication of code */
+            for (i = bound; i < sblimit; i++) {
+                bit_alloc_bits = alloc_table[j];
+                b = bit_alloc[0][i];
+                if (b) {
+                    int mant, scale0, scale1;
+                    scale0 = scale_factors[0][i][k];
+                    scale1 = scale_factors[1][i][k];
+                    qindex = alloc_table[j+b];
+                    bits = ff_mpa_quant_bits[qindex];
+                    if (bits < 0) {
+                        /* 3 values at the same time */
+                        v = get_bits(&s->gb, -bits);
+                        steps = ff_mpa_quant_steps[qindex];
+                        mant = v % steps;
+                        v = v / steps;
+                        s->sb_samples[0][k * 12 + l + 0][i] =
+                            l2_unscale_group(steps, mant, scale0);
+                        s->sb_samples[1][k * 12 + l + 0][i] =
+                            l2_unscale_group(steps, mant, scale1);
+                        mant = v % steps;
+                        v = v / steps;
+                        s->sb_samples[0][k * 12 + l + 1][i] =
+                            l2_unscale_group(steps, mant, scale0);
+                        s->sb_samples[1][k * 12 + l + 1][i] =
+                            l2_unscale_group(steps, mant, scale1);
+                        s->sb_samples[0][k * 12 + l + 2][i] =
+                            l2_unscale_group(steps, v, scale0);
+                        s->sb_samples[1][k * 12 + l + 2][i] =
+                            l2_unscale_group(steps, v, scale1);
+                    } else {
+                        for (m = 0; m < 3; m++) {
+                            mant = get_bits(&s->gb, bits);
+                            s->sb_samples[0][k * 12 + l + m][i] =
+                                l1_unscale(bits - 1, mant, scale0);
+                            s->sb_samples[1][k * 12 + l + m][i] =
+                                l1_unscale(bits - 1, mant, scale1);
+                        }
+                    }
+                } else {
+                    s->sb_samples[0][k * 12 + l + 0][i] = 0;
+                    s->sb_samples[0][k * 12 + l + 1][i] = 0;
+                    s->sb_samples[0][k * 12 + l + 2][i] = 0;
+                    s->sb_samples[1][k * 12 + l + 0][i] = 0;
+                    s->sb_samples[1][k * 12 + l + 1][i] = 0;
+                    s->sb_samples[1][k * 12 + l + 2][i] = 0;
+                }
+                /* next subband in alloc table */
+                j += 1 << bit_alloc_bits;
+            }
+            /* fill remaining samples to zero */
+            for (i = sblimit; i < SBLIMIT; i++) {
+                for (ch = 0; ch < s->nb_channels; ch++) {
+                    s->sb_samples[ch][k * 12 + l + 0][i] = 0;
+                    s->sb_samples[ch][k * 12 + l + 1][i] = 0;
+                    s->sb_samples[ch][k * 12 + l + 2][i] = 0;
+                }
+            }
+        }
+    }
+    return 3 * 12;
+}
+
+#define SPLIT(dst,sf,n)             \
+    if (n == 3) {                   \
+        int m = (sf * 171) >> 9;    \
+        dst   = sf - 3 * m;         \
+        sf    = m;                  \
+    } else if (n == 4) {            \
+        dst  = sf & 3;              \
+        sf >>= 2;                   \
+    } else if (n == 5) {            \
+        int m = (sf * 205) >> 10;   \
+        dst   = sf - 5 * m;         \
+        sf    = m;                  \
+    } else if (n == 6) {            \
+        int m = (sf * 171) >> 10;   \
+        dst   = sf - 6 * m;         \
+        sf    = m;                  \
+    } else {                        \
+        dst = 0;                    \
+    }
+
+static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2,
+                                           int n3)
+{
+    SPLIT(slen[3], sf, n3)
+    SPLIT(slen[2], sf, n2)
+    SPLIT(slen[1], sf, n1)
+    slen[0] = sf;
+}
+
+static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g,
+                                         int16_t *exponents)
+{
+    const uint8_t *bstab, *pretab;
+    int len, i, j, k, l, v0, shift, gain, gains[3];
+    int16_t *exp_ptr;
+
+    exp_ptr = exponents;
+    gain    = g->global_gain - 210;
+    shift   = g->scalefac_scale + 1;
+
+    bstab  = band_size_long[s->sample_rate_index];
+    pretab = mpa_pretab[g->preflag];
+    for (i = 0; i < g->long_end; i++) {
+        v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400;
+        len = bstab[i];
+        for (j = len; j > 0; j--)
+            *exp_ptr++ = v0;
+    }
+
+    if (g->short_start < 13) {
+        bstab    = band_size_short[s->sample_rate_index];
+        gains[0] = gain - (g->subblock_gain[0] << 3);
+        gains[1] = gain - (g->subblock_gain[1] << 3);
+        gains[2] = gain - (g->subblock_gain[2] << 3);
+        k        = g->long_end;
+        for (i = g->short_start; i < 13; i++) {
+            len = bstab[i];
+            for (l = 0; l < 3; l++) {
+                v0 = gains[l] - (g->scale_factors[k++] << shift) + 400;
+                for (j = len; j > 0; j--)
+                    *exp_ptr++ = v0;
+            }
+        }
+    }
+}
+
+/* handle n = 0 too */
+static inline int get_bitsz(GetBitContext *s, int n)
+{
+    return n ? get_bits(s, n) : 0;
+}
+
+
+static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos,
+                          int *end_pos2)
+{
+    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);
+        skip_bits_long(&s->gb, *pos - *end_pos);
+        *end_pos2 =
+        *end_pos  = *end_pos2 + get_bits_count(&s->gb) - *pos;
+        *pos      = get_bits_count(&s->gb);
+    }
+}
+
+/* Following is a optimized code for
+            INTFLOAT v = *src
+            if(get_bits1(&s->gb))
+                v = -v;
+            *dst = v;
+*/
+#if CONFIG_FLOAT
+#define READ_FLIP_SIGN(dst,src)                     \
+    v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31);  \
+    AV_WN32A(dst, v);
+#else
+#define READ_FLIP_SIGN(dst,src)     \
+    v      = -get_bits1(&s->gb);    \
+    *(dst) = (*(src) ^ v) - v;
+#endif
+
+static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
+                          int16_t *exponents, int end_pos2)
+{
+    int s_index;
+    int i;
+    int last_pos, bits_left;
+    VLC *vlc;
+    int end_pos = FFMIN(end_pos2, s->gb.size_in_bits);
+
+    /* low frequencies (called big values) */
+    s_index = 0;
+    for (i = 0; i < 3; i++) {
+        int j, k, l, linbits;
+        j = g->region_size[i];
+        if (j == 0)
+            continue;
+        /* select vlc table */
+        k       = g->table_select[i];
+        l       = mpa_huff_data[k][0];
+        linbits = mpa_huff_data[k][1];
+        vlc     = &huff_vlc[l];
+
+        if (!l) {
+            memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j);
+            s_index += 2 * j;
+            continue;
+        }
+
+        /* read huffcode and compute each couple */
+        for (; j > 0; j--) {
+            int exponent, x, y;
+            int v;
+            int pos = get_bits_count(&s->gb);
+
+            if (pos >= end_pos){
+                switch_buffer(s, &pos, &end_pos, &end_pos2);
+                if (pos >= end_pos)
+                    break;
+            }
+            y = get_vlc2(&s->gb, vlc->table, 7, 3);
+
+            if (!y) {
+                g->sb_hybrid[s_index  ] =
+                g->sb_hybrid[s_index+1] = 0;
+                s_index += 2;
+                continue;
+            }
+
+            exponent= exponents[s_index];
+
+            av_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n",
+                    i, g->region_size[i] - j, x, y, exponent);
+            if (y & 16) {
+                x = y >> 5;
+                y = y & 0x0f;
+                if (x < 15) {
+                    READ_FLIP_SIGN(g->sb_hybrid + s_index, RENAME(expval_table)[exponent] + x)
+                } else {
+                    x += get_bitsz(&s->gb, linbits);
+                    v  = l3_unscale(x, exponent);
+                    if (get_bits1(&s->gb))
+                        v = -v;
+                    g->sb_hybrid[s_index] = v;
+                }
+                if (y < 15) {
+                    READ_FLIP_SIGN(g->sb_hybrid + s_index + 1, RENAME(expval_table)[exponent] + y)
+                } else {
+                    y += get_bitsz(&s->gb, linbits);
+                    v  = l3_unscale(y, exponent);
+                    if (get_bits1(&s->gb))
+                        v = -v;
+                    g->sb_hybrid[s_index+1] = v;
+                }
+            } else {
+                x = y >> 5;
+                y = y & 0x0f;
+                x += y;
+                if (x < 15) {
+                    READ_FLIP_SIGN(g->sb_hybrid + s_index + !!y, RENAME(expval_table)[exponent] + x)
+                } else {
+                    x += get_bitsz(&s->gb, linbits);
+                    v  = l3_unscale(x, exponent);
+                    if (get_bits1(&s->gb))
+                        v = -v;
+                    g->sb_hybrid[s_index+!!y] = v;
+                }
+                g->sb_hybrid[s_index + !y] = 0;
+            }
+            s_index += 2;
+        }
+    }
+
+    /* high frequencies */
+    vlc = &huff_quad_vlc[g->count1table_select];
+    last_pos = 0;
+    while (s_index <= 572) {
+        int pos, code;
+        pos = get_bits_count(&s->gb);
+        if (pos >= end_pos) {
+            if (pos > end_pos2 && last_pos) {
+                /* some encoders generate an incorrect size for this
+                   part. We must go back into the data */
+                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)
+                    s_index=0;
+                break;
+            }
+            switch_buffer(s, &pos, &end_pos, &end_pos2);
+            if (pos >= end_pos)
+                break;
+        }
+        last_pos = pos;
+
+        code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1);
+        av_dlog(s->avctx, "t=%d code=%d\n", g->count1table_select, code);
+        g->sb_hybrid[s_index+0] =
+        g->sb_hybrid[s_index+1] =
+        g->sb_hybrid[s_index+2] =
+        g->sb_hybrid[s_index+3] = 0;
+        while (code) {
+            static const int idxtab[16] = { 3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 };
+            int v;
+            int pos = s_index + idxtab[code];
+            code   ^= 8 >> idxtab[code];
+            READ_FLIP_SIGN(g->sb_hybrid + pos, RENAME(exp_table)+exponents[pos])
+        }
+        s_index += 4;
+    }
+    /* skip extension bits */
+    bits_left = end_pos2 - get_bits_count(&s->gb);
+    if (bits_left < 0 && (s->err_recognition & AV_EF_BUFFER)) {
+        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)) {
+        av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
+        s_index = 0;
+    }
+    memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * (576 - s_index));
+    skip_bits_long(&s->gb, bits_left);
+
+    i = get_bits_count(&s->gb);
+    switch_buffer(s, &i, &end_pos, &end_pos2);
+
+    return 0;
+}
+
+/* Reorder short blocks from bitstream order to interleaved order. It
+   would be faster to do it in parsing, but the code would be far more
+   complicated */
+static void reorder_block(MPADecodeContext *s, GranuleDef *g)
+{
+    int i, j, len;
+    INTFLOAT *ptr, *dst, *ptr1;
+    INTFLOAT tmp[576];
+
+    if (g->block_type != 2)
+        return;
+
+    if (g->switch_point) {
+        if (s->sample_rate_index != 8)
+            ptr = g->sb_hybrid + 36;
+        else
+            ptr = g->sb_hybrid + 72;
+    } else {
+        ptr = g->sb_hybrid;
+    }
+
+    for (i = g->short_start; i < 13; i++) {
+        len  = band_size_short[s->sample_rate_index][i];
+        ptr1 = ptr;
+        dst  = tmp;
+        for (j = len; j > 0; j--) {
+            *dst++ = ptr[0*len];
+            *dst++ = ptr[1*len];
+            *dst++ = ptr[2*len];
+            ptr++;
+        }
+        ptr += 2 * len;
+        memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1));
+    }
+}
+
+#define ISQRT2 FIXR(0.70710678118654752440)
+
+static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1)
+{
+    int i, j, k, l;
+    int sf_max, sf, len, non_zero_found;
+    INTFLOAT (*is_tab)[16], *tab0, *tab1, tmp0, tmp1, v1, v2;
+    int non_zero_found_short[3];
+
+    /* intensity stereo */
+    if (s->mode_ext & MODE_EXT_I_STEREO) {
+        if (!s->lsf) {
+            is_tab = is_table;
+            sf_max = 7;
+        } else {
+            is_tab = is_table_lsf[g1->scalefac_compress & 1];
+            sf_max = 16;
+        }
+
+        tab0 = g0->sb_hybrid + 576;
+        tab1 = g1->sb_hybrid + 576;
+
+        non_zero_found_short[0] = 0;
+        non_zero_found_short[1] = 0;
+        non_zero_found_short[2] = 0;
+        k = (13 - g1->short_start) * 3 + g1->long_end - 3;
+        for (i = 12; i >= g1->short_start; i--) {
+            /* for last band, use previous scale factor */
+            if (i != 11)
+                k -= 3;
+            len = band_size_short[s->sample_rate_index][i];
+            for (l = 2; l >= 0; l--) {
+                tab0 -= len;
+                tab1 -= len;
+                if (!non_zero_found_short[l]) {
+                    /* test if non zero band. if so, stop doing i-stereo */
+                    for (j = 0; j < len; j++) {
+                        if (tab1[j] != 0) {
+                            non_zero_found_short[l] = 1;
+                            goto found1;
+                        }
+                    }
+                    sf = g1->scale_factors[k + l];
+                    if (sf >= sf_max)
+                        goto found1;
+
+                    v1 = is_tab[0][sf];
+                    v2 = is_tab[1][sf];
+                    for (j = 0; j < len; j++) {
+                        tmp0    = tab0[j];
+                        tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
+                        tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
+                    }
+                } else {
+found1:
+                    if (s->mode_ext & MODE_EXT_MS_STEREO) {
+                        /* lower part of the spectrum : do ms stereo
+                           if enabled */
+                        for (j = 0; j < len; j++) {
+                            tmp0    = tab0[j];
+                            tmp1    = tab1[j];
+                            tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
+                            tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
+                        }
+                    }
+                }
+            }
+        }
+
+        non_zero_found = non_zero_found_short[0] |
+                         non_zero_found_short[1] |
+                         non_zero_found_short[2];
+
+        for (i = g1->long_end - 1;i >= 0;i--) {
+            len   = band_size_long[s->sample_rate_index][i];
+            tab0 -= len;
+            tab1 -= len;
+            /* test if non zero band. if so, stop doing i-stereo */
+            if (!non_zero_found) {
+                for (j = 0; j < len; j++) {
+                    if (tab1[j] != 0) {
+                        non_zero_found = 1;
+                        goto found2;
+                    }
+                }
+                /* for last band, use previous scale factor */
+                k  = (i == 21) ? 20 : i;
+                sf = g1->scale_factors[k];
+                if (sf >= sf_max)
+                    goto found2;
+                v1 = is_tab[0][sf];
+                v2 = is_tab[1][sf];
+                for (j = 0; j < len; j++) {
+                    tmp0    = tab0[j];
+                    tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
+                    tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
+                }
+            } else {
+found2:
+                if (s->mode_ext & MODE_EXT_MS_STEREO) {
+                    /* lower part of the spectrum : do ms stereo
+                       if enabled */
+                    for (j = 0; j < len; j++) {
+                        tmp0    = tab0[j];
+                        tmp1    = tab1[j];
+                        tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
+                        tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
+                    }
+                }
+            }
+        }
+    } else if (s->mode_ext & MODE_EXT_MS_STEREO) {
+        /* ms stereo ONLY */
+        /* NOTE: the 1/sqrt(2) normalization factor is included in the
+           global gain */
+#if CONFIG_FLOAT
+       s->fdsp.butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
+#else
+        tab0 = g0->sb_hybrid;
+        tab1 = g1->sb_hybrid;
+        for (i = 0; i < 576; i++) {
+            tmp0    = tab0[i];
+            tmp1    = tab1[i];
+            tab0[i] = tmp0 + tmp1;
+            tab1[i] = tmp0 - tmp1;
+        }
+#endif
+    }
+}
+
+#if CONFIG_FLOAT
+#define AA(j) do {                                                      \
+        float tmp0 = ptr[-1-j];                                         \
+        float tmp1 = ptr[   j];                                         \
+        ptr[-1-j] = tmp0 * csa_table[j][0] - tmp1 * csa_table[j][1];    \
+        ptr[   j] = tmp0 * csa_table[j][1] + tmp1 * csa_table[j][0];    \
+    } while (0)
+#else
+#define AA(j) do {                                              \
+        int tmp0 = ptr[-1-j];                                   \
+        int tmp1 = ptr[   j];                                   \
+        int tmp2 = MULH(tmp0 + tmp1, csa_table[j][0]);          \
+        ptr[-1-j] = 4 * (tmp2 - MULH(tmp1, csa_table[j][2]));   \
+        ptr[   j] = 4 * (tmp2 + MULH(tmp0, csa_table[j][3]));   \
+    } while (0)
+#endif
+
+static void compute_antialias(MPADecodeContext *s, GranuleDef *g)
+{
+    INTFLOAT *ptr;
+    int n, i;
+
+    /* 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--) {
+        AA(0);
+        AA(1);
+        AA(2);
+        AA(3);
+        AA(4);
+        AA(5);
+        AA(6);
+        AA(7);
+
+        ptr += 18;
+    }
+}
+
+static void compute_imdct(MPADecodeContext *s, GranuleDef *g,
+                          INTFLOAT *sb_samples, INTFLOAT *mdct_buf)
+{
+    INTFLOAT *win, *out_ptr, *ptr, *buf, *ptr1;
+    INTFLOAT out2[12];
+    int i, j, mdct_long_end, sblimit;
+
+    /* find last non zero block */
+    ptr  = g->sb_hybrid + 576;
+    ptr1 = g->sb_hybrid + 2 * 18;
+    while (ptr >= ptr1) {
+        int32_t *p;
+        ptr -= 6;
+        p    = (int32_t*)ptr;
+        if (p[0] | p[1] | p[2] | p[3] | p[4] | p[5])
+            break;
+    }
+    sblimit = ((ptr - g->sb_hybrid) / 18) + 1;
+
+    if (g->block_type == 2) {
+        /* XXX: check for 8000 Hz */
+        if (g->switch_point)
+            mdct_long_end = 2;
+        else
+            mdct_long_end = 0;
+    } else {
+        mdct_long_end = sblimit;
+    }
+
+    s->mpadsp.RENAME(imdct36_blocks)(sb_samples, mdct_buf, g->sb_hybrid,
+                                     mdct_long_end, g->switch_point,
+                                     g->block_type);
+
+    buf = mdct_buf + 4*18*(mdct_long_end >> 2) + (mdct_long_end & 3);
+    ptr = g->sb_hybrid + 18 * mdct_long_end;
+
+    for (j = mdct_long_end; j < sblimit; j++) {
+        /* select frequency inversion */
+        win     = RENAME(ff_mdct_win)[2 + (4  & -(j & 1))];
+        out_ptr = sb_samples + j;
+
+        for (i = 0; i < 6; i++) {
+            *out_ptr = buf[4*i];
+            out_ptr += SBLIMIT;
+        }
+        imdct12(out2, ptr + 0);
+        for (i = 0; i < 6; i++) {
+            *out_ptr     = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*1)];
+            buf[4*(i + 6*2)] = MULH3(out2[i + 6], win[i + 6], 1);
+            out_ptr += SBLIMIT;
+        }
+        imdct12(out2, ptr + 1);
+        for (i = 0; i < 6; i++) {
+            *out_ptr     = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*2)];
+            buf[4*(i + 6*0)] = MULH3(out2[i + 6], win[i + 6], 1);
+            out_ptr += SBLIMIT;
+        }
+        imdct12(out2, ptr + 2);
+        for (i = 0; i < 6; i++) {
+            buf[4*(i + 6*0)] = MULH3(out2[i    ], win[i    ], 1) + buf[4*(i + 6*0)];
+            buf[4*(i + 6*1)] = MULH3(out2[i + 6], win[i + 6], 1);
+            buf[4*(i + 6*2)] = 0;
+        }
+        ptr += 18;
+        buf += (j&3) != 3 ? 1 : (4*18-3);
+    }
+    /* zero bands */
+    for (j = sblimit; j < SBLIMIT; j++) {
+        /* overlap */
+        out_ptr = sb_samples + j;
+        for (i = 0; i < 18; i++) {
+            *out_ptr = buf[4*i];
+            buf[4*i]   = 0;
+            out_ptr += SBLIMIT;
+        }
+        buf += (j&3) != 3 ? 1 : (4*18-3);
+    }
+}
+
+/* main layer3 decoding function */
+static int mp_decode_layer3(MPADecodeContext *s)
+{
+    int nb_granules, main_data_begin;
+    int gr, ch, blocksplit_flag, i, j, k, n, bits_pos;
+    GranuleDef *g;
+    int16_t exponents[576]; //FIXME try INTFLOAT
+
+    /* read side info */
+    if (s->lsf) {
+        main_data_begin = get_bits(&s->gb, 8);
+        skip_bits(&s->gb, s->nb_channels);
+        nb_granules = 1;
+    } else {
+        main_data_begin = get_bits(&s->gb, 9);
+        if (s->nb_channels == 2)
+            skip_bits(&s->gb, 3);
+        else
+            skip_bits(&s->gb, 5);
+        nb_granules = 2;
+        for (ch = 0; ch < s->nb_channels; ch++) {
+            s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */
+            s->granules[ch][1].scfsi = get_bits(&s->gb, 4);
+        }
+    }
+
+    for (gr = 0; gr < nb_granules; gr++) {
+        for (ch = 0; ch < s->nb_channels; ch++) {
+            av_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);
+            g = &s->granules[ch][gr];
+            g->part2_3_length = get_bits(&s->gb, 12);
+            g->big_values     = get_bits(&s->gb,  9);
+            if (g->big_values > 288) {
+                av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            g->global_gain = get_bits(&s->gb, 8);
+            /* if MS stereo only is selected, we precompute the
+               1/sqrt(2) renormalization factor */
+            if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) ==
+                MODE_EXT_MS_STEREO)
+                g->global_gain -= 2;
+            if (s->lsf)
+                g->scalefac_compress = get_bits(&s->gb, 9);
+            else
+                g->scalefac_compress = get_bits(&s->gb, 4);
+            blocksplit_flag = get_bits1(&s->gb);
+            if (blocksplit_flag) {
+                g->block_type = get_bits(&s->gb, 2);
+                if (g->block_type == 0) {
+                    av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n");
+                    return AVERROR_INVALIDDATA;
+                }
+                g->switch_point = get_bits1(&s->gb);
+                for (i = 0; i < 2; i++)
+                    g->table_select[i] = get_bits(&s->gb, 5);
+                for (i = 0; i < 3; i++)
+                    g->subblock_gain[i] = get_bits(&s->gb, 3);
+                init_short_region(s, g);
+            } else {
+                int region_address1, region_address2;
+                g->block_type = 0;
+                g->switch_point = 0;
+                for (i = 0; i < 3; i++)
+                    g->table_select[i] = get_bits(&s->gb, 5);
+                /* compute huffman coded region sizes */
+                region_address1 = get_bits(&s->gb, 4);
+                region_address2 = get_bits(&s->gb, 3);
+                av_dlog(s->avctx, "region1=%d region2=%d\n",
+                        region_address1, region_address2);
+                init_long_region(s, g, region_address1, region_address2);
+            }
+            region_offset2size(g);
+            compute_band_indexes(s, g);
+
+            g->preflag = 0;
+            if (!s->lsf)
+                g->preflag = get_bits1(&s->gb);
+            g->scalefac_scale     = get_bits1(&s->gb);
+            g->count1table_select = get_bits1(&s->gb);
+            av_dlog(s->avctx, "block_type=%d switch_point=%d\n",
+                    g->block_type, g->switch_point);
+        }
+    }
+
+    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);
+        /* 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);
+
+        memcpy(s->last_buf + s->last_buf_size, ptr, extrasize);
+        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;
+#endif
+        s->last_buf_size <<= 3;
+        for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) {
+            for (ch = 0; ch < s->nb_channels; ch++) {
+                g = &s->granules[ch][gr];
+                s->last_buf_size += g->part2_3_length;
+                memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
+                compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
+            }
+        }
+        skip = s->last_buf_size - 8 * main_data_begin;
+        if (skip >= s->gb.size_in_bits && s->in_gb.buffer) {
+            skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits);
+            s->gb           = s->in_gb;
+            s->in_gb.buffer = NULL;
+        } else {
+            skip_bits_long(&s->gb, skip);
+        }
+    } else {
+        gr = 0;
+    }
+
+    for (; gr < nb_granules; gr++) {
+        for (ch = 0; ch < s->nb_channels; ch++) {
+            g = &s->granules[ch][gr];
+            bits_pos = get_bits_count(&s->gb);
+
+            if (!s->lsf) {
+                uint8_t *sc;
+                int slen, slen1, slen2;
+
+                /* MPEG1 scale factors */
+                slen1 = slen_table[0][g->scalefac_compress];
+                slen2 = slen_table[1][g->scalefac_compress];
+                av_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2);
+                if (g->block_type == 2) {
+                    n = g->switch_point ? 17 : 18;
+                    j = 0;
+                    if (slen1) {
+                        for (i = 0; i < n; i++)
+                            g->scale_factors[j++] = get_bits(&s->gb, slen1);
+                    } else {
+                        for (i = 0; i < n; i++)
+                            g->scale_factors[j++] = 0;
+                    }
+                    if (slen2) {
+                        for (i = 0; i < 18; i++)
+                            g->scale_factors[j++] = get_bits(&s->gb, slen2);
+                        for (i = 0; i < 3; i++)
+                            g->scale_factors[j++] = 0;
+                    } else {
+                        for (i = 0; i < 21; i++)
+                            g->scale_factors[j++] = 0;
+                    }
+                } else {
+                    sc = s->granules[ch][0].scale_factors;
+                    j = 0;
+                    for (k = 0; k < 4; k++) {
+                        n = k == 0 ? 6 : 5;
+                        if ((g->scfsi & (0x8 >> k)) == 0) {
+                            slen = (k < 2) ? slen1 : slen2;
+                            if (slen) {
+                                for (i = 0; i < n; i++)
+                                    g->scale_factors[j++] = get_bits(&s->gb, slen);
+                            } else {
+                                for (i = 0; i < n; i++)
+                                    g->scale_factors[j++] = 0;
+                            }
+                        } else {
+                            /* simply copy from last granule */
+                            for (i = 0; i < n; i++) {
+                                g->scale_factors[j] = sc[j];
+                                j++;
+                            }
+                        }
+                    }
+                    g->scale_factors[j++] = 0;
+                }
+            } else {
+                int tindex, tindex2, slen[4], sl, sf;
+
+                /* LSF scale factors */
+                if (g->block_type == 2)
+                    tindex = g->switch_point ? 2 : 1;
+                else
+                    tindex = 0;
+
+                sf = g->scalefac_compress;
+                if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) {
+                    /* intensity stereo case */
+                    sf >>= 1;
+                    if (sf < 180) {
+                        lsf_sf_expand(slen, sf, 6, 6, 0);
+                        tindex2 = 3;
+                    } else if (sf < 244) {
+                        lsf_sf_expand(slen, sf - 180, 4, 4, 0);
+                        tindex2 = 4;
+                    } else {
+                        lsf_sf_expand(slen, sf - 244, 3, 0, 0);
+                        tindex2 = 5;
+                    }
+                } else {
+                    /* normal case */
+                    if (sf < 400) {
+                        lsf_sf_expand(slen, sf, 5, 4, 4);
+                        tindex2 = 0;
+                    } else if (sf < 500) {
+                        lsf_sf_expand(slen, sf - 400, 5, 4, 0);
+                        tindex2 = 1;
+                    } else {
+                        lsf_sf_expand(slen, sf - 500, 3, 0, 0);
+                        tindex2 = 2;
+                        g->preflag = 1;
+                    }
+                }
+
+                j = 0;
+                for (k = 0; k < 4; k++) {
+                    n  = lsf_nsf_table[tindex2][tindex][k];
+                    sl = slen[k];
+                    if (sl) {
+                        for (i = 0; i < n; i++)
+                            g->scale_factors[j++] = get_bits(&s->gb, sl);
+                    } else {
+                        for (i = 0; i < n; i++)
+                            g->scale_factors[j++] = 0;
+                    }
+                }
+                /* XXX: should compute exact size */
+                for (; j < 40; j++)
+                    g->scale_factors[j] = 0;
+            }
+
+            exponents_from_scale_factors(s, g, exponents);
+
+            /* read Huffman coded residue */
+            huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);
+        } /* ch */
+
+        if (s->mode == MPA_JSTEREO)
+            compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]);
+
+        for (ch = 0; ch < s->nb_channels; ch++) {
+            g = &s->granules[ch][gr];
+
+            reorder_block(s, g);
+            compute_antialias(s, g);
+            compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
+        }
+    } /* gr */
+    if (get_bits_count(&s->gb) < 0)
+        skip_bits_long(&s->gb, -get_bits_count(&s->gb));
+    return nb_granules * 18;
+}
+
+static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples,
+                           const uint8_t *buf, int buf_size)
+{
+    int i, nb_frames, ch, ret;
+    OUT_INT *samples_ptr;
+
+    init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
+
+    /* skip error protection field */
+    if (s->error_protection)
+        skip_bits(&s->gb, 16);
+
+    switch(s->layer) {
+    case 1:
+        s->avctx->frame_size = 384;
+        nb_frames = mp_decode_layer1(s);
+        break;
+    case 2:
+        s->avctx->frame_size = 1152;
+        nb_frames = mp_decode_layer2(s);
+        break;
+    case 3:
+        s->avctx->frame_size = s->lsf ? 576 : 1152;
+    default:
+        nb_frames = mp_decode_layer3(s);
+
+        if (nb_frames < 0)
+            return nb_frames;
+
+        s->last_buf_size=0;
+        if (s->in_gb.buffer) {
+            align_get_bits(&s->gb);
+            i = get_bits_left(&s->gb)>>3;
+            if (i >= 0 && i <= BACKSTEP_SIZE) {
+                memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i);
+                s->last_buf_size=i;
+            } else
+                av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i);
+            s->gb           = s->in_gb;
+            s->in_gb.buffer = NULL;
+        }
+
+        align_get_bits(&s->gb);
+        assert((get_bits_count(&s->gb) & 7) == 0);
+        i = get_bits_left(&s->gb) >> 3;
+
+        if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) {
+            if (i < 0)
+                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);
+        memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i);
+        s->last_buf_size += i;
+    }
+
+    /* get output buffer */
+    if (!samples) {
+        av_assert0(s->frame != NULL);
+        s->frame->nb_samples = s->avctx->frame_size;
+        if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+            return ret;
+        }
+        samples = (OUT_INT **)s->frame->extended_data;
+    }
+
+    /* apply the synthesis filter */
+    for (ch = 0; ch < s->nb_channels; ch++) {
+        int sample_stride;
+        if (s->avctx->sample_fmt == OUT_FMT_P) {
+            samples_ptr   = samples[ch];
+            sample_stride = 1;
+        } else {
+            samples_ptr   = samples[0] + ch;
+            sample_stride = s->nb_channels;
+        }
+        for (i = 0; i < nb_frames; i++) {
+            RENAME(ff_mpa_synth_filter)(&s->mpadsp, s->synth_buf[ch],
+                                        &(s->synth_buf_offset[ch]),
+                                        RENAME(ff_mpa_synth_window),
+                                        &s->dither_state, samples_ptr,
+                                        sample_stride, s->sb_samples[ch][i]);
+            samples_ptr += 32 * sample_stride;
+        }
+    }
+
+    return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels;
+}
+
+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;
+    MPADecodeContext *s = avctx->priv_data;
+    uint32_t header;
+    int ret;
+
+    if (buf_size < HEADER_SIZE)
+        return AVERROR_INVALIDDATA;
+
+    header = AV_RB32(buf);
+    if (ff_mpa_check_header(header) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Header missing\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
+        /* free format: prepare to compute frame size */
+        s->frame_size = -1;
+        return AVERROR_INVALIDDATA;
+    }
+    /* update codec info */
+    avctx->channels       = s->nb_channels;
+    avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+    if (!avctx->bit_rate)
+        avctx->bit_rate = s->bit_rate;
+
+    if (s->frame_size <= 0 || s->frame_size > buf_size) {
+        av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
+        return AVERROR_INVALIDDATA;
+    } else if (s->frame_size < buf_size) {
+        buf_size= s->frame_size;
+    }
+
+    s->frame = data;
+
+    ret = mp_decode_frame(s, NULL, buf, buf_size);
+    if (ret >= 0) {
+        s->frame->nb_samples = avctx->frame_size;
+        *got_frame_ptr       = 1;
+        avctx->sample_rate   = s->sample_rate;
+        //FIXME maybe move the other codec info stuff from above here too
+    } else {
+        av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
+        /* Only return an error if the bad frame makes up the whole packet or
+         * the error is related to buffer management.
+         * If there is more data in the packet, just consume the bad frame
+         * instead of returning an error, which would discard the whole
+         * packet. */
+        *got_frame_ptr = 0;
+        if (buf_size == avpkt->size || ret != AVERROR_INVALIDDATA)
+            return ret;
+    }
+    s->frame_size = 0;
+    return buf_size;
+}
+
+static void mp_flush(MPADecodeContext *ctx)
+{
+    memset(ctx->synth_buf, 0, sizeof(ctx->synth_buf));
+    ctx->last_buf_size = 0;
+}
+
+static void flush(AVCodecContext *avctx)
+{
+    mp_flush(avctx->priv_data);
+}
+
+#if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER
+static int decode_frame_adu(AVCodecContext *avctx, void *data,
+                            int *got_frame_ptr, AVPacket *avpkt)
+{
+    const uint8_t *buf  = avpkt->data;
+    int buf_size        = avpkt->size;
+    MPADecodeContext *s = avctx->priv_data;
+    uint32_t header;
+    int len, ret;
+
+    len = buf_size;
+
+    // Discard too short frames
+    if (buf_size < HEADER_SIZE) {
+        av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+
+    if (len > MPA_MAX_CODED_FRAME_SIZE)
+        len = MPA_MAX_CODED_FRAME_SIZE;
+
+    // Get header and restore sync word
+    header = AV_RB32(buf) | 0xffe00000;
+
+    if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame
+        av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
+    /* update codec info */
+    avctx->sample_rate = s->sample_rate;
+    avctx->channels    = s->nb_channels;
+    avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+    if (!avctx->bit_rate)
+        avctx->bit_rate = s->bit_rate;
+
+    s->frame_size = len;
+
+    s->frame = data;
+
+    ret = mp_decode_frame(s, NULL, buf, buf_size);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
+        return ret;
+    }
+
+    *got_frame_ptr = 1;
+
+    return buf_size;
+}
+#endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */
+
+#if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
+
+/**
+ * Context for MP3On4 decoder
+ */
+typedef struct MP3On4DecodeContext {
+    int frames;                     ///< number of mp3 frames per block (number of mp3 decoder instances)
+    int syncword;                   ///< syncword patch
+    const uint8_t *coff;            ///< channel offsets in output buffer
+    MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
+} MP3On4DecodeContext;
+
+#include "mpeg4audio.h"
+
+/* Next 3 arrays are indexed by channel config number (passed via codecdata) */
+
+/* number of mp3 decoder instances */
+static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 };
+
+/* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */
+static const uint8_t chan_offset[8][5] = {
+    { 0             },
+    { 0             },  // C
+    { 0             },  // FLR
+    { 2, 0          },  // C FLR
+    { 2, 0, 3       },  // C FLR BS
+    { 2, 0, 3       },  // C FLR BLRS
+    { 2, 0, 4, 3    },  // C FLR BLRS LFE
+    { 2, 0, 6, 4, 3 },  // C FLR BLRS BLR LFE
+};
+
+/* mp3on4 channel layouts */
+static const int16_t chan_layout[8] = {
+    0,
+    AV_CH_LAYOUT_MONO,
+    AV_CH_LAYOUT_STEREO,
+    AV_CH_LAYOUT_SURROUND,
+    AV_CH_LAYOUT_4POINT0,
+    AV_CH_LAYOUT_5POINT0,
+    AV_CH_LAYOUT_5POINT1,
+    AV_CH_LAYOUT_7POINT1
+};
+
+static av_cold int decode_close_mp3on4(AVCodecContext * avctx)
+{
+    MP3On4DecodeContext *s = avctx->priv_data;
+    int i;
+
+    for (i = 0; i < s->frames; i++)
+        av_free(s->mp3decctx[i]);
+
+    return 0;
+}
+
+
+static av_cold int decode_init_mp3on4(AVCodecContext * avctx)
+{
+    MP3On4DecodeContext *s = avctx->priv_data;
+    MPEG4AudioConfig cfg;
+    int i;
+
+    if ((avctx->extradata_size < 2) || (avctx->extradata == NULL)) {
+        av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    avpriv_mpeg4audio_get_config(&cfg, avctx->extradata,
+                                 avctx->extradata_size * 8, 1);
+    if (!cfg.chan_config || cfg.chan_config > 7) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
+        return AVERROR_INVALIDDATA;
+    }
+    s->frames             = mp3Frames[cfg.chan_config];
+    s->coff               = chan_offset[cfg.chan_config];
+    avctx->channels       = ff_mpeg4audio_channels[cfg.chan_config];
+    avctx->channel_layout = chan_layout[cfg.chan_config];
+
+    if (cfg.sample_rate < 16000)
+        s->syncword = 0xffe00000;
+    else
+        s->syncword = 0xfff00000;
+
+    /* Init the first mp3 decoder in standard way, so that all tables get builded
+     * We replace avctx->priv_data with the context of the first decoder so that
+     * decode_init() does not have to be changed.
+     * Other decoders will be initialized here copying data from the first context
+     */
+    // Allocate zeroed memory for the first decoder context
+    s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext));
+    if (!s->mp3decctx[0])
+        goto alloc_fail;
+    // Put decoder context in place to make init_decode() happy
+    avctx->priv_data = s->mp3decctx[0];
+    decode_init(avctx);
+    // Restore mp3on4 context pointer
+    avctx->priv_data = s;
+    s->mp3decctx[0]->adu_mode = 1; // Set adu mode
+
+    /* Create a separate codec/context for each frame (first is already ok).
+     * Each frame is 1 or 2 channels - up to 5 frames allowed
+     */
+    for (i = 1; i < s->frames; i++) {
+        s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext));
+        if (!s->mp3decctx[i])
+            goto alloc_fail;
+        s->mp3decctx[i]->adu_mode = 1;
+        s->mp3decctx[i]->avctx = avctx;
+        s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;
+    }
+
+    return 0;
+alloc_fail:
+    decode_close_mp3on4(avctx);
+    return AVERROR(ENOMEM);
+}
+
+
+static void flush_mp3on4(AVCodecContext *avctx)
+{
+    int i;
+    MP3On4DecodeContext *s = avctx->priv_data;
+
+    for (i = 0; i < s->frames; i++)
+        mp_flush(s->mp3decctx[i]);
+}
+
+
+static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
+                               int *got_frame_ptr, AVPacket *avpkt)
+{
+    AVFrame *frame         = data;
+    const uint8_t *buf     = avpkt->data;
+    int buf_size           = avpkt->size;
+    MP3On4DecodeContext *s = avctx->priv_data;
+    MPADecodeContext *m;
+    int fsize, len = buf_size, out_size = 0;
+    uint32_t header;
+    OUT_INT **out_samples;
+    OUT_INT *outptr[2];
+    int fr, ch, ret;
+
+    /* get output buffer */
+    frame->nb_samples = MPA_FRAME_SIZE;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+    out_samples = (OUT_INT **)frame->extended_data;
+
+    // Discard too short frames
+    if (buf_size < HEADER_SIZE)
+        return AVERROR_INVALIDDATA;
+
+    avctx->bit_rate = 0;
+
+    ch = 0;
+    for (fr = 0; fr < s->frames; fr++) {
+        fsize = AV_RB16(buf) >> 4;
+        fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);
+        m     = s->mp3decctx[fr];
+        assert(m != NULL);
+
+        if (fsize < HEADER_SIZE) {
+            av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
+            return AVERROR_INVALIDDATA;
+        }
+        header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
+
+        if (ff_mpa_check_header(header) < 0) // Bad header, discard block
+            break;
+
+        avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
+
+        if (ch + m->nb_channels > avctx->channels ||
+            s->coff[fr] + m->nb_channels > avctx->channels) {
+            av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
+                                        "channel count\n");
+            return AVERROR_INVALIDDATA;
+        }
+        ch += m->nb_channels;
+
+        outptr[0] = out_samples[s->coff[fr]];
+        if (m->nb_channels > 1)
+            outptr[1] = out_samples[s->coff[fr] + 1];
+
+        if ((ret = mp_decode_frame(m, outptr, buf, fsize)) < 0)
+            return ret;
+
+        out_size += ret;
+        buf      += fsize;
+        len      -= fsize;
+
+        avctx->bit_rate += m->bit_rate;
+    }
+
+    /* update codec info */
+    avctx->sample_rate = s->mp3decctx[0]->sample_rate;
+
+    frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
+    *got_frame_ptr    = 1;
+
+    return buf_size;
+}
+#endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */
diff --git a/libavcodec/mpegaudiodecheader.c b/libavcodec/mpegaudiodecheader.c
index f8fc833..69dda45 100644
--- a/libavcodec/mpegaudiodecheader.c
+++ b/libavcodec/mpegaudiodecheader.c
@@ -24,7 +24,6 @@
  * MPEG Audio header decoder.
  */
 
-//#define DEBUG
 #include "avcodec.h"
 #include "mpegaudio.h"
 #include "mpegaudiodata.h"
diff --git a/libavcodec/mpegaudiodsp.c b/libavcodec/mpegaudiodsp.c
index cd9371b..342ed16 100644
--- a/libavcodec/mpegaudiodsp.c
+++ b/libavcodec/mpegaudiodsp.c
@@ -19,11 +19,12 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "mpegaudiodsp.h"
 #include "dct.h"
 #include "dct32.h"
 
-void ff_mpadsp_init(MPADSPContext *s)
+av_cold void ff_mpadsp_init(MPADSPContext *s)
 {
     DCTContext dct;
 
@@ -41,6 +42,6 @@ void ff_mpadsp_init(MPADSPContext *s)
     s->imdct36_blocks_fixed = ff_imdct36_blocks_fixed;
 
     if (ARCH_ARM)     ff_mpadsp_init_arm(s);
+    if (ARCH_PPC)     ff_mpadsp_init_ppc(s);
     if (ARCH_X86)     ff_mpadsp_init_x86(s);
-    if (HAVE_ALTIVEC) ff_mpadsp_init_altivec(s);
 }
diff --git a/libavcodec/mpegaudiodsp.h b/libavcodec/mpegaudiodsp.h
index 1f85a15..d6aa3f5 100644
--- a/libavcodec/mpegaudiodsp.h
+++ b/libavcodec/mpegaudiodsp.h
@@ -55,8 +55,8 @@ void ff_mpa_synth_filter_float(MPADSPContext *s,
                                float *sb_samples);
 
 void ff_mpadsp_init_arm(MPADSPContext *s);
+void ff_mpadsp_init_ppc(MPADSPContext *s);
 void ff_mpadsp_init_x86(MPADSPContext *s);
-void ff_mpadsp_init_altivec(MPADSPContext *s);
 
 void ff_mpa_synth_init_float(float *window);
 void ff_mpa_synth_init_fixed(int32_t *window);
diff --git a/libavcodec/mpegaudiodsp_template.c b/libavcodec/mpegaudiodsp_template.c
index e7a7656..621bbd4 100644
--- a/libavcodec/mpegaudiodsp_template.c
+++ b/libavcodec/mpegaudiodsp_template.c
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 #include "dct32.h"
 #include "mathops.h"
@@ -220,7 +221,7 @@ av_cold void RENAME(ff_mpa_synth_init)(MPA_INT *window)
             window[512+128+16*i+j] = window[64*i+48-j];
 }
 
-void RENAME(ff_init_mpadsp_tabs)(void)
+av_cold void RENAME(ff_init_mpadsp_tabs)(void)
 {
     int i, j;
     /* compute mdct windows */
diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc.c
index ba0d8cf..a940c0d 100644
--- a/libavcodec/mpegaudioenc.c
+++ b/libavcodec/mpegaudioenc.c
@@ -35,6 +35,8 @@
 
 #include "mpegaudio.h"
 #include "mpegaudiodsp.h"
+#include "mpegaudiodata.h"
+#include "mpegaudiotab.h"
 
 /* currently, cannot change these constants (need to modify
    quantization stage) */
@@ -59,14 +61,13 @@ typedef struct MpegAudioContext {
     unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
     int sblimit; /* number of used subbands */
     const unsigned char *alloc_table;
+    int16_t filter_bank[512];
+    int scale_factor_table[64];
+    unsigned char scale_diff_table[128];
+    float scale_factor_inv_table[64];
+    unsigned short total_quant_bits[17]; /* total number of bits per allocation group */
 } MpegAudioContext;
 
-/* define it to use floats in quantization (I don't like floats !) */
-#define USE_FLOATS
-
-#include "mpegaudiodata.h"
-#include "mpegaudiotab.h"
-
 static av_cold int MPA_encode_init(AVCodecContext *avctx)
 {
     MpegAudioContext *s = avctx->priv_data;
@@ -140,25 +141,19 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx)
 #if WFRAC_BITS != 16
         v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);
 #endif
-        filter_bank[i] = v;
+        s->filter_bank[i] = v;
         if ((i & 63) != 0)
             v = -v;
         if (i != 0)
-            filter_bank[512 - i] = v;
+            s->filter_bank[512 - i] = v;
     }
 
     for(i=0;i<64;i++) {
         v = (int)(pow(2.0, (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);
-#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);
-#endif
+        s->scale_factor_table[i] = v;
+        s->scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20);
     }
     for(i=0;i<128;i++) {
         v = i - 64;
@@ -172,7 +167,7 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx)
             v = 3;
         else
             v = 4;
-        scale_diff_table[i] = v;
+        s->scale_diff_table[i] = v;
     }
 
     for(i=0;i<17;i++) {
@@ -181,15 +176,9 @@ static av_cold int MPA_encode_init(AVCodecContext *avctx)
             v = -v;
         else
             v = v * 3;
-        total_quant_bits[i] = 12 * v;
+        s->total_quant_bits[i] = 12 * v;
     }
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame= avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-#endif
-
     return 0;
 }
 
@@ -334,7 +323,7 @@ static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
 
         /* filter */
         p = s->samples_buf[ch] + offset;
-        q = filter_bank;
+        q = s->filter_bank;
         /* maxsum = 23169 */
         for(i=0;i<64;i++) {
             sum = p[0*64] * q[0*64];
@@ -368,7 +357,8 @@ static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
     s->samples_offset[ch] = offset;
 }
 
-static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
+static void compute_scale_factors(MpegAudioContext *s,
+                                  unsigned char scale_code[SBLIMIT],
                                   unsigned char scale_factors[SBLIMIT][3],
                                   int sb_samples[3][12][SBLIMIT],
                                   int sblimit)
@@ -395,7 +385,7 @@ static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
                    use at most 2 compares to find the index */
                 index = (21 - n) * 3 - 3;
                 if (index >= 0) {
-                    while (vmax <= scale_factor_table[index+1])
+                    while (vmax <= s->scale_factor_table[index+1])
                         index++;
                 } else {
                     index = 0; /* very unlikely case of overflow */
@@ -405,7 +395,7 @@ static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
             }
 
             av_dlog(NULL, "%2d:%d in=%x %x %d\n",
-                    j, i, vmax, scale_factor_table[index], index);
+                    j, i, vmax, s->scale_factor_table[index], index);
             /* store the scale factor */
             assert(index >=0 && index <= 63);
             sf[i] = index;
@@ -413,8 +403,8 @@ static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
 
         /* compute the transmission factor : look if the scale factors
            are close enough to each other */
-        d1 = scale_diff_table[sf[0] - sf[1] + 64];
-        d2 = scale_diff_table[sf[1] - sf[2] + 64];
+        d1 = s->scale_diff_table[sf[0] - sf[1] + 64];
+        d2 = s->scale_diff_table[sf[1] - sf[2] + 64];
 
         /* handle the 25 cases */
         switch(d1 * 5 + d2) {
@@ -564,12 +554,12 @@ static void compute_bit_allocation(MpegAudioContext *s,
         if (subband_status[max_ch][max_sb] == SB_NOTALLOCATED) {
             /* nothing was coded for this band: add the necessary bits */
             incr = 2 + nb_scale_factors[s->scale_code[max_ch][max_sb]] * 6;
-            incr += total_quant_bits[alloc[1]];
+            incr += s->total_quant_bits[alloc[1]];
         } else {
             /* increments bit allocation */
             b = bit_alloc[max_ch][max_sb];
-            incr = total_quant_bits[alloc[b + 1]] -
-                total_quant_bits[alloc[b]];
+            incr = s->total_quant_bits[alloc[b + 1]] -
+                s->total_quant_bits[alloc[b]];
         }
 
         if (current_frame_size + incr <= max_frame_size) {
@@ -678,30 +668,11 @@ static void encode_frame(MpegAudioContext *s,
                         qindex = s->alloc_table[j+b];
                         steps = ff_mpa_quant_steps[qindex];
                         for(m=0;m<3;m++) {
+                            float a;
                             sample = s->sb_samples[ch][k][l + m][i];
                             /* divide by scale factor */
-#ifdef USE_FLOATS
-                            {
-                                float a;
-                                a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]];
-                                q[m] = (int)((a + 1.0) * steps * 0.5);
-                            }
-#else
-                            {
-                                int q1, e, shift, mult;
-                                e = s->scale_factors[ch][i][k];
-                                shift = scale_factor_shift[e];
-                                mult = scale_factor_mult[e];
-
-                                /* normalize to P bits */
-                                if (shift < 0)
-                                    q1 = sample << (-shift);
-                                else
-                                    q1 = sample >> shift;
-                                q1 = (q1 * mult) >> P;
-                                q[m] = ((q1 + (1 << P)) * steps) >> (P + 1);
-                            }
-#endif
+                            a = (float)sample * s->scale_factor_inv_table[s->scale_factors[ch][i][k]];
+                            q[m] = (int)((a + 1.0) * steps * 0.5);
                             if (q[m] >= steps)
                                 q[m] = steps - 1;
                             assert(q[m] >= 0 && q[m] < steps);
@@ -746,7 +717,7 @@ static int MPA_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     }
 
     for(i=0;i<s->nb_channels;i++) {
-        compute_scale_factors(s->scale_code[i], s->scale_factors[i],
+        compute_scale_factors(s, s->scale_code[i], s->scale_factors[i],
                               s->sb_samples[i], s->sblimit);
     }
     for(i=0;i<s->nb_channels;i++) {
@@ -771,14 +742,6 @@ static int MPA_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     return 0;
 }
 
-static av_cold int MPA_encode_close(AVCodecContext *avctx)
-{
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
-    return 0;
-}
-
 static const AVCodecDefault mp2_defaults[] = {
     { "b",    "128k" },
     { NULL },
@@ -786,12 +749,12 @@ static const AVCodecDefault mp2_defaults[] = {
 
 AVCodec ff_mp2_encoder = {
     .name                  = "mp2",
+    .long_name             = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
     .type                  = AVMEDIA_TYPE_AUDIO,
     .id                    = AV_CODEC_ID_MP2,
     .priv_data_size        = sizeof(MpegAudioContext),
     .init                  = MPA_encode_init,
     .encode2               = MPA_encode_frame,
-    .close                 = MPA_encode_close,
     .sample_fmts           = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                             AV_SAMPLE_FMT_NONE },
     .supported_samplerates = (const int[]){
@@ -800,6 +763,5 @@ AVCodec ff_mp2_encoder = {
     .channel_layouts       = (const uint64_t[]){ AV_CH_LAYOUT_MONO,
                                                  AV_CH_LAYOUT_STEREO,
                                                  0 },
-    .long_name             = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
     .defaults              = mp2_defaults,
 };
diff --git a/libavcodec/mpegaudiotab.h b/libavcodec/mpegaudiotab.h
index 45afe9b..d30ef1b 100644
--- a/libavcodec/mpegaudiotab.h
+++ b/libavcodec/mpegaudiotab.h
@@ -79,20 +79,6 @@ static const int bitinv32[32] = {
 };
 
 
-static int16_t filter_bank[512];
-
-static int scale_factor_table[64];
-#ifdef USE_FLOATS
-static float scale_factor_inv_table[64];
-#else
-static int8_t scale_factor_shift[64];
-static unsigned short scale_factor_mult[64];
-#endif
-static unsigned char scale_diff_table[128];
-
-/* total number of bits per allocation group */
-static unsigned short total_quant_bits[17];
-
 /* signal to noise ratio of each quantification step (could be
    computed from quant_steps[]). The values are dB multiplied by 10
 */
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 0274f01..f39cdca 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -27,7 +27,10 @@
  * The simplest mpeg encoder (well, it was the simplest!).
  */
 
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "internal.h"
@@ -39,30 +42,20 @@
 #include "thread.h"
 #include <limits.h>
 
-//#undef NDEBUG
-//#include <assert.h>
-
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale);
+                                   int16_t *block, int n, int qscale);
 static void dct_unquantize_h263_intra_c(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale);
+                                  int16_t *block, int n, int qscale);
 static void dct_unquantize_h263_inter_c(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale);
-
-
-/* enable all paranoid tests for rounding, overflows, etc... */
-//#define PARANOID
-
-//#define DEBUG
-
+                                  int16_t *block, int n, int qscale);
 
 static const uint8_t ff_default_chroma_qscale_table[32] = {
 //   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
@@ -130,51 +123,38 @@ const enum AVPixelFormat ff_pixfmt_list_420[] = {
     AV_PIX_FMT_NONE
 };
 
-const enum AVPixelFormat ff_hwaccel_pixfmt_list_420[] = {
-    AV_PIX_FMT_DXVA2_VLD,
-    AV_PIX_FMT_VAAPI_VLD,
-    AV_PIX_FMT_VDA_VLD,
-    AV_PIX_FMT_YUV420P,
-    AV_PIX_FMT_NONE
-};
-
-const uint8_t *avpriv_mpv_find_start_code(const uint8_t *restrict p,
-                                          const uint8_t *end,
-                                          uint32_t * restrict state)
+static void mpeg_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
+                              int (*mv)[2][4][2],
+                              int mb_x, int mb_y, int mb_intra, int mb_skipped)
 {
-    int i;
+    MpegEncContext *s = opaque;
 
-    assert(p <= end);
-    if (p >= end)
-        return end;
+    s->mv_dir     = mv_dir;
+    s->mv_type    = mv_type;
+    s->mb_intra   = mb_intra;
+    s->mb_skipped = mb_skipped;
+    s->mb_x       = mb_x;
+    s->mb_y       = mb_y;
+    memcpy(s->mv, mv, sizeof(*mv));
 
-    for (i = 0; i < 3; i++) {
-        uint32_t tmp = *state << 8;
-        *state = tmp + *(p++);
-        if (tmp == 0x100 || p == end)
-            return p;
-    }
+    ff_init_block_index(s);
+    ff_update_block_index(s);
 
-    while (p < end) {
-        if      (p[-1] > 1      ) p += 3;
-        else if (p[-2]          ) p += 2;
-        else if (p[-3]|(p[-1]-1)) p++;
-        else {
-            p++;
-            break;
-        }
-    }
+    s->dsp.clear_blocks(s->block[0]);
 
-    p = FFMIN(p, end) - 4;
-    *state = AV_RB32(p);
+    s->dest[0] = s->current_picture.f.data[0] + (s->mb_y *  16                       * s->linesize)   + s->mb_x *  16;
+    s->dest[1] = s->current_picture.f.data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
+    s->dest[2] = s->current_picture.f.data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
 
-    return p + 4;
+    assert(ref == 0);
+    ff_MPV_decode_mb(s, s->block);
 }
 
 /* init common dct for both encoder and decoder */
 av_cold int ff_dct_common_init(MpegEncContext *s)
 {
     ff_dsputil_init(&s->dsp, s->avctx);
+    ff_hpeldsp_init(&s->hdsp, s->avctx->flags);
     ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample);
 
     s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;
@@ -186,17 +166,14 @@ av_cold int ff_dct_common_init(MpegEncContext *s)
         s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;
     s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;
 
-#if ARCH_X86
-    ff_MPV_common_init_x86(s);
-#elif ARCH_ALPHA
-    ff_MPV_common_init_axp(s);
-#elif ARCH_ARM
-    ff_MPV_common_init_arm(s);
-#elif HAVE_ALTIVEC
-    ff_MPV_common_init_altivec(s);
-#elif ARCH_BFIN
-    ff_MPV_common_init_bfin(s);
-#endif
+    if (ARCH_ARM)
+        ff_MPV_common_init_arm(s);
+    if (ARCH_BFIN)
+        ff_MPV_common_init_bfin(s);
+    if (ARCH_PPC)
+        ff_MPV_common_init_ppc(s);
+    if (ARCH_X86)
+        ff_MPV_common_init_x86(s);
 
     /* load & permutate scantables
      * note: only wmv uses different ones
@@ -214,29 +191,7 @@ av_cold int ff_dct_common_init(MpegEncContext *s)
     return 0;
 }
 
-void ff_copy_picture(Picture *dst, Picture *src)
-{
-    *dst = *src;
-    dst->f.type = FF_BUFFER_TYPE_COPY;
-}
-
-/**
- * Release a frame buffer
- */
-static void free_frame_buffer(MpegEncContext *s, Picture *pic)
-{
-    /* WM Image / Screen codecs allocate internal buffers with different
-     * dimensions / colorspaces; ignore user-defined callbacks for these. */
-    if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
-        s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
-        s->codec_id != AV_CODEC_ID_MSS2)
-        ff_thread_release_buffer(s->avctx, &pic->f);
-    else
-        avcodec_default_release_buffer(s->avctx, &pic->f);
-    av_freep(&pic->f.hwaccel_picture_private);
-}
-
-int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize)
+static int frame_size_alloc(MpegEncContext *s, int linesize)
 {
     int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
 
@@ -268,79 +223,156 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
 {
     int r, ret;
 
+    pic->tf.f = &pic->f;
+    if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
+        s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
+        s->codec_id != AV_CODEC_ID_MSS2)
+        r = ff_thread_get_buffer(s->avctx, &pic->tf,
+                                 pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
+    else {
+        pic->f.width  = s->avctx->width;
+        pic->f.height = s->avctx->height;
+        pic->f.format = s->avctx->pix_fmt;
+        r = avcodec_default_get_buffer2(s->avctx, &pic->f, 0);
+    }
+
+    if (r < 0 || !pic->f.buf[0]) {
+        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n",
+               r, pic->f.data[0]);
+        return -1;
+    }
+
     if (s->avctx->hwaccel) {
-        assert(!pic->f.hwaccel_picture_private);
+        assert(!pic->hwaccel_picture_private);
         if (s->avctx->hwaccel->priv_data_size) {
-            pic->f.hwaccel_picture_private = av_mallocz(s->avctx->hwaccel->priv_data_size);
-            if (!pic->f.hwaccel_picture_private) {
+            pic->hwaccel_priv_buf = av_buffer_allocz(s->avctx->hwaccel->priv_data_size);
+            if (!pic->hwaccel_priv_buf) {
                 av_log(s->avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n");
                 return -1;
             }
+            pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data;
         }
     }
 
-    if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
-        s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
-        s->codec_id != AV_CODEC_ID_MSS2)
-        r = ff_thread_get_buffer(s->avctx, &pic->f);
-    else
-        r = avcodec_default_get_buffer(s->avctx, &pic->f);
-
-    if (r < 0 || !pic->f.type || !pic->f.data[0]) {
-        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %p)\n",
-               r, pic->f.type, pic->f.data[0]);
-        av_freep(&pic->f.hwaccel_picture_private);
-        return -1;
-    }
-
     if (s->linesize && (s->linesize   != pic->f.linesize[0] ||
                         s->uvlinesize != pic->f.linesize[1])) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed (stride changed)\n");
-        free_frame_buffer(s, pic);
+        ff_mpeg_unref_picture(s, pic);
         return -1;
     }
 
     if (pic->f.linesize[1] != pic->f.linesize[2]) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed (uv stride mismatch)\n");
-        free_frame_buffer(s, pic);
+        ff_mpeg_unref_picture(s, pic);
         return -1;
     }
 
     if (!s->edge_emu_buffer &&
-        (ret = ff_mpv_frame_size_alloc(s, pic->f.linesize[0])) < 0) {
+        (ret = frame_size_alloc(s, pic->f.linesize[0])) < 0) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed to allocate context scratch buffers.\n");
-        free_frame_buffer(s, pic);
+        ff_mpeg_unref_picture(s, pic);
         return ret;
     }
 
     return 0;
 }
 
-/**
- * Allocate a Picture.
- * The pixels are allocated/set by calling get_buffer() if shared = 0
- */
-int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared)
+void ff_free_picture_tables(Picture *pic)
 {
-    const int big_mb_num = s->mb_stride * (s->mb_height + 1) + 1;
+    int i;
+
+    av_buffer_unref(&pic->mb_var_buf);
+    av_buffer_unref(&pic->mc_mb_var_buf);
+    av_buffer_unref(&pic->mb_mean_buf);
+    av_buffer_unref(&pic->mbskip_table_buf);
+    av_buffer_unref(&pic->qscale_table_buf);
+    av_buffer_unref(&pic->mb_type_buf);
 
-    // the + 1 is needed so memset(,,stride*height) does not sig11
+    for (i = 0; i < 2; i++) {
+        av_buffer_unref(&pic->motion_val_buf[i]);
+        av_buffer_unref(&pic->ref_index_buf[i]);
+    }
+}
 
+static int alloc_picture_tables(MpegEncContext *s, Picture *pic)
+{
+    const int big_mb_num    = s->mb_stride * (s->mb_height + 1) + 1;
     const int mb_array_size = s->mb_stride * s->mb_height;
     const int b8_array_size = s->b8_stride * s->mb_height * 2;
-    const int b4_array_size = s->b4_stride * s->mb_height * 4;
     int i;
-    int r = -1;
+
+
+    pic->mbskip_table_buf = av_buffer_allocz(mb_array_size + 2);
+    pic->qscale_table_buf = av_buffer_allocz(big_mb_num + s->mb_stride);
+    pic->mb_type_buf      = av_buffer_allocz((big_mb_num + s->mb_stride) *
+                                             sizeof(uint32_t));
+    if (!pic->mbskip_table_buf || !pic->qscale_table_buf || !pic->mb_type_buf)
+        return AVERROR(ENOMEM);
+
+    if (s->encoding) {
+        pic->mb_var_buf    = av_buffer_allocz(mb_array_size * sizeof(int16_t));
+        pic->mc_mb_var_buf = av_buffer_allocz(mb_array_size * sizeof(int16_t));
+        pic->mb_mean_buf   = av_buffer_allocz(mb_array_size);
+        if (!pic->mb_var_buf || !pic->mc_mb_var_buf || !pic->mb_mean_buf)
+            return AVERROR(ENOMEM);
+    }
+
+    if (s->out_format == FMT_H263 || s->encoding) {
+        int mv_size        = 2 * (b8_array_size + 4) * sizeof(int16_t);
+        int ref_index_size = 4 * mb_array_size;
+
+        for (i = 0; mv_size && i < 2; i++) {
+            pic->motion_val_buf[i] = av_buffer_allocz(mv_size);
+            pic->ref_index_buf[i]  = av_buffer_allocz(ref_index_size);
+            if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i])
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    return 0;
+}
+
+static int make_tables_writable(Picture *pic)
+{
+    int ret, i;
+#define MAKE_WRITABLE(table) \
+do {\
+    if (pic->table &&\
+       (ret = av_buffer_make_writable(&pic->table)) < 0)\
+    return ret;\
+} while (0)
+
+    MAKE_WRITABLE(mb_var_buf);
+    MAKE_WRITABLE(mc_mb_var_buf);
+    MAKE_WRITABLE(mb_mean_buf);
+    MAKE_WRITABLE(mbskip_table_buf);
+    MAKE_WRITABLE(qscale_table_buf);
+    MAKE_WRITABLE(mb_type_buf);
+
+    for (i = 0; i < 2; i++) {
+        MAKE_WRITABLE(motion_val_buf[i]);
+        MAKE_WRITABLE(ref_index_buf[i]);
+    }
+
+    return 0;
+}
+
+/**
+ * Allocate a Picture.
+ * The pixels are allocated/set by calling get_buffer() if shared = 0
+ */
+int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared)
+{
+    int i, ret;
 
     if (shared) {
         assert(pic->f.data[0]);
-        assert(pic->f.type == 0 || pic->f.type == FF_BUFFER_TYPE_SHARED);
-        pic->f.type = FF_BUFFER_TYPE_SHARED;
+        pic->shared = 1;
     } else {
-        assert(!pic->f.data[0]);
+        assert(!pic->f.buf[0]);
 
         if (alloc_frame_buffer(s, pic) < 0)
             return -1;
@@ -349,104 +381,153 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared)
         s->uvlinesize = pic->f.linesize[1];
     }
 
-    if (pic->f.qscale_table == NULL) {
-        if (s->encoding) {
-            FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_var,
-                              mb_array_size * sizeof(int16_t), fail)
-            FF_ALLOCZ_OR_GOTO(s->avctx, pic->mc_mb_var,
-                              mb_array_size * sizeof(int16_t), fail)
-            FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_mean,
-                              mb_array_size * sizeof(int8_t ), fail)
-        }
+    if (!pic->qscale_table_buf)
+        ret = alloc_picture_tables(s, pic);
+    else
+        ret = make_tables_writable(pic);
+    if (ret < 0)
+        goto fail;
 
-        FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.mbskip_table,
-                          mb_array_size * sizeof(uint8_t) + 2, fail)// the + 2 is for the slice end check
-        FF_ALLOCZ_OR_GOTO(s->avctx, pic->qscale_table_base,
-                          (big_mb_num + s->mb_stride) * sizeof(uint8_t),
-                          fail)
-        FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_type_base,
-                          (big_mb_num + s->mb_stride) * sizeof(uint32_t),
-                          fail)
-        pic->f.mb_type = pic->mb_type_base + 2 * s->mb_stride + 1;
-        pic->f.qscale_table = pic->qscale_table_base + 2 * s->mb_stride + 1;
-        if (s->out_format == FMT_H264) {
-            for (i = 0; i < 2; i++) {
-                FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i],
-                                  2 * (b4_array_size + 4) * sizeof(int16_t),
-                                  fail)
-                pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
-                FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.ref_index[i],
-                                  4 * mb_array_size * sizeof(uint8_t), fail)
-            }
-            pic->f.motion_subsample_log2 = 2;
-        } else if (s->out_format == FMT_H263 || s->encoding ||
-                   (s->avctx->debug & FF_DEBUG_MV) || s->avctx->debug_mv) {
-            for (i = 0; i < 2; i++) {
-                FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i],
-                                  2 * (b8_array_size + 4) * sizeof(int16_t),
-                                  fail)
-                pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
-                FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.ref_index[i],
-                                  4 * mb_array_size * sizeof(uint8_t), fail)
-            }
-            pic->f.motion_subsample_log2 = 3;
-        }
-        if (s->avctx->debug&FF_DEBUG_DCT_COEFF) {
-            FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.dct_coeff,
-                              64 * mb_array_size * sizeof(DCTELEM) * 6, fail)
-        }
-        pic->f.qstride = s->mb_stride;
-        FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.pan_scan,
-                          1 * sizeof(AVPanScan), fail)
+    if (s->encoding) {
+        pic->mb_var    = (uint16_t*)pic->mb_var_buf->data;
+        pic->mc_mb_var = (uint16_t*)pic->mc_mb_var_buf->data;
+        pic->mb_mean   = pic->mb_mean_buf->data;
     }
 
-    pic->owner2 = s;
+    pic->mbskip_table = pic->mbskip_table_buf->data;
+    pic->qscale_table = pic->qscale_table_buf->data + 2 * s->mb_stride + 1;
+    pic->mb_type      = (uint32_t*)pic->mb_type_buf->data + 2 * s->mb_stride + 1;
+
+    if (pic->motion_val_buf[0]) {
+        for (i = 0; i < 2; i++) {
+            pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
+            pic->ref_index[i]  = pic->ref_index_buf[i]->data;
+        }
+    }
 
     return 0;
-fail: // for  the FF_ALLOCZ_OR_GOTO macro
-    if (r >= 0)
-        free_frame_buffer(s, pic);
-    return -1;
+fail:
+    av_log(s->avctx, AV_LOG_ERROR, "Error allocating a picture.\n");
+    ff_mpeg_unref_picture(s, pic);
+    ff_free_picture_tables(pic);
+    return AVERROR(ENOMEM);
 }
 
 /**
  * Deallocate a picture.
  */
-static void free_picture(MpegEncContext *s, Picture *pic)
+void ff_mpeg_unref_picture(MpegEncContext *s, Picture *pic)
 {
-    int i;
+    int off = offsetof(Picture, mb_mean) + sizeof(pic->mb_mean);
 
-    if (pic->f.data[0] && pic->f.type != FF_BUFFER_TYPE_SHARED) {
-        free_frame_buffer(s, pic);
-    }
-
-    av_freep(&pic->mb_var);
-    av_freep(&pic->mc_mb_var);
-    av_freep(&pic->mb_mean);
-    av_freep(&pic->f.mbskip_table);
-    av_freep(&pic->qscale_table_base);
-    pic->f.qscale_table = NULL;
-    av_freep(&pic->mb_type_base);
-    pic->f.mb_type = NULL;
-    av_freep(&pic->f.dct_coeff);
-    av_freep(&pic->f.pan_scan);
-    pic->f.mb_type = NULL;
+    pic->tf.f = &pic->f;
+    /* WM Image / Screen codecs allocate internal buffers with different
+     * dimensions / colorspaces; ignore user-defined callbacks for these. */
+    if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
+        s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
+        s->codec_id != AV_CODEC_ID_MSS2)
+        ff_thread_release_buffer(s->avctx, &pic->tf);
+    else
+        av_frame_unref(&pic->f);
+
+    av_buffer_unref(&pic->hwaccel_priv_buf);
+
+    if (pic->needs_realloc)
+        ff_free_picture_tables(pic);
+
+    memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
+}
+
+static int update_picture_tables(Picture *dst, Picture *src)
+{
+     int i;
+
+#define UPDATE_TABLE(table)\
+do {\
+    if (src->table &&\
+        (!dst->table || dst->table->buffer != src->table->buffer)) {\
+        av_buffer_unref(&dst->table);\
+        dst->table = av_buffer_ref(src->table);\
+        if (!dst->table) {\
+            ff_free_picture_tables(dst);\
+            return AVERROR(ENOMEM);\
+        }\
+    }\
+} while (0)
+
+    UPDATE_TABLE(mb_var_buf);
+    UPDATE_TABLE(mc_mb_var_buf);
+    UPDATE_TABLE(mb_mean_buf);
+    UPDATE_TABLE(mbskip_table_buf);
+    UPDATE_TABLE(qscale_table_buf);
+    UPDATE_TABLE(mb_type_buf);
     for (i = 0; i < 2; i++) {
-        av_freep(&pic->motion_val_base[i]);
-        av_freep(&pic->f.ref_index[i]);
-        pic->f.motion_val[i] = NULL;
+        UPDATE_TABLE(motion_val_buf[i]);
+        UPDATE_TABLE(ref_index_buf[i]);
     }
 
-    if (pic->f.type == FF_BUFFER_TYPE_SHARED) {
-        for (i = 0; i < 4; i++) {
-            pic->f.base[i] =
-            pic->f.data[i] = NULL;
-        }
-        pic->f.type = 0;
+    dst->mb_var        = src->mb_var;
+    dst->mc_mb_var     = src->mc_mb_var;
+    dst->mb_mean       = src->mb_mean;
+    dst->mbskip_table  = src->mbskip_table;
+    dst->qscale_table  = src->qscale_table;
+    dst->mb_type       = src->mb_type;
+    for (i = 0; i < 2; i++) {
+        dst->motion_val[i] = src->motion_val[i];
+        dst->ref_index[i]  = src->ref_index[i];
+    }
+
+    return 0;
+}
+
+int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src)
+{
+    int ret;
+
+    av_assert0(!dst->f.buf[0]);
+    av_assert0(src->f.buf[0]);
+
+    src->tf.f = &src->f;
+    dst->tf.f = &dst->f;
+    ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+    if (ret < 0)
+        goto fail;
+
+    ret = update_picture_tables(dst, src);
+    if (ret < 0)
+        goto fail;
+
+    if (src->hwaccel_picture_private) {
+        dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
+        if (!dst->hwaccel_priv_buf)
+            goto fail;
+        dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
     }
+
+    dst->field_picture           = src->field_picture;
+    dst->mb_var_sum              = src->mb_var_sum;
+    dst->mc_mb_var_sum           = src->mc_mb_var_sum;
+    dst->b_frame_score           = src->b_frame_score;
+    dst->needs_realloc           = src->needs_realloc;
+    dst->reference               = src->reference;
+    dst->shared                  = src->shared;
+
+    return 0;
+fail:
+    ff_mpeg_unref_picture(s, dst);
+    return ret;
+}
+
+static void exchange_uv(MpegEncContext *s)
+{
+    int16_t (*tmp)[64];
+
+    tmp           = s->pblocks[4];
+    s->pblocks[4] = s->pblocks[5];
+    s->pblocks[5] = tmp;
 }
 
-static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base)
+static int init_duplicate_context(MpegEncContext *s)
 {
     int y_size = s->b8_stride * (2 * s->mb_height + 1);
     int c_size = s->mb_stride * (s->mb_height + 1);
@@ -470,12 +551,14 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base)
                               2 * 64 * sizeof(int), fail)
         }
     }
-    FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(DCTELEM), fail)
+    FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(int16_t), fail)
     s->block = s->blocks[0];
 
     for (i = 0; i < 12; i++) {
         s->pblocks[i] = &s->block[i];
     }
+    if (s->avctx->codec_tag == AV_RL32("VCR2"))
+        exchange_uv(s);
 
     if (s->out_format == FMT_H263) {
         /* ac values */
@@ -550,8 +633,10 @@ int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src)
     for (i = 0; i < 12; i++) {
         dst->pblocks[i] = &dst->block[i];
     }
+    if (dst->avctx->codec_tag == AV_RL32("VCR2"))
+        exchange_uv(dst);
     if (!dst->edge_emu_buffer &&
-        (ret = ff_mpv_frame_size_alloc(dst, dst->linesize)) < 0) {
+        (ret = frame_size_alloc(dst, dst->linesize)) < 0) {
         av_log(dst->avctx, AV_LOG_ERROR, "failed to allocate context "
                "scratch buffers.\n");
         return ret;
@@ -564,7 +649,7 @@ int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src)
 int ff_mpeg_update_thread_context(AVCodecContext *dst,
                                   const AVCodecContext *src)
 {
-    int i;
+    int i, ret;
     MpegEncContext *s = dst->priv_data, *s1 = src->priv_data;
 
     if (dst == src || !s1->context_initialized)
@@ -576,8 +661,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
         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;
 
@@ -600,15 +683,28 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
 
     s->coded_picture_number = s1->coded_picture_number;
     s->picture_number       = s1->picture_number;
-    s->input_picture_number = s1->input_picture_number;
 
-    memcpy(s->picture, s1->picture, s1->picture_count * sizeof(Picture));
-    memcpy(&s->last_picture, &s1->last_picture,
-           (char *) &s1->last_picture_ptr - (char *) &s1->last_picture);
-
-    // reset s->picture[].f.extended_data to s->picture[].f.data
-    for (i = 0; i < s->picture_count; i++)
-        s->picture[i].f.extended_data = s->picture[i].f.data;
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        ff_mpeg_unref_picture(s, &s->picture[i]);
+        if (s1->picture[i].f.buf[0] &&
+            (ret = ff_mpeg_ref_picture(s, &s->picture[i], &s1->picture[i])) < 0)
+            return ret;
+    }
+
+#define UPDATE_PICTURE(pic)\
+do {\
+    ff_mpeg_unref_picture(s, &s->pic);\
+    if (s1->pic.f.buf[0])\
+        ret = ff_mpeg_ref_picture(s, &s->pic, &s1->pic);\
+    else\
+        ret = update_picture_tables(&s->pic, &s1->pic);\
+    if (ret < 0)\
+        return ret;\
+} while (0)
+
+    UPDATE_PICTURE(current_picture);
+    UPDATE_PICTURE(last_picture);
+    UPDATE_PICTURE(next_picture);
 
     s->last_picture_ptr    = REBASE_PICTURE(s1->last_picture_ptr,    s, s1);
     s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1);
@@ -619,8 +715,9 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
     s->workaround_bugs      = s1->workaround_bugs;
 
     // MPEG4 timing info
-    memcpy(&s->time_increment_bits, &s1->time_increment_bits,
-           (char *) &s1->shape - (char *) &s1->time_increment_bits);
+    memcpy(&s->last_time_base, &s1->last_time_base,
+           (char *) &s1->pb_field_time + sizeof(s1->pb_field_time) -
+           (char *) &s1->last_time_base);
 
     // B-frame info
     s->max_b_frames = s1->max_b_frames;
@@ -646,7 +743,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
     // linesize dependend scratch buffer allocation
     if (!s->edge_emu_buffer)
         if (s1->linesize) {
-            if (ff_mpv_frame_size_alloc(s, s1->linesize) < 0) {
+            if (frame_size_alloc(s, s1->linesize) < 0) {
                 av_log(s->avctx, AV_LOG_ERROR, "Failed to allocate context "
                        "scratch buffers.\n");
                 return AVERROR(ENOMEM);
@@ -665,10 +762,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
         s->last_pict_type = s1->pict_type;
         if (s1->current_picture_ptr)
             s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f.quality;
-
-        if (s1->pict_type != AV_PICTURE_TYPE_B) {
-            s->last_non_b_pict_type = s1->pict_type;
-        }
     }
 
     return 0;
@@ -691,16 +784,10 @@ void ff_MPV_common_defaults(MpegEncContext *s)
 
     s->coded_picture_number  = 0;
     s->picture_number        = 0;
-    s->input_picture_number  = 0;
-
-    s->picture_in_gop_number = 0;
 
     s->f_code                = 1;
     s->b_code                = 1;
 
-    s->picture_range_start   = 0;
-    s->picture_range_end     = MAX_PICTURE_COUNT;
-
     s->slice_context_count   = 1;
 }
 
@@ -714,6 +801,43 @@ void ff_MPV_decode_defaults(MpegEncContext *s)
     ff_MPV_common_defaults(s);
 }
 
+static int init_er(MpegEncContext *s)
+{
+    ERContext *er = &s->er;
+    int mb_array_size = s->mb_height * s->mb_stride;
+    int i;
+
+    er->avctx       = s->avctx;
+    er->dsp         = &s->dsp;
+
+    er->mb_index2xy = s->mb_index2xy;
+    er->mb_num      = s->mb_num;
+    er->mb_width    = s->mb_width;
+    er->mb_height   = s->mb_height;
+    er->mb_stride   = s->mb_stride;
+    er->b8_stride   = s->b8_stride;
+
+    er->er_temp_buffer     = av_malloc(s->mb_height * s->mb_stride);
+    er->error_status_table = av_mallocz(mb_array_size);
+    if (!er->er_temp_buffer || !er->error_status_table)
+        goto fail;
+
+    er->mbskip_table  = s->mbskip_table;
+    er->mbintra_table = s->mbintra_table;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->dc_val); i++)
+        er->dc_val[i] = s->dc_val[i];
+
+    er->decode_mb = mpeg_er_decode_mb;
+    er->opaque    = s;
+
+    return 0;
+fail:
+    av_freep(&er->er_temp_buffer);
+    av_freep(&er->error_status_table);
+    return AVERROR(ENOMEM);
+}
+
 /**
  * Initialize and allocates MpegEncContext fields dependent on the resolution.
  */
@@ -792,11 +916,6 @@ static int init_context_frame(MpegEncContext *s)
 
     }
 
-    FF_ALLOC_OR_GOTO(s->avctx, s->er_temp_buffer,
-                     mb_array_size * sizeof(uint8_t), fail);
-    FF_ALLOCZ_OR_GOTO(s->avctx, s->error_status_table,
-                      mb_array_size * sizeof(uint8_t), fail);
-
     if (s->codec_id == AV_CODEC_ID_MPEG4 ||
         (s->flags & CODEC_FLAG_INTERLACED_ME)) {
         /* interlaced direct mode decoding tables */
@@ -854,17 +973,7 @@ static int init_context_frame(MpegEncContext *s)
     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;
+    return init_er(s);
 fail:
     return AVERROR(ENOMEM);
 }
@@ -885,7 +994,7 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
 
     if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
         s->mb_height = (s->height + 31) / 32 * 2;
-    else if (s->codec_id != AV_CODEC_ID_H264)
+    else
         s->mb_height = (s->height + 15) / 16;
 
     if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) {
@@ -924,43 +1033,17 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
 
     s->stream_codec_tag   = avpriv_toupper4(s->avctx->stream_codec_tag);
 
-    if (s->width && s->height) {
-        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);
-
-            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);
-            }
-        }
-    }
-
-    s->picture_count = MAX_PICTURE_COUNT * FFMAX(1, s->avctx->thread_count);
     FF_ALLOCZ_OR_GOTO(s->avctx, s->picture,
-                      s->picture_count * sizeof(Picture), fail);
-    for (i = 0; i < s->picture_count; i++) {
-        avcodec_get_frame_defaults(&s->picture[i].f);
+                      MAX_PICTURE_COUNT * sizeof(Picture), fail);
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        av_frame_unref(&s->picture[i].f);
     }
+    memset(&s->next_picture, 0, sizeof(s->next_picture));
+    memset(&s->last_picture, 0, sizeof(s->last_picture));
+    memset(&s->current_picture, 0, sizeof(s->current_picture));
+    av_frame_unref(&s->next_picture.f);
+    av_frame_unref(&s->last_picture.f);
+    av_frame_unref(&s->current_picture.f);
 
     if (s->width && s->height) {
         if (init_context_frame(s))
@@ -980,7 +1063,7 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
             }
 
             for (i = 0; i < nb_slices; i++) {
-                if (init_duplicate_context(s->thread_context[i], s) < 0)
+                if (init_duplicate_context(s->thread_context[i]) < 0)
                     goto fail;
                     s->thread_context[i]->start_mb_y =
                         (s->mb_height * (i) + nb_slices / 2) / nb_slices;
@@ -988,7 +1071,7 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
                         (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
             }
         } else {
-            if (init_duplicate_context(s, s) < 0)
+            if (init_duplicate_context(s) < 0)
                 goto fail;
             s->start_mb_y = 0;
             s->end_mb_y   = s->mb_height;
@@ -1045,8 +1128,8 @@ static int free_context_frame(MpegEncContext *s)
 
     av_freep(&s->mbskip_table);
 
-    av_freep(&s->error_status_table);
-    av_freep(&s->er_temp_buffer);
+    av_freep(&s->er.error_status_table);
+    av_freep(&s->er.er_temp_buffer);
     av_freep(&s->mb_index2xy);
     av_freep(&s->lambda_table);
     av_freep(&s->cplx_tab);
@@ -1054,9 +1137,6 @@ static int free_context_frame(MpegEncContext *s)
 
     s->linesize = s->uvlinesize = 0;
 
-    for (i = 0; i < 3; i++)
-        av_freep(&s->visualization_buffer[i]);
-
     return 0;
 }
 
@@ -1074,10 +1154,11 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s)
     } else
         free_duplicate_context(s);
 
-    free_context_frame(s);
+    if ((err = free_context_frame(s)) < 0)
+        return err;
 
     if (s->picture)
-        for (i = 0; i < s->picture_count; i++) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
                 s->picture[i].needs_realloc = 1;
         }
 
@@ -1088,7 +1169,7 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s)
     // init
     if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
         s->mb_height = (s->height + 31) / 32 * 2;
-    else if (s->codec_id != AV_CODEC_ID_H264)
+    else
         s->mb_height = (s->height + 15) / 16;
 
     if ((s->width || s->height) &&
@@ -1109,7 +1190,7 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s)
             }
 
             for (i = 0; i < nb_slices; i++) {
-                if (init_duplicate_context(s->thread_context[i], s) < 0)
+                if (init_duplicate_context(s->thread_context[i]) < 0)
                     goto fail;
                     s->thread_context[i]->start_mb_y =
                         (s->mb_height * (i) + nb_slices / 2) / nb_slices;
@@ -1117,7 +1198,7 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s)
                         (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
             }
         } else {
-            if (init_duplicate_context(s, s) < 0)
+            if (init_duplicate_context(s) < 0)
                 goto fail;
             s->start_mb_y = 0;
             s->end_mb_y   = s->mb_height;
@@ -1152,29 +1233,22 @@ void ff_MPV_common_end(MpegEncContext *s)
     av_freep(&s->bitstream_buffer);
     s->allocated_bitstream_buffer_size = 0;
 
-    av_freep(&s->avctx->stats_out);
-    av_freep(&s->ac_stats);
-
-    av_freep(&s->q_intra_matrix);
-    av_freep(&s->q_inter_matrix);
-    av_freep(&s->q_intra_matrix16);
-    av_freep(&s->q_inter_matrix16);
-    av_freep(&s->input_picture);
-    av_freep(&s->reordered_input_picture);
-    av_freep(&s->dct_offset);
-
-    if (s->picture && !s->avctx->internal->is_copy) {
-        for (i = 0; i < s->picture_count; i++) {
-            free_picture(s, &s->picture[i]);
+    if (s->picture) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            ff_free_picture_tables(&s->picture[i]);
+            ff_mpeg_unref_picture(s, &s->picture[i]);
         }
     }
     av_freep(&s->picture);
+    ff_free_picture_tables(&s->last_picture);
+    ff_mpeg_unref_picture(s, &s->last_picture);
+    ff_free_picture_tables(&s->current_picture);
+    ff_mpeg_unref_picture(s, &s->current_picture);
+    ff_free_picture_tables(&s->next_picture);
+    ff_mpeg_unref_picture(s, &s->next_picture);
 
     free_context_frame(s);
 
-    if (!(s->avctx->active_thread_type & FF_THREAD_FRAME))
-        avcodec_default_free_buffers(s->avctx);
-
     s->context_initialized      = 0;
     s->last_picture_ptr         =
     s->next_picture_ptr         =
@@ -1182,8 +1256,8 @@ void ff_MPV_common_end(MpegEncContext *s)
     s->linesize = s->uvlinesize = 0;
 }
 
-void ff_init_rl(RLTable *rl,
-                uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3])
+av_cold void ff_init_rl(RLTable *rl,
+                        uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3])
 {
     int8_t  max_level[MAX_RUN + 1], max_run[MAX_LEVEL + 1];
     uint8_t index_run[MAX_RUN + 1];
@@ -1234,7 +1308,7 @@ void ff_init_rl(RLTable *rl,
     }
 }
 
-void ff_init_vlc_rl(RLTable *rl)
+av_cold void ff_init_vlc_rl(RLTable *rl)
 {
     int i, q;
 
@@ -1274,28 +1348,23 @@ void ff_init_vlc_rl(RLTable *rl)
     }
 }
 
-void ff_release_unused_pictures(MpegEncContext*s, int remove_current)
+static void release_unused_pictures(MpegEncContext *s)
 {
     int i;
 
     /* release non reference frames */
-    for (i = 0; i < s->picture_count; i++) {
-        if (s->picture[i].f.data[0] && !s->picture[i].f.reference &&
-            (!s->picture[i].owner2 || s->picture[i].owner2 == s) &&
-            (remove_current || &s->picture[i] !=  s->current_picture_ptr)
-            /* && s->picture[i].type!= FF_BUFFER_TYPE_SHARED */) {
-            free_frame_buffer(s, &s->picture[i]);
-        }
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        if (!s->picture[i].reference)
+            ff_mpeg_unref_picture(s, &s->picture[i]);
     }
 }
 
 static inline int pic_is_unused(MpegEncContext *s, Picture *pic)
 {
-    if (pic->f.data[0] == NULL)
+    if (pic->f.buf[0] == NULL)
+        return 1;
+    if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF))
         return 1;
-    if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF))
-        if (!pic->owner2 || pic->owner2 == s)
-            return 1;
     return 0;
 }
 
@@ -1304,16 +1373,12 @@ static int find_unused_picture(MpegEncContext *s, int shared)
     int i;
 
     if (shared) {
-        for (i = s->picture_range_start; i < s->picture_range_end; i++) {
-            if (s->picture[i].f.data[0] == NULL && s->picture[i].f.type == 0)
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            if (s->picture[i].f.buf[0] == NULL)
                 return i;
         }
     } else {
-        for (i = s->picture_range_start; i < s->picture_range_end; i++) {
-            if (pic_is_unused(s, &s->picture[i]) && s->picture[i].f.type != 0)
-                return i; // FIXME
-        }
-        for (i = s->picture_range_start; i < s->picture_range_end; i++) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
             if (pic_is_unused(s, &s->picture[i]))
                 return i;
         }
@@ -1326,11 +1391,11 @@ int ff_find_unused_picture(MpegEncContext *s, int shared)
 {
     int ret = find_unused_picture(s, shared);
 
-    if (ret >= 0 && ret < s->picture_range_end) {
+    if (ret >= 0 && ret < MAX_PICTURE_COUNT) {
         if (s->picture[ret].needs_realloc) {
             s->picture[ret].needs_realloc = 0;
-            free_picture(s, &s->picture[ret]);
-            avcodec_get_frame_defaults(&s->picture[ret].f);
+            ff_free_picture_tables(&s->picture[ret]);
+            ff_mpeg_unref_picture(s, &s->picture[ret]);
         }
     }
     return ret;
@@ -1363,41 +1428,39 @@ static void update_noise_reduction(MpegEncContext *s)
  */
 int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
 {
-    int i;
+    int i, ret;
     Picture *pic;
     s->mb_skipped = 0;
 
     /* 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 &&
-            s->last_picture_ptr != s->next_picture_ptr &&
-            s->last_picture_ptr->f.data[0]) {
-            if (s->last_picture_ptr->owner2 == s)
-                free_frame_buffer(s, s->last_picture_ptr);
-        }
+    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
+        s->last_picture_ptr != s->next_picture_ptr &&
+        s->last_picture_ptr->f.buf[0]) {
+        ff_mpeg_unref_picture(s, s->last_picture_ptr);
+    }
 
-        /* release forgotten pictures */
-        /* if (mpeg124/h263) */
-        if (!s->encoding) {
-            for (i = 0; i < s->picture_count; i++) {
-                if (s->picture[i].owner2 == s && s->picture[i].f.data[0] &&
-                    &s->picture[i] != s->last_picture_ptr &&
-                    &s->picture[i] != s->next_picture_ptr &&
-                    s->picture[i].f.reference && !s->picture[i].needs_realloc) {
-                    if (!(avctx->active_thread_type & FF_THREAD_FRAME))
-                        av_log(avctx, AV_LOG_ERROR,
-                               "releasing zombie picture\n");
-                    free_frame_buffer(s, &s->picture[i]);
-                }
+    /* release forgotten pictures */
+    /* if (mpeg124/h263) */
+    if (!s->encoding) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            if (&s->picture[i] != s->last_picture_ptr &&
+                &s->picture[i] != s->next_picture_ptr &&
+                s->picture[i].reference && !s->picture[i].needs_realloc) {
+                if (!(avctx->active_thread_type & FF_THREAD_FRAME))
+                    av_log(avctx, AV_LOG_ERROR,
+                           "releasing zombie picture\n");
+                ff_mpeg_unref_picture(s, &s->picture[i]);
             }
         }
     }
 
+    ff_mpeg_unref_picture(s, &s->current_picture);
+
     if (!s->encoding) {
-        ff_release_unused_pictures(s, 1);
+        release_unused_pictures(s);
 
         if (s->current_picture_ptr &&
-            s->current_picture_ptr->f.data[0] == NULL) {
+            s->current_picture_ptr->f.buf[0] == NULL) {
             // we already have a unused image
             // (maybe it was set before reading the header)
             pic = s->current_picture_ptr;
@@ -1410,12 +1473,10 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
             pic = &s->picture[i];
         }
 
-        pic->f.reference = 0;
+        pic->reference = 0;
         if (!s->droppable) {
-            if (s->codec_id == AV_CODEC_ID_H264)
-                pic->f.reference = s->picture_structure;
-            else if (s->pict_type != AV_PICTURE_TYPE_B)
-                pic->f.reference = 3;
+            if (s->pict_type != AV_PICTURE_TYPE_B)
+                pic->reference = 3;
         }
 
         pic->f.coded_picture_number = s->coded_picture_number++;
@@ -1442,7 +1503,9 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     //     s->current_picture_ptr->quality = s->new_picture_ptr->quality;
     s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
-    ff_copy_picture(&s->current_picture, s->current_picture_ptr);
+    if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,
+                                   s->current_picture_ptr)) < 0)
+        return ret;
 
     if (s->pict_type != AV_PICTURE_TYPE_B) {
         s->last_picture_ptr = s->next_picture_ptr;
@@ -1456,69 +1519,85 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
             s->current_picture_ptr ? s->current_picture_ptr->f.data[0] : NULL,
             s->pict_type, s->droppable);
 
-    if (s->codec_id != AV_CODEC_ID_H264) {
-        if ((s->last_picture_ptr == NULL ||
-             s->last_picture_ptr->f.data[0] == NULL) &&
-            (s->pict_type != AV_PICTURE_TYPE_I ||
-             s->picture_structure != PICT_FRAME)) {
-            if (s->pict_type != AV_PICTURE_TYPE_I)
-                av_log(avctx, AV_LOG_ERROR,
-                       "warning: first frame is no keyframe\n");
-            else if (s->picture_structure != PICT_FRAME)
-                av_log(avctx, AV_LOG_INFO,
-                       "allocate dummy last picture for field based first keyframe\n");
-
-            /* Allocate a dummy frame */
-            i = ff_find_unused_picture(s, 0);
-            if (i < 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
-                return i;
-            }
-            s->last_picture_ptr = &s->picture[i];
-            if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) {
-                s->last_picture_ptr = NULL;
-                return -1;
-            }
-            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;
+    if ((s->last_picture_ptr == NULL ||
+         s->last_picture_ptr->f.buf[0] == NULL) &&
+        (s->pict_type != AV_PICTURE_TYPE_I ||
+         s->picture_structure != PICT_FRAME)) {
+        int h_chroma_shift, v_chroma_shift;
+        av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
+                                         &h_chroma_shift, &v_chroma_shift);
+        if (s->pict_type != AV_PICTURE_TYPE_I)
+            av_log(avctx, AV_LOG_ERROR,
+                   "warning: first frame is no keyframe\n");
+        else if (s->picture_structure != PICT_FRAME)
+            av_log(avctx, AV_LOG_INFO,
+                   "allocate dummy last picture for field based first keyframe\n");
+
+        /* Allocate a dummy frame */
+        i = ff_find_unused_picture(s, 0);
+        if (i < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
+            return i;
         }
-        if ((s->next_picture_ptr == NULL ||
-             s->next_picture_ptr->f.data[0] == NULL) &&
-            s->pict_type == AV_PICTURE_TYPE_B) {
-            /* Allocate a dummy frame */
-            i = ff_find_unused_picture(s, 0);
-            if (i < 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
-                return i;
-            }
-            s->next_picture_ptr = &s->picture[i];
-            if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) {
-                s->next_picture_ptr = NULL;
-                return -1;
-            }
-            ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 0);
-            ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 1);
-            s->next_picture_ptr->f.reference = 3;
+        s->last_picture_ptr = &s->picture[i];
+        if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) {
+            s->last_picture_ptr = NULL;
+            return -1;
         }
-    }
 
-    if (s->last_picture_ptr)
-        ff_copy_picture(&s->last_picture, s->last_picture_ptr);
-    if (s->next_picture_ptr)
-        ff_copy_picture(&s->next_picture, s->next_picture_ptr);
+        memset(s->last_picture_ptr->f.data[0], 0,
+               avctx->height * s->last_picture_ptr->f.linesize[0]);
+        memset(s->last_picture_ptr->f.data[1], 0x80,
+               (avctx->height >> v_chroma_shift) *
+               s->last_picture_ptr->f.linesize[1]);
+        memset(s->last_picture_ptr->f.data[2], 0x80,
+               (avctx->height >> v_chroma_shift) *
+               s->last_picture_ptr->f.linesize[2]);
+
+        ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0);
+        ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1);
+    }
+    if ((s->next_picture_ptr == NULL ||
+         s->next_picture_ptr->f.buf[0] == NULL) &&
+        s->pict_type == AV_PICTURE_TYPE_B) {
+        /* Allocate a dummy frame */
+        i = ff_find_unused_picture(s, 0);
+        if (i < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n");
+            return i;
+        }
+        s->next_picture_ptr = &s->picture[i];
+        if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) {
+            s->next_picture_ptr = NULL;
+            return -1;
+        }
+        ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0);
+        ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1);
+    }
 
-    if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME)) {
-        if (s->next_picture_ptr)
-            s->next_picture_ptr->owner2 = s;
-        if (s->last_picture_ptr)
-            s->last_picture_ptr->owner2 = s;
+    if (s->last_picture_ptr) {
+        ff_mpeg_unref_picture(s, &s->last_picture);
+        if (s->last_picture_ptr->f.buf[0] &&
+            (ret = ff_mpeg_ref_picture(s, &s->last_picture,
+                                       s->last_picture_ptr)) < 0)
+            return ret;
+    }
+    if (s->next_picture_ptr) {
+        ff_mpeg_unref_picture(s, &s->next_picture);
+        if (s->next_picture_ptr->f.buf[0] &&
+            (ret = ff_mpeg_ref_picture(s, &s->next_picture,
+                                       s->next_picture_ptr)) < 0)
+            return ret;
     }
 
-    assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
-                                                 s->last_picture_ptr->f.data[0]));
+    if (s->pict_type != AV_PICTURE_TYPE_I &&
+        !(s->last_picture_ptr && s->last_picture_ptr->f.buf[0])) {
+        av_log(s, AV_LOG_ERROR,
+               "Non-reference picture received and no reference available\n");
+        return AVERROR_INVALIDDATA;
+    }
 
-    if (s->picture_structure!= PICT_FRAME && s->out_format != FMT_H264) {
+    if (s->picture_structure!= PICT_FRAME) {
         int i;
         for (i = 0; i < 4; i++) {
             if (s->picture_structure == PICT_BOTTOM_FIELD) {
@@ -1552,180 +1631,66 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
         update_noise_reduction(s);
     }
 
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
     if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
         return ff_xvmc_field_start(s, avctx);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
 
     return 0;
 }
 
-/* generic function for encode/decode called after a
- * frame has been coded/decoded. */
+/* called after a frame has been decoded. */
 void ff_MPV_frame_end(MpegEncContext *s)
 {
-    int i;
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
     /* redraw edges for the frame if decoding didn't complete */
     // just to make sure that all data is rendered.
     if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) {
         ff_xvmc_field_end(s);
-   } else if ((s->error_count || s->encoding) &&
-              !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);
+    } else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+    if (s->er.error_count  &&
+        !s->avctx->hwaccel &&
+        s->unrestricted_mv &&
+        s->current_picture.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);
     }
 
     emms_c();
 
-    s->last_pict_type                 = s->pict_type;
-    s->last_lambda_for [s->pict_type] = s->current_picture_ptr->f.quality;
-    if (s->pict_type!= AV_PICTURE_TYPE_B) {
-        s->last_non_b_pict_type = s->pict_type;
-    }
-#if 0
-    /* copy back current_picture variables */
-    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
-        if (s->picture[i].f.data[0] == s->current_picture.f.data[0]) {
-            s->picture[i] = s->current_picture;
-            break;
-        }
-    }
-    assert(i < MAX_PICTURE_COUNT);
-#endif
-
-    if (s->encoding) {
-        /* release non-reference frames */
-        for (i = 0; i < s->picture_count; i++) {
-            if (s->picture[i].f.data[0] && !s->picture[i].f.reference
-                /* && s->picture[i].type != FF_BUFFER_TYPE_SHARED */) {
-                free_frame_buffer(s, &s->picture[i]);
-            }
-        }
-    }
-    // clear copies, to avoid confusion
-#if 0
-    memset(&s->last_picture,    0, sizeof(Picture));
-    memset(&s->next_picture,    0, sizeof(Picture));
-    memset(&s->current_picture, 0, sizeof(Picture));
-#endif
-    s->avctx->coded_frame = &s->current_picture_ptr->f;
-
-    if (s->codec_id != AV_CODEC_ID_H264 && s->current_picture.f.reference) {
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
-    }
-}
-
-/**
- * Draw a line from (ex, ey) -> (sx, sy).
- * @param w width of the image
- * @param h height of the image
- * @param stride stride/linesize of the image
- * @param color color of the arrow
- */
-static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey,
-                      int w, int h, int stride, int color)
-{
-    int x, y, fr, f;
-
-    sx = av_clip(sx, 0, w - 1);
-    sy = av_clip(sy, 0, h - 1);
-    ex = av_clip(ex, 0, w - 1);
-    ey = av_clip(ey, 0, h - 1);
-
-    buf[sy * stride + sx] += color;
-
-    if (FFABS(ex - sx) > FFABS(ey - sy)) {
-        if (sx > ex) {
-            FFSWAP(int, sx, ex);
-            FFSWAP(int, sy, ey);
-        }
-        buf += sx + sy * stride;
-        ex  -= sx;
-        f    = ((ey - sy) << 16) / ex;
-        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;
-        }
-    } else {
-        if (sy > ey) {
-            FFSWAP(int, sx, ex);
-            FFSWAP(int, sy, ey);
-        }
-        buf += sx + sy * stride;
-        ey  -= sy;
-        if (ey)
-            f  = ((ex - sx) << 16) / ey;
-        else
-            f = 0;
-        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;
-        }
-    }
-}
-
-/**
- * Draw an arrow from (ex, ey) -> (sx, sy).
- * @param w width of the image
- * @param h height of the image
- * @param stride stride/linesize of the image
- * @param color color of the arrow
- */
-static void draw_arrow(uint8_t *buf, int sx, int sy, int ex,
-                       int ey, int w, int h, int stride, int color)
-{
-    int dx,dy;
-
-    sx = av_clip(sx, -100, w + 100);
-    sy = av_clip(sy, -100, h + 100);
-    ex = av_clip(ex, -100, w + 100);
-    ey = av_clip(ey, -100, h + 100);
-
-    dx = ex - sx;
-    dy = ey - sy;
-
-    if (dx * dx + dy * dy > 3 * 3) {
-        int rx =  dx + dy;
-        int ry = -dx + dy;
-        int length = ff_sqrt((rx * rx + ry * ry) << 8);
-
-        // FIXME subpixel accuracy
-        rx = ROUNDED_DIV(rx * 3 << 4, length);
-        ry = ROUNDED_DIV(ry * 3 << 4, length);
-
-        draw_line(buf, sx, sy, sx + rx, sy + ry, w, h, stride, color);
-        draw_line(buf, sx, sy, sx - ry, sy + rx, w, h, stride, color);
-    }
-    draw_line(buf, sx, sy, ex, ey, w, h, stride, color);
+    if (s->current_picture.reference)
+        ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
 }
 
 /**
  * Print debugging info for the given picture.
  */
-void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
+void ff_print_debug_info(MpegEncContext *s, Picture *p)
 {
-    if (s->avctx->hwaccel || !pict || !pict->mb_type)
+    AVFrame *pict;
+    if (s->avctx->hwaccel || !p || !p->mb_type)
         return;
+    pict = &p->f;
 
     if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) {
         int x,y;
@@ -1761,10 +1726,10 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
                 }
                 if (s->avctx->debug & FF_DEBUG_QP) {
                     av_log(s->avctx, AV_LOG_DEBUG, "%2d",
-                           pict->qscale_table[x + y * s->mb_stride]);
+                           p->qscale_table[x + y * s->mb_stride]);
                 }
                 if (s->avctx->debug & FF_DEBUG_MB_TYPE) {
-                    int mb_type = pict->mb_type[x + y * s->mb_stride];
+                    int mb_type = p->mb_type[x + y * s->mb_stride];
                     // Type & MV direction
                     if (IS_PCM(mb_type))
                         av_log(s->avctx, AV_LOG_DEBUG, "P");
@@ -1815,215 +1780,6 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
             av_log(s->avctx, AV_LOG_DEBUG, "\n");
         }
     }
-
-    if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
-        (s->avctx->debug_mv)) {
-        const int shift = 1 + s->quarter_sample;
-        int mb_y;
-        uint8_t *ptr;
-        int i;
-        int h_chroma_shift, v_chroma_shift, block_height;
-        const int width          = s->avctx->width;
-        const int height         = s->avctx->height;
-        const int mv_sample_log2 = 4 - pict->motion_subsample_log2;
-        const int mv_stride      = (s->mb_width << mv_sample_log2) +
-                                   (s->codec_id == AV_CODEC_ID_H264 ? 0 : 1);
-        s->low_delay = 0; // needed to see the vectors without trashing the buffers
-
-        av_pix_fmt_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);
-            pict->data[i] = s->visualization_buffer[i];
-        }
-        pict->type   = FF_BUFFER_TYPE_COPY;
-        ptr          = pict->data[0];
-        block_height = 16 >> v_chroma_shift;
-
-        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-            int mb_x;
-            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
-                const int mb_index = mb_x + mb_y * s->mb_stride;
-                if ((s->avctx->debug_mv) && pict->motion_val) {
-                    int type;
-                    for (type = 0; type < 3; type++) {
-                        int direction = 0;
-                        switch (type) {
-                        case 0:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_P_FOR)) ||
-                                (pict->pict_type!= AV_PICTURE_TYPE_P))
-                                continue;
-                            direction = 0;
-                            break;
-                        case 1:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_FOR)) ||
-                                (pict->pict_type!= AV_PICTURE_TYPE_B))
-                                continue;
-                            direction = 0;
-                            break;
-                        case 2:
-                            if ((!(s->avctx->debug_mv & FF_DEBUG_VIS_MV_B_BACK)) ||
-                                (pict->pict_type!= AV_PICTURE_TYPE_B))
-                                continue;
-                            direction = 1;
-                            break;
-                        }
-                        if (!USES_LIST(pict->mb_type[mb_index], direction))
-                            continue;
-
-                        if (IS_8X8(pict->mb_type[mb_index])) {
-                            int i;
-                            for (i = 0; i < 4; i++) {
-                                int sx = mb_x * 16 + 4 + 8 * (i & 1);
-                                int sy = mb_y * 16 + 4 + 8 * (i >> 1);
-                                int xy = (mb_x * 2 + (i & 1) +
-                                          (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);
-                                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);
-                            }
-                        } else if (IS_16X8(pict->mb_type[mb_index])) {
-                            int i;
-                            for (i = 0; i < 2; i++) {
-                                int sx = mb_x * 16 + 8;
-                                int sy = mb_y * 16 + 4 + 8 * i;
-                                int xy = (mb_x * 2 + (mb_y * 2 + i) * mv_stride) << (mv_sample_log2 - 1);
-                                int mx = (pict->motion_val[direction][xy][0] >> shift);
-                                int my = (pict->motion_val[direction][xy][1] >> shift);
-
-                                if (IS_INTERLACED(pict->mb_type[mb_index]))
-                                    my *= 2;
-
-                            draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
-                                       height, s->linesize, 100);
-                            }
-                        } else if (IS_8X16(pict->mb_type[mb_index])) {
-                            int i;
-                            for (i = 0; i < 2; i++) {
-                                int sx = mb_x * 16 + 4 + 8 * i;
-                                int sy = mb_y * 16 + 8;
-                                int xy = (mb_x * 2 + i + mb_y * 2 * mv_stride) << (mv_sample_log2 - 1);
-                                int mx = pict->motion_val[direction][xy][0] >> shift;
-                                int my = pict->motion_val[direction][xy][1] >> shift;
-
-                                if (IS_INTERLACED(pict->mb_type[mb_index]))
-                                    my *= 2;
-
-                                draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
-                                           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;
-                              draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
-                        }
-                    }
-                }
-                if ((s->avctx->debug & FF_DEBUG_VIS_QP) && pict->motion_val) {
-                    uint64_t c = (pict->qscale_table[mb_index] * 128 / 31) *
-                                 0x0101010101010101ULL;
-                    int y;
-                    for (y = 0; y < block_height; y++) {
-                        *(uint64_t *)(pict->data[1] + 8 * mb_x +
-                                      (block_height * mb_y + y) *
-                                      pict->linesize[1]) = c;
-                        *(uint64_t *)(pict->data[2] + 8 * mb_x +
-                                      (block_height * mb_y + y) *
-                                      pict->linesize[2]) = c;
-                    }
-                }
-                if ((s->avctx->debug & FF_DEBUG_VIS_MB_TYPE) &&
-                    pict->motion_val) {
-                    int mb_type = pict->mb_type[mb_index];
-                    uint64_t u,v;
-                    int y;
-#define COLOR(theta, r) \
-    u = (int)(128 + r * cos(theta * 3.141592 / 180)); \
-    v = (int)(128 + r * sin(theta * 3.141592 / 180));
-
-
-                    u = v = 128;
-                    if (IS_PCM(mb_type)) {
-                        COLOR(120, 48)
-                    } else if ((IS_INTRA(mb_type) && IS_ACPRED(mb_type)) ||
-                               IS_INTRA16x16(mb_type)) {
-                        COLOR(30, 48)
-                    } else if (IS_INTRA4x4(mb_type)) {
-                        COLOR(90, 48)
-                    } else if (IS_DIRECT(mb_type) && IS_SKIP(mb_type)) {
-                        // COLOR(120, 48)
-                    } else if (IS_DIRECT(mb_type)) {
-                        COLOR(150, 48)
-                    } else if (IS_GMC(mb_type) && IS_SKIP(mb_type)) {
-                        COLOR(170, 48)
-                    } else if (IS_GMC(mb_type)) {
-                        COLOR(190, 48)
-                    } else if (IS_SKIP(mb_type)) {
-                        // COLOR(180, 48)
-                    } else if (!USES_LIST(mb_type, 1)) {
-                        COLOR(240, 48)
-                    } else if (!USES_LIST(mb_type, 0)) {
-                        COLOR(0, 48)
-                    } else {
-                        assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
-                        COLOR(300,48)
-                    }
-
-                    u *= 0x0101010101010101ULL;
-                    v *= 0x0101010101010101ULL;
-                    for (y = 0; y < block_height; y++) {
-                        *(uint64_t *)(pict->data[1] + 8 * mb_x +
-                                      (block_height * mb_y + y) * pict->linesize[1]) = u;
-                        *(uint64_t *)(pict->data[2] + 8 * mb_x +
-                                      (block_height * mb_y + y) * pict->linesize[2]) = v;
-                    }
-
-                    // segmentation
-                    if (IS_8X8(mb_type) || IS_16X8(mb_type)) {
-                        *(uint64_t *)(pict->data[0] + 16 * mb_x + 0 +
-                                      (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL;
-                        *(uint64_t *)(pict->data[0] + 16 * mb_x + 8 +
-                                      (16 * mb_y + 8) * pict->linesize[0]) ^= 0x8080808080808080ULL;
-                    }
-                    if (IS_8X8(mb_type) || IS_8X16(mb_type)) {
-                        for (y = 0; y < 16; y++)
-                            pict->data[0][16 * mb_x + 8 + (16 * mb_y + y) *
-                                          pict->linesize[0]] ^= 0x80;
-                    }
-                    if (IS_8X8(mb_type) && mv_sample_log2 >= 2) {
-                        int dm = 1 << (mv_sample_log2 - 2);
-                        for (i = 0; i < 4; i++) {
-                            int sx = mb_x * 16 + 8 * (i & 1);
-                            int sy = mb_y * 16 + 8 * (i >> 1);
-                            int xy = (mb_x * 2 + (i & 1) +
-                                     (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);
-                            // FIXME bidir
-                            int32_t *mv = (int32_t *) &pict->motion_val[0][xy];
-                            if (mv[0] != mv[dm] ||
-                                mv[dm * mv_stride] != mv[dm * (mv_stride + 1)])
-                                for (y = 0; y < 8; y++)
-                                    pict->data[0][sx + 4 + (sy + y) * pict->linesize[0]] ^= 0x80;
-                            if (mv[0] != mv[dm * mv_stride] || mv[dm] != mv[dm * (mv_stride + 1)])
-                                *(uint64_t *)(pict->data[0] + sx + (sy + 4) *
-                                              pict->linesize[0]) ^= 0x8080808080808080ULL;
-                        }
-                    }
-
-                    if (IS_INTERLACED(mb_type) &&
-                        s->codec_id == AV_CODEC_ID_H264) {
-                        // hmm
-                    }
-                }
-                s->mbskip_table[mb_index] = 0;
-            }
-        }
-    }
 }
 
 /**
@@ -2066,7 +1822,7 @@ unhandled:
 
 /* put block[] to dest[] */
 static inline void put_dct(MpegEncContext *s,
-                           DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale)
+                           int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
 {
     s->dct_unquantize_intra(s, block, i, qscale);
     s->dsp.idct_put (dest, line_size, block);
@@ -2074,7 +1830,7 @@ static inline void put_dct(MpegEncContext *s,
 
 /* add block[] to dest[] */
 static inline void add_dct(MpegEncContext *s,
-                           DCTELEM *block, int i, uint8_t *dest, int line_size)
+                           int16_t *block, int i, uint8_t *dest, int line_size)
 {
     if (s->block_last_index[i] >= 0) {
         s->dsp.idct_add (dest, line_size, block);
@@ -2082,7 +1838,7 @@ static inline void add_dct(MpegEncContext *s,
 }
 
 static inline void add_dequant_dct(MpegEncContext *s,
-                           DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale)
+                           int16_t *block, int i, uint8_t *dest, int line_size, int qscale)
 {
     if (s->block_last_index[i] >= 0) {
         s->dct_unquantize_inter(s, block, i, qscale);
@@ -2135,30 +1891,33 @@ void ff_clean_intra_table_entries(MpegEncContext *s)
    s->interlaced_dct : true if interlaced dct used (mpeg2)
  */
 static av_always_inline
-void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
+void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
                             int is_mpeg12)
 {
     const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
+
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
         ff_xvmc_decode_mb(s);//xvmc uses pblocks
         return;
     }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
 
     if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
-       /* save DCT coefficients */
+       /* print DCT coefficients */
        int i,j;
-       DCTELEM *dct = &s->current_picture.f.dct_coeff[mb_xy * 64 * 6];
        av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y);
        for(i=0; i<6; i++){
            for(j=0; j<64; j++){
-               *dct++ = block[i][s->dsp.idct_permutation[j]];
-               av_log(s->avctx, AV_LOG_DEBUG, "%5d", dct[-1]);
+               av_log(s->avctx, AV_LOG_DEBUG, "%5d", block[i][s->dsp.idct_permutation[j]]);
            }
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
        }
     }
 
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    s->current_picture.qscale_table[mb_xy] = s->qscale;
 
     /* update DC predictors for P macroblocks */
     if (!s->mb_intra) {
@@ -2193,7 +1952,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
                 s->mb_skipped= 0;
                 assert(s->pict_type!=AV_PICTURE_TYPE_I);
                 *mbskip_ptr = 1;
-            } else if(!s->current_picture.f.reference) {
+            } else if(!s->current_picture.reference) {
                 *mbskip_ptr = 1;
             } else{
                 *mbskip_ptr = 0; /* not skipped */
@@ -2220,12 +1979,12 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
 
                 if(HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) {
                     if (s->mv_dir & MV_DIR_FORWARD) {
-                        ff_thread_await_progress(&s->last_picture_ptr->f,
+                        ff_thread_await_progress(&s->last_picture_ptr->tf,
                                                  ff_MPV_lowest_referenced_row(s, 0),
                                                  0);
                     }
                     if (s->mv_dir & MV_DIR_BACKWARD) {
-                        ff_thread_await_progress(&s->next_picture_ptr->f,
+                        ff_thread_await_progress(&s->next_picture_ptr->tf,
                                                  ff_MPV_lowest_referenced_row(s, 1),
                                                  0);
                     }
@@ -2233,13 +1992,13 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
 
                 op_qpix= s->me.qpel_put;
                 if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
-                    op_pix = s->dsp.put_pixels_tab;
+                    op_pix = s->hdsp.put_pixels_tab;
                 }else{
-                    op_pix = s->dsp.put_no_rnd_pixels_tab;
+                    op_pix = s->hdsp.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_pix = s->hdsp.avg_pixels_tab;
                     op_qpix= s->me.qpel_avg;
                 }
                 if (s->mv_dir & MV_DIR_BACKWARD) {
@@ -2359,14 +2118,14 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
         }
 skip_idct:
         if(!readable){
-            s->dsp.put_pixels_tab[0][0](s->dest[0], dest_y ,   linesize,16);
-            s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift);
-            s->dsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[2], dest_cr, uvlinesize,16 >> s->chroma_y_shift);
+            s->hdsp.put_pixels_tab[0][0](s->dest[0], dest_y ,   linesize,16);
+            s->hdsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[1], dest_cb, uvlinesize,16 >> s->chroma_y_shift);
+            s->hdsp.put_pixels_tab[s->chroma_x_shift][0](s->dest[2], dest_cr, uvlinesize,16 >> s->chroma_y_shift);
         }
     }
 }
 
-void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){
+void ff_MPV_decode_mb(MpegEncContext *s, int16_t block[12][64]){
 #if !CONFIG_SMALL
     if(s->out_format == FMT_MPEG1) {
         MPV_decode_mb_internal(s, block, 1);
@@ -2378,73 +2137,89 @@ void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){
 /**
  * @param h is the normal height, this will be reduced automatically if needed for the last row
  */
-void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
-    const int field_pic= s->picture_structure != PICT_FRAME;
+void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
+                        Picture *last, int y, int h, int picture_structure,
+                        int first_field, int draw_edges, int low_delay,
+                        int v_edge_pos, int h_edge_pos)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    int hshift = desc->log2_chroma_w;
+    int vshift = desc->log2_chroma_h;
+    const int field_pic = picture_structure != PICT_FRAME;
     if(field_pic){
         h <<= 1;
         y <<= 1;
     }
 
-    if (!s->avctx->hwaccel
-       && !(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-       && s->unrestricted_mv
-       && s->current_picture.f.reference
-       && !s->intra_only
-       && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
-        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+    if (!avctx->hwaccel &&
+        draw_edges &&
+        cur->reference &&
+        !(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
+        int *linesize = cur->f.linesize;
         int sides = 0, edge_h;
-        int hshift = desc->log2_chroma_w;
-        int vshift = desc->log2_chroma_h;
         if (y==0) sides |= EDGE_TOP;
-        if (y + h >= s->v_edge_pos) sides |= EDGE_BOTTOM;
+        if (y + h >= v_edge_pos)
+            sides |= EDGE_BOTTOM;
 
-        edge_h= FFMIN(h, s->v_edge_pos - y);
+        edge_h= FFMIN(h, v_edge_pos - y);
 
-        s->dsp.draw_edges(s->current_picture_ptr->f.data[0] +  y         *s->linesize,
-                          s->linesize,           s->h_edge_pos,         edge_h,
-                          EDGE_WIDTH,            EDGE_WIDTH,            sides);
-        s->dsp.draw_edges(s->current_picture_ptr->f.data[1] + (y>>vshift)*s->uvlinesize,
-                          s->uvlinesize,         s->h_edge_pos>>hshift, edge_h>>vshift,
-                          EDGE_WIDTH>>hshift,    EDGE_WIDTH>>vshift,    sides);
-        s->dsp.draw_edges(s->current_picture_ptr->f.data[2] + (y>>vshift)*s->uvlinesize,
-                          s->uvlinesize,         s->h_edge_pos>>hshift, edge_h>>vshift,
-                          EDGE_WIDTH>>hshift,    EDGE_WIDTH>>vshift,    sides);
+        dsp->draw_edges(cur->f.data[0] + y * linesize[0],
+                        linesize[0], h_edge_pos, edge_h,
+                        EDGE_WIDTH, EDGE_WIDTH, sides);
+        dsp->draw_edges(cur->f.data[1] + (y >> vshift) * linesize[1],
+                        linesize[1], h_edge_pos >> hshift, edge_h >> vshift,
+                        EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, sides);
+        dsp->draw_edges(cur->f.data[2] + (y >> vshift) * linesize[2],
+                        linesize[2], h_edge_pos >> hshift, edge_h >> vshift,
+                        EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift, sides);
     }
 
-    h= FFMIN(h, s->avctx->height - y);
+    h = FFMIN(h, avctx->height - y);
 
-    if(field_pic && s->first_field && !(s->avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)) return;
+    if(field_pic && first_field && !(avctx->slice_flags&SLICE_FLAG_ALLOW_FIELD)) return;
 
-    if (s->avctx->draw_horiz_band) {
+    if (avctx->draw_horiz_band) {
         AVFrame *src;
         int offset[AV_NUM_DATA_POINTERS];
         int i;
 
-        if(s->pict_type==AV_PICTURE_TYPE_B || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER))
-            src = &s->current_picture_ptr->f;
-        else if(s->last_picture_ptr)
-            src = &s->last_picture_ptr->f;
+        if(cur->f.pict_type == AV_PICTURE_TYPE_B || low_delay ||
+           (avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
+            src = &cur->f;
+        else if (last)
+            src = &last->f;
         else
             return;
 
-        if(s->pict_type==AV_PICTURE_TYPE_B && s->picture_structure == PICT_FRAME && s->out_format != FMT_H264){
+        if (cur->f.pict_type == AV_PICTURE_TYPE_B &&
+            picture_structure == PICT_FRAME &&
+            avctx->codec_id != AV_CODEC_ID_SVQ3) {
             for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
                 offset[i] = 0;
         }else{
-            offset[0]= y * s->linesize;
+            offset[0]= y * src->linesize[0];
             offset[1]=
-            offset[2]= (y >> s->chroma_y_shift) * s->uvlinesize;
+            offset[2]= (y >> vshift) * src->linesize[1];
             for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
                 offset[i] = 0;
         }
 
         emms_c();
 
-        s->avctx->draw_horiz_band(s->avctx, src, offset,
-                                  y, s->picture_structure, h);
+        avctx->draw_horiz_band(avctx, src, offset,
+                               y, picture_structure, h);
     }
 }
 
+void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
+{
+    int draw_edges = s->unrestricted_mv && !s->intra_only;
+    ff_draw_horiz_band(s->avctx, &s->dsp, &s->current_picture,
+                       &s->last_picture, y, h, s->picture_structure,
+                       s->first_field, draw_edges, s->low_delay,
+                       s->v_edge_pos, s->h_edge_pos);
+}
+
 void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
     const int linesize   = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics
     const int uvlinesize = s->current_picture.f.linesize[1];
@@ -2477,6 +2252,35 @@ void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename
     }
 }
 
+/**
+ * Permute an 8x8 block.
+ * @param block the block which will be permuted according to the given permutation vector
+ * @param permutation the permutation vector
+ * @param last the last non zero coefficient in scantable order, used to speed the permutation up
+ * @param scantable the used scantable, this is only used to speed the permutation up, the block is not
+ *                  (inverse) permutated to scantable order!
+ */
+void ff_block_permute(int16_t *block, uint8_t *permutation, const uint8_t *scantable, int last)
+{
+    int i;
+    int16_t temp[64];
+
+    if(last<=0) return;
+    //if(permutation[1]==1) return; //FIXME it is ok but not clean and might fail for some permutations
+
+    for(i=0; i<=last; i++){
+        const int j= scantable[i];
+        temp[j]= block[j];
+        block[j]=0;
+    }
+
+    for(i=0; i<=last; i++){
+        const int j= scantable[i];
+        const int perm_j= permutation[j];
+        block[perm_j]= temp[j];
+    }
+}
+
 void ff_mpeg_flush(AVCodecContext *avctx){
     int i;
     MpegEncContext *s = avctx->priv_data;
@@ -2484,14 +2288,14 @@ void ff_mpeg_flush(AVCodecContext *avctx){
     if(s==NULL || s->picture==NULL)
         return;
 
-    for(i=0; i<s->picture_count; i++){
-       if (s->picture[i].f.data[0] &&
-           (s->picture[i].f.type == FF_BUFFER_TYPE_INTERNAL ||
-            s->picture[i].f.type == FF_BUFFER_TYPE_USER))
-        free_frame_buffer(s, &s->picture[i]);
-    }
+    for (i = 0; i < MAX_PICTURE_COUNT; i++)
+        ff_mpeg_unref_picture(s, &s->picture[i]);
     s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL;
 
+    ff_mpeg_unref_picture(s, &s->current_picture);
+    ff_mpeg_unref_picture(s, &s->last_picture);
+    ff_mpeg_unref_picture(s, &s->next_picture);
+
     s->mb_x= s->mb_y= 0;
 
     s->parse_context.state= -1;
@@ -2505,7 +2309,7 @@ void ff_mpeg_flush(AVCodecContext *avctx){
 }
 
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2537,7 +2341,7 @@ static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
 }
 
 static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2566,7 +2370,7 @@ static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,
 }
 
 static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2596,7 +2400,7 @@ static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
 }
 
 static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2629,7 +2433,7 @@ static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
 }
 
 static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
-                                   DCTELEM *block, int n, int qscale)
+                                   int16_t *block, int n, int qscale)
 {
     int i, level, nCoeffs;
     const uint16_t *quant_matrix;
@@ -2660,7 +2464,7 @@ static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
 }
 
 static void dct_unquantize_h263_intra_c(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     int i, level, qmul, qadd;
     int nCoeffs;
@@ -2697,7 +2501,7 @@ static void dct_unquantize_h263_intra_c(MpegEncContext *s,
 }
 
 static void dct_unquantize_h263_inter_c(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     int i, level, qmul, qadd;
     int nCoeffs;
@@ -2741,6 +2545,24 @@ void ff_set_qscale(MpegEncContext * s, int qscale)
 
 void ff_MPV_report_decode_progress(MpegEncContext *s)
 {
-    if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->error_occurred)
-        ff_thread_report_progress(&s->current_picture_ptr->f, s->mb_y, 0);
+    if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->er.error_occurred)
+        ff_thread_report_progress(&s->current_picture_ptr->tf, s->mb_y, 0);
+}
+
+#if CONFIG_ERROR_RESILIENCE
+void ff_mpeg_er_frame_start(MpegEncContext *s)
+{
+    ERContext *er = &s->er;
+
+    er->cur_pic  = s->current_picture_ptr;
+    er->last_pic = s->last_picture_ptr;
+    er->next_pic = s->next_picture_ptr;
+
+    er->pp_time           = s->pp_time;
+    er->pb_time           = s->pb_time;
+    er->quarter_sample    = s->quarter_sample;
+    er->partitioned_frame = s->partitioned_frame;
+
+    ff_er_frame_start(er);
 }
+#endif /* CONFIG_ERROR_RESILIENCE */
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 38d9ab6..8a43fdc 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -30,12 +30,16 @@
 
 #include "avcodec.h"
 #include "dsputil.h"
+#include "error_resilience.h"
 #include "get_bits.h"
+#include "h263dsp.h"
+#include "hpeldsp.h"
 #include "put_bits.h"
 #include "ratecontrol.h"
 #include "parser.h"
 #include "mpeg12data.h"
 #include "rl.h"
+#include "thread.h"
 #include "videodsp.h"
 
 #include "libavutil/opt.h"
@@ -47,7 +51,6 @@ enum OutputFormat {
     FMT_H261,
     FMT_H263,
     FMT_MJPEG,
-    FMT_H264,
 };
 
 #define MPEG_BUF_SIZE (16 * 1024)
@@ -62,6 +65,8 @@ enum OutputFormat {
 
 #define MAX_PICTURE_COUNT 32
 
+#define MAX_B_FRAMES 16
+
 #define ME_MAP_SIZE 64
 #define ME_MAP_SHIFT 3
 #define ME_MAP_MV_BITS 11
@@ -93,14 +98,62 @@ struct MpegEncContext;
  */
 typedef struct Picture{
     struct AVFrame f;
+    ThreadFrame tf;
+
+    AVBufferRef *qscale_table_buf;
+    int8_t *qscale_table;
+
+    AVBufferRef *motion_val_buf[2];
+    int16_t (*motion_val[2])[2];
+
+    AVBufferRef *mb_type_buf;
+    uint32_t *mb_type;
+
+#if !FF_API_MB_TYPE
+#define MB_TYPE_INTRA4x4   0x0001
+#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
+#define MB_TYPE_INTRA_PCM  0x0004 //FIXME H.264-specific
+#define MB_TYPE_16x16      0x0008
+#define MB_TYPE_16x8       0x0010
+#define MB_TYPE_8x16       0x0020
+#define MB_TYPE_8x8        0x0040
+#define MB_TYPE_INTERLACED 0x0080
+#define MB_TYPE_DIRECT2    0x0100 //FIXME
+#define MB_TYPE_ACPRED     0x0200
+#define MB_TYPE_GMC        0x0400
+#define MB_TYPE_SKIP       0x0800
+#define MB_TYPE_P0L0       0x1000
+#define MB_TYPE_P1L0       0x2000
+#define MB_TYPE_P0L1       0x4000
+#define MB_TYPE_P1L1       0x8000
+#define MB_TYPE_L0         (MB_TYPE_P0L0 | MB_TYPE_P1L0)
+#define MB_TYPE_L1         (MB_TYPE_P0L1 | MB_TYPE_P1L1)
+#define MB_TYPE_L0L1       (MB_TYPE_L0   | MB_TYPE_L1)
+#define MB_TYPE_QUANT      0x00010000
+#define MB_TYPE_CBP        0x00020000
+#endif
+
+    AVBufferRef *mbskip_table_buf;
+    uint8_t *mbskip_table;
+
+    AVBufferRef *ref_index_buf[2];
+    int8_t *ref_index[2];
+
+    AVBufferRef *mb_var_buf;
+    uint16_t *mb_var;           ///< Table for MB variances
+
+    AVBufferRef *mc_mb_var_buf;
+    uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
 
+    AVBufferRef *mb_mean_buf;
+    uint8_t *mb_mean;           ///< Table for MB luminance
+
+    AVBufferRef *hwaccel_priv_buf;
     /**
-     * halfpel luma planes.
+     * hardware accelerator private data
      */
-    uint8_t *interpolated[3];
-    int8_t *qscale_table_base;
-    int16_t (*motion_val_base[2])[2];
-    uint32_t *mb_type_base;
+    void *hwaccel_picture_private;
+
 #define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if there is just one type
 #define IS_INTRA4x4(a)   ((a)&MB_TYPE_INTRA4x4)
 #define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16)
@@ -140,13 +193,13 @@ typedef struct Picture{
 
     int mb_var_sum;             ///< sum of MB variance for current frame
     int mc_mb_var_sum;          ///< motion compensated MB variance for current frame
-    uint16_t *mb_var;           ///< Table for MB variances
-    uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
-    uint8_t *mb_mean;           ///< Table for MB luminance
-    int32_t *mb_cmp_score;      ///< Table for MB cmp scores, for mb decision FIXME remove
+
     int b_frame_score;          /* */
-    struct MpegEncContext *owner2; ///< pointer to the MpegEncContext that allocated this picture
     int needs_realloc;          ///< Picture needs to be reallocated (eg due to a frame size change)
+
+    int reference;
+    int shared;
+    int recovered;              ///< Picture at IDR or recovery point + recovery count
 } Picture;
 
 /**
@@ -250,8 +303,8 @@ typedef struct MpegEncContext {
     int b4_stride;             ///< 4*mb_width+1 used for some 4x4 block arrays to allow simple addressing
     int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replication)
     int mb_num;                ///< number of MBs of a picture
-    int linesize;              ///< line size, in bytes, may be different from width
-    int uvlinesize;            ///< line size, for chroma in bytes, may be different from width
+    ptrdiff_t linesize;        ///< line size, in bytes, may be different from width
+    ptrdiff_t uvlinesize;      ///< line size, for chroma in bytes, may be different from width
     Picture *picture;          ///< main picture buffer
     Picture **input_picture;   ///< next pictures on display order for encoding
     Picture **reordered_input_picture; ///< pointer to the next pictures in codedorder for encoding
@@ -270,7 +323,7 @@ typedef struct MpegEncContext {
     /* WARNING: changes above this line require updates to hardcoded
      *          offsets used in asm. */
 
-    int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video()
+    int64_t user_specified_pts; ///< last non-zero pts from AVFrame which was passed into avcodec_encode_video2()
     /**
      * pts difference between the first and second input frame, used for
      * calculating dts of the first frame when there's a delay */
@@ -315,9 +368,6 @@ typedef struct MpegEncContext {
     Picture *last_picture_ptr;     ///< pointer to the previous picture.
     Picture *next_picture_ptr;     ///< pointer to the next picture (for bidir pred)
     Picture *current_picture_ptr;  ///< pointer to the current picture
-    int picture_count;             ///< number of allocated pictures (MAX_PICTURE_COUNT * avctx->thread_count)
-    int picture_range_start, picture_range_end; ///< the part of picture that this context can allocate in
-    uint8_t *visualization_buffer[3]; ///< temporary buffer vor MV visualization
     int last_dc[3];                ///< last DC values for MPEG1
     int16_t *dc_val_base;
     int16_t *dc_val[3];            ///< used for mpeg4 DC prediction, all 3 arrays must be continuous
@@ -359,7 +409,9 @@ typedef struct MpegEncContext {
     int h263_long_vectors;      ///< use horrible h263v1 long vector mode
 
     DSPContext dsp;             ///< pointers for accelerated dsp functions
+    HpelDSPContext hdsp;
     VideoDSPContext vdsp;
+    H263DSPContext h263dsp;
     int f_code;                 ///< forward MV resolution
     int b_code;                 ///< backward MV resolution for B Frames (mpeg4)
     int16_t (*p_mv_table_base)[2];
@@ -489,19 +541,6 @@ typedef struct MpegEncContext {
     int last_bits; ///< temp var used for calculating the above vars
 
     /* error concealment / resync */
-    int error_count, error_occurred;
-    uint8_t *error_status_table;       ///< table of the error status of each MB
-#define VP_START            1          ///< current MB is the first after a resync marker
-#define ER_AC_ERROR            2
-#define ER_DC_ERROR            4
-#define ER_MV_ERROR            8
-#define ER_AC_END              16
-#define ER_DC_END              32
-#define ER_MV_END              64
-
-#define ER_MB_ERROR (ER_AC_ERROR|ER_DC_ERROR|ER_MV_ERROR)
-#define ER_MB_END   (ER_AC_END|ER_DC_END|ER_MV_END)
-
     int resync_mb_x;                 ///< x position of last resync marker
     int resync_mb_y;                 ///< y position of last resync marker
     GetBitContext last_resync_gb;    ///< used to search for the next resync marker
@@ -514,7 +553,6 @@ typedef struct MpegEncContext {
     /* H.263 specific */
     int gob_index;
     int obmc;                       ///< overlapped block motion compensation
-    int showed_packed_warning;      ///< flag for having shown the warning about divxs invalid b frames
     int mb_info;                    ///< interval for outputting info about mb offsets as side data
     int prev_mb_info, last_mb_info;
     uint8_t *mb_info_ptr;
@@ -530,7 +568,8 @@ typedef struct MpegEncContext {
     int custom_pcf;
 
     /* mpeg4 specific */
-    int time_increment_bits;        ///< number of bits to represent the fractional part of time
+    ///< number of bits to represent the fractional part of time (encoder only)
+    int time_increment_bits;
     int last_time_base;
     int time_base;                  ///< time in seconds of last I,P,S Frame
     int64_t time;                   ///< time of current frame
@@ -539,61 +578,30 @@ typedef struct MpegEncContext {
     uint16_t pb_time;               ///< time distance between the last b and p,s,i frame
     uint16_t pp_field_time;
     uint16_t pb_field_time;         ///< like above, just for interlaced
-    int shape;
-    int vol_sprite_usage;
-    int sprite_width;
-    int sprite_height;
-    int sprite_left;
-    int sprite_top;
-    int sprite_brightness_change;
-    int num_sprite_warping_points;
     int real_sprite_warping_points;
-    uint16_t sprite_traj[4][2];      ///< sprite trajectory points
     int sprite_offset[2][2];         ///< sprite offset[isChroma][isMVY]
     int sprite_delta[2][2];          ///< sprite_delta [isY][isMVY]
-    int sprite_shift[2];             ///< sprite shift [isChroma]
     int mcsel;
     int quant_precision;
     int quarter_sample;              ///< 1->qpel, 0->half pel ME/MC
-    int scalability;
-    int hierachy_type;
-    int enhancement_type;
-    int new_pred;
-    int reduced_res_vop;
     int aspect_ratio_info; //FIXME remove
     int sprite_warping_accuracy;
-    int low_latency_sprite;
     int data_partitioning;           ///< data partitioning flag from header
     int partitioned_frame;           ///< is current frame partitioned
-    int rvlc;                        ///< reversible vlc
-    int resync_marker;               ///< could this stream contain resync markers
     int low_delay;                   ///< no reordering needed / has no b-frames
     int vo_type;
     int vol_control_parameters;      ///< does the stream contain the low_delay flag, used to workaround buggy encoders
-    int intra_dc_threshold;          ///< QP above whch the ac VLC should be used for intra dc
-    int use_intra_dc_vlc;
     PutBitContext tex_pb;            ///< used for data partitioned VOPs
     PutBitContext pb2;               ///< used for data partitioned VOPs
     int mpeg_quant;
-    int t_frame;                       ///< time distance of first I -> B, used for interlaced b frames
     int padding_bug_score;             ///< used to detect the VERY common padding bug in MPEG4
-    int cplx_estimation_trash_i;
-    int cplx_estimation_trash_p;
-    int cplx_estimation_trash_b;
 
     /* divx specific, used to workaround (many) bugs in divx5 */
-    int divx_version;
-    int divx_build;
     int divx_packed;
     uint8_t *bitstream_buffer; //Divx 5.01 puts several frames in a single one, this is used to reorder them
     int bitstream_buffer_size;
     unsigned int allocated_bitstream_buffer_size;
 
-    int xvid_build;
-
-    /* lavc specific stuff, used to workaround bugs in libavcodec */
-    int lavc_build;
-
     /* RV10 specific */
     int rv10_version; ///< RV10 version: 0 or 3
     int rv10_first_dc_coded[3];
@@ -601,8 +609,6 @@ typedef struct MpegEncContext {
 
     /* MJPEG specific */
     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}
 
     /* MSMPEG4 specific */
     int mv_table_index;
@@ -628,7 +634,6 @@ typedef struct MpegEncContext {
     /* Mpeg1 specific */
     int gop_picture_number;  ///< index of the first picture of a GOP based on fake_pic_num & mpeg1 specific
     int last_mv_dir;         ///< last mv_dir, used for b frame encoding
-    int broken_link;         ///< no_output_of_prior_pics_flag
     uint8_t *vbv_delay_ptr;  ///< pointer to vbv_delay in the bitstream
 
     /* MPEG-2-specific - I wished not to have to support this mess. */
@@ -659,7 +664,6 @@ typedef struct MpegEncContext {
     int progressive_frame;
     int full_pel[2];
     int interlaced_dct;
-    int first_slice;
     int first_field;         ///< is 1 for the first field of a field picture 0 otherwise
     int drop_frame_timecode; ///< timecode is in drop frame format.
     int scan_offset;         ///< reserve space for SVCD scan offset user data.
@@ -668,59 +672,62 @@ typedef struct MpegEncContext {
     int rtp_mode;
 
     uint8_t *ptr_lastgob;
-    int swap_uv;             //vcr2 codec is an MPEG-2 variant with U and V swapped
-    DCTELEM (*pblocks[12])[64];
+    int16_t (*pblocks[12])[64];
 
-    DCTELEM (*block)[64]; ///< points to one of the following blocks
-    DCTELEM (*blocks)[8][64]; // for HQ mode we need to keep the best block
-    int (*decode_mb)(struct MpegEncContext *s, DCTELEM block[6][64]); // used by some codecs to avoid a switch()
+    int16_t (*block)[64]; ///< points to one of the following blocks
+    int16_t (*blocks)[8][64]; // for HQ mode we need to keep the best block
+    int (*decode_mb)(struct MpegEncContext *s, int16_t block[6][64]); // used by some codecs to avoid a switch()
 #define SLICE_OK         0
 #define SLICE_ERROR     -1
 #define SLICE_END       -2 ///<end marker found
 #define SLICE_NOEND     -3 ///<no end marker or error found but mb count exceeded
 
     void (*dct_unquantize_mpeg1_intra)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_mpeg1_inter)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_mpeg2_intra)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_mpeg2_inter)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_h263_intra)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_h263_inter)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_h261_intra)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_h261_inter)(struct MpegEncContext *s,
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_intra)(struct MpegEncContext *s, // unquantizer to use (mpeg4 can use both)
-                           DCTELEM *block/*align 16*/, int n, int qscale);
+                           int16_t *block/*align 16*/, int n, int qscale);
     void (*dct_unquantize_inter)(struct MpegEncContext *s, // unquantizer to use (mpeg4 can use both)
-                           DCTELEM *block/*align 16*/, int n, int qscale);
-    int (*dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow);
-    int (*fast_dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow);
-    void (*denoise_dct)(struct MpegEncContext *s, DCTELEM *block);
+                           int16_t *block/*align 16*/, int n, int qscale);
+    int (*dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
+    int (*fast_dct_quantize)(struct MpegEncContext *s, int16_t *block/*align 16*/, int n, int qscale, int *overflow);
+    void (*denoise_dct)(struct MpegEncContext *s, int16_t *block);
 
     int mpv_flags;      ///< flags set by private options
     int quantizer_noise_shaping;
 
-    /* error resilience stuff */
-    uint8_t *er_temp_buffer;
-
     /* temp buffers for rate control */
     float *cplx_tab, *bits_tab;
 
     /* flag to indicate a reinitialization is required, e.g. after
      * a frame size change */
     int context_reinit;
+
+    ERContext er;
+
+    int error_rate;
+
+    /* temporary frames used by b_frame_strategy = 2 */
+    AVFrame *tmp_frames[MAX_B_FRAMES + 2];
 } MpegEncContext;
 
-#define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
-    (pic >= old_ctx->picture && pic < old_ctx->picture+old_ctx->picture_count ?\
-        &new_ctx->picture[pic - old_ctx->picture] : (Picture*) ((uint8_t*)pic - (uint8_t*)old_ctx + (uint8_t*)new_ctx))\
-    : NULL)
+#define REBASE_PICTURE(pic, new_ctx, old_ctx)             \
+    ((pic && pic >= old_ctx->picture &&                   \
+      pic < old_ctx->picture + MAX_PICTURE_COUNT) ?  \
+        &new_ctx->picture[pic - old_ctx->picture] : NULL)
 
 /* mpegvideo_enc common options */
 #define FF_MPV_FLAG_SKIP_RD      0x0001
@@ -740,7 +747,9 @@ typedef struct MpegEncContext {
                                                                       FF_MPV_OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
 { "chroma_elim_threshold", "single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)",\
                                                                       FF_MPV_OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FF_MPV_OPT_FLAGS },\
-{ "quantizer_noise_shaping", NULL,                                  FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 },       0, INT_MAX, FF_MPV_OPT_FLAGS },
+{ "quantizer_noise_shaping", NULL,                                  FF_MPV_OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, { .i64 = 0 },       0, INT_MAX, FF_MPV_OPT_FLAGS },\
+{ "error_rate", "Simulate errors in the bitstream to test error concealment.",                                                                                                  \
+                                                                    FF_MPV_OFFSET(error_rate),              AV_OPT_TYPE_INT, { .i64 = 0 },       0, INT_MAX, FF_MPV_OPT_FLAGS },
 
 extern const AVOption ff_mpv_generic_options[];
 
@@ -761,10 +770,9 @@ void ff_MPV_common_defaults(MpegEncContext *s);
 
 void ff_MPV_decode_defaults(MpegEncContext *s);
 int ff_MPV_common_init(MpegEncContext *s);
-int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize);
 int ff_MPV_common_frame_size_change(MpegEncContext *s);
 void ff_MPV_common_end(MpegEncContext *s);
-void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]);
+void ff_MPV_decode_mb(MpegEncContext *s, int16_t block[12][64]);
 int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx);
 void ff_MPV_frame_end(MpegEncContext *s);
 int ff_MPV_encode_init(AVCodecContext *avctx);
@@ -773,36 +781,34 @@ int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
                           const AVFrame *frame, int *got_packet);
 void ff_MPV_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_arm(MpegEncContext *s);
-void ff_MPV_common_init_altivec(MpegEncContext *s);
 void ff_MPV_common_init_bfin(MpegEncContext *s);
+void ff_MPV_common_init_ppc(MpegEncContext *s);
 void ff_clean_intra_table_entries(MpegEncContext *s);
-void ff_draw_horiz_band(MpegEncContext *s, int y, int h);
+void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
+                        Picture *last, int y, int h, int picture_structure,
+                        int first_field, int draw_edges, int low_delay,
+                        int v_edge_pos, int h_edge_pos);
+void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h);
 void ff_mpeg_flush(AVCodecContext *avctx);
-void ff_print_debug_info(MpegEncContext *s, AVFrame *pict);
+void ff_print_debug_info(MpegEncContext *s, Picture *p);
 void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix);
-void ff_release_unused_pictures(MpegEncContext *s, int remove_current);
 int ff_find_unused_picture(MpegEncContext *s, int shared);
-void ff_denoise_dct(MpegEncContext *s, DCTELEM *block);
+void ff_denoise_dct(MpegEncContext *s, int16_t *block);
 int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
 int ff_MPV_lowest_referenced_row(MpegEncContext *s, int dir);
 void ff_MPV_report_decode_progress(MpegEncContext *s);
 int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src);
-const uint8_t *avpriv_mpv_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state);
 void ff_set_qscale(MpegEncContext * s, int qscale);
 
-void ff_er_frame_start(MpegEncContext *s);
-void ff_er_frame_end(MpegEncContext *s);
-void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status);
+void ff_mpeg_er_frame_start(MpegEncContext *s);
 
 int ff_dct_common_init(MpegEncContext *s);
 void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],
                        const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra);
-int ff_dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
+int ff_dct_quantize_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
 
 void ff_init_block_index(MpegEncContext *s);
-void ff_copy_picture(Picture *dst, Picture *src);
 
 void ff_MPV_motion(MpegEncContext *s,
                    uint8_t *dest_y, uint8_t *dest_cb,
@@ -818,7 +824,12 @@ void ff_MPV_motion(MpegEncContext *s,
 int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared);
 
 extern const enum AVPixelFormat ff_pixfmt_list_420[];
-extern const enum AVPixelFormat ff_hwaccel_pixfmt_list_420[];
+
+/**
+ * permute block according to permuatation.
+ * @param last last non zero element in scantable order
+ */
+void ff_block_permute(int16_t *block, uint8_t *permutation, const uint8_t *scantable, int last);
 
 static inline void ff_update_block_index(MpegEncContext *s){
     const int block_size = 8;
@@ -874,27 +885,13 @@ extern const uint8_t * const ff_mpeg2_dc_scale_table[4];
 
 void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number);
 void ff_mpeg1_encode_mb(MpegEncContext *s,
-                        DCTELEM block[6][64],
+                        int16_t block[6][64],
                         int motion_x, int motion_y);
 void ff_mpeg1_encode_init(MpegEncContext *s);
 void ff_mpeg1_encode_slice_header(MpegEncContext *s);
-void ff_mpeg1_clean_buffers(MpegEncContext *s);
-int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, AVCodecParserContext *s);
 
 extern const uint8_t ff_aic_dc_scale_table[32];
 extern const uint8_t ff_h263_chroma_qscale_table[32];
-extern const uint8_t ff_h263_loop_filter_strength[32];
-
-/* h261.c */
-void ff_h261_loop_filter(MpegEncContext *s);
-void ff_h261_reorder_mb_index(MpegEncContext* s);
-void ff_h261_encode_mb(MpegEncContext *s,
-                    DCTELEM block[6][64],
-                    int motion_x, int motion_y);
-void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number);
-void ff_h261_encode_init(MpegEncContext *s);
-int ff_h261_get_picture_format(int width, int height);
-
 
 /* rv10.c */
 void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number);
@@ -906,7 +903,7 @@ void ff_rv20_encode_picture_header(MpegEncContext *s, int picture_number);
 void ff_msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number);
 void ff_msmpeg4_encode_ext_header(MpegEncContext * s);
 void ff_msmpeg4_encode_mb(MpegEncContext * s,
-                          DCTELEM block[6][64],
+                          int16_t block[6][64],
                           int motion_x, int motion_y);
 int ff_msmpeg4_decode_picture_header(MpegEncContext * s);
 int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size);
@@ -914,14 +911,18 @@ int ff_msmpeg4_decode_init(AVCodecContext *avctx);
 void ff_msmpeg4_encode_init(MpegEncContext *s);
 int ff_wmv2_decode_picture_header(MpegEncContext * s);
 int ff_wmv2_decode_secondary_picture_header(MpegEncContext * s);
-void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr);
+void ff_wmv2_add_mb(MpegEncContext *s, int16_t block[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr);
 void ff_mspel_motion(MpegEncContext *s,
                                uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
                                uint8_t **ref_picture, op_pixels_func (*pix_op)[4],
                                int motion_x, int motion_y, int h);
 int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number);
 void ff_wmv2_encode_mb(MpegEncContext * s,
-                       DCTELEM block[6][64],
+                       int16_t block[6][64],
                        int motion_x, int motion_y);
 
+int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src);
+void ff_mpeg_unref_picture(MpegEncContext *s, Picture *picture);
+void ff_free_picture_tables(Picture *pic);
+
 #endif /* AVCODEC_MPEGVIDEO_H */
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index f783dc7..590e025 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -27,13 +27,19 @@
  * The simplest mpeg encoder (well, it was the simplest!).
  */
 
+#include <stdint.h>
+
+#include "libavutil/internal.h"
 #include "libavutil/intmath.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
+#include "dct.h"
 #include "dsputil.h"
+#include "mpeg12.h"
 #include "mpegvideo.h"
+#include "h261.h"
 #include "h263.h"
 #include "mathops.h"
 #include "mjpegenc.h"
@@ -47,19 +53,11 @@
 #include "bytestream.h"
 #include <limits.h>
 
-//#undef NDEBUG
-//#include <assert.h>
-
 static int encode_picture(MpegEncContext *s, int picture_number);
-static int dct_quantize_refine(MpegEncContext *s, DCTELEM *block, int16_t *weight, DCTELEM *orig, int n, int qscale);
+static int dct_quantize_refine(MpegEncContext *s, int16_t *block, int16_t *weight, int16_t *orig, int n, int qscale);
 static int sse_mb(MpegEncContext *s);
-static void denoise_dct_c(MpegEncContext *s, DCTELEM *block);
-static int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
-
-/* enable all paranoid tests for rounding, overflows, etc... */
-//#define PARANOID
-
-//#define DEBUG
+static void denoise_dct_c(MpegEncContext *s, int16_t *block);
+static int dct_quantize_trellis_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
 
 static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1];
 static uint8_t default_fcode_tab[MAX_MV * 2 + 1];
@@ -175,7 +173,7 @@ void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix)
  */
 void ff_init_qscale_tab(MpegEncContext *s)
 {
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t * const qscale_table = s->current_picture.qscale_table;
     int i;
 
     for (i = 0; i < s->mb_num; i++) {
@@ -186,54 +184,6 @@ void ff_init_qscale_tab(MpegEncContext *s)
     }
 }
 
-static void copy_picture_attributes(MpegEncContext *s,
-                                    AVFrame *dst,
-                                    AVFrame *src)
-{
-    int i;
-
-    dst->pict_type              = src->pict_type;
-    dst->quality                = src->quality;
-    dst->coded_picture_number   = src->coded_picture_number;
-    dst->display_picture_number = src->display_picture_number;
-    //dst->reference              = src->reference;
-    dst->pts                    = src->pts;
-    dst->interlaced_frame       = src->interlaced_frame;
-    dst->top_field_first        = src->top_field_first;
-
-    if (s->avctx->me_threshold) {
-        if (!src->motion_val[0])
-            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_val not set!\n");
-        if (!src->mb_type)
-            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.mb_type not set!\n");
-        if (!src->ref_index[0])
-            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.ref_index not set!\n");
-        if (src->motion_subsample_log2 != dst->motion_subsample_log2)
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "AVFrame.motion_subsample_log2 doesn't match! (%d!=%d)\n",
-                   src->motion_subsample_log2, dst->motion_subsample_log2);
-
-        memcpy(dst->mb_type, src->mb_type,
-               s->mb_stride * s->mb_height * sizeof(dst->mb_type[0]));
-
-        for (i = 0; i < 2; i++) {
-            int stride = ((16 * s->mb_width ) >>
-                          src->motion_subsample_log2) + 1;
-            int height = ((16 * s->mb_height) >> src->motion_subsample_log2);
-
-            if (src->motion_val[i] &&
-                src->motion_val[i] != dst->motion_val[i]) {
-                memcpy(dst->motion_val[i], src->motion_val[i],
-                       2 * stride * height * sizeof(int16_t));
-            }
-            if (src->ref_index[i] && src->ref_index[i] != dst->ref_index[i]) {
-                memcpy(dst->ref_index[i], src->ref_index[i],
-                       s->mb_stride * 4 * s->mb_height * sizeof(int8_t));
-            }
-        }
-    }
-}
-
 static void update_duplicate_context_after_me(MpegEncContext *dst,
                                               MpegEncContext *src)
 {
@@ -267,14 +217,16 @@ static void MPV_encode_defaults(MpegEncContext *s)
     }
     s->me.mv_penalty = default_mv_penalty;
     s->fcode_tab     = default_fcode_tab;
+
+    s->input_picture_number  = 0;
+    s->picture_in_gop_number = 0;
 }
 
 /* init video encoder */
 av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
-    int i;
-    int chroma_h_shift, chroma_v_shift;
+    int i, ret;
 
     MPV_encode_defaults(s);
 
@@ -287,19 +239,6 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
             return -1;
         }
         break;
-    case AV_CODEC_ID_LJPEG:
-        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_BGRA     &&
-            ((avctx->pix_fmt != AV_PIX_FMT_YUV420P &&
-              avctx->pix_fmt != AV_PIX_FMT_YUV422P &&
-              avctx->pix_fmt != AV_PIX_FMT_YUV444P) ||
-             avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)) {
-            av_log(avctx, AV_LOG_ERROR, "colorspace not supported in LJPEG\n");
-            return -1;
-        }
-        break;
     case AV_CODEC_ID_MJPEG:
         if (avctx->pix_fmt != AV_PIX_FMT_YUVJ420P &&
             avctx->pix_fmt != AV_PIX_FMT_YUVJ422P &&
@@ -342,14 +281,12 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
     s->avctx        = avctx;
     s->flags        = avctx->flags;
     s->flags2       = avctx->flags2;
+    if (avctx->max_b_frames > MAX_B_FRAMES) {
+        av_log(avctx, AV_LOG_ERROR, "Too many B-frames requested, maximum "
+               "is %d.\n", MAX_B_FRAMES);
+    }
     s->max_b_frames = avctx->max_b_frames;
     s->codec_id     = avctx->codec->id;
-#if FF_API_MPV_GLOBAL_OPTS
-    if (avctx->luma_elim_threshold)
-        s->luma_elim_threshold   = avctx->luma_elim_threshold;
-    if (avctx->chroma_elim_threshold)
-        s->chroma_elim_threshold = avctx->chroma_elim_threshold;
-#endif
     s->strict_std_compliance = avctx->strict_std_compliance;
     s->quarter_sample     = (avctx->flags & CODEC_FLAG_QPEL) != 0;
     s->mpeg_quant         = avctx->mpeg_quant;
@@ -369,11 +306,6 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
     /* Fixed QSCALE */
     s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE);
 
-#if FF_API_MPV_GLOBAL_OPTS
-    if (s->flags & CODEC_FLAG_QP_RD)
-        s->mpv_flags |= FF_MPV_FLAG_QP_RD;
-#endif
-
     s->adaptive_quant = (s->avctx->lumi_masking ||
                          s->avctx->dark_masking ||
                          s->avctx->temporal_cplx_masking ||
@@ -490,11 +422,6 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
         return -1;
     }
 
-#if FF_API_MPV_GLOBAL_OPTS
-    if (s->flags & CODEC_FLAG_CBP_RD)
-        s->mpv_flags |= FF_MPV_FLAG_CBP_RD;
-#endif
-
     if ((s->mpv_flags & FF_MPV_FLAG_CBP_RD) && !avctx->trellis) {
         av_log(avctx, AV_LOG_ERROR, "CBP RD needs trellis quant\n");
         return -1;
@@ -561,11 +488,6 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
     }
 
     i = (INT_MAX / 2 + 128) >> 8;
-    if (avctx->me_threshold >= i) {
-        av_log(avctx, AV_LOG_ERROR, "me_threshold too large, max is %d\n",
-               i - 1);
-        return -1;
-    }
     if (avctx->mb_threshold >= i) {
         av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n",
                i - 1);
@@ -602,9 +524,6 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
     if (avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS)
         s->inter_quant_bias = avctx->inter_quant_bias;
 
-    av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift,
-                                     &chroma_v_shift);
-
     if (avctx->codec_id == AV_CODEC_ID_MPEG4 &&
         s->avctx->time_base.den > (1 << 16) - 1) {
         av_log(avctx, AV_LOG_ERROR,
@@ -616,15 +535,6 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
     }
     s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;
 
-#if FF_API_MPV_GLOBAL_OPTS
-    if (avctx->flags2 & CODEC_FLAG2_SKIP_RD)
-        s->mpv_flags |= FF_MPV_FLAG_SKIP_RD;
-    if (avctx->flags2 & CODEC_FLAG2_STRICT_GOP)
-        s->mpv_flags |= FF_MPV_FLAG_STRICT_GOP;
-    if (avctx->quantizer_noise_shaping)
-        s->quantizer_noise_shaping = avctx->quantizer_noise_shaping;
-#endif
-
     switch (avctx->codec->id) {
     case AV_CODEC_ID_MPEG1VIDEO:
         s->out_format = FMT_MPEG1;
@@ -637,24 +547,10 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
         avctx->delay  = s->low_delay ? 0 : (s->max_b_frames + 1);
         s->rtp_mode   = 1;
         break;
-    case AV_CODEC_ID_LJPEG:
     case AV_CODEC_ID_MJPEG:
         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) {
-            s->mjpeg_vsample[0] = s->mjpeg_hsample[0] =
-            s->mjpeg_vsample[1] = s->mjpeg_hsample[1] =
-            s->mjpeg_vsample[2] = s->mjpeg_hsample[2] = 1;
-        } else {
-            s->mjpeg_vsample[0] = 2;
-            s->mjpeg_vsample[1] = 2 >> chroma_v_shift;
-            s->mjpeg_vsample[2] = 2 >> chroma_v_shift;
-            s->mjpeg_hsample[0] = 2;
-            s->mjpeg_hsample[1] = 2 >> chroma_h_shift;
-            s->mjpeg_hsample[2] = 2 >> chroma_h_shift;
-        }
-        if (!(CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) ||
+        if (!CONFIG_MJPEG_ENCODER ||
             ff_mjpeg_encode_init(s) < 0)
             return -1;
         avctx->delay = 0;
@@ -789,6 +685,30 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
     if (ARCH_X86)
         ff_MPV_encode_init_x86(s);
 
+    s->avctx->coded_frame = &s->current_picture.f;
+
+    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_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);
+    }
+
+    ff_h263dsp_init(&s->h263dsp);
     if (!s->dct_quantize)
         s->dct_quantize = ff_dct_quantize_c;
     if (!s->denoise_dct)
@@ -850,22 +770,66 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
     if (ff_rate_control_init(s) < 0)
         return -1;
 
+#if FF_API_ERROR_RATE
+    FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->error_rate)
+        s->error_rate = avctx->error_rate;
+    FF_ENABLE_DEPRECATION_WARNINGS;
+#endif
+
+    if (avctx->b_frame_strategy == 2) {
+        for (i = 0; i < s->max_b_frames + 2; i++) {
+            s->tmp_frames[i] = av_frame_alloc();
+            if (!s->tmp_frames[i])
+                return AVERROR(ENOMEM);
+
+            s->tmp_frames[i]->format = AV_PIX_FMT_YUV420P;
+            s->tmp_frames[i]->width  = s->width  >> avctx->brd_scale;
+            s->tmp_frames[i]->height = s->height >> avctx->brd_scale;
+
+            ret = av_frame_get_buffer(s->tmp_frames[i], 32);
+            if (ret < 0)
+                return ret;
+        }
+    }
+
     return 0;
+fail:
+    ff_MPV_encode_end(avctx);
+    return AVERROR_UNKNOWN;
 }
 
 av_cold int ff_MPV_encode_end(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
+    int i;
 
     ff_rate_control_uninit(s);
 
     ff_MPV_common_end(s);
-    if ((CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) &&
+    if (CONFIG_MJPEG_ENCODER &&
         s->out_format == FMT_MJPEG)
         ff_mjpeg_encode_close(s);
 
     av_freep(&avctx->extradata);
 
+    for (i = 0; i < FF_ARRAY_ELEMS(s->tmp_frames); i++)
+        av_frame_free(&s->tmp_frames[i]);
+
+    ff_free_picture_tables(&s->new_picture);
+    ff_mpeg_unref_picture(s, &s->new_picture);
+
+    av_freep(&s->avctx->stats_out);
+    av_freep(&s->ac_stats);
+
+    av_freep(&s->q_intra_matrix);
+    av_freep(&s->q_inter_matrix);
+    av_freep(&s->q_intra_matrix16);
+    av_freep(&s->q_inter_matrix16);
+    av_freep(&s->input_picture);
+    av_freep(&s->reordered_input_picture);
+    av_freep(&s->dct_offset);
+
     return 0;
 }
 
@@ -907,18 +871,18 @@ static int get_intra_count(MpegEncContext *s, uint8_t *src,
 }
 
 
-static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg)
+static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
 {
-    AVFrame *pic = NULL;
+    Picture *pic = NULL;
     int64_t pts;
-    int i;
+    int i, display_picture_number = 0, ret;
     const int encoding_delay = s->max_b_frames ? s->max_b_frames :
                                                  (s->low_delay ? 0 : 1);
     int direct = 1;
 
     if (pic_arg) {
         pts = pic_arg->pts;
-        pic_arg->display_picture_number = s->input_picture_number++;
+        display_picture_number = s->input_picture_number++;
 
         if (pts != AV_NOPTS_VALUE) {
             if (s->user_specified_pts != AV_NOPTS_VALUE) {
@@ -932,7 +896,7 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg)
                     return -1;
                 }
 
-                if (!s->low_delay && pic_arg->display_picture_number == 1)
+                if (!s->low_delay && display_picture_number == 1)
                     s->dts_delta = time - last;
             }
             s->user_specified_pts = pts;
@@ -944,89 +908,91 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg)
                        "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n",
                        pts);
             } else {
-                pts = pic_arg->display_picture_number;
+                pts = display_picture_number;
             }
         }
     }
 
-  if (pic_arg) {
-    if (encoding_delay && !(s->flags & CODEC_FLAG_INPUT_PRESERVED))
-        direct = 0;
-    if (pic_arg->linesize[0] != s->linesize)
-        direct = 0;
-    if (pic_arg->linesize[1] != s->uvlinesize)
-        direct = 0;
-    if (pic_arg->linesize[2] != s->uvlinesize)
-        direct = 0;
-
-    av_dlog(s->avctx, "%d %d %d %d\n", pic_arg->linesize[0],
-            pic_arg->linesize[1], s->linesize, s->uvlinesize);
-
-    if (direct) {
-        i = ff_find_unused_picture(s, 1);
-        if (i < 0)
-            return i;
+    if (pic_arg) {
+        if (!pic_arg->buf[0]);
+            direct = 0;
+        if (pic_arg->linesize[0] != s->linesize)
+            direct = 0;
+        if (pic_arg->linesize[1] != s->uvlinesize)
+            direct = 0;
+        if (pic_arg->linesize[2] != s->uvlinesize)
+            direct = 0;
+
+        av_dlog(s->avctx, "%d %d %td %td\n", pic_arg->linesize[0],
+                pic_arg->linesize[1], s->linesize, s->uvlinesize);
+
+        if (direct) {
+            i = ff_find_unused_picture(s, 1);
+            if (i < 0)
+                return i;
 
-        pic = &s->picture[i].f;
-        pic->reference = 3;
+            pic = &s->picture[i];
+            pic->reference = 3;
 
-        for (i = 0; i < 4; i++) {
-            pic->data[i]     = pic_arg->data[i];
-            pic->linesize[i] = pic_arg->linesize[i];
-        }
-        if (ff_alloc_picture(s, (Picture *) pic, 1) < 0) {
-            return -1;
-        }
-    } else {
-        i = ff_find_unused_picture(s, 0);
-        if (i < 0)
-            return i;
+            if ((ret = av_frame_ref(&pic->f, pic_arg)) < 0)
+                return ret;
+            if (ff_alloc_picture(s, pic, 1) < 0) {
+                return -1;
+            }
+        } else {
+            i = ff_find_unused_picture(s, 0);
+            if (i < 0)
+                return i;
 
-        pic = &s->picture[i].f;
-        pic->reference = 3;
+            pic = &s->picture[i];
+            pic->reference = 3;
 
-        if (ff_alloc_picture(s, (Picture *) pic, 0) < 0) {
-            return -1;
-        }
+            if (ff_alloc_picture(s, pic, 0) < 0) {
+                return -1;
+            }
 
-        if (pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] &&
-            pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] &&
-            pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]) {
-            // empty
-        } else {
-            int h_chroma_shift, v_chroma_shift;
-            av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
-                                             &h_chroma_shift,
-                                             &v_chroma_shift);
-
-            for (i = 0; i < 3; i++) {
-                int src_stride = pic_arg->linesize[i];
-                int dst_stride = i ? s->uvlinesize : s->linesize;
-                int h_shift = i ? h_chroma_shift : 0;
-                int v_shift = i ? v_chroma_shift : 0;
-                int w = s->width  >> h_shift;
-                int h = s->height >> v_shift;
-                uint8_t *src = pic_arg->data[i];
-                uint8_t *dst = pic->data[i];
-
-                if (!s->avctx->rc_buffer_size)
-                    dst += INPLACE_OFFSET;
-
-                if (src_stride == dst_stride)
-                    memcpy(dst, src, src_stride * h);
-                else {
-                    while (h--) {
-                        memcpy(dst, src, w);
-                        dst += dst_stride;
-                        src += src_stride;
+            if (pic->f.data[0] + INPLACE_OFFSET == pic_arg->data[0] &&
+                pic->f.data[1] + INPLACE_OFFSET == pic_arg->data[1] &&
+                pic->f.data[2] + INPLACE_OFFSET == pic_arg->data[2]) {
+                // empty
+            } else {
+                int h_chroma_shift, v_chroma_shift;
+                av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt,
+                                                 &h_chroma_shift,
+                                                 &v_chroma_shift);
+
+                for (i = 0; i < 3; i++) {
+                    int src_stride = pic_arg->linesize[i];
+                    int dst_stride = i ? s->uvlinesize : s->linesize;
+                    int h_shift = i ? h_chroma_shift : 0;
+                    int v_shift = i ? v_chroma_shift : 0;
+                    int w = s->width  >> h_shift;
+                    int h = s->height >> v_shift;
+                    uint8_t *src = pic_arg->data[i];
+                    uint8_t *dst = pic->f.data[i];
+
+                    if (!s->avctx->rc_buffer_size)
+                        dst += INPLACE_OFFSET;
+
+                    if (src_stride == dst_stride)
+                        memcpy(dst, src, src_stride * h);
+                    else {
+                        while (h--) {
+                            memcpy(dst, src, w);
+                            dst += dst_stride;
+                            src += src_stride;
+                        }
                     }
                 }
             }
         }
+        ret = av_frame_copy_props(&pic->f, pic_arg);
+        if (ret < 0)
+            return ret;
+
+        pic->f.display_picture_number = display_picture_number;
+        pic->f.pts = pts; // we set this here to avoid modifiying pic_arg
     }
-    copy_picture_attributes(s, pic, pic_arg);
-    pic->pts = pts; // we set this here to avoid modifiying pic_arg
-  }
 
     /* shift buffer entries */
     for (i = 1; i < MAX_PICTURE_COUNT /*s->encoding_delay + 1*/; i++)
@@ -1048,7 +1014,7 @@ static int skip_check(MpegEncContext *s, Picture *p, Picture *ref)
         const int bw = plane ? 1 : 2;
         for (y = 0; y < s->mb_height * bw; y++) {
             for (x = 0; x < s->mb_width * bw; x++) {
-                int off = p->f.type == FF_BUFFER_TYPE_SHARED ? 0 : 16;
+                int off = p->shared ? 0 : 16;
                 uint8_t *dptr = p->f.data[plane] + 8 * (x + y * stride) + off;
                 uint8_t *rptr = ref->f.data[plane] + 8 * (x + y * stride);
                 int v   = s->dsp.frame_skip_cmp[1](s, dptr, rptr, stride, 8);
@@ -1093,7 +1059,6 @@ static int estimate_best_b_count(MpegEncContext *s)
 {
     AVCodec *codec    = avcodec_find_encoder(s->avctx->codec_id);
     AVCodecContext *c = avcodec_alloc_context3(NULL);
-    AVFrame input[FF_MAX_B_FRAMES + 2];
     const int scale = s->avctx->brd_scale;
     int i, j, out_size, p_lambda, b_lambda, lambda2;
     int64_t best_rd  = INT64_MAX;
@@ -1128,35 +1093,25 @@ static int estimate_best_b_count(MpegEncContext *s)
         return -1;
 
     for (i = 0; i < s->max_b_frames + 2; i++) {
-        int ysize = c->width * c->height;
-        int csize = (c->width / 2) * (c->height / 2);
         Picture pre_input, *pre_input_ptr = i ? s->input_picture[i - 1] :
                                                 s->next_picture_ptr;
 
-        avcodec_get_frame_defaults(&input[i]);
-        input[i].data[0]     = av_malloc(ysize + 2 * csize);
-        input[i].data[1]     = input[i].data[0] + ysize;
-        input[i].data[2]     = input[i].data[1] + csize;
-        input[i].linesize[0] = c->width;
-        input[i].linesize[1] =
-        input[i].linesize[2] = c->width / 2;
-
         if (pre_input_ptr && (!i || s->input_picture[i - 1])) {
             pre_input = *pre_input_ptr;
 
-            if (pre_input.f.type != FF_BUFFER_TYPE_SHARED && i) {
+            if (!pre_input.shared && i) {
                 pre_input.f.data[0] += INPLACE_OFFSET;
                 pre_input.f.data[1] += INPLACE_OFFSET;
                 pre_input.f.data[2] += INPLACE_OFFSET;
             }
 
-            s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0],
+            s->dsp.shrink[scale](s->tmp_frames[i]->data[0], s->tmp_frames[i]->linesize[0],
                                  pre_input.f.data[0], pre_input.f.linesize[0],
                                  c->width,      c->height);
-            s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1],
+            s->dsp.shrink[scale](s->tmp_frames[i]->data[1], s->tmp_frames[i]->linesize[1],
                                  pre_input.f.data[1], pre_input.f.linesize[1],
                                  c->width >> 1, c->height >> 1);
-            s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2],
+            s->dsp.shrink[scale](s->tmp_frames[i]->data[2], s->tmp_frames[i]->linesize[2],
                                  pre_input.f.data[2], pre_input.f.linesize[2],
                                  c->width >> 1, c->height >> 1);
         }
@@ -1170,21 +1125,21 @@ static int estimate_best_b_count(MpegEncContext *s)
 
         c->error[0] = c->error[1] = c->error[2] = 0;
 
-        input[0].pict_type = AV_PICTURE_TYPE_I;
-        input[0].quality   = 1 * FF_QP2LAMBDA;
+        s->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I;
+        s->tmp_frames[0]->quality   = 1 * FF_QP2LAMBDA;
 
-        out_size = encode_frame(c, &input[0]);
+        out_size = encode_frame(c, s->tmp_frames[0]);
 
         //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT;
 
         for (i = 0; i < s->max_b_frames + 1; i++) {
             int is_p = i % (j + 1) == j || i == s->max_b_frames;
 
-            input[i + 1].pict_type = is_p ?
+            s->tmp_frames[i + 1]->pict_type = is_p ?
                                      AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B;
-            input[i + 1].quality   = is_p ? p_lambda : b_lambda;
+            s->tmp_frames[i + 1]->quality   = is_p ? p_lambda : b_lambda;
 
-            out_size = encode_frame(c, &input[i + 1]);
+            out_size = encode_frame(c, s->tmp_frames[i + 1]);
 
             rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);
         }
@@ -1206,16 +1161,12 @@ static int estimate_best_b_count(MpegEncContext *s)
     avcodec_close(c);
     av_freep(&c);
 
-    for (i = 0; i < s->max_b_frames + 2; i++) {
-        av_freep(&input[i].data[0]);
-    }
-
     return best_b_count;
 }
 
 static int select_input_picture(MpegEncContext *s)
 {
-    int i;
+    int i, ret;
 
     for (i = 1; i < MAX_PICTURE_COUNT; i++)
         s->reordered_input_picture[i - 1] = s->reordered_input_picture[i];
@@ -1236,17 +1187,7 @@ static int select_input_picture(MpegEncContext *s)
                 if (s->picture_in_gop_number < s->gop_size &&
                     skip_check(s, s->input_picture[0], s->next_picture_ptr)) {
                     // FIXME check that te gop check above is +-1 correct
-                    if (s->input_picture[0]->f.type == FF_BUFFER_TYPE_SHARED) {
-                        for (i = 0; i < 4; i++)
-                            s->input_picture[0]->f.data[i] = NULL;
-                        s->input_picture[0]->f.type = 0;
-                    } else {
-                        assert(s->input_picture[0]->f.type == FF_BUFFER_TYPE_USER ||
-                               s->input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL);
-
-                        s->avctx->release_buffer(s->avctx,
-                                                 &s->input_picture[0]->f);
-                    }
+                    av_frame_unref(&s->input_picture[0]->f);
 
                     emms_c();
                     ff_vbv_update(s, 0);
@@ -1350,14 +1291,15 @@ static int select_input_picture(MpegEncContext *s)
     }
 no_output_pic:
     if (s->reordered_input_picture[0]) {
-        s->reordered_input_picture[0]->f.reference =
+        s->reordered_input_picture[0]->reference =
            s->reordered_input_picture[0]->f.pict_type !=
                AV_PICTURE_TYPE_B ? 3 : 0;
 
-        ff_copy_picture(&s->new_picture, s->reordered_input_picture[0]);
+        ff_mpeg_unref_picture(s, &s->new_picture);
+        if ((ret = ff_mpeg_ref_picture(s, &s->new_picture, s->reordered_input_picture[0])))
+            return ret;
 
-        if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_SHARED ||
-            s->avctx->rc_buffer_size) {
+        if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) {
             // input is a shared pix, so we can't modifiy it -> alloc a new
             // one & ensure that the shared one is reuseable
 
@@ -1367,45 +1309,82 @@ no_output_pic:
                 return i;
             pic = &s->picture[i];
 
-            pic->f.reference = s->reordered_input_picture[0]->f.reference;
+            pic->reference = s->reordered_input_picture[0]->reference;
             if (ff_alloc_picture(s, pic, 0) < 0) {
                 return -1;
             }
 
-            /* mark us unused / free shared pic */
-            if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL)
-                s->avctx->release_buffer(s->avctx,
-                                         &s->reordered_input_picture[0]->f);
-            for (i = 0; i < 4; i++)
-                s->reordered_input_picture[0]->f.data[i] = NULL;
-            s->reordered_input_picture[0]->f.type = 0;
+            ret = av_frame_copy_props(&pic->f, &s->reordered_input_picture[0]->f);
+            if (ret < 0)
+                return ret;
 
-            copy_picture_attributes(s, &pic->f,
-                                    &s->reordered_input_picture[0]->f);
+            /* mark us unused / free shared pic */
+            av_frame_unref(&s->reordered_input_picture[0]->f);
+            s->reordered_input_picture[0]->shared = 0;
 
             s->current_picture_ptr = pic;
         } else {
             // input is not a shared pix -> reuse buffer for current_pix
-
-            assert(s->reordered_input_picture[0]->f.type ==
-                       FF_BUFFER_TYPE_USER ||
-                   s->reordered_input_picture[0]->f.type ==
-                       FF_BUFFER_TYPE_INTERNAL);
-
             s->current_picture_ptr = s->reordered_input_picture[0];
             for (i = 0; i < 4; i++) {
                 s->new_picture.f.data[i] += INPLACE_OFFSET;
             }
         }
-        ff_copy_picture(&s->current_picture, s->current_picture_ptr);
+        ff_mpeg_unref_picture(s, &s->current_picture);
+        if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,
+                                       s->current_picture_ptr)) < 0)
+            return ret;
 
         s->picture_number = s->new_picture.f.display_picture_number;
     } else {
-        memset(&s->new_picture, 0, sizeof(Picture));
+        ff_mpeg_unref_picture(s, &s->new_picture);
     }
     return 0;
 }
 
+static void frame_end(MpegEncContext *s)
+{
+    int i;
+
+    if (s->unrestricted_mv &&
+        s->current_picture.reference &&
+        !s->intra_only) {
+        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);
+    }
+
+    emms_c();
+
+    s->last_pict_type                 = s->pict_type;
+    s->last_lambda_for [s->pict_type] = s->current_picture_ptr->f.quality;
+    if (s->pict_type!= AV_PICTURE_TYPE_B)
+        s->last_non_b_pict_type = s->pict_type;
+
+    if (s->encoding) {
+        /* release non-reference frames */
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            if (!s->picture[i].reference)
+                ff_mpeg_unref_picture(s, &s->picture[i]);
+        }
+    }
+
+    s->avctx->coded_frame = &s->current_picture_ptr->f;
+
+}
+
 int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
                           const AVFrame *pic_arg, int *got_packet)
 {
@@ -1461,10 +1440,10 @@ vbv_retry:
         avctx->p_count     = s->mb_num - s->i_count - s->skip_count;
         avctx->skip_count  = s->skip_count;
 
-        ff_MPV_frame_end(s);
+        frame_end(s);
 
         if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)
-            ff_mjpeg_encode_picture_trailer(s);
+            ff_mjpeg_encode_picture_trailer(&s->pb, s->header_bits);
 
         if (avctx->rc_buffer_size) {
             RateControlContext *rcc = &s->rc_context;
@@ -1625,7 +1604,7 @@ static inline void dct_single_coeff_elimination(MpegEncContext *s,
     int score = 0;
     int run = 0;
     int i;
-    DCTELEM *block = s->block[n];
+    int16_t *block = s->block[n];
     const int last_index = s->block_last_index[n];
     int skip_dc;
 
@@ -1665,7 +1644,7 @@ static inline void dct_single_coeff_elimination(MpegEncContext *s,
         s->block_last_index[n] = -1;
 }
 
-static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block,
+static inline void clip_coeffs(MpegEncContext *s, int16_t *block,
                                int last_index)
 {
     int i;
@@ -1729,14 +1708,14 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
                                                 int mb_block_count)
 {
     int16_t weight[8][64];
-    DCTELEM orig[8][64];
+    int16_t orig[8][64];
     const int mb_x = s->mb_x;
     const int mb_y = s->mb_y;
     int i;
     int skip_dct[8];
     int dct_offset = s->linesize * 8; // default for progressive frames
     uint8_t *ptr_y, *ptr_cb, *ptr_cr;
-    int wrap_y, wrap_c;
+    ptrdiff_t wrap_y, wrap_c;
 
     for (i = 0; i < mb_block_count; i++)
         skip_dct[i] = s->skipdct;
@@ -1749,7 +1728,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
         update_qscale(s);
 
         if (!(s->mpv_flags & FF_MPV_FLAG_QP_RD)) {
-            s->qscale = s->current_picture_ptr->f.qscale_table[mb_xy];
+            s->qscale = s->current_picture_ptr->qscale_table[mb_xy];
             s->dquant = s->qscale - last_qp;
 
             if (s->out_format == FMT_H263) {
@@ -1782,15 +1761,19 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
 
     if (mb_x * 16 + 16 > s->width || mb_y * 16 + 16 > s->height) {
         uint8_t *ebuf = s->edge_emu_buffer + 32;
-        s->vdsp.emulated_edge_mc(ebuf, ptr_y, wrap_y, 16, 16, mb_x * 16,
-                                 mb_y * 16, s->width, s->height);
+        s->vdsp.emulated_edge_mc(ebuf, ptr_y,
+                                 wrap_y, wrap_y,
+                                 16, 16, mb_x * 16, mb_y * 16,
+                                 s->width, s->height);
         ptr_y = ebuf;
-        s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb, wrap_c, 8,
-                                 mb_block_height, mb_x * 8, mb_y * 8,
+        s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb,
+                                 wrap_c, wrap_c,
+                                 8, mb_block_height, mb_x * 8, mb_y * 8,
                                  s->width >> 1, s->height >> 1);
         ptr_cb = ebuf + 18 * wrap_y;
-        s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y + 8, ptr_cr, wrap_c, 8,
-                                 mb_block_height, mb_x * 8, mb_y * 8,
+        s->vdsp.emulated_edge_mc(ebuf + 18 * wrap_y + 8, ptr_cr,
+                                 wrap_c, wrap_c,
+                                 8, mb_block_height, mb_x * 8, mb_y * 8,
                                  s->width >> 1, s->height >> 1);
         ptr_cr = ebuf + 18 * wrap_y + 8;
     }
@@ -1849,10 +1832,10 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
         dest_cr = s->dest[2];
 
         if ((!s->no_rounding) || s->pict_type == AV_PICTURE_TYPE_B) {
-            op_pix  = s->dsp.put_pixels_tab;
+            op_pix  = s->hdsp.put_pixels_tab;
             op_qpix = s->dsp.put_qpel_pixels_tab;
         } else {
-            op_pix  = s->dsp.put_no_rnd_pixels_tab;
+            op_pix  = s->hdsp.put_no_rnd_pixels_tab;
             op_qpix = s->dsp.put_no_rnd_qpel_pixels_tab;
         }
 
@@ -1860,7 +1843,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
             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_pix  = s->hdsp.avg_pixels_tab;
             op_qpix = s->dsp.avg_qpel_pixels_tab;
         }
         if (s->mv_dir & MV_DIR_BACKWARD) {
@@ -1979,7 +1962,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
                 get_visual_weight(weight[7], ptr_cr + (dct_offset >> 1),
                                   wrap_c);
         }
-        memcpy(orig[0], s->block[0], sizeof(DCTELEM) * 64 * mb_block_count);
+        memcpy(orig[0], s->block[0], sizeof(int16_t) * 64 * mb_block_count);
     }
 
     /* DCT & quantize */
@@ -2515,9 +2498,9 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     assert((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){
+                    if (s->error_rate && s->resync_mb_x + s->resync_mb_y > 0) {
                         int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y;
-                        int d= 100 / s->avctx->error_rate;
+                        int d = 100 / s->error_rate;
                         if(r % d == 0){
                             current_packet_size=0;
                             s->pb.buf_ptr= s->ptr_lastgob;
@@ -2623,8 +2606,8 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     s->mv_type = MV_TYPE_8X8;
                     s->mb_intra= 0;
                     for(i=0; i<4; i++){
-                        s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
-                        s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
+                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
+                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
                     }
                     encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
@@ -2716,7 +2699,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     if(best_s.mv_type==MV_TYPE_16X16){ //FIXME move 4mv after QPRD
                         const int last_qp= backup_s.qscale;
                         int qpi, qp, dc[6];
-                        DCTELEM ac[6][16];
+                        int16_t ac[6][16];
                         const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0;
                         static const int dquant_tab[4]={-1,1,-2,2};
 
@@ -2741,7 +2724,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                             if(s->mb_intra && s->dc_val[0]){
                                 for(i=0; i<6; i++){
                                     dc[i]= s->dc_val[0][ s->block_index[i] ];
-                                    memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(DCTELEM)*16);
+                                    memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(int16_t)*16);
                                 }
                             }
 
@@ -2751,7 +2734,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                                 if(s->mb_intra && s->dc_val[0]){
                                     for(i=0; i<6; i++){
                                         s->dc_val[0][ s->block_index[i] ]= dc[i];
-                                        memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(DCTELEM)*16);
+                                        memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(int16_t)*16);
                                     }
                                 }
                             }
@@ -2810,7 +2793,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     }
                 }
 
-                s->current_picture.f.qscale_table[xy] = best_s.qscale;
+                s->current_picture.qscale_table[xy] = best_s.qscale;
 
                 copy_context_after_encode(s, &best_s, -1);
 
@@ -2837,9 +2820,9 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     ff_h263_update_motion_val(s);
 
                 if(next_block==0){ //FIXME 16 vs linesize16
-                    s->dsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad                     , s->linesize  ,16);
-                    s->dsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize    , s->uvlinesize, 8);
-                    s->dsp.put_pixels_tab[1][0](s->dest[2], s->rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8);
+                    s->hdsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad                     , s->linesize  ,16);
+                    s->hdsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize    , s->uvlinesize, 8);
+                    s->hdsp.put_pixels_tab[1][0](s->dest[2], s->rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8);
                 }
 
                 if(s->avctx->mb_decision == FF_MB_DECISION_BITS)
@@ -2877,8 +2860,8 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     s->mv_type = MV_TYPE_8X8;
                     s->mb_intra= 0;
                     for(i=0; i<4; i++){
-                        s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
-                        s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
+                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
+                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
                     }
                     break;
                 case CANDIDATE_MB_TYPE_DIRECT:
@@ -3035,7 +3018,7 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src)
     MERGE(b_count);
     MERGE(skip_count);
     MERGE(misc_bits);
-    MERGE(error_count);
+    MERGE(er.error_count);
     MERGE(padding_bug_score);
     MERGE(current_picture.f.error[0]);
     MERGE(current_picture.f.error[1]);
@@ -3162,7 +3145,7 @@ static int encode_picture(MpegEncContext *s, int picture_number)
     if(s->pict_type != AV_PICTURE_TYPE_I){
         s->lambda = (s->lambda * s->avctx->me_penalty_compensation + 128)>>8;
         s->lambda2= (s->lambda2* (int64_t)s->avctx->me_penalty_compensation + 128)>>8;
-        if(s->pict_type != AV_PICTURE_TYPE_B && s->avctx->me_threshold==0){
+        if (s->pict_type != AV_PICTURE_TYPE_B) {
             if((s->avctx->pre_me && s->last_non_b_pict_type==AV_PICTURE_TYPE_I) || s->avctx->pre_me==2){
                 s->avctx->execute(s->avctx, pre_estimate_motion_thread, &s->thread_context[0], NULL, context_count, sizeof(void*));
             }
@@ -3282,7 +3265,8 @@ static int encode_picture(MpegEncContext *s, int picture_number)
     switch(s->out_format) {
     case FMT_MJPEG:
         if (CONFIG_MJPEG_ENCODER)
-            ff_mjpeg_encode_picture_header(s);
+            ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable,
+                                           s->intra_matrix);
         break;
     case FMT_H261:
         if (CONFIG_H261_ENCODER)
@@ -3308,8 +3292,6 @@ static int encode_picture(MpegEncContext *s, int picture_number)
         if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
             ff_mpeg1_encode_picture_header(s, picture_number);
         break;
-    case FMT_H264:
-        break;
     default:
         assert(0);
     }
@@ -3327,7 +3309,7 @@ static int encode_picture(MpegEncContext *s, int picture_number)
     return 0;
 }
 
-static void denoise_dct_c(MpegEncContext *s, DCTELEM *block){
+static void denoise_dct_c(MpegEncContext *s, int16_t *block){
     const int intra= s->mb_intra;
     int i;
 
@@ -3352,7 +3334,7 @@ static void denoise_dct_c(MpegEncContext *s, DCTELEM *block){
 }
 
 static int dct_quantize_trellis_c(MpegEncContext *s,
-                                  DCTELEM *block, int n,
+                                  int16_t *block, int n,
                                   int qscale, int *overflow){
     const int *qmat;
     const uint8_t *scantable= s->intra_scantable.scantable;
@@ -3459,7 +3441,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
     *overflow= s->max_qcoeff < max; //overflow might have happened
 
     if(last_non_zero < start_i){
-        memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM));
+        memset(block + start_i, 0, (64-start_i)*sizeof(int16_t));
         return last_non_zero;
     }
 
@@ -3591,7 +3573,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
 
     dc= FFABS(block[0]);
     last_non_zero= last_i - 1;
-    memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM));
+    memset(block + start_i, 0, (64-start_i)*sizeof(int16_t));
 
     if(last_non_zero < start_i)
         return last_non_zero;
@@ -3666,10 +3648,10 @@ static void build_basis(uint8_t *perm){
 }
 
 static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
-                        DCTELEM *block, int16_t *weight, DCTELEM *orig,
+                        int16_t *block, int16_t *weight, int16_t *orig,
                         int n, int qscale){
     int16_t rem[64];
-    LOCAL_ALIGNED_16(DCTELEM, d1, [64]);
+    LOCAL_ALIGNED_16(int16_t, d1, [64]);
     const uint8_t *scantable= s->intra_scantable.scantable;
     const uint8_t *perm_scantable= s->intra_scantable.permutated;
 //    unsigned int threshold1, threshold2;
@@ -4039,7 +4021,7 @@ STOP_TIMER("iterative search")
 }
 
 int ff_dct_quantize_c(MpegEncContext *s,
-                        DCTELEM *block, int n,
+                        int16_t *block, int n,
                         int qscale, int *overflow)
 {
     int i, j, level, last_non_zero, q, start_i;
@@ -4137,6 +4119,7 @@ static const AVClass h263_class = {
 
 AVCodec ff_h263_encoder = {
     .name           = "h263",
+    .long_name      = NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H263,
     .priv_data_size = sizeof(MpegEncContext),
@@ -4144,7 +4127,6 @@ AVCodec ff_h263_encoder = {
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
     .pix_fmts= (const enum AVPixelFormat[]){AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE},
-    .long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"),
     .priv_class     = &h263_class,
 };
 
@@ -4165,6 +4147,7 @@ static const AVClass h263p_class = {
 
 AVCodec ff_h263p_encoder = {
     .name           = "h263p",
+    .long_name      = NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H263P,
     .priv_data_size = sizeof(MpegEncContext),
@@ -4173,7 +4156,6 @@ AVCodec ff_h263p_encoder = {
     .close          = ff_MPV_encode_end,
     .capabilities   = CODEC_CAP_SLICE_THREADS,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"),
     .priv_class     = &h263p_class,
 };
 
@@ -4181,6 +4163,7 @@ FF_MPV_GENERIC_CLASS(msmpeg4v2)
 
 AVCodec ff_msmpeg4v2_encoder = {
     .name           = "msmpeg4v2",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MSMPEG4V2,
     .priv_data_size = sizeof(MpegEncContext),
@@ -4188,7 +4171,6 @@ AVCodec ff_msmpeg4v2_encoder = {
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
     .priv_class     = &msmpeg4v2_class,
 };
 
@@ -4196,6 +4178,7 @@ FF_MPV_GENERIC_CLASS(msmpeg4v3)
 
 AVCodec ff_msmpeg4v3_encoder = {
     .name           = "msmpeg4",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MSMPEG4V3,
     .priv_data_size = sizeof(MpegEncContext),
@@ -4203,7 +4186,6 @@ AVCodec ff_msmpeg4v3_encoder = {
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
     .priv_class     = &msmpeg4v3_class,
 };
 
@@ -4211,6 +4193,7 @@ FF_MPV_GENERIC_CLASS(wmv1)
 
 AVCodec ff_wmv1_encoder = {
     .name           = "wmv1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WMV1,
     .priv_data_size = sizeof(MpegEncContext),
@@ -4218,6 +4201,5 @@ AVCodec ff_wmv1_encoder = {
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
     .priv_class     = &wmv1_class,
 };
diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index a432763..fafbaa9 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -22,8 +22,11 @@
  */
 
 #include <string.h>
+
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "dsputil.h"
+#include "h261.h"
 #include "mpegvideo.h"
 #include "mjpegenc.h"
 #include "msmpeg4.h"
@@ -34,85 +37,100 @@ static void gmc1_motion(MpegEncContext *s,
                         uint8_t **ref_picture)
 {
     uint8_t *ptr;
-    int offset, src_x, src_y, linesize, uvlinesize;
-    int motion_x, motion_y;
-    int emu=0;
-
-    motion_x= s->sprite_offset[0][0];
-    motion_y= s->sprite_offset[0][1];
-    src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy+1));
-    src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy+1));
-    motion_x<<=(3-s->sprite_warping_accuracy);
-    motion_y<<=(3-s->sprite_warping_accuracy);
-    src_x = av_clip(src_x, -16, s->width);
+    int src_x, src_y, motion_x, motion_y;
+    ptrdiff_t offset, linesize, uvlinesize;
+    int emu = 0;
+
+    motion_x   = s->sprite_offset[0][0];
+    motion_y   = s->sprite_offset[0][1];
+    src_x      = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));
+    src_y      = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));
+    motion_x <<= (3 - s->sprite_warping_accuracy);
+    motion_y <<= (3 - s->sprite_warping_accuracy);
+    src_x      = av_clip(src_x, -16, s->width);
     if (src_x == s->width)
-        motion_x =0;
+        motion_x = 0;
     src_y = av_clip(src_y, -16, s->height);
     if (src_y == s->height)
-        motion_y =0;
+        motion_y = 0;
 
-    linesize = s->linesize;
+    linesize   = s->linesize;
     uvlinesize = s->uvlinesize;
 
-    ptr = ref_picture[0] + (src_y * linesize) + src_x;
-
-    if(s->flags&CODEC_FLAG_EMU_EDGE){
-        if(   (unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0)
-           || (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)){
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
-            ptr= s->edge_emu_buffer;
+    ptr = ref_picture[0] + src_y * linesize + src_x;
+
+    if (s->flags & CODEC_FLAG_EMU_EDGE) {
+        if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||
+            (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                                     linesize, linesize,
+                                     17, 17,
+                                     src_x, src_y,
+                                     s->h_edge_pos, s->v_edge_pos);
+            ptr = s->edge_emu_buffer;
         }
     }
 
-    if((motion_x|motion_y)&7){
-        s->dsp.gmc1(dest_y  , ptr  , linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
-        s->dsp.gmc1(dest_y+8, ptr+8, linesize, 16, motion_x&15, motion_y&15, 128 - s->no_rounding);
-    }else{
+    if ((motion_x | motion_y) & 7) {
+        s->dsp.gmc1(dest_y, ptr, linesize, 16,
+                    motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+        s->dsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,
+                    motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+    } else {
         int dxy;
 
-        dxy= ((motion_x>>3)&1) | ((motion_y>>2)&2);
-        if (s->no_rounding){
-            s->dsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
-        }else{
-            s->dsp.put_pixels_tab       [0][dxy](dest_y, ptr, linesize, 16);
+        dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);
+        if (s->no_rounding) {
+            s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
+        } else {
+            s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
         }
     }
 
-    if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return;
-
-    motion_x= s->sprite_offset[1][0];
-    motion_y= s->sprite_offset[1][1];
-    src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy+1));
-    src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy+1));
-    motion_x<<=(3-s->sprite_warping_accuracy);
-    motion_y<<=(3-s->sprite_warping_accuracy);
-    src_x = av_clip(src_x, -8, s->width>>1);
-    if (src_x == s->width>>1)
-        motion_x =0;
-    src_y = av_clip(src_y, -8, s->height>>1);
-    if (src_y == s->height>>1)
-        motion_y =0;
+    if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY)
+        return;
+
+    motion_x   = s->sprite_offset[1][0];
+    motion_y   = s->sprite_offset[1][1];
+    src_x      = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));
+    src_y      = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));
+    motion_x <<= (3 - s->sprite_warping_accuracy);
+    motion_y <<= (3 - s->sprite_warping_accuracy);
+    src_x      = av_clip(src_x, -8, s->width >> 1);
+    if (src_x == s->width >> 1)
+        motion_x = 0;
+    src_y = av_clip(src_y, -8, s->height >> 1);
+    if (src_y == s->height >> 1)
+        motion_y = 0;
 
     offset = (src_y * uvlinesize) + src_x;
-    ptr = ref_picture[1] + offset;
-    if(s->flags&CODEC_FLAG_EMU_EDGE){
-        if(   (unsigned)src_x >= FFMAX((s->h_edge_pos>>1) - 9, 0)
-           || (unsigned)src_y >= FFMAX((s->v_edge_pos>>1) - 9, 0)){
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
-            ptr= s->edge_emu_buffer;
-            emu=1;
+    ptr    = ref_picture[1] + offset;
+    if (s->flags & CODEC_FLAG_EMU_EDGE) {
+        if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||
+            (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                                     uvlinesize, uvlinesize,
+                                     9, 9,
+                                     src_x, src_y,
+                                     s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+            ptr = s->edge_emu_buffer;
+            emu = 1;
         }
     }
-    s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
+    s->dsp.gmc1(dest_cb, ptr, uvlinesize, 8,
+                motion_x & 15, motion_y & 15, 128 - s->no_rounding);
 
     ptr = ref_picture[2] + offset;
-    if(emu){
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
-        ptr= s->edge_emu_buffer;
+    if (emu) {
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                                 uvlinesize, uvlinesize,
+                                 9, 9,
+                                 src_x, src_y,
+                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+        ptr = s->edge_emu_buffer;
     }
-    s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
-
-    return;
+    s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8,
+                motion_x & 15, motion_y & 15, 128 - s->no_rounding);
 }
 
 static void gmc_motion(MpegEncContext *s,
@@ -121,70 +139,72 @@ static void gmc_motion(MpegEncContext *s,
 {
     uint8_t *ptr;
     int linesize, uvlinesize;
-    const int a= s->sprite_warping_accuracy;
+    const int a = s->sprite_warping_accuracy;
     int ox, oy;
 
-    linesize = s->linesize;
+    linesize   = s->linesize;
     uvlinesize = s->uvlinesize;
 
     ptr = ref_picture[0];
 
-    ox= s->sprite_offset[0][0] + s->sprite_delta[0][0]*s->mb_x*16 + s->sprite_delta[0][1]*s->mb_y*16;
-    oy= s->sprite_offset[0][1] + s->sprite_delta[1][0]*s->mb_x*16 + s->sprite_delta[1][1]*s->mb_y*16;
+    ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +
+         s->sprite_delta[0][1] * s->mb_y * 16;
+    oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +
+         s->sprite_delta[1][1] * s->mb_y * 16;
 
     s->dsp.gmc(dest_y, ptr, linesize, 16,
-           ox,
-           oy,
-           s->sprite_delta[0][0], s->sprite_delta[0][1],
-           s->sprite_delta[1][0], s->sprite_delta[1][1],
-           a+1, (1<<(2*a+1)) - s->no_rounding,
-           s->h_edge_pos, s->v_edge_pos);
-    s->dsp.gmc(dest_y+8, ptr, linesize, 16,
-           ox + s->sprite_delta[0][0]*8,
-           oy + s->sprite_delta[1][0]*8,
-           s->sprite_delta[0][0], s->sprite_delta[0][1],
-           s->sprite_delta[1][0], s->sprite_delta[1][1],
-           a+1, (1<<(2*a+1)) - s->no_rounding,
-           s->h_edge_pos, s->v_edge_pos);
-
-    if(CONFIG_GRAY && s->flags&CODEC_FLAG_GRAY) return;
-
-    ox= s->sprite_offset[1][0] + s->sprite_delta[0][0]*s->mb_x*8 + s->sprite_delta[0][1]*s->mb_y*8;
-    oy= s->sprite_offset[1][1] + s->sprite_delta[1][0]*s->mb_x*8 + s->sprite_delta[1][1]*s->mb_y*8;
+               ox, oy,
+               s->sprite_delta[0][0], s->sprite_delta[0][1],
+               s->sprite_delta[1][0], s->sprite_delta[1][1],
+               a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+               s->h_edge_pos, s->v_edge_pos);
+    s->dsp.gmc(dest_y + 8, ptr, linesize, 16,
+               ox + s->sprite_delta[0][0] * 8,
+               oy + s->sprite_delta[1][0] * 8,
+               s->sprite_delta[0][0], s->sprite_delta[0][1],
+               s->sprite_delta[1][0], s->sprite_delta[1][1],
+               a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+               s->h_edge_pos, s->v_edge_pos);
+
+    if (CONFIG_GRAY && s->flags & CODEC_FLAG_GRAY)
+        return;
+
+    ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +
+         s->sprite_delta[0][1] * s->mb_y * 8;
+    oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +
+         s->sprite_delta[1][1] * s->mb_y * 8;
 
     ptr = ref_picture[1];
     s->dsp.gmc(dest_cb, ptr, uvlinesize, 8,
-           ox,
-           oy,
-           s->sprite_delta[0][0], s->sprite_delta[0][1],
-           s->sprite_delta[1][0], s->sprite_delta[1][1],
-           a+1, (1<<(2*a+1)) - s->no_rounding,
-           s->h_edge_pos>>1, s->v_edge_pos>>1);
+               ox, oy,
+               s->sprite_delta[0][0], s->sprite_delta[0][1],
+               s->sprite_delta[1][0], s->sprite_delta[1][1],
+               a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+               s->h_edge_pos >> 1, s->v_edge_pos >> 1);
 
     ptr = ref_picture[2];
     s->dsp.gmc(dest_cr, ptr, uvlinesize, 8,
-           ox,
-           oy,
-           s->sprite_delta[0][0], s->sprite_delta[0][1],
-           s->sprite_delta[1][0], s->sprite_delta[1][1],
-           a+1, (1<<(2*a+1)) - s->no_rounding,
-           s->h_edge_pos>>1, s->v_edge_pos>>1);
+               ox, oy,
+               s->sprite_delta[0][0], s->sprite_delta[0][1],
+               s->sprite_delta[1][0], s->sprite_delta[1][1],
+               a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+               s->h_edge_pos >> 1, s->v_edge_pos >> 1);
 }
 
 static inline int hpel_motion(MpegEncContext *s,
-                                  uint8_t *dest, uint8_t *src,
-                                  int src_x, int src_y,
-                                  op_pixels_func *pix_op,
-                                  int motion_x, int motion_y)
+                              uint8_t *dest, uint8_t *src,
+                              int src_x, int src_y,
+                              op_pixels_func *pix_op,
+                              int motion_x, int motion_y)
 {
     int dxy = 0;
-    int emu=0;
+    int emu = 0;
 
     src_x += motion_x >> 1;
     src_y += motion_y >> 1;
 
     /* WARNING: do no forget half pels */
-    src_x = av_clip(src_x, -16, s->width); //FIXME unneeded for emu?
+    src_x = av_clip(src_x, -16, s->width); // FIXME unneeded for emu?
     if (src_x != s->width)
         dxy |= motion_x & 1;
     src_y = av_clip(src_y, -16, s->height);
@@ -192,13 +212,16 @@ static inline int hpel_motion(MpegEncContext *s,
         dxy |= (motion_y & 1) << 1;
     src += src_y * s->linesize + src_x;
 
-    if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
-        if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&1) - 8, 0)
-           || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&1) - 8, 0)){
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, 9, 9,
-                             src_x, src_y, s->h_edge_pos, s->v_edge_pos);
-            src= s->edge_emu_buffer;
-            emu=1;
+    if (s->unrestricted_mv && (s->flags & CODEC_FLAG_EMU_EDGE)) {
+        if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 8, 0) ||
+            (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 1) - 8, 0)) {
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src,
+                                     s->linesize, s->linesize,
+                                     9, 9,
+                                     src_x, src_y, s->h_edge_pos,
+                                     s->v_edge_pos);
+            src = s->edge_emu_buffer;
+            emu = 1;
         }
     }
     pix_op[dxy](dest, src, s->linesize, 8);
@@ -207,10 +230,19 @@ static inline int hpel_motion(MpegEncContext *s,
 
 static av_always_inline
 void mpeg_motion_internal(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, op_pixels_func (*pix_op)[4],
-                 int motion_x, int motion_y, int h, int is_mpeg12, int mb_y)
+                          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,
+                          op_pixels_func (*pix_op)[4],
+                          int motion_x,
+                          int motion_y,
+                          int h,
+                          int is_mpeg12,
+                          int mb_y)
 {
     uint8_t *ptr_y, *ptr_cb, *ptr_cr;
     int dxy, uvdxy, mx, my, src_x, src_y,
@@ -218,56 +250,56 @@ void mpeg_motion_internal(MpegEncContext *s,
     ptrdiff_t uvlinesize, linesize;
 
 #if 0
-if(s->quarter_sample)
-{
-    motion_x>>=1;
-    motion_y>>=1;
-}
+    if (s->quarter_sample) {
+        motion_x >>= 1;
+        motion_y >>= 1;
+    }
 #endif
 
     v_edge_pos = s->v_edge_pos >> field_based;
     linesize   = s->current_picture.f.linesize[0] << field_based;
     uvlinesize = s->current_picture.f.linesize[1] << field_based;
 
-    dxy = ((motion_y & 1) << 1) | (motion_x & 1);
-    src_x = s->mb_x* 16               + (motion_x >> 1);
-    src_y =(   mb_y<<(4-field_based)) + (motion_y >> 1);
+    dxy   = ((motion_y & 1) << 1) | (motion_x & 1);
+    src_x = s->mb_x * 16 + (motion_x >> 1);
+    src_y = (mb_y << (4 - field_based)) + (motion_y >> 1);
 
     if (!is_mpeg12 && s->out_format == FMT_H263) {
-        if((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based){
-            mx = (motion_x>>1)|(motion_x&1);
-            my = motion_y >>1;
-            uvdxy = ((my & 1) << 1) | (mx & 1);
-            uvsrc_x = s->mb_x* 8               + (mx >> 1);
-            uvsrc_y =(   mb_y<<(3-field_based))+ (my >> 1);
-        }else{
-            uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
-            uvsrc_x = src_x>>1;
-            uvsrc_y = src_y>>1;
+        if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) {
+            mx      = (motion_x >> 1) | (motion_x & 1);
+            my      = motion_y >> 1;
+            uvdxy   = ((my & 1) << 1) | (mx & 1);
+            uvsrc_x = s->mb_x * 8 + (mx >> 1);
+            uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);
+        } else {
+            uvdxy   = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
+            uvsrc_x = src_x >> 1;
+            uvsrc_y = src_y >> 1;
         }
-    }else if(!is_mpeg12 && s->out_format == FMT_H261){//even chroma mv's are full pel in H261
-        mx = motion_x / 4;
-        my = motion_y / 4;
-        uvdxy = 0;
-        uvsrc_x = s->mb_x*8 + mx;
-        uvsrc_y =    mb_y*8 + my;
+    // Even chroma mv's are full pel in H261
+    } else if (!is_mpeg12 && s->out_format == FMT_H261) {
+        mx      = motion_x / 4;
+        my      = motion_y / 4;
+        uvdxy   = 0;
+        uvsrc_x = s->mb_x * 8 + mx;
+        uvsrc_y = mb_y * 8 + my;
     } else {
-        if(s->chroma_y_shift){
-            mx = motion_x / 2;
-            my = motion_y / 2;
-            uvdxy = ((my & 1) << 1) | (mx & 1);
-            uvsrc_x = s->mb_x* 8               + (mx >> 1);
-            uvsrc_y =(   mb_y<<(3-field_based))+ (my >> 1);
+        if (s->chroma_y_shift) {
+            mx      = motion_x / 2;
+            my      = motion_y / 2;
+            uvdxy   = ((my & 1) << 1) | (mx & 1);
+            uvsrc_x = s->mb_x * 8 + (mx >> 1);
+            uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);
         } else {
-            if(s->chroma_x_shift){
-            //Chroma422
-                mx = motion_x / 2;
-                uvdxy = ((motion_y & 1) << 1) | (mx & 1);
-                uvsrc_x = s->mb_x* 8           + (mx >> 1);
+            if (s->chroma_x_shift) {
+                // Chroma422
+                mx      = motion_x / 2;
+                uvdxy   = ((motion_y & 1) << 1) | (mx & 1);
+                uvsrc_x = s->mb_x * 8 + (mx >> 1);
                 uvsrc_y = src_y;
             } else {
-            //Chroma444
-                uvdxy = dxy;
+                // Chroma444
+                uvdxy   = dxy;
                 uvsrc_x = src_x;
                 uvsrc_y = src_y;
             }
@@ -278,58 +310,63 @@ if(s->quarter_sample)
     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(s->h_edge_pos - (motion_x&1) - 16, 0)
-       || (unsigned)src_y > FFMAX(   v_edge_pos - (motion_y&1) - h , 0)){
-            if(is_mpeg12 || s->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
-               s->codec_id == AV_CODEC_ID_MPEG1VIDEO){
-                av_log(s->avctx,AV_LOG_DEBUG,
-                        "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y);
-                return;
-            }
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
-                                17, 17+field_based,
-                                src_x, src_y<<field_based,
-                                s->h_edge_pos, s->v_edge_pos);
-            ptr_y = s->edge_emu_buffer;
-            if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
-                uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
-                s->vdsp.emulated_edge_mc(uvbuf ,
-                                    ptr_cb, s->uvlinesize,
-                                    9, 9+field_based,
-                                    uvsrc_x, uvsrc_y<<field_based,
-                                    s->h_edge_pos>>1, s->v_edge_pos>>1);
-                s->vdsp.emulated_edge_mc(uvbuf+16,
-                                    ptr_cr, s->uvlinesize,
-                                    9, 9+field_based,
-                                    uvsrc_x, uvsrc_y<<field_based,
-                                    s->h_edge_pos>>1, s->v_edge_pos>>1);
-                ptr_cb= uvbuf;
-                ptr_cr= uvbuf+16;
-            }
+    if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 16, 0) ||
+        (unsigned)src_y > FFMAX(v_edge_pos - (motion_y & 1) - h, 0)) {
+        if (is_mpeg12 ||
+            s->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
+            s->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+            av_log(s->avctx, AV_LOG_DEBUG,
+                   "MPEG motion vector out of boundary (%d %d)\n", src_x,
+                   src_y);
+            return;
+        }
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
+                                 s->linesize, s->linesize,
+                                 17, 17 + field_based,
+                                 src_x, src_y << field_based,
+                                 s->h_edge_pos, s->v_edge_pos);
+        ptr_y = s->edge_emu_buffer;
+        if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+            uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize;
+            s->vdsp.emulated_edge_mc(uvbuf, ptr_cb,
+                                     s->uvlinesize, s->uvlinesize,
+                                     9, 9 + field_based,
+                                     uvsrc_x, uvsrc_y << field_based,
+                                     s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+            s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr,
+                                     s->uvlinesize, s->uvlinesize,
+                                     9, 9 + field_based,
+                                     uvsrc_x, uvsrc_y << field_based,
+                                     s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+            ptr_cb = uvbuf;
+            ptr_cr = uvbuf + 16;
+        }
     }
 
-    if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data
-        dest_y += s->linesize;
-        dest_cb+= s->uvlinesize;
-        dest_cr+= s->uvlinesize;
+    /* FIXME use this for field pix too instead of the obnoxious hack which
+     * changes picture.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;
+    if (field_select) {
+        ptr_y  += s->linesize;
+        ptr_cb += s->uvlinesize;
+        ptr_cr += s->uvlinesize;
     }
 
     pix_op[0][dxy](dest_y, ptr_y, linesize, h);
 
-    if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+    if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
         pix_op[s->chroma_x_shift][uvdxy]
-                (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
+            (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
         pix_op[s->chroma_x_shift][uvdxy]
-                (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
+            (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
     }
-    if(!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&
-         s->out_format == FMT_H261){
+    if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&
+        s->out_format == FMT_H261) {
         ff_h261_loop_filter(s);
     }
 }
@@ -341,15 +378,15 @@ static void mpeg_motion(MpegEncContext *s,
                         int motion_x, int motion_y, int h, int mb_y)
 {
 #if !CONFIG_SMALL
-    if(s->out_format == FMT_MPEG1)
+    if (s->out_format == FMT_MPEG1)
         mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
-                    field_select, ref_picture, pix_op,
-                    motion_x, motion_y, h, 1, mb_y);
+                             field_select, ref_picture, pix_op,
+                             motion_x, motion_y, h, 1, mb_y);
     else
 #endif
         mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
-                    field_select, ref_picture, pix_op,
-                    motion_x, motion_y, h, 0, mb_y);
+                             field_select, ref_picture, pix_op,
+                             motion_x, motion_y, h, 0, mb_y);
 }
 
 static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y,
@@ -362,23 +399,24 @@ static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y,
 #if !CONFIG_SMALL
     if(s->out_format == FMT_MPEG1)
         mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
-                    bottom_field, field_select, ref_picture, pix_op,
-                    motion_x, motion_y, h, 1, mb_y);
+                             bottom_field, field_select, ref_picture, pix_op,
+                             motion_x, motion_y, h, 1, mb_y);
     else
 #endif
         mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
-                    bottom_field, field_select, ref_picture, pix_op,
-                    motion_x, motion_y, h, 0, mb_y);
+                             bottom_field, field_select, ref_picture, pix_op,
+                             motion_x, motion_y, h, 0, mb_y);
 }
 
-//FIXME move to dsputil, avg variant, 16x16 version
-static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){
+// FIXME move to dsputil, avg variant, 16x16 version
+static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride)
+{
     int x;
-    uint8_t * const top   = src[1];
-    uint8_t * const left  = src[2];
-    uint8_t * const mid   = src[0];
-    uint8_t * const right = src[3];
-    uint8_t * const bottom= src[4];
+    uint8_t *const top    = src[1];
+    uint8_t *const left   = src[2];
+    uint8_t *const mid    = src[0];
+    uint8_t *const right  = src[3];
+    uint8_t *const bottom = src[4];
 #define OBMC_FILTER(x, t, l, m, r, b)\
     dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3
 #define OBMC_FILTER4(x, t, l, m, r, b)\
@@ -387,40 +425,40 @@ static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride){
     OBMC_FILTER(x  +stride, t, l, m, r, b);\
     OBMC_FILTER(x+1+stride, t, l, m, r, b);
 
-    x=0;
-    OBMC_FILTER (x  , 2, 2, 4, 0, 0);
-    OBMC_FILTER (x+1, 2, 1, 5, 0, 0);
-    OBMC_FILTER4(x+2, 2, 1, 5, 0, 0);
-    OBMC_FILTER4(x+4, 2, 0, 5, 1, 0);
-    OBMC_FILTER (x+6, 2, 0, 5, 1, 0);
-    OBMC_FILTER (x+7, 2, 0, 4, 2, 0);
-    x+= stride;
-    OBMC_FILTER (x  , 1, 2, 5, 0, 0);
-    OBMC_FILTER (x+1, 1, 2, 5, 0, 0);
-    OBMC_FILTER (x+6, 1, 0, 5, 2, 0);
-    OBMC_FILTER (x+7, 1, 0, 5, 2, 0);
-    x+= stride;
-    OBMC_FILTER4(x  , 1, 2, 5, 0, 0);
-    OBMC_FILTER4(x+2, 1, 1, 6, 0, 0);
-    OBMC_FILTER4(x+4, 1, 0, 6, 1, 0);
-    OBMC_FILTER4(x+6, 1, 0, 5, 2, 0);
-    x+= 2*stride;
-    OBMC_FILTER4(x  , 0, 2, 5, 0, 1);
-    OBMC_FILTER4(x+2, 0, 1, 6, 0, 1);
-    OBMC_FILTER4(x+4, 0, 0, 6, 1, 1);
-    OBMC_FILTER4(x+6, 0, 0, 5, 2, 1);
-    x+= 2*stride;
-    OBMC_FILTER (x  , 0, 2, 5, 0, 1);
-    OBMC_FILTER (x+1, 0, 2, 5, 0, 1);
-    OBMC_FILTER4(x+2, 0, 1, 5, 0, 2);
-    OBMC_FILTER4(x+4, 0, 0, 5, 1, 2);
-    OBMC_FILTER (x+6, 0, 0, 5, 2, 1);
-    OBMC_FILTER (x+7, 0, 0, 5, 2, 1);
-    x+= stride;
-    OBMC_FILTER (x  , 0, 2, 4, 0, 2);
-    OBMC_FILTER (x+1, 0, 1, 5, 0, 2);
-    OBMC_FILTER (x+6, 0, 0, 5, 1, 2);
-    OBMC_FILTER (x+7, 0, 0, 4, 2, 2);
+    x = 0;
+    OBMC_FILTER (x    , 2, 2, 4, 0, 0);
+    OBMC_FILTER (x + 1, 2, 1, 5, 0, 0);
+    OBMC_FILTER4(x + 2, 2, 1, 5, 0, 0);
+    OBMC_FILTER4(x + 4, 2, 0, 5, 1, 0);
+    OBMC_FILTER (x + 6, 2, 0, 5, 1, 0);
+    OBMC_FILTER (x + 7, 2, 0, 4, 2, 0);
+    x += stride;
+    OBMC_FILTER (x    , 1, 2, 5, 0, 0);
+    OBMC_FILTER (x + 1, 1, 2, 5, 0, 0);
+    OBMC_FILTER (x + 6, 1, 0, 5, 2, 0);
+    OBMC_FILTER (x + 7, 1, 0, 5, 2, 0);
+    x += stride;
+    OBMC_FILTER4(x    , 1, 2, 5, 0, 0);
+    OBMC_FILTER4(x + 2, 1, 1, 6, 0, 0);
+    OBMC_FILTER4(x + 4, 1, 0, 6, 1, 0);
+    OBMC_FILTER4(x + 6, 1, 0, 5, 2, 0);
+    x += 2 * stride;
+    OBMC_FILTER4(x    , 0, 2, 5, 0, 1);
+    OBMC_FILTER4(x + 2, 0, 1, 6, 0, 1);
+    OBMC_FILTER4(x + 4, 0, 0, 6, 1, 1);
+    OBMC_FILTER4(x + 6, 0, 0, 5, 2, 1);
+    x += 2*stride;
+    OBMC_FILTER (x    , 0, 2, 5, 0, 1);
+    OBMC_FILTER (x + 1, 0, 2, 5, 0, 1);
+    OBMC_FILTER4(x + 2, 0, 1, 5, 0, 2);
+    OBMC_FILTER4(x + 4, 0, 0, 5, 1, 2);
+    OBMC_FILTER (x + 6, 0, 0, 5, 2, 1);
+    OBMC_FILTER (x + 7, 0, 0, 5, 2, 1);
+    x += stride;
+    OBMC_FILTER (x    , 0, 2, 4, 0, 2);
+    OBMC_FILTER (x + 1, 0, 1, 5, 0, 2);
+    OBMC_FILTER (x + 6, 0, 0, 5, 1, 2);
+    OBMC_FILTER (x + 7, 0, 0, 4, 2, 2);
 }
 
 /* obmc for 1 8x8 luma block */
@@ -428,22 +466,21 @@ static inline void obmc_motion(MpegEncContext *s,
                                uint8_t *dest, uint8_t *src,
                                int src_x, int src_y,
                                op_pixels_func *pix_op,
-                               int16_t mv[5][2]/* mid top left right bottom*/)
+                               int16_t mv[5][2] /* mid top left right bottom */)
 #define MID    0
 {
     int i;
     uint8_t *ptr[5];
 
-    assert(s->quarter_sample==0);
+    assert(s->quarter_sample == 0);
 
-    for(i=0; i<5; i++){
-        if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){
-            ptr[i]= ptr[MID];
-        }else{
-            ptr[i]= s->obmc_scratchpad + 8*(i&1) + s->linesize*8*(i>>1);
-            hpel_motion(s, ptr[i], src,
-                        src_x, src_y,
-                        pix_op,
+    for (i = 0; i < 5; i++) {
+        if (i && mv[i][0] == mv[MID][0] && mv[i][1] == mv[MID][1]) {
+            ptr[i] = ptr[MID];
+        } else {
+            ptr[i] = s->obmc_scratchpad + 8 * (i & 1) +
+                     s->linesize * 8 * (i >> 1);
+            hpel_motion(s, ptr[i], src, src_x, src_y, pix_op,
                         mv[i][0], mv[i][1]);
         }
     }
@@ -452,92 +489,101 @@ static inline void obmc_motion(MpegEncContext *s,
 }
 
 static inline void qpel_motion(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, op_pixels_func (*pix_op)[4],
+                               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,
+                               op_pixels_func (*pix_op)[4],
                                qpel_mc_func (*qpix_op)[16],
                                int motion_x, int motion_y, int h)
 {
     uint8_t *ptr_y, *ptr_cb, *ptr_cr;
-    int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos, linesize, uvlinesize;
+    int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos;
+    ptrdiff_t linesize, uvlinesize;
+
+    dxy   = ((motion_y & 3) << 2) | (motion_x & 3);
 
-    dxy = ((motion_y & 3) << 2) | (motion_x & 3);
     src_x = s->mb_x *  16                 + (motion_x >> 2);
     src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
 
     v_edge_pos = s->v_edge_pos >> field_based;
-    linesize = s->linesize << field_based;
+    linesize   = s->linesize   << field_based;
     uvlinesize = s->uvlinesize << field_based;
 
-    if(field_based){
-        mx= motion_x/2;
-        my= motion_y>>1;
-    }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA2){
-        static const int rtab[8]= {0,0,1,1,0,0,0,1};
-        mx= (motion_x>>1) + rtab[motion_x&7];
-        my= (motion_y>>1) + rtab[motion_y&7];
-    }else if(s->workaround_bugs&FF_BUG_QPEL_CHROMA){
-        mx= (motion_x>>1)|(motion_x&1);
-        my= (motion_y>>1)|(motion_y&1);
-    }else{
-        mx= motion_x/2;
-        my= motion_y/2;
+    if (field_based) {
+        mx = motion_x / 2;
+        my = motion_y >> 1;
+    } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA2) {
+        static const int rtab[8] = { 0, 0, 1, 1, 0, 0, 0, 1 };
+        mx = (motion_x >> 1) + rtab[motion_x & 7];
+        my = (motion_y >> 1) + rtab[motion_y & 7];
+    } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA) {
+        mx = (motion_x >> 1) | (motion_x & 1);
+        my = (motion_y >> 1) | (motion_y & 1);
+    } else {
+        mx = motion_x / 2;
+        my = motion_y / 2;
     }
-    mx= (mx>>1)|(mx&1);
-    my= (my>>1)|(my&1);
+    mx = (mx >> 1) | (mx & 1);
+    my = (my >> 1) | (my & 1);
 
-    uvdxy= (mx&1) | ((my&1)<<1);
-    mx>>=1;
-    my>>=1;
+    uvdxy = (mx & 1) | ((my & 1) << 1);
+    mx  >>= 1;
+    my  >>= 1;
 
     uvsrc_x = s->mb_x *  8                 + mx;
     uvsrc_y = s->mb_y * (8 >> field_based) + my;
 
-    ptr_y  = ref_picture[0] +   src_y *   linesize +   src_x;
+    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(s->h_edge_pos - (motion_x&3) - 16, 0)
-       || (unsigned)src_y > FFMAX(   v_edge_pos - (motion_y&3) - h , 0)){
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
-                            17, 17+field_based, src_x, src_y<<field_based,
-                            s->h_edge_pos, s->v_edge_pos);
-        ptr_y= s->edge_emu_buffer;
-        if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
-            uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
-            s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
-                                9, 9 + field_based,
-                                uvsrc_x, uvsrc_y<<field_based,
-                                s->h_edge_pos>>1, s->v_edge_pos>>1);
-            s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
-                                9, 9 + field_based,
-                                uvsrc_x, uvsrc_y<<field_based,
-                                s->h_edge_pos>>1, s->v_edge_pos>>1);
-            ptr_cb= uvbuf;
-            ptr_cr= uvbuf + 16;
+    if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 3) - 16, 0) ||
+        (unsigned)src_y > FFMAX(v_edge_pos - (motion_y & 3) - h, 0)) {
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
+                                 s->linesize, s->linesize,
+                                 17, 17 + field_based,
+                                 src_x, src_y << field_based,
+                                 s->h_edge_pos, s->v_edge_pos);
+        ptr_y = s->edge_emu_buffer;
+        if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+            uint8_t *uvbuf = s->edge_emu_buffer + 18 * s->linesize;
+            s->vdsp.emulated_edge_mc(uvbuf, ptr_cb,
+                                     s->uvlinesize, s->uvlinesize,
+                                     9, 9 + field_based,
+                                     uvsrc_x, uvsrc_y << field_based,
+                                     s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+            s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr,
+                                     s->uvlinesize, s->uvlinesize,
+                                     9, 9 + field_based,
+                                     uvsrc_x, uvsrc_y << field_based,
+                                     s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+            ptr_cb = uvbuf;
+            ptr_cr = uvbuf + 16;
         }
     }
 
-    if(!field_based)
+    if (!field_based)
         qpix_op[0][dxy](dest_y, ptr_y, linesize);
-    else{
-        if(bottom_field){
-            dest_y += s->linesize;
-            dest_cb+= s->uvlinesize;
-            dest_cr+= s->uvlinesize;
+    else {
+        if (bottom_field) {
+            dest_y  += s->linesize;
+            dest_cb += s->uvlinesize;
+            dest_cr += s->uvlinesize;
         }
 
-        if(field_select){
+        if (field_select) {
             ptr_y  += s->linesize;
             ptr_cb += s->uvlinesize;
             ptr_cr += s->uvlinesize;
         }
-        //damn interlaced mode
-        //FIXME boundary mirroring is not exactly correct here
-        qpix_op[1][dxy](dest_y  , ptr_y  , linesize);
-        qpix_op[1][dxy](dest_y+8, ptr_y+8, linesize);
+        // damn interlaced mode
+        // FIXME boundary mirroring is not exactly correct here
+        qpix_op[1][dxy](dest_y, ptr_y, linesize);
+        qpix_op[1][dxy](dest_y + 8, ptr_y + 8, linesize);
     }
-    if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+    if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
         pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1);
         pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1);
     }
@@ -552,15 +598,16 @@ static void chroma_4mv_motion(MpegEncContext *s,
                               op_pixels_func *pix_op,
                               int mx, int my)
 {
-    int dxy, emu=0, src_x, src_y, offset;
     uint8_t *ptr;
+    int src_x, src_y, dxy, emu = 0;
+    ptrdiff_t offset;
 
     /* 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);
+     * with a special rounding */
+    mx = ff_h263_round_chroma(mx);
+    my = ff_h263_round_chroma(my);
 
-    dxy = ((my & 1) << 1) | (mx & 1);
+    dxy  = ((my & 1) << 1) | (mx & 1);
     mx >>= 1;
     my >>= 1;
 
@@ -574,39 +621,204 @@ static void chroma_4mv_motion(MpegEncContext *s,
         dxy &= ~2;
 
     offset = src_y * s->uvlinesize + src_x;
-    ptr = ref_picture[1] + offset;
-    if(s->flags&CODEC_FLAG_EMU_EDGE){
-        if(   (unsigned)src_x > FFMAX((s->h_edge_pos>>1) - (dxy &1) - 8, 0)
-           || (unsigned)src_y > FFMAX((s->v_edge_pos>>1) - (dxy>>1) - 8, 0)){
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
-                                9, 9, src_x, src_y,
-                                s->h_edge_pos>>1, s->v_edge_pos>>1);
-            ptr= s->edge_emu_buffer;
-            emu=1;
+    ptr    = ref_picture[1] + offset;
+    if (s->flags & CODEC_FLAG_EMU_EDGE) {
+        if ((unsigned)src_x > FFMAX((s->h_edge_pos >> 1) - (dxy & 1) - 8, 0) ||
+            (unsigned)src_y > FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 8, 0)) {
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                                     s->uvlinesize, s->uvlinesize,
+                                     9, 9, src_x, src_y,
+                                     s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+            ptr = s->edge_emu_buffer;
+            emu = 1;
         }
     }
     pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
 
     ptr = ref_picture[2] + offset;
-    if(emu){
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
-                            9, 9, src_x, src_y,
-                            s->h_edge_pos>>1, s->v_edge_pos>>1);
-        ptr= s->edge_emu_buffer;
+    if (emu) {
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                                 s->uvlinesize, s->uvlinesize,
+                                 9, 9, src_x, src_y,
+                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+        ptr = s->edge_emu_buffer;
     }
     pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
 }
 
-static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){
+static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir)
+{
     /* fetch pixels for estimated mv 4 macroblocks ahead
      * optimized for 64byte cache lines */
     const int shift = s->quarter_sample ? 2 : 1;
-    const int mx= (s->mv[dir][0][0]>>shift) + 16*s->mb_x + 8;
-    const int my= (s->mv[dir][0][1]>>shift) + 16*s->mb_y;
-    int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64;
-    s->vdsp.prefetch(pix[0]+off, s->linesize, 4);
-    off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64;
-    s->vdsp.prefetch(pix[1]+off, pix[2]-pix[1], 2);
+    const int mx    = (s->mv[dir][0][0] >> shift) + 16 * s->mb_x + 8;
+    const int my    = (s->mv[dir][0][1] >> shift) + 16 * s->mb_y;
+    int off         = mx + (my + (s->mb_x & 3) * 4) * s->linesize + 64;
+
+    s->vdsp.prefetch(pix[0] + off, s->linesize, 4);
+    off = (mx >> 1) + ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize + 64;
+    s->vdsp.prefetch(pix[1] + off, pix[2] - pix[1], 2);
+}
+
+static inline void apply_obmc(MpegEncContext *s,
+                              uint8_t *dest_y,
+                              uint8_t *dest_cb,
+                              uint8_t *dest_cr,
+                              uint8_t **ref_picture,
+                              op_pixels_func (*pix_op)[4])
+{
+    LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
+    Picture *cur_frame   = &s->current_picture;
+    int mb_x = s->mb_x;
+    int mb_y = s->mb_y;
+    const int xy         = mb_x + mb_y * s->mb_stride;
+    const int mot_stride = s->b8_stride;
+    const int mot_xy     = mb_x * 2 + mb_y * 2 * mot_stride;
+    int mx, my, i;
+
+    assert(!s->mb_skipped);
+
+    AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy]);
+    AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
+
+    AV_COPY32(mv_cache[2][1],
+              cur_frame->motion_val[0][mot_xy + mot_stride]);
+    AV_COPY32(mv_cache[2][2],
+              cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
+
+    AV_COPY32(mv_cache[3][1],
+              cur_frame->motion_val[0][mot_xy + mot_stride]);
+    AV_COPY32(mv_cache[3][2],
+              cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
+
+    if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
+        AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
+        AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
+    } else {
+        AV_COPY32(mv_cache[0][1],
+                  cur_frame->motion_val[0][mot_xy - mot_stride]);
+        AV_COPY32(mv_cache[0][2],
+                  cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
+    }
+
+    if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) {
+        AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
+        AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
+    } else {
+        AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]);
+        AV_COPY32(mv_cache[2][0],
+                  cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
+    }
+
+    if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) {
+        AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
+        AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
+    } else {
+        AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]);
+        AV_COPY32(mv_cache[2][3],
+                  cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
+    }
+
+    mx = 0;
+    my = 0;
+    for (i = 0; i < 4; i++) {
+        const int x      = (i & 1) + 1;
+        const int y      = (i >> 1) + 1;
+        int16_t mv[5][2] = {
+            { mv_cache[y][x][0],     mv_cache[y][x][1]         },
+            { mv_cache[y - 1][x][0], mv_cache[y - 1][x][1]     },
+            { mv_cache[y][x - 1][0], mv_cache[y][x - 1][1]     },
+            { mv_cache[y][x + 1][0], mv_cache[y][x + 1][1]     },
+            { mv_cache[y + 1][x][0], mv_cache[y + 1][x][1]     }
+        };
+        // FIXME cleanup
+        obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
+                    ref_picture[0],
+                    mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8,
+                    pix_op[1],
+                    mv);
+
+        mx += mv[0][0];
+        my += mv[0][1];
+    }
+    if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY))
+        chroma_4mv_motion(s, dest_cb, dest_cr,
+                          ref_picture, pix_op[1],
+                          mx, my);
+}
+
+static inline void apply_8x8(MpegEncContext *s,
+                             uint8_t *dest_y,
+                             uint8_t *dest_cb,
+                             uint8_t *dest_cr,
+                             int dir,
+                             uint8_t **ref_picture,
+                             qpel_mc_func (*qpix_op)[16],
+                             op_pixels_func (*pix_op)[4])
+{
+    int dxy, mx, my, src_x, src_y;
+    int i;
+    int mb_x = s->mb_x;
+    int mb_y = s->mb_y;
+    uint8_t *ptr, *dest;
+
+    mx = 0;
+    my = 0;
+    if (s->quarter_sample) {
+        for (i = 0; i < 4; i++) {
+            int motion_x = s->mv[dir][i][0];
+            int motion_y = s->mv[dir][i][1];
+
+            dxy   = ((motion_y & 3) << 2) | (motion_x & 3);
+            src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
+            src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8;
+
+            /* WARNING: do no forget half pels */
+            src_x = av_clip(src_x, -16, s->width);
+            if (src_x == s->width)
+                dxy &= ~3;
+            src_y = av_clip(src_y, -16, s->height);
+            if (src_y == s->height)
+                dxy &= ~12;
+
+            ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
+            if (s->flags & CODEC_FLAG_EMU_EDGE) {
+                if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 3) - 8, 0) ||
+                    (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 3) - 8, 0)) {
+                    s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                                             s->linesize, s->linesize,
+                                             9, 9,
+                                             src_x, src_y,
+                                             s->h_edge_pos,
+                                             s->v_edge_pos);
+                    ptr = s->edge_emu_buffer;
+                }
+            }
+            dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
+            qpix_op[1][dxy](dest, ptr, s->linesize);
+
+            mx += s->mv[dir][i][0] / 2;
+            my += s->mv[dir][i][1] / 2;
+        }
+    } else {
+        for (i = 0; i < 4; i++) {
+            hpel_motion(s,
+                        dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
+                        ref_picture[0],
+                        mb_x * 16 + (i & 1) * 8,
+                        mb_y * 16 + (i >> 1) * 8,
+                        pix_op[1],
+                        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(s, dest_cb, dest_cr,
+                          ref_picture, pix_op[1], mx, my);
 }
 
 /**
@@ -622,101 +834,36 @@ static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir){
  * the motion vectors are taken from s->mv and the MV type from s->mv_type
  */
 static av_always_inline void MPV_motion_internal(MpegEncContext *s,
-                              uint8_t *dest_y, uint8_t *dest_cb,
-                              uint8_t *dest_cr, int dir,
-                              uint8_t **ref_picture,
-                              op_pixels_func (*pix_op)[4],
-                              qpel_mc_func (*qpix_op)[16], int is_mpeg12)
+                                                 uint8_t *dest_y,
+                                                 uint8_t *dest_cb,
+                                                 uint8_t *dest_cr,
+                                                 int dir,
+                                                 uint8_t **ref_picture,
+                                                 op_pixels_func (*pix_op)[4],
+                                                 qpel_mc_func (*qpix_op)[16],
+                                                 int is_mpeg12)
 {
-    int dxy, mx, my, src_x, src_y, motion_x, motion_y;
-    int mb_x, mb_y, i;
-    uint8_t *ptr, *dest;
-
-    mb_x = s->mb_x;
-    mb_y = s->mb_y;
+    int i;
+    int mb_y = s->mb_y;
 
     prefetch_motion(s, ref_picture, dir);
 
-    if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){
-        LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
-        AVFrame *cur_frame = &s->current_picture.f;
-        const int xy= s->mb_x + s->mb_y*s->mb_stride;
-        const int mot_stride= s->b8_stride;
-        const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
-
-        assert(!s->mb_skipped);
-
-        AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy    ]);
-        AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
-
-        AV_COPY32(mv_cache[2][1], cur_frame->motion_val[0][mot_xy + mot_stride    ]);
-        AV_COPY32(mv_cache[2][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
-
-        AV_COPY32(mv_cache[3][1], cur_frame->motion_val[0][mot_xy + mot_stride    ]);
-        AV_COPY32(mv_cache[3][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
-
-        if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
-            AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
-            AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
-        }else{
-            AV_COPY32(mv_cache[0][1], cur_frame->motion_val[0][mot_xy - mot_stride    ]);
-            AV_COPY32(mv_cache[0][2], cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
-        }
-
-        if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) {
-            AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
-            AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
-        }else{
-            AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]);
-            AV_COPY32(mv_cache[2][0], cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
-        }
-
-        if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) {
-            AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
-            AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
-        }else{
-            AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]);
-            AV_COPY32(mv_cache[2][3], cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
-        }
-
-        mx = 0;
-        my = 0;
-        for(i=0;i<4;i++) {
-            const int x= (i&1)+1;
-            const int y= (i>>1)+1;
-            int16_t mv[5][2]= {
-                {mv_cache[y][x  ][0], mv_cache[y][x  ][1]},
-                {mv_cache[y-1][x][0], mv_cache[y-1][x][1]},
-                {mv_cache[y][x-1][0], mv_cache[y][x-1][1]},
-                {mv_cache[y][x+1][0], mv_cache[y][x+1][1]},
-                {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}};
-            //FIXME cleanup
-            obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
-                        ref_picture[0],
-                        mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
-                        pix_op[1],
-                        mv);
-
-            mx += mv[0][0];
-            my += mv[0][1];
-        }
-        if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY))
-            chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
-
+    if (!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B) {
+        apply_obmc(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op);
         return;
     }
 
-    switch(s->mv_type) {
+    switch (s->mv_type) {
     case MV_TYPE_16X16:
-        if(s->mcsel){
-            if(s->real_sprite_warping_points==1){
+        if (s->mcsel) {
+            if (s->real_sprite_warping_points == 1) {
                 gmc1_motion(s, dest_y, dest_cb, dest_cr,
                             ref_picture);
-            }else{
+            } else {
                 gmc_motion(s, dest_y, dest_cb, dest_cr,
-                            ref_picture);
+                           ref_picture);
             }
-        }else if(!is_mpeg12 && s->quarter_sample){
+        } else if (!is_mpeg12 && s->quarter_sample) {
             qpel_motion(s, dest_y, dest_cb, dest_cr,
                         0, 0, 0,
                         ref_picture, pix_op, qpix_op,
@@ -724,80 +871,28 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
         } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&
                    s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {
             ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
-                        ref_picture, pix_op,
-                        s->mv[dir][0][0], s->mv[dir][0][1], 16);
-        }else
-        {
+                            ref_picture, pix_op,
+                            s->mv[dir][0][0], s->mv[dir][0][1], 16);
+        } else {
             mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
                         ref_picture, pix_op,
                         s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y);
         }
         break;
     case MV_TYPE_8X8:
-    if (!is_mpeg12) {
-        mx = 0;
-        my = 0;
-        if(s->quarter_sample){
-            for(i=0;i<4;i++) {
-                motion_x = s->mv[dir][i][0];
-                motion_y = s->mv[dir][i][1];
-
-                dxy = ((motion_y & 3) << 2) | (motion_x & 3);
-                src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
-                src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8;
-
-                /* WARNING: do no forget half pels */
-                src_x = av_clip(src_x, -16, s->width);
-                if (src_x == s->width)
-                    dxy &= ~3;
-                src_y = av_clip(src_y, -16, s->height);
-                if (src_y == s->height)
-                    dxy &= ~12;
-
-                ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
-                if(s->flags&CODEC_FLAG_EMU_EDGE){
-                    if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 8, 0)
-                       || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&3) - 8, 0)){
-                        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
-                                            s->linesize, 9, 9,
-                                            src_x, src_y,
-                                            s->h_edge_pos, s->v_edge_pos);
-                        ptr= s->edge_emu_buffer;
-                    }
-                }
-                dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
-                qpix_op[1][dxy](dest, ptr, s->linesize);
-
-                mx += s->mv[dir][i][0]/2;
-                my += s->mv[dir][i][1]/2;
-            }
-        }else{
-            for(i=0;i<4;i++) {
-                hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
-                            ref_picture[0],
-                            mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,
-                            pix_op[1],
-                            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(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);
-    }
+        if (!is_mpeg12)
+            apply_8x8(s, dest_y, dest_cb, dest_cr,
+                      dir, ref_picture, qpix_op, pix_op);
         break;
     case MV_TYPE_FIELD:
         if (s->picture_structure == PICT_FRAME) {
-            if(!is_mpeg12 && s->quarter_sample){
-                for(i=0; i<2; i++){
+            if (!is_mpeg12 && s->quarter_sample) {
+                for (i = 0; i < 2; i++)
                     qpel_motion(s, dest_y, dest_cb, dest_cr,
                                 1, i, s->field_select[dir][i],
                                 ref_picture, pix_op, qpix_op,
                                 s->mv[dir][i][0], s->mv[dir][i][1], 8);
-                }
-            }else{
+            } else {
                 /* top field */
                 mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
                                   0, s->field_select[dir][0],
@@ -810,66 +905,69 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
                                   s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y);
             }
         } else {
-            if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field){
+            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(s, dest_y, dest_cb, dest_cr,
                         s->field_select[dir][0],
                         ref_picture, pix_op,
-                        s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y>>1);
+                        s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y >> 1);
         }
         break;
     case MV_TYPE_16X8:
-        for(i=0; i<2; i++){
-            uint8_t ** ref2picture;
+        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{
+            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(s, dest_y, dest_cb, dest_cr,
                         s->field_select[dir][i],
                         ref2picture, pix_op,
-                        s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8, mb_y>>1);
+                        s->mv[dir][i][0], s->mv[dir][i][1] + 16 * i,
+                        8, mb_y >> 1);
 
-            dest_y += 16*s->linesize;
-            dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize;
-            dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize;
+            dest_y  += 16 * s->linesize;
+            dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize;
+            dest_cr += (16 >> s->chroma_y_shift) * s->uvlinesize;
         }
         break;
     case MV_TYPE_DMV:
-        if(s->picture_structure == PICT_FRAME){
-            for(i=0; i<2; i++){
+        if (s->picture_structure == PICT_FRAME) {
+            for (i = 0; i < 2; i++) {
                 int j;
-                for(j=0; j<2; j++){
+                for (j = 0; j < 2; j++)
                     mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
-                                      j, j^i, ref_picture, pix_op,
-                                      s->mv[dir][2*i + j][0],
-                                      s->mv[dir][2*i + j][1], 8, mb_y);
-                }
-                pix_op = s->dsp.avg_pixels_tab;
+                                      j, j ^ i, ref_picture, pix_op,
+                                      s->mv[dir][2 * i + j][0],
+                                      s->mv[dir][2 * i + j][1], 8, mb_y);
+                pix_op = s->hdsp.avg_pixels_tab;
             }
-        }else{
-            for(i=0; i<2; i++){
+        } else {
+            for (i = 0; i < 2; i++) {
                 mpeg_motion(s, dest_y, dest_cb, dest_cr,
-                            s->picture_structure != i+1,
+                            s->picture_structure != i + 1,
                             ref_picture, pix_op,
-                            s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1);
+                            s->mv[dir][2 * i][0], s->mv[dir][2 * i][1],
+                            16, mb_y >> 1);
 
                 // after put we make avg of the same block
-                pix_op=s->dsp.avg_pixels_tab;
+                pix_op = s->hdsp.avg_pixels_tab;
 
-                //opposite parity is always in the same frame if this is second field
-                if(!s->first_field){
+                /* 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;
+        break;
     default: assert(0);
     }
 }
@@ -882,7 +980,7 @@ void ff_MPV_motion(MpegEncContext *s,
                    qpel_mc_func (*qpix_op)[16])
 {
 #if !CONFIG_SMALL
-    if(s->out_format == FMT_MPEG1)
+    if (s->out_format == FMT_MPEG1)
         MPV_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
                             ref_picture, pix_op, qpix_op, 1);
     else
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index 051796e..bec1b36 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -21,7 +21,8 @@
  */
 
 #include "parser.h"
-#include "mpegvideo.h"
+#include "mpeg12.h"
+#include "internal.h"
 
 struct MpvParseContext {
     ParseContext pc;
@@ -48,7 +49,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
 
     while (buf < buf_end) {
         start_code= -1;
-        buf= avpriv_mpv_find_start_code(buf, buf_end, &start_code);
+        buf= avpriv_find_start_code(buf, buf_end, &start_code);
         bytes_left = buf_end - buf;
         switch(start_code) {
         case PICTURE_START_CODE:
@@ -61,7 +62,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
                 pc->width  = (buf[0] << 4) | (buf[1] >> 4);
                 pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
                 if(!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height){
-                    avcodec_set_dimensions(avctx, pc->width, pc->height);
+                    ff_set_dimensions(avctx, pc->width, pc->height);
                     did_set_size=1;
                 }
                 frame_rate_index = buf[3] & 0xf;
@@ -89,7 +90,7 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
                         pc->height |=( vert_size_ext << 12);
                         avctx->bit_rate += (bit_rate_ext << 18) * 400;
                         if(did_set_size)
-                            avcodec_set_dimensions(avctx, pc->width, pc->height);
+                            ff_set_dimensions(avctx, pc->width, pc->height);
                         avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1) * 2;
                         avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1);
                         avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
@@ -113,6 +114,14 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
                                 s->repeat_pict = 2;
                             }
                         }
+
+                        if (!pc->progressive_sequence) {
+                            if (top_field_first)
+                                s->field_order = AV_FIELD_TT;
+                            else
+                                s->field_order = AV_FIELD_BB;
+                        } else
+                            s->field_order = AV_FIELD_PROGRESSIVE;
                     }
                     break;
                 }
diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c
index 159fe21..ec218c2 100644
--- a/libavcodec/mpegvideo_xvmc.c
+++ b/libavcodec/mpegvideo_xvmc.c
@@ -23,7 +23,6 @@
 #include <X11/extensions/XvMC.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 
 #undef NDEBUG
@@ -31,6 +30,9 @@
 
 #include "xvmc.h"
 #include "xvmc_internal.h"
+#include "version.h"
+
+#if FF_API_XVMC
 
 /**
  * Initialize the block field of the MpegEncContext pointer passed as
@@ -44,7 +46,7 @@ void ff_xvmc_init_block(MpegEncContext *s)
     struct xvmc_pix_fmt *render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2];
     assert(render && render->xvmc_id == AV_XVMC_ID);
 
-    s->block = (DCTELEM (*)[64])(render->data_blocks + render->next_free_data_block_num * 64);
+    s->block = (int16_t (*)[64])(render->data_blocks + render->next_free_data_block_num * 64);
 }
 
 /**
@@ -145,7 +147,7 @@ void ff_xvmc_field_end(MpegEncContext *s)
     assert(render);
 
     if (render->filled_mv_blocks_num > 0)
-        ff_draw_horiz_band(s, 0, 0);
+        ff_mpeg_draw_horiz_band(s, 0, 0);
 }
 
 /**
@@ -179,7 +181,7 @@ void ff_xvmc_decode_mb(MpegEncContext *s)
 
     // Do I need to export quant when I could not perform postprocessing?
     // Anyway, it doesn't hurt.
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    s->current_picture.qscale_table[mb_xy] = s->qscale;
 
     // start of XVMC-specific code
     render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2];
@@ -328,5 +330,7 @@ void ff_xvmc_decode_mb(MpegEncContext *s)
 
 
     if (render->filled_mv_blocks_num == render->allocated_mv_blocks)
-        ff_draw_horiz_band(s, 0, 0);
+        ff_mpeg_draw_horiz_band(s, 0, 0);
 }
+
+#endif /* FF_API_XVMC */
diff --git a/libavcodec/mqc.c b/libavcodec/mqc.c
new file mode 100644
index 0000000..60d87ba
--- /dev/null
+++ b/libavcodec/mqc.c
@@ -0,0 +1,115 @@
+/*
+ * MQ-coder encoder and decoder common functions
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * 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
+ */
+
+/**
+ * MQ-coder common (decoder/encoder) functions
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+#include "mqc.h"
+
+/* MQ coder context state structure */
+typedef struct MqcCxState {
+    uint16_t qe;
+    uint8_t  nmps;
+    uint8_t  nlps;
+    uint8_t  sw;
+} MqcCxState;
+
+static const 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_context_tables(void)
+{
+    int i;
+    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;
+    }
+}
+
+void ff_mqc_init_contexts(MqcState *mqc)
+{
+    memset(mqc->cx_states, 0, sizeof(mqc->cx_states));
+    mqc->cx_states[MQC_CX_UNI] = 2 * 46;
+    mqc->cx_states[MQC_CX_RL]  = 2 * 3;
+    mqc->cx_states[0]          = 2 * 4;
+}
diff --git a/libavcodec/mqc.h b/libavcodec/mqc.h
new file mode 100644
index 0000000..a65433e
--- /dev/null
+++ b/libavcodec/mqc.h
@@ -0,0 +1,78 @@
+/*
+ * MQ-coder: structures, common and decoder functions
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * 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_MQC_H
+#define AVCODEC_MQC_H
+
+/**
+ * MQ-coder
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include <stdint.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 MqcState {
+    uint8_t *bp, *bpstart;
+    unsigned int a;
+    unsigned int c;
+    unsigned int ct;
+    uint8_t cx_states[19];
+} MqcState;
+
+/* decoder */
+
+/**
+ * Initialize MQ-decoder.
+ * @param mqc   MQ decoder state
+ * @param bp    byte poiter
+ */
+void ff_mqc_initdec(MqcState *mqc, uint8_t *bp);
+
+/**
+ * MQ decoder.
+ * @param mqc       MQ decoder state
+ * @param cxstate   Context
+ * @return          Decision (0 ot 1)
+ */
+int ff_mqc_decode(MqcState *mqc, uint8_t *cxstate);
+
+/* common */
+
+/**
+ * MQ-coder Initialize context tables (QE, NLPS, NMPS)
+ */
+void ff_mqc_init_context_tables(void);
+
+/**
+ * MQ-coder context initialisations.
+ * @param mqc       MQ-coder context
+ */
+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..889763a
--- /dev/null
+++ b/libavcodec/mqcdec.c
@@ -0,0 +1,93 @@
+/*
+ * MQ-coder decoder
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * 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
+ */
+
+/**
+ * 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];
+    }
+    // do RENORMD: see ISO/IEC 15444-1:2002 §C.3.3
+    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/msgsmdec.c b/libavcodec/msgsmdec.c
index 52b0f5d..be5062a 100644
--- a/libavcodec/msgsmdec.c
+++ b/libavcodec/msgsmdec.c
@@ -26,13 +26,13 @@
 #include "gsmdec_template.c"
 
 int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples,
-                          const uint8_t *buf)
+                          const uint8_t *buf, int mode)
 {
     int res;
     GetBitContext gb;
     init_get_bits(&gb, buf, GSM_MS_BLOCK_SIZE * 8);
-    res = gsm_decode_block(avctx, samples, &gb);
+    res = gsm_decode_block(avctx, samples, &gb, mode);
     if (res < 0)
         return res;
-    return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb);
+    return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb, mode);
 }
diff --git a/libavcodec/msgsmdec.h b/libavcodec/msgsmdec.h
index 76c87f1..adbda9a 100644
--- a/libavcodec/msgsmdec.h
+++ b/libavcodec/msgsmdec.h
@@ -25,6 +25,6 @@
 #include "avcodec.h"
 
 int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples,
-                          const uint8_t *buf);
+                          const uint8_t *buf, int mode);
 
 #endif /* AVCODEC_MSGSMDEC_H */
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index 5e562d8..c76a14b 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -44,16 +44,6 @@
  *        - (encoding) select best mv table (two choices)
  *        - (encoding) select best vlc/dc table
  */
-//#define DEBUG
-
-#define DC_VLC_BITS 9
-#define V2_INTRA_CBPC_VLC_BITS 3
-#define V2_MB_TYPE_VLC_BITS 7
-#define MV_VLC_BITS 9
-#define V2_MV_VLC_BITS 9
-#define TEX_VLC_BITS 9
-
-#define DEFAULT_INTER_INDEX 3
 
 /* This table is practically identical to the one from h263
  * except that it is inverted. */
@@ -187,21 +177,6 @@ int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block
     return pred;
 }
 
-static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n,
-                                    int32_t **dc_val_ptr)
-{
-    int i;
-
-    if (n < 4) {
-        i= 0;
-    } else {
-        i= n-3;
-    }
-
-    *dc_val_ptr= &s->last_dc[i];
-    return s->last_dc[i];
-}
-
 static int get_dc(uint8_t *src, int stride, int scale)
 {
     int y;
@@ -267,10 +242,7 @@ int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
         : "%eax", "%edx"
     );
 #else
-    /* #elif ARCH_ALPHA */
-    /* Divisions are extremely costly on Alpha; optimize the most
-       common case. But they are costly everywhere...
-     */
+    /* Divisions are costly everywhere; optimize the most common case. */
     if (scale == 8) {
         a = (a + (8 >> 1)) / 8;
         b = (b + (8 >> 1)) / 8;
@@ -363,898 +335,3 @@ int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
     return pred;
 }
 
-/****************************************/
-/* decoding stuff */
-
-VLC ff_mb_non_intra_vlc[4];
-static VLC v2_dc_lum_vlc;
-static VLC v2_dc_chroma_vlc;
-static VLC v2_intra_cbpc_vlc;
-static VLC v2_mb_type_vlc;
-static VLC v2_mv_vlc;
-VLC ff_inter_intra_vlc;
-
-/* This is identical to h263 except that its range is multiplied by 2. */
-static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
-{
-    int code, val, sign, shift;
-
-    code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2);
-    av_dlog(s, "MV code %d at %d %d pred: %d\n", code, s->mb_x,s->mb_y, pred);
-    if (code < 0)
-        return 0xffff;
-
-    if (code == 0)
-        return pred;
-    sign = get_bits1(&s->gb);
-    shift = f_code - 1;
-    val = code;
-    if (shift) {
-        val = (val - 1) << shift;
-        val |= get_bits(&s->gb, shift);
-        val++;
-    }
-    if (sign)
-        val = -val;
-
-    val += pred;
-    if (val <= -64)
-        val += 64;
-    else if (val >= 64)
-        val -= 64;
-
-    return val;
-}
-
-static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
-{
-    int cbp, code, i;
-
-    if (s->pict_type == AV_PICTURE_TYPE_P) {
-        if (s->use_skip_mb_code) {
-            if (get_bits1(&s->gb)) {
-                /* skip mb */
-                s->mb_intra = 0;
-                for(i=0;i<6;i++)
-                    s->block_last_index[i] = -1;
-                s->mv_dir = MV_DIR_FORWARD;
-                s->mv_type = MV_TYPE_16X16;
-                s->mv[0][0][0] = 0;
-                s->mv[0][0][1] = 0;
-                s->mb_skipped = 1;
-                return 0;
-            }
-        }
-
-        if(s->msmpeg4_version==2)
-            code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1);
-        else
-            code = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
-        if(code<0 || code>7){
-            av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y);
-            return -1;
-        }
-
-        s->mb_intra = code >>2;
-
-        cbp = code & 0x3;
-    } else {
-        s->mb_intra = 1;
-        if(s->msmpeg4_version==2)
-            cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1);
-        else
-            cbp= get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 1);
-        if(cbp<0 || cbp>3){
-            av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
-            return -1;
-        }
-    }
-
-    if (!s->mb_intra) {
-        int mx, my, cbpy;
-
-        cbpy= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
-        if(cbpy<0){
-            av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
-            return -1;
-        }
-
-        cbp|= cbpy<<2;
-        if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C;
-
-        ff_h263_pred_motion(s, 0, 0, &mx, &my);
-        mx= msmpeg4v2_decode_motion(s, mx, 1);
-        my= msmpeg4v2_decode_motion(s, my, 1);
-
-        s->mv_dir = MV_DIR_FORWARD;
-        s->mv_type = MV_TYPE_16X16;
-        s->mv[0][0][0] = mx;
-        s->mv[0][0][1] = my;
-    } else {
-        if(s->msmpeg4_version==2){
-            s->ac_pred = get_bits1(&s->gb);
-            cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
-        } else{
-            s->ac_pred = 0;
-            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;
-        }
-    }
-
-    s->dsp.clear_blocks(s->block[0]);
-    for (i = 0; i < 6; i++) {
-        if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
-        {
-             av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
-             return -1;
-        }
-    }
-    return 0;
-}
-
-static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
-{
-    int cbp, code, i;
-    uint8_t *coded_val;
-    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) {
-            if (get_bits1(&s->gb)) {
-                /* skip mb */
-                s->mb_intra = 0;
-                for(i=0;i<6;i++)
-                    s->block_last_index[i] = -1;
-                s->mv_dir = MV_DIR_FORWARD;
-                s->mv_type = MV_TYPE_16X16;
-                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;
-            }
-        }
-
-        code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3);
-        if (code < 0)
-            return -1;
-        //s->mb_intra = (code & 0x40) ? 0 : 1;
-        s->mb_intra = (~code & 0x40) >> 6;
-
-        cbp = code & 0x3f;
-    } else {
-        s->mb_intra = 1;
-        code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
-        if (code < 0)
-            return -1;
-        /* predict coded block pattern */
-        cbp = 0;
-        for(i=0;i<6;i++) {
-            int val = ((code >> (5 - i)) & 1);
-            if (i < 4) {
-                int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val);
-                val = val ^ pred;
-                *coded_val = val;
-            }
-            cbp |= val << (5 - i);
-        }
-    }
-
-    if (!s->mb_intra) {
-        int mx, my;
-        if(s->per_mb_rl_table && cbp){
-            s->rl_table_index = decode012(&s->gb);
-            s->rl_chroma_table_index = s->rl_table_index;
-        }
-        ff_h263_pred_motion(s, 0, 0, &mx, &my);
-        if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0)
-            return -1;
-        s->mv_dir = MV_DIR_FORWARD;
-        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 {
-        av_dlog(s, "I at %d %d %d %06X\n", s->mb_x, s->mb_y,
-                ((cbp & 3) ? 1 : 0) +((cbp & 0x3C)? 2 : 0),
-                show_bits(&s->gb, 24));
-        s->ac_pred = get_bits1(&s->gb);
-        *mb_type_ptr = MB_TYPE_INTRA;
-        if(s->inter_intra_pred){
-            s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);
-            av_dlog(s, "%d%d %d %d/",
-                    s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
-        }
-        if(s->per_mb_rl_table && cbp){
-            s->rl_table_index = decode012(&s->gb);
-            s->rl_chroma_table_index = s->rl_table_index;
-        }
-    }
-
-    s->dsp.clear_blocks(s->block[0]);
-    for (i = 0; i < 6; i++) {
-        if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
-        {
-            av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-/* init all vlc decoding tables */
-av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx)
-{
-    MpegEncContext *s = avctx->priv_data;
-    static int done = 0;
-    int i;
-    MVTable *mv;
-
-    if (ff_h263_decode_init(avctx) < 0)
-        return -1;
-
-    ff_msmpeg4_common_init(s);
-
-    if (!done) {
-        done = 1;
-
-        for(i=0;i<NB_RL_TABLES;i++) {
-            ff_init_rl(&ff_rl_table[i], ff_static_rl_table_store[i]);
-        }
-        INIT_VLC_RL(ff_rl_table[0], 642);
-        INIT_VLC_RL(ff_rl_table[1], 1104);
-        INIT_VLC_RL(ff_rl_table[2], 554);
-        INIT_VLC_RL(ff_rl_table[3], 940);
-        INIT_VLC_RL(ff_rl_table[4], 962);
-        INIT_VLC_RL(ff_rl_table[5], 554);
-
-        mv = &ff_mv_tables[0];
-        INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1,
-                    mv->table_mv_bits, 1, 1,
-                    mv->table_mv_code, 2, 2, 3714);
-        mv = &ff_mv_tables[1];
-        INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1,
-                    mv->table_mv_bits, 1, 1,
-                    mv->table_mv_code, 2, 2, 2694);
-
-        INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120,
-                 &ff_table0_dc_lum[0][1], 8, 4,
-                 &ff_table0_dc_lum[0][0], 8, 4, 1158);
-        INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120,
-                 &ff_table0_dc_chroma[0][1], 8, 4,
-                 &ff_table0_dc_chroma[0][0], 8, 4, 1118);
-        INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120,
-                 &ff_table1_dc_lum[0][1], 8, 4,
-                 &ff_table1_dc_lum[0][0], 8, 4, 1476);
-        INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120,
-                 &ff_table1_dc_chroma[0][1], 8, 4,
-                 &ff_table1_dc_chroma[0][0], 8, 4, 1216);
-
-        INIT_VLC_STATIC(&v2_dc_lum_vlc, DC_VLC_BITS, 512,
-                 &ff_v2_dc_lum_table[0][1], 8, 4,
-                 &ff_v2_dc_lum_table[0][0], 8, 4, 1472);
-        INIT_VLC_STATIC(&v2_dc_chroma_vlc, DC_VLC_BITS, 512,
-                 &ff_v2_dc_chroma_table[0][1], 8, 4,
-                 &ff_v2_dc_chroma_table[0][0], 8, 4, 1506);
-
-        INIT_VLC_STATIC(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4,
-                 &ff_v2_intra_cbpc[0][1], 2, 1,
-                 &ff_v2_intra_cbpc[0][0], 2, 1, 8);
-        INIT_VLC_STATIC(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8,
-                 &ff_v2_mb_type[0][1], 2, 1,
-                 &ff_v2_mb_type[0][0], 2, 1, 128);
-        INIT_VLC_STATIC(&v2_mv_vlc, V2_MV_VLC_BITS, 33,
-                 &ff_mvtab[0][1], 2, 1,
-                 &ff_mvtab[0][0], 2, 1, 538);
-
-        INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128,
-                     &ff_wmv2_inter_table[0][0][1], 8, 4,
-                     &ff_wmv2_inter_table[0][0][0], 8, 4, 1636);
-        INIT_VLC_STATIC(&ff_mb_non_intra_vlc[1], MB_NON_INTRA_VLC_BITS, 128,
-                     &ff_wmv2_inter_table[1][0][1], 8, 4,
-                     &ff_wmv2_inter_table[1][0][0], 8, 4, 2648);
-        INIT_VLC_STATIC(&ff_mb_non_intra_vlc[2], MB_NON_INTRA_VLC_BITS, 128,
-                     &ff_wmv2_inter_table[2][0][1], 8, 4,
-                     &ff_wmv2_inter_table[2][0][0], 8, 4, 1532);
-        INIT_VLC_STATIC(&ff_mb_non_intra_vlc[3], MB_NON_INTRA_VLC_BITS, 128,
-                     &ff_wmv2_inter_table[3][0][1], 8, 4,
-                     &ff_wmv2_inter_table[3][0][0], 8, 4, 2488);
-
-        INIT_VLC_STATIC(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64,
-                 &ff_msmp4_mb_i_table[0][1], 4, 2,
-                 &ff_msmp4_mb_i_table[0][0], 4, 2, 536);
-
-        INIT_VLC_STATIC(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4,
-                 &ff_table_inter_intra[0][1], 2, 1,
-                 &ff_table_inter_intra[0][0], 2, 1, 8);
-    }
-
-    switch(s->msmpeg4_version){
-    case 1:
-    case 2:
-        s->decode_mb= msmpeg4v12_decode_mb;
-        break;
-    case 3:
-    case 4:
-        s->decode_mb= msmpeg4v34_decode_mb;
-        break;
-    case 5:
-        if (CONFIG_WMV2_DECODER)
-            s->decode_mb= ff_wmv2_decode_mb;
-    case 6:
-        //FIXME + TODO VC1 decode mb
-        break;
-    }
-
-    s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe
-
-    return 0;
-}
-
-int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
-{
-    int code;
-
-    if(s->msmpeg4_version==1){
-        int start_code = get_bits_long(&s->gb, 32);
-        if(start_code!=0x00000100){
-            av_log(s->avctx, AV_LOG_ERROR, "invalid startcode\n");
-            return -1;
-        }
-
-        skip_bits(&s->gb, 5); // frame number */
-    }
-
-    s->pict_type = get_bits(&s->gb, 2) + 1;
-    if (s->pict_type != AV_PICTURE_TYPE_I &&
-        s->pict_type != AV_PICTURE_TYPE_P){
-        av_log(s->avctx, AV_LOG_ERROR, "invalid picture type\n");
-        return -1;
-    }
-#if 0
-{
-    static int had_i=0;
-    if(s->pict_type == AV_PICTURE_TYPE_I) had_i=1;
-    if(!had_i) return -1;
-}
-#endif
-    s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
-    if(s->qscale==0){
-        av_log(s->avctx, AV_LOG_ERROR, "invalid qscale\n");
-        return -1;
-    }
-
-    if (s->pict_type == AV_PICTURE_TYPE_I) {
-        code = get_bits(&s->gb, 5);
-        if(s->msmpeg4_version==1){
-            if(code==0 || code>s->mb_height){
-                av_log(s->avctx, AV_LOG_ERROR, "invalid slice height %d\n", code);
-                return -1;
-            }
-
-            s->slice_height = code;
-        }else{
-            /* 0x17: one slice, 0x18: two slices, ... */
-            if (code < 0x17){
-                av_log(s->avctx, AV_LOG_ERROR, "error, slice code was %X\n", code);
-                return -1;
-            }
-
-            s->slice_height = s->mb_height / (code - 0x16);
-        }
-
-        switch(s->msmpeg4_version){
-        case 1:
-        case 2:
-            s->rl_chroma_table_index = 2;
-            s->rl_table_index = 2;
-
-            s->dc_table_index = 0; //not used
-            break;
-        case 3:
-            s->rl_chroma_table_index = decode012(&s->gb);
-            s->rl_table_index = decode012(&s->gb);
-
-            s->dc_table_index = get_bits1(&s->gb);
-            break;
-        case 4:
-            ff_msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8);
-
-            if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
-            else                           s->per_mb_rl_table= 0;
-
-            if(!s->per_mb_rl_table){
-                s->rl_chroma_table_index = decode012(&s->gb);
-                s->rl_table_index = decode012(&s->gb);
-            }
-
-            s->dc_table_index = get_bits1(&s->gb);
-            s->inter_intra_pred= 0;
-            break;
-        }
-        s->no_rounding = 1;
-        if(s->avctx->debug&FF_DEBUG_PICT_INFO)
-            av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d   \n",
-                s->qscale,
-                s->rl_chroma_table_index,
-                s->rl_table_index,
-                s->dc_table_index,
-                s->per_mb_rl_table,
-                s->slice_height);
-    } else {
-        switch(s->msmpeg4_version){
-        case 1:
-        case 2:
-            if(s->msmpeg4_version==1)
-                s->use_skip_mb_code = 1;
-            else
-                s->use_skip_mb_code = get_bits1(&s->gb);
-            s->rl_table_index = 2;
-            s->rl_chroma_table_index = s->rl_table_index;
-            s->dc_table_index = 0; //not used
-            s->mv_table_index = 0;
-            break;
-        case 3:
-            s->use_skip_mb_code = get_bits1(&s->gb);
-            s->rl_table_index = decode012(&s->gb);
-            s->rl_chroma_table_index = s->rl_table_index;
-
-            s->dc_table_index = get_bits1(&s->gb);
-
-            s->mv_table_index = get_bits1(&s->gb);
-            break;
-        case 4:
-            s->use_skip_mb_code = get_bits1(&s->gb);
-
-            if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
-            else                           s->per_mb_rl_table= 0;
-
-            if(!s->per_mb_rl_table){
-                s->rl_table_index = decode012(&s->gb);
-                s->rl_chroma_table_index = s->rl_table_index;
-            }
-
-            s->dc_table_index = get_bits1(&s->gb);
-
-            s->mv_table_index = get_bits1(&s->gb);
-            s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE);
-            break;
-        }
-
-        if(s->avctx->debug&FF_DEBUG_PICT_INFO)
-            av_log(s->avctx, AV_LOG_DEBUG, "skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d   \n",
-                s->use_skip_mb_code,
-                s->rl_table_index,
-                s->rl_chroma_table_index,
-                s->dc_table_index,
-                s->mv_table_index,
-                s->per_mb_rl_table,
-                s->qscale);
-
-        if(s->flipflop_rounding){
-            s->no_rounding ^= 1;
-        }else{
-            s->no_rounding = 0;
-        }
-    }
-    av_dlog(s->avctx, "%d %d %d %d %d\n", s->pict_type, s->bit_rate,
-            s->inter_intra_pred, s->width, s->height);
-
-    s->esc3_level_length= 0;
-    s->esc3_run_length= 0;
-
-    return 0;
-}
-
-int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size)
-{
-    int left= buf_size*8 - get_bits_count(&s->gb);
-    int length= s->msmpeg4_version>=3 ? 17 : 16;
-    /* the alt_bitstream reader could read over the end so we need to check it */
-    if(left>=length && left<length+8)
-    {
-        skip_bits(&s->gb, 5); /* fps */
-        s->bit_rate= get_bits(&s->gb, 11)*1024;
-        if(s->msmpeg4_version>=3)
-            s->flipflop_rounding= get_bits1(&s->gb);
-        else
-            s->flipflop_rounding= 0;
-    }
-    else if(left<length+8)
-    {
-        s->flipflop_rounding= 0;
-        if(s->msmpeg4_version != 2)
-            av_log(s->avctx, AV_LOG_ERROR, "ext header missing, %d left\n", left);
-    }
-    else
-    {
-        av_log(s->avctx, AV_LOG_ERROR, "I frame too long, ignoring ext header\n");
-    }
-
-    return 0;
-}
-
-static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
-{
-    int level, pred;
-
-    if(s->msmpeg4_version<=2){
-        if (n < 4) {
-            level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3);
-        } else {
-            level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3);
-        }
-        if (level < 0)
-            return -1;
-        level-=256;
-    }else{  //FIXME optimize use unified tables & index
-        if (n < 4) {
-            level = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
-        } else {
-            level = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
-        }
-        if (level < 0){
-            av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
-            return -1;
-        }
-
-        if (level == DC_MAX) {
-            level = get_bits(&s->gb, 8);
-            if (get_bits1(&s->gb))
-                level = -level;
-        } else if (level != 0) {
-            if (get_bits1(&s->gb))
-                level = -level;
-        }
-    }
-
-    if(s->msmpeg4_version==1){
-        int32_t *dc_val;
-        pred = msmpeg4v1_pred_dc(s, n, &dc_val);
-        level += pred;
-
-        /* update predictor */
-        *dc_val= level;
-    }else{
-        int16_t *dc_val;
-        pred   = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
-        level += pred;
-
-        /* update predictor */
-        if (n < 4) {
-            *dc_val = level * s->y_dc_scale;
-        } else {
-            *dc_val = level * s->c_dc_scale;
-        }
-    }
-
-    return level;
-}
-
-//#define ERROR_DETAILS
-int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
-                              int n, int coded, const uint8_t *scan_table)
-{
-    int level, i, last, run, run_diff;
-    int av_uninit(dc_pred_dir);
-    RLTable *rl;
-    RL_VLC_ELEM *rl_vlc;
-    int qmul, qadd;
-
-    if (s->mb_intra) {
-        qmul=1;
-        qadd=0;
-
-        /* DC coef */
-        level = msmpeg4_decode_dc(s, n, &dc_pred_dir);
-
-        if (level < 0){
-            av_log(s->avctx, AV_LOG_ERROR, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);
-            if(s->inter_intra_pred) level=0;
-            else                    return -1;
-        }
-        if (n < 4) {
-            rl = &ff_rl_table[s->rl_table_index];
-            if(level > 256*s->y_dc_scale){
-                av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ L qscale: %d//\n", s->qscale);
-                if(!s->inter_intra_pred) return -1;
-            }
-        } else {
-            rl = &ff_rl_table[3 + s->rl_chroma_table_index];
-            if(level > 256*s->c_dc_scale){
-                av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ C qscale: %d//\n", s->qscale);
-                if(!s->inter_intra_pred) return -1;
-            }
-        }
-        block[0] = level;
-
-        run_diff = s->msmpeg4_version >= 4;
-        i = 0;
-        if (!coded) {
-            goto not_coded;
-        }
-        if (s->ac_pred) {
-            if (dc_pred_dir == 0)
-                scan_table = s->intra_v_scantable.permutated; /* left */
-            else
-                scan_table = s->intra_h_scantable.permutated; /* top */
-        } else {
-            scan_table = s->intra_scantable.permutated;
-        }
-        rl_vlc= rl->rl_vlc[0];
-    } else {
-        qmul = s->qscale << 1;
-        qadd = (s->qscale - 1) | 1;
-        i = -1;
-        rl = &ff_rl_table[3 + s->rl_table_index];
-
-        if(s->msmpeg4_version==2)
-            run_diff = 0;
-        else
-            run_diff = 1;
-
-        if (!coded) {
-            s->block_last_index[n] = i;
-            return 0;
-        }
-        if(!scan_table)
-            scan_table = s->inter_scantable.permutated;
-        rl_vlc= rl->rl_vlc[s->qscale];
-    }
-  {
-    OPEN_READER(re, &s->gb);
-    for(;;) {
-        UPDATE_CACHE(re, &s->gb);
-        GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
-        if (level==0) {
-            int cache;
-            cache= GET_CACHE(re, &s->gb);
-            /* escape */
-            if (s->msmpeg4_version==1 || (cache&0x80000000)==0) {
-                if (s->msmpeg4_version==1 || (cache&0x40000000)==0) {
-                    /* third escape */
-                    if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2);
-                    UPDATE_CACHE(re, &s->gb);
-                    if(s->msmpeg4_version<=3){
-                        last=  SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
-                        run=   SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);
-                        level= SHOW_SBITS(re, &s->gb, 8);
-                        SKIP_COUNTER(re, &s->gb, 1+6+8);
-                    }else{
-                        int sign;
-                        last=  SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
-                        if(!s->esc3_level_length){
-                            int ll;
-                            av_dlog(s->avctx, "ESC-3 %X at %d %d\n",
-                                    show_bits(&s->gb, 24), s->mb_x, s->mb_y);
-                            if(s->qscale<8){
-                                ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3);
-                                if(ll==0){
-                                    ll= 8+SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
-                                }
-                            }else{
-                                ll=2;
-                                while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){
-                                    ll++;
-                                    SKIP_BITS(re, &s->gb, 1);
-                                }
-                                if(ll<8) SKIP_BITS(re, &s->gb, 1);
-                            }
-
-                            s->esc3_level_length= ll;
-                            s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);
-                            UPDATE_CACHE(re, &s->gb);
-                        }
-                        run=   SHOW_UBITS(re, &s->gb, s->esc3_run_length);
-                        SKIP_BITS(re, &s->gb, s->esc3_run_length);
-
-                        sign=  SHOW_UBITS(re, &s->gb, 1);
-                        SKIP_BITS(re, &s->gb, 1);
-
-                        level= SHOW_UBITS(re, &s->gb, s->esc3_level_length);
-                        SKIP_BITS(re, &s->gb, s->esc3_level_length);
-                        if(sign) level= -level;
-                    }
-
-#if 0 // waste of time / this will detect very few errors
-                    {
-                        const int abs_level= FFABS(level);
-                        const int run1= run - rl->max_run[last][abs_level] - run_diff;
-                        if(abs_level<=MAX_LEVEL && run<=MAX_RUN){
-                            if(abs_level <= rl->max_level[last][run]){
-                                av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
-                                return DECODING_AC_LOST;
-                            }
-                            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 DECODING_AC_LOST;
-                            }
-                            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 DECODING_AC_LOST;
-                            }
-                        }
-                    }
-#endif
-                    //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ;
-                    if (level>0) level= level * qmul + qadd;
-                    else         level= level * qmul - qadd;
-#if 0 // waste of time too :(
-                    if(level>2048 || level<-2048){
-                        av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc\n");
-                        return DECODING_AC_LOST;
-                    }
-#endif
-                    i+= run + 1;
-                    if(last) i+=192;
-#ifdef ERROR_DETAILS
-                if(run==66)
-                    av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC3 level=%d\n", level);
-                else if((i>62 && i<192) || i>192+63)
-                    av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level);
-#endif
-                } else {
-                    /* second escape */
-                    SKIP_BITS(re, &s->gb, 2);
-                    GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
-                    i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing
-                    level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                    LAST_SKIP_BITS(re, &s->gb, 1);
-#ifdef ERROR_DETAILS
-                if(run==66)
-                    av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC2 level=%d\n", level);
-                else if((i>62 && i<192) || i>192+63)
-                    av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level);
-#endif
-                }
-            } else {
-                /* first escape */
-                SKIP_BITS(re, &s->gb, 1);
-                GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
-                i+= run;
-                level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
-                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-                LAST_SKIP_BITS(re, &s->gb, 1);
-#ifdef ERROR_DETAILS
-                if(run==66)
-                    av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC1 level=%d\n", level);
-                else if((i>62 && i<192) || i>192+63)
-                    av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level);
-#endif
-            }
-        } else {
-            i+= run;
-            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
-            LAST_SKIP_BITS(re, &s->gb, 1);
-#ifdef ERROR_DETAILS
-                if(run==66)
-                    av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code level=%d\n", level);
-                else if((i>62 && i<192) || i>192+63)
-                    av_log(s->avctx, AV_LOG_ERROR, "run overflow i=%d run=%d level=%d\n", i, run, level);
-#endif
-        }
-        if (i > 62){
-            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){
-                    av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
-                    break;
-                }else{
-                    av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
-                    return -1;
-                }
-            }
-
-            block[scan_table[i]] = level;
-            break;
-        }
-
-        block[scan_table[i]] = level;
-    }
-    CLOSE_READER(re, &s->gb);
-  }
- not_coded:
-    if (s->mb_intra) {
-        ff_mpeg4_pred_ac(s, block, n, dc_pred_dir);
-        if (s->ac_pred) {
-            i = 63; /* XXX: not optimal */
-        }
-    }
-    if(s->msmpeg4_version>=4 && i>0) i=63; //FIXME/XXX optimize
-    s->block_last_index[n] = i;
-
-    return 0;
-}
-
-int ff_msmpeg4_decode_motion(MpegEncContext * s,
-                                 int *mx_ptr, int *my_ptr)
-{
-    MVTable *mv;
-    int code, mx, my;
-
-    mv = &ff_mv_tables[s->mv_table_index];
-
-    code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2);
-    if (code < 0){
-        av_log(s->avctx, AV_LOG_ERROR, "illegal MV code at %d %d\n", s->mb_x, s->mb_y);
-        return -1;
-    }
-    if (code == mv->n) {
-        mx = get_bits(&s->gb, 6);
-        my = get_bits(&s->gb, 6);
-    } else {
-        mx = mv->table_mvx[code];
-        my = mv->table_mvy[code];
-    }
-
-    mx += *mx_ptr - 32;
-    my += *my_ptr - 32;
-    /* WARNING : they do not do exactly modulo encoding */
-    if (mx <= -64)
-        mx += 64;
-    else if (mx >= 64)
-        mx -= 64;
-
-    if (my <= -64)
-        my += 64;
-    else if (my >= 64)
-        my -= 64;
-    *mx_ptr = mx;
-    *my_ptr = my;
-    return 0;
-}
-
-AVCodec ff_msmpeg4v1_decoder = {
-    .name           = "msmpeg4v1",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MSMPEG4V1,
-    .priv_data_size = sizeof(MpegEncContext),
-    .init           = ff_msmpeg4_decode_init,
-    .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
-    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
-    .pix_fmts       = ff_pixfmt_list_420,
-};
-
-AVCodec ff_msmpeg4v2_decoder = {
-    .name           = "msmpeg4v2",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MSMPEG4V2,
-    .priv_data_size = sizeof(MpegEncContext),
-    .init           = ff_msmpeg4_decode_init,
-    .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
-    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
-    .pix_fmts       = ff_pixfmt_list_420,
-};
-
-AVCodec ff_msmpeg4v3_decoder = {
-    .name           = "msmpeg4",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_MSMPEG4V3,
-    .priv_data_size = sizeof(MpegEncContext),
-    .init           = ff_msmpeg4_decode_init,
-    .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
-    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
-    .pix_fmts       = ff_pixfmt_list_420,
-};
-
-AVCodec ff_wmv1_decoder = {
-    .name           = "wmv1",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_WMV1,
-    .priv_data_size = sizeof(MpegEncContext),
-    .init           = ff_msmpeg4_decode_init,
-    .close          = ff_h263_decode_end,
-    .decode         = ff_h263_decode_frame,
-    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
-    .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..0a8ecd9 100644
--- a/libavcodec/msmpeg4.h
+++ b/libavcodec/msmpeg4.h
@@ -26,7 +26,6 @@
 
 #include "config.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "msmpeg4data.h"
 #include "put_bits.h"
@@ -45,17 +44,17 @@ extern VLC ff_inter_intra_vlc;
 
 void ff_msmpeg4_code012(PutBitContext *pb, int n);
 void ff_msmpeg4_common_init(MpegEncContext *s);
-void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
+void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n);
 void ff_msmpeg4_handle_slices(MpegEncContext *s);
 void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my);
 int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n,
                                 uint8_t **coded_block_ptr);
 int ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr);
-int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
+int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
                             int n, int coded, const uint8_t *scan_table);
 int ff_msmpeg4_pred_dc(MpegEncContext *s, int n,
                        int16_t **dc_val_ptr, int *dir_ptr);
-int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);
+int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64]);
 
 #define CONFIG_MSMPEG4_DECODER (CONFIG_MSMPEG4V1_DECODER || \
                                 CONFIG_MSMPEG4V2_DECODER || \
diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c
index 5721d8f..cf291af 100644
--- a/libavcodec/msmpeg4data.c
+++ b/libavcodec/msmpeg4data.c
@@ -27,6 +27,8 @@
  * MSMPEG4 data tables.
  */
 
+#include "h263.h"
+#include "mpeg4video.h"
 #include "msmpeg4data.h"
 
 uint32_t ff_v2_dc_lum_table[512][2];
@@ -596,14 +598,6 @@ static const int8_t table4_run[168] = {
  29, 30, 31, 32, 33, 34, 35, 36,
 };
 
-extern const uint16_t ff_inter_vlc[103][2];
-extern const int8_t ff_inter_level[102];
-extern const int8_t ff_inter_run[102];
-
-extern const uint16_t ff_mpeg4_intra_vlc[103][2];
-extern const int8_t ff_mpeg4_intra_level[102];
-extern const int8_t ff_mpeg4_intra_run[102];
-
 RLTable ff_rl_table[NB_RL_TABLES] = {
     /* intra luminance tables */
     /* low motion  */
diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c
new file mode 100644
index 0000000..9a12633
--- /dev/null
+++ b/libavcodec/msmpeg4dec.c
@@ -0,0 +1,953 @@
+/*
+ * MSMPEG4 backend for encoder and decoder
+ * Copyright (c) 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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 "avcodec.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+#include "msmpeg4.h"
+#include "libavutil/x86/asm.h"
+#include "h263.h"
+#include "mpeg4video.h"
+#include "msmpeg4data.h"
+#include "vc1data.h"
+
+#define DC_VLC_BITS 9
+#define V2_INTRA_CBPC_VLC_BITS 3
+#define V2_MB_TYPE_VLC_BITS 7
+#define MV_VLC_BITS 9
+#define V2_MV_VLC_BITS 9
+#define TEX_VLC_BITS 9
+
+#define DEFAULT_INTER_INDEX 3
+
+static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n,
+                                    int32_t **dc_val_ptr)
+{
+    int i;
+
+    if (n < 4) {
+        i= 0;
+    } else {
+        i= n-3;
+    }
+
+    *dc_val_ptr= &s->last_dc[i];
+    return s->last_dc[i];
+}
+
+/****************************************/
+/* decoding stuff */
+
+VLC ff_mb_non_intra_vlc[4];
+static VLC v2_dc_lum_vlc;
+static VLC v2_dc_chroma_vlc;
+static VLC v2_intra_cbpc_vlc;
+static VLC v2_mb_type_vlc;
+static VLC v2_mv_vlc;
+VLC ff_inter_intra_vlc;
+
+/* This is identical to h263 except that its range is multiplied by 2. */
+static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
+{
+    int code, val, sign, shift;
+
+    code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2);
+    av_dlog(s, "MV code %d at %d %d pred: %d\n", code, s->mb_x,s->mb_y, pred);
+    if (code < 0)
+        return 0xffff;
+
+    if (code == 0)
+        return pred;
+    sign = get_bits1(&s->gb);
+    shift = f_code - 1;
+    val = code;
+    if (shift) {
+        val = (val - 1) << shift;
+        val |= get_bits(&s->gb, shift);
+        val++;
+    }
+    if (sign)
+        val = -val;
+
+    val += pred;
+    if (val <= -64)
+        val += 64;
+    else if (val >= 64)
+        val -= 64;
+
+    return val;
+}
+
+static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64])
+{
+    int cbp, code, i;
+
+    if (s->pict_type == AV_PICTURE_TYPE_P) {
+        if (s->use_skip_mb_code) {
+            if (get_bits1(&s->gb)) {
+                /* skip mb */
+                s->mb_intra = 0;
+                for(i=0;i<6;i++)
+                    s->block_last_index[i] = -1;
+                s->mv_dir = MV_DIR_FORWARD;
+                s->mv_type = MV_TYPE_16X16;
+                s->mv[0][0][0] = 0;
+                s->mv[0][0][1] = 0;
+                s->mb_skipped = 1;
+                return 0;
+            }
+        }
+
+        if(s->msmpeg4_version==2)
+            code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1);
+        else
+            code = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
+        if(code<0 || code>7){
+            av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y);
+            return -1;
+        }
+
+        s->mb_intra = code >>2;
+
+        cbp = code & 0x3;
+    } else {
+        s->mb_intra = 1;
+        if(s->msmpeg4_version==2)
+            cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1);
+        else
+            cbp= get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 1);
+        if(cbp<0 || cbp>3){
+            av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
+            return -1;
+        }
+    }
+
+    if (!s->mb_intra) {
+        int mx, my, cbpy;
+
+        cbpy= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+        if(cbpy<0){
+            av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
+            return -1;
+        }
+
+        cbp|= cbpy<<2;
+        if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C;
+
+        ff_h263_pred_motion(s, 0, 0, &mx, &my);
+        mx= msmpeg4v2_decode_motion(s, mx, 1);
+        my= msmpeg4v2_decode_motion(s, my, 1);
+
+        s->mv_dir = MV_DIR_FORWARD;
+        s->mv_type = MV_TYPE_16X16;
+        s->mv[0][0][0] = mx;
+        s->mv[0][0][1] = my;
+    } else {
+        if(s->msmpeg4_version==2){
+            s->ac_pred = get_bits1(&s->gb);
+            cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
+        } else{
+            s->ac_pred = 0;
+            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;
+        }
+    }
+
+    s->dsp.clear_blocks(s->block[0]);
+    for (i = 0; i < 6; i++) {
+        if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
+        {
+             av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
+             return -1;
+        }
+    }
+    return 0;
+}
+
+static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
+{
+    int cbp, code, i;
+    uint8_t *coded_val;
+    uint32_t * const mb_type_ptr = &s->current_picture.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) {
+            if (get_bits1(&s->gb)) {
+                /* skip mb */
+                s->mb_intra = 0;
+                for(i=0;i<6;i++)
+                    s->block_last_index[i] = -1;
+                s->mv_dir = MV_DIR_FORWARD;
+                s->mv_type = MV_TYPE_16X16;
+                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;
+            }
+        }
+
+        code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3);
+        if (code < 0)
+            return -1;
+        //s->mb_intra = (code & 0x40) ? 0 : 1;
+        s->mb_intra = (~code & 0x40) >> 6;
+
+        cbp = code & 0x3f;
+    } else {
+        s->mb_intra = 1;
+        code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
+        if (code < 0)
+            return -1;
+        /* predict coded block pattern */
+        cbp = 0;
+        for(i=0;i<6;i++) {
+            int val = ((code >> (5 - i)) & 1);
+            if (i < 4) {
+                int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val);
+                val = val ^ pred;
+                *coded_val = val;
+            }
+            cbp |= val << (5 - i);
+        }
+    }
+
+    if (!s->mb_intra) {
+        int mx, my;
+        if(s->per_mb_rl_table && cbp){
+            s->rl_table_index = decode012(&s->gb);
+            s->rl_chroma_table_index = s->rl_table_index;
+        }
+        ff_h263_pred_motion(s, 0, 0, &mx, &my);
+        if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0)
+            return -1;
+        s->mv_dir = MV_DIR_FORWARD;
+        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 {
+        av_dlog(s, "I at %d %d %d %06X\n", s->mb_x, s->mb_y,
+                ((cbp & 3) ? 1 : 0) +((cbp & 0x3C)? 2 : 0),
+                show_bits(&s->gb, 24));
+        s->ac_pred = get_bits1(&s->gb);
+        *mb_type_ptr = MB_TYPE_INTRA;
+        if(s->inter_intra_pred){
+            s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);
+            av_dlog(s, "%d%d %d %d/",
+                    s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
+        }
+        if(s->per_mb_rl_table && cbp){
+            s->rl_table_index = decode012(&s->gb);
+            s->rl_chroma_table_index = s->rl_table_index;
+        }
+    }
+
+    s->dsp.clear_blocks(s->block[0]);
+    for (i = 0; i < 6; i++) {
+        if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
+        {
+            av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+/* init all vlc decoding tables */
+av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx)
+{
+    MpegEncContext *s = avctx->priv_data;
+    static int done = 0;
+    int i;
+    MVTable *mv;
+
+    if (ff_h263_decode_init(avctx) < 0)
+        return -1;
+
+    ff_msmpeg4_common_init(s);
+
+    if (!done) {
+        done = 1;
+
+        for(i=0;i<NB_RL_TABLES;i++) {
+            ff_init_rl(&ff_rl_table[i], ff_static_rl_table_store[i]);
+        }
+        INIT_VLC_RL(ff_rl_table[0], 642);
+        INIT_VLC_RL(ff_rl_table[1], 1104);
+        INIT_VLC_RL(ff_rl_table[2], 554);
+        INIT_VLC_RL(ff_rl_table[3], 940);
+        INIT_VLC_RL(ff_rl_table[4], 962);
+        INIT_VLC_RL(ff_rl_table[5], 554);
+
+        mv = &ff_mv_tables[0];
+        INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1,
+                    mv->table_mv_bits, 1, 1,
+                    mv->table_mv_code, 2, 2, 3714);
+        mv = &ff_mv_tables[1];
+        INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1,
+                    mv->table_mv_bits, 1, 1,
+                    mv->table_mv_code, 2, 2, 2694);
+
+        INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120,
+                 &ff_table0_dc_lum[0][1], 8, 4,
+                 &ff_table0_dc_lum[0][0], 8, 4, 1158);
+        INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120,
+                 &ff_table0_dc_chroma[0][1], 8, 4,
+                 &ff_table0_dc_chroma[0][0], 8, 4, 1118);
+        INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120,
+                 &ff_table1_dc_lum[0][1], 8, 4,
+                 &ff_table1_dc_lum[0][0], 8, 4, 1476);
+        INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120,
+                 &ff_table1_dc_chroma[0][1], 8, 4,
+                 &ff_table1_dc_chroma[0][0], 8, 4, 1216);
+
+        INIT_VLC_STATIC(&v2_dc_lum_vlc, DC_VLC_BITS, 512,
+                 &ff_v2_dc_lum_table[0][1], 8, 4,
+                 &ff_v2_dc_lum_table[0][0], 8, 4, 1472);
+        INIT_VLC_STATIC(&v2_dc_chroma_vlc, DC_VLC_BITS, 512,
+                 &ff_v2_dc_chroma_table[0][1], 8, 4,
+                 &ff_v2_dc_chroma_table[0][0], 8, 4, 1506);
+
+        INIT_VLC_STATIC(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4,
+                 &ff_v2_intra_cbpc[0][1], 2, 1,
+                 &ff_v2_intra_cbpc[0][0], 2, 1, 8);
+        INIT_VLC_STATIC(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8,
+                 &ff_v2_mb_type[0][1], 2, 1,
+                 &ff_v2_mb_type[0][0], 2, 1, 128);
+        INIT_VLC_STATIC(&v2_mv_vlc, V2_MV_VLC_BITS, 33,
+                 &ff_mvtab[0][1], 2, 1,
+                 &ff_mvtab[0][0], 2, 1, 538);
+
+        INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128,
+                     &ff_wmv2_inter_table[0][0][1], 8, 4,
+                     &ff_wmv2_inter_table[0][0][0], 8, 4, 1636);
+        INIT_VLC_STATIC(&ff_mb_non_intra_vlc[1], MB_NON_INTRA_VLC_BITS, 128,
+                     &ff_wmv2_inter_table[1][0][1], 8, 4,
+                     &ff_wmv2_inter_table[1][0][0], 8, 4, 2648);
+        INIT_VLC_STATIC(&ff_mb_non_intra_vlc[2], MB_NON_INTRA_VLC_BITS, 128,
+                     &ff_wmv2_inter_table[2][0][1], 8, 4,
+                     &ff_wmv2_inter_table[2][0][0], 8, 4, 1532);
+        INIT_VLC_STATIC(&ff_mb_non_intra_vlc[3], MB_NON_INTRA_VLC_BITS, 128,
+                     &ff_wmv2_inter_table[3][0][1], 8, 4,
+                     &ff_wmv2_inter_table[3][0][0], 8, 4, 2488);
+
+        INIT_VLC_STATIC(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64,
+                 &ff_msmp4_mb_i_table[0][1], 4, 2,
+                 &ff_msmp4_mb_i_table[0][0], 4, 2, 536);
+
+        INIT_VLC_STATIC(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4,
+                 &ff_table_inter_intra[0][1], 2, 1,
+                 &ff_table_inter_intra[0][0], 2, 1, 8);
+    }
+
+    switch(s->msmpeg4_version){
+    case 1:
+    case 2:
+        s->decode_mb= msmpeg4v12_decode_mb;
+        break;
+    case 3:
+    case 4:
+        s->decode_mb= msmpeg4v34_decode_mb;
+        break;
+    case 5:
+        if (CONFIG_WMV2_DECODER)
+            s->decode_mb= ff_wmv2_decode_mb;
+    case 6:
+        //FIXME + TODO VC1 decode mb
+        break;
+    }
+
+    s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe
+
+    return 0;
+}
+
+int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
+{
+    int code;
+
+    if(s->msmpeg4_version==1){
+        int start_code = get_bits_long(&s->gb, 32);
+        if(start_code!=0x00000100){
+            av_log(s->avctx, AV_LOG_ERROR, "invalid startcode\n");
+            return -1;
+        }
+
+        skip_bits(&s->gb, 5); // frame number */
+    }
+
+    s->pict_type = get_bits(&s->gb, 2) + 1;
+    if (s->pict_type != AV_PICTURE_TYPE_I &&
+        s->pict_type != AV_PICTURE_TYPE_P){
+        av_log(s->avctx, AV_LOG_ERROR, "invalid picture type\n");
+        return -1;
+    }
+#if 0
+{
+    static int had_i=0;
+    if(s->pict_type == AV_PICTURE_TYPE_I) had_i=1;
+    if(!had_i) return -1;
+}
+#endif
+    s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
+    if(s->qscale==0){
+        av_log(s->avctx, AV_LOG_ERROR, "invalid qscale\n");
+        return -1;
+    }
+
+    if (s->pict_type == AV_PICTURE_TYPE_I) {
+        code = get_bits(&s->gb, 5);
+        if(s->msmpeg4_version==1){
+            if(code==0 || code>s->mb_height){
+                av_log(s->avctx, AV_LOG_ERROR, "invalid slice height %d\n", code);
+                return -1;
+            }
+
+            s->slice_height = code;
+        }else{
+            /* 0x17: one slice, 0x18: two slices, ... */
+            if (code < 0x17){
+                av_log(s->avctx, AV_LOG_ERROR, "error, slice code was %X\n", code);
+                return -1;
+            }
+
+            s->slice_height = s->mb_height / (code - 0x16);
+        }
+
+        switch(s->msmpeg4_version){
+        case 1:
+        case 2:
+            s->rl_chroma_table_index = 2;
+            s->rl_table_index = 2;
+
+            s->dc_table_index = 0; //not used
+            break;
+        case 3:
+            s->rl_chroma_table_index = decode012(&s->gb);
+            s->rl_table_index = decode012(&s->gb);
+
+            s->dc_table_index = get_bits1(&s->gb);
+            break;
+        case 4:
+            ff_msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8);
+
+            if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
+            else                           s->per_mb_rl_table= 0;
+
+            if(!s->per_mb_rl_table){
+                s->rl_chroma_table_index = decode012(&s->gb);
+                s->rl_table_index = decode012(&s->gb);
+            }
+
+            s->dc_table_index = get_bits1(&s->gb);
+            s->inter_intra_pred= 0;
+            break;
+        }
+        s->no_rounding = 1;
+        if(s->avctx->debug&FF_DEBUG_PICT_INFO)
+            av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d   \n",
+                s->qscale,
+                s->rl_chroma_table_index,
+                s->rl_table_index,
+                s->dc_table_index,
+                s->per_mb_rl_table,
+                s->slice_height);
+    } else {
+        switch(s->msmpeg4_version){
+        case 1:
+        case 2:
+            if(s->msmpeg4_version==1)
+                s->use_skip_mb_code = 1;
+            else
+                s->use_skip_mb_code = get_bits1(&s->gb);
+            s->rl_table_index = 2;
+            s->rl_chroma_table_index = s->rl_table_index;
+            s->dc_table_index = 0; //not used
+            s->mv_table_index = 0;
+            break;
+        case 3:
+            s->use_skip_mb_code = get_bits1(&s->gb);
+            s->rl_table_index = decode012(&s->gb);
+            s->rl_chroma_table_index = s->rl_table_index;
+
+            s->dc_table_index = get_bits1(&s->gb);
+
+            s->mv_table_index = get_bits1(&s->gb);
+            break;
+        case 4:
+            s->use_skip_mb_code = get_bits1(&s->gb);
+
+            if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
+            else                           s->per_mb_rl_table= 0;
+
+            if(!s->per_mb_rl_table){
+                s->rl_table_index = decode012(&s->gb);
+                s->rl_chroma_table_index = s->rl_table_index;
+            }
+
+            s->dc_table_index = get_bits1(&s->gb);
+
+            s->mv_table_index = get_bits1(&s->gb);
+            s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE);
+            break;
+        }
+
+        if(s->avctx->debug&FF_DEBUG_PICT_INFO)
+            av_log(s->avctx, AV_LOG_DEBUG, "skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d   \n",
+                s->use_skip_mb_code,
+                s->rl_table_index,
+                s->rl_chroma_table_index,
+                s->dc_table_index,
+                s->mv_table_index,
+                s->per_mb_rl_table,
+                s->qscale);
+
+        if(s->flipflop_rounding){
+            s->no_rounding ^= 1;
+        }else{
+            s->no_rounding = 0;
+        }
+    }
+    av_dlog(s->avctx, "%d %d %d %d %d\n", s->pict_type, s->bit_rate,
+            s->inter_intra_pred, s->width, s->height);
+
+    s->esc3_level_length= 0;
+    s->esc3_run_length= 0;
+
+    return 0;
+}
+
+int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size)
+{
+    int left= buf_size*8 - get_bits_count(&s->gb);
+    int length= s->msmpeg4_version>=3 ? 17 : 16;
+    /* the alt_bitstream reader could read over the end so we need to check it */
+    if(left>=length && left<length+8)
+    {
+        skip_bits(&s->gb, 5); /* fps */
+        s->bit_rate= get_bits(&s->gb, 11)*1024;
+        if(s->msmpeg4_version>=3)
+            s->flipflop_rounding= get_bits1(&s->gb);
+        else
+            s->flipflop_rounding= 0;
+    }
+    else if(left<length+8)
+    {
+        s->flipflop_rounding= 0;
+        if(s->msmpeg4_version != 2)
+            av_log(s->avctx, AV_LOG_ERROR, "ext header missing, %d left\n", left);
+    }
+    else
+    {
+        av_log(s->avctx, AV_LOG_ERROR, "I frame too long, ignoring ext header\n");
+    }
+
+    return 0;
+}
+
+static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
+{
+    int level, pred;
+
+    if(s->msmpeg4_version<=2){
+        if (n < 4) {
+            level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3);
+        } else {
+            level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3);
+        }
+        if (level < 0)
+            return -1;
+        level-=256;
+    }else{  //FIXME optimize use unified tables & index
+        if (n < 4) {
+            level = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+        } else {
+            level = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+        }
+        if (level < 0){
+            av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
+            return -1;
+        }
+
+        if (level == DC_MAX) {
+            level = get_bits(&s->gb, 8);
+            if (get_bits1(&s->gb))
+                level = -level;
+        } else if (level != 0) {
+            if (get_bits1(&s->gb))
+                level = -level;
+        }
+    }
+
+    if(s->msmpeg4_version==1){
+        int32_t *dc_val;
+        pred = msmpeg4v1_pred_dc(s, n, &dc_val);
+        level += pred;
+
+        /* update predictor */
+        *dc_val= level;
+    }else{
+        int16_t *dc_val;
+        pred   = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+        level += pred;
+
+        /* update predictor */
+        if (n < 4) {
+            *dc_val = level * s->y_dc_scale;
+        } else {
+            *dc_val = level * s->c_dc_scale;
+        }
+    }
+
+    return level;
+}
+
+//#define ERROR_DETAILS
+int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
+                              int n, int coded, const uint8_t *scan_table)
+{
+    int level, i, last, run, run_diff;
+    int av_uninit(dc_pred_dir);
+    RLTable *rl;
+    RL_VLC_ELEM *rl_vlc;
+    int qmul, qadd;
+
+    if (s->mb_intra) {
+        qmul=1;
+        qadd=0;
+
+        /* DC coef */
+        level = msmpeg4_decode_dc(s, n, &dc_pred_dir);
+
+        if (level < 0){
+            av_log(s->avctx, AV_LOG_ERROR, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);
+            if(s->inter_intra_pred) level=0;
+            else                    return -1;
+        }
+        if (n < 4) {
+            rl = &ff_rl_table[s->rl_table_index];
+            if(level > 256*s->y_dc_scale){
+                av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ L qscale: %d//\n", s->qscale);
+                if(!s->inter_intra_pred) return -1;
+            }
+        } else {
+            rl = &ff_rl_table[3 + s->rl_chroma_table_index];
+            if(level > 256*s->c_dc_scale){
+                av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ C qscale: %d//\n", s->qscale);
+                if(!s->inter_intra_pred) return -1;
+            }
+        }
+        block[0] = level;
+
+        run_diff = s->msmpeg4_version >= 4;
+        i = 0;
+        if (!coded) {
+            goto not_coded;
+        }
+        if (s->ac_pred) {
+            if (dc_pred_dir == 0)
+                scan_table = s->intra_v_scantable.permutated; /* left */
+            else
+                scan_table = s->intra_h_scantable.permutated; /* top */
+        } else {
+            scan_table = s->intra_scantable.permutated;
+        }
+        rl_vlc= rl->rl_vlc[0];
+    } else {
+        qmul = s->qscale << 1;
+        qadd = (s->qscale - 1) | 1;
+        i = -1;
+        rl = &ff_rl_table[3 + s->rl_table_index];
+
+        if(s->msmpeg4_version==2)
+            run_diff = 0;
+        else
+            run_diff = 1;
+
+        if (!coded) {
+            s->block_last_index[n] = i;
+            return 0;
+        }
+        if(!scan_table)
+            scan_table = s->inter_scantable.permutated;
+        rl_vlc= rl->rl_vlc[s->qscale];
+    }
+  {
+    OPEN_READER(re, &s->gb);
+    for(;;) {
+        UPDATE_CACHE(re, &s->gb);
+        GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
+        if (level==0) {
+            int cache;
+            cache= GET_CACHE(re, &s->gb);
+            /* escape */
+            if (s->msmpeg4_version==1 || (cache&0x80000000)==0) {
+                if (s->msmpeg4_version==1 || (cache&0x40000000)==0) {
+                    /* third escape */
+                    if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2);
+                    UPDATE_CACHE(re, &s->gb);
+                    if(s->msmpeg4_version<=3){
+                        last=  SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
+                        run=   SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);
+                        level= SHOW_SBITS(re, &s->gb, 8);
+                        SKIP_COUNTER(re, &s->gb, 1+6+8);
+                    }else{
+                        int sign;
+                        last=  SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
+                        if(!s->esc3_level_length){
+                            int ll;
+                            av_dlog(s->avctx, "ESC-3 %X at %d %d\n",
+                                    show_bits(&s->gb, 24), s->mb_x, s->mb_y);
+                            if(s->qscale<8){
+                                ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3);
+                                if(ll==0){
+                                    ll= 8+SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
+                                }
+                            }else{
+                                ll=2;
+                                while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){
+                                    ll++;
+                                    SKIP_BITS(re, &s->gb, 1);
+                                }
+                                if(ll<8) SKIP_BITS(re, &s->gb, 1);
+                            }
+
+                            s->esc3_level_length= ll;
+                            s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);
+                            UPDATE_CACHE(re, &s->gb);
+                        }
+                        run=   SHOW_UBITS(re, &s->gb, s->esc3_run_length);
+                        SKIP_BITS(re, &s->gb, s->esc3_run_length);
+
+                        sign=  SHOW_UBITS(re, &s->gb, 1);
+                        SKIP_BITS(re, &s->gb, 1);
+
+                        level= SHOW_UBITS(re, &s->gb, s->esc3_level_length);
+                        SKIP_BITS(re, &s->gb, s->esc3_level_length);
+                        if(sign) level= -level;
+                    }
+
+#if 0 // waste of time / this will detect very few errors
+                    {
+                        const int abs_level= FFABS(level);
+                        const int run1= run - rl->max_run[last][abs_level] - run_diff;
+                        if(abs_level<=MAX_LEVEL && run<=MAX_RUN){
+                            if(abs_level <= rl->max_level[last][run]){
+                                av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
+                                return DECODING_AC_LOST;
+                            }
+                            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 DECODING_AC_LOST;
+                            }
+                            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 DECODING_AC_LOST;
+                            }
+                        }
+                    }
+#endif
+                    //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ;
+                    if (level>0) level= level * qmul + qadd;
+                    else         level= level * qmul - qadd;
+#if 0 // waste of time too :(
+                    if(level>2048 || level<-2048){
+                        av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc\n");
+                        return DECODING_AC_LOST;
+                    }
+#endif
+                    i+= run + 1;
+                    if(last) i+=192;
+#ifdef ERROR_DETAILS
+                if(run==66)
+                    av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC3 level=%d\n", level);
+                else if((i>62 && i<192) || i>192+63)
+                    av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level);
+#endif
+                } else {
+                    /* second escape */
+                    SKIP_BITS(re, &s->gb, 2);
+                    GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+                    i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing
+                    level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                    LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+                if(run==66)
+                    av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC2 level=%d\n", level);
+                else if((i>62 && i<192) || i>192+63)
+                    av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level);
+#endif
+                }
+            } else {
+                /* first escape */
+                SKIP_BITS(re, &s->gb, 1);
+                GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+                i+= run;
+                level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
+                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+                LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+                if(run==66)
+                    av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC1 level=%d\n", level);
+                else if((i>62 && i<192) || i>192+63)
+                    av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level);
+#endif
+            }
+        } else {
+            i+= run;
+            level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+            LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+                if(run==66)
+                    av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code level=%d\n", level);
+                else if((i>62 && i<192) || i>192+63)
+                    av_log(s->avctx, AV_LOG_ERROR, "run overflow i=%d run=%d level=%d\n", i, run, level);
+#endif
+        }
+        if (i > 62){
+            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){
+                    av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
+                    break;
+                }else{
+                    av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+                    return -1;
+                }
+            }
+
+            block[scan_table[i]] = level;
+            break;
+        }
+
+        block[scan_table[i]] = level;
+    }
+    CLOSE_READER(re, &s->gb);
+  }
+ not_coded:
+    if (s->mb_intra) {
+        ff_mpeg4_pred_ac(s, block, n, dc_pred_dir);
+        if (s->ac_pred) {
+            i = 63; /* XXX: not optimal */
+        }
+    }
+    if(s->msmpeg4_version>=4 && i>0) i=63; //FIXME/XXX optimize
+    s->block_last_index[n] = i;
+
+    return 0;
+}
+
+int ff_msmpeg4_decode_motion(MpegEncContext * s,
+                                 int *mx_ptr, int *my_ptr)
+{
+    MVTable *mv;
+    int code, mx, my;
+
+    mv = &ff_mv_tables[s->mv_table_index];
+
+    code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2);
+    if (code < 0){
+        av_log(s->avctx, AV_LOG_ERROR, "illegal MV code at %d %d\n", s->mb_x, s->mb_y);
+        return -1;
+    }
+    if (code == mv->n) {
+        mx = get_bits(&s->gb, 6);
+        my = get_bits(&s->gb, 6);
+    } else {
+        mx = mv->table_mvx[code];
+        my = mv->table_mvy[code];
+    }
+
+    mx += *mx_ptr - 32;
+    my += *my_ptr - 32;
+    /* WARNING : they do not do exactly modulo encoding */
+    if (mx <= -64)
+        mx += 64;
+    else if (mx >= 64)
+        mx -= 64;
+
+    if (my <= -64)
+        my += 64;
+    else if (my >= 64)
+        my -= 64;
+    *mx_ptr = mx;
+    *my_ptr = my;
+    return 0;
+}
+
+AVCodec ff_msmpeg4v1_decoder = {
+    .name           = "msmpeg4v1",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MSMPEG4V1,
+    .priv_data_size = sizeof(MpegEncContext),
+    .init           = ff_msmpeg4_decode_init,
+    .close          = ff_h263_decode_end,
+    .decode         = ff_h263_decode_frame,
+    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .pix_fmts       = ff_pixfmt_list_420,
+};
+
+AVCodec ff_msmpeg4v2_decoder = {
+    .name           = "msmpeg4v2",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MSMPEG4V2,
+    .priv_data_size = sizeof(MpegEncContext),
+    .init           = ff_msmpeg4_decode_init,
+    .close          = ff_h263_decode_end,
+    .decode         = ff_h263_decode_frame,
+    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .pix_fmts       = ff_pixfmt_list_420,
+};
+
+AVCodec ff_msmpeg4v3_decoder = {
+    .name           = "msmpeg4",
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MSMPEG4V3,
+    .priv_data_size = sizeof(MpegEncContext),
+    .init           = ff_msmpeg4_decode_init,
+    .close          = ff_h263_decode_end,
+    .decode         = ff_h263_decode_frame,
+    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .pix_fmts       = ff_pixfmt_list_420,
+};
+
+AVCodec ff_wmv1_decoder = {
+    .name           = "wmv1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_WMV1,
+    .priv_data_size = sizeof(MpegEncContext),
+    .init           = ff_msmpeg4_decode_init,
+    .close          = ff_h263_decode_end,
+    .decode         = ff_h263_decode_frame,
+    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .pix_fmts       = ff_pixfmt_list_420,
+};
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 4a362c3..45ef208 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -30,6 +30,7 @@
 #include <stdint.h>
 #include <string.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
 #include "libavutil/mem.h"
 #include "mpegvideo.h"
@@ -45,7 +46,7 @@
 static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];
 
 /* build the table which associate a (x,y) motion vector to a vlc */
-static void init_mv_table(MVTable *tab)
+static av_cold void init_mv_table(MVTable *tab)
 {
     int i, x, y;
 
@@ -368,7 +369,7 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val)
 }
 
 void ff_msmpeg4_encode_mb(MpegEncContext * s,
-                          DCTELEM block[6][64],
+                          int16_t block[6][64],
                           int motion_x, int motion_y)
 {
     int cbp, coded_cbp, i;
@@ -569,7 +570,7 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr
 /* Encoding of a block. Very similar to MPEG4 except for a different
    escape coding (same as H263) and more vlc tables.
  */
-void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n)
+void ff_msmpeg4_encode_block(MpegEncContext * s, int16_t * block, int n)
 {
     int level, run, last, i, j, last_index;
     int last_non_zero, sign, slevel;
diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c
index 7cd8823..4b39c92 100644
--- a/libavcodec/msrle.c
+++ b/libavcodec/msrle.c
@@ -33,12 +33,12 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "msrledec.h"
 
 typedef struct MsrleContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     GetByteContext gb;
     const unsigned char *buf;
@@ -63,10 +63,12 @@ static av_cold int msrle_decode_init(AVCodecContext *avctx)
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "unsupported bits per sample\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -79,33 +81,32 @@ static int msrle_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     MsrleContext *s = avctx->priv_data;
     int istride = FFALIGN(avctx->width*avctx->bits_per_coded_sample, 32) / 8;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (avctx->bits_per_coded_sample <= 8) {
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
         if (pal) {
-            s->frame.palette_has_changed = 1;
+            s->frame->palette_has_changed = 1;
             memcpy(s->pal, pal, AVPALETTE_SIZE);
         }
 
         /* make the palette available */
-        memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+        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;
-        uint8_t *ptr = s->frame.data[0];
+        uint8_t *ptr = s->frame->data[0];
         uint8_t *buf = avpkt->data + (avctx->height-1)*istride;
         int i, j;
 
@@ -121,15 +122,17 @@ static int msrle_decode_frame(AVCodecContext *avctx,
                 memcpy(ptr, buf, linesize);
             }
             buf -= istride;
-            ptr += s->frame.linesize[0];
+            ptr += s->frame->linesize[0];
         }
     } else {
         bytestream2_init(&s->gb, buf, buf_size);
-        ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb);
+        ff_msrle_decode(avctx, (AVPicture*)s->frame, avctx->bits_per_coded_sample, &s->gb);
     }
 
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -140,14 +143,14 @@ static av_cold int msrle_decode_end(AVCodecContext *avctx)
     MsrleContext *s = avctx->priv_data;
 
     /* release the last frame */
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_msrle_decoder = {
     .name           = "msrle",
+    .long_name      = NULL_IF_CONFIG_SMALL("Microsoft RLE"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MSRLE,
     .priv_data_size = sizeof(MsrleContext),
@@ -155,5 +158,4 @@ AVCodec ff_msrle_decoder = {
     .close          = msrle_decode_end,
     .decode         = msrle_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Microsoft RLE"),
 };
diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c
index c9edb2e..a67a942 100644
--- a/libavcodec/mss1.c
+++ b/libavcodec/mss1.c
@@ -25,11 +25,12 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "mss12.h"
 
 typedef struct MSS1Context {
     MSS12Context   ctx;
-    AVFrame        pic;
+    AVFrame       *pic;
     SliceContext   sc;
 } MSS1Context;
 
@@ -150,38 +151,37 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     init_get_bits(&gb, buf, buf_size * 8);
     arith_init(&acoder, &gb);
 
-    ctx->pic.reference    = 3;
-    ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
-                            FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &ctx->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, ctx->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
 
-    c->pal_pic    =  ctx->pic.data[0] + ctx->pic.linesize[0] * (avctx->height - 1);
-    c->pal_stride = -ctx->pic.linesize[0];
+    c->pal_pic    =  ctx->pic->data[0] + ctx->pic->linesize[0] * (avctx->height - 1);
+    c->pal_stride = -ctx->pic->linesize[0];
     c->keyframe   = !arith_get_bit(&acoder);
     if (c->keyframe) {
         c->corrupted = 0;
         ff_mss12_slicecontext_reset(&ctx->sc);
         pal_changed        = decode_pal(c, &acoder);
-        ctx->pic.key_frame = 1;
-        ctx->pic.pict_type = AV_PICTURE_TYPE_I;
+        ctx->pic->key_frame = 1;
+        ctx->pic->pict_type = AV_PICTURE_TYPE_I;
     } else {
         if (c->corrupted)
             return AVERROR_INVALIDDATA;
-        ctx->pic.key_frame = 0;
-        ctx->pic.pict_type = AV_PICTURE_TYPE_P;
+        ctx->pic->key_frame = 0;
+        ctx->pic->pict_type = AV_PICTURE_TYPE_P;
     }
     c->corrupted = ff_mss12_decode_rect(&ctx->sc, &acoder, 0, 0,
                                         avctx->width, avctx->height);
     if (c->corrupted)
         return AVERROR_INVALIDDATA;
-    memcpy(ctx->pic.data[1], c->pal, AVPALETTE_SIZE);
-    ctx->pic.palette_has_changed = pal_changed;
+    memcpy(ctx->pic->data[1], c->pal, AVPALETTE_SIZE);
+    ctx->pic->palette_has_changed = pal_changed;
+
+    if ((ret = av_frame_ref(data, ctx->pic)) < 0)
+        return ret;
 
     *got_frame      = 1;
-    *(AVFrame*)data = ctx->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -193,7 +193,10 @@ static av_cold int mss1_decode_init(AVCodecContext *avctx)
     int ret;
 
     c->ctx.avctx       = avctx;
-    avctx->coded_frame = &c->pic;
+
+    c->pic = av_frame_alloc();
+    if (!c->pic)
+        return AVERROR(ENOMEM);
 
     ret = ff_mss12_decode_init(&c->ctx, 0, &c->sc, NULL);
 
@@ -206,8 +209,7 @@ static av_cold int mss1_decode_end(AVCodecContext *avctx)
 {
     MSS1Context * const ctx = avctx->priv_data;
 
-    if (ctx->pic.data[0])
-        avctx->release_buffer(avctx, &ctx->pic);
+    av_frame_free(&ctx->pic);
     ff_mss12_decode_end(&ctx->ctx);
 
     return 0;
@@ -215,6 +217,7 @@ static av_cold int mss1_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_mss1_decoder = {
     .name           = "mss1",
+    .long_name      = NULL_IF_CONFIG_SMALL("MS Screen 1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MSS1,
     .priv_data_size = sizeof(MSS1Context),
@@ -222,5 +225,4 @@ AVCodec ff_mss1_decoder = {
     .close          = mss1_decode_end,
     .decode         = mss1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MS Screen 1"),
 };
diff --git a/libavcodec/mss12.h b/libavcodec/mss12.h
index f5d0366..5b1fee8 100644
--- a/libavcodec/mss12.h
+++ b/libavcodec/mss12.h
@@ -95,9 +95,9 @@ int ff_mss12_decode_rect(SliceContext *ctx, ArithCoder *acoder,
                          int x, int y, int width, int height);
 void ff_mss12_model_update(Model *m, int val);
 void ff_mss12_slicecontext_reset(SliceContext *sc);
-av_cold int ff_mss12_decode_init(MSS12Context *c, int version,
-                                 SliceContext* sc1, SliceContext *sc2);
-av_cold int ff_mss12_decode_end(MSS12Context *ctx);
+int ff_mss12_decode_init(MSS12Context *c, int version,
+                         SliceContext *sc1, SliceContext *sc2);
+int ff_mss12_decode_end(MSS12Context *ctx);
 
 #define ARITH_GET_BIT(VERSION)                                          \
 static int arith ## VERSION ## _get_bit(ArithCoder *c)                  \
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index 9746335..3fe8620 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -24,6 +24,7 @@
  */
 
 #include "libavutil/avassert.h"
+#include "error_resilience.h"
 #include "internal.h"
 #include "msmpeg4data.h"
 #include "vc1.h"
@@ -33,8 +34,7 @@
 typedef struct MSS2Context {
     VC1Context     v;
     int            split_position;
-    AVFrame        pic;
-    AVFrame        last_pic;
+    AVFrame       *last_pic;
     MSS12Context   c;
     MSS2DSPContext dsp;
     SliceContext   sc[2];
@@ -163,7 +163,7 @@ static int decode_pal_v2(MSS12Context *ctx, const uint8_t *buf, int buf_size)
 
     ncol = *buf++;
     if (ncol > ctx->free_colours || buf_size < 2 + ncol * 3)
-        return -1;
+        return AVERROR_INVALIDDATA;
     for (i = 0; i < ncol; i++)
         *pal++ = AV_RB24(buf + 3 * i);
 
@@ -189,7 +189,7 @@ static int decode_555(GetByteContext *gB, uint16_t *dst, int stride,
         READ_PAIR(y, endy)
 
         if (endx >= w || endy >= h || x > endx || y > endy)
-            return -1;
+            return AVERROR_INVALIDDATA;
         dst += x + stride * y;
         w    = endx - x + 1;
         h    = endy - y + 1;
@@ -373,21 +373,15 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
     VC1Context *v     = avctx->priv_data;
     MpegEncContext *s = &v->s;
     AVFrame *f;
+    int ret;
 
     ff_mpeg_flush(avctx);
 
-    if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
-        int i = ff_find_unused_picture(s, 0);
-        if (i < 0)
-            return -1;
-        s->current_picture_ptr = &s->picture[i];
-    }
-
     init_get_bits(&s->gb, buf, buf_size * 8);
 
     s->loop_filter = avctx->skip_loop_filter < AVDISCARD_ALL;
 
-    if (ff_vc1_parse_frame_header(v, &s->gb) == -1) {
+    if (ff_vc1_parse_frame_header(v, &s->gb) < 0) {
         av_log(v->s.avctx, AV_LOG_ERROR, "header error\n");
         return AVERROR_INVALIDDATA;
     }
@@ -399,13 +393,13 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    if (ff_MPV_frame_start(s, avctx) < 0) {
+    if ((ret = ff_MPV_frame_start(s, avctx)) < 0) {
         av_log(v->s.avctx, AV_LOG_ERROR, "ff_MPV_frame_start error\n");
         avctx->pix_fmt = AV_PIX_FMT_RGB24;
-        return -1;
+        return ret;
     }
 
-    ff_er_frame_start(s);
+    ff_mpeg_er_frame_start(s);
 
     v->bits = buf_size * 8;
 
@@ -418,7 +412,7 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
 
     ff_vc1_decode_blocks(v);
 
-    ff_er_frame_end(s);
+    ff_er_frame_end(&s->er);
 
     ff_MPV_frame_end(s);
 
@@ -429,8 +423,8 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
         ctx->dsp.upsample_plane(f->data[1], f->linesize[1], w >> 1, h >> 1);
         ctx->dsp.upsample_plane(f->data[2], f->linesize[2], w >> 1, h >> 1);
     } else if (v->respic)
-        av_log_ask_for_sample(v->s.avctx,
-                              "Asymmetric WMV9 rectangle subsampling\n");
+        avpriv_request_sample(v->s.avctx,
+                              "Asymmetric WMV9 rectangle subsampling");
 
     av_assert0(f->linesize[1] == f->linesize[2]);
 
@@ -468,6 +462,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int buf_size       = avpkt->size;
     MSS2Context *ctx = avctx->priv_data;
     MSS12Context *c  = &ctx->c;
+    AVFrame *frame   = data;
     GetBitContext gb;
     GetByteContext gB;
     ArithCoder acoder;
@@ -521,8 +516,8 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
 
     avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24;
-    if (ctx->pic.data[0] && ctx->pic.format != avctx->pix_fmt)
-        avctx->release_buffer(avctx, &ctx->pic);
+    if (ctx->last_pic->format != avctx->pix_fmt)
+        av_frame_unref(ctx->last_pic);
 
     if (has_wmv9) {
         bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
@@ -594,54 +589,37 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     if (c->mvX < 0 || c->mvY < 0) {
-        FFSWAP(AVFrame, ctx->pic, ctx->last_pic);
         FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic);
 
-        if (ctx->pic.data[0])
-            avctx->release_buffer(avctx, &ctx->pic);
-
-        ctx->pic.reference    = 3;
-        ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID    |
-                                FF_BUFFER_HINTS_READABLE |
-                                FF_BUFFER_HINTS_PRESERVE |
-                                FF_BUFFER_HINTS_REUSABLE;
-
-        if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) {
+        if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
 
-        if (ctx->last_pic.data[0]) {
-            av_assert0(ctx->pic.linesize[0] == ctx->last_pic.linesize[0]);
-            c->last_rgb_pic = ctx->last_pic.data[0] +
-                              ctx->last_pic.linesize[0] * (avctx->height - 1);
+        if (ctx->last_pic->data[0]) {
+            av_assert0(frame->linesize[0] == ctx->last_pic->linesize[0]);
+            c->last_rgb_pic = ctx->last_pic->data[0] +
+                              ctx->last_pic->linesize[0] * (avctx->height - 1);
         } else {
             av_log(avctx, AV_LOG_ERROR, "Missing keyframe\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     } else {
-        if (ctx->last_pic.data[0])
-            avctx->release_buffer(avctx, &ctx->last_pic);
-
-        ctx->pic.reference    = 3;
-        ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID    |
-                                FF_BUFFER_HINTS_READABLE |
-                                FF_BUFFER_HINTS_PRESERVE |
-                                FF_BUFFER_HINTS_REUSABLE;
-
-        if ((ret = avctx->reget_buffer(avctx, &ctx->pic)) < 0) {
+        if ((ret = ff_reget_buffer(avctx, ctx->last_pic)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
         }
+        if ((ret = av_frame_ref(frame, ctx->last_pic)) < 0)
+            return ret;
 
         c->last_rgb_pic = NULL;
     }
-    c->rgb_pic    = ctx->pic.data[0] +
-                    ctx->pic.linesize[0] * (avctx->height - 1);
-    c->rgb_stride = -ctx->pic.linesize[0];
+    c->rgb_pic    = frame->data[0] +
+                    frame->linesize[0] * (avctx->height - 1);
+    c->rgb_stride = -frame->linesize[0];
 
-    ctx->pic.key_frame = keyframe;
-    ctx->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    frame->key_frame = keyframe;
+    frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
 
     if (is_555) {
         bytestream2_init(&gB, buf, buf_size);
@@ -744,8 +722,14 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (buf_size)
         av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n");
 
+    if (c->mvX < 0 || c->mvY < 0) {
+        av_frame_unref(ctx->last_pic);
+        ret = av_frame_ref(ctx->last_pic, frame);
+        if (ret < 0)
+            return ret;
+    }
+
     *got_frame       = 1;
-    *(AVFrame *)data = ctx->pic;
 
     return avpkt->size;
 }
@@ -753,16 +737,14 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 static av_cold int wmv9_init(AVCodecContext *avctx)
 {
     VC1Context *v = avctx->priv_data;
+    int ret;
 
     v->s.avctx    = avctx;
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
     v->s.flags   |= CODEC_FLAG_EMU_EDGE;
 
-    if (avctx->idct_algo == FF_IDCT_AUTO)
-        avctx->idct_algo = FF_IDCT_WMV2;
-
-    if (ff_vc1_init_common(v) < 0)
-        return -1;
+    if ((ret = ff_vc1_init_common(v)) < 0)
+        return ret;
     ff_vc1dsp_init(&v->vc1dsp);
 
     v->profile = PROFILE_MAIN;
@@ -790,7 +772,7 @@ static av_cold int wmv9_init(AVCodecContext *avctx)
 
     v->overlap         = 0;
 
-    v->s.resync_marker = 0;
+    v->resync_marker   = 0;
     v->rangered        = 0;
 
     v->s.max_b_frames = avctx->max_b_frames = 0;
@@ -802,9 +784,9 @@ static av_cold int wmv9_init(AVCodecContext *avctx)
 
     ff_vc1_init_transposed_scantables(v);
 
-    if (ff_msmpeg4_decode_init(avctx) < 0 ||
-        ff_vc1_decode_init_alloc_tables(v) < 0)
-        return -1;
+    if ((ret = ff_msmpeg4_decode_init(avctx)) < 0 ||
+        (ret = ff_vc1_decode_init_alloc_tables(v)) < 0)
+        return ret;
 
     /* error concealment */
     v->s.me.qpel_put = v->s.dsp.put_qpel_pixels_tab;
@@ -817,10 +799,7 @@ static av_cold int mss2_decode_end(AVCodecContext *avctx)
 {
     MSS2Context *const ctx = avctx->priv_data;
 
-    if (ctx->pic.data[0])
-        avctx->release_buffer(avctx, &ctx->pic);
-    if (ctx->last_pic.data[0])
-        avctx->release_buffer(avctx, &ctx->last_pic);
+    av_frame_free(&ctx->last_pic);
 
     ff_mss12_decode_end(&ctx->c);
     av_freep(&ctx->c.pal_pic);
@@ -836,7 +815,6 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx)
     MSS12Context *c = &ctx->c;
     int ret;
     c->avctx = avctx;
-    avctx->coded_frame = &ctx->pic;
     if (ret = ff_mss12_decode_init(c, 1, &ctx->sc[0], &ctx->sc[1]))
         return ret;
     c->pal_stride   = c->mask_stride;
@@ -855,11 +833,18 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx)
     avctx->pix_fmt = c->free_colours == 127 ? AV_PIX_FMT_RGB555
                                             : AV_PIX_FMT_RGB24;
 
+    ctx->last_pic = av_frame_alloc();
+    if (!ctx->last_pic) {
+        mss2_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
 AVCodec ff_mss2_decoder = {
     .name           = "mss2",
+    .long_name      = NULL_IF_CONFIG_SMALL("MS Windows Media Video V9 Screen"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MSS2,
     .priv_data_size = sizeof(MSS2Context),
@@ -867,5 +852,4 @@ AVCodec ff_mss2_decoder = {
     .close          = mss2_decode_end,
     .decode         = mss2_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MS Windows Media Video V9 Screen"),
 };
diff --git a/libavcodec/mss2dsp.h b/libavcodec/mss2dsp.h
index b3d67a1..61c3a04 100644
--- a/libavcodec/mss2dsp.h
+++ b/libavcodec/mss2dsp.h
@@ -26,7 +26,7 @@
 #ifndef AVCODEC_MSS2DSP_H
 #define AVCODEC_MSS2DSP_H
 
-#include "dsputil.h"
+#include <stdint.h>
 
 typedef struct MSS2DSPContext {
     void (*mss2_blit_wmv9)(uint8_t *dst, int dst_stride,
@@ -45,6 +45,6 @@ typedef struct MSS2DSPContext {
     void (*upsample_plane)(uint8_t *plane, int plane_stride, int w, int h);
 } MSS2DSPContext;
 
-av_cold void ff_mss2dsp_init(MSS2DSPContext* dsp);
+void ff_mss2dsp_init(MSS2DSPContext *dsp);
 
 #endif /* AVCODEC_MSS2DSP_H */
diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c
index 689daee..c5e29a3 100644
--- a/libavcodec/mss3.c
+++ b/libavcodec/mss3.c
@@ -27,6 +27,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "dsputil.h"
+#include "internal.h"
 #include "mss34dsp.h"
 
 #define HEADER_SIZE 27
@@ -107,7 +108,7 @@ typedef struct HaarBlockCoder {
 
 typedef struct MSS3Context {
     AVCodecContext   *avctx;
-    AVFrame          pic;
+    AVFrame          *pic;
 
     int              got_error;
     RangeCoder       coder;
@@ -730,18 +731,16 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return buf_size;
     c->got_error = 0;
 
-    c->pic.reference    = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
-    c->pic.key_frame = keyframe;
-    c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    c->pic->key_frame = keyframe;
+    c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
     if (!bytestream2_get_bytes_left(&gb)) {
+        if ((ret = av_frame_ref(data, c->pic)) < 0)
+            return ret;
         *got_frame      = 1;
-        *(AVFrame*)data = c->pic;
 
         return buf_size;
     }
@@ -752,9 +751,9 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     mb_width  = dec_width  >> 4;
     mb_height = dec_height >> 4;
-    dst[0] = c->pic.data[0] + dec_x     +  dec_y      * c->pic.linesize[0];
-    dst[1] = c->pic.data[1] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[1];
-    dst[2] = c->pic.data[2] + dec_x / 2 + (dec_y / 2) * c->pic.linesize[2];
+    dst[0] = c->pic->data[0] + dec_x     +  dec_y      * c->pic->linesize[0];
+    dst[1] = c->pic->data[1] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[1];
+    dst[2] = c->pic->data[2] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[2];
     for (y = 0; y < mb_height; y++) {
         for (x = 0; x < mb_width; x++) {
             for (i = 0; i < 3; i++) {
@@ -765,23 +764,23 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                 case FILL_BLOCK:
                     decode_fill_block(acoder, c->fill_coder + i,
                                       dst[i] + x * blk_size,
-                                      c->pic.linesize[i], blk_size);
+                                      c->pic->linesize[i], blk_size);
                     break;
                 case IMAGE_BLOCK:
                     decode_image_block(acoder, c->image_coder + i,
                                        dst[i] + x * blk_size,
-                                       c->pic.linesize[i], blk_size);
+                                       c->pic->linesize[i], blk_size);
                     break;
                 case DCT_BLOCK:
                     decode_dct_block(acoder, c->dct_coder + i,
                                      dst[i] + x * blk_size,
-                                     c->pic.linesize[i], blk_size,
+                                     c->pic->linesize[i], blk_size,
                                      c->dctblock, x, y);
                     break;
                 case HAAR_BLOCK:
                     decode_haar_block(acoder, c->haar_coder + i,
                                       dst[i] + x * blk_size,
-                                      c->pic.linesize[i], blk_size,
+                                      c->pic->linesize[i], blk_size,
                                       c->hblock);
                     break;
                 }
@@ -793,17 +792,31 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                 }
             }
         }
-        dst[0] += c->pic.linesize[0] * 16;
-        dst[1] += c->pic.linesize[1] * 8;
-        dst[2] += c->pic.linesize[2] * 8;
+        dst[0] += c->pic->linesize[0] * 16;
+        dst[1] += c->pic->linesize[1] * 8;
+        dst[2] += c->pic->linesize[2] * 8;
     }
 
+    if ((ret = av_frame_ref(data, c->pic)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
 
     return buf_size;
 }
 
+static av_cold int mss3_decode_end(AVCodecContext *avctx)
+{
+    MSS3Context * const c = avctx->priv_data;
+    int i;
+
+    av_frame_free(&c->pic);
+    for (i = 0; i < 3; i++)
+        av_freep(&c->dct_coder[i].prev_dc);
+
+    return 0;
+}
+
 static av_cold int mss3_decode_init(AVCodecContext *avctx)
 {
     MSS3Context * const c = avctx->priv_data;
@@ -835,29 +848,22 @@ static av_cold int mss3_decode_init(AVCodecContext *avctx)
         }
     }
 
+    c->pic = av_frame_alloc();
+    if (!c->pic) {
+        mss3_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     avctx->pix_fmt     = AV_PIX_FMT_YUV420P;
-    avctx->coded_frame = &c->pic;
 
     init_coders(c);
 
     return 0;
 }
 
-static av_cold int mss3_decode_end(AVCodecContext *avctx)
-{
-    MSS3Context * const c = avctx->priv_data;
-    int i;
-
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    for (i = 0; i < 3; i++)
-        av_freep(&c->dct_coder[i].prev_dc);
-
-    return 0;
-}
-
 AVCodec ff_msa1_decoder = {
     .name           = "msa1",
+    .long_name      = NULL_IF_CONFIG_SMALL("MS ATC Screen"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MSA1,
     .priv_data_size = sizeof(MSS3Context),
@@ -865,5 +871,4 @@ AVCodec ff_msa1_decoder = {
     .close          = mss3_decode_end,
     .decode         = mss3_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MS ATC Screen"),
 };
diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c
index 7c714cb..fa85258 100644
--- a/libavcodec/mss4.c
+++ b/libavcodec/mss4.c
@@ -29,6 +29,7 @@
 #include "bytestream.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "mss34dsp.h"
 #include "unary.h"
 
@@ -125,8 +126,7 @@ static const uint8_t mss4_vec_entry_vlc_syms[2][9] = {
 #define MAX_ENTRIES  162
 
 typedef struct MSS4Context {
-    AVFrame    pic;
-    DSPContext dsp;
+    AVFrame   *pic;
 
     VLC        dc_vlc[2], ac_vlc[2];
     VLC        vec_entry_vlc[2];
@@ -297,10 +297,10 @@ static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb,
                 return ret;
             c->prev_dc[0][mb_x * 2 + i] = c->dc_cache[j][LEFT];
 
-            ff_mss34_dct_put(out + xpos * 8, c->pic.linesize[0],
+            ff_mss34_dct_put(out + xpos * 8, c->pic->linesize[0],
                              c->block);
         }
-        out += 8 * c->pic.linesize[0];
+        out += 8 * c->pic->linesize[0];
     }
 
     for (i = 1; i < 3; i++) {
@@ -320,7 +320,7 @@ static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb,
         for (j = 0; j < 16; j++) {
             for (k = 0; k < 8; k++)
                 AV_WN16A(out + k * 2, c->imgbuf[i][k + (j & ~1) * 4] * 0x101);
-            out += c->pic.linesize[i];
+            out += c->pic->linesize[i];
         }
     }
 
@@ -481,7 +481,7 @@ static int mss4_decode_image_block(MSS4Context *ctx, GetBitContext *gb,
 
     for (i = 0; i < 3; i++)
         for (j = 0; j < 16; j++)
-            memcpy(picdst[i] + mb_x * 16 + j * ctx->pic.linesize[i],
+            memcpy(picdst[i] + mb_x * 16 + j * ctx->pic->linesize[i],
                    ctx->imgbuf[i] + j * 16, 16);
 
     return 0;
@@ -554,20 +554,17 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    c->pic.reference    = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID    |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
-    c->pic.key_frame = (frame_type == INTRA_FRAME);
-    c->pic.pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I
+    c->pic->key_frame = (frame_type == INTRA_FRAME);
+    c->pic->pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I
                                                    : AV_PICTURE_TYPE_P;
     if (frame_type == SKIP_FRAME) {
         *got_frame      = 1;
-        *(AVFrame*)data = c->pic;
+        if ((ret = av_frame_ref(data, c->pic)) < 0)
+            return ret;
 
         return buf_size;
     }
@@ -582,9 +579,9 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     mb_width  = FFALIGN(width,  16) >> 4;
     mb_height = FFALIGN(height, 16) >> 4;
-    dst[0] = c->pic.data[0];
-    dst[1] = c->pic.data[1];
-    dst[2] = c->pic.data[2];
+    dst[0] = c->pic->data[0];
+    dst[1] = c->pic->data[1];
+    dst[2] = c->pic->data[2];
 
     memset(c->prev_vec, 0, sizeof(c->prev_vec));
     for (y = 0; y < mb_height; y++) {
@@ -618,17 +615,32 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             if (blk_type != DCT_BLOCK)
                 mss4_update_dc_cache(c, x);
         }
-        dst[0] += c->pic.linesize[0] * 16;
-        dst[1] += c->pic.linesize[1] * 16;
-        dst[2] += c->pic.linesize[2] * 16;
+        dst[0] += c->pic->linesize[0] * 16;
+        dst[1] += c->pic->linesize[1] * 16;
+        dst[2] += c->pic->linesize[2] * 16;
     }
 
+    if ((ret = av_frame_ref(data, c->pic)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
 
     return buf_size;
 }
 
+static av_cold int mss4_decode_end(AVCodecContext *avctx)
+{
+    MSS4Context * const c = avctx->priv_data;
+    int i;
+
+    av_frame_free(&c->pic);
+    for (i = 0; i < 3; i++)
+        av_freep(&c->prev_dc[i]);
+    mss4_free_vlcs(c);
+
+    return 0;
+}
+
 static av_cold int mss4_decode_init(AVCodecContext *avctx)
 {
     MSS4Context * const c = avctx->priv_data;
@@ -649,28 +661,20 @@ static av_cold int mss4_decode_init(AVCodecContext *avctx)
         }
     }
 
-    avctx->pix_fmt     = AV_PIX_FMT_YUV444P;
-    avctx->coded_frame = &c->pic;
-
-    return 0;
-}
-
-static av_cold int mss4_decode_end(AVCodecContext *avctx)
-{
-    MSS4Context * const c = avctx->priv_data;
-    int i;
+    c->pic = av_frame_alloc();
+    if (!c->pic) {
+        mss4_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    for (i = 0; i < 3; i++)
-        av_freep(&c->prev_dc[i]);
-    mss4_free_vlcs(c);
+    avctx->pix_fmt     = AV_PIX_FMT_YUV444P;
 
     return 0;
 }
 
 AVCodec ff_mts2_decoder = {
     .name           = "mts2",
+    .long_name      = NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MTS2,
     .priv_data_size = sizeof(MSS4Context),
@@ -678,5 +682,4 @@ AVCodec ff_mts2_decoder = {
     .close          = mss4_decode_end,
     .decode         = mss4_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"),
 };
diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c
index 860a893..7fd8633 100644
--- a/libavcodec/msvideo1.c
+++ b/libavcodec/msvideo1.c
@@ -34,6 +34,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 #define PALETTE_COUNT 256
 #define CHECK_STREAM_PTR(n) \
@@ -46,7 +47,7 @@
 typedef struct Msvideo1Context {
 
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     const unsigned char *buf;
     int size;
@@ -71,7 +72,9 @@ static av_cold int msvideo1_decode_init(AVCodecContext *avctx)
         avctx->pix_fmt = AV_PIX_FMT_RGB555;
     }
 
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -92,8 +95,8 @@ static void msvideo1_decode_8bit(Msvideo1Context *s)
     unsigned short flags;
     int skip_blocks;
     unsigned char colors[8];
-    unsigned char *pixels = s->frame.data[0];
-    int stride = s->frame.linesize[0];
+    unsigned char *pixels = s->frame->data[0];
+    int stride = s->frame->linesize[0];
 
     stream_ptr = 0;
     skip_blocks = 0;
@@ -173,7 +176,7 @@ static void msvideo1_decode_8bit(Msvideo1Context *s)
 
     /* make the palette available on the way out */
     if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
-        memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+        memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
 }
 
 static void msvideo1_decode_16bit(Msvideo1Context *s)
@@ -192,8 +195,8 @@ static void msvideo1_decode_16bit(Msvideo1Context *s)
     unsigned short flags;
     int skip_blocks;
     unsigned short colors[8];
-    unsigned short *pixels = (unsigned short *)s->frame.data[0];
-    int stride = s->frame.linesize[0] / 2;
+    unsigned short *pixels = (unsigned short *)s->frame->data[0];
+    int stride = s->frame->linesize[0] / 2;
 
     stream_ptr = 0;
     skip_blocks = 0;
@@ -292,15 +295,14 @@ static int msvideo1_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     Msvideo1Context *s = avctx->priv_data;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (s->mode_8bit) {
@@ -308,7 +310,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx,
 
         if (pal) {
             memcpy(s->pal, pal, AVPALETTE_SIZE);
-            s->frame.palette_has_changed = 1;
+            s->frame->palette_has_changed = 1;
         }
     }
 
@@ -317,8 +319,10 @@ static int msvideo1_decode_frame(AVCodecContext *avctx,
     else
         msvideo1_decode_16bit(s);
 
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -328,14 +332,14 @@ static av_cold int msvideo1_decode_end(AVCodecContext *avctx)
 {
     Msvideo1Context *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_msvideo1_decoder = {
     .name           = "msvideo1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Microsoft Video 1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_MSVIDEO1,
     .priv_data_size = sizeof(Msvideo1Context),
@@ -343,5 +347,4 @@ AVCodec ff_msvideo1_decoder = {
     .close          = msvideo1_decode_end,
     .decode         = msvideo1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Microsoft Video 1"),
 };
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index d81e9fc..bfaae34 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -31,7 +31,7 @@
 
 typedef struct MXpegDecodeContext {
     MJpegDecodeContext jpg;
-    AVFrame picture[2]; /* pictures array */
+    AVFrame *picture[2]; /* pictures array */
     int picture_index; /* index of current picture */
     int got_sof_data; /* true if SOF data successfully parsed */
     int got_mxm_bitmask; /* true if MXM bitmask available */
@@ -42,12 +42,36 @@ typedef struct MXpegDecodeContext {
     unsigned mb_width, mb_height; /* size of picture in MB's from MXM header */
 } MXpegDecodeContext;
 
+static av_cold int mxpeg_decode_end(AVCodecContext *avctx)
+{
+    MXpegDecodeContext *s = avctx->priv_data;
+    MJpegDecodeContext *jpg = &s->jpg;
+    int i;
+
+    jpg->picture_ptr = NULL;
+    ff_mjpeg_decode_end(avctx);
+
+    for (i = 0; i < 2; ++i)
+        av_frame_free(&s->picture[i]);
+
+    av_freep(&s->mxm_bitmask);
+    av_freep(&s->completion_bitmask);
+
+    return 0;
+}
+
 static av_cold int mxpeg_decode_init(AVCodecContext *avctx)
 {
     MXpegDecodeContext *s = avctx->priv_data;
 
-    s->picture[0].reference = s->picture[1].reference = 3;
-    s->jpg.picture_ptr      = &s->picture[0];
+    s->picture[0] = av_frame_alloc();
+    s->picture[1] = av_frame_alloc();
+    if (!s->picture[0] || !s->picture[1]) {
+        mxpeg_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
+    s->jpg.picture_ptr      = s->picture[0];
     return ff_mjpeg_decode_init(avctx);
 }
 
@@ -167,7 +191,6 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
     const uint8_t *unescaped_buf_ptr;
     int unescaped_buf_size;
     int start_code;
-    AVFrame *picture = data;
     int ret;
 
     buf_ptr = buf;
@@ -248,9 +271,9 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
                         break;
                     }
                     /* use stored SOF data to allocate current picture */
-                    if (jpg->picture_ptr->data[0])
-                        avctx->release_buffer(avctx, jpg->picture_ptr);
-                    if (ff_get_buffer(avctx, jpg->picture_ptr) < 0) {
+                    av_frame_unref(jpg->picture_ptr);
+                    if (ff_get_buffer(avctx, jpg->picture_ptr,
+                                      AV_GET_BUFFER_FLAG_REF) < 0) {
                         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                         return AVERROR(ENOMEM);
                     }
@@ -263,13 +286,14 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
                 }
 
                 if (s->got_mxm_bitmask) {
-                    AVFrame *reference_ptr = &s->picture[s->picture_index ^ 1];
+                    AVFrame *reference_ptr = s->picture[s->picture_index ^ 1];
                     if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0)
                         break;
 
                     /* allocate dummy reference picture if needed */
                     if (!reference_ptr->data[0] &&
-                        ff_get_buffer(avctx, reference_ptr) < 0) {
+                        ff_get_buffer(avctx, reference_ptr,
+                                      AV_GET_BUFFER_FLAG_REF) < 0) {
                         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                         return AVERROR(ENOMEM);
                     }
@@ -293,10 +317,13 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
 
 the_end:
     if (jpg->got_picture) {
+        int ret = av_frame_ref(data, jpg->picture_ptr);
+        if (ret < 0)
+            return ret;
         *got_frame = 1;
-        *picture = *jpg->picture_ptr;
+
         s->picture_index ^= 1;
-        jpg->picture_ptr = &s->picture[s->picture_index];
+        jpg->picture_ptr = s->picture[s->picture_index];
 
         if (!s->has_complete_frame) {
             if (!s->got_mxm_bitmask)
@@ -309,26 +336,6 @@ the_end:
     return buf_ptr - buf;
 }
 
-static av_cold int mxpeg_decode_end(AVCodecContext *avctx)
-{
-    MXpegDecodeContext *s = avctx->priv_data;
-    MJpegDecodeContext *jpg = &s->jpg;
-    int i;
-
-    jpg->picture_ptr = NULL;
-    ff_mjpeg_decode_end(avctx);
-
-    for (i = 0; i < 2; ++i) {
-        if (s->picture[i].data[0])
-            avctx->release_buffer(avctx, &s->picture[i]);
-    }
-
-    av_freep(&s->mxm_bitmask);
-    av_freep(&s->completion_bitmask);
-
-    return 0;
-}
-
 AVCodec ff_mxpeg_decoder = {
     .name           = "mxpeg",
     .long_name      = NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"),
diff --git a/libavcodec/nellymoser.c b/libavcodec/nellymoser.c
index 195e2e8..0740c75 100644
--- a/libavcodec/nellymoser.c
+++ b/libavcodec/nellymoser.c
@@ -33,7 +33,6 @@
 
 #include "nellymoser.h"
 #include "avcodec.h"
-#include "dsputil.h"
 
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c
index b6aa6f5..3b9b77c 100644
--- a/libavcodec/nellymoserdec.c
+++ b/libavcodec/nellymoserdec.c
@@ -32,10 +32,10 @@
  */
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/lfg.h"
 #include "libavutil/random_seed.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "fmtconvert.h"
 #include "internal.h"
@@ -48,11 +48,10 @@
 
 typedef struct NellyMoserDecodeContext {
     AVCodecContext* avctx;
-    AVFrame         frame;
     AVLFG           random_state;
     GetBitContext   gb;
     float           scale_bias;
-    DSPContext      dsp;
+    AVFloatDSPContext fdsp;
     FFTContext      imdct_ctx;
     DECLARE_ALIGNED(32, float, imdct_buf)[2][NELLY_BUF_LEN];
     float          *imdct_out;
@@ -107,7 +106,9 @@ static void nelly_decode_block(NellyMoserDecodeContext *s,
                (NELLY_BUF_LEN - NELLY_FILL_LEN) * sizeof(float));
 
         s->imdct_ctx.imdct_half(&s->imdct_ctx, s->imdct_out, aptr);
-        s->dsp.vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN/2, s->imdct_out, ff_sine_128, NELLY_BUF_LEN/2);
+        s->fdsp.vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN / 2,
+                                   s->imdct_out, ff_sine_128,
+                                   NELLY_BUF_LEN / 2);
         FFSWAP(float *, s->imdct_out, s->imdct_prev);
     }
 }
@@ -121,7 +122,7 @@ static av_cold int decode_init(AVCodecContext * avctx) {
     av_lfg_init(&s->random_state, 0);
     ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);
 
-    ff_dsputil_init(&s->dsp, avctx);
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     s->scale_bias = 1.0/(32768*8);
     avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
@@ -133,15 +134,13 @@ static av_cold int decode_init(AVCodecContext * avctx) {
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int decode_tag(AVCodecContext *avctx, void *data,
                       int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     NellyMoserDecodeContext *s = avctx->priv_data;
@@ -166,12 +165,12 @@ static int decode_tag(AVCodecContext *avctx, void *data,
      */
 
     /* get output buffer */
-    s->frame.nb_samples = NELLY_SAMPLES * blocks;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = NELLY_SAMPLES * blocks;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples_flt = (float   *)s->frame.data[0];
+    samples_flt = (float *)frame->data[0];
 
     for (i=0 ; i<blocks ; i++) {
         nelly_decode_block(s, buf, samples_flt);
@@ -179,8 +178,7 @@ static int decode_tag(AVCodecContext *avctx, void *data,
         buf += NELLY_BLOCK_LEN;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -195,6 +193,7 @@ static av_cold int decode_end(AVCodecContext * avctx) {
 
 AVCodec ff_nellymoser_decoder = {
     .name           = "nellymoser",
+    .long_name      = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_NELLYMOSER,
     .priv_data_size = sizeof(NellyMoserDecodeContext),
@@ -202,7 +201,6 @@ AVCodec ff_nellymoser_decoder = {
     .close          = decode_end,
     .decode         = decode_tag,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_PARAM_CHANGE,
-    .long_name      = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c
index 1222826..fc803a2 100644
--- a/libavcodec/nellymoserenc.c
+++ b/libavcodec/nellymoserenc.c
@@ -40,7 +40,6 @@
 #include "nellymoser.h"
 #include "avcodec.h"
 #include "audio_frame_queue.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "internal.h"
 #include "sinewin.h"
@@ -55,7 +54,6 @@
 typedef struct NellyMoserEncodeContext {
     AVCodecContext  *avctx;
     int             last_frame;
-    DSPContext      dsp;
     AVFloatDSPContext fdsp;
     FFTContext      mdct_ctx;
     AudioFrameQueue afq;
@@ -122,12 +120,12 @@ static void apply_mdct(NellyMoserEncodeContext *s)
     float *in1 = s->buf + NELLY_BUF_LEN;
     float *in2 = s->buf + 2 * NELLY_BUF_LEN;
 
-    s->fdsp.vector_fmul       (s->in_buff,                 in0, ff_sine_128, NELLY_BUF_LEN);
-    s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
+    s->fdsp.vector_fmul        (s->in_buff,                 in0, ff_sine_128, NELLY_BUF_LEN);
+    s->fdsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in1, ff_sine_128, NELLY_BUF_LEN);
     s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out, s->in_buff);
 
-    s->fdsp.vector_fmul       (s->in_buff,                 in1, ff_sine_128, NELLY_BUF_LEN);
-    s->dsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
+    s->fdsp.vector_fmul        (s->in_buff,                 in1, ff_sine_128, NELLY_BUF_LEN);
+    s->fdsp.vector_fmul_reverse(s->in_buff + NELLY_BUF_LEN, in2, ff_sine_128, NELLY_BUF_LEN);
     s->mdct_ctx.mdct_calc(&s->mdct_ctx, s->mdct_out + NELLY_BUF_LEN, s->in_buff);
 }
 
@@ -142,9 +140,6 @@ static av_cold int encode_end(AVCodecContext *avctx)
         av_free(s->path);
     }
     ff_af_queue_close(&s->afq);
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
 
     return 0;
 }
@@ -173,7 +168,6 @@ static av_cold int encode_init(AVCodecContext *avctx)
     s->avctx = avctx;
     if ((ret = ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0)) < 0)
         goto error;
-    ff_dsputil_init(&s->dsp, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     /* Generate overlap window */
@@ -190,14 +184,6 @@ static av_cold int encode_init(AVCodecContext *avctx)
         }
     }
 
-#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:
     encode_end(avctx);
@@ -420,6 +406,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_nellymoser_encoder = {
     .name           = "nellymoser",
+    .long_name      = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_NELLYMOSER,
     .priv_data_size = sizeof(NellyMoserEncodeContext),
@@ -427,7 +414,6 @@ AVCodec ff_nellymoser_encoder = {
     .encode2        = encode_frame,
     .close          = encode_end,
     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
-    .long_name      = NULL_IF_CONFIG_SMALL("Nellymoser Asao"),
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c
index e253bfb..4d244bd 100644
--- a/libavcodec/nuv.c
+++ b/libavcodec/nuv.c
@@ -27,11 +27,11 @@
 #include "libavutil/lzo.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "rtjpeg.h"
 
 typedef struct {
-    AVFrame pic;
+    AVFrame *pic;
     int codec_frameheader;
     int quality;
     int width, height;
@@ -137,8 +137,7 @@ static int codec_reinit(AVCodecContext *avctx, int width, int height,
             c->decomp_buf = ptr;
         ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
                               c->lq, c->cq);
-        if (c->pic.data[0])
-            avctx->release_buffer(avctx, &c->pic);
+        av_frame_unref(c->pic);
     } else if (quality != c->quality)
         ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
                               c->lq, c->cq);
@@ -154,9 +153,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     NuvContext *c      = avctx->priv_data;
     AVFrame *picture   = data;
     int orig_size      = buf_size;
-    int keyframe;
-    int result;
-    int ret;
+    int keyframe, ret;
+    int result, init_frame = !avctx->frame_number;
     enum {
         NUV_UNCOMPRESSED  = '0',
         NUV_RTJPEG        = '1',
@@ -233,19 +231,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         buf_size -= RTJPEG_HEADER_SIZE;
     }
 
-    if (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 |
-                          FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    result = avctx->reget_buffer(avctx, &c->pic);
+    if (keyframe) {
+        av_frame_unref(c->pic);
+        init_frame = 1;
+    }
+
+    result = ff_reget_buffer(avctx, c->pic);
     if (result < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return result;
     }
+    if (init_frame) {
+        memset(c->pic->data[0], 0,    avctx->height * c->pic->linesize[0]);
+        memset(c->pic->data[1], 0x80, avctx->height * c->pic->linesize[1] / 2);
+        memset(c->pic->data[2], 0x80, avctx->height * c->pic->linesize[2] / 2);
+    }
 
-    c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
-    c->pic.key_frame = keyframe;
+    c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    c->pic->key_frame = keyframe;
     // decompress/copy/whatever data
     switch (comptype) {
     case NUV_LZO:
@@ -255,19 +258,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             av_log(avctx, AV_LOG_ERROR, "uncompressed frame too short\n");
             height = buf_size / c->width / 3 * 2;
         }
-        copy_frame(&c->pic, buf, c->width, height);
+        copy_frame(c->pic, buf, c->width, height);
         break;
     }
     case NUV_RTJPEG_IN_LZO:
     case NUV_RTJPEG:
-        ret = ff_rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size);
+        ret = ff_rtjpeg_decode_frame_yuv420(&c->rtj, c->pic, buf, buf_size);
         if (ret < 0)
             return ret;
         break;
     case NUV_BLACK:
-        memset(c->pic.data[0], 0, c->width * c->height);
-        memset(c->pic.data[1], 128, c->width * c->height / 4);
-        memset(c->pic.data[2], 128, c->width * c->height / 4);
+        memset(c->pic->data[0], 0, c->width * c->height);
+        memset(c->pic->data[1], 128, c->width * c->height / 4);
+        memset(c->pic->data[2], 128, c->width * c->height / 4);
         break;
     case NUV_COPY_LAST:
         /* nothing more to do here */
@@ -277,7 +280,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    *picture   = c->pic;
+    if ((result = av_frame_ref(picture, c->pic)) < 0)
+        return result;
+
     *got_frame = 1;
     return orig_size;
 }
@@ -287,8 +292,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
     NuvContext *c  = avctx->priv_data;
     int ret;
 
+    c->pic = av_frame_alloc();
+    if (!c->pic)
+        return AVERROR(ENOMEM);
+
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-    c->pic.data[0] = NULL;
     c->decomp_buf  = NULL;
     c->quality     = -1;
     c->width       = 0;
@@ -312,14 +320,14 @@ static av_cold int decode_end(AVCodecContext *avctx)
     NuvContext *c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_free(&c->pic);
 
     return 0;
 }
 
 AVCodec ff_nuv_decoder = {
     .name           = "nuv",
+    .long_name      = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_NUV,
     .priv_data_size = sizeof(NuvContext),
@@ -327,5 +335,4 @@ AVCodec ff_nuv_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("NuppelVideo/RTJPEG"),
 };
diff --git a/libavcodec/old_codec_ids.h b/libavcodec/old_codec_ids.h
deleted file mode 100644
index 2b72e38..0000000
--- a/libavcodec/old_codec_ids.h
+++ /dev/null
@@ -1,366 +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 AVCODEC_OLD_CODEC_IDS_H
-#define AVCODEC_OLD_CODEC_IDS_H
-
-/*
- * This header exists to prevent new codec IDs from being accidentally added to
- * the deprecated list.
- * Do not include it directly. It will be removed on next major bump
- *
- * Do not add new items to this list. Use the AVCodecID enum instead.
- */
-
-    CODEC_ID_NONE = AV_CODEC_ID_NONE,
-
-    /* video codecs */
-    CODEC_ID_MPEG1VIDEO,
-    CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
-    CODEC_ID_MPEG2VIDEO_XVMC,
-    CODEC_ID_H261,
-    CODEC_ID_H263,
-    CODEC_ID_RV10,
-    CODEC_ID_RV20,
-    CODEC_ID_MJPEG,
-    CODEC_ID_MJPEGB,
-    CODEC_ID_LJPEG,
-    CODEC_ID_SP5X,
-    CODEC_ID_JPEGLS,
-    CODEC_ID_MPEG4,
-    CODEC_ID_RAWVIDEO,
-    CODEC_ID_MSMPEG4V1,
-    CODEC_ID_MSMPEG4V2,
-    CODEC_ID_MSMPEG4V3,
-    CODEC_ID_WMV1,
-    CODEC_ID_WMV2,
-    CODEC_ID_H263P,
-    CODEC_ID_H263I,
-    CODEC_ID_FLV1,
-    CODEC_ID_SVQ1,
-    CODEC_ID_SVQ3,
-    CODEC_ID_DVVIDEO,
-    CODEC_ID_HUFFYUV,
-    CODEC_ID_CYUV,
-    CODEC_ID_H264,
-    CODEC_ID_INDEO3,
-    CODEC_ID_VP3,
-    CODEC_ID_THEORA,
-    CODEC_ID_ASV1,
-    CODEC_ID_ASV2,
-    CODEC_ID_FFV1,
-    CODEC_ID_4XM,
-    CODEC_ID_VCR1,
-    CODEC_ID_CLJR,
-    CODEC_ID_MDEC,
-    CODEC_ID_ROQ,
-    CODEC_ID_INTERPLAY_VIDEO,
-    CODEC_ID_XAN_WC3,
-    CODEC_ID_XAN_WC4,
-    CODEC_ID_RPZA,
-    CODEC_ID_CINEPAK,
-    CODEC_ID_WS_VQA,
-    CODEC_ID_MSRLE,
-    CODEC_ID_MSVIDEO1,
-    CODEC_ID_IDCIN,
-    CODEC_ID_8BPS,
-    CODEC_ID_SMC,
-    CODEC_ID_FLIC,
-    CODEC_ID_TRUEMOTION1,
-    CODEC_ID_VMDVIDEO,
-    CODEC_ID_MSZH,
-    CODEC_ID_ZLIB,
-    CODEC_ID_QTRLE,
-    CODEC_ID_SNOW,
-    CODEC_ID_TSCC,
-    CODEC_ID_ULTI,
-    CODEC_ID_QDRAW,
-    CODEC_ID_VIXL,
-    CODEC_ID_QPEG,
-    CODEC_ID_PNG,
-    CODEC_ID_PPM,
-    CODEC_ID_PBM,
-    CODEC_ID_PGM,
-    CODEC_ID_PGMYUV,
-    CODEC_ID_PAM,
-    CODEC_ID_FFVHUFF,
-    CODEC_ID_RV30,
-    CODEC_ID_RV40,
-    CODEC_ID_VC1,
-    CODEC_ID_WMV3,
-    CODEC_ID_LOCO,
-    CODEC_ID_WNV1,
-    CODEC_ID_AASC,
-    CODEC_ID_INDEO2,
-    CODEC_ID_FRAPS,
-    CODEC_ID_TRUEMOTION2,
-    CODEC_ID_BMP,
-    CODEC_ID_CSCD,
-    CODEC_ID_MMVIDEO,
-    CODEC_ID_ZMBV,
-    CODEC_ID_AVS,
-    CODEC_ID_SMACKVIDEO,
-    CODEC_ID_NUV,
-    CODEC_ID_KMVC,
-    CODEC_ID_FLASHSV,
-    CODEC_ID_CAVS,
-    CODEC_ID_JPEG2000,
-    CODEC_ID_VMNC,
-    CODEC_ID_VP5,
-    CODEC_ID_VP6,
-    CODEC_ID_VP6F,
-    CODEC_ID_TARGA,
-    CODEC_ID_DSICINVIDEO,
-    CODEC_ID_TIERTEXSEQVIDEO,
-    CODEC_ID_TIFF,
-    CODEC_ID_GIF,
-    CODEC_ID_DXA,
-    CODEC_ID_DNXHD,
-    CODEC_ID_THP,
-    CODEC_ID_SGI,
-    CODEC_ID_C93,
-    CODEC_ID_BETHSOFTVID,
-    CODEC_ID_PTX,
-    CODEC_ID_TXD,
-    CODEC_ID_VP6A,
-    CODEC_ID_AMV,
-    CODEC_ID_VB,
-    CODEC_ID_PCX,
-    CODEC_ID_SUNRAST,
-    CODEC_ID_INDEO4,
-    CODEC_ID_INDEO5,
-    CODEC_ID_MIMIC,
-    CODEC_ID_RL2,
-    CODEC_ID_ESCAPE124,
-    CODEC_ID_DIRAC,
-    CODEC_ID_BFI,
-    CODEC_ID_CMV,
-    CODEC_ID_MOTIONPIXELS,
-    CODEC_ID_TGV,
-    CODEC_ID_TGQ,
-    CODEC_ID_TQI,
-    CODEC_ID_AURA,
-    CODEC_ID_AURA2,
-    CODEC_ID_V210X,
-    CODEC_ID_TMV,
-    CODEC_ID_V210,
-    CODEC_ID_DPX,
-    CODEC_ID_MAD,
-    CODEC_ID_FRWU,
-    CODEC_ID_FLASHSV2,
-    CODEC_ID_CDGRAPHICS,
-    CODEC_ID_R210,
-    CODEC_ID_ANM,
-    CODEC_ID_BINKVIDEO,
-    CODEC_ID_IFF_ILBM,
-    CODEC_ID_IFF_BYTERUN1,
-    CODEC_ID_KGV1,
-    CODEC_ID_YOP,
-    CODEC_ID_VP8,
-    CODEC_ID_PICTOR,
-    CODEC_ID_ANSI,
-    CODEC_ID_A64_MULTI,
-    CODEC_ID_A64_MULTI5,
-    CODEC_ID_R10K,
-    CODEC_ID_MXPEG,
-    CODEC_ID_LAGARITH,
-    CODEC_ID_PRORES,
-    CODEC_ID_JV,
-    CODEC_ID_DFA,
-    CODEC_ID_WMV3IMAGE,
-    CODEC_ID_VC1IMAGE,
-    CODEC_ID_UTVIDEO,
-    CODEC_ID_BMV_VIDEO,
-    CODEC_ID_VBLE,
-    CODEC_ID_DXTORY,
-    CODEC_ID_V410,
-    CODEC_ID_XWD,
-    CODEC_ID_CDXL,
-    CODEC_ID_XBM,
-    CODEC_ID_ZEROCODEC,
-    CODEC_ID_MSS1,
-    CODEC_ID_MSA1,
-    CODEC_ID_TSCC2,
-    CODEC_ID_MTS2,
-    CODEC_ID_CLLC,
-
-    /* various PCM "codecs" */
-    CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
-    CODEC_ID_PCM_S16LE = 0x10000,
-    CODEC_ID_PCM_S16BE,
-    CODEC_ID_PCM_U16LE,
-    CODEC_ID_PCM_U16BE,
-    CODEC_ID_PCM_S8,
-    CODEC_ID_PCM_U8,
-    CODEC_ID_PCM_MULAW,
-    CODEC_ID_PCM_ALAW,
-    CODEC_ID_PCM_S32LE,
-    CODEC_ID_PCM_S32BE,
-    CODEC_ID_PCM_U32LE,
-    CODEC_ID_PCM_U32BE,
-    CODEC_ID_PCM_S24LE,
-    CODEC_ID_PCM_S24BE,
-    CODEC_ID_PCM_U24LE,
-    CODEC_ID_PCM_U24BE,
-    CODEC_ID_PCM_S24DAUD,
-    CODEC_ID_PCM_ZORK,
-    CODEC_ID_PCM_S16LE_PLANAR,
-    CODEC_ID_PCM_DVD,
-    CODEC_ID_PCM_F32BE,
-    CODEC_ID_PCM_F32LE,
-    CODEC_ID_PCM_F64BE,
-    CODEC_ID_PCM_F64LE,
-    CODEC_ID_PCM_BLURAY,
-    CODEC_ID_PCM_LXF,
-    CODEC_ID_S302M,
-    CODEC_ID_PCM_S8_PLANAR,
-
-    /* various ADPCM codecs */
-    CODEC_ID_ADPCM_IMA_QT = 0x11000,
-    CODEC_ID_ADPCM_IMA_WAV,
-    CODEC_ID_ADPCM_IMA_DK3,
-    CODEC_ID_ADPCM_IMA_DK4,
-    CODEC_ID_ADPCM_IMA_WS,
-    CODEC_ID_ADPCM_IMA_SMJPEG,
-    CODEC_ID_ADPCM_MS,
-    CODEC_ID_ADPCM_4XM,
-    CODEC_ID_ADPCM_XA,
-    CODEC_ID_ADPCM_ADX,
-    CODEC_ID_ADPCM_EA,
-    CODEC_ID_ADPCM_G726,
-    CODEC_ID_ADPCM_CT,
-    CODEC_ID_ADPCM_SWF,
-    CODEC_ID_ADPCM_YAMAHA,
-    CODEC_ID_ADPCM_SBPRO_4,
-    CODEC_ID_ADPCM_SBPRO_3,
-    CODEC_ID_ADPCM_SBPRO_2,
-    CODEC_ID_ADPCM_THP,
-    CODEC_ID_ADPCM_IMA_AMV,
-    CODEC_ID_ADPCM_EA_R1,
-    CODEC_ID_ADPCM_EA_R3,
-    CODEC_ID_ADPCM_EA_R2,
-    CODEC_ID_ADPCM_IMA_EA_SEAD,
-    CODEC_ID_ADPCM_IMA_EA_EACS,
-    CODEC_ID_ADPCM_EA_XAS,
-    CODEC_ID_ADPCM_EA_MAXIS_XA,
-    CODEC_ID_ADPCM_IMA_ISS,
-    CODEC_ID_ADPCM_G722,
-    CODEC_ID_ADPCM_IMA_APC,
-
-    /* AMR */
-    CODEC_ID_AMR_NB = 0x12000,
-    CODEC_ID_AMR_WB,
-
-    /* RealAudio codecs*/
-    CODEC_ID_RA_144 = 0x13000,
-    CODEC_ID_RA_288,
-
-    /* various DPCM codecs */
-    CODEC_ID_ROQ_DPCM = 0x14000,
-    CODEC_ID_INTERPLAY_DPCM,
-    CODEC_ID_XAN_DPCM,
-    CODEC_ID_SOL_DPCM,
-
-    /* audio codecs */
-    CODEC_ID_MP2 = 0x15000,
-    CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
-    CODEC_ID_AAC,
-    CODEC_ID_AC3,
-    CODEC_ID_DTS,
-    CODEC_ID_VORBIS,
-    CODEC_ID_DVAUDIO,
-    CODEC_ID_WMAV1,
-    CODEC_ID_WMAV2,
-    CODEC_ID_MACE3,
-    CODEC_ID_MACE6,
-    CODEC_ID_VMDAUDIO,
-    CODEC_ID_FLAC,
-    CODEC_ID_MP3ADU,
-    CODEC_ID_MP3ON4,
-    CODEC_ID_SHORTEN,
-    CODEC_ID_ALAC,
-    CODEC_ID_WESTWOOD_SND1,
-    CODEC_ID_GSM, ///< as in Berlin toast format
-    CODEC_ID_QDM2,
-    CODEC_ID_COOK,
-    CODEC_ID_TRUESPEECH,
-    CODEC_ID_TTA,
-    CODEC_ID_SMACKAUDIO,
-    CODEC_ID_QCELP,
-    CODEC_ID_WAVPACK,
-    CODEC_ID_DSICINAUDIO,
-    CODEC_ID_IMC,
-    CODEC_ID_MUSEPACK7,
-    CODEC_ID_MLP,
-    CODEC_ID_GSM_MS, /* as found in WAV */
-    CODEC_ID_ATRAC3,
-    CODEC_ID_VOXWARE,
-    CODEC_ID_APE,
-    CODEC_ID_NELLYMOSER,
-    CODEC_ID_MUSEPACK8,
-    CODEC_ID_SPEEX,
-    CODEC_ID_WMAVOICE,
-    CODEC_ID_WMAPRO,
-    CODEC_ID_WMALOSSLESS,
-    CODEC_ID_ATRAC3P,
-    CODEC_ID_EAC3,
-    CODEC_ID_SIPR,
-    CODEC_ID_MP1,
-    CODEC_ID_TWINVQ,
-    CODEC_ID_TRUEHD,
-    CODEC_ID_MP4ALS,
-    CODEC_ID_ATRAC1,
-    CODEC_ID_BINKAUDIO_RDFT,
-    CODEC_ID_BINKAUDIO_DCT,
-    CODEC_ID_AAC_LATM,
-    CODEC_ID_QDMC,
-    CODEC_ID_CELT,
-    CODEC_ID_G723_1,
-    CODEC_ID_G729,
-    CODEC_ID_8SVX_EXP,
-    CODEC_ID_8SVX_FIB,
-    CODEC_ID_BMV_AUDIO,
-    CODEC_ID_RALF,
-    CODEC_ID_IAC,
-    CODEC_ID_ILBC,
-
-    /* subtitle codecs */
-    CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
-    CODEC_ID_DVD_SUBTITLE = 0x17000,
-    CODEC_ID_DVB_SUBTITLE,
-    CODEC_ID_TEXT,  ///< raw UTF-8 text
-    CODEC_ID_XSUB,
-    CODEC_ID_SSA,
-    CODEC_ID_MOV_TEXT,
-    CODEC_ID_HDMV_PGS_SUBTITLE,
-    CODEC_ID_DVB_TELETEXT,
-    CODEC_ID_SRT,
-
-    /* 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_PROBE = 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it
-
-    CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
-                                * stream (only used by libavformat) */
-    CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems
-                                * stream (only used by libavformat) */
-    CODEC_ID_FFMETADATA = 0x21000,   ///< Dummy codec for streams containing only metadata information.
-
-#endif /* AVCODEC_OLD_CODEC_IDS_H */
diff --git a/libavcodec/options.c b/libavcodec/options.c
index fc2a184..2e41ce4 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -70,7 +70,7 @@ static const AVClass *codec_child_class_next(const AVClass *prev)
 static const AVClass av_codec_context_class = {
     .class_name              = "AVCodecContext",
     .item_name               = context_to_name,
-    .option                  = options,
+    .option                  = avcodec_options,
     .version                 = LIBAVUTIL_VERSION_INT,
     .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
     .child_next              = codec_child_next,
@@ -88,8 +88,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
     av_opt_set_defaults(s);
 
     s->time_base           = (AVRational){0,1};
-    s->get_buffer          = avcodec_default_get_buffer;
-    s->release_buffer      = avcodec_default_release_buffer;
+    s->get_buffer2         = avcodec_default_get_buffer2;
     s->get_format          = avcodec_default_get_format;
     s->execute             = avcodec_default_execute;
     s->execute2            = avcodec_default_execute2;
@@ -97,7 +96,6 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
     s->pix_fmt             = AV_PIX_FMT_NONE;
     s->sample_fmt          = AV_SAMPLE_FMT_NONE;
 
-    s->reget_buffer        = avcodec_default_reget_buffer;
     s->reordered_opaque    = AV_NOPTS_VALUE;
     if(codec && codec->priv_data_size){
         if(!s->priv_data){
@@ -152,7 +150,6 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
     dest->codec           = NULL;
     dest->slice_offset    = NULL;
     dest->hwaccel         = NULL;
-    dest->thread_opaque   = NULL;
     dest->internal        = NULL;
 
     /* reallocate values that should be allocated separately */
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 57c80dd..8b3a4b6 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -22,6 +22,7 @@
 
 #include <float.h>
 #include <limits.h>
+#include <stdint.h>
 
 #include "libavutil/opt.h"
 #include "avcodec.h"
@@ -39,13 +40,14 @@
 
 #define AV_CODEC_DEFAULT_BITRATE 200*1000
 
-static const AVOption options[]={
+static const AVOption avcodec_options[] = {
 {"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, V|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 minimum/maximum bitrate. Lowering tolerance too much has an adverse effect on quality.",
        OFFSET(bit_rate_tolerance), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE*20 }, 1, INT_MAX, V|E},
 {"flags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, UINT_MAX, V|A|E|D, "flags"},
+{"unaligned", "allow decoders to produce unaligned output", 0, AV_OPT_TYPE_CONST, { .i64 = CODEC_FLAG_UNALIGNED }, INT_MIN, INT_MAX, V | D, "flags" },
 {"mv4", "use four motion vectors per macroblock (MPEG-4)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_4MV }, INT_MIN, INT_MAX, V|E, "flags"},
 {"qpel", "use 1/4-pel motion compensation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QPEL }, INT_MIN, INT_MAX, V|E, "flags"},
 {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
@@ -65,21 +67,13 @@ static const AVOption options[]={
 {"global_header", "place global headers in extradata instead of every keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_GLOBAL_HEADER }, INT_MIN, INT_MAX, V|A|E, "flags"},
 {"bitexact", "use only bitexact functions (except (I)DCT)", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_BITEXACT }, INT_MIN, INT_MAX, A|V|S|D|E, "flags"},
 {"aic", "H.263 advanced intra coding / MPEG-4 AC prediction", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_AC_PRED }, INT_MIN, INT_MAX, V|E, "flags"},
-#if FF_API_MPV_GLOBAL_OPTS
-{"cbp", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_CBP_RD }, INT_MIN, INT_MAX, V|E, "flags"},
-{"qprd", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_QP_RD }, INT_MIN, INT_MAX, V|E, "flags"},
-#endif
 {"ilme", "interlaced motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_INTERLACED_ME }, INT_MIN, INT_MAX, V|E, "flags"},
 {"cgop", "closed GOP", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_CLOSED_GOP }, INT_MIN, INT_MAX, V|E, "flags"},
+{"output_corrupt", "Output even potentially corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_OUTPUT_CORRUPT }, INT_MIN, INT_MAX, V|D, "flags"},
 {"fast", "allow non-spec-compliant speedup tricks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_FAST }, INT_MIN, INT_MAX, V|E, "flags2"},
-#if FF_API_MPV_GLOBAL_OPTS
-{"sgop", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_STRICT_GOP }, INT_MIN, INT_MAX, V|E, "flags2"},
-#endif
 {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "flags2"},
+{"ignorecrop", "ignore cropping information from sps", 1, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_IGNORE_CROP }, INT_MIN, INT_MAX, V|D, "flags2"},
 {"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
-#if FF_API_SUB_ID
-{"sub_id", NULL, OFFSET(sub_id), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#endif
 {"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"},
 {"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
@@ -92,7 +86,6 @@ static const AVOption options[]={
 {"x1", "X1 motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_X1 }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"hex", "hex motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" },
-{"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"extradata_size", NULL, OFFSET(extradata_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX},
 {"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E},
@@ -109,7 +102,7 @@ static const AVOption options[]={
 {"qmin", "minimum video quantizer scale (VBR)", OFFSET(qmin), AV_OPT_TYPE_INT, {.i64 = 2 }, -1, 69, V|E},
 {"qmax", "maximum video quantizer scale (VBR)", OFFSET(qmax), AV_OPT_TYPE_INT, {.i64 = 31 }, -1, 69, V|E},
 {"qdiff", "maximum difference between the quantizer scales (VBR)", OFFSET(max_qdiff), AV_OPT_TYPE_INT, {.i64 = 3 }, INT_MIN, INT_MAX, V|E},
-{"bf", "use 'frames' B frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, FF_MAX_B_FRAMES, V|E},
+{"bf", "use 'frames' B frames", OFFSET(max_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, -1, INT_MAX, V|E},
 {"b_qfactor", "QP factor between P- and B-frames", OFFSET(b_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
 {"rc_strategy", "ratecontrol method", OFFSET(rc_strategy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"b_strategy", "strategy to choose between I/P/B-frames", OFFSET(b_frame_strategy), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, V|E},
@@ -126,12 +119,16 @@ static const AVOption options[]={
 {"codec_tag", NULL, OFFSET(codec_tag), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"bug", "work around not autodetected encoder bugs", OFFSET(workaround_bugs), AV_OPT_TYPE_FLAGS, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
 {"autodetect", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AUTODETECT }, INT_MIN, INT_MAX, V|D, "bug"},
+#if FF_API_OLD_MSMPEG4
 {"old_msmpeg4", "some old lavc-generated MSMPEG4v3 files (no autodetection)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_OLD_MSMPEG4 }, INT_MIN, INT_MAX, V|D, "bug"},
+#endif
 {"xvid_ilace", "Xvid interlacing bug (autodetected if FOURCC == XVIX)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_XVID_ILACE }, INT_MIN, INT_MAX, V|D, "bug"},
 {"ump4", "(autodetected if FOURCC == UMP4)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_UMP4 }, INT_MIN, INT_MAX, V|D, "bug"},
 {"no_padding", "padding bug (autodetected)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_NO_PADDING }, INT_MIN, INT_MAX, V|D, "bug"},
 {"amv", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AMV }, INT_MIN, INT_MAX, V|D, "bug"},
+#if FF_API_AC_VLC
 {"ac_vlc", "illegal VLC bug (autodetected per FOURCC)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_AC_VLC }, INT_MIN, INT_MAX, V|D, "bug"},
+#endif
 {"qpel_chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA }, INT_MIN, INT_MAX, V|D, "bug"},
 {"std_qpel", "old standard qpel (autodetected per FOURCC/version)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_STD_QPEL }, INT_MIN, INT_MAX, V|D, "bug"},
 {"qpel_chroma2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_QPEL_CHROMA2 }, INT_MIN, INT_MAX, V|D, "bug"},
@@ -141,10 +138,6 @@ static const AVOption options[]={
 {"dc_clip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_DC_CLIP }, INT_MIN, INT_MAX, V|D, "bug"},
 {"ms", "work around various bugs in Microsoft's broken decoders", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_MS }, INT_MIN, INT_MAX, V|D, "bug"},
 {"trunc", "truncated frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_BUG_TRUNCATED}, INT_MIN, INT_MAX, V|D, "bug"},
-#if FF_API_MPV_GLOBAL_OPTS
-{"lelim", "single coefficient elimination threshold for luminance (negative values also consider DC coefficient)", OFFSET(luma_elim_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-{"celim", "single coefficient elimination threshold for chrominance (negative values also consider DC coefficient)", OFFSET(chroma_elim_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
 {"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|V|D|E, "strict"},
 {"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
 {"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, V|D|E, "strict"},
@@ -152,7 +145,7 @@ static const AVOption options[]={
 {"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
 {"experimental", "allow non-standardized experimental things", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, V|D|E, "strict"},
 {"b_qoffset", "QP offset between P- and B-frames", OFFSET(b_quant_offset), AV_OPT_TYPE_FLOAT, {.dbl = 1.25 }, -FLT_MAX, FLT_MAX, V|E},
-{"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"},
+{"err_detect", "set error detection flags", OFFSET(err_recognition), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 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"},
@@ -194,9 +187,6 @@ static const AVOption options[]={
 {"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"},
-#if FF_API_MMI
-{"mmi", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_MMI }, INT_MIN, INT_MAX, V|E|D, "idct"},
-#endif
 {"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"},
 {"sh4", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"},
@@ -204,9 +194,9 @@ static const AVOption options[]={
 {"simplearmv5te", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"simplearmv6", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"simpleneon", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"},
+#if FF_API_ARCH_ALPHA
 {"simplealpha", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"h264", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_H264 }, INT_MIN, INT_MAX, V|E|D, "idct"},
-{"vp3", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_VP3 }, INT_MIN, INT_MAX, V|E|D, "idct"},
+#endif
 {"ipp", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"xvidmmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVIDMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"faani", "floating point AAN IDCT", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"},
@@ -226,7 +216,9 @@ static const AVOption options[]={
 {"bitstream", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BITSTREAM }, INT_MIN, INT_MAX, V|D, "debug"},
 {"mb_type", "macroblock (MB) type", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
 {"qp", "per-block quantization parameter (QP)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_QP }, INT_MIN, INT_MAX, V|D, "debug"},
+#if FF_API_DEBUG_MV
 {"mv", "motion vector", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MV }, INT_MIN, INT_MAX, V|D, "debug"},
+#endif
 {"dct_coeff", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_DCT_COEFF }, INT_MIN, INT_MAX, V|D, "debug"},
 {"skip", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_SKIP }, INT_MIN, INT_MAX, V|D, "debug"},
 {"startcode", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_STARTCODE }, INT_MIN, INT_MAX, V|D, "debug"},
@@ -234,14 +226,18 @@ static const AVOption options[]={
 {"er", "error recognition", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_ER }, INT_MIN, INT_MAX, V|D, "debug"},
 {"mmco", "memory management control operations (H.264)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_MMCO }, INT_MIN, INT_MAX, V|D, "debug"},
 {"bugs", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUGS }, INT_MIN, INT_MAX, V|D, "debug"},
+#if FF_API_DEBUG_MV
 {"vis_qp", "visualize quantization parameter (QP), lower QP are tinted greener", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_QP }, INT_MIN, INT_MAX, V|D, "debug"},
 {"vis_mb_type", "visualize block types", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MB_TYPE }, INT_MIN, INT_MAX, V|D, "debug"},
+#endif
 {"buffers", "picture buffer allocations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_BUFFERS }, INT_MIN, INT_MAX, V|D, "debug"},
 {"thread_ops", "threading operations", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_THREADS }, INT_MIN, INT_MAX, V|D, "debug"},
+#if FF_API_DEBUG_MV
 {"vismv", "visualize motion vectors (MVs)", OFFSET(debug_mv), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|D, "debug_mv"},
 {"pf", "forward predicted MVs of P-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_P_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
 {"bf", "forward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_FOR }, INT_MIN, INT_MAX, V|D, "debug_mv"},
 {"bb", "backward predicted MVs of B-frames", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DEBUG_VIS_MV_B_BACK }, INT_MIN, INT_MAX, V|D, "debug_mv"},
+#endif
 {"cmp", "full-pel ME compare function", OFFSET(me_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"subcmp", "sub-pel ME compare function", OFFSET(me_sub_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"mbcmp", "macroblock compare function", OFFSET(mb_cmp), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "cmp_func"},
@@ -261,10 +257,6 @@ static const AVOption options[]={
 {"vsad", "sum of absolute vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSAD }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"vsse", "sum of squared vertical differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_VSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"nsse", "noise preserving sum of squared differences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_NSSE }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-#if CONFIG_SNOW_ENCODER
-{"w53", "5/3 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W53 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-{"w97", "9/7 wavelet, only used in snow", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_W97 }, INT_MIN, INT_MAX, V|E, "cmp_func"},
-#endif
 {"dctmax", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_DCTMAX }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"chroma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_CMP_CHROMA }, INT_MIN, INT_MAX, V|E, "cmp_func"},
 {"pre_dia_size", "diamond type & size for motion estimation pre-pass", OFFSET(pre_dia_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
@@ -273,9 +265,6 @@ static const AVOption options[]={
 {"me_range", "limit motion vectors range (1023 for DivX player)", OFFSET(me_range), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"ibias", "intra quant bias", OFFSET(intra_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
 {"pbias", "inter quant bias", OFFSET(inter_quant_bias), AV_OPT_TYPE_INT, {.i64 = FF_DEFAULT_QUANT_BIAS }, INT_MIN, INT_MAX, V|E},
-#if FF_API_COLOR_TABLE_ID
-{"color_table_id", NULL, OFFSET(color_table_id), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
-#endif
 {"global_quality", NULL, OFFSET(global_quality), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
 {"coder", NULL, OFFSET(coder_type), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "coder"},
 {"vlc", "variable length coder / Huffman coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_VLC }, INT_MIN, INT_MAX, V|E, "coder"},
@@ -285,7 +274,9 @@ static const AVOption options[]={
 {"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"},
 {"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+#if FF_API_XVMC
 {"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+#endif /* FF_API_XVMC */
 {"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "mbd"},
 {"simple", "use mbcmp (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
 {"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
@@ -296,13 +287,9 @@ static const AVOption options[]={
 {"lmax", "maximum Lagrange factor (VBR)", OFFSET(lmax), AV_OPT_TYPE_INT, {.i64 = 31*FF_QP2LAMBDA }, 0, INT_MAX, V|E},
 {"nr", "noise reduction", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"rc_init_occupancy", "number of bits which should be loaded into the rc buffer before decoding starts", OFFSET(rc_initial_buffer_occupancy), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#if FF_API_INTER_THRESHOLD
-{"inter_threshold", NULL, OFFSET(inter_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#endif
 {"flags2", NULL, OFFSET(flags2), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, V|A|E|D, "flags2"},
+#if FF_API_ERROR_RATE
 {"error", NULL, OFFSET(error_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
-#if FF_API_MPV_GLOBAL_OPTS
-{"qns", "deprecated, use mpegvideo private options instead", OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 #endif
 {"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, V|E|D, "threads"},
 {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
@@ -322,6 +309,8 @@ static const AVOption options[]={
 {"aac_he_v2", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_HE_V2 }, INT_MIN, INT_MAX, A|E, "profile"},
 {"aac_ld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_LD }, INT_MIN, INT_MAX, A|E, "profile"},
 {"aac_eld", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_AAC_ELD }, INT_MIN, INT_MAX, A|E, "profile"},
+{"mpeg2_aac_low", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_LOW }, INT_MIN, INT_MAX, A|E, "profile"},
+{"mpeg2_aac_he", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_MPEG2_AAC_HE }, INT_MIN, INT_MAX, A|E, "profile"},
 {"dts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS }, INT_MIN, INT_MAX, A|E, "profile"},
 {"dts_es", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_ES }, INT_MIN, INT_MAX, A|E, "profile"},
 {"dts_96_24", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_96_24 }, INT_MIN, INT_MAX, A|E, "profile"},
@@ -352,9 +341,6 @@ static const AVOption options[]={
 {"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},
-#if FF_API_MPV_GLOBAL_OPTS
-{"skiprd", "Deprecated, use mpegvideo private options instead", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SKIP_RD }, INT_MIN, INT_MAX, V|E, "flags2"},
-#endif
 {"sc_factor", "multiplied by qscale for each frame and added to scene_change_score", OFFSET(scenechange_factor), AV_OPT_TYPE_INT, {.i64 = 6 }, 0, INT_MAX, V|E},
 {"mv0_threshold", NULL, OFFSET(mv0_threshold), AV_OPT_TYPE_INT, {.i64 = 256 }, 0, INT_MAX, V|E},
 {"b_sensitivity", "adjust sensitivity of b_frame_strategy 1", OFFSET(b_sensitivity), AV_OPT_TYPE_INT, {.i64 = 40 }, 1, INT_MAX, V|E},
@@ -402,6 +388,7 @@ static const AVOption options[]={
 {"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"},
+{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|D },
 {NULL},
 };
 
diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c
index dba4771..8535d3d 100644
--- a/libavcodec/pamenc.c
+++ b/libavcodec/pamenc.c
@@ -22,14 +22,12 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
-#include "pnm.h"
-
 
 static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *pict, int *got_packet)
 {
-    PNMContext *s     = avctx->priv_data;
-    AVFrame * const p = &s->picture;
+    uint8_t *bytestream_start, *bytestream, *bytestream_end;
+    const AVFrame * const p = pict;
     int i, h, w, n, linesize, depth, maxval, ret;
     const char *tuple_type;
     uint8_t *ptr;
@@ -41,13 +39,9 @@ static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         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;
+    bytestream_start =
+    bytestream       = pkt->data;
+    bytestream_end   = pkt->data + pkt->size;
 
     h = avctx->height;
     w = avctx->width;
@@ -79,10 +73,10 @@ static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     default:
         return -1;
     }
-    snprintf(s->bytestream, s->bytestream_end - s->bytestream,
+    snprintf(bytestream, bytestream_end - bytestream,
              "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
              w, h, depth, maxval, tuple_type);
-    s->bytestream += strlen(s->bytestream);
+    bytestream += strlen(bytestream);
 
     ptr      = p->data[0];
     linesize = p->linesize[0];
@@ -94,36 +88,53 @@ static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         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;
+                bytestream_put_be24(&bytestream, v);
+                *bytestream++ = v >> 24;
             }
             ptr += linesize;
         }
     } else {
         for (i = 0; i < h; i++) {
-            memcpy(s->bytestream, ptr, n);
-            s->bytestream += n;
-            ptr           += linesize;
+            memcpy(bytestream, ptr, n);
+            bytestream += n;
+            ptr        += linesize;
         }
     }
 
-    pkt->size   = s->bytestream - s->bytestream_start;
+    pkt->size   = bytestream - bytestream_start;
     pkt->flags |= AV_PKT_FLAG_KEY;
     *got_packet = 1;
     return 0;
 }
 
+static av_cold int pam_encode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+
+    return 0;
+}
+
+static av_cold int pam_encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
 
 AVCodec ff_pam_encoder = {
     .name           = "pam",
+    .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PAM,
-    .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
+    .init           = pam_encode_init,
+    .close          = pam_encode_close,
     .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
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
 };
diff --git a/libavcodec/parser.c b/libavcodec/parser.c
index 6e755f6..511f1f3 100644
--- a/libavcodec/parser.c
+++ b/libavcodec/parser.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
 #include <string.h>
 
 #include "parser.h"
diff --git a/libavcodec/pcm-bluray.c b/libavcodec/pcm-bluray.c
new file mode 100644
index 0000000..7e4dcf8
--- /dev/null
+++ b/libavcodec/pcm-bluray.c
@@ -0,0 +1,315 @@
+/*
+ * LPCM codecs for PCM format found in Blu-ray PCM streams
+ * Copyright (c) 2009, 2013 Christian Schmidt
+ *
+ * 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
+ * PCM codec for Blu-ray PCM audio tracks
+ */
+
+#include "libavutil/channel_layout.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+/*
+ * Channel Mapping according to
+ * Blu-ray Disc Read-Only Format Version 1
+ * Part 3: Audio Visual Basic Specifications
+ * mono     M1    X
+ * stereo   L     R
+ * 3/0      L     R    C    X
+ * 2/1      L     R    S    X
+ * 3/1      L     R    C    S
+ * 2/2      L     R    LS   RS
+ * 3/2      L     R    C    LS    RS    X
+ * 3/2+lfe  L     R    C    LS    RS    lfe
+ * 3/4      L     R    C    LS    Rls   Rrs  RS   X
+ * 3/4+lfe  L     R    C    LS    Rls   Rrs  RS   lfe
+ */
+
+/**
+ * Parse the header of a LPCM frame read from a Blu-ray MPEG-TS stream
+ * @param avctx the codec context
+ * @param header pointer to the first four bytes of the data packet
+ */
+static int pcm_bluray_parse_header(AVCodecContext *avctx,
+                                   const uint8_t *header)
+{
+    static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 };
+    static const uint32_t channel_layouts[16] = {
+        0, AV_CH_LAYOUT_MONO, 0, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND,
+        AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_2_2,
+        AV_CH_LAYOUT_5POINT0, AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_7POINT0,
+        AV_CH_LAYOUT_7POINT1, 0, 0, 0, 0
+    };
+    static const uint8_t channels[16] = {
+        0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0
+    };
+    uint8_t channel_layout = header[2] >> 4;
+
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n",
+                header[0], header[1], header[2], header[3]);
+
+    /* 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");
+        return AVERROR_INVALIDDATA;
+    }
+    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;
+
+    /* get the sample rate. Not all values are used. */
+    switch (header[2] & 0x0f) {
+    case 1:
+        avctx->sample_rate = 48000;
+        break;
+    case 4:
+        avctx->sample_rate = 96000;
+        break;
+    case 5:
+        avctx->sample_rate = 192000;
+        break;
+    default:
+        avctx->sample_rate = 0;
+        av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n",
+               header[2] & 0x0f);
+        return AVERROR_INVALIDDATA;
+    }
+
+    /*
+     * get the channel number (and mapping). Not all values are used.
+     * It must be noted that the number of channels in the MPEG stream can
+     * differ from the actual meaningful number, e.g. mono audio still has two
+     * channels, one being empty.
+     */
+    avctx->channel_layout  = channel_layouts[channel_layout];
+    avctx->channels        =        channels[channel_layout];
+    if (!avctx->channels) {
+        av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n",
+               channel_layout);
+        return AVERROR_INVALIDDATA;
+    }
+
+    avctx->bit_rate = FFALIGN(avctx->channels, 2) * avctx->sample_rate *
+                      avctx->bits_per_coded_sample;
+
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_dlog(avctx,
+                "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %d bit/s\n",
+                avctx->channels, avctx->bits_per_coded_sample,
+                avctx->sample_rate, avctx->bit_rate);
+    return 0;
+}
+
+static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
+                                   int *got_frame_ptr, AVPacket *avpkt)
+{
+    AVFrame *frame     = data;
+    const uint8_t *src = avpkt->data;
+    int buf_size = avpkt->size;
+    GetByteContext gb;
+    int num_source_channels, channel, retval;
+    int sample_size, samples;
+    int16_t *dst16;
+    int32_t *dst32;
+
+    if (buf_size < 4) {
+        av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((retval = pcm_bluray_parse_header(avctx, src)))
+        return retval;
+    src += 4;
+    buf_size -= 4;
+
+    bytestream2_init(&gb, src, buf_size);
+
+    /* There's always an even number of channels in the source */
+    num_source_channels = FFALIGN(avctx->channels, 2);
+    sample_size = (num_source_channels *
+                   (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
+    samples = buf_size / sample_size;
+
+    /* get output buffer */
+    frame->nb_samples = samples;
+    if ((retval = ff_get_buffer(avctx, frame, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return retval;
+    }
+    dst16 = (int16_t *)frame->data[0];
+    dst32 = (int32_t *)frame->data[0];
+
+    if (samples) {
+        switch (avctx->channel_layout) {
+            /* cases with same number of source and coded channels */
+        case AV_CH_LAYOUT_STEREO:
+        case AV_CH_LAYOUT_4POINT0:
+        case AV_CH_LAYOUT_2_2:
+            samples *= num_source_channels;
+            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
+#if HAVE_BIGENDIAN
+                bytestream2_get_buffer(&gb, dst16, buf_size);
+#else
+                do {
+                    *dst16++ = bytestream2_get_be16u(&gb);
+                } while (--samples);
+#endif
+            } else {
+                do {
+                    *dst32++ = bytestream2_get_be24u(&gb) << 8;
+                } while (--samples);
+            }
+            break;
+        /* cases where number of source channels = coded channels + 1 */
+        case AV_CH_LAYOUT_MONO:
+        case AV_CH_LAYOUT_SURROUND:
+        case AV_CH_LAYOUT_2_1:
+        case AV_CH_LAYOUT_5POINT0:
+            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
+                do {
+#if HAVE_BIGENDIAN
+                    bytestream2_get_buffer(&gb, dst16, avctx->channels * 2);
+                    dst16 += avctx->channels;
+#else
+                    channel = avctx->channels;
+                    do {
+                        *dst16++ = bytestream2_get_be16u(&gb);
+                    } while (--channel);
+#endif
+                    bytestream2_skip(&gb, 2);
+                } while (--samples);
+            } else {
+                do {
+                    channel = avctx->channels;
+                    do {
+                        *dst32++ = bytestream2_get_be24u(&gb) << 8;
+                    } while (--channel);
+                    bytestream2_skip(&gb, 3);
+                } while (--samples);
+            }
+            break;
+            /* remapping: L, R, C, LBack, RBack, LF */
+        case AV_CH_LAYOUT_5POINT1:
+            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
+                do {
+                    dst16[0] = bytestream2_get_be16u(&gb);
+                    dst16[1] = bytestream2_get_be16u(&gb);
+                    dst16[2] = bytestream2_get_be16u(&gb);
+                    dst16[4] = bytestream2_get_be16u(&gb);
+                    dst16[5] = bytestream2_get_be16u(&gb);
+                    dst16[3] = bytestream2_get_be16u(&gb);
+                    dst16 += 6;
+                } while (--samples);
+            } else {
+                do {
+                    dst32[0] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[1] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[2] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[4] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[5] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[3] = bytestream2_get_be24u(&gb) << 8;
+                    dst32 += 6;
+                } while (--samples);
+            }
+            break;
+            /* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */
+        case AV_CH_LAYOUT_7POINT0:
+            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
+                do {
+                    dst16[0] = bytestream2_get_be16u(&gb);
+                    dst16[1] = bytestream2_get_be16u(&gb);
+                    dst16[2] = bytestream2_get_be16u(&gb);
+                    dst16[5] = bytestream2_get_be16u(&gb);
+                    dst16[3] = bytestream2_get_be16u(&gb);
+                    dst16[4] = bytestream2_get_be16u(&gb);
+                    dst16[6] = bytestream2_get_be16u(&gb);
+                    dst16 += 7;
+                    bytestream2_skip(&gb, 2);
+                } while (--samples);
+            } else {
+                do {
+                    dst32[0] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[1] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[2] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[5] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[3] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[4] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[6] = bytestream2_get_be24u(&gb) << 8;
+                    dst32 += 7;
+                    bytestream2_skip(&gb, 3);
+                } while (--samples);
+            }
+            break;
+            /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */
+        case AV_CH_LAYOUT_7POINT1:
+            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
+                do {
+                    dst16[0] = bytestream2_get_be16u(&gb);
+                    dst16[1] = bytestream2_get_be16u(&gb);
+                    dst16[2] = bytestream2_get_be16u(&gb);
+                    dst16[6] = bytestream2_get_be16u(&gb);
+                    dst16[4] = bytestream2_get_be16u(&gb);
+                    dst16[5] = bytestream2_get_be16u(&gb);
+                    dst16[7] = bytestream2_get_be16u(&gb);
+                    dst16[3] = bytestream2_get_be16u(&gb);
+                    dst16 += 8;
+                } while (--samples);
+            } else {
+                do {
+                    dst32[0] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[1] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[2] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[6] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[4] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[5] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[7] = bytestream2_get_be24u(&gb) << 8;
+                    dst32[3] = bytestream2_get_be24u(&gb) << 8;
+                    dst32 += 8;
+                } while (--samples);
+            }
+            break;
+        }
+    }
+
+    *got_frame_ptr = 1;
+
+    retval = bytestream2_tell(&gb);
+    if (avctx->debug & FF_DEBUG_BITSTREAM)
+        av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n",
+                retval, buf_size);
+    return retval + 4;
+}
+
+AVCodec ff_pcm_bluray_decoder = {
+    .name           = "pcm_bluray",
+    .long_name      = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_PCM_BLURAY,
+    .decode         = pcm_bluray_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .sample_fmts    = (const enum AVSampleFormat[]){
+        AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE
+    },
+};
diff --git a/libavcodec/pcm-dvd.c b/libavcodec/pcm-dvd.c
new file mode 100644
index 0000000..172e93a
--- /dev/null
+++ b/libavcodec/pcm-dvd.c
@@ -0,0 +1,288 @@
+/*
+ * LPCM codecs for PCM formats found in Video DVD streams
+ * Copyright (c) 2013 Christian Schmidt
+ *
+ * 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
+ * LPCM codecs for PCM formats found in Video DVD streams
+ */
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+typedef struct PCMDVDContext {
+    uint32_t last_header;    // Cached header to see if parsing is needed
+    int block_size;          // Size of a block of samples in bytes
+    int samples_per_block;   // Number of samples per channel per block
+    int groups_per_block;    // Number of 20/24bit sample groups per block
+    uint8_t *extra_samples;  // Pointer to leftover samples from a frame
+    int extra_sample_count;  // Number of leftover samples in the buffer
+} PCMDVDContext;
+
+static av_cold int pcm_dvd_decode_init(AVCodecContext *avctx)
+{
+    PCMDVDContext *s = avctx->priv_data;
+
+    /* Invalid header to force parsing of the first header */
+    s->last_header = -1;
+    /* reserve space for 8 channels, 3 bytes/sample, 4 samples/block */
+    if (!(s->extra_samples = av_malloc(8 * 3 * 4)))
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
+static av_cold int pcm_dvd_decode_uninit(AVCodecContext *avctx)
+{
+    PCMDVDContext *s = avctx->priv_data;
+
+    av_freep(&s->extra_samples);
+
+    return 0;
+}
+
+static int pcm_dvd_parse_header(AVCodecContext *avctx, const uint8_t *header)
+{
+    /* no traces of 44100 and 32000Hz in any commercial software or player */
+    static const uint32_t frequencies[4] = { 48000, 96000, 44100, 32000 };
+    PCMDVDContext *s = avctx->priv_data;
+    int header_int = (header[0] & 0xe0) | (header[1] << 8) | (header[2] << 16);
+
+    /* early exit if the header didn't change apart from the frame number */
+    if (s->last_header == header_int)
+        return 0;
+
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_dlog(avctx, "pcm_dvd_parse_header: header = %02x%02x%02x\n",
+                header[0], header[1], header[2]);
+    /*
+     * header[0] emphasis (1), muse(1), reserved(1), frame number(5)
+     * header[1] quant (2), freq(2), reserved(1), channels(3)
+     * header[2] dynamic range control (0x80 = off)
+     */
+
+    /* Discard potentially existing leftover samples from old channel layout */
+    s->extra_sample_count = 0;
+
+    /* get the sample depth and derive the sample format from it */
+    avctx->bits_per_coded_sample = 16 + (header[1] >> 6 & 3) * 4;
+    if (avctx->bits_per_coded_sample == 28) {
+        av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n");
+        return AVERROR_INVALIDDATA;
+    }
+    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;
+
+    /* get the sample rate */
+    avctx->sample_rate = frequencies[header[1] >> 4 & 3];
+
+    /* get the number of channels */
+    avctx->channels = 1 + (header[1] & 7);
+    /* calculate the bitrate */
+    avctx->bit_rate = avctx->channels *
+                      avctx->sample_rate *
+                      avctx->bits_per_coded_sample;
+
+    /* 4 samples form a group in 20/24bit PCM on DVD Video.
+     * A block is formed by the number of groups that are
+     * needed to complete a set of samples for each channel. */
+    if (avctx->bits_per_coded_sample == 16) {
+        s->samples_per_block = 1;
+        s->block_size        = avctx->channels * 2;
+    } else {
+        switch (avctx->channels) {
+        case 1:
+        case 2:
+        case 4:
+            /* one group has all the samples needed */
+            s->block_size        = 4 * avctx->bits_per_coded_sample / 8;
+            s->samples_per_block = 4 / avctx->channels;
+            s->groups_per_block  = 1;
+            break;
+        case 8:
+            /* two groups have all the samples needed */
+            s->block_size        = 8 * avctx->bits_per_coded_sample / 8;
+            s->samples_per_block = 1;
+            s->groups_per_block  = 2;
+            break;
+        default:
+            /* need avctx->channels groups */
+            s->block_size        = 4 * avctx->channels *
+                                   avctx->bits_per_coded_sample / 8;
+            s->samples_per_block = 4;
+            s->groups_per_block  = avctx->channels;
+            break;
+        }
+    }
+
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_dlog(avctx,
+                "pcm_dvd_parse_header: %d channels, %d bits per sample, %d Hz, %d bit/s\n",
+                avctx->channels, avctx->bits_per_coded_sample,
+                avctx->sample_rate, avctx->bit_rate);
+
+    s->last_header = header_int;
+
+    return 0;
+}
+
+static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src,
+                                    void *dst, int blocks)
+{
+    PCMDVDContext *s = avctx->priv_data;
+    int16_t *dst16   = dst;
+    int32_t *dst32   = dst;
+    GetByteContext gb;
+    int i;
+    uint8_t t;
+    int samples;
+
+    bytestream2_init(&gb, src, blocks * s->block_size);
+    switch (avctx->bits_per_coded_sample) {
+    case 16:
+#if HAVE_BIGENDIAN
+        bytestream2_get_buffer(&gb, dst16, blocks * s->block_size);
+        dst16 += blocks * s->block_size / 2;
+#else
+        samples = blocks * avctx->channels;
+        do {
+            *dst16++ = bytestream2_get_be16u(&gb);
+        } while (--samples);
+#endif
+        return dst16;
+    case 20:
+        do {
+            for (i = s->groups_per_block; i; i--) {
+                dst32[0] = bytestream2_get_be16u(&gb) << 16;
+                dst32[1] = bytestream2_get_be16u(&gb) << 16;
+                dst32[2] = bytestream2_get_be16u(&gb) << 16;
+                dst32[3] = bytestream2_get_be16u(&gb) << 16;
+                t = bytestream2_get_byteu(&gb);
+                *dst32 += (t & 0xf0) << 8;
+                *dst32 += (t & 0x0f) << 12;
+                t = bytestream2_get_byteu(&gb);
+                *dst32 += (t & 0xf0) << 8;
+                *dst32 += (t & 0x0f) << 12;
+            }
+        } while (--blocks);
+        return dst32;
+    case 24:
+        do {
+            for (i = s->groups_per_block; i; i--) {
+                dst32[0] = bytestream2_get_be16u(&gb) << 16;
+                dst32[1] = bytestream2_get_be16u(&gb) << 16;
+                dst32[2] = bytestream2_get_be16u(&gb) << 16;
+                dst32[3] = bytestream2_get_be16u(&gb) << 16;
+                *dst32++ += bytestream2_get_byteu(&gb) << 8;
+                *dst32++ += bytestream2_get_byteu(&gb) << 8;
+                *dst32++ += bytestream2_get_byteu(&gb) << 8;
+                *dst32++ += bytestream2_get_byteu(&gb) << 8;
+            }
+        } while (--blocks);
+        return dst32;
+    default:
+        return NULL;
+    }
+}
+
+static int pcm_dvd_decode_frame(AVCodecContext *avctx, void *data,
+                                int *got_frame_ptr, AVPacket *avpkt)
+{
+    AVFrame *frame     = data;
+    const uint8_t *src = avpkt->data;
+    int buf_size       = avpkt->size;
+    PCMDVDContext *s   = avctx->priv_data;
+    int retval;
+    int blocks;
+    void *dst;
+
+    if (buf_size < 3) {
+        av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if ((retval = pcm_dvd_parse_header(avctx, src)))
+        return retval;
+    src      += 3;
+    buf_size -= 3;
+
+    blocks = (buf_size + s->extra_sample_count) / s->block_size;
+
+    /* get output buffer */
+    frame->nb_samples = blocks * s->samples_per_block;
+    if ((retval = ff_get_buffer(avctx, frame, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return retval;
+    }
+    dst = frame->data[0];
+
+    /* consume leftover samples from last packet */
+    if (s->extra_sample_count) {
+        int missing_samples = s->block_size - s->extra_sample_count;
+        if (buf_size >= missing_samples) {
+            memcpy(s->extra_samples + s->extra_sample_count, src,
+                   missing_samples);
+            dst = pcm_dvd_decode_samples(avctx, s->extra_samples, dst, 1);
+            src += missing_samples;
+            buf_size -= missing_samples;
+            s->extra_sample_count = 0;
+            blocks--;
+        } else {
+            /* new packet still doesn't have enough samples */
+            memcpy(s->extra_samples + s->extra_sample_count, src, buf_size);
+            s->extra_sample_count += buf_size;
+            return avpkt->size;
+        }
+    }
+
+    /* decode remaining complete samples */
+    if (blocks) {
+        pcm_dvd_decode_samples(avctx, src, dst, blocks);
+        buf_size -= blocks * s->block_size;
+    }
+
+    /* store leftover samples */
+    if (buf_size) {
+        src += blocks * s->block_size;
+        memcpy(s->extra_samples, src, buf_size);
+        s->extra_sample_count = buf_size;
+    }
+
+    *got_frame_ptr = 1;
+
+    return avpkt->size;
+}
+
+AVCodec ff_pcm_dvd_decoder = {
+    .name           = "pcm_dvd",
+    .long_name      = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for DVD media"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_PCM_DVD,
+    .priv_data_size = sizeof(PCMDVDContext),
+    .init           = pcm_dvd_decode_init,
+    .decode         = pcm_dvd_decode_frame,
+    .close          = pcm_dvd_decode_uninit,
+    .capabilities   = CODEC_CAP_DR1,
+    .sample_fmts    = (const enum AVSampleFormat[]) {
+        AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE
+    }
+};
diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c
deleted file mode 100644
index c8c683d..0000000
--- a/libavcodec/pcm-mpeg.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * LPCM codecs for PCM formats found in MPEG streams
- * Copyright (c) 2009 Christian Schmidt
- *
- * 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
- * PCM codecs for encodings found in MPEG streams (DVD/Blu-ray)
- */
-
-#include "libavutil/channel_layout.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-
-/*
- * Channel Mapping according to
- * Blu-ray Disc Read-Only Format Version 1
- * Part 3: Audio Visual Basic Specifications
- * mono     M1    X
- * stereo   L     R
- * 3/0      L     R    C    X
- * 2/1      L     R    S    X
- * 3/1      L     R    C    S
- * 2/2      L     R    LS   RS
- * 3/2      L     R    C    LS    RS    X
- * 3/2+lfe  L     R    C    LS    RS    lfe
- * 3/4      L     R    C    LS    Rls   Rrs  RS   X
- * 3/4+lfe  L     R    C    LS    Rls   Rrs  RS   lfe
- */
-
-/**
- * Parse the header of a LPCM frame read from a MPEG-TS stream
- * @param avctx the codec context
- * @param header pointer to the first four bytes of the data packet
- */
-static int pcm_bluray_parse_header(AVCodecContext *avctx,
-                                   const uint8_t *header)
-{
-    static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 };
-    static const uint32_t channel_layouts[16] = {
-        0, AV_CH_LAYOUT_MONO, 0, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND,
-        AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_2_2, AV_CH_LAYOUT_5POINT0,
-        AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_7POINT0, AV_CH_LAYOUT_7POINT1, 0, 0, 0, 0
-    };
-    static const uint8_t channels[16] = {
-        0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0
-    };
-    uint8_t channel_layout = header[2] >> 4;
-
-    if (avctx->debug & FF_DEBUG_PICT_INFO)
-        av_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n",
-                header[0], header[1], header[2], header[3]);
-
-    /* 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");
-        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;
-
-    /* get the sample rate. Not all values are used. */
-    switch (header[2] & 0x0f) {
-    case 1:
-        avctx->sample_rate = 48000;
-        break;
-    case 4:
-        avctx->sample_rate = 96000;
-        break;
-    case 5:
-        avctx->sample_rate = 192000;
-        break;
-    default:
-        avctx->sample_rate = 0;
-        av_log(avctx, AV_LOG_ERROR, "reserved sample rate (%d)\n",
-               header[2] & 0x0f);
-        return -1;
-    }
-
-    /*
-     * get the channel number (and mapping). Not all values are used.
-     * It must be noted that the number of channels in the MPEG stream can
-     * differ from the actual meaningful number, e.g. mono audio still has two
-     * channels, one being empty.
-     */
-    avctx->channel_layout  = channel_layouts[channel_layout];
-    avctx->channels        =        channels[channel_layout];
-    if (!avctx->channels) {
-        av_log(avctx, AV_LOG_ERROR, "reserved channel configuration (%d)\n",
-               channel_layout);
-        return -1;
-    }
-
-    avctx->bit_rate = FFALIGN(avctx->channels, 2) * avctx->sample_rate *
-                      avctx->bits_per_coded_sample;
-
-    if (avctx->debug & FF_DEBUG_PICT_INFO)
-        av_dlog(avctx,
-                "pcm_bluray_parse_header: %d channels, %d bits per sample, %d Hz, %d bit/s\n",
-                avctx->channels, avctx->bits_per_coded_sample,
-                avctx->sample_rate, avctx->bit_rate);
-    return 0;
-}
-
-typedef struct PCMBRDecode {
-    AVFrame frame;
-} PCMBRDecode;
-
-static av_cold int pcm_bluray_decode_init(AVCodecContext * avctx)
-{
-    PCMBRDecode *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
-    return 0;
-}
-
-static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
-                                   int *got_frame_ptr, AVPacket *avpkt)
-{
-    const uint8_t *src = avpkt->data;
-    int buf_size = avpkt->size;
-    PCMBRDecode *s = avctx->priv_data;
-    GetByteContext gb;
-    int num_source_channels, channel, retval;
-    int sample_size, samples;
-    int16_t *dst16;
-    int32_t *dst32;
-
-    if (buf_size < 4) {
-        av_log(avctx, AV_LOG_ERROR, "PCM packet too small\n");
-        return -1;
-    }
-
-    if (pcm_bluray_parse_header(avctx, src))
-        return -1;
-    src += 4;
-    buf_size -= 4;
-
-    bytestream2_init(&gb, src, buf_size);
-
-    /* There's always an even number of channels in the source */
-    num_source_channels = FFALIGN(avctx->channels, 2);
-    sample_size = (num_source_channels * (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3;
-    samples = buf_size / sample_size;
-
-    /* get output buffer */
-    s->frame.nb_samples = samples;
-    if ((retval = ff_get_buffer(avctx, &s->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return retval;
-    }
-    dst16 = (int16_t *)s->frame.data[0];
-    dst32 = (int32_t *)s->frame.data[0];
-
-    if (samples) {
-        switch (avctx->channel_layout) {
-            /* cases with same number of source and coded channels */
-        case AV_CH_LAYOUT_STEREO:
-        case AV_CH_LAYOUT_4POINT0:
-        case AV_CH_LAYOUT_2_2:
-            samples *= num_source_channels;
-            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
-#if HAVE_BIGENDIAN
-                bytestream2_get_buffer(&gb, dst16, buf_size);
-#else
-                do {
-                    *dst16++ = bytestream2_get_be16u(&gb);
-                } while (--samples);
-#endif
-            } else {
-                do {
-                    *dst32++ = bytestream2_get_be24u(&gb) << 8;
-                } while (--samples);
-            }
-            break;
-        /* cases where number of source channels = coded channels + 1 */
-        case AV_CH_LAYOUT_MONO:
-        case AV_CH_LAYOUT_SURROUND:
-        case AV_CH_LAYOUT_2_1:
-        case AV_CH_LAYOUT_5POINT0:
-            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
-                do {
-#if HAVE_BIGENDIAN
-                    bytestream2_get_buffer(&gb, dst16, avctx->channels * 2);
-                    dst16 += avctx->channels;
-#else
-                    channel = avctx->channels;
-                    do {
-                        *dst16++ = bytestream2_get_be16u(&gb);
-                    } while (--channel);
-#endif
-                    bytestream2_skip(&gb, 2);
-                } while (--samples);
-            } else {
-                do {
-                    channel = avctx->channels;
-                    do {
-                        *dst32++ = bytestream2_get_be24u(&gb) << 8;
-                    } while (--channel);
-                    bytestream2_skip(&gb, 3);
-                } while (--samples);
-            }
-            break;
-            /* remapping: L, R, C, LBack, RBack, LF */
-        case AV_CH_LAYOUT_5POINT1:
-            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
-                do {
-                    dst16[0] = bytestream2_get_be16u(&gb);
-                    dst16[1] = bytestream2_get_be16u(&gb);
-                    dst16[2] = bytestream2_get_be16u(&gb);
-                    dst16[4] = bytestream2_get_be16u(&gb);
-                    dst16[5] = bytestream2_get_be16u(&gb);
-                    dst16[3] = bytestream2_get_be16u(&gb);
-                    dst16 += 6;
-                } while (--samples);
-            } else {
-                do {
-                    dst32[0] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[1] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[2] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[4] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[5] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[3] = bytestream2_get_be24u(&gb) << 8;
-                    dst32 += 6;
-                } while (--samples);
-            }
-            break;
-            /* remapping: L, R, C, LSide, LBack, RBack, RSide, <unused> */
-        case AV_CH_LAYOUT_7POINT0:
-            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
-                do {
-                    dst16[0] = bytestream2_get_be16u(&gb);
-                    dst16[1] = bytestream2_get_be16u(&gb);
-                    dst16[2] = bytestream2_get_be16u(&gb);
-                    dst16[5] = bytestream2_get_be16u(&gb);
-                    dst16[3] = bytestream2_get_be16u(&gb);
-                    dst16[4] = bytestream2_get_be16u(&gb);
-                    dst16[6] = bytestream2_get_be16u(&gb);
-                    dst16 += 7;
-                    bytestream2_skip(&gb, 2);
-                } while (--samples);
-            } else {
-                do {
-                    dst32[0] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[1] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[2] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[5] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[3] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[4] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[6] = bytestream2_get_be24u(&gb) << 8;
-                    dst32 += 7;
-                    bytestream2_skip(&gb, 3);
-                } while (--samples);
-            }
-            break;
-            /* remapping: L, R, C, LSide, LBack, RBack, RSide, LF */
-        case AV_CH_LAYOUT_7POINT1:
-            if (AV_SAMPLE_FMT_S16 == avctx->sample_fmt) {
-                do {
-                    dst16[0] = bytestream2_get_be16u(&gb);
-                    dst16[1] = bytestream2_get_be16u(&gb);
-                    dst16[2] = bytestream2_get_be16u(&gb);
-                    dst16[6] = bytestream2_get_be16u(&gb);
-                    dst16[4] = bytestream2_get_be16u(&gb);
-                    dst16[5] = bytestream2_get_be16u(&gb);
-                    dst16[7] = bytestream2_get_be16u(&gb);
-                    dst16[3] = bytestream2_get_be16u(&gb);
-                    dst16 += 8;
-                } while (--samples);
-            } else {
-                do {
-                    dst32[0] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[1] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[2] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[6] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[4] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[5] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[7] = bytestream2_get_be24u(&gb) << 8;
-                    dst32[3] = bytestream2_get_be24u(&gb) << 8;
-                    dst32 += 8;
-                } while (--samples);
-            }
-            break;
-        }
-    }
-
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
-
-    retval = bytestream2_tell(&gb);
-    if (avctx->debug & FF_DEBUG_BITSTREAM)
-        av_dlog(avctx, "pcm_bluray_decode_frame: decoded %d -> %d bytes\n",
-                retval, buf_size);
-    return retval + 4;
-}
-
-AVCodec ff_pcm_bluray_decoder = {
-    .name           = "pcm_bluray",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_PCM_BLURAY,
-    .priv_data_size = sizeof(PCMBRDecode),
-    .init           = pcm_bluray_decode_init,
-    .decode         = pcm_bluray_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .sample_fmts    = (const enum AVSampleFormat[]){
-        AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE
-    },
-    .long_name      = NULL_IF_CONFIG_SMALL("PCM signed 16|20|24-bit big-endian for Blu-ray media"),
-};
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index 5cc989b..9fadcb7 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -48,7 +48,7 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx)
     avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id);
     avctx->block_align           = avctx->channels * avctx->bits_per_coded_sample / 8;
     avctx->bit_rate              = avctx->block_align * avctx->sample_rate * 8;
-    avctx->coded_frame           = avcodec_alloc_frame();
+    avctx->coded_frame           = av_frame_alloc();
     if (!avctx->coded_frame)
         return AVERROR(ENOMEM);
 
@@ -199,7 +199,6 @@ static int pcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 }
 
 typedef struct PCMDecode {
-    AVFrame frame;
     short   table[256];
 } PCMDecode;
 
@@ -231,9 +230,6 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
     if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
         avctx->bits_per_raw_sample = av_get_bits_per_sample(avctx->codec->id);
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -254,12 +250,37 @@ static av_cold int pcm_decode_init(AVCodecContext *avctx)
         dst += size / 8;                                                \
     }
 
+#if HAVE_BIGENDIAN
+#define DECODE_PLANAR(size, endian, src, dst, n, shift, offset)         \
+    {                                                                   \
+        int av_unused n2;                                               \
+        n /= avctx->channels;                                           \
+        for (c = 0; c < avctx->channels; c++) {                         \
+            samples = frame->extended_data[c];                          \
+            n2 = n;                                                     \
+            DECODE(size, endian, src, samples, n2, 0, 0)                \
+        }                                                               \
+    }
+#else
+#define DECODE_PLANAR(size, endian, src, dst, n, shift, offset)         \
+    {                                                                   \
+        int av_unused n2;                                               \
+        n /= avctx->channels;                                           \
+        for (c = 0; c < avctx->channels; c++) {                         \
+            samples = frame->extended_data[c];                          \
+            memcpy(samples, src, n * size / 8);                         \
+            src += n * size / 8;                                        \
+        }                                                               \
+    }
+#endif /* HAVE_BIGENDIAN */
+
 static int pcm_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
     const uint8_t *src = avpkt->data;
     int buf_size       = avpkt->size;
     PCMDecode *s       = avctx->priv_data;
+    AVFrame *frame     = data;
     int sample_size, c, n, ret, samples_per_block;
     uint8_t *samples;
     int32_t *dst_int32_t;
@@ -268,16 +289,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
 
     /* av_get_bits_per_sample returns 0 for AV_CODEC_ID_PCM_DVD */
     samples_per_block = 1;
-    if (avctx->codec->id == AV_CODEC_ID_PCM_DVD) {
-        if (avctx->bits_per_coded_sample != 20 &&
-            avctx->bits_per_coded_sample != 24) {
-            av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n");
-            return AVERROR(EINVAL);
-        }
-        /* 2 samples are interleaved per block in PCM_DVD */
-        samples_per_block = 2;
-        sample_size       = avctx->bits_per_coded_sample * 2 / 8;
-    } else if (avctx->codec_id == AV_CODEC_ID_PCM_LXF) {
+    if (avctx->codec_id == AV_CODEC_ID_PCM_LXF) {
         /* we process 40-bit blocks per channel for LXF */
         samples_per_block = 2;
         sample_size       = 5;
@@ -301,12 +313,12 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
     n = buf_size / sample_size;
 
     /* get output buffer */
-    s->frame.nb_samples = n * samples_per_block / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = n * samples_per_block / avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = s->frame.data[0];
+    samples = frame->data[0];
 
     switch (avctx->codec->id) {
     case AV_CODEC_ID_PCM_U32LE:
@@ -337,21 +349,14 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
         }
         break;
     case AV_CODEC_ID_PCM_S16LE_PLANAR:
-    {
-        int av_unused n2;
-        n /= avctx->channels;
-        for (c = 0; c < avctx->channels; c++) {
-            samples = s->frame.extended_data[c];
-#if HAVE_BIGENDIAN
-            n2 = n;
-            DECODE(16, le16, src, samples, n2, 0, 0)
-#else
-            memcpy(samples, src, n * 2);
-            src += n * 2;
-#endif
-        }
+        DECODE_PLANAR(16, le16, src, samples, n, 0, 0);
+        break;
+    case AV_CODEC_ID_PCM_S24LE_PLANAR:
+        DECODE_PLANAR(32, le24, src, samples, n, 8, 0);
+        break;
+    case AV_CODEC_ID_PCM_S32LE_PLANAR:
+        DECODE_PLANAR(32, le32, src, samples, n, 0, 0);
         break;
-    }
     case AV_CODEC_ID_PCM_U16LE:
         DECODE(16, le16, src, samples, n, 0, 0x8000)
         break;
@@ -411,43 +416,12 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
             samples += 2;
         }
         break;
-    case AV_CODEC_ID_PCM_DVD:
-    {
-        const uint8_t *src8;
-        dst_int32_t = (int32_t *)s->frame.data[0];
-        n /= avctx->channels;
-        switch (avctx->bits_per_coded_sample) {
-        case 20:
-            while (n--) {
-                c    = avctx->channels;
-                src8 = src + 4 * c;
-                while (c--) {
-                    *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8   & 0xf0) <<  8);
-                    *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++ & 0x0f) << 12);
-                }
-                src = src8;
-            }
-            break;
-        case 24:
-            while (n--) {
-                c    = avctx->channels;
-                src8 = src + 4 * c;
-                while (c--) {
-                    *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8);
-                    *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8);
-                }
-                src = src8;
-            }
-            break;
-        }
-        break;
-    }
     case AV_CODEC_ID_PCM_LXF:
     {
         int i;
         n /= avctx->channels;
         for (c = 0; c < avctx->channels; c++) {
-            dst_int32_t = (int32_t *)s->frame.extended_data[c];
+            dst_int32_t = (int32_t *)frame->extended_data[c];
             for (i = 0; i < n; i++) {
                 // extract low 20 bits and expand to 32 bits
                 *dst_int32_t++ =  (src[2]         << 28) |
@@ -470,8 +444,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
         return -1;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
@@ -480,6 +453,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
 #define PCM_ENCODER_1(id_, sample_fmt_, name_, long_name_)                  \
 AVCodec ff_ ## name_ ## _encoder = {                                        \
     .name         = #name_,                                                 \
+    .long_name    = NULL_IF_CONFIG_SMALL(long_name_),                       \
     .type         = AVMEDIA_TYPE_AUDIO,                                     \
     .id           = AV_CODEC_ID_ ## id_,                                    \
     .init         = pcm_encode_init,                                        \
@@ -488,7 +462,6 @@ AVCodec ff_ ## name_ ## _encoder = {                                        \
     .capabilities = CODEC_CAP_VARIABLE_FRAME_SIZE,                          \
     .sample_fmts  = (const enum AVSampleFormat[]){ sample_fmt_,             \
                                                    AV_SAMPLE_FMT_NONE },    \
-    .long_name    = NULL_IF_CONFIG_SMALL(long_name_),                       \
 }
 
 #define PCM_ENCODER_2(cf, id, sample_fmt, name, long_name)                  \
@@ -502,6 +475,7 @@ AVCodec ff_ ## name_ ## _encoder = {                                        \
 #define PCM_DECODER_1(id_, sample_fmt_, name_, long_name_)                  \
 AVCodec ff_ ## name_ ## _decoder = {                                        \
     .name           = #name_,                                               \
+    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),                     \
     .type           = AVMEDIA_TYPE_AUDIO,                                   \
     .id             = AV_CODEC_ID_ ## id_,                                  \
     .priv_data_size = sizeof(PCMDecode),                                    \
@@ -510,7 +484,6 @@ AVCodec ff_ ## name_ ## _decoder = {                                        \
     .capabilities   = CODEC_CAP_DR1,                                        \
     .sample_fmts    = (const enum AVSampleFormat[]){ sample_fmt_,           \
                                                      AV_SAMPLE_FMT_NONE },  \
-    .long_name      = NULL_IF_CONFIG_SMALL(long_name_),                     \
 }
 
 #define PCM_DECODER_2(cf, id, sample_fmt, name, long_name)                  \
@@ -526,7 +499,6 @@ AVCodec ff_ ## name_ ## _decoder = {                                        \
 
 /* Note: Do not forget to add new entries to the Makefile as well. */
 PCM_CODEC  (PCM_ALAW,         AV_SAMPLE_FMT_S16, pcm_alaw,         "PCM A-law");
-PCM_DECODER(PCM_DVD,          AV_SAMPLE_FMT_S32, pcm_dvd,          "PCM signed 20|24-bit big-endian");
 PCM_CODEC  (PCM_F32BE,        AV_SAMPLE_FMT_FLT, pcm_f32be,        "PCM 32-bit floating point big-endian");
 PCM_CODEC  (PCM_F32LE,        AV_SAMPLE_FMT_FLT, pcm_f32le,        "PCM 32-bit floating point little-endian");
 PCM_CODEC  (PCM_F64BE,        AV_SAMPLE_FMT_DBL, pcm_f64be,        "PCM 64-bit floating point big-endian");
@@ -540,8 +512,10 @@ PCM_DECODER(PCM_S16LE_PLANAR, AV_SAMPLE_FMT_S16P, pcm_s16le_planar, "PCM 16-bit
 PCM_CODEC  (PCM_S24BE,        AV_SAMPLE_FMT_S32, pcm_s24be,        "PCM signed 24-bit big-endian");
 PCM_CODEC  (PCM_S24DAUD,      AV_SAMPLE_FMT_S16, pcm_s24daud,      "PCM D-Cinema audio signed 24-bit");
 PCM_CODEC  (PCM_S24LE,        AV_SAMPLE_FMT_S32, pcm_s24le,        "PCM signed 24-bit little-endian");
+PCM_DECODER(PCM_S24LE_PLANAR, AV_SAMPLE_FMT_S32P,pcm_s24le_planar, "PCM signed 24-bit little-endian planar");
 PCM_CODEC  (PCM_S32BE,        AV_SAMPLE_FMT_S32, pcm_s32be,        "PCM signed 32-bit big-endian");
 PCM_CODEC  (PCM_S32LE,        AV_SAMPLE_FMT_S32, pcm_s32le,        "PCM signed 32-bit little-endian");
+PCM_DECODER(PCM_S32LE_PLANAR, AV_SAMPLE_FMT_S32P,pcm_s32le_planar, "PCM signed 32-bit little-endian planar");
 PCM_CODEC  (PCM_U8,           AV_SAMPLE_FMT_U8,  pcm_u8,           "PCM unsigned 8-bit");
 PCM_CODEC  (PCM_U16BE,        AV_SAMPLE_FMT_S16, pcm_u16be,        "PCM unsigned 16-bit big-endian");
 PCM_CODEC  (PCM_U16LE,        AV_SAMPLE_FMT_S16, pcm_u16le,        "PCM unsigned 16-bit little-endian");
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index 223429d..61c971e 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -28,19 +28,6 @@
 #include "get_bits.h"
 #include "internal.h"
 
-typedef struct PCXContext {
-    AVFrame picture;
-} PCXContext;
-
-static av_cold int pcx_init(AVCodecContext *avctx) {
-    PCXContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame= &s->picture;
-
-    return 0;
-}
-
 /**
  * @return advanced src pointer
  */
@@ -48,19 +35,20 @@ static const uint8_t *pcx_rle_decode(const uint8_t *src,
                                      const uint8_t *end,
                                      uint8_t *dst,
                                      unsigned int bytes_per_scanline,
-                                     int compressed) {
+                                     int compressed)
+{
     unsigned int i = 0;
     unsigned char run, value;
 
     if (compressed) {
         while (i < bytes_per_scanline && src < end) {
-            run = 1;
+            run   = 1;
             value = *src++;
             if (value >= 0xc0 && src < end) {
-                run = value & 0x3f;
+                run   = value & 0x3f;
                 value = *src++;
             }
-            while (i<bytes_per_scanline && run--)
+            while (i < bytes_per_scanline && run--)
                 dst[i++] = value;
         }
     } else {
@@ -71,22 +59,23 @@ static const uint8_t *pcx_rle_decode(const uint8_t *src,
     return src;
 }
 
-static void pcx_palette(const uint8_t **src, uint32_t *dst, unsigned int pallen) {
+static void pcx_palette(const uint8_t **src, uint32_t *dst,
+                        unsigned int pallen)
+{
     unsigned int i;
 
-    for (i=0; i<pallen; i++)
+    for (i = 0; i < pallen; i++)
         *dst++ = bytestream_get_be24(src);
     if (pallen < 256)
         memset(dst, 0, (256 - pallen) * sizeof(*dst));
 }
 
 static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                            AVPacket *avpkt) {
+                            AVPacket *avpkt)
+{
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    PCXContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+    int buf_size       = avpkt->size;
+    AVFrame *const p   = data;
     int compressed, xmin, ymin, xmax, ymax;
     unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x,
                  bytes_per_scanline;
@@ -98,64 +87,60 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     if (buf[0] != 0x0a || buf[1] > 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);
+    xmin       = AV_RL16(buf + 4);
+    ymin       = AV_RL16(buf + 6);
+    xmax       = AV_RL16(buf + 8);
+    ymax       = AV_RL16(buf + 10);
 
     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);
+    bytes_per_line     = AV_RL16(buf + 66);
     nplanes            = buf[65];
     bytes_per_scanline = nplanes * bytes_per_line;
 
-    if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8 ||
+    if (bytes_per_scanline < (w * bits_per_pixel * nplanes + 7) / 8 ||
         (!compressed && bytes_per_scanline > buf_size / h)) {
         av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    switch ((nplanes<<8) + bits_per_pixel) {
-        case 0x0308:
-            avctx->pix_fmt = AV_PIX_FMT_RGB24;
-            break;
-        case 0x0108:
-        case 0x0104:
-        case 0x0102:
-        case 0x0101:
-        case 0x0401:
-        case 0x0301:
-        case 0x0201:
-            avctx->pix_fmt = AV_PIX_FMT_PAL8;
-            break;
-        default:
-            av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n");
-            return -1;
+    switch ((nplanes << 8) + bits_per_pixel) {
+    case 0x0308:
+        avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        break;
+    case 0x0108:
+    case 0x0104:
+    case 0x0102:
+    case 0x0101:
+    case 0x0401:
+    case 0x0301:
+    case 0x0201:
+        avctx->pix_fmt = AV_PIX_FMT_PAL8;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n");
+        return AVERROR_INVALIDDATA;
     }
 
     buf += 128;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
+        return ret;
 
-    if (av_image_check_size(w, h, 0, avctx))
-        return -1;
-    if (w != avctx->width || h != avctx->height)
-        avcodec_set_dimensions(avctx, w, h);
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     p->pict_type = AV_PICTURE_TYPE_I;
@@ -168,25 +153,25 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR(ENOMEM);
 
     if (nplanes == 3 && bits_per_pixel == 8) {
-        for (y=0; y<h; y++) {
+        for (y = 0; y < h; y++) {
             buf = pcx_rle_decode(buf, buf_end,
                                  scanline, bytes_per_scanline, compressed);
 
-            for (x=0; x<w; x++) {
-                ptr[3*x  ] = scanline[x                    ];
-                ptr[3*x+1] = scanline[x+ bytes_per_line    ];
-                ptr[3*x+2] = scanline[x+(bytes_per_line<<1)];
+            for (x = 0; x < w; x++) {
+                ptr[3 * x]     = scanline[x];
+                ptr[3 * x + 1] = scanline[x + bytes_per_line];
+                ptr[3 * x + 2] = scanline[x + (bytes_per_line << 1)];
             }
 
             ptr += stride;
         }
-
     } else if (nplanes == 1 && bits_per_pixel == 8) {
         const uint8_t *palstart = bufstart + buf_size - 769;
 
         if (buf_size < 769) {
             av_log(avctx, AV_LOG_ERROR, "File is too short\n");
-            ret = buf_size;
+            ret = avctx->err_recognition & AV_EF_EXPLODE ?
+                  AVERROR_INVALIDDATA : buf_size;
             goto end;
         }
 
@@ -202,36 +187,35 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         }
         if (*buf++ != 12) {
             av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n");
-            ret = buf_size;
+            ret = avctx->err_recognition & AV_EF_EXPLODE ?
+                  AVERROR_INVALIDDATA : buf_size;
             goto end;
         }
-
     } else if (nplanes == 1) {   /* all packed formats, max. 16 colors */
         GetBitContext s;
 
-        for (y=0; y<h; y++) {
-            init_get_bits(&s, scanline, bytes_per_scanline<<3);
+        for (y = 0; y < h; y++) {
+            init_get_bits(&s, scanline, bytes_per_scanline << 3);
 
             buf = pcx_rle_decode(buf, buf_end,
                                  scanline, bytes_per_scanline, compressed);
 
-            for (x=0; x<w; x++)
+            for (x = 0; x < w; x++)
                 ptr[x] = get_bits(&s, bits_per_pixel);
             ptr += stride;
         }
-
     } else {    /* planar, 4, 8 or 16 colors */
         int i;
 
-        for (y=0; y<h; y++) {
+        for (y = 0; y < h; y++) {
             buf = pcx_rle_decode(buf, buf_end,
                                  scanline, bytes_per_scanline, compressed);
 
-            for (x=0; x<w; x++) {
-                int m = 0x80 >> (x&7), v = 0;
-                for (i=nplanes - 1; i>=0; i--) {
+            for (x = 0; x < w; x++) {
+                int m = 0x80 >> (x & 7), v = 0;
+                for (i = nplanes - 1; i >= 0; i--) {
                     v <<= 1;
-                    v  += !!(scanline[i*bytes_per_line + (x>>3)] & m);
+                    v  += !!(scanline[i * bytes_per_line + (x >> 3)] & m);
                 }
                 ptr[x] = v;
             }
@@ -240,13 +224,12 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     if (nplanes == 1 && bits_per_pixel == 8) {
-        pcx_palette(&buf, (uint32_t *) p->data[1], 256);
+        pcx_palette(&buf, (uint32_t *)p->data[1], 256);
     } else if (bits_per_pixel < 8) {
-        const uint8_t *palette = bufstart+16;
-        pcx_palette(&palette, (uint32_t *) p->data[1], 16);
+        const uint8_t *palette = bufstart + 16;
+        pcx_palette(&palette, (uint32_t *)p->data[1], 16);
     }
 
-    *picture = s->picture;
     *got_frame = 1;
 
     ret = buf - bufstart;
@@ -255,23 +238,11 @@ end:
     return ret;
 }
 
-static av_cold int pcx_end(AVCodecContext *avctx) {
-    PCXContext *s = avctx->priv_data;
-
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_pcx_decoder = {
-    .name           = "pcx",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_PCX,
-    .priv_data_size = sizeof(PCXContext),
-    .init           = pcx_init,
-    .close          = pcx_end,
-    .decode         = pcx_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
+    .name         = "pcx",
+    .long_name    = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_PCX,
+    .decode       = pcx_decode_frame,
+    .capabilities = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c
index e0ee20a..4bf7377 100644
--- a/libavcodec/pcxenc.c
+++ b/libavcodec/pcxenc.c
@@ -30,19 +30,23 @@
 #include "bytestream.h"
 #include "internal.h"
 
-typedef struct PCXContext {
-    AVFrame picture;
-} PCXContext;
-
 static const uint32_t monoblack_pal[16] = { 0x000000, 0xFFFFFF };
 
 static av_cold int pcx_encode_init(AVCodecContext *avctx)
 {
-    PCXContext *s = avctx->priv_data;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
 
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
+    return 0;
+}
 
+static av_cold int pcx_encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
     return 0;
 }
 
@@ -99,8 +103,6 @@ static int pcx_rle_encode(      uint8_t *dst, int dst_size,
 static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *frame, int *got_packet)
 {
-    PCXContext *s = avctx->priv_data;
-    AVFrame *const pict = &s->picture;
     const uint8_t *buf_end;
     uint8_t *buf;
 
@@ -108,10 +110,6 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     const uint32_t *pal = NULL;
     const uint8_t *src;
 
-    *pict = *frame;
-    pict->pict_type = AV_PICTURE_TYPE_I;
-    pict->key_frame = 1;
-
     if (avctx->width > 65535 || avctx->height > 65535) {
         av_log(avctx, AV_LOG_ERROR, "image dimensions do not fit in 16 bits\n");
         return -1;
@@ -130,7 +128,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     case AV_PIX_FMT_PAL8:
         bpp = 8;
         nplanes = 1;
-        pal = (uint32_t *)pict->data[1];
+        pal = (uint32_t *)frame->data[1];
         break;
     case AV_PIX_FMT_MONOBLACK:
         bpp = 1;
@@ -172,7 +170,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     while (buf - pkt->data < 128)
         *buf++= 0;
 
-    src = pict->data[0];
+    src = frame->data[0];
 
     for (y = 0; y < avctx->height; y++) {
         if ((written = pcx_rle_encode(buf, buf_end - buf,
@@ -181,7 +179,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
             return -1;
         }
         buf += written;
-        src += pict->linesize[0];
+        src += frame->linesize[0];
     }
 
     if (nplanes == 1 && bpp == 8) {
@@ -204,10 +202,11 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
 AVCodec ff_pcx_encoder = {
     .name           = "pcx",
+    .long_name      = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PCX,
-    .priv_data_size = sizeof(PCXContext),
     .init           = pcx_encode_init,
+    .close          = pcx_encode_close,
     .encode2        = pcx_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24,
@@ -216,5 +215,4 @@ AVCodec ff_pcx_encoder = {
         AV_PIX_FMT_MONOBLACK,
         AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
 };
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index f22088a..2102a51 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -27,6 +27,8 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "bytestream.h"
+#include "internal.h"
+
 #include "libavutil/colorspace.h"
 #include "libavutil/imgutils.h"
 
@@ -272,13 +274,13 @@ static void parse_palette_segment(AVCodecContext *avctx,
  * @todo TODO: Implement cropping
  * @todo TODO: Implement forcing of subtitles
  */
-static void parse_presentation_segment(AVCodecContext *avctx,
-                                       const uint8_t *buf, int buf_size,
-                                       int64_t pts)
+static int parse_presentation_segment(AVCodecContext *avctx,
+                                      const uint8_t *buf, int buf_size,
+                                      int64_t pts)
 {
     PGSSubContext *ctx = avctx->priv_data;
 
-    int x, y;
+    int x, y, ret;
 
     int w = bytestream_get_be16(&buf);
     int h = bytestream_get_be16(&buf);
@@ -287,8 +289,9 @@ static void parse_presentation_segment(AVCodecContext *avctx,
 
     av_dlog(avctx, "Video Dimensions %dx%d\n",
             w, h);
-    if (av_image_check_size(w, h, 0, avctx) >= 0)
-        avcodec_set_dimensions(avctx, w, h);
+    ret = ff_set_dimensions(avctx, w, h);
+    if (ret < 0)
+        return ret;
 
     /* Skip 1 bytes of unknown, frame rate? */
     buf++;
@@ -306,7 +309,7 @@ static void parse_presentation_segment(AVCodecContext *avctx,
     ctx->presentation.object_number = bytestream_get_byte(&buf);
     ctx->presentation.composition_flag = 0;
     if (!ctx->presentation.object_number)
-        return;
+        return 0;
 
     /*
      * Skip 3 bytes of unknown:
@@ -332,6 +335,8 @@ static void parse_presentation_segment(AVCodecContext *avctx,
     /* Fill in dimensions */
     ctx->presentation.x = x;
     ctx->presentation.y = y;
+
+    return 0;
 }
 
 /**
@@ -413,7 +418,7 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size,
     const uint8_t *buf_end;
     uint8_t       segment_type;
     int           segment_length;
-    int i;
+    int i, ret;
 
     av_dlog(avctx, "PGS sub packet:\n");
 
@@ -452,7 +457,9 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size,
             parse_picture_segment(avctx, buf, segment_length);
             break;
         case PRESENTATION_SEGMENT:
-            parse_presentation_segment(avctx, buf, segment_length, avpkt->pts);
+            ret = parse_presentation_segment(avctx, buf, segment_length, avpkt->pts);
+            if (ret < 0)
+                return ret;
             break;
         case WINDOW_SEGMENT:
             /*
@@ -481,11 +488,11 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size,
 
 AVCodec ff_pgssub_decoder = {
     .name           = "pgssub",
+    .long_name      = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),
     .type           = AVMEDIA_TYPE_SUBTITLE,
     .id             = AV_CODEC_ID_HDMV_PGS_SUBTITLE,
     .priv_data_size = sizeof(PGSSubContext),
     .init           = init_decoder,
     .close          = close_decoder,
     .decode         = decode,
-    .long_name      = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),
 };
diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c
index 53fef1c..33c4545 100644
--- a/libavcodec/pictordec.c
+++ b/libavcodec/pictordec.c
@@ -31,16 +31,16 @@
 #include "internal.h"
 
 typedef struct PicContext {
-    AVFrame frame;
     int width, height;
     int nb_planes;
     GetByteContext g;
 } PicContext;
 
-static void picmemset_8bpp(PicContext *s, int value, int run, int *x, int *y)
+static void picmemset_8bpp(PicContext *s, AVFrame *frame, int value, int run,
+                           int *x, int *y)
 {
     while (run > 0) {
-        uint8_t *d = s->frame.data[0] + *y * s->frame.linesize[0];
+        uint8_t *d = frame->data[0] + *y * frame->linesize[0];
         if (*x + run >= s->width) {
             int n = s->width - *x;
             memset(d + *x, value, n);
@@ -57,7 +57,7 @@ static void picmemset_8bpp(PicContext *s, int value, int run, int *x, int *y)
     }
 }
 
-static void picmemset(PicContext *s, int value, int run,
+static void picmemset(PicContext *s, AVFrame *frame, int value, int run,
                       int *x, int *y, int *plane, int bits_per_plane)
 {
     uint8_t *d;
@@ -68,7 +68,7 @@ static void picmemset(PicContext *s, int value, int run,
     while (run > 0) {
         int j;
         for (j = 8-bits_per_plane; j >= 0; j -= bits_per_plane) {
-            d = s->frame.data[0] + *y * s->frame.linesize[0];
+            d = frame->data[0] + *y * frame->linesize[0];
             d[*x] |= (value >> j) & mask;
             *x += 1;
             if (*x == s->width) {
@@ -102,9 +102,10 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     PicContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     uint32_t *palette;
     int bits_per_plane, bpp, etype, esize, npal, pos_after_pal;
-    int i, x, y, plane, tmp;
+    int i, x, y, plane, tmp, ret;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
 
@@ -122,7 +123,7 @@ static int decode_frame(AVCodecContext *avctx,
     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(avctx, "unsupported bit depth\n");
+        avpriv_request_sample(avctx, "Unsupported bit depth");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -140,23 +141,21 @@ static int decode_frame(AVCodecContext *avctx,
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     if (s->width != avctx->width && s->height != avctx->height) {
-        if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
-            return -1;
-        avcodec_set_dimensions(avctx, s->width, s->height);
-        if (s->frame.data[0])
-            avctx->release_buffer(avctx, &s->frame);
+        ret = ff_set_dimensions(avctx, s->width, s->height);
+        if (ret < 0)
+            return ret;
     }
 
-    if (ff_get_buffer(avctx, &s->frame) < 0){
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    memset(s->frame.data[0], 0, s->height * s->frame.linesize[0]);
-    s->frame.pict_type           = AV_PICTURE_TYPE_I;
-    s->frame.palette_has_changed = 1;
+    memset(frame->data[0], 0, s->height * frame->linesize[0]);
+    frame->pict_type           = AV_PICTURE_TYPE_I;
+    frame->palette_has_changed = 1;
 
     pos_after_pal = bytestream2_tell(&s->g) + esize;
-    palette = (uint32_t*)s->frame.data[1];
+    palette = (uint32_t*)frame->data[1];
     if (etype == 1 && esize > 1 && bytestream2_peek_byte(&s->g) < 6) {
         int idx = bytestream2_get_byte(&s->g);
         npal = 4;
@@ -225,40 +224,30 @@ static int decode_frame(AVCodecContext *avctx,
                     break;
 
                 if (bits_per_plane == 8) {
-                    picmemset_8bpp(s, val, run, &x, &y);
+                    picmemset_8bpp(s, frame, val, run, &x, &y);
                     if (y < 0)
                         goto finish;
                 } else {
-                    picmemset(s, val, run, &x, &y, &plane, bits_per_plane);
+                    picmemset(s, frame, val, run, &x, &y, &plane, bits_per_plane);
                 }
             }
         }
     } else {
-        av_log_ask_for_sample(avctx, "uncompressed image\n");
+        avpriv_request_sample(avctx, "Uncompressed image");
         return avpkt->size;
     }
 finish:
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
     return avpkt->size;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    PicContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-    return 0;
-}
-
 AVCodec ff_pictor_decoder = {
     .name           = "pictor",
+    .long_name      = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PICTOR,
     .priv_data_size = sizeof(PicContext),
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"),
 };
diff --git a/libavcodec/png_parser.c b/libavcodec/png_parser.c
new file mode 100644
index 0000000..d07f288
--- /dev/null
+++ b/libavcodec/png_parser.c
@@ -0,0 +1,124 @@
+/*
+ * PNG parser
+ * Copyright (c) 2009 Peter Holik
+ *
+ * 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
+ * PNG parser
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/common.h"
+
+#include "parser.h"
+
+#define PNG_SIGNATURE UINT64_C(0x89504e470d0a1a0a)
+#define MNG_SIGNATURE UINT64_C(0x8a4d4e470d0a1a0a)
+
+typedef struct PNGParseContext {
+    ParseContext pc;
+
+    int chunk_pos;          ///< position inside current chunk
+    int chunk_length;       ///< length of the current chunk
+    int remaining_size;     ///< remaining size of the current chunk
+} 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;
+
+    *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 == PNG_SIGNATURE ||
+                state64 == MNG_SIGNATURE) {
+                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->chunk_pos == -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->chunk_pos == 3) {
+            ppc->chunk_length = ppc->pc.state;
+            if (ppc->chunk_length > 0x7fffffff) {
+                ppc->chunk_pos = ppc->pc.frame_start_found = 0;
+                goto flush;
+            }
+            ppc->chunk_length += 4;
+        } else if (ppc->chunk_pos == 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->chunk_pos = -1;
+                else
+                    next = ppc->chunk_length + i + 1;
+                break;
+            } else {
+                ppc->chunk_pos = 0;
+                if (ppc->remaining_size)
+                    break;
+                else
+                    i += ppc->chunk_length;
+                continue;
+            }
+        }
+        ppc->chunk_pos++;
+    }
+
+flush:
+    if (ff_combine_frame(&ppc->pc, next, &buf, &buf_size) < 0)
+        return buf_size;
+
+    ppc->chunk_pos = 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 6c2df12..e646296 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -31,14 +31,11 @@
 
 #include <zlib.h>
 
-//#define DEBUG
-
 typedef struct PNGDecContext {
     PNGDSPContext dsp;
 
     GetByteContext gb;
-    AVFrame picture1, picture2;
-    AVFrame *current_picture, *last_picture;
+    AVFrame *prev;
 
     int state;
     int width, height;
@@ -86,15 +83,16 @@ static void png_put_interlaced_row(uint8_t *dst, int width,
     uint8_t *d;
     const uint8_t *s;
 
-    mask = ff_png_pass_mask[pass];
+    mask     = ff_png_pass_mask[pass];
     dsp_mask = png_pass_dsp_mask[pass];
-    switch(bits_per_pixel) {
+
+    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++) {
+        for (x = 0; x < width; x++) {
             j = (x & 7);
             if ((dsp_mask << j) & 0x80) {
                 b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
@@ -106,10 +104,10 @@ static void png_put_interlaced_row(uint8_t *dst, int width,
         break;
     default:
         bpp = bits_per_pixel >> 3;
-        d = dst;
-        s = src;
+        d   = dst;
+        s   = src;
         if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-            for(x = 0; x < width; x++) {
+            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];
@@ -136,14 +134,14 @@ static void png_put_interlaced_row(uint8_t *dst, int width,
 void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
 {
     int i;
-    for(i = 0; i < w; i++) {
+    for (i = 0; i < w; i++) {
         int a, b, c, p, pa, pb, pc;
 
         a = dst[i - bpp];
         b = top[i];
         c = top[i - bpp];
 
-        p = b - c;
+        p  = b - c;
         pc = a - c;
 
         pa = abs(p);
@@ -195,20 +193,20 @@ static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type,
 {
     int i, p, r, g, b, a;
 
-    switch(filter_type) {
+    switch (filter_type) {
     case PNG_FILTER_VALUE_NONE:
         memcpy(dst, src, size);
         break;
     case PNG_FILTER_VALUE_SUB:
-        for(i = 0; i < bpp; i++) {
+        for (i = 0; i < bpp; i++) {
             dst[i] = src[i];
         }
-        if(bpp == 4) {
+        if (bpp == 4) {
             p = *(int*)dst;
-            for(; i < size; i+=bpp) {
-                int s = *(int*)(src+i);
-                p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080);
-                *(int*)(dst+i) = p;
+            for (; i < size; i += bpp) {
+                int s = *(int*)(src + i);
+                p = ((s & 0x7f7f7f7f) + (p & 0x7f7f7f7f)) ^ ((s ^ p) & 0x80808080);
+                *(int*)(dst + i) = p;
             }
         } else {
 #define OP_SUB(x,s,l) x+s
@@ -219,7 +217,7 @@ static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type,
         dsp->add_bytes_l2(dst, src, last, size);
         break;
     case PNG_FILTER_VALUE_AVG:
-        for(i = 0; i < bpp; i++) {
+        for (i = 0; i < bpp; i++) {
             p = (last[i] >> 1);
             dst[i] = p + src[i];
         }
@@ -227,34 +225,36 @@ static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type,
         UNROLL_FILTER(OP_AVG);
         break;
     case PNG_FILTER_VALUE_PAETH:
-        for(i = 0; i < bpp; i++) {
+        for (i = 0; i < bpp; i++) {
             p = last[i];
             dst[i] = p + src[i];
         }
-        if(bpp > 1 && size > 4) {
+        if (bpp > 1 && size > 4) {
             // would write off the end of the array if we let it process the last pixel with bpp=3
-            int w = bpp==4 ? size : size-3;
-            dsp->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
+            int w = bpp == 4 ? size : size - 3;
+            dsp->add_paeth_prediction(dst + i, src + i, last + i, w - i, bpp);
             i = w;
         }
-        ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp);
+        ff_add_png_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);
         break;
     }
 }
 
-static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco)
+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++) {
+    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;
+        if (loco) {
+            r = (r + g) & 0xff;
+            b = (b + g) & 0xff;
         }
         *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
         dst += 4;
@@ -264,7 +264,7 @@ static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *
 
 static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco)
 {
-    if(loco)
+    if (loco)
         convert_to_rgb32_loco(dst, src, width, 1);
     else
         convert_to_rgb32_loco(dst, src, width, 0);
@@ -273,10 +273,10 @@ static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int lo
 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;
+    for (i = 0; i < size; i += 3) {
+        int g = dst[i + 1];
+        dst[i + 0] += g;
+        dst[i + 2] += g;
     }
 }
 
@@ -317,7 +317,7 @@ static void png_handle_row(PNGDecContext *s)
         }
     } else {
         got_line = 0;
-        for(;;) {
+        for (;;) {
             ptr = s->image_buf + s->image_linesize * s->y;
             if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
                 /* if we already read one row, it is time to stop to
@@ -336,7 +336,7 @@ static void png_handle_row(PNGDecContext *s)
             }
             s->y++;
             if (s->y == s->height) {
-                for(;;) {
+                for (;;) {
                     if (s->pass == NB_PASSES - 1) {
                         s->state |= PNG_ALLIMAGE;
                         goto the_end;
@@ -362,7 +362,7 @@ static int png_decode_idat(PNGDecContext *s, int length)
 {
     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  = s->gb.buffer;
     bytestream2_skip(&s->gb, length);
 
     /* decode one line if possible */
@@ -376,7 +376,7 @@ static int png_decode_idat(PNGDecContext *s, int length)
                 png_handle_row(s);
             }
             s->zstream.avail_out = s->crow_size;
-            s->zstream.next_out = s->crow_buf;
+            s->zstream.next_out  = s->crow_buf;
         }
         if (ret == Z_STREAM_END && s->zstream.avail_in > 0) {
             av_log(NULL, AV_LOG_WARNING, "%d undecompressed bytes left in buffer\n", s->zstream.avail_in);
@@ -390,19 +390,14 @@ static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     PNGDecContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame *p;
-    uint8_t *crow_buf_base = NULL;
+    const uint8_t *buf      = avpkt->data;
+    int buf_size            = avpkt->size;
+    AVFrame *p              = data;
+    uint8_t *crow_buf_base  = NULL;
     uint32_t tag, length;
     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 &&
@@ -410,17 +405,16 @@ static int decode_frame(AVCodecContext *avctx,
         return -1;
 
     bytestream2_init(&s->gb, buf + 8, buf_size - 8);
-    s->y=
-    s->state=0;
-//    memset(s, 0, sizeof(PNGDecContext));
+    s->y = s->state = 0;
+
     /* init the zlib */
     s->zstream.zalloc = ff_png_zalloc;
-    s->zstream.zfree = ff_png_zfree;
+    s->zstream.zfree  = ff_png_zfree;
     s->zstream.opaque = NULL;
     ret = inflateInit(&s->zstream);
     if (ret != Z_OK)
         return -1;
-    for(;;) {
+    for (;;) {
         if (bytestream2_get_bytes_left(&s->gb) <= 0)
             goto fail;
         length = bytestream2_get_be32(&s->gb);
@@ -432,14 +426,14 @@ static int decode_frame(AVCodecContext *avctx,
                 ((tag >> 8) & 0xff),
                 ((tag >> 16) & 0xff),
                 ((tag >> 24) & 0xff), length);
-        switch(tag) {
+        switch (tag) {
         case MKTAG('I', 'H', 'D', 'R'):
             if (length != 13)
                 goto fail;
             s->width  = bytestream2_get_be32(&s->gb);
             s->height = bytestream2_get_be32(&s->gb);
-            if(av_image_check_size(s->width, s->height, 0, avctx)){
-                s->width= s->height= 0;
+            if (av_image_check_size(s->width, s->height, 0, avctx)) {
+                s->width = s->height = 0;
                 goto fail;
             }
             s->bit_depth        = bytestream2_get_byte(&s->gb);
@@ -449,7 +443,8 @@ static int decode_frame(AVCodecContext *avctx,
             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",
+            av_dlog(avctx, "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;
@@ -458,13 +453,13 @@ static int decode_frame(AVCodecContext *avctx,
                 goto fail;
             if (!(s->state & PNG_IDAT)) {
                 /* init image info */
-                avctx->width = s->width;
+                avctx->width  = s->width;
                 avctx->height = s->height;
 
-                s->channels = ff_png_get_nb_channels(s->color_type);
+                s->channels       = ff_png_get_nb_channels(s->color_type);
                 s->bits_per_pixel = s->bit_depth * s->channels;
-                s->bpp = (s->bits_per_pixel + 7) >> 3;
-                s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
+                s->bpp            = (s->bits_per_pixel + 7) >> 3;
+                s->row_size       = (avctx->width * s->bits_per_pixel + 7) >> 3;
 
                 if (s->bit_depth == 8 &&
                     s->color_type == PNG_COLOR_TYPE_RGB) {
@@ -493,16 +488,13 @@ static int decode_frame(AVCodecContext *avctx,
                 } else {
                     goto fail;
                 }
-                if(p->data[0])
-                    avctx->release_buffer(avctx, p);
 
-                p->reference= 0;
-                if(ff_get_buffer(avctx, p) < 0){
+                if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) {
                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                     goto fail;
                 }
-                p->pict_type= AV_PICTURE_TYPE_I;
-                p->key_frame= 1;
+                p->pict_type        = AV_PICTURE_TYPE_I;
+                p->key_frame        = 1;
                 p->interlaced_frame = !!s->interlace_type;
 
                 /* compute the compressed row size */
@@ -517,7 +509,7 @@ static int decode_frame(AVCodecContext *avctx,
                 }
                 av_dlog(avctx, "row_size=%d crow_size =%d\n",
                         s->row_size, s->crow_size);
-                s->image_buf = p->data[0];
+                s->image_buf      = p->data[0];
                 s->image_linesize = p->linesize[0];
                 /* copy the palette if needed */
                 if (s->color_type == PNG_COLOR_TYPE_PALETTE)
@@ -538,9 +530,9 @@ static int decode_frame(AVCodecContext *avctx,
                     goto fail;
 
                 /* we want crow_buf+1 to be 16-byte aligned */
-                s->crow_buf = crow_buf_base + 15;
+                s->crow_buf          = crow_buf_base + 15;
                 s->zstream.avail_out = s->crow_size;
-                s->zstream.next_out = s->crow_buf;
+                s->zstream.next_out  = s->crow_buf;
             }
             s->state |= PNG_IDAT;
             if (png_decode_idat(s, length) < 0)
@@ -555,13 +547,13 @@ static int decode_frame(AVCodecContext *avctx,
                     goto skip_tag;
                 /* read the palette */
                 n = length / 3;
-                for(i=0;i<n;i++) {
+                for (i = 0; i < n; i++) {
                     r = bytestream2_get_byte(&s->gb);
                     g = bytestream2_get_byte(&s->gb);
                     b = bytestream2_get_byte(&s->gb);
                     s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
                 }
-                for(;i<256;i++) {
+                for (; i < 256; i++) {
                     s->palette[i] = (0xff << 24);
                 }
                 s->state |= PNG_PLTE;
@@ -577,7 +569,7 @@ static int decode_frame(AVCodecContext *avctx,
                     length > 256 ||
                     !(s->state & PNG_PLTE))
                     goto skip_tag;
-                for(i=0;i<length;i++) {
+                for (i = 0; i < length; i++) {
                     v = bytestream2_get_byte(&s->gb);
                     s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
                 }
@@ -598,23 +590,26 @@ static int decode_frame(AVCodecContext *avctx,
     }
  exit_loop:
      /* handle p-frames only if a predecessor frame is available */
-     if(s->last_picture->data[0] != NULL) {
-         if(!(avpkt->flags & AV_PKT_FLAG_KEY)) {
+     if (s->prev->data[0]) {
+         if (!(avpkt->flags & AV_PKT_FLAG_KEY)) {
             int i, j;
-            uint8_t *pd = s->current_picture->data[0];
-            uint8_t *pd_last = s->last_picture->data[0];
+            uint8_t *pd      = p->data[0];
+            uint8_t *pd_last = s->prev->data[0];
 
-            for(j=0; j < s->height; j++) {
-                for(i=0; i < s->width * s->bpp; i++) {
+            for (j = 0; j < s->height; j++) {
+                for (i = 0; i < s->width * s->bpp; i++) {
                     pd[i] += pd_last[i];
                 }
-                pd += s->image_linesize;
+                pd      += s->image_linesize;
                 pd_last += s->image_linesize;
             }
         }
     }
 
-    *picture= *s->current_picture;
+     av_frame_unref(s->prev);
+     if ((ret = av_frame_ref(s->prev, p)) < 0)
+         goto fail;
+
     *got_frame = 1;
 
     ret = bytestream2_tell(&s->gb);
@@ -630,13 +625,14 @@ static int decode_frame(AVCodecContext *avctx,
     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);
+    s->prev = av_frame_alloc();
+    if (!s->prev)
+        return AVERROR(ENOMEM);
+
     ff_pngdsp_init(&s->dsp);
 
     return 0;
@@ -646,16 +642,14 @@ static av_cold int png_dec_end(AVCodecContext *avctx)
 {
     PNGDecContext *s = avctx->priv_data;
 
-    if (s->picture1.data[0])
-        avctx->release_buffer(avctx, &s->picture1);
-    if (s->picture2.data[0])
-        avctx->release_buffer(avctx, &s->picture2);
+    av_frame_free(&s->prev);
 
     return 0;
 }
 
 AVCodec ff_png_decoder = {
     .name           = "png",
+    .long_name      = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PNG,
     .priv_data_size = sizeof(PNGDecContext),
@@ -663,5 +657,4 @@ AVCodec ff_png_decoder = {
     .close          = png_dec_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
-    .long_name      = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
 };
diff --git a/libavcodec/pngdsp.c b/libavcodec/pngdsp.c
index 00734d7..5cc41c4 100644
--- a/libavcodec/pngdsp.c
+++ b/libavcodec/pngdsp.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "png.h"
 #include "pngdsp.h"
@@ -30,7 +31,7 @@
 static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w)
 {
     long i;
-    for (i = 0; i <= w - sizeof(long); i += sizeof(long)) {
+    for (i = 0; i <= w - (int)sizeof(long); i += sizeof(long)) {
         long a = *(long *)(src1 + i);
         long b = *(long *)(src2 + i);
         *(long *)(dst + i) = ((a & pb_7f) + (b & pb_7f)) ^ ((a ^ b) & pb_80);
@@ -39,7 +40,7 @@ static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w)
         dst[i] = src1[i] + src2[i];
 }
 
-void ff_pngdsp_init(PNGDSPContext *dsp)
+av_cold void ff_pngdsp_init(PNGDSPContext *dsp)
 {
     dsp->add_bytes_l2         = add_bytes_l2_c;
     dsp->add_paeth_prediction = ff_add_png_paeth_prediction;
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index b20a6d6..f58f715 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -29,8 +29,6 @@
 
 #include <zlib.h>
 
-//#define DEBUG
-
 #define IOBUF_SIZE 4096
 
 typedef struct PNGEncContext {
@@ -39,7 +37,6 @@ typedef struct PNGEncContext {
     uint8_t *bytestream;
     uint8_t *bytestream_start;
     uint8_t *bytestream_end;
-    AVFrame picture;
 
     int filter_type;
 
@@ -233,7 +230,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *pict, int *got_packet)
 {
     PNGEncContext *s = avctx->priv_data;
-    AVFrame * const p= &s->picture;
+    const AVFrame * const p = pict;
     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 compression_level;
@@ -243,10 +240,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     uint8_t *rgba_buf = NULL;
     uint8_t *top_buf = NULL;
 
-    *p = *pict;
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
-
     is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
     switch(avctx->pix_fmt) {
     case AV_PIX_FMT_RGB32:
@@ -257,6 +250,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         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:
         bit_depth = 8;
         color_type = PNG_COLOR_TYPE_GRAY;
@@ -442,8 +439,13 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 static av_cold int png_enc_init(AVCodecContext *avctx){
     PNGEncContext *s = avctx->priv_data;
 
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame= &s->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+
     ff_dsputil_init(&s->dsp, avctx);
 
     s->filter_type = av_clip(avctx->prediction_method, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED);
@@ -453,16 +455,24 @@ static av_cold int png_enc_init(AVCodecContext *avctx){
     return 0;
 }
 
+static av_cold int png_enc_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
 AVCodec ff_png_encoder = {
     .name           = "png",
+    .long_name      = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PNG,
     .priv_data_size = sizeof(PNGEncContext),
     .init           = png_enc_init,
+    .close          = png_enc_close,
     .encode2        = encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8,
+        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..1c380b0 100644
--- a/libavcodec/pnm.c
+++ b/libavcodec/pnm.c
@@ -65,7 +65,7 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
     pnm_get(s, buf1, sizeof(buf1));
     s->type= buf1[1]-'0';
     if(buf1[0] != 'P')
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (s->type==1 || s->type==4) {
         avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
@@ -103,12 +103,12 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
             } else if (!strcmp(buf1, "ENDHDR")) {
                 break;
             } else {
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
         /* check that all tags are present */
         if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx))
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         avctx->width  = w;
         avctx->height = h;
@@ -123,25 +123,25 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
             } 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;
+                return AVERROR_INVALIDDATA;
             }
         } else if (depth == 4) {
             avctx->pix_fmt = AV_PIX_FMT_RGB32;
         } else {
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         return 0;
     } else {
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     pnm_get(s, buf1, sizeof(buf1));
     avctx->width = atoi(buf1);
     if (avctx->width <= 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
     pnm_get(s, buf1, sizeof(buf1));
     avctx->height = atoi(buf1);
     if(av_image_check_size(avctx->width, avctx->height, 0, avctx))
-        return -1;
+        return AVERROR_INVALIDDATA;
     if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) {
         pnm_get(s, buf1, sizeof(buf1));
         s->maxval = atoi(buf1);
@@ -157,43 +157,30 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
             } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
                 if (s->maxval > 255)
                     avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
+            } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) {
+                if (s->maxval < 512)
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P9BE;
+                else if (s->maxval < 1024)
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P10BE;
+                else
+                    avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
             } else {
                 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");
                 avctx->pix_fmt = AV_PIX_FMT_NONE;
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
         }
     }else
         s->maxval=1;
     /* more check if YUV420 */
-    if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
+    if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) {
         if ((avctx->width & 1) != 0)
-            return -1;
+            return AVERROR_INVALIDDATA;
         h = (avctx->height * 2);
         if ((h % 3) != 0)
-            return -1;
+            return AVERROR_INVALIDDATA;
         h /= 3;
         avctx->height = h;
     }
     return 0;
 }
-
-av_cold int ff_pnm_end(AVCodecContext *avctx)
-{
-    PNMContext *s = avctx->priv_data;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
-av_cold int ff_pnm_init(AVCodecContext *avctx)
-{
-    PNMContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
diff --git a/libavcodec/pnm.h b/libavcodec/pnm.h
index 702921f..5fc6513 100644
--- a/libavcodec/pnm.h
+++ b/libavcodec/pnm.h
@@ -28,13 +28,10 @@ typedef struct PNMContext {
     uint8_t *bytestream;
     uint8_t *bytestream_start;
     uint8_t *bytestream_end;
-    AVFrame picture;
     int maxval;                 ///< maximum value of a pixel
     int type;
 } PNMContext;
 
 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s);
-av_cold int ff_pnm_end(AVCodecContext *avctx);
-av_cold int ff_pnm_init(AVCodecContext *avctx);
 
 #endif /* AVCODEC_PNM_H */
diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index b4b042c..9074d9b 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -32,33 +32,28 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf   = avpkt->data;
     int buf_size         = avpkt->size;
     PNMContext * const s = avctx->priv_data;
-    AVFrame *picture     = data;
-    AVFrame * const p    = &s->picture;
+    AVFrame * const p    = data;
     int i, j, n, linesize, h, upgrade = 0;
     unsigned char *ptr;
-    int components, sample_len;
+    int components, sample_len, ret;
 
     s->bytestream_start =
     s->bytestream       = buf;
     s->bytestream_end   = buf + buf_size;
 
-    if (ff_pnm_decode_header(avctx, s) < 0)
-        return -1;
+    if ((ret = ff_pnm_decode_header(avctx, s)) < 0)
+        return ret;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
     switch (avctx->pix_fmt) {
     default:
-        return -1;
+        return AVERROR(EINVAL);
     case AV_PIX_FMT_RGB48BE:
         n = avctx->width * 6;
         components=3;
@@ -93,7 +88,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
         ptr      = p->data[0];
         linesize = p->linesize[0];
         if (s->bytestream + n * avctx->height > s->bytestream_end)
-            return -1;
+            return AVERROR_INVALIDDATA;
         if(s->type < 4){
             for (i=0; i<avctx->height; i++) {
                 PutBitContext pb;
@@ -104,7 +99,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
                     while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' ))
                         s->bytestream++;
                     if(s->bytestream >= s->bytestream_end)
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     do{
                         v= 10*v + c;
                         c= (*s->bytestream++) - '0';
@@ -135,14 +130,18 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
         }
         break;
     case AV_PIX_FMT_YUV420P:
+    case AV_PIX_FMT_YUV420P9BE:
+    case AV_PIX_FMT_YUV420P10BE:
         {
             unsigned char *ptr1, *ptr2;
 
             n        = avctx->width;
             ptr      = p->data[0];
             linesize = p->linesize[0];
+            if (s->maxval >= 256)
+                n *= 2;
             if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end)
-                return -1;
+                return AVERROR_INVALIDDATA;
             for (i = 0; i < avctx->height; i++) {
                 memcpy(ptr, s->bytestream, n);
                 s->bytestream += n;
@@ -162,11 +161,52 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
             }
         }
         break;
+    case AV_PIX_FMT_YUV420P16:
+        {
+            uint16_t *ptr1, *ptr2;
+            const int f = (65535 * 32768 + s->maxval / 2) / s->maxval;
+            unsigned int j, v;
+
+            n        = avctx->width * 2;
+            ptr      = p->data[0];
+            linesize = p->linesize[0];
+            if (s->bytestream + n * avctx->height * 3 / 2 > s->bytestream_end)
+                return AVERROR_INVALIDDATA;
+            for (i = 0; i < avctx->height; i++) {
+                for (j = 0; j < n / 2; j++) {
+                    v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
+                    ((uint16_t *)ptr)[j] = (v * f + 16384) >> 15;
+                }
+                s->bytestream += n;
+                ptr           += linesize;
+            }
+            ptr1 = (uint16_t*)p->data[1];
+            ptr2 = (uint16_t*)p->data[2];
+            n >>= 1;
+            h = avctx->height >> 1;
+            for (i = 0; i < h; i++) {
+                for (j = 0; j < n / 2; j++) {
+                    v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
+                    ptr1[j] = (v * f + 16384) >> 15;
+                }
+                s->bytestream += n;
+
+                for (j = 0; j < n / 2; j++) {
+                    v = av_be2ne16(((uint16_t *)s->bytestream)[j]);
+                    ptr2[j] = (v * f + 16384) >> 15;
+                }
+                s->bytestream += n;
+
+                ptr1 += p->linesize[1] / 2;
+                ptr2 += p->linesize[2] / 2;
+            }
+        }
+        break;
     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;
+            return AVERROR_INVALIDDATA;
         for (i = 0; i < avctx->height; i++) {
             int j, r, g, b, a;
 
@@ -181,7 +221,6 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
         }
         break;
     }
-    *picture   = s->picture;
     *got_frame = 1;
 
     return s->bytestream - s->bytestream_start;
@@ -191,69 +230,59 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
 #if CONFIG_PGM_DECODER
 AVCodec ff_pgm_decoder = {
     .name           = "pgm",
+    .long_name      = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PGM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
 };
 #endif
 
 #if CONFIG_PGMYUV_DECODER
 AVCodec ff_pgmyuv_decoder = {
     .name           = "pgmyuv",
+    .long_name      = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PGMYUV,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
 };
 #endif
 
 #if CONFIG_PPM_DECODER
 AVCodec ff_ppm_decoder = {
     .name           = "ppm",
+    .long_name      = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PPM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
 };
 #endif
 
 #if CONFIG_PBM_DECODER
 AVCodec ff_pbm_decoder = {
     .name           = "pbm",
+    .long_name      = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PBM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
 };
 #endif
 
 #if CONFIG_PAM_DECODER
 AVCodec ff_pam_decoder = {
     .name           = "pam",
+    .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PAM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
 };
 #endif
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index 2863db7..7513552 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -19,17 +19,16 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
-#include "pnm.h"
-
 
 static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *pict, int *got_packet)
 {
-    PNMContext *s     = avctx->priv_data;
-    AVFrame * const p = &s->picture;
+    uint8_t *bytestream, *bytestream_start, *bytestream_end;
+    const AVFrame * const p = pict;
     int i, h, h1, c, n, linesize, ret;
     uint8_t *ptr, *ptr1, *ptr2;
 
@@ -40,13 +39,9 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         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;
+    bytestream_start =
+    bytestream       = pkt->data;
+    bytestream_end   = pkt->data + pkt->size;
 
     h  = avctx->height;
     h1 = h;
@@ -76,101 +71,126 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         n  = avctx->width;
         h1 = (h * 3) / 2;
         break;
+    case AV_PIX_FMT_YUV420P16BE:
+        c  = '5';
+        n  = avctx->width * 2;
+        h1 = (h * 3) / 2;
+        break;
     default:
         return -1;
     }
-    snprintf(s->bytestream, s->bytestream_end - s->bytestream,
+    snprintf(bytestream, bytestream_end - bytestream,
              "P%c\n%d %d\n", c, avctx->width, h1);
-    s->bytestream += strlen(s->bytestream);
+    bytestream += strlen(bytestream);
     if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) {
-        snprintf(s->bytestream, s->bytestream_end - s->bytestream,
-                 "%d\n", (avctx->pix_fmt != AV_PIX_FMT_GRAY16BE && avctx->pix_fmt != AV_PIX_FMT_RGB48BE) ? 255 : 65535);
-        s->bytestream += strlen(s->bytestream);
+        int maxdepth = (1 << (av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1)) - 1;
+        snprintf(bytestream, bytestream_end - bytestream,
+                 "%d\n", maxdepth);
+        bytestream += strlen(bytestream);
     }
 
     ptr      = p->data[0];
     linesize = p->linesize[0];
     for (i = 0; i < h; i++) {
-        memcpy(s->bytestream, ptr, n);
-        s->bytestream += n;
-        ptr           += linesize;
+        memcpy(bytestream, ptr, n);
+        bytestream += n;
+        ptr        += linesize;
     }
 
-    if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
+    if (avctx->pix_fmt == AV_PIX_FMT_YUV420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P16BE) {
         h >>= 1;
         n >>= 1;
         ptr1 = p->data[1];
         ptr2 = p->data[2];
         for (i = 0; i < h; i++) {
-            memcpy(s->bytestream, ptr1, n);
-            s->bytestream += n;
-            memcpy(s->bytestream, ptr2, n);
-            s->bytestream += n;
+            memcpy(bytestream, ptr1, n);
+            bytestream += n;
+            memcpy(bytestream, ptr2, n);
+            bytestream += n;
                 ptr1 += p->linesize[1];
                 ptr2 += p->linesize[2];
         }
     }
-    pkt->size   = s->bytestream - s->bytestream_start;
+    pkt->size   = bytestream - bytestream_start;
     pkt->flags |= AV_PKT_FLAG_KEY;
     *got_packet = 1;
 
     return 0;
 }
 
+static av_cold int pnm_encode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+
+    return 0;
+}
+
+static av_cold int pnm_encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
 
 #if CONFIG_PGM_ENCODER
 AVCodec ff_pgm_encoder = {
     .name           = "pgm",
+    .long_name      = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PGM,
-    .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
+    .init           = pnm_encode_init,
+    .close          = pnm_encode_close,
     .encode2        = pnm_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
 };
 #endif
 
 #if CONFIG_PGMYUV_ENCODER
 AVCodec ff_pgmyuv_encoder = {
     .name           = "pgmyuv",
+    .long_name      = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PGMYUV,
-    .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
+    .init           = pnm_encode_init,
+    .close          = pnm_encode_close,
     .encode2        = pnm_encode_frame,
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
+    .pix_fmts       = (const enum AVPixelFormat[]){
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE
+    },
 };
 #endif
 
 #if CONFIG_PPM_ENCODER
 AVCodec ff_ppm_encoder = {
     .name           = "ppm",
+    .long_name      = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PPM,
-    .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
+    .init           = pnm_encode_init,
+    .close          = pnm_encode_close,
     .encode2        = pnm_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
 };
 #endif
 
 #if CONFIG_PBM_ENCODER
 AVCodec ff_pbm_encoder = {
     .name           = "pbm",
+    .long_name      = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PBM,
-    .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
+    .init           = pnm_encode_init,
+    .close          = pnm_encode_close,
     .encode2        = pnm_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE,
                                                   AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
 };
 #endif
diff --git a/libavcodec/ppc/Makefile b/libavcodec/ppc/Makefile
index c8c3025..71b23da 100644
--- a/libavcodec/ppc/Makefile
+++ b/libavcodec/ppc/Makefile
@@ -1,21 +1,24 @@
 OBJS                                   += ppc/dsputil_ppc.o             \
+                                          ppc/fmtconvert_altivec.o      \
                                           ppc/videodsp_ppc.o            \
 
+OBJS-$(CONFIG_FFT)                     += ppc/fft_altivec.o
+OBJS-$(CONFIG_H264CHROMA)              += ppc/h264chroma_init.o
+OBJS-$(CONFIG_H264DSP)                 += ppc/h264dsp.o
+OBJS-$(CONFIG_H264QPEL)                += ppc/h264qpel.o
+OBJS-$(CONFIG_HPELDSP)                 += ppc/hpeldsp_altivec.o
+OBJS-$(CONFIG_MPEGAUDIODSP)            += ppc/mpegaudiodsp_altivec.o
+OBJS-$(CONFIG_MPEGVIDEO)               += ppc/mpegvideo_altivec.o
+OBJS-$(CONFIG_VC1_DECODER)             += ppc/vc1dsp_altivec.o
+OBJS-$(CONFIG_VORBIS_DECODER)          += ppc/vorbisdsp_altivec.o
 OBJS-$(CONFIG_VP3DSP)                  += ppc/vp3dsp_altivec.o
-
-FFT-OBJS-$(HAVE_GNU_AS)                += ppc/fft_altivec_s.o
-ALTIVEC-OBJS-$(CONFIG_FFT)             += ppc/fft_altivec.o             \
-                                          $(FFT-OBJS-yes)
-ALTIVEC-OBJS-$(CONFIG_H264DSP)         += ppc/h264_altivec.o
-ALTIVEC-OBJS-$(CONFIG_MPEGAUDIODSP)    += ppc/mpegaudiodec_altivec.o
-ALTIVEC-OBJS-$(CONFIG_MPEGVIDEO)       += ppc/mpegvideo_altivec.o
-ALTIVEC-OBJS-$(CONFIG_VC1_DECODER)     += ppc/vc1dsp_altivec.o
-ALTIVEC-OBJS-$(CONFIG_VP8_DECODER)     += ppc/vp8dsp_altivec.o
+OBJS-$(CONFIG_VP8_DECODER)             += ppc/vp8dsp_altivec.o
 
 ALTIVEC-OBJS                           += ppc/dsputil_altivec.o         \
                                           ppc/fdct_altivec.o            \
-                                          ppc/float_altivec.o           \
-                                          ppc/fmtconvert_altivec.o      \
                                           ppc/gmc_altivec.o             \
                                           ppc/idct_altivec.o            \
                                           ppc/int_altivec.o             \
+
+FFT-OBJS-$(HAVE_GNU_AS)                += ppc/fft_altivec_s.o
+ALTIVEC-OBJS-$(CONFIG_FFT)             += $(FFT-OBJS-yes)
diff --git a/libavcodec/ppc/dsputil_altivec.c b/libavcodec/ppc/dsputil_altivec.c
index 9ad73ef..f90ec74 100644
--- a/libavcodec/ppc/dsputil_altivec.c
+++ b/libavcodec/ppc/dsputil_altivec.c
@@ -24,6 +24,7 @@
 #if HAVE_ALTIVEC_H
 #include <altivec.h>
 #endif
+#include "libavutil/attributes.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
 #include "libavcodec/dsputil.h"
@@ -476,7 +477,7 @@ static int pix_sum_altivec(uint8_t * pix, int line_size)
     return s;
 }
 
-static void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
+static void get_pixels_altivec(int16_t *restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
     vector unsigned char perm = vec_lvsl(0, pixels);
@@ -502,7 +503,7 @@ static void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, i
     }
 }
 
-static void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1,
+static void diff_pixels_altivec(int16_t *restrict block, const uint8_t *s1,
         const uint8_t *s2, int stride)
 {
     int i;
@@ -576,7 +577,7 @@ static void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1,
 }
 
 
-static void clear_block_altivec(DCTELEM *block) {
+static void clear_block_altivec(int16_t *block) {
     LOAD_ZERO;
     vec_st(zero_s16v,   0, block);
     vec_st(zero_s16v,  16, block);
@@ -606,354 +607,6 @@ static void add_bytes_altivec(uint8_t *dst, uint8_t *src, int w) {
     }
 }
 
-/* next one assumes that ((line_size % 16) == 0) */
-void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    register vector unsigned char pixelsv1, pixelsv2;
-    register vector unsigned char pixelsv1B, pixelsv2B;
-    register vector unsigned char pixelsv1C, pixelsv2C;
-    register vector unsigned char pixelsv1D, pixelsv2D;
-
-    register vector unsigned char perm = vec_lvsl(0, pixels);
-    int i;
-    register int line_size_2 = line_size << 1;
-    register int line_size_3 = line_size + line_size_2;
-    register int line_size_4 = line_size << 2;
-
-// hand-unrolling the loop by 4 gains about 15%
-// mininum execution time goes from 74 to 60 cycles
-// it's faster than -funroll-loops, but using
-// -funroll-loops w/ this is bad - 74 cycles again.
-// all this is on a 7450, tuning for the 7450
-    for (i = 0; i < h; i += 4) {
-        pixelsv1  = vec_ld( 0, pixels);
-        pixelsv2  = vec_ld(15, pixels);
-        pixelsv1B = vec_ld(line_size, pixels);
-        pixelsv2B = vec_ld(15 + line_size, pixels);
-        pixelsv1C = vec_ld(line_size_2, pixels);
-        pixelsv2C = vec_ld(15 + line_size_2, pixels);
-        pixelsv1D = vec_ld(line_size_3, pixels);
-        pixelsv2D = vec_ld(15 + line_size_3, pixels);
-        vec_st(vec_perm(pixelsv1, pixelsv2, perm),
-               0, (unsigned char*)block);
-        vec_st(vec_perm(pixelsv1B, pixelsv2B, perm),
-               line_size, (unsigned char*)block);
-        vec_st(vec_perm(pixelsv1C, pixelsv2C, perm),
-               line_size_2, (unsigned char*)block);
-        vec_st(vec_perm(pixelsv1D, pixelsv2D, perm),
-               line_size_3, (unsigned char*)block);
-        pixels+=line_size_4;
-        block +=line_size_4;
-    }
-}
-
-/* next one assumes that ((line_size % 16) == 0) */
-#define op_avg(a,b)  a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) )
-void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
-    register vector unsigned char perm = vec_lvsl(0, pixels);
-    int i;
-
-    for (i = 0; i < h; i++) {
-        pixelsv1 = vec_ld( 0, pixels);
-        pixelsv2 = vec_ld(16,pixels);
-        blockv = vec_ld(0, block);
-        pixelsv = vec_perm(pixelsv1, pixelsv2, perm);
-        blockv = vec_avg(blockv,pixelsv);
-        vec_st(blockv, 0, (unsigned char*)block);
-        pixels+=line_size;
-        block +=line_size;
-    }
-}
-
-/* next one assumes that ((line_size % 8) == 0) */
-static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
-{
-    register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
-    int i;
-
-   for (i = 0; i < h; i++) {
-       /* block is 8 bytes-aligned, so we're either in the
-          left block (16 bytes-aligned) or in the right block (not) */
-       int rightside = ((unsigned long)block & 0x0000000F);
-
-       blockv = vec_ld(0, block);
-       pixelsv1 = vec_ld( 0, pixels);
-       pixelsv2 = vec_ld(16, pixels);
-       pixelsv = vec_perm(pixelsv1, pixelsv2, vec_lvsl(0, pixels));
-
-       if (rightside) {
-           pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
-       } else {
-           pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3));
-       }
-
-       blockv = vec_avg(blockv, pixelsv);
-
-       vec_st(blockv, 0, block);
-
-       pixels += line_size;
-       block += line_size;
-   }
-}
-
-/* next one assumes that ((line_size % 8) == 0) */
-static void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    register int i;
-    register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
-    register vector unsigned char blockv, temp1, temp2;
-    register vector unsigned short pixelssum1, pixelssum2, temp3;
-    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
-    register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
-
-    temp1 = vec_ld(0, pixels);
-    temp2 = vec_ld(16, pixels);
-    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
-    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
-        pixelsv2 = temp2;
-    } else {
-        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
-    }
-    pixelsv1 = vec_mergeh(vczero, pixelsv1);
-    pixelsv2 = vec_mergeh(vczero, pixelsv2);
-    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
-                         (vector unsigned short)pixelsv2);
-    pixelssum1 = vec_add(pixelssum1, vctwo);
-
-    for (i = 0; i < h ; i++) {
-        int rightside = ((unsigned long)block & 0x0000000F);
-        blockv = vec_ld(0, block);
-
-        temp1 = vec_ld(line_size, pixels);
-        temp2 = vec_ld(line_size + 16, pixels);
-        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
-        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
-            pixelsv2 = temp2;
-        } else {
-            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
-        }
-
-        pixelsv1 = vec_mergeh(vczero, pixelsv1);
-        pixelsv2 = vec_mergeh(vczero, pixelsv2);
-        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
-                             (vector unsigned short)pixelsv2);
-        temp3 = vec_add(pixelssum1, pixelssum2);
-        temp3 = vec_sra(temp3, vctwo);
-        pixelssum1 = vec_add(pixelssum2, vctwo);
-        pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
-
-        if (rightside) {
-            blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
-        } else {
-            blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
-        }
-
-        vec_st(blockv, 0, block);
-
-        block += line_size;
-        pixels += line_size;
-    }
-}
-
-/* next one assumes that ((line_size % 8) == 0) */
-static void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    register int i;
-    register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
-    register vector unsigned char blockv, temp1, temp2;
-    register vector unsigned short pixelssum1, pixelssum2, temp3;
-    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
-    register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);
-    register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
-
-    temp1 = vec_ld(0, pixels);
-    temp2 = vec_ld(16, pixels);
-    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
-    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
-        pixelsv2 = temp2;
-    } else {
-        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
-    }
-    pixelsv1 = vec_mergeh(vczero, pixelsv1);
-    pixelsv2 = vec_mergeh(vczero, pixelsv2);
-    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
-                         (vector unsigned short)pixelsv2);
-    pixelssum1 = vec_add(pixelssum1, vcone);
-
-    for (i = 0; i < h ; i++) {
-        int rightside = ((unsigned long)block & 0x0000000F);
-        blockv = vec_ld(0, block);
-
-        temp1 = vec_ld(line_size, pixels);
-        temp2 = vec_ld(line_size + 16, pixels);
-        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
-        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
-            pixelsv2 = temp2;
-        } else {
-            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
-        }
-
-        pixelsv1 = vec_mergeh(vczero, pixelsv1);
-        pixelsv2 = vec_mergeh(vczero, pixelsv2);
-        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
-                             (vector unsigned short)pixelsv2);
-        temp3 = vec_add(pixelssum1, pixelssum2);
-        temp3 = vec_sra(temp3, vctwo);
-        pixelssum1 = vec_add(pixelssum2, vcone);
-        pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
-
-        if (rightside) {
-            blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
-        } else {
-            blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
-        }
-
-        vec_st(blockv, 0, block);
-
-        block += line_size;
-        pixels += line_size;
-    }
-}
-
-/* next one assumes that ((line_size % 16) == 0) */
-static void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
-{
-    register int i;
-    register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4;
-    register vector unsigned char blockv, temp1, temp2;
-    register vector unsigned short temp3, temp4,
-        pixelssum1, pixelssum2, pixelssum3, pixelssum4;
-    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
-    register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
-
-    temp1 = vec_ld(0, pixels);
-    temp2 = vec_ld(16, pixels);
-    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
-    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
-        pixelsv2 = temp2;
-    } else {
-        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
-    }
-    pixelsv3 = vec_mergel(vczero, pixelsv1);
-    pixelsv4 = vec_mergel(vczero, pixelsv2);
-    pixelsv1 = vec_mergeh(vczero, pixelsv1);
-    pixelsv2 = vec_mergeh(vczero, pixelsv2);
-    pixelssum3 = vec_add((vector unsigned short)pixelsv3,
-                         (vector unsigned short)pixelsv4);
-    pixelssum3 = vec_add(pixelssum3, vctwo);
-    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
-                         (vector unsigned short)pixelsv2);
-    pixelssum1 = vec_add(pixelssum1, vctwo);
-
-    for (i = 0; i < h ; i++) {
-        blockv = vec_ld(0, block);
-
-        temp1 = vec_ld(line_size, pixels);
-        temp2 = vec_ld(line_size + 16, pixels);
-        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
-        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
-            pixelsv2 = temp2;
-        } else {
-            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
-        }
-
-        pixelsv3 = vec_mergel(vczero, pixelsv1);
-        pixelsv4 = vec_mergel(vczero, pixelsv2);
-        pixelsv1 = vec_mergeh(vczero, pixelsv1);
-        pixelsv2 = vec_mergeh(vczero, pixelsv2);
-
-        pixelssum4 = vec_add((vector unsigned short)pixelsv3,
-                             (vector unsigned short)pixelsv4);
-        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
-                             (vector unsigned short)pixelsv2);
-        temp4 = vec_add(pixelssum3, pixelssum4);
-        temp4 = vec_sra(temp4, vctwo);
-        temp3 = vec_add(pixelssum1, pixelssum2);
-        temp3 = vec_sra(temp3, vctwo);
-
-        pixelssum3 = vec_add(pixelssum4, vctwo);
-        pixelssum1 = vec_add(pixelssum2, vctwo);
-
-        blockv = vec_packsu(temp3, temp4);
-
-        vec_st(blockv, 0, block);
-
-        block += line_size;
-        pixels += line_size;
-    }
-}
-
-/* next one assumes that ((line_size % 16) == 0) */
-static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, int line_size, int h)
-{
-    register int i;
-    register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4;
-    register vector unsigned char blockv, temp1, temp2;
-    register vector unsigned short temp3, temp4,
-        pixelssum1, pixelssum2, pixelssum3, pixelssum4;
-    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
-    register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);
-    register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
-
-    temp1 = vec_ld(0, pixels);
-    temp2 = vec_ld(16, pixels);
-    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
-    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
-        pixelsv2 = temp2;
-    } else {
-        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
-    }
-    pixelsv3 = vec_mergel(vczero, pixelsv1);
-    pixelsv4 = vec_mergel(vczero, pixelsv2);
-    pixelsv1 = vec_mergeh(vczero, pixelsv1);
-    pixelsv2 = vec_mergeh(vczero, pixelsv2);
-    pixelssum3 = vec_add((vector unsigned short)pixelsv3,
-                         (vector unsigned short)pixelsv4);
-    pixelssum3 = vec_add(pixelssum3, vcone);
-    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
-                         (vector unsigned short)pixelsv2);
-    pixelssum1 = vec_add(pixelssum1, vcone);
-
-    for (i = 0; i < h ; i++) {
-        blockv = vec_ld(0, block);
-
-        temp1 = vec_ld(line_size, pixels);
-        temp2 = vec_ld(line_size + 16, pixels);
-        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
-        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
-            pixelsv2 = temp2;
-        } else {
-            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
-        }
-
-        pixelsv3 = vec_mergel(vczero, pixelsv1);
-        pixelsv4 = vec_mergel(vczero, pixelsv2);
-        pixelsv1 = vec_mergeh(vczero, pixelsv1);
-        pixelsv2 = vec_mergeh(vczero, pixelsv2);
-
-        pixelssum4 = vec_add((vector unsigned short)pixelsv3,
-                             (vector unsigned short)pixelsv4);
-        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
-                             (vector unsigned short)pixelsv2);
-        temp4 = vec_add(pixelssum3, pixelssum4);
-        temp4 = vec_sra(temp4, vctwo);
-        temp3 = vec_add(pixelssum1, pixelssum2);
-        temp3 = vec_sra(temp3, vctwo);
-
-        pixelssum3 = vec_add(pixelssum4, vcone);
-        pixelssum1 = vec_add(pixelssum2, vcone);
-
-        blockv = vec_packsu(temp3, temp4);
-
-        vec_st(blockv, 0, block);
-
-        block += line_size;
-        pixels += line_size;
-    }
-}
-
 static int hadamard8_diff8x8_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, uint8_t *src, int stride, int h){
     int sum;
     register const vector unsigned char vzero =
@@ -1283,93 +936,7 @@ static int hadamard8_diff16_altivec(/*MpegEncContext*/ void *s, uint8_t *dst, ui
     return score;
 }
 
-static void vorbis_inverse_coupling_altivec(float *mag, float *ang,
-                                            int blocksize)
-{
-    int i;
-    vector float m, a;
-    vector bool int t0, t1;
-    const vector unsigned int v_31 = //XXX
-        vec_add(vec_add(vec_splat_u32(15),vec_splat_u32(15)),vec_splat_u32(1));
-    for (i = 0; i < blocksize; i += 4) {
-        m = vec_ld(0, mag+i);
-        a = vec_ld(0, ang+i);
-        t0 = vec_cmple(m, (vector float)vec_splat_u32(0));
-        t1 = vec_cmple(a, (vector float)vec_splat_u32(0));
-        a = vec_xor(a, (vector float) vec_sl((vector unsigned int)t0, v_31));
-        t0 = (vector bool int)vec_and(a, t1);
-        t1 = (vector bool int)vec_andc(a, t1);
-        a = vec_sub(m, (vector float)t1);
-        m = vec_add(m, (vector float)t0);
-        vec_stl(a, 0, ang+i);
-        vec_stl(m, 0, mag+i);
-    }
-}
-
-/* next one assumes that ((line_size % 8) == 0) */
-static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    register int i;
-    register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
-    register vector unsigned char blockv, temp1, temp2, blocktemp;
-    register vector unsigned short pixelssum1, pixelssum2, temp3;
-
-    register const vector unsigned char vczero = (const vector unsigned char)
-                                        vec_splat_u8(0);
-    register const vector unsigned short vctwo = (const vector unsigned short)
-                                        vec_splat_u16(2);
-
-    temp1 = vec_ld(0, pixels);
-    temp2 = vec_ld(16, pixels);
-    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
-    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
-        pixelsv2 = temp2;
-    } else {
-        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
-    }
-    pixelsv1 = vec_mergeh(vczero, pixelsv1);
-    pixelsv2 = vec_mergeh(vczero, pixelsv2);
-    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
-                         (vector unsigned short)pixelsv2);
-    pixelssum1 = vec_add(pixelssum1, vctwo);
-
-    for (i = 0; i < h ; i++) {
-        int rightside = ((unsigned long)block & 0x0000000F);
-        blockv = vec_ld(0, block);
-
-        temp1 = vec_ld(line_size, pixels);
-        temp2 = vec_ld(line_size + 16, pixels);
-        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
-        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
-            pixelsv2 = temp2;
-        } else {
-            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
-        }
-
-        pixelsv1 = vec_mergeh(vczero, pixelsv1);
-        pixelsv2 = vec_mergeh(vczero, pixelsv2);
-        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
-                             (vector unsigned short)pixelsv2);
-        temp3 = vec_add(pixelssum1, pixelssum2);
-        temp3 = vec_sra(temp3, vctwo);
-        pixelssum1 = vec_add(pixelssum2, vctwo);
-        pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
-
-        if (rightside) {
-            blocktemp = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
-        } else {
-            blocktemp = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
-        }
-
-        blockv = vec_avg(blocktemp, blockv);
-        vec_st(blockv, 0, block);
-
-        block += line_size;
-        pixels += line_size;
-    }
-}
-
-void ff_dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_altivec(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -1389,20 +956,8 @@ void ff_dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx)
     if (!high_bit_depth) {
     c->get_pixels = get_pixels_altivec;
     c->clear_block = clear_block_altivec;
-    c->put_pixels_tab[0][0] = ff_put_pixels16_altivec;
-    /* the two functions do the same thing, so use the same code */
-    c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_altivec;
-    c->avg_pixels_tab[0][0] = ff_avg_pixels16_altivec;
-    c->avg_pixels_tab[1][0] = avg_pixels8_altivec;
-    c->avg_pixels_tab[1][3] = avg_pixels8_xy2_altivec;
-    c->put_pixels_tab[1][3] = put_pixels8_xy2_altivec;
-    c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec;
-    c->put_pixels_tab[0][3] = put_pixels16_xy2_altivec;
-    c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec;
     }
 
     c->hadamard8_diff[0] = hadamard8_diff16_altivec;
     c->hadamard8_diff[1] = hadamard8_diff8x8_altivec;
-    if (CONFIG_VORBIS_DECODER)
-        c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec;
 }
diff --git a/libavcodec/ppc/dsputil_altivec.h b/libavcodec/ppc/dsputil_altivec.h
index 7cbda36..de5054b 100644
--- a/libavcodec/ppc/dsputil_altivec.h
+++ b/libavcodec/ppc/dsputil_altivec.h
@@ -26,9 +26,9 @@
 #include <stdint.h>
 #include "libavcodec/dsputil.h"
 
-void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h);
+void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
 
-void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, int line_size, int h);
+void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h);
 
 void ff_fdct_altivec(int16_t *block);
 void ff_gmc1_altivec(uint8_t *dst, uint8_t *src, int stride, int h,
@@ -36,8 +36,6 @@ void ff_gmc1_altivec(uint8_t *dst, uint8_t *src, int stride, int h,
 void ff_idct_put_altivec(uint8_t *dest, int line_size, int16_t *block);
 void ff_idct_add_altivec(uint8_t *dest, int line_size, int16_t *block);
 
-void ff_dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx);
-
 void ff_dsputil_init_altivec(DSPContext* c, AVCodecContext *avctx);
 void ff_float_init_altivec(DSPContext* c, AVCodecContext *avctx);
 void ff_int_init_altivec(DSPContext* c, AVCodecContext *avctx);
diff --git a/libavcodec/ppc/dsputil_ppc.c b/libavcodec/ppc/dsputil_ppc.c
index a306940..6ae6e3f 100644
--- a/libavcodec/ppc/dsputil_ppc.c
+++ b/libavcodec/ppc/dsputil_ppc.c
@@ -22,9 +22,10 @@
 
 #include <string.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/mem.h"
-#include "libavcodec/dsputil.h"
+#include "libavutil/ppc/cpu.h"
 #include "dsputil_altivec.h"
 
 /* ***** WARNING ***** WARNING ***** WARNING ***** */
@@ -47,7 +48,7 @@ distinguish, and use dcbz (32 bytes) or dcbzl (one cache line) as required.
 see <http://developer.apple.com/technotes/tn/tn2087.html>
 and <http://developer.apple.com/technotes/tn/tn2086.html>
 */
-static void clear_blocks_dcbz32_ppc(DCTELEM *blocks)
+static void clear_blocks_dcbz32_ppc(int16_t *blocks)
 {
     register int misal = ((unsigned long)blocks & 0x00000010);
     register int i = 0;
@@ -58,7 +59,7 @@ static void clear_blocks_dcbz32_ppc(DCTELEM *blocks)
         ((unsigned long*)blocks)[3] = 0L;
         i += 16;
     }
-    for ( ; i < sizeof(DCTELEM)*6*64-31 ; i += 32) {
+    for ( ; i < sizeof(int16_t)*6*64-31 ; i += 32) {
         __asm__ volatile("dcbz %0,%1" : : "b" (blocks), "r" (i) : "memory");
     }
     if (misal) {
@@ -73,7 +74,7 @@ static void clear_blocks_dcbz32_ppc(DCTELEM *blocks)
 /* same as above, when dcbzl clear a whole 128B cache line
    i.e. the PPC970 aka G5 */
 #if HAVE_DCBZL
-static void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
+static void clear_blocks_dcbz128_ppc(int16_t *blocks)
 {
     register int misal = ((unsigned long)blocks & 0x0000007f);
     register int i = 0;
@@ -81,17 +82,17 @@ static void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
         // we could probably also optimize this case,
         // but there's not much point as the machines
         // aren't available yet (2003-06-26)
-        memset(blocks, 0, sizeof(DCTELEM)*6*64);
+        memset(blocks, 0, sizeof(int16_t)*6*64);
     }
     else
-        for ( ; i < sizeof(DCTELEM)*6*64 ; i += 128) {
+        for ( ; i < sizeof(int16_t)*6*64 ; i += 128) {
             __asm__ volatile("dcbzl %0,%1" : : "b" (blocks), "r" (i) : "memory");
         }
 }
 #else
-static void clear_blocks_dcbz128_ppc(DCTELEM *blocks)
+static void clear_blocks_dcbz128_ppc(int16_t *blocks)
 {
-    memset(blocks, 0, sizeof(DCTELEM)*6*64);
+    memset(blocks, 0, sizeof(int16_t)*6*64);
 }
 #endif
 
@@ -137,7 +138,7 @@ static long check_dcbzl_effect(void)
 }
 #endif
 
-void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_ppc(DSPContext *c, AVCodecContext *avctx)
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
@@ -155,12 +156,8 @@ void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
     }
     }
 
-#if HAVE_ALTIVEC
-    if(CONFIG_H264_DECODER) ff_dsputil_h264_init_ppc(c, avctx);
-
-    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
+    if (PPC_ALTIVEC(av_get_cpu_flags())) {
         ff_dsputil_init_altivec(c, avctx);
-        ff_float_init_altivec(c, avctx);
         ff_int_init_altivec(c, avctx);
         c->gmc1 = ff_gmc1_altivec;
 
@@ -182,5 +179,4 @@ void ff_dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx)
         }
 
     }
-#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/fdct_altivec.c b/libavcodec/ppc/fdct_altivec.c
index 0e3658d..355a697 100644
--- a/libavcodec/ppc/fdct_altivec.c
+++ b/libavcodec/ppc/fdct_altivec.c
@@ -23,7 +23,6 @@
 #include <altivec.h>
 #endif
 #include "libavutil/common.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_altivec.h"
 
 #define vs16(v) ((vector signed short)(v))
@@ -459,5 +458,3 @@ void ff_fdct_altivec(int16_t *block)
 #undef CTS
     /* }}} */
 }
-
-/* vim:set foldmethod=marker foldlevel=0: */
diff --git a/libavcodec/ppc/fft_altivec.c b/libavcodec/ppc/fft_altivec.c
index c85d04f..2885d3f 100644
--- a/libavcodec/ppc/fft_altivec.c
+++ b/libavcodec/ppc/fft_altivec.c
@@ -20,6 +20,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
+#include "libavutil/cpu.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
 #include "libavcodec/fft.h"
@@ -36,8 +38,8 @@
 void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z);
 void ff_fft_calc_interleave_altivec(FFTContext *s, FFTComplex *z);
 
-#if HAVE_GNU_AS
-static void ff_imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSample *input)
+#if HAVE_GNU_AS && HAVE_ALTIVEC
+static void imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSample *input)
 {
     int j, k;
     int n = 1 << s->mdct_bits;
@@ -117,7 +119,7 @@ static void ff_imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSam
     } while(k >= 0);
 }
 
-static void ff_imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSample *input)
+static void imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSample *input)
 {
     int k;
     int n = 1 << s->mdct_bits;
@@ -127,7 +129,7 @@ static void ff_imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSam
     vec_u32 *p0 = (vec_u32*)(output+n4);
     vec_u32 *p1 = (vec_u32*)(output+n4*3);
 
-    ff_imdct_half_altivec(s, output+n4, input);
+    imdct_half_altivec(s, output + n4, input);
 
     for (k = 0; k < n16; k++) {
         vec_u32 a = p0[k] ^ sign;
@@ -136,15 +138,18 @@ static void ff_imdct_calc_altivec(FFTContext *s, FFTSample *output, const FFTSam
         p1[k]    = vec_perm(b, b, vcprm(3,2,1,0));
     }
 }
-#endif /* HAVE_GNU_AS */
+#endif /* HAVE_GNU_AS && HAVE_ALTIVEC */
 
-av_cold void ff_fft_init_altivec(FFTContext *s)
+av_cold void ff_fft_init_ppc(FFTContext *s)
 {
-#if HAVE_GNU_AS
+#if HAVE_GNU_AS && HAVE_ALTIVEC
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
     s->fft_calc   = ff_fft_calc_interleave_altivec;
     if (s->mdct_bits >= 5) {
-        s->imdct_calc = ff_imdct_calc_altivec;
-        s->imdct_half = ff_imdct_half_altivec;
+        s->imdct_calc = imdct_calc_altivec;
+        s->imdct_half = imdct_half_altivec;
     }
-#endif
+#endif /* HAVE_GNU_AS && HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/float_altivec.c b/libavcodec/ppc/float_altivec.c
deleted file mode 100644
index 5068fd4..0000000
--- a/libavcodec/ppc/float_altivec.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2006 Luca Barbato <lu_zero at gentoo.org>
- *
- * 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/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
-
-#include "dsputil_altivec.h"
-
-static void vector_fmul_reverse_altivec(float *dst, const float *src0,
-                                        const float *src1, int len)
-{
-    int i;
-    vector float d, s0, s1, h0, l0,
-                 s2, s3, zero = (vector float)vec_splat_u32(0);
-    src1 += len-4;
-    for(i=0; i<len-7; i+=8) {
-        s1 = vec_ld(0, src1-i);              // [a,b,c,d]
-        s0 = vec_ld(0, src0+i);
-        l0 = vec_mergel(s1, s1);             // [c,c,d,d]
-        s3 = vec_ld(-16, src1-i);
-        h0 = vec_mergeh(s1, s1);             // [a,a,b,b]
-        s2 = vec_ld(16, src0+i);
-        s1 = vec_mergeh(vec_mergel(l0,h0),   // [d,b,d,b]
-                        vec_mergeh(l0,h0));  // [c,a,c,a]
-                                             // [d,c,b,a]
-        l0 = vec_mergel(s3, s3);
-        d = vec_madd(s0, s1, zero);
-        h0 = vec_mergeh(s3, s3);
-        vec_st(d, 0, dst+i);
-        s3 = vec_mergeh(vec_mergel(l0,h0),
-                        vec_mergeh(l0,h0));
-        d = vec_madd(s2, s3, zero);
-        vec_st(d, 16, dst+i);
-    }
-}
-
-static void vector_fmul_add_altivec(float *dst, const float *src0,
-                                    const float *src1, const float *src2,
-                                    int len)
-{
-    int i;
-    vector float d, s0, s1, s2, t0, t1, edges;
-    vector unsigned char align = vec_lvsr(0,dst),
-                         mask = vec_lvsl(0, dst);
-
-    for (i=0; i<len-3; i+=4) {
-        t0 = vec_ld(0, dst+i);
-        t1 = vec_ld(15, dst+i);
-        s0 = vec_ld(0, src0+i);
-        s1 = vec_ld(0, src1+i);
-        s2 = vec_ld(0, src2+i);
-        edges = vec_perm(t1 ,t0, mask);
-        d = vec_madd(s0,s1,s2);
-        t1 = vec_perm(d, edges, align);
-        t0 = vec_perm(edges, d, align);
-        vec_st(t1, 15, dst+i);
-        vec_st(t0, 0, dst+i);
-    }
-}
-
-static void vector_fmul_window_altivec(float *dst, const float *src0, const float *src1, const float *win, int len)
-{
-    vector float zero, t0, t1, s0, s1, wi, wj;
-    const vector unsigned char reverse = vcprm(3,2,1,0);
-    int i,j;
-
-    dst += len;
-    win += len;
-    src0+= len;
-
-    zero = (vector float)vec_splat_u32(0);
-
-    for(i=-len*4, j=len*4-16; i<0; i+=16, j-=16) {
-        s0 = vec_ld(i, src0);
-        s1 = vec_ld(j, src1);
-        wi = vec_ld(i, win);
-        wj = vec_ld(j, win);
-
-        s1 = vec_perm(s1, s1, reverse);
-        wj = vec_perm(wj, wj, reverse);
-
-        t0 = vec_madd(s0, wj, zero);
-        t0 = vec_nmsub(s1, wi, t0);
-        t1 = vec_madd(s0, wi, zero);
-        t1 = vec_madd(s1, wj, t1);
-        t1 = vec_perm(t1, t1, reverse);
-
-        vec_st(t0, i, dst);
-        vec_st(t1, j, dst);
-    }
-}
-
-void ff_float_init_altivec(DSPContext* c, AVCodecContext *avctx)
-{
-    c->vector_fmul_reverse = vector_fmul_reverse_altivec;
-    c->vector_fmul_add = vector_fmul_add_altivec;
-    if(!(avctx->flags & CODEC_FLAG_BITEXACT)) {
-        c->vector_fmul_window = vector_fmul_window_altivec;
-    }
-}
diff --git a/libavcodec/ppc/fmtconvert_altivec.c b/libavcodec/ppc/fmtconvert_altivec.c
index 68e5e00..1359259 100644
--- a/libavcodec/ppc/fmtconvert_altivec.c
+++ b/libavcodec/ppc/fmtconvert_altivec.c
@@ -18,13 +18,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/fmtconvert.h"
-
-#include "libavutil/ppc/util_altivec.h"
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
 #include "libavutil/mem.h"
+#include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/fmtconvert.h"
 #include "dsputil_altivec.h"
 
-static void int32_to_float_fmul_scalar_altivec(float *dst, const int *src,
+#if HAVE_ALTIVEC
+
+static void int32_to_float_fmul_scalar_altivec(float *dst, const int32_t *src,
                                                float mul, int len)
 {
     union {
@@ -92,8 +96,8 @@ static void float_to_int16_altivec(int16_t *dst, const float *src, long len)
 static void float_to_int16_stride_altivec(int16_t *dst, const float *src,
                                           long len, int stride)
 {
-    int i, j;
-    vector signed short d, s;
+    int i;
+    vector signed short d;
 
     for (i = 0; i < len - 7; i += 8) {
         d = float_to_int16_one_altivec(src + i);
@@ -155,11 +159,19 @@ static void float_to_int16_interleave_altivec(int16_t *dst, const float **src,
     }
 }
 
-void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_fmt_convert_init_ppc(FmtConvertContext *c,
+                                     AVCodecContext *avctx)
 {
+#if HAVE_ALTIVEC
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
     c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_altivec;
     if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
         c->float_to_int16 = float_to_int16_altivec;
         c->float_to_int16_interleave = float_to_int16_interleave_altivec;
     }
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/gmc_altivec.c b/libavcodec/ppc/gmc_altivec.c
index f86964b..38968dd 100644
--- a/libavcodec/ppc/gmc_altivec.c
+++ b/libavcodec/ppc/gmc_altivec.c
@@ -23,7 +23,6 @@
 #include "libavutil/mem.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_altivec.h"
 
 /*
diff --git a/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264_altivec.c
deleted file mode 100644
index 73e2adb..0000000
--- a/libavcodec/ppc/h264_altivec.c
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*
- * Copyright (c) 2004 Romain Dolbeau <romain at dolbeau.org>
- *
- * 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/cpu.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/ppc/types_altivec.h"
-#include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
-#include "libavcodec/h264data.h"
-#include "libavcodec/h264dsp.h"
-
-#include "dsputil_altivec.h"
-
-#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
-#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
-
-#define OP_U8_ALTIVEC                          PUT_OP_U8_ALTIVEC
-#define PREFIX_h264_chroma_mc8_altivec         put_h264_chroma_mc8_altivec
-#define PREFIX_h264_chroma_mc8_num             altivec_put_h264_chroma_mc8_num
-#define PREFIX_h264_qpel16_h_lowpass_altivec   put_h264_qpel16_h_lowpass_altivec
-#define PREFIX_h264_qpel16_h_lowpass_num       altivec_put_h264_qpel16_h_lowpass_num
-#define PREFIX_h264_qpel16_v_lowpass_altivec   put_h264_qpel16_v_lowpass_altivec
-#define PREFIX_h264_qpel16_v_lowpass_num       altivec_put_h264_qpel16_v_lowpass_num
-#define PREFIX_h264_qpel16_hv_lowpass_altivec  put_h264_qpel16_hv_lowpass_altivec
-#define PREFIX_h264_qpel16_hv_lowpass_num      altivec_put_h264_qpel16_hv_lowpass_num
-#include "h264_altivec_template.c"
-#undef OP_U8_ALTIVEC
-#undef PREFIX_h264_chroma_mc8_altivec
-#undef PREFIX_h264_chroma_mc8_num
-#undef PREFIX_h264_qpel16_h_lowpass_altivec
-#undef PREFIX_h264_qpel16_h_lowpass_num
-#undef PREFIX_h264_qpel16_v_lowpass_altivec
-#undef PREFIX_h264_qpel16_v_lowpass_num
-#undef PREFIX_h264_qpel16_hv_lowpass_altivec
-#undef PREFIX_h264_qpel16_hv_lowpass_num
-
-#define OP_U8_ALTIVEC                          AVG_OP_U8_ALTIVEC
-#define PREFIX_h264_chroma_mc8_altivec         avg_h264_chroma_mc8_altivec
-#define PREFIX_h264_chroma_mc8_num             altivec_avg_h264_chroma_mc8_num
-#define PREFIX_h264_qpel16_h_lowpass_altivec   avg_h264_qpel16_h_lowpass_altivec
-#define PREFIX_h264_qpel16_h_lowpass_num       altivec_avg_h264_qpel16_h_lowpass_num
-#define PREFIX_h264_qpel16_v_lowpass_altivec   avg_h264_qpel16_v_lowpass_altivec
-#define PREFIX_h264_qpel16_v_lowpass_num       altivec_avg_h264_qpel16_v_lowpass_num
-#define PREFIX_h264_qpel16_hv_lowpass_altivec  avg_h264_qpel16_hv_lowpass_altivec
-#define PREFIX_h264_qpel16_hv_lowpass_num      altivec_avg_h264_qpel16_hv_lowpass_num
-#include "h264_altivec_template.c"
-#undef OP_U8_ALTIVEC
-#undef PREFIX_h264_chroma_mc8_altivec
-#undef PREFIX_h264_chroma_mc8_num
-#undef PREFIX_h264_qpel16_h_lowpass_altivec
-#undef PREFIX_h264_qpel16_h_lowpass_num
-#undef PREFIX_h264_qpel16_v_lowpass_altivec
-#undef PREFIX_h264_qpel16_v_lowpass_num
-#undef PREFIX_h264_qpel16_hv_lowpass_altivec
-#undef PREFIX_h264_qpel16_hv_lowpass_num
-
-#define H264_MC(OPNAME, SIZE, CODETYPE) \
-static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## CODETYPE (uint8_t *dst, uint8_t *src, int stride){\
-    ff_ ## OPNAME ## pixels ## SIZE ## _ ## CODETYPE(dst, src, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){ \
-    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(dst, src, stride, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+1, half, stride, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(dst, src, stride, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+stride, half, stride, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(dst, tmp, src, stride, SIZE, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, uint8_t *src, int stride){\
-    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
-    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
-    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
-}\
-
-static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
-                                    const uint8_t * src2, int dst_stride,
-                                    int src_stride1, int h)
-{
-    int i;
-    vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
-
-    mask_ = vec_lvsl(0, src2);
-
-    for (i = 0; i < h; i++) {
-
-        tmp1 = vec_ld(i * src_stride1, src1);
-        mask = vec_lvsl(i * src_stride1, src1);
-        tmp2 = vec_ld(i * src_stride1 + 15, src1);
-
-        a = vec_perm(tmp1, tmp2, mask);
-
-        tmp1 = vec_ld(i * 16, src2);
-        tmp2 = vec_ld(i * 16 + 15, src2);
-
-        b = vec_perm(tmp1, tmp2, mask_);
-
-        tmp1 = vec_ld(0, dst);
-        mask = vec_lvsl(0, dst);
-        tmp2 = vec_ld(15, dst);
-
-        d = vec_avg(a, b);
-
-        edges = vec_perm(tmp2, tmp1, mask);
-
-        align = vec_lvsr(0, dst);
-
-        tmp2 = vec_perm(d, edges, align);
-        tmp1 = vec_perm(edges, d, align);
-
-        vec_st(tmp2, 15, dst);
-        vec_st(tmp1, 0 , dst);
-
-        dst += dst_stride;
-    }
-}
-
-static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
-                                    const uint8_t * src2, int dst_stride,
-                                    int src_stride1, int h)
-{
-    int i;
-    vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
-
-    mask_ = vec_lvsl(0, src2);
-
-    for (i = 0; i < h; i++) {
-
-        tmp1 = vec_ld(i * src_stride1, src1);
-        mask = vec_lvsl(i * src_stride1, src1);
-        tmp2 = vec_ld(i * src_stride1 + 15, src1);
-
-        a = vec_perm(tmp1, tmp2, mask);
-
-        tmp1 = vec_ld(i * 16, src2);
-        tmp2 = vec_ld(i * 16 + 15, src2);
-
-        b = vec_perm(tmp1, tmp2, mask_);
-
-        tmp1 = vec_ld(0, dst);
-        mask = vec_lvsl(0, dst);
-        tmp2 = vec_ld(15, dst);
-
-        d = vec_avg(vec_perm(tmp1, tmp2, mask), vec_avg(a, b));
-
-        edges = vec_perm(tmp2, tmp1, mask);
-
-        align = vec_lvsr(0, dst);
-
-        tmp2 = vec_perm(d, edges, align);
-        tmp1 = vec_perm(edges, d, align);
-
-        vec_st(tmp2, 15, dst);
-        vec_st(tmp1, 0 , dst);
-
-        dst += dst_stride;
-    }
-}
-
-/* Implemented but could be faster
-#define put_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) put_pixels16_l2(d,s1,s2,ds,s1s,16,h)
-#define avg_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) avg_pixels16_l2(d,s1,s2,ds,s1s,16,h)
- */
-
-H264_MC(put_, 16, altivec)
-H264_MC(avg_, 16, altivec)
-
-
-/****************************************************************************
- * IDCT transform:
- ****************************************************************************/
-
-#define VEC_1D_DCT(vb0,vb1,vb2,vb3,va0,va1,va2,va3)               \
-    /* 1st stage */                                               \
-    vz0 = vec_add(vb0,vb2);       /* temp[0] = Y[0] + Y[2] */     \
-    vz1 = vec_sub(vb0,vb2);       /* temp[1] = Y[0] - Y[2] */     \
-    vz2 = vec_sra(vb1,vec_splat_u16(1));                          \
-    vz2 = vec_sub(vz2,vb3);       /* temp[2] = Y[1].1/2 - Y[3] */ \
-    vz3 = vec_sra(vb3,vec_splat_u16(1));                          \
-    vz3 = vec_add(vb1,vz3);       /* temp[3] = Y[1] + Y[3].1/2 */ \
-    /* 2nd stage: output */                                       \
-    va0 = vec_add(vz0,vz3);       /* x[0] = temp[0] + temp[3] */  \
-    va1 = vec_add(vz1,vz2);       /* x[1] = temp[1] + temp[2] */  \
-    va2 = vec_sub(vz1,vz2);       /* x[2] = temp[1] - temp[2] */  \
-    va3 = vec_sub(vz0,vz3)        /* x[3] = temp[0] - temp[3] */
-
-#define VEC_TRANSPOSE_4(a0,a1,a2,a3,b0,b1,b2,b3) \
-    b0 = vec_mergeh( a0, a0 ); \
-    b1 = vec_mergeh( a1, a0 ); \
-    b2 = vec_mergeh( a2, a0 ); \
-    b3 = vec_mergeh( a3, a0 ); \
-    a0 = vec_mergeh( b0, b2 ); \
-    a1 = vec_mergel( b0, b2 ); \
-    a2 = vec_mergeh( b1, b3 ); \
-    a3 = vec_mergel( b1, b3 ); \
-    b0 = vec_mergeh( a0, a2 ); \
-    b1 = vec_mergel( a0, a2 ); \
-    b2 = vec_mergeh( a1, a3 ); \
-    b3 = vec_mergel( a1, a3 )
-
-#define VEC_LOAD_U8_ADD_S16_STORE_U8(va)                      \
-    vdst_orig = vec_ld(0, dst);                               \
-    vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask);          \
-    vdst_ss = (vec_s16) vec_mergeh(zero_u8v, vdst);         \
-    va = vec_add(va, vdst_ss);                                \
-    va_u8 = vec_packsu(va, zero_s16v);                        \
-    va_u32 = vec_splat((vec_u32)va_u8, 0);                  \
-    vec_ste(va_u32, element, (uint32_t*)dst);
-
-static void ff_h264_idct_add_altivec(uint8_t *dst, DCTELEM *block, int stride)
-{
-    vec_s16 va0, va1, va2, va3;
-    vec_s16 vz0, vz1, vz2, vz3;
-    vec_s16 vtmp0, vtmp1, vtmp2, vtmp3;
-    vec_u8 va_u8;
-    vec_u32 va_u32;
-    vec_s16 vdst_ss;
-    const vec_u16 v6us = vec_splat_u16(6);
-    vec_u8 vdst, vdst_orig;
-    vec_u8 vdst_mask = vec_lvsl(0, dst);
-    int element = ((unsigned long)dst & 0xf) >> 2;
-    LOAD_ZERO;
-
-    block[0] += 32;  /* add 32 as a DC-level for rounding */
-
-    vtmp0 = vec_ld(0,block);
-    vtmp1 = vec_sld(vtmp0, vtmp0, 8);
-    vtmp2 = vec_ld(16,block);
-    vtmp3 = vec_sld(vtmp2, vtmp2, 8);
-
-    VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3);
-    VEC_TRANSPOSE_4(va0,va1,va2,va3,vtmp0,vtmp1,vtmp2,vtmp3);
-    VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3);
-
-    va0 = vec_sra(va0,v6us);
-    va1 = vec_sra(va1,v6us);
-    va2 = vec_sra(va2,v6us);
-    va3 = vec_sra(va3,v6us);
-
-    VEC_LOAD_U8_ADD_S16_STORE_U8(va0);
-    dst += stride;
-    VEC_LOAD_U8_ADD_S16_STORE_U8(va1);
-    dst += stride;
-    VEC_LOAD_U8_ADD_S16_STORE_U8(va2);
-    dst += stride;
-    VEC_LOAD_U8_ADD_S16_STORE_U8(va3);
-}
-
-#define IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7,  d0, d1, d2, d3, d4, d5, d6, d7) {\
-    /*        a0  = SRC(0) + SRC(4); */ \
-    vec_s16 a0v = vec_add(s0, s4);    \
-    /*        a2  = SRC(0) - SRC(4); */ \
-    vec_s16 a2v = vec_sub(s0, s4);    \
-    /*        a4  =           (SRC(2)>>1) - SRC(6); */ \
-    vec_s16 a4v = vec_sub(vec_sra(s2, onev), s6);    \
-    /*        a6  =           (SRC(6)>>1) + SRC(2); */ \
-    vec_s16 a6v = vec_add(vec_sra(s6, onev), s2);    \
-    /*        b0  =         a0 + a6; */ \
-    vec_s16 b0v = vec_add(a0v, a6v);  \
-    /*        b2  =         a2 + a4; */ \
-    vec_s16 b2v = vec_add(a2v, a4v);  \
-    /*        b4  =         a2 - a4; */ \
-    vec_s16 b4v = vec_sub(a2v, a4v);  \
-    /*        b6  =         a0 - a6; */ \
-    vec_s16 b6v = vec_sub(a0v, a6v);  \
-    /* a1 =  SRC(5) - SRC(3) - SRC(7) - (SRC(7)>>1); */ \
-    /*        a1 =             (SRC(5)-SRC(3)) -  (SRC(7)  +  (SRC(7)>>1)); */ \
-    vec_s16 a1v = vec_sub( vec_sub(s5, s3), vec_add(s7, vec_sra(s7, onev)) ); \
-    /* a3 =  SRC(7) + SRC(1) - SRC(3) - (SRC(3)>>1); */ \
-    /*        a3 =             (SRC(7)+SRC(1)) -  (SRC(3)  +  (SRC(3)>>1)); */ \
-    vec_s16 a3v = vec_sub( vec_add(s7, s1), vec_add(s3, vec_sra(s3, onev)) );\
-    /* a5 =  SRC(7) - SRC(1) + SRC(5) + (SRC(5)>>1); */ \
-    /*        a5 =             (SRC(7)-SRC(1)) +   SRC(5) +   (SRC(5)>>1); */ \
-    vec_s16 a5v = vec_add( vec_sub(s7, s1), vec_add(s5, vec_sra(s5, onev)) );\
-    /*        a7 =                SRC(5)+SRC(3) +  SRC(1) +   (SRC(1)>>1); */ \
-    vec_s16 a7v = vec_add( vec_add(s5, s3), vec_add(s1, vec_sra(s1, onev)) );\
-    /*        b1 =                  (a7>>2)  +  a1; */ \
-    vec_s16 b1v = vec_add( vec_sra(a7v, twov), a1v); \
-    /*        b3 =          a3 +        (a5>>2); */ \
-    vec_s16 b3v = vec_add(a3v, vec_sra(a5v, twov)); \
-    /*        b5 =                  (a3>>2)  -   a5; */ \
-    vec_s16 b5v = vec_sub( vec_sra(a3v, twov), a5v); \
-    /*        b7 =           a7 -        (a1>>2); */ \
-    vec_s16 b7v = vec_sub( a7v, vec_sra(a1v, twov)); \
-    /* DST(0,    b0 + b7); */ \
-    d0 = vec_add(b0v, b7v); \
-    /* DST(1,    b2 + b5); */ \
-    d1 = vec_add(b2v, b5v); \
-    /* DST(2,    b4 + b3); */ \
-    d2 = vec_add(b4v, b3v); \
-    /* DST(3,    b6 + b1); */ \
-    d3 = vec_add(b6v, b1v); \
-    /* DST(4,    b6 - b1); */ \
-    d4 = vec_sub(b6v, b1v); \
-    /* DST(5,    b4 - b3); */ \
-    d5 = vec_sub(b4v, b3v); \
-    /* DST(6,    b2 - b5); */ \
-    d6 = vec_sub(b2v, b5v); \
-    /* DST(7,    b0 - b7); */ \
-    d7 = vec_sub(b0v, b7v); \
-}
-
-#define ALTIVEC_STORE_SUM_CLIP(dest, idctv, perm_ldv, perm_stv, sel) { \
-    /* unaligned load */                                       \
-    vec_u8 hv = vec_ld( 0, dest );                           \
-    vec_u8 lv = vec_ld( 7, dest );                           \
-    vec_u8 dstv   = vec_perm( hv, lv, (vec_u8)perm_ldv );  \
-    vec_s16 idct_sh6 = vec_sra(idctv, sixv);                 \
-    vec_u16 dst16 = (vec_u16)vec_mergeh(zero_u8v, dstv);   \
-    vec_s16 idstsum = vec_adds(idct_sh6, (vec_s16)dst16);  \
-    vec_u8 idstsum8 = vec_packsu(zero_s16v, idstsum);        \
-    vec_u8 edgehv;                                           \
-    /* unaligned store */                                      \
-    vec_u8 bodyv  = vec_perm( idstsum8, idstsum8, perm_stv );\
-    vec_u8 edgelv = vec_perm( sel, zero_u8v, perm_stv );     \
-    lv    = vec_sel( lv, bodyv, edgelv );                      \
-    vec_st( lv, 7, dest );                                     \
-    hv    = vec_ld( 0, dest );                                 \
-    edgehv = vec_perm( zero_u8v, sel, perm_stv );              \
-    hv    = vec_sel( hv, bodyv, edgehv );                      \
-    vec_st( hv, 0, dest );                                     \
- }
-
-static void ff_h264_idct8_add_altivec( uint8_t *dst, DCTELEM *dct, int stride ) {
-    vec_s16 s0, s1, s2, s3, s4, s5, s6, s7;
-    vec_s16 d0, d1, d2, d3, d4, d5, d6, d7;
-    vec_s16 idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7;
-
-    vec_u8 perm_ldv = vec_lvsl(0, dst);
-    vec_u8 perm_stv = vec_lvsr(8, dst);
-
-    const vec_u16 onev = vec_splat_u16(1);
-    const vec_u16 twov = vec_splat_u16(2);
-    const vec_u16 sixv = vec_splat_u16(6);
-
-    const vec_u8 sel = (vec_u8) {0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1};
-    LOAD_ZERO;
-
-    dct[0] += 32; // rounding for the >>6 at the end
-
-    s0 = vec_ld(0x00, (int16_t*)dct);
-    s1 = vec_ld(0x10, (int16_t*)dct);
-    s2 = vec_ld(0x20, (int16_t*)dct);
-    s3 = vec_ld(0x30, (int16_t*)dct);
-    s4 = vec_ld(0x40, (int16_t*)dct);
-    s5 = vec_ld(0x50, (int16_t*)dct);
-    s6 = vec_ld(0x60, (int16_t*)dct);
-    s7 = vec_ld(0x70, (int16_t*)dct);
-
-    IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7,
-                     d0, d1, d2, d3, d4, d5, d6, d7);
-
-    TRANSPOSE8( d0,  d1,  d2,  d3,  d4,  d5,  d6, d7 );
-
-    IDCT8_1D_ALTIVEC(d0,  d1,  d2,  d3,  d4,  d5,  d6, d7,
-                     idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7);
-
-    ALTIVEC_STORE_SUM_CLIP(&dst[0*stride], idct0, perm_ldv, perm_stv, sel);
-    ALTIVEC_STORE_SUM_CLIP(&dst[1*stride], idct1, perm_ldv, perm_stv, sel);
-    ALTIVEC_STORE_SUM_CLIP(&dst[2*stride], idct2, perm_ldv, perm_stv, sel);
-    ALTIVEC_STORE_SUM_CLIP(&dst[3*stride], idct3, perm_ldv, perm_stv, sel);
-    ALTIVEC_STORE_SUM_CLIP(&dst[4*stride], idct4, perm_ldv, perm_stv, sel);
-    ALTIVEC_STORE_SUM_CLIP(&dst[5*stride], idct5, perm_ldv, perm_stv, sel);
-    ALTIVEC_STORE_SUM_CLIP(&dst[6*stride], idct6, perm_ldv, perm_stv, sel);
-    ALTIVEC_STORE_SUM_CLIP(&dst[7*stride], idct7, perm_ldv, perm_stv, sel);
-}
-
-static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, DCTELEM *block, int stride, int size)
-{
-    vec_s16 dc16;
-    vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner;
-    LOAD_ZERO;
-    DECLARE_ALIGNED(16, int, dc);
-    int i;
-
-    dc = (block[0] + 32) >> 6;
-    dc16 = vec_splat((vec_s16) vec_lde(0, &dc), 1);
-
-    if (size == 4)
-        dc16 = vec_sld(dc16, zero_s16v, 8);
-    dcplus = vec_packsu(dc16, zero_s16v);
-    dcminus = vec_packsu(vec_sub(zero_s16v, dc16), zero_s16v);
-
-    aligner = vec_lvsr(0, dst);
-    dcplus = vec_perm(dcplus, dcplus, aligner);
-    dcminus = vec_perm(dcminus, dcminus, aligner);
-
-    for (i = 0; i < size; i += 4) {
-        v0 = vec_ld(0, dst+0*stride);
-        v1 = vec_ld(0, dst+1*stride);
-        v2 = vec_ld(0, dst+2*stride);
-        v3 = vec_ld(0, dst+3*stride);
-
-        v0 = vec_adds(v0, dcplus);
-        v1 = vec_adds(v1, dcplus);
-        v2 = vec_adds(v2, dcplus);
-        v3 = vec_adds(v3, dcplus);
-
-        v0 = vec_subs(v0, dcminus);
-        v1 = vec_subs(v1, dcminus);
-        v2 = vec_subs(v2, dcminus);
-        v3 = vec_subs(v3, dcminus);
-
-        vec_st(v0, 0, dst+0*stride);
-        vec_st(v1, 0, dst+1*stride);
-        vec_st(v2, 0, dst+2*stride);
-        vec_st(v3, 0, dst+3*stride);
-
-        dst += 4*stride;
-    }
-}
-
-static void h264_idct_dc_add_altivec(uint8_t *dst, DCTELEM *block, int stride)
-{
-    h264_idct_dc_add_internal(dst, block, stride, 4);
-}
-
-static void ff_h264_idct8_dc_add_altivec(uint8_t *dst, DCTELEM *block, int stride)
-{
-    h264_idct_dc_add_internal(dst, block, stride, 8);
-}
-
-static void ff_h264_idct_add16_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
-    int i;
-    for(i=0; i<16; i++){
-        int nnz = nnzc[ scan8[i] ];
-        if(nnz){
-            if(nnz==1 && block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
-            else                      ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
-        }
-    }
-}
-
-static void ff_h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
-    int i;
-    for(i=0; i<16; i++){
-        if(nnzc[ scan8[i] ]) ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
-        else if(block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
-    }
-}
-
-static void ff_h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
-    int i;
-    for(i=0; i<16; i+=4){
-        int nnz = nnzc[ scan8[i] ];
-        if(nnz){
-            if(nnz==1 && block[i*16]) ff_h264_idct8_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
-            else                      ff_h264_idct8_add_altivec   (dst + block_offset[i], block + i*16, stride);
-        }
-    }
-}
-
-static void ff_h264_idct_add8_altivec(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
-    int i, j;
-    for (j = 1; j < 3; j++) {
-        for(i = j * 16; i < j * 16 + 4; i++){
-            if(nnzc[ scan8[i] ])
-                ff_h264_idct_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
-            else if(block[i*16])
-                h264_idct_dc_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
-        }
-    }
-}
-
-#define transpose4x16(r0, r1, r2, r3) {      \
-    register vec_u8 r4;                    \
-    register vec_u8 r5;                    \
-    register vec_u8 r6;                    \
-    register vec_u8 r7;                    \
-                                             \
-    r4 = vec_mergeh(r0, r2);  /*0, 2 set 0*/ \
-    r5 = vec_mergel(r0, r2);  /*0, 2 set 1*/ \
-    r6 = vec_mergeh(r1, r3);  /*1, 3 set 0*/ \
-    r7 = vec_mergel(r1, r3);  /*1, 3 set 1*/ \
-                                             \
-    r0 = vec_mergeh(r4, r6);  /*all set 0*/  \
-    r1 = vec_mergel(r4, r6);  /*all set 1*/  \
-    r2 = vec_mergeh(r5, r7);  /*all set 2*/  \
-    r3 = vec_mergel(r5, r7);  /*all set 3*/  \
-}
-
-static inline void write16x4(uint8_t *dst, int dst_stride,
-                             register vec_u8 r0, register vec_u8 r1,
-                             register vec_u8 r2, register vec_u8 r3) {
-    DECLARE_ALIGNED(16, unsigned char, result)[64];
-    uint32_t *src_int = (uint32_t *)result, *dst_int = (uint32_t *)dst;
-    int int_dst_stride = dst_stride/4;
-
-    vec_st(r0, 0, result);
-    vec_st(r1, 16, result);
-    vec_st(r2, 32, result);
-    vec_st(r3, 48, result);
-    /* FIXME: there has to be a better way!!!! */
-    *dst_int = *src_int;
-    *(dst_int+   int_dst_stride) = *(src_int + 1);
-    *(dst_int+ 2*int_dst_stride) = *(src_int + 2);
-    *(dst_int+ 3*int_dst_stride) = *(src_int + 3);
-    *(dst_int+ 4*int_dst_stride) = *(src_int + 4);
-    *(dst_int+ 5*int_dst_stride) = *(src_int + 5);
-    *(dst_int+ 6*int_dst_stride) = *(src_int + 6);
-    *(dst_int+ 7*int_dst_stride) = *(src_int + 7);
-    *(dst_int+ 8*int_dst_stride) = *(src_int + 8);
-    *(dst_int+ 9*int_dst_stride) = *(src_int + 9);
-    *(dst_int+10*int_dst_stride) = *(src_int + 10);
-    *(dst_int+11*int_dst_stride) = *(src_int + 11);
-    *(dst_int+12*int_dst_stride) = *(src_int + 12);
-    *(dst_int+13*int_dst_stride) = *(src_int + 13);
-    *(dst_int+14*int_dst_stride) = *(src_int + 14);
-    *(dst_int+15*int_dst_stride) = *(src_int + 15);
-}
-
-/** @brief performs a 6x16 transpose of data in src, and stores it to dst
-    @todo FIXME: see if we can't spare some vec_lvsl() by them factorizing
-    out of unaligned_load() */
-#define readAndTranspose16x6(src, src_stride, r8, r9, r10, r11, r12, r13) {\
-    register vec_u8 r0  = unaligned_load(0,             src);            \
-    register vec_u8 r1  = unaligned_load(   src_stride, src);            \
-    register vec_u8 r2  = unaligned_load(2* src_stride, src);            \
-    register vec_u8 r3  = unaligned_load(3* src_stride, src);            \
-    register vec_u8 r4  = unaligned_load(4* src_stride, src);            \
-    register vec_u8 r5  = unaligned_load(5* src_stride, src);            \
-    register vec_u8 r6  = unaligned_load(6* src_stride, src);            \
-    register vec_u8 r7  = unaligned_load(7* src_stride, src);            \
-    register vec_u8 r14 = unaligned_load(14*src_stride, src);            \
-    register vec_u8 r15 = unaligned_load(15*src_stride, src);            \
-                                                                           \
-    r8  = unaligned_load( 8*src_stride, src);                              \
-    r9  = unaligned_load( 9*src_stride, src);                              \
-    r10 = unaligned_load(10*src_stride, src);                              \
-    r11 = unaligned_load(11*src_stride, src);                              \
-    r12 = unaligned_load(12*src_stride, src);                              \
-    r13 = unaligned_load(13*src_stride, src);                              \
-                                                                           \
-    /*Merge first pairs*/                                                  \
-    r0 = vec_mergeh(r0, r8);    /*0, 8*/                                   \
-    r1 = vec_mergeh(r1, r9);    /*1, 9*/                                   \
-    r2 = vec_mergeh(r2, r10);   /*2,10*/                                   \
-    r3 = vec_mergeh(r3, r11);   /*3,11*/                                   \
-    r4 = vec_mergeh(r4, r12);   /*4,12*/                                   \
-    r5 = vec_mergeh(r5, r13);   /*5,13*/                                   \
-    r6 = vec_mergeh(r6, r14);   /*6,14*/                                   \
-    r7 = vec_mergeh(r7, r15);   /*7,15*/                                   \
-                                                                           \
-    /*Merge second pairs*/                                                 \
-    r8  = vec_mergeh(r0, r4);   /*0,4, 8,12 set 0*/                        \
-    r9  = vec_mergel(r0, r4);   /*0,4, 8,12 set 1*/                        \
-    r10 = vec_mergeh(r1, r5);   /*1,5, 9,13 set 0*/                        \
-    r11 = vec_mergel(r1, r5);   /*1,5, 9,13 set 1*/                        \
-    r12 = vec_mergeh(r2, r6);   /*2,6,10,14 set 0*/                        \
-    r13 = vec_mergel(r2, r6);   /*2,6,10,14 set 1*/                        \
-    r14 = vec_mergeh(r3, r7);   /*3,7,11,15 set 0*/                        \
-    r15 = vec_mergel(r3, r7);   /*3,7,11,15 set 1*/                        \
-                                                                           \
-    /*Third merge*/                                                        \
-    r0 = vec_mergeh(r8,  r12);  /*0,2,4,6,8,10,12,14 set 0*/               \
-    r1 = vec_mergel(r8,  r12);  /*0,2,4,6,8,10,12,14 set 1*/               \
-    r2 = vec_mergeh(r9,  r13);  /*0,2,4,6,8,10,12,14 set 2*/               \
-    r4 = vec_mergeh(r10, r14);  /*1,3,5,7,9,11,13,15 set 0*/               \
-    r5 = vec_mergel(r10, r14);  /*1,3,5,7,9,11,13,15 set 1*/               \
-    r6 = vec_mergeh(r11, r15);  /*1,3,5,7,9,11,13,15 set 2*/               \
-    /* Don't need to compute 3 and 7*/                                     \
-                                                                           \
-    /*Final merge*/                                                        \
-    r8  = vec_mergeh(r0, r4);   /*all set 0*/                              \
-    r9  = vec_mergel(r0, r4);   /*all set 1*/                              \
-    r10 = vec_mergeh(r1, r5);   /*all set 2*/                              \
-    r11 = vec_mergel(r1, r5);   /*all set 3*/                              \
-    r12 = vec_mergeh(r2, r6);   /*all set 4*/                              \
-    r13 = vec_mergel(r2, r6);   /*all set 5*/                              \
-    /* Don't need to compute 14 and 15*/                                   \
-                                                                           \
-}
-
-// out: o = |x-y| < a
-static inline vec_u8 diff_lt_altivec ( register vec_u8 x,
-                                         register vec_u8 y,
-                                         register vec_u8 a) {
-
-    register vec_u8 diff = vec_subs(x, y);
-    register vec_u8 diffneg = vec_subs(y, x);
-    register vec_u8 o = vec_or(diff, diffneg); /* |x-y| */
-    o = (vec_u8)vec_cmplt(o, a);
-    return o;
-}
-
-static inline vec_u8 h264_deblock_mask ( register vec_u8 p0,
-                                           register vec_u8 p1,
-                                           register vec_u8 q0,
-                                           register vec_u8 q1,
-                                           register vec_u8 alpha,
-                                           register vec_u8 beta) {
-
-    register vec_u8 mask;
-    register vec_u8 tempmask;
-
-    mask = diff_lt_altivec(p0, q0, alpha);
-    tempmask = diff_lt_altivec(p1, p0, beta);
-    mask = vec_and(mask, tempmask);
-    tempmask = diff_lt_altivec(q1, q0, beta);
-    mask = vec_and(mask, tempmask);
-
-    return mask;
-}
-
-// out: newp1 = clip((p2 + ((p0 + q0 + 1) >> 1)) >> 1, p1-tc0, p1+tc0)
-static inline vec_u8 h264_deblock_q1(register vec_u8 p0,
-                                       register vec_u8 p1,
-                                       register vec_u8 p2,
-                                       register vec_u8 q0,
-                                       register vec_u8 tc0) {
-
-    register vec_u8 average = vec_avg(p0, q0);
-    register vec_u8 temp;
-    register vec_u8 uncliped;
-    register vec_u8 ones;
-    register vec_u8 max;
-    register vec_u8 min;
-    register vec_u8 newp1;
-
-    temp = vec_xor(average, p2);
-    average = vec_avg(average, p2);     /*avg(p2, avg(p0, q0)) */
-    ones = vec_splat_u8(1);
-    temp = vec_and(temp, ones);         /*(p2^avg(p0, q0)) & 1 */
-    uncliped = vec_subs(average, temp); /*(p2+((p0+q0+1)>>1))>>1 */
-    max = vec_adds(p1, tc0);
-    min = vec_subs(p1, tc0);
-    newp1 = vec_max(min, uncliped);
-    newp1 = vec_min(max, newp1);
-    return newp1;
-}
-
-#define h264_deblock_p0_q0(p0, p1, q0, q1, tc0masked) {                                           \
-                                                                                                  \
-    const vec_u8 A0v = vec_sl(vec_splat_u8(10), vec_splat_u8(4));                               \
-                                                                                                  \
-    register vec_u8 pq0bit = vec_xor(p0,q0);                                                    \
-    register vec_u8 q1minus;                                                                    \
-    register vec_u8 p0minus;                                                                    \
-    register vec_u8 stage1;                                                                     \
-    register vec_u8 stage2;                                                                     \
-    register vec_u8 vec160;                                                                     \
-    register vec_u8 delta;                                                                      \
-    register vec_u8 deltaneg;                                                                   \
-                                                                                                  \
-    q1minus = vec_nor(q1, q1);                 /* 255 - q1 */                                     \
-    stage1 = vec_avg(p1, q1minus);             /* (p1 - q1 + 256)>>1 */                           \
-    stage2 = vec_sr(stage1, vec_splat_u8(1));  /* (p1 - q1 + 256)>>2 = 64 + (p1 - q1) >> 2 */     \
-    p0minus = vec_nor(p0, p0);                 /* 255 - p0 */                                     \
-    stage1 = vec_avg(q0, p0minus);             /* (q0 - p0 + 256)>>1 */                           \
-    pq0bit = vec_and(pq0bit, vec_splat_u8(1));                                                    \
-    stage2 = vec_avg(stage2, pq0bit);          /* 32 + ((q0 - p0)&1 + (p1 - q1) >> 2 + 1) >> 1 */ \
-    stage2 = vec_adds(stage2, stage1);         /* 160 + ((p0 - q0) + (p1 - q1) >> 2 + 1) >> 1 */  \
-    vec160 = vec_ld(0, &A0v);                                                                     \
-    deltaneg = vec_subs(vec160, stage2);       /* -d */                                           \
-    delta = vec_subs(stage2, vec160);          /* d */                                            \
-    deltaneg = vec_min(tc0masked, deltaneg);                                                      \
-    delta = vec_min(tc0masked, delta);                                                            \
-    p0 = vec_subs(p0, deltaneg);                                                                  \
-    q0 = vec_subs(q0, delta);                                                                     \
-    p0 = vec_adds(p0, delta);                                                                     \
-    q0 = vec_adds(q0, deltaneg);                                                                  \
-}
-
-#define h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0) {            \
-    DECLARE_ALIGNED(16, unsigned char, temp)[16];                                             \
-    register vec_u8 alphavec;                                                              \
-    register vec_u8 betavec;                                                               \
-    register vec_u8 mask;                                                                  \
-    register vec_u8 p1mask;                                                                \
-    register vec_u8 q1mask;                                                                \
-    register vector signed   char tc0vec;                                                    \
-    register vec_u8 finaltc0;                                                              \
-    register vec_u8 tc0masked;                                                             \
-    register vec_u8 newp1;                                                                 \
-    register vec_u8 newq1;                                                                 \
-                                                                                             \
-    temp[0] = alpha;                                                                         \
-    temp[1] = beta;                                                                          \
-    alphavec = vec_ld(0, temp);                                                              \
-    betavec = vec_splat(alphavec, 0x1);                                                      \
-    alphavec = vec_splat(alphavec, 0x0);                                                     \
-    mask = h264_deblock_mask(p0, p1, q0, q1, alphavec, betavec); /*if in block */            \
-                                                                                             \
-    AV_COPY32(temp, tc0);                                                                    \
-    tc0vec = vec_ld(0, (signed char*)temp);                                                  \
-    tc0vec = vec_mergeh(tc0vec, tc0vec);                                                     \
-    tc0vec = vec_mergeh(tc0vec, tc0vec);                                                     \
-    mask = vec_and(mask, vec_cmpgt(tc0vec, vec_splat_s8(-1)));  /* if tc0[i] >= 0 */         \
-    finaltc0 = vec_and((vec_u8)tc0vec, mask);     /* tc = tc0 */                           \
-                                                                                             \
-    p1mask = diff_lt_altivec(p2, p0, betavec);                                               \
-    p1mask = vec_and(p1mask, mask);                             /* if ( |p2 - p0| < beta) */ \
-    tc0masked = vec_and(p1mask, (vec_u8)tc0vec);                                           \
-    finaltc0 = vec_sub(finaltc0, p1mask);                       /* tc++ */                   \
-    newp1 = h264_deblock_q1(p0, p1, p2, q0, tc0masked);                                      \
-    /*end if*/                                                                               \
-                                                                                             \
-    q1mask = diff_lt_altivec(q2, q0, betavec);                                               \
-    q1mask = vec_and(q1mask, mask);                             /* if ( |q2 - q0| < beta ) */\
-    tc0masked = vec_and(q1mask, (vec_u8)tc0vec);                                           \
-    finaltc0 = vec_sub(finaltc0, q1mask);                       /* tc++ */                   \
-    newq1 = h264_deblock_q1(p0, q1, q2, q0, tc0masked);                                      \
-    /*end if*/                                                                               \
-                                                                                             \
-    h264_deblock_p0_q0(p0, p1, q0, q1, finaltc0);                                            \
-    p1 = newp1;                                                                              \
-    q1 = newq1;                                                                              \
-}
-
-static void h264_v_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) {
-
-    if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) >= 0) {
-        register vec_u8 p2 = vec_ld(-3*stride, pix);
-        register vec_u8 p1 = vec_ld(-2*stride, pix);
-        register vec_u8 p0 = vec_ld(-1*stride, pix);
-        register vec_u8 q0 = vec_ld(0, pix);
-        register vec_u8 q1 = vec_ld(stride, pix);
-        register vec_u8 q2 = vec_ld(2*stride, pix);
-        h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0);
-        vec_st(p1, -2*stride, pix);
-        vec_st(p0, -1*stride, pix);
-        vec_st(q0, 0, pix);
-        vec_st(q1, stride, pix);
-    }
-}
-
-static void h264_h_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) {
-
-    register vec_u8 line0, line1, line2, line3, line4, line5;
-    if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) < 0)
-        return;
-    readAndTranspose16x6(pix-3, stride, line0, line1, line2, line3, line4, line5);
-    h264_loop_filter_luma_altivec(line0, line1, line2, line3, line4, line5, alpha, beta, tc0);
-    transpose4x16(line1, line2, line3, line4);
-    write16x4(pix-2, stride, line1, line2, line3, line4);
-}
-
-static av_always_inline
-void weight_h264_W_altivec(uint8_t *block, int stride, int height,
-                           int log2_denom, int weight, int offset, int w)
-{
-    int y, aligned;
-    vec_u8 vblock;
-    vec_s16 vtemp, vweight, voffset, v0, v1;
-    vec_u16 vlog2_denom;
-    DECLARE_ALIGNED(16, int32_t, temp)[4];
-    LOAD_ZERO;
-
-    offset <<= log2_denom;
-    if(log2_denom) offset += 1<<(log2_denom-1);
-    temp[0] = log2_denom;
-    temp[1] = weight;
-    temp[2] = offset;
-
-    vtemp = (vec_s16)vec_ld(0, temp);
-    vlog2_denom = (vec_u16)vec_splat(vtemp, 1);
-    vweight = vec_splat(vtemp, 3);
-    voffset = vec_splat(vtemp, 5);
-    aligned = !((unsigned long)block & 0xf);
-
-    for (y = 0; y < height; y++) {
-        vblock = vec_ld(0, block);
-
-        v0 = (vec_s16)vec_mergeh(zero_u8v, vblock);
-        v1 = (vec_s16)vec_mergel(zero_u8v, vblock);
-
-        if (w == 16 || aligned) {
-            v0 = vec_mladd(v0, vweight, zero_s16v);
-            v0 = vec_adds(v0, voffset);
-            v0 = vec_sra(v0, vlog2_denom);
-        }
-        if (w == 16 || !aligned) {
-            v1 = vec_mladd(v1, vweight, zero_s16v);
-            v1 = vec_adds(v1, voffset);
-            v1 = vec_sra(v1, vlog2_denom);
-        }
-        vblock = vec_packsu(v0, v1);
-        vec_st(vblock, 0, block);
-
-        block += stride;
-    }
-}
-
-static av_always_inline
-void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height,
-                             int log2_denom, int weightd, int weights, int offset, int w)
-{
-    int y, dst_aligned, src_aligned;
-    vec_u8 vsrc, vdst;
-    vec_s16 vtemp, vweights, vweightd, voffset, v0, v1, v2, v3;
-    vec_u16 vlog2_denom;
-    DECLARE_ALIGNED(16, int32_t, temp)[4];
-    LOAD_ZERO;
-
-    offset = ((offset + 1) | 1) << log2_denom;
-    temp[0] = log2_denom+1;
-    temp[1] = weights;
-    temp[2] = weightd;
-    temp[3] = offset;
-
-    vtemp = (vec_s16)vec_ld(0, temp);
-    vlog2_denom = (vec_u16)vec_splat(vtemp, 1);
-    vweights = vec_splat(vtemp, 3);
-    vweightd = vec_splat(vtemp, 5);
-    voffset = vec_splat(vtemp, 7);
-    dst_aligned = !((unsigned long)dst & 0xf);
-    src_aligned = !((unsigned long)src & 0xf);
-
-    for (y = 0; y < height; y++) {
-        vdst = vec_ld(0, dst);
-        vsrc = vec_ld(0, src);
-
-        v0 = (vec_s16)vec_mergeh(zero_u8v, vdst);
-        v1 = (vec_s16)vec_mergel(zero_u8v, vdst);
-        v2 = (vec_s16)vec_mergeh(zero_u8v, vsrc);
-        v3 = (vec_s16)vec_mergel(zero_u8v, vsrc);
-
-        if (w == 8) {
-            if (src_aligned)
-                v3 = v2;
-            else
-                v2 = v3;
-        }
-
-        if (w == 16 || dst_aligned) {
-            v0 = vec_mladd(v0, vweightd, zero_s16v);
-            v2 = vec_mladd(v2, vweights, zero_s16v);
-
-            v0 = vec_adds(v0, voffset);
-            v0 = vec_adds(v0, v2);
-            v0 = vec_sra(v0, vlog2_denom);
-        }
-        if (w == 16 || !dst_aligned) {
-            v1 = vec_mladd(v1, vweightd, zero_s16v);
-            v3 = vec_mladd(v3, vweights, zero_s16v);
-
-            v1 = vec_adds(v1, voffset);
-            v1 = vec_adds(v1, v3);
-            v1 = vec_sra(v1, vlog2_denom);
-        }
-        vdst = vec_packsu(v0, v1);
-        vec_st(vdst, 0, dst);
-
-        dst += stride;
-        src += stride;
-    }
-}
-
-#define H264_WEIGHT(W) \
-static void ff_weight_h264_pixels ## W ## _altivec(uint8_t *block, int stride, int height, \
-                                                   int log2_denom, int weight, int offset){ \
-    weight_h264_W_altivec(block, stride, height, log2_denom, weight, offset, W); \
-}\
-static void ff_biweight_h264_pixels ## W ## _altivec(uint8_t *dst, uint8_t *src, int stride, int height, \
-                                                     int log2_denom, int weightd, int weights, int offset){ \
-    biweight_h264_W_altivec(dst, src, stride, height, log2_denom, weightd, weights, offset, W); \
-}
-
-H264_WEIGHT(16)
-H264_WEIGHT( 8)
-
-void ff_dsputil_h264_init_ppc(DSPContext* c, AVCodecContext *avctx) {
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
-    if (!high_bit_depth) {
-        c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec;
-        c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec;
-
-#define dspfunc(PFX, IDX, NUM) \
-        c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \
-        c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \
-        c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \
-        c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \
-        c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \
-        c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \
-        c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \
-        c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec
-
-        dspfunc(put_h264_qpel, 0, 16);
-        dspfunc(avg_h264_qpel, 0, 16);
-#undef dspfunc
-    }
-    }
-}
-
-void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
-{
-    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
-    if (bit_depth == 8) {
-        c->h264_idct_add = ff_h264_idct_add_altivec;
-        if (chroma_format_idc == 1)
-            c->h264_idct_add8 = ff_h264_idct_add8_altivec;
-        c->h264_idct_add16 = ff_h264_idct_add16_altivec;
-        c->h264_idct_add16intra = ff_h264_idct_add16intra_altivec;
-        c->h264_idct_dc_add= h264_idct_dc_add_altivec;
-        c->h264_idct8_dc_add = ff_h264_idct8_dc_add_altivec;
-        c->h264_idct8_add = ff_h264_idct8_add_altivec;
-        c->h264_idct8_add4 = ff_h264_idct8_add4_altivec;
-        c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_altivec;
-        c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_altivec;
-
-        c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels16_altivec;
-        c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels8_altivec;
-        c->biweight_h264_pixels_tab[0] = ff_biweight_h264_pixels16_altivec;
-        c->biweight_h264_pixels_tab[1] = ff_biweight_h264_pixels8_altivec;
-    }
-    }
-}
diff --git a/libavcodec/ppc/h264_altivec_template.c b/libavcodec/ppc/h264_altivec_template.c
deleted file mode 100644
index b445f92..0000000
--- a/libavcodec/ppc/h264_altivec_template.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/*
- * Copyright (c) 2004 Romain Dolbeau <romain at dolbeau.org>
- *
- * 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/mem.h"
-
-#ifdef DEBUG
-#define ASSERT_ALIGNED(ptr) assert(((unsigned long)ptr&0x0000000F));
-#else
-#define ASSERT_ALIGNED(ptr) ;
-#endif
-
-/* this code assume that stride % 16 == 0 */
-
-#define CHROMA_MC8_ALTIVEC_CORE(BIAS1, BIAS2) \
-        vsrc2ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc2uc);\
-        vsrc3ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc3uc);\
-\
-        psum = vec_mladd(vA, vsrc0ssH, BIAS1);\
-        psum = vec_mladd(vB, vsrc1ssH, psum);\
-        psum = vec_mladd(vC, vsrc2ssH, psum);\
-        psum = vec_mladd(vD, vsrc3ssH, psum);\
-        psum = BIAS2(psum);\
-        psum = vec_sr(psum, v6us);\
-\
-        vdst = vec_ld(0, dst);\
-        ppsum = (vec_u8)vec_pack(psum, psum);\
-        vfdst = vec_perm(vdst, ppsum, fperm);\
-\
-        OP_U8_ALTIVEC(fsum, vfdst, vdst);\
-\
-        vec_st(fsum, 0, dst);\
-\
-        vsrc0ssH = vsrc2ssH;\
-        vsrc1ssH = vsrc3ssH;\
-\
-        dst += stride;\
-        src += stride;
-
-#define CHROMA_MC8_ALTIVEC_CORE_SIMPLE \
-\
-        vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);\
-        vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);\
-\
-        psum = vec_mladd(vA, vsrc0ssH, v32ss);\
-        psum = vec_mladd(vE, vsrc1ssH, psum);\
-        psum = vec_sr(psum, v6us);\
-\
-        vdst = vec_ld(0, dst);\
-        ppsum = (vec_u8)vec_pack(psum, psum);\
-        vfdst = vec_perm(vdst, ppsum, fperm);\
-\
-        OP_U8_ALTIVEC(fsum, vfdst, vdst);\
-\
-        vec_st(fsum, 0, dst);\
-\
-        dst += stride;\
-        src += stride;
-
-#define noop(a) a
-#define add28(a) vec_add(v28ss, a)
-
-#ifdef PREFIX_h264_chroma_mc8_altivec
-static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src,
-                                    int stride, int h, int x, int y) {
-    DECLARE_ALIGNED(16, signed int, ABCD)[4] =
-                        {((8 - x) * (8 - y)),
-                         ((    x) * (8 - y)),
-                         ((8 - x) * (    y)),
-                         ((    x) * (    y))};
-    register int i;
-    vec_u8 fperm;
-    const vec_s32 vABCD = vec_ld(0, ABCD);
-    const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
-    const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
-    const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
-    const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
-    LOAD_ZERO;
-    const vec_s16 v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5));
-    const vec_u16 v6us = vec_splat_u16(6);
-    register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
-    register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
-
-    vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
-    vec_u8 vsrc0uc, vsrc1uc;
-    vec_s16 vsrc0ssH, vsrc1ssH;
-    vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
-    vec_s16 vsrc2ssH, vsrc3ssH, psum;
-    vec_u8 vdst, ppsum, vfdst, fsum;
-
-    if (((unsigned long)dst) % 16 == 0) {
-        fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
-                         0x14, 0x15, 0x16, 0x17,
-                         0x08, 0x09, 0x0A, 0x0B,
-                         0x0C, 0x0D, 0x0E, 0x0F};
-    } else {
-        fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
-                         0x04, 0x05, 0x06, 0x07,
-                         0x18, 0x19, 0x1A, 0x1B,
-                         0x1C, 0x1D, 0x1E, 0x1F};
-    }
-
-    vsrcAuc = vec_ld(0, src);
-
-    if (loadSecond)
-        vsrcBuc = vec_ld(16, src);
-    vsrcperm0 = vec_lvsl(0, src);
-    vsrcperm1 = vec_lvsl(1, src);
-
-    vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
-    if (reallyBadAlign)
-        vsrc1uc = vsrcBuc;
-    else
-        vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
-
-    vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);
-    vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);
-
-    if (ABCD[3]) {
-        if (!loadSecond) {// -> !reallyBadAlign
-            for (i = 0 ; i < h ; i++) {
-                vsrcCuc = vec_ld(stride + 0, src);
-                vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
-                vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
-
-                CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
-            }
-        } else {
-            vec_u8 vsrcDuc;
-            for (i = 0 ; i < h ; i++) {
-                vsrcCuc = vec_ld(stride + 0, src);
-                vsrcDuc = vec_ld(stride + 16, src);
-                vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
-                if (reallyBadAlign)
-                    vsrc3uc = vsrcDuc;
-                else
-                    vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
-                CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
-            }
-        }
-    } else {
-        const vec_s16 vE = vec_add(vB, vC);
-        if (ABCD[2]) { // x == 0 B == 0
-            if (!loadSecond) {// -> !reallyBadAlign
-                for (i = 0 ; i < h ; i++) {
-                    vsrcCuc = vec_ld(stride + 0, src);
-                    vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
-                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-
-                    vsrc0uc = vsrc1uc;
-                }
-            } else {
-                vec_u8 vsrcDuc;
-                for (i = 0 ; i < h ; i++) {
-                    vsrcCuc = vec_ld(stride + 0, src);
-                    vsrcDuc = vec_ld(stride + 15, src);
-                    vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
-                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-
-                    vsrc0uc = vsrc1uc;
-                }
-            }
-        } else { // y == 0 C == 0
-            if (!loadSecond) {// -> !reallyBadAlign
-                for (i = 0 ; i < h ; i++) {
-                    vsrcCuc = vec_ld(0, src);
-                    vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
-                    vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
-
-                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-                }
-            } else {
-                vec_u8 vsrcDuc;
-                for (i = 0 ; i < h ; i++) {
-                    vsrcCuc = vec_ld(0, src);
-                    vsrcDuc = vec_ld(15, src);
-                    vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
-                    if (reallyBadAlign)
-                        vsrc1uc = vsrcDuc;
-                    else
-                        vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
-                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
-                }
-            }
-        }
-    }
-}
-#endif
-
-/* this code assume that stride % 16 == 0 */
-#ifdef PREFIX_no_rnd_vc1_chroma_mc8_altivec
-static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) {
-   DECLARE_ALIGNED(16, signed int, ABCD)[4] =
-                        {((8 - x) * (8 - y)),
-                         ((    x) * (8 - y)),
-                         ((8 - x) * (    y)),
-                         ((    x) * (    y))};
-    register int i;
-    vec_u8 fperm;
-    const vec_s32 vABCD = vec_ld(0, ABCD);
-    const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
-    const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
-    const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
-    const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
-    LOAD_ZERO;
-    const vec_s16 v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4));
-    const vec_u16 v6us  = vec_splat_u16(6);
-    register int loadSecond     = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
-    register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
-
-    vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
-    vec_u8 vsrc0uc, vsrc1uc;
-    vec_s16 vsrc0ssH, vsrc1ssH;
-    vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
-    vec_s16 vsrc2ssH, vsrc3ssH, psum;
-    vec_u8 vdst, ppsum, vfdst, fsum;
-
-    if (((unsigned long)dst) % 16 == 0) {
-        fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
-                         0x14, 0x15, 0x16, 0x17,
-                         0x08, 0x09, 0x0A, 0x0B,
-                         0x0C, 0x0D, 0x0E, 0x0F};
-    } else {
-        fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
-                         0x04, 0x05, 0x06, 0x07,
-                         0x18, 0x19, 0x1A, 0x1B,
-                         0x1C, 0x1D, 0x1E, 0x1F};
-    }
-
-    vsrcAuc = vec_ld(0, src);
-
-    if (loadSecond)
-        vsrcBuc = vec_ld(16, src);
-    vsrcperm0 = vec_lvsl(0, src);
-    vsrcperm1 = vec_lvsl(1, src);
-
-    vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
-    if (reallyBadAlign)
-        vsrc1uc = vsrcBuc;
-    else
-        vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
-
-    vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc0uc);
-    vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc1uc);
-
-    if (!loadSecond) {// -> !reallyBadAlign
-        for (i = 0 ; i < h ; i++) {
-
-
-            vsrcCuc = vec_ld(stride + 0, src);
-
-            vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
-            vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
-
-            CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
-        }
-    } else {
-        vec_u8 vsrcDuc;
-        for (i = 0 ; i < h ; i++) {
-            vsrcCuc = vec_ld(stride + 0, src);
-            vsrcDuc = vec_ld(stride + 16, src);
-
-            vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
-            if (reallyBadAlign)
-                vsrc3uc = vsrcDuc;
-            else
-                vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
-
-            CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
-        }
-    }
-}
-#endif
-
-#undef noop
-#undef add28
-#undef CHROMA_MC8_ALTIVEC_CORE
-
-/* this code assume stride % 16 == 0 */
-#ifdef PREFIX_h264_qpel16_h_lowpass_altivec
-static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) {
-    register int i;
-
-    LOAD_ZERO;
-    const vec_u8 permM2 = vec_lvsl(-2, src);
-    const vec_u8 permM1 = vec_lvsl(-1, src);
-    const vec_u8 permP0 = vec_lvsl(+0, src);
-    const vec_u8 permP1 = vec_lvsl(+1, src);
-    const vec_u8 permP2 = vec_lvsl(+2, src);
-    const vec_u8 permP3 = vec_lvsl(+3, src);
-    const vec_s16 v5ss = vec_splat_s16(5);
-    const vec_u16 v5us = vec_splat_u16(5);
-    const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
-    const vec_s16 v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4));
-
-    vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3;
-
-    register int align = ((((unsigned long)src) - 2) % 16);
-
-    vec_s16 srcP0A, srcP0B, srcP1A, srcP1B,
-              srcP2A, srcP2B, srcP3A, srcP3B,
-              srcM1A, srcM1B, srcM2A, srcM2B,
-              sum1A, sum1B, sum2A, sum2B, sum3A, sum3B,
-              pp1A, pp1B, pp2A, pp2B, pp3A, pp3B,
-              psumA, psumB, sumA, sumB;
-
-    vec_u8 sum, fsum;
-
-    for (i = 0 ; i < 16 ; i ++) {
-        vec_u8 srcR1 = vec_ld(-2, src);
-        vec_u8 srcR2 = vec_ld(14, src);
-
-        switch (align) {
-        default: {
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = vec_perm(srcR1, srcR2, permP0);
-            srcP1 = vec_perm(srcR1, srcR2, permP1);
-            srcP2 = vec_perm(srcR1, srcR2, permP2);
-            srcP3 = vec_perm(srcR1, srcR2, permP3);
-        } break;
-        case 11: {
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = vec_perm(srcR1, srcR2, permP0);
-            srcP1 = vec_perm(srcR1, srcR2, permP1);
-            srcP2 = vec_perm(srcR1, srcR2, permP2);
-            srcP3 = srcR2;
-        } break;
-        case 12: {
-            vec_u8 srcR3 = vec_ld(30, src);
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = vec_perm(srcR1, srcR2, permP0);
-            srcP1 = vec_perm(srcR1, srcR2, permP1);
-            srcP2 = srcR2;
-            srcP3 = vec_perm(srcR2, srcR3, permP3);
-        } break;
-        case 13: {
-            vec_u8 srcR3 = vec_ld(30, src);
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = vec_perm(srcR1, srcR2, permP0);
-            srcP1 = srcR2;
-            srcP2 = vec_perm(srcR2, srcR3, permP2);
-            srcP3 = vec_perm(srcR2, srcR3, permP3);
-        } break;
-        case 14: {
-            vec_u8 srcR3 = vec_ld(30, src);
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = srcR2;
-            srcP1 = vec_perm(srcR2, srcR3, permP1);
-            srcP2 = vec_perm(srcR2, srcR3, permP2);
-            srcP3 = vec_perm(srcR2, srcR3, permP3);
-        } break;
-        case 15: {
-            vec_u8 srcR3 = vec_ld(30, src);
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = srcR2;
-            srcP0 = vec_perm(srcR2, srcR3, permP0);
-            srcP1 = vec_perm(srcR2, srcR3, permP1);
-            srcP2 = vec_perm(srcR2, srcR3, permP2);
-            srcP3 = vec_perm(srcR2, srcR3, permP3);
-        } break;
-        }
-
-        srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0);
-        srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0);
-        srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1);
-        srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1);
-
-        srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2);
-        srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2);
-        srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3);
-        srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3);
-
-        srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1);
-        srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1);
-        srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2);
-        srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2);
-
-        sum1A = vec_adds(srcP0A, srcP1A);
-        sum1B = vec_adds(srcP0B, srcP1B);
-        sum2A = vec_adds(srcM1A, srcP2A);
-        sum2B = vec_adds(srcM1B, srcP2B);
-        sum3A = vec_adds(srcM2A, srcP3A);
-        sum3B = vec_adds(srcM2B, srcP3B);
-
-        pp1A = vec_mladd(sum1A, v20ss, v16ss);
-        pp1B = vec_mladd(sum1B, v20ss, v16ss);
-
-        pp2A = vec_mladd(sum2A, v5ss, zero_s16v);
-        pp2B = vec_mladd(sum2B, v5ss, zero_s16v);
-
-        pp3A = vec_add(sum3A, pp1A);
-        pp3B = vec_add(sum3B, pp1B);
-
-        psumA = vec_sub(pp3A, pp2A);
-        psumB = vec_sub(pp3B, pp2B);
-
-        sumA = vec_sra(psumA, v5us);
-        sumB = vec_sra(psumB, v5us);
-
-        sum = vec_packsu(sumA, sumB);
-
-        ASSERT_ALIGNED(dst);
-
-        OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst));
-
-        vec_st(fsum, 0, dst);
-
-        src += srcStride;
-        dst += dstStride;
-    }
-}
-#endif
-
-/* this code assume stride % 16 == 0 */
-#ifdef PREFIX_h264_qpel16_v_lowpass_altivec
-static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) {
-    register int i;
-
-    LOAD_ZERO;
-    const vec_u8 perm = vec_lvsl(0, src);
-    const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
-    const vec_u16 v5us = vec_splat_u16(5);
-    const vec_s16 v5ss = vec_splat_s16(5);
-    const vec_s16 v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4));
-
-    uint8_t *srcbis = src - (srcStride * 2);
-
-    const vec_u8 srcM2a = vec_ld(0, srcbis);
-    const vec_u8 srcM2b = vec_ld(16, srcbis);
-    const vec_u8 srcM2 = vec_perm(srcM2a, srcM2b, perm);
-    //srcbis += srcStride;
-    const vec_u8 srcM1a = vec_ld(0, srcbis += srcStride);
-    const vec_u8 srcM1b = vec_ld(16, srcbis);
-    const vec_u8 srcM1 = vec_perm(srcM1a, srcM1b, perm);
-    //srcbis += srcStride;
-    const vec_u8 srcP0a = vec_ld(0, srcbis += srcStride);
-    const vec_u8 srcP0b = vec_ld(16, srcbis);
-    const vec_u8 srcP0 = vec_perm(srcP0a, srcP0b, perm);
-    //srcbis += srcStride;
-    const vec_u8 srcP1a = vec_ld(0, srcbis += srcStride);
-    const vec_u8 srcP1b = vec_ld(16, srcbis);
-    const vec_u8 srcP1 = vec_perm(srcP1a, srcP1b, perm);
-    //srcbis += srcStride;
-    const vec_u8 srcP2a = vec_ld(0, srcbis += srcStride);
-    const vec_u8 srcP2b = vec_ld(16, srcbis);
-    const vec_u8 srcP2 = vec_perm(srcP2a, srcP2b, perm);
-    //srcbis += srcStride;
-
-    vec_s16 srcM2ssA = (vec_s16) vec_mergeh(zero_u8v, srcM2);
-    vec_s16 srcM2ssB = (vec_s16) vec_mergel(zero_u8v, srcM2);
-    vec_s16 srcM1ssA = (vec_s16) vec_mergeh(zero_u8v, srcM1);
-    vec_s16 srcM1ssB = (vec_s16) vec_mergel(zero_u8v, srcM1);
-    vec_s16 srcP0ssA = (vec_s16) vec_mergeh(zero_u8v, srcP0);
-    vec_s16 srcP0ssB = (vec_s16) vec_mergel(zero_u8v, srcP0);
-    vec_s16 srcP1ssA = (vec_s16) vec_mergeh(zero_u8v, srcP1);
-    vec_s16 srcP1ssB = (vec_s16) vec_mergel(zero_u8v, srcP1);
-    vec_s16 srcP2ssA = (vec_s16) vec_mergeh(zero_u8v, srcP2);
-    vec_s16 srcP2ssB = (vec_s16) vec_mergel(zero_u8v, srcP2);
-
-    vec_s16 pp1A, pp1B, pp2A, pp2B, pp3A, pp3B,
-              psumA, psumB, sumA, sumB,
-              srcP3ssA, srcP3ssB,
-              sum1A, sum1B, sum2A, sum2B, sum3A, sum3B;
-
-    vec_u8 sum, fsum, srcP3a, srcP3b, srcP3;
-
-    for (i = 0 ; i < 16 ; i++) {
-        srcP3a = vec_ld(0, srcbis += srcStride);
-        srcP3b = vec_ld(16, srcbis);
-        srcP3 = vec_perm(srcP3a, srcP3b, perm);
-        srcP3ssA = (vec_s16) vec_mergeh(zero_u8v, srcP3);
-        srcP3ssB = (vec_s16) vec_mergel(zero_u8v, srcP3);
-        //srcbis += srcStride;
-
-        sum1A = vec_adds(srcP0ssA, srcP1ssA);
-        sum1B = vec_adds(srcP0ssB, srcP1ssB);
-        sum2A = vec_adds(srcM1ssA, srcP2ssA);
-        sum2B = vec_adds(srcM1ssB, srcP2ssB);
-        sum3A = vec_adds(srcM2ssA, srcP3ssA);
-        sum3B = vec_adds(srcM2ssB, srcP3ssB);
-
-        srcM2ssA = srcM1ssA;
-        srcM2ssB = srcM1ssB;
-        srcM1ssA = srcP0ssA;
-        srcM1ssB = srcP0ssB;
-        srcP0ssA = srcP1ssA;
-        srcP0ssB = srcP1ssB;
-        srcP1ssA = srcP2ssA;
-        srcP1ssB = srcP2ssB;
-        srcP2ssA = srcP3ssA;
-        srcP2ssB = srcP3ssB;
-
-        pp1A = vec_mladd(sum1A, v20ss, v16ss);
-        pp1B = vec_mladd(sum1B, v20ss, v16ss);
-
-        pp2A = vec_mladd(sum2A, v5ss, zero_s16v);
-        pp2B = vec_mladd(sum2B, v5ss, zero_s16v);
-
-        pp3A = vec_add(sum3A, pp1A);
-        pp3B = vec_add(sum3B, pp1B);
-
-        psumA = vec_sub(pp3A, pp2A);
-        psumB = vec_sub(pp3B, pp2B);
-
-        sumA = vec_sra(psumA, v5us);
-        sumB = vec_sra(psumB, v5us);
-
-        sum = vec_packsu(sumA, sumB);
-
-        ASSERT_ALIGNED(dst);
-
-        OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst));
-
-        vec_st(fsum, 0, dst);
-
-        dst += dstStride;
-    }
-}
-#endif
-
-/* this code assume stride % 16 == 0 *and* tmp is properly aligned */
-#ifdef PREFIX_h264_qpel16_hv_lowpass_altivec
-static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, uint8_t * src, int dstStride, int tmpStride, int srcStride) {
-    register int i;
-    LOAD_ZERO;
-    const vec_u8 permM2 = vec_lvsl(-2, src);
-    const vec_u8 permM1 = vec_lvsl(-1, src);
-    const vec_u8 permP0 = vec_lvsl(+0, src);
-    const vec_u8 permP1 = vec_lvsl(+1, src);
-    const vec_u8 permP2 = vec_lvsl(+2, src);
-    const vec_u8 permP3 = vec_lvsl(+3, src);
-    const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
-    const vec_u32 v10ui = vec_splat_u32(10);
-    const vec_s16 v5ss = vec_splat_s16(5);
-    const vec_s16 v1ss = vec_splat_s16(1);
-    const vec_s32 v512si = vec_sl(vec_splat_s32(1),vec_splat_u32(9));
-    const vec_u32 v16ui = vec_sl(vec_splat_u32(1),vec_splat_u32(4));
-
-    register int align = ((((unsigned long)src) - 2) % 16);
-
-    vec_s16 srcP0A, srcP0B, srcP1A, srcP1B,
-              srcP2A, srcP2B, srcP3A, srcP3B,
-              srcM1A, srcM1B, srcM2A, srcM2B,
-              sum1A, sum1B, sum2A, sum2B, sum3A, sum3B,
-              pp1A, pp1B, pp2A, pp2B, psumA, psumB;
-
-    const vec_u8 mperm = (const vec_u8)
-        {0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B,
-         0x04, 0x0C, 0x05, 0x0D, 0x06, 0x0E, 0x07, 0x0F};
-    int16_t *tmpbis = tmp;
-
-    vec_s16 tmpM1ssA, tmpM1ssB, tmpM2ssA, tmpM2ssB,
-              tmpP0ssA, tmpP0ssB, tmpP1ssA, tmpP1ssB,
-              tmpP2ssA, tmpP2ssB;
-
-    vec_s32 pp1Ae, pp1Ao, pp1Be, pp1Bo, pp2Ae, pp2Ao, pp2Be, pp2Bo,
-              pp3Ae, pp3Ao, pp3Be, pp3Bo, pp1cAe, pp1cAo, pp1cBe, pp1cBo,
-              pp32Ae, pp32Ao, pp32Be, pp32Bo, sumAe, sumAo, sumBe, sumBo,
-              ssumAe, ssumAo, ssumBe, ssumBo;
-    vec_u8 fsum, sumv, sum;
-    vec_s16 ssume, ssumo;
-
-    src -= (2 * srcStride);
-    for (i = 0 ; i < 21 ; i ++) {
-        vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3;
-        vec_u8 srcR1 = vec_ld(-2, src);
-        vec_u8 srcR2 = vec_ld(14, src);
-
-        switch (align) {
-        default: {
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = vec_perm(srcR1, srcR2, permP0);
-            srcP1 = vec_perm(srcR1, srcR2, permP1);
-            srcP2 = vec_perm(srcR1, srcR2, permP2);
-            srcP3 = vec_perm(srcR1, srcR2, permP3);
-        } break;
-        case 11: {
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = vec_perm(srcR1, srcR2, permP0);
-            srcP1 = vec_perm(srcR1, srcR2, permP1);
-            srcP2 = vec_perm(srcR1, srcR2, permP2);
-            srcP3 = srcR2;
-        } break;
-        case 12: {
-            vec_u8 srcR3 = vec_ld(30, src);
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = vec_perm(srcR1, srcR2, permP0);
-            srcP1 = vec_perm(srcR1, srcR2, permP1);
-            srcP2 = srcR2;
-            srcP3 = vec_perm(srcR2, srcR3, permP3);
-        } break;
-        case 13: {
-            vec_u8 srcR3 = vec_ld(30, src);
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = vec_perm(srcR1, srcR2, permP0);
-            srcP1 = srcR2;
-            srcP2 = vec_perm(srcR2, srcR3, permP2);
-            srcP3 = vec_perm(srcR2, srcR3, permP3);
-        } break;
-        case 14: {
-            vec_u8 srcR3 = vec_ld(30, src);
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = vec_perm(srcR1, srcR2, permM1);
-            srcP0 = srcR2;
-            srcP1 = vec_perm(srcR2, srcR3, permP1);
-            srcP2 = vec_perm(srcR2, srcR3, permP2);
-            srcP3 = vec_perm(srcR2, srcR3, permP3);
-        } break;
-        case 15: {
-            vec_u8 srcR3 = vec_ld(30, src);
-            srcM2 = vec_perm(srcR1, srcR2, permM2);
-            srcM1 = srcR2;
-            srcP0 = vec_perm(srcR2, srcR3, permP0);
-            srcP1 = vec_perm(srcR2, srcR3, permP1);
-            srcP2 = vec_perm(srcR2, srcR3, permP2);
-            srcP3 = vec_perm(srcR2, srcR3, permP3);
-        } break;
-        }
-
-        srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0);
-        srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0);
-        srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1);
-        srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1);
-
-        srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2);
-        srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2);
-        srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3);
-        srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3);
-
-        srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1);
-        srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1);
-        srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2);
-        srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2);
-
-        sum1A = vec_adds(srcP0A, srcP1A);
-        sum1B = vec_adds(srcP0B, srcP1B);
-        sum2A = vec_adds(srcM1A, srcP2A);
-        sum2B = vec_adds(srcM1B, srcP2B);
-        sum3A = vec_adds(srcM2A, srcP3A);
-        sum3B = vec_adds(srcM2B, srcP3B);
-
-        pp1A = vec_mladd(sum1A, v20ss, sum3A);
-        pp1B = vec_mladd(sum1B, v20ss, sum3B);
-
-        pp2A = vec_mladd(sum2A, v5ss, zero_s16v);
-        pp2B = vec_mladd(sum2B, v5ss, zero_s16v);
-
-        psumA = vec_sub(pp1A, pp2A);
-        psumB = vec_sub(pp1B, pp2B);
-
-        vec_st(psumA, 0, tmp);
-        vec_st(psumB, 16, tmp);
-
-        src += srcStride;
-        tmp += tmpStride; /* int16_t*, and stride is 16, so it's OK here */
-    }
-
-    tmpM2ssA = vec_ld(0, tmpbis);
-    tmpM2ssB = vec_ld(16, tmpbis);
-    tmpbis += tmpStride;
-    tmpM1ssA = vec_ld(0, tmpbis);
-    tmpM1ssB = vec_ld(16, tmpbis);
-    tmpbis += tmpStride;
-    tmpP0ssA = vec_ld(0, tmpbis);
-    tmpP0ssB = vec_ld(16, tmpbis);
-    tmpbis += tmpStride;
-    tmpP1ssA = vec_ld(0, tmpbis);
-    tmpP1ssB = vec_ld(16, tmpbis);
-    tmpbis += tmpStride;
-    tmpP2ssA = vec_ld(0, tmpbis);
-    tmpP2ssB = vec_ld(16, tmpbis);
-    tmpbis += tmpStride;
-
-    for (i = 0 ; i < 16 ; i++) {
-        const vec_s16 tmpP3ssA = vec_ld(0, tmpbis);
-        const vec_s16 tmpP3ssB = vec_ld(16, tmpbis);
-
-        const vec_s16 sum1A = vec_adds(tmpP0ssA, tmpP1ssA);
-        const vec_s16 sum1B = vec_adds(tmpP0ssB, tmpP1ssB);
-        const vec_s16 sum2A = vec_adds(tmpM1ssA, tmpP2ssA);
-        const vec_s16 sum2B = vec_adds(tmpM1ssB, tmpP2ssB);
-        const vec_s16 sum3A = vec_adds(tmpM2ssA, tmpP3ssA);
-        const vec_s16 sum3B = vec_adds(tmpM2ssB, tmpP3ssB);
-
-        tmpbis += tmpStride;
-
-        tmpM2ssA = tmpM1ssA;
-        tmpM2ssB = tmpM1ssB;
-        tmpM1ssA = tmpP0ssA;
-        tmpM1ssB = tmpP0ssB;
-        tmpP0ssA = tmpP1ssA;
-        tmpP0ssB = tmpP1ssB;
-        tmpP1ssA = tmpP2ssA;
-        tmpP1ssB = tmpP2ssB;
-        tmpP2ssA = tmpP3ssA;
-        tmpP2ssB = tmpP3ssB;
-
-        pp1Ae = vec_mule(sum1A, v20ss);
-        pp1Ao = vec_mulo(sum1A, v20ss);
-        pp1Be = vec_mule(sum1B, v20ss);
-        pp1Bo = vec_mulo(sum1B, v20ss);
-
-        pp2Ae = vec_mule(sum2A, v5ss);
-        pp2Ao = vec_mulo(sum2A, v5ss);
-        pp2Be = vec_mule(sum2B, v5ss);
-        pp2Bo = vec_mulo(sum2B, v5ss);
-
-        pp3Ae = vec_sra((vec_s32)sum3A, v16ui);
-        pp3Ao = vec_mulo(sum3A, v1ss);
-        pp3Be = vec_sra((vec_s32)sum3B, v16ui);
-        pp3Bo = vec_mulo(sum3B, v1ss);
-
-        pp1cAe = vec_add(pp1Ae, v512si);
-        pp1cAo = vec_add(pp1Ao, v512si);
-        pp1cBe = vec_add(pp1Be, v512si);
-        pp1cBo = vec_add(pp1Bo, v512si);
-
-        pp32Ae = vec_sub(pp3Ae, pp2Ae);
-        pp32Ao = vec_sub(pp3Ao, pp2Ao);
-        pp32Be = vec_sub(pp3Be, pp2Be);
-        pp32Bo = vec_sub(pp3Bo, pp2Bo);
-
-        sumAe = vec_add(pp1cAe, pp32Ae);
-        sumAo = vec_add(pp1cAo, pp32Ao);
-        sumBe = vec_add(pp1cBe, pp32Be);
-        sumBo = vec_add(pp1cBo, pp32Bo);
-
-        ssumAe = vec_sra(sumAe, v10ui);
-        ssumAo = vec_sra(sumAo, v10ui);
-        ssumBe = vec_sra(sumBe, v10ui);
-        ssumBo = vec_sra(sumBo, v10ui);
-
-        ssume = vec_packs(ssumAe, ssumBe);
-        ssumo = vec_packs(ssumAo, ssumBo);
-
-        sumv = vec_packsu(ssume, ssumo);
-        sum = vec_perm(sumv, sumv, mperm);
-
-        ASSERT_ALIGNED(dst);
-
-        OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst));
-
-        vec_st(fsum, 0, dst);
-
-        dst += dstStride;
-    }
-}
-#endif
diff --git a/libavcodec/ppc/h264chroma_init.c b/libavcodec/ppc/h264chroma_init.c
new file mode 100644
index 0000000..415a8df
--- /dev/null
+++ b/libavcodec/ppc/h264chroma_init.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2004 Romain Dolbeau <romain at dolbeau.org>
+ *
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/h264chroma.h"
+#include "dsputil_altivec.h"
+
+#if HAVE_ALTIVEC
+#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
+#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
+
+#define OP_U8_ALTIVEC                          PUT_OP_U8_ALTIVEC
+#define PREFIX_h264_chroma_mc8_altivec         put_h264_chroma_mc8_altivec
+#define PREFIX_h264_chroma_mc8_num             altivec_put_h264_chroma_mc8_num
+#include "h264chroma_template.c"
+#undef OP_U8_ALTIVEC
+#undef PREFIX_h264_chroma_mc8_altivec
+#undef PREFIX_h264_chroma_mc8_num
+
+#define OP_U8_ALTIVEC                          AVG_OP_U8_ALTIVEC
+#define PREFIX_h264_chroma_mc8_altivec         avg_h264_chroma_mc8_altivec
+#define PREFIX_h264_chroma_mc8_num             altivec_avg_h264_chroma_mc8_num
+#include "h264chroma_template.c"
+#undef OP_U8_ALTIVEC
+#undef PREFIX_h264_chroma_mc8_altivec
+#undef PREFIX_h264_chroma_mc8_num
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_h264chroma_init_ppc(H264ChromaContext *c, int bit_depth)
+{
+#if HAVE_ALTIVEC
+    const int high_bit_depth = bit_depth > 8;
+
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
+    if (!high_bit_depth) {
+        c->put_h264_chroma_pixels_tab[0] = put_h264_chroma_mc8_altivec;
+        c->avg_h264_chroma_pixels_tab[0] = avg_h264_chroma_mc8_altivec;
+    }
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/h264chroma_template.c b/libavcodec/ppc/h264chroma_template.c
new file mode 100644
index 0000000..293fef5
--- /dev/null
+++ b/libavcodec/ppc/h264chroma_template.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2004 Romain Dolbeau <romain at dolbeau.org>
+ *
+ * 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/mem.h"
+
+/* this code assume that stride % 16 == 0 */
+
+#define CHROMA_MC8_ALTIVEC_CORE(BIAS1, BIAS2) \
+        vsrc2ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc2uc);\
+        vsrc3ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc3uc);\
+\
+        psum = vec_mladd(vA, vsrc0ssH, BIAS1);\
+        psum = vec_mladd(vB, vsrc1ssH, psum);\
+        psum = vec_mladd(vC, vsrc2ssH, psum);\
+        psum = vec_mladd(vD, vsrc3ssH, psum);\
+        psum = BIAS2(psum);\
+        psum = vec_sr(psum, v6us);\
+\
+        vdst = vec_ld(0, dst);\
+        ppsum = (vec_u8)vec_pack(psum, psum);\
+        vfdst = vec_perm(vdst, ppsum, fperm);\
+\
+        OP_U8_ALTIVEC(fsum, vfdst, vdst);\
+\
+        vec_st(fsum, 0, dst);\
+\
+        vsrc0ssH = vsrc2ssH;\
+        vsrc1ssH = vsrc3ssH;\
+\
+        dst += stride;\
+        src += stride;
+
+#define CHROMA_MC8_ALTIVEC_CORE_SIMPLE \
+\
+        vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);\
+        vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);\
+\
+        psum = vec_mladd(vA, vsrc0ssH, v32ss);\
+        psum = vec_mladd(vE, vsrc1ssH, psum);\
+        psum = vec_sr(psum, v6us);\
+\
+        vdst = vec_ld(0, dst);\
+        ppsum = (vec_u8)vec_pack(psum, psum);\
+        vfdst = vec_perm(vdst, ppsum, fperm);\
+\
+        OP_U8_ALTIVEC(fsum, vfdst, vdst);\
+\
+        vec_st(fsum, 0, dst);\
+\
+        dst += stride;\
+        src += stride;
+
+#define noop(a) a
+#define add28(a) vec_add(v28ss, a)
+
+#ifdef PREFIX_h264_chroma_mc8_altivec
+static void PREFIX_h264_chroma_mc8_altivec(uint8_t * dst, uint8_t * src,
+                                    int stride, int h, int x, int y) {
+    DECLARE_ALIGNED(16, signed int, ABCD)[4] =
+                        {((8 - x) * (8 - y)),
+                         ((    x) * (8 - y)),
+                         ((8 - x) * (    y)),
+                         ((    x) * (    y))};
+    register int i;
+    vec_u8 fperm;
+    const vec_s32 vABCD = vec_ld(0, ABCD);
+    const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
+    const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
+    const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
+    const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
+    LOAD_ZERO;
+    const vec_s16 v32ss = vec_sl(vec_splat_s16(1),vec_splat_u16(5));
+    const vec_u16 v6us = vec_splat_u16(6);
+    register int loadSecond = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
+    register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
+
+    vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
+    vec_u8 vsrc0uc, vsrc1uc;
+    vec_s16 vsrc0ssH, vsrc1ssH;
+    vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
+    vec_s16 vsrc2ssH, vsrc3ssH, psum;
+    vec_u8 vdst, ppsum, vfdst, fsum;
+
+    if (((unsigned long)dst) % 16 == 0) {
+        fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
+                         0x14, 0x15, 0x16, 0x17,
+                         0x08, 0x09, 0x0A, 0x0B,
+                         0x0C, 0x0D, 0x0E, 0x0F};
+    } else {
+        fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
+                         0x04, 0x05, 0x06, 0x07,
+                         0x18, 0x19, 0x1A, 0x1B,
+                         0x1C, 0x1D, 0x1E, 0x1F};
+    }
+
+    vsrcAuc = vec_ld(0, src);
+
+    if (loadSecond)
+        vsrcBuc = vec_ld(16, src);
+    vsrcperm0 = vec_lvsl(0, src);
+    vsrcperm1 = vec_lvsl(1, src);
+
+    vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
+    if (reallyBadAlign)
+        vsrc1uc = vsrcBuc;
+    else
+        vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
+
+    vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc0uc);
+    vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v,(vec_u8)vsrc1uc);
+
+    if (ABCD[3]) {
+        if (!loadSecond) {// -> !reallyBadAlign
+            for (i = 0 ; i < h ; i++) {
+                vsrcCuc = vec_ld(stride + 0, src);
+                vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
+                vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
+
+                CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
+            }
+        } else {
+            vec_u8 vsrcDuc;
+            for (i = 0 ; i < h ; i++) {
+                vsrcCuc = vec_ld(stride + 0, src);
+                vsrcDuc = vec_ld(stride + 16, src);
+                vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
+                if (reallyBadAlign)
+                    vsrc3uc = vsrcDuc;
+                else
+                    vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
+
+                CHROMA_MC8_ALTIVEC_CORE(v32ss, noop)
+            }
+        }
+    } else {
+        const vec_s16 vE = vec_add(vB, vC);
+        if (ABCD[2]) { // x == 0 B == 0
+            if (!loadSecond) {// -> !reallyBadAlign
+                for (i = 0 ; i < h ; i++) {
+                    vsrcCuc = vec_ld(stride + 0, src);
+                    vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
+                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
+
+                    vsrc0uc = vsrc1uc;
+                }
+            } else {
+                vec_u8 vsrcDuc;
+                for (i = 0 ; i < h ; i++) {
+                    vsrcCuc = vec_ld(stride + 0, src);
+                    vsrcDuc = vec_ld(stride + 15, src);
+                    vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
+                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
+
+                    vsrc0uc = vsrc1uc;
+                }
+            }
+        } else { // y == 0 C == 0
+            if (!loadSecond) {// -> !reallyBadAlign
+                for (i = 0 ; i < h ; i++) {
+                    vsrcCuc = vec_ld(0, src);
+                    vsrc0uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
+                    vsrc1uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
+
+                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
+                }
+            } else {
+                vec_u8 vsrcDuc;
+                for (i = 0 ; i < h ; i++) {
+                    vsrcCuc = vec_ld(0, src);
+                    vsrcDuc = vec_ld(15, src);
+                    vsrc0uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
+                    if (reallyBadAlign)
+                        vsrc1uc = vsrcDuc;
+                    else
+                        vsrc1uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
+
+                    CHROMA_MC8_ALTIVEC_CORE_SIMPLE
+                }
+            }
+        }
+    }
+}
+#endif
+
+/* this code assume that stride % 16 == 0 */
+#ifdef PREFIX_no_rnd_vc1_chroma_mc8_altivec
+static void PREFIX_no_rnd_vc1_chroma_mc8_altivec(uint8_t * dst, uint8_t * src, int stride, int h, int x, int y) {
+   DECLARE_ALIGNED(16, signed int, ABCD)[4] =
+                        {((8 - x) * (8 - y)),
+                         ((    x) * (8 - y)),
+                         ((8 - x) * (    y)),
+                         ((    x) * (    y))};
+    register int i;
+    vec_u8 fperm;
+    const vec_s32 vABCD = vec_ld(0, ABCD);
+    const vec_s16 vA = vec_splat((vec_s16)vABCD, 1);
+    const vec_s16 vB = vec_splat((vec_s16)vABCD, 3);
+    const vec_s16 vC = vec_splat((vec_s16)vABCD, 5);
+    const vec_s16 vD = vec_splat((vec_s16)vABCD, 7);
+    LOAD_ZERO;
+    const vec_s16 v28ss = vec_sub(vec_sl(vec_splat_s16(1),vec_splat_u16(5)),vec_splat_s16(4));
+    const vec_u16 v6us  = vec_splat_u16(6);
+    register int loadSecond     = (((unsigned long)src) % 16) <= 7 ? 0 : 1;
+    register int reallyBadAlign = (((unsigned long)src) % 16) == 15 ? 1 : 0;
+
+    vec_u8 vsrcAuc, av_uninit(vsrcBuc), vsrcperm0, vsrcperm1;
+    vec_u8 vsrc0uc, vsrc1uc;
+    vec_s16 vsrc0ssH, vsrc1ssH;
+    vec_u8 vsrcCuc, vsrc2uc, vsrc3uc;
+    vec_s16 vsrc2ssH, vsrc3ssH, psum;
+    vec_u8 vdst, ppsum, vfdst, fsum;
+
+    if (((unsigned long)dst) % 16 == 0) {
+        fperm = (vec_u8){0x10, 0x11, 0x12, 0x13,
+                         0x14, 0x15, 0x16, 0x17,
+                         0x08, 0x09, 0x0A, 0x0B,
+                         0x0C, 0x0D, 0x0E, 0x0F};
+    } else {
+        fperm = (vec_u8){0x00, 0x01, 0x02, 0x03,
+                         0x04, 0x05, 0x06, 0x07,
+                         0x18, 0x19, 0x1A, 0x1B,
+                         0x1C, 0x1D, 0x1E, 0x1F};
+    }
+
+    vsrcAuc = vec_ld(0, src);
+
+    if (loadSecond)
+        vsrcBuc = vec_ld(16, src);
+    vsrcperm0 = vec_lvsl(0, src);
+    vsrcperm1 = vec_lvsl(1, src);
+
+    vsrc0uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm0);
+    if (reallyBadAlign)
+        vsrc1uc = vsrcBuc;
+    else
+        vsrc1uc = vec_perm(vsrcAuc, vsrcBuc, vsrcperm1);
+
+    vsrc0ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc0uc);
+    vsrc1ssH = (vec_s16)vec_mergeh(zero_u8v, (vec_u8)vsrc1uc);
+
+    if (!loadSecond) {// -> !reallyBadAlign
+        for (i = 0 ; i < h ; i++) {
+
+
+            vsrcCuc = vec_ld(stride + 0, src);
+
+            vsrc2uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm0);
+            vsrc3uc = vec_perm(vsrcCuc, vsrcCuc, vsrcperm1);
+
+            CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
+        }
+    } else {
+        vec_u8 vsrcDuc;
+        for (i = 0 ; i < h ; i++) {
+            vsrcCuc = vec_ld(stride + 0, src);
+            vsrcDuc = vec_ld(stride + 16, src);
+
+            vsrc2uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm0);
+            if (reallyBadAlign)
+                vsrc3uc = vsrcDuc;
+            else
+                vsrc3uc = vec_perm(vsrcCuc, vsrcDuc, vsrcperm1);
+
+            CHROMA_MC8_ALTIVEC_CORE(vec_splat_s16(0), add28)
+        }
+    }
+}
+#endif
+
+#undef noop
+#undef add28
+#undef CHROMA_MC8_ALTIVEC_CORE
diff --git a/libavcodec/ppc/h264dsp.c b/libavcodec/ppc/h264dsp.c
new file mode 100644
index 0000000..df298dd
--- /dev/null
+++ b/libavcodec/ppc/h264dsp.c
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 2004 Romain Dolbeau <romain at dolbeau.org>
+ *
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/h264data.h"
+#include "libavcodec/h264dsp.h"
+
+#if HAVE_ALTIVEC
+
+/****************************************************************************
+ * IDCT transform:
+ ****************************************************************************/
+
+#define VEC_1D_DCT(vb0,vb1,vb2,vb3,va0,va1,va2,va3)               \
+    /* 1st stage */                                               \
+    vz0 = vec_add(vb0,vb2);       /* temp[0] = Y[0] + Y[2] */     \
+    vz1 = vec_sub(vb0,vb2);       /* temp[1] = Y[0] - Y[2] */     \
+    vz2 = vec_sra(vb1,vec_splat_u16(1));                          \
+    vz2 = vec_sub(vz2,vb3);       /* temp[2] = Y[1].1/2 - Y[3] */ \
+    vz3 = vec_sra(vb3,vec_splat_u16(1));                          \
+    vz3 = vec_add(vb1,vz3);       /* temp[3] = Y[1] + Y[3].1/2 */ \
+    /* 2nd stage: output */                                       \
+    va0 = vec_add(vz0,vz3);       /* x[0] = temp[0] + temp[3] */  \
+    va1 = vec_add(vz1,vz2);       /* x[1] = temp[1] + temp[2] */  \
+    va2 = vec_sub(vz1,vz2);       /* x[2] = temp[1] - temp[2] */  \
+    va3 = vec_sub(vz0,vz3)        /* x[3] = temp[0] - temp[3] */
+
+#define VEC_TRANSPOSE_4(a0,a1,a2,a3,b0,b1,b2,b3) \
+    b0 = vec_mergeh( a0, a0 ); \
+    b1 = vec_mergeh( a1, a0 ); \
+    b2 = vec_mergeh( a2, a0 ); \
+    b3 = vec_mergeh( a3, a0 ); \
+    a0 = vec_mergeh( b0, b2 ); \
+    a1 = vec_mergel( b0, b2 ); \
+    a2 = vec_mergeh( b1, b3 ); \
+    a3 = vec_mergel( b1, b3 ); \
+    b0 = vec_mergeh( a0, a2 ); \
+    b1 = vec_mergel( a0, a2 ); \
+    b2 = vec_mergeh( a1, a3 ); \
+    b3 = vec_mergel( a1, a3 )
+
+#define VEC_LOAD_U8_ADD_S16_STORE_U8(va)                      \
+    vdst_orig = vec_ld(0, dst);                               \
+    vdst = vec_perm(vdst_orig, zero_u8v, vdst_mask);          \
+    vdst_ss = (vec_s16) vec_mergeh(zero_u8v, vdst);         \
+    va = vec_add(va, vdst_ss);                                \
+    va_u8 = vec_packsu(va, zero_s16v);                        \
+    va_u32 = vec_splat((vec_u32)va_u8, 0);                  \
+    vec_ste(va_u32, element, (uint32_t*)dst);
+
+static void h264_idct_add_altivec(uint8_t *dst, int16_t *block, int stride)
+{
+    vec_s16 va0, va1, va2, va3;
+    vec_s16 vz0, vz1, vz2, vz3;
+    vec_s16 vtmp0, vtmp1, vtmp2, vtmp3;
+    vec_u8 va_u8;
+    vec_u32 va_u32;
+    vec_s16 vdst_ss;
+    const vec_u16 v6us = vec_splat_u16(6);
+    vec_u8 vdst, vdst_orig;
+    vec_u8 vdst_mask = vec_lvsl(0, dst);
+    int element = ((unsigned long)dst & 0xf) >> 2;
+    LOAD_ZERO;
+
+    block[0] += 32;  /* add 32 as a DC-level for rounding */
+
+    vtmp0 = vec_ld(0,block);
+    vtmp1 = vec_sld(vtmp0, vtmp0, 8);
+    vtmp2 = vec_ld(16,block);
+    vtmp3 = vec_sld(vtmp2, vtmp2, 8);
+    memset(block, 0, 16 * sizeof(int16_t));
+
+    VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3);
+    VEC_TRANSPOSE_4(va0,va1,va2,va3,vtmp0,vtmp1,vtmp2,vtmp3);
+    VEC_1D_DCT(vtmp0,vtmp1,vtmp2,vtmp3,va0,va1,va2,va3);
+
+    va0 = vec_sra(va0,v6us);
+    va1 = vec_sra(va1,v6us);
+    va2 = vec_sra(va2,v6us);
+    va3 = vec_sra(va3,v6us);
+
+    VEC_LOAD_U8_ADD_S16_STORE_U8(va0);
+    dst += stride;
+    VEC_LOAD_U8_ADD_S16_STORE_U8(va1);
+    dst += stride;
+    VEC_LOAD_U8_ADD_S16_STORE_U8(va2);
+    dst += stride;
+    VEC_LOAD_U8_ADD_S16_STORE_U8(va3);
+}
+
+#define IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7,  d0, d1, d2, d3, d4, d5, d6, d7) {\
+    /*        a0  = SRC(0) + SRC(4); */ \
+    vec_s16 a0v = vec_add(s0, s4);    \
+    /*        a2  = SRC(0) - SRC(4); */ \
+    vec_s16 a2v = vec_sub(s0, s4);    \
+    /*        a4  =           (SRC(2)>>1) - SRC(6); */ \
+    vec_s16 a4v = vec_sub(vec_sra(s2, onev), s6);    \
+    /*        a6  =           (SRC(6)>>1) + SRC(2); */ \
+    vec_s16 a6v = vec_add(vec_sra(s6, onev), s2);    \
+    /*        b0  =         a0 + a6; */ \
+    vec_s16 b0v = vec_add(a0v, a6v);  \
+    /*        b2  =         a2 + a4; */ \
+    vec_s16 b2v = vec_add(a2v, a4v);  \
+    /*        b4  =         a2 - a4; */ \
+    vec_s16 b4v = vec_sub(a2v, a4v);  \
+    /*        b6  =         a0 - a6; */ \
+    vec_s16 b6v = vec_sub(a0v, a6v);  \
+    /* a1 =  SRC(5) - SRC(3) - SRC(7) - (SRC(7)>>1); */ \
+    /*        a1 =             (SRC(5)-SRC(3)) -  (SRC(7)  +  (SRC(7)>>1)); */ \
+    vec_s16 a1v = vec_sub( vec_sub(s5, s3), vec_add(s7, vec_sra(s7, onev)) ); \
+    /* a3 =  SRC(7) + SRC(1) - SRC(3) - (SRC(3)>>1); */ \
+    /*        a3 =             (SRC(7)+SRC(1)) -  (SRC(3)  +  (SRC(3)>>1)); */ \
+    vec_s16 a3v = vec_sub( vec_add(s7, s1), vec_add(s3, vec_sra(s3, onev)) );\
+    /* a5 =  SRC(7) - SRC(1) + SRC(5) + (SRC(5)>>1); */ \
+    /*        a5 =             (SRC(7)-SRC(1)) +   SRC(5) +   (SRC(5)>>1); */ \
+    vec_s16 a5v = vec_add( vec_sub(s7, s1), vec_add(s5, vec_sra(s5, onev)) );\
+    /*        a7 =                SRC(5)+SRC(3) +  SRC(1) +   (SRC(1)>>1); */ \
+    vec_s16 a7v = vec_add( vec_add(s5, s3), vec_add(s1, vec_sra(s1, onev)) );\
+    /*        b1 =                  (a7>>2)  +  a1; */ \
+    vec_s16 b1v = vec_add( vec_sra(a7v, twov), a1v); \
+    /*        b3 =          a3 +        (a5>>2); */ \
+    vec_s16 b3v = vec_add(a3v, vec_sra(a5v, twov)); \
+    /*        b5 =                  (a3>>2)  -   a5; */ \
+    vec_s16 b5v = vec_sub( vec_sra(a3v, twov), a5v); \
+    /*        b7 =           a7 -        (a1>>2); */ \
+    vec_s16 b7v = vec_sub( a7v, vec_sra(a1v, twov)); \
+    /* DST(0,    b0 + b7); */ \
+    d0 = vec_add(b0v, b7v); \
+    /* DST(1,    b2 + b5); */ \
+    d1 = vec_add(b2v, b5v); \
+    /* DST(2,    b4 + b3); */ \
+    d2 = vec_add(b4v, b3v); \
+    /* DST(3,    b6 + b1); */ \
+    d3 = vec_add(b6v, b1v); \
+    /* DST(4,    b6 - b1); */ \
+    d4 = vec_sub(b6v, b1v); \
+    /* DST(5,    b4 - b3); */ \
+    d5 = vec_sub(b4v, b3v); \
+    /* DST(6,    b2 - b5); */ \
+    d6 = vec_sub(b2v, b5v); \
+    /* DST(7,    b0 - b7); */ \
+    d7 = vec_sub(b0v, b7v); \
+}
+
+#define ALTIVEC_STORE_SUM_CLIP(dest, idctv, perm_ldv, perm_stv, sel) { \
+    /* unaligned load */                                       \
+    vec_u8 hv = vec_ld( 0, dest );                           \
+    vec_u8 lv = vec_ld( 7, dest );                           \
+    vec_u8 dstv   = vec_perm( hv, lv, (vec_u8)perm_ldv );  \
+    vec_s16 idct_sh6 = vec_sra(idctv, sixv);                 \
+    vec_u16 dst16 = (vec_u16)vec_mergeh(zero_u8v, dstv);   \
+    vec_s16 idstsum = vec_adds(idct_sh6, (vec_s16)dst16);  \
+    vec_u8 idstsum8 = vec_packsu(zero_s16v, idstsum);        \
+    vec_u8 edgehv;                                           \
+    /* unaligned store */                                      \
+    vec_u8 bodyv  = vec_perm( idstsum8, idstsum8, perm_stv );\
+    vec_u8 edgelv = vec_perm( sel, zero_u8v, perm_stv );     \
+    lv    = vec_sel( lv, bodyv, edgelv );                      \
+    vec_st( lv, 7, dest );                                     \
+    hv    = vec_ld( 0, dest );                                 \
+    edgehv = vec_perm( zero_u8v, sel, perm_stv );              \
+    hv    = vec_sel( hv, bodyv, edgehv );                      \
+    vec_st( hv, 0, dest );                                     \
+ }
+
+static void h264_idct8_add_altivec(uint8_t *dst, int16_t *dct, int stride)
+{
+    vec_s16 s0, s1, s2, s3, s4, s5, s6, s7;
+    vec_s16 d0, d1, d2, d3, d4, d5, d6, d7;
+    vec_s16 idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7;
+
+    vec_u8 perm_ldv = vec_lvsl(0, dst);
+    vec_u8 perm_stv = vec_lvsr(8, dst);
+
+    const vec_u16 onev = vec_splat_u16(1);
+    const vec_u16 twov = vec_splat_u16(2);
+    const vec_u16 sixv = vec_splat_u16(6);
+
+    const vec_u8 sel = (vec_u8) {0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1};
+    LOAD_ZERO;
+
+    dct[0] += 32; // rounding for the >>6 at the end
+
+    s0 = vec_ld(0x00, (int16_t*)dct);
+    s1 = vec_ld(0x10, (int16_t*)dct);
+    s2 = vec_ld(0x20, (int16_t*)dct);
+    s3 = vec_ld(0x30, (int16_t*)dct);
+    s4 = vec_ld(0x40, (int16_t*)dct);
+    s5 = vec_ld(0x50, (int16_t*)dct);
+    s6 = vec_ld(0x60, (int16_t*)dct);
+    s7 = vec_ld(0x70, (int16_t*)dct);
+    memset(dct, 0, 64 * sizeof(int16_t));
+
+    IDCT8_1D_ALTIVEC(s0, s1, s2, s3, s4, s5, s6, s7,
+                     d0, d1, d2, d3, d4, d5, d6, d7);
+
+    TRANSPOSE8( d0,  d1,  d2,  d3,  d4,  d5,  d6, d7 );
+
+    IDCT8_1D_ALTIVEC(d0,  d1,  d2,  d3,  d4,  d5,  d6, d7,
+                     idct0, idct1, idct2, idct3, idct4, idct5, idct6, idct7);
+
+    ALTIVEC_STORE_SUM_CLIP(&dst[0*stride], idct0, perm_ldv, perm_stv, sel);
+    ALTIVEC_STORE_SUM_CLIP(&dst[1*stride], idct1, perm_ldv, perm_stv, sel);
+    ALTIVEC_STORE_SUM_CLIP(&dst[2*stride], idct2, perm_ldv, perm_stv, sel);
+    ALTIVEC_STORE_SUM_CLIP(&dst[3*stride], idct3, perm_ldv, perm_stv, sel);
+    ALTIVEC_STORE_SUM_CLIP(&dst[4*stride], idct4, perm_ldv, perm_stv, sel);
+    ALTIVEC_STORE_SUM_CLIP(&dst[5*stride], idct5, perm_ldv, perm_stv, sel);
+    ALTIVEC_STORE_SUM_CLIP(&dst[6*stride], idct6, perm_ldv, perm_stv, sel);
+    ALTIVEC_STORE_SUM_CLIP(&dst[7*stride], idct7, perm_ldv, perm_stv, sel);
+}
+
+static av_always_inline void h264_idct_dc_add_internal(uint8_t *dst, int16_t *block, int stride, int size)
+{
+    vec_s16 dc16;
+    vec_u8 dcplus, dcminus, v0, v1, v2, v3, aligner;
+    LOAD_ZERO;
+    DECLARE_ALIGNED(16, int, dc);
+    int i;
+
+    dc = (block[0] + 32) >> 6;
+    block[0] = 0;
+    dc16 = vec_splat((vec_s16) vec_lde(0, &dc), 1);
+
+    if (size == 4)
+        dc16 = vec_sld(dc16, zero_s16v, 8);
+    dcplus = vec_packsu(dc16, zero_s16v);
+    dcminus = vec_packsu(vec_sub(zero_s16v, dc16), zero_s16v);
+
+    aligner = vec_lvsr(0, dst);
+    dcplus = vec_perm(dcplus, dcplus, aligner);
+    dcminus = vec_perm(dcminus, dcminus, aligner);
+
+    for (i = 0; i < size; i += 4) {
+        v0 = vec_ld(0, dst+0*stride);
+        v1 = vec_ld(0, dst+1*stride);
+        v2 = vec_ld(0, dst+2*stride);
+        v3 = vec_ld(0, dst+3*stride);
+
+        v0 = vec_adds(v0, dcplus);
+        v1 = vec_adds(v1, dcplus);
+        v2 = vec_adds(v2, dcplus);
+        v3 = vec_adds(v3, dcplus);
+
+        v0 = vec_subs(v0, dcminus);
+        v1 = vec_subs(v1, dcminus);
+        v2 = vec_subs(v2, dcminus);
+        v3 = vec_subs(v3, dcminus);
+
+        vec_st(v0, 0, dst+0*stride);
+        vec_st(v1, 0, dst+1*stride);
+        vec_st(v2, 0, dst+2*stride);
+        vec_st(v3, 0, dst+3*stride);
+
+        dst += 4*stride;
+    }
+}
+
+static void h264_idct_dc_add_altivec(uint8_t *dst, int16_t *block, int stride)
+{
+    h264_idct_dc_add_internal(dst, block, stride, 4);
+}
+
+static void h264_idct8_dc_add_altivec(uint8_t *dst, int16_t *block, int stride)
+{
+    h264_idct_dc_add_internal(dst, block, stride, 8);
+}
+
+static void h264_idct_add16_altivec(uint8_t *dst, const int *block_offset,
+                                    int16_t *block, int stride,
+                                    const uint8_t nnzc[15 * 8])
+{
+    int i;
+    for(i=0; i<16; i++){
+        int nnz = nnzc[ scan8[i] ];
+        if(nnz){
+            if(nnz==1 && block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
+            else                      h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
+        }
+    }
+}
+
+static void h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset,
+                                         int16_t *block, int stride,
+                                         const uint8_t nnzc[15 * 8])
+{
+    int i;
+    for(i=0; i<16; i++){
+        if(nnzc[ scan8[i] ]) h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
+        else if(block[i*16]) h264_idct_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
+    }
+}
+
+static void h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset,
+                                    int16_t *block, int stride,
+                                    const uint8_t nnzc[15 * 8])
+{
+    int i;
+    for(i=0; i<16; i+=4){
+        int nnz = nnzc[ scan8[i] ];
+        if(nnz){
+            if(nnz==1 && block[i*16]) h264_idct8_dc_add_altivec(dst + block_offset[i], block + i*16, stride);
+            else                      h264_idct8_add_altivec(dst + block_offset[i], block + i*16, stride);
+        }
+    }
+}
+
+static void h264_idct_add8_altivec(uint8_t **dest, const int *block_offset,
+                                   int16_t *block, int stride,
+                                   const uint8_t nnzc[15 * 8])
+{
+    int i, j;
+    for (j = 1; j < 3; j++) {
+        for(i = j * 16; i < j * 16 + 4; i++){
+            if(nnzc[ scan8[i] ])
+                h264_idct_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
+            else if(block[i*16])
+                h264_idct_dc_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
+        }
+    }
+}
+
+#define transpose4x16(r0, r1, r2, r3) {      \
+    register vec_u8 r4;                    \
+    register vec_u8 r5;                    \
+    register vec_u8 r6;                    \
+    register vec_u8 r7;                    \
+                                             \
+    r4 = vec_mergeh(r0, r2);  /*0, 2 set 0*/ \
+    r5 = vec_mergel(r0, r2);  /*0, 2 set 1*/ \
+    r6 = vec_mergeh(r1, r3);  /*1, 3 set 0*/ \
+    r7 = vec_mergel(r1, r3);  /*1, 3 set 1*/ \
+                                             \
+    r0 = vec_mergeh(r4, r6);  /*all set 0*/  \
+    r1 = vec_mergel(r4, r6);  /*all set 1*/  \
+    r2 = vec_mergeh(r5, r7);  /*all set 2*/  \
+    r3 = vec_mergel(r5, r7);  /*all set 3*/  \
+}
+
+static inline void write16x4(uint8_t *dst, int dst_stride,
+                             register vec_u8 r0, register vec_u8 r1,
+                             register vec_u8 r2, register vec_u8 r3) {
+    DECLARE_ALIGNED(16, unsigned char, result)[64];
+    uint32_t *src_int = (uint32_t *)result, *dst_int = (uint32_t *)dst;
+    int int_dst_stride = dst_stride/4;
+
+    vec_st(r0, 0, result);
+    vec_st(r1, 16, result);
+    vec_st(r2, 32, result);
+    vec_st(r3, 48, result);
+    /* FIXME: there has to be a better way!!!! */
+    *dst_int = *src_int;
+    *(dst_int+   int_dst_stride) = *(src_int + 1);
+    *(dst_int+ 2*int_dst_stride) = *(src_int + 2);
+    *(dst_int+ 3*int_dst_stride) = *(src_int + 3);
+    *(dst_int+ 4*int_dst_stride) = *(src_int + 4);
+    *(dst_int+ 5*int_dst_stride) = *(src_int + 5);
+    *(dst_int+ 6*int_dst_stride) = *(src_int + 6);
+    *(dst_int+ 7*int_dst_stride) = *(src_int + 7);
+    *(dst_int+ 8*int_dst_stride) = *(src_int + 8);
+    *(dst_int+ 9*int_dst_stride) = *(src_int + 9);
+    *(dst_int+10*int_dst_stride) = *(src_int + 10);
+    *(dst_int+11*int_dst_stride) = *(src_int + 11);
+    *(dst_int+12*int_dst_stride) = *(src_int + 12);
+    *(dst_int+13*int_dst_stride) = *(src_int + 13);
+    *(dst_int+14*int_dst_stride) = *(src_int + 14);
+    *(dst_int+15*int_dst_stride) = *(src_int + 15);
+}
+
+/** @brief performs a 6x16 transpose of data in src, and stores it to dst
+    @todo FIXME: see if we can't spare some vec_lvsl() by them factorizing
+    out of unaligned_load() */
+#define readAndTranspose16x6(src, src_stride, r8, r9, r10, r11, r12, r13) {\
+    register vec_u8 r0  = unaligned_load(0,             src);            \
+    register vec_u8 r1  = unaligned_load(   src_stride, src);            \
+    register vec_u8 r2  = unaligned_load(2* src_stride, src);            \
+    register vec_u8 r3  = unaligned_load(3* src_stride, src);            \
+    register vec_u8 r4  = unaligned_load(4* src_stride, src);            \
+    register vec_u8 r5  = unaligned_load(5* src_stride, src);            \
+    register vec_u8 r6  = unaligned_load(6* src_stride, src);            \
+    register vec_u8 r7  = unaligned_load(7* src_stride, src);            \
+    register vec_u8 r14 = unaligned_load(14*src_stride, src);            \
+    register vec_u8 r15 = unaligned_load(15*src_stride, src);            \
+                                                                           \
+    r8  = unaligned_load( 8*src_stride, src);                              \
+    r9  = unaligned_load( 9*src_stride, src);                              \
+    r10 = unaligned_load(10*src_stride, src);                              \
+    r11 = unaligned_load(11*src_stride, src);                              \
+    r12 = unaligned_load(12*src_stride, src);                              \
+    r13 = unaligned_load(13*src_stride, src);                              \
+                                                                           \
+    /*Merge first pairs*/                                                  \
+    r0 = vec_mergeh(r0, r8);    /*0, 8*/                                   \
+    r1 = vec_mergeh(r1, r9);    /*1, 9*/                                   \
+    r2 = vec_mergeh(r2, r10);   /*2,10*/                                   \
+    r3 = vec_mergeh(r3, r11);   /*3,11*/                                   \
+    r4 = vec_mergeh(r4, r12);   /*4,12*/                                   \
+    r5 = vec_mergeh(r5, r13);   /*5,13*/                                   \
+    r6 = vec_mergeh(r6, r14);   /*6,14*/                                   \
+    r7 = vec_mergeh(r7, r15);   /*7,15*/                                   \
+                                                                           \
+    /*Merge second pairs*/                                                 \
+    r8  = vec_mergeh(r0, r4);   /*0,4, 8,12 set 0*/                        \
+    r9  = vec_mergel(r0, r4);   /*0,4, 8,12 set 1*/                        \
+    r10 = vec_mergeh(r1, r5);   /*1,5, 9,13 set 0*/                        \
+    r11 = vec_mergel(r1, r5);   /*1,5, 9,13 set 1*/                        \
+    r12 = vec_mergeh(r2, r6);   /*2,6,10,14 set 0*/                        \
+    r13 = vec_mergel(r2, r6);   /*2,6,10,14 set 1*/                        \
+    r14 = vec_mergeh(r3, r7);   /*3,7,11,15 set 0*/                        \
+    r15 = vec_mergel(r3, r7);   /*3,7,11,15 set 1*/                        \
+                                                                           \
+    /*Third merge*/                                                        \
+    r0 = vec_mergeh(r8,  r12);  /*0,2,4,6,8,10,12,14 set 0*/               \
+    r1 = vec_mergel(r8,  r12);  /*0,2,4,6,8,10,12,14 set 1*/               \
+    r2 = vec_mergeh(r9,  r13);  /*0,2,4,6,8,10,12,14 set 2*/               \
+    r4 = vec_mergeh(r10, r14);  /*1,3,5,7,9,11,13,15 set 0*/               \
+    r5 = vec_mergel(r10, r14);  /*1,3,5,7,9,11,13,15 set 1*/               \
+    r6 = vec_mergeh(r11, r15);  /*1,3,5,7,9,11,13,15 set 2*/               \
+    /* Don't need to compute 3 and 7*/                                     \
+                                                                           \
+    /*Final merge*/                                                        \
+    r8  = vec_mergeh(r0, r4);   /*all set 0*/                              \
+    r9  = vec_mergel(r0, r4);   /*all set 1*/                              \
+    r10 = vec_mergeh(r1, r5);   /*all set 2*/                              \
+    r11 = vec_mergel(r1, r5);   /*all set 3*/                              \
+    r12 = vec_mergeh(r2, r6);   /*all set 4*/                              \
+    r13 = vec_mergel(r2, r6);   /*all set 5*/                              \
+    /* Don't need to compute 14 and 15*/                                   \
+                                                                           \
+}
+
+// out: o = |x-y| < a
+static inline vec_u8 diff_lt_altivec ( register vec_u8 x,
+                                         register vec_u8 y,
+                                         register vec_u8 a) {
+
+    register vec_u8 diff = vec_subs(x, y);
+    register vec_u8 diffneg = vec_subs(y, x);
+    register vec_u8 o = vec_or(diff, diffneg); /* |x-y| */
+    o = (vec_u8)vec_cmplt(o, a);
+    return o;
+}
+
+static inline vec_u8 h264_deblock_mask ( register vec_u8 p0,
+                                           register vec_u8 p1,
+                                           register vec_u8 q0,
+                                           register vec_u8 q1,
+                                           register vec_u8 alpha,
+                                           register vec_u8 beta) {
+
+    register vec_u8 mask;
+    register vec_u8 tempmask;
+
+    mask = diff_lt_altivec(p0, q0, alpha);
+    tempmask = diff_lt_altivec(p1, p0, beta);
+    mask = vec_and(mask, tempmask);
+    tempmask = diff_lt_altivec(q1, q0, beta);
+    mask = vec_and(mask, tempmask);
+
+    return mask;
+}
+
+// out: newp1 = clip((p2 + ((p0 + q0 + 1) >> 1)) >> 1, p1-tc0, p1+tc0)
+static inline vec_u8 h264_deblock_q1(register vec_u8 p0,
+                                       register vec_u8 p1,
+                                       register vec_u8 p2,
+                                       register vec_u8 q0,
+                                       register vec_u8 tc0) {
+
+    register vec_u8 average = vec_avg(p0, q0);
+    register vec_u8 temp;
+    register vec_u8 uncliped;
+    register vec_u8 ones;
+    register vec_u8 max;
+    register vec_u8 min;
+    register vec_u8 newp1;
+
+    temp = vec_xor(average, p2);
+    average = vec_avg(average, p2);     /*avg(p2, avg(p0, q0)) */
+    ones = vec_splat_u8(1);
+    temp = vec_and(temp, ones);         /*(p2^avg(p0, q0)) & 1 */
+    uncliped = vec_subs(average, temp); /*(p2+((p0+q0+1)>>1))>>1 */
+    max = vec_adds(p1, tc0);
+    min = vec_subs(p1, tc0);
+    newp1 = vec_max(min, uncliped);
+    newp1 = vec_min(max, newp1);
+    return newp1;
+}
+
+#define h264_deblock_p0_q0(p0, p1, q0, q1, tc0masked) {                                           \
+                                                                                                  \
+    const vec_u8 A0v = vec_sl(vec_splat_u8(10), vec_splat_u8(4));                               \
+                                                                                                  \
+    register vec_u8 pq0bit = vec_xor(p0,q0);                                                    \
+    register vec_u8 q1minus;                                                                    \
+    register vec_u8 p0minus;                                                                    \
+    register vec_u8 stage1;                                                                     \
+    register vec_u8 stage2;                                                                     \
+    register vec_u8 vec160;                                                                     \
+    register vec_u8 delta;                                                                      \
+    register vec_u8 deltaneg;                                                                   \
+                                                                                                  \
+    q1minus = vec_nor(q1, q1);                 /* 255 - q1 */                                     \
+    stage1 = vec_avg(p1, q1minus);             /* (p1 - q1 + 256)>>1 */                           \
+    stage2 = vec_sr(stage1, vec_splat_u8(1));  /* (p1 - q1 + 256)>>2 = 64 + (p1 - q1) >> 2 */     \
+    p0minus = vec_nor(p0, p0);                 /* 255 - p0 */                                     \
+    stage1 = vec_avg(q0, p0minus);             /* (q0 - p0 + 256)>>1 */                           \
+    pq0bit = vec_and(pq0bit, vec_splat_u8(1));                                                    \
+    stage2 = vec_avg(stage2, pq0bit);          /* 32 + ((q0 - p0)&1 + (p1 - q1) >> 2 + 1) >> 1 */ \
+    stage2 = vec_adds(stage2, stage1);         /* 160 + ((p0 - q0) + (p1 - q1) >> 2 + 1) >> 1 */  \
+    vec160 = vec_ld(0, &A0v);                                                                     \
+    deltaneg = vec_subs(vec160, stage2);       /* -d */                                           \
+    delta = vec_subs(stage2, vec160);          /* d */                                            \
+    deltaneg = vec_min(tc0masked, deltaneg);                                                      \
+    delta = vec_min(tc0masked, delta);                                                            \
+    p0 = vec_subs(p0, deltaneg);                                                                  \
+    q0 = vec_subs(q0, delta);                                                                     \
+    p0 = vec_adds(p0, delta);                                                                     \
+    q0 = vec_adds(q0, deltaneg);                                                                  \
+}
+
+#define h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0) {            \
+    DECLARE_ALIGNED(16, unsigned char, temp)[16];                                             \
+    register vec_u8 alphavec;                                                              \
+    register vec_u8 betavec;                                                               \
+    register vec_u8 mask;                                                                  \
+    register vec_u8 p1mask;                                                                \
+    register vec_u8 q1mask;                                                                \
+    register vector signed   char tc0vec;                                                    \
+    register vec_u8 finaltc0;                                                              \
+    register vec_u8 tc0masked;                                                             \
+    register vec_u8 newp1;                                                                 \
+    register vec_u8 newq1;                                                                 \
+                                                                                             \
+    temp[0] = alpha;                                                                         \
+    temp[1] = beta;                                                                          \
+    alphavec = vec_ld(0, temp);                                                              \
+    betavec = vec_splat(alphavec, 0x1);                                                      \
+    alphavec = vec_splat(alphavec, 0x0);                                                     \
+    mask = h264_deblock_mask(p0, p1, q0, q1, alphavec, betavec); /*if in block */            \
+                                                                                             \
+    AV_COPY32(temp, tc0);                                                                    \
+    tc0vec = vec_ld(0, (signed char*)temp);                                                  \
+    tc0vec = vec_mergeh(tc0vec, tc0vec);                                                     \
+    tc0vec = vec_mergeh(tc0vec, tc0vec);                                                     \
+    mask = vec_and(mask, vec_cmpgt(tc0vec, vec_splat_s8(-1)));  /* if tc0[i] >= 0 */         \
+    finaltc0 = vec_and((vec_u8)tc0vec, mask);     /* tc = tc0 */                           \
+                                                                                             \
+    p1mask = diff_lt_altivec(p2, p0, betavec);                                               \
+    p1mask = vec_and(p1mask, mask);                             /* if ( |p2 - p0| < beta) */ \
+    tc0masked = vec_and(p1mask, (vec_u8)tc0vec);                                           \
+    finaltc0 = vec_sub(finaltc0, p1mask);                       /* tc++ */                   \
+    newp1 = h264_deblock_q1(p0, p1, p2, q0, tc0masked);                                      \
+    /*end if*/                                                                               \
+                                                                                             \
+    q1mask = diff_lt_altivec(q2, q0, betavec);                                               \
+    q1mask = vec_and(q1mask, mask);                             /* if ( |q2 - q0| < beta ) */\
+    tc0masked = vec_and(q1mask, (vec_u8)tc0vec);                                           \
+    finaltc0 = vec_sub(finaltc0, q1mask);                       /* tc++ */                   \
+    newq1 = h264_deblock_q1(p0, q1, q2, q0, tc0masked);                                      \
+    /*end if*/                                                                               \
+                                                                                             \
+    h264_deblock_p0_q0(p0, p1, q0, q1, finaltc0);                                            \
+    p1 = newp1;                                                                              \
+    q1 = newq1;                                                                              \
+}
+
+static void h264_v_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) {
+
+    if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) >= 0) {
+        register vec_u8 p2 = vec_ld(-3*stride, pix);
+        register vec_u8 p1 = vec_ld(-2*stride, pix);
+        register vec_u8 p0 = vec_ld(-1*stride, pix);
+        register vec_u8 q0 = vec_ld(0, pix);
+        register vec_u8 q1 = vec_ld(stride, pix);
+        register vec_u8 q2 = vec_ld(2*stride, pix);
+        h264_loop_filter_luma_altivec(p2, p1, p0, q0, q1, q2, alpha, beta, tc0);
+        vec_st(p1, -2*stride, pix);
+        vec_st(p0, -1*stride, pix);
+        vec_st(q0, 0, pix);
+        vec_st(q1, stride, pix);
+    }
+}
+
+static void h264_h_loop_filter_luma_altivec(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) {
+
+    register vec_u8 line0, line1, line2, line3, line4, line5;
+    if ((tc0[0] & tc0[1] & tc0[2] & tc0[3]) < 0)
+        return;
+    readAndTranspose16x6(pix-3, stride, line0, line1, line2, line3, line4, line5);
+    h264_loop_filter_luma_altivec(line0, line1, line2, line3, line4, line5, alpha, beta, tc0);
+    transpose4x16(line1, line2, line3, line4);
+    write16x4(pix-2, stride, line1, line2, line3, line4);
+}
+
+static av_always_inline
+void weight_h264_W_altivec(uint8_t *block, int stride, int height,
+                           int log2_denom, int weight, int offset, int w)
+{
+    int y, aligned;
+    vec_u8 vblock;
+    vec_s16 vtemp, vweight, voffset, v0, v1;
+    vec_u16 vlog2_denom;
+    DECLARE_ALIGNED(16, int32_t, temp)[4];
+    LOAD_ZERO;
+
+    offset <<= log2_denom;
+    if(log2_denom) offset += 1<<(log2_denom-1);
+    temp[0] = log2_denom;
+    temp[1] = weight;
+    temp[2] = offset;
+
+    vtemp = (vec_s16)vec_ld(0, temp);
+    vlog2_denom = (vec_u16)vec_splat(vtemp, 1);
+    vweight = vec_splat(vtemp, 3);
+    voffset = vec_splat(vtemp, 5);
+    aligned = !((unsigned long)block & 0xf);
+
+    for (y = 0; y < height; y++) {
+        vblock = vec_ld(0, block);
+
+        v0 = (vec_s16)vec_mergeh(zero_u8v, vblock);
+        v1 = (vec_s16)vec_mergel(zero_u8v, vblock);
+
+        if (w == 16 || aligned) {
+            v0 = vec_mladd(v0, vweight, zero_s16v);
+            v0 = vec_adds(v0, voffset);
+            v0 = vec_sra(v0, vlog2_denom);
+        }
+        if (w == 16 || !aligned) {
+            v1 = vec_mladd(v1, vweight, zero_s16v);
+            v1 = vec_adds(v1, voffset);
+            v1 = vec_sra(v1, vlog2_denom);
+        }
+        vblock = vec_packsu(v0, v1);
+        vec_st(vblock, 0, block);
+
+        block += stride;
+    }
+}
+
+static av_always_inline
+void biweight_h264_W_altivec(uint8_t *dst, uint8_t *src, int stride, int height,
+                             int log2_denom, int weightd, int weights, int offset, int w)
+{
+    int y, dst_aligned, src_aligned;
+    vec_u8 vsrc, vdst;
+    vec_s16 vtemp, vweights, vweightd, voffset, v0, v1, v2, v3;
+    vec_u16 vlog2_denom;
+    DECLARE_ALIGNED(16, int32_t, temp)[4];
+    LOAD_ZERO;
+
+    offset = ((offset + 1) | 1) << log2_denom;
+    temp[0] = log2_denom+1;
+    temp[1] = weights;
+    temp[2] = weightd;
+    temp[3] = offset;
+
+    vtemp = (vec_s16)vec_ld(0, temp);
+    vlog2_denom = (vec_u16)vec_splat(vtemp, 1);
+    vweights = vec_splat(vtemp, 3);
+    vweightd = vec_splat(vtemp, 5);
+    voffset = vec_splat(vtemp, 7);
+    dst_aligned = !((unsigned long)dst & 0xf);
+    src_aligned = !((unsigned long)src & 0xf);
+
+    for (y = 0; y < height; y++) {
+        vdst = vec_ld(0, dst);
+        vsrc = vec_ld(0, src);
+
+        v0 = (vec_s16)vec_mergeh(zero_u8v, vdst);
+        v1 = (vec_s16)vec_mergel(zero_u8v, vdst);
+        v2 = (vec_s16)vec_mergeh(zero_u8v, vsrc);
+        v3 = (vec_s16)vec_mergel(zero_u8v, vsrc);
+
+        if (w == 8) {
+            if (src_aligned)
+                v3 = v2;
+            else
+                v2 = v3;
+        }
+
+        if (w == 16 || dst_aligned) {
+            v0 = vec_mladd(v0, vweightd, zero_s16v);
+            v2 = vec_mladd(v2, vweights, zero_s16v);
+
+            v0 = vec_adds(v0, voffset);
+            v0 = vec_adds(v0, v2);
+            v0 = vec_sra(v0, vlog2_denom);
+        }
+        if (w == 16 || !dst_aligned) {
+            v1 = vec_mladd(v1, vweightd, zero_s16v);
+            v3 = vec_mladd(v3, vweights, zero_s16v);
+
+            v1 = vec_adds(v1, voffset);
+            v1 = vec_adds(v1, v3);
+            v1 = vec_sra(v1, vlog2_denom);
+        }
+        vdst = vec_packsu(v0, v1);
+        vec_st(vdst, 0, dst);
+
+        dst += stride;
+        src += stride;
+    }
+}
+
+#define H264_WEIGHT(W) \
+static void weight_h264_pixels ## W ## _altivec(uint8_t *block, int stride, int height, \
+                                                int log2_denom, int weight, int offset) \
+{ \
+    weight_h264_W_altivec(block, stride, height, log2_denom, weight, offset, W); \
+}\
+static void biweight_h264_pixels ## W ## _altivec(uint8_t *dst, uint8_t *src, int stride, int height, \
+                                                  int log2_denom, int weightd, int weights, int offset) \
+{ \
+    biweight_h264_W_altivec(dst, src, stride, height, log2_denom, weightd, weights, offset, W); \
+}
+
+H264_WEIGHT(16)
+H264_WEIGHT( 8)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth,
+                                 const int chroma_format_idc)
+{
+#if HAVE_ALTIVEC
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
+    if (bit_depth == 8) {
+        c->h264_idct_add = h264_idct_add_altivec;
+        if (chroma_format_idc == 1)
+            c->h264_idct_add8 = h264_idct_add8_altivec;
+        c->h264_idct_add16      = h264_idct_add16_altivec;
+        c->h264_idct_add16intra = h264_idct_add16intra_altivec;
+        c->h264_idct_dc_add= h264_idct_dc_add_altivec;
+        c->h264_idct8_dc_add = h264_idct8_dc_add_altivec;
+        c->h264_idct8_add    = h264_idct8_add_altivec;
+        c->h264_idct8_add4   = h264_idct8_add4_altivec;
+        c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_altivec;
+        c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_altivec;
+
+        c->weight_h264_pixels_tab[0]   = weight_h264_pixels16_altivec;
+        c->weight_h264_pixels_tab[1]   = weight_h264_pixels8_altivec;
+        c->biweight_h264_pixels_tab[0] = biweight_h264_pixels16_altivec;
+        c->biweight_h264_pixels_tab[1] = biweight_h264_pixels8_altivec;
+    }
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/h264qpel.c b/libavcodec/ppc/h264qpel.c
new file mode 100644
index 0000000..f99c8f8
--- /dev/null
+++ b/libavcodec/ppc/h264qpel.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2004 Romain Dolbeau <romain at dolbeau.org>
+ *
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/h264qpel.h"
+#include "dsputil_altivec.h"
+
+#if HAVE_ALTIVEC
+
+#define PUT_OP_U8_ALTIVEC(d, s, dst) d = s
+#define AVG_OP_U8_ALTIVEC(d, s, dst) d = vec_avg(dst, s)
+
+#define OP_U8_ALTIVEC                          PUT_OP_U8_ALTIVEC
+#define PREFIX_h264_qpel16_h_lowpass_altivec   put_h264_qpel16_h_lowpass_altivec
+#define PREFIX_h264_qpel16_h_lowpass_num       altivec_put_h264_qpel16_h_lowpass_num
+#define PREFIX_h264_qpel16_v_lowpass_altivec   put_h264_qpel16_v_lowpass_altivec
+#define PREFIX_h264_qpel16_v_lowpass_num       altivec_put_h264_qpel16_v_lowpass_num
+#define PREFIX_h264_qpel16_hv_lowpass_altivec  put_h264_qpel16_hv_lowpass_altivec
+#define PREFIX_h264_qpel16_hv_lowpass_num      altivec_put_h264_qpel16_hv_lowpass_num
+#include "h264qpel_template.c"
+#undef OP_U8_ALTIVEC
+#undef PREFIX_h264_qpel16_h_lowpass_altivec
+#undef PREFIX_h264_qpel16_h_lowpass_num
+#undef PREFIX_h264_qpel16_v_lowpass_altivec
+#undef PREFIX_h264_qpel16_v_lowpass_num
+#undef PREFIX_h264_qpel16_hv_lowpass_altivec
+#undef PREFIX_h264_qpel16_hv_lowpass_num
+
+#define OP_U8_ALTIVEC                          AVG_OP_U8_ALTIVEC
+#define PREFIX_h264_qpel16_h_lowpass_altivec   avg_h264_qpel16_h_lowpass_altivec
+#define PREFIX_h264_qpel16_h_lowpass_num       altivec_avg_h264_qpel16_h_lowpass_num
+#define PREFIX_h264_qpel16_v_lowpass_altivec   avg_h264_qpel16_v_lowpass_altivec
+#define PREFIX_h264_qpel16_v_lowpass_num       altivec_avg_h264_qpel16_v_lowpass_num
+#define PREFIX_h264_qpel16_hv_lowpass_altivec  avg_h264_qpel16_hv_lowpass_altivec
+#define PREFIX_h264_qpel16_hv_lowpass_num      altivec_avg_h264_qpel16_hv_lowpass_num
+#include "h264qpel_template.c"
+#undef OP_U8_ALTIVEC
+#undef PREFIX_h264_qpel16_h_lowpass_altivec
+#undef PREFIX_h264_qpel16_h_lowpass_num
+#undef PREFIX_h264_qpel16_v_lowpass_altivec
+#undef PREFIX_h264_qpel16_v_lowpass_num
+#undef PREFIX_h264_qpel16_hv_lowpass_altivec
+#undef PREFIX_h264_qpel16_hv_lowpass_num
+
+#define H264_MC(OPNAME, SIZE, CODETYPE) \
+static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## CODETYPE (uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    ff_ ## OPNAME ## pixels ## SIZE ## _ ## CODETYPE(dst, src, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{ \
+    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(dst, src, stride, stride);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+1, half, stride, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src, half, stride, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(dst, src, stride, stride);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, half)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(half, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, src+stride, half, stride, stride, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(dst, tmp, src, stride, SIZE, stride);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, halfH)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    put_h264_qpel ## SIZE ## _h_lowpass_ ## CODETYPE(halfH, src + stride, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfH, halfHV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
+}\
+\
+static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## CODETYPE(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
+    DECLARE_ALIGNED(16, uint8_t, halfV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, uint8_t, halfHV)[SIZE*SIZE];\
+    DECLARE_ALIGNED(16, int16_t, tmp)[SIZE*(SIZE+8)];\
+    put_h264_qpel ## SIZE ## _v_lowpass_ ## CODETYPE(halfV, src+1, SIZE, stride);\
+    put_h264_qpel ## SIZE ## _hv_lowpass_ ## CODETYPE(halfHV, tmp, src, SIZE, SIZE, stride);\
+    OPNAME ## pixels ## SIZE ## _l2_ ## CODETYPE(dst, halfV, halfHV, stride, SIZE, SIZE);\
+}\
+
+static inline void put_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
+                                    const uint8_t * src2, int dst_stride,
+                                    int src_stride1, int h)
+{
+    int i;
+    vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
+
+    mask_ = vec_lvsl(0, src2);
+
+    for (i = 0; i < h; i++) {
+
+        tmp1 = vec_ld(i * src_stride1, src1);
+        mask = vec_lvsl(i * src_stride1, src1);
+        tmp2 = vec_ld(i * src_stride1 + 15, src1);
+
+        a = vec_perm(tmp1, tmp2, mask);
+
+        tmp1 = vec_ld(i * 16, src2);
+        tmp2 = vec_ld(i * 16 + 15, src2);
+
+        b = vec_perm(tmp1, tmp2, mask_);
+
+        tmp1 = vec_ld(0, dst);
+        mask = vec_lvsl(0, dst);
+        tmp2 = vec_ld(15, dst);
+
+        d = vec_avg(a, b);
+
+        edges = vec_perm(tmp2, tmp1, mask);
+
+        align = vec_lvsr(0, dst);
+
+        tmp2 = vec_perm(d, edges, align);
+        tmp1 = vec_perm(edges, d, align);
+
+        vec_st(tmp2, 15, dst);
+        vec_st(tmp1, 0 , dst);
+
+        dst += dst_stride;
+    }
+}
+
+static inline void avg_pixels16_l2_altivec( uint8_t * dst, const uint8_t * src1,
+                                    const uint8_t * src2, int dst_stride,
+                                    int src_stride1, int h)
+{
+    int i;
+    vec_u8 a, b, d, tmp1, tmp2, mask, mask_, edges, align;
+
+    mask_ = vec_lvsl(0, src2);
+
+    for (i = 0; i < h; i++) {
+
+        tmp1 = vec_ld(i * src_stride1, src1);
+        mask = vec_lvsl(i * src_stride1, src1);
+        tmp2 = vec_ld(i * src_stride1 + 15, src1);
+
+        a = vec_perm(tmp1, tmp2, mask);
+
+        tmp1 = vec_ld(i * 16, src2);
+        tmp2 = vec_ld(i * 16 + 15, src2);
+
+        b = vec_perm(tmp1, tmp2, mask_);
+
+        tmp1 = vec_ld(0, dst);
+        mask = vec_lvsl(0, dst);
+        tmp2 = vec_ld(15, dst);
+
+        d = vec_avg(vec_perm(tmp1, tmp2, mask), vec_avg(a, b));
+
+        edges = vec_perm(tmp2, tmp1, mask);
+
+        align = vec_lvsr(0, dst);
+
+        tmp2 = vec_perm(d, edges, align);
+        tmp1 = vec_perm(edges, d, align);
+
+        vec_st(tmp2, 15, dst);
+        vec_st(tmp1, 0 , dst);
+
+        dst += dst_stride;
+    }
+}
+
+/* Implemented but could be faster
+#define put_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) put_pixels16_l2(d,s1,s2,ds,s1s,16,h)
+#define avg_pixels16_l2_altivec(d,s1,s2,ds,s1s,h) avg_pixels16_l2(d,s1,s2,ds,s1s,16,h)
+ */
+
+H264_MC(put_, 16, altivec)
+H264_MC(avg_, 16, altivec)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_h264qpel_init_ppc(H264QpelContext *c, int bit_depth)
+{
+#if HAVE_ALTIVEC
+    const int high_bit_depth = bit_depth > 8;
+
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
+    if (!high_bit_depth) {
+#define dspfunc(PFX, IDX, NUM) \
+        c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_altivec; \
+        c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_altivec; \
+        c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_altivec; \
+        c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_altivec; \
+        c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_altivec; \
+        c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_altivec; \
+        c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_altivec; \
+        c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_altivec
+
+        dspfunc(put_h264_qpel, 0, 16);
+        dspfunc(avg_h264_qpel, 0, 16);
+#undef dspfunc
+    }
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/h264qpel_template.c b/libavcodec/ppc/h264qpel_template.c
new file mode 100644
index 0000000..4df1d09
--- /dev/null
+++ b/libavcodec/ppc/h264qpel_template.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 2004 Romain Dolbeau <romain at dolbeau.org>
+ *
+ * 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/mem.h"
+
+#ifdef DEBUG
+#define ASSERT_ALIGNED(ptr) assert(((unsigned long)ptr&0x0000000F));
+#else
+#define ASSERT_ALIGNED(ptr) ;
+#endif
+
+/* this code assume stride % 16 == 0 */
+#ifdef PREFIX_h264_qpel16_h_lowpass_altivec
+static void PREFIX_h264_qpel16_h_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) {
+    register int i;
+
+    LOAD_ZERO;
+    const vec_u8 permM2 = vec_lvsl(-2, src);
+    const vec_u8 permM1 = vec_lvsl(-1, src);
+    const vec_u8 permP0 = vec_lvsl(+0, src);
+    const vec_u8 permP1 = vec_lvsl(+1, src);
+    const vec_u8 permP2 = vec_lvsl(+2, src);
+    const vec_u8 permP3 = vec_lvsl(+3, src);
+    const vec_s16 v5ss = vec_splat_s16(5);
+    const vec_u16 v5us = vec_splat_u16(5);
+    const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
+    const vec_s16 v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4));
+
+    vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3;
+
+    register int align = ((((unsigned long)src) - 2) % 16);
+
+    vec_s16 srcP0A, srcP0B, srcP1A, srcP1B,
+              srcP2A, srcP2B, srcP3A, srcP3B,
+              srcM1A, srcM1B, srcM2A, srcM2B,
+              sum1A, sum1B, sum2A, sum2B, sum3A, sum3B,
+              pp1A, pp1B, pp2A, pp2B, pp3A, pp3B,
+              psumA, psumB, sumA, sumB;
+
+    vec_u8 sum, fsum;
+
+    for (i = 0 ; i < 16 ; i ++) {
+        vec_u8 srcR1 = vec_ld(-2, src);
+        vec_u8 srcR2 = vec_ld(14, src);
+
+        switch (align) {
+        default: {
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = vec_perm(srcR1, srcR2, permP0);
+            srcP1 = vec_perm(srcR1, srcR2, permP1);
+            srcP2 = vec_perm(srcR1, srcR2, permP2);
+            srcP3 = vec_perm(srcR1, srcR2, permP3);
+        } break;
+        case 11: {
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = vec_perm(srcR1, srcR2, permP0);
+            srcP1 = vec_perm(srcR1, srcR2, permP1);
+            srcP2 = vec_perm(srcR1, srcR2, permP2);
+            srcP3 = srcR2;
+        } break;
+        case 12: {
+            vec_u8 srcR3 = vec_ld(30, src);
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = vec_perm(srcR1, srcR2, permP0);
+            srcP1 = vec_perm(srcR1, srcR2, permP1);
+            srcP2 = srcR2;
+            srcP3 = vec_perm(srcR2, srcR3, permP3);
+        } break;
+        case 13: {
+            vec_u8 srcR3 = vec_ld(30, src);
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = vec_perm(srcR1, srcR2, permP0);
+            srcP1 = srcR2;
+            srcP2 = vec_perm(srcR2, srcR3, permP2);
+            srcP3 = vec_perm(srcR2, srcR3, permP3);
+        } break;
+        case 14: {
+            vec_u8 srcR3 = vec_ld(30, src);
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = srcR2;
+            srcP1 = vec_perm(srcR2, srcR3, permP1);
+            srcP2 = vec_perm(srcR2, srcR3, permP2);
+            srcP3 = vec_perm(srcR2, srcR3, permP3);
+        } break;
+        case 15: {
+            vec_u8 srcR3 = vec_ld(30, src);
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = srcR2;
+            srcP0 = vec_perm(srcR2, srcR3, permP0);
+            srcP1 = vec_perm(srcR2, srcR3, permP1);
+            srcP2 = vec_perm(srcR2, srcR3, permP2);
+            srcP3 = vec_perm(srcR2, srcR3, permP3);
+        } break;
+        }
+
+        srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0);
+        srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0);
+        srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1);
+        srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1);
+
+        srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2);
+        srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2);
+        srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3);
+        srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3);
+
+        srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1);
+        srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1);
+        srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2);
+        srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2);
+
+        sum1A = vec_adds(srcP0A, srcP1A);
+        sum1B = vec_adds(srcP0B, srcP1B);
+        sum2A = vec_adds(srcM1A, srcP2A);
+        sum2B = vec_adds(srcM1B, srcP2B);
+        sum3A = vec_adds(srcM2A, srcP3A);
+        sum3B = vec_adds(srcM2B, srcP3B);
+
+        pp1A = vec_mladd(sum1A, v20ss, v16ss);
+        pp1B = vec_mladd(sum1B, v20ss, v16ss);
+
+        pp2A = vec_mladd(sum2A, v5ss, zero_s16v);
+        pp2B = vec_mladd(sum2B, v5ss, zero_s16v);
+
+        pp3A = vec_add(sum3A, pp1A);
+        pp3B = vec_add(sum3B, pp1B);
+
+        psumA = vec_sub(pp3A, pp2A);
+        psumB = vec_sub(pp3B, pp2B);
+
+        sumA = vec_sra(psumA, v5us);
+        sumB = vec_sra(psumB, v5us);
+
+        sum = vec_packsu(sumA, sumB);
+
+        ASSERT_ALIGNED(dst);
+
+        OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst));
+
+        vec_st(fsum, 0, dst);
+
+        src += srcStride;
+        dst += dstStride;
+    }
+}
+#endif
+
+/* this code assume stride % 16 == 0 */
+#ifdef PREFIX_h264_qpel16_v_lowpass_altivec
+static void PREFIX_h264_qpel16_v_lowpass_altivec(uint8_t * dst, uint8_t * src, int dstStride, int srcStride) {
+    register int i;
+
+    LOAD_ZERO;
+    const vec_u8 perm = vec_lvsl(0, src);
+    const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
+    const vec_u16 v5us = vec_splat_u16(5);
+    const vec_s16 v5ss = vec_splat_s16(5);
+    const vec_s16 v16ss = vec_sl(vec_splat_s16(1),vec_splat_u16(4));
+
+    uint8_t *srcbis = src - (srcStride * 2);
+
+    const vec_u8 srcM2a = vec_ld(0, srcbis);
+    const vec_u8 srcM2b = vec_ld(16, srcbis);
+    const vec_u8 srcM2 = vec_perm(srcM2a, srcM2b, perm);
+    //srcbis += srcStride;
+    const vec_u8 srcM1a = vec_ld(0, srcbis += srcStride);
+    const vec_u8 srcM1b = vec_ld(16, srcbis);
+    const vec_u8 srcM1 = vec_perm(srcM1a, srcM1b, perm);
+    //srcbis += srcStride;
+    const vec_u8 srcP0a = vec_ld(0, srcbis += srcStride);
+    const vec_u8 srcP0b = vec_ld(16, srcbis);
+    const vec_u8 srcP0 = vec_perm(srcP0a, srcP0b, perm);
+    //srcbis += srcStride;
+    const vec_u8 srcP1a = vec_ld(0, srcbis += srcStride);
+    const vec_u8 srcP1b = vec_ld(16, srcbis);
+    const vec_u8 srcP1 = vec_perm(srcP1a, srcP1b, perm);
+    //srcbis += srcStride;
+    const vec_u8 srcP2a = vec_ld(0, srcbis += srcStride);
+    const vec_u8 srcP2b = vec_ld(16, srcbis);
+    const vec_u8 srcP2 = vec_perm(srcP2a, srcP2b, perm);
+    //srcbis += srcStride;
+
+    vec_s16 srcM2ssA = (vec_s16) vec_mergeh(zero_u8v, srcM2);
+    vec_s16 srcM2ssB = (vec_s16) vec_mergel(zero_u8v, srcM2);
+    vec_s16 srcM1ssA = (vec_s16) vec_mergeh(zero_u8v, srcM1);
+    vec_s16 srcM1ssB = (vec_s16) vec_mergel(zero_u8v, srcM1);
+    vec_s16 srcP0ssA = (vec_s16) vec_mergeh(zero_u8v, srcP0);
+    vec_s16 srcP0ssB = (vec_s16) vec_mergel(zero_u8v, srcP0);
+    vec_s16 srcP1ssA = (vec_s16) vec_mergeh(zero_u8v, srcP1);
+    vec_s16 srcP1ssB = (vec_s16) vec_mergel(zero_u8v, srcP1);
+    vec_s16 srcP2ssA = (vec_s16) vec_mergeh(zero_u8v, srcP2);
+    vec_s16 srcP2ssB = (vec_s16) vec_mergel(zero_u8v, srcP2);
+
+    vec_s16 pp1A, pp1B, pp2A, pp2B, pp3A, pp3B,
+              psumA, psumB, sumA, sumB,
+              srcP3ssA, srcP3ssB,
+              sum1A, sum1B, sum2A, sum2B, sum3A, sum3B;
+
+    vec_u8 sum, fsum, srcP3a, srcP3b, srcP3;
+
+    for (i = 0 ; i < 16 ; i++) {
+        srcP3a = vec_ld(0, srcbis += srcStride);
+        srcP3b = vec_ld(16, srcbis);
+        srcP3 = vec_perm(srcP3a, srcP3b, perm);
+        srcP3ssA = (vec_s16) vec_mergeh(zero_u8v, srcP3);
+        srcP3ssB = (vec_s16) vec_mergel(zero_u8v, srcP3);
+        //srcbis += srcStride;
+
+        sum1A = vec_adds(srcP0ssA, srcP1ssA);
+        sum1B = vec_adds(srcP0ssB, srcP1ssB);
+        sum2A = vec_adds(srcM1ssA, srcP2ssA);
+        sum2B = vec_adds(srcM1ssB, srcP2ssB);
+        sum3A = vec_adds(srcM2ssA, srcP3ssA);
+        sum3B = vec_adds(srcM2ssB, srcP3ssB);
+
+        srcM2ssA = srcM1ssA;
+        srcM2ssB = srcM1ssB;
+        srcM1ssA = srcP0ssA;
+        srcM1ssB = srcP0ssB;
+        srcP0ssA = srcP1ssA;
+        srcP0ssB = srcP1ssB;
+        srcP1ssA = srcP2ssA;
+        srcP1ssB = srcP2ssB;
+        srcP2ssA = srcP3ssA;
+        srcP2ssB = srcP3ssB;
+
+        pp1A = vec_mladd(sum1A, v20ss, v16ss);
+        pp1B = vec_mladd(sum1B, v20ss, v16ss);
+
+        pp2A = vec_mladd(sum2A, v5ss, zero_s16v);
+        pp2B = vec_mladd(sum2B, v5ss, zero_s16v);
+
+        pp3A = vec_add(sum3A, pp1A);
+        pp3B = vec_add(sum3B, pp1B);
+
+        psumA = vec_sub(pp3A, pp2A);
+        psumB = vec_sub(pp3B, pp2B);
+
+        sumA = vec_sra(psumA, v5us);
+        sumB = vec_sra(psumB, v5us);
+
+        sum = vec_packsu(sumA, sumB);
+
+        ASSERT_ALIGNED(dst);
+
+        OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst));
+
+        vec_st(fsum, 0, dst);
+
+        dst += dstStride;
+    }
+}
+#endif
+
+/* this code assume stride % 16 == 0 *and* tmp is properly aligned */
+#ifdef PREFIX_h264_qpel16_hv_lowpass_altivec
+static void PREFIX_h264_qpel16_hv_lowpass_altivec(uint8_t * dst, int16_t * tmp, uint8_t * src, int dstStride, int tmpStride, int srcStride) {
+    register int i;
+    LOAD_ZERO;
+    const vec_u8 permM2 = vec_lvsl(-2, src);
+    const vec_u8 permM1 = vec_lvsl(-1, src);
+    const vec_u8 permP0 = vec_lvsl(+0, src);
+    const vec_u8 permP1 = vec_lvsl(+1, src);
+    const vec_u8 permP2 = vec_lvsl(+2, src);
+    const vec_u8 permP3 = vec_lvsl(+3, src);
+    const vec_s16 v20ss = vec_sl(vec_splat_s16(5),vec_splat_u16(2));
+    const vec_u32 v10ui = vec_splat_u32(10);
+    const vec_s16 v5ss = vec_splat_s16(5);
+    const vec_s16 v1ss = vec_splat_s16(1);
+    const vec_s32 v512si = vec_sl(vec_splat_s32(1),vec_splat_u32(9));
+    const vec_u32 v16ui = vec_sl(vec_splat_u32(1),vec_splat_u32(4));
+
+    register int align = ((((unsigned long)src) - 2) % 16);
+
+    vec_s16 srcP0A, srcP0B, srcP1A, srcP1B,
+              srcP2A, srcP2B, srcP3A, srcP3B,
+              srcM1A, srcM1B, srcM2A, srcM2B,
+              sum1A, sum1B, sum2A, sum2B, sum3A, sum3B,
+              pp1A, pp1B, pp2A, pp2B, psumA, psumB;
+
+    const vec_u8 mperm = (const vec_u8)
+        {0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B,
+         0x04, 0x0C, 0x05, 0x0D, 0x06, 0x0E, 0x07, 0x0F};
+    int16_t *tmpbis = tmp;
+
+    vec_s16 tmpM1ssA, tmpM1ssB, tmpM2ssA, tmpM2ssB,
+              tmpP0ssA, tmpP0ssB, tmpP1ssA, tmpP1ssB,
+              tmpP2ssA, tmpP2ssB;
+
+    vec_s32 pp1Ae, pp1Ao, pp1Be, pp1Bo, pp2Ae, pp2Ao, pp2Be, pp2Bo,
+              pp3Ae, pp3Ao, pp3Be, pp3Bo, pp1cAe, pp1cAo, pp1cBe, pp1cBo,
+              pp32Ae, pp32Ao, pp32Be, pp32Bo, sumAe, sumAo, sumBe, sumBo,
+              ssumAe, ssumAo, ssumBe, ssumBo;
+    vec_u8 fsum, sumv, sum;
+    vec_s16 ssume, ssumo;
+
+    src -= (2 * srcStride);
+    for (i = 0 ; i < 21 ; i ++) {
+        vec_u8 srcM2, srcM1, srcP0, srcP1, srcP2, srcP3;
+        vec_u8 srcR1 = vec_ld(-2, src);
+        vec_u8 srcR2 = vec_ld(14, src);
+
+        switch (align) {
+        default: {
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = vec_perm(srcR1, srcR2, permP0);
+            srcP1 = vec_perm(srcR1, srcR2, permP1);
+            srcP2 = vec_perm(srcR1, srcR2, permP2);
+            srcP3 = vec_perm(srcR1, srcR2, permP3);
+        } break;
+        case 11: {
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = vec_perm(srcR1, srcR2, permP0);
+            srcP1 = vec_perm(srcR1, srcR2, permP1);
+            srcP2 = vec_perm(srcR1, srcR2, permP2);
+            srcP3 = srcR2;
+        } break;
+        case 12: {
+            vec_u8 srcR3 = vec_ld(30, src);
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = vec_perm(srcR1, srcR2, permP0);
+            srcP1 = vec_perm(srcR1, srcR2, permP1);
+            srcP2 = srcR2;
+            srcP3 = vec_perm(srcR2, srcR3, permP3);
+        } break;
+        case 13: {
+            vec_u8 srcR3 = vec_ld(30, src);
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = vec_perm(srcR1, srcR2, permP0);
+            srcP1 = srcR2;
+            srcP2 = vec_perm(srcR2, srcR3, permP2);
+            srcP3 = vec_perm(srcR2, srcR3, permP3);
+        } break;
+        case 14: {
+            vec_u8 srcR3 = vec_ld(30, src);
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = vec_perm(srcR1, srcR2, permM1);
+            srcP0 = srcR2;
+            srcP1 = vec_perm(srcR2, srcR3, permP1);
+            srcP2 = vec_perm(srcR2, srcR3, permP2);
+            srcP3 = vec_perm(srcR2, srcR3, permP3);
+        } break;
+        case 15: {
+            vec_u8 srcR3 = vec_ld(30, src);
+            srcM2 = vec_perm(srcR1, srcR2, permM2);
+            srcM1 = srcR2;
+            srcP0 = vec_perm(srcR2, srcR3, permP0);
+            srcP1 = vec_perm(srcR2, srcR3, permP1);
+            srcP2 = vec_perm(srcR2, srcR3, permP2);
+            srcP3 = vec_perm(srcR2, srcR3, permP3);
+        } break;
+        }
+
+        srcP0A = (vec_s16) vec_mergeh(zero_u8v, srcP0);
+        srcP0B = (vec_s16) vec_mergel(zero_u8v, srcP0);
+        srcP1A = (vec_s16) vec_mergeh(zero_u8v, srcP1);
+        srcP1B = (vec_s16) vec_mergel(zero_u8v, srcP1);
+
+        srcP2A = (vec_s16) vec_mergeh(zero_u8v, srcP2);
+        srcP2B = (vec_s16) vec_mergel(zero_u8v, srcP2);
+        srcP3A = (vec_s16) vec_mergeh(zero_u8v, srcP3);
+        srcP3B = (vec_s16) vec_mergel(zero_u8v, srcP3);
+
+        srcM1A = (vec_s16) vec_mergeh(zero_u8v, srcM1);
+        srcM1B = (vec_s16) vec_mergel(zero_u8v, srcM1);
+        srcM2A = (vec_s16) vec_mergeh(zero_u8v, srcM2);
+        srcM2B = (vec_s16) vec_mergel(zero_u8v, srcM2);
+
+        sum1A = vec_adds(srcP0A, srcP1A);
+        sum1B = vec_adds(srcP0B, srcP1B);
+        sum2A = vec_adds(srcM1A, srcP2A);
+        sum2B = vec_adds(srcM1B, srcP2B);
+        sum3A = vec_adds(srcM2A, srcP3A);
+        sum3B = vec_adds(srcM2B, srcP3B);
+
+        pp1A = vec_mladd(sum1A, v20ss, sum3A);
+        pp1B = vec_mladd(sum1B, v20ss, sum3B);
+
+        pp2A = vec_mladd(sum2A, v5ss, zero_s16v);
+        pp2B = vec_mladd(sum2B, v5ss, zero_s16v);
+
+        psumA = vec_sub(pp1A, pp2A);
+        psumB = vec_sub(pp1B, pp2B);
+
+        vec_st(psumA, 0, tmp);
+        vec_st(psumB, 16, tmp);
+
+        src += srcStride;
+        tmp += tmpStride; /* int16_t*, and stride is 16, so it's OK here */
+    }
+
+    tmpM2ssA = vec_ld(0, tmpbis);
+    tmpM2ssB = vec_ld(16, tmpbis);
+    tmpbis += tmpStride;
+    tmpM1ssA = vec_ld(0, tmpbis);
+    tmpM1ssB = vec_ld(16, tmpbis);
+    tmpbis += tmpStride;
+    tmpP0ssA = vec_ld(0, tmpbis);
+    tmpP0ssB = vec_ld(16, tmpbis);
+    tmpbis += tmpStride;
+    tmpP1ssA = vec_ld(0, tmpbis);
+    tmpP1ssB = vec_ld(16, tmpbis);
+    tmpbis += tmpStride;
+    tmpP2ssA = vec_ld(0, tmpbis);
+    tmpP2ssB = vec_ld(16, tmpbis);
+    tmpbis += tmpStride;
+
+    for (i = 0 ; i < 16 ; i++) {
+        const vec_s16 tmpP3ssA = vec_ld(0, tmpbis);
+        const vec_s16 tmpP3ssB = vec_ld(16, tmpbis);
+
+        const vec_s16 sum1A = vec_adds(tmpP0ssA, tmpP1ssA);
+        const vec_s16 sum1B = vec_adds(tmpP0ssB, tmpP1ssB);
+        const vec_s16 sum2A = vec_adds(tmpM1ssA, tmpP2ssA);
+        const vec_s16 sum2B = vec_adds(tmpM1ssB, tmpP2ssB);
+        const vec_s16 sum3A = vec_adds(tmpM2ssA, tmpP3ssA);
+        const vec_s16 sum3B = vec_adds(tmpM2ssB, tmpP3ssB);
+
+        tmpbis += tmpStride;
+
+        tmpM2ssA = tmpM1ssA;
+        tmpM2ssB = tmpM1ssB;
+        tmpM1ssA = tmpP0ssA;
+        tmpM1ssB = tmpP0ssB;
+        tmpP0ssA = tmpP1ssA;
+        tmpP0ssB = tmpP1ssB;
+        tmpP1ssA = tmpP2ssA;
+        tmpP1ssB = tmpP2ssB;
+        tmpP2ssA = tmpP3ssA;
+        tmpP2ssB = tmpP3ssB;
+
+        pp1Ae = vec_mule(sum1A, v20ss);
+        pp1Ao = vec_mulo(sum1A, v20ss);
+        pp1Be = vec_mule(sum1B, v20ss);
+        pp1Bo = vec_mulo(sum1B, v20ss);
+
+        pp2Ae = vec_mule(sum2A, v5ss);
+        pp2Ao = vec_mulo(sum2A, v5ss);
+        pp2Be = vec_mule(sum2B, v5ss);
+        pp2Bo = vec_mulo(sum2B, v5ss);
+
+        pp3Ae = vec_sra((vec_s32)sum3A, v16ui);
+        pp3Ao = vec_mulo(sum3A, v1ss);
+        pp3Be = vec_sra((vec_s32)sum3B, v16ui);
+        pp3Bo = vec_mulo(sum3B, v1ss);
+
+        pp1cAe = vec_add(pp1Ae, v512si);
+        pp1cAo = vec_add(pp1Ao, v512si);
+        pp1cBe = vec_add(pp1Be, v512si);
+        pp1cBo = vec_add(pp1Bo, v512si);
+
+        pp32Ae = vec_sub(pp3Ae, pp2Ae);
+        pp32Ao = vec_sub(pp3Ao, pp2Ao);
+        pp32Be = vec_sub(pp3Be, pp2Be);
+        pp32Bo = vec_sub(pp3Bo, pp2Bo);
+
+        sumAe = vec_add(pp1cAe, pp32Ae);
+        sumAo = vec_add(pp1cAo, pp32Ao);
+        sumBe = vec_add(pp1cBe, pp32Be);
+        sumBo = vec_add(pp1cBo, pp32Bo);
+
+        ssumAe = vec_sra(sumAe, v10ui);
+        ssumAo = vec_sra(sumAo, v10ui);
+        ssumBe = vec_sra(sumBe, v10ui);
+        ssumBo = vec_sra(sumBo, v10ui);
+
+        ssume = vec_packs(ssumAe, ssumBe);
+        ssumo = vec_packs(ssumAo, ssumBo);
+
+        sumv = vec_packsu(ssume, ssumo);
+        sum = vec_perm(sumv, sumv, mperm);
+
+        ASSERT_ALIGNED(dst);
+
+        OP_U8_ALTIVEC(fsum, sum, vec_ld(0, dst));
+
+        vec_st(fsum, 0, dst);
+
+        dst += dstStride;
+    }
+}
+#endif
diff --git a/libavcodec/ppc/hpeldsp_altivec.c b/libavcodec/ppc/hpeldsp_altivec.c
new file mode 100644
index 0000000..d40c5d8
--- /dev/null
+++ b/libavcodec/ppc/hpeldsp_altivec.c
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2002 Brian Foley
+ * Copyright (c) 2002 Dieter Shirley
+ * Copyright (c) 2003-2004 Romain Dolbeau <romain at dolbeau.org>
+ *
+ * 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_ALTIVEC_H
+#include <altivec.h>
+#endif
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/ppc/types_altivec.h"
+#include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/hpeldsp.h"
+#include "dsputil_altivec.h"
+
+#if HAVE_ALTIVEC
+/* next one assumes that ((line_size % 16) == 0) */
+void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    register vector unsigned char pixelsv1, pixelsv2;
+    register vector unsigned char pixelsv1B, pixelsv2B;
+    register vector unsigned char pixelsv1C, pixelsv2C;
+    register vector unsigned char pixelsv1D, pixelsv2D;
+
+    register vector unsigned char perm = vec_lvsl(0, pixels);
+    int i;
+    register ptrdiff_t line_size_2 = line_size << 1;
+    register ptrdiff_t line_size_3 = line_size + line_size_2;
+    register ptrdiff_t line_size_4 = line_size << 2;
+
+// hand-unrolling the loop by 4 gains about 15%
+// mininum execution time goes from 74 to 60 cycles
+// it's faster than -funroll-loops, but using
+// -funroll-loops w/ this is bad - 74 cycles again.
+// all this is on a 7450, tuning for the 7450
+    for (i = 0; i < h; i += 4) {
+        pixelsv1  = vec_ld( 0, pixels);
+        pixelsv2  = vec_ld(15, pixels);
+        pixelsv1B = vec_ld(line_size, pixels);
+        pixelsv2B = vec_ld(15 + line_size, pixels);
+        pixelsv1C = vec_ld(line_size_2, pixels);
+        pixelsv2C = vec_ld(15 + line_size_2, pixels);
+        pixelsv1D = vec_ld(line_size_3, pixels);
+        pixelsv2D = vec_ld(15 + line_size_3, pixels);
+        vec_st(vec_perm(pixelsv1, pixelsv2, perm),
+               0, (unsigned char*)block);
+        vec_st(vec_perm(pixelsv1B, pixelsv2B, perm),
+               line_size, (unsigned char*)block);
+        vec_st(vec_perm(pixelsv1C, pixelsv2C, perm),
+               line_size_2, (unsigned char*)block);
+        vec_st(vec_perm(pixelsv1D, pixelsv2D, perm),
+               line_size_3, (unsigned char*)block);
+        pixels+=line_size_4;
+        block +=line_size_4;
+    }
+}
+
+/* next one assumes that ((line_size % 16) == 0) */
+#define op_avg(a,b)  a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) )
+void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
+    register vector unsigned char perm = vec_lvsl(0, pixels);
+    int i;
+
+    for (i = 0; i < h; i++) {
+        pixelsv1 = vec_ld( 0, pixels);
+        pixelsv2 = vec_ld(16,pixels);
+        blockv = vec_ld(0, block);
+        pixelsv = vec_perm(pixelsv1, pixelsv2, perm);
+        blockv = vec_avg(blockv,pixelsv);
+        vec_st(blockv, 0, (unsigned char*)block);
+        pixels+=line_size;
+        block +=line_size;
+    }
+}
+
+/* next one assumes that ((line_size % 8) == 0) */
+static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff_t line_size, int h)
+{
+    register vector unsigned char pixelsv1, pixelsv2, pixelsv, blockv;
+    int i;
+
+   for (i = 0; i < h; i++) {
+       /* block is 8 bytes-aligned, so we're either in the
+          left block (16 bytes-aligned) or in the right block (not) */
+       int rightside = ((unsigned long)block & 0x0000000F);
+
+       blockv = vec_ld(0, block);
+       pixelsv1 = vec_ld( 0, pixels);
+       pixelsv2 = vec_ld(16, pixels);
+       pixelsv = vec_perm(pixelsv1, pixelsv2, vec_lvsl(0, pixels));
+
+       if (rightside) {
+           pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
+       } else {
+           pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3));
+       }
+
+       blockv = vec_avg(blockv, pixelsv);
+
+       vec_st(blockv, 0, block);
+
+       pixels += line_size;
+       block += line_size;
+   }
+}
+
+/* next one assumes that ((line_size % 8) == 0) */
+static void put_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    register int i;
+    register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
+    register vector unsigned char blockv, temp1, temp2;
+    register vector unsigned short pixelssum1, pixelssum2, temp3;
+    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
+    register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
+
+    temp1 = vec_ld(0, pixels);
+    temp2 = vec_ld(16, pixels);
+    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
+    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
+        pixelsv2 = temp2;
+    } else {
+        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
+    }
+    pixelsv1 = vec_mergeh(vczero, pixelsv1);
+    pixelsv2 = vec_mergeh(vczero, pixelsv2);
+    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
+                         (vector unsigned short)pixelsv2);
+    pixelssum1 = vec_add(pixelssum1, vctwo);
+
+    for (i = 0; i < h ; i++) {
+        int rightside = ((unsigned long)block & 0x0000000F);
+        blockv = vec_ld(0, block);
+
+        temp1 = vec_ld(line_size, pixels);
+        temp2 = vec_ld(line_size + 16, pixels);
+        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
+        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
+            pixelsv2 = temp2;
+        } else {
+            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
+        }
+
+        pixelsv1 = vec_mergeh(vczero, pixelsv1);
+        pixelsv2 = vec_mergeh(vczero, pixelsv2);
+        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
+                             (vector unsigned short)pixelsv2);
+        temp3 = vec_add(pixelssum1, pixelssum2);
+        temp3 = vec_sra(temp3, vctwo);
+        pixelssum1 = vec_add(pixelssum2, vctwo);
+        pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
+
+        if (rightside) {
+            blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
+        } else {
+            blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
+        }
+
+        vec_st(blockv, 0, block);
+
+        block += line_size;
+        pixels += line_size;
+    }
+}
+
+/* next one assumes that ((line_size % 8) == 0) */
+static void put_no_rnd_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    register int i;
+    register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
+    register vector unsigned char blockv, temp1, temp2;
+    register vector unsigned short pixelssum1, pixelssum2, temp3;
+    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
+    register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);
+    register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
+
+    temp1 = vec_ld(0, pixels);
+    temp2 = vec_ld(16, pixels);
+    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
+    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
+        pixelsv2 = temp2;
+    } else {
+        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
+    }
+    pixelsv1 = vec_mergeh(vczero, pixelsv1);
+    pixelsv2 = vec_mergeh(vczero, pixelsv2);
+    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
+                         (vector unsigned short)pixelsv2);
+    pixelssum1 = vec_add(pixelssum1, vcone);
+
+    for (i = 0; i < h ; i++) {
+        int rightside = ((unsigned long)block & 0x0000000F);
+        blockv = vec_ld(0, block);
+
+        temp1 = vec_ld(line_size, pixels);
+        temp2 = vec_ld(line_size + 16, pixels);
+        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
+        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
+            pixelsv2 = temp2;
+        } else {
+            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
+        }
+
+        pixelsv1 = vec_mergeh(vczero, pixelsv1);
+        pixelsv2 = vec_mergeh(vczero, pixelsv2);
+        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
+                             (vector unsigned short)pixelsv2);
+        temp3 = vec_add(pixelssum1, pixelssum2);
+        temp3 = vec_sra(temp3, vctwo);
+        pixelssum1 = vec_add(pixelssum2, vcone);
+        pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
+
+        if (rightside) {
+            blockv = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
+        } else {
+            blockv = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
+        }
+
+        vec_st(blockv, 0, block);
+
+        block += line_size;
+        pixels += line_size;
+    }
+}
+
+/* next one assumes that ((line_size % 16) == 0) */
+static void put_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff_t line_size, int h)
+{
+    register int i;
+    register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4;
+    register vector unsigned char blockv, temp1, temp2;
+    register vector unsigned short temp3, temp4,
+        pixelssum1, pixelssum2, pixelssum3, pixelssum4;
+    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
+    register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
+
+    temp1 = vec_ld(0, pixels);
+    temp2 = vec_ld(16, pixels);
+    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
+    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
+        pixelsv2 = temp2;
+    } else {
+        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
+    }
+    pixelsv3 = vec_mergel(vczero, pixelsv1);
+    pixelsv4 = vec_mergel(vczero, pixelsv2);
+    pixelsv1 = vec_mergeh(vczero, pixelsv1);
+    pixelsv2 = vec_mergeh(vczero, pixelsv2);
+    pixelssum3 = vec_add((vector unsigned short)pixelsv3,
+                         (vector unsigned short)pixelsv4);
+    pixelssum3 = vec_add(pixelssum3, vctwo);
+    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
+                         (vector unsigned short)pixelsv2);
+    pixelssum1 = vec_add(pixelssum1, vctwo);
+
+    for (i = 0; i < h ; i++) {
+        blockv = vec_ld(0, block);
+
+        temp1 = vec_ld(line_size, pixels);
+        temp2 = vec_ld(line_size + 16, pixels);
+        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
+        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
+            pixelsv2 = temp2;
+        } else {
+            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
+        }
+
+        pixelsv3 = vec_mergel(vczero, pixelsv1);
+        pixelsv4 = vec_mergel(vczero, pixelsv2);
+        pixelsv1 = vec_mergeh(vczero, pixelsv1);
+        pixelsv2 = vec_mergeh(vczero, pixelsv2);
+
+        pixelssum4 = vec_add((vector unsigned short)pixelsv3,
+                             (vector unsigned short)pixelsv4);
+        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
+                             (vector unsigned short)pixelsv2);
+        temp4 = vec_add(pixelssum3, pixelssum4);
+        temp4 = vec_sra(temp4, vctwo);
+        temp3 = vec_add(pixelssum1, pixelssum2);
+        temp3 = vec_sra(temp3, vctwo);
+
+        pixelssum3 = vec_add(pixelssum4, vctwo);
+        pixelssum1 = vec_add(pixelssum2, vctwo);
+
+        blockv = vec_packsu(temp3, temp4);
+
+        vec_st(blockv, 0, block);
+
+        block += line_size;
+        pixels += line_size;
+    }
+}
+
+/* next one assumes that ((line_size % 16) == 0) */
+static void put_no_rnd_pixels16_xy2_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff_t line_size, int h)
+{
+    register int i;
+    register vector unsigned char pixelsv1, pixelsv2, pixelsv3, pixelsv4;
+    register vector unsigned char blockv, temp1, temp2;
+    register vector unsigned short temp3, temp4,
+        pixelssum1, pixelssum2, pixelssum3, pixelssum4;
+    register const vector unsigned char vczero = (const vector unsigned char)vec_splat_u8(0);
+    register const vector unsigned short vcone = (const vector unsigned short)vec_splat_u16(1);
+    register const vector unsigned short vctwo = (const vector unsigned short)vec_splat_u16(2);
+
+    temp1 = vec_ld(0, pixels);
+    temp2 = vec_ld(16, pixels);
+    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
+    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
+        pixelsv2 = temp2;
+    } else {
+        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
+    }
+    pixelsv3 = vec_mergel(vczero, pixelsv1);
+    pixelsv4 = vec_mergel(vczero, pixelsv2);
+    pixelsv1 = vec_mergeh(vczero, pixelsv1);
+    pixelsv2 = vec_mergeh(vczero, pixelsv2);
+    pixelssum3 = vec_add((vector unsigned short)pixelsv3,
+                         (vector unsigned short)pixelsv4);
+    pixelssum3 = vec_add(pixelssum3, vcone);
+    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
+                         (vector unsigned short)pixelsv2);
+    pixelssum1 = vec_add(pixelssum1, vcone);
+
+    for (i = 0; i < h ; i++) {
+        blockv = vec_ld(0, block);
+
+        temp1 = vec_ld(line_size, pixels);
+        temp2 = vec_ld(line_size + 16, pixels);
+        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
+        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
+            pixelsv2 = temp2;
+        } else {
+            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
+        }
+
+        pixelsv3 = vec_mergel(vczero, pixelsv1);
+        pixelsv4 = vec_mergel(vczero, pixelsv2);
+        pixelsv1 = vec_mergeh(vczero, pixelsv1);
+        pixelsv2 = vec_mergeh(vczero, pixelsv2);
+
+        pixelssum4 = vec_add((vector unsigned short)pixelsv3,
+                             (vector unsigned short)pixelsv4);
+        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
+                             (vector unsigned short)pixelsv2);
+        temp4 = vec_add(pixelssum3, pixelssum4);
+        temp4 = vec_sra(temp4, vctwo);
+        temp3 = vec_add(pixelssum1, pixelssum2);
+        temp3 = vec_sra(temp3, vctwo);
+
+        pixelssum3 = vec_add(pixelssum4, vcone);
+        pixelssum1 = vec_add(pixelssum2, vcone);
+
+        blockv = vec_packsu(temp3, temp4);
+
+        vec_st(blockv, 0, block);
+
+        block += line_size;
+        pixels += line_size;
+    }
+}
+
+/* next one assumes that ((line_size % 8) == 0) */
+static void avg_pixels8_xy2_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    register int i;
+    register vector unsigned char pixelsv1, pixelsv2, pixelsavg;
+    register vector unsigned char blockv, temp1, temp2, blocktemp;
+    register vector unsigned short pixelssum1, pixelssum2, temp3;
+
+    register const vector unsigned char vczero = (const vector unsigned char)
+                                        vec_splat_u8(0);
+    register const vector unsigned short vctwo = (const vector unsigned short)
+                                        vec_splat_u16(2);
+
+    temp1 = vec_ld(0, pixels);
+    temp2 = vec_ld(16, pixels);
+    pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(0, pixels));
+    if ((((unsigned long)pixels) & 0x0000000F) ==  0x0000000F) {
+        pixelsv2 = temp2;
+    } else {
+        pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(1, pixels));
+    }
+    pixelsv1 = vec_mergeh(vczero, pixelsv1);
+    pixelsv2 = vec_mergeh(vczero, pixelsv2);
+    pixelssum1 = vec_add((vector unsigned short)pixelsv1,
+                         (vector unsigned short)pixelsv2);
+    pixelssum1 = vec_add(pixelssum1, vctwo);
+
+    for (i = 0; i < h ; i++) {
+        int rightside = ((unsigned long)block & 0x0000000F);
+        blockv = vec_ld(0, block);
+
+        temp1 = vec_ld(line_size, pixels);
+        temp2 = vec_ld(line_size + 16, pixels);
+        pixelsv1 = vec_perm(temp1, temp2, vec_lvsl(line_size, pixels));
+        if (((((unsigned long)pixels) + line_size) & 0x0000000F) ==  0x0000000F) {
+            pixelsv2 = temp2;
+        } else {
+            pixelsv2 = vec_perm(temp1, temp2, vec_lvsl(line_size + 1, pixels));
+        }
+
+        pixelsv1 = vec_mergeh(vczero, pixelsv1);
+        pixelsv2 = vec_mergeh(vczero, pixelsv2);
+        pixelssum2 = vec_add((vector unsigned short)pixelsv1,
+                             (vector unsigned short)pixelsv2);
+        temp3 = vec_add(pixelssum1, pixelssum2);
+        temp3 = vec_sra(temp3, vctwo);
+        pixelssum1 = vec_add(pixelssum2, vctwo);
+        pixelsavg = vec_packsu(temp3, (vector unsigned short) vczero);
+
+        if (rightside) {
+            blocktemp = vec_perm(blockv, pixelsavg, vcprm(0, 1, s0, s1));
+        } else {
+            blocktemp = vec_perm(blockv, pixelsavg, vcprm(s0, s1, 2, 3));
+        }
+
+        blockv = vec_avg(blocktemp, blockv);
+        vec_st(blockv, 0, block);
+
+        block += line_size;
+        pixels += line_size;
+    }
+}
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags)
+{
+#if HAVE_ALTIVEC
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
+    c->avg_pixels_tab[0][0]        = ff_avg_pixels16_altivec;
+    c->avg_pixels_tab[1][0]        = avg_pixels8_altivec;
+    c->avg_pixels_tab[1][3]        = avg_pixels8_xy2_altivec;
+
+    c->put_pixels_tab[0][0]        = ff_put_pixels16_altivec;
+    c->put_pixels_tab[1][3]        = put_pixels8_xy2_altivec;
+    c->put_pixels_tab[0][3]        = put_pixels16_xy2_altivec;
+
+    c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_altivec;
+    c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_altivec;
+    c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_altivec;
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/idct_altivec.c b/libavcodec/ppc/idct_altivec.c
index e599491..f68a61d 100644
--- a/libavcodec/ppc/idct_altivec.c
+++ b/libavcodec/ppc/idct_altivec.c
@@ -42,7 +42,6 @@
 #include <altivec.h>
 #endif
 #include "libavutil/ppc/types_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "dsputil_altivec.h"
 
 #define IDCT_HALF                                       \
diff --git a/libavcodec/ppc/int_altivec.c b/libavcodec/ppc/int_altivec.c
index 4fcdf77..38ec99b 100644
--- a/libavcodec/ppc/int_altivec.c
+++ b/libavcodec/ppc/int_altivec.c
@@ -28,6 +28,7 @@
 #include <altivec.h>
 #endif
 
+#include "libavutil/attributes.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavcodec/dsputil.h"
 
@@ -83,14 +84,12 @@ static int32_t scalarproduct_int16_altivec(const int16_t *v1, const int16_t *v2,
 {
     int i;
     LOAD_ZERO;
-    const vec_s16 *pv;
     register vec_s16 vec1;
     register vec_s32 res = vec_splat_s32(0), t;
     int32_t ires;
 
     for(i = 0; i < order; i += 8){
-        pv = (const vec_s16*)v1;
-        vec1 = vec_perm(pv[0], pv[1], vec_lvsl(0, v1));
+        vec1 = vec_unaligned_load(v1);
         t = vec_msum(vec1, vec_ld(0, v2), zero_s32v);
         res = vec_sums(t, res);
         v1 += 8;
@@ -128,15 +127,15 @@ static int32_t scalarproduct_and_madd_int16_altivec(int16_t *v1, const int16_t *
         pv1[0] = vec_mladd(t0, muls, i0);
         pv1[1] = vec_mladd(t1, muls, i1);
         pv1 += 2;
-        v2  += 8;
-        v3  += 8;
+        v2  += 16;
+        v3  += 16;
     } while(--order);
     res = vec_splat(vec_sums(res, zero_s32v), 3);
     vec_ste(res, 0, &ires);
     return ires;
 }
 
-void ff_int_init_altivec(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_int_init_altivec(DSPContext *c, AVCodecContext *avctx)
 {
     c->ssd_int8_vs_int16 = ssd_int8_vs_int16_altivec;
     c->scalarproduct_int16 = scalarproduct_int16_altivec;
diff --git a/libavcodec/ppc/mpegaudiodec_altivec.c b/libavcodec/ppc/mpegaudiodec_altivec.c
deleted file mode 100644
index fabde6a..0000000
--- a/libavcodec/ppc/mpegaudiodec_altivec.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Altivec optimized MP3 decoding functions
- * Copyright (c) 2010 Vitor Sessak
- *
- * 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 "dsputil_altivec.h"
-#include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
-#include "libavcodec/mpegaudiodsp.h"
-
-#define MACS(rt, ra, rb) rt+=(ra)*(rb)
-#define MLSS(rt, ra, rb) rt-=(ra)*(rb)
-
-#define SUM8(op, sum, w, p)               \
-{                                         \
-    op(sum, (w)[0 * 64], (p)[0 * 64]);    \
-    op(sum, (w)[1 * 64], (p)[1 * 64]);    \
-    op(sum, (w)[2 * 64], (p)[2 * 64]);    \
-    op(sum, (w)[3 * 64], (p)[3 * 64]);    \
-    op(sum, (w)[4 * 64], (p)[4 * 64]);    \
-    op(sum, (w)[5 * 64], (p)[5 * 64]);    \
-    op(sum, (w)[6 * 64], (p)[6 * 64]);    \
-    op(sum, (w)[7 * 64], (p)[7 * 64]);    \
-}
-
-static void apply_window(const float *buf, const float *win1,
-                         const float *win2, float *sum1, float *sum2, int len)
-{
-    const vector float *win1a = (const vector float *) win1;
-    const vector float *win2a = (const vector float *) win2;
-    const vector float *bufa  = (const vector float *) buf;
-    vector float *sum1a = (vector float *) sum1;
-    vector float *sum2a = (vector float *) sum2;
-    vector float av_uninit(v0), av_uninit(v4);
-    vector float v1, v2, v3;
-
-    len = len >> 2;
-
-#define MULT(a, b)                         \
-    {                                      \
-        v1 = vec_ld(a, win1a);             \
-        v2 = vec_ld(b, win2a);             \
-        v3 = vec_ld(a, bufa);              \
-        v0 = vec_madd(v3, v1, v0);         \
-        v4 = vec_madd(v2, v3, v4);         \
-    }
-
-    while (len--) {
-        v0 = vec_xor(v0, v0);
-        v4 = vec_xor(v4, v4);
-
-        MULT(   0,   0);
-        MULT( 256,  64);
-        MULT( 512, 128);
-        MULT( 768, 192);
-        MULT(1024, 256);
-        MULT(1280, 320);
-        MULT(1536, 384);
-        MULT(1792, 448);
-
-        vec_st(v0, 0, sum1a);
-        vec_st(v4, 0, sum2a);
-        sum1a++;
-        sum2a++;
-        win1a++;
-        win2a++;
-        bufa++;
-    }
-}
-
-static void apply_window_mp3(float *in, float *win, int *unused, float *out,
-                             int incr)
-{
-    LOCAL_ALIGNED_16(float, suma, [17]);
-    LOCAL_ALIGNED_16(float, sumb, [17]);
-    LOCAL_ALIGNED_16(float, sumc, [17]);
-    LOCAL_ALIGNED_16(float, sumd, [17]);
-
-    float sum;
-    int j;
-    float *out2 = out + 32 * incr;
-
-    /* copy to avoid wrap */
-    memcpy(in + 512, in, 32 * sizeof(*in));
-
-    apply_window(in + 16, win     , win + 512, suma, sumc, 16);
-    apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16);
-
-    SUM8(MLSS, suma[0], win + 32, in + 48);
-
-    sumc[ 0] = 0;
-    sumb[16] = 0;
-    sumd[16] = 0;
-
-    out[0  ]  = suma[   0];
-    out += incr;
-    out2 -= incr;
-    for(j=1;j<16;j++) {
-        *out  =  suma[   j] - sumd[16-j];
-        *out2 = -sumb[16-j] - sumc[   j];
-        out  += incr;
-        out2 -= incr;
-    }
-
-    sum = 0;
-    SUM8(MLSS, sum, win + 16 + 32, in + 32);
-    *out = sum;
-}
-
-void ff_mpadsp_init_altivec(MPADSPContext *s)
-{
-    s->apply_window_float = apply_window_mp3;
-}
diff --git a/libavcodec/ppc/mpegaudiodsp_altivec.c b/libavcodec/ppc/mpegaudiodsp_altivec.c
new file mode 100644
index 0000000..6855c0b
--- /dev/null
+++ b/libavcodec/ppc/mpegaudiodsp_altivec.c
@@ -0,0 +1,141 @@
+/*
+ * Altivec optimized MP3 decoding functions
+ * Copyright (c) 2010 Vitor Sessak
+ *
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/internal.h"
+#include "libavutil/ppc/util_altivec.h"
+#include "libavcodec/mpegaudiodsp.h"
+#include "dsputil_altivec.h"
+
+#if HAVE_ALTIVEC
+
+#define MACS(rt, ra, rb) rt+=(ra)*(rb)
+#define MLSS(rt, ra, rb) rt-=(ra)*(rb)
+
+#define SUM8(op, sum, w, p)               \
+{                                         \
+    op(sum, (w)[0 * 64], (p)[0 * 64]);    \
+    op(sum, (w)[1 * 64], (p)[1 * 64]);    \
+    op(sum, (w)[2 * 64], (p)[2 * 64]);    \
+    op(sum, (w)[3 * 64], (p)[3 * 64]);    \
+    op(sum, (w)[4 * 64], (p)[4 * 64]);    \
+    op(sum, (w)[5 * 64], (p)[5 * 64]);    \
+    op(sum, (w)[6 * 64], (p)[6 * 64]);    \
+    op(sum, (w)[7 * 64], (p)[7 * 64]);    \
+}
+
+static void apply_window(const float *buf, const float *win1,
+                         const float *win2, float *sum1, float *sum2, int len)
+{
+    const vector float *win1a = (const vector float *) win1;
+    const vector float *win2a = (const vector float *) win2;
+    const vector float *bufa  = (const vector float *) buf;
+    vector float *sum1a = (vector float *) sum1;
+    vector float *sum2a = (vector float *) sum2;
+    vector float av_uninit(v0), av_uninit(v4);
+    vector float v1, v2, v3;
+
+    len = len >> 2;
+
+#define MULT(a, b)                         \
+    {                                      \
+        v1 = vec_ld(a, win1a);             \
+        v2 = vec_ld(b, win2a);             \
+        v3 = vec_ld(a, bufa);              \
+        v0 = vec_madd(v3, v1, v0);         \
+        v4 = vec_madd(v2, v3, v4);         \
+    }
+
+    while (len--) {
+        v0 = vec_xor(v0, v0);
+        v4 = vec_xor(v4, v4);
+
+        MULT(   0,   0);
+        MULT( 256,  64);
+        MULT( 512, 128);
+        MULT( 768, 192);
+        MULT(1024, 256);
+        MULT(1280, 320);
+        MULT(1536, 384);
+        MULT(1792, 448);
+
+        vec_st(v0, 0, sum1a);
+        vec_st(v4, 0, sum2a);
+        sum1a++;
+        sum2a++;
+        win1a++;
+        win2a++;
+        bufa++;
+    }
+}
+
+static void apply_window_mp3(float *in, float *win, int *unused, float *out,
+                             int incr)
+{
+    LOCAL_ALIGNED_16(float, suma, [17]);
+    LOCAL_ALIGNED_16(float, sumb, [17]);
+    LOCAL_ALIGNED_16(float, sumc, [17]);
+    LOCAL_ALIGNED_16(float, sumd, [17]);
+
+    float sum;
+    int j;
+    float *out2 = out + 32 * incr;
+
+    /* copy to avoid wrap */
+    memcpy(in + 512, in, 32 * sizeof(*in));
+
+    apply_window(in + 16, win     , win + 512, suma, sumc, 16);
+    apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16);
+
+    SUM8(MLSS, suma[0], win + 32, in + 48);
+
+    sumc[ 0] = 0;
+    sumb[16] = 0;
+    sumd[16] = 0;
+
+    out[0  ]  = suma[   0];
+    out += incr;
+    out2 -= incr;
+    for(j=1;j<16;j++) {
+        *out  =  suma[   j] - sumd[16-j];
+        *out2 = -sumb[16-j] - sumc[   j];
+        out  += incr;
+        out2 -= incr;
+    }
+
+    sum = 0;
+    SUM8(MLSS, sum, win + 16 + 32, in + 32);
+    *out = sum;
+}
+
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_mpadsp_init_ppc(MPADSPContext *s)
+{
+#if HAVE_ALTIVEC
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
+    s->apply_window_float = apply_window_mp3;
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c
index df111e9..3d74029 100644
--- a/libavcodec/ppc/mpegvideo_altivec.c
+++ b/libavcodec/ppc/mpegvideo_altivec.c
@@ -24,18 +24,20 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
-
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
+
 /* AltiVec version of dct_unquantize_h263
    this code assumes `block' is 16 bytes-aligned */
 static void dct_unquantize_h263_altivec(MpegEncContext *s,
-                                 DCTELEM *block, int n, int qscale)
+                                 int16_t *block, int n, int qscale)
 {
     int i, level, qmul, qadd;
     int nCoeffs;
@@ -111,14 +113,18 @@ static void dct_unquantize_h263_altivec(MpegEncContext *s,
     }
 }
 
+#endif /* HAVE_ALTIVEC */
 
-void ff_MPV_common_init_altivec(MpegEncContext *s)
+av_cold void ff_MPV_common_init_ppc(MpegEncContext *s)
 {
-    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)) return;
+#if HAVE_ALTIVEC
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
 
     if ((s->avctx->dct_algo == FF_DCT_AUTO) ||
-            (s->avctx->dct_algo == FF_DCT_ALTIVEC)) {
+        (s->avctx->dct_algo == FF_DCT_ALTIVEC)) {
         s->dct_unquantize_h263_intra = dct_unquantize_h263_altivec;
         s->dct_unquantize_h263_inter = dct_unquantize_h263_altivec;
     }
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c
index 6c110db..4695b1c 100644
--- a/libavcodec/ppc/vc1dsp_altivec.c
+++ b/libavcodec/ppc/vc1dsp_altivec.c
@@ -19,11 +19,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/vc1dsp.h"
 
+#if HAVE_ALTIVEC
+
 // main steps of 8x8 transform
 #define STEP8(s0, s1, s2, s3, s4, s5, s6, s7, vec_rnd) \
 do { \
@@ -129,7 +132,7 @@ do { \
 
 /** Do inverse transform on 8x8 block
 */
-static void vc1_inv_trans_8x8_altivec(DCTELEM block[64])
+static void vc1_inv_trans_8x8_altivec(int16_t block[64])
 {
     vector signed short src0, src1, src2, src3, src4, src5, src6, src7;
     vector signed int s0, s1, s2, s3, s4, s5, s6, s7;
@@ -224,7 +227,7 @@ static void vc1_inv_trans_8x8_altivec(DCTELEM block[64])
 
 /** Do inverse transform on 8x4 part of block
 */
-static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, DCTELEM *block)
+static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, int16_t *block)
 {
     vector signed short src0, src1, src2, src3, src4, src5, src6, src7;
     vector signed int s0, s1, s2, s3, s4, s5, s6, s7;
@@ -325,18 +328,21 @@ static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, DCTELEM *block)
 
 #define OP_U8_ALTIVEC                          PUT_OP_U8_ALTIVEC
 #define PREFIX_no_rnd_vc1_chroma_mc8_altivec   put_no_rnd_vc1_chroma_mc8_altivec
-#include "h264_altivec_template.c"
+#include "h264chroma_template.c"
 #undef OP_U8_ALTIVEC
 #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
 
 #define OP_U8_ALTIVEC                          AVG_OP_U8_ALTIVEC
 #define PREFIX_no_rnd_vc1_chroma_mc8_altivec   avg_no_rnd_vc1_chroma_mc8_altivec
-#include "h264_altivec_template.c"
+#include "h264chroma_template.c"
 #undef OP_U8_ALTIVEC
 #undef PREFIX_no_rnd_vc1_chroma_mc8_altivec
 
-void ff_vc1dsp_init_altivec(VC1DSPContext* dsp)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_vc1dsp_init_ppc(VC1DSPContext *dsp)
 {
+#if HAVE_ALTIVEC
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
 
@@ -344,4 +350,5 @@ void ff_vc1dsp_init_altivec(VC1DSPContext* dsp)
     dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_altivec;
     dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = put_no_rnd_vc1_chroma_mc8_altivec;
     dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = avg_no_rnd_vc1_chroma_mc8_altivec;
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/ppc/videodsp_ppc.c b/libavcodec/ppc/videodsp_ppc.c
index 1865b19..b9e003b 100644
--- a/libavcodec/ppc/videodsp_ppc.c
+++ b/libavcodec/ppc/videodsp_ppc.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/videodsp.h"
 
 static void prefetch_ppc(uint8_t *mem, ptrdiff_t stride, int h)
@@ -29,7 +30,7 @@ static void prefetch_ppc(uint8_t *mem, ptrdiff_t stride, int h)
     } while(--h);
 }
 
-void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc)
+av_cold void ff_videodsp_init_ppc(VideoDSPContext *ctx, int bpc)
 {
     ctx->prefetch = prefetch_ppc;
 }
diff --git a/libavcodec/ppc/vorbisdsp_altivec.c b/libavcodec/ppc/vorbisdsp_altivec.c
new file mode 100644
index 0000000..56a865d
--- /dev/null
+++ b/libavcodec/ppc/vorbisdsp_altivec.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2006 Luca Barbato <lu_zero at gentoo.org>
+ *
+ * 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_ALTIVEC_H
+#include <altivec.h>
+#endif
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavcodec/vorbisdsp.h"
+
+#if HAVE_ALTIVEC
+static void vorbis_inverse_coupling_altivec(float *mag, float *ang,
+                                            intptr_t blocksize)
+{
+    int i;
+    vector float m, a;
+    vector bool int t0, t1;
+    const vector unsigned int v_31 = //XXX
+        vec_add(vec_add(vec_splat_u32(15),vec_splat_u32(15)),vec_splat_u32(1));
+    for (i = 0; i < blocksize; i += 4) {
+        m = vec_ld(0, mag+i);
+        a = vec_ld(0, ang+i);
+        t0 = vec_cmple(m, (vector float)vec_splat_u32(0));
+        t1 = vec_cmple(a, (vector float)vec_splat_u32(0));
+        a = vec_xor(a, (vector float) vec_sl((vector unsigned int)t0, v_31));
+        t0 = (vector bool int)vec_and(a, t1);
+        t1 = (vector bool int)vec_andc(a, t1);
+        a = vec_sub(m, (vector float)t1);
+        m = vec_add(m, (vector float)t0);
+        vec_stl(a, 0, ang+i);
+        vec_stl(m, 0, mag+i);
+    }
+}
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_vorbisdsp_init_ppc(VorbisDSPContext *c)
+{
+#if HAVE_ALTIVEC
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
+    c->vorbis_inverse_coupling = vorbis_inverse_coupling_altivec;
+#endif /* HAVE_ALTIVEC */
+}
diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c
index 75a3677..bf50c02 100644
--- a/libavcodec/ppc/vp3dsp_altivec.c
+++ b/libavcodec/ppc/vp3dsp_altivec.c
@@ -18,18 +18,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <string.h>
+
 #include "config.h"
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
-#include "libavcodec/vp3dsp.h"
-
-#if HAVE_ALTIVEC
-
 #include "libavutil/ppc/types_altivec.h"
 #include "libavutil/ppc/util_altivec.h"
-#include "libavcodec/dsputil.h"
+#include "libavcodec/vp3dsp.h"
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
+
 static const vec_s16 constants =
     {0, 64277, 60547, 54491, 46341, 36410, 25080, 12785};
 static const vec_u8 interleave_high =
@@ -114,7 +114,7 @@ static inline vec_s16 M16(vec_s16 a, vec_s16 C)
 #define ADD8(a) vec_add(a, eight)
 #define SHIFT4(a) vec_sra(a, four)
 
-static void vp3_idct_put_altivec(uint8_t *dst, int stride, DCTELEM block[64])
+static void vp3_idct_put_altivec(uint8_t *dst, int stride, int16_t block[64])
 {
     vec_u8 t;
     IDCT_START
@@ -140,9 +140,10 @@ static void vp3_idct_put_altivec(uint8_t *dst, int stride, DCTELEM block[64])
     PUT(b5)     dst += stride;
     PUT(b6)     dst += stride;
     PUT(b7)
+    memset(block, 0, sizeof(*block) * 64);
 }
 
-static void vp3_idct_add_altivec(uint8_t *dst, int stride, DCTELEM block[64])
+static void vp3_idct_add_altivec(uint8_t *dst, int stride, int16_t block[64])
 {
     LOAD_ZERO;
     vec_u8 t, vdst;
@@ -171,6 +172,7 @@ static void vp3_idct_add_altivec(uint8_t *dst, int stride, DCTELEM block[64])
     ADD(b5)     dst += stride;
     ADD(b6)     dst += stride;
     ADD(b7)
+    memset(block, 0, sizeof(*block) * 64);
 }
 
 #endif /* HAVE_ALTIVEC */
@@ -178,10 +180,10 @@ static void vp3_idct_add_altivec(uint8_t *dst, int stride, DCTELEM block[64])
 av_cold void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags)
 {
 #if HAVE_ALTIVEC
-    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
-        c->idct_put  = vp3_idct_put_altivec;
-        c->idct_add  = vp3_idct_add_altivec;
-        c->idct_perm = FF_TRANSPOSE_IDCT_PERM;
-    }
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
+    c->idct_put = vp3_idct_put_altivec;
+    c->idct_add = vp3_idct_add_altivec;
 #endif
 }
diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c
index 4336453..504139d 100644
--- a/libavcodec/ppc/vp8dsp_altivec.c
+++ b/libavcodec/ppc/vp8dsp_altivec.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
 #include "libavutil/cpu.h"
 #include "libavutil/mem.h"
 #include "libavutil/ppc/types_altivec.h"
@@ -27,6 +28,7 @@
 #include "libavcodec/vp8dsp.h"
 #include "dsputil_altivec.h"
 
+#if HAVE_ALTIVEC
 #define REPT4(...) { __VA_ARGS__, __VA_ARGS__, __VA_ARGS__, __VA_ARGS__ }
 
 // h subpel filter uses msum to multiply+add 4 pixel taps at once
@@ -272,8 +274,11 @@ static void put_vp8_pixels16_altivec(uint8_t *dst, ptrdiff_t stride, uint8_t *sr
     ff_put_pixels16_altivec(dst, src, stride, h);
 }
 
-av_cold void ff_vp8dsp_init_altivec(VP8DSPContext *c)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_vp8dsp_init_ppc(VP8DSPContext *c)
 {
+#if HAVE_ALTIVEC
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
 
@@ -301,4 +306,5 @@ av_cold void ff_vp8dsp_init_altivec(VP8DSPContext *c)
     c->put_vp8_epel_pixels_tab[2][1][1] = put_vp8_epel4_h4v4_altivec;
     c->put_vp8_epel_pixels_tab[2][1][2] = put_vp8_epel4_h6v4_altivec;
     c->put_vp8_epel_pixels_tab[2][2][1] = put_vp8_epel4_h4v6_altivec;
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c
index 4b196f6..144fa26 100644
--- a/libavcodec/proresdec.c
+++ b/libavcodec/proresdec.c
@@ -34,6 +34,7 @@
 
 #include "libavutil/intmath.h"
 #include "avcodec.h"
+#include "dsputil.h"
 #include "internal.h"
 #include "proresdata.h"
 #include "proresdsp.h"
@@ -45,14 +46,14 @@ typedef struct {
     int x_pos, y_pos;
     int slice_width;
     int prev_slice_sf;               ///< scalefactor of the previous decoded slice
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[8 * 4 * 64];
+    DECLARE_ALIGNED(16, int16_t, blocks)[8 * 4 * 64];
     DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled)[64];
     DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
 } ProresThreadData;
 
 typedef struct {
     ProresDSPContext dsp;
-    AVFrame    picture;
+    AVFrame    *frame;
     ScanTable  scantable;
     int        scantable_type;           ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced
 
@@ -87,11 +88,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     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);
@@ -138,12 +134,21 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
     ctx->chroma_factor     = (buf[12] >> 6) & 3;
     ctx->mb_chroma_factor  = ctx->chroma_factor + 2;
     ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
+    ctx->alpha_info        = buf[17] & 0xf;
+
+    if (ctx->alpha_info > 2) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info);
+        return AVERROR_INVALIDDATA;
+    }
+
     switch (ctx->chroma_factor) {
     case 2:
-        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
+        avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA422P10
+                                         : AV_PIX_FMT_YUV422P10;
         break;
     case 3:
-        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
+        avctx->pix_fmt = ctx->alpha_info ? AV_PIX_FMT_YUVA444P10
+                                         : AV_PIX_FMT_YUV444P10;
         break;
     default:
         av_log(avctx, AV_LOG_ERROR,
@@ -162,20 +167,16 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
     }
 
     if (ctx->frame_type) {      /* if interlaced */
-        ctx->picture.interlaced_frame = 1;
-        ctx->picture.top_field_first  = ctx->frame_type & 1;
+        ctx->frame->interlaced_frame = 1;
+        ctx->frame->top_field_first  = ctx->frame_type & 1;
     } else {
-        ctx->picture.interlaced_frame = 0;
+        ctx->frame->interlaced_frame = 0;
     }
 
     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];
@@ -246,8 +247,8 @@ static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
 
     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);
+                      (1 << (4 + ctx->frame->interlaced_frame)) - 1) >>
+                     (4 + ctx->frame->interlaced_frame);
 
     remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
     num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
@@ -340,10 +341,10 @@ static inline int decode_vlc_codeword(GetBitContext *gb, unsigned codebook)
 /**
  * Decode DC coefficients for all blocks in a slice.
  */
-static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
+static inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out,
                                     int nblocks)
 {
-    DCTELEM prev_dc;
+    int16_t prev_dc;
     int     i, sign;
     int16_t delta;
     unsigned int code;
@@ -368,10 +369,10 @@ static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
 /**
  * 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)
+static inline int decode_ac_coeffs(GetBitContext *gb, int16_t *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;
@@ -389,15 +390,19 @@ static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
 
         bits_left = get_bits_left(gb);
         if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
-            return;
+            return 0;
 
         run = decode_vlc_codeword(gb, ff_prores_ac_codebook[run_cb_index]);
+        if (run < 0)
+            return AVERROR_INVALIDDATA;
 
         bits_left = get_bits_left(gb);
         if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
-            return;
+            return AVERROR_INVALIDDATA;
 
         level = decode_vlc_codeword(gb, ff_prores_ac_codebook[lev_cb_index]) + 1;
+        if (level < 0)
+            return AVERROR_INVALIDDATA;
 
         pos += run + 1;
         if (pos >= max_coeffs)
@@ -407,22 +412,24 @@ static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
         out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
             (level ^ sign) - sign;
     }
+
+    return 0;
 }
 
 
 /**
  * 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)
+static int 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;
+    int16_t *block_ptr;
+    int mb_num, blocks_per_slice, ret;
 
     blocks_per_slice = mbs_per_slice * blocks_per_mb;
 
@@ -432,8 +439,10 @@ static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
 
     decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
 
-    decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
-                     plane_size_factor, ctx->scantable.permutated);
+    ret = decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
+                           plane_size_factor, ctx->scantable.permutated);
+    if (ret < 0)
+        return ret;
 
     /* inverse quantization, inverse transform and output */
     block_ptr = td->blocks;
@@ -467,9 +476,82 @@ static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
             }
         }
     }
+    return 0;
 }
 
 
+static void unpack_alpha(GetBitContext *gb, uint16_t *dst, int num_coeffs,
+                         const int num_bits)
+{
+    const int mask = (1 << num_bits) - 1;
+    int i, idx, val, alpha_val;
+
+    idx       = 0;
+    alpha_val = mask;
+    do {
+        do {
+            if (get_bits1(gb))
+                val = get_bits(gb, num_bits);
+            else {
+                int sign;
+                val  = get_bits(gb, num_bits == 16 ? 7 : 4);
+                sign = val & 1;
+                val  = (val + 2) >> 1;
+                if (sign)
+                    val = -val;
+            }
+            alpha_val = (alpha_val + val) & mask;
+            if (num_bits == 16)
+                dst[idx++] = alpha_val >> 6;
+            else
+                dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+            if (idx >= num_coeffs - 1)
+                break;
+        } while (get_bits1(gb));
+        val = get_bits(gb, 4);
+        if (!val)
+            val = get_bits(gb, 11);
+        if (idx + val > num_coeffs)
+            val = num_coeffs - idx;
+        if (num_bits == 16)
+            for (i = 0; i < val; i++)
+                dst[idx++] = alpha_val >> 6;
+        else
+            for (i = 0; i < val; i++)
+                dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
+    } while (idx < num_coeffs);
+}
+
+/**
+ * Decode alpha slice plane.
+ */
+static void decode_alpha_plane(ProresContext *ctx, ProresThreadData *td,
+                               const uint8_t *buf, int data_size,
+                               uint16_t *out_ptr, int linesize,
+                               int mbs_per_slice)
+{
+    GetBitContext gb;
+    int i;
+    uint16_t *block_ptr;
+
+    memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
+
+    init_get_bits(&gb, buf, data_size << 3);
+
+    if (ctx->alpha_info == 2)
+        unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 16);
+    else
+        unpack_alpha(&gb, td->blocks, mbs_per_slice * 4 * 64, 8);
+
+    block_ptr = td->blocks;
+
+    for (i = 0; i < 16; i++) {
+        memcpy(out_ptr, block_ptr, 16 * mbs_per_slice * sizeof(*out_ptr));
+        out_ptr   += linesize >> 1;
+        block_ptr += 16 * mbs_per_slice;
+    }
+}
+
 static int decode_slice(AVCodecContext *avctx, void *tdata)
 {
     ProresThreadData *td = tdata;
@@ -480,11 +562,14 @@ static int decode_slice(AVCodecContext *avctx, void *tdata)
     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;
+    uint8_t *y_data, *u_data, *v_data, *a_data;
+    AVFrame *pic = ctx->frame;
     int i, sf, slice_width_factor;
-    int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
-    int y_linesize, u_linesize, v_linesize;
+    int slice_data_size, hdr_size;
+    int y_data_size, u_data_size, v_data_size, a_data_size;
+    int y_linesize, u_linesize, v_linesize, a_linesize;
+    int coff[4];
+    int ret;
 
     buf             = ctx->slice_data[slice_num].index;
     slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
@@ -494,20 +579,30 @@ static int decode_slice(AVCodecContext *avctx, void *tdata)
     y_data     = pic->data[0];
     u_data     = pic->data[1];
     v_data     = pic->data[2];
+    a_data     = pic->data[3];
     y_linesize = pic->linesize[0];
     u_linesize = pic->linesize[1];
     v_linesize = pic->linesize[2];
+    a_linesize = pic->linesize[3];
 
     if (pic->interlaced_frame) {
         if (!(pic_num ^ pic->top_field_first)) {
             y_data += y_linesize;
             u_data += u_linesize;
             v_data += v_linesize;
+            if (a_data)
+                a_data += a_linesize;
         }
         y_linesize <<= 1;
         u_linesize <<= 1;
         v_linesize <<= 1;
+        a_linesize <<= 1;
     }
+    y_data += (mb_y_pos << 4) * y_linesize + (mb_x_pos << 5);
+    u_data += (mb_y_pos << 4) * u_linesize + (mb_x_pos << ctx->mb_chroma_factor);
+    v_data += (mb_y_pos << 4) * v_linesize + (mb_x_pos << ctx->mb_chroma_factor);
+    if (a_data)
+        a_data += (mb_y_pos << 4) * a_linesize + (mb_x_pos << 5);
 
     if (slice_data_size < 6) {
         av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
@@ -516,13 +611,18 @@ static int decode_slice(AVCodecContext *avctx, void *tdata)
 
     /* parse slice header */
     hdr_size    = buf[0] >> 3;
+    coff[0]     = hdr_size;
     y_data_size = AV_RB16(buf + 2);
+    coff[1]     = coff[0] + y_data_size;
     u_data_size = AV_RB16(buf + 4);
-    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
-        slice_data_size - y_data_size - u_data_size - hdr_size;
-
-    if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
-        v_data_size < 0 || hdr_size < 6) {
+    coff[2]     = coff[1] + u_data_size;
+    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : slice_data_size - coff[2];
+    coff[3]     = coff[2] + v_data_size;
+    a_data_size = slice_data_size - coff[3];
+
+    /* if V or alpha component size is negative that means that previous
+       component sizes are too large */
+    if (v_data_size < 0 || a_data_size < 0 || hdr_size < 6) {
         av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
         return AVERROR_INVALIDDATA;
     }
@@ -541,28 +641,37 @@ static int decode_slice(AVCodecContext *avctx, void *tdata)
     }
 
     /* 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);
+    ret = decode_slice_plane(ctx, td, buf + coff[0], y_data_size,
+                             (uint16_t*) y_data, y_linesize,
+                             mbs_per_slice, 4, slice_width_factor + 2,
+                             td->qmat_luma_scaled, 0);
+
+    if (ret < 0)
+        return ret;
 
     /* 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);
+    ret = decode_slice_plane(ctx, td, buf + coff[1], u_data_size,
+                             (uint16_t*) u_data, u_linesize,
+                             mbs_per_slice, ctx->num_chroma_blocks,
+                             slice_width_factor + ctx->chroma_factor - 1,
+                             td->qmat_chroma_scaled, 1);
+    if (ret < 0)
+        return ret;
 
     /* 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);
+    ret = decode_slice_plane(ctx, td, buf + coff[2], v_data_size,
+                             (uint16_t*) v_data, v_linesize,
+                             mbs_per_slice, ctx->num_chroma_blocks,
+                             slice_width_factor + ctx->chroma_factor - 1,
+                             td->qmat_chroma_scaled, 1);
+    if (ret < 0)
+        return ret;
+
+    /* decode alpha plane if available */
+    if (a_data && a_data_size)
+        decode_alpha_plane(ctx, td, buf + coff[3], a_data_size,
+                           (uint16_t*) a_data, a_linesize,
+                           mbs_per_slice);
 
     return 0;
 }
@@ -605,11 +714,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         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;
 
+    ctx->frame            = data;
+    ctx->frame->pict_type = AV_PICTURE_TYPE_I;
+    ctx->frame->key_frame = 1;
+
     /* check frame atom container */
     if (buf_size < 28 || buf_size < AV_RB32(buf) ||
         AV_RB32(buf + 4) != FRAME_ID) {
@@ -625,14 +737,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     MOVE_DATA_PTR(frame_hdr_size);
 
-    if (picture->data[0])
-        avctx->release_buffer(avctx, picture);
-
-    picture->reference = 0;
-    if (ff_get_buffer(avctx, picture) < 0)
+    if (ff_get_buffer(avctx, ctx->frame, 0) < 0)
         return -1;
 
-    for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
+    for (pic_num = 0; ctx->frame->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;
@@ -643,8 +751,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         MOVE_DATA_PTR(pic_data_size);
     }
 
-    *got_frame       = 1;
-    *(AVFrame*) data = *avctx->coded_frame;
+    ctx->frame = NULL;
+    *got_frame = 1;
 
     return avpkt->size;
 }
@@ -654,9 +762,6 @@ 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;
@@ -665,6 +770,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
 
 AVCodec ff_prores_decoder = {
     .name           = "prores",
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PRORES,
     .priv_data_size = sizeof(ProresContext),
@@ -672,5 +778,4 @@ AVCodec ff_prores_decoder = {
     .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..1c0f391 100644
--- a/libavcodec/proresdsp.c
+++ b/libavcodec/proresdsp.c
@@ -20,9 +20,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "dct.h"
+#include "dsputil.h"
 #include "proresdsp.h"
 #include "simple_idct.h"
-#include "libavutil/common.h"
 
 #define BIAS     (1 << (PRORES_BITS_PER_SAMPLE - 1))           ///< bias value for converting signed pixels into unsigned ones
 #define CLIP_MIN (1 << (PRORES_BITS_PER_SAMPLE - 8))           ///< minimum value for clipping resulting pixels
@@ -34,7 +37,7 @@
 /**
  * Add bias value, clamp and output pixels of a slice
  */
-static void put_pixels(uint16_t *dst, int stride, const DCTELEM *in)
+static void put_pixels(uint16_t *dst, int stride, const int16_t *in)
 {
     int x, y, src_offset, dst_offset;
 
@@ -47,7 +50,7 @@ static void put_pixels(uint16_t *dst, int stride, const DCTELEM *in)
     }
 }
 
-static void prores_idct_put_c(uint16_t *out, int linesize, DCTELEM *block, const int16_t *qmat)
+static void prores_idct_put_c(uint16_t *out, int linesize, int16_t *block, const int16_t *qmat)
 {
     ff_prores_idct(block, qmat);
     put_pixels(out, linesize >> 1, block);
@@ -55,7 +58,7 @@ static void prores_idct_put_c(uint16_t *out, int linesize, DCTELEM *block, const
 #endif
 
 #if CONFIG_PRORES_ENCODER
-static void prores_fdct_c(const uint16_t *src, int linesize, DCTELEM *block)
+static void prores_fdct_c(const uint16_t *src, int linesize, int16_t *block)
 {
     int x, y;
     const uint16_t *tsrc = src;
@@ -69,7 +72,7 @@ static void prores_fdct_c(const uint16_t *src, int linesize, DCTELEM *block)
 }
 #endif
 
-void ff_proresdsp_init(ProresDSPContext *dsp)
+av_cold void ff_proresdsp_init(ProresDSPContext *dsp)
 {
 #if CONFIG_PRORES_DECODER
     dsp->idct_put = prores_idct_put_c;
diff --git a/libavcodec/proresdsp.h b/libavcodec/proresdsp.h
index ba22259..5e35140 100644
--- a/libavcodec/proresdsp.h
+++ b/libavcodec/proresdsp.h
@@ -23,7 +23,7 @@
 #ifndef AVCODEC_PRORESDSP_H
 #define AVCODEC_PRORESDSP_H
 
-#include "dsputil.h"
+#include <stdint.h>
 
 #define PRORES_BITS_PER_SAMPLE 10 ///< output precision of prores decoder
 
@@ -32,8 +32,8 @@ typedef struct ProresDSPContext {
     uint8_t idct_permutation[64];
     int dct_permutation_type;
     uint8_t dct_permutation[64];
-    void (* idct_put) (uint16_t *out, int linesize, DCTELEM *block, const int16_t *qmat);
-    void (* fdct) (const uint16_t *src, int linesize, DCTELEM *block);
+    void (* idct_put) (uint16_t *out, int linesize, int16_t *block, const int16_t *qmat);
+    void (* fdct) (const uint16_t *src, int linesize, int16_t *block);
 } ProresDSPContext;
 
 void ff_proresdsp_init(ProresDSPContext *dsp);
diff --git a/libavcodec/proresenc.c b/libavcodec/proresenc.c
index c4716d6..7e9ce54 100644
--- a/libavcodec/proresenc.c
+++ b/libavcodec/proresenc.c
@@ -21,7 +21,9 @@
  */
 
 #include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
 #include "avcodec.h"
+#include "dsputil.h"
 #include "put_bits.h"
 #include "bytestream.h"
 #include "internal.h"
@@ -33,13 +35,14 @@
 
 #define MAX_MBS_PER_SLICE 8
 
-#define MAX_PLANES 3 // should be increased to 4 when there's AV_PIX_FMT_YUV444AP10
+#define MAX_PLANES 4
 
 enum {
     PRORES_PROFILE_PROXY = 0,
     PRORES_PROFILE_LT,
     PRORES_PROFILE_STANDARD,
     PRORES_PROFILE_HQ,
+    PRORES_PROFILE_4444,
 };
 
 enum {
@@ -118,7 +121,7 @@ static const struct prores_profile {
     int         max_quant;
     int         br_tab[NUM_MB_LIMITS];
     int         quant;
-} prores_profile_info[4] = {
+} prores_profile_info[5] = {
     {
         .full_name = "proxy",
         .tag       = MKTAG('a', 'p', 'c', 'o'),
@@ -150,8 +153,15 @@ static const struct prores_profile {
         .max_quant = 6,
         .br_tab    = { 1566, 1216, 1070, 950 },
         .quant     = QUANT_MAT_HQ,
+    },
+    {
+        .full_name = "4444",
+        .tag       = MKTAG('a', 'p', '4', 'h'),
+        .min_quant = 1,
+        .max_quant = 6,
+        .br_tab    = { 2350, 1828, 1600, 1425 },
+        .quant     = QUANT_MAT_HQ,
     }
-// for 4444 profile bitrate numbers are { 2350, 1828, 1600, 1425 }
 };
 
 #define TRELLIS_WIDTH 16
@@ -167,7 +177,7 @@ struct TrellisNode {
 #define MAX_STORED_Q 16
 
 typedef struct ProresThreadData {
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
+    DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
     DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
     int16_t custom_q[64];
     struct TrellisNode *nodes;
@@ -175,7 +185,7 @@ typedef struct ProresThreadData {
 
 typedef struct ProresContext {
     AVClass *class;
-    DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
+    DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
     DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
     int16_t quants[MAX_STORED_Q][64];
     int16_t custom_q[64];
@@ -194,6 +204,7 @@ typedef struct ProresContext {
     int num_planes;
     int bits_per_mb;
     int force_quant;
+    int alpha_bits;
 
     char *vendor;
     int quant_sel;
@@ -210,7 +221,7 @@ typedef struct 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,
+                           int16_t *blocks, uint16_t *emu_buf,
                            int mbs_per_slice, int blocks_per_mb, int is_chroma)
 {
     const uint16_t *esrc;
@@ -279,6 +290,34 @@ static void get_slice_data(ProresContext *ctx, const uint16_t *src,
     }
 }
 
+static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
+                           int linesize, int x, int y, int w, int h,
+                           int16_t *blocks, int mbs_per_slice, int abits)
+{
+    const int slice_width = 16 * mbs_per_slice;
+    int i, j, copy_w, copy_h;
+
+    copy_w = FFMIN(w - x, slice_width);
+    copy_h = FFMIN(h - y, 16);
+    for (i = 0; i < copy_h; i++) {
+        memcpy(blocks, src, copy_w * sizeof(*src));
+        if (abits == 8)
+            for (j = 0; j < copy_w; j++)
+                blocks[j] >>= 2;
+        else
+            for (j = 0; j < copy_w; j++)
+                blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
+        for (j = copy_w; j < slice_width; j++)
+            blocks[j] = blocks[copy_w - 1];
+        blocks += slice_width;
+        src    += linesize >> 1;
+    }
+    for (; i < 16; i++) {
+        memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
+        blocks += slice_width;
+    }
+}
+
 /**
  * Write an unsigned rice/exp golomb codeword.
  */
@@ -314,7 +353,7 @@ static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int
 #define GET_SIGN(x)  ((x) >> 31)
 #define MAKE_CODE(x) (((x) << 1) ^ GET_SIGN(x))
 
-static void encode_dcs(PutBitContext *pb, DCTELEM *blocks,
+static void encode_dcs(PutBitContext *pb, int16_t *blocks,
                        int blocks_per_slice, int scale)
 {
     int i;
@@ -340,7 +379,7 @@ static void encode_dcs(PutBitContext *pb, DCTELEM *blocks,
     }
 }
 
-static void encode_acs(PutBitContext *pb, DCTELEM *blocks,
+static void encode_acs(PutBitContext *pb, int16_t *blocks,
                        int blocks_per_slice,
                        int plane_size_factor,
                        const uint8_t *scan, const int16_t *qmat)
@@ -376,7 +415,7 @@ static void encode_acs(PutBitContext *pb, DCTELEM *blocks,
 
 static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
                               const uint16_t *src, int linesize,
-                              int mbs_per_slice, DCTELEM *blocks,
+                              int mbs_per_slice, int16_t *blocks,
                               int blocks_per_mb, int plane_size_factor,
                               const int16_t *qmat)
 {
@@ -393,6 +432,73 @@ static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
     return (put_bits_count(pb) - saved_pos) >> 3;
 }
 
+static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
+{
+    const int mask  = (1 << abits) - 1;
+    const int dbits = (abits == 8) ? 4 : 7;
+    const int dsize = 1 << dbits - 1;
+    int diff = cur - prev;
+
+    diff &= mask;
+    if (diff >= (1 << abits) - dsize)
+        diff -= 1 << abits;
+    if (diff < -dsize || diff > dsize || !diff) {
+        put_bits(pb, 1, 1);
+        put_bits(pb, abits, diff);
+    } else {
+        put_bits(pb, 1, 0);
+        put_bits(pb, dbits - 1, FFABS(diff) - 1);
+        put_bits(pb, 1, diff < 0);
+    }
+}
+
+static void put_alpha_run(PutBitContext *pb, int run)
+{
+    if (run) {
+        put_bits(pb, 1, 0);
+        if (run < 0x10)
+            put_bits(pb, 4, run);
+        else
+            put_bits(pb, 15, run);
+    } else {
+        put_bits(pb, 1, 1);
+    }
+}
+
+// todo alpha quantisation for high quants
+static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
+                              const uint16_t *src, int linesize,
+                              int mbs_per_slice, uint16_t *blocks,
+                              int quant)
+{
+    const int abits = ctx->alpha_bits;
+    const int mask  = (1 << abits) - 1;
+    const int num_coeffs = mbs_per_slice * 256;
+    int saved_pos = put_bits_count(pb);
+    int prev = mask, cur;
+    int idx = 0;
+    int run = 0;
+
+    cur = blocks[idx++];
+    put_alpha_diff(pb, cur, prev, abits);
+    prev = cur;
+    do {
+        cur = blocks[idx++];
+        if (cur != prev) {
+            put_alpha_run (pb, run);
+            put_alpha_diff(pb, cur, prev, abits);
+            prev = cur;
+            run  = 0;
+        } else {
+            run++;
+        }
+    } while (idx < num_coeffs);
+    if (run)
+        put_alpha_run(pb, run);
+    flush_put_bits(pb);
+    return (put_bits_count(pb) - saved_pos) >> 3;
+}
+
 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
                         PutBitContext *pb,
                         int sizes[4], int x, int y, int quant,
@@ -443,14 +549,23 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
         src = (const uint16_t*)(pic->data[i] + yp * linesize +
                                 line_add * pic->linesize[i]) + xp;
 
-        get_slice_data(ctx, src, linesize, xp, yp,
-                       pwidth, avctx->height / ctx->pictures_per_frame,
-                       ctx->blocks[0], ctx->emu_buf,
-                       mbs_per_slice, num_cblocks, is_chroma);
-        sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
-                                      mbs_per_slice, ctx->blocks[0],
-                                      num_cblocks, plane_factor,
-                                      qmat);
+        if (i < 3) {
+            get_slice_data(ctx, src, linesize, xp, yp,
+                           pwidth, avctx->height / ctx->pictures_per_frame,
+                           ctx->blocks[0], ctx->emu_buf,
+                           mbs_per_slice, num_cblocks, is_chroma);
+            sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
+                                          mbs_per_slice, ctx->blocks[0],
+                                          num_cblocks, plane_factor,
+                                          qmat);
+        } else {
+            get_alpha_data(ctx, src, linesize, xp, yp,
+                           pwidth, avctx->height / ctx->pictures_per_frame,
+                           ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
+            sizes[i] = encode_alpha_plane(ctx, pb, src, linesize,
+                                          mbs_per_slice, ctx->blocks[0],
+                                          quant);
+        }
         total_size += sizes[i];
     }
     return total_size;
@@ -478,7 +593,7 @@ static inline int estimate_vlc(unsigned codebook, int val)
     }
 }
 
-static int estimate_dcs(int *error, DCTELEM *blocks, int blocks_per_slice,
+static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
                         int scale)
 {
     int i;
@@ -509,7 +624,7 @@ static int estimate_dcs(int *error, DCTELEM *blocks, int blocks_per_slice,
     return bits;
 }
 
-static int estimate_acs(int *error, DCTELEM *blocks, int blocks_per_slice,
+static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
                         int plane_size_factor,
                         const uint8_t *scan, const int16_t *qmat)
 {
@@ -563,6 +678,66 @@ static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
     return FFALIGN(bits, 8);
 }
 
+static int est_alpha_diff(int cur, int prev, int abits)
+{
+    const int mask  = (1 << abits) - 1;
+    const int dbits = (abits == 8) ? 4 : 7;
+    const int dsize = 1 << dbits - 1;
+    int diff = cur - prev;
+
+    diff &= mask;
+    if (diff >= (1 << abits) - dsize)
+        diff -= 1 << abits;
+    if (diff < -dsize || diff > dsize || !diff)
+        return abits + 1;
+    else
+        return dbits + 1;
+}
+
+static int estimate_alpha_plane(ProresContext *ctx, int *error,
+                                const uint16_t *src, int linesize,
+                                int mbs_per_slice, int quant,
+                                int16_t *blocks)
+{
+    const int abits = ctx->alpha_bits;
+    const int mask  = (1 << abits) - 1;
+    const int num_coeffs = mbs_per_slice * 256;
+    int prev = mask, cur;
+    int idx = 0;
+    int run = 0;
+    int bits;
+
+    *error = 0;
+    cur = blocks[idx++];
+    bits = est_alpha_diff(cur, prev, abits);
+    prev = cur;
+    do {
+        cur = blocks[idx++];
+        if (cur != prev) {
+            if (!run)
+                bits++;
+            else if (run < 0x10)
+                bits += 4;
+            else
+                bits += 15;
+            bits += est_alpha_diff(cur, prev, abits);
+            prev = cur;
+            run  = 0;
+        } else {
+            run++;
+        }
+    } while (idx < num_coeffs);
+
+    if (run) {
+        if (run < 0x10)
+            bits += 4;
+        else
+            bits += 15;
+    }
+
+    return bits;
+}
+
 static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
                             int trellis_node, int x, int y, int mbs_per_slice,
                             ProresThreadData *td)
@@ -609,10 +784,16 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
         src = (const uint16_t*)(pic->data[i] + yp * linesize[i] +
                                 line_add * pic->linesize[i]) + xp;
 
-        get_slice_data(ctx, src, linesize[i], xp, yp,
-                       pwidth, avctx->height / ctx->pictures_per_frame,
-                       td->blocks[i], td->emu_buf,
-                       mbs_per_slice, num_cblocks[i], is_chroma[i]);
+        if (i < 3) {
+            get_slice_data(ctx, src, linesize[i], xp, yp,
+                           pwidth, avctx->height / ctx->pictures_per_frame,
+                           td->blocks[i], td->emu_buf,
+                           mbs_per_slice, num_cblocks[i], is_chroma[i]);
+        } else {
+            get_alpha_data(ctx, src, linesize[i], xp, yp,
+                           pwidth, avctx->height / ctx->pictures_per_frame,
+                           td->blocks[i], mbs_per_slice, ctx->alpha_bits);
+        }
     }
 
     for (q = min_quant; q < max_quant + 2; q++) {
@@ -624,13 +805,16 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
     for (q = min_quant; q <= max_quant; q++) {
         bits  = 0;
         error = 0;
-        for (i = 0; i < ctx->num_planes; i++) {
+        for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {
             bits += estimate_slice_plane(ctx, &error, i,
                                          src, linesize[i],
                                          mbs_per_slice,
                                          num_cblocks[i], plane_factor[i],
                                          ctx->quants[q], td);
         }
+        if (ctx->alpha_bits)
+            bits += estimate_alpha_plane(ctx, &error, src, linesize[3],
+                                         mbs_per_slice, q, td->blocks[3]);
         if (bits > 65000 * 8) {
             error = SCORE_LIMIT;
             break;
@@ -653,13 +837,16 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
                 for (i = 0; i < 64; i++)
                     qmat[i] = ctx->quant_mat[i] * q;
             }
-            for (i = 0; i < ctx->num_planes; i++) {
+            for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {
                 bits += estimate_slice_plane(ctx, &error, i,
                                              src, linesize[i],
                                              mbs_per_slice,
                                              num_cblocks[i], plane_factor[i],
                                              qmat, td);
             }
+            if (ctx->alpha_bits)
+                bits += estimate_alpha_plane(ctx, &error, src, linesize[3],
+                                             mbs_per_slice, q, td->blocks[3]);
             if (bits <= ctx->bits_per_mb * mbs_per_slice)
                 break;
         }
@@ -781,7 +968,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     bytestream_put_byte  (&buf, avctx->color_primaries);
     bytestream_put_byte  (&buf, avctx->color_trc);
     bytestream_put_byte  (&buf, avctx->colorspace);
-    bytestream_put_byte  (&buf, 0x40);          // source format and alpha information
+    bytestream_put_byte  (&buf, 0x40 | (ctx->alpha_bits >> 3));
     bytestream_put_byte  (&buf, 0);             // reserved
     if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
         bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present
@@ -888,7 +1075,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     int interlaced = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
 
     avctx->bits_per_raw_sample = 10;
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame)
         return AVERROR(ENOMEM);
 
@@ -903,12 +1090,20 @@ static av_cold int encode_init(AVCodecContext *avctx)
                "there should be an integer power of two MBs per slice\n");
         return AVERROR(EINVAL);
     }
+    if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
+        if (ctx->alpha_bits & 7) {
+            av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
+            return AVERROR(EINVAL);
+        }
+    } else {
+        ctx->alpha_bits = 0;
+    }
 
     ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
                          ? CFACTOR_Y422
                          : CFACTOR_Y444;
     ctx->profile_info  = prores_profile_info + ctx->profile;
-    ctx->num_planes    = 3;
+    ctx->num_planes    = 3 + !!ctx->alpha_bits;
 
     ctx->mb_width      = FFALIGN(avctx->width,  16) >> 4;
 
@@ -1024,7 +1219,7 @@ static const AVOption options[] = {
         AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
     { "profile",       NULL, OFFSET(profile), AV_OPT_TYPE_INT,
         { .i64 = PRORES_PROFILE_STANDARD },
-        PRORES_PROFILE_PROXY, PRORES_PROFILE_HQ, VE, "profile" },
+        PRORES_PROFILE_PROXY, PRORES_PROFILE_4444, VE, "profile" },
     { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
         0, 0, VE, "profile" },
     { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
@@ -1033,6 +1228,8 @@ static const AVOption options[] = {
         0, 0, VE, "profile" },
     { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
         0, 0, VE, "profile" },
+    { "4444",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
+        0, 0, VE, "profile" },
     { "vendor", "vendor ID", OFFSET(vendor),
         AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
     { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
@@ -1051,6 +1248,8 @@ static const AVOption options[] = {
         0, 0, VE, "quant_mat" },
     { "default",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
         0, 0, VE, "quant_mat" },
+    { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
+        { .i64 = 16 }, 0, 16, VE },
     { NULL }
 };
 
@@ -1063,6 +1262,7 @@ static const AVClass proresenc_class = {
 
 AVCodec ff_prores_encoder = {
     .name           = "prores",
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PRORES,
     .priv_data_size = sizeof(ProresContext),
@@ -1070,9 +1270,9 @@ AVCodec ff_prores_encoder = {
     .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
+                          AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
+                          AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
                       },
     .priv_class     = &proresenc_class,
 };
diff --git a/libavcodec/psymodel.h b/libavcodec/psymodel.h
index 34b20d7..1cc3066 100644
--- a/libavcodec/psymodel.h
+++ b/libavcodec/psymodel.h
@@ -137,9 +137,9 @@ typedef struct FFPsyModel {
  *
  * @return zero if successful, a negative value if not
  */
-av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
-                        const uint8_t **bands, const int* num_bands,
-                        int num_groups, const uint8_t *group_map);
+int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
+                const uint8_t **bands, const int *num_bands,
+                int num_groups, const uint8_t *group_map);
 
 /**
  * Determine what group a channel belongs to.
@@ -156,7 +156,7 @@ FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel);
  *
  * @param ctx model context
  */
-av_cold void ff_psy_end(FFPsyContext *ctx);
+void ff_psy_end(FFPsyContext *ctx);
 
 
 /**************************************************************************
@@ -168,7 +168,7 @@ struct FFPsyPreprocessContext;
 /**
  * psychoacoustic model audio preprocessing initialization
  */
-av_cold struct FFPsyPreprocessContext* ff_psy_preprocess_init(AVCodecContext *avctx);
+struct FFPsyPreprocessContext *ff_psy_preprocess_init(AVCodecContext *avctx);
 
 /**
  * Preprocess several channel in audio frame in order to compress it better.
@@ -182,6 +182,6 @@ void ff_psy_preprocess(struct FFPsyPreprocessContext *ctx, float **audio, int ch
 /**
  * Cleanup audio preprocessing module.
  */
-av_cold void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx);
+void ff_psy_preprocess_end(struct FFPsyPreprocessContext *ctx);
 
 #endif /* AVCODEC_PSYMODEL_H */
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 73d9da3..682fd05 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -29,971 +29,10 @@
  * @see doc/multithreading.txt
  */
 
-#include "config.h"
-
-#if HAVE_SCHED_GETAFFINITY
-#define _GNU_SOURCE
-#include <sched.h>
-#endif
-#if HAVE_GETPROCESSAFFINITYMASK
-#include <windows.h>
-#endif
-#if HAVE_SYSCTL
-#if HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#endif
-#if HAVE_SYSCONF
-#include <unistd.h>
-#endif
-
 #include "avcodec.h"
 #include "internal.h"
+#include "pthread_internal.h"
 #include "thread.h"
-#include "libavutil/common.h"
-
-#if HAVE_PTHREADS
-#include <pthread.h>
-#elif HAVE_W32THREADS
-#include "w32pthreads.h"
-#endif
-
-typedef int (action_func)(AVCodecContext *c, void *arg);
-typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
-
-typedef struct ThreadContext {
-    pthread_t *workers;
-    action_func *func;
-    action_func2 *func2;
-    void *args;
-    int *rets;
-    int rets_count;
-    int job_count;
-    int job_size;
-
-    pthread_cond_t last_job_cond;
-    pthread_cond_t current_job_cond;
-    pthread_mutex_t current_job_lock;
-    int current_job;
-    int done;
-} ThreadContext;
-
-/// Max number of frame buffers that can be allocated when using frame threads.
-#define MAX_BUFFERS (32+1)
-
-/**
- * Context used by codec threads and stored in their AVCodecContext thread_opaque.
- */
-typedef struct PerThreadContext {
-    struct FrameThreadContext *parent;
-
-    pthread_t      thread;
-    int            thread_init;
-    pthread_cond_t input_cond;      ///< Used to wait for a new packet from the main thread.
-    pthread_cond_t progress_cond;   ///< Used by child threads to wait for progress to change.
-    pthread_cond_t output_cond;     ///< Used by the main thread to wait for frames to finish.
-
-    pthread_mutex_t mutex;          ///< Mutex used to protect the contents of the PerThreadContext.
-    pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
-
-    AVCodecContext *avctx;          ///< Context used to decode packets passed to this thread.
-
-    AVPacket       avpkt;           ///< Input packet (for decoding) or output (for encoding).
-    int            allocated_buf_size; ///< Size allocated for avpkt.data
-
-    AVFrame frame;                  ///< Output frame (for decoding) or input (for encoding).
-    int     got_frame;              ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
-    int     result;                 ///< The result of the last codec decode/encode() call.
-
-    enum {
-        STATE_INPUT_READY,          ///< Set when the thread is awaiting a packet.
-        STATE_SETTING_UP,           ///< Set before the codec has called ff_thread_finish_setup().
-        STATE_GET_BUFFER,           /**<
-                                     * Set when the codec calls get_buffer().
-                                     * State is returned to STATE_SETTING_UP afterwards.
-                                     */
-        STATE_SETUP_FINISHED        ///< Set after the codec has called ff_thread_finish_setup().
-    } state;
-
-    /**
-     * Array of frames passed to ff_thread_release_buffer().
-     * Frames are released after all threads referencing them are finished.
-     */
-    AVFrame released_buffers[MAX_BUFFERS];
-    int     num_released_buffers;
-
-    /**
-     * Array of progress values used by ff_thread_get_buffer().
-     */
-    int     progress[MAX_BUFFERS][2];
-    uint8_t progress_used[MAX_BUFFERS];
-
-    AVFrame *requested_frame;       ///< AVFrame the codec passed to get_buffer()
-} PerThreadContext;
-
-/**
- * Context stored in the client AVCodecContext thread_opaque.
- */
-typedef struct FrameThreadContext {
-    PerThreadContext *threads;     ///< The contexts for each thread.
-    PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
-
-    pthread_mutex_t buffer_mutex;  ///< Mutex used to protect get/release_buffer().
-
-    int next_decoding;             ///< The next context to submit a packet to.
-    int next_finished;             ///< The next context to return output from.
-
-    int delaying;                  /**<
-                                    * Set for the first N packets, where N is the number of threads.
-                                    * While it is set, ff_thread_en/decode_frame won't return any results.
-                                    */
-
-    int die;                       ///< Set when threads should exit.
-} FrameThreadContext;
-
-
-/* H264 slice threading seems to be buggy with more than 16 threads,
- * limit the number of threads to 16 for automatic detection */
-#define MAX_AUTO_THREADS 16
-
-static int get_logical_cpus(AVCodecContext *avctx)
-{
-    int ret, nb_cpus = 1;
-#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
-    cpu_set_t cpuset;
-
-    CPU_ZERO(&cpuset);
-
-    ret = sched_getaffinity(0, sizeof(cpuset), &cpuset);
-    if (!ret) {
-        nb_cpus = CPU_COUNT(&cpuset);
-    }
-#elif HAVE_GETPROCESSAFFINITYMASK
-    DWORD_PTR proc_aff, sys_aff;
-    ret = GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff);
-    if (ret)
-        nb_cpus = av_popcount64(proc_aff);
-#elif HAVE_SYSCTL && defined(HW_NCPU)
-    int mib[2] = { CTL_HW, HW_NCPU };
-    size_t len = sizeof(nb_cpus);
-
-    ret = sysctl(mib, 2, &nb_cpus, &len, NULL, 0);
-    if (ret == -1)
-        nb_cpus = 0;
-#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
-    nb_cpus = sysconf(_SC_NPROC_ONLN);
-#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
-    nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
-#endif
-    av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
-    return nb_cpus;
-}
-
-
-static void* attribute_align_arg worker(void *v)
-{
-    AVCodecContext *avctx = v;
-    ThreadContext *c = avctx->thread_opaque;
-    int our_job = c->job_count;
-    int thread_count = avctx->thread_count;
-    int self_id;
-
-    pthread_mutex_lock(&c->current_job_lock);
-    self_id = c->current_job++;
-    for (;;){
-        while (our_job >= c->job_count) {
-            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);
-            our_job = self_id;
-
-            if (c->done) {
-                pthread_mutex_unlock(&c->current_job_lock);
-                return NULL;
-            }
-        }
-        pthread_mutex_unlock(&c->current_job_lock);
-
-        c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size):
-                                                   c->func2(avctx, c->args, our_job, self_id);
-
-        pthread_mutex_lock(&c->current_job_lock);
-        our_job = c->current_job++;
-    }
-}
-
-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);
-    pthread_mutex_unlock(&c->current_job_lock);
-}
-
-static void thread_free(AVCodecContext *avctx)
-{
-    ThreadContext *c = avctx->thread_opaque;
-    int i;
-
-    pthread_mutex_lock(&c->current_job_lock);
-    c->done = 1;
-    pthread_cond_broadcast(&c->current_job_cond);
-    pthread_mutex_unlock(&c->current_job_lock);
-
-    for (i=0; i<avctx->thread_count; i++)
-         pthread_join(c->workers[i], NULL);
-
-    pthread_mutex_destroy(&c->current_job_lock);
-    pthread_cond_destroy(&c->current_job_cond);
-    pthread_cond_destroy(&c->last_job_cond);
-    av_free(c->workers);
-    av_freep(&avctx->thread_opaque);
-}
-
-static int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)
-{
-    ThreadContext *c= avctx->thread_opaque;
-    int dummy_ret;
-
-    if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1)
-        return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size);
-
-    if (job_count <= 0)
-        return 0;
-
-    pthread_mutex_lock(&c->current_job_lock);
-
-    c->current_job = avctx->thread_count;
-    c->job_count = job_count;
-    c->job_size = job_size;
-    c->args = arg;
-    c->func = func;
-    if (ret) {
-        c->rets = ret;
-        c->rets_count = job_count;
-    } else {
-        c->rets = &dummy_ret;
-        c->rets_count = 1;
-    }
-    pthread_cond_broadcast(&c->current_job_cond);
-
-    avcodec_thread_park_workers(c, avctx->thread_count);
-
-    return 0;
-}
-
-static int avcodec_thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count)
-{
-    ThreadContext *c= avctx->thread_opaque;
-    c->func2 = func2;
-    return avcodec_thread_execute(avctx, NULL, arg, ret, job_count, 0);
-}
-
-static int thread_init(AVCodecContext *avctx)
-{
-    int i;
-    ThreadContext *c;
-    int thread_count = avctx->thread_count;
-
-    if (!thread_count) {
-        int nb_cpus = 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);
-        else
-            thread_count = avctx->thread_count = 1;
-    }
-
-    if (thread_count <= 1) {
-        avctx->active_thread_type = 0;
-        return 0;
-    }
-
-    c = av_mallocz(sizeof(ThreadContext));
-    if (!c)
-        return -1;
-
-    c->workers = av_mallocz(sizeof(pthread_t)*thread_count);
-    if (!c->workers) {
-        av_free(c);
-        return -1;
-    }
-
-    avctx->thread_opaque = c;
-    c->current_job = 0;
-    c->job_count = 0;
-    c->job_size = 0;
-    c->done = 0;
-    pthread_cond_init(&c->current_job_cond, NULL);
-    pthread_cond_init(&c->last_job_cond, NULL);
-    pthread_mutex_init(&c->current_job_lock, NULL);
-    pthread_mutex_lock(&c->current_job_lock);
-    for (i=0; i<thread_count; i++) {
-        if(pthread_create(&c->workers[i], NULL, worker, avctx)) {
-           avctx->thread_count = i;
-           pthread_mutex_unlock(&c->current_job_lock);
-           ff_thread_free(avctx);
-           return -1;
-        }
-    }
-
-    avcodec_thread_park_workers(c, thread_count);
-
-    avctx->execute = avcodec_thread_execute;
-    avctx->execute2 = avcodec_thread_execute2;
-    return 0;
-}
-
-/**
- * Codec worker thread.
- *
- * Automatically calls ff_thread_finish_setup() if the codec does
- * not provide an update_thread_context method, or if the codec returns
- * before calling it.
- */
-static attribute_align_arg void *frame_worker_thread(void *arg)
-{
-    PerThreadContext *p = arg;
-    FrameThreadContext *fctx = p->parent;
-    AVCodecContext *avctx = p->avctx;
-    const AVCodec *codec = avctx->codec;
-
-    while (1) {
-        if (p->state == STATE_INPUT_READY && !fctx->die) {
-            pthread_mutex_lock(&p->mutex);
-            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)
-            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);
-
-        /* many decoders assign whole AVFrames, thus overwriting extended_data;
-         * make sure it's set correctly */
-        p->frame.extended_data = p->frame.data;
-
-        if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
-
-        p->state = STATE_INPUT_READY;
-
-        pthread_mutex_lock(&p->progress_mutex);
-        pthread_cond_signal(&p->output_cond);
-        pthread_mutex_unlock(&p->progress_mutex);
-
-        pthread_mutex_unlock(&p->mutex);
-    }
-
-    return NULL;
-}
-
-/**
- * Update the next thread's AVCodecContext with values from the reference thread's context.
- *
- * @param dst The destination context.
- * @param src The source context.
- * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
- */
-static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user)
-{
-    int err = 0;
-
-    if (dst != src) {
-        dst->time_base = src->time_base;
-        dst->width     = src->width;
-        dst->height    = src->height;
-        dst->pix_fmt   = src->pix_fmt;
-
-        dst->coded_width  = src->coded_width;
-        dst->coded_height = src->coded_height;
-
-        dst->has_b_frames = src->has_b_frames;
-        dst->idct_algo    = src->idct_algo;
-
-        dst->bits_per_coded_sample = src->bits_per_coded_sample;
-        dst->sample_aspect_ratio   = src->sample_aspect_ratio;
-        dst->dtg_active_format     = src->dtg_active_format;
-
-        dst->profile = src->profile;
-        dst->level   = src->level;
-
-        dst->bits_per_raw_sample = src->bits_per_raw_sample;
-        dst->ticks_per_frame     = src->ticks_per_frame;
-        dst->color_primaries     = src->color_primaries;
-
-        dst->color_trc   = src->color_trc;
-        dst->colorspace  = src->colorspace;
-        dst->color_range = src->color_range;
-        dst->chroma_sample_location = src->chroma_sample_location;
-    }
-
-    if (for_user) {
-        dst->coded_frame = src->coded_frame;
-    } else {
-        if (dst->codec->update_thread_context)
-            err = dst->codec->update_thread_context(dst, src);
-    }
-
-    return err;
-}
-
-/**
- * Update the next thread's AVCodecContext with values set by the user.
- *
- * @param dst The destination context.
- * @param src The source context.
- * @return 0 on success, negative error code on failure
- */
-static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
-{
-#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s);
-    dst->flags          = src->flags;
-
-    dst->draw_horiz_band= src->draw_horiz_band;
-    dst->get_buffer     = src->get_buffer;
-    dst->release_buffer = src->release_buffer;
-
-    dst->opaque   = src->opaque;
-    dst->debug    = src->debug;
-    dst->debug_mv = src->debug_mv;
-
-    dst->slice_flags = src->slice_flags;
-    dst->flags2      = src->flags2;
-
-    copy_fields(skip_loop_filter, subtitle_header);
-
-    dst->frame_number     = src->frame_number;
-    dst->reordered_opaque = src->reordered_opaque;
-
-    if (src->slice_count && src->slice_offset) {
-        if (dst->slice_count < src->slice_count) {
-            int *tmp = av_realloc(dst->slice_offset, src->slice_count *
-                                  sizeof(*dst->slice_offset));
-            if (!tmp) {
-                av_free(dst->slice_offset);
-                return AVERROR(ENOMEM);
-            }
-            dst->slice_offset = tmp;
-        }
-        memcpy(dst->slice_offset, src->slice_offset,
-               src->slice_count * sizeof(*dst->slice_offset));
-    }
-    dst->slice_count = src->slice_count;
-    return 0;
-#undef copy_fields
-}
-
-static void free_progress(AVFrame *f)
-{
-    PerThreadContext *p = f->owner->thread_opaque;
-    int *progress = f->thread_opaque;
-
-    p->progress_used[(progress - p->progress[0]) / 2] = 0;
-}
-
-/// Releases the buffers that this decoding thread was the last user of.
-static void release_delayed_buffers(PerThreadContext *p)
-{
-    FrameThreadContext *fctx = p->parent;
-
-    while (p->num_released_buffers > 0) {
-        AVFrame *f;
-
-        pthread_mutex_lock(&fctx->buffer_mutex);
-        f = &p->released_buffers[--p->num_released_buffers];
-        free_progress(f);
-        f->thread_opaque = NULL;
-
-        f->owner->release_buffer(f->owner, f);
-        pthread_mutex_unlock(&fctx->buffer_mutex);
-    }
-}
-
-static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
-{
-    FrameThreadContext *fctx = p->parent;
-    PerThreadContext *prev_thread = fctx->prev_thread;
-    const AVCodec *codec = p->avctx->codec;
-    uint8_t *buf = p->avpkt.data;
-
-    if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0;
-
-    pthread_mutex_lock(&p->mutex);
-
-    release_delayed_buffers(p);
-
-    if (prev_thread) {
-        int err;
-        if (prev_thread->state == STATE_SETTING_UP) {
-            pthread_mutex_lock(&prev_thread->progress_mutex);
-            while (prev_thread->state == STATE_SETTING_UP)
-                pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
-            pthread_mutex_unlock(&prev_thread->progress_mutex);
-        }
-
-        err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
-        if (err) {
-            pthread_mutex_unlock(&p->mutex);
-            return err;
-        }
-    }
-
-    av_fast_malloc(&buf, &p->allocated_buf_size, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
-    p->avpkt = *avpkt;
-    p->avpkt.data = buf;
-    memcpy(buf, avpkt->data, avpkt->size);
-    memset(buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-
-    p->state = STATE_SETTING_UP;
-    pthread_cond_signal(&p->input_cond);
-    pthread_mutex_unlock(&p->mutex);
-
-    /*
-     * If the client doesn't have a thread-safe get_buffer(),
-     * then decoding threads call back to the main thread,
-     * and it calls back to the client here.
-     */
-
-    if (!p->avctx->thread_safe_callbacks &&
-         p->avctx->get_buffer != avcodec_default_get_buffer) {
-        while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) {
-            pthread_mutex_lock(&p->progress_mutex);
-            while (p->state == STATE_SETTING_UP)
-                pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
-
-            if (p->state == STATE_GET_BUFFER) {
-                p->result = ff_get_buffer(p->avctx, p->requested_frame);
-                p->state  = STATE_SETTING_UP;
-                pthread_cond_signal(&p->progress_cond);
-            }
-            pthread_mutex_unlock(&p->progress_mutex);
-        }
-    }
-
-    fctx->prev_thread = p;
-    fctx->next_decoding++;
-
-    return 0;
-}
-
-int ff_thread_decode_frame(AVCodecContext *avctx,
-                           AVFrame *picture, int *got_picture_ptr,
-                           AVPacket *avpkt)
-{
-    FrameThreadContext *fctx = avctx->thread_opaque;
-    int finished = fctx->next_finished;
-    PerThreadContext *p;
-    int err;
-
-    /*
-     * Submit a packet to the next decoding thread.
-     */
-
-    p = &fctx->threads[fctx->next_decoding];
-    err = update_context_from_user(p->avctx, avctx);
-    if (err) return err;
-    err = submit_packet(p, avpkt);
-    if (err) return err;
-
-    /*
-     * If we're still receiving the initial packets, don't return a frame.
-     */
-
-    if (fctx->delaying) {
-        if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0;
-
-        *got_picture_ptr=0;
-        if (avpkt->size)
-            return avpkt->size;
-    }
-
-    /*
-     * Return the next available frame from the oldest thread.
-     * If we're at the end of the stream, then we have to skip threads that
-     * didn't output a frame, because we don't want to accidentally signal
-     * EOF (avpkt->size == 0 && *got_picture_ptr == 0).
-     */
-
-    do {
-        p = &fctx->threads[finished++];
-
-        if (p->state != STATE_INPUT_READY) {
-            pthread_mutex_lock(&p->progress_mutex);
-            while (p->state != STATE_INPUT_READY)
-                pthread_cond_wait(&p->output_cond, &p->progress_mutex);
-            pthread_mutex_unlock(&p->progress_mutex);
-        }
-
-        *picture = p->frame;
-        *got_picture_ptr = p->got_frame;
-        picture->pkt_dts = p->avpkt.dts;
-
-        /*
-         * A later call with avkpt->size == 0 may loop over all threads,
-         * including this one, searching for a frame to return before being
-         * stopped by the "finished != fctx->next_finished" condition.
-         * Make sure we don't mistakenly return the same frame again.
-         */
-        p->got_frame = 0;
-
-        if (finished >= avctx->thread_count) finished = 0;
-    } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished);
-
-    update_context_from_thread(avctx, p->avctx, 1);
-
-    if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
-
-    fctx->next_finished = finished;
-
-    /* return the size of the consumed packet if no error occurred */
-    return (p->result >= 0) ? avpkt->size : p->result;
-}
-
-void ff_thread_report_progress(AVFrame *f, int n, int field)
-{
-    PerThreadContext *p;
-    int *progress = f->thread_opaque;
-
-    if (!progress || progress[field] >= n) return;
-
-    p = f->owner->thread_opaque;
-
-    if (f->owner->debug&FF_DEBUG_THREADS)
-        av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field);
-
-    pthread_mutex_lock(&p->progress_mutex);
-    progress[field] = n;
-    pthread_cond_broadcast(&p->progress_cond);
-    pthread_mutex_unlock(&p->progress_mutex);
-}
-
-void ff_thread_await_progress(AVFrame *f, int n, int field)
-{
-    PerThreadContext *p;
-    int *progress = f->thread_opaque;
-
-    if (!progress || progress[field] >= n) return;
-
-    p = f->owner->thread_opaque;
-
-    if (f->owner->debug&FF_DEBUG_THREADS)
-        av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress);
-
-    pthread_mutex_lock(&p->progress_mutex);
-    while (progress[field] < n)
-        pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
-    pthread_mutex_unlock(&p->progress_mutex);
-}
-
-void ff_thread_finish_setup(AVCodecContext *avctx) {
-    PerThreadContext *p = avctx->thread_opaque;
-
-    if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
-
-    pthread_mutex_lock(&p->progress_mutex);
-    p->state = STATE_SETUP_FINISHED;
-    pthread_cond_broadcast(&p->progress_cond);
-    pthread_mutex_unlock(&p->progress_mutex);
-}
-
-/// Waits for all threads to finish.
-static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
-{
-    int i;
-
-    for (i = 0; i < thread_count; i++) {
-        PerThreadContext *p = &fctx->threads[i];
-
-        if (p->state != STATE_INPUT_READY) {
-            pthread_mutex_lock(&p->progress_mutex);
-            while (p->state != STATE_INPUT_READY)
-                pthread_cond_wait(&p->output_cond, &p->progress_mutex);
-            pthread_mutex_unlock(&p->progress_mutex);
-        }
-    }
-}
-
-static void frame_thread_free(AVCodecContext *avctx, int thread_count)
-{
-    FrameThreadContext *fctx = avctx->thread_opaque;
-    const AVCodec *codec = avctx->codec;
-    int i;
-
-    park_frame_worker_threads(fctx, thread_count);
-
-    if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
-        update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0);
-
-    fctx->die = 1;
-
-    for (i = 0; i < thread_count; i++) {
-        PerThreadContext *p = &fctx->threads[i];
-
-        pthread_mutex_lock(&p->mutex);
-        pthread_cond_signal(&p->input_cond);
-        pthread_mutex_unlock(&p->mutex);
-
-        if (p->thread_init)
-            pthread_join(p->thread, NULL);
-
-        if (codec->close)
-            codec->close(p->avctx);
-
-        avctx->codec = NULL;
-
-        release_delayed_buffers(p);
-    }
-
-    for (i = 0; i < thread_count; i++) {
-        PerThreadContext *p = &fctx->threads[i];
-
-        avcodec_default_free_buffers(p->avctx);
-
-        pthread_mutex_destroy(&p->mutex);
-        pthread_mutex_destroy(&p->progress_mutex);
-        pthread_cond_destroy(&p->input_cond);
-        pthread_cond_destroy(&p->progress_cond);
-        pthread_cond_destroy(&p->output_cond);
-        av_freep(&p->avpkt.data);
-
-        if (i) {
-            av_freep(&p->avctx->priv_data);
-            av_freep(&p->avctx->internal);
-            av_freep(&p->avctx->slice_offset);
-        }
-
-        av_freep(&p->avctx);
-    }
-
-    av_freep(&fctx->threads);
-    pthread_mutex_destroy(&fctx->buffer_mutex);
-    av_freep(&avctx->thread_opaque);
-}
-
-static int frame_thread_init(AVCodecContext *avctx)
-{
-    int thread_count = avctx->thread_count;
-    const AVCodec *codec = avctx->codec;
-    AVCodecContext *src = avctx;
-    FrameThreadContext *fctx;
-    int i, err = 0;
-
-    if (!thread_count) {
-        int nb_cpus = 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);
-        else
-            thread_count = avctx->thread_count = 1;
-    }
-
-    if (thread_count <= 1) {
-        avctx->active_thread_type = 0;
-        return 0;
-    }
-
-    avctx->thread_opaque = fctx = av_mallocz(sizeof(FrameThreadContext));
-
-    fctx->threads = av_mallocz(sizeof(PerThreadContext) * thread_count);
-    pthread_mutex_init(&fctx->buffer_mutex, NULL);
-    fctx->delaying = 1;
-
-    for (i = 0; i < thread_count; i++) {
-        AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
-        PerThreadContext *p  = &fctx->threads[i];
-
-        pthread_mutex_init(&p->mutex, NULL);
-        pthread_mutex_init(&p->progress_mutex, NULL);
-        pthread_cond_init(&p->input_cond, NULL);
-        pthread_cond_init(&p->progress_cond, NULL);
-        pthread_cond_init(&p->output_cond, NULL);
-
-        p->parent = fctx;
-        p->avctx  = copy;
-
-        if (!copy) {
-            err = AVERROR(ENOMEM);
-            goto error;
-        }
-
-        *copy = *src;
-        copy->thread_opaque = p;
-        copy->pkt = &p->avpkt;
-
-        if (!i) {
-            src = copy;
-
-            if (codec->init)
-                err = codec->init(copy);
-
-            update_context_from_thread(avctx, copy, 1);
-        } else {
-            copy->priv_data = av_malloc(codec->priv_data_size);
-            if (!copy->priv_data) {
-                err = AVERROR(ENOMEM);
-                goto error;
-            }
-            memcpy(copy->priv_data, src->priv_data, codec->priv_data_size);
-            copy->internal = av_malloc(sizeof(AVCodecInternal));
-            if (!copy->internal) {
-                err = AVERROR(ENOMEM);
-                goto error;
-            }
-            *copy->internal = *src->internal;
-            copy->internal->is_copy = 1;
-
-            if (codec->init_thread_copy)
-                err = codec->init_thread_copy(copy);
-        }
-
-        if (err) goto error;
-
-        if (!pthread_create(&p->thread, NULL, frame_worker_thread, p))
-            p->thread_init = 1;
-    }
-
-    return 0;
-
-error:
-    frame_thread_free(avctx, i+1);
-
-    return err;
-}
-
-void ff_thread_flush(AVCodecContext *avctx)
-{
-    int i;
-    FrameThreadContext *fctx = avctx->thread_opaque;
-
-    if (!avctx->thread_opaque) return;
-
-    park_frame_worker_threads(fctx, avctx->thread_count);
-    if (fctx->prev_thread) {
-        if (fctx->prev_thread != &fctx->threads[0])
-            update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);
-        if (avctx->codec->flush)
-            avctx->codec->flush(fctx->threads[0].avctx);
-    }
-
-    fctx->next_decoding = fctx->next_finished = 0;
-    fctx->delaying = 1;
-    fctx->prev_thread = NULL;
-    for (i = 0; i < avctx->thread_count; i++) {
-        PerThreadContext *p = &fctx->threads[i];
-        // Make sure decode flush calls with size=0 won't return old frames
-        p->got_frame = 0;
-
-        release_delayed_buffers(p);
-    }
-}
-
-static int *allocate_progress(PerThreadContext *p)
-{
-    int i;
-
-    for (i = 0; i < MAX_BUFFERS; i++)
-        if (!p->progress_used[i]) break;
-
-    if (i == MAX_BUFFERS) {
-        av_log(p->avctx, AV_LOG_ERROR, "allocate_progress() overflow\n");
-        return NULL;
-    }
-
-    p->progress_used[i] = 1;
-
-    return p->progress[i];
-}
-
-int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
-{
-    PerThreadContext *p = avctx->thread_opaque;
-    int *progress, err;
-
-    f->owner = avctx;
-
-    if (!(avctx->active_thread_type&FF_THREAD_FRAME)) {
-        f->thread_opaque = NULL;
-        return ff_get_buffer(avctx, f);
-    }
-
-    if (p->state != STATE_SETTING_UP &&
-        (avctx->codec->update_thread_context || !avctx->thread_safe_callbacks)) {
-        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);
-
-    if (!progress) {
-        pthread_mutex_unlock(&p->parent->buffer_mutex);
-        return -1;
-    }
-
-    progress[0] =
-    progress[1] = -1;
-
-    if (avctx->thread_safe_callbacks ||
-        avctx->get_buffer == avcodec_default_get_buffer) {
-        err = ff_get_buffer(avctx, f);
-    } else {
-        p->requested_frame = f;
-        p->state = STATE_GET_BUFFER;
-        pthread_mutex_lock(&p->progress_mutex);
-        pthread_cond_signal(&p->progress_cond);
-
-        while (p->state != STATE_SETTING_UP)
-            pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
-
-        err = p->result;
-
-        pthread_mutex_unlock(&p->progress_mutex);
-
-        if (!avctx->codec->update_thread_context)
-            ff_thread_finish_setup(avctx);
-    }
-
-    if (err) {
-        free_progress(f);
-        f->thread_opaque = NULL;
-    }
-    pthread_mutex_unlock(&p->parent->buffer_mutex);
-
-    return err;
-}
-
-void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
-{
-    PerThreadContext *p = avctx->thread_opaque;
-    FrameThreadContext *fctx;
-
-    if (!(avctx->active_thread_type&FF_THREAD_FRAME)) {
-        avctx->release_buffer(avctx, f);
-        return;
-    }
-
-    if (p->num_released_buffers >= MAX_BUFFERS) {
-        av_log(p->avctx, AV_LOG_ERROR, "too many thread_release_buffer calls!\n");
-        return;
-    }
-
-    if(avctx->debug & FF_DEBUG_BUFFERS)
-        av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
-
-    fctx = p->parent;
-    pthread_mutex_lock(&fctx->buffer_mutex);
-    p->released_buffers[p->num_released_buffers++] = *f;
-    pthread_mutex_unlock(&fctx->buffer_mutex);
-    memset(f->data, 0, sizeof(f->data));
-}
 
 /**
  * Set the threading algorithms used.
@@ -1030,23 +69,12 @@ static void validate_thread_parameters(AVCodecContext *avctx)
 
 int ff_thread_init(AVCodecContext *avctx)
 {
-    if (avctx->thread_opaque) {
-        av_log(avctx, AV_LOG_ERROR, "avcodec_thread_init is ignored after avcodec_open\n");
-        return -1;
-    }
-
-#if HAVE_W32THREADS
-    w32thread_init();
-#endif
+    validate_thread_parameters(avctx);
 
-    if (avctx->codec) {
-        validate_thread_parameters(avctx);
-
-        if (avctx->active_thread_type&FF_THREAD_SLICE)
-            return thread_init(avctx);
-        else if (avctx->active_thread_type&FF_THREAD_FRAME)
-            return frame_thread_init(avctx);
-    }
+    if (avctx->active_thread_type&FF_THREAD_SLICE)
+        return ff_slice_thread_init(avctx);
+    else if (avctx->active_thread_type&FF_THREAD_FRAME)
+        return ff_frame_thread_init(avctx);
 
     return 0;
 }
@@ -1054,7 +82,7 @@ int ff_thread_init(AVCodecContext *avctx)
 void ff_thread_free(AVCodecContext *avctx)
 {
     if (avctx->active_thread_type&FF_THREAD_FRAME)
-        frame_thread_free(avctx, avctx->thread_count);
+        ff_frame_thread_free(avctx, avctx->thread_count);
     else
-        thread_free(avctx);
+        ff_slice_thread_free(avctx);
 }
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
new file mode 100644
index 0000000..ece0e80
--- /dev/null
+++ b/libavcodec/pthread_frame.c
@@ -0,0 +1,795 @@
+/*
+ * 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
+ * Frame multithreading support functions
+ * @see doc/multithreading.txt
+ */
+
+#include "config.h"
+
+#include <stdint.h>
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "compat/w32pthreads.h"
+#endif
+
+#include "avcodec.h"
+#include "internal.h"
+#include "pthread_internal.h"
+#include "thread.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/buffer.h"
+#include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/frame.h"
+#include "libavutil/log.h"
+#include "libavutil/mem.h"
+
+/**
+ * Context used by codec threads and stored in their AVCodecInternal thread_ctx.
+ */
+typedef struct PerThreadContext {
+    struct FrameThreadContext *parent;
+
+    pthread_t      thread;
+    int            thread_init;
+    pthread_cond_t input_cond;      ///< Used to wait for a new packet from the main thread.
+    pthread_cond_t progress_cond;   ///< Used by child threads to wait for progress to change.
+    pthread_cond_t output_cond;     ///< Used by the main thread to wait for frames to finish.
+
+    pthread_mutex_t mutex;          ///< Mutex used to protect the contents of the PerThreadContext.
+    pthread_mutex_t progress_mutex; ///< Mutex used to protect frame progress values and progress_cond.
+
+    AVCodecContext *avctx;          ///< Context used to decode packets passed to this thread.
+
+    AVPacket       avpkt;           ///< Input packet (for decoding) or output (for encoding).
+    uint8_t       *buf;             ///< backup storage for packet data when the input packet is not refcounted
+    int            allocated_buf_size; ///< Size allocated for buf
+
+    AVFrame *frame;                 ///< Output frame (for decoding) or input (for encoding).
+    int     got_frame;              ///< The output of got_picture_ptr from the last avcodec_decode_video() call.
+    int     result;                 ///< The result of the last codec decode/encode() call.
+
+    enum {
+        STATE_INPUT_READY,          ///< Set when the thread is awaiting a packet.
+        STATE_SETTING_UP,           ///< Set before the codec has called ff_thread_finish_setup().
+        STATE_GET_BUFFER,           /**<
+                                     * Set when the codec calls get_buffer().
+                                     * State is returned to STATE_SETTING_UP afterwards.
+                                     */
+        STATE_SETUP_FINISHED        ///< Set after the codec has called ff_thread_finish_setup().
+    } state;
+
+    /**
+     * Array of frames passed to ff_thread_release_buffer().
+     * Frames are released after all threads referencing them are finished.
+     */
+    AVFrame *released_buffers;
+    int  num_released_buffers;
+    int      released_buffers_allocated;
+
+    AVFrame *requested_frame;       ///< AVFrame the codec passed to get_buffer()
+    int      requested_flags;       ///< flags passed to get_buffer() for requested_frame
+} PerThreadContext;
+
+/**
+ * Context stored in the client AVCodecInternal thread_ctx.
+ */
+typedef struct FrameThreadContext {
+    PerThreadContext *threads;     ///< The contexts for each thread.
+    PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on.
+
+    pthread_mutex_t buffer_mutex;  ///< Mutex used to protect get/release_buffer().
+
+    int next_decoding;             ///< The next context to submit a packet to.
+    int next_finished;             ///< The next context to return output from.
+
+    int delaying;                  /**<
+                                    * Set for the first N packets, where N is the number of threads.
+                                    * While it is set, ff_thread_en/decode_frame won't return any results.
+                                    */
+
+    int die;                       ///< Set when threads should exit.
+} FrameThreadContext;
+
+/**
+ * Codec worker thread.
+ *
+ * Automatically calls ff_thread_finish_setup() if the codec does
+ * not provide an update_thread_context method, or if the codec returns
+ * before calling it.
+ */
+static attribute_align_arg void *frame_worker_thread(void *arg)
+{
+    PerThreadContext *p = arg;
+    FrameThreadContext *fctx = p->parent;
+    AVCodecContext *avctx = p->avctx;
+    const AVCodec *codec = avctx->codec;
+
+    while (1) {
+        if (p->state == STATE_INPUT_READY && !fctx->die) {
+            pthread_mutex_lock(&p->mutex);
+            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)
+            ff_thread_finish_setup(avctx);
+
+        pthread_mutex_lock(&p->mutex);
+        av_frame_unref(p->frame);
+        p->got_frame = 0;
+        p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt);
+
+        if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
+
+        p->state = STATE_INPUT_READY;
+
+        pthread_mutex_lock(&p->progress_mutex);
+        pthread_cond_signal(&p->output_cond);
+        pthread_mutex_unlock(&p->progress_mutex);
+
+        pthread_mutex_unlock(&p->mutex);
+    }
+
+    return NULL;
+}
+
+/**
+ * Update the next thread's AVCodecContext with values from the reference thread's context.
+ *
+ * @param dst The destination context.
+ * @param src The source context.
+ * @param for_user 0 if the destination is a codec thread, 1 if the destination is the user's thread
+ */
+static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, int for_user)
+{
+    int err = 0;
+
+    if (dst != src) {
+        dst->time_base = src->time_base;
+        dst->width     = src->width;
+        dst->height    = src->height;
+        dst->pix_fmt   = src->pix_fmt;
+
+        dst->coded_width  = src->coded_width;
+        dst->coded_height = src->coded_height;
+
+        dst->has_b_frames = src->has_b_frames;
+        dst->idct_algo    = src->idct_algo;
+
+        dst->bits_per_coded_sample = src->bits_per_coded_sample;
+        dst->sample_aspect_ratio   = src->sample_aspect_ratio;
+        dst->dtg_active_format     = src->dtg_active_format;
+
+        dst->profile = src->profile;
+        dst->level   = src->level;
+
+        dst->bits_per_raw_sample = src->bits_per_raw_sample;
+        dst->ticks_per_frame     = src->ticks_per_frame;
+        dst->color_primaries     = src->color_primaries;
+
+        dst->color_trc   = src->color_trc;
+        dst->colorspace  = src->colorspace;
+        dst->color_range = src->color_range;
+        dst->chroma_sample_location = src->chroma_sample_location;
+
+        dst->hwaccel = src->hwaccel;
+        dst->hwaccel_context = src->hwaccel_context;
+    }
+
+    if (for_user) {
+        dst->coded_frame = src->coded_frame;
+    } else {
+        if (dst->codec->update_thread_context)
+            err = dst->codec->update_thread_context(dst, src);
+    }
+
+    return err;
+}
+
+/**
+ * Update the next thread's AVCodecContext with values set by the user.
+ *
+ * @param dst The destination context.
+ * @param src The source context.
+ * @return 0 on success, negative error code on failure
+ */
+static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
+{
+#define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s);
+    dst->flags          = src->flags;
+
+    dst->draw_horiz_band= src->draw_horiz_band;
+    dst->get_buffer2    = src->get_buffer2;
+#if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
+    dst->get_buffer     = src->get_buffer;
+    dst->release_buffer = src->release_buffer;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+    dst->opaque   = src->opaque;
+    dst->debug    = src->debug;
+
+    dst->slice_flags = src->slice_flags;
+    dst->flags2      = src->flags2;
+
+    copy_fields(skip_loop_filter, subtitle_header);
+
+    dst->frame_number     = src->frame_number;
+    dst->reordered_opaque = src->reordered_opaque;
+
+    if (src->slice_count && src->slice_offset) {
+        if (dst->slice_count < src->slice_count) {
+            int *tmp = av_realloc(dst->slice_offset, src->slice_count *
+                                  sizeof(*dst->slice_offset));
+            if (!tmp) {
+                av_free(dst->slice_offset);
+                return AVERROR(ENOMEM);
+            }
+            dst->slice_offset = tmp;
+        }
+        memcpy(dst->slice_offset, src->slice_offset,
+               src->slice_count * sizeof(*dst->slice_offset));
+    }
+    dst->slice_count = src->slice_count;
+    return 0;
+#undef copy_fields
+}
+
+/// Releases the buffers that this decoding thread was the last user of.
+static void release_delayed_buffers(PerThreadContext *p)
+{
+    FrameThreadContext *fctx = p->parent;
+
+    while (p->num_released_buffers > 0) {
+        AVFrame *f;
+
+        pthread_mutex_lock(&fctx->buffer_mutex);
+
+        // fix extended data in case the caller screwed it up
+        av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO);
+        f = &p->released_buffers[--p->num_released_buffers];
+        f->extended_data = f->data;
+        av_frame_unref(f);
+
+        pthread_mutex_unlock(&fctx->buffer_mutex);
+    }
+}
+
+static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
+{
+    FrameThreadContext *fctx = p->parent;
+    PerThreadContext *prev_thread = fctx->prev_thread;
+    const AVCodec *codec = p->avctx->codec;
+
+    if (!avpkt->size && !(codec->capabilities & CODEC_CAP_DELAY)) return 0;
+
+    pthread_mutex_lock(&p->mutex);
+
+    release_delayed_buffers(p);
+
+    if (prev_thread) {
+        int err;
+        if (prev_thread->state == STATE_SETTING_UP) {
+            pthread_mutex_lock(&prev_thread->progress_mutex);
+            while (prev_thread->state == STATE_SETTING_UP)
+                pthread_cond_wait(&prev_thread->progress_cond, &prev_thread->progress_mutex);
+            pthread_mutex_unlock(&prev_thread->progress_mutex);
+        }
+
+        err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
+        if (err) {
+            pthread_mutex_unlock(&p->mutex);
+            return err;
+        }
+    }
+
+    av_buffer_unref(&p->avpkt.buf);
+    p->avpkt = *avpkt;
+    if (avpkt->buf)
+        p->avpkt.buf = av_buffer_ref(avpkt->buf);
+    else {
+        av_fast_malloc(&p->buf, &p->allocated_buf_size, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
+        p->avpkt.data = p->buf;
+        memcpy(p->buf, avpkt->data, avpkt->size);
+        memset(p->buf + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    }
+
+    p->state = STATE_SETTING_UP;
+    pthread_cond_signal(&p->input_cond);
+    pthread_mutex_unlock(&p->mutex);
+
+    /*
+     * If the client doesn't have a thread-safe get_buffer(),
+     * then decoding threads call back to the main thread,
+     * and it calls back to the client here.
+     */
+
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (!p->avctx->thread_safe_callbacks && (
+#if FF_API_GET_BUFFER
+         p->avctx->get_buffer ||
+#endif
+         p->avctx->get_buffer2 != avcodec_default_get_buffer2)) {
+FF_ENABLE_DEPRECATION_WARNINGS
+        while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) {
+            pthread_mutex_lock(&p->progress_mutex);
+            while (p->state == STATE_SETTING_UP)
+                pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
+
+            if (p->state == STATE_GET_BUFFER) {
+                p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags);
+                p->state  = STATE_SETTING_UP;
+                pthread_cond_signal(&p->progress_cond);
+            }
+            pthread_mutex_unlock(&p->progress_mutex);
+        }
+    }
+
+    fctx->prev_thread = p;
+    fctx->next_decoding++;
+
+    return 0;
+}
+
+int ff_thread_decode_frame(AVCodecContext *avctx,
+                           AVFrame *picture, int *got_picture_ptr,
+                           AVPacket *avpkt)
+{
+    FrameThreadContext *fctx = avctx->internal->thread_ctx;
+    int finished = fctx->next_finished;
+    PerThreadContext *p;
+    int err;
+
+    /*
+     * Submit a packet to the next decoding thread.
+     */
+
+    p = &fctx->threads[fctx->next_decoding];
+    err = update_context_from_user(p->avctx, avctx);
+    if (err) return err;
+    err = submit_packet(p, avpkt);
+    if (err) return err;
+
+    /*
+     * If we're still receiving the initial packets, don't return a frame.
+     */
+
+    if (fctx->delaying) {
+        if (fctx->next_decoding >= (avctx->thread_count-1)) fctx->delaying = 0;
+
+        *got_picture_ptr=0;
+        if (avpkt->size)
+            return avpkt->size;
+    }
+
+    /*
+     * Return the next available frame from the oldest thread.
+     * If we're at the end of the stream, then we have to skip threads that
+     * didn't output a frame, because we don't want to accidentally signal
+     * EOF (avpkt->size == 0 && *got_picture_ptr == 0).
+     */
+
+    do {
+        p = &fctx->threads[finished++];
+
+        if (p->state != STATE_INPUT_READY) {
+            pthread_mutex_lock(&p->progress_mutex);
+            while (p->state != STATE_INPUT_READY)
+                pthread_cond_wait(&p->output_cond, &p->progress_mutex);
+            pthread_mutex_unlock(&p->progress_mutex);
+        }
+
+        av_frame_move_ref(picture, p->frame);
+        *got_picture_ptr = p->got_frame;
+        picture->pkt_dts = p->avpkt.dts;
+
+        /*
+         * A later call with avkpt->size == 0 may loop over all threads,
+         * including this one, searching for a frame to return before being
+         * stopped by the "finished != fctx->next_finished" condition.
+         * Make sure we don't mistakenly return the same frame again.
+         */
+        p->got_frame = 0;
+
+        if (finished >= avctx->thread_count) finished = 0;
+    } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished);
+
+    update_context_from_thread(avctx, p->avctx, 1);
+
+    if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
+
+    fctx->next_finished = finished;
+
+    /* return the size of the consumed packet if no error occurred */
+    return (p->result >= 0) ? avpkt->size : p->result;
+}
+
+void ff_thread_report_progress(ThreadFrame *f, int n, int field)
+{
+    PerThreadContext *p;
+    int *progress = f->progress ? (int*)f->progress->data : NULL;
+
+    if (!progress || progress[field] >= n) return;
+
+    p = f->owner->internal->thread_ctx;
+
+    if (f->owner->debug&FF_DEBUG_THREADS)
+        av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, n, field);
+
+    pthread_mutex_lock(&p->progress_mutex);
+    progress[field] = n;
+    pthread_cond_broadcast(&p->progress_cond);
+    pthread_mutex_unlock(&p->progress_mutex);
+}
+
+void ff_thread_await_progress(ThreadFrame *f, int n, int field)
+{
+    PerThreadContext *p;
+    int *progress = f->progress ? (int*)f->progress->data : NULL;
+
+    if (!progress || progress[field] >= n) return;
+
+    p = f->owner->internal->thread_ctx;
+
+    if (f->owner->debug&FF_DEBUG_THREADS)
+        av_log(f->owner, AV_LOG_DEBUG, "thread awaiting %d field %d from %p\n", n, field, progress);
+
+    pthread_mutex_lock(&p->progress_mutex);
+    while (progress[field] < n)
+        pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
+    pthread_mutex_unlock(&p->progress_mutex);
+}
+
+void ff_thread_finish_setup(AVCodecContext *avctx) {
+    PerThreadContext *p = avctx->internal->thread_ctx;
+
+    if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
+
+    pthread_mutex_lock(&p->progress_mutex);
+    p->state = STATE_SETUP_FINISHED;
+    pthread_cond_broadcast(&p->progress_cond);
+    pthread_mutex_unlock(&p->progress_mutex);
+}
+
+/// Waits for all threads to finish.
+static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count)
+{
+    int i;
+
+    for (i = 0; i < thread_count; i++) {
+        PerThreadContext *p = &fctx->threads[i];
+
+        if (p->state != STATE_INPUT_READY) {
+            pthread_mutex_lock(&p->progress_mutex);
+            while (p->state != STATE_INPUT_READY)
+                pthread_cond_wait(&p->output_cond, &p->progress_mutex);
+            pthread_mutex_unlock(&p->progress_mutex);
+        }
+    }
+}
+
+void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
+{
+    FrameThreadContext *fctx = avctx->internal->thread_ctx;
+    const AVCodec *codec = avctx->codec;
+    int i;
+
+    park_frame_worker_threads(fctx, thread_count);
+
+    if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
+        update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0);
+
+    fctx->die = 1;
+
+    for (i = 0; i < thread_count; i++) {
+        PerThreadContext *p = &fctx->threads[i];
+
+        pthread_mutex_lock(&p->mutex);
+        pthread_cond_signal(&p->input_cond);
+        pthread_mutex_unlock(&p->mutex);
+
+        if (p->thread_init)
+            pthread_join(p->thread, NULL);
+
+        if (codec->close)
+            codec->close(p->avctx);
+
+        avctx->codec = NULL;
+
+        release_delayed_buffers(p);
+        av_frame_free(&p->frame);
+    }
+
+    for (i = 0; i < thread_count; i++) {
+        PerThreadContext *p = &fctx->threads[i];
+
+        pthread_mutex_destroy(&p->mutex);
+        pthread_mutex_destroy(&p->progress_mutex);
+        pthread_cond_destroy(&p->input_cond);
+        pthread_cond_destroy(&p->progress_cond);
+        pthread_cond_destroy(&p->output_cond);
+        av_buffer_unref(&p->avpkt.buf);
+        av_freep(&p->buf);
+        av_freep(&p->released_buffers);
+
+        if (i) {
+            av_freep(&p->avctx->priv_data);
+            av_freep(&p->avctx->slice_offset);
+        }
+
+        av_freep(&p->avctx->internal);
+        av_freep(&p->avctx);
+    }
+
+    av_freep(&fctx->threads);
+    pthread_mutex_destroy(&fctx->buffer_mutex);
+    av_freep(&avctx->internal->thread_ctx);
+}
+
+int ff_frame_thread_init(AVCodecContext *avctx)
+{
+    int thread_count = avctx->thread_count;
+    const AVCodec *codec = avctx->codec;
+    AVCodecContext *src = avctx;
+    FrameThreadContext *fctx;
+    int i, err = 0;
+
+#if HAVE_W32THREADS
+    w32thread_init();
+#endif
+
+    if (!thread_count) {
+        int nb_cpus = av_cpu_count();
+        av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
+        // 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);
+        else
+            thread_count = avctx->thread_count = 1;
+    }
+
+    if (thread_count <= 1) {
+        avctx->active_thread_type = 0;
+        return 0;
+    }
+
+    avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext));
+
+    fctx->threads = av_mallocz(sizeof(PerThreadContext) * thread_count);
+    pthread_mutex_init(&fctx->buffer_mutex, NULL);
+    fctx->delaying = 1;
+
+    for (i = 0; i < thread_count; i++) {
+        AVCodecContext *copy = av_malloc(sizeof(AVCodecContext));
+        PerThreadContext *p  = &fctx->threads[i];
+
+        pthread_mutex_init(&p->mutex, NULL);
+        pthread_mutex_init(&p->progress_mutex, NULL);
+        pthread_cond_init(&p->input_cond, NULL);
+        pthread_cond_init(&p->progress_cond, NULL);
+        pthread_cond_init(&p->output_cond, NULL);
+
+        p->frame = av_frame_alloc();
+        if (!p->frame) {
+            err = AVERROR(ENOMEM);
+            goto error;
+        }
+
+        p->parent = fctx;
+        p->avctx  = copy;
+
+        if (!copy) {
+            err = AVERROR(ENOMEM);
+            goto error;
+        }
+
+        *copy = *src;
+
+        copy->internal = av_malloc(sizeof(AVCodecInternal));
+        if (!copy->internal) {
+            err = AVERROR(ENOMEM);
+            goto error;
+        }
+        *copy->internal = *src->internal;
+        copy->internal->thread_ctx = p;
+        copy->internal->pkt = &p->avpkt;
+
+        if (!i) {
+            src = copy;
+
+            if (codec->init)
+                err = codec->init(copy);
+
+            update_context_from_thread(avctx, copy, 1);
+        } else {
+            copy->priv_data = av_malloc(codec->priv_data_size);
+            if (!copy->priv_data) {
+                err = AVERROR(ENOMEM);
+                goto error;
+            }
+            memcpy(copy->priv_data, src->priv_data, codec->priv_data_size);
+            copy->internal->is_copy = 1;
+
+            if (codec->init_thread_copy)
+                err = codec->init_thread_copy(copy);
+        }
+
+        if (err) goto error;
+
+        if (!pthread_create(&p->thread, NULL, frame_worker_thread, p))
+            p->thread_init = 1;
+    }
+
+    return 0;
+
+error:
+    ff_frame_thread_free(avctx, i+1);
+
+    return err;
+}
+
+void ff_thread_flush(AVCodecContext *avctx)
+{
+    int i;
+    FrameThreadContext *fctx = avctx->internal->thread_ctx;
+
+    if (!fctx) return;
+
+    park_frame_worker_threads(fctx, avctx->thread_count);
+    if (fctx->prev_thread) {
+        if (fctx->prev_thread != &fctx->threads[0])
+            update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);
+        if (avctx->codec->flush)
+            avctx->codec->flush(fctx->threads[0].avctx);
+    }
+
+    fctx->next_decoding = fctx->next_finished = 0;
+    fctx->delaying = 1;
+    fctx->prev_thread = NULL;
+    for (i = 0; i < avctx->thread_count; i++) {
+        PerThreadContext *p = &fctx->threads[i];
+        // Make sure decode flush calls with size=0 won't return old frames
+        p->got_frame = 0;
+        av_frame_unref(p->frame);
+
+        release_delayed_buffers(p);
+    }
+}
+
+int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
+{
+    PerThreadContext *p = avctx->internal->thread_ctx;
+    int err;
+
+    f->owner = avctx;
+
+    if (!(avctx->active_thread_type & FF_THREAD_FRAME))
+        return ff_get_buffer(avctx, f->f, flags);
+
+    if (p->state != STATE_SETTING_UP &&
+        (avctx->codec->update_thread_context || !avctx->thread_safe_callbacks)) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
+        return -1;
+    }
+
+    if (avctx->internal->allocate_progress) {
+        int *progress;
+        f->progress = av_buffer_alloc(2 * sizeof(int));
+        if (!f->progress) {
+            return AVERROR(ENOMEM);
+        }
+        progress = (int*)f->progress->data;
+
+        progress[0] = progress[1] = -1;
+    }
+
+    pthread_mutex_lock(&p->parent->buffer_mutex);
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->thread_safe_callbacks || (
+#if FF_API_GET_BUFFER
+        !avctx->get_buffer &&
+#endif
+        avctx->get_buffer2 == avcodec_default_get_buffer2)) {
+FF_ENABLE_DEPRECATION_WARNINGS
+        err = ff_get_buffer(avctx, f->f, flags);
+    } else {
+        p->requested_frame = f->f;
+        p->requested_flags = flags;
+        p->state = STATE_GET_BUFFER;
+        pthread_mutex_lock(&p->progress_mutex);
+        pthread_cond_signal(&p->progress_cond);
+
+        while (p->state != STATE_SETTING_UP)
+            pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
+
+        err = p->result;
+
+        pthread_mutex_unlock(&p->progress_mutex);
+
+    }
+    if (!avctx->thread_safe_callbacks && !avctx->codec->update_thread_context)
+        ff_thread_finish_setup(avctx);
+
+    if (err)
+        av_buffer_unref(&f->progress);
+
+    pthread_mutex_unlock(&p->parent->buffer_mutex);
+
+    return err;
+}
+
+void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
+{
+    PerThreadContext *p = avctx->internal->thread_ctx;
+    FrameThreadContext *fctx;
+    AVFrame *dst, *tmp;
+FF_DISABLE_DEPRECATION_WARNINGS
+    int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
+                          avctx->thread_safe_callbacks                   ||
+                          (
+#if FF_API_GET_BUFFER
+                           !avctx->get_buffer &&
+#endif
+                           avctx->get_buffer2 == avcodec_default_get_buffer2);
+FF_ENABLE_DEPRECATION_WARNINGS
+
+    if (!f->f->buf[0])
+        return;
+
+    if (avctx->debug & FF_DEBUG_BUFFERS)
+        av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
+
+    av_buffer_unref(&f->progress);
+    f->owner    = NULL;
+
+    if (can_direct_free) {
+        av_frame_unref(f->f);
+        return;
+    }
+
+    fctx = p->parent;
+    pthread_mutex_lock(&fctx->buffer_mutex);
+
+    if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers))
+        goto fail;
+    tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
+                          (p->num_released_buffers + 1) *
+                          sizeof(*p->released_buffers));
+    if (!tmp)
+        goto fail;
+    p->released_buffers = tmp;
+
+    dst = &p->released_buffers[p->num_released_buffers];
+    av_frame_move_ref(dst, f->f);
+
+    p->num_released_buffers++;
+
+fail:
+    pthread_mutex_unlock(&fctx->buffer_mutex);
+}
diff --git a/libavcodec/pthread_internal.h b/libavcodec/pthread_internal.h
new file mode 100644
index 0000000..5dfd0b2
--- /dev/null
+++ b/libavcodec/pthread_internal.h
@@ -0,0 +1,34 @@
+/*
+ * 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_PTHREAD_INTERNAL_H
+#define AVCODEC_PTHREAD_INTERNAL_H
+
+#include "avcodec.h"
+
+/* H264 slice threading seems to be buggy with more than 16 threads,
+ * limit the number of threads to 16 for automatic detection */
+#define MAX_AUTO_THREADS 16
+
+int ff_slice_thread_init(AVCodecContext *avctx);
+void ff_slice_thread_free(AVCodecContext *avctx);
+
+int ff_frame_thread_init(AVCodecContext *avctx);
+void ff_frame_thread_free(AVCodecContext *avctx, int thread_count);
+
+#endif // AVCODEC_PTHREAD_INTERNAL_H
diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c
new file mode 100644
index 0000000..d7c73f0
--- /dev/null
+++ b/libavcodec/pthread_slice.c
@@ -0,0 +1,224 @@
+/*
+ * 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
+ * Slice multithreading support functions
+ * @see doc/multithreading.txt
+ */
+
+#include "config.h"
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "compat/w32pthreads.h"
+#endif
+
+#include "avcodec.h"
+#include "internal.h"
+#include "pthread_internal.h"
+#include "thread.h"
+
+#include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
+
+typedef int (action_func)(AVCodecContext *c, void *arg);
+typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
+
+typedef struct SliceThreadContext {
+    pthread_t *workers;
+    action_func *func;
+    action_func2 *func2;
+    void *args;
+    int *rets;
+    int rets_count;
+    int job_count;
+    int job_size;
+
+    pthread_cond_t last_job_cond;
+    pthread_cond_t current_job_cond;
+    pthread_mutex_t current_job_lock;
+    unsigned current_execute;
+    int current_job;
+    int done;
+} SliceThreadContext;
+
+static void* attribute_align_arg worker(void *v)
+{
+    AVCodecContext *avctx = v;
+    SliceThreadContext *c = avctx->internal->thread_ctx;
+    unsigned last_execute = 0;
+    int our_job = c->job_count;
+    int thread_count = avctx->thread_count;
+    int self_id;
+
+    pthread_mutex_lock(&c->current_job_lock);
+    self_id = c->current_job++;
+    for (;;){
+        while (our_job >= c->job_count) {
+            if (c->current_job == thread_count + c->job_count)
+                pthread_cond_signal(&c->last_job_cond);
+
+            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) {
+                pthread_mutex_unlock(&c->current_job_lock);
+                return NULL;
+            }
+        }
+        pthread_mutex_unlock(&c->current_job_lock);
+
+        c->rets[our_job%c->rets_count] = c->func ? c->func(avctx, (char*)c->args + our_job*c->job_size):
+                                                   c->func2(avctx, c->args, our_job, self_id);
+
+        pthread_mutex_lock(&c->current_job_lock);
+        our_job = c->current_job++;
+    }
+}
+
+void ff_slice_thread_free(AVCodecContext *avctx)
+{
+    SliceThreadContext *c = avctx->internal->thread_ctx;
+    int i;
+
+    pthread_mutex_lock(&c->current_job_lock);
+    c->done = 1;
+    pthread_cond_broadcast(&c->current_job_cond);
+    pthread_mutex_unlock(&c->current_job_lock);
+
+    for (i=0; i<avctx->thread_count; i++)
+         pthread_join(c->workers[i], NULL);
+
+    pthread_mutex_destroy(&c->current_job_lock);
+    pthread_cond_destroy(&c->current_job_cond);
+    pthread_cond_destroy(&c->last_job_cond);
+    av_free(c->workers);
+    av_freep(&avctx->internal->thread_ctx);
+}
+
+static av_always_inline void thread_park_workers(SliceThreadContext *c, int thread_count)
+{
+    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);
+}
+
+static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)
+{
+    SliceThreadContext *c = avctx->internal->thread_ctx;
+    int dummy_ret;
+
+    if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1)
+        return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size);
+
+    if (job_count <= 0)
+        return 0;
+
+    pthread_mutex_lock(&c->current_job_lock);
+
+    c->current_job = avctx->thread_count;
+    c->job_count = job_count;
+    c->job_size = job_size;
+    c->args = arg;
+    c->func = func;
+    if (ret) {
+        c->rets = ret;
+        c->rets_count = job_count;
+    } else {
+        c->rets = &dummy_ret;
+        c->rets_count = 1;
+    }
+    c->current_execute++;
+    pthread_cond_broadcast(&c->current_job_cond);
+
+    thread_park_workers(c, avctx->thread_count);
+
+    return 0;
+}
+
+static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count)
+{
+    SliceThreadContext *c = avctx->internal->thread_ctx;
+    c->func2 = func2;
+    return thread_execute(avctx, NULL, arg, ret, job_count, 0);
+}
+
+int ff_slice_thread_init(AVCodecContext *avctx)
+{
+    int i;
+    SliceThreadContext *c;
+    int thread_count = avctx->thread_count;
+
+#if HAVE_W32THREADS
+    w32thread_init();
+#endif
+
+    if (!thread_count) {
+        int nb_cpus = av_cpu_count();
+        av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
+        // 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);
+        else
+            thread_count = avctx->thread_count = 1;
+    }
+
+    if (thread_count <= 1) {
+        avctx->active_thread_type = 0;
+        return 0;
+    }
+
+    c = av_mallocz(sizeof(SliceThreadContext));
+    if (!c)
+        return -1;
+
+    c->workers = av_mallocz(sizeof(pthread_t)*thread_count);
+    if (!c->workers) {
+        av_free(c);
+        return -1;
+    }
+
+    avctx->internal->thread_ctx = c;
+    c->current_job = 0;
+    c->job_count = 0;
+    c->job_size = 0;
+    c->done = 0;
+    pthread_cond_init(&c->current_job_cond, NULL);
+    pthread_cond_init(&c->last_job_cond, NULL);
+    pthread_mutex_init(&c->current_job_lock, NULL);
+    pthread_mutex_lock(&c->current_job_lock);
+    for (i=0; i<thread_count; i++) {
+        if(pthread_create(&c->workers[i], NULL, worker, avctx)) {
+           avctx->thread_count = i;
+           pthread_mutex_unlock(&c->current_job_lock);
+           ff_thread_free(avctx);
+           return -1;
+        }
+    }
+
+    thread_park_workers(c, thread_count);
+
+    avctx->execute = thread_execute;
+    avctx->execute2 = thread_execute2;
+    return 0;
+}
diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c
index d4cd963..76fff26 100644
--- a/libavcodec/ptx.c
+++ b/libavcodec/ptx.c
@@ -25,27 +25,13 @@
 #include "avcodec.h"
 #include "internal.h"
 
-typedef struct PTXContext {
-    AVFrame picture;
-} PTXContext;
-
-static av_cold int ptx_init(AVCodecContext *avctx) {
-    PTXContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame= &s->picture;
-
-    return 0;
-}
-
 static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt) {
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = avpkt->data + avpkt->size;
-    PTXContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+    AVFrame * const p = data;
     unsigned int offset, w, h, y, stride, bytes_per_pixel;
+    int ret;
     uint8_t *ptr;
 
     if (buf_end - buf < 14)
@@ -56,7 +42,7 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     bytes_per_pixel = AV_RL16(buf+12) >> 3;
 
     if (bytes_per_pixel != 2) {
-        av_log_ask_for_sample(avctx, "Image format is not RGB15.\n");
+        avpriv_request_sample(avctx, "Image format not RGB15");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -65,20 +51,16 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (buf_end - buf < offset)
         return AVERROR_INVALIDDATA;
     if (offset != 0x2c)
-        av_log_ask_for_sample(avctx, "offset != 0x2c\n");
+        avpriv_request_sample(avctx, "offset != 0x2c");
 
     buf += offset;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
+        return ret;
 
-    if (av_image_check_size(w, h, 0, avctx))
-        return -1;
-    if (w != avctx->width || h != avctx->height)
-        avcodec_set_dimensions(avctx, w, h);
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     p->pict_type = AV_PICTURE_TYPE_I;
@@ -98,7 +80,6 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         buf += w*bytes_per_pixel;
     }
 
-    *picture = s->picture;
     *got_frame = 1;
 
     if (y < h) {
@@ -109,23 +90,11 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     return offset + w*h*bytes_per_pixel;
 }
 
-static av_cold int ptx_end(AVCodecContext *avctx) {
-    PTXContext *s = avctx->priv_data;
-
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_ptx_decoder = {
     .name           = "ptx",
+    .long_name      = NULL_IF_CONFIG_SMALL("V.Flash PTX image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PTX,
-    .priv_data_size = sizeof(PTXContext),
-    .init           = ptx_init,
-    .close          = ptx_end,
     .decode         = ptx_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("V.Flash PTX image"),
 };
diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h
index d13a744..e3412cb 100644
--- a/libavcodec/put_bits.h
+++ b/libavcodec/put_bits.h
@@ -29,6 +29,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <assert.h>
+
 #include "libavutil/bswap.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
@@ -49,19 +50,20 @@ typedef struct PutBitContext {
  * @param buffer the buffer where to put bits
  * @param buffer_size the size in bytes of buffer
  */
-static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
+static inline void init_put_bits(PutBitContext *s, uint8_t *buffer,
+                                 int buffer_size)
 {
-    if(buffer_size < 0) {
+    if (buffer_size < 0) {
         buffer_size = 0;
-        buffer = NULL;
+        buffer      = NULL;
     }
 
-    s->size_in_bits= 8*buffer_size;
-    s->buf = buffer;
-    s->buf_end = s->buf + buffer_size;
-    s->buf_ptr = s->buf;
-    s->bit_left=32;
-    s->bit_buf=0;
+    s->size_in_bits = 8 * buffer_size;
+    s->buf          = buffer;
+    s->buf_end      = s->buf + buffer_size;
+    s->buf_ptr      = s->buf;
+    s->bit_left     = 32;
+    s->bit_buf      = 0;
 }
 
 /**
@@ -87,21 +89,21 @@ static inline void flush_put_bits(PutBitContext *s)
 {
 #ifndef BITSTREAM_WRITER_LE
     if (s->bit_left < 32)
-        s->bit_buf<<= s->bit_left;
+        s->bit_buf <<= s->bit_left;
 #endif
     while (s->bit_left < 32) {
         /* XXX: should test end of buffer */
 #ifdef BITSTREAM_WRITER_LE
-        *s->buf_ptr++=s->bit_buf;
-        s->bit_buf>>=8;
+        *s->buf_ptr++ = s->bit_buf;
+        s->bit_buf  >>= 8;
 #else
-        *s->buf_ptr++=s->bit_buf >> 24;
-        s->bit_buf<<=8;
+        *s->buf_ptr++ = s->bit_buf >> 24;
+        s->bit_buf  <<= 8;
 #endif
-        s->bit_left+=8;
+        s->bit_left  += 8;
     }
-    s->bit_left=32;
-    s->bit_buf=0;
+    s->bit_left = 32;
+    s->bit_buf  = 0;
 }
 
 #ifdef BITSTREAM_WRITER_LE
@@ -119,7 +121,8 @@ void avpriv_align_put_bits(PutBitContext *s);
  *
  * @param terminate_string 0-terminates the written string if value is 1
  */
-void avpriv_put_string(PutBitContext *pb, const char *string, int terminate_string);
+void avpriv_put_string(PutBitContext *pb, const char *string,
+                       int terminate_string);
 
 /**
  * Copy the content of src to the bitstream.
@@ -140,7 +143,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
 
     assert(n <= 31 && value < (1U << n));
 
-    bit_buf = s->bit_buf;
+    bit_buf  = s->bit_buf;
     bit_left = s->bit_left;
 
     /* XXX: optimize */
@@ -148,26 +151,26 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value)
     bit_buf |= value << (32 - bit_left);
     if (n >= bit_left) {
         AV_WL32(s->buf_ptr, bit_buf);
-        s->buf_ptr+=4;
-        bit_buf = (bit_left==32)?0:value >> bit_left;
-        bit_left+=32;
+        s->buf_ptr += 4;
+        bit_buf     = (bit_left == 32) ? 0 : value >> bit_left;
+        bit_left   += 32;
     }
-    bit_left-=n;
+    bit_left -= n;
 #else
     if (n < bit_left) {
-        bit_buf = (bit_buf<<n) | value;
-        bit_left-=n;
+        bit_buf     = (bit_buf << n) | value;
+        bit_left   -= n;
     } else {
-        bit_buf<<=bit_left;
-        bit_buf |= value >> (n - bit_left);
+        bit_buf   <<= bit_left;
+        bit_buf    |= value >> (n - bit_left);
         AV_WB32(s->buf_ptr, bit_buf);
-        s->buf_ptr+=4;
-        bit_left+=32 - n;
-        bit_buf = value;
+        s->buf_ptr += 4;
+        bit_left   += 32 - n;
+        bit_buf     = value;
     }
 #endif
 
-    s->bit_buf = bit_buf;
+    s->bit_buf  = bit_buf;
     s->bit_left = bit_left;
 }
 
@@ -175,7 +178,7 @@ static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
 {
     assert(n >= 0 && n <= 31);
 
-    put_bits(pb, n, value & ((1<<n)-1));
+    put_bits(pb, n, value & ((1 << n) - 1));
 }
 
 /**
@@ -198,9 +201,9 @@ static void av_unused put_bits32(PutBitContext *s, uint32_t value)
  * Return the pointer to the byte where the bitstream writer will put
  * the next bit.
  */
-static inline uint8_t* put_bits_ptr(PutBitContext *s)
+static inline uint8_t *put_bits_ptr(PutBitContext *s)
 {
-        return s->buf_ptr;
+    return s->buf_ptr;
 }
 
 /**
@@ -209,9 +212,9 @@ static inline uint8_t* put_bits_ptr(PutBitContext *s)
  */
 static inline void skip_put_bytes(PutBitContext *s, int n)
 {
-        assert((put_bits_count(s)&7)==0);
-        assert(s->bit_left==32);
-        s->buf_ptr += n;
+    assert((put_bits_count(s) & 7) == 0);
+    assert(s->bit_left == 32);
+    s->buf_ptr += n;
 }
 
 /**
@@ -222,7 +225,7 @@ static inline void skip_put_bytes(PutBitContext *s, int n)
 static inline void skip_put_bits(PutBitContext *s, int n)
 {
     s->bit_left -= n;
-    s->buf_ptr-= 4*(s->bit_left>>5);
+    s->buf_ptr  -= 4 * (s->bit_left >> 5);
     s->bit_left &= 31;
 }
 
@@ -233,7 +236,7 @@ static inline void skip_put_bits(PutBitContext *s, int n)
  */
 static inline void set_put_bits_buffer_size(PutBitContext *s, int size)
 {
-    s->buf_end= s->buf + size;
+    s->buf_end = s->buf + size;
 }
 
 #endif /* AVCODEC_PUT_BITS_H */
diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c
index b702175..7d9427c 100644
--- a/libavcodec/qcelpdec.c
+++ b/libavcodec/qcelpdec.c
@@ -30,10 +30,10 @@
 #include <stddef.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "qcelpdata.h"
 #include "celp_filters.h"
 #include "acelp_filters.h"
@@ -53,7 +53,6 @@ typedef enum {
 } qcelp_packet_rate;
 
 typedef struct {
-    AVFrame           avframe;
     GetBitContext     gb;
     qcelp_packet_rate bitrate;
     QCELPFrame        frame;    /**< unpacked data frame */
@@ -95,10 +94,7 @@ static av_cold int qcelp_decode_init(AVCodecContext *avctx)
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;
 
     for (i = 0; i < 10; i++)
-        q->prev_lspf[i] = (i + 1) / 11.;
-
-    avcodec_get_frame_defaults(&q->avframe);
-    avctx->coded_frame = &q->avframe;
+        q->prev_lspf[i] = (i + 1) / 11.0;
 
     return 0;
 }
@@ -166,7 +162,7 @@ static int decode_lspf(QCELPContext *q, float *lspf)
     } else {
         q->octave_count = 0;
 
-        tmp_lspf = 0.;
+        tmp_lspf = 0.0;
         for (i = 0; i < 5; i++) {
             lspf[2 * i + 0] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][0] * 0.0001;
             lspf[2 * i + 1] = tmp_lspf += qcelp_lspvq[i][q->frame.lspv[i]][1] * 0.0001;
@@ -400,12 +396,10 @@ static void apply_gain_ctrl(float *v_out, const float *v_ref, const float *v_in)
 {
     int i;
 
-    for (i = 0; i < 160; i += 40)
-        ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i,
-                                                ff_scalarproduct_float_c(v_ref + i,
-                                                                         v_ref + i,
-                                                                         40),
-                                                40);
+    for (i = 0; i < 160; i += 40) {
+        float res = avpriv_scalarproduct_float_c(v_ref + i, v_ref + i, 40);
+        ff_scale_vector_to_given_sum_of_squares(v_out + i, v_in + i, res, 40);
+    }
 }
 
 /**
@@ -440,7 +434,7 @@ static const float *do_pitchfilter(float memory[303], const float v_in[160],
             v_lag = memory + 143 + 40 * i - lag[i];
             for (v_len = v_in + 40; v_in < v_len; v_in++) {
                 if (pfrac[i]) { // If it is a fractional lag...
-                    for (j = 0, *v_out = 0.; j < 4; j++)
+                    for (j = 0, *v_out = 0.0; j < 4; j++)
                         *v_out += qcelp_hammsinc_table[j] * (v_lag[j - 4] + v_lag[3 - j]);
                 } else
                     *v_out = *v_lag;
@@ -641,8 +635,8 @@ static qcelp_packet_rate determine_bitrate(AVCodecContext *avctx,
         return I_F_Q;
 
     if (bitrate == SILENCE) {
-        //FIXME: Remove experimental warning when tested with samples.
-        av_log_ask_for_sample(avctx, "'Blank frame handling is experimental.");
+        // FIXME: Remove this warning when tested with samples.
+        avpriv_request_sample(avctx, "Blank frame handling");
     }
     return bitrate;
 }
@@ -680,8 +674,9 @@ static void postfilter(QCELPContext *q, float *samples, float *lpc)
     ff_tilt_compensation(&q->postfilter_tilt_mem, 0.3, pole_out + 10, 160);
 
     ff_adaptive_gain_control(samples, pole_out + 10,
-                             ff_scalarproduct_float_c(q->formant_mem + 10,
-                                                      q->formant_mem + 10, 160),
+                             avpriv_scalarproduct_float_c(q->formant_mem + 10,
+                                                          q->formant_mem + 10,
+                                                          160),
                              160, 0.9375, &q->postfilter_agc_mem);
 }
 
@@ -691,6 +686,7 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     QCELPContext *q    = avctx->priv_data;
+    AVFrame *frame     = data;
     float *outbuffer;
     int   i, ret;
     float quantized_lspf[10], lpc[10];
@@ -698,12 +694,12 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data,
     float *formant_mem;
 
     /* get output buffer */
-    q->avframe.nb_samples = 160;
-    if ((ret = ff_get_buffer(avctx, &q->avframe)) < 0) {
+    frame->nb_samples = 160;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    outbuffer = (float *)q->avframe.data[0];
+    outbuffer = (float *)frame->data[0];
 
     if ((q->bitrate = determine_bitrate(avctx, buf_size, &buf)) == I_F_Q) {
         warn_insufficient_frame_quality(avctx, "bitrate cannot be determined.");
@@ -786,19 +782,18 @@ erasure:
     memcpy(q->prev_lspf, quantized_lspf, sizeof(q->prev_lspf));
     q->prev_bitrate  = q->bitrate;
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = q->avframe;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
 
 AVCodec ff_qcelp_decoder = {
     .name           = "qcelp",
+    .long_name      = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_QCELP,
     .init           = qcelp_decode_init,
     .decode         = qcelp_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .priv_data_size = sizeof(QCELPContext),
-    .long_name      = NULL_IF_CONFIG_SMALL("QCELP / PureVoice"),
 };
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 99775d2..04e7def 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -39,7 +39,6 @@
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "rdft.h"
 #include "mpegaudiodsp.h"
@@ -130,8 +129,6 @@ typedef struct {
  * QDM2 decoder context
  */
 typedef struct {
-    AVFrame frame;
-
     /// Parameters from codec header, do not change during playback
     int nb_channels;         ///< number of channels
     int channels;            ///< number of channels
@@ -822,7 +819,7 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb,
     if (length == 0) {
         // If no data use noise
         for (sb=sb_min; sb < sb_max; sb++)
-            build_sb_samples_from_noise (q, sb);
+            build_sb_samples_from_noise(q, sb);
 
         return;
     }
@@ -835,12 +832,12 @@ static void synthfilt_build_sb_samples(QDM2Context *q, GetBitContext *gb,
         else if (sb >= 24)
             joined_stereo = 1;
         else
-            joined_stereo = (get_bits_left(gb) >= 1) ? get_bits1 (gb) : 0;
+            joined_stereo = (get_bits_left(gb) >= 1) ? get_bits1(gb) : 0;
 
         if (joined_stereo) {
             if (get_bits_left(gb) >= 16)
                 for (j = 0; j < 16; j++)
-                    sign_bits[j] = get_bits1 (gb);
+                    sign_bits[j] = get_bits1(gb);
 
             for (j = 0; j < 64; j++)
                 if (q->coding_method[1][sb][j] > q->coding_method[0][sb][j])
@@ -1042,7 +1039,7 @@ static void init_quantized_coeffs_elem0(int8_t *quantized_coeffs,
  * @param q         context
  * @param gb        bitreader context
  */
-static void init_tone_level_dequantization (QDM2Context *q, GetBitContext *gb)
+static void init_tone_level_dequantization(QDM2Context *q, GetBitContext *gb)
 {
     int sb, j, k, n, ch;
 
@@ -1898,9 +1895,6 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -1975,6 +1969,7 @@ static int qdm2_decode(QDM2Context *q, const uint8_t *in, int16_t *out)
 static int qdm2_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     QDM2Context *s = avctx->priv_data;
@@ -1987,12 +1982,12 @@ static int qdm2_decode_frame(AVCodecContext *avctx, void *data,
         return -1;
 
     /* get output buffer */
-    s->frame.nb_samples = 16 * s->frame_size;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 16 * s->frame_size;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out = (int16_t *)s->frame.data[0];
+    out = (int16_t *)frame->data[0];
 
     for (i = 0; i < 16; i++) {
         if (qdm2_decode(s, buf, out) < 0)
@@ -2000,14 +1995,14 @@ static int qdm2_decode_frame(AVCodecContext *avctx, void *data,
         out += s->channels * s->frame_size;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return s->checksum_size;
 }
 
 AVCodec ff_qdm2_decoder = {
     .name             = "qdm2",
+    .long_name        = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"),
     .type             = AVMEDIA_TYPE_AUDIO,
     .id               = AV_CODEC_ID_QDM2,
     .priv_data_size   = sizeof(QDM2Context),
@@ -2016,5 +2011,4 @@ AVCodec ff_qdm2_decoder = {
     .close            = qdm2_decode_close,
     .decode           = qdm2_decode_frame,
     .capabilities     = CODEC_CAP_DR1,
-    .long_name        = NULL_IF_CONFIG_SMALL("QDesign Music Codec 2"),
 };
diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c
index ca982f3..c365bfd 100644
--- a/libavcodec/qdrw.c
+++ b/libavcodec/qdrw.c
@@ -29,48 +29,38 @@
 #include "avcodec.h"
 #include "internal.h"
 
-typedef struct QdrawContext{
-    AVCodecContext *avctx;
-    AVFrame pic;
-} QdrawContext;
-
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
+    const uint8_t *buf     = avpkt->data;
     const uint8_t *buf_end = avpkt->data + avpkt->size;
-    int buf_size = avpkt->size;
-    QdrawContext * const a = avctx->priv_data;
-    AVFrame * const p = &a->pic;
+    int buf_size           = avpkt->size;
+    AVFrame * const p      = data;
     uint8_t* outdata;
     int colors;
-    int i;
+    int i, ret;
     uint32_t *pal;
     int r, g, b;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference= 0;
-    if(ff_get_buffer(avctx, p) < 0){
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    p->pict_type= AV_PICTURE_TYPE_I;
-    p->key_frame= 1;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
 
-    outdata = a->pic.data[0];
+    outdata = p->data[0];
 
     if (buf_end - buf < 0x68 + 4)
         return AVERROR_INVALIDDATA;
-    buf += 0x68; /* jump to palette */
+    buf   += 0x68; /* jump to palette */
     colors = AV_RB32(buf);
-    buf += 4;
+    buf   += 4;
 
-    if(colors < 0 || colors > 256) {
+    if (colors < 0 || colors > 256) {
         av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (buf_end - buf < (colors + 1) * 8)
         return AVERROR_INVALIDDATA;
@@ -106,7 +96,7 @@ static int decode_frame(AVCodecContext *avctx,
         int tsize = 0;
 
         /* decode line */
-        out = outdata;
+        out  = outdata;
         size = AV_RB16(buf); /* size of packed line */
         buf += 2;
         if (buf_end - buf < size)
@@ -118,60 +108,46 @@ static int decode_frame(AVCodecContext *avctx,
             code = *buf++;
             if (code & 0x80 ) { /* run */
                 pix = *buf++;
-                if ((out + (257 - code)) > (outdata +  a->pic.linesize[0]))
+                if ((out + (257 - code)) > (outdata +  p->linesize[0]))
                     break;
                 memset(out, pix, 257 - code);
-                out += 257 - code;
+                out   += 257 - code;
                 tsize += 257 - code;
-                left -= 2;
+                left  -= 2;
             } else { /* copy */
-                if ((out + code) > (outdata +  a->pic.linesize[0]))
+                if ((out + code) > (outdata +  p->linesize[0]))
                     break;
                 if (buf_end - buf < code + 1)
                     return AVERROR_INVALIDDATA;
                 memcpy(out, buf, code + 1);
-                out += code + 1;
-                buf += code + 1;
-                left -= 2 + code;
+                out   += code + 1;
+                buf   += code + 1;
+                left  -= 2 + code;
                 tsize += code + 1;
             }
         }
         buf = next;
-        outdata += a->pic.linesize[0];
+        outdata += p->linesize[0];
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = a->pic;
 
     return buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
-//    QdrawContext * const a = avctx->priv_data;
-
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     avctx->pix_fmt= AV_PIX_FMT_PAL8;
 
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
-    QdrawContext * const a = avctx->priv_data;
-    AVFrame *pic = &a->pic;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    return 0;
-}
-
 AVCodec ff_qdraw_decoder = {
     .name           = "qdraw",
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple QuickDraw"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_QDRAW,
-    .priv_data_size = sizeof(QdrawContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Apple QuickDraw"),
 };
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index 75e1223..4de1655 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -26,10 +26,11 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct QpegContext{
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *pic;
     uint8_t *refdata;
     uint32_t pal[256];
     GetByteContext buffer;
@@ -249,9 +250,9 @@ static int decode_frame(AVCodecContext *avctx,
 {
     uint8_t ctable[128];
     QpegContext * const a = avctx->priv_data;
-    AVFrame * const p = &a->pic;
+    AVFrame * const p = a->pic;
     uint8_t* outdata;
-    int delta;
+    int delta, ret;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
     if (avpkt->size < 0x86) {
@@ -260,59 +261,66 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     bytestream2_init(&a->buffer, avpkt->data, avpkt->size);
-    p->reference = 3;
-    if (avctx->reget_buffer(avctx, p) < 0) {
+    if ((ret = ff_reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    outdata = a->pic.data[0];
+    outdata = p->data[0];
     bytestream2_skip(&a->buffer, 4);
     bytestream2_get_buffer(&a->buffer, ctable, 128);
     bytestream2_skip(&a->buffer, 1);
 
     delta = bytestream2_get_byte(&a->buffer);
     if(delta == 0x10) {
-        qpeg_decode_intra(a, outdata, a->pic.linesize[0], avctx->width, avctx->height);
+        qpeg_decode_intra(a, outdata, p->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, p->linesize[0], avctx->width, avctx->height, delta, ctable, a->refdata);
     }
 
     /* make the palette available on the way out */
     if (pal) {
-        a->pic.palette_has_changed = 1;
+        p->palette_has_changed = 1;
         memcpy(a->pal, pal, AVPALETTE_SIZE);
     }
-    memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE);
+    memcpy(p->data[1], a->pal, AVPALETTE_SIZE);
+
+    if ((ret = av_frame_ref(data, p)) < 0)
+        return ret;
 
     *got_frame      = 1;
-    *(AVFrame*)data = a->pic;
 
     return avpkt->size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     QpegContext * const a = avctx->priv_data;
 
-    a->avctx = avctx;
-    avctx->pix_fmt= AV_PIX_FMT_PAL8;
-    a->refdata = av_malloc(avctx->width * avctx->height);
+    av_frame_free(&a->pic);
 
+    av_free(a->refdata);
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx){
     QpegContext * const a = avctx->priv_data;
-    AVFrame * const p = &a->pic;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
+    a->avctx = avctx;
+    avctx->pix_fmt= AV_PIX_FMT_PAL8;
+    a->refdata = av_malloc(avctx->width * avctx->height);
+
+    a->pic = av_frame_alloc();
+    if (!a->pic) {
+        decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
-    av_free(a->refdata);
     return 0;
 }
 
 AVCodec ff_qpeg_decoder = {
     .name           = "qpeg",
+    .long_name      = NULL_IF_CONFIG_SMALL("Q-team QPEG"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_QPEG,
     .priv_data_size = sizeof(QpegContext),
@@ -320,5 +328,4 @@ AVCodec ff_qpeg_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Q-team QPEG"),
 };
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index 23b2a61..28f1720 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -37,30 +37,31 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct QtrleContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     GetByteContext g;
     uint32_t pal[256];
 } QtrleContext;
 
-#define CHECK_PIXEL_PTR(n) \
-  if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \
-    av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \
-      pixel_ptr + n, pixel_limit); \
-    return; \
-  } \
+#define CHECK_PIXEL_PTR(n)                                                            \
+    if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) {                       \
+        av_log (s->avctx, AV_LOG_ERROR, "Problem: pixel_ptr = %d, pixel_limit = %d\n",\
+                pixel_ptr + n, pixel_limit);                                          \
+        return;                                                                       \
+    }                                                                                 \
 
 static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change)
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
+    int row_inc = s->frame->linesize[0];
     unsigned char pi0, pi1;  /* 2 8-pixel values */
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    unsigned char *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
     int skip;
 
     row_ptr  -= row_inc;
@@ -109,10 +110,10 @@ static inline void qtrle_decode_2n4bpp(QtrleContext *s, int row_ptr,
 {
     int rle_code, i;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
+    int row_inc = s->frame->linesize[0];
     unsigned char pi[16];  /* 16 palette indices */
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    unsigned char *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
     int num_pixels = (bpp == 4) ? 8 : 16;
 
     while (lines_to_change--) {
@@ -165,10 +166,10 @@ static void qtrle_decode_8bpp(QtrleContext *s, int row_ptr, int lines_to_change)
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
+    int row_inc = s->frame->linesize[0];
     unsigned char pi1, pi2, pi3, pi4;  /* 4 palette indexes */
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    unsigned char *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (4 * (bytestream2_get_byte(&s->g) - 1));
@@ -215,10 +216,10 @@ static void qtrle_decode_16bpp(QtrleContext *s, int row_ptr, int lines_to_change
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
+    int row_inc = s->frame->linesize[0];
     unsigned short rgb16;
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    unsigned char *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 2;
@@ -259,10 +260,10 @@ static void qtrle_decode_24bpp(QtrleContext *s, int row_ptr, int lines_to_change
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
+    int row_inc = s->frame->linesize[0];
     unsigned char r, g, b;
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    unsigned char *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 3;
@@ -306,10 +307,10 @@ static void qtrle_decode_32bpp(QtrleContext *s, int row_ptr, int lines_to_change
 {
     int rle_code;
     int pixel_ptr;
-    int row_inc = s->frame.linesize[0];
+    int row_inc = s->frame->linesize[0];
     unsigned int argb;
-    unsigned char *rgb = s->frame.data[0];
-    int pixel_limit = s->frame.linesize[0] * s->avctx->height;
+    unsigned char *rgb = s->frame->data[0];
+    int pixel_limit = s->frame->linesize[0] * s->avctx->height;
 
     while (lines_to_change--) {
         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 4;
@@ -384,7 +385,9 @@ static av_cold int qtrle_decode_init(AVCodecContext *avctx)
         return AVERROR_INVALIDDATA;
     }
 
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -397,14 +400,12 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
     int header, start_line;
     int height, row_ptr;
     int has_palette = 0;
+    int ret;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* check if this frame is even supposed to change */
@@ -429,7 +430,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
         start_line = 0;
         height     = s->avctx->height;
     }
-    row_ptr = s->frame.linesize[0] * start_line;
+    row_ptr = s->frame->linesize[0] * start_line;
 
     switch (avctx->bits_per_coded_sample) {
     case 1:
@@ -477,17 +478,18 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
         if (pal) {
-            s->frame.palette_has_changed = 1;
+            s->frame->palette_has_changed = 1;
             memcpy(s->pal, pal, AVPALETTE_SIZE);
         }
 
         /* make the palette available on the way out */
-        memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+        memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
     }
 
 done:
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* always report that the buffer was completely consumed */
     return avpkt->size;
@@ -497,14 +499,14 @@ static av_cold int qtrle_decode_end(AVCodecContext *avctx)
 {
     QtrleContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_qtrle_decoder = {
     .name           = "qtrle",
+    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_QTRLE,
     .priv_data_size = sizeof(QtrleContext),
@@ -512,5 +514,4 @@ AVCodec ff_qtrle_decoder = {
     .close          = qtrle_decode_end,
     .decode         = qtrle_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
 };
diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c
index bb686f5..7c98bea 100644
--- a/libavcodec/qtrleenc.c
+++ b/libavcodec/qtrleenc.c
@@ -36,7 +36,6 @@
 
 typedef struct QtrleEncContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     int pixel_size;
     AVPicture previous_frame;
     unsigned int max_buf_size;
@@ -60,6 +59,19 @@ typedef struct QtrleEncContext {
     uint8_t* skip_table;
 } QtrleEncContext;
 
+static av_cold int qtrle_encode_end(AVCodecContext *avctx)
+{
+    QtrleEncContext *s = avctx->priv_data;
+
+    av_frame_free(&avctx->coded_frame);
+
+    avpicture_free(&s->previous_frame);
+    av_free(s->rlecode_table);
+    av_free(s->length_table);
+    av_free(s->skip_table);
+    return 0;
+}
+
 static av_cold int qtrle_encode_init(AVCodecContext *avctx)
 {
     QtrleEncContext *s = avctx->priv_data;
@@ -101,7 +113,13 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx)
                       + 15                                           /* header + footer */
                       + s->avctx->height*2                           /* skip code+rle end */
                       + s->avctx->width/MAX_RLE_BULK + 1             /* rle codes */;
-    avctx->coded_frame = &s->frame;
+
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame) {
+        qtrle_encode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
@@ -141,7 +159,7 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui
 
     for (i = width - 1; i >= 0; i--) {
 
-        if (!s->frame.key_frame && !memcmp(this_line, prev_line, s->pixel_size))
+        if (!s->avctx->coded_frame->key_frame && !memcmp(this_line, prev_line, s->pixel_size))
             skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP);
         else
             skipcount = 0;
@@ -245,7 +263,7 @@ static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf)
     int end_line = s->avctx->height;
     uint8_t *orig_buf = buf;
 
-    if (!s->frame.key_frame) {
+    if (!s->avctx->coded_frame->key_frame) {
         unsigned line_size = s->avctx->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],
@@ -283,11 +301,9 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                               const AVFrame *pict, int *got_packet)
 {
     QtrleEncContext * const s = avctx->priv_data;
-    AVFrame * const p = &s->frame;
+    AVFrame * const p = avctx->coded_frame;
     int ret;
 
-    *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);
@@ -307,7 +323,8 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     pkt->size = encode_frame(s, pict, pkt->data);
 
     /* save the current frame */
-    av_picture_copy(&s->previous_frame, (AVPicture *)p, avctx->pix_fmt, avctx->width, avctx->height);
+    av_picture_copy(&s->previous_frame, (const AVPicture *)pict,
+                    avctx->pix_fmt, avctx->width, avctx->height);
 
     if (p->key_frame)
         pkt->flags |= AV_PKT_FLAG_KEY;
@@ -316,19 +333,9 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
-static av_cold int qtrle_encode_end(AVCodecContext *avctx)
-{
-    QtrleEncContext *s = avctx->priv_data;
-
-    avpicture_free(&s->previous_frame);
-    av_free(s->rlecode_table);
-    av_free(s->length_table);
-    av_free(s->skip_table);
-    return 0;
-}
-
 AVCodec ff_qtrle_encoder = {
     .name           = "qtrle",
+    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_QTRLE,
     .priv_data_size = sizeof(QtrleEncContext),
@@ -338,5 +345,4 @@ AVCodec ff_qtrle_encoder = {
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB555BE, AV_PIX_FMT_ARGB, 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 fd6d521..6adaac0 100644
--- a/libavcodec/r210dec.c
+++ b/libavcodec/r210dec.c
@@ -30,31 +30,25 @@ static av_cold int decode_init(AVCodecContext *avctx)
     avctx->pix_fmt             = AV_PIX_FMT_RGB48;
     avctx->bits_per_raw_sample = 10;
 
-    avctx->coded_frame         = avcodec_alloc_frame();
-
     return 0;
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    int h, w;
-    AVFrame *pic = avctx->coded_frame;
+    int h, w, ret;
+    AVFrame *pic = data;
     const uint32_t *src = (const uint32_t *)avpkt->data;
     int aligned_width = FFALIGN(avctx->width, 64);
     uint8_t *dst_line;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < 4 * aligned_width * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    pic->reference = 0;
-    if (ff_get_buffer(avctx, pic) < 0)
-        return -1;
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+        return ret;
 
     pic->pict_type = AV_PICTURE_TYPE_I;
     pic->key_frame = 1;
@@ -83,42 +77,29 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = *avctx->coded_frame;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 #if CONFIG_R210_DECODER
 AVCodec ff_r210_decoder = {
     .name           = "r210",
+    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_R210,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"),
 };
 #endif
 #if CONFIG_R10K_DECODER
 AVCodec ff_r10k_decoder = {
     .name           = "r10k",
+    .long_name      = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_R10K,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
 };
 #endif
diff --git a/libavcodec/ra144.c b/libavcodec/ra144.c
index 3705610..355badd 100644
--- a/libavcodec/ra144.c
+++ b/libavcodec/ra144.c
@@ -1504,8 +1504,8 @@ const int16_t * const ff_lpc_refl_cb[10]={
     lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10
 };
 
-static void ff_add_wav(int16_t *dest, int n, int skip_first, int *m, const int16_t *s1,
-                       const int8_t *s2, const int8_t *s3)
+static void add_wav(int16_t *dest, int n, int skip_first, int *m,
+                    const int16_t *s1, const int8_t *s2, const int8_t *s3)
 {
     int i;
     int v[3];
@@ -1709,8 +1709,8 @@ void ff_subblock_synthesis(RA144Context *ractx, const uint16_t *lpc_coefs,
 
     block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE;
 
-    ff_add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
-               ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
+    add_wav(block, gain, cba_idx, m, cba_idx? buffer_a: NULL,
+            ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
 
     memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,
            LPC_ORDER*sizeof(*ractx->curr_sblock));
diff --git a/libavcodec/ra144.h b/libavcodec/ra144.h
index 73f83f0..81d6964 100644
--- a/libavcodec/ra144.h
+++ b/libavcodec/ra144.h
@@ -35,7 +35,6 @@
 
 typedef struct RA144Context {
     AVCodecContext *avctx;
-    AVFrame frame;
     LPCContext lpc_ctx;
     AudioFrameQueue afq;
     int last_frame;
diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c
index 1a987fc..3be3877 100644
--- a/libavcodec/ra144dec.c
+++ b/libavcodec/ra144dec.c
@@ -23,7 +23,6 @@
  */
 
 #include "libavutil/channel_layout.h"
-#include "libavutil/intmath.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "internal.h"
@@ -43,9 +42,6 @@ static av_cold int ra144_decode_init(AVCodecContext * avctx)
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&ractx->frame);
-    avctx->coded_frame = &ractx->frame;
-
     return 0;
 }
 
@@ -65,6 +61,7 @@ static void do_output_subblock(RA144Context *ractx, const uint16_t  *lpc_coefs,
 static int ra144_decode_frame(AVCodecContext * avctx, void *data,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
@@ -79,20 +76,21 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data,
     RA144Context *ractx = avctx->priv_data;
     GetBitContext gb;
 
+    if (buf_size < FRAMESIZE) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Frame too small (%d bytes). Truncated file?\n", buf_size);
+        *got_frame_ptr = 0;
+        return AVERROR_INVALIDDATA;
+    }
+
     /* get output buffer */
-    ractx->frame.nb_samples = NBLOCKS * BLOCKSIZE;
-    if ((ret = ff_get_buffer(avctx, &ractx->frame)) < 0) {
+    frame->nb_samples = NBLOCKS * BLOCKSIZE;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)ractx->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
-    if(buf_size < FRAMESIZE) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Frame too small (%d bytes). Truncated file?\n", buf_size);
-        *got_frame_ptr = 0;
-        return buf_size;
-    }
     init_get_bits(&gb, buf, FRAMESIZE * 8);
 
     for (i = 0; i < LPC_ORDER; i++)
@@ -124,19 +122,18 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data,
 
     FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ractx->frame;
+    *got_frame_ptr = 1;
 
     return FRAMESIZE;
 }
 
 AVCodec ff_ra_144_decoder = {
     .name           = "real_144",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_RA_144,
     .priv_data_size = sizeof(RA144Context),
     .init           = ra144_decode_init,
     .decode         = ra144_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
 };
diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c
index b9473ac..9f953d4 100644
--- a/libavcodec/ra144enc.c
+++ b/libavcodec/ra144enc.c
@@ -40,9 +40,6 @@ static av_cold int ra144_encode_close(AVCodecContext *avctx)
     RA144Context *ractx = avctx->priv_data;
     ff_lpc_end(&ractx->lpc_ctx);
     ff_af_queue_close(&ractx->afq);
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     return 0;
 }
 
@@ -71,14 +68,6 @@ static av_cold int ra144_encode_init(AVCodecContext * avctx)
 
     ff_af_queue_init(avctx, &ractx->afq);
 
-#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:
     ra144_encode_close(avctx);
@@ -556,6 +545,7 @@ static int ra144_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_ra_144_encoder = {
     .name           = "real_144",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_RA_144,
     .priv_data_size = sizeof(RA144Context),
@@ -565,5 +555,4 @@ AVCodec ff_ra_144_encoder = {
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
 };
diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c
index 8266673..215786c 100644
--- a/libavcodec/ra288.c
+++ b/libavcodec/ra288.c
@@ -21,6 +21,7 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/float_dsp.h"
+#include "libavutil/internal.h"
 #include "avcodec.h"
 #include "internal.h"
 #define BITSTREAM_READER_LE
@@ -37,8 +38,6 @@
 #define RA288_BLOCKS_PER_FRAME 32
 
 typedef struct {
-    AVFrame frame;
-    DSPContext dsp;
     AVFloatDSPContext fdsp;
     DECLARE_ALIGNED(32, float,   sp_lpc)[FFALIGN(36, 16)];   ///< LPC coefficients for speech data (spec: A)
     DECLARE_ALIGNED(32, float, gain_lpc)[FFALIGN(10, 16)];   ///< LPC coefficients for gain        (spec: GB)
@@ -70,16 +69,13 @@ static av_cold int ra288_decode_init(AVCodecContext *avctx)
 
     avpriv_float_dsp_init(&ractx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
-    avcodec_get_frame_defaults(&ractx->frame);
-    avctx->coded_frame = &ractx->frame;
-
     return 0;
 }
 
 static void convolve(float *tgt, const float *src, int len, int n)
 {
     for (; n >= 0; n--)
-        tgt[n] = ff_scalarproduct_float_c(src, src - n, len);
+        tgt[n] = avpriv_scalarproduct_float_c(src, src - n, len);
 
 }
 
@@ -94,7 +90,7 @@ static void decode(RA288Context *ractx, float gain, int cb_coef)
     memmove(ractx->sp_hist + 70, ractx->sp_hist + 75, 36*sizeof(*block));
 
     /* block 46 of G.728 spec */
-    sum = 32.;
+    sum = 32.0;
     for (i=0; i < 10; i++)
         sum -= gain_block[9-i] * ractx->gain_lpc[i];
 
@@ -108,7 +104,7 @@ static void decode(RA288Context *ractx, float gain, int cb_coef)
     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 = avpriv_scalarproduct_float_c(buffer, buffer, 5) * ((1 << 24) / 5.0);
 
     sum = FFMAX(sum, 1);
 
@@ -154,7 +150,7 @@ static void do_hybrid_window(RA288Context *ractx,
     }
 
     /* Multiply by the white noise correcting factor (WNCF). */
-    *out *= 257./256.;
+    *out *= 257.0 / 256.0;
 }
 
 /**
@@ -178,6 +174,7 @@ static void backward_filter(RA288Context *ractx,
 static int ra288_decode_frame(AVCodecContext * avctx, void *data,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     float *out;
@@ -193,12 +190,12 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data,
     }
 
     /* get output buffer */
-    ractx->frame.nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME;
-    if ((ret = ff_get_buffer(avctx, &ractx->frame)) < 0) {
+    frame->nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    out = (float *)ractx->frame.data[0];
+    out = (float *)frame->data[0];
 
     init_get_bits(&gb, buf, avctx->block_align * 8);
 
@@ -220,19 +217,18 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data,
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ractx->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
 }
 
 AVCodec ff_ra_288_decoder = {
     .name           = "real_288",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_RA_288,
     .priv_data_size = sizeof(RA288Context),
     .init           = ra288_decode_init,
     .decode         = ra288_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 2.0 (28.8K)"),
 };
diff --git a/libavcodec/ra288.h b/libavcodec/ra288.h
index 8083580..9f4beeb 100644
--- a/libavcodec/ra288.h
+++ b/libavcodec/ra288.h
@@ -23,7 +23,6 @@
 #define AVCODEC_RA288_H
 
 #include <stdint.h>
-#include "dsputil.h"
 #include "libavutil/common.h"
 
 static const float amptable[8]={
diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c
index 580def3..ebcdf6f 100644
--- a/libavcodec/ralf.c
+++ b/libavcodec/ralf.c
@@ -26,6 +26,7 @@
  * Dedicated to the mastermind behind it, Ralph Wiggum.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
@@ -49,8 +50,6 @@ typedef struct VLCSet {
 #define RALF_MAX_PKT_SIZE 8192
 
 typedef struct RALFContext {
-    AVFrame frame;
-
     int version;
     int max_frame_size;
     VLCSet sets[3];
@@ -74,7 +73,7 @@ typedef struct RALFContext {
 
 #define MAX_ELEMS 644 // no RALF table uses more than that
 
-static int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems)
+static av_cold int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems)
 {
     uint8_t  lens[MAX_ELEMS];
     uint16_t codes[MAX_ELEMS];
@@ -138,7 +137,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     ctx->version = AV_RB16(avctx->extradata + 4);
     if (ctx->version != 0x103) {
-        av_log_ask_for_sample(avctx, "unknown version %X\n", ctx->version);
+        avpriv_request_sample(avctx, "Unknown version %X", ctx->version);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -154,9 +153,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO
                                                    : AV_CH_LAYOUT_MONO;
 
-    avcodec_get_frame_defaults(&ctx->frame);
-    avctx->coded_frame = &ctx->frame;
-
     ctx->max_frame_size = AV_RB32(avctx->extradata + 16);
     if (ctx->max_frame_size > (1 << 20) || !ctx->max_frame_size) {
         av_log(avctx, AV_LOG_ERROR, "invalid frame size %d\n",
@@ -426,6 +422,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
                         AVPacket *avpkt)
 {
     RALFContext *ctx = avctx->priv_data;
+    AVFrame *frame   = data;
     int16_t *samples0;
     int16_t *samples1;
     int ret;
@@ -463,13 +460,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
         src_size = avpkt->size;
     }
 
-    ctx->frame.nb_samples = ctx->max_frame_size;
-    if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    frame->nb_samples = ctx->max_frame_size;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Me fail get_buffer()? That's unpossible!\n");
         return ret;
     }
-    samples0 = (int16_t *)ctx->frame.data[0];
-    samples1 = (int16_t *)ctx->frame.data[1];
+    samples0 = (int16_t *)frame->data[0];
+    samples1 = (int16_t *)frame->data[1];
 
     if (src_size < 5) {
         av_log(avctx, AV_LOG_ERROR, "too short packets are too short!\n");
@@ -511,9 +508,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
         bytes_left    -= ctx->block_size[i];
     }
 
-    ctx->frame.nb_samples = ctx->sample_offset;
-    *got_frame_ptr  = ctx->sample_offset > 0;
-    *(AVFrame*)data = ctx->frame;
+    frame->nb_samples = ctx->sample_offset;
+    *got_frame_ptr    = ctx->sample_offset > 0;
 
     return avpkt->size;
 }
@@ -528,6 +524,7 @@ static void decode_flush(AVCodecContext *avctx)
 
 AVCodec ff_ralf_decoder = {
     .name           = "ralf",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio Lossless"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_RALF,
     .priv_data_size = sizeof(RALFContext),
@@ -536,7 +533,6 @@ AVCodec ff_ralf_decoder = {
     .decode         = decode_frame,
     .flush          = decode_flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio Lossless"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/rangecoder.c b/libavcodec/rangecoder.c
index fcadfe4..af0a8c0 100644
--- a/libavcodec/rangecoder.c
+++ b/libavcodec/rangecoder.c
@@ -33,11 +33,12 @@
 
 #include <string.h>
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "rangecoder.h"
 #include "bytestream.h"
 
-void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size)
+av_cold void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size)
 {
     c->bytestream_start  =
     c->bytestream        = buf;
@@ -48,7 +49,8 @@ void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size)
     c->outstanding_byte  = -1;
 }
 
-void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size)
+av_cold void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf,
+                                   int buf_size)
 {
     /* cast to avoid compiler warning */
     ff_init_range_encoder(c, (uint8_t *)buf, buf_size);
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index e0b6e9b..5aaf151 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -25,9 +25,8 @@
  * Rate control for video encoders.
  */
 
-#include "libavutil/intmath.h"
+#include "libavutil/attributes.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "ratecontrol.h"
 #include "mpegvideo.h"
 #include "libavutil/eval.h"
@@ -40,34 +39,51 @@
 #endif
 
 static int init_pass2(MpegEncContext *s);
-static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num);
+static double get_qscale(MpegEncContext *s, RateControlEntry *rce,
+                         double rate_factor, int frame_num);
 
-void ff_write_pass1_stats(MpegEncContext *s){
-    snprintf(s->avctx->stats_out, 256, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;\n",
-             s->current_picture_ptr->f.display_picture_number, s->current_picture_ptr->f.coded_picture_number, s->pict_type,
-             s->current_picture.f.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits,
-             s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count, s->skip_count, s->header_bits);
+void ff_write_pass1_stats(MpegEncContext *s)
+{
+    snprintf(s->avctx->stats_out, 256,
+             "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d "
+             "fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;\n",
+             s->current_picture_ptr->f.display_picture_number,
+             s->current_picture_ptr->f.coded_picture_number,
+             s->pict_type,
+             s->current_picture.f.quality,
+             s->i_tex_bits,
+             s->p_tex_bits,
+             s->mv_bits,
+             s->misc_bits,
+             s->f_code,
+             s->b_code,
+             s->current_picture.mc_mb_var_sum,
+             s->current_picture.mb_var_sum,
+             s->i_count, s->skip_count,
+             s->header_bits);
 }
 
-static inline double qp2bits(RateControlEntry *rce, double qp){
-    if(qp<=0.0){
+static inline double qp2bits(RateControlEntry *rce, double qp)
+{
+    if (qp <= 0.0) {
         av_log(NULL, AV_LOG_ERROR, "qp<=0.0\n");
     }
-    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ qp;
+    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / qp;
 }
 
-static inline double bits2qp(RateControlEntry *rce, double bits){
-    if(bits<0.9){
+static inline double bits2qp(RateControlEntry *rce, double bits)
+{
+    if (bits < 0.9) {
         av_log(NULL, AV_LOG_ERROR, "bits<0.9\n");
     }
-    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ bits;
+    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / bits;
 }
 
-int ff_rate_control_init(MpegEncContext *s)
+av_cold int ff_rate_control_init(MpegEncContext *s)
 {
-    RateControlContext *rcc= &s->rc_context;
+    RateControlContext *rcc = &s->rc_context;
     int i, res;
-    static const char * const const_names[]={
+    static const char * const const_names[] = {
         "PI",
         "E",
         "iTex",
@@ -83,10 +99,12 @@ int ff_rate_control_init(MpegEncContext *s)
         "isB",
         "avgQP",
         "qComp",
-/*        "lastIQP",
+#if 0
+        "lastIQP",
         "lastPQP",
         "lastBQP",
-        "nextNonBQP",*/
+        "nextNonBQP",
+#endif
         "avgIITex",
         "avgPITex",
         "avgPPTex",
@@ -94,204 +112,222 @@ int ff_rate_control_init(MpegEncContext *s)
         "avgTex",
         NULL
     };
-    static double (* const func1[])(void *, double)={
+    static double (* const func1[])(void *, double) = {
         (void *)bits2qp,
         (void *)qp2bits,
         NULL
     };
-    static const char * const func1_names[]={
+    static const char * const func1_names[] = {
         "bits2qp",
         "qp2bits",
         NULL
     };
     emms_c();
 
-    res = av_expr_parse(&rcc->rc_eq_eval, s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp", const_names, func1_names, func1, NULL, NULL, 0, s->avctx);
+    res = av_expr_parse(&rcc->rc_eq_eval,
+                        s->avctx->rc_eq ? s->avctx->rc_eq : "tex^qComp",
+                        const_names, func1_names, func1,
+                        NULL, NULL, 0, s->avctx);
     if (res < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq);
         return res;
     }
 
-    for(i=0; i<5; i++){
-        rcc->pred[i].coeff= FF_QP2LAMBDA * 7.0;
-        rcc->pred[i].count= 1.0;
-
-        rcc->pred[i].decay= 0.4;
-        rcc->i_cplx_sum [i]=
-        rcc->p_cplx_sum [i]=
-        rcc->mv_bits_sum[i]=
-        rcc->qscale_sum [i]=
-        rcc->frame_count[i]= 1; // 1 is better because of 1/0 and such
-        rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5;
+    for (i = 0; i < 5; i++) {
+        rcc->pred[i].coeff = FF_QP2LAMBDA * 7.0;
+        rcc->pred[i].count = 1.0;
+        rcc->pred[i].decay = 0.4;
+
+        rcc->i_cplx_sum [i] =
+        rcc->p_cplx_sum [i] =
+        rcc->mv_bits_sum[i] =
+        rcc->qscale_sum [i] =
+        rcc->frame_count[i] = 1; // 1 is better because of 1/0 and such
+
+        rcc->last_qscale_for[i] = FF_QP2LAMBDA * 5;
     }
-    rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy;
+    rcc->buffer_index = s->avctx->rc_initial_buffer_occupancy;
 
-    if(s->flags&CODEC_FLAG_PASS2){
+    if (s->flags & CODEC_FLAG_PASS2) {
         int i;
         char *p;
 
         /* find number of pics */
-        p= s->avctx->stats_in;
-        for(i=-1; p; i++){
-            p= strchr(p+1, ';');
-        }
-        i+= s->max_b_frames;
-        if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry))
+        p = s->avctx->stats_in;
+        for (i = -1; p; i++)
+            p = strchr(p + 1, ';');
+        i += s->max_b_frames;
+        if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry))
             return -1;
-        rcc->entry = av_mallocz(i*sizeof(RateControlEntry));
-        rcc->num_entries= i;
-
-        /* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */
-        for(i=0; i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
-            rce->pict_type= rce->new_pict_type=AV_PICTURE_TYPE_P;
-            rce->qscale= rce->new_qscale=FF_QP2LAMBDA * 2;
-            rce->misc_bits= s->mb_num + 10;
-            rce->mb_var_sum= s->mb_num*100;
+        rcc->entry       = av_mallocz(i * sizeof(RateControlEntry));
+        rcc->num_entries = i;
+
+        /* init all to skipped p frames
+         * (with b frames we might have a not encoded frame at the end FIXME) */
+        for (i = 0; i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
+
+            rce->pict_type  = rce->new_pict_type = AV_PICTURE_TYPE_P;
+            rce->qscale     = rce->new_qscale    = FF_QP2LAMBDA * 2;
+            rce->misc_bits  = s->mb_num + 10;
+            rce->mb_var_sum = s->mb_num * 100;
         }
 
         /* read stats */
-        p= s->avctx->stats_in;
-        for(i=0; i<rcc->num_entries - s->max_b_frames; i++){
+        p = s->avctx->stats_in;
+        for (i = 0; i < rcc->num_entries - s->max_b_frames; i++) {
             RateControlEntry *rce;
             int picture_number;
             int e;
             char *next;
 
-            next= strchr(p, ';');
-            if(next){
-                (*next)=0; //sscanf in unbelievably slow on looong strings //FIXME copy / do not write
+            next = strchr(p, ';');
+            if (next) {
+                (*next) = 0; // sscanf in unbelievably slow on looong strings // FIXME copy / do not write
                 next++;
             }
-            e= sscanf(p, " in:%d ", &picture_number);
+            e = sscanf(p, " in:%d ", &picture_number);
 
             assert(picture_number >= 0);
             assert(picture_number < rcc->num_entries);
-            rce= &rcc->entry[picture_number];
-
-            e+=sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d",
-                   &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits,
-                   &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits);
-            if(e!=14){
-                av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e);
+            rce = &rcc->entry[picture_number];
+
+            e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d",
+                        &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits,
+                        &rce->mv_bits, &rce->misc_bits,
+                        &rce->f_code, &rce->b_code,
+                        &rce->mc_mb_var_sum, &rce->mb_var_sum,
+                        &rce->i_count, &rce->skip_count, &rce->header_bits);
+            if (e != 14) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "statistics are damaged at line %d, parser out=%d\n",
+                       i, e);
                 return -1;
             }
 
-            p= next;
+            p = next;
         }
 
-        if(init_pass2(s) < 0) return -1;
+        if (init_pass2(s) < 0)
+            return -1;
 
-        //FIXME maybe move to end
-        if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) {
+        // FIXME maybe move to end
+        if ((s->flags & CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) {
 #if CONFIG_LIBXVID
             return ff_xvid_rate_control_init(s);
 #else
-            av_log(s->avctx, AV_LOG_ERROR, "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n");
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n");
             return -1;
 #endif
         }
     }
 
-    if(!(s->flags&CODEC_FLAG_PASS2)){
+    if (!(s->flags & CODEC_FLAG_PASS2)) {
+        rcc->short_term_qsum   = 0.001;
+        rcc->short_term_qcount = 0.001;
 
-        rcc->short_term_qsum=0.001;
-        rcc->short_term_qcount=0.001;
+        rcc->pass1_rc_eq_output_sum = 0.001;
+        rcc->pass1_wanted_bits      = 0.001;
 
-        rcc->pass1_rc_eq_output_sum= 0.001;
-        rcc->pass1_wanted_bits=0.001;
-
-        if(s->avctx->qblur > 1.0){
+        if (s->avctx->qblur > 1.0) {
             av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n");
             return -1;
         }
         /* init stuff with the user specified complexity */
-        if(s->avctx->rc_initial_cplx){
-            for(i=0; i<60*30; i++){
-                double bits= s->avctx->rc_initial_cplx * (i/10000.0 + 1.0)*s->mb_num;
+        if (s->avctx->rc_initial_cplx) {
+            for (i = 0; i < 60 * 30; i++) {
+                double bits = s->avctx->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;
                 RateControlEntry rce;
 
-                if     (i%((s->gop_size+3)/4)==0) rce.pict_type= AV_PICTURE_TYPE_I;
-                else if(i%(s->max_b_frames+1))    rce.pict_type= AV_PICTURE_TYPE_B;
-                else                              rce.pict_type= AV_PICTURE_TYPE_P;
-
-                rce.new_pict_type= rce.pict_type;
-                rce.mc_mb_var_sum= bits*s->mb_num/100000;
-                rce.mb_var_sum   = s->mb_num;
-                rce.qscale   = FF_QP2LAMBDA * 2;
-                rce.f_code   = 2;
-                rce.b_code   = 1;
-                rce.misc_bits= 1;
-
-                if(s->pict_type== AV_PICTURE_TYPE_I){
-                    rce.i_count   = s->mb_num;
-                    rce.i_tex_bits= bits;
-                    rce.p_tex_bits= 0;
-                    rce.mv_bits= 0;
-                }else{
-                    rce.i_count   = 0; //FIXME we do know this approx
-                    rce.i_tex_bits= 0;
-                    rce.p_tex_bits= bits*0.9;
-                    rce.mv_bits= bits*0.1;
+                if (i % ((s->gop_size + 3) / 4) == 0)
+                    rce.pict_type = AV_PICTURE_TYPE_I;
+                else if (i % (s->max_b_frames + 1))
+                    rce.pict_type = AV_PICTURE_TYPE_B;
+                else
+                    rce.pict_type = AV_PICTURE_TYPE_P;
+
+                rce.new_pict_type = rce.pict_type;
+                rce.mc_mb_var_sum = bits * s->mb_num / 100000;
+                rce.mb_var_sum    = s->mb_num;
+
+                rce.qscale    = FF_QP2LAMBDA * 2;
+                rce.f_code    = 2;
+                rce.b_code    = 1;
+                rce.misc_bits = 1;
+
+                if (s->pict_type == AV_PICTURE_TYPE_I) {
+                    rce.i_count    = s->mb_num;
+                    rce.i_tex_bits = bits;
+                    rce.p_tex_bits = 0;
+                    rce.mv_bits    = 0;
+                } else {
+                    rce.i_count    = 0; // FIXME we do know this approx
+                    rce.i_tex_bits = 0;
+                    rce.p_tex_bits = bits * 0.9;
+                    rce.mv_bits    = bits * 0.1;
                 }
-                rcc->i_cplx_sum [rce.pict_type] += rce.i_tex_bits*rce.qscale;
-                rcc->p_cplx_sum [rce.pict_type] += rce.p_tex_bits*rce.qscale;
+                rcc->i_cplx_sum[rce.pict_type]  += rce.i_tex_bits * rce.qscale;
+                rcc->p_cplx_sum[rce.pict_type]  += rce.p_tex_bits * rce.qscale;
                 rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits;
-                rcc->frame_count[rce.pict_type] ++;
+                rcc->frame_count[rce.pict_type]++;
+
+                get_qscale(s, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i);
 
-                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
+                // FIXME misbehaves a little for variable fps
+                rcc->pass1_wanted_bits += s->bit_rate / (1 / av_q2d(s->avctx->time_base));
             }
         }
-
     }
 
     return 0;
 }
 
-void ff_rate_control_uninit(MpegEncContext *s)
+av_cold void ff_rate_control_uninit(MpegEncContext *s)
 {
-    RateControlContext *rcc= &s->rc_context;
+    RateControlContext *rcc = &s->rc_context;
     emms_c();
 
     av_expr_free(rcc->rc_eq_eval);
     av_freep(&rcc->entry);
 
 #if CONFIG_LIBXVID
-    if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
+    if ((s->flags & CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
         ff_xvid_rate_control_uninit(s);
 #endif
 }
 
-int ff_vbv_update(MpegEncContext *s, int frame_size){
-    RateControlContext *rcc= &s->rc_context;
-    const double fps= 1/av_q2d(s->avctx->time_base);
-    const int buffer_size= s->avctx->rc_buffer_size;
-    const double min_rate= s->avctx->rc_min_rate/fps;
-    const double max_rate= s->avctx->rc_max_rate/fps;
+int ff_vbv_update(MpegEncContext *s, int frame_size)
+{
+    RateControlContext *rcc = &s->rc_context;
+    const double fps        = 1 / av_q2d(s->avctx->time_base);
+    const int buffer_size   = s->avctx->rc_buffer_size;
+    const double min_rate   = s->avctx->rc_min_rate / fps;
+    const double max_rate   = s->avctx->rc_max_rate / fps;
 
     av_dlog(s, "%d %f %d %f %f\n",
             buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate);
-    if(buffer_size){
+
+    if (buffer_size) {
         int left;
 
-        rcc->buffer_index-= frame_size;
-        if(rcc->buffer_index < 0){
+        rcc->buffer_index -= frame_size;
+        if (rcc->buffer_index < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n");
-            rcc->buffer_index= 0;
+            rcc->buffer_index = 0;
         }
 
-        left= buffer_size - rcc->buffer_index - 1;
+        left = buffer_size - rcc->buffer_index - 1;
         rcc->buffer_index += av_clip(left, min_rate, max_rate);
 
-        if(rcc->buffer_index > buffer_size){
-            int stuffing= ceil((rcc->buffer_index - buffer_size)/8);
+        if (rcc->buffer_index > buffer_size) {
+            int stuffing = ceil((rcc->buffer_index - buffer_size) / 8);
 
-            if(stuffing < 4 && s->codec_id == AV_CODEC_ID_MPEG4)
-                stuffing=4;
-            rcc->buffer_index -= 8*stuffing;
+            if (stuffing < 4 && s->codec_id == AV_CODEC_ID_MPEG4)
+                stuffing = 4;
+            rcc->buffer_index -= 8 * stuffing;
 
-            if(s->avctx->debug & FF_DEBUG_RC)
+            if (s->avctx->debug & FF_DEBUG_RC)
                 av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing);
 
             return stuffing;
@@ -303,34 +339,38 @@ int ff_vbv_update(MpegEncContext *s, int frame_size){
 /**
  * Modify the bitrate curve from pass1 for one frame.
  */
-static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num){
-    RateControlContext *rcc= &s->rc_context;
-    AVCodecContext *a= s->avctx;
+static double get_qscale(MpegEncContext *s, RateControlEntry *rce,
+                         double rate_factor, int frame_num)
+{
+    RateControlContext *rcc = &s->rc_context;
+    AVCodecContext *a       = s->avctx;
+    const int pict_type     = rce->new_pict_type;
+    const double mb_num     = s->mb_num;
     double q, bits;
-    const int pict_type= rce->new_pict_type;
-    const double mb_num= s->mb_num;
     int i;
 
-    double const_values[]={
+    double const_values[] = {
         M_PI,
         M_E,
-        rce->i_tex_bits*rce->qscale,
-        rce->p_tex_bits*rce->qscale,
-        (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale,
-        rce->mv_bits/mb_num,
-        rce->pict_type == AV_PICTURE_TYPE_B ? (rce->f_code + rce->b_code)*0.5 : rce->f_code,
-        rce->i_count/mb_num,
-        rce->mc_mb_var_sum/mb_num,
-        rce->mb_var_sum/mb_num,
+        rce->i_tex_bits * rce->qscale,
+        rce->p_tex_bits * rce->qscale,
+        (rce->i_tex_bits + rce->p_tex_bits) * (double)rce->qscale,
+        rce->mv_bits / mb_num,
+        rce->pict_type == AV_PICTURE_TYPE_B ? (rce->f_code + rce->b_code) * 0.5 : rce->f_code,
+        rce->i_count / mb_num,
+        rce->mc_mb_var_sum / mb_num,
+        rce->mb_var_sum / mb_num,
         rce->pict_type == AV_PICTURE_TYPE_I,
         rce->pict_type == AV_PICTURE_TYPE_P,
         rce->pict_type == AV_PICTURE_TYPE_B,
         rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type],
         a->qcompress,
-/*        rcc->last_qscale_for[AV_PICTURE_TYPE_I],
+#if 0
+        rcc->last_qscale_for[AV_PICTURE_TYPE_I],
         rcc->last_qscale_for[AV_PICTURE_TYPE_P],
         rcc->last_qscale_for[AV_PICTURE_TYPE_B],
-        rcc->next_non_b_qscale,*/
+        rcc->next_non_b_qscale,
+#endif
         rcc->i_cplx_sum[AV_PICTURE_TYPE_I] / (double)rcc->frame_count[AV_PICTURE_TYPE_I],
         rcc->i_cplx_sum[AV_PICTURE_TYPE_P] / (double)rcc->frame_count[AV_PICTURE_TYPE_P],
         rcc->p_cplx_sum[AV_PICTURE_TYPE_P] / (double)rcc->frame_count[AV_PICTURE_TYPE_P],
@@ -345,61 +385,71 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f
         return -1;
     }
 
-    rcc->pass1_rc_eq_output_sum+= bits;
-    bits*=rate_factor;
-    if(bits<0.0) bits=0.0;
-    bits+= 1.0; //avoid 1/0 issues
+    rcc->pass1_rc_eq_output_sum += bits;
+    bits *= rate_factor;
+    if (bits < 0.0)
+        bits = 0.0;
+    bits += 1.0; // avoid 1/0 issues
 
     /* user override */
-    for(i=0; i<s->avctx->rc_override_count; i++){
-        RcOverride *rco= s->avctx->rc_override;
-        if(rco[i].start_frame > frame_num) continue;
-        if(rco[i].end_frame   < frame_num) continue;
-
-        if(rco[i].qscale)
-            bits= qp2bits(rce, rco[i].qscale); //FIXME move at end to really force it?
+    for (i = 0; i < s->avctx->rc_override_count; i++) {
+        RcOverride *rco = s->avctx->rc_override;
+        if (rco[i].start_frame > frame_num)
+            continue;
+        if (rco[i].end_frame < frame_num)
+            continue;
+
+        if (rco[i].qscale)
+            bits = qp2bits(rce, rco[i].qscale);  // FIXME move at end to really force it?
         else
-            bits*= rco[i].quality_factor;
+            bits *= rco[i].quality_factor;
     }
 
-    q= bits2qp(rce, bits);
+    q = bits2qp(rce, bits);
 
     /* I/B difference */
-    if     (pict_type==AV_PICTURE_TYPE_I && s->avctx->i_quant_factor<0.0)
-        q= -q*s->avctx->i_quant_factor + s->avctx->i_quant_offset;
-    else if(pict_type==AV_PICTURE_TYPE_B && s->avctx->b_quant_factor<0.0)
-        q= -q*s->avctx->b_quant_factor + s->avctx->b_quant_offset;
-    if(q<1) q=1;
+    if (pict_type == AV_PICTURE_TYPE_I && s->avctx->i_quant_factor < 0.0)
+        q = -q * s->avctx->i_quant_factor + s->avctx->i_quant_offset;
+    else if (pict_type == AV_PICTURE_TYPE_B && s->avctx->b_quant_factor < 0.0)
+        q = -q * s->avctx->b_quant_factor + s->avctx->b_quant_offset;
+    if (q < 1)
+        q = 1;
 
     return q;
 }
 
-static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q){
-    RateControlContext *rcc= &s->rc_context;
-    AVCodecContext *a= s->avctx;
-    const int pict_type= rce->new_pict_type;
-    const double last_p_q    = rcc->last_qscale_for[AV_PICTURE_TYPE_P];
-    const double last_non_b_q= rcc->last_qscale_for[rcc->last_non_b_pict_type];
-
-    if     (pict_type==AV_PICTURE_TYPE_I && (a->i_quant_factor>0.0 || rcc->last_non_b_pict_type==AV_PICTURE_TYPE_P))
-        q= last_p_q    *FFABS(a->i_quant_factor) + a->i_quant_offset;
-    else if(pict_type==AV_PICTURE_TYPE_B && a->b_quant_factor>0.0)
-        q= last_non_b_q*    a->b_quant_factor  + a->b_quant_offset;
-    if(q<1) q=1;
+static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q)
+{
+    RateControlContext *rcc   = &s->rc_context;
+    AVCodecContext *a         = s->avctx;
+    const int pict_type       = rce->new_pict_type;
+    const double last_p_q     = rcc->last_qscale_for[AV_PICTURE_TYPE_P];
+    const double last_non_b_q = rcc->last_qscale_for[rcc->last_non_b_pict_type];
+
+    if (pict_type == AV_PICTURE_TYPE_I &&
+        (a->i_quant_factor > 0.0 || rcc->last_non_b_pict_type == AV_PICTURE_TYPE_P))
+        q = last_p_q * FFABS(a->i_quant_factor) + a->i_quant_offset;
+    else if (pict_type == AV_PICTURE_TYPE_B &&
+             a->b_quant_factor > 0.0)
+        q = last_non_b_q * a->b_quant_factor + a->b_quant_offset;
+    if (q < 1)
+        q = 1;
 
     /* last qscale / qdiff stuff */
-    if(rcc->last_non_b_pict_type==pict_type || pict_type!=AV_PICTURE_TYPE_I){
-        double last_q= rcc->last_qscale_for[pict_type];
-        const int maxdiff= FF_QP2LAMBDA * a->max_qdiff;
-
-        if     (q > last_q + maxdiff) q= last_q + maxdiff;
-        else if(q < last_q - maxdiff) q= last_q - maxdiff;
+    if (rcc->last_non_b_pict_type == pict_type || pict_type != AV_PICTURE_TYPE_I) {
+        double last_q     = rcc->last_qscale_for[pict_type];
+        const int maxdiff = FF_QP2LAMBDA * a->max_qdiff;
+
+        if (q > last_q + maxdiff)
+            q = last_q + maxdiff;
+        else if (q < last_q - maxdiff)
+            q = last_q - maxdiff;
     }
 
-    rcc->last_qscale_for[pict_type]= q; //Note we cannot do that after blurring
+    rcc->last_qscale_for[pict_type] = q; // Note we cannot do that after blurring
 
-    if(pict_type!=AV_PICTURE_TYPE_B)
-        rcc->last_non_b_pict_type= pict_type;
+    if (pict_type != AV_PICTURE_TYPE_B)
+        rcc->last_non_b_pict_type = pict_type;
 
     return q;
 }
@@ -407,239 +457,269 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl
 /**
  * Get the qmin & qmax for pict_type.
  */
-static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type){
-    int qmin= s->avctx->lmin;
-    int qmax= s->avctx->lmax;
+static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type)
+{
+    int qmin = s->avctx->lmin;
+    int qmax = s->avctx->lmax;
 
     assert(qmin <= qmax);
 
-    if(pict_type==AV_PICTURE_TYPE_B){
-        qmin= (int)(qmin*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5);
-        qmax= (int)(qmax*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5);
-    }else if(pict_type==AV_PICTURE_TYPE_I){
-        qmin= (int)(qmin*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5);
-        qmax= (int)(qmax*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5);
+    switch (pict_type) {
+    case AV_PICTURE_TYPE_B:
+        qmin = (int)(qmin * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset + 0.5);
+        qmax = (int)(qmax * FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset + 0.5);
+        break;
+    case AV_PICTURE_TYPE_I:
+        qmin = (int)(qmin * FFABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset + 0.5);
+        qmax = (int)(qmax * FFABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset + 0.5);
+        break;
     }
 
-    qmin= av_clip(qmin, 1, FF_LAMBDA_MAX);
-    qmax= av_clip(qmax, 1, FF_LAMBDA_MAX);
+    qmin = av_clip(qmin, 1, FF_LAMBDA_MAX);
+    qmax = av_clip(qmax, 1, FF_LAMBDA_MAX);
 
-    if(qmax<qmin) qmax= qmin;
+    if (qmax < qmin)
+        qmax = qmin;
 
-    *qmin_ret= qmin;
-    *qmax_ret= qmax;
+    *qmin_ret = qmin;
+    *qmax_ret = qmax;
 }
 
-static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q, int frame_num){
-    RateControlContext *rcc= &s->rc_context;
+static double modify_qscale(MpegEncContext *s, RateControlEntry *rce,
+                            double q, int frame_num)
+{
+    RateControlContext *rcc  = &s->rc_context;
+    const double buffer_size = s->avctx->rc_buffer_size;
+    const double fps         = 1 / av_q2d(s->avctx->time_base);
+    const double min_rate    = s->avctx->rc_min_rate / fps;
+    const double max_rate    = s->avctx->rc_max_rate / fps;
+    const int pict_type      = rce->new_pict_type;
     int qmin, qmax;
-    const int pict_type= rce->new_pict_type;
-    const double buffer_size= s->avctx->rc_buffer_size;
-    const double fps= 1/av_q2d(s->avctx->time_base);
-    const double min_rate= s->avctx->rc_min_rate / fps;
-    const double max_rate= s->avctx->rc_max_rate / fps;
 
     get_qminmax(&qmin, &qmax, s, pict_type);
 
     /* modulation */
-    if(s->avctx->rc_qmod_freq && frame_num%s->avctx->rc_qmod_freq==0 && pict_type==AV_PICTURE_TYPE_P)
-        q*= s->avctx->rc_qmod_amp;
+    if (s->avctx->rc_qmod_freq &&
+        frame_num % s->avctx->rc_qmod_freq == 0 &&
+        pict_type == AV_PICTURE_TYPE_P)
+        q *= s->avctx->rc_qmod_amp;
 
     /* buffer overflow/underflow protection */
-    if(buffer_size){
-        double expected_size= rcc->buffer_index;
+    if (buffer_size) {
+        double expected_size = rcc->buffer_index;
         double q_limit;
 
-        if(min_rate){
-            double d= 2*(buffer_size - expected_size)/buffer_size;
-            if(d>1.0) d=1.0;
-            else if(d<0.0001) d=0.0001;
-            q*= pow(d, 1.0/s->avctx->rc_buffer_aggressivity);
-
-            q_limit= bits2qp(rce, FFMAX((min_rate - buffer_size + rcc->buffer_index) * s->avctx->rc_min_vbv_overflow_use, 1));
-            if(q > q_limit){
-                if(s->avctx->debug&FF_DEBUG_RC){
-                    av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit);
-                }
-                q= q_limit;
+        if (min_rate) {
+            double d = 2 * (buffer_size - expected_size) / buffer_size;
+            if (d > 1.0)
+                d = 1.0;
+            else if (d < 0.0001)
+                d = 0.0001;
+            q *= pow(d, 1.0 / s->avctx->rc_buffer_aggressivity);
+
+            q_limit = bits2qp(rce,
+                              FFMAX((min_rate - buffer_size + rcc->buffer_index) *
+                                    s->avctx->rc_min_vbv_overflow_use, 1));
+
+            if (q > q_limit) {
+                if (s->avctx->debug & FF_DEBUG_RC)
+                    av_log(s->avctx, AV_LOG_DEBUG,
+                           "limiting QP %f -> %f\n", q, q_limit);
+                q = q_limit;
             }
         }
 
-        if(max_rate){
-            double d= 2*expected_size/buffer_size;
-            if(d>1.0) d=1.0;
-            else if(d<0.0001) d=0.0001;
-            q/= pow(d, 1.0/s->avctx->rc_buffer_aggressivity);
-
-            q_limit= bits2qp(rce, FFMAX(rcc->buffer_index * s->avctx->rc_max_available_vbv_use, 1));
-            if(q < q_limit){
-                if(s->avctx->debug&FF_DEBUG_RC){
-                    av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit);
-                }
-                q= q_limit;
+        if (max_rate) {
+            double d = 2 * expected_size / buffer_size;
+            if (d > 1.0)
+                d = 1.0;
+            else if (d < 0.0001)
+                d = 0.0001;
+            q /= pow(d, 1.0 / s->avctx->rc_buffer_aggressivity);
+
+            q_limit = bits2qp(rce,
+                              FFMAX(rcc->buffer_index *
+                                    s->avctx->rc_max_available_vbv_use,
+                                    1));
+            if (q < q_limit) {
+                if (s->avctx->debug & FF_DEBUG_RC)
+                    av_log(s->avctx, AV_LOG_DEBUG,
+                           "limiting QP %f -> %f\n", q, q_limit);
+                q = q_limit;
             }
         }
     }
     av_dlog(s, "q:%f max:%f min:%f size:%f index:%f agr:%f\n",
             q, max_rate, min_rate, buffer_size, rcc->buffer_index,
             s->avctx->rc_buffer_aggressivity);
-    if(s->avctx->rc_qsquish==0.0 || qmin==qmax){
-        if     (q<qmin) q=qmin;
-        else if(q>qmax) q=qmax;
-    }else{
-        double min2= log(qmin);
-        double max2= log(qmax);
-
-        q= log(q);
-        q= (q - min2)/(max2-min2) - 0.5;
-        q*= -4.0;
-        q= 1.0/(1.0 + exp(q));
-        q= q*(max2-min2) + min2;
-
-        q= exp(q);
+    if (s->avctx->rc_qsquish == 0.0 || qmin == qmax) {
+        if (q < qmin)
+            q = qmin;
+        else if (q > qmax)
+            q = qmax;
+    } else {
+        double min2 = log(qmin);
+        double max2 = log(qmax);
+
+        q  = log(q);
+        q  = (q - min2) / (max2 - min2) - 0.5;
+        q *= -4.0;
+        q  = 1.0 / (1.0 + exp(q));
+        q  = q * (max2 - min2) + min2;
+
+        q = exp(q);
     }
 
     return q;
 }
 
-//----------------------------------
+// ----------------------------------
 // 1 Pass Code
 
 static double predict_size(Predictor *p, double q, double var)
 {
-     return p->coeff*var / (q*p->count);
+    return p->coeff * var / (q * p->count);
 }
 
 static void update_predictor(Predictor *p, double q, double var, double size)
 {
-    double new_coeff= size*q / (var + 1);
-    if(var<10) return;
+    double new_coeff = size * q / (var + 1);
+    if (var < 10)
+        return;
 
-    p->count*= p->decay;
-    p->coeff*= p->decay;
+    p->count *= p->decay;
+    p->coeff *= p->decay;
     p->count++;
-    p->coeff+= new_coeff;
+    p->coeff += new_coeff;
 }
 
-static void adaptive_quantization(MpegEncContext *s, double q){
+static void adaptive_quantization(MpegEncContext *s, double q)
+{
     int i;
-    const float lumi_masking= s->avctx->lumi_masking / (128.0*128.0);
-    const float dark_masking= s->avctx->dark_masking / (128.0*128.0);
-    const float temp_cplx_masking= s->avctx->temporal_cplx_masking;
+    const float lumi_masking         = s->avctx->lumi_masking / (128.0 * 128.0);
+    const float dark_masking         = s->avctx->dark_masking / (128.0 * 128.0);
+    const float temp_cplx_masking    = s->avctx->temporal_cplx_masking;
     const float spatial_cplx_masking = s->avctx->spatial_cplx_masking;
-    const float p_masking = s->avctx->p_masking;
-    const float border_masking = s->avctx->border_masking;
-    float bits_sum= 0.0;
-    float cplx_sum= 0.0;
-    float *cplx_tab = s->cplx_tab;
-    float *bits_tab = s->bits_tab;
-    const int qmin= s->avctx->mb_lmin;
-    const int qmax= s->avctx->mb_lmax;
-    Picture * const pic= &s->current_picture;
-    const int mb_width = s->mb_width;
-    const int mb_height = s->mb_height;
-
-    for(i=0; i<s->mb_num; i++){
-        const int mb_xy= s->mb_index2xy[i];
-        float temp_cplx= sqrt(pic->mc_mb_var[mb_xy]); //FIXME merge in pow()
-        float spat_cplx= sqrt(pic->mb_var[mb_xy]);
-        const int lumi= pic->mb_mean[mb_xy];
+    const float p_masking            = s->avctx->p_masking;
+    const float border_masking       = s->avctx->border_masking;
+    float bits_sum                   = 0.0;
+    float cplx_sum                   = 0.0;
+    float *cplx_tab                  = s->cplx_tab;
+    float *bits_tab                  = s->bits_tab;
+    const int qmin                   = s->avctx->mb_lmin;
+    const int qmax                   = s->avctx->mb_lmax;
+    Picture *const pic               = &s->current_picture;
+    const int mb_width               = s->mb_width;
+    const int mb_height              = s->mb_height;
+
+    for (i = 0; i < s->mb_num; i++) {
+        const int mb_xy = s->mb_index2xy[i];
+        float temp_cplx = sqrt(pic->mc_mb_var[mb_xy]); // FIXME merge in pow()
+        float spat_cplx = sqrt(pic->mb_var[mb_xy]);
+        const int lumi  = pic->mb_mean[mb_xy];
         float bits, cplx, factor;
         int mb_x = mb_xy % s->mb_stride;
         int mb_y = mb_xy / s->mb_stride;
         int mb_distance;
         float mb_factor = 0.0;
-        if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune
-        if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune
-
-        if((s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTRA)){//FIXME hq mode
-            cplx= spat_cplx;
-            factor= 1.0 + p_masking;
-        }else{
-            cplx= temp_cplx;
-            factor= pow(temp_cplx, - temp_cplx_masking);
+        if (spat_cplx < 4)
+            spat_cplx = 4;              // FIXME finetune
+        if (temp_cplx < 4)
+            temp_cplx = 4;              // FIXME finetune
+
+        if ((s->mb_type[mb_xy] & CANDIDATE_MB_TYPE_INTRA)) { // FIXME hq mode
+            cplx   = spat_cplx;
+            factor = 1.0 + p_masking;
+        } else {
+            cplx   = temp_cplx;
+            factor = pow(temp_cplx, -temp_cplx_masking);
         }
-        factor*=pow(spat_cplx, - spatial_cplx_masking);
+        factor *= pow(spat_cplx, -spatial_cplx_masking);
 
-        if(lumi>127)
-            factor*= (1.0 - (lumi-128)*(lumi-128)*lumi_masking);
+        if (lumi > 127)
+            factor *= (1.0 - (lumi - 128) * (lumi - 128) * lumi_masking);
         else
-            factor*= (1.0 - (lumi-128)*(lumi-128)*dark_masking);
-
-        if(mb_x < mb_width/5){
-            mb_distance = mb_width/5 - mb_x;
-            mb_factor = (float)mb_distance / (float)(mb_width/5);
-        }else if(mb_x > 4*mb_width/5){
-            mb_distance = mb_x - 4*mb_width/5;
-            mb_factor = (float)mb_distance / (float)(mb_width/5);
+            factor *= (1.0 - (lumi - 128) * (lumi - 128) * dark_masking);
+
+        if (mb_x < mb_width / 5) {
+            mb_distance = mb_width / 5 - mb_x;
+            mb_factor   = (float)mb_distance / (float)(mb_width / 5);
+        } else if (mb_x > 4 * mb_width / 5) {
+            mb_distance = mb_x - 4 * mb_width / 5;
+            mb_factor   = (float)mb_distance / (float)(mb_width / 5);
         }
-        if(mb_y < mb_height/5){
-            mb_distance = mb_height/5 - mb_y;
-            mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5));
-        }else if(mb_y > 4*mb_height/5){
-            mb_distance = mb_y - 4*mb_height/5;
-            mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5));
+        if (mb_y < mb_height / 5) {
+            mb_distance = mb_height / 5 - mb_y;
+            mb_factor   = FFMAX(mb_factor,
+                                (float)mb_distance / (float)(mb_height / 5));
+        } else if (mb_y > 4 * mb_height / 5) {
+            mb_distance = mb_y - 4 * mb_height / 5;
+            mb_factor   = FFMAX(mb_factor,
+                                (float)mb_distance / (float)(mb_height / 5));
         }
 
-        factor*= 1.0 - border_masking*mb_factor;
+        factor *= 1.0 - border_masking * mb_factor;
 
-        if(factor<0.00001) factor= 0.00001;
+        if (factor < 0.00001)
+            factor = 0.00001;
 
-        bits= cplx*factor;
-        cplx_sum+= cplx;
-        bits_sum+= bits;
-        cplx_tab[i]= cplx;
-        bits_tab[i]= bits;
+        bits        = cplx * factor;
+        cplx_sum   += cplx;
+        bits_sum   += bits;
+        cplx_tab[i] = cplx;
+        bits_tab[i] = bits;
     }
 
     /* handle qmin/qmax clipping */
-    if(s->flags&CODEC_FLAG_NORMALIZE_AQP){
-        float factor= bits_sum/cplx_sum;
-        for(i=0; i<s->mb_num; i++){
-            float newq= q*cplx_tab[i]/bits_tab[i];
-            newq*= factor;
+    if (s->flags & CODEC_FLAG_NORMALIZE_AQP) {
+        float factor = bits_sum / cplx_sum;
+        for (i = 0; i < s->mb_num; i++) {
+            float newq = q * cplx_tab[i] / bits_tab[i];
+            newq *= factor;
 
-            if     (newq > qmax){
+            if (newq > qmax) {
                 bits_sum -= bits_tab[i];
-                cplx_sum -= cplx_tab[i]*q/qmax;
-            }
-            else if(newq < qmin){
+                cplx_sum -= cplx_tab[i] * q / qmax;
+            } else if (newq < qmin) {
                 bits_sum -= bits_tab[i];
-                cplx_sum -= cplx_tab[i]*q/qmin;
+                cplx_sum -= cplx_tab[i] * q / qmin;
             }
         }
-        if(bits_sum < 0.001) bits_sum= 0.001;
-        if(cplx_sum < 0.001) cplx_sum= 0.001;
+        if (bits_sum < 0.001)
+            bits_sum = 0.001;
+        if (cplx_sum < 0.001)
+            cplx_sum = 0.001;
     }
 
-    for(i=0; i<s->mb_num; i++){
-        const int mb_xy= s->mb_index2xy[i];
-        float newq= q*cplx_tab[i]/bits_tab[i];
+    for (i = 0; i < s->mb_num; i++) {
+        const int mb_xy = s->mb_index2xy[i];
+        float newq      = q * cplx_tab[i] / bits_tab[i];
         int intq;
 
-        if(s->flags&CODEC_FLAG_NORMALIZE_AQP){
-            newq*= bits_sum/cplx_sum;
+        if (s->flags & CODEC_FLAG_NORMALIZE_AQP) {
+            newq *= bits_sum / cplx_sum;
         }
 
-        intq= (int)(newq + 0.5);
+        intq = (int)(newq + 0.5);
 
-        if     (intq > qmax) intq= qmax;
-        else if(intq < qmin) intq= qmin;
-        s->lambda_table[mb_xy]= intq;
+        if (intq > qmax)
+            intq = qmax;
+        else if (intq < qmin)
+            intq = qmin;
+        s->lambda_table[mb_xy] = intq;
     }
 }
 
-void ff_get_2pass_fcode(MpegEncContext *s){
-    RateControlContext *rcc= &s->rc_context;
-    int picture_number= s->picture_number;
-    RateControlEntry *rce;
+void ff_get_2pass_fcode(MpegEncContext *s)
+{
+    RateControlContext *rcc = &s->rc_context;
+    RateControlEntry *rce   = &rcc->entry[s->picture_number];
 
-    rce= &rcc->entry[picture_number];
-    s->f_code= rce->f_code;
-    s->b_code= rce->b_code;
+    s->f_code = rce->f_code;
+    s->b_code = rce->b_code;
 }
 
-//FIXME rd or at least approx for dquant
+// FIXME rd or at least approx for dquant
 
 float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
 {
@@ -649,249 +729,272 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
     double diff;
     double short_term_q;
     double fps;
-    int picture_number= s->picture_number;
+    int picture_number = s->picture_number;
     int64_t wanted_bits;
-    RateControlContext *rcc= &s->rc_context;
-    AVCodecContext *a= s->avctx;
+    RateControlContext *rcc = &s->rc_context;
+    AVCodecContext *a       = s->avctx;
     RateControlEntry local_rce, *rce;
     double bits;
     double rate_factor;
     int var;
-    const int pict_type= s->pict_type;
-    Picture * const pic= &s->current_picture;
+    const int pict_type = s->pict_type;
+    Picture * const pic = &s->current_picture;
     emms_c();
 
 #if CONFIG_LIBXVID
-    if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
+    if ((s->flags & CODEC_FLAG_PASS2) &&
+        s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
         return ff_xvid_rate_estimate_qscale(s, dry_run);
 #endif
 
     get_qminmax(&qmin, &qmax, s, pict_type);
 
-    fps= 1/av_q2d(s->avctx->time_base);
-        /* 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);
+    fps = 1 / av_q2d(s->avctx->time_base);
+    /* 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);
     }
 
-    if(s->flags&CODEC_FLAG_PASS2){
-        assert(picture_number>=0);
-        assert(picture_number<rcc->num_entries);
-        rce= &rcc->entry[picture_number];
-        wanted_bits= rce->expected_bits;
-    }else{
+    if (s->flags & CODEC_FLAG_PASS2) {
+        assert(picture_number >= 0);
+        assert(picture_number < rcc->num_entries);
+        rce         = &rcc->entry[picture_number];
+        wanted_bits = rce->expected_bits;
+    } else {
         Picture *dts_pic;
-        rce= &local_rce;
+        rce = &local_rce;
 
-        //FIXME add a dts field to AVFrame and ensure its set and use it here instead of reordering
-        //but the reordering is simpler for now until h.264 b pyramid must be handeld
-        if(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
-            dts_pic= s->current_picture_ptr;
+        /* FIXME add a dts field to AVFrame and ensure it is set and use it
+         * here instead of reordering but the reordering is simpler for now
+         * until H.264 B-pyramid must be handled. */
+        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
+            dts_pic = s->current_picture_ptr;
         else
-            dts_pic= s->last_picture_ptr;
+            dts_pic = s->last_picture_ptr;
 
         if (!dts_pic || dts_pic->f.pts == AV_NOPTS_VALUE)
-            wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps);
+            wanted_bits = (uint64_t)(s->bit_rate * (double)picture_number / fps);
         else
-            wanted_bits = (uint64_t)(s->bit_rate*(double)dts_pic->f.pts / fps);
+            wanted_bits = (uint64_t)(s->bit_rate * (double)dts_pic->f.pts / fps);
     }
 
-    diff= s->total_bits - wanted_bits;
-    br_compensation= (a->bit_rate_tolerance - diff)/a->bit_rate_tolerance;
-    if(br_compensation<=0.0) br_compensation=0.001;
+    diff = s->total_bits - wanted_bits;
+    br_compensation = (a->bit_rate_tolerance - diff) / a->bit_rate_tolerance;
+    if (br_compensation <= 0.0)
+        br_compensation = 0.001;
 
-    var= pict_type == AV_PICTURE_TYPE_I ? pic->mb_var_sum : pic->mc_mb_var_sum;
+    var = pict_type == AV_PICTURE_TYPE_I ? pic->mb_var_sum : pic->mc_mb_var_sum;
 
     short_term_q = 0; /* avoid warning */
-    if(s->flags&CODEC_FLAG_PASS2){
-        if(pict_type!=AV_PICTURE_TYPE_I)
+    if (s->flags & CODEC_FLAG_PASS2) {
+        if (pict_type != AV_PICTURE_TYPE_I)
             assert(pict_type == rce->new_pict_type);
 
-        q= rce->new_qscale / br_compensation;
+        q = rce->new_qscale / br_compensation;
         av_dlog(s, "%f %f %f last:%d var:%d type:%d//\n", q, rce->new_qscale,
                 br_compensation, s->frame_bits, var, pict_type);
-    }else{
-        rce->pict_type=
-        rce->new_pict_type= pict_type;
-        rce->mc_mb_var_sum= pic->mc_mb_var_sum;
-        rce->mb_var_sum   = pic->   mb_var_sum;
-        rce->qscale   = FF_QP2LAMBDA * 2;
-        rce->f_code   = s->f_code;
-        rce->b_code   = s->b_code;
-        rce->misc_bits= 1;
-
-        bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
-        if(pict_type== AV_PICTURE_TYPE_I){
-            rce->i_count   = s->mb_num;
-            rce->i_tex_bits= bits;
-            rce->p_tex_bits= 0;
-            rce->mv_bits= 0;
-        }else{
-            rce->i_count   = 0; //FIXME we do know this approx
-            rce->i_tex_bits= 0;
-            rce->p_tex_bits= bits*0.9;
-
-            rce->mv_bits= bits*0.1;
+    } else {
+        rce->pict_type     =
+        rce->new_pict_type = pict_type;
+        rce->mc_mb_var_sum = pic->mc_mb_var_sum;
+        rce->mb_var_sum    = pic->mb_var_sum;
+        rce->qscale        = FF_QP2LAMBDA * 2;
+        rce->f_code        = s->f_code;
+        rce->b_code        = s->b_code;
+        rce->misc_bits     = 1;
+
+        bits = predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
+        if (pict_type == AV_PICTURE_TYPE_I) {
+            rce->i_count    = s->mb_num;
+            rce->i_tex_bits = bits;
+            rce->p_tex_bits = 0;
+            rce->mv_bits    = 0;
+        } else {
+            rce->i_count    = 0;    // FIXME we do know this approx
+            rce->i_tex_bits = 0;
+            rce->p_tex_bits = bits * 0.9;
+            rce->mv_bits    = bits * 0.1;
         }
-        rcc->i_cplx_sum [pict_type] += rce->i_tex_bits*rce->qscale;
-        rcc->p_cplx_sum [pict_type] += rce->p_tex_bits*rce->qscale;
+        rcc->i_cplx_sum[pict_type]  += rce->i_tex_bits * rce->qscale;
+        rcc->p_cplx_sum[pict_type]  += rce->p_tex_bits * rce->qscale;
         rcc->mv_bits_sum[pict_type] += rce->mv_bits;
-        rcc->frame_count[pict_type] ++;
+        rcc->frame_count[pict_type]++;
 
-        bits= rce->i_tex_bits + rce->p_tex_bits;
-        rate_factor= rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum * br_compensation;
+        bits        = rce->i_tex_bits + rce->p_tex_bits;
+        rate_factor = rcc->pass1_wanted_bits /
+                      rcc->pass1_rc_eq_output_sum * br_compensation;
 
-        q= get_qscale(s, rce, rate_factor, picture_number);
+        q = get_qscale(s, rce, rate_factor, picture_number);
         if (q < 0)
             return -1;
 
-        assert(q>0.0);
-        q= get_diff_limited_q(s, rce, q);
-        assert(q>0.0);
+        assert(q > 0.0);
+        q = get_diff_limited_q(s, rce, q);
+        assert(q > 0.0);
 
-        if(pict_type==AV_PICTURE_TYPE_P || s->intra_only){ //FIXME type dependent blur like in 2-pass
-            rcc->short_term_qsum*=a->qblur;
-            rcc->short_term_qcount*=a->qblur;
+        // FIXME type dependent blur like in 2-pass
+        if (pict_type == AV_PICTURE_TYPE_P || s->intra_only) {
+            rcc->short_term_qsum   *= a->qblur;
+            rcc->short_term_qcount *= a->qblur;
 
-            rcc->short_term_qsum+= q;
+            rcc->short_term_qsum += q;
             rcc->short_term_qcount++;
-            q= short_term_q= rcc->short_term_qsum/rcc->short_term_qcount;
+            q = short_term_q = rcc->short_term_qsum / rcc->short_term_qcount;
         }
-        assert(q>0.0);
+        assert(q > 0.0);
 
-        q= modify_qscale(s, rce, q, picture_number);
+        q = modify_qscale(s, rce, q, picture_number);
 
-        rcc->pass1_wanted_bits+= s->bit_rate/fps;
+        rcc->pass1_wanted_bits += s->bit_rate / fps;
 
-        assert(q>0.0);
+        assert(q > 0.0);
     }
 
-    if(s->avctx->debug&FF_DEBUG_RC){
-        av_log(s->avctx, AV_LOG_DEBUG, "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d\n",
-        av_get_picture_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits/1000, (int)s->total_bits/1000,
-        br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate/1000, (int)fps
-        );
+    if (s->avctx->debug & FF_DEBUG_RC) {
+        av_log(s->avctx, AV_LOG_DEBUG,
+               "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f "
+               "size:%d var:%d/%d br:%d fps:%d\n",
+               av_get_picture_type_char(pict_type),
+               qmin, q, qmax, picture_number,
+               (int)wanted_bits / 1000, (int)s->total_bits / 1000,
+               br_compensation, short_term_q, s->frame_bits,
+               pic->mb_var_sum, pic->mc_mb_var_sum,
+               s->bit_rate / 1000, (int)fps);
     }
 
-    if     (q<qmin) q=qmin;
-    else if(q>qmax) q=qmax;
+    if (q < qmin)
+        q = qmin;
+    else if (q > qmax)
+        q = qmax;
 
-    if(s->adaptive_quant)
+    if (s->adaptive_quant)
         adaptive_quantization(s, q);
     else
-        q= (int)(q + 0.5);
+        q = (int)(q + 0.5);
 
-    if(!dry_run){
-        rcc->last_qscale= q;
-        rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum;
-        rcc->last_mb_var_sum= pic->mb_var_sum;
+    if (!dry_run) {
+        rcc->last_qscale        = q;
+        rcc->last_mc_mb_var_sum = pic->mc_mb_var_sum;
+        rcc->last_mb_var_sum    = pic->mb_var_sum;
     }
     return q;
 }
 
-//----------------------------------------------
+// ----------------------------------------------
 // 2-Pass code
 
 static int init_pass2(MpegEncContext *s)
 {
-    RateControlContext *rcc= &s->rc_context;
-    AVCodecContext *a= s->avctx;
+    RateControlContext *rcc = &s->rc_context;
+    AVCodecContext *a       = s->avctx;
     int i, toobig;
-    double fps= 1/av_q2d(s->avctx->time_base);
-    double complexity[5]={0,0,0,0,0};   // approximate bits at quant=1
-    uint64_t const_bits[5]={0,0,0,0,0}; // quantizer independent bits
+    double fps             = 1 / av_q2d(s->avctx->time_base);
+    double complexity[5]   = { 0 }; // approximate bits at quant=1
+    uint64_t const_bits[5] = { 0 }; // quantizer independent bits
     uint64_t all_const_bits;
-    uint64_t all_available_bits= (uint64_t)(s->bit_rate*(double)rcc->num_entries/fps);
-    double rate_factor=0;
+    uint64_t all_available_bits = (uint64_t)(s->bit_rate *
+                                             (double)rcc->num_entries / fps);
+    double rate_factor          = 0;
     double step;
-    //int last_i_frame=-10000000;
-    const int filter_size= (int)(a->qblur*4) | 1;
+    const int filter_size = (int)(a->qblur * 4) | 1;
     double expected_bits;
     double *qscale, *blurred_qscale, qscale_sum;
 
     /* find complexity & const_bits & decide the pict_types */
-    for(i=0; i<rcc->num_entries; i++){
-        RateControlEntry *rce= &rcc->entry[i];
+    for (i = 0; i < rcc->num_entries; i++) {
+        RateControlEntry *rce = &rcc->entry[i];
 
-        rce->new_pict_type= rce->pict_type;
-        rcc->i_cplx_sum [rce->pict_type] += rce->i_tex_bits*rce->qscale;
-        rcc->p_cplx_sum [rce->pict_type] += rce->p_tex_bits*rce->qscale;
+        rce->new_pict_type                = rce->pict_type;
+        rcc->i_cplx_sum[rce->pict_type]  += rce->i_tex_bits * rce->qscale;
+        rcc->p_cplx_sum[rce->pict_type]  += rce->p_tex_bits * rce->qscale;
         rcc->mv_bits_sum[rce->pict_type] += rce->mv_bits;
-        rcc->frame_count[rce->pict_type] ++;
+        rcc->frame_count[rce->pict_type]++;
 
-        complexity[rce->new_pict_type]+= (rce->i_tex_bits+ rce->p_tex_bits)*(double)rce->qscale;
-        const_bits[rce->new_pict_type]+= rce->mv_bits + rce->misc_bits;
+        complexity[rce->new_pict_type] += (rce->i_tex_bits + rce->p_tex_bits) *
+                                          (double)rce->qscale;
+        const_bits[rce->new_pict_type] += rce->mv_bits + rce->misc_bits;
     }
-    all_const_bits= const_bits[AV_PICTURE_TYPE_I] + const_bits[AV_PICTURE_TYPE_P] + const_bits[AV_PICTURE_TYPE_B];
 
-    if(all_available_bits < all_const_bits){
+    all_const_bits = const_bits[AV_PICTURE_TYPE_I] +
+                     const_bits[AV_PICTURE_TYPE_P] +
+                     const_bits[AV_PICTURE_TYPE_B];
+
+    if (all_available_bits < all_const_bits) {
         av_log(s->avctx, AV_LOG_ERROR, "requested bitrate is too low\n");
         return -1;
     }
 
-    qscale= av_malloc(sizeof(double)*rcc->num_entries);
-    blurred_qscale= av_malloc(sizeof(double)*rcc->num_entries);
+    qscale         = av_malloc(sizeof(double) * rcc->num_entries);
+    blurred_qscale = av_malloc(sizeof(double) * rcc->num_entries);
     toobig = 0;
 
-    for(step=256*256; step>0.0000001; step*=0.5){
-        expected_bits=0;
-        rate_factor+= step;
+    for (step = 256 * 256; step > 0.0000001; step *= 0.5) {
+        expected_bits = 0;
+        rate_factor  += step;
 
-        rcc->buffer_index= s->avctx->rc_buffer_size/2;
+        rcc->buffer_index = s->avctx->rc_buffer_size / 2;
 
         /* find qscale */
-        for(i=0; i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
-            qscale[i]= get_qscale(s, &rcc->entry[i], rate_factor, i);
+        for (i = 0; i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
+
+            qscale[i] = get_qscale(s, &rcc->entry[i], rate_factor, i);
             rcc->last_qscale_for[rce->pict_type] = qscale[i];
         }
-        assert(filter_size%2==1);
+        assert(filter_size % 2 == 1);
 
         /* fixed I/B QP relative to P mode */
-        for(i=rcc->num_entries-1; i>=0; i--){
-            RateControlEntry *rce= &rcc->entry[i];
+        for (i = rcc->num_entries - 1; i >= 0; i--) {
+            RateControlEntry *rce = &rcc->entry[i];
 
-            qscale[i]= get_diff_limited_q(s, rce, qscale[i]);
+            qscale[i] = get_diff_limited_q(s, rce, qscale[i]);
         }
 
         /* smooth curve */
-        for(i=0; i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
-            const int pict_type= rce->new_pict_type;
+        for (i = 0; i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
+            const int pict_type   = rce->new_pict_type;
             int j;
-            double q=0.0, sum=0.0;
-
-            for(j=0; j<filter_size; j++){
-                int index= i+j-filter_size/2;
-                double d= index-i;
-                double coeff= a->qblur==0 ? 1.0 : exp(-d*d/(a->qblur * a->qblur));
-
-                if(index < 0 || index >= rcc->num_entries) continue;
-                if(pict_type != rcc->entry[index].new_pict_type) continue;
-                q+= qscale[index] * coeff;
-                sum+= coeff;
+            double q = 0.0, sum = 0.0;
+
+            for (j = 0; j < filter_size; j++) {
+                int index    = i + j - filter_size / 2;
+                double d     = index - i;
+                double coeff = a->qblur == 0 ? 1.0 : exp(-d * d / (a->qblur * a->qblur));
+
+                if (index < 0 || index >= rcc->num_entries)
+                    continue;
+                if (pict_type != rcc->entry[index].new_pict_type)
+                    continue;
+                q   += qscale[index] * coeff;
+                sum += coeff;
             }
-            blurred_qscale[i]= q/sum;
+            blurred_qscale[i] = q / sum;
         }
 
         /* find expected bits */
-        for(i=0; i<rcc->num_entries; i++){
-            RateControlEntry *rce= &rcc->entry[i];
+        for (i = 0; i < rcc->num_entries; i++) {
+            RateControlEntry *rce = &rcc->entry[i];
             double bits;
-            rce->new_qscale= modify_qscale(s, rce, blurred_qscale[i], i);
-            bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
-            bits += 8*ff_vbv_update(s, bits);
 
-            rce->expected_bits= expected_bits;
-            expected_bits += bits;
+            rce->new_qscale = modify_qscale(s, rce, blurred_qscale[i], i);
+
+            bits  = qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
+            bits += 8 * ff_vbv_update(s, bits);
+
+            rce->expected_bits = expected_bits;
+            expected_bits     += bits;
         }
 
         av_dlog(s->avctx,
                 "expected_bits: %f all_available_bits: %d rate_factor: %f\n",
                 expected_bits, (int)all_available_bits, rate_factor);
-        if(expected_bits > all_available_bits) {
-            rate_factor-= step;
+        if (expected_bits > all_available_bits) {
+            rate_factor -= step;
             ++toobig;
         }
     }
@@ -900,33 +1003,34 @@ static int init_pass2(MpegEncContext *s)
 
     /* check bitrate calculations and print info */
     qscale_sum = 0.0;
-    for(i=0; i<rcc->num_entries; i++){
+    for (i = 0; i < rcc->num_entries; i++) {
         av_dlog(s, "[lavc rc] entry[%d].new_qscale = %.3f  qp = %.3f\n",
                 i,
                 rcc->entry[i].new_qscale,
                 rcc->entry[i].new_qscale / FF_QP2LAMBDA);
-        qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA, s->avctx->qmin, s->avctx->qmax);
+        qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA,
+                              s->avctx->qmin, s->avctx->qmax);
     }
     assert(toobig <= 40);
     av_log(s->avctx, AV_LOG_DEBUG,
-        "[lavc rc] requested bitrate: %d bps  expected bitrate: %d bps\n",
-        s->bit_rate,
-        (int)(expected_bits / ((double)all_available_bits/s->bit_rate)));
+           "[lavc rc] requested bitrate: %d bps  expected bitrate: %d bps\n",
+           s->bit_rate,
+           (int)(expected_bits / ((double)all_available_bits / s->bit_rate)));
     av_log(s->avctx, AV_LOG_DEBUG,
-        "[lavc rc] estimated target average qp: %.3f\n",
-        (float)qscale_sum / rcc->num_entries);
+           "[lavc rc] estimated target average qp: %.3f\n",
+           (float)qscale_sum / rcc->num_entries);
     if (toobig == 0) {
         av_log(s->avctx, AV_LOG_INFO,
-            "[lavc rc] Using all of requested bitrate is not "
-            "necessary for this video with these parameters.\n");
+               "[lavc rc] Using all of requested bitrate is not "
+               "necessary for this video with these parameters.\n");
     } else if (toobig == 40) {
         av_log(s->avctx, AV_LOG_ERROR,
-            "[lavc rc] Error: bitrate too low for this video "
-            "with these parameters.\n");
+               "[lavc rc] Error: bitrate too low for this video "
+               "with these parameters.\n");
         return -1;
-    } else if (fabs(expected_bits/all_available_bits - 1.0) > 0.01) {
+    } else if (fabs(expected_bits / all_available_bits - 1.0) > 0.01) {
         av_log(s->avctx, AV_LOG_ERROR,
-            "[lavc rc] Error: 2pass curve failed to converge\n");
+               "[lavc rc] Error: 2pass curve failed to converge\n");
         return -1;
     }
 
diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h
index c0e05cc..63ebeb2 100644
--- a/libavcodec/ratecontrol.h
+++ b/libavcodec/ratecontrol.h
@@ -61,7 +61,6 @@ typedef struct RateControlEntry{
  * rate control context.
  */
 typedef struct RateControlContext{
-    FILE *stats_file;
     int num_entries;              ///< number of RateControlEntries
     RateControlEntry *entry;
     double buffer_index;          ///< amount of bits in the video/audio buffer
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index 16ee64e..a8227c7 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -25,17 +25,19 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "raw.h"
+#include "libavutil/buffer.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 
 typedef struct RawVideoContext {
-    uint32_t palette[AVPALETTE_COUNT];
-    unsigned char * buffer;  /* block of memory for holding one frame */
-    int             length;  /* number of bytes in buffer */
+    AVBufferRef *palette;
+    int frame_size;  /* size of the frame in bytes */
     int flip;
-    AVFrame pic;             ///< AVCodecContext.coded_frame
+    int is_2_4_bpp; // 2 or 4 bpp raw in avi/mov
+    int is_yuv2;
 } RawVideoContext;
 
 static const PixelFormatTag pix_fmt_bps_avi[] = {
@@ -46,7 +48,7 @@ static const PixelFormatTag pix_fmt_bps_avi[] = {
     { AV_PIX_FMT_RGB555, 16 },
     { AV_PIX_FMT_BGR24,  24 },
     { AV_PIX_FMT_RGB32,  32 },
-    { AV_PIX_FMT_NONE, 0 },
+    { AV_PIX_FMT_NONE,    0 },
 };
 
 static const PixelFormatTag pix_fmt_bps_mov[] = {
@@ -60,10 +62,11 @@ static const PixelFormatTag pix_fmt_bps_mov[] = {
     { AV_PIX_FMT_RGB24,    24 },
     { AV_PIX_FMT_ARGB,     32 },
     { AV_PIX_FMT_MONOWHITE,33 },
-    { AV_PIX_FMT_NONE, 0 },
+    { AV_PIX_FMT_NONE,      0 },
 };
 
-static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
+static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags,
+                                       unsigned int fourcc)
 {
     while (tags->pix_fmt >= 0) {
         if (tags->fourcc == fourcc)
@@ -76,122 +79,164 @@ static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags, unsigned int
 static av_cold int raw_init_decoder(AVCodecContext *avctx)
 {
     RawVideoContext *context = avctx->priv_data;
+    const AVPixFmtDescriptor *desc;
 
-    if (avctx->codec_tag == MKTAG('r','a','w',' '))
-        avctx->pix_fmt = 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);
+    if (avctx->codec_tag == MKTAG('r', 'a', 'w', ' '))
+        avctx->pix_fmt = 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);
     else if (avctx->codec_tag)
         avctx->pix_fmt = 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);
-
-    avpriv_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->buffer = av_malloc(context->length);
-        if (!context->buffer)
-            return -1;
+        avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi,
+                                      avctx->bits_per_coded_sample);
+
+    desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    if (!desc) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL)) {
+        context->palette = av_buffer_alloc(AVPALETTE_SIZE);
+        if (!context->palette)
+            return AVERROR(ENOMEM);
+        if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
+            avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt);
+        else
+            memset(context->palette->data, 0, AVPALETTE_SIZE);
     }
-    context->pic.pict_type = AV_PICTURE_TYPE_I;
-    context->pic.key_frame = 1;
 
-    avctx->coded_frame= &context->pic;
+    context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width,
+                                             avctx->height);
+    if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) &&
+        avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
+       (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' ')))
+        context->is_2_4_bpp = 1;
+
+    if ((avctx->extradata_size >= 9 &&
+         !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
+        avctx->codec_tag == MKTAG(3, 0, 0, 0) ||
+        avctx->codec_tag == MKTAG('W','R','A','W'))
+        context->flip = 1;
 
-    if((avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
-        avctx->codec_tag == MKTAG(3, 0, 0, 0) || avctx->codec_tag == MKTAG('W','R','A','W'))
-        context->flip=1;
+    if (avctx->codec_tag == AV_RL32("yuv2") &&
+        avctx->pix_fmt   == AV_PIX_FMT_YUYV422)
+        context->is_yuv2 = 1;
 
     return 0;
 }
 
-static void flip(AVCodecContext *avctx, AVPicture * picture){
-    picture->data[0] += picture->linesize[0] * (avctx->height-1);
+static void flip(AVCodecContext *avctx, AVPicture *picture)
+{
+    picture->data[0]     += picture->linesize[0] * (avctx->height - 1);
     picture->linesize[0] *= -1;
 }
 
-static int raw_decode(AVCodecContext *avctx,
-                            void *data, int *got_frame,
-                            AVPacket *avpkt)
+static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
+                      AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    RawVideoContext *context = avctx->priv_data;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    RawVideoContext *context       = avctx->priv_data;
+    const uint8_t *buf             = avpkt->data;
+    int buf_size                   = avpkt->size;
+    int need_copy                  = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2;
     int res;
 
     AVFrame   *frame   = data;
     AVPicture *picture = data;
 
-    frame->pict_type        = avctx->coded_frame->pict_type;
-    frame->interlaced_frame = avctx->coded_frame->interlaced_frame;
-    frame->top_field_first = avctx->coded_frame->top_field_first;
+    frame->pict_type        = AV_PICTURE_TYPE_I;
+    frame->key_frame        = 1;
     frame->reordered_opaque = avctx->reordered_opaque;
-    frame->pkt_pts          = avctx->pkt->pts;
+    frame->pkt_pts          = avctx->internal->pkt->pts;
 
-    if(buf_size < context->length - (avctx->pix_fmt==AV_PIX_FMT_PAL8 ? 256*4 : 0))
+    if (buf_size < context->frame_size - (avctx->pix_fmt == AV_PIX_FMT_PAL8 ?
+                                          AVPALETTE_SIZE : 0))
         return -1;
 
+    if (need_copy)
+        frame->buf[0] = av_buffer_alloc(context->frame_size);
+    else
+        frame->buf[0] = av_buffer_ref(avpkt->buf);
+    if (!frame->buf[0])
+        return AVERROR(ENOMEM);
+
     //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)
-    if (context->buffer) {
+    if (context->is_2_4_bpp) {
         int i;
-        uint8_t *dst = context->buffer;
-        buf_size = context->length - 256*4;
-        if (avctx->bits_per_coded_sample == 4){
-            for(i=0; 2*i+1 < buf_size; i++){
-                dst[2*i+0]= buf[i]>>4;
-                dst[2*i+1]= buf[i]&15;
+        uint8_t *dst = frame->buf[0]->data;
+        buf_size = context->frame_size - AVPALETTE_SIZE;
+        if (avctx->bits_per_coded_sample == 4) {
+            for (i = 0; 2 * i + 1 < buf_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++){
-                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;
+        } else {
+            for (i = 0; 4 * i + 3 < buf_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;
             }
-        buf= dst;
+        }
+        buf = dst;
+    } else if (need_copy) {
+        memcpy(frame->buf[0]->data, buf, FFMIN(buf_size, context->frame_size));
+        buf = frame->buf[0]->data;
     }
 
-    if(avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||
-       avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
-        buf += buf_size - context->length;
+    if (avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||
+        avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
+        buf += buf_size - context->frame_size;
 
     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;
-    }
+
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
+        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
+                                                     NULL);
 
         if (pal) {
-            memcpy(frame->data[1], pal, AVPALETTE_SIZE);
+            av_buffer_unref(&context->palette);
+            context->palette = av_buffer_alloc(AVPALETTE_SIZE);
+            if (!context->palette)
+                return AVERROR(ENOMEM);
+            memcpy(context->palette->data, pal, AVPALETTE_SIZE);
             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(context->flip)
+    if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) ||
+        (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
+        frame->buf[1]  = av_buffer_ref(context->palette);
+        if (!frame->buf[1])
+            return AVERROR(ENOMEM);
+        frame->data[1] = frame->buf[1]->data;
+    }
+    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 (context->flip)
         flip(avctx, picture);
 
-    if (   avctx->codec_tag == MKTAG('Y', 'V', '1', '2')
-        || avctx->codec_tag == MKTAG('Y', 'V', '1', '6')
-        || avctx->codec_tag == MKTAG('Y', 'V', '2', '4')
-        || avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))
+    if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2') ||
+        avctx->codec_tag == MKTAG('Y', 'V', '1', '6') ||
+        avctx->codec_tag == MKTAG('Y', 'V', '2', '4') ||
+        avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))
         FFSWAP(uint8_t *, picture->data[1], picture->data[2]);
 
-    if(avctx->codec_tag == AV_RL32("yuv2") &&
-       avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
+    if (avctx->codec_tag == AV_RL32("yuv2") &&
+        avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
         int x, y;
         uint8_t *line = picture->data[0];
-        for(y = 0; y < avctx->height; y++) {
-            for(x = 0; x < avctx->width; x++)
-                line[2*x + 1] ^= 0x80;
+        for (y = 0; y < avctx->height; y++) {
+            for (x = 0; x < avctx->width; x++)
+                line[2 * x + 1] ^= 0x80;
             line += picture->linesize[0];
         }
     }
@@ -204,17 +249,17 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx)
 {
     RawVideoContext *context = avctx->priv_data;
 
-    av_freep(&context->buffer);
+    av_buffer_unref(&context->palette);
     return 0;
 }
 
 AVCodec ff_rawvideo_decoder = {
     .name           = "rawvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_RAWVIDEO,
     .priv_data_size = sizeof(RawVideoContext),
     .init           = raw_init_decoder,
     .close          = raw_close_decoder,
     .decode         = raw_decode,
-    .long_name      = NULL_IF_CONFIG_SMALL("raw video"),
 };
diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index 3e607af..6c90d33 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -71,10 +71,10 @@ static int raw_encode(AVCodecContext *avctx, AVPacket *pkt,
 
 AVCodec ff_rawvideo_encoder = {
     .name           = "rawvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_RAWVIDEO,
     .priv_data_size = sizeof(AVFrame),
     .init           = raw_init_encoder,
     .encode2        = raw_encode,
-    .long_name      = NULL_IF_CONFIG_SMALL("raw video"),
 };
diff --git a/libavcodec/rdft.c b/libavcodec/rdft.c
index 116cfa4..54cf14a 100644
--- a/libavcodec/rdft.c
+++ b/libavcodec/rdft.c
@@ -54,7 +54,7 @@ static SINTABLE_CONST FFTSample * const ff_sin_tabs[] = {
  * the two real FFTs into one complex FFT. Unmangle the results.
  * ref: http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM
  */
-static void ff_rdft_calc_c(RDFTContext* s, FFTSample* data)
+static void rdft_calc_c(RDFTContext *s, FFTSample *data)
 {
     int i, i1, i2;
     FFTComplex ev, od;
@@ -120,7 +120,7 @@ av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans)
         s->tsin[i] = sin(i*theta);
     }
 #endif
-    s->rdft_calc   = ff_rdft_calc_c;
+    s->rdft_calc   = rdft_calc_c;
 
     if (ARCH_ARM) ff_rdft_init_arm(s);
 
diff --git a/libavcodec/rectangle.h b/libavcodec/rectangle.h
index 5cc81fe..73e8b0a 100644
--- a/libavcodec/rectangle.h
+++ b/libavcodec/rectangle.h
@@ -31,7 +31,6 @@
 #include <assert.h>
 #include "config.h"
 #include "libavutil/common.h"
-#include "dsputil.h"
 
 /**
  * fill a rectangle.
@@ -47,7 +46,6 @@ static av_always_inline void fill_rectangle(void *vp, int w, int h, int stride,
     w      *= size;
     stride *= size;
 
-    assert((((long)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0);
     assert((stride&(w-1))==0);
     if(w==2){
         const uint16_t v= size==4 ? val : val*0x0101;
diff --git a/libavcodec/resample.c b/libavcodec/resample.c
deleted file mode 100644
index 1b3bb83..0000000
--- a/libavcodec/resample.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * samplerate conversion for both audio and video
- * Copyright (c) 2000 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
- * samplerate conversion for both audio and video
- */
-
-#include <string.h>
-
-#include "avcodec.h"
-#include "audioconvert.h"
-#include "libavutil/opt.h"
-#include "libavutil/mem.h"
-#include "libavutil/samplefmt.h"
-
-#if FF_API_AVCODEC_RESAMPLE
-
-#define MAX_CHANNELS 8
-
-struct AVResampleContext;
-
-static const char *context_to_name(void *ptr)
-{
-    return "audioresample";
-}
-
-static const AVOption options[] = {{NULL}};
-static const AVClass audioresample_context_class = {
-    "ReSampleContext", context_to_name, options, LIBAVUTIL_VERSION_INT
-};
-
-struct ReSampleContext {
-    struct AVResampleContext *resample_context;
-    short *temp[MAX_CHANNELS];
-    int temp_len;
-    float ratio;
-    /* channel convert */
-    int input_channels, output_channels, filter_channels;
-    AVAudioConvert *convert_ctx[2];
-    enum AVSampleFormat sample_fmt[2]; ///< input and output sample format
-    unsigned sample_size[2];           ///< size of one sample in sample_fmt
-    short *buffer[2];                  ///< buffers used for conversion to S16
-    unsigned buffer_size[2];           ///< sizes of allocated buffers
-};
-
-/* n1: number of samples */
-static void stereo_to_mono(short *output, short *input, int n1)
-{
-    short *p, *q;
-    int n = n1;
-
-    p = input;
-    q = output;
-    while (n >= 4) {
-        q[0] = (p[0] + p[1]) >> 1;
-        q[1] = (p[2] + p[3]) >> 1;
-        q[2] = (p[4] + p[5]) >> 1;
-        q[3] = (p[6] + p[7]) >> 1;
-        q += 4;
-        p += 8;
-        n -= 4;
-    }
-    while (n > 0) {
-        q[0] = (p[0] + p[1]) >> 1;
-        q++;
-        p += 2;
-        n--;
-    }
-}
-
-/* n1: number of samples */
-static void mono_to_stereo(short *output, short *input, int n1)
-{
-    short *p, *q;
-    int n = n1;
-    int v;
-
-    p = input;
-    q = output;
-    while (n >= 4) {
-        v = p[0]; q[0] = v; q[1] = v;
-        v = p[1]; q[2] = v; q[3] = v;
-        v = p[2]; q[4] = v; q[5] = v;
-        v = p[3]; q[6] = v; q[7] = v;
-        q += 8;
-        p += 4;
-        n -= 4;
-    }
-    while (n > 0) {
-        v = p[0]; q[0] = v; q[1] = v;
-        q += 2;
-        p += 1;
-        n--;
-    }
-}
-
-static void deinterleave(short **output, short *input, int channels, int samples)
-{
-    int i, j;
-
-    for (i = 0; i < samples; i++) {
-        for (j = 0; j < channels; j++) {
-            *output[j]++ = *input++;
-        }
-    }
-}
-
-static void interleave(short *output, short **input, int channels, int samples)
-{
-    int i, j;
-
-    for (i = 0; i < samples; i++) {
-        for (j = 0; j < channels; j++) {
-            *output++ = *input[j]++;
-        }
-    }
-}
-
-static void ac3_5p1_mux(short *output, short *input1, short *input2, int n)
-{
-    int i;
-    short l, r;
-
-    for (i = 0; i < n; i++) {
-        l = *input1++;
-        r = *input2++;
-        *output++ = l;                  /* left */
-        *output++ = (l / 2) + (r / 2);  /* center */
-        *output++ = r;                  /* right */
-        *output++ = 0;                  /* left surround */
-        *output++ = 0;                  /* right surroud */
-        *output++ = 0;                  /* low freq */
-    }
-}
-
-ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
-                                        int output_rate, int input_rate,
-                                        enum AVSampleFormat sample_fmt_out,
-                                        enum AVSampleFormat sample_fmt_in,
-                                        int filter_length, int log2_phase_count,
-                                        int linear, double cutoff)
-{
-    ReSampleContext *s;
-
-    if (input_channels > MAX_CHANNELS) {
-        av_log(NULL, AV_LOG_ERROR,
-               "Resampling with input channels greater than %d is unsupported.\n",
-               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");
-        return NULL;
-    }
-
-    s = av_mallocz(sizeof(ReSampleContext));
-    if (!s) {
-        av_log(NULL, AV_LOG_ERROR, "Can't allocate memory for resample context.\n");
-        return NULL;
-    }
-
-    s->ratio = (float)output_rate / (float)input_rate;
-
-    s->input_channels = input_channels;
-    s->output_channels = output_channels;
-
-    s->filter_channels = s->input_channels;
-    if (s->output_channels < s->filter_channels)
-        s->filter_channels = s->output_channels;
-
-    s->sample_fmt[0]  = sample_fmt_in;
-    s->sample_fmt[1]  = sample_fmt_out;
-    s->sample_size[0] = av_get_bytes_per_sample(s->sample_fmt[0]);
-    s->sample_size[1] = av_get_bytes_per_sample(s->sample_fmt[1]);
-
-    if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) {
-        if (!(s->convert_ctx[0] = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1,
-                                                         s->sample_fmt[0], 1, NULL, 0))) {
-            av_log(s, AV_LOG_ERROR,
-                   "Cannot convert %s sample format to s16 sample format\n",
-                   av_get_sample_fmt_name(s->sample_fmt[0]));
-            av_free(s);
-            return NULL;
-        }
-    }
-
-    if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
-        if (!(s->convert_ctx[1] = av_audio_convert_alloc(s->sample_fmt[1], 1,
-                                                         AV_SAMPLE_FMT_S16, 1, NULL, 0))) {
-            av_log(s, AV_LOG_ERROR,
-                   "Cannot convert s16 sample format to %s sample format\n",
-                   av_get_sample_fmt_name(s->sample_fmt[1]));
-            av_audio_convert_free(s->convert_ctx[0]);
-            av_free(s);
-            return NULL;
-        }
-    }
-
-    s->resample_context = av_resample_init(output_rate, input_rate,
-                                           filter_length, log2_phase_count,
-                                           linear, cutoff);
-
-    *(const AVClass**)s->resample_context = &audioresample_context_class;
-
-    return s;
-}
-
-/* resample audio. 'nb_samples' is the number of input samples */
-/* XXX: optimize it ! */
-int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples)
-{
-    int i, nb_samples1;
-    short *bufin[MAX_CHANNELS];
-    short *bufout[MAX_CHANNELS];
-    short *buftmp2[MAX_CHANNELS], *buftmp3[MAX_CHANNELS];
-    short *output_bak = NULL;
-    int lenout;
-
-    if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) {
-        /* nothing to do */
-        memcpy(output, input, nb_samples * s->input_channels * sizeof(short));
-        return nb_samples;
-    }
-
-    if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) {
-        int istride[1] = { s->sample_size[0] };
-        int ostride[1] = { 2 };
-        const void *ibuf[1] = { input };
-        void       *obuf[1];
-        unsigned input_size = nb_samples * s->input_channels * 2;
-
-        if (!s->buffer_size[0] || s->buffer_size[0] < input_size) {
-            av_free(s->buffer[0]);
-            s->buffer_size[0] = input_size;
-            s->buffer[0] = av_malloc(s->buffer_size[0]);
-            if (!s->buffer[0]) {
-                av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n");
-                return 0;
-            }
-        }
-
-        obuf[0] = s->buffer[0];
-
-        if (av_audio_convert(s->convert_ctx[0], obuf, ostride,
-                             ibuf, istride, nb_samples * s->input_channels) < 0) {
-            av_log(s->resample_context, AV_LOG_ERROR,
-                   "Audio sample format conversion failed\n");
-            return 0;
-        }
-
-        input = s->buffer[0];
-    }
-
-    lenout = 4 * 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]) *
-                       s->output_channels;
-        output_bak = output;
-
-        if (!s->buffer_size[1] || s->buffer_size[1] < out_size) {
-            av_free(s->buffer[1]);
-            s->buffer_size[1] = out_size;
-            s->buffer[1] = av_malloc(s->buffer_size[1]);
-            if (!s->buffer[1]) {
-                av_log(s->resample_context, AV_LOG_ERROR, "Could not allocate buffer\n");
-                return 0;
-            }
-        }
-
-        output = s->buffer[1];
-    }
-
-    /* XXX: move those malloc to resample init code */
-    for (i = 0; i < s->filter_channels; i++) {
-        bufin[i] = av_malloc((nb_samples + s->temp_len) * sizeof(short));
-        memcpy(bufin[i], s->temp[i], s->temp_len * sizeof(short));
-        buftmp2[i] = bufin[i] + s->temp_len;
-        bufout[i] = av_malloc(lenout * sizeof(short));
-    }
-
-    if (s->input_channels == 2 && s->output_channels == 1) {
-        buftmp3[0] = output;
-        stereo_to_mono(buftmp2[0], input, nb_samples);
-    } 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->output_channels >= s->input_channels && s->input_channels >= 2) {
-        for (i = 0; i < s->input_channels; i++) {
-            buftmp3[i] = bufout[i];
-        }
-        deinterleave(buftmp2, input, s->input_channels, nb_samples);
-    } else {
-        buftmp3[0] = output;
-        memcpy(buftmp2[0], input, nb_samples * sizeof(short));
-    }
-
-    nb_samples += s->temp_len;
-
-    /* resample each channel */
-    nb_samples1 = 0; /* avoid warning */
-    for (i = 0; i < s->filter_channels; i++) {
-        int consumed;
-        int is_last = i + 1 == s->filter_channels;
-
-        nb_samples1 = av_resample(s->resample_context, buftmp3[i], bufin[i],
-                                  &consumed, nb_samples, lenout, is_last);
-        s->temp_len = nb_samples - consumed;
-        s->temp[i] = av_realloc(s->temp[i], s->temp_len * sizeof(short));
-        memcpy(s->temp[i], bufin[i] + consumed, s->temp_len * sizeof(short));
-    }
-
-    if (s->output_channels == 2 && s->input_channels == 1) {
-        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) {
-        interleave(output, buftmp3, s->output_channels, nb_samples1);
-    }
-
-    if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
-        int istride[1] = { 2 };
-        int ostride[1] = { s->sample_size[1] };
-        const void *ibuf[1] = { output };
-        void       *obuf[1] = { output_bak };
-
-        if (av_audio_convert(s->convert_ctx[1], obuf, ostride,
-                             ibuf, istride, nb_samples1 * s->output_channels) < 0) {
-            av_log(s->resample_context, AV_LOG_ERROR,
-                   "Audio sample format conversion failed\n");
-            return 0;
-        }
-    }
-
-    for (i = 0; i < s->filter_channels; i++) {
-        av_free(bufin[i]);
-        av_free(bufout[i]);
-    }
-
-    return nb_samples1;
-}
-
-void audio_resample_close(ReSampleContext *s)
-{
-    int i;
-    av_resample_close(s->resample_context);
-    for (i = 0; i < s->filter_channels; i++)
-        av_freep(&s->temp[i]);
-    av_freep(&s->buffer[0]);
-    av_freep(&s->buffer[1]);
-    av_audio_convert_free(s->convert_ctx[0]);
-    av_audio_convert_free(s->convert_ctx[1]);
-    av_free(s);
-}
-
-#endif
diff --git a/libavcodec/resample2.c b/libavcodec/resample2.c
deleted file mode 100644
index c6e5c48..0000000
--- a/libavcodec/resample2.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * audio resampling
- * Copyright (c) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- * audio resampling
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#include "avcodec.h"
-#include "dsputil.h"
-#include "libavutil/common.h"
-
-#if FF_API_AVCODEC_RESAMPLE
-
-#ifndef CONFIG_RESAMPLE_HP
-#define FILTER_SHIFT 15
-
-#define FELEM int16_t
-#define FELEM2 int32_t
-#define FELEML int64_t
-#define FELEM_MAX INT16_MAX
-#define FELEM_MIN INT16_MIN
-#define WINDOW_TYPE 9
-#elif !defined(CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE)
-#define FILTER_SHIFT 30
-
-#define FELEM int32_t
-#define FELEM2 int64_t
-#define FELEML int64_t
-#define FELEM_MAX INT32_MAX
-#define FELEM_MIN INT32_MIN
-#define WINDOW_TYPE 12
-#else
-#define FILTER_SHIFT 0
-
-#define FELEM double
-#define FELEM2 double
-#define FELEML double
-#define WINDOW_TYPE 24
-#endif
-
-
-typedef struct AVResampleContext{
-    const AVClass *av_class;
-    FELEM *filter_bank;
-    int filter_length;
-    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;
-}AVResampleContext;
-
-/**
- * 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;
-
-    x= x*x/4;
-    for(i=1; v != lastv; i++){
-        lastv=v;
-        t *= x/(i*i);
-        v += t;
-    }
-    return v;
-}
-
-/**
- * Build a polyphase filterbank.
- * @param factor resampling factor
- * @param scale wanted sum of coefficients for each filter
- * @param type 0->cubic, 1->blackman nuttall windowed sinc, 2..16->kaiser windowed sinc beta=2..16
- * @return 0 on success, negative on error
- */
-static int build_filter(FELEM *filter, double factor, int tap_count, int phase_count, int scale, int type){
-    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(type){
-            case 0:{
-                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 1:
-                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;
-            default:
-                w = 2.0*x / (factor*tap_count*M_PI);
-                y *= bessel(type*sqrt(FFMAX(1-w*w, 0)));
-                break;
-            }
-
-            tab[i] = y;
-            norm += y;
-        }
-
-        /* normalize so that an uniform color remains the same */
-        for(i=0;i<tap_count;i++) {
-#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE
-            filter[ph * tap_count + i] = tab[i] / norm;
-#else
-            filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm), FELEM_MIN, FELEM_MAX);
-#endif
-        }
-    }
-#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;
-}
-
-AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){
-    AVResampleContext *c= av_mallocz(sizeof(AVResampleContext));
-    double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
-    int phase_count= 1<<phase_shift;
-
-    if (!c)
-        return NULL;
-
-    c->phase_shift= phase_shift;
-    c->phase_mask= phase_count-1;
-    c->linear= linear;
-
-    c->filter_length= FFMAX((int)ceil(filter_size/factor), 1);
-    c->filter_bank= av_mallocz(c->filter_length*(phase_count+1)*sizeof(FELEM));
-    if (!c->filter_bank)
-        goto error;
-    if (build_filter(c->filter_bank, factor, c->filter_length, phase_count, 1<<FILTER_SHIFT, WINDOW_TYPE))
-        goto error;
-    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;
-    c->index= -phase_count*((c->filter_length-1)/2);
-
-    return c;
-error:
-    av_free(c->filter_bank);
-    av_free(c);
-    return NULL;
-}
-
-void av_resample_close(AVResampleContext *c){
-    av_freep(&c->filter_bank);
-    av_freep(&c);
-}
-
-void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){
-//    sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr;
-    c->compensation_distance= compensation_distance;
-    c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
-}
-
-int av_resample(AVResampleContext *c, short *dst, short *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;
-
-  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;
-        }
-        frac += dst_index * dst_incr_frac;
-        index += dst_index * dst_incr;
-        index += frac / c->src_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);
-        int sample_index= index >> c->phase_shift;
-        FELEM2 val=0;
-
-        if(sample_index < 0){
-            for(i=0; i<c->filter_length; i++)
-                val += src[FFABS(sample_index + i) % src_size] * filter[i];
-        }else if(sample_index + c->filter_length > src_size){
-            break;
-        }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_length];
-            }
-            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];
-            }
-        }
-
-#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE
-        dst[dst_index] = av_clip_int16(lrintf(val));
-#else
-        val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;
-        dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val;
-#endif
-
-        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;
-        assert(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;
-}
-
-#endif
diff --git a/libavcodec/rl2.c b/libavcodec/rl2.c
index c9eb93e..54b3e6a 100644
--- a/libavcodec/rl2.c
+++ b/libavcodec/rl2.c
@@ -41,12 +41,11 @@
 
 typedef struct Rl2Context {
     AVCodecContext *avctx;
-    AVFrame frame;
 
-    unsigned short video_base; ///< initial drawing offset
-    unsigned int clr_count;    ///< number of used colors (currently unused)
-    unsigned char* back_frame; ///< background frame
-    unsigned int palette[AVPALETTE_COUNT];
+    uint16_t video_base;  ///< initial drawing offset
+    uint32_t clr_count;   ///< number of used colors (currently unused)
+    uint8_t *back_frame;  ///< background frame
+    uint32_t palette[AVPALETTE_COUNT];
 } Rl2Context;
 
 /**
@@ -58,67 +57,68 @@ typedef struct Rl2Context {
  * @param stride stride of the output buffer
  * @param video_base offset of the rle data inside the frame
  */
-static void rl2_rle_decode(Rl2Context *s,const unsigned char* in,int size,
-                               unsigned char* out,int stride,int video_base){
+static void rl2_rle_decode(Rl2Context *s, const uint8_t *in, int size,
+                               uint8_t *out, int stride, int video_base)
+{
     int base_x = video_base % s->avctx->width;
     int base_y = video_base / s->avctx->width;
     int stride_adj = stride - s->avctx->width;
     int i;
-    const unsigned char* back_frame = s->back_frame;
-    const unsigned char* in_end = in + size;
-    const unsigned char* out_end = out + stride * s->avctx->height;
-    unsigned char* line_end;
+    const uint8_t *back_frame = s->back_frame;
+    const uint8_t *in_end     = in + size;
+    const uint8_t *out_end    = out + stride * s->avctx->height;
+    uint8_t *line_end;
 
     /** copy start of the background frame */
-    for(i=0;i<=base_y;i++){
-        if(s->back_frame)
-            memcpy(out,back_frame,s->avctx->width);
-        out += stride;
+    for (i = 0; i <= base_y; i++) {
+        if (s->back_frame)
+            memcpy(out, back_frame, s->avctx->width);
+        out        += stride;
         back_frame += s->avctx->width;
     }
     back_frame += base_x - s->avctx->width;
-    line_end = out - stride_adj;
-    out += base_x - stride;
+    line_end    = out - stride_adj;
+    out        += base_x - stride;
 
     /** decode the variable part of the frame */
-    while(in < in_end){
-        unsigned char val = *in++;
-        int len = 1;
-        if(val >= 0x80){
-            if(in >= in_end)
+    while (in < in_end) {
+        uint8_t val = *in++;
+        int len     = 1;
+        if (val >= 0x80) {
+            if (in >= in_end)
                 break;
             len = *in++;
-            if(!len)
+            if (!len)
                 break;
         }
 
-        if(len >= out_end - out)
+        if (len >= out_end - out)
             break;
 
-        if(s->back_frame)
+        if (s->back_frame)
             val |= 0x80;
         else
             val &= ~0x80;
 
-        while(len--){
-            *out++ = (val == 0x80)? *back_frame:val;
+        while (len--) {
+            *out++ = (val == 0x80) ? *back_frame : val;
             back_frame++;
-            if(out == line_end){
-                 out += stride_adj;
+            if (out == line_end) {
+                 out      += stride_adj;
                  line_end += stride;
-                 if(len >= out_end - out)
+                 if (len >= out_end - out)
                      break;
             }
         }
     }
 
     /** copy the rest from the background frame */
-    if(s->back_frame){
-        while(out < out_end){
+    if (s->back_frame) {
+        while (out < out_end) {
             memcpy(out, back_frame, line_end - out);
             back_frame += line_end - out;
-            out = line_end + stride_adj;
-            line_end += stride;
+            out         = line_end + stride_adj;
+            line_end   += stride;
         }
     }
 }
@@ -134,37 +134,38 @@ static av_cold int rl2_decode_init(AVCodecContext *avctx)
     Rl2Context *s = avctx->priv_data;
     int back_size;
     int i;
-    s->avctx = avctx;
+
+    s->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     /** parse extra data */
-    if(!avctx->extradata || avctx->extradata_size < EXTRADATA1_SIZE){
+    if (!avctx->extradata || avctx->extradata_size < EXTRADATA1_SIZE) {
         av_log(avctx, AV_LOG_ERROR, "invalid extradata size\n");
-        return -1;
+        return AVERROR(EINVAL);
     }
 
     /** get frame_offset */
     s->video_base = AV_RL16(&avctx->extradata[0]);
-    s->clr_count = AV_RL32(&avctx->extradata[2]);
+    s->clr_count  = AV_RL32(&avctx->extradata[2]);
 
-    if(s->video_base >= avctx->width * avctx->height){
+    if (s->video_base >= avctx->width * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "invalid video_base\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /** initialize palette */
-    for(i=0;i<AVPALETTE_COUNT;i++)
+    for (i = 0; i < AVPALETTE_COUNT; i++)
         s->palette[i] = AV_RB24(&avctx->extradata[6 + i * 3]);
 
     /** decode background frame if present */
     back_size = avctx->extradata_size - EXTRADATA1_SIZE;
 
-    if(back_size > 0){
-        unsigned char* back_frame = av_mallocz(avctx->width*avctx->height);
-        if(!back_frame)
-            return -1;
-        rl2_rle_decode(s,avctx->extradata + EXTRADATA1_SIZE,back_size,
-                           back_frame,avctx->width,0);
+    if (back_size > 0) {
+        uint8_t *back_frame = av_mallocz(avctx->width*avctx->height);
+        if (!back_frame)
+            return AVERROR(ENOMEM);
+        rl2_rle_decode(s, avctx->extradata + EXTRADATA1_SIZE, back_size,
+                       back_frame, avctx->width, 0);
         s->back_frame = back_frame;
     }
     return 0;
@@ -172,31 +173,27 @@ static av_cold int rl2_decode_init(AVCodecContext *avctx)
 
 
 static int rl2_decode_frame(AVCodecContext *avctx,
-                              void *data, int *got_frame,
-                              AVPacket *avpkt)
+                            void *data, int *got_frame,
+                            AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    int ret, buf_size  = avpkt->size;
     Rl2Context *s = avctx->priv_data;
 
-    if(s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    /** get buffer */
-    s->frame.reference= 0;
-    if(ff_get_buffer(avctx, &s->frame)) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /** run length decode */
-    rl2_rle_decode(s,buf,buf_size,s->frame.data[0],s->frame.linesize[0],s->video_base);
+    rl2_rle_decode(s, buf, buf_size, frame->data[0], frame->linesize[0],
+                   s->video_base);
 
     /** make the palette available on the way out */
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     /** report that the buffer was completely consumed */
     return buf_size;
@@ -212,9 +209,6 @@ static av_cold int rl2_decode_end(AVCodecContext *avctx)
 {
     Rl2Context *s = avctx->priv_data;
 
-    if(s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
     av_free(s->back_frame);
 
     return 0;
@@ -223,6 +217,7 @@ static av_cold int rl2_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_rl2_decoder = {
     .name           = "rl2",
+    .long_name      = NULL_IF_CONFIG_SMALL("RL2 video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_RL2,
     .priv_data_size = sizeof(Rl2Context),
@@ -230,5 +225,4 @@ AVCodec ff_rl2_decoder = {
     .close          = rl2_decode_end,
     .decode         = rl2_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("RL2 video"),
 };
diff --git a/libavcodec/rnd_avg.h b/libavcodec/rnd_avg.h
new file mode 100644
index 0000000..7301578
--- /dev/null
+++ b/libavcodec/rnd_avg.h
@@ -0,0 +1,54 @@
+/*
+ * 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_RND_AVG_H
+#define AVCODEC_RND_AVG_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define CALL_2X_PIXELS(a, b, n)\
+static void a(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){\
+    b(block  , pixels  , line_size, h);\
+    b(block+n, pixels+n, line_size, h);\
+}
+
+#define         BYTE_VEC32(c)   ((c)*0x01010101UL)
+#define         BYTE_VEC64(c)   ((c)*0x0001000100010001UL)
+
+static inline uint32_t rnd_avg32(uint32_t a, uint32_t b)
+{
+    return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
+}
+
+static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
+{
+    return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
+}
+
+static inline uint64_t rnd_avg64(uint64_t a, uint64_t b)
+{
+    return (a | b) - (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
+}
+
+static inline uint64_t no_rnd_avg64(uint64_t a, uint64_t b)
+{
+    return (a & b) + (((a ^ b) & ~BYTE_VEC64(0x01)) >> 1);
+}
+
+#endif /* AVCODEC_RND_AVG_H */
diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c
index 3cc9931..f97d5d6 100644
--- a/libavcodec/roqaudioenc.c
+++ b/libavcodec/roqaudioenc.c
@@ -46,9 +46,6 @@ static av_cold int roq_dpcm_encode_close(AVCodecContext *avctx)
 {
     ROQDPCMContext *context = avctx->priv_data;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
     av_freep(&context->frame_buffer);
 
     return 0;
@@ -81,14 +78,6 @@ static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx)
 
     context->lastSample[0] = context->lastSample[1] = 0;
 
-#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:
     roq_dpcm_encode_close(avctx);
@@ -204,6 +193,7 @@ static int roq_dpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_roq_dpcm_encoder = {
     .name           = "roq_dpcm",
+    .long_name      = NULL_IF_CONFIG_SMALL("id RoQ DPCM"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_ROQ_DPCM,
     .priv_data_size = sizeof(ROQDPCMContext),
@@ -213,5 +203,4 @@ AVCodec ff_roq_dpcm_encoder = {
     .capabilities   = CODEC_CAP_DELAY,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("id RoQ DPCM"),
 };
diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h
index 33d77ed..3f00022 100644
--- a/libavcodec/roqvideo.h
+++ b/libavcodec/roqvideo.h
@@ -25,7 +25,6 @@
 #include "libavutil/lfg.h"
 #include "avcodec.h"
 #include "bytestream.h"
-#include "dsputil.h"
 
 typedef struct roq_cell {
     unsigned char y[4];
@@ -45,7 +44,6 @@ struct RoqTempData;
 typedef struct RoqContext {
 
     AVCodecContext *avctx;
-    AVFrame frames[2];
     AVFrame *last_frame;
     AVFrame *current_frame;
     int first_frame;
diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c
index d156a84..ac7d4ba 100644
--- a/libavcodec/roqvideodec.c
+++ b/libavcodec/roqvideodec.c
@@ -31,6 +31,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "roqvideo.h"
 
 static void roqvideo_decode_frame(RoqContext *ri)
@@ -168,8 +169,15 @@ static av_cold int roq_decode_init(AVCodecContext *avctx)
 
     s->width = avctx->width;
     s->height = avctx->height;
-    s->last_frame    = &s->frames[0];
-    s->current_frame = &s->frames[1];
+
+    s->last_frame    = av_frame_alloc();
+    s->current_frame = av_frame_alloc();
+    if (!s->current_frame || !s->last_frame) {
+        av_frame_free(&s->current_frame);
+        av_frame_free(&s->last_frame);
+        return AVERROR(ENOMEM);
+    }
+
     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
 
     return 0;
@@ -183,11 +191,11 @@ static int roq_decode_frame(AVCodecContext *avctx,
     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)) {
+    if ((ret = ff_reget_buffer(avctx, s->current_frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "  RoQ: get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if(copy)
@@ -197,8 +205,9 @@ static int roq_decode_frame(AVCodecContext *avctx,
     bytestream2_init(&s->gb, buf, buf_size);
     roqvideo_decode_frame(s);
 
+    if ((ret = av_frame_ref(data, s->current_frame)) < 0)
+        return ret;
     *got_frame      = 1;
-    *(AVFrame*)data = *s->current_frame;
 
     /* shuffle frames */
     FFSWAP(AVFrame *, s->current_frame, s->last_frame);
@@ -210,17 +219,15 @@ static av_cold int roq_decode_end(AVCodecContext *avctx)
 {
     RoqContext *s = avctx->priv_data;
 
-    /* release the last frame */
-    if (s->last_frame->data[0])
-        avctx->release_buffer(avctx, s->last_frame);
-    if (s->current_frame->data[0])
-        avctx->release_buffer(avctx, s->current_frame);
+    av_frame_free(&s->current_frame);
+    av_frame_free(&s->last_frame);
 
     return 0;
 }
 
 AVCodec ff_roq_decoder = {
     .name           = "roqvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("id RoQ video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ROQ,
     .priv_data_size = sizeof(RoqContext),
@@ -228,5 +235,4 @@ AVCodec ff_roq_decoder = {
     .close          = roq_decode_end,
     .decode         = roq_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("id RoQ video"),
 };
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index 192f1eb..af0089f 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -56,6 +56,7 @@
 
 #include <string.h>
 
+#include "libavutil/attributes.h"
 #include "roqvideo.h"
 #include "bytestream.h"
 #include "elbg.h"
@@ -936,7 +937,23 @@ static void roq_encode_video(RoqContext *enc)
     enc->framesSinceKeyframe++;
 }
 
-static int roq_encode_init(AVCodecContext *avctx)
+static av_cold int roq_encode_end(AVCodecContext *avctx)
+{
+    RoqContext *enc = avctx->priv_data;
+
+    av_frame_free(&enc->current_frame);
+    av_frame_free(&enc->last_frame);
+
+    av_free(enc->tmpData);
+    av_free(enc->this_motion4);
+    av_free(enc->last_motion4);
+    av_free(enc->this_motion8);
+    av_free(enc->last_motion8);
+
+    return 0;
+}
+
+static av_cold int roq_encode_init(AVCodecContext *avctx)
 {
     RoqContext *enc = avctx->priv_data;
 
@@ -957,8 +974,12 @@ static int roq_encode_init(AVCodecContext *avctx)
     enc->framesSinceKeyframe = 0;
     enc->first_frame = 1;
 
-    enc->last_frame    = &enc->frames[0];
-    enc->current_frame = &enc->frames[1];
+    enc->last_frame    = av_frame_alloc();
+    enc->current_frame = av_frame_alloc();
+    if (!enc->last_frame || !enc->current_frame) {
+        roq_encode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
     enc->tmpData      = av_malloc(sizeof(RoqTempdata));
 
@@ -1033,8 +1054,8 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     if (enc->first_frame) {
         /* Alloc memory for the reconstruction data (we must know the stride
          for that) */
-        if (ff_get_buffer(avctx, enc->current_frame) ||
-            ff_get_buffer(avctx, enc->last_frame)) {
+        if (ff_get_buffer(avctx, enc->current_frame, 0) ||
+            ff_get_buffer(avctx, enc->last_frame, 0)) {
             av_log(avctx, AV_LOG_ERROR, "  RoQ: get_buffer() failed\n");
             return -1;
         }
@@ -1056,24 +1077,9 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
-static int roq_encode_end(AVCodecContext *avctx)
-{
-    RoqContext *enc = avctx->priv_data;
-
-    avctx->release_buffer(avctx, enc->last_frame);
-    avctx->release_buffer(avctx, enc->current_frame);
-
-    av_free(enc->tmpData);
-    av_free(enc->this_motion4);
-    av_free(enc->last_motion4);
-    av_free(enc->this_motion8);
-    av_free(enc->last_motion8);
-
-    return 0;
-}
-
 AVCodec ff_roq_encoder = {
     .name                 = "roqvideo",
+    .long_name            = NULL_IF_CONFIG_SMALL("id RoQ video"),
     .type                 = AVMEDIA_TYPE_VIDEO,
     .id                   = AV_CODEC_ID_ROQ,
     .priv_data_size       = sizeof(RoqContext),
@@ -1083,5 +1089,4 @@ AVCodec ff_roq_encoder = {
     .supported_framerates = (const AVRational[]){ {30,1}, {0,0} },
     .pix_fmts             = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P,
                                                         AV_PIX_FMT_NONE },
-    .long_name            = NULL_IF_CONFIG_SMALL("id RoQ video"),
 };
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 59b15c6..70d145e 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -41,11 +41,12 @@
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct RpzaContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     const unsigned char *buf;
     int size;
@@ -71,7 +72,7 @@ typedef struct RpzaContext {
 static void rpza_decode_stream(RpzaContext *s)
 {
     int width = s->avctx->width;
-    int stride = s->frame.linesize[0] / 2;
+    int stride = s->frame->linesize[0] / 2;
     int row_inc = stride - 4;
     int stream_ptr = 0;
     int chunk_size;
@@ -81,7 +82,7 @@ static void rpza_decode_stream(RpzaContext *s)
     unsigned short color4[4];
     unsigned char index, idx;
     unsigned short ta, tb;
-    unsigned short *pixels = (unsigned short *)s->frame.data[0];
+    unsigned short *pixels = (unsigned short *)s->frame->data[0];
 
     int row_ptr = 0;
     int pixel_ptr = 0;
@@ -238,7 +239,9 @@ static av_cold int rpza_decode_init(AVCodecContext *avctx)
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_RGB555;
 
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -250,21 +253,22 @@ static int rpza_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     RpzaContext *s = avctx->priv_data;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     rpza_decode_stream(s);
 
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -274,14 +278,14 @@ static av_cold int rpza_decode_end(AVCodecContext *avctx)
 {
     RpzaContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_rpza_decoder = {
     .name           = "rpza",
+    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime video (RPZA)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_RPZA,
     .priv_data_size = sizeof(RpzaContext),
@@ -289,5 +293,4 @@ AVCodec ff_rpza_decoder = {
     .close          = rpza_decode_end,
     .decode         = rpza_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime video (RPZA)"),
 };
diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c
index 77baa5b..f5abe63 100644
--- a/libavcodec/rtjpeg.c
+++ b/libavcodec/rtjpeg.c
@@ -20,7 +20,6 @@
  */
 #include "libavutil/common.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "rtjpeg.h"
 
 #define PUT_COEFF(c) \
@@ -44,7 +43,7 @@
  * aligned this could be done faster in a different way, e.g. as it is done
  * in MPlayer libmpcodecs/native/rtjpegn.c.
  */
-static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *scan,
+static inline int get_block(GetBitContext *gb, int16_t *block, const uint8_t *scan,
                             const uint32_t *quant) {
     int coeff, i, n;
     int8_t ac;
@@ -57,11 +56,11 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc
     // number of non-zero coefficients
     coeff = get_bits(gb, 6);
     if (get_bits_left(gb) < (coeff << 1))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     // normally we would only need to clear the (63 - coeff) last values,
     // but since we do not know where they are we just clear the whole block
-    memset(block, 0, 64 * sizeof(DCTELEM));
+    memset(block, 0, 64 * sizeof(int16_t));
 
     // 2 bits per coefficient
     while (coeff) {
@@ -74,7 +73,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc
     // 4 bits per coefficient
     ALIGN(4);
     if (get_bits_left(gb) < (coeff << 2))
-        return -1;
+        return AVERROR_INVALIDDATA;
     while (coeff) {
         ac = get_sbits(gb, 4);
         if (ac == -8)
@@ -85,7 +84,7 @@ static inline int get_block(GetBitContext *gb, DCTELEM *block, const uint8_t *sc
     // 8 bits per coefficient
     ALIGN(8);
     if (get_bits_left(gb) < (coeff << 3))
-        return -1;
+        return AVERROR_INVALIDDATA;
     while (coeff) {
         ac = get_sbits(gb, 8);
         PUT_COEFF(ac);
@@ -124,7 +123,7 @@ int ff_rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,
     if (res > 0) \
         c->dsp->idct_put(dst, stride, block); \
 } while (0)
-            DCTELEM *block = c->block;
+            int16_t *block = c->block;
             BLOCK(c->lquant, y1, f->linesize[0]);
             y1 += 8;
             BLOCK(c->lquant, y1, f->linesize[0]);
diff --git a/libavcodec/rtjpeg.h b/libavcodec/rtjpeg.h
index 9fbfb34..c544b0b 100644
--- a/libavcodec/rtjpeg.h
+++ b/libavcodec/rtjpeg.h
@@ -35,7 +35,7 @@ typedef struct RTJpegContext {
     uint8_t scan[64];
     uint32_t lquant[64];
     uint32_t cquant[64];
-    DECLARE_ALIGNED(16, DCTELEM, block)[64];
+    DECLARE_ALIGNED(16, int16_t, block)[64];
 } RTJpegContext;
 
 void ff_rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp,
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 04518dd..944db58 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -27,13 +27,12 @@
 
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
-#include "dsputil.h"
+#include "error_resilience.h"
+#include "internal.h"
 #include "mpegvideo.h"
 #include "mpeg4video.h"
 #include "h263.h"
 
-//#define DEBUG
-
 #define RV_GET_MAJOR_VER(x)  ((x) >> 28)
 #define RV_GET_MINOR_VER(x) (((x) >> 20) & 0xFF)
 #define RV_GET_MICRO_VER(x) (((x) >> 12) & 0xFF)
@@ -45,148 +44,144 @@ typedef struct RVDecContext {
     int sub_id;
 } RVDecContext;
 
-static const uint16_t rv_lum_code[256] =
-{
- 0x3e7f, 0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06,
- 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e,
- 0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16,
- 0x0f17, 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e,
- 0x0f1f, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26,
- 0x0f27, 0x0f28, 0x0f29, 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e,
- 0x0f2f, 0x0f30, 0x0f31, 0x0f32, 0x0f33, 0x0f34, 0x0f35, 0x0f36,
- 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 0x0f3c, 0x0f3d, 0x0f3e,
- 0x0f3f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386,
- 0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e,
- 0x038f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396,
- 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e,
- 0x039f, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6,
- 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
- 0x00cf, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056,
- 0x0057, 0x0020, 0x0021, 0x0022, 0x0023, 0x000c, 0x000d, 0x0004,
- 0x0000, 0x0005, 0x000e, 0x000f, 0x0024, 0x0025, 0x0026, 0x0027,
- 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
- 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
- 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
- 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
- 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
- 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
- 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 0x0f45, 0x0f46, 0x0f47,
- 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 0x0f4e, 0x0f4f,
- 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 0x0f57,
- 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f,
- 0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67,
- 0x0f68, 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f,
- 0x0f70, 0x0f71, 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77,
- 0x0f78, 0x0f79, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f,
+static const uint16_t rv_lum_code[256] = {
+    0x3e7f, 0x0f00, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05, 0x0f06,
+    0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e,
+    0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16,
+    0x0f17, 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e,
+    0x0f1f, 0x0f20, 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26,
+    0x0f27, 0x0f28, 0x0f29, 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e,
+    0x0f2f, 0x0f30, 0x0f31, 0x0f32, 0x0f33, 0x0f34, 0x0f35, 0x0f36,
+    0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b, 0x0f3c, 0x0f3d, 0x0f3e,
+    0x0f3f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0386,
+    0x0387, 0x0388, 0x0389, 0x038a, 0x038b, 0x038c, 0x038d, 0x038e,
+    0x038f, 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396,
+    0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e,
+    0x039f, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6,
+    0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
+    0x00cf, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056,
+    0x0057, 0x0020, 0x0021, 0x0022, 0x0023, 0x000c, 0x000d, 0x0004,
+    0x0000, 0x0005, 0x000e, 0x000f, 0x0024, 0x0025, 0x0026, 0x0027,
+    0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
+    0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+    0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+    0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+    0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
+    0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+    0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+    0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44, 0x0f45, 0x0f46, 0x0f47,
+    0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d, 0x0f4e, 0x0f4f,
+    0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56, 0x0f57,
+    0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f,
+    0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67,
+    0x0f68, 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f,
+    0x0f70, 0x0f71, 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77,
+    0x0f78, 0x0f79, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f,
 };
 
-static const uint8_t rv_lum_bits[256] =
-{
- 14, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 10,  8,  8,  8,  8,  8,  8,  8,
-  8,  8,  8,  8,  8,  8,  8,  8,
-  8,  7,  7,  7,  7,  7,  7,  7,
-  7,  6,  6,  6,  6,  5,  5,  4,
-  2,  4,  5,  5,  6,  6,  6,  6,
-  7,  7,  7,  7,  7,  7,  7,  7,
-  8,  8,  8,  8,  8,  8,  8,  8,
-  8,  8,  8,  8,  8,  8,  8,  8,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
+static const uint8_t rv_lum_bits[256] = {
+    14, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  7,  7,  7,  7,  7,  7,  7,
+     7,  6,  6,  6,  6,  5,  5,  4,
+     2,  4,  5,  5,  6,  6,  6,  6,
+     7,  7,  7,  7,  7,  7,  7,  7,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
 };
 
-static const uint16_t rv_chrom_code[256] =
-{
- 0xfe7f, 0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f04, 0x3f05, 0x3f06,
- 0x3f07, 0x3f08, 0x3f09, 0x3f0a, 0x3f0b, 0x3f0c, 0x3f0d, 0x3f0e,
- 0x3f0f, 0x3f10, 0x3f11, 0x3f12, 0x3f13, 0x3f14, 0x3f15, 0x3f16,
- 0x3f17, 0x3f18, 0x3f19, 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e,
- 0x3f1f, 0x3f20, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26,
- 0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e,
- 0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36,
- 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e,
- 0x3f3f, 0x0f80, 0x0f81, 0x0f82, 0x0f83, 0x0f84, 0x0f85, 0x0f86,
- 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 0x0f8d, 0x0f8e,
- 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 0x0f96,
- 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e,
- 0x0f9f, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6,
- 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce,
- 0x03cf, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6,
- 0x00e7, 0x0030, 0x0031, 0x0032, 0x0033, 0x0008, 0x0009, 0x0002,
- 0x0000, 0x0003, 0x000a, 0x000b, 0x0034, 0x0035, 0x0036, 0x0037,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
- 0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7,
- 0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df,
- 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7,
- 0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
- 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
- 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
- 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47,
- 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f,
- 0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57,
- 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f,
- 0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67,
- 0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f,
- 0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77,
- 0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f,
+static const uint16_t rv_chrom_code[256] = {
+    0xfe7f, 0x3f00, 0x3f01, 0x3f02, 0x3f03, 0x3f04, 0x3f05, 0x3f06,
+    0x3f07, 0x3f08, 0x3f09, 0x3f0a, 0x3f0b, 0x3f0c, 0x3f0d, 0x3f0e,
+    0x3f0f, 0x3f10, 0x3f11, 0x3f12, 0x3f13, 0x3f14, 0x3f15, 0x3f16,
+    0x3f17, 0x3f18, 0x3f19, 0x3f1a, 0x3f1b, 0x3f1c, 0x3f1d, 0x3f1e,
+    0x3f1f, 0x3f20, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26,
+    0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e,
+    0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36,
+    0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e,
+    0x3f3f, 0x0f80, 0x0f81, 0x0f82, 0x0f83, 0x0f84, 0x0f85, 0x0f86,
+    0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c, 0x0f8d, 0x0f8e,
+    0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95, 0x0f96,
+    0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e,
+    0x0f9f, 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6,
+    0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce,
+    0x03cf, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6,
+    0x00e7, 0x0030, 0x0031, 0x0032, 0x0033, 0x0008, 0x0009, 0x0002,
+    0x0000, 0x0003, 0x000a, 0x000b, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+    0x03d0, 0x03d1, 0x03d2, 0x03d3, 0x03d4, 0x03d5, 0x03d6, 0x03d7,
+    0x03d8, 0x03d9, 0x03da, 0x03db, 0x03dc, 0x03dd, 0x03de, 0x03df,
+    0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7,
+    0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf,
+    0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7,
+    0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf,
+    0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47,
+    0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f,
+    0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57,
+    0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f,
+    0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67,
+    0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f,
+    0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77,
+    0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x3f7f,
 };
 
-static const uint8_t rv_chrom_bits[256] =
-{
- 16, 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, 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, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 10,  8,  8,  8,  8,  8,  8,  8,
-  8,  6,  6,  6,  6,  4,  4,  3,
-  2,  3,  4,  4,  6,  6,  6,  6,
-  8,  8,  8,  8,  8,  8,  8,  8,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 12,
- 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,
- 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,
+static const uint8_t rv_chrom_bits[256] = {
+    16, 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, 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, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10,  8,  8,  8,  8,  8,  8,  8,
+     8,  6,  6,  6,  6,  4,  4,  3,
+     2,  3,  4,  4,  6,  6,  6,  6,
+     8,  8,  8,  8,  8,  8,  8,  8,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 12, 12,
+    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,
+    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,
 };
 
 static VLC rv_dc_lum, rv_dc_chrom;
@@ -252,20 +247,23 @@ static int rv10_decode_picture_header(MpegEncContext *s)
         s->pict_type = AV_PICTURE_TYPE_P;
     else
         s->pict_type = AV_PICTURE_TYPE_I;
-    if(!marker) av_log(s->avctx, AV_LOG_ERROR, "marker missing\n");
+
+    if (!marker)
+        av_log(s->avctx, AV_LOG_ERROR, "marker missing\n");
+
     pb_frame = get_bits1(&s->gb);
 
     av_dlog(s->avctx, "pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame);
 
-    if (pb_frame){
-        av_log(s->avctx, AV_LOG_ERROR, "pb frame not supported\n");
-        return -1;
+    if (pb_frame) {
+        avpriv_request_sample(s->avctx, "pb frame");
+        return AVERROR_PATCHWELCOME;
     }
 
     s->qscale = get_bits(&s->gb, 5);
-    if(s->qscale==0){
-        av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n");
-        return -1;
+    if (s->qscale == 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid qscale value: 0\n");
+        return AVERROR_INVALIDDATA;
     }
 
     if (s->pict_type == AV_PICTURE_TYPE_I) {
@@ -281,14 +279,14 @@ static int rv10_decode_picture_header(MpegEncContext *s)
     /* if multiple packets per frame are sent, the position at which
        to display the macroblocks is coded here */
 
-    mb_xy= s->mb_x + s->mb_y*s->mb_width;
-    if(show_bits(&s->gb, 12)==0 || (mb_xy && mb_xy < s->mb_num)){
-        s->mb_x = get_bits(&s->gb, 6); /* mb_x */
-        s->mb_y = get_bits(&s->gb, 6); /* mb_y */
+    mb_xy = s->mb_x + s->mb_y * s->mb_width;
+    if (show_bits(&s->gb, 12) == 0 || (mb_xy && mb_xy < s->mb_num)) {
+        s->mb_x  = get_bits(&s->gb, 6); /* mb_x */
+        s->mb_y  = get_bits(&s->gb, 6); /* mb_y */
         mb_count = get_bits(&s->gb, 12);
     } else {
-        s->mb_x = 0;
-        s->mb_y = 0;
+        s->mb_x  = 0;
+        s->mb_y  = 0;
         mb_count = s->mb_width * s->mb_height;
     }
     skip_bits(&s->gb, 3);   /* ignored */
@@ -301,76 +299,79 @@ static int rv10_decode_picture_header(MpegEncContext *s)
 static int rv20_decode_picture_header(RVDecContext *rv)
 {
     MpegEncContext *s = &rv->m;
-    int seq, mb_pos, i;
+    int seq, mb_pos, i, ret;
     int rpr_bits;
 
-    i= get_bits(&s->gb, 2);
-    switch(i){
-    case 0: s->pict_type= AV_PICTURE_TYPE_I; break;
-    case 1: s->pict_type= AV_PICTURE_TYPE_I; break; //hmm ...
-    case 2: s->pict_type= AV_PICTURE_TYPE_P; break;
-    case 3: s->pict_type= AV_PICTURE_TYPE_B; break;
+    i = get_bits(&s->gb, 2);
+    switch (i) {
+    case 0: s->pict_type = AV_PICTURE_TYPE_I; break;
+    case 1: s->pict_type = AV_PICTURE_TYPE_I; break; //hmm ...
+    case 2: s->pict_type = AV_PICTURE_TYPE_P; break;
+    case 3: s->pict_type = AV_PICTURE_TYPE_B; break;
     default:
         av_log(s->avctx, AV_LOG_ERROR, "unknown frame type\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(s->last_picture_ptr==NULL && s->pict_type==AV_PICTURE_TYPE_B){
-        av_log(s->avctx, AV_LOG_ERROR, "early B pix\n");
-        return -1;
+    if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B) {
+        av_log(s->avctx, AV_LOG_ERROR, "early B-frame\n");
+        return AVERROR_INVALIDDATA;
     }
 
-    if (get_bits1(&s->gb)){
+    if (get_bits1(&s->gb)) {
         av_log(s->avctx, AV_LOG_ERROR, "reserved bit set\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     s->qscale = get_bits(&s->gb, 5);
-    if(s->qscale==0){
-        av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n");
-        return -1;
+    if (s->qscale == 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid qscale value: 0\n");
+        return AVERROR_INVALIDDATA;
     }
 
-    if(RV_GET_MINOR_VER(rv->sub_id) >= 2)
+    if (RV_GET_MINOR_VER(rv->sub_id) >= 2)
         s->loop_filter = get_bits1(&s->gb);
 
-    if(RV_GET_MINOR_VER(rv->sub_id) <= 1)
+    if (RV_GET_MINOR_VER(rv->sub_id) <= 1)
         seq = get_bits(&s->gb, 8) << 7;
     else
         seq = get_bits(&s->gb, 13) << 2;
 
     rpr_bits = s->avctx->extradata[1] & 7;
-    if(rpr_bits){
+    if (rpr_bits) {
         int f, new_w, new_h;
         rpr_bits = FFMIN((rpr_bits >> 1) + 1, 3);
 
         f = get_bits(&s->gb, rpr_bits);
 
-        if(f){
+        if (f) {
             if (s->avctx->extradata_size < 8 + 2 * f) {
                 av_log(s->avctx, AV_LOG_ERROR, "Extradata too small.\n");
                 return AVERROR_INVALIDDATA;
             }
 
-            new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f];
-            new_h= 4*((uint8_t*)s->avctx->extradata)[7+2*f];
-        }else{
-            new_w= s->orig_width ;
-            new_h= s->orig_height;
+            new_w = 4 * ((uint8_t*)s->avctx->extradata)[6 + 2 * f];
+            new_h = 4 * ((uint8_t*)s->avctx->extradata)[7 + 2 * f];
+        } else {
+            new_w = s->orig_width ;
+            new_h = s->orig_height;
         }
-        if(new_w != s->width || new_h != s->height){
-            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;
+        if (new_w != s->width || new_h != s->height) {
+            av_log(s->avctx, AV_LOG_DEBUG,
+                   "attempting to change resolution to %dx%d\n", new_w, new_h);
             ff_MPV_common_end(s);
-            avcodec_set_dimensions(s->avctx, new_w, new_h);
+
+            ret = ff_set_dimensions(s->avctx, new_w, new_h);
+            if (ret < 0)
+                return ret;
+
             s->width  = new_w;
             s->height = new_h;
-            if (ff_MPV_common_init(s) < 0)
-                return -1;
+            if ((ret = ff_MPV_common_init(s)) < 0)
+                return ret;
         }
 
-        if(s->avctx->debug & FF_DEBUG_PICT_INFO){
+        if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
             av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, rpr_bits);
         }
     } else if (av_image_check_size(s->width, s->height, 0, s->avctx) < 0)
@@ -378,42 +379,44 @@ static int rv20_decode_picture_header(RVDecContext *rv)
 
     mb_pos = ff_h263_decode_mba(s);
 
-    seq |= s->time &~0x7FFF;
-    if(seq - s->time >  0x4000) seq -= 0x8000;
-    if(seq - s->time < -0x4000) seq += 0x8000;
-    if(seq != s->time){
-        if(s->pict_type!=AV_PICTURE_TYPE_B){
-            s->time= seq;
-            s->pp_time= s->time - s->last_non_b_time;
-            s->last_non_b_time= s->time;
-        }else{
-            s->time= seq;
-            s->pb_time= s->pp_time - (s->last_non_b_time - s->time);
-            if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){
-                av_log(s->avctx, AV_LOG_DEBUG, "messed up order, possible from seeking? skipping current b frame\n");
+    seq |= s->time & ~0x7FFF;
+    if (seq - s->time >  0x4000)
+        seq -= 0x8000;
+    if (seq - s->time < -0x4000)
+        seq += 0x8000;
+
+    if (seq != s->time) {
+        if (s->pict_type != AV_PICTURE_TYPE_B) {
+            s->time            = seq;
+            s->pp_time         = s->time - s->last_non_b_time;
+            s->last_non_b_time = s->time;
+        } else {
+            s->time    = seq;
+            s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
+            if (s->pp_time <= s->pb_time ||
+                s->pp_time <= s->pp_time - s->pb_time || s->pp_time <= 0) {
+                av_log(s->avctx, AV_LOG_DEBUG, "messed up order, possible "
+                       "from seeking? skipping current b frame\n");
                 return FRAME_SKIPPED;
             }
             ff_mpeg4_init_direct_mv(s);
         }
     }
 
-    s->no_rounding= get_bits1(&s->gb);
+    s->no_rounding = get_bits1(&s->gb);
 
-    if(RV_GET_MINOR_VER(rv->sub_id) <= 1 && s->pict_type == AV_PICTURE_TYPE_B)
+    if (RV_GET_MINOR_VER(rv->sub_id) <= 1 && s->pict_type == AV_PICTURE_TYPE_B)
         skip_bits(&s->gb, 5); // binary decoder reads 3+2 bits here but they don't seem to be used
 
-    s->f_code = 1;
+    s->f_code          = 1;
     s->unrestricted_mv = 1;
-    s->h263_aic= s->pict_type == AV_PICTURE_TYPE_I;
-//    s->alt_inter_vlc=1;
-//    s->obmc=1;
-//    s->umvplus=1;
-    s->modified_quant=1;
-    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);
+    s->h263_aic        = s->pict_type == AV_PICTURE_TYPE_I;
+    s->modified_quant  = 1;
+    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);
@@ -425,12 +428,12 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
 {
     RVDecContext  *rv = avctx->priv_data;
     MpegEncContext *s = &rv->m;
-    static int done=0;
+    static int done = 0;
     int major_ver, minor_ver, micro_ver, ret;
 
     if (avctx->extradata_size < 8) {
         av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if ((ret = av_image_check_size(avctx->coded_width,
                                    avctx->coded_height, 0, avctx)) < 0)
@@ -438,16 +441,16 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
 
     ff_MPV_decode_defaults(s);
 
-    s->avctx= avctx;
+    s->avctx      = avctx;
     s->out_format = FMT_H263;
-    s->codec_id= avctx->codec_id;
+    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;
+    s->orig_width  = s->width  = avctx->coded_width;
+    s->orig_height = s->height = avctx->coded_height;
 
-    s->h263_long_vectors= ((uint8_t*)avctx->extradata)[3] & 1;
-    rv->sub_id = AV_RB32((uint8_t*)avctx->extradata + 4);
+    s->h263_long_vectors = ((uint8_t*)avctx->extradata)[3] & 1;
+    rv->sub_id           = AV_RB32((uint8_t*)avctx->extradata + 4);
 
     major_ver = RV_GET_MAJOR_VER(rv->sub_id);
     minor_ver = RV_GET_MINOR_VER(rv->sub_id);
@@ -457,39 +460,41 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx)
     switch (major_ver) {
     case 1:
         s->rv10_version = micro_ver ? 3 : 1;
-        s->obmc = micro_ver == 2;
+        s->obmc         = micro_ver == 2;
         break;
     case 2:
         if (minor_ver >= 2) {
-            s->low_delay = 0;
+            s->low_delay           = 0;
             s->avctx->has_b_frames = 1;
         }
         break;
     default:
         av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", rv->sub_id);
-        av_log_missing_feature(avctx, "RV1/2 version", 1);
+        avpriv_request_sample(avctx, "RV1/2 version");
         return AVERROR_PATCHWELCOME;
     }
 
-    if(avctx->debug & FF_DEBUG_PICT_INFO){
-        av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id, avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1);
+    if (avctx->debug & FF_DEBUG_PICT_INFO) {
+        av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id,
+               avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1);
     }
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    if (ff_MPV_common_init(s) < 0)
-        return -1;
+    if ((ret = ff_MPV_common_init(s)) < 0)
+        return ret;
 
-    ff_h263_decode_init_vlc(s);
+    ff_h263dsp_init(&s->h263dsp);
+    ff_h263_decode_init_vlc();
 
     /* init rv vlc */
     if (!done) {
         INIT_VLC_STATIC(&rv_dc_lum, DC_VLC_BITS, 256,
-                 rv_lum_bits, 1, 1,
-                 rv_lum_code, 2, 2, 16384);
+                        rv_lum_bits, 1, 1,
+                        rv_lum_code, 2, 2, 16384);
         INIT_VLC_STATIC(&rv_dc_chrom, DC_VLC_BITS, 256,
-                 rv_chrom_bits, 1, 1,
-                 rv_chrom_code, 2, 2, 16388);
+                        rv_chrom_bits, 1, 1,
+                        rv_chrom_code, 2, 2, 16388);
         done = 1;
     }
 
@@ -505,95 +510,94 @@ static av_cold int rv10_decode_end(AVCodecContext *avctx)
 }
 
 static int rv10_decode_packet(AVCodecContext *avctx,
-                             const uint8_t *buf, int buf_size, int buf_size2)
+                              const uint8_t *buf, int buf_size, int buf_size2)
 {
     RVDecContext  *rv = avctx->priv_data;
     MpegEncContext *s = &rv->m;
-    int mb_count, mb_pos, left, start_mb_x, active_bits_size;
+    int mb_count, mb_pos, left, start_mb_x, active_bits_size, ret;
 
     active_bits_size = buf_size * 8;
     init_get_bits(&s->gb, buf, FFMAX(buf_size, buf_size2) * 8);
-    if(s->codec_id ==AV_CODEC_ID_RV10)
+    if (s->codec_id == AV_CODEC_ID_RV10)
         mb_count = rv10_decode_picture_header(s);
     else
         mb_count = rv20_decode_picture_header(rv);
     if (mb_count < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (s->mb_x >= s->mb_width ||
         s->mb_y >= s->mb_height) {
         av_log(s->avctx, AV_LOG_ERROR, "POS ERROR %d %d\n", s->mb_x, s->mb_y);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     mb_pos = s->mb_y * s->mb_width + s->mb_x;
     left = s->mb_width * s->mb_height - mb_pos;
     if (mb_count > left) {
         av_log(s->avctx, AV_LOG_ERROR, "COUNT ERROR\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
-        if(s->current_picture_ptr){ //FIXME write parser so we always have complete frames?
-            ff_er_frame_end(s);
+    if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr == NULL) {
+        if (s->current_picture_ptr) { // FIXME write parser so we always have complete frames?
+            ff_er_frame_end(&s->er);
             ff_MPV_frame_end(s);
-            s->mb_x= s->mb_y = s->resync_mb_x = s->resync_mb_y= 0;
+            s->mb_x = s->mb_y = s->resync_mb_x = s->resync_mb_y = 0;
         }
-        if(ff_MPV_frame_start(s, avctx) < 0)
-            return -1;
-        ff_er_frame_start(s);
+        if ((ret = ff_MPV_frame_start(s, avctx)) < 0)
+            return ret;
+        ff_mpeg_er_frame_start(s);
     } else {
         if (s->current_picture_ptr->f.pict_type != s->pict_type) {
             av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
     av_dlog(avctx, "qscale=%d\n", s->qscale);
 
     /* default quantization values */
-    if(s->codec_id== AV_CODEC_ID_RV10){
-        if(s->mb_y==0) s->first_slice_line=1;
-    }else{
-        s->first_slice_line=1;
-        s->resync_mb_x= s->mb_x;
+    if (s->codec_id == AV_CODEC_ID_RV10) {
+        if (s->mb_y == 0)
+            s->first_slice_line = 1;
+    } else {
+        s->first_slice_line = 1;
+        s->resync_mb_x      = s->mb_x;
     }
-    start_mb_x= s->mb_x;
-    s->resync_mb_y= s->mb_y;
-    if(s->h263_aic){
-        s->y_dc_scale_table=
-        s->c_dc_scale_table= ff_aic_dc_scale_table;
-    }else{
-        s->y_dc_scale_table=
-        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
+    start_mb_x     = s->mb_x;
+    s->resync_mb_y = s->mb_y;
+    if (s->h263_aic) {
+        s->y_dc_scale_table = s->c_dc_scale_table = ff_aic_dc_scale_table;
+    } else {
+        s->y_dc_scale_table = s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
     }
 
-    if(s->modified_quant)
-        s->chroma_qscale_table= ff_h263_chroma_qscale_table;
+    if (s->modified_quant)
+        s->chroma_qscale_table = ff_h263_chroma_qscale_table;
 
     ff_set_qscale(s, s->qscale);
 
     s->rv10_first_dc_coded[0] = 0;
     s->rv10_first_dc_coded[1] = 0;
     s->rv10_first_dc_coded[2] = 0;
-    s->block_wrap[0]=
-    s->block_wrap[1]=
-    s->block_wrap[2]=
-    s->block_wrap[3]= s->b8_stride;
-    s->block_wrap[4]=
-    s->block_wrap[5]= s->mb_stride;
+    s->block_wrap[0] =
+    s->block_wrap[1] =
+    s->block_wrap[2] =
+    s->block_wrap[3] = s->b8_stride;
+    s->block_wrap[4] =
+    s->block_wrap[5] = s->mb_stride;
     ff_init_block_index(s);
-    /* decode each macroblock */
 
-    for(s->mb_num_left= mb_count; s->mb_num_left>0; s->mb_num_left--) {
+    /* decode each macroblock */
+    for (s->mb_num_left = mb_count; s->mb_num_left > 0; s->mb_num_left--) {
         int ret;
         ff_update_block_index(s);
         av_dlog(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y);
 
-        s->mv_dir = MV_DIR_FORWARD;
+        s->mv_dir  = MV_DIR_FORWARD;
         s->mv_type = MV_TYPE_16X16;
-        ret=ff_h263_decode_mb(s, s->block);
+        ret = ff_h263_decode_mb(s, s->block);
 
         // Repeat the slice end check from ff_h263_decode_mb with our active
         // bitstream size
@@ -611,17 +615,17 @@ static int rv10_decode_packet(AVCodecContext *avctx,
             active_bits_size = buf_size2 * 8;
             av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n",
                    8 * buf_size, active_bits_size);
-            ret= SLICE_OK;
+            ret = SLICE_OK;
         }
 
         if (ret == SLICE_ERROR || active_bits_size < get_bits_count(&s->gb)) {
             av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
-        if(s->pict_type != AV_PICTURE_TYPE_B)
+        if (s->pict_type != AV_PICTURE_TYPE_B)
             ff_h263_update_motion_val(s);
         ff_MPV_decode_mb(s, s->block);
-        if(s->loop_filter)
+        if (s->loop_filter)
             ff_h263_loop_filter(s);
 
         if (++s->mb_x == s->mb_width) {
@@ -629,20 +633,24 @@ static int rv10_decode_packet(AVCodecContext *avctx,
             s->mb_y++;
             ff_init_block_index(s);
         }
-        if(s->mb_x == s->resync_mb_x)
-            s->first_slice_line=0;
-        if(ret == SLICE_END) break;
+        if (s->mb_x == s->resync_mb_x)
+            s->first_slice_line = 0;
+        if (ret == SLICE_END)
+            break;
     }
 
-    ff_er_add_slice(s, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+    ff_er_add_slice(&s->er, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y,
+                    ER_MB_END);
 
     return active_bits_size;
 }
 
 static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
 {
-    if(avctx->slice_count) return avctx->slice_offset[n];
-    else                   return AV_RL32(buf + n*8);
+    if (avctx->slice_count)
+        return avctx->slice_offset[n];
+    else
+        return AV_RL32(buf + n * 8);
 }
 
 static int rv10_decode_frame(AVCodecContext *avctx,
@@ -650,10 +658,10 @@ static int rv10_decode_frame(AVCodecContext *avctx,
                              AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    MpegEncContext *s = avctx->priv_data;
-    int i;
-    AVFrame *pict = data;
+    int buf_size       = avpkt->size;
+    MpegEncContext *s  = avctx->priv_data;
+    AVFrame *pict      = data;
+    int i, ret;
     int slice_count;
     const uint8_t *slices_hdr = NULL;
 
@@ -664,57 +672,66 @@ static int rv10_decode_frame(AVCodecContext *avctx,
         return 0;
     }
 
-    if(!avctx->slice_count){
+    if (!avctx->slice_count) {
         slice_count = (*buf++) + 1;
         buf_size--;
-        slices_hdr = buf + 4;
-        buf += 8 * slice_count;
-        buf_size -= 8 * slice_count;
-        if (buf_size <= 0)
+
+        if (!slice_count || buf_size <= 8 * slice_count) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid slice count: %d.\n", slice_count);
             return AVERROR_INVALIDDATA;
-    }else
+        }
+
+        slices_hdr = buf + 4;
+        buf       += 8 * slice_count;
+        buf_size  -= 8 * slice_count;
+    } else
         slice_count = avctx->slice_count;
 
-    for(i=0; i<slice_count; i++){
+    for (i = 0; i < slice_count; i++) {
         unsigned offset = get_slice_offset(avctx, slices_hdr, i);
         int size, size2;
 
         if (offset >= buf_size)
             return AVERROR_INVALIDDATA;
 
-        if(i+1 == slice_count)
-            size= buf_size - offset;
+        if (i + 1 == slice_count)
+            size = buf_size - offset;
         else
-            size= get_slice_offset(avctx, slices_hdr, i+1) - offset;
+            size = get_slice_offset(avctx, slices_hdr, i + 1) - offset;
 
-        if(i+2 >= slice_count)
-            size2= buf_size - offset;
+        if (i + 2 >= slice_count)
+            size2 = buf_size - offset;
         else
-            size2= get_slice_offset(avctx, slices_hdr, i+2) - offset;
+            size2 = get_slice_offset(avctx, slices_hdr, i + 2) - offset;
 
         if (size <= 0 || size2 <= 0 ||
             offset + FFMAX(size, size2) > buf_size)
             return AVERROR_INVALIDDATA;
 
-        if(rv10_decode_packet(avctx, buf+offset, size, size2) > 8*size)
+        if (rv10_decode_packet(avctx, buf + offset, size, size2) > 8 * size)
             i++;
     }
 
-    if(s->current_picture_ptr != NULL && s->mb_y>=s->mb_height){
-        ff_er_frame_end(s);
+    if (s->current_picture_ptr != NULL && s->mb_y >= s->mb_height) {
+        ff_er_frame_end(&s->er);
         ff_MPV_frame_end(s);
 
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            *pict = s->current_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+                return ret;
+            ff_print_debug_info(s, s->current_picture_ptr);
         } else if (s->last_picture_ptr != NULL) {
-            *pict = s->last_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+                return ret;
+            ff_print_debug_info(s, s->last_picture_ptr);
         }
 
-        if(s->last_picture_ptr || s->low_delay){
+        if (s->last_picture_ptr || s->low_delay) {
             *got_frame = 1;
-            ff_print_debug_info(s, pict);
         }
-        s->current_picture_ptr= NULL; // so we can detect if frame_end was not called (find some nicer solution...)
+
+        // so we can detect if frame_end was not called (find some nicer solution...)
+        s->current_picture_ptr = NULL;
     }
 
     return avpkt->size;
@@ -722,6 +739,7 @@ static int rv10_decode_frame(AVCodecContext *avctx,
 
 AVCodec ff_rv10_decoder = {
     .name           = "rv10",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_RV10,
     .priv_data_size = sizeof(RVDecContext),
@@ -729,12 +747,12 @@ AVCodec ff_rv10_decoder = {
     .close          = rv10_decode_end,
     .decode         = rv10_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
 
 AVCodec ff_rv20_decoder = {
     .name           = "rv20",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_RV20,
     .priv_data_size = sizeof(RVDecContext),
@@ -743,6 +761,5 @@ AVCodec ff_rv20_decoder = {
     .decode         = rv10_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
     .flush          = ff_mpeg_flush,
-    .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..9b23d7d 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -60,6 +60,7 @@ FF_MPV_GENERIC_CLASS(rv10)
 
 AVCodec ff_rv10_encoder = {
     .name           = "rv10",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_RV10,
     .priv_data_size = sizeof(MpegEncContext),
@@ -67,6 +68,5 @@ AVCodec ff_rv10_encoder = {
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
     .priv_class     = &rv10_class,
 };
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index c392b53..67879e2 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -61,6 +61,7 @@ FF_MPV_GENERIC_CLASS(rv20)
 
 AVCodec ff_rv20_encoder = {
     .name           = "rv20",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_RV20,
     .priv_data_size = sizeof(MpegEncContext),
@@ -68,6 +69,5 @@ AVCodec ff_rv20_encoder = {
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
     .priv_class     = &rv20_class,
 };
diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index b61b75d..ffb433b 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -25,7 +25,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "golomb.h"
 
@@ -120,7 +119,7 @@ static int rv30_decode_mb_info(RV34DecContext *r)
 static inline void rv30_weak_loop_filter(uint8_t *src, const int step,
                                          const int stride, const int lim)
 {
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     int i, diff;
 
     for(i = 0; i < 4; i++){
@@ -142,7 +141,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
 
     mb_pos = row * s->mb_stride;
     for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
-        int mbtype = s->current_picture_ptr->f.mb_type[mb_pos];
+        int mbtype = s->current_picture_ptr->mb_type[mb_pos];
         if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))
             r->deblock_coefs[mb_pos] = 0xFFFF;
         if(IS_INTRA(mbtype))
@@ -154,9 +153,9 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
      */
     mb_pos = row * s->mb_stride;
     for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
-        cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]];
+        cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]];
         if(mb_x)
-            left_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - 1]];
+            left_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - 1]];
         for(j = 0; j < 16; j += 4){
             Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x;
             for(i = !mb_x; i < 4; i++, Y += 4){
@@ -196,9 +195,9 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
     }
     mb_pos = row * s->mb_stride;
     for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
-        cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]];
+        cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]];
         if(row)
-            top_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - s->mb_stride]];
+            top_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride]];
         for(j = 4*!row; j < 16; j += 4){
             Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize;
             for(i = 0; i < 4; i++, Y += 4){
@@ -271,6 +270,7 @@ static av_cold int rv30_decode_init(AVCodecContext *avctx)
 
 AVCodec ff_rv30_decoder = {
     .name                  = "rv30",
+    .long_name             = NULL_IF_CONFIG_SMALL("RealVideo 3.0"),
     .type                  = AVMEDIA_TYPE_VIDEO,
     .id                    = AV_CODEC_ID_RV30,
     .priv_data_size        = sizeof(RV34DecContext),
@@ -280,7 +280,6 @@ AVCodec ff_rv30_decoder = {
     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_DELAY |
                              CODEC_CAP_FRAME_THREADS,
     .flush                 = ff_mpeg_flush,
-    .long_name             = NULL_IF_CONFIG_SMALL("RealVideo 3.0"),
     .pix_fmts              = ff_pixfmt_list_420,
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context),
diff --git a/libavcodec/rv30dsp.c b/libavcodec/rv30dsp.c
index bcd1a46..d4b122e 100644
--- a/libavcodec/rv30dsp.c
+++ b/libavcodec/rv30dsp.c
@@ -25,13 +25,14 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "h264chroma.h"
+#include "h264qpel.h"
 #include "rv34dsp.h"
 
 #define RV30_LOWPASS(OPNAME, OP) \
 static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\
     const int h = 8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     for(i = 0; i < h; i++)\
     {\
@@ -50,7 +51,7 @@ static av_unused void OPNAME ## rv30_tpel8_h_lowpass(uint8_t *dst, uint8_t *src,
 \
 static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, const int C1, const int C2){\
     const int w = 8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     for(i = 0; i < w; i++)\
     {\
@@ -81,7 +82,7 @@ static void OPNAME ## rv30_tpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstSt
 static void OPNAME ## rv30_tpel8_hv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
     const int w = 8;\
     const int h = 8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i, j;\
     for(j = 0; j < h; j++){\
         for(i = 0; i < w; i++){\
@@ -100,7 +101,7 @@ static void OPNAME ## rv30_tpel8_hv_lowpass(uint8_t *dst, uint8_t *src, int dstS
 static void OPNAME ## rv30_tpel8_hhv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
     const int w = 8;\
     const int h = 8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i, j;\
     for(j = 0; j < h; j++){\
         for(i = 0; i < w; i++){\
@@ -119,7 +120,7 @@ static void OPNAME ## rv30_tpel8_hhv_lowpass(uint8_t *dst, uint8_t *src, int dst
 static void OPNAME ## rv30_tpel8_hvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
     const int w = 8;\
     const int h = 8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i, j;\
     for(j = 0; j < h; j++){\
         for(i = 0; i < w; i++){\
@@ -138,7 +139,7 @@ static void OPNAME ## rv30_tpel8_hvv_lowpass(uint8_t *dst, uint8_t *src, int dst
 static void OPNAME ## rv30_tpel8_hhvv_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
     const int w = 8;\
     const int h = 8;\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i, j;\
     for(j = 0; j < h; j++){\
         for(i = 0; i < w; i++){\
@@ -209,35 +210,43 @@ static void OPNAME ## rv30_tpel16_hhvv_lowpass(uint8_t *dst, uint8_t *src, int d
 \
 
 #define RV30_MC(OPNAME, SIZE) \
-static void OPNAME ## rv30_tpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv30_tpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 12, 6);\
 }\
 \
-static void OPNAME ## rv30_tpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv30_tpel ## SIZE ## _mc20_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv30_tpel ## SIZE ## _h_lowpass(dst, src, stride, stride, 6, 12);\
 }\
 \
-static void OPNAME ## rv30_tpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv30_tpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 12, 6);\
 }\
 \
-static void OPNAME ## rv30_tpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv30_tpel ## SIZE ## _mc02_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv30_tpel ## SIZE ## _v_lowpass(dst, src, stride, stride, 6, 12);\
 }\
 \
-static void OPNAME ## rv30_tpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv30_tpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv30_tpel ## SIZE ## _hv_lowpass(dst, src, stride, stride);\
 }\
 \
-static void OPNAME ## rv30_tpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv30_tpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv30_tpel ## SIZE ## _hvv_lowpass(dst, src, stride, stride);\
 }\
 \
-static void OPNAME ## rv30_tpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv30_tpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv30_tpel ## SIZE ## _hhv_lowpass(dst, src, stride, stride);\
 }\
 \
-static void OPNAME ## rv30_tpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv30_tpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv30_tpel ## SIZE ## _hhvv_lowpass(dst, src, stride, stride);\
 }\
 \
@@ -252,11 +261,16 @@ RV30_MC(put_, 16)
 RV30_MC(avg_, 8)
 RV30_MC(avg_, 16)
 
-av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+av_cold void ff_rv30dsp_init(RV34DSPContext *c)
+{
+    H264ChromaContext h264chroma;
+    H264QpelContext qpel;
 
-    ff_rv34dsp_init(c, dsp);
+    ff_rv34dsp_init(c);
+    ff_h264chroma_init(&h264chroma, 8);
+    ff_h264qpel_init(&qpel, 8);
 
-    c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0];
+    c->put_pixels_tab[0][ 0] = qpel.put_h264_qpel_pixels_tab[0][0];
     c->put_pixels_tab[0][ 1] = put_rv30_tpel16_mc10_c;
     c->put_pixels_tab[0][ 2] = put_rv30_tpel16_mc20_c;
     c->put_pixels_tab[0][ 4] = put_rv30_tpel16_mc01_c;
@@ -265,7 +279,7 @@ av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->put_pixels_tab[0][ 8] = put_rv30_tpel16_mc02_c;
     c->put_pixels_tab[0][ 9] = put_rv30_tpel16_mc12_c;
     c->put_pixels_tab[0][10] = put_rv30_tpel16_mc22_c;
-    c->avg_pixels_tab[0][ 0] = dsp->avg_h264_qpel_pixels_tab[0][0];
+    c->avg_pixels_tab[0][ 0] = qpel.avg_h264_qpel_pixels_tab[0][0];
     c->avg_pixels_tab[0][ 1] = avg_rv30_tpel16_mc10_c;
     c->avg_pixels_tab[0][ 2] = avg_rv30_tpel16_mc20_c;
     c->avg_pixels_tab[0][ 4] = avg_rv30_tpel16_mc01_c;
@@ -274,7 +288,7 @@ av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->avg_pixels_tab[0][ 8] = avg_rv30_tpel16_mc02_c;
     c->avg_pixels_tab[0][ 9] = avg_rv30_tpel16_mc12_c;
     c->avg_pixels_tab[0][10] = avg_rv30_tpel16_mc22_c;
-    c->put_pixels_tab[1][ 0] = dsp->put_h264_qpel_pixels_tab[1][0];
+    c->put_pixels_tab[1][ 0] = qpel.put_h264_qpel_pixels_tab[1][0];
     c->put_pixels_tab[1][ 1] = put_rv30_tpel8_mc10_c;
     c->put_pixels_tab[1][ 2] = put_rv30_tpel8_mc20_c;
     c->put_pixels_tab[1][ 4] = put_rv30_tpel8_mc01_c;
@@ -283,7 +297,7 @@ av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->put_pixels_tab[1][ 8] = put_rv30_tpel8_mc02_c;
     c->put_pixels_tab[1][ 9] = put_rv30_tpel8_mc12_c;
     c->put_pixels_tab[1][10] = put_rv30_tpel8_mc22_c;
-    c->avg_pixels_tab[1][ 0] = dsp->avg_h264_qpel_pixels_tab[1][0];
+    c->avg_pixels_tab[1][ 0] = qpel.avg_h264_qpel_pixels_tab[1][0];
     c->avg_pixels_tab[1][ 1] = avg_rv30_tpel8_mc10_c;
     c->avg_pixels_tab[1][ 2] = avg_rv30_tpel8_mc20_c;
     c->avg_pixels_tab[1][ 4] = avg_rv30_tpel8_mc01_c;
@@ -293,8 +307,8 @@ av_cold void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->avg_pixels_tab[1][ 9] = avg_rv30_tpel8_mc12_c;
     c->avg_pixels_tab[1][10] = avg_rv30_tpel8_mc22_c;
 
-    c->put_chroma_pixels_tab[0] = dsp->put_h264_chroma_pixels_tab[0];
-    c->put_chroma_pixels_tab[1] = dsp->put_h264_chroma_pixels_tab[1];
-    c->avg_chroma_pixels_tab[0] = dsp->avg_h264_chroma_pixels_tab[0];
-    c->avg_chroma_pixels_tab[1] = dsp->avg_h264_chroma_pixels_tab[1];
+    c->put_chroma_pixels_tab[0] = h264chroma.put_h264_chroma_pixels_tab[0];
+    c->put_chroma_pixels_tab[1] = h264chroma.put_h264_chroma_pixels_tab[1];
+    c->avg_chroma_pixels_tab[0] = h264chroma.avg_h264_chroma_pixels_tab[0];
+    c->avg_chroma_pixels_tab[1] = h264chroma.avg_h264_chroma_pixels_tab[1];
 }
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index 3106bfb..c02ea74 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -27,7 +27,7 @@
 #include "libavutil/internal.h"
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "error_resilience.h"
 #include "mpegvideo.h"
 #include "golomb.h"
 #include "internal.h"
@@ -39,8 +39,6 @@
 #include "rv34data.h"
 #include "rv34.h"
 
-//#define DEBUG
-
 static inline void ZERO8x2(void* dst, int stride)
 {
     fill_rectangle(dst,                 1, 2, stride, 0, 4);
@@ -216,7 +214,7 @@ static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
 /**
  * Get one coefficient value from the bistream and store it.
  */
-static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
+static inline void decode_coeff(int16_t *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
 {
     if(coef){
         if(coef == esc){
@@ -236,7 +234,7 @@ static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *
 /**
  * Decode 2x2 subblock of coefficients.
  */
-static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
+static inline void decode_subblock(int16_t *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
 {
     int flags = modulo_three_table[code];
 
@@ -254,13 +252,13 @@ static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2,
 /**
  * Decode a single coefficient.
  */
-static inline void decode_subblock1(DCTELEM *dst, int code, GetBitContext *gb, VLC *vlc, int q)
+static inline void decode_subblock1(int16_t *dst, int code, GetBitContext *gb, VLC *vlc, int q)
 {
     int coeff = modulo_three_table[code] >> 6;
     decode_coeff(dst, coeff, 3, gb, vlc, q);
 }
 
-static inline void decode_subblock3(DCTELEM *dst, int code, GetBitContext *gb, VLC *vlc,
+static inline void decode_subblock3(int16_t *dst, int code, GetBitContext *gb, VLC *vlc,
                                     int q_dc, int q_ac1, int q_ac2)
 {
     int flags = modulo_three_table[code];
@@ -282,7 +280,7 @@ static inline void decode_subblock3(DCTELEM *dst, int code, GetBitContext *gb, V
  *  o--o
  */
 
-static int rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
+static int rv34_decode_block(int16_t *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
 {
     int code, pattern, has_ac = 1;
 
@@ -357,7 +355,7 @@ static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types)
 
     r->is16 = get_bits1(gb);
     if(r->is16){
-        s->current_picture_ptr->f.mb_type[mb_pos] = MB_TYPE_INTRA16x16;
+        s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA16x16;
         r->block_type = RV34_MB_TYPE_INTRA16x16;
         t = get_bits(gb, 2);
         fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
@@ -367,7 +365,7 @@ static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types)
             if(!get_bits1(gb))
                 av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
         }
-        s->current_picture_ptr->f.mb_type[mb_pos] = MB_TYPE_INTRA;
+        s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA;
         r->block_type = RV34_MB_TYPE_INTRA;
         if(r->decode_intra_types(r, gb, intra_types) < 0)
             return -1;
@@ -393,7 +391,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
     r->block_type = r->decode_mb_info(r);
     if(r->block_type == -1)
         return -1;
-    s->current_picture_ptr->f.mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
+    s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
     r->mb_type[mb_pos] = r->block_type;
     if(r->block_type == RV34_MB_SKIP){
         if(s->pict_type == AV_PICTURE_TYPE_P)
@@ -401,7 +399,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
         if(s->pict_type == AV_PICTURE_TYPE_B)
             r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
     }
-    r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->f.mb_type[mb_pos]);
+    r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]);
     rv34_decode_mv(r, r->block_type);
     if(r->block_type == RV34_MB_SKIP){
         fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
@@ -410,7 +408,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
     r->chroma_vlc = 1;
     r->luma_vlc   = 0;
 
-    if(IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
+    if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
         if(r->is16){
             t = get_bits(gb, 2);
             fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
@@ -475,27 +473,27 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int
         c_off = -1;
 
     if(avail[-1]){
-        A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][0];
-        A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][1];
+        A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
+        A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
     }
     if(avail[-4]){
-        B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][0];
-        B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][1];
+        B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
+        B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
     }else{
         B[0] = A[0];
         B[1] = A[1];
     }
     if(!avail[c_off-4]){
         if(avail[-4] && (avail[-1] || r->rv30)){
-            C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][0];
-            C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][1];
+            C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
+            C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
         }else{
             C[0] = A[0];
             C[1] = A[1];
         }
     }else{
-        C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][0];
-        C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][1];
+        C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0];
+        C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1];
     }
     mx = mid_pred(A[0], B[0], C[0]);
     my = mid_pred(A[1], B[1], C[1]);
@@ -503,8 +501,8 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int
     my += r->dmv[dmv_no][1];
     for(j = 0; j < part_sizes_h[block_type]; j++){
         for(i = 0; i < part_sizes_w[block_type]; i++){
-            s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
-            s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
+            s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
+            s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
         }
     }
 }
@@ -555,25 +553,25 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
     int i, j;
     Picture *cur_pic = s->current_picture_ptr;
     const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
-    int type = cur_pic->f.mb_type[mb_pos];
+    int type = cur_pic->mb_type[mb_pos];
 
     if((r->avail_cache[6-1] & type) & mask){
-        A[0] = cur_pic->f.motion_val[dir][mv_pos - 1][0];
-        A[1] = cur_pic->f.motion_val[dir][mv_pos - 1][1];
+        A[0] = cur_pic->motion_val[dir][mv_pos - 1][0];
+        A[1] = cur_pic->motion_val[dir][mv_pos - 1][1];
         has_A = 1;
     }
     if((r->avail_cache[6-4] & type) & mask){
-        B[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][0];
-        B[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][1];
+        B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0];
+        B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1];
         has_B = 1;
     }
     if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
-        C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][0];
-        C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][1];
+        C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0];
+        C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1];
         has_C = 1;
     }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
-        C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][0];
-        C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][1];
+        C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0];
+        C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1];
         has_C = 1;
     }
 
@@ -584,12 +582,12 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
 
     for(j = 0; j < 2; j++){
         for(i = 0; i < 2; i++){
-            cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
-            cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
+            cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
+            cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
         }
     }
     if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
-        ZERO8x2(cur_pic->f.motion_val[!dir][mv_pos], s->b8_stride);
+        ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride);
     }
 }
 
@@ -606,27 +604,27 @@ static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
     int* avail = r->avail_cache + avail_indexes[0];
 
     if(avail[-1]){
-        A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][0];
-        A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][1];
+        A[0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0];
+        A[1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1];
     }
     if(avail[-4]){
-        B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][0];
-        B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][1];
+        B[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0];
+        B[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1];
     }else{
         B[0] = A[0];
         B[1] = A[1];
     }
     if(!avail[-4 + 2]){
         if(avail[-4] && (avail[-1])){
-            C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][0];
-            C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][1];
+            C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][0];
+            C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][1];
         }else{
             C[0] = A[0];
             C[1] = A[1];
         }
     }else{
-        C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][0];
-        C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][1];
+        C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][0];
+        C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][1];
     }
     mx = mid_pred(A[0], B[0], C[0]);
     my = mid_pred(A[1], B[1], C[1]);
@@ -635,8 +633,8 @@ static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
     for(j = 0; j < 2; j++){
         for(i = 0; i < 2; i++){
             for(k = 0; k < 2; k++){
-                s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
-                s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
+                s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
+                s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
             }
         }
     }
@@ -674,24 +672,24 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
 
     if(thirdpel){
         int chroma_mx, chroma_my;
-        mx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
-        my = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
-        lx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
-        ly = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
-        chroma_mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
-        chroma_my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
+        mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
+        my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
+        lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
+        ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
+        chroma_mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
+        chroma_my = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
         umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
         umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
         uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
         uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
     }else{
         int cx, cy;
-        mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] >> 2;
-        my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] >> 2;
-        lx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] & 3;
-        ly = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] & 3;
-        cx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
-        cy = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
+        mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2;
+        my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2;
+        lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3;
+        ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3;
+        cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
+        cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
         umx = cx >> 2;
         umy = cy >> 2;
         uvmx = (cx & 3) << 1;
@@ -704,7 +702,7 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
     if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
         /* wait for the referenced mb row to be finished */
         int mb_row = s->mb_y + ((yoff + my + 5 + 8 * height) >> 4);
-        AVFrame *f = dir ? &s->next_picture_ptr->f : &s->last_picture_ptr->f;
+        ThreadFrame *f = dir ? &s->next_picture_ptr->tf : &s->last_picture_ptr->tf;
         ff_thread_await_progress(f, mb_row, 0);
     }
 
@@ -725,12 +723,18 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
         uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;
 
         srcY -= 2 + 2*s->linesize;
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+                                 s->linesize, s->linesize,
+                                 (width << 3) + 6, (height << 3) + 6,
                             src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos);
         srcY = s->edge_emu_buffer + 2 + 2*s->linesize;
-        s->vdsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
+        s->vdsp.emulated_edge_mc(uvbuf, srcU,
+                                 s->uvlinesize,s->uvlinesize,
+                                 (width << 2) + 1, (height << 2) + 1,
                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
-        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, (width<<2)+1, (height<<2)+1,
+        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
+                                 s->uvlinesize, s->uvlinesize,
+                                 (width << 2) + 1, (height << 2) + 1,
                             uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
         srcU = uvbuf;
         srcV = uvbuf + 16;
@@ -853,11 +857,11 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
     switch(block_type){
     case RV34_MB_TYPE_INTRA:
     case RV34_MB_TYPE_INTRA16x16:
-        ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+        ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
         return 0;
     case RV34_MB_SKIP:
         if(s->pict_type == AV_PICTURE_TYPE_P){
-            ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+            ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
             rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
             break;
         }
@@ -865,23 +869,23 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
         //surprisingly, it uses motion scheme from next reference frame
         /* wait for the current mb row to be finished */
         if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
-            ff_thread_await_progress(&s->next_picture_ptr->f, FFMAX(0, s->mb_y-1), 0);
+            ff_thread_await_progress(&s->next_picture_ptr->tf, FFMAX(0, s->mb_y-1), 0);
 
-        next_bt = s->next_picture_ptr->f.mb_type[s->mb_x + s->mb_y * s->mb_stride];
+        next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride];
         if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
-            ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
-            ZERO8x2(s->current_picture_ptr->f.motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+            ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+            ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
         }else
             for(j = 0; j < 2; j++)
                 for(i = 0; i < 2; i++)
                     for(k = 0; k < 2; k++)
                         for(l = 0; l < 2; l++)
-                            s->current_picture_ptr->f.motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][k]);
+                            s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]);
         if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC
             rv34_mc_2mv(r, block_type);
         else
             rv34_mc_2mv_skip(r);
-        ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+        ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
         break;
     case RV34_MB_P_16x16:
     case RV34_MB_P_MIX16x16:
@@ -994,7 +998,7 @@ static inline void rv34_process_block(RV34DecContext *r,
                                       int fc, int sc, int q_dc, int q_ac)
 {
     MpegEncContext *s = &r->s;
-    DCTELEM *ptr = s->block[0];
+    int16_t *ptr = s->block[0];
     int has_ac = rv34_decode_block(ptr, &s->gb, r->cur_vlcs,
                                    fc, sc, q_dc, q_ac, q_ac);
     if(has_ac){
@@ -1007,13 +1011,13 @@ static inline void rv34_process_block(RV34DecContext *r,
 
 static void rv34_output_i16x16(RV34DecContext *r, int8_t *intra_types, int cbp)
 {
-    LOCAL_ALIGNED_16(DCTELEM, block16, [16]);
+    LOCAL_ALIGNED_16(int16_t, block16, [16]);
     MpegEncContext *s    = &r->s;
     GetBitContext  *gb   = &s->gb;
     int             q_dc = rv34_qscale_tab[ r->luma_dc_quant_i[s->qscale] ],
                     q_ac = rv34_qscale_tab[s->qscale];
     uint8_t        *dst  = s->dest[0];
-    DCTELEM        *ptr  = s->block[0];
+    int16_t        *ptr  = s->block[0];
     int i, j, itype, has_ac;
 
     memset(block16, 0, 16 * sizeof(*block16));
@@ -1149,7 +1153,7 @@ static int rv34_set_deblock_coef(RV34DecContext *r)
     MpegEncContext *s = &r->s;
     int hmvmask = 0, vmvmask = 0, i, j;
     int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
-    int16_t (*motion_val)[2] = &s->current_picture_ptr->f.motion_val[0][midx];
+    int16_t (*motion_val)[2] = &s->current_picture_ptr->motion_val[0][midx];
     for(j = 0; j < 16; j += 8){
         for(i = 0; i < 2; i++){
             if(is_mv_diff_gt_3(motion_val + i, 1))
@@ -1179,7 +1183,7 @@ static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
     MpegEncContext *s   = &r->s;
     GetBitContext  *gb  = &s->gb;
     uint8_t        *dst = s->dest[0];
-    DCTELEM        *ptr = s->block[0];
+    int16_t        *ptr = s->block[0];
     int          mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp, cbp2;
     int q_dc, q_ac, has_ac;
@@ -1192,26 +1196,26 @@ static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
     dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
     if(s->mb_x && dist)
         r->avail_cache[5] =
-        r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1];
+        r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
     if(dist >= s->mb_width)
         r->avail_cache[2] =
-        r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride];
+        r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
     if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
-        r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1];
+        r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
     if(s->mb_x && dist > s->mb_width)
-        r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
+        r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
 
     s->qscale = r->si.quant;
     cbp = cbp2 = rv34_decode_inter_mb_header(r, intra_types);
     r->cbp_luma  [mb_pos] = cbp;
     r->cbp_chroma[mb_pos] = cbp >> 16;
     r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
-    s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
+    s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
 
     if(cbp == -1)
         return -1;
 
-    if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
+    if (IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
         if(r->is16) rv34_output_i16x16(r, intra_types, cbp);
         else        rv34_output_intra(r, intra_types, cbp);
         return 0;
@@ -1219,7 +1223,7 @@ static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
 
     if(r->is16){
         // Only for RV34_MB_P_MIX16x16
-        LOCAL_ALIGNED_16(DCTELEM, block16, [16]);
+        LOCAL_ALIGNED_16(int16_t, block16, [16]);
         memset(block16, 0, 16 * sizeof(*block16));
         q_dc = rv34_qscale_tab[ r->luma_dc_quant_p[s->qscale] ];
         q_ac = rv34_qscale_tab[s->qscale];
@@ -1294,21 +1298,21 @@ static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
     dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
     if(s->mb_x && dist)
         r->avail_cache[5] =
-        r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1];
+        r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
     if(dist >= s->mb_width)
         r->avail_cache[2] =
-        r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride];
+        r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
     if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
-        r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1];
+        r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
     if(s->mb_x && dist > s->mb_width)
-        r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
+        r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
 
     s->qscale = r->si.quant;
     cbp = rv34_decode_intra_mb_header(r, intra_types);
     r->cbp_luma  [mb_pos] = cbp;
     r->cbp_chroma[mb_pos] = cbp >> 16;
     r->deblock_coefs[mb_pos] = 0xFFFF;
-    s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
+    s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
 
     if(cbp == -1)
         return -1;
@@ -1429,7 +1433,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
         else
             res = rv34_decode_intra_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
         if(res < 0){
-            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
+            ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
             return -1;
         }
         if (++s->mb_x == s->mb_width) {
@@ -1444,7 +1448,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
                 r->loop_filter(r, s->mb_y - 2);
 
             if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
-                ff_thread_report_progress(&s->current_picture_ptr->f,
+                ff_thread_report_progress(&s->current_picture_ptr->tf,
                                           s->mb_y - 2, 0);
 
         }
@@ -1452,7 +1456,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
             s->first_slice_line=0;
         s->mb_num_left--;
     }
-    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+    ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
 
     return s->mb_y == s->mb_height;
 }
@@ -1490,19 +1494,23 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
 
 #if CONFIG_RV30_DECODER
     if (avctx->codec_id == AV_CODEC_ID_RV30)
-        ff_rv30dsp_init(&r->rdsp, &r->s.dsp);
+        ff_rv30dsp_init(&r->rdsp);
 #endif
 #if CONFIG_RV40_DECODER
     if (avctx->codec_id == AV_CODEC_ID_RV40)
-        ff_rv40dsp_init(&r->rdsp, &r->s.dsp);
+        ff_rv40dsp_init(&r->rdsp);
 #endif
 
-    if ((ret = rv34_decoder_alloc(r)) < 0)
+    if ((ret = rv34_decoder_alloc(r)) < 0) {
+        ff_MPV_common_end(&r->s);
         return ret;
+    }
 
     if(!intra_vlcs[0].cbppattern[0].bits)
         rv34_init_tables();
 
+    avctx->internal->allocate_progress = 1;
+
     return 0;
 }
 
@@ -1517,9 +1525,12 @@ int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx)
         r->tmp_b_block_base = NULL;
         if ((err = ff_MPV_common_init(&r->s)) < 0)
             return err;
-        if ((err = rv34_decoder_alloc(r)) < 0)
+        if ((err = rv34_decoder_alloc(r)) < 0) {
+            ff_MPV_common_end(&r->s);
             return err;
+        }
     }
+
     return 0;
 }
 
@@ -1563,24 +1574,26 @@ static int finish_frame(AVCodecContext *avctx, AVFrame *pict)
 {
     RV34DecContext *r = avctx->priv_data;
     MpegEncContext *s = &r->s;
-    int got_picture = 0;
+    int got_picture = 0, ret;
 
-    ff_er_frame_end(s);
+    ff_er_frame_end(&s->er);
     ff_MPV_frame_end(s);
     s->mb_num_left = 0;
 
     if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
+        ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
 
     if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-        *pict = s->current_picture_ptr->f;
+        if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+            return ret;
+        ff_print_debug_info(s, s->current_picture_ptr);
         got_picture = 1;
     } else if (s->last_picture_ptr != NULL) {
-        *pict = s->last_picture_ptr->f;
+        if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+            return ret;
+        ff_print_debug_info(s, s->last_picture_ptr);
         got_picture = 1;
     }
-    if (got_picture)
-        ff_print_debug_info(s, pict);
 
     return got_picture;
 }
@@ -1595,7 +1608,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
     MpegEncContext *s = &r->s;
     AVFrame *pict = data;
     SliceInfo si;
-    int i;
+    int i, ret;
     int slice_count;
     const uint8_t *slices_hdr = NULL;
     int last = 0;
@@ -1604,7 +1617,8 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
     if (buf_size == 0) {
         /* special case for last picture */
         if (s->low_delay==0 && s->next_picture_ptr) {
-            *pict = s->next_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
+                return ret;
             s->next_picture_ptr = NULL;
 
             *got_picture_ptr = 1;
@@ -1647,7 +1661,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
         if (s->mb_num_left > 0) {
             av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.",
                    s->mb_num_left);
-            ff_er_frame_end(s);
+            ff_er_frame_end(&s->er);
             ff_MPV_frame_end(s);
         }
 
@@ -1659,7 +1673,11 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
 
             s->width  = si.width;
             s->height = si.height;
-            avcodec_set_dimensions(s->avctx, s->width, s->height);
+
+            err = ff_set_dimensions(s->avctx, s->width, s->height);
+            if (err < 0)
+                return err;
+
             if ((err = ff_MPV_common_frame_size_change(s)) < 0)
                 return err;
             if ((err = rv34_decoder_realloc(r)) < 0)
@@ -1668,7 +1686,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
         s->pict_type = si.type ? si.type : AV_PICTURE_TYPE_I;
         if (ff_MPV_frame_start(s, s->avctx) < 0)
             return -1;
-        ff_er_frame_start(s);
+        ff_mpeg_er_frame_start(s);
         if (!r->tmp_b_block_base) {
             int i;
 
@@ -1761,16 +1779,19 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
             if(r->loop_filter)
                 r->loop_filter(r, s->mb_height - 1);
 
-            *got_picture_ptr = finish_frame(avctx, pict);
+            ret = finish_frame(avctx, pict);
+            if (ret < 0)
+                return ret;
+            *got_picture_ptr = ret;
         } else if (HAVE_THREADS &&
                    (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
             av_log(avctx, AV_LOG_INFO, "marking unfished frame as finished\n");
             /* always mark the current frame as finished, frame-mt supports
              * only complete frames */
-            ff_er_frame_end(s);
+            ff_er_frame_end(&s->er);
             ff_MPV_frame_end(s);
             s->mb_num_left = 0;
-            ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
+            ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
             return AVERROR_INVALIDDATA;
         }
     }
diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h
index f40e282..c32c089 100644
--- a/libavcodec/rv34.h
+++ b/libavcodec/rv34.h
@@ -28,7 +28,6 @@
 #define AVCODEC_RV34_H
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 
 #include "h264pred.h"
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 @@ static int rv34_parse(AVCodecParserContext *s,
     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 @@ AVCodecParser ff_rv30_parser = {
 };
 #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/rv34dsp.c b/libavcodec/rv34dsp.c
index 86a2ffd..7234ee8 100644
--- a/libavcodec/rv34dsp.c
+++ b/libavcodec/rv34dsp.c
@@ -24,7 +24,7 @@
  * @file
  * RV30/40 decoder common dsp functions
  */
-#include "dsputil.h"
+
 #include "rv34dsp.h"
 #include "libavutil/common.h"
 
@@ -33,7 +33,7 @@
  * @{
  */
 
-static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
+static av_always_inline void rv34_row_transform(int temp[16], int16_t *block)
 {
     int i;
 
@@ -54,12 +54,12 @@ static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block)
  * Real Video 3.0/4.0 inverse transform + sample reconstruction
  * Code is almost the same as in SVQ3, only scaling is different.
  */
-static void rv34_idct_add_c(uint8_t *dst, ptrdiff_t stride, DCTELEM *block){
+static void rv34_idct_add_c(uint8_t *dst, ptrdiff_t stride, int16_t *block){
     int      temp[16];
     int      i;
 
     rv34_row_transform(temp, block);
-    memset(block, 0, 16*sizeof(DCTELEM));
+    memset(block, 0, 16*sizeof(int16_t));
 
     for(i = 0; i < 4; i++){
         const int z0 = 13*(temp[4*0+i] +    temp[4*2+i]) + 0x200;
@@ -82,7 +82,7 @@ static void rv34_idct_add_c(uint8_t *dst, ptrdiff_t stride, DCTELEM *block){
  * Code is almost the same as rv34_inv_transform()
  * but final coefficients are multiplied by 1.5 and have no rounding.
  */
-static void rv34_inv_transform_noround_c(DCTELEM *block){
+static void rv34_inv_transform_noround_c(int16_t *block){
     int temp[16];
     int i;
 
@@ -115,9 +115,9 @@ static void rv34_idct_dc_add_c(uint8_t *dst, ptrdiff_t stride, int dc)
     }
 }
 
-static void rv34_inv_transform_dc_noround_c(DCTELEM *block)
+static void rv34_inv_transform_dc_noround_c(int16_t *block)
 {
-    DCTELEM dc = (13 * 13 * 3 * block[0]) >> 11;
+    int16_t dc = (13 * 13 * 3 * block[0]) >> 11;
     int i, j;
 
     for (i = 0; i < 4; i++, block += 4)
@@ -128,7 +128,8 @@ static void rv34_inv_transform_dc_noround_c(DCTELEM *block)
 /** @} */ // transform
 
 
-av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+av_cold void ff_rv34dsp_init(RV34DSPContext *c)
+{
     c->rv34_inv_transform    = rv34_inv_transform_noround_c;
     c->rv34_inv_transform_dc = rv34_inv_transform_dc_noround_c;
 
@@ -136,7 +137,7 @@ av_cold void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->rv34_idct_dc_add = rv34_idct_dc_add_c;
 
     if (ARCH_ARM)
-        ff_rv34dsp_init_arm(c, dsp);
+        ff_rv34dsp_init_arm(c);
     if (ARCH_X86)
-        ff_rv34dsp_init_x86(c, dsp);
+        ff_rv34dsp_init_x86(c);
 }
diff --git a/libavcodec/rv34dsp.h b/libavcodec/rv34dsp.h
index f0263b1..c5d4e39 100644
--- a/libavcodec/rv34dsp.h
+++ b/libavcodec/rv34dsp.h
@@ -28,15 +28,16 @@
 #define AVCODEC_RV34DSP_H
 
 #include "dsputil.h"
+#include "h264chroma.h"
 
 typedef void (*rv40_weight_func)(uint8_t *dst/*align width (8 or 16)*/,
                                  uint8_t *src1/*align width (8 or 16)*/,
                                  uint8_t *src2/*align width (8 or 16)*/,
                                  int w1, int w2, ptrdiff_t stride);
 
-typedef void (*rv34_inv_transform_func)(DCTELEM *block);
+typedef void (*rv34_inv_transform_func)(int16_t *block);
 
-typedef void (*rv34_idct_add_func)(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
+typedef void (*rv34_idct_add_func)(uint8_t *dst, ptrdiff_t stride, int16_t *block);
 typedef void (*rv34_idct_dc_add_func)(uint8_t *dst, ptrdiff_t stride,
                                       int   dc);
 
@@ -73,14 +74,14 @@ typedef struct RV34DSPContext {
     rv40_loop_filter_strength_func rv40_loop_filter_strength[2];
 } RV34DSPContext;
 
-void ff_rv30dsp_init(RV34DSPContext *c, DSPContext* dsp);
-void ff_rv34dsp_init(RV34DSPContext *c, DSPContext* dsp);
-void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp);
+void ff_rv30dsp_init(RV34DSPContext *c);
+void ff_rv34dsp_init(RV34DSPContext *c);
+void ff_rv40dsp_init(RV34DSPContext *c);
 
-void ff_rv34dsp_init_arm(RV34DSPContext *c, DSPContext *dsp);
-void ff_rv34dsp_init_x86(RV34DSPContext *c, DSPContext *dsp);
+void ff_rv34dsp_init_arm(RV34DSPContext *c);
+void ff_rv34dsp_init_x86(RV34DSPContext *c);
 
-void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp);
-void ff_rv40dsp_init_arm(RV34DSPContext *c, DSPContext *dsp);
+void ff_rv40dsp_init_x86(RV34DSPContext *c);
+void ff_rv40dsp_init_arm(RV34DSPContext *c);
 
 #endif /* AVCODEC_RV34DSP_H */
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index d317d07..def3990 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -27,7 +27,6 @@
 #include "libavutil/imgutils.h"
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "golomb.h"
 
@@ -364,7 +363,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
 
     mb_pos = row * s->mb_stride;
     for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
-        int mbtype = s->current_picture_ptr->f.mb_type[mb_pos];
+        int mbtype = s->current_picture_ptr->mb_type[mb_pos];
         if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))
             r->cbp_luma  [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF;
         if(IS_INTRA(mbtype))
@@ -379,7 +378,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
         unsigned y_to_deblock;
         int c_to_deblock[2];
 
-        q = s->current_picture_ptr->f.qscale_table[mb_pos];
+        q = s->current_picture_ptr->qscale_table[mb_pos];
         alpha = rv40_alpha_tab[q];
         beta  = rv40_beta_tab [q];
         betaY = betaC = beta * 3;
@@ -394,7 +393,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
             if(avail[i]){
                 int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride;
                 mvmasks[i] = r->deblock_coefs[pos];
-                mbtype [i] = s->current_picture_ptr->f.mb_type[pos];
+                mbtype [i] = s->current_picture_ptr->mb_type[pos];
                 cbp    [i] = r->cbp_luma[pos];
                 uvcbp[i][0] = r->cbp_chroma[pos] & 0xF;
                 uvcbp[i][1] = r->cbp_chroma[pos] >> 4;
@@ -563,6 +562,7 @@ static av_cold int rv40_decode_init(AVCodecContext *avctx)
 
 AVCodec ff_rv40_decoder = {
     .name                  = "rv40",
+    .long_name             = NULL_IF_CONFIG_SMALL("RealVideo 4.0"),
     .type                  = AVMEDIA_TYPE_VIDEO,
     .id                    = AV_CODEC_ID_RV40,
     .priv_data_size        = sizeof(RV34DecContext),
@@ -572,7 +572,6 @@ AVCodec ff_rv40_decoder = {
     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_DELAY |
                              CODEC_CAP_FRAME_THREADS,
     .flush                 = ff_mpeg_flush,
-    .long_name             = NULL_IF_CONFIG_SMALL("RealVideo 4.0"),
     .pix_fmts              = ff_pixfmt_list_420,
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context),
diff --git a/libavcodec/rv40dsp.c b/libavcodec/rv40dsp.c
index c6968d9..a7af1d6 100644
--- a/libavcodec/rv40dsp.c
+++ b/libavcodec/rv40dsp.c
@@ -25,14 +25,14 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "h264qpel.h"
 #include "rv34dsp.h"
 #include "libavutil/common.h"
 
 #define RV40_LOWPASS(OPNAME, OP) \
 static av_unused void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\
                                                      const int h, const int C1, const int C2, const int SHIFT){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     for(i = 0; i < h; i++)\
     {\
@@ -51,7 +51,7 @@ static av_unused void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, uint8_t *src,
 \
 static void OPNAME ## rv40_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,\
                                            const int w, const int C1, const int C2, const int SHIFT){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
     int i;\
     for(i = 0; i < w; i++)\
     {\
@@ -103,72 +103,84 @@ static void OPNAME ## rv40_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstS
 \
 
 #define RV40_MC(OPNAME, SIZE) \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc10_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc30_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc30_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc01_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc11_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[SIZE*(SIZE+5)];\
     uint8_t * const full_mid = full + SIZE*2;\
     put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc21_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[SIZE*(SIZE+5)];\
     uint8_t * const full_mid = full + SIZE*2;\
     put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc31_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc31_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[SIZE*(SIZE+5)];\
     uint8_t * const full_mid = full + SIZE*2;\
     put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc12_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[SIZE*(SIZE+5)];\
     uint8_t * const full_mid = full + SIZE*2;\
     put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc22_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[SIZE*(SIZE+5)];\
     uint8_t * const full_mid = full + SIZE*2;\
     put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc32_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc32_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[SIZE*(SIZE+5)];\
     uint8_t * const full_mid = full + SIZE*2;\
     put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc03_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc03_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc13_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc13_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[SIZE*(SIZE+5)];\
     uint8_t * const full_mid = full + SIZE*2;\
     put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
     OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\
 }\
 \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc23_c(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc23_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     uint8_t full[SIZE*(SIZE+5)];\
     uint8_t * const full_mid = full + SIZE*2;\
     put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
@@ -338,7 +350,7 @@ static av_always_inline void rv40_weak_loop_filter(uint8_t *src,
                                                    const int lim_q1,
                                                    const int lim_p1)
 {
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     int i, t, u, diff;
 
     for (i = 0; i < 4; i++, src += stride) {
@@ -517,19 +529,22 @@ static int rv40_v_loop_filter_strength(uint8_t *src, ptrdiff_t stride,
     return rv40_loop_filter_strength(src, 1, stride, beta, beta2, edge, p1, q1);
 }
 
-av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) {
+av_cold void ff_rv40dsp_init(RV34DSPContext *c)
+{
+    H264QpelContext qpel;
 
-    ff_rv34dsp_init(c, dsp);
+    ff_rv34dsp_init(c);
+    ff_h264qpel_init(&qpel, 8);
 
-    c->put_pixels_tab[0][ 0] = dsp->put_h264_qpel_pixels_tab[0][0];
+    c->put_pixels_tab[0][ 0] = qpel.put_h264_qpel_pixels_tab[0][0];
     c->put_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c;
-    c->put_pixels_tab[0][ 2] = dsp->put_h264_qpel_pixels_tab[0][2];
+    c->put_pixels_tab[0][ 2] = qpel.put_h264_qpel_pixels_tab[0][2];
     c->put_pixels_tab[0][ 3] = put_rv40_qpel16_mc30_c;
     c->put_pixels_tab[0][ 4] = put_rv40_qpel16_mc01_c;
     c->put_pixels_tab[0][ 5] = put_rv40_qpel16_mc11_c;
     c->put_pixels_tab[0][ 6] = put_rv40_qpel16_mc21_c;
     c->put_pixels_tab[0][ 7] = put_rv40_qpel16_mc31_c;
-    c->put_pixels_tab[0][ 8] = dsp->put_h264_qpel_pixels_tab[0][8];
+    c->put_pixels_tab[0][ 8] = qpel.put_h264_qpel_pixels_tab[0][8];
     c->put_pixels_tab[0][ 9] = put_rv40_qpel16_mc12_c;
     c->put_pixels_tab[0][10] = put_rv40_qpel16_mc22_c;
     c->put_pixels_tab[0][11] = put_rv40_qpel16_mc32_c;
@@ -537,15 +552,15 @@ av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->put_pixels_tab[0][13] = put_rv40_qpel16_mc13_c;
     c->put_pixels_tab[0][14] = put_rv40_qpel16_mc23_c;
     c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_c;
-    c->avg_pixels_tab[0][ 0] = dsp->avg_h264_qpel_pixels_tab[0][0];
+    c->avg_pixels_tab[0][ 0] = qpel.avg_h264_qpel_pixels_tab[0][0];
     c->avg_pixels_tab[0][ 1] = avg_rv40_qpel16_mc10_c;
-    c->avg_pixels_tab[0][ 2] = dsp->avg_h264_qpel_pixels_tab[0][2];
+    c->avg_pixels_tab[0][ 2] = qpel.avg_h264_qpel_pixels_tab[0][2];
     c->avg_pixels_tab[0][ 3] = avg_rv40_qpel16_mc30_c;
     c->avg_pixels_tab[0][ 4] = avg_rv40_qpel16_mc01_c;
     c->avg_pixels_tab[0][ 5] = avg_rv40_qpel16_mc11_c;
     c->avg_pixels_tab[0][ 6] = avg_rv40_qpel16_mc21_c;
     c->avg_pixels_tab[0][ 7] = avg_rv40_qpel16_mc31_c;
-    c->avg_pixels_tab[0][ 8] = dsp->avg_h264_qpel_pixels_tab[0][8];
+    c->avg_pixels_tab[0][ 8] = qpel.avg_h264_qpel_pixels_tab[0][8];
     c->avg_pixels_tab[0][ 9] = avg_rv40_qpel16_mc12_c;
     c->avg_pixels_tab[0][10] = avg_rv40_qpel16_mc22_c;
     c->avg_pixels_tab[0][11] = avg_rv40_qpel16_mc32_c;
@@ -553,15 +568,15 @@ av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->avg_pixels_tab[0][13] = avg_rv40_qpel16_mc13_c;
     c->avg_pixels_tab[0][14] = avg_rv40_qpel16_mc23_c;
     c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_c;
-    c->put_pixels_tab[1][ 0] = dsp->put_h264_qpel_pixels_tab[1][0];
+    c->put_pixels_tab[1][ 0] = qpel.put_h264_qpel_pixels_tab[1][0];
     c->put_pixels_tab[1][ 1] = put_rv40_qpel8_mc10_c;
-    c->put_pixels_tab[1][ 2] = dsp->put_h264_qpel_pixels_tab[1][2];
+    c->put_pixels_tab[1][ 2] = qpel.put_h264_qpel_pixels_tab[1][2];
     c->put_pixels_tab[1][ 3] = put_rv40_qpel8_mc30_c;
     c->put_pixels_tab[1][ 4] = put_rv40_qpel8_mc01_c;
     c->put_pixels_tab[1][ 5] = put_rv40_qpel8_mc11_c;
     c->put_pixels_tab[1][ 6] = put_rv40_qpel8_mc21_c;
     c->put_pixels_tab[1][ 7] = put_rv40_qpel8_mc31_c;
-    c->put_pixels_tab[1][ 8] = dsp->put_h264_qpel_pixels_tab[1][8];
+    c->put_pixels_tab[1][ 8] = qpel.put_h264_qpel_pixels_tab[1][8];
     c->put_pixels_tab[1][ 9] = put_rv40_qpel8_mc12_c;
     c->put_pixels_tab[1][10] = put_rv40_qpel8_mc22_c;
     c->put_pixels_tab[1][11] = put_rv40_qpel8_mc32_c;
@@ -569,15 +584,15 @@ av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->put_pixels_tab[1][13] = put_rv40_qpel8_mc13_c;
     c->put_pixels_tab[1][14] = put_rv40_qpel8_mc23_c;
     c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_c;
-    c->avg_pixels_tab[1][ 0] = dsp->avg_h264_qpel_pixels_tab[1][0];
+    c->avg_pixels_tab[1][ 0] = qpel.avg_h264_qpel_pixels_tab[1][0];
     c->avg_pixels_tab[1][ 1] = avg_rv40_qpel8_mc10_c;
-    c->avg_pixels_tab[1][ 2] = dsp->avg_h264_qpel_pixels_tab[1][2];
+    c->avg_pixels_tab[1][ 2] = qpel.avg_h264_qpel_pixels_tab[1][2];
     c->avg_pixels_tab[1][ 3] = avg_rv40_qpel8_mc30_c;
     c->avg_pixels_tab[1][ 4] = avg_rv40_qpel8_mc01_c;
     c->avg_pixels_tab[1][ 5] = avg_rv40_qpel8_mc11_c;
     c->avg_pixels_tab[1][ 6] = avg_rv40_qpel8_mc21_c;
     c->avg_pixels_tab[1][ 7] = avg_rv40_qpel8_mc31_c;
-    c->avg_pixels_tab[1][ 8] = dsp->avg_h264_qpel_pixels_tab[1][8];
+    c->avg_pixels_tab[1][ 8] = qpel.avg_h264_qpel_pixels_tab[1][8];
     c->avg_pixels_tab[1][ 9] = avg_rv40_qpel8_mc12_c;
     c->avg_pixels_tab[1][10] = avg_rv40_qpel8_mc22_c;
     c->avg_pixels_tab[1][11] = avg_rv40_qpel8_mc32_c;
@@ -603,8 +618,8 @@ av_cold void ff_rv40dsp_init(RV34DSPContext *c, DSPContext* dsp) {
     c->rv40_loop_filter_strength[0] = rv40_h_loop_filter_strength;
     c->rv40_loop_filter_strength[1] = rv40_v_loop_filter_strength;
 
-    if (ARCH_X86)
-        ff_rv40dsp_init_x86(c, dsp);
     if (ARCH_ARM)
-        ff_rv40dsp_init_arm(c, dsp);
+        ff_rv40dsp_init_arm(c);
+    if (ARCH_X86)
+        ff_rv40dsp_init_x86(c);
 }
diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
index 76fab59..36384fb 100644
--- a/libavcodec/s302m.c
+++ b/libavcodec/s302m.c
@@ -28,10 +28,6 @@
 
 #define AES3_HEADER_LEN 4
 
-typedef struct S302MDecodeContext {
-    AVFrame frame;
-} S302MDecodeContext;
-
 static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
                                     int buf_size)
 {
@@ -82,7 +78,7 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
 static int s302m_decode_frame(AVCodecContext *avctx, void *data,
                               int *got_frame_ptr, AVPacket *avpkt)
 {
-    S302MDecodeContext *s = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     int block_size, ret;
@@ -96,16 +92,16 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     block_size = (avctx->bits_per_coded_sample + 4) / 4;
-    s->frame.nb_samples = 2 * (buf_size / block_size) / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = 2 * (buf_size / block_size) / avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    buf_size = (s->frame.nb_samples * avctx->channels / 2) * block_size;
+    buf_size = (frame->nb_samples * avctx->channels / 2) * block_size;
 
     if (avctx->bits_per_coded_sample == 24) {
-        uint32_t *o = (uint32_t *)s->frame.data[0];
+        uint32_t *o = (uint32_t *)frame->data[0];
         for (; buf_size > 6; buf_size -= 7) {
             *o++ = (ff_reverse[buf[2]]        << 24) |
                    (ff_reverse[buf[1]]        << 16) |
@@ -117,7 +113,7 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
             buf += 7;
         }
     } else if (avctx->bits_per_coded_sample == 20) {
-        uint32_t *o = (uint32_t *)s->frame.data[0];
+        uint32_t *o = (uint32_t *)frame->data[0];
         for (; buf_size > 5; buf_size -= 6) {
             *o++ = (ff_reverse[buf[2] & 0xf0] << 28) |
                    (ff_reverse[buf[1]]        << 20) |
@@ -128,7 +124,7 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
             buf += 6;
         }
     } else {
-        uint16_t *o = (uint16_t *)s->frame.data[0];
+        uint16_t *o = (uint16_t *)frame->data[0];
         for (; buf_size > 4; buf_size -= 5) {
             *o++ = (ff_reverse[buf[1]]        <<  8) |
                     ff_reverse[buf[0]];
@@ -139,30 +135,16 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
 
-static int s302m_decode_init(AVCodecContext *avctx)
-{
-    S302MDecodeContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
-    return 0;
-}
-
-
 AVCodec ff_s302m_decoder = {
     .name           = "s302m",
+    .long_name      = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_S302M,
-    .priv_data_size = sizeof(S302MDecodeContext),
-    .init           = s302m_decode_init,
     .decode         = s302m_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
 };
diff --git a/libavcodec/s3tc.c b/libavcodec/s3tc.c
index 62dc356..d35cf2a 100644
--- a/libavcodec/s3tc.c
+++ b/libavcodec/s3tc.c
@@ -21,8 +21,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/bytestream.h"
 #include "avcodec.h"
+#include "bytestream.h"
 #include "s3tc.h"
 
 static inline void dxt1_decode_pixels(GetByteContext *gb, uint32_t *d,
diff --git a/libavcodec/sbrdsp.c b/libavcodec/sbrdsp.c
index 781ec83..4d07af5 100644
--- a/libavcodec/sbrdsp.c
+++ b/libavcodec/sbrdsp.c
@@ -22,6 +22,7 @@
 
 #include "config.h"
 #include "libavutil/attributes.h"
+#include "libavutil/intfloat.h"
 #include "sbrdsp.h"
 
 static void sbr_sum64x5_c(float *z)
@@ -51,37 +52,51 @@ static float sbr_sum_square_c(float (*x)[2], int n)
 
 static void sbr_neg_odd_64_c(float *x)
 {
+    union av_intfloat32 *xi = (union av_intfloat32*) x;
     int i;
-    for (i = 1; i < 64; i += 2)
-        x[i] = -x[i];
+    for (i = 1; i < 64; i += 4) {
+        xi[i + 0].i ^= 1U << 31;
+        xi[i + 2].i ^= 1U << 31;
+    }
 }
 
 static void sbr_qmf_pre_shuffle_c(float *z)
 {
+    union av_intfloat32 *zi = (union av_intfloat32*) z;
     int k;
-    z[64] = z[0];
-    z[65] = z[1];
-    for (k = 1; k < 32; k++) {
-        z[64+2*k  ] = -z[64 - k];
-        z[64+2*k+1] =  z[ k + 1];
+    zi[64].i = zi[0].i;
+    zi[65].i = zi[1].i;
+    for (k = 1; k < 31; k += 2) {
+        zi[64 + 2 * k + 0].i = zi[64 - k].i ^ (1U << 31);
+        zi[64 + 2 * k + 1].i = zi[ k + 1].i;
+        zi[64 + 2 * k + 2].i = zi[63 - k].i ^ (1U << 31);
+        zi[64 + 2 * k + 3].i = zi[ k + 2].i;
     }
+    zi[64 + 2 * 31 + 0].i = zi[64 - 31].i ^ (1U << 31);
+    zi[64 + 2 * 31 + 1].i = zi[31 +  1].i;
 }
 
 static void sbr_qmf_post_shuffle_c(float W[32][2], const float *z)
 {
+    const union av_intfloat32 *zi = (const union av_intfloat32*) z;
+    union av_intfloat32 *Wi       = (union av_intfloat32*) W;
     int k;
-    for (k = 0; k < 32; k++) {
-        W[k][0] = -z[63-k];
-        W[k][1] = z[k];
+    for (k = 0; k < 32; k += 2) {
+        Wi[2 * k + 0].i = zi[63 - k].i ^ (1U << 31);
+        Wi[2 * k + 1].i = zi[ k + 0].i;
+        Wi[2 * k + 2].i = zi[62 - k].i ^ (1U << 31);
+        Wi[2 * k + 3].i = zi[ k + 1].i;
     }
 }
 
 static void sbr_qmf_deint_neg_c(float *v, const float *src)
 {
+    const union av_intfloat32 *si = (const union av_intfloat32*)src;
+    union av_intfloat32 *vi = (union av_intfloat32*)v;
     int i;
     for (i = 0; i < 32; i++) {
-        v[     i] =  src[63 - 2*i    ];
-        v[63 - i] = -src[63 - 2*i - 1];
+        vi[     i].i = si[63 - 2 * i    ].i;
+        vi[63 - i].i = si[63 - 2 * i - 1].i ^ (1U << 31);
     }
 }
 
@@ -122,9 +137,34 @@ static av_always_inline void autocorrelate(const float x[40][2],
 
 static void sbr_autocorrelate_c(const float x[40][2], float phi[3][2][2])
 {
+#if 0
+    /* This code is slower because it multiplies memory accesses.
+     * It is left for educational purposes and because it may offer
+     * a better reference for writing arch-specific DSP functions. */
     autocorrelate(x, phi, 0);
     autocorrelate(x, phi, 1);
     autocorrelate(x, phi, 2);
+#else
+    float real_sum2 = x[0][0] * x[2][0] + x[0][1] * x[2][1];
+    float imag_sum2 = x[0][0] * x[2][1] - x[0][1] * x[2][0];
+    float real_sum1 = 0.0f, imag_sum1 = 0.0f, real_sum0 = 0.0f;
+    int   i;
+    for (i = 1; i < 38; i++) {
+        real_sum0 += x[i][0] * x[i    ][0] + x[i][1] * x[i    ][1];
+        real_sum1 += x[i][0] * x[i + 1][0] + x[i][1] * x[i + 1][1];
+        imag_sum1 += x[i][0] * x[i + 1][1] - x[i][1] * x[i + 1][0];
+        real_sum2 += x[i][0] * x[i + 2][0] + x[i][1] * x[i + 2][1];
+        imag_sum2 += x[i][0] * x[i + 2][1] - x[i][1] * x[i + 2][0];
+    }
+    phi[2 - 2][1][0] = real_sum2;
+    phi[2 - 2][1][1] = imag_sum2;
+    phi[2    ][1][0] = real_sum0 + x[ 0][0] * x[ 0][0] + x[ 0][1] * x[ 0][1];
+    phi[1    ][0][0] = real_sum0 + x[38][0] * x[38][0] + x[38][1] * x[38][1];
+    phi[2 - 1][1][0] = real_sum1 + x[ 0][0] * x[ 1][0] + x[ 0][1] * x[ 1][1];
+    phi[2 - 1][1][1] = imag_sum1 + x[ 0][0] * x[ 1][1] - x[ 0][1] * x[ 1][0];
+    phi[0    ][0][0] = real_sum1 + x[38][0] * x[39][0] + x[38][1] * x[39][1];
+    phi[0    ][0][1] = imag_sum1 + x[38][0] * x[39][1] - x[38][1] * x[39][0];
+#endif
 }
 
 static void sbr_hf_gen_c(float (*X_high)[2], const float (*X_low)[2],
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index 0e72751..928806f 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -26,7 +26,6 @@
 #include "sgi.h"
 
 typedef struct SgiState {
-    AVFrame picture;
     unsigned int width;
     unsigned int height;
     unsigned int depth;
@@ -155,8 +154,7 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     SgiState *s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame *p = &s->picture;
+    AVFrame *p = data;
     unsigned int dimension, rle;
     int ret = 0;
     uint8_t *out_buf, *out_end;
@@ -202,15 +200,11 @@ static int decode_frame(AVCodecContext *avctx,
         return -1;
     }
 
-    if (av_image_check_size(s->width, s->height, 0, avctx))
-        return -1;
-    avcodec_set_dimensions(avctx, s->width, s->height);
-
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    ret = ff_set_dimensions(avctx, s->width, s->height);
+    if (ret < 0)
+        return ret;
 
-    p->reference = 0;
-    if (ff_get_buffer(avctx, p) < 0) {
+    if (ff_get_buffer(avctx, p, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed.\n");
         return -1;
     }
@@ -232,7 +226,6 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     if (ret == 0) {
-        *picture   = s->picture;
         *got_frame = 1;
         return avpkt->size;
     } else {
@@ -240,33 +233,12 @@ static int decode_frame(AVCodecContext *avctx,
     }
 }
 
-static av_cold int sgi_init(AVCodecContext *avctx){
-    SgiState *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
-static av_cold int sgi_end(AVCodecContext *avctx)
-{
-    SgiState * const s = avctx->priv_data;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_sgi_decoder = {
     .name           = "sgi",
+    .long_name      = NULL_IF_CONFIG_SMALL("SGI image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SGI,
     .priv_data_size = sizeof(SgiState),
-    .init           = sgi_init,
-    .close          = sgi_end,
     .decode         = decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("SGI image"),
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c
index 2aecc59..902437f 100644
--- a/libavcodec/sgienc.c
+++ b/libavcodec/sgienc.c
@@ -28,16 +28,11 @@
 #define SGI_SINGLE_CHAN 2
 #define SGI_MULTI_CHAN 3
 
-typedef struct SgiContext {
-    AVFrame picture;
-} SgiContext;
-
 static av_cold int encode_init(AVCodecContext *avctx)
 {
-    SgiContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -45,16 +40,14 @@ static av_cold int encode_init(AVCodecContext *avctx)
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *frame, int *got_packet)
 {
-    SgiContext *s = avctx->priv_data;
-    AVFrame * const p = &s->picture;
+    const AVFrame * const p = frame;
     uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf, *buf;
     int x, y, z, length, tablesize, ret;
     unsigned int width, height, depth, dimension;
     unsigned char *end_buf;
 
-    *p = *frame;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
 
     width  = avctx->width;
     height = avctx->height;
@@ -170,15 +163,21 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
 AVCodec ff_sgi_encoder = {
     .name           = "sgi",
+    .long_name      = NULL_IF_CONFIG_SMALL("SGI image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SGI,
-    .priv_data_size = sizeof(SgiContext),
     .init           = encode_init,
     .encode2        = encode_frame,
+    .close          = encode_close,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("SGI image"),
 };
diff --git a/libavcodec/sh4/Makefile b/libavcodec/sh4/Makefile
index aa17eab..01a573b 100644
--- a/libavcodec/sh4/Makefile
+++ b/libavcodec/sh4/Makefile
@@ -1,3 +1,2 @@
-OBJS += sh4/dsputil_align.o                                             \
-        sh4/dsputil_sh4.o                                               \
+OBJS += sh4/dsputil_sh4.o                                               \
         sh4/idct_sh4.o                                                  \
diff --git a/libavcodec/sh4/dsputil_align.c b/libavcodec/sh4/dsputil_align.c
deleted file mode 100644
index 333e563..0000000
--- a/libavcodec/sh4/dsputil_align.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * aligned/packed access motion
- *
- * Copyright (c) 2001-2003 BERO <bero at geocities.co.jp>
- *
- * 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 "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
-#include "dsputil_sh4.h"
-
-
-#define         LP(p)           *(uint32_t*)(p)
-#define         LPC(p)          *(const uint32_t*)(p)
-
-
-#define         UNPACK(ph,pl,tt0,tt1) do { \
-        uint32_t t0,t1; t0=tt0;t1=tt1; \
-        ph = ( (t0 & ~BYTE_VEC32(0x03))>>2) + ( (t1 & ~BYTE_VEC32(0x03))>>2); \
-        pl = (t0 & BYTE_VEC32(0x03)) + (t1 & BYTE_VEC32(0x03)); } while(0)
-
-#define         rnd_PACK(ph,pl,nph,npl) ph + nph + (((pl + npl + BYTE_VEC32(0x02))>>2) & BYTE_VEC32(0x03))
-#define         no_rnd_PACK(ph,pl,nph,npl)      ph + nph + (((pl + npl + BYTE_VEC32(0x01))>>2) & BYTE_VEC32(0x03))
-
-/* little-endian */
-#define         MERGE1(a,b,ofs) (ofs==0)?a:( ((a)>>(8*ofs))|((b)<<(32-8*ofs)) )
-#define         MERGE2(a,b,ofs) (ofs==3)?b:( ((a)>>(8*(ofs+1)))|((b)<<(32-8*(ofs+1))) )
-/* big
-#define         MERGE1(a,b,ofs) (ofs==0)?a:( ((a)<<(8*ofs))|((b)>>(32-8*ofs)) )
-#define         MERGE2(a,b,ofs) (ofs==3)?b:( ((a)<<(8+8*ofs))|((b)>>(32-8-8*ofs)) )
-*/
-
-
-#define         put(d,s)        d = s
-#define         avg(d,s)        d = rnd_avg32(s,d)
-
-#define         OP_C4(ofs) \
-        ref-=ofs; \
-        do { \
-                OP(LP(dest),MERGE1(LPC(ref),LPC(ref+4),ofs)); \
-                ref+=stride; \
-                dest+=stride; \
-        } while(--height)
-
-#define        OP_C40() \
-        do { \
-                OP(LP(dest),LPC(ref)); \
-                ref+=stride; \
-                dest+=stride; \
-        } while(--height)
-
-
-#define         OP      put
-
-static void put_pixels4_c(uint8_t *dest,const uint8_t *ref, const int stride,int height)
-{
-        switch((int)ref&3){
-        case 0: OP_C40(); return;
-        case 1: OP_C4(1); return;
-        case 2: OP_C4(2); return;
-        case 3: OP_C4(3); return;
-        }
-}
-
-#undef          OP
-#define         OP      avg
-
-static void avg_pixels4_c(uint8_t *dest,const uint8_t *ref, const int stride,int height)
-{
-        switch((int)ref&3){
-        case 0: OP_C40(); return;
-        case 1: OP_C4(1); return;
-        case 2: OP_C4(2); return;
-        case 3: OP_C4(3); return;
-        }
-}
-
-#undef          OP
-
-#define         OP_C(ofs,sz,avg2) \
-{ \
-        ref-=ofs; \
-        do { \
-                uint32_t        t0,t1; \
-                t0 = LPC(ref+0); \
-                t1 = LPC(ref+4); \
-                OP(LP(dest+0), MERGE1(t0,t1,ofs)); \
-                t0 = LPC(ref+8); \
-                OP(LP(dest+4), MERGE1(t1,t0,ofs)); \
-if (sz==16) { \
-                t1 = LPC(ref+12); \
-                OP(LP(dest+8), MERGE1(t0,t1,ofs)); \
-                t0 = LPC(ref+16); \
-                OP(LP(dest+12), MERGE1(t1,t0,ofs)); \
-} \
-                ref+=stride; \
-                dest+= stride; \
-        } while(--height); \
-}
-
-/* aligned */
-#define         OP_C0(sz,avg2) \
-{ \
-        do { \
-                OP(LP(dest+0), LPC(ref+0)); \
-                OP(LP(dest+4), LPC(ref+4)); \
-if (sz==16) { \
-                OP(LP(dest+8), LPC(ref+8)); \
-                OP(LP(dest+12), LPC(ref+12)); \
-} \
-                ref+=stride; \
-                dest+= stride; \
-        } while(--height); \
-}
-
-#define         OP_X(ofs,sz,avg2) \
-{ \
-        ref-=ofs; \
-        do { \
-                uint32_t        t0,t1; \
-                t0 = LPC(ref+0); \
-                t1 = LPC(ref+4); \
-                OP(LP(dest+0), avg2(MERGE1(t0,t1,ofs),MERGE2(t0,t1,ofs))); \
-                t0 = LPC(ref+8); \
-                OP(LP(dest+4), avg2(MERGE1(t1,t0,ofs),MERGE2(t1,t0,ofs))); \
-if (sz==16) { \
-                t1 = LPC(ref+12); \
-                OP(LP(dest+8), avg2(MERGE1(t0,t1,ofs),MERGE2(t0,t1,ofs))); \
-                t0 = LPC(ref+16); \
-                OP(LP(dest+12), avg2(MERGE1(t1,t0,ofs),MERGE2(t1,t0,ofs))); \
-} \
-                ref+=stride; \
-                dest+= stride; \
-        } while(--height); \
-}
-
-/* aligned */
-#define         OP_Y0(sz,avg2) \
-{ \
-        uint32_t t0,t1,t2,t3,t; \
-\
-        t0 = LPC(ref+0); \
-        t1 = LPC(ref+4); \
-if (sz==16) { \
-        t2 = LPC(ref+8); \
-        t3 = LPC(ref+12); \
-} \
-        do { \
-                ref += stride; \
-\
-                t = LPC(ref+0); \
-                OP(LP(dest+0), avg2(t0,t)); t0 = t; \
-                t = LPC(ref+4); \
-                OP(LP(dest+4), avg2(t1,t)); t1 = t; \
-if (sz==16) { \
-                t = LPC(ref+8); \
-                OP(LP(dest+8), avg2(t2,t)); t2 = t; \
-                t = LPC(ref+12); \
-                OP(LP(dest+12), avg2(t3,t)); t3 = t; \
-} \
-                dest+= stride; \
-        } while(--height); \
-}
-
-#define         OP_Y(ofs,sz,avg2) \
-{ \
-        uint32_t t0,t1,t2,t3,t,w0,w1; \
-\
-        ref-=ofs; \
-        w0 = LPC(ref+0); \
-        w1 = LPC(ref+4); \
-        t0 = MERGE1(w0,w1,ofs); \
-        w0 = LPC(ref+8); \
-        t1 = MERGE1(w1,w0,ofs); \
-if (sz==16) { \
-        w1 = LPC(ref+12); \
-        t2 = MERGE1(w0,w1,ofs); \
-        w0 = LPC(ref+16); \
-        t3 = MERGE1(w1,w0,ofs); \
-} \
-        do { \
-                ref += stride; \
-\
-                w0 = LPC(ref+0); \
-                w1 = LPC(ref+4); \
-                t = MERGE1(w0,w1,ofs); \
-                OP(LP(dest+0), avg2(t0,t)); t0 = t; \
-                w0 = LPC(ref+8); \
-                t = MERGE1(w1,w0,ofs); \
-                OP(LP(dest+4), avg2(t1,t)); t1 = t; \
-if (sz==16) { \
-                w1 = LPC(ref+12); \
-                t = MERGE1(w0,w1,ofs); \
-                OP(LP(dest+8), avg2(t2,t)); t2 = t; \
-                w0 = LPC(ref+16); \
-                t = MERGE1(w1,w0,ofs); \
-                OP(LP(dest+12), avg2(t3,t)); t3 = t; \
-} \
-                dest+=stride; \
-        } while(--height); \
-}
-
-#define OP_X0(sz,avg2) OP_X(0,sz,avg2)
-#define OP_XY0(sz,PACK) OP_XY(0,sz,PACK)
-#define         OP_XY(ofs,sz,PACK) \
-{ \
-        uint32_t        t2,t3,w0,w1; \
-        uint32_t        a0,a1,a2,a3,a4,a5,a6,a7; \
-\
-        ref -= ofs; \
-        w0 = LPC(ref+0); \
-        w1 = LPC(ref+4); \
-        UNPACK(a0,a1,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \
-        w0 = LPC(ref+8); \
-        UNPACK(a2,a3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \
-if (sz==16) { \
-        w1 = LPC(ref+12); \
-        UNPACK(a4,a5,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \
-        w0 = LPC(ref+16); \
-        UNPACK(a6,a7,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \
-} \
-        do { \
-                ref+=stride; \
-                w0 = LPC(ref+0); \
-                w1 = LPC(ref+4); \
-                UNPACK(t2,t3,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \
-                OP(LP(dest+0),PACK(a0,a1,t2,t3)); \
-                a0 = t2; a1 = t3; \
-                w0 = LPC(ref+8); \
-                UNPACK(t2,t3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \
-                OP(LP(dest+4),PACK(a2,a3,t2,t3)); \
-                a2 = t2; a3 = t3; \
-if (sz==16) { \
-                w1 = LPC(ref+12); \
-                UNPACK(t2,t3,MERGE1(w0,w1,ofs),MERGE2(w0,w1,ofs)); \
-                OP(LP(dest+8),PACK(a4,a5,t2,t3)); \
-                a4 = t2; a5 = t3; \
-                w0 = LPC(ref+16); \
-                UNPACK(t2,t3,MERGE1(w1,w0,ofs),MERGE2(w1,w0,ofs)); \
-                OP(LP(dest+12),PACK(a6,a7,t2,t3)); \
-                a6 = t2; a7 = t3; \
-} \
-                dest+=stride; \
-        } while(--height); \
-}
-
-#define         DEFFUNC(op,rnd,xy,sz,OP_N,avgfunc) \
-static void op##_##rnd##_pixels##sz##_##xy (uint8_t * dest, const uint8_t * ref, \
-                                const int stride, int height) \
-{ \
-        switch((int)ref&3) { \
-        case 0:OP_N##0(sz,rnd##_##avgfunc); return; \
-        case 1:OP_N(1,sz,rnd##_##avgfunc); return; \
-        case 2:OP_N(2,sz,rnd##_##avgfunc); return; \
-        case 3:OP_N(3,sz,rnd##_##avgfunc); return; \
-        } \
-}
-
-#define OP put
-
-DEFFUNC(put,   rnd,o,8,OP_C,avg32)
-DEFFUNC(put,   rnd,x,8,OP_X,avg32)
-DEFFUNC(put,no_rnd,x,8,OP_X,avg32)
-DEFFUNC(put,   rnd,y,8,OP_Y,avg32)
-DEFFUNC(put,no_rnd,y,8,OP_Y,avg32)
-DEFFUNC(put,   rnd,xy,8,OP_XY,PACK)
-DEFFUNC(put,no_rnd,xy,8,OP_XY,PACK)
-DEFFUNC(put,   rnd,o,16,OP_C,avg32)
-DEFFUNC(put,   rnd,x,16,OP_X,avg32)
-DEFFUNC(put,no_rnd,x,16,OP_X,avg32)
-DEFFUNC(put,   rnd,y,16,OP_Y,avg32)
-DEFFUNC(put,no_rnd,y,16,OP_Y,avg32)
-DEFFUNC(put,   rnd,xy,16,OP_XY,PACK)
-DEFFUNC(put,no_rnd,xy,16,OP_XY,PACK)
-
-#undef OP
-#define OP avg
-
-DEFFUNC(avg,   rnd,o,8,OP_C,avg32)
-DEFFUNC(avg,   rnd,x,8,OP_X,avg32)
-DEFFUNC(avg,no_rnd,x,8,OP_X,avg32)
-DEFFUNC(avg,   rnd,y,8,OP_Y,avg32)
-DEFFUNC(avg,no_rnd,y,8,OP_Y,avg32)
-DEFFUNC(avg,   rnd,xy,8,OP_XY,PACK)
-DEFFUNC(avg,no_rnd,xy,8,OP_XY,PACK)
-DEFFUNC(avg,   rnd,o,16,OP_C,avg32)
-DEFFUNC(avg,   rnd,x,16,OP_X,avg32)
-DEFFUNC(avg,no_rnd,x,16,OP_X,avg32)
-DEFFUNC(avg,   rnd,y,16,OP_Y,avg32)
-DEFFUNC(avg,no_rnd,y,16,OP_Y,avg32)
-DEFFUNC(avg,   rnd,xy,16,OP_XY,PACK)
-DEFFUNC(avg,no_rnd,xy,16,OP_XY,PACK)
-
-#undef OP
-
-#define         put_no_rnd_pixels8_o     put_rnd_pixels8_o
-#define         put_no_rnd_pixels16_o    put_rnd_pixels16_o
-#define         avg_no_rnd_pixels8_o     avg_rnd_pixels8_o
-#define         avg_no_rnd_pixels16_o    avg_rnd_pixels16_o
-
-#define         put_pixels8_c            put_rnd_pixels8_o
-#define         put_pixels16_c           put_rnd_pixels16_o
-#define         avg_pixels8_c            avg_rnd_pixels8_o
-#define         avg_pixels16_c           avg_rnd_pixels16_o
-#define         put_no_rnd_pixels8_c     put_rnd_pixels8_o
-#define         put_no_rnd_pixels16_c    put_rnd_pixels16_o
-#define         avg_no_rnd_pixels8_c     avg_rnd_pixels8_o
-#define         avg_no_rnd_pixels16_c    avg_rnd_pixels16_o
-
-#define         QPEL
-
-#ifdef QPEL
-
-#include "qpel.c"
-
-#endif
-
-void ff_dsputil_init_align(DSPContext* c, AVCodecContext *avctx)
-{
-        const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-        if (!high_bit_depth) {
-        c->put_pixels_tab[0][0] = put_rnd_pixels16_o;
-        c->put_pixels_tab[0][1] = put_rnd_pixels16_x;
-        c->put_pixels_tab[0][2] = put_rnd_pixels16_y;
-        c->put_pixels_tab[0][3] = put_rnd_pixels16_xy;
-        c->put_pixels_tab[1][0] = put_rnd_pixels8_o;
-        c->put_pixels_tab[1][1] = put_rnd_pixels8_x;
-        c->put_pixels_tab[1][2] = put_rnd_pixels8_y;
-        c->put_pixels_tab[1][3] = put_rnd_pixels8_xy;
-
-        c->put_no_rnd_pixels_tab[0][0] = put_no_rnd_pixels16_o;
-        c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x;
-        c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y;
-        c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy;
-        c->put_no_rnd_pixels_tab[1][0] = put_no_rnd_pixels8_o;
-        c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x;
-        c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y;
-        c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy;
-
-        c->avg_pixels_tab[0][0] = avg_rnd_pixels16_o;
-        c->avg_pixels_tab[0][1] = avg_rnd_pixels16_x;
-        c->avg_pixels_tab[0][2] = avg_rnd_pixels16_y;
-        c->avg_pixels_tab[0][3] = avg_rnd_pixels16_xy;
-        c->avg_pixels_tab[1][0] = avg_rnd_pixels8_o;
-        c->avg_pixels_tab[1][1] = avg_rnd_pixels8_x;
-        c->avg_pixels_tab[1][2] = avg_rnd_pixels8_y;
-        c->avg_pixels_tab[1][3] = avg_rnd_pixels8_xy;
-
-        c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_o;
-        c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x;
-        c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y;
-        c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy;
-        c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels8_o;
-        c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels8_x;
-        c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels8_y;
-        c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels8_xy;
-        }
-
-#ifdef QPEL
-
-#define dspfunc(PFX, IDX, NUM) \
-    c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_sh4; \
-    c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_sh4; \
-    c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_sh4; \
-    c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_sh4; \
-    c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_sh4; \
-    c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_sh4; \
-    c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_sh4; \
-    c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_sh4
-
-    dspfunc(put_qpel, 0, 16);
-    dspfunc(put_no_rnd_qpel, 0, 16);
-
-    dspfunc(avg_qpel, 0, 16);
-    /* dspfunc(avg_no_rnd_qpel, 0, 16); */
-
-    dspfunc(put_qpel, 1, 8);
-    dspfunc(put_no_rnd_qpel, 1, 8);
-
-    dspfunc(avg_qpel, 1, 8);
-    /* dspfunc(avg_no_rnd_qpel, 1, 8); */
-
-    if (!high_bit_depth) {
-    dspfunc(put_h264_qpel, 0, 16);
-    dspfunc(put_h264_qpel, 1, 8);
-    dspfunc(put_h264_qpel, 2, 4);
-    dspfunc(avg_h264_qpel, 0, 16);
-    dspfunc(avg_h264_qpel, 1, 8);
-    dspfunc(avg_h264_qpel, 2, 4);
-    }
-
-#undef dspfunc
-    if (!high_bit_depth) {
-    c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_sh4;
-    c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_sh4;
-    c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_sh4;
-    c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_sh4;
-    c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_sh4;
-    c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_sh4;
-    }
-
-    c->put_mspel_pixels_tab[0]= put_mspel8_mc00_sh4;
-    c->put_mspel_pixels_tab[1]= put_mspel8_mc10_sh4;
-    c->put_mspel_pixels_tab[2]= put_mspel8_mc20_sh4;
-    c->put_mspel_pixels_tab[3]= put_mspel8_mc30_sh4;
-    c->put_mspel_pixels_tab[4]= put_mspel8_mc02_sh4;
-    c->put_mspel_pixels_tab[5]= put_mspel8_mc12_sh4;
-    c->put_mspel_pixels_tab[6]= put_mspel8_mc22_sh4;
-    c->put_mspel_pixels_tab[7]= put_mspel8_mc32_sh4;
-
-    c->gmc1 = gmc1_c;
-
-#endif
-}
diff --git a/libavcodec/sh4/dsputil_sh4.c b/libavcodec/sh4/dsputil_sh4.c
index 74c8670..6fd287d 100644
--- a/libavcodec/sh4/dsputil_sh4.c
+++ b/libavcodec/sh4/dsputil_sh4.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
 #include "dsputil_sh4.h"
@@ -47,15 +48,15 @@ static void memzero_align8(void *dst,size_t size)
         fp_single_leave(fpscr);
 }
 
-static void clear_blocks_sh4(DCTELEM *blocks)
+static void clear_blocks_sh4(int16_t *blocks)
 {
-        memzero_align8(blocks,sizeof(DCTELEM)*6*64);
+        memzero_align8(blocks,sizeof(int16_t)*6*64);
 }
 
-static void idct_put(uint8_t *dest, int line_size, DCTELEM *block)
+static void idct_put(uint8_t *dest, int line_size, int16_t *block)
 {
         int i;
-        uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+        const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
         ff_idct_sh4(block);
         for(i=0;i<8;i++) {
                 dest[0] = cm[block[0]];
@@ -70,10 +71,10 @@ static void idct_put(uint8_t *dest, int line_size, DCTELEM *block)
                 block+=8;
         }
 }
-static void idct_add(uint8_t *dest, int line_size, DCTELEM *block)
+static void idct_add(uint8_t *dest, int line_size, int16_t *block)
 {
         int i;
-        uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+        const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
         ff_idct_sh4(block);
         for(i=0;i<8;i++) {
                 dest[0] = cm[dest[0]+block[0]];
@@ -89,11 +90,10 @@ static void idct_add(uint8_t *dest, int line_size, DCTELEM *block)
         }
 }
 
-void ff_dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_sh4(DSPContext *c, AVCodecContext *avctx)
 {
         const int idct_algo= avctx->idct_algo;
         const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-        ff_dsputil_init_align(c,avctx);
 
         if (!high_bit_depth)
         c->clear_blocks = clear_blocks_sh4;
diff --git a/libavcodec/sh4/dsputil_sh4.h b/libavcodec/sh4/dsputil_sh4.h
index 7e8ebbc..9c2b311 100644
--- a/libavcodec/sh4/dsputil_sh4.h
+++ b/libavcodec/sh4/dsputil_sh4.h
@@ -22,7 +22,6 @@
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
 
-void ff_idct_sh4(DCTELEM *block);
-void ff_dsputil_init_align(DSPContext* c, AVCodecContext *avctx);
+void ff_idct_sh4(int16_t *block);
 
 #endif /* AVCODEC_SH4_DSPUTIL_SH4_H */
diff --git a/libavcodec/sh4/idct_sh4.c b/libavcodec/sh4/idct_sh4.c
index 9da6ffc..768b334 100644
--- a/libavcodec/sh4/idct_sh4.c
+++ b/libavcodec/sh4/idct_sh4.c
@@ -20,7 +20,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/dsputil.h"
 #include "dsputil_sh4.h"
 #include "sh4.h"
 
@@ -89,7 +88,7 @@ static const float odd_table[] __attribute__ ((aligned(8))) = {
 
 //optimized
 
-void ff_idct_sh4(DCTELEM *block)
+void ff_idct_sh4(int16_t *block)
 {
         DEFREG;
 
diff --git a/libavcodec/sh4/qpel.c b/libavcodec/sh4/qpel.c
deleted file mode 100644
index 20540f7..0000000
--- a/libavcodec/sh4/qpel.c
+++ /dev/null
@@ -1,1352 +0,0 @@
-/*
- * This is optimized for sh, which have post increment addressing (*p++).
- * Some CPU may be index (p[n]) faster than post increment (*p++).
- *
- * copyright (c) 2001-2003 BERO <bero at geocities.co.jp>
- *
- * 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/common.h"
-
-#define PIXOP2(OPNAME, OP) \
-\
-static inline void OPNAME ## _pixels4_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),rnd_avg32(LPC(src1  ),LPC(src2  )) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _pixels4_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),rnd_avg32(AV_RN32(src1  ),LPC(src2  )) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _no_rnd_pixels16_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),no_rnd_avg32(AV_RN32(src1  ),LPC(src2  )) ); \
-                OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \
-                OP(LP(dst+8),no_rnd_avg32(AV_RN32(src1+8),LPC(src2+8)) ); \
-                OP(LP(dst+12),no_rnd_avg32(AV_RN32(src1+12),LPC(src2+12)) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _pixels16_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),rnd_avg32(AV_RN32(src1  ),LPC(src2  )) ); \
-                OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \
-                OP(LP(dst+8),rnd_avg32(AV_RN32(src1+8),LPC(src2+8)) ); \
-                OP(LP(dst+12),rnd_avg32(AV_RN32(src1+12),LPC(src2+12)) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _no_rnd_pixels8_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do { /* onlye src2 aligned */\
-                OP(LP(dst  ),no_rnd_avg32(AV_RN32(src1  ),LPC(src2  )) ); \
-                OP(LP(dst+4),no_rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _pixels8_l2_aligned2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),rnd_avg32(AV_RN32(src1  ),LPC(src2  )) ); \
-                OP(LP(dst+4),rnd_avg32(AV_RN32(src1+4),LPC(src2+4)) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _no_rnd_pixels8_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),no_rnd_avg32(LPC(src1  ),LPC(src2  )) ); \
-                OP(LP(dst+4),no_rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _pixels8_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),rnd_avg32(LPC(src1  ),LPC(src2  )) ); \
-                OP(LP(dst+4),rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _no_rnd_pixels16_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),no_rnd_avg32(LPC(src1  ),LPC(src2  )) ); \
-                OP(LP(dst+4),no_rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \
-                OP(LP(dst+8),no_rnd_avg32(LPC(src1+8),LPC(src2+8)) ); \
-                OP(LP(dst+12),no_rnd_avg32(LPC(src1+12),LPC(src2+12)) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _pixels16_l2_aligned(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{\
-        do {\
-                OP(LP(dst  ),rnd_avg32(LPC(src1  ),LPC(src2  )) ); \
-                OP(LP(dst+4),rnd_avg32(LPC(src1+4),LPC(src2+4)) ); \
-                OP(LP(dst+8),rnd_avg32(LPC(src1+8),LPC(src2+8)) ); \
-                OP(LP(dst+12),rnd_avg32(LPC(src1+12),LPC(src2+12)) ); \
-                src1+=src_stride1; \
-                src2+=src_stride2; \
-                dst+=dst_stride; \
-        } while(--h); \
-}\
-\
-static inline void OPNAME ## _no_rnd_pixels16_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{ OPNAME ## _no_rnd_pixels16_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \
-\
-static inline void OPNAME ## _pixels16_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{ OPNAME ## _pixels16_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \
-\
-static inline void OPNAME ## _no_rnd_pixels8_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{ OPNAME ## _no_rnd_pixels8_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \
-\
-static inline void OPNAME ## _pixels8_l2_aligned1(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, int src_stride1, int src_stride2, int h) \
-{ OPNAME ## _pixels8_l2_aligned2(dst,src2,src1,dst_stride,src_stride2,src_stride1,h); } \
-\
-static inline void OPNAME ## _pixels8_l4_aligned(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-        do { \
-                uint32_t a0,a1,a2,a3; \
-                UNPACK(a0,a1,LPC(src1),LPC(src2)); \
-                UNPACK(a2,a3,LPC(src3),LPC(src4)); \
-                OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \
-                UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \
-                OP(LP(dst+4),rnd_PACK(a0,a1,a2,a3)); \
-                src1+=src_stride1;\
-                src2+=src_stride2;\
-                src3+=src_stride3;\
-                src4+=src_stride4;\
-                dst+=dst_stride;\
-        } while(--h); \
-} \
-\
-static inline void OPNAME ## _no_rnd_pixels8_l4_aligned(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-        do { \
-                uint32_t a0,a1,a2,a3; \
-                UNPACK(a0,a1,LPC(src1),LPC(src2)); \
-                UNPACK(a2,a3,LPC(src3),LPC(src4)); \
-                OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \
-                UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \
-                OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \
-                src1+=src_stride1;\
-                src2+=src_stride2;\
-                src3+=src_stride3;\
-                src4+=src_stride4;\
-                dst+=dst_stride;\
-        } while(--h); \
-} \
-\
-static inline void OPNAME ## _pixels8_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-        do { \
-                uint32_t a0,a1,a2,a3; /* src1 only not aligned */\
-                UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \
-                UNPACK(a2,a3,LPC(src3),LPC(src4)); \
-                OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \
-                UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \
-                OP(LP(dst+4),rnd_PACK(a0,a1,a2,a3)); \
-                src1+=src_stride1;\
-                src2+=src_stride2;\
-                src3+=src_stride3;\
-                src4+=src_stride4;\
-                dst+=dst_stride;\
-        } while(--h); \
-} \
-\
-static inline void OPNAME ## _no_rnd_pixels8_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-        do { \
-                uint32_t a0,a1,a2,a3; \
-                UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \
-                UNPACK(a2,a3,LPC(src3),LPC(src4)); \
-                OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \
-                UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \
-                OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \
-                src1+=src_stride1;\
-                src2+=src_stride2;\
-                src3+=src_stride3;\
-                src4+=src_stride4;\
-                dst+=dst_stride;\
-        } while(--h); \
-} \
-\
-static inline void OPNAME ## _pixels16_l4_aligned(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-        do { \
-                uint32_t a0,a1,a2,a3; \
-                UNPACK(a0,a1,LPC(src1),LPC(src2)); \
-                UNPACK(a2,a3,LPC(src3),LPC(src4)); \
-                OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \
-                UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \
-                OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,LPC(src1+8),LPC(src2+8)); \
-                UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \
-                OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,LPC(src1+12),LPC(src2+12)); \
-                UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \
-                OP(LP(dst+12),rnd_PACK(a0,a1,a2,a3)); \
-                src1+=src_stride1;\
-                src2+=src_stride2;\
-                src3+=src_stride3;\
-                src4+=src_stride4;\
-                dst+=dst_stride;\
-        } while(--h); \
-} \
-\
-static inline void OPNAME ## _no_rnd_pixels16_l4_aligned(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-        do { \
-                uint32_t a0,a1,a2,a3; \
-                UNPACK(a0,a1,LPC(src1),LPC(src2)); \
-                UNPACK(a2,a3,LPC(src3),LPC(src4)); \
-                OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,LPC(src1+4),LPC(src2+4)); \
-                UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \
-                OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,LPC(src1+8),LPC(src2+8)); \
-                UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \
-                OP(LP(dst+8),no_rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,LPC(src1+12),LPC(src2+12)); \
-                UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \
-                OP(LP(dst+12),no_rnd_PACK(a0,a1,a2,a3)); \
-                src1+=src_stride1;\
-                src2+=src_stride2;\
-                src3+=src_stride3;\
-                src4+=src_stride4;\
-                dst+=dst_stride;\
-        } while(--h); \
-} \
-\
-static inline void OPNAME ## _pixels16_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-        do { /* src1 is unaligned */\
-                uint32_t a0,a1,a2,a3; \
-                UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \
-                UNPACK(a2,a3,LPC(src3),LPC(src4)); \
-                OP(LP(dst),rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \
-                UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \
-                OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,AV_RN32(src1+8),LPC(src2+8)); \
-                UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \
-                OP(LP(dst+8),rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,AV_RN32(src1+12),LPC(src2+12)); \
-                UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \
-                OP(LP(dst+12),rnd_PACK(a0,a1,a2,a3)); \
-                src1+=src_stride1;\
-                src2+=src_stride2;\
-                src3+=src_stride3;\
-                src4+=src_stride4;\
-                dst+=dst_stride;\
-        } while(--h); \
-} \
-\
-static inline void OPNAME ## _no_rnd_pixels16_l4_aligned0(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\
-        do { \
-                uint32_t a0,a1,a2,a3; \
-                UNPACK(a0,a1,AV_RN32(src1),LPC(src2)); \
-                UNPACK(a2,a3,LPC(src3),LPC(src4)); \
-                OP(LP(dst),no_rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,AV_RN32(src1+4),LPC(src2+4)); \
-                UNPACK(a2,a3,LPC(src3+4),LPC(src4+4)); \
-                OP(LP(dst+4),no_rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,AV_RN32(src1+8),LPC(src2+8)); \
-                UNPACK(a2,a3,LPC(src3+8),LPC(src4+8)); \
-                OP(LP(dst+8),no_rnd_PACK(a0,a1,a2,a3)); \
-                UNPACK(a0,a1,AV_RN32(src1+12),LPC(src2+12)); \
-                UNPACK(a2,a3,LPC(src3+12),LPC(src4+12)); \
-                OP(LP(dst+12),no_rnd_PACK(a0,a1,a2,a3)); \
-                src1+=src_stride1;\
-                src2+=src_stride2;\
-                src3+=src_stride3;\
-                src4+=src_stride4;\
-                dst+=dst_stride;\
-        } while(--h); \
-} \
-\
-
-#define op_avg(a, b) a = rnd_avg32(a,b)
-#define op_put(a, b) a = b
-
-PIXOP2(avg, op_avg)
-PIXOP2(put, op_put)
-#undef op_avg
-#undef op_put
-
-#define avg2(a,b) ((a+b+1)>>1)
-#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
-
-
-static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, int x16, int y16, int rounder)
-{
-    const int A=(16-x16)*(16-y16);
-    const int B=(   x16)*(16-y16);
-    const int C=(16-x16)*(   y16);
-    const int D=(   x16)*(   y16);
-
-    do {
-        int t0,t1,t2,t3;
-        uint8_t *s0 = src;
-        uint8_t *s1 = src+stride;
-        t0 = *s0++; t2 = *s1++;
-        t1 = *s0++; t3 = *s1++;
-        dst[0]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8;
-        t0 = *s0++; t2 = *s1++;
-        dst[1]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8;
-        t1 = *s0++; t3 = *s1++;
-        dst[2]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8;
-        t0 = *s0++; t2 = *s1++;
-        dst[3]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8;
-        t1 = *s0++; t3 = *s1++;
-        dst[4]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8;
-        t0 = *s0++; t2 = *s1++;
-        dst[5]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8;
-        t1 = *s0++; t3 = *s1++;
-        dst[6]= (A*t0 + B*t1 + C*t2 + D*t3 + rounder)>>8;
-        t0 = *s0++; t2 = *s1++;
-        dst[7]= (A*t1 + B*t0 + C*t3 + D*t2 + rounder)>>8;
-        dst+= stride;
-        src+= stride;
-    }while(--h);
-}
-
-#define H264_CHROMA_MC(OPNAME, OP)\
-static void OPNAME ## h264_chroma_mc2_sh4(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
-    const int A=(8-x)*(8-y);\
-    const int B=(  x)*(8-y);\
-    const int C=(8-x)*(  y);\
-    const int D=(  x)*(  y);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    do {\
-        int t0,t1,t2,t3; \
-        uint8_t *s0 = src; \
-        uint8_t *s1 = src+stride; \
-        t0 = *s0++; t2 = *s1++; \
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
-        dst+= stride;\
-        src+= stride;\
-    }while(--h);\
-}\
-\
-static void OPNAME ## h264_chroma_mc4_sh4(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
-    const int A=(8-x)*(8-y);\
-    const int B=(  x)*(8-y);\
-    const int C=(8-x)*(  y);\
-    const int D=(  x)*(  y);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    do {\
-        int t0,t1,t2,t3; \
-        uint8_t *s0 = src; \
-        uint8_t *s1 = src+stride; \
-        t0 = *s0++; t2 = *s1++; \
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\
-        dst+= stride;\
-        src+= stride;\
-    }while(--h);\
-}\
-\
-static void OPNAME ## h264_chroma_mc8_sh4(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
-    const int A=(8-x)*(8-y);\
-    const int B=(  x)*(8-y);\
-    const int C=(8-x)*(  y);\
-    const int D=(  x)*(  y);\
-    \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
-\
-    do {\
-        int t0,t1,t2,t3; \
-        uint8_t *s0 = src; \
-        uint8_t *s1 = src+stride; \
-        t0 = *s0++; t2 = *s1++; \
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[0], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[1], (A*t1 + B*t0 + C*t3 + D*t2));\
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[2], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[3], (A*t1 + B*t0 + C*t3 + D*t2));\
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[4], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[5], (A*t1 + B*t0 + C*t3 + D*t2));\
-        t1 = *s0++; t3 = *s1++; \
-        OP(dst[6], (A*t0 + B*t1 + C*t2 + D*t3));\
-        t0 = *s0++; t2 = *s1++; \
-        OP(dst[7], (A*t1 + B*t0 + C*t3 + D*t2));\
-        dst+= stride;\
-        src+= stride;\
-    }while(--h);\
-}
-
-#define op_avg(a, b) a = (((a)+(((b) + 32)>>6)+1)>>1)
-#define op_put(a, b) a = (((b) + 32)>>6)
-
-H264_CHROMA_MC(put_       , op_put)
-H264_CHROMA_MC(avg_       , op_avg)
-#undef op_avg
-#undef op_put
-
-#define QPEL_MC(r, OPNAME, RND, OP) \
-static void OPNAME ## mpeg4_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    do {\
-        uint8_t *s = src; \
-        int src0,src1,src2,src3,src4,src5,src6,src7,src8;\
-        src0= *s++;\
-        src1= *s++;\
-        src2= *s++;\
-        src3= *s++;\
-        src4= *s++;\
-        OP(dst[0], (src0+src1)*20 - (src0+src2)*6 + (src1+src3)*3 - (src2+src4));\
-        src5= *s++;\
-        OP(dst[1], (src1+src2)*20 - (src0+src3)*6 + (src0+src4)*3 - (src1+src5));\
-        src6= *s++;\
-        OP(dst[2], (src2+src3)*20 - (src1+src4)*6 + (src0+src5)*3 - (src0+src6));\
-        src7= *s++;\
-        OP(dst[3], (src3+src4)*20 - (src2+src5)*6 + (src1+src6)*3 - (src0+src7));\
-        src8= *s++;\
-        OP(dst[4], (src4+src5)*20 - (src3+src6)*6 + (src2+src7)*3 - (src1+src8));\
-        OP(dst[5], (src5+src6)*20 - (src4+src7)*6 + (src3+src8)*3 - (src2+src8));\
-        OP(dst[6], (src6+src7)*20 - (src5+src8)*6 + (src4+src8)*3 - (src3+src7));\
-        OP(dst[7], (src7+src8)*20 - (src6+src8)*6 + (src5+src7)*3 - (src4+src6));\
-        dst+=dstStride;\
-        src+=srcStride;\
-    }while(--h);\
-}\
-\
-static void OPNAME ## mpeg4_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    int w=8;\
-    do{\
-        uint8_t *s = src, *d=dst;\
-        int src0,src1,src2,src3,src4,src5,src6,src7,src8;\
-        src0 = *s; s+=srcStride; \
-        src1 = *s; s+=srcStride; \
-        src2 = *s; s+=srcStride; \
-        src3 = *s; s+=srcStride; \
-        src4 = *s; s+=srcStride; \
-        OP(*d, (src0+src1)*20 - (src0+src2)*6 + (src1+src3)*3 - (src2+src4));d+=dstStride;\
-        src5 = *s; s+=srcStride; \
-        OP(*d, (src1+src2)*20 - (src0+src3)*6 + (src0+src4)*3 - (src1+src5));d+=dstStride;\
-        src6 = *s; s+=srcStride; \
-        OP(*d, (src2+src3)*20 - (src1+src4)*6 + (src0+src5)*3 - (src0+src6));d+=dstStride;\
-        src7 = *s; s+=srcStride; \
-        OP(*d, (src3+src4)*20 - (src2+src5)*6 + (src1+src6)*3 - (src0+src7));d+=dstStride;\
-        src8 = *s; \
-        OP(*d, (src4+src5)*20 - (src3+src6)*6 + (src2+src7)*3 - (src1+src8));d+=dstStride;\
-        OP(*d, (src5+src6)*20 - (src4+src7)*6 + (src3+src8)*3 - (src2+src8));d+=dstStride;\
-        OP(*d, (src6+src7)*20 - (src5+src8)*6 + (src4+src8)*3 - (src3+src7));d+=dstStride;\
-        OP(*d, (src7+src8)*20 - (src6+src8)*6 + (src5+src7)*3 - (src4+src6));\
-        dst++;\
-        src++;\
-    }while(--w);\
-}\
-\
-static void OPNAME ## mpeg4_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    do {\
-        uint8_t *s = src;\
-        int src0,src1,src2,src3,src4,src5,src6,src7,src8;\
-        int src9,src10,src11,src12,src13,src14,src15,src16;\
-        src0= *s++;\
-        src1= *s++;\
-        src2= *s++;\
-        src3= *s++;\
-        src4= *s++;\
-        OP(dst[ 0], (src0 +src1 )*20 - (src0 +src2 )*6 + (src1 +src3 )*3 - (src2 +src4 ));\
-        src5= *s++;\
-        OP(dst[ 1], (src1 +src2 )*20 - (src0 +src3 )*6 + (src0 +src4 )*3 - (src1 +src5 ));\
-        src6= *s++;\
-        OP(dst[ 2], (src2 +src3 )*20 - (src1 +src4 )*6 + (src0 +src5 )*3 - (src0 +src6 ));\
-        src7= *s++;\
-        OP(dst[ 3], (src3 +src4 )*20 - (src2 +src5 )*6 + (src1 +src6 )*3 - (src0 +src7 ));\
-        src8= *s++;\
-        OP(dst[ 4], (src4 +src5 )*20 - (src3 +src6 )*6 + (src2 +src7 )*3 - (src1 +src8 ));\
-        src9= *s++;\
-        OP(dst[ 5], (src5 +src6 )*20 - (src4 +src7 )*6 + (src3 +src8 )*3 - (src2 +src9 ));\
-        src10= *s++;\
-        OP(dst[ 6], (src6 +src7 )*20 - (src5 +src8 )*6 + (src4 +src9 )*3 - (src3 +src10));\
-        src11= *s++;\
-        OP(dst[ 7], (src7 +src8 )*20 - (src6 +src9 )*6 + (src5 +src10)*3 - (src4 +src11));\
-        src12= *s++;\
-        OP(dst[ 8], (src8 +src9 )*20 - (src7 +src10)*6 + (src6 +src11)*3 - (src5 +src12));\
-        src13= *s++;\
-        OP(dst[ 9], (src9 +src10)*20 - (src8 +src11)*6 + (src7 +src12)*3 - (src6 +src13));\
-        src14= *s++;\
-        OP(dst[10], (src10+src11)*20 - (src9 +src12)*6 + (src8 +src13)*3 - (src7 +src14));\
-        src15= *s++;\
-        OP(dst[11], (src11+src12)*20 - (src10+src13)*6 + (src9 +src14)*3 - (src8 +src15));\
-        src16= *s++;\
-        OP(dst[12], (src12+src13)*20 - (src11+src14)*6 + (src10+src15)*3 - (src9 +src16));\
-        OP(dst[13], (src13+src14)*20 - (src12+src15)*6 + (src11+src16)*3 - (src10+src16));\
-        OP(dst[14], (src14+src15)*20 - (src13+src16)*6 + (src12+src16)*3 - (src11+src15));\
-        OP(dst[15], (src15+src16)*20 - (src14+src16)*6 + (src13+src15)*3 - (src12+src14));\
-        dst+=dstStride;\
-        src+=srcStride;\
-    }while(--h);\
-}\
-\
-static void OPNAME ## mpeg4_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    int w=16;\
-    do {\
-        uint8_t *s = src, *d=dst;\
-        int src0,src1,src2,src3,src4,src5,src6,src7,src8;\
-        int src9,src10,src11,src12,src13,src14,src15,src16;\
-        src0 = *s; s+=srcStride; \
-        src1 = *s; s+=srcStride; \
-        src2 = *s; s+=srcStride; \
-        src3 = *s; s+=srcStride; \
-        src4 = *s; s+=srcStride; \
-        OP(*d, (src0 +src1 )*20 - (src0 +src2 )*6 + (src1 +src3 )*3 - (src2 +src4 ));d+=dstStride;\
-        src5 = *s; s+=srcStride; \
-        OP(*d, (src1 +src2 )*20 - (src0 +src3 )*6 + (src0 +src4 )*3 - (src1 +src5 ));d+=dstStride;\
-        src6 = *s; s+=srcStride; \
-        OP(*d, (src2 +src3 )*20 - (src1 +src4 )*6 + (src0 +src5 )*3 - (src0 +src6 ));d+=dstStride;\
-        src7 = *s; s+=srcStride; \
-        OP(*d, (src3 +src4 )*20 - (src2 +src5 )*6 + (src1 +src6 )*3 - (src0 +src7 ));d+=dstStride;\
-        src8 = *s; s+=srcStride; \
-        OP(*d, (src4 +src5 )*20 - (src3 +src6 )*6 + (src2 +src7 )*3 - (src1 +src8 ));d+=dstStride;\
-        src9 = *s; s+=srcStride; \
-        OP(*d, (src5 +src6 )*20 - (src4 +src7 )*6 + (src3 +src8 )*3 - (src2 +src9 ));d+=dstStride;\
-        src10 = *s; s+=srcStride; \
-        OP(*d, (src6 +src7 )*20 - (src5 +src8 )*6 + (src4 +src9 )*3 - (src3 +src10));d+=dstStride;\
-        src11 = *s; s+=srcStride; \
-        OP(*d, (src7 +src8 )*20 - (src6 +src9 )*6 + (src5 +src10)*3 - (src4 +src11));d+=dstStride;\
-        src12 = *s; s+=srcStride; \
-        OP(*d, (src8 +src9 )*20 - (src7 +src10)*6 + (src6 +src11)*3 - (src5 +src12));d+=dstStride;\
-        src13 = *s; s+=srcStride; \
-        OP(*d, (src9 +src10)*20 - (src8 +src11)*6 + (src7 +src12)*3 - (src6 +src13));d+=dstStride;\
-        src14 = *s; s+=srcStride; \
-        OP(*d, (src10+src11)*20 - (src9 +src12)*6 + (src8 +src13)*3 - (src7 +src14));d+=dstStride;\
-        src15 = *s; s+=srcStride; \
-        OP(*d, (src11+src12)*20 - (src10+src13)*6 + (src9 +src14)*3 - (src8 +src15));d+=dstStride;\
-        src16 = *s; \
-        OP(*d, (src12+src13)*20 - (src11+src14)*6 + (src10+src15)*3 - (src9 +src16));d+=dstStride;\
-        OP(*d, (src13+src14)*20 - (src12+src15)*6 + (src11+src16)*3 - (src10+src16));d+=dstStride;\
-        OP(*d, (src14+src15)*20 - (src13+src16)*6 + (src12+src16)*3 - (src11+src15));d+=dstStride;\
-        OP(*d, (src15+src16)*20 - (src14+src16)*6 + (src13+src15)*3 - (src12+src14));\
-        dst++;\
-        src++;\
-    }while(--w);\
-}\
-\
-static void OPNAME ## qpel8_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## pixels8_c(dst, src, stride, 8);\
-}\
-\
-static void OPNAME ## qpel8_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[64];\
-    put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8);\
-    OPNAME ## pixels8_l2_aligned2(dst, src, half, stride, stride, 8, 8);\
-}\
-\
-static void OPNAME ## qpel8_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## mpeg4_qpel8_h_lowpass(dst, src, stride, stride, 8);\
-}\
-\
-static void OPNAME ## qpel8_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[64];\
-    put ## RND ## mpeg4_qpel8_h_lowpass(half, src, 8, stride, 8);\
-    OPNAME ## pixels8_l2_aligned2(dst, src+1, half, stride, stride, 8, 8);\
-}\
-\
-static void OPNAME ## qpel8_mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    uint8_t half[64];\
-    copy_block9(full, src, 16, stride, 9);\
-    put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16);\
-    OPNAME ## pixels8_l2_aligned(dst, full, half, stride, 16, 8, 8);\
-}\
-\
-static void OPNAME ## qpel8_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    copy_block9(full, src, 16, stride, 9);\
-    OPNAME ## mpeg4_qpel8_v_lowpass(dst, full, stride, 16);\
-}\
-\
-static void OPNAME ## qpel8_mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    uint8_t half[64];\
-    copy_block9(full, src, 16, stride, 9);\
-    put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16);\
-    OPNAME ## pixels8_l2_aligned(dst, full+16, half, stride, 16, 8, 8);\
-}\
-static void OPNAME ## qpel8_mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    uint8_t halfH[72];\
-    uint8_t halfHV[64];\
-    copy_block9(full, src, 16, stride, 9);\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\
-    put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\
-    put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
-    OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\
-}\
-static void OPNAME ## qpel8_mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    uint8_t halfH[72];\
-    uint8_t halfHV[64];\
-    copy_block9(full, src, 16, stride, 9);\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\
-    put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\
-    put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
-    OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\
-}\
-static void OPNAME ## qpel8_mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    uint8_t halfH[72];\
-    uint8_t halfHV[64];\
-    copy_block9(full, src, 16, stride, 9);\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\
-    put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\
-    put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
-    OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\
-}\
-static void OPNAME ## qpel8_mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    uint8_t halfH[72];\
-    uint8_t halfHV[64];\
-    copy_block9(full, src, 16, stride, 9);\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\
-    put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\
-    put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
-    OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\
-}\
-static void OPNAME ## qpel8_mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t halfH[72];\
-    uint8_t halfHV[64];\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\
-    put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
-    OPNAME ## pixels8_l2_aligned(dst, halfH, halfHV, stride, 8, 8, 8);\
-}\
-static void OPNAME ## qpel8_mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t halfH[72];\
-    uint8_t halfHV[64];\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\
-    put ## RND ## mpeg4_qpel8_v_lowpass(halfHV, halfH, 8, 8);\
-    OPNAME ## pixels8_l2_aligned(dst, halfH+8, halfHV, stride, 8, 8, 8);\
-}\
-static void OPNAME ## qpel8_mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    uint8_t halfH[72];\
-    copy_block9(full, src, 16, stride, 9);\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\
-    put ## RND ## pixels8_l2_aligned(halfH, halfH, full, 8, 8, 16, 9);\
-    OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\
-}\
-static void OPNAME ## qpel8_mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[16*9];\
-    uint8_t halfH[72];\
-    copy_block9(full, src, 16, stride, 9);\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, full, 8, 16, 9);\
-    put ## RND ## pixels8_l2_aligned1(halfH, halfH, full+1, 8, 8, 16, 9);\
-    OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\
-}\
-static void OPNAME ## qpel8_mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t halfH[72];\
-    put ## RND ## mpeg4_qpel8_h_lowpass(halfH, src, 8, stride, 9);\
-    OPNAME ## mpeg4_qpel8_v_lowpass(dst, halfH, stride, 8);\
-}\
-static void OPNAME ## qpel16_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## pixels16_c(dst, src, stride, 16);\
-}\
-\
-static void OPNAME ## qpel16_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[256];\
-    put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16);\
-    OPNAME ## pixels16_l2_aligned2(dst, src, half, stride, stride, 16, 16);\
-}\
-\
-static void OPNAME ## qpel16_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## mpeg4_qpel16_h_lowpass(dst, src, stride, stride, 16);\
-}\
-\
-static void OPNAME ## qpel16_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[256];\
-    put ## RND ## mpeg4_qpel16_h_lowpass(half, src, 16, stride, 16);\
-    OPNAME ## pixels16_l2_aligned2(dst, src+1, half, stride, stride, 16, 16);\
-}\
-\
-static void OPNAME ## qpel16_mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    uint8_t half[256];\
-    copy_block17(full, src, 24, stride, 17);\
-    put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24);\
-    OPNAME ## pixels16_l2_aligned(dst, full, half, stride, 24, 16, 16);\
-}\
-\
-static void OPNAME ## qpel16_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    copy_block17(full, src, 24, stride, 17);\
-    OPNAME ## mpeg4_qpel16_v_lowpass(dst, full, stride, 24);\
-}\
-\
-static void OPNAME ## qpel16_mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    uint8_t half[256];\
-    copy_block17(full, src, 24, stride, 17);\
-    put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24);\
-    OPNAME ## pixels16_l2_aligned(dst, full+24, half, stride, 24, 16, 16);\
-}\
-static void OPNAME ## qpel16_mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    uint8_t halfH[272];\
-    uint8_t halfHV[256];\
-    copy_block17(full, src, 24, stride, 17);\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\
-    put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\
-    put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
-    OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\
-}\
-static void OPNAME ## qpel16_mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    uint8_t halfH[272];\
-    uint8_t halfHV[256];\
-    copy_block17(full, src, 24, stride, 17);\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\
-    put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\
-    put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
-    OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\
-}\
-static void OPNAME ## qpel16_mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    uint8_t halfH[272];\
-    uint8_t halfHV[256];\
-    copy_block17(full, src, 24, stride, 17);\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\
-    put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\
-    put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
-    OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\
-}\
-static void OPNAME ## qpel16_mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    uint8_t halfH[272];\
-    uint8_t halfHV[256];\
-    copy_block17(full, src, 24, stride, 17);\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\
-    put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\
-    put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
-    OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\
-}\
-static void OPNAME ## qpel16_mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t halfH[272];\
-    uint8_t halfHV[256];\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\
-    put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
-    OPNAME ## pixels16_l2_aligned(dst, halfH, halfHV, stride, 16, 16, 16);\
-}\
-static void OPNAME ## qpel16_mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t halfH[272];\
-    uint8_t halfHV[256];\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\
-    put ## RND ## mpeg4_qpel16_v_lowpass(halfHV, halfH, 16, 16);\
-    OPNAME ## pixels16_l2_aligned(dst, halfH+16, halfHV, stride, 16, 16, 16);\
-}\
-static void OPNAME ## qpel16_mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    uint8_t halfH[272];\
-    copy_block17(full, src, 24, stride, 17);\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\
-    put ## RND ## pixels16_l2_aligned(halfH, halfH, full, 16, 16, 24, 17);\
-    OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\
-}\
-static void OPNAME ## qpel16_mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[24*17];\
-    uint8_t halfH[272];\
-    copy_block17(full, src, 24, stride, 17);\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, full, 16, 24, 17);\
-    put ## RND ## pixels16_l2_aligned1(halfH, halfH, full+1, 16, 16, 24, 17);\
-    OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\
-}\
-static void OPNAME ## qpel16_mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t halfH[272];\
-    put ## RND ## mpeg4_qpel16_h_lowpass(halfH, src, 16, stride, 17);\
-    OPNAME ## mpeg4_qpel16_v_lowpass(dst, halfH, stride, 16);\
-}
-
-#define op_avg(a, b) a = (((a)+cm[((b) + 16)>>5]+1)>>1)
-#define op_avg_no_rnd(a, b) a = (((a)+cm[((b) + 15)>>5])>>1)
-#define op_put(a, b) a = cm[((b) + 16)>>5]
-#define op_put_no_rnd(a, b) a = cm[((b) + 15)>>5]
-
-QPEL_MC(0, put_       , _       , op_put)
-QPEL_MC(1, put_no_rnd_, _no_rnd_, op_put_no_rnd)
-QPEL_MC(0, avg_       , _       , op_avg)
-//QPEL_MC(1, avg_no_rnd , _       , op_avg)
-#undef op_avg
-#undef op_avg_no_rnd
-#undef op_put
-#undef op_put_no_rnd
-
-#define H264_LOWPASS(OPNAME, OP, OP2) \
-static inline void OPNAME ## h264_qpel_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,int w,int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    do {\
-        int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\
-        uint8_t *s = src-2;\
-        srcB = *s++;\
-        srcA = *s++;\
-        src0 = *s++;\
-        src1 = *s++;\
-        src2 = *s++;\
-        src3 = *s++;\
-        OP(dst[0], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        src4 = *s++;\
-        OP(dst[1], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        src5 = *s++;\
-        OP(dst[2], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
-        src6 = *s++;\
-        OP(dst[3], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
-      if (w>4) { /* it optimized */ \
-        int src7,src8,src9,src10; \
-        src7 = *s++;\
-        OP(dst[4], (src4+src5)*20 - (src3+src6)*5 + (src2+src7));\
-        src8 = *s++;\
-        OP(dst[5], (src5+src6)*20 - (src4+src7)*5 + (src3+src8));\
-        src9 = *s++;\
-        OP(dst[6], (src6+src7)*20 - (src5+src8)*5 + (src4+src9));\
-        src10 = *s++;\
-        OP(dst[7], (src7+src8)*20 - (src6+src9)*5 + (src5+src10));\
-       if (w>8) { \
-        int src11,src12,src13,src14,src15,src16,src17,src18; \
-        src11 = *s++;\
-        OP(dst[8] , (src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));\
-        src12 = *s++;\
-        OP(dst[9] , (src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));\
-        src13 = *s++;\
-        OP(dst[10], (src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));\
-        src14 = *s++;\
-        OP(dst[11], (src11+src12)*20 - (src10+src13)*5 + (src9 +src14));\
-        src15 = *s++;\
-        OP(dst[12], (src12+src13)*20 - (src11+src14)*5 + (src10+src15));\
-        src16 = *s++;\
-        OP(dst[13], (src13+src14)*20 - (src12+src15)*5 + (src11+src16));\
-        src17 = *s++;\
-        OP(dst[14], (src14+src15)*20 - (src13+src16)*5 + (src12+src17));\
-        src18 = *s++;\
-        OP(dst[15], (src15+src16)*20 - (src14+src17)*5 + (src13+src18));\
-       } \
-      } \
-        dst+=dstStride;\
-        src+=srcStride;\
-    }while(--h);\
-}\
-\
-static inline void OPNAME ## h264_qpel_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride,int w,int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    do{\
-        int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\
-        uint8_t *s = src-2*srcStride,*d=dst;\
-        srcB = *s; s+=srcStride;\
-        srcA = *s; s+=srcStride;\
-        src0 = *s; s+=srcStride;\
-        src1 = *s; s+=srcStride;\
-        src2 = *s; s+=srcStride;\
-        src3 = *s; s+=srcStride;\
-        OP(*d, (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));d+=dstStride;\
-        src4 = *s; s+=srcStride;\
-        OP(*d, (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));d+=dstStride;\
-        src5 = *s; s+=srcStride;\
-        OP(*d, (src2+src3)*20 - (src1+src4)*5 + (src0+src5));d+=dstStride;\
-        src6 = *s; s+=srcStride;\
-        OP(*d, (src3+src4)*20 - (src2+src5)*5 + (src1+src6));d+=dstStride;\
-      if (h>4) { \
-        int src7,src8,src9,src10; \
-        src7 = *s; s+=srcStride;\
-        OP(*d, (src4+src5)*20 - (src3+src6)*5 + (src2+src7));d+=dstStride;\
-        src8 = *s; s+=srcStride;\
-        OP(*d, (src5+src6)*20 - (src4+src7)*5 + (src3+src8));d+=dstStride;\
-        src9 = *s; s+=srcStride;\
-        OP(*d, (src6+src7)*20 - (src5+src8)*5 + (src4+src9));d+=dstStride;\
-        src10 = *s; s+=srcStride;\
-        OP(*d, (src7+src8)*20 - (src6+src9)*5 + (src5+src10));d+=dstStride;\
-       if (h>8) { \
-        int src11,src12,src13,src14,src15,src16,src17,src18; \
-        src11 = *s; s+=srcStride;\
-        OP(*d , (src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));d+=dstStride;\
-        src12 = *s; s+=srcStride;\
-        OP(*d , (src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));d+=dstStride;\
-        src13 = *s; s+=srcStride;\
-        OP(*d, (src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));d+=dstStride;\
-        src14 = *s; s+=srcStride;\
-        OP(*d, (src11+src12)*20 - (src10+src13)*5 + (src9 +src14));d+=dstStride;\
-        src15 = *s; s+=srcStride;\
-        OP(*d, (src12+src13)*20 - (src11+src14)*5 + (src10+src15));d+=dstStride;\
-        src16 = *s; s+=srcStride;\
-        OP(*d, (src13+src14)*20 - (src12+src15)*5 + (src11+src16));d+=dstStride;\
-        src17 = *s; s+=srcStride;\
-        OP(*d, (src14+src15)*20 - (src13+src16)*5 + (src12+src17));d+=dstStride;\
-        src18 = *s; s+=srcStride;\
-        OP(*d, (src15+src16)*20 - (src14+src17)*5 + (src13+src18));d+=dstStride;\
-       } \
-      } \
-        dst++;\
-        src++;\
-    }while(--w);\
-}\
-\
-static inline void OPNAME ## h264_qpel_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride,int w,int h){\
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;\
-    int i;\
-    src -= 2*srcStride;\
-    i= h+5; \
-    do {\
-        int srcB,srcA,src0,src1,src2,src3,src4,src5,src6;\
-        uint8_t *s = src-2;\
-        srcB = *s++;\
-        srcA = *s++;\
-        src0 = *s++;\
-        src1 = *s++;\
-        src2 = *s++;\
-        src3 = *s++;\
-        tmp[0] = ((src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
-        src4 = *s++;\
-        tmp[1] = ((src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
-        src5 = *s++;\
-        tmp[2] = ((src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
-        src6 = *s++;\
-        tmp[3] = ((src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
-      if (w>4) { /* it optimized */ \
-        int src7,src8,src9,src10; \
-        src7 = *s++;\
-        tmp[4] = ((src4+src5)*20 - (src3+src6)*5 + (src2+src7));\
-        src8 = *s++;\
-        tmp[5] = ((src5+src6)*20 - (src4+src7)*5 + (src3+src8));\
-        src9 = *s++;\
-        tmp[6] = ((src6+src7)*20 - (src5+src8)*5 + (src4+src9));\
-        src10 = *s++;\
-        tmp[7] = ((src7+src8)*20 - (src6+src9)*5 + (src5+src10));\
-       if (w>8) { \
-        int src11,src12,src13,src14,src15,src16,src17,src18; \
-        src11 = *s++;\
-        tmp[8] = ((src8 +src9 )*20 - (src7 +src10)*5 + (src6 +src11));\
-        src12 = *s++;\
-        tmp[9] = ((src9 +src10)*20 - (src8 +src11)*5 + (src7 +src12));\
-        src13 = *s++;\
-        tmp[10] = ((src10+src11)*20 - (src9 +src12)*5 + (src8 +src13));\
-        src14 = *s++;\
-        tmp[11] = ((src11+src12)*20 - (src10+src13)*5 + (src9 +src14));\
-        src15 = *s++;\
-        tmp[12] = ((src12+src13)*20 - (src11+src14)*5 + (src10+src15));\
-        src16 = *s++;\
-        tmp[13] = ((src13+src14)*20 - (src12+src15)*5 + (src11+src16));\
-        src17 = *s++;\
-        tmp[14] = ((src14+src15)*20 - (src13+src16)*5 + (src12+src17));\
-        src18 = *s++;\
-        tmp[15] = ((src15+src16)*20 - (src14+src17)*5 + (src13+src18));\
-       } \
-      } \
-        tmp+=tmpStride;\
-        src+=srcStride;\
-    }while(--i);\
-    tmp -= tmpStride*(h+5-2);\
-    i = w; \
-    do {\
-        int tmpB,tmpA,tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6;\
-        int16_t *s = tmp-2*tmpStride; \
-        uint8_t *d=dst;\
-        tmpB = *s; s+=tmpStride;\
-        tmpA = *s; s+=tmpStride;\
-        tmp0 = *s; s+=tmpStride;\
-        tmp1 = *s; s+=tmpStride;\
-        tmp2 = *s; s+=tmpStride;\
-        tmp3 = *s; s+=tmpStride;\
-        OP2(*d, (tmp0+tmp1)*20 - (tmpA+tmp2)*5 + (tmpB+tmp3));d+=dstStride;\
-        tmp4 = *s; s+=tmpStride;\
-        OP2(*d, (tmp1+tmp2)*20 - (tmp0+tmp3)*5 + (tmpA+tmp4));d+=dstStride;\
-        tmp5 = *s; s+=tmpStride;\
-        OP2(*d, (tmp2+tmp3)*20 - (tmp1+tmp4)*5 + (tmp0+tmp5));d+=dstStride;\
-        tmp6 = *s; s+=tmpStride;\
-        OP2(*d, (tmp3+tmp4)*20 - (tmp2+tmp5)*5 + (tmp1+tmp6));d+=dstStride;\
-      if (h>4) { \
-        int tmp7,tmp8,tmp9,tmp10; \
-        tmp7 = *s; s+=tmpStride;\
-        OP2(*d, (tmp4+tmp5)*20 - (tmp3+tmp6)*5 + (tmp2+tmp7));d+=dstStride;\
-        tmp8 = *s; s+=tmpStride;\
-        OP2(*d, (tmp5+tmp6)*20 - (tmp4+tmp7)*5 + (tmp3+tmp8));d+=dstStride;\
-        tmp9 = *s; s+=tmpStride;\
-        OP2(*d, (tmp6+tmp7)*20 - (tmp5+tmp8)*5 + (tmp4+tmp9));d+=dstStride;\
-        tmp10 = *s; s+=tmpStride;\
-        OP2(*d, (tmp7+tmp8)*20 - (tmp6+tmp9)*5 + (tmp5+tmp10));d+=dstStride;\
-       if (h>8) { \
-        int tmp11,tmp12,tmp13,tmp14,tmp15,tmp16,tmp17,tmp18; \
-        tmp11 = *s; s+=tmpStride;\
-        OP2(*d , (tmp8 +tmp9 )*20 - (tmp7 +tmp10)*5 + (tmp6 +tmp11));d+=dstStride;\
-        tmp12 = *s; s+=tmpStride;\
-        OP2(*d , (tmp9 +tmp10)*20 - (tmp8 +tmp11)*5 + (tmp7 +tmp12));d+=dstStride;\
-        tmp13 = *s; s+=tmpStride;\
-        OP2(*d, (tmp10+tmp11)*20 - (tmp9 +tmp12)*5 + (tmp8 +tmp13));d+=dstStride;\
-        tmp14 = *s; s+=tmpStride;\
-        OP2(*d, (tmp11+tmp12)*20 - (tmp10+tmp13)*5 + (tmp9 +tmp14));d+=dstStride;\
-        tmp15 = *s; s+=tmpStride;\
-        OP2(*d, (tmp12+tmp13)*20 - (tmp11+tmp14)*5 + (tmp10+tmp15));d+=dstStride;\
-        tmp16 = *s; s+=tmpStride;\
-        OP2(*d, (tmp13+tmp14)*20 - (tmp12+tmp15)*5 + (tmp11+tmp16));d+=dstStride;\
-        tmp17 = *s; s+=tmpStride;\
-        OP2(*d, (tmp14+tmp15)*20 - (tmp13+tmp16)*5 + (tmp12+tmp17));d+=dstStride;\
-        tmp18 = *s; s+=tmpStride;\
-        OP2(*d, (tmp15+tmp16)*20 - (tmp14+tmp17)*5 + (tmp13+tmp18));d+=dstStride;\
-       } \
-      } \
-        dst++;\
-        tmp++;\
-    }while(--i);\
-}\
-\
-static void OPNAME ## h264_qpel4_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-    OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,4,4); \
-}\
-static void OPNAME ## h264_qpel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,8,8); \
-}\
-static void OPNAME ## h264_qpel16_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_h_lowpass(dst,src,dstStride,srcStride,16,16); \
-}\
-\
-static void OPNAME ## h264_qpel4_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,4,4); \
-}\
-static void OPNAME ## h264_qpel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,8,8); \
-}\
-static void OPNAME ## h264_qpel16_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\
-   OPNAME ## h264_qpel_v_lowpass(dst,src,dstStride,srcStride,16,16); \
-}\
-static void OPNAME ## h264_qpel4_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
-   OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,4,4); \
-}\
-static void OPNAME ## h264_qpel8_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
-   OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,8,8); \
-}\
-static void OPNAME ## h264_qpel16_hv_lowpass(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
-   OPNAME ## h264_qpel_hv_lowpass(dst,tmp,src,dstStride,tmpStride,srcStride,16,16); \
-}\
-
-#define H264_MC(OPNAME, SIZE) \
-static void OPNAME ## h264_qpel ## SIZE ## _mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## pixels ## SIZE ## _c(dst, src, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc10_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned2(dst, src, half, stride, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc20_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    OPNAME ## h264_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc30_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t half[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(half, src, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned2(dst, src+1, half, stride, stride, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc01_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t half[SIZE*SIZE];\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(half, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, full_mid, half, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc02_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    OPNAME ## h264_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc03_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t half[SIZE*SIZE];\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(half, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, full_mid+SIZE, half, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc11_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc31_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\
-    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc13_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc33_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\
-    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc22_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    OPNAME ## h264_qpel ## SIZE ## _hv_lowpass(dst, tmp, src, stride, SIZE, stride);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc21_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfHV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfHV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc23_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    uint8_t halfH[SIZE*SIZE];\
-    uint8_t halfHV[SIZE*SIZE];\
-    put_h264_qpel ## SIZE ## _h_lowpass(halfH, src + stride, SIZE, stride);\
-    put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfH, halfHV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc12_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    uint8_t halfV[SIZE*SIZE];\
-    uint8_t halfHV[SIZE*SIZE];\
-    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfV, halfHV, stride, SIZE, SIZE, SIZE);\
-}\
-\
-static void OPNAME ## h264_qpel ## SIZE ## _mc32_sh4(uint8_t *dst, uint8_t *src, int stride){\
-    uint8_t full[SIZE*(SIZE+5)];\
-    uint8_t * const full_mid= full + SIZE*2;\
-    int16_t tmp[SIZE*(SIZE+5)];\
-    uint8_t halfV[SIZE*SIZE];\
-    uint8_t halfHV[SIZE*SIZE];\
-    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
-    put_h264_qpel ## SIZE ## _v_lowpass(halfV, full_mid, SIZE, SIZE);\
-    put_h264_qpel ## SIZE ## _hv_lowpass(halfHV, tmp, src, SIZE, SIZE, stride);\
-    OPNAME ## pixels ## SIZE ## _l2_aligned(dst, halfV, halfHV, stride, SIZE, SIZE, SIZE);\
-}\
-
-#define op_avg(a, b)  a = (((a)+cm[((b) + 16)>>5]+1)>>1)
-//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7)
-#define op_put(a, b)  a = cm[((b) + 16)>>5]
-#define op2_avg(a, b)  a = (((a)+cm[((b) + 512)>>10]+1)>>1)
-#define op2_put(a, b)  a = cm[((b) + 512)>>10]
-
-H264_LOWPASS(put_       , op_put, op2_put)
-H264_LOWPASS(avg_       , op_avg, op2_avg)
-H264_MC(put_, 4)
-H264_MC(put_, 8)
-H264_MC(put_, 16)
-H264_MC(avg_, 4)
-H264_MC(avg_, 8)
-H264_MC(avg_, 16)
-
-#undef op_avg
-#undef op_put
-#undef op2_avg
-#undef op2_put
-
-static void wmv2_mspel8_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
-
-    do{
-        int src_1,src0,src1,src2,src3,src4,src5,src6,src7,src8,src9;
-        uint8_t *s = src;
-        src_1 = s[-1];
-        src0 = *s++;
-        src1 = *s++;
-        src2 = *s++;
-        dst[0]= cm[(9*(src0 + src1) - (src_1 + src2) + 8)>>4];
-        src3 = *s++;
-        dst[1]= cm[(9*(src1 + src2) - (src0 + src3) + 8)>>4];
-        src4 = *s++;
-        dst[2]= cm[(9*(src2 + src3) - (src1 + src4) + 8)>>4];
-        src5 = *s++;
-        dst[3]= cm[(9*(src3 + src4) - (src2 + src5) + 8)>>4];
-        src6 = *s++;
-        dst[4]= cm[(9*(src4 + src5) - (src3 + src6) + 8)>>4];
-        src7 = *s++;
-        dst[5]= cm[(9*(src5 + src6) - (src4 + src7) + 8)>>4];
-        src8 = *s++;
-        dst[6]= cm[(9*(src6 + src7) - (src5 + src8) + 8)>>4];
-        src9 = *s++;
-        dst[7]= cm[(9*(src7 + src8) - (src6 + src9) + 8)>>4];
-        dst+=dstStride;
-        src+=srcStride;
-    }while(--h);
-}
-
-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;
-
-    do{
-        int src_1,src0,src1,src2,src3,src4,src5,src6,src7,src8,src9;
-        uint8_t *s = src,*d = dst;
-        src_1 = *(s-srcStride);
-        src0 = *s; s+=srcStride;
-        src1 = *s; s+=srcStride;
-        src2 = *s; s+=srcStride;
-        *d= cm[(9*(src0 + src1) - (src_1 + src2) + 8)>>4]; d+=dstStride;
-        src3 = *s; s+=srcStride;
-        *d= cm[(9*(src1 + src2) - (src0  + src3) + 8)>>4]; d+=dstStride;
-        src4 = *s; s+=srcStride;
-        *d= cm[(9*(src2 + src3) - (src1  + src4) + 8)>>4]; d+=dstStride;
-        src5 = *s; s+=srcStride;
-        *d= cm[(9*(src3 + src4) - (src2  + src5) + 8)>>4]; d+=dstStride;
-        src6 = *s; s+=srcStride;
-        *d= cm[(9*(src4 + src5) - (src3  + src6) + 8)>>4]; d+=dstStride;
-        src7 = *s; s+=srcStride;
-        *d= cm[(9*(src5 + src6) - (src4  + src7) + 8)>>4]; d+=dstStride;
-        src8 = *s; s+=srcStride;
-        *d= cm[(9*(src6 + src7) - (src5  + src8) + 8)>>4]; d+=dstStride;
-        src9 = *s;
-        *d= cm[(9*(src7 + src8) - (src6  + src9) + 8)>>4]; d+=dstStride;
-        src++;
-        dst++;
-    }while(--w);
-}
-
-static void put_mspel8_mc00_sh4 (uint8_t *dst, uint8_t *src, int stride){
-    put_pixels8_c(dst, src, stride, 8);
-}
-
-static void put_mspel8_mc10_sh4(uint8_t *dst, uint8_t *src, int stride){
-    uint8_t half[64];
-    wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
-    put_pixels8_l2_aligned2(dst, src, half, stride, stride, 8, 8);
-}
-
-static void put_mspel8_mc20_sh4(uint8_t *dst, uint8_t *src, int stride){
-    wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8);
-}
-
-static void put_mspel8_mc30_sh4(uint8_t *dst, uint8_t *src, int stride){
-    uint8_t half[64];
-    wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
-    put_pixels8_l2_aligned2(dst, src+1, half, stride, stride, 8, 8);
-}
-
-static void put_mspel8_mc02_sh4(uint8_t *dst, uint8_t *src, int stride){
-    wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8);
-}
-
-static void put_mspel8_mc12_sh4(uint8_t *dst, uint8_t *src, int stride){
-    uint8_t halfH[88];
-    uint8_t halfV[64];
-    uint8_t halfHV[64];
-    wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11);
-    wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8);
-    wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8);
-    put_pixels8_l2_aligned(dst, halfV, halfHV, stride, 8, 8, 8);
-}
-static void put_mspel8_mc32_sh4(uint8_t *dst, uint8_t *src, int stride){
-    uint8_t halfH[88];
-    uint8_t halfV[64];
-    uint8_t halfHV[64];
-    wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11);
-    wmv2_mspel8_v_lowpass(halfV, src+1, 8, stride, 8);
-    wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8);
-    put_pixels8_l2_aligned(dst, halfV, halfHV, stride, 8, 8, 8);
-}
-static void put_mspel8_mc22_sh4(uint8_t *dst, uint8_t *src, int stride){
-    uint8_t halfH[88];
-    wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11);
-    wmv2_mspel8_v_lowpass(dst, halfH+8, stride, 8, 8);
-}
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index fda90fe..992e01b 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -80,7 +80,6 @@ static const uint8_t is_audio_command[10] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0 };
 
 typedef struct ShortenContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     GetBitContext gb;
 
     int min_framesize, max_framesize;
@@ -115,17 +114,12 @@ static av_cold int shorten_decode_init(AVCodecContext *avctx)
     s->avctx          = avctx;
     avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int allocate_buffers(ShortenContext *s)
 {
-    int i, chan;
-    int *coeffs;
-    void *tmp_ptr;
+    int i, chan, err;
 
     for (chan = 0; chan < s->channels; chan++) {
         if (FFMAX(1, s->nmean) >= UINT_MAX / sizeof(int32_t)) {
@@ -139,26 +133,21 @@ static int allocate_buffers(ShortenContext *s)
             return AVERROR_INVALIDDATA;
         }
 
-        tmp_ptr =
-            av_realloc(s->offset[chan], sizeof(int32_t) * FFMAX(1, s->nmean));
-        if (!tmp_ptr)
-            return AVERROR(ENOMEM);
-        s->offset[chan] = tmp_ptr;
+        if ((err = av_reallocp(&s->offset[chan],
+                               sizeof(int32_t) *
+                               FFMAX(1, s->nmean))) < 0)
+            return err;
 
-        tmp_ptr = av_realloc(s->decoded_base[chan], (s->blocksize + s->nwrap) *
-                             sizeof(s->decoded_base[0][0]));
-        if (!tmp_ptr)
-            return AVERROR(ENOMEM);
-        s->decoded_base[chan] = tmp_ptr;
+        if ((err = av_reallocp(&s->decoded_base[chan], (s->blocksize + s->nwrap) *
+                               sizeof(s->decoded_base[0][0]))) < 0)
+            return err;
         for (i = 0; i < s->nwrap; i++)
             s->decoded_base[chan][i] = 0;
         s->decoded[chan] = s->decoded_base[chan] + s->nwrap;
     }
 
-    coeffs = av_realloc(s->coeffs, s->nwrap * sizeof(*s->coeffs));
-    if (!coeffs)
-        return AVERROR(ENOMEM);
-    s->coeffs = coeffs;
+    if ((err = av_reallocp(&s->coeffs, s->nwrap * sizeof(*s->coeffs))) < 0)
+        return err;
 
     return 0;
 }
@@ -277,7 +266,8 @@ static void output_buffer(int16_t **samples, int nchan, int blocksize,
     }
 }
 
-static const int fixed_coeffs[3][3] = {
+static const int fixed_coeffs[][3] = {
+    { 0,  0,  0 },
     { 1,  0,  0 },
     { 2, -1,  0 },
     { 3, -3,  1 }
@@ -306,7 +296,12 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel,
     } else {
         /* fixed LPC coeffs */
         pred_order = command;
-        coeffs     = fixed_coeffs[pred_order - 1];
+        if (pred_order >= FF_ARRAY_ELEMS(fixed_coeffs)) {
+            av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n",
+                   pred_order);
+            return AVERROR_INVALIDDATA;
+        }
+        coeffs     = fixed_coeffs[pred_order];
         qshift     = 0;
     }
 
@@ -424,6 +419,7 @@ static int read_header(ShortenContext *s)
 static int shorten_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     ShortenContext *s  = avctx->priv_data;
@@ -488,7 +484,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data,
 
     s->cur_chan = 0;
     while (s->cur_chan < s->channels) {
-        int cmd;
+        unsigned cmd;
         int len;
 
         if (get_bits_left(&s->gb) < 3 + FNSIZE) {
@@ -602,17 +598,16 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data,
             s->cur_chan++;
             if (s->cur_chan == s->channels) {
                 /* get output buffer */
-                s->frame.nb_samples = s->blocksize;
-                if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+                frame->nb_samples = s->blocksize;
+                if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                     return ret;
                 }
                 /* interleave output */
-                output_buffer((int16_t **)s->frame.extended_data, s->channels,
+                output_buffer((int16_t **)frame->extended_data, s->channels,
                               s->blocksize, s->decoded);
 
-                *got_frame_ptr   = 1;
-                *(AVFrame *)data = s->frame;
+                *got_frame_ptr = 1;
             }
         }
     }
@@ -654,6 +649,7 @@ static av_cold int shorten_decode_close(AVCodecContext *avctx)
 
 AVCodec ff_shorten_decoder = {
     .name           = "shorten",
+    .long_name      = NULL_IF_CONFIG_SMALL("Shorten"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_SHORTEN,
     .priv_data_size = sizeof(ShortenContext),
@@ -661,7 +657,6 @@ AVCodec ff_shorten_decoder = {
     .close          = shorten_decode_close,
     .decode         = shorten_decode_frame,
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Shorten"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/simple_idct.c b/libavcodec/simple_idct.c
index 5812a87..f61e9e6 100644
--- a/libavcodec/simple_idct.c
+++ b/libavcodec/simple_idct.c
@@ -27,7 +27,6 @@
 
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mathops.h"
 #include "simple_idct.h"
 
@@ -50,7 +49,7 @@
    and the butterfly must be multiplied by 0.5 * sqrt(2.0) */
 #define C_SHIFT (4+1+12)
 
-static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col)
+static inline void idct4col_put(uint8_t *dest, int line_size, const int16_t *col)
 {
     int c0, c1, c2, c3, a0, a1, a2, a3;
 
@@ -86,10 +85,10 @@ static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col
 /* XXX: I think a 1.0/sqrt(2) normalization should be needed to
    compensate the extra butterfly stage - I don't have the full DV
    specification */
-void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct248_put(uint8_t *dest, int line_size, int16_t *block)
 {
     int i;
-    DCTELEM *ptr;
+    int16_t *ptr;
 
     /* butterfly */
     ptr = block;
@@ -129,7 +128,7 @@ void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block)
 #define C2 C_FIX(0.2705980501)
 #define C3 C_FIX(0.5)
 #define C_SHIFT (4+1+12)
-static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col)
+static inline void idct4col_add(uint8_t *dest, int line_size, const int16_t *col)
 {
     int c0, c1, c2, c3, a0, a1, a2, a3;
 
@@ -156,7 +155,7 @@ static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col
 #define R2 R_FIX(0.2705980501)
 #define R3 R_FIX(0.5)
 #define R_SHIFT 11
-static inline void idct4row(DCTELEM *row)
+static inline void idct4row(int16_t *row)
 {
     int c0, c1, c2, c3, a0, a1, a2, a3;
 
@@ -174,7 +173,7 @@ static inline void idct4row(DCTELEM *row)
     row[3]= (c0 - c1) >> R_SHIFT;
 }
 
-void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct84_add(uint8_t *dest, int line_size, int16_t *block)
 {
     int i;
 
@@ -189,7 +188,7 @@ void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block)
     }
 }
 
-void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct48_add(uint8_t *dest, int line_size, int16_t *block)
 {
     int i;
 
@@ -204,7 +203,7 @@ void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block)
     }
 }
 
-void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct44_add(uint8_t *dest, int line_size, int16_t *block)
 {
     int i;
 
@@ -219,7 +218,7 @@ void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block)
     }
 }
 
-void ff_prores_idct(DCTELEM *block, const int16_t *qmat)
+void ff_prores_idct(int16_t *block, const int16_t *qmat)
 {
     int i;
 
diff --git a/libavcodec/simple_idct.h b/libavcodec/simple_idct.h
index 6e22158..e257290 100644
--- a/libavcodec/simple_idct.h
+++ b/libavcodec/simple_idct.h
@@ -29,30 +29,29 @@
 #define AVCODEC_SIMPLE_IDCT_H
 
 #include <stdint.h>
-#include "dsputil.h"
 
-void ff_simple_idct_put_8(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_add_8(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_8(DCTELEM *block);
+void ff_simple_idct_put_8(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_add_8(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_8(int16_t *block);
 
-void ff_simple_idct_put_10(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_add_10(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct_10(DCTELEM *block);
+void ff_simple_idct_put_10(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_add_10(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct_10(int16_t *block);
 /**
  * Special version of ff_simple_idct_10() which does dequantization
  * and scales by a factor of 2 more between the two IDCTs to account
  * for larger scale of input coefficients.
  */
-void ff_prores_idct(DCTELEM *block, const int16_t *qmat);
+void ff_prores_idct(int16_t *block, const int16_t *qmat);
 
 void ff_simple_idct_mmx(int16_t *block);
 void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block);
 void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block);
 
-void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct248_put(uint8_t *dest, int line_size, int16_t *block);
 
-void ff_simple_idct84_add(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct48_add(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_simple_idct44_add(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_simple_idct84_add(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct48_add(uint8_t *dest, int line_size, int16_t *block);
+void ff_simple_idct44_add(uint8_t *dest, int line_size, int16_t *block);
 
 #endif /* AVCODEC_SIMPLE_IDCT_H */
diff --git a/libavcodec/simple_idct_template.c b/libavcodec/simple_idct_template.c
index 3c855e3..367bc34 100644
--- a/libavcodec/simple_idct_template.c
+++ b/libavcodec/simple_idct_template.c
@@ -85,7 +85,7 @@
 
 #endif
 
-static inline void FUNC(idctRowCondDC)(DCTELEM *row, int extra_shift)
+static inline void FUNC(idctRowCondDC)(int16_t *row, int extra_shift)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -221,7 +221,7 @@ static inline void FUNC(idctRowCondDC)(DCTELEM *row, int extra_shift)
     } while (0)
 
 static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size,
-                                          DCTELEM *col)
+                                          int16_t *col)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -245,7 +245,7 @@ static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size,
 }
 
 static inline void FUNC(idctSparseColAdd)(pixel *dest, int line_size,
-                                          DCTELEM *col)
+                                          int16_t *col)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -268,7 +268,7 @@ static inline void FUNC(idctSparseColAdd)(pixel *dest, int line_size,
     dest[0] = av_clip_pixel(dest[0] + ((a0 - b0) >> COL_SHIFT));
 }
 
-static inline void FUNC(idctSparseCol)(DCTELEM *col)
+static inline void FUNC(idctSparseCol)(int16_t *col)
 {
     int a0, a1, a2, a3, b0, b1, b2, b3;
 
@@ -284,7 +284,7 @@ static inline void FUNC(idctSparseCol)(DCTELEM *col)
     col[56] = ((a0 - b0) >> COL_SHIFT);
 }
 
-void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, DCTELEM *block)
+void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, int16_t *block)
 {
     pixel *dest = (pixel *)dest_;
     int i;
@@ -298,7 +298,7 @@ void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, DCTELEM *block)
         FUNC(idctSparseColPut)(dest + i, line_size, block + i);
 }
 
-void FUNC(ff_simple_idct_add)(uint8_t *dest_, int line_size, DCTELEM *block)
+void FUNC(ff_simple_idct_add)(uint8_t *dest_, int line_size, int16_t *block)
 {
     pixel *dest = (pixel *)dest_;
     int i;
@@ -312,7 +312,7 @@ void FUNC(ff_simple_idct_add)(uint8_t *dest_, int line_size, DCTELEM *block)
         FUNC(idctSparseColAdd)(dest + i, line_size, block + i);
 }
 
-void FUNC(ff_simple_idct)(DCTELEM *block)
+void FUNC(ff_simple_idct)(int16_t *block)
 {
     int i;
 
diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c
index d482b0f..98607f2 100644
--- a/libavcodec/sipr.c
+++ b/libavcodec/sipr.c
@@ -26,11 +26,11 @@
 #include <string.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/mathematics.h"
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
-#include "dsputil.h"
 #include "internal.h"
 
 #include "lsp.h"
@@ -240,7 +240,7 @@ static void eval_ir(const float *Az, int pitch_lag, float *freq,
     float tmp1[SUBFR_SIZE+1], tmp2[LP_FILTER_ORDER+1];
     int i;
 
-    tmp1[0] = 1.;
+    tmp1[0] = 1.0;
     for (i = 0; i < LP_FILTER_ORDER; i++) {
         tmp1[i+1] = Az[i] * ff_pow_0_55[i];
         tmp2[i  ] = Az[i] * ff_pow_0_7 [i];
@@ -411,9 +411,10 @@ static void decode_frame(SiprContext *ctx, SiprParameters *params,
         convolute_with_sparse(fixed_vector, &fixed_cb, impulse_response,
                               SUBFR_SIZE);
 
-        avg_energy =
-            (0.01 + ff_scalarproduct_float_c(fixed_vector, fixed_vector, SUBFR_SIZE)) /
-                SUBFR_SIZE;
+        avg_energy = (0.01 + avpriv_scalarproduct_float_c(fixed_vector,
+                                                          fixed_vector,
+                                                          SUBFR_SIZE)) /
+                     SUBFR_SIZE;
 
         ctx->past_pitch_gain = pitch_gain = gain_cb[params->gc_index[i]][0];
 
@@ -454,9 +455,9 @@ static void decode_frame(SiprContext *ctx, SiprParameters *params,
 
     if (ctx->mode == MODE_5k0) {
         for (i = 0; i < subframe_count; i++) {
-            float energy = ff_scalarproduct_float_c(ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE,
-                                                    ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE,
-                                                    SUBFR_SIZE);
+            float energy = avpriv_scalarproduct_float_c(ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE,
+                                                        ctx->postfilter_syn5k0 + LP_FILTER_ORDER + i * SUBFR_SIZE,
+                                                        SUBFR_SIZE);
             ff_adaptive_gain_control(&synth[i * SUBFR_SIZE],
                                      &synth[i * SUBFR_SIZE], energy,
                                      SUBFR_SIZE, 0.9, &ctx->postfilter_agc);
@@ -515,9 +516,6 @@ static av_cold int sipr_decoder_init(AVCodecContext * avctx)
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_FLT;
 
-    avcodec_get_frame_defaults(&ctx->frame);
-    avctx->coded_frame = &ctx->frame;
-
     return 0;
 }
 
@@ -525,6 +523,7 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
     SiprContext *ctx = avctx->priv_data;
+    AVFrame *frame   = data;
     const uint8_t *buf=avpkt->data;
     SiprParameters parm;
     const SiprModeParam *mode_par = &modes[ctx->mode];
@@ -542,13 +541,13 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    ctx->frame.nb_samples = mode_par->frames_per_packet * subframe_size *
-                            mode_par->subframe_count;
-    if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    frame->nb_samples = mode_par->frames_per_packet * subframe_size *
+                        mode_par->subframe_count;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (float *)ctx->frame.data[0];
+    samples = (float *)frame->data[0];
 
     init_get_bits(&gb, buf, mode_par->bits_per_frame);
 
@@ -560,19 +559,18 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data,
         samples += subframe_size * mode_par->subframe_count;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = ctx->frame;
+    *got_frame_ptr = 1;
 
     return mode_par->bits_per_frame >> 3;
 }
 
 AVCodec ff_sipr_decoder = {
     .name           = "sipr",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio SIPR / ACELP.NET"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_SIPR,
     .priv_data_size = sizeof(SiprContext),
     .init           = sipr_decoder_init,
     .decode         = sipr_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio SIPR / ACELP.NET"),
 };
diff --git a/libavcodec/sipr.h b/libavcodec/sipr.h
index 5007c75..4cdea67 100644
--- a/libavcodec/sipr.h
+++ b/libavcodec/sipr.h
@@ -25,7 +25,6 @@
 #define AVCODEC_SIPR_H
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "acelp_pitch_delay.h"
 #include "libavutil/mem.h"
 
@@ -65,7 +64,6 @@ typedef struct SiprParameters {
 
 typedef struct SiprContext {
     AVCodecContext *avctx;
-    AVFrame frame;
 
     SiprMode mode;
 
diff --git a/libavcodec/sipr16k.c b/libavcodec/sipr16k.c
index bff739e..f7fcb34 100644
--- a/libavcodec/sipr16k.c
+++ b/libavcodec/sipr16k.c
@@ -24,9 +24,10 @@
 #include <math.h>
 
 #include "sipr.h"
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/mathematics.h"
-#include "dsputil.h"
 #include "lsp.h"
 #include "celp_filters.h"
 #include "acelp_vectors.h"
@@ -163,11 +164,11 @@ static float acelp_decode_gain_codef(float gain_corr_factor, const float *fc_v,
                                      const float *ma_prediction_coeff,
                                      int subframe_size, int ma_pred_order)
 {
-    mr_energy +=
-        ff_scalarproduct_float_c(quant_energy, ma_prediction_coeff, ma_pred_order);
+    mr_energy += avpriv_scalarproduct_float_c(quant_energy, ma_prediction_coeff,
+                                              ma_pred_order);
 
     mr_energy = gain_corr_factor * exp(M_LN10 / 20. * mr_energy) /
-        sqrt((0.01 + ff_scalarproduct_float_c(fc_v, fc_v, subframe_size)));
+        sqrt((0.01 + avpriv_scalarproduct_float_c(fc_v, fc_v, subframe_size)));
     return mr_energy;
 }
 
@@ -268,7 +269,7 @@ void ff_sipr_decode_frame_16k(SiprContext *ctx, SiprParameters *params,
     memcpy(ctx->iir_mem, Az[1], LP_FILTER_ORDER_16k * sizeof(float));
 }
 
-void ff_sipr_init_16k(SiprContext *ctx)
+av_cold void ff_sipr_init_16k(SiprContext *ctx)
 {
     int i;
 
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 2baf059..ba69303 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -48,7 +48,7 @@
  */
 typedef struct SmackVContext {
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *pic;
 
     int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl;
     int mmap_last[3], mclr_last[3], full_last[3], type_last[3];
@@ -200,6 +200,11 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
     tmp2.bits = av_mallocz(256 * 4);
     tmp2.lengths = av_mallocz(256 * sizeof(int));
     tmp2.values = av_mallocz(256 * sizeof(int));
+    if (!tmp1.bits || !tmp1.lengths || !tmp1.values ||
+        !tmp2.bits || !tmp2.lengths || !tmp2.values) {
+        err = AVERROR(ENOMEM);
+        goto error;
+    }
 
     if(get_bits1(gb)) {
         smacker_decode_tree(gb, &tmp1, 0, 0);
@@ -209,7 +214,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
                     tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE);
         if(res < 0) {
             av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
-            return -1;
+            err = res;
+            goto error;
         }
     } else {
         av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n");
@@ -222,7 +228,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
                     tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE);
         if(res < 0) {
             av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
-            return -1;
+            err = res;
+            goto error;
         }
     } else {
         av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n");
@@ -250,6 +257,10 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
     huff.maxlength = 0;
     huff.current = 0;
     huff.values = av_mallocz(huff.length * sizeof(int));
+    if (!huff.values) {
+        err = AVERROR(ENOMEM);
+        goto error;
+    }
 
     if (smacker_decode_bigtree(gb, &huff, &ctx) < 0)
         err = -1;
@@ -266,6 +277,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
 
     *recodes = huff.values;
 
+error:
     if(vlc[0].table)
         ff_free_vlc(&vlc[0]);
     if(vlc[1].table)
@@ -294,6 +306,8 @@ static int decode_header_trees(SmackVContext *smk) {
     if(!get_bits1(&gb)) {
         av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n");
         smk->mmap_tbl = av_malloc(sizeof(int) * 2);
+        if (!smk->mmap_tbl)
+            return AVERROR(ENOMEM);
         smk->mmap_tbl[0] = 0;
         smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1;
     } else {
@@ -303,6 +317,8 @@ static int decode_header_trees(SmackVContext *smk) {
     if(!get_bits1(&gb)) {
         av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n");
         smk->mclr_tbl = av_malloc(sizeof(int) * 2);
+        if (!smk->mclr_tbl)
+            return AVERROR(ENOMEM);
         smk->mclr_tbl[0] = 0;
         smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1;
     } else {
@@ -312,6 +328,8 @@ static int decode_header_trees(SmackVContext *smk) {
     if(!get_bits1(&gb)) {
         av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n");
         smk->full_tbl = av_malloc(sizeof(int) * 2);
+        if (!smk->full_tbl)
+            return AVERROR(ENOMEM);
         smk->full_tbl[0] = 0;
         smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1;
     } else {
@@ -321,6 +339,8 @@ static int decode_header_trees(SmackVContext *smk) {
     if(!get_bits1(&gb)) {
         av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n");
         smk->type_tbl = av_malloc(sizeof(int) * 2);
+        if (!smk->type_tbl)
+            return AVERROR(ENOMEM);
         smk->type_tbl[0] = 0;
         smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1;
     } else {
@@ -364,30 +384,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     GetByteContext gb2;
     GetBitContext gb;
     int blocks, blk, bw, bh;
-    int i;
+    int i, ret;
     int stride;
     int flags;
 
     if (avpkt->size <= 769)
         return 0;
 
-    smk->pic.reference = 1;
-    smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if(avctx->reget_buffer(avctx, &smk->pic) < 0){
+    if ((ret = ff_reget_buffer(avctx, smk->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* make the palette available on the way out */
-    pal = (uint32_t*)smk->pic.data[1];
+    pal = (uint32_t*)smk->pic->data[1];
     bytestream2_init(&gb2, avpkt->data, avpkt->size);
     flags = bytestream2_get_byteu(&gb2);
-    smk->pic.palette_has_changed = flags & 1;
-    smk->pic.key_frame = !!(flags & 2);
-    if(smk->pic.key_frame)
-        smk->pic.pict_type = AV_PICTURE_TYPE_I;
+    smk->pic->palette_has_changed = flags & 1;
+    smk->pic->key_frame = !!(flags & 2);
+    if(smk->pic->key_frame)
+        smk->pic->pict_type = AV_PICTURE_TYPE_I;
     else
-        smk->pic.pict_type = AV_PICTURE_TYPE_P;
+        smk->pic->pict_type = AV_PICTURE_TYPE_P;
 
     for(i = 0; i < 256; i++)
         *pal++ = bytestream2_get_be24u(&gb2);
@@ -402,8 +420,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     bw = avctx->width >> 2;
     bh = avctx->height >> 2;
     blocks = bw * bh;
-    out = smk->pic.data[0];
-    stride = smk->pic.linesize[0];
+    out = smk->pic->data[0];
+    stride = smk->pic->linesize[0];
     while(blk < blocks) {
         int type, run, mode;
         uint16_t pix;
@@ -417,7 +435,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                 int hi, lo;
                 clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last);
                 map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last);
-                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
+                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                 hi = clr >> 8;
                 lo = clr & 0xFF;
                 for(i = 0; i < 4; i++) {
@@ -438,7 +456,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                 else if(get_bits1(&gb)) mode = 2;
             }
             while(run-- && blk < blocks){
-                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
+                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                 switch(mode){
                 case 0:
                     for(i = 0; i < 4; i++) {
@@ -490,7 +508,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             mode = type >> 8;
             while(run-- && blk < blocks){
                 uint32_t col;
-                out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
+                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
                 col = mode * 0x01010101;
                 for(i = 0; i < 4; i++) {
                     *((uint32_t*)out) = col;
@@ -503,8 +521,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     }
 
+    if ((ret = av_frame_ref(data, smk->pic)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = smk->pic;
 
     /* always report that the buffer was completely consumed */
     return avpkt->size;
@@ -514,6 +534,26 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
 /*
  *
+ * Uninit smacker decoder
+ *
+ */
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+    SmackVContext * const smk = avctx->priv_data;
+
+    av_freep(&smk->mmap_tbl);
+    av_freep(&smk->mclr_tbl);
+    av_freep(&smk->full_tbl);
+    av_freep(&smk->type_tbl);
+
+    av_frame_free(&smk->pic);
+
+    return 0;
+}
+
+
+/*
+ *
  * Init smacker decoder
  *
  */
@@ -525,6 +565,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    c->pic = av_frame_alloc();
+    if (!c->pic)
+        return AVERROR(ENOMEM);
 
     /* decode huffman trees from extradata */
     if(avctx->extradata_size < 16){
@@ -532,43 +575,18 @@ static av_cold int decode_init(AVCodecContext *avctx)
         return -1;
     }
 
-    if (decode_header_trees(c))
+    if (decode_header_trees(c)) {
+        decode_end(avctx);
         return -1;
+    }
 
     return 0;
 }
 
 
 
-/*
- *
- * Uninit smacker decoder
- *
- */
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    SmackVContext * const smk = avctx->priv_data;
-
-    av_freep(&smk->mmap_tbl);
-    av_freep(&smk->mclr_tbl);
-    av_freep(&smk->full_tbl);
-    av_freep(&smk->type_tbl);
-
-    if (smk->pic.data[0])
-        avctx->release_buffer(avctx, &smk->pic);
-
-    return 0;
-}
-
-
-typedef struct SmackerAudioContext {
-    AVFrame frame;
-} SmackerAudioContext;
-
 static av_cold int smka_decode_init(AVCodecContext *avctx)
 {
-    SmackerAudioContext *s = avctx->priv_data;
-
     if (avctx->channels < 1 || avctx->channels > 2) {
         av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
         return AVERROR(EINVAL);
@@ -576,9 +594,6 @@ static av_cold int smka_decode_init(AVCodecContext *avctx)
     avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
     avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -588,7 +603,7 @@ static av_cold int smka_decode_init(AVCodecContext *avctx)
 static int smka_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
 {
-    SmackerAudioContext *s = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     GetBitContext gb;
@@ -628,13 +643,13 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    s->frame.nb_samples = unp_size / (avctx->channels * (bits + 1));
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = unp_size / (avctx->channels * (bits + 1));
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples  = (int16_t *)s->frame.data[0];
-    samples8 =            s->frame.data[0];
+    samples  = (int16_t *)frame->data[0];
+    samples8 =            frame->data[0];
 
     // Initialize
     for(i = 0; i < (1 << (bits + stereo)); i++) {
@@ -644,16 +659,14 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
         h[i].bits = av_mallocz(256 * 4);
         h[i].lengths = av_mallocz(256 * sizeof(int));
         h[i].values = av_mallocz(256 * sizeof(int));
+        if (!h[i].bits || !h[i].lengths || !h[i].values) {
+            ret = AVERROR(ENOMEM);
+            goto error;
+        }
         skip_bits1(&gb);
         if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) {
-            for (; i >= 0; i--) {
-                if (vlc[i].table)
-                    ff_free_vlc(&vlc[i]);
-                av_free(h[i].bits);
-                av_free(h[i].lengths);
-                av_free(h[i].values);
-            }
-            return AVERROR_INVALIDDATA;
+            ret = AVERROR_INVALIDDATA;
+            goto error;
         }
         skip_bits1(&gb);
         if(h[i].current > 1) {
@@ -662,10 +675,12 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
                     h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE);
             if(res < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
-                return -1;
+                ret = AVERROR_INVALIDDATA;
+                goto error;
             }
         }
     }
+    /* this codec relies on wraparound instead of clipping audio */
     if(bits) { //decode 16-bit data
         for(i = stereo; i >= 0; i--)
             pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16);
@@ -684,7 +699,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
                     res = 0;
                 val |= h[3].values[res] << 8;
                 pred[1] += sign_extend(val, 16);
-                *samples++ = av_clip_int16(pred[1]);
+                *samples++ = pred[1];
             } else {
                 if(vlc[0].table)
                     res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
@@ -697,7 +712,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
                     res = 0;
                 val |= h[1].values[res] << 8;
                 pred[0] += sign_extend(val, 16);
-                *samples++ = av_clip_int16(pred[0]);
+                *samples++ = pred[0];
             }
         }
     } else { //8-bit data
@@ -712,18 +727,22 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
                 else
                     res = 0;
                 pred[1] += sign_extend(h[1].values[res], 8);
-                *samples8++ = av_clip_uint8(pred[1]);
+                *samples8++ = pred[1];
             } else {
                 if(vlc[0].table)
                     res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
                 else
                     res = 0;
                 pred[0] += sign_extend(h[0].values[res], 8);
-                *samples8++ = av_clip_uint8(pred[0]);
+                *samples8++ = pred[0];
             }
         }
     }
 
+    *got_frame_ptr = 1;
+    ret = buf_size;
+
+error:
     for(i = 0; i < 4; i++) {
         if(vlc[i].table)
             ff_free_vlc(&vlc[i]);
@@ -732,14 +751,12 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
         av_free(h[i].values);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
-
-    return buf_size;
+    return ret;
 }
 
 AVCodec ff_smacker_decoder = {
     .name           = "smackvid",
+    .long_name      = NULL_IF_CONFIG_SMALL("Smacker video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SMACKVIDEO,
     .priv_data_size = sizeof(SmackVContext),
@@ -747,16 +764,14 @@ AVCodec ff_smacker_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Smacker video"),
 };
 
 AVCodec ff_smackaud_decoder = {
     .name           = "smackaud",
+    .long_name      = NULL_IF_CONFIG_SMALL("Smacker audio"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_SMACKAUDIO,
-    .priv_data_size = sizeof(SmackerAudioContext),
     .init           = smka_decode_init,
     .decode         = smka_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Smacker audio"),
 };
diff --git a/libavcodec/smc.c b/libavcodec/smc.c
index 1834003..46903ab 100644
--- a/libavcodec/smc.c
+++ b/libavcodec/smc.c
@@ -35,6 +35,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #define CPAIR 2
 #define CQUAD 4
@@ -45,7 +46,7 @@
 typedef struct SmcContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     GetByteContext gb;
 
@@ -80,7 +81,7 @@ static void smc_decode_stream(SmcContext *s)
 {
     int width = s->avctx->width;
     int height = s->avctx->height;
-    int stride = s->frame.linesize[0];
+    int stride = s->frame->linesize[0];
     int i;
     int chunk_size;
     int buf_size = (int) (s->gb.buffer_end - s->gb.buffer_start);
@@ -91,9 +92,9 @@ static void smc_decode_stream(SmcContext *s)
     unsigned int color_flags_b;
     unsigned int flag_mask;
 
-    unsigned char *pixels = s->frame.data[0];
+    unsigned char *pixels = s->frame->data[0];
 
-    int image_size = height * s->frame.linesize[0];
+    int image_size = height * s->frame->linesize[0];
     int row_ptr = 0;
     int pixel_ptr = 0;
     int pixel_x, pixel_y;
@@ -111,7 +112,7 @@ static void smc_decode_stream(SmcContext *s)
     int color_octet_index = 0;
 
     /* make the palette available */
-    memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+    memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
 
     bytestream2_skip(&s->gb, 1);
     chunk_size = bytestream2_get_be24(&s->gb);
@@ -401,7 +402,7 @@ static void smc_decode_stream(SmcContext *s)
             break;
 
         case 0xF0:
-            av_log_missing_feature(s->avctx, "0xF0 opcode", 1);
+            avpriv_request_sample(s->avctx, "0xF0 opcode");
             break;
         }
     }
@@ -416,7 +417,9 @@ static av_cold int smc_decode_init(AVCodecContext *avctx)
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -429,26 +432,25 @@ static int smc_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     SmcContext *s = avctx->priv_data;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
+    int ret;
 
     bytestream2_init(&s->gb, buf, buf_size);
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (pal) {
-        s->frame.palette_has_changed = 1;
+        s->frame->palette_has_changed = 1;
         memcpy(s->pal, pal, AVPALETTE_SIZE);
     }
 
     smc_decode_stream(s);
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -458,14 +460,14 @@ static av_cold int smc_decode_end(AVCodecContext *avctx)
 {
     SmcContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
 
 AVCodec ff_smc_decoder = {
     .name           = "smc",
+    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SMC,
     .priv_data_size = sizeof(SmcContext),
@@ -473,5 +475,4 @@ AVCodec ff_smc_decoder = {
     .close          = smc_decode_end,
     .decode         = smc_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"),
 };
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
deleted file mode 100644
index 153e5b2..0000000
--- a/libavcodec/snow.c
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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/intmath.h"
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "dsputil.h"
-#include "dwt.h"
-#include "internal.h"
-#include "snow.h"
-#include "snowdata.h"
-
-#include "rangecoder.h"
-#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){
-    int y, x;
-    IDWTELEM * dst;
-    for(y=0; y<b_h; y++){
-        //FIXME ugly misuse of obmc_stride
-        const uint8_t *obmc1= obmc + y*obmc_stride;
-        const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
-        const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
-        const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
-        dst = slice_buffer_get_line(sb, src_y + y);
-        for(x=0; x<b_w; x++){
-            int v=   obmc1[x] * block[3][x + y*src_stride]
-                    +obmc2[x] * block[2][x + y*src_stride]
-                    +obmc3[x] * block[1][x + y*src_stride]
-                    +obmc4[x] * block[0][x + y*src_stride];
-
-            v <<= 8 - LOG2_OBMC_MAX;
-            if(FRAC_BITS != 8){
-                v >>= 8 - FRAC_BITS;
-            }
-            if(add){
-                v += dst[x + src_x];
-                v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
-                if(v&(~255)) v= ~(v>>31);
-                dst8[x + y*src_stride] = v;
-            }else{
-                dst[x + src_x] -= v;
-            }
-        }
-    }
-}
-
-void ff_snow_reset_contexts(SnowContext *s){ //FIXME better initial contexts
-    int plane_index, level, orientation;
-
-    for(plane_index=0; plane_index<3; plane_index++){
-        for(level=0; level<MAX_DECOMPOSITIONS; level++){
-            for(orientation=level ? 1:0; orientation<4; orientation++){
-                memset(s->plane[plane_index].band[level][orientation].state, MID_STATE, sizeof(s->plane[plane_index].band[level][orientation].state));
-            }
-        }
-    }
-    memset(s->header_state, MID_STATE, sizeof(s->header_state));
-    memset(s->block_state, MID_STATE, sizeof(s->block_state));
-}
-
-int ff_snow_alloc_blocks(SnowContext *s){
-    int w= -((-s->avctx->width )>>LOG2_MB_SIZE);
-    int h= -((-s->avctx->height)>>LOG2_MB_SIZE);
-
-    s->b_width = w;
-    s->b_height= h;
-
-    av_free(s->block);
-    s->block= av_mallocz(w * h * sizeof(BlockNode) << (s->block_max_depth*2));
-    return 0;
-}
-
-static void init_qexp(void){
-    int i;
-    double v=128;
-
-    for(i=0; i<QROOT; i++){
-        ff_qexp[i]= lrintf(v);
-        v *= pow(2, 1.0 / QROOT);
-    }
-}
-static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int b_w, int b_h, int dx, int dy){
-    static const uint8_t weight[64]={
-    8,7,6,5,4,3,2,1,
-    7,7,0,0,0,0,0,1,
-    6,0,6,0,0,0,2,0,
-    5,0,0,5,0,3,0,0,
-    4,0,0,0,4,0,0,0,
-    3,0,0,5,0,3,0,0,
-    2,0,6,0,0,0,2,0,
-    1,7,0,0,0,0,0,1,
-    };
-
-    static const uint8_t brane[256]={
-    0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x11,0x12,0x12,0x12,0x12,0x12,0x12,0x12,
-    0x04,0x05,0xcc,0xcc,0xcc,0xcc,0xcc,0x41,0x15,0x16,0xcc,0xcc,0xcc,0xcc,0xcc,0x52,
-    0x04,0xcc,0x05,0xcc,0xcc,0xcc,0x41,0xcc,0x15,0xcc,0x16,0xcc,0xcc,0xcc,0x52,0xcc,
-    0x04,0xcc,0xcc,0x05,0xcc,0x41,0xcc,0xcc,0x15,0xcc,0xcc,0x16,0xcc,0x52,0xcc,0xcc,
-    0x04,0xcc,0xcc,0xcc,0x41,0xcc,0xcc,0xcc,0x15,0xcc,0xcc,0xcc,0x16,0xcc,0xcc,0xcc,
-    0x04,0xcc,0xcc,0x41,0xcc,0x05,0xcc,0xcc,0x15,0xcc,0xcc,0x52,0xcc,0x16,0xcc,0xcc,
-    0x04,0xcc,0x41,0xcc,0xcc,0xcc,0x05,0xcc,0x15,0xcc,0x52,0xcc,0xcc,0xcc,0x16,0xcc,
-    0x04,0x41,0xcc,0xcc,0xcc,0xcc,0xcc,0x05,0x15,0x52,0xcc,0xcc,0xcc,0xcc,0xcc,0x16,
-    0x44,0x45,0x45,0x45,0x45,0x45,0x45,0x45,0x55,0x56,0x56,0x56,0x56,0x56,0x56,0x56,
-    0x48,0x49,0xcc,0xcc,0xcc,0xcc,0xcc,0x85,0x59,0x5A,0xcc,0xcc,0xcc,0xcc,0xcc,0x96,
-    0x48,0xcc,0x49,0xcc,0xcc,0xcc,0x85,0xcc,0x59,0xcc,0x5A,0xcc,0xcc,0xcc,0x96,0xcc,
-    0x48,0xcc,0xcc,0x49,0xcc,0x85,0xcc,0xcc,0x59,0xcc,0xcc,0x5A,0xcc,0x96,0xcc,0xcc,
-    0x48,0xcc,0xcc,0xcc,0x49,0xcc,0xcc,0xcc,0x59,0xcc,0xcc,0xcc,0x96,0xcc,0xcc,0xcc,
-    0x48,0xcc,0xcc,0x85,0xcc,0x49,0xcc,0xcc,0x59,0xcc,0xcc,0x96,0xcc,0x5A,0xcc,0xcc,
-    0x48,0xcc,0x85,0xcc,0xcc,0xcc,0x49,0xcc,0x59,0xcc,0x96,0xcc,0xcc,0xcc,0x5A,0xcc,
-    0x48,0x85,0xcc,0xcc,0xcc,0xcc,0xcc,0x49,0x59,0x96,0xcc,0xcc,0xcc,0xcc,0xcc,0x5A,
-    };
-
-    static const uint8_t needs[16]={
-    0,1,0,0,
-    2,4,2,0,
-    0,1,0,0,
-    15
-    };
-
-    int x, y, b, r, l;
-    int16_t tmpIt   [64*(32+HTAPS_MAX)];
-    uint8_t tmp2t[3][64*(32+HTAPS_MAX)];
-    int16_t *tmpI= tmpIt;
-    uint8_t *tmp2= tmp2t[0];
-    const uint8_t *hpel[11];
-    assert(dx<16 && dy<16);
-    r= brane[dx + 16*dy]&15;
-    l= brane[dx + 16*dy]>>4;
-
-    b= needs[l] | needs[r];
-    if(p && !p->diag_mc)
-        b= 15;
-
-    if(b&5){
-        for(y=0; y < b_h+HTAPS_MAX-1; y++){
-            for(x=0; x < b_w; x++){
-                int a_1=src[x + HTAPS_MAX/2-4];
-                int a0= src[x + HTAPS_MAX/2-3];
-                int a1= src[x + HTAPS_MAX/2-2];
-                int a2= src[x + HTAPS_MAX/2-1];
-                int a3= src[x + HTAPS_MAX/2+0];
-                int a4= src[x + HTAPS_MAX/2+1];
-                int a5= src[x + HTAPS_MAX/2+2];
-                int a6= src[x + HTAPS_MAX/2+3];
-                int am=0;
-                if(!p || p->fast_mc){
-                    am= 20*(a2+a3) - 5*(a1+a4) + (a0+a5);
-                    tmpI[x]= am;
-                    am= (am+16)>>5;
-                }else{
-                    am= p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6);
-                    tmpI[x]= am;
-                    am= (am+32)>>6;
-                }
-
-                if(am&(~255)) am= ~(am>>31);
-                tmp2[x]= am;
-            }
-            tmpI+= 64;
-            tmp2+= 64;
-            src += stride;
-        }
-        src -= stride*y;
-    }
-    src += HTAPS_MAX/2 - 1;
-    tmp2= tmp2t[1];
-
-    if(b&2){
-        for(y=0; y < b_h; y++){
-            for(x=0; x < b_w+1; x++){
-                int a_1=src[x + (HTAPS_MAX/2-4)*stride];
-                int a0= src[x + (HTAPS_MAX/2-3)*stride];
-                int a1= src[x + (HTAPS_MAX/2-2)*stride];
-                int a2= src[x + (HTAPS_MAX/2-1)*stride];
-                int a3= src[x + (HTAPS_MAX/2+0)*stride];
-                int a4= src[x + (HTAPS_MAX/2+1)*stride];
-                int a5= src[x + (HTAPS_MAX/2+2)*stride];
-                int a6= src[x + (HTAPS_MAX/2+3)*stride];
-                int am=0;
-                if(!p || p->fast_mc)
-                    am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 16)>>5;
-                else
-                    am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 32)>>6;
-
-                if(am&(~255)) am= ~(am>>31);
-                tmp2[x]= am;
-            }
-            src += stride;
-            tmp2+= 64;
-        }
-        src -= stride*y;
-    }
-    src += stride*(HTAPS_MAX/2 - 1);
-    tmp2= tmp2t[2];
-    tmpI= tmpIt;
-    if(b&4){
-        for(y=0; y < b_h; y++){
-            for(x=0; x < b_w; x++){
-                int a_1=tmpI[x + (HTAPS_MAX/2-4)*64];
-                int a0= tmpI[x + (HTAPS_MAX/2-3)*64];
-                int a1= tmpI[x + (HTAPS_MAX/2-2)*64];
-                int a2= tmpI[x + (HTAPS_MAX/2-1)*64];
-                int a3= tmpI[x + (HTAPS_MAX/2+0)*64];
-                int a4= tmpI[x + (HTAPS_MAX/2+1)*64];
-                int a5= tmpI[x + (HTAPS_MAX/2+2)*64];
-                int a6= tmpI[x + (HTAPS_MAX/2+3)*64];
-                int am=0;
-                if(!p || p->fast_mc)
-                    am= (20*(a2+a3) - 5*(a1+a4) + (a0+a5) + 512)>>10;
-                else
-                    am= (p->hcoeff[0]*(a2+a3) + p->hcoeff[1]*(a1+a4) + p->hcoeff[2]*(a0+a5) + p->hcoeff[3]*(a_1+a6) + 2048)>>12;
-                if(am&(~255)) am= ~(am>>31);
-                tmp2[x]= am;
-            }
-            tmpI+= 64;
-            tmp2+= 64;
-        }
-    }
-
-    hpel[ 0]= src;
-    hpel[ 1]= tmp2t[0] + 64*(HTAPS_MAX/2-1);
-    hpel[ 2]= src + 1;
-
-    hpel[ 4]= tmp2t[1];
-    hpel[ 5]= tmp2t[2];
-    hpel[ 6]= tmp2t[1] + 1;
-
-    hpel[ 8]= src + stride;
-    hpel[ 9]= hpel[1] + 64;
-    hpel[10]= hpel[8] + 1;
-
-#define MC_STRIDE(x) (needs[x] ? 64 : stride)
-
-    if(b==15){
-        int dxy = dx / 8 + dy / 8 * 4;
-        const uint8_t *src1 = hpel[dxy    ];
-        const uint8_t *src2 = hpel[dxy + 1];
-        const uint8_t *src3 = hpel[dxy + 4];
-        const uint8_t *src4 = hpel[dxy + 5];
-        int stride1 = MC_STRIDE(dxy);
-        int stride2 = MC_STRIDE(dxy + 1);
-        int stride3 = MC_STRIDE(dxy + 4);
-        int stride4 = MC_STRIDE(dxy + 5);
-        dx&=7;
-        dy&=7;
-        for(y=0; y < b_h; y++){
-            for(x=0; x < b_w; x++){
-                dst[x]= ((8-dx)*(8-dy)*src1[x] + dx*(8-dy)*src2[x]+
-                         (8-dx)*   dy *src3[x] + dx*   dy *src4[x]+32)>>6;
-            }
-            src1+=stride1;
-            src2+=stride2;
-            src3+=stride3;
-            src4+=stride4;
-            dst +=stride;
-        }
-    }else{
-        const uint8_t *src1= hpel[l];
-        const uint8_t *src2= hpel[r];
-        int stride1 = MC_STRIDE(l);
-        int stride2 = MC_STRIDE(r);
-        int a= weight[((dx&7) + (8*(dy&7)))];
-        int b= 8-a;
-        for(y=0; y < b_h; y++){
-            for(x=0; x < b_w; x++){
-                dst[x]= (a*src1[x] + b*src2[x] + 4)>>3;
-            }
-            src1+=stride1;
-            src2+=stride2;
-            dst +=stride;
-        }
-    }
-}
-
-void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){
-    if(block->type & BLOCK_INTRA){
-        int x, y;
-        const unsigned color  = block->color[plane_index];
-        const unsigned color4 = color*0x01010101;
-        if(b_w==32){
-            for(y=0; y < b_h; y++){
-                *(uint32_t*)&dst[0 + y*stride]= color4;
-                *(uint32_t*)&dst[4 + y*stride]= color4;
-                *(uint32_t*)&dst[8 + y*stride]= color4;
-                *(uint32_t*)&dst[12+ y*stride]= color4;
-                *(uint32_t*)&dst[16+ y*stride]= color4;
-                *(uint32_t*)&dst[20+ y*stride]= color4;
-                *(uint32_t*)&dst[24+ y*stride]= color4;
-                *(uint32_t*)&dst[28+ y*stride]= color4;
-            }
-        }else if(b_w==16){
-            for(y=0; y < b_h; y++){
-                *(uint32_t*)&dst[0 + y*stride]= color4;
-                *(uint32_t*)&dst[4 + y*stride]= color4;
-                *(uint32_t*)&dst[8 + y*stride]= color4;
-                *(uint32_t*)&dst[12+ y*stride]= color4;
-            }
-        }else if(b_w==8){
-            for(y=0; y < b_h; y++){
-                *(uint32_t*)&dst[0 + y*stride]= color4;
-                *(uint32_t*)&dst[4 + y*stride]= color4;
-            }
-        }else if(b_w==4){
-            for(y=0; y < b_h; y++){
-                *(uint32_t*)&dst[0 + y*stride]= color4;
-            }
-        }else{
-            for(y=0; y < b_h; y++){
-                for(x=0; x < b_w; x++){
-                    dst[x + y*stride]= color;
-                }
-            }
-        }
-    }else{
-        uint8_t *src= s->last_picture[block->ref].data[plane_index];
-        const int scale= plane_index ?  s->mv_scale : 2*s->mv_scale;
-        int mx= block->mx*scale;
-        int my= block->my*scale;
-        const int dx= mx&15;
-        const int dy= my&15;
-        const int tab_index= 3 - (b_w>>2) + (b_w>>4);
-        sx += (mx>>4) - (HTAPS_MAX/2-1);
-        sy += (my>>4) - (HTAPS_MAX/2-1);
-        src += sx + sy*stride;
-        if(   (unsigned)sx >= w - b_w - (HTAPS_MAX-2)
-           || (unsigned)sy >= h - b_h - (HTAPS_MAX-2)){
-            s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h);
-            src= tmp + MB_SIZE;
-        }
-//        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);
-        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){
-            int y;
-            for(y=0; y<b_h; y+=16){
-                s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride);
-                s->dsp.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride);
-            }
-        }else if(b_w==b_h)
-            s->dsp.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride);
-        else if(b_w==2*b_h){
-            s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst    ,src + 3       + 3*stride,stride);
-            s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride);
-        }else{
-            assert(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);
-        }
-    }
-}
-
-#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);\
-    mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, stride, b_w, b_w, dx, dy);\
-}
-
-mca( 0, 0,16)
-mca( 8, 0,16)
-mca( 0, 8,16)
-mca( 8, 8,16)
-mca( 0, 0,8)
-mca( 8, 0,8)
-mca( 0, 8,8)
-mca( 8, 8,8)
-
-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;
-
-    s->avctx= avctx;
-    s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe
-
-    ff_dsputil_init(&s->dsp, avctx);
-    ff_videodsp_init(&s->vdsp, 8);
-    ff_dwt_init(&s->dwt);
-
-#define mcf(dx,dy)\
-    s->dsp.put_qpel_pixels_tab       [0][dy+dx/4]=\
-    s->dsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\
-        s->dsp.put_h264_qpel_pixels_tab[0][dy+dx/4];\
-    s->dsp.put_qpel_pixels_tab       [1][dy+dx/4]=\
-    s->dsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\
-        s->dsp.put_h264_qpel_pixels_tab[1][dy+dx/4];
-
-    mcf( 0, 0)
-    mcf( 4, 0)
-    mcf( 8, 0)
-    mcf(12, 0)
-    mcf( 0, 4)
-    mcf( 4, 4)
-    mcf( 8, 4)
-    mcf(12, 4)
-    mcf( 0, 8)
-    mcf( 4, 8)
-    mcf( 8, 8)
-    mcf(12, 8)
-    mcf( 0,12)
-    mcf( 4,12)
-    mcf( 8,12)
-    mcf(12,12)
-
-#define mcfh(dx,dy)\
-    s->dsp.put_pixels_tab       [0][dy/4+dx/8]=\
-    s->dsp.put_no_rnd_pixels_tab[0][dy/4+dx/8]=\
-        mc_block_hpel ## dx ## dy ## 16;\
-    s->dsp.put_pixels_tab       [1][dy/4+dx/8]=\
-    s->dsp.put_no_rnd_pixels_tab[1][dy/4+dx/8]=\
-        mc_block_hpel ## dx ## dy ## 8;
-
-    mcfh(0, 0)
-    mcfh(8, 0)
-    mcfh(0, 8)
-    mcfh(8, 8)
-
-    init_qexp();
-
-//    dec += FFMAX(s->chroma_h_shift, s->chroma_v_shift);
-
-    width= s->avctx->width;
-    height= s->avctx->height;
-
-    FF_ALLOCZ_OR_GOTO(avctx, s->spatial_idwt_buffer, width * height * sizeof(IDWTELEM), fail);
-    FF_ALLOCZ_OR_GOTO(avctx, s->spatial_dwt_buffer,  width * height * sizeof(DWTELEM),  fail); //FIXME this does not belong here
-    FF_ALLOCZ_OR_GOTO(avctx, s->temp_dwt_buffer,     width * sizeof(DWTELEM),  fail);
-    FF_ALLOCZ_OR_GOTO(avctx, s->temp_idwt_buffer,    width * sizeof(IDWTELEM), fail);
-    FF_ALLOC_OR_GOTO(avctx,  s->run_buffer,          ((width + 1) >> 1) * ((height + 1) >> 1) * sizeof(*s->run_buffer), fail);
-
-    for(i=0; i<MAX_REF_FRAMES; i++)
-        for(j=0; j<MAX_REF_FRAMES; j++)
-            ff_scale_mv_ref[i][j] = 256*(i+1)/(j+1);
-
-    if ((ret = ff_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);
-}
-
-int ff_snow_common_init_after_header(AVCodecContext *avctx) {
-    SnowContext *s = avctx->priv_data;
-    int plane_index, level, orientation;
-
-    for(plane_index=0; plane_index<3; plane_index++){
-        int w= s->avctx->width;
-        int h= s->avctx->height;
-
-        if(plane_index){
-            w>>= s->chroma_h_shift;
-            h>>= s->chroma_v_shift;
-        }
-        s->plane[plane_index].width = w;
-        s->plane[plane_index].height= h;
-
-        for(level=s->spatial_decomposition_count-1; level>=0; level--){
-            for(orientation=level ? 1 : 0; orientation<4; orientation++){
-                SubBand *b= &s->plane[plane_index].band[level][orientation];
-
-                b->buf= s->spatial_dwt_buffer;
-                b->level= level;
-                b->stride= s->plane[plane_index].width << (s->spatial_decomposition_count - level);
-                b->width = (w + !(orientation&1))>>1;
-                b->height= (h + !(orientation>1))>>1;
-
-                b->stride_line = 1 << (s->spatial_decomposition_count - level);
-                b->buf_x_offset = 0;
-                b->buf_y_offset = 0;
-
-                if(orientation&1){
-                    b->buf += (w+1)>>1;
-                    b->buf_x_offset = (w+1)>>1;
-                }
-                if(orientation>1){
-                    b->buf += b->stride>>1;
-                    b->buf_y_offset = b->stride_line >> 1;
-                }
-                b->ibuf= s->spatial_idwt_buffer + (b->buf - s->spatial_dwt_buffer);
-
-                if(level)
-                    b->parent= &s->plane[plane_index].band[level-1][orientation];
-                //FIXME avoid this realloc
-                av_freep(&b->x_coeff);
-                b->x_coeff=av_mallocz(((b->width+1) * b->height+1)*sizeof(x_and_coeff));
-            }
-            w= (w+1)>>1;
-            h= (h+1)>>1;
-        }
-    }
-
-    return 0;
-}
-
-#define USE_HALFPEL_PLANE 0
-
-static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){
-    int p,x,y;
-
-    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 ls= frame->linesize[p];
-        uint8_t *src= frame->data[p];
-
-        halfpel[1][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
-        halfpel[2][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
-        halfpel[3][p] = (uint8_t*) av_malloc(ls * (h + 2 * EDGE_WIDTH)) + EDGE_WIDTH * (1 + ls);
-
-        halfpel[0][p]= src;
-        for(y=0; y<h; y++){
-            for(x=0; x<w; x++){
-                int i= y*ls + x;
-
-                halfpel[1][p][i]= (20*(src[i] + src[i+1]) - 5*(src[i-1] + src[i+2]) + (src[i-2] + src[i+3]) + 16 )>>5;
-            }
-        }
-        for(y=0; y<h; y++){
-            for(x=0; x<w; x++){
-                int i= y*ls + x;
-
-                halfpel[2][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5;
-            }
-        }
-        src= halfpel[1][p];
-        for(y=0; y<h; y++){
-            for(x=0; x<w; x++){
-                int i= y*ls + x;
-
-                halfpel[3][p][i]= (20*(src[i] + src[i+ls]) - 5*(src[i-ls] + src[i+2*ls]) + (src[i-2*ls] + src[i+3*ls]) + 16 )>>5;
-            }
-        }
-
-//FIXME border!
-    }
-}
-
-void ff_snow_release_buffer(AVCodecContext *avctx)
-{
-    SnowContext *s = avctx->priv_data;
-    int i;
-
-    if(s->last_picture[s->max_ref_frames-1].data[0]){
-        avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]);
-        for(i=0; i<9; i++)
-            if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3])
-                av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3]));
-    }
-}
-
-int ff_snow_frame_start(SnowContext *s){
-   AVFrame tmp;
-   int w= s->avctx->width; //FIXME round up to x16 ?
-   int h= s->avctx->height;
-
-    if (s->current_picture.data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)) {
-        s->dsp.draw_edges(s->current_picture.data[0],
-                          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->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);
-    }
-
-    ff_snow_release_buffer(s->avctx);
-
-    tmp= s->last_picture[s->max_ref_frames-1];
-    memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame));
-    memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);
-    if(USE_HALFPEL_PLANE && s->current_picture.data[0])
-        halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture);
-    s->last_picture[0]= s->current_picture;
-    s->current_picture= tmp;
-
-    if(s->keyframe){
-        s->ref_frames= 0;
-    }else{
-        int i;
-        for(i=0; i<s->max_ref_frames && s->last_picture[i].data[0]; i++)
-            if(i && s->last_picture[i-1].key_frame)
-                break;
-        s->ref_frames= i;
-        if(s->ref_frames==0){
-            av_log(s->avctx,AV_LOG_ERROR, "No reference frames\n");
-            return -1;
-        }
-    }
-
-    s->current_picture.reference= 1;
-    if(ff_get_buffer(s->avctx, &s->current_picture) < 0){
-        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
-    }
-
-    s->current_picture.key_frame= s->keyframe;
-
-    return 0;
-}
-
-av_cold void ff_snow_common_end(SnowContext *s)
-{
-    int plane_index, level, orientation, i;
-
-    av_freep(&s->spatial_dwt_buffer);
-    av_freep(&s->temp_dwt_buffer);
-    av_freep(&s->spatial_idwt_buffer);
-    av_freep(&s->temp_idwt_buffer);
-    av_freep(&s->run_buffer);
-
-    s->m.me.temp= NULL;
-    av_freep(&s->m.me.scratchpad);
-    av_freep(&s->m.me.map);
-    av_freep(&s->m.me.score_map);
-    av_freep(&s->m.obmc_scratchpad);
-
-    av_freep(&s->block);
-    av_freep(&s->scratchbuf);
-    av_freep(&s->emu_edge_buffer);
-
-    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])
-            s->avctx->release_buffer(s->avctx, &s->last_picture[i]);
-    }
-
-    for(plane_index=0; plane_index<3; plane_index++){
-        for(level=s->spatial_decomposition_count-1; level>=0; level--){
-            for(orientation=level ? 1 : 0; orientation<4; orientation++){
-                SubBand *b= &s->plane[plane_index].band[level][orientation];
-
-                av_freep(&b->x_coeff);
-            }
-        }
-    }
-    if (s->mconly_picture.data[0])
-        s->avctx->release_buffer(s->avctx, &s->mconly_picture);
-    if (s->current_picture.data[0])
-        s->avctx->release_buffer(s->avctx, &s->current_picture);
-}
diff --git a/libavcodec/snow.h b/libavcodec/snow.h
deleted file mode 100644
index b988115..0000000
--- a/libavcodec/snow.h
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
- * Copyright (C) 2006 Robert Edele <yartrebo at earthlink.net>
- *
- * 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_SNOW_H
-#define AVCODEC_SNOW_H
-
-#include "dsputil.h"
-#include "dwt.h"
-
-#include "rangecoder.h"
-#include "mathops.h"
-#include "mpegvideo.h"
-
-#define MID_STATE 128
-
-#define MAX_PLANES 4
-#define QSHIFT 5
-#define QROOT (1<<QSHIFT)
-#define LOSSLESS_QLOG -128
-#define FRAC_BITS 4
-#define MAX_REF_FRAMES 8
-
-#define LOG2_OBMC_MAX 8
-#define OBMC_MAX (1<<(LOG2_OBMC_MAX))
-typedef struct BlockNode{
-    int16_t mx;
-    int16_t my;
-    uint8_t ref;
-    uint8_t color[3];
-    uint8_t type;
-//#define TYPE_SPLIT    1
-#define BLOCK_INTRA   1
-#define BLOCK_OPT     2
-//#define TYPE_NOCOLOR  4
-    uint8_t level; //FIXME merge into type?
-}BlockNode;
-
-static const BlockNode null_block= { //FIXME add border maybe
-    .color= {128,128,128},
-    .mx= 0,
-    .my= 0,
-    .ref= 0,
-    .type= 0,
-    .level= 0,
-};
-
-#define LOG2_MB_SIZE 4
-#define MB_SIZE (1<<LOG2_MB_SIZE)
-#define ENCODER_EXTRA_BITS 4
-#define HTAPS_MAX 8
-
-typedef struct x_and_coeff{
-    int16_t x;
-    uint16_t coeff;
-} x_and_coeff;
-
-typedef struct SubBand{
-    int level;
-    int stride;
-    int width;
-    int height;
-    int qlog;        ///< log(qscale)/log[2^(1/6)]
-    DWTELEM *buf;
-    IDWTELEM *ibuf;
-    int buf_x_offset;
-    int buf_y_offset;
-    int stride_line; ///< Stride measured in lines, not pixels.
-    x_and_coeff * x_coeff;
-    struct SubBand *parent;
-    uint8_t state[/*7*2*/ 7 + 512][32];
-}SubBand;
-
-typedef struct Plane{
-    int width;
-    int height;
-    SubBand band[MAX_DECOMPOSITIONS][4];
-
-    int htaps;
-    int8_t hcoeff[HTAPS_MAX/2];
-    int diag_mc;
-    int fast_mc;
-
-    int last_htaps;
-    int8_t last_hcoeff[HTAPS_MAX/2];
-    int last_diag_mc;
-}Plane;
-
-typedef struct SnowContext{
-    AVClass *class;
-    AVCodecContext *avctx;
-    RangeCoder c;
-    DSPContext dsp;
-    VideoDSPContext vdsp;
-    DWTContext dwt;
-    AVFrame new_picture;
-    AVFrame input_picture;              ///< new_picture with the internal linesizes
-    AVFrame current_picture;
-    AVFrame last_picture[MAX_REF_FRAMES];
-    uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4];
-    AVFrame mconly_picture;
-//     uint8_t q_context[16];
-    uint8_t header_state[32];
-    uint8_t block_state[128 + 32*128];
-    int keyframe;
-    int always_reset;
-    int version;
-    int spatial_decomposition_type;
-    int last_spatial_decomposition_type;
-    int temporal_decomposition_type;
-    int spatial_decomposition_count;
-    int last_spatial_decomposition_count;
-    int temporal_decomposition_count;
-    int max_ref_frames;
-    int ref_frames;
-    int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
-    uint32_t *ref_scores[MAX_REF_FRAMES];
-    DWTELEM *spatial_dwt_buffer;
-    DWTELEM *temp_dwt_buffer;
-    IDWTELEM *spatial_idwt_buffer;
-    IDWTELEM *temp_idwt_buffer;
-    int *run_buffer;
-    int colorspace_type;
-    int chroma_h_shift;
-    int chroma_v_shift;
-    int spatial_scalability;
-    int qlog;
-    int last_qlog;
-    int lambda;
-    int lambda2;
-    int pass1_rc;
-    int mv_scale;
-    int last_mv_scale;
-    int qbias;
-    int last_qbias;
-#define QBIAS_SHIFT 3
-    int b_width;
-    int b_height;
-    int block_max_depth;
-    int last_block_max_depth;
-    Plane plane[MAX_PLANES];
-    BlockNode *block;
-#define ME_CACHE_SIZE 1024
-    unsigned me_cache[ME_CACHE_SIZE];
-    unsigned me_cache_generation;
-    slice_buffer sb;
-    int memc_only;
-
-    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)
-
-    uint8_t *scratchbuf;
-    uint8_t *emu_edge_buffer;
-}SnowContext;
-
-/* Tables */
-extern const uint8_t * const ff_obmc_tab[4];
-extern uint8_t ff_qexp[QROOT];
-extern int ff_scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
-
-/* C bits used by mmx/sse2/altivec */
-
-static av_always_inline void snow_interleave_line_header(int * i, int width, IDWTELEM * low, IDWTELEM * high){
-    (*i) = (width) - 2;
-
-    if (width & 1){
-        low[(*i)+1] = low[((*i)+1)>>1];
-        (*i)--;
-    }
-}
-
-static av_always_inline void snow_interleave_line_footer(int * i, IDWTELEM * low, IDWTELEM * high){
-    for (; (*i)>=0; (*i)-=2){
-        low[(*i)+1] = high[(*i)>>1];
-        low[*i] = low[(*i)>>1];
-    }
-}
-
-static av_always_inline void snow_horizontal_compose_lift_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w, int lift_high, int mul, int add, int shift){
-    for(; i<w; i++){
-        dst[i] = src[i] - ((mul * (ref[i] + ref[i + 1]) + add) >> shift);
-    }
-
-    if((width^lift_high)&1){
-        dst[w] = src[w] - ((mul * 2 * ref[w] + add) >> shift);
-    }
-}
-
-static av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w){
-        for(; i<w; i++){
-            dst[i] = src[i] + ((ref[i] + ref[(i+1)]+W_BO + 4 * src[i]) >> W_BS);
-        }
-
-        if(width&1){
-            dst[w] = src[w] + ((2 * ref[w] + W_BO + 4 * src[w]) >> W_BS);
-        }
-}
-
-/* common code */
-
-int ff_snow_common_init(AVCodecContext *avctx);
-int ff_snow_common_init_after_header(AVCodecContext *avctx);
-void ff_snow_common_end(SnowContext *s);
-void ff_snow_release_buffer(AVCodecContext *avctx);
-void ff_snow_reset_contexts(SnowContext *s);
-int ff_snow_alloc_blocks(SnowContext *s);
-int ff_snow_frame_start(SnowContext *s);
-void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride,
-                     int sx, int sy, int b_w, int b_h, BlockNode *block,
-                     int plane_index, int w, int h);
-/* common inline functions */
-//XXX doublecheck all of them should stay inlined
-
-static inline void snow_set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
-    const int w= s->b_width << s->block_max_depth;
-    const int rem_depth= s->block_max_depth - level;
-    const int index= (x + y*w) << rem_depth;
-    const int block_w= 1<<rem_depth;
-    BlockNode block;
-    int i,j;
-
-    block.color[0]= l;
-    block.color[1]= cb;
-    block.color[2]= cr;
-    block.mx= mx;
-    block.my= my;
-    block.ref= ref;
-    block.type= type;
-    block.level= level;
-
-    for(j=0; j<block_w; j++){
-        for(i=0; i<block_w; i++){
-            s->block[index + i + j*w]= block;
-        }
-    }
-}
-
-static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref,
-                           const BlockNode *left, const BlockNode *top, const BlockNode *tr){
-    if(s->ref_frames == 1){
-        *mx = mid_pred(left->mx, top->mx, tr->mx);
-        *my = mid_pred(left->my, top->my, tr->my);
-    }else{
-        const int *scale = ff_scale_mv_ref[ref];
-        *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8,
-                       (top ->mx * scale[top ->ref] + 128) >>8,
-                       (tr  ->mx * scale[tr  ->ref] + 128) >>8);
-        *my = mid_pred((left->my * scale[left->ref] + 128) >>8,
-                       (top ->my * scale[top ->ref] + 128) >>8,
-                       (tr  ->my * scale[tr  ->ref] + 128) >>8);
-    }
-}
-
-static av_always_inline int same_block(BlockNode *a, BlockNode *b){
-    if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){
-        return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2]));
-    }else{
-        return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA));
-    }
-}
-
-//FIXME name cleanup (b_w, block_w, b_width stuff)
-//XXX should we really inline it?
-static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){
-    const int b_width = s->b_width  << s->block_max_depth;
-    const int b_height= s->b_height << s->block_max_depth;
-    const int b_stride= b_width;
-    BlockNode *lt= &s->block[b_x + b_y*b_stride];
-    BlockNode *rt= lt+1;
-    BlockNode *lb= lt+b_stride;
-    BlockNode *rb= lb+1;
-    uint8_t *block[4];
-    int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride;
-    uint8_t *tmp = s->scratchbuf;
-    uint8_t *ptmp;
-    int x,y;
-
-    if(b_x<0){
-        lt= rt;
-        lb= rb;
-    }else if(b_x + 1 >= b_width){
-        rt= lt;
-        rb= lb;
-    }
-    if(b_y<0){
-        lt= lb;
-        rt= rb;
-    }else if(b_y + 1 >= b_height){
-        lb= lt;
-        rb= rt;
-    }
-
-    if(src_x<0){ //FIXME merge with prev & always round internal width up to *16
-        obmc -= src_x;
-        b_w += src_x;
-        if(!sliced && !offset_dst)
-            dst -= src_x;
-        src_x=0;
-    }else if(src_x + b_w > w){
-        b_w = w - src_x;
-    }
-    if(src_y<0){
-        obmc -= src_y*obmc_stride;
-        b_h += src_y;
-        if(!sliced && !offset_dst)
-            dst -= src_y*dst_stride;
-        src_y=0;
-    }else if(src_y + b_h> h){
-        b_h = h - src_y;
-    }
-
-    if(b_w<=0 || b_h<=0) return;
-
-    assert(src_stride > 2*MB_SIZE + 5);
-
-    if(!sliced && offset_dst)
-        dst += src_x + src_y*dst_stride;
-    dst8+= src_x + src_y*src_stride;
-//    src += src_x + src_y*src_stride;
-
-    ptmp= tmp + 3*tmp_step;
-    block[0]= ptmp;
-    ptmp+=tmp_step;
-    ff_snow_pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h);
-
-    if(same_block(lt, rt)){
-        block[1]= block[0];
-    }else{
-        block[1]= ptmp;
-        ptmp+=tmp_step;
-        ff_snow_pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h);
-    }
-
-    if(same_block(lt, lb)){
-        block[2]= block[0];
-    }else if(same_block(rt, lb)){
-        block[2]= block[1];
-    }else{
-        block[2]= ptmp;
-        ptmp+=tmp_step;
-        ff_snow_pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h);
-    }
-
-    if(same_block(lt, rb) ){
-        block[3]= block[0];
-    }else if(same_block(rt, rb)){
-        block[3]= block[1];
-    }else if(same_block(lb, rb)){
-        block[3]= block[2];
-    }else{
-        block[3]= ptmp;
-        ff_snow_pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h);
-    }
-    if(sliced){
-        s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
-    }else{
-        for(y=0; y<b_h; y++){
-            //FIXME ugly misuse of obmc_stride
-            const uint8_t *obmc1= obmc + y*obmc_stride;
-            const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
-            const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
-            const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
-            for(x=0; x<b_w; x++){
-                int v=   obmc1[x] * block[3][x + y*src_stride]
-                        +obmc2[x] * block[2][x + y*src_stride]
-                        +obmc3[x] * block[1][x + y*src_stride]
-                        +obmc4[x] * block[0][x + y*src_stride];
-
-                v <<= 8 - LOG2_OBMC_MAX;
-                if(FRAC_BITS != 8){
-                    v >>= 8 - FRAC_BITS;
-                }
-                if(add){
-                    v += dst[x + y*dst_stride];
-                    v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
-                    if(v&(~255)) v= ~(v>>31);
-                    dst8[x + y*src_stride] = v;
-                }else{
-                    dst[x + y*dst_stride] -= v;
-                }
-            }
-        }
-    }
-}
-
-static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){
-    Plane *p= &s->plane[plane_index];
-    const int mb_w= s->b_width  << s->block_max_depth;
-    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 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;
-
-    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(x=0; x<w; x++){
-                    int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
-                    v >>= FRAC_BITS;
-                    if(v&(~255)) v= ~(v>>31);
-                    dst8[x + y*ref_stride]= v;
-                }
-            }
-        }else{
-            for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
-                for(x=0; x<w; x++){
-                    buf[x + y*w]-= 128<<FRAC_BITS;
-                }
-            }
-        }
-
-        return;
-    }
-
-    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,
-                   w, h,
-                   w, ref_stride, obmc_stride,
-                   mb_x - 1, mb_y - 1,
-                   add, 1, plane_index);
-    }
-}
-
-static av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){
-    const int mb_h= s->b_height << s->block_max_depth;
-    int mb_y;
-    for(mb_y=0; mb_y<=mb_h; mb_y++)
-        predict_slice(s, buf, plane_index, add, mb_y);
-}
-
-static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
-    const int w= s->b_width << s->block_max_depth;
-    const int rem_depth= s->block_max_depth - level;
-    const int index= (x + y*w) << rem_depth;
-    const int block_w= 1<<rem_depth;
-    BlockNode block;
-    int i,j;
-
-    block.color[0]= l;
-    block.color[1]= cb;
-    block.color[2]= cr;
-    block.mx= mx;
-    block.my= my;
-    block.ref= ref;
-    block.type= type;
-    block.level= level;
-
-    for(j=0; j<block_w; j++){
-        for(i=0; i<block_w; i++){
-            s->block[index + i + j*w]= block;
-        }
-    }
-}
-
-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){
-    const int offset[3]= {
-          y*c->  stride + x,
-        ((y*c->uvstride + x)>>1),
-        ((y*c->uvstride + x)>>1),
-    };
-    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);
-}
-
-
-/* bitstream functions */
-
-extern const int8_t ff_quant3bA[256];
-
-#define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
-
-static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
-    int i;
-
-    if(v){
-        const int a= FFABS(v);
-        const int e= av_log2(a);
-        const int el= FFMIN(e, 10);
-        put_rac(c, state+0, 0);
-
-        for(i=0; i<el; i++){
-            put_rac(c, state+1+i, 1);  //1..10
-        }
-        for(; i<e; i++){
-            put_rac(c, state+1+9, 1);  //1..10
-        }
-        put_rac(c, state+1+FFMIN(i,9), 0);
-
-        for(i=e-1; i>=el; i--){
-            put_rac(c, state+22+9, (a>>i)&1); //22..31
-        }
-        for(; i>=0; i--){
-            put_rac(c, state+22+i, (a>>i)&1); //22..31
-        }
-
-        if(is_signed)
-            put_rac(c, state+11 + el, v < 0); //11..21
-    }else{
-        put_rac(c, state+0, 1);
-    }
-}
-
-static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
-    if(get_rac(c, state+0))
-        return 0;
-    else{
-        int i, e, a;
-        e= 0;
-        while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
-            e++;
-        }
-
-        a= 1;
-        for(i=e-1; i>=0; i--){
-            a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
-        }
-
-        e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21
-        return (a^e)-e;
-    }
-}
-
-static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
-    int i;
-    int r= log2>=0 ? 1<<log2 : 1;
-
-    assert(v>=0);
-    assert(log2>=-4);
-
-    while(v >= r){
-        put_rac(c, state+4+log2, 1);
-        v -= r;
-        log2++;
-        if(log2>0) r+=r;
-    }
-    put_rac(c, state+4+log2, 0);
-
-    for(i=log2-1; i>=0; i--){
-        put_rac(c, state+31-i, (v>>i)&1);
-    }
-}
-
-static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
-    int i;
-    int r= log2>=0 ? 1<<log2 : 1;
-    int v=0;
-
-    assert(log2>=-4);
-
-    while(get_rac(c, state+4+log2)){
-        v+= r;
-        log2++;
-        if(log2>0) r+=r;
-    }
-
-    for(i=log2-1; i>=0; i--){
-        v+= get_rac(c, state+31-i)<<i;
-    }
-
-    return v;
-}
-
-static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){
-    const int w= b->width;
-    const int h= b->height;
-    int x,y;
-
-    int run, runs;
-    x_and_coeff *xc= b->x_coeff;
-    x_and_coeff *prev_xc= NULL;
-    x_and_coeff *prev2_xc= xc;
-    x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL;
-    x_and_coeff *prev_parent_xc= parent_xc;
-
-    runs= get_symbol2(&s->c, b->state[30], 0);
-    if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
-    else           run= INT_MAX;
-
-    for(y=0; y<h; y++){
-        int v=0;
-        int lt=0, t=0, rt=0;
-
-        if(y && prev_xc->x == 0){
-            rt= prev_xc->coeff;
-        }
-        for(x=0; x<w; x++){
-            int p=0;
-            const int l= v;
-
-            lt= t; t= rt;
-
-            if(y){
-                if(prev_xc->x <= x)
-                    prev_xc++;
-                if(prev_xc->x == x + 1)
-                    rt= prev_xc->coeff;
-                else
-                    rt=0;
-            }
-            if(parent_xc){
-                if(x>>1 > parent_xc->x){
-                    parent_xc++;
-                }
-                if(x>>1 == parent_xc->x){
-                    p= parent_xc->coeff;
-                }
-            }
-            if(/*ll|*/l|lt|t|rt|p){
-                int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1));
-
-                v=get_rac(&s->c, &b->state[0][context]);
-                if(v){
-                    v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1);
-                    v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l&0xFF] + 3*ff_quant3bA[t&0xFF]]);
-
-                    xc->x=x;
-                    (xc++)->coeff= v;
-                }
-            }else{
-                if(!run){
-                    if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
-                    else           run= INT_MAX;
-                    v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1);
-                    v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]);
-
-                    xc->x=x;
-                    (xc++)->coeff= v;
-                }else{
-                    int max_run;
-                    run--;
-                    v=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);
-                    x+= max_run;
-                    run-= max_run;
-                }
-            }
-        }
-        (xc++)->x= w+1; //end marker
-        prev_xc= prev2_xc;
-        prev2_xc= xc;
-
-        if(parent_xc){
-            if(y&1){
-                while(parent_xc->x != parent->width+1)
-                    parent_xc++;
-                parent_xc++;
-                prev_parent_xc= parent_xc;
-            }else{
-                parent_xc= prev_parent_xc;
-            }
-        }
-    }
-
-    (xc++)->x= w+1; //end marker
-}
-
-#endif /* AVCODEC_SNOW_H */
diff --git a/libavcodec/snowdata.h b/libavcodec/snowdata.h
deleted file mode 100644
index 4a91858..0000000
--- a/libavcodec/snowdata.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
- * Copyright (C) 2006 Robert Edele <yartrebo at earthlink.net>
- *
- * 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_SNOWDATA_H
-#define AVCODEC_SNOWDATA_H
-
-#include "snow.h"
-
-static const uint8_t obmc32[1024]={
-  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8,  8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,
-  0,  4,  4,  4,  8,  8,  8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12,  8,  8,  8,  4,  4,  4,  0,
-  0,  4,  8,  8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12,  8,  8,  4,  0,
-  0,  4,  8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12,  8,  4,  0,
-  4,  8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12,  8,  4,
-  4,  8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12,  8,  4,
-  4,  8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16,  8,  4,
-  4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12,  4,
-  4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12,  4,
-  4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16,  4,
-  4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16,  4,
-  4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16,  4,
-  8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20,  8,
-  8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20,  8,
-  8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20,  8,
-  8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24,  8,
-  8, 24, 40, 56, 68, 84,100,116,132,148,164,180,192,208,224,240,240,224,208,192,180,164,148,132,116,100, 84, 68, 56, 40, 24,  8,
-  8, 20, 36, 52, 64, 80, 96,108,124,136,152,168,180,196,212,224,224,212,196,180,168,152,136,124,108, 96, 80, 64, 52, 36, 20,  8,
-  8, 20, 32, 48, 60, 76, 88,100,116,128,140,156,168,184,196,208,208,196,184,168,156,140,128,116,100, 88, 76, 60, 48, 32, 20,  8,
-  8, 20, 32, 44, 56, 68, 80, 92,108,120,132,144,156,168,180,192,192,180,168,156,144,132,120,108, 92, 80, 68, 56, 44, 32, 20,  8,
-  4, 16, 28, 40, 52, 64, 76, 88, 96,108,120,132,144,156,168,180,180,168,156,144,132,120,108, 96, 88, 76, 64, 52, 40, 28, 16,  4,
-  4, 16, 28, 36, 48, 56, 68, 80, 88,100,112,120,132,140,152,164,164,152,140,132,120,112,100, 88, 80, 68, 56, 48, 36, 28, 16,  4,
-  4, 16, 24, 32, 44, 52, 60, 72, 80, 92,100,108,120,128,136,148,148,136,128,120,108,100, 92, 80, 72, 60, 52, 44, 32, 24, 16,  4,
-  4, 12, 20, 28, 40, 48, 56, 64, 72, 80, 88, 96,108,116,124,132,132,124,116,108, 96, 88, 80, 72, 64, 56, 48, 40, 28, 20, 12,  4,
-  4, 12, 20, 28, 32, 40, 48, 56, 64, 72, 80, 88, 92,100,108,116,116,108,100, 92, 88, 80, 72, 64, 56, 48, 40, 32, 28, 20, 12,  4,
-  4,  8, 16, 24, 28, 36, 44, 48, 56, 60, 68, 76, 80, 88, 96,100,100, 96, 88, 80, 76, 68, 60, 56, 48, 44, 36, 28, 24, 16,  8,  4,
-  4,  8, 12, 20, 24, 32, 36, 40, 48, 52, 56, 64, 68, 76, 80, 84, 84, 80, 76, 68, 64, 56, 52, 48, 40, 36, 32, 24, 20, 12,  8,  4,
-  4,  8, 12, 16, 20, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 68, 64, 60, 56, 52, 48, 44, 40, 32, 28, 24, 20, 16, 12,  8,  4,
-  0,  4,  8, 12, 16, 20, 24, 28, 28, 32, 36, 40, 44, 48, 52, 56, 56, 52, 48, 44, 40, 36, 32, 28, 28, 24, 20, 16, 12,  8,  4,  0,
-  0,  4,  8,  8, 12, 12, 16, 20, 20, 24, 28, 28, 32, 32, 36, 40, 40, 36, 32, 32, 28, 28, 24, 20, 20, 16, 12, 12,  8,  8,  4,  0,
-  0,  4,  4,  4,  8,  8,  8, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 20, 20, 20, 16, 16, 16, 12, 12,  8,  8,  8,  4,  4,  4,  0,
-  0,  0,  0,  0,  4,  4,  4,  4,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8,  8,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,
- //error:0.000020
-};
-static const uint8_t obmc16[256]={
-  0,  4,  4,  8,  8, 12, 12, 16, 16, 12, 12,  8,  8,  4,  4,  0,
-  4,  8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16,  8,  4,
-  4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16,  4,
-  8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20,  8,
-  8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28,  8,
- 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
- 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
- 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
- 16, 44, 76,104,136,164,196,224,224,196,164,136,104, 76, 44, 16,
- 12, 40, 64, 92,116,144,168,196,196,168,144,116, 92, 64, 40, 12,
- 12, 32, 56, 76,100,120,144,164,164,144,120,100, 76, 56, 32, 12,
-  8, 28, 44, 64, 80,100,116,136,136,116,100, 80, 64, 44, 28,  8,
-  8, 20, 36, 48, 64, 76, 92,104,104, 92, 76, 64, 48, 36, 20,  8,
-  4, 16, 24, 36, 44, 56, 64, 76, 76, 64, 56, 44, 36, 24, 16,  4,
-  4,  8, 16, 20, 28, 32, 40, 44, 44, 40, 32, 28, 20, 16,  8,  4,
-  0,  4,  4,  8,  8, 12, 12, 16, 16, 12, 12,  8,  8,  4,  4,  0,
-//error:0.000015
-};
-
-//linear *64
-static const uint8_t obmc8[64]={
-  4, 12, 20, 28, 28, 20, 12,  4,
- 12, 36, 60, 84, 84, 60, 36, 12,
- 20, 60,100,140,140,100, 60, 20,
- 28, 84,140,196,196,140, 84, 28,
- 28, 84,140,196,196,140, 84, 28,
- 20, 60,100,140,140,100, 60, 20,
- 12, 36, 60, 84, 84, 60, 36, 12,
-  4, 12, 20, 28, 28, 20, 12,  4,
-//error:0.000000
-};
-
-//linear *64
-static const uint8_t obmc4[16]={
- 16, 48, 48, 16,
- 48,144,144, 48,
- 48,144,144, 48,
- 16, 48, 48, 16,
-//error:0.000000
-};
-
-const int8_t ff_quant3bA[256]={
- 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, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
- 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
-};
-
-const uint8_t * const ff_obmc_tab[4]= {
-    obmc32, obmc16, obmc8, obmc4
-};
-
-/* runtime generated tables */
-uint8_t ff_qexp[QROOT];
-int ff_scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
-
-
-#endif /* AVCODEC_SNOW_H */
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
deleted file mode 100644
index 603cef0..0000000
--- a/libavcodec/snowdec.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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/intmath.h"
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "dsputil.h"
-#include "dwt.h"
-#include "internal.h"
-#include "snow.h"
-
-#include "rangecoder.h"
-#include "mathops.h"
-
-#include "mpegvideo.h"
-#include "h263.h"
-
-#undef NDEBUG
-#include <assert.h>
-
-static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){
-    Plane *p= &s->plane[plane_index];
-    const int mb_w= s->b_width  << s->block_max_depth;
-    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 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;
-
-    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++){
-//                DWTELEM * line = slice_buffer_get_line(sb, y);
-                IDWTELEM * line = sb->line[y];
-                for(x=0; x<w; x++){
-//                    int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
-                    int v= line[x] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
-                    v >>= FRAC_BITS;
-                    if(v&(~255)) v= ~(v>>31);
-                    dst8[x + y*ref_stride]= v;
-                }
-            }
-        }else{
-            for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
-//                DWTELEM * line = slice_buffer_get_line(sb, y);
-                IDWTELEM * line = sb->line[y];
-                for(x=0; x<w; x++){
-                    line[x] -= 128 << FRAC_BITS;
-//                    buf[x + y*w]-= 128<<FRAC_BITS;
-                }
-            }
-        }
-
-        return;
-    }
-
-    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,
-                   w, h,
-                   w, ref_stride, obmc_stride,
-                   mb_x - 1, mb_y - 1,
-                   add, 0, plane_index);
-    }
-}
-
-static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){
-    const int w= b->width;
-    int y;
-    const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
-    int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
-    int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
-    int new_index = 0;
-
-    if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){
-        qadd= 0;
-        qmul= 1<<QEXPSHIFT;
-    }
-
-    /* If we are on the second or later slice, restore our index. */
-    if (start_y != 0)
-        new_index = save_state[0];
-
-
-    for(y=start_y; y<h; y++){
-        int x = 0;
-        int v;
-        IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset;
-        memset(line, 0, b->width*sizeof(IDWTELEM));
-        v = b->x_coeff[new_index].coeff;
-        x = b->x_coeff[new_index++].x;
-        while(x < w){
-            register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT;
-            register int u= -(v&1);
-            line[x] = (t^u) - u;
-
-            v = b->x_coeff[new_index].coeff;
-            x = b->x_coeff[new_index++].x;
-        }
-    }
-
-    /* Save our variables for the next slice. */
-    save_state[0] = new_index;
-
-    return;
-}
-
-static int decode_q_branch(SnowContext *s, int level, int x, int y){
-    const int w= s->b_width << s->block_max_depth;
-    const int rem_depth= s->block_max_depth - level;
-    const int index= (x + y*w) << rem_depth;
-    int trx= (x+1)<<rem_depth;
-    const BlockNode *left  = x ? &s->block[index-1] : &null_block;
-    const BlockNode *top   = y ? &s->block[index-w] : &null_block;
-    const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
-    const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
-    int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
-    int res;
-
-    if(s->keyframe){
-        set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
-        return 0;
-    }
-
-    if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){
-        int type, mx, my;
-        int l = left->color[0];
-        int cb= left->color[1];
-        int cr= left->color[2];
-        int ref = 0;
-        int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
-        int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx));
-        int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my));
-
-        type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
-
-        if(type){
-            pred_mv(s, &mx, &my, 0, left, top, tr);
-            l += get_symbol(&s->c, &s->block_state[32], 1);
-            cb+= get_symbol(&s->c, &s->block_state[64], 1);
-            cr+= get_symbol(&s->c, &s->block_state[96], 1);
-        }else{
-            if(s->ref_frames > 1)
-                ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
-            if (ref >= s->ref_frames) {
-                av_log(s->avctx, AV_LOG_ERROR, "Invalid ref\n");
-                return AVERROR_INVALIDDATA;
-            }
-            pred_mv(s, &mx, &my, ref, left, top, tr);
-            mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
-            my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);
-        }
-        set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
-    }else{
-        if ((res = decode_q_branch(s, level+1, 2*x+0, 2*y+0)) < 0 ||
-            (res = decode_q_branch(s, level+1, 2*x+1, 2*y+0)) < 0 ||
-            (res = decode_q_branch(s, level+1, 2*x+0, 2*y+1)) < 0 ||
-            (res = decode_q_branch(s, level+1, 2*x+1, 2*y+1)) < 0)
-            return res;
-    }
-    return 0;
-}
-
-static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){
-    const int w= b->width;
-    const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
-    const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
-    const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
-    int x,y;
-
-    if(s->qlog == LOSSLESS_QLOG) return;
-
-    for(y=start_y; y<end_y; y++){
-//        DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
-        IDWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
-        for(x=0; x<w; x++){
-            int i= line[x];
-            if(i<0){
-                line[x]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
-            }else if(i>0){
-                line[x]=  (( i*qmul + qadd)>>(QEXPSHIFT));
-            }
-        }
-    }
-}
-
-static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){
-    const int w= b->width;
-    int x,y;
-
-    IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning
-    IDWTELEM * prev;
-
-    if (start_y != 0)
-        line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
-
-    for(y=start_y; y<end_y; y++){
-        prev = line;
-//        line = slice_buffer_get_line_from_address(sb, src + (y * stride));
-        line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
-        for(x=0; x<w; x++){
-            if(x){
-                if(use_median){
-                    if(y && x+1<w) line[x] += mid_pred(line[x - 1], prev[x], prev[x + 1]);
-                    else  line[x] += line[x - 1];
-                }else{
-                    if(y) line[x] += mid_pred(line[x - 1], prev[x], line[x - 1] + prev[x] - prev[x - 1]);
-                    else  line[x] += line[x - 1];
-                }
-            }else{
-                if(y) line[x] += prev[x];
-            }
-        }
-    }
-}
-
-static void decode_qlogs(SnowContext *s){
-    int plane_index, level, orientation;
-
-    for(plane_index=0; plane_index<3; plane_index++){
-        for(level=0; level<s->spatial_decomposition_count; level++){
-            for(orientation=level ? 1:0; orientation<4; orientation++){
-                int q;
-                if     (plane_index==2) q= s->plane[1].band[level][orientation].qlog;
-                else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog;
-                else                    q= get_symbol(&s->c, s->header_state, 1);
-                s->plane[plane_index].band[level][orientation].qlog= q;
-            }
-        }
-    }
-}
-
-#define GET_S(dst, check) \
-    tmp= get_symbol(&s->c, s->header_state, 0);\
-    if(!(check)){\
-        av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\
-        return -1;\
-    }\
-    dst= tmp;
-
-static int decode_header(SnowContext *s){
-    int plane_index, tmp;
-    uint8_t kstate[32];
-
-    memset(kstate, MID_STATE, sizeof(kstate));
-
-    s->keyframe= get_rac(&s->c, kstate);
-    if(s->keyframe || s->always_reset){
-        ff_snow_reset_contexts(s);
-        s->spatial_decomposition_type=
-        s->qlog=
-        s->qbias=
-        s->mv_scale=
-        s->block_max_depth= 0;
-    }
-    if(s->keyframe){
-        GET_S(s->version, tmp <= 0U)
-        s->always_reset= get_rac(&s->c, s->header_state);
-        s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0);
-        s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0);
-        GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
-        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);
-        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)
-        s->max_ref_frames++;
-
-        decode_qlogs(s);
-    }
-
-    if(!s->keyframe){
-        if(get_rac(&s->c, s->header_state)){
-            for(plane_index=0; plane_index<2; plane_index++){
-                int htaps, i, sum=0;
-                Plane *p= &s->plane[plane_index];
-                p->diag_mc= get_rac(&s->c, s->header_state);
-                htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2;
-                if((unsigned)htaps > HTAPS_MAX || htaps==0)
-                    return -1;
-                p->htaps= htaps;
-                for(i= htaps/2; i; i--){
-                    p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1));
-                    sum += p->hcoeff[i];
-                }
-                p->hcoeff[0]= 32-sum;
-            }
-            s->plane[2].diag_mc= s->plane[1].diag_mc;
-            s->plane[2].htaps  = s->plane[1].htaps;
-            memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff));
-        }
-        if(get_rac(&s->c, s->header_state)){
-            GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
-            decode_qlogs(s);
-        }
-    }
-
-    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);
-        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);
-        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);
-        s->block_max_depth= 0;
-        return -1;
-    }
-
-    return 0;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    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;
-    }
-
-    return 0;
-}
-
-static int decode_blocks(SnowContext *s){
-    int x, y;
-    int w= s->b_width;
-    int h= s->b_height;
-    int res;
-
-    for(y=0; y<h; y++){
-        for(x=0; x<w; x++){
-            if ((res = decode_q_branch(s, 0, x, y)) < 0)
-                return res;
-        }
-    }
-    return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                        AVPacket *avpkt)
-{
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    SnowContext *s = avctx->priv_data;
-    RangeCoder * const c= &s->c;
-    int bytes_read;
-    AVFrame *picture = data;
-    int level, orientation, plane_index;
-    int res;
-
-    ff_init_range_decoder(c, buf, buf_size);
-    ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
-
-    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);
-
-    // 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->plane[0].width,
-                                    s->spatial_idwt_buffer)) < 0)
-        return res;
-
-    for(plane_index=0; plane_index<3; plane_index++){
-        Plane *p= &s->plane[plane_index];
-        p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40
-                                              && p->hcoeff[1]==-10
-                                              && p->hcoeff[2]==2;
-    }
-
-    ff_snow_alloc_blocks(s);
-
-    if(ff_snow_frame_start(s) < 0)
-        return -1;
-    //keyframe flag duplication mess FIXME
-    if(avctx->debug&FF_DEBUG_PICT_INFO)
-        av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog);
-
-    if ((res = decode_blocks(s)) < 0)
-        return res;
-
-    for(plane_index=0; plane_index<3; plane_index++){
-        Plane *p= &s->plane[plane_index];
-        int w= p->width;
-        int h= p->height;
-        int x, y;
-        int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
-
-        if(s->avctx->debug&2048){
-            memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
-            predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
-
-            for(y=0; y<h; y++){
-                for(x=0; x<w; x++){
-                    int v= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x];
-                    s->mconly_picture.data[plane_index][y*s->mconly_picture.linesize[plane_index] + x]= v;
-                }
-            }
-        }
-
-        {
-        for(level=0; level<s->spatial_decomposition_count; level++){
-            for(orientation=level ? 1 : 0; orientation<4; orientation++){
-                SubBand *b= &p->band[level][orientation];
-                unpack_coeffs(s, b, b->parent, orientation);
-            }
-        }
-        }
-
-        {
-        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;
-        int mb_y;
-        DWTCompose cs[MAX_DECOMPOSITIONS];
-        int yd=0, yq=0;
-        int y;
-        int end_y;
-
-        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);
-            if (!(s->keyframe || s->avctx->debug&512)){
-                slice_starty = FFMAX(0, slice_starty - (block_w >> 1));
-                slice_h -= (block_w >> 1);
-            }
-
-            for(level=0; level<s->spatial_decomposition_count; level++){
-                for(orientation=level ? 1 : 0; orientation<4; orientation++){
-                    SubBand *b= &p->band[level][orientation];
-                    int start_y;
-                    int end_y;
-                    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);
-                    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 = FFMIN(b->height, start_y);
-                    end_y = FFMIN(b->height, end_y);
-
-                    if (start_y != end_y){
-                        if (orientation == 0){
-                            SubBand * correlate_band = &p->band[0][0];
-                            int correlate_end_y = FFMIN(b->height, end_y + 1);
-                            int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0));
-                            decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]);
-                            correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y);
-                            dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y);
-                        }
-                        else
-                            decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
-                    }
-                }
-            }
-
-            for(; yd<slice_h; yd+=4){
-                ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, s->temp_idwt_buffer, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
-            }
-
-            if(s->qlog == LOSSLESS_QLOG){
-                for(; yq<slice_h && yq<h; yq++){
-                    IDWTELEM * line = slice_buffer_get_line(&s->sb, yq);
-                    for(x=0; x<w; x++){
-                        line[x] <<= FRAC_BITS;
-                    }
-                }
-            }
-
-            predict_slice_buffered(s, &s->sb, s->spatial_idwt_buffer, plane_index, 1, mb_y);
-
-            y = FFMIN(p->height, slice_starty);
-            end_y = FFMIN(p->height, slice_h);
-            while(y < end_y)
-                ff_slice_buffer_release(&s->sb, y++);
-        }
-
-        ff_slice_buffer_flush(&s->sb);
-        }
-
-    }
-
-    emms_c();
-
-    ff_snow_release_buffer(avctx);
-
-    if(!(s->avctx->debug&2048))
-        *picture= s->current_picture;
-    else
-        *picture= s->mconly_picture;
-
-    *got_frame = 1;
-
-    bytes_read= c->bytestream - c->bytestream_start;
-    if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
-
-    return bytes_read;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    SnowContext *s = avctx->priv_data;
-
-    ff_slice_buffer_destroy(&s->sb);
-
-    ff_snow_common_end(s);
-
-    return 0;
-}
-
-AVCodec ff_snow_decoder = {
-    .name           = "snow",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_SNOW,
-    .priv_data_size = sizeof(SnowContext),
-    .init           = decode_init,
-    .close          = decode_end,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
-    .long_name      = NULL_IF_CONFIG_SMALL("Snow"),
-};
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
deleted file mode 100644
index f93c53f..0000000
--- a/libavcodec/snowenc.c
+++ /dev/null
@@ -1,1939 +0,0 @@
-/*
- * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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/intmath.h"
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "dsputil.h"
-#include "internal.h"
-#include "dwt.h"
-#include "snow.h"
-
-#include "rangecoder.h"
-#include "mathops.h"
-
-#include "mpegvideo.h"
-#include "h263.h"
-
-#undef NDEBUG
-#include <assert.h>
-
-#define QUANTIZE2 0
-
-#if QUANTIZE2==1
-#define Q2_STEP 8
-
-static void find_sse(SnowContext *s, Plane *p, int *score, int score_stride, IDWTELEM *r0, IDWTELEM *r1, int level, int orientation){
-    SubBand *b= &p->band[level][orientation];
-    int x, y;
-    int xo=0;
-    int yo=0;
-    int step= 1 << (s->spatial_decomposition_count - level);
-
-    if(orientation&1)
-        xo= step>>1;
-    if(orientation&2)
-        yo= step>>1;
-
-    //FIXME bias for nonzero ?
-    //FIXME optimize
-    memset(score, 0, sizeof(*score)*score_stride*((p->height + Q2_STEP-1)/Q2_STEP));
-    for(y=0; y<p->height; y++){
-        for(x=0; x<p->width; x++){
-            int sx= (x-xo + step/2) / step / Q2_STEP;
-            int sy= (y-yo + step/2) / step / Q2_STEP;
-            int v= r0[x + y*p->width] - r1[x + y*p->width];
-            assert(sx>=0 && sy>=0 && sx < score_stride);
-            v= ((v+8)>>4)<<4;
-            score[sx + sy*score_stride] += v*v;
-            assert(score[sx + sy*score_stride] >= 0);
-        }
-    }
-}
-
-static void dequantize_all(SnowContext *s, Plane *p, IDWTELEM *buffer, int width, int height){
-    int level, orientation;
-
-    for(level=0; level<s->spatial_decomposition_count; level++){
-        for(orientation=level ? 1 : 0; orientation<4; orientation++){
-            SubBand *b= &p->band[level][orientation];
-            IDWTELEM *dst= buffer + (b->ibuf - s->spatial_idwt_buffer);
-
-            dequantize(s, b, dst, b->stride);
-        }
-    }
-}
-
-static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, int height, int stride, int type){
-    int level, orientation, ys, xs, x, y, pass;
-    IDWTELEM best_dequant[height * stride];
-    IDWTELEM idwt2_buffer[height * stride];
-    const int score_stride= (width + 10)/Q2_STEP;
-    int best_score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size
-    int score[(width + 10)/Q2_STEP * (height + 10)/Q2_STEP]; //FIXME size
-    int threshold= (s->m.lambda * s->m.lambda) >> 6;
-
-    //FIXME pass the copy cleanly ?
-
-//    memcpy(dwt_buffer, buffer, height * stride * sizeof(DWTELEM));
-    ff_spatial_dwt(buffer, s->temp_dwt_buffer, width, height, stride, type, s->spatial_decomposition_count);
-
-    for(level=0; level<s->spatial_decomposition_count; level++){
-        for(orientation=level ? 1 : 0; orientation<4; orientation++){
-            SubBand *b= &p->band[level][orientation];
-            IDWTELEM *dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer);
-             DWTELEM *src=       buffer + (b-> buf - s->spatial_dwt_buffer);
-            assert(src == b->buf); // code does not depend on this but it is true currently
-
-            quantize(s, b, dst, src, b->stride, s->qbias);
-        }
-    }
-    for(pass=0; pass<1; pass++){
-        if(s->qbias == 0) //keyframe
-            continue;
-        for(level=0; level<s->spatial_decomposition_count; level++){
-            for(orientation=level ? 1 : 0; orientation<4; orientation++){
-                SubBand *b= &p->band[level][orientation];
-                IDWTELEM *dst= idwt2_buffer + (b->ibuf - s->spatial_idwt_buffer);
-                IDWTELEM *best_dst= best_dequant + (b->ibuf - s->spatial_idwt_buffer);
-
-                for(ys= 0; ys<Q2_STEP; ys++){
-                    for(xs= 0; xs<Q2_STEP; xs++){
-                        memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
-                        dequantize_all(s, p, idwt2_buffer, width, height);
-                        ff_spatial_idwt(idwt2_buffer, s->temp_idwt_buffer, width, height, stride, type, s->spatial_decomposition_count);
-                        find_sse(s, p, best_score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
-                        memcpy(idwt2_buffer, best_dequant, height * stride * sizeof(IDWTELEM));
-                        for(y=ys; y<b->height; y+= Q2_STEP){
-                            for(x=xs; x<b->width; x+= Q2_STEP){
-                                if(dst[x + y*b->stride]<0) dst[x + y*b->stride]++;
-                                if(dst[x + y*b->stride]>0) dst[x + y*b->stride]--;
-                                //FIXME try more than just --
-                            }
-                        }
-                        dequantize_all(s, p, idwt2_buffer, width, height);
-                        ff_spatial_idwt(idwt2_buffer, s->temp_idwt_buffer, width, height, stride, type, s->spatial_decomposition_count);
-                        find_sse(s, p, score, score_stride, idwt2_buffer, s->spatial_idwt_buffer, level, orientation);
-                        for(y=ys; y<b->height; y+= Q2_STEP){
-                            for(x=xs; x<b->width; x+= Q2_STEP){
-                                int score_idx= x/Q2_STEP + (y/Q2_STEP)*score_stride;
-                                if(score[score_idx] <= best_score[score_idx] + threshold){
-                                    best_score[score_idx]= score[score_idx];
-                                    if(best_dst[x + y*b->stride]<0) best_dst[x + y*b->stride]++;
-                                    if(best_dst[x + y*b->stride]>0) best_dst[x + y*b->stride]--;
-                                    //FIXME copy instead
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-    memcpy(s->spatial_idwt_buffer, best_dequant, height * stride * sizeof(IDWTELEM)); //FIXME work with that directly instead of copy at the end
-}
-
-#endif /* QUANTIZE2==1 */
-
-static av_cold int encode_init(AVCodecContext *avctx)
-{
-    SnowContext *s = avctx->priv_data;
-    int plane_index, ret;
-
-    if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){
-        av_log(avctx, AV_LOG_ERROR, "This codec is under development, files encoded with it may not be decodable with future versions!!!\n"
-               "Use vstrict=-2 / -strict -2 to use it anyway.\n");
-        return -1;
-    }
-
-    if(avctx->prediction_method == DWT_97
-       && (avctx->flags & CODEC_FLAG_QSCALE)
-       && avctx->global_quality == 0){
-        av_log(avctx, AV_LOG_ERROR, "The 9/7 wavelet is incompatible with lossless mode.\n");
-        return -1;
-    }
-
-    s->spatial_decomposition_type= avctx->prediction_method; //FIXME add decorrelator type r transform_type
-
-    s->mv_scale       = (avctx->flags & CODEC_FLAG_QPEL) ? 2 : 4;
-    s->block_max_depth= (avctx->flags & CODEC_FLAG_4MV ) ? 1 : 0;
-
-    for(plane_index=0; plane_index<3; plane_index++){
-        s->plane[plane_index].diag_mc= 1;
-        s->plane[plane_index].htaps= 6;
-        s->plane[plane_index].hcoeff[0]=  40;
-        s->plane[plane_index].hcoeff[1]= -10;
-        s->plane[plane_index].hcoeff[2]=   2;
-        s->plane[plane_index].fast_mc= 1;
-    }
-
-    if ((ret = ff_snow_common_init(avctx)) < 0) {
-        ff_snow_common_end(avctx->priv_data);
-        return ret;
-    }
-    ff_snow_alloc_blocks(s);
-
-    s->version=0;
-
-    s->m.avctx   = avctx;
-    s->m.flags   = avctx->flags;
-    s->m.bit_rate= avctx->bit_rate;
-
-    s->m.me.temp      =
-    s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t));
-    s->m.me.map       = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
-    s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t));
-    s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t));
-    ff_h263_encode_init(&s->m); //mv_penalty
-
-    s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1);
-
-    if(avctx->flags&CODEC_FLAG_PASS1){
-        if(!avctx->stats_out)
-            avctx->stats_out = av_mallocz(256);
-    }
-    if((avctx->flags&CODEC_FLAG_PASS2) || !(avctx->flags&CODEC_FLAG_QSCALE)){
-        if(ff_rate_control_init(&s->m) < 0)
-            return -1;
-    }
-    s->pass1_rc= !(avctx->flags & (CODEC_FLAG_QSCALE|CODEC_FLAG_PASS2));
-
-    avctx->coded_frame= &s->current_picture;
-    switch(avctx->pix_fmt){
-//    case AV_PIX_FMT_YUV444P:
-//    case AV_PIX_FMT_YUV422P:
-    case AV_PIX_FMT_YUV420P:
-    case AV_PIX_FMT_GRAY8:
-//    case AV_PIX_FMT_YUV411P:
-//    case AV_PIX_FMT_YUV410P:
-        s->colorspace_type= 0;
-        break;
-/*    case AV_PIX_FMT_RGB32:
-        s->colorspace= 1;
-        break;*/
-    default:
-        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;
-
-    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);
-
-    ff_get_buffer(s->avctx, &s->input_picture);
-
-    if(s->avctx->me_method == ME_ITER){
-        int i;
-        int size= s->b_width * s->b_height << 2*s->block_max_depth;
-        for(i=0; i<s->max_ref_frames; i++){
-            s->ref_mvs[i]= av_mallocz(size*sizeof(int16_t[2]));
-            s->ref_scores[i]= av_mallocz(size*sizeof(uint32_t));
-        }
-    }
-
-    return 0;
-}
-
-//near copy & paste from dsputil, FIXME
-static int pix_sum(uint8_t * pix, int line_size, int w)
-{
-    int s, i, j;
-
-    s = 0;
-    for (i = 0; i < w; i++) {
-        for (j = 0; j < w; j++) {
-            s += pix[0];
-            pix ++;
-        }
-        pix += line_size - w;
-    }
-    return s;
-}
-
-//near copy & paste from dsputil, FIXME
-static int pix_norm1(uint8_t * pix, int line_size, int w)
-{
-    int s, i, j;
-    uint32_t *sq = ff_squareTbl + 256;
-
-    s = 0;
-    for (i = 0; i < w; i++) {
-        for (j = 0; j < w; j ++) {
-            s += sq[pix[0]];
-            pix ++;
-        }
-        pix += line_size - w;
-    }
-    return s;
-}
-
-//FIXME copy&paste
-#define P_LEFT P[1]
-#define P_TOP P[2]
-#define P_TOPRIGHT P[3]
-#define P_MEDIAN P[4]
-#define P_MV1 P[9]
-#define FLAG_QPEL   1 //must be 1
-
-static int encode_q_branch(SnowContext *s, int level, int x, int y){
-    uint8_t p_buffer[1024];
-    uint8_t i_buffer[1024];
-    uint8_t p_state[sizeof(s->block_state)];
-    uint8_t i_state[sizeof(s->block_state)];
-    RangeCoder pc, ic;
-    uint8_t *pbbak= s->c.bytestream;
-    uint8_t *pbbak_start= s->c.bytestream_start;
-    int score, score2, iscore, i_len, p_len, block_s, sum, base_bits;
-    const int w= s->b_width  << s->block_max_depth;
-    const int h= s->b_height << s->block_max_depth;
-    const int rem_depth= s->block_max_depth - level;
-    const int index= (x + y*w) << rem_depth;
-    const int block_w= 1<<(LOG2_MB_SIZE - level);
-    int trx= (x+1)<<rem_depth;
-    int try= (y+1)<<rem_depth;
-    const BlockNode *left  = x ? &s->block[index-1] : &null_block;
-    const BlockNode *top   = y ? &s->block[index-w] : &null_block;
-    const BlockNode *right = trx<w ? &s->block[index+1] : &null_block;
-    const BlockNode *bottom= try<h ? &s->block[index+w] : &null_block;
-    const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
-    const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
-    int pl = left->color[0];
-    int pcb= left->color[1];
-    int pcr= left->color[2];
-    int pmx, pmy;
-    int mx=0, my=0;
-    int l,cr,cb;
-    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};
-    int P[10][2];
-    int16_t last_mv[3][2];
-    int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused
-    const int shift= 1+qpel;
-    MotionEstContext *c= &s->m.me;
-    int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
-    int mx_context= av_log2(2*FFABS(left->mx - top->mx));
-    int my_context= av_log2(2*FFABS(left->my - top->my));
-    int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
-    int ref, best_ref, ref_score, ref_mx, ref_my;
-
-    assert(sizeof(s->block_state) >= 256);
-    if(s->keyframe){
-        set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
-        return 0;
-    }
-
-//    clip predictors / edge ?
-
-    P_LEFT[0]= left->mx;
-    P_LEFT[1]= left->my;
-    P_TOP [0]= top->mx;
-    P_TOP [1]= top->my;
-    P_TOPRIGHT[0]= tr->mx;
-    P_TOPRIGHT[1]= tr->my;
-
-    last_mv[0][0]= s->block[index].mx;
-    last_mv[0][1]= s->block[index].my;
-    last_mv[1][0]= right->mx;
-    last_mv[1][1]= right->my;
-    last_mv[2][0]= bottom->mx;
-    last_mv[2][1]= bottom->my;
-
-    s->m.mb_stride=2;
-    s->m.mb_x=
-    s->m.mb_y= 0;
-    c->skip= 0;
-
-    assert(c->  stride ==   stride);
-    assert(c->uvstride == 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);
-    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
-    c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_MV;
-
-    c->xmin = - x*block_w - 16+3;
-    c->ymin = - y*block_w - 16+3;
-    c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
-    c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3;
-
-    if(P_LEFT[0]     > (c->xmax<<shift)) P_LEFT[0]    = (c->xmax<<shift);
-    if(P_LEFT[1]     > (c->ymax<<shift)) P_LEFT[1]    = (c->ymax<<shift);
-    if(P_TOP[0]      > (c->xmax<<shift)) P_TOP[0]     = (c->xmax<<shift);
-    if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);
-    if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
-    if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift); //due to pmx no clip
-    if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
-
-    P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
-    P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
-
-    if (!y) {
-        c->pred_x= P_LEFT[0];
-        c->pred_y= P_LEFT[1];
-    } else {
-        c->pred_x = P_MEDIAN[0];
-        c->pred_y = P_MEDIAN[1];
-    }
-
-    score= INT_MAX;
-    best_ref= 0;
-    for(ref=0; ref<s->ref_frames; ref++){
-        init_ref(c, current_data, s->last_picture[ref].data, NULL, block_w*x, block_w*y, 0);
-
-        ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv,
-                                         (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w);
-
-        assert(ref_mx >= c->xmin);
-        assert(ref_mx <= c->xmax);
-        assert(ref_my >= c->ymin);
-        assert(ref_my <= c->ymax);
-
-        ref_score= c->sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w);
-        ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0);
-        ref_score+= 2*av_log2(2*ref)*c->penalty_factor;
-        if(s->ref_mvs[ref]){
-            s->ref_mvs[ref][index][0]= ref_mx;
-            s->ref_mvs[ref][index][1]= ref_my;
-            s->ref_scores[ref][index]= ref_score;
-        }
-        if(score > ref_score){
-            score= ref_score;
-            best_ref= ref;
-            mx= ref_mx;
-            my= ref_my;
-        }
-    }
-    //FIXME if mb_cmp != SSE then intra cannot be compared currently and mb_penalty vs. lambda2
-
-  //  subpel search
-    base_bits= get_rac_count(&s->c) - 8*(s->c.bytestream - s->c.bytestream_start);
-    pc= s->c;
-    pc.bytestream_start=
-    pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo
-    memcpy(p_state, s->block_state, sizeof(s->block_state));
-
-    if(level!=s->block_max_depth)
-        put_rac(&pc, &p_state[4 + s_context], 1);
-    put_rac(&pc, &p_state[1 + left->type + top->type], 0);
-    if(s->ref_frames > 1)
-        put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0);
-    pred_mv(s, &pmx, &pmy, best_ref, left, top, tr);
-    put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1);
-    put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1);
-    p_len= pc.bytestream - pc.bytestream_start;
-    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);
-    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);
-    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);
-    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;
-
-    ic= s->c;
-    ic.bytestream_start=
-    ic.bytestream= i_buffer; //FIXME end/start? and at the other stoo
-    memcpy(i_state, s->block_state, sizeof(s->block_state));
-    if(level!=s->block_max_depth)
-        put_rac(&ic, &i_state[4 + s_context], 1);
-    put_rac(&ic, &i_state[1 + left->type + top->type], 1);
-    put_symbol(&ic, &i_state[32],  l-pl , 1);
-    put_symbol(&ic, &i_state[64], cb-pcb, 1);
-    put_symbol(&ic, &i_state[96], cr-pcr, 1);
-    i_len= ic.bytestream - ic.bytestream_start;
-    iscore += (s->lambda2*(get_rac_count(&ic)-base_bits))>>FF_LAMBDA_SHIFT;
-
-//    assert(score==256*256*256*64-1);
-    assert(iscore < 255*255*256 + s->lambda2*10);
-    assert(iscore >= 0);
-    assert(l>=0 && l<=255);
-    assert(pl>=0 && pl<=255);
-
-    if(level==0){
-        int varc= iscore >> 8;
-        int vard= score >> 8;
-        if (vard <= 64 || vard < varc)
-            c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
-        else
-            c->scene_change_score+= s->m.qscale;
-    }
-
-    if(level!=s->block_max_depth){
-        put_rac(&s->c, &s->block_state[4 + s_context], 0);
-        score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0);
-        score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0);
-        score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1);
-        score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+1);
-        score2+= s->lambda2>>FF_LAMBDA_SHIFT; //FIXME exact split overhead
-
-        if(score2 < score && score2 < iscore)
-            return score2;
-    }
-
-    if(iscore < score){
-        pred_mv(s, &pmx, &pmy, 0, left, top, tr);
-        memcpy(pbbak, i_buffer, i_len);
-        s->c= ic;
-        s->c.bytestream_start= pbbak_start;
-        s->c.bytestream= pbbak + i_len;
-        set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA);
-        memcpy(s->block_state, i_state, sizeof(s->block_state));
-        return iscore;
-    }else{
-        memcpy(pbbak, p_buffer, p_len);
-        s->c= pc;
-        s->c.bytestream_start= pbbak_start;
-        s->c.bytestream= pbbak + p_len;
-        set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, best_ref, 0);
-        memcpy(s->block_state, p_state, sizeof(s->block_state));
-        return score;
-    }
-}
-
-static void encode_q_branch2(SnowContext *s, int level, int x, int y){
-    const int w= s->b_width  << s->block_max_depth;
-    const int rem_depth= s->block_max_depth - level;
-    const int index= (x + y*w) << rem_depth;
-    int trx= (x+1)<<rem_depth;
-    BlockNode *b= &s->block[index];
-    const BlockNode *left  = x ? &s->block[index-1] : &null_block;
-    const BlockNode *top   = y ? &s->block[index-w] : &null_block;
-    const BlockNode *tl    = y && x ? &s->block[index-w-1] : left;
-    const BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
-    int pl = left->color[0];
-    int pcb= left->color[1];
-    int pcr= left->color[2];
-    int pmx, pmy;
-    int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
-    int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 16*!!b->ref;
-    int my_context= av_log2(2*FFABS(left->my - top->my)) + 16*!!b->ref;
-    int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
-
-    if(s->keyframe){
-        set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA);
-        return;
-    }
-
-    if(level!=s->block_max_depth){
-        if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){
-            put_rac(&s->c, &s->block_state[4 + s_context], 1);
-        }else{
-            put_rac(&s->c, &s->block_state[4 + s_context], 0);
-            encode_q_branch2(s, level+1, 2*x+0, 2*y+0);
-            encode_q_branch2(s, level+1, 2*x+1, 2*y+0);
-            encode_q_branch2(s, level+1, 2*x+0, 2*y+1);
-            encode_q_branch2(s, level+1, 2*x+1, 2*y+1);
-            return;
-        }
-    }
-    if(b->type & BLOCK_INTRA){
-        pred_mv(s, &pmx, &pmy, 0, left, top, tr);
-        put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1);
-        put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1);
-        put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1);
-        put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1);
-        set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA);
-    }else{
-        pred_mv(s, &pmx, &pmy, b->ref, left, top, tr);
-        put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0);
-        if(s->ref_frames > 1)
-            put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0);
-        put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1);
-        put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1);
-        set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, b->ref, 0);
-    }
-}
-
-static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){
-    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 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
-    const int b_stride = s->b_width << s->block_max_depth;
-    const int w= p->width;
-    const int h= p->height;
-    int index= mb_x + mb_y*b_stride;
-    BlockNode *b= &s->block[index];
-    BlockNode backup= *b;
-    int ab=0;
-    int aa=0;
-
-    b->type|= BLOCK_INTRA;
-    b->color[plane_index]= 0;
-    memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM));
-
-    for(i=0; i<4; i++){
-        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;
-
-        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);
-
-        for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_w); 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 obmc_v= obmc[index];
-                int d;
-                if(y<0) obmc_v += obmc[index + block_w*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(x+block_w>w) obmc_v += obmc[index - block_w];
-                //FIXME precalculate this or simplify it somehow else
-
-                d = -dst[index] + (1<<(FRAC_BITS-1));
-                dst[index] = d;
-                ab += (src[x2 + y2*ref_stride] - (d>>FRAC_BITS)) * obmc_v;
-                aa += obmc_v * obmc_v; //FIXME precalculate this
-            }
-        }
-    }
-    *b= backup;
-
-    return av_clip(((ab<<LOG2_OBMC_MAX) + aa/2)/aa, 0, 255); //FIXME we should not need clipping
-}
-
-static inline int get_block_bits(SnowContext *s, int x, int y, int w){
-    const int b_stride = s->b_width << s->block_max_depth;
-    const int b_height = s->b_height<< s->block_max_depth;
-    int index= x + y*b_stride;
-    const BlockNode *b     = &s->block[index];
-    const BlockNode *left  = x ? &s->block[index-1] : &null_block;
-    const BlockNode *top   = y ? &s->block[index-b_stride] : &null_block;
-    const BlockNode *tl    = y && x ? &s->block[index-b_stride-1] : left;
-    const BlockNode *tr    = y && x+w<b_stride ? &s->block[index-b_stride+w] : tl;
-    int dmx, dmy;
-//  int mx_context= av_log2(2*FFABS(left->mx - top->mx));
-//  int my_context= av_log2(2*FFABS(left->my - top->my));
-
-    if(x<0 || x>=b_stride || y>=b_height)
-        return 0;
-/*
-1            0      0
-01X          1-2    1
-001XX        3-6    2-3
-0001XXX      7-14   4-7
-00001XXXX   15-30   8-15
-*/
-//FIXME try accurate rate
-//FIXME intra and inter predictors if surrounding blocks are not the same type
-    if(b->type & BLOCK_INTRA){
-        return 3+2*( av_log2(2*FFABS(left->color[0] - b->color[0]))
-                   + av_log2(2*FFABS(left->color[1] - b->color[1]))
-                   + av_log2(2*FFABS(left->color[2] - b->color[2])));
-    }else{
-        pred_mv(s, &dmx, &dmy, b->ref, left, top, tr);
-        dmx-= b->mx;
-        dmy-= b->my;
-        return 2*(1 + av_log2(2*FFABS(dmx)) //FIXME kill the 2* can be merged in lambda
-                    + av_log2(2*FFABS(dmy))
-                    + av_log2(2*b->ref));
-    }
-}
-
-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 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];
-    IDWTELEM *pred= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4;
-    uint8_t *cur = s->scratchbuf;
-    uint8_t *tmp = s->emu_edge_buffer;
-    const int b_stride = s->b_width << s->block_max_depth;
-    const int b_height = s->b_height<< s->block_max_depth;
-    const int w= p->width;
-    const int h= p->height;
-    int distortion;
-    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 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 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);
-
-    for(y=y0; y<y1; y++){
-        const uint8_t *obmc1= obmc_edged[y];
-        const IDWTELEM *pred1 = pred + y*obmc_stride;
-        uint8_t *cur1 = cur + y*ref_stride;
-        uint8_t *dst1 = dst + sx + (sy+y)*ref_stride;
-        for(x=x0; x<x1; x++){
-#if FRAC_BITS >= LOG2_OBMC_MAX
-            int v = (cur1[x] * obmc1[x]) << (FRAC_BITS - LOG2_OBMC_MAX);
-#else
-            int v = (cur1[x] * obmc1[x] + (1<<(LOG2_OBMC_MAX - FRAC_BITS-1))) >> (LOG2_OBMC_MAX - FRAC_BITS);
-#endif
-            v = (v + pred1[x]) >> FRAC_BITS;
-            if(v&(~255)) v= ~(v>>31);
-            dst1[x] = v;
-        }
-    }
-
-    /* copy the regions where obmc[] = (uint8_t)256 */
-    if(LOG2_OBMC_MAX == 8
-        && (mb_x == 0 || mb_x == b_stride-1)
-        && (mb_y == 0 || mb_y == b_height-1)){
-        if(mb_x == 0)
-            x1 = block_w;
-        else
-            x0 = block_w;
-        if(mb_y == 0)
-            y1 = block_w;
-        else
-            y0 = block_w;
-        for(y=y0; y<y1; y++)
-            memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0);
-    }
-
-    if(block_w==16){
-        /* FIXME rearrange dsputil to fit 32x32 cmp functions */
-        /* FIXME check alignment of the cmp wavelet vs the encoding wavelet */
-        /* FIXME cmps overlap but do not cover the wavelet's whole support.
-         * So improving the score of one block is not strictly guaranteed
-         * to improve the score of the whole frame, thus iterative motion
-         * estimation does not always converge. */
-        if(s->avctx->me_cmp == FF_CMP_W97)
-            distortion = ff_w97_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
-        else if(s->avctx->me_cmp == FF_CMP_W53)
-            distortion = ff_w53_32_c(&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, 32);
-        else{
-            distortion = 0;
-            for(i=0; i<4; i++){
-                int off = sx+16*(i&1) + (sy+16*(i>>1))*ref_stride;
-                distortion += s->dsp.me_cmp[0](&s->m, src + off, dst + off, ref_stride, 16);
-            }
-        }
-    }else{
-        assert(block_w==8);
-        distortion = s->dsp.me_cmp[0](&s->m, src + sx + sy*ref_stride, dst + sx + sy*ref_stride, ref_stride, block_w*2);
-    }
-
-    if(plane_index==0){
-        for(i=0; i<4; i++){
-/* ..RRr
- * .RXx.
- * rxx..
- */
-            rate += get_block_bits(s, mb_x + (i&1) - (i>>1), mb_y + (i>>1), 1);
-        }
-        if(mb_x == b_stride-2)
-            rate += get_block_bits(s, mb_x + 1, mb_y + 1, 1);
-    }
-    return distortion + rate*penalty_factor;
-}
-
-static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){
-    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 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];
-    //FIXME zero_dst is const but add_yblock changes dst if add is 0 (this is never the case for dst=zero_dst
-    // const has only been removed from zero_dst to suppress a warning
-    static IDWTELEM zero_dst[4096]; //FIXME
-    const int b_stride = s->b_width << s->block_max_depth;
-    const int w= p->width;
-    const int h= p->height;
-    int distortion= 0;
-    int rate= 0;
-    const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
-
-    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;
-
-        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);
-
-        //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++)
-            memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
-        if(x<0){
-            for(y2= y; y2<y+block_w; 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++)
-                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);
-    }
-
-    if(plane_index==0){
-        BlockNode *b= &s->block[mb_x+mb_y*b_stride];
-        int merged= same_block(b,b+1) && same_block(b,b+b_stride) && same_block(b,b+b_stride+1);
-
-/* ..RRRr
- * .RXXx.
- * .RXXx.
- * rxxx.
- */
-        if(merged)
-            rate = get_block_bits(s, mb_x, mb_y, 2);
-        for(i=merged?4:0; i<9; i++){
-            static const int dxy[9][2] = {{0,0},{1,0},{0,1},{1,1},{2,0},{2,1},{-1,2},{0,2},{1,2}};
-            rate += get_block_bits(s, mb_x + dxy[i][0], mb_y + dxy[i][1], 1);
-        }
-    }
-    return distortion + rate*penalty_factor;
-}
-
-static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
-    const int w= b->width;
-    const int h= b->height;
-    int x, y;
-
-    if(1){
-        int run=0;
-        int *runs = s->run_buffer;
-        int run_index=0;
-        int max_index;
-
-        for(y=0; y<h; y++){
-            for(x=0; x<w; x++){
-                int v, p=0;
-                int /*ll=0, */l=0, lt=0, t=0, rt=0;
-                v= src[x + y*stride];
-
-                if(y){
-                    t= src[x + (y-1)*stride];
-                    if(x){
-                        lt= src[x - 1 + (y-1)*stride];
-                    }
-                    if(x + 1 < w){
-                        rt= src[x + 1 + (y-1)*stride];
-                    }
-                }
-                if(x){
-                    l= src[x - 1 + y*stride];
-                    /*if(x > 1){
-                        if(orientation==1) ll= src[y + (x-2)*stride];
-                        else               ll= src[x - 2 + y*stride];
-                    }*/
-                }
-                if(parent){
-                    int px= x>>1;
-                    int py= y>>1;
-                    if(px<b->parent->width && py<b->parent->height)
-                        p= parent[px + py*2*stride];
-                }
-                if(!(/*ll|*/l|lt|t|rt|p)){
-                    if(v){
-                        runs[run_index++]= run;
-                        run=0;
-                    }else{
-                        run++;
-                    }
-                }
-            }
-        }
-        max_index= run_index;
-        runs[run_index++]= run;
-        run_index=0;
-        run= runs[run_index++];
-
-        put_symbol2(&s->c, b->state[30], max_index, 0);
-        if(run_index <= max_index)
-            put_symbol2(&s->c, b->state[1], run, 3);
-
-        for(y=0; y<h; y++){
-            if(s->c.bytestream_end - s->c.bytestream < w*40){
-                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
-                return -1;
-            }
-            for(x=0; x<w; x++){
-                int v, p=0;
-                int /*ll=0, */l=0, lt=0, t=0, rt=0;
-                v= src[x + y*stride];
-
-                if(y){
-                    t= src[x + (y-1)*stride];
-                    if(x){
-                        lt= src[x - 1 + (y-1)*stride];
-                    }
-                    if(x + 1 < w){
-                        rt= src[x + 1 + (y-1)*stride];
-                    }
-                }
-                if(x){
-                    l= src[x - 1 + y*stride];
-                    /*if(x > 1){
-                        if(orientation==1) ll= src[y + (x-2)*stride];
-                        else               ll= src[x - 2 + y*stride];
-                    }*/
-                }
-                if(parent){
-                    int px= x>>1;
-                    int py= y>>1;
-                    if(px<b->parent->width && py<b->parent->height)
-                        p= parent[px + py*2*stride];
-                }
-                if(/*ll|*/l|lt|t|rt|p){
-                    int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
-
-                    put_rac(&s->c, &b->state[0][context], !!v);
-                }else{
-                    if(!run){
-                        run= runs[run_index++];
-
-                        if(run_index <= max_index)
-                            put_symbol2(&s->c, b->state[1], run, 3);
-                        assert(v);
-                    }else{
-                        run--;
-                        assert(!v);
-                    }
-                }
-                if(v){
-                    int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p));
-                    int l2= 2*FFABS(l) + (l<0);
-                    int t2= 2*FFABS(t) + (t<0);
-
-                    put_symbol2(&s->c, b->state[context + 2], FFABS(v)-1, context-4);
-                    put_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l2&0xFF] + 3*ff_quant3bA[t2&0xFF]], v<0);
-                }
-            }
-        }
-    }
-    return 0;
-}
-
-static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, 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);
-//    encode_subband_dzr(s, b, src, parent, stride, orientation);
-}
-
-static av_always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, uint8_t (*obmc_edged)[MB_SIZE * 2], int *best_rd){
-    const int b_stride= s->b_width << s->block_max_depth;
-    BlockNode *block= &s->block[mb_x + mb_y * b_stride];
-    BlockNode backup= *block;
-    unsigned value;
-    int rd, index;
-
-    assert(mb_x>=0 && mb_y>=0);
-    assert(mb_x<b_stride);
-
-    if(intra){
-        block->color[0] = p[0];
-        block->color[1] = p[1];
-        block->color[2] = p[2];
-        block->type |= BLOCK_INTRA;
-    }else{
-        index= (p[0] + 31*p[1]) & (ME_CACHE_SIZE-1);
-        value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6) + (block->ref<<12);
-        if(s->me_cache[index] == value)
-            return 0;
-        s->me_cache[index]= value;
-
-        block->mx= p[0];
-        block->my= p[1];
-        block->type &= ~BLOCK_INTRA;
-    }
-
-    rd= get_block_rd(s, mb_x, mb_y, 0, obmc_edged);
-
-//FIXME chroma
-    if(rd < *best_rd){
-        *best_rd= rd;
-        return 1;
-    }else{
-        *block= backup;
-        return 0;
-    }
-}
-
-/* special case for int[2] args we discard afterwards,
- * fixes compilation problem with gcc 2.95 */
-static av_always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, uint8_t (*obmc_edged)[MB_SIZE * 2], int *best_rd){
-    int p[2] = {p0, p1};
-    return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd);
-}
-
-static av_always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int ref, int *best_rd){
-    const int b_stride= s->b_width << s->block_max_depth;
-    BlockNode *block= &s->block[mb_x + mb_y * b_stride];
-    BlockNode backup[4];
-    unsigned value;
-    int rd, index;
-
-    /* We don't initialize backup[] during variable declaration, because
-     * that fails to compile on MSVC: "cannot convert from 'BlockNode' to
-     * 'int16_t'". */
-    backup[0] = block[0];
-    backup[1] = block[1];
-    backup[2] = block[b_stride];
-    backup[3] = block[b_stride + 1];
-
-    assert(mb_x>=0 && mb_y>=0);
-    assert(mb_x<b_stride);
-    assert(((mb_x|mb_y)&1) == 0);
-
-    index= (p0 + 31*p1) & (ME_CACHE_SIZE-1);
-    value= s->me_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12);
-    if(s->me_cache[index] == value)
-        return 0;
-    s->me_cache[index]= value;
-
-    block->mx= p0;
-    block->my= p1;
-    block->ref= ref;
-    block->type &= ~BLOCK_INTRA;
-    block[1]= block[b_stride]= block[b_stride+1]= *block;
-
-    rd= get_4block_rd(s, mb_x, mb_y, 0);
-
-//FIXME chroma
-    if(rd < *best_rd){
-        *best_rd= rd;
-        return 1;
-    }else{
-        block[0]= backup[0];
-        block[1]= backup[1];
-        block[b_stride]= backup[2];
-        block[b_stride+1]= backup[3];
-        return 0;
-    }
-}
-
-static void iterative_me(SnowContext *s){
-    int pass, mb_x, mb_y;
-    const int b_width = s->b_width  << s->block_max_depth;
-    const int b_height= s->b_height << s->block_max_depth;
-    const int b_stride= b_width;
-    int color[3];
-
-    {
-        RangeCoder r = s->c;
-        uint8_t state[sizeof(s->block_state)];
-        memcpy(state, s->block_state, sizeof(s->block_state));
-        for(mb_y= 0; mb_y<s->b_height; mb_y++)
-            for(mb_x= 0; mb_x<s->b_width; mb_x++)
-                encode_q_branch(s, 0, mb_x, mb_y);
-        s->c = r;
-        memcpy(s->block_state, state, sizeof(s->block_state));
-    }
-
-    for(pass=0; pass<25; pass++){
-        int change= 0;
-
-        for(mb_y= 0; mb_y<b_height; mb_y++){
-            for(mb_x= 0; mb_x<b_width; mb_x++){
-                int dia_change, i, j, ref;
-                int best_rd= INT_MAX, ref_rd;
-                BlockNode backup, ref_b;
-                const int index= mb_x + mb_y * b_stride;
-                BlockNode *block= &s->block[index];
-                BlockNode *tb =                   mb_y            ? &s->block[index-b_stride  ] : NULL;
-                BlockNode *lb = mb_x                              ? &s->block[index         -1] : NULL;
-                BlockNode *rb = mb_x+1<b_width                    ? &s->block[index         +1] : NULL;
-                BlockNode *bb =                   mb_y+1<b_height ? &s->block[index+b_stride  ] : NULL;
-                BlockNode *tlb= mb_x           && mb_y            ? &s->block[index-b_stride-1] : NULL;
-                BlockNode *trb= mb_x+1<b_width && mb_y            ? &s->block[index-b_stride+1] : NULL;
-                BlockNode *blb= mb_x           && mb_y+1<b_height ? &s->block[index+b_stride-1] : NULL;
-                BlockNode *brb= mb_x+1<b_width && mb_y+1<b_height ? &s->block[index+b_stride+1] : NULL;
-                const int b_w= (MB_SIZE >> s->block_max_depth);
-                uint8_t obmc_edged[MB_SIZE * 2][MB_SIZE * 2];
-
-                if(pass && (block->type & BLOCK_OPT))
-                    continue;
-                block->type |= BLOCK_OPT;
-
-                backup= *block;
-
-                if(!s->me_cache_generation)
-                    memset(s->me_cache, 0, sizeof(s->me_cache));
-                s->me_cache_generation += 1<<22;
-
-                //FIXME precalculate
-                {
-                    int x, y;
-                    for (y = 0; y < b_w * 2; y++)
-                        memcpy(obmc_edged[y], ff_obmc_tab[s->block_max_depth] + y * b_w * 2, b_w * 2);
-                    if(mb_x==0)
-                        for(y=0; y<b_w*2; y++)
-                            memset(obmc_edged[y], obmc_edged[y][0] + obmc_edged[y][b_w-1], b_w);
-                    if(mb_x==b_stride-1)
-                        for(y=0; y<b_w*2; y++)
-                            memset(obmc_edged[y]+b_w, obmc_edged[y][b_w] + obmc_edged[y][b_w*2-1], b_w);
-                    if(mb_y==0){
-                        for(x=0; x<b_w*2; x++)
-                            obmc_edged[0][x] += obmc_edged[b_w-1][x];
-                        for(y=1; y<b_w; y++)
-                            memcpy(obmc_edged[y], obmc_edged[0], b_w*2);
-                    }
-                    if(mb_y==b_height-1){
-                        for(x=0; x<b_w*2; x++)
-                            obmc_edged[b_w*2-1][x] += obmc_edged[b_w][x];
-                        for(y=b_w; y<b_w*2-1; y++)
-                            memcpy(obmc_edged[y], obmc_edged[b_w*2-1], b_w*2);
-                    }
-                }
-
-                //skip stuff outside the picture
-                if(mb_x==0 || mb_y==0 || mb_x==b_width-1 || mb_y==b_height-1){
-                    uint8_t *src= s->  input_picture.data[0];
-                    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 sx= block_w*mb_x - block_w/2;
-                    const int sy= block_w*mb_y - block_w/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++)
-                        memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
-                    if(sx<0){
-                        for(y=sy; y<sy+block_w*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++)
-                            memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w);
-                    }
-                }
-
-                // intra(black) = neighbors' contribution to the current block
-                for(i=0; i<3; i++)
-                    color[i]= get_dc(s, mb_x, mb_y, i);
-
-                // get previous score (cannot be cached due to OBMC)
-                if(pass > 0 && (block->type&BLOCK_INTRA)){
-                    int color0[3]= {block->color[0], block->color[1], block->color[2]};
-                    check_block(s, mb_x, mb_y, color0, 1, obmc_edged, &best_rd);
-                }else
-                    check_block_inter(s, mb_x, mb_y, block->mx, block->my, obmc_edged, &best_rd);
-
-                ref_b= *block;
-                ref_rd= best_rd;
-                for(ref=0; ref < s->ref_frames; ref++){
-                    int16_t (*mvr)[2]= &s->ref_mvs[ref][index];
-                    if(s->ref_scores[ref][index] > s->ref_scores[ref_b.ref][index]*3/2) //FIXME tune threshold
-                        continue;
-                    block->ref= ref;
-                    best_rd= INT_MAX;
-
-                    check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], obmc_edged, &best_rd);
-                    check_block_inter(s, mb_x, mb_y, 0, 0, obmc_edged, &best_rd);
-                    if(tb)
-                        check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], obmc_edged, &best_rd);
-                    if(lb)
-                        check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], obmc_edged, &best_rd);
-                    if(rb)
-                        check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], obmc_edged, &best_rd);
-                    if(bb)
-                        check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], obmc_edged, &best_rd);
-
-                    /* fullpel ME */
-                    //FIXME avoid subpel interpolation / round to nearest integer
-                    do{
-                        dia_change=0;
-                        for(i=0; i<FFMAX(s->avctx->dia_size, 1); i++){
-                            for(j=0; j<i; j++){
-                                dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my+(4*j), obmc_edged, &best_rd);
-                                dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), obmc_edged, &best_rd);
-                                dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), obmc_edged, &best_rd);
-                                dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), obmc_edged, &best_rd);
-                            }
-                        }
-                    }while(dia_change);
-                    /* subpel ME */
-                    do{
-                        static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},};
-                        dia_change=0;
-                        for(i=0; i<8; i++)
-                            dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], obmc_edged, &best_rd);
-                    }while(dia_change);
-                    //FIXME or try the standard 2 pass qpel or similar
-
-                    mvr[0][0]= block->mx;
-                    mvr[0][1]= block->my;
-                    if(ref_rd > best_rd){
-                        ref_rd= best_rd;
-                        ref_b= *block;
-                    }
-                }
-                best_rd= ref_rd;
-                *block= ref_b;
-                check_block(s, mb_x, mb_y, color, 1, obmc_edged, &best_rd);
-                //FIXME RD style color selection
-                if(!same_block(block, &backup)){
-                    if(tb ) tb ->type &= ~BLOCK_OPT;
-                    if(lb ) lb ->type &= ~BLOCK_OPT;
-                    if(rb ) rb ->type &= ~BLOCK_OPT;
-                    if(bb ) bb ->type &= ~BLOCK_OPT;
-                    if(tlb) tlb->type &= ~BLOCK_OPT;
-                    if(trb) trb->type &= ~BLOCK_OPT;
-                    if(blb) blb->type &= ~BLOCK_OPT;
-                    if(brb) brb->type &= ~BLOCK_OPT;
-                    change ++;
-                }
-            }
-        }
-        av_log(s->avctx, AV_LOG_ERROR, "pass:%d changed:%d\n", pass, change);
-        if(!change)
-            break;
-    }
-
-    if(s->block_max_depth == 1){
-        int change= 0;
-        for(mb_y= 0; mb_y<b_height; mb_y+=2){
-            for(mb_x= 0; mb_x<b_width; mb_x+=2){
-                int i;
-                int best_rd, init_rd;
-                const int index= mb_x + mb_y * b_stride;
-                BlockNode *b[4];
-
-                b[0]= &s->block[index];
-                b[1]= b[0]+1;
-                b[2]= b[0]+b_stride;
-                b[3]= b[2]+1;
-                if(same_block(b[0], b[1]) &&
-                   same_block(b[0], b[2]) &&
-                   same_block(b[0], b[3]))
-                    continue;
-
-                if(!s->me_cache_generation)
-                    memset(s->me_cache, 0, sizeof(s->me_cache));
-                s->me_cache_generation += 1<<22;
-
-                init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0);
-
-                //FIXME more multiref search?
-                check_4block_inter(s, mb_x, mb_y,
-                                   (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2,
-                                   (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, 0, &best_rd);
-
-                for(i=0; i<4; i++)
-                    if(!(b[i]->type&BLOCK_INTRA))
-                        check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, b[i]->ref, &best_rd);
-
-                if(init_rd != best_rd)
-                    change++;
-            }
-        }
-        av_log(s->avctx, AV_LOG_ERROR, "pass:4mv changed:%d\n", change*4);
-    }
-}
-
-static void encode_blocks(SnowContext *s, int search){
-    int x, y;
-    int w= s->b_width;
-    int h= s->b_height;
-
-    if(s->avctx->me_method == ME_ITER && !s->keyframe && search)
-        iterative_me(s);
-
-    for(y=0; y<h; y++){
-        if(s->c.bytestream_end - s->c.bytestream < w*MB_SIZE*MB_SIZE*3){ //FIXME nicer limit
-            av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
-            return;
-        }
-        for(x=0; x<w; x++){
-            if(s->avctx->me_method == ME_ITER || !search)
-                encode_q_branch2(s, 0, x, y);
-            else
-                encode_q_branch (s, 0, x, y);
-        }
-    }
-}
-
-static void quantize(SnowContext *s, SubBand *b, IDWTELEM *dst, DWTELEM *src, int stride, int bias){
-    const int w= b->width;
-    const int h= b->height;
-    const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
-    const int qmul= ff_qexp[qlog&(QROOT-1)]<<((qlog>>QSHIFT) + ENCODER_EXTRA_BITS);
-    int x,y, thres1, thres2;
-
-    if(s->qlog == LOSSLESS_QLOG){
-        for(y=0; y<h; y++)
-            for(x=0; x<w; x++)
-                dst[x + y*stride]= src[x + y*stride];
-        return;
-    }
-
-    bias= bias ? 0 : (3*qmul)>>3;
-    thres1= ((qmul - bias)>>QEXPSHIFT) - 1;
-    thres2= 2*thres1;
-
-    if(!bias){
-        for(y=0; y<h; y++){
-            for(x=0; x<w; x++){
-                int i= src[x + y*stride];
-
-                if((unsigned)(i+thres1) > thres2){
-                    if(i>=0){
-                        i<<= QEXPSHIFT;
-                        i/= qmul; //FIXME optimize
-                        dst[x + y*stride]=  i;
-                    }else{
-                        i= -i;
-                        i<<= QEXPSHIFT;
-                        i/= qmul; //FIXME optimize
-                        dst[x + y*stride]= -i;
-                    }
-                }else
-                    dst[x + y*stride]= 0;
-            }
-        }
-    }else{
-        for(y=0; y<h; y++){
-            for(x=0; x<w; x++){
-                int i= src[x + y*stride];
-
-                if((unsigned)(i+thres1) > thres2){
-                    if(i>=0){
-                        i<<= QEXPSHIFT;
-                        i= (i + bias) / qmul; //FIXME optimize
-                        dst[x + y*stride]=  i;
-                    }else{
-                        i= -i;
-                        i<<= QEXPSHIFT;
-                        i= (i + bias) / qmul; //FIXME optimize
-                        dst[x + y*stride]= -i;
-                    }
-                }else
-                    dst[x + y*stride]= 0;
-            }
-        }
-    }
-}
-
-static void dequantize(SnowContext *s, SubBand *b, IDWTELEM *src, int stride){
-    const int w= b->width;
-    const int h= b->height;
-    const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
-    const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
-    const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
-    int x,y;
-
-    if(s->qlog == LOSSLESS_QLOG) return;
-
-    for(y=0; y<h; y++){
-        for(x=0; x<w; x++){
-            int i= src[x + y*stride];
-            if(i<0){
-                src[x + y*stride]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
-            }else if(i>0){
-                src[x + y*stride]=  (( i*qmul + qadd)>>(QEXPSHIFT));
-            }
-        }
-    }
-}
-
-static void decorrelate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
-    const int w= b->width;
-    const int h= b->height;
-    int x,y;
-
-    for(y=h-1; y>=0; y--){
-        for(x=w-1; x>=0; x--){
-            int i= x + y*stride;
-
-            if(x){
-                if(use_median){
-                    if(y && x+1<w) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
-                    else  src[i] -= src[i - 1];
-                }else{
-                    if(y) src[i] -= mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
-                    else  src[i] -= src[i - 1];
-                }
-            }else{
-                if(y) src[i] -= src[i - stride];
-            }
-        }
-    }
-}
-
-static void correlate(SnowContext *s, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median){
-    const int w= b->width;
-    const int h= b->height;
-    int x,y;
-
-    for(y=0; y<h; y++){
-        for(x=0; x<w; x++){
-            int i= x + y*stride;
-
-            if(x){
-                if(use_median){
-                    if(y && x+1<w) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - stride + 1]);
-                    else  src[i] += src[i - 1];
-                }else{
-                    if(y) src[i] += mid_pred(src[i - 1], src[i - stride], src[i - 1] + src[i - stride] - src[i - 1 - stride]);
-                    else  src[i] += src[i - 1];
-                }
-            }else{
-                if(y) src[i] += src[i - stride];
-            }
-        }
-    }
-}
-
-static void encode_qlogs(SnowContext *s){
-    int plane_index, level, orientation;
-
-    for(plane_index=0; plane_index<2; plane_index++){
-        for(level=0; level<s->spatial_decomposition_count; level++){
-            for(orientation=level ? 1:0; orientation<4; orientation++){
-                if(orientation==2) continue;
-                put_symbol(&s->c, s->header_state, s->plane[plane_index].band[level][orientation].qlog, 1);
-            }
-        }
-    }
-}
-
-static void encode_header(SnowContext *s){
-    int plane_index, i;
-    uint8_t kstate[32];
-
-    memset(kstate, MID_STATE, sizeof(kstate));
-
-    put_rac(&s->c, kstate, s->keyframe);
-    if(s->keyframe || s->always_reset){
-        ff_snow_reset_contexts(s);
-        s->last_spatial_decomposition_type=
-        s->last_qlog=
-        s->last_qbias=
-        s->last_mv_scale=
-        s->last_block_max_depth= 0;
-        for(plane_index=0; plane_index<2; plane_index++){
-            Plane *p= &s->plane[plane_index];
-            p->last_htaps=0;
-            p->last_diag_mc=0;
-            memset(p->last_hcoeff, 0, sizeof(p->last_hcoeff));
-        }
-    }
-    if(s->keyframe){
-        put_symbol(&s->c, s->header_state, s->version, 0);
-        put_rac(&s->c, s->header_state, s->always_reset);
-        put_symbol(&s->c, s->header_state, s->temporal_decomposition_type, 0);
-        put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0);
-        put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
-        put_symbol(&s->c, s->header_state, s->colorspace_type, 0);
-        put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0);
-        put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0);
-        put_rac(&s->c, s->header_state, s->spatial_scalability);
-//        put_rac(&s->c, s->header_state, s->rate_scalability);
-        put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0);
-
-        encode_qlogs(s);
-    }
-
-    if(!s->keyframe){
-        int update_mc=0;
-        for(plane_index=0; plane_index<2; plane_index++){
-            Plane *p= &s->plane[plane_index];
-            update_mc |= p->last_htaps   != p->htaps;
-            update_mc |= p->last_diag_mc != p->diag_mc;
-            update_mc |= !!memcmp(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
-        }
-        put_rac(&s->c, s->header_state, update_mc);
-        if(update_mc){
-            for(plane_index=0; plane_index<2; plane_index++){
-                Plane *p= &s->plane[plane_index];
-                put_rac(&s->c, s->header_state, p->diag_mc);
-                put_symbol(&s->c, s->header_state, p->htaps/2-1, 0);
-                for(i= p->htaps/2; i; i--)
-                    put_symbol(&s->c, s->header_state, FFABS(p->hcoeff[i]), 0);
-            }
-        }
-        if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
-            put_rac(&s->c, s->header_state, 1);
-            put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
-            encode_qlogs(s);
-        }else
-            put_rac(&s->c, s->header_state, 0);
-    }
-
-    put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1);
-    put_symbol(&s->c, s->header_state, s->qlog            - s->last_qlog    , 1);
-    put_symbol(&s->c, s->header_state, s->mv_scale        - s->last_mv_scale, 1);
-    put_symbol(&s->c, s->header_state, s->qbias           - s->last_qbias   , 1);
-    put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1);
-
-}
-
-static void update_last_header_values(SnowContext *s){
-    int plane_index;
-
-    if(!s->keyframe){
-        for(plane_index=0; plane_index<2; plane_index++){
-            Plane *p= &s->plane[plane_index];
-            p->last_diag_mc= p->diag_mc;
-            p->last_htaps  = p->htaps;
-            memcpy(p->last_hcoeff, p->hcoeff, sizeof(p->hcoeff));
-        }
-    }
-
-    s->last_spatial_decomposition_type  = s->spatial_decomposition_type;
-    s->last_qlog                        = s->qlog;
-    s->last_qbias                       = s->qbias;
-    s->last_mv_scale                    = s->mv_scale;
-    s->last_block_max_depth             = s->block_max_depth;
-    s->last_spatial_decomposition_count = s->spatial_decomposition_count;
-}
-
-static int qscale2qlog(int qscale){
-    return rint(QROOT*log2(qscale / (float)FF_QP2LAMBDA))
-           + 61*QROOT/8; ///< 64 > 60
-}
-
-static int ratecontrol_1pass(SnowContext *s, AVFrame *pict)
-{
-    /* Estimate the frame's complexity as a sum of weighted dwt coefficients.
-     * FIXME we know exact mv bits at this point,
-     * but ratecontrol isn't set up to include them. */
-    uint32_t coef_sum= 0;
-    int level, orientation, delta_qlog;
-
-    for(level=0; level<s->spatial_decomposition_count; level++){
-        for(orientation=level ? 1 : 0; orientation<4; orientation++){
-            SubBand *b= &s->plane[0].band[level][orientation];
-            IDWTELEM *buf= b->ibuf;
-            const int w= b->width;
-            const int h= b->height;
-            const int stride= b->stride;
-            const int qlog= av_clip(2*QROOT + b->qlog, 0, QROOT*16);
-            const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
-            const int qdiv= (1<<16)/qmul;
-            int x, y;
-            //FIXME this is ugly
-            for(y=0; y<h; y++)
-                for(x=0; x<w; x++)
-                    buf[x+y*stride]= b->buf[x+y*stride];
-            if(orientation==0)
-                decorrelate(s, b, buf, stride, 1, 0);
-            for(y=0; y<h; y++)
-                for(x=0; x<w; x++)
-                    coef_sum+= abs(buf[x+y*stride]) * qdiv >> 16;
-        }
-    }
-
-    /* ugly, ratecontrol just takes a sqrt again */
-    coef_sum = (uint64_t)coef_sum * coef_sum >> 16;
-    assert(coef_sum < INT_MAX);
-
-    if(pict->pict_type == AV_PICTURE_TYPE_I){
-        s->m.current_picture.mb_var_sum= coef_sum;
-        s->m.current_picture.mc_mb_var_sum= 0;
-    }else{
-        s->m.current_picture.mc_mb_var_sum= coef_sum;
-        s->m.current_picture.mb_var_sum= 0;
-    }
-
-    pict->quality= ff_rate_estimate_qscale(&s->m, 1);
-    if (pict->quality < 0)
-        return INT_MIN;
-    s->lambda= pict->quality * 3/2;
-    delta_qlog= qscale2qlog(pict->quality) - s->qlog;
-    s->qlog+= delta_qlog;
-    return delta_qlog;
-}
-
-static void calculate_visual_weight(SnowContext *s, Plane *p){
-    int width = p->width;
-    int height= p->height;
-    int level, orientation, x, y;
-
-    for(level=0; level<s->spatial_decomposition_count; level++){
-        for(orientation=level ? 1 : 0; orientation<4; orientation++){
-            SubBand *b= &p->band[level][orientation];
-            IDWTELEM *ibuf= b->ibuf;
-            int64_t error=0;
-
-            memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height);
-            ibuf[b->width/2 + b->height/2*b->stride]= 256*16;
-            ff_spatial_idwt(s->spatial_idwt_buffer, 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= s->spatial_idwt_buffer[x + y*width]*16;
-                    error += d*d;
-                }
-            }
-
-            b->qlog= (int)(log(352256.0/sqrt(error)) / log(pow(2.0, 1.0/QROOT))+0.5);
-        }
-    }
-}
-
-static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
-                        const AVFrame *pict, int *got_packet)
-{
-    SnowContext *s = avctx->priv_data;
-    RangeCoder * const c= &s->c;
-    AVFrame *pic = &s->new_picture;
-    const int width= s->avctx->width;
-    const int height= s->avctx->height;
-    int level, orientation, plane_index, i, y, ret;
-    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");
-        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++)
-            memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]],
-                   &pict->data[i][y * pict->linesize[i]],
-                   width>>shift);
-    }
-    s->new_picture = *pict;
-
-    s->m.picture_number= avctx->frame_number;
-    if(avctx->flags&CODEC_FLAG_PASS2){
-        s->m.pict_type = pic->pict_type = s->m.rc_context.entry[avctx->frame_number].new_pict_type;
-        s->keyframe = pic->pict_type == AV_PICTURE_TYPE_I;
-        if(!(avctx->flags&CODEC_FLAG_QSCALE)) {
-            pic->quality = ff_rate_estimate_qscale(&s->m, 0);
-            if (pic->quality < 0)
-                return -1;
-        }
-    }else{
-        s->keyframe= avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0;
-        s->m.pict_type = pic->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
-    }
-
-    if(s->pass1_rc && avctx->frame_number == 0)
-        pic->quality = 2*FF_QP2LAMBDA;
-    if (pic->quality) {
-        s->qlog   = qscale2qlog(pic->quality);
-        s->lambda = pic->quality * 3/2;
-    }
-    if (s->qlog < 0 || (!pic->quality && (avctx->flags & CODEC_FLAG_QSCALE))) {
-        s->qlog= LOSSLESS_QLOG;
-        s->lambda = 0;
-    }//else keep previous frame's qlog until after motion estimation
-
-    ff_snow_frame_start(s);
-
-    s->m.current_picture_ptr= &s->m.current_picture;
-    s->m.last_picture.f.pts = s->m.current_picture.f.pts;
-    s->m.current_picture.f.pts = pict->pts;
-    if(pic->pict_type == AV_PICTURE_TYPE_P){
-        int block_width = (width +15)>>4;
-        int block_height= (height+15)>>4;
-        int stride= s->current_picture.linesize[0];
-
-        assert(s->current_picture.data[0]);
-        assert(s->last_picture[0].data[0]);
-
-        s->m.avctx= s->avctx;
-        s->m.current_picture.f.data[0] = s->current_picture.data[0];
-        s->m.   last_picture.f.data[0] = s->last_picture[0].data[0];
-        s->m.    new_picture.f.data[0] = s->  input_picture.data[0];
-        s->m.   last_picture_ptr= &s->m.   last_picture;
-        s->m.linesize=
-        s->m.   last_picture.f.linesize[0] =
-        s->m.    new_picture.f.linesize[0] =
-        s->m.current_picture.f.linesize[0] = stride;
-        s->m.uvlinesize= s->current_picture.linesize[1];
-        s->m.width = width;
-        s->m.height= height;
-        s->m.mb_width = block_width;
-        s->m.mb_height= block_height;
-        s->m.mb_stride=   s->m.mb_width+1;
-        s->m.b8_stride= 2*s->m.mb_width+1;
-        s->m.f_code=1;
-        s->m.pict_type = pic->pict_type;
-        s->m.me_method= s->avctx->me_method;
-        s->m.me.scene_change_score=0;
-        s->m.flags= s->avctx->flags;
-        s->m.quarter_sample= (s->avctx->flags & CODEC_FLAG_QPEL)!=0;
-        s->m.out_format= FMT_H263;
-        s->m.unrestricted_mv= 1;
-
-        s->m.lambda = s->lambda;
-        s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
-        s->lambda2= s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
-
-        s->m.dsp= s->dsp; //move
-        ff_init_me(&s->m);
-        s->dsp= s->m.dsp;
-    }
-
-    if(s->pass1_rc){
-        memcpy(rc_header_bak, s->header_state, sizeof(s->header_state));
-        memcpy(rc_block_bak, s->block_state, sizeof(s->block_state));
-    }
-
-redo_frame:
-
-    if (pic->pict_type == AV_PICTURE_TYPE_I)
-        s->spatial_decomposition_count= 5;
-    else
-        s->spatial_decomposition_count= 5;
-
-    s->m.pict_type = pic->pict_type;
-    s->qbias = pic->pict_type == AV_PICTURE_TYPE_P ? 2 : 0;
-
-    ff_snow_common_init_after_header(avctx);
-
-    if(s->last_spatial_decomposition_count != s->spatial_decomposition_count){
-        for(plane_index=0; plane_index<3; plane_index++){
-            calculate_visual_weight(s, &s->plane[plane_index]);
-        }
-    }
-
-    encode_header(s);
-    s->m.misc_bits = 8*(s->c.bytestream - s->c.bytestream_start);
-    encode_blocks(s, 1);
-    s->m.mv_bits = 8*(s->c.bytestream - s->c.bytestream_start) - s->m.misc_bits;
-
-    for(plane_index=0; plane_index<3; plane_index++){
-        Plane *p= &s->plane[plane_index];
-        int w= p->width;
-        int h= p->height;
-        int x, y;
-//        int bits= put_bits_count(&s->c.pb);
-
-        if (!s->memc_only) {
-            //FIXME optimize
-            if(pict->data[plane_index]) //FIXME gray hack
-                for(y=0; y<h; y++){
-                    for(x=0; x<w; x++){
-                        s->spatial_idwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<FRAC_BITS;
-                    }
-                }
-            predict_plane(s, s->spatial_idwt_buffer, plane_index, 0);
-
-            if(   plane_index==0
-               && pic->pict_type == AV_PICTURE_TYPE_P
-               && !(avctx->flags&CODEC_FLAG_PASS2)
-               && s->m.me.scene_change_score > s->avctx->scenechange_threshold){
-                ff_init_range_encoder(c, pkt->data, pkt->size);
-                ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
-                pic->pict_type= AV_PICTURE_TYPE_I;
-                s->keyframe=1;
-                s->current_picture.key_frame=1;
-                goto redo_frame;
-            }
-
-            if(s->qlog == LOSSLESS_QLOG){
-                for(y=0; y<h; y++){
-                    for(x=0; x<w; x++){
-                        s->spatial_dwt_buffer[y*w + x]= (s->spatial_idwt_buffer[y*w + x] + (1<<(FRAC_BITS-1))-1)>>FRAC_BITS;
-                    }
-                }
-            }else{
-                for(y=0; y<h; y++){
-                    for(x=0; x<w; x++){
-                        s->spatial_dwt_buffer[y*w + x]=s->spatial_idwt_buffer[y*w + x]<<ENCODER_EXTRA_BITS;
-                    }
-                }
-            }
-
-            /*  if(QUANTIZE2)
-                dwt_quantize(s, p, s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type);
-            else*/
-                ff_spatial_dwt(s->spatial_dwt_buffer, s->temp_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
-
-            if(s->pass1_rc && plane_index==0){
-                int delta_qlog = ratecontrol_1pass(s, pic);
-                if (delta_qlog <= INT_MIN)
-                    return -1;
-                if(delta_qlog){
-                    //reordering qlog in the bitstream would eliminate this reset
-                    ff_init_range_encoder(c, pkt->data, pkt->size);
-                    memcpy(s->header_state, rc_header_bak, sizeof(s->header_state));
-                    memcpy(s->block_state, rc_block_bak, sizeof(s->block_state));
-                    encode_header(s);
-                    encode_blocks(s, 0);
-                }
-            }
-
-            for(level=0; level<s->spatial_decomposition_count; level++){
-                for(orientation=level ? 1 : 0; orientation<4; orientation++){
-                    SubBand *b= &p->band[level][orientation];
-
-                    if(!QUANTIZE2)
-                        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);
-                    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)
-                        correlate(s, b, b->ibuf, b->stride, 1, 0);
-                }
-            }
-
-            for(level=0; level<s->spatial_decomposition_count; level++){
-                for(orientation=level ? 1 : 0; orientation<4; orientation++){
-                    SubBand *b= &p->band[level][orientation];
-
-                    dequantize(s, b, b->ibuf, b->stride);
-                }
-            }
-
-            ff_spatial_idwt(s->spatial_idwt_buffer, s->temp_idwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);
-            if(s->qlog == LOSSLESS_QLOG){
-                for(y=0; y<h; y++){
-                    for(x=0; x<w; x++){
-                        s->spatial_idwt_buffer[y*w + x]<<=FRAC_BITS;
-                    }
-                }
-            }
-            predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
-        }else{
-            //ME/MC only
-            if(pic->pict_type == AV_PICTURE_TYPE_I){
-                for(y=0; y<h; y++){
-                    for(x=0; x<w; x++){
-                        s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]=
-                            pict->data[plane_index][y*pict->linesize[plane_index] + x];
-                    }
-                }
-            }else{
-                memset(s->spatial_idwt_buffer, 0, sizeof(IDWTELEM)*w*h);
-                predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
-            }
-        }
-        if(s->avctx->flags&CODEC_FLAG_PSNR){
-            int64_t error= 0;
-
-            if(pict->data[plane_index]) //FIXME gray hack
-                for(y=0; y<h; y++){
-                    for(x=0; x<w; x++){
-                        int d= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x];
-                        error += d*d;
-                    }
-                }
-            s->avctx->error[plane_index] += error;
-            s->current_picture.error[plane_index] = error;
-        }
-
-    }
-
-    update_last_header_values(s);
-
-    ff_snow_release_buffer(avctx);
-
-    s->current_picture.coded_picture_number = avctx->frame_number;
-    s->current_picture.pict_type = pict->pict_type;
-    s->current_picture.quality = pict->quality;
-    s->m.frame_bits = 8*(s->c.bytestream - s->c.bytestream_start);
-    s->m.p_tex_bits = s->m.frame_bits - s->m.misc_bits - s->m.mv_bits;
-    s->m.current_picture.f.display_picture_number =
-    s->m.current_picture.f.coded_picture_number   = avctx->frame_number;
-    s->m.current_picture.f.quality                = pic->quality;
-    s->m.total_bits += 8*(s->c.bytestream - s->c.bytestream_start);
-    if(s->pass1_rc)
-        if (ff_rate_estimate_qscale(&s->m, 0) < 0)
-            return -1;
-    if(avctx->flags&CODEC_FLAG_PASS1)
-        ff_write_pass1_stats(&s->m);
-    s->m.last_pict_type = s->m.pict_type;
-    avctx->frame_bits = s->m.frame_bits;
-    avctx->mv_bits = s->m.mv_bits;
-    avctx->misc_bits = s->m.misc_bits;
-    avctx->p_tex_bits = s->m.p_tex_bits;
-
-    emms_c();
-
-    pkt->size = ff_rac_terminate(c);
-    if (avctx->coded_frame->key_frame)
-        pkt->flags |= AV_PKT_FLAG_KEY;
-    *got_packet = 1;
-
-    return 0;
-}
-
-static av_cold int encode_end(AVCodecContext *avctx)
-{
-    SnowContext *s = avctx->priv_data;
-
-    ff_snow_common_end(s);
-    if (s->input_picture.data[0])
-        avctx->release_buffer(avctx, &s->input_picture);
-    av_free(avctx->stats_out);
-
-    return 0;
-}
-
-#define OFFSET(x) offsetof(SnowContext, x)
-#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 },
-    { NULL },
-};
-
-static const AVClass snowenc_class = {
-    .class_name = "snow encoder",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_snow_encoder = {
-    .name           = "snow",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_SNOW,
-    .priv_data_size = sizeof(SnowContext),
-    .init           = encode_init,
-    .encode2        = encode_frame,
-    .close          = encode_end,
-    .long_name      = NULL_IF_CONFIG_SMALL("Snow"),
-    .priv_class     = &snowenc_class,
-};
diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c
index 90c3491..ca6b9fd 100644
--- a/libavcodec/sp5xdec.c
+++ b/libavcodec/sp5xdec.c
@@ -95,6 +95,7 @@ static int sp5x_decode_frame(AVCodecContext *avctx,
 
 AVCodec ff_sp5x_decoder = {
     .name           = "sp5x",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SP5X,
     .priv_data_size = sizeof(MJpegDecodeContext),
@@ -102,16 +103,15 @@ AVCodec ff_sp5x_decoder = {
     .close          = ff_mjpeg_decode_end,
     .decode         = sp5x_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"),
 };
 
 AVCodec ff_amv_decoder = {
     .name           = "amv",
+    .long_name      = NULL_IF_CONFIG_SMALL("AMV Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_AMV,
     .priv_data_size = sizeof(MJpegDecodeContext),
     .init           = ff_mjpeg_decode_init,
     .close          = ff_mjpeg_decode_end,
     .decode         = sp5x_decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("AMV Video"),
 };
diff --git a/libavcodec/sparc/Makefile b/libavcodec/sparc/Makefile
index 1b6ac81..aeb0f47 100644
--- a/libavcodec/sparc/Makefile
+++ b/libavcodec/sparc/Makefile
@@ -1,2 +1,4 @@
 VIS-OBJS += sparc/dsputil_vis.o                                         \
             sparc/simple_idct_vis.o                                     \
+
+VIS-OBJS-$(CONFIG_HPELDSP) += sparc/hpeldsp_vis.o
diff --git a/libavcodec/sparc/dsputil_vis.c b/libavcodec/sparc/dsputil_vis.c
index 5bac83e..cee2e1d 100644
--- a/libavcodec/sparc/dsputil_vis.c
+++ b/libavcodec/sparc/dsputil_vis.c
@@ -18,3993 +18,23 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/* The *no_round* functions have been added by James A. Morrison, 2003,2004.
-   The vis code from libmpeg2 was adapted for libavcodec by James A. Morrison.
- */
-
-#include "config.h"
-
-#include <inttypes.h>
-
-#include "libavcodec/dsputil.h"
-#include "libavutil/mem.h"
-#include "dsputil_vis.h"
-
-#include "vis.h"
-
-/* The trick used in some of this file is the formula from the MMX
- * motion comp code, which is:
- *
- * (x+y+1)>>1 == (x|y)-((x^y)>>1)
- *
- * This allows us to average 8 bytes at a time in a 64-bit FPU reg.
- * We avoid overflows by masking before we do the shift, and we
- * implement the shift by multiplying by 1/2 using mul8x16.  So in
- * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask
- * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and
- * the value 0x80808080 is in f8):
- *
- *      fxor            f0,   f2, f10
- *      fand            f10,  f4, f10
- *      fmul8x16        f8,  f10, f10
- *      fand            f10,  f6, f10
- *      for             f0,   f2, f12
- *      fpsub16         f12, f10, f10
- */
-
-#define DUP4(x) {x, x, x, x}
-#define DUP8(x) {x, x, x, x, x, x, x, x}
-DECLARE_ALIGNED(8, static const int16_t, constants1)[] = DUP4 (1);
-DECLARE_ALIGNED(8, static const int16_t, constants2)[] = DUP4 (2);
-DECLARE_ALIGNED(8, static const int16_t, constants3)[] = DUP4 (3);
-DECLARE_ALIGNED(8, static const int16_t, constants6)[] = DUP4 (6);
-DECLARE_ALIGNED(8, static const int8_t, constants_fe)[] = DUP8 (0xfe);
-DECLARE_ALIGNED(8, static const int8_t, constants_7f)[] = DUP8 (0x7f);
-DECLARE_ALIGNED(8, static const int8_t, constants128)[] = DUP8 (128);
-DECLARE_ALIGNED(8, static const int16_t, constants256_512)[] =
-        {256, 512, 256, 512};
-DECLARE_ALIGNED(8, static const int16_t, constants256_1024)[] =
-        {256, 1024, 256, 1024};
-
-#define REF_0           0
-#define REF_0_1         1
-#define REF_2           2
-#define REF_2_1         3
-#define REF_4           4
-#define REF_4_1         5
-#define REF_6           6
-#define REF_6_1         7
-#define REF_S0          8
-#define REF_S0_1        9
-#define REF_S2          10
-#define REF_S2_1        11
-#define REF_S4          12
-#define REF_S4_1        13
-#define REF_S6          14
-#define REF_S6_1        15
-#define DST_0           16
-#define DST_1           17
-#define DST_2           18
-#define DST_3           19
-#define CONST_1         20
-#define CONST_2         20
-#define CONST_3         20
-#define CONST_6         20
-#define MASK_fe         20
-#define CONST_128       22
-#define CONST_256       22
-#define CONST_512       22
-#define CONST_1024      22
-#define TMP0            24
-#define TMP1            25
-#define TMP2            26
-#define TMP3            27
-#define TMP4            28
-#define TMP5            29
-#define ZERO            30
-#define MASK_7f         30
-
-#define TMP6            32
-#define TMP8            34
-#define TMP10           36
-#define TMP12           38
-#define TMP14           40
-#define TMP16           42
-#define TMP18           44
-#define TMP20           46
-#define TMP22           48
-#define TMP24           50
-#define TMP26           52
-#define TMP28           54
-#define TMP30           56
-#define TMP32           58
-
-static void MC_put_o_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-        do {    /* 5 cycles */
-                vis_ld64(ref[0], TMP0);
-
-                vis_ld64_2(ref, 8, TMP2);
-
-                vis_ld64_2(ref, 16, TMP4);
-                ref += stride;
-
-                vis_faligndata(TMP0, TMP2, REF_0);
-                vis_st64(REF_0, dest[0]);
-
-                vis_faligndata(TMP2, TMP4, REF_2);
-                vis_st64_2(REF_2, dest, 8);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_put_o_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-        do {    /* 4 cycles */
-                vis_ld64(ref[0], TMP0);
-
-                vis_ld64(ref[8], TMP2);
-                ref += stride;
-
-                /* stall */
-
-                vis_faligndata(TMP0, TMP2, REF_0);
-                vis_st64(REF_0, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-
-static void MC_avg_o_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        int stride_8 = stride + 8;
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64(ref[8], TMP2);
-
-        vis_ld64(ref[16], TMP4);
-
-        vis_ld64(dest[0], DST_0);
-
-        vis_ld64(dest[8], DST_2);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP2, TMP4, REF_2);
-
-        vis_ld64(constants128[0], CONST_128);
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 24 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(DST_0, REF_0, TMP6);
-
-                vis_ld64_2(ref, 8, TMP2);
-                vis_and(TMP6, MASK_fe, TMP6);
-
-                vis_ld64_2(ref, 16, TMP4);
-                ref += stride;
-                vis_mul8x16(CONST_128, TMP6, TMP6);
-                vis_xor(DST_2, REF_2, TMP8);
-
-                vis_and(TMP8, MASK_fe, TMP8);
-
-                vis_or(DST_0, REF_0, TMP10);
-                vis_ld64_2(dest, stride, DST_0);
-                vis_mul8x16(CONST_128, TMP8, TMP8);
-
-                vis_or(DST_2, REF_2, TMP12);
-                vis_ld64_2(dest, stride_8, DST_2);
-
-                vis_ld64(ref[0], TMP14);
-                vis_and(TMP6, MASK_7f, TMP6);
-
-                vis_and(TMP8, MASK_7f, TMP8);
-
-                vis_psub16(TMP10, TMP6, TMP6);
-                vis_st64(TMP6, dest[0]);
-
-                vis_psub16(TMP12, TMP8, TMP8);
-                vis_st64_2(TMP8, dest, 8);
-
-                dest += stride;
-                vis_ld64_2(ref, 8, TMP16);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, 16, TMP18);
-                vis_faligndata(TMP2, TMP4, REF_2);
-                ref += stride;
-
-                vis_xor(DST_0, REF_0, TMP20);
-
-                vis_and(TMP20, MASK_fe, TMP20);
-
-                vis_xor(DST_2, REF_2, TMP22);
-                vis_mul8x16(CONST_128, TMP20, TMP20);
-
-                vis_and(TMP22, MASK_fe, TMP22);
-
-                vis_or(DST_0, REF_0, TMP24);
-                vis_mul8x16(CONST_128, TMP22, TMP22);
-
-                vis_or(DST_2, REF_2, TMP26);
-
-                vis_ld64_2(dest, stride, DST_0);
-                vis_faligndata(TMP14, TMP16, REF_0);
-
-                vis_ld64_2(dest, stride_8, DST_2);
-                vis_faligndata(TMP16, TMP18, REF_2);
-
-                vis_and(TMP20, MASK_7f, TMP20);
-
-                vis_and(TMP22, MASK_7f, TMP22);
-
-                vis_psub16(TMP24, TMP20, TMP20);
-                vis_st64(TMP20, dest[0]);
-
-                vis_psub16(TMP26, TMP22, TMP22);
-                vis_st64_2(TMP22, dest, 8);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(DST_0, REF_0, TMP6);
-
-        vis_ld64_2(ref, 8, TMP2);
-        vis_and(TMP6, MASK_fe, TMP6);
-
-        vis_ld64_2(ref, 16, TMP4);
-        vis_mul8x16(CONST_128, TMP6, TMP6);
-        vis_xor(DST_2, REF_2, TMP8);
-
-        vis_and(TMP8, MASK_fe, TMP8);
-
-        vis_or(DST_0, REF_0, TMP10);
-        vis_ld64_2(dest, stride, DST_0);
-        vis_mul8x16(CONST_128, TMP8, TMP8);
-
-        vis_or(DST_2, REF_2, TMP12);
-        vis_ld64_2(dest, stride_8, DST_2);
-
-        vis_ld64(ref[0], TMP14);
-        vis_and(TMP6, MASK_7f, TMP6);
-
-        vis_and(TMP8, MASK_7f, TMP8);
-
-        vis_psub16(TMP10, TMP6, TMP6);
-        vis_st64(TMP6, dest[0]);
-
-        vis_psub16(TMP12, TMP8, TMP8);
-        vis_st64_2(TMP8, dest, 8);
-
-        dest += stride;
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_faligndata(TMP2, TMP4, REF_2);
-
-        vis_xor(DST_0, REF_0, TMP20);
-
-        vis_and(TMP20, MASK_fe, TMP20);
-
-        vis_xor(DST_2, REF_2, TMP22);
-        vis_mul8x16(CONST_128, TMP20, TMP20);
-
-        vis_and(TMP22, MASK_fe, TMP22);
-
-        vis_or(DST_0, REF_0, TMP24);
-        vis_mul8x16(CONST_128, TMP22, TMP22);
-
-        vis_or(DST_2, REF_2, TMP26);
-
-        vis_and(TMP20, MASK_7f, TMP20);
-
-        vis_and(TMP22, MASK_7f, TMP22);
-
-        vis_psub16(TMP24, TMP20, TMP20);
-        vis_st64(TMP20, dest[0]);
-
-        vis_psub16(TMP26, TMP22, TMP22);
-        vis_st64_2(TMP22, dest, 8);
-}
-
-static void MC_avg_o_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64(ref[8], TMP2);
-
-        vis_ld64(dest[0], DST_0);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants128[0], CONST_128);
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 12 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(DST_0, REF_0, TMP4);
-
-                vis_ld64(ref[8], TMP2);
-                vis_and(TMP4, MASK_fe, TMP4);
-
-                vis_or(DST_0, REF_0, TMP6);
-                vis_ld64_2(dest, stride, DST_0);
-                ref += stride;
-                vis_mul8x16(CONST_128, TMP4, TMP4);
-
-                vis_ld64(ref[0], TMP12);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64(ref[8], TMP2);
-                vis_xor(DST_0, REF_0, TMP0);
-                ref += stride;
-
-                vis_and(TMP0, MASK_fe, TMP0);
-
-                vis_and(TMP4, MASK_7f, TMP4);
-
-                vis_psub16(TMP6, TMP4, TMP4);
-                vis_st64(TMP4, dest[0]);
-                dest += stride;
-                vis_mul8x16(CONST_128, TMP0, TMP0);
-
-                vis_or(DST_0, REF_0, TMP6);
-                vis_ld64_2(dest, stride, DST_0);
-
-                vis_faligndata(TMP12, TMP2, REF_0);
-
-                vis_and(TMP0, MASK_7f, TMP0);
-
-                vis_psub16(TMP6, TMP0, TMP4);
-                vis_st64(TMP4, dest[0]);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(DST_0, REF_0, TMP4);
-
-        vis_ld64(ref[8], TMP2);
-        vis_and(TMP4, MASK_fe, TMP4);
-
-        vis_or(DST_0, REF_0, TMP6);
-        vis_ld64_2(dest, stride, DST_0);
-        vis_mul8x16(CONST_128, TMP4, TMP4);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_xor(DST_0, REF_0, TMP0);
-
-        vis_and(TMP0, MASK_fe, TMP0);
-
-        vis_and(TMP4, MASK_7f, TMP4);
-
-        vis_psub16(TMP6, TMP4, TMP4);
-        vis_st64(TMP4, dest[0]);
-        dest += stride;
-        vis_mul8x16(CONST_128, TMP0, TMP0);
-
-        vis_or(DST_0, REF_0, TMP6);
-
-        vis_and(TMP0, MASK_7f, TMP0);
-
-        vis_psub16(TMP6, TMP0, TMP4);
-        vis_st64(TMP4, dest[0]);
-}
-
-static void MC_put_x_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0],    TMP0);
-
-        vis_ld64_2(ref, 8,  TMP2);
-
-        vis_ld64_2(ref, 16, TMP4);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants128[0], CONST_128);
-        vis_faligndata(TMP2, TMP4, REF_4);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_2);
-                vis_faligndata(TMP2, TMP4, REF_6);
-        } else {
-                vis_src1(TMP2, REF_2);
-                vis_src1(TMP4, REF_6);
-        }
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 34 cycles */
-                vis_ld64(ref[0],    TMP0);
-                vis_xor(REF_0, REF_2, TMP6);
-
-                vis_ld64_2(ref, 8,  TMP2);
-                vis_xor(REF_4, REF_6, TMP8);
-
-                vis_ld64_2(ref, 16, TMP4);
-                vis_and(TMP6, MASK_fe, TMP6);
-                ref += stride;
-
-                vis_ld64(ref[0],    TMP14);
-                vis_mul8x16(CONST_128, TMP6, TMP6);
-                vis_and(TMP8, MASK_fe, TMP8);
-
-                vis_ld64_2(ref, 8,  TMP16);
-                vis_mul8x16(CONST_128, TMP8, TMP8);
-                vis_or(REF_0, REF_2, TMP10);
-
-                vis_ld64_2(ref, 16, TMP18);
-                ref += stride;
-                vis_or(REF_4, REF_6, TMP12);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                        vis_faligndata(TMP2, TMP4, REF_6);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                        vis_src1(TMP4, REF_6);
-                }
-
-                vis_and(TMP6, MASK_7f, TMP6);
-
-                vis_and(TMP8, MASK_7f, TMP8);
-
-                vis_psub16(TMP10, TMP6, TMP6);
-                vis_st64(TMP6, dest[0]);
-
-                vis_psub16(TMP12, TMP8, TMP8);
-                vis_st64_2(TMP8, dest, 8);
-                dest += stride;
-
-                vis_xor(REF_0, REF_2, TMP6);
-
-                vis_xor(REF_4, REF_6, TMP8);
-
-                vis_and(TMP6, MASK_fe, TMP6);
-
-                vis_mul8x16(CONST_128, TMP6, TMP6);
-                vis_and(TMP8, MASK_fe, TMP8);
-
-                vis_mul8x16(CONST_128, TMP8, TMP8);
-                vis_or(REF_0, REF_2, TMP10);
-
-                vis_or(REF_4, REF_6, TMP12);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_faligndata(TMP14, TMP16, REF_0);
-
-                vis_faligndata(TMP16, TMP18, REF_4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP14, TMP16, REF_2);
-                        vis_faligndata(TMP16, TMP18, REF_6);
-                } else {
-                        vis_src1(TMP16, REF_2);
-                        vis_src1(TMP18, REF_6);
-                }
-
-                vis_and(TMP6, MASK_7f, TMP6);
-
-                vis_and(TMP8, MASK_7f, TMP8);
-
-                vis_psub16(TMP10, TMP6, TMP6);
-                vis_st64(TMP6, dest[0]);
-
-                vis_psub16(TMP12, TMP8, TMP8);
-                vis_st64_2(TMP8, dest, 8);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0],    TMP0);
-        vis_xor(REF_0, REF_2, TMP6);
-
-        vis_ld64_2(ref, 8,  TMP2);
-        vis_xor(REF_4, REF_6, TMP8);
-
-        vis_ld64_2(ref, 16, TMP4);
-        vis_and(TMP6, MASK_fe, TMP6);
-
-        vis_mul8x16(CONST_128, TMP6, TMP6);
-        vis_and(TMP8, MASK_fe, TMP8);
-
-        vis_mul8x16(CONST_128, TMP8, TMP8);
-        vis_or(REF_0, REF_2, TMP10);
-
-        vis_or(REF_4, REF_6, TMP12);
-
-        vis_alignaddr_g0((void *)off);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_faligndata(TMP2, TMP4, REF_4);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_2);
-                vis_faligndata(TMP2, TMP4, REF_6);
-        } else {
-                vis_src1(TMP2, REF_2);
-                vis_src1(TMP4, REF_6);
-        }
-
-        vis_and(TMP6, MASK_7f, TMP6);
-
-        vis_and(TMP8, MASK_7f, TMP8);
-
-        vis_psub16(TMP10, TMP6, TMP6);
-        vis_st64(TMP6, dest[0]);
-
-        vis_psub16(TMP12, TMP8, TMP8);
-        vis_st64_2(TMP8, dest, 8);
-        dest += stride;
-
-        vis_xor(REF_0, REF_2, TMP6);
-
-        vis_xor(REF_4, REF_6, TMP8);
-
-        vis_and(TMP6, MASK_fe, TMP6);
-
-        vis_mul8x16(CONST_128, TMP6, TMP6);
-        vis_and(TMP8, MASK_fe, TMP8);
-
-        vis_mul8x16(CONST_128, TMP8, TMP8);
-        vis_or(REF_0, REF_2, TMP10);
-
-        vis_or(REF_4, REF_6, TMP12);
-
-        vis_and(TMP6, MASK_7f, TMP6);
-
-        vis_and(TMP8, MASK_7f, TMP8);
-
-        vis_psub16(TMP10, TMP6, TMP6);
-        vis_st64(TMP6, dest[0]);
-
-        vis_psub16(TMP12, TMP8, TMP8);
-        vis_st64_2(TMP8, dest, 8);
-}
-
-static void MC_put_x_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64(ref[8], TMP2);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-
-        vis_ld64(constants128[0], CONST_128);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_2);
-        } else {
-                vis_src1(TMP2, REF_2);
-        }
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 20 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(REF_0, REF_2, TMP4);
-
-                vis_ld64_2(ref, 8, TMP2);
-                vis_and(TMP4, MASK_fe, TMP4);
-                ref += stride;
-
-                vis_ld64(ref[0], TMP8);
-                vis_or(REF_0, REF_2, TMP6);
-                vis_mul8x16(CONST_128, TMP4, TMP4);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, 8, TMP10);
-                ref += stride;
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                }
-
-                vis_and(TMP4, MASK_7f, TMP4);
-
-                vis_psub16(TMP6, TMP4, DST_0);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_xor(REF_0, REF_2, TMP12);
-
-                vis_and(TMP12, MASK_fe, TMP12);
-
-                vis_or(REF_0, REF_2, TMP14);
-                vis_mul8x16(CONST_128, TMP12, TMP12);
-
-                vis_alignaddr_g0((void *)off);
-                vis_faligndata(TMP8, TMP10, REF_0);
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP8, TMP10, REF_2);
-                } else {
-                        vis_src1(TMP10, REF_2);
-                }
-
-                vis_and(TMP12, MASK_7f, TMP12);
-
-                vis_psub16(TMP14, TMP12, DST_0);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(REF_0, REF_2, TMP4);
-
-        vis_ld64_2(ref, 8, TMP2);
-        vis_and(TMP4, MASK_fe, TMP4);
-
-        vis_or(REF_0, REF_2, TMP6);
-        vis_mul8x16(CONST_128, TMP4, TMP4);
-
-        vis_alignaddr_g0((void *)off);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_2);
-        } else {
-                vis_src1(TMP2, REF_2);
-        }
-
-        vis_and(TMP4, MASK_7f, TMP4);
-
-        vis_psub16(TMP6, TMP4, DST_0);
-        vis_st64(DST_0, dest[0]);
-        dest += stride;
-
-        vis_xor(REF_0, REF_2, TMP12);
-
-        vis_and(TMP12, MASK_fe, TMP12);
-
-        vis_or(REF_0, REF_2, TMP14);
-        vis_mul8x16(CONST_128, TMP12, TMP12);
-
-        vis_and(TMP12, MASK_7f, TMP12);
-
-        vis_psub16(TMP14, TMP12, DST_0);
-        vis_st64(DST_0, dest[0]);
-        dest += stride;
-}
-
-static void MC_avg_x_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_fzero(ZERO);
-        vis_ld64(constants256_512[0], CONST_256);
-
-        ref = vis_alignaddr(ref);
-        do {    /* 26 cycles */
-                vis_ld64(ref[0], TMP0);
-
-                vis_ld64(ref[8], TMP2);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64(ref[16], TMP4);
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64(dest[8], DST_2);
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                        vis_faligndata(TMP2, TMP4, REF_6);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                        vis_src1(TMP4, REF_6);
-                }
-
-                vis_mul8x16au(REF_0,   CONST_256, TMP0);
-
-                vis_pmerge(ZERO,     REF_2,     TMP4);
-                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
-
-                vis_pmerge(ZERO, REF_2_1, TMP6);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-
-                vis_mul8x16al(DST_0,   CONST_512, TMP4);
-                vis_padd16(TMP2, TMP6, TMP2);
-
-                vis_mul8x16al(DST_1,   CONST_512, TMP6);
-
-                vis_mul8x16au(REF_6,   CONST_256, TMP12);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP14);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_4,   CONST_256, TMP16);
-
-                vis_padd16(TMP0, CONST_3, TMP8);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP18);
-
-                vis_padd16(TMP2, CONST_3, TMP10);
-                vis_pack16(TMP8, DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_padd16(TMP16, TMP12, TMP0);
-
-                vis_st64(DST_0, dest[0]);
-                vis_mul8x16al(DST_2,   CONST_512, TMP4);
-                vis_padd16(TMP18, TMP14, TMP2);
-
-                vis_mul8x16al(DST_3,   CONST_512, TMP6);
-                vis_padd16(TMP0, CONST_3, TMP0);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_pack16(TMP0, DST_2);
-
-                vis_pack16(TMP2, DST_3);
-                vis_st64(DST_2, dest[8]);
-
-                ref += stride;
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_avg_x_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_times_2 = stride << 1;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_fzero(ZERO);
-        vis_ld64(constants256_512[0], CONST_256);
-
-        ref = vis_alignaddr(ref);
-        height >>= 2;
-        do {    /* 47 cycles */
-                vis_ld64(ref[0],   TMP0);
-
-                vis_ld64_2(ref, 8, TMP2);
-                ref += stride;
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64(ref[0],   TMP4);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, 8, TMP6);
-                ref += stride;
-
-                vis_ld64(ref[0],   TMP8);
-
-                vis_ld64_2(ref, 8, TMP10);
-                ref += stride;
-                vis_faligndata(TMP4, TMP6, REF_4);
-
-                vis_ld64(ref[0],   TMP12);
-
-                vis_ld64_2(ref, 8, TMP14);
-                ref += stride;
-                vis_faligndata(TMP8, TMP10, REF_S0);
-
-                vis_faligndata(TMP12, TMP14, REF_S4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-
-                        vis_ld64(dest[0], DST_0);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-
-                        vis_ld64_2(dest, stride, DST_2);
-                        vis_faligndata(TMP4, TMP6, REF_6);
-
-                        vis_faligndata(TMP8, TMP10, REF_S2);
-
-                        vis_faligndata(TMP12, TMP14, REF_S6);
-                } else {
-                        vis_ld64(dest[0], DST_0);
-                        vis_src1(TMP2, REF_2);
-
-                        vis_ld64_2(dest, stride, DST_2);
-                        vis_src1(TMP6, REF_6);
-
-                        vis_src1(TMP10, REF_S2);
-
-                        vis_src1(TMP14, REF_S6);
-                }
-
-                vis_pmerge(ZERO,     REF_0,     TMP0);
-                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
-
-                vis_pmerge(ZERO,     REF_2,     TMP4);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP6);
-
-                vis_padd16(TMP0, CONST_3, TMP0);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-                vis_mul8x16au(REF_4, CONST_256, TMP8);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP10);
-
-                vis_padd16(TMP0, TMP16, TMP0);
-                vis_mul8x16au(REF_6, CONST_256, TMP12);
-
-                vis_padd16(TMP2, TMP18, TMP2);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP14);
-
-                vis_padd16(TMP8, CONST_3, TMP8);
-                vis_mul8x16al(DST_2, CONST_512, TMP16);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-                vis_mul8x16al(DST_3, CONST_512, TMP18);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_pack16(TMP0, DST_0);
-
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-                vis_padd16(TMP10, CONST_3, TMP10);
-
-                vis_ld64_2(dest, stride, DST_0);
-                vis_padd16(TMP8, TMP16, TMP8);
-
-                vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/);
-                vis_padd16(TMP10, TMP18, TMP10);
-                vis_pack16(TMP8, DST_2);
-
-                vis_pack16(TMP10, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-
-                vis_mul8x16au(REF_S0_1, CONST_256, TMP2);
-                vis_pmerge(ZERO,     REF_S0,     TMP0);
-
-                vis_pmerge(ZERO,     REF_S2,     TMP24);
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP6);
-
-                vis_padd16(TMP0, CONST_3, TMP0);
-                vis_mul8x16au(REF_S4, CONST_256, TMP8);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-                vis_mul8x16au(REF_S4_1, CONST_256, TMP10);
-
-                vis_padd16(TMP0, TMP24, TMP0);
-                vis_mul8x16au(REF_S6, CONST_256, TMP12);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_S6_1, CONST_256, TMP14);
-
-                vis_padd16(TMP8, CONST_3, TMP8);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-
-                vis_padd16(TMP10, CONST_3, TMP10);
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-                vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20);
-
-                vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22);
-                vis_padd16(TMP0, TMP16, TMP0);
-
-                vis_padd16(TMP2, TMP18, TMP2);
-                vis_pack16(TMP0, DST_0);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_padd16(TMP8, TMP20, TMP8);
-
-                vis_padd16(TMP10, TMP22, TMP10);
-                vis_pack16(TMP8, DST_2);
-
-                vis_pack16(TMP10, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_put_y_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64_2(ref, 8, TMP2);
-
-        vis_ld64_2(ref, 16, TMP4);
-        ref += stride;
-
-        vis_ld64(ref[0], TMP6);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64_2(ref, 8, TMP8);
-        vis_faligndata(TMP2, TMP4, REF_4);
-
-        vis_ld64_2(ref, 16, TMP10);
-        ref += stride;
-
-        vis_ld64(constants_fe[0], MASK_fe);
-        vis_faligndata(TMP6, TMP8, REF_2);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP8, TMP10, REF_6);
-
-        vis_ld64(constants128[0], CONST_128);
-        height = (height >> 1) - 1;
-        do {    /* 24 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(REF_0, REF_2, TMP12);
-
-                vis_ld64_2(ref, 8, TMP2);
-                vis_xor(REF_4, REF_6, TMP16);
-
-                vis_ld64_2(ref, 16, TMP4);
-                ref += stride;
-                vis_or(REF_0, REF_2, TMP14);
-
-                vis_ld64(ref[0], TMP6);
-                vis_or(REF_4, REF_6, TMP18);
-
-                vis_ld64_2(ref, 8, TMP8);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, 16, TMP10);
-                ref += stride;
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                vis_and(TMP12, MASK_fe, TMP12);
-
-                vis_and(TMP16, MASK_fe, TMP16);
-                vis_mul8x16(CONST_128, TMP12, TMP12);
-
-                vis_mul8x16(CONST_128, TMP16, TMP16);
-                vis_xor(REF_0, REF_2, TMP0);
-
-                vis_xor(REF_4, REF_6, TMP2);
-
-                vis_or(REF_0, REF_2, TMP20);
-
-                vis_and(TMP12, MASK_7f, TMP12);
-
-                vis_and(TMP16, MASK_7f, TMP16);
-
-                vis_psub16(TMP14, TMP12, TMP12);
-                vis_st64(TMP12, dest[0]);
-
-                vis_psub16(TMP18, TMP16, TMP16);
-                vis_st64_2(TMP16, dest, 8);
-                dest += stride;
-
-                vis_or(REF_4, REF_6, TMP18);
-
-                vis_and(TMP0, MASK_fe, TMP0);
-
-                vis_and(TMP2, MASK_fe, TMP2);
-                vis_mul8x16(CONST_128, TMP0, TMP0);
-
-                vis_faligndata(TMP6, TMP8, REF_2);
-                vis_mul8x16(CONST_128, TMP2, TMP2);
-
-                vis_faligndata(TMP8, TMP10, REF_6);
-
-                vis_and(TMP0, MASK_7f, TMP0);
-
-                vis_and(TMP2, MASK_7f, TMP2);
-
-                vis_psub16(TMP20, TMP0, TMP0);
-                vis_st64(TMP0, dest[0]);
-
-                vis_psub16(TMP18, TMP2, TMP2);
-                vis_st64_2(TMP2, dest, 8);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(REF_0, REF_2, TMP12);
-
-        vis_ld64_2(ref, 8, TMP2);
-        vis_xor(REF_4, REF_6, TMP16);
-
-        vis_ld64_2(ref, 16, TMP4);
-        vis_or(REF_0, REF_2, TMP14);
-
-        vis_or(REF_4, REF_6, TMP18);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_faligndata(TMP2, TMP4, REF_4);
-
-        vis_and(TMP12, MASK_fe, TMP12);
-
-        vis_and(TMP16, MASK_fe, TMP16);
-        vis_mul8x16(CONST_128, TMP12, TMP12);
-
-        vis_mul8x16(CONST_128, TMP16, TMP16);
-        vis_xor(REF_0, REF_2, TMP0);
-
-        vis_xor(REF_4, REF_6, TMP2);
-
-        vis_or(REF_0, REF_2, TMP20);
-
-        vis_and(TMP12, MASK_7f, TMP12);
-
-        vis_and(TMP16, MASK_7f, TMP16);
-
-        vis_psub16(TMP14, TMP12, TMP12);
-        vis_st64(TMP12, dest[0]);
-
-        vis_psub16(TMP18, TMP16, TMP16);
-        vis_st64_2(TMP16, dest, 8);
-        dest += stride;
-
-        vis_or(REF_4, REF_6, TMP18);
-
-        vis_and(TMP0, MASK_fe, TMP0);
-
-        vis_and(TMP2, MASK_fe, TMP2);
-        vis_mul8x16(CONST_128, TMP0, TMP0);
-
-        vis_mul8x16(CONST_128, TMP2, TMP2);
-
-        vis_and(TMP0, MASK_7f, TMP0);
-
-        vis_and(TMP2, MASK_7f, TMP2);
-
-        vis_psub16(TMP20, TMP0, TMP0);
-        vis_st64(TMP0, dest[0]);
-
-        vis_psub16(TMP18, TMP2, TMP2);
-        vis_st64_2(TMP2, dest, 8);
-}
-
-static void MC_put_y_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64_2(ref, 8, TMP2);
-        ref += stride;
-
-        vis_ld64(ref[0], TMP4);
-
-        vis_ld64_2(ref, 8, TMP6);
-        ref += stride;
-
-        vis_ld64(constants_fe[0], MASK_fe);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP4, TMP6, REF_2);
-
-        vis_ld64(constants128[0], CONST_128);
-        height = (height >> 1) - 1;
-        do {    /* 12 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(REF_0, REF_2, TMP4);
-
-                vis_ld64_2(ref, 8, TMP2);
-                ref += stride;
-                vis_and(TMP4, MASK_fe, TMP4);
-
-                vis_or(REF_0, REF_2, TMP6);
-                vis_mul8x16(CONST_128, TMP4, TMP4);
-
-                vis_faligndata(TMP0, TMP2, REF_0);
-                vis_ld64(ref[0], TMP0);
-
-                vis_ld64_2(ref, 8, TMP2);
-                ref += stride;
-                vis_xor(REF_0, REF_2, TMP12);
-
-                vis_and(TMP4, MASK_7f, TMP4);
-
-                vis_and(TMP12, MASK_fe, TMP12);
-
-                vis_mul8x16(CONST_128, TMP12, TMP12);
-                vis_or(REF_0, REF_2, TMP14);
-
-                vis_psub16(TMP6, TMP4, DST_0);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_faligndata(TMP0, TMP2, REF_2);
-
-                vis_and(TMP12, MASK_7f, TMP12);
-
-                vis_psub16(TMP14, TMP12, DST_0);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(REF_0, REF_2, TMP4);
-
-        vis_ld64_2(ref, 8, TMP2);
-        vis_and(TMP4, MASK_fe, TMP4);
-
-        vis_or(REF_0, REF_2, TMP6);
-        vis_mul8x16(CONST_128, TMP4, TMP4);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_xor(REF_0, REF_2, TMP12);
-
-        vis_and(TMP4, MASK_7f, TMP4);
-
-        vis_and(TMP12, MASK_fe, TMP12);
-
-        vis_mul8x16(CONST_128, TMP12, TMP12);
-        vis_or(REF_0, REF_2, TMP14);
-
-        vis_psub16(TMP6, TMP4, DST_0);
-        vis_st64(DST_0, dest[0]);
-        dest += stride;
-
-        vis_and(TMP12, MASK_7f, TMP12);
-
-        vis_psub16(TMP14, TMP12, DST_0);
-        vis_st64(DST_0, dest[0]);
-}
-
-static void MC_avg_y_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        int stride_8 = stride + 8;
-        int stride_16 = stride + 16;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(ref[16], TMP4);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_faligndata(TMP0, TMP2, REF_2);
-
-        vis_ld64(constants256_512[0], CONST_256);
-        vis_faligndata(TMP2, TMP4, REF_6);
-        height >>= 1;
-
-        do {    /* 31 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_pmerge(ZERO,       REF_2,     TMP12);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP14);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                vis_pmerge(ZERO,       REF_6,     TMP16);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP18);
-
-                vis_ld64_2(ref, stride_16, TMP4);
-                ref += stride;
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(dest, 8, DST_2);
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                vis_ld64_2(ref, stride, TMP6);
-                vis_pmerge(ZERO,     REF_0,     TMP0);
-                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
-
-                vis_ld64_2(ref, stride_8, TMP8);
-                vis_pmerge(ZERO,     REF_4,     TMP4);
-
-                vis_ld64_2(ref, stride_16, TMP10);
-                ref += stride;
-
-                vis_ld64_2(dest, stride, REF_S0/*DST_4*/);
-                vis_faligndata(TMP6, TMP8, REF_2);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP6);
-
-                vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/);
-                vis_faligndata(TMP8, TMP10, REF_6);
-                vis_mul8x16al(DST_0,   CONST_512, TMP20);
-
-                vis_padd16(TMP0, CONST_3, TMP0);
-                vis_mul8x16al(DST_1,   CONST_512, TMP22);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-                vis_mul8x16al(DST_2,   CONST_512, TMP24);
-
-                vis_padd16(TMP4, CONST_3, TMP4);
-                vis_mul8x16al(DST_3,   CONST_512, TMP26);
-
-                vis_padd16(TMP6, CONST_3, TMP6);
-
-                vis_padd16(TMP12, TMP20, TMP12);
-                vis_mul8x16al(REF_S0,   CONST_512, TMP20);
-
-                vis_padd16(TMP14, TMP22, TMP14);
-                vis_mul8x16al(REF_S0_1, CONST_512, TMP22);
-
-                vis_padd16(TMP16, TMP24, TMP16);
-                vis_mul8x16al(REF_S2,   CONST_512, TMP24);
-
-                vis_padd16(TMP18, TMP26, TMP18);
-                vis_mul8x16al(REF_S2_1, CONST_512, TMP26);
-
-                vis_padd16(TMP12, TMP0, TMP12);
-                vis_mul8x16au(REF_2,   CONST_256, TMP28);
-
-                vis_padd16(TMP14, TMP2, TMP14);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP30);
-
-                vis_padd16(TMP16, TMP4, TMP16);
-                vis_mul8x16au(REF_6,   CONST_256, REF_S4);
-
-                vis_padd16(TMP18, TMP6, TMP18);
-                vis_mul8x16au(REF_6_1, CONST_256, REF_S6);
-
-                vis_pack16(TMP12, DST_0);
-                vis_padd16(TMP28, TMP0, TMP12);
-
-                vis_pack16(TMP14, DST_1);
-                vis_st64(DST_0, dest[0]);
-                vis_padd16(TMP30, TMP2, TMP14);
-
-                vis_pack16(TMP16, DST_2);
-                vis_padd16(REF_S4, TMP4, TMP16);
-
-                vis_pack16(TMP18, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-                vis_padd16(REF_S6, TMP6, TMP18);
-
-                vis_padd16(TMP12, TMP20, TMP12);
-
-                vis_padd16(TMP14, TMP22, TMP14);
-                vis_pack16(TMP12, DST_0);
-
-                vis_padd16(TMP16, TMP24, TMP16);
-                vis_pack16(TMP14, DST_1);
-                vis_st64(DST_0, dest[0]);
-
-                vis_padd16(TMP18, TMP26, TMP18);
-                vis_pack16(TMP16, DST_2);
-
-                vis_pack16(TMP18, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_avg_y_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        int stride_8 = stride + 8;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_faligndata(TMP0, TMP2, REF_2);
-
-        vis_ld64(constants256_512[0], CONST_256);
-
-        height >>= 1;
-        do {    /* 20 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_pmerge(ZERO,       REF_2,     TMP8);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP10);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                ref += stride;
-
-                vis_ld64(dest[0], DST_0);
-
-                vis_ld64_2(dest, stride, DST_2);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, stride, TMP4);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-                vis_pmerge(ZERO,       REF_0,     TMP12);
-
-                vis_ld64_2(ref, stride_8, TMP6);
-                ref += stride;
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-                vis_pmerge(ZERO,       REF_0_1,   TMP14);
-
-                vis_padd16(TMP12, CONST_3, TMP12);
-                vis_mul8x16al(DST_2,   CONST_512, TMP24);
-
-                vis_padd16(TMP14, CONST_3, TMP14);
-                vis_mul8x16al(DST_3,   CONST_512, TMP26);
-
-                vis_faligndata(TMP4, TMP6, REF_2);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_mul8x16au(REF_2,   CONST_256, TMP20);
-
-                vis_padd16(TMP8, TMP16, TMP0);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP22);
-
-                vis_padd16(TMP10, TMP18, TMP2);
-                vis_pack16(TMP0, DST_0);
-
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-                vis_padd16(TMP12, TMP20, TMP12);
-
-                vis_padd16(TMP14, TMP22, TMP14);
-
-                vis_padd16(TMP12, TMP24, TMP0);
-
-                vis_padd16(TMP14, TMP26, TMP2);
-                vis_pack16(TMP0, DST_2);
-
-                vis_pack16(TMP2, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_put_xy_16_vis (uint8_t * dest, const uint8_t * ref,
-                              const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-        int stride_16 = stride + 16;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(ref[16], TMP4);
-
-        vis_ld64(constants2[0], CONST_2);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        vis_ld64(constants256_512[0], CONST_256);
-        vis_faligndata(TMP2, TMP4, REF_S4);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-                vis_faligndata(TMP2, TMP4, REF_S6);
-        } else {
-                vis_src1(TMP2, REF_S2);
-                vis_src1(TMP4, REF_S6);
-        }
-
-        height >>= 1;
-        do {
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0, CONST_256, TMP12);
-                vis_pmerge(ZERO,      REF_S0_1,  TMP14);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                vis_mul8x16au(REF_S2, CONST_256, TMP16);
-                vis_pmerge(ZERO,      REF_S2_1,  TMP18);
-
-                vis_ld64_2(ref, stride_16, TMP4);
-                ref += stride;
-                vis_mul8x16au(REF_S4, CONST_256, TMP20);
-                vis_pmerge(ZERO,      REF_S4_1,  TMP22);
-
-                vis_ld64_2(ref, stride, TMP6);
-                vis_mul8x16au(REF_S6, CONST_256, TMP24);
-                vis_pmerge(ZERO,      REF_S6_1,  TMP26);
-
-                vis_ld64_2(ref, stride_8, TMP8);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, stride_16, TMP10);
-                ref += stride;
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                vis_faligndata(TMP6, TMP8, REF_S0);
-
-                vis_faligndata(TMP8, TMP10, REF_S4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                        vis_faligndata(TMP2, TMP4, REF_6);
-                        vis_faligndata(TMP6, TMP8, REF_S2);
-                        vis_faligndata(TMP8, TMP10, REF_S6);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                        vis_src1(TMP4, REF_6);
-                        vis_src1(TMP8, REF_S2);
-                        vis_src1(TMP10, REF_S6);
-                }
-
-                vis_mul8x16au(REF_0, CONST_256, TMP0);
-                vis_pmerge(ZERO,      REF_0_1,  TMP2);
-
-                vis_mul8x16au(REF_2, CONST_256, TMP4);
-                vis_pmerge(ZERO,      REF_2_1,  TMP6);
-
-                vis_padd16(TMP0, CONST_2, TMP8);
-                vis_mul8x16au(REF_4, CONST_256, TMP0);
-
-                vis_padd16(TMP2, CONST_2, TMP10);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP2);
-
-                vis_padd16(TMP8, TMP4, TMP8);
-                vis_mul8x16au(REF_6, CONST_256, TMP4);
-
-                vis_padd16(TMP10, TMP6, TMP10);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP6);
-
-                vis_padd16(TMP12, TMP8, TMP12);
-
-                vis_padd16(TMP14, TMP10, TMP14);
-
-                vis_padd16(TMP12, TMP16, TMP12);
-
-                vis_padd16(TMP14, TMP18, TMP14);
-                vis_pack16(TMP12, DST_0);
-
-                vis_pack16(TMP14, DST_1);
-                vis_st64(DST_0, dest[0]);
-                vis_padd16(TMP0, CONST_2, TMP12);
-
-                vis_mul8x16au(REF_S0, CONST_256, TMP0);
-                vis_padd16(TMP2, CONST_2, TMP14);
-
-                vis_mul8x16au(REF_S0_1, CONST_256, TMP2);
-                vis_padd16(TMP12, TMP4, TMP12);
-
-                vis_mul8x16au(REF_S2, CONST_256, TMP4);
-                vis_padd16(TMP14, TMP6, TMP14);
-
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP6);
-                vis_padd16(TMP20, TMP12, TMP20);
-
-                vis_padd16(TMP22, TMP14, TMP22);
-
-                vis_padd16(TMP20, TMP24, TMP20);
-
-                vis_padd16(TMP22, TMP26, TMP22);
-                vis_pack16(TMP20, DST_2);
-
-                vis_pack16(TMP22, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-                vis_padd16(TMP0, TMP4, TMP24);
-
-                vis_mul8x16au(REF_S4, CONST_256, TMP0);
-                vis_padd16(TMP2, TMP6, TMP26);
-
-                vis_mul8x16au(REF_S4_1, CONST_256, TMP2);
-                vis_padd16(TMP24, TMP8, TMP24);
-
-                vis_padd16(TMP26, TMP10, TMP26);
-                vis_pack16(TMP24, DST_0);
-
-                vis_pack16(TMP26, DST_1);
-                vis_st64(DST_0, dest[0]);
-                vis_pmerge(ZERO, REF_S6, TMP4);
-
-                vis_pmerge(ZERO,      REF_S6_1,  TMP6);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-
-                vis_padd16(TMP0, TMP12, TMP0);
-
-                vis_padd16(TMP2, TMP14, TMP2);
-                vis_pack16(TMP0, DST_2);
-
-                vis_pack16(TMP2, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_put_xy_8_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(constants2[0], CONST_2);
-
-        vis_ld64(constants256_512[0], CONST_256);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-        } else {
-                vis_src1(TMP2, REF_S2);
-        }
-
-        height >>= 1;
-        do {    /* 26 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0,   CONST_256, TMP8);
-                vis_pmerge(ZERO,        REF_S2,    TMP12);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                ref += stride;
-                vis_mul8x16au(REF_S0_1, CONST_256, TMP10);
-                vis_pmerge(ZERO,        REF_S2_1,  TMP14);
-
-                vis_ld64_2(ref, stride, TMP4);
-
-                vis_ld64_2(ref, stride_8, TMP6);
-                ref += stride;
-                vis_faligndata(TMP0, TMP2, REF_S4);
-
-                vis_pmerge(ZERO, REF_S4, TMP18);
-
-                vis_pmerge(ZERO, REF_S4_1, TMP20);
-
-                vis_faligndata(TMP4, TMP6, REF_S0);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_S6);
-                        vis_faligndata(TMP4, TMP6, REF_S2);
-                } else {
-                        vis_src1(TMP2, REF_S6);
-                        vis_src1(TMP6, REF_S2);
-                }
-
-                vis_padd16(TMP18, CONST_2, TMP18);
-                vis_mul8x16au(REF_S6,   CONST_256, TMP22);
-
-                vis_padd16(TMP20, CONST_2, TMP20);
-                vis_mul8x16au(REF_S6_1, CONST_256, TMP24);
-
-                vis_mul8x16au(REF_S0,   CONST_256, TMP26);
-                vis_pmerge(ZERO, REF_S0_1, TMP28);
-
-                vis_mul8x16au(REF_S2,   CONST_256, TMP30);
-                vis_padd16(TMP18, TMP22, TMP18);
-
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP32);
-                vis_padd16(TMP20, TMP24, TMP20);
-
-                vis_padd16(TMP8,  TMP18, TMP8);
-
-                vis_padd16(TMP10, TMP20, TMP10);
-
-                vis_padd16(TMP8,  TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_pack16(TMP8,  DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-                vis_padd16(TMP18, TMP26, TMP18);
-
-                vis_padd16(TMP20, TMP28, TMP20);
-
-                vis_padd16(TMP18, TMP30, TMP18);
-
-                vis_padd16(TMP20, TMP32, TMP20);
-                vis_pack16(TMP18, DST_2);
-
-                vis_pack16(TMP20, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_avg_xy_16_vis (uint8_t * dest, const uint8_t * ref,
-                              const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-        int stride_16 = stride + 16;
-
-        vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(ref[16], TMP4);
-
-        vis_ld64(constants6[0], CONST_6);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        vis_ld64(constants256_1024[0], CONST_256);
-        vis_faligndata(TMP2, TMP4, REF_S4);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-                vis_faligndata(TMP2, TMP4, REF_S6);
-        } else {
-                vis_src1(TMP2, REF_S2);
-                vis_src1(TMP4, REF_S6);
-        }
-
-        height >>= 1;
-        do {    /* 55 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0, CONST_256, TMP12);
-                vis_pmerge(ZERO,      REF_S0_1,  TMP14);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                vis_mul8x16au(REF_S2, CONST_256, TMP16);
-                vis_pmerge(ZERO,      REF_S2_1,  TMP18);
-
-                vis_ld64_2(ref, stride_16, TMP4);
-                ref += stride;
-                vis_mul8x16au(REF_S4, CONST_256, TMP20);
-                vis_pmerge(ZERO,      REF_S4_1,  TMP22);
-
-                vis_ld64_2(ref, stride, TMP6);
-                vis_mul8x16au(REF_S6, CONST_256, TMP24);
-                vis_pmerge(ZERO,      REF_S6_1,  TMP26);
-
-                vis_ld64_2(ref, stride_8, TMP8);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, stride_16, TMP10);
-                ref += stride;
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP6, TMP8, REF_S0);
-
-                vis_ld64_2(dest, 8, DST_2);
-                vis_faligndata(TMP8, TMP10, REF_S4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                        vis_faligndata(TMP2, TMP4, REF_6);
-                        vis_faligndata(TMP6, TMP8, REF_S2);
-                        vis_faligndata(TMP8, TMP10, REF_S6);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                        vis_src1(TMP4, REF_6);
-                        vis_src1(TMP8, REF_S2);
-                        vis_src1(TMP10, REF_S6);
-                }
-
-                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
-                vis_pmerge(ZERO, REF_0, TMP0);
-
-                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
-                vis_pmerge(ZERO,      REF_0_1,  TMP2);
-
-                vis_mul8x16au(REF_2, CONST_256, TMP4);
-                vis_pmerge(ZERO,      REF_2_1,  TMP6);
-
-                vis_mul8x16al(DST_2,   CONST_1024, REF_0);
-                vis_padd16(TMP0, CONST_6, TMP0);
-
-                vis_mul8x16al(DST_3,   CONST_1024, REF_2);
-                vis_padd16(TMP2, CONST_6, TMP2);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-                vis_mul8x16au(REF_4, CONST_256, TMP4);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP6);
-
-                vis_padd16(TMP12, TMP0, TMP12);
-                vis_mul8x16au(REF_6, CONST_256, TMP8);
-
-                vis_padd16(TMP14, TMP2, TMP14);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP10);
-
-                vis_padd16(TMP12, TMP16, TMP12);
-                vis_mul8x16au(REF_S0, CONST_256, REF_4);
-
-                vis_padd16(TMP14, TMP18, TMP14);
-                vis_mul8x16au(REF_S0_1, CONST_256, REF_6);
-
-                vis_padd16(TMP12, TMP30, TMP12);
-
-                vis_padd16(TMP14, TMP32, TMP14);
-                vis_pack16(TMP12, DST_0);
-
-                vis_pack16(TMP14, DST_1);
-                vis_st64(DST_0, dest[0]);
-                vis_padd16(TMP4, CONST_6, TMP4);
-
-                vis_ld64_2(dest, stride, DST_0);
-                vis_padd16(TMP6, CONST_6, TMP6);
-                vis_mul8x16au(REF_S2, CONST_256, TMP12);
-
-                vis_padd16(TMP4, TMP8, TMP4);
-                vis_mul8x16au(REF_S2_1, CONST_256,  TMP14);
-
-                vis_padd16(TMP6, TMP10, TMP6);
-
-                vis_padd16(TMP20, TMP4, TMP20);
-
-                vis_padd16(TMP22, TMP6, TMP22);
-
-                vis_padd16(TMP20, TMP24, TMP20);
-
-                vis_padd16(TMP22, TMP26, TMP22);
-
-                vis_padd16(TMP20, REF_0, TMP20);
-                vis_mul8x16au(REF_S4, CONST_256, REF_0);
-
-                vis_padd16(TMP22, REF_2, TMP22);
-                vis_pack16(TMP20, DST_2);
-
-                vis_pack16(TMP22, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-
-                vis_ld64_2(dest, 8, DST_2);
-                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
-                vis_pmerge(ZERO,      REF_S4_1,  REF_2);
-
-                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
-                vis_padd16(REF_4, TMP0, TMP8);
-
-                vis_mul8x16au(REF_S6, CONST_256, REF_4);
-                vis_padd16(REF_6, TMP2, TMP10);
-
-                vis_mul8x16au(REF_S6_1, CONST_256, REF_6);
-                vis_padd16(TMP8, TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-
-                vis_padd16(TMP8, TMP30, TMP8);
-
-                vis_padd16(TMP10, TMP32, TMP10);
-                vis_pack16(TMP8, DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_st64(DST_0, dest[0]);
-
-                vis_padd16(REF_0, TMP4, REF_0);
-
-                vis_mul8x16al(DST_2,   CONST_1024, TMP30);
-                vis_padd16(REF_2, TMP6, REF_2);
-
-                vis_mul8x16al(DST_3,   CONST_1024, TMP32);
-                vis_padd16(REF_0, REF_4, REF_0);
-
-                vis_padd16(REF_2, REF_6, REF_2);
-
-                vis_padd16(REF_0, TMP30, REF_0);
-
-                /* stall */
-
-                vis_padd16(REF_2, TMP32, REF_2);
-                vis_pack16(REF_0, DST_2);
-
-                vis_pack16(REF_2, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_avg_xy_8_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-
-        vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64_2(ref, 8, TMP2);
-
-        vis_ld64(constants6[0], CONST_6);
-
-        vis_ld64(constants256_1024[0], CONST_256);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-        } else {
-                vis_src1(TMP2, REF_S2);
-        }
-
-        height >>= 1;
-        do {    /* 31 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0, CONST_256, TMP8);
-                vis_pmerge(ZERO,      REF_S0_1,  TMP10);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                ref += stride;
-                vis_mul8x16au(REF_S2, CONST_256, TMP12);
-                vis_pmerge(ZERO,      REF_S2_1,  TMP14);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride, TMP4);
-                vis_faligndata(TMP0, TMP2, REF_S4);
-
-                vis_ld64_2(ref, stride_8, TMP6);
-                ref += stride;
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP4, TMP6, REF_S0);
-
-                vis_ld64_2(dest, stride, DST_2);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_S6);
-                        vis_faligndata(TMP4, TMP6, REF_S2);
-                } else {
-                        vis_src1(TMP2, REF_S6);
-                        vis_src1(TMP6, REF_S2);
-                }
-
-                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
-                vis_pmerge(ZERO, REF_S4, TMP22);
-
-                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
-                vis_pmerge(ZERO,      REF_S4_1,  TMP24);
-
-                vis_mul8x16au(REF_S6, CONST_256, TMP26);
-                vis_pmerge(ZERO,      REF_S6_1,  TMP28);
-
-                vis_mul8x16au(REF_S0, CONST_256, REF_S4);
-                vis_padd16(TMP22, CONST_6, TMP22);
-
-                vis_mul8x16au(REF_S0_1, CONST_256, REF_S6);
-                vis_padd16(TMP24, CONST_6, TMP24);
-
-                vis_mul8x16al(DST_2,   CONST_1024, REF_0);
-                vis_padd16(TMP22, TMP26, TMP22);
-
-                vis_mul8x16al(DST_3,   CONST_1024, REF_2);
-                vis_padd16(TMP24, TMP28, TMP24);
-
-                vis_mul8x16au(REF_S2, CONST_256, TMP26);
-                vis_padd16(TMP8, TMP22, TMP8);
-
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP28);
-                vis_padd16(TMP10, TMP24, TMP10);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-
-                vis_padd16(TMP8, TMP30, TMP8);
-
-                vis_padd16(TMP10, TMP32, TMP10);
-                vis_pack16(TMP8, DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_padd16(REF_S4, TMP22, TMP12);
-
-                vis_padd16(REF_S6, TMP24, TMP14);
-
-                vis_padd16(TMP12, TMP26, TMP12);
-
-                vis_padd16(TMP14, TMP28, TMP14);
-
-                vis_padd16(TMP12, REF_0, TMP12);
-
-                vis_padd16(TMP14, REF_2, TMP14);
-                vis_pack16(TMP12, DST_2);
-
-                vis_pack16(TMP14, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-/* End of rounding code */
-
-/* Start of no rounding code */
-/* The trick used in some of this file is the formula from the MMX
- * motion comp code, which is:
- *
- * (x+y)>>1 == (x&y)+((x^y)>>1)
- *
- * This allows us to average 8 bytes at a time in a 64-bit FPU reg.
- * We avoid overflows by masking before we do the shift, and we
- * implement the shift by multiplying by 1/2 using mul8x16.  So in
- * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask
- * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and
- * the value 0x80808080 is in f8):
- *
- *      fxor            f0,   f2, f10
- *      fand            f10,  f4, f10
- *      fmul8x16        f8,  f10, f10
- *      fand            f10,  f6, f10
- *      fand            f0,   f2, f12
- *      fpadd16         f12, f10, f10
- */
-
-static void MC_put_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
-                                      const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-        do {    /* 5 cycles */
-                vis_ld64(ref[0], TMP0);
-
-                vis_ld64_2(ref, 8, TMP2);
-
-                vis_ld64_2(ref, 16, TMP4);
-                ref += stride;
-
-                vis_faligndata(TMP0, TMP2, REF_0);
-                vis_st64(REF_0, dest[0]);
-
-                vis_faligndata(TMP2, TMP4, REF_2);
-                vis_st64_2(REF_2, dest, 8);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_put_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-        do {    /* 4 cycles */
-                vis_ld64(ref[0], TMP0);
-
-                vis_ld64(ref[8], TMP2);
-                ref += stride;
-
-                /* stall */
-
-                vis_faligndata(TMP0, TMP2, REF_0);
-                vis_st64(REF_0, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-
-static void MC_avg_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        int stride_8 = stride + 8;
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64(ref[8], TMP2);
-
-        vis_ld64(ref[16], TMP4);
-
-        vis_ld64(dest[0], DST_0);
-
-        vis_ld64(dest[8], DST_2);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP2, TMP4, REF_2);
-
-        vis_ld64(constants128[0], CONST_128);
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 24 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(DST_0, REF_0, TMP6);
-
-                vis_ld64_2(ref, 8, TMP2);
-                vis_and(TMP6, MASK_fe, TMP6);
-
-                vis_ld64_2(ref, 16, TMP4);
-                ref += stride;
-                vis_mul8x16(CONST_128, TMP6, TMP6);
-                vis_xor(DST_2, REF_2, TMP8);
-
-                vis_and(TMP8, MASK_fe, TMP8);
-
-                vis_and(DST_0, REF_0, TMP10);
-                vis_ld64_2(dest, stride, DST_0);
-                vis_mul8x16(CONST_128, TMP8, TMP8);
-
-                vis_and(DST_2, REF_2, TMP12);
-                vis_ld64_2(dest, stride_8, DST_2);
-
-                vis_ld64(ref[0], TMP14);
-                vis_and(TMP6, MASK_7f, TMP6);
-
-                vis_and(TMP8, MASK_7f, TMP8);
-
-                vis_padd16(TMP10, TMP6, TMP6);
-                vis_st64(TMP6, dest[0]);
-
-                vis_padd16(TMP12, TMP8, TMP8);
-                vis_st64_2(TMP8, dest, 8);
-
-                dest += stride;
-                vis_ld64_2(ref, 8, TMP16);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, 16, TMP18);
-                vis_faligndata(TMP2, TMP4, REF_2);
-                ref += stride;
-
-                vis_xor(DST_0, REF_0, TMP20);
-
-                vis_and(TMP20, MASK_fe, TMP20);
-
-                vis_xor(DST_2, REF_2, TMP22);
-                vis_mul8x16(CONST_128, TMP20, TMP20);
-
-                vis_and(TMP22, MASK_fe, TMP22);
-
-                vis_and(DST_0, REF_0, TMP24);
-                vis_mul8x16(CONST_128, TMP22, TMP22);
-
-                vis_and(DST_2, REF_2, TMP26);
-
-                vis_ld64_2(dest, stride, DST_0);
-                vis_faligndata(TMP14, TMP16, REF_0);
-
-                vis_ld64_2(dest, stride_8, DST_2);
-                vis_faligndata(TMP16, TMP18, REF_2);
-
-                vis_and(TMP20, MASK_7f, TMP20);
-
-                vis_and(TMP22, MASK_7f, TMP22);
-
-                vis_padd16(TMP24, TMP20, TMP20);
-                vis_st64(TMP20, dest[0]);
-
-                vis_padd16(TMP26, TMP22, TMP22);
-                vis_st64_2(TMP22, dest, 8);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(DST_0, REF_0, TMP6);
-
-        vis_ld64_2(ref, 8, TMP2);
-        vis_and(TMP6, MASK_fe, TMP6);
-
-        vis_ld64_2(ref, 16, TMP4);
-        vis_mul8x16(CONST_128, TMP6, TMP6);
-        vis_xor(DST_2, REF_2, TMP8);
-
-        vis_and(TMP8, MASK_fe, TMP8);
-
-        vis_and(DST_0, REF_0, TMP10);
-        vis_ld64_2(dest, stride, DST_0);
-        vis_mul8x16(CONST_128, TMP8, TMP8);
-
-        vis_and(DST_2, REF_2, TMP12);
-        vis_ld64_2(dest, stride_8, DST_2);
-
-        vis_ld64(ref[0], TMP14);
-        vis_and(TMP6, MASK_7f, TMP6);
-
-        vis_and(TMP8, MASK_7f, TMP8);
-
-        vis_padd16(TMP10, TMP6, TMP6);
-        vis_st64(TMP6, dest[0]);
-
-        vis_padd16(TMP12, TMP8, TMP8);
-        vis_st64_2(TMP8, dest, 8);
-
-        dest += stride;
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_faligndata(TMP2, TMP4, REF_2);
-
-        vis_xor(DST_0, REF_0, TMP20);
-
-        vis_and(TMP20, MASK_fe, TMP20);
-
-        vis_xor(DST_2, REF_2, TMP22);
-        vis_mul8x16(CONST_128, TMP20, TMP20);
-
-        vis_and(TMP22, MASK_fe, TMP22);
-
-        vis_and(DST_0, REF_0, TMP24);
-        vis_mul8x16(CONST_128, TMP22, TMP22);
-
-        vis_and(DST_2, REF_2, TMP26);
-
-        vis_and(TMP20, MASK_7f, TMP20);
-
-        vis_and(TMP22, MASK_7f, TMP22);
-
-        vis_padd16(TMP24, TMP20, TMP20);
-        vis_st64(TMP20, dest[0]);
-
-        vis_padd16(TMP26, TMP22, TMP22);
-        vis_st64_2(TMP22, dest, 8);
-}
-
-static void MC_avg_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64(ref[8], TMP2);
-
-        vis_ld64(dest[0], DST_0);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants128[0], CONST_128);
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 12 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(DST_0, REF_0, TMP4);
-
-                vis_ld64(ref[8], TMP2);
-                vis_and(TMP4, MASK_fe, TMP4);
-
-                vis_and(DST_0, REF_0, TMP6);
-                vis_ld64_2(dest, stride, DST_0);
-                ref += stride;
-                vis_mul8x16(CONST_128, TMP4, TMP4);
-
-                vis_ld64(ref[0], TMP12);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64(ref[8], TMP2);
-                vis_xor(DST_0, REF_0, TMP0);
-                ref += stride;
-
-                vis_and(TMP0, MASK_fe, TMP0);
-
-                vis_and(TMP4, MASK_7f, TMP4);
-
-                vis_padd16(TMP6, TMP4, TMP4);
-                vis_st64(TMP4, dest[0]);
-                dest += stride;
-                vis_mul8x16(CONST_128, TMP0, TMP0);
-
-                vis_and(DST_0, REF_0, TMP6);
-                vis_ld64_2(dest, stride, DST_0);
-
-                vis_faligndata(TMP12, TMP2, REF_0);
-
-                vis_and(TMP0, MASK_7f, TMP0);
-
-                vis_padd16(TMP6, TMP0, TMP4);
-                vis_st64(TMP4, dest[0]);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(DST_0, REF_0, TMP4);
-
-        vis_ld64(ref[8], TMP2);
-        vis_and(TMP4, MASK_fe, TMP4);
-
-        vis_and(DST_0, REF_0, TMP6);
-        vis_ld64_2(dest, stride, DST_0);
-        vis_mul8x16(CONST_128, TMP4, TMP4);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_xor(DST_0, REF_0, TMP0);
-
-        vis_and(TMP0, MASK_fe, TMP0);
-
-        vis_and(TMP4, MASK_7f, TMP4);
-
-        vis_padd16(TMP6, TMP4, TMP4);
-        vis_st64(TMP4, dest[0]);
-        dest += stride;
-        vis_mul8x16(CONST_128, TMP0, TMP0);
-
-        vis_and(DST_0, REF_0, TMP6);
-
-        vis_and(TMP0, MASK_7f, TMP0);
-
-        vis_padd16(TMP6, TMP0, TMP4);
-        vis_st64(TMP4, dest[0]);
-}
-
-static void MC_put_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0],    TMP0);
-
-        vis_ld64_2(ref, 8,  TMP2);
-
-        vis_ld64_2(ref, 16, TMP4);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants128[0], CONST_128);
-        vis_faligndata(TMP2, TMP4, REF_4);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_2);
-                vis_faligndata(TMP2, TMP4, REF_6);
-        } else {
-                vis_src1(TMP2, REF_2);
-                vis_src1(TMP4, REF_6);
-        }
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 34 cycles */
-                vis_ld64(ref[0],    TMP0);
-                vis_xor(REF_0, REF_2, TMP6);
-
-                vis_ld64_2(ref, 8,  TMP2);
-                vis_xor(REF_4, REF_6, TMP8);
-
-                vis_ld64_2(ref, 16, TMP4);
-                vis_and(TMP6, MASK_fe, TMP6);
-                ref += stride;
-
-                vis_ld64(ref[0],    TMP14);
-                vis_mul8x16(CONST_128, TMP6, TMP6);
-                vis_and(TMP8, MASK_fe, TMP8);
-
-                vis_ld64_2(ref, 8,  TMP16);
-                vis_mul8x16(CONST_128, TMP8, TMP8);
-                vis_and(REF_0, REF_2, TMP10);
-
-                vis_ld64_2(ref, 16, TMP18);
-                ref += stride;
-                vis_and(REF_4, REF_6, TMP12);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                        vis_faligndata(TMP2, TMP4, REF_6);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                        vis_src1(TMP4, REF_6);
-                }
-
-                vis_and(TMP6, MASK_7f, TMP6);
-
-                vis_and(TMP8, MASK_7f, TMP8);
-
-                vis_padd16(TMP10, TMP6, TMP6);
-                vis_st64(TMP6, dest[0]);
-
-                vis_padd16(TMP12, TMP8, TMP8);
-                vis_st64_2(TMP8, dest, 8);
-                dest += stride;
-
-                vis_xor(REF_0, REF_2, TMP6);
-
-                vis_xor(REF_4, REF_6, TMP8);
-
-                vis_and(TMP6, MASK_fe, TMP6);
-
-                vis_mul8x16(CONST_128, TMP6, TMP6);
-                vis_and(TMP8, MASK_fe, TMP8);
-
-                vis_mul8x16(CONST_128, TMP8, TMP8);
-                vis_and(REF_0, REF_2, TMP10);
-
-                vis_and(REF_4, REF_6, TMP12);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_faligndata(TMP14, TMP16, REF_0);
-
-                vis_faligndata(TMP16, TMP18, REF_4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP14, TMP16, REF_2);
-                        vis_faligndata(TMP16, TMP18, REF_6);
-                } else {
-                        vis_src1(TMP16, REF_2);
-                        vis_src1(TMP18, REF_6);
-                }
-
-                vis_and(TMP6, MASK_7f, TMP6);
-
-                vis_and(TMP8, MASK_7f, TMP8);
-
-                vis_padd16(TMP10, TMP6, TMP6);
-                vis_st64(TMP6, dest[0]);
-
-                vis_padd16(TMP12, TMP8, TMP8);
-                vis_st64_2(TMP8, dest, 8);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0],    TMP0);
-        vis_xor(REF_0, REF_2, TMP6);
-
-        vis_ld64_2(ref, 8,  TMP2);
-        vis_xor(REF_4, REF_6, TMP8);
-
-        vis_ld64_2(ref, 16, TMP4);
-        vis_and(TMP6, MASK_fe, TMP6);
-
-        vis_mul8x16(CONST_128, TMP6, TMP6);
-        vis_and(TMP8, MASK_fe, TMP8);
-
-        vis_mul8x16(CONST_128, TMP8, TMP8);
-        vis_and(REF_0, REF_2, TMP10);
-
-        vis_and(REF_4, REF_6, TMP12);
-
-        vis_alignaddr_g0((void *)off);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_faligndata(TMP2, TMP4, REF_4);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_2);
-                vis_faligndata(TMP2, TMP4, REF_6);
-        } else {
-                vis_src1(TMP2, REF_2);
-                vis_src1(TMP4, REF_6);
-        }
-
-        vis_and(TMP6, MASK_7f, TMP6);
-
-        vis_and(TMP8, MASK_7f, TMP8);
-
-        vis_padd16(TMP10, TMP6, TMP6);
-        vis_st64(TMP6, dest[0]);
-
-        vis_padd16(TMP12, TMP8, TMP8);
-        vis_st64_2(TMP8, dest, 8);
-        dest += stride;
-
-        vis_xor(REF_0, REF_2, TMP6);
-
-        vis_xor(REF_4, REF_6, TMP8);
-
-        vis_and(TMP6, MASK_fe, TMP6);
-
-        vis_mul8x16(CONST_128, TMP6, TMP6);
-        vis_and(TMP8, MASK_fe, TMP8);
-
-        vis_mul8x16(CONST_128, TMP8, TMP8);
-        vis_and(REF_0, REF_2, TMP10);
-
-        vis_and(REF_4, REF_6, TMP12);
-
-        vis_and(TMP6, MASK_7f, TMP6);
-
-        vis_and(TMP8, MASK_7f, TMP8);
-
-        vis_padd16(TMP10, TMP6, TMP6);
-        vis_st64(TMP6, dest[0]);
-
-        vis_padd16(TMP12, TMP8, TMP8);
-        vis_st64_2(TMP8, dest, 8);
-}
-
-static void MC_put_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64(ref[8], TMP2);
-
-        vis_ld64(constants_fe[0], MASK_fe);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-
-        vis_ld64(constants128[0], CONST_128);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_2);
-        } else {
-                vis_src1(TMP2, REF_2);
-        }
-
-        ref += stride;
-        height = (height >> 1) - 1;
-
-        do {    /* 20 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(REF_0, REF_2, TMP4);
-
-                vis_ld64_2(ref, 8, TMP2);
-                vis_and(TMP4, MASK_fe, TMP4);
-                ref += stride;
-
-                vis_ld64(ref[0], TMP8);
-                vis_and(REF_0, REF_2, TMP6);
-                vis_mul8x16(CONST_128, TMP4, TMP4);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, 8, TMP10);
-                ref += stride;
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                }
-
-                vis_and(TMP4, MASK_7f, TMP4);
-
-                vis_padd16(TMP6, TMP4, DST_0);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_xor(REF_0, REF_2, TMP12);
-
-                vis_and(TMP12, MASK_fe, TMP12);
-
-                vis_and(REF_0, REF_2, TMP14);
-                vis_mul8x16(CONST_128, TMP12, TMP12);
-
-                vis_alignaddr_g0((void *)off);
-                vis_faligndata(TMP8, TMP10, REF_0);
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP8, TMP10, REF_2);
-                } else {
-                        vis_src1(TMP10, REF_2);
-                }
-
-                vis_and(TMP12, MASK_7f, TMP12);
-
-                vis_padd16(TMP14, TMP12, DST_0);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(REF_0, REF_2, TMP4);
-
-        vis_ld64_2(ref, 8, TMP2);
-        vis_and(TMP4, MASK_fe, TMP4);
-
-        vis_and(REF_0, REF_2, TMP6);
-        vis_mul8x16(CONST_128, TMP4, TMP4);
-
-        vis_alignaddr_g0((void *)off);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_2);
-        } else {
-                vis_src1(TMP2, REF_2);
-        }
-
-        vis_and(TMP4, MASK_7f, TMP4);
-
-        vis_padd16(TMP6, TMP4, DST_0);
-        vis_st64(DST_0, dest[0]);
-        dest += stride;
-
-        vis_xor(REF_0, REF_2, TMP12);
-
-        vis_and(TMP12, MASK_fe, TMP12);
-
-        vis_and(REF_0, REF_2, TMP14);
-        vis_mul8x16(CONST_128, TMP12, TMP12);
-
-        vis_and(TMP12, MASK_7f, TMP12);
-
-        vis_padd16(TMP14, TMP12, DST_0);
-        vis_st64(DST_0, dest[0]);
-        dest += stride;
-}
-
-static void MC_avg_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_fzero(ZERO);
-        vis_ld64(constants256_512[0], CONST_256);
-
-        ref = vis_alignaddr(ref);
-        do {    /* 26 cycles */
-                vis_ld64(ref[0], TMP0);
-
-                vis_ld64(ref[8], TMP2);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64(ref[16], TMP4);
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64(dest[8], DST_2);
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                        vis_faligndata(TMP2, TMP4, REF_6);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                        vis_src1(TMP4, REF_6);
-                }
-
-                vis_mul8x16au(REF_0,   CONST_256, TMP0);
-
-                vis_pmerge(ZERO,     REF_2,     TMP4);
-                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
-
-                vis_pmerge(ZERO, REF_2_1, TMP6);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-
-                vis_mul8x16al(DST_0,   CONST_512, TMP4);
-                vis_padd16(TMP2, TMP6, TMP2);
-
-                vis_mul8x16al(DST_1,   CONST_512, TMP6);
-
-                vis_mul8x16au(REF_6,   CONST_256, TMP12);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP14);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_4,   CONST_256, TMP16);
-
-                vis_padd16(TMP0, CONST_3, TMP8);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP18);
-
-                vis_padd16(TMP2, CONST_3, TMP10);
-                vis_pack16(TMP8, DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_padd16(TMP16, TMP12, TMP0);
-
-                vis_st64(DST_0, dest[0]);
-                vis_mul8x16al(DST_2,   CONST_512, TMP4);
-                vis_padd16(TMP18, TMP14, TMP2);
-
-                vis_mul8x16al(DST_3,   CONST_512, TMP6);
-                vis_padd16(TMP0, CONST_3, TMP0);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_pack16(TMP0, DST_2);
-
-                vis_pack16(TMP2, DST_3);
-                vis_st64(DST_2, dest[8]);
-
-                ref += stride;
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_avg_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_times_2 = stride << 1;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_fzero(ZERO);
-        vis_ld64(constants256_512[0], CONST_256);
-
-        ref = vis_alignaddr(ref);
-        height >>= 2;
-        do {    /* 47 cycles */
-                vis_ld64(ref[0],   TMP0);
-
-                vis_ld64_2(ref, 8, TMP2);
-                ref += stride;
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64(ref[0],   TMP4);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, 8, TMP6);
-                ref += stride;
-
-                vis_ld64(ref[0],   TMP8);
-
-                vis_ld64_2(ref, 8, TMP10);
-                ref += stride;
-                vis_faligndata(TMP4, TMP6, REF_4);
-
-                vis_ld64(ref[0],   TMP12);
-
-                vis_ld64_2(ref, 8, TMP14);
-                ref += stride;
-                vis_faligndata(TMP8, TMP10, REF_S0);
-
-                vis_faligndata(TMP12, TMP14, REF_S4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-
-                        vis_ld64(dest[0], DST_0);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-
-                        vis_ld64_2(dest, stride, DST_2);
-                        vis_faligndata(TMP4, TMP6, REF_6);
-
-                        vis_faligndata(TMP8, TMP10, REF_S2);
-
-                        vis_faligndata(TMP12, TMP14, REF_S6);
-                } else {
-                        vis_ld64(dest[0], DST_0);
-                        vis_src1(TMP2, REF_2);
-
-                        vis_ld64_2(dest, stride, DST_2);
-                        vis_src1(TMP6, REF_6);
-
-                        vis_src1(TMP10, REF_S2);
-
-                        vis_src1(TMP14, REF_S6);
-                }
-
-                vis_pmerge(ZERO,     REF_0,     TMP0);
-                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
-
-                vis_pmerge(ZERO,     REF_2,     TMP4);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP6);
-
-                vis_padd16(TMP0, CONST_3, TMP0);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-                vis_mul8x16au(REF_4, CONST_256, TMP8);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP10);
-
-                vis_padd16(TMP0, TMP16, TMP0);
-                vis_mul8x16au(REF_6, CONST_256, TMP12);
-
-                vis_padd16(TMP2, TMP18, TMP2);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP14);
-
-                vis_padd16(TMP8, CONST_3, TMP8);
-                vis_mul8x16al(DST_2, CONST_512, TMP16);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-                vis_mul8x16al(DST_3, CONST_512, TMP18);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_pack16(TMP0, DST_0);
-
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-                vis_padd16(TMP10, CONST_3, TMP10);
-
-                vis_ld64_2(dest, stride, DST_0);
-                vis_padd16(TMP8, TMP16, TMP8);
-
-                vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/);
-                vis_padd16(TMP10, TMP18, TMP10);
-                vis_pack16(TMP8, DST_2);
-
-                vis_pack16(TMP10, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-
-                vis_mul8x16au(REF_S0_1, CONST_256, TMP2);
-                vis_pmerge(ZERO,     REF_S0,     TMP0);
-
-                vis_pmerge(ZERO,     REF_S2,     TMP24);
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP6);
-
-                vis_padd16(TMP0, CONST_3, TMP0);
-                vis_mul8x16au(REF_S4, CONST_256, TMP8);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-                vis_mul8x16au(REF_S4_1, CONST_256, TMP10);
-
-                vis_padd16(TMP0, TMP24, TMP0);
-                vis_mul8x16au(REF_S6, CONST_256, TMP12);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_S6_1, CONST_256, TMP14);
-
-                vis_padd16(TMP8, CONST_3, TMP8);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-
-                vis_padd16(TMP10, CONST_3, TMP10);
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-                vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20);
-
-                vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22);
-                vis_padd16(TMP0, TMP16, TMP0);
-
-                vis_padd16(TMP2, TMP18, TMP2);
-                vis_pack16(TMP0, DST_0);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_padd16(TMP8, TMP20, TMP8);
-
-                vis_padd16(TMP10, TMP22, TMP10);
-                vis_pack16(TMP8, DST_2);
-
-                vis_pack16(TMP10, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_put_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64_2(ref, 8, TMP2);
-
-        vis_ld64_2(ref, 16, TMP4);
-        ref += stride;
-
-        vis_ld64(ref[0], TMP6);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64_2(ref, 8, TMP8);
-        vis_faligndata(TMP2, TMP4, REF_4);
-
-        vis_ld64_2(ref, 16, TMP10);
-        ref += stride;
-
-        vis_ld64(constants_fe[0], MASK_fe);
-        vis_faligndata(TMP6, TMP8, REF_2);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP8, TMP10, REF_6);
-
-        vis_ld64(constants128[0], CONST_128);
-        height = (height >> 1) - 1;
-        do {    /* 24 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(REF_0, REF_2, TMP12);
-
-                vis_ld64_2(ref, 8, TMP2);
-                vis_xor(REF_4, REF_6, TMP16);
-
-                vis_ld64_2(ref, 16, TMP4);
-                ref += stride;
-                vis_and(REF_0, REF_2, TMP14);
-
-                vis_ld64(ref[0], TMP6);
-                vis_and(REF_4, REF_6, TMP18);
-
-                vis_ld64_2(ref, 8, TMP8);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, 16, TMP10);
-                ref += stride;
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                vis_and(TMP12, MASK_fe, TMP12);
-
-                vis_and(TMP16, MASK_fe, TMP16);
-                vis_mul8x16(CONST_128, TMP12, TMP12);
-
-                vis_mul8x16(CONST_128, TMP16, TMP16);
-                vis_xor(REF_0, REF_2, TMP0);
-
-                vis_xor(REF_4, REF_6, TMP2);
-
-                vis_and(REF_0, REF_2, TMP20);
-
-                vis_and(TMP12, MASK_7f, TMP12);
-
-                vis_and(TMP16, MASK_7f, TMP16);
-
-                vis_padd16(TMP14, TMP12, TMP12);
-                vis_st64(TMP12, dest[0]);
-
-                vis_padd16(TMP18, TMP16, TMP16);
-                vis_st64_2(TMP16, dest, 8);
-                dest += stride;
-
-                vis_and(REF_4, REF_6, TMP18);
-
-                vis_and(TMP0, MASK_fe, TMP0);
-
-                vis_and(TMP2, MASK_fe, TMP2);
-                vis_mul8x16(CONST_128, TMP0, TMP0);
-
-                vis_faligndata(TMP6, TMP8, REF_2);
-                vis_mul8x16(CONST_128, TMP2, TMP2);
-
-                vis_faligndata(TMP8, TMP10, REF_6);
-
-                vis_and(TMP0, MASK_7f, TMP0);
-
-                vis_and(TMP2, MASK_7f, TMP2);
-
-                vis_padd16(TMP20, TMP0, TMP0);
-                vis_st64(TMP0, dest[0]);
-
-                vis_padd16(TMP18, TMP2, TMP2);
-                vis_st64_2(TMP2, dest, 8);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(REF_0, REF_2, TMP12);
-
-        vis_ld64_2(ref, 8, TMP2);
-        vis_xor(REF_4, REF_6, TMP16);
-
-        vis_ld64_2(ref, 16, TMP4);
-        vis_and(REF_0, REF_2, TMP14);
-
-        vis_and(REF_4, REF_6, TMP18);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_faligndata(TMP2, TMP4, REF_4);
-
-        vis_and(TMP12, MASK_fe, TMP12);
-
-        vis_and(TMP16, MASK_fe, TMP16);
-        vis_mul8x16(CONST_128, TMP12, TMP12);
-
-        vis_mul8x16(CONST_128, TMP16, TMP16);
-        vis_xor(REF_0, REF_2, TMP0);
-
-        vis_xor(REF_4, REF_6, TMP2);
-
-        vis_and(REF_0, REF_2, TMP20);
-
-        vis_and(TMP12, MASK_7f, TMP12);
-
-        vis_and(TMP16, MASK_7f, TMP16);
-
-        vis_padd16(TMP14, TMP12, TMP12);
-        vis_st64(TMP12, dest[0]);
-
-        vis_padd16(TMP18, TMP16, TMP16);
-        vis_st64_2(TMP16, dest, 8);
-        dest += stride;
-
-        vis_and(REF_4, REF_6, TMP18);
-
-        vis_and(TMP0, MASK_fe, TMP0);
-
-        vis_and(TMP2, MASK_fe, TMP2);
-        vis_mul8x16(CONST_128, TMP0, TMP0);
-
-        vis_mul8x16(CONST_128, TMP2, TMP2);
-
-        vis_and(TMP0, MASK_7f, TMP0);
-
-        vis_and(TMP2, MASK_7f, TMP2);
-
-        vis_padd16(TMP20, TMP0, TMP0);
-        vis_st64(TMP0, dest[0]);
-
-        vis_padd16(TMP18, TMP2, TMP2);
-        vis_st64_2(TMP2, dest, 8);
-}
-
-static void MC_put_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        ref = vis_alignaddr(ref);
-        vis_ld64(ref[0], TMP0);
-
-        vis_ld64_2(ref, 8, TMP2);
-        ref += stride;
-
-        vis_ld64(ref[0], TMP4);
-
-        vis_ld64_2(ref, 8, TMP6);
-        ref += stride;
-
-        vis_ld64(constants_fe[0], MASK_fe);
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_ld64(constants_7f[0], MASK_7f);
-        vis_faligndata(TMP4, TMP6, REF_2);
-
-        vis_ld64(constants128[0], CONST_128);
-        height = (height >> 1) - 1;
-        do {    /* 12 cycles */
-                vis_ld64(ref[0], TMP0);
-                vis_xor(REF_0, REF_2, TMP4);
-
-                vis_ld64_2(ref, 8, TMP2);
-                ref += stride;
-                vis_and(TMP4, MASK_fe, TMP4);
-
-                vis_and(REF_0, REF_2, TMP6);
-                vis_mul8x16(CONST_128, TMP4, TMP4);
-
-                vis_faligndata(TMP0, TMP2, REF_0);
-                vis_ld64(ref[0], TMP0);
-
-                vis_ld64_2(ref, 8, TMP2);
-                ref += stride;
-                vis_xor(REF_0, REF_2, TMP12);
-
-                vis_and(TMP4, MASK_7f, TMP4);
-
-                vis_and(TMP12, MASK_fe, TMP12);
-
-                vis_mul8x16(CONST_128, TMP12, TMP12);
-                vis_and(REF_0, REF_2, TMP14);
-
-                vis_padd16(TMP6, TMP4, DST_0);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_faligndata(TMP0, TMP2, REF_2);
-
-                vis_and(TMP12, MASK_7f, TMP12);
-
-                vis_padd16(TMP14, TMP12, DST_0);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-        } while (--height);
-
-        vis_ld64(ref[0], TMP0);
-        vis_xor(REF_0, REF_2, TMP4);
-
-        vis_ld64_2(ref, 8, TMP2);
-        vis_and(TMP4, MASK_fe, TMP4);
-
-        vis_and(REF_0, REF_2, TMP6);
-        vis_mul8x16(CONST_128, TMP4, TMP4);
-
-        vis_faligndata(TMP0, TMP2, REF_0);
-
-        vis_xor(REF_0, REF_2, TMP12);
-
-        vis_and(TMP4, MASK_7f, TMP4);
-
-        vis_and(TMP12, MASK_fe, TMP12);
-
-        vis_mul8x16(CONST_128, TMP12, TMP12);
-        vis_and(REF_0, REF_2, TMP14);
-
-        vis_padd16(TMP6, TMP4, DST_0);
-        vis_st64(DST_0, dest[0]);
-        dest += stride;
-
-        vis_and(TMP12, MASK_7f, TMP12);
-
-        vis_padd16(TMP14, TMP12, DST_0);
-        vis_st64(DST_0, dest[0]);
-}
-
-static void MC_avg_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
-                             const int stride, int height)
-{
-        int stride_8 = stride + 8;
-        int stride_16 = stride + 16;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(ref[16], TMP4);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_faligndata(TMP0, TMP2, REF_2);
-
-        vis_ld64(constants256_512[0], CONST_256);
-        vis_faligndata(TMP2, TMP4, REF_6);
-        height >>= 1;
-
-        do {    /* 31 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_pmerge(ZERO,       REF_2,     TMP12);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP14);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                vis_pmerge(ZERO,       REF_6,     TMP16);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP18);
-
-                vis_ld64_2(ref, stride_16, TMP4);
-                ref += stride;
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(dest, 8, DST_2);
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                vis_ld64_2(ref, stride, TMP6);
-                vis_pmerge(ZERO,     REF_0,     TMP0);
-                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
-
-                vis_ld64_2(ref, stride_8, TMP8);
-                vis_pmerge(ZERO,     REF_4,     TMP4);
-
-                vis_ld64_2(ref, stride_16, TMP10);
-                ref += stride;
-
-                vis_ld64_2(dest, stride, REF_S0/*DST_4*/);
-                vis_faligndata(TMP6, TMP8, REF_2);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP6);
-
-                vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/);
-                vis_faligndata(TMP8, TMP10, REF_6);
-                vis_mul8x16al(DST_0,   CONST_512, TMP20);
-
-                vis_padd16(TMP0, CONST_3, TMP0);
-                vis_mul8x16al(DST_1,   CONST_512, TMP22);
-
-                vis_padd16(TMP2, CONST_3, TMP2);
-                vis_mul8x16al(DST_2,   CONST_512, TMP24);
-
-                vis_padd16(TMP4, CONST_3, TMP4);
-                vis_mul8x16al(DST_3,   CONST_512, TMP26);
-
-                vis_padd16(TMP6, CONST_3, TMP6);
-
-                vis_padd16(TMP12, TMP20, TMP12);
-                vis_mul8x16al(REF_S0,   CONST_512, TMP20);
-
-                vis_padd16(TMP14, TMP22, TMP14);
-                vis_mul8x16al(REF_S0_1, CONST_512, TMP22);
-
-                vis_padd16(TMP16, TMP24, TMP16);
-                vis_mul8x16al(REF_S2,   CONST_512, TMP24);
-
-                vis_padd16(TMP18, TMP26, TMP18);
-                vis_mul8x16al(REF_S2_1, CONST_512, TMP26);
-
-                vis_padd16(TMP12, TMP0, TMP12);
-                vis_mul8x16au(REF_2,   CONST_256, TMP28);
-
-                vis_padd16(TMP14, TMP2, TMP14);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP30);
-
-                vis_padd16(TMP16, TMP4, TMP16);
-                vis_mul8x16au(REF_6,   CONST_256, REF_S4);
-
-                vis_padd16(TMP18, TMP6, TMP18);
-                vis_mul8x16au(REF_6_1, CONST_256, REF_S6);
-
-                vis_pack16(TMP12, DST_0);
-                vis_padd16(TMP28, TMP0, TMP12);
-
-                vis_pack16(TMP14, DST_1);
-                vis_st64(DST_0, dest[0]);
-                vis_padd16(TMP30, TMP2, TMP14);
-
-                vis_pack16(TMP16, DST_2);
-                vis_padd16(REF_S4, TMP4, TMP16);
-
-                vis_pack16(TMP18, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-                vis_padd16(REF_S6, TMP6, TMP18);
-
-                vis_padd16(TMP12, TMP20, TMP12);
-
-                vis_padd16(TMP14, TMP22, TMP14);
-                vis_pack16(TMP12, DST_0);
-
-                vis_padd16(TMP16, TMP24, TMP16);
-                vis_pack16(TMP14, DST_1);
-                vis_st64(DST_0, dest[0]);
-
-                vis_padd16(TMP18, TMP26, TMP18);
-                vis_pack16(TMP16, DST_2);
-
-                vis_pack16(TMP18, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_avg_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref,
-                            const int stride, int height)
-{
-        int stride_8 = stride + 8;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(constants3[0], CONST_3);
-        vis_faligndata(TMP0, TMP2, REF_2);
-
-        vis_ld64(constants256_512[0], CONST_256);
-
-        height >>= 1;
-        do {    /* 20 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_pmerge(ZERO,       REF_2,     TMP8);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP10);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                ref += stride;
-
-                vis_ld64(dest[0], DST_0);
-
-                vis_ld64_2(dest, stride, DST_2);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, stride, TMP4);
-                vis_mul8x16al(DST_0,   CONST_512, TMP16);
-                vis_pmerge(ZERO,       REF_0,     TMP12);
-
-                vis_ld64_2(ref, stride_8, TMP6);
-                ref += stride;
-                vis_mul8x16al(DST_1,   CONST_512, TMP18);
-                vis_pmerge(ZERO,       REF_0_1,   TMP14);
-
-                vis_padd16(TMP12, CONST_3, TMP12);
-                vis_mul8x16al(DST_2,   CONST_512, TMP24);
-
-                vis_padd16(TMP14, CONST_3, TMP14);
-                vis_mul8x16al(DST_3,   CONST_512, TMP26);
-
-                vis_faligndata(TMP4, TMP6, REF_2);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_mul8x16au(REF_2,   CONST_256, TMP20);
-
-                vis_padd16(TMP8, TMP16, TMP0);
-                vis_mul8x16au(REF_2_1, CONST_256, TMP22);
-
-                vis_padd16(TMP10, TMP18, TMP2);
-                vis_pack16(TMP0, DST_0);
-
-                vis_pack16(TMP2, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-                vis_padd16(TMP12, TMP20, TMP12);
-
-                vis_padd16(TMP14, TMP22, TMP14);
-
-                vis_padd16(TMP12, TMP24, TMP0);
-
-                vis_padd16(TMP14, TMP26, TMP2);
-                vis_pack16(TMP0, DST_2);
-
-                vis_pack16(TMP2, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_put_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
-                                       const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-        int stride_16 = stride + 16;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(ref[16], TMP4);
-
-        vis_ld64(constants1[0], CONST_1);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        vis_ld64(constants256_512[0], CONST_256);
-        vis_faligndata(TMP2, TMP4, REF_S4);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-                vis_faligndata(TMP2, TMP4, REF_S6);
-        } else {
-                vis_src1(TMP2, REF_S2);
-                vis_src1(TMP4, REF_S6);
-        }
-
-        height >>= 1;
-        do {
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0, CONST_256, TMP12);
-                vis_pmerge(ZERO,      REF_S0_1,  TMP14);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                vis_mul8x16au(REF_S2, CONST_256, TMP16);
-                vis_pmerge(ZERO,      REF_S2_1,  TMP18);
-
-                vis_ld64_2(ref, stride_16, TMP4);
-                ref += stride;
-                vis_mul8x16au(REF_S4, CONST_256, TMP20);
-                vis_pmerge(ZERO,      REF_S4_1,  TMP22);
-
-                vis_ld64_2(ref, stride, TMP6);
-                vis_mul8x16au(REF_S6, CONST_256, TMP24);
-                vis_pmerge(ZERO,      REF_S6_1,  TMP26);
-
-                vis_ld64_2(ref, stride_8, TMP8);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, stride_16, TMP10);
-                ref += stride;
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                vis_faligndata(TMP6, TMP8, REF_S0);
-
-                vis_faligndata(TMP8, TMP10, REF_S4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                        vis_faligndata(TMP2, TMP4, REF_6);
-                        vis_faligndata(TMP6, TMP8, REF_S2);
-                        vis_faligndata(TMP8, TMP10, REF_S6);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                        vis_src1(TMP4, REF_6);
-                        vis_src1(TMP8, REF_S2);
-                        vis_src1(TMP10, REF_S6);
-                }
-
-                vis_mul8x16au(REF_0, CONST_256, TMP0);
-                vis_pmerge(ZERO,      REF_0_1,  TMP2);
-
-                vis_mul8x16au(REF_2, CONST_256, TMP4);
-                vis_pmerge(ZERO,      REF_2_1,  TMP6);
-
-                vis_padd16(TMP0, CONST_2, TMP8);
-                vis_mul8x16au(REF_4, CONST_256, TMP0);
-
-                vis_padd16(TMP2, CONST_1, TMP10);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP2);
-
-                vis_padd16(TMP8, TMP4, TMP8);
-                vis_mul8x16au(REF_6, CONST_256, TMP4);
-
-                vis_padd16(TMP10, TMP6, TMP10);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP6);
-
-                vis_padd16(TMP12, TMP8, TMP12);
-
-                vis_padd16(TMP14, TMP10, TMP14);
-
-                vis_padd16(TMP12, TMP16, TMP12);
-
-                vis_padd16(TMP14, TMP18, TMP14);
-                vis_pack16(TMP12, DST_0);
-
-                vis_pack16(TMP14, DST_1);
-                vis_st64(DST_0, dest[0]);
-                vis_padd16(TMP0, CONST_1, TMP12);
-
-                vis_mul8x16au(REF_S0, CONST_256, TMP0);
-                vis_padd16(TMP2, CONST_1, TMP14);
-
-                vis_mul8x16au(REF_S0_1, CONST_256, TMP2);
-                vis_padd16(TMP12, TMP4, TMP12);
-
-                vis_mul8x16au(REF_S2, CONST_256, TMP4);
-                vis_padd16(TMP14, TMP6, TMP14);
-
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP6);
-                vis_padd16(TMP20, TMP12, TMP20);
-
-                vis_padd16(TMP22, TMP14, TMP22);
-
-                vis_padd16(TMP20, TMP24, TMP20);
-
-                vis_padd16(TMP22, TMP26, TMP22);
-                vis_pack16(TMP20, DST_2);
-
-                vis_pack16(TMP22, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-                vis_padd16(TMP0, TMP4, TMP24);
-
-                vis_mul8x16au(REF_S4, CONST_256, TMP0);
-                vis_padd16(TMP2, TMP6, TMP26);
-
-                vis_mul8x16au(REF_S4_1, CONST_256, TMP2);
-                vis_padd16(TMP24, TMP8, TMP24);
-
-                vis_padd16(TMP26, TMP10, TMP26);
-                vis_pack16(TMP24, DST_0);
-
-                vis_pack16(TMP26, DST_1);
-                vis_st64(DST_0, dest[0]);
-                vis_pmerge(ZERO, REF_S6, TMP4);
-
-                vis_pmerge(ZERO,      REF_S6_1,  TMP6);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-
-                vis_padd16(TMP0, TMP12, TMP0);
-
-                vis_padd16(TMP2, TMP14, TMP2);
-                vis_pack16(TMP0, DST_2);
-
-                vis_pack16(TMP2, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_put_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref,
-                                      const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-
-        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(constants1[0], CONST_1);
-
-        vis_ld64(constants256_512[0], CONST_256);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-        } else {
-                vis_src1(TMP2, REF_S2);
-        }
-
-        height >>= 1;
-        do {    /* 26 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0,   CONST_256, TMP8);
-                vis_pmerge(ZERO,        REF_S2,    TMP12);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                ref += stride;
-                vis_mul8x16au(REF_S0_1, CONST_256, TMP10);
-                vis_pmerge(ZERO,        REF_S2_1,  TMP14);
-
-                vis_ld64_2(ref, stride, TMP4);
-
-                vis_ld64_2(ref, stride_8, TMP6);
-                ref += stride;
-                vis_faligndata(TMP0, TMP2, REF_S4);
-
-                vis_pmerge(ZERO, REF_S4, TMP18);
-
-                vis_pmerge(ZERO, REF_S4_1, TMP20);
-
-                vis_faligndata(TMP4, TMP6, REF_S0);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_S6);
-                        vis_faligndata(TMP4, TMP6, REF_S2);
-                } else {
-                        vis_src1(TMP2, REF_S6);
-                        vis_src1(TMP6, REF_S2);
-                }
-
-                vis_padd16(TMP18, CONST_1, TMP18);
-                vis_mul8x16au(REF_S6,   CONST_256, TMP22);
-
-                vis_padd16(TMP20, CONST_1, TMP20);
-                vis_mul8x16au(REF_S6_1, CONST_256, TMP24);
-
-                vis_mul8x16au(REF_S0,   CONST_256, TMP26);
-                vis_pmerge(ZERO, REF_S0_1, TMP28);
-
-                vis_mul8x16au(REF_S2,   CONST_256, TMP30);
-                vis_padd16(TMP18, TMP22, TMP18);
-
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP32);
-                vis_padd16(TMP20, TMP24, TMP20);
-
-                vis_padd16(TMP8,  TMP18, TMP8);
-
-                vis_padd16(TMP10, TMP20, TMP10);
-
-                vis_padd16(TMP8,  TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-                vis_pack16(TMP8,  DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-                vis_padd16(TMP18, TMP26, TMP18);
-
-                vis_padd16(TMP20, TMP28, TMP20);
-
-                vis_padd16(TMP18, TMP30, TMP18);
-
-                vis_padd16(TMP20, TMP32, TMP20);
-                vis_pack16(TMP18, DST_2);
-
-                vis_pack16(TMP20, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_avg_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
-                                       const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-        int stride_16 = stride + 16;
-
-        vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[ 0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64(ref[ 8], TMP2);
-
-        vis_ld64(ref[16], TMP4);
-
-        vis_ld64(constants6[0], CONST_6);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        vis_ld64(constants256_1024[0], CONST_256);
-        vis_faligndata(TMP2, TMP4, REF_S4);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-                vis_faligndata(TMP2, TMP4, REF_S6);
-        } else {
-                vis_src1(TMP2, REF_S2);
-                vis_src1(TMP4, REF_S6);
-        }
-
-        height >>= 1;
-        do {    /* 55 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0, CONST_256, TMP12);
-                vis_pmerge(ZERO,      REF_S0_1,  TMP14);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                vis_mul8x16au(REF_S2, CONST_256, TMP16);
-                vis_pmerge(ZERO,      REF_S2_1,  TMP18);
-
-                vis_ld64_2(ref, stride_16, TMP4);
-                ref += stride;
-                vis_mul8x16au(REF_S4, CONST_256, TMP20);
-                vis_pmerge(ZERO,      REF_S4_1,  TMP22);
-
-                vis_ld64_2(ref, stride, TMP6);
-                vis_mul8x16au(REF_S6, CONST_256, TMP24);
-                vis_pmerge(ZERO,      REF_S6_1,  TMP26);
-
-                vis_ld64_2(ref, stride_8, TMP8);
-                vis_faligndata(TMP0, TMP2, REF_0);
-
-                vis_ld64_2(ref, stride_16, TMP10);
-                ref += stride;
-                vis_faligndata(TMP2, TMP4, REF_4);
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP6, TMP8, REF_S0);
-
-                vis_ld64_2(dest, 8, DST_2);
-                vis_faligndata(TMP8, TMP10, REF_S4);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_2);
-                        vis_faligndata(TMP2, TMP4, REF_6);
-                        vis_faligndata(TMP6, TMP8, REF_S2);
-                        vis_faligndata(TMP8, TMP10, REF_S6);
-                } else {
-                        vis_src1(TMP2, REF_2);
-                        vis_src1(TMP4, REF_6);
-                        vis_src1(TMP8, REF_S2);
-                        vis_src1(TMP10, REF_S6);
-                }
-
-                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
-                vis_pmerge(ZERO, REF_0, TMP0);
-
-                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
-                vis_pmerge(ZERO,      REF_0_1,  TMP2);
-
-                vis_mul8x16au(REF_2, CONST_256, TMP4);
-                vis_pmerge(ZERO,      REF_2_1,  TMP6);
-
-                vis_mul8x16al(DST_2,   CONST_1024, REF_0);
-                vis_padd16(TMP0, CONST_6, TMP0);
-
-                vis_mul8x16al(DST_3,   CONST_1024, REF_2);
-                vis_padd16(TMP2, CONST_6, TMP2);
-
-                vis_padd16(TMP0, TMP4, TMP0);
-                vis_mul8x16au(REF_4, CONST_256, TMP4);
-
-                vis_padd16(TMP2, TMP6, TMP2);
-                vis_mul8x16au(REF_4_1, CONST_256, TMP6);
-
-                vis_padd16(TMP12, TMP0, TMP12);
-                vis_mul8x16au(REF_6, CONST_256, TMP8);
-
-                vis_padd16(TMP14, TMP2, TMP14);
-                vis_mul8x16au(REF_6_1, CONST_256, TMP10);
-
-                vis_padd16(TMP12, TMP16, TMP12);
-                vis_mul8x16au(REF_S0, CONST_256, REF_4);
-
-                vis_padd16(TMP14, TMP18, TMP14);
-                vis_mul8x16au(REF_S0_1, CONST_256, REF_6);
-
-                vis_padd16(TMP12, TMP30, TMP12);
-
-                vis_padd16(TMP14, TMP32, TMP14);
-                vis_pack16(TMP12, DST_0);
-
-                vis_pack16(TMP14, DST_1);
-                vis_st64(DST_0, dest[0]);
-                vis_padd16(TMP4, CONST_6, TMP4);
-
-                vis_ld64_2(dest, stride, DST_0);
-                vis_padd16(TMP6, CONST_6, TMP6);
-                vis_mul8x16au(REF_S2, CONST_256, TMP12);
-
-                vis_padd16(TMP4, TMP8, TMP4);
-                vis_mul8x16au(REF_S2_1, CONST_256,  TMP14);
-
-                vis_padd16(TMP6, TMP10, TMP6);
-
-                vis_padd16(TMP20, TMP4, TMP20);
-
-                vis_padd16(TMP22, TMP6, TMP22);
-
-                vis_padd16(TMP20, TMP24, TMP20);
-
-                vis_padd16(TMP22, TMP26, TMP22);
-
-                vis_padd16(TMP20, REF_0, TMP20);
-                vis_mul8x16au(REF_S4, CONST_256, REF_0);
-
-                vis_padd16(TMP22, REF_2, TMP22);
-                vis_pack16(TMP20, DST_2);
-
-                vis_pack16(TMP22, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-
-                vis_ld64_2(dest, 8, DST_2);
-                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
-                vis_pmerge(ZERO,      REF_S4_1,  REF_2);
-
-                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
-                vis_padd16(REF_4, TMP0, TMP8);
-
-                vis_mul8x16au(REF_S6, CONST_256, REF_4);
-                vis_padd16(REF_6, TMP2, TMP10);
-
-                vis_mul8x16au(REF_S6_1, CONST_256, REF_6);
-                vis_padd16(TMP8, TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-
-                vis_padd16(TMP8, TMP30, TMP8);
-
-                vis_padd16(TMP10, TMP32, TMP10);
-                vis_pack16(TMP8, DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_st64(DST_0, dest[0]);
-
-                vis_padd16(REF_0, TMP4, REF_0);
-
-                vis_mul8x16al(DST_2,   CONST_1024, TMP30);
-                vis_padd16(REF_2, TMP6, REF_2);
-
-                vis_mul8x16al(DST_3,   CONST_1024, TMP32);
-                vis_padd16(REF_0, REF_4, REF_0);
-
-                vis_padd16(REF_2, REF_6, REF_2);
-
-                vis_padd16(REF_0, TMP30, REF_0);
-
-                /* stall */
-
-                vis_padd16(REF_2, TMP32, REF_2);
-                vis_pack16(REF_0, DST_2);
-
-                vis_pack16(REF_2, DST_3);
-                vis_st64_2(DST_2, dest, 8);
-                dest += stride;
-        } while (--height);
-}
-
-static void MC_avg_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref,
-                                      const int stride, int height)
-{
-        unsigned long off = (unsigned long) ref & 0x7;
-        unsigned long off_plus_1 = off + 1;
-        int stride_8 = stride + 8;
-
-        vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT);
-
-        ref = vis_alignaddr(ref);
-
-        vis_ld64(ref[0], TMP0);
-        vis_fzero(ZERO);
-
-        vis_ld64_2(ref, 8, TMP2);
-
-        vis_ld64(constants6[0], CONST_6);
-
-        vis_ld64(constants256_1024[0], CONST_256);
-        vis_faligndata(TMP0, TMP2, REF_S0);
-
-        if (off != 0x7) {
-                vis_alignaddr_g0((void *)off_plus_1);
-                vis_faligndata(TMP0, TMP2, REF_S2);
-        } else {
-                vis_src1(TMP2, REF_S2);
-        }
-
-        height >>= 1;
-        do {    /* 31 cycles */
-                vis_ld64_2(ref, stride, TMP0);
-                vis_mul8x16au(REF_S0, CONST_256, TMP8);
-                vis_pmerge(ZERO,      REF_S0_1,  TMP10);
-
-                vis_ld64_2(ref, stride_8, TMP2);
-                ref += stride;
-                vis_mul8x16au(REF_S2, CONST_256, TMP12);
-                vis_pmerge(ZERO,      REF_S2_1,  TMP14);
-
-                vis_alignaddr_g0((void *)off);
-
-                vis_ld64_2(ref, stride, TMP4);
-                vis_faligndata(TMP0, TMP2, REF_S4);
-
-                vis_ld64_2(ref, stride_8, TMP6);
-                ref += stride;
-
-                vis_ld64(dest[0], DST_0);
-                vis_faligndata(TMP4, TMP6, REF_S0);
-
-                vis_ld64_2(dest, stride, DST_2);
-
-                if (off != 0x7) {
-                        vis_alignaddr_g0((void *)off_plus_1);
-                        vis_faligndata(TMP0, TMP2, REF_S6);
-                        vis_faligndata(TMP4, TMP6, REF_S2);
-                } else {
-                        vis_src1(TMP2, REF_S6);
-                        vis_src1(TMP6, REF_S2);
-                }
-
-                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
-                vis_pmerge(ZERO, REF_S4, TMP22);
-
-                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
-                vis_pmerge(ZERO,      REF_S4_1,  TMP24);
-
-                vis_mul8x16au(REF_S6, CONST_256, TMP26);
-                vis_pmerge(ZERO,      REF_S6_1,  TMP28);
-
-                vis_mul8x16au(REF_S0, CONST_256, REF_S4);
-                vis_padd16(TMP22, CONST_6, TMP22);
-
-                vis_mul8x16au(REF_S0_1, CONST_256, REF_S6);
-                vis_padd16(TMP24, CONST_6, TMP24);
-
-                vis_mul8x16al(DST_2,   CONST_1024, REF_0);
-                vis_padd16(TMP22, TMP26, TMP22);
-
-                vis_mul8x16al(DST_3,   CONST_1024, REF_2);
-                vis_padd16(TMP24, TMP28, TMP24);
-
-                vis_mul8x16au(REF_S2, CONST_256, TMP26);
-                vis_padd16(TMP8, TMP22, TMP8);
-
-                vis_mul8x16au(REF_S2_1, CONST_256, TMP28);
-                vis_padd16(TMP10, TMP24, TMP10);
-
-                vis_padd16(TMP8, TMP12, TMP8);
-
-                vis_padd16(TMP10, TMP14, TMP10);
-
-                vis_padd16(TMP8, TMP30, TMP8);
-
-                vis_padd16(TMP10, TMP32, TMP10);
-                vis_pack16(TMP8, DST_0);
-
-                vis_pack16(TMP10, DST_1);
-                vis_st64(DST_0, dest[0]);
-                dest += stride;
-
-                vis_padd16(REF_S4, TMP22, TMP12);
-
-                vis_padd16(REF_S6, TMP24, TMP14);
-
-                vis_padd16(TMP12, TMP26, TMP12);
-
-                vis_padd16(TMP14, TMP28, TMP14);
-
-                vis_padd16(TMP12, REF_0, TMP12);
-
-                vis_padd16(TMP14, REF_2, TMP14);
-                vis_pack16(TMP12, DST_2);
-
-                vis_pack16(TMP14, DST_3);
-                vis_st64(DST_2, dest[0]);
-                dest += stride;
-        } while (--height);
-}
-
-/* End of no rounding code */
-
-#define ACCEL_SPARC_VIS 1
-#define ACCEL_SPARC_VIS2 2
-
-static int vis_level(void)
-{
-    int accel = 0;
-    accel |= ACCEL_SPARC_VIS;
-    accel |= ACCEL_SPARC_VIS2;
-    return accel;
-}
+#include "libavutil/attributes.h"
+#include "libavcodec/dsputil.h"
+#include "dsputil_vis.h"
+#include "vis.h"
 
-/* libavcodec initialization code */
-void ff_dsputil_init_vis(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_vis(DSPContext *c, AVCodecContext *avctx)
 {
   /* VIS-specific optimizations */
   int accel = vis_level ();
   const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
-  if (accel & ACCEL_SPARC_VIS) {
-      if (avctx->bits_per_raw_sample <= 8 &&
-          avctx->idct_algo == FF_IDCT_SIMPLEVIS) {
+  if (accel & ACCEL_SPARC_VIS && !high_bit_depth) {
+      if (avctx->idct_algo == FF_IDCT_SIMPLEVIS) {
           c->idct_put = ff_simple_idct_put_vis;
           c->idct_add = ff_simple_idct_add_vis;
           c->idct     = ff_simple_idct_vis;
           c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
       }
-
-      if (!high_bit_depth) {
-      c->put_pixels_tab[0][0] = MC_put_o_16_vis;
-      c->put_pixels_tab[0][1] = MC_put_x_16_vis;
-      c->put_pixels_tab[0][2] = MC_put_y_16_vis;
-      c->put_pixels_tab[0][3] = MC_put_xy_16_vis;
-
-      c->put_pixels_tab[1][0] = MC_put_o_8_vis;
-      c->put_pixels_tab[1][1] = MC_put_x_8_vis;
-      c->put_pixels_tab[1][2] = MC_put_y_8_vis;
-      c->put_pixels_tab[1][3] = MC_put_xy_8_vis;
-
-      c->avg_pixels_tab[0][0] = MC_avg_o_16_vis;
-      c->avg_pixels_tab[0][1] = MC_avg_x_16_vis;
-      c->avg_pixels_tab[0][2] = MC_avg_y_16_vis;
-      c->avg_pixels_tab[0][3] = MC_avg_xy_16_vis;
-
-      c->avg_pixels_tab[1][0] = MC_avg_o_8_vis;
-      c->avg_pixels_tab[1][1] = MC_avg_x_8_vis;
-      c->avg_pixels_tab[1][2] = MC_avg_y_8_vis;
-      c->avg_pixels_tab[1][3] = MC_avg_xy_8_vis;
-
-      c->put_no_rnd_pixels_tab[0][0] = MC_put_no_round_o_16_vis;
-      c->put_no_rnd_pixels_tab[0][1] = MC_put_no_round_x_16_vis;
-      c->put_no_rnd_pixels_tab[0][2] = MC_put_no_round_y_16_vis;
-      c->put_no_rnd_pixels_tab[0][3] = MC_put_no_round_xy_16_vis;
-
-      c->put_no_rnd_pixels_tab[1][0] = MC_put_no_round_o_8_vis;
-      c->put_no_rnd_pixels_tab[1][1] = MC_put_no_round_x_8_vis;
-      c->put_no_rnd_pixels_tab[1][2] = MC_put_no_round_y_8_vis;
-      c->put_no_rnd_pixels_tab[1][3] = MC_put_no_round_xy_8_vis;
-
-      c->avg_no_rnd_pixels_tab[0][0] = MC_avg_no_round_o_16_vis;
-      c->avg_no_rnd_pixels_tab[0][1] = MC_avg_no_round_x_16_vis;
-      c->avg_no_rnd_pixels_tab[0][2] = MC_avg_no_round_y_16_vis;
-      c->avg_no_rnd_pixels_tab[0][3] = MC_avg_no_round_xy_16_vis;
-
-      c->avg_no_rnd_pixels_tab[1][0] = MC_avg_no_round_o_8_vis;
-      c->avg_no_rnd_pixels_tab[1][1] = MC_avg_no_round_x_8_vis;
-      c->avg_no_rnd_pixels_tab[1][2] = MC_avg_no_round_y_8_vis;
-      c->avg_no_rnd_pixels_tab[1][3] = MC_avg_no_round_xy_8_vis;
-      }
   }
 }
diff --git a/libavcodec/sparc/dsputil_vis.h b/libavcodec/sparc/dsputil_vis.h
index 4be86e2..d7f6e01 100644
--- a/libavcodec/sparc/dsputil_vis.h
+++ b/libavcodec/sparc/dsputil_vis.h
@@ -20,10 +20,9 @@
 #define AVCODEC_SPARC_DSPUTIL_VIS_H
 
 #include <stdint.h>
-#include "libavcodec/dsputil.h"
 
-void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_add_vis(uint8_t *dest, int line_size, DCTELEM *data);
-void ff_simple_idct_vis(DCTELEM *data);
+void ff_simple_idct_put_vis(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_add_vis(uint8_t *dest, int line_size, int16_t *data);
+void ff_simple_idct_vis(int16_t *data);
 
 #endif /* AVCODEC_SPARC_DSPUTIL_VIS_H */
diff --git a/libavcodec/sparc/hpeldsp_vis.c b/libavcodec/sparc/hpeldsp_vis.c
new file mode 100644
index 0000000..bca32e2
--- /dev/null
+++ b/libavcodec/sparc/hpeldsp_vis.c
@@ -0,0 +1,3524 @@
+/*
+ * Copyright (C) 2003 David S. Miller <davem at redhat.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
+ */
+
+/* The *no_round* functions have been added by James A. Morrison, 2003,2004.
+   The vis code from libmpeg2 was adapted for libavcodec by James A. Morrison.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/mem.h"
+#include "libavcodec/hpeldsp.h"
+#include "vis.h"
+
+/* The trick used in some of this file is the formula from the MMX
+ * motion comp code, which is:
+ *
+ * (x+y+1)>>1 == (x|y)-((x^y)>>1)
+ *
+ * This allows us to average 8 bytes at a time in a 64-bit FPU reg.
+ * We avoid overflows by masking before we do the shift, and we
+ * implement the shift by multiplying by 1/2 using mul8x16.  So in
+ * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask
+ * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and
+ * the value 0x80808080 is in f8):
+ *
+ *      fxor            f0,   f2, f10
+ *      fand            f10,  f4, f10
+ *      fmul8x16        f8,  f10, f10
+ *      fand            f10,  f6, f10
+ *      for             f0,   f2, f12
+ *      fpsub16         f12, f10, f10
+ */
+
+#define DUP4(x) {x, x, x, x}
+#define DUP8(x) {x, x, x, x, x, x, x, x}
+DECLARE_ALIGNED(8, static const int16_t, constants1)[] = DUP4 (1);
+DECLARE_ALIGNED(8, static const int16_t, constants2)[] = DUP4 (2);
+DECLARE_ALIGNED(8, static const int16_t, constants3)[] = DUP4 (3);
+DECLARE_ALIGNED(8, static const int16_t, constants6)[] = DUP4 (6);
+DECLARE_ALIGNED(8, static const int8_t, constants_fe)[] = DUP8 (0xfe);
+DECLARE_ALIGNED(8, static const int8_t, constants_7f)[] = DUP8 (0x7f);
+DECLARE_ALIGNED(8, static const int8_t, constants128)[] = DUP8 (128);
+DECLARE_ALIGNED(8, static const int16_t, constants256_512)[] =
+        {256, 512, 256, 512};
+DECLARE_ALIGNED(8, static const int16_t, constants256_1024)[] =
+        {256, 1024, 256, 1024};
+
+#define REF_0           0
+#define REF_0_1         1
+#define REF_2           2
+#define REF_2_1         3
+#define REF_4           4
+#define REF_4_1         5
+#define REF_6           6
+#define REF_6_1         7
+#define REF_S0          8
+#define REF_S0_1        9
+#define REF_S2          10
+#define REF_S2_1        11
+#define REF_S4          12
+#define REF_S4_1        13
+#define REF_S6          14
+#define REF_S6_1        15
+#define DST_0           16
+#define DST_1           17
+#define DST_2           18
+#define DST_3           19
+#define CONST_1         20
+#define CONST_2         20
+#define CONST_3         20
+#define CONST_6         20
+#define MASK_fe         20
+#define CONST_128       22
+#define CONST_256       22
+#define CONST_512       22
+#define CONST_1024      22
+#define TMP0            24
+#define TMP1            25
+#define TMP2            26
+#define TMP3            27
+#define TMP4            28
+#define TMP5            29
+#define ZERO            30
+#define MASK_7f         30
+
+#define TMP6            32
+#define TMP8            34
+#define TMP10           36
+#define TMP12           38
+#define TMP14           40
+#define TMP16           42
+#define TMP18           44
+#define TMP20           46
+#define TMP22           48
+#define TMP24           50
+#define TMP26           52
+#define TMP28           54
+#define TMP30           56
+#define TMP32           58
+
+static void MC_put_o_16_vis (uint8_t * dest, const uint8_t * ref,
+                             const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+        do {    /* 5 cycles */
+                vis_ld64(ref[0], TMP0);
+
+                vis_ld64_2(ref, 8, TMP2);
+
+                vis_ld64_2(ref, 16, TMP4);
+                ref += stride;
+
+                vis_faligndata(TMP0, TMP2, REF_0);
+                vis_st64(REF_0, dest[0]);
+
+                vis_faligndata(TMP2, TMP4, REF_2);
+                vis_st64_2(REF_2, dest, 8);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_put_o_8_vis (uint8_t * dest, const uint8_t * ref,
+                            const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+        do {    /* 4 cycles */
+                vis_ld64(ref[0], TMP0);
+
+                vis_ld64(ref[8], TMP2);
+                ref += stride;
+
+                /* stall */
+
+                vis_faligndata(TMP0, TMP2, REF_0);
+                vis_st64(REF_0, dest[0]);
+                dest += stride;
+        } while (--height);
+}
+
+
+static void MC_avg_o_16_vis (uint8_t * dest, const uint8_t * ref,
+                             const ptrdiff_t stride, int height)
+{
+        int stride_8 = stride + 8;
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64(ref[8], TMP2);
+
+        vis_ld64(ref[16], TMP4);
+
+        vis_ld64(dest[0], DST_0);
+
+        vis_ld64(dest[8], DST_2);
+
+        vis_ld64(constants_fe[0], MASK_fe);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP2, TMP4, REF_2);
+
+        vis_ld64(constants128[0], CONST_128);
+
+        ref += stride;
+        height = (height >> 1) - 1;
+
+        do {    /* 24 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(DST_0, REF_0, TMP6);
+
+                vis_ld64_2(ref, 8, TMP2);
+                vis_and(TMP6, MASK_fe, TMP6);
+
+                vis_ld64_2(ref, 16, TMP4);
+                ref += stride;
+                vis_mul8x16(CONST_128, TMP6, TMP6);
+                vis_xor(DST_2, REF_2, TMP8);
+
+                vis_and(TMP8, MASK_fe, TMP8);
+
+                vis_or(DST_0, REF_0, TMP10);
+                vis_ld64_2(dest, stride, DST_0);
+                vis_mul8x16(CONST_128, TMP8, TMP8);
+
+                vis_or(DST_2, REF_2, TMP12);
+                vis_ld64_2(dest, stride_8, DST_2);
+
+                vis_ld64(ref[0], TMP14);
+                vis_and(TMP6, MASK_7f, TMP6);
+
+                vis_and(TMP8, MASK_7f, TMP8);
+
+                vis_psub16(TMP10, TMP6, TMP6);
+                vis_st64(TMP6, dest[0]);
+
+                vis_psub16(TMP12, TMP8, TMP8);
+                vis_st64_2(TMP8, dest, 8);
+
+                dest += stride;
+                vis_ld64_2(ref, 8, TMP16);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, 16, TMP18);
+                vis_faligndata(TMP2, TMP4, REF_2);
+                ref += stride;
+
+                vis_xor(DST_0, REF_0, TMP20);
+
+                vis_and(TMP20, MASK_fe, TMP20);
+
+                vis_xor(DST_2, REF_2, TMP22);
+                vis_mul8x16(CONST_128, TMP20, TMP20);
+
+                vis_and(TMP22, MASK_fe, TMP22);
+
+                vis_or(DST_0, REF_0, TMP24);
+                vis_mul8x16(CONST_128, TMP22, TMP22);
+
+                vis_or(DST_2, REF_2, TMP26);
+
+                vis_ld64_2(dest, stride, DST_0);
+                vis_faligndata(TMP14, TMP16, REF_0);
+
+                vis_ld64_2(dest, stride_8, DST_2);
+                vis_faligndata(TMP16, TMP18, REF_2);
+
+                vis_and(TMP20, MASK_7f, TMP20);
+
+                vis_and(TMP22, MASK_7f, TMP22);
+
+                vis_psub16(TMP24, TMP20, TMP20);
+                vis_st64(TMP20, dest[0]);
+
+                vis_psub16(TMP26, TMP22, TMP22);
+                vis_st64_2(TMP22, dest, 8);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(DST_0, REF_0, TMP6);
+
+        vis_ld64_2(ref, 8, TMP2);
+        vis_and(TMP6, MASK_fe, TMP6);
+
+        vis_ld64_2(ref, 16, TMP4);
+        vis_mul8x16(CONST_128, TMP6, TMP6);
+        vis_xor(DST_2, REF_2, TMP8);
+
+        vis_and(TMP8, MASK_fe, TMP8);
+
+        vis_or(DST_0, REF_0, TMP10);
+        vis_ld64_2(dest, stride, DST_0);
+        vis_mul8x16(CONST_128, TMP8, TMP8);
+
+        vis_or(DST_2, REF_2, TMP12);
+        vis_ld64_2(dest, stride_8, DST_2);
+
+        vis_ld64(ref[0], TMP14);
+        vis_and(TMP6, MASK_7f, TMP6);
+
+        vis_and(TMP8, MASK_7f, TMP8);
+
+        vis_psub16(TMP10, TMP6, TMP6);
+        vis_st64(TMP6, dest[0]);
+
+        vis_psub16(TMP12, TMP8, TMP8);
+        vis_st64_2(TMP8, dest, 8);
+
+        dest += stride;
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_faligndata(TMP2, TMP4, REF_2);
+
+        vis_xor(DST_0, REF_0, TMP20);
+
+        vis_and(TMP20, MASK_fe, TMP20);
+
+        vis_xor(DST_2, REF_2, TMP22);
+        vis_mul8x16(CONST_128, TMP20, TMP20);
+
+        vis_and(TMP22, MASK_fe, TMP22);
+
+        vis_or(DST_0, REF_0, TMP24);
+        vis_mul8x16(CONST_128, TMP22, TMP22);
+
+        vis_or(DST_2, REF_2, TMP26);
+
+        vis_and(TMP20, MASK_7f, TMP20);
+
+        vis_and(TMP22, MASK_7f, TMP22);
+
+        vis_psub16(TMP24, TMP20, TMP20);
+        vis_st64(TMP20, dest[0]);
+
+        vis_psub16(TMP26, TMP22, TMP22);
+        vis_st64_2(TMP22, dest, 8);
+}
+
+static void MC_avg_o_8_vis (uint8_t * dest, const uint8_t * ref,
+                            const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64(ref[8], TMP2);
+
+        vis_ld64(dest[0], DST_0);
+
+        vis_ld64(constants_fe[0], MASK_fe);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64(constants128[0], CONST_128);
+
+        ref += stride;
+        height = (height >> 1) - 1;
+
+        do {    /* 12 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(DST_0, REF_0, TMP4);
+
+                vis_ld64(ref[8], TMP2);
+                vis_and(TMP4, MASK_fe, TMP4);
+
+                vis_or(DST_0, REF_0, TMP6);
+                vis_ld64_2(dest, stride, DST_0);
+                ref += stride;
+                vis_mul8x16(CONST_128, TMP4, TMP4);
+
+                vis_ld64(ref[0], TMP12);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64(ref[8], TMP2);
+                vis_xor(DST_0, REF_0, TMP0);
+                ref += stride;
+
+                vis_and(TMP0, MASK_fe, TMP0);
+
+                vis_and(TMP4, MASK_7f, TMP4);
+
+                vis_psub16(TMP6, TMP4, TMP4);
+                vis_st64(TMP4, dest[0]);
+                dest += stride;
+                vis_mul8x16(CONST_128, TMP0, TMP0);
+
+                vis_or(DST_0, REF_0, TMP6);
+                vis_ld64_2(dest, stride, DST_0);
+
+                vis_faligndata(TMP12, TMP2, REF_0);
+
+                vis_and(TMP0, MASK_7f, TMP0);
+
+                vis_psub16(TMP6, TMP0, TMP4);
+                vis_st64(TMP4, dest[0]);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(DST_0, REF_0, TMP4);
+
+        vis_ld64(ref[8], TMP2);
+        vis_and(TMP4, MASK_fe, TMP4);
+
+        vis_or(DST_0, REF_0, TMP6);
+        vis_ld64_2(dest, stride, DST_0);
+        vis_mul8x16(CONST_128, TMP4, TMP4);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_xor(DST_0, REF_0, TMP0);
+
+        vis_and(TMP0, MASK_fe, TMP0);
+
+        vis_and(TMP4, MASK_7f, TMP4);
+
+        vis_psub16(TMP6, TMP4, TMP4);
+        vis_st64(TMP4, dest[0]);
+        dest += stride;
+        vis_mul8x16(CONST_128, TMP0, TMP0);
+
+        vis_or(DST_0, REF_0, TMP6);
+
+        vis_and(TMP0, MASK_7f, TMP0);
+
+        vis_psub16(TMP6, TMP0, TMP4);
+        vis_st64(TMP4, dest[0]);
+}
+
+static void MC_put_x_16_vis (uint8_t * dest, const uint8_t * ref,
+                             const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[0],    TMP0);
+
+        vis_ld64_2(ref, 8,  TMP2);
+
+        vis_ld64_2(ref, 16, TMP4);
+
+        vis_ld64(constants_fe[0], MASK_fe);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64(constants128[0], CONST_128);
+        vis_faligndata(TMP2, TMP4, REF_4);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_2);
+                vis_faligndata(TMP2, TMP4, REF_6);
+        } else {
+                vis_src1(TMP2, REF_2);
+                vis_src1(TMP4, REF_6);
+        }
+
+        ref += stride;
+        height = (height >> 1) - 1;
+
+        do {    /* 34 cycles */
+                vis_ld64(ref[0],    TMP0);
+                vis_xor(REF_0, REF_2, TMP6);
+
+                vis_ld64_2(ref, 8,  TMP2);
+                vis_xor(REF_4, REF_6, TMP8);
+
+                vis_ld64_2(ref, 16, TMP4);
+                vis_and(TMP6, MASK_fe, TMP6);
+                ref += stride;
+
+                vis_ld64(ref[0],    TMP14);
+                vis_mul8x16(CONST_128, TMP6, TMP6);
+                vis_and(TMP8, MASK_fe, TMP8);
+
+                vis_ld64_2(ref, 8,  TMP16);
+                vis_mul8x16(CONST_128, TMP8, TMP8);
+                vis_or(REF_0, REF_2, TMP10);
+
+                vis_ld64_2(ref, 16, TMP18);
+                ref += stride;
+                vis_or(REF_4, REF_6, TMP12);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                        vis_faligndata(TMP2, TMP4, REF_6);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                        vis_src1(TMP4, REF_6);
+                }
+
+                vis_and(TMP6, MASK_7f, TMP6);
+
+                vis_and(TMP8, MASK_7f, TMP8);
+
+                vis_psub16(TMP10, TMP6, TMP6);
+                vis_st64(TMP6, dest[0]);
+
+                vis_psub16(TMP12, TMP8, TMP8);
+                vis_st64_2(TMP8, dest, 8);
+                dest += stride;
+
+                vis_xor(REF_0, REF_2, TMP6);
+
+                vis_xor(REF_4, REF_6, TMP8);
+
+                vis_and(TMP6, MASK_fe, TMP6);
+
+                vis_mul8x16(CONST_128, TMP6, TMP6);
+                vis_and(TMP8, MASK_fe, TMP8);
+
+                vis_mul8x16(CONST_128, TMP8, TMP8);
+                vis_or(REF_0, REF_2, TMP10);
+
+                vis_or(REF_4, REF_6, TMP12);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_faligndata(TMP14, TMP16, REF_0);
+
+                vis_faligndata(TMP16, TMP18, REF_4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP14, TMP16, REF_2);
+                        vis_faligndata(TMP16, TMP18, REF_6);
+                } else {
+                        vis_src1(TMP16, REF_2);
+                        vis_src1(TMP18, REF_6);
+                }
+
+                vis_and(TMP6, MASK_7f, TMP6);
+
+                vis_and(TMP8, MASK_7f, TMP8);
+
+                vis_psub16(TMP10, TMP6, TMP6);
+                vis_st64(TMP6, dest[0]);
+
+                vis_psub16(TMP12, TMP8, TMP8);
+                vis_st64_2(TMP8, dest, 8);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0],    TMP0);
+        vis_xor(REF_0, REF_2, TMP6);
+
+        vis_ld64_2(ref, 8,  TMP2);
+        vis_xor(REF_4, REF_6, TMP8);
+
+        vis_ld64_2(ref, 16, TMP4);
+        vis_and(TMP6, MASK_fe, TMP6);
+
+        vis_mul8x16(CONST_128, TMP6, TMP6);
+        vis_and(TMP8, MASK_fe, TMP8);
+
+        vis_mul8x16(CONST_128, TMP8, TMP8);
+        vis_or(REF_0, REF_2, TMP10);
+
+        vis_or(REF_4, REF_6, TMP12);
+
+        vis_alignaddr_g0((void *)off);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_faligndata(TMP2, TMP4, REF_4);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_2);
+                vis_faligndata(TMP2, TMP4, REF_6);
+        } else {
+                vis_src1(TMP2, REF_2);
+                vis_src1(TMP4, REF_6);
+        }
+
+        vis_and(TMP6, MASK_7f, TMP6);
+
+        vis_and(TMP8, MASK_7f, TMP8);
+
+        vis_psub16(TMP10, TMP6, TMP6);
+        vis_st64(TMP6, dest[0]);
+
+        vis_psub16(TMP12, TMP8, TMP8);
+        vis_st64_2(TMP8, dest, 8);
+        dest += stride;
+
+        vis_xor(REF_0, REF_2, TMP6);
+
+        vis_xor(REF_4, REF_6, TMP8);
+
+        vis_and(TMP6, MASK_fe, TMP6);
+
+        vis_mul8x16(CONST_128, TMP6, TMP6);
+        vis_and(TMP8, MASK_fe, TMP8);
+
+        vis_mul8x16(CONST_128, TMP8, TMP8);
+        vis_or(REF_0, REF_2, TMP10);
+
+        vis_or(REF_4, REF_6, TMP12);
+
+        vis_and(TMP6, MASK_7f, TMP6);
+
+        vis_and(TMP8, MASK_7f, TMP8);
+
+        vis_psub16(TMP10, TMP6, TMP6);
+        vis_st64(TMP6, dest[0]);
+
+        vis_psub16(TMP12, TMP8, TMP8);
+        vis_st64_2(TMP8, dest, 8);
+}
+
+static void MC_put_x_8_vis (uint8_t * dest, const uint8_t * ref,
+                            const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64(ref[8], TMP2);
+
+        vis_ld64(constants_fe[0], MASK_fe);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+
+        vis_ld64(constants128[0], CONST_128);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_2);
+        } else {
+                vis_src1(TMP2, REF_2);
+        }
+
+        ref += stride;
+        height = (height >> 1) - 1;
+
+        do {    /* 20 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(REF_0, REF_2, TMP4);
+
+                vis_ld64_2(ref, 8, TMP2);
+                vis_and(TMP4, MASK_fe, TMP4);
+                ref += stride;
+
+                vis_ld64(ref[0], TMP8);
+                vis_or(REF_0, REF_2, TMP6);
+                vis_mul8x16(CONST_128, TMP4, TMP4);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, 8, TMP10);
+                ref += stride;
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                }
+
+                vis_and(TMP4, MASK_7f, TMP4);
+
+                vis_psub16(TMP6, TMP4, DST_0);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+
+                vis_xor(REF_0, REF_2, TMP12);
+
+                vis_and(TMP12, MASK_fe, TMP12);
+
+                vis_or(REF_0, REF_2, TMP14);
+                vis_mul8x16(CONST_128, TMP12, TMP12);
+
+                vis_alignaddr_g0((void *)off);
+                vis_faligndata(TMP8, TMP10, REF_0);
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP8, TMP10, REF_2);
+                } else {
+                        vis_src1(TMP10, REF_2);
+                }
+
+                vis_and(TMP12, MASK_7f, TMP12);
+
+                vis_psub16(TMP14, TMP12, DST_0);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(REF_0, REF_2, TMP4);
+
+        vis_ld64_2(ref, 8, TMP2);
+        vis_and(TMP4, MASK_fe, TMP4);
+
+        vis_or(REF_0, REF_2, TMP6);
+        vis_mul8x16(CONST_128, TMP4, TMP4);
+
+        vis_alignaddr_g0((void *)off);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_2);
+        } else {
+                vis_src1(TMP2, REF_2);
+        }
+
+        vis_and(TMP4, MASK_7f, TMP4);
+
+        vis_psub16(TMP6, TMP4, DST_0);
+        vis_st64(DST_0, dest[0]);
+        dest += stride;
+
+        vis_xor(REF_0, REF_2, TMP12);
+
+        vis_and(TMP12, MASK_fe, TMP12);
+
+        vis_or(REF_0, REF_2, TMP14);
+        vis_mul8x16(CONST_128, TMP12, TMP12);
+
+        vis_and(TMP12, MASK_7f, TMP12);
+
+        vis_psub16(TMP14, TMP12, DST_0);
+        vis_st64(DST_0, dest[0]);
+        dest += stride;
+}
+
+static void MC_avg_x_16_vis (uint8_t * dest, const uint8_t * ref,
+                             const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        vis_ld64(constants3[0], CONST_3);
+        vis_fzero(ZERO);
+        vis_ld64(constants256_512[0], CONST_256);
+
+        ref = vis_alignaddr(ref);
+        do {    /* 26 cycles */
+                vis_ld64(ref[0], TMP0);
+
+                vis_ld64(ref[8], TMP2);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64(ref[16], TMP4);
+
+                vis_ld64(dest[0], DST_0);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64(dest[8], DST_2);
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                        vis_faligndata(TMP2, TMP4, REF_6);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                        vis_src1(TMP4, REF_6);
+                }
+
+                vis_mul8x16au(REF_0,   CONST_256, TMP0);
+
+                vis_pmerge(ZERO,     REF_2,     TMP4);
+                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
+
+                vis_pmerge(ZERO, REF_2_1, TMP6);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+
+                vis_mul8x16al(DST_0,   CONST_512, TMP4);
+                vis_padd16(TMP2, TMP6, TMP2);
+
+                vis_mul8x16al(DST_1,   CONST_512, TMP6);
+
+                vis_mul8x16au(REF_6,   CONST_256, TMP12);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP14);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+                vis_mul8x16au(REF_4,   CONST_256, TMP16);
+
+                vis_padd16(TMP0, CONST_3, TMP8);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP18);
+
+                vis_padd16(TMP2, CONST_3, TMP10);
+                vis_pack16(TMP8, DST_0);
+
+                vis_pack16(TMP10, DST_1);
+                vis_padd16(TMP16, TMP12, TMP0);
+
+                vis_st64(DST_0, dest[0]);
+                vis_mul8x16al(DST_2,   CONST_512, TMP4);
+                vis_padd16(TMP18, TMP14, TMP2);
+
+                vis_mul8x16al(DST_3,   CONST_512, TMP6);
+                vis_padd16(TMP0, CONST_3, TMP0);
+
+                vis_padd16(TMP2, CONST_3, TMP2);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+                vis_pack16(TMP0, DST_2);
+
+                vis_pack16(TMP2, DST_3);
+                vis_st64(DST_2, dest[8]);
+
+                ref += stride;
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_avg_x_8_vis (uint8_t * dest, const uint8_t * ref,
+                            const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+        int stride_times_2 = stride << 1;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        vis_ld64(constants3[0], CONST_3);
+        vis_fzero(ZERO);
+        vis_ld64(constants256_512[0], CONST_256);
+
+        ref = vis_alignaddr(ref);
+        height >>= 2;
+        do {    /* 47 cycles */
+                vis_ld64(ref[0],   TMP0);
+
+                vis_ld64_2(ref, 8, TMP2);
+                ref += stride;
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64(ref[0],   TMP4);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, 8, TMP6);
+                ref += stride;
+
+                vis_ld64(ref[0],   TMP8);
+
+                vis_ld64_2(ref, 8, TMP10);
+                ref += stride;
+                vis_faligndata(TMP4, TMP6, REF_4);
+
+                vis_ld64(ref[0],   TMP12);
+
+                vis_ld64_2(ref, 8, TMP14);
+                ref += stride;
+                vis_faligndata(TMP8, TMP10, REF_S0);
+
+                vis_faligndata(TMP12, TMP14, REF_S4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+
+                        vis_ld64(dest[0], DST_0);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+
+                        vis_ld64_2(dest, stride, DST_2);
+                        vis_faligndata(TMP4, TMP6, REF_6);
+
+                        vis_faligndata(TMP8, TMP10, REF_S2);
+
+                        vis_faligndata(TMP12, TMP14, REF_S6);
+                } else {
+                        vis_ld64(dest[0], DST_0);
+                        vis_src1(TMP2, REF_2);
+
+                        vis_ld64_2(dest, stride, DST_2);
+                        vis_src1(TMP6, REF_6);
+
+                        vis_src1(TMP10, REF_S2);
+
+                        vis_src1(TMP14, REF_S6);
+                }
+
+                vis_pmerge(ZERO,     REF_0,     TMP0);
+                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
+
+                vis_pmerge(ZERO,     REF_2,     TMP4);
+                vis_mul8x16au(REF_2_1, CONST_256, TMP6);
+
+                vis_padd16(TMP0, CONST_3, TMP0);
+                vis_mul8x16al(DST_0,   CONST_512, TMP16);
+
+                vis_padd16(TMP2, CONST_3, TMP2);
+                vis_mul8x16al(DST_1,   CONST_512, TMP18);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+                vis_mul8x16au(REF_4, CONST_256, TMP8);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP10);
+
+                vis_padd16(TMP0, TMP16, TMP0);
+                vis_mul8x16au(REF_6, CONST_256, TMP12);
+
+                vis_padd16(TMP2, TMP18, TMP2);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP14);
+
+                vis_padd16(TMP8, CONST_3, TMP8);
+                vis_mul8x16al(DST_2, CONST_512, TMP16);
+
+                vis_padd16(TMP8, TMP12, TMP8);
+                vis_mul8x16al(DST_3, CONST_512, TMP18);
+
+                vis_padd16(TMP10, TMP14, TMP10);
+                vis_pack16(TMP0, DST_0);
+
+                vis_pack16(TMP2, DST_1);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+                vis_padd16(TMP10, CONST_3, TMP10);
+
+                vis_ld64_2(dest, stride, DST_0);
+                vis_padd16(TMP8, TMP16, TMP8);
+
+                vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/);
+                vis_padd16(TMP10, TMP18, TMP10);
+                vis_pack16(TMP8, DST_2);
+
+                vis_pack16(TMP10, DST_3);
+                vis_st64(DST_2, dest[0]);
+                dest += stride;
+
+                vis_mul8x16au(REF_S0_1, CONST_256, TMP2);
+                vis_pmerge(ZERO,     REF_S0,     TMP0);
+
+                vis_pmerge(ZERO,     REF_S2,     TMP24);
+                vis_mul8x16au(REF_S2_1, CONST_256, TMP6);
+
+                vis_padd16(TMP0, CONST_3, TMP0);
+                vis_mul8x16au(REF_S4, CONST_256, TMP8);
+
+                vis_padd16(TMP2, CONST_3, TMP2);
+                vis_mul8x16au(REF_S4_1, CONST_256, TMP10);
+
+                vis_padd16(TMP0, TMP24, TMP0);
+                vis_mul8x16au(REF_S6, CONST_256, TMP12);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+                vis_mul8x16au(REF_S6_1, CONST_256, TMP14);
+
+                vis_padd16(TMP8, CONST_3, TMP8);
+                vis_mul8x16al(DST_0,   CONST_512, TMP16);
+
+                vis_padd16(TMP10, CONST_3, TMP10);
+                vis_mul8x16al(DST_1,   CONST_512, TMP18);
+
+                vis_padd16(TMP8, TMP12, TMP8);
+                vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20);
+
+                vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22);
+                vis_padd16(TMP0, TMP16, TMP0);
+
+                vis_padd16(TMP2, TMP18, TMP2);
+                vis_pack16(TMP0, DST_0);
+
+                vis_padd16(TMP10, TMP14, TMP10);
+                vis_pack16(TMP2, DST_1);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+
+                vis_padd16(TMP8, TMP20, TMP8);
+
+                vis_padd16(TMP10, TMP22, TMP10);
+                vis_pack16(TMP8, DST_2);
+
+                vis_pack16(TMP10, DST_3);
+                vis_st64(DST_2, dest[0]);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_put_y_16_vis (uint8_t * dest, const uint8_t * ref,
+                             const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64_2(ref, 8, TMP2);
+
+        vis_ld64_2(ref, 16, TMP4);
+        ref += stride;
+
+        vis_ld64(ref[0], TMP6);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64_2(ref, 8, TMP8);
+        vis_faligndata(TMP2, TMP4, REF_4);
+
+        vis_ld64_2(ref, 16, TMP10);
+        ref += stride;
+
+        vis_ld64(constants_fe[0], MASK_fe);
+        vis_faligndata(TMP6, TMP8, REF_2);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP8, TMP10, REF_6);
+
+        vis_ld64(constants128[0], CONST_128);
+        height = (height >> 1) - 1;
+        do {    /* 24 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(REF_0, REF_2, TMP12);
+
+                vis_ld64_2(ref, 8, TMP2);
+                vis_xor(REF_4, REF_6, TMP16);
+
+                vis_ld64_2(ref, 16, TMP4);
+                ref += stride;
+                vis_or(REF_0, REF_2, TMP14);
+
+                vis_ld64(ref[0], TMP6);
+                vis_or(REF_4, REF_6, TMP18);
+
+                vis_ld64_2(ref, 8, TMP8);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, 16, TMP10);
+                ref += stride;
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                vis_and(TMP12, MASK_fe, TMP12);
+
+                vis_and(TMP16, MASK_fe, TMP16);
+                vis_mul8x16(CONST_128, TMP12, TMP12);
+
+                vis_mul8x16(CONST_128, TMP16, TMP16);
+                vis_xor(REF_0, REF_2, TMP0);
+
+                vis_xor(REF_4, REF_6, TMP2);
+
+                vis_or(REF_0, REF_2, TMP20);
+
+                vis_and(TMP12, MASK_7f, TMP12);
+
+                vis_and(TMP16, MASK_7f, TMP16);
+
+                vis_psub16(TMP14, TMP12, TMP12);
+                vis_st64(TMP12, dest[0]);
+
+                vis_psub16(TMP18, TMP16, TMP16);
+                vis_st64_2(TMP16, dest, 8);
+                dest += stride;
+
+                vis_or(REF_4, REF_6, TMP18);
+
+                vis_and(TMP0, MASK_fe, TMP0);
+
+                vis_and(TMP2, MASK_fe, TMP2);
+                vis_mul8x16(CONST_128, TMP0, TMP0);
+
+                vis_faligndata(TMP6, TMP8, REF_2);
+                vis_mul8x16(CONST_128, TMP2, TMP2);
+
+                vis_faligndata(TMP8, TMP10, REF_6);
+
+                vis_and(TMP0, MASK_7f, TMP0);
+
+                vis_and(TMP2, MASK_7f, TMP2);
+
+                vis_psub16(TMP20, TMP0, TMP0);
+                vis_st64(TMP0, dest[0]);
+
+                vis_psub16(TMP18, TMP2, TMP2);
+                vis_st64_2(TMP2, dest, 8);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(REF_0, REF_2, TMP12);
+
+        vis_ld64_2(ref, 8, TMP2);
+        vis_xor(REF_4, REF_6, TMP16);
+
+        vis_ld64_2(ref, 16, TMP4);
+        vis_or(REF_0, REF_2, TMP14);
+
+        vis_or(REF_4, REF_6, TMP18);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_faligndata(TMP2, TMP4, REF_4);
+
+        vis_and(TMP12, MASK_fe, TMP12);
+
+        vis_and(TMP16, MASK_fe, TMP16);
+        vis_mul8x16(CONST_128, TMP12, TMP12);
+
+        vis_mul8x16(CONST_128, TMP16, TMP16);
+        vis_xor(REF_0, REF_2, TMP0);
+
+        vis_xor(REF_4, REF_6, TMP2);
+
+        vis_or(REF_0, REF_2, TMP20);
+
+        vis_and(TMP12, MASK_7f, TMP12);
+
+        vis_and(TMP16, MASK_7f, TMP16);
+
+        vis_psub16(TMP14, TMP12, TMP12);
+        vis_st64(TMP12, dest[0]);
+
+        vis_psub16(TMP18, TMP16, TMP16);
+        vis_st64_2(TMP16, dest, 8);
+        dest += stride;
+
+        vis_or(REF_4, REF_6, TMP18);
+
+        vis_and(TMP0, MASK_fe, TMP0);
+
+        vis_and(TMP2, MASK_fe, TMP2);
+        vis_mul8x16(CONST_128, TMP0, TMP0);
+
+        vis_mul8x16(CONST_128, TMP2, TMP2);
+
+        vis_and(TMP0, MASK_7f, TMP0);
+
+        vis_and(TMP2, MASK_7f, TMP2);
+
+        vis_psub16(TMP20, TMP0, TMP0);
+        vis_st64(TMP0, dest[0]);
+
+        vis_psub16(TMP18, TMP2, TMP2);
+        vis_st64_2(TMP2, dest, 8);
+}
+
+static void MC_put_y_8_vis (uint8_t * dest, const uint8_t * ref,
+                            const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64_2(ref, 8, TMP2);
+        ref += stride;
+
+        vis_ld64(ref[0], TMP4);
+
+        vis_ld64_2(ref, 8, TMP6);
+        ref += stride;
+
+        vis_ld64(constants_fe[0], MASK_fe);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP4, TMP6, REF_2);
+
+        vis_ld64(constants128[0], CONST_128);
+        height = (height >> 1) - 1;
+        do {    /* 12 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(REF_0, REF_2, TMP4);
+
+                vis_ld64_2(ref, 8, TMP2);
+                ref += stride;
+                vis_and(TMP4, MASK_fe, TMP4);
+
+                vis_or(REF_0, REF_2, TMP6);
+                vis_mul8x16(CONST_128, TMP4, TMP4);
+
+                vis_faligndata(TMP0, TMP2, REF_0);
+                vis_ld64(ref[0], TMP0);
+
+                vis_ld64_2(ref, 8, TMP2);
+                ref += stride;
+                vis_xor(REF_0, REF_2, TMP12);
+
+                vis_and(TMP4, MASK_7f, TMP4);
+
+                vis_and(TMP12, MASK_fe, TMP12);
+
+                vis_mul8x16(CONST_128, TMP12, TMP12);
+                vis_or(REF_0, REF_2, TMP14);
+
+                vis_psub16(TMP6, TMP4, DST_0);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+
+                vis_faligndata(TMP0, TMP2, REF_2);
+
+                vis_and(TMP12, MASK_7f, TMP12);
+
+                vis_psub16(TMP14, TMP12, DST_0);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(REF_0, REF_2, TMP4);
+
+        vis_ld64_2(ref, 8, TMP2);
+        vis_and(TMP4, MASK_fe, TMP4);
+
+        vis_or(REF_0, REF_2, TMP6);
+        vis_mul8x16(CONST_128, TMP4, TMP4);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_xor(REF_0, REF_2, TMP12);
+
+        vis_and(TMP4, MASK_7f, TMP4);
+
+        vis_and(TMP12, MASK_fe, TMP12);
+
+        vis_mul8x16(CONST_128, TMP12, TMP12);
+        vis_or(REF_0, REF_2, TMP14);
+
+        vis_psub16(TMP6, TMP4, DST_0);
+        vis_st64(DST_0, dest[0]);
+        dest += stride;
+
+        vis_and(TMP12, MASK_7f, TMP12);
+
+        vis_psub16(TMP14, TMP12, DST_0);
+        vis_st64(DST_0, dest[0]);
+}
+
+static void MC_avg_y_16_vis (uint8_t * dest, const uint8_t * ref,
+                             const ptrdiff_t stride, int height)
+{
+        int stride_8 = stride + 8;
+        int stride_16 = stride + 16;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(ref[16], TMP4);
+
+        vis_ld64(constants3[0], CONST_3);
+        vis_faligndata(TMP0, TMP2, REF_2);
+
+        vis_ld64(constants256_512[0], CONST_256);
+        vis_faligndata(TMP2, TMP4, REF_6);
+        height >>= 1;
+
+        do {    /* 31 cycles */
+                vis_ld64_2(ref, stride, TMP0);
+                vis_pmerge(ZERO,       REF_2,     TMP12);
+                vis_mul8x16au(REF_2_1, CONST_256, TMP14);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                vis_pmerge(ZERO,       REF_6,     TMP16);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP18);
+
+                vis_ld64_2(ref, stride_16, TMP4);
+                ref += stride;
+
+                vis_ld64(dest[0], DST_0);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(dest, 8, DST_2);
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                vis_ld64_2(ref, stride, TMP6);
+                vis_pmerge(ZERO,     REF_0,     TMP0);
+                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
+
+                vis_ld64_2(ref, stride_8, TMP8);
+                vis_pmerge(ZERO,     REF_4,     TMP4);
+
+                vis_ld64_2(ref, stride_16, TMP10);
+                ref += stride;
+
+                vis_ld64_2(dest, stride, REF_S0/*DST_4*/);
+                vis_faligndata(TMP6, TMP8, REF_2);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP6);
+
+                vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/);
+                vis_faligndata(TMP8, TMP10, REF_6);
+                vis_mul8x16al(DST_0,   CONST_512, TMP20);
+
+                vis_padd16(TMP0, CONST_3, TMP0);
+                vis_mul8x16al(DST_1,   CONST_512, TMP22);
+
+                vis_padd16(TMP2, CONST_3, TMP2);
+                vis_mul8x16al(DST_2,   CONST_512, TMP24);
+
+                vis_padd16(TMP4, CONST_3, TMP4);
+                vis_mul8x16al(DST_3,   CONST_512, TMP26);
+
+                vis_padd16(TMP6, CONST_3, TMP6);
+
+                vis_padd16(TMP12, TMP20, TMP12);
+                vis_mul8x16al(REF_S0,   CONST_512, TMP20);
+
+                vis_padd16(TMP14, TMP22, TMP14);
+                vis_mul8x16al(REF_S0_1, CONST_512, TMP22);
+
+                vis_padd16(TMP16, TMP24, TMP16);
+                vis_mul8x16al(REF_S2,   CONST_512, TMP24);
+
+                vis_padd16(TMP18, TMP26, TMP18);
+                vis_mul8x16al(REF_S2_1, CONST_512, TMP26);
+
+                vis_padd16(TMP12, TMP0, TMP12);
+                vis_mul8x16au(REF_2,   CONST_256, TMP28);
+
+                vis_padd16(TMP14, TMP2, TMP14);
+                vis_mul8x16au(REF_2_1, CONST_256, TMP30);
+
+                vis_padd16(TMP16, TMP4, TMP16);
+                vis_mul8x16au(REF_6,   CONST_256, REF_S4);
+
+                vis_padd16(TMP18, TMP6, TMP18);
+                vis_mul8x16au(REF_6_1, CONST_256, REF_S6);
+
+                vis_pack16(TMP12, DST_0);
+                vis_padd16(TMP28, TMP0, TMP12);
+
+                vis_pack16(TMP14, DST_1);
+                vis_st64(DST_0, dest[0]);
+                vis_padd16(TMP30, TMP2, TMP14);
+
+                vis_pack16(TMP16, DST_2);
+                vis_padd16(REF_S4, TMP4, TMP16);
+
+                vis_pack16(TMP18, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+                vis_padd16(REF_S6, TMP6, TMP18);
+
+                vis_padd16(TMP12, TMP20, TMP12);
+
+                vis_padd16(TMP14, TMP22, TMP14);
+                vis_pack16(TMP12, DST_0);
+
+                vis_padd16(TMP16, TMP24, TMP16);
+                vis_pack16(TMP14, DST_1);
+                vis_st64(DST_0, dest[0]);
+
+                vis_padd16(TMP18, TMP26, TMP18);
+                vis_pack16(TMP16, DST_2);
+
+                vis_pack16(TMP18, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_avg_y_8_vis (uint8_t * dest, const uint8_t * ref,
+                            const ptrdiff_t stride, int height)
+{
+        int stride_8 = stride + 8;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(constants3[0], CONST_3);
+        vis_faligndata(TMP0, TMP2, REF_2);
+
+        vis_ld64(constants256_512[0], CONST_256);
+
+        height >>= 1;
+        do {    /* 20 cycles */
+                vis_ld64_2(ref, stride, TMP0);
+                vis_pmerge(ZERO,       REF_2,     TMP8);
+                vis_mul8x16au(REF_2_1, CONST_256, TMP10);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                ref += stride;
+
+                vis_ld64(dest[0], DST_0);
+
+                vis_ld64_2(dest, stride, DST_2);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, stride, TMP4);
+                vis_mul8x16al(DST_0,   CONST_512, TMP16);
+                vis_pmerge(ZERO,       REF_0,     TMP12);
+
+                vis_ld64_2(ref, stride_8, TMP6);
+                ref += stride;
+                vis_mul8x16al(DST_1,   CONST_512, TMP18);
+                vis_pmerge(ZERO,       REF_0_1,   TMP14);
+
+                vis_padd16(TMP12, CONST_3, TMP12);
+                vis_mul8x16al(DST_2,   CONST_512, TMP24);
+
+                vis_padd16(TMP14, CONST_3, TMP14);
+                vis_mul8x16al(DST_3,   CONST_512, TMP26);
+
+                vis_faligndata(TMP4, TMP6, REF_2);
+
+                vis_padd16(TMP8, TMP12, TMP8);
+
+                vis_padd16(TMP10, TMP14, TMP10);
+                vis_mul8x16au(REF_2,   CONST_256, TMP20);
+
+                vis_padd16(TMP8, TMP16, TMP0);
+                vis_mul8x16au(REF_2_1, CONST_256, TMP22);
+
+                vis_padd16(TMP10, TMP18, TMP2);
+                vis_pack16(TMP0, DST_0);
+
+                vis_pack16(TMP2, DST_1);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+                vis_padd16(TMP12, TMP20, TMP12);
+
+                vis_padd16(TMP14, TMP22, TMP14);
+
+                vis_padd16(TMP12, TMP24, TMP0);
+
+                vis_padd16(TMP14, TMP26, TMP2);
+                vis_pack16(TMP0, DST_2);
+
+                vis_pack16(TMP2, DST_3);
+                vis_st64(DST_2, dest[0]);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_put_xy_16_vis (uint8_t * dest, const uint8_t * ref,
+                              const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+        int stride_8 = stride + 8;
+        int stride_16 = stride + 16;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(ref[16], TMP4);
+
+        vis_ld64(constants2[0], CONST_2);
+        vis_faligndata(TMP0, TMP2, REF_S0);
+
+        vis_ld64(constants256_512[0], CONST_256);
+        vis_faligndata(TMP2, TMP4, REF_S4);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_S2);
+                vis_faligndata(TMP2, TMP4, REF_S6);
+        } else {
+                vis_src1(TMP2, REF_S2);
+                vis_src1(TMP4, REF_S6);
+        }
+
+        height >>= 1;
+        do {
+                vis_ld64_2(ref, stride, TMP0);
+                vis_mul8x16au(REF_S0, CONST_256, TMP12);
+                vis_pmerge(ZERO,      REF_S0_1,  TMP14);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                vis_mul8x16au(REF_S2, CONST_256, TMP16);
+                vis_pmerge(ZERO,      REF_S2_1,  TMP18);
+
+                vis_ld64_2(ref, stride_16, TMP4);
+                ref += stride;
+                vis_mul8x16au(REF_S4, CONST_256, TMP20);
+                vis_pmerge(ZERO,      REF_S4_1,  TMP22);
+
+                vis_ld64_2(ref, stride, TMP6);
+                vis_mul8x16au(REF_S6, CONST_256, TMP24);
+                vis_pmerge(ZERO,      REF_S6_1,  TMP26);
+
+                vis_ld64_2(ref, stride_8, TMP8);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, stride_16, TMP10);
+                ref += stride;
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                vis_faligndata(TMP6, TMP8, REF_S0);
+
+                vis_faligndata(TMP8, TMP10, REF_S4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                        vis_faligndata(TMP2, TMP4, REF_6);
+                        vis_faligndata(TMP6, TMP8, REF_S2);
+                        vis_faligndata(TMP8, TMP10, REF_S6);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                        vis_src1(TMP4, REF_6);
+                        vis_src1(TMP8, REF_S2);
+                        vis_src1(TMP10, REF_S6);
+                }
+
+                vis_mul8x16au(REF_0, CONST_256, TMP0);
+                vis_pmerge(ZERO,      REF_0_1,  TMP2);
+
+                vis_mul8x16au(REF_2, CONST_256, TMP4);
+                vis_pmerge(ZERO,      REF_2_1,  TMP6);
+
+                vis_padd16(TMP0, CONST_2, TMP8);
+                vis_mul8x16au(REF_4, CONST_256, TMP0);
+
+                vis_padd16(TMP2, CONST_2, TMP10);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP2);
+
+                vis_padd16(TMP8, TMP4, TMP8);
+                vis_mul8x16au(REF_6, CONST_256, TMP4);
+
+                vis_padd16(TMP10, TMP6, TMP10);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP6);
+
+                vis_padd16(TMP12, TMP8, TMP12);
+
+                vis_padd16(TMP14, TMP10, TMP14);
+
+                vis_padd16(TMP12, TMP16, TMP12);
+
+                vis_padd16(TMP14, TMP18, TMP14);
+                vis_pack16(TMP12, DST_0);
+
+                vis_pack16(TMP14, DST_1);
+                vis_st64(DST_0, dest[0]);
+                vis_padd16(TMP0, CONST_2, TMP12);
+
+                vis_mul8x16au(REF_S0, CONST_256, TMP0);
+                vis_padd16(TMP2, CONST_2, TMP14);
+
+                vis_mul8x16au(REF_S0_1, CONST_256, TMP2);
+                vis_padd16(TMP12, TMP4, TMP12);
+
+                vis_mul8x16au(REF_S2, CONST_256, TMP4);
+                vis_padd16(TMP14, TMP6, TMP14);
+
+                vis_mul8x16au(REF_S2_1, CONST_256, TMP6);
+                vis_padd16(TMP20, TMP12, TMP20);
+
+                vis_padd16(TMP22, TMP14, TMP22);
+
+                vis_padd16(TMP20, TMP24, TMP20);
+
+                vis_padd16(TMP22, TMP26, TMP22);
+                vis_pack16(TMP20, DST_2);
+
+                vis_pack16(TMP22, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+                vis_padd16(TMP0, TMP4, TMP24);
+
+                vis_mul8x16au(REF_S4, CONST_256, TMP0);
+                vis_padd16(TMP2, TMP6, TMP26);
+
+                vis_mul8x16au(REF_S4_1, CONST_256, TMP2);
+                vis_padd16(TMP24, TMP8, TMP24);
+
+                vis_padd16(TMP26, TMP10, TMP26);
+                vis_pack16(TMP24, DST_0);
+
+                vis_pack16(TMP26, DST_1);
+                vis_st64(DST_0, dest[0]);
+                vis_pmerge(ZERO, REF_S6, TMP4);
+
+                vis_pmerge(ZERO,      REF_S6_1,  TMP6);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+
+                vis_padd16(TMP0, TMP12, TMP0);
+
+                vis_padd16(TMP2, TMP14, TMP2);
+                vis_pack16(TMP0, DST_2);
+
+                vis_pack16(TMP2, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_put_xy_8_vis (uint8_t * dest, const uint8_t * ref,
+                             const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+        int stride_8 = stride + 8;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(constants2[0], CONST_2);
+
+        vis_ld64(constants256_512[0], CONST_256);
+        vis_faligndata(TMP0, TMP2, REF_S0);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_S2);
+        } else {
+                vis_src1(TMP2, REF_S2);
+        }
+
+        height >>= 1;
+        do {    /* 26 cycles */
+                vis_ld64_2(ref, stride, TMP0);
+                vis_mul8x16au(REF_S0,   CONST_256, TMP8);
+                vis_pmerge(ZERO,        REF_S2,    TMP12);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                ref += stride;
+                vis_mul8x16au(REF_S0_1, CONST_256, TMP10);
+                vis_pmerge(ZERO,        REF_S2_1,  TMP14);
+
+                vis_ld64_2(ref, stride, TMP4);
+
+                vis_ld64_2(ref, stride_8, TMP6);
+                ref += stride;
+                vis_faligndata(TMP0, TMP2, REF_S4);
+
+                vis_pmerge(ZERO, REF_S4, TMP18);
+
+                vis_pmerge(ZERO, REF_S4_1, TMP20);
+
+                vis_faligndata(TMP4, TMP6, REF_S0);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_S6);
+                        vis_faligndata(TMP4, TMP6, REF_S2);
+                } else {
+                        vis_src1(TMP2, REF_S6);
+                        vis_src1(TMP6, REF_S2);
+                }
+
+                vis_padd16(TMP18, CONST_2, TMP18);
+                vis_mul8x16au(REF_S6,   CONST_256, TMP22);
+
+                vis_padd16(TMP20, CONST_2, TMP20);
+                vis_mul8x16au(REF_S6_1, CONST_256, TMP24);
+
+                vis_mul8x16au(REF_S0,   CONST_256, TMP26);
+                vis_pmerge(ZERO, REF_S0_1, TMP28);
+
+                vis_mul8x16au(REF_S2,   CONST_256, TMP30);
+                vis_padd16(TMP18, TMP22, TMP18);
+
+                vis_mul8x16au(REF_S2_1, CONST_256, TMP32);
+                vis_padd16(TMP20, TMP24, TMP20);
+
+                vis_padd16(TMP8,  TMP18, TMP8);
+
+                vis_padd16(TMP10, TMP20, TMP10);
+
+                vis_padd16(TMP8,  TMP12, TMP8);
+
+                vis_padd16(TMP10, TMP14, TMP10);
+                vis_pack16(TMP8,  DST_0);
+
+                vis_pack16(TMP10, DST_1);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+                vis_padd16(TMP18, TMP26, TMP18);
+
+                vis_padd16(TMP20, TMP28, TMP20);
+
+                vis_padd16(TMP18, TMP30, TMP18);
+
+                vis_padd16(TMP20, TMP32, TMP20);
+                vis_pack16(TMP18, DST_2);
+
+                vis_pack16(TMP20, DST_3);
+                vis_st64(DST_2, dest[0]);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_avg_xy_16_vis (uint8_t * dest, const uint8_t * ref,
+                              const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+        int stride_8 = stride + 8;
+        int stride_16 = stride + 16;
+
+        vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(ref[16], TMP4);
+
+        vis_ld64(constants6[0], CONST_6);
+        vis_faligndata(TMP0, TMP2, REF_S0);
+
+        vis_ld64(constants256_1024[0], CONST_256);
+        vis_faligndata(TMP2, TMP4, REF_S4);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_S2);
+                vis_faligndata(TMP2, TMP4, REF_S6);
+        } else {
+                vis_src1(TMP2, REF_S2);
+                vis_src1(TMP4, REF_S6);
+        }
+
+        height >>= 1;
+        do {    /* 55 cycles */
+                vis_ld64_2(ref, stride, TMP0);
+                vis_mul8x16au(REF_S0, CONST_256, TMP12);
+                vis_pmerge(ZERO,      REF_S0_1,  TMP14);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                vis_mul8x16au(REF_S2, CONST_256, TMP16);
+                vis_pmerge(ZERO,      REF_S2_1,  TMP18);
+
+                vis_ld64_2(ref, stride_16, TMP4);
+                ref += stride;
+                vis_mul8x16au(REF_S4, CONST_256, TMP20);
+                vis_pmerge(ZERO,      REF_S4_1,  TMP22);
+
+                vis_ld64_2(ref, stride, TMP6);
+                vis_mul8x16au(REF_S6, CONST_256, TMP24);
+                vis_pmerge(ZERO,      REF_S6_1,  TMP26);
+
+                vis_ld64_2(ref, stride_8, TMP8);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, stride_16, TMP10);
+                ref += stride;
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                vis_ld64(dest[0], DST_0);
+                vis_faligndata(TMP6, TMP8, REF_S0);
+
+                vis_ld64_2(dest, 8, DST_2);
+                vis_faligndata(TMP8, TMP10, REF_S4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                        vis_faligndata(TMP2, TMP4, REF_6);
+                        vis_faligndata(TMP6, TMP8, REF_S2);
+                        vis_faligndata(TMP8, TMP10, REF_S6);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                        vis_src1(TMP4, REF_6);
+                        vis_src1(TMP8, REF_S2);
+                        vis_src1(TMP10, REF_S6);
+                }
+
+                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
+                vis_pmerge(ZERO, REF_0, TMP0);
+
+                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
+                vis_pmerge(ZERO,      REF_0_1,  TMP2);
+
+                vis_mul8x16au(REF_2, CONST_256, TMP4);
+                vis_pmerge(ZERO,      REF_2_1,  TMP6);
+
+                vis_mul8x16al(DST_2,   CONST_1024, REF_0);
+                vis_padd16(TMP0, CONST_6, TMP0);
+
+                vis_mul8x16al(DST_3,   CONST_1024, REF_2);
+                vis_padd16(TMP2, CONST_6, TMP2);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+                vis_mul8x16au(REF_4, CONST_256, TMP4);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP6);
+
+                vis_padd16(TMP12, TMP0, TMP12);
+                vis_mul8x16au(REF_6, CONST_256, TMP8);
+
+                vis_padd16(TMP14, TMP2, TMP14);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP10);
+
+                vis_padd16(TMP12, TMP16, TMP12);
+                vis_mul8x16au(REF_S0, CONST_256, REF_4);
+
+                vis_padd16(TMP14, TMP18, TMP14);
+                vis_mul8x16au(REF_S0_1, CONST_256, REF_6);
+
+                vis_padd16(TMP12, TMP30, TMP12);
+
+                vis_padd16(TMP14, TMP32, TMP14);
+                vis_pack16(TMP12, DST_0);
+
+                vis_pack16(TMP14, DST_1);
+                vis_st64(DST_0, dest[0]);
+                vis_padd16(TMP4, CONST_6, TMP4);
+
+                vis_ld64_2(dest, stride, DST_0);
+                vis_padd16(TMP6, CONST_6, TMP6);
+                vis_mul8x16au(REF_S2, CONST_256, TMP12);
+
+                vis_padd16(TMP4, TMP8, TMP4);
+                vis_mul8x16au(REF_S2_1, CONST_256,  TMP14);
+
+                vis_padd16(TMP6, TMP10, TMP6);
+
+                vis_padd16(TMP20, TMP4, TMP20);
+
+                vis_padd16(TMP22, TMP6, TMP22);
+
+                vis_padd16(TMP20, TMP24, TMP20);
+
+                vis_padd16(TMP22, TMP26, TMP22);
+
+                vis_padd16(TMP20, REF_0, TMP20);
+                vis_mul8x16au(REF_S4, CONST_256, REF_0);
+
+                vis_padd16(TMP22, REF_2, TMP22);
+                vis_pack16(TMP20, DST_2);
+
+                vis_pack16(TMP22, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+
+                vis_ld64_2(dest, 8, DST_2);
+                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
+                vis_pmerge(ZERO,      REF_S4_1,  REF_2);
+
+                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
+                vis_padd16(REF_4, TMP0, TMP8);
+
+                vis_mul8x16au(REF_S6, CONST_256, REF_4);
+                vis_padd16(REF_6, TMP2, TMP10);
+
+                vis_mul8x16au(REF_S6_1, CONST_256, REF_6);
+                vis_padd16(TMP8, TMP12, TMP8);
+
+                vis_padd16(TMP10, TMP14, TMP10);
+
+                vis_padd16(TMP8, TMP30, TMP8);
+
+                vis_padd16(TMP10, TMP32, TMP10);
+                vis_pack16(TMP8, DST_0);
+
+                vis_pack16(TMP10, DST_1);
+                vis_st64(DST_0, dest[0]);
+
+                vis_padd16(REF_0, TMP4, REF_0);
+
+                vis_mul8x16al(DST_2,   CONST_1024, TMP30);
+                vis_padd16(REF_2, TMP6, REF_2);
+
+                vis_mul8x16al(DST_3,   CONST_1024, TMP32);
+                vis_padd16(REF_0, REF_4, REF_0);
+
+                vis_padd16(REF_2, REF_6, REF_2);
+
+                vis_padd16(REF_0, TMP30, REF_0);
+
+                /* stall */
+
+                vis_padd16(REF_2, TMP32, REF_2);
+                vis_pack16(REF_0, DST_2);
+
+                vis_pack16(REF_2, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_avg_xy_8_vis (uint8_t * dest, const uint8_t * ref,
+                             const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+        int stride_8 = stride + 8;
+
+        vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64_2(ref, 8, TMP2);
+
+        vis_ld64(constants6[0], CONST_6);
+
+        vis_ld64(constants256_1024[0], CONST_256);
+        vis_faligndata(TMP0, TMP2, REF_S0);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_S2);
+        } else {
+                vis_src1(TMP2, REF_S2);
+        }
+
+        height >>= 1;
+        do {    /* 31 cycles */
+                vis_ld64_2(ref, stride, TMP0);
+                vis_mul8x16au(REF_S0, CONST_256, TMP8);
+                vis_pmerge(ZERO,      REF_S0_1,  TMP10);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                ref += stride;
+                vis_mul8x16au(REF_S2, CONST_256, TMP12);
+                vis_pmerge(ZERO,      REF_S2_1,  TMP14);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, stride, TMP4);
+                vis_faligndata(TMP0, TMP2, REF_S4);
+
+                vis_ld64_2(ref, stride_8, TMP6);
+                ref += stride;
+
+                vis_ld64(dest[0], DST_0);
+                vis_faligndata(TMP4, TMP6, REF_S0);
+
+                vis_ld64_2(dest, stride, DST_2);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_S6);
+                        vis_faligndata(TMP4, TMP6, REF_S2);
+                } else {
+                        vis_src1(TMP2, REF_S6);
+                        vis_src1(TMP6, REF_S2);
+                }
+
+                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
+                vis_pmerge(ZERO, REF_S4, TMP22);
+
+                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
+                vis_pmerge(ZERO,      REF_S4_1,  TMP24);
+
+                vis_mul8x16au(REF_S6, CONST_256, TMP26);
+                vis_pmerge(ZERO,      REF_S6_1,  TMP28);
+
+                vis_mul8x16au(REF_S0, CONST_256, REF_S4);
+                vis_padd16(TMP22, CONST_6, TMP22);
+
+                vis_mul8x16au(REF_S0_1, CONST_256, REF_S6);
+                vis_padd16(TMP24, CONST_6, TMP24);
+
+                vis_mul8x16al(DST_2,   CONST_1024, REF_0);
+                vis_padd16(TMP22, TMP26, TMP22);
+
+                vis_mul8x16al(DST_3,   CONST_1024, REF_2);
+                vis_padd16(TMP24, TMP28, TMP24);
+
+                vis_mul8x16au(REF_S2, CONST_256, TMP26);
+                vis_padd16(TMP8, TMP22, TMP8);
+
+                vis_mul8x16au(REF_S2_1, CONST_256, TMP28);
+                vis_padd16(TMP10, TMP24, TMP10);
+
+                vis_padd16(TMP8, TMP12, TMP8);
+
+                vis_padd16(TMP10, TMP14, TMP10);
+
+                vis_padd16(TMP8, TMP30, TMP8);
+
+                vis_padd16(TMP10, TMP32, TMP10);
+                vis_pack16(TMP8, DST_0);
+
+                vis_pack16(TMP10, DST_1);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+
+                vis_padd16(REF_S4, TMP22, TMP12);
+
+                vis_padd16(REF_S6, TMP24, TMP14);
+
+                vis_padd16(TMP12, TMP26, TMP12);
+
+                vis_padd16(TMP14, TMP28, TMP14);
+
+                vis_padd16(TMP12, REF_0, TMP12);
+
+                vis_padd16(TMP14, REF_2, TMP14);
+                vis_pack16(TMP12, DST_2);
+
+                vis_pack16(TMP14, DST_3);
+                vis_st64(DST_2, dest[0]);
+                dest += stride;
+        } while (--height);
+}
+
+/* End of rounding code */
+
+/* Start of no rounding code */
+/* The trick used in some of this file is the formula from the MMX
+ * motion comp code, which is:
+ *
+ * (x+y)>>1 == (x&y)+((x^y)>>1)
+ *
+ * This allows us to average 8 bytes at a time in a 64-bit FPU reg.
+ * We avoid overflows by masking before we do the shift, and we
+ * implement the shift by multiplying by 1/2 using mul8x16.  So in
+ * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask
+ * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and
+ * the value 0x80808080 is in f8):
+ *
+ *      fxor            f0,   f2, f10
+ *      fand            f10,  f4, f10
+ *      fmul8x16        f8,  f10, f10
+ *      fand            f10,  f6, f10
+ *      fand            f0,   f2, f12
+ *      fpadd16         f12, f10, f10
+ */
+
+static void MC_put_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
+                                      const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+        do {    /* 5 cycles */
+                vis_ld64(ref[0], TMP0);
+
+                vis_ld64_2(ref, 8, TMP2);
+
+                vis_ld64_2(ref, 16, TMP4);
+                ref += stride;
+
+                vis_faligndata(TMP0, TMP2, REF_0);
+                vis_st64(REF_0, dest[0]);
+
+                vis_faligndata(TMP2, TMP4, REF_2);
+                vis_st64_2(REF_2, dest, 8);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_put_no_round_o_8_vis (uint8_t * dest, const uint8_t * ref,
+                                     const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+        do {    /* 4 cycles */
+                vis_ld64(ref[0], TMP0);
+
+                vis_ld64(ref[8], TMP2);
+                ref += stride;
+
+                /* stall */
+
+                vis_faligndata(TMP0, TMP2, REF_0);
+                vis_st64(REF_0, dest[0]);
+                dest += stride;
+        } while (--height);
+}
+
+
+static void MC_avg_no_round_o_16_vis (uint8_t * dest, const uint8_t * ref,
+                                      const ptrdiff_t stride, int height)
+{
+        int stride_8 = stride + 8;
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64(ref[8], TMP2);
+
+        vis_ld64(ref[16], TMP4);
+
+        vis_ld64(dest[0], DST_0);
+
+        vis_ld64(dest[8], DST_2);
+
+        vis_ld64(constants_fe[0], MASK_fe);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP2, TMP4, REF_2);
+
+        vis_ld64(constants128[0], CONST_128);
+
+        ref += stride;
+        height = (height >> 1) - 1;
+
+        do {    /* 24 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(DST_0, REF_0, TMP6);
+
+                vis_ld64_2(ref, 8, TMP2);
+                vis_and(TMP6, MASK_fe, TMP6);
+
+                vis_ld64_2(ref, 16, TMP4);
+                ref += stride;
+                vis_mul8x16(CONST_128, TMP6, TMP6);
+                vis_xor(DST_2, REF_2, TMP8);
+
+                vis_and(TMP8, MASK_fe, TMP8);
+
+                vis_and(DST_0, REF_0, TMP10);
+                vis_ld64_2(dest, stride, DST_0);
+                vis_mul8x16(CONST_128, TMP8, TMP8);
+
+                vis_and(DST_2, REF_2, TMP12);
+                vis_ld64_2(dest, stride_8, DST_2);
+
+                vis_ld64(ref[0], TMP14);
+                vis_and(TMP6, MASK_7f, TMP6);
+
+                vis_and(TMP8, MASK_7f, TMP8);
+
+                vis_padd16(TMP10, TMP6, TMP6);
+                vis_st64(TMP6, dest[0]);
+
+                vis_padd16(TMP12, TMP8, TMP8);
+                vis_st64_2(TMP8, dest, 8);
+
+                dest += stride;
+                vis_ld64_2(ref, 8, TMP16);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, 16, TMP18);
+                vis_faligndata(TMP2, TMP4, REF_2);
+                ref += stride;
+
+                vis_xor(DST_0, REF_0, TMP20);
+
+                vis_and(TMP20, MASK_fe, TMP20);
+
+                vis_xor(DST_2, REF_2, TMP22);
+                vis_mul8x16(CONST_128, TMP20, TMP20);
+
+                vis_and(TMP22, MASK_fe, TMP22);
+
+                vis_and(DST_0, REF_0, TMP24);
+                vis_mul8x16(CONST_128, TMP22, TMP22);
+
+                vis_and(DST_2, REF_2, TMP26);
+
+                vis_ld64_2(dest, stride, DST_0);
+                vis_faligndata(TMP14, TMP16, REF_0);
+
+                vis_ld64_2(dest, stride_8, DST_2);
+                vis_faligndata(TMP16, TMP18, REF_2);
+
+                vis_and(TMP20, MASK_7f, TMP20);
+
+                vis_and(TMP22, MASK_7f, TMP22);
+
+                vis_padd16(TMP24, TMP20, TMP20);
+                vis_st64(TMP20, dest[0]);
+
+                vis_padd16(TMP26, TMP22, TMP22);
+                vis_st64_2(TMP22, dest, 8);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(DST_0, REF_0, TMP6);
+
+        vis_ld64_2(ref, 8, TMP2);
+        vis_and(TMP6, MASK_fe, TMP6);
+
+        vis_ld64_2(ref, 16, TMP4);
+        vis_mul8x16(CONST_128, TMP6, TMP6);
+        vis_xor(DST_2, REF_2, TMP8);
+
+        vis_and(TMP8, MASK_fe, TMP8);
+
+        vis_and(DST_0, REF_0, TMP10);
+        vis_ld64_2(dest, stride, DST_0);
+        vis_mul8x16(CONST_128, TMP8, TMP8);
+
+        vis_and(DST_2, REF_2, TMP12);
+        vis_ld64_2(dest, stride_8, DST_2);
+
+        vis_ld64(ref[0], TMP14);
+        vis_and(TMP6, MASK_7f, TMP6);
+
+        vis_and(TMP8, MASK_7f, TMP8);
+
+        vis_padd16(TMP10, TMP6, TMP6);
+        vis_st64(TMP6, dest[0]);
+
+        vis_padd16(TMP12, TMP8, TMP8);
+        vis_st64_2(TMP8, dest, 8);
+
+        dest += stride;
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_faligndata(TMP2, TMP4, REF_2);
+
+        vis_xor(DST_0, REF_0, TMP20);
+
+        vis_and(TMP20, MASK_fe, TMP20);
+
+        vis_xor(DST_2, REF_2, TMP22);
+        vis_mul8x16(CONST_128, TMP20, TMP20);
+
+        vis_and(TMP22, MASK_fe, TMP22);
+
+        vis_and(DST_0, REF_0, TMP24);
+        vis_mul8x16(CONST_128, TMP22, TMP22);
+
+        vis_and(DST_2, REF_2, TMP26);
+
+        vis_and(TMP20, MASK_7f, TMP20);
+
+        vis_and(TMP22, MASK_7f, TMP22);
+
+        vis_padd16(TMP24, TMP20, TMP20);
+        vis_st64(TMP20, dest[0]);
+
+        vis_padd16(TMP26, TMP22, TMP22);
+        vis_st64_2(TMP22, dest, 8);
+}
+
+static void MC_put_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
+                                      const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[0],    TMP0);
+
+        vis_ld64_2(ref, 8,  TMP2);
+
+        vis_ld64_2(ref, 16, TMP4);
+
+        vis_ld64(constants_fe[0], MASK_fe);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64(constants128[0], CONST_128);
+        vis_faligndata(TMP2, TMP4, REF_4);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_2);
+                vis_faligndata(TMP2, TMP4, REF_6);
+        } else {
+                vis_src1(TMP2, REF_2);
+                vis_src1(TMP4, REF_6);
+        }
+
+        ref += stride;
+        height = (height >> 1) - 1;
+
+        do {    /* 34 cycles */
+                vis_ld64(ref[0],    TMP0);
+                vis_xor(REF_0, REF_2, TMP6);
+
+                vis_ld64_2(ref, 8,  TMP2);
+                vis_xor(REF_4, REF_6, TMP8);
+
+                vis_ld64_2(ref, 16, TMP4);
+                vis_and(TMP6, MASK_fe, TMP6);
+                ref += stride;
+
+                vis_ld64(ref[0],    TMP14);
+                vis_mul8x16(CONST_128, TMP6, TMP6);
+                vis_and(TMP8, MASK_fe, TMP8);
+
+                vis_ld64_2(ref, 8,  TMP16);
+                vis_mul8x16(CONST_128, TMP8, TMP8);
+                vis_and(REF_0, REF_2, TMP10);
+
+                vis_ld64_2(ref, 16, TMP18);
+                ref += stride;
+                vis_and(REF_4, REF_6, TMP12);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                        vis_faligndata(TMP2, TMP4, REF_6);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                        vis_src1(TMP4, REF_6);
+                }
+
+                vis_and(TMP6, MASK_7f, TMP6);
+
+                vis_and(TMP8, MASK_7f, TMP8);
+
+                vis_padd16(TMP10, TMP6, TMP6);
+                vis_st64(TMP6, dest[0]);
+
+                vis_padd16(TMP12, TMP8, TMP8);
+                vis_st64_2(TMP8, dest, 8);
+                dest += stride;
+
+                vis_xor(REF_0, REF_2, TMP6);
+
+                vis_xor(REF_4, REF_6, TMP8);
+
+                vis_and(TMP6, MASK_fe, TMP6);
+
+                vis_mul8x16(CONST_128, TMP6, TMP6);
+                vis_and(TMP8, MASK_fe, TMP8);
+
+                vis_mul8x16(CONST_128, TMP8, TMP8);
+                vis_and(REF_0, REF_2, TMP10);
+
+                vis_and(REF_4, REF_6, TMP12);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_faligndata(TMP14, TMP16, REF_0);
+
+                vis_faligndata(TMP16, TMP18, REF_4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP14, TMP16, REF_2);
+                        vis_faligndata(TMP16, TMP18, REF_6);
+                } else {
+                        vis_src1(TMP16, REF_2);
+                        vis_src1(TMP18, REF_6);
+                }
+
+                vis_and(TMP6, MASK_7f, TMP6);
+
+                vis_and(TMP8, MASK_7f, TMP8);
+
+                vis_padd16(TMP10, TMP6, TMP6);
+                vis_st64(TMP6, dest[0]);
+
+                vis_padd16(TMP12, TMP8, TMP8);
+                vis_st64_2(TMP8, dest, 8);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0],    TMP0);
+        vis_xor(REF_0, REF_2, TMP6);
+
+        vis_ld64_2(ref, 8,  TMP2);
+        vis_xor(REF_4, REF_6, TMP8);
+
+        vis_ld64_2(ref, 16, TMP4);
+        vis_and(TMP6, MASK_fe, TMP6);
+
+        vis_mul8x16(CONST_128, TMP6, TMP6);
+        vis_and(TMP8, MASK_fe, TMP8);
+
+        vis_mul8x16(CONST_128, TMP8, TMP8);
+        vis_and(REF_0, REF_2, TMP10);
+
+        vis_and(REF_4, REF_6, TMP12);
+
+        vis_alignaddr_g0((void *)off);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_faligndata(TMP2, TMP4, REF_4);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_2);
+                vis_faligndata(TMP2, TMP4, REF_6);
+        } else {
+                vis_src1(TMP2, REF_2);
+                vis_src1(TMP4, REF_6);
+        }
+
+        vis_and(TMP6, MASK_7f, TMP6);
+
+        vis_and(TMP8, MASK_7f, TMP8);
+
+        vis_padd16(TMP10, TMP6, TMP6);
+        vis_st64(TMP6, dest[0]);
+
+        vis_padd16(TMP12, TMP8, TMP8);
+        vis_st64_2(TMP8, dest, 8);
+        dest += stride;
+
+        vis_xor(REF_0, REF_2, TMP6);
+
+        vis_xor(REF_4, REF_6, TMP8);
+
+        vis_and(TMP6, MASK_fe, TMP6);
+
+        vis_mul8x16(CONST_128, TMP6, TMP6);
+        vis_and(TMP8, MASK_fe, TMP8);
+
+        vis_mul8x16(CONST_128, TMP8, TMP8);
+        vis_and(REF_0, REF_2, TMP10);
+
+        vis_and(REF_4, REF_6, TMP12);
+
+        vis_and(TMP6, MASK_7f, TMP6);
+
+        vis_and(TMP8, MASK_7f, TMP8);
+
+        vis_padd16(TMP10, TMP6, TMP6);
+        vis_st64(TMP6, dest[0]);
+
+        vis_padd16(TMP12, TMP8, TMP8);
+        vis_st64_2(TMP8, dest, 8);
+}
+
+static void MC_put_no_round_x_8_vis (uint8_t * dest, const uint8_t * ref,
+                                     const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64(ref[8], TMP2);
+
+        vis_ld64(constants_fe[0], MASK_fe);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+
+        vis_ld64(constants128[0], CONST_128);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_2);
+        } else {
+                vis_src1(TMP2, REF_2);
+        }
+
+        ref += stride;
+        height = (height >> 1) - 1;
+
+        do {    /* 20 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(REF_0, REF_2, TMP4);
+
+                vis_ld64_2(ref, 8, TMP2);
+                vis_and(TMP4, MASK_fe, TMP4);
+                ref += stride;
+
+                vis_ld64(ref[0], TMP8);
+                vis_and(REF_0, REF_2, TMP6);
+                vis_mul8x16(CONST_128, TMP4, TMP4);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, 8, TMP10);
+                ref += stride;
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                }
+
+                vis_and(TMP4, MASK_7f, TMP4);
+
+                vis_padd16(TMP6, TMP4, DST_0);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+
+                vis_xor(REF_0, REF_2, TMP12);
+
+                vis_and(TMP12, MASK_fe, TMP12);
+
+                vis_and(REF_0, REF_2, TMP14);
+                vis_mul8x16(CONST_128, TMP12, TMP12);
+
+                vis_alignaddr_g0((void *)off);
+                vis_faligndata(TMP8, TMP10, REF_0);
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP8, TMP10, REF_2);
+                } else {
+                        vis_src1(TMP10, REF_2);
+                }
+
+                vis_and(TMP12, MASK_7f, TMP12);
+
+                vis_padd16(TMP14, TMP12, DST_0);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(REF_0, REF_2, TMP4);
+
+        vis_ld64_2(ref, 8, TMP2);
+        vis_and(TMP4, MASK_fe, TMP4);
+
+        vis_and(REF_0, REF_2, TMP6);
+        vis_mul8x16(CONST_128, TMP4, TMP4);
+
+        vis_alignaddr_g0((void *)off);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_2);
+        } else {
+                vis_src1(TMP2, REF_2);
+        }
+
+        vis_and(TMP4, MASK_7f, TMP4);
+
+        vis_padd16(TMP6, TMP4, DST_0);
+        vis_st64(DST_0, dest[0]);
+        dest += stride;
+
+        vis_xor(REF_0, REF_2, TMP12);
+
+        vis_and(TMP12, MASK_fe, TMP12);
+
+        vis_and(REF_0, REF_2, TMP14);
+        vis_mul8x16(CONST_128, TMP12, TMP12);
+
+        vis_and(TMP12, MASK_7f, TMP12);
+
+        vis_padd16(TMP14, TMP12, DST_0);
+        vis_st64(DST_0, dest[0]);
+        dest += stride;
+}
+
+static void MC_avg_no_round_x_16_vis (uint8_t * dest, const uint8_t * ref,
+                                      const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        vis_ld64(constants3[0], CONST_3);
+        vis_fzero(ZERO);
+        vis_ld64(constants256_512[0], CONST_256);
+
+        ref = vis_alignaddr(ref);
+        do {    /* 26 cycles */
+                vis_ld64(ref[0], TMP0);
+
+                vis_ld64(ref[8], TMP2);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64(ref[16], TMP4);
+
+                vis_ld64(dest[0], DST_0);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64(dest[8], DST_2);
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                        vis_faligndata(TMP2, TMP4, REF_6);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                        vis_src1(TMP4, REF_6);
+                }
+
+                vis_mul8x16au(REF_0,   CONST_256, TMP0);
+
+                vis_pmerge(ZERO,     REF_2,     TMP4);
+                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
+
+                vis_pmerge(ZERO, REF_2_1, TMP6);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+
+                vis_mul8x16al(DST_0,   CONST_512, TMP4);
+                vis_padd16(TMP2, TMP6, TMP2);
+
+                vis_mul8x16al(DST_1,   CONST_512, TMP6);
+
+                vis_mul8x16au(REF_6,   CONST_256, TMP12);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP14);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+                vis_mul8x16au(REF_4,   CONST_256, TMP16);
+
+                vis_padd16(TMP0, CONST_3, TMP8);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP18);
+
+                vis_padd16(TMP2, CONST_3, TMP10);
+                vis_pack16(TMP8, DST_0);
+
+                vis_pack16(TMP10, DST_1);
+                vis_padd16(TMP16, TMP12, TMP0);
+
+                vis_st64(DST_0, dest[0]);
+                vis_mul8x16al(DST_2,   CONST_512, TMP4);
+                vis_padd16(TMP18, TMP14, TMP2);
+
+                vis_mul8x16al(DST_3,   CONST_512, TMP6);
+                vis_padd16(TMP0, CONST_3, TMP0);
+
+                vis_padd16(TMP2, CONST_3, TMP2);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+                vis_pack16(TMP0, DST_2);
+
+                vis_pack16(TMP2, DST_3);
+                vis_st64(DST_2, dest[8]);
+
+                ref += stride;
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_put_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
+                                      const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64_2(ref, 8, TMP2);
+
+        vis_ld64_2(ref, 16, TMP4);
+        ref += stride;
+
+        vis_ld64(ref[0], TMP6);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64_2(ref, 8, TMP8);
+        vis_faligndata(TMP2, TMP4, REF_4);
+
+        vis_ld64_2(ref, 16, TMP10);
+        ref += stride;
+
+        vis_ld64(constants_fe[0], MASK_fe);
+        vis_faligndata(TMP6, TMP8, REF_2);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP8, TMP10, REF_6);
+
+        vis_ld64(constants128[0], CONST_128);
+        height = (height >> 1) - 1;
+        do {    /* 24 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(REF_0, REF_2, TMP12);
+
+                vis_ld64_2(ref, 8, TMP2);
+                vis_xor(REF_4, REF_6, TMP16);
+
+                vis_ld64_2(ref, 16, TMP4);
+                ref += stride;
+                vis_and(REF_0, REF_2, TMP14);
+
+                vis_ld64(ref[0], TMP6);
+                vis_and(REF_4, REF_6, TMP18);
+
+                vis_ld64_2(ref, 8, TMP8);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, 16, TMP10);
+                ref += stride;
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                vis_and(TMP12, MASK_fe, TMP12);
+
+                vis_and(TMP16, MASK_fe, TMP16);
+                vis_mul8x16(CONST_128, TMP12, TMP12);
+
+                vis_mul8x16(CONST_128, TMP16, TMP16);
+                vis_xor(REF_0, REF_2, TMP0);
+
+                vis_xor(REF_4, REF_6, TMP2);
+
+                vis_and(REF_0, REF_2, TMP20);
+
+                vis_and(TMP12, MASK_7f, TMP12);
+
+                vis_and(TMP16, MASK_7f, TMP16);
+
+                vis_padd16(TMP14, TMP12, TMP12);
+                vis_st64(TMP12, dest[0]);
+
+                vis_padd16(TMP18, TMP16, TMP16);
+                vis_st64_2(TMP16, dest, 8);
+                dest += stride;
+
+                vis_and(REF_4, REF_6, TMP18);
+
+                vis_and(TMP0, MASK_fe, TMP0);
+
+                vis_and(TMP2, MASK_fe, TMP2);
+                vis_mul8x16(CONST_128, TMP0, TMP0);
+
+                vis_faligndata(TMP6, TMP8, REF_2);
+                vis_mul8x16(CONST_128, TMP2, TMP2);
+
+                vis_faligndata(TMP8, TMP10, REF_6);
+
+                vis_and(TMP0, MASK_7f, TMP0);
+
+                vis_and(TMP2, MASK_7f, TMP2);
+
+                vis_padd16(TMP20, TMP0, TMP0);
+                vis_st64(TMP0, dest[0]);
+
+                vis_padd16(TMP18, TMP2, TMP2);
+                vis_st64_2(TMP2, dest, 8);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(REF_0, REF_2, TMP12);
+
+        vis_ld64_2(ref, 8, TMP2);
+        vis_xor(REF_4, REF_6, TMP16);
+
+        vis_ld64_2(ref, 16, TMP4);
+        vis_and(REF_0, REF_2, TMP14);
+
+        vis_and(REF_4, REF_6, TMP18);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_faligndata(TMP2, TMP4, REF_4);
+
+        vis_and(TMP12, MASK_fe, TMP12);
+
+        vis_and(TMP16, MASK_fe, TMP16);
+        vis_mul8x16(CONST_128, TMP12, TMP12);
+
+        vis_mul8x16(CONST_128, TMP16, TMP16);
+        vis_xor(REF_0, REF_2, TMP0);
+
+        vis_xor(REF_4, REF_6, TMP2);
+
+        vis_and(REF_0, REF_2, TMP20);
+
+        vis_and(TMP12, MASK_7f, TMP12);
+
+        vis_and(TMP16, MASK_7f, TMP16);
+
+        vis_padd16(TMP14, TMP12, TMP12);
+        vis_st64(TMP12, dest[0]);
+
+        vis_padd16(TMP18, TMP16, TMP16);
+        vis_st64_2(TMP16, dest, 8);
+        dest += stride;
+
+        vis_and(REF_4, REF_6, TMP18);
+
+        vis_and(TMP0, MASK_fe, TMP0);
+
+        vis_and(TMP2, MASK_fe, TMP2);
+        vis_mul8x16(CONST_128, TMP0, TMP0);
+
+        vis_mul8x16(CONST_128, TMP2, TMP2);
+
+        vis_and(TMP0, MASK_7f, TMP0);
+
+        vis_and(TMP2, MASK_7f, TMP2);
+
+        vis_padd16(TMP20, TMP0, TMP0);
+        vis_st64(TMP0, dest[0]);
+
+        vis_padd16(TMP18, TMP2, TMP2);
+        vis_st64_2(TMP2, dest, 8);
+}
+
+static void MC_put_no_round_y_8_vis (uint8_t * dest, const uint8_t * ref,
+                                     const ptrdiff_t stride, int height)
+{
+        ref = vis_alignaddr(ref);
+        vis_ld64(ref[0], TMP0);
+
+        vis_ld64_2(ref, 8, TMP2);
+        ref += stride;
+
+        vis_ld64(ref[0], TMP4);
+
+        vis_ld64_2(ref, 8, TMP6);
+        ref += stride;
+
+        vis_ld64(constants_fe[0], MASK_fe);
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_ld64(constants_7f[0], MASK_7f);
+        vis_faligndata(TMP4, TMP6, REF_2);
+
+        vis_ld64(constants128[0], CONST_128);
+        height = (height >> 1) - 1;
+        do {    /* 12 cycles */
+                vis_ld64(ref[0], TMP0);
+                vis_xor(REF_0, REF_2, TMP4);
+
+                vis_ld64_2(ref, 8, TMP2);
+                ref += stride;
+                vis_and(TMP4, MASK_fe, TMP4);
+
+                vis_and(REF_0, REF_2, TMP6);
+                vis_mul8x16(CONST_128, TMP4, TMP4);
+
+                vis_faligndata(TMP0, TMP2, REF_0);
+                vis_ld64(ref[0], TMP0);
+
+                vis_ld64_2(ref, 8, TMP2);
+                ref += stride;
+                vis_xor(REF_0, REF_2, TMP12);
+
+                vis_and(TMP4, MASK_7f, TMP4);
+
+                vis_and(TMP12, MASK_fe, TMP12);
+
+                vis_mul8x16(CONST_128, TMP12, TMP12);
+                vis_and(REF_0, REF_2, TMP14);
+
+                vis_padd16(TMP6, TMP4, DST_0);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+
+                vis_faligndata(TMP0, TMP2, REF_2);
+
+                vis_and(TMP12, MASK_7f, TMP12);
+
+                vis_padd16(TMP14, TMP12, DST_0);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+        } while (--height);
+
+        vis_ld64(ref[0], TMP0);
+        vis_xor(REF_0, REF_2, TMP4);
+
+        vis_ld64_2(ref, 8, TMP2);
+        vis_and(TMP4, MASK_fe, TMP4);
+
+        vis_and(REF_0, REF_2, TMP6);
+        vis_mul8x16(CONST_128, TMP4, TMP4);
+
+        vis_faligndata(TMP0, TMP2, REF_0);
+
+        vis_xor(REF_0, REF_2, TMP12);
+
+        vis_and(TMP4, MASK_7f, TMP4);
+
+        vis_and(TMP12, MASK_fe, TMP12);
+
+        vis_mul8x16(CONST_128, TMP12, TMP12);
+        vis_and(REF_0, REF_2, TMP14);
+
+        vis_padd16(TMP6, TMP4, DST_0);
+        vis_st64(DST_0, dest[0]);
+        dest += stride;
+
+        vis_and(TMP12, MASK_7f, TMP12);
+
+        vis_padd16(TMP14, TMP12, DST_0);
+        vis_st64(DST_0, dest[0]);
+}
+
+static void MC_avg_no_round_y_16_vis (uint8_t * dest, const uint8_t * ref,
+                                      const ptrdiff_t stride, int height)
+{
+        int stride_8 = stride + 8;
+        int stride_16 = stride + 16;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(ref[16], TMP4);
+
+        vis_ld64(constants3[0], CONST_3);
+        vis_faligndata(TMP0, TMP2, REF_2);
+
+        vis_ld64(constants256_512[0], CONST_256);
+        vis_faligndata(TMP2, TMP4, REF_6);
+        height >>= 1;
+
+        do {    /* 31 cycles */
+                vis_ld64_2(ref, stride, TMP0);
+                vis_pmerge(ZERO,       REF_2,     TMP12);
+                vis_mul8x16au(REF_2_1, CONST_256, TMP14);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                vis_pmerge(ZERO,       REF_6,     TMP16);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP18);
+
+                vis_ld64_2(ref, stride_16, TMP4);
+                ref += stride;
+
+                vis_ld64(dest[0], DST_0);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(dest, 8, DST_2);
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                vis_ld64_2(ref, stride, TMP6);
+                vis_pmerge(ZERO,     REF_0,     TMP0);
+                vis_mul8x16au(REF_0_1, CONST_256, TMP2);
+
+                vis_ld64_2(ref, stride_8, TMP8);
+                vis_pmerge(ZERO,     REF_4,     TMP4);
+
+                vis_ld64_2(ref, stride_16, TMP10);
+                ref += stride;
+
+                vis_ld64_2(dest, stride, REF_S0/*DST_4*/);
+                vis_faligndata(TMP6, TMP8, REF_2);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP6);
+
+                vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/);
+                vis_faligndata(TMP8, TMP10, REF_6);
+                vis_mul8x16al(DST_0,   CONST_512, TMP20);
+
+                vis_padd16(TMP0, CONST_3, TMP0);
+                vis_mul8x16al(DST_1,   CONST_512, TMP22);
+
+                vis_padd16(TMP2, CONST_3, TMP2);
+                vis_mul8x16al(DST_2,   CONST_512, TMP24);
+
+                vis_padd16(TMP4, CONST_3, TMP4);
+                vis_mul8x16al(DST_3,   CONST_512, TMP26);
+
+                vis_padd16(TMP6, CONST_3, TMP6);
+
+                vis_padd16(TMP12, TMP20, TMP12);
+                vis_mul8x16al(REF_S0,   CONST_512, TMP20);
+
+                vis_padd16(TMP14, TMP22, TMP14);
+                vis_mul8x16al(REF_S0_1, CONST_512, TMP22);
+
+                vis_padd16(TMP16, TMP24, TMP16);
+                vis_mul8x16al(REF_S2,   CONST_512, TMP24);
+
+                vis_padd16(TMP18, TMP26, TMP18);
+                vis_mul8x16al(REF_S2_1, CONST_512, TMP26);
+
+                vis_padd16(TMP12, TMP0, TMP12);
+                vis_mul8x16au(REF_2,   CONST_256, TMP28);
+
+                vis_padd16(TMP14, TMP2, TMP14);
+                vis_mul8x16au(REF_2_1, CONST_256, TMP30);
+
+                vis_padd16(TMP16, TMP4, TMP16);
+                vis_mul8x16au(REF_6,   CONST_256, REF_S4);
+
+                vis_padd16(TMP18, TMP6, TMP18);
+                vis_mul8x16au(REF_6_1, CONST_256, REF_S6);
+
+                vis_pack16(TMP12, DST_0);
+                vis_padd16(TMP28, TMP0, TMP12);
+
+                vis_pack16(TMP14, DST_1);
+                vis_st64(DST_0, dest[0]);
+                vis_padd16(TMP30, TMP2, TMP14);
+
+                vis_pack16(TMP16, DST_2);
+                vis_padd16(REF_S4, TMP4, TMP16);
+
+                vis_pack16(TMP18, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+                vis_padd16(REF_S6, TMP6, TMP18);
+
+                vis_padd16(TMP12, TMP20, TMP12);
+
+                vis_padd16(TMP14, TMP22, TMP14);
+                vis_pack16(TMP12, DST_0);
+
+                vis_padd16(TMP16, TMP24, TMP16);
+                vis_pack16(TMP14, DST_1);
+                vis_st64(DST_0, dest[0]);
+
+                vis_padd16(TMP18, TMP26, TMP18);
+                vis_pack16(TMP16, DST_2);
+
+                vis_pack16(TMP18, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_put_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
+                                       const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+        int stride_8 = stride + 8;
+        int stride_16 = stride + 16;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(ref[16], TMP4);
+
+        vis_ld64(constants1[0], CONST_1);
+        vis_faligndata(TMP0, TMP2, REF_S0);
+
+        vis_ld64(constants256_512[0], CONST_256);
+        vis_faligndata(TMP2, TMP4, REF_S4);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_S2);
+                vis_faligndata(TMP2, TMP4, REF_S6);
+        } else {
+                vis_src1(TMP2, REF_S2);
+                vis_src1(TMP4, REF_S6);
+        }
+
+        height >>= 1;
+        do {
+                vis_ld64_2(ref, stride, TMP0);
+                vis_mul8x16au(REF_S0, CONST_256, TMP12);
+                vis_pmerge(ZERO,      REF_S0_1,  TMP14);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                vis_mul8x16au(REF_S2, CONST_256, TMP16);
+                vis_pmerge(ZERO,      REF_S2_1,  TMP18);
+
+                vis_ld64_2(ref, stride_16, TMP4);
+                ref += stride;
+                vis_mul8x16au(REF_S4, CONST_256, TMP20);
+                vis_pmerge(ZERO,      REF_S4_1,  TMP22);
+
+                vis_ld64_2(ref, stride, TMP6);
+                vis_mul8x16au(REF_S6, CONST_256, TMP24);
+                vis_pmerge(ZERO,      REF_S6_1,  TMP26);
+
+                vis_ld64_2(ref, stride_8, TMP8);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, stride_16, TMP10);
+                ref += stride;
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                vis_faligndata(TMP6, TMP8, REF_S0);
+
+                vis_faligndata(TMP8, TMP10, REF_S4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                        vis_faligndata(TMP2, TMP4, REF_6);
+                        vis_faligndata(TMP6, TMP8, REF_S2);
+                        vis_faligndata(TMP8, TMP10, REF_S6);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                        vis_src1(TMP4, REF_6);
+                        vis_src1(TMP8, REF_S2);
+                        vis_src1(TMP10, REF_S6);
+                }
+
+                vis_mul8x16au(REF_0, CONST_256, TMP0);
+                vis_pmerge(ZERO,      REF_0_1,  TMP2);
+
+                vis_mul8x16au(REF_2, CONST_256, TMP4);
+                vis_pmerge(ZERO,      REF_2_1,  TMP6);
+
+                vis_padd16(TMP0, CONST_2, TMP8);
+                vis_mul8x16au(REF_4, CONST_256, TMP0);
+
+                vis_padd16(TMP2, CONST_1, TMP10);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP2);
+
+                vis_padd16(TMP8, TMP4, TMP8);
+                vis_mul8x16au(REF_6, CONST_256, TMP4);
+
+                vis_padd16(TMP10, TMP6, TMP10);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP6);
+
+                vis_padd16(TMP12, TMP8, TMP12);
+
+                vis_padd16(TMP14, TMP10, TMP14);
+
+                vis_padd16(TMP12, TMP16, TMP12);
+
+                vis_padd16(TMP14, TMP18, TMP14);
+                vis_pack16(TMP12, DST_0);
+
+                vis_pack16(TMP14, DST_1);
+                vis_st64(DST_0, dest[0]);
+                vis_padd16(TMP0, CONST_1, TMP12);
+
+                vis_mul8x16au(REF_S0, CONST_256, TMP0);
+                vis_padd16(TMP2, CONST_1, TMP14);
+
+                vis_mul8x16au(REF_S0_1, CONST_256, TMP2);
+                vis_padd16(TMP12, TMP4, TMP12);
+
+                vis_mul8x16au(REF_S2, CONST_256, TMP4);
+                vis_padd16(TMP14, TMP6, TMP14);
+
+                vis_mul8x16au(REF_S2_1, CONST_256, TMP6);
+                vis_padd16(TMP20, TMP12, TMP20);
+
+                vis_padd16(TMP22, TMP14, TMP22);
+
+                vis_padd16(TMP20, TMP24, TMP20);
+
+                vis_padd16(TMP22, TMP26, TMP22);
+                vis_pack16(TMP20, DST_2);
+
+                vis_pack16(TMP22, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+                vis_padd16(TMP0, TMP4, TMP24);
+
+                vis_mul8x16au(REF_S4, CONST_256, TMP0);
+                vis_padd16(TMP2, TMP6, TMP26);
+
+                vis_mul8x16au(REF_S4_1, CONST_256, TMP2);
+                vis_padd16(TMP24, TMP8, TMP24);
+
+                vis_padd16(TMP26, TMP10, TMP26);
+                vis_pack16(TMP24, DST_0);
+
+                vis_pack16(TMP26, DST_1);
+                vis_st64(DST_0, dest[0]);
+                vis_pmerge(ZERO, REF_S6, TMP4);
+
+                vis_pmerge(ZERO,      REF_S6_1,  TMP6);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+
+                vis_padd16(TMP0, TMP12, TMP0);
+
+                vis_padd16(TMP2, TMP14, TMP2);
+                vis_pack16(TMP0, DST_2);
+
+                vis_pack16(TMP2, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_put_no_round_xy_8_vis (uint8_t * dest, const uint8_t * ref,
+                                      const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+        int stride_8 = stride + 8;
+
+        vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(constants1[0], CONST_1);
+
+        vis_ld64(constants256_512[0], CONST_256);
+        vis_faligndata(TMP0, TMP2, REF_S0);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_S2);
+        } else {
+                vis_src1(TMP2, REF_S2);
+        }
+
+        height >>= 1;
+        do {    /* 26 cycles */
+                vis_ld64_2(ref, stride, TMP0);
+                vis_mul8x16au(REF_S0,   CONST_256, TMP8);
+                vis_pmerge(ZERO,        REF_S2,    TMP12);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                ref += stride;
+                vis_mul8x16au(REF_S0_1, CONST_256, TMP10);
+                vis_pmerge(ZERO,        REF_S2_1,  TMP14);
+
+                vis_ld64_2(ref, stride, TMP4);
+
+                vis_ld64_2(ref, stride_8, TMP6);
+                ref += stride;
+                vis_faligndata(TMP0, TMP2, REF_S4);
+
+                vis_pmerge(ZERO, REF_S4, TMP18);
+
+                vis_pmerge(ZERO, REF_S4_1, TMP20);
+
+                vis_faligndata(TMP4, TMP6, REF_S0);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_S6);
+                        vis_faligndata(TMP4, TMP6, REF_S2);
+                } else {
+                        vis_src1(TMP2, REF_S6);
+                        vis_src1(TMP6, REF_S2);
+                }
+
+                vis_padd16(TMP18, CONST_1, TMP18);
+                vis_mul8x16au(REF_S6,   CONST_256, TMP22);
+
+                vis_padd16(TMP20, CONST_1, TMP20);
+                vis_mul8x16au(REF_S6_1, CONST_256, TMP24);
+
+                vis_mul8x16au(REF_S0,   CONST_256, TMP26);
+                vis_pmerge(ZERO, REF_S0_1, TMP28);
+
+                vis_mul8x16au(REF_S2,   CONST_256, TMP30);
+                vis_padd16(TMP18, TMP22, TMP18);
+
+                vis_mul8x16au(REF_S2_1, CONST_256, TMP32);
+                vis_padd16(TMP20, TMP24, TMP20);
+
+                vis_padd16(TMP8,  TMP18, TMP8);
+
+                vis_padd16(TMP10, TMP20, TMP10);
+
+                vis_padd16(TMP8,  TMP12, TMP8);
+
+                vis_padd16(TMP10, TMP14, TMP10);
+                vis_pack16(TMP8,  DST_0);
+
+                vis_pack16(TMP10, DST_1);
+                vis_st64(DST_0, dest[0]);
+                dest += stride;
+                vis_padd16(TMP18, TMP26, TMP18);
+
+                vis_padd16(TMP20, TMP28, TMP20);
+
+                vis_padd16(TMP18, TMP30, TMP18);
+
+                vis_padd16(TMP20, TMP32, TMP20);
+                vis_pack16(TMP18, DST_2);
+
+                vis_pack16(TMP20, DST_3);
+                vis_st64(DST_2, dest[0]);
+                dest += stride;
+        } while (--height);
+}
+
+static void MC_avg_no_round_xy_16_vis (uint8_t * dest, const uint8_t * ref,
+                                       const ptrdiff_t stride, int height)
+{
+        unsigned long off = (unsigned long) ref & 0x7;
+        unsigned long off_plus_1 = off + 1;
+        int stride_8 = stride + 8;
+        int stride_16 = stride + 16;
+
+        vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT);
+
+        ref = vis_alignaddr(ref);
+
+        vis_ld64(ref[ 0], TMP0);
+        vis_fzero(ZERO);
+
+        vis_ld64(ref[ 8], TMP2);
+
+        vis_ld64(ref[16], TMP4);
+
+        vis_ld64(constants6[0], CONST_6);
+        vis_faligndata(TMP0, TMP2, REF_S0);
+
+        vis_ld64(constants256_1024[0], CONST_256);
+        vis_faligndata(TMP2, TMP4, REF_S4);
+
+        if (off != 0x7) {
+                vis_alignaddr_g0((void *)off_plus_1);
+                vis_faligndata(TMP0, TMP2, REF_S2);
+                vis_faligndata(TMP2, TMP4, REF_S6);
+        } else {
+                vis_src1(TMP2, REF_S2);
+                vis_src1(TMP4, REF_S6);
+        }
+
+        height >>= 1;
+        do {    /* 55 cycles */
+                vis_ld64_2(ref, stride, TMP0);
+                vis_mul8x16au(REF_S0, CONST_256, TMP12);
+                vis_pmerge(ZERO,      REF_S0_1,  TMP14);
+
+                vis_alignaddr_g0((void *)off);
+
+                vis_ld64_2(ref, stride_8, TMP2);
+                vis_mul8x16au(REF_S2, CONST_256, TMP16);
+                vis_pmerge(ZERO,      REF_S2_1,  TMP18);
+
+                vis_ld64_2(ref, stride_16, TMP4);
+                ref += stride;
+                vis_mul8x16au(REF_S4, CONST_256, TMP20);
+                vis_pmerge(ZERO,      REF_S4_1,  TMP22);
+
+                vis_ld64_2(ref, stride, TMP6);
+                vis_mul8x16au(REF_S6, CONST_256, TMP24);
+                vis_pmerge(ZERO,      REF_S6_1,  TMP26);
+
+                vis_ld64_2(ref, stride_8, TMP8);
+                vis_faligndata(TMP0, TMP2, REF_0);
+
+                vis_ld64_2(ref, stride_16, TMP10);
+                ref += stride;
+                vis_faligndata(TMP2, TMP4, REF_4);
+
+                vis_ld64(dest[0], DST_0);
+                vis_faligndata(TMP6, TMP8, REF_S0);
+
+                vis_ld64_2(dest, 8, DST_2);
+                vis_faligndata(TMP8, TMP10, REF_S4);
+
+                if (off != 0x7) {
+                        vis_alignaddr_g0((void *)off_plus_1);
+                        vis_faligndata(TMP0, TMP2, REF_2);
+                        vis_faligndata(TMP2, TMP4, REF_6);
+                        vis_faligndata(TMP6, TMP8, REF_S2);
+                        vis_faligndata(TMP8, TMP10, REF_S6);
+                } else {
+                        vis_src1(TMP2, REF_2);
+                        vis_src1(TMP4, REF_6);
+                        vis_src1(TMP8, REF_S2);
+                        vis_src1(TMP10, REF_S6);
+                }
+
+                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
+                vis_pmerge(ZERO, REF_0, TMP0);
+
+                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
+                vis_pmerge(ZERO,      REF_0_1,  TMP2);
+
+                vis_mul8x16au(REF_2, CONST_256, TMP4);
+                vis_pmerge(ZERO,      REF_2_1,  TMP6);
+
+                vis_mul8x16al(DST_2,   CONST_1024, REF_0);
+                vis_padd16(TMP0, CONST_6, TMP0);
+
+                vis_mul8x16al(DST_3,   CONST_1024, REF_2);
+                vis_padd16(TMP2, CONST_6, TMP2);
+
+                vis_padd16(TMP0, TMP4, TMP0);
+                vis_mul8x16au(REF_4, CONST_256, TMP4);
+
+                vis_padd16(TMP2, TMP6, TMP2);
+                vis_mul8x16au(REF_4_1, CONST_256, TMP6);
+
+                vis_padd16(TMP12, TMP0, TMP12);
+                vis_mul8x16au(REF_6, CONST_256, TMP8);
+
+                vis_padd16(TMP14, TMP2, TMP14);
+                vis_mul8x16au(REF_6_1, CONST_256, TMP10);
+
+                vis_padd16(TMP12, TMP16, TMP12);
+                vis_mul8x16au(REF_S0, CONST_256, REF_4);
+
+                vis_padd16(TMP14, TMP18, TMP14);
+                vis_mul8x16au(REF_S0_1, CONST_256, REF_6);
+
+                vis_padd16(TMP12, TMP30, TMP12);
+
+                vis_padd16(TMP14, TMP32, TMP14);
+                vis_pack16(TMP12, DST_0);
+
+                vis_pack16(TMP14, DST_1);
+                vis_st64(DST_0, dest[0]);
+                vis_padd16(TMP4, CONST_6, TMP4);
+
+                vis_ld64_2(dest, stride, DST_0);
+                vis_padd16(TMP6, CONST_6, TMP6);
+                vis_mul8x16au(REF_S2, CONST_256, TMP12);
+
+                vis_padd16(TMP4, TMP8, TMP4);
+                vis_mul8x16au(REF_S2_1, CONST_256,  TMP14);
+
+                vis_padd16(TMP6, TMP10, TMP6);
+
+                vis_padd16(TMP20, TMP4, TMP20);
+
+                vis_padd16(TMP22, TMP6, TMP22);
+
+                vis_padd16(TMP20, TMP24, TMP20);
+
+                vis_padd16(TMP22, TMP26, TMP22);
+
+                vis_padd16(TMP20, REF_0, TMP20);
+                vis_mul8x16au(REF_S4, CONST_256, REF_0);
+
+                vis_padd16(TMP22, REF_2, TMP22);
+                vis_pack16(TMP20, DST_2);
+
+                vis_pack16(TMP22, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+
+                vis_ld64_2(dest, 8, DST_2);
+                vis_mul8x16al(DST_0,   CONST_1024, TMP30);
+                vis_pmerge(ZERO,      REF_S4_1,  REF_2);
+
+                vis_mul8x16al(DST_1,   CONST_1024, TMP32);
+                vis_padd16(REF_4, TMP0, TMP8);
+
+                vis_mul8x16au(REF_S6, CONST_256, REF_4);
+                vis_padd16(REF_6, TMP2, TMP10);
+
+                vis_mul8x16au(REF_S6_1, CONST_256, REF_6);
+                vis_padd16(TMP8, TMP12, TMP8);
+
+                vis_padd16(TMP10, TMP14, TMP10);
+
+                vis_padd16(TMP8, TMP30, TMP8);
+
+                vis_padd16(TMP10, TMP32, TMP10);
+                vis_pack16(TMP8, DST_0);
+
+                vis_pack16(TMP10, DST_1);
+                vis_st64(DST_0, dest[0]);
+
+                vis_padd16(REF_0, TMP4, REF_0);
+
+                vis_mul8x16al(DST_2,   CONST_1024, TMP30);
+                vis_padd16(REF_2, TMP6, REF_2);
+
+                vis_mul8x16al(DST_3,   CONST_1024, TMP32);
+                vis_padd16(REF_0, REF_4, REF_0);
+
+                vis_padd16(REF_2, REF_6, REF_2);
+
+                vis_padd16(REF_0, TMP30, REF_0);
+
+                /* stall */
+
+                vis_padd16(REF_2, TMP32, REF_2);
+                vis_pack16(REF_0, DST_2);
+
+                vis_pack16(REF_2, DST_3);
+                vis_st64_2(DST_2, dest, 8);
+                dest += stride;
+        } while (--height);
+}
+
+/* End of no rounding code */
+
+av_cold void ff_hpeldsp_init_vis(HpelDSPContext *c, int flags)
+{
+  /* VIS-specific optimizations */
+  int accel = vis_level ();
+
+  if (accel & ACCEL_SPARC_VIS) {
+      c->put_pixels_tab[0][0] = MC_put_o_16_vis;
+      c->put_pixels_tab[0][1] = MC_put_x_16_vis;
+      c->put_pixels_tab[0][2] = MC_put_y_16_vis;
+      c->put_pixels_tab[0][3] = MC_put_xy_16_vis;
+
+      c->put_pixels_tab[1][0] = MC_put_o_8_vis;
+      c->put_pixels_tab[1][1] = MC_put_x_8_vis;
+      c->put_pixels_tab[1][2] = MC_put_y_8_vis;
+      c->put_pixels_tab[1][3] = MC_put_xy_8_vis;
+
+      c->avg_pixels_tab[0][0] = MC_avg_o_16_vis;
+      c->avg_pixels_tab[0][1] = MC_avg_x_16_vis;
+      c->avg_pixels_tab[0][2] = MC_avg_y_16_vis;
+      c->avg_pixels_tab[0][3] = MC_avg_xy_16_vis;
+
+      c->avg_pixels_tab[1][0] = MC_avg_o_8_vis;
+      c->avg_pixels_tab[1][1] = MC_avg_x_8_vis;
+      c->avg_pixels_tab[1][2] = MC_avg_y_8_vis;
+      c->avg_pixels_tab[1][3] = MC_avg_xy_8_vis;
+
+      c->put_no_rnd_pixels_tab[0][0] = MC_put_no_round_o_16_vis;
+      c->put_no_rnd_pixels_tab[0][1] = MC_put_no_round_x_16_vis;
+      c->put_no_rnd_pixels_tab[0][2] = MC_put_no_round_y_16_vis;
+      c->put_no_rnd_pixels_tab[0][3] = MC_put_no_round_xy_16_vis;
+
+      c->put_no_rnd_pixels_tab[1][0] = MC_put_no_round_o_8_vis;
+      c->put_no_rnd_pixels_tab[1][1] = MC_put_no_round_x_8_vis;
+      c->put_no_rnd_pixels_tab[1][2] = MC_put_no_round_y_8_vis;
+      c->put_no_rnd_pixels_tab[1][3] = MC_put_no_round_xy_8_vis;
+
+      c->avg_no_rnd_pixels_tab[0] = MC_avg_no_round_o_16_vis;
+      c->avg_no_rnd_pixels_tab[1] = MC_avg_no_round_x_16_vis;
+      c->avg_no_rnd_pixels_tab[2] = MC_avg_no_round_y_16_vis;
+      c->avg_no_rnd_pixels_tab[3] = MC_avg_no_round_xy_16_vis;
+  }
+}
diff --git a/libavcodec/sparc/simple_idct_vis.c b/libavcodec/sparc/simple_idct_vis.c
index 43a898a..2057d66 100644
--- a/libavcodec/sparc/simple_idct_vis.c
+++ b/libavcodec/sparc/simple_idct_vis.c
@@ -24,7 +24,6 @@
 
 #include <stdint.h>
 
-#include "libavcodec/dsputil.h"
 #include "dsputil_vis.h"
 #include "libavutil/mem.h"
 
@@ -388,7 +387,7 @@ static const DECLARE_ALIGNED(8, uint16_t, expand)[4] = {
         "st %%f14, [%12+" dest "] \n\t"\
 
 
-void ff_simple_idct_vis(DCTELEM *data) {
+void ff_simple_idct_vis(int16_t *data) {
     int out1, out2, out3, out4;
     DECLARE_ALIGNED(8, int16_t, temp)[8*8];
 
@@ -428,7 +427,7 @@ void ff_simple_idct_vis(DCTELEM *data) {
     );
 }
 
-void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data) {
+void ff_simple_idct_put_vis(uint8_t *dest, int line_size, int16_t *data) {
     int out1, out2, out3, out4, out5;
     int r1, r2, r3, r4, r5, r6, r7;
 
@@ -478,7 +477,7 @@ void ff_simple_idct_put_vis(uint8_t *dest, int line_size, DCTELEM *data) {
     );
 }
 
-void ff_simple_idct_add_vis(uint8_t *dest, int line_size, DCTELEM *data) {
+void ff_simple_idct_add_vis(uint8_t *dest, int line_size, int16_t *data) {
     int out1, out2, out3, out4, out5, out6;
     int r1, r2, r3, r4, r5, r6, r7;
 
diff --git a/libavcodec/sparc/vis.h b/libavcodec/sparc/vis.h
index 505c735..ff2fb9d 100644
--- a/libavcodec/sparc/vis.h
+++ b/libavcodec/sparc/vis.h
@@ -42,6 +42,17 @@
 #ifndef AVCODEC_SPARC_VIS_H
 #define AVCODEC_SPARC_VIS_H
 
+#define ACCEL_SPARC_VIS 1
+#define ACCEL_SPARC_VIS2 2
+
+static inline int vis_level(void)
+{
+    int accel = 0;
+    accel |= ACCEL_SPARC_VIS;
+    accel |= ACCEL_SPARC_VIS2;
+    return accel;
+}
+
 #define vis_opc_base    ((0x1 << 31) | (0x36 << 19))
 #define vis_opf(X)      ((X) << 5)
 #define vis_sreg(X)     (X)
@@ -139,12 +150,9 @@
 #define vis_m2r_2(op,mem1,mem2,rd) \
         __asm__ volatile (#op "\t[%0 + %1], %%f" #rd : : "r" (mem1), "r" (mem2) )
 
-static inline void vis_set_gsr(unsigned int _val)
+static inline void vis_set_gsr(unsigned int val)
 {
-        register unsigned int val __asm__("g1");
-
-        val = _val;
-        __asm__ volatile(".word 0xa7804000"
+        __asm__ volatile("mov %0,%%asr19"
                              : : "r" (val));
 }
 
@@ -162,32 +170,6 @@ static inline void vis_set_gsr(unsigned int _val)
 #define vis_st64(rs1,mem)               vis_r2m(std, rs1, mem)
 #define vis_st64_2(rs1,mem1,mem2)       vis_r2m_2(std, rs1, mem1, mem2)
 
-#define vis_ldblk(mem, rd) \
-do {        register void *__mem __asm__("g1"); \
-        __mem = &(mem); \
-        __asm__ volatile(".word 0xc1985e00 | %1" \
-                             : \
-                             : "r" (__mem), \
-                               "i" (vis_rd_d(rd)) \
-                             : "memory"); \
-} while (0)
-
-#define vis_stblk(rd, mem) \
-do {        register void *__mem __asm__("g1"); \
-        __mem = &(mem); \
-        __asm__ volatile(".word 0xc1b85e00 | %1" \
-                             : \
-                             : "r" (__mem), \
-                               "i" (vis_rd_d(rd)) \
-                             : "memory"); \
-} while (0)
-
-#define vis_membar_storestore()        \
-        __asm__ volatile(".word 0x8143e008" : : : "memory")
-
-#define vis_membar_sync()        \
-        __asm__ volatile(".word 0x8143e040" : : : "memory")
-
 /* 16 and 32 bit partitioned addition and subtraction.  The normal
  * versions perform 4 16-bit or 2 32-bit additions or subtractions.
  * The 's' versions perform 2 16-bit or 1 32-bit additions or
@@ -223,68 +205,19 @@ do {        register void *__mem __asm__("g1"); \
 
 /* Alignment instructions.  */
 
-static inline const void *vis_alignaddr(const void *_ptr)
+static inline const void *vis_alignaddr(const void *ptr)
 {
-        register const void *ptr __asm__("g1");
-
-        ptr = _ptr;
-
-        __asm__ volatile(".word %2"
+        __asm__ volatile("alignaddr %0, %%g0, %0"
                              : "=&r" (ptr)
-                             : "0" (ptr),
-                               "i" (vis_opc_base | vis_opf(0x18) |
-                                    vis_rs1_s(1) |
-                                    vis_rs2_s(0) |
-                                    vis_rd_s(1)));
+                             : "0" (ptr));
 
         return ptr;
 }
 
-static inline void vis_alignaddr_g0(void *_ptr)
+static inline void vis_alignaddr_g0(void *ptr)
 {
-        register void *ptr __asm__("g1");
-
-        ptr = _ptr;
-
-        __asm__ volatile(".word %2"
-                             : "=&r" (ptr)
-                             : "0" (ptr),
-                               "i" (vis_opc_base | vis_opf(0x18) |
-                                    vis_rs1_s(1) |
-                                    vis_rs2_s(0) |
-                                    vis_rd_s(0)));
-}
-
-static inline void *vis_alignaddrl(void *_ptr)
-{
-        register void *ptr __asm__("g1");
-
-        ptr = _ptr;
-
-        __asm__ volatile(".word %2"
-                             : "=&r" (ptr)
-                             : "0" (ptr),
-                               "i" (vis_opc_base | vis_opf(0x19) |
-                                    vis_rs1_s(1) |
-                                    vis_rs2_s(0) |
-                                    vis_rd_s(1)));
-
-        return ptr;
-}
-
-static inline void vis_alignaddrl_g0(void *_ptr)
-{
-        register void *ptr __asm__("g1");
-
-        ptr = _ptr;
-
-        __asm__ volatile(".word %2"
-                             : "=&r" (ptr)
-                             : "0" (ptr),
-                               "i" (vis_opc_base | vis_opf(0x19) |
-                                    vis_rs1_s(1) |
-                                    vis_rs2_s(0) |
-                                    vis_rd_s(0)));
+        __asm__ volatile("alignaddr %0, %%g0, %%g0"
+                             : : "r" (ptr));
 }
 
 #define vis_faligndata(rs1,rs2,rd)        vis_dd2d(0x48, rs1, rs2, rd)
diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c
index a44cdf0..ffa685c 100644
--- a/libavcodec/sunrast.c
+++ b/libavcodec/sunrast.c
@@ -26,27 +26,12 @@
 #include "internal.h"
 #include "sunrast.h"
 
-typedef struct SUNRASTContext {
-    AVFrame picture;
-} SUNRASTContext;
-
-static av_cold int sunrast_init(AVCodecContext *avctx) {
-    SUNRASTContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
 static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf       = avpkt->data;
     const uint8_t *buf_end   = avpkt->data + avpkt->size;
-    SUNRASTContext * const s = avctx->priv_data;
-    AVFrame *picture         = data;
-    AVFrame * const p        = &s->picture;
+    AVFrame * const p        = data;
     unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen;
     uint8_t *ptr;
     const uint8_t *bufstart = buf;
@@ -69,19 +54,15 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
     buf      += 32;
 
     if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF || type == RT_EXPERIMENTAL) {
-        av_log_ask_for_sample(avctx, "unsupported (compression) type\n");
+        avpriv_request_sample(avctx, "TIFF/IFF/EXPERIMENTAL (compression) type");
         return AVERROR_PATCHWELCOME;
     }
     if (type > RT_FORMAT_IFF) {
         av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n");
         return AVERROR_INVALIDDATA;
     }
-    if (av_image_check_size(w, h, 0, avctx)) {
-        av_log(avctx, AV_LOG_ERROR, "invalid image size\n");
-        return AVERROR_INVALIDDATA;
-    }
     if (maptype == RMT_RAW) {
-        av_log_ask_for_sample(avctx, "unsupported colormap type\n");
+        avpriv_request_sample(avctx, "Unknown colormap type");
         return AVERROR_PATCHWELCOME;
     }
     if (maptype > RMT_RAW) {
@@ -105,12 +86,11 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    ret = ff_set_dimensions(avctx, w, h);
+    if (ret < 0)
+        return ret;
 
-    if (w != avctx->width || h != avctx->height)
-        avcodec_set_dimensions(avctx, w, h);
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -181,29 +161,16 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return buf - bufstart;
 }
 
-static av_cold int sunrast_end(AVCodecContext *avctx) {
-    SUNRASTContext *s = avctx->priv_data;
-
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_sunrast_decoder = {
     .name           = "sunrast",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SUNRAST,
-    .priv_data_size = sizeof(SUNRASTContext),
-    .init           = sunrast_init,
-    .close          = sunrast_end,
     .decode         = sunrast_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"),
 };
diff --git a/libavcodec/sunrastenc.c b/libavcodec/sunrastenc.c
index e1b5211..25ae9bd 100644
--- a/libavcodec/sunrastenc.c
+++ b/libavcodec/sunrastenc.c
@@ -25,7 +25,6 @@
 #include "sunrast.h"
 
 typedef struct SUNRASTContext {
-    AVFrame picture;
     PutByteContext p;
     int depth;      ///< depth of pixel
     int length;     ///< length (bytes) of image
@@ -154,7 +153,10 @@ static av_cold int sunrast_encode_init(AVCodecContext *avctx)
         return AVERROR(EINVAL);
     }
 
-    avctx->coded_frame            = &s->picture;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
     avctx->coded_frame->key_frame = 1;
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     s->maptype                    = RMT_NONE;
@@ -207,6 +209,12 @@ static int sunrast_encode_frame(AVCodecContext *avctx,  AVPacket *avpkt,
     return 0;
 }
 
+static av_cold int sunrast_encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
 static const AVCodecDefault sunrast_defaults[] = {
      { "coder", "rle" },
      { NULL },
@@ -214,10 +222,12 @@ static const AVCodecDefault sunrast_defaults[] = {
 
 AVCodec ff_sunrast_encoder = {
     .name           = "sunrast",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SUNRAST,
     .priv_data_size = sizeof(SUNRASTContext),
     .init           = sunrast_encode_init,
+    .close          = sunrast_encode_close,
     .encode2        = sunrast_encode_frame,
     .defaults       = sunrast_defaults,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24,
@@ -225,5 +235,4 @@ AVCodec ff_sunrast_encoder = {
                                                   AV_PIX_FMT_GRAY8,
                                                   AV_PIX_FMT_MONOWHITE,
                                                   AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"),
 };
diff --git a/libavcodec/svq1.c b/libavcodec/svq1.c
index e20fa43..545df80 100644
--- a/libavcodec/svq1.c
+++ b/libavcodec/svq1.c
@@ -37,7 +37,7 @@
 #include "svq1_vlc.h"
 
 /* standard video sizes */
-const struct svq1_frame_size ff_svq1_frame_size_table[7] = {
+const uint16_t ff_svq1_frame_size_table[7][2] = {
     { 160, 120 }, { 128,  96 }, { 176, 144 }, { 352, 288 },
     { 704, 576 }, { 240, 180 }, { 320, 240 }
 };
diff --git a/libavcodec/svq1.h b/libavcodec/svq1.h
index b2055fa..70b5c37 100644
--- a/libavcodec/svq1.h
+++ b/libavcodec/svq1.h
@@ -42,11 +42,6 @@
 #define SVQ1_BLOCK_INTER_4V     2
 #define SVQ1_BLOCK_INTRA        3
 
-struct svq1_frame_size {
-    uint16_t width;
-    uint16_t height;
-};
-
 uint16_t ff_svq1_packet_checksum(const uint8_t *data,
                                  const int length, int value);
 
@@ -59,6 +54,6 @@ extern const uint8_t ff_svq1_inter_multistage_vlc[6][8][2];
 extern const uint16_t ff_svq1_intra_mean_vlc[256][2];
 extern const uint16_t ff_svq1_inter_mean_vlc[512][2];
 
-extern const struct svq1_frame_size ff_svq1_frame_size_table[7];
+extern const uint16_t ff_svq1_frame_size_table[7][2];
 
 #endif /* AVCODEC_SVQ1_H */
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 82f9301..000487b 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -33,8 +33,9 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
+#include "h263.h"
+#include "hpeldsp.h"
 #include "internal.h"
 #include "mathops.h"
 #include "svq1.h"
@@ -42,8 +43,6 @@
 #undef NDEBUG
 #include <assert.h>
 
-extern const uint8_t ff_mvtab[33][2];
-
 static VLC svq1_block_type;
 static VLC svq1_motion_component;
 static VLC svq1_intra_multistage[6];
@@ -58,9 +57,9 @@ typedef struct svq1_pmv_s {
 } svq1_pmv;
 
 typedef struct SVQ1Context {
-    DSPContext dsp;
+    HpelDSPContext hdsp;
     GetBitContext gb;
-    AVFrame *cur, *prev;
+    AVFrame *prev;
     int width;
     int height;
     int frame_code;
@@ -320,7 +319,7 @@ static void svq1_skip_block(uint8_t *current, uint8_t *previous,
     }
 }
 
-static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
+static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf,
                                    uint8_t *current, uint8_t *previous,
                                    int pitch, svq1_pmv *motion, int x, int y,
                                    int width, int height)
@@ -359,12 +358,12 @@ static int svq1_motion_inter_block(DSPContext *dsp, GetBitContext *bitbuf,
     src = &previous[(x + (mv.x >> 1)) + (y + (mv.y >> 1)) * pitch];
     dst = current;
 
-    dsp->put_pixels_tab[0][(mv.y & 1) << 1 | (mv.x & 1)](dst, src, pitch, 16);
+    hdsp->put_pixels_tab[0][(mv.y & 1) << 1 | (mv.x & 1)](dst, src, pitch, 16);
 
     return 0;
 }
 
-static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
+static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbuf,
                                       uint8_t *current, uint8_t *previous,
                                       int pitch, svq1_pmv *motion, int x, int y,
                                       int width, int height)
@@ -433,7 +432,7 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
         src = &previous[(x + (mvx >> 1)) + (y + (mvy >> 1)) * pitch];
         dst = current;
 
-        dsp->put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst, src, pitch, 8);
+        hdsp->put_pixels_tab[1][((mvy & 1) << 1) | (mvx & 1)](dst, src, pitch, 8);
 
         /* select next block */
         if (i & 1)
@@ -445,7 +444,7 @@ static int svq1_motion_inter_4v_block(DSPContext *dsp, GetBitContext *bitbuf,
     return 0;
 }
 
-static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
+static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp,
                                    GetBitContext *bitbuf,
                                    uint8_t *current, uint8_t *previous,
                                    int pitch, svq1_pmv *motion, int x, int y,
@@ -473,7 +472,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
         break;
 
     case SVQ1_BLOCK_INTER:
-        result = svq1_motion_inter_block(dsp, bitbuf, current, previous,
+        result = svq1_motion_inter_block(hdsp, bitbuf, current, previous,
                                          pitch, motion, x, y, width, height);
 
         if (result != 0) {
@@ -484,7 +483,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, DSPContext *dsp,
         break;
 
     case SVQ1_BLOCK_INTER_4V:
-        result = svq1_motion_inter_4v_block(dsp, bitbuf, current, previous,
+        result = svq1_motion_inter_4v_block(hdsp, bitbuf, current, previous,
                                             pitch, motion, x, y, width, height);
 
         if (result != 0) {
@@ -578,8 +577,8 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame)
                 return AVERROR_INVALIDDATA;
         } else {
             /* get width, height from table */
-            s->width  = ff_svq1_frame_size_table[frame_size_code].width;
-            s->height = ff_svq1_frame_size_table[frame_size_code].height;
+            s->width  = ff_svq1_frame_size_table[frame_size_code][0];
+            s->height = ff_svq1_frame_size_table[frame_size_code][1];
         }
     }
 
@@ -611,14 +610,11 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     SVQ1Context     *s = avctx->priv_data;
-    AVFrame       *cur = s->cur;
+    AVFrame       *cur = data;
     uint8_t *current;
     int result, i, x, y, width, height;
     svq1_pmv *pmv;
 
-    if (cur->data[0])
-        avctx->release_buffer(avctx, cur);
-
     /* initialize bit buffer */
     init_get_bits(&s->gb, buf, buf_size * 8);
 
@@ -642,7 +638,10 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         av_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result);
         return result;
     }
-    avcodec_set_dimensions(avctx, s->width, s->height);
+
+    result = ff_set_dimensions(avctx, s->width, s->height);
+    if (result < 0)
+        return result;
 
     if ((avctx->skip_frame >= AVDISCARD_NONREF && s->nonref) ||
         (avctx->skip_frame >= AVDISCARD_NONKEY &&
@@ -650,7 +649,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         avctx->skip_frame >= AVDISCARD_ALL)
         return buf_size;
 
-    result = ff_get_buffer(avctx, cur);
+    result = ff_get_buffer(avctx, cur, s->nonref ? 0 : AV_GET_BUFFER_FLAG_REF);
     if (result < 0)
         return result;
 
@@ -702,7 +701,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
 
             for (y = 0; y < height; y += 16) {
                 for (x = 0; x < width; x += 16) {
-                    result = svq1_decode_delta_block(avctx, &s->dsp,
+                    result = svq1_decode_delta_block(avctx, &s->hdsp,
                                                      &s->gb, &current[x],
                                                      previous, linesize,
                                                      pmv, x, y, width, height);
@@ -722,9 +721,12 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *(AVFrame*)data = *cur;
-    if (!s->nonref)
-        FFSWAP(AVFrame*, s->cur, s->prev);
+    if (!s->nonref) {
+        av_frame_unref(s->prev);
+        result = av_frame_ref(s->prev, cur);
+        if (result < 0)
+            goto err;
+    }
 
     *got_frame = 1;
     result     = buf_size;
@@ -740,19 +742,15 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx)
     int i;
     int offset = 0;
 
-    s->cur  = avcodec_alloc_frame();
-    s->prev = avcodec_alloc_frame();
-    if (!s->cur || !s->prev) {
-        avcodec_free_frame(&s->cur);
-        avcodec_free_frame(&s->prev);
+    s->prev = av_frame_alloc();
+    if (!s->prev)
         return AVERROR(ENOMEM);
-    }
 
     s->width            = avctx->width  + 3 & ~3;
     s->height           = avctx->height + 3 & ~3;
     avctx->pix_fmt      = AV_PIX_FMT_YUV410P;
 
-    ff_dsputil_init(&s->dsp, avctx);
+    ff_hpeldsp_init(&s->hdsp, avctx->flags);
 
     INIT_VLC_STATIC(&svq1_block_type, 2, 4,
                     &ff_svq1_block_type_vlc[0][1], 2, 1,
@@ -797,12 +795,7 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx)
 {
     SVQ1Context *s = avctx->priv_data;
 
-    if (s->cur->data[0])
-        avctx->release_buffer(avctx, s->cur);
-    if (s->prev->data[0])
-        avctx->release_buffer(avctx, s->prev);
-    avcodec_free_frame(&s->cur);
-    avcodec_free_frame(&s->prev);
+    av_frame_free(&s->prev);
 
     return 0;
 }
@@ -811,14 +804,12 @@ static void svq1_flush(AVCodecContext *avctx)
 {
     SVQ1Context *s = avctx->priv_data;
 
-    if (s->cur->data[0])
-        avctx->release_buffer(avctx, s->cur);
-    if (s->prev->data[0])
-        avctx->release_buffer(avctx, s->prev);
+    av_frame_unref(s->prev);
 }
 
 AVCodec ff_svq1_decoder = {
     .name           = "svq1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SVQ1,
     .priv_data_size = sizeof(SVQ1Context),
@@ -829,5 +820,4 @@ AVCodec ff_svq1_decoder = {
     .flush          = svq1_flush,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
                                                      AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
 };
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 21531f6..3cd3a4a 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -28,6 +28,7 @@
 
 #include "avcodec.h"
 #include "dsputil.h"
+#include "hpeldsp.h"
 #include "mpegvideo.h"
 #include "h263.h"
 #include "internal.h"
@@ -44,9 +45,9 @@ typedef struct SVQ1Context {
     MpegEncContext m;
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame picture;
-    AVFrame current_picture;
-    AVFrame last_picture;
+    HpelDSPContext hdsp;
+    AVFrame *current_picture;
+    AVFrame *last_picture;
     PutBitContext pb;
     GetBitContext gb;
 
@@ -263,13 +264,14 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
                              unsigned char *decoded_plane,
                              int width, int height, int src_stride, int stride)
 {
+    const AVFrame *f = s->avctx->coded_frame;
     int x, y;
     int i;
     int block_width, block_height;
     int level;
     int threshold[6];
     uint8_t *src     = s->scratchbuf + stride * 16;
-    const int lambda = (s->picture.quality * s->picture.quality) >>
+    const int lambda = (f->quality * f->quality) >>
                        (2 * FF_LAMBDA_SHIFT);
 
     /* figure out the acceptable level thresholds in advance */
@@ -280,7 +282,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
     block_width  = (width  + 15) / 16;
     block_height = (height + 15) / 16;
 
-    if (s->picture.pict_type == AV_PICTURE_TYPE_P) {
+    if (f->pict_type == AV_PICTURE_TYPE_P) {
         s->m.avctx                         = s->avctx;
         s->m.current_picture_ptr           = &s->m.current_picture;
         s->m.last_picture_ptr              = &s->m.last_picture;
@@ -296,13 +298,13 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
         s->m.mb_stride                     = s->m.mb_width + 1;
         s->m.b8_stride                     = 2 * s->m.mb_width + 1;
         s->m.f_code                        = 1;
-        s->m.pict_type                     = s->picture.pict_type;
+        s->m.pict_type                     = f->pict_type;
         s->m.me_method                     = s->avctx->me_method;
         s->m.me.scene_change_score         = 0;
         s->m.flags                         = s->avctx->flags;
         // s->m.out_format                    = FMT_H263;
         // s->m.unrestricted_mv               = 1;
-        s->m.lambda                        = s->picture.quality;
+        s->m.lambda                        = f->quality;
         s->m.qscale                        = s->m.lambda * 139 +
                                              FF_LAMBDA_SCALE * 64 >>
                                              FF_LAMBDA_SHIFT + 7;
@@ -325,9 +327,9 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
         s->m.current_picture.mb_mean   = (uint8_t *)s->dummy;
         s->m.current_picture.mb_var    = (uint16_t *)s->dummy;
         s->m.current_picture.mc_mb_var = (uint16_t *)s->dummy;
-        s->m.current_picture.f.mb_type = s->dummy;
+        s->m.current_picture.mb_type = s->dummy;
 
-        s->m.current_picture.f.motion_val[0] = s->motion_val8[plane] + 2;
+        s->m.current_picture.motion_val[0]   = s->motion_val8[plane] + 2;
         s->m.p_mv_table                      = s->motion_val16[plane] +
                                                s->m.mb_stride + 1;
         s->m.dsp                             = s->dsp; // move
@@ -395,13 +397,13 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
             ff_init_block_index(&s->m);
             ff_update_block_index(&s->m);
 
-            if (s->picture.pict_type == AV_PICTURE_TYPE_I ||
+            if (f->pict_type == AV_PICTURE_TYPE_I ||
                 (s->m.mb_type[x + y * s->m.mb_stride] &
                  CANDIDATE_MB_TYPE_INTRA)) {
                 for (i = 0; i < 6; i++)
                     init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i],
                                   7 * 32);
-                if (s->picture.pict_type == AV_PICTURE_TYPE_P) {
+                if (f->pict_type == AV_PICTURE_TYPE_P) {
                     const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA];
                     put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);
                     score[0] = vlc[1] * lambda;
@@ -417,7 +419,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
 
             best = 0;
 
-            if (s->picture.pict_type == AV_PICTURE_TYPE_P) {
+            if (f->pict_type == AV_PICTURE_TYPE_P) {
                 const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER];
                 int mx, my, pred_x, pred_y, dxy;
                 int16_t *motion_ptr;
@@ -445,10 +447,10 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
 
                     dxy = (mx & 1) + 2 * (my & 1);
 
-                    s->dsp.put_pixels_tab[0][dxy](temp + 16,
-                                                  ref + (mx >> 1) +
-                                                  stride * (my >> 1),
-                                                  stride, 16);
+                    s->hdsp.put_pixels_tab[0][dxy](temp + 16,
+                                                   ref + (mx >> 1) +
+                                                   stride * (my >> 1),
+                                                   stride, 16);
 
                     score[1] += encode_block(s, src + 16 * x, temp + 16,
                                              decoded, stride, 5, 64, lambda, 0);
@@ -460,7 +462,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
                     score[2] += vlc[1] * lambda;
                     if (score[2] < score[best] && mx == 0 && my == 0) {
                         best = 2;
-                        s->dsp.put_pixels_tab[0][0](decoded, ref, stride, 16);
+                        s->hdsp.put_pixels_tab[0][0](decoded, ref, stride, 16);
                         for (i = 0; i < 6; i++)
                             count[2][i] = 0;
                         put_bits(&s->pb, vlc[1], vlc[0]);
@@ -490,19 +492,55 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
                 avpriv_copy_bits(&s->pb, reorder_buffer[best][i],
                                  count[best][i]);
             if (best == 0)
-                s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16);
+                s->hdsp.put_pixels_tab[0][0](decoded, temp, stride, 16);
         }
         s->m.first_slice_line = 0;
     }
     return 0;
 }
 
+static av_cold int svq1_encode_end(AVCodecContext *avctx)
+{
+    SVQ1Context *const s = avctx->priv_data;
+    int i;
+
+    av_log(avctx, AV_LOG_DEBUG, "RD: %f\n",
+           s->rd_total / (double)(avctx->width * avctx->height *
+                                  avctx->frame_number));
+
+    av_freep(&s->m.me.scratchpad);
+    av_freep(&s->m.me.map);
+    av_freep(&s->m.me.score_map);
+    av_freep(&s->mb_type);
+    av_freep(&s->dummy);
+    av_freep(&s->scratchbuf);
+
+    for (i = 0; i < 3; i++) {
+        av_freep(&s->motion_val8[i]);
+        av_freep(&s->motion_val16[i]);
+    }
+
+    av_frame_free(&s->current_picture);
+    av_frame_free(&s->last_picture);
+    av_frame_free(&avctx->coded_frame);
+
+    return 0;
+}
+
 static av_cold int svq1_encode_init(AVCodecContext *avctx)
 {
     SVQ1Context *const s = avctx->priv_data;
 
     ff_dsputil_init(&s->dsp, avctx);
-    avctx->coded_frame = &s->picture;
+    ff_hpeldsp_init(&s->hdsp, avctx->flags);
+
+    avctx->coded_frame = av_frame_alloc();
+    s->current_picture = av_frame_alloc();
+    s->last_picture    = av_frame_alloc();
+    if (!avctx->coded_frame || !s->current_picture || !s->last_picture) {
+        svq1_encode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
     s->frame_width  = avctx->width;
     s->frame_height = avctx->height;
@@ -534,13 +572,12 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                              const AVFrame *pict, int *got_packet)
 {
     SVQ1Context *const s = avctx->priv_data;
-    AVFrame *const p     = &s->picture;
-    AVFrame temp;
+    AVFrame *const p     = avctx->coded_frame;
     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)) {
+                             MAX_MB_BYTES * 3 + FF_MIN_BUFFER_SIZE)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
         return ret;
     }
@@ -550,33 +587,31 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         return -1;
     }
 
-    if (!s->current_picture.data[0]) {
-        ff_get_buffer(avctx, &s->current_picture);
-        ff_get_buffer(avctx, &s->last_picture);
-        s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2);
+    if (!s->current_picture->data[0]) {
+        ff_get_buffer(avctx, s->current_picture, 0);
+        ff_get_buffer(avctx, s->last_picture, 0);
+        s->scratchbuf = av_malloc(s->current_picture->linesize[0] * 16 * 2);
     }
 
-    temp               = s->current_picture;
-    s->current_picture = s->last_picture;
-    s->last_picture    = temp;
+    FFSWAP(AVFrame*, s->current_picture, s->last_picture);
 
     init_put_bits(&s->pb, pkt->data, pkt->size);
 
-    *p           = *pict;
     p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ?
                    AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
     p->key_frame = p->pict_type == AV_PICTURE_TYPE_I;
+    p->quality   = pict->quality;
 
     svq1_write_header(s, p->pict_type);
     for (i = 0; i < 3; i++)
         if (svq1_encode_plane(s, i,
-                              s->picture.data[i],
-                              s->last_picture.data[i],
-                              s->current_picture.data[i],
+                              pict->data[i],
+                              s->last_picture->data[i],
+                              s->current_picture->data[i],
                               s->frame_width  / (i ? 4 : 1),
                               s->frame_height / (i ? 4 : 1),
-                              s->picture.linesize[i],
-                              s->current_picture.linesize[i]) < 0)
+                              pict->linesize[i],
+                              s->current_picture->linesize[i]) < 0)
             return -1;
 
     // avpriv_align_put_bits(&s->pb);
@@ -593,39 +628,15 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
-static av_cold int svq1_encode_end(AVCodecContext *avctx)
-{
-    SVQ1Context *const s = avctx->priv_data;
-    int i;
-
-    av_log(avctx, AV_LOG_DEBUG, "RD: %f\n",
-           s->rd_total / (double)(avctx->width * avctx->height *
-                                  avctx->frame_number));
-
-    av_freep(&s->m.me.scratchpad);
-    av_freep(&s->m.me.map);
-    av_freep(&s->m.me.score_map);
-    av_freep(&s->mb_type);
-    av_freep(&s->dummy);
-    av_freep(&s->scratchbuf);
-
-    for (i = 0; i < 3; i++) {
-        av_freep(&s->motion_val8[i]);
-        av_freep(&s->motion_val16[i]);
-    }
-
-    return 0;
-}
-
 AVCodec ff_svq1_encoder = {
     .name           = "svq1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SVQ1,
     .priv_data_size = sizeof(SVQ1Context),
     .init           = svq1_encode_init,
     .encode2        = svq1_encode_frame,
     .close          = svq1_encode_end,
-    .pix_fmts       = (const enum PixelFormat[]) { AV_PIX_FMT_YUV410P,
-                                                   AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"),
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P,
+                                                     AV_PIX_FMT_NONE },
 };
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index 34cda32..cdff5af 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -39,8 +39,9 @@
  * correctly decodes this file:
  *  http://samples.libav.org/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
  */
+
+#include "libavutil/attributes.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "h264.h"
@@ -49,14 +50,15 @@
 
 #include "h264_mvpred.h"
 #include "golomb.h"
+#include "hpeldsp.h"
 #include "rectangle.h"
-#include "vdpau_internal.h"
 
 #if CONFIG_ZLIB
 #include <zlib.h>
 #endif
 
 #include "svq1.h"
+#include "svq3.h"
 
 /**
  * @file
@@ -65,11 +67,20 @@
 
 typedef struct {
     H264Context h;
+    HpelDSPContext hdsp;
+    Picture *cur_pic;
+    Picture *next_pic;
+    Picture *last_pic;
     int halfpel_flag;
     int thirdpel_flag;
     int unknown_flag;
     int next_slice_index;
     uint32_t watermark_key;
+    int adaptive_quant;
+    int next_p_frame_damaged;
+    int h_edge_pos;
+    int v_edge_pos;
+    int last_frame_output;
 } SVQ3Context;
 
 #define FULLPEL_MODE  1
@@ -93,6 +104,13 @@ static const uint8_t svq3_scan[16] = {
     0 + 3 * 4, 1 + 3 * 4, 2 + 3 * 4, 3 + 3 * 4,
 };
 
+static const uint8_t luma_dc_zigzag_scan[16] = {
+    0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64,
+    3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64,
+    1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64,
+    3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64,
+};
+
 static const uint8_t svq3_pred_0[25][2] = {
     { 0, 0 },
     { 1, 0 }, { 0, 1 },
@@ -137,7 +155,7 @@ static const uint32_t svq3_dequant_coeff[32] = {
     61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533
 };
 
-void ff_svq3_luma_dc_dequant_idct_c(DCTELEM *output, DCTELEM *input, int qp)
+void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp)
 {
     const int qmul = svq3_dequant_coeff[qp];
 #define stride 16
@@ -172,7 +190,7 @@ void ff_svq3_luma_dc_dequant_idct_c(DCTELEM *output, DCTELEM *input, int qp)
 }
 #undef stride
 
-void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block,
+void ff_svq3_add_idct_c(uint8_t *dst, int16_t *block,
                         int stride, int qp, int dc)
 {
     const int qmul = svq3_dequant_coeff[qp];
@@ -208,9 +226,11 @@ void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block,
         dst[i + stride * 2] = av_clip_uint8(dst[i + stride * 2] + ((z1 - z2) * qmul + rr >> 20));
         dst[i + stride * 3] = av_clip_uint8(dst[i + stride * 3] + ((z0 - z3) * qmul + rr >> 20));
     }
+
+    memset(block, 0, 16 * sizeof(int16_t));
 }
 
-static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block,
+static inline int svq3_decode_block(GetBitContext *gb, int16_t *block,
                                     int index, const int type)
 {
     static const uint8_t *const scan_patterns[4] =
@@ -266,12 +286,13 @@ static inline int svq3_decode_block(GetBitContext *gb, DCTELEM *block,
     return 0;
 }
 
-static inline void svq3_mc_dir_part(MpegEncContext *s,
+static inline void svq3_mc_dir_part(SVQ3Context *s,
                                     int x, int y, int width, int height,
                                     int mx, int my, int dxy,
                                     int thirdpel, int dir, int avg)
 {
-    const Picture *pic = (dir == 0) ? &s->last_picture : &s->next_picture;
+    H264Context *h     = &s->h;
+    const Picture *pic = (dir == 0) ? s->last_pic : s->next_pic;
     uint8_t *src, *dest;
     int i, emu = 0;
     int blocksize = 2 - (width >> 3); // 16->0, 8->1, 4->2
@@ -281,33 +302,32 @@ static inline void svq3_mc_dir_part(MpegEncContext *s,
 
     if (mx < 0 || mx >= s->h_edge_pos - width  - 1 ||
         my < 0 || my >= s->v_edge_pos - height - 1) {
-        if ((s->flags & CODEC_FLAG_EMU_EDGE))
-            emu = 1;
-
+        emu = 1;
         mx = av_clip(mx, -16, s->h_edge_pos - width  + 15);
         my = av_clip(my, -16, s->v_edge_pos - height + 15);
     }
 
     /* form component predictions */
-    dest = s->current_picture.f.data[0] + x + y * s->linesize;
-    src  = pic->f.data[0] + mx + my * s->linesize;
+    dest = h->cur_pic.f.data[0] + x + y * h->linesize;
+    src  = pic->f.data[0] + mx + my * h->linesize;
 
     if (emu) {
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize,
+        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src,
+                                 h->linesize, h->linesize,
                                  width + 1, height + 1,
                                  mx, my, s->h_edge_pos, s->v_edge_pos);
-        src = s->edge_emu_buffer;
+        src = h->edge_emu_buffer;
     }
     if (thirdpel)
-        (avg ? s->dsp.avg_tpel_pixels_tab
-             : s->dsp.put_tpel_pixels_tab)[dxy](dest, src, s->linesize,
+        (avg ? h->dsp.avg_tpel_pixels_tab
+             : h->dsp.put_tpel_pixels_tab)[dxy](dest, src, h->linesize,
                                                 width, height);
     else
-        (avg ? s->dsp.avg_pixels_tab
-             : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src, s->linesize,
-                                                      height);
+        (avg ? s->hdsp.avg_pixels_tab
+             : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, h->linesize,
+                                                       height);
 
-    if (!(s->flags & CODEC_FLAG_GRAY)) {
+    if (!(h->flags & CODEC_FLAG_GRAY)) {
         mx     = mx + (mx < (int) x) >> 1;
         my     = my + (my < (int) y) >> 1;
         width  = width  >> 1;
@@ -315,35 +335,36 @@ static inline void svq3_mc_dir_part(MpegEncContext *s,
         blocksize++;
 
         for (i = 1; i < 3; i++) {
-            dest = s->current_picture.f.data[i] + (x >> 1) + (y >> 1) * s->uvlinesize;
-            src  = pic->f.data[i] + mx + my * s->uvlinesize;
+            dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * h->uvlinesize;
+            src  = pic->f.data[i] + mx + my * h->uvlinesize;
 
             if (emu) {
-                s->vdsp.emulated_edge_mc(s->edge_emu_buffer, src, s->uvlinesize,
+                h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src,
+                                         h->uvlinesize, h->uvlinesize,
                                          width + 1, height + 1,
                                          mx, my, (s->h_edge_pos >> 1),
                                          s->v_edge_pos >> 1);
-                src = s->edge_emu_buffer;
+                src = h->edge_emu_buffer;
             }
             if (thirdpel)
-                (avg ? s->dsp.avg_tpel_pixels_tab
-                     : s->dsp.put_tpel_pixels_tab)[dxy](dest, src,
-                                                        s->uvlinesize,
+                (avg ? h->dsp.avg_tpel_pixels_tab
+                     : h->dsp.put_tpel_pixels_tab)[dxy](dest, src,
+                                                        h->uvlinesize,
                                                         width, height);
             else
-                (avg ? s->dsp.avg_pixels_tab
-                     : s->dsp.put_pixels_tab)[blocksize][dxy](dest, src,
-                                                              s->uvlinesize,
-                                                              height);
+                (avg ? s->hdsp.avg_pixels_tab
+                     : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src,
+                                                               h->uvlinesize,
+                                                               height);
         }
     }
 }
 
-static inline int svq3_mc_dir(H264Context *h, int size, int mode,
+static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
                               int dir, int avg)
 {
     int i, j, k, mx, my, dx, dy, x, y;
-    MpegEncContext *const s = (MpegEncContext *)h;
+    H264Context *h          = &s->h;
     const int part_width    = ((size & 5) == 4) ? 4 : 16 >> (size & 1);
     const int part_height   = 16 >> ((unsigned)(size + 1) / 3);
     const int extra_width   = (mode == PREDICT_MODE) ? -16 * 6 : 0;
@@ -352,19 +373,19 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode,
 
     for (i = 0; i < 16; i += part_height)
         for (j = 0; j < 16; j += part_width) {
-            const int b_xy = (4 * s->mb_x + (j >> 2)) +
-                             (4 * s->mb_y + (i >> 2)) * h->b_stride;
+            const int b_xy = (4 * h->mb_x + (j >> 2)) +
+                             (4 * h->mb_y + (i >> 2)) * h->b_stride;
             int dxy;
-            x = 16 * s->mb_x + j;
-            y = 16 * s->mb_y + i;
+            x = 16 * h->mb_x + j;
+            y = 16 * h->mb_y + i;
             k = (j >> 2 & 1) + (i >> 1 & 2) +
                 (j >> 1 & 4) + (i      & 8);
 
             if (mode != PREDICT_MODE) {
                 pred_motion(h, k, part_width >> 2, dir, 1, &mx, &my);
             } else {
-                mx = s->next_picture.f.motion_val[0][b_xy][0] << 1;
-                my = s->next_picture.f.motion_val[0][b_xy][1] << 1;
+                mx = s->next_pic->motion_val[0][b_xy][0] << 1;
+                my = s->next_pic->motion_val[0][b_xy][1] << 1;
 
                 if (dir == 0) {
                     mx = mx * h->frame_num_offset /
@@ -387,11 +408,11 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode,
             if (mode == PREDICT_MODE) {
                 dx = dy = 0;
             } else {
-                dy = svq3_get_se_golomb(&s->gb);
-                dx = svq3_get_se_golomb(&s->gb);
+                dy = svq3_get_se_golomb(&h->gb);
+                dx = svq3_get_se_golomb(&h->gb);
 
                 if (dx == INVALID_VLC || dy == INVALID_VLC) {
-                    av_log(h->s.avctx, AV_LOG_ERROR, "invalid MV vlc\n");
+                    av_log(h->avctx, AV_LOG_ERROR, "invalid MV vlc\n");
                     return -1;
                 }
             }
@@ -445,7 +466,7 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode,
             }
 
             /* write back motion vectors */
-            fill_rectangle(s->current_picture.f.motion_val[dir][b_xy],
+            fill_rectangle(h->cur_pic.motion_val[dir][b_xy],
                            part_width >> 2, part_height >> 2, h->b_stride,
                            pack16to32(mx, my), 4);
         }
@@ -453,46 +474,45 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode,
     return 0;
 }
 
-static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
+static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
 {
-    H264Context *h = &svq3->h;
+    H264Context *h = &s->h;
     int i, j, k, m, dir, mode;
     int cbp = 0;
     uint32_t vlc;
     int8_t *top, *left;
-    MpegEncContext *const s = (MpegEncContext *)h;
     const int mb_xy         = h->mb_xy;
-    const int b_xy          = 4 * s->mb_x + 4 * s->mb_y * h->b_stride;
+    const int b_xy          = 4 * h->mb_x + 4 * h->mb_y * h->b_stride;
 
-    h->top_samples_available      = (s->mb_y == 0) ? 0x33FF : 0xFFFF;
-    h->left_samples_available     = (s->mb_x == 0) ? 0x5F5F : 0xFFFF;
+    h->top_samples_available      = (h->mb_y == 0) ? 0x33FF : 0xFFFF;
+    h->left_samples_available     = (h->mb_x == 0) ? 0x5F5F : 0xFFFF;
     h->topright_samples_available = 0xFFFF;
 
     if (mb_type == 0) {           /* SKIP */
-        if (s->pict_type == AV_PICTURE_TYPE_P ||
-            s->next_picture.f.mb_type[mb_xy] == -1) {
-            svq3_mc_dir_part(s, 16 * s->mb_x, 16 * s->mb_y, 16, 16,
+        if (h->pict_type == AV_PICTURE_TYPE_P ||
+            s->next_pic->mb_type[mb_xy] == -1) {
+            svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,
                              0, 0, 0, 0, 0, 0);
 
-            if (s->pict_type == AV_PICTURE_TYPE_B)
-                svq3_mc_dir_part(s, 16 * s->mb_x, 16 * s->mb_y, 16, 16,
+            if (h->pict_type == AV_PICTURE_TYPE_B)
+                svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,
                                  0, 0, 0, 0, 1, 1);
 
             mb_type = MB_TYPE_SKIP;
         } else {
-            mb_type = FFMIN(s->next_picture.f.mb_type[mb_xy], 6);
-            if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 0, 0) < 0)
+            mb_type = FFMIN(s->next_pic->mb_type[mb_xy], 6);
+            if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0)
                 return -1;
-            if (svq3_mc_dir(h, mb_type, PREDICT_MODE, 1, 1) < 0)
+            if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0)
                 return -1;
 
             mb_type = MB_TYPE_16x16;
         }
     } else if (mb_type < 8) {     /* INTER */
-        if (svq3->thirdpel_flag && svq3->halfpel_flag == !get_bits1(&s->gb))
+        if (s->thirdpel_flag && s->halfpel_flag == !get_bits1(&h->gb))
             mode = THIRDPEL_MODE;
-        else if (svq3->halfpel_flag &&
-                 svq3->thirdpel_flag == !get_bits1(&s->gb))
+        else if (s->halfpel_flag &&
+                 s->thirdpel_flag == !get_bits1(&h->gb))
             mode = HALFPEL_MODE;
         else
             mode = FULLPEL_MODE;
@@ -507,63 +527,63 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
          */
 
         for (m = 0; m < 2; m++) {
-            if (s->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
+            if (h->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
                 for (i = 0; i < 4; i++)
                     AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i * 8],
-                              s->current_picture.f.motion_val[m][b_xy - 1 + i * h->b_stride]);
+                              h->cur_pic.motion_val[m][b_xy - 1 + i * h->b_stride]);
             } else {
                 for (i = 0; i < 4; i++)
                     AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i * 8]);
             }
-            if (s->mb_y > 0) {
+            if (h->mb_y > 0) {
                 memcpy(h->mv_cache[m][scan8[0] - 1 * 8],
-                       s->current_picture.f.motion_val[m][b_xy - h->b_stride],
+                       h->cur_pic.motion_val[m][b_xy - h->b_stride],
                        4 * 2 * sizeof(int16_t));
                 memset(&h->ref_cache[m][scan8[0] - 1 * 8],
-                       (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
+                       (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
 
-                if (s->mb_x < s->mb_width - 1) {
+                if (h->mb_x < h->mb_width - 1) {
                     AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1 * 8],
-                              s->current_picture.f.motion_val[m][b_xy - h->b_stride + 4]);
+                              h->cur_pic.motion_val[m][b_xy - h->b_stride + 4]);
                     h->ref_cache[m][scan8[0] + 4 - 1 * 8] =
-                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride + 1] + 6] == -1 ||
-                         h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
+                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 ||
+                         h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
                 } else
                     h->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;
-                if (s->mb_x > 0) {
+                if (h->mb_x > 0) {
                     AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1 * 8],
-                              s->current_picture.f.motion_val[m][b_xy - h->b_stride - 1]);
+                              h->cur_pic.motion_val[m][b_xy - h->b_stride - 1]);
                     h->ref_cache[m][scan8[0] - 1 - 1 * 8] =
-                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
+                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
                 } else
                     h->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE;
             } else
                 memset(&h->ref_cache[m][scan8[0] - 1 * 8 - 1],
                        PART_NOT_AVAILABLE, 8);
 
-            if (s->pict_type != AV_PICTURE_TYPE_B)
+            if (h->pict_type != AV_PICTURE_TYPE_B)
                 break;
         }
 
         /* decode motion vector(s) and form prediction(s) */
-        if (s->pict_type == AV_PICTURE_TYPE_P) {
-            if (svq3_mc_dir(h, mb_type - 1, mode, 0, 0) < 0)
+        if (h->pict_type == AV_PICTURE_TYPE_P) {
+            if (svq3_mc_dir(s, mb_type - 1, mode, 0, 0) < 0)
                 return -1;
         } else {        /* AV_PICTURE_TYPE_B */
             if (mb_type != 2) {
-                if (svq3_mc_dir(h, 0, mode, 0, 0) < 0)
+                if (svq3_mc_dir(s, 0, mode, 0, 0) < 0)
                     return -1;
             } else {
                 for (i = 0; i < 4; i++)
-                    memset(s->current_picture.f.motion_val[0][b_xy + i * h->b_stride],
+                    memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],
                            0, 4 * 2 * sizeof(int16_t));
             }
             if (mb_type != 1) {
-                if (svq3_mc_dir(h, 0, mode, 1, mb_type == 3) < 0)
+                if (svq3_mc_dir(s, 0, mode, 1, mb_type == 3) < 0)
                     return -1;
             } else {
                 for (i = 0; i < 4; i++)
-                    memset(s->current_picture.f.motion_val[1][b_xy + i * h->b_stride],
+                    memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],
                            0, 4 * 2 * sizeof(int16_t));
             }
         }
@@ -573,17 +593,17 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
         memset(h->intra4x4_pred_mode_cache, -1, 8 * 5 * sizeof(int8_t));
 
         if (mb_type == 8) {
-            if (s->mb_x > 0) {
+            if (h->mb_x > 0) {
                 for (i = 0; i < 4; i++)
                     h->intra4x4_pred_mode_cache[scan8[0] - 1 + i * 8] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6 - i];
                 if (h->intra4x4_pred_mode_cache[scan8[0] - 1] == -1)
                     h->left_samples_available = 0x5F5F;
             }
-            if (s->mb_y > 0) {
-                h->intra4x4_pred_mode_cache[4 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride] + 0];
-                h->intra4x4_pred_mode_cache[5 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride] + 1];
-                h->intra4x4_pred_mode_cache[6 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride] + 2];
-                h->intra4x4_pred_mode_cache[7 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride] + 3];
+            if (h->mb_y > 0) {
+                h->intra4x4_pred_mode_cache[4 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 0];
+                h->intra4x4_pred_mode_cache[5 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 1];
+                h->intra4x4_pred_mode_cache[6 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 2];
+                h->intra4x4_pred_mode_cache[7 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 3];
 
                 if (h->intra4x4_pred_mode_cache[4 + 8 * 0] == -1)
                     h->top_samples_available = 0x33FF;
@@ -591,10 +611,10 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
 
             /* decode prediction codes for luma blocks */
             for (i = 0; i < 16; i += 2) {
-                vlc = svq3_get_ue_golomb(&s->gb);
+                vlc = svq3_get_ue_golomb(&h->gb);
 
                 if (vlc >= 25) {
-                    av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);
+                    av_log(h->avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);
                     return -1;
                 }
 
@@ -605,7 +625,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
                 left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]];
 
                 if (left[1] == -1 || left[2] == -1) {
-                    av_log(h->s.avctx, AV_LOG_ERROR, "weird prediction\n");
+                    av_log(h->avctx, AV_LOG_ERROR, "weird prediction\n");
                     return -1;
                 }
             }
@@ -619,8 +639,8 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
         if (mb_type == 8) {
             ff_h264_check_intra4x4_pred_mode(h);
 
-            h->top_samples_available  = (s->mb_y == 0) ? 0x33FF : 0xFFFF;
-            h->left_samples_available = (s->mb_x == 0) ? 0x5F5F : 0xFFFF;
+            h->top_samples_available  = (h->mb_y == 0) ? 0x33FF : 0xFFFF;
+            h->left_samples_available = (h->mb_x == 0) ? 0x5F5F : 0xFFFF;
         } else {
             for (i = 0; i < 4; i++)
                 memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_128_PRED, 4);
@@ -635,7 +655,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
         dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1;
 
         if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) < 0) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n");
+            av_log(h->avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n");
             return h->intra16x16_pred_mode;
         }
 
@@ -643,29 +663,27 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
         mb_type = MB_TYPE_INTRA16x16;
     }
 
-    if (!IS_INTER(mb_type) && s->pict_type != AV_PICTURE_TYPE_I) {
+    if (!IS_INTER(mb_type) && h->pict_type != AV_PICTURE_TYPE_I) {
         for (i = 0; i < 4; i++)
-            memset(s->current_picture.f.motion_val[0][b_xy + i * h->b_stride],
+            memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],
                    0, 4 * 2 * sizeof(int16_t));
-        if (s->pict_type == AV_PICTURE_TYPE_B) {
+        if (h->pict_type == AV_PICTURE_TYPE_B) {
             for (i = 0; i < 4; i++)
-                memset(s->current_picture.f.motion_val[1][b_xy + i * h->b_stride],
+                memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],
                        0, 4 * 2 * sizeof(int16_t));
         }
     }
     if (!IS_INTRA4x4(mb_type)) {
         memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy], DC_PRED, 8);
     }
-    if (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B) {
+    if (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B) {
         memset(h->non_zero_count_cache + 8, 0, 14 * 8 * sizeof(uint8_t));
-        s->dsp.clear_blocks(h->mb +   0);
-        s->dsp.clear_blocks(h->mb + 384);
     }
 
     if (!IS_INTRA16x16(mb_type) &&
-        (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) {
-        if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);
+        (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B)) {
+        if ((vlc = svq3_get_ue_golomb(&h->gb)) >= 48) {
+            av_log(h->avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);
             return -1;
         }
 
@@ -673,19 +691,19 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
                                 : golomb_to_inter_cbp[vlc];
     }
     if (IS_INTRA16x16(mb_type) ||
-        (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
-        s->qscale += svq3_get_se_golomb(&s->gb);
+        (h->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
+        h->qscale += svq3_get_se_golomb(&h->gb);
 
-        if (s->qscale > 31u) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale);
+        if (h->qscale > 31u) {
+            av_log(h->avctx, AV_LOG_ERROR, "qscale:%d\n", h->qscale);
             return -1;
         }
     }
     if (IS_INTRA16x16(mb_type)) {
         AV_ZERO128(h->mb_luma_dc[0] + 0);
         AV_ZERO128(h->mb_luma_dc[0] + 8);
-        if (svq3_decode_block(&s->gb, h->mb_luma_dc[0], 0, 1)) {
-            av_log(h->s.avctx, AV_LOG_ERROR,
+        if (svq3_decode_block(&h->gb, h->mb_luma_dc[0], 0, 1)) {
+            av_log(h->avctx, AV_LOG_ERROR,
                    "error while decoding intra luma dc\n");
             return -1;
         }
@@ -693,7 +711,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
 
     if (cbp) {
         const int index = IS_INTRA16x16(mb_type) ? 1 : 0;
-        const int type  = ((s->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
+        const int type  = ((h->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
 
         for (i = 0; i < 4; i++)
             if ((cbp & (1 << i))) {
@@ -703,8 +721,8 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
                               : (4 * i + j);
                     h->non_zero_count_cache[scan8[k]] = 1;
 
-                    if (svq3_decode_block(&s->gb, &h->mb[16 * k], index, type)) {
-                        av_log(h->s.avctx, AV_LOG_ERROR,
+                    if (svq3_decode_block(&h->gb, &h->mb[16 * k], index, type)) {
+                        av_log(h->avctx, AV_LOG_ERROR,
                                "error while decoding block\n");
                         return -1;
                     }
@@ -713,8 +731,8 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
 
         if ((cbp & 0x30)) {
             for (i = 1; i < 3; ++i)
-                if (svq3_decode_block(&s->gb, &h->mb[16 * 16 * i], 0, 3)) {
-                    av_log(h->s.avctx, AV_LOG_ERROR,
+                if (svq3_decode_block(&h->gb, &h->mb[16 * 16 * i], 0, 3)) {
+                    av_log(h->avctx, AV_LOG_ERROR,
                            "error while decoding chroma dc block\n");
                     return -1;
                 }
@@ -725,8 +743,8 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
                         k                                 = 16 * i + j;
                         h->non_zero_count_cache[scan8[k]] = 1;
 
-                        if (svq3_decode_block(&s->gb, &h->mb[16 * k], 1, 1)) {
-                            av_log(h->s.avctx, AV_LOG_ERROR,
+                        if (svq3_decode_block(&h->gb, &h->mb[16 * k], 1, 1)) {
+                            av_log(h->avctx, AV_LOG_ERROR,
                                    "error while decoding chroma ac block\n");
                             return -1;
                         }
@@ -737,7 +755,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
     }
 
     h->cbp                              = cbp;
-    s->current_picture.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.mb_type[mb_xy] = mb_type;
 
     if (IS_INTRA(mb_type))
         h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1);
@@ -747,14 +765,13 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
 
 static int svq3_decode_slice_header(AVCodecContext *avctx)
 {
-    SVQ3Context *svq3 = avctx->priv_data;
-    H264Context *h    = &svq3->h;
-    MpegEncContext *s = &h->s;
+    SVQ3Context *s = avctx->priv_data;
+    H264Context *h    = &s->h;
     const int mb_xy   = h->mb_xy;
     int i, header;
     unsigned slice_id;
 
-    header = get_bits(&s->gb, 8);
+    header = get_bits(&h->gb, 8);
 
     if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) {
         /* TODO: what? */
@@ -763,75 +780,75 @@ static int svq3_decode_slice_header(AVCodecContext *avctx)
     } else {
         int length = header >> 5 & 3;
 
-        svq3->next_slice_index = get_bits_count(&s->gb) +
-                                 8 * show_bits(&s->gb, 8 * length) +
-                                 8 * length;
+        s->next_slice_index = get_bits_count(&h->gb) +
+                              8 * show_bits(&h->gb, 8 * length) +
+                              8 * length;
 
-        if (svq3->next_slice_index > s->gb.size_in_bits) {
+        if (s->next_slice_index > h->gb.size_in_bits) {
             av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n");
             return -1;
         }
 
-        s->gb.size_in_bits = svq3->next_slice_index - 8 * (length - 1);
-        skip_bits(&s->gb, 8);
+        h->gb.size_in_bits = s->next_slice_index - 8 * (length - 1);
+        skip_bits(&h->gb, 8);
 
-        if (svq3->watermark_key) {
-            uint32_t header = AV_RL32(&s->gb.buffer[(get_bits_count(&s->gb) >> 3) + 1]);
-            AV_WL32(&s->gb.buffer[(get_bits_count(&s->gb) >> 3) + 1],
-                    header ^ svq3->watermark_key);
+        if (s->watermark_key) {
+            uint32_t header = AV_RL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1]);
+            AV_WL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1],
+                    header ^ s->watermark_key);
         }
         if (length > 0) {
-            memcpy((uint8_t *) &s->gb.buffer[get_bits_count(&s->gb) >> 3],
-                   &s->gb.buffer[s->gb.size_in_bits >> 3], length - 1);
+            memcpy((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3],
+                   &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1);
         }
-        skip_bits_long(&s->gb, 0);
+        skip_bits_long(&h->gb, 0);
     }
 
-    if ((slice_id = svq3_get_ue_golomb(&s->gb)) >= 3) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", slice_id);
+    if ((slice_id = svq3_get_ue_golomb(&h->gb)) >= 3) {
+        av_log(h->avctx, AV_LOG_ERROR, "illegal slice type %d \n", slice_id);
         return -1;
     }
 
     h->slice_type = golomb_to_pict_type[slice_id];
 
     if ((header & 0x9F) == 2) {
-        i              = (s->mb_num < 64) ? 6 : (1 + av_log2(s->mb_num - 1));
-        s->mb_skip_run = get_bits(&s->gb, i) -
-                         (s->mb_y * s->mb_width + s->mb_x);
+        i              = (h->mb_num < 64) ? 6 : (1 + av_log2(h->mb_num - 1));
+        h->mb_skip_run = get_bits(&h->gb, i) -
+                         (h->mb_y * h->mb_width + h->mb_x);
     } else {
-        skip_bits1(&s->gb);
-        s->mb_skip_run = 0;
+        skip_bits1(&h->gb);
+        h->mb_skip_run = 0;
     }
 
-    h->slice_num      = get_bits(&s->gb, 8);
-    s->qscale         = get_bits(&s->gb, 5);
-    s->adaptive_quant = get_bits1(&s->gb);
+    h->slice_num      = get_bits(&h->gb, 8);
+    h->qscale         = get_bits(&h->gb, 5);
+    s->adaptive_quant = get_bits1(&h->gb);
 
     /* unknown fields */
-    skip_bits1(&s->gb);
+    skip_bits1(&h->gb);
 
-    if (svq3->unknown_flag)
-        skip_bits1(&s->gb);
+    if (s->unknown_flag)
+        skip_bits1(&h->gb);
 
-    skip_bits1(&s->gb);
-    skip_bits(&s->gb, 2);
+    skip_bits1(&h->gb);
+    skip_bits(&h->gb, 2);
 
-    while (get_bits1(&s->gb))
-        skip_bits(&s->gb, 8);
+    while (get_bits1(&h->gb))
+        skip_bits(&h->gb, 8);
 
     /* reset intra predictors and invalidate motion vector references */
-    if (s->mb_x > 0) {
+    if (h->mb_x > 0) {
         memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - 1] + 3,
                -1, 4 * sizeof(int8_t));
-        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - s->mb_x],
-               -1, 8 * sizeof(int8_t) * s->mb_x);
+        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - h->mb_x],
+               -1, 8 * sizeof(int8_t) * h->mb_x);
     }
-    if (s->mb_y > 0) {
-        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - s->mb_stride],
-               -1, 8 * sizeof(int8_t) * (s->mb_width - s->mb_x));
+    if (h->mb_y > 0) {
+        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy - h->mb_stride],
+               -1, 8 * sizeof(int8_t) * (h->mb_width - h->mb_x));
 
-        if (s->mb_x > 0)
-            h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1] + 3] = -1;
+        if (h->mb_x > 0)
+            h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] = -1;
     }
 
     return 0;
@@ -839,238 +856,358 @@ static int svq3_decode_slice_header(AVCodecContext *avctx)
 
 static av_cold int svq3_decode_init(AVCodecContext *avctx)
 {
-    SVQ3Context *svq3 = avctx->priv_data;
-    H264Context *h    = &svq3->h;
-    MpegEncContext *s = &h->s;
+    SVQ3Context *s = avctx->priv_data;
+    H264Context *h = &s->h;
     int m;
     unsigned char *extradata;
     unsigned char *extradata_end;
     unsigned int size;
     int marker_found = 0;
 
+    s->cur_pic  = av_mallocz(sizeof(*s->cur_pic));
+    s->last_pic = av_mallocz(sizeof(*s->last_pic));
+    s->next_pic = av_mallocz(sizeof(*s->next_pic));
+    if (!s->next_pic || !s->last_pic || !s->cur_pic) {
+        av_freep(&s->cur_pic);
+        av_freep(&s->last_pic);
+        av_freep(&s->next_pic);
+        return AVERROR(ENOMEM);
+    }
+
     if (ff_h264_decode_init(avctx) < 0)
         return -1;
 
-    s->flags           = avctx->flags;
-    s->flags2          = avctx->flags2;
-    s->unrestricted_mv = 1;
+    ff_hpeldsp_init(&s->hdsp, avctx->flags);
+    h->flags           = avctx->flags;
     h->is_complex      = 1;
+    h->picture_structure = PICT_FRAME;
     avctx->pix_fmt     = avctx->codec->pix_fmts[0];
 
-    if (!s->context_initialized) {
-        h->chroma_qp[0] = h->chroma_qp[1] = 4;
-
-        svq3->halfpel_flag  = 1;
-        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;
-        if (extradata) {
-            for (m = 0; m + 8 < avctx->extradata_size; m++) {
-                if (!memcmp(extradata, "SEQH", 4)) {
-                    marker_found = 1;
-                    break;
-                }
-                extradata++;
-            }
-        }
+    h->chroma_qp[0] = h->chroma_qp[1] = 4;
+    h->chroma_x_shift = h->chroma_y_shift = 1;
 
-        /* if a match was found, parse the extra data */
-        if (marker_found) {
-            GetBitContext gb;
-            int frame_size_code;
-
-            size = AV_RB32(&extradata[4]);
-            if (size > extradata_end - extradata - 8)
-                return AVERROR_INVALIDDATA;
-            init_get_bits(&gb, extradata + 8, size * 8);
-
-            /* 'frame size code' and optional 'width, height' */
-            frame_size_code = get_bits(&gb, 3);
-            switch (frame_size_code) {
-            case 0:
-                avctx->width  = 160;
-                avctx->height = 120;
-                break;
-            case 1:
-                avctx->width  = 128;
-                avctx->height =  96;
-                break;
-            case 2:
-                avctx->width  = 176;
-                avctx->height = 144;
-                break;
-            case 3:
-                avctx->width  = 352;
-                avctx->height = 288;
-                break;
-            case 4:
-                avctx->width  = 704;
-                avctx->height = 576;
-                break;
-            case 5:
-                avctx->width  = 240;
-                avctx->height = 180;
-                break;
-            case 6:
-                avctx->width  = 320;
-                avctx->height = 240;
-                break;
-            case 7:
-                avctx->width  = get_bits(&gb, 12);
-                avctx->height = get_bits(&gb, 12);
+    s->halfpel_flag  = 1;
+    s->thirdpel_flag = 1;
+    s->unknown_flag  = 0;
+
+    /* prowl for the "SEQH" marker in the extradata */
+    extradata     = (unsigned char *)avctx->extradata;
+    extradata_end = avctx->extradata + avctx->extradata_size;
+    if (extradata) {
+        for (m = 0; m + 8 < avctx->extradata_size; m++) {
+            if (!memcmp(extradata, "SEQH", 4)) {
+                marker_found = 1;
                 break;
             }
+            extradata++;
+        }
+    }
+
+    /* if a match was found, parse the extra data */
+    if (marker_found) {
+        GetBitContext gb;
+        int frame_size_code;
+
+        size = AV_RB32(&extradata[4]);
+        if (size > extradata_end - extradata - 8)
+            return AVERROR_INVALIDDATA;
+        init_get_bits(&gb, extradata + 8, size * 8);
+
+        /* 'frame size code' and optional 'width, height' */
+        frame_size_code = get_bits(&gb, 3);
+        switch (frame_size_code) {
+        case 0:
+            avctx->width  = 160;
+            avctx->height = 120;
+            break;
+        case 1:
+            avctx->width  = 128;
+            avctx->height =  96;
+            break;
+        case 2:
+            avctx->width  = 176;
+            avctx->height = 144;
+            break;
+        case 3:
+            avctx->width  = 352;
+            avctx->height = 288;
+            break;
+        case 4:
+            avctx->width  = 704;
+            avctx->height = 576;
+            break;
+        case 5:
+            avctx->width  = 240;
+            avctx->height = 180;
+            break;
+        case 6:
+            avctx->width  = 320;
+            avctx->height = 240;
+            break;
+        case 7:
+            avctx->width  = get_bits(&gb, 12);
+            avctx->height = get_bits(&gb, 12);
+            break;
+        }
 
-            svq3->halfpel_flag  = get_bits1(&gb);
-            svq3->thirdpel_flag = get_bits1(&gb);
+        s->halfpel_flag  = get_bits1(&gb);
+        s->thirdpel_flag = get_bits1(&gb);
 
-            /* unknown fields */
-            skip_bits1(&gb);
-            skip_bits1(&gb);
-            skip_bits1(&gb);
-            skip_bits1(&gb);
+        /* unknown fields */
+        skip_bits1(&gb);
+        skip_bits1(&gb);
+        skip_bits1(&gb);
+        skip_bits1(&gb);
 
-            s->low_delay = get_bits1(&gb);
+        h->low_delay = get_bits1(&gb);
 
-            /* unknown field */
-            skip_bits1(&gb);
+        /* unknown field */
+        skip_bits1(&gb);
 
-            while (get_bits1(&gb))
-                skip_bits(&gb, 8);
+        while (get_bits1(&gb))
+            skip_bits(&gb, 8);
 
-            svq3->unknown_flag  = get_bits1(&gb);
-            avctx->has_b_frames = !s->low_delay;
-            if (svq3->unknown_flag) {
+        s->unknown_flag  = get_bits1(&gb);
+        avctx->has_b_frames = !h->low_delay;
+        if (s->unknown_flag) {
 #if CONFIG_ZLIB
-                unsigned watermark_width  = svq3_get_ue_golomb(&gb);
-                unsigned watermark_height = svq3_get_ue_golomb(&gb);
-                int u1                    = svq3_get_ue_golomb(&gb);
-                int u2                    = get_bits(&gb, 8);
-                int u3                    = get_bits(&gb, 2);
-                int u4                    = svq3_get_ue_golomb(&gb);
-                unsigned long buf_len     = watermark_width *
-                                            watermark_height * 4;
-                int offset                = get_bits_count(&gb) + 7 >> 3;
-                uint8_t *buf;
-
-                if (watermark_height > 0 &&
-                    (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height)
-                    return -1;
+            unsigned watermark_width  = svq3_get_ue_golomb(&gb);
+            unsigned watermark_height = svq3_get_ue_golomb(&gb);
+            int u1                    = svq3_get_ue_golomb(&gb);
+            int u2                    = get_bits(&gb, 8);
+            int u3                    = get_bits(&gb, 2);
+            int u4                    = svq3_get_ue_golomb(&gb);
+            unsigned long buf_len     = watermark_width *
+                                        watermark_height * 4;
+            int offset                = get_bits_count(&gb) + 7 >> 3;
+            uint8_t *buf;
+
+            if (watermark_height > 0 &&
+                (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height)
+                return -1;
 
-                buf = av_malloc(buf_len);
-                av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n",
-                       watermark_width, watermark_height);
-                av_log(avctx, AV_LOG_DEBUG,
-                       "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
-                       u1, u2, u3, u4, offset);
-                if (uncompress(buf, &buf_len, extradata + 8 + offset,
-                               size - offset) != Z_OK) {
-                    av_log(avctx, AV_LOG_ERROR,
-                           "could not uncompress watermark logo\n");
-                    av_free(buf);
-                    return -1;
-                }
-                svq3->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);
-                svq3->watermark_key = svq3->watermark_key << 16 |
-                                      svq3->watermark_key;
-                av_log(avctx, AV_LOG_DEBUG,
-                       "watermark key %#x\n", svq3->watermark_key);
-                av_free(buf);
-#else
+            buf = av_malloc(buf_len);
+            av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n",
+                   watermark_width, watermark_height);
+            av_log(avctx, AV_LOG_DEBUG,
+                   "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
+                   u1, u2, u3, u4, offset);
+            if (uncompress(buf, &buf_len, extradata + 8 + offset,
+                           size - offset) != Z_OK) {
                 av_log(avctx, AV_LOG_ERROR,
-                       "this svq3 file contains watermark which need zlib support compiled in\n");
+                       "could not uncompress watermark logo\n");
+                av_free(buf);
                 return -1;
-#endif
             }
+            s->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);
+            s->watermark_key = s->watermark_key << 16 | s->watermark_key;
+            av_log(avctx, AV_LOG_DEBUG,
+                   "watermark key %#x\n", s->watermark_key);
+            av_free(buf);
+#else
+            av_log(avctx, AV_LOG_ERROR,
+                   "this svq3 file contains watermark which need zlib support compiled in\n");
+            return -1;
+#endif
         }
+    }
 
-        s->width  = avctx->width;
-        s->height = avctx->height;
+    h->width  = avctx->width;
+    h->height = avctx->height;
+    h->mb_width  = (h->width + 15) / 16;
+    h->mb_height = (h->height + 15) / 16;
+    h->mb_stride = h->mb_width + 1;
+    h->mb_num    = h->mb_width * h->mb_height;
+    h->b_stride = 4 * h->mb_width;
+    s->h_edge_pos = h->mb_width * 16;
+    s->v_edge_pos = h->mb_height * 16;
+
+    if (ff_h264_alloc_tables(h) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
+        return AVERROR(ENOMEM);
+    }
 
-        if (ff_MPV_common_init(s) < 0)
-            return -1;
+    return 0;
+}
 
-        h->b_stride = 4 * s->mb_width;
+static void free_picture(AVCodecContext *avctx, Picture *pic)
+{
+    int i;
+    for (i = 0; i < 2; i++) {
+        av_buffer_unref(&pic->motion_val_buf[i]);
+        av_buffer_unref(&pic->ref_index_buf[i]);
+    }
+    av_buffer_unref(&pic->mb_type_buf);
 
-        if (ff_h264_alloc_tables(h) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
+    av_frame_unref(&pic->f);
+}
+
+static int get_buffer(AVCodecContext *avctx, Picture *pic)
+{
+    SVQ3Context *s = avctx->priv_data;
+    H264Context *h = &s->h;
+    const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
+    const int mb_array_size = h->mb_stride * h->mb_height;
+    const int b4_stride     = h->mb_width * 4 + 1;
+    const int b4_array_size = b4_stride * h->mb_height * 4;
+    int ret;
+
+    if (!pic->motion_val_buf[0]) {
+        int i;
+
+        pic->mb_type_buf = av_buffer_allocz((big_mb_num + h->mb_stride) * sizeof(uint32_t));
+        if (!pic->mb_type_buf)
             return AVERROR(ENOMEM);
+        pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * h->mb_stride + 1;
+
+        for (i = 0; i < 2; i++) {
+            pic->motion_val_buf[i] = av_buffer_allocz(2 * (b4_array_size + 4) * sizeof(int16_t));
+            pic->ref_index_buf[i]  = av_buffer_allocz(4 * mb_array_size);
+            if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+
+            pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
+            pic->ref_index[i]  = pic->ref_index_buf[i]->data;
         }
     }
+    pic->reference = !(h->pict_type == AV_PICTURE_TYPE_B);
+
+    ret = ff_get_buffer(avctx, &pic->f,
+                        pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
+    if (ret < 0)
+        goto fail;
+
+    if (!h->edge_emu_buffer) {
+        h->edge_emu_buffer = av_mallocz(pic->f.linesize[0] * 17);
+        if (!h->edge_emu_buffer)
+            return AVERROR(ENOMEM);
+    }
+
+    h->linesize   = pic->f.linesize[0];
+    h->uvlinesize = pic->f.linesize[1];
 
     return 0;
+fail:
+    free_picture(avctx, pic);
+    return ret;
 }
 
 static int svq3_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    SVQ3Context *svq3  = avctx->priv_data;
-    H264Context *h     = &svq3->h;
-    MpegEncContext *s  = &h->s;
+    SVQ3Context *s     = avctx->priv_data;
+    H264Context *h     = &s->h;
     int buf_size       = avpkt->size;
-    int m;
+    int ret, m, i;
 
     /* special case for last picture */
     if (buf_size == 0) {
-        if (s->next_picture_ptr && !s->low_delay) {
-            *(AVFrame *) data   = s->next_picture.f;
-            s->next_picture_ptr = NULL;
+        if (s->next_pic->f.data[0] && !h->low_delay && !s->last_frame_output) {
+            ret = av_frame_ref(data, &s->next_pic->f);
+            if (ret < 0)
+                return ret;
+            s->last_frame_output = 1;
             *got_frame          = 1;
         }
         return 0;
     }
 
-    init_get_bits(&s->gb, buf, 8 * buf_size);
+    init_get_bits(&h->gb, buf, 8 * buf_size);
 
-    s->mb_x = s->mb_y = h->mb_xy = 0;
+    h->mb_x = h->mb_y = h->mb_xy = 0;
 
     if (svq3_decode_slice_header(avctx))
         return -1;
 
-    s->pict_type      = h->slice_type;
-    s->picture_number = h->slice_num;
+    h->pict_type = h->slice_type;
 
-    if (avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(h->s.avctx, AV_LOG_DEBUG,
-               "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",
-               av_get_picture_type_char(s->pict_type),
-               svq3->halfpel_flag, svq3->thirdpel_flag,
-               s->adaptive_quant, s->qscale, h->slice_num);
+    if (h->pict_type != AV_PICTURE_TYPE_B)
+        FFSWAP(Picture*, s->next_pic, s->last_pic);
+
+    av_frame_unref(&s->cur_pic->f);
 
     /* for skipping the frame */
-    s->current_picture.f.pict_type = s->pict_type;
-    s->current_picture.f.key_frame = (s->pict_type == AV_PICTURE_TYPE_I);
+    s->cur_pic->f.pict_type = h->pict_type;
+    s->cur_pic->f.key_frame = (h->pict_type == AV_PICTURE_TYPE_I);
+
+    ret = get_buffer(avctx, s->cur_pic);
+    if (ret < 0)
+        return ret;
+
+    h->cur_pic_ptr = s->cur_pic;
+    av_frame_unref(&h->cur_pic.f);
+    h->cur_pic     = *s->cur_pic;
+    ret = av_frame_ref(&h->cur_pic.f, &s->cur_pic->f);
+    if (ret < 0)
+        return ret;
+
+    for (i = 0; i < 16; i++) {
+        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
+    }
+    for (i = 0; i < 16; i++) {
+        h->block_offset[16 + i]      =
+        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+        h->block_offset[48 + 16 + i] =
+        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+    }
 
-    /* Skip B-frames if we do not have reference frames. */
-    if (s->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B)
-        return 0;
-    if (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B ||
-        avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I ||
+    if (h->pict_type != AV_PICTURE_TYPE_I) {
+        if (!s->last_pic->f.data[0]) {
+            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+            ret = get_buffer(avctx, s->last_pic);
+            if (ret < 0)
+                return ret;
+            memset(s->last_pic->f.data[0], 0, avctx->height * s->last_pic->f.linesize[0]);
+            memset(s->last_pic->f.data[1], 0x80, (avctx->height / 2) *
+                   s->last_pic->f.linesize[1]);
+            memset(s->last_pic->f.data[2], 0x80, (avctx->height / 2) *
+                   s->last_pic->f.linesize[2]);
+        }
+
+        if (h->pict_type == AV_PICTURE_TYPE_B && !s->next_pic->f.data[0]) {
+            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+            ret = get_buffer(avctx, s->next_pic);
+            if (ret < 0)
+                return ret;
+            memset(s->next_pic->f.data[0], 0, avctx->height * s->next_pic->f.linesize[0]);
+            memset(s->next_pic->f.data[1], 0x80, (avctx->height / 2) *
+                   s->next_pic->f.linesize[1]);
+            memset(s->next_pic->f.data[2], 0x80, (avctx->height / 2) *
+                   s->next_pic->f.linesize[2]);
+        }
+    }
+
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(h->avctx, AV_LOG_DEBUG,
+               "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",
+               av_get_picture_type_char(h->pict_type),
+               s->halfpel_flag, s->thirdpel_flag,
+               s->adaptive_quant, h->qscale, h->slice_num);
+
+    if (avctx->skip_frame >= AVDISCARD_NONREF && h->pict_type == AV_PICTURE_TYPE_B ||
+        avctx->skip_frame >= AVDISCARD_NONKEY && h->pict_type != AV_PICTURE_TYPE_I ||
         avctx->skip_frame >= AVDISCARD_ALL)
         return 0;
 
     if (s->next_p_frame_damaged) {
-        if (s->pict_type == AV_PICTURE_TYPE_B)
+        if (h->pict_type == AV_PICTURE_TYPE_B)
             return 0;
         else
             s->next_p_frame_damaged = 0;
     }
 
-    if (ff_h264_frame_start(h) < 0)
-        return -1;
-
-    if (s->pict_type == AV_PICTURE_TYPE_B) {
+    if (h->pict_type == AV_PICTURE_TYPE_B) {
         h->frame_num_offset = h->slice_num - h->prev_frame_num;
 
         if (h->frame_num_offset < 0)
             h->frame_num_offset += 256;
         if (h->frame_num_offset == 0 ||
             h->frame_num_offset >= h->prev_frame_num_offset) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n");
+            av_log(h->avctx, AV_LOG_ERROR, "error in B-frame picture id\n");
             return -1;
         }
     } else {
@@ -1093,16 +1230,16 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    for (s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
-        for (s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
+    for (h->mb_y = 0; h->mb_y < h->mb_height; h->mb_y++) {
+        for (h->mb_x = 0; h->mb_x < h->mb_width; h->mb_x++) {
             unsigned mb_type;
-            h->mb_xy = s->mb_x + s->mb_y * s->mb_stride;
+            h->mb_xy = h->mb_x + h->mb_y * h->mb_stride;
 
-            if ((get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits &&
-                ((get_bits_count(&s->gb) & 7) == 0 ||
-                 show_bits(&s->gb, -get_bits_count(&s->gb) & 7) == 0)) {
-                skip_bits(&s->gb, svq3->next_slice_index - get_bits_count(&s->gb));
-                s->gb.size_in_bits = 8 * buf_size;
+            if ((get_bits_count(&h->gb) + 7) >= h->gb.size_in_bits &&
+                ((get_bits_count(&h->gb) & 7) == 0 ||
+                 show_bits(&h->gb, -get_bits_count(&h->gb) & 7) == 0)) {
+                skip_bits(&h->gb, s->next_slice_index - get_bits_count(&h->gb));
+                h->gb.size_in_bits = 8 * buf_size;
 
                 if (svq3_decode_slice_header(avctx))
                     return -1;
@@ -1110,58 +1247,73 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
                 /* TODO: support s->mb_skip_run */
             }
 
-            mb_type = svq3_get_ue_golomb(&s->gb);
+            mb_type = svq3_get_ue_golomb(&h->gb);
 
-            if (s->pict_type == AV_PICTURE_TYPE_I)
+            if (h->pict_type == AV_PICTURE_TYPE_I)
                 mb_type += 8;
-            else if (s->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4)
+            else if (h->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4)
                 mb_type += 4;
-            if (mb_type > 33 || svq3_decode_mb(svq3, mb_type)) {
-                av_log(h->s.avctx, AV_LOG_ERROR,
-                       "error while decoding MB %d %d\n", s->mb_x, s->mb_y);
+            if (mb_type > 33 || svq3_decode_mb(s, mb_type)) {
+                av_log(h->avctx, AV_LOG_ERROR,
+                       "error while decoding MB %d %d\n", h->mb_x, h->mb_y);
                 return -1;
             }
 
             if (mb_type != 0)
                 ff_h264_hl_decode_mb(h);
 
-            if (s->pict_type != AV_PICTURE_TYPE_B && !s->low_delay)
-                s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
-                    (s->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
+            if (h->pict_type != AV_PICTURE_TYPE_B && !h->low_delay)
+                h->cur_pic.mb_type[h->mb_x + h->mb_y * h->mb_stride] =
+                    (h->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
         }
 
-        ff_draw_horiz_band(s, 16 * s->mb_y, 16);
+        ff_draw_horiz_band(avctx, NULL, s->cur_pic, s->last_pic->f.data[0] ? s->last_pic : NULL,
+                           16 * h->mb_y, 16, h->picture_structure, 0, 0,
+                           h->low_delay, h->mb_height * 16, h->mb_width * 16);
     }
 
-    ff_MPV_frame_end(s);
-
-    if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
-        *(AVFrame *)data = s->current_picture.f;
-    else
-        *(AVFrame *)data = s->last_picture.f;
+    if (h->pict_type == AV_PICTURE_TYPE_B || h->low_delay)
+        ret = av_frame_ref(data, &s->cur_pic->f);
+    else if (s->last_pic->f.data[0])
+        ret = av_frame_ref(data, &s->last_pic->f);
+    if (ret < 0)
+        return ret;
 
     /* Do not output the last pic after seeking. */
-    if (s->last_picture_ptr || s->low_delay)
+    if (s->last_pic->f.data[0] || h->low_delay)
         *got_frame = 1;
 
+    if (h->pict_type != AV_PICTURE_TYPE_B) {
+        FFSWAP(Picture*, s->cur_pic, s->next_pic);
+    } else {
+        av_frame_unref(&s->cur_pic->f);
+    }
+
     return buf_size;
 }
 
-static int svq3_decode_end(AVCodecContext *avctx)
+static av_cold int svq3_decode_end(AVCodecContext *avctx)
 {
-    SVQ3Context *svq3 = avctx->priv_data;
-    H264Context *h    = &svq3->h;
-    MpegEncContext *s = &h->s;
+    SVQ3Context *s = avctx->priv_data;
+    H264Context *h = &s->h;
 
-    ff_h264_free_context(h);
+    free_picture(avctx, s->cur_pic);
+    free_picture(avctx, s->next_pic);
+    free_picture(avctx, s->last_pic);
+    av_freep(&s->cur_pic);
+    av_freep(&s->next_pic);
+    av_freep(&s->last_pic);
+
+    av_frame_unref(&h->cur_pic.f);
 
-    ff_MPV_common_end(s);
+    ff_h264_free_context(h);
 
     return 0;
 }
 
 AVCodec ff_svq3_decoder = {
     .name           = "svq3",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SVQ3,
     .priv_data_size = sizeof(SVQ3Context),
@@ -1171,7 +1323,6 @@ AVCodec ff_svq3_decoder = {
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND |
                       CODEC_CAP_DR1             |
                       CODEC_CAP_DELAY,
-    .long_name      = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"),
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P,
                                                      AV_PIX_FMT_NONE},
 };
diff --git a/libavcodec/svq3.h b/libavcodec/svq3.h
new file mode 100644
index 0000000..8c67a23
--- /dev/null
+++ b/libavcodec/svq3.h
@@ -0,0 +1,27 @@
+/*
+ * 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_SVQ3_H
+#define AVCODEC_SVQ3_H
+
+#include <stdint.h>
+
+void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp);
+void ff_svq3_add_idct_c(uint8_t *dst, int16_t *block, int stride, int qp, int dc);
+
+#endif /* AVCODEC_DSPUTIL_H */
diff --git a/libavcodec/tableprint.h b/libavcodec/tableprint.h
index 81bb9af..daa89fe 100644
--- a/libavcodec/tableprint.h
+++ b/libavcodec/tableprint.h
@@ -71,10 +71,20 @@ void write_uint32_t_2d_array(const void *, int, int);
 void write_float_2d_array   (const void *, int, int);
 /** @} */ // end of printfuncs group
 
+/*
+ * MSVC doesn't have %zu, since it was introduced in C99,
+ * but has its own %Iu for printing size_t values.
+ */
+#if defined(_MSC_VER)
+#define FMT "Iu"
+#else
+#define FMT "zu"
+#endif
+
 #define WRITE_ARRAY(prefix, type, name)                 \
     do {                                                \
         const size_t array_size = FF_ARRAY_ELEMS(name); \
-        printf(prefix" "#type" "#name"[%zu] = {\n",     \
+        printf(prefix" "#type" "#name"[%"FMT"] = {\n",  \
                array_size);                             \
         write_##type##_array(name, array_size);         \
         printf("};\n");                                 \
@@ -84,7 +94,7 @@ void write_float_2d_array   (const void *, int, int);
     do {                                                                \
         const size_t array_size1 = FF_ARRAY_ELEMS(name);                \
         const size_t array_size2 = FF_ARRAY_ELEMS(name[0]);             \
-        printf(prefix" "#type" "#name"[%zu][%zu] = {\n",                \
+        printf(prefix" "#type" "#name"[%"FMT"][%"FMT"] = {\n",          \
                array_size1, array_size2 );                              \
         write_##type##_2d_array(name, array_size1, array_size2);        \
         printf("};\n");                                                 \
diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
index d47db48..0d2dcbb 100644
--- a/libavcodec/takdec.c
+++ b/libavcodec/takdec.c
@@ -25,6 +25,7 @@
  * @author Paul B Mahol
  */
 
+#include "libavutil/internal.h"
 #include "libavutil/samplefmt.h"
 #include "tak.h"
 #include "avcodec.h"
@@ -44,7 +45,6 @@ typedef struct 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
@@ -175,8 +175,6 @@ static av_cold int tak_decode_init(AVCodecContext *avctx)
     ff_dsputil_init(&s->dsp, avctx);
 
     s->avctx = avctx;
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
 
     set_sample_rate_params(avctx);
 
@@ -674,6 +672,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *pkt)
 {
     TAKDecContext *s  = avctx->priv_data;
+    AVFrame *frame    = data;
     GetBitContext *gb = &s->gb;
     int chan, i, ret, hsize;
 
@@ -686,7 +685,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
         return ret;
 
     if (s->ti.flags & TAK_FRAME_FLAG_HAS_METADATA) {
-        av_log_missing_feature(avctx, "frame metadata", 1);
+        avpriv_request_sample(avctx, "Frame metadata");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -694,7 +693,8 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
     if (avctx->err_recognition & AV_EF_CRCCHECK) {
         if (ff_tak_check_crc(pkt->data, hsize)) {
             av_log(avctx, AV_LOG_ERROR, "CRC error\n");
-            return AVERROR_INVALIDDATA;
+            if (avctx->err_recognition & AV_EF_EXPLODE)
+                return AVERROR_INVALIDDATA;
         }
     }
 
@@ -740,8 +740,8 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
     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 = ff_get_buffer(avctx, &s->frame)) < 0)
+    frame->nb_samples = s->nb_samples;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     if (avctx->bits_per_coded_sample <= 16) {
@@ -758,7 +758,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
             return ret;
     } else {
         for (chan = 0; chan < avctx->channels; chan++)
-            s->decoded[chan] = (int32_t *)s->frame.extended_data[chan];
+            s->decoded[chan] = (int32_t *)frame->extended_data[chan];
     }
 
     if (s->nb_samples < 16) {
@@ -868,7 +868,8 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
         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;
+            if (avctx->err_recognition & AV_EF_EXPLODE)
+                return AVERROR_INVALIDDATA;
         }
     }
 
@@ -876,7 +877,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
     switch (avctx->sample_fmt) {
     case AV_SAMPLE_FMT_U8P:
         for (chan = 0; chan < avctx->channels; chan++) {
-            uint8_t *samples = (uint8_t *)s->frame.extended_data[chan];
+            uint8_t *samples = (uint8_t *)frame->extended_data[chan];
             int32_t *decoded = s->decoded[chan];
             for (i = 0; i < s->nb_samples; i++)
                 samples[i] = decoded[i] + 0x80;
@@ -884,7 +885,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
         break;
     case AV_SAMPLE_FMT_S16P:
         for (chan = 0; chan < avctx->channels; chan++) {
-            int16_t *samples = (int16_t *)s->frame.extended_data[chan];
+            int16_t *samples = (int16_t *)frame->extended_data[chan];
             int32_t *decoded = s->decoded[chan];
             for (i = 0; i < s->nb_samples; i++)
                 samples[i] = decoded[i];
@@ -892,15 +893,14 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
         break;
     case AV_SAMPLE_FMT_S32P:
         for (chan = 0; chan < avctx->channels; chan++) {
-            int32_t *samples = (int32_t *)s->frame.extended_data[chan];
+            int32_t *samples = (int32_t *)frame->extended_data[chan];
             for (i = 0; i < s->nb_samples; i++)
                 samples[i] <<= 8;
         }
         break;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return pkt->size;
 }
@@ -917,6 +917,7 @@ static av_cold int tak_decode_close(AVCodecContext *avctx)
 
 AVCodec ff_tak_decoder = {
     .name             = "tak",
+    .long_name        = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
     .type             = AVMEDIA_TYPE_AUDIO,
     .id               = AV_CODEC_ID_TAK,
     .priv_data_size   = sizeof(TAKDecContext),
@@ -925,7 +926,6 @@ AVCodec ff_tak_decoder = {
     .close            = tak_decode_close,
     .decode           = tak_decode_frame,
     .capabilities     = CODEC_CAP_DR1,
-    .long_name        = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
     .sample_fmts      = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                         AV_SAMPLE_FMT_S16P,
                                                         AV_SAMPLE_FMT_S32P,
diff --git a/libavcodec/targa.c b/libavcodec/targa.c
index 3bbed94..f077c03 100644
--- a/libavcodec/targa.c
+++ b/libavcodec/targa.c
@@ -27,7 +27,6 @@
 #include "targa.h"
 
 typedef struct TargaContext {
-    AVFrame picture;
     GetByteContext gb;
 
     int color_type;
@@ -99,11 +98,10 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     TargaContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+    AVFrame * const p = data;
     uint8_t *dst;
     int stride;
-    int idlen, compr, y, w, h, bpp, flags;
+    int idlen, compr, y, w, h, bpp, flags, ret;
     int first_clr, colors, csize;
 
     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
@@ -141,19 +139,15 @@ static int decode_frame(AVCodecContext *avctx,
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Bit depth %i is not supported\n", bpp);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
+    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
+        return ret;
 
-    if(av_image_check_size(w, h, 0, avctx))
-        return -1;
-    if(w != avctx->width || h != avctx->height)
-        avcodec_set_dimensions(avctx, w, h);
-    if(ff_get_buffer(avctx, p) < 0){
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     if(flags & 0x20){
         dst = p->data[0];
@@ -167,7 +161,7 @@ static int decode_frame(AVCodecContext *avctx,
         int pal_size, pal_sample_size;
         if((colors + first_clr) > 256){
             av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         switch (csize) {
         case 24: pal_sample_size = 3; break;
@@ -175,7 +169,7 @@ static int decode_frame(AVCodecContext *avctx,
         case 15: pal_sample_size = 2; break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Palette entry size %i bits is not supported\n", csize);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         pal_size = colors * pal_sample_size;
         if(avctx->pix_fmt != AV_PIX_FMT_PAL8)//should not occur but skip palette anyway
@@ -232,38 +226,17 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return avpkt->size;
 }
 
-static av_cold int targa_init(AVCodecContext *avctx){
-    TargaContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
-static av_cold int targa_end(AVCodecContext *avctx){
-    TargaContext *s = avctx->priv_data;
-
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_targa_decoder = {
     .name           = "targa",
+    .long_name      = NULL_IF_CONFIG_SMALL("Truevision Targa image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TARGA,
     .priv_data_size = sizeof(TargaContext),
-    .init           = targa_init,
-    .close          = targa_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Truevision Targa image"),
 };
diff --git a/libavcodec/targaenc.c b/libavcodec/targaenc.c
index e13545f..7679029 100644
--- a/libavcodec/targaenc.c
+++ b/libavcodec/targaenc.c
@@ -29,10 +29,6 @@
 #include "rle.h"
 #include "targa.h"
 
-typedef struct TargaContext {
-    AVFrame picture;
-} TargaContext;
-
 /**
  * RLE compress the image, with maximum size of out_size
  * @param outbuf Output buffer
@@ -154,26 +150,32 @@ static int targa_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
 static av_cold int targa_encode_init(AVCodecContext *avctx)
 {
-    TargaContext *s = avctx->priv_data;
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
 
-    avcodec_get_frame_defaults(&s->picture);
-    s->picture.key_frame= 1;
-    s->picture.pict_type = AV_PICTURE_TYPE_I;
-    avctx->coded_frame= &s->picture;
+    avctx->coded_frame->key_frame = 1;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
 
     return 0;
 }
 
+static av_cold int targa_encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
 AVCodec ff_targa_encoder = {
     .name           = "targa",
+    .long_name      = NULL_IF_CONFIG_SMALL("Truevision Targa image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TARGA,
-    .priv_data_size = sizeof(TargaContext),
     .init           = targa_encode_init,
+    .close          = targa_encode_close,
     .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_NONE
     },
-    .long_name= NULL_IF_CONFIG_SMALL("Truevision Targa image"),
 };
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 99b0ce1..864e67e 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -27,9 +27,19 @@
 #ifndef AVCODEC_THREAD_H
 #define AVCODEC_THREAD_H
 
+#include "libavutil/buffer.h"
+
 #include "config.h"
 #include "avcodec.h"
 
+typedef struct ThreadFrame {
+    AVFrame *f;
+    AVCodecContext *owner;
+    // progress->data is an array of 2 ints holding progress for top/bottom
+    // fields
+    AVBufferRef *progress;
+} ThreadFrame;
+
 /**
  * Wait for decoding threads to finish and reset internal state.
  * Called by avcodec_flush_buffers().
@@ -71,7 +81,7 @@ void ff_thread_finish_setup(AVCodecContext *avctx);
  * @param field The field being decoded, for field-picture codecs.
  * 0 for top field or frame pictures, 1 for bottom field.
  */
-void ff_thread_report_progress(AVFrame *f, int progress, int field);
+void ff_thread_report_progress(ThreadFrame *f, int progress, int field);
 
 /**
  * Wait for earlier decoding threads to finish reference pictures.
@@ -85,7 +95,7 @@ void ff_thread_report_progress(AVFrame *f, int progress, int field);
  * @param field The field being referenced, for field-picture codecs.
  * 0 for top field or frame pictures, 1 for bottom field.
  */
-void ff_thread_await_progress(AVFrame *f, int progress, int field);
+void ff_thread_await_progress(ThreadFrame *f, int progress, int field);
 
 /**
  * Wrapper around get_buffer() for frame-multithreaded codecs.
@@ -95,7 +105,7 @@ void ff_thread_await_progress(AVFrame *f, int progress, int field);
  * @param avctx The current context.
  * @param f The frame to write into.
  */
-int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f);
+int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags);
 
 /**
  * Wrapper around release_buffer() frame-for multithreaded codecs.
@@ -108,7 +118,9 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f);
  * @param avctx The current context.
  * @param f The picture being released.
  */
-void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f);
+void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f);
+
+int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src);
 
 int ff_thread_init(AVCodecContext *s);
 void ff_thread_free(AVCodecContext *s);
diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c
index a9064ec..33b2579 100644
--- a/libavcodec/tiertexseqv.c
+++ b/libavcodec/tiertexseqv.c
@@ -27,11 +27,12 @@
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 
 
 typedef struct SeqVideoContext {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 } SeqVideoContext;
 
 
@@ -92,14 +93,14 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq,
             src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
             for (b = 0; b < 8; b++) {
                 memcpy(dst, &block[b * 8], 8);
-                dst += seq->frame.linesize[0];
+                dst += seq->frame->linesize[0];
             }
             break;
         case 2:
             src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
             for (i = 0; i < 8; i++) {
                 for (b = 0; b < 8; b++)
-                    dst[b * seq->frame.linesize[0]] = block[i * 8 + b];
+                    dst[b * seq->frame->linesize[0]] = block[i * 8 + b];
                 ++dst;
             }
             break;
@@ -116,7 +117,7 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq,
         for (b = 0; b < 8; b++) {
             for (i = 0; i < 8; i++)
                 dst[i] = color_table[get_bits(&gb, bits)];
-            dst += seq->frame.linesize[0];
+            dst += seq->frame->linesize[0];
         }
     }
 
@@ -136,7 +137,7 @@ static const unsigned char *seq_decode_op2(SeqVideoContext *seq,
     for (i = 0; i < 8; i++) {
         memcpy(dst, src, 8);
         src += 8;
-        dst += seq->frame.linesize[0];
+        dst += seq->frame->linesize[0];
     }
 
     return src;
@@ -153,7 +154,7 @@ static const unsigned char *seq_decode_op3(SeqVideoContext *seq,
         if (src_end - src < 2)
             return NULL;
         pos = *src++;
-        offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7);
+        offset = ((pos >> 3) & 7) * seq->frame->linesize[0] + (pos & 7);
         dst[offset] = *src++;
     } while (!(pos & 0x80));
 
@@ -172,7 +173,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int
     flags = *data++;
 
     if (flags & 1) {
-        palette = (uint32_t *)seq->frame.data[1];
+        palette = (uint32_t *)seq->frame->data[1];
         if (data_end - data < 256 * 3)
             return AVERROR_INVALIDDATA;
         for (i = 0; i < 256; i++) {
@@ -180,7 +181,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int
                 c[j] = (*data << 2) | (*data >> 4);
             palette[i] = AV_RB24(c);
         }
-        seq->frame.palette_has_changed = 1;
+        seq->frame->palette_has_changed = 1;
     }
 
     if (flags & 2) {
@@ -189,7 +190,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int
         init_get_bits(&gb, data, 128 * 8); data += 128;
         for (y = 0; y < 128; y += 8)
             for (x = 0; x < 256; x += 8) {
-                dst = &seq->frame.data[0][y * seq->frame.linesize[0] + x];
+                dst = &seq->frame->data[0][y * seq->frame->linesize[0] + x];
                 op = get_bits(&gb, 2);
                 switch (op) {
                 case 1:
@@ -216,7 +217,9 @@ static av_cold int seqvideo_decode_init(AVCodecContext *avctx)
     seq->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    seq->frame.data[0] = NULL;
+    seq->frame = av_frame_alloc();
+    if (!seq->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -227,21 +230,21 @@ static int seqvideo_decode_frame(AVCodecContext *avctx,
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
+    int ret;
 
     SeqVideoContext *seq = avctx->priv_data;
 
-    seq->frame.reference = 1;
-    seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &seq->frame)) {
+    if ((ret = ff_reget_buffer(avctx, seq->frame)) < 0) {
         av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (seqvideo_decode(seq, buf, buf_size))
         return AVERROR_INVALIDDATA;
 
+    if ((ret = av_frame_ref(data, seq->frame)) < 0)
+        return ret;
     *got_frame       = 1;
-    *(AVFrame *)data = seq->frame;
 
     return buf_size;
 }
@@ -250,14 +253,14 @@ static av_cold int seqvideo_decode_end(AVCodecContext *avctx)
 {
     SeqVideoContext *seq = avctx->priv_data;
 
-    if (seq->frame.data[0])
-        avctx->release_buffer(avctx, &seq->frame);
+    av_frame_free(&seq->frame);
 
     return 0;
 }
 
 AVCodec ff_tiertexseqvideo_decoder = {
     .name           = "tiertexseqvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TIERTEXSEQVIDEO,
     .priv_data_size = sizeof(SeqVideoContext),
@@ -265,5 +268,4 @@ AVCodec ff_tiertexseqvideo_decoder = {
     .close          = seqvideo_decode_end,
     .decode         = seqvideo_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"),
 };
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 264e985..7fb0e7a 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -25,23 +25,23 @@
  * @author Konstantin Shishkov
  */
 
-#include "avcodec.h"
 #include "config.h"
 #if CONFIG_ZLIB
 #include <zlib.h>
 #endif
-#include "lzw.h"
-#include "tiff.h"
-#include "faxcompr.h"
-#include "internal.h"
-#include "mathops.h"
+
 #include "libavutil/attributes.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "faxcompr.h"
+#include "internal.h"
+#include "lzw.h"
+#include "mathops.h"
+#include "tiff.h"
 
 typedef struct TiffContext {
     AVCodecContext *avctx;
-    AVFrame picture;
 
     int width, height;
     unsigned int bpp, bppcount;
@@ -79,10 +79,14 @@ static unsigned tget_long(const uint8_t **p, int le)
 static unsigned tget(const uint8_t **p, 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);
-    default        : return UINT_MAX;
+    case TIFF_BYTE:
+        return *(*p)++;
+    case TIFF_SHORT:
+        return tget_short(p, le);
+    case TIFF_LONG:
+        return tget_long(p, le);
+    default:
+        return UINT_MAX;
     }
 }
 
@@ -93,11 +97,11 @@ static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src,
     z_stream zstream = { 0 };
     int zret;
 
-    zstream.next_in = src;
-    zstream.avail_in = size;
-    zstream.next_out = dst;
+    zstream.next_in   = src;
+    zstream.avail_in  = size;
+    zstream.next_out  = dst;
     zstream.avail_out = *len;
-    zret = inflateInit(&zstream);
+    zret              = inflateInit(&zstream);
     if (zret != Z_OK) {
         av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
         return zret;
@@ -107,90 +111,103 @@ static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src,
     *len = zstream.total_out;
     return zret == Z_STREAM_END ? Z_OK : zret;
 }
+
+static int tiff_unpack_zlib(TiffContext *s, uint8_t *dst, int stride,
+                            const uint8_t *src, int size,
+                            int width, int lines)
+{
+    uint8_t *zbuf;
+    unsigned long outlen;
+    int ret, line;
+    outlen = width * lines;
+    zbuf   = av_malloc(outlen);
+    if (!zbuf)
+        return AVERROR(ENOMEM);
+    ret = tiff_uncompress(zbuf, &outlen, src, size);
+    if (ret != Z_OK) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
+               (unsigned long)width * lines, ret);
+        av_free(zbuf);
+        return AVERROR_UNKNOWN;
+    }
+    src = zbuf;
+    for (line = 0; line < lines; line++) {
+        memcpy(dst, src, width);
+        dst += stride;
+        src += width;
+    }
+    av_free(zbuf);
+    return 0;
+}
 #endif
 
+
+static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride,
+                           const uint8_t *src, int size, int lines)
+{
+    int i, ret = 0;
+    uint8_t *src2 = av_malloc((unsigned)size +
+                              FF_INPUT_BUFFER_PADDING_SIZE);
+
+    if (!src2) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Error allocating temporary buffer\n");
+        return AVERROR(ENOMEM);
+    }
+    if (s->fax_opts & 2) {
+        avpriv_request_sample(s->avctx, "Uncompressed fax mode");
+        av_free(src2);
+        return AVERROR_PATCHWELCOME;
+    }
+    if (!s->fill_order) {
+        memcpy(src2, src, size);
+    } else {
+        for (i = 0; i < size; i++)
+            src2[i] = ff_reverse[src[i]];
+    }
+    memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride,
+                          s->compr, s->fax_opts);
+    av_free(src2);
+    return ret;
+}
+
 static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
                              const uint8_t *src, int size, int lines)
 {
-    int c, line, pixels, code;
+    int c, line, pixels, code, ret;
     const uint8_t *ssrc = src;
-    int width = ((s->width * s->bpp) + 7) >> 3;
+    int width           = ((s->width * s->bpp) + 7) >> 3;
 
     if (size <= 0)
         return AVERROR_INVALIDDATA;
 
-#if CONFIG_ZLIB
     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
-        uint8_t *zbuf;
-        unsigned long outlen;
-        int ret;
-        outlen = width * lines;
-        zbuf = av_malloc(outlen);
-        if (!zbuf)
-            return AVERROR(ENOMEM);
-        ret = tiff_uncompress(zbuf, &outlen, src, size);
-        if (ret != Z_OK) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
-                   (unsigned long)width * lines, ret);
-            av_free(zbuf);
-            return -1;
-        }
-        src = zbuf;
-        for (line = 0; line < lines; line++) {
-            memcpy(dst, src, width);
-            dst += stride;
-            src += width;
-        }
-        av_free(zbuf);
-        return 0;
-    }
+#if CONFIG_ZLIB
+        return tiff_unpack_zlib(s, dst, stride, src, size, width, lines);
+#else
+        av_log(s->avctx, AV_LOG_ERROR,
+               "zlib support not enabled, "
+               "deflate compression not supported\n");
+        return AVERROR(ENOSYS);
 #endif
+    }
     if (s->compr == TIFF_LZW) {
-        if (ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF) < 0) {
+        if ((ret = ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF)) < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
-            return -1;
+            return ret;
         }
     }
-    if (s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3
-        || s->compr == TIFF_G4) {
-        int i, ret = 0;
-        uint8_t *src2 = av_malloc((unsigned)size +
-                                  FF_INPUT_BUFFER_PADDING_SIZE);
-
-        if (!src2) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Error allocating temporary buffer\n");
-            return AVERROR(ENOMEM);
-        }
-        if (s->fax_opts & 2) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Uncompressed fax mode is not supported (yet)\n");
-            av_free(src2);
-            return -1;
-        }
-        if (!s->fill_order) {
-            memcpy(src2, src, size);
-        } else {
-            for (i = 0; i < size; i++)
-                src2[i] = ff_reverse[src[i]];
-        }
-        memset(src2 + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-        switch (s->compr) {
-        case TIFF_CCITT_RLE:
-        case TIFF_G3:
-        case TIFF_G4:
-            ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride,
-                                  s->compr, s->fax_opts);
-            break;
-        }
-        av_free(src2);
-        return ret;
+    if (s->compr == TIFF_CCITT_RLE ||
+        s->compr == TIFF_G3        ||
+        s->compr == TIFF_G4) {
+        return tiff_unpack_fax(s, dst, stride, src, size, lines);
     }
     for (line = 0; line < lines; line++) {
         if (src - ssrc > size) {
             av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         switch (s->compr) {
         case TIFF_RAW:
@@ -209,24 +226,24 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
             for (pixels = 0; pixels < width;) {
                 if (ssrc + size - src < 2)
                     return AVERROR_INVALIDDATA;
-                code = (int8_t) * src++;
+                code = (int8_t) *src++;
                 if (code >= 0) {
                     code++;
                     if (pixels + code > width ||
                         ssrc + size - src < code) {
                         av_log(s->avctx, AV_LOG_ERROR,
                                "Copy went out of bounds\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     memcpy(dst + pixels, src, code);
-                    src += code;
+                    src    += code;
                     pixels += code;
                 } else if (code != -128) { // -127..-1
                     code = (-code) + 1;
                     if (pixels + code > width) {
                         av_log(s->avctx, AV_LOG_ERROR,
                                "Run went out of bounds\n");
-                        return -1;
+                        return AVERROR_INVALIDDATA;
                     }
                     c = *src++;
                     memset(dst + pixels, c, code);
@@ -239,7 +256,7 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
             if (pixels < width) {
                 av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",
                        pixels, width);
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             break;
         }
@@ -248,7 +265,7 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
     return 0;
 }
 
-static int init_image(TiffContext *s)
+static int init_image(TiffContext *s, AVFrame *frame)
 {
     int i, ret;
     uint32_t *pal;
@@ -279,22 +296,20 @@ static int init_image(TiffContext *s)
         return AVERROR_INVALIDDATA;
     }
     if (s->width != s->avctx->width || s->height != s->avctx->height) {
-        if ((ret = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
+        ret = ff_set_dimensions(s->avctx, s->width, s->height);
+        if (ret < 0)
             return ret;
-        avcodec_set_dimensions(s->avctx, s->width, s->height);
     }
-    if (s->picture.data[0])
-        s->avctx->release_buffer(s->avctx, &s->picture);
-    if ((ret = ff_get_buffer(s->avctx, &s->picture)) < 0) {
+    if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
     if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         if (s->palette_is_set) {
-            memcpy(s->picture.data[1], s->palette, sizeof(s->palette));
+            memcpy(frame->data[1], s->palette, sizeof(s->palette));
         } else {
             /* make default grayscale pal */
-            pal = (uint32_t *) s->picture.data[1];
+            pal = (uint32_t *) frame->data[1];
             for (i = 0; i < 256; i++)
                 pal[i] = i * 0x010101;
         }
@@ -311,11 +326,11 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
     const uint8_t *rp, *gp, *bp;
 
     if (end_buf - buf < 12)
-        return -1;
-    tag = tget_short(&buf, s->le);
-    type = tget_short(&buf, s->le);
+        return AVERROR_INVALIDDATA;
+    tag   = tget_short(&buf, s->le);
+    type  = tget_short(&buf, s->le);
     count = tget_long(&buf, s->le);
-    off = tget_long(&buf, s->le);
+    off   = tget_long(&buf, s->le);
 
     if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {
         av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n",
@@ -327,13 +342,13 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
         switch (type) {
         case TIFF_BYTE:
         case TIFF_SHORT:
-            buf -= 4;
+            buf  -= 4;
             value = tget(&buf, type, s->le);
-            buf = NULL;
+            buf   = NULL;
             break;
         case TIFF_LONG:
             value = off;
-            buf = NULL;
+            buf   = NULL;
             break;
         case TIFF_STRING:
             if (count <= 4) {
@@ -342,20 +357,19 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
             }
         default:
             value = UINT_MAX;
-            buf = start + off;
+            buf   = start + off;
         }
     } else {
-        if (count <= 4 && type_sizes[type] * count <= 4) {
+        if (count <= 4 && type_sizes[type] * count <= 4)
             buf -= 4;
-        } else {
+        else
             buf = start + off;
-        }
     }
 
     if (buf && (buf < start || buf > end_buf)) {
         av_log(s->avctx, AV_LOG_ERROR,
                "Tag referencing position outside the image\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     switch (tag) {
@@ -371,7 +385,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
             av_log(s->avctx, AV_LOG_ERROR,
                    "This format is not supported (bpp=%d, %d components)\n",
                    s->bpp, count);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         if (count == 1)
             s->bpp = value;
@@ -403,7 +417,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
         s->bppcount = value;
         break;
     case TIFF_COMPR:
-        s->compr = value;
+        s->compr     = value;
         s->predictor = 0;
         switch (s->compr) {
         case TIFF_RAW:
@@ -421,17 +435,16 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
             break;
 #else
             av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
-            return -1;
+            return AVERROR(ENOSYS);
 #endif
         case TIFF_JPEG:
         case TIFF_NEWJPEG:
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "JPEG compression is not supported\n");
-            return -1;
+            avpriv_report_missing_feature(s->avctx, "JPEG compression");
+            return AVERROR_PATCHWELCOME;
         default:
             av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",
                    s->compr);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     case TIFF_ROWSPERSTRIP:
@@ -440,14 +453,14 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
         if (value < 1) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "Incorrect value of rows per strip\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         s->rps = value;
         break;
     case TIFF_STRIP_OFFS:
         if (count == 1) {
             s->stripdata = NULL;
-            s->stripoff = value;
+            s->stripoff  = value;
         } else
             s->stripdata = start + off;
         s->strips = count;
@@ -457,14 +470,14 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
         if (s->stripdata > end_buf) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "Tag referencing position outside the image\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     case TIFF_STRIP_SIZE:
         if (count == 1) {
             s->stripsizes = NULL;
-            s->stripsize = value;
-            s->strips = 1;
+            s->stripsize  = value;
+            s->strips     = 1;
         } else {
             s->stripsizes = start + off;
         }
@@ -473,7 +486,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
         if (s->stripsizes > end_buf) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "Tag referencing position outside the image\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     case TIFF_PREDICTOR:
@@ -493,7 +506,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
         default:
             av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n",
                    value);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         break;
     case TIFF_FILL_ORDER:
@@ -508,23 +521,23 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
         pal = (uint32_t *) s->palette;
         off = type_sizes[type];
         if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)
-            return -1;
-        rp = buf;
-        gp = buf + count / 3 * off;
-        bp = buf + count / 3 * off * 2;
+            return AVERROR_INVALIDDATA;
+        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;
+            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;
         }
         s->palette_is_set = 1;
         break;
     case TIFF_PLANAR:
         if (value == 2) {
-            av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");
-            return -1;
+            avpriv_report_missing_feature(s->avctx, "Planar format");
+            return AVERROR_PATCHWELCOME;
         }
         break;
     case TIFF_T4OPTIONS:
@@ -536,8 +549,12 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
             s->fax_opts = value;
         break;
     default:
-        av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n",
-               tag, tag);
+        if (s->avctx->err_recognition & AV_EF_EXPLODE) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Unknown or unsupported tag %d/0X%0X\n",
+                   tag, tag);
+            return AVERROR_INVALIDDATA;
+        }
     }
     return 0;
 }
@@ -546,22 +563,20 @@ static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    int buf_size       = avpkt->size;
     TiffContext *const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame *const p = &s->picture;
+    AVFrame *const p = data;
     const uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
     unsigned off;
     int id, le, ret;
-    int i, j, entries;
-    int stride;
+    int i, j, entries, stride;
     unsigned soff, ssize;
     uint8_t *dst;
 
-    //parse image header
+    // parse image header
     if (end_buf - buf < 8)
         return AVERROR_INVALIDDATA;
-    id = AV_RL16(buf);
+    id   = AV_RL16(buf);
     buf += 2;
     if (id == 0x4949)
         le = 1;
@@ -569,18 +584,18 @@ static int decode_frame(AVCodecContext *avctx,
         le = 0;
     else {
         av_log(avctx, AV_LOG_ERROR, "TIFF header not found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
-    s->le = le;
-    s->invert = 0;
-    s->compr = TIFF_RAW;
+    s->le         = le;
+    s->invert     = 0;
+    s->compr      = TIFF_RAW;
     s->fill_order = 0;
     // 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) {
         av_log(avctx, AV_LOG_ERROR,
                "The answer to life, universe and everything is not correct!\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     // Reset these pointers so we can tell if they were set this frame
     s->stripsizes = s->stripdata = NULL;
@@ -590,19 +605,19 @@ static int decode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
         return AVERROR_INVALIDDATA;
     }
-    buf = orig_buf + off;
+    buf     = orig_buf + off;
     entries = tget_short(&buf, le);
     for (i = 0; i < entries; i++) {
-        if (tiff_decode_tag(s, orig_buf, buf, end_buf) < 0)
-            return -1;
+        if ((ret = tiff_decode_tag(s, orig_buf, buf, end_buf)) < 0)
+            return ret;
         buf += 12;
     }
     if (!s->stripdata && !s->stripoff) {
         av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     /* now we have the data and may start decoding */
-    if ((ret = init_image(s)) < 0)
+    if ((ret = init_image(s, p)) < 0)
         return ret;
 
     if (s->strips == 1 && !s->stripsize) {
@@ -610,7 +625,7 @@ static int decode_frame(AVCodecContext *avctx,
         s->stripsize = buf_size - s->stripoff;
     }
     stride = p->linesize[0];
-    dst = p->data[0];
+    dst    = p->data[0];
     for (i = 0; i < s->height; i += s->rps) {
         if (s->stripsizes) {
             if (s->stripsizes >= end_buf)
@@ -628,16 +643,19 @@ static int decode_frame(AVCodecContext *avctx,
 
         if (soff > buf_size || ssize > buf_size - soff) {
             av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
-        if (tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize,
-                              FFMIN(s->rps, s->height - i)) < 0)
+        if ((ret = tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize,
+                                     FFMIN(s->rps, s->height - i))) < 0) {
+            if (avctx->err_recognition & AV_EF_EXPLODE)
+                return ret;
             break;
+        }
         dst += s->rps * stride;
     }
     if (s->predictor == 2) {
-        dst = p->data[0];
-        soff = s->bpp >> 3;
+        dst   = p->data[0];
+        soff  = s->bpp >> 3;
         ssize = s->width * soff;
         for (i = 0; i < s->height; i++) {
             for (j = soff; j < ssize; j++)
@@ -650,14 +668,13 @@ static int decode_frame(AVCodecContext *avctx,
         uint8_t *src;
         int j;
 
-        src = s->picture.data[0];
+        src = p->data[0];
         for (j = 0; j < s->height; j++) {
-            for (i = 0; i < s->picture.linesize[0]; i++)
+            for (i = 0; i < p->linesize[0]; i++)
                 src[i] = 255 - src[i];
-            src += s->picture.linesize[0];
+            src += p->linesize[0];
         }
     }
-    *picture   = s->picture;
     *got_frame = 1;
 
     return buf_size;
@@ -667,11 +684,9 @@ static av_cold int tiff_init(AVCodecContext *avctx)
 {
     TiffContext *s = avctx->priv_data;
 
-    s->width = 0;
+    s->width  = 0;
     s->height = 0;
-    s->avctx = avctx;
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
+    s->avctx  = avctx;
     ff_lzw_decode_open(&s->lzw);
     ff_ccitt_unpack_init();
 
@@ -683,13 +698,12 @@ static av_cold int tiff_end(AVCodecContext *avctx)
     TiffContext *const s = avctx->priv_data;
 
     ff_lzw_decode_close(&s->lzw);
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
     return 0;
 }
 
 AVCodec ff_tiff_decoder = {
     .name           = "tiff",
+    .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TIFF,
     .priv_data_size = sizeof(TiffContext),
@@ -697,5 +711,4 @@ AVCodec ff_tiff_decoder = {
     .close          = tiff_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
 };
diff --git a/libavcodec/tiff.h b/libavcodec/tiff.h
index cf890d6..9052d2f 100644
--- a/libavcodec/tiff.h
+++ b/libavcodec/tiff.h
@@ -31,37 +31,37 @@
 #include <stdint.h>
 
 /** abridged list of TIFF tags */
-enum TiffTags{
-    TIFF_SUBFILE = 0xfe,
-    TIFF_WIDTH = 0x100,
+enum TiffTags {
+    TIFF_SUBFILE            = 0xfe,
+    TIFF_WIDTH              = 0x100,
     TIFF_HEIGHT,
     TIFF_BPP,
     TIFF_COMPR,
-    TIFF_INVERT = 0x106,
-    TIFF_FILL_ORDER = 0x10A,
-    TIFF_STRIP_OFFS = 0x111,
-    TIFF_SAMPLES_PER_PIXEL = 0x115,
-    TIFF_ROWSPERSTRIP = 0x116,
+    TIFF_INVERT             = 0x106,
+    TIFF_FILL_ORDER         = 0x10A,
+    TIFF_STRIP_OFFS         = 0x111,
+    TIFF_SAMPLES_PER_PIXEL  = 0x115,
+    TIFF_ROWSPERSTRIP       = 0x116,
     TIFF_STRIP_SIZE,
-    TIFF_XRES = 0x11A,
-    TIFF_YRES = 0x11B,
-    TIFF_PLANAR = 0x11C,
-    TIFF_XPOS = 0x11E,
-    TIFF_YPOS = 0x11F,
-    TIFF_T4OPTIONS = 0x124,
+    TIFF_XRES               = 0x11A,
+    TIFF_YRES               = 0x11B,
+    TIFF_PLANAR             = 0x11C,
+    TIFF_XPOS               = 0x11E,
+    TIFF_YPOS               = 0x11F,
+    TIFF_T4OPTIONS          = 0x124,
     TIFF_T6OPTIONS,
-    TIFF_RES_UNIT = 0x128,
-    TIFF_SOFTWARE_NAME = 0x131,
-    TIFF_PREDICTOR = 0x13D,
-    TIFF_PAL = 0x140,
+    TIFF_RES_UNIT           = 0x128,
+    TIFF_SOFTWARE_NAME      = 0x131,
+    TIFF_PREDICTOR          = 0x13D,
+    TIFF_PAL                = 0x140,
     TIFF_YCBCR_COEFFICIENTS = 0x211,
-    TIFF_YCBCR_SUBSAMPLING = 0x212,
-    TIFF_YCBCR_POSITIONING = 0x213,
-    TIFF_REFERENCE_BW = 0x214,
+    TIFF_YCBCR_SUBSAMPLING  = 0x212,
+    TIFF_YCBCR_POSITIONING  = 0x213,
+    TIFF_REFERENCE_BW       = 0x214,
 };
 
 /** list of TIFF compression types */
-enum TiffCompr{
+enum TiffCompr {
     TIFF_RAW = 1,
     TIFF_CCITT_RLE,
     TIFF_G3,
@@ -71,10 +71,10 @@ enum TiffCompr{
     TIFF_NEWJPEG,
     TIFF_ADOBE_DEFLATE,
     TIFF_PACKBITS = 0x8005,
-    TIFF_DEFLATE = 0x80B2
+    TIFF_DEFLATE  = 0x80B2
 };
 
-enum TiffTypes{
+enum TiffTypes {
     TIFF_BYTE = 1,
     TIFF_STRING,
     TIFF_SHORT,
diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index 8162c40..4cbc517 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -25,20 +25,20 @@
  * @author Bartlomiej Wolowiec
  */
 
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
-
-#include "avcodec.h"
 #include "config.h"
 #if CONFIG_ZLIB
 #include <zlib.h>
 #endif
+
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avcodec.h"
 #include "bytestream.h"
-#include "tiff.h"
-#include "rle.h"
 #include "lzw.h"
 #include "put_bits.h"
+#include "rle.h"
+#include "tiff.h"
 
 #define TIFF_MAX_ENTRY 32
 
@@ -48,27 +48,25 @@ static const uint8_t type_sizes2[6] = {
 };
 
 typedef struct TiffEncoderContext {
-    AVClass *class;                     ///< for private options
+    AVClass *class;                         ///< for private options
     AVCodecContext *avctx;
-    AVFrame picture;
-
-    int width;                          ///< picture width
-    int height;                         ///< picture height
-    unsigned int bpp;                   ///< bits per pixel
-    int compr;                          ///< compression level
-    int bpp_tab_size;                   ///< bpp_tab size
-    int photometric_interpretation;     ///< photometric interpretation
-    int strips;                         ///< number of strips
-    int rps;                            ///< row per strip
-    uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header
-    int num_entries;                    ///< number of entires
-    uint8_t **buf;                      ///< actual position in buffer
-    uint8_t *buf_start;                 ///< pointer to first byte in buffer
-    int buf_size;                       ///< buffer size
-    uint16_t subsampling[2];            ///< YUV subsampling factors
-    struct LZWEncodeState *lzws;        ///< LZW Encode state
-} TiffEncoderContext;
 
+    int width;                              ///< picture width
+    int height;                             ///< picture height
+    unsigned int bpp;                       ///< bits per pixel
+    int compr;                              ///< compression level
+    int bpp_tab_size;                       ///< bpp_tab size
+    int photometric_interpretation;         ///< photometric interpretation
+    int strips;                             ///< number of strips
+    int rps;                                ///< row per strip
+    uint8_t entries[TIFF_MAX_ENTRY * 12];   ///< entries in header
+    int num_entries;                        ///< number of entries
+    uint8_t **buf;                          ///< actual position in buffer
+    uint8_t *buf_start;                     ///< pointer to first byte in buffer
+    int buf_size;                           ///< buffer size
+    uint16_t subsampling[2];                ///< YUV subsampling factors
+    struct LZWEncodeState *lzws;            ///< LZW encode state
+} TiffEncoderContext;
 
 /**
  * Check free space in buffer
@@ -76,7 +74,7 @@ typedef struct TiffEncoderContext {
  * @param need Needed bytes
  * @return 0 - ok, 1 - no free space
  */
-static inline int check_size(TiffEncoderContext * s, uint64_t need)
+static inline int check_size(TiffEncoderContext *s, uint64_t need)
 {
     if (s->buf_size < *s->buf - s->buf_start + need) {
         *s->buf = s->buf_start + s->buf_size + 1;
@@ -95,12 +93,12 @@ static inline int check_size(TiffEncoderContext * s, uint64_t need)
  * @param type Type of values
  * @param flip =0 - normal copy, >0 - flip
  */
-static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type,
+static void tnput(uint8_t **p, int n, const uint8_t *val, enum TiffTypes type,
                   int flip)
 {
     int i;
 #if HAVE_BIGENDIAN
-    flip ^= ((int[]) {0, 0, 0, 1, 3, 3})[type];
+    flip ^= ((int[]) { 0, 0, 0, 1, 3, 3 })[type];
 #endif
     for (i = 0; i < n * type_sizes2[type]; i++)
         *(*p)++ = val[i ^ flip];
@@ -114,9 +112,8 @@ static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes 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,
-                      const void *ptr_val)
+static void add_entry(TiffEncoderContext *s, enum TiffTags tag,
+                      enum TiffTypes type, int count, const void *ptr_val)
 {
     uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
 
@@ -137,10 +134,11 @@ static void add_entry(TiffEncoderContext * s,
     s->num_entries++;
 }
 
-static void add_entry1(TiffEncoderContext * s,
-                       enum TiffTags tag, enum TiffTypes type, int val){
-    uint16_t w = val;
-    uint32_t dw= val;
+static void add_entry1(TiffEncoderContext *s,
+                       enum TiffTags tag, enum TiffTypes type, int val)
+{
+    uint16_t w  = val;
+    uint32_t dw = val;
     add_entry(s, tag, type, 1, type == TIFF_SHORT ? (void *)&w : (void *)&dw);
 }
 
@@ -154,22 +152,21 @@ static void add_entry1(TiffEncoderContext * s,
  * @param compr Compression method
  * @return Number of output bytes. If an output error is encountered, -1 returned
  */
-static int encode_strip(TiffEncoderContext * s, const int8_t * src,
-                        uint8_t * dst, int n, int compr)
+static int encode_strip(TiffEncoderContext *s, const int8_t *src,
+                        uint8_t *dst, int n, int compr)
 {
-
     switch (compr) {
 #if CONFIG_ZLIB
     case TIFF_DEFLATE:
     case TIFF_ADOBE_DEFLATE:
-        {
-            unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
-            if (compress(dst, &zlen, src, n) != Z_OK) {
-                av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
-                return -1;
-            }
-            return zlen;
+    {
+        unsigned long zlen = s->buf_size - (*s->buf - s->buf_start);
+        if (compress(dst, &zlen, src, n) != Z_OK) {
+            av_log(s->avctx, AV_LOG_ERROR, "Compressing failed\n");
+            return -1;
         }
+        return zlen;
+    }
 #endif
     case TIFF_RAW:
         if (check_size(s, n))
@@ -177,7 +174,8 @@ static int encode_strip(TiffEncoderContext * s, const int8_t * src,
         memcpy(dst, src, n);
         return n;
     case TIFF_PACKBITS:
-        return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start), src, 1, n, 2, 0xff, -1, 0);
+        return ff_rle_encode(dst, s->buf_size - (*s->buf - s->buf_start),
+                             src, 1, n, 2, 0xff, -1, 0);
     case TIFF_LZW:
         return ff_lzw_encode(s->lzws, src, n);
     default:
@@ -185,14 +183,14 @@ static int encode_strip(TiffEncoderContext * s, const int8_t * src,
     }
 }
 
-static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum)
+static void pack_yuv(TiffEncoderContext *s, const AVFrame *p,
+                     uint8_t *dst, int lnum)
 {
-    AVFrame *p = &s->picture;
     int i, j, k;
-    int w = (s->width - 1) / s->subsampling[0] + 1;
+    int w       = (s->width - 1) / s->subsampling[0] + 1;
     uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
     uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
-    for (i = 0; i < w; i++){
+    for (i = 0; i < w; i++) {
         for (j = 0; j < s->subsampling[1]; j++)
             for (k = 0; k < s->subsampling[0]; k++)
                 *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
@@ -202,35 +200,30 @@ static void pack_yuv(TiffEncoderContext * s, uint8_t * dst, int lnum)
     }
 }
 
-static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *pict, int *got_packet)
 {
     TiffEncoderContext *s = avctx->priv_data;
-    AVFrame *const p = &s->picture;
+    const AVFrame *const p = pict;
     int i;
     uint8_t *ptr;
     uint8_t *offset;
     uint32_t strips;
-    uint32_t *strip_sizes = NULL;
+    uint32_t *strip_sizes   = NULL;
     uint32_t *strip_offsets = NULL;
     int bytes_per_row;
-    uint32_t res[2] = { 72, 1 };        // image resolution (72/1)
+    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;
     int shift_h, shift_v;
-    const AVPixFmtDescriptor* pfd;
+    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->width          = avctx->width;
+    s->height         = avctx->height;
     s->subsampling[0] = 1;
     s->subsampling[1] = 1;
 
@@ -240,43 +233,40 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
     case AV_PIX_FMT_RGB24:
     case AV_PIX_FMT_GRAY8:
     case AV_PIX_FMT_PAL8:
-        pfd = av_pix_fmt_desc_get(avctx->pix_fmt);
+        pfd    = av_pix_fmt_desc_get(avctx->pix_fmt);
         s->bpp = av_get_bits_per_pixel(pfd);
-        if (pfd->flags & PIX_FMT_PAL) {
+        if (pfd->flags & AV_PIX_FMT_FLAG_PAL)
             s->photometric_interpretation = 3;
-        } else if (pfd->flags & PIX_FMT_RGB) {
+        else if (pfd->flags & AV_PIX_FMT_FLAG_RGB)
             s->photometric_interpretation = 2;
-        } else {
+        else
             s->photometric_interpretation = 1;
-        }
         s->bpp_tab_size = pfd->nb_components;
-        for (i = 0; i < s->bpp_tab_size; i++) {
+        for (i = 0; i < s->bpp_tab_size; i++)
             bpp_tab[i] = s->bpp / s->bpp_tab_size;
-        }
         break;
     case AV_PIX_FMT_MONOBLACK:
-        s->bpp = 1;
+        s->bpp                        = 1;
         s->photometric_interpretation = 1;
-        s->bpp_tab_size = 0;
+        s->bpp_tab_size               = 0;
         break;
     case AV_PIX_FMT_MONOWHITE:
-        s->bpp = 1;
+        s->bpp                        = 1;
         s->photometric_interpretation = 0;
-        s->bpp_tab_size = 0;
+        s->bpp_tab_size               = 0;
         break;
     case AV_PIX_FMT_YUV420P:
     case AV_PIX_FMT_YUV422P:
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUV410P:
     case AV_PIX_FMT_YUV411P:
+        av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &shift_h, &shift_v);
         s->photometric_interpretation = 6;
-        av_pix_fmt_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;
+        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:
         av_log(s->avctx, AV_LOG_ERROR,
@@ -284,18 +274,23 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
         return -1;
     }
 
-    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)
-        //best choose for DEFLATE
+    if (s->compr == TIFF_DEFLATE       ||
+        s->compr == TIFF_ADOBE_DEFLATE ||
+        s->compr == TIFF_LZW)
+        // best choice for DEFLATE
         s->rps = s->height;
     else
-        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);     // suggest size of strip
-    s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up
+        // suggest size of strip
+        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);
+    // round rps up
+    s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1];
 
     strips = (s->height - 1) / s->rps + 1;
 
     if (!pkt->data &&
-        (ret = av_new_packet(pkt, avctx->width * avctx->height * s->bpp * 2 +
-                                  avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0) {
+        (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");
         return ret;
     }
@@ -314,18 +309,18 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
     offset = ptr;
     bytestream_put_le32(&ptr, 0);
 
-    strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips);
+    strip_sizes   = av_mallocz(sizeof(*strip_sizes)   * strips);
     strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips);
     if (!strip_sizes || !strip_offsets) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
 
-    bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp
-                    * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
-    if (is_yuv){
+    bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp *
+                     s->subsampling[0] * s->subsampling[1] + 7) >> 3;
+    if (is_yuv) {
         yuv_line = av_malloc(bytes_per_row);
-        if (yuv_line == NULL){
+        if (yuv_line == NULL) {
             av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
             ret = AVERROR(ENOMEM);
             goto fail;
@@ -345,14 +340,13 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
             goto fail;
         }
         strip_offsets[0] = ptr - pkt->data;
-        zn = 0;
+        zn               = 0;
         for (j = 0; j < s->rps; j++) {
-            if (is_yuv){
-                pack_yuv(s, yuv_line, j);
+            if (is_yuv) {
+                pack_yuv(s, p, yuv_line, j);
                 memcpy(zbuf + zn, yuv_line, bytes_per_row);
                 j += s->subsampling[1] - 1;
-            }
-            else
+            } else
                 memcpy(zbuf + j * bytes_per_row,
                        p->data[0] + j * p->linesize[0], bytes_per_row);
             zn += bytes_per_row;
@@ -363,93 +357,93 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
             av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
             goto fail;
         }
-        ptr += ret;
+        ptr           += ret;
         strip_sizes[0] = ptr - pkt->data - strip_offsets[0];
     } else
 #endif
-    {
-        if (s->compr == TIFF_LZW) {
-            s->lzws = av_malloc(ff_lzw_encode_state_size);
-            if (!s->lzws) {
-                ret = AVERROR(ENOMEM);
-                goto fail;
-            }
+    if (s->compr == TIFF_LZW) {
+        s->lzws = av_malloc(ff_lzw_encode_state_size);
+        if (!s->lzws) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
         }
-        for (i = 0; i < s->height; i++) {
-            if (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;
-            }
-            if (is_yuv){
-                 pack_yuv(s, yuv_line, i);
-                 ret = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr);
-                 i += s->subsampling[1] - 1;
-            }
-            else
-                ret = encode_strip(s, p->data[0] + i * p->linesize[0],
-                        ptr, bytes_per_row, s->compr);
-            if (ret < 0) {
-                av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
-                goto fail;
-            }
-            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 ;
-                ptr += ret;
+    }
+    for (i = 0; i < s->height; i++) {
+        if (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;
+        }
+        if (is_yuv) {
+            pack_yuv(s, p, yuv_line, i);
+            ret = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr);
+            i  += s->subsampling[1] - 1;
+        } else
+            ret = encode_strip(s, p->data[0] + i * p->linesize[0],
+                               ptr, bytes_per_row, s->compr);
+        if (ret < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
+            goto fail;
+        }
+        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;
+            ptr                       += ret;
         }
-        if(s->compr == TIFF_LZW)
-            av_free(s->lzws);
     }
+    if (s->compr == TIFF_LZW)
+        av_free(s->lzws);
 
     s->num_entries = 0;
 
-    add_entry1(s,TIFF_SUBFILE,           TIFF_LONG,             0);
-    add_entry1(s,TIFF_WIDTH,             TIFF_LONG,             s->width);
-    add_entry1(s,TIFF_HEIGHT,            TIFF_LONG,             s->height);
+    add_entry1(s, TIFF_SUBFILE, TIFF_LONG, 0);
+    add_entry1(s, TIFF_WIDTH,   TIFF_LONG, s->width);
+    add_entry1(s, TIFF_HEIGHT,  TIFF_LONG, s->height);
 
     if (s->bpp_tab_size)
-    add_entry(s, TIFF_BPP,               TIFF_SHORT,    s->bpp_tab_size, bpp_tab);
+        add_entry(s, TIFF_BPP, TIFF_SHORT, s->bpp_tab_size, bpp_tab);
 
-    add_entry1(s,TIFF_COMPR,             TIFF_SHORT,            s->compr);
-    add_entry1(s,TIFF_INVERT,            TIFF_SHORT,            s->photometric_interpretation);
-    add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, strip_offsets);
+    add_entry1(s, TIFF_COMPR,      TIFF_SHORT, s->compr);
+    add_entry1(s, TIFF_INVERT,     TIFF_SHORT, s->photometric_interpretation);
+    add_entry(s,  TIFF_STRIP_OFFS, TIFF_LONG,  strips, strip_offsets);
 
     if (s->bpp_tab_size)
-    add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT,            s->bpp_tab_size);
+        add_entry1(s, TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT, s->bpp_tab_size);
 
-    add_entry1(s,TIFF_ROWSPERSTRIP,      TIFF_LONG,             s->rps);
-    add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, strip_sizes);
-    add_entry(s, TIFF_XRES,              TIFF_RATIONAL, 1,      res);
-    add_entry(s, TIFF_YRES,              TIFF_RATIONAL, 1,      res);
-    add_entry1(s,TIFF_RES_UNIT,          TIFF_SHORT,            2);
+    add_entry1(s, TIFF_ROWSPERSTRIP, TIFF_LONG,     s->rps);
+    add_entry(s,  TIFF_STRIP_SIZE,   TIFF_LONG,     strips, strip_sizes);
+    add_entry(s,  TIFF_XRES,         TIFF_RATIONAL, 1,      res);
+    add_entry(s,  TIFF_YRES,         TIFF_RATIONAL, 1,      res);
+    add_entry1(s, TIFF_RES_UNIT,     TIFF_SHORT,    2);
 
-    if(!(avctx->flags & CODEC_FLAG_BITEXACT))
-    add_entry(s, TIFF_SOFTWARE_NAME,     TIFF_STRING,
-              strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
+    if (!(avctx->flags & CODEC_FLAG_BITEXACT))
+        add_entry(s, TIFF_SOFTWARE_NAME, TIFF_STRING,
+                  strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);
 
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         uint16_t pal[256 * 3];
         for (i = 0; i < 256; i++) {
             uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4);
             pal[i]       = ((rgb >> 16) & 0xff) * 257;
-            pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257;
-            pal[i + 512] = ( rgb        & 0xff) * 257;
+            pal[i + 256] = ((rgb >>  8) & 0xff) * 257;
+            pal[i + 512] =  (rgb        & 0xff) * 257;
         }
         add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
     }
-    if (is_yuv){
+    if (is_yuv) {
         /** according to CCIR Recommendation 601.1 */
-        uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1};
+        uint32_t refbw[12] = { 15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1 };
         add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT,    2, s->subsampling);
         add_entry(s, TIFF_REFERENCE_BW,      TIFF_RATIONAL, 6, refbw);
     }
-    bytestream_put_le32(&offset, ptr - pkt->data);    // write offset to dir
+    // write offset to dir
+    bytestream_put_le32(&offset, ptr - pkt->data);
 
     if (check_size(s, 6 + s->num_entries * 12)) {
         ret = AVERROR(EINVAL);
@@ -470,15 +464,33 @@ fail:
     return ret;
 }
 
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+
+    return 0;
+}
+
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    av_frame_free(&avctx->coded_frame);
+    return 0;
+}
+
 #define OFFSET(x) offsetof(TiffEncoderContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {.i64 = TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
-    { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_PACKBITS}, 0, 0, VE, "compression_algo" },
-    { "raw",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_RAW},      0, 0, VE, "compression_algo" },
-    { "lzw",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_LZW},      0, 0, VE, "compression_algo" },
+    { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT,   { .i64 = TIFF_PACKBITS }, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
+    { "packbits",         NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_PACKBITS }, 0,        0,            VE, "compression_algo" },
+    { "raw",              NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_RAW      }, 0,        0,            VE, "compression_algo" },
+    { "lzw",              NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_LZW      }, 0,        0,            VE, "compression_algo" },
 #if CONFIG_ZLIB
-    { "deflate",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_DEFLATE},  0, 0, VE, "compression_algo" },
+    { "deflate",          NULL, 0,             AV_OPT_TYPE_CONST, { .i64 = TIFF_DEFLATE  }, 0,        0,            VE, "compression_algo" },
 #endif
     { NULL },
 };
@@ -492,9 +504,12 @@ static const AVClass tiffenc_class = {
 
 AVCodec ff_tiff_encoder = {
     .name           = "tiff",
+    .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TIFF,
     .priv_data_size = sizeof(TiffEncoderContext),
+    .init           = encode_init,
+    .close          = encode_close,
     .encode2        = encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]) {
         AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48LE, AV_PIX_FMT_PAL8,
@@ -504,6 +519,5 @@ AVCodec ff_tiff_encoder = {
         AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
         AV_PIX_FMT_NONE
     },
-    .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
     .priv_class     = &tiffenc_class,
 };
diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c
index d4e5aa1..f04a5f5 100644
--- a/libavcodec/tmv.c
+++ b/libavcodec/tmv.c
@@ -34,55 +34,49 @@
 
 #include "cga_data.h"
 
-typedef struct TMVContext {
-    AVFrame pic;
-} TMVContext;
-
 static int tmv_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
-    TMVContext *tmv    = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *src = avpkt->data;
     uint8_t *dst;
     unsigned char_cols = avctx->width >> 3;
     unsigned char_rows = avctx->height >> 3;
     unsigned x, y, fg, bg, c;
+    int ret;
 
-    if (tmv->pic.data[0])
-        avctx->release_buffer(avctx, &tmv->pic);
-
-    if (ff_get_buffer(avctx, &tmv->pic) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (avpkt->size < 2*char_rows*char_cols) {
         av_log(avctx, AV_LOG_ERROR,
                "Input buffer too small, truncated sample?\n");
         *got_frame = 0;
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    tmv->pic.pict_type = AV_PICTURE_TYPE_I;
-    tmv->pic.key_frame = 1;
-    dst                = tmv->pic.data[0];
+    frame->pict_type = AV_PICTURE_TYPE_I;
+    frame->key_frame = 1;
+    dst              = frame->data[0];
 
-    tmv->pic.palette_has_changed = 1;
-    memcpy(tmv->pic.data[1], ff_cga_palette, 16 * 4);
+    frame->palette_has_changed = 1;
+    memcpy(frame->data[1], ff_cga_palette, 16 * 4);
 
     for (y = 0; y < char_rows; y++) {
         for (x = 0; x < char_cols; x++) {
             c  = *src++;
             bg = *src  >> 4;
             fg = *src++ & 0xF;
-            ff_draw_pc_font(dst + x * 8, tmv->pic.linesize[0],
+            ff_draw_pc_font(dst + x * 8, frame->linesize[0],
                             ff_cga_font, 8, c, fg, bg);
         }
-        dst += tmv->pic.linesize[0] * 8;
+        dst += frame->linesize[0] * 8;
     }
 
     *got_frame = 1;
-    *(AVFrame *)data = tmv->pic;
+
     return avpkt->size;
 }
 
@@ -92,24 +86,12 @@ static av_cold int tmv_decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int tmv_decode_close(AVCodecContext *avctx)
-{
-    TMVContext *tmv = avctx->priv_data;
-
-    if (tmv->pic.data[0])
-        avctx->release_buffer(avctx, &tmv->pic);
-
-    return 0;
-}
-
 AVCodec ff_tmv_decoder = {
     .name           = "tmv",
+    .long_name      = NULL_IF_CONFIG_SMALL("8088flex TMV"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TMV,
-    .priv_data_size = sizeof(TMVContext),
     .init           = tmv_decode_init,
-    .close          = tmv_decode_close,
     .decode         = tmv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("8088flex TMV"),
 };
diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c
index c49f9fe..b1497d5 100644
--- a/libavcodec/truemotion1.c
+++ b/libavcodec/truemotion1.c
@@ -34,16 +34,17 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
+#include "internal.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/mem.h"
 
 #include "truemotion1data.h"
 
 typedef struct TrueMotion1Context {
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     const uint8_t *buf;
     int size;
@@ -308,7 +309,7 @@ static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_
  * there was an error while decoding the header */
 static int truemotion1_decode_header(TrueMotion1Context *s)
 {
-    int i;
+    int i, ret;
     int width_shift = 0;
     int new_pix_fmt;
     struct frame_header header;
@@ -319,7 +320,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
     if (s->buf[0] < 0x10)
     {
         av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     /* unscramble the header bytes with a XOR operation */
@@ -343,7 +344,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
         if (header.header_type > 3)
         {
             av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type);
-            return -1;
+            return AVERROR_INVALIDDATA;
         } else if ((header.header_type == 2) || (header.header_type == 3)) {
             s->flags = header.flags;
             if (!(s->flags & FLAG_INTERFRAME))
@@ -354,7 +355,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
         s->flags = FLAG_KEYFRAME;
 
     if (s->flags & FLAG_SPRITE) {
-        av_log_ask_for_sample(s->avctx, "SPRITE frame found.\n");
+        avpriv_request_sample(s->avctx, "Frame with sprite");
         /* FIXME header.width, height, xoffset and yoffset aren't initialized */
         return AVERROR_PATCHWELCOME;
     } else {
@@ -364,14 +365,14 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
             if ((s->w < 213) && (s->h >= 176))
             {
                 s->flags |= FLAG_INTERPOLATED;
-                av_log_ask_for_sample(s->avctx, "INTERPOLATION selected.\n");
+                avpriv_request_sample(s->avctx, "Interpolated frame");
             }
         }
     }
 
     if (header.compression >= 17) {
         av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if ((header.deltaset != s->last_deltaset) ||
@@ -385,7 +386,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
             sel_vector_table = tables[header.vectable - 1];
         else {
             av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -396,16 +397,16 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
         new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
 
     s->w >>= width_shift;
-    if (av_image_check_size(s->w, s->h, 0, s->avctx) < 0)
-        return -1;
 
     if (s->w != s->avctx->width || s->h != s->avctx->height ||
         new_pix_fmt != s->avctx->pix_fmt) {
-        if (s->frame.data[0])
-            s->avctx->release_buffer(s->avctx, &s->frame);
+        av_frame_unref(s->frame);
         s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
         s->avctx->pix_fmt = new_pix_fmt;
-        avcodec_set_dimensions(s->avctx, s->w, s->h);
+
+        if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
+            return ret;
+
         av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
     }
 
@@ -468,7 +469,9 @@ static av_cold int truemotion1_decode_init(AVCodecContext *avctx)
 //    else
 //        avctx->pix_fmt = AV_PIX_FMT_RGB555;
 
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     /* there is a vertical predictor for each pixel in a line; each vertical
      * predictor is 0 to start with */
@@ -512,6 +515,15 @@ hres,vres,i,i%vres (0 < i < 4)
     index = s->index_stream[index_stream_index++] * 4; \
 }
 
+#define INC_INDEX                                                   \
+do {                                                                \
+    if (index >= 1023) {                                            \
+        av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n");   \
+        return;                                                     \
+    }                                                               \
+    index++;                                                        \
+} while (0)
+
 #define APPLY_C_PREDICTOR() \
     predictor_pair = s->c_predictor_table[index]; \
     horiz_pred += (predictor_pair >> 1); \
@@ -524,10 +536,10 @@ hres,vres,i,i%vres (0 < i < 4)
             if (predictor_pair & 1) \
                 GET_NEXT_INDEX() \
             else \
-                index++; \
+                INC_INDEX; \
         } \
     } else \
-        index++;
+        INC_INDEX;
 
 #define APPLY_C_PREDICTOR_24() \
     predictor_pair = s->c_predictor_table[index]; \
@@ -541,10 +553,10 @@ hres,vres,i,i%vres (0 < i < 4)
             if (predictor_pair & 1) \
                 GET_NEXT_INDEX() \
             else \
-                index++; \
+                INC_INDEX; \
         } \
     } else \
-        index++;
+        INC_INDEX;
 
 
 #define APPLY_Y_PREDICTOR() \
@@ -559,10 +571,10 @@ hres,vres,i,i%vres (0 < i < 4)
             if (predictor_pair & 1) \
                 GET_NEXT_INDEX() \
             else \
-                index++; \
+                INC_INDEX; \
         } \
     } else \
-        index++;
+        INC_INDEX;
 
 #define APPLY_Y_PREDICTOR_24() \
     predictor_pair = s->y_predictor_table[index]; \
@@ -576,10 +588,10 @@ hres,vres,i,i%vres (0 < i < 4)
             if (predictor_pair & 1) \
                 GET_NEXT_INDEX() \
             else \
-                index++; \
+                INC_INDEX; \
         } \
     } else \
-        index++;
+        INC_INDEX;
 
 #define OUTPUT_PIXEL_PAIR() \
     *current_pixel_pair = *vert_pred + horiz_pred; \
@@ -593,7 +605,7 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s)
     unsigned int horiz_pred;
     unsigned int *vert_pred;
     unsigned int *current_pixel_pair;
-    unsigned char *current_line = s->frame.data[0];
+    unsigned char *current_line = s->frame->data[0];
     int keyframe = s->flags & FLAG_KEYFRAME;
 
     /* these variables are for managing the stream of macroblock change bits */
@@ -707,7 +719,7 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s)
         if (((y + 1) & 3) == 0)
             mb_change_bits += s->mb_change_bits_row_size;
 
-        current_line += s->frame.linesize[0];
+        current_line += s->frame->linesize[0];
     }
 }
 
@@ -719,7 +731,7 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s)
     unsigned int horiz_pred;
     unsigned int *vert_pred;
     unsigned int *current_pixel_pair;
-    unsigned char *current_line = s->frame.data[0];
+    unsigned char *current_line = s->frame->data[0];
     int keyframe = s->flags & FLAG_KEYFRAME;
 
     /* these variables are for managing the stream of macroblock change bits */
@@ -833,7 +845,7 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s)
         if (((y + 1) & 3) == 0)
             mb_change_bits += s->mb_change_bits_row_size;
 
-        current_line += s->frame.linesize[0];
+        current_line += s->frame->linesize[0];
     }
 }
 
@@ -843,21 +855,18 @@ static int truemotion1_decode_frame(AVCodecContext *avctx,
                                     AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    int ret, buf_size = avpkt->size;
     TrueMotion1Context *s = avctx->priv_data;
 
     s->buf = buf;
     s->size = buf_size;
 
-    if (truemotion1_decode_header(s) == -1)
-        return -1;
+    if ((ret = truemotion1_decode_header(s)) < 0)
+        return ret;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
-        FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
@@ -866,8 +875,10 @@ static int truemotion1_decode_frame(AVCodecContext *avctx,
         truemotion1_decode_16bit(s);
     }
 
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -877,9 +888,7 @@ static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
 {
     TrueMotion1Context *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
+    av_frame_free(&s->frame);
     av_free(s->vert_pred);
 
     return 0;
@@ -887,6 +896,7 @@ static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_truemotion1_decoder = {
     .name           = "truemotion1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TRUEMOTION1,
     .priv_data_size = sizeof(TrueMotion1Context),
@@ -894,5 +904,4 @@ AVCodec ff_truemotion1_decoder = {
     .close          = truemotion1_decode_end,
     .decode         = truemotion1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
 };
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index 7691989..e41d7a3 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -28,19 +28,37 @@
 #include "bytestream.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
 
 #define TM2_ESCAPE 0x80000000
 #define TM2_DELTAS 64
+
 /* Huffman-coded streams of different types of blocks */
-enum TM2_STREAMS{ TM2_C_HI = 0, TM2_C_LO, TM2_L_HI, TM2_L_LO,
-     TM2_UPD, TM2_MOT, TM2_TYPE, TM2_NUM_STREAMS};
+enum TM2_STREAMS {
+    TM2_C_HI = 0,
+    TM2_C_LO,
+    TM2_L_HI,
+    TM2_L_LO,
+    TM2_UPD,
+    TM2_MOT,
+    TM2_TYPE,
+    TM2_NUM_STREAMS
+};
+
 /* Block types */
-enum TM2_BLOCKS{ TM2_HI_RES = 0, TM2_MED_RES, TM2_LOW_RES, TM2_NULL_RES,
-                 TM2_UPDATE, TM2_STILL, TM2_MOTION};
+enum TM2_BLOCKS {
+    TM2_HI_RES = 0,
+    TM2_MED_RES,
+    TM2_LOW_RES,
+    TM2_NULL_RES,
+    TM2_UPDATE,
+    TM2_STILL,
+    TM2_MOTION
+};
 
-typedef struct TM2Context{
+typedef struct TM2Context {
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *pic;
 
     GetBitContext gb;
     DSPContext dsp;
@@ -66,7 +84,7 @@ typedef struct TM2Context{
 /**
 * Huffman codes for each of streams
 */
-typedef struct TM2Codes{
+typedef struct TM2Codes {
     VLC vlc; ///< table for Libav bitstream reader
     int bits;
     int *recode; ///< table for converting from code indexes to values
@@ -76,7 +94,7 @@ typedef struct TM2Codes{
 /**
 * structure for gathering Huffman codes information
 */
-typedef struct TM2Huff{
+typedef struct TM2Huff {
     int val_bits; ///< length of literal
     int max_bits; ///< maximum length of code
     int min_bits; ///< minimum length of code
@@ -90,18 +108,20 @@ typedef struct TM2Huff{
 
 static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *huff)
 {
-    if(length > huff->max_bits) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n", huff->max_bits);
-        return -1;
+    int ret;
+    if (length > huff->max_bits) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n",
+               huff->max_bits);
+        return AVERROR_INVALIDDATA;
     }
 
-    if(!get_bits1(&ctx->gb)) { /* literal */
+    if (!get_bits1(&ctx->gb)) { /* literal */
         if (length == 0) {
             length = 1;
         }
-        if(huff->num >= huff->max_num) {
+        if (huff->num >= huff->max_num) {
             av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         huff->nums[huff->num] = get_bits_long(&ctx->gb, huff->val_bits);
         huff->bits[huff->num] = prefix;
@@ -109,10 +129,10 @@ static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *
         huff->num++;
         return 0;
     } else { /* non-terminal node */
-        if(tm2_read_tree(ctx, prefix << 1, length + 1, huff) == -1)
-            return -1;
-        if(tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff) == -1)
-            return -1;
+        if ((ret = tm2_read_tree(ctx, prefix << 1, length + 1, huff)) < 0)
+            return ret;
+        if ((ret = tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff)) < 0)
+            return ret;
     }
     return 0;
 }
@@ -125,56 +145,53 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code)
     huff.val_bits = get_bits(&ctx->gb, 5);
     huff.max_bits = get_bits(&ctx->gb, 5);
     huff.min_bits = get_bits(&ctx->gb, 5);
-    huff.nodes = get_bits_long(&ctx->gb, 17);
-    huff.num = 0;
+    huff.nodes    = get_bits_long(&ctx->gb, 17);
+    huff.num      = 0;
 
     /* check for correct codes parameters */
-    if((huff.val_bits < 1) || (huff.val_bits > 32) ||
-       (huff.max_bits < 0) || (huff.max_bits > 25)) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal length: %i, max code length: %i\n",
-               huff.val_bits, huff.max_bits);
-        return -1;
+    if ((huff.val_bits < 1) || (huff.val_bits > 32) ||
+        (huff.max_bits < 0) || (huff.max_bits > 25)) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal "
+               "length: %i, max code length: %i\n", huff.val_bits, huff.max_bits);
+        return AVERROR_INVALIDDATA;
     }
-    if((huff.nodes <= 0) || (huff.nodes > 0x10000)) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes);
-        return -1;
+    if ((huff.nodes <= 0) || (huff.nodes > 0x10000)) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree "
+               "nodes: %i\n", huff.nodes);
+        return AVERROR_INVALIDDATA;
     }
     /* one-node tree */
-    if(huff.max_bits == 0)
+    if (huff.max_bits == 0)
         huff.max_bits = 1;
 
     /* allocate space for codes - it is exactly ceil(nodes / 2) entries */
     huff.max_num = (huff.nodes + 1) >> 1;
-    huff.nums = av_mallocz(huff.max_num * sizeof(int));
-    huff.bits = av_mallocz(huff.max_num * sizeof(uint32_t));
-    huff.lens = av_mallocz(huff.max_num * sizeof(int));
+    huff.nums    = av_mallocz(huff.max_num * sizeof(int));
+    huff.bits    = av_mallocz(huff.max_num * sizeof(uint32_t));
+    huff.lens    = av_mallocz(huff.max_num * sizeof(int));
 
-    if(tm2_read_tree(ctx, 0, 0, &huff) == -1)
-        res = -1;
+    res = tm2_read_tree(ctx, 0, 0, &huff);
 
-    if(huff.num != huff.max_num) {
+    if (huff.num != huff.max_num) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Got less codes than expected: %i of %i\n",
                huff.num, huff.max_num);
-        res = -1;
+        res = AVERROR_INVALIDDATA;
     }
 
     /* convert codes to vlc_table */
-    if(res != -1) {
+    if (res >= 0) {
         int i;
 
         res = init_vlc(&code->vlc, huff.max_bits, huff.max_num,
-                    huff.lens, sizeof(int), sizeof(int),
-                    huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0);
-        if(res < 0) {
+                       huff.lens, sizeof(int), sizeof(int),
+                       huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0);
+        if (res < 0)
             av_log(ctx->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
-            res = -1;
-        } else
-            res = 0;
-        if(res != -1) {
+        else {
             code->bits = huff.max_bits;
             code->length = huff.max_num;
             code->recode = av_malloc(code->length * sizeof(int));
-            for(i = 0; i < code->length; i++)
+            for (i = 0; i < code->length; i++)
                 code->recode[i] = huff.nums[i];
         }
     }
@@ -189,7 +206,7 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code)
 static void tm2_free_codes(TM2Codes *code)
 {
     av_free(code->recode);
-    if(code->vlc.table)
+    if (code->vlc.table)
         ff_free_vlc(&code->vlc);
 }
 
@@ -209,7 +226,7 @@ static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf)
 
     switch (magic) {
     case TM2_OLD_HEADER_MAGIC:
-        av_log_missing_feature(ctx->avctx, "TM2 old header", 1);
+        avpriv_request_sample(ctx->avctx, "Old TM2 header");
         return 0;
     case TM2_NEW_HEADER_MAGIC:
         return 0;
@@ -219,26 +236,27 @@ static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf)
     }
 }
 
-static int tm2_read_deltas(TM2Context *ctx, int stream_id) {
+static int tm2_read_deltas(TM2Context *ctx, int stream_id)
+{
     int d, mb;
     int i, v;
 
-    d = get_bits(&ctx->gb, 9);
+    d  = get_bits(&ctx->gb, 9);
     mb = get_bits(&ctx->gb, 5);
 
-    if((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) {
+    if ((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    for(i = 0; i < d; i++) {
+    for (i = 0; i < d; i++) {
         v = get_bits_long(&ctx->gb, mb);
-        if(v & (1 << (mb - 1)))
+        if (v & (1 << (mb - 1)))
             ctx->deltas[stream_id][i] = v - (1 << mb);
         else
             ctx->deltas[stream_id][i] = v;
     }
-    for(; i < TM2_DELTAS; i++)
+    for (; i < TM2_DELTAS; i++)
         ctx->deltas[stream_id][i] = 0;
 
     return 0;
@@ -246,7 +264,7 @@ static int tm2_read_deltas(TM2Context *ctx, int stream_id) {
 
 static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, int buf_size)
 {
-    int i;
+    int i, ret;
     int skip = 0;
     int len, toks, pos;
     TM2Codes codes;
@@ -257,33 +275,33 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i
     len  = bytestream2_get_be32(&gb);
     skip = len * 4 + 4;
 
-    if(len == 0)
+    if (len == 0)
         return 4;
 
     if (len >= INT_MAX/4-1 || len < 0 || len > buf_size) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Error, invalid stream size.\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     toks = bytestream2_get_be32(&gb);
-    if(toks & 1) {
+    if (toks & 1) {
         len = bytestream2_get_be32(&gb);
-        if(len == TM2_ESCAPE) {
+        if (len == TM2_ESCAPE) {
             len = bytestream2_get_be32(&gb);
         }
-        if(len > 0) {
+        if (len > 0) {
             pos = bytestream2_tell(&gb);
             if (skip <= pos)
-                return -1;
+                return AVERROR_INVALIDDATA;
             init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
-            if(tm2_read_deltas(ctx, stream_id) == -1)
-                return -1;
+            if ((ret = tm2_read_deltas(ctx, stream_id)) < 0)
+                return ret;
             bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
         }
     }
     /* skip unused fields */
     len = bytestream2_get_be32(&gb);
-    if(len == TM2_ESCAPE) { /* some unknown length - could be escaped too */
+    if (len == TM2_ESCAPE) { /* some unknown length - could be escaped too */
         bytestream2_skip(&gb, 8); /* unused by decoder */
     } else {
         bytestream2_skip(&gb, 4); /* unused by decoder */
@@ -291,31 +309,31 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i
 
     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;
+    if ((ret = tm2_build_huff_table(ctx, &codes)) < 0)
+        return ret;
     bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
 
     toks >>= 1;
     /* check if we have sane number of tokens */
-    if((toks < 0) || (toks > 0xFFFFFF)){
+    if ((toks < 0) || (toks > 0xFFFFFF)) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
         tm2_free_codes(&codes);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
-    ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int));
+    ctx->tokens[stream_id]   = av_realloc(ctx->tokens[stream_id], toks * sizeof(int));
     ctx->tok_lens[stream_id] = toks;
     len = bytestream2_get_be32(&gb);
-    if(len > 0) {
+    if (len > 0) {
         pos = bytestream2_tell(&gb);
         if (skip <= pos)
-            return -1;
+            return AVERROR_INVALIDDATA;
         init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
-        for(i = 0; i < toks; i++) {
+        for (i = 0; i < toks; i++) {
             if (get_bits_left(&ctx->gb) <= 0) {
                 av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
-                return -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) {
@@ -325,7 +343,7 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i
             }
         }
     } else {
-        for(i = 0; i < toks; i++) {
+        for (i = 0; i < toks; i++) {
             ctx->tokens[stream_id][i] = codes.recode[0];
             if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) {
                 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
@@ -339,12 +357,13 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i
     return skip;
 }
 
-static inline int GET_TOK(TM2Context *ctx,int type) {
-    if(ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
+static inline int GET_TOK(TM2Context *ctx,int type)
+{
+    if (ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Read token from stream %i out of bounds (%i>=%i)\n", type, ctx->tok_ptrs[type], ctx->tok_lens[type]);
         return 0;
     }
-    if(type <= TM2_MOT)
+    if (type <= TM2_MOT)
         return ctx->deltas[type][ctx->tokens[type][ctx->tok_ptrs[type]++]];
     return ctx->tokens[type][ctx->tok_ptrs[type]++];
 }
@@ -391,15 +410,15 @@ static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *de
     int ct, d;
     int i, j;
 
-    for(j = 0; j < 4; j++){
+    for (j = 0; j < 4; j++){
         ct = ctx->D[j];
-        for(i = 0; i < 4; i++){
-            d = deltas[i + j * 4];
-            ct += d;
+        for (i = 0; i < 4; i++){
+            d        = deltas[i + j * 4];
+            ct      += d;
             last[i] += ct;
-            Y[i] = av_clip_uint8(last[i]);
+            Y[i]     = av_clip_uint8(last[i]);
         }
-        Y += stride;
+        Y        += stride;
         ctx->D[j] = ct;
     }
 }
@@ -407,11 +426,11 @@ static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *de
 static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas)
 {
     int i, j;
-    for(j = 0; j < 2; j++){
-        for(i = 0; i < 2; i++){
-            CD[j] += deltas[i + j * 2];
+    for (j = 0; j < 2; j++) {
+        for (i = 0; i < 2; i++)  {
+            CD[j]   += deltas[i + j * 2];
             last[i] += CD[j];
-            data[i] = last[i];
+            data[i]  = last[i];
         }
         data += stride;
     }
@@ -423,14 +442,14 @@ static inline void tm2_low_chroma(int *data, int stride, int *clast, int *CD, in
     int l;
     int prev;
 
-    if(bx > 0)
+    if (bx > 0)
         prev = clast[-3];
     else
         prev = 0;
-    t = (CD[0] + CD[1]) >> 1;
-    l = (prev - CD[0] - CD[1] + clast[1]) >> 1;
-    CD[1] = CD[0] + CD[1] - t;
-    CD[0] = t;
+    t        = (CD[0] + CD[1]) >> 1;
+    l        = (prev - CD[0] - CD[1] + clast[1]) >> 1;
+    CD[1]    = CD[0] + CD[1] - t;
+    CD[0]    = t;
     clast[0] = l;
 
     tm2_high_chroma(data, stride, clast, CD, deltas);
@@ -443,15 +462,15 @@ static inline void tm2_hi_res_block(TM2Context *ctx, AVFrame *pic, int bx, int b
     TM2_INIT_POINTERS();
 
     /* hi-res chroma */
-    for(i = 0; i < 4; i++) {
-        deltas[i] = GET_TOK(ctx, TM2_C_HI);
+    for (i = 0; i < 4; i++) {
+        deltas[i]     = GET_TOK(ctx, TM2_C_HI);
         deltas[i + 4] = GET_TOK(ctx, TM2_C_HI);
     }
-    tm2_high_chroma(U, Ustride, clast, ctx->CD, deltas);
+    tm2_high_chroma(U, Ustride, clast,     ctx->CD,     deltas);
     tm2_high_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas + 4);
 
     /* hi-res luma */
-    for(i = 0; i < 16; i++)
+    for (i = 0; i < 16; i++)
         deltas[i] = GET_TOK(ctx, TM2_L_HI);
 
     tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
@@ -473,7 +492,7 @@ static inline void tm2_med_res_block(TM2Context *ctx, AVFrame *pic, int bx, int
     tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
 
     /* hi-res luma */
-    for(i = 0; i < 16; i++)
+    for (i = 0; i < 16; i++)
         deltas[i] = GET_TOK(ctx, TM2_L_HI);
 
     tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
@@ -496,7 +515,7 @@ static inline void tm2_low_res_block(TM2Context *ctx, AVFrame *pic, int bx, int
     tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
 
     /* low-res luma */
-    for(i = 0; i < 16; i++)
+    for (i = 0; i < 16; i++)
         deltas[i] = 0;
 
     deltas[ 0] = GET_TOK(ctx, TM2_L_LO);
@@ -504,7 +523,7 @@ static inline void tm2_low_res_block(TM2Context *ctx, AVFrame *pic, int bx, int
     deltas[ 8] = GET_TOK(ctx, TM2_L_LO);
     deltas[10] = GET_TOK(ctx, TM2_L_LO);
 
-    if(bx > 0)
+    if (bx > 0)
         last[0] = (last[-1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3] + last[1]) >> 1;
     else
         last[0] = (last[1]  - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3])>> 1;
@@ -536,18 +555,18 @@ static inline void tm2_null_res_block(TM2Context *ctx, AVFrame *pic, int bx, int
     tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
 
     /* null luma */
-    for(i = 0; i < 16; i++)
+    for (i = 0; i < 16; i++)
         deltas[i] = 0;
 
     ct = ctx->D[0] + ctx->D[1] + ctx->D[2] + ctx->D[3];
 
-    if(bx > 0)
+    if (bx > 0)
         left = last[-1] - ct;
     else
         left = 0;
 
-    right = last[3];
-    diff = right - left;
+    right   = last[3];
+    diff    = right - left;
     last[0] = left + (diff >> 2);
     last[1] = left + (diff >> 1);
     last[2] = right - (diff >> 2);
@@ -556,11 +575,11 @@ static inline void tm2_null_res_block(TM2Context *ctx, AVFrame *pic, int bx, int
         int tp = left;
 
         ctx->D[0] = (tp + (ct >> 2)) - left;
-        left += ctx->D[0];
+        left     += ctx->D[0];
         ctx->D[1] = (tp + (ct >> 1)) - left;
-        left += ctx->D[1];
+        left     += ctx->D[1];
         ctx->D[2] = ((tp + ct) - (ct >> 2)) - left;
-        left += ctx->D[2];
+        left     += ctx->D[2];
         ctx->D[3] = (tp + ct) - left;
     }
     tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
@@ -572,12 +591,12 @@ static inline void tm2_still_block(TM2Context *ctx, AVFrame *pic, int bx, int by
     TM2_INIT_POINTERS_2();
 
     /* update chroma */
-    for(j = 0; j < 2; j++){
-        for(i = 0; i < 2; i++){
+    for (j = 0; j < 2; j++) {
+        for (i = 0; i < 2; i++){
             U[i] = Uo[i];
             V[i] = Vo[i];
         }
-        U += Ustride; V += Vstride;
+        U  += Ustride; V += Vstride;
         Uo += oUstride; Vo += oVstride;
     }
     U -= Ustride * 2;
@@ -591,12 +610,12 @@ static inline void tm2_still_block(TM2Context *ctx, AVFrame *pic, int bx, int by
     ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
     ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
 
-    for(j = 0; j < 4; j++){
-        for(i = 0; i < 4; i++){
-            Y[i] = Yo[i];
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
+            Y[i]    = Yo[i];
             last[i] = Yo[i];
         }
-        Y += Ystride;
+        Y  += Ystride;
         Yo += oYstride;
     }
 }
@@ -608,13 +627,15 @@ static inline void tm2_update_block(TM2Context *ctx, AVFrame *pic, int bx, int b
     TM2_INIT_POINTERS_2();
 
     /* update chroma */
-    for(j = 0; j < 2; j++){
-        for(i = 0; i < 2; i++){
+    for (j = 0; j < 2; j++) {
+        for (i = 0; i < 2; i++) {
             U[i] = Uo[i] + GET_TOK(ctx, TM2_UPD);
             V[i] = Vo[i] + GET_TOK(ctx, TM2_UPD);
         }
-        U += Ustride; V += Vstride;
-        Uo += oUstride; Vo += oVstride;
+        U  += Ustride;
+        V  += Vstride;
+        Uo += oUstride;
+        Vo += oVstride;
     }
     U -= Ustride * 2;
     V -= Vstride * 2;
@@ -627,14 +648,14 @@ static inline void tm2_update_block(TM2Context *ctx, AVFrame *pic, int bx, int b
     ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
     ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
 
-    for(j = 0; j < 4; j++){
+    for (j = 0; j < 4; j++) {
         d = last[3];
-        for(i = 0; i < 4; i++){
-            Y[i] = Yo[i] + GET_TOK(ctx, TM2_UPD);
+        for (i = 0; i < 4; i++) {
+            Y[i]    = Yo[i] + GET_TOK(ctx, TM2_UPD);
             last[i] = Y[i];
         }
         ctx->D[j] = last[3] - d;
-        Y += Ystride;
+        Y  += Ystride;
         Yo += oYstride;
     }
 }
@@ -655,13 +676,15 @@ static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int b
     Vo += (my >> 1) * oVstride + (mx >> 1);
 
     /* copy chroma */
-    for(j = 0; j < 2; j++){
-        for(i = 0; i < 2; i++){
+    for (j = 0; j < 2; j++) {
+        for (i = 0; i < 2; i++) {
             U[i] = Uo[i];
             V[i] = Vo[i];
         }
-        U += Ustride; V += Vstride;
-        Uo += oUstride; Vo += oVstride;
+        U  += Ustride;
+        V  += Vstride;
+        Uo += oUstride;
+        Vo += oVstride;
     }
     U -= Ustride * 2;
     V -= Vstride * 2;
@@ -669,11 +692,11 @@ static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int b
     TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
 
     /* copy luma */
-    for(j = 0; j < 4; j++){
-        for(i = 0; i < 4; i++){
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
             Y[i] = Yo[i];
         }
-        Y += Ystride;
+        Y  += Ystride;
         Yo += oYstride;
     }
     /* calculate deltas */
@@ -682,7 +705,7 @@ static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int b
     ctx->D[1] = Y[3 + Ystride] - Y[3];
     ctx->D[2] = Y[3 + Ystride * 2] - Y[3 + Ystride];
     ctx->D[3] = Y[3 + Ystride * 3] - Y[3 + Ystride * 2];
-    for(i = 0; i < 4; i++)
+    for (i = 0; i < 4; i++)
         last[i] = Y[i + Ystride * 3];
 }
 
@@ -695,21 +718,21 @@ static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p)
     int *Y, *U, *V;
     uint8_t *dst;
 
-    for(i = 0; i < TM2_NUM_STREAMS; i++)
+    for (i = 0; i < TM2_NUM_STREAMS; i++)
         ctx->tok_ptrs[i] = 0;
 
-    if (ctx->tok_lens[TM2_TYPE]<bw*bh){
+    if (ctx->tok_lens[TM2_TYPE]<bw*bh) {
         av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     memset(ctx->last, 0, 4 * bw * sizeof(int));
     memset(ctx->clast, 0, 4 * bw * sizeof(int));
 
-    for(j = 0; j < bh; j++) {
+    for (j = 0; j < bh; j++) {
         memset(ctx->D, 0, 4 * sizeof(int));
         memset(ctx->CD, 0, 4 * sizeof(int));
-        for(i = 0; i < bw; i++) {
+        for (i = 0; i < bw; i++) {
             type = GET_TOK(ctx, TM2_TYPE);
             switch(type) {
             case TM2_HI_RES:
@@ -747,8 +770,8 @@ static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p)
     U = (ctx->cur?ctx->U2:ctx->U1);
     V = (ctx->cur?ctx->V2:ctx->V1);
     dst = p->data[0];
-    for(j = 0; j < h; j++){
-        for(i = 0; i < w; i++){
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < w; i++) {
             int y = Y[i], u = U[i >> 1], v = V[i >> 1];
             dst[3*i+0] = av_clip_uint8(y + v);
             dst[3*i+1] = av_clip_uint8(y);
@@ -812,24 +835,24 @@ static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size & ~3;
     TM2Context * const l = avctx->priv_data;
-    AVFrame * const p = &l->pic;
-    int i, offset = TM2_HEADER_SIZE, t, ret;
+    const uint8_t *buf   = avpkt->data;
+    int buf_size         = avpkt->size & ~3;
+    AVFrame * const p    = l->pic;
+    int offset           = TM2_HEADER_SIZE;
+    int i, t, ret;
     uint8_t *swbuf;
 
     swbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    if(!swbuf){
+    if (!swbuf) {
         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
-        return -1;
+        return AVERROR(ENOMEM);
     }
-    p->reference = 1;
-    p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if(avctx->reget_buffer(avctx, p) < 0){
+
+    if ((ret = ff_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);
@@ -839,52 +862,56 @@ static int decode_frame(AVCodecContext *avctx,
         return ret;
     }
 
-    for(i = 0; i < TM2_NUM_STREAMS; i++){
+    for (i = 0; i < TM2_NUM_STREAMS; i++) {
         if (offset >= buf_size) {
             av_free(swbuf);
             return AVERROR_INVALIDDATA;
         }
         t = tm2_read_stream(l, swbuf + offset, tm2_stream_order[i],
                             buf_size - offset);
-        if(t < 0){
+        if (t < 0) {
             av_free(swbuf);
             return t;
         }
         offset += t;
     }
     p->key_frame = tm2_decode_blocks(l, p);
-    if(p->key_frame)
+    if (p->key_frame)
         p->pict_type = AV_PICTURE_TYPE_I;
     else
         p->pict_type = AV_PICTURE_TYPE_P;
 
     l->cur = !l->cur;
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
+    ret = av_frame_ref(data, l->pic);
     av_free(swbuf);
 
-    return buf_size;
+    return (ret < 0) ? ret : buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
+static av_cold int decode_init(AVCodecContext *avctx)
+{
     TM2Context * const l = avctx->priv_data;
     int i, w = avctx->width, h = avctx->height;
 
-    if((avctx->width & 3) || (avctx->height & 3)){
+    if ((avctx->width & 3) || (avctx->height & 3)) {
         av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n");
-        return -1;
+        return AVERROR(EINVAL);
     }
 
-    l->avctx = avctx;
-    l->pic.data[0]=NULL;
+    l->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_BGR24;
 
+    l->pic = av_frame_alloc();
+    if (!l->pic)
+        return AVERROR(ENOMEM);
+
     ff_dsputil_init(&l->dsp, avctx);
 
     l->last  = av_malloc(4 * sizeof(*l->last)  * (w >> 2));
     l->clast = av_malloc(4 * sizeof(*l->clast) * (w >> 2));
 
-    for(i = 0; i < TM2_NUM_STREAMS; i++) {
+    for (i = 0; i < TM2_NUM_STREAMS; i++) {
         l->tokens[i] = NULL;
         l->tok_lens[i] = 0;
     }
@@ -925,16 +952,16 @@ static av_cold int decode_init(AVCodecContext *avctx){
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
+static av_cold int decode_end(AVCodecContext *avctx)
+{
     TM2Context * const l = avctx->priv_data;
-    AVFrame *pic = &l->pic;
     int i;
 
     av_free(l->last);
     av_free(l->clast);
-    for(i = 0; i < TM2_NUM_STREAMS; i++)
+    for (i = 0; i < TM2_NUM_STREAMS; i++)
         av_free(l->tokens[i]);
-    if(l->Y1){
+    if (l->Y1) {
         av_free(l->Y1_base);
         av_free(l->U1_base);
         av_free(l->V1_base);
@@ -943,14 +970,14 @@ static av_cold int decode_end(AVCodecContext *avctx){
         av_free(l->V2_base);
     }
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
+    av_frame_free(&l->pic);
 
     return 0;
 }
 
 AVCodec ff_truemotion2_decoder = {
     .name           = "truemotion2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TRUEMOTION2,
     .priv_data_size = sizeof(TM2Context),
@@ -958,5 +985,4 @@ AVCodec ff_truemotion2_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
 };
diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c
index 486e41f..3f56973 100644
--- a/libavcodec/truespeech.c
+++ b/libavcodec/truespeech.c
@@ -36,7 +36,6 @@
  * TrueSpeech decoder context
  */
 typedef struct {
-    AVFrame frame;
     DSPContext dsp;
     /* input data */
     DECLARE_ALIGNED(16, uint8_t, buffer)[32];
@@ -64,7 +63,7 @@ static av_cold int truespeech_decode_init(AVCodecContext * avctx)
     TSContext *c = avctx->priv_data;
 
     if (avctx->channels != 1) {
-        av_log_ask_for_sample(avctx, "Unsupported channel count: %d\n", avctx->channels);
+        avpriv_request_sample(avctx, "Channel count %d", avctx->channels);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -73,9 +72,6 @@ static av_cold int truespeech_decode_init(AVCodecContext * avctx)
 
     ff_dsputil_init(&c->dsp, avctx);
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -310,6 +306,7 @@ static void truespeech_save_prevvec(TSContext *c)
 static int truespeech_decode_frame(AVCodecContext *avctx, void *data,
                                    int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     TSContext *c = avctx->priv_data;
@@ -327,12 +324,12 @@ static int truespeech_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    c->frame.nb_samples = iterations * 240;
-    if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) {
+    frame->nb_samples = iterations * 240;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (int16_t *)c->frame.data[0];
+    samples = (int16_t *)frame->data[0];
 
     memset(samples, 0, iterations * 240 * sizeof(*samples));
 
@@ -354,19 +351,18 @@ static int truespeech_decode_frame(AVCodecContext *avctx, void *data,
         truespeech_save_prevvec(c);
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = c->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 }
 
 AVCodec ff_truespeech_decoder = {
     .name           = "truespeech",
+    .long_name      = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_TRUESPEECH,
     .priv_data_size = sizeof(TSContext),
     .init           = truespeech_decode_init,
     .decode         = truespeech_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("DSP Group TrueSpeech"),
 };
diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c
index 5b1c7be..c26853e 100644
--- a/libavcodec/tscc.c
+++ b/libavcodec/tscc.c
@@ -44,14 +44,9 @@
 
 #include <zlib.h>
 
-
-/*
- * Decoder context
- */
 typedef struct TsccContext {
 
     AVCodecContext *avctx;
-    AVFrame pic;
 
     // Bits per pixel
     int bpp;
@@ -66,11 +61,6 @@ typedef struct TsccContext {
     uint32_t pal[256];
 } CamtasiaContext;
 
-/*
- *
- * Decode a frame
- *
- */
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
@@ -78,23 +68,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int buf_size = avpkt->size;
     CamtasiaContext * const c = avctx->priv_data;
     const unsigned char *encoded = buf;
+    AVFrame *frame = data;
     int zret; // Zlib return code
-    int len = buf_size;
-
-    if(c->pic.data[0])
-            avctx->release_buffer(avctx, &c->pic);
+    int ret, len = buf_size;
 
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if(ff_get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 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_UNKNOWN;
     }
     c->zstream.next_in = encoded;
     c->zstream.avail_in = len;
@@ -104,14 +90,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     // 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_UNKNOWN;
     }
 
 
     if (zret != Z_DATA_ERROR) {
         bytestream2_init(&c->gb, c->decomp_buf,
                          c->decomp_size - c->zstream.avail_out);
-        ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, &c->gb);
+        ff_msrle_decode(avctx, (AVPicture*)frame, c->bpp, &c->gb);
     }
 
     /* make the palette available on the way out */
@@ -119,26 +105,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
         if (pal) {
-            c->pic.palette_has_changed = 1;
+            frame->palette_has_changed = 1;
             memcpy(c->pal, pal, AVPALETTE_SIZE);
         }
-        memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
+        memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
 }
 
-
-
-/*
- *
- * Init tscc decoder
- *
- */
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     CamtasiaContext * const c = avctx->priv_data;
@@ -158,7 +136,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
              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_INVALIDDATA;
     }
     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
@@ -168,7 +146,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     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);
         }
     }
 
@@ -178,27 +156,18 @@ static av_cold int decode_init(AVCodecContext *avctx)
     zret = inflateInit(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
-        return 1;
+        return AVERROR_UNKNOWN;
     }
 
     return 0;
 }
 
-
-
-/*
- *
- * Uninit tscc decoder
- *
- */
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     CamtasiaContext * const c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
     inflateEnd(&c->zstream);
 
     return 0;
@@ -206,6 +175,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
 AVCodec ff_tscc_decoder = {
     .name           = "camtasia",
+    .long_name      = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TSCC,
     .priv_data_size = sizeof(CamtasiaContext),
@@ -213,5 +183,4 @@ AVCodec ff_tscc_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"),
 };
diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c
index b7f1b88..3d22fd7 100644
--- a/libavcodec/tscc2.c
+++ b/libavcodec/tscc2.c
@@ -28,11 +28,12 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "tscc2data.h"
 
 typedef struct TSCC2Context {
     AVCodecContext *avctx;
-    AVFrame        pic;
+    AVFrame       *pic;
     int            mb_width, mb_height;
     uint8_t        *slice_quants;
     int            quant[2];
@@ -199,9 +200,9 @@ static int tscc2_decode_slice(TSCC2Context *c, int mb_y,
         if (q == 0 || q == 3) // skip block
             continue;
         for (i = 0; i < 3; i++) {
-            off = mb_x * 16 + mb_y * 8 * c->pic.linesize[i];
+            off = mb_x * 16 + mb_y * 8 * c->pic->linesize[i];
             ret = tscc2_decode_mb(c, c->q[q - 1], c->quant[q - 1] - 2,
-                                  c->pic.data[i] + off, c->pic.linesize[i], i);
+                                  c->pic->data[i] + off, c->pic->linesize[i], i);
             if (ret)
                 return ret;
         }
@@ -229,17 +230,15 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    c->pic.reference    = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
 
     if (frame_type == 0) {
         *got_frame      = 1;
-        *(AVFrame*)data = c->pic;
+        if ((ret = av_frame_ref(data, c->pic)) < 0)
+            return ret;
 
         return buf_size;
     }
@@ -323,12 +322,24 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
+    if ((ret = av_frame_ref(data, c->pic)) < 0)
+        return ret;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
 }
 
+static av_cold int tscc2_decode_end(AVCodecContext *avctx)
+{
+    TSCC2Context * const c = avctx->priv_data;
+
+    av_frame_free(&c->pic);
+    av_freep(&c->slice_quants);
+    free_vlcs(c);
+
+    return 0;
+}
+
 static av_cold int tscc2_decode_init(AVCodecContext *avctx)
 {
     TSCC2Context * const c = avctx->priv_data;
@@ -352,25 +363,18 @@ static av_cold int tscc2_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
-    avctx->coded_frame = &c->pic;
-
-    return 0;
-}
-
-static av_cold int tscc2_decode_end(AVCodecContext *avctx)
-{
-    TSCC2Context * const c = avctx->priv_data;
-
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    av_freep(&c->slice_quants);
-    free_vlcs(c);
+    c->pic = av_frame_alloc();
+    if (!c->pic) {
+        tscc2_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
     return 0;
 }
 
 AVCodec ff_tscc2_decoder = {
     .name           = "tscc2",
+    .long_name      = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TSCC2,
     .priv_data_size = sizeof(TSCC2Context),
@@ -378,5 +382,4 @@ AVCodec ff_tscc2_decoder = {
     .close          = tscc2_decode_end,
     .decode         = tscc2_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("TechSmith Screen Codec 2"),
 };
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index 5ed70e9..4d2e2a0 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -28,7 +28,6 @@
  */
 
 #define BITSTREAM_READER_LE
-//#define DEBUG
 #include <limits.h>
 #include "avcodec.h"
 #include "get_bits.h"
@@ -58,7 +57,6 @@ typedef struct TTAChannel {
 
 typedef struct TTAContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     GetBitContext gb;
     const AVCRC *crc_table;
 
@@ -223,7 +221,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
             return -1;
         }
         if (s->format == FORMAT_ENCRYPTED) {
-            av_log_missing_feature(s->avctx, "Encrypted TTA", 0);
+            avpriv_report_missing_feature(s->avctx, "Encrypted TTA");
             return AVERROR_PATCHWELCOME;
         }
         avctx->channels = s->channels = get_bits(&s->gb, 16);
@@ -277,7 +275,8 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
             avctx->extradata_size - 26 < total_frames * 4)
             av_log(avctx, AV_LOG_WARNING, "Seek table missing or too small\n");
         else if (avctx->err_recognition & AV_EF_CRCCHECK) {
-            if (tta_check_crc(s, avctx->extradata + 22, total_frames * 4))
+            int ret = tta_check_crc(s, avctx->extradata + 22, total_frames * 4);
+            if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE)
                 return AVERROR_INVALIDDATA;
         }
         skip_bits_long(&s->gb, 32 * total_frames);
@@ -303,15 +302,13 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
         return -1;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int tta_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     TTAContext *s = avctx->priv_data;
@@ -320,22 +317,23 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data,
     int32_t *p;
 
     if (avctx->err_recognition & AV_EF_CRCCHECK) {
-        if (buf_size < 4 || tta_check_crc(s, buf, buf_size - 4))
+        if (buf_size < 4 ||
+            (tta_check_crc(s, buf, buf_size - 4) && avctx->err_recognition & AV_EF_EXPLODE))
             return AVERROR_INVALIDDATA;
     }
 
     init_get_bits(&s->gb, buf, buf_size*8);
 
     /* get output buffer */
-    s->frame.nb_samples = framelen;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = framelen;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     // decode directly to output buffer for 24-bit sample format
     if (s->bps == 3)
-        s->decode_buffer = (int32_t *)s->frame.data[0];
+        s->decode_buffer = (int32_t *)frame->data[0];
 
     // init per channel states
     for (i = 0; i < s->channels; i++) {
@@ -424,7 +422,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data,
             i++;
             // check for last frame
             if (i == s->last_frame_length && get_bits_left(&s->gb) / 8 == 4) {
-                s->frame.nb_samples = framelen = s->last_frame_length;
+                frame->nb_samples = framelen = s->last_frame_length;
                 break;
             }
         }
@@ -439,20 +437,19 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data,
 
     // convert to output buffer
     if (s->bps == 2) {
-        int16_t *samples = (int16_t *)s->frame.data[0];
+        int16_t *samples = (int16_t *)frame->data[0];
         for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
             *samples++ = *p;
     } else {
         // shift samples for 24-bit sample format
-        int32_t *samples = (int32_t *)s->frame.data[0];
+        int32_t *samples = (int32_t *)frame->data[0];
         for (i = 0; i < framelen * s->channels; i++)
             *samples++ <<= 8;
         // reset decode buffer
         s->decode_buffer = NULL;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return buf_size;
 error:
@@ -473,6 +470,7 @@ static av_cold int tta_decode_close(AVCodecContext *avctx) {
 
 AVCodec ff_tta_decoder = {
     .name           = "tta",
+    .long_name      = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_TTA,
     .priv_data_size = sizeof(TTAContext),
@@ -480,5 +478,4 @@ AVCodec ff_tta_decoder = {
     .close          = tta_decode_close,
     .decode         = tta_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("TTA (True Audio)"),
 };
diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index f6c897f..e1b1c7b 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -19,222 +19,23 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <math.h>
+#include <stdint.h>
+
 #include "libavutil/channel_layout.h"
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
-#include "get_bits.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "internal.h"
 #include "lsp.h"
 #include "sinewin.h"
-
-#include <math.h>
-#include <stdint.h>
-
-#include "twinvq_data.h"
-
-enum FrameType {
-    FT_SHORT = 0,  ///< Short frame  (divided in n   sub-blocks)
-    FT_MEDIUM,     ///< Medium frame (divided in m<n sub-blocks)
-    FT_LONG,       ///< Long frame   (single sub-block + PPC)
-    FT_PPC,        ///< Periodic Peak Component (part of the long frame)
-};
-
-/**
- * Parameters and tables that are different for each frame type
- */
-struct FrameMode {
-    uint8_t         sub;      ///< Number subblocks in each frame
-    const uint16_t *bark_tab;
-
-    /** number of distinct bark scale envelope values */
-    uint8_t         bark_env_size;
-
-    const int16_t  *bark_cb;    ///< codebook for the bark scale envelope (BSE)
-    uint8_t         bark_n_coef;///< number of BSE CB coefficients to read
-    uint8_t         bark_n_bit; ///< number of bits of the BSE coefs
-
-    //@{
-    /** main codebooks for spectrum data */
-    const int16_t    *cb0;
-    const int16_t    *cb1;
-    //@}
-
-    uint8_t         cb_len_read; ///< number of spectrum coefficients to read
-};
-
-/**
- * Parameters and tables that are different for every combination of
- * bitrate/sample rate
- */
-typedef struct {
-    struct FrameMode fmode[3]; ///< frame type-dependant parameters
-
-    uint16_t     size;        ///< frame size in samples
-    uint8_t      n_lsp;       ///< number of lsp coefficients
-    const float *lspcodebook;
-
-    /* number of bits of the different LSP CB coefficients */
-    uint8_t      lsp_bit0;
-    uint8_t      lsp_bit1;
-    uint8_t      lsp_bit2;
-
-    uint8_t      lsp_split;      ///< number of CB entries for the LSP decoding
-    const int16_t *ppc_shape_cb; ///< PPC shape CB
-
-    /** number of the bits for the PPC period value */
-    uint8_t      ppc_period_bit;
-
-    uint8_t      ppc_shape_bit;  ///< number of bits of the PPC shape CB coeffs
-    uint8_t      ppc_shape_len;  ///< size of PPC shape CB
-    uint8_t      pgain_bit;      ///< bits for PPC gain
-
-    /** constant for peak period to peak width conversion */
-    uint16_t     peak_per2wid;
-} ModeTab;
-
-static const ModeTab mode_08_08 = {
-    {
-        { 8, bark_tab_s08_64,  10, tab.fcb08s  , 1, 5, tab.cb0808s0, tab.cb0808s1, 18},
-        { 2, bark_tab_m08_256, 20, tab.fcb08m  , 2, 5, tab.cb0808m0, tab.cb0808m1, 16},
-        { 1, bark_tab_l08_512, 30, tab.fcb08l  , 3, 6, tab.cb0808l0, tab.cb0808l1, 17}
-    },
-    512 , 12, tab.lsp08,   1, 5, 3, 3, tab.shape08  , 8, 28, 20, 6, 40
-};
-
-static const ModeTab mode_11_08 = {
-    {
-        { 8, bark_tab_s11_64,  10, tab.fcb11s  , 1, 5, tab.cb1108s0, tab.cb1108s1, 29},
-        { 2, bark_tab_m11_256, 20, tab.fcb11m  , 2, 5, tab.cb1108m0, tab.cb1108m1, 24},
-        { 1, bark_tab_l11_512, 30, tab.fcb11l  , 3, 6, tab.cb1108l0, tab.cb1108l1, 27}
-    },
-    512 , 16, tab.lsp11,   1, 6, 4, 3, tab.shape11  , 9, 36, 30, 7, 90
-};
-
-static const ModeTab mode_11_10 = {
-    {
-        { 8, bark_tab_s11_64,  10, tab.fcb11s  , 1, 5, tab.cb1110s0, tab.cb1110s1, 21},
-        { 2, bark_tab_m11_256, 20, tab.fcb11m  , 2, 5, tab.cb1110m0, tab.cb1110m1, 18},
-        { 1, bark_tab_l11_512, 30, tab.fcb11l  , 3, 6, tab.cb1110l0, tab.cb1110l1, 20}
-    },
-    512 , 16, tab.lsp11,   1, 6, 4, 3, tab.shape11  , 9, 36, 30, 7, 90
-};
-
-static const ModeTab mode_16_16 = {
-    {
-        { 8, bark_tab_s16_128, 10, tab.fcb16s  , 1, 5, tab.cb1616s0, tab.cb1616s1, 16},
-        { 2, bark_tab_m16_512, 20, tab.fcb16m  , 2, 5, tab.cb1616m0, tab.cb1616m1, 15},
-        { 1, bark_tab_l16_1024,30, tab.fcb16l  , 3, 6, tab.cb1616l0, tab.cb1616l1, 16}
-    },
-    1024, 16, tab.lsp16,   1, 6, 4, 3, tab.shape16  , 9, 56, 60, 7, 180
-};
-
-static const ModeTab mode_22_20 = {
-    {
-        { 8, bark_tab_s22_128, 10, tab.fcb22s_1, 1, 6, tab.cb2220s0, tab.cb2220s1, 18},
-        { 2, bark_tab_m22_512, 20, tab.fcb22m_1, 2, 6, tab.cb2220m0, tab.cb2220m1, 17},
-        { 1, bark_tab_l22_1024,32, tab.fcb22l_1, 4, 6, tab.cb2220l0, tab.cb2220l1, 18}
-    },
-    1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144
-};
-
-static const ModeTab mode_22_24 = {
-    {
-        { 8, bark_tab_s22_128, 10, tab.fcb22s_1, 1, 6, tab.cb2224s0, tab.cb2224s1, 15},
-        { 2, bark_tab_m22_512, 20, tab.fcb22m_1, 2, 6, tab.cb2224m0, tab.cb2224m1, 14},
-        { 1, bark_tab_l22_1024,32, tab.fcb22l_1, 4, 6, tab.cb2224l0, tab.cb2224l1, 15}
-    },
-    1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144
-};
-
-static const ModeTab mode_22_32 = {
-    {
-        { 4, bark_tab_s22_128, 10, tab.fcb22s_2, 1, 6, tab.cb2232s0, tab.cb2232s1, 11},
-        { 2, bark_tab_m22_256, 20, tab.fcb22m_2, 2, 6, tab.cb2232m0, tab.cb2232m1, 11},
-        { 1, bark_tab_l22_512, 32, tab.fcb22l_2, 4, 6, tab.cb2232l0, tab.cb2232l1, 12}
-    },
-    512 , 16, tab.lsp22_2, 1, 6, 4, 4, tab.shape22_2, 9, 56, 36, 7, 72
-};
-
-static const ModeTab mode_44_40 = {
-    {
-        {16, bark_tab_s44_128, 10, tab.fcb44s  , 1, 6, tab.cb4440s0, tab.cb4440s1, 18},
-        { 4, bark_tab_m44_512, 20, tab.fcb44m  , 2, 6, tab.cb4440m0, tab.cb4440m1, 17},
-        { 1, bark_tab_l44_2048,40, tab.fcb44l  , 4, 6, tab.cb4440l0, tab.cb4440l1, 17}
-    },
-    2048, 20, tab.lsp44,   1, 6, 4, 4, tab.shape44  , 9, 84, 54, 7, 432
-};
-
-static const ModeTab mode_44_48 = {
-    {
-        {16, bark_tab_s44_128, 10, tab.fcb44s  , 1, 6, tab.cb4448s0, tab.cb4448s1, 15},
-        { 4, bark_tab_m44_512, 20, tab.fcb44m  , 2, 6, tab.cb4448m0, tab.cb4448m1, 14},
-        { 1, bark_tab_l44_2048,40, tab.fcb44l  , 4, 6, tab.cb4448l0, tab.cb4448l1, 14}
-    },
-    2048, 20, tab.lsp44,   1, 6, 4, 4, tab.shape44  , 9, 84, 54, 7, 432
-};
-
-typedef struct TwinContext {
-    AVCodecContext *avctx;
-    AVFrame frame;
-    DSPContext      dsp;
-    AVFloatDSPContext fdsp;
-    FFTContext mdct_ctx[3];
-
-    const ModeTab *mtab;
-
-    // history
-    float lsp_hist[2][20];           ///< LSP coefficients of the last frame
-    float bark_hist[3][2][40];       ///< BSE coefficients of last frame
-
-    // bitstream parameters
-    int16_t permut[4][4096];
-    uint8_t length[4][2];            ///< main codebook stride
-    uint8_t length_change[4];
-    uint8_t bits_main_spec[2][4][2]; ///< bits for the main codebook
-    int bits_main_spec_change[4];
-    int n_div[4];
-
-    float *spectrum;
-    float *curr_frame;               ///< non-interleaved output
-    float *prev_frame;               ///< non-interleaved previous frame
-    int last_block_pos[2];
-    int discarded_packets;
-
-    float *cos_tabs[3];
-
-    // scratch buffers
-    float *tmp_buf;
-} TwinContext;
-
-#define PPC_SHAPE_CB_SIZE 64
-#define PPC_SHAPE_LEN_MAX 60
-#define SUB_AMP_MAX       4500.0
-#define MULAW_MU          100.0
-#define GAIN_BITS         8
-#define AMP_MAX           13000.0
-#define SUB_GAIN_BITS     5
-#define WINDOW_TYPE_BITS  4
-#define PGAIN_MU          200
-#define LSP_COEFS_MAX     20
-#define LSP_SPLIT_MAX     4
-#define CHANNELS_MAX      2
-#define SUBBLOCKS_MAX     16
-#define BARK_N_COEF_MAX   4
-
-/** @note not speed critical, hence not optimized */
-static void memset_float(float *buf, float val, int size)
-{
-    while (size--)
-        *buf++ = val;
-}
+#include "twinvq.h"
 
 /**
  * Evaluate a single LPC amplitude spectrum envelope coefficient from the line
  * spectrum pairs.
  *
- * @param lsp a vector of the cosinus of the LSP values
+ * @param lsp a vector of the cosine of the LSP values
  * @param cos_val cos(PI*i/N) where i is the index of the LPC amplitude
  * @param order the order of the LSP (and the size of the *lsp buffer). Must
  *        be a multiple of four.
@@ -245,17 +46,17 @@ static void memset_float(float *buf, float val, int size)
 static float eval_lpc_spectrum(const float *lsp, float cos_val, int order)
 {
     int j;
-    float p = 0.5f;
-    float q = 0.5f;
-    float two_cos_w = 2.0f*cos_val;
+    float p         = 0.5f;
+    float q         = 0.5f;
+    float two_cos_w = 2.0f * cos_val;
 
-    for (j = 0; j + 1 < order; j += 2*2) {
+    for (j = 0; j + 1 < order; j += 2 * 2) {
         // Unroll the loop once since order is a multiple of four
-        q *= lsp[j  ] - two_cos_w;
-        p *= lsp[j+1] - two_cos_w;
+        q *= lsp[j]     - two_cos_w;
+        p *= lsp[j + 1] - two_cos_w;
 
-        q *= lsp[j+2] - two_cos_w;
-        p *= lsp[j+3] - two_cos_w;
+        q *= lsp[j + 2] - two_cos_w;
+        p *= lsp[j + 3] - two_cos_w;
     }
 
     p *= p * (2.0f - two_cos_w);
@@ -267,34 +68,34 @@ static float eval_lpc_spectrum(const float *lsp, float cos_val, int order)
 /**
  * Evaluate the LPC amplitude spectrum envelope from the line spectrum pairs.
  */
-static void eval_lpcenv(TwinContext *tctx, const float *cos_vals, float *lpc)
+static void eval_lpcenv(TwinVQContext *tctx, const float *cos_vals, float *lpc)
 {
     int i;
-    const ModeTab *mtab = tctx->mtab;
-    int size_s = mtab->size / mtab->fmode[FT_SHORT].sub;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int size_s = mtab->size / mtab->fmode[TWINVQ_FT_SHORT].sub;
 
-    for (i = 0; i < size_s/2; i++) {
+    for (i = 0; i < size_s / 2; i++) {
         float cos_i = tctx->cos_tabs[0][i];
-        lpc[i]          = eval_lpc_spectrum(cos_vals,  cos_i, mtab->n_lsp);
-        lpc[size_s-i-1] = eval_lpc_spectrum(cos_vals, -cos_i, mtab->n_lsp);
+        lpc[i]              = eval_lpc_spectrum(cos_vals,  cos_i, mtab->n_lsp);
+        lpc[size_s - i - 1] = eval_lpc_spectrum(cos_vals, -cos_i, mtab->n_lsp);
     }
 }
 
 static void interpolate(float *out, float v1, float v2, int size)
 {
     int i;
-    float step = (v1 - v2)/(size + 1);
+    float step = (v1 - v2) / (size + 1);
 
     for (i = 0; i < size; i++) {
-        v2 += step;
+        v2    += step;
         out[i] = v2;
     }
 }
 
 static inline float get_cos(int idx, int part, const float *cos_tab, int size)
 {
-    return part ? -cos_tab[size - idx - 1] :
-                   cos_tab[       idx    ];
+    return part ? -cos_tab[size - idx - 1]
+                :  cos_tab[idx];
 }
 
 /**
@@ -306,19 +107,19 @@ static inline float get_cos(int idx, int part, const float *cos_tab, int size)
  * unexplained condition.
  *
  * @param step the size of a block "siiiibiiii"
- * @param in the cosinus of the LSP data
- * @param part is 0 for 0...PI (positive cossinus values) and 1 for PI...2PI
-          (negative cossinus values)
+ * @param in the cosine of the LSP data
+ * @param part is 0 for 0...PI (positive cosine values) and 1 for PI...2PI
+ *        (negative cosine values)
  * @param size the size of the whole output
  */
-static inline void eval_lpcenv_or_interp(TwinContext *tctx,
-                                         enum FrameType ftype,
+static inline void eval_lpcenv_or_interp(TwinVQContext *tctx,
+                                         enum TwinVQFrameType ftype,
                                          float *out, const float *in,
                                          int size, int step, int part)
 {
     int i;
-    const ModeTab *mtab = tctx->mtab;
-    const float *cos_tab = tctx->cos_tabs[ftype];
+    const TwinVQModeTab *mtab = tctx->mtab;
+    const float *cos_tab      = tctx->cos_tabs[ftype];
 
     // Fill the 's'
     for (i = 0; i < size; i += step)
@@ -328,33 +129,39 @@ static inline void eval_lpcenv_or_interp(TwinContext *tctx,
                               mtab->n_lsp);
 
     // Fill the 'iiiibiiii'
-    for (i = step; i <= size - 2*step; i += step) {
-        if (out[i + step] + out[i - step] >  1.95*out[i] ||
-            out[i + step]                 >=  out[i - step]) {
-            interpolate(out + i - step + 1, out[i], out[i-step], step - 1);
+    for (i = step; i <= size - 2 * step; i += step) {
+        if (out[i + step] + out[i - step] > 1.95 * out[i] ||
+            out[i + step]                 >= out[i - step]) {
+            interpolate(out + i - step + 1, out[i], out[i - step], step - 1);
         } else {
-            out[i - step/2] =
+            out[i - step / 2] =
                 eval_lpc_spectrum(in,
-                                  get_cos(i-step/2, part, cos_tab, size),
+                                  get_cos(i - step / 2, part, cos_tab, size),
                                   mtab->n_lsp);
-            interpolate(out + i - step   + 1, out[i-step/2], out[i-step  ], step/2 - 1);
-            interpolate(out + i - step/2 + 1, out[i       ], out[i-step/2], step/2 - 1);
+            interpolate(out + i - step + 1, out[i - step / 2],
+                        out[i - step], step / 2 - 1);
+            interpolate(out + i - step / 2 + 1, out[i],
+                        out[i - step / 2], step / 2 - 1);
         }
     }
 
-    interpolate(out + size - 2*step + 1, out[size-step], out[size - 2*step], step - 1);
+    interpolate(out + size - 2 * step + 1, out[size - step],
+                out[size - 2 * step], step - 1);
 }
 
-static void eval_lpcenv_2parts(TwinContext *tctx, enum FrameType ftype,
+static void eval_lpcenv_2parts(TwinVQContext *tctx, enum TwinVQFrameType ftype,
                                const float *buf, float *lpc,
                                int size, int step)
 {
-    eval_lpcenv_or_interp(tctx, ftype, lpc         , buf, size/2,   step, 0);
-    eval_lpcenv_or_interp(tctx, ftype, lpc + size/2, buf, size/2, 2*step, 1);
+    eval_lpcenv_or_interp(tctx, ftype, lpc, buf, size / 2, step, 0);
+    eval_lpcenv_or_interp(tctx, ftype, lpc + size / 2, buf, size / 2,
+                          2 * step, 1);
 
-    interpolate(lpc+size/2-step+1, lpc[size/2], lpc[size/2-step], step);
+    interpolate(lpc + size / 2 - step + 1, lpc[size / 2],
+                lpc[size / 2 - step], step);
 
-    memset_float(lpc + size - 2*step + 1, lpc[size - 2*step], 2*step - 1);
+    twinvq_memset_float(lpc + size - 2 * step + 1, lpc[size - 2 * step],
+                        2 * step - 1);
 }
 
 /**
@@ -362,8 +169,8 @@ static void eval_lpcenv_2parts(TwinContext *tctx, enum FrameType ftype,
  * bitstream, sum the corresponding vectors and write the result to *out
  * after permutation.
  */
-static void dequant(TwinContext *tctx, GetBitContext *gb, float *out,
-                    enum FrameType ftype,
+static void dequant(TwinVQContext *tctx, const uint8_t *cb_bits, float *out,
+                    enum TwinVQFrameType ftype,
                     const int16_t *cb0, const int16_t *cb1, int cb_len)
 {
     int pos = 0;
@@ -378,156 +185,58 @@ static void dequant(TwinContext *tctx, GetBitContext *gb, float *out,
         int bitstream_second_part = (i >= tctx->bits_main_spec_change[ftype]);
 
         int bits = tctx->bits_main_spec[0][ftype][bitstream_second_part];
+        tmp0 = *cb_bits++;
         if (bits == 7) {
-            if (get_bits1(gb))
+            if (tmp0 & 0x40)
                 sign0 = -1;
-            bits = 6;
+            tmp0 &= 0x3F;
         }
-        tmp0 = get_bits(gb, bits);
 
         bits = tctx->bits_main_spec[1][ftype][bitstream_second_part];
-
+        tmp1 = *cb_bits++;
         if (bits == 7) {
-            if (get_bits1(gb))
+            if (tmp1 & 0x40)
                 sign1 = -1;
-
-            bits = 6;
+            tmp1 &= 0x3F;
         }
-        tmp1 = get_bits(gb, bits);
 
-        tab0 = cb0 + tmp0*cb_len;
-        tab1 = cb1 + tmp1*cb_len;
+        tab0 = cb0 + tmp0 * cb_len;
+        tab1 = cb1 + tmp1 * cb_len;
 
         for (j = 0; j < length; j++)
-            out[tctx->permut[ftype][pos+j]] = sign0*tab0[j] + sign1*tab1[j];
+            out[tctx->permut[ftype][pos + j]] = sign0 * tab0[j] +
+                                                sign1 * tab1[j];
 
         pos += length;
     }
-
-}
-
-static inline float mulawinv(float y, float clip, float mu)
-{
-    y = av_clipf(y/clip, -1, 1);
-    return clip * FFSIGN(y) * (exp(log(1+mu) * fabs(y)) - 1) / mu;
-}
-
-/**
- * Evaluate a*b/400 rounded to the nearest integer. When, for example,
- * a*b == 200 and the nearest integer is ill-defined, use a table to emulate
- * the following broken float-based implementation used by the binary decoder:
- *
- * @code
- * static int very_broken_op(int a, int b)
- * {
- *    static float test; // Ugh, force gcc to do the division first...
- *
- *    test = a/400.;
- *    return b * test +  0.5;
- * }
- * @endcode
- *
- * @note if this function is replaced by just ROUNDED_DIV(a*b,400.), the stddev
- * between the original file (before encoding with Yamaha encoder) and the
- * decoded output increases, which leads one to believe that the encoder expects
- * exactly this broken calculation.
- */
-static int very_broken_op(int a, int b)
-{
-    int x = a*b + 200;
-    int size;
-    const uint8_t *rtab;
-
-    if (x%400 || b%5)
-        return x/400;
-
-    x /= 400;
-
-    size = tabs[b/5].size;
-    rtab = tabs[b/5].tab;
-    return x - rtab[size*av_log2(2*(x - 1)/size)+(x - 1)%size];
-}
-
-/**
- * Sum to data a periodic peak of a given period, width and shape.
- *
- * @param period the period of the peak divised by 400.0
- */
-static void add_peak(int period, int width, const float *shape,
-                     float ppc_gain, float *speech, int len)
-{
-    int i, j;
-
-    const float *shape_end = shape + len;
-    int center;
-
-    // First peak centered around zero
-    for (i = 0; i < width/2; i++)
-        speech[i] += ppc_gain * *shape++;
-
-    for (i = 1; i < ROUNDED_DIV(len,width) ; i++) {
-        center = very_broken_op(period, i);
-        for (j = -width/2; j < (width+1)/2; j++)
-            speech[j+center] += ppc_gain * *shape++;
-    }
-
-    // For the last block, be careful not to go beyond the end of the buffer
-    center = very_broken_op(period, i);
-    for (j = -width/2; j < (width + 1)/2 && shape < shape_end; j++)
-        speech[j+center] += ppc_gain * *shape++;
 }
 
-static void decode_ppc(TwinContext *tctx, int period_coef, const float *shape,
-                       float ppc_gain, float *speech)
+static void dec_gain(TwinVQContext *tctx,
+                     enum TwinVQFrameType ftype, float *out)
 {
-    const ModeTab *mtab = tctx->mtab;
-    int isampf = tctx->avctx->sample_rate/1000;
-    int ibps = tctx->avctx->bit_rate/(1000 * tctx->avctx->channels);
-    int min_period = ROUNDED_DIV(  40*2*mtab->size, isampf);
-    int max_period = ROUNDED_DIV(6*40*2*mtab->size, isampf);
-    int period_range = max_period - min_period;
-
-    // This is actually the period multiplied by 400. It is just linearly coded
-    // between its maximum and minimum value.
-    int period = min_period +
-        ROUNDED_DIV(period_coef*period_range, (1 << mtab->ppc_period_bit) - 1);
-    int width;
-
-    if (isampf == 22 && ibps == 32) {
-        // For some unknown reason, NTT decided to code this case differently...
-        width = ROUNDED_DIV((period + 800)* mtab->peak_per2wid, 400*mtab->size);
-    } else
-        width =             (period      )* mtab->peak_per2wid/(400*mtab->size);
-
-    add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len);
-}
-
-static void dec_gain(TwinContext *tctx, GetBitContext *gb, enum FrameType ftype,
-                     float *out)
-{
-    const ModeTab *mtab = tctx->mtab;
+    const TwinVQModeTab   *mtab =  tctx->mtab;
+    const TwinVQFrameData *bits = &tctx->bits[tctx->cur_frame];
     int i, j;
-    int sub = mtab->fmode[ftype].sub;
-    float step     = AMP_MAX     / ((1 <<     GAIN_BITS) - 1);
-    float sub_step = SUB_AMP_MAX / ((1 << SUB_GAIN_BITS) - 1);
+    int sub        = mtab->fmode[ftype].sub;
+    float step     = TWINVQ_AMP_MAX     / ((1 << TWINVQ_GAIN_BITS)     - 1);
+    float sub_step = TWINVQ_SUB_AMP_MAX / ((1 << TWINVQ_SUB_GAIN_BITS) - 1);
 
-    if (ftype == FT_LONG) {
+    if (ftype == TWINVQ_FT_LONG) {
         for (i = 0; i < tctx->avctx->channels; i++)
-            out[i] = (1./(1<<13)) *
-                mulawinv(step * 0.5 + step * get_bits(gb, GAIN_BITS),
-                         AMP_MAX, MULAW_MU);
+            out[i] = (1.0 / (1 << 13)) *
+                     twinvq_mulawinv(step * 0.5 + step * bits->gain_bits[i],
+                                     TWINVQ_AMP_MAX, TWINVQ_MULAW_MU);
     } else {
         for (i = 0; i < tctx->avctx->channels; i++) {
-            float val = (1./(1<<23)) *
-                mulawinv(step * 0.5 + step * get_bits(gb, GAIN_BITS),
-                         AMP_MAX, MULAW_MU);
-
-            for (j = 0; j < sub; j++) {
-                out[i*sub + j] =
-                    val*mulawinv(sub_step* 0.5 +
-                                 sub_step* get_bits(gb, SUB_GAIN_BITS),
-                                 SUB_AMP_MAX, MULAW_MU);
-            }
+            float val = (1.0 / (1 << 23)) *
+                        twinvq_mulawinv(step * 0.5 + step * bits->gain_bits[i],
+                                        TWINVQ_AMP_MAX, TWINVQ_MULAW_MU);
+
+            for (j = 0; j < sub; j++)
+                out[i * sub + j] =
+                    val * twinvq_mulawinv(sub_step * 0.5 +
+                                          sub_step * bits->sub_gain_bits[i * sub + j],
+                                          TWINVQ_SUB_AMP_MAX, TWINVQ_MULAW_MU);
         }
     }
 }
@@ -543,23 +252,23 @@ static void rearrange_lsp(int order, float *lsp, float min_dist)
     int i;
     float min_dist2 = min_dist * 0.5;
     for (i = 1; i < order; i++)
-        if (lsp[i] - lsp[i-1] < min_dist) {
-            float avg = (lsp[i] + lsp[i-1]) * 0.5;
+        if (lsp[i] - lsp[i - 1] < min_dist) {
+            float avg = (lsp[i] + lsp[i - 1]) * 0.5;
 
-            lsp[i-1] = avg - min_dist2;
-            lsp[i  ] = avg + min_dist2;
+            lsp[i - 1] = avg - min_dist2;
+            lsp[i]     = avg + min_dist2;
         }
 }
 
-static void decode_lsp(TwinContext *tctx, int lpc_idx1, uint8_t *lpc_idx2,
+static void decode_lsp(TwinVQContext *tctx, int lpc_idx1, uint8_t *lpc_idx2,
                        int lpc_hist_idx, float *lsp, float *hist)
 {
-    const ModeTab *mtab = tctx->mtab;
+    const TwinVQModeTab *mtab = tctx->mtab;
     int i, j;
 
-    const float *cb  =  mtab->lspcodebook;
-    const float *cb2 =  cb  + (1 << mtab->lsp_bit1)*mtab->n_lsp;
-    const float *cb3 =  cb2 + (1 << mtab->lsp_bit2)*mtab->n_lsp;
+    const float *cb  = mtab->lspcodebook;
+    const float *cb2 = cb  + (1 << mtab->lsp_bit1) * mtab->n_lsp;
+    const float *cb3 = cb2 + (1 << mtab->lsp_bit2) * mtab->n_lsp;
 
     const int8_t funny_rounding[4] = {
         -2,
@@ -570,17 +279,18 @@ static void decode_lsp(TwinContext *tctx, int lpc_idx1, uint8_t *lpc_idx2,
 
     j = 0;
     for (i = 0; i < mtab->lsp_split; i++) {
-        int chunk_end = ((i + 1)*mtab->n_lsp + funny_rounding[i])/mtab->lsp_split;
+        int chunk_end = ((i + 1) * mtab->n_lsp + funny_rounding[i]) /
+                        mtab->lsp_split;
         for (; j < chunk_end; j++)
-            lsp[j] = cb [lpc_idx1    * mtab->n_lsp + j] +
+            lsp[j] = cb[lpc_idx1     * mtab->n_lsp + j] +
                      cb2[lpc_idx2[i] * mtab->n_lsp + j];
     }
 
     rearrange_lsp(mtab->n_lsp, lsp, 0.0001);
 
     for (i = 0; i < mtab->n_lsp; i++) {
-        float tmp1 = 1. -          cb3[lpc_hist_idx*mtab->n_lsp + i];
-        float tmp2 =     hist[i] * cb3[lpc_hist_idx*mtab->n_lsp + i];
+        float tmp1 = 1.0     - cb3[lpc_hist_idx * mtab->n_lsp + i];
+        float tmp2 = hist[i] * cb3[lpc_hist_idx * mtab->n_lsp + i];
         hist[i] = lsp[i];
         lsp[i]  = lsp[i] * tmp1 + tmp2;
     }
@@ -590,97 +300,94 @@ static void decode_lsp(TwinContext *tctx, int lpc_idx1, uint8_t *lpc_idx2,
     ff_sort_nearly_sorted_floats(lsp, mtab->n_lsp);
 }
 
-static void dec_lpc_spectrum_inv(TwinContext *tctx, float *lsp,
-                                 enum FrameType ftype, float *lpc)
+static void dec_lpc_spectrum_inv(TwinVQContext *tctx, float *lsp,
+                                 enum TwinVQFrameType ftype, float *lpc)
 {
     int i;
     int size = tctx->mtab->size / tctx->mtab->fmode[ftype].sub;
 
     for (i = 0; i < tctx->mtab->n_lsp; i++)
-        lsp[i] =  2*cos(lsp[i]);
+        lsp[i] = 2 * cos(lsp[i]);
 
     switch (ftype) {
-    case FT_LONG:
+    case TWINVQ_FT_LONG:
         eval_lpcenv_2parts(tctx, ftype, lsp, lpc, size, 8);
         break;
-    case FT_MEDIUM:
+    case TWINVQ_FT_MEDIUM:
         eval_lpcenv_2parts(tctx, ftype, lsp, lpc, size, 2);
         break;
-    case FT_SHORT:
+    case TWINVQ_FT_SHORT:
         eval_lpcenv(tctx, lsp, lpc);
         break;
     }
 }
 
-static void imdct_and_window(TwinContext *tctx, enum FrameType ftype, int wtype,
-                            float *in, float *prev, int ch)
+static const uint8_t wtype_to_wsize[] = { 0, 0, 2, 2, 2, 1, 0, 1, 1 };
+
+static void imdct_and_window(TwinVQContext *tctx, enum TwinVQFrameType ftype,
+                             int wtype, float *in, float *prev, int ch)
 {
     FFTContext *mdct = &tctx->mdct_ctx[ftype];
-    const ModeTab *mtab = tctx->mtab;
+    const TwinVQModeTab *mtab = tctx->mtab;
     int bsize = mtab->size / mtab->fmode[ftype].sub;
     int size  = mtab->size;
     float *buf1 = tctx->tmp_buf;
-    int j;
-    int wsize; // Window size
-    float *out = tctx->curr_frame + 2*ch*mtab->size;
+    int j, first_wsize, wsize; // Window size
+    float *out  = tctx->curr_frame + 2 * ch * mtab->size;
     float *out2 = out;
     float *prev_buf;
-    int first_wsize;
-
-    static const uint8_t wtype_to_wsize[]      = {0, 0, 2, 2, 2, 1, 0, 1, 1};
     int types_sizes[] = {
-        mtab->size /    mtab->fmode[FT_LONG  ].sub,
-        mtab->size /    mtab->fmode[FT_MEDIUM].sub,
-        mtab->size / (2*mtab->fmode[FT_SHORT ].sub),
+        mtab->size /  mtab->fmode[TWINVQ_FT_LONG].sub,
+        mtab->size /  mtab->fmode[TWINVQ_FT_MEDIUM].sub,
+        mtab->size / (mtab->fmode[TWINVQ_FT_SHORT].sub * 2),
     };
 
-    wsize = types_sizes[wtype_to_wsize[wtype]];
+    wsize       = types_sizes[wtype_to_wsize[wtype]];
     first_wsize = wsize;
-    prev_buf = prev + (size - bsize)/2;
+    prev_buf    = prev + (size - bsize) / 2;
 
     for (j = 0; j < mtab->fmode[ftype].sub; j++) {
-        int sub_wtype = ftype == FT_MEDIUM ? 8 : wtype;
+        int sub_wtype = ftype == TWINVQ_FT_MEDIUM ? 8 : wtype;
 
         if (!j && wtype == 4)
             sub_wtype = 4;
-        else if (j == mtab->fmode[ftype].sub-1 && wtype == 7)
+        else if (j == mtab->fmode[ftype].sub - 1 && wtype == 7)
             sub_wtype = 7;
 
         wsize = types_sizes[wtype_to_wsize[sub_wtype]];
 
-        mdct->imdct_half(mdct, buf1 + bsize*j, in + bsize*j);
+        mdct->imdct_half(mdct, buf1 + bsize * j, in + bsize * j);
 
-        tctx->dsp.vector_fmul_window(out2,
-                                     prev_buf + (bsize-wsize)/2,
-                                     buf1 + bsize*j,
-                                     ff_sine_windows[av_log2(wsize)],
-                                     wsize/2);
+        tctx->fdsp.vector_fmul_window(out2, prev_buf + (bsize - wsize) / 2,
+                                      buf1 + bsize * j,
+                                      ff_sine_windows[av_log2(wsize)],
+                                      wsize / 2);
         out2 += wsize;
 
-        memcpy(out2, buf1 + bsize*j + wsize/2, (bsize - wsize/2)*sizeof(float));
+        memcpy(out2, buf1 + bsize * j + wsize / 2,
+               (bsize - wsize / 2) * sizeof(float));
 
-        out2 += ftype == FT_MEDIUM ? (bsize-wsize)/2 : bsize - wsize;
+        out2 += ftype == TWINVQ_FT_MEDIUM ? (bsize - wsize) / 2 : bsize - wsize;
 
-        prev_buf = buf1 + bsize*j + bsize/2;
+        prev_buf = buf1 + bsize * j + bsize / 2;
     }
 
-    tctx->last_block_pos[ch] = (size + first_wsize)/2;
+    tctx->last_block_pos[ch] = (size + first_wsize) / 2;
 }
 
-static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype,
-                         float **out)
+static void imdct_output(TwinVQContext *tctx, enum TwinVQFrameType ftype,
+                         int wtype, float **out, int offset)
 {
-    const ModeTab *mtab = tctx->mtab;
-    int size1, size2;
-    float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0];
-    int i;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    float *prev_buf           = tctx->prev_frame + tctx->last_block_pos[0];
+    int size1, size2, i;
+    float *out1, *out2;
 
-    for (i = 0; i < tctx->avctx->channels; i++) {
+    for (i = 0; i < tctx->avctx->channels; i++)
         imdct_and_window(tctx, ftype, wtype,
-                         tctx->spectrum + i*mtab->size,
-                         prev_buf + 2*i*mtab->size,
+                         tctx->spectrum + i * mtab->size,
+                         prev_buf + 2 * i * mtab->size,
                          i);
-    }
 
     if (!out)
         return;
@@ -688,118 +395,68 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype,
     size2 = tctx->last_block_pos[0];
     size1 = mtab->size - size2;
 
-    memcpy(&out[0][0    ], prev_buf,         size1 * sizeof(out[0][0]));
-    memcpy(&out[0][size1], tctx->curr_frame, size2 * sizeof(out[0][0]));
+    out1 = &out[0][0] + offset;
+    memcpy(out1,         prev_buf,         size1 * sizeof(*out1));
+    memcpy(out1 + size1, tctx->curr_frame, size2 * sizeof(*out1));
 
     if (tctx->avctx->channels == 2) {
-        memcpy(&out[1][0],     &prev_buf[2*mtab->size],         size1 * sizeof(out[1][0]));
-        memcpy(&out[1][size1], &tctx->curr_frame[2*mtab->size], size2 * sizeof(out[1][0]));
-        tctx->dsp.butterflies_float(out[0], out[1], mtab->size);
+        out2 = &out[1][0] + offset;
+        memcpy(out2, &prev_buf[2 * mtab->size],
+               size1 * sizeof(*out2));
+        memcpy(out2 + size1, &tctx->curr_frame[2 * mtab->size],
+               size2 * sizeof(*out2));
+        tctx->fdsp.butterflies_float(out1, out2, mtab->size);
     }
 }
 
-static void dec_bark_env(TwinContext *tctx, const uint8_t *in, int use_hist,
-                         int ch, float *out, float gain, enum FrameType ftype)
-{
-    const ModeTab *mtab = tctx->mtab;
-    int i,j;
-    float *hist = tctx->bark_hist[ftype][ch];
-    float val = ((const float []) {0.4, 0.35, 0.28})[ftype];
-    int bark_n_coef  = mtab->fmode[ftype].bark_n_coef;
-    int fw_cb_len = mtab->fmode[ftype].bark_env_size / bark_n_coef;
-    int idx = 0;
-
-    for (i = 0; i < fw_cb_len; i++)
-        for (j = 0; j < bark_n_coef; j++, idx++) {
-            float tmp2 =
-                mtab->fmode[ftype].bark_cb[fw_cb_len*in[j] + i] * (1./4096);
-            float st = use_hist ?
-                (1. - val) * tmp2 + val*hist[idx] + 1. : tmp2 + 1.;
-
-            hist[idx] = tmp2;
-            if (st < -1.) st = 1.;
-
-            memset_float(out, st * gain, mtab->fmode[ftype].bark_tab[idx]);
-            out += mtab->fmode[ftype].bark_tab[idx];
-        }
-
-}
-
-static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb,
-                                     float *out, enum FrameType ftype)
+static void read_and_decode_spectrum(TwinVQContext *tctx, float *out,
+                                     enum TwinVQFrameType ftype)
 {
-    const ModeTab *mtab = tctx->mtab;
-    int channels = tctx->avctx->channels;
-    int sub = mtab->fmode[ftype].sub;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    TwinVQFrameData *bits     = &tctx->bits[tctx->cur_frame];
+    int channels              = tctx->avctx->channels;
+    int sub        = mtab->fmode[ftype].sub;
     int block_size = mtab->size / sub;
-    float gain[CHANNELS_MAX*SUBBLOCKS_MAX];
-    float ppc_shape[PPC_SHAPE_LEN_MAX * CHANNELS_MAX * 4];
-    uint8_t bark1[CHANNELS_MAX][SUBBLOCKS_MAX][BARK_N_COEF_MAX];
-    uint8_t bark_use_hist[CHANNELS_MAX][SUBBLOCKS_MAX];
+    float gain[TWINVQ_CHANNELS_MAX * TWINVQ_SUBBLOCKS_MAX];
+    float ppc_shape[TWINVQ_PPC_SHAPE_LEN_MAX * TWINVQ_CHANNELS_MAX * 4];
 
-    uint8_t lpc_idx1[CHANNELS_MAX];
-    uint8_t lpc_idx2[CHANNELS_MAX][LSP_SPLIT_MAX];
-    uint8_t lpc_hist_idx[CHANNELS_MAX];
-
-    int i, j, k;
+    int i, j;
 
-    dequant(tctx, gb, out, ftype,
+    dequant(tctx, bits->main_coeffs, out, ftype,
             mtab->fmode[ftype].cb0, mtab->fmode[ftype].cb1,
             mtab->fmode[ftype].cb_len_read);
 
-    for (i = 0; i < channels; i++)
-        for (j = 0; j < sub; j++)
-            for (k = 0; k < mtab->fmode[ftype].bark_n_coef; k++)
-                bark1[i][j][k] =
-                    get_bits(gb, mtab->fmode[ftype].bark_n_bit);
-
-    for (i = 0; i < channels; i++)
-        for (j = 0; j < sub; j++)
-            bark_use_hist[i][j] = get_bits1(gb);
-
-    dec_gain(tctx, gb, ftype, gain);
-
-    for (i = 0; i < channels; i++) {
-        lpc_hist_idx[i] = get_bits(gb, tctx->mtab->lsp_bit0);
-        lpc_idx1    [i] = get_bits(gb, tctx->mtab->lsp_bit1);
-
-        for (j = 0; j < tctx->mtab->lsp_split; j++)
-            lpc_idx2[i][j] = get_bits(gb, tctx->mtab->lsp_bit2);
-    }
+    dec_gain(tctx, ftype, gain);
 
-    if (ftype == FT_LONG) {
-        int cb_len_p = (tctx->n_div[3] + mtab->ppc_shape_len*channels - 1)/
-            tctx->n_div[3];
-        dequant(tctx, gb, ppc_shape, FT_PPC, mtab->ppc_shape_cb,
-                mtab->ppc_shape_cb + cb_len_p*PPC_SHAPE_CB_SIZE, cb_len_p);
+    if (ftype == TWINVQ_FT_LONG) {
+        int cb_len_p = (tctx->n_div[3] + mtab->ppc_shape_len * channels - 1) /
+                       tctx->n_div[3];
+        dequant(tctx, bits->ppc_coeffs, ppc_shape,
+                TWINVQ_FT_PPC, mtab->ppc_shape_cb,
+                mtab->ppc_shape_cb + cb_len_p * TWINVQ_PPC_SHAPE_CB_SIZE,
+                cb_len_p);
     }
 
     for (i = 0; i < channels; i++) {
         float *chunk = out + mtab->size * i;
-        float lsp[LSP_COEFS_MAX];
+        float lsp[TWINVQ_LSP_COEFS_MAX];
 
         for (j = 0; j < sub; j++) {
-            dec_bark_env(tctx, bark1[i][j], bark_use_hist[i][j], i,
-                         tctx->tmp_buf, gain[sub*i+j], ftype);
+            tctx->dec_bark_env(tctx, bits->bark1[i][j],
+                               bits->bark_use_hist[i][j], i,
+                               tctx->tmp_buf, gain[sub * i + j], ftype);
 
-            tctx->fdsp.vector_fmul(chunk + block_size*j, chunk + block_size*j,
+            tctx->fdsp.vector_fmul(chunk + block_size * j,
+                                   chunk + block_size * j,
                                    tctx->tmp_buf, block_size);
-
         }
 
-        if (ftype == FT_LONG) {
-            float pgain_step = 25000. / ((1 << mtab->pgain_bit) - 1);
-            int p_coef = get_bits(gb, tctx->mtab->ppc_period_bit);
-            int g_coef = get_bits(gb, tctx->mtab->pgain_bit);
-            float v = 1./8192*
-                mulawinv(pgain_step*g_coef+ pgain_step/2, 25000., PGAIN_MU);
-
-            decode_ppc(tctx, p_coef, ppc_shape + i*mtab->ppc_shape_len, v,
-                       chunk);
-        }
+        if (ftype == TWINVQ_FT_LONG)
+            tctx->decode_ppc(tctx, bits->p_coef[i], bits->g_coef[i],
+                             ppc_shape + i * mtab->ppc_shape_len, chunk);
 
-        decode_lsp(tctx, lpc_idx1[i], lpc_idx2[i], lpc_hist_idx[i], lsp,
-                   tctx->lsp_hist[i]);
+        decode_lsp(tctx, bits->lpc_idx1[i], bits->lpc_idx2[i],
+                   bits->lpc_hist_idx[i], lsp, tctx->lsp_hist[i]);
 
         dec_lpc_spectrum_inv(tctx, lsp, ftype, tctx->tmp_buf);
 
@@ -810,54 +467,53 @@ static void read_and_decode_spectrum(TwinContext *tctx, GetBitContext *gb,
     }
 }
 
-static int twin_decode_frame(AVCodecContext * avctx, void *data,
-                             int *got_frame_ptr, AVPacket *avpkt)
+const enum TwinVQFrameType ff_twinvq_wtype_to_ftype_table[] = {
+    TWINVQ_FT_LONG,   TWINVQ_FT_LONG, TWINVQ_FT_SHORT, TWINVQ_FT_LONG,
+    TWINVQ_FT_MEDIUM, TWINVQ_FT_LONG, TWINVQ_FT_LONG,  TWINVQ_FT_MEDIUM,
+    TWINVQ_FT_MEDIUM
+};
+
+int ff_twinvq_decode_frame(AVCodecContext *avctx, void *data,
+                           int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    TwinContext *tctx = avctx->priv_data;
-    GetBitContext gb;
-    const ModeTab *mtab = tctx->mtab;
+    int buf_size       = avpkt->size;
+    TwinVQContext *tctx = avctx->priv_data;
+    const TwinVQModeTab *mtab = tctx->mtab;
     float **out = NULL;
-    enum FrameType ftype;
-    int window_type, ret;
-    static const enum FrameType wtype_to_ftype_table[] = {
-        FT_LONG,   FT_LONG, FT_SHORT, FT_LONG,
-        FT_MEDIUM, FT_LONG, FT_LONG,  FT_MEDIUM, FT_MEDIUM
-    };
-
-    if (buf_size*8 < avctx->bit_rate*mtab->size/avctx->sample_rate + 8) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Frame too small (%d bytes). Truncated file?\n", buf_size);
-        return AVERROR(EINVAL);
-    }
+    int ret;
 
     /* get output buffer */
     if (tctx->discarded_packets >= 2) {
-        tctx->frame.nb_samples = mtab->size;
-        if ((ret = ff_get_buffer(avctx, &tctx->frame)) < 0) {
+        frame->nb_samples = mtab->size * tctx->frames_per_packet;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
-        out = (float **)tctx->frame.extended_data;
+        out = (float **)frame->extended_data;
     }
 
-    init_get_bits(&gb, buf, buf_size * 8);
-    skip_bits(&gb, get_bits(&gb, 8));
-    window_type = get_bits(&gb, WINDOW_TYPE_BITS);
-
-    if (window_type > 8) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
-        return -1;
+    if (buf_size < avctx->block_align) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Frame too small (%d bytes). Truncated file?\n", buf_size);
+        return AVERROR(EINVAL);
     }
 
-    ftype = wtype_to_ftype_table[window_type];
+    if ((ret = tctx->read_bitstream(avctx, tctx, buf, buf_size)) < 0)
+        return ret;
 
-    read_and_decode_spectrum(tctx, &gb, tctx->spectrum, ftype);
+    for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet;
+         tctx->cur_frame++) {
+        read_and_decode_spectrum(tctx, tctx->spectrum,
+                                 tctx->bits[tctx->cur_frame].ftype);
 
-    imdct_output(tctx, ftype, window_type, out);
+        imdct_output(tctx, tctx->bits[tctx->cur_frame].ftype,
+                     tctx->bits[tctx->cur_frame].window_type, out,
+                     tctx->cur_frame * mtab->size);
 
-    FFSWAP(float*, tctx->curr_frame, tctx->prev_frame);
+        FFSWAP(float *, tctx->curr_frame, tctx->prev_frame);
+    }
 
     if (tctx->discarded_packets < 2) {
         tctx->discarded_packets++;
@@ -865,28 +521,30 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data,
         return buf_size;
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = tctx->frame;;
+    *got_frame_ptr = 1;
 
-    return buf_size;
+    // VQF can deliver packets 1 byte greater than block align
+    if (buf_size == avctx->block_align + 1)
+        return buf_size;
+    return avctx->block_align;
 }
 
 /**
  * Init IMDCT and windowing tables
  */
-static av_cold int init_mdct_win(TwinContext *tctx)
+static av_cold int init_mdct_win(TwinVQContext *tctx)
 {
     int i, j, ret;
-    const ModeTab *mtab = tctx->mtab;
-    int size_s = mtab->size / mtab->fmode[FT_SHORT].sub;
-    int size_m = mtab->size / mtab->fmode[FT_MEDIUM].sub;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int size_s = mtab->size / mtab->fmode[TWINVQ_FT_SHORT].sub;
+    int size_m = mtab->size / mtab->fmode[TWINVQ_FT_MEDIUM].sub;
     int channels = tctx->avctx->channels;
-    float norm = channels == 1 ? 2. : 1.;
+    float norm = channels == 1 ? 2.0 : 1.0;
 
     for (i = 0; i < 3; i++) {
-        int bsize = tctx->mtab->size/tctx->mtab->fmode[i].sub;
+        int bsize = tctx->mtab->size / tctx->mtab->fmode[i].sub;
         if ((ret = ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1,
-                                -sqrt(norm/bsize) / (1<<15))))
+                                -sqrt(norm / bsize) / (1 << 15))))
             return ret;
     }
 
@@ -904,23 +562,23 @@ static av_cold int init_mdct_win(TwinContext *tctx)
                      alloc_fail);
 
     for (i = 0; i < 3; i++) {
-        int m = 4*mtab->size/mtab->fmode[i].sub;
-        double freq = 2*M_PI/m;
+        int m       = 4 * mtab->size / mtab->fmode[i].sub;
+        double freq = 2 * M_PI / m;
         FF_ALLOC_OR_GOTO(tctx->avctx, tctx->cos_tabs[i],
                          (m / 4) * sizeof(*tctx->cos_tabs[i]), alloc_fail);
 
-        for (j = 0; j <= m/8; j++)
-            tctx->cos_tabs[i][j] = cos((2*j + 1)*freq);
-        for (j = 1; j <  m/8; j++)
-            tctx->cos_tabs[i][m/4-j] = tctx->cos_tabs[i][j];
+        for (j = 0; j <= m / 8; j++)
+            tctx->cos_tabs[i][j] = cos((2 * j + 1) * freq);
+        for (j = 1; j < m / 8; j++)
+            tctx->cos_tabs[i][m / 4 - j] = tctx->cos_tabs[i][j];
     }
 
-
     ff_init_ff_sine_windows(av_log2(size_m));
-    ff_init_ff_sine_windows(av_log2(size_s/2));
+    ff_init_ff_sine_windows(av_log2(size_s / 2));
     ff_init_ff_sine_windows(av_log2(mtab->size));
 
     return 0;
+
 alloc_fail:
     return AVERROR(ENOMEM);
 }
@@ -934,26 +592,25 @@ alloc_fail:
 static void permutate_in_line(int16_t *tab, int num_vect, int num_blocks,
                               int block_size,
                               const uint8_t line_len[2], int length_div,
-                              enum FrameType ftype)
-
+                              enum TwinVQFrameType ftype)
 {
-    int i,j;
+    int i, j;
 
     for (i = 0; i < line_len[0]; i++) {
         int shift;
 
-        if (num_blocks == 1 ||
-            (ftype == FT_LONG && num_vect % num_blocks) ||
-            (ftype != FT_LONG && num_vect & 1         ) ||
+        if (num_blocks == 1                                    ||
+            (ftype == TWINVQ_FT_LONG && num_vect % num_blocks) ||
+            (ftype != TWINVQ_FT_LONG && num_vect & 1)          ||
             i == line_len[1]) {
             shift = 0;
-        } else if (ftype == FT_LONG) {
+        } else if (ftype == TWINVQ_FT_LONG) {
             shift = i;
         } else
-            shift = i*i;
+            shift = i * i;
 
-        for (j = 0; j < num_vect && (j+num_vect*i < block_size*num_blocks); j++)
-            tab[i*num_vect+j] = i*num_vect + (j + shift) % num_vect;
+        for (j = 0; j < num_vect && (j + num_vect * i < block_size * num_blocks); j++)
+            tab[i * num_vect + j] = i * num_vect + (j + shift) % num_vect;
     }
 }
 
@@ -975,31 +632,32 @@ static void permutate_in_line(int16_t *tab, int num_vect, int num_blocks,
 static void transpose_perm(int16_t *out, int16_t *in, int num_vect,
                            const uint8_t line_len[2], int length_div)
 {
-    int i,j;
-    int cont= 0;
+    int i, j;
+    int cont = 0;
+
     for (i = 0; i < num_vect; i++)
         for (j = 0; j < line_len[i >= length_div]; j++)
-            out[cont++] = in[j*num_vect + i];
+            out[cont++] = in[j * num_vect + i];
 }
 
 static void linear_perm(int16_t *out, int16_t *in, int n_blocks, int size)
 {
-    int block_size = size/n_blocks;
+    int block_size = size / n_blocks;
     int i;
 
     for (i = 0; i < size; i++)
         out[i] = block_size * (in[i] % n_blocks) + in[i] / n_blocks;
 }
 
-static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype)
+static av_cold void construct_perm_table(TwinVQContext *tctx,
+                                         enum TwinVQFrameType ftype)
 {
-    int block_size;
-    const ModeTab *mtab = tctx->mtab;
-    int size;
-    int16_t *tmp_perm = (int16_t *) tctx->tmp_buf;
+    int block_size, size;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int16_t *tmp_perm = (int16_t *)tctx->tmp_buf;
 
-    if (ftype == FT_PPC) {
-        size  = tctx->avctx->channels;
+    if (ftype == TWINVQ_FT_PPC) {
+        size       = tctx->avctx->channels;
         block_size = mtab->ppc_shape_len;
     } else {
         size       = tctx->avctx->channels * mtab->fmode[ftype].sub;
@@ -1014,81 +672,87 @@ static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype)
                    tctx->length[ftype], tctx->length_change[ftype]);
 
     linear_perm(tctx->permut[ftype], tctx->permut[ftype], size,
-                size*block_size);
+                size * block_size);
 }
 
-static av_cold void init_bitstream_params(TwinContext *tctx)
+static av_cold void init_bitstream_params(TwinVQContext *tctx)
 {
-    const ModeTab *mtab = tctx->mtab;
-    int n_ch = tctx->avctx->channels;
-    int total_fr_bits = tctx->avctx->bit_rate*mtab->size/
-                             tctx->avctx->sample_rate;
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int n_ch                  = tctx->avctx->channels;
+    int total_fr_bits         = tctx->avctx->bit_rate * mtab->size /
+                                tctx->avctx->sample_rate;
 
-    int lsp_bits_per_block = n_ch*(mtab->lsp_bit0 + mtab->lsp_bit1 +
-                                   mtab->lsp_split*mtab->lsp_bit2);
+    int lsp_bits_per_block = n_ch * (mtab->lsp_bit0 + mtab->lsp_bit1 +
+                                     mtab->lsp_split * mtab->lsp_bit2);
 
-    int ppc_bits = n_ch*(mtab->pgain_bit + mtab->ppc_shape_bit +
-                         mtab->ppc_period_bit);
+    int ppc_bits = n_ch * (mtab->pgain_bit + mtab->ppc_shape_bit +
+                           mtab->ppc_period_bit);
 
-    int bsize_no_main_cb[3];
-    int bse_bits[3];
-    int i;
-    enum FrameType frametype;
+    int bsize_no_main_cb[3], bse_bits[3], i;
+    enum TwinVQFrameType frametype;
 
     for (i = 0; i < 3; i++)
         // +1 for history usage switch
         bse_bits[i] = n_ch *
-            (mtab->fmode[i].bark_n_coef * mtab->fmode[i].bark_n_bit + 1);
+                      (mtab->fmode[i].bark_n_coef *
+                       mtab->fmode[i].bark_n_bit + 1);
 
     bsize_no_main_cb[2] = bse_bits[2] + lsp_bits_per_block + ppc_bits +
-                          WINDOW_TYPE_BITS + n_ch*GAIN_BITS;
+                          TWINVQ_WINDOW_TYPE_BITS + n_ch * TWINVQ_GAIN_BITS;
 
     for (i = 0; i < 2; i++)
         bsize_no_main_cb[i] =
-            lsp_bits_per_block + n_ch*GAIN_BITS + WINDOW_TYPE_BITS +
-            mtab->fmode[i].sub*(bse_bits[i] + n_ch*SUB_GAIN_BITS);
+            lsp_bits_per_block + n_ch * TWINVQ_GAIN_BITS +
+            TWINVQ_WINDOW_TYPE_BITS +
+            mtab->fmode[i].sub * (bse_bits[i] + n_ch * TWINVQ_SUB_GAIN_BITS);
+
+    if (tctx->codec == TWINVQ_CODEC_METASOUND && !tctx->is_6kbps) {
+        bsize_no_main_cb[1] += 2;
+        bsize_no_main_cb[2] += 2;
+    }
 
     // The remaining bits are all used for the main spectrum coefficients
     for (i = 0; i < 4; i++) {
-        int bit_size;
-        int vect_size;
+        int bit_size, vect_size;
         int rounded_up, rounded_down, num_rounded_down, num_rounded_up;
         if (i == 3) {
             bit_size  = n_ch * mtab->ppc_shape_bit;
             vect_size = n_ch * mtab->ppc_shape_len;
         } else {
-            bit_size = total_fr_bits - bsize_no_main_cb[i];
+            bit_size  = total_fr_bits - bsize_no_main_cb[i];
             vect_size = n_ch * mtab->size;
         }
 
         tctx->n_div[i] = (bit_size + 13) / 14;
 
-        rounded_up   = (bit_size + tctx->n_div[i] - 1)/tctx->n_div[i];
-        rounded_down = (bit_size           )/tctx->n_div[i];
-        num_rounded_down = rounded_up * tctx->n_div[i] - bit_size;
-        num_rounded_up = tctx->n_div[i] - num_rounded_down;
-        tctx->bits_main_spec[0][i][0] = (rounded_up   + 1)/2;
-        tctx->bits_main_spec[1][i][0] = (rounded_up      )/2;
-        tctx->bits_main_spec[0][i][1] = (rounded_down + 1)/2;
-        tctx->bits_main_spec[1][i][1] = (rounded_down    )/2;
+        rounded_up                     = (bit_size + tctx->n_div[i] - 1) /
+                                         tctx->n_div[i];
+        rounded_down                   = (bit_size) / tctx->n_div[i];
+        num_rounded_down               = rounded_up * tctx->n_div[i] - bit_size;
+        num_rounded_up                 = tctx->n_div[i] - num_rounded_down;
+        tctx->bits_main_spec[0][i][0]  = (rounded_up + 1)   / 2;
+        tctx->bits_main_spec[1][i][0]  =  rounded_up        / 2;
+        tctx->bits_main_spec[0][i][1]  = (rounded_down + 1) / 2;
+        tctx->bits_main_spec[1][i][1]  =  rounded_down      / 2;
         tctx->bits_main_spec_change[i] = num_rounded_up;
 
-        rounded_up   = (vect_size + tctx->n_div[i] - 1)/tctx->n_div[i];
-        rounded_down = (vect_size                     )/tctx->n_div[i];
-        num_rounded_down = rounded_up * tctx->n_div[i] - vect_size;
-        num_rounded_up = tctx->n_div[i] - num_rounded_down;
-        tctx->length[i][0] = rounded_up;
-        tctx->length[i][1] = rounded_down;
+        rounded_up             = (vect_size + tctx->n_div[i] - 1) /
+                                 tctx->n_div[i];
+        rounded_down           = (vect_size) / tctx->n_div[i];
+        num_rounded_down       = rounded_up * tctx->n_div[i] - vect_size;
+        num_rounded_up         = tctx->n_div[i] - num_rounded_down;
+        tctx->length[i][0]     = rounded_up;
+        tctx->length[i][1]     = rounded_down;
         tctx->length_change[i] = num_rounded_up;
     }
 
-    for (frametype = FT_SHORT; frametype <= FT_PPC; frametype++)
+    for (frametype = TWINVQ_FT_SHORT; frametype <= TWINVQ_FT_PPC; frametype++)
         construct_perm_table(tctx, frametype);
 }
 
-static av_cold int twin_decode_close(AVCodecContext *avctx)
+av_cold int ff_twinvq_decode_close(AVCodecContext *avctx)
 {
-    TwinContext *tctx = avctx->priv_data;
+    TwinVQContext *tctx = avctx->priv_data;
     int i;
 
     for (i = 0; i < 3; i++) {
@@ -1096,7 +760,6 @@ static av_cold int twin_decode_close(AVCodecContext *avctx)
         av_free(tctx->cos_tabs[i]);
     }
 
-
     av_free(tctx->curr_frame);
     av_free(tctx->spectrum);
     av_free(tctx->prev_frame);
@@ -1105,90 +768,38 @@ static av_cold int twin_decode_close(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int twin_decode_init(AVCodecContext *avctx)
+av_cold int ff_twinvq_decode_init(AVCodecContext *avctx)
 {
     int ret;
-    TwinContext *tctx = avctx->priv_data;
-    int isampf, ibps;
+    TwinVQContext *tctx = avctx->priv_data;
 
     tctx->avctx       = avctx;
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
-    if (!avctx->extradata || avctx->extradata_size < 12) {
-        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
+    if (!avctx->block_align) {
+        avctx->block_align = tctx->frame_size + 7 >> 3;
+    } else if (avctx->block_align * 8 < tctx->frame_size) {
+        av_log(avctx, AV_LOG_ERROR, "Block align is %d bits, expected %d\n",
+               avctx->block_align * 8, tctx->frame_size);
         return AVERROR_INVALIDDATA;
     }
-    avctx->channels = AV_RB32(avctx->extradata    ) + 1;
-    avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000;
-    isampf          = AV_RB32(avctx->extradata + 8);
-
-    if (isampf < 8 || isampf > 44) {
-        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n");
-        return AVERROR_INVALIDDATA;
-    }
-    switch (isampf) {
-    case 44: avctx->sample_rate = 44100;         break;
-    case 22: avctx->sample_rate = 22050;         break;
-    case 11: avctx->sample_rate = 11025;         break;
-    default: avctx->sample_rate = isampf * 1000; break;
-    }
-
-    if (avctx->channels <= 0 || avctx->channels > CHANNELS_MAX) {
-        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
-               avctx->channels);
-        return -1;
-    }
-    avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
-                                                   AV_CH_LAYOUT_STEREO;
-
-    ibps = avctx->bit_rate / (1000 * avctx->channels);
-    if (ibps < 8 || ibps > 48) {
-        av_log(avctx, AV_LOG_ERROR, "Bad bitrate per channel value %d\n", ibps);
+    tctx->frames_per_packet = avctx->block_align * 8 / tctx->frame_size;
+    if (tctx->frames_per_packet > TWINVQ_MAX_FRAMES_PER_PACKET) {
+        av_log(avctx, AV_LOG_ERROR, "Too many frames per packet (%d)\n",
+               tctx->frames_per_packet);
         return AVERROR_INVALIDDATA;
     }
 
-    switch ((isampf << 8) +  ibps) {
-    case (8 <<8) +  8: tctx->mtab = &mode_08_08; break;
-    case (11<<8) +  8: tctx->mtab = &mode_11_08; break;
-    case (11<<8) + 10: tctx->mtab = &mode_11_10; break;
-    case (16<<8) + 16: tctx->mtab = &mode_16_16; break;
-    case (22<<8) + 20: tctx->mtab = &mode_22_20; break;
-    case (22<<8) + 24: tctx->mtab = &mode_22_24; break;
-    case (22<<8) + 32: tctx->mtab = &mode_22_32; break;
-    case (44<<8) + 40: tctx->mtab = &mode_44_40; break;
-    case (44<<8) + 48: tctx->mtab = &mode_44_48; break;
-    default:
-        av_log(avctx, AV_LOG_ERROR, "This version does not support %d kHz - %d kbit/s/ch mode.\n", isampf, isampf);
-        return -1;
-    }
-
-    ff_dsputil_init(&tctx->dsp, avctx);
     avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
     if ((ret = init_mdct_win(tctx))) {
         av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
-        twin_decode_close(avctx);
+        ff_twinvq_decode_close(avctx);
         return ret;
     }
     init_bitstream_params(tctx);
 
-    memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist));
-
-    avcodec_get_frame_defaults(&tctx->frame);
-    avctx->coded_frame = &tctx->frame;
+    twinvq_memset_float(tctx->bark_hist[0][0], 0.1,
+                        FF_ARRAY_ELEMS(tctx->bark_hist));
 
     return 0;
 }
-
-AVCodec ff_twinvq_decoder = {
-    .name           = "twinvq",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_TWINVQ,
-    .priv_data_size = sizeof(TwinContext),
-    .init           = twin_decode_init,
-    .close          = twin_decode_close,
-    .decode         = twin_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("VQF TwinVQ"),
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
-                                                      AV_SAMPLE_FMT_NONE },
-};
diff --git a/libavcodec/twinvq.h b/libavcodec/twinvq.h
new file mode 100644
index 0000000..7601e5b
--- /dev/null
+++ b/libavcodec/twinvq.h
@@ -0,0 +1,203 @@
+/*
+ * TwinVQ decoder
+ * Copyright (c) 2009 Vitor Sessak
+ *
+ * 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_TWINVQ_H
+#define AVCODEC_TWINVQ_H
+
+#include <math.h>
+#include <stdint.h>
+
+#include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
+#include "avcodec.h"
+#include "fft.h"
+#include "internal.h"
+
+enum TwinVQCodec {
+    TWINVQ_CODEC_VQF,
+    TWINVQ_CODEC_METASOUND,
+};
+
+enum TwinVQFrameType {
+    TWINVQ_FT_SHORT = 0,  ///< Short frame  (divided in n   sub-blocks)
+    TWINVQ_FT_MEDIUM,     ///< Medium frame (divided in m<n sub-blocks)
+    TWINVQ_FT_LONG,       ///< Long frame   (single sub-block + PPC)
+    TWINVQ_FT_PPC,        ///< Periodic Peak Component (part of the long frame)
+};
+
+#define TWINVQ_PPC_SHAPE_CB_SIZE 64
+#define TWINVQ_PPC_SHAPE_LEN_MAX 60
+#define TWINVQ_SUB_AMP_MAX       4500.0
+#define TWINVQ_MULAW_MU          100.0
+#define TWINVQ_GAIN_BITS         8
+#define TWINVQ_AMP_MAX           13000.0
+#define TWINVQ_SUB_GAIN_BITS     5
+#define TWINVQ_WINDOW_TYPE_BITS  4
+#define TWINVQ_PGAIN_MU          200
+#define TWINVQ_LSP_COEFS_MAX     20
+#define TWINVQ_LSP_SPLIT_MAX     4
+#define TWINVQ_CHANNELS_MAX      2
+#define TWINVQ_SUBBLOCKS_MAX     16
+#define TWINVQ_BARK_N_COEF_MAX   4
+
+#define TWINVQ_MAX_FRAMES_PER_PACKET 2
+
+/**
+ * Parameters and tables that are different for each frame type
+ */
+struct TwinVQFrameMode {
+    uint8_t         sub;      ///< Number subblocks in each frame
+    const uint16_t *bark_tab;
+
+    /** number of distinct bark scale envelope values */
+    uint8_t         bark_env_size;
+
+    const int16_t  *bark_cb;    ///< codebook for the bark scale envelope (BSE)
+    uint8_t         bark_n_coef;///< number of BSE CB coefficients to read
+    uint8_t         bark_n_bit; ///< number of bits of the BSE coefs
+
+    //@{
+    /** main codebooks for spectrum data */
+    const int16_t    *cb0;
+    const int16_t    *cb1;
+    //@}
+
+    uint8_t         cb_len_read; ///< number of spectrum coefficients to read
+};
+
+typedef struct TwinVQFrameData {
+    int     window_type;
+    enum TwinVQFrameType ftype;
+
+    uint8_t main_coeffs[1024];
+    uint8_t ppc_coeffs[TWINVQ_PPC_SHAPE_LEN_MAX];
+
+    uint8_t gain_bits[TWINVQ_CHANNELS_MAX];
+    uint8_t sub_gain_bits[TWINVQ_CHANNELS_MAX * TWINVQ_SUBBLOCKS_MAX];
+
+    uint8_t bark1[TWINVQ_CHANNELS_MAX][TWINVQ_SUBBLOCKS_MAX][TWINVQ_BARK_N_COEF_MAX];
+    uint8_t bark_use_hist[TWINVQ_CHANNELS_MAX][TWINVQ_SUBBLOCKS_MAX];
+
+    uint8_t lpc_idx1[TWINVQ_CHANNELS_MAX];
+    uint8_t lpc_idx2[TWINVQ_CHANNELS_MAX][TWINVQ_LSP_SPLIT_MAX];
+    uint8_t lpc_hist_idx[TWINVQ_CHANNELS_MAX];
+
+    int     p_coef[TWINVQ_CHANNELS_MAX];
+    int     g_coef[TWINVQ_CHANNELS_MAX];
+} TwinVQFrameData;
+
+/**
+ * Parameters and tables that are different for every combination of
+ * bitrate/sample rate
+ */
+typedef struct TwinVQModeTab {
+    struct TwinVQFrameMode fmode[3]; ///< frame type-dependant parameters
+
+    uint16_t     size;        ///< frame size in samples
+    uint8_t      n_lsp;       ///< number of lsp coefficients
+    const float *lspcodebook;
+
+    /* number of bits of the different LSP CB coefficients */
+    uint8_t      lsp_bit0;
+    uint8_t      lsp_bit1;
+    uint8_t      lsp_bit2;
+
+    uint8_t      lsp_split;      ///< number of CB entries for the LSP decoding
+    const int16_t *ppc_shape_cb; ///< PPC shape CB
+
+    /** number of the bits for the PPC period value */
+    uint8_t      ppc_period_bit;
+
+    uint8_t      ppc_shape_bit;  ///< number of bits of the PPC shape CB coeffs
+    uint8_t      ppc_shape_len;  ///< size of PPC shape CB
+    uint8_t      pgain_bit;      ///< bits for PPC gain
+
+    /** constant for peak period to peak width conversion */
+    uint16_t     peak_per2wid;
+} TwinVQModeTab;
+
+typedef struct TwinVQContext {
+    AVCodecContext *avctx;
+    AVFloatDSPContext fdsp;
+    FFTContext mdct_ctx[3];
+
+    const TwinVQModeTab *mtab;
+
+    int is_6kbps;
+
+    // history
+    float lsp_hist[2][20];           ///< LSP coefficients of the last frame
+    float bark_hist[3][2][40];       ///< BSE coefficients of last frame
+
+    // bitstream parameters
+    int16_t permut[4][4096];
+    uint8_t length[4][2];            ///< main codebook stride
+    uint8_t length_change[4];
+    uint8_t bits_main_spec[2][4][2]; ///< bits for the main codebook
+    int bits_main_spec_change[4];
+    int n_div[4];
+
+    float *spectrum;
+    float *curr_frame;               ///< non-interleaved output
+    float *prev_frame;               ///< non-interleaved previous frame
+    int last_block_pos[2];
+    int discarded_packets;
+
+    float *cos_tabs[3];
+
+    // scratch buffers
+    float *tmp_buf;
+
+    int frame_size, frames_per_packet, cur_frame;
+    TwinVQFrameData bits[TWINVQ_MAX_FRAMES_PER_PACKET];
+
+    enum TwinVQCodec codec;
+
+    int (*read_bitstream)(AVCodecContext *avctx, struct TwinVQContext *tctx,
+                          const uint8_t *buf, int buf_size);
+    void (*dec_bark_env)(struct TwinVQContext *tctx, const uint8_t *in,
+                         int use_hist, int ch, float *out, float gain,
+                         enum TwinVQFrameType ftype);
+    void (*decode_ppc)(struct TwinVQContext *tctx, int period_coef, int g_coef,
+                       const float *shape, float *speech);
+} TwinVQContext;
+
+extern const enum TwinVQFrameType ff_twinvq_wtype_to_ftype_table[];
+
+/** @note not speed critical, hence not optimized */
+static inline void twinvq_memset_float(float *buf, float val, int size)
+{
+    while (size--)
+        *buf++ = val;
+}
+
+static inline float twinvq_mulawinv(float y, float clip, float mu)
+{
+    y = av_clipf(y / clip, -1, 1);
+    return clip * FFSIGN(y) * (exp(log(1 + mu) * fabs(y)) - 1) / mu;
+}
+
+int ff_twinvq_decode_frame(AVCodecContext *avctx, void *data,
+                           int *got_frame_ptr, AVPacket *avpkt);
+av_cold int ff_twinvq_decode_close(AVCodecContext *avctx);
+av_cold int ff_twinvq_decode_init(AVCodecContext *avctx);
+
+#endif /* AVCODEC_TWINVQ_DATA_H */
diff --git a/libavcodec/twinvq_data.h b/libavcodec/twinvq_data.h
index a236127..01a54a5 100644
--- a/libavcodec/twinvq_data.h
+++ b/libavcodec/twinvq_data.h
@@ -39,95 +39,94 @@
  * for some slightly nonconventional bark-scale function
  */
 static const uint16_t bark_tab_l08_512[] = {
-    7,     8,     7,     8,     8,     8,     8,     8,     8,     9,
-    9,    10,    10,    11,    11,    12,    12,    14,    15,    16,
-   18,    19,    21,    24,    27,    30,    35,    40,    46,    53
+     7,  8,  7,  8,  8,  8,  8,  8,  8,  9,
+     9, 10, 10, 11, 11, 12, 12, 14, 15, 16,
+    18, 19, 21, 24, 27, 30, 35, 40, 46, 53
 };
 
 static const uint16_t bark_tab_l11_512[] = {
-    6,     6,     6,     6,     6,     6,     7,     6,     7,     7,
-    8,     8,     8,     9,    10,    10,    11,    13,    13,    15,
-   17,    18,    21,    25,    27,    33,    38,    45,    54,    66
+     6,  6,  6,  6,  6,  6,  7,  6,  7,  7,
+     8,  8,  8,  9, 10, 10, 11, 13, 13, 15,
+    17, 18, 21, 25, 27, 33, 38, 45, 54, 66
 };
 
 static const uint16_t bark_tab_l16_1024[] = {
-    9,     9,     8,     9,    10,     9,    10,    10,    10,    12,
-   11,    13,    13,    14,    16,    17,    19,    20,    24,    26,
-   30,    35,    40,    48,    56,    68,    83,   102,   128,   165
+     9,  9,  8,  9, 10, 9,  10,  10,  10,  12,
+    11, 13, 13, 14, 16, 17, 19,  20,  24,  26,
+    30, 35, 40, 48, 56, 68, 83, 102, 128, 165
 };
 
 static const uint16_t bark_tab_l22_1024[] = {
-    6,     7,     6,     6,     7,     7,     7,     7,     7,     8,
-    9,     8,    10,    10,    11,    12,    13,    15,    16,    18,
-   21,    24,    27,    33,    38,    46,    55,    68,    84,   107,
-  140,   191
+      6,   7,  6,  6,  7,  7,  7,  7,  7,   8,
+      9,   8, 10, 10, 11, 12, 13, 15, 16,  18,
+     21,  24, 27, 33, 38, 46, 55, 68, 84, 107,
+    140, 191
 };
 
 static const uint16_t bark_tab_l22_512[] = {
-    3,     3,     3,     4,     3,     3,     4,     3,     4,     4,
-    4,     5,     4,     5,     6,     6,     7,     7,     8,     9,
-   10,    12,    14,    16,    20,    22,    28,    34,    42,    53,
-   71,    95
+     3,  3,  3,  4,  3,  3,  4,  3,  4,  4,
+     4,  5,  4,  5,  6,  6,  7,  7,  8,  9,
+    10, 12, 14, 16, 20, 22, 28, 34, 42, 53,
+    71, 95
 };
 
 static const uint16_t bark_tab_l44_2048[] = {
-    5,     6,     5,     6,     5,     6,     6,     6,     6,     6,
-    7,     7,     7,     8,     8,     9,     9,    10,    11,    11,
-   13,    14,    16,    17,    19,    22,    25,    29,    33,    39,
-   46,    54,    64,    79,    98,   123,   161,   220,   320,   512
+     5,  6,  5,  6,  5,   6,   6,   6,   6,   6,
+     7,  7,  7,  8,  8,   9,   9,  10,  11,  11,
+    13, 14, 16, 17, 19,  22,  25,  29,  33,  39,
+    46, 54, 64, 79, 98, 123, 161, 220, 320, 512
 };
 
 static const uint16_t bark_tab_m08_256[] = {
-    6,     5,     6,     6,     6,     6,     7,     7,     8,     8,
-    9,    10,    11,    13,    15,    18,    20,    25,    31,    39
+    6,  5,  6,  6,  6,  6,  7,  7,  8,  8,
+    9, 10, 11, 13, 15, 18, 20, 25, 31, 39
 };
 
 static const uint16_t bark_tab_m11_256[] = {
-    4,     5,     4,     5,     5,     5,     6,     5,     7,     7,
-    8,     9,    10,    12,    15,    17,    22,    28,    35,    47
+    4, 5,  4,  5,  5,  5,  6,  5,  7,  7,
+    8, 9, 10, 12, 15, 17, 22, 28, 35, 47
 };
 
 static const uint16_t bark_tab_m16_512[] = {
-    7,     6,     7,     7,     7,     8,     9,     9,    10,    11,
-   14,    15,    18,    22,    27,    34,    44,    59,    81,   117
+     7,  6,  7,  7,  7,  8,  9,  9, 10,  11,
+    14, 15, 18, 22, 27, 34, 44, 59, 81, 117
 };
 
 static const uint16_t bark_tab_m22_256[] = {
-    3,     2,     3,     2,     3,     3,     4,     3,     4,     5,
-    5,     7,     8,     9,    13,    16,    22,    30,    44,    70
+    3, 2, 3, 2,  3,  3,  4,  3,  4,  5,
+    5, 7, 8, 9, 13, 16, 22, 30, 44, 70
 };
 
 static const uint16_t bark_tab_m22_512[] = {
-    5,     5,     5,     6,     5,     7,     6,     7,     9,     9,
-   11,    13,    15,    20,    24,    33,    43,    61,    88,   140
+     5,  5,  5,  6,  5,  7,  6,  7,  9,   9,
+    11, 13, 15, 20, 24, 33, 43, 61, 88, 140
 };
 
 static const uint16_t bark_tab_m44_512[] = {
-    3,     2,     3,     3,     3,     4,     3,     5,     4,     6,
-    7,     8,    10,    14,    18,    25,    36,    55,    95,   208
+    3, 2,  3,  3,  3,  4,  3,  5,  4,   6,
+    7, 8, 10, 14, 18, 25, 36, 55, 95, 208
 };
 
 static const uint16_t bark_tab_s08_64[] = {
-    3,     3,     3,     3,     4,     5,     6,     8,    12,    17
+    3, 3, 3, 3, 4, 5, 6, 8, 12, 17
 };
 
 static const uint16_t bark_tab_s11_64[] = {
-    2,     3,     2,     3,     3,     4,     6,     8,    12,    21
+    2, 3, 2, 3, 3, 4, 6, 8, 12, 21
 };
 
 static const uint16_t bark_tab_s16_128[] = {
-    3,     4,     4,     4,     5,     7,    10,    16,    26,    49
+    3, 4, 4, 4, 5, 7, 10, 16, 26, 49
 };
 
 static const uint16_t bark_tab_s22_128[] = {
-    3,     2,     3,     4,     4,     6,     9,    14,    26,    57
+    3, 2, 3, 4, 4, 6, 9, 14, 26, 57
 };
 
 static const uint16_t bark_tab_s44_128[] = {
-    1,     2,     1,     2,     3,     4,     6,    10,    23,    76
+    1, 2, 1, 2, 3, 4, 6, 10, 23, 76
 };
 
-
 /**
  * TwinVQ codebooks. They are coded in a struct so we can use code such as
  *
@@ -10991,147 +10990,155 @@ static const struct twinvq_data {
     },
 };
 
-
 static const uint8_t tab7[][35] = {
-    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0},
-    {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
-    {0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-    {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
-    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0},
-    {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
-    {0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
-    {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
-    {0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1},
-    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},
-    {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0}
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
+      0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+      0, 0, 0 },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
+      0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+      0, 0, 0 },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0,
+      0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0,
+      1, 0, 1 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0 }
 };
 
 static const uint8_t tab8[][5] = {
-    {0, 0, 0, 1, 1},
-    {0, 1, 0, 0, 1},
-    {1, 1, 0, 0, 0},
-    {1, 0, 0, 1, 0},
-    {0, 0, 0, 1, 1},
-    {0, 1, 0, 0, 1},
-    {1, 1, 0, 0, 0},
-    {1, 0, 0, 1, 0},
-    {0, 0, 0, 1, 1},
-    {0, 1, 0, 0, 1},
-    {1, 1, 0, 0, 0},
-    {0, 0, 0, 0, 0},
-    {0, 1, 0, 1, 0}
+    { 0, 0, 0, 1, 1 },
+    { 0, 1, 0, 0, 1 },
+    { 1, 1, 0, 0, 0 },
+    { 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 1, 1 },
+    { 0, 1, 0, 0, 1 },
+    { 1, 1, 0, 0, 0 },
+    { 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 1, 1 },
+    { 0, 1, 0, 0, 1 },
+    { 1, 1, 0, 0, 0 },
+    { 0, 0, 0, 0, 0 },
+    { 0, 1, 0, 1, 0 }
 };
 
 static const uint8_t tab9[][45] = {
-    {
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-     0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    },{
-     0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1,
-     1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0
-    },{
-     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
-     0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    }
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1,
+      1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
 };
 
-static const uint8_t tab10[][25] =
-{
-    {1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0},
-    {1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
-    {1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0},
-    {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-    {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1},
-    {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1},
-    {1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
-    {0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1}
+static const uint8_t tab10[][25] = {
+    { 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0,
+      0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0 },
+    { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0,
+      0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
+    { 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0,
+      0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
+    { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
+      0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+    { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+      0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 },
+    { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+      0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 },
+    { 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+      0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+    { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0,
+      0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1 }
 };
 
 static const uint8_t tab11[][55] = {
-    {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0
-    },{
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    }, {
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    },{
-        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
-    }
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
+    { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }
 };
 
 static const uint8_t tab12[][15] = {
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0},
-    {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
-    {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0},
-    {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
-    {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
-    {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0},
-    {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
-    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1},
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+    { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+    { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0 },
+    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1 },
 };
 
 static const struct {
     int size;
     const uint8_t *tab;
 } tabs[] = {
-    {0 , NULL},
-    {5 , &tab8 [0][0]},{5 , &tab8 [0][0]}, {15, &tab12[0][0]},
-    {5 , &tab8 [0][0]},{25, &tab10[0][0]}, {15, &tab12[0][0]},
-    {35, &tab7 [0][0]},{5 , &tab8 [0][0]}, {45, &tab9 [0][0]},
-    {25, &tab10[0][0]},{55, &tab11[0][0]}, {15, &tab12[0][0]}
+    {  0, NULL         },
+    {  5, &tab8[0][0]  }, {  5, &tab8[0][0]  }, { 15, &tab12[0][0] },
+    {  5, &tab8[0][0]  }, { 25, &tab10[0][0] }, { 15, &tab12[0][0] },
+    { 35, &tab7[0][0]  }, {  5, &tab8[0][0]  }, { 45, &tab9[0][0]  },
+    { 25, &tab10[0][0] }, { 55, &tab11[0][0] }, { 15, &tab12[0][0] }
 };
 
 #endif /* AVCODEC_TWINVQ_DATA_H */
diff --git a/libavcodec/twinvqdec.c b/libavcodec/twinvqdec.c
new file mode 100644
index 0000000..65028a6
--- /dev/null
+++ b/libavcodec/twinvqdec.c
@@ -0,0 +1,427 @@
+/*
+ * TwinVQ decoder
+ * Copyright (c) 2009 Vitor Sessak
+ *
+ * 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 <math.h>
+#include <stdint.h>
+
+#include "libavutil/channel_layout.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "twinvq.h"
+#include "twinvq_data.h"
+
+static const TwinVQModeTab mode_08_08 = {
+    {
+        { 8, bark_tab_s08_64,  10, tab.fcb08s, 1, 5, tab.cb0808s0, tab.cb0808s1, 18 },
+        { 2, bark_tab_m08_256, 20, tab.fcb08m, 2, 5, tab.cb0808m0, tab.cb0808m1, 16 },
+        { 1, bark_tab_l08_512, 30, tab.fcb08l, 3, 6, tab.cb0808l0, tab.cb0808l1, 17 }
+    },
+    512, 12, tab.lsp08, 1, 5, 3, 3, tab.shape08, 8, 28, 20, 6, 40
+};
+
+static const TwinVQModeTab mode_11_08 = {
+    {
+        { 8, bark_tab_s11_64,  10, tab.fcb11s, 1, 5, tab.cb1108s0, tab.cb1108s1, 29 },
+        { 2, bark_tab_m11_256, 20, tab.fcb11m, 2, 5, tab.cb1108m0, tab.cb1108m1, 24 },
+        { 1, bark_tab_l11_512, 30, tab.fcb11l, 3, 6, tab.cb1108l0, tab.cb1108l1, 27 }
+    },
+    512, 16, tab.lsp11, 1, 6, 4, 3, tab.shape11, 9, 36, 30, 7, 90
+};
+
+static const TwinVQModeTab mode_11_10 = {
+    {
+        { 8, bark_tab_s11_64,  10, tab.fcb11s, 1, 5, tab.cb1110s0, tab.cb1110s1, 21 },
+        { 2, bark_tab_m11_256, 20, tab.fcb11m, 2, 5, tab.cb1110m0, tab.cb1110m1, 18 },
+        { 1, bark_tab_l11_512, 30, tab.fcb11l, 3, 6, tab.cb1110l0, tab.cb1110l1, 20 }
+    },
+    512, 16, tab.lsp11, 1, 6, 4, 3, tab.shape11, 9, 36, 30, 7, 90
+};
+
+static const TwinVQModeTab mode_16_16 = {
+    {
+        { 8, bark_tab_s16_128,  10, tab.fcb16s, 1, 5, tab.cb1616s0, tab.cb1616s1, 16 },
+        { 2, bark_tab_m16_512,  20, tab.fcb16m, 2, 5, tab.cb1616m0, tab.cb1616m1, 15 },
+        { 1, bark_tab_l16_1024, 30, tab.fcb16l, 3, 6, tab.cb1616l0, tab.cb1616l1, 16 }
+    },
+    1024, 16, tab.lsp16, 1, 6, 4, 3, tab.shape16, 9, 56, 60, 7, 180
+};
+
+static const TwinVQModeTab mode_22_20 = {
+    {
+        { 8, bark_tab_s22_128,  10, tab.fcb22s_1, 1, 6, tab.cb2220s0, tab.cb2220s1, 18 },
+        { 2, bark_tab_m22_512,  20, tab.fcb22m_1, 2, 6, tab.cb2220m0, tab.cb2220m1, 17 },
+        { 1, bark_tab_l22_1024, 32, tab.fcb22l_1, 4, 6, tab.cb2220l0, tab.cb2220l1, 18 }
+    },
+    1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144
+};
+
+static const TwinVQModeTab mode_22_24 = {
+    {
+        { 8, bark_tab_s22_128,  10, tab.fcb22s_1, 1, 6, tab.cb2224s0, tab.cb2224s1, 15 },
+        { 2, bark_tab_m22_512,  20, tab.fcb22m_1, 2, 6, tab.cb2224m0, tab.cb2224m1, 14 },
+        { 1, bark_tab_l22_1024, 32, tab.fcb22l_1, 4, 6, tab.cb2224l0, tab.cb2224l1, 15 }
+    },
+    1024, 16, tab.lsp22_1, 1, 6, 4, 3, tab.shape22_1, 9, 56, 36, 7, 144
+};
+
+static const TwinVQModeTab mode_22_32 = {
+    {
+        { 4, bark_tab_s22_128, 10, tab.fcb22s_2, 1, 6, tab.cb2232s0, tab.cb2232s1, 11 },
+        { 2, bark_tab_m22_256, 20, tab.fcb22m_2, 2, 6, tab.cb2232m0, tab.cb2232m1, 11 },
+        { 1, bark_tab_l22_512, 32, tab.fcb22l_2, 4, 6, tab.cb2232l0, tab.cb2232l1, 12 }
+    },
+    512, 16, tab.lsp22_2, 1, 6, 4, 4, tab.shape22_2, 9, 56, 36, 7, 72
+};
+
+static const TwinVQModeTab mode_44_40 = {
+    {
+        { 16, bark_tab_s44_128,  10, tab.fcb44s, 1, 6, tab.cb4440s0, tab.cb4440s1, 18 },
+        { 4,  bark_tab_m44_512,  20, tab.fcb44m, 2, 6, tab.cb4440m0, tab.cb4440m1, 17 },
+        { 1,  bark_tab_l44_2048, 40, tab.fcb44l, 4, 6, tab.cb4440l0, tab.cb4440l1, 17 }
+    },
+    2048, 20, tab.lsp44, 1, 6, 4, 4, tab.shape44, 9, 84, 54, 7, 432
+};
+
+static const TwinVQModeTab mode_44_48 = {
+    {
+        { 16, bark_tab_s44_128,  10, tab.fcb44s, 1, 6, tab.cb4448s0, tab.cb4448s1, 15 },
+        { 4,  bark_tab_m44_512,  20, tab.fcb44m, 2, 6, tab.cb4448m0, tab.cb4448m1, 14 },
+        { 1,  bark_tab_l44_2048, 40, tab.fcb44l, 4, 6, tab.cb4448l0, tab.cb4448l1, 14 }
+    },
+    2048, 20, tab.lsp44, 1, 6, 4, 4, tab.shape44, 9, 84, 54, 7, 432
+};
+
+/**
+ * Evaluate a * b / 400 rounded to the nearest integer. When, for example,
+ * a * b == 200 and the nearest integer is ill-defined, use a table to emulate
+ * the following broken float-based implementation used by the binary decoder:
+ *
+ * @code
+ * static int very_broken_op(int a, int b)
+ * {
+ *    static float test; // Ugh, force gcc to do the division first...
+ *
+ *    test = a / 400.0;
+ *    return b * test + 0.5;
+ * }
+ * @endcode
+ *
+ * @note if this function is replaced by just ROUNDED_DIV(a * b, 400.0), the
+ * stddev between the original file (before encoding with Yamaha encoder) and
+ * the decoded output increases, which leads one to believe that the encoder
+ * expects exactly this broken calculation.
+ */
+static int very_broken_op(int a, int b)
+{
+    int x = a * b + 200;
+    int size;
+    const uint8_t *rtab;
+
+    if (x % 400 || b % 5)
+        return x / 400;
+
+    x /= 400;
+
+    size = tabs[b / 5].size;
+    rtab = tabs[b / 5].tab;
+    return x - rtab[size * av_log2(2 * (x - 1) / size) + (x - 1) % size];
+}
+
+/**
+ * Sum to data a periodic peak of a given period, width and shape.
+ *
+ * @param period the period of the peak divised by 400.0
+ */
+static void add_peak(int period, int width, const float *shape,
+                     float ppc_gain, float *speech, int len)
+{
+    int i, j;
+
+    const float *shape_end = shape + len;
+    int center;
+
+    // First peak centered around zero
+    for (i = 0; i < width / 2; i++)
+        speech[i] += ppc_gain * *shape++;
+
+    for (i = 1; i < ROUNDED_DIV(len, width); i++) {
+        center = very_broken_op(period, i);
+        for (j = -width / 2; j < (width + 1) / 2; j++)
+            speech[j + center] += ppc_gain * *shape++;
+    }
+
+    // For the last block, be careful not to go beyond the end of the buffer
+    center = very_broken_op(period, i);
+    for (j = -width / 2; j < (width + 1) / 2 && shape < shape_end; j++)
+        speech[j + center] += ppc_gain * *shape++;
+}
+
+static void decode_ppc(TwinVQContext *tctx, int period_coef, int g_coef,
+                       const float *shape, float *speech)
+{
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int isampf = tctx->avctx->sample_rate /  1000;
+    int ibps   = tctx->avctx->bit_rate    / (1000 * tctx->avctx->channels);
+    int min_period   = ROUNDED_DIV(40 * 2 * mtab->size, isampf);
+    int max_period   = ROUNDED_DIV(40 * 2 * mtab->size * 6, isampf);
+    int period_range = max_period - min_period;
+    float pgain_step = 25000.0 / ((1 << mtab->pgain_bit) - 1);
+    float ppc_gain   = 1.0 / 8192 *
+                       twinvq_mulawinv(pgain_step * g_coef +
+                                           pgain_step / 2,
+                                       25000.0, TWINVQ_PGAIN_MU);
+
+    // This is actually the period multiplied by 400. It is just linearly coded
+    // between its maximum and minimum value.
+    int period = min_period +
+                 ROUNDED_DIV(period_coef * period_range,
+                             (1 << mtab->ppc_period_bit) - 1);
+    int width;
+
+    if (isampf == 22 && ibps == 32) {
+        // For some unknown reason, NTT decided to code this case differently...
+        width = ROUNDED_DIV((period + 800) * mtab->peak_per2wid,
+                            400 * mtab->size);
+    } else
+        width = period * mtab->peak_per2wid / (400 * mtab->size);
+
+    add_peak(period, width, shape, ppc_gain, speech, mtab->ppc_shape_len);
+}
+
+static void dec_bark_env(TwinVQContext *tctx, const uint8_t *in, int use_hist,
+                         int ch, float *out, float gain,
+                         enum TwinVQFrameType ftype)
+{
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int i, j;
+    float *hist     = tctx->bark_hist[ftype][ch];
+    float val       = ((const float []) { 0.4, 0.35, 0.28 })[ftype];
+    int bark_n_coef = mtab->fmode[ftype].bark_n_coef;
+    int fw_cb_len   = mtab->fmode[ftype].bark_env_size / bark_n_coef;
+    int idx         = 0;
+
+    for (i = 0; i < fw_cb_len; i++)
+        for (j = 0; j < bark_n_coef; j++, idx++) {
+            float tmp2 = mtab->fmode[ftype].bark_cb[fw_cb_len * in[j] + i] *
+                         (1.0 / 4096);
+            float st   = use_hist ? (1.0 - val) * tmp2 + val * hist[idx] + 1.0
+                                  : tmp2 + 1.0;
+
+            hist[idx] = tmp2;
+            if (st < -1.0)
+                st = 1.0;
+
+            twinvq_memset_float(out, st * gain, mtab->fmode[ftype].bark_tab[idx]);
+            out += mtab->fmode[ftype].bark_tab[idx];
+        }
+}
+
+static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb,
+                         uint8_t *dst, enum TwinVQFrameType ftype)
+{
+    int i;
+
+    for (i = 0; i < tctx->n_div[ftype]; i++) {
+        int bs_second_part = (i >= tctx->bits_main_spec_change[ftype]);
+
+        *dst++ = get_bits(gb, tctx->bits_main_spec[0][ftype][bs_second_part]);
+        *dst++ = get_bits(gb, tctx->bits_main_spec[1][ftype][bs_second_part]);
+    }
+}
+
+static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,
+                                 const uint8_t *buf, int buf_size)
+{
+    TwinVQFrameData     *bits = &tctx->bits[0];
+    const TwinVQModeTab *mtab = tctx->mtab;
+    int channels              = tctx->avctx->channels;
+    int sub;
+    GetBitContext gb;
+    int i, j, k;
+
+    init_get_bits(&gb, buf, buf_size * 8);
+    skip_bits(&gb, get_bits(&gb, 8));
+
+    bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
+
+    if (bits->window_type > 8) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits[0].window_type];
+
+    sub = mtab->fmode[bits->ftype].sub;
+
+    read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
+
+    for (i = 0; i < channels; i++)
+        for (j = 0; j < sub; j++)
+            for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
+                bits->bark1[i][j][k] =
+                    get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
+
+    for (i = 0; i < channels; i++)
+        for (j = 0; j < sub; j++)
+            bits->bark_use_hist[i][j] = get_bits1(&gb);
+
+    if (bits->ftype == TWINVQ_FT_LONG) {
+        for (i = 0; i < channels; i++)
+            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+    } else {
+        for (i = 0; i < channels; i++) {
+            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+            for (j = 0; j < sub; j++)
+                bits->sub_gain_bits[i * sub + j] = get_bits(&gb,
+                                                       TWINVQ_SUB_GAIN_BITS);
+        }
+    }
+
+    for (i = 0; i < channels; i++) {
+        bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
+        bits->lpc_idx1[i]     = get_bits(&gb, mtab->lsp_bit1);
+
+        for (j = 0; j < mtab->lsp_split; j++)
+            bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
+    }
+
+    if (bits->ftype == TWINVQ_FT_LONG) {
+        read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
+        for (i = 0; i < channels; i++) {
+            bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
+            bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+        }
+    }
+
+    return 0;
+}
+
+static av_cold int twinvq_decode_init(AVCodecContext *avctx)
+{
+    int isampf, ibps;
+    TwinVQContext *tctx = avctx->priv_data;
+
+    if (!avctx->extradata || avctx->extradata_size < 12) {
+        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");
+        return AVERROR_INVALIDDATA;
+    }
+    avctx->channels = AV_RB32(avctx->extradata)     + 1;
+    avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000;
+    isampf          = AV_RB32(avctx->extradata + 8);
+
+    if (isampf < 8 || isampf > 44) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n");
+        return AVERROR_INVALIDDATA;
+    }
+    switch (isampf) {
+    case 44:
+        avctx->sample_rate = 44100;
+        break;
+    case 22:
+        avctx->sample_rate = 22050;
+        break;
+    case 11:
+        avctx->sample_rate = 11025;
+        break;
+    default:
+        avctx->sample_rate = isampf * 1000;
+        break;
+    }
+
+    if (avctx->channels <= 0 || avctx->channels > TWINVQ_CHANNELS_MAX) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",
+               avctx->channels);
+        return -1;
+    }
+    avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO
+                                                 : AV_CH_LAYOUT_STEREO;
+
+    ibps = avctx->bit_rate / (1000 * avctx->channels);
+    if (ibps < 8 || ibps > 48) {
+        av_log(avctx, AV_LOG_ERROR, "Bad bitrate per channel value %d\n", ibps);
+        return AVERROR_INVALIDDATA;
+    }
+
+    switch ((isampf << 8) + ibps) {
+    case (8 << 8) + 8:
+        tctx->mtab = &mode_08_08;
+        break;
+    case (11 << 8) + 8:
+        tctx->mtab = &mode_11_08;
+        break;
+    case (11 << 8) + 10:
+        tctx->mtab = &mode_11_10;
+        break;
+    case (16 << 8) + 16:
+        tctx->mtab = &mode_16_16;
+        break;
+    case (22 << 8) + 20:
+        tctx->mtab = &mode_22_20;
+        break;
+    case (22 << 8) + 24:
+        tctx->mtab = &mode_22_24;
+        break;
+    case (22 << 8) + 32:
+        tctx->mtab = &mode_22_32;
+        break;
+    case (44 << 8) + 40:
+        tctx->mtab = &mode_44_40;
+        break;
+    case (44 << 8) + 48:
+        tctx->mtab = &mode_44_48;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR,
+               "This version does not support %d kHz - %d kbit/s/ch mode.\n",
+               isampf, isampf);
+        return -1;
+    }
+
+    tctx->codec          = TWINVQ_CODEC_VQF;
+    tctx->read_bitstream = twinvq_read_bitstream;
+    tctx->dec_bark_env   = dec_bark_env;
+    tctx->decode_ppc     = decode_ppc;
+    tctx->frame_size     = avctx->bit_rate * tctx->mtab->size
+                                           / avctx->sample_rate + 8;
+    tctx->is_6kbps       = 0;
+    if (avctx->block_align && avctx->block_align * 8 / tctx->frame_size > 1) {
+        av_log(avctx, AV_LOG_ERROR,
+               "VQF TwinVQ should have only one frame per packet\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    return ff_twinvq_decode_init(avctx);
+}
+
+AVCodec ff_twinvq_decoder = {
+    .name           = "twinvq",
+    .long_name      = NULL_IF_CONFIG_SMALL("VQF TwinVQ"),
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_TWINVQ,
+    .priv_data_size = sizeof(TwinVQContext),
+    .init           = twinvq_decode_init,
+    .close          = ff_twinvq_decode_close,
+    .decode         = ff_twinvq_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+                                                      AV_SAMPLE_FMT_NONE },
+};
diff --git a/libavcodec/txd.c b/libavcodec/txd.c
index 8a10385..8f12291 100644
--- a/libavcodec/txd.c
+++ b/libavcodec/txd.c
@@ -28,29 +28,15 @@
 #include "internal.h"
 #include "s3tc.h"
 
-typedef struct TXDContext {
-    AVFrame picture;
-} TXDContext;
-
-static av_cold int txd_init(AVCodecContext *avctx) {
-    TXDContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
 static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt) {
-    TXDContext * const s = avctx->priv_data;
     GetByteContext gb;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+    AVFrame * const p = data;
     unsigned int version, w, h, d3d_format, depth, stride, flags;
     unsigned int y, v;
     uint8_t *ptr;
     uint32_t *pal;
+    int ret;
 
     bytestream2_init(&gb, avpkt->data, avpkt->size);
     version         = bytestream2_get_le32(&gb);
@@ -65,7 +51,7 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (version < 8 || version > 9) {
         av_log(avctx, AV_LOG_ERROR, "texture data version %i is unsupported\n",
                                                                     version);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
     if (depth == 8) {
@@ -74,19 +60,15 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
     } else {
         av_log(avctx, AV_LOG_ERROR, "depth of %i is unsupported\n", depth);
-        return -1;
+        return AVERROR_PATCHWELCOME;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
+        return ret;
 
-    if (av_image_check_size(w, h, 0, avctx))
-        return -1;
-    if (w != avctx->width || h != avctx->height)
-        avcodec_set_dimensions(avctx, w, h);
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     p->pict_type = AV_PICTURE_TYPE_I;
@@ -134,33 +116,20 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         }
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return avpkt->size;
 
 unsupported:
     av_log(avctx, AV_LOG_ERROR, "unsupported d3d format (%08x)\n", d3d_format);
-    return -1;
-}
-
-static av_cold int txd_end(AVCodecContext *avctx) {
-    TXDContext *s = avctx->priv_data;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
+    return AVERROR_PATCHWELCOME;
 }
 
 AVCodec ff_txd_decoder = {
     .name           = "txd",
+    .long_name      = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TXD,
-    .priv_data_size = sizeof(TXDContext),
-    .init           = txd_init,
-    .close          = txd_end,
     .decode         = txd_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"),
 };
diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c
index 2753196..186f1a6 100644
--- a/libavcodec/ulti.c
+++ b/libavcodec/ulti.c
@@ -30,13 +30,14 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #include "ulti_cb.h"
 
 typedef struct UltimotionDecodeContext {
     AVCodecContext *avctx;
     int width, height, blocks;
-    AVFrame frame;
+    AVFrame *frame;
     const uint8_t *ulti_codebook;
     GetByteContext gb;
 } UltimotionDecodeContext;
@@ -50,18 +51,19 @@ static av_cold int ulti_decode_init(AVCodecContext *avctx)
     s->height = avctx->height;
     s->blocks = (s->width / 8) * (s->height / 8);
     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
-    avctx->coded_frame = &s->frame;
     s->ulti_codebook = ulti_codebook;
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
 static av_cold int ulti_decode_end(AVCodecContext *avctx){
     UltimotionDecodeContext *s = avctx->priv_data;
-    AVFrame *pic = &s->frame;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
+    av_frame_free(&s->frame);
 
     return 0;
 }
@@ -221,15 +223,13 @@ static int ulti_decode_frame(AVCodecContext *avctx,
     int blocks = 0;
     int done = 0;
     int x = 0, y = 0;
-    int i;
+    int i, ret;
     int skip;
     int tmp;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     bytestream2_init(&s->gb, buf, buf_size);
@@ -370,7 +370,7 @@ static int ulti_decode_frame(AVCodecContext *avctx,
                         Luma[14] = (tmp >> 6) & 0x3F;
                         Luma[15] = tmp & 0x3F;
 
-                        ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma);
+                        ulti_convert_yuv(s->frame, tx, ty, Luma, chroma);
                     } else {
                         if (bytestream2_get_bytes_left(&s->gb) < 4)
                             goto err;
@@ -382,20 +382,20 @@ static int ulti_decode_frame(AVCodecContext *avctx,
                             Y[1] = tmp & 0x3F;
                             Y[2] = bytestream2_get_byteu(&s->gb) & 0x3F;
                             Y[3] = bytestream2_get_byteu(&s->gb) & 0x3F;
-                            ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block
+                            ulti_grad(s->frame, tx, ty, Y, chroma, angle); //draw block
                         } else { // some patterns
                             int f0, f1;
                             f0 = bytestream2_get_byteu(&s->gb);
                             f1 = tmp;
                             Y[0] = bytestream2_get_byteu(&s->gb) & 0x3F;
                             Y[1] = bytestream2_get_byteu(&s->gb) & 0x3F;
-                            ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma);
+                            ulti_pattern(s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma);
                         }
                     }
                     break;
                 }
                 if(code != 3)
-                    ulti_grad(&s->frame, tx, ty, Y, chroma, angle); // draw block
+                    ulti_grad(s->frame, tx, ty, Y, chroma, angle); // draw block
             }
             blocks++;
                 x += 8;
@@ -407,7 +407,8 @@ static int ulti_decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data= s->frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
 
     return buf_size;
 
@@ -419,6 +420,7 @@ err:
 
 AVCodec ff_ulti_decoder = {
     .name           = "ultimotion",
+    .long_name      = NULL_IF_CONFIG_SMALL("IBM UltiMotion"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ULTI,
     .priv_data_size = sizeof(UltimotionDecodeContext),
@@ -426,5 +428,4 @@ AVCodec ff_ulti_decoder = {
     .close          = ulti_decode_end,
     .decode         = ulti_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("IBM UltiMotion"),
 };
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 19c8a99..1fa9cb8 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -25,10 +25,14 @@
  * utils.
  */
 
+#include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
+#include "libavutil/frame.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
@@ -40,47 +44,28 @@
 #include "thread.h"
 #include "internal.h"
 #include "bytestream.h"
+#include "version.h"
 #include <stdlib.h>
 #include <stdarg.h>
 #include <limits.h>
 #include <float.h>
 
 static int volatile entangled_thread_counter = 0;
-static int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op);
+static int (*lockmgr_cb)(void **mutex, enum AVLockOp op);
 static void *codec_mutex;
 static void *avformat_mutex;
 
-void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
+#if FF_API_FAST_MALLOC && CONFIG_SHARED && HAVE_SYMVER
+FF_SYMVER(void*, av_fast_realloc, (void *ptr, unsigned int *size, size_t min_size), "LIBAVCODEC_55")
 {
-    if (min_size < *size)
-        return ptr;
-
-    min_size = FFMAX(17 * min_size / 16 + 32, min_size);
-
-    ptr = av_realloc(ptr, min_size);
-    /* we could set this to the unmodified min_size but this is safer
-     * if the user lost the ptr and uses NULL now
-     */
-    if (!ptr)
-        min_size = 0;
-
-    *size = min_size;
-
-    return ptr;
+    return av_fast_realloc(ptr, size, min_size);
 }
 
-void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
+FF_SYMVER(void, av_fast_malloc, (void *ptr, unsigned int *size, size_t min_size), "LIBAVCODEC_55")
 {
-    void **p = ptr;
-    if (min_size < *size)
-        return;
-    min_size = FFMAX(17 * min_size / 16 + 32, min_size);
-    av_free(*p);
-    *p = av_malloc(min_size);
-    if (!*p)
-        min_size = 0;
-    *size = min_size;
+    av_fast_malloc(ptr, size, min_size);
 }
+#endif
 
 void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
 {
@@ -106,7 +91,7 @@ AVCodec *av_codec_next(const AVCodec *c)
         return first_avcodec;
 }
 
-static void avcodec_init(void)
+static av_cold void avcodec_init(void)
 {
     static int initialized = 0;
 
@@ -114,7 +99,8 @@ static void avcodec_init(void)
         return;
     initialized = 1;
 
-    ff_dsputil_static_init();
+    if (CONFIG_DSPUTIL)
+        ff_dsputil_static_init();
 }
 
 int av_codec_is_encoder(const AVCodec *codec)
@@ -127,7 +113,7 @@ int av_codec_is_decoder(const AVCodec *codec)
     return codec && codec->decode;
 }
 
-void avcodec_register(AVCodec *codec)
+av_cold void avcodec_register(AVCodec *codec)
 {
     AVCodec **p;
     avcodec_init();
@@ -146,15 +132,30 @@ unsigned avcodec_get_edge_width(void)
     return EDGE_WIDTH;
 }
 
+#if FF_API_SET_DIMENSIONS
 void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
 {
-    s->coded_width  = width;
-    s->coded_height = height;
-    s->width        = width;
-    s->height       = height;
+    ff_set_dimensions(s, width, height);
+}
+#endif
+
+int ff_set_dimensions(AVCodecContext *s, int width, int height)
+{
+    int ret = av_image_check_size(width, height, 0, s);
+
+    if (ret < 0)
+        width = height = 0;
+    s->width  = s->coded_width  = width;
+    s->height = s->coded_height = height;
+
+    return ret;
 }
 
-#define INTERNAL_BUFFER_SIZE (32 + 1)
+#if HAVE_NEON || ARCH_PPC || HAVE_MMX
+#   define STRIDE_ALIGN 16
+#else
+#   define STRIDE_ALIGN 8
+#endif
 
 void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
                                int linesize_align[AV_NUM_DATA_POINTERS])
@@ -297,87 +298,26 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
     return ret;
 }
 
-static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame)
 {
-    AVCodecInternal *avci = avctx->internal;
-    int buf_size, ret;
-
-    av_freep(&avci->audio_data);
-    buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
-                                          frame->nb_samples, avctx->sample_fmt,
-                                          0);
-    if (buf_size < 0)
-        return AVERROR(EINVAL);
-
-    frame->data[0] = av_mallocz(buf_size);
-    if (!frame->data[0])
-        return AVERROR(ENOMEM);
-
-    ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt,
-                                   frame->data[0], buf_size, 0);
-    if (ret < 0) {
-        av_freep(&frame->data[0]);
-        return ret;
-    }
-
-    avci->audio_data = frame->data[0];
-    if (avctx->debug & FF_DEBUG_BUFFERS)
-        av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, "
-                                    "internal audio buffer used\n", frame);
-
-    return 0;
-}
-
-static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
-{
-    int i;
-    int w = s->width;
-    int h = s->height;
-    InternalBuffer *buf;
-    AVCodecInternal *avci = s->internal;
-
-    if (pic->data[0] != NULL) {
-        av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n");
-        return -1;
-    }
-    if (avci->buffer_count >= INTERNAL_BUFFER_SIZE) {
-        av_log(s, AV_LOG_ERROR, "buffer_count overflow (missing release_buffer?)\n");
-        return -1;
-    }
-
-    if (av_image_check_size(w, h, 0, s))
-        return -1;
-
-    if (!avci->buffer) {
-        avci->buffer = av_mallocz((INTERNAL_BUFFER_SIZE + 1) *
-                                  sizeof(InternalBuffer));
-    }
+    FramePool *pool = avctx->internal->pool;
+    int i, ret;
 
-    buf = &avci->buffer[avci->buffer_count];
-
-    if (buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)) {
-        for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
-            av_freep(&buf->base[i]);
-            buf->data[i] = NULL;
-        }
-    }
-
-    if (!buf->base[0]) {
-        int h_chroma_shift, v_chroma_shift;
-        int size[4] = { 0 };
-        int tmpsize;
-        int unaligned;
+    switch (avctx->codec_type) {
+    case AVMEDIA_TYPE_VIDEO: {
         AVPicture picture;
-        int stride_align[AV_NUM_DATA_POINTERS];
-        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt);
-        const int pixel_size = desc->comp[0].step_minus1 + 1;
+        int size[4] = { 0 };
+        int w = frame->width;
+        int h = frame->height;
+        int tmpsize, unaligned;
 
-        av_pix_fmt_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift,
-                                         &v_chroma_shift);
+        if (pool->format == frame->format &&
+            pool->width == frame->width && pool->height == frame->height)
+            return 0;
 
-        avcodec_align_dimensions2(s, &w, &h, stride_align);
+        avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align);
 
-        if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
+        if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
             w += EDGE_WIDTH * 2;
             h += EDGE_WIDTH * 2;
         }
@@ -385,16 +325,17 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
         do {
             // NOTE: do not align linesizes individually, this breaks e.g. assumptions
             // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2
-            av_image_fill_linesizes(picture.linesize, s->pix_fmt, w);
+            av_image_fill_linesizes(picture.linesize, avctx->pix_fmt, w);
             // increase alignment of w for next try (rhs gives the lowest bit set in w)
             w += w & ~(w - 1);
 
             unaligned = 0;
             for (i = 0; i < 4; i++)
-                unaligned |= picture.linesize[i] % stride_align[i];
+                unaligned |= picture.linesize[i] % pool->stride_align[i];
         } while (unaligned);
 
-        tmpsize = av_image_fill_pointers(picture.data, s->pix_fmt, h, NULL, picture.linesize);
+        tmpsize = av_image_fill_pointers(picture.data, avctx->pix_fmt, h,
+                                         NULL, picture.linesize);
         if (tmpsize < 0)
             return -1;
 
@@ -402,55 +343,171 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
             size[i] = picture.data[i + 1] - picture.data[i];
         size[i] = tmpsize - (picture.data[i] - picture.data[0]);
 
-        memset(buf->base, 0, sizeof(buf->base));
-        memset(buf->data, 0, sizeof(buf->data));
+        for (i = 0; i < 4; i++) {
+            av_buffer_pool_uninit(&pool->pools[i]);
+            pool->linesize[i] = picture.linesize[i];
+            if (size[i]) {
+                pool->pools[i] = av_buffer_pool_init(size[i] + 16, NULL);
+                if (!pool->pools[i]) {
+                    ret = AVERROR(ENOMEM);
+                    goto fail;
+                }
+            }
+        }
+        pool->format = frame->format;
+        pool->width  = frame->width;
+        pool->height = frame->height;
 
-        for (i = 0; i < 4 && size[i]; i++) {
-            const int h_shift = i == 0 ? 0 : h_chroma_shift;
-            const int v_shift = i == 0 ? 0 : v_chroma_shift;
+        break;
+        }
+    case AVMEDIA_TYPE_AUDIO: {
+        int ch     = av_get_channel_layout_nb_channels(frame->channel_layout);
+        int planar = av_sample_fmt_is_planar(frame->format);
+        int planes = planar ? ch : 1;
+
+        if (pool->format == frame->format && pool->planes == planes &&
+            pool->channels == ch && frame->nb_samples == pool->samples)
+            return 0;
+
+        av_buffer_pool_uninit(&pool->pools[0]);
+        ret = av_samples_get_buffer_size(&pool->linesize[0], ch,
+                                         frame->nb_samples, frame->format, 0);
+        if (ret < 0)
+            goto fail;
+
+        pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL);
+        if (!pool->pools[0]) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
 
-            buf->linesize[i] = picture.linesize[i];
+        pool->format     = frame->format;
+        pool->planes     = planes;
+        pool->channels   = ch;
+        pool->samples = frame->nb_samples;
+        break;
+        }
+    default: av_assert0(0);
+    }
+    return 0;
+fail:
+    for (i = 0; i < 4; i++)
+        av_buffer_pool_uninit(&pool->pools[i]);
+    pool->format = -1;
+    pool->planes = pool->channels = pool->samples = 0;
+    pool->width  = pool->height = 0;
+    return ret;
+}
 
-            buf->base[i] = av_malloc(size[i] + 16); //FIXME 16
-            if (buf->base[i] == NULL)
-                return -1;
-            memset(buf->base[i], 128, size[i]);
+static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+    FramePool *pool = avctx->internal->pool;
+    int planes = pool->planes;
+    int i;
 
-            // no edge if EDGE EMU or not planar YUV
-            if ((s->flags & CODEC_FLAG_EMU_EDGE) || !size[2])
-                buf->data[i] = buf->base[i];
-            else
-                buf->data[i] = buf->base[i] + FFALIGN((buf->linesize[i] * EDGE_WIDTH >> v_shift) + (pixel_size * EDGE_WIDTH >> h_shift), stride_align[i]);
-        }
-        for (; i < AV_NUM_DATA_POINTERS; i++) {
-            buf->base[i]     = buf->data[i] = NULL;
-            buf->linesize[i] = 0;
+    frame->linesize[0] = pool->linesize[0];
+
+    if (planes > AV_NUM_DATA_POINTERS) {
+        frame->extended_data = av_mallocz(planes * sizeof(*frame->extended_data));
+        frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS;
+        frame->extended_buf  = av_mallocz(frame->nb_extended_buf *
+                                          sizeof(*frame->extended_buf));
+        if (!frame->extended_data || !frame->extended_buf) {
+            av_freep(&frame->extended_data);
+            av_freep(&frame->extended_buf);
+            return AVERROR(ENOMEM);
         }
-        if (size[1] && !size[2])
-            avpriv_set_systematic_pal2((uint32_t *)buf->data[1], s->pix_fmt);
-        buf->width   = s->width;
-        buf->height  = s->height;
-        buf->pix_fmt = s->pix_fmt;
+    } else
+        frame->extended_data = frame->data;
+
+    for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) {
+        frame->buf[i] = av_buffer_pool_get(pool->pools[0]);
+        if (!frame->buf[i])
+            goto fail;
+        frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
     }
+    for (i = 0; i < frame->nb_extended_buf; i++) {
+        frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]);
+        if (!frame->extended_buf[i])
+            goto fail;
+        frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
+    }
+
+    if (avctx->debug & FF_DEBUG_BUFFERS)
+        av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame);
 
-    for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
-        pic->base[i]     = buf->base[i];
-        pic->data[i]     = buf->data[i];
-        pic->linesize[i] = buf->linesize[i];
+    return 0;
+fail:
+    av_frame_unref(frame);
+    return AVERROR(ENOMEM);
+}
+
+static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
+{
+    FramePool *pool = s->internal->pool;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
+    int pixel_size = desc->comp[0].step_minus1 + 1;
+    int h_chroma_shift, v_chroma_shift;
+    int i;
+
+    if (pic->data[0] != NULL) {
+        av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n");
+        return -1;
     }
+
+    memset(pic->data, 0, sizeof(pic->data));
     pic->extended_data = pic->data;
-    avci->buffer_count++;
+
+    av_pix_fmt_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+
+    for (i = 0; i < 4 && pool->pools[i]; i++) {
+        const int h_shift = i == 0 ? 0 : h_chroma_shift;
+        const int v_shift = i == 0 ? 0 : v_chroma_shift;
+
+        pic->linesize[i] = pool->linesize[i];
+
+        pic->buf[i] = av_buffer_pool_get(pool->pools[i]);
+        if (!pic->buf[i])
+            goto fail;
+
+        // no edge if EDGE EMU or not planar YUV
+        if ((s->flags & CODEC_FLAG_EMU_EDGE) || !pool->pools[2])
+            pic->data[i] = pic->buf[i]->data;
+        else {
+            pic->data[i] = pic->buf[i]->data +
+                FFALIGN((pic->linesize[i] * EDGE_WIDTH >> v_shift) +
+                        (pixel_size * EDGE_WIDTH >> h_shift), pool->stride_align[i]);
+        }
+    }
+    for (; i < AV_NUM_DATA_POINTERS; i++) {
+        pic->data[i] = NULL;
+        pic->linesize[i] = 0;
+    }
+    if (pic->data[1] && !pic->data[2])
+        avpriv_set_systematic_pal2((uint32_t *)pic->data[1], s->pix_fmt);
 
     if (s->debug & FF_DEBUG_BUFFERS)
-        av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d "
-                                "buffers used\n", pic, avci->buffer_count);
+        av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic);
 
     return 0;
+fail:
+    av_frame_unref(pic);
+    return AVERROR(ENOMEM);
 }
 
-int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags)
 {
+    int ret;
+
+    if ((ret = update_frame_pool(avctx, frame)) < 0)
+        return ret;
+
+#if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
     frame->type = FF_BUFFER_TYPE_INTERNAL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
     switch (avctx->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
         return video_get_buffer(avctx, frame);
@@ -461,107 +518,252 @@ int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
     }
 }
 
-int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+#if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
+int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+    return avcodec_default_get_buffer2(avctx, frame, 0);
+}
+
+typedef struct CompatReleaseBufPriv {
+    AVCodecContext avctx;
+    AVFrame frame;
+} CompatReleaseBufPriv;
+
+static void compat_free_buffer(void *opaque, uint8_t *data)
+{
+    CompatReleaseBufPriv *priv = opaque;
+    if (priv->avctx.release_buffer)
+        priv->avctx.release_buffer(&priv->avctx, &priv->frame);
+    av_freep(&priv);
+}
+
+static void compat_release_buffer(void *opaque, uint8_t *data)
 {
+    AVBufferRef *buf = opaque;
+    av_buffer_unref(&buf);
+}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
+{
+    int ret;
+
     switch (avctx->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
-        frame->width               = avctx->width;
-        frame->height              = avctx->height;
-        frame->format              = avctx->pix_fmt;
-        frame->sample_aspect_ratio = avctx->sample_aspect_ratio;
+        frame->width  = FFMAX(avctx->width, avctx->coded_width);
+        frame->height = FFMAX(avctx->height, avctx->coded_height);
+        if (frame->format < 0)
+            frame->format              = avctx->pix_fmt;
+        if (!frame->sample_aspect_ratio.num)
+            frame->sample_aspect_ratio = avctx->sample_aspect_ratio;
+
+        if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
+            return ret;
         break;
     case AVMEDIA_TYPE_AUDIO:
-        frame->sample_rate    = avctx->sample_rate;
-        frame->format         = avctx->sample_fmt;
-        frame->channel_layout = avctx->channel_layout;
+        if (!frame->sample_rate)
+            frame->sample_rate    = avctx->sample_rate;
+        if (frame->format < 0)
+            frame->format         = avctx->sample_fmt;
+        if (!frame->channel_layout) {
+            if (avctx->channel_layout) {
+                 if (av_get_channel_layout_nb_channels(avctx->channel_layout) !=
+                     avctx->channels) {
+                     av_log(avctx, AV_LOG_ERROR, "Inconsistent channel "
+                            "configuration.\n");
+                     return AVERROR(EINVAL);
+                 }
+
+                frame->channel_layout = avctx->channel_layout;
+            } else {
+                if (avctx->channels > FF_SANE_NB_CHANNELS) {
+                    av_log(avctx, AV_LOG_ERROR, "Too many channels: %d.\n",
+                           avctx->channels);
+                    return AVERROR(ENOSYS);
+                }
+
+                frame->channel_layout = av_get_default_channel_layout(avctx->channels);
+                if (!frame->channel_layout)
+                    frame->channel_layout = (1ULL << avctx->channels) - 1;
+            }
+        }
         break;
     default: return AVERROR(EINVAL);
     }
 
-    frame->pkt_pts = avctx->pkt ? avctx->pkt->pts : AV_NOPTS_VALUE;
+    frame->pkt_pts = avctx->internal->pkt ? avctx->internal->pkt->pts : AV_NOPTS_VALUE;
     frame->reordered_opaque = avctx->reordered_opaque;
 
-    return avctx->get_buffer(avctx, frame);
-}
+#if FF_API_GET_BUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
+    /*
+     * Wrap an old get_buffer()-allocated buffer in an bunch of AVBuffers.
+     * We wrap each plane in its own AVBuffer. Each of those has a reference to
+     * a dummy AVBuffer as its private data, unreffing it on free.
+     * When all the planes are freed, the dummy buffer's free callback calls
+     * release_buffer().
+     */
+    if (avctx->get_buffer) {
+        CompatReleaseBufPriv *priv = NULL;
+        AVBufferRef *dummy_buf = NULL;
+        int planes, i, ret;
 
-void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic)
-{
-    int i;
-    InternalBuffer *buf, *last;
-    AVCodecInternal *avci = s->internal;
+        if (flags & AV_GET_BUFFER_FLAG_REF)
+            frame->reference    = 1;
 
-    assert(s->codec_type == AVMEDIA_TYPE_VIDEO);
+        ret = avctx->get_buffer(avctx, frame);
+        if (ret < 0)
+            return ret;
 
-    assert(pic->type == FF_BUFFER_TYPE_INTERNAL);
-    assert(avci->buffer_count);
+        /* return if the buffers are already set up
+         * this would happen e.g. when a custom get_buffer() calls
+         * avcodec_default_get_buffer
+         */
+        if (frame->buf[0])
+            return 0;
+
+        priv = av_mallocz(sizeof(*priv));
+        if (!priv) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        priv->avctx = *avctx;
+        priv->frame = *frame;
 
-    if (avci->buffer) {
-        buf = NULL; /* avoids warning */
-        for (i = 0; i < avci->buffer_count; i++) { //just 3-5 checks so is not worth to optimize
-            buf = &avci->buffer[i];
-            if (buf->data[0] == pic->data[0])
-                break;
+        dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, priv, 0);
+        if (!dummy_buf) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
         }
-        assert(i < avci->buffer_count);
-        avci->buffer_count--;
-        last = &avci->buffer[avci->buffer_count];
 
-        if (buf != last)
-            FFSWAP(InternalBuffer, *buf, *last);
+#define WRAP_PLANE(ref_out, data, data_size)                            \
+do {                                                                    \
+    AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf);                  \
+    if (!dummy_ref) {                                                   \
+        ret = AVERROR(ENOMEM);                                          \
+        goto fail;                                                      \
+    }                                                                   \
+    ref_out = av_buffer_create(data, data_size, compat_release_buffer,  \
+                               dummy_ref, 0);                           \
+    if (!ref_out) {                                                     \
+        av_frame_unref(frame);                                          \
+        ret = AVERROR(ENOMEM);                                          \
+        goto fail;                                                      \
+    }                                                                   \
+} while (0)
+
+        if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+
+            planes = av_pix_fmt_count_planes(frame->format);
+            /* workaround for AVHWAccel plane count of 0, buf[0] is used as
+               check for allocated buffers: make libavcodec happy */
+            if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
+                planes = 1;
+            if (!desc || planes <= 0) {
+                ret = AVERROR(EINVAL);
+                goto fail;
+            }
+
+            for (i = 0; i < planes; i++) {
+                int v_shift    = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
+                int plane_size = (frame->height >> v_shift) * frame->linesize[i];
+
+                WRAP_PLANE(frame->buf[i], frame->data[i], plane_size);
+            }
+        } else {
+            int planar = av_sample_fmt_is_planar(frame->format);
+            planes = planar ? avctx->channels : 1;
+
+            if (planes > FF_ARRAY_ELEMS(frame->buf)) {
+                frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf);
+                frame->extended_buf = av_malloc(sizeof(*frame->extended_buf) *
+                                                frame->nb_extended_buf);
+                if (!frame->extended_buf) {
+                    ret = AVERROR(ENOMEM);
+                    goto fail;
+                }
+            }
+
+            for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++)
+                WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]);
+
+            for (i = 0; i < frame->nb_extended_buf; i++)
+                WRAP_PLANE(frame->extended_buf[i],
+                           frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)],
+                           frame->linesize[0]);
+        }
+
+        av_buffer_unref(&dummy_buf);
+
+        frame->width  = avctx->width;
+        frame->height = avctx->height;
+
+        return 0;
+
+fail:
+        avctx->release_buffer(avctx, frame);
+        av_freep(&priv);
+        av_buffer_unref(&dummy_buf);
+        return ret;
     }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
 
-    for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
-        pic->data[i] = NULL;
-//        pic->base[i]=NULL;
+    ret = avctx->get_buffer2(avctx, frame, flags);
 
-    if (s->debug & FF_DEBUG_BUFFERS)
-        av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d "
-                                "buffers used\n", pic, avci->buffer_count);
+    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+        frame->width  = avctx->width;
+        frame->height = avctx->height;
+    }
+
+    return ret;
 }
 
-int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic)
+int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
 {
-    AVFrame temp_pic;
-    int i;
-
-    assert(s->codec_type == AVMEDIA_TYPE_VIDEO);
+    AVFrame tmp;
+    int ret;
 
-    /* If no picture return a new buffer */
-    if (pic->data[0] == NULL) {
-        /* We will copy from buffer, so must be readable */
-        pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
-        return ff_get_buffer(s, pic);
-    }
+    av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO);
 
-    assert(s->pix_fmt == pic->format);
+    if (!frame->data[0])
+        return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
 
-    /* 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;
+    if (av_frame_is_writable(frame))
         return 0;
+
+    av_frame_move_ref(&tmp, frame);
+
+    ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
+    if (ret < 0) {
+        av_frame_unref(&tmp);
+        return ret;
     }
 
-    /*
-     * Not internal type and reget_buffer not overridden, emulate cr buffer
-     */
-    temp_pic = *pic;
-    for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
-        pic->data[i] = pic->base[i] = NULL;
-    pic->opaque = NULL;
-    /* Allocate new frame */
-    if (ff_get_buffer(s, pic))
-        return -1;
-    /* Copy image data from old buffer to new buffer */
-    av_picture_copy((AVPicture *)pic, (AVPicture *)&temp_pic, s->pix_fmt, s->width,
-                    s->height);
-    s->release_buffer(s, &temp_pic); // Release old frame
+    av_image_copy(frame->data, frame->linesize, tmp.data, tmp.linesize,
+                  frame->format, frame->width, frame->height);
+
+    av_frame_unref(&tmp);
+
     return 0;
 }
 
+#if FF_API_GET_BUFFER
+void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic)
+{
+    av_frame_unref(pic);
+}
+
+int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic)
+{
+    av_assert0(0);
+    return AVERROR_BUG;
+}
+#endif
+
 int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size)
 {
     int i;
@@ -589,7 +791,7 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2,
 static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-    return desc->flags & PIX_FMT_HWACCEL;
+    return desc->flags & AV_PIX_FMT_FLAG_HWACCEL;
 }
 
 enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
@@ -599,6 +801,7 @@ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const en
     return fmt[0];
 }
 
+#if FF_API_AVFRAME_LAVC
 void avcodec_get_frame_defaults(AVFrame *frame)
 {
     if (frame->extended_data != frame->data)
@@ -627,18 +830,9 @@ AVFrame *avcodec_alloc_frame(void)
 
 void avcodec_free_frame(AVFrame **frame)
 {
-    AVFrame *f;
-
-    if (!frame || !*frame)
-        return;
-
-    f = *frame;
-
-    if (f->extended_data != f->data)
-        av_freep(&f->extended_data);
-
-    av_freep(frame);
+    av_frame_free(frame);
 }
+#endif
 
 int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
 {
@@ -667,8 +861,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
         av_dict_copy(&tmp, *options, 0);
 
     /* If there is a user-supplied mutex locking routine, call it. */
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
+    if (lockmgr_cb) {
+        if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
             return -1;
     }
 
@@ -685,6 +879,18 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
         goto end;
     }
 
+    avctx->internal->pool = av_mallocz(sizeof(*avctx->internal->pool));
+    if (!avctx->internal->pool) {
+        ret = AVERROR(ENOMEM);
+        goto free_and_end;
+    }
+
+    avctx->internal->to_free = av_frame_alloc();
+    if (!avctx->internal->to_free) {
+        ret = AVERROR(ENOMEM);
+        goto free_and_end;
+    }
+
     if (codec->priv_data_size > 0) {
         if (!avctx->priv_data) {
             avctx->priv_data = av_mallocz(codec->priv_data_size);
@@ -705,16 +911,18 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
     if ((ret = av_opt_set_dict(avctx, &tmp)) < 0)
         goto free_and_end;
 
-    if (avctx->coded_width && avctx->coded_height)
-        avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height);
+    if (avctx->coded_width && avctx->coded_height && !avctx->width && !avctx->height)
+        ret = ff_set_dimensions(avctx, avctx->coded_width, avctx->coded_height);
     else if (avctx->width && avctx->height)
-        avcodec_set_dimensions(avctx, avctx->width, avctx->height);
+        ret = ff_set_dimensions(avctx, avctx->width, avctx->height);
+    if (ret < 0)
+        goto free_and_end;
 
     if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height)
         && (  av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0
            || av_image_check_size(avctx->width,       avctx->height,       0, avctx) < 0)) {
         av_log(avctx, AV_LOG_WARNING, "ignoring invalid width/height values\n");
-        avcodec_set_dimensions(avctx, 0, 0);
+        ff_set_dimensions(avctx, 0, 0);
     }
 
     /* if the decoder init function was already called previously,
@@ -753,7 +961,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
         avctx->time_base.den = avctx->sample_rate;
     }
 
-    if (HAVE_THREADS && !avctx->thread_opaque) {
+    if (HAVE_THREADS) {
         ret = ff_thread_init(avctx);
         if (ret < 0) {
             goto free_and_end;
@@ -858,8 +1066,8 @@ end:
     entangled_thread_counter--;
 
     /* Release any user-supplied mutex. */
-    if (ff_lockmgr_cb) {
-        (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
+    if (lockmgr_cb) {
+        (*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
     }
     if (options) {
         av_dict_free(options);
@@ -870,6 +1078,8 @@ end:
 free_and_end:
     av_dict_free(&tmp);
     av_freep(&avctx->priv_data);
+    if (avctx->internal)
+        av_freep(&avctx->internal->pool);
     av_freep(&avctx->internal);
     avctx->codec = NULL;
     goto end;
@@ -881,13 +1091,23 @@ int ff_alloc_packet(AVPacket *avpkt, int size)
         return AVERROR(EINVAL);
 
     if (avpkt->data) {
+        AVBufferRef *buf = avpkt->buf;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
         void *destruct = avpkt->destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
 
         if (avpkt->size < size)
             return AVERROR(EINVAL);
 
         av_init_packet(avpkt);
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
         avpkt->destruct = destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+        avpkt->buf      = buf;
         avpkt->size     = size;
         return 0;
     } else {
@@ -901,26 +1121,22 @@ int ff_alloc_packet(AVPacket *avpkt, int size)
 static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
 {
     AVFrame *frame = NULL;
-    uint8_t *buf   = NULL;
     int ret;
 
-    if (!(frame = avcodec_alloc_frame()))
+    if (!(frame = av_frame_alloc()))
         return AVERROR(ENOMEM);
-    *frame = *src;
 
-    if ((ret = av_samples_get_buffer_size(&frame->linesize[0], s->channels,
-                                          s->frame_size, s->sample_fmt, 0)) < 0)
+    frame->format         = src->format;
+    frame->channel_layout = src->channel_layout;
+    frame->nb_samples     = s->frame_size;
+    ret = av_frame_get_buffer(frame, 32);
+    if (ret < 0)
         goto fail;
 
-    if (!(buf = av_malloc(ret))) {
-        ret = AVERROR(ENOMEM);
+    ret = av_frame_copy_props(frame, src);
+    if (ret < 0)
         goto fail;
-    }
 
-    frame->nb_samples = s->frame_size;
-    if ((ret = avcodec_fill_audio_frame(frame, s->channels, s->sample_fmt,
-                                        buf, ret, 0)) < 0)
-        goto fail;
     if ((ret = av_samples_copy(frame->extended_data, src->extended_data, 0, 0,
                                src->nb_samples, s->channels, s->sample_fmt)) < 0)
         goto fail;
@@ -934,10 +1150,7 @@ static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src)
     return 0;
 
 fail:
-    if (frame->extended_data != frame->data)
-        av_freep(&frame->extended_data);
-    av_freep(&buf);
-    av_freep(&frame);
+    av_frame_free(&frame);
     return ret;
 }
 
@@ -1014,9 +1227,9 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
         }
 
         if (!user_packet && avpkt->size) {
-            uint8_t *new_data = av_realloc(avpkt->data, avpkt->size);
-            if (new_data)
-                avpkt->data = new_data;
+            ret = av_buffer_realloc(&avpkt->buf, avpkt->size);
+            if (ret >= 0)
+                avpkt->data = avpkt->buf->data;
         }
 
         avctx->frame_number++;
@@ -1034,133 +1247,11 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,
     avpkt->flags |= AV_PKT_FLAG_KEY;
 
 end:
-    if (padded_frame) {
-        av_freep(&padded_frame->data[0]);
-        if (padded_frame->extended_data != padded_frame->data)
-            av_freep(&padded_frame->extended_data);
-        av_freep(&padded_frame);
-    }
+    av_frame_free(&padded_frame);
 
     return ret;
 }
 
-#if FF_API_OLD_ENCODE_AUDIO
-int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx,
-                                             uint8_t *buf, int buf_size,
-                                             const short *samples)
-{
-    AVPacket pkt;
-    AVFrame frame0 = { { 0 } };
-    AVFrame *frame;
-    int ret, samples_size, got_packet;
-
-    av_init_packet(&pkt);
-    pkt.data = buf;
-    pkt.size = buf_size;
-
-    if (samples) {
-        frame = &frame0;
-        avcodec_get_frame_defaults(frame);
-
-        if (avctx->frame_size) {
-            frame->nb_samples = avctx->frame_size;
-        } else {
-            /* if frame_size is not set, the number of samples must be
-             * calculated from the buffer size */
-            int64_t nb_samples;
-            if (!av_get_bits_per_sample(avctx->codec_id)) {
-                av_log(avctx, AV_LOG_ERROR, "avcodec_encode_audio() does not "
-                                            "support this codec\n");
-                return AVERROR(EINVAL);
-            }
-            nb_samples = (int64_t)buf_size * 8 /
-                         (av_get_bits_per_sample(avctx->codec_id) *
-                          avctx->channels);
-            if (nb_samples >= INT_MAX)
-                return AVERROR(EINVAL);
-            frame->nb_samples = nb_samples;
-        }
-
-        /* it is assumed that the samples buffer is large enough based on the
-         * relevant parameters */
-        samples_size = av_samples_get_buffer_size(NULL, avctx->channels,
-                                                  frame->nb_samples,
-                                                  avctx->sample_fmt, 1);
-        if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
-                                            avctx->sample_fmt,
-                                            (const uint8_t *)samples,
-                                            samples_size, 1)))
-            return ret;
-
-        /* 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);
-        avctx->internal->sample_count += frame->nb_samples;
-    } else {
-        frame = NULL;
-    }
-
-    got_packet = 0;
-    ret = avcodec_encode_audio2(avctx, &pkt, frame, &got_packet);
-    if (!ret && got_packet && avctx->coded_frame) {
-        avctx->coded_frame->pts       = pkt.pts;
-        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;
-    }
-
-    if (frame && frame->extended_data != frame->data)
-        av_free(frame->extended_data);
-
-    return ret ? ret : pkt.size;
-}
-
-#endif
-
-#if FF_API_OLD_ENCODE_VIDEO
-int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
-                                             const AVFrame *pict)
-{
-    AVPacket pkt;
-    int ret, got_packet = 0;
-
-    if (buf_size < FF_MIN_BUFFER_SIZE) {
-        av_log(avctx, AV_LOG_ERROR, "buffer smaller than minimum size\n");
-        return -1;
-    }
-
-    av_init_packet(&pkt);
-    pkt.data = buf;
-    pkt.size = buf_size;
-
-    ret = avcodec_encode_video2(avctx, &pkt, pict, &got_packet);
-    if (!ret && got_packet && avctx->coded_frame) {
-        avctx->coded_frame->pts       = pkt.pts;
-        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;
-    }
-
-    return ret ? ret : pkt.size;
-}
-
-#endif
-
 int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
                                               AVPacket *avpkt,
                                               const AVFrame *frame,
@@ -1191,9 +1282,9 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx,
             avpkt->pts = avpkt->dts = frame->pts;
 
         if (!user_packet && avpkt->size) {
-            uint8_t *new_data = av_realloc(avpkt->data, avpkt->size);
-            if (new_data)
-                avpkt->data = new_data;
+            ret = av_buffer_realloc(&avpkt->buf, avpkt->size);
+            if (ret >= 0)
+                avpkt->data = avpkt->buf->data;
         }
 
         avctx->frame_number++;
@@ -1221,62 +1312,128 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
     return ret;
 }
 
-static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt)
+static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt)
 {
-    int size = 0;
+    int size = 0, ret;
     const uint8_t *data;
     uint32_t flags;
 
-    if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE))
-        return;
-
     data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size);
-    if (!data || size < 4)
-        return;
+    if (!data)
+        return 0;
+
+    if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) {
+        av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter "
+               "changes, but PARAM_CHANGE side data was sent to it.\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (size < 4)
+        goto fail;
+
     flags = bytestream_get_le32(&data);
     size -= 4;
-    if (size < 4) /* Required for any of the changes */
-        return;
+
     if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) {
+        if (size < 4)
+            goto fail;
         avctx->channels = bytestream_get_le32(&data);
         size -= 4;
     }
     if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) {
         if (size < 8)
-            return;
+            goto fail;
         avctx->channel_layout = bytestream_get_le64(&data);
         size -= 8;
     }
-    if (size < 4)
-        return;
     if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) {
+        if (size < 4)
+            goto fail;
         avctx->sample_rate = bytestream_get_le32(&data);
         size -= 4;
     }
     if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) {
         if (size < 8)
-            return;
+            goto fail;
         avctx->width  = bytestream_get_le32(&data);
         avctx->height = bytestream_get_le32(&data);
-        avcodec_set_dimensions(avctx, avctx->width, avctx->height);
         size -= 8;
+        ret = ff_set_dimensions(avctx, avctx->width, avctx->height);
+        if (ret < 0)
+            return ret;
     }
+
+    return 0;
+fail:
+    av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n");
+    return AVERROR_INVALIDDATA;
+}
+
+static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame)
+{
+    int ret;
+
+    /* move the original frame to our backup */
+    av_frame_unref(avci->to_free);
+    av_frame_move_ref(avci->to_free, frame);
+
+    /* now copy everything except the AVBufferRefs back
+     * note that we make a COPY of the side data, so calling av_frame_free() on
+     * the caller's frame will work properly */
+    ret = av_frame_copy_props(frame, avci->to_free);
+    if (ret < 0)
+        return ret;
+
+    memcpy(frame->data,     avci->to_free->data,     sizeof(frame->data));
+    memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize));
+    if (avci->to_free->extended_data != avci->to_free->data) {
+        int planes = av_get_channel_layout_nb_channels(avci->to_free->channel_layout);
+        int size   = planes * sizeof(*frame->extended_data);
+
+        if (!size) {
+            av_frame_unref(frame);
+            return AVERROR_BUG;
+        }
+
+        frame->extended_data = av_malloc(size);
+        if (!frame->extended_data) {
+            av_frame_unref(frame);
+            return AVERROR(ENOMEM);
+        }
+        memcpy(frame->extended_data, avci->to_free->extended_data,
+               size);
+    } else
+        frame->extended_data = frame->data;
+
+    frame->format         = avci->to_free->format;
+    frame->width          = avci->to_free->width;
+    frame->height         = avci->to_free->height;
+    frame->channel_layout = avci->to_free->channel_layout;
+    frame->nb_samples     = avci->to_free->nb_samples;
+
+    return 0;
 }
 
 int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
                                               int *got_picture_ptr,
                                               AVPacket *avpkt)
 {
+    AVCodecInternal *avci = avctx->internal;
     int ret;
 
     *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);
+    avctx->internal->pkt = avpkt;
+    ret = apply_param_change(avctx, avpkt);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");
+        if (avctx->err_recognition & AV_EF_EXPLODE)
+            return ret;
+    }
 
-    avcodec_get_frame_defaults(picture);
+    av_frame_unref(picture);
 
     if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
         if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
@@ -1297,86 +1454,47 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
 
         emms_c(); //needed to avoid an emms_c() call before every return;
 
-        if (*got_picture_ptr)
+        if (*got_picture_ptr) {
+            if (!avctx->refcounted_frames) {
+                int err = unrefcount_frame(avci, picture);
+                if (err < 0)
+                    return err;
+            }
+
             avctx->frame_number++;
+        } else
+            av_frame_unref(picture);
     } else
         ret = 0;
 
-    /* many decoders assign whole AVFrames, thus overwriting extended_data;
-     * make sure it's set correctly */
-    picture->extended_data = picture->data;
-
     return ret;
 }
 
-#if FF_API_OLD_DECODE_AUDIO
-int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
-                                              int *frame_size_ptr,
-                                              AVPacket *avpkt)
-{
-    AVFrame frame = { { 0 } };
-    int ret, got_frame = 0;
-
-    if (avctx->get_buffer != avcodec_default_get_buffer) {
-        av_log(avctx, AV_LOG_ERROR, "Custom get_buffer() for use with"
-                                    "avcodec_decode_audio3() detected. Overriding with avcodec_default_get_buffer\n");
-        av_log(avctx, AV_LOG_ERROR, "Please port your application to "
-                                    "avcodec_decode_audio4()\n");
-        avctx->get_buffer = avcodec_default_get_buffer;
-    }
-
-    ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt);
-
-    if (ret >= 0 && got_frame) {
-        int ch, plane_size;
-        int planar    = av_sample_fmt_is_planar(avctx->sample_fmt);
-        int data_size = av_samples_get_buffer_size(&plane_size, avctx->channels,
-                                                   frame.nb_samples,
-                                                   avctx->sample_fmt, 1);
-        if (*frame_size_ptr < data_size) {
-            av_log(avctx, AV_LOG_ERROR, "output buffer size is too small for "
-                                        "the current frame (%d < %d)\n", *frame_size_ptr, data_size);
-            return AVERROR(EINVAL);
-        }
-
-        memcpy(samples, frame.extended_data[0], plane_size);
-
-        if (planar && avctx->channels > 1) {
-            uint8_t *out = ((uint8_t *)samples) + plane_size;
-            for (ch = 1; ch < avctx->channels; ch++) {
-                memcpy(out, frame.extended_data[ch], plane_size);
-                out += plane_size;
-            }
-        }
-        *frame_size_ptr = data_size;
-    } else {
-        *frame_size_ptr = 0;
-    }
-    return ret;
-}
-
-#endif
-
 int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
                                               AVFrame *frame,
                                               int *got_frame_ptr,
                                               AVPacket *avpkt)
 {
-    int planar, channels;
+    AVCodecInternal *avci = avctx->internal;
     int ret = 0;
 
     *got_frame_ptr = 0;
 
-    avctx->pkt = avpkt;
+    avctx->internal->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);
+    ret = apply_param_change(avctx, avpkt);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");
+        if (avctx->err_recognition & AV_EF_EXPLODE)
+            return ret;
+    }
 
-    avcodec_get_frame_defaults(frame);
+    av_frame_unref(frame);
 
     if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
         ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt);
@@ -1385,16 +1503,16 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
             frame->pkt_dts = avpkt->dts;
             if (frame->format == AV_SAMPLE_FMT_NONE)
                 frame->format = avctx->sample_fmt;
-        }
+
+            if (!avctx->refcounted_frames) {
+                int err = unrefcount_frame(avci, frame);
+                if (err < 0)
+                    return err;
+            }
+        } else
+            av_frame_unref(frame);
     }
 
-    /* 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;
 
     return ret;
 }
@@ -1405,7 +1523,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
 {
     int ret;
 
-    avctx->pkt = avpkt;
+    avctx->internal->pkt = avpkt;
     *got_sub_ptr = 0;
     ret = avctx->codec->decode(avctx, sub, got_sub_ptr, avpkt);
     if (*got_sub_ptr)
@@ -1435,8 +1553,8 @@ void avsubtitle_free(AVSubtitle *sub)
 av_cold int avcodec_close(AVCodecContext *avctx)
 {
     /* If there is a user-supplied mutex locking routine, call it. */
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
+    if (lockmgr_cb) {
+        if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
             return -1;
     }
 
@@ -1448,12 +1566,17 @@ av_cold int avcodec_close(AVCodecContext *avctx)
     }
 
     if (avcodec_is_open(avctx)) {
-        if (HAVE_THREADS && avctx->thread_opaque)
+        FramePool *pool = avctx->internal->pool;
+        int i;
+        if (HAVE_THREADS && avctx->internal->thread_ctx)
             ff_thread_free(avctx);
         if (avctx->codec && avctx->codec->close)
             avctx->codec->close(avctx);
-        avcodec_default_free_buffers(avctx);
         avctx->coded_frame = NULL;
+        av_frame_free(&avctx->internal->to_free);
+        for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)
+            av_buffer_pool_uninit(&pool->pools[i]);
+        av_freep(&avctx->internal->pool);
         av_freep(&avctx->internal);
     }
 
@@ -1468,8 +1591,8 @@ av_cold int avcodec_close(AVCodecContext *avctx)
     entangled_thread_counter--;
 
     /* Release any user-supplied mutex. */
-    if (ff_lockmgr_cb) {
-        (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
+    if (lockmgr_cb) {
+        (*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
     }
     return 0;
 }
@@ -1556,9 +1679,14 @@ size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_ta
 {
     int i, len, ret = 0;
 
+#define TAG_PRINT(x)                                              \
+    (((x) >= '0' && (x) <= '9') ||                                \
+     ((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z') ||  \
+     ((x) == '.' || (x) == ' '))
+
     for (i = 0; i < 4; i++) {
         len = snprintf(buf, buf_size,
-                       isprint(codec_tag & 0xFF) ? "%c" : "[%d]", codec_tag & 0xFF);
+                       TAG_PRINT(codec_tag & 0xFF) ? "%c" : "[%d]", codec_tag & 0xFF);
         buf        += len;
         buf_size    = buf_size > len ? buf_size - len : 0;
         ret        += len;
@@ -1720,49 +1848,9 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
         ff_thread_flush(avctx);
     else if (avctx->codec->flush)
         avctx->codec->flush(avctx);
-}
 
-static void video_free_buffers(AVCodecContext *s)
-{
-    AVCodecInternal *avci = s->internal;
-    int i, j;
-
-    if (!avci->buffer)
-        return;
-
-    if (avci->buffer_count)
-        av_log(s, AV_LOG_WARNING, "Found %i unreleased buffers!\n",
-               avci->buffer_count);
-    for (i = 0; i < INTERNAL_BUFFER_SIZE; i++) {
-        InternalBuffer *buf = &avci->buffer[i];
-        for (j = 0; j < 4; j++) {
-            av_freep(&buf->base[j]);
-            buf->data[j] = NULL;
-        }
-    }
-    av_freep(&avci->buffer);
-
-    avci->buffer_count = 0;
-}
-
-static void audio_free_buffers(AVCodecContext *avctx)
-{
-    AVCodecInternal *avci = avctx->internal;
-    av_freep(&avci->audio_data);
-}
-
-void avcodec_default_free_buffers(AVCodecContext *avctx)
-{
-    switch (avctx->codec_type) {
-    case AVMEDIA_TYPE_VIDEO:
-        video_free_buffers(avctx);
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        audio_free_buffers(avctx);
-        break;
-    default:
-        break;
-    }
+    if (!avctx->refcounted_frames)
+        av_frame_unref(avctx->internal->to_free);
 }
 
 int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
@@ -1790,11 +1878,13 @@ int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
     case AV_CODEC_ID_PCM_S24DAUD:
     case AV_CODEC_ID_PCM_S24BE:
     case AV_CODEC_ID_PCM_S24LE:
+    case AV_CODEC_ID_PCM_S24LE_PLANAR:
     case AV_CODEC_ID_PCM_U24BE:
     case AV_CODEC_ID_PCM_U24LE:
         return 24;
     case AV_CODEC_ID_PCM_S32BE:
     case AV_CODEC_ID_PCM_S32LE:
+    case AV_CODEC_ID_PCM_S32LE_PLANAR:
     case AV_CODEC_ID_PCM_U32BE:
     case AV_CODEC_ID_PCM_U32LE:
     case AV_CODEC_ID_PCM_F32BE:
@@ -2002,6 +2092,8 @@ int ff_match_2uint16(const uint16_t(*tab)[2], int size, int a, int b)
     return i;
 }
 
+#if FF_API_MISSING_SAMPLE
+FF_DISABLE_DEPRECATION_WARNINGS
 void av_log_missing_feature(void *avc, const char *feature, int want_sample)
 {
     av_log(avc, AV_LOG_WARNING, "%s is not implemented. Update your Libav "
@@ -2026,6 +2118,8 @@ void av_log_ask_for_sample(void *avc, const char *msg, ...)
 
     va_end(argument_list);
 }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_MISSING_SAMPLE */
 
 static AVHWAccel *first_hwaccel = NULL;
 
@@ -2043,8 +2137,11 @@ AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel)
     return hwaccel ? hwaccel->next : first_hwaccel;
 }
 
-AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt)
+AVHWAccel *ff_find_hwaccel(AVCodecContext *avctx)
 {
+    enum AVCodecID codec_id = avctx->codec->id;
+    enum AVPixelFormat pix_fmt = avctx->pix_fmt;
+
     AVHWAccel *hwaccel = NULL;
 
     while ((hwaccel = av_hwaccel_next(hwaccel)))
@@ -2056,19 +2153,19 @@ AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt)
 
 int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
 {
-    if (ff_lockmgr_cb) {
-        if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
+    if (lockmgr_cb) {
+        if (lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
             return -1;
-        if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
+        if (lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
             return -1;
     }
 
-    ff_lockmgr_cb = cb;
+    lockmgr_cb = cb;
 
-    if (ff_lockmgr_cb) {
-        if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
+    if (lockmgr_cb) {
+        if (lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
             return -1;
-        if (ff_lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
+        if (lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
             return -1;
     }
     return 0;
@@ -2076,8 +2173,8 @@ int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
 
 int avpriv_lock_avformat(void)
 {
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_OBTAIN))
+    if (lockmgr_cb) {
+        if ((*lockmgr_cb)(&avformat_mutex, AV_LOCK_OBTAIN))
             return -1;
     }
     return 0;
@@ -2085,8 +2182,8 @@ int avpriv_lock_avformat(void)
 
 int avpriv_unlock_avformat(void)
 {
-    if (ff_lockmgr_cb) {
-        if ((*ff_lockmgr_cb)(&avformat_mutex, AV_LOCK_RELEASE))
+    if (lockmgr_cb) {
+        if ((*lockmgr_cb)(&avformat_mutex, AV_LOCK_RELEASE))
             return -1;
     }
     return 0;
@@ -2094,34 +2191,53 @@ int avpriv_unlock_avformat(void)
 
 unsigned int avpriv_toupper4(unsigned int x)
 {
-    return toupper(x & 0xFF)
-           + (toupper((x >> 8) & 0xFF) << 8)
-           + (toupper((x >> 16) & 0xFF) << 16)
-           + (toupper((x >> 24) & 0xFF) << 24);
+    return av_toupper(x & 0xFF) +
+          (av_toupper((x >>  8) & 0xFF) << 8)  +
+          (av_toupper((x >> 16) & 0xFF) << 16) +
+          (av_toupper((x >> 24) & 0xFF) << 24);
+}
+
+int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src)
+{
+    int ret;
+
+    dst->owner = src->owner;
+
+    ret = av_frame_ref(dst->f, src->f);
+    if (ret < 0)
+        return ret;
+
+    if (src->progress &&
+        !(dst->progress = av_buffer_ref(src->progress))) {
+        ff_thread_release_buffer(dst->owner, dst);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
 }
 
 #if !HAVE_THREADS
 
-int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
+int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
 {
     f->owner = avctx;
-    return ff_get_buffer(avctx, f);
+    return ff_get_buffer(avctx, f->f, flags);
 }
 
-void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
+void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
 {
-    f->owner->release_buffer(f->owner, f);
+    av_frame_unref(f->f);
 }
 
 void ff_thread_finish_setup(AVCodecContext *avctx)
 {
 }
 
-void ff_thread_report_progress(AVFrame *f, int progress, int field)
+void ff_thread_report_progress(ThreadFrame *f, int progress, int field)
 {
 }
 
-void ff_thread_await_progress(AVFrame *f, int progress, int field)
+void ff_thread_await_progress(ThreadFrame *f, int progress, int field)
 {
 }
 
@@ -2145,3 +2261,36 @@ int avcodec_is_open(AVCodecContext *s)
 {
     return !!s->internal;
 }
+
+const uint8_t *avpriv_find_start_code(const uint8_t *restrict p,
+                                      const uint8_t *end,
+                                      uint32_t * restrict state)
+{
+    int i;
+
+    assert(p <= end);
+    if (p >= end)
+        return end;
+
+    for (i = 0; i < 3; i++) {
+        uint32_t tmp = *state << 8;
+        *state = tmp + *(p++);
+        if (tmp == 0x100 || p == end)
+            return p;
+    }
+
+    while (p < end) {
+        if      (p[-1] > 1      ) p += 3;
+        else if (p[-2]          ) p += 2;
+        else if (p[-3]|(p[-1]-1)) p++;
+        else {
+            p++;
+            break;
+        }
+    }
+
+    p = FFMIN(p, end) - 4;
+    *state = AV_RB32(p);
+
+    return p + 4;
+}
diff --git a/libavcodec/utvideo.h b/libavcodec/utvideo.h
index 0d7664c..0a1317e 100644
--- a/libavcodec/utvideo.h
+++ b/libavcodec/utvideo.h
@@ -65,7 +65,6 @@ extern const int ff_ut_rgb_order[4];
 
 typedef struct UtvideoContext {
     AVCodecContext *avctx;
-    AVFrame        pic;
     DSPContext     dsp;
 
     uint32_t frame_info_size, flags, frame_info;
diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index 3f8f690..3492595 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -331,13 +331,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
     int ret;
     GetByteContext gb;
+    ThreadFrame frame = { .f = data };
 
-    if (c->pic.data[0])
-        ff_thread_release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = ff_thread_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -380,7 +376,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     c->frame_pred = (c->frame_info >> 8) & 3;
 
     if (c->frame_pred == PRED_GRADIENT) {
-        av_log_ask_for_sample(avctx, "Frame uses gradient prediction\n");
+        avpriv_request_sample(avctx, "Frame with gradient prediction");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -396,42 +392,42 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     case AV_PIX_FMT_RGB24:
     case AV_PIX_FMT_RGBA:
         for (i = 0; i < c->planes; i++) {
-            ret = decode_plane(c, i, c->pic.data[0] + ff_ut_rgb_order[i],
-                               c->planes, c->pic.linesize[0], avctx->width,
+            ret = decode_plane(c, i, frame.f->data[0] + ff_ut_rgb_order[i],
+                               c->planes, frame.f->linesize[0], avctx->width,
                                avctx->height, plane_start[i],
                                c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median(c->pic.data[0] + ff_ut_rgb_order[i],
-                                   c->planes, c->pic.linesize[0], avctx->width,
+                    restore_median(frame.f->data[0] + ff_ut_rgb_order[i],
+                                   c->planes, frame.f->linesize[0], avctx->width,
                                    avctx->height, c->slices, 0);
                 } else {
-                    restore_median_il(c->pic.data[0] + ff_ut_rgb_order[i],
-                                      c->planes, c->pic.linesize[0],
+                    restore_median_il(frame.f->data[0] + ff_ut_rgb_order[i],
+                                      c->planes, frame.f->linesize[0],
                                       avctx->width, avctx->height, c->slices,
                                       0);
                 }
             }
         }
-        restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0],
+        restore_rgb_planes(frame.f->data[0], c->planes, frame.f->linesize[0],
                            avctx->width, avctx->height);
         break;
     case AV_PIX_FMT_YUV420P:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane(c, i, c->pic.data[i], 1, c->pic.linesize[i],
+            ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i],
                                avctx->width >> !!i, avctx->height >> !!i,
                                plane_start[i], c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median(c->pic.data[i], 1, c->pic.linesize[i],
+                    restore_median(frame.f->data[i], 1, frame.f->linesize[i],
                                    avctx->width >> !!i, avctx->height >> !!i,
                                    c->slices, !i);
                 } else {
-                    restore_median_il(c->pic.data[i], 1, c->pic.linesize[i],
+                    restore_median_il(frame.f->data[i], 1, frame.f->linesize[i],
                                       avctx->width  >> !!i,
                                       avctx->height >> !!i,
                                       c->slices, !i);
@@ -441,18 +437,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     case AV_PIX_FMT_YUV422P:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane(c, i, c->pic.data[i], 1, c->pic.linesize[i],
+            ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i],
                                avctx->width >> !!i, avctx->height,
                                plane_start[i], c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median(c->pic.data[i], 1, c->pic.linesize[i],
+                    restore_median(frame.f->data[i], 1, frame.f->linesize[i],
                                    avctx->width >> !!i, avctx->height,
                                    c->slices, 0);
                 } else {
-                    restore_median_il(c->pic.data[i], 1, c->pic.linesize[i],
+                    restore_median_il(frame.f->data[i], 1, frame.f->linesize[i],
                                       avctx->width >> !!i, avctx->height,
                                       c->slices, 0);
                 }
@@ -461,12 +457,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     }
 
-    c->pic.key_frame = 1;
-    c->pic.pict_type = AV_PICTURE_TYPE_I;
-    c->pic.interlaced_frame = !!c->interlaced;
+    frame.f->key_frame = 1;
+    frame.f->pict_type = AV_PICTURE_TYPE_I;
+    frame.f->interlaced_frame = !!c->interlaced;
 
-    *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
+    *got_frame = 1;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -496,7 +491,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     c->flags           = AV_RL32(avctx->extradata + 12);
 
     if (c->frame_info_size != 4)
-        av_log_ask_for_sample(avctx, "Frame info is not 4 bytes\n");
+        avpriv_request_sample(avctx, "Frame info not 4 bytes");
     av_log(avctx, AV_LOG_DEBUG, "Encoding parameters %08X\n", c->flags);
     c->slices      = (c->flags >> 24) + 1;
     c->compression = c->flags & 1;
@@ -516,10 +511,22 @@ static av_cold int decode_init(AVCodecContext *avctx)
     case MKTAG('U', 'L', 'Y', '0'):
         c->planes      = 3;
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        avctx->colorspace = AVCOL_SPC_BT470BG;
         break;
     case MKTAG('U', 'L', 'Y', '2'):
         c->planes      = 3;
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+        avctx->colorspace = AVCOL_SPC_BT470BG;
+        break;
+    case MKTAG('U', 'L', 'H', '0'):
+        c->planes      = 3;
+        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        avctx->colorspace = AVCOL_SPC_BT709;
+        break;
+    case MKTAG('U', 'L', 'H', '2'):
+        c->planes      = 3;
+        avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+        avctx->colorspace = AVCOL_SPC_BT709;
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n",
@@ -534,9 +541,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     UtvideoContext * const c = avctx->priv_data;
 
-    if (c->pic.data[0])
-        ff_thread_release_buffer(avctx, &c->pic);
-
     av_freep(&c->slice_bits);
 
     return 0;
@@ -544,6 +548,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
 AVCodec ff_utvideo_decoder = {
     .name           = "utvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_UTVIDEO,
     .priv_data_size = sizeof(UtvideoContext),
@@ -551,5 +556,4 @@ AVCodec ff_utvideo_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
-    .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
 };
diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c
index 085c415..dd8d07e 100644
--- a/libavcodec/utvideoenc.c
+++ b/libavcodec/utvideoenc.c
@@ -24,6 +24,7 @@
  * Ut Video encoder
  */
 
+#include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "internal.h"
@@ -125,7 +126,7 @@ static av_cold int utvideo_encode_init(AVCodecContext *avctx)
         return AVERROR_OPTION_NOT_FOUND;
     }
 
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
 
     if (!avctx->coded_frame) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
@@ -230,20 +231,6 @@ static void mangle_rgb_planes(uint8_t *dst[4], int dst_stride, uint8_t *src,
     }
 }
 
-/* Write data to a plane, no prediction applied */
-static void write_plane(uint8_t *src, uint8_t *dst, int stride,
-                        int width, int height)
-{
-    int i, j;
-
-    for (j = 0; j < height; j++) {
-        for (i = 0; i < width; i++)
-            *dst++ = src[i];
-
-        src += stride;
-    }
-}
-
 /* Write data to a plane with left prediction */
 static void left_predict(uint8_t *src, uint8_t *dst, int stride,
                          int width, int height)
@@ -383,8 +370,9 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src,
         for (i = 0; i < c->slices; i++) {
             sstart = send;
             send   = height * (i + 1) / c->slices;
-            write_plane(src + sstart * stride, dst + sstart * width,
-                        stride, width, send - sstart);
+            av_image_copy_plane(dst + sstart * width, width,
+                                src + sstart * stride, stride,
+                                width, send - sstart);
         }
         break;
     case PRED_LEFT:
@@ -598,7 +586,6 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
      * At least currently Ut Video is IDR only.
      * Set flags accordingly.
      */
-    avctx->coded_frame->reference = 0;
     avctx->coded_frame->key_frame = 1;
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
 
@@ -613,6 +600,7 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 
 AVCodec ff_utvideo_encoder = {
     .name           = "utvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_UTVIDEO,
     .priv_data_size = sizeof(UtvideoContext),
@@ -623,5 +611,4 @@ AVCodec ff_utvideo_encoder = {
                           AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_YUV422P,
                           AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE
                       },
-    .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
 };
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index 6c53e36..8827397 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -31,39 +31,31 @@ static av_cold int decode_init(AVCodecContext *avctx)
 {
     if (avctx->width & 1) {
         av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     avctx->pix_fmt             = AV_PIX_FMT_YUV422P10;
     avctx->bits_per_raw_sample = 10;
 
-    avctx->coded_frame         = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
     return 0;
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    int h, w;
-    AVFrame *pic = avctx->coded_frame;
+    int h, w, ret;
+    AVFrame *pic = data;
     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 (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;
+        return AVERROR_INVALIDDATA;
     }
 
-    pic->reference = 0;
-    if (ff_get_buffer(avctx, pic) < 0)
-        return -1;
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+        return ret;
 
     y = (uint16_t*)pic->data[0];
     u = (uint16_t*)pic->data[1];
@@ -110,28 +102,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = *avctx->coded_frame;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_v210_decoder = {
     .name           = "v210",
+    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_V210,
     .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"),
 };
diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c
index ad8a4a5..ef0d6ab 100644
--- a/libavcodec/v210enc.c
+++ b/libavcodec/v210enc.c
@@ -36,7 +36,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_WARNING, "bits per raw sample: %d != 10-bit\n",
                avctx->bits_per_raw_sample);
 
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame)
         return AVERROR(ENOMEM);
 
@@ -118,11 +118,11 @@ static av_cold int encode_close(AVCodecContext *avctx)
 
 AVCodec ff_v210_encoder = {
     .name           = "v210",
+    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_V210,
     .init           = encode_init,
     .encode2        = encode_frame,
     .close          = encode_close,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
 };
diff --git a/libavcodec/v210x.c b/libavcodec/v210x.c
index 0b1b721..2922c05 100644
--- a/libavcodec/v210x.c
+++ b/libavcodec/v210x.c
@@ -26,14 +26,12 @@
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
-    if(avctx->width & 1){
+    if (avctx->width & 1) {
         av_log(avctx, AV_LOG_ERROR, "v210x needs even width\n");
-        return -1;
+        return AVERROR(EINVAL);
     }
-    avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
-    avctx->bits_per_raw_sample= 10;
-
-    avctx->coded_frame= avcodec_alloc_frame();
+    avctx->pix_fmt             = AV_PIX_FMT_YUV422P16;
+    avctx->bits_per_raw_sample = 10;
 
     return 0;
 }
@@ -41,108 +39,93 @@ static av_cold int decode_init(AVCodecContext *avctx)
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
-    int y=0;
-    int width= avctx->width;
-    AVFrame *pic= avctx->coded_frame;
-    const uint32_t *src= (const uint32_t *)avpkt->data;
+    const uint32_t *src = (const uint32_t *)avpkt->data;
+    AVFrame *pic        = data;
+    int width           = avctx->width;
+    int y               = 0;
     uint16_t *ydst, *udst, *vdst, *yend;
+    int ret;
 
-    if(pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    if(avpkt->size < avctx->width * avctx->height * 8 / 3){
+    if (avpkt->size < avctx->width * avctx->height * 8 / 3) {
         av_log(avctx, AV_LOG_ERROR, "Packet too small\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    if(avpkt->size > avctx->width * avctx->height * 8 / 3){
-        av_log_ask_for_sample(avctx, "Probably padded data\n");
+    if (avpkt->size > avctx->width * avctx->height * 8 / 3) {
+        avpriv_request_sample(avctx, "(Probably) padded data");
     }
 
-    pic->reference= 0;
-    if(ff_get_buffer(avctx, pic) < 0)
-        return -1;
-
-    ydst= (uint16_t *)pic->data[0];
-    udst= (uint16_t *)pic->data[1];
-    vdst= (uint16_t *)pic->data[2];
-    yend= ydst + width;
-    pic->pict_type= AV_PICTURE_TYPE_I;
-    pic->key_frame= 1;
-
-    for(;;){
-        uint32_t v= av_be2ne32(*src++);
-        *udst++= (v>>16) & 0xFFC0;
-        *ydst++= (v>>6 ) & 0xFFC0;
-        *vdst++= (v<<4 ) & 0xFFC0;
-
-        v= av_be2ne32(*src++);
-        *ydst++= (v>>16) & 0xFFC0;
-
-        if(ydst >= yend){
-            ydst+= pic->linesize[0]/2 - width;
-            udst+= pic->linesize[1]/2 - width/2;
-            vdst+= pic->linesize[2]/2 - width/2;
-            yend= ydst + width;
-            if(++y >= avctx->height)
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+        return ret;
+
+    ydst = (uint16_t *)pic->data[0];
+    udst = (uint16_t *)pic->data[1];
+    vdst = (uint16_t *)pic->data[2];
+    yend = ydst + width;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+    pic->key_frame = 1;
+
+    for (;;) {
+        uint32_t v = av_be2ne32(*src++);
+        *udst++ = (v >> 16) & 0xFFC0;
+        *ydst++ = (v >> 6 ) & 0xFFC0;
+        *vdst++ = (v << 4 ) & 0xFFC0;
+
+        v       = av_be2ne32(*src++);
+        *ydst++ = (v >> 16) & 0xFFC0;
+
+        if (ydst >= yend) {
+            ydst += pic->linesize[0] / 2 - width;
+            udst += pic->linesize[1] / 2 - width / 2;
+            vdst += pic->linesize[2] / 2 - width / 2;
+            yend = ydst + width;
+            if (++y >= avctx->height)
                 break;
         }
 
-        *udst++= (v>>6 ) & 0xFFC0;
-        *ydst++= (v<<4 ) & 0xFFC0;
+        *udst++ = (v >> 6 ) & 0xFFC0;
+        *ydst++ = (v << 4 ) & 0xFFC0;
 
-        v= av_be2ne32(*src++);
-        *vdst++= (v>>16) & 0xFFC0;
-        *ydst++= (v>>6 ) & 0xFFC0;
+        v = av_be2ne32(*src++);
+        *vdst++ = (v >> 16) & 0xFFC0;
+        *ydst++ = (v >> 6 ) & 0xFFC0;
 
-        if(ydst >= yend){
-            ydst+= pic->linesize[0]/2 - width;
-            udst+= pic->linesize[1]/2 - width/2;
-            vdst+= pic->linesize[2]/2 - width/2;
-            yend= ydst + width;
-            if(++y >= avctx->height)
+        if (ydst >= yend) {
+            ydst += pic->linesize[0] / 2 - width;
+            udst += pic->linesize[1] / 2 - width / 2;
+            vdst += pic->linesize[2] / 2 - width / 2;
+            yend  = ydst + width;
+            if (++y >= avctx->height)
                 break;
         }
 
-        *udst++= (v<<4 ) & 0xFFC0;
-
-        v= av_be2ne32(*src++);
-        *ydst++= (v>>16) & 0xFFC0;
-        *vdst++= (v>>6 ) & 0xFFC0;
-        *ydst++= (v<<4 ) & 0xFFC0;
-        if(ydst >= yend){
-            ydst+= pic->linesize[0]/2 - width;
-            udst+= pic->linesize[1]/2 - width/2;
-            vdst+= pic->linesize[2]/2 - width/2;
-            yend= ydst + width;
-            if(++y >= avctx->height)
+        *udst++ = (v << 4 ) & 0xFFC0;
+
+        v = av_be2ne32(*src++);
+        *ydst++ = (v >> 16) & 0xFFC0;
+        *vdst++ = (v >> 6 ) & 0xFFC0;
+        *ydst++ = (v << 4 ) & 0xFFC0;
+        if (ydst >= yend) {
+            ydst += pic->linesize[0] / 2 - width;
+            udst += pic->linesize[1] / 2 - width / 2;
+            vdst += pic->linesize[2] / 2 - width / 2;
+            yend  = ydst + width;
+            if (++y >= avctx->height)
                 break;
         }
     }
 
     *got_frame = 1;
-    *(AVFrame*)data= *avctx->coded_frame;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_v210x_decoder = {
     .name           = "v210x",
+    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_V210X,
     .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"),
 };
diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c
index efd2093..07be502 100644
--- a/libavcodec/v410dec.c
+++ b/libavcodec/v410dec.c
@@ -39,36 +39,24 @@ static av_cold int v410_decode_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 v410_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     uint8_t *src = avpkt->data;
     uint16_t *y, *u, *v;
     uint32_t val;
     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 (ff_get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -97,28 +85,16 @@ static int v410_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
 
-static av_cold int v410_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_v410_decoder = {
     .name         = "v410",
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"),
     .type         = AVMEDIA_TYPE_VIDEO,
     .id           = AV_CODEC_ID_V410,
     .init         = v410_decode_init,
     .decode       = v410_decode_frame,
-    .close        = v410_decode_close,
     .capabilities = CODEC_CAP_DR1,
-    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"),
 };
diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c
index cc7cef7..77b32d7 100644
--- a/libavcodec/v410enc.c
+++ b/libavcodec/v410enc.c
@@ -32,7 +32,7 @@ static av_cold int v410_encode_init(AVCodecContext *avctx)
         return AVERROR_INVALIDDATA;
     }
 
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
 
     if (!avctx->coded_frame) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
@@ -56,7 +56,6 @@ static int v410_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     }
     dst = pkt->data;
 
-    avctx->coded_frame->reference = 0;
     avctx->coded_frame->key_frame = 1;
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
 
@@ -91,11 +90,11 @@ static av_cold int v410_encode_close(AVCodecContext *avctx)
 
 AVCodec ff_v410_encoder = {
     .name         = "v410",
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"),
     .type         = AVMEDIA_TYPE_VIDEO,
     .id           = AV_CODEC_ID_V410,
     .init         = v410_encode_init,
     .encode2      = v410_encode_frame,
     .close        = v410_encode_close,
     .pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE },
-    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"),
 };
diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c
index d6b0298..0532daf 100644
--- a/libavcodec/vaapi.c
+++ b/libavcodec/vaapi.c
@@ -21,6 +21,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "h264.h"
 #include "vaapi_internal.h"
 
 /**
@@ -40,7 +41,7 @@ static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int
     }
 }
 
-static int render_picture(struct vaapi_context *vactx, VASurfaceID surface)
+int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface)
 {
     VABufferID va_buffers[3];
     unsigned int n_va_buffers = 0;
@@ -77,7 +78,7 @@ static int render_picture(struct vaapi_context *vactx, VASurfaceID surface)
     return 0;
 }
 
-static int commit_slices(struct vaapi_context *vactx)
+int ff_vaapi_commit_slices(struct vaapi_context *vactx)
 {
     VABufferID *slice_buf_ids;
     VABufferID slice_param_buf_id, slice_data_buf_id;
@@ -152,7 +153,7 @@ VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, co
     if (!vactx->slice_data)
         vactx->slice_data = buffer;
     if (vactx->slice_data + vactx->slice_data_size != buffer) {
-        if (commit_slices(vactx) < 0)
+        if (ff_vaapi_commit_slices(vactx) < 0)
             return NULL;
         vactx->slice_data = buffer;
     }
@@ -175,23 +176,12 @@ VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, co
     return slice_param;
 }
 
-int ff_vaapi_common_end_frame(MpegEncContext *s)
+void ff_vaapi_common_end_frame(AVCodecContext *avctx)
 {
-    struct vaapi_context * const vactx = s->avctx->hwaccel_context;
-    int ret = -1;
+    struct vaapi_context * const vactx = avctx->hwaccel_context;
 
-    av_dlog(s->avctx, "ff_vaapi_common_end_frame()\n");
+    av_dlog(avctx, "ff_vaapi_common_end_frame()\n");
 
-    if (commit_slices(vactx) < 0)
-        goto done;
-    if (vactx->n_slice_buf_ids > 0) {
-        if (render_picture(vactx, ff_vaapi_get_surface_id(s->current_picture_ptr)) < 0)
-            goto done;
-        ff_draw_horiz_band(s, 0, s->avctx->height);
-    }
-    ret = 0;
-
-done:
     destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1);
     destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1);
     destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1);
@@ -202,6 +192,27 @@ done:
     vactx->slice_buf_ids_alloc = 0;
     vactx->slice_count         = 0;
     vactx->slice_params_alloc  = 0;
+}
+
+int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx)
+{
+    struct vaapi_context * const vactx = avctx->hwaccel_context;
+    MpegEncContext *s = avctx->priv_data;
+    int ret;
+
+    ret = ff_vaapi_commit_slices(vactx);
+    if (ret < 0)
+        goto finish;
+
+    ret = ff_vaapi_render_picture(vactx,
+                                  ff_vaapi_get_surface_id(s->current_picture_ptr));
+    if (ret < 0)
+        goto finish;
+
+    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
+
+finish:
+    ff_vaapi_common_end_frame(avctx);
     return ret;
 }
 
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index 4ffc7d8..dfa2ec7 100644
--- a/libavcodec/vaapi_h264.c
+++ b/libavcodec/vaapi_h264.c
@@ -55,7 +55,7 @@ static void fill_vaapi_pic(VAPictureH264 *va_pic,
                            int            pic_structure)
 {
     if (pic_structure == 0)
-        pic_structure = pic->f.reference;
+        pic_structure = pic->reference;
     pic_structure &= PICT_FRAME; /* PICT_TOP_FIELD|PICT_BOTTOM_FIELD */
 
     va_pic->picture_id = ff_vaapi_get_surface_id(pic);
@@ -64,7 +64,7 @@ static void fill_vaapi_pic(VAPictureH264 *va_pic,
     va_pic->flags      = 0;
     if (pic_structure != PICT_FRAME)
         va_pic->flags |= (pic_structure & PICT_TOP_FIELD) ? VA_PICTURE_H264_TOP_FIELD : VA_PICTURE_H264_BOTTOM_FIELD;
-    if (pic->f.reference)
+    if (pic->reference)
         va_pic->flags |= pic->long_ref ? VA_PICTURE_H264_LONG_TERM_REFERENCE : VA_PICTURE_H264_SHORT_TERM_REFERENCE;
 
     va_pic->TopFieldOrderCnt = 0;
@@ -134,13 +134,13 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param,
 
     for (i = 0; i < h->short_ref_count; i++) {
         Picture * const pic = h->short_ref[i];
-        if (pic && pic->f.reference && dpb_add(&dpb, pic) < 0)
+        if (pic && pic->reference && dpb_add(&dpb, pic) < 0)
             return -1;
     }
 
     for (i = 0; i < 16; i++) {
         Picture * const pic = h->long_ref[i];
-        if (pic && pic->f.reference && dpb_add(&dpb, pic) < 0)
+        if (pic && pic->reference && dpb_add(&dpb, pic) < 0)
             return -1;
     }
     return 0;
@@ -160,7 +160,7 @@ static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32],
 {
     unsigned int i, n = 0;
     for (i = 0; i < ref_count; i++)
-        if (ref_list[i].f.reference)
+        if (ref_list[i].reference)
             fill_vaapi_pic(&RefPicList[n++], &ref_list[i], 0);
 
     for (; n < 32; n++)
@@ -219,17 +219,16 @@ static void fill_vaapi_plain_pred_weight_table(H264Context   *h,
 }
 
 /** Initialize and start decoding a frame with VA API. */
-static int start_frame(AVCodecContext          *avctx,
-                       av_unused const uint8_t *buffer,
-                       av_unused uint32_t       size)
+static int vaapi_h264_start_frame(AVCodecContext          *avctx,
+                                  av_unused const uint8_t *buffer,
+                                  av_unused uint32_t       size)
 {
     H264Context * const h = avctx->priv_data;
-    MpegEncContext * const s = &h->s;
     struct vaapi_context * const vactx = avctx->hwaccel_context;
     VAPictureParameterBufferH264 *pic_param;
     VAIQMatrixBufferH264 *iq_matrix;
 
-    av_dlog(avctx, "start_frame()\n");
+    av_dlog(avctx, "vaapi_h264_start_frame()\n");
 
     vactx->slice_param_size = sizeof(VASliceParameterBufferH264);
 
@@ -237,11 +236,11 @@ static int start_frame(AVCodecContext          *avctx,
     pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferH264));
     if (!pic_param)
         return -1;
-    fill_vaapi_pic(&pic_param->CurrPic, s->current_picture_ptr, s->picture_structure);
+    fill_vaapi_pic(&pic_param->CurrPic, h->cur_pic_ptr, h->picture_structure);
     if (fill_vaapi_ReferenceFrames(pic_param, h) < 0)
         return -1;
-    pic_param->picture_width_in_mbs_minus1                      = s->mb_width - 1;
-    pic_param->picture_height_in_mbs_minus1                     = s->mb_height - 1;
+    pic_param->picture_width_in_mbs_minus1                      = h->mb_width - 1;
+    pic_param->picture_height_in_mbs_minus1                     = h->mb_height - 1;
     pic_param->bit_depth_luma_minus8                            = h->sps.bit_depth_luma - 8;
     pic_param->bit_depth_chroma_minus8                          = h->sps.bit_depth_chroma - 8;
     pic_param->num_ref_frames                                   = h->sps.ref_frame_count;
@@ -269,7 +268,7 @@ static int start_frame(AVCodecContext          *avctx,
     pic_param->pic_fields.bits.weighted_pred_flag               = h->pps.weighted_pred;
     pic_param->pic_fields.bits.weighted_bipred_idc              = h->pps.weighted_bipred_idc;
     pic_param->pic_fields.bits.transform_8x8_mode_flag          = h->pps.transform_8x8_mode;
-    pic_param->pic_fields.bits.field_pic_flag                   = s->picture_structure != PICT_FRAME;
+    pic_param->pic_fields.bits.field_pic_flag                   = h->picture_structure != PICT_FRAME;
     pic_param->pic_fields.bits.constrained_intra_pred_flag      = h->pps.constrained_intra_pred;
     pic_param->pic_fields.bits.pic_order_present_flag           = h->pps.pic_order_present;
     pic_param->pic_fields.bits.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
@@ -287,37 +286,51 @@ static int start_frame(AVCodecContext          *avctx,
 }
 
 /** End a hardware decoding based frame. */
-static int end_frame(AVCodecContext *avctx)
+static int vaapi_h264_end_frame(AVCodecContext *avctx)
 {
+    struct vaapi_context * const vactx = avctx->hwaccel_context;
     H264Context * const h = avctx->priv_data;
+    int ret;
+
+    av_dlog(avctx, "vaapi_h264_end_frame()\n");
+    ret = ff_vaapi_commit_slices(vactx);
+    if (ret < 0)
+        goto finish;
+
+    ret = ff_vaapi_render_picture(vactx, ff_vaapi_get_surface_id(h->cur_pic_ptr));
+    if (ret < 0)
+        goto finish;
+
+    ff_h264_draw_horiz_band(h, 0, h->avctx->height);
 
-    av_dlog(avctx, "end_frame()\n");
-    return ff_vaapi_common_end_frame(&h->s);
+finish:
+    ff_vaapi_common_end_frame(avctx);
+    return ret;
 }
 
 /** Decode the given H.264 slice with VA API. */
-static int decode_slice(AVCodecContext *avctx,
-                        const uint8_t  *buffer,
-                        uint32_t        size)
+static int vaapi_h264_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t  *buffer,
+                                   uint32_t        size)
 {
     H264Context * const h = avctx->priv_data;
-    MpegEncContext * const s = &h->s;
     VASliceParameterBufferH264 *slice_param;
 
-    av_dlog(avctx, "decode_slice(): buffer %p, size %d\n", buffer, size);
+    av_dlog(avctx, "vaapi_h264_decode_slice(): buffer %p, size %d\n",
+            buffer, size);
 
     /* Fill in VASliceParameterBufferH264. */
     slice_param = (VASliceParameterBufferH264 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size);
     if (!slice_param)
         return -1;
-    slice_param->slice_data_bit_offset          = get_bits_count(&h->s.gb) + 8; /* bit buffer started beyond nal_unit_type */
-    slice_param->first_mb_in_slice              = (s->mb_y >> FIELD_OR_MBAFF_PICTURE) * s->mb_width + s->mb_x;
+    slice_param->slice_data_bit_offset          = get_bits_count(&h->gb) + 8; /* bit buffer started beyond nal_unit_type */
+    slice_param->first_mb_in_slice              = (h->mb_y >> FIELD_OR_MBAFF_PICTURE(h)) * h->mb_width + h->mb_x;
     slice_param->slice_type                     = ff_h264_get_slice_type(h);
     slice_param->direct_spatial_mv_pred_flag    = h->slice_type == AV_PICTURE_TYPE_B ? h->direct_spatial_mv_pred : 0;
     slice_param->num_ref_idx_l0_active_minus1   = h->list_count > 0 ? h->ref_count[0] - 1 : 0;
     slice_param->num_ref_idx_l1_active_minus1   = h->list_count > 1 ? h->ref_count[1] - 1 : 0;
     slice_param->cabac_init_idc                 = h->cabac_init_idc;
-    slice_param->slice_qp_delta                 = s->qscale - h->pps.init_qp;
+    slice_param->slice_qp_delta                 = h->qscale - h->pps.init_qp;
     slice_param->disable_deblocking_filter_idc  = h->deblocking_filter < 2 ? !h->deblocking_filter : h->deblocking_filter;
     slice_param->slice_alpha_c0_offset_div2     = h->slice_alpha_c0_offset / 2 - 26;
     slice_param->slice_beta_offset_div2         = h->slice_beta_offset     / 2 - 26;
@@ -341,7 +354,7 @@ AVHWAccel ff_h264_vaapi_hwaccel = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H264,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
-    .start_frame    = start_frame,
-    .end_frame      = end_frame,
-    .decode_slice   = decode_slice,
+    .start_frame    = vaapi_h264_start_frame,
+    .end_frame      = vaapi_h264_end_frame,
+    .decode_slice   = vaapi_h264_decode_slice,
 };
diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h
index c6d5d6e..0292654 100644
--- a/libavcodec/vaapi_internal.h
+++ b/libavcodec/vaapi_internal.h
@@ -42,7 +42,7 @@ static inline VASurfaceID ff_vaapi_get_surface_id(Picture *pic)
 }
 
 /** Common AVHWAccel.end_frame() implementation */
-int ff_vaapi_common_end_frame(MpegEncContext *s);
+void ff_vaapi_common_end_frame(AVCodecContext *avctx);
 
 /** Allocate a new picture parameter buffer */
 void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size);
@@ -63,6 +63,10 @@ uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size);
  */
 VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size);
 
+int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx);
+int ff_vaapi_commit_slices(struct vaapi_context *vactx);
+int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface);
+
 /* @} */
 
 #endif /* AVCODEC_VAAPI_INTERNAL_H */
diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c
index cfe5d3a..cf0a4b5 100644
--- a/libavcodec/vaapi_mpeg2.c
+++ b/libavcodec/vaapi_mpeg2.c
@@ -21,7 +21,6 @@
  */
 
 #include "vaapi_internal.h"
-#include "dsputil.h"
 
 /** Reconstruct bitstream f_code */
 static inline int mpeg2_get_f_code(MpegEncContext *s)
@@ -99,11 +98,6 @@ static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_
     return 0;
 }
 
-static int vaapi_mpeg2_end_frame(AVCodecContext *avctx)
-{
-    return ff_vaapi_common_end_frame(avctx->priv_data);
-}
-
 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext * const s = avctx->priv_data;
@@ -144,6 +138,6 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = {
     .id             = AV_CODEC_ID_MPEG2VIDEO,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_mpeg2_start_frame,
-    .end_frame      = vaapi_mpeg2_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_mpeg2_decode_slice,
 };
diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c
index 7d9ffd7..b771482 100644
--- a/libavcodec/vaapi_mpeg4.c
+++ b/libavcodec/vaapi_mpeg4.c
@@ -22,9 +22,10 @@
 
 #include "vaapi_internal.h"
 #include "h263.h"
+#include "mpeg4video.h"
 
 /** Reconstruct bitstream intra_dc_vlc_thr */
-static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext *s)
+static int mpeg4_get_intra_dc_vlc_thr(Mpeg4DecContext *s)
 {
     switch (s->intra_dc_threshold) {
     case 99: return 0;
@@ -41,7 +42,8 @@ static int mpeg4_get_intra_dc_vlc_thr(MpegEncContext *s)
 
 static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
 {
-    MpegEncContext * const s = avctx->priv_data;
+    Mpeg4DecContext *ctx = avctx->priv_data;
+    MpegEncContext * const s = &ctx->m;
     struct vaapi_context * const vactx = avctx->hwaccel_context;
     VAPictureParameterBufferMPEG4 *pic_param;
     VAIQMatrixBufferMPEG4 *iq_matrix;
@@ -64,24 +66,24 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_
     pic_param->vol_fields.bits.chroma_format            = CHROMA_420;
     pic_param->vol_fields.bits.interlaced               = !s->progressive_sequence;
     pic_param->vol_fields.bits.obmc_disable             = 1;
-    pic_param->vol_fields.bits.sprite_enable            = s->vol_sprite_usage;
+    pic_param->vol_fields.bits.sprite_enable            = ctx->vol_sprite_usage;
     pic_param->vol_fields.bits.sprite_warping_accuracy  = s->sprite_warping_accuracy;
     pic_param->vol_fields.bits.quant_type               = s->mpeg_quant;
     pic_param->vol_fields.bits.quarter_sample           = s->quarter_sample;
     pic_param->vol_fields.bits.data_partitioned         = s->data_partitioning;
-    pic_param->vol_fields.bits.reversible_vlc           = s->rvlc;
-    pic_param->vol_fields.bits.resync_marker_disable    = !s->resync_marker;
-    pic_param->no_of_sprite_warping_points              = s->num_sprite_warping_points;
-    for (i = 0; i < s->num_sprite_warping_points && i < 3; i++) {
-        pic_param->sprite_trajectory_du[i]              = s->sprite_traj[i][0];
-        pic_param->sprite_trajectory_dv[i]              = s->sprite_traj[i][1];
+    pic_param->vol_fields.bits.reversible_vlc           = ctx->rvlc;
+    pic_param->vol_fields.bits.resync_marker_disable    = !ctx->resync_marker;
+    pic_param->no_of_sprite_warping_points              = ctx->num_sprite_warping_points;
+    for (i = 0; i < ctx->num_sprite_warping_points && i < 3; i++) {
+        pic_param->sprite_trajectory_du[i]              = ctx->sprite_traj[i][0];
+        pic_param->sprite_trajectory_dv[i]              = ctx->sprite_traj[i][1];
     }
     pic_param->quant_precision                          = s->quant_precision;
     pic_param->vop_fields.value                         = 0; /* reset all bits */
     pic_param->vop_fields.bits.vop_coding_type          = s->pict_type - AV_PICTURE_TYPE_I;
     pic_param->vop_fields.bits.backward_reference_vop_coding_type = s->pict_type == AV_PICTURE_TYPE_B ? s->next_picture.f.pict_type - AV_PICTURE_TYPE_I : 0;
     pic_param->vop_fields.bits.vop_rounding_type        = s->no_rounding;
-    pic_param->vop_fields.bits.intra_dc_vlc_thr         = mpeg4_get_intra_dc_vlc_thr(s);
+    pic_param->vop_fields.bits.intra_dc_vlc_thr         = mpeg4_get_intra_dc_vlc_thr(ctx);
     pic_param->vop_fields.bits.top_field_first          = s->top_field_first;
     pic_param->vop_fields.bits.alternate_vertical_scan_flag = s->alternate_scan;
     pic_param->vop_fcode_forward                        = s->f_code;
@@ -115,11 +117,6 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_
     return 0;
 }
 
-static int vaapi_mpeg4_end_frame(AVCodecContext *avctx)
-{
-    return ff_vaapi_common_end_frame(avctx->priv_data);
-}
-
 static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext * const s = avctx->priv_data;
@@ -156,7 +153,7 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = {
     .id             = AV_CODEC_ID_MPEG4,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_mpeg4_start_frame,
-    .end_frame      = vaapi_mpeg4_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_mpeg4_decode_slice,
 };
 #endif
@@ -168,7 +165,7 @@ AVHWAccel ff_h263_vaapi_hwaccel = {
     .id             = AV_CODEC_ID_H263,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_mpeg4_start_frame,
-    .end_frame      = vaapi_mpeg4_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_mpeg4_decode_slice,
 };
 #endif
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index 4a98ba7..50cba16 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -169,7 +169,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t
     pic_param->sequence_fields.bits.psf                             = v->psf;
     pic_param->sequence_fields.bits.multires                        = v->multires;
     pic_param->sequence_fields.bits.overlap                         = v->overlap;
-    pic_param->sequence_fields.bits.syncmarker                      = s->resync_marker;
+    pic_param->sequence_fields.bits.syncmarker                      = v->resync_marker;
     pic_param->sequence_fields.bits.rangered                        = v->rangered;
     pic_param->sequence_fields.bits.max_b_frames                    = s->avctx->max_b_frames;
 #if VA_CHECK_VERSION(0,32,0)
@@ -310,13 +310,6 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t
     return 0;
 }
 
-static int vaapi_vc1_end_frame(AVCodecContext *avctx)
-{
-    VC1Context * const v = avctx->priv_data;
-
-    return ff_vaapi_common_end_frame(&v->s);
-}
-
 static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     VC1Context * const v = avctx->priv_data;
@@ -347,7 +340,7 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = {
     .id             = AV_CODEC_ID_WMV3,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_vc1_start_frame,
-    .end_frame      = vaapi_vc1_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_vc1_decode_slice,
 };
 #endif
@@ -358,6 +351,6 @@ AVHWAccel ff_vc1_vaapi_hwaccel = {
     .id             = AV_CODEC_ID_VC1,
     .pix_fmt        = AV_PIX_FMT_VAAPI_VLD,
     .start_frame    = vaapi_vc1_start_frame,
-    .end_frame      = vaapi_vc1_end_frame,
+    .end_frame      = ff_vaapi_mpeg_end_frame,
     .decode_slice   = vaapi_vc1_decode_slice,
 };
diff --git a/libavcodec/vb.c b/libavcodec/vb.c
index 1e241e7..56094d8 100644
--- a/libavcodec/vb.c
+++ b/libavcodec/vb.c
@@ -31,7 +31,7 @@
 #include "bytestream.h"
 #include "internal.h"
 
-enum VBFlags{
+enum VBFlags {
     VB_HAS_GMC     = 0x01,
     VB_HAS_AUDIO   = 0x04,
     VB_HAS_VIDEO   = 0x08,
@@ -41,7 +41,6 @@ enum VBFlags{
 
 typedef struct VBDecContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     uint8_t *frame, *prev_frame;
     uint32_t pal[AVPALETTE_COUNT];
@@ -64,16 +63,16 @@ static void vb_decode_palette(VBDecContext *c, int data_size)
     int start, size, i;
 
     start = bytestream2_get_byte(&c->stream);
-    size = (bytestream2_get_byte(&c->stream) - 1) & 0xFF;
-    if(start + size > 255){
+    size  = (bytestream2_get_byte(&c->stream) - 1) & 0xFF;
+    if (start + size > 255) {
         av_log(c->avctx, AV_LOG_ERROR, "Palette change runs beyond entry 256\n");
         return;
     }
-    if(size*3+2 > data_size){
+    if (size*3+2 > data_size) {
         av_log(c->avctx, AV_LOG_ERROR, "Palette data runs beyond chunk size\n");
         return;
     }
-    for(i = start; i <= start + size; i++)
+    for (i = start; i <= start + size; i++)
         c->pal[i] = bytestream2_get_be24(&c->stream);
 }
 
@@ -97,42 +96,42 @@ static int vb_decode_framedata(VBDecContext *c, int offset)
     int pattype, pattern;
     const int width = c->avctx->width;
     uint8_t *pstart = c->prev_frame;
-    uint8_t *pend = c->prev_frame + width*c->avctx->height;
+    uint8_t *pend   = c->prev_frame + width*c->avctx->height;
 
     g = c->stream;
 
     prev = c->prev_frame + offset;
-    cur = c->frame;
+    cur  = c->frame;
 
     blocks = (c->avctx->width >> 2) * (c->avctx->height >> 2);
-    blk2 = 0;
-    for(blk = 0; blk < blocks; blk++){
-        if(!(blk & 3)) {
+    blk2   = 0;
+    for (blk = 0; blk < blocks; blk++) {
+        if (!(blk & 3)) {
             blocktypes = bytestream2_get_byte(&g);
         }
-        switch(blocktypes & 0xC0){
+        switch (blocktypes & 0xC0) {
         case 0x00: //skip
-            for(y = 0; y < 4; y++)
-                if(check_line(prev + y*width, pstart, pend))
+            for (y = 0; y < 4; y++)
+                if (check_line(prev + y*width, pstart, pend))
                     memcpy(cur + y*width, prev + y*width, 4);
                 else
                     memset(cur + y*width, 0, 4);
             break;
         case 0x40:
             t = bytestream2_get_byte(&g);
-            if(!t){ //raw block
+            if (!t) { //raw block
                 if (bytestream2_get_bytes_left(&g) < 16) {
                     av_log(c->avctx, AV_LOG_ERROR, "Insufficient data\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
-                for(y = 0; y < 4; y++)
+                for (y = 0; y < 4; y++)
                     bytestream2_get_buffer(&g, cur + y * width, 4);
-            }else{ // motion compensation
+            } else { // motion compensation
                 x = ((t & 0xF)^8) - 8;
                 y = ((t >> 4) ^8) - 8;
                 t = x + y*width;
-                for(y = 0; y < 4; y++)
-                    if(check_line(prev + t + y*width, pstart, pend))
+                for (y = 0; y < 4; y++)
+                    if (check_line(prev + t + y*width, pstart, pend))
                         memcpy(cur + y*width, prev + t + y*width, 4);
                     else
                         memset(cur + y*width, 0, 4);
@@ -140,35 +139,35 @@ static int vb_decode_framedata(VBDecContext *c, int offset)
             break;
         case 0x80: // fill
             t = bytestream2_get_byte(&g);
-            for(y = 0; y < 4; y++)
+            for (y = 0; y < 4; y++)
                 memset(cur + y*width, t, 4);
             break;
         case 0xC0: // pattern fill
-            t = bytestream2_get_byte(&g);
+            t       = bytestream2_get_byte(&g);
             pattype = t >> 6;
             pattern = vb_patterns[t & 0x3F];
-            switch(pattype){
+            switch (pattype) {
             case 0:
                 a = bytestream2_get_byte(&g);
                 b = bytestream2_get_byte(&g);
-                for(y = 0; y < 4; y++)
-                    for(x = 0; x < 4; x++, pattern >>= 1)
+                for (y = 0; y < 4; y++)
+                    for (x = 0; x < 4; x++, pattern >>= 1)
                         cur[x + y*width] = (pattern & 1) ? b : a;
                 break;
             case 1:
                 pattern = ~pattern;
             case 2:
                 a = bytestream2_get_byte(&g);
-                for(y = 0; y < 4; y++)
-                    for(x = 0; x < 4; x++, pattern >>= 1)
-                        if(pattern & 1 && check_pixel(prev + x + y*width, pstart, pend))
+                for (y = 0; y < 4; y++)
+                    for (x = 0; x < 4; x++, pattern >>= 1)
+                        if (pattern & 1 && check_pixel(prev + x + y*width, pstart, pend))
                             cur[x + y*width] = prev[x + y*width];
                         else
                             cur[x + y*width] = a;
                 break;
             case 3:
-                av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n",blk);
-                return -1;
+                av_log(c->avctx, AV_LOG_ERROR, "Invalid opcode seen @%d\n", blk);
+                return AVERROR_INVALIDDATA;
             }
             break;
         }
@@ -176,8 +175,8 @@ static int vb_decode_framedata(VBDecContext *c, int offset)
         cur  += 4;
         prev += 4;
         blk2++;
-        if(blk2 == (width >> 2)){
-            blk2 = 0;
+        if (blk2 == (width >> 2)) {
+            blk2  = 0;
             cur  += width * 3;
             prev += width * 3;
         }
@@ -189,55 +188,52 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     VBDecContext * const c = avctx->priv_data;
+    AVFrame *frame         = data;
     uint8_t *outptr, *srcptr;
-    int i, j;
+    int i, j, ret;
     int flags;
     uint32_t size;
     int offset = 0;
 
     bytestream2_init(&c->stream, avpkt->data, avpkt->size);
 
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    c->pic.reference = 1;
-    if(ff_get_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     flags = bytestream2_get_le16(&c->stream);
 
-    if(flags & VB_HAS_GMC){
+    if (flags & VB_HAS_GMC) {
         i = (int16_t)bytestream2_get_le16(&c->stream);
         j = (int16_t)bytestream2_get_le16(&c->stream);
         offset = i + j * avctx->width;
     }
-    if(flags & VB_HAS_VIDEO){
+    if (flags & VB_HAS_VIDEO) {
         size = bytestream2_get_le32(&c->stream);
         vb_decode_framedata(c, offset);
         bytestream2_skip(&c->stream, size - 4);
     }
-    if(flags & VB_HAS_PALETTE){
+    if (flags & VB_HAS_PALETTE) {
         size = bytestream2_get_le32(&c->stream);
         vb_decode_palette(c, size);
     }
 
-    memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
-    c->pic.palette_has_changed = flags & VB_HAS_PALETTE;
+    memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
+    frame->palette_has_changed = flags & VB_HAS_PALETTE;
 
-    outptr = c->pic.data[0];
+    outptr = frame->data[0];
     srcptr = c->frame;
 
-    for(i = 0; i < avctx->height; i++){
+    for (i = 0; i < avctx->height; i++) {
         memcpy(outptr, srcptr, avctx->width);
         srcptr += avctx->width;
-        outptr += c->pic.linesize[0];
+        outptr += frame->linesize[0];
     }
 
     FFSWAP(uint8_t*, c->frame, c->prev_frame);
 
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return avpkt->size;
@@ -247,7 +243,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
 {
     VBDecContext * const c = avctx->priv_data;
 
-    c->avctx = avctx;
+    c->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     c->frame      = av_mallocz(avctx->width * avctx->height);
@@ -262,20 +258,18 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
     av_freep(&c->frame);
     av_freep(&c->prev_frame);
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
 
     return 0;
 }
 
 AVCodec ff_vb_decoder = {
     .name           = "vb",
+    .long_name      = NULL_IF_CONFIG_SMALL("Beam Software VB"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VB,
     .priv_data_size = sizeof(VBDecContext),
     .init           = decode_init,
     .close          = decode_end,
     .decode         = decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("Beam Software VB"),
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/vble.c b/libavcodec/vble.c
index 228b1bd..a349d8f 100644
--- a/libavcodec/vble.c
+++ b/libavcodec/vble.c
@@ -84,10 +84,10 @@ static int vble_unpack(VBLEContext *ctx, GetBitContext *gb)
     return 0;
 }
 
-static void vble_restore_plane(VBLEContext *ctx, int plane, int offset,
-                              int width, int height)
+static void vble_restore_plane(VBLEContext *ctx, AVFrame *pic,
+                               int plane, int offset,
+                               int width, int height)
 {
-    AVFrame *pic = ctx->avctx->coded_frame;
     uint8_t *dst = pic->data[plane];
     uint8_t *val = ctx->val + offset;
     int stride = pic->linesize[plane];
@@ -116,21 +116,15 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     VBLEContext *ctx = avctx->priv_data;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic     = data;
     GetBitContext gb;
     const uint8_t *src = avpkt->data;
     int version;
     int offset = 0;
     int width_uv = avctx->width / 2, height_uv = avctx->height / 2;
 
-    pic->reference = 0;
-
-    /* Clear buffer if need be */
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     /* Allocate buffer */
-    if (ff_get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -154,19 +148,18 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     /* Restore planes. Should be almost identical to Huffyuv's. */
-    vble_restore_plane(ctx, 0, offset, avctx->width, avctx->height);
+    vble_restore_plane(ctx, pic, 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, pic, 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, pic, 2, offset, width_uv, height_uv);
     }
 
     *got_frame       = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
@@ -174,12 +167,6 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 static av_cold int vble_decode_close(AVCodecContext *avctx)
 {
     VBLEContext *ctx = avctx->priv_data;
-    AVFrame *pic = avctx->coded_frame;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    av_freep(&avctx->coded_frame);
     av_freep(&ctx->val);
 
     return 0;
@@ -195,12 +182,6 @@ static av_cold int vble_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     avctx->bits_per_raw_sample = 8;
-    avctx->coded_frame = avcodec_alloc_frame();
-
-    if (!avctx->coded_frame) {
-        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
-        return AVERROR(ENOMEM);
-    }
 
     ctx->size = avpicture_get_size(avctx->pix_fmt,
                                    avctx->width, avctx->height);
@@ -218,6 +199,7 @@ static av_cold int vble_decode_init(AVCodecContext *avctx)
 
 AVCodec ff_vble_decoder = {
     .name           = "vble",
+    .long_name      = NULL_IF_CONFIG_SMALL("VBLE Lossless Codec"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VBLE,
     .priv_data_size = sizeof(VBLEContext),
@@ -225,5 +207,4 @@ AVCodec ff_vble_decoder = {
     .close          = vble_decode_close,
     .decode         = vble_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("VBLE Lossless Codec"),
 };
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index a8dd38a..6d89e71 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -27,8 +27,8 @@
  *
  */
 
+#include "libavutil/attributes.h"
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "vc1.h"
@@ -367,7 +367,7 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo
 
     v->overlap         = get_bits1(gb); //common
 
-    v->s.resync_marker = get_bits1(gb);
+    v->resync_marker   = get_bits1(gb);
     v->rangered        = get_bits1(gb);
     if (v->rangered && v->profile == PROFILE_SIMPLE) {
         av_log(avctx, AV_LOG_INFO,
@@ -408,7 +408,7 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitCo
            "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
            v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
            v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
-           v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
+           v->rangered, v->vstransform, v->overlap, v->resync_marker,
            v->dquant, v->quantizer_mode, avctx->max_b_frames);
     return 0;
 }
@@ -570,6 +570,52 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex
     return 0;
 }
 
+/* fill lookup tables for intensity compensation */
+#define INIT_LUT(lumscale, lumshift, luty, lutuv, chain) do {                 \
+        int scale, shift, i;                                                  \
+        if (!lumscale) {                                                      \
+            scale = -64;                                                      \
+            shift = (255 - lumshift * 2) << 6;                                \
+            if (lumshift > 31)                                                \
+                shift += 128 << 6;                                            \
+        } else {                                                              \
+            scale = lumscale + 32;                                            \
+            if (lumshift > 31)                                                \
+                shift = (lumshift - 64) << 6;                                 \
+            else                                                              \
+                shift = lumshift << 6;                                        \
+        }                                                                     \
+        for (i = 0; i < 256; i++) {                                           \
+            int iy = chain ? luty[i]  : i;                                    \
+            int iu = chain ? lutuv[i] : i;                                    \
+            luty[i]  = av_clip_uint8((scale * iy + shift + 32) >> 6);         \
+            lutuv[i] = av_clip_uint8((scale * (iu - 128) + 128*64 + 32) >> 6);\
+        }                                                                     \
+    } while(0)
+
+static void rotate_luts(VC1Context *v)
+{
+#define ROTATE(DEF, L, N, C, A) do {                          \
+        if (v->s.pict_type == AV_PICTURE_TYPE_BI || v->s.pict_type == AV_PICTURE_TYPE_B) { \
+            C = A;                                            \
+        } else {                                              \
+            DEF;                                              \
+            memcpy(&tmp, &L  , sizeof(tmp));                  \
+            memcpy(&L  , &N  , sizeof(tmp));                  \
+            memcpy(&N  , &tmp, sizeof(tmp));                  \
+            C = N;                                            \
+        }                                                     \
+    } while(0)
+
+    ROTATE(int tmp,             v->last_use_ic, v->next_use_ic, v->curr_use_ic, v->aux_use_ic);
+    ROTATE(uint8_t tmp[2][256], v->last_luty,   v->next_luty,   v->curr_luty,   v->aux_luty);
+    ROTATE(uint8_t tmp[2][256], v->last_lutuv,  v->next_lutuv,  v->curr_lutuv,  v->aux_lutuv);
+
+    INIT_LUT(32, 0, v->curr_luty[0], v->curr_lutuv[0], 0);
+    INIT_LUT(32, 0, v->curr_luty[1], v->curr_lutuv[1], 0);
+    v->curr_use_ic = 0;
+}
+
 int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
 {
     int pqindex, lowquant, status;
@@ -656,8 +702,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
             (v->s.pict_type == AV_PICTURE_TYPE_P) ? 'P' : ((v->s.pict_type == AV_PICTURE_TYPE_I) ? 'I' : 'B'),
             pqindex, v->pq, v->halfpq, v->rangeredfrm);
 
-    if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P)
-        v->use_ic = 0;
+    if (v->first_pic_header_flag)
+        rotate_luts(v);
 
     switch (v->s.pict_type) {
     case AV_PICTURE_TYPE_P:
@@ -668,28 +714,13 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
         lowquant = (v->pq > 12) ? 0 : 1;
         v->mv_mode = ff_vc1_mv_pmode_table[lowquant][get_unary(gb, 1, 4)];
         if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
-            int scale, shift, i;
             v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][get_unary(gb, 1, 3)];
             v->lumscale = get_bits(gb, 6);
             v->lumshift = get_bits(gb, 6);
-            v->use_ic   = 1;
+            v->last_use_ic = 1;
             /* fill lookup tables for intensity compensation */
-            if (!v->lumscale) {
-                scale = -64;
-                shift = (255 - v->lumshift * 2) << 6;
-                if (v->lumshift > 31)
-                    shift += 128 << 6;
-            } else {
-                scale = v->lumscale + 32;
-                if (v->lumshift > 31)
-                    shift = (v->lumshift - 64) << 6;
-                else
-                    shift = v->lumshift << 6;
-            }
-            for (i = 0; i < 256; i++) {
-                v->luty[i]  = av_clip_uint8((scale * i + shift + 32) >> 6);
-                v->lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);
-            }
+            INIT_LUT(v->lumscale, v->lumshift, v->last_luty[0], v->last_lutuv[0], 1);
+            INIT_LUT(v->lumscale, v->lumshift, v->last_luty[1], v->last_lutuv[1], 1);
         }
         v->qs_last = v->s.quarter_sample;
         if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
@@ -800,31 +831,12 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
     return 0;
 }
 
-/* fill lookup tables for intensity compensation */
-#define INIT_LUT(lumscale, lumshift, luty, lutuv)   \
-    if (!lumscale) {                                \
-        scale = -64;                                \
-        shift = (255 - lumshift * 2) << 6;          \
-        if (lumshift > 31)                          \
-            shift += 128 << 6;                      \
-    } else {                                        \
-        scale = lumscale + 32;                      \
-        if (lumshift > 31)                          \
-            shift = (lumshift - 64) << 6;           \
-        else                                        \
-            shift = lumshift << 6;                  \
-    }                                               \
-    for (i = 0; i < 256; i++) {                     \
-        luty[i]  = av_clip_uint8((scale * i + shift + 32) >> 6);           \
-        lutuv[i] = av_clip_uint8((scale * (i - 128) + 128*64 + 32) >> 6);  \
-    }
-
 int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
 {
     int pqindex, lowquant;
     int status;
     int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */
-    int scale, shift, i; /* for initializing LUT for intensity compensation */
+    int field_mode, fcm;
 
     v->p_frame_skipped = 0;
     if (v->second_field) {
@@ -836,26 +848,29 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
             goto parse_common_info;
     }
 
-    v->field_mode = 0;
+    field_mode = 0;
     if (v->interlace) {
-        v->fcm = decode012(gb);
-        if (v->fcm) {
-            if (v->fcm == ILACE_FIELD)
-                v->field_mode = 1;
-            if (!v->warn_interlaced++)
-                av_log(v->s.avctx, AV_LOG_ERROR,
-                       "Interlaced frames/fields support is incomplete\n");
+        fcm = decode012(gb);
+        if (fcm) {
+            if (fcm == ILACE_FIELD)
+                field_mode = 1;
         }
     } else {
-        v->fcm = PROGRESSIVE;
+        fcm = PROGRESSIVE;
     }
+    if (!v->first_pic_header_flag && v->field_mode != field_mode)
+        return AVERROR_INVALIDDATA;
+    v->field_mode = field_mode;
+    v->fcm = fcm;
 
     if (v->field_mode) {
+        v->s.mb_height = FFALIGN(v->s.height + 15 >> 4, 2);
         v->fptype = get_bits(gb, 3);
         v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
         if (v->fptype & 4) // B-picture
             v->s.pict_type = (v->fptype & 2) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
     } else {
+        v->s.mb_height = v->s.height + 15 >> 4;
         switch (get_unary(gb, 0, 4)) {
         case 0:
             v->s.pict_type = AV_PICTURE_TYPE_P;
@@ -886,7 +901,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
         }
     }
     if (v->panscanflag) {
-        av_log_missing_feature(v->s.avctx, "Pan-scan", 0);
+        avpriv_report_missing_feature(v->s.avctx, "Pan-scan");
         //...
     }
     if (v->p_frame_skipped) {
@@ -952,12 +967,12 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
     if (v->postprocflag)
         v->postproc = get_bits(gb, 2);
 
-    if (v->s.pict_type == AV_PICTURE_TYPE_I || v->s.pict_type == AV_PICTURE_TYPE_P)
-        v->use_ic = 0;
-
     if (v->parse_only)
         return 0;
 
+    if (v->first_pic_header_flag)
+        rotate_luts(v);
+
     switch (v->s.pict_type) {
     case AV_PICTURE_TYPE_I:
     case AV_PICTURE_TYPE_BI:
@@ -992,6 +1007,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
                 v->reffield          = get_bits1(gb);
                 v->ref_field_type[0] = v->reffield ^ !v->cur_field_type;
             }
+        } else {
+            v->numref = 0;
         }
         if (v->extended_mv)
             v->mvrange = get_unary(gb, 0, 3);
@@ -1008,7 +1025,9 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
                 if (v->intcomp) {
                     v->lumscale = get_bits(gb, 6);
                     v->lumshift = get_bits(gb, 6);
-                    INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);
+                    INIT_LUT(v->lumscale, v->lumshift, v->last_luty[0], v->last_lutuv[0], 1);
+                    INIT_LUT(v->lumscale, v->lumshift, v->last_luty[1], v->last_lutuv[1], 1);
+                    v->last_use_ic = 1;
                 }
                 status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
                 av_log(v->s.avctx, AV_LOG_DEBUG, "SKIPMB plane encoding: "
@@ -1051,17 +1070,38 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
                 int mvmode2;
                 mvmode2 = get_unary(gb, 1, 3);
                 v->mv_mode2 = ff_vc1_mv_pmode_table2[lowquant][mvmode2];
-                if (v->field_mode)
-                    v->intcompfield = decode210(gb);
-                v->lumscale = get_bits(gb, 6);
-                v->lumshift = get_bits(gb, 6);
-                INIT_LUT(v->lumscale, v->lumshift, v->luty, v->lutuv);
-                if ((v->field_mode) && !v->intcompfield) {
+                if (v->field_mode) {
+                    v->intcompfield = decode210(gb) ^ 3;
+                } else
+                    v->intcompfield = 3;
+
+                v->lumscale2 = v->lumscale = 32;
+                v->lumshift2 = v->lumshift =  0;
+                if (v->intcompfield & 1) {
+                    v->lumscale = get_bits(gb, 6);
+                    v->lumshift = get_bits(gb, 6);
+                }
+                if ((v->intcompfield & 2) && v->field_mode) {
                     v->lumscale2 = get_bits(gb, 6);
                     v->lumshift2 = get_bits(gb, 6);
-                    INIT_LUT(v->lumscale2, v->lumshift2, v->luty2, v->lutuv2);
+                } else if(!v->field_mode) {
+                    v->lumscale2 = v->lumscale;
+                    v->lumshift2 = v->lumshift;
+                }
+                if (v->field_mode && v->second_field) {
+                    if (v->cur_field_type) {
+                        INIT_LUT(v->lumscale , v->lumshift , v->curr_luty[v->cur_field_type^1], v->curr_lutuv[v->cur_field_type^1], 0);
+                        INIT_LUT(v->lumscale2, v->lumshift2, v->last_luty[v->cur_field_type  ], v->last_lutuv[v->cur_field_type  ], 1);
+                    } else {
+                        INIT_LUT(v->lumscale2, v->lumshift2, v->curr_luty[v->cur_field_type^1], v->curr_lutuv[v->cur_field_type^1], 0);
+                        INIT_LUT(v->lumscale , v->lumshift , v->last_luty[v->cur_field_type  ], v->last_lutuv[v->cur_field_type  ], 1);
+                    }
+                    v->next_use_ic = v->curr_use_ic = 1;
+                } else {
+                    INIT_LUT(v->lumscale , v->lumshift , v->last_luty[0], v->last_lutuv[0], 1);
+                    INIT_LUT(v->lumscale2, v->lumshift2, v->last_luty[1], v->last_lutuv[1], 1);
                 }
-                v->use_ic = 1;
+                v->last_use_ic = 1;
             }
             v->qs_last = v->s.quarter_sample;
             if (v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
@@ -1138,9 +1178,14 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
         }
         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
@@ -1186,6 +1231,38 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
                 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);
+            if (get_bits1(gb)) /* intcomp - present but shall always be 0 */
+                av_log(v->s.avctx, AV_LOG_WARNING, "Intensity compensation set for B picture\n");
+            v->intcomp          = 0;
+            v->mv_mode          = MV_PMODE_1MV;
+            v->fourmvswitch     = 0;
+            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;
@@ -1485,7 +1562,7 @@ static const uint16_t vlc_offs[] = {
  * @param v The VC1Context to initialize
  * @return Status
  */
-int ff_vc1_init_common(VC1Context *v)
+av_cold int ff_vc1_init_common(VC1Context *v)
 {
     static int done = 0;
     int i = 0;
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index 13011ae..9db8edd 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -24,6 +24,7 @@
 #define AVCODEC_VC1_H
 
 #include "avcodec.h"
+#include "h264chroma.h"
 #include "mpegvideo.h"
 #include "intrax8.h"
 #include "vc1dsp.h"
@@ -181,6 +182,7 @@ enum FrameCodingMode {
 typedef struct VC1Context{
     MpegEncContext s;
     IntraX8Context x8;
+    H264ChromaContext h264chroma;
     VC1DSPContext vc1dsp;
 
     int bits;
@@ -296,8 +298,11 @@ typedef struct VC1Context{
     int dmb_is_raw;                 ///< direct mb plane is raw
     int fmb_is_raw;                 ///< forward mb plane is raw
     int skip_is_raw;                ///< skip mb plane is not coded
-    uint8_t luty[256], lutuv[256];  ///< lookup tables used for intensity compensation
-    int use_ic;                     ///< use intensity compensation in B-frames
+    uint8_t last_luty[2][256], last_lutuv[2][256];  ///< lookup tables used for intensity compensation
+    uint8_t  aux_luty[2][256],  aux_lutuv[2][256];  ///< lookup tables used for intensity compensation
+    uint8_t next_luty[2][256], next_lutuv[2][256];  ///< lookup tables used for intensity compensation
+    uint8_t (*curr_luty)[256]  ,(*curr_lutuv)[256];
+    int last_use_ic, curr_use_ic, next_use_ic, aux_use_ic;
     int rnd;                        ///< rounding control
 
     /** Frame decoding info for S/M profiles only */
@@ -340,7 +345,6 @@ typedef struct VC1Context{
     int intcomp;
     uint8_t lumscale2;  ///< for interlaced field P picture
     uint8_t lumshift2;
-    uint8_t luty2[256], lutuv2[256]; // lookup tables used for intensity compensation
     VLC* mbmode_vlc;
     VLC* imv_vlc;
     VLC* twomvbp_vlc;
@@ -352,7 +356,6 @@ typedef struct VC1Context{
     int8_t zzi_8x8[64];
     uint8_t *blk_mv_type_base, *blk_mv_type;    ///< 0: frame MV, 1: field MV (interlaced frame)
     uint8_t *mv_f_base, *mv_f[2];               ///< 0: MV obtained from same field, 1: opposite field
-    uint8_t *mv_f_last_base, *mv_f_last[2];
     uint8_t *mv_f_next_base, *mv_f_next[2];
     int field_mode;         ///< 1 for interlaced field pictures
     int fptype;
@@ -370,13 +373,14 @@ typedef struct VC1Context{
     int qs_last;            ///< if qpel has been used in the previous (tr.) picture
     int bmvtype;
     int frfd, brfd;         ///< reference frame distance (forward or backward)
+    int first_pic_header_flag;
     int pic_header_flag;
 
     /** Frame decoding info for sprite modes */
     //@{
     int new_sprite;
     int two_sprites;
-    AVFrame sprite_output_frame;
+    AVFrame *sprite_output_frame;
     int output_width, output_height, sprite_width, sprite_height;
     uint8_t* sr_rows[2][2];      ///< Sprite resizer line cache
     //@}
@@ -385,7 +389,7 @@ typedef struct VC1Context{
     int bi_type;
     int x8_type;
 
-    DCTELEM (*block)[6][64];
+    int16_t (*block)[6][64];
     int n_allocated_blks, cur_blk_idx, left_blk_idx, topleft_blk_idx, top_blk_idx;
     uint32_t *cbp_base, *cbp;
     uint8_t *is_intra_base, *is_intra;
@@ -397,8 +401,7 @@ typedef struct VC1Context{
     int end_mb_x;                ///< Horizontal macroblock limit (used only by mss2)
 
     int parse_only;              ///< Context is used within parser
-
-    int warn_interlaced;
+    int resync_marker;           ///< could this stream contain resync markers
 } VC1Context;
 
 /** Find VC-1 marker in buffer
@@ -453,9 +456,9 @@ int ff_vc1_parse_frame_header    (VC1Context *v, GetBitContext *gb);
 int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb);
 int ff_vc1_init_common(VC1Context *v);
 
-av_cold int  ff_vc1_decode_init_alloc_tables(VC1Context *v);
-av_cold void ff_vc1_init_transposed_scantables(VC1Context *v);
-av_cold int  ff_vc1_decode_end(AVCodecContext *avctx);
+int  ff_vc1_decode_init_alloc_tables(VC1Context *v);
+void ff_vc1_init_transposed_scantables(VC1Context *v);
+int  ff_vc1_decode_end(AVCodecContext *avctx);
 void ff_vc1_decode_blocks(VC1Context *v);
 
 #endif /* AVCODEC_VC1_H */
diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index 5aa1248..1bedd98 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -25,6 +25,7 @@
  * VC-1 and WMV3 parser
  */
 
+#include "libavutil/attributes.h"
 #include "parser.h"
 #include "vc1.h"
 #include "get_bits.h"
@@ -88,6 +89,11 @@ static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx,
                 }
             }
 
+            if (vpc->v.broadcast && vpc->v.interlace && !vpc->v.psf)
+                s->field_order = vpc->v.tff ? AV_FIELD_TT : AV_FIELD_BB;
+            else
+                s->field_order = AV_FIELD_PROGRESSIVE;
+
             break;
         }
     }
@@ -184,7 +190,7 @@ static int vc1_split(AVCodecContext *avctx,
     return 0;
 }
 
-static int vc1_parse_init(AVCodecParserContext *s)
+static av_cold int vc1_parse_init(AVCodecParserContext *s)
 {
     VC1ParseContext *vpc = s->priv_data;
     vpc->v.s.slice_context_count = 1;
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 6b32116..37da794 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -27,17 +27,17 @@
  */
 
 #include "internal.h"
-#include "dsputil.h"
 #include "avcodec.h"
+#include "error_resilience.h"
 #include "mpegvideo.h"
 #include "h263.h"
+#include "h264chroma.h"
 #include "vc1.h"
 #include "vc1data.h"
 #include "vc1acdata.h"
 #include "msmpeg4data.h"
 #include "unary.h"
 #include "mathops.h"
-#include "vdpau_internal.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -72,6 +72,16 @@ enum Imode {
 };
 /** @} */ //imode defines
 
+static void init_block_index(VC1Context *v)
+{
+    MpegEncContext *s = &v->s;
+    ff_init_block_index(s);
+    if (v->field_mode && !(v->second_field ^ v->tff)) {
+        s->dest[0] += s->current_picture_ptr->f.linesize[0];
+        s->dest[1] += s->current_picture_ptr->f.linesize[1];
+        s->dest[2] += s->current_picture_ptr->f.linesize[2];
+    }
+}
 
 /** @} */ //Bitplane group
 
@@ -79,7 +89,7 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     int topleft_mb_pos, top_mb_pos;
-    int stride_y, fieldtx;
+    int stride_y, fieldtx = 0;
     int v_dist;
 
     /* The put pixels loop is always one MB row behind the decoding loop,
@@ -92,7 +102,8 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v)
     if (!s->first_slice_line) {
         if (s->mb_x) {
             topleft_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x - 1;
-            fieldtx        = v->fieldtx_plane[topleft_mb_pos];
+            if (v->fcm == ILACE_FRAME)
+                fieldtx = v->fieldtx_plane[topleft_mb_pos];
             stride_y       = s->linesize << fieldtx;
             v_dist         = (16 - fieldtx) >> (fieldtx == 0);
             s->dsp.put_signed_pixels_clamped(v->block[v->topleft_blk_idx][0],
@@ -116,7 +127,8 @@ static void vc1_put_signed_blocks_clamped(VC1Context *v)
         }
         if (s->mb_x == s->mb_width - 1) {
             top_mb_pos = (s->mb_y - 1) * s->mb_stride + s->mb_x;
-            fieldtx    = v->fieldtx_plane[top_mb_pos];
+            if (v->fcm == ILACE_FRAME)
+                fieldtx = v->fieldtx_plane[top_mb_pos];
             stride_y   = s->linesize << fieldtx;
             v_dist     = fieldtx ? 15 : 8;
             s->dsp.put_signed_pixels_clamped(v->block[v->top_blk_idx][0],
@@ -330,11 +342,13 @@ static void vc1_smooth_overlap_filter_iblk(VC1Context *v)
 static void vc1_mc_1mv(VC1Context *v, int dir)
 {
     MpegEncContext *s = &v->s;
-    DSPContext *dsp   = &v->s.dsp;
+    H264ChromaContext *h264chroma = &v->h264chroma;
     uint8_t *srcY, *srcU, *srcV;
     int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
-    int off, off_uv;
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
+    int i;
+    uint8_t (*luty)[256], (*lutuv)[256];
+    int use_ic;
 
     if ((!v->field_mode ||
          (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
@@ -346,8 +360,10 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
 
     // store motion vectors for further use in B frames
     if (s->pict_type == AV_PICTURE_TYPE_P) {
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = mx;
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = my;
+        for (i = 0; i < 4; i++) {
+            s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][0] = mx;
+            s->current_picture.motion_val[1][s->block_index[i] + v->blocks_off][1] = my;
+        }
     }
 
     uvmx = (mx + ((mx & 3) == 3)) >> 1;
@@ -366,32 +382,29 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
         uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));
         uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 1));
     }
-    if (v->field_mode) { // interlaced field picture
-        if (!dir) {
-            if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) {
-                srcY = s->current_picture.f.data[0];
-                srcU = s->current_picture.f.data[1];
-                srcV = s->current_picture.f.data[2];
-            } else {
-                srcY = s->last_picture.f.data[0];
-                srcU = s->last_picture.f.data[1];
-                srcV = s->last_picture.f.data[2];
-            }
+    if (!dir) {
+        if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
+            srcY = s->current_picture.f.data[0];
+            srcU = s->current_picture.f.data[1];
+            srcV = s->current_picture.f.data[2];
+            luty  = v->curr_luty;
+            lutuv = v->curr_lutuv;
+            use_ic = v->curr_use_ic;
         } else {
-            srcY = s->next_picture.f.data[0];
-            srcU = s->next_picture.f.data[1];
-            srcV = s->next_picture.f.data[2];
-        }
-    } else {
-        if (!dir) {
             srcY = s->last_picture.f.data[0];
             srcU = s->last_picture.f.data[1];
             srcV = s->last_picture.f.data[2];
-        } else {
-            srcY = s->next_picture.f.data[0];
-            srcU = s->next_picture.f.data[1];
-            srcV = s->next_picture.f.data[2];
+            luty  = v->last_luty;
+            lutuv = v->last_lutuv;
+            use_ic = v->last_use_ic;
         }
+    } else {
+        srcY = s->next_picture.f.data[0];
+        srcU = s->next_picture.f.data[1];
+        srcV = s->next_picture.f.data[2];
+        luty  = v->next_luty;
+        lutuv = v->next_lutuv;
+        use_ic = v->next_use_ic;
     }
 
     if (!srcY || !srcU) {
@@ -432,21 +445,26 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
         srcV = s->edge_emu_buffer + 18 * s->linesize;
     }
 
-    if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
+    if (v->rangeredfrm || use_ic
         || s->h_edge_pos < 22 || v_edge_pos < 22
         || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx&3) - 16 - s->mspel * 3
         || (unsigned)(src_y - 1)        > v_edge_pos    - (my&3) - 16 - 3) {
         uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
 
         srcY -= s->mspel * (1 + s->linesize);
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+                                 s->linesize, s->linesize,
                                  17 + s->mspel * 2, 17 + s->mspel * 2,
                                  src_x - s->mspel, src_y - s->mspel,
                                  s->h_edge_pos, v_edge_pos);
         srcY = s->edge_emu_buffer;
-        s->vdsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, 8 + 1, 8 + 1,
+        s->vdsp.emulated_edge_mc(uvbuf, srcU,
+                                 s->uvlinesize, s->uvlinesize,
+                                 8 + 1, 8 + 1,
                                  uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
-        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1,
+        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
+                                 s->uvlinesize, s->uvlinesize,
+                                 8 + 1, 8 + 1,
                                  uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
         srcU = uvbuf;
         srcV = uvbuf + 16;
@@ -473,22 +491,24 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
             }
         }
         /* if we deal with intensity compensation we need to scale source blocks */
-        if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+        if (use_ic) {
             int i, j;
             uint8_t *src, *src2;
 
             src = srcY;
             for (j = 0; j < 17 + s->mspel * 2; j++) {
+                int f = v->field_mode ? v->ref_field_type[dir] : ((j + src_y - s->mspel) & 1) ;
                 for (i = 0; i < 17 + s->mspel * 2; i++)
-                    src[i] = v->luty[src[i]];
+                    src[i] = luty[f][src[i]];
                 src += s->linesize;
             }
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
+                int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1);
                 for (i = 0; i < 9; i++) {
-                    src[i]  = v->lutuv[src[i]];
-                    src2[i] = v->lutuv[src2[i]];
+                    src[i]  = lutuv[f][src[i]];
+                    src2[i] = lutuv[f][src2[i]];
                 }
                 src  += s->uvlinesize;
                 src2 += s->uvlinesize;
@@ -497,26 +517,19 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
         srcY += s->mspel * (1 + s->linesize);
     }
 
-    if (v->field_mode && v->cur_field_type) {
-        off    = s->current_picture_ptr->f.linesize[0];
-        off_uv = s->current_picture_ptr->f.linesize[1];
-    } else {
-        off    = 0;
-        off_uv = 0;
-    }
     if (s->mspel) {
         dxy = ((my & 3) << 2) | (mx & 3);
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off    , srcY    , s->linesize, v->rnd);
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8, srcY + 8, s->linesize, v->rnd);
+        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0]    , srcY    , s->linesize, v->rnd);
+        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8, srcY + 8, s->linesize, v->rnd);
         srcY += s->linesize * 8;
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize    , srcY    , s->linesize, v->rnd);
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
+        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize    , srcY    , s->linesize, v->rnd);
+        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + 8 * s->linesize + 8, srcY + 8, s->linesize, v->rnd);
     } else { // hpel mc - always used for luma
         dxy = (my & 2) | ((mx & 2) >> 1);
         if (!v->rnd)
-            dsp->put_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+            s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
         else
-            dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+            s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
     }
 
     if (s->flags & CODEC_FLAG_GRAY) return;
@@ -524,11 +537,11 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
-        dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     } else {
-        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     }
 }
 
@@ -545,15 +558,16 @@ static inline int median4(int a, int b, int c, int d)
 
 /** Do motion compensation for 4-MV macroblock - luminance block
  */
-static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
+static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
 {
     MpegEncContext *s = &v->s;
-    DSPContext *dsp = &v->s.dsp;
     uint8_t *srcY;
     int dxy, mx, my, src_x, src_y;
     int off;
     int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
+    uint8_t (*luty)[256];
+    int use_ic;
 
     if ((!v->field_mode ||
          (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&
@@ -564,15 +578,20 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
     my = s->mv[dir][n][1];
 
     if (!dir) {
-        if (v->field_mode) {
-            if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type)
-                srcY = s->current_picture.f.data[0];
-            else
-                srcY = s->last_picture.f.data[0];
-        } else
+        if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
+            srcY = s->current_picture.f.data[0];
+            luty = v->curr_luty;
+            use_ic = v->curr_use_ic;
+        } else {
             srcY = s->last_picture.f.data[0];
-    } else
+            luty = v->last_luty;
+            use_ic = v->last_use_ic;
+        }
+    } else {
         srcY = s->next_picture.f.data[0];
+        luty = v->next_luty;
+        use_ic = v->next_use_ic;
+    }
 
     if (!srcY) {
         av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");
@@ -612,8 +631,8 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
             ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
             break;
         }
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
         for (k = 0; k < 4; k++)
             v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
     }
@@ -622,6 +641,10 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
         int qx, qy;
         int width  = s->avctx->coded_width;
         int height = s->avctx->coded_height >> 1;
+        if (s->pict_type == AV_PICTURE_TYPE_P) {
+            s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;
+            s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;
+        }
         qx = (s->mb_x * 16) + (mx >> 2);
         qy = (s->mb_y *  8) + (my >> 3);
 
@@ -639,8 +662,6 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
         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)
-        off += s->current_picture_ptr->f.linesize[0];
 
     src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);
     if (!fieldmv)
@@ -671,13 +692,14 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
         v_edge_pos--;
     if (fieldmv && (src_y & 1) && src_y < 4)
         src_y--;
-    if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
+    if (v->rangeredfrm || use_ic
         || s->h_edge_pos < 13 || v_edge_pos < 23
         || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2
         || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {
         srcY -= s->mspel * (1 + (s->linesize << fieldmv));
         /* check emulate edge stride and offset */
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+                                 s->linesize, s->linesize,
                                  9 + s->mspel * 2, (9 + s->mspel * 2) << fieldmv,
                                  src_x - s->mspel, src_y - (s->mspel << fieldmv),
                                  s->h_edge_pos, v_edge_pos);
@@ -695,14 +717,15 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
             }
         }
         /* if we deal with intensity compensation we need to scale source blocks */
-        if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+        if (use_ic) {
             int i, j;
             uint8_t *src;
 
             src = srcY;
             for (j = 0; j < 9 + s->mspel * 2; j++) {
+                int f = v->field_mode ? v->ref_field_type[dir] : (((j<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1);
                 for (i = 0; i < 9 + s->mspel * 2; i++)
-                    src[i] = v->luty[src[i]];
+                    src[i] = luty[f][src[i]];
                 src += s->linesize << fieldmv;
             }
         }
@@ -711,13 +734,16 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
 
     if (s->mspel) {
         dxy = ((my & 3) << 2) | (mx & 3);
-        v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
+        if (avg)
+            v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
+        else
+            v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);
     } else { // hpel mc - always used for luma
         dxy = (my & 2) | ((mx & 2) >> 1);
         if (!v->rnd)
-            dsp->put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
+            s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
         else
-            dsp->put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
+            s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);
     }
 }
 
@@ -779,14 +805,16 @@ static av_always_inline int get_chroma_mv(int *mvx, int *mvy, int *a, int flag,
 static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
 {
     MpegEncContext *s = &v->s;
-    DSPContext *dsp   = &v->s.dsp;
+    H264ChromaContext *h264chroma = &v->h264chroma;
     uint8_t *srcU, *srcV;
     int uvmx, uvmy, uvsrc_x, uvsrc_y;
     int k, tx = 0, ty = 0;
     int mvx[4], mvy[4], intra[4], mv_f[4];
     int valid_count;
-    int chroma_ref_type = v->cur_field_type, off = 0;
+    int chroma_ref_type = v->cur_field_type;
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
+    uint8_t (*lutuv)[256];
+    int use_ic;
 
     if (!v->field_mode && !v->s.last_picture.f.data[0])
         return;
@@ -806,8 +834,8 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
         valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
         chroma_ref_type = v->reffield;
         if (!valid_count) {
-            s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
-            s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
             return; //no need to do MC for intra blocks
         }
@@ -821,8 +849,8 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
     }
     if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f.data[0])
         return;
-    s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
-    s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
+    s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+    s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
     uvmx = (tx + ((tx & 3) == 3)) >> 1;
     uvmy = (ty + ((ty & 3) == 3)) >> 1;
 
@@ -849,21 +877,22 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
     }
 
     if (!dir) {
-        if (v->field_mode) {
-            if ((v->cur_field_type != chroma_ref_type) && v->cur_field_type) {
-                srcU = s->current_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
-                srcV = s->current_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
-            } else {
-                srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
-                srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
-            }
+        if (v->field_mode && (v->cur_field_type != chroma_ref_type) && v->second_field) {
+            srcU = s->current_picture.f.data[1];
+            srcV = s->current_picture.f.data[2];
+            lutuv = v->curr_lutuv;
+            use_ic = v->curr_use_ic;
         } else {
-            srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
-            srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+            srcU = s->last_picture.f.data[1];
+            srcV = s->last_picture.f.data[2];
+            lutuv = v->last_lutuv;
+            use_ic = v->last_use_ic;
         }
     } else {
-        srcU = s->next_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
-        srcV = s->next_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+        srcU = s->next_picture.f.data[1];
+        srcV = s->next_picture.f.data[2];
+        lutuv = v->next_lutuv;
+        use_ic = v->next_use_ic;
     }
 
     if (!srcU) {
@@ -871,22 +900,26 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
         return;
     }
 
+    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+
     if (v->field_mode) {
         if (chroma_ref_type) {
             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;
     }
 
-    if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
+    if (v->rangeredfrm || use_ic
         || s->h_edge_pos < 18 || v_edge_pos < 18
         || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 9
         || (unsigned)uvsrc_y > (v_edge_pos    >> 1) - 9) {
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer     , srcU, s->uvlinesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
+                                 s->uvlinesize, s->uvlinesize,
                                  8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
+                                 s->uvlinesize, s->uvlinesize,
                                  8 + 1, 8 + 1, uvsrc_x, uvsrc_y,
                                  s->h_edge_pos >> 1, v_edge_pos >> 1);
         srcU = s->edge_emu_buffer;
@@ -909,16 +942,17 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
             }
         }
         /* if we deal with intensity compensation we need to scale source blocks */
-        if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+        if (use_ic) {
             int i, j;
             uint8_t *src, *src2;
 
             src  = srcU;
             src2 = srcV;
             for (j = 0; j < 9; j++) {
+                int f = v->field_mode ? chroma_ref_type : ((j + uvsrc_y) & 1);
                 for (i = 0; i < 9; i++) {
-                    src[i]  = v->lutuv[src[i]];
-                    src2[i] = v->lutuv[src2[i]];
+                    src[i]  = lutuv[f][src[i]];
+                    src2[i] = lutuv[f][src2[i]];
                 }
                 src  += s->uvlinesize;
                 src2 += s->uvlinesize;
@@ -930,20 +964,20 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
-        dsp->put_h264_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        dsp->put_h264_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     } else {
-        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);
+        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
     }
 }
 
-/** Do motion compensation for 4-MV field chroma macroblock (both U and V)
+/** Do motion compensation for 4-MV interlaced frame chroma macroblock (both U and V)
  */
-static void vc1_mc_4mv_chroma4(VC1Context *v)
+static void vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
 {
     MpegEncContext *s = &v->s;
-    DSPContext *dsp = &v->s.dsp;
+    H264ChromaContext *h264chroma = &v->h264chroma;
     uint8_t *srcU, *srcV;
     int uvsrc_x, uvsrc_y;
     int uvmx_field[4], uvmy_field[4];
@@ -952,16 +986,17 @@ static void vc1_mc_4mv_chroma4(VC1Context *v)
     static const int s_rndtblfield[16] = { 0, 0, 1, 2, 4, 4, 5, 6, 2, 2, 3, 8, 6, 6, 7, 12 };
     int v_dist = fieldmv ? 1 : 4; // vertical offset for lower sub-blocks
     int v_edge_pos = s->v_edge_pos >> 1;
+    int use_ic;
+    uint8_t (*lutuv)[256];
 
-    if (!v->s.last_picture.f.data[0])
-        return;
     if (s->flags & CODEC_FLAG_GRAY)
         return;
 
     for (i = 0; i < 4; i++) {
-        tx = s->mv[0][i][0];
+        int d = i < 2 ? dir: dir2;
+        tx = s->mv[d][i][0];
         uvmx_field[i] = (tx + ((tx & 3) == 3)) >> 1;
-        ty = s->mv[0][i][1];
+        ty = s->mv[d][i][1];
         if (fieldmv)
             uvmy_field[i] = (ty >> 4) * 8 + s_rndtblfield[ty & 0xF];
         else
@@ -975,8 +1010,17 @@ static void vc1_mc_4mv_chroma4(VC1Context *v)
         // FIXME: implement proper pull-back (see vc1cropmv.c, vc1CROPMV_ChromaPullBack())
         uvsrc_x = av_clip(uvsrc_x, -8, s->avctx->coded_width  >> 1);
         uvsrc_y = av_clip(uvsrc_y, -8, s->avctx->coded_height >> 1);
-        srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
-        srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+        if (i < 2 ? dir : dir2) {
+            srcU = s->next_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+            srcV = s->next_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+            lutuv  = v->next_lutuv;
+            use_ic = v->next_use_ic;
+        } else {
+            srcU = s->last_picture.f.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+            srcV = s->last_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+            lutuv  = v->last_lutuv;
+            use_ic = v->last_use_ic;
+        }
         uvmx_field[i] = (uvmx_field[i] & 3) << 1;
         uvmy_field[i] = (uvmy_field[i] & 3) << 1;
 
@@ -984,42 +1028,55 @@ static void vc1_mc_4mv_chroma4(VC1Context *v)
             v_edge_pos--;
         if (fieldmv && (uvsrc_y & 1) && uvsrc_y < 2)
             uvsrc_y--;
-        if ((v->mv_mode == MV_PMODE_INTENSITY_COMP)
+        if (use_ic
             || s->h_edge_pos < 10 || v_edge_pos < (5 << fieldmv)
             || (unsigned)uvsrc_x > (s->h_edge_pos >> 1) - 5
             || (unsigned)uvsrc_y > v_edge_pos - (5 << fieldmv)) {
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcU,
+                                     s->uvlinesize, s->uvlinesize,
                                      5, (5 << fieldmv), uvsrc_x, uvsrc_y,
                                      s->h_edge_pos >> 1, v_edge_pos);
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV, s->uvlinesize,
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer + 16, srcV,
+                                     s->uvlinesize, s->uvlinesize,
                                      5, (5 << fieldmv), uvsrc_x, uvsrc_y,
                                      s->h_edge_pos >> 1, v_edge_pos);
             srcU = s->edge_emu_buffer;
             srcV = s->edge_emu_buffer + 16;
 
             /* if we deal with intensity compensation we need to scale source blocks */
-            if (v->mv_mode == MV_PMODE_INTENSITY_COMP) {
+            if (use_ic) {
                 int i, j;
                 uint8_t *src, *src2;
 
                 src  = srcU;
                 src2 = srcV;
                 for (j = 0; j < 5; j++) {
+                    int f = (uvsrc_y + (j << fieldmv)) & 1;
                     for (i = 0; i < 5; i++) {
-                        src[i]  = v->lutuv[src[i]];
-                        src2[i] = v->lutuv[src2[i]];
+                        src[i]  = lutuv[f][src[i]];
+                        src2[i] = lutuv[f][src2[i]];
                     }
-                    src  += s->uvlinesize << 1;
-                    src2 += s->uvlinesize << 1;
+                    src  += s->uvlinesize << fieldmv;
+                    src2 += s->uvlinesize << fieldmv;
                 }
             }
         }
-        if (!v->rnd) {
-            dsp->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
-            dsp->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+        if (avg) {
+            if (!v->rnd) {
+                h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+                h264chroma->avg_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            } else {
+                v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+                v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            }
         } else {
-            v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
-            v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            if (!v->rnd) {
+                h264chroma->put_h264_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+                h264chroma->put_h264_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            } else {
+                v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[1] + off, srcU, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+                v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[1](s->dest[2] + off, srcV, s->uvlinesize << fieldmv, 4, uvmx_field[i], uvmy_field[i]);
+            }
         }
     }
 }
@@ -1389,30 +1446,30 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
     xy   = s->block_index[n];
 
     if (s->mb_intra) {
-        s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = 0;
-        s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = 0;
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = 0;
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0;
+        s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0;
+        s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0;
+        s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0;
+        s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
         if (mv1) { /* duplicate motion data for 1-MV block */
-            s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][0]        = 0;
-            s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][1]        = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][0]     = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][1]     = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
+            s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0]        = 0;
+            s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1]        = 0;
+            s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0]     = 0;
+            s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1]     = 0;
+            s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
+            s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
-            s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][0]        = 0;
-            s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][1]        = 0;
-            s->current_picture.f.motion_val[1][xy + wrap][0]                     = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + v->blocks_off][1]     = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
+            s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0]        = 0;
+            s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1]        = 0;
+            s->current_picture.motion_val[1][xy + wrap][0]                     = 0;
+            s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1]     = 0;
+            s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
+            s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
         }
         return;
     }
 
-    C = s->current_picture.f.motion_val[dir][xy -    1 + v->blocks_off];
-    A = s->current_picture.f.motion_val[dir][xy - wrap + v->blocks_off];
+    C = s->current_picture.motion_val[dir][xy -    1 + v->blocks_off];
+    A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off];
     if (mv1) {
         if (v->field_mode && mixedmv_pic)
             off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
@@ -1434,7 +1491,7 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
             off = -1;
         }
     }
-    B = s->current_picture.f.motion_val[dir][xy - wrap + off + v->blocks_off];
+    B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off];
 
     a_valid = !s->first_slice_line || (n == 2 || n == 3);
     b_valid = a_valid && (s->mb_width > 1);
@@ -1597,15 +1654,15 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
     if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
         y_bias = 1;
     /* store MV using signed modulus of MV range defined in 4.11 */
-    s->mv[dir][n][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
-    s->mv[dir][n][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
+    s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+    s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
     if (mv1) { /* duplicate motion data for 1-MV block */
-        s->current_picture.f.motion_val[dir][xy +    1 +     v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
-        s->current_picture.f.motion_val[dir][xy +    1 +     v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
-        s->current_picture.f.motion_val[dir][xy + wrap +     v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
-        s->current_picture.f.motion_val[dir][xy + wrap +     v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
-        s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
-        s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
+        s->current_picture.motion_val[dir][xy +    1 +     v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+        s->current_picture.motion_val[dir][xy +    1 +     v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+        s->current_picture.motion_val[dir][xy + wrap +     v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+        s->current_picture.motion_val[dir][xy + wrap +     v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+        s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+        s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
         v->mv_f[dir][xy +    1 + v->blocks_off] = v->mv_f[dir][xy +            v->blocks_off];
         v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
     }
@@ -1614,7 +1671,7 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
 /** Predict and set motion vector for interlaced frame picture MBs
  */
 static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
-                                     int mvn, int r_x, int r_y, uint8_t* is_intra)
+                                     int mvn, int r_x, int r_y, uint8_t* is_intra, int dir)
 {
     MpegEncContext *s = &v->s;
     int xy, wrap, off = 0;
@@ -1629,24 +1686,24 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
     xy = s->block_index[n];
 
     if (s->mb_intra) {
-        s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = 0;
-        s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = 0;
-        s->current_picture.f.motion_val[1][xy][0] = 0;
-        s->current_picture.f.motion_val[1][xy][1] = 0;
+        s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
+        s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
+        s->current_picture.motion_val[1][xy][0] = 0;
+        s->current_picture.motion_val[1][xy][1] = 0;
         if (mvn == 1) { /* duplicate motion data for 1-MV block */
-            s->current_picture.f.motion_val[0][xy + 1][0]        = 0;
-            s->current_picture.f.motion_val[0][xy + 1][1]        = 0;
-            s->current_picture.f.motion_val[0][xy + wrap][0]     = 0;
-            s->current_picture.f.motion_val[0][xy + wrap][1]     = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + 1][0] = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + 1][1] = 0;
+            s->current_picture.motion_val[0][xy + 1][0]        = 0;
+            s->current_picture.motion_val[0][xy + 1][1]        = 0;
+            s->current_picture.motion_val[0][xy + wrap][0]     = 0;
+            s->current_picture.motion_val[0][xy + wrap][1]     = 0;
+            s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
+            s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
-            s->current_picture.f.motion_val[1][xy + 1][0]        = 0;
-            s->current_picture.f.motion_val[1][xy + 1][1]        = 0;
-            s->current_picture.f.motion_val[1][xy + wrap][0]     = 0;
-            s->current_picture.f.motion_val[1][xy + wrap][1]     = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + 1][0] = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + 1][1] = 0;
+            s->current_picture.motion_val[1][xy + 1][0]        = 0;
+            s->current_picture.motion_val[1][xy + 1][1]        = 0;
+            s->current_picture.motion_val[1][xy + wrap][0]     = 0;
+            s->current_picture.motion_val[1][xy + wrap][1]     = 0;
+            s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
+            s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
         }
         return;
     }
@@ -1656,14 +1713,14 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
     if (s->mb_x || (n == 1) || (n == 3)) {
         if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
             || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
-            A[0] = s->current_picture.f.motion_val[0][xy - 1][0];
-            A[1] = s->current_picture.f.motion_val[0][xy - 1][1];
+            A[0] = s->current_picture.motion_val[dir][xy - 1][0];
+            A[1] = s->current_picture.motion_val[dir][xy - 1][1];
             a_valid = 1;
         } else { // current block has frame mv and cand. has field MV (so average)
-            A[0] = (s->current_picture.f.motion_val[0][xy - 1][0]
-                    + s->current_picture.f.motion_val[0][xy - 1 + off * wrap][0] + 1) >> 1;
-            A[1] = (s->current_picture.f.motion_val[0][xy - 1][1]
-                    + s->current_picture.f.motion_val[0][xy - 1 + off * wrap][1] + 1) >> 1;
+            A[0] = (s->current_picture.motion_val[dir][xy - 1][0]
+                    + s->current_picture.motion_val[dir][xy - 1 + off * wrap][0] + 1) >> 1;
+            A[1] = (s->current_picture.motion_val[dir][xy - 1][1]
+                    + s->current_picture.motion_val[dir][xy - 1 + off * wrap][1] + 1) >> 1;
             a_valid = 1;
         }
         if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
@@ -1683,11 +1740,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
                 if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
                     n_adj = (n & 2) | (n & 1);
                 }
-                B[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][0];
-                B[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][1];
+                B[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][0];
+                B[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap][1];
                 if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
-                    B[0] = (B[0] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
-                    B[1] = (B[1] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
+                    B[0] = (B[0] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
+                    B[1] = (B[1] + s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
                 }
             }
             if (s->mb_width > 1) {
@@ -1698,11 +1755,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
                     if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
                         n_adj = n & 2;
                     }
-                    C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][0];
-                    C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][1];
+                    C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][0];
+                    C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap + 2][1];
                     if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
-                        C[0] = (1 + C[0] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
-                        C[1] = (1 + C[1] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
+                        C[0] = (1 + C[0] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
+                        C[1] = (1 + C[1] + (s->current_picture.motion_val[dir][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
                     }
                     if (s->mb_x == s->mb_width - 1) {
                         if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
@@ -1712,11 +1769,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
                             if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
                                 n_adj = n | 1;
                             }
-                            C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][0];
-                            C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][1];
+                            C[0] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][0];
+                            C[1] = s->current_picture.motion_val[dir][s->block_index[n_adj] - 2 * wrap - 2][1];
                             if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
-                                C[0] = (1 + C[0] + s->current_picture.f.motion_val[0][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
-                                C[1] = (1 + C[1] + s->current_picture.f.motion_val[0][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
+                                C[0] = (1 + C[0] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
+                                C[1] = (1 + C[1] + s->current_picture.motion_val[dir][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
                             }
                         } else
                             c_valid = 0;
@@ -1727,12 +1784,12 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
     } else {
         pos_b   = s->block_index[1];
         b_valid = 1;
-        B[0]    = s->current_picture.f.motion_val[0][pos_b][0];
-        B[1]    = s->current_picture.f.motion_val[0][pos_b][1];
+        B[0]    = s->current_picture.motion_val[dir][pos_b][0];
+        B[1]    = s->current_picture.motion_val[dir][pos_b][1];
         pos_c   = s->block_index[0];
         c_valid = 1;
-        C[0]    = s->current_picture.f.motion_val[0][pos_c][0];
-        C[1]    = s->current_picture.f.motion_val[0][pos_c][1];
+        C[0]    = s->current_picture.motion_val[dir][pos_c][0];
+        C[1]    = s->current_picture.motion_val[dir][pos_c][1];
     }
 
     total_valid = a_valid + b_valid + c_valid;
@@ -1820,20 +1877,20 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
     }
 
     /* store MV using signed modulus of MV range defined in 4.11 */
-    s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
-    s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
+    s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+    s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
     if (mvn == 1) { /* duplicate motion data for 1-MV block */
-        s->current_picture.f.motion_val[0][xy +    1    ][0] = s->current_picture.f.motion_val[0][xy][0];
-        s->current_picture.f.motion_val[0][xy +    1    ][1] = s->current_picture.f.motion_val[0][xy][1];
-        s->current_picture.f.motion_val[0][xy + wrap    ][0] = s->current_picture.f.motion_val[0][xy][0];
-        s->current_picture.f.motion_val[0][xy + wrap    ][1] = s->current_picture.f.motion_val[0][xy][1];
-        s->current_picture.f.motion_val[0][xy + wrap + 1][0] = s->current_picture.f.motion_val[0][xy][0];
-        s->current_picture.f.motion_val[0][xy + wrap + 1][1] = s->current_picture.f.motion_val[0][xy][1];
+        s->current_picture.motion_val[dir][xy +    1    ][0] = s->current_picture.motion_val[dir][xy][0];
+        s->current_picture.motion_val[dir][xy +    1    ][1] = s->current_picture.motion_val[dir][xy][1];
+        s->current_picture.motion_val[dir][xy + wrap    ][0] = s->current_picture.motion_val[dir][xy][0];
+        s->current_picture.motion_val[dir][xy + wrap    ][1] = s->current_picture.motion_val[dir][xy][1];
+        s->current_picture.motion_val[dir][xy + wrap + 1][0] = s->current_picture.motion_val[dir][xy][0];
+        s->current_picture.motion_val[dir][xy + wrap + 1][1] = s->current_picture.motion_val[dir][xy][1];
     } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
-        s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0];
-        s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1];
-        s->mv[0][n + 1][0] = s->mv[0][n][0];
-        s->mv[0][n + 1][1] = s->mv[0][n][1];
+        s->current_picture.motion_val[dir][xy + 1][0] = s->current_picture.motion_val[dir][xy][0];
+        s->current_picture.motion_val[dir][xy + 1][1] = s->current_picture.motion_val[dir][xy][1];
+        s->mv[dir][n + 1][0] = s->mv[dir][n][0];
+        s->mv[dir][n + 1][1] = s->mv[dir][n][1];
     }
 }
 
@@ -1842,11 +1899,12 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
 static void vc1_interp_mc(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
-    DSPContext *dsp = &v->s.dsp;
+    H264ChromaContext *h264chroma = &v->h264chroma;
     uint8_t *srcY, *srcU, *srcV;
     int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
     int off, off_uv;
     int v_edge_pos = s->v_edge_pos >> v->field_mode;
+    int use_ic = v->next_use_ic;
 
     if (!v->field_mode && !v->s.next_picture.f.data[0])
         return;
@@ -1901,20 +1959,25 @@ static void vc1_interp_mc(VC1Context *v)
         srcV = s->edge_emu_buffer + 18 * s->linesize;
     }
 
-    if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22
+    if (v->rangeredfrm || s->h_edge_pos < 22 || v_edge_pos < 22 || use_ic
         || (unsigned)(src_x - 1) > s->h_edge_pos - (mx & 3) - 16 - 3
         || (unsigned)(src_y - 1) > v_edge_pos    - (my & 3) - 16 - 3) {
         uint8_t *uvbuf = s->edge_emu_buffer + 19 * s->linesize;
 
         srcY -= s->mspel * (1 + s->linesize);
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize,
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,
+                                 s->linesize, s->linesize,
                                  17 + s->mspel * 2, 17 + s->mspel * 2,
                                  src_x - s->mspel, src_y - s->mspel,
                                  s->h_edge_pos, v_edge_pos);
         srcY = s->edge_emu_buffer;
-        s->vdsp.emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, 8 + 1, 8 + 1,
+        s->vdsp.emulated_edge_mc(uvbuf, srcU,
+                                 s->uvlinesize, s->uvlinesize,
+                                 8 + 1, 8 + 1,
                                  uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
-        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8 + 1, 8 + 1,
+        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,
+                                 s->uvlinesize, s->uvlinesize,
+                                 8 + 1, 8 + 1,
                                  uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);
         srcU = uvbuf;
         srcV = uvbuf + 16;
@@ -1940,16 +2003,37 @@ static void vc1_interp_mc(VC1Context *v)
                 src2 += s->uvlinesize;
             }
         }
+
+        if (use_ic) {
+            uint8_t (*luty )[256] = v->next_luty;
+            uint8_t (*lutuv)[256] = v->next_lutuv;
+            int i, j;
+            uint8_t *src, *src2;
+
+            src = srcY;
+            for (j = 0; j < 17 + s->mspel * 2; j++) {
+                int f = v->field_mode ? v->ref_field_type[1] : ((j+src_y - s->mspel) & 1);
+                for (i = 0; i < 17 + s->mspel * 2; i++)
+                    src[i] = luty[f][src[i]];
+                src += s->linesize;
+            }
+            src  = srcU;
+            src2 = srcV;
+            for (j = 0; j < 9; j++) {
+                int f = v->field_mode ? v->ref_field_type[1] : ((j+uvsrc_y) & 1);
+                for (i = 0; i < 9; i++) {
+                    src[i]  = lutuv[f][src[i]];
+                    src2[i] = lutuv[f][src2[i]];
+                }
+                src  += s->uvlinesize;
+                src2 += s->uvlinesize;
+            }
+        }
         srcY += s->mspel * (1 + s->linesize);
     }
 
-    if (v->field_mode && v->cur_field_type) {
-        off    = s->current_picture_ptr->f.linesize[0];
-        off_uv = s->current_picture_ptr->f.linesize[1];
-    } else {
-        off    = 0;
-        off_uv = 0;
-    }
+    off    = 0;
+    off_uv = 0;
 
     if (s->mspel) {
         dxy = ((my & 3) << 2) | (mx & 3);
@@ -1962,9 +2046,9 @@ static void vc1_interp_mc(VC1Context *v)
         dxy = (my & 2) | ((mx & 2) >> 1);
 
         if (!v->rnd)
-            dsp->avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+            s->hdsp.avg_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
         else
-            dsp->avg_no_rnd_pixels_tab[0][dxy](s->dest[0] + off, srcY, s->linesize, 16);
+            s->hdsp.avg_no_rnd_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize, 16);
     }
 
     if (s->flags & CODEC_FLAG_GRAY) return;
@@ -1972,8 +2056,8 @@ static void vc1_interp_mc(VC1Context *v)
     uvmx = (uvmx & 3) << 1;
     uvmy = (uvmy & 3) << 1;
     if (!v->rnd) {
-        dsp->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
-        dsp->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
+        h264chroma->avg_h264_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
     } else {
         v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1] + off_uv, srcU, s->uvlinesize, 8, uvmx, uvmy);
         v->vc1dsp.avg_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2] + off_uv, srcV, s->uvlinesize, 8, uvmx, uvmy);
@@ -2004,30 +2088,18 @@ static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs)
 static inline void vc1_b_mc(VC1Context *v, int dmv_x[2], int dmv_y[2],
                             int direct, int mode)
 {
-    if (v->use_ic) {
-        v->mv_mode2 = v->mv_mode;
-        v->mv_mode  = MV_PMODE_INTENSITY_COMP;
-    }
     if (direct) {
         vc1_mc_1mv(v, 0);
         vc1_interp_mc(v);
-        if (v->use_ic)
-            v->mv_mode = v->mv_mode2;
         return;
     }
     if (mode == BMV_TYPE_INTERPOLATED) {
         vc1_mc_1mv(v, 0);
         vc1_interp_mc(v);
-        if (v->use_ic)
-            v->mv_mode = v->mv_mode2;
         return;
     }
 
-    if (v->use_ic && (mode == BMV_TYPE_BACKWARD))
-        v->mv_mode = v->mv_mode2;
     vc1_mc_1mv(v, (mode == BMV_TYPE_BACKWARD));
-    if (v->use_ic)
-        v->mv_mode = v->mv_mode2;
 }
 
 static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
@@ -2053,17 +2125,17 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
     xy = s->block_index[0];
 
     if (s->mb_intra) {
-        s->current_picture.f.motion_val[0][xy + v->blocks_off][0] =
-        s->current_picture.f.motion_val[0][xy + v->blocks_off][1] =
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][0] =
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0;
+        s->current_picture.motion_val[0][xy + v->blocks_off][0] =
+        s->current_picture.motion_val[0][xy + v->blocks_off][1] =
+        s->current_picture.motion_val[1][xy + v->blocks_off][0] =
+        s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
         return;
     }
     if (!v->field_mode) {
-        s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
-        s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
-        s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
-        s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
+        s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
+        s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
+        s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
+        s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
 
         /* Pullback predicted motion vectors as specified in 8.4.5.4 */
         s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width  << 6) - 4 - (s->mb_x << 6));
@@ -2072,18 +2144,18 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
         s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
     }
     if (direct) {
-        s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0];
-        s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1];
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0];
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1];
+        s->current_picture.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0];
+        s->current_picture.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1];
+        s->current_picture.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0];
+        s->current_picture.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1];
         return;
     }
 
     if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
-        C   = s->current_picture.f.motion_val[0][xy - 2];
-        A   = s->current_picture.f.motion_val[0][xy - wrap * 2];
+        C   = s->current_picture.motion_val[0][xy - 2];
+        A   = s->current_picture.motion_val[0][xy - wrap * 2];
         off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
-        B   = s->current_picture.f.motion_val[0][xy - wrap * 2 + off];
+        B   = s->current_picture.motion_val[0][xy - wrap * 2 + off];
 
         if (!s->mb_x) C[0] = C[1] = 0;
         if (!s->first_slice_line) { // predictor A is not out of bounds
@@ -2158,10 +2230,10 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
         s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
     }
     if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
-        C   = s->current_picture.f.motion_val[1][xy - 2];
-        A   = s->current_picture.f.motion_val[1][xy - wrap * 2];
+        C   = s->current_picture.motion_val[1][xy - 2];
+        A   = s->current_picture.motion_val[1][xy - wrap * 2];
         off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
-        B   = s->current_picture.f.motion_val[1][xy - wrap * 2 + off];
+        B   = s->current_picture.motion_val[1][xy - wrap * 2 + off];
 
         if (!s->mb_x)
             C[0] = C[1] = 0;
@@ -2237,10 +2309,10 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
         s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
         s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
     }
-    s->current_picture.f.motion_val[0][xy][0] = s->mv[0][0][0];
-    s->current_picture.f.motion_val[0][xy][1] = s->mv[0][0][1];
-    s->current_picture.f.motion_val[1][xy][0] = s->mv[1][0][0];
-    s->current_picture.f.motion_val[1][xy][1] = s->mv[1][0][1];
+    s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
+    s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
+    s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
+    s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
 }
 
 static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag)
@@ -2251,14 +2323,14 @@ static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dm
 
     if (v->bmvtype == BMV_TYPE_DIRECT) {
         int total_opp, k, f;
-        if (s->next_picture.f.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
-            s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0],
+        if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
+            s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
                                       v->bfraction, 0, s->quarter_sample);
-            s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1],
+            s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
                                       v->bfraction, 0, s->quarter_sample);
-            s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0],
+            s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
                                       v->bfraction, 1, s->quarter_sample);
-            s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1],
+            s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
                                       v->bfraction, 1, s->quarter_sample);
 
             total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off]
@@ -2273,10 +2345,10 @@ static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dm
         }
         v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
         for (k = 0; k < 4; k++) {
-            s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
-            s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
-            s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
-            s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
+            s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
+            s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
+            s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
+            s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
             v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
             v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
         }
@@ -2394,17 +2466,17 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
     b = dc_val[ - 1 - wrap];
     a = dc_val[ - wrap];
     /* scale predictors if needed */
-    q1 = s->current_picture.f.qscale_table[mb_pos];
+    q1 = s->current_picture.qscale_table[mb_pos];
     dqscale_index = s->y_dc_scale_table[q1] - 1;
     if (dqscale_index < 0)
         return 0;
     if (c_avail && (n != 1 && n != 3)) {
-        q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+        q2 = s->current_picture.qscale_table[mb_pos - 1];
         if (q2 && q2 != q1)
             c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
     if (a_avail && (n != 2 && n != 3)) {
-        q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+        q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
         if (q2 && q2 != q1)
             a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
@@ -2414,7 +2486,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
             off--;
         if (n != 2)
             off -= s->mb_stride;
-        q2 = s->current_picture.f.qscale_table[off];
+        q2 = s->current_picture.qscale_table[off];
         if (q2 && q2 != q1)
             b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
@@ -2553,7 +2625,7 @@ static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip,
  * @param coded are AC coeffs present or not
  * @param codingset set of VLC to decode data
  */
-static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_i_block(VC1Context *v, int16_t block[64], int n,
                               int coded, int codingset)
 {
     GetBitContext *gb = &v->s.gb;
@@ -2716,7 +2788,7 @@ not_coded:
  * @param codingset set of VLC to decode data
  * @param mquant quantizer value for this macroblock
  */
-static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
                                   int coded, int codingset, int mquant)
 {
     GetBitContext *gb = &v->s.gb;
@@ -2785,11 +2857,11 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n,
     else // top
         ac_val -= 16 * s->block_wrap[n];
 
-    q1 = s->current_picture.f.qscale_table[mb_pos];
+    q1 = s->current_picture.qscale_table[mb_pos];
     if ( dc_pred_dir && c_avail && mb_pos)
-        q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+        q2 = s->current_picture.qscale_table[mb_pos - 1];
     if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
-        q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+        q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
     if ( dc_pred_dir && n == 1)
         q2 = q1;
     if (!dc_pred_dir && n == 2)
@@ -2928,7 +3000,7 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n,
  * @param mquant block quantizer
  * @param codingset set of VLC to decode data
  */
-static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
                                   int coded, int mquant, int codingset)
 {
     GetBitContext *gb = &v->s.gb;
@@ -3008,11 +3080,11 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n,
     else //top
         ac_val -= 16 * s->block_wrap[n];
 
-    q1 = s->current_picture.f.qscale_table[mb_pos];
+    q1 = s->current_picture.qscale_table[mb_pos];
     if (dc_pred_dir && c_avail && mb_pos)
-        q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+        q2 = s->current_picture.qscale_table[mb_pos - 1];
     if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
-        q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+        q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
     if ( dc_pred_dir && n == 1)
         q2 = q1;
     if (!dc_pred_dir && n == 2)
@@ -3138,7 +3210,7 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n,
 
 /** Decode P block
  */
-static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n,
+static int vc1_decode_p_block(VC1Context *v, int16_t block[64], int n,
                               int mquant, int ttmb, int first_block,
                               uint8_t *dst, int linesize, int skip_block,
                               int *ttmb_out)
@@ -3330,7 +3402,7 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_
             bottom_is_intra = (block_num < 2) ? (mb_is_intra          >> ((block_num + 2) * 4))
                                               : (v->is_intra[s->mb_x] >> ((block_num - 2) * 4));
             mv_stride       = s->b8_stride;
-            mv              = &s->current_picture.f.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
+            mv              = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
         }
 
         if (bottom_is_intra & 1 || block_is_intra & 1 ||
@@ -3392,7 +3464,7 @@ static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_
                                              : (mb_cbp                              >> ((block_num + 1) * 4));
             right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
                                              : (mb_is_intra                         >> ((block_num + 1) * 4));
-            mv             = &s->current_picture.f.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
+            mv             = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
         }
         if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) {
             v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
@@ -3486,10 +3558,10 @@ static int vc1_decode_p_mb(VC1Context *v)
             GET_MVDATA(dmv_x, dmv_y);
 
             if (s->mb_intra) {
-                s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
-                s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
+                s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+                s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
             }
-            s->current_picture.f.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
+            s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
             vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
 
             /* FIXME Set DC val for inter block ? */
@@ -3506,7 +3578,7 @@ static int vc1_decode_p_mb(VC1Context *v)
                 mquant = v->pq;
                 cbp    = 0;
             }
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
 
             if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table,
@@ -3560,8 +3632,8 @@ static int vc1_decode_p_mb(VC1Context *v)
                 v->mb_type[0][s->block_index[i]] = 0;
                 s->dc_val[0][s->block_index[i]]  = 0;
             }
-            s->current_picture.f.mb_type[mb_pos]      = MB_TYPE_SKIP;
-            s->current_picture.f.qscale_table[mb_pos] = 0;
+            s->current_picture.mb_type[mb_pos]      = MB_TYPE_SKIP;
+            s->current_picture.qscale_table[mb_pos] = 0;
             vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
             vc1_mc_1mv(v, 0);
         }
@@ -3584,7 +3656,7 @@ static int vc1_decode_p_mb(VC1Context *v)
                     }
                     vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
                     if (!s->mb_intra)
-                        vc1_mc_4mv_luma(v, i, 0);
+                        vc1_mc_4mv_luma(v, i, 0, 0);
                     intra_count += s->mb_intra;
                     is_intra[i]  = s->mb_intra;
                     is_coded[i]  = mb_has_coeffs;
@@ -3604,7 +3676,7 @@ static int vc1_decode_p_mb(VC1Context *v)
             if (!intra_count && !coded_inter)
                 goto end;
             GET_MQUANT();
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             /* test if block is intra and has pred */
             {
                 int intrapred = 0;
@@ -3667,17 +3739,17 @@ static int vc1_decode_p_mb(VC1Context *v)
             }
         } else { // skipped MB
             s->mb_intra                               = 0;
-            s->current_picture.f.qscale_table[mb_pos] = 0;
+            s->current_picture.qscale_table[mb_pos] = 0;
             for (i = 0; i < 6; i++) {
                 v->mb_type[0][s->block_index[i]] = 0;
                 s->dc_val[0][s->block_index[i]]  = 0;
             }
             for (i = 0; i < 4; i++) {
                 vc1_pred_mv(v, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0], 0, 0);
-                vc1_mc_4mv_luma(v, i, 0);
+                vc1_mc_4mv_luma(v, i, 0, 0);
             }
             vc1_mc_4mv_chroma(v, 0);
-            s->current_picture.f.qscale_table[mb_pos] = 0;
+            s->current_picture.qscale_table[mb_pos] = 0;
         }
     }
 end:
@@ -3752,9 +3824,11 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             break;
         }
         if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
-            s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
-            s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
-            s->current_picture.f.mb_type[mb_pos]                     = MB_TYPE_INTRA;
+            for (i = 0; i < 4; i++) {
+                s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
+                s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
+            }
+            s->current_picture.mb_type[mb_pos]                     = MB_TYPE_INTRA;
             s->mb_intra = v->is_intra[s->mb_x] = 1;
             for (i = 0; i < 6; i++)
                 v->mb_type[0][s->block_index[i]] = 1;
@@ -3764,7 +3838,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
                 cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
             GET_MQUANT();
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             /* Set DC scale - y and c use the same (not sure if necessary here) */
             s->y_dc_scale = s->y_dc_scale_table[mquant];
             s->c_dc_scale = s->c_dc_scale_table[mquant];
@@ -3822,10 +3896,10 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
                         if (val) {
                             get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                         }
-                        vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]);
-                        vc1_mc_4mv_luma(v, i, 0);
+                        vc1_pred_mv_intfr(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], 0);
+                        vc1_mc_4mv_luma(v, i, 0, 0);
                     } else if (i == 4) {
-                        vc1_mc_4mv_chroma4(v);
+                        vc1_mc_4mv_chroma4(v, 0, 0, 0);
                     }
                 }
             } else if (twomv) {
@@ -3834,29 +3908,29 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
                 if (mvbp & 2) {
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                 }
-                vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0]);
-                vc1_mc_4mv_luma(v, 0, 0);
-                vc1_mc_4mv_luma(v, 1, 0);
+                vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
+                vc1_mc_4mv_luma(v, 0, 0, 0);
+                vc1_mc_4mv_luma(v, 1, 0, 0);
                 dmv_x = dmv_y = 0;
                 if (mvbp & 1) {
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                 }
-                vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0]);
-                vc1_mc_4mv_luma(v, 2, 0);
-                vc1_mc_4mv_luma(v, 3, 0);
-                vc1_mc_4mv_chroma4(v);
+                vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], 0);
+                vc1_mc_4mv_luma(v, 2, 0, 0);
+                vc1_mc_4mv_luma(v, 3, 0, 0);
+                vc1_mc_4mv_chroma4(v, 0, 0, 0);
             } else {
                 mvbp = ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][2];
                 dmv_x = dmv_y = 0;
                 if (mvbp) {
                     get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
                 }
-                vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]);
+                vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
                 vc1_mc_1mv(v, 0);
             }
             if (cbp)
                 GET_MQUANT();  // p. 227
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             if (!v->ttmbf && cbp)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
             for (i = 0; i < 6; i++) {
@@ -3885,13 +3959,13 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             v->mb_type[0][s->block_index[i]] = 0;
             s->dc_val[0][s->block_index[i]] = 0;
         }
-        s->current_picture.f.mb_type[mb_pos]      = MB_TYPE_SKIP;
-        s->current_picture.f.qscale_table[mb_pos] = 0;
+        s->current_picture.mb_type[mb_pos]      = MB_TYPE_SKIP;
+        s->current_picture.qscale_table[mb_pos] = 0;
         v->blk_mv_type[s->block_index[0]] = 0;
         v->blk_mv_type[s->block_index[1]] = 0;
         v->blk_mv_type[s->block_index[2]] = 0;
         v->blk_mv_type[s->block_index[3]] = 0;
-        vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]);
+        vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
         vc1_mc_1mv(v, 0);
     }
     if (s->mb_x == s->mb_width - 1)
@@ -3923,11 +3997,11 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
     idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
     if (idx_mbmode <= 1) { // intra MB
         s->mb_intra = v->is_intra[s->mb_x] = 1;
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
-        s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+        s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
         GET_MQUANT();
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same (not sure if necessary here) */
         s->y_dc_scale = s->y_dc_scale_table[mquant];
         s->c_dc_scale = s->c_dc_scale_table[mquant];
@@ -3953,13 +4027,12 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
                 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;
             s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i & 4) ? s->uvlinesize : s->linesize);
             // TODO: loop filter
         }
     } else {
         s->mb_intra = v->is_intra[s->mb_x] = 0;
-        s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
+        s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
         for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
         if (idx_mbmode <= 5) { // 1-MV
             dmv_x = dmv_y = pred_flag = 0;
@@ -3979,7 +4052,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
                         get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag);
                     }
                     vc1_pred_mv(v, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0], pred_flag, 0);
-                    vc1_mc_4mv_luma(v, i, 0);
+                    vc1_mc_4mv_luma(v, i, 0, 0);
                 } else if (i == 4)
                     vc1_mc_4mv_chroma(v, 0);
             }
@@ -3990,7 +4063,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
         if (cbp) {
             GET_MQUANT();
         }
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         if (!v->ttmbf && cbp) {
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
@@ -4000,8 +4073,6 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
             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)
-                off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
             if (val) {
                 pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                          first_block, s->dest[dst_idx] + off,
@@ -4056,7 +4127,7 @@ static void vc1_decode_b_mb(VC1Context *v)
         v->mb_type[0][s->block_index[i]] = 0;
         s->dc_val[0][s->block_index[i]]  = 0;
     }
-    s->current_picture.f.qscale_table[mb_pos] = 0;
+    s->current_picture.qscale_table[mb_pos] = 0;
 
     if (!direct) {
         if (!skipped) {
@@ -4093,7 +4164,7 @@ static void vc1_decode_b_mb(VC1Context *v)
         cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
         GET_MQUANT();
         s->mb_intra = 0;
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         if (!v->ttmbf)
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;
@@ -4108,7 +4179,7 @@ static void vc1_decode_b_mb(VC1Context *v)
         }
         if (s->mb_intra && !mb_has_coeffs) {
             GET_MQUANT();
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             s->ac_pred = get_bits1(gb);
             cbp = 0;
             vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
@@ -4130,7 +4201,7 @@ static void vc1_decode_b_mb(VC1Context *v)
                 s->ac_pred = get_bits1(gb);
             cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             GET_MQUANT();
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
@@ -4197,11 +4268,11 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
     idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
     if (idx_mbmode <= 1) { // intra MB
         s->mb_intra = v->is_intra[s->mb_x] = 1;
-        s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
-        s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
-        s->current_picture.f.mb_type[mb_pos + v->mb_off]         = MB_TYPE_INTRA;
+        s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+        s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+        s->current_picture.mb_type[mb_pos + v->mb_off]         = MB_TYPE_INTRA;
         GET_MQUANT();
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same (not sure if necessary here) */
         s->y_dc_scale = s->y_dc_scale_table[mquant];
         s->c_dc_scale = s->c_dc_scale_table[mquant];
@@ -4230,13 +4301,12 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
                 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;
             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
         }
     } else {
         s->mb_intra = v->is_intra[s->mb_x] = 0;
-        s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
+        s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
         for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
         if (v->fmb_is_raw)
             fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb);
@@ -4291,7 +4361,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
                                              &pred_flag[bmvtype == BMV_TYPE_BACKWARD]);
                     }
                     vc1_pred_b_mv_intfi(v, i, dmv_x, dmv_y, 0, pred_flag);
-                    vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD);
+                    vc1_mc_4mv_luma(v, i, bmvtype == BMV_TYPE_BACKWARD, 0);
                 } else if (i == 4)
                     vc1_mc_4mv_chroma(v, bmvtype == BMV_TYPE_BACKWARD);
             }
@@ -4302,7 +4372,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
         if (cbp) {
             GET_MQUANT();
         }
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         if (!v->ttmbf && cbp) {
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
@@ -4312,8 +4382,6 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
             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)
-                off += (i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0];
             if (val) {
                 vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
                                    first_block, s->dest[dst_idx] + off,
@@ -4327,6 +4395,350 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
     }
 }
 
+/** Decode one B-frame MB (in interlaced frame B picture)
+ */
+static int vc1_decode_b_mb_intfr(VC1Context *v)
+{
+    MpegEncContext *s = &v->s;
+    GetBitContext *gb = &s->gb;
+    int i, j;
+    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+    int cbp = 0; /* cbp decoding stuff */
+    int mqdiff, mquant; /* MB quantization */
+    int ttmb = v->ttfrm; /* MB Transform type */
+    int mvsw = 0; /* motion vector switch */
+    int mb_has_coeffs = 1; /* last_flag */
+    int dmv_x, dmv_y; /* Differential MV components */
+    int val; /* temp value */
+    int first_block = 1;
+    int dst_idx, off;
+    int skipped, direct, twomv = 0;
+    int block_cbp = 0, pat, block_tt = 0;
+    int idx_mbmode = 0, mvbp;
+    int stride_y, fieldtx;
+    int bmvtype = BMV_TYPE_BACKWARD;
+    int dir, dir2;
+
+    mquant = v->pq; /* Lossy initialization */
+    s->mb_intra = 0;
+    if (v->skip_is_raw)
+        skipped = get_bits1(gb);
+    else
+        skipped = v->s.mbskip_table[mb_pos];
+
+    if (!skipped) {
+        idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 2);
+        if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_2MV_FIELD) {
+            twomv = 1;
+            v->blk_mv_type[s->block_index[0]] = 1;
+            v->blk_mv_type[s->block_index[1]] = 1;
+            v->blk_mv_type[s->block_index[2]] = 1;
+            v->blk_mv_type[s->block_index[3]] = 1;
+        } else {
+            v->blk_mv_type[s->block_index[0]] = 0;
+            v->blk_mv_type[s->block_index[1]] = 0;
+            v->blk_mv_type[s->block_index[2]] = 0;
+            v->blk_mv_type[s->block_index[3]] = 0;
+        }
+    }
+
+    if (v->dmb_is_raw)
+        direct = get_bits1(gb);
+    else
+        direct = v->direct_mb_plane[mb_pos];
+
+    if (direct) {
+        s->mv[0][0][0] = s->current_picture.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample);
+        s->mv[0][0][1] = s->current_picture.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample);
+        s->mv[1][0][0] = s->current_picture.motion_val[1][s->block_index[0]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][0], v->bfraction, 1, s->quarter_sample);
+        s->mv[1][0][1] = s->current_picture.motion_val[1][s->block_index[0]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0]][1], v->bfraction, 1, s->quarter_sample);
+
+        if (twomv) {
+            s->mv[0][2][0] = s->current_picture.motion_val[0][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 0, s->quarter_sample);
+            s->mv[0][2][1] = s->current_picture.motion_val[0][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 0, s->quarter_sample);
+            s->mv[1][2][0] = s->current_picture.motion_val[1][s->block_index[2]][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][0], v->bfraction, 1, s->quarter_sample);
+            s->mv[1][2][1] = s->current_picture.motion_val[1][s->block_index[2]][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[2]][1], v->bfraction, 1, s->quarter_sample);
+
+            for (i = 1; i < 4; i += 2) {
+                s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][i-1][0];
+                s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][i-1][1];
+                s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][i-1][0];
+                s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][i-1][1];
+            }
+        } else {
+            for (i = 1; i < 4; i++) {
+                s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = s->mv[0][0][0];
+                s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = s->mv[0][0][1];
+                s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = s->mv[1][0][0];
+                s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = s->mv[1][0][1];
+            }
+        }
+    }
+
+    if (ff_vc1_mbmode_intfrp[0][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
+        for (i = 0; i < 4; i++) {
+            s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0] = 0;
+            s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1] = 0;
+            s->mv[1][i][0] = s->current_picture.motion_val[1][s->block_index[i]][0] = 0;
+            s->mv[1][i][1] = s->current_picture.motion_val[1][s->block_index[i]][1] = 0;
+        }
+        s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
+        s->mb_intra = v->is_intra[s->mb_x] = 1;
+        for (i = 0; i < 6; i++)
+            v->mb_type[0][s->block_index[i]] = 1;
+        fieldtx = v->fieldtx_plane[mb_pos] = get_bits1(gb);
+        mb_has_coeffs = get_bits1(gb);
+        if (mb_has_coeffs)
+            cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+        v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
+        GET_MQUANT();
+        s->current_picture.qscale_table[mb_pos] = mquant;
+        /* Set DC scale - y and c use the same (not sure if necessary here) */
+        s->y_dc_scale = s->y_dc_scale_table[mquant];
+        s->c_dc_scale = s->c_dc_scale_table[mquant];
+        dst_idx = 0;
+        for (i = 0; i < 6; i++) {
+            s->dc_val[0][s->block_index[i]] = 0;
+            dst_idx += i >> 2;
+            val = ((cbp >> (5 - i)) & 1);
+            v->mb_type[0][s->block_index[i]] = s->mb_intra;
+            v->a_avail = v->c_avail = 0;
+            if (i == 2 || i == 3 || !s->first_slice_line)
+                v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];
+            if (i == 1 || i == 3 || s->mb_x)
+                v->c_avail = v->mb_type[0][s->block_index[i] - 1];
+
+            vc1_decode_intra_block(v, s->block[i], i, val, mquant,
+                                   (i & 4) ? v->codingset2 : v->codingset);
+            if (i > 3 && (s->flags & CODEC_FLAG_GRAY))
+                continue;
+            v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
+            if (i < 4) {
+                stride_y = s->linesize << fieldtx;
+                off = (fieldtx) ? ((i & 1) * 8) + ((i & 2) >> 1) * s->linesize : (i & 1) * 8 + 4 * (i & 2) * s->linesize;
+            } else {
+                stride_y = s->uvlinesize;
+                off = 0;
+            }
+            s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, stride_y);
+        }
+    } else {
+        s->mb_intra = v->is_intra[s->mb_x] = 0;
+        if (!direct) {
+            if (skipped || !s->mb_intra) {
+                bmvtype = decode012(gb);
+                switch (bmvtype) {
+                case 0:
+                    bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;
+                    break;
+                case 1:
+                    bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;
+                    break;
+                case 2:
+                    bmvtype  = BMV_TYPE_INTERPOLATED;
+                }
+            }
+
+            if (twomv && bmvtype != BMV_TYPE_INTERPOLATED)
+                mvsw = get_bits1(gb);
+        }
+
+        if (!skipped) { // inter MB
+            mb_has_coeffs = ff_vc1_mbmode_intfrp[0][idx_mbmode][3];
+            if (mb_has_coeffs)
+                cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
+            if (!direct) {
+                if (bmvtype == BMV_TYPE_INTERPOLATED & twomv) {
+                    v->fourmvbp = get_vlc2(gb, v->fourmvbp_vlc->table, VC1_4MV_BLOCK_PATTERN_VLC_BITS, 1);
+                } else if (bmvtype == BMV_TYPE_INTERPOLATED | twomv) {
+                    v->twomvbp = get_vlc2(gb, v->twomvbp_vlc->table, VC1_2MV_BLOCK_PATTERN_VLC_BITS, 1);
+                }
+            }
+
+            for (i = 0; i < 6; i++)
+                v->mb_type[0][s->block_index[i]] = 0;
+            fieldtx = v->fieldtx_plane[mb_pos] = ff_vc1_mbmode_intfrp[0][idx_mbmode][1];
+            /* for all motion vector read MVDATA and motion compensate each block */
+            dst_idx = 0;
+            if (direct) {
+                if (twomv) {
+                    for (i = 0; i < 4; i++) {
+                        vc1_mc_4mv_luma(v, i, 0, 0);
+                        vc1_mc_4mv_luma(v, i, 1, 1);
+                    }
+                    vc1_mc_4mv_chroma4(v, 0, 0, 0);
+                    vc1_mc_4mv_chroma4(v, 1, 1, 1);
+                } else {
+                    vc1_mc_1mv(v, 0);
+                    vc1_interp_mc(v);
+                }
+            } else if (twomv && bmvtype == BMV_TYPE_INTERPOLATED) {
+                mvbp = v->fourmvbp;
+                for (i = 0; i < 4; i++) {
+                    dir = i==1 || i==3;
+                    dmv_x = dmv_y = 0;
+                    val = ((mvbp >> (3 - i)) & 1);
+                    if (val)
+                        get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+                    j = i > 1 ? 2 : 0;
+                    vc1_pred_mv_intfr(v, j, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
+                    vc1_mc_4mv_luma(v, j, dir, dir);
+                    vc1_mc_4mv_luma(v, j+1, dir, dir);
+                }
+
+                vc1_mc_4mv_chroma4(v, 0, 0, 0);
+                vc1_mc_4mv_chroma4(v, 1, 1, 1);
+            } else if (bmvtype == BMV_TYPE_INTERPOLATED) {
+                mvbp = v->twomvbp;
+                dmv_x = dmv_y = 0;
+                if (mvbp & 2)
+                    get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+
+                vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0);
+                vc1_mc_1mv(v, 0);
+
+                dmv_x = dmv_y = 0;
+                if (mvbp & 1)
+                    get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+
+                vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 1);
+                vc1_interp_mc(v);
+            } else if (twomv) {
+                dir = bmvtype == BMV_TYPE_BACKWARD;
+                dir2 = dir;
+                if (mvsw)
+                    dir2 = !dir;
+                mvbp = v->twomvbp;
+                dmv_x = dmv_y = 0;
+                if (mvbp & 2)
+                    get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+                vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir);
+
+                dmv_x = dmv_y = 0;
+                if (mvbp & 1)
+                    get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+                vc1_pred_mv_intfr(v, 2, dmv_x, dmv_y, 2, v->range_x, v->range_y, v->mb_type[0], dir2);
+
+                if (mvsw) {
+                    for (i = 0; i < 2; i++) {
+                        s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
+                        s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
+                        s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
+                        s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
+                    }
+                } else {
+                    vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
+                    vc1_pred_mv_intfr(v, 2, 0, 0, 2, v->range_x, v->range_y, v->mb_type[0], !dir);
+                }
+
+                vc1_mc_4mv_luma(v, 0, dir, 0);
+                vc1_mc_4mv_luma(v, 1, dir, 0);
+                vc1_mc_4mv_luma(v, 2, dir2, 0);
+                vc1_mc_4mv_luma(v, 3, dir2, 0);
+                vc1_mc_4mv_chroma4(v, dir, dir2, 0);
+            } else {
+                dir = bmvtype == BMV_TYPE_BACKWARD;
+
+                mvbp = ff_vc1_mbmode_intfrp[0][idx_mbmode][2];
+                dmv_x = dmv_y = 0;
+                if (mvbp)
+                    get_mvdata_interlaced(v, &dmv_x, &dmv_y, 0);
+
+                vc1_pred_mv_intfr(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], dir);
+                v->blk_mv_type[s->block_index[0]] = 1;
+                v->blk_mv_type[s->block_index[1]] = 1;
+                v->blk_mv_type[s->block_index[2]] = 1;
+                v->blk_mv_type[s->block_index[3]] = 1;
+                vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
+                for (i = 0; i < 2; i++) {
+                    s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
+                    s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
+                }
+                vc1_mc_1mv(v, dir);
+            }
+
+            if (cbp)
+                GET_MQUANT();  // p. 227
+            s->current_picture.qscale_table[mb_pos] = mquant;
+            if (!v->ttmbf && cbp)
+                ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
+            for (i = 0; i < 6; i++) {
+                s->dc_val[0][s->block_index[i]] = 0;
+                dst_idx += i >> 2;
+                val = ((cbp >> (5 - i)) & 1);
+                if (!fieldtx)
+                    off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+                else
+                    off = (i & 4) ? 0 : ((i & 1) * 8 + ((i > 1) * s->linesize));
+                if (val) {
+                    pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb,
+                                             first_block, s->dest[dst_idx] + off,
+                                             (i & 4) ? s->uvlinesize : (s->linesize << fieldtx),
+                                             (i & 4) && (s->flags & CODEC_FLAG_GRAY), &block_tt);
+                    block_cbp |= pat << (i << 2);
+                    if (!v->ttmbf && ttmb < 8)
+                        ttmb = -1;
+                    first_block = 0;
+                }
+            }
+
+        } else { // skipped
+            dir = 0;
+            for (i = 0; i < 6; i++) {
+                v->mb_type[0][s->block_index[i]] = 0;
+                s->dc_val[0][s->block_index[i]] = 0;
+            }
+            s->current_picture.mb_type[mb_pos]      = MB_TYPE_SKIP;
+            s->current_picture.qscale_table[mb_pos] = 0;
+            v->blk_mv_type[s->block_index[0]] = 0;
+            v->blk_mv_type[s->block_index[1]] = 0;
+            v->blk_mv_type[s->block_index[2]] = 0;
+            v->blk_mv_type[s->block_index[3]] = 0;
+
+            if (!direct) {
+                if (bmvtype == BMV_TYPE_INTERPOLATED) {
+                    vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0);
+                    vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 1);
+                } else {
+                    dir = bmvtype == BMV_TYPE_BACKWARD;
+                    vc1_pred_mv_intfr(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], dir);
+                    if (mvsw) {
+                        int dir2 = dir;
+                        if (mvsw)
+                            dir2 = !dir;
+                        for (i = 0; i < 2; i++) {
+                            s->mv[dir][i+2][0] = s->mv[dir][i][0] = s->current_picture.motion_val[dir][s->block_index[i+2]][0] = s->current_picture.motion_val[dir][s->block_index[i]][0];
+                            s->mv[dir][i+2][1] = s->mv[dir][i][1] = s->current_picture.motion_val[dir][s->block_index[i+2]][1] = s->current_picture.motion_val[dir][s->block_index[i]][1];
+                            s->mv[dir2][i+2][0] = s->mv[dir2][i][0] = s->current_picture.motion_val[dir2][s->block_index[i]][0] = s->current_picture.motion_val[dir2][s->block_index[i+2]][0];
+                            s->mv[dir2][i+2][1] = s->mv[dir2][i][1] = s->current_picture.motion_val[dir2][s->block_index[i]][1] = s->current_picture.motion_val[dir2][s->block_index[i+2]][1];
+                        }
+                    } else {
+                        v->blk_mv_type[s->block_index[0]] = 1;
+                        v->blk_mv_type[s->block_index[1]] = 1;
+                        v->blk_mv_type[s->block_index[2]] = 1;
+                        v->blk_mv_type[s->block_index[3]] = 1;
+                        vc1_pred_mv_intfr(v, 0, 0, 0, 2, v->range_x, v->range_y, 0, !dir);
+                        for (i = 0; i < 2; i++) {
+                            s->mv[!dir][i+2][0] = s->mv[!dir][i][0] = s->current_picture.motion_val[!dir][s->block_index[i+2]][0] = s->current_picture.motion_val[!dir][s->block_index[i]][0];
+                            s->mv[!dir][i+2][1] = s->mv[!dir][i][1] = s->current_picture.motion_val[!dir][s->block_index[i+2]][1] = s->current_picture.motion_val[!dir][s->block_index[i]][1];
+                        }
+                    }
+                }
+            }
+
+            vc1_mc_1mv(v, dir);
+            if (direct || bmvtype == BMV_TYPE_INTERPOLATED) {
+                vc1_interp_mc(v);
+            }
+        }
+    }
+    if (s->mb_x == s->mb_width - 1)
+        memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
+    v->cbp[s->mb_x]      = block_cbp;
+    v->ttblk[s->mb_x]    = block_tt;
+    return 0;
+}
+
 /** Decode blocks of I-frame
  */
 static void vc1_decode_i_blocks(VC1Context *v)
@@ -4372,7 +4784,7 @@ static void vc1_decode_i_blocks(VC1Context *v)
     s->first_slice_line = 1;
     for (s->mb_y = 0; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (; s->mb_x < v->end_mb_x; s->mb_x++) {
             uint8_t *dst[6];
             ff_update_block_index(s);
@@ -4384,10 +4796,10 @@ static void vc1_decode_i_blocks(VC1Context *v)
             dst[5] = s->dest[2];
             s->dsp.clear_blocks(s->block[0]);
             mb_pos = s->mb_x + s->mb_y * s->mb_width;
-            s->current_picture.f.mb_type[mb_pos]                     = MB_TYPE_INTRA;
-            s->current_picture.f.qscale_table[mb_pos]                = v->pq;
-            s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
-            s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
+            s->current_picture.mb_type[mb_pos]                     = MB_TYPE_INTRA;
+            s->current_picture.qscale_table[mb_pos]                = v->pq;
+            s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+            s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
 
             // do actual MB decoding and displaying
             cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
@@ -4446,25 +4858,25 @@ static void vc1_decode_i_blocks(VC1Context *v)
             if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
 
             if (get_bits_count(&s->gb) > v->bits) {
-                ff_er_add_slice(s, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
+                ff_er_add_slice(&s->er, 0, 0, s->mb_x, s->mb_y, ER_MB_ERROR);
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
                        get_bits_count(&s->gb), v->bits);
                 return;
             }
         }
         if (!v->s.loop_filter)
-            ff_draw_horiz_band(s, s->mb_y * 16, 16);
+            ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
         else if (s->mb_y)
-            ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+            ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
 
         s->first_slice_line = 0;
     }
     if (v->s.loop_filter)
-        ff_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+        ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
 
     /* This is intentionally mb_height and not end_mb_y - unlike in advanced
      * profile, these only differ are when decoding MSS2 rectangles. */
-    ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
+    ff_er_add_slice(&s->er, 0, 0, s->mb_width - 1, s->mb_height - 1, ER_MB_END);
 }
 
 /** Decode blocks of I-frame for advanced profile
@@ -4512,21 +4924,21 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
     s->mb_y             = s->start_mb_y;
     if (s->start_mb_y) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         memset(&s->coded_block[s->block_index[0] - s->b8_stride], 0,
                (1 + s->b8_stride) * sizeof(*s->coded_block));
     }
     for (; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (;s->mb_x < s->mb_width; s->mb_x++) {
-            DCTELEM (*block)[64] = v->block[v->cur_blk_idx];
+            int16_t (*block)[64] = v->block[v->cur_blk_idx];
             ff_update_block_index(s);
             s->dsp.clear_blocks(block[0]);
             mb_pos = s->mb_x + s->mb_y * s->mb_stride;
-            s->current_picture.f.mb_type[mb_pos + v->mb_off]                         = MB_TYPE_INTRA;
-            s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
-            s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+            s->current_picture.mb_type[mb_pos + v->mb_off]                         = MB_TYPE_INTRA;
+            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
 
             // do actual MB decoding and displaying
             if (v->fieldtx_is_raw)
@@ -4542,7 +4954,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
 
             GET_MQUANT();
 
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             /* Set DC scale - y and c use the same */
             s->y_dc_scale = s->y_dc_scale_table[mquant];
             s->c_dc_scale = s->c_dc_scale_table[mquant];
@@ -4574,22 +4986,23 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
 
             if (get_bits_count(&s->gb) > v->bits) {
                 // TODO: may need modification to handle slice coding
-                ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+                ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n",
                        get_bits_count(&s->gb), v->bits);
                 return;
             }
         }
         if (!v->s.loop_filter)
-            ff_draw_horiz_band(s, s->mb_y * 16, 16);
+            ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
         else if (s->mb_y)
-            ff_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
+            ff_mpeg_draw_horiz_band(s, (s->mb_y-1) * 16, 16);
         s->first_slice_line = 0;
     }
 
     /* raw bottom MB row */
     s->mb_x = 0;
-    ff_init_block_index(s);
+    init_block_index(v);
+
     for (;s->mb_x < s->mb_width; s->mb_x++) {
         ff_update_block_index(s);
         vc1_put_signed_blocks_clamped(v);
@@ -4597,8 +5010,8 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
             vc1_loop_filter_iblk_delayed(v, v->pq);
     }
     if (v->s.loop_filter)
-        ff_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
-    ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+        ff_mpeg_draw_horiz_band(s, (s->end_mb_y-1)*16, 16);
+    ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
 }
 
@@ -4632,12 +5045,13 @@ static void vc1_decode_p_blocks(VC1Context *v)
         break;
     }
 
-    apply_loop_filter   = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY);
+    apply_loop_filter   = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY) &&
+                          v->fcm == PROGRESSIVE;
     s->first_slice_line = 1;
     memset(v->cbp_base, 0, sizeof(v->cbp_base[0])*2*s->mb_stride);
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
 
@@ -4646,11 +5060,11 @@ static void vc1_decode_p_blocks(VC1Context *v)
             else if (v->fcm == ILACE_FRAME)
                 vc1_decode_p_mb_intfr(v);
             else vc1_decode_p_mb(v);
-            if (s->mb_y != s->start_mb_y && apply_loop_filter && v->fcm == PROGRESSIVE)
+            if (s->mb_y != s->start_mb_y && apply_loop_filter)
                 vc1_apply_p_loop_filter(v);
             if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
                 // TODO: may need modification to handle slice coding
-                ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+                ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
                        get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
                 return;
@@ -4660,20 +5074,20 @@ static void vc1_decode_p_blocks(VC1Context *v)
         memmove(v->ttblk_base,    v->ttblk,    sizeof(v->ttblk_base[0])    * s->mb_stride);
         memmove(v->is_intra_base, v->is_intra, sizeof(v->is_intra_base[0]) * s->mb_stride);
         memmove(v->luma_mv_base,  v->luma_mv,  sizeof(v->luma_mv_base[0])  * s->mb_stride);
-        if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+        if (s->mb_y != s->start_mb_y) ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
         s->first_slice_line = 0;
     }
     if (apply_loop_filter) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
             vc1_apply_p_loop_filter(v);
         }
     }
     if (s->end_mb_y >= s->start_mb_y)
-        ff_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
-    ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+        ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+    ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
 }
 
@@ -4709,17 +5123,19 @@ static void vc1_decode_b_blocks(VC1Context *v)
     s->first_slice_line = 1;
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         for (; s->mb_x < s->mb_width; s->mb_x++) {
             ff_update_block_index(s);
 
             if (v->fcm == ILACE_FIELD)
                 vc1_decode_b_mb_intfi(v);
+            else if (v->fcm == ILACE_FRAME)
+                vc1_decode_b_mb_intfr(v);
             else
                 vc1_decode_b_mb(v);
             if (get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
                 // TODO: may need modification to handle slice coding
-                ff_er_add_slice(s, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
+                ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR);
                 av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n",
                        get_bits_count(&s->gb), v->bits, s->mb_x, s->mb_y);
                 return;
@@ -4727,14 +5143,14 @@ static void vc1_decode_b_blocks(VC1Context *v)
             if (v->s.loop_filter) vc1_loop_filter_iblk(v, v->pq);
         }
         if (!v->s.loop_filter)
-            ff_draw_horiz_band(s, s->mb_y * 16, 16);
+            ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
         else if (s->mb_y)
-            ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
+            ff_mpeg_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
         s->first_slice_line = 0;
     }
     if (v->s.loop_filter)
-        ff_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
-    ff_er_add_slice(s, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
+        ff_mpeg_draw_horiz_band(s, (s->end_mb_y - 1) * 16, 16);
+    ff_er_add_slice(&s->er, 0, s->start_mb_y << v->field_mode, s->mb_width - 1,
                     (s->end_mb_y << v->field_mode) - 1, ER_MB_END);
 }
 
@@ -4745,16 +5161,16 @@ static void vc1_decode_skip_blocks(VC1Context *v)
     if (!v->s.last_picture.f.data[0])
         return;
 
-    ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
+    ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END);
     s->first_slice_line = 1;
     for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
         s->mb_x = 0;
-        ff_init_block_index(s);
+        init_block_index(v);
         ff_update_block_index(s);
         memcpy(s->dest[0], s->last_picture.f.data[0] + s->mb_y * 16 * s->linesize,   s->linesize   * 16);
         memcpy(s->dest[1], s->last_picture.f.data[1] + s->mb_y *  8 * s->uvlinesize, s->uvlinesize *  8);
         memcpy(s->dest[2], s->last_picture.f.data[2] + s->mb_y *  8 * s->uvlinesize, s->uvlinesize *  8);
-        ff_draw_horiz_band(s, s->mb_y * 16, 16);
+        ff_mpeg_draw_horiz_band(s, s->mb_y * 16, 16);
         s->first_slice_line = 0;
     }
     s->pict_type = AV_PICTURE_TYPE_P;
@@ -4865,7 +5281,7 @@ static void vc1_parse_sprites(VC1Context *v, GetBitContext* gb, SpriteData* sd)
     for (sprite = 0; sprite <= v->two_sprites; sprite++) {
         vc1_sprite_parse_transform(gb, sd->coefs[sprite]);
         if (sd->coefs[sprite][1] || sd->coefs[sprite][3])
-            av_log_ask_for_sample(avctx, "Rotation coefficients are not zero");
+            avpriv_request_sample(avctx, "Non-zero rotation coefficients");
         av_log(avctx, AV_LOG_DEBUG, sprite ? "S2:" : "S1:");
         for (i = 0; i < 7; i++)
             av_log(avctx, AV_LOG_DEBUG, " %d.%.3d",
@@ -4948,8 +5364,8 @@ static void vc1_draw_sprites(VC1Context *v, SpriteData* sd)
         int width = v->output_width>>!!plane;
 
         for (row = 0; row < v->output_height>>!!plane; row++) {
-            uint8_t *dst = v->sprite_output_frame.data[plane] +
-                           v->sprite_output_frame.linesize[plane] * row;
+            uint8_t *dst = v->sprite_output_frame->data[plane] +
+                           v->sprite_output_frame->linesize[plane] * row;
 
             for (sprite = 0; sprite <= v->two_sprites; sprite++) {
                 uint8_t *iplane = s->current_picture.f.data[plane];
@@ -5039,12 +5455,8 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb)
         v->two_sprites = 0;
     }
 
-    if (v->sprite_output_frame.data[0])
-        avctx->release_buffer(avctx, &v->sprite_output_frame);
-
-    v->sprite_output_frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-    v->sprite_output_frame.reference = 0;
-    if (ff_get_buffer(avctx, &v->sprite_output_frame) < 0) {
+    av_frame_unref(v->sprite_output_frame);
+    if (ff_get_buffer(avctx, v->sprite_output_frame, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -5078,14 +5490,15 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
     int i;
+    int mb_height = FFALIGN(s->mb_height, 2);
 
     /* Allocate mb bitplanes */
-    v->mv_type_mb_plane = av_malloc (s->mb_stride * s->mb_height);
-    v->direct_mb_plane  = av_malloc (s->mb_stride * s->mb_height);
-    v->forward_mb_plane = av_malloc (s->mb_stride * s->mb_height);
-    v->fieldtx_plane    = av_mallocz(s->mb_stride * s->mb_height);
-    v->acpred_plane     = av_malloc (s->mb_stride * s->mb_height);
-    v->over_flags_plane = av_malloc (s->mb_stride * s->mb_height);
+    v->mv_type_mb_plane = av_malloc (s->mb_stride * mb_height);
+    v->direct_mb_plane  = av_malloc (s->mb_stride * mb_height);
+    v->forward_mb_plane = av_malloc (s->mb_stride * mb_height);
+    v->fieldtx_plane    = av_mallocz(s->mb_stride * mb_height);
+    v->acpred_plane     = av_malloc (s->mb_stride * mb_height);
+    v->over_flags_plane = av_malloc (s->mb_stride * mb_height);
 
     v->n_allocated_blks = s->mb_width + 2;
     v->block            = av_malloc(sizeof(*v->block) * v->n_allocated_blks);
@@ -5099,23 +5512,20 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v)
     v->luma_mv          = v->luma_mv_base + s->mb_stride;
 
     /* allocate block type info in that way so it could be used with s->block_index[] */
-    v->mb_type_base = av_malloc(s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+    v->mb_type_base = av_malloc(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
     v->mb_type[0]   = v->mb_type_base + s->b8_stride + 1;
-    v->mb_type[1]   = v->mb_type_base + s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride + 1;
-    v->mb_type[2]   = v->mb_type[1] + s->mb_stride * (s->mb_height + 1);
+    v->mb_type[1]   = v->mb_type_base + s->b8_stride * (mb_height * 2 + 1) + s->mb_stride + 1;
+    v->mb_type[2]   = v->mb_type[1] + s->mb_stride * (mb_height + 1);
 
     /* allocate memory to store block level MV info */
-    v->blk_mv_type_base = av_mallocz(     s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+    v->blk_mv_type_base = av_mallocz(     s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
     v->blk_mv_type      = v->blk_mv_type_base + s->b8_stride + 1;
-    v->mv_f_base        = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
+    v->mv_f_base        = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2));
     v->mv_f[0]          = v->mv_f_base + s->b8_stride + 1;
-    v->mv_f[1]          = v->mv_f[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
-    v->mv_f_last_base   = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
-    v->mv_f_last[0]     = v->mv_f_last_base + s->b8_stride + 1;
-    v->mv_f_last[1]     = v->mv_f_last[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
-    v->mv_f_next_base   = av_mallocz(2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
+    v->mv_f[1]          = v->mv_f[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
+    v->mv_f_next_base   = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2));
     v->mv_f_next[0]     = v->mv_f_next_base + s->b8_stride + 1;
-    v->mv_f_next[1]     = v->mv_f_next[0] + (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2);
+    v->mv_f_next[1]     = v->mv_f_next[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);
 
     /* Init coded blocks info */
     if (v->profile == PROFILE_ADVANCED) {
@@ -5186,17 +5596,14 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
         avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
     else
         avctx->pix_fmt = AV_PIX_FMT_GRAY8;
-    avctx->hwaccel = ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
+    avctx->hwaccel = ff_find_hwaccel(avctx);
     v->s.avctx = avctx;
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
     v->s.flags   |= CODEC_FLAG_EMU_EDGE;
 
-    if (avctx->idct_algo == FF_IDCT_AUTO) {
-        avctx->idct_algo = FF_IDCT_WMV2;
-    }
-
     if (ff_vc1_init_common(v) < 0)
         return -1;
+    ff_h264chroma_init(&v->h264chroma, 8);
     ff_vc1dsp_init(&v->vc1dsp);
 
     if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) {
@@ -5264,9 +5671,13 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
             av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n");
             return -1;
         }
-        v->res_sprite = (avctx->codec_tag == MKTAG('W','V','P','2'));
+        v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE);
     }
 
+    v->sprite_output_frame = av_frame_alloc();
+    if (!v->sprite_output_frame)
+        return AVERROR(ENOMEM);
+
     avctx->profile = v->profile;
     if (v->profile == PROFILE_ADVANCED)
         avctx->level = v->level;
@@ -5308,9 +5719,8 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx)
     VC1Context *v = avctx->priv_data;
     int i;
 
-    if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE)
-        && v->sprite_output_frame.data[0])
-        avctx->release_buffer(avctx, &v->sprite_output_frame);
+    av_frame_free(&v->sprite_output_frame);
+
     for (i = 0; i < 4; i++)
         av_freep(&v->sr_rows[i >> 1][i & 1]);
     av_freep(&v->hrd_rate);
@@ -5325,7 +5735,6 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx)
     av_freep(&v->mb_type_base);
     av_freep(&v->blk_mv_type_base);
     av_freep(&v->mv_f_base);
-    av_freep(&v->mv_f_last_base);
     av_freep(&v->mv_f_next_base);
     av_freep(&v->block);
     av_freep(&v->cbp_base);
@@ -5344,7 +5753,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size, n_slices = 0, i;
+    int buf_size = avpkt->size, n_slices = 0, i, ret;
     VC1Context *v = avctx->priv_data;
     MpegEncContext *s = &v->s;
     AVFrame *pict = data;
@@ -5361,7 +5770,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
     if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) {
         /* special case for last picture */
         if (s->low_delay == 0 && s->next_picture_ptr) {
-            *pict = s->next_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
+                return ret;
             s->next_picture_ptr = NULL;
 
             *got_frame = 1;
@@ -5370,13 +5780,6 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
         return 0;
     }
 
-    if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
-        if (v->profile < PROFILE_ADVANCED)
-            avctx->pix_fmt = AV_PIX_FMT_VDPAU_WMV3;
-        else
-            avctx->pix_fmt = AV_PIX_FMT_VDPAU_VC1;
-    }
-
     //for advanced profile we may need to parse and unescape data
     if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
         int buf_size2 = 0;
@@ -5393,8 +5796,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
                 if (size <= 0) continue;
                 switch (AV_RB32(start)) {
                 case VC1_CODE_FRAME:
-                    if (avctx->hwaccel ||
-                        s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
+                    if (avctx->hwaccel)
                         buf_start = start;
                     buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);
                     break;
@@ -5513,26 +5915,19 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    /* We need to set current_picture_ptr before reading the header,
-     * otherwise we cannot store anything in there. */
-    if (s->current_picture_ptr == NULL || s->current_picture_ptr->f.data[0]) {
-        int i = ff_find_unused_picture(s, 0);
-        if (i < 0)
-            goto err;
-        s->current_picture_ptr = &s->picture[i];
-    }
-
     // do parse frame header
     v->pic_header_flag = 0;
+    v->first_pic_header_flag = 1;
     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;
         }
     }
+    v->first_pic_header_flag = 0;
 
     if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE)
         && s->pict_type != AV_PICTURE_TYPE_I) {
@@ -5540,18 +5935,6 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
         goto err;
     }
 
-    // process pulldown flags
-    s->current_picture_ptr->f.repeat_pict = 0;
-    // Pulldown flags are only valid when 'broadcast' has been set.
-    // So ticks_per_frame will be 2
-    if (v->rff) {
-        // repeat field
-        s->current_picture_ptr->f.repeat_pict = 1;
-    } else if (v->rptfrm) {
-        // repeat frames
-        s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2;
-    }
-
     // for skipping the frame
     s->current_picture.f.pict_type = s->pict_type;
     s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
@@ -5577,13 +5960,22 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
         goto err;
     }
 
+    // process pulldown flags
+    s->current_picture_ptr->f.repeat_pict = 0;
+    // Pulldown flags are only valid when 'broadcast' has been set.
+    // So ticks_per_frame will be 2
+    if (v->rff) {
+        // repeat field
+        s->current_picture_ptr->f.repeat_pict = 1;
+    } else if (v->rptfrm) {
+        // repeat frames
+        s->current_picture_ptr->f.repeat_pict = v->rptfrm * 2;
+    }
+
     s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
     s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
 
-    if ((CONFIG_VC1_VDPAU_DECODER)
-        &&s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
-        ff_vdpau_vc1_decode_picture(s, buf_start, (buf + buf_size) - buf_start);
-    else if (avctx->hwaccel) {
+    if (avctx->hwaccel) {
         if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
             goto err;
         if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0)
@@ -5593,25 +5985,16 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
     } else {
         int header_ret = 0;
 
-        ff_er_frame_start(s);
+        ff_mpeg_er_frame_start(s);
 
         v->bits = buf_size * 8;
         v->end_mb_x = s->mb_width;
         if (v->field_mode) {
-            uint8_t *tmp[2];
             s->current_picture.f.linesize[0] <<= 1;
             s->current_picture.f.linesize[1] <<= 1;
             s->current_picture.f.linesize[2] <<= 1;
             s->linesize                      <<= 1;
             s->uvlinesize                    <<= 1;
-            tmp[0]          = v->mv_f_last[0];
-            tmp[1]          = v->mv_f_last[1];
-            v->mv_f_last[0] = v->mv_f_next[0];
-            v->mv_f_last[1] = v->mv_f_next[1];
-            v->mv_f_next[0] = v->mv_f[0];
-            v->mv_f_next[1] = v->mv_f[1];
-            v->mv_f[0] = tmp[0];
-            v->mv_f[1] = tmp[1];
         }
         mb_height = s->mb_height >> v->field_mode;
 
@@ -5641,12 +6024,16 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
                 if (v->field_mode && i == n_slices1 + 2) {
                     if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {
                         av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n");
+                        if (avctx->err_recognition & AV_EF_EXPLODE)
+                            goto err;
                         continue;
                     }
                 } else if (get_bits1(&s->gb)) {
                     v->pic_header_flag = 1;
                     if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {
                         av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n");
+                        if (avctx->err_recognition & AV_EF_EXPLODE)
+                            goto err;
                         continue;
                     }
                 }
@@ -5664,21 +6051,22 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
         }
         if (v->field_mode) {
             v->second_field = 0;
-            if (s->pict_type == AV_PICTURE_TYPE_B) {
-                memcpy(v->mv_f_base, v->mv_f_next_base,
-                       2 * (s->b8_stride * (s->mb_height * 2 + 1) + s->mb_stride * (s->mb_height + 1) * 2));
-            }
             s->current_picture.f.linesize[0] >>= 1;
             s->current_picture.f.linesize[1] >>= 1;
             s->current_picture.f.linesize[2] >>= 1;
             s->linesize                      >>= 1;
             s->uvlinesize                    >>= 1;
+            if (v->s.pict_type != AV_PICTURE_TYPE_BI && v->s.pict_type != AV_PICTURE_TYPE_B) {
+                FFSWAP(uint8_t *, v->mv_f_next[0], v->mv_f[0]);
+                FFSWAP(uint8_t *, v->mv_f_next[1], v->mv_f[1]);
+            }
         }
         av_dlog(s->avctx, "Consumed %i/%i bits\n",
                 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 (!v->field_mode)
+            ff_er_frame_end(&s->er);
     }
 
     ff_MPV_frame_end(s);
@@ -5693,17 +6081,20 @@ image:
         if (vc1_decode_sprites(v, &s->gb))
             goto err;
 #endif
-        *pict      = v->sprite_output_frame;
+        if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0)
+            goto err;
         *got_frame = 1;
     } else {
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            *pict = s->current_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+                goto err;
+            ff_print_debug_info(s, s->current_picture_ptr);
+            *got_frame = 1;
         } else if (s->last_picture_ptr != NULL) {
-            *pict = s->last_picture_ptr->f;
-        }
-        if (s->last_picture_ptr || s->low_delay) {
+            if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+                goto err;
+            ff_print_debug_info(s, s->last_picture_ptr);
             *got_frame = 1;
-            ff_print_debug_info(s, pict);
         }
     }
 
@@ -5731,8 +6122,23 @@ static const AVProfile profiles[] = {
     { FF_PROFILE_UNKNOWN },
 };
 
+static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_DXVA2
+    AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_VAAPI
+    AV_PIX_FMT_VAAPI_VLD,
+#endif
+#if CONFIG_VDPAU
+    AV_PIX_FMT_VDPAU,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
 AVCodec ff_vc1_decoder = {
     .name           = "vc1",
+    .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VC1,
     .priv_data_size = sizeof(VC1Context),
@@ -5741,14 +6147,14 @@ AVCodec ff_vc1_decoder = {
     .decode         = vc1_decode_frame,
     .flush          = ff_mpeg_flush,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
-    .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1"),
-    .pix_fmts       = ff_hwaccel_pixfmt_list_420,
+    .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
     .profiles       = NULL_IF_CONFIG_SMALL(profiles)
 };
 
 #if CONFIG_WMV3_DECODER
 AVCodec ff_wmv3_decoder = {
     .name           = "wmv3",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WMV3,
     .priv_data_size = sizeof(VC1Context),
@@ -5757,40 +6163,7 @@ AVCodec ff_wmv3_decoder = {
     .decode         = vc1_decode_frame,
     .flush          = ff_mpeg_flush,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9"),
-    .pix_fmts       = ff_hwaccel_pixfmt_list_420,
-    .profiles       = NULL_IF_CONFIG_SMALL(profiles)
-};
-#endif
-
-#if CONFIG_WMV3_VDPAU_DECODER
-AVCodec ff_wmv3_vdpau_decoder = {
-    .name           = "wmv3_vdpau",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_WMV3,
-    .priv_data_size = sizeof(VC1Context),
-    .init           = vc1_decode_init,
-    .close          = ff_vc1_decode_end,
-    .decode         = vc1_decode_frame,
-    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 VDPAU"),
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_WMV3, AV_PIX_FMT_NONE },
-    .profiles       = NULL_IF_CONFIG_SMALL(profiles)
-};
-#endif
-
-#if CONFIG_VC1_VDPAU_DECODER
-AVCodec ff_vc1_vdpau_decoder = {
-    .name           = "vc1_vdpau",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_VC1,
-    .priv_data_size = sizeof(VC1Context),
-    .init           = vc1_decode_init,
-    .close          = ff_vc1_decode_end,
-    .decode         = vc1_decode_frame,
-    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_HWACCEL_VDPAU,
-    .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1 VDPAU"),
-    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_VC1, AV_PIX_FMT_NONE },
+    .pix_fmts       = vc1_hwaccel_pixfmt_list_420,
     .profiles       = NULL_IF_CONFIG_SMALL(profiles)
 };
 #endif
@@ -5798,6 +6171,7 @@ AVCodec ff_vc1_vdpau_decoder = {
 #if CONFIG_WMV3IMAGE_DECODER
 AVCodec ff_wmv3image_decoder = {
     .name           = "wmv3image",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WMV3IMAGE,
     .priv_data_size = sizeof(VC1Context),
@@ -5806,7 +6180,6 @@ AVCodec ff_wmv3image_decoder = {
     .decode         = vc1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = vc1_sprite_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image"),
     .pix_fmts       = ff_pixfmt_list_420
 };
 #endif
@@ -5814,6 +6187,7 @@ AVCodec ff_wmv3image_decoder = {
 #if CONFIG_VC1IMAGE_DECODER
 AVCodec ff_vc1image_decoder = {
     .name           = "vc1image",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VC1IMAGE,
     .priv_data_size = sizeof(VC1Context),
@@ -5822,7 +6196,6 @@ AVCodec ff_vc1image_decoder = {
     .decode         = vc1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .flush          = vc1_sprite_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Image v2"),
     .pix_fmts       = ff_pixfmt_list_420
 };
 #endif
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index 81a74e3..12295ff 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -25,8 +25,9 @@
  *
  */
 
-#include "vc1dsp.h"
 #include "libavutil/common.h"
+#include "h264chroma.h"
+#include "vc1dsp.h"
 
 
 /** Apply overlap transform to horizontal edge
@@ -79,7 +80,7 @@ static void vc1_h_overlap_c(uint8_t* src, int stride)
     }
 }
 
-static void vc1_v_s_overlap_c(DCTELEM *top,  DCTELEM *bottom)
+static void vc1_v_s_overlap_c(int16_t *top,  int16_t *bottom)
 {
     int i;
     int a, b, c, d;
@@ -105,7 +106,7 @@ static void vc1_v_s_overlap_c(DCTELEM *top,  DCTELEM *bottom)
     }
 }
 
-static void vc1_h_s_overlap_c(DCTELEM *left, DCTELEM *right)
+static void vc1_h_s_overlap_c(int16_t *left, int16_t *right)
 {
     int i;
     int a, b, c, d;
@@ -229,7 +230,7 @@ static void vc1_h_loop_filter16_c(uint8_t *src, int stride, int pq)
 
 /** Do inverse transform on 8x8 block
 */
-static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     int dc = block[0];
@@ -248,11 +249,11 @@ static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
     }
 }
 
-static void vc1_inv_trans_8x8_c(DCTELEM block[64])
+static void vc1_inv_trans_8x8_c(int16_t block[64])
 {
     int i;
     register int t1,t2,t3,t4,t5,t6,t7,t8;
-    DCTELEM *src, *dst, temp[64];
+    int16_t *src, *dst, temp[64];
 
     src = block;
     dst = temp;
@@ -319,7 +320,7 @@ static void vc1_inv_trans_8x8_c(DCTELEM block[64])
 
 /** Do inverse transform on 8x4 part of block
 */
-static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     int dc = block[0];
@@ -338,11 +339,11 @@ static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
     }
 }
 
-static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     register int t1,t2,t3,t4,t5,t6,t7,t8;
-    DCTELEM *src, *dst;
+    int16_t *src, *dst;
 
     src = block;
     dst = block;
@@ -394,7 +395,7 @@ static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, DCTELEM *block)
 
 /** Do inverse transform on 4x8 parts of block
 */
-static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     int dc = block[0];
@@ -409,11 +410,11 @@ static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
     }
 }
 
-static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     register int t1,t2,t3,t4,t5,t6,t7,t8;
-    DCTELEM *src, *dst;
+    int16_t *src, *dst;
 
     src = block;
     dst = block;
@@ -465,7 +466,7 @@ static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, DCTELEM *block)
 
 /** Do inverse transform on 4x4 part of block
 */
-static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     int dc = block[0];
@@ -480,11 +481,11 @@ static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block)
     }
 }
 
-static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, DCTELEM *block)
+static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, int16_t *block)
 {
     int i;
     register int t1,t2,t3,t4;
-    DCTELEM *src, *dst;
+    int16_t *src, *dst;
 
     src = block;
     dst = block;
@@ -626,11 +627,17 @@ VC1_MSPEL_MC(op_avg, avg_)
 /* pixel functions - really are entry points to vc1_mspel_mc */
 
 #define PUT_VC1_MSPEL(a, b)\
-static void put_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \
-     put_vc1_mspel_mc(dst, src, stride, a, b, rnd);                         \
-}\
-static void avg_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \
-     avg_vc1_mspel_mc(dst, src, stride, a, b, rnd);                         \
+static void put_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst,               \
+                                            const uint8_t *src,         \
+                                            ptrdiff_t stride, int rnd)  \
+{                                                                       \
+    put_vc1_mspel_mc(dst, src, stride, a, b, rnd);                      \
+}                                                                       \
+static void avg_vc1_mspel_mc ## a ## b ##_c(uint8_t *dst,               \
+                                            const uint8_t *src,         \
+                                            ptrdiff_t stride, int rnd)  \
+{                                                                       \
+    avg_vc1_mspel_mc(dst, src, stride, a, b, rnd);                      \
 }
 
 PUT_VC1_MSPEL(1, 0)
@@ -847,8 +854,8 @@ av_cold void ff_vc1dsp_init(VC1DSPContext* dsp) {
     dsp->sprite_v_double_twoscale = sprite_v_double_twoscale_c;
 #endif
 
-    if (HAVE_ALTIVEC)
-        ff_vc1dsp_init_altivec(dsp);
+    if (ARCH_PPC)
+        ff_vc1dsp_init_ppc(dsp);
     if (ARCH_X86)
         ff_vc1dsp_init_x86(dsp);
 }
diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h
index 5f364b3..84d4b70 100644
--- a/libavcodec/vc1dsp.h
+++ b/libavcodec/vc1dsp.h
@@ -29,21 +29,23 @@
 #define AVCODEC_VC1DSP_H
 
 #include "dsputil.h"
+#include "hpeldsp.h"
+#include "h264chroma.h"
 
 typedef struct VC1DSPContext {
     /* vc1 functions */
-    void (*vc1_inv_trans_8x8)(DCTELEM *b);
-    void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, int line_size, DCTELEM *block);
+    void (*vc1_inv_trans_8x8)(int16_t *b);
+    void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_8x8_dc)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_8x4_dc)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_4x8_dc)(uint8_t *dest, int line_size, int16_t *block);
+    void (*vc1_inv_trans_4x4_dc)(uint8_t *dest, int line_size, int16_t *block);
     void (*vc1_v_overlap)(uint8_t *src, int stride);
     void (*vc1_h_overlap)(uint8_t *src, int stride);
-    void (*vc1_v_s_overlap)(DCTELEM *top,  DCTELEM *bottom);
-    void (*vc1_h_s_overlap)(DCTELEM *left, DCTELEM *right);
+    void (*vc1_v_s_overlap)(int16_t *top,  int16_t *bottom);
+    void (*vc1_h_s_overlap)(int16_t *left, int16_t *right);
     void (*vc1_v_loop_filter4)(uint8_t *src, int stride, int pq);
     void (*vc1_h_loop_filter4)(uint8_t *src, int stride, int pq);
     void (*vc1_v_loop_filter8)(uint8_t *src, int stride, int pq);
@@ -73,7 +75,7 @@ typedef struct VC1DSPContext {
 } VC1DSPContext;
 
 void ff_vc1dsp_init(VC1DSPContext* c);
-void ff_vc1dsp_init_altivec(VC1DSPContext* c);
+void ff_vc1dsp_init_ppc(VC1DSPContext *c);
 void ff_vc1dsp_init_x86(VC1DSPContext* dsp);
 
 #endif /* AVCODEC_VC1DSP_H */
diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index 42ba787..161704f 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -25,29 +25,16 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "libavutil/internal.h"
 
 typedef struct VCR1Context {
-    AVFrame picture;
     int delta[16];
     int offset[4];
 } VCR1Context;
 
-static av_cold int vcr1_common_init(AVCodecContext *avctx)
-{
-    VCR1Context *const a = avctx->priv_data;
-
-    avctx->coded_frame = &a->picture;
-
-    return 0;
-}
-
 static av_cold int vcr1_decode_init(AVCodecContext *avctx)
 {
-    vcr1_common_init(avctx);
-
     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
 
     if (avctx->width & 7) {
@@ -58,34 +45,19 @@ static av_cold int vcr1_decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int vcr1_decode_end(AVCodecContext *avctx)
-{
-    VCR1Context *s = avctx->priv_data;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf        = avpkt->data;
     int buf_size              = avpkt->size;
     VCR1Context *const a      = avctx->priv_data;
-    AVFrame *picture          = data;
-    AVFrame *const p          = &a->picture;
+    AVFrame *const p          = data;
     const uint8_t *bytestream = buf;
-    int i, x, y;
-
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    int i, x, y, ret;
 
-    p->reference = 0;
-    if (ff_get_buffer(avctx, p) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
@@ -101,11 +73,11 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
 
     for (y = 0; y < avctx->height; y++) {
         int offset;
-        uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]];
+        uint8_t *luma = &p->data[0][y * p->linesize[0]];
 
         if ((y & 3) == 0) {
-            uint8_t *cb = &a->picture.data[1][(y >> 2) * a->picture.linesize[1]];
-            uint8_t *cr = &a->picture.data[2][(y >> 2) * a->picture.linesize[2]];
+            uint8_t *cb = &p->data[1][(y >> 2) * p->linesize[1]];
+            uint8_t *cr = &p->data[2][(y >> 2) * p->linesize[2]];
 
             if (buf_size < 4 + avctx->width)
                 goto packet_small;
@@ -150,7 +122,6 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *picture   = a->picture;
     *got_frame = 1;
 
     return buf_size;
@@ -161,51 +132,11 @@ packet_small:
 
 AVCodec ff_vcr1_decoder = {
     .name           = "vcr1",
+    .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VCR1,
     .priv_data_size = sizeof(VCR1Context),
     .init           = vcr1_decode_init,
-    .close          = vcr1_decode_end,
     .decode         = vcr1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
-};
-
-/* Disable the encoder. */
-#undef CONFIG_VCR1_ENCODER
-#define CONFIG_VCR1_ENCODER 0
-
-#if CONFIG_VCR1_ENCODER
-
-#include "put_bits.h"
-
-static int vcr1_encode_frame(AVCodecContext *avctx, unsigned char *buf,
-                             int buf_size, void *data)
-{
-    VCR1Context *const a = avctx->priv_data;
-    AVFrame *pict        = data;
-    AVFrame *const p     = &a->picture;
-    int size;
-
-    *p           = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
-
-    avpriv_align_put_bits(&a->pb);
-    flush_put_bits(&a->pb);
-
-    size = put_bits_count(&a->pb) / 32;
-
-    return size * 4;
-}
-
-AVCodec ff_vcr1_encoder = {
-    .name           = "vcr1",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_VCR1,
-    .priv_data_size = sizeof(VCR1Context),
-    .init           = vcr1_common_init,
-    .encode         = vcr1_encode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
 };
-#endif /* CONFIG_VCR1_ENCODER */
diff --git a/libavcodec/vda.h b/libavcodec/vda.h
index f0ec2bf..987b94f 100644
--- a/libavcodec/vda.h
+++ b/libavcodec/vda.h
@@ -31,10 +31,6 @@
 
 #include "libavcodec/version.h"
 
-#if FF_API_VDA_ASYNC
-#include <pthread.h>
-#endif
-
 #include <stdint.h>
 
 // emmintrin.h is unable to compile with -std=c99 -Werror=missing-prototypes
@@ -52,39 +48,6 @@
  * @{
  */
 
-#if FF_API_VDA_ASYNC
-/**
- * This structure is used to store decoded frame information and data.
- *
- * @deprecated Use synchronous decoding mode.
- */
-typedef struct vda_frame {
-    /**
-     * The PTS of the frame.
-     *
-     * - encoding: unused
-     * - decoding: Set/Unset by libavcodec.
-     */
-    int64_t             pts;
-
-    /**
-     * The CoreVideo buffer that contains the decoded data.
-     *
-     * - encoding: unused
-     * - decoding: Set/Unset by libavcodec.
-     */
-    CVPixelBufferRef    cv_buffer;
-
-    /**
-     * A pointer to the next frame.
-     *
-     * - encoding: unused
-     * - decoding: Set/Unset by libavcodec.
-     */
-    struct vda_frame    *next_frame;
-} vda_frame;
-#endif
-
 /**
  * This structure is used to provide the necessary configurations and data
  * to the VDA Libav HWAccel implementation.
@@ -116,28 +79,6 @@ struct vda_context {
      */
     int                 use_sync_decoding;
 
-#if FF_API_VDA_ASYNC
-    /**
-     * VDA frames queue ordered by presentation timestamp.
-     *
-     * @deprecated Use synchronous decoding mode.
-     *
-     * - encoding: unused
-     * - decoding: Set/Unset by libavcodec.
-     */
-    vda_frame           *queue;
-
-    /**
-     * Mutex for locking queue operations.
-     *
-     * @deprecated Use synchronous decoding mode.
-     *
-     * - encoding: unused
-     * - decoding: Set/Unset by libavcodec.
-     */
-    pthread_mutex_t     queue_mutex;
-#endif
-
     /**
      * The frame width.
      *
@@ -194,22 +135,6 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx,
 /** Destroy the video decoder. */
 int ff_vda_destroy_decoder(struct vda_context *vda_ctx);
 
-#if FF_API_VDA_ASYNC
-/**
- * Return the top frame of the queue.
- *
- * @deprecated Use synchronous decoding mode.
- */
-vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx);
-
-/**
- * Release the given frame.
- *
- * @deprecated Use synchronous decoding mode.
- */
-void ff_vda_release_vda_frame(vda_frame *frame);
-#endif
-
 /**
  * @}
  */
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
index 34fcd3c..6c1845a 100644
--- a/libavcodec/vda_h264.c
+++ b/libavcodec/vda_h264.c
@@ -28,101 +28,6 @@
 #include "h264.h"
 #include "vda.h"
 
-#if FF_API_VDA_ASYNC
-#include <CoreFoundation/CFDictionary.h>
-
-/* 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);
-    CFDictionaryRef user_info = CFDictionaryCreate(kCFAllocatorDefault,
-                                                   (const void **)&key,
-                                                   (const void **)&value,
-                                                   1,
-                                                   &kCFTypeDictionaryKeyCallBacks,
-                                                   &kCFTypeDictionaryValueCallBacks);
-    CFRelease(value);
-    return user_info;
-}
-
-/* helper to retrieve the pts from the given dictionary */
-static int64_t vda_pts_from_dictionary(CFDictionaryRef user_info)
-{
-    CFNumberRef pts;
-    int64_t outValue = 0;
-
-    if (!user_info)
-        return 0;
-
-    pts = CFDictionaryGetValue(user_info, CFSTR("FF_VDA_DECODER_PTS_KEY"));
-
-    if (pts)
-        CFNumberGetValue(pts, kCFNumberSInt64Type, &outValue);
-
-    return outValue;
-}
-
-/* Remove and release all frames from the queue. */
-static void vda_clear_queue(struct vda_context *vda_ctx)
-{
-    vda_frame *top_frame;
-
-    pthread_mutex_lock(&vda_ctx->queue_mutex);
-
-    while (vda_ctx->queue) {
-        top_frame      = vda_ctx->queue;
-        vda_ctx->queue = top_frame->next_frame;
-        ff_vda_release_vda_frame(top_frame);
-    }
-
-    pthread_mutex_unlock(&vda_ctx->queue_mutex);
-}
-
-static int vda_decoder_decode(struct vda_context *vda_ctx,
-                              uint8_t *bitstream,
-                              int bitstream_size,
-                              int64_t frame_pts)
-{
-    OSStatus status = kVDADecoderNoErr;
-    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);
-
-    CFRelease(user_info);
-    CFRelease(coded_frame);
-
-    return status;
-}
-
-vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx)
-{
-    vda_frame *top_frame;
-
-    if (!vda_ctx->queue)
-        return NULL;
-
-    pthread_mutex_lock(&vda_ctx->queue_mutex);
-    top_frame      = vda_ctx->queue;
-    vda_ctx->queue = top_frame->next_frame;
-    pthread_mutex_unlock(&vda_ctx->queue_mutex);
-
-    return top_frame;
-}
-
-void ff_vda_release_vda_frame(vda_frame *frame)
-{
-    if (frame) {
-        CVPixelBufferRelease(frame->cv_buffer);
-        av_freep(&frame);
-    }
-}
-#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,
@@ -138,42 +43,7 @@ static void vda_decoder_callback(void *vda_hw_ctx,
     if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer))
         return;
 
-    if (vda_ctx->use_sync_decoding) {
-        vda_ctx->cv_buffer = CVPixelBufferRetain(image_buffer);
-    } else {
-        vda_frame *new_frame;
-        vda_frame *queue_walker;
-
-        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);
-
-        pthread_mutex_lock(&vda_ctx->queue_mutex);
-
-        queue_walker = vda_ctx->queue;
-
-        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;
-        } 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;
-                    queue_walker->next_frame = new_frame;
-                    break;
-                }
-                queue_walker = next_frame;
-            }
-        }
-
-        pthread_mutex_unlock(&vda_ctx->queue_mutex);
-    }
+    vda_ctx->cv_buffer = CVPixelBufferRetain(image_buffer);
 }
 
 static int vda_sync_decode(struct vda_context *vda_ctx)
@@ -197,9 +67,9 @@ static int vda_sync_decode(struct vda_context *vda_ctx)
 }
 
 
-static int start_frame(AVCodecContext *avctx,
-                       av_unused const uint8_t *buffer,
-                       av_unused uint32_t size)
+static int vda_h264_start_frame(AVCodecContext *avctx,
+                                av_unused const uint8_t *buffer,
+                                av_unused uint32_t size)
 {
     struct vda_context *vda_ctx         = avctx->hwaccel_context;
 
@@ -211,9 +81,9 @@ static int start_frame(AVCodecContext *avctx,
     return 0;
 }
 
-static int decode_slice(AVCodecContext *avctx,
-                        const uint8_t *buffer,
-                        uint32_t size)
+static int vda_h264_decode_slice(AVCodecContext *avctx,
+                                 const uint8_t *buffer,
+                                 uint32_t size)
 {
     struct vda_context *vda_ctx         = avctx->hwaccel_context;
     void *tmp;
@@ -237,24 +107,18 @@ static int decode_slice(AVCodecContext *avctx,
     return 0;
 }
 
-static int end_frame(AVCodecContext *avctx)
+static int vda_h264_end_frame(AVCodecContext *avctx)
 {
     H264Context *h                      = avctx->priv_data;
     struct vda_context *vda_ctx         = avctx->hwaccel_context;
-    AVFrame *frame                      = &h->s.current_picture_ptr->f;
+    AVFrame *frame                      = &h->cur_pic_ptr->f;
     int status;
 
     if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
         return -1;
 
-    if (vda_ctx->use_sync_decoding) {
-        status = vda_sync_decode(vda_ctx);
-        frame->data[3] = (void*)vda_ctx->cv_buffer;
-    } else {
-        status = vda_decoder_decode(vda_ctx, vda_ctx->priv_bitstream,
-                                    vda_ctx->priv_bitstream_size,
-                                    frame->reordered_opaque);
-    }
+    status = vda_sync_decode(vda_ctx);
+    frame->data[3] = (void*)vda_ctx->cv_buffer;
 
     if (status)
         av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
@@ -276,10 +140,6 @@ int ff_vda_create_decoder(struct vda_context *vda_ctx,
     CFMutableDictionaryRef io_surface_properties;
     CFNumberRef cv_pix_fmt;
 
-#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 preceded by a 4 bytes length header.
      * Change the avcC atom header if needed, to signal headers of 4 bytes. */
@@ -357,11 +217,6 @@ int ff_vda_destroy_decoder(struct vda_context *vda_ctx)
     if (vda_ctx->decoder)
         status = VDADecoderDestroy(vda_ctx->decoder);
 
-#if FF_API_VDA_ASYNC
-    vda_clear_queue(vda_ctx);
-    pthread_mutex_destroy(&vda_ctx->queue_mutex);
-#endif
-
     av_freep(&vda_ctx->priv_bitstream);
 
     return status;
@@ -372,7 +227,7 @@ AVHWAccel ff_h264_vda_hwaccel = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_H264,
     .pix_fmt        = AV_PIX_FMT_VDA_VLD,
-    .start_frame    = start_frame,
-    .decode_slice   = decode_slice,
-    .end_frame      = end_frame,
+    .start_frame    = vda_h264_start_frame,
+    .decode_slice   = vda_h264_decode_slice,
+    .end_frame      = vda_h264_end_frame,
 };
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 6daf494..d8a35ee 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -38,336 +38,104 @@
  * @{
  */
 
-void ff_vdpau_h264_set_reference_frames(MpegEncContext *s)
+int ff_vdpau_common_start_frame(Picture *pic,
+                                av_unused const uint8_t *buffer,
+                                av_unused uint32_t size)
 {
-    H264Context *h = s->avctx->priv_data;
-    struct vdpau_render_state *render, *render_ref;
-    VdpReferenceFrameH264 *rf, *rf2;
-    Picture *pic;
-    int i, list, pic_frame_idx;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
-    assert(render);
-
-    rf = &render->info.h264.referenceFrames[0];
-#define H264_RF_COUNT FF_ARRAY_ELEMS(render->info.h264.referenceFrames)
-
-    for (list = 0; list < 2; ++list) {
-        Picture **lp = list ? h->long_ref : h->short_ref;
-        int ls = list ? 16 : h->short_ref_count;
-
-        for (i = 0; i < ls; ++i) {
-            pic = lp[i];
-            if (!pic || !pic->f.reference)
-                continue;
-            pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
-
-            render_ref = (struct vdpau_render_state *)pic->f.data[0];
-            assert(render_ref);
-
-            rf2 = &render->info.h264.referenceFrames[0];
-            while (rf2 != rf) {
-                if (
-                    (rf2->surface == render_ref->surface)
-                    && (rf2->is_long_term == pic->long_ref)
-                    && (rf2->frame_idx == pic_frame_idx)
-                )
-                    break;
-                ++rf2;
-            }
-            if (rf2 != rf) {
-                rf2->top_is_reference    |= (pic->f.reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
-                rf2->bottom_is_reference |= (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
-                continue;
-            }
-
-            if (rf >= &render->info.h264.referenceFrames[H264_RF_COUNT])
-                continue;
-
-            rf->surface             = render_ref->surface;
-            rf->is_long_term        = pic->long_ref;
-            rf->top_is_reference    = (pic->f.reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
-            rf->bottom_is_reference = (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
-            rf->field_order_cnt[0]  = pic->field_poc[0];
-            rf->field_order_cnt[1]  = pic->field_poc[1];
-            rf->frame_idx           = pic_frame_idx;
-
-            ++rf;
-        }
-    }
-
-    for (; rf < &render->info.h264.referenceFrames[H264_RF_COUNT]; ++rf) {
-        rf->surface             = VDP_INVALID_HANDLE;
-        rf->is_long_term        = 0;
-        rf->top_is_reference    = 0;
-        rf->bottom_is_reference = 0;
-        rf->field_order_cnt[0]  = 0;
-        rf->field_order_cnt[1]  = 0;
-        rf->frame_idx           = 0;
-    }
+    pic_ctx->bitstream_buffers_allocated = 0;
+    pic_ctx->bitstream_buffers_used      = 0;
+    pic_ctx->bitstream_buffers           = NULL;
+    return 0;
 }
 
-void ff_vdpau_add_data_chunk(MpegEncContext *s,
-                             const uint8_t *buf, int buf_size)
+#if CONFIG_H263_VDPAU_HWACCEL  || CONFIG_MPEG1_VDPAU_HWACCEL || \
+    CONFIG_MPEG2_VDPAU_HWACCEL || CONFIG_MPEG4_VDPAU_HWACCEL || \
+    CONFIG_VC1_VDPAU_HWACCEL   || CONFIG_WMV3_VDPAU_HWACCEL
+int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)
 {
-    struct vdpau_render_state *render;
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    MpegEncContext *s = avctx->priv_data;
+    Picture *pic = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpVideoSurface surf = ff_vdpau_get_surface_id(pic);
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
-    assert(render);
+    hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info,
+                  pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
 
-    render->bitstream_buffers= av_fast_realloc(
-        render->bitstream_buffers,
-        &render->bitstream_buffers_allocated,
-        sizeof(*render->bitstream_buffers)*(render->bitstream_buffers_used + 1)
-    );
+    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
+    av_freep(&pic_ctx->bitstream_buffers);
 
-    render->bitstream_buffers[render->bitstream_buffers_used].struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
-    render->bitstream_buffers[render->bitstream_buffers_used].bitstream       = buf;
-    render->bitstream_buffers[render->bitstream_buffers_used].bitstream_bytes = buf_size;
-    render->bitstream_buffers_used++;
+    return 0;
 }
+#endif
 
-void ff_vdpau_h264_picture_start(MpegEncContext *s)
+int ff_vdpau_add_buffer(Picture *pic, const uint8_t *buf, uint32_t size)
 {
-    H264Context *h = s->avctx->priv_data;
-    struct vdpau_render_state *render;
-    int i;
-
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
-    assert(render);
-
-    for (i = 0; i < 2; ++i) {
-        int foc = s->current_picture_ptr->field_poc[i];
-        if (foc == INT_MAX)
-            foc = 0;
-        render->info.h264.field_order_cnt[i] = foc;
-    }
-
-    render->info.h264.frame_num = h->frame_num;
-}
-
-void ff_vdpau_h264_picture_complete(MpegEncContext *s)
-{
-    H264Context *h = s->avctx->priv_data;
-    struct vdpau_render_state *render;
-
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
-    assert(render);
-
-    render->info.h264.slice_count = h->slice_num;
-    if (render->info.h264.slice_count < 1)
-        return;
-
-    render->info.h264.is_reference                           = (s->current_picture_ptr->f.reference & 3) ? VDP_TRUE : VDP_FALSE;
-    render->info.h264.field_pic_flag                         = s->picture_structure != PICT_FRAME;
-    render->info.h264.bottom_field_flag                      = s->picture_structure == PICT_BOTTOM_FIELD;
-    render->info.h264.num_ref_frames                         = h->sps.ref_frame_count;
-    render->info.h264.mb_adaptive_frame_field_flag           = h->sps.mb_aff && !render->info.h264.field_pic_flag;
-    render->info.h264.constrained_intra_pred_flag            = h->pps.constrained_intra_pred;
-    render->info.h264.weighted_pred_flag                     = h->pps.weighted_pred;
-    render->info.h264.weighted_bipred_idc                    = h->pps.weighted_bipred_idc;
-    render->info.h264.frame_mbs_only_flag                    = h->sps.frame_mbs_only_flag;
-    render->info.h264.transform_8x8_mode_flag                = h->pps.transform_8x8_mode;
-    render->info.h264.chroma_qp_index_offset                 = h->pps.chroma_qp_index_offset[0];
-    render->info.h264.second_chroma_qp_index_offset          = h->pps.chroma_qp_index_offset[1];
-    render->info.h264.pic_init_qp_minus26                    = h->pps.init_qp - 26;
-    render->info.h264.num_ref_idx_l0_active_minus1           = h->pps.ref_count[0] - 1;
-    render->info.h264.num_ref_idx_l1_active_minus1           = h->pps.ref_count[1] - 1;
-    render->info.h264.log2_max_frame_num_minus4              = h->sps.log2_max_frame_num - 4;
-    render->info.h264.pic_order_cnt_type                     = h->sps.poc_type;
-    render->info.h264.log2_max_pic_order_cnt_lsb_minus4      = h->sps.poc_type ? 0 : h->sps.log2_max_poc_lsb - 4;
-    render->info.h264.delta_pic_order_always_zero_flag       = h->sps.delta_pic_order_always_zero_flag;
-    render->info.h264.direct_8x8_inference_flag              = h->sps.direct_8x8_inference_flag;
-    render->info.h264.entropy_coding_mode_flag               = h->pps.cabac;
-    render->info.h264.pic_order_present_flag                 = h->pps.pic_order_present;
-    render->info.h264.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
-    render->info.h264.redundant_pic_cnt_present_flag         = h->pps.redundant_pic_cnt_present;
-    memcpy(render->info.h264.scaling_lists_4x4, h->pps.scaling_matrix4, sizeof(render->info.h264.scaling_lists_4x4));
-    memcpy(render->info.h264.scaling_lists_8x8[0], h->pps.scaling_matrix8[0], sizeof(render->info.h264.scaling_lists_8x8[0]));
-    memcpy(render->info.h264.scaling_lists_8x8[1], h->pps.scaling_matrix8[3], sizeof(render->info.h264.scaling_lists_8x8[0]));
-
-    ff_draw_horiz_band(s, 0, s->avctx->height);
-    render->bitstream_buffers_used = 0;
-}
-
-void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
-                                    int buf_size, int slice_count)
-{
-    struct vdpau_render_state *render, *last, *next;
-    int i;
-
-    if (!s->current_picture_ptr) return;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpBitstreamBuffer *buffers = pic_ctx->bitstream_buffers;
 
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
-    assert(render);
+    buffers = av_fast_realloc(buffers, &pic_ctx->bitstream_buffers_allocated,
+                              (pic_ctx->bitstream_buffers_used + 1) * sizeof(*buffers));
+    if (!buffers)
+        return AVERROR(ENOMEM);
 
-    /* fill VdpPictureInfoMPEG1Or2 struct */
-    render->info.mpeg.picture_structure          = s->picture_structure;
-    render->info.mpeg.picture_coding_type        = s->pict_type;
-    render->info.mpeg.intra_dc_precision         = s->intra_dc_precision;
-    render->info.mpeg.frame_pred_frame_dct       = s->frame_pred_frame_dct;
-    render->info.mpeg.concealment_motion_vectors = s->concealment_motion_vectors;
-    render->info.mpeg.intra_vlc_format           = s->intra_vlc_format;
-    render->info.mpeg.alternate_scan             = s->alternate_scan;
-    render->info.mpeg.q_scale_type               = s->q_scale_type;
-    render->info.mpeg.top_field_first            = s->top_field_first;
-    render->info.mpeg.full_pel_forward_vector    = s->full_pel[0]; // MPEG-1 only.  Set 0 for MPEG-2
-    render->info.mpeg.full_pel_backward_vector   = s->full_pel[1]; // MPEG-1 only.  Set 0 for MPEG-2
-    render->info.mpeg.f_code[0][0]               = s->mpeg_f_code[0][0]; // For MPEG-1 fill both horiz. & vert.
-    render->info.mpeg.f_code[0][1]               = s->mpeg_f_code[0][1];
-    render->info.mpeg.f_code[1][0]               = s->mpeg_f_code[1][0];
-    render->info.mpeg.f_code[1][1]               = s->mpeg_f_code[1][1];
-    for (i = 0; i < 64; ++i) {
-        render->info.mpeg.intra_quantizer_matrix[i]     = s->intra_matrix[i];
-        render->info.mpeg.non_intra_quantizer_matrix[i] = s->inter_matrix[i];
-    }
-
-    render->info.mpeg.forward_reference          = VDP_INVALID_HANDLE;
-    render->info.mpeg.backward_reference         = VDP_INVALID_HANDLE;
-
-    switch(s->pict_type){
-    case  AV_PICTURE_TYPE_B:
-        next = (struct vdpau_render_state *)s->next_picture.f.data[0];
-        assert(next);
-        render->info.mpeg.backward_reference     = next->surface;
-        // no return here, going to set forward prediction
-    case  AV_PICTURE_TYPE_P:
-        last = (struct vdpau_render_state *)s->last_picture.f.data[0];
-        if (!last) // FIXME: Does this test make sense?
-            last = render; // predict second field from the first
-        render->info.mpeg.forward_reference      = last->surface;
-    }
+    pic_ctx->bitstream_buffers = buffers;
+    buffers += pic_ctx->bitstream_buffers_used++;
 
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
-
-    render->info.mpeg.slice_count                = slice_count;
-
-    if (slice_count)
-        ff_draw_horiz_band(s, 0, s->avctx->height);
-    render->bitstream_buffers_used               = 0;
+    buffers->struct_version  = VDP_BITSTREAM_BUFFER_VERSION;
+    buffers->bitstream       = buf;
+    buffers->bitstream_bytes = size;
+    return 0;
 }
 
-void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf,
-                                 int buf_size)
+int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile)
 {
-    VC1Context *v = s->avctx->priv_data;
-    struct vdpau_render_state *render, *last, *next;
-
-    render = (struct vdpau_render_state *)s->current_picture.f.data[0];
-    assert(render);
-
-    /*  fill LvPictureInfoVC1 struct */
-    render->info.vc1.frame_coding_mode  = v->fcm;
-    render->info.vc1.postprocflag       = v->postprocflag;
-    render->info.vc1.pulldown           = v->broadcast;
-    render->info.vc1.interlace          = v->interlace;
-    render->info.vc1.tfcntrflag         = v->tfcntrflag;
-    render->info.vc1.finterpflag        = v->finterpflag;
-    render->info.vc1.psf                = v->psf;
-    render->info.vc1.dquant             = v->dquant;
-    render->info.vc1.panscan_flag       = v->panscanflag;
-    render->info.vc1.refdist_flag       = v->refdist_flag;
-    render->info.vc1.quantizer          = v->quantizer_mode;
-    render->info.vc1.extended_mv        = v->extended_mv;
-    render->info.vc1.extended_dmv       = v->extended_dmv;
-    render->info.vc1.overlap            = v->overlap;
-    render->info.vc1.vstransform        = v->vstransform;
-    render->info.vc1.loopfilter         = v->s.loop_filter;
-    render->info.vc1.fastuvmc           = v->fastuvmc;
-    render->info.vc1.range_mapy_flag    = v->range_mapy_flag;
-    render->info.vc1.range_mapy         = v->range_mapy;
-    render->info.vc1.range_mapuv_flag   = v->range_mapuv_flag;
-    render->info.vc1.range_mapuv        = v->range_mapuv;
-    /* Specific to simple/main profile only */
-    render->info.vc1.multires           = v->multires;
-    render->info.vc1.syncmarker         = v->s.resync_marker;
-    render->info.vc1.rangered           = v->rangered | (v->rangeredfrm << 1);
-    render->info.vc1.maxbframes         = v->s.max_b_frames;
-
-    render->info.vc1.deblockEnable      = v->postprocflag & 1;
-    render->info.vc1.pquant             = v->pq;
-
-    render->info.vc1.forward_reference  = VDP_INVALID_HANDLE;
-    render->info.vc1.backward_reference = VDP_INVALID_HANDLE;
-
-    if (v->bi_type)
-        render->info.vc1.picture_type = 4;
-    else
-        render->info.vc1.picture_type = s->pict_type - 1 + s->pict_type / 3;
-
-    switch(s->pict_type){
-    case  AV_PICTURE_TYPE_B:
-        next = (struct vdpau_render_state *)s->next_picture.f.data[0];
-        assert(next);
-        render->info.vc1.backward_reference = next->surface;
-        // no break here, going to set forward prediction
-    case  AV_PICTURE_TYPE_P:
-        last = (struct vdpau_render_state *)s->last_picture.f.data[0];
-        if (!last) // FIXME: Does this test make sense?
-            last = render; // predict second field from the first
-        render->info.vc1.forward_reference = last->surface;
+#define PROFILE(prof)       \
+do {                        \
+    *profile = prof;        \
+    return 0;               \
+} while (0)
+
+    switch (avctx->codec_id) {
+    case AV_CODEC_ID_MPEG1VIDEO:               PROFILE(VDP_DECODER_PROFILE_MPEG1);
+    case AV_CODEC_ID_MPEG2VIDEO:
+        switch (avctx->profile) {
+        case FF_PROFILE_MPEG2_MAIN:            PROFILE(VDP_DECODER_PROFILE_MPEG2_MAIN);
+        case FF_PROFILE_MPEG2_SIMPLE:          PROFILE(VDP_DECODER_PROFILE_MPEG2_SIMPLE);
+        default:                               return AVERROR(EINVAL);
+        }
+    case AV_CODEC_ID_H263:                     PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_ASP);
+    case AV_CODEC_ID_MPEG4:
+        switch (avctx->profile) {
+        case FF_PROFILE_MPEG4_SIMPLE:          PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_SP);
+        case FF_PROFILE_MPEG4_ADVANCED_SIMPLE: PROFILE(VDP_DECODER_PROFILE_MPEG4_PART2_ASP);
+        default:                               return AVERROR(EINVAL);
+        }
+    case AV_CODEC_ID_H264:
+        switch (avctx->profile) {
+        case FF_PROFILE_H264_CONSTRAINED_BASELINE:
+        case FF_PROFILE_H264_BASELINE:         PROFILE(VDP_DECODER_PROFILE_H264_BASELINE);
+        case FF_PROFILE_H264_MAIN:             PROFILE(VDP_DECODER_PROFILE_H264_MAIN);
+        case FF_PROFILE_H264_HIGH:             PROFILE(VDP_DECODER_PROFILE_H264_HIGH);
+        default:                               return AVERROR(EINVAL);
+        }
+    case AV_CODEC_ID_WMV3:
+    case AV_CODEC_ID_VC1:
+        switch (avctx->profile) {
+        case FF_PROFILE_VC1_SIMPLE:            PROFILE(VDP_DECODER_PROFILE_VC1_SIMPLE);
+        case FF_PROFILE_VC1_MAIN:              PROFILE(VDP_DECODER_PROFILE_VC1_MAIN);
+        case FF_PROFILE_VC1_ADVANCED:          PROFILE(VDP_DECODER_PROFILE_VC1_ADVANCED);
+        default:                               return AVERROR(EINVAL);
+        }
     }
-
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
-
-    render->info.vc1.slice_count          = 1;
-
-    ff_draw_horiz_band(s, 0, s->avctx->height);
-    render->bitstream_buffers_used        = 0;
+    return AVERROR(EINVAL);
 }
 
-void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf,
-                                   int buf_size)
+AVVDPAUContext *av_vdpau_alloc_context(void)
 {
-    struct vdpau_render_state *render, *last, *next;
-    int i;
-
-    if (!s->current_picture_ptr) return;
-
-    render = (struct vdpau_render_state *)s->current_picture_ptr->f.data[0];
-    assert(render);
-
-    /* fill VdpPictureInfoMPEG4Part2 struct */
-    render->info.mpeg4.trd[0]                            = s->pp_time;
-    render->info.mpeg4.trb[0]                            = s->pb_time;
-    render->info.mpeg4.trd[1]                            = s->pp_field_time >> 1;
-    render->info.mpeg4.trb[1]                            = s->pb_field_time >> 1;
-    render->info.mpeg4.vop_time_increment_resolution     = s->avctx->time_base.den;
-    render->info.mpeg4.vop_coding_type                   = 0;
-    render->info.mpeg4.vop_fcode_forward                 = s->f_code;
-    render->info.mpeg4.vop_fcode_backward                = s->b_code;
-    render->info.mpeg4.resync_marker_disable             = !s->resync_marker;
-    render->info.mpeg4.interlaced                        = !s->progressive_sequence;
-    render->info.mpeg4.quant_type                        = s->mpeg_quant;
-    render->info.mpeg4.quarter_sample                    = s->quarter_sample;
-    render->info.mpeg4.short_video_header                = s->avctx->codec->id == AV_CODEC_ID_H263;
-    render->info.mpeg4.rounding_control                  = s->no_rounding;
-    render->info.mpeg4.alternate_vertical_scan_flag      = s->alternate_scan;
-    render->info.mpeg4.top_field_first                   = s->top_field_first;
-    for (i = 0; i < 64; ++i) {
-        render->info.mpeg4.intra_quantizer_matrix[i]     = s->intra_matrix[i];
-        render->info.mpeg4.non_intra_quantizer_matrix[i] = s->inter_matrix[i];
-    }
-    render->info.mpeg4.forward_reference                 = VDP_INVALID_HANDLE;
-    render->info.mpeg4.backward_reference                = VDP_INVALID_HANDLE;
-
-    switch (s->pict_type) {
-    case AV_PICTURE_TYPE_B:
-        next = (struct vdpau_render_state *)s->next_picture.f.data[0];
-        assert(next);
-        render->info.mpeg4.backward_reference     = next->surface;
-        render->info.mpeg4.vop_coding_type        = 2;
-        // no break here, going to set forward prediction
-    case AV_PICTURE_TYPE_P:
-        last = (struct vdpau_render_state *)s->last_picture.f.data[0];
-        assert(last);
-        render->info.mpeg4.forward_reference      = last->surface;
-    }
-
-    ff_vdpau_add_data_chunk(s, buf, buf_size);
-
-    ff_draw_horiz_band(s, 0, s->avctx->height);
-    render->bitstream_buffers_used = 0;
+    return av_mallocz(sizeof(AVVDPAUContext));
 }
 
 /* @}*/
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 241ff19..75cb1bf 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -52,6 +52,105 @@
 #include <vdpau/vdpau.h>
 #include <vdpau/vdpau_x11.h>
 
+#include "libavutil/attributes.h"
+
+#include "avcodec.h"
+#include "version.h"
+
+#if FF_API_BUFS_VDPAU
+union AVVDPAUPictureInfo {
+    VdpPictureInfoH264        h264;
+    VdpPictureInfoMPEG1Or2    mpeg;
+    VdpPictureInfoVC1          vc1;
+    VdpPictureInfoMPEG4Part2 mpeg4;
+};
+#endif
+
+/**
+ * This structure is used to share data between the libavcodec library and
+ * the client video application.
+ * The user shall zero-allocate the structure and make it available as
+ * AVCodecContext.hwaccel_context. Members can be set by the user once
+ * during initialization or through each AVCodecContext.get_buffer()
+ * function call. In any case, they must be valid prior to calling
+ * decoding functions.
+ *
+ * The size of this structure is not a part of the public ABI and must not
+ * be used outside of libavcodec. Use av_vdpau_alloc_context() to allocate an
+ * AVVDPAUContext.
+ */
+typedef struct AVVDPAUContext {
+    /**
+     * VDPAU decoder handle
+     *
+     * Set by user.
+     */
+    VdpDecoder decoder;
+
+    /**
+     * VDPAU decoder render callback
+     *
+     * Set by the user.
+     */
+    VdpDecoderRender *render;
+
+#if FF_API_BUFS_VDPAU
+    /**
+     * VDPAU picture information
+     *
+     * Set by libavcodec.
+     */
+    attribute_deprecated
+    union AVVDPAUPictureInfo info;
+
+    /**
+     * Allocated size of the bitstream_buffers table.
+     *
+     * Set by libavcodec.
+     */
+    attribute_deprecated
+    int bitstream_buffers_allocated;
+
+    /**
+     * Useful bitstream buffers in the bitstream buffers table.
+     *
+     * Set by libavcodec.
+     */
+    attribute_deprecated
+    int bitstream_buffers_used;
+
+   /**
+     * Table of bitstream buffers.
+     * The user is responsible for freeing this buffer using av_freep().
+     *
+     * Set by libavcodec.
+     */
+    attribute_deprecated
+    VdpBitstreamBuffer *bitstream_buffers;
+#endif
+} AVVDPAUContext;
+
+/**
+ * Allocate an AVVDPAUContext.
+ *
+ * @return Newly-allocated AVVDPAUContext or NULL on failure.
+ */
+AVVDPAUContext *av_vdpau_alloc_context(void);
+
+/**
+ * Get a decoder profile that should be used for initializing a VDPAU decoder.
+ * Should be called from the AVCodecContext.get_format() callback.
+ *
+ * @param avctx the codec context being used for decoding the stream
+ * @param profile a pointer into which the result will be written on success.
+ *                The contents of profile are undefined if this function returns
+ *                an error.
+ *
+ * @return 0 on success (non-negative), a negative AVERROR on failure.
+ */
+int av_vdpau_get_profile(AVCodecContext *avctx, VdpDecoderProfile *profile);
+
+#if FF_API_CAP_VDPAU
 /** @brief The videoSurface is used for rendering. */
 #define FF_VDPAU_STATE_USED_FOR_RENDER 1
 
@@ -74,12 +173,7 @@ struct vdpau_render_state {
     int state; ///< Holds FF_VDPAU_STATE_* values.
 
     /** picture parameter information for all supported codecs */
-    union VdpPictureInfo {
-        VdpPictureInfoH264        h264;
-        VdpPictureInfoMPEG1Or2    mpeg;
-        VdpPictureInfoVC1          vc1;
-        VdpPictureInfoMPEG4Part2 mpeg4;
-    } info;
+    union AVVDPAUPictureInfo info;
 
     /** Describe size/location of the compressed video data.
         Set to 0 when freeing bitstream_buffers. */
@@ -88,6 +182,7 @@ struct vdpau_render_state {
     /** The user is responsible for freeing this buffer using av_freep(). */
     VdpBitstreamBuffer *bitstream_buffers;
 };
+#endif
 
 /* @}*/
 
diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c
new file mode 100644
index 0000000..3e84644
--- /dev/null
+++ b/libavcodec/vdpau_h264.c
@@ -0,0 +1,215 @@
+/*
+ * MPEG-4 Part 10 / AVC / H.264 HW decode acceleration through VDPAU
+ *
+ * Copyright (c) 2008 NVIDIA
+ * Copyright (c) 2013 Rémi Denis-Courmont
+ *
+ * This file is part of 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "h264.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int32_t h264_foc(int foc)
+{
+    if (foc == INT_MAX)
+        foc = 0;
+    return foc;
+}
+
+static void vdpau_h264_clear_rf(VdpReferenceFrameH264 *rf)
+{
+    rf->surface             = VDP_INVALID_HANDLE;
+    rf->is_long_term        = VDP_FALSE;
+    rf->top_is_reference    = VDP_FALSE;
+    rf->bottom_is_reference = VDP_FALSE;
+    rf->field_order_cnt[0]  = 0;
+    rf->field_order_cnt[1]  = 0;
+    rf->frame_idx           = 0;
+}
+
+static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, Picture *pic,
+                              int pic_structure)
+{
+    VdpVideoSurface surface = ff_vdpau_get_surface_id(pic);
+
+    if (pic_structure == 0)
+        pic_structure = pic->reference;
+
+    rf->surface             = surface;
+    rf->is_long_term        = pic->reference && pic->long_ref;
+    rf->top_is_reference    = (pic_structure & PICT_TOP_FIELD)    != 0;
+    rf->bottom_is_reference = (pic_structure & PICT_BOTTOM_FIELD) != 0;
+    rf->field_order_cnt[0]  = h264_foc(pic->field_poc[0]);
+    rf->field_order_cnt[1]  = h264_foc(pic->field_poc[1]);
+    rf->frame_idx           = pic->long_ref ? pic->pic_id : pic->frame_num;
+}
+
+static void vdpau_h264_set_reference_frames(AVCodecContext *avctx)
+{
+    H264Context * const h = avctx->priv_data;
+    struct vdpau_picture_context *pic_ctx = h->cur_pic_ptr->hwaccel_picture_private;
+    VdpPictureInfoH264 *info = &pic_ctx->info.h264;
+    int list;
+
+    VdpReferenceFrameH264 *rf = &info->referenceFrames[0];
+#define H264_RF_COUNT FF_ARRAY_ELEMS(info->referenceFrames)
+
+    for (list = 0; list < 2; ++list) {
+        Picture **lp = list ? h->long_ref : h->short_ref;
+        int i, ls    = list ? 16          : h->short_ref_count;
+
+        for (i = 0; i < ls; ++i) {
+            Picture *pic = lp[i];
+            VdpReferenceFrameH264 *rf2;
+            VdpVideoSurface surface_ref;
+            int pic_frame_idx;
+
+            if (!pic || !pic->reference)
+                continue;
+            pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
+            surface_ref = ff_vdpau_get_surface_id(pic);
+
+            rf2 = &info->referenceFrames[0];
+            while (rf2 != rf) {
+                if ((rf2->surface      == surface_ref)   &&
+                    (rf2->is_long_term == pic->long_ref) &&
+                    (rf2->frame_idx    == pic_frame_idx))
+                    break;
+                ++rf2;
+            }
+            if (rf2 != rf) {
+                rf2->top_is_reference    |= (pic->reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
+                rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+                continue;
+            }
+
+            if (rf >= &info->referenceFrames[H264_RF_COUNT])
+                continue;
+
+            vdpau_h264_set_rf(rf, pic, pic->reference);
+            ++rf;
+        }
+    }
+
+    for (; rf < &info->referenceFrames[H264_RF_COUNT]; ++rf)
+        vdpau_h264_clear_rf(rf);
+}
+
+static int vdpau_h264_start_frame(AVCodecContext *avctx,
+                                  const uint8_t *buffer, uint32_t size)
+{
+    H264Context * const h = avctx->priv_data;
+    Picture *pic = h->cur_pic_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpPictureInfoH264 *info = &pic_ctx->info.h264;
+
+    /* init VdpPictureInfoH264 */
+    info->slice_count                            = 0;
+    info->field_order_cnt[0]                     = h264_foc(pic->field_poc[0]);
+    info->field_order_cnt[1]                     = h264_foc(pic->field_poc[1]);
+    info->is_reference                           = h->nal_ref_idc != 0;
+    info->frame_num                              = h->frame_num;
+    info->field_pic_flag                         = h->picture_structure != PICT_FRAME;
+    info->bottom_field_flag                      = h->picture_structure == PICT_BOTTOM_FIELD;
+    info->num_ref_frames                         = h->sps.ref_frame_count;
+    info->mb_adaptive_frame_field_flag           = h->sps.mb_aff && !info->field_pic_flag;
+    info->constrained_intra_pred_flag            = h->pps.constrained_intra_pred;
+    info->weighted_pred_flag                     = h->pps.weighted_pred;
+    info->weighted_bipred_idc                    = h->pps.weighted_bipred_idc;
+    info->frame_mbs_only_flag                    = h->sps.frame_mbs_only_flag;
+    info->transform_8x8_mode_flag                = h->pps.transform_8x8_mode;
+    info->chroma_qp_index_offset                 = h->pps.chroma_qp_index_offset[0];
+    info->second_chroma_qp_index_offset          = h->pps.chroma_qp_index_offset[1];
+    info->pic_init_qp_minus26                    = h->pps.init_qp - 26;
+    info->num_ref_idx_l0_active_minus1           = h->pps.ref_count[0] - 1;
+    info->num_ref_idx_l1_active_minus1           = h->pps.ref_count[1] - 1;
+    info->log2_max_frame_num_minus4              = h->sps.log2_max_frame_num - 4;
+    info->pic_order_cnt_type                     = h->sps.poc_type;
+    info->log2_max_pic_order_cnt_lsb_minus4      = h->sps.poc_type ? 0 : h->sps.log2_max_poc_lsb - 4;
+    info->delta_pic_order_always_zero_flag       = h->sps.delta_pic_order_always_zero_flag;
+    info->direct_8x8_inference_flag              = h->sps.direct_8x8_inference_flag;
+    info->entropy_coding_mode_flag               = h->pps.cabac;
+    info->pic_order_present_flag                 = h->pps.pic_order_present;
+    info->deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
+    info->redundant_pic_cnt_present_flag         = h->pps.redundant_pic_cnt_present;
+
+    memcpy(info->scaling_lists_4x4, h->pps.scaling_matrix4,
+           sizeof(info->scaling_lists_4x4));
+    memcpy(info->scaling_lists_8x8[0], h->pps.scaling_matrix8[0],
+           sizeof(info->scaling_lists_8x8[0]));
+    memcpy(info->scaling_lists_8x8[1], h->pps.scaling_matrix8[3],
+           sizeof(info->scaling_lists_8x8[1]));
+
+    vdpau_h264_set_reference_frames(avctx);
+
+    return ff_vdpau_common_start_frame(pic, buffer, size);
+}
+
+static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
+
+static int vdpau_h264_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t *buffer, uint32_t size)
+{
+    H264Context *h = avctx->priv_data;
+    Picture *pic   = h->cur_pic_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    int val;
+
+    val = ff_vdpau_add_buffer(pic, start_code_prefix, 3);
+    if (val)
+        return val;
+
+    val = ff_vdpau_add_buffer(pic, buffer, size);
+    if (val)
+        return val;
+
+    pic_ctx->info.h264.slice_count++;
+    return 0;
+}
+
+static int vdpau_h264_end_frame(AVCodecContext *avctx)
+{
+    AVVDPAUContext *hwctx = avctx->hwaccel_context;
+    H264Context *h = avctx->priv_data;
+    Picture *pic   = h->cur_pic_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpVideoSurface surf = ff_vdpau_get_surface_id(pic);
+
+    hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info,
+                  pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);
+
+    ff_h264_draw_horiz_band(h, 0, h->avctx->height);
+    av_freep(&pic_ctx->bitstream_buffers);
+
+    return 0;
+}
+
+AVHWAccel ff_h264_vdpau_hwaccel = {
+    .name           = "h264_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H264,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_h264_start_frame,
+    .end_frame      = vdpau_h264_end_frame,
+    .decode_slice   = vdpau_h264_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
+};
diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
index 673fd33..50c4f5e 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -25,22 +25,54 @@
 #define AVCODEC_VDPAU_INTERNAL_H
 
 #include <stdint.h>
+#include <vdpau/vdpau.h>
+
+#include "avcodec.h"
 #include "mpegvideo.h"
+#include "version.h"
+
+/** Extract VdpVideoSurface from a Picture */
+static inline uintptr_t ff_vdpau_get_surface_id(Picture *pic)
+{
+    return (uintptr_t)pic->f.data[3];
+}
+
+#if !FF_API_BUFS_VDPAU
+union AVVDPAUPictureInfo {
+    VdpPictureInfoH264        h264;
+    VdpPictureInfoMPEG1Or2    mpeg;
+    VdpPictureInfoVC1          vc1;
+    VdpPictureInfoMPEG4Part2 mpeg4;
+};
+#else
+#include "vdpau.h"
+#endif
 
-void ff_vdpau_add_data_chunk(MpegEncContext *s, const uint8_t *buf,
-                             int buf_size);
+struct vdpau_picture_context {
+    /**
+     * VDPAU picture information.
+     */
+    union AVVDPAUPictureInfo info;
 
-void ff_vdpau_mpeg_picture_complete(MpegEncContext *s, const uint8_t *buf,
-                                    int buf_size, int slice_count);
+    /**
+     * Allocated size of the bitstream_buffers table.
+     */
+    int bitstream_buffers_allocated;
 
-void ff_vdpau_h264_picture_start(MpegEncContext *s);
-void ff_vdpau_h264_set_reference_frames(MpegEncContext *s);
-void ff_vdpau_h264_picture_complete(MpegEncContext *s);
+    /**
+     * Useful bitstream buffers in the bitstream buffers table.
+     */
+    int bitstream_buffers_used;
 
-void ff_vdpau_vc1_decode_picture(MpegEncContext *s, const uint8_t *buf,
-                                 int buf_size);
+   /**
+     * Table of bitstream buffers.
+     */
+    VdpBitstreamBuffer *bitstream_buffers;
+};
 
-void ff_vdpau_mpeg4_decode_picture(MpegEncContext *s, const uint8_t *buf,
-                                   int buf_size);
+int ff_vdpau_common_start_frame(Picture *pic,
+                                const uint8_t *buffer, uint32_t size);
+int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx);
+int ff_vdpau_add_buffer(Picture *pic, const uint8_t *buf, uint32_t buf_size);
 
 #endif /* AVCODEC_VDPAU_INTERNAL_H */
diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c
new file mode 100644
index 0000000..426d580
--- /dev/null
+++ b/libavcodec/vdpau_mpeg12.c
@@ -0,0 +1,121 @@
+/*
+ * MPEG-1/2 HW decode acceleration through VDPAU
+ *
+ * Copyright (c) 2008 NVIDIA
+ * Copyright (c) 2013 Rémi Denis-Courmont
+ *
+ * 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int vdpau_mpeg_start_frame(AVCodecContext *avctx,
+                                  const uint8_t *buffer, uint32_t size)
+{
+    MpegEncContext * const s = avctx->priv_data;
+    Picture *pic             = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpPictureInfoMPEG1Or2 *info = &pic_ctx->info.mpeg;
+    VdpVideoSurface ref;
+    int i;
+
+    /* fill VdpPictureInfoMPEG1Or2 struct */
+    info->forward_reference  = VDP_INVALID_HANDLE;
+    info->backward_reference = VDP_INVALID_HANDLE;
+
+    switch (s->pict_type) {
+    case AV_PICTURE_TYPE_B:
+        ref = ff_vdpau_get_surface_id(&s->next_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->backward_reference = ref;
+        /* fall through to forward prediction */
+    case AV_PICTURE_TYPE_P:
+        ref = ff_vdpau_get_surface_id(&s->last_picture);
+        info->forward_reference  = ref;
+    }
+
+    info->slice_count                = 0;
+    info->picture_structure          = s->picture_structure;
+    info->picture_coding_type        = s->pict_type;
+    info->intra_dc_precision         = s->intra_dc_precision;
+    info->frame_pred_frame_dct       = s->frame_pred_frame_dct;
+    info->concealment_motion_vectors = s->concealment_motion_vectors;
+    info->intra_vlc_format           = s->intra_vlc_format;
+    info->alternate_scan             = s->alternate_scan;
+    info->q_scale_type               = s->q_scale_type;
+    info->top_field_first            = s->top_field_first;
+    // Both for MPEG-1 only, zero for MPEG-2:
+    info->full_pel_forward_vector    = s->full_pel[0];
+    info->full_pel_backward_vector   = s->full_pel[1];
+    // For MPEG-1 fill both horizontal & vertical:
+    info->f_code[0][0]               = s->mpeg_f_code[0][0];
+    info->f_code[0][1]               = s->mpeg_f_code[0][1];
+    info->f_code[1][0]               = s->mpeg_f_code[1][0];
+    info->f_code[1][1]               = s->mpeg_f_code[1][1];
+    for (i = 0; i < 64; ++i) {
+        info->intra_quantizer_matrix[i]     = s->intra_matrix[i];
+        info->non_intra_quantizer_matrix[i] = s->inter_matrix[i];
+    }
+
+    return ff_vdpau_common_start_frame(pic, buffer, size);
+}
+
+static int vdpau_mpeg_decode_slice(AVCodecContext *avctx,
+                                   const uint8_t *buffer, uint32_t size)
+{
+    MpegEncContext * const s = avctx->priv_data;
+    Picture *pic             = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    int val;
+
+    val = ff_vdpau_add_buffer(pic, buffer, size);
+    if (val < 0)
+        return val;
+
+    pic_ctx->info.mpeg.slice_count++;
+    return 0;
+}
+
+#if CONFIG_MPEG1_VDPAU_HWACCEL
+AVHWAccel ff_mpeg1_vdpau_hwaccel = {
+    .name           = "mpeg1_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG1VIDEO,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_mpeg_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_mpeg_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
+};
+#endif
+
+#if CONFIG_MPEG2_VDPAU_HWACCEL
+AVHWAccel ff_mpeg2_vdpau_hwaccel = {
+    .name           = "mpeg2_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG2VIDEO,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_mpeg_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_mpeg_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
+};
+#endif
diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c
new file mode 100644
index 0000000..17205fe
--- /dev/null
+++ b/libavcodec/vdpau_mpeg4.c
@@ -0,0 +1,115 @@
+/*
+ * MPEG-4 Part 2 / H.263 decode acceleration through VDPAU
+ *
+ * Copyright (c) 2008 NVIDIA
+ * Copyright (c) 2013 Rémi Denis-Courmont
+ *
+ * This file is part of 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "mpeg4video.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int vdpau_mpeg4_start_frame(AVCodecContext *avctx,
+                                   const uint8_t *buffer, uint32_t size)
+{
+    Mpeg4DecContext *ctx = avctx->priv_data;
+    MpegEncContext * const s = &ctx->m;
+    Picture *pic             = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpPictureInfoMPEG4Part2 *info = &pic_ctx->info.mpeg4;
+    VdpVideoSurface ref;
+    int i;
+
+    /* fill VdpPictureInfoMPEG4Part2 struct */
+    info->forward_reference  = VDP_INVALID_HANDLE;
+    info->backward_reference = VDP_INVALID_HANDLE;
+    info->vop_coding_type    = 0;
+
+    switch (s->pict_type) {
+    case AV_PICTURE_TYPE_B:
+        ref = ff_vdpau_get_surface_id(&s->next_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->backward_reference = ref;
+        info->vop_coding_type    = 2;
+        /* fall-through */
+    case AV_PICTURE_TYPE_P:
+        ref = ff_vdpau_get_surface_id(&s->last_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->forward_reference  = ref;
+    }
+
+    info->trd[0]                            = s->pp_time;
+    info->trb[0]                            = s->pb_time;
+    info->trd[1]                            = s->pp_field_time >> 1;
+    info->trb[1]                            = s->pb_field_time >> 1;
+    info->vop_time_increment_resolution     = s->avctx->time_base.den;
+    info->vop_fcode_forward                 = s->f_code;
+    info->vop_fcode_backward                = s->b_code;
+    info->resync_marker_disable             = !ctx->resync_marker;
+    info->interlaced                        = !s->progressive_sequence;
+    info->quant_type                        = s->mpeg_quant;
+    info->quarter_sample                    = s->quarter_sample;
+    info->short_video_header                = avctx->codec->id == AV_CODEC_ID_H263;
+    info->rounding_control                  = s->no_rounding;
+    info->alternate_vertical_scan_flag      = s->alternate_scan;
+    info->top_field_first                   = s->top_field_first;
+    for (i = 0; i < 64; ++i) {
+        info->intra_quantizer_matrix[i]     = s->intra_matrix[i];
+        info->non_intra_quantizer_matrix[i] = s->inter_matrix[i];
+    }
+
+    ff_vdpau_common_start_frame(pic, buffer, size);
+    return ff_vdpau_add_buffer(pic, buffer, size);
+}
+
+static int vdpau_mpeg4_decode_slice(av_unused AVCodecContext *avctx,
+                                    av_unused const uint8_t *buffer,
+                                    av_unused uint32_t size)
+{
+     return 0;
+}
+
+#if CONFIG_H263_VDPAU_HWACCEL
+AVHWAccel ff_h263_vdpau_hwaccel = {
+    .name           = "h263_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H263,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_mpeg4_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_mpeg4_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
+};
+#endif
+
+#if CONFIG_MPEG4_VDPAU_HWACCEL
+AVHWAccel ff_mpeg4_vdpau_hwaccel = {
+    .name           = "mpeg4_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG4,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_mpeg4_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_mpeg4_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
+};
+#endif
diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c
new file mode 100644
index 0000000..b401352
--- /dev/null
+++ b/libavcodec/vdpau_vc1.c
@@ -0,0 +1,134 @@
+/*
+ * VC-1 decode acceleration through VDPAU
+ *
+ * Copyright (c) 2008 NVIDIA
+ * Copyright (c) 2013 Rémi Denis-Courmont
+ *
+ * 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "vc1.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int vdpau_vc1_start_frame(AVCodecContext *avctx,
+                                 const uint8_t *buffer, uint32_t size)
+{
+    VC1Context * const v  = avctx->priv_data;
+    MpegEncContext * const s = &v->s;
+    Picture *pic          = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    VdpPictureInfoVC1 *info = &pic_ctx->info.vc1;
+    VdpVideoSurface ref;
+
+    /*  fill LvPictureInfoVC1 struct */
+    info->forward_reference  = VDP_INVALID_HANDLE;
+    info->backward_reference = VDP_INVALID_HANDLE;
+
+    switch (s->pict_type) {
+    case AV_PICTURE_TYPE_B:
+        ref = ff_vdpau_get_surface_id(&s->next_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->backward_reference = ref;
+        /* fall-through */
+    case AV_PICTURE_TYPE_P:
+        ref = ff_vdpau_get_surface_id(&s->last_picture);
+        assert(ref != VDP_INVALID_HANDLE);
+        info->forward_reference  = ref;
+    }
+
+    info->slice_count       = 0;
+    if (v->bi_type)
+        info->picture_type  = 4;
+    else
+        info->picture_type  = s->pict_type - 1 + s->pict_type / 3;
+
+    info->frame_coding_mode = v->fcm ? (v->fcm + 1) : 0;
+    info->postprocflag      = v->postprocflag;
+    info->pulldown          = v->broadcast;
+    info->interlace         = v->interlace;
+    info->tfcntrflag        = v->tfcntrflag;
+    info->finterpflag       = v->finterpflag;
+    info->psf               = v->psf;
+    info->dquant            = v->dquant;
+    info->panscan_flag      = v->panscanflag;
+    info->refdist_flag      = v->refdist_flag;
+    info->quantizer         = v->quantizer_mode;
+    info->extended_mv       = v->extended_mv;
+    info->extended_dmv      = v->extended_dmv;
+    info->overlap           = v->overlap;
+    info->vstransform       = v->vstransform;
+    info->loopfilter        = v->s.loop_filter;
+    info->fastuvmc          = v->fastuvmc;
+    info->range_mapy_flag   = v->range_mapy_flag;
+    info->range_mapy        = v->range_mapy;
+    info->range_mapuv_flag  = v->range_mapuv_flag;
+    info->range_mapuv       = v->range_mapuv;
+    /* Specific to simple/main profile only */
+    info->multires          = v->multires;
+    info->syncmarker        = v->resync_marker;
+    info->rangered          = v->rangered | (v->rangeredfrm << 1);
+    info->maxbframes        = v->s.max_b_frames;
+    info->deblockEnable     = v->postprocflag & 1;
+    info->pquant            = v->pq;
+
+    return ff_vdpau_common_start_frame(pic, buffer, size);
+}
+
+static int vdpau_vc1_decode_slice(AVCodecContext *avctx,
+                                  const uint8_t *buffer, uint32_t size)
+{
+    VC1Context * const v  = avctx->priv_data;
+    MpegEncContext * const s = &v->s;
+    Picture *pic          = s->current_picture_ptr;
+    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+    int val;
+
+    val = ff_vdpau_add_buffer(pic, buffer, size);
+    if (val < 0)
+        return val;
+
+    pic_ctx->info.vc1.slice_count++;
+    return 0;
+}
+
+#if CONFIG_WMV3_VDPAU_HWACCEL
+AVHWAccel ff_wmv3_vdpau_hwaccel = {
+    .name           = "wm3_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_WMV3,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_vc1_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_vc1_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
+};
+#endif
+
+AVHWAccel ff_vc1_vdpau_hwaccel = {
+    .name           = "vc1_vdpau",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VC1,
+    .pix_fmt        = AV_PIX_FMT_VDPAU,
+    .start_frame    = vdpau_vc1_start_frame,
+    .end_frame      = ff_vdpau_mpeg_end_frame,
+    .decode_slice   = vdpau_vc1_decode_slice,
+    .priv_data_size = sizeof(struct vdpau_picture_context),
+};
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 348ce99..c5a777b 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -26,8 +26,8 @@
  * Libavcodec version macros.
  */
 
-#define LIBAVCODEC_VERSION_MAJOR 54
-#define LIBAVCODEC_VERSION_MINOR 35
+#define LIBAVCODEC_VERSION_MAJOR 55
+#define LIBAVCODEC_VERSION_MINOR 29
 #define LIBAVCODEC_VERSION_MICRO  0
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -47,49 +47,76 @@
  */
 
 #ifndef FF_API_REQUEST_CHANNELS
-#define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 55)
+#define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_OLD_DECODE_AUDIO
-#define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_DEINTERLACE
+#define FF_API_DEINTERLACE       (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_OLD_ENCODE_AUDIO
-#define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_DESTRUCT_PACKET
+#define FF_API_DESTRUCT_PACKET   (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_OLD_ENCODE_VIDEO
-#define FF_API_OLD_ENCODE_VIDEO (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_GET_BUFFER
+#define FF_API_GET_BUFFER        (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_MPV_GLOBAL_OPTS
-#define FF_API_MPV_GLOBAL_OPTS  (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_MISSING_SAMPLE
+#define FF_API_MISSING_SAMPLE    (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_COLOR_TABLE_ID
-#define FF_API_COLOR_TABLE_ID   (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_LOWRES
+#define FF_API_LOWRES            (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_INTER_THRESHOLD
-#define FF_API_INTER_THRESHOLD  (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_CAP_VDPAU
+#define FF_API_CAP_VDPAU         (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_SUB_ID
-#define FF_API_SUB_ID           (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_BUFS_VDPAU
+#define FF_API_BUFS_VDPAU        (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_DSP_MASK
-#define FF_API_DSP_MASK         (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_VOXWARE
+#define FF_API_VOXWARE           (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_FIND_BEST_PIX_FMT
-#define FF_API_FIND_BEST_PIX_FMT (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_SET_DIMENSIONS
+#define FF_API_SET_DIMENSIONS    (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_CODEC_ID
-#define FF_API_CODEC_ID          (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_DEBUG_MV
+#define FF_API_DEBUG_MV          (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_VDA_ASYNC
-#define FF_API_VDA_ASYNC         (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_AC_VLC
+#define FF_API_AC_VLC            (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_AVCODEC_RESAMPLE
-#define FF_API_AVCODEC_RESAMPLE  (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_OLD_MSMPEG4
+#define FF_API_OLD_MSMPEG4       (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_LIBMPEG2
-#define FF_API_LIBMPEG2          (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_ASPECT_EXTENDED
+#define FF_API_ASPECT_EXTENDED   (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
-#ifndef FF_API_MMI
-#define FF_API_MMI               (LIBAVCODEC_VERSION_MAJOR < 55)
+#ifndef FF_API_THREAD_OPAQUE
+#define FF_API_THREAD_OPAQUE     (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_CODEC_PKT
+#define FF_API_CODEC_PKT         (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_ARCH_ALPHA
+#define FF_API_ARCH_ALPHA        (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_XVMC
+#define FF_API_XVMC              (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_ERROR_RATE
+#define FF_API_ERROR_RATE        (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_QSCALE_TYPE
+#define FF_API_QSCALE_TYPE       (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_MB_TYPE
+#define FF_API_MB_TYPE           (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_MAX_BFRAMES
+#define FF_API_MAX_BFRAMES       (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_FAST_MALLOC
+#define FF_API_FAST_MALLOC       (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
+#ifndef FF_API_NEG_LINESIZES
+#define FF_API_NEG_LINESIZES     (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
 
 #endif /* AVCODEC_VERSION_H */
diff --git a/libavcodec/videodsp.c b/libavcodec/videodsp.c
index d14b0a1..a6a1d37 100644
--- a/libavcodec/videodsp.c
+++ b/libavcodec/videodsp.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "videodsp.h"
 
@@ -33,7 +34,7 @@ static void just_return(uint8_t *buf, ptrdiff_t stride, int h)
 {
 }
 
-void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
+av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
 {
     ctx->prefetch = just_return;
     if (bpc <= 8) {
diff --git a/libavcodec/videodsp.h b/libavcodec/videodsp.h
index 7d78593..2211c5d 100644
--- a/libavcodec/videodsp.h
+++ b/libavcodec/videodsp.h
@@ -36,8 +36,10 @@ typedef struct VideoDSPContext {
      *
      * @param buf destination buffer
      * @param src source buffer
-     * @param linesize number of bytes between 2 vertically adjacent samples
-     *                 in both the source and destination buffers
+     * @param buf_linesize number of bytes between 2 vertically adjacent
+     *                     samples in the destination buffer
+     * @param src_linesize number of bytes between 2 vertically adjacent
+     *                     samples in both the source buffer
      * @param block_w width of block
      * @param block_h height of block
      * @param src_x x coordinate of the top left sample of the block in the
@@ -48,15 +50,17 @@ typedef struct VideoDSPContext {
      * @param h height of the source buffer
      */
     void (*emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
-                             ptrdiff_t linesize, int block_w, int block_h,
+                             ptrdiff_t buf_linesize,
+                             ptrdiff_t src_linesize,
+                             int block_w, int block_h,
                              int src_x, int src_y, int w, int h);
 
     /**
      * Prefetch memory into cache (if supported by hardware).
      *
-     * @buf pointer to buffer to prefetch memory from
-     * @stride distance between two lines of buf (in bytes)
-     * @h number of lines to prefetch
+     * @param buf    pointer to buffer to prefetch memory from
+     * @param stride distance between two lines of buf (in bytes)
+     * @param h      number of lines to prefetch
      */
     void (*prefetch)(uint8_t *buf, ptrdiff_t stride, int h);
 } VideoDSPContext;
diff --git a/libavcodec/videodsp_template.c b/libavcodec/videodsp_template.c
index 5d5a32f..98313ac 100644
--- a/libavcodec/videodsp_template.c
+++ b/libavcodec/videodsp_template.c
@@ -22,7 +22,8 @@
 #include "bit_depth_template.c"
 
 static void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
-                                      ptrdiff_t linesize,
+                                      ptrdiff_t buf_linesize,
+                                      ptrdiff_t src_linesize,
                                       int block_w, int block_h,
                                       int src_x, int src_y, int w, int h)
 {
@@ -30,10 +31,10 @@ static void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
     int start_y, start_x, end_y, end_x;
 
     if (src_y >= h) {
-        src  += (h - 1 - src_y) * linesize;
+        src  += (h - 1 - src_y) * src_linesize;
         src_y = h - 1;
     } else if (src_y <= -block_h) {
-        src  += (1 - block_h - src_y) * linesize;
+        src  += (1 - block_h - src_y) * src_linesize;
         src_y = 1 - block_h;
     }
     if (src_x >= w) {
@@ -52,30 +53,30 @@ static void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
     assert(start_x < end_x && block_w);
 
     w    = end_x - start_x;
-    src += start_y * linesize + start_x * sizeof(pixel);
+    src += start_y * src_linesize + start_x * sizeof(pixel);
     buf += start_x * sizeof(pixel);
 
     // top
     for (y = 0; y < start_y; y++) {
         memcpy(buf, src, w * sizeof(pixel));
-        buf += linesize;
+        buf += buf_linesize;
     }
 
     // copy existing part
     for (; y < end_y; y++) {
         memcpy(buf, src, w * sizeof(pixel));
-        src += linesize;
-        buf += linesize;
+        src += src_linesize;
+        buf += buf_linesize;
     }
 
     // bottom
-    src -= linesize;
+    src -= src_linesize;
     for (; y < block_h; y++) {
         memcpy(buf, src, w * sizeof(pixel));
-        buf += linesize;
+        buf += buf_linesize;
     }
 
-    buf -= block_h * linesize + start_x * sizeof(pixel);
+    buf -= block_h * buf_linesize + start_x * sizeof(pixel);
     while (block_h--) {
         pixel *bufp = (pixel *) buf;
 
@@ -88,6 +89,6 @@ static void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src,
         for (x = end_x; x < block_w; x++) {
             bufp[x] = bufp[end_x - 1];
         }
-        buf += linesize;
+        buf += buf_linesize;
     }
 }
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index d4ac6f7..a1e39c0 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -60,8 +60,7 @@
 typedef struct VmdVideoContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
-    AVFrame prev_frame;
+    AVFrame *prev_frame;
 
     const unsigned char *buf;
     int size;
@@ -153,9 +152,10 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
     int src_count, int src_size, int dest_len)
 {
     unsigned char *pd;
-    int i, l;
+    int i, l, used = 0;
     unsigned char *dest_end = dest + dest_len;
     GetByteContext gb;
+    uint16_t run_val;
 
     bytestream2_init(&gb, src, src_size);
     pd = dest;
@@ -163,10 +163,9 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
         if (bytestream2_get_bytes_left(&gb) < 1)
             return 0;
         *pd++ = bytestream2_get_byteu(&gb);
+        used++;
     }
 
-    src_count >>= 1;
-    i = 0;
     do {
         if (bytestream2_get_bytes_left(&gb) < 1)
             break;
@@ -178,21 +177,22 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
             bytestream2_get_buffer(&gb, pd, l);
             pd += l;
         } else {
-            if (pd + i > dest_end || bytestream2_get_bytes_left(&gb) < 2)
+            if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < 2)
                 return bytestream2_tell(&gb);
+            run_val = bytestream2_get_ne16(&gb);
             for (i = 0; i < l; i++) {
-                *pd++ = bytestream2_get_byteu(&gb);
-                *pd++ = bytestream2_get_byteu(&gb);
+                AV_WN16(pd, run_val);
+                pd += 2;
             }
-            bytestream2_skip(&gb, 2);
+            l *= 2;
         }
-        i += l;
-    } while (i < src_count);
+        used += l;
+    } while (used < src_count);
 
     return bytestream2_tell(&gb);
 }
 
-static int vmd_decode(VmdVideoContext *s)
+static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
 {
     int i;
     unsigned int *palette32;
@@ -243,12 +243,12 @@ static int vmd_decode(VmdVideoContext *s)
 
     /* if only a certain region will be updated, copy the entire previous
      * frame before the decode */
-    if (s->prev_frame.data[0] &&
+    if (s->prev_frame->data[0] &&
         (frame_x || frame_y || (frame_width != s->avctx->width) ||
         (frame_height != s->avctx->height))) {
 
-        memcpy(s->frame.data[0], s->prev_frame.data[0],
-            s->avctx->height * s->frame.linesize[0]);
+        memcpy(frame->data[0], s->prev_frame->data[0],
+            s->avctx->height * frame->linesize[0]);
     }
 
     /* check if there is a new palette */
@@ -278,14 +278,19 @@ static int vmd_decode(VmdVideoContext *s)
         return AVERROR_INVALIDDATA;
     meth = bytestream2_get_byteu(&gb);
     if (meth & 0x80) {
+        if (!s->unpack_buffer_size) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Trying to unpack LZ-compressed frame with no LZ buffer\n");
+            return AVERROR_INVALIDDATA;
+        }
         lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
                   s->unpack_buffer, s->unpack_buffer_size);
         meth &= 0x7F;
         bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
     }
 
-    dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
-    pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
+    dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
+    pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x];
     switch (meth) {
     case 1:
         for (i = 0; i < frame_height; i++) {
@@ -301,7 +306,7 @@ static int vmd_decode(VmdVideoContext *s)
                     ofs += len;
                 } else {
                     /* interframe pixel copy */
-                    if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+                    if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
                         return AVERROR_INVALIDDATA;
                     memcpy(&dp[ofs], &pp[ofs], len + 1);
                     ofs += len + 1;
@@ -313,16 +318,16 @@ static int vmd_decode(VmdVideoContext *s)
                        ofs, frame_width);
                 return AVERROR_INVALIDDATA;
             }
-            dp += s->frame.linesize[0];
-            pp += s->prev_frame.linesize[0];
+            dp += frame->linesize[0];
+            pp += s->prev_frame->linesize[0];
         }
         break;
 
     case 2:
         for (i = 0; i < frame_height; i++) {
             bytestream2_get_buffer(&gb, dp, frame_width);
-            dp += s->frame.linesize[0];
-            pp += s->prev_frame.linesize[0];
+            dp += frame->linesize[0];
+            pp += s->prev_frame->linesize[0];
         }
         break;
 
@@ -333,16 +338,21 @@ static int vmd_decode(VmdVideoContext *s)
                 len = bytestream2_get_byte(&gb);
                 if (len & 0x80) {
                     len = (len & 0x7F) + 1;
-                    if (bytestream2_get_byte(&gb) == 0xFF)
+                    if (bytestream2_peek_byte(&gb) == 0xFF) {
+                        int slen = len;
+                        bytestream2_get_byte(&gb);
                         len = rle_unpack(gb.buffer, &dp[ofs],
                                          len, bytestream2_get_bytes_left(&gb),
                                          frame_width - ofs);
-                    else
+                        ofs += slen;
+                        bytestream2_skip(&gb, len);
+                    } else {
                         bytestream2_get_buffer(&gb, &dp[ofs], len);
-                    bytestream2_skip(&gb, len);
+                        ofs += len;
+                    }
                 } else {
                     /* interframe pixel copy */
-                    if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
+                    if (ofs + len + 1 > frame_width || !s->prev_frame->data[0])
                         return AVERROR_INVALIDDATA;
                     memcpy(&dp[ofs], &pp[ofs], len + 1);
                     ofs += len + 1;
@@ -354,14 +364,24 @@ static int vmd_decode(VmdVideoContext *s)
                        ofs, frame_width);
                 return AVERROR_INVALIDDATA;
             }
-            dp += s->frame.linesize[0];
-            pp += s->prev_frame.linesize[0];
+            dp += frame->linesize[0];
+            pp += s->prev_frame->linesize[0];
         }
         break;
     }
     return 0;
 }
 
+static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
+{
+    VmdVideoContext *s = avctx->priv_data;
+
+    av_frame_free(&s->prev_frame);
+    av_free(s->unpack_buffer);
+
+    return 0;
+}
+
 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
 {
     VmdVideoContext *s = avctx->priv_data;
@@ -384,9 +404,11 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
     vmd_header = (unsigned char *)avctx->extradata;
 
     s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
-    s->unpack_buffer = av_malloc(s->unpack_buffer_size);
-    if (!s->unpack_buffer)
-        return -1;
+    if (s->unpack_buffer_size) {
+        s->unpack_buffer = av_malloc(s->unpack_buffer_size);
+        if (!s->unpack_buffer)
+            return AVERROR(ENOMEM);
+    }
 
     /* load up the initial palette */
     raw_palette = &vmd_header[28];
@@ -398,6 +420,12 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
         palette32[i] = (r << 16) | (g << 8) | (b);
     }
 
+    s->prev_frame = av_frame_alloc();
+    if (!s->prev_frame) {
+        vmdvideo_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
@@ -408,6 +436,8 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     VmdVideoContext *s = avctx->priv_data;
+    AVFrame *frame = data;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
@@ -415,40 +445,28 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
     if (buf_size < 16)
         return AVERROR_INVALIDDATA;
 
-    s->frame.reference = 1;
-    if (ff_get_buffer(avctx, &s->frame)) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    vmd_decode(s);
+    if ((ret = vmd_decode(s, frame)) < 0)
+        return ret;
 
     /* make the palette available on the way out */
-    memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
+    memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
 
     /* shuffle frames */
-    FFSWAP(AVFrame, s->frame, s->prev_frame);
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(s->prev_frame);
+    if ((ret = av_frame_ref(s->prev_frame, frame)) < 0)
+        return ret;
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->prev_frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
 }
 
-static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
-{
-    VmdVideoContext *s = avctx->priv_data;
-
-    if (s->prev_frame.data[0])
-        avctx->release_buffer(avctx, &s->prev_frame);
-    av_free(s->unpack_buffer);
-
-    return 0;
-}
-
 
 /*
  * Audio Decoder
@@ -459,7 +477,6 @@ static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
 #define BLOCK_TYPE_SILENCE  3
 
 typedef struct VmdAudioContext {
-    AVFrame frame;
     int out_bps;
     int chunk_size;
 } VmdAudioContext;
@@ -504,9 +521,6 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
 
     s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
            "block align = %d, sample rate = %d\n",
            avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
@@ -547,6 +561,7 @@ static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end;
     int buf_size = avpkt->size;
@@ -594,18 +609,19 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
     buf_size     = audio_chunks * s->chunk_size;
 
     /* get output buffer */
-    s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
+                        avctx->channels;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    output_samples_u8  = s->frame.data[0];
-    output_samples_s16 = (int16_t *)s->frame.data[0];
+    output_samples_u8  =            frame->data[0];
+    output_samples_s16 = (int16_t *)frame->data[0];
 
     /* decode silent chunks */
     if (silent_chunks > 0) {
         int silent_size = FFMIN(avctx->block_align * silent_chunks,
-                                s->frame.nb_samples * avctx->channels);
+                                frame->nb_samples * avctx->channels);
         if (s->out_bps == 2) {
             memset(output_samples_s16, 0x00, silent_size * 2);
             output_samples_s16 += silent_size;
@@ -631,8 +647,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
@@ -644,6 +659,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
 
 AVCodec ff_vmdvideo_decoder = {
     .name           = "vmdvideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VMDVIDEO,
     .priv_data_size = sizeof(VmdVideoContext),
@@ -651,16 +667,15 @@ AVCodec ff_vmdvideo_decoder = {
     .close          = vmdvideo_decode_end,
     .decode         = vmdvideo_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
 };
 
 AVCodec ff_vmdaudio_decoder = {
     .name           = "vmdaudio",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_VMDAUDIO,
     .priv_data_size = sizeof(VmdAudioContext),
     .init           = vmdaudio_decode_init,
     .decode         = vmdaudio_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
 };
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index 4071cdf..16984fb 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -31,6 +31,8 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
+#include "bytestream.h"
 
 enum EncTypes {
     MAGIC_WMVd = 0x574D5664,
@@ -55,62 +57,73 @@ enum HexTile_Flags {
  */
 typedef struct VmncContext {
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *pic;
 
     int bpp;
     int bpp2;
     int bigendian;
     uint8_t pal[768];
     int width, height;
+    GetByteContext gb;
 
     /* cursor data */
     int cur_w, cur_h;
     int cur_x, cur_y;
     int cur_hx, cur_hy;
-    uint8_t* curbits, *curmask;
-    uint8_t* screendta;
+    uint8_t *curbits, *curmask;
+    uint8_t *screendta;
 } VmncContext;
 
 /* read pixel value from stream */
-static av_always_inline int vmnc_get_pixel(const uint8_t* buf, int bpp, int be) {
-    switch(bpp * 2 + be) {
+static av_always_inline int vmnc_get_pixel(GetByteContext *gb, int bpp, int be)
+{
+    switch (bpp * 2 + be) {
     case 2:
-    case 3: return *buf;
-    case 4: return AV_RL16(buf);
-    case 5: return AV_RB16(buf);
-    case 8: return AV_RL32(buf);
-    case 9: return AV_RB32(buf);
+    case 3:
+        return bytestream2_get_byte(gb);
+    case 4:
+        return bytestream2_get_le16(gb);
+    case 5:
+        return bytestream2_get_be16(gb);
+    case 8:
+        return bytestream2_get_le32(gb);
+    case 9:
+        return bytestream2_get_be32(gb);
     default: return 0;
     }
 }
 
-static void load_cursor(VmncContext *c, const uint8_t *src)
+static void load_cursor(VmncContext *c)
 {
     int i, j, p;
-    const int bpp = c->bpp2;
-    uint8_t  *dst8  = c->curbits;
-    uint16_t *dst16 = (uint16_t*)c->curbits;
-    uint32_t *dst32 = (uint32_t*)c->curbits;
-
-    for(j = 0; j < c->cur_h; j++) {
-        for(i = 0; i < c->cur_w; i++) {
-            p = vmnc_get_pixel(src, bpp, c->bigendian);
-            src += bpp;
-            if(bpp == 1) *dst8++ = p;
-            if(bpp == 2) *dst16++ = p;
-            if(bpp == 4) *dst32++ = p;
+    const int bpp   = c->bpp2;
+    uint8_t *dst8   =             c->curbits;
+    uint16_t *dst16 = (uint16_t *)c->curbits;
+    uint32_t *dst32 = (uint32_t *)c->curbits;
+
+    for (j = 0; j < c->cur_h; j++) {
+        for (i = 0; i < c->cur_w; i++) {
+            p = vmnc_get_pixel(&c->gb, bpp, c->bigendian);
+            if (bpp == 1)
+                *dst8++ = p;
+            if (bpp == 2)
+                *dst16++ = p;
+            if (bpp == 4)
+                *dst32++ = p;
         }
     }
-    dst8 = c->curmask;
+    dst8  =            c->curmask;
     dst16 = (uint16_t*)c->curmask;
     dst32 = (uint32_t*)c->curmask;
-    for(j = 0; j < c->cur_h; j++) {
-        for(i = 0; i < c->cur_w; i++) {
-            p = vmnc_get_pixel(src, bpp, c->bigendian);
-            src += bpp;
-            if(bpp == 1) *dst8++ = p;
-            if(bpp == 2) *dst16++ = p;
-            if(bpp == 4) *dst32++ = p;
+    for (j = 0; j < c->cur_h; j++) {
+        for (i = 0; i < c->cur_w; i++) {
+            p = vmnc_get_pixel(&c->gb, bpp, c->bigendian);
+            if (bpp == 1)
+                *dst8++ = p;
+            if (bpp == 2)
+                *dst16++ = p;
+            if (bpp == 4)
+                *dst32++ = p;
         }
     }
 }
@@ -120,96 +133,100 @@ static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy)
     int i, j;
     int w, h, x, y;
     w = c->cur_w;
-    if(c->width < c->cur_x + c->cur_w) w = c->width - c->cur_x;
+    if (c->width < c->cur_x + c->cur_w)
+        w = c->width - c->cur_x;
     h = c->cur_h;
-    if(c->height < c->cur_y + c->cur_h) h = c->height - c->cur_y;
+    if (c->height < c->cur_y + c->cur_h)
+        h = c->height - c->cur_y;
     x = c->cur_x;
     y = c->cur_y;
-    if(x < 0) {
+    if (x < 0) {
         w += x;
-        x = 0;
+        x  = 0;
     }
-    if(y < 0) {
+    if (y < 0) {
         h += y;
-        y = 0;
+        y  = 0;
     }
 
-    if((w < 1) || (h < 1)) return;
+    if ((w < 1) || (h < 1))
+        return;
     dst += x * c->bpp2 + y * stride;
 
-    if(c->bpp2 == 1) {
-        uint8_t* cd = c->curbits, *msk = c->curmask;
-        for(j = 0; j < h; j++) {
-            for(i = 0; i < w; i++)
+    if (c->bpp2 == 1) {
+        uint8_t *cd = c->curbits, *msk = c->curmask;
+        for (j = 0; j < h; j++) {
+            for (i = 0; i < w; i++)
                 dst[i] = (dst[i] & cd[i]) ^ msk[i];
             msk += c->cur_w;
-            cd += c->cur_w;
+            cd  += c->cur_w;
             dst += stride;
         }
-    } else if(c->bpp2 == 2) {
-        uint16_t* cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask;
-        uint16_t* dst2;
-        for(j = 0; j < h; j++) {
+    } else if (c->bpp2 == 2) {
+        uint16_t *cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask;
+        uint16_t *dst2;
+        for (j = 0; j < h; j++) {
             dst2 = (uint16_t*)dst;
-            for(i = 0; i < w; i++)
+            for (i = 0; i < w; i++)
                 dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
             msk += c->cur_w;
-            cd += c->cur_w;
+            cd  += c->cur_w;
             dst += stride;
         }
-    } else if(c->bpp2 == 4) {
-        uint32_t* cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask;
-        uint32_t* dst2;
-        for(j = 0; j < h; j++) {
+    } else if (c->bpp2 == 4) {
+        uint32_t *cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask;
+        uint32_t *dst2;
+        for (j = 0; j < h; j++) {
             dst2 = (uint32_t*)dst;
-            for(i = 0; i < w; i++)
+            for (i = 0; i < w; i++)
                 dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
             msk += c->cur_w;
-            cd += c->cur_w;
+            cd  += c->cur_w;
             dst += stride;
         }
     }
 }
 
 /* fill rectangle with given color */
-static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy, int w, int h, int color, int bpp, int stride)
+static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy,
+                                        int w, int h, int color,
+                                        int bpp, int stride)
 {
     int i, j;
     dst += dx * bpp + dy * stride;
-    if(bpp == 1){
-        for(j = 0; j < h; j++) {
+    if (bpp == 1) {
+        for (j = 0; j < h; j++) {
             memset(dst, color, w);
             dst += stride;
         }
-    }else if(bpp == 2){
-        uint16_t* dst2;
-        for(j = 0; j < h; j++) {
+    } else if (bpp == 2) {
+        uint16_t *dst2;
+        for (j = 0; j < h; j++) {
             dst2 = (uint16_t*)dst;
-            for(i = 0; i < w; i++) {
+            for (i = 0; i < w; i++)
                 *dst2++ = color;
-            }
             dst += stride;
         }
-    }else if(bpp == 4){
-        uint32_t* dst2;
-        for(j = 0; j < h; j++) {
+    } else if (bpp == 4) {
+        uint32_t *dst2;
+        for (j = 0; j < h; j++) {
             dst2 = (uint32_t*)dst;
-            for(i = 0; i < w; i++) {
+            for (i = 0; i < w; i++)
                 dst2[i] = color;
-            }
             dst += stride;
         }
     }
 }
 
-static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t* src, int bpp, int be, int stride)
+static av_always_inline void paint_raw(uint8_t *dst, int w, int h,
+                                       GetByteContext *gb, int bpp,
+                                       int be, int stride)
 {
     int i, j, p;
-    for(j = 0; j < h; j++) {
-        for(i = 0; i < w; i++) {
-            p = vmnc_get_pixel(src, bpp, be);
-            src += bpp;
-            switch(bpp){
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < w; i++) {
+            p = vmnc_get_pixel(gb, bpp, be);
+            switch (bpp) {
             case 1:
                 dst[i] = p;
                 break;
@@ -225,255 +242,282 @@ static av_always_inline void paint_raw(uint8_t *dst, int w, int h, const uint8_t
     }
 }
 
-static int decode_hextile(VmncContext *c, uint8_t* dst, const uint8_t* src, int ssize, int w, int h, int stride)
+static int decode_hextile(VmncContext *c, uint8_t* dst, GetByteContext *gb,
+                          int w, int h, int stride)
 {
     int i, j, k;
     int bg = 0, fg = 0, rects, color, flags, xy, wh;
     const int bpp = c->bpp2;
     uint8_t *dst2;
     int bw = 16, bh = 16;
-    const uint8_t *ssrc=src;
 
-    for(j = 0; j < h; j += 16) {
+    for (j = 0; j < h; j += 16) {
         dst2 = dst;
-        bw = 16;
-        if(j + 16 > h) bh = h - j;
-        for(i = 0; i < w; i += 16, dst2 += 16 * bpp) {
-            if(src - ssrc >= ssize) {
+        bw   = 16;
+        if (j + 16 > h)
+            bh = h - j;
+        for (i = 0; i < w; i += 16, dst2 += 16 * bpp) {
+            if (bytestream2_get_bytes_left(gb) <= 0) {
                 av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
-            if(i + 16 > w) bw = w - i;
-            flags = *src++;
-            if(flags & HT_RAW) {
-                if(src - ssrc > ssize - bw * bh * bpp) {
+            if (i + 16 > w)
+                bw = w - i;
+            flags = bytestream2_get_byte(gb);
+            if (flags & HT_RAW) {
+                if (bytestream2_get_bytes_left(gb) < bw * bh * bpp) {
                     av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
-                paint_raw(dst2, bw, bh, src, bpp, c->bigendian, stride);
-                src += bw * bh * bpp;
+                paint_raw(dst2, bw, bh, gb, bpp, c->bigendian, stride);
             } else {
-                if(flags & HT_BKG) {
-                    bg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
-                }
-                if(flags & HT_FG) {
-                    fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
-                }
+                if (flags & HT_BKG)
+                    bg = vmnc_get_pixel(gb, bpp, c->bigendian);
+                if (flags & HT_FG)
+                    fg = vmnc_get_pixel(gb, bpp, c->bigendian);
                 rects = 0;
-                if(flags & HT_SUB)
-                    rects = *src++;
+                if (flags & HT_SUB)
+                    rects = bytestream2_get_byte(gb);
                 color = !!(flags & HT_CLR);
 
                 paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);
 
-                if(src - ssrc > ssize - rects * (color * bpp + 2)) {
+                if (bytestream2_get_bytes_left(gb) < rects * (color * bpp + 2)) {
                     av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
-                for(k = 0; k < rects; k++) {
-                    if(color) {
-                        fg = vmnc_get_pixel(src, bpp, c->bigendian); src += bpp;
-                    }
-                    xy = *src++;
-                    wh = *src++;
-                    paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride);
+                for (k = 0; k < rects; k++) {
+                    if (color)
+                        fg = vmnc_get_pixel(gb, bpp, c->bigendian);
+                    xy = bytestream2_get_byte(gb);
+                    wh = bytestream2_get_byte(gb);
+                    paint_rect(dst2, xy >> 4, xy & 0xF,
+                               (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride);
                 }
             }
         }
         dst += stride * 16;
     }
-    return src - ssrc;
+    return 0;
+}
+
+static void reset_buffers(VmncContext *c)
+{
+    av_freep(&c->curbits);
+    av_freep(&c->curmask);
+    av_freep(&c->screendta);
+    c->cur_w = c->cur_h = 0;
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    int buf_size       = avpkt->size;
     VmncContext * const c = avctx->priv_data;
+    GetByteContext *gb = &c->gb;
     uint8_t *outptr;
-    const uint8_t *src = buf;
-    int dx, dy, w, h, depth, enc, chunks, res, size_left;
+    int dx, dy, w, h, depth, enc, chunks, res, size_left, ret;
 
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if(avctx->reget_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    c->pic.key_frame = 0;
-    c->pic.pict_type = AV_PICTURE_TYPE_P;
+    bytestream2_init(gb, buf, buf_size);
+
+    c->pic->key_frame = 0;
+    c->pic->pict_type = AV_PICTURE_TYPE_P;
 
-    //restore screen after cursor
-    if(c->screendta) {
+    // restore screen after cursor
+    if (c->screendta) {
         int i;
         w = c->cur_w;
-        if(c->width < c->cur_x + w) w = c->width - c->cur_x;
+        if (c->width < c->cur_x + w)
+            w = c->width - c->cur_x;
         h = c->cur_h;
-        if(c->height < c->cur_y + h) h = c->height - c->cur_y;
+        if (c->height < c->cur_y + h)
+            h = c->height - c->cur_y;
         dx = c->cur_x;
-        if(dx < 0) {
+        if (dx < 0) {
             w += dx;
             dx = 0;
         }
         dy = c->cur_y;
-        if(dy < 0) {
+        if (dy < 0) {
             h += dy;
             dy = 0;
         }
-        if((w > 0) && (h > 0)) {
-            outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
-            for(i = 0; i < h; i++) {
-                memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2);
-                outptr += c->pic.linesize[0];
+        if ((w > 0) && (h > 0)) {
+            outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
+            for (i = 0; i < h; i++) {
+                memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2,
+                       w * c->bpp2);
+                outptr += c->pic->linesize[0];
             }
         }
     }
-    src += 2;
-    chunks = AV_RB16(src); src += 2;
-    while(chunks--) {
-        dx = AV_RB16(src); src += 2;
-        dy = AV_RB16(src); src += 2;
-        w  = AV_RB16(src); src += 2;
-        h  = AV_RB16(src); src += 2;
-        enc = AV_RB32(src); src += 4;
-        outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
-        size_left = buf_size - (src - buf);
-        switch(enc) {
+    bytestream2_skip(gb, 2);
+    chunks = bytestream2_get_be16(gb);
+    while (chunks--) {
+        dx  = bytestream2_get_be16(gb);
+        dy  = bytestream2_get_be16(gb);
+        w   = bytestream2_get_be16(gb);
+        h   = bytestream2_get_be16(gb);
+        enc = bytestream2_get_be32(gb);
+        outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
+        size_left = bytestream2_get_bytes_left(gb);
+        switch (enc) {
         case MAGIC_WMVd: // cursor
-            if(size_left < 2 + w * h * c->bpp2 * 2) {
-                av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", 2 + w * h * c->bpp2 * 2, size_left);
-                return -1;
+            if (size_left < 2 + w * h * c->bpp2 * 2) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Premature end of data! (need %i got %i)\n",
+                       2 + w * h * c->bpp2 * 2, size_left);
+                return AVERROR_INVALIDDATA;
             }
-            src += 2;
-            c->cur_w = w;
-            c->cur_h = h;
+            bytestream2_skip(gb, 2);
+            c->cur_w  = w;
+            c->cur_h  = h;
             c->cur_hx = dx;
             c->cur_hy = dy;
-            if((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) {
-                av_log(avctx, AV_LOG_ERROR, "Cursor hot spot is not in image: %ix%i of %ix%i cursor size\n", c->cur_hx, c->cur_hy, c->cur_w, c->cur_h);
+            if ((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Cursor hot spot is not in image: "
+                       "%ix%i of %ix%i cursor size\n",
+                       c->cur_hx, c->cur_hy, c->cur_w, c->cur_h);
                 c->cur_hx = c->cur_hy = 0;
             }
-            c->curbits = av_realloc(c->curbits, c->cur_w * c->cur_h * c->bpp2);
-            c->curmask = av_realloc(c->curmask, c->cur_w * c->cur_h * c->bpp2);
-            c->screendta = av_realloc(c->screendta, c->cur_w * c->cur_h * c->bpp2);
-            load_cursor(c, src);
-            src += w * h * c->bpp2 * 2;
+            if (c->cur_w * c->cur_h >= INT_MAX / c->bpp2) {
+                reset_buffers(c);
+                return AVERROR(EINVAL);
+            } else {
+                int screen_size = c->cur_w * c->cur_h * c->bpp2;
+                if ((ret = av_reallocp(&c->curbits, screen_size)) < 0 ||
+                    (ret = av_reallocp(&c->curmask, screen_size)) < 0 ||
+                    (ret = av_reallocp(&c->screendta, screen_size)) < 0) {
+                    reset_buffers(c);
+                    return ret;
+                }
+            }
+            load_cursor(c);
             break;
         case MAGIC_WMVe: // unknown
-            src += 2;
+            bytestream2_skip(gb, 2);
             break;
         case MAGIC_WMVf: // update cursor position
             c->cur_x = dx - c->cur_hx;
             c->cur_y = dy - c->cur_hy;
             break;
         case MAGIC_WMVg: // unknown
-            src += 10;
+            bytestream2_skip(gb, 10);
             break;
         case MAGIC_WMVh: // unknown
-            src += 4;
+            bytestream2_skip(gb, 4);
             break;
         case MAGIC_WMVi: // ServerInitialization struct
-            c->pic.key_frame = 1;
-            c->pic.pict_type = AV_PICTURE_TYPE_I;
-            depth = *src++;
-            if(depth != c->bpp) {
-                av_log(avctx, AV_LOG_INFO, "Depth mismatch. Container %i bpp, Frame data: %i bpp\n", c->bpp, depth);
+            c->pic->key_frame = 1;
+            c->pic->pict_type = AV_PICTURE_TYPE_I;
+            depth = bytestream2_get_byte(gb);
+            if (depth != c->bpp) {
+                av_log(avctx, AV_LOG_INFO,
+                       "Depth mismatch. Container %i bpp, "
+                       "Frame data: %i bpp\n",
+                       c->bpp, depth);
             }
-            src++;
-            c->bigendian = *src++;
-            if(c->bigendian & (~1)) {
-                av_log(avctx, AV_LOG_INFO, "Invalid header: bigendian flag = %i\n", c->bigendian);
-                return -1;
+            bytestream2_skip(gb, 1);
+            c->bigendian = bytestream2_get_byte(gb);
+            if (c->bigendian & (~1)) {
+                av_log(avctx, AV_LOG_INFO,
+                       "Invalid header: bigendian flag = %i\n", c->bigendian);
+                return AVERROR_INVALIDDATA;
             }
             //skip the rest of pixel format data
-            src += 13;
+            bytestream2_skip(gb, 13);
             break;
         case MAGIC_WMVj: // unknown
-            src += 2;
+            bytestream2_skip(gb, 2);
             break;
         case 0x00000000: // raw rectangle data
-            if((dx + w > c->width) || (dy + h > c->height)) {
-                av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
-                return -1;
+            if ((dx + w > c->width) || (dy + h > c->height)) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Incorrect frame size: %ix%i+%ix%i of %ix%i\n",
+                       w, h, dx, dy, c->width, c->height);
+                return AVERROR_INVALIDDATA;
             }
-            if(size_left < w * h * c->bpp2) {
-                av_log(avctx, AV_LOG_ERROR, "Premature end of data! (need %i got %i)\n", w * h * c->bpp2, size_left);
-                return -1;
+            if (size_left < w * h * c->bpp2) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Premature end of data! (need %i got %i)\n",
+                       w * h * c->bpp2, size_left);
+                return AVERROR_INVALIDDATA;
             }
-            paint_raw(outptr, w, h, src, c->bpp2, c->bigendian, c->pic.linesize[0]);
-            src += w * h * c->bpp2;
+            paint_raw(outptr, w, h, gb, c->bpp2, c->bigendian,
+                      c->pic->linesize[0]);
             break;
         case 0x00000005: // HexTile encoded rectangle
-            if((dx + w > c->width) || (dy + h > c->height)) {
-                av_log(avctx, AV_LOG_ERROR, "Incorrect frame size: %ix%i+%ix%i of %ix%i\n", w, h, dx, dy, c->width, c->height);
-                return -1;
+            if ((dx + w > c->width) || (dy + h > c->height)) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Incorrect frame size: %ix%i+%ix%i of %ix%i\n",
+                       w, h, dx, dy, c->width, c->height);
+                return AVERROR_INVALIDDATA;
             }
-            res = decode_hextile(c, outptr, src, size_left, w, h, c->pic.linesize[0]);
-            if(res < 0)
-                return -1;
-            src += res;
+            res = decode_hextile(c, outptr, gb, w, h, c->pic->linesize[0]);
+            if (res < 0)
+                return res;
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc);
             chunks = 0; // leave chunks decoding loop
         }
     }
-    if(c->screendta){
+    if (c->screendta) {
         int i;
-        //save screen data before painting cursor
+        // save screen data before painting cursor
         w = c->cur_w;
-        if(c->width < c->cur_x + w) w = c->width - c->cur_x;
+        if (c->width < c->cur_x + w)
+            w = c->width - c->cur_x;
         h = c->cur_h;
-        if(c->height < c->cur_y + h) h = c->height - c->cur_y;
+        if (c->height < c->cur_y + h)
+            h = c->height - c->cur_y;
         dx = c->cur_x;
-        if(dx < 0) {
+        if (dx < 0) {
             w += dx;
             dx = 0;
         }
         dy = c->cur_y;
-        if(dy < 0) {
+        if (dy < 0) {
             h += dy;
             dy = 0;
         }
-        if((w > 0) && (h > 0)) {
-            outptr = c->pic.data[0] + dx * c->bpp2 + dy * c->pic.linesize[0];
-            for(i = 0; i < h; i++) {
-                memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2);
-                outptr += c->pic.linesize[0];
+        if ((w > 0) && (h > 0)) {
+            outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
+            for (i = 0; i < h; i++) {
+                memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr,
+                       w * c->bpp2);
+                outptr += c->pic->linesize[0];
             }
-            outptr = c->pic.data[0];
-            put_cursor(outptr, c->pic.linesize[0], c, c->cur_x, c->cur_y);
+            outptr = c->pic->data[0];
+            put_cursor(outptr, c->pic->linesize[0], c, c->cur_x, c->cur_y);
         }
     }
-    *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
+    *got_frame = 1;
+    if ((ret = av_frame_ref(data, c->pic)) < 0)
+        return ret;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
 }
 
-
-
-/*
- *
- * Init VMnc decoder
- *
- */
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     VmncContext * const c = avctx->priv_data;
 
-    c->avctx = avctx;
-
-    c->width = avctx->width;
+    c->avctx  = avctx;
+    c->width  = avctx->width;
     c->height = avctx->height;
+    c->bpp    = avctx->bits_per_coded_sample;
+    c->bpp2   = c->bpp / 8;
 
-    c->bpp = avctx->bits_per_coded_sample;
-    c->bpp2 = c->bpp/8;
-
-    switch(c->bpp){
+    switch (c->bpp) {
     case 8:
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
         break;
@@ -488,22 +532,18 @@ static av_cold int decode_init(AVCodecContext *avctx)
         return AVERROR_INVALIDDATA;
     }
 
+    c->pic = av_frame_alloc();
+    if (!c->pic)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
-
-
-/*
- *
- * Uninit VMnc decoder
- *
- */
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     VmncContext * const c = avctx->priv_data;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_free(&c->pic);
 
     av_free(c->curbits);
     av_free(c->curmask);
@@ -513,6 +553,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
 AVCodec ff_vmnc_decoder = {
     .name           = "vmnc",
+    .long_name      = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VMNC,
     .priv_data_size = sizeof(VmncContext),
@@ -520,5 +561,4 @@ AVCodec ff_vmnc_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"),
 };
diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c
index 78a2467..66fa21b 100644
--- a/libavcodec/vorbis.c
+++ b/libavcodec/vorbis.c
@@ -117,7 +117,7 @@ int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num)
     return 0;
 }
 
-int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext,
+int ff_vorbis_ready_floor1_list(AVCodecContext *avctx,
                                 vorbis_floor1_entry *list, int values)
 {
     int i;
@@ -143,7 +143,7 @@ int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext,
         int j;
         for (j = i + 1; j < values; j++) {
             if (list[i].x == list[j].x) {
-                av_log(avccontext, AV_LOG_ERROR,
+                av_log(avctx, AV_LOG_ERROR,
                        "Duplicate value found in floor 1 X coordinates\n");
                 return AVERROR_INVALIDDATA;
             }
diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h
index 6b72f6a..5ae20ac 100644
--- a/libavcodec/vorbis.h
+++ b/libavcodec/vorbis.h
@@ -36,14 +36,14 @@ typedef struct vorbis_floor1_entry {
     uint16_t high;
 } vorbis_floor1_entry;
 
-int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext,
+int ff_vorbis_ready_floor1_list(AVCodecContext *avctx,
                                 vorbis_floor1_entry *list, int values);
 unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n)
 int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num);
 void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values,
                                   uint16_t *y_list, int *flag,
                                   int multiplier, float * out, int samples);
-void ff_vorbis_inverse_coupling(float *mag, float *ang, int blocksize);
+void ff_vorbis_inverse_coupling(float *mag, float *ang, intptr_t blocksize);
 
 #define ilog(i) av_log2(2*(i))
 
diff --git a/libavcodec/vorbis_data.c b/libavcodec/vorbis_data.c
index 03c3d6b..bafb77b 100644
--- a/libavcodec/vorbis_data.c
+++ b/libavcodec/vorbis_data.c
@@ -20,7 +20,6 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/mem.h"
-#include "dsputil.h"
 #include "vorbis.h"
 
 const uint8_t ff_vorbis_channel_layout_offsets[8][8] = {
diff --git a/libavcodec/vorbis_parser.c b/libavcodec/vorbis_parser.c
index c6d300d..c413135 100644
--- a/libavcodec/vorbis_parser.c
+++ b/libavcodec/vorbis_parser.c
@@ -141,8 +141,9 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
      * we may need to approach this the long way and parse the whole Setup
      * header, but I hope very much that it never comes to that. */
     if (last_mode_count > 2) {
-        av_log_ask_for_sample(avctx, "%d modes found. This is either a false "
-                              "positive or a sample from an unknown encoder.\n",
+        avpriv_request_sample(avctx,
+                              "%d modes (either a false positive or a "
+                              "sample from an unknown encoder)",
                               last_mode_count);
     }
     /* We're limiting the mode count to 63 so that we know that the previous
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index 884cd5b..d7fec98 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -29,12 +29,12 @@
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
 #include "get_bits.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "fmtconvert.h"
 #include "internal.h"
 
 #include "vorbis.h"
+#include "vorbisdsp.h"
 #include "xiph.h"
 
 #define V_NB_BITS 8
@@ -42,9 +42,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;
@@ -122,10 +119,9 @@ typedef struct {
 } vorbis_mode;
 
 typedef struct vorbis_context_s {
-    AVCodecContext *avccontext;
-    AVFrame frame;
+    AVCodecContext *avctx;
     GetBitContext gb;
-    DSPContext dsp;
+    VorbisDSPContext dsp;
     AVFloatDSPContext fdsp;
     FmtConvertContext fmt_conv;
 
@@ -163,7 +159,7 @@ typedef struct vorbis_context_s {
 static const char idx_err_str[] = "Index value %d out of range (0 - %d) for %s at %s:%i\n";
 #define VALIDATE_INDEX(idx, limit) \
     if (idx >= limit) {\
-        av_log(vc->avccontext, AV_LOG_ERROR,\
+        av_log(vc->avctx, AV_LOG_ERROR,\
                idx_err_str,\
                (int)(idx), (int)(limit - 1), #idx, __FILE__, __LINE__);\
         return AVERROR_INVALIDDATA;\
@@ -234,10 +230,10 @@ static void vorbis_free(vorbis_context *vc)
 static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
 {
     unsigned cb;
-    uint8_t  *tmp_vlc_bits;
-    uint32_t *tmp_vlc_codes;
+    uint8_t  *tmp_vlc_bits  = NULL;
+    uint32_t *tmp_vlc_codes = NULL;
     GetBitContext *gb = &vc->gb;
-    uint16_t *codebook_multiplicands;
+    uint16_t *codebook_multiplicands = NULL;
     int ret = 0;
 
     vc->codebook_count = get_bits(gb, 8) + 1;
@@ -248,6 +244,11 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
     tmp_vlc_bits  = av_mallocz(V_MAX_VLCS * sizeof(*tmp_vlc_bits));
     tmp_vlc_codes = av_mallocz(V_MAX_VLCS * sizeof(*tmp_vlc_codes));
     codebook_multiplicands = av_malloc(V_MAX_VLCS * sizeof(*codebook_multiplicands));
+    if (!vc->codebooks ||
+        !tmp_vlc_bits || !tmp_vlc_codes || !codebook_multiplicands) {
+        ret = AVERROR(ENOMEM);
+        goto error;
+    }
 
     for (cb = 0; cb < vc->codebook_count; ++cb) {
         vorbis_codebook *codebook_setup = &vc->codebooks[cb];
@@ -256,7 +257,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
         av_dlog(NULL, " %u. Codebook\n", cb);
 
         if (get_bits(gb, 24) != 0x564342) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
+            av_log(vc->avctx, AV_LOG_ERROR,
                    " %u. Codebook setup data corrupt.\n", cb);
             ret = AVERROR_INVALIDDATA;
             goto error;
@@ -264,7 +265,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
 
         codebook_setup->dimensions=get_bits(gb, 16);
         if (codebook_setup->dimensions > 16 || codebook_setup->dimensions == 0) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
+            av_log(vc->avctx, AV_LOG_ERROR,
                    " %u. Codebook's dimension is invalid (%d).\n",
                    cb, codebook_setup->dimensions);
             ret = AVERROR_INVALIDDATA;
@@ -272,7 +273,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
         }
         entries = get_bits(gb, 24);
         if (entries > V_MAX_VLCS) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
+            av_log(vc->avctx, AV_LOG_ERROR,
                    " %u. Codebook has too many entries (%u).\n",
                    cb, entries);
             ret = AVERROR_INVALIDDATA;
@@ -332,7 +333,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
                 current_entry+=number;
             }
             if (current_entry>used_entries) {
-                av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n");
+                av_log(vc->avctx, AV_LOG_ERROR, " More codelengths than codes in codebook. \n");
                 ret = AVERROR_INVALIDDATA;
                 goto error;
             }
@@ -379,7 +380,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
                     float last = 0.0;
                     unsigned lookup_offset = i;
 
-                    av_dlog(vc->avccontext, "Lookup offset %u ,", i);
+                    av_dlog(vc->avctx, "Lookup offset %u ,", i);
 
                     for (k = 0; k < dim; ++k) {
                         unsigned multiplicand_offset = lookup_offset % codebook_lookup_values;
@@ -390,30 +391,30 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
                     }
                     tmp_vlc_bits[j] = tmp_vlc_bits[i];
 
-                    av_dlog(vc->avccontext, "real lookup offset %u, vector: ", j);
+                    av_dlog(vc->avctx, "real lookup offset %u, vector: ", j);
                     for (k = 0; k < dim; ++k)
-                        av_dlog(vc->avccontext, " %f ",
+                        av_dlog(vc->avctx, " %f ",
                                 codebook_setup->codevectors[j * dim + k]);
-                    av_dlog(vc->avccontext, "\n");
+                    av_dlog(vc->avctx, "\n");
 
                     ++j;
                 }
             }
             if (j != used_entries) {
-                av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n");
+                av_log(vc->avctx, AV_LOG_ERROR, "Bug in codevector vector building code. \n");
                 ret = AVERROR_INVALIDDATA;
                 goto error;
             }
             entries = used_entries;
         } else if (codebook_setup->lookup_type >= 2) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Codebook lookup type not supported. \n");
             ret = AVERROR_INVALIDDATA;
             goto error;
         }
 
 // Initialize VLC table
         if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) {
-            av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n");
             ret = AVERROR_INVALIDDATA;
             goto error;
         }
@@ -434,7 +435,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc)
                             sizeof(*tmp_vlc_bits), tmp_vlc_codes,
                             sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes),
                             INIT_VLC_LE))) {
-            av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, " Error generating vlc tables. \n");
             goto error;
         }
     }
@@ -466,7 +467,7 @@ static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc)
                 vorbis_time_count, vorbis_tdtransform);
 
         if (vorbis_tdtransform) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n");
             return AVERROR_INVALIDDATA;
         }
     }
@@ -477,17 +478,19 @@ static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc)
 
 static int vorbis_floor0_decode(vorbis_context *vc,
                                 vorbis_floor_data *vfu, float *vec);
-static void create_map(vorbis_context *vc, unsigned floor_number);
+static int create_map(vorbis_context *vc, unsigned floor_number);
 static int vorbis_floor1_decode(vorbis_context *vc,
                                 vorbis_floor_data *vfu, float *vec);
 static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
 {
     GetBitContext *gb = &vc->gb;
-    int i,j,k;
+    int i, j, k, ret;
 
     vc->floor_count = get_bits(gb, 6) + 1;
 
     vc->floors = av_mallocz(vc->floor_count * sizeof(*vc->floors));
+    if (!vc->floors)
+        return AVERROR(ENOMEM);
 
     for (i = 0; i < vc->floor_count; ++i) {
         vorbis_floor *floor_setup = &vc->floors[i];
@@ -551,12 +554,13 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
 
             floor_setup->data.t1.list = av_mallocz(floor_setup->data.t1.x_list_dim *
                                                    sizeof(*floor_setup->data.t1.list));
-
+            if (!floor_setup->data.t1.list)
+                return AVERROR(ENOMEM);
 
             rangebits = get_bits(gb, 4);
             rangemax = (1 << rangebits);
             if (rangemax > vc->blocksize[1] / 2) {
-                av_log(vc->avccontext, AV_LOG_ERROR,
+                av_log(vc->avctx, AV_LOG_ERROR,
                        "Floor value is too large for blocksize: %u (%"PRIu32")\n",
                        rangemax, vc->blocksize[1] / 2);
                 return AVERROR_INVALIDDATA;
@@ -574,7 +578,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
             }
 
 // Precalculate order of x coordinates - needed for decode
-            if (ff_vorbis_ready_floor1_list(vc->avccontext,
+            if (ff_vorbis_ready_floor1_list(vc->avctx,
                                             floor_setup->data.t1.list,
                                             floor_setup->data.t1.x_list_dim)) {
                 return AVERROR_INVALIDDATA;
@@ -586,19 +590,17 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
 
             floor_setup->data.t0.order          = get_bits(gb,  8);
             if (!floor_setup->data.t0.order) {
-                av_log(vc->avccontext, AV_LOG_ERROR,
-                       "Floor 0 order is 0.\n");
+                av_log(vc->avctx, AV_LOG_ERROR, "Floor 0 order is 0.\n");
                 return AVERROR_INVALIDDATA;
             }
             floor_setup->data.t0.rate           = get_bits(gb, 16);
             if (!floor_setup->data.t0.rate) {
-                av_log(vc->avccontext, AV_LOG_ERROR,
-                       "Floor 0 rate is 0.\n");
+                av_log(vc->avctx, AV_LOG_ERROR, "Floor 0 rate is 0.\n");
                 return AVERROR_INVALIDDATA;
             }
             floor_setup->data.t0.bark_map_size  = get_bits(gb, 16);
-            if (floor_setup->data.t0.bark_map_size == 0) {
-                av_log(vc->avccontext, AV_LOG_ERROR,
+            if (!floor_setup->data.t0.bark_map_size) {
+                av_log(vc->avctx, AV_LOG_ERROR,
                        "Floor 0 bark map size is 0.\n");
                 return AVERROR_INVALIDDATA;
             }
@@ -623,7 +625,8 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
                 }
             }
 
-            create_map(vc, i);
+            if ((ret = create_map(vc, i)) < 0)
+                return ret;
 
             /* codebook dim is for padding if codebook dim doesn't *
              * divide order+1 then we need to read more data       */
@@ -654,7 +657,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc)
                 }
             }
         } else {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Invalid floor type!\n");
             return AVERROR_INVALIDDATA;
         }
     }
@@ -670,6 +673,8 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc)
 
     vc->residue_count = get_bits(gb, 6)+1;
     vc->residues      = av_mallocz(vc->residue_count * sizeof(*vc->residues));
+    if (!vc->residues)
+        return AVERROR(ENOMEM);
 
     av_dlog(NULL, " There are %d residues. \n", vc->residue_count);
 
@@ -687,9 +692,9 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc)
         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->avctx->channels : 1) * vc->blocksize[1] / 2 ||
             (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
+            av_log(vc->avctx, AV_LOG_ERROR,
                    "partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n",
                    res_setup->type, res_setup->begin, res_setup->end,
                    res_setup->partition_size, vc->blocksize[1] / 2);
@@ -750,6 +755,8 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
 
     vc->mapping_count = get_bits(gb, 6)+1;
     vc->mappings      = av_mallocz(vc->mapping_count * sizeof(*vc->mappings));
+    if (!vc->mappings)
+        return AVERROR(ENOMEM);
 
     av_dlog(NULL, " There are %d mappings. \n", vc->mapping_count);
 
@@ -757,7 +764,7 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
         vorbis_mapping *mapping_setup = &vc->mappings[i];
 
         if (get_bits(gb, 16)) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n");
             return AVERROR_INVALIDDATA;
         }
         if (get_bits1(gb)) {
@@ -772,6 +779,9 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
                                                        sizeof(*mapping_setup->magnitude));
             mapping_setup->angle          = av_mallocz(mapping_setup->coupling_steps *
                                                        sizeof(*mapping_setup->angle));
+            if (!mapping_setup->angle || !mapping_setup->magnitude)
+                return AVERROR(ENOMEM);
+
             for (j = 0; j < mapping_setup->coupling_steps; ++j) {
                 GET_VALIDATED_INDEX(mapping_setup->magnitude[j], ilog(vc->audio_channels - 1), vc->audio_channels)
                 GET_VALIDATED_INDEX(mapping_setup->angle[j],     ilog(vc->audio_channels - 1), vc->audio_channels)
@@ -784,13 +794,16 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
                 i, mapping_setup->coupling_steps);
 
         if (get_bits(gb, 2)) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "%u. mapping setup data invalid.\n", i);
+            av_log(vc->avctx, AV_LOG_ERROR, "%u. mapping setup data invalid.\n", i);
             return AVERROR_INVALIDDATA; // following spec.
         }
 
         if (mapping_setup->submaps>1) {
             mapping_setup->mux = av_mallocz(vc->audio_channels *
                                             sizeof(*mapping_setup->mux));
+            if (!mapping_setup->mux)
+                return AVERROR(ENOMEM);
+
             for (j = 0; j < vc->audio_channels; ++j)
                 mapping_setup->mux[j] = get_bits(gb, 4);
         }
@@ -810,7 +823,7 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc)
 
 // Process modes part
 
-static void create_map(vorbis_context *vc, unsigned floor_number)
+static int create_map(vorbis_context *vc, unsigned floor_number)
 {
     vorbis_floor *floors = vc->floors;
     vorbis_floor0 *vf;
@@ -822,6 +835,8 @@ static void create_map(vorbis_context *vc, unsigned floor_number)
         n = vc->blocksize[blockflag] / 2;
         floors[floor_number].data.t0.map[blockflag] =
             av_malloc((n + 1) * sizeof(int32_t)); // n + sentinel
+        if (!floors[floor_number].data.t0.map[blockflag])
+            return AVERROR(ENOMEM);
 
         map =  floors[floor_number].data.t0.map[blockflag];
         vf  = &floors[floor_number].data.t0;
@@ -839,6 +854,8 @@ static void create_map(vorbis_context *vc, unsigned floor_number)
     for (idx = 0; idx <= n; ++idx) {
         av_dlog(NULL, "floor0 map: map at pos %d is %d\n", idx, map[idx]);
     }
+
+    return 0;
 }
 
 static int vorbis_parse_setup_hdr_modes(vorbis_context *vc)
@@ -848,6 +865,8 @@ static int vorbis_parse_setup_hdr_modes(vorbis_context *vc)
 
     vc->mode_count = get_bits(gb, 6) + 1;
     vc->modes      = av_mallocz(vc->mode_count * sizeof(*vc->modes));
+    if (!vc->modes)
+        return AVERROR(ENOMEM);
 
     av_dlog(NULL, " There are %d modes.\n", vc->mode_count);
 
@@ -876,36 +895,36 @@ static int vorbis_parse_setup_hdr(vorbis_context *vc)
     if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
         (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
         (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n");
         return AVERROR_INVALIDDATA;
     }
 
     if ((ret = vorbis_parse_setup_hdr_codebooks(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_tdtransforms(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_floors(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_residues(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_mappings(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n");
         return ret;
     }
     if ((ret = vorbis_parse_setup_hdr_modes(vc))) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n");
         return ret;
     }
     if (!get_bits1(gb)) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n");
         return AVERROR_INVALIDDATA; // framing flag bit unset error
     }
 
@@ -922,19 +941,19 @@ static int vorbis_parse_id_hdr(vorbis_context *vc)
     if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') ||
         (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') ||
         (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n");
         return AVERROR_INVALIDDATA;
     }
 
     vc->version        = get_bits_long(gb, 32);    //FIXME check 0
     vc->audio_channels = get_bits(gb, 8);
     if (vc->audio_channels <= 0) {
-        av_log(vc->avccontext, AV_LOG_ERROR, "Invalid number of channels\n");
+        av_log(vc->avctx, AV_LOG_ERROR, "Invalid number of channels\n");
         return AVERROR_INVALIDDATA;
     }
     vc->audio_samplerate = get_bits_long(gb, 32);
     if (vc->audio_samplerate <= 0) {
-        av_log(vc->avccontext, AV_LOG_ERROR, "Invalid samplerate\n");
+        av_log(vc->avctx, AV_LOG_ERROR, "Invalid samplerate\n");
         return AVERROR_INVALIDDATA;
     }
     vc->bitrate_maximum = get_bits_long(gb, 32);
@@ -945,19 +964,22 @@ static int vorbis_parse_id_hdr(vorbis_context *vc)
     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");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");
         return AVERROR_INVALIDDATA;
     }
     vc->win[0] = ff_vorbis_vwin[bl0 - 6];
     vc->win[1] = ff_vorbis_vwin[bl1 - 6];
 
     if ((get_bits1(gb)) == 0) {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n");
         return AVERROR_INVALIDDATA;
     }
 
     vc->channel_residues =  av_malloc((vc->blocksize[1]  / 2) * vc->audio_channels * sizeof(*vc->channel_residues));
     vc->saved            =  av_mallocz((vc->blocksize[1] / 4) * vc->audio_channels * sizeof(*vc->saved));
+    if (!vc->channel_residues || !vc->saved)
+        return AVERROR(ENOMEM);
+
     vc->previous_window  = 0;
 
     ff_mdct_init(&vc->mdct[0], bl0, 1, -1.0);
@@ -978,41 +1000,41 @@ static int vorbis_parse_id_hdr(vorbis_context *vc)
 
 // Process the extradata using the functions above (identification header, setup header)
 
-static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
+static av_cold int vorbis_decode_init(AVCodecContext *avctx)
 {
-    vorbis_context *vc = avccontext->priv_data;
-    uint8_t *headers   = avccontext->extradata;
-    int headers_len    = avccontext->extradata_size;
+    vorbis_context *vc = avctx->priv_data;
+    uint8_t *headers   = avctx->extradata;
+    int headers_len    = avctx->extradata_size;
     uint8_t *header_start[3];
     int header_len[3];
     GetBitContext *gb = &vc->gb;
     int hdr_type, ret;
 
-    vc->avccontext = avccontext;
-    ff_dsputil_init(&vc->dsp, avccontext);
-    avpriv_float_dsp_init(&vc->fdsp, avccontext->flags & CODEC_FLAG_BITEXACT);
-    ff_fmt_convert_init(&vc->fmt_conv, avccontext);
+    vc->avctx = avctx;
+    ff_vorbisdsp_init(&vc->dsp);
+    avpriv_float_dsp_init(&vc->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
+    ff_fmt_convert_init(&vc->fmt_conv, avctx);
 
-    avccontext->sample_fmt = AV_SAMPLE_FMT_FLTP;
+    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     if (!headers_len) {
-        av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n");
+        av_log(avctx, AV_LOG_ERROR, "Extradata missing.\n");
         return AVERROR_INVALIDDATA;
     }
 
     if ((ret = avpriv_split_xiph_headers(headers, headers_len, 30, header_start, header_len)) < 0) {
-        av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");
+        av_log(avctx, AV_LOG_ERROR, "Extradata corrupt.\n");
         return ret;
     }
 
     init_get_bits(gb, header_start[0], header_len[0]*8);
     hdr_type = get_bits(gb, 8);
     if (hdr_type != 1) {
-        av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n");
+        av_log(avctx, AV_LOG_ERROR, "First header is not the id header.\n");
         return AVERROR_INVALIDDATA;
     }
     if ((ret = vorbis_parse_id_hdr(vc))) {
-        av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n");
+        av_log(avctx, AV_LOG_ERROR, "Id header corrupt.\n");
         vorbis_free(vc);
         return ret;
     }
@@ -1020,26 +1042,23 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
     init_get_bits(gb, header_start[2], header_len[2]*8);
     hdr_type = get_bits(gb, 8);
     if (hdr_type != 5) {
-        av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n");
+        av_log(avctx, AV_LOG_ERROR, "Third header is not the setup header.\n");
         vorbis_free(vc);
         return AVERROR_INVALIDDATA;
     }
     if ((ret = vorbis_parse_setup_hdr(vc))) {
-        av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n");
+        av_log(avctx, AV_LOG_ERROR, "Setup header corrupt.\n");
         vorbis_free(vc);
         return ret;
     }
 
     if (vc->audio_channels > 8)
-        avccontext->channel_layout = 0;
+        avctx->channel_layout = 0;
     else
-        avccontext->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1];
+        avctx->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1];
 
-    avccontext->channels    = vc->audio_channels;
-    avccontext->sample_rate = vc->audio_samplerate;
-
-    avcodec_get_frame_defaults(&vc->frame);
-    avccontext->coded_frame = &vc->frame;
+    avctx->channels    = vc->audio_channels;
+    avctx->sample_rate = vc->audio_samplerate;
 
     return 0;
 }
@@ -1067,8 +1086,7 @@ static int vorbis_floor0_decode(vorbis_context *vc,
 
         book_idx = get_bits(&vc->gb, ilog(vf->num_books));
         if (book_idx >= vf->num_books) {
-            av_log(vc->avccontext, AV_LOG_ERROR,
-                    "floor0 dec: booknumber too high!\n");
+            av_log(vc->avctx, AV_LOG_ERROR, "floor0 dec: booknumber too high!\n");
             book_idx =  0;
         }
         av_dlog(NULL, "floor0 dec: booknumber: %u\n", book_idx);
@@ -1281,6 +1299,45 @@ static int vorbis_floor1_decode(vorbis_context *vc,
     return 0;
 }
 
+static av_always_inline int setup_classifs(vorbis_context *vc,
+                                           vorbis_residue *vr,
+                                           uint8_t *do_not_decode,
+                                           unsigned ch_used,
+                                           int partition_count)
+{
+    int p, j, i;
+    unsigned c_p_c         = vc->codebooks[vr->classbook].dimensions;
+    unsigned inverse_class = ff_inverse[vr->classifications];
+    unsigned temp, temp2;
+    for (p = 0, j = 0; j < ch_used; ++j) {
+        if (!do_not_decode[j]) {
+            temp = get_vlc2(&vc->gb, vc->codebooks[vr->classbook].vlc.table,
+                                     vc->codebooks[vr->classbook].nb_bits, 3);
+
+            av_dlog(NULL, "Classword: %u\n", temp);
+
+            if (temp <= 65536) {
+                for (i = partition_count + c_p_c - 1; i >= partition_count; i--) {
+                    temp2 = (((uint64_t)temp) * inverse_class) >> 32;
+
+                    if (i < vr->ptns_to_read)
+                        vr->classifs[p + i] = temp - temp2 * vr->classifications;
+                    temp = temp2;
+                }
+            } else {
+                for (i = partition_count + c_p_c - 1; i >= partition_count; i--) {
+                    temp2 = temp / vr->classifications;
+
+                    if (i < vr->ptns_to_read)
+                        vr->classifs[p + i] = temp - temp2 * vr->classifications;
+                    temp = temp2;
+                }
+            }
+        }
+        p += vr->ptns_to_read;
+    }
+    return 0;
+}
 // Read and decode residue
 
 static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
@@ -1294,10 +1351,10 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
 {
     GetBitContext *gb = &vc->gb;
     unsigned c_p_c        = vc->codebooks[vr->classbook].dimensions;
-    unsigned ptns_to_read = vr->ptns_to_read;
     uint8_t *classifs = vr->classifs;
     unsigned pass, ch_used, i, j, k, l;
     unsigned max_output = (ch - 1) * vlen;
+    int ptns_to_read = vr->ptns_to_read;
 
     if (vr_type == 2) {
         for (j = 1; j < ch; ++j)
@@ -1312,38 +1369,19 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
     }
 
     if (max_output > ch_left * vlen) {
-        av_log(vc->avccontext, AV_LOG_ERROR, "Insufficient output buffer\n");
-        return -1;
+        av_log(vc->avctx, AV_LOG_ERROR, "Insufficient output buffer\n");
+        return AVERROR_INVALIDDATA;
     }
 
     av_dlog(NULL, " residue type 0/1/2 decode begin, ch: %d  cpc %d  \n", ch, c_p_c);
 
     for (pass = 0; pass <= vr->maxpass; ++pass) { // FIXME OPTIMIZE?
-        uint16_t voffset, partition_count, j_times_ptns_to_read;
+        int voffset, partition_count, j_times_ptns_to_read;
 
         voffset = vr->begin;
         for (partition_count = 0; partition_count < ptns_to_read;) {  // SPEC        error
             if (!pass) {
-                unsigned inverse_class = ff_inverse[vr->classifications];
-                for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
-                    if (!do_not_decode[j]) {
-                        unsigned temp = get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table,
-                                                 vc->codebooks[vr->classbook].nb_bits, 3);
-
-                        av_dlog(NULL, "Classword: %u\n", temp);
-
-                        assert(vr->classifications > 1 && temp <= 65536); //needed for inverse[]
-                        for (i = 0; i < c_p_c; ++i) {
-                            unsigned temp2;
-
-                            temp2 = (((uint64_t)temp) * inverse_class) >> 32;
-                            if (partition_count + c_p_c - 1 - i < ptns_to_read)
-                                classifs[j_times_ptns_to_read + partition_count + c_p_c - 1 - i] = temp - temp2 * vr->classifications;
-                            temp = temp2;
-                        }
-                    }
-                    j_times_ptns_to_read += ptns_to_read;
-                }
+                setup_classifs(vc, vr, do_not_decode, ch_used, partition_count);
             }
             for (i = 0; (i < c_p_c) && (partition_count < ptns_to_read); ++i) {
                 for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
@@ -1456,12 +1494,12 @@ static inline int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr,
     else if (vr->type == 0)
         return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, ch_left, 0);
     else {
-        av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n");
+        av_log(vc->avctx, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n");
         return AVERROR_INVALIDDATA;
     }
 }
 
-void ff_vorbis_inverse_coupling(float *mag, float *ang, int blocksize)
+void ff_vorbis_inverse_coupling(float *mag, float *ang, intptr_t blocksize)
 {
     int i;
     for (i = 0;  i < blocksize;  i++) {
@@ -1505,7 +1543,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr)
     unsigned vlen;
 
     if (get_bits1(gb)) {
-        av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
+        av_log(vc->avctx, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n");
         return AVERROR_INVALIDDATA; // packet type not audio
     }
 
@@ -1546,7 +1584,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr)
         ret = floor->decode(vc, &floor->data, floor_ptr[i]);
 
         if (ret < 0) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n");
+            av_log(vc->avctx, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n");
             return AVERROR_INVALIDDATA;
         }
         no_residue[i] = ret;
@@ -1582,8 +1620,8 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr)
         }
         residue = &vc->residues[mapping->submap_residue[i]];
         if (ch_left < ch) {
-            av_log(vc->avccontext, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n");
-            return -1;
+            av_log(vc->avctx, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n");
+            return AVERROR_INVALIDDATA;
         }
         if (ch) {
             ret = vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, vlen, ch_left);
@@ -1631,13 +1669,13 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr)
         const float *win  = vc->win[blockflag & previous_window];
 
         if (blockflag == previous_window) {
-            vc->dsp.vector_fmul_window(ret, saved, buf, win, blocksize / 4);
+            vc->fdsp.vector_fmul_window(ret, saved, buf, win, blocksize / 4);
         } else if (blockflag > previous_window) {
-            vc->dsp.vector_fmul_window(ret, saved, buf, win, bs0 / 4);
+            vc->fdsp.vector_fmul_window(ret, saved, buf, win, bs0 / 4);
             memcpy(ret+bs0/2, buf+bs0/4, ((bs1-bs0)/4) * sizeof(float));
         } else {
             memcpy(ret, saved, ((bs1 - bs0) / 4) * sizeof(float));
-            vc->dsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
+            vc->fdsp.vector_fmul_window(ret + (bs1 - bs0) / 4, saved + (bs1 - bs0) / 4, buf, win, bs0 / 4);
         }
         memcpy(saved, buf + blocksize / 4, blocksize / 4 * sizeof(float));
     }
@@ -1648,12 +1686,13 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr)
 
 // Return the decoded audio packet through the standard api
 
-static int vorbis_decode_frame(AVCodecContext *avccontext, void *data,
+static int vorbis_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    vorbis_context *vc = avccontext->priv_data;
+    vorbis_context *vc = avctx->priv_data;
+    AVFrame *frame     = data;
     GetBitContext *gb = &vc->gb;
     float *channel_ptrs[255];
     int i, len, ret;
@@ -1661,19 +1700,19 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, void *data,
     av_dlog(NULL, "packet length %d \n", buf_size);
 
     /* get output buffer */
-    vc->frame.nb_samples = vc->blocksize[1] / 2;
-    if ((ret = ff_get_buffer(avccontext, &vc->frame)) < 0) {
-        av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n");
+    frame->nb_samples = vc->blocksize[1] / 2;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     if (vc->audio_channels > 8) {
         for (i = 0; i < vc->audio_channels; i++)
-            channel_ptrs[i] = (float *)vc->frame.extended_data[i];
+            channel_ptrs[i] = (float *)frame->extended_data[i];
     } else {
         for (i = 0; i < vc->audio_channels; i++) {
             int ch = ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i];
-            channel_ptrs[ch] = (float *)vc->frame.extended_data[i];
+            channel_ptrs[ch] = (float *)frame->extended_data[i];
         }
     }
 
@@ -1685,33 +1724,33 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, void *data,
     if (!vc->first_frame) {
         vc->first_frame = 1;
         *got_frame_ptr = 0;
+        av_frame_unref(frame);
         return buf_size;
     }
 
     av_dlog(NULL, "parsed %d bytes %d bits, returned %d samples (*ch*bits) \n",
             get_bits_count(gb) / 8, get_bits_count(gb) % 8, len);
 
-    vc->frame.nb_samples = len;
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = vc->frame;
+    frame->nb_samples = len;
+    *got_frame_ptr    = 1;
 
     return buf_size;
 }
 
 // Close decoder
 
-static av_cold int vorbis_decode_close(AVCodecContext *avccontext)
+static av_cold int vorbis_decode_close(AVCodecContext *avctx)
 {
-    vorbis_context *vc = avccontext->priv_data;
+    vorbis_context *vc = avctx->priv_data;
 
     vorbis_free(vc);
 
     return 0;
 }
 
-static av_cold void vorbis_decode_flush(AVCodecContext *avccontext)
+static av_cold void vorbis_decode_flush(AVCodecContext *avctx)
 {
-    vorbis_context *vc = avccontext->priv_data;
+    vorbis_context *vc = avctx->priv_data;
 
     if (vc->saved) {
         memset(vc->saved, 0, (vc->blocksize[1] / 4) * vc->audio_channels *
@@ -1722,6 +1761,7 @@ static av_cold void vorbis_decode_flush(AVCodecContext *avccontext)
 
 AVCodec ff_vorbis_decoder = {
     .name            = "vorbis",
+    .long_name       = NULL_IF_CONFIG_SMALL("Vorbis"),
     .type            = AVMEDIA_TYPE_AUDIO,
     .id              = AV_CODEC_ID_VORBIS,
     .priv_data_size  = sizeof(vorbis_context),
@@ -1730,7 +1770,6 @@ AVCodec ff_vorbis_decoder = {
     .decode          = vorbis_decode_frame,
     .flush           = vorbis_decode_flush,
     .capabilities    = CODEC_CAP_DR1,
-    .long_name       = NULL_IF_CONFIG_SMALL("Vorbis"),
     .channel_layouts = ff_vorbis_channel_layouts,
     .sample_fmts     = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                        AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/vorbisdsp.c b/libavcodec/vorbisdsp.c
new file mode 100644
index 0000000..8e82c10
--- /dev/null
+++ b/libavcodec/vorbisdsp.c
@@ -0,0 +1,34 @@
+/*
+ * 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 "libavutil/attributes.h"
+#include "vorbisdsp.h"
+#include "vorbis.h"
+
+av_cold void ff_vorbisdsp_init(VorbisDSPContext *dsp)
+{
+    dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling;
+
+    if (ARCH_ARM)
+        ff_vorbisdsp_init_arm(dsp);
+    if (ARCH_PPC)
+        ff_vorbisdsp_init_ppc(dsp);
+    if (ARCH_X86)
+        ff_vorbisdsp_init_x86(dsp);
+}
diff --git a/libavcodec/vorbisdsp.h b/libavcodec/vorbisdsp.h
new file mode 100644
index 0000000..32fcfef
--- /dev/null
+++ b/libavcodec/vorbisdsp.h
@@ -0,0 +1,37 @@
+/*
+ * 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_VORBISDSP_H
+#define AVCODEC_VORBISDSP_H
+
+#include <stdint.h>
+
+typedef struct VorbisDSPContext {
+    /* assume len is a multiple of 4, and arrays are 16-byte aligned */
+    void (*vorbis_inverse_coupling)(float *mag, float *ang,
+                                    intptr_t blocksize);
+} VorbisDSPContext;
+
+void ff_vorbisdsp_init(VorbisDSPContext *dsp);
+
+/* for internal use only */
+void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp);
+void ff_vorbisdsp_init_arm(VorbisDSPContext *dsp);
+void ff_vorbisdsp_init_ppc(VorbisDSPContext *dsp);
+
+#endif /* AVCODEC_VORBISDSP_H */
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index 42713f9..f16060e 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -26,7 +26,6 @@
 
 #include <float.h>
 #include "avcodec.h"
-#include "dsputil.h"
 #include "internal.h"
 #include "fft.h"
 #include "vorbis.h"
@@ -190,7 +189,7 @@ static int ready_codebook(vorbis_enc_codebook *cb)
                 cb->pow2[i] += cb->dimensions[i * cb->ndimensions + j] * cb->dimensions[i * cb->ndimensions + j];
                 div *= vals;
             }
-            cb->pow2[i] /= 2.;
+            cb->pow2[i] /= 2.0;
         }
     }
     return 0;
@@ -236,15 +235,15 @@ static int ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc)
 }
 
 static int create_vorbis_context(vorbis_enc_context *venc,
-                                 AVCodecContext *avccontext)
+                                 AVCodecContext *avctx)
 {
     vorbis_enc_floor   *fc;
     vorbis_enc_residue *rc;
     vorbis_enc_mapping *mc;
     int i, book, ret;
 
-    venc->channels    = avccontext->channels;
-    venc->sample_rate = avccontext->sample_rate;
+    venc->channels    = avctx->channels;
+    venc->sample_rate = avctx->sample_rate;
     venc->log2_blocksize[0] = venc->log2_blocksize[1] = 11;
 
     venc->ncodebooks = FF_ARRAY_ELEMS(cvectors);
@@ -340,7 +339,7 @@ static int create_vorbis_context(vorbis_enc_context *venc,
         };
         fc->list[i].x = a[i - 2];
     }
-    if (ff_vorbis_ready_floor1_list(avccontext, fc->list, fc->values))
+    if (ff_vorbis_ready_floor1_list(avctx, fc->list, fc->values))
         return AVERROR_BUG;
 
     venc->nresidues = 1;
@@ -729,7 +728,7 @@ static void floor_fit(vorbis_enc_context *venc, vorbis_enc_floor *fc,
 {
     int range = 255 / fc->multiplier + 1;
     int i;
-    float tot_average = 0.;
+    float tot_average = 0.0;
     float averages[MAX_FLOOR_VALUES];
     for (i = 0; i < fc->values; i++) {
         averages[i] = get_floor_average(fc, coeffs, i);
@@ -882,7 +881,7 @@ static int residue_encode(vorbis_enc_context *venc, vorbis_enc_residue *rc,
     assert(rc->type == 2);
     assert(real_ch == 2);
     for (p = 0; p < partitions; p++) {
-        float max1 = 0., max2 = 0.;
+        float max1 = 0.0, max2 = 0.0;
         int s = rc->begin + p * psize;
         for (k = s; k < s + psize; k += 2) {
             max1 = FFMAX(max1, fabs(coeffs[          k / real_ch]));
@@ -969,7 +968,7 @@ static int apply_window_and_mdct(vorbis_enc_context *venc,
     int i, channel;
     const float * win = venc->win[0];
     int window_len = 1 << (venc->log2_blocksize[0] - 1);
-    float n = (float)(1 << venc->log2_blocksize[0]) / 4.;
+    float n = (float)(1 << venc->log2_blocksize[0]) / 4.0;
     // FIXME use dsp
 
     if (!venc->have_saved && !samples)
@@ -1015,10 +1014,10 @@ static int apply_window_and_mdct(vorbis_enc_context *venc,
 }
 
 
-static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt,
+static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                                const AVFrame *frame, int *got_packet_ptr)
 {
-    vorbis_enc_context *venc = avccontext->priv_data;
+    vorbis_enc_context *venc = avctx->priv_data;
     float **audio = frame ? (float **)frame->extended_data : NULL;
     int samples = frame ? frame->nb_samples : 0;
     vorbis_enc_mode *mode;
@@ -1031,14 +1030,14 @@ static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt,
     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");
+        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
         return ret;
     }
 
     init_put_bits(&pb, avpkt->data, avpkt->size);
 
     if (pb.size_in_bits - put_bits_count(&pb) < 1 + ilog(venc->nmodes - 1)) {
-        av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n");
+        av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
         return AVERROR(EINVAL);
     }
 
@@ -1058,7 +1057,7 @@ static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt,
         uint16_t posts[MAX_FLOOR_VALUES];
         floor_fit(venc, fc, &venc->coeffs[i * samples], posts, samples);
         if (floor_encode(venc, fc, &pb, posts, &venc->floor[i * samples], samples)) {
-            av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n");
+            av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
             return AVERROR(EINVAL);
         }
     }
@@ -1082,17 +1081,17 @@ static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt,
 
     if (residue_encode(venc, &venc->residues[mapping->residue[mapping->mux[0]]],
                        &pb, venc->coeffs, samples, venc->channels)) {
-        av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n");
+        av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
         return AVERROR(EINVAL);
     }
 
     flush_put_bits(&pb);
     avpkt->size = put_bits_count(&pb) >> 3;
 
-    avpkt->duration = ff_samples_to_time_base(avccontext, avccontext->frame_size);
+    avpkt->duration = ff_samples_to_time_base(avctx, avctx->frame_size);
     if (frame)
         if (frame->pts != AV_NOPTS_VALUE)
-            avpkt->pts = ff_samples_to_time_base(avccontext, frame->pts);
+            avpkt->pts = ff_samples_to_time_base(avctx, frame->pts);
     else
         avpkt->pts = venc->next_pts;
     if (avpkt->pts != AV_NOPTS_VALUE)
@@ -1103,9 +1102,9 @@ static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt,
 }
 
 
-static av_cold int vorbis_encode_close(AVCodecContext *avccontext)
+static av_cold int vorbis_encode_close(AVCodecContext *avctx)
 {
-    vorbis_enc_context *venc = avccontext->priv_data;
+    vorbis_enc_context *venc = avctx->priv_data;
     int i;
 
     if (venc->codebooks)
@@ -1157,56 +1156,46 @@ static av_cold int vorbis_encode_close(AVCodecContext *avccontext)
     ff_mdct_end(&venc->mdct[0]);
     ff_mdct_end(&venc->mdct[1]);
 
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avccontext->coded_frame);
-#endif
-    av_freep(&avccontext->extradata);
+    av_freep(&avctx->extradata);
 
     return 0 ;
 }
 
-static av_cold int vorbis_encode_init(AVCodecContext *avccontext)
+static av_cold int vorbis_encode_init(AVCodecContext *avctx)
 {
-    vorbis_enc_context *venc = avccontext->priv_data;
+    vorbis_enc_context *venc = avctx->priv_data;
     int ret;
 
-    if (avccontext->channels != 2) {
-        av_log(avccontext, AV_LOG_ERROR, "Current Libav Vorbis encoder only supports 2 channels.\n");
+    if (avctx->channels != 2) {
+        av_log(avctx, AV_LOG_ERROR, "Current Libav Vorbis encoder only supports 2 channels.\n");
         return -1;
     }
 
-    if ((ret = create_vorbis_context(venc, avccontext)) < 0)
+    if ((ret = create_vorbis_context(venc, avctx)) < 0)
         goto error;
 
-    avccontext->bit_rate = 0;
-    if (avccontext->flags & CODEC_FLAG_QSCALE)
-        venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA;
+    avctx->bit_rate = 0;
+    if (avctx->flags & CODEC_FLAG_QSCALE)
+        venc->quality = avctx->global_quality / (float)FF_QP2LAMBDA;
     else
         venc->quality = 3.0;
     venc->quality *= venc->quality;
 
-    if ((ret = put_main_header(venc, (uint8_t**)&avccontext->extradata)) < 0)
+    if ((ret = put_main_header(venc, (uint8_t**)&avctx->extradata)) < 0)
         goto error;
-    avccontext->extradata_size = ret;
+    avctx->extradata_size = ret;
 
-    avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1);
-
-#if FF_API_OLD_ENCODE_AUDIO
-    avccontext->coded_frame = avcodec_alloc_frame();
-    if (!avccontext->coded_frame) {
-        ret = AVERROR(ENOMEM);
-        goto error;
-    }
-#endif
+    avctx->frame_size = 1 << (venc->log2_blocksize[0] - 1);
 
     return 0;
 error:
-    vorbis_encode_close(avccontext);
+    vorbis_encode_close(avctx);
     return ret;
 }
 
 AVCodec ff_vorbis_encoder = {
     .name           = "vorbis",
+    .long_name      = NULL_IF_CONFIG_SMALL("Vorbis"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_VORBIS,
     .priv_data_size = sizeof(vorbis_enc_context),
@@ -1216,5 +1205,4 @@ AVCodec ff_vorbis_encoder = {
     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Vorbis"),
 };
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 1d68c09..adcecbc 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -38,6 +38,7 @@
 #include "internal.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "hpeldsp.h"
 #include "videodsp.h"
 #include "vp3data.h"
 #include "vp3dsp.h"
@@ -131,13 +132,16 @@ typedef struct Vp3DecodeContext {
     int version;
     int width, height;
     int chroma_x_shift, chroma_y_shift;
-    AVFrame golden_frame;
-    AVFrame last_frame;
-    AVFrame current_frame;
+    ThreadFrame golden_frame;
+    ThreadFrame last_frame;
+    ThreadFrame current_frame;
     int keyframe;
-    DSPContext dsp;
+    uint8_t idct_permutation[64];
+    uint8_t idct_scantable[64];
+    HpelDSPContext hdsp;
     VideoDSPContext vdsp;
     VP3DSPContext vp3dsp;
+    DECLARE_ALIGNED(16, int16_t, block)[64];
     int flipped_image;
     int last_slice_end;
     int skip_loop_filter;
@@ -171,8 +175,6 @@ typedef struct Vp3DecodeContext {
 
     int8_t (*motion_val[2])[2];
 
-    ScanTable scantable;
-
     /* tables */
     uint16_t coded_dc_scale_factor[64];
     uint32_t coded_ac_scale_factor[64];
@@ -260,19 +262,11 @@ static void vp3_decode_flush(AVCodecContext *avctx)
 {
     Vp3DecodeContext *s = avctx->priv_data;
 
-    if (s->golden_frame.data[0]) {
-        if (s->golden_frame.data[0] == s->last_frame.data[0])
-            memset(&s->last_frame, 0, sizeof(AVFrame));
-        if (s->current_frame.data[0] == s->golden_frame.data[0])
-            memset(&s->current_frame, 0, sizeof(AVFrame));
+    if (s->golden_frame.f)
         ff_thread_release_buffer(avctx, &s->golden_frame);
-    }
-    if (s->last_frame.data[0]) {
-        if (s->current_frame.data[0] == s->last_frame.data[0])
-            memset(&s->current_frame, 0, sizeof(AVFrame));
+    if (s->last_frame.f)
         ff_thread_release_buffer(avctx, &s->last_frame);
-    }
-    if (s->current_frame.data[0])
+    if (s->current_frame.f)
         ff_thread_release_buffer(avctx, &s->current_frame);
 }
 
@@ -291,6 +285,12 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
     av_freep(&s->motion_val[1]);
     av_freep(&s->edge_emu_buffer);
 
+    /* release all frames */
+    vp3_decode_flush(avctx);
+    av_frame_free(&s->current_frame.f);
+    av_frame_free(&s->last_frame.f);
+    av_frame_free(&s->golden_frame.f);
+
     if (avctx->internal->is_copy)
         return 0;
 
@@ -307,8 +307,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
     ff_free_vlc(&s->mode_code_vlc);
     ff_free_vlc(&s->motion_vector_vlc);
 
-    /* release all frames */
-    vp3_decode_flush(avctx);
 
     return 0;
 }
@@ -377,7 +375,8 @@ static void init_dequantizer(Vp3DecodeContext *s, int qpi)
                 int qmin= 8<<(inter + !i);
                 int qscale= i ? ac_scale_factor : dc_scale_factor;
 
-                s->qmat[qpi][inter][plane][s->dsp.idct_permutation[i]]= av_clip((qscale * coeff)/100 * 4, qmin, 4096);
+                s->qmat[qpi][inter][plane][s->idct_permutation[i]] =
+                    av_clip((qscale * coeff) / 100 * 4, qmin, 4096);
             }
             // all DC coefficients use the same quant so as not to interfere with DC prediction
             s->qmat[qpi][inter][plane][0] = s->qmat[0][inter][plane][0];
@@ -919,7 +918,7 @@ static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
     int i, j = 0;
     int token;
     int zero_run = 0;
-    DCTELEM coeff = 0;
+    int16_t coeff = 0;
     int bits_to_get;
     int blocks_ended;
     int coeff_i = 0;
@@ -1289,8 +1288,8 @@ static void apply_loop_filter(Vp3DecodeContext *s, int plane, int ystart, int ye
     int width           = s->fragment_width[!!plane];
     int height          = s->fragment_height[!!plane];
     int fragment        = s->fragment_start        [plane] + ystart * width;
-    int stride          = s->current_frame.linesize[plane];
-    uint8_t *plane_data = s->current_frame.data    [plane];
+    ptrdiff_t stride    = s->current_frame.f->linesize[plane];
+    uint8_t *plane_data = s->current_frame.f->data    [plane];
     if (!s->flipped_image) stride = -stride;
     plane_data += s->data_offset[plane] + 8*ystart*stride;
 
@@ -1349,10 +1348,10 @@ static void apply_loop_filter(Vp3DecodeContext *s, int plane, int ystart, int ye
  * for the next block in coding order
  */
 static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag,
-                              int plane, int inter, DCTELEM block[64])
+                              int plane, int inter, int16_t block[64])
 {
     int16_t *dequantizer = s->qmat[frag->qpi][inter][plane];
-    uint8_t *perm = s->scantable.permutated;
+    uint8_t *perm = s->idct_scantable;
     int i = 0;
 
     do {
@@ -1419,14 +1418,14 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
     }
 
     cy = y >> s->chroma_y_shift;
-    offset[0] = s->current_frame.linesize[0]*y;
-    offset[1] = s->current_frame.linesize[1]*cy;
-    offset[2] = s->current_frame.linesize[2]*cy;
+    offset[0] = s->current_frame.f->linesize[0]*y;
+    offset[1] = s->current_frame.f->linesize[1]*cy;
+    offset[2] = s->current_frame.f->linesize[2]*cy;
     for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
         offset[i] = 0;
 
     emms_c();
-    s->avctx->draw_horiz_band(s->avctx, &s->current_frame, offset, y, 3, h);
+    s->avctx->draw_horiz_band(s->avctx, s->current_frame.f, offset, y, 3, h);
 }
 
 /**
@@ -1435,7 +1434,7 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
  */
 static void await_reference_row(Vp3DecodeContext *s, Vp3Fragment *fragment, int motion_y, int y)
 {
-    AVFrame *ref_frame;
+    ThreadFrame *ref_frame;
     int ref_row;
     int border = motion_y&1;
 
@@ -1458,7 +1457,7 @@ static void await_reference_row(Vp3DecodeContext *s, Vp3Fragment *fragment, int
 static void render_slice(Vp3DecodeContext *s, int slice)
 {
     int x, y, i, j, fragment;
-    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
+    int16_t *block = s->block;
     int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;
     int motion_halfpel_index;
     uint8_t *motion_source;
@@ -1468,10 +1467,10 @@ static void render_slice(Vp3DecodeContext *s, int slice)
         return;
 
     for (plane = 0; plane < 3; plane++) {
-        uint8_t *output_plane = s->current_frame.data    [plane] + s->data_offset[plane];
-        uint8_t *  last_plane = s->   last_frame.data    [plane] + s->data_offset[plane];
-        uint8_t *golden_plane = s-> golden_frame.data    [plane] + s->data_offset[plane];
-        int stride            = s->current_frame.linesize[plane];
+        uint8_t *output_plane = s->current_frame.f->data    [plane] + s->data_offset[plane];
+        uint8_t *  last_plane = s->   last_frame.f->data    [plane] + s->data_offset[plane];
+        uint8_t *golden_plane = s-> golden_frame.f->data    [plane] + s->data_offset[plane];
+        ptrdiff_t stride      = s->current_frame.f->linesize[plane];
         int plane_width       = s->width  >> (plane && s->chroma_x_shift);
         int plane_height      = s->height >> (plane && s->chroma_y_shift);
         int8_t (*motion_val)[2] = s->motion_val[!!plane];
@@ -1544,7 +1543,11 @@ static void render_slice(Vp3DecodeContext *s, int slice)
                             uint8_t *temp= s->edge_emu_buffer;
                             if(stride<0) temp -= 8*stride;
 
-                            s->vdsp.emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height);
+                            s->vdsp.emulated_edge_mc(temp, motion_source,
+                                                     stride, stride,
+                                                     9, 9, src_x, src_y,
+                                                     plane_width,
+                                                     plane_height);
                             motion_source= temp;
                         }
                     }
@@ -1558,12 +1561,12 @@ static void render_slice(Vp3DecodeContext *s, int slice)
                            VP3 source but this would be slower as
                            put_no_rnd_pixels_tab is better optimzed */
                         if(motion_halfpel_index != 3){
-                            s->dsp.put_no_rnd_pixels_tab[1][motion_halfpel_index](
+                            s->hdsp.put_no_rnd_pixels_tab[1][motion_halfpel_index](
                                 output_plane + first_pixel,
                                 motion_source, stride, 8);
                         }else{
                             int d= (motion_x ^ motion_y)>>31; // d is 0 if motion_x and _y have the same sign, else -1
-                            s->dsp.put_no_rnd_pixels_l2[1](
+                            s->vp3dsp.put_no_rnd_pixels_l2(
                                 output_plane + first_pixel,
                                 motion_source - d,
                                 motion_source + stride + 1 + d,
@@ -1571,8 +1574,6 @@ static void render_slice(Vp3DecodeContext *s, int slice)
                         }
                     }
 
-                        s->dsp.clear_block(block);
-
                     /* invert DCT and place (or add) in final output */
 
                     if (s->all_fragments[i].coding_method == MODE_INTRA) {
@@ -1600,7 +1601,7 @@ static void render_slice(Vp3DecodeContext *s, int slice)
                 } else {
 
                     /* copy directly from the previous frame */
-                    s->dsp.put_pixels_tab[1][0](
+                    s->hdsp.put_pixels_tab[1][0](
                         output_plane + first_pixel,
                         last_plane + first_pixel,
                         stride, 8);
@@ -1658,14 +1659,36 @@ static av_cold int allocate_tables(AVCodecContext *avctx)
     return 0;
 }
 
+static av_cold int init_frames(Vp3DecodeContext *s)
+{
+    s->current_frame.f = av_frame_alloc();
+    s->last_frame.f    = av_frame_alloc();
+    s->golden_frame.f  = av_frame_alloc();
+
+    if (!s->current_frame.f || !s->last_frame.f || !s->golden_frame.f) {
+        av_frame_free(&s->current_frame.f);
+        av_frame_free(&s->last_frame.f);
+        av_frame_free(&s->golden_frame.f);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
 static av_cold int vp3_decode_init(AVCodecContext *avctx)
 {
     Vp3DecodeContext *s = avctx->priv_data;
-    int i, inter, plane;
+    int i, inter, plane, ret;
     int c_width;
     int c_height;
     int y_fragment_count, c_fragment_count;
 
+    ret = init_frames(s);
+    if (ret < 0)
+        return ret;
+
+    avctx->internal->allocate_progress = 1;
+
     if (avctx->codec_tag == MKTAG('V','P','3','0'))
         s->version = 0;
     else
@@ -1677,12 +1700,16 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
     if (avctx->pix_fmt == AV_PIX_FMT_NONE)
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
-    ff_dsputil_init(&s->dsp, avctx);
+    ff_hpeldsp_init(&s->hdsp, avctx->flags | CODEC_FLAG_BITEXACT);
     ff_videodsp_init(&s->vdsp, 8);
     ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
 
-    ff_init_scantable_permutation(s->dsp.idct_permutation, s->vp3dsp.idct_perm);
-    ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);
+    for (i = 0; i < 64; i++) {
+#define T(x) (x >> 3) | ((x & 7) << 3)
+        s->idct_permutation[i] = T(i);
+        s->idct_scantable[i] = T(ff_zigzag_direct[i]);
+#undef T
+    }
 
     /* initialize to an impossible value which will force a recalculation
      * in the first frame decode */
@@ -1822,12 +1849,6 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
         &motion_vector_vlc_table[0][1], 2, 1,
         &motion_vector_vlc_table[0][0], 2, 1, 0);
 
-    for (i = 0; i < 3; i++) {
-        s->current_frame.data[i] = NULL;
-        s->last_frame.data[i] = NULL;
-        s->golden_frame.data[i] = NULL;
-    }
-
     return allocate_tables(avctx);
 
 vlc_fail:
@@ -1836,26 +1857,44 @@ vlc_fail:
 }
 
 /// Release and shuffle frames after decode finishes
-static void update_frames(AVCodecContext *avctx)
+static int update_frames(AVCodecContext *avctx)
 {
     Vp3DecodeContext *s = avctx->priv_data;
+    int ret = 0;
 
-    /* release the last frame, if it is allocated and if it is not the
-     * golden frame */
-    if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY)
-        ff_thread_release_buffer(avctx, &s->last_frame);
 
     /* shuffle frames (last = current) */
-    s->last_frame= s->current_frame;
+    ff_thread_release_buffer(avctx, &s->last_frame);
+    ret = ff_thread_ref_frame(&s->last_frame, &s->current_frame);
+    if (ret < 0)
+        goto fail;
 
     if (s->keyframe) {
-        if (s->golden_frame.data[0])
-            ff_thread_release_buffer(avctx, &s->golden_frame);
-        s->golden_frame = s->current_frame;
-        s->last_frame.type = FF_BUFFER_TYPE_COPY;
+        ff_thread_release_buffer(avctx, &s->golden_frame);
+        ret = ff_thread_ref_frame(&s->golden_frame, &s->current_frame);
     }
 
-    s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */
+fail:
+    ff_thread_release_buffer(avctx, &s->current_frame);
+    return ret;
+}
+
+static int ref_frame(Vp3DecodeContext *s, ThreadFrame *dst, ThreadFrame *src)
+{
+    ff_thread_release_buffer(s->avctx, dst);
+    if (src->f->data[0])
+        return ff_thread_ref_frame(dst, src);
+    return 0;
+}
+
+static int ref_frames(Vp3DecodeContext *dst, Vp3DecodeContext *src)
+{
+    int ret;
+    if ((ret = ref_frame(dst, &dst->current_frame, &src->current_frame)) < 0 ||
+        (ret = ref_frame(dst, &dst->golden_frame,  &src->golden_frame)) < 0  ||
+        (ret = ref_frame(dst, &dst->last_frame,    &src->last_frame)) < 0)
+        return ret;
+    return 0;
 }
 
 static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
@@ -1865,17 +1904,17 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
 
 #define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field)
 
-    if (!s1->current_frame.data[0]
+    if (!s1->current_frame.f->data[0]
         ||s->width != s1->width
         ||s->height!= s1->height) {
         if (s != s1)
-            copy_fields(s, s1, golden_frame, current_frame);
+            ref_frames(s, s1);
         return -1;
     }
 
     if (s != s1) {
         // init tables if the first frame hasn't been decoded
-        if (!s->current_frame.data[0]) {
+        if (!s->current_frame.f->data[0]) {
             int y_fragment_count, c_fragment_count;
             s->avctx = dst;
             err = allocate_tables(dst);
@@ -1888,7 +1927,10 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
         }
 
         // copy previous frame data
-        copy_fields(s, s1, golden_frame, dsp);
+        if ((err = ref_frames(s, s1)) < 0)
+            return err;
+
+        s->keyframe = s1->keyframe;
 
         // copy qscale data if necessary
         for (i = 0; i < 3; i++) {
@@ -1906,9 +1948,7 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
 #undef copy_fields
     }
 
-    update_frames(dst);
-
-    return 0;
+    return update_frames(dst);
 }
 
 static int vp3_decode_frame(AVCodecContext *avctx,
@@ -1919,7 +1959,7 @@ static int vp3_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     Vp3DecodeContext *s = avctx->priv_data;
     GetBitContext gb;
-    int i;
+    int i, ret;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -1961,15 +2001,14 @@ static int vp3_decode_frame(AVCodecContext *avctx,
     if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe)
         return buf_size;
 
-    s->current_frame.reference = 3;
-    s->current_frame.pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
-    if (ff_thread_get_buffer(avctx, &s->current_frame) < 0) {
+    s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         goto error;
     }
 
     if (!s->edge_emu_buffer)
-        s->edge_emu_buffer = av_malloc(9*FFABS(s->current_frame.linesize[0]));
+        s->edge_emu_buffer = av_malloc(9*FFABS(s->current_frame.f->linesize[0]));
 
     if (s->keyframe) {
         if (!s->theora)
@@ -1990,17 +2029,17 @@ static int vp3_decode_frame(AVCodecContext *avctx,
             skip_bits(&gb, 2); /* reserved? */
         }
     } else {
-        if (!s->golden_frame.data[0]) {
+        if (!s->golden_frame.f->data[0]) {
             av_log(s->avctx, AV_LOG_WARNING, "vp3: first frame not a keyframe\n");
 
-            s->golden_frame.reference = 3;
-            s->golden_frame.pict_type = AV_PICTURE_TYPE_I;
-            if (ff_thread_get_buffer(avctx, &s->golden_frame) < 0) {
+            s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I;
+            if (ff_thread_get_buffer(avctx, &s->golden_frame, AV_GET_BUFFER_FLAG_REF) < 0) {
                 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 goto error;
             }
-            s->last_frame = s->golden_frame;
-            s->last_frame.type = FF_BUFFER_TYPE_COPY;
+            ff_thread_release_buffer(avctx, &s->last_frame);
+            if ((ret = ff_thread_ref_frame(&s->last_frame, &s->golden_frame)) < 0)
+                goto error;
             ff_thread_report_progress(&s->last_frame, INT_MAX, 0);
         }
     }
@@ -2034,7 +2073,7 @@ static int vp3_decode_frame(AVCodecContext *avctx,
         if (s->flipped_image)
             s->data_offset[i] = 0;
         else
-            s->data_offset[i] = (height-1) * s->current_frame.linesize[i];
+            s->data_offset[i] = (height-1) * s->current_frame.f->linesize[i];
     }
 
     s->last_slice_end = 0;
@@ -2048,11 +2087,15 @@ static int vp3_decode_frame(AVCodecContext *avctx,
     }
     vp3_draw_horiz_band(s, s->avctx->height);
 
+    if ((ret = av_frame_ref(data, s->current_frame.f)) < 0)
+        return ret;
     *got_frame = 1;
-    *(AVFrame*)data= s->current_frame;
 
-    if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
-        update_frames(avctx);
+    if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME)) {
+        ret = update_frames(avctx);
+        if (ret < 0)
+            return ret;
+    }
 
     return buf_size;
 
@@ -2060,7 +2103,7 @@ error:
     ff_thread_report_progress(&s->current_frame, INT_MAX, 0);
 
     if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
-        avctx->release_buffer(avctx, &s->current_frame);
+        av_frame_unref(s->current_frame.f);
 
     return -1;
 }
@@ -2114,7 +2157,7 @@ static int vp3_init_thread_copy(AVCodecContext *avctx)
     s->motion_val[1]          = NULL;
     s->edge_emu_buffer        = NULL;
 
-    return 0;
+    return init_frames(s);
 }
 
 #if CONFIG_THEORA_DECODER
@@ -2127,6 +2170,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
     Vp3DecodeContext *s = avctx->priv_data;
     int visible_width, visible_height, colorspace;
     int offset_x = 0, offset_y = 0;
+    int ret;
     AVRational fps, aspect;
 
     s->theora = get_bits_long(gb, 24);
@@ -2143,12 +2187,6 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
     visible_width  = s->width  = get_bits(gb, 16) << 4;
     visible_height = s->height = get_bits(gb, 16) << 4;
 
-    if(av_image_check_size(s->width, s->height, 0, avctx)){
-        av_log(avctx, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", s->width, s->height);
-        s->width= s->height= 0;
-        return -1;
-    }
-
     if (s->theora >= 0x030200) {
         visible_width  = get_bits_long(gb, 24);
         visible_height = get_bits_long(gb, 24);
@@ -2195,9 +2233,11 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
     if (   visible_width  <= s->width  && visible_width  > s->width-16
         && visible_height <= s->height && visible_height > s->height-16
         && !offset_x && (offset_y == s->height - visible_height))
-        avcodec_set_dimensions(avctx, visible_width, visible_height);
+        ret = ff_set_dimensions(avctx, visible_width, visible_height);
     else
-        avcodec_set_dimensions(avctx, s->width, s->height);
+        ret = ff_set_dimensions(avctx, s->width, s->height);
+    if (ret < 0)
+        return ret;
 
     if (colorspace == 1) {
         avctx->color_primaries = AVCOL_PRI_BT470M;
@@ -2386,6 +2426,7 @@ static av_cold int theora_decode_init(AVCodecContext *avctx)
 
 AVCodec ff_theora_decoder = {
     .name                  = "theora",
+    .long_name             = NULL_IF_CONFIG_SMALL("Theora"),
     .type                  = AVMEDIA_TYPE_VIDEO,
     .id                    = AV_CODEC_ID_THEORA,
     .priv_data_size        = sizeof(Vp3DecodeContext),
@@ -2395,7 +2436,6 @@ AVCodec ff_theora_decoder = {
     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
                              CODEC_CAP_FRAME_THREADS,
     .flush                 = vp3_decode_flush,
-    .long_name             = NULL_IF_CONFIG_SMALL("Theora"),
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context)
 };
@@ -2403,6 +2443,7 @@ AVCodec ff_theora_decoder = {
 
 AVCodec ff_vp3_decoder = {
     .name                  = "vp3",
+    .long_name             = NULL_IF_CONFIG_SMALL("On2 VP3"),
     .type                  = AVMEDIA_TYPE_VIDEO,
     .id                    = AV_CODEC_ID_VP3,
     .priv_data_size        = sizeof(Vp3DecodeContext),
@@ -2412,7 +2453,6 @@ AVCodec ff_vp3_decoder = {
     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND |
                              CODEC_CAP_FRAME_THREADS,
     .flush                 = vp3_decode_flush,
-    .long_name             = NULL_IF_CONFIG_SMALL("On2 VP3"),
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context),
 };
diff --git a/libavcodec/vp3dsp.c b/libavcodec/vp3dsp.c
index 9b0b5d0..94de0e5 100644
--- a/libavcodec/vp3dsp.c
+++ b/libavcodec/vp3dsp.c
@@ -28,6 +28,7 @@
 #include "libavutil/common.h"
 #include "avcodec.h"
 #include "dsputil.h"
+#include "rnd_avg.h"
 #include "vp3dsp.h"
 
 #define IdctAdjustBeforeShift 8
@@ -53,11 +54,12 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int
     /* Inverse DCT on the rows now */
     for (i = 0; i < 8; i++) {
         /* Check for non-zero values */
-        if ( ip[0] | ip[1] | ip[2] | ip[3] | ip[4] | ip[5] | ip[6] | ip[7] ) {
-            A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
-            B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
-            C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
-            D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);
+        if ( ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
+             ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8] ) {
+            A = M(xC1S7, ip[1 * 8]) + M(xC7S1, ip[7 * 8]);
+            B = M(xC7S1, ip[1 * 8]) - M(xC1S7, ip[7 * 8]);
+            C = M(xC3S5, ip[3 * 8]) + M(xC5S3, ip[5 * 8]);
+            D = M(xC3S5, ip[5 * 8]) - M(xC5S3, ip[3 * 8]);
 
             Ad = M(xC4S4, (A - C));
             Bd = M(xC4S4, (B - D));
@@ -65,11 +67,11 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int
             Cd = A + C;
             Dd = B + D;
 
-            E = M(xC4S4, (ip[0] + ip[4]));
-            F = M(xC4S4, (ip[0] - ip[4]));
+            E = M(xC4S4, (ip[0 * 8] + ip[4 * 8]));
+            F = M(xC4S4, (ip[0 * 8] - ip[4 * 8]));
 
-            G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
-            H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);
+            G = M(xC2S6, ip[2 * 8]) + M(xC6S2, ip[6 * 8]);
+            H = M(xC6S2, ip[2 * 8]) - M(xC2S6, ip[6 * 8]);
 
             Ed = E - G;
             Gd = E + G;
@@ -81,33 +83,33 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int
             Hd = Bd + H;
 
             /*  Final sequence of operations over-write original inputs. */
-            ip[0] = Gd + Cd ;
-            ip[7] = Gd - Cd ;
+            ip[0 * 8] = Gd + Cd ;
+            ip[7 * 8] = Gd - Cd ;
 
-            ip[1] = Add + Hd;
-            ip[2] = Add - Hd;
+            ip[1 * 8] = Add + Hd;
+            ip[2 * 8] = Add - Hd;
 
-            ip[3] = Ed + Dd ;
-            ip[4] = Ed - Dd ;
+            ip[3 * 8] = Ed + Dd ;
+            ip[4 * 8] = Ed - Dd ;
 
-            ip[5] = Fd + Bdd;
-            ip[6] = Fd - Bdd;
+            ip[5 * 8] = Fd + Bdd;
+            ip[6 * 8] = Fd - Bdd;
         }
 
-        ip += 8;            /* next row */
+        ip += 1;            /* next row */
     }
 
     ip = input;
 
     for ( i = 0; i < 8; i++) {
         /* Check for non-zero values (bitwise or faster than ||) */
-        if ( ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
-             ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8] ) {
+        if ( ip[1] | ip[2] | ip[3] |
+             ip[4] | ip[5] | ip[6] | ip[7] ) {
 
-            A = M(xC1S7, ip[1*8]) + M(xC7S1, ip[7*8]);
-            B = M(xC7S1, ip[1*8]) - M(xC1S7, ip[7*8]);
-            C = M(xC3S5, ip[3*8]) + M(xC5S3, ip[5*8]);
-            D = M(xC3S5, ip[5*8]) - M(xC5S3, ip[3*8]);
+            A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
+            B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
+            C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
+            D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);
 
             Ad = M(xC4S4, (A - C));
             Bd = M(xC4S4, (B - D));
@@ -115,16 +117,16 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int
             Cd = A + C;
             Dd = B + D;
 
-            E = M(xC4S4, (ip[0*8] + ip[4*8])) + 8;
-            F = M(xC4S4, (ip[0*8] - ip[4*8])) + 8;
+            E = M(xC4S4, (ip[0] + ip[4])) + 8;
+            F = M(xC4S4, (ip[0] - ip[4])) + 8;
 
             if(type==1){  //HACK
                 E += 16*128;
                 F += 16*128;
             }
 
-            G = M(xC2S6, ip[2*8]) + M(xC6S2, ip[6*8]);
-            H = M(xC6S2, ip[2*8]) - M(xC2S6, ip[6*8]);
+            G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
+            H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);
 
             Ed = E - G;
             Gd = E + G;
@@ -136,19 +138,7 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int
             Hd = Bd + H;
 
             /* Final sequence of operations over-write original inputs. */
-            if(type==0){
-                ip[0*8] = (Gd + Cd )  >> 4;
-                ip[7*8] = (Gd - Cd )  >> 4;
-
-                ip[1*8] = (Add + Hd ) >> 4;
-                ip[2*8] = (Add - Hd ) >> 4;
-
-                ip[3*8] = (Ed + Dd )  >> 4;
-                ip[4*8] = (Ed - Dd )  >> 4;
-
-                ip[5*8] = (Fd + Bdd ) >> 4;
-                ip[6*8] = (Fd - Bdd ) >> 4;
-            }else if(type==1){
+            if (type == 1) {
                 dst[0*stride] = av_clip_uint8((Gd + Cd )  >> 4);
                 dst[7*stride] = av_clip_uint8((Gd - Cd )  >> 4);
 
@@ -175,16 +165,7 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int
             }
 
         } else {
-            if(type==0){
-                ip[0*8] =
-                ip[1*8] =
-                ip[2*8] =
-                ip[3*8] =
-                ip[4*8] =
-                ip[5*8] =
-                ip[6*8] =
-                ip[7*8] = ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);
-            }else if(type==1){
+            if (type == 1) {
                 dst[0*stride]=
                 dst[1*stride]=
                 dst[2*stride]=
@@ -192,10 +173,10 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int
                 dst[4*stride]=
                 dst[5*stride]=
                 dst[6*stride]=
-                dst[7*stride]= av_clip_uint8(128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20));
+                dst[7*stride]= av_clip_uint8(128 + ((xC4S4 * ip[0] + (IdctAdjustBeforeShift<<16))>>20));
             }else{
-                if(ip[0*8]){
-                    int v= ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);
+                if(ip[0]){
+                    int v= ((xC4S4 * ip[0] + (IdctAdjustBeforeShift<<16))>>20);
                     dst[0*stride] = av_clip_uint8(dst[0*stride] + v);
                     dst[1*stride] = av_clip_uint8(dst[1*stride] + v);
                     dst[2*stride] = av_clip_uint8(dst[2*stride] + v);
@@ -208,21 +189,28 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int
             }
         }
 
-        ip++;            /* next column */
+        ip += 8;            /* next column */
         dst++;
     }
 }
 
-static void vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){
+static void vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size,
+                           int16_t *block/*align 16*/)
+{
     idct(dest, line_size, block, 1);
+    memset(block, 0, sizeof(*block) * 64);
 }
 
-static void vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){
+static void vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size,
+                           int16_t *block/*align 16*/)
+{
     idct(dest, line_size, block, 2);
+    memset(block, 0, sizeof(*block) * 64);
 }
 
 static void vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size,
-                              const DCTELEM *block/*align 16*/){
+                              int16_t *block/*align 16*/)
+{
     int i, dc = (block[0] + 15) >> 5;
 
     for(i = 0; i < 8; i++){
@@ -236,6 +224,7 @@ static void vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size,
         dest[7] = av_clip_uint8(dest[7] + dc);
         dest += line_size;
     }
+    block[0] = 0;
 }
 
 static void vp3_v_loop_filter_c(uint8_t *first_pixel, int stride,
@@ -271,18 +260,37 @@ static void vp3_h_loop_filter_c(uint8_t *first_pixel, int stride,
     }
 }
 
+static void put_no_rnd_pixels_l2(uint8_t *dst, const uint8_t *src1,
+                                 const uint8_t *src2, ptrdiff_t stride, int h)
+{
+    int i;
+
+    for (i = 0; i < h; i++) {
+        uint32_t a, b;
+
+        a = AV_RN32(&src1[i * stride]);
+        b = AV_RN32(&src2[i * stride]);
+        AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
+        a = AV_RN32(&src1[i * stride + 4]);
+        b = AV_RN32(&src2[i * stride + 4]);
+        AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
+    }
+}
+
 av_cold void ff_vp3dsp_init(VP3DSPContext *c, int flags)
 {
+    c->put_no_rnd_pixels_l2 = put_no_rnd_pixels_l2;
+
     c->idct_put      = vp3_idct_put_c;
     c->idct_add      = vp3_idct_add_c;
     c->idct_dc_add   = vp3_idct_dc_add_c;
     c->v_loop_filter = vp3_v_loop_filter_c;
     c->h_loop_filter = vp3_h_loop_filter_c;
 
-    c->idct_perm = FF_NO_IDCT_PERM;
-
     if (ARCH_ARM)
         ff_vp3dsp_init_arm(c, flags);
+    if (ARCH_BFIN)
+        ff_vp3dsp_init_bfin(c, flags);
     if (ARCH_PPC)
         ff_vp3dsp_init_ppc(c, flags);
     if (ARCH_X86)
diff --git a/libavcodec/vp3dsp.h b/libavcodec/vp3dsp.h
index 3781bbf..39c4408 100644
--- a/libavcodec/vp3dsp.h
+++ b/libavcodec/vp3dsp.h
@@ -19,21 +19,35 @@
 #ifndef AVCODEC_VP3DSP_H
 #define AVCODEC_VP3DSP_H
 
+#include <stddef.h>
 #include <stdint.h>
-#include "dsputil.h"
 
 typedef struct VP3DSPContext {
-    void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*idct_add)(uint8_t *dest, int line_size, DCTELEM *block);
-    void (*idct_dc_add)(uint8_t *dest, int line_size, const DCTELEM *block);
+    /**
+     * Copy 8xH pixels from source to destination buffer using a bilinear
+     * filter with no rounding (i.e. *dst = (*a + *b) >> 1).
+     *
+     * @param dst destination buffer, aligned by 8
+     * @param a first source buffer, no alignment
+     * @param b second source buffer, no alignment
+     * @param stride distance between two lines in source/dest buffers
+     * @param h height
+     */
+    void (*put_no_rnd_pixels_l2)(uint8_t *dst,
+                                 const uint8_t *a,
+                                 const uint8_t *b,
+                                 ptrdiff_t stride, int h);
+
+    void (*idct_put)(uint8_t *dest, int line_size, int16_t *block);
+    void (*idct_add)(uint8_t *dest, int line_size, int16_t *block);
+    void (*idct_dc_add)(uint8_t *dest, int line_size, int16_t *block);
     void (*v_loop_filter)(uint8_t *src, int stride, int *bounding_values);
     void (*h_loop_filter)(uint8_t *src, int stride, int *bounding_values);
-
-    int idct_perm;
 } VP3DSPContext;
 
 void ff_vp3dsp_init(VP3DSPContext *c, int flags);
 void ff_vp3dsp_init_arm(VP3DSPContext *c, int flags);
+void ff_vp3dsp_init_bfin(VP3DSPContext *c, int flags);
 void ff_vp3dsp_init_ppc(VP3DSPContext *c, int flags);
 void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags);
 
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index 3671623..b609282 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -27,8 +27,8 @@
 #include <string.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 
 #include "vp56.h"
 #include "vp56data.h"
@@ -42,10 +42,10 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
     int rows, cols;
 
     ff_vp56_init_range_decoder(&s->c, buf, buf_size);
-    s->framep[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
+    s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
     vp56_rac_get(c);
     ff_vp56_init_dequant(s, vp56_rac_gets(c, 6));
-    if (s->framep[VP56_FRAME_CURRENT]->key_frame)
+    if (s->frames[VP56_FRAME_CURRENT]->key_frame)
     {
         vp56_rac_gets(c, 8);
         if(vp56_rac_gets(c, 5) > 5)
@@ -68,7 +68,9 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
         if (!s->macroblocks || /* first frame */
             16*cols != s->avctx->coded_width ||
             16*rows != s->avctx->coded_height) {
-            avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
+            int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+            if (ret < 0)
+                return ret;
             return VP56_SIZE_CHANGE;
         }
     } else if (!s->macroblocks)
@@ -139,7 +141,7 @@ static int vp5_parse_coeff_models(VP56Context *s)
             if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) {
                 def_prob[node] = vp56_rac_gets_nn(c, 7);
                 model->coeff_dccv[pt][node] = def_prob[node];
-            } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+            } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
                 model->coeff_dccv[pt][node] = def_prob[node];
             }
 
@@ -150,7 +152,7 @@ static int vp5_parse_coeff_models(VP56Context *s)
                     if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) {
                         def_prob[node] = vp56_rac_gets_nn(c, 7);
                         model->coeff_ract[pt][ct][cg][node] = def_prob[node];
-                    } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+                    } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
                         model->coeff_ract[pt][ct][cg][node] = def_prob[node];
                     }
 
@@ -174,7 +176,7 @@ static void vp5_parse_coeff(VP56Context *s)
 {
     VP56RangeCoder *c = &s->c;
     VP56Model *model = s->modelp;
-    uint8_t *permute = s->scantable.permutated;
+    uint8_t *permute = s->idct_scantable;
     uint8_t *model1, *model2;
     int coeff, sign, coeff_idx;
     int b, i, cg, idx, ctx, ctx_last;
@@ -265,8 +267,10 @@ static void vp5_default_models_init(VP56Context *s)
 static av_cold int vp5_decode_init(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
+    int ret;
 
-    ff_vp56_init(avctx, 1, 0);
+    if ((ret = ff_vp56_init(avctx, 1, 0)) < 0)
+        return ret;
     s->vp56_coord_div = vp5_coord_div;
     s->parse_vector_adjustment = vp5_parse_vector_adjustment;
     s->parse_coeff = vp5_parse_coeff;
@@ -280,6 +284,7 @@ static av_cold int vp5_decode_init(AVCodecContext *avctx)
 
 AVCodec ff_vp5_decoder = {
     .name           = "vp5",
+    .long_name      = NULL_IF_CONFIG_SMALL("On2 VP5"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VP5,
     .priv_data_size = sizeof(VP56Context),
@@ -287,5 +292,4 @@ AVCodec ff_vp5_decoder = {
     .close          = ff_vp56_free,
     .decode         = ff_vp56_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("On2 VP5"),
 };
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index c3c9cb2..7fbf9a0 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -26,7 +26,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
-
+#include "h264chroma.h"
 #include "vp56.h"
 #include "vp56data.h"
 
@@ -34,9 +34,8 @@
 void ff_vp56_init_dequant(VP56Context *s, int quantizer)
 {
     s->quantizer = quantizer;
-    s->dequant_dc = vp56_dc_dequant[quantizer] << 2;
-    s->dequant_ac = vp56_ac_dequant[quantizer] << 2;
-    memset(s->qscale_table, quantizer, s->mb_width);
+    s->dequant_dc = ff_vp56_dc_dequant[quantizer] << 2;
+    s->dequant_ac = ff_vp56_ac_dequant[quantizer] << 2;
 }
 
 static int vp56_get_vectors_predictors(VP56Context *s, int row, int col,
@@ -48,14 +47,14 @@ static int vp56_get_vectors_predictors(VP56Context *s, int row, int col,
     VP56mv mvp;
 
     for (pos=0; pos<12; pos++) {
-        mvp.x = col + vp56_candidate_predictor_pos[pos][0];
-        mvp.y = row + vp56_candidate_predictor_pos[pos][1];
+        mvp.x = col + ff_vp56_candidate_predictor_pos[pos][0];
+        mvp.y = row + ff_vp56_candidate_predictor_pos[pos][1];
         if (mvp.x < 0 || mvp.x >= s->mb_width ||
             mvp.y < 0 || mvp.y >= s->mb_height)
             continue;
         offset = mvp.x + s->mb_width*mvp.y;
 
-        if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)
+        if (ff_vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)
             continue;
         if ((s->macroblocks[offset].mv.x == vect[0].x &&
              s->macroblocks[offset].mv.y == vect[0].y) ||
@@ -87,7 +86,7 @@ static void vp56_parse_mb_type_models(VP56Context *s)
         if (vp56_rac_get_prob(c, 174)) {
             int idx = vp56_rac_gets(c, 4);
             memcpy(model->mb_types_stats[ctx],
-                   vp56_pre_def_mb_type_stats[idx][ctx],
+                   ff_vp56_pre_def_mb_type_stats[idx][ctx],
                    sizeof(model->mb_types_stats[ctx]));
         }
         if (vp56_rac_get_prob(c, 254)) {
@@ -96,8 +95,8 @@ static void vp56_parse_mb_type_models(VP56Context *s)
                     if (vp56_rac_get_prob(c, 205)) {
                         int delta, sign = vp56_rac_get(c);
 
-                        delta = vp56_rac_get_tree(c, vp56_pmbtm_tree,
-                                                  vp56_mb_type_model_model);
+                        delta = vp56_rac_get_tree(c, ff_vp56_pmbtm_tree,
+                                                  ff_vp56_mb_type_model_model);
                         if (!delta)
                             delta = 4 * vp56_rac_gets(c, 7);
                         model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign;
@@ -157,7 +156,7 @@ static VP56mb vp56_parse_mb_type(VP56Context *s,
     if (vp56_rac_get_prob(c, mb_type_model[0]))
         return prev_type;
     else
-        return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model);
+        return vp56_rac_get_tree(c, ff_vp56_pmbt_tree, mb_type_model);
 }
 
 static void vp56_decode_4mv(VP56Context *s, int row, int col)
@@ -264,7 +263,7 @@ static VP56mb vp56_decode_mv(VP56Context *s, int row, int col)
 
 static void vp56_add_predictors_dc(VP56Context *s, VP56Frame ref_frame)
 {
-    int idx = s->scantable.permutated[0];
+    int idx = s->idct_scantable[0];
     int b;
 
     for (b=0; b<6; b++) {
@@ -304,17 +303,17 @@ static void vp56_add_predictors_dc(VP56Context *s, VP56Frame ref_frame)
 }
 
 static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv,
-                                int stride, int dx, int dy)
+                                ptrdiff_t stride, int dx, int dy)
 {
-    int t = vp56_filter_threshold[s->quantizer];
+    int t = ff_vp56_filter_threshold[s->quantizer];
     if (dx)  s->vp56dsp.edge_filter_hor(yuv +         10-dx , stride, t);
     if (dy)  s->vp56dsp.edge_filter_ver(yuv + stride*(10-dy), stride, t);
 }
 
 static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
-                    int stride, int x, int y)
+                    ptrdiff_t stride, int x, int y)
 {
-    uint8_t *dst=s->framep[VP56_FRAME_CURRENT]->data[plane]+s->block_offset[b];
+    uint8_t *dst = s->frames[VP56_FRAME_CURRENT]->data[plane] + s->block_offset[b];
     uint8_t *src_block;
     int src_offset;
     int overlap_offset = 0;
@@ -325,7 +324,7 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
 
     if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
         (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY
-         && !s->framep[VP56_FRAME_CURRENT]->key_frame))
+         && !s->frames[VP56_FRAME_CURRENT]->key_frame))
         deblock_filtering = 0;
 
     dx = s->mv[b].x / s->vp56_coord_div[b];
@@ -342,7 +341,8 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
         y<0 || y+12>=s->plane_height[plane]) {
         s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
                             src + s->block_offset[b] + (dy-2)*stride + (dx-2),
-                            stride, 12, 12, x, y,
+                            stride, stride,
+                            12, 12, x, y,
                             s->plane_width[plane],
                             s->plane_height[plane]);
         src_block = s->edge_emu_buffer;
@@ -350,9 +350,9 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
     } else if (deblock_filtering) {
         /* only need a 12x12 block, but there is no such dsp function, */
         /* so copy a 16x12 block */
-        s->dsp.put_pixels_tab[0][0](s->edge_emu_buffer,
-                                    src + s->block_offset[b] + (dy-2)*stride + (dx-2),
-                                    stride, 12);
+        s->hdsp.put_pixels_tab[0][0](s->edge_emu_buffer,
+                                     src + s->block_offset[b] + (dy-2)*stride + (dx-2),
+                                     stride, 12);
         src_block = s->edge_emu_buffer;
         src_offset = 2 + 2*stride;
     } else {
@@ -373,11 +373,11 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
             s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset,
                       stride, s->mv[b], mask, s->filter_selection, b<4);
         else
-            s->dsp.put_no_rnd_pixels_l2[1](dst, src_block+src_offset,
+            s->vp3dsp.put_no_rnd_pixels_l2(dst, src_block+src_offset,
                                            src_block+src_offset+overlap_offset,
                                            stride, 8);
     } else {
-        s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8);
+        s->hdsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8);
     }
 }
 
@@ -388,20 +388,18 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
     VP56Frame ref_frame;
     int b, ab, b_max, plane, off;
 
-    if (s->framep[VP56_FRAME_CURRENT]->key_frame)
+    if (s->frames[VP56_FRAME_CURRENT]->key_frame)
         mb_type = VP56_MB_INTRA;
     else
         mb_type = vp56_decode_mv(s, row, col);
-    ref_frame = vp56_reference_frame[mb_type];
-
-    s->dsp.clear_blocks(*s->block_coeff);
+    ref_frame = ff_vp56_reference_frame[mb_type];
 
     s->parse_coeff(s);
 
     vp56_add_predictors_dc(s, ref_frame);
 
-    frame_current = s->framep[VP56_FRAME_CURRENT];
-    frame_ref = s->framep[ref_frame];
+    frame_current = s->frames[VP56_FRAME_CURRENT];
+    frame_ref = s->frames[ref_frame];
     if (mb_type != VP56_MB_INTRA && !frame_ref->data[0])
         return;
 
@@ -422,9 +420,9 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
             for (b=0; b<b_max; b++) {
                 plane = ff_vp56_b2p[b+ab];
                 off = s->block_offset[b];
-                s->dsp.put_pixels_tab[1][0](frame_current->data[plane] + off,
-                                            frame_ref->data[plane] + off,
-                                            s->stride[plane], 8);
+                s->hdsp.put_pixels_tab[1][0](frame_current->data[plane] + off,
+                                             frame_ref->data[plane] + off,
+                                             s->stride[plane], 8);
                 s->vp3dsp.idct_add(frame_current->data[plane] + off,
                                 s->stride[plane], s->block_coeff[b]);
             }
@@ -448,12 +446,17 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
             }
             break;
     }
+
+    if (is_alpha) {
+        s->block_coeff[4][0] = 0;
+        s->block_coeff[5][0] = 0;
+    }
 }
 
 static int vp56_size_changed(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
-    int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0];
+    int stride = s->frames[VP56_FRAME_CURRENT]->linesize[0];
     int i;
 
     s->plane_width[0]  = s->plane_width[3]  = avctx->coded_width;
@@ -462,18 +465,17 @@ static int vp56_size_changed(AVCodecContext *avctx)
     s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2;
 
     for (i=0; i<4; i++)
-        s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i];
+        s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT]->linesize[i];
 
     s->mb_width  = (avctx->coded_width +15) / 16;
     s->mb_height = (avctx->coded_height+15) / 16;
 
     if (s->mb_width > 1000 || s->mb_height > 1000) {
-        avcodec_set_dimensions(avctx, 0, 0);
+        ff_set_dimensions(avctx, 0, 0);
         av_log(avctx, AV_LOG_ERROR, "picture too big\n");
         return -1;
     }
 
-    s->qscale_table = av_realloc(s->qscale_table, s->mb_width);
     s->above_blocks = av_realloc(s->above_blocks,
                                  (4*s->mb_width+6) * sizeof(*s->above_blocks));
     s->macroblocks = av_realloc(s->macroblocks,
@@ -492,9 +494,10 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 {
     const uint8_t *buf = avpkt->data;
     VP56Context *s = avctx->priv_data;
-    AVFrame *const p = s->framep[VP56_FRAME_CURRENT];
+    AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
     int remaining_buf_size = avpkt->size;
     int is_alpha, av_uninit(alpha_offset);
+    int res;
 
     if (s->has_alpha) {
         if (remaining_buf_size < 3)
@@ -507,44 +510,39 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     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 block, y, uv;
+        ptrdiff_t stride_y, stride_uv;
         int golden_frame = 0;
-        int res;
 
         s->modelp = &s->models[is_alpha];
 
         res = s->parse_header(s, buf, remaining_buf_size, &golden_frame);
         if (res < 0) {
             int i;
-            for (i = 0; i < 4; i++) {
-                if (s->frames[i].data[0])
-                    avctx->release_buffer(avctx, &s->frames[i]);
-            }
+            for (i = 0; i < 4; i++)
+                av_frame_unref(s->frames[i]);
             return res;
         }
 
         if (res == VP56_SIZE_CHANGE) {
             int i;
-            for (i = 0; i < 4; i++) {
-                if (s->frames[i].data[0])
-                    avctx->release_buffer(avctx, &s->frames[i]);
-            }
+            for (i = 0; i < 4; i++)
+                av_frame_unref(s->frames[i]);
             if (is_alpha) {
-                avcodec_set_dimensions(avctx, 0, 0);
+                ff_set_dimensions(avctx, 0, 0);
                 return -1;
             }
         }
 
         if (!is_alpha) {
-            p->reference = 1;
-            if (ff_get_buffer(avctx, p) < 0) {
+            if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return -1;
             }
 
             if (res == VP56_SIZE_CHANGE)
                 if (vp56_size_changed(avctx)) {
-                    avctx->release_buffer(avctx, p);
+                    av_frame_unref(p);
                     return -1;
                 }
         }
@@ -628,44 +626,31 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     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;
+            av_frame_unref(s->frames[VP56_FRAME_GOLDEN]);
+            if ((res = av_frame_ref(s->frames[VP56_FRAME_GOLDEN], p)) < 0)
+                return res;
         }
 
         if (s->has_alpha) {
-            FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN],
-                              s->framep[VP56_FRAME_GOLDEN2]);
+            FFSWAP(AVFrame *, s->frames[VP56_FRAME_GOLDEN],
+                              s->frames[VP56_FRAME_GOLDEN2]);
             buf += alpha_offset;
             remaining_buf_size -= alpha_offset;
         }
     }
 
-    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->qstride = 0;
-    p->qscale_table = s->qscale_table;
-    p->qscale_type = FF_QSCALE_TYPE_VP56;
-    *(AVFrame*)data = *p;
+    av_frame_unref(s->frames[VP56_FRAME_PREVIOUS]);
+    FFSWAP(AVFrame *, s->frames[VP56_FRAME_CURRENT],
+                      s->frames[VP56_FRAME_PREVIOUS]);
+
+    if ((res = av_frame_ref(data, p)) < 0)
+        return res;
     *got_frame = 1;
 
     return avpkt->size;
 }
 
-av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
+av_cold int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
 {
     VP56Context *s = avctx->priv_data;
     int i;
@@ -673,17 +658,24 @@ av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
     s->avctx = avctx;
     avctx->pix_fmt = has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
 
-    ff_dsputil_init(&s->dsp, avctx);
+    ff_h264chroma_init(&s->h264chroma, 8);
+    ff_hpeldsp_init(&s->hdsp, avctx->flags);
     ff_videodsp_init(&s->vdsp, 8);
     ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
     ff_vp56dsp_init(&s->vp56dsp, avctx->codec->id);
-    ff_init_scantable_permutation(s->dsp.idct_permutation, s->vp3dsp.idct_perm);
-    ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct);
+    for (i = 0; i < 64; i++) {
+#define T(x) (x >> 3) | ((x & 7) << 3)
+        s->idct_scantable[i] = T(ff_zigzag_direct[i]);
+#undef T
+    }
 
-    for (i=0; i<4; i++)
-        s->framep[i] = &s->frames[i];
-    s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN];
-    s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2];
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
+        s->frames[i] = av_frame_alloc();
+        if (!s->frames[i]) {
+            ff_vp56_free(avctx);
+            return AVERROR(ENOMEM);
+        }
+    }
     s->edge_emu_buffer_alloc = NULL;
 
     s->above_blocks = NULL;
@@ -703,21 +695,21 @@ av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
         s->frbi = 0;
         s->srbi = 2;
     }
+
+    return 0;
 }
 
 av_cold int ff_vp56_free(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
+    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 < FF_ARRAY_ELEMS(s->frames); i++)
+        av_frame_free(&s->frames[i]);
+
     return 0;
 }
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h
index 431d1a9..f71b9a8 100644
--- a/libavcodec/vp56.h
+++ b/libavcodec/vp56.h
@@ -26,16 +26,43 @@
 #ifndef AVCODEC_VP56_H
 #define AVCODEC_VP56_H
 
-#include "vp56data.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "hpeldsp.h"
 #include "bytestream.h"
+#include "h264chroma.h"
 #include "videodsp.h"
 #include "vp3dsp.h"
 #include "vp56dsp.h"
 
 typedef struct vp56_context VP56Context;
 
+typedef enum {
+    VP56_FRAME_NONE     =-1,
+    VP56_FRAME_CURRENT  = 0,
+    VP56_FRAME_PREVIOUS = 1,
+    VP56_FRAME_GOLDEN   = 2,
+    VP56_FRAME_GOLDEN2  = 3,
+} VP56Frame;
+
+typedef enum {
+    VP56_MB_INTER_NOVEC_PF = 0,  /**< Inter MB, no vector, from previous frame */
+    VP56_MB_INTRA          = 1,  /**< Intra MB */
+    VP56_MB_INTER_DELTA_PF = 2,  /**< Inter MB, above/left vector + delta, from previous frame */
+    VP56_MB_INTER_V1_PF    = 3,  /**< Inter MB, first vector, from previous frame */
+    VP56_MB_INTER_V2_PF    = 4,  /**< Inter MB, second vector, from previous frame */
+    VP56_MB_INTER_NOVEC_GF = 5,  /**< Inter MB, no vector, from golden frame */
+    VP56_MB_INTER_DELTA_GF = 6,  /**< Inter MB, above/left vector + delta, from golden frame */
+    VP56_MB_INTER_4V       = 7,  /**< Inter MB, 4 vectors, from previous frame */
+    VP56_MB_INTER_V1_GF    = 8,  /**< Inter MB, first vector, from golden frame */
+    VP56_MB_INTER_V2_GF    = 9,  /**< Inter MB, second vector, from golden frame */
+} VP56mb;
+
+typedef struct VP56Tree {
+  int8_t val;
+  int8_t prob_idx;
+} VP56Tree;
+
 typedef struct VP56mv {
     DECLARE_ALIGNED(4, int16_t, x);
     int16_t y;
@@ -67,7 +94,7 @@ typedef struct VP56RangeCoder {
 typedef struct VP56RefDc {
     uint8_t not_null_dc;
     VP56Frame ref_frame;
-    DCTELEM dc_coeff;
+    int16_t dc_coeff;
 } VP56RefDc;
 
 typedef struct VP56Macroblock {
@@ -94,13 +121,13 @@ typedef struct VP56Model {
 
 struct vp56_context {
     AVCodecContext *avctx;
-    DSPContext dsp;
+    H264ChromaContext h264chroma;
+    HpelDSPContext hdsp;
     VideoDSPContext vdsp;
     VP3DSPContext vp3dsp;
     VP56DSPContext vp56dsp;
-    ScanTable scantable;
-    AVFrame frames[4];
-    AVFrame *framep[6];
+    uint8_t idct_scantable[64];
+    AVFrame *frames[4];
     uint8_t *edge_emu_buffer_alloc;
     uint8_t *edge_emu_buffer;
     VP56RangeCoder c;
@@ -118,18 +145,17 @@ struct vp56_context {
     int quantizer;
     uint16_t dequant_dc;
     uint16_t dequant_ac;
-    int8_t *qscale_table;
 
     /* DC predictors management */
     VP56RefDc *above_blocks;
     VP56RefDc left_block[4];
     int above_block_idx[6];
-    DCTELEM prev_dc[3][3];    /* [plan][ref_frame] */
+    int16_t prev_dc[3][3];    /* [plan][ref_frame] */
 
     /* blocks / macroblock */
     VP56mb mb_type;
     VP56Macroblock *macroblocks;
-    DECLARE_ALIGNED(16, DCTELEM, block_coeff)[6][64];
+    DECLARE_ALIGNED(16, int16_t, block_coeff)[6][64];
 
     /* motion vectors */
     VP56mv mv[6];  /* vectors for each block in MB */
@@ -177,7 +203,7 @@ struct vp56_context {
 };
 
 
-void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
+int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
 int ff_vp56_free(AVCodecContext *avctx);
 void ff_vp56_init_dequant(VP56Context *s, int quantizer);
 int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
diff --git a/libavcodec/vp56data.c b/libavcodec/vp56data.c
index 90e2f36..989c76a 100644
--- a/libavcodec/vp56data.c
+++ b/libavcodec/vp56data.c
@@ -66,3 +66,189 @@ const VP56Tree ff_vp56_pc_tree[] = {
 
 const uint8_t ff_vp56_coeff_bias[] = { 0, 1, 2, 3, 4, 5, 7, 11, 19, 35, 67 };
 const uint8_t ff_vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 };
+
+const VP56Frame ff_vp56_reference_frame[] = {
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_NOVEC_PF */
+    VP56_FRAME_CURRENT,   /* VP56_MB_INTRA */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_DELTA_PF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V1_PF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V2_PF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_NOVEC_GF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_DELTA_GF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_4V */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V1_GF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V2_GF */
+};
+
+const uint8_t ff_vp56_ac_dequant[64] = {
+    94, 92, 90, 88, 86, 82, 78, 74,
+    70, 66, 62, 58, 54, 53, 52, 51,
+    50, 49, 48, 47, 46, 45, 44, 43,
+    42, 40, 39, 37, 36, 35, 34, 33,
+    32, 31, 30, 29, 28, 27, 26, 25,
+    24, 23, 22, 21, 20, 19, 18, 17,
+    16, 15, 14, 13, 12, 11, 10,  9,
+     8,  7,  6,  5,  4,  3,  2,  1,
+};
+
+const uint8_t ff_vp56_dc_dequant[64] = {
+    47, 47, 47, 47, 45, 43, 43, 43,
+    43, 43, 42, 41, 41, 40, 40, 40,
+    40, 35, 35, 35, 35, 33, 33, 33,
+    33, 32, 32, 32, 27, 27, 26, 26,
+    25, 25, 24, 24, 23, 23, 19, 19,
+    19, 19, 18, 18, 17, 16, 16, 16,
+    16, 16, 15, 11, 11, 11, 10, 10,
+     9,  8,  7,  5,  3,  3,  2,  2,
+};
+
+const uint8_t ff_vp56_pre_def_mb_type_stats[16][3][10][2] = {
+  { { {   9, 15 }, {  32, 25 }, {  7,  19 }, {   9, 21 }, {  1, 12 },
+      {  14, 12 }, {   3, 18 }, { 14,  23 }, {   3, 10 }, {  0,  4 }, },
+    { {  41, 22 }, {   1,  0 }, {  1,  31 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   1,  7 }, {  0,   1 }, {  98, 25 }, {  4, 10 }, },
+    { {   2,  3 }, {   2,  3 }, {  0,   2 }, {   0,  2 }, {  0,  0 },
+      {  11,  4 }, {   1,  4 }, {  0,   2 }, {   3,  2 }, {  0,  4 }, }, },
+  { { {  48, 39 }, {   1,  2 }, { 11,  27 }, {  29, 44 }, {  7, 27 },
+      {   1,  4 }, {   0,  3 }, {  1,   6 }, {   1,  2 }, {  0,  0 }, },
+    { { 123, 37 }, {   6,  4 }, {  1,  27 }, {   0,  0 }, {  0,  0 },
+      {   5,  8 }, {   1,  7 }, {  0,   1 }, {  12, 10 }, {  0,  2 }, },
+    { {  49, 46 }, {   3,  4 }, {  7,  31 }, {  42, 41 }, {  0,  0 },
+      {   2,  6 }, {   1,  7 }, {  1,   4 }, {   2,  4 }, {  0,  1 }, }, },
+  { { {  21, 32 }, {   1,  2 }, {  4,  10 }, {  32, 43 }, {  6, 23 },
+      {   2,  3 }, {   1, 19 }, {  1,   6 }, {  12, 21 }, {  0,  7 }, },
+    { {  26, 14 }, {  14, 12 }, {  0,  24 }, {   0,  0 }, {  0,  0 },
+      {  55, 17 }, {   1,  9 }, {  0,  36 }, {   5,  7 }, {  1,  3 }, },
+    { {  26, 25 }, {   1,  1 }, {  2,  10 }, {  67, 39 }, {  0,  0 },
+      {   1,  1 }, {   0, 14 }, {  0,   2 }, {  31, 26 }, {  1,  6 }, }, },
+  { { {  69, 83 }, {   0,  0 }, {  0,   2 }, {  10, 29 }, {  3, 12 },
+      {   0,  1 }, {   0,  3 }, {  0,   3 }, {   2,  2 }, {  0,  0 }, },
+    { { 209,  5 }, {   0,  0 }, {  0,  27 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { { 103, 46 }, {   1,  2 }, {  2,  10 }, {  33, 42 }, {  0,  0 },
+      {   1,  4 }, {   0,  3 }, {  0,   1 }, {   1,  3 }, {  0,  0 }, }, },
+  { { {  11, 20 }, {   1,  4 }, { 18,  36 }, {  43, 48 }, { 13, 35 },
+      {   0,  2 }, {   0,  5 }, {  3,  12 }, {   1,  2 }, {  0,  0 }, },
+    { {   2,  5 }, {   4,  5 }, {  0, 121 }, {   0,  0 }, {  0,  0 },
+      {   0,  3 }, {   2,  4 }, {  1,   4 }, {   2,  2 }, {  0,  1 }, },
+    { {  14, 31 }, {   9, 13 }, { 14,  54 }, {  22, 29 }, {  0,  0 },
+      {   2,  6 }, {   4, 18 }, {  6,  13 }, {   1,  5 }, {  0,  1 }, }, },
+  { { {  70, 44 }, {   0,  1 }, {  2,  10 }, {  37, 46 }, {  8, 26 },
+      {   0,  2 }, {   0,  2 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
+    { { 175,  5 }, {   0,  1 }, {  0,  48 }, {   0,  0 }, {  0,  0 },
+      {   0,  2 }, {   0,  1 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
+    { {  85, 39 }, {   0,  0 }, {  1,   9 }, {  69, 40 }, {  0,  0 },
+      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  0 }, }, },
+  { { {   8, 15 }, {   0,  1 }, {  8,  21 }, {  74, 53 }, { 22, 42 },
+      {   0,  1 }, {   0,  2 }, {  0,   3 }, {   1,  2 }, {  0,  0 }, },
+    { {  83,  5 }, {   2,  3 }, {  0, 102 }, {   0,  0 }, {  0,  0 },
+      {   1,  3 }, {   0,  2 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { {  31, 28 }, {   0,  0 }, {  3,  14 }, { 130, 34 }, {  0,  0 },
+      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   3,  3 }, {  0,  1 }, }, },
+  { { { 141, 42 }, {   0,  0 }, {  1,   4 }, {  11, 24 }, {  1, 11 },
+      {   0,  1 }, {   0,  1 }, {  0,   2 }, {   0,  0 }, {  0,  0 }, },
+    { { 233,  6 }, {   0,  0 }, {  0,   8 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
+    { { 171, 25 }, {   0,  0 }, {  1,   5 }, {  25, 21 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, }, },
+  { { {   8, 19 }, {   4, 10 }, { 24,  45 }, {  21, 37 }, {  9, 29 },
+      {   0,  3 }, {   1,  7 }, { 11,  25 }, {   0,  2 }, {  0,  1 }, },
+    { {  34, 16 }, { 112, 21 }, {  1,  28 }, {   0,  0 }, {  0,  0 },
+      {   6,  8 }, {   1,  7 }, {  0,   3 }, {   2,  5 }, {  0,  2 }, },
+    { {  17, 21 }, {  68, 29 }, {  6,  15 }, {  13, 22 }, {  0,  0 },
+      {   6, 12 }, {   3, 14 }, {  4,  10 }, {   1,  7 }, {  0,  3 }, }, },
+  { { {  46, 42 }, {   0,  1 }, {  2,  10 }, {  54, 51 }, { 10, 30 },
+      {   0,  2 }, {   0,  2 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, },
+    { { 159, 35 }, {   2,  2 }, {  0,  25 }, {   0,  0 }, {  0,  0 },
+      {   3,  6 }, {   0,  5 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
+    { {  51, 39 }, {   0,  1 }, {  2,  12 }, {  91, 44 }, {  0,  0 },
+      {   0,  2 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  1 }, }, },
+  { { {  28, 32 }, {   0,  0 }, {  3,  10 }, {  75, 51 }, { 14, 33 },
+      {   0,  1 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, },
+    { {  75, 39 }, {   5,  7 }, {  2,  48 }, {   0,  0 }, {  0,  0 },
+      {   3, 11 }, {   2, 16 }, {  1,   4 }, {   7, 10 }, {  0,  2 }, },
+    { {  81, 25 }, {   0,  0 }, {  2,   9 }, { 106, 26 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
+  { { { 100, 46 }, {   0,  1 }, {  3,   9 }, {  21, 37 }, {  5, 20 },
+      {   0,  1 }, {   0,  2 }, {  1,   2 }, {   0,  1 }, {  0,  0 }, },
+    { { 212, 21 }, {   0,  1 }, {  0,   9 }, {   0,  0 }, {  0,  0 },
+      {   1,  2 }, {   0,  2 }, {  0,   0 }, {   2,  2 }, {  0,  0 }, },
+    { { 140, 37 }, {   0,  1 }, {  1,   8 }, {  24, 33 }, {  0,  0 },
+      {   1,  2 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, }, },
+  { { {  27, 29 }, {   0,  1 }, {  9,  25 }, {  53, 51 }, { 12, 34 },
+      {   0,  1 }, {   0,  3 }, {  1,   5 }, {   0,  2 }, {  0,  0 }, },
+    { {   4,  2 }, {   0,  0 }, {  0, 172 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  2 }, {  0,   0 }, {   2,  0 }, {  0,  0 }, },
+    { {  14, 23 }, {   1,  3 }, { 11,  53 }, {  90, 31 }, {  0,  0 },
+      {   0,  3 }, {   1,  5 }, {  2,   6 }, {   1,  2 }, {  0,  0 }, }, },
+  { { {  80, 38 }, {   0,  0 }, {  1,   4 }, {  69, 33 }, {  5, 16 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
+    { { 187, 22 }, {   1,  1 }, {  0,  17 }, {   0,  0 }, {  0,  0 },
+      {   3,  6 }, {   0,  4 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
+    { { 123, 29 }, {   0,  0 }, {  1,   7 }, {  57, 30 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, }, },
+  { { {  16, 20 }, {   0,  0 }, {  2,   8 }, { 104, 49 }, { 15, 33 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, },
+    { { 133,  6 }, {   1,  2 }, {  1,  70 }, {   0,  0 }, {  0,  0 },
+      {   0,  2 }, {   0,  4 }, {  0,   3 }, {   1,  1 }, {  0,  0 }, },
+    { {  13, 14 }, {   0,  0 }, {  4,  20 }, { 175, 20 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
+  { { { 194, 16 }, {   0,  0 }, {  1,   1 }, {   1,  9 }, {  1,  3 },
+      {   0,  0 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { { 251,  1 }, {   0,  0 }, {  0,   2 }, {   0,  0 }, {  0,  0 },
+      {   0,  0 }, {   0,  0 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, },
+    { { 202, 23 }, {   0,  0 }, {  1,   3 }, {   2,  9 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, }, },
+};
+
+const uint8_t ff_vp56_filter_threshold[] = {
+    14, 14, 13, 13, 12, 12, 10, 10,
+    10, 10,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  7,  7,  7,  7,
+     7,  7,  6,  6,  6,  6,  6,  6,
+     5,  5,  5,  5,  4,  4,  4,  4,
+     4,  4,  4,  3,  3,  3,  3,  2,
+};
+
+const uint8_t ff_vp56_mb_type_model_model[] = {
+    171, 83, 199, 140, 125, 104,
+};
+
+const VP56Tree ff_vp56_pmbtm_tree[] = {
+    { 4, 0},
+    { 2, 1}, {-8}, {-4},
+    { 8, 2},
+    { 6, 3},
+    { 4, 4},
+    { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0},
+};
+
+const VP56Tree ff_vp56_pmbt_tree[] = {
+    { 8, 1},
+    { 4, 2},
+    { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF},
+    { 2, 5}, {-VP56_MB_INTER_V1_PF},    {-VP56_MB_INTER_V2_PF},
+    { 4, 3},
+    { 2, 6}, {-VP56_MB_INTRA},          {-VP56_MB_INTER_4V},
+    { 4, 7},
+    { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF},
+    { 2, 9}, {-VP56_MB_INTER_V1_GF},    {-VP56_MB_INTER_V2_GF},
+};
+
+/* relative pos of surrounding blocks, from closest to farthest */
+const int8_t ff_vp56_candidate_predictor_pos[12][2] = {
+    {  0, -1 },
+    { -1,  0 },
+    { -1, -1 },
+    {  1, -1 },
+    {  0, -2 },
+    { -2,  0 },
+    { -2, -1 },
+    { -1, -2 },
+    {  1, -2 },
+    {  2, -1 },
+    { -2, -2 },
+    {  2, -2 },
+};
diff --git a/libavcodec/vp56data.h b/libavcodec/vp56data.h
index 0535425..21907bd 100644
--- a/libavcodec/vp56data.h
+++ b/libavcodec/vp56data.h
@@ -27,34 +27,7 @@
 #define AVCODEC_VP56DATA_H
 
 #include "libavutil/common.h"
-
-typedef enum {
-    VP56_FRAME_NONE     =-1,
-    VP56_FRAME_CURRENT  = 0,
-    VP56_FRAME_PREVIOUS = 1,
-    VP56_FRAME_GOLDEN   = 2,
-    VP56_FRAME_GOLDEN2  = 3,
-    VP56_FRAME_UNUSED   = 4,
-    VP56_FRAME_UNUSED2  = 5,
-} VP56Frame;
-
-typedef enum {
-    VP56_MB_INTER_NOVEC_PF = 0,  /**< Inter MB, no vector, from previous frame */
-    VP56_MB_INTRA          = 1,  /**< Intra MB */
-    VP56_MB_INTER_DELTA_PF = 2,  /**< Inter MB, above/left vector + delta, from previous frame */
-    VP56_MB_INTER_V1_PF    = 3,  /**< Inter MB, first vector, from previous frame */
-    VP56_MB_INTER_V2_PF    = 4,  /**< Inter MB, second vector, from previous frame */
-    VP56_MB_INTER_NOVEC_GF = 5,  /**< Inter MB, no vector, from golden frame */
-    VP56_MB_INTER_DELTA_GF = 6,  /**< Inter MB, above/left vector + delta, from golden frame */
-    VP56_MB_INTER_4V       = 7,  /**< Inter MB, 4 vectors, from previous frame */
-    VP56_MB_INTER_V1_GF    = 8,  /**< Inter MB, first vector, from golden frame */
-    VP56_MB_INTER_V2_GF    = 9,  /**< Inter MB, second vector, from golden frame */
-} VP56mb;
-
-typedef struct VP56Tree {
-  int8_t val;
-  int8_t prob_idx;
-} VP56Tree;
+#include "vp56.h"
 
 extern const uint8_t ff_vp56_b2p[];
 extern const uint8_t ff_vp56_b6to4[];
@@ -65,190 +38,14 @@ extern const VP56Tree ff_vp56_pc_tree[];
 extern const uint8_t ff_vp56_coeff_bias[];
 extern const uint8_t ff_vp56_coeff_bit_length[];
 
-static const VP56Frame vp56_reference_frame[] = {
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_NOVEC_PF */
-    VP56_FRAME_CURRENT,   /* VP56_MB_INTRA */
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_DELTA_PF */
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V1_PF */
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V2_PF */
-    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_NOVEC_GF */
-    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_DELTA_GF */
-    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_4V */
-    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V1_GF */
-    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V2_GF */
-};
-
-static const uint8_t vp56_ac_dequant[64] = {
-    94, 92, 90, 88, 86, 82, 78, 74,
-    70, 66, 62, 58, 54, 53, 52, 51,
-    50, 49, 48, 47, 46, 45, 44, 43,
-    42, 40, 39, 37, 36, 35, 34, 33,
-    32, 31, 30, 29, 28, 27, 26, 25,
-    24, 23, 22, 21, 20, 19, 18, 17,
-    16, 15, 14, 13, 12, 11, 10,  9,
-     8,  7,  6,  5,  4,  3,  2,  1,
-};
-
-static const uint8_t vp56_dc_dequant[64] = {
-    47, 47, 47, 47, 45, 43, 43, 43,
-    43, 43, 42, 41, 41, 40, 40, 40,
-    40, 35, 35, 35, 35, 33, 33, 33,
-    33, 32, 32, 32, 27, 27, 26, 26,
-    25, 25, 24, 24, 23, 23, 19, 19,
-    19, 19, 18, 18, 17, 16, 16, 16,
-    16, 16, 15, 11, 11, 11, 10, 10,
-     9,  8,  7,  5,  3,  3,  2,  2,
-};
-
-static const uint8_t vp56_pre_def_mb_type_stats[16][3][10][2] = {
-  { { {   9, 15 }, {  32, 25 }, {  7,  19 }, {   9, 21 }, {  1, 12 },
-      {  14, 12 }, {   3, 18 }, { 14,  23 }, {   3, 10 }, {  0,  4 }, },
-    { {  41, 22 }, {   1,  0 }, {  1,  31 }, {   0,  0 }, {  0,  0 },
-      {   0,  1 }, {   1,  7 }, {  0,   1 }, {  98, 25 }, {  4, 10 }, },
-    { {   2,  3 }, {   2,  3 }, {  0,   2 }, {   0,  2 }, {  0,  0 },
-      {  11,  4 }, {   1,  4 }, {  0,   2 }, {   3,  2 }, {  0,  4 }, }, },
-  { { {  48, 39 }, {   1,  2 }, { 11,  27 }, {  29, 44 }, {  7, 27 },
-      {   1,  4 }, {   0,  3 }, {  1,   6 }, {   1,  2 }, {  0,  0 }, },
-    { { 123, 37 }, {   6,  4 }, {  1,  27 }, {   0,  0 }, {  0,  0 },
-      {   5,  8 }, {   1,  7 }, {  0,   1 }, {  12, 10 }, {  0,  2 }, },
-    { {  49, 46 }, {   3,  4 }, {  7,  31 }, {  42, 41 }, {  0,  0 },
-      {   2,  6 }, {   1,  7 }, {  1,   4 }, {   2,  4 }, {  0,  1 }, }, },
-  { { {  21, 32 }, {   1,  2 }, {  4,  10 }, {  32, 43 }, {  6, 23 },
-      {   2,  3 }, {   1, 19 }, {  1,   6 }, {  12, 21 }, {  0,  7 }, },
-    { {  26, 14 }, {  14, 12 }, {  0,  24 }, {   0,  0 }, {  0,  0 },
-      {  55, 17 }, {   1,  9 }, {  0,  36 }, {   5,  7 }, {  1,  3 }, },
-    { {  26, 25 }, {   1,  1 }, {  2,  10 }, {  67, 39 }, {  0,  0 },
-      {   1,  1 }, {   0, 14 }, {  0,   2 }, {  31, 26 }, {  1,  6 }, }, },
-  { { {  69, 83 }, {   0,  0 }, {  0,   2 }, {  10, 29 }, {  3, 12 },
-      {   0,  1 }, {   0,  3 }, {  0,   3 }, {   2,  2 }, {  0,  0 }, },
-    { { 209,  5 }, {   0,  0 }, {  0,  27 }, {   0,  0 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
-    { { 103, 46 }, {   1,  2 }, {  2,  10 }, {  33, 42 }, {  0,  0 },
-      {   1,  4 }, {   0,  3 }, {  0,   1 }, {   1,  3 }, {  0,  0 }, }, },
-  { { {  11, 20 }, {   1,  4 }, { 18,  36 }, {  43, 48 }, { 13, 35 },
-      {   0,  2 }, {   0,  5 }, {  3,  12 }, {   1,  2 }, {  0,  0 }, },
-    { {   2,  5 }, {   4,  5 }, {  0, 121 }, {   0,  0 }, {  0,  0 },
-      {   0,  3 }, {   2,  4 }, {  1,   4 }, {   2,  2 }, {  0,  1 }, },
-    { {  14, 31 }, {   9, 13 }, { 14,  54 }, {  22, 29 }, {  0,  0 },
-      {   2,  6 }, {   4, 18 }, {  6,  13 }, {   1,  5 }, {  0,  1 }, }, },
-  { { {  70, 44 }, {   0,  1 }, {  2,  10 }, {  37, 46 }, {  8, 26 },
-      {   0,  2 }, {   0,  2 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
-    { { 175,  5 }, {   0,  1 }, {  0,  48 }, {   0,  0 }, {  0,  0 },
-      {   0,  2 }, {   0,  1 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
-    { {  85, 39 }, {   0,  0 }, {  1,   9 }, {  69, 40 }, {  0,  0 },
-      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  0 }, }, },
-  { { {   8, 15 }, {   0,  1 }, {  8,  21 }, {  74, 53 }, { 22, 42 },
-      {   0,  1 }, {   0,  2 }, {  0,   3 }, {   1,  2 }, {  0,  0 }, },
-    { {  83,  5 }, {   2,  3 }, {  0, 102 }, {   0,  0 }, {  0,  0 },
-      {   1,  3 }, {   0,  2 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
-    { {  31, 28 }, {   0,  0 }, {  3,  14 }, { 130, 34 }, {  0,  0 },
-      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   3,  3 }, {  0,  1 }, }, },
-  { { { 141, 42 }, {   0,  0 }, {  1,   4 }, {  11, 24 }, {  1, 11 },
-      {   0,  1 }, {   0,  1 }, {  0,   2 }, {   0,  0 }, {  0,  0 }, },
-    { { 233,  6 }, {   0,  0 }, {  0,   8 }, {   0,  0 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
-    { { 171, 25 }, {   0,  0 }, {  1,   5 }, {  25, 21 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, }, },
-  { { {   8, 19 }, {   4, 10 }, { 24,  45 }, {  21, 37 }, {  9, 29 },
-      {   0,  3 }, {   1,  7 }, { 11,  25 }, {   0,  2 }, {  0,  1 }, },
-    { {  34, 16 }, { 112, 21 }, {  1,  28 }, {   0,  0 }, {  0,  0 },
-      {   6,  8 }, {   1,  7 }, {  0,   3 }, {   2,  5 }, {  0,  2 }, },
-    { {  17, 21 }, {  68, 29 }, {  6,  15 }, {  13, 22 }, {  0,  0 },
-      {   6, 12 }, {   3, 14 }, {  4,  10 }, {   1,  7 }, {  0,  3 }, }, },
-  { { {  46, 42 }, {   0,  1 }, {  2,  10 }, {  54, 51 }, { 10, 30 },
-      {   0,  2 }, {   0,  2 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, },
-    { { 159, 35 }, {   2,  2 }, {  0,  25 }, {   0,  0 }, {  0,  0 },
-      {   3,  6 }, {   0,  5 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
-    { {  51, 39 }, {   0,  1 }, {  2,  12 }, {  91, 44 }, {  0,  0 },
-      {   0,  2 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  1 }, }, },
-  { { {  28, 32 }, {   0,  0 }, {  3,  10 }, {  75, 51 }, { 14, 33 },
-      {   0,  1 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, },
-    { {  75, 39 }, {   5,  7 }, {  2,  48 }, {   0,  0 }, {  0,  0 },
-      {   3, 11 }, {   2, 16 }, {  1,   4 }, {   7, 10 }, {  0,  2 }, },
-    { {  81, 25 }, {   0,  0 }, {  2,   9 }, { 106, 26 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
-  { { { 100, 46 }, {   0,  1 }, {  3,   9 }, {  21, 37 }, {  5, 20 },
-      {   0,  1 }, {   0,  2 }, {  1,   2 }, {   0,  1 }, {  0,  0 }, },
-    { { 212, 21 }, {   0,  1 }, {  0,   9 }, {   0,  0 }, {  0,  0 },
-      {   1,  2 }, {   0,  2 }, {  0,   0 }, {   2,  2 }, {  0,  0 }, },
-    { { 140, 37 }, {   0,  1 }, {  1,   8 }, {  24, 33 }, {  0,  0 },
-      {   1,  2 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, }, },
-  { { {  27, 29 }, {   0,  1 }, {  9,  25 }, {  53, 51 }, { 12, 34 },
-      {   0,  1 }, {   0,  3 }, {  1,   5 }, {   0,  2 }, {  0,  0 }, },
-    { {   4,  2 }, {   0,  0 }, {  0, 172 }, {   0,  0 }, {  0,  0 },
-      {   0,  1 }, {   0,  2 }, {  0,   0 }, {   2,  0 }, {  0,  0 }, },
-    { {  14, 23 }, {   1,  3 }, { 11,  53 }, {  90, 31 }, {  0,  0 },
-      {   0,  3 }, {   1,  5 }, {  2,   6 }, {   1,  2 }, {  0,  0 }, }, },
-  { { {  80, 38 }, {   0,  0 }, {  1,   4 }, {  69, 33 }, {  5, 16 },
-      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
-    { { 187, 22 }, {   1,  1 }, {  0,  17 }, {   0,  0 }, {  0,  0 },
-      {   3,  6 }, {   0,  4 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
-    { { 123, 29 }, {   0,  0 }, {  1,   7 }, {  57, 30 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, }, },
-  { { {  16, 20 }, {   0,  0 }, {  2,   8 }, { 104, 49 }, { 15, 33 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, },
-    { { 133,  6 }, {   1,  2 }, {  1,  70 }, {   0,  0 }, {  0,  0 },
-      {   0,  2 }, {   0,  4 }, {  0,   3 }, {   1,  1 }, {  0,  0 }, },
-    { {  13, 14 }, {   0,  0 }, {  4,  20 }, { 175, 20 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
-  { { { 194, 16 }, {   0,  0 }, {  1,   1 }, {   1,  9 }, {  1,  3 },
-      {   0,  0 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
-    { { 251,  1 }, {   0,  0 }, {  0,   2 }, {   0,  0 }, {  0,  0 },
-      {   0,  0 }, {   0,  0 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, },
-    { { 202, 23 }, {   0,  0 }, {  1,   3 }, {   2,  9 }, {  0,  0 },
-      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, }, },
-};
-
-static const uint8_t vp56_filter_threshold[] = {
-    14, 14, 13, 13, 12, 12, 10, 10,
-    10, 10,  8,  8,  8,  8,  8,  8,
-     8,  8,  8,  8,  8,  8,  8,  8,
-     8,  8,  8,  8,  8,  8,  8,  8,
-     8,  8,  8,  8,  7,  7,  7,  7,
-     7,  7,  6,  6,  6,  6,  6,  6,
-     5,  5,  5,  5,  4,  4,  4,  4,
-     4,  4,  4,  3,  3,  3,  3,  2,
-};
-
-static const uint8_t vp56_mb_type_model_model[] = {
-    171, 83, 199, 140, 125, 104,
-};
-
-static const VP56Tree vp56_pmbtm_tree[] = {
-    { 4, 0},
-    { 2, 1}, {-8}, {-4},
-    { 8, 2},
-    { 6, 3},
-    { 4, 4},
-    { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0},
-};
-
-static const VP56Tree vp56_pmbt_tree[] = {
-    { 8, 1},
-    { 4, 2},
-    { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF},
-    { 2, 5}, {-VP56_MB_INTER_V1_PF},    {-VP56_MB_INTER_V2_PF},
-    { 4, 3},
-    { 2, 6}, {-VP56_MB_INTRA},          {-VP56_MB_INTER_4V},
-    { 4, 7},
-    { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF},
-    { 2, 9}, {-VP56_MB_INTER_V1_GF},    {-VP56_MB_INTER_V2_GF},
-};
-
-/* relative pos of surrounding blocks, from closest to farthest */
-static const int8_t vp56_candidate_predictor_pos[12][2] = {
-    {  0, -1 },
-    { -1,  0 },
-    { -1, -1 },
-    {  1, -1 },
-    {  0, -2 },
-    { -2,  0 },
-    { -2, -1 },
-    { -1, -2 },
-    {  1, -2 },
-    {  2, -1 },
-    { -2, -2 },
-    {  2, -2 },
-};
+extern const VP56Frame ff_vp56_reference_frame[];
+extern const uint8_t ff_vp56_ac_dequant[64];
+extern const uint8_t ff_vp56_dc_dequant[64];
+extern const uint8_t ff_vp56_pre_def_mb_type_stats[16][3][10][2];
+extern const uint8_t ff_vp56_filter_threshold[];
+extern const uint8_t ff_vp56_mb_type_model_model[];
+extern const VP56Tree ff_vp56_pmbtm_tree[];
+extern const VP56Tree ff_vp56_pmbt_tree[];
+extern const int8_t ff_vp56_candidate_predictor_pos[12][2];
 
 #endif /* AVCODEC_VP56DATA_H */
diff --git a/libavcodec/vp56dsp.c b/libavcodec/vp56dsp.c
index 5a36e52..5e09d24 100644
--- a/libavcodec/vp56dsp.c
+++ b/libavcodec/vp56dsp.c
@@ -20,6 +20,8 @@
  */
 
 #include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "vp56dsp.h"
 #include "libavutil/common.h"
@@ -75,7 +77,7 @@ VP56_EDGE_FILTER(vp5, ver, stride, 1)
 VP56_EDGE_FILTER(vp6, hor, 1, stride)
 VP56_EDGE_FILTER(vp6, ver, stride, 1)
 
-void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec)
+av_cold void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec)
 {
     if (codec == AV_CODEC_ID_VP5) {
         s->edge_filter_hor = vp5_edge_filter_hor;
@@ -86,9 +88,11 @@ void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec)
 
         if (CONFIG_VP6_DECODER) {
             s->vp6_filter_diag4 = ff_vp6_filter_diag4_c;
+
+            if (ARCH_ARM)
+                ff_vp6dsp_init_arm(s, codec);
+            if (ARCH_X86)
+                ff_vp6dsp_init_x86(s, codec);
         }
     }
-
-    if (ARCH_ARM) ff_vp56dsp_init_arm(s, codec);
-    if (ARCH_X86) ff_vp56dsp_init_x86(s, codec);
 }
diff --git a/libavcodec/vp56dsp.h b/libavcodec/vp56dsp.h
index 034e2e9..389d359 100644
--- a/libavcodec/vp56dsp.h
+++ b/libavcodec/vp56dsp.h
@@ -36,7 +36,7 @@ void ff_vp6_filter_diag4_c(uint8_t *dst, uint8_t *src, int stride,
                            const int16_t *h_weights, const int16_t *v_weights);
 
 void ff_vp56dsp_init(VP56DSPContext *s, enum AVCodecID codec);
-void ff_vp56dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec);
-void ff_vp56dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec);
+void ff_vp6dsp_init_arm(VP56DSPContext *s, enum AVCodecID codec);
+void ff_vp6dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec);
 
 #endif /* AVCODEC_VP56DSP_H */
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index c433acb..d10a640 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -30,9 +30,9 @@
 #include <stdlib.h>
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "get_bits.h"
 #include "huffman.h"
+#include "internal.h"
 
 #include "vp56.h"
 #include "vp56data.h"
@@ -55,16 +55,16 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
     int res = 0;
     int separated_coeff = buf[0] & 1;
 
-    s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
+    s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
     ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);
 
-    if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+    if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
         sub_version = buf[1] >> 3;
         if (sub_version > 8)
             return AVERROR_INVALIDDATA;
         s->filter_header = buf[1] & 0x06;
         if (buf[1] & 1) {
-            av_log_missing_feature(s->avctx, "Interlacing", 0);
+            avpriv_report_missing_feature(s->avctx, "Interlacing");
             return AVERROR_PATCHWELCOME;
         }
         if (separated_coeff || !s->filter_header) {
@@ -85,10 +85,23 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
         if (!s->macroblocks || /* first frame */
             16*cols != s->avctx->coded_width ||
             16*rows != s->avctx->coded_height) {
-            avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
-            if (s->avctx->extradata_size == 1) {
-                s->avctx->width  -= s->avctx->extradata[0] >> 4;
-                s->avctx->height -= s->avctx->extradata[0] & 0x0F;
+            if (s->avctx->extradata_size == 0 &&
+                FFALIGN(s->avctx->width,  16) == 16 * cols &&
+                FFALIGN(s->avctx->height, 16) == 16 * rows) {
+                // We assume this is properly signalled container cropping,
+                // in an F4V file. Just set the coded_width/height, don't
+                // touch the cropped ones.
+                s->avctx->coded_width  = 16 * cols;
+                s->avctx->coded_height = 16 * rows;
+            } else {
+                int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+                if (ret < 0)
+                    return ret;
+
+                if (s->avctx->extradata_size == 1) {
+                    s->avctx->width  -= s->avctx->extradata[0] >> 4;
+                    s->avctx->height -= s->avctx->extradata[0] & 0x0F;
+                }
             }
             res = VP56_SIZE_CHANGE;
         }
@@ -144,8 +157,8 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
         buf      += coeff_offset;
         buf_size -= coeff_offset;
         if (buf_size < 0) {
-            if (s->framep[VP56_FRAME_CURRENT]->key_frame)
-                avcodec_set_dimensions(s->avctx, 0, 0);
+            if (s->frames[VP56_FRAME_CURRENT]->key_frame)
+                ff_set_dimensions(s->avctx, 0, 0);
             return AVERROR_INVALIDDATA;
         }
         if (s->use_huffman) {
@@ -259,7 +272,7 @@ static int vp6_parse_coeff_models(VP56Context *s)
             if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) {
                 def_prob[node] = vp56_rac_gets_nn(c, 7);
                 model->coeff_dccv[pt][node] = def_prob[node];
-            } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+            } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
                 model->coeff_dccv[pt][node] = def_prob[node];
             }
 
@@ -282,7 +295,7 @@ static int vp6_parse_coeff_models(VP56Context *s)
                     if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) {
                         def_prob[node] = vp56_rac_gets_nn(c, 7);
                         model->coeff_ract[pt][ct][cg][node] = def_prob[node];
-                    } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+                    } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
                         model->coeff_ract[pt][ct][cg][node] = def_prob[node];
                     }
 
@@ -369,7 +382,7 @@ static unsigned vp6_get_nb_null(VP56Context *s)
 static void vp6_parse_coeff_huffman(VP56Context *s)
 {
     VP56Model *model = s->modelp;
-    uint8_t *permute = s->scantable.permutated;
+    uint8_t *permute = s->idct_scantable;
     VLC *vlc_coeff;
     int coeff, sign, coeff_idx;
     int b, cg, idx;
@@ -429,7 +442,7 @@ static void vp6_parse_coeff(VP56Context *s)
 {
     VP56RangeCoder *c = s->ccp;
     VP56Model *model = s->modelp;
-    uint8_t *permute = s->scantable.permutated;
+    uint8_t *permute = s->idct_scantable;
     uint8_t *model1, *model2, *model3;
     int coeff, sign, coeff_idx;
     int b, i, cg, idx, ctx;
@@ -536,8 +549,8 @@ static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src,
                              int stride, int h_weight, int v_weight)
 {
     uint8_t *tmp = s->edge_emu_buffer+16;
-    s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0);
-    s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight);
+    s->h264chroma.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0);
+    s->h264chroma.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight);
 }
 
 static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src,
@@ -583,7 +596,7 @@ static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src,
         }
     } else {
         if (!x8 || !y8) {
-            s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8);
+            s->h264chroma.put_h264_chroma_pixels_tab[0](dst, src + offset1, stride, 8, x8, y8);
         } else {
             vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8);
         }
@@ -593,9 +606,12 @@ static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src,
 static av_cold int vp6_decode_init(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
+    int ret;
+
+    if ((ret = ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6,
+                            avctx->codec->id == AV_CODEC_ID_VP6A)) < 0)
+        return ret;
 
-    ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6,
-                        avctx->codec->id == AV_CODEC_ID_VP6A);
     s->vp56_coord_div = vp6_coord_div;
     s->parse_vector_adjustment = vp6_parse_vector_adjustment;
     s->filter = vp6_filter;
@@ -626,6 +642,7 @@ static av_cold int vp6_decode_free(AVCodecContext *avctx)
 
 AVCodec ff_vp6_decoder = {
     .name           = "vp6",
+    .long_name      = NULL_IF_CONFIG_SMALL("On2 VP6"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VP6,
     .priv_data_size = sizeof(VP56Context),
@@ -633,12 +650,12 @@ AVCodec ff_vp6_decoder = {
     .close          = vp6_decode_free,
     .decode         = ff_vp56_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("On2 VP6"),
 };
 
 /* flash version, not flipped upside-down */
 AVCodec ff_vp6f_decoder = {
     .name           = "vp6f",
+    .long_name      = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VP6F,
     .priv_data_size = sizeof(VP56Context),
@@ -646,12 +663,12 @@ AVCodec ff_vp6f_decoder = {
     .close          = vp6_decode_free,
     .decode         = ff_vp56_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
 };
 
 /* flash version, not flipped upside-down, with alpha channel */
 AVCodec ff_vp6a_decoder = {
     .name           = "vp6a",
+    .long_name      = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VP6A,
     .priv_data_size = sizeof(VP56Context),
@@ -659,5 +676,4 @@ AVCodec ff_vp6a_decoder = {
     .close          = vp6_decode_free,
     .decode         = ff_vp56_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .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..2de90e7 100644
--- a/libavcodec/vp6data.h
+++ b/libavcodec/vp6data.h
@@ -26,7 +26,9 @@
 #ifndef AVCODEC_VP6DATA_H
 #define AVCODEC_VP6DATA_H
 
-#include "vp56data.h"
+#include <stdint.h>
+
+#include "vp56.h"
 
 static const uint8_t vp6_def_fdv_vector_model[2][8] = {
     { 247, 210, 135, 68, 138, 220, 239, 246 },
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index deb5015..2660395 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -56,79 +56,73 @@ static void free_buffers(VP8Context *s)
     s->macroblocks = NULL;
 }
 
-static int vp8_alloc_frame(VP8Context *s, AVFrame *f)
+static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
 {
     int ret;
-    if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0)
+    if ((ret = ff_thread_get_buffer(s->avctx, &f->tf,
+                                    ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
         return ret;
-    if (s->num_maps_to_be_freed && !s->maps_are_invalid) {
-        f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed];
-    } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) {
-        ff_thread_release_buffer(s->avctx, f);
+    if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) {
+        ff_thread_release_buffer(s->avctx, &f->tf);
         return AVERROR(ENOMEM);
     }
     return 0;
 }
 
-static void vp8_release_frame(VP8Context *s, AVFrame *f, int prefer_delayed_free, int can_direct_free)
+static void vp8_release_frame(VP8Context *s, VP8Frame *f)
 {
-    if (f->ref_index[0]) {
-        if (prefer_delayed_free) {
-            /* Upon a size change, we want to free the maps but other threads may still
-             * be using them, so queue them. Upon a seek, all threads are inactive so
-             * we want to cache one to prevent re-allocation in the next decoding
-             * iteration, but the rest we can free directly. */
-            int max_queued_maps = can_direct_free ? 1 : FF_ARRAY_ELEMS(s->segmentation_maps);
-            if (s->num_maps_to_be_freed < max_queued_maps) {
-                s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0];
-            } else if (can_direct_free) /* vp8_decode_flush(), but our queue is full */ {
-                av_free(f->ref_index[0]);
-            } /* else: MEMLEAK (should never happen, but better that than crash) */
-            f->ref_index[0] = NULL;
-        } else /* vp8_decode_free() */ {
-            av_free(f->ref_index[0]);
-        }
+    av_buffer_unref(&f->seg_map);
+    ff_thread_release_buffer(s->avctx, &f->tf);
+}
+
+static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src)
+{
+    int ret;
+
+    vp8_release_frame(s, dst);
+
+    if ((ret = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0)
+        return ret;
+    if (src->seg_map &&
+        !(dst->seg_map = av_buffer_ref(src->seg_map))) {
+        vp8_release_frame(s, dst);
+        return AVERROR(ENOMEM);
     }
-    ff_thread_release_buffer(s->avctx, f);
+
+    return 0;
 }
 
-static void vp8_decode_flush_impl(AVCodecContext *avctx,
-                                  int prefer_delayed_free, int can_direct_free, int free_mem)
+
+static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
 {
     VP8Context *s = avctx->priv_data;
     int i;
 
-    if (!avctx->internal->is_copy) {
-        for (i = 0; i < 5; i++)
-            if (s->frames[i].data[0])
-                vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_direct_free);
-    }
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+        vp8_release_frame(s, &s->frames[i]);
     memset(s->framep, 0, sizeof(s->framep));
 
-    if (free_mem) {
+    if (free_mem)
         free_buffers(s);
-        s->maps_are_invalid = 1;
-    }
 }
 
 static void vp8_decode_flush(AVCodecContext *avctx)
 {
-    vp8_decode_flush_impl(avctx, 1, 1, 0);
+    vp8_decode_flush_impl(avctx, 0);
 }
 
 static int update_dimensions(VP8Context *s, int width, int height)
 {
     AVCodecContext *avctx = s->avctx;
-    int i;
+    int i, ret;
 
     if (width  != s->avctx->width ||
         height != s->avctx->height) {
-        if (av_image_check_size(width, height, 0, s->avctx))
-            return AVERROR_INVALIDDATA;
-
-        vp8_decode_flush_impl(s->avctx, 1, 0, 1);
+        vp8_decode_flush_impl(s->avctx, 1);
 
-        avcodec_set_dimensions(s->avctx, width, height);
+        ret = ff_set_dimensions(s->avctx, width, height);
+        if (ret < 0)
+            return ret;
     }
 
     s->mb_width  = (s->avctx->coded_width +15) / 16;
@@ -346,7 +340,7 @@ static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
         buf_size -= 7;
 
         if (hscale || vscale)
-            av_log_missing_feature(s->avctx, "Upscaling", 1);
+            avpriv_request_sample(s->avctx, "Upscaling");
 
         s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
         for (i = 0; i < 4; i++)
@@ -764,7 +758,7 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
  * @return 0 if no coeffs were decoded
  *         otherwise, the index of the last coeff decoded plus one
  */
-static int decode_block_coeffs_internal(VP56RangeCoder *r, DCTELEM block[16],
+static int decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16],
                                         uint8_t probs[16][3][NUM_DCT_TOKENS-1],
                                         int i, uint8_t *token_prob, int16_t qmul[2])
 {
@@ -832,7 +826,7 @@ skip_eob:
  *         otherwise, the index of the last coeff decoded plus one
  */
 static av_always_inline
-int decode_block_coeffs(VP56RangeCoder *c, DCTELEM block[16],
+int decode_block_coeffs(VP56RangeCoder *c, int16_t block[16],
                         uint8_t probs[16][3][NUM_DCT_TOKENS-1],
                         int i, int zero_nhood, int16_t qmul[2])
 {
@@ -1182,12 +1176,12 @@ static const uint8_t subpel_idx[3][8] = {
  */
 static av_always_inline
 void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
-                 AVFrame *ref, const VP56mv *mv,
+                 ThreadFrame *ref, const VP56mv *mv,
                  int x_off, int y_off, int block_w, int block_h,
-                 int width, int height, int linesize,
+                 int width, int height, ptrdiff_t linesize,
                  vp8_mc_func mc_func[3][3])
 {
-    uint8_t *src = ref->data[0];
+    uint8_t *src = ref->f->data[0];
 
     if (AV_RN32A(mv)) {
 
@@ -1202,7 +1196,9 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
         src += y_off * linesize + x_off;
         if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
             y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
-            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,
+            s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+                                     src - my_idx * linesize - mx_idx,
+                                     linesize, linesize,
                                      block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
                                      x_off - mx_idx, y_off - my_idx, width, height);
             src = td->edge_emu_buffer + mx_idx + linesize * my_idx;
@@ -1233,11 +1229,11 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
  */
 static av_always_inline
 void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2,
-                   AVFrame *ref, const VP56mv *mv, int x_off, int y_off,
-                   int block_w, int block_h, int width, int height, int linesize,
+                   ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off,
+                   int block_w, int block_h, int width, int height, ptrdiff_t linesize,
                    vp8_mc_func mc_func[3][3])
 {
-    uint8_t *src1 = ref->data[1], *src2 = ref->data[2];
+    uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2];
 
     if (AV_RN32A(mv)) {
         int mx = mv->x&7, mx_idx = subpel_idx[0][mx];
@@ -1252,13 +1248,17 @@ void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst
         ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3, 0);
         if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
             y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
-            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src1 - my_idx * linesize - mx_idx, linesize,
+            s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+                                     src1 - my_idx * linesize - mx_idx,
+                                     linesize, linesize,
                                      block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
                                      x_off - mx_idx, y_off - my_idx, width, height);
             src1 = td->edge_emu_buffer + mx_idx + linesize * my_idx;
             mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
 
-            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src2 - my_idx * linesize - mx_idx, linesize,
+            s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+                                     src2 - my_idx * linesize - mx_idx,
+                                     linesize, linesize,
                                      block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
                                      x_off - mx_idx, y_off - my_idx, width, height);
             src2 = td->edge_emu_buffer + mx_idx + linesize * my_idx;
@@ -1276,7 +1276,7 @@ void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst
 
 static av_always_inline
 void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
-                 AVFrame *ref_frame, int x_off, int y_off,
+                 ThreadFrame *ref_frame, int x_off, int y_off,
                  int bx_off, int by_off,
                  int block_w, int block_h,
                  int width, int height, VP56mv *mv)
@@ -1314,7 +1314,7 @@ static av_always_inline void prefetch_motion(VP8Context *s, VP8Macroblock *mb, i
         int x_off = mb_x << 4, y_off = mb_y << 4;
         int mx = (mb->mv.x>>2) + x_off + 8;
         int my = (mb->mv.y>>2) + y_off;
-        uint8_t **src= s->framep[ref]->data;
+        uint8_t **src= s->framep[ref]->tf.f->data;
         int off= mx + (my + (mb_x&3)*4)*s->linesize + 64;
         /* For threading, a ff_thread_await_progress here might be useful, but
          * it actually slows down the decoder. Since a bad prefetch doesn't
@@ -1334,7 +1334,7 @@ void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
 {
     int x_off = mb_x << 4, y_off = mb_y << 4;
     int width = 16*s->mb_width, height = 16*s->mb_height;
-    AVFrame *ref = s->framep[mb->ref_frame];
+    ThreadFrame *ref = &s->framep[mb->ref_frame]->tf;
     VP56mv *bmv = mb->bmv;
 
     switch (mb->partitioning) {
@@ -1593,17 +1593,9 @@ static av_always_inline void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8Fi
     }
 }
 
-static void release_queued_segmaps(VP8Context *s, int is_close)
-{
-    int leave_behind = is_close ? 0 : !s->maps_are_invalid;
-    while (s->num_maps_to_be_freed > leave_behind)
-        av_freep(&s->segmentation_maps[--s->num_maps_to_be_freed]);
-    s->maps_are_invalid = 0;
-}
-
 #define MARGIN (16 << 2)
-static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe,
-                                   AVFrame *prev_frame)
+static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe,
+                                   VP8Frame *prev_frame)
 {
     VP8Context *s = avctx->priv_data;
     int mb_x, mb_y;
@@ -1621,8 +1613,9 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe,
         for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
             if (mb_y == 0)
                 AV_WN32A((mb-s->mb_width-1)->intra4x4_pred_mode_top, DC_PRED*0x01010101);
-            decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy,
-                           prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL, 1);
+            decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
+                           prev_frame && prev_frame->seg_map ?
+                           prev_frame->seg_map->data + mb_xy : NULL, 1);
             s->mv_min.x -= 64;
             s->mv_max.x -= 64;
         }
@@ -1676,13 +1669,13 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
     int mb_y = td->thread_mb_pos>>16;
     int i, y, mb_x, mb_xy = mb_y*s->mb_width;
     int num_jobs = s->num_jobs;
-    AVFrame *curframe = s->curframe, *prev_frame = s->prev_frame;
+    VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame;
     VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions-1)];
     VP8Macroblock *mb;
     uint8_t *dst[3] = {
-        curframe->data[0] + 16*mb_y*s->linesize,
-        curframe->data[1] +  8*mb_y*s->uvlinesize,
-        curframe->data[2] +  8*mb_y*s->uvlinesize
+        curframe->tf.f->data[0] + 16*mb_y*s->linesize,
+        curframe->tf.f->data[1] +  8*mb_y*s->uvlinesize,
+        curframe->tf.f->data[2] +  8*mb_y*s->uvlinesize
     };
     if (mb_y == 0) prev_td = td;
     else           prev_td = &s->thread_data[(jobnr + num_jobs - 1)%num_jobs];
@@ -1691,6 +1684,11 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
     if (s->mb_layout == 1)
         mb = s->macroblocks_base + ((s->mb_width+1)*(mb_y + 1) + 1);
     else {
+        // Make sure the previous frame has read its segmentation map,
+        // if we re-use the same map.
+        if (prev_frame && s->segmentation.enabled &&
+            !s->segmentation.update_map)
+            ff_thread_await_progress(&prev_frame->tf, mb_y, 0);
         mb = s->macroblocks + (s->mb_height - mb_y - 1)*2;
         memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock
         AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED*0x01010101);
@@ -1701,7 +1699,7 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
     if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
         for (i = 0; i < 3; i++)
             for (y = 0; y < 16>>!!i; y++)
-                dst[i][y*curframe->linesize[i]-1] = 129;
+                dst[i][y*curframe->tf.f->linesize[i]-1] = 129;
         if (mb_y == 1) {
             s->top_border[0][15] = s->top_border[0][23] = s->top_border[0][31] = 129;
         }
@@ -1724,8 +1722,9 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
         s->vdsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2);
 
         if (!s->mb_layout)
-            decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy,
-                           prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL, 0);
+            decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
+                           prev_frame && prev_frame->seg_map ?
+                           prev_frame->seg_map->data + mb_xy : NULL, 0);
 
         prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);
 
@@ -1784,7 +1783,7 @@ static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata,
     VP8Context *s = avctx->priv_data;
     VP8ThreadData *td = &s->thread_data[threadnr];
     int mb_x, mb_y = td->thread_mb_pos>>16, num_jobs = s->num_jobs;
-    AVFrame *curframe = s->curframe;
+    AVFrame *curframe = s->curframe->tf.f;
     VP8Macroblock *mb;
     VP8ThreadData *prev_td, *next_td;
     uint8_t *dst[3] = {
@@ -1838,7 +1837,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
     VP8Context *s = avctx->priv_data;
     VP8ThreadData *td = &s->thread_data[jobnr];
     VP8ThreadData *next_td = NULL, *prev_td = NULL;
-    AVFrame *curframe = s->curframe;
+    VP8Frame *curframe = s->curframe;
     int mb_y, num_jobs = s->num_jobs;
     td->thread_nr = threadnr;
     for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
@@ -1853,21 +1852,19 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
         s->mv_max.y -= 64;
 
         if (avctx->active_thread_type == FF_THREAD_FRAME)
-            ff_thread_report_progress(curframe, mb_y, 0);
+            ff_thread_report_progress(&curframe->tf, mb_y, 0);
     }
 
     return 0;
 }
 
-static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                            AVPacket *avpkt)
+int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt)
 {
     VP8Context *s = avctx->priv_data;
     int ret, i, referenced, num_jobs;
     enum AVDiscard skip_thresh;
-    AVFrame *av_uninit(curframe), *prev_frame;
-
-    release_queued_segmaps(s, 0);
+    VP8Frame *av_uninit(curframe), *prev_frame;
 
     if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0)
         goto err;
@@ -1889,12 +1886,12 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     // release no longer referenced frames
     for (i = 0; i < 5; i++)
-        if (s->frames[i].data[0] &&
+        if (s->frames[i].tf.f->data[0] &&
             &s->frames[i] != prev_frame &&
             &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2])
-            vp8_release_frame(s, &s->frames[i], 1, 0);
+            vp8_release_frame(s, &s->frames[i]);
 
     // find a free buffer
     for (i = 0; i < 5; i++)
@@ -1909,8 +1906,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
         abort();
     }
-    if (curframe->data[0])
-        vp8_release_frame(s, curframe, 1, 0);
+    if (curframe->tf.f->data[0])
+        vp8_release_frame(s, curframe);
 
     // Given that arithmetic probabilities are updated every frame, it's quite likely
     // that the values we have on a random interframe are complete junk if we didn't
@@ -1923,10 +1920,9 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         goto err;
     }
 
-    curframe->key_frame = s->keyframe;
-    curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
-    curframe->reference = referenced ? 3 : 0;
-    if ((ret = vp8_alloc_frame(s, curframe))) {
+    curframe->tf.f->key_frame = s->keyframe;
+    curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    if ((ret = vp8_alloc_frame(s, curframe, referenced))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
         goto err;
     }
@@ -1951,8 +1947,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     ff_thread_finish_setup(avctx);
 
-    s->linesize   = curframe->linesize[0];
-    s->uvlinesize = curframe->linesize[1];
+    s->linesize   = curframe->tf.f->linesize[0];
+    s->uvlinesize = curframe->tf.f->linesize[1];
 
     if (!s->thread_data[0].edge_emu_buffer)
         for (i = 0; i < MAX_THREADS; i++)
@@ -1974,13 +1970,14 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     memset(s->ref_count, 0, sizeof(s->ref_count));
 
 
-    // Make sure the previous frame has read its segmentation map,
-    // if we re-use the same map.
-    if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map)
-        ff_thread_await_progress(prev_frame, 1, 0);
-
-    if (s->mb_layout == 1)
+    if (s->mb_layout == 1) {
+        // Make sure the previous frame has read its segmentation map,
+        // if we re-use the same map.
+        if (prev_frame && s->segmentation.enabled &&
+            !s->segmentation.update_map)
+            ff_thread_await_progress(&prev_frame->tf, 1, 0);
         vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
+    }
 
     if (avctx->active_thread_type == FF_THREAD_FRAME)
         num_jobs = 1;
@@ -1997,7 +1994,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
     avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, num_jobs);
 
-    ff_thread_report_progress(curframe, INT_MAX, 0);
+    ff_thread_report_progress(&curframe->tf, INT_MAX, 0);
     memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
 
 skip_decode:
@@ -2007,7 +2004,8 @@ skip_decode:
         s->prob[0] = s->prob[1];
 
     if (!s->invisible) {
-        *(AVFrame*)data = *curframe;
+        if ((ret = av_frame_ref(data, curframe->tf.f)) < 0)
+            return ret;
         *got_frame      = 1;
     }
 
@@ -2017,33 +2015,62 @@ err:
     return ret;
 }
 
-static av_cold int vp8_decode_init(AVCodecContext *avctx)
+av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
 {
     VP8Context *s = avctx->priv_data;
+    int i;
+
+    vp8_decode_flush_impl(avctx, 1);
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+        av_frame_free(&s->frames[i].tf.f);
+
+    return 0;
+}
+
+static av_cold int vp8_init_frames(VP8Context *s)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
+        s->frames[i].tf.f = av_frame_alloc();
+        if (!s->frames[i].tf.f)
+            return AVERROR(ENOMEM);
+    }
+    return 0;
+}
+
+av_cold int ff_vp8_decode_init(AVCodecContext *avctx)
+{
+    VP8Context *s = avctx->priv_data;
+    int ret;
 
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    avctx->internal->allocate_progress = 1;
 
     ff_videodsp_init(&s->vdsp, 8);
     ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1);
     ff_vp8dsp_init(&s->vp8dsp);
 
-    return 0;
-}
+    if ((ret = vp8_init_frames(s)) < 0) {
+        ff_vp8_decode_free(avctx);
+        return ret;
+    }
 
-static av_cold int vp8_decode_free(AVCodecContext *avctx)
-{
-    vp8_decode_flush_impl(avctx, 0, 1, 1);
-    release_queued_segmaps(avctx->priv_data, 1);
     return 0;
 }
 
 static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
 {
     VP8Context *s = avctx->priv_data;
+    int ret;
 
     s->avctx = avctx;
 
+    if ((ret = vp8_init_frames(s)) < 0) {
+        ff_vp8_decode_free(avctx);
+        return ret;
+    }
+
     return 0;
 }
 
@@ -2053,11 +2080,11 @@ static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
 static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
 {
     VP8Context *s = dst->priv_data, *s_src = src->priv_data;
+    int i;
 
     if (s->macroblocks_base &&
         (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) {
         free_buffers(s);
-        s->maps_are_invalid = 1;
         s->mb_width  = s_src->mb_width;
         s->mb_height = s_src->mb_height;
     }
@@ -2067,7 +2094,14 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
     s->lf_delta = s_src->lf_delta;
     memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias));
 
-    memcpy(&s->frames, &s_src->frames, sizeof(s->frames));
+    for (i = 0; i < FF_ARRAY_ELEMS(s_src->frames); i++) {
+        if (s_src->frames[i].tf.f->data[0]) {
+            int ret = vp8_ref_frame(s, &s->frames[i], &s_src->frames[i]);
+            if (ret < 0)
+                return ret;
+        }
+    }
+
     s->framep[0] = REBASE(s_src->next_framep[0]);
     s->framep[1] = REBASE(s_src->next_framep[1]);
     s->framep[2] = REBASE(s_src->next_framep[2]);
@@ -2078,15 +2112,15 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
 
 AVCodec ff_vp8_decoder = {
     .name                  = "vp8",
+    .long_name             = NULL_IF_CONFIG_SMALL("On2 VP8"),
     .type                  = AVMEDIA_TYPE_VIDEO,
     .id                    = AV_CODEC_ID_VP8,
     .priv_data_size        = sizeof(VP8Context),
-    .init                  = vp8_decode_init,
-    .close                 = vp8_decode_free,
-    .decode                = vp8_decode_frame,
+    .init                  = ff_vp8_decode_init,
+    .close                 = ff_vp8_decode_free,
+    .decode                = ff_vp8_decode_frame,
     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
     .flush                 = vp8_decode_flush,
-    .long_name             = NULL_IF_CONFIG_SMALL("On2 VP8"),
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
 };
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index 4a85541..6555629 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -26,14 +26,16 @@
 #ifndef AVCODEC_VP8_H
 #define AVCODEC_VP8_H
 
+#include "libavutil/buffer.h"
+
 #include "vp56.h"
-#include "vp56data.h"
 #include "vp8dsp.h"
 #include "h264pred.h"
+#include "thread.h"
 #if HAVE_PTHREADS
 #include <pthread.h>
 #elif HAVE_W32THREADS
-#include "w32pthreads.h"
+#include "compat/w32pthreads.h"
 #endif
 
 #define VP8_MAX_QUANT 127
@@ -94,8 +96,8 @@ typedef struct VP8Macroblock {
 } VP8Macroblock;
 
 typedef struct VP8ThreadData {
-    DECLARE_ALIGNED(16, DCTELEM, block)[6][4][16];
-    DECLARE_ALIGNED(16, DCTELEM, block_dc)[16];
+    DECLARE_ALIGNED(16, int16_t, block)[6][4][16];
+    DECLARE_ALIGNED(16, int16_t, block_dc)[16];
     /**
      * This is the index plus one of the last non-zero coeff
      * for each of the blocks in the current macroblock.
@@ -122,14 +124,19 @@ typedef struct VP8ThreadData {
     VP8FilterStrength *filter_strength;
 } VP8ThreadData;
 
+typedef struct VP8Frame {
+    ThreadFrame tf;
+    AVBufferRef *seg_map;
+} VP8Frame;
+
 #define MAX_THREADS 8
 typedef struct VP8Context {
     VP8ThreadData *thread_data;
     AVCodecContext *avctx;
-    AVFrame *framep[4];
-    AVFrame *next_framep[4];
-    AVFrame *curframe;
-    AVFrame *prev_frame;
+    VP8Frame *framep[4];
+    VP8Frame *next_framep[4];
+    VP8Frame *curframe;
+    VP8Frame *prev_frame;
 
     uint16_t mb_width;   /* number of horizontal MB */
     uint16_t mb_height;  /* number of vertical MB */
@@ -251,17 +258,8 @@ typedef struct VP8Context {
     VP8DSPContext vp8dsp;
     H264PredContext hpc;
     vp8_mc_func put_pixels_tab[3][3][3];
-    AVFrame frames[5];
+    VP8Frame frames[5];
 
-    /**
-     * A list of segmentation_map buffers that are to be free()'ed in
-     * the next decoding iteration. We can't free() them right away
-     * because the map may still be used by subsequent decoding threads.
-     * Unused if frame threading is off.
-     */
-    uint8_t *segmentation_maps[5];
-    int num_maps_to_be_freed;
-    int maps_are_invalid;
     int num_jobs;
     /**
      * This describes the macroblock memory layout.
@@ -271,4 +269,11 @@ typedef struct VP8Context {
     int mb_layout;
 } VP8Context;
 
+int ff_vp8_decode_init(AVCodecContext *avctx);
+
+int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                        AVPacket *avpkt);
+
+int ff_vp8_decode_free(AVCodecContext *avctx);
+
 #endif /* AVCODEC_VP8_H */
diff --git a/libavcodec/vp8dsp.c b/libavcodec/vp8dsp.c
index 2ab68bc..34e2da0 100644
--- a/libavcodec/vp8dsp.c
+++ b/libavcodec/vp8dsp.c
@@ -29,7 +29,7 @@
 #include "libavutil/common.h"
 
 // TODO: Maybe add dequant
-static void vp8_luma_dc_wht_c(DCTELEM block[4][4][16], DCTELEM dc[16])
+static void vp8_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16])
 {
     int i, t0, t1, t2, t3;
 
@@ -62,7 +62,7 @@ static void vp8_luma_dc_wht_c(DCTELEM block[4][4][16], DCTELEM dc[16])
     }
 }
 
-static void vp8_luma_dc_wht_dc_c(DCTELEM block[4][4][16], DCTELEM dc[16])
+static void vp8_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16])
 {
     int i, val = (dc[0] + 3) >> 3;
     dc[0] = 0;
@@ -78,10 +78,10 @@ static void vp8_luma_dc_wht_dc_c(DCTELEM block[4][4][16], DCTELEM dc[16])
 #define MUL_20091(a) ((((a)*20091) >> 16) + (a))
 #define MUL_35468(a)  (((a)*35468) >> 16)
 
-static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride)
+static void vp8_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
 {
     int i, t0, t1, t2, t3;
-    DCTELEM tmp[16];
+    int16_t tmp[16];
 
     for (i = 0; i < 4; i++) {
         t0 = block[0*4+i] + block[2*4+i];
@@ -113,7 +113,7 @@ static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride)
     }
 }
 
-static void vp8_idct_dc_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride)
+static void vp8_idct_dc_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
 {
     int i, dc = (block[0] + 4) >> 3;
     block[0] = 0;
@@ -127,7 +127,7 @@ static void vp8_idct_dc_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride)
     }
 }
 
-static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride)
+static void vp8_idct_dc_add4uv_c(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride)
 {
     vp8_idct_dc_add_c(dst+stride*0+0, block[0], stride);
     vp8_idct_dc_add_c(dst+stride*0+4, block[1], stride);
@@ -135,7 +135,7 @@ static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t s
     vp8_idct_dc_add_c(dst+stride*4+4, block[3], stride);
 }
 
-static void vp8_idct_dc_add4y_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride)
+static void vp8_idct_dc_add4y_c(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride)
 {
     vp8_idct_dc_add_c(dst+ 0, block[0], stride);
     vp8_idct_dc_add_c(dst+ 4, block[1], stride);
@@ -160,7 +160,7 @@ static av_always_inline void filter_common(uint8_t *p, ptrdiff_t stride, int is4
 {
     LOAD_PIXELS
     int a, f1, f2;
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
 
     a = 3*(q0 - p0);
 
@@ -215,7 +215,7 @@ static av_always_inline int hev(uint8_t *p, ptrdiff_t stride, int thresh)
 static av_always_inline void filter_mbedge(uint8_t *p, ptrdiff_t stride)
 {
     int a0, a1, a2, w;
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
 
     LOAD_PIXELS
 
@@ -337,7 +337,7 @@ PUT_PIXELS(4)
 static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \
 { \
     const uint8_t *filter = subpel_filters[mx-1]; \
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
     int x, y; \
 \
     for (y = 0; y < h; y++) { \
@@ -351,7 +351,7 @@ static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, ptrdiff_t dst
 static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \
 { \
     const uint8_t *filter = subpel_filters[my-1]; \
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
     int x, y; \
 \
     for (y = 0; y < h; y++) { \
@@ -365,7 +365,7 @@ static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, ptrdiff_t dst
 static void put_vp8_epel ## SIZE ## _h ## HTAPS ## v ## VTAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \
 { \
     const uint8_t *filter = subpel_filters[mx-1]; \
-    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
     int x, y; \
     uint8_t tmp_array[(2*SIZE+VTAPS-1)*SIZE]; \
     uint8_t *tmp = tmp_array; \
@@ -521,10 +521,10 @@ av_cold void ff_vp8dsp_init(VP8DSPContext *dsp)
     VP8_BILINEAR_MC_FUNC(1, 8);
     VP8_BILINEAR_MC_FUNC(2, 4);
 
-    if (ARCH_X86)
-        ff_vp8dsp_init_x86(dsp);
-    if (HAVE_ALTIVEC)
-        ff_vp8dsp_init_altivec(dsp);
     if (ARCH_ARM)
         ff_vp8dsp_init_arm(dsp);
+    if (ARCH_PPC)
+        ff_vp8dsp_init_ppc(dsp);
+    if (ARCH_X86)
+        ff_vp8dsp_init_x86(dsp);
 }
diff --git a/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h
index bce0062..877e264 100644
--- a/libavcodec/vp8dsp.h
+++ b/libavcodec/vp8dsp.h
@@ -27,20 +27,21 @@
 #ifndef AVCODEC_VP8DSP_H
 #define AVCODEC_VP8DSP_H
 
-#include "dsputil.h"
+#include <stddef.h>
+#include <stdint.h>
 
 typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, ptrdiff_t dstStride,
                             uint8_t *src/*align 1*/, ptrdiff_t srcStride,
                             int h, int x, int y);
 
 typedef struct VP8DSPContext {
-    void (*vp8_luma_dc_wht)(DCTELEM block[4][4][16], DCTELEM dc[16]);
-    void (*vp8_luma_dc_wht_dc)(DCTELEM block[4][4][16], DCTELEM dc[16]);
-    void (*vp8_idct_add)(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-    void (*vp8_idct_dc_add)(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride);
-    void (*vp8_idct_dc_add4y)(uint8_t *dst, DCTELEM block[4][16],
+    void (*vp8_luma_dc_wht)(int16_t block[4][4][16], int16_t dc[16]);
+    void (*vp8_luma_dc_wht_dc)(int16_t block[4][4][16], int16_t dc[16]);
+    void (*vp8_idct_add)(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+    void (*vp8_idct_dc_add)(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+    void (*vp8_idct_dc_add4y)(uint8_t *dst, int16_t block[4][16],
                               ptrdiff_t stride);
-    void (*vp8_idct_dc_add4uv)(uint8_t *dst, DCTELEM block[4][16],
+    void (*vp8_idct_dc_add4uv)(uint8_t *dst, int16_t block[4][16],
                                ptrdiff_t stride);
 
     // loop filter applied to edges between macroblocks
@@ -89,7 +90,7 @@ void ff_put_vp8_pixels4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride,
 
 void ff_vp8dsp_init(VP8DSPContext *c);
 void ff_vp8dsp_init_x86(VP8DSPContext *c);
-void ff_vp8dsp_init_altivec(VP8DSPContext *c);
 void ff_vp8dsp_init_arm(VP8DSPContext *c);
+void ff_vp8dsp_init_ppc(VP8DSPContext *c);
 
 #endif /* AVCODEC_VP8DSP_H */
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
new file mode 100644
index 0000000..9048700
--- /dev/null
+++ b/libavcodec/vp9.c
@@ -0,0 +1,1270 @@
+/*
+ * VP9 compatible video decoder
+ *
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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/avassert.h"
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "videodsp.h"
+#include "vp56.h"
+#include "vp9.h"
+#include "vp9data.h"
+
+#define VP9_SYNCCODE 0x498342
+#define MAX_PROB 255
+
+static void vp9_decode_flush(AVCodecContext *avctx)
+{
+    VP9Context *s = avctx->priv_data;
+    int i;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++)
+        av_frame_unref(s->refs[i]);
+}
+
+static int update_size(AVCodecContext *avctx, int w, int h)
+{
+    VP9Context *s = avctx->priv_data;
+    uint8_t *p;
+
+    if (s->above_partition_ctx && w == avctx->width && h == avctx->height)
+        return 0;
+
+    vp9_decode_flush(avctx);
+
+    if (w <= 0 || h <= 0)
+        return AVERROR_INVALIDDATA;
+
+    avctx->width  = w;
+    avctx->height = h;
+    s->sb_cols    = (w + 63) >> 6;
+    s->sb_rows    = (h + 63) >> 6;
+    s->cols       = (w +  7) >> 3;
+    s->rows       = (h +  7) >> 3;
+
+#define assign(var, type, n) var = (type)p; p += s->sb_cols * n * sizeof(*var)
+    av_free(s->above_partition_ctx);
+    p = av_malloc(s->sb_cols *
+                  (240 + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx) +
+                   64 * s->sb_rows * (1 + sizeof(*s->mv[0]) * 2)));
+    if (!p)
+        return AVERROR(ENOMEM);
+    assign(s->above_partition_ctx, uint8_t *,     8);
+    assign(s->above_skip_ctx,      uint8_t *,     8);
+    assign(s->above_txfm_ctx,      uint8_t *,     8);
+    assign(s->above_mode_ctx,      uint8_t *,    16);
+    assign(s->above_y_nnz_ctx,     uint8_t *,    16);
+    assign(s->above_uv_nnz_ctx[0], uint8_t *,     8);
+    assign(s->above_uv_nnz_ctx[1], uint8_t *,     8);
+    assign(s->intra_pred_data[0],  uint8_t *,    64);
+    assign(s->intra_pred_data[1],  uint8_t *,    32);
+    assign(s->intra_pred_data[2],  uint8_t *,    32);
+    assign(s->above_segpred_ctx,   uint8_t *,     8);
+    assign(s->above_intra_ctx,     uint8_t *,     8);
+    assign(s->above_comp_ctx,      uint8_t *,     8);
+    assign(s->above_ref_ctx,       uint8_t *,     8);
+    assign(s->above_filter_ctx,    uint8_t *,     8);
+    assign(s->lflvl,               VP9Filter *,   1);
+    assign(s->above_mv_ctx,        VP56mv(*)[2], 16);
+    assign(s->segmentation_map,    uint8_t *,      64 * s->sb_rows);
+    assign(s->mv[0],               VP9MVRefPair *, 64 * s->sb_rows);
+    assign(s->mv[1],               VP9MVRefPair *, 64 * s->sb_rows);
+#undef assign
+
+    return 0;
+}
+
+// The sign bit is at the end, not the start, of a bit sequence
+static av_always_inline int get_bits_with_sign(GetBitContext *gb, int n)
+{
+    int v = get_bits(gb, n);
+    return get_bits1(gb) ? -v : v;
+}
+
+static av_always_inline int inv_recenter_nonneg(int v, int m)
+{
+    if (v > 2 * m)
+        return v;
+    if (v & 1)
+        return m - ((v + 1) >> 1);
+    return m + (v >> 1);
+}
+
+// differential forward probability updates
+static int update_prob(VP56RangeCoder *c, int p)
+{
+    static const int inv_map_table[MAX_PROB - 1] = {
+          7,  20,  33,  46,  59,  72,  85,  98, 111, 124, 137, 150, 163, 176,
+        189, 202, 215, 228, 241, 254,   1,   2,   3,   4,   5,   6,   8,   9,
+         10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  21,  22,  23,  24,
+         25,  26,  27,  28,  29,  30,  31,  32,  34,  35,  36,  37,  38,  39,
+         40,  41,  42,  43,  44,  45,  47,  48,  49,  50,  51,  52,  53,  54,
+         55,  56,  57,  58,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
+         70,  71,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,
+         86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  99, 100,
+        101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115,
+        116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130,
+        131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145,
+        146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
+        161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+        177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, 191,
+        192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206,
+        207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221,
+        222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236,
+        237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
+        252, 253,
+    };
+    int d;
+
+    /* This code is trying to do a differential probability update. For a
+     * current probability A in the range [1, 255], the difference to a new
+     * probability of any value can be expressed differentially as 1-A, 255-A
+     * where some part of this (absolute range) exists both in positive as
+     * well as the negative part, whereas another part only exists in one
+     * half. We're trying to code this shared part differentially, i.e.
+     * times two where the value of the lowest bit specifies the sign, and
+     * the single part is then coded on top of this. This absolute difference
+     * then again has a value of [0, 254], but a bigger value in this range
+     * indicates that we're further away from the original value A, so we
+     * can code this as a VLC code, since higher values are increasingly
+     * unlikely. The first 20 values in inv_map_table[] allow 'cheap, rough'
+     * updates vs. the 'fine, exact' updates further down the range, which
+     * adds one extra dimension to this differential update model. */
+
+    if (!vp8_rac_get(c)) {
+        d = vp8_rac_get_uint(c, 4) + 0;
+    } else if (!vp8_rac_get(c)) {
+        d = vp8_rac_get_uint(c, 4) + 16;
+    } else if (!vp8_rac_get(c)) {
+        d = vp8_rac_get_uint(c, 5) + 32;
+    } else {
+        d = vp8_rac_get_uint(c, 7);
+        if (d >= 65) {
+            d = (d << 1) - 65 + vp8_rac_get(c);
+            d = av_clip(d, 0, MAX_PROB - 65 - 1);
+        }
+        d += 64;
+    }
+
+    return p <= 128
+           ?   1 + inv_recenter_nonneg(inv_map_table[d], p - 1)
+           : 255 - inv_recenter_nonneg(inv_map_table[d], 255 - p);
+}
+
+static int decode_frame_header(AVCodecContext *avctx,
+                               const uint8_t *data, int size, int *ref)
+{
+    VP9Context *s = avctx->priv_data;
+    int c, i, j, k, l, m, n, w, h, max, size2, ret, sharp;
+    int last_invisible;
+    const uint8_t *data2;
+
+    /* general header */
+    if ((ret = init_get_bits8(&s->gb, data, size)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n");
+        return ret;
+    }
+    if (get_bits(&s->gb, 2) != 0x2) { // frame marker
+        av_log(avctx, AV_LOG_ERROR, "Invalid frame marker\n");
+        return AVERROR_INVALIDDATA;
+    }
+    s->profile = get_bits1(&s->gb);
+    if (get_bits1(&s->gb)) { // reserved bit
+        av_log(avctx, AV_LOG_ERROR, "Reserved bit should be zero\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (get_bits1(&s->gb)) {
+        *ref = get_bits(&s->gb, 3);
+        return 0;
+    }
+
+    s->last_keyframe = s->keyframe;
+    s->keyframe      = !get_bits1(&s->gb);
+
+    last_invisible = s->invisible;
+    s->invisible   = !get_bits1(&s->gb);
+    s->errorres    = get_bits1(&s->gb);
+    // FIXME disable this upon resolution change
+    s->use_last_frame_mvs = !s->errorres && !last_invisible;
+
+    if (s->keyframe) {
+        if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
+            av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n");
+            return AVERROR_INVALIDDATA;
+        }
+        s->colorspace = get_bits(&s->gb, 3);
+        if (s->colorspace == 7) { // RGB = profile 1
+            av_log(avctx, AV_LOG_ERROR, "RGB not supported in profile 0\n");
+            return AVERROR_INVALIDDATA;
+        }
+        s->fullrange = get_bits1(&s->gb);
+        // for profile 1, here follows the subsampling bits
+        s->refreshrefmask = 0xff;
+        w = get_bits(&s->gb, 16) + 1;
+        h = get_bits(&s->gb, 16) + 1;
+        if (get_bits1(&s->gb)) // display size
+            skip_bits(&s->gb, 32);
+    } else {
+        s->intraonly = s->invisible ? get_bits1(&s->gb) : 0;
+        s->resetctx  = s->errorres ? 0 : get_bits(&s->gb, 2);
+        if (s->intraonly) {
+            if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
+                av_log(avctx, AV_LOG_ERROR, "Invalid sync code\n");
+                return AVERROR_INVALIDDATA;
+            }
+            s->refreshrefmask = get_bits(&s->gb, 8);
+            w = get_bits(&s->gb, 16) + 1;
+            h = get_bits(&s->gb, 16) + 1;
+            if (get_bits1(&s->gb)) // display size
+                skip_bits(&s->gb, 32);
+        } else {
+            s->refreshrefmask = get_bits(&s->gb, 8);
+            s->refidx[0]      = get_bits(&s->gb, 3);
+            s->signbias[0]    = get_bits1(&s->gb);
+            s->refidx[1]      = get_bits(&s->gb, 3);
+            s->signbias[1]    = get_bits1(&s->gb);
+            s->refidx[2]      = get_bits(&s->gb, 3);
+            s->signbias[2]    = get_bits1(&s->gb);
+            if (!s->refs[s->refidx[0]]->buf[0] ||
+                !s->refs[s->refidx[1]]->buf[0] ||
+                !s->refs[s->refidx[2]]->buf[0]) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Not all references are available\n");
+                return AVERROR_INVALIDDATA;
+            }
+            if (get_bits1(&s->gb)) {
+                w = s->refs[s->refidx[0]]->width;
+                h = s->refs[s->refidx[0]]->height;
+            } else if (get_bits1(&s->gb)) {
+                w = s->refs[s->refidx[1]]->width;
+                h = s->refs[s->refidx[1]]->height;
+            } else if (get_bits1(&s->gb)) {
+                w = s->refs[s->refidx[2]]->width;
+                h = s->refs[s->refidx[2]]->height;
+            } else {
+                w = get_bits(&s->gb, 16) + 1;
+                h = get_bits(&s->gb, 16) + 1;
+            }
+            if (get_bits1(&s->gb)) // display size
+                skip_bits(&s->gb, 32);
+            s->highprecisionmvs = get_bits1(&s->gb);
+            s->filtermode       = get_bits1(&s->gb) ? FILTER_SWITCHABLE :
+                                  get_bits(&s->gb, 2);
+            s->allowcompinter   = s->signbias[0] != s->signbias[1] ||
+                                  s->signbias[0] != s->signbias[2];
+            if (s->allowcompinter) {
+                if (s->signbias[0] == s->signbias[1]) {
+                    s->fixcompref    = 2;
+                    s->varcompref[0] = 0;
+                    s->varcompref[1] = 1;
+                } else if (s->signbias[0] == s->signbias[2]) {
+                    s->fixcompref    = 1;
+                    s->varcompref[0] = 0;
+                    s->varcompref[1] = 2;
+                } else {
+                    s->fixcompref    = 0;
+                    s->varcompref[0] = 1;
+                    s->varcompref[1] = 2;
+                }
+            }
+        }
+    }
+
+    s->refreshctx   = s->errorres ? 0 : get_bits1(&s->gb);
+    s->parallelmode = s->errorres ? 1 : get_bits1(&s->gb);
+    s->framectxid   = c = get_bits(&s->gb, 2);
+
+    /* loopfilter header data */
+    s->filter.level = get_bits(&s->gb, 6);
+    sharp           = get_bits(&s->gb, 3);
+    /* If sharpness changed, reinit lim/mblim LUTs. if it didn't change,
+     * keep the old cache values since they are still valid. */
+    if (s->filter.sharpness != sharp)
+        memset(s->filter.lim_lut, 0, sizeof(s->filter.lim_lut));
+    s->filter.sharpness = sharp;
+    if ((s->lf_delta.enabled = get_bits1(&s->gb))) {
+        if (get_bits1(&s->gb)) {
+            for (i = 0; i < 4; i++)
+                if (get_bits1(&s->gb))
+                    s->lf_delta.ref[i] = get_bits_with_sign(&s->gb, 6);
+            for (i = 0; i < 2; i++)
+                if (get_bits1(&s->gb))
+                    s->lf_delta.mode[i] = get_bits_with_sign(&s->gb, 6);
+        }
+    } else {
+        memset(&s->lf_delta, 0, sizeof(s->lf_delta));
+    }
+
+    /* quantization header data */
+    s->yac_qi      = get_bits(&s->gb, 8);
+    s->ydc_qdelta  = get_bits1(&s->gb) ? get_bits_with_sign(&s->gb, 4) : 0;
+    s->uvdc_qdelta = get_bits1(&s->gb) ? get_bits_with_sign(&s->gb, 4) : 0;
+    s->uvac_qdelta = get_bits1(&s->gb) ? get_bits_with_sign(&s->gb, 4) : 0;
+    s->lossless    = s->yac_qi == 0 && s->ydc_qdelta == 0 &&
+                     s->uvdc_qdelta == 0 && s->uvac_qdelta == 0;
+
+    /* segmentation header info */
+    if ((s->segmentation.enabled = get_bits1(&s->gb))) {
+        if ((s->segmentation.update_map = get_bits1(&s->gb))) {
+            for (i = 0; i < 7; i++)
+                s->prob.seg[i] = get_bits1(&s->gb) ?
+                                 get_bits(&s->gb, 8) : 255;
+            if ((s->segmentation.temporal = get_bits1(&s->gb)))
+                for (i = 0; i < 3; i++)
+                    s->prob.segpred[i] = get_bits1(&s->gb) ?
+                                         get_bits(&s->gb, 8) : 255;
+        }
+
+        if (get_bits1(&s->gb)) {
+            s->segmentation.absolute_vals = get_bits1(&s->gb);
+            for (i = 0; i < 8; i++) {
+                if ((s->segmentation.feat[i].q_enabled = get_bits1(&s->gb)))
+                    s->segmentation.feat[i].q_val = get_bits_with_sign(&s->gb, 8);
+                if ((s->segmentation.feat[i].lf_enabled = get_bits1(&s->gb)))
+                    s->segmentation.feat[i].lf_val = get_bits_with_sign(&s->gb, 6);
+                if ((s->segmentation.feat[i].ref_enabled = get_bits1(&s->gb)))
+                    s->segmentation.feat[i].ref_val = get_bits(&s->gb, 2);
+                s->segmentation.feat[i].skip_enabled = get_bits1(&s->gb);
+            }
+        }
+    } else {
+        s->segmentation.feat[0].q_enabled    = 0;
+        s->segmentation.feat[0].lf_enabled   = 0;
+        s->segmentation.feat[0].skip_enabled = 0;
+        s->segmentation.feat[0].ref_enabled  = 0;
+    }
+
+    // set qmul[] based on Y/UV, AC/DC and segmentation Q idx deltas
+    for (i = 0; i < (s->segmentation.enabled ? 8 : 1); i++) {
+        int qyac, qydc, quvac, quvdc, lflvl, sh;
+
+        if (s->segmentation.feat[i].q_enabled) {
+            if (s->segmentation.absolute_vals)
+                qyac = s->segmentation.feat[i].q_val;
+            else
+                qyac = s->yac_qi + s->segmentation.feat[i].q_val;
+        } else {
+            qyac = s->yac_qi;
+        }
+        qydc  = av_clip_uintp2(qyac + s->ydc_qdelta, 8);
+        quvdc = av_clip_uintp2(qyac + s->uvdc_qdelta, 8);
+        quvac = av_clip_uintp2(qyac + s->uvac_qdelta, 8);
+        qyac  = av_clip_uintp2(qyac, 8);
+
+        s->segmentation.feat[i].qmul[0][0] = ff_vp9_dc_qlookup[qydc];
+        s->segmentation.feat[i].qmul[0][1] = ff_vp9_ac_qlookup[qyac];
+        s->segmentation.feat[i].qmul[1][0] = ff_vp9_dc_qlookup[quvdc];
+        s->segmentation.feat[i].qmul[1][1] = ff_vp9_ac_qlookup[quvac];
+
+        sh = s->filter.level >= 32;
+        if (s->segmentation.feat[i].lf_enabled) {
+            if (s->segmentation.absolute_vals)
+                lflvl = s->segmentation.feat[i].lf_val;
+            else
+                lflvl = s->filter.level + s->segmentation.feat[i].lf_val;
+        } else {
+            lflvl = s->filter.level;
+        }
+        s->segmentation.feat[i].lflvl[0][0] =
+        s->segmentation.feat[i].lflvl[0][1] =
+            av_clip_uintp2(lflvl + (s->lf_delta.ref[0] << sh), 6);
+        for (j = 1; j < 4; j++) {
+            s->segmentation.feat[i].lflvl[j][0] =
+                av_clip_uintp2(lflvl + ((s->lf_delta.ref[j] +
+                                         s->lf_delta.mode[0]) << sh), 6);
+            s->segmentation.feat[i].lflvl[j][1] =
+                av_clip_uintp2(lflvl + ((s->lf_delta.ref[j] +
+                                         s->lf_delta.mode[1]) << sh), 6);
+        }
+    }
+
+    /* tiling info */
+    if ((ret = update_size(avctx, w, h)) < 0) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Failed to initialize decoder for %dx%d\n", w, h);
+        return ret;
+    }
+    for (s->tiling.log2_tile_cols = 0;
+         (s->sb_cols >> s->tiling.log2_tile_cols) > 64;
+         s->tiling.log2_tile_cols++) ;
+    for (max = 0; (s->sb_cols >> max) >= 4; max++) ;
+    max = FFMAX(0, max - 1);
+    while (max > s->tiling.log2_tile_cols) {
+        if (get_bits1(&s->gb))
+            s->tiling.log2_tile_cols++;
+        else
+            break;
+    }
+    s->tiling.log2_tile_rows = decode012(&s->gb);
+    s->tiling.tile_rows      = 1 << s->tiling.log2_tile_rows;
+    if (s->tiling.tile_cols != (1 << s->tiling.log2_tile_cols)) {
+        s->tiling.tile_cols = 1 << s->tiling.log2_tile_cols;
+        s->c_b              = av_fast_realloc(s->c_b, &s->c_b_size,
+                                              sizeof(VP56RangeCoder) *
+                                              s->tiling.tile_cols);
+        if (!s->c_b) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Ran out of memory during range coder init\n");
+            return AVERROR(ENOMEM);
+        }
+    }
+
+    if (s->keyframe || s->errorres || s->intraonly) {
+        s->prob_ctx[0].p =
+        s->prob_ctx[1].p =
+        s->prob_ctx[2].p =
+        s->prob_ctx[3].p = ff_vp9_default_probs;
+        memcpy(s->prob_ctx[0].coef, ff_vp9_default_coef_probs,
+               sizeof(ff_vp9_default_coef_probs));
+        memcpy(s->prob_ctx[1].coef, ff_vp9_default_coef_probs,
+               sizeof(ff_vp9_default_coef_probs));
+        memcpy(s->prob_ctx[2].coef, ff_vp9_default_coef_probs,
+               sizeof(ff_vp9_default_coef_probs));
+        memcpy(s->prob_ctx[3].coef, ff_vp9_default_coef_probs,
+               sizeof(ff_vp9_default_coef_probs));
+    }
+
+    // next 16 bits is size of the rest of the header (arith-coded)
+    size2 = get_bits(&s->gb, 16);
+    data2 = align_get_bits(&s->gb);
+    if (size2 > size - (data2 - data)) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid compressed header size\n");
+        return AVERROR_INVALIDDATA;
+    }
+    ff_vp56_init_range_decoder(&s->c, data2, size2);
+    if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit
+        av_log(avctx, AV_LOG_ERROR, "Marker bit was set\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (s->keyframe || s->intraonly)
+        memset(s->counts.coef, 0,
+               sizeof(s->counts.coef) + sizeof(s->counts.eob));
+    else
+        memset(&s->counts, 0, sizeof(s->counts));
+
+    /* FIXME is it faster to not copy here, but do it down in the fw updates
+     * as explicit copies if the fw update is missing (and skip the copy upon
+     * fw update)? */
+    s->prob.p = s->prob_ctx[c].p;
+
+    // txfm updates
+    if (s->lossless) {
+        s->txfmmode = TX_4X4;
+    } else {
+        s->txfmmode = vp8_rac_get_uint(&s->c, 2);
+        if (s->txfmmode == 3)
+            s->txfmmode += vp8_rac_get(&s->c);
+
+        if (s->txfmmode == TX_SWITCHABLE) {
+            for (i = 0; i < 2; i++)
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.tx8p[i] = update_prob(&s->c, s->prob.p.tx8p[i]);
+            for (i = 0; i < 2; i++)
+                for (j = 0; j < 2; j++)
+                    if (vp56_rac_get_prob_branchy(&s->c, 252))
+                        s->prob.p.tx16p[i][j] =
+                            update_prob(&s->c, s->prob.p.tx16p[i][j]);
+            for (i = 0; i < 2; i++)
+                for (j = 0; j < 3; j++)
+                    if (vp56_rac_get_prob_branchy(&s->c, 252))
+                        s->prob.p.tx32p[i][j] =
+                            update_prob(&s->c, s->prob.p.tx32p[i][j]);
+        }
+    }
+
+    // coef updates
+    for (i = 0; i < 4; i++) {
+        uint8_t (*ref)[2][6][6][3] = s->prob_ctx[c].coef[i];
+        if (vp8_rac_get(&s->c)) {
+            for (j = 0; j < 2; j++)
+                for (k = 0; k < 2; k++)
+                    for (l = 0; l < 6; l++)
+                        for (m = 0; m < 6; m++) {
+                            uint8_t *p = s->prob.coef[i][j][k][l][m];
+                            uint8_t *r = ref[j][k][l][m];
+                            if (m >= 3 && l == 0) // dc only has 3 pt
+                                break;
+                            for (n = 0; n < 3; n++) {
+                                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                                    p[n] = update_prob(&s->c, r[n]);
+                                else
+                                    p[n] = r[n];
+                            }
+                            p[3] = 0;
+                        }
+        } else {
+            for (j = 0; j < 2; j++)
+                for (k = 0; k < 2; k++)
+                    for (l = 0; l < 6; l++)
+                        for (m = 0; m < 6; m++) {
+                            uint8_t *p = s->prob.coef[i][j][k][l][m];
+                            uint8_t *r = ref[j][k][l][m];
+                            if (m > 3 && l == 0) // dc only has 3 pt
+                                break;
+                            memcpy(p, r, 3);
+                            p[3] = 0;
+                        }
+        }
+        if (s->txfmmode == i)
+            break;
+    }
+
+    // mode updates
+    for (i = 0; i < 3; i++)
+        if (vp56_rac_get_prob_branchy(&s->c, 252))
+            s->prob.p.skip[i] = update_prob(&s->c, s->prob.p.skip[i]);
+    if (!s->keyframe && !s->intraonly) {
+        for (i = 0; i < 7; i++)
+            for (j = 0; j < 3; j++)
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.mv_mode[i][j] =
+                        update_prob(&s->c, s->prob.p.mv_mode[i][j]);
+
+        if (s->filtermode == FILTER_SWITCHABLE)
+            for (i = 0; i < 4; i++)
+                for (j = 0; j < 2; j++)
+                    if (vp56_rac_get_prob_branchy(&s->c, 252))
+                        s->prob.p.filter[i][j] =
+                            update_prob(&s->c, s->prob.p.filter[i][j]);
+
+        for (i = 0; i < 4; i++)
+            if (vp56_rac_get_prob_branchy(&s->c, 252))
+                s->prob.p.intra[i] = update_prob(&s->c, s->prob.p.intra[i]);
+
+        if (s->allowcompinter) {
+            s->comppredmode = vp8_rac_get(&s->c);
+            if (s->comppredmode)
+                s->comppredmode += vp8_rac_get(&s->c);
+            if (s->comppredmode == PRED_SWITCHABLE)
+                for (i = 0; i < 5; i++)
+                    if (vp56_rac_get_prob_branchy(&s->c, 252))
+                        s->prob.p.comp[i] =
+                            update_prob(&s->c, s->prob.p.comp[i]);
+        } else {
+            s->comppredmode = PRED_SINGLEREF;
+        }
+
+        if (s->comppredmode != PRED_COMPREF) {
+            for (i = 0; i < 5; i++) {
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.single_ref[i][0] =
+                        update_prob(&s->c, s->prob.p.single_ref[i][0]);
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.single_ref[i][1] =
+                        update_prob(&s->c, s->prob.p.single_ref[i][1]);
+            }
+        }
+
+        if (s->comppredmode != PRED_SINGLEREF) {
+            for (i = 0; i < 5; i++)
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.comp_ref[i] =
+                        update_prob(&s->c, s->prob.p.comp_ref[i]);
+        }
+
+        for (i = 0; i < 4; i++)
+            for (j = 0; j < 9; j++)
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.y_mode[i][j] =
+                        update_prob(&s->c, s->prob.p.y_mode[i][j]);
+
+        for (i = 0; i < 4; i++)
+            for (j = 0; j < 4; j++)
+                for (k = 0; k < 3; k++)
+                    if (vp56_rac_get_prob_branchy(&s->c, 252))
+                        s->prob.p.partition[3 - i][j][k] =
+                            update_prob(&s->c,
+                                        s->prob.p.partition[3 - i][j][k]);
+
+        // mv fields don't use the update_prob subexp model for some reason
+        for (i = 0; i < 3; i++)
+            if (vp56_rac_get_prob_branchy(&s->c, 252))
+                s->prob.p.mv_joint[i] = (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+        for (i = 0; i < 2; i++) {
+            if (vp56_rac_get_prob_branchy(&s->c, 252))
+                s->prob.p.mv_comp[i].sign =
+                    (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+            for (j = 0; j < 10; j++)
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.mv_comp[i].classes[j] =
+                        (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+            if (vp56_rac_get_prob_branchy(&s->c, 252))
+                s->prob.p.mv_comp[i].class0 =
+                    (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+            for (j = 0; j < 10; j++)
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.mv_comp[i].bits[j] =
+                        (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+        }
+
+        for (i = 0; i < 2; i++) {
+            for (j = 0; j < 2; j++)
+                for (k = 0; k < 3; k++)
+                    if (vp56_rac_get_prob_branchy(&s->c, 252))
+                        s->prob.p.mv_comp[i].class0_fp[j][k] =
+                            (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+            for (j = 0; j < 3; j++)
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.mv_comp[i].fp[j] =
+                        (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+        }
+
+        if (s->highprecisionmvs) {
+            for (i = 0; i < 2; i++) {
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.mv_comp[i].class0_hp =
+                        (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+                if (vp56_rac_get_prob_branchy(&s->c, 252))
+                    s->prob.p.mv_comp[i].hp =
+                        (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+            }
+        }
+    }
+
+    return (data2 - data) + size2;
+}
+
+static int decode_subblock(AVCodecContext *avctx, int row, int col,
+                           VP9Filter *lflvl,
+                           ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
+{
+    VP9Context *s = avctx->priv_data;
+    int c = ((s->above_partition_ctx[col]       >> (3 - bl)) & 1) |
+            (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1);
+    int ret;
+    const uint8_t *p = s->keyframe ? ff_vp9_default_kf_partition_probs[bl][c]
+                                   : s->prob.p.partition[bl][c];
+    enum BlockPartition bp;
+    ptrdiff_t hbs = 4 >> bl;
+
+    if (bl == BL_8X8) {
+        bp  = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p);
+        ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff, bl, bp);
+    } else if (col + hbs < s->cols) {
+        if (row + hbs < s->rows) {
+            bp = vp8_rac_get_tree(&s->c, ff_vp9_partition_tree, p);
+            switch (bp) {
+            case PARTITION_NONE:
+                ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
+                                          bl, bp);
+                break;
+            case PARTITION_H:
+                ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
+                                          bl, bp);
+                if (!ret) {
+                    yoff  += hbs * 8 * s->cur_frame->linesize[0];
+                    uvoff += hbs * 4 * s->cur_frame->linesize[1];
+                    ret    = ff_vp9_decode_block(avctx, row + hbs, col, lflvl,
+                                                 yoff, uvoff, bl, bp);
+                }
+                break;
+            case PARTITION_V:
+                ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
+                                          bl, bp);
+                if (!ret) {
+                    yoff  += hbs * 8;
+                    uvoff += hbs * 4;
+                    ret    = ff_vp9_decode_block(avctx, row, col + hbs, lflvl,
+                                                 yoff, uvoff, bl, bp);
+                }
+                break;
+            case PARTITION_SPLIT:
+                ret = decode_subblock(avctx, row, col, lflvl,
+                                      yoff, uvoff, bl + 1);
+                if (!ret) {
+                    ret = decode_subblock(avctx, row, col + hbs, lflvl,
+                                          yoff + 8 * hbs, uvoff + 4 * hbs,
+                                          bl + 1);
+                    if (!ret) {
+                        yoff  += hbs * 8 * s->cur_frame->linesize[0];
+                        uvoff += hbs * 4 * s->cur_frame->linesize[1];
+                        ret    = decode_subblock(avctx, row + hbs, col, lflvl,
+                                                 yoff, uvoff, bl + 1);
+                        if (!ret) {
+                            ret = decode_subblock(avctx, row + hbs, col + hbs,
+                                                  lflvl, yoff + 8 * hbs,
+                                                  uvoff + 4 * hbs, bl + 1);
+                        }
+                    }
+                }
+                break;
+            default:
+                av_log(avctx, AV_LOG_ERROR, "Unexpected partition %d.", bp);
+                return AVERROR_INVALIDDATA;
+            }
+        } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) {
+            bp  = PARTITION_SPLIT;
+            ret = decode_subblock(avctx, row, col, lflvl, yoff, uvoff, bl + 1);
+            if (!ret)
+                ret = decode_subblock(avctx, row, col + hbs, lflvl,
+                                      yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
+        } else {
+            bp  = PARTITION_H;
+            ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
+                                      bl, bp);
+        }
+    } else if (row + hbs < s->rows) {
+        if (vp56_rac_get_prob_branchy(&s->c, p[2])) {
+            bp  = PARTITION_SPLIT;
+            ret = decode_subblock(avctx, row, col, lflvl, yoff, uvoff, bl + 1);
+            if (!ret) {
+                yoff  += hbs * 8 * s->cur_frame->linesize[0];
+                uvoff += hbs * 4 * s->cur_frame->linesize[1];
+                ret    = decode_subblock(avctx, row + hbs, col, lflvl,
+                                         yoff, uvoff, bl + 1);
+            }
+        } else {
+            bp  = PARTITION_V;
+            ret = ff_vp9_decode_block(avctx, row, col, lflvl, yoff, uvoff,
+                                      bl, bp);
+        }
+    } else {
+        bp  = PARTITION_SPLIT;
+        ret = decode_subblock(avctx, row, col, lflvl, yoff, uvoff, bl + 1);
+    }
+    s->counts.partition[bl][c][bp]++;
+
+    return ret;
+}
+
+static void loopfilter_subblock(AVCodecContext *avctx, VP9Filter *lflvl,
+                                int row, int col,
+                                ptrdiff_t yoff, ptrdiff_t uvoff)
+{
+    VP9Context *s = avctx->priv_data;
+    uint8_t *dst   = s->cur_frame->data[0] + yoff, *lvl = lflvl->level;
+    ptrdiff_t ls_y = s->cur_frame->linesize[0], ls_uv = s->cur_frame->linesize[1];
+    int y, x, p;
+
+    /* FIXME: In how far can we interleave the v/h loopfilter calls? E.g.
+     * if you think of them as acting on a 8x8 block max, we can interleave
+     * each v/h within the single x loop, but that only works if we work on
+     * 8 pixel blocks, and we won't always do that (we want at least 16px
+     * to use SSE2 optimizations, perhaps 32 for AVX2). */
+
+    // filter edges between columns, Y plane (e.g. block1 | block2)
+    for (y = 0; y < 8; y += 2, dst += 16 * ls_y, lvl += 16) {
+        uint8_t *ptr = dst, *l = lvl, *hmask1 = lflvl->mask[0][0][y];
+        uint8_t *hmask2 = lflvl->mask[0][0][y + 1];
+        unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3];
+        unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3];
+        unsigned hm  = hm1 | hm2 | hm13 | hm23;
+
+        for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8, l++) {
+            if (hm1 & x) {
+                int L = *l, H = L >> 4;
+                int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+                if (col || x > 1) {
+                    if (hmask1[0] & x) {
+                        if (hmask2[0] & x) {
+                            av_assert2(l[8] == L);
+                            s->dsp.loop_filter_16[0](ptr, ls_y, E, I, H);
+                        } else {
+                            s->dsp.loop_filter_8[2][0](ptr, ls_y, E, I, H);
+                        }
+                    } else if (hm2 & x) {
+                        L  = l[8];
+                        H |= (L >> 4) << 8;
+                        E |= s->filter.mblim_lut[L] << 8;
+                        I |= s->filter.lim_lut[L] << 8;
+                        s->dsp.loop_filter_mix2[!!(hmask1[1] & x)]
+                                               [!!(hmask2[1] & x)]
+                                               [0](ptr, ls_y, E, I, H);
+                    } else {
+                        s->dsp.loop_filter_8[!!(hmask1[1] & x)]
+                                            [0](ptr, ls_y, E, I, H);
+                    }
+                }
+            } else if (hm2 & x) {
+                int L = l[8], H = L >> 4;
+                int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+                if (col || x > 1) {
+                    s->dsp.loop_filter_8[!!(hmask2[1] & x)]
+                                        [0](ptr + 8 * ls_y, ls_y, E, I, H);
+                }
+            }
+            if (hm13 & x) {
+                int L = *l, H = L >> 4;
+                int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+                if (hm23 & x) {
+                    L  = l[8];
+                    H |= (L >> 4) << 8;
+                    E |= s->filter.mblim_lut[L] << 8;
+                    I |= s->filter.lim_lut[L] << 8;
+                    s->dsp.loop_filter_mix2[0][0][0](ptr + 4, ls_y, E, I, H);
+                } else {
+                    s->dsp.loop_filter_8[0][0](ptr + 4, ls_y, E, I, H);
+                }
+            } else if (hm23 & x) {
+                int L = l[8], H = L >> 4;
+                int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+                s->dsp.loop_filter_8[0][0](ptr + 8 * ls_y + 4, ls_y, E, I, H);
+            }
+        }
+    }
+
+    //                                          block1
+    // filter edges between rows, Y plane (e.g. ------)
+    //                                          block2
+    dst = s->cur_frame->data[0] + yoff;
+    lvl = lflvl->level;
+    for (y = 0; y < 8; y++, dst += 8 * ls_y, lvl += 8) {
+        uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[0][1][y];
+        unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3];
+
+        for (x = 1; vm & ~(x - 1); x <<= 2, ptr += 16, l += 2) {
+            if (row || y) {
+                if (vm & x) {
+                    int L = *l, H = L >> 4;
+                    int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+                    if (vmask[0] & x) {
+                        if (vmask[0] & (x << 1)) {
+                            av_assert2(l[1] == L);
+                            s->dsp.loop_filter_16[1](ptr, ls_y, E, I, H);
+                        } else {
+                            s->dsp.loop_filter_8[2][1](ptr, ls_y, E, I, H);
+                        }
+                    } else if (vm & (x << 1)) {
+                        L  = l[1];
+                        H |= (L >> 4) << 8;
+                        E |= s->filter.mblim_lut[L] << 8;
+                        I |= s->filter.lim_lut[L] << 8;
+                        s->dsp.loop_filter_mix2[!!(vmask[1] &  x)]
+                                               [!!(vmask[1] & (x << 1))]
+                                               [1](ptr, ls_y, E, I, H);
+                    } else {
+                        s->dsp.loop_filter_8[!!(vmask[1] & x)]
+                                            [1](ptr, ls_y, E, I, H);
+                    }
+                } else if (vm & (x << 1)) {
+                    int L = l[1], H = L >> 4;
+                    int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+                    s->dsp.loop_filter_8[!!(vmask[1] & (x << 1))]
+                                        [1](ptr + 8, ls_y, E, I, H);
+                }
+            }
+            if (vm3 & x) {
+                int L = *l, H = L >> 4;
+                int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+                if (vm3 & (x << 1)) {
+                    L  = l[1];
+                    H |= (L >> 4) << 8;
+                    E |= s->filter.mblim_lut[L] << 8;
+                    I |= s->filter.lim_lut[L] << 8;
+                    s->dsp.loop_filter_mix2[0][0][1](ptr + ls_y * 4, ls_y, E, I, H);
+                } else {
+                    s->dsp.loop_filter_8[0][1](ptr + ls_y * 4, ls_y, E, I, H);
+                }
+            } else if (vm3 & (x << 1)) {
+                int L = l[1], H = L >> 4;
+                int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+                s->dsp.loop_filter_8[0][1](ptr + ls_y * 4 + 8, ls_y, E, I, H);
+            }
+        }
+    }
+
+    // same principle but for U/V planes
+    for (p = 0; p < 2; p++) {
+        lvl = lflvl->level;
+        dst = s->cur_frame->data[1 + p] + uvoff;
+        for (y = 0; y < 8; y += 4, dst += 16 * ls_uv, lvl += 32) {
+            uint8_t *ptr = dst, *l = lvl, *hmask1 = lflvl->mask[1][0][y];
+            uint8_t *hmask2 = lflvl->mask[1][0][y + 2];
+            unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2];
+            unsigned hm2 = hmask2[1] | hmask2[2], hm = hm1 | hm2;
+
+            for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 4) {
+                if (col || x > 1) {
+                    if (hm1 & x) {
+                        int L = *l, H = L >> 4;
+                        int E = s->filter.mblim_lut[L];
+                        int I = s->filter.lim_lut[L];
+
+                        if (hmask1[0] & x) {
+                            if (hmask2[0] & x) {
+                                av_assert2(l[16] == L);
+                                s->dsp.loop_filter_16[0](ptr, ls_uv, E, I, H);
+                            } else {
+                                s->dsp.loop_filter_8[2][0](ptr, ls_uv, E, I, H);
+                            }
+                        } else if (hm2 & x) {
+                            L  = l[16];
+                            H |= (L >> 4) << 8;
+                            E |= s->filter.mblim_lut[L] << 8;
+                            I |= s->filter.lim_lut[L] << 8;
+                            s->dsp.loop_filter_mix2[!!(hmask1[1] & x)]
+                                                   [!!(hmask2[1] & x)]
+                                                   [0](ptr, ls_uv, E, I, H);
+                        } else {
+                            s->dsp.loop_filter_8[!!(hmask1[1] & x)]
+                                                [0](ptr, ls_uv, E, I, H);
+                        }
+                    } else if (hm2 & x) {
+                        int L = l[16], H = L >> 4;
+                        int E = s->filter.mblim_lut[L];
+                        int I = s->filter.lim_lut[L];
+
+                        s->dsp.loop_filter_8[!!(hmask2[1] & x)]
+                                            [0](ptr + 8 * ls_uv, ls_uv, E, I, H);
+                    }
+                }
+                if (x & 0xAA)
+                    l += 2;
+            }
+        }
+        lvl = lflvl->level;
+        dst = s->cur_frame->data[1 + p] + uvoff;
+        for (y = 0; y < 8; y++, dst += 4 * ls_uv) {
+            uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[1][1][y];
+            unsigned vm = vmask[0] | vmask[1] | vmask[2];
+
+            for (x = 1; vm & ~(x - 1); x <<= 4, ptr += 16, l += 4) {
+                if (row || y) {
+                    if (vm & x) {
+                        int L = *l, H = L >> 4;
+                        int E = s->filter.mblim_lut[L];
+                        int I = s->filter.lim_lut[L];
+
+                        if (vmask[0] & x) {
+                            if (vmask[0] & (x << 2)) {
+                                av_assert2(l[2] == L);
+                                s->dsp.loop_filter_16[1](ptr, ls_uv, E, I, H);
+                            } else {
+                                s->dsp.loop_filter_8[2][1](ptr, ls_uv, E, I, H);
+                            }
+                        } else if (vm & (x << 2)) {
+                            L  = l[2];
+                            H |= (L >> 4) << 8;
+                            E |= s->filter.mblim_lut[L] << 8;
+                            I |= s->filter.lim_lut[L] << 8;
+                            s->dsp.loop_filter_mix2[!!(vmask[1] &  x)]
+                                                   [!!(vmask[1] & (x << 2))]
+                                                   [1](ptr, ls_uv, E, I, H);
+                        } else {
+                            s->dsp.loop_filter_8[!!(vmask[1] & x)]
+                                                [1](ptr, ls_uv, E, I, H);
+                        }
+                    } else if (vm & (x << 2)) {
+                        int L = l[2], H = L >> 4;
+                        int E = s->filter.mblim_lut[L];
+                        int I = s->filter.lim_lut[L];
+
+                        s->dsp.loop_filter_8[!!(vmask[1] & (x << 2))]
+                                            [1](ptr + 8, ls_uv, E, I, H);
+                    }
+                }
+            }
+            if (y & 1)
+                lvl += 16;
+        }
+    }
+}
+
+static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n)
+{
+    int sb_start =  (idx      * n) >> log2_n;
+    int sb_end   = ((idx + 1) * n) >> log2_n;
+    *start = FFMIN(sb_start, n) << 3;
+    *end   = FFMIN(sb_end,   n) << 3;
+}
+
+static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame,
+                            int *got_frame, const uint8_t *data, int size)
+{
+    VP9Context *s = avctx->priv_data;
+    int ret, tile_row, tile_col, i, ref = -1, row, col;
+    ptrdiff_t yoff = 0, uvoff = 0;
+
+    ret = decode_frame_header(avctx, data, size, &ref);
+    if (ret < 0) {
+        return ret;
+    } else if (!ret) {
+        if (!s->refs[ref]->buf[0]) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Requested reference %d not available\n", ref);
+            return AVERROR_INVALIDDATA;
+        }
+
+        ret = av_frame_ref(frame, s->refs[ref]);
+        if (ret < 0)
+            return ret;
+        *got_frame = 1;
+        return 0;
+    }
+    data += ret;
+    size -= ret;
+
+    s->cur_frame = frame;
+
+    av_frame_unref(s->cur_frame);
+    if ((ret = ff_get_buffer(avctx, s->cur_frame,
+                             s->refreshrefmask ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
+        return ret;
+    s->cur_frame->key_frame = s->keyframe;
+    s->cur_frame->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
+                                          : AV_PICTURE_TYPE_P;
+
+    // main tile decode loop
+    memset(s->above_partition_ctx, 0, s->cols);
+    memset(s->above_skip_ctx, 0, s->cols);
+    if (s->keyframe || s->intraonly)
+        memset(s->above_mode_ctx, DC_PRED, s->cols * 2);
+    else
+        memset(s->above_mode_ctx, NEARESTMV, s->cols);
+    memset(s->above_y_nnz_ctx, 0, s->sb_cols * 16);
+    memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 8);
+    memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 8);
+    memset(s->above_segpred_ctx, 0, s->cols);
+    for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
+        set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
+                        tile_row, s->tiling.log2_tile_rows, s->sb_rows);
+        for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
+            int64_t tile_size;
+
+            if (tile_col == s->tiling.tile_cols - 1 &&
+                tile_row == s->tiling.tile_rows - 1) {
+                tile_size = size;
+            } else {
+                tile_size = AV_RB32(data);
+                data     += 4;
+                size     -= 4;
+            }
+            if (tile_size > size)
+                return AVERROR_INVALIDDATA;
+            ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
+            if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) // marker bit
+                return AVERROR_INVALIDDATA;
+            data += tile_size;
+            size -= tile_size;
+        }
+
+        for (row = s->tiling.tile_row_start;
+             row < s->tiling.tile_row_end;
+             row += 8, yoff += s->cur_frame->linesize[0] * 64,
+             uvoff += s->cur_frame->linesize[1] * 32) {
+            VP9Filter *lflvl = s->lflvl;
+            ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
+
+            for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
+                set_tile_offset(&s->tiling.tile_col_start,
+                                &s->tiling.tile_col_end,
+                                tile_col, s->tiling.log2_tile_cols, s->sb_cols);
+
+                memset(s->left_partition_ctx, 0, 8);
+                memset(s->left_skip_ctx, 0, 8);
+                if (s->keyframe || s->intraonly)
+                    memset(s->left_mode_ctx, DC_PRED, 16);
+                else
+                    memset(s->left_mode_ctx, NEARESTMV, 8);
+                memset(s->left_y_nnz_ctx, 0, 16);
+                memset(s->left_uv_nnz_ctx, 0, 16);
+                memset(s->left_segpred_ctx, 0, 8);
+
+                memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
+                for (col = s->tiling.tile_col_start;
+                     col < s->tiling.tile_col_end;
+                     col += 8, yoff2 += 64, uvoff2 += 32, lflvl++) {
+                    // FIXME integrate with lf code (i.e. zero after each
+                    // use, similar to invtxfm coefficients, or similar)
+                    memset(lflvl->mask, 0, sizeof(lflvl->mask));
+
+                    if ((ret = decode_subblock(avctx, row, col, lflvl,
+                                               yoff2, uvoff2, BL_64X64)) < 0)
+                        return ret;
+                }
+                memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
+            }
+
+            // backup pre-loopfilter reconstruction data for intra
+            // prediction of next row of sb64s
+            if (row + 8 < s->rows) {
+                memcpy(s->intra_pred_data[0],
+                       s->cur_frame->data[0] + yoff +
+                       63 * s->cur_frame->linesize[0],
+                       8 * s->cols);
+                memcpy(s->intra_pred_data[1],
+                       s->cur_frame->data[1] + uvoff +
+                       31 * s->cur_frame->linesize[1],
+                       4 * s->cols);
+                memcpy(s->intra_pred_data[2],
+                       s->cur_frame->data[2] + uvoff +
+                       31 * s->cur_frame->linesize[2],
+                       4 * s->cols);
+            }
+
+            // loopfilter one row
+            if (s->filter.level) {
+                yoff2  = yoff;
+                uvoff2 = uvoff;
+                lflvl  = s->lflvl;
+                for (col = 0; col < s->cols;
+                     col += 8, yoff2 += 64, uvoff2 += 32, lflvl++)
+                    loopfilter_subblock(avctx, lflvl, row, col, yoff2, uvoff2);
+            }
+        }
+    }
+
+    // bw adaptivity (or in case of parallel decoding mode, fw adaptivity
+    // probability maintenance between frames)
+    if (s->refreshctx) {
+        if (s->parallelmode) {
+            memcpy(s->prob_ctx[s->framectxid].coef, s->prob.coef,
+                   sizeof(s->prob.coef));
+            s->prob_ctx[s->framectxid].p = s->prob.p;
+        } else {
+            ff_vp9_adapt_probs(s);
+        }
+    }
+    FFSWAP(VP9MVRefPair *, s->mv[0], s->mv[1]);
+
+    // ref frame setup
+    for (i = 0; i < 8; i++)
+        if (s->refreshrefmask & (1 << i)) {
+            av_frame_unref(s->refs[i]);
+            ret = av_frame_ref(s->refs[i], s->cur_frame);
+            if (ret < 0)
+                return ret;
+        }
+
+    if (s->invisible)
+        av_frame_unref(s->cur_frame);
+    else
+        *got_frame = 1;
+
+    return 0;
+}
+
+static int vp9_decode_packet(AVCodecContext *avctx, void *frame,
+                             int *got_frame, AVPacket *avpkt)
+{
+    const uint8_t *data = avpkt->data;
+    int size            = avpkt->size;
+    int marker, ret;
+
+    /* Read superframe index - this is a collection of individual frames
+     * that together lead to one visible frame */
+    marker = data[size - 1];
+    if ((marker & 0xe0) == 0xc0) {
+        int nbytes   = 1 + ((marker >> 3) & 0x3);
+        int n_frames = 1 + (marker & 0x7);
+        int idx_sz   = 2 + n_frames * nbytes;
+
+        if (size >= idx_sz && data[size - idx_sz] == marker) {
+            const uint8_t *idx = data + size + 1 - idx_sz;
+
+            while (n_frames--) {
+                int sz = AV_RL32(idx);
+
+                if (nbytes < 4)
+                    sz &= (1 << (8 * nbytes)) - 1;
+                idx += nbytes;
+
+                if (sz > size) {
+                    av_log(avctx, AV_LOG_ERROR,
+                           "Superframe packet size too big: %d > %d\n",
+                           sz, size);
+                    return AVERROR_INVALIDDATA;
+                }
+
+                ret = vp9_decode_frame(avctx, frame, got_frame, data, sz);
+                if (ret < 0)
+                    return ret;
+                data += sz;
+                size -= sz;
+            }
+            return size;
+        }
+    }
+
+    /* If we get here, there was no valid superframe index, i.e. this is just
+     * one whole single frame. Decode it as such from the complete input buf. */
+    if ((ret = vp9_decode_frame(avctx, frame, got_frame, data, size)) < 0)
+        return ret;
+    return size;
+}
+
+static av_cold int vp9_decode_free(AVCodecContext *avctx)
+{
+    VP9Context *s = avctx->priv_data;
+    int i;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++)
+        av_frame_free(&s->refs[i]);
+
+    av_freep(&s->c_b);
+    av_freep(&s->above_partition_ctx);
+
+    return 0;
+}
+
+static av_cold int vp9_decode_init(AVCodecContext *avctx)
+{
+    VP9Context *s = avctx->priv_data;
+    int i;
+
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    ff_vp9dsp_init(&s->dsp);
+    ff_videodsp_init(&s->vdsp, 8);
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->refs); i++) {
+        s->refs[i] = av_frame_alloc();
+        if (!s->refs[i]) {
+            vp9_decode_free(avctx);
+            return AVERROR(ENOMEM);
+        }
+    }
+
+    s->filter.sharpness = -1;
+
+    return 0;
+}
+
+AVCodec ff_vp9_decoder = {
+    .name           = "vp9",
+    .long_name      = NULL_IF_CONFIG_SMALL("Google VP9"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VP9,
+    .priv_data_size = sizeof(VP9Context),
+    .init           = vp9_decode_init,
+    .decode         = vp9_decode_packet,
+    .flush          = vp9_decode_flush,
+    .close          = vp9_decode_free,
+    .capabilities   = CODEC_CAP_DR1,
+};
diff --git a/libavcodec/vp9.h b/libavcodec/vp9.h
new file mode 100644
index 0000000..0a6c6ee
--- /dev/null
+++ b/libavcodec/vp9.h
@@ -0,0 +1,419 @@
+/*
+ * VP9 compatible video decoder
+ *
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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_VP9_H
+#define AVCODEC_VP9_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/internal.h"
+
+#include "avcodec.h"
+#include "vp56.h"
+
+enum TxfmMode {
+    TX_4X4,
+    TX_8X8,
+    TX_16X16,
+    TX_32X32,
+    N_TXFM_SIZES,
+    TX_SWITCHABLE = N_TXFM_SIZES,
+    N_TXFM_MODES
+};
+
+enum TxfmType {
+    DCT_DCT,
+    DCT_ADST,
+    ADST_DCT,
+    ADST_ADST,
+    N_TXFM_TYPES
+};
+
+enum IntraPredMode {
+    VERT_PRED,
+    HOR_PRED,
+    DC_PRED,
+    DIAG_DOWN_LEFT_PRED,
+    DIAG_DOWN_RIGHT_PRED,
+    VERT_RIGHT_PRED,
+    HOR_DOWN_PRED,
+    VERT_LEFT_PRED,
+    HOR_UP_PRED,
+    TM_VP8_PRED,
+    LEFT_DC_PRED,
+    TOP_DC_PRED,
+    DC_128_PRED,
+    DC_127_PRED,
+    DC_129_PRED,
+    N_INTRA_PRED_MODES
+};
+
+enum FilterMode {
+    FILTER_8TAP_SMOOTH,
+    FILTER_8TAP_REGULAR,
+    FILTER_8TAP_SHARP,
+    FILTER_BILINEAR,
+    FILTER_SWITCHABLE,
+};
+
+enum BlockPartition {
+    PARTITION_NONE,    // [ ] <-.
+    PARTITION_H,       // [-]   |
+    PARTITION_V,       // [|]   |
+    PARTITION_SPLIT,   // [+] --'
+};
+
+enum InterPredMode {
+    NEARESTMV = 10,
+    NEARMV    = 11,
+    ZEROMV    = 12,
+    NEWMV     = 13,
+};
+
+enum MVJoint {
+    MV_JOINT_ZERO,
+    MV_JOINT_H,
+    MV_JOINT_V,
+    MV_JOINT_HV,
+};
+
+typedef struct ProbContext {
+    uint8_t y_mode[4][9];
+    uint8_t uv_mode[10][9];
+    uint8_t filter[4][2];
+    uint8_t mv_mode[7][3];
+    uint8_t intra[4];
+    uint8_t comp[5];
+    uint8_t single_ref[5][2];
+    uint8_t comp_ref[5];
+    uint8_t tx32p[2][3];
+    uint8_t tx16p[2][2];
+    uint8_t tx8p[2];
+    uint8_t skip[3];
+    uint8_t mv_joint[3];
+    struct {
+        uint8_t sign;
+        uint8_t classes[10];
+        uint8_t class0;
+        uint8_t bits[10];
+        uint8_t class0_fp[2][3];
+        uint8_t fp[3];
+        uint8_t class0_hp;
+        uint8_t hp;
+    } mv_comp[2];
+    uint8_t partition[4][4][3];
+} ProbContext;
+
+typedef void (*vp9_mc_func)(uint8_t *dst, const uint8_t *ref,
+                            ptrdiff_t dst_stride,
+                            ptrdiff_t ref_stride,
+                            int h, int mx, int my);
+
+typedef struct VP9DSPContext {
+    /*
+     * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32
+     * dimension 2: intra prediction modes
+     *
+     * dst/left/top is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels)
+     * stride is aligned by 16 pixels
+     * top[-1] is top/left; top[4,7] is top-right for 4x4
+     */
+    // FIXME(rbultje) maybe replace left/top pointers with HAVE_TOP/
+    // HAVE_LEFT/HAVE_TOPRIGHT flags instead, and then handle it in-place?
+    // also needs to fit in with what h264/vp8/etc do
+    void (*intra_pred[N_TXFM_SIZES][N_INTRA_PRED_MODES])(uint8_t *dst,
+                                                         ptrdiff_t stride,
+                                                         const uint8_t *left,
+                                                         const uint8_t *top);
+
+    /*
+     * dimension 1: 0=4x4, 1=8x8, 2=16x16, 3=32x32, 4=lossless (3-4=dct only)
+     * dimension 2: 0=dct/dct, 1=dct/adst, 2=adst/dct, 3=adst/adst
+     *
+     * dst is aligned by transform-size (i.e. 4, 8, 16 or 32 pixels)
+     * stride is aligned by 16 pixels
+     * block is 16-byte aligned
+     * eob indicates the position (+1) of the last non-zero coefficient,
+     * in scan-order. This can be used to write faster versions, e.g. a
+     * dc-only 4x4/8x8/16x16/32x32, or a 4x4-only (eob<10) 8x8/16x16/32x32,
+     * etc.
+     */
+    // FIXME also write idct_add_block() versions for whole (inter) pred
+    // blocks, so we can do 2 4x4s at once
+    void (*itxfm_add[N_TXFM_SIZES + 1][N_TXFM_TYPES])(uint8_t *dst,
+                                                      ptrdiff_t stride,
+                                                      int16_t *block, int eob);
+
+    /*
+     * dimension 1: width of filter (0=4, 1=8, 2=16)
+     * dimension 2: 0=col-edge filter (h), 1=row-edge filter (v)
+     *
+     * dst/stride are aligned by 8
+     */
+    void (*loop_filter_8[3][2])(uint8_t *dst, ptrdiff_t stride,
+                                int mb_lim, int lim, int hev_thr);
+
+    /*
+     * dimension 1: 0=col-edge filter (h), 1=row-edge filter (v)
+     *
+     * The width of filter is assumed to be 16; dst/stride are aligned by 16
+     */
+    void (*loop_filter_16[2])(uint8_t *dst, ptrdiff_t stride,
+                              int mb_lim, int lim, int hev_thr);
+
+    /*
+     * dimension 1/2: width of filter (0=4, 1=8) for each filter half
+     * dimension 3: 0=col-edge filter (h), 1=row-edge filter (v)
+     *
+     * dst/stride are aligned by operation size
+     * this basically calls loop_filter[d1][d3][0](), followed by
+     * loop_filter[d2][d3][0]() on the next 8 pixels
+     * mb_lim/lim/hev_thr contain two values in the lowest two bytes of the
+     * integer.
+     */
+    // FIXME perhaps a mix4 that operates on 32px (for AVX2)
+    void (*loop_filter_mix2[2][2][2])(uint8_t *dst, ptrdiff_t stride,
+                                      int mb_lim, int lim, int hev_thr);
+
+    /*
+     * dimension 1: hsize (0: 64, 1: 32, 2: 16, 3: 8, 4: 4)
+     * dimension 2: filter type (0: smooth, 1: regular, 2: sharp, 3: bilin)
+     * dimension 3: averaging type (0: put, 1: avg)
+     * dimension 4: x subpel interpolation (0: none, 1: 8tap/bilin)
+     * dimension 5: y subpel interpolation (1: none, 1: 8tap/bilin)
+     *
+     * dst/stride are aligned by hsize
+     */
+    vp9_mc_func mc[5][4][2][2][2];
+} VP9DSPContext;
+
+enum CompPredMode {
+    PRED_SINGLEREF,
+    PRED_COMPREF,
+    PRED_SWITCHABLE,
+};
+
+typedef struct VP9MVRefPair {
+    VP56mv mv[2];
+    int8_t ref[2];
+} VP9MVRefPair;
+
+typedef struct VP9Filter {
+    uint8_t level[8 * 8];
+    uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */]
+                              [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */];
+} VP9Filter;
+
+enum BlockLevel {
+    BL_64X64,
+    BL_32X32,
+    BL_16X16,
+    BL_8X8,
+};
+
+enum BlockSize {
+    BS_64x64,
+    BS_64x32,
+    BS_32x64,
+    BS_32x32,
+    BS_32x16,
+    BS_16x32,
+    BS_16x16,
+    BS_16x8,
+    BS_8x16,
+    BS_8x8,
+    BS_8x4,
+    BS_4x8,
+    BS_4x4,
+    N_BS_SIZES,
+};
+
+typedef struct VP9Block {
+    uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip;
+    enum FilterMode filter;
+    VP56mv mv[4 /* b_idx */][2 /* ref */];
+    enum BlockSize bs;
+    enum TxfmMode tx, uvtx;
+
+    int row, row7, col, col7;
+    uint8_t *dst[3];
+    ptrdiff_t y_stride, uv_stride;
+} VP9Block;
+
+typedef struct VP9Context {
+    VP9DSPContext dsp;
+    VideoDSPContext vdsp;
+    GetBitContext gb;
+    VP56RangeCoder c;
+    VP56RangeCoder *c_b;
+    unsigned c_b_size;
+    VP9Block b;
+
+    // bitstream header
+    uint8_t profile;
+    uint8_t keyframe, last_keyframe;
+    uint8_t invisible;
+    uint8_t use_last_frame_mvs;
+    uint8_t errorres;
+    uint8_t colorspace;
+    uint8_t fullrange;
+    uint8_t intraonly;
+    uint8_t resetctx;
+    uint8_t refreshrefmask;
+    uint8_t highprecisionmvs;
+    enum FilterMode filtermode;
+    uint8_t allowcompinter;
+    uint8_t fixcompref;
+    uint8_t refreshctx;
+    uint8_t parallelmode;
+    uint8_t framectxid;
+    uint8_t refidx[3];
+    uint8_t signbias[3];
+    uint8_t varcompref[2];
+    AVFrame *refs[8];
+    AVFrame *cur_frame;
+
+    struct {
+        uint8_t level;
+        int8_t sharpness;
+        uint8_t lim_lut[64];
+        uint8_t mblim_lut[64];
+    } filter;
+    struct {
+        uint8_t enabled;
+        int8_t mode[2];
+        int8_t ref[4];
+    } lf_delta;
+    uint8_t yac_qi;
+    int8_t ydc_qdelta, uvdc_qdelta, uvac_qdelta;
+    uint8_t lossless;
+    struct {
+        uint8_t enabled;
+        uint8_t temporal;
+        uint8_t absolute_vals;
+        uint8_t update_map;
+        struct {
+            uint8_t q_enabled;
+            uint8_t lf_enabled;
+            uint8_t ref_enabled;
+            uint8_t skip_enabled;
+            uint8_t ref_val;
+            int16_t q_val;
+            int8_t lf_val;
+            int16_t qmul[2][2];
+            uint8_t lflvl[4][2];
+        } feat[8];
+    } segmentation;
+    struct {
+        unsigned log2_tile_cols, log2_tile_rows;
+        unsigned tile_cols, tile_rows;
+        unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end;
+    } tiling;
+    unsigned sb_cols, sb_rows, rows, cols;
+    struct {
+        ProbContext p;
+        uint8_t coef[4][2][2][6][6][3];
+    } prob_ctx[4];
+    struct {
+        ProbContext p;
+        uint8_t coef[4][2][2][6][6][11];
+        uint8_t seg[7];
+        uint8_t segpred[3];
+    } prob;
+    struct {
+        unsigned y_mode[4][10];
+        unsigned uv_mode[10][10];
+        unsigned filter[4][3];
+        unsigned mv_mode[7][4];
+        unsigned intra[4][2];
+        unsigned comp[5][2];
+        unsigned single_ref[5][2][2];
+        unsigned comp_ref[5][2];
+        unsigned tx32p[2][4];
+        unsigned tx16p[2][3];
+        unsigned tx8p[2][2];
+        unsigned skip[3][2];
+        unsigned mv_joint[4];
+        struct {
+            unsigned sign[2];
+            unsigned classes[11];
+            unsigned class0[2];
+            unsigned bits[10][2];
+            unsigned class0_fp[2][4];
+            unsigned fp[4];
+            unsigned class0_hp[2];
+            unsigned hp[2];
+        } mv_comp[2];
+        unsigned partition[4][4][4];
+        unsigned coef[4][2][2][6][6][3];
+        unsigned eob[4][2][2][6][6][2];
+    } counts;
+    enum TxfmMode txfmmode;
+    enum CompPredMode comppredmode;
+
+    // contextual (left/above) cache
+    uint8_t left_partition_ctx[8], *above_partition_ctx;
+    uint8_t left_mode_ctx[16], *above_mode_ctx;
+    // FIXME maybe merge some of the below in a flags field?
+    uint8_t left_y_nnz_ctx[16], *above_y_nnz_ctx;
+    uint8_t left_uv_nnz_ctx[2][8], *above_uv_nnz_ctx[2];
+    uint8_t left_skip_ctx[8], *above_skip_ctx; // 1bit
+    uint8_t left_txfm_ctx[8], *above_txfm_ctx; // 2bit
+    uint8_t left_segpred_ctx[8], *above_segpred_ctx; // 1bit
+    uint8_t left_intra_ctx[8], *above_intra_ctx; // 1bit
+    uint8_t left_comp_ctx[8], *above_comp_ctx; // 1bit
+    uint8_t left_ref_ctx[8], *above_ref_ctx; // 2bit
+    uint8_t left_filter_ctx[8], *above_filter_ctx;
+    VP56mv left_mv_ctx[16][2], (*above_mv_ctx)[2];
+
+    // whole-frame cache
+    uint8_t *intra_pred_data[3];
+    uint8_t *segmentation_map;
+    VP9MVRefPair *mv[2];
+    VP9Filter *lflvl;
+    DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71 * 80];
+
+    // block reconstruction intermediates
+    DECLARE_ALIGNED(32, int16_t, block)[4096];
+    DECLARE_ALIGNED(32, int16_t, uvblock)[2][1024];
+    uint8_t eob[256];
+    uint8_t uveob[2][64];
+    VP56mv min_mv, max_mv;
+    DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64];
+    DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32 * 32];
+} VP9Context;
+
+void ff_vp9dsp_init(VP9DSPContext *dsp);
+
+void ff_vp9dsp_init_x86(VP9DSPContext *dsp);
+
+void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb);
+
+void ff_vp9_adapt_probs(VP9Context *s);
+
+int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col,
+                        VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
+                        enum BlockLevel bl, enum BlockPartition bp);
+
+#endif /* AVCODEC_VP9_H */
diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c
new file mode 100644
index 0000000..e686593
--- /dev/null
+++ b/libavcodec/vp9block.c
@@ -0,0 +1,1684 @@
+/*
+ * VP9 compatible video decoder
+ *
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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/avassert.h"
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "videodsp.h"
+#include "vp56.h"
+#include "vp9.h"
+#include "vp9data.h"
+
+static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
+    {
+        { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 },
+        {  4,  4 }, {  4, 2 }, { 2,  4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 },
+    },  {
+        {  8,  8 }, {  8, 4 }, { 4,  8 }, { 4, 4 }, { 4, 2 }, { 2, 4 },
+        {  2,  2 }, {  2, 1 }, { 1,  2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
+    }
+};
+
+// differential forward probability updates
+static void decode_mode(VP9Context *s, VP9Block *const b)
+{
+    static const uint8_t left_ctx[N_BS_SIZES] = {
+        0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf
+    };
+    static const uint8_t above_ctx[N_BS_SIZES] = {
+        0x0, 0x0, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0xf, 0xf
+    };
+    static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = {
+        TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16,
+        TX_16X16, TX_8X8,   TX_8X8,   TX_8X8,   TX_4X4,   TX_4X4,  TX_4X4
+    };
+    int row = b->row, col = b->col, row7 = b->row7;
+    enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs];
+    int w4 = FFMIN(s->cols - col, bwh_tab[1][b->bs][0]);
+    int h4 = FFMIN(s->rows - row, bwh_tab[1][b->bs][1]);
+    int have_a = row > 0, have_l = col > s->tiling.tile_col_start;
+    int y;
+
+    if (!s->segmentation.enabled) {
+        b->seg_id = 0;
+    } else if (s->keyframe || s->intraonly) {
+        b->seg_id = s->segmentation.update_map ?
+                    vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree, s->prob.seg) : 0;
+    } else if (!s->segmentation.update_map ||
+               (s->segmentation.temporal &&
+                vp56_rac_get_prob_branchy(&s->c,
+                                          s->prob.segpred[s->above_segpred_ctx[col] +
+                                                          s->left_segpred_ctx[row7]]))) {
+        int pred = 8, x;
+
+        for (y = 0; y < h4; y++)
+            for (x = 0; x < w4; x++)
+                pred = FFMIN(pred,
+                             s->segmentation_map[(y + row) * 8 * s->sb_cols + x + col]);
+        b->seg_id = pred;
+
+        memset(&s->above_segpred_ctx[col], 1, w4);
+        memset(&s->left_segpred_ctx[row7], 1, h4);
+    } else {
+        b->seg_id = vp8_rac_get_tree(&s->c, ff_vp9_segmentation_tree,
+                                     s->prob.seg);
+
+        memset(&s->above_segpred_ctx[col], 0, w4);
+        memset(&s->left_segpred_ctx[row7], 0, h4);
+    }
+    if ((s->segmentation.enabled && s->segmentation.update_map) || s->keyframe) {
+        for (y = 0; y < h4; y++)
+            memset(&s->segmentation_map[(y + row) * 8 * s->sb_cols + col],
+                   b->seg_id, w4);
+    }
+
+    b->skip = s->segmentation.enabled &&
+              s->segmentation.feat[b->seg_id].skip_enabled;
+    if (!b->skip) {
+        int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col];
+        b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]);
+        s->counts.skip[c][b->skip]++;
+    }
+
+    if (s->keyframe || s->intraonly) {
+        b->intra = 1;
+    } else if (s->segmentation.feat[b->seg_id].ref_enabled) {
+        b->intra = !s->segmentation.feat[b->seg_id].ref_val;
+    } else {
+        int c, bit;
+
+        if (have_a && have_l) {
+            c  = s->above_intra_ctx[col] + s->left_intra_ctx[row7];
+            c += (c == 2);
+        } else {
+            c = have_a ? 2 * s->above_intra_ctx[col] :
+                have_l ? 2 * s->left_intra_ctx[row7] : 0;
+        }
+        bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]);
+        s->counts.intra[c][bit]++;
+        b->intra = !bit;
+    }
+
+    if ((b->intra || !b->skip) && s->txfmmode == TX_SWITCHABLE) {
+        int c;
+        if (have_a) {
+            if (have_l) {
+                c = (s->above_skip_ctx[col] ? max_tx :
+                     s->above_txfm_ctx[col]) +
+                    (s->left_skip_ctx[row7] ? max_tx :
+                     s->left_txfm_ctx[row7]) > max_tx;
+            } else {
+                c = s->above_skip_ctx[col] ? 1 :
+                    (s->above_txfm_ctx[col] * 2 > max_tx);
+            }
+        } else if (have_l) {
+            c = s->left_skip_ctx[row7] ? 1 :
+                (s->left_txfm_ctx[row7] * 2 > max_tx);
+        } else {
+            c = 1;
+        }
+        switch (max_tx) {
+        case TX_32X32:
+            b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]);
+            if (b->tx) {
+                b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]);
+                if (b->tx == 2)
+                    b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]);
+            }
+            s->counts.tx32p[c][b->tx]++;
+            break;
+        case TX_16X16:
+            b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]);
+            if (b->tx)
+                b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]);
+            s->counts.tx16p[c][b->tx]++;
+            break;
+        case TX_8X8:
+            b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]);
+            s->counts.tx8p[c][b->tx]++;
+            break;
+        case TX_4X4:
+            b->tx = TX_4X4;
+            break;
+        }
+    } else {
+        b->tx = FFMIN(max_tx, s->txfmmode);
+    }
+
+    if (s->keyframe || s->intraonly) {
+        uint8_t *a = &s->above_mode_ctx[col * 2];
+        uint8_t *l = &s->left_mode_ctx[(row7) << 1];
+
+        b->comp = 0;
+        if (b->bs > BS_8x8) {
+            // FIXME the memory storage intermediates here aren't really
+            // necessary, they're just there to make the code slightly
+            // simpler for now
+            b->mode[0] =
+            a[0]       = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                          ff_vp9_default_kf_ymode_probs[a[0]][l[0]]);
+            if (b->bs != BS_8x4) {
+                b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                              ff_vp9_default_kf_ymode_probs[a[1]][b->mode[0]]);
+                l[0]       =
+                a[1]       = b->mode[1];
+            } else {
+                l[0]       =
+                a[1]       =
+                b->mode[1] = b->mode[0];
+            }
+            if (b->bs != BS_4x8) {
+                b->mode[2] =
+                a[0]       = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                              ff_vp9_default_kf_ymode_probs[a[0]][l[1]]);
+                if (b->bs != BS_8x4) {
+                    b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                                  ff_vp9_default_kf_ymode_probs[a[1]][b->mode[2]]);
+                    l[1]       =
+                    a[1]       = b->mode[3];
+                } else {
+                    l[1]       =
+                    a[1]       =
+                    b->mode[3] = b->mode[2];
+                }
+            } else {
+                b->mode[2] = b->mode[0];
+                l[1]       =
+                a[1]       =
+                b->mode[3] = b->mode[1];
+            }
+        } else {
+            b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                          ff_vp9_default_kf_ymode_probs[*a][*l]);
+            b->mode[3] =
+            b->mode[2] =
+            b->mode[1] = b->mode[0];
+            // FIXME this can probably be optimized
+            memset(a, b->mode[0], bwh_tab[0][b->bs][0]);
+            memset(l, b->mode[0], bwh_tab[0][b->bs][1]);
+        }
+        b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                     ff_vp9_default_kf_uvmode_probs[b->mode[3]]);
+    } else if (b->intra) {
+        b->comp = 0;
+        if (b->bs > BS_8x8) {
+            b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                          s->prob.p.y_mode[0]);
+            s->counts.y_mode[0][b->mode[0]]++;
+            if (b->bs != BS_8x4) {
+                b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                              s->prob.p.y_mode[0]);
+                s->counts.y_mode[0][b->mode[1]]++;
+            } else {
+                b->mode[1] = b->mode[0];
+            }
+            if (b->bs != BS_4x8) {
+                b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                              s->prob.p.y_mode[0]);
+                s->counts.y_mode[0][b->mode[2]]++;
+                if (b->bs != BS_8x4) {
+                    b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                                  s->prob.p.y_mode[0]);
+                    s->counts.y_mode[0][b->mode[3]]++;
+                } else {
+                    b->mode[3] = b->mode[2];
+                }
+            } else {
+                b->mode[2] = b->mode[0];
+                b->mode[3] = b->mode[1];
+            }
+        } else {
+            static const uint8_t size_group[10] = {
+                3, 3, 3, 3, 2, 2, 2, 1, 1, 1
+            };
+            int sz = size_group[b->bs];
+
+            b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                          s->prob.p.y_mode[sz]);
+            b->mode[1] =
+            b->mode[2] =
+            b->mode[3] = b->mode[0];
+            s->counts.y_mode[sz][b->mode[3]]++;
+        }
+        b->uvmode = vp8_rac_get_tree(&s->c, ff_vp9_intramode_tree,
+                                     s->prob.p.uv_mode[b->mode[3]]);
+        s->counts.uv_mode[b->mode[3]][b->uvmode]++;
+    } else {
+        static const uint8_t inter_mode_ctx_lut[14][14] = {
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+            { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 },
+            { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 },
+            { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 3 },
+            { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 4 },
+        };
+
+        if (s->segmentation.feat[b->seg_id].ref_enabled) {
+            av_assert2(s->segmentation.feat[b->seg_id].ref_val != 0);
+            b->comp   = 0;
+            b->ref[0] = s->segmentation.feat[b->seg_id].ref_val - 1;
+        } else {
+            // read comp_pred flag
+            if (s->comppredmode != PRED_SWITCHABLE) {
+                b->comp = s->comppredmode == PRED_COMPREF;
+            } else {
+                int c;
+
+                // FIXME add intra as ref=0xff (or -1) to make these easier?
+                if (have_a) {
+                    if (have_l) {
+                        if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) {
+                            c = 4;
+                        } else if (s->above_comp_ctx[col]) {
+                            c = 2 + (s->left_intra_ctx[row7] ||
+                                     s->left_ref_ctx[row7] == s->fixcompref);
+                        } else if (s->left_comp_ctx[row7]) {
+                            c = 2 + (s->above_intra_ctx[col] ||
+                                     s->above_ref_ctx[col] == s->fixcompref);
+                        } else {
+                            c = (!s->above_intra_ctx[col] &&
+                                 s->above_ref_ctx[col] == s->fixcompref) ^
+                                (!s->left_intra_ctx[row7] &&
+                                 s->left_ref_ctx[row & 7] == s->fixcompref);
+                        }
+                    } else {
+                        c = s->above_comp_ctx[col] ? 3 :
+                            (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->fixcompref);
+                    }
+                } else if (have_l) {
+                    c = s->left_comp_ctx[row7] ? 3 :
+                        (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->fixcompref);
+                } else {
+                    c = 1;
+                }
+                b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]);
+                s->counts.comp[c][b->comp]++;
+            }
+
+            // read actual references
+            // FIXME probably cache a few variables here to prevent repetitive
+            // memory accesses below
+            if (b->comp) { /* two references */
+                int fix_idx = s->signbias[s->fixcompref], var_idx = !fix_idx, c, bit;
+
+                b->ref[fix_idx] = s->fixcompref;
+                // FIXME can this codeblob be replaced by some sort of LUT?
+                if (have_a) {
+                    if (have_l) {
+                        if (s->above_intra_ctx[col]) {
+                            if (s->left_intra_ctx[row7]) {
+                                c = 2;
+                            } else {
+                                c = 1 + 2 * (s->left_ref_ctx[row7] != s->varcompref[1]);
+                            }
+                        } else if (s->left_intra_ctx[row7]) {
+                            c = 1 + 2 * (s->above_ref_ctx[col] != s->varcompref[1]);
+                        } else {
+                            int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col];
+
+                            if (refl == refa && refa == s->varcompref[1]) {
+                                c = 0;
+                            } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) {
+                                if ((refa == s->fixcompref && refl == s->varcompref[0]) ||
+                                    (refl == s->fixcompref && refa == s->varcompref[0])) {
+                                    c = 4;
+                                } else {
+                                    c = (refa == refl) ? 3 : 1;
+                                }
+                            } else if (!s->left_comp_ctx[row7]) {
+                                if (refa == s->varcompref[1] && refl != s->varcompref[1]) {
+                                    c = 1;
+                                } else {
+                                    c = (refl == s->varcompref[1] &&
+                                         refa != s->varcompref[1]) ? 2 : 4;
+                                }
+                            } else if (!s->above_comp_ctx[col]) {
+                                if (refl == s->varcompref[1] && refa != s->varcompref[1]) {
+                                    c = 1;
+                                } else {
+                                    c = (refa == s->varcompref[1] &&
+                                         refl != s->varcompref[1]) ? 2 : 4;
+                                }
+                            } else {
+                                c = (refl == refa) ? 4 : 2;
+                            }
+                        }
+                    } else {
+                        if (s->above_intra_ctx[col]) {
+                            c = 2;
+                        } else if (s->above_comp_ctx[col]) {
+                            c = 4 * (s->above_ref_ctx[col] != s->varcompref[1]);
+                        } else {
+                            c = 3 * (s->above_ref_ctx[col] != s->varcompref[1]);
+                        }
+                    }
+                } else if (have_l) {
+                    if (s->left_intra_ctx[row7]) {
+                        c = 2;
+                    } else if (s->left_comp_ctx[row7]) {
+                        c = 4 * (s->left_ref_ctx[row7] != s->varcompref[1]);
+                    } else {
+                        c = 3 * (s->left_ref_ctx[row7] != s->varcompref[1]);
+                    }
+                } else {
+                    c = 2;
+                }
+                bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]);
+                b->ref[var_idx] = s->varcompref[bit];
+                s->counts.comp_ref[c][bit]++;
+            } else { /* single reference */
+                int bit, c;
+
+                if (have_a && !s->above_intra_ctx[col]) {
+                    if (have_l && !s->left_intra_ctx[row7]) {
+                        if (s->left_comp_ctx[row7]) {
+                            if (s->above_comp_ctx[col]) {
+                                c = 1 + (!s->fixcompref || !s->left_ref_ctx[row7] ||
+                                         !s->above_ref_ctx[col]);
+                            } else {
+                                c = (3 * !s->above_ref_ctx[col]) +
+                                    (!s->fixcompref || !s->left_ref_ctx[row7]);
+                            }
+                        } else if (s->above_comp_ctx[col]) {
+                            c = (3 * !s->left_ref_ctx[row7]) +
+                                (!s->fixcompref || !s->above_ref_ctx[col]);
+                        } else {
+                            c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col];
+                        }
+                    } else if (s->above_intra_ctx[col]) {
+                        c = 2;
+                    } else if (s->above_comp_ctx[col]) {
+                        c = 1 + (!s->fixcompref || !s->above_ref_ctx[col]);
+                    } else {
+                        c = 4 * (!s->above_ref_ctx[col]);
+                    }
+                } else if (have_l && !s->left_intra_ctx[row7]) {
+                    if (s->left_intra_ctx[row7]) {
+                        c = 2;
+                    } else if (s->left_comp_ctx[row7]) {
+                        c = 1 + (!s->fixcompref || !s->left_ref_ctx[row7]);
+                    } else {
+                        c = 4 * (!s->left_ref_ctx[row7]);
+                    }
+                } else {
+                    c = 2;
+                }
+                bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]);
+                s->counts.single_ref[c][0][bit]++;
+                if (!bit) {
+                    b->ref[0] = 0;
+                } else {
+                    // FIXME can this codeblob be replaced by some sort of LUT?
+                    if (have_a) {
+                        if (have_l) {
+                            if (s->left_intra_ctx[row7]) {
+                                if (s->above_intra_ctx[col]) {
+                                    c = 2;
+                                } else if (s->above_comp_ctx[col]) {
+                                    c = 1 + 2 * (s->fixcompref == 1 ||
+                                                 s->above_ref_ctx[col] == 1);
+                                } else if (!s->above_ref_ctx[col]) {
+                                    c = 3;
+                                } else {
+                                    c = 4 * (s->above_ref_ctx[col] == 1);
+                                }
+                            } else if (s->above_intra_ctx[col]) {
+                                if (s->left_intra_ctx[row7]) {
+                                    c = 2;
+                                } else if (s->left_comp_ctx[row7]) {
+                                    c = 1 + 2 * (s->fixcompref == 1 ||
+                                                 s->left_ref_ctx[row7] == 1);
+                                } else if (!s->left_ref_ctx[row7]) {
+                                    c = 3;
+                                } else {
+                                    c = 4 * (s->left_ref_ctx[row7] == 1);
+                                }
+                            } else if (s->above_comp_ctx[col]) {
+                                if (s->left_comp_ctx[row7]) {
+                                    if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) {
+                                        c = 3 * (s->fixcompref == 1 ||
+                                                 s->left_ref_ctx[row7] == 1);
+                                    } else {
+                                        c = 2;
+                                    }
+                                } else if (!s->left_ref_ctx[row7]) {
+                                    c = 1 + 2 * (s->fixcompref == 1 ||
+                                                 s->above_ref_ctx[col] == 1);
+                                } else {
+                                    c = 3 * (s->left_ref_ctx[row7] == 1) +
+                                        (s->fixcompref == 1 || s->above_ref_ctx[col] == 1);
+                                }
+                            } else if (s->left_comp_ctx[row7]) {
+                                if (!s->above_ref_ctx[col]) {
+                                    c = 1 + 2 * (s->fixcompref == 1 ||
+                                                 s->left_ref_ctx[row7] == 1);
+                                } else {
+                                    c = 3 * (s->above_ref_ctx[col] == 1) +
+                                        (s->fixcompref == 1 || s->left_ref_ctx[row7] == 1);
+                                }
+                            } else if (!s->above_ref_ctx[col]) {
+                                if (!s->left_ref_ctx[row7]) {
+                                    c = 3;
+                                } else {
+                                    c = 4 * (s->left_ref_ctx[row7] == 1);
+                                }
+                            } else if (!s->left_ref_ctx[row7]) {
+                                c = 4 * (s->above_ref_ctx[col] == 1);
+                            } else {
+                                c = 2 * (s->left_ref_ctx[row7] == 1) +
+                                    2 * (s->above_ref_ctx[col] == 1);
+                            }
+                        } else {
+                            if (s->above_intra_ctx[col] ||
+                                (!s->above_comp_ctx[col] && !s->above_ref_ctx[col])) {
+                                c = 2;
+                            } else if (s->above_comp_ctx[col]) {
+                                c = 3 * (s->fixcompref == 1 || s->above_ref_ctx[col] == 1);
+                            } else {
+                                c = 4 * (s->above_ref_ctx[col] == 1);
+                            }
+                        }
+                    } else if (have_l) {
+                        if (s->left_intra_ctx[row7] ||
+                            (!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) {
+                            c = 2;
+                        } else if (s->left_comp_ctx[row7]) {
+                            c = 3 * (s->fixcompref == 1 || s->left_ref_ctx[row7] == 1);
+                        } else {
+                            c = 4 * (s->left_ref_ctx[row7] == 1);
+                        }
+                    } else {
+                        c = 2;
+                    }
+                    bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]);
+                    s->counts.single_ref[c][1][bit]++;
+                    b->ref[0] = 1 + bit;
+                }
+            }
+        }
+
+        if (b->bs <= BS_8x8) {
+            if (s->segmentation.feat[b->seg_id].skip_enabled) {
+                b->mode[0] =
+                b->mode[1] =
+                b->mode[2] =
+                b->mode[3] = ZEROMV;
+            } else {
+                static const uint8_t off[10] = {
+                    3, 0, 0, 1, 0, 0, 0, 0, 0, 0
+                };
+
+                // FIXME this needs to use the LUT tables from find_ref_mvs
+                // because not all are -1,0/0,-1
+                int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]]
+                                          [s->left_mode_ctx[row7 + off[b->bs]]];
+
+                b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
+                                              s->prob.p.mv_mode[c]);
+                b->mode[1] =
+                b->mode[2] =
+                b->mode[3] = b->mode[0];
+                s->counts.mv_mode[c][b->mode[0] - 10]++;
+            }
+        }
+
+        if (s->filtermode == FILTER_SWITCHABLE) {
+            int c;
+
+            if (have_a && s->above_mode_ctx[col] >= NEARESTMV) {
+                if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) {
+                    c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ?
+                        s->left_filter_ctx[row7] : 3;
+                } else {
+                    c = s->above_filter_ctx[col];
+                }
+            } else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) {
+                c = s->left_filter_ctx[row7];
+            } else {
+                c = 3;
+            }
+
+            b->filter = vp8_rac_get_tree(&s->c, ff_vp9_filter_tree,
+                                         s->prob.p.filter[c]);
+            s->counts.filter[c][b->filter]++;
+        } else {
+            b->filter = s->filtermode;
+        }
+
+        if (b->bs > BS_8x8) {
+            int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]];
+
+            b->mode[0] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
+                                          s->prob.p.mv_mode[c]);
+            s->counts.mv_mode[c][b->mode[0] - 10]++;
+            ff_vp9_fill_mv(s, b->mv[0], b->mode[0], 0);
+
+            if (b->bs != BS_8x4) {
+                b->mode[1] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
+                                              s->prob.p.mv_mode[c]);
+                s->counts.mv_mode[c][b->mode[1] - 10]++;
+                ff_vp9_fill_mv(s, b->mv[1], b->mode[1], 1);
+            } else {
+                b->mode[1] = b->mode[0];
+                AV_COPY32(&b->mv[1][0], &b->mv[0][0]);
+                AV_COPY32(&b->mv[1][1], &b->mv[0][1]);
+            }
+
+            if (b->bs != BS_4x8) {
+                b->mode[2] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
+                                              s->prob.p.mv_mode[c]);
+                s->counts.mv_mode[c][b->mode[2] - 10]++;
+                ff_vp9_fill_mv(s, b->mv[2], b->mode[2], 2);
+
+                if (b->bs != BS_8x4) {
+                    b->mode[3] = vp8_rac_get_tree(&s->c, ff_vp9_inter_mode_tree,
+                                                  s->prob.p.mv_mode[c]);
+                    s->counts.mv_mode[c][b->mode[3] - 10]++;
+                    ff_vp9_fill_mv(s, b->mv[3], b->mode[3], 3);
+                } else {
+                    b->mode[3] = b->mode[2];
+                    AV_COPY32(&b->mv[3][0], &b->mv[2][0]);
+                    AV_COPY32(&b->mv[3][1], &b->mv[2][1]);
+                }
+            } else {
+                b->mode[2] = b->mode[0];
+                AV_COPY32(&b->mv[2][0], &b->mv[0][0]);
+                AV_COPY32(&b->mv[2][1], &b->mv[0][1]);
+                b->mode[3] = b->mode[1];
+                AV_COPY32(&b->mv[3][0], &b->mv[1][0]);
+                AV_COPY32(&b->mv[3][1], &b->mv[1][1]);
+            }
+        } else {
+            ff_vp9_fill_mv(s, b->mv[0], b->mode[0], -1);
+            AV_COPY32(&b->mv[1][0], &b->mv[0][0]);
+            AV_COPY32(&b->mv[2][0], &b->mv[0][0]);
+            AV_COPY32(&b->mv[3][0], &b->mv[0][0]);
+            AV_COPY32(&b->mv[1][1], &b->mv[0][1]);
+            AV_COPY32(&b->mv[2][1], &b->mv[0][1]);
+            AV_COPY32(&b->mv[3][1], &b->mv[0][1]);
+        }
+    }
+
+    // FIXME this can probably be optimized
+    memset(&s->above_skip_ctx[col], b->skip, w4);
+    memset(&s->left_skip_ctx[row7], b->skip, h4);
+    memset(&s->above_txfm_ctx[col], b->tx, w4);
+    memset(&s->left_txfm_ctx[row7], b->tx, h4);
+    memset(&s->above_partition_ctx[col], above_ctx[b->bs], w4);
+    memset(&s->left_partition_ctx[row7], left_ctx[b->bs], h4);
+    if (!s->keyframe && !s->intraonly) {
+        memset(&s->above_intra_ctx[col], b->intra, w4);
+        memset(&s->left_intra_ctx[row7], b->intra, h4);
+        memset(&s->above_comp_ctx[col], b->comp, w4);
+        memset(&s->left_comp_ctx[row7], b->comp, h4);
+        memset(&s->above_mode_ctx[col], b->mode[3], w4);
+        memset(&s->left_mode_ctx[row7], b->mode[3], h4);
+        if (s->filtermode == FILTER_SWITCHABLE && !b->intra) {
+            memset(&s->above_filter_ctx[col], b->filter, w4);
+            memset(&s->left_filter_ctx[row7], b->filter, h4);
+            b->filter = ff_vp9_filter_lut[b->filter];
+        }
+        if (b->bs > BS_8x8) {
+            int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]);
+
+            AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]);
+            AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]);
+            AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0);
+            AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1);
+            AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]);
+            AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]);
+            AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0);
+            AV_WN32A(&s->above_mv_ctx[col * 2 + 1][1], mv1);
+        } else {
+            int n, mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]);
+
+            for (n = 0; n < w4 * 2; n++) {
+                AV_WN32A(&s->above_mv_ctx[col * 2 + n][0], mv0);
+                AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1);
+            }
+            for (n = 0; n < h4 * 2; n++) {
+                AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0);
+                AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1);
+            }
+        }
+
+        if (!b->intra) { // FIXME write 0xff or -1 if intra, so we can use this
+                         // as a direct check in above branches
+            int vref = b->ref[b->comp ? s->signbias[s->varcompref[0]] : 0];
+
+            memset(&s->above_ref_ctx[col], vref, w4);
+            memset(&s->left_ref_ctx[row7], vref, h4);
+        }
+    }
+
+    // FIXME kinda ugly
+    for (y = 0; y < h4; y++) {
+        int x, o = (row + y) * s->sb_cols * 8 + col;
+
+        if (b->intra) {
+            for (x = 0; x < w4; x++) {
+                s->mv[0][o + x].ref[0] =
+                s->mv[0][o + x].ref[1] = -1;
+            }
+        } else if (b->comp) {
+            for (x = 0; x < w4; x++) {
+                s->mv[0][o + x].ref[0] = b->ref[0];
+                s->mv[0][o + x].ref[1] = b->ref[1];
+                AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]);
+                AV_COPY32(&s->mv[0][o + x].mv[1], &b->mv[3][1]);
+            }
+        } else {
+            for (x = 0; x < w4; x++) {
+                s->mv[0][o + x].ref[0] = b->ref[0];
+                s->mv[0][o + x].ref[1] = -1;
+                AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]);
+            }
+        }
+    }
+}
+
+// FIXME remove tx argument, and merge cnt/eob arguments?
+static int decode_block_coeffs(VP56RangeCoder *c, int16_t *coef, int n_coeffs,
+                               enum TxfmMode tx, unsigned (*cnt)[6][3],
+                               unsigned (*eob)[6][2], uint8_t(*p)[6][11],
+                               int nnz, const int16_t *scan,
+                               const int16_t(*nb)[2],
+                               const int16_t *band_counts, const int16_t *qmul)
+{
+    int i = 0, band = 0, band_left = band_counts[band];
+    uint8_t *tp = p[0][nnz];
+    uint8_t cache[1024];
+
+    do {
+        int val, rc;
+
+        val = vp56_rac_get_prob_branchy(c, tp[0]); // eob
+        eob[band][nnz][val]++;
+        if (!val)
+            break;
+
+skip_eob:
+        if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero
+            cnt[band][nnz][0]++;
+            if (!--band_left)
+                band_left = band_counts[++band];
+            cache[scan[i]] = 0;
+            nnz            = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1;
+            tp             = p[band][nnz];
+            if (++i == n_coeffs)
+                break;  //invalid input; blocks should end with EOB
+            goto skip_eob;
+        }
+
+        rc = scan[i];
+        if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one
+            cnt[band][nnz][1]++;
+            val       = 1;
+            cache[rc] = 1;
+        } else {
+            // fill in p[3-10] (model fill) - only once per frame for each pos
+            if (!tp[3])
+                memcpy(&tp[3], ff_vp9_model_pareto8[tp[2]], 8);
+
+            cnt[band][nnz][2]++;
+            if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4
+                if (!vp56_rac_get_prob_branchy(c, tp[4])) {
+                    cache[rc] = val = 2;
+                } else {
+                    val       = 3 + vp56_rac_get_prob(c, tp[5]);
+                    cache[rc] = 3;
+                }
+            } else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2
+                cache[rc] = 4;
+                if (!vp56_rac_get_prob_branchy(c, tp[7])) {
+                    val  =  vp56_rac_get_prob(c, 159) + 5;
+                } else {
+                    val  = (vp56_rac_get_prob(c, 165) << 1) + 7;
+                    val +=  vp56_rac_get_prob(c, 145);
+                }
+            } else { // cat 3-6
+                cache[rc] = 5;
+                if (!vp56_rac_get_prob_branchy(c, tp[8])) {
+                    if (!vp56_rac_get_prob_branchy(c, tp[9])) {
+                        val  = (vp56_rac_get_prob(c, 173) << 2) + 11;
+                        val += (vp56_rac_get_prob(c, 148) << 1);
+                        val +=  vp56_rac_get_prob(c, 140);
+                    } else {
+                        val  = (vp56_rac_get_prob(c, 176) << 3) + 19;
+                        val += (vp56_rac_get_prob(c, 155) << 2);
+                        val += (vp56_rac_get_prob(c, 140) << 1);
+                        val +=  vp56_rac_get_prob(c, 135);
+                    }
+                } else if (!vp56_rac_get_prob_branchy(c, tp[10])) {
+                    val  = (vp56_rac_get_prob(c, 180) << 4) + 35;
+                    val += (vp56_rac_get_prob(c, 157) << 3);
+                    val += (vp56_rac_get_prob(c, 141) << 2);
+                    val += (vp56_rac_get_prob(c, 134) << 1);
+                    val +=  vp56_rac_get_prob(c, 130);
+                } else {
+                    val  = (vp56_rac_get_prob(c, 254) << 13) + 67;
+                    val += (vp56_rac_get_prob(c, 254) << 12);
+                    val += (vp56_rac_get_prob(c, 254) << 11);
+                    val += (vp56_rac_get_prob(c, 252) << 10);
+                    val += (vp56_rac_get_prob(c, 249) << 9);
+                    val += (vp56_rac_get_prob(c, 243) << 8);
+                    val += (vp56_rac_get_prob(c, 230) << 7);
+                    val += (vp56_rac_get_prob(c, 196) << 6);
+                    val += (vp56_rac_get_prob(c, 177) << 5);
+                    val += (vp56_rac_get_prob(c, 153) << 4);
+                    val += (vp56_rac_get_prob(c, 140) << 3);
+                    val += (vp56_rac_get_prob(c, 133) << 2);
+                    val += (vp56_rac_get_prob(c, 130) << 1);
+                    val +=  vp56_rac_get_prob(c, 129);
+                }
+            }
+        }
+        if (!--band_left)
+            band_left = band_counts[++band];
+        if (tx == TX_32X32) // FIXME slow
+            coef[rc] = ((vp8_rac_get(c) ? -val : val) * qmul[!!i]) / 2;
+        else
+            coef[rc] = (vp8_rac_get(c) ? -val : val) * qmul[!!i];
+        nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1;
+        tp  = p[band][nnz];
+    } while (++i < n_coeffs);
+
+    return i;
+}
+
+static int decode_coeffs(AVCodecContext *avctx)
+{
+    VP9Context *s = avctx->priv_data;
+    VP9Block *const b = &s->b;
+    int row = b->row, col = b->col;
+    uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra];
+    unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra];
+    unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra];
+    int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1;
+    int end_x = FFMIN(2 * (s->cols - col), w4);
+    int end_y = FFMIN(2 * (s->rows - row), h4);
+    int n, pl, x, y, step1d = 1 << b->tx, step = 1 << (b->tx * 2);
+    int uvstep1d = 1 << b->uvtx, uvstep = 1 << (b->uvtx * 2), ret;
+    int16_t (*qmul)[2] = s->segmentation.feat[b->seg_id].qmul;
+    int tx = 4 * s->lossless + b->tx;
+    const int16_t **yscans = ff_vp9_scans[tx];
+    const int16_t (**ynbs)[2] = ff_vp9_scans_nb[tx];
+    const int16_t *uvscan = ff_vp9_scans[b->uvtx][DCT_DCT];
+    const int16_t (*uvnb)[2] = ff_vp9_scans_nb[b->uvtx][DCT_DCT];
+    uint8_t *a = &s->above_y_nnz_ctx[col * 2];
+    uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1];
+    static const int16_t band_counts[4][8] = {
+        { 1, 2, 3, 4,  3,   16 - 13, 0 },
+        { 1, 2, 3, 4, 11,   64 - 21, 0 },
+        { 1, 2, 3, 4, 11,  256 - 21, 0 },
+        { 1, 2, 3, 4, 11, 1024 - 21, 0 },
+    };
+    const int16_t *y_band_counts  = band_counts[b->tx];
+    const int16_t *uv_band_counts = band_counts[b->uvtx];
+
+    /* y tokens */
+    if (b->tx > TX_4X4) { // FIXME slow
+        for (y = 0; y < end_y; y += step1d)
+            for (x = 1; x < step1d; x++)
+                l[y] |= l[y + x];
+        for (x = 0; x < end_x; x += step1d)
+            for (y = 1; y < step1d; y++)
+                a[x] |= a[x + y];
+    }
+    for (n = 0, y = 0; y < end_y; y += step1d) {
+        for (x = 0; x < end_x; x += step1d, n += step) {
+            enum TxfmType txtp = ff_vp9_intra_txfm_type[b->mode[b->tx == TX_4X4 &&
+                                                                b->bs > BS_8x8 ?
+                                                                n : 0]];
+            int nnz = a[x] + l[y];
+            if ((ret = decode_block_coeffs(&s->c, s->block + 16 * n, 16 * step,
+                                           b->tx, c, e, p, nnz, yscans[txtp],
+                                           ynbs[txtp], y_band_counts,
+                                           qmul[0])) < 0)
+                return ret;
+            a[x] = l[y] = !!ret;
+            if (b->tx > TX_8X8)
+                AV_WN16A(&s->eob[n], ret);
+            else
+                s->eob[n] = ret;
+        }
+    }
+    if (b->tx > TX_4X4) { // FIXME slow
+        for (y = 0; y < end_y; y += step1d)
+            memset(&l[y + 1], l[y], FFMIN(end_y - y - 1, step1d - 1));
+        for (x = 0; x < end_x; x += step1d)
+            memset(&a[x + 1], a[x], FFMIN(end_x - x - 1, step1d - 1));
+    }
+
+    p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra];
+    c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra];
+    e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra];
+    w4    >>= 1;
+    h4    >>= 1;
+    end_x >>= 1;
+    end_y >>= 1;
+    for (pl = 0; pl < 2; pl++) {
+        a = &s->above_uv_nnz_ctx[pl][col];
+        l = &s->left_uv_nnz_ctx[pl][row & 7];
+        if (b->uvtx > TX_4X4) { // FIXME slow
+            for (y = 0; y < end_y; y += uvstep1d)
+                for (x = 1; x < uvstep1d; x++)
+                    l[y] |= l[y + x];
+            for (x = 0; x < end_x; x += uvstep1d)
+                for (y = 1; y < uvstep1d; y++)
+                    a[x] |= a[x + y];
+        }
+        for (n = 0, y = 0; y < end_y; y += uvstep1d) {
+            for (x = 0; x < end_x; x += uvstep1d, n += uvstep) {
+                int nnz = a[x] + l[y];
+                if ((ret = decode_block_coeffs(&s->c, s->uvblock[pl] + 16 * n,
+                                               16 * uvstep, b->uvtx, c, e, p,
+                                               nnz, uvscan, uvnb,
+                                               uv_band_counts, qmul[1])) < 0)
+                    return ret;
+                a[x] = l[y] = !!ret;
+                if (b->uvtx > TX_8X8)
+                    AV_WN16A(&s->uveob[pl][n], ret);
+                else
+                    s->uveob[pl][n] = ret;
+            }
+        }
+        if (b->uvtx > TX_4X4) { // FIXME slow
+            for (y = 0; y < end_y; y += uvstep1d)
+                memset(&l[y + 1], l[y], FFMIN(end_y - y - 1, uvstep1d - 1));
+            for (x = 0; x < end_x; x += uvstep1d)
+                memset(&a[x + 1], a[x], FFMIN(end_x - x - 1, uvstep1d - 1));
+        }
+    }
+
+    return 0;
+}
+
+static av_always_inline int check_intra_mode(VP9Context *s, int mode,
+                                             uint8_t **a,
+                                             uint8_t *dst_edge,
+                                             ptrdiff_t stride_edge,
+                                             uint8_t *dst_inner,
+                                             ptrdiff_t stride_inner,
+                                             uint8_t *l, int col, int x, int w,
+                                             int row, int y, enum TxfmMode tx,
+                                             int p)
+{
+    int have_top   = row > 0 || y > 0;
+    int have_left  = col > s->tiling.tile_col_start || x > 0;
+    int have_right = x < w - 1;
+    static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = {
+        [VERT_PRED]            = { { DC_127_PRED,          VERT_PRED            },
+                                   { DC_127_PRED,          VERT_PRED            } },
+        [HOR_PRED]             = { { DC_129_PRED,          DC_129_PRED          },
+                                   { HOR_PRED,             HOR_PRED             } },
+        [DC_PRED]              = { { DC_128_PRED,          TOP_DC_PRED          },
+                                   { LEFT_DC_PRED,         DC_PRED              } },
+        [DIAG_DOWN_LEFT_PRED]  = { { DC_127_PRED,          DIAG_DOWN_LEFT_PRED  },
+                                   { DC_127_PRED,          DIAG_DOWN_LEFT_PRED  } },
+        [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED },
+                                   { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } },
+        [VERT_RIGHT_PRED]      = { { VERT_RIGHT_PRED,      VERT_RIGHT_PRED      },
+                                   { VERT_RIGHT_PRED,      VERT_RIGHT_PRED      } },
+        [HOR_DOWN_PRED]        = { { HOR_DOWN_PRED,        HOR_DOWN_PRED        },
+                                   { HOR_DOWN_PRED,        HOR_DOWN_PRED        } },
+        [VERT_LEFT_PRED]       = { { DC_127_PRED,          VERT_LEFT_PRED       },
+                                   { DC_127_PRED,          VERT_LEFT_PRED       } },
+        [HOR_UP_PRED]          = { { DC_129_PRED,          DC_129_PRED          },
+                                   { HOR_UP_PRED,          HOR_UP_PRED          } },
+        [TM_VP8_PRED]          = { { DC_129_PRED,          VERT_PRED            },
+                                   { HOR_PRED,             TM_VP8_PRED          } },
+    };
+    static const struct {
+        uint8_t needs_left:1;
+        uint8_t needs_top:1;
+        uint8_t needs_topleft:1;
+        uint8_t needs_topright:1;
+    } edges[N_INTRA_PRED_MODES] = {
+        [VERT_PRED]            = { .needs_top  = 1 },
+        [HOR_PRED]             = { .needs_left = 1 },
+        [DC_PRED]              = { .needs_top  = 1, .needs_left = 1 },
+        [DIAG_DOWN_LEFT_PRED]  = { .needs_top  = 1, .needs_topright = 1 },
+        [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1,
+                                   .needs_topleft = 1 },
+        [VERT_RIGHT_PRED]      = { .needs_left = 1, .needs_top = 1,
+                                   .needs_topleft = 1 },
+        [HOR_DOWN_PRED]        = { .needs_left = 1, .needs_top = 1,
+                                   .needs_topleft = 1 },
+        [VERT_LEFT_PRED]       = { .needs_top  = 1, .needs_topright = 1 },
+        [HOR_UP_PRED]          = { .needs_left = 1 },
+        [TM_VP8_PRED]          = { .needs_left = 1, .needs_top = 1,
+                                   .needs_topleft = 1 },
+        [LEFT_DC_PRED]         = { .needs_left = 1 },
+        [TOP_DC_PRED]          = { .needs_top  = 1 },
+        [DC_128_PRED]          = { 0 },
+        [DC_127_PRED]          = { 0 },
+        [DC_129_PRED]          = { 0 }
+    };
+
+    av_assert2(mode >= 0 && mode < 10);
+    mode = mode_conv[mode][have_left][have_top];
+    if (edges[mode].needs_top) {
+        uint8_t *top = NULL, *topleft = NULL;
+        int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !p) - x) * 4;
+        int n_px_need_tr = 0;
+
+        if (tx == TX_4X4 && edges[mode].needs_topright && have_right)
+            n_px_need_tr = 4;
+
+        // if top of sb64-row, use s->intra_pred_data[] instead of
+        // dst[-stride] for intra prediction (it contains pre- instead of
+        // post-loopfilter data)
+        if (have_top) {
+            top = !(row & 7) && !y ?
+                  s->intra_pred_data[p] + col * (8 >> !!p) + x * 4 :
+                  y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner];
+            if (have_left)
+                topleft = !(row & 7) && !y ?
+                          s->intra_pred_data[p] + col * (8 >> !!p) + x * 4 :
+                          y == 0 || x == 0 ? &dst_edge[-stride_edge] :
+                          &dst_inner[-stride_inner];
+        }
+
+        if (have_top &&
+            (!edges[mode].needs_topleft || (have_left && top == topleft)) &&
+            (tx != TX_4X4 || !edges[mode].needs_topright || have_right) &&
+            n_px_need + n_px_need_tr <= n_px_have) {
+            *a = top;
+        } else {
+            if (have_top) {
+                if (n_px_need <= n_px_have) {
+                    memcpy(*a, top, n_px_need);
+                } else {
+                    memcpy(*a, top, n_px_have);
+                    memset(&(*a)[n_px_have], (*a)[n_px_have - 1],
+                           n_px_need - n_px_have);
+                }
+            } else {
+                memset(*a, 127, n_px_need);
+            }
+            if (edges[mode].needs_topleft) {
+                if (have_left && have_top)
+                    (*a)[-1] = topleft[-1];
+                else
+                    (*a)[-1] = have_top ? 129 : 127;
+            }
+            if (tx == TX_4X4 && edges[mode].needs_topright) {
+                if (have_top && have_right &&
+                    n_px_need + n_px_need_tr <= n_px_have) {
+                    memcpy(&(*a)[4], &top[4], 4);
+                } else {
+                    memset(&(*a)[4], (*a)[3], 4);
+                }
+            }
+        }
+    }
+    if (edges[mode].needs_left) {
+        if (have_left) {
+            int i;
+            int n_px_need = 4 << tx;
+            int n_px_have = (((s->rows - row) << !p) - y) * 4;
+            uint8_t *dst     = x == 0 ? dst_edge : dst_inner;
+            ptrdiff_t stride = x == 0 ? stride_edge : stride_inner;
+
+            if (n_px_need <= n_px_have) {
+                for (i = 0; i < n_px_need; i++)
+                    l[i] = dst[i * stride - 1];
+            } else {
+                for (i = 0; i < n_px_have; i++)
+                    l[i] = dst[i * stride - 1];
+                memset(&l[i], l[i - 1], n_px_need - n_px_have);
+            }
+        } else {
+            memset(l, 129, 4 << tx);
+        }
+    }
+
+    return mode;
+}
+
+static void intra_recon(AVCodecContext *avctx, ptrdiff_t y_off, ptrdiff_t uv_off)
+{
+    VP9Context *s = avctx->priv_data;
+    VP9Block *const b = &s->b;
+    int row = b->row, col = b->col;
+    int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
+    int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
+    int end_x = FFMIN(2 * (s->cols - col), w4);
+    int end_y = FFMIN(2 * (s->rows - row), h4);
+    int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
+    int uvstep1d = 1 << b->uvtx, p;
+    uint8_t *dst = b->dst[0], *dst_r = s->cur_frame->data[0] + y_off;
+
+    for (n = 0, y = 0; y < end_y; y += step1d) {
+        uint8_t *ptr = dst, *ptr_r = dst_r;
+        for (x = 0; x < end_x;
+             x += step1d, ptr += 4 * step1d, ptr_r += 4 * step1d, n += step) {
+            int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ?
+                               y * 2 + x : 0];
+            LOCAL_ALIGNED_16(uint8_t, a_buf, [48]);
+            uint8_t *a = &a_buf[16], l[32];
+            enum TxfmType txtp = ff_vp9_intra_txfm_type[mode];
+            int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
+
+            mode = check_intra_mode(s, mode, &a, ptr_r,
+                                    s->cur_frame->linesize[0],
+                                    ptr, b->y_stride, l,
+                                    col, x, w4, row, y, b->tx, 0);
+            s->dsp.intra_pred[b->tx][mode](ptr, b->y_stride, l, a);
+            if (eob)
+                s->dsp.itxfm_add[tx][txtp](ptr, b->y_stride,
+                                           s->block + 16 * n, eob);
+        }
+        dst_r += 4 * s->cur_frame->linesize[0] * step1d;
+        dst   += 4 * b->y_stride * step1d;
+    }
+
+    // U/V
+    h4    >>= 1;
+    w4    >>= 1;
+    end_x >>= 1;
+    end_y >>= 1;
+    step    = 1 << (b->uvtx * 2);
+    for (p = 0; p < 2; p++) {
+        dst   = b->dst[1 + p];
+        dst_r = s->cur_frame->data[1 + p] + uv_off;
+        for (n = 0, y = 0; y < end_y; y += uvstep1d) {
+            uint8_t *ptr = dst, *ptr_r = dst_r;
+            for (x = 0; x < end_x;
+                 x += uvstep1d, ptr += 4 * uvstep1d,
+                 ptr_r += 4 * uvstep1d, n += step) {
+                int mode = b->uvmode;
+                LOCAL_ALIGNED_16(uint8_t, a_buf, [48]);
+                uint8_t *a = &a_buf[16], l[32];
+                int eob    = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n])
+                                              : s->uveob[p][n];
+
+                mode = check_intra_mode(s, mode, &a, ptr_r,
+                                        s->cur_frame->linesize[1],
+                                        ptr, b->uv_stride, l,
+                                        col, x, w4, row, y, b->uvtx, p + 1);
+                s->dsp.intra_pred[b->uvtx][mode](ptr, b->uv_stride, l, a);
+                if (eob)
+                    s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, b->uv_stride,
+                                                    s->uvblock[p] + 16 * n,
+                                                    eob);
+            }
+            dst_r += 4 * uvstep1d * s->cur_frame->linesize[1];
+            dst   += 4 * uvstep1d * b->uv_stride;
+        }
+    }
+}
+
+static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func(*mc)[2],
+                                         uint8_t *dst, ptrdiff_t dst_stride,
+                                         const uint8_t *ref,
+                                         ptrdiff_t ref_stride,
+                                         ptrdiff_t y, ptrdiff_t x,
+                                         const VP56mv *mv,
+                                         int bw, int bh, int w, int h)
+{
+    int mx = mv->x, my = mv->y;
+
+    y   += my >> 3;
+    x   += mx >> 3;
+    ref += y * ref_stride + x;
+    mx  &= 7;
+    my  &= 7;
+    // FIXME bilinear filter only needs 0/1 pixels, not 3/4
+    if (x < !!mx * 3 || y < !!my * 3 ||
+        x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+                                 ref - !!my * 3 * ref_stride - !!mx * 3,
+                                 80,
+                                 ref_stride,
+                                 bw + !!mx * 7, bh + !!my * 7,
+                                 x - !!mx * 3, y - !!my * 3, w, h);
+        ref        = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
+        ref_stride = 80;
+    }
+    mc[!!mx][!!my](dst, ref, dst_stride, ref_stride, bh, mx << 1, my << 1);
+}
+
+static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func(*mc)[2],
+                                           uint8_t *dst_u, uint8_t *dst_v,
+                                           ptrdiff_t dst_stride,
+                                           const uint8_t *ref_u,
+                                           ptrdiff_t src_stride_u,
+                                           const uint8_t *ref_v,
+                                           ptrdiff_t src_stride_v,
+                                           ptrdiff_t y, ptrdiff_t x,
+                                           const VP56mv *mv,
+                                           int bw, int bh, int w, int h)
+{
+    int mx = mv->x, my = mv->y;
+
+    y     += my >> 4;
+    x     += mx >> 4;
+    ref_u += y * src_stride_u + x;
+    ref_v += y * src_stride_v + x;
+    mx    &= 15;
+    my    &= 15;
+    // FIXME bilinear filter only needs 0/1 pixels, not 3/4
+    if (x < !!mx * 3 || y < !!my * 3 ||
+        x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+                                 ref_u - !!my * 3 * src_stride_u - !!mx * 3,
+                                 80,
+                                 src_stride_u,
+                                 bw + !!mx * 7, bh + !!my * 7,
+                                 x - !!mx * 3, y - !!my * 3, w, h);
+        ref_u = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
+        mc[!!mx][!!my](dst_u, ref_u, dst_stride, 80, bh, mx, my);
+
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+                                 ref_v - !!my * 3 * src_stride_v - !!mx * 3,
+                                 80,
+                                 src_stride_v,
+                                 bw + !!mx * 7, bh + !!my * 7,
+                                 x - !!mx * 3, y - !!my * 3, w, h);
+        ref_v = s->edge_emu_buffer + !!my * 3 * 80 + !!mx * 3;
+        mc[!!mx][!!my](dst_v, ref_v, dst_stride, 80, bh, mx, my);
+    } else {
+        mc[!!mx][!!my](dst_u, ref_u, dst_stride, src_stride_u, bh, mx, my);
+        mc[!!mx][!!my](dst_v, ref_v, dst_stride, src_stride_v, bh, mx, my);
+    }
+}
+
+static int inter_recon(AVCodecContext *avctx)
+{
+    static const uint8_t bwlog_tab[2][N_BS_SIZES] = {
+        { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
+        { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 },
+    };
+    VP9Context *s = avctx->priv_data;
+    VP9Block *const b = &s->b;
+    int row = b->row, col = b->col;
+    AVFrame *ref1 = s->refs[s->refidx[b->ref[0]]];
+    AVFrame *ref2 = b->comp ? s->refs[s->refidx[b->ref[1]]] : NULL;
+    int w = avctx->width, h = avctx->height;
+    ptrdiff_t ls_y = b->y_stride, ls_uv = b->uv_stride;
+
+    if (!ref1->data[0] || (b->comp && !ref2->data[0]))
+        return AVERROR_INVALIDDATA;
+
+    // y inter pred
+    if (b->bs > BS_8x8) {
+        if (b->bs == BS_8x4) {
+            mc_luma_dir(s, s->dsp.mc[3][b->filter][0], b->dst[0], ls_y,
+                        ref1->data[0], ref1->linesize[0],
+                        row << 3, col << 3, &b->mv[0][0], 8, 4, w, h);
+            mc_luma_dir(s, s->dsp.mc[3][b->filter][0],
+                        b->dst[0] + 4 * ls_y, ls_y,
+                        ref1->data[0], ref1->linesize[0],
+                        (row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w, h);
+
+            if (b->comp) {
+                mc_luma_dir(s, s->dsp.mc[3][b->filter][1], b->dst[0], ls_y,
+                            ref2->data[0], ref2->linesize[0],
+                            row << 3, col << 3, &b->mv[0][1], 8, 4, w, h);
+                mc_luma_dir(s, s->dsp.mc[3][b->filter][1],
+                            b->dst[0] + 4 * ls_y, ls_y,
+                            ref2->data[0], ref2->linesize[0],
+                            (row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w, h);
+            }
+        } else if (b->bs == BS_4x8) {
+            mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y,
+                        ref1->data[0], ref1->linesize[0],
+                        row << 3, col << 3, &b->mv[0][0], 4, 8, w, h);
+            mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y,
+                        ref1->data[0], ref1->linesize[0],
+                        row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w, h);
+
+            if (b->comp) {
+                mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y,
+                            ref2->data[0], ref2->linesize[0],
+                            row << 3, col << 3, &b->mv[0][1], 4, 8, w, h);
+                mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y,
+                            ref2->data[0], ref2->linesize[0],
+                            row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w, h);
+            }
+        } else {
+            av_assert2(b->bs == BS_4x4);
+
+            // FIXME if two horizontally adjacent blocks have the same MV,
+            // do a w8 instead of a w4 call
+            mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y,
+                        ref1->data[0], ref1->linesize[0],
+                        row << 3, col << 3, &b->mv[0][0], 4, 4, w, h);
+            mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y,
+                        ref1->data[0], ref1->linesize[0],
+                        row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w, h);
+            mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
+                        b->dst[0] + 4 * ls_y, ls_y,
+                        ref1->data[0], ref1->linesize[0],
+                        (row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w, h);
+            mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
+                        b->dst[0] + 4 * ls_y + 4, ls_y,
+                        ref1->data[0], ref1->linesize[0],
+                        (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w, h);
+
+            if (b->comp) {
+                mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y,
+                            ref2->data[0], ref2->linesize[0],
+                            row << 3, col << 3, &b->mv[0][1], 4, 4, w, h);
+                mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y,
+                            ref2->data[0], ref2->linesize[0],
+                            row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w, h);
+                mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
+                            b->dst[0] + 4 * ls_y, ls_y,
+                            ref2->data[0], ref2->linesize[0],
+                            (row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w, h);
+                mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
+                            b->dst[0] + 4 * ls_y + 4, ls_y,
+                            ref2->data[0], ref2->linesize[0],
+                            (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w, h);
+            }
+        }
+    } else {
+        int bwl = bwlog_tab[0][b->bs];
+        int bw  = bwh_tab[0][b->bs][0] * 4;
+        int bh  = bwh_tab[0][b->bs][1] * 4;
+
+        mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], b->dst[0], ls_y,
+                    ref1->data[0], ref1->linesize[0],
+                    row << 3, col << 3, &b->mv[0][0], bw, bh, w, h);
+
+        if (b->comp)
+            mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], b->dst[0], ls_y,
+                        ref2->data[0], ref2->linesize[0],
+                        row << 3, col << 3, &b->mv[0][1], bw, bh, w, h);
+    }
+
+    // uv inter pred
+    {
+        int bwl = bwlog_tab[1][b->bs];
+        int bw  = bwh_tab[1][b->bs][0] * 4, bh = bwh_tab[1][b->bs][1] * 4;
+        VP56mv mvuv;
+
+        w = (w + 1) >> 1;
+        h = (h + 1) >> 1;
+        if (b->bs > BS_8x8) {
+            mvuv.x = ROUNDED_DIV(b->mv[0][0].x + b->mv[1][0].x +
+                                 b->mv[2][0].x + b->mv[3][0].x, 4);
+            mvuv.y = ROUNDED_DIV(b->mv[0][0].y + b->mv[1][0].y +
+                                 b->mv[2][0].y + b->mv[3][0].y, 4);
+        } else {
+            mvuv = b->mv[0][0];
+        }
+
+        mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][0],
+                      b->dst[1], b->dst[2], ls_uv,
+                      ref1->data[1], ref1->linesize[1],
+                      ref1->data[2], ref1->linesize[2],
+                      row << 2, col << 2, &mvuv, bw, bh, w, h);
+
+        if (b->comp) {
+            if (b->bs > BS_8x8) {
+                mvuv.x = ROUNDED_DIV(b->mv[0][1].x + b->mv[1][1].x +
+                                     b->mv[2][1].x + b->mv[3][1].x, 4);
+                mvuv.y = ROUNDED_DIV(b->mv[0][1].y + b->mv[1][1].y +
+                                     b->mv[2][1].y + b->mv[3][1].y, 4);
+            } else {
+                mvuv = b->mv[0][1];
+            }
+            mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][1],
+                          b->dst[1], b->dst[2], ls_uv,
+                          ref2->data[1], ref2->linesize[1],
+                          ref2->data[2], ref2->linesize[2],
+                          row << 2, col << 2, &mvuv, bw, bh, w, h);
+        }
+    }
+
+    if (!b->skip) {
+        /* mostly copied intra_reconn() */
+
+        int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
+        int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
+        int end_x = FFMIN(2 * (s->cols - col), w4);
+        int end_y = FFMIN(2 * (s->rows - row), h4);
+        int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
+        int uvstep1d = 1 << b->uvtx, p;
+        uint8_t *dst = b->dst[0];
+
+        // y itxfm add
+        for (n = 0, y = 0; y < end_y; y += step1d) {
+            uint8_t *ptr = dst;
+            for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d, n += step) {
+                int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
+
+                if (eob)
+                    s->dsp.itxfm_add[tx][DCT_DCT](ptr, b->y_stride,
+                                                  s->block + 16 * n, eob);
+            }
+            dst += 4 * b->y_stride * step1d;
+        }
+
+        // uv itxfm add
+        h4    >>= 1;
+        w4    >>= 1;
+        end_x >>= 1;
+        end_y >>= 1;
+        step    = 1 << (b->uvtx * 2);
+        for (p = 0; p < 2; p++) {
+            dst = b->dst[p + 1];
+            for (n = 0, y = 0; y < end_y; y += uvstep1d) {
+                uint8_t *ptr = dst;
+                for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d, n += step) {
+                    int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n])
+                                               : s->uveob[p][n];
+                    if (eob)
+                        s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, b->uv_stride,
+                                                        s->uvblock[p] + 16 * n, eob);
+                }
+                dst += 4 * uvstep1d * b->uv_stride;
+            }
+        }
+    }
+    return 0;
+}
+
+static av_always_inline void mask_edges(VP9Filter *lflvl, int is_uv,
+                                        int row_and_7, int col_and_7,
+                                        int w, int h, int col_end, int row_end,
+                                        enum TxfmMode tx, int skip_inter)
+{
+    // FIXME I'm pretty sure all loops can be replaced by a single LUT if
+    // we make VP9Filter.mask uint64_t (i.e. row/col all single variable)
+    // and make the LUT 5-indexed (bl, bp, is_uv, tx and row/col), and then
+    // use row_and_7/col_and_7 as shifts (1*col_and_7+8*row_and_7)
+
+    // the intended behaviour of the vp9 loopfilter is to work on 8-pixel
+    // edges. This means that for UV, we work on two subsampled blocks at
+    // a time, and we only use the topleft block's mode information to set
+    // things like block strength. Thus, for any block size smaller than
+    // 16x16, ignore the odd portion of the block.
+    if (tx == TX_4X4 && is_uv) {
+        if (h == 1) {
+            if (row_and_7 & 1)
+                return;
+            if (!row_end)
+                h += 1;
+        }
+        if (w == 1) {
+            if (col_and_7 & 1)
+                return;
+            if (!col_end)
+                w += 1;
+        }
+    }
+
+    if (tx == TX_4X4 && !skip_inter) {
+        int t = 1 << col_and_7, m_col = (t << w) - t, y;
+        int m_col_odd = (t << (w - 1)) - t;
+
+        // on 32-px edges, use the 8-px wide loopfilter; else, use 4-px wide
+        if (is_uv) {
+            int m_row_8 = m_col & 0x01, m_row_4 = m_col - m_row_8;
+
+            for (y = row_and_7; y < h + row_and_7; y++) {
+                int col_mask_id = 2 - !(y & 7);
+
+                lflvl->mask[is_uv][0][y][1] |= m_row_8;
+                lflvl->mask[is_uv][0][y][2] |= m_row_4;
+                // for odd lines, if the odd col is not being filtered,
+                // skip odd row also:
+                // .---. <-- a
+                // |   |
+                // |___| <-- b
+                // ^   ^
+                // c   d
+                //
+                // if a/c are even row/col and b/d are odd, and d is skipped,
+                // e.g. right edge of size-66x66.webm, then skip b also (bug)
+                if ((col_end & 1) && (y & 1)) {
+                    lflvl->mask[is_uv][1][y][col_mask_id] |= m_col_odd;
+                } else {
+                    lflvl->mask[is_uv][1][y][col_mask_id] |= m_col;
+                }
+            }
+        } else {
+            int m_row_8 = m_col & 0x11, m_row_4 = m_col - m_row_8;
+
+            for (y = row_and_7; y < h + row_and_7; y++) {
+                int col_mask_id = 2 - !(y & 3);
+
+                lflvl->mask[is_uv][0][y][1]           |= m_row_8; // row edge
+                lflvl->mask[is_uv][0][y][2]           |= m_row_4;
+                lflvl->mask[is_uv][1][y][col_mask_id] |= m_col; // col edge
+                lflvl->mask[is_uv][0][y][3]           |= m_col;
+                lflvl->mask[is_uv][1][y][3]           |= m_col;
+            }
+        }
+    } else {
+        int y, t = 1 << col_and_7, m_col = (t << w) - t;
+
+        if (!skip_inter) {
+            int mask_id = (tx == TX_8X8);
+            int l2 = tx + is_uv - 1, step1d = 1 << l2;
+            static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 };
+            int m_row = m_col & masks[l2];
+
+            // at odd UV col/row edges tx16/tx32 loopfilter edges, force
+            // 8wd loopfilter to prevent going off the visible edge.
+            if (is_uv && tx > TX_8X8 && (w ^ (w - 1)) == 1) {
+                int m_row_16 = ((t << (w - 1)) - t) & masks[l2];
+                int m_row_8  = m_row - m_row_16;
+
+                for (y = row_and_7; y < h + row_and_7; y++) {
+                    lflvl->mask[is_uv][0][y][0] |= m_row_16;
+                    lflvl->mask[is_uv][0][y][1] |= m_row_8;
+                }
+            } else {
+                for (y = row_and_7; y < h + row_and_7; y++)
+                    lflvl->mask[is_uv][0][y][mask_id] |= m_row;
+            }
+
+            if (is_uv && tx > TX_8X8 && (h ^ (h - 1)) == 1) {
+                for (y = row_and_7; y < h + row_and_7 - 1; y += step1d)
+                    lflvl->mask[is_uv][1][y][0] |= m_col;
+                if (y - row_and_7 == h - 1)
+                    lflvl->mask[is_uv][1][y][1] |= m_col;
+            } else {
+                for (y = row_and_7; y < h + row_and_7; y += step1d)
+                    lflvl->mask[is_uv][1][y][mask_id] |= m_col;
+            }
+        } else if (tx != TX_4X4) {
+            int mask_id;
+
+            mask_id = (tx == TX_8X8) || (is_uv && h == 1);
+            lflvl->mask[is_uv][1][row_and_7][mask_id] |= m_col;
+            mask_id = (tx == TX_8X8) || (is_uv && w == 1);
+            for (y = row_and_7; y < h + row_and_7; y++)
+                lflvl->mask[is_uv][0][y][mask_id] |= t;
+        } else if (is_uv) {
+            int t8 = t & 0x01, t4 = t - t8;
+
+            for (y = row_and_7; y < h + row_and_7; y++) {
+                lflvl->mask[is_uv][0][y][2] |= t4;
+                lflvl->mask[is_uv][0][y][1] |= t8;
+            }
+            lflvl->mask[is_uv][1][row_and_7][2 - !(row_and_7 & 7)] |= m_col;
+        } else {
+            int t8 = t & 0x11, t4 = t - t8;
+
+            for (y = row_and_7; y < h + row_and_7; y++) {
+                lflvl->mask[is_uv][0][y][2] |= t4;
+                lflvl->mask[is_uv][0][y][1] |= t8;
+            }
+            lflvl->mask[is_uv][1][row_and_7][2 - !(row_and_7 & 3)] |= m_col;
+        }
+    }
+}
+
+int ff_vp9_decode_block(AVCodecContext *avctx, int row, int col,
+                        VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
+                        enum BlockLevel bl, enum BlockPartition bp)
+{
+    VP9Context *s = avctx->priv_data;
+    VP9Block *const b = &s->b;
+    enum BlockSize bs = bl * 3 + bp;
+    int ret, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
+    int emu[2];
+
+    b->row  = row;
+    b->row7 = row & 7;
+    b->col  = col;
+    b->col7 = col & 7;
+
+    s->min_mv.x = -(128 + col * 64);
+    s->min_mv.y = -(128 + row * 64);
+    s->max_mv.x = 128 + (s->cols - col - w4) * 64;
+    s->max_mv.y = 128 + (s->rows - row - h4) * 64;
+
+    b->bs = bs;
+    decode_mode(s, b);
+    b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx));
+
+    if (!b->skip) {
+        if ((ret = decode_coeffs(avctx)) < 0)
+            return ret;
+    } else {
+        int pl;
+
+        memset(&s->above_y_nnz_ctx[col * 2], 0, w4 * 2);
+        memset(&s->left_y_nnz_ctx[(row & 7) << 1], 0, h4 * 2);
+        for (pl = 0; pl < 2; pl++) {
+            memset(&s->above_uv_nnz_ctx[pl][col], 0, w4);
+            memset(&s->left_uv_nnz_ctx[pl][row & 7], 0, h4);
+        }
+    }
+
+    /* Emulated overhangs if the stride of the target buffer can't hold.
+     * This allows to support emu-edge and so on even if we have large
+     * block overhangs. */
+    emu[0] = (col + w4) * 8 > s->cur_frame->linesize[0] ||
+             (row + h4) > s->rows + 2 * !(avctx->flags & CODEC_FLAG_EMU_EDGE);
+    emu[1] = (col + w4) * 4 > s->cur_frame->linesize[1] ||
+             (row + h4) > s->rows + 2 * !(avctx->flags & CODEC_FLAG_EMU_EDGE);
+    if (emu[0]) {
+        b->dst[0]   = s->tmp_y;
+        b->y_stride = 64;
+    } else {
+        b->dst[0]   = s->cur_frame->data[0] + yoff;
+        b->y_stride = s->cur_frame->linesize[0];
+    }
+    if (emu[1]) {
+        b->dst[1]    = s->tmp_uv[0];
+        b->dst[2]    = s->tmp_uv[1];
+        b->uv_stride = 32;
+    } else {
+        b->dst[1]    = s->cur_frame->data[1] + uvoff;
+        b->dst[2]    = s->cur_frame->data[2] + uvoff;
+        b->uv_stride = s->cur_frame->linesize[1];
+    }
+    if (b->intra) {
+        intra_recon(avctx, yoff, uvoff);
+    } else {
+        if ((ret = inter_recon(avctx)) < 0)
+            return ret;
+    }
+    if (emu[0]) {
+        int w = FFMIN(s->cols - col, w4) * 8;
+        int h = FFMIN(s->rows - row, h4) * 8;
+        int n, o = 0;
+
+        for (n = 0; o < w; n++) {
+            int bw = 64 >> n;
+
+            av_assert2(n <= 4);
+            if (w & bw) {
+                s->dsp.mc[n][0][0][0][0](s->cur_frame->data[0] + yoff + o,
+                                         s->tmp_y + o,
+                                         s->cur_frame->linesize[0],
+                                         64, h, 0, 0);
+                o += bw;
+            }
+        }
+    }
+    if (emu[1]) {
+        int w = FFMIN(s->cols - col, w4) * 4;
+        int h = FFMIN(s->rows - row, h4) * 4;
+        int n, o = 0;
+
+        for (n = 1; o < w; n++) {
+            int bw = 64 >> n;
+
+            av_assert2(n <= 4);
+            if (w & bw) {
+                s->dsp.mc[n][0][0][0][0](s->cur_frame->data[1] + uvoff + o,
+                                         s->tmp_uv[0] + o,
+                                         s->cur_frame->linesize[1],
+                                         32, h, 0, 0);
+                s->dsp.mc[n][0][0][0][0](s->cur_frame->data[2] + uvoff + o,
+                                         s->tmp_uv[1] + o,
+                                         s->cur_frame->linesize[2],
+                                         32, h, 0, 0);
+                o += bw;
+            }
+        }
+    }
+
+    // pick filter level and find edges to apply filter to
+    if (s->filter.level &&
+        (lvl = s->segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1]
+                                                    [b->mode[3] != ZEROMV]) > 0) {
+        int x_end = FFMIN(s->cols - col, w4);
+        int y_end = FFMIN(s->rows - row, h4);
+        int skip_inter = !b->intra && b->skip;
+
+        for (y = 0; y < h4; y++)
+            memset(&lflvl->level[((row & 7) + y) * 8 + (col & 7)], lvl, w4);
+        mask_edges(lflvl, 0, row & 7, col & 7, x_end, y_end, 0, 0, b->tx, skip_inter);
+        mask_edges(lflvl, 1, row & 7, col & 7, x_end, y_end,
+                   s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0,
+                   s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0,
+                   b->uvtx, skip_inter);
+
+        if (!s->filter.lim_lut[lvl]) {
+            int sharp = s->filter.sharpness;
+            int limit = lvl;
+
+            if (sharp > 0) {
+                limit >>= (sharp + 3) >> 2;
+                limit   = FFMIN(limit, 9 - sharp);
+            }
+            limit = FFMAX(limit, 1);
+
+            s->filter.lim_lut[lvl]   = limit;
+            s->filter.mblim_lut[lvl] = 2 * (lvl + 2) + limit;
+        }
+    }
+
+    return 0;
+}
diff --git a/libavcodec/vp9data.c b/libavcodec/vp9data.c
new file mode 100644
index 0000000..374fa8b
--- /dev/null
+++ b/libavcodec/vp9data.c
@@ -0,0 +1,2133 @@
+/*
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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 "vp9.h"
+#include "vp9data.h"
+
+const int8_t ff_vp9_partition_tree[3][2] = {
+    { -PARTITION_NONE,                1 }, // '0'
+    {    -PARTITION_H,                2 }, // '10'
+    {    -PARTITION_V, -PARTITION_SPLIT }, // '110', '111'
+};
+
+const uint8_t ff_vp9_default_kf_partition_probs[4][4][3] = {
+    { /* 64x64 -> 32x32 */
+        { 174,  35,  49 } /* a/l both not split */,
+        {  68,  11,  27 } /* a split, l not split */,
+        {  57,  15,   9 } /* l split, a not split */,
+        {  12,   3,   3 } /* a/l both split */
+    }, { /* 32x32 -> 16x16 */
+        { 150,  40,  39 } /* a/l both not split */,
+        {  78,  12,  26 } /* a split, l not split */,
+        {  67,  33,  11 } /* l split, a not split */,
+        {  24,   7,   5 } /* a/l both split */,
+    }, { /* 16x16 -> 8x8 */
+        { 149,  53,  53 } /* a/l both not split */,
+        {  94,  20,  48 } /* a split, l not split */,
+        {  83,  53,  24 } /* l split, a not split */,
+        {  52,  18,  18 } /* a/l both split */,
+    }, { /* 8x8 -> 4x4 */
+        { 158,  97,  94 } /* a/l both not split */,
+        {  93,  24,  99 } /* a split, l not split */,
+        {  85, 119,  44 } /* l split, a not split */,
+        {  62,  59,  67 } /* a/l both split */,
+    },
+};
+
+const int8_t ff_vp9_segmentation_tree[7][2] = {
+    {  1,  2 },
+    {  3,  4 },
+    {  5,  6 },
+    { -0, -1 }, // '00x'
+    { -2, -3 }, // '01x'
+    { -4, -5 }, // '10x'
+    { -6, -7 }, // '11x'
+};
+
+const int8_t ff_vp9_intramode_tree[9][2] = {
+    {              -DC_PRED,                1 }, // '0'
+    {          -TM_VP8_PRED,                2 }, // '10'
+    {            -VERT_PRED,                3 }, // '110'
+    {                     4,                6 },
+    {             -HOR_PRED,                5 }, // '11100'
+    { -DIAG_DOWN_RIGHT_PRED, -VERT_RIGHT_PRED }, // '11101x'
+    {  -DIAG_DOWN_LEFT_PRED,                7 }, // '11110'
+    {       -VERT_LEFT_PRED,                8 }, // '111110'
+    {        -HOR_DOWN_PRED,     -HOR_UP_PRED }, // '111111x'
+};
+
+const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9] = {
+    { /* above = v */
+        {  43,  46, 168, 134, 107, 128,  69, 142,  92 } /* left = v */,
+        {  44,  29,  68, 159, 201, 177,  50,  57,  77 } /* left = h */,
+        {  63,  36, 126, 146, 123, 158,  60,  90,  96 } /* left = dc */,
+        {  58,  38,  76, 114,  97, 172,  78, 133,  92 } /* left = d45 */,
+        {  46,  41,  76, 140,  63, 184,  69, 112,  57 } /* left = d135 */,
+        {  38,  32,  85, 140,  46, 112,  54, 151, 133 } /* left = d117 */,
+        {  39,  27,  61, 131, 110, 175,  44,  75, 136 } /* left = d153 */,
+        {  47,  35,  80, 100,  74, 143,  64, 163,  74 } /* left = d63 */,
+        {  52,  30,  74, 113, 130, 175,  51,  64,  58 } /* left = d27 */,
+        {  36,  61, 116, 114, 128, 162,  80, 125,  82 } /* left = tm */
+    }, { /* above = h */
+        {  55,  44,  68, 166, 179, 192,  57,  57, 108 } /* left = v */,
+        {  42,  26,  11, 199, 241, 228,  23,  15,  85 } /* left = h */,
+        {  82,  26,  26, 171, 208, 204,  44,  32, 105 } /* left = dc */,
+        {  68,  42,  19, 131, 160, 199,  55,  52,  83 } /* left = d45 */,
+        {  58,  50,  25, 139, 115, 232,  39,  52, 118 } /* left = d135 */,
+        {  50,  35,  33, 153, 104, 162,  64,  59, 131 } /* left = d117 */,
+        {  44,  24,  16, 150, 177, 202,  33,  19, 156 } /* left = d153 */,
+        {  53,  49,  21, 110, 116, 168,  59,  80,  76 } /* left = d63 */,
+        {  55,  27,  12, 153, 203, 218,  26,  27,  49 } /* left = d27 */,
+        {  38,  72,  19, 168, 203, 212,  50,  50, 107 } /* left = tm */
+    }, { /* above = dc */
+        {  92,  45, 102, 136, 116, 180,  74,  90, 100 } /* left = v */,
+        {  73,  32,  19, 187, 222, 215,  46,  34, 100 } /* left = h */,
+        { 137,  30,  42, 148, 151, 207,  70,  52,  91 } /* left = dc */,
+        {  91,  30,  32, 116, 121, 186,  93,  86,  94 } /* left = d45 */,
+        {  72,  35,  36, 149,  68, 206,  68,  63, 105 } /* left = d135 */,
+        {  73,  31,  28, 138,  57, 124,  55, 122, 151 } /* left = d117 */,
+        {  67,  23,  21, 140, 126, 197,  40,  37, 171 } /* left = d153 */,
+        {  74,  32,  27, 107,  86, 160,  63, 134, 102 } /* left = d63 */,
+        {  86,  27,  28, 128, 154, 212,  45,  43,  53 } /* left = d27 */,
+        {  59,  67,  44, 140, 161, 202,  78,  67, 119 } /* left = tm */
+    }, { /* above = d45 */
+        {  59,  38,  83, 112, 103, 162,  98, 136,  90 } /* left = v */,
+        {  62,  30,  23, 158, 200, 207,  59,  57,  50 } /* left = h */,
+        { 103,  26,  36, 129, 132, 201,  83,  80,  93 } /* left = dc */,
+        {  67,  30,  29,  84,  86, 191, 102,  91,  59 } /* left = d45 */,
+        {  60,  32,  33, 112,  71, 220,  64,  89, 104 } /* left = d135 */,
+        {  53,  26,  34, 130,  56, 149,  84, 120, 103 } /* left = d117 */,
+        {  53,  21,  23, 133, 109, 210,  56,  77, 172 } /* left = d153 */,
+        {  61,  29,  29,  93,  97, 165,  83, 175, 162 } /* left = d63 */,
+        {  77,  19,  29, 112, 142, 228,  55,  66,  36 } /* left = d27 */,
+        {  47,  47,  43, 114, 137, 181, 100,  99,  95 } /* left = tm */
+    }, { /* above = d135 */
+        {  53,  40,  55, 139,  69, 183,  61,  80, 110 } /* left = v */,
+        {  40,  29,  19, 161, 180, 207,  43,  24,  91 } /* left = h */,
+        {  69,  23,  29, 128,  83, 199,  46,  44, 101 } /* left = dc */,
+        {  60,  34,  19, 105,  61, 198,  53,  64,  89 } /* left = d45 */,
+        {  52,  31,  22, 158,  40, 209,  58,  62,  89 } /* left = d135 */,
+        {  44,  31,  29, 147,  46, 158,  56, 102, 198 } /* left = d117 */,
+        {  35,  19,  12, 135,  87, 209,  41,  45, 167 } /* left = d153 */,
+        {  51,  38,  25, 113,  58, 164,  70,  93,  97 } /* left = d63 */,
+        {  55,  25,  21, 118,  95, 215,  38,  39,  66 } /* left = d27 */,
+        {  47,  54,  34, 146, 108, 203,  72, 103, 151 } /* left = tm */
+    }, { /* above = d117 */
+        {  46,  27,  80, 150,  55, 124,  55, 121, 135 } /* left = v */,
+        {  36,  23,  27, 165, 149, 166,  54,  64, 118 } /* left = h */,
+        {  64,  19,  37, 156,  66, 138,  49,  95, 133 } /* left = dc */,
+        {  53,  21,  36, 131,  63, 163,  60, 109,  81 } /* left = d45 */,
+        {  40,  26,  35, 154,  40, 185,  51,  97, 123 } /* left = d135 */,
+        {  35,  19,  34, 179,  19,  97,  48, 129, 124 } /* left = d117 */,
+        {  36,  20,  26, 136,  62, 164,  33,  77, 154 } /* left = d153 */,
+        {  45,  26,  28, 129,  45, 129,  49, 147, 123 } /* left = d63 */,
+        {  45,  18,  32, 130,  90, 157,  40,  79,  91 } /* left = d27 */,
+        {  38,  44,  51, 136,  74, 162,  57,  97, 121 } /* left = tm */
+    }, { /* above = d153 */
+        {  56,  39,  58, 133, 117, 173,  48,  53, 187 } /* left = v */,
+        {  35,  21,  12, 161, 212, 207,  20,  23, 145 } /* left = h */,
+        {  75,  17,  22, 136, 138, 185,  32,  34, 166 } /* left = dc */,
+        {  56,  29,  19, 117, 109, 181,  55,  68, 112 } /* left = d45 */,
+        {  47,  29,  17, 153,  64, 220,  59,  51, 114 } /* left = d135 */,
+        {  46,  16,  24, 136,  76, 147,  41,  64, 172 } /* left = d117 */,
+        {  34,  17,  11, 108, 152, 187,  13,  15, 209 } /* left = d153 */,
+        {  55,  30,  18, 122,  79, 179,  44,  88, 116 } /* left = d63 */,
+        {  51,  24,  14, 115, 133, 209,  32,  26, 104 } /* left = d27 */,
+        {  37,  49,  25, 129, 168, 164,  41,  54, 148 } /* left = tm */
+    }, { /* above = d63 */
+        {  48,  34,  86, 101,  92, 146,  78, 179, 134 } /* left = v */,
+        {  47,  22,  24, 138, 187, 178,  68,  69,  59 } /* left = h */,
+        {  78,  23,  39, 111, 117, 170,  74, 124,  94 } /* left = dc */,
+        {  56,  25,  33, 105, 112, 187,  95, 177, 129 } /* left = d45 */,
+        {  48,  31,  27, 114,  63, 183,  82, 116,  56 } /* left = d135 */,
+        {  43,  28,  37, 121,  63, 123,  61, 192, 169 } /* left = d117 */,
+        {  42,  17,  24, 109,  97, 177,  56,  76, 122 } /* left = d153 */,
+        {  46,  23,  32,  74,  86, 150,  67, 183,  88 } /* left = d63 */,
+        {  58,  18,  28, 105, 139, 182,  70,  92,  63 } /* left = d27 */,
+        {  36,  38,  48,  92, 122, 165,  88, 137,  91 } /* left = tm */
+    }, { /* above = d27 */
+        {  62,  44,  61, 123, 105, 189,  48,  57,  64 } /* left = v */,
+        {  47,  25,  17, 175, 222, 220,  24,  30,  86 } /* left = h */,
+        {  82,  22,  32, 127, 143, 213,  39,  41,  70 } /* left = dc */,
+        {  68,  36,  17, 106, 102, 206,  59,  74,  74 } /* left = d45 */,
+        {  57,  39,  23, 151,  68, 216,  55,  63,  58 } /* left = d135 */,
+        {  49,  30,  35, 141,  70, 168,  82,  40, 115 } /* left = d117 */,
+        {  51,  25,  15, 136, 129, 202,  38,  35, 139 } /* left = d153 */,
+        {  59,  39,  19, 114,  75, 180,  77, 104,  42 } /* left = d63 */,
+        {  68,  26,  16, 111, 141, 215,  29,  28,  28 } /* left = d27 */,
+        {  40,  61,  26, 126, 152, 206,  61,  59,  93 } /* left = tm */
+    }, { /* above = tm */
+        {  44,  78, 115, 132, 119, 173,  71, 112,  93 } /* left = v */,
+        {  39,  38,  21, 184, 227, 206,  42,  32,  64 } /* left = h */,
+        {  65,  70,  60, 155, 159, 199,  61,  60,  81 } /* left = dc */,
+        {  58,  47,  36, 124, 137, 193,  80,  82,  78 } /* left = d45 */,
+        {  49,  50,  35, 144,  95, 205,  63,  78,  59 } /* left = d135 */,
+        {  41,  53,  52, 148,  71, 142,  65, 128,  51 } /* left = d117 */,
+        {  40,  36,  28, 143, 143, 202,  40,  55, 137 } /* left = d153 */,
+        {  42,  44,  44, 104, 105, 164,  64, 130,  80 } /* left = d63 */,
+        {  52,  34,  29, 129, 183, 227,  42,  35,  43 } /* left = d27 */,
+        {  43,  81,  53, 140, 169, 204,  68,  84,  72 } /* left = tm */
+    }
+};
+
+const uint8_t ff_vp9_default_kf_uvmode_probs[10][9] = {
+    { 118,  15, 123, 148, 131, 101,  44,  93, 131 } /* y = v */,
+    { 113,  12,  23, 188, 226, 142,  26,  32, 125 } /* y = h */,
+    { 144,  11,  54, 157, 195, 130,  46,  58, 108 } /* y = dc */,
+    { 120,  11,  50, 123, 163, 135,  64,  77, 103 } /* y = d45 */,
+    { 113,   9,  36, 155, 111, 157,  32,  44, 161 } /* y = d135 */,
+    { 116,   9,  55, 176,  76,  96,  37,  61, 149 } /* y = d117 */,
+    { 115,   9,  28, 141, 161, 167,  21,  25, 193 } /* y = d153 */,
+    { 116,  12,  64, 120, 140, 125,  49, 115, 121 } /* y = d63 */,
+    { 120,  12,  32, 145, 195, 142,  32,  38,  86 } /* y = d27 */,
+    { 102,  19,  66, 162, 182, 122,  35,  59, 128 } /* y = tm */
+};
+
+const int8_t ff_vp9_inter_mode_tree[3][2] = {
+    {    -ZEROMV,      1 }, // '0'
+    { -NEARESTMV,      2 }, // '10'
+    {    -NEARMV, -NEWMV }, // '11x'
+};
+
+const int8_t ff_vp9_filter_tree[2][2] = {
+    { -0,  1 },  // '0'
+    { -1, -2 },  // '1x'
+};
+
+const enum FilterMode ff_vp9_filter_lut[3] = {
+    FILTER_8TAP_REGULAR,
+    FILTER_8TAP_SMOOTH,
+    FILTER_8TAP_SHARP,
+};
+
+const int16_t ff_vp9_dc_qlookup[256] = {
+       4,    8,    8,    9,   10,   11,   12,   12,
+      13,   14,   15,   16,   17,   18,   19,   19,
+      20,   21,   22,   23,   24,   25,   26,   26,
+      27,   28,   29,   30,   31,   32,   32,   33,
+      34,   35,   36,   37,   38,   38,   39,   40,
+      41,   42,   43,   43,   44,   45,   46,   47,
+      48,   48,   49,   50,   51,   52,   53,   53,
+      54,   55,   56,   57,   57,   58,   59,   60,
+      61,   62,   62,   63,   64,   65,   66,   66,
+      67,   68,   69,   70,   70,   71,   72,   73,
+      74,   74,   75,   76,   77,   78,   78,   79,
+      80,   81,   81,   82,   83,   84,   85,   85,
+      87,   88,   90,   92,   93,   95,   96,   98,
+      99,  101,  102,  104,  105,  107,  108,  110,
+     111,  113,  114,  116,  117,  118,  120,  121,
+     123,  125,  127,  129,  131,  134,  136,  138,
+     140,  142,  144,  146,  148,  150,  152,  154,
+     156,  158,  161,  164,  166,  169,  172,  174,
+     177,  180,  182,  185,  187,  190,  192,  195,
+     199,  202,  205,  208,  211,  214,  217,  220,
+     223,  226,  230,  233,  237,  240,  243,  247,
+     250,  253,  257,  261,  265,  269,  272,  276,
+     280,  284,  288,  292,  296,  300,  304,  309,
+     313,  317,  322,  326,  330,  335,  340,  344,
+     349,  354,  359,  364,  369,  374,  379,  384,
+     389,  395,  400,  406,  411,  417,  423,  429,
+     435,  441,  447,  454,  461,  467,  475,  482,
+     489,  497,  505,  513,  522,  530,  539,  549,
+     559,  569,  579,  590,  602,  614,  626,  640,
+     654,  668,  684,  700,  717,  736,  755,  775,
+     796,  819,  843,  869,  896,  925,  955,  988,
+    1022, 1058, 1098, 1139, 1184, 1232, 1282, 1336,
+};
+
+const int16_t ff_vp9_ac_qlookup[256] = {
+       4,    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,   65,   66,   67,   68,   69,   70,
+      71,   72,   73,   74,   75,   76,   77,   78,
+      79,   80,   81,   82,   83,   84,   85,   86,
+      87,   88,   89,   90,   91,   92,   93,   94,
+      95,   96,   97,   98,   99,  100,  101,  102,
+     104,  106,  108,  110,  112,  114,  116,  118,
+     120,  122,  124,  126,  128,  130,  132,  134,
+     136,  138,  140,  142,  144,  146,  148,  150,
+     152,  155,  158,  161,  164,  167,  170,  173,
+     176,  179,  182,  185,  188,  191,  194,  197,
+     200,  203,  207,  211,  215,  219,  223,  227,
+     231,  235,  239,  243,  247,  251,  255,  260,
+     265,  270,  275,  280,  285,  290,  295,  300,
+     305,  311,  317,  323,  329,  335,  341,  347,
+     353,  359,  366,  373,  380,  387,  394,  401,
+     408,  416,  424,  432,  440,  448,  456,  465,
+     474,  483,  492,  501,  510,  520,  530,  540,
+     550,  560,  571,  582,  593,  604,  615,  627,
+     639,  651,  663,  676,  689,  702,  715,  729,
+     743,  757,  771,  786,  801,  816,  832,  848,
+     864,  881,  898,  915,  933,  951,  969,  988,
+    1007, 1026, 1046, 1066, 1087, 1108, 1129, 1151,
+    1173, 1196, 1219, 1243, 1267, 1292, 1317, 1343,
+    1369, 1396, 1423, 1451, 1479, 1508, 1537, 1567,
+    1597, 1628, 1660, 1692, 1725, 1759, 1793, 1828,
+};
+
+const enum TxfmType ff_vp9_intra_txfm_type[14] = {
+    [VERT_PRED]            = ADST_DCT,
+    [HOR_PRED]             = DCT_ADST,
+    [DC_PRED]              = DCT_DCT,
+    [DIAG_DOWN_LEFT_PRED]  = DCT_DCT,
+    [DIAG_DOWN_RIGHT_PRED] = ADST_ADST,
+    [VERT_RIGHT_PRED]      = ADST_DCT,
+    [HOR_DOWN_PRED]        = DCT_ADST,
+    [VERT_LEFT_PRED]       = ADST_DCT,
+    [HOR_UP_PRED]          = DCT_ADST,
+    [TM_VP8_PRED]          = ADST_ADST,
+    [NEARESTMV]            = DCT_DCT,
+    [NEARMV]               = DCT_DCT,
+    [ZEROMV]               = DCT_DCT,
+    [NEWMV]                = DCT_DCT,
+};
+
+const int16_t ff_vp9_default_scan_4x4[16] = {
+     0,  1,  4,  5,
+     2,  8,  3,  6,
+    12,  9,  7, 10,
+    13, 11, 14, 15,
+};
+
+const int16_t ff_vp9_col_scan_4x4[16] = {
+     0,  1,  2,  4,
+     3,  5,  6,  8,
+     7,  9, 10, 12,
+    13, 11, 14, 15,
+};
+
+const int16_t ff_vp9_row_scan_4x4[16] = {
+     0,  4,  1,  8,
+     5, 12,  9,  2,
+     6, 13,  3, 10,
+     7, 14, 11, 15,
+};
+
+const int16_t ff_vp9_default_scan_8x8[64] = {
+     0,  1,  8,  2,  9, 16, 10,  3,
+    17, 24, 18, 11,  4, 25, 32, 19,
+    12, 26,  5, 33, 20, 27, 40, 13,
+    34,  6, 41, 28, 21, 35, 42, 48,
+    14,  7, 36, 29, 43, 56, 49, 22,
+    15, 37, 50, 44, 57, 30, 23, 51,
+    45, 58, 38, 31, 52, 59, 39, 46,
+    53, 60, 47, 54, 61, 55, 62, 63,
+};
+
+const int16_t ff_vp9_col_scan_8x8[64] = {
+     0,  1,  2,  8,  3,  9,  4, 10,
+    16,  5, 11, 17, 12, 18,  6, 24,
+    19, 13, 25,  7, 26, 20, 32, 14,
+    27, 21, 33, 28, 34, 15, 22, 35,
+    40, 29, 41, 36, 23, 30, 42, 37,
+    48, 43, 31, 44, 49, 38, 50, 56,
+    45, 39, 51, 57, 52, 46, 58, 53,
+    59, 47, 60, 54, 61, 55, 62, 63,
+};
+
+const int16_t ff_vp9_row_scan_8x8[64] = {
+     0,  8, 16,  1,  9, 24,  2, 17,
+    32, 10, 25,  3, 40, 18, 11, 33,
+    26, 19,  4, 48, 41, 34, 12, 27,
+    56, 20,  5, 42, 35, 13, 49, 28,
+     6, 21, 43, 36, 14, 50, 29, 57,
+     7, 44, 22, 37, 51, 15, 58, 30,
+    23, 45, 52, 38, 59, 31, 46, 53,
+    39, 60, 47, 61, 54, 62, 55, 63,
+};
+
+const int16_t ff_vp9_default_scan_16x16[256] = {
+      0,   1,  16,   2,  17,  32,   3,  18,  33,  48,   4,  34,  19,  49,  20,   5,
+     35,  64,  50,  36,  65,  21,   6,  51,  80,  66,  37,  22,  52,   7,  81,  67,
+     38,  82,  53,  23,  96,  68,   8,  83,  97,  54,  39,  69, 112,  24,  98,  84,
+     70,  55,   9,  40,  85,  99, 113, 128,  25, 114, 100,  71,  86,  56,  10,  41,
+    115, 101, 129, 116,  72,  87,  26, 130, 144, 102,  57,  11,  42, 117, 131, 145,
+     88, 103,  27,  73, 132, 118, 146,  58, 160,  12,  43, 133, 147, 104,  89, 119,
+    161,  74, 148, 134,  28, 162,  59,  13, 176, 120, 149,  90, 135, 105, 163,  44,
+     75, 177, 164,  29, 150, 121, 136, 178, 165,  14, 106,  60,  91, 151,  45, 179,
+    192, 137, 166, 122,  76, 180, 152,  30,  61,  15, 107, 167, 181, 193,  92, 208,
+     46, 138, 123, 153, 194,  77, 168, 182,  31, 195, 209, 183, 108, 139,  62, 154,
+     47, 196,  93, 169, 210, 197, 224, 124, 184, 211,  78, 109, 170, 155,  63, 198,
+    212, 185, 225, 240, 140,  94, 199, 125,  79, 213, 226, 171, 186, 156, 214, 200,
+    110, 227, 141,  95, 241, 215, 228, 201, 126, 242, 187, 172, 157, 229, 111, 216,
+    243, 142, 202, 230, 127, 217, 244, 173, 188, 231, 158, 203, 143, 245, 218, 232,
+    189, 246, 159, 174, 233, 247, 219, 204, 175, 190, 248, 234, 205, 220, 249, 191,
+    235, 221, 250, 206, 222, 251, 236, 207, 237, 223, 252, 238, 253, 239, 254, 255,
+};
+
+const int16_t ff_vp9_col_scan_16x16[256] = {
+      0,   1,   2,   3,  16,   4,  17,   5,  18,   6,  19,  32,  20,   7,  33,  21,
+     34,   8,  35,  22,  48,  36,   9,  49,  23,  50,  37,  10,  38,  51,  24,  64,
+     52,  11,  65,  39,  25,  53,  66,  54,  40,  67,  12,  80,  26,  68,  55,  81,
+     41,  69,  13,  27,  82,  56,  70,  83,  42,  14,  84,  96,  71,  28,  57,  85,
+     97,  15,  72,  98,  43,  86,  58,  99,  29,  87, 100, 112,  73,  44, 101,  59,
+     30, 113,  88, 114,  74, 128, 102,  45,  31, 115,  60, 103,  89, 116,  75, 129,
+    117,  46, 104,  90,  61, 130, 118, 131, 132, 105,  76,  47, 119, 144,  91,  62,
+    133, 106, 145, 120, 146, 134,  77, 147, 121,  92, 135, 148,  63, 107, 136, 122,
+     93, 149, 160,  78, 150, 137, 108, 161, 162, 151, 123,  79, 138, 163, 152,  94,
+    164, 109, 165, 153, 124, 139, 176, 166,  95, 177, 167, 110, 154, 178, 125, 179,
+    140, 168, 155, 111, 180, 192, 181, 169, 141, 126, 182, 193, 194, 156, 183, 170,
+    195, 127, 142, 196, 184, 208, 197, 157, 171, 143, 185, 198, 209, 199, 210, 172,
+    158, 186, 211, 224, 212, 200, 240, 159, 213, 225, 187, 201, 173, 226, 214, 215,
+    227, 202, 228, 188, 241, 216, 174, 229, 242, 203, 243, 217, 230, 175, 189, 244,
+    231, 204, 218, 232, 245, 219, 246, 190, 233, 205, 191, 247, 234, 248, 220, 206,
+    249, 235, 221, 207, 250, 236, 222, 251, 223, 237, 238, 252, 239, 253, 254, 255,
+};
+
+const int16_t ff_vp9_row_scan_16x16[256] = {
+      0,  16,  32,   1,  48,  17,  64,  33,   2,  80,  18,  49,  96,  34,   3,  65,
+     19, 112,  50,  81,  35,   4, 128,  66,  20,  97,  51,  82,   5, 144,  36,  67,
+    113,  98,  21,  52, 160,  83, 129,  37,  68,   6, 114, 176,  99,  53,  22,  84,
+    145,  38,  69, 130,   7, 115, 192, 100,  54,  23,  85, 161, 146, 131,  39,  70,
+    208, 116,   8, 101, 177,  55,  86,  24, 162, 147, 132,  71, 224, 117,  40, 102,
+      9, 148,  56,  87, 193, 163, 240, 133, 178,  25, 118,  72,  41, 103, 164,  10,
+    149,  88, 134, 209, 179,  57, 119, 194,  26,  73, 165, 150, 104,  42, 135,  11,
+    180, 120,  89, 225, 195,  58,  27, 210, 151, 181, 166,  74,  43, 105,  12, 136,
+     90,  59, 241, 121,  28, 196, 167, 211, 152,  44, 182, 137,  75,  13, 226, 106,
+    122,  60, 197,  91, 168,  29, 183, 153,  14,  76, 212, 138,  45, 107,  15, 198,
+     92, 227, 169,  30, 123, 154,  61, 242, 184, 213, 139,  46,  77,  31, 108, 170,
+    199, 185, 124, 228,  93, 155, 214,  62, 140, 243,  78,  47, 200, 109, 186, 171,
+    201,  94,  63, 215, 229, 156,  79, 125, 141, 110, 216, 187, 172, 244, 202, 230,
+    217,  95, 157, 126, 245, 111, 142, 231, 188, 127, 158, 218, 173, 232, 246, 233,
+    203, 143, 247, 174, 189, 159, 219, 204, 248, 234, 249, 175, 190, 220, 205, 250,
+    235, 191, 221, 251, 236, 206, 252, 222, 207, 237, 223, 253, 238, 254, 239, 255,
+};
+
+const int16_t ff_vp9_default_scan_32x32[1024] = {
+       0,    1,   32,    2,   33,   64,    3,   34,   65,    4,   96,   35,   66,    5,   36,   97,
+      67,  128,   98,   68,   37,    6,  129,   99,    7,  160,   69,   38,  130,  100,  161,  131,
+      39,   70,    8,  101,  162,  132,  192,   71,   40,    9,  102,  163,  133,  193,   72,  224,
+     103,   41,  164,   10,  194,  134,  165,   73,  104,  135,  225,   42,  195,   11,  256,  166,
+     226,  196,   74,  105,  136,   43,   12,  167,  197,  227,  257,   75,  106,  137,  228,   44,
+     198,  168,  258,  288,   13,  229,   76,  107,  199,  138,  259,  169,  289,   45,  230,  260,
+     200,  108,   14,  170,  139,  320,  290,   77,  231,  261,   46,  201,  140,  291,  109,  232,
+     321,  262,  171,   78,  292,   15,  322,  202,  263,  352,  172,  293,  233,  141,  323,  110,
+      47,  203,  264,  234,  294,  353,  324,   16,   79,  204,  265,  295,  325,  173,  354,  142,
+     235,  384,   48,  296,  111,  266,  355,  326,   80,   17,  205,  236,  174,  356,  385,  327,
+     143,  297,  267,  357,  386,  112,   49,  328,  298,  206,  416,  237,  358,  387,   81,  175,
+      18,  329,  359,  388,  299,  330,  389,  113,  417,  238,  360,   50,  207,  418,  390,  331,
+      19,  448,  361,   82,  419,  391,  239,   51,  362,  420,  114,  449,  480,  421,   83,  363,
+     450,  422,  512,  451,  423,  115,  452,  481,  453,  482,  454,  544,  483,  455,  513,  484,
+     514,  485,  515,  486,  545,  576,  487,  546,  547,  608,  577,  578,  579,  609,  610,  611,
+      20,  144,  268,  392,  516,  640,   21,   52,  145,  176,  269,  300,  393,  424,  517,  548,
+     641,  672,   22,   53,   84,  146,  177,  208,  270,  301,  332,  394,  425,  456,  518,  549,
+     580,  642,  673,  704,   23,   54,   85,  116,  147,  178,  209,  240,  271,  302,  333,  364,
+     395,  426,  457,  488,  519,  550,  581,  612,  643,  674,  705,  736,   55,   86,  117,  179,
+     210,  241,  303,  334,  365,  427,  458,  489,  551,  582,  613,  675,  706,  737,   87,  118,
+     211,  242,  335,  366,  459,  490,  583,  614,  707,  738,  119,  243,  367,  491,  615,  739,
+      24,  148,  272,  396,  520,  644,  768,   25,   56,  149,  180,  273,  304,  397,  428,  521,
+     552,  645,  676,  769,  800,   26,   57,   88,  150,  181,  212,  274,  305,  336,  398,  429,
+     460,  522,  553,  584,  646,  677,  708,  770,  801,  832,   27,   58,   89,  120,  151,  182,
+     213,  244,  275,  306,  337,  368,  399,  430,  461,  492,  523,  554,  585,  616,  647,  678,
+     709,  740,  771,  802,  833,  864,   59,   90,  121,  183,  214,  245,  307,  338,  369,  431,
+     462,  493,  555,  586,  617,  679,  710,  741,  803,  834,  865,   91,  122,  215,  246,  339,
+     370,  463,  494,  587,  618,  711,  742,  835,  866,  123,  247,  371,  495,  619,  743,  867,
+      28,  152,  276,  400,  524,  648,  772,  896,   29,   60,  153,  184,  277,  308,  401,  432,
+     525,  556,  649,  680,  773,  804,  897,  928,   30,   61,   92,  154,  185,  216,  278,  309,
+     340,  402,  433,  464,  526,  557,  588,  650,  681,  712,  774,  805,  836,  898,  929,  960,
+      31,   62,   93,  124,  155,  186,  217,  248,  279,  310,  341,  372,  403,  434,  465,  496,
+     527,  558,  589,  620,  651,  682,  713,  744,  775,  806,  837,  868,  899,  930,  961,  992,
+      63,   94,  125,  187,  218,  249,  311,  342,  373,  435,  466,  497,  559,  590,  621,  683,
+     714,  745,  807,  838,  869,  931,  962,  993,   95,  126,  219,  250,  343,  374,  467,  498,
+     591,  622,  715,  746,  839,  870,  963,  994,  127,  251,  375,  499,  623,  747,  871,  995,
+     156,  280,  404,  528,  652,  776,  900,  157,  188,  281,  312,  405,  436,  529,  560,  653,
+     684,  777,  808,  901,  932,  158,  189,  220,  282,  313,  344,  406,  437,  468,  530,  561,
+     592,  654,  685,  716,  778,  809,  840,  902,  933,  964,  159,  190,  221,  252,  283,  314,
+     345,  376,  407,  438,  469,  500,  531,  562,  593,  624,  655,  686,  717,  748,  779,  810,
+     841,  872,  903,  934,  965,  996,  191,  222,  253,  315,  346,  377,  439,  470,  501,  563,
+     594,  625,  687,  718,  749,  811,  842,  873,  935,  966,  997,  223,  254,  347,  378,  471,
+     502,  595,  626,  719,  750,  843,  874,  967,  998,  255,  379,  503,  627,  751,  875,  999,
+     284,  408,  532,  656,  780,  904,  285,  316,  409,  440,  533,  564,  657,  688,  781,  812,
+     905,  936,  286,  317,  348,  410,  441,  472,  534,  565,  596,  658,  689,  720,  782,  813,
+     844,  906,  937,  968,  287,  318,  349,  380,  411,  442,  473,  504,  535,  566,  597,  628,
+     659,  690,  721,  752,  783,  814,  845,  876,  907,  938,  969, 1000,  319,  350,  381,  443,
+     474,  505,  567,  598,  629,  691,  722,  753,  815,  846,  877,  939,  970, 1001,  351,  382,
+     475,  506,  599,  630,  723,  754,  847,  878,  971, 1002,  383,  507,  631,  755,  879, 1003,
+     412,  536,  660,  784,  908,  413,  444,  537,  568,  661,  692,  785,  816,  909,  940,  414,
+     445,  476,  538,  569,  600,  662,  693,  724,  786,  817,  848,  910,  941,  972,  415,  446,
+     477,  508,  539,  570,  601,  632,  663,  694,  725,  756,  787,  818,  849,  880,  911,  942,
+     973, 1004,  447,  478,  509,  571,  602,  633,  695,  726,  757,  819,  850,  881,  943,  974,
+    1005,  479,  510,  603,  634,  727,  758,  851,  882,  975, 1006,  511,  635,  759,  883, 1007,
+     540,  664,  788,  912,  541,  572,  665,  696,  789,  820,  913,  944,  542,  573,  604,  666,
+     697,  728,  790,  821,  852,  914,  945,  976,  543,  574,  605,  636,  667,  698,  729,  760,
+     791,  822,  853,  884,  915,  946,  977, 1008,  575,  606,  637,  699,  730,  761,  823,  854,
+     885,  947,  978, 1009,  607,  638,  731,  762,  855,  886,  979, 1010,  639,  763,  887, 1011,
+     668,  792,  916,  669,  700,  793,  824,  917,  948,  670,  701,  732,  794,  825,  856,  918,
+     949,  980,  671,  702,  733,  764,  795,  826,  857,  888,  919,  950,  981, 1012,  703,  734,
+     765,  827,  858,  889,  951,  982, 1013,  735,  766,  859,  890,  983, 1014,  767,  891, 1015,
+     796,  920,  797,  828,  921,  952,  798,  829,  860,  922,  953,  984,  799,  830,  861,  892,
+     923,  954,  985, 1016,  831,  862,  893,  955,  986, 1017,  863,  894,  987, 1018,  895, 1019,
+     924,  925,  956,  926,  957,  988,  927,  958,  989, 1020,  959,  990, 1021,  991, 1022, 1023,
+};
+
+const int16_t *ff_vp9_scans[5][4] = {
+    {
+        ff_vp9_default_scan_4x4, ff_vp9_col_scan_4x4,
+        ff_vp9_row_scan_4x4, ff_vp9_default_scan_4x4
+    }, {
+        ff_vp9_default_scan_8x8, ff_vp9_col_scan_8x8,
+        ff_vp9_row_scan_8x8, ff_vp9_default_scan_8x8
+    }, {
+        ff_vp9_default_scan_16x16, ff_vp9_col_scan_16x16,
+        ff_vp9_row_scan_16x16, ff_vp9_default_scan_16x16
+    }, {
+        ff_vp9_default_scan_32x32, ff_vp9_default_scan_32x32,
+        ff_vp9_default_scan_32x32, ff_vp9_default_scan_32x32
+    }, { // lossless
+        ff_vp9_default_scan_4x4, ff_vp9_default_scan_4x4,
+        ff_vp9_default_scan_4x4, ff_vp9_default_scan_4x4
+    }
+};
+
+const int16_t ff_vp9_default_scan_4x4_nb[16][2] = {
+    {  0,  0 }, {  0,  0 }, {  4,  1 }, {  1,  1 },
+    {  4,  4 }, {  2,  2 }, {  5,  2 }, {  8,  8 },
+    {  8,  5 }, {  6,  3 }, {  9,  6 }, { 12,  9 },
+    { 10,  7 }, { 13, 10 }, { 14, 11 }, {  0,  0 },
+};
+
+const int16_t ff_vp9_col_scan_4x4_nb[16][2] = {
+    {  0,  0 }, {  1,  1 }, {  0,  0 }, {  2,  2 },
+    {  4,  4 }, {  5,  5 }, {  4,  4 }, {  6,  6 },
+    {  8,  8 }, {  9,  9 }, {  8,  8 }, { 12, 12 },
+    { 10, 10 }, { 13, 13 }, { 14, 14 }, {  0,  0 },
+};
+
+const int16_t ff_vp9_row_scan_4x4_nb[16][2] = {
+    {  0,  0 }, {  0,  0 }, {  4,  4 }, {  1,  1 },
+    {  8,  8 }, {  5,  5 }, {  1,  1 }, {  2,  2 },
+    {  9,  9 }, {  2,  2 }, {  6,  6 }, {  3,  3 },
+    { 10, 10 }, {  7,  7 }, { 11, 11 }, {  0,  0 },
+};
+
+const int16_t ff_vp9_default_scan_8x8_nb[64][2] = {
+    {  0,  0 }, {  0,  0 }, {  1,  1 }, {  8,  1 },
+    {  8,  8 }, {  9,  2 }, {  2,  2 }, { 16,  9 },
+    { 16, 16 }, { 17, 10 }, { 10,  3 }, {  3,  3 },
+    { 24, 17 }, { 24, 24 }, { 18, 11 }, { 11,  4 },
+    { 25, 18 }, {  4,  4 }, { 32, 25 }, { 19, 12 },
+    { 26, 19 }, { 32, 32 }, { 12,  5 }, { 33, 26 },
+    {  5,  5 }, { 40, 33 }, { 27, 20 }, { 20, 13 },
+    { 34, 27 }, { 41, 34 }, { 40, 40 }, { 13,  6 },
+    {  6,  6 }, { 35, 28 }, { 28, 21 }, { 42, 35 },
+    { 48, 48 }, { 48, 41 }, { 21, 14 }, { 14,  7 },
+    { 36, 29 }, { 49, 42 }, { 43, 36 }, { 56, 49 },
+    { 29, 22 }, { 22, 15 }, { 50, 43 }, { 44, 37 },
+    { 57, 50 }, { 37, 30 }, { 30, 23 }, { 51, 44 },
+    { 58, 51 }, { 38, 31 }, { 45, 38 }, { 52, 45 },
+    { 59, 52 }, { 46, 39 }, { 53, 46 }, { 60, 53 },
+    { 54, 47 }, { 61, 54 }, { 62, 55 }, {  0,  0 },
+};
+
+const int16_t ff_vp9_col_scan_8x8_nb[64][2] = {
+    {  0,  0 }, {  1,  1 }, {  0,  0 }, {  2,  2 },
+    {  8,  8 }, {  3,  3 }, {  9,  9 }, {  8,  8 },
+    {  4,  4 }, { 10, 10 }, { 16, 16 }, { 11, 11 },
+    { 17, 17 }, {  5,  5 }, { 16, 16 }, { 18, 18 },
+    { 12, 12 }, { 24, 24 }, {  6,  6 }, { 25, 25 },
+    { 19, 19 }, { 24, 24 }, { 13, 13 }, { 26, 26 },
+    { 20, 20 }, { 32, 32 }, { 27, 27 }, { 33, 33 },
+    { 14, 14 }, { 21, 21 }, { 34, 34 }, { 32, 32 },
+    { 28, 28 }, { 40, 40 }, { 35, 35 }, { 22, 22 },
+    { 29, 29 }, { 41, 41 }, { 36, 36 }, { 40, 40 },
+    { 42, 42 }, { 30, 30 }, { 43, 43 }, { 48, 48 },
+    { 37, 37 }, { 49, 49 }, { 48, 48 }, { 44, 44 },
+    { 38, 38 }, { 50, 50 }, { 56, 56 }, { 51, 51 },
+    { 45, 45 }, { 57, 57 }, { 52, 52 }, { 58, 58 },
+    { 46, 46 }, { 59, 59 }, { 53, 53 }, { 60, 60 },
+    { 54, 54 }, { 61, 61 }, { 62, 62 }, {  0,  0 },
+};
+
+const int16_t ff_vp9_row_scan_8x8_nb[64][2] = {
+    {  0,  0 }, {  8,  8 }, {  0,  0 }, {  1,  1 },
+    { 16, 16 }, {  1,  1 }, {  9,  9 }, { 24, 24 },
+    {  2,  2 }, { 17, 17 }, {  2,  2 }, { 32, 32 },
+    { 10, 10 }, {  3,  3 }, { 25, 25 }, { 18, 18 },
+    { 11, 11 }, {  3,  3 }, { 40, 40 }, { 33, 33 },
+    { 26, 26 }, {  4,  4 }, { 19, 19 }, { 48, 48 },
+    { 12, 12 }, {  4,  4 }, { 34, 34 }, { 27, 27 },
+    {  5,  5 }, { 41, 41 }, { 20, 20 }, {  5,  5 },
+    { 13, 13 }, { 35, 35 }, { 28, 28 }, {  6,  6 },
+    { 42, 42 }, { 21, 21 }, { 49, 49 }, {  6,  6 },
+    { 36, 36 }, { 14, 14 }, { 29, 29 }, { 43, 43 },
+    {  7,  7 }, { 50, 50 }, { 22, 22 }, { 15, 15 },
+    { 37, 37 }, { 44, 44 }, { 30, 30 }, { 51, 51 },
+    { 23, 23 }, { 38, 38 }, { 45, 45 }, { 31, 31 },
+    { 52, 52 }, { 39, 39 }, { 53, 53 }, { 46, 46 },
+    { 54, 54 }, { 47, 47 }, { 55, 55 }, {  0,  0 },
+};
+
+const int16_t ff_vp9_default_scan_16x16_nb[256][2] = {
+    {   0,   0 }, {   0,   0 }, {   1,   1 }, {  16,   1 },
+    {  16,  16 }, {   2,   2 }, {  17,   2 }, {  32,  17 },
+    {  32,  32 }, {   3,   3 }, {  33,  18 }, {  18,   3 },
+    {  48,  33 }, {  19,   4 }, {   4,   4 }, {  34,  19 },
+    {  48,  48 }, {  49,  34 }, {  35,  20 }, {  64,  49 },
+    {  20,   5 }, {   5,   5 }, {  50,  35 }, {  64,  64 },
+    {  65,  50 }, {  36,  21 }, {  21,   6 }, {  51,  36 },
+    {   6,   6 }, {  80,  65 }, {  66,  51 }, {  37,  22 },
+    {  81,  66 }, {  52,  37 }, {  22,   7 }, {  80,  80 },
+    {  67,  52 }, {   7,   7 }, {  82,  67 }, {  96,  81 },
+    {  53,  38 }, {  38,  23 }, {  68,  53 }, {  96,  96 },
+    {  23,   8 }, {  97,  82 }, {  83,  68 }, {  69,  54 },
+    {  54,  39 }, {   8,   8 }, {  39,  24 }, {  84,  69 },
+    {  98,  83 }, { 112,  97 }, { 112, 112 }, {  24,   9 },
+    { 113,  98 }, {  99,  84 }, {  70,  55 }, {  85,  70 },
+    {  55,  40 }, {   9,   9 }, {  40,  25 }, { 114,  99 },
+    { 100,  85 }, { 128, 113 }, { 115, 100 }, {  71,  56 },
+    {  86,  71 }, {  25,  10 }, { 129, 114 }, { 128, 128 },
+    { 101,  86 }, {  56,  41 }, {  10,  10 }, {  41,  26 },
+    { 116, 101 }, { 130, 115 }, { 144, 129 }, {  87,  72 },
+    { 102,  87 }, {  26,  11 }, {  72,  57 }, { 131, 116 },
+    { 117, 102 }, { 145, 130 }, {  57,  42 }, { 144, 144 },
+    {  11,  11 }, {  42,  27 }, { 132, 117 }, { 146, 131 },
+    { 103,  88 }, {  88,  73 }, { 118, 103 }, { 160, 145 },
+    {  73,  58 }, { 147, 132 }, { 133, 118 }, {  27,  12 },
+    { 161, 146 }, {  58,  43 }, {  12,  12 }, { 160, 160 },
+    { 119, 104 }, { 148, 133 }, {  89,  74 }, { 134, 119 },
+    { 104,  89 }, { 162, 147 }, {  43,  28 }, {  74,  59 },
+    { 176, 161 }, { 163, 148 }, {  28,  13 }, { 149, 134 },
+    { 120, 105 }, { 135, 120 }, { 177, 162 }, { 164, 149 },
+    {  13,  13 }, { 105,  90 }, {  59,  44 }, {  90,  75 },
+    { 150, 135 }, {  44,  29 }, { 178, 163 }, { 176, 176 },
+    { 136, 121 }, { 165, 150 }, { 121, 106 }, {  75,  60 },
+    { 179, 164 }, { 151, 136 }, {  29,  14 }, {  60,  45 },
+    {  14,  14 }, { 106,  91 }, { 166, 151 }, { 180, 165 },
+    { 192, 177 }, {  91,  76 }, { 192, 192 }, {  45,  30 },
+    { 137, 122 }, { 122, 107 }, { 152, 137 }, { 193, 178 },
+    {  76,  61 }, { 167, 152 }, { 181, 166 }, {  30,  15 },
+    { 194, 179 }, { 208, 193 }, { 182, 167 }, { 107,  92 },
+    { 138, 123 }, {  61,  46 }, { 153, 138 }, {  46,  31 },
+    { 195, 180 }, {  92,  77 }, { 168, 153 }, { 209, 194 },
+    { 196, 181 }, { 208, 208 }, { 123, 108 }, { 183, 168 },
+    { 210, 195 }, {  77,  62 }, { 108,  93 }, { 169, 154 },
+    { 154, 139 }, {  62,  47 }, { 197, 182 }, { 211, 196 },
+    { 184, 169 }, { 224, 209 }, { 224, 224 }, { 139, 124 },
+    {  93,  78 }, { 198, 183 }, { 124, 109 }, {  78,  63 },
+    { 212, 197 }, { 225, 210 }, { 170, 155 }, { 185, 170 },
+    { 155, 140 }, { 213, 198 }, { 199, 184 }, { 109,  94 },
+    { 226, 211 }, { 140, 125 }, {  94,  79 }, { 240, 225 },
+    { 214, 199 }, { 227, 212 }, { 200, 185 }, { 125, 110 },
+    { 241, 226 }, { 186, 171 }, { 171, 156 }, { 156, 141 },
+    { 228, 213 }, { 110,  95 }, { 215, 200 }, { 242, 227 },
+    { 141, 126 }, { 201, 186 }, { 229, 214 }, { 126, 111 },
+    { 216, 201 }, { 243, 228 }, { 172, 157 }, { 187, 172 },
+    { 230, 215 }, { 157, 142 }, { 202, 187 }, { 142, 127 },
+    { 244, 229 }, { 217, 202 }, { 231, 216 }, { 188, 173 },
+    { 245, 230 }, { 158, 143 }, { 173, 158 }, { 232, 217 },
+    { 246, 231 }, { 218, 203 }, { 203, 188 }, { 174, 159 },
+    { 189, 174 }, { 247, 232 }, { 233, 218 }, { 204, 189 },
+    { 219, 204 }, { 248, 233 }, { 190, 175 }, { 234, 219 },
+    { 220, 205 }, { 249, 234 }, { 205, 190 }, { 221, 206 },
+    { 250, 235 }, { 235, 220 }, { 206, 191 }, { 236, 221 },
+    { 222, 207 }, { 251, 236 }, { 237, 222 }, { 252, 237 },
+    { 238, 223 }, { 253, 238 }, { 254, 239 }, {   0,   0 },
+};
+
+const int16_t ff_vp9_col_scan_16x16_nb[256][2] = {
+    {   0,   0 }, {   1,   1 }, {   2,   2 }, {   0,   0 },
+    {   3,   3 }, {  16,  16 }, {   4,   4 }, {  17,  17 },
+    {   5,   5 }, {  18,  18 }, {  16,  16 }, {  19,  19 },
+    {   6,   6 }, {  32,  32 }, {  20,  20 }, {  33,  33 },
+    {   7,   7 }, {  34,  34 }, {  21,  21 }, {  32,  32 },
+    {  35,  35 }, {   8,   8 }, {  48,  48 }, {  22,  22 },
+    {  49,  49 }, {  36,  36 }, {   9,   9 }, {  37,  37 },
+    {  50,  50 }, {  23,  23 }, {  48,  48 }, {  51,  51 },
+    {  10,  10 }, {  64,  64 }, {  38,  38 }, {  24,  24 },
+    {  52,  52 }, {  65,  65 }, {  53,  53 }, {  39,  39 },
+    {  66,  66 }, {  11,  11 }, {  64,  64 }, {  25,  25 },
+    {  67,  67 }, {  54,  54 }, {  80,  80 }, {  40,  40 },
+    {  68,  68 }, {  12,  12 }, {  26,  26 }, {  81,  81 },
+    {  55,  55 }, {  69,  69 }, {  82,  82 }, {  41,  41 },
+    {  13,  13 }, {  83,  83 }, {  80,  80 }, {  70,  70 },
+    {  27,  27 }, {  56,  56 }, {  84,  84 }, {  96,  96 },
+    {  14,  14 }, {  71,  71 }, {  97,  97 }, {  42,  42 },
+    {  85,  85 }, {  57,  57 }, {  98,  98 }, {  28,  28 },
+    {  86,  86 }, {  99,  99 }, {  96,  96 }, {  72,  72 },
+    {  43,  43 }, { 100, 100 }, {  58,  58 }, {  29,  29 },
+    { 112, 112 }, {  87,  87 }, { 113, 113 }, {  73,  73 },
+    { 112, 112 }, { 101, 101 }, {  44,  44 }, {  30,  30 },
+    { 114, 114 }, {  59,  59 }, { 102, 102 }, {  88,  88 },
+    { 115, 115 }, {  74,  74 }, { 128, 128 }, { 116, 116 },
+    {  45,  45 }, { 103, 103 }, {  89,  89 }, {  60,  60 },
+    { 129, 129 }, { 117, 117 }, { 130, 130 }, { 131, 131 },
+    { 104, 104 }, {  75,  75 }, {  46,  46 }, { 118, 118 },
+    { 128, 128 }, {  90,  90 }, {  61,  61 }, { 132, 132 },
+    { 105, 105 }, { 144, 144 }, { 119, 119 }, { 145, 145 },
+    { 133, 133 }, {  76,  76 }, { 146, 146 }, { 120, 120 },
+    {  91,  91 }, { 134, 134 }, { 147, 147 }, {  62,  62 },
+    { 106, 106 }, { 135, 135 }, { 121, 121 }, {  92,  92 },
+    { 148, 148 }, { 144, 144 }, {  77,  77 }, { 149, 149 },
+    { 136, 136 }, { 107, 107 }, { 160, 160 }, { 161, 161 },
+    { 150, 150 }, { 122, 122 }, {  78,  78 }, { 137, 137 },
+    { 162, 162 }, { 151, 151 }, {  93,  93 }, { 163, 163 },
+    { 108, 108 }, { 164, 164 }, { 152, 152 }, { 123, 123 },
+    { 138, 138 }, { 160, 160 }, { 165, 165 }, {  94,  94 },
+    { 176, 176 }, { 166, 166 }, { 109, 109 }, { 153, 153 },
+    { 177, 177 }, { 124, 124 }, { 178, 178 }, { 139, 139 },
+    { 167, 167 }, { 154, 154 }, { 110, 110 }, { 179, 179 },
+    { 176, 176 }, { 180, 180 }, { 168, 168 }, { 140, 140 },
+    { 125, 125 }, { 181, 181 }, { 192, 192 }, { 193, 193 },
+    { 155, 155 }, { 182, 182 }, { 169, 169 }, { 194, 194 },
+    { 126, 126 }, { 141, 141 }, { 195, 195 }, { 183, 183 },
+    { 192, 192 }, { 196, 196 }, { 156, 156 }, { 170, 170 },
+    { 142, 142 }, { 184, 184 }, { 197, 197 }, { 208, 208 },
+    { 198, 198 }, { 209, 209 }, { 171, 171 }, { 157, 157 },
+    { 185, 185 }, { 210, 210 }, { 208, 208 }, { 211, 211 },
+    { 199, 199 }, { 224, 224 }, { 158, 158 }, { 212, 212 },
+    { 224, 224 }, { 186, 186 }, { 200, 200 }, { 172, 172 },
+    { 225, 225 }, { 213, 213 }, { 214, 214 }, { 226, 226 },
+    { 201, 201 }, { 227, 227 }, { 187, 187 }, { 240, 240 },
+    { 215, 215 }, { 173, 173 }, { 228, 228 }, { 241, 241 },
+    { 202, 202 }, { 242, 242 }, { 216, 216 }, { 229, 229 },
+    { 174, 174 }, { 188, 188 }, { 243, 243 }, { 230, 230 },
+    { 203, 203 }, { 217, 217 }, { 231, 231 }, { 244, 244 },
+    { 218, 218 }, { 245, 245 }, { 189, 189 }, { 232, 232 },
+    { 204, 204 }, { 190, 190 }, { 246, 246 }, { 233, 233 },
+    { 247, 247 }, { 219, 219 }, { 205, 205 }, { 248, 248 },
+    { 234, 234 }, { 220, 220 }, { 206, 206 }, { 249, 249 },
+    { 235, 235 }, { 221, 221 }, { 250, 250 }, { 222, 222 },
+    { 236, 236 }, { 237, 237 }, { 251, 251 }, { 238, 238 },
+    { 252, 252 }, { 253, 253 }, { 254, 254 }, {   0,   0 },
+};
+
+const int16_t ff_vp9_row_scan_16x16_nb[256][2] = {
+    {   0,   0 }, {  16,  16 }, {   0,   0 }, {  32,  32 },
+    {   1,   1 }, {  48,  48 }, {  17,  17 }, {   1,   1 },
+    {  64,  64 }, {   2,   2 }, {  33,  33 }, {  80,  80 },
+    {  18,  18 }, {   2,   2 }, {  49,  49 }, {   3,   3 },
+    {  96,  96 }, {  34,  34 }, {  65,  65 }, {  19,  19 },
+    {   3,   3 }, { 112, 112 }, {  50,  50 }, {   4,   4 },
+    {  81,  81 }, {  35,  35 }, {  66,  66 }, {   4,   4 },
+    { 128, 128 }, {  20,  20 }, {  51,  51 }, {  97,  97 },
+    {  82,  82 }, {   5,   5 }, {  36,  36 }, { 144, 144 },
+    {  67,  67 }, { 113, 113 }, {  21,  21 }, {  52,  52 },
+    {   5,   5 }, {  98,  98 }, { 160, 160 }, {  83,  83 },
+    {  37,  37 }, {   6,   6 }, {  68,  68 }, { 129, 129 },
+    {  22,  22 }, {  53,  53 }, { 114, 114 }, {   6,   6 },
+    {  99,  99 }, { 176, 176 }, {  84,  84 }, {  38,  38 },
+    {   7,   7 }, {  69,  69 }, { 145, 145 }, { 130, 130 },
+    { 115, 115 }, {  23,  23 }, {  54,  54 }, { 192, 192 },
+    { 100, 100 }, {   7,   7 }, {  85,  85 }, { 161, 161 },
+    {  39,  39 }, {  70,  70 }, {   8,   8 }, { 146, 146 },
+    { 131, 131 }, { 116, 116 }, {  55,  55 }, { 208, 208 },
+    { 101, 101 }, {  24,  24 }, {  86,  86 }, {   8,   8 },
+    { 132, 132 }, {  40,  40 }, {  71,  71 }, { 177, 177 },
+    { 147, 147 }, { 224, 224 }, { 117, 117 }, { 162, 162 },
+    {   9,   9 }, { 102, 102 }, {  56,  56 }, {  25,  25 },
+    {  87,  87 }, { 148, 148 }, {   9,   9 }, { 133, 133 },
+    {  72,  72 }, { 118, 118 }, { 193, 193 }, { 163, 163 },
+    {  41,  41 }, { 103, 103 }, { 178, 178 }, {  10,  10 },
+    {  57,  57 }, { 149, 149 }, { 134, 134 }, {  88,  88 },
+    {  26,  26 }, { 119, 119 }, {  10,  10 }, { 164, 164 },
+    { 104, 104 }, {  73,  73 }, { 209, 209 }, { 179, 179 },
+    {  42,  42 }, {  11,  11 }, { 194, 194 }, { 135, 135 },
+    { 165, 165 }, { 150, 150 }, {  58,  58 }, {  27,  27 },
+    {  89,  89 }, {  11,  11 }, { 120, 120 }, {  74,  74 },
+    {  43,  43 }, { 225, 225 }, { 105, 105 }, {  12,  12 },
+    { 180, 180 }, { 151, 151 }, { 195, 195 }, { 136, 136 },
+    {  28,  28 }, { 166, 166 }, { 121, 121 }, {  59,  59 },
+    {  12,  12 }, { 210, 210 }, {  90,  90 }, { 106, 106 },
+    {  44,  44 }, { 181, 181 }, {  75,  75 }, { 152, 152 },
+    {  13,  13 }, { 167, 167 }, { 137, 137 }, {  13,  13 },
+    {  60,  60 }, { 196, 196 }, { 122, 122 }, {  29,  29 },
+    {  91,  91 }, {  14,  14 }, { 182, 182 }, {  76,  76 },
+    { 211, 211 }, { 153, 153 }, {  14,  14 }, { 107, 107 },
+    { 138, 138 }, {  45,  45 }, { 226, 226 }, { 168, 168 },
+    { 197, 197 }, { 123, 123 }, {  30,  30 }, {  61,  61 },
+    {  15,  15 }, {  92,  92 }, { 154, 154 }, { 183, 183 },
+    { 169, 169 }, { 108, 108 }, { 212, 212 }, {  77,  77 },
+    { 139, 139 }, { 198, 198 }, {  46,  46 }, { 124, 124 },
+    { 227, 227 }, {  62,  62 }, {  31,  31 }, { 184, 184 },
+    {  93,  93 }, { 170, 170 }, { 155, 155 }, { 185, 185 },
+    {  78,  78 }, {  47,  47 }, { 199, 199 }, { 213, 213 },
+    { 140, 140 }, {  63,  63 }, { 109, 109 }, { 125, 125 },
+    {  94,  94 }, { 200, 200 }, { 171, 171 }, { 156, 156 },
+    { 228, 228 }, { 186, 186 }, { 214, 214 }, { 201, 201 },
+    {  79,  79 }, { 141, 141 }, { 110, 110 }, { 229, 229 },
+    {  95,  95 }, { 126, 126 }, { 215, 215 }, { 172, 172 },
+    { 111, 111 }, { 142, 142 }, { 202, 202 }, { 157, 157 },
+    { 216, 216 }, { 230, 230 }, { 217, 217 }, { 187, 187 },
+    { 127, 127 }, { 231, 231 }, { 158, 158 }, { 173, 173 },
+    { 143, 143 }, { 203, 203 }, { 188, 188 }, { 232, 232 },
+    { 218, 218 }, { 233, 233 }, { 159, 159 }, { 174, 174 },
+    { 204, 204 }, { 189, 189 }, { 234, 234 }, { 219, 219 },
+    { 175, 175 }, { 205, 205 }, { 235, 235 }, { 220, 220 },
+    { 190, 190 }, { 236, 236 }, { 206, 206 }, { 191, 191 },
+    { 221, 221 }, { 207, 207 }, { 237, 237 }, { 222, 222 },
+    { 238, 238 }, { 223, 223 }, { 239, 239 }, {   0,   0 },
+};
+
+const int16_t ff_vp9_default_scan_32x32_nb[1024][2] = {
+    {    0,    0 }, {    0,    0 }, {    1,    1 }, {   32,    1 },
+    {   32,   32 }, {    2,    2 }, {   33,    2 }, {   64,   33 },
+    {    3,    3 }, {   64,   64 }, {   34,    3 }, {   65,   34 },
+    {    4,    4 }, {   35,    4 }, {   96,   65 }, {   66,   35 },
+    {   96,   96 }, {   97,   66 }, {   67,   36 }, {   36,    5 },
+    {    5,    5 }, {  128,   97 }, {   98,   67 }, {    6,    6 },
+    {  128,  128 }, {   68,   37 }, {   37,    6 }, {  129,   98 },
+    {   99,   68 }, {  160,  129 }, {  130,   99 }, {   38,    7 },
+    {   69,   38 }, {    7,    7 }, {  100,   69 }, {  161,  130 },
+    {  131,  100 }, {  160,  160 }, {   70,   39 }, {   39,    8 },
+    {    8,    8 }, {  101,   70 }, {  162,  131 }, {  132,  101 },
+    {  192,  161 }, {   71,   40 }, {  192,  192 }, {  102,   71 },
+    {   40,    9 }, {  163,  132 }, {    9,    9 }, {  193,  162 },
+    {  133,  102 }, {  164,  133 }, {   72,   41 }, {  103,   72 },
+    {  134,  103 }, {  224,  193 }, {   41,   10 }, {  194,  163 },
+    {   10,   10 }, {  224,  224 }, {  165,  134 }, {  225,  194 },
+    {  195,  164 }, {   73,   42 }, {  104,   73 }, {  135,  104 },
+    {   42,   11 }, {   11,   11 }, {  166,  135 }, {  196,  165 },
+    {  226,  195 }, {  256,  225 }, {   74,   43 }, {  105,   74 },
+    {  136,  105 }, {  227,  196 }, {   43,   12 }, {  197,  166 },
+    {  167,  136 }, {  257,  226 }, {  256,  256 }, {   12,   12 },
+    {  228,  197 }, {   75,   44 }, {  106,   75 }, {  198,  167 },
+    {  137,  106 }, {  258,  227 }, {  168,  137 }, {  288,  257 },
+    {   44,   13 }, {  229,  198 }, {  259,  228 }, {  199,  168 },
+    {  107,   76 }, {   13,   13 }, {  169,  138 }, {  138,  107 },
+    {  288,  288 }, {  289,  258 }, {   76,   45 }, {  230,  199 },
+    {  260,  229 }, {   45,   14 }, {  200,  169 }, {  139,  108 },
+    {  290,  259 }, {  108,   77 }, {  231,  200 }, {  320,  289 },
+    {  261,  230 }, {  170,  139 }, {   77,   46 }, {  291,  260 },
+    {   14,   14 }, {  321,  290 }, {  201,  170 }, {  262,  231 },
+    {  320,  320 }, {  171,  140 }, {  292,  261 }, {  232,  201 },
+    {  140,  109 }, {  322,  291 }, {  109,   78 }, {   46,   15 },
+    {  202,  171 }, {  263,  232 }, {  233,  202 }, {  293,  262 },
+    {  352,  321 }, {  323,  292 }, {   15,   15 }, {   78,   47 },
+    {  203,  172 }, {  264,  233 }, {  294,  263 }, {  324,  293 },
+    {  172,  141 }, {  353,  322 }, {  141,  110 }, {  234,  203 },
+    {  352,  352 }, {   47,   16 }, {  295,  264 }, {  110,   79 },
+    {  265,  234 }, {  354,  323 }, {  325,  294 }, {   79,   48 },
+    {   16,   16 }, {  204,  173 }, {  235,  204 }, {  173,  142 },
+    {  355,  324 }, {  384,  353 }, {  326,  295 }, {  142,  111 },
+    {  296,  265 }, {  266,  235 }, {  356,  325 }, {  385,  354 },
+    {  111,   80 }, {   48,   17 }, {  327,  296 }, {  297,  266 },
+    {  205,  174 }, {  384,  384 }, {  236,  205 }, {  357,  326 },
+    {  386,  355 }, {   80,   49 }, {  174,  143 }, {   17,   17 },
+    {  328,  297 }, {  358,  327 }, {  387,  356 }, {  298,  267 },
+    {  329,  298 }, {  388,  357 }, {  112,   81 }, {  416,  385 },
+    {  237,  206 }, {  359,  328 }, {   49,   18 }, {  206,  175 },
+    {  417,  386 }, {  389,  358 }, {  330,  299 }, {   18,   18 },
+    {  416,  416 }, {  360,  329 }, {   81,   50 }, {  418,  387 },
+    {  390,  359 }, {  238,  207 }, {   50,   19 }, {  361,  330 },
+    {  419,  388 }, {  113,   82 }, {  448,  417 }, {  448,  448 },
+    {  420,  389 }, {   82,   51 }, {  362,  331 }, {  449,  418 },
+    {  421,  390 }, {  480,  480 }, {  450,  419 }, {  422,  391 },
+    {  114,   83 }, {  451,  420 }, {  480,  449 }, {  452,  421 },
+    {  481,  450 }, {  453,  422 }, {  512,  512 }, {  482,  451 },
+    {  454,  423 }, {  512,  481 }, {  483,  452 }, {  513,  482 },
+    {  484,  453 }, {  514,  483 }, {  485,  454 }, {  544,  513 },
+    {  544,  544 }, {  486,  455 }, {  545,  514 }, {  546,  515 },
+    {  576,  576 }, {  576,  545 }, {  577,  546 }, {  578,  547 },
+    {  608,  577 }, {  609,  578 }, {  610,  579 }, {   19,   19 },
+    {  143,  112 }, {  267,  236 }, {  391,  360 }, {  515,  484 },
+    {  608,  608 }, {   20,   20 }, {   51,   20 }, {  144,  113 },
+    {  175,  144 }, {  268,  237 }, {  299,  268 }, {  392,  361 },
+    {  423,  392 }, {  516,  485 }, {  547,  516 }, {  640,  609 },
+    {  640,  640 }, {   21,   21 }, {   52,   21 }, {   83,   52 },
+    {  145,  114 }, {  176,  145 }, {  207,  176 }, {  269,  238 },
+    {  300,  269 }, {  331,  300 }, {  393,  362 }, {  424,  393 },
+    {  455,  424 }, {  517,  486 }, {  548,  517 }, {  579,  548 },
+    {  641,  610 }, {  672,  641 }, {  672,  672 }, {   22,   22 },
+    {   53,   22 }, {   84,   53 }, {  115,   84 }, {  146,  115 },
+    {  177,  146 }, {  208,  177 }, {  239,  208 }, {  270,  239 },
+    {  301,  270 }, {  332,  301 }, {  363,  332 }, {  394,  363 },
+    {  425,  394 }, {  456,  425 }, {  487,  456 }, {  518,  487 },
+    {  549,  518 }, {  580,  549 }, {  611,  580 }, {  642,  611 },
+    {  673,  642 }, {  704,  673 }, {  704,  704 }, {   54,   23 },
+    {   85,   54 }, {  116,   85 }, {  178,  147 }, {  209,  178 },
+    {  240,  209 }, {  302,  271 }, {  333,  302 }, {  364,  333 },
+    {  426,  395 }, {  457,  426 }, {  488,  457 }, {  550,  519 },
+    {  581,  550 }, {  612,  581 }, {  674,  643 }, {  705,  674 },
+    {  736,  705 }, {   86,   55 }, {  117,   86 }, {  210,  179 },
+    {  241,  210 }, {  334,  303 }, {  365,  334 }, {  458,  427 },
+    {  489,  458 }, {  582,  551 }, {  613,  582 }, {  706,  675 },
+    {  737,  706 }, {  118,   87 }, {  242,  211 }, {  366,  335 },
+    {  490,  459 }, {  614,  583 }, {  738,  707 }, {   23,   23 },
+    {  147,  116 }, {  271,  240 }, {  395,  364 }, {  519,  488 },
+    {  643,  612 }, {  736,  736 }, {   24,   24 }, {   55,   24 },
+    {  148,  117 }, {  179,  148 }, {  272,  241 }, {  303,  272 },
+    {  396,  365 }, {  427,  396 }, {  520,  489 }, {  551,  520 },
+    {  644,  613 }, {  675,  644 }, {  768,  737 }, {  768,  768 },
+    {   25,   25 }, {   56,   25 }, {   87,   56 }, {  149,  118 },
+    {  180,  149 }, {  211,  180 }, {  273,  242 }, {  304,  273 },
+    {  335,  304 }, {  397,  366 }, {  428,  397 }, {  459,  428 },
+    {  521,  490 }, {  552,  521 }, {  583,  552 }, {  645,  614 },
+    {  676,  645 }, {  707,  676 }, {  769,  738 }, {  800,  769 },
+    {  800,  800 }, {   26,   26 }, {   57,   26 }, {   88,   57 },
+    {  119,   88 }, {  150,  119 }, {  181,  150 }, {  212,  181 },
+    {  243,  212 }, {  274,  243 }, {  305,  274 }, {  336,  305 },
+    {  367,  336 }, {  398,  367 }, {  429,  398 }, {  460,  429 },
+    {  491,  460 }, {  522,  491 }, {  553,  522 }, {  584,  553 },
+    {  615,  584 }, {  646,  615 }, {  677,  646 }, {  708,  677 },
+    {  739,  708 }, {  770,  739 }, {  801,  770 }, {  832,  801 },
+    {  832,  832 }, {   58,   27 }, {   89,   58 }, {  120,   89 },
+    {  182,  151 }, {  213,  182 }, {  244,  213 }, {  306,  275 },
+    {  337,  306 }, {  368,  337 }, {  430,  399 }, {  461,  430 },
+    {  492,  461 }, {  554,  523 }, {  585,  554 }, {  616,  585 },
+    {  678,  647 }, {  709,  678 }, {  740,  709 }, {  802,  771 },
+    {  833,  802 }, {  864,  833 }, {   90,   59 }, {  121,   90 },
+    {  214,  183 }, {  245,  214 }, {  338,  307 }, {  369,  338 },
+    {  462,  431 }, {  493,  462 }, {  586,  555 }, {  617,  586 },
+    {  710,  679 }, {  741,  710 }, {  834,  803 }, {  865,  834 },
+    {  122,   91 }, {  246,  215 }, {  370,  339 }, {  494,  463 },
+    {  618,  587 }, {  742,  711 }, {  866,  835 }, {   27,   27 },
+    {  151,  120 }, {  275,  244 }, {  399,  368 }, {  523,  492 },
+    {  647,  616 }, {  771,  740 }, {  864,  864 }, {   28,   28 },
+    {   59,   28 }, {  152,  121 }, {  183,  152 }, {  276,  245 },
+    {  307,  276 }, {  400,  369 }, {  431,  400 }, {  524,  493 },
+    {  555,  524 }, {  648,  617 }, {  679,  648 }, {  772,  741 },
+    {  803,  772 }, {  896,  865 }, {  896,  896 }, {   29,   29 },
+    {   60,   29 }, {   91,   60 }, {  153,  122 }, {  184,  153 },
+    {  215,  184 }, {  277,  246 }, {  308,  277 }, {  339,  308 },
+    {  401,  370 }, {  432,  401 }, {  463,  432 }, {  525,  494 },
+    {  556,  525 }, {  587,  556 }, {  649,  618 }, {  680,  649 },
+    {  711,  680 }, {  773,  742 }, {  804,  773 }, {  835,  804 },
+    {  897,  866 }, {  928,  897 }, {  928,  928 }, {   30,   30 },
+    {   61,   30 }, {   92,   61 }, {  123,   92 }, {  154,  123 },
+    {  185,  154 }, {  216,  185 }, {  247,  216 }, {  278,  247 },
+    {  309,  278 }, {  340,  309 }, {  371,  340 }, {  402,  371 },
+    {  433,  402 }, {  464,  433 }, {  495,  464 }, {  526,  495 },
+    {  557,  526 }, {  588,  557 }, {  619,  588 }, {  650,  619 },
+    {  681,  650 }, {  712,  681 }, {  743,  712 }, {  774,  743 },
+    {  805,  774 }, {  836,  805 }, {  867,  836 }, {  898,  867 },
+    {  929,  898 }, {  960,  929 }, {  960,  960 }, {   62,   31 },
+    {   93,   62 }, {  124,   93 }, {  186,  155 }, {  217,  186 },
+    {  248,  217 }, {  310,  279 }, {  341,  310 }, {  372,  341 },
+    {  434,  403 }, {  465,  434 }, {  496,  465 }, {  558,  527 },
+    {  589,  558 }, {  620,  589 }, {  682,  651 }, {  713,  682 },
+    {  744,  713 }, {  806,  775 }, {  837,  806 }, {  868,  837 },
+    {  930,  899 }, {  961,  930 }, {  992,  961 }, {   94,   63 },
+    {  125,   94 }, {  218,  187 }, {  249,  218 }, {  342,  311 },
+    {  373,  342 }, {  466,  435 }, {  497,  466 }, {  590,  559 },
+    {  621,  590 }, {  714,  683 }, {  745,  714 }, {  838,  807 },
+    {  869,  838 }, {  962,  931 }, {  993,  962 }, {  126,   95 },
+    {  250,  219 }, {  374,  343 }, {  498,  467 }, {  622,  591 },
+    {  746,  715 }, {  870,  839 }, {  994,  963 }, {  155,  124 },
+    {  279,  248 }, {  403,  372 }, {  527,  496 }, {  651,  620 },
+    {  775,  744 }, {  899,  868 }, {  156,  125 }, {  187,  156 },
+    {  280,  249 }, {  311,  280 }, {  404,  373 }, {  435,  404 },
+    {  528,  497 }, {  559,  528 }, {  652,  621 }, {  683,  652 },
+    {  776,  745 }, {  807,  776 }, {  900,  869 }, {  931,  900 },
+    {  157,  126 }, {  188,  157 }, {  219,  188 }, {  281,  250 },
+    {  312,  281 }, {  343,  312 }, {  405,  374 }, {  436,  405 },
+    {  467,  436 }, {  529,  498 }, {  560,  529 }, {  591,  560 },
+    {  653,  622 }, {  684,  653 }, {  715,  684 }, {  777,  746 },
+    {  808,  777 }, {  839,  808 }, {  901,  870 }, {  932,  901 },
+    {  963,  932 }, {  158,  127 }, {  189,  158 }, {  220,  189 },
+    {  251,  220 }, {  282,  251 }, {  313,  282 }, {  344,  313 },
+    {  375,  344 }, {  406,  375 }, {  437,  406 }, {  468,  437 },
+    {  499,  468 }, {  530,  499 }, {  561,  530 }, {  592,  561 },
+    {  623,  592 }, {  654,  623 }, {  685,  654 }, {  716,  685 },
+    {  747,  716 }, {  778,  747 }, {  809,  778 }, {  840,  809 },
+    {  871,  840 }, {  902,  871 }, {  933,  902 }, {  964,  933 },
+    {  995,  964 }, {  190,  159 }, {  221,  190 }, {  252,  221 },
+    {  314,  283 }, {  345,  314 }, {  376,  345 }, {  438,  407 },
+    {  469,  438 }, {  500,  469 }, {  562,  531 }, {  593,  562 },
+    {  624,  593 }, {  686,  655 }, {  717,  686 }, {  748,  717 },
+    {  810,  779 }, {  841,  810 }, {  872,  841 }, {  934,  903 },
+    {  965,  934 }, {  996,  965 }, {  222,  191 }, {  253,  222 },
+    {  346,  315 }, {  377,  346 }, {  470,  439 }, {  501,  470 },
+    {  594,  563 }, {  625,  594 }, {  718,  687 }, {  749,  718 },
+    {  842,  811 }, {  873,  842 }, {  966,  935 }, {  997,  966 },
+    {  254,  223 }, {  378,  347 }, {  502,  471 }, {  626,  595 },
+    {  750,  719 }, {  874,  843 }, {  998,  967 }, {  283,  252 },
+    {  407,  376 }, {  531,  500 }, {  655,  624 }, {  779,  748 },
+    {  903,  872 }, {  284,  253 }, {  315,  284 }, {  408,  377 },
+    {  439,  408 }, {  532,  501 }, {  563,  532 }, {  656,  625 },
+    {  687,  656 }, {  780,  749 }, {  811,  780 }, {  904,  873 },
+    {  935,  904 }, {  285,  254 }, {  316,  285 }, {  347,  316 },
+    {  409,  378 }, {  440,  409 }, {  471,  440 }, {  533,  502 },
+    {  564,  533 }, {  595,  564 }, {  657,  626 }, {  688,  657 },
+    {  719,  688 }, {  781,  750 }, {  812,  781 }, {  843,  812 },
+    {  905,  874 }, {  936,  905 }, {  967,  936 }, {  286,  255 },
+    {  317,  286 }, {  348,  317 }, {  379,  348 }, {  410,  379 },
+    {  441,  410 }, {  472,  441 }, {  503,  472 }, {  534,  503 },
+    {  565,  534 }, {  596,  565 }, {  627,  596 }, {  658,  627 },
+    {  689,  658 }, {  720,  689 }, {  751,  720 }, {  782,  751 },
+    {  813,  782 }, {  844,  813 }, {  875,  844 }, {  906,  875 },
+    {  937,  906 }, {  968,  937 }, {  999,  968 }, {  318,  287 },
+    {  349,  318 }, {  380,  349 }, {  442,  411 }, {  473,  442 },
+    {  504,  473 }, {  566,  535 }, {  597,  566 }, {  628,  597 },
+    {  690,  659 }, {  721,  690 }, {  752,  721 }, {  814,  783 },
+    {  845,  814 }, {  876,  845 }, {  938,  907 }, {  969,  938 },
+    { 1000,  969 }, {  350,  319 }, {  381,  350 }, {  474,  443 },
+    {  505,  474 }, {  598,  567 }, {  629,  598 }, {  722,  691 },
+    {  753,  722 }, {  846,  815 }, {  877,  846 }, {  970,  939 },
+    { 1001,  970 }, {  382,  351 }, {  506,  475 }, {  630,  599 },
+    {  754,  723 }, {  878,  847 }, { 1002,  971 }, {  411,  380 },
+    {  535,  504 }, {  659,  628 }, {  783,  752 }, {  907,  876 },
+    {  412,  381 }, {  443,  412 }, {  536,  505 }, {  567,  536 },
+    {  660,  629 }, {  691,  660 }, {  784,  753 }, {  815,  784 },
+    {  908,  877 }, {  939,  908 }, {  413,  382 }, {  444,  413 },
+    {  475,  444 }, {  537,  506 }, {  568,  537 }, {  599,  568 },
+    {  661,  630 }, {  692,  661 }, {  723,  692 }, {  785,  754 },
+    {  816,  785 }, {  847,  816 }, {  909,  878 }, {  940,  909 },
+    {  971,  940 }, {  414,  383 }, {  445,  414 }, {  476,  445 },
+    {  507,  476 }, {  538,  507 }, {  569,  538 }, {  600,  569 },
+    {  631,  600 }, {  662,  631 }, {  693,  662 }, {  724,  693 },
+    {  755,  724 }, {  786,  755 }, {  817,  786 }, {  848,  817 },
+    {  879,  848 }, {  910,  879 }, {  941,  910 }, {  972,  941 },
+    { 1003,  972 }, {  446,  415 }, {  477,  446 }, {  508,  477 },
+    {  570,  539 }, {  601,  570 }, {  632,  601 }, {  694,  663 },
+    {  725,  694 }, {  756,  725 }, {  818,  787 }, {  849,  818 },
+    {  880,  849 }, {  942,  911 }, {  973,  942 }, { 1004,  973 },
+    {  478,  447 }, {  509,  478 }, {  602,  571 }, {  633,  602 },
+    {  726,  695 }, {  757,  726 }, {  850,  819 }, {  881,  850 },
+    {  974,  943 }, { 1005,  974 }, {  510,  479 }, {  634,  603 },
+    {  758,  727 }, {  882,  851 }, { 1006,  975 }, {  539,  508 },
+    {  663,  632 }, {  787,  756 }, {  911,  880 }, {  540,  509 },
+    {  571,  540 }, {  664,  633 }, {  695,  664 }, {  788,  757 },
+    {  819,  788 }, {  912,  881 }, {  943,  912 }, {  541,  510 },
+    {  572,  541 }, {  603,  572 }, {  665,  634 }, {  696,  665 },
+    {  727,  696 }, {  789,  758 }, {  820,  789 }, {  851,  820 },
+    {  913,  882 }, {  944,  913 }, {  975,  944 }, {  542,  511 },
+    {  573,  542 }, {  604,  573 }, {  635,  604 }, {  666,  635 },
+    {  697,  666 }, {  728,  697 }, {  759,  728 }, {  790,  759 },
+    {  821,  790 }, {  852,  821 }, {  883,  852 }, {  914,  883 },
+    {  945,  914 }, {  976,  945 }, { 1007,  976 }, {  574,  543 },
+    {  605,  574 }, {  636,  605 }, {  698,  667 }, {  729,  698 },
+    {  760,  729 }, {  822,  791 }, {  853,  822 }, {  884,  853 },
+    {  946,  915 }, {  977,  946 }, { 1008,  977 }, {  606,  575 },
+    {  637,  606 }, {  730,  699 }, {  761,  730 }, {  854,  823 },
+    {  885,  854 }, {  978,  947 }, { 1009,  978 }, {  638,  607 },
+    {  762,  731 }, {  886,  855 }, { 1010,  979 }, {  667,  636 },
+    {  791,  760 }, {  915,  884 }, {  668,  637 }, {  699,  668 },
+    {  792,  761 }, {  823,  792 }, {  916,  885 }, {  947,  916 },
+    {  669,  638 }, {  700,  669 }, {  731,  700 }, {  793,  762 },
+    {  824,  793 }, {  855,  824 }, {  917,  886 }, {  948,  917 },
+    {  979,  948 }, {  670,  639 }, {  701,  670 }, {  732,  701 },
+    {  763,  732 }, {  794,  763 }, {  825,  794 }, {  856,  825 },
+    {  887,  856 }, {  918,  887 }, {  949,  918 }, {  980,  949 },
+    { 1011,  980 }, {  702,  671 }, {  733,  702 }, {  764,  733 },
+    {  826,  795 }, {  857,  826 }, {  888,  857 }, {  950,  919 },
+    {  981,  950 }, { 1012,  981 }, {  734,  703 }, {  765,  734 },
+    {  858,  827 }, {  889,  858 }, {  982,  951 }, { 1013,  982 },
+    {  766,  735 }, {  890,  859 }, { 1014,  983 }, {  795,  764 },
+    {  919,  888 }, {  796,  765 }, {  827,  796 }, {  920,  889 },
+    {  951,  920 }, {  797,  766 }, {  828,  797 }, {  859,  828 },
+    {  921,  890 }, {  952,  921 }, {  983,  952 }, {  798,  767 },
+    {  829,  798 }, {  860,  829 }, {  891,  860 }, {  922,  891 },
+    {  953,  922 }, {  984,  953 }, { 1015,  984 }, {  830,  799 },
+    {  861,  830 }, {  892,  861 }, {  954,  923 }, {  985,  954 },
+    { 1016,  985 }, {  862,  831 }, {  893,  862 }, {  986,  955 },
+    { 1017,  986 }, {  894,  863 }, { 1018,  987 }, {  923,  892 },
+    {  924,  893 }, {  955,  924 }, {  925,  894 }, {  956,  925 },
+    {  987,  956 }, {  926,  895 }, {  957,  926 }, {  988,  957 },
+    { 1019,  988 }, {  958,  927 }, {  989,  958 }, { 1020,  989 },
+    {  990,  959 }, { 1021,  990 }, { 1022,  991 }, {    0,    0 },
+};
+
+const int16_t (*ff_vp9_scans_nb[5][4])[2] = {
+    {
+        ff_vp9_default_scan_4x4_nb, ff_vp9_col_scan_4x4_nb,
+        ff_vp9_row_scan_4x4_nb, ff_vp9_default_scan_4x4_nb
+    }, {
+        ff_vp9_default_scan_8x8_nb, ff_vp9_col_scan_8x8_nb,
+        ff_vp9_row_scan_8x8_nb, ff_vp9_default_scan_8x8_nb
+    }, {
+        ff_vp9_default_scan_16x16_nb, ff_vp9_col_scan_16x16_nb,
+        ff_vp9_row_scan_16x16_nb, ff_vp9_default_scan_16x16_nb
+    }, {
+        ff_vp9_default_scan_32x32_nb, ff_vp9_default_scan_32x32_nb,
+        ff_vp9_default_scan_32x32_nb, ff_vp9_default_scan_32x32_nb
+    }, { // lossless
+        ff_vp9_default_scan_4x4_nb, ff_vp9_default_scan_4x4_nb,
+        ff_vp9_default_scan_4x4_nb, ff_vp9_default_scan_4x4_nb
+    }
+};
+
+const uint8_t ff_vp9_model_pareto8[256][8] = {
+    {   6,  86, 128,  11,  87,  42,  91,  52 },
+    {   3,  86, 128,   6,  86,  23,  88,  29 },
+    {   6,  86, 128,  11,  87,  42,  91,  52 },
+    {   9,  86, 129,  17,  88,  61,  94,  76 },
+    {  12,  86, 129,  22,  88,  77,  97,  93 },
+    {  15,  87, 129,  28,  89,  93, 100, 110 },
+    {  17,  87, 129,  33,  90, 105, 103, 123 },
+    {  20,  88, 130,  38,  91, 118, 106, 136 },
+    {  23,  88, 130,  43,  91, 128, 108, 146 },
+    {  26,  89, 131,  48,  92, 139, 111, 156 },
+    {  28,  89, 131,  53,  93, 147, 114, 163 },
+    {  31,  90, 131,  58,  94, 156, 117, 171 },
+    {  34,  90, 131,  62,  94, 163, 119, 177 },
+    {  37,  90, 132,  66,  95, 171, 122, 184 },
+    {  39,  90, 132,  70,  96, 177, 124, 189 },
+    {  42,  91, 132,  75,  97, 183, 127, 194 },
+    {  44,  91, 132,  79,  97, 188, 129, 198 },
+    {  47,  92, 133,  83,  98, 193, 132, 202 },
+    {  49,  92, 133,  86,  99, 197, 134, 205 },
+    {  52,  93, 133,  90, 100, 201, 137, 208 },
+    {  54,  93, 133,  94, 100, 204, 139, 211 },
+    {  57,  94, 134,  98, 101, 208, 142, 214 },
+    {  59,  94, 134, 101, 102, 211, 144, 216 },
+    {  62,  94, 135, 105, 103, 214, 146, 218 },
+    {  64,  94, 135, 108, 103, 216, 148, 220 },
+    {  66,  95, 135, 111, 104, 219, 151, 222 },
+    {  68,  95, 135, 114, 105, 221, 153, 223 },
+    {  71,  96, 136, 117, 106, 224, 155, 225 },
+    {  73,  96, 136, 120, 106, 225, 157, 226 },
+    {  76,  97, 136, 123, 107, 227, 159, 228 },
+    {  78,  97, 136, 126, 108, 229, 160, 229 },
+    {  80,  98, 137, 129, 109, 231, 162, 231 },
+    {  82,  98, 137, 131, 109, 232, 164, 232 },
+    {  84,  98, 138, 134, 110, 234, 166, 233 },
+    {  86,  98, 138, 137, 111, 235, 168, 234 },
+    {  89,  99, 138, 140, 112, 236, 170, 235 },
+    {  91,  99, 138, 142, 112, 237, 171, 235 },
+    {  93, 100, 139, 145, 113, 238, 173, 236 },
+    {  95, 100, 139, 147, 114, 239, 174, 237 },
+    {  97, 101, 140, 149, 115, 240, 176, 238 },
+    {  99, 101, 140, 151, 115, 241, 177, 238 },
+    { 101, 102, 140, 154, 116, 242, 179, 239 },
+    { 103, 102, 140, 156, 117, 242, 180, 239 },
+    { 105, 103, 141, 158, 118, 243, 182, 240 },
+    { 107, 103, 141, 160, 118, 243, 183, 240 },
+    { 109, 104, 141, 162, 119, 244, 185, 241 },
+    { 111, 104, 141, 164, 119, 244, 186, 241 },
+    { 113, 104, 142, 166, 120, 245, 187, 242 },
+    { 114, 104, 142, 168, 121, 245, 188, 242 },
+    { 116, 105, 143, 170, 122, 246, 190, 243 },
+    { 118, 105, 143, 171, 122, 246, 191, 243 },
+    { 120, 106, 143, 173, 123, 247, 192, 244 },
+    { 121, 106, 143, 175, 124, 247, 193, 244 },
+    { 123, 107, 144, 177, 125, 248, 195, 244 },
+    { 125, 107, 144, 178, 125, 248, 196, 244 },
+    { 127, 108, 145, 180, 126, 249, 197, 245 },
+    { 128, 108, 145, 181, 127, 249, 198, 245 },
+    { 130, 109, 145, 183, 128, 249, 199, 245 },
+    { 132, 109, 145, 184, 128, 249, 200, 245 },
+    { 134, 110, 146, 186, 129, 250, 201, 246 },
+    { 135, 110, 146, 187, 130, 250, 202, 246 },
+    { 137, 111, 147, 189, 131, 251, 203, 246 },
+    { 138, 111, 147, 190, 131, 251, 204, 246 },
+    { 140, 112, 147, 192, 132, 251, 205, 247 },
+    { 141, 112, 147, 193, 132, 251, 206, 247 },
+    { 143, 113, 148, 194, 133, 251, 207, 247 },
+    { 144, 113, 148, 195, 134, 251, 207, 247 },
+    { 146, 114, 149, 197, 135, 252, 208, 248 },
+    { 147, 114, 149, 198, 135, 252, 209, 248 },
+    { 149, 115, 149, 199, 136, 252, 210, 248 },
+    { 150, 115, 149, 200, 137, 252, 210, 248 },
+    { 152, 115, 150, 201, 138, 252, 211, 248 },
+    { 153, 115, 150, 202, 138, 252, 212, 248 },
+    { 155, 116, 151, 204, 139, 253, 213, 249 },
+    { 156, 116, 151, 205, 139, 253, 213, 249 },
+    { 158, 117, 151, 206, 140, 253, 214, 249 },
+    { 159, 117, 151, 207, 141, 253, 215, 249 },
+    { 161, 118, 152, 208, 142, 253, 216, 249 },
+    { 162, 118, 152, 209, 142, 253, 216, 249 },
+    { 163, 119, 153, 210, 143, 253, 217, 249 },
+    { 164, 119, 153, 211, 143, 253, 217, 249 },
+    { 166, 120, 153, 212, 144, 254, 218, 250 },
+    { 167, 120, 153, 212, 145, 254, 219, 250 },
+    { 168, 121, 154, 213, 146, 254, 220, 250 },
+    { 169, 121, 154, 214, 146, 254, 220, 250 },
+    { 171, 122, 155, 215, 147, 254, 221, 250 },
+    { 172, 122, 155, 216, 147, 254, 221, 250 },
+    { 173, 123, 155, 217, 148, 254, 222, 250 },
+    { 174, 123, 155, 217, 149, 254, 222, 250 },
+    { 176, 124, 156, 218, 150, 254, 223, 250 },
+    { 177, 124, 156, 219, 150, 254, 223, 250 },
+    { 178, 125, 157, 220, 151, 254, 224, 251 },
+    { 179, 125, 157, 220, 151, 254, 224, 251 },
+    { 180, 126, 157, 221, 152, 254, 225, 251 },
+    { 181, 126, 157, 221, 152, 254, 225, 251 },
+    { 183, 127, 158, 222, 153, 254, 226, 251 },
+    { 184, 127, 158, 223, 154, 254, 226, 251 },
+    { 185, 128, 159, 224, 155, 255, 227, 251 },
+    { 186, 128, 159, 224, 155, 255, 227, 251 },
+    { 187, 129, 160, 225, 156, 255, 228, 251 },
+    { 188, 130, 160, 225, 156, 255, 228, 251 },
+    { 189, 131, 160, 226, 157, 255, 228, 251 },
+    { 190, 131, 160, 226, 158, 255, 228, 251 },
+    { 191, 132, 161, 227, 159, 255, 229, 251 },
+    { 192, 132, 161, 227, 159, 255, 229, 251 },
+    { 193, 133, 162, 228, 160, 255, 230, 252 },
+    { 194, 133, 162, 229, 160, 255, 230, 252 },
+    { 195, 134, 163, 230, 161, 255, 231, 252 },
+    { 196, 134, 163, 230, 161, 255, 231, 252 },
+    { 197, 135, 163, 231, 162, 255, 231, 252 },
+    { 198, 135, 163, 231, 162, 255, 231, 252 },
+    { 199, 136, 164, 232, 163, 255, 232, 252 },
+    { 200, 136, 164, 232, 164, 255, 232, 252 },
+    { 201, 137, 165, 233, 165, 255, 233, 252 },
+    { 201, 137, 165, 233, 165, 255, 233, 252 },
+    { 202, 138, 166, 233, 166, 255, 233, 252 },
+    { 203, 138, 166, 233, 166, 255, 233, 252 },
+    { 204, 139, 166, 234, 167, 255, 234, 252 },
+    { 205, 139, 166, 234, 167, 255, 234, 252 },
+    { 206, 140, 167, 235, 168, 255, 235, 252 },
+    { 206, 140, 167, 235, 168, 255, 235, 252 },
+    { 207, 141, 168, 236, 169, 255, 235, 252 },
+    { 208, 141, 168, 236, 170, 255, 235, 252 },
+    { 209, 142, 169, 237, 171, 255, 236, 252 },
+    { 209, 143, 169, 237, 171, 255, 236, 252 },
+    { 210, 144, 169, 237, 172, 255, 236, 252 },
+    { 211, 144, 169, 237, 172, 255, 236, 252 },
+    { 212, 145, 170, 238, 173, 255, 237, 252 },
+    { 213, 145, 170, 238, 173, 255, 237, 252 },
+    { 214, 146, 171, 239, 174, 255, 237, 253 },
+    { 214, 146, 171, 239, 174, 255, 237, 253 },
+    { 215, 147, 172, 240, 175, 255, 238, 253 },
+    { 215, 147, 172, 240, 175, 255, 238, 253 },
+    { 216, 148, 173, 240, 176, 255, 238, 253 },
+    { 217, 148, 173, 240, 176, 255, 238, 253 },
+    { 218, 149, 173, 241, 177, 255, 239, 253 },
+    { 218, 149, 173, 241, 178, 255, 239, 253 },
+    { 219, 150, 174, 241, 179, 255, 239, 253 },
+    { 219, 151, 174, 241, 179, 255, 239, 253 },
+    { 220, 152, 175, 242, 180, 255, 240, 253 },
+    { 221, 152, 175, 242, 180, 255, 240, 253 },
+    { 222, 153, 176, 242, 181, 255, 240, 253 },
+    { 222, 153, 176, 242, 181, 255, 240, 253 },
+    { 223, 154, 177, 243, 182, 255, 240, 253 },
+    { 223, 154, 177, 243, 182, 255, 240, 253 },
+    { 224, 155, 178, 244, 183, 255, 241, 253 },
+    { 224, 155, 178, 244, 183, 255, 241, 253 },
+    { 225, 156, 178, 244, 184, 255, 241, 253 },
+    { 225, 157, 178, 244, 184, 255, 241, 253 },
+    { 226, 158, 179, 244, 185, 255, 242, 253 },
+    { 227, 158, 179, 244, 185, 255, 242, 253 },
+    { 228, 159, 180, 245, 186, 255, 242, 253 },
+    { 228, 159, 180, 245, 186, 255, 242, 253 },
+    { 229, 160, 181, 245, 187, 255, 242, 253 },
+    { 229, 160, 181, 245, 187, 255, 242, 253 },
+    { 230, 161, 182, 246, 188, 255, 243, 253 },
+    { 230, 162, 182, 246, 188, 255, 243, 253 },
+    { 231, 163, 183, 246, 189, 255, 243, 253 },
+    { 231, 163, 183, 246, 189, 255, 243, 253 },
+    { 232, 164, 184, 247, 190, 255, 243, 253 },
+    { 232, 164, 184, 247, 190, 255, 243, 253 },
+    { 233, 165, 185, 247, 191, 255, 244, 253 },
+    { 233, 165, 185, 247, 191, 255, 244, 253 },
+    { 234, 166, 185, 247, 192, 255, 244, 253 },
+    { 234, 167, 185, 247, 192, 255, 244, 253 },
+    { 235, 168, 186, 248, 193, 255, 244, 253 },
+    { 235, 168, 186, 248, 193, 255, 244, 253 },
+    { 236, 169, 187, 248, 194, 255, 244, 253 },
+    { 236, 169, 187, 248, 194, 255, 244, 253 },
+    { 236, 170, 188, 248, 195, 255, 245, 253 },
+    { 236, 170, 188, 248, 195, 255, 245, 253 },
+    { 237, 171, 189, 249, 196, 255, 245, 254 },
+    { 237, 172, 189, 249, 196, 255, 245, 254 },
+    { 238, 173, 190, 249, 197, 255, 245, 254 },
+    { 238, 173, 190, 249, 197, 255, 245, 254 },
+    { 239, 174, 191, 249, 198, 255, 245, 254 },
+    { 239, 174, 191, 249, 198, 255, 245, 254 },
+    { 240, 175, 192, 249, 199, 255, 246, 254 },
+    { 240, 176, 192, 249, 199, 255, 246, 254 },
+    { 240, 177, 193, 250, 200, 255, 246, 254 },
+    { 240, 177, 193, 250, 200, 255, 246, 254 },
+    { 241, 178, 194, 250, 201, 255, 246, 254 },
+    { 241, 178, 194, 250, 201, 255, 246, 254 },
+    { 242, 179, 195, 250, 202, 255, 246, 254 },
+    { 242, 180, 195, 250, 202, 255, 246, 254 },
+    { 242, 181, 196, 250, 203, 255, 247, 254 },
+    { 242, 181, 196, 250, 203, 255, 247, 254 },
+    { 243, 182, 197, 251, 204, 255, 247, 254 },
+    { 243, 183, 197, 251, 204, 255, 247, 254 },
+    { 244, 184, 198, 251, 205, 255, 247, 254 },
+    { 244, 184, 198, 251, 205, 255, 247, 254 },
+    { 244, 185, 199, 251, 206, 255, 247, 254 },
+    { 244, 185, 199, 251, 206, 255, 247, 254 },
+    { 245, 186, 200, 251, 207, 255, 247, 254 },
+    { 245, 187, 200, 251, 207, 255, 247, 254 },
+    { 246, 188, 201, 252, 207, 255, 248, 254 },
+    { 246, 188, 201, 252, 207, 255, 248, 254 },
+    { 246, 189, 202, 252, 208, 255, 248, 254 },
+    { 246, 190, 202, 252, 208, 255, 248, 254 },
+    { 247, 191, 203, 252, 209, 255, 248, 254 },
+    { 247, 191, 203, 252, 209, 255, 248, 254 },
+    { 247, 192, 204, 252, 210, 255, 248, 254 },
+    { 247, 193, 204, 252, 210, 255, 248, 254 },
+    { 248, 194, 205, 252, 211, 255, 248, 254 },
+    { 248, 194, 205, 252, 211, 255, 248, 254 },
+    { 248, 195, 206, 252, 212, 255, 249, 254 },
+    { 248, 196, 206, 252, 212, 255, 249, 254 },
+    { 249, 197, 207, 253, 213, 255, 249, 254 },
+    { 249, 197, 207, 253, 213, 255, 249, 254 },
+    { 249, 198, 208, 253, 214, 255, 249, 254 },
+    { 249, 199, 209, 253, 214, 255, 249, 254 },
+    { 250, 200, 210, 253, 215, 255, 249, 254 },
+    { 250, 200, 210, 253, 215, 255, 249, 254 },
+    { 250, 201, 211, 253, 215, 255, 249, 254 },
+    { 250, 202, 211, 253, 215, 255, 249, 254 },
+    { 250, 203, 212, 253, 216, 255, 249, 254 },
+    { 250, 203, 212, 253, 216, 255, 249, 254 },
+    { 251, 204, 213, 253, 217, 255, 250, 254 },
+    { 251, 205, 213, 253, 217, 255, 250, 254 },
+    { 251, 206, 214, 254, 218, 255, 250, 254 },
+    { 251, 206, 215, 254, 218, 255, 250, 254 },
+    { 252, 207, 216, 254, 219, 255, 250, 254 },
+    { 252, 208, 216, 254, 219, 255, 250, 254 },
+    { 252, 209, 217, 254, 220, 255, 250, 254 },
+    { 252, 210, 217, 254, 220, 255, 250, 254 },
+    { 252, 211, 218, 254, 221, 255, 250, 254 },
+    { 252, 212, 218, 254, 221, 255, 250, 254 },
+    { 253, 213, 219, 254, 222, 255, 250, 254 },
+    { 253, 213, 220, 254, 222, 255, 250, 254 },
+    { 253, 214, 221, 254, 223, 255, 250, 254 },
+    { 253, 215, 221, 254, 223, 255, 250, 254 },
+    { 253, 216, 222, 254, 224, 255, 251, 254 },
+    { 253, 217, 223, 254, 224, 255, 251, 254 },
+    { 253, 218, 224, 254, 225, 255, 251, 254 },
+    { 253, 219, 224, 254, 225, 255, 251, 254 },
+    { 254, 220, 225, 254, 225, 255, 251, 254 },
+    { 254, 221, 226, 254, 225, 255, 251, 254 },
+    { 254, 222, 227, 255, 226, 255, 251, 254 },
+    { 254, 223, 227, 255, 226, 255, 251, 254 },
+    { 254, 224, 228, 255, 227, 255, 251, 254 },
+    { 254, 225, 229, 255, 227, 255, 251, 254 },
+    { 254, 226, 230, 255, 228, 255, 251, 254 },
+    { 254, 227, 230, 255, 229, 255, 251, 254 },
+    { 255, 228, 231, 255, 230, 255, 251, 254 },
+    { 255, 229, 232, 255, 230, 255, 251, 254 },
+    { 255, 230, 233, 255, 231, 255, 252, 254 },
+    { 255, 231, 234, 255, 231, 255, 252, 254 },
+    { 255, 232, 235, 255, 232, 255, 252, 254 },
+    { 255, 233, 236, 255, 232, 255, 252, 254 },
+    { 255, 235, 237, 255, 233, 255, 252, 254 },
+    { 255, 236, 238, 255, 234, 255, 252, 254 },
+    { 255, 238, 240, 255, 235, 255, 252, 255 },
+    { 255, 239, 241, 255, 235, 255, 252, 254 },
+    { 255, 241, 243, 255, 236, 255, 252, 254 },
+    { 255, 243, 245, 255, 237, 255, 252, 254 },
+    { 255, 246, 247, 255, 239, 255, 253, 255 },
+};
+
+const ProbContext ff_vp9_default_probs = {
+    { /* y_mode */
+        {  65,  32,  18, 144, 162, 194,  41,  51,  98 } /* bsize < 8x8 */,
+        { 132,  68,  18, 165, 217, 196,  45,  40,  78 } /* bsize < 16x16 */,
+        { 173,  80,  19, 176, 240, 193,  64,  35,  46 } /* bsize < 32x32 */,
+        { 221, 135,  38, 194, 248, 121,  96,  85,  29 } /* bsize >= 32x32 */
+    }, { /* uv_mode */
+        {  48,  12, 154, 155, 139,  90,  34, 117, 119 } /* y = v */,
+        {  67,   6,  25, 204, 243, 158,  13,  21,  96 } /* y = h */,
+        { 120,   7,  76, 176, 208, 126,  28,  54, 103 } /* y = dc */,
+        {  97,   5,  44, 131, 176, 139,  48,  68,  97 } /* y = d45 */,
+        {  83,   5,  42, 156, 111, 152,  26,  49, 152 } /* y = d135 */,
+        {  80,   5,  58, 178,  74,  83,  33,  62, 145 } /* y = d117 */,
+        {  86,   5,  32, 154, 192, 168,  14,  22, 163 } /* y = d153 */,
+        {  77,   7,  64, 116, 132, 122,  37, 126, 120 } /* y = d63 */,
+        {  85,   5,  32, 156, 216, 148,  19,  29,  73 } /* y = d27 */,
+        { 101,  21, 107, 181, 192, 103,  19,  67, 125 } /* y = tm */
+    }, { /* filter */
+        { 235, 162, },
+        {  36, 255, },
+        {  34,   3, },
+        { 149, 144, },
+    }, { /* mv_mode */
+        {  2, 173,  34 },  // 0 = both zero mv
+        {  7, 145,  85 },  // 1 = one zero mv + one a predicted mv
+        {  7, 166,  63 },  // 2 = two predicted mvs
+        {  7,  94,  66 },  // 3 = one predicted/zero and one new mv
+        {  8,  64,  46 },  // 4 = two new mvs
+        { 17,  81,  31 },  // 5 = one intra neighbor + x
+        { 25,  29,  30 },  // 6 = two intra neighbors
+    }, { /* intra */
+        9, 102, 187, 225
+    }, { /* comp */
+        239, 183, 119,  96,  41
+    }, { /* single_ref */
+        {  33,  16 },
+        {  77,  74 },
+        { 142, 142 },
+        { 172, 170 },
+        { 238, 247 }
+    }, { /* comp_ref */
+        50, 126, 123, 221, 226
+    }, { /* tx32p */
+        { 3, 136, 37, },
+        { 5,  52, 13, },
+    }, { /* tx16p */
+        { 20, 152, },
+        { 15, 101, },
+    }, { /* tx8p */
+        100, 66
+    }, { /* skip */
+        192, 128, 64
+    }, { /* mv_joint */
+        32, 64, 96
+    }, {
+        { /* mv vertical component */
+            128, /* sign */
+            { 224, 144, 192, 168, 192, 176, 192, 198, 198, 245 }, /* class */
+            216, /* class0 */
+            { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */
+            { /* class0_fp */
+                { 128, 128, 64 },
+                {  96, 112, 64 }
+            },
+            { 64, 96, 64 }, /* fp */
+            160, /* class0_hp bit */
+            128, /* hp */
+        }, { /* mv horizontal component */
+            128, /* sign */
+            { 216, 128, 176, 160, 176, 176, 192, 198, 198, 208 }, /* class */
+            208, /* class0 */
+            { 136, 140, 148, 160, 176, 192, 224, 234, 234, 240 }, /* bits */
+            { /* class0_fp */
+                { 128, 128, 64 },
+                {  96, 112, 64 }
+            },
+            { 64, 96, 64 }, /* fp */
+            160, /* class0_hp bit */
+            128, /* hp */
+        }
+    }, { /* partition */
+        { /* 64x64 -> 32x32 */
+            { 222,  34,  30 } /* a/l both not split */,
+            {  72,  16,  44 } /* a split, l not split */,
+            {  58,  32,  12 } /* l split, a not split */,
+            {  10,   7,   6 } /* a/l both split */,
+        }, { /* 32x32 -> 16x16 */
+            { 177,  58,  59 } /* a/l both not split */,
+            {  68,  26,  63 } /* a split, l not split */,
+            {  52,  79,  25 } /* l split, a not split */,
+            {  17,  14,  12 } /* a/l both split */,
+        }, { /* 16x16 -> 8x8 */
+            { 174,  73,  87 } /* a/l both not split */,
+            {  92,  41,  83 } /* a split, l not split */,
+            {  82,  99,  50 } /* l split, a not split */,
+            {  53,  39,  39 } /* a/l both split */,
+        }, { /* 8x8 -> 4x4 */
+            { 199, 122, 141 } /* a/l both not split */,
+            { 147,  63, 159 } /* a split, l not split */,
+            { 148, 133, 118 } /* l split, a not split */,
+            { 121, 104, 114 } /* a/l both split */,
+        }
+    },
+};
+
+const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3] = {
+    { /* tx = 4x4 */
+        { /* block Type 0 */
+            { /* Intra */
+                { /* Coeff Band 0 */
+                    { 195,  29, 183 },
+                    {  84,  49, 136 },
+                    {   8,  42,  71 }
+                }, { /* Coeff Band 1 */
+                    {  31, 107, 169 },
+                    {  35,  99, 159 },
+                    {  17,  82, 140 },
+                    {   8,  66, 114 },
+                    {   2,  44,  76 },
+                    {   1,  19,  32 }
+                }, { /* Coeff Band 2 */
+                    {  40, 132, 201 },
+                    {  29, 114, 187 },
+                    {  13,  91, 157 },
+                    {   7,  75, 127 },
+                    {   3,  58,  95 },
+                    {   1,  28,  47 }
+                }, { /* Coeff Band 3 */
+                    {  69, 142, 221 },
+                    {  42, 122, 201 },
+                    {  15,  91, 159 },
+                    {   6,  67, 121 },
+                    {   1,  42,  77 },
+                    {   1,  17,  31 }
+                }, { /* Coeff Band 4 */
+                    { 102, 148, 228 },
+                    {  67, 117, 204 },
+                    {  17,  82, 154 },
+                    {   6,  59, 114 },
+                    {   2,  39,  75 },
+                    {   1,  15,  29 }
+                }, { /* Coeff Band 5 */
+                    { 156,  57, 233 },
+                    { 119,  57, 212 },
+                    {  58,  48, 163 },
+                    {  29,  40, 124 },
+                    {  12,  30,  81 },
+                    {   3,  12,  31 }
+                }
+            }, { /* Inter */
+                { /* Coeff Band 0 */
+                    { 191, 107, 226 },
+                    { 124, 117, 204 },
+                    {  25,  99, 155 }
+                }, { /* Coeff Band 1 */
+                    {  29, 148, 210 },
+                    {  37, 126, 194 },
+                    {   8,  93, 157 },
+                    {   2,  68, 118 },
+                    {   1,  39,  69 },
+                    {   1,  17,  33 }
+                }, { /* Coeff Band 2 */
+                    {  41, 151, 213 },
+                    {  27, 123, 193 },
+                    {   3,  82, 144 },
+                    {   1,  58, 105 },
+                    {   1,  32,  60 },
+                    {   1,  13,  26 }
+                }, { /* Coeff Band 3 */
+                    {  59, 159, 220 },
+                    {  23, 126, 198 },
+                    {   4,  88, 151 },
+                    {   1,  66, 114 },
+                    {   1,  38,  71 },
+                    {   1,  18,  34 }
+                }, { /* Coeff Band 4 */
+                    { 114, 136, 232 },
+                    {  51, 114, 207 },
+                    {  11,  83, 155 },
+                    {   3,  56, 105 },
+                    {   1,  33,  65 },
+                    {   1,  17,  34 }
+                }, { /* Coeff Band 5 */
+                    { 149,  65, 234 },
+                    { 121,  57, 215 },
+                    {  61,  49, 166 },
+                    {  28,  36, 114 },
+                    {  12,  25,  76 },
+                    {   3,  16,  42 }
+                }
+            }
+        }, { /* block Type 1 */
+            { /* Intra */
+                { /* Coeff Band 0 */
+                    { 214,  49, 220 },
+                    { 132,  63, 188 },
+                    {  42,  65, 137 }
+                }, { /* Coeff Band 1 */
+                    {  85, 137, 221 },
+                    { 104, 131, 216 },
+                    {  49, 111, 192 },
+                    {  21,  87, 155 },
+                    {   2,  49,  87 },
+                    {   1,  16,  28 }
+                }, { /* Coeff Band 2 */
+                    {  89, 163, 230 },
+                    {  90, 137, 220 },
+                    {  29, 100, 183 },
+                    {  10,  70, 135 },
+                    {   2,  42,  81 },
+                    {   1,  17,  33 }
+                }, { /* Coeff Band 3 */
+                    { 108, 167, 237 },
+                    {  55, 133, 222 },
+                    {  15,  97, 179 },
+                    {   4,  72, 135 },
+                    {   1,  45,  85 },
+                    {   1,  19,  38 }
+                }, { /* Coeff Band 4 */
+                    { 124, 146, 240 },
+                    {  66, 124, 224 },
+                    {  17,  88, 175 },
+                    {   4,  58, 122 },
+                    {   1,  36,  75 },
+                    {   1,  18,  37 }
+                }, { /* Coeff Band 5 */
+                    { 141,  79, 241 },
+                    { 126,  70, 227 },
+                    {  66,  58, 182 },
+                    {  30,  44, 136 },
+                    {  12,  34,  96 },
+                    {   2,  20,  47 }
+                }
+            }, { /* Inter */
+                { /* Coeff Band 0 */
+                    { 229,  99, 249 },
+                    { 143, 111, 235 },
+                    {  46, 109, 192 }
+                }, { /* Coeff Band 1 */
+                    {  82, 158, 236 },
+                    {  94, 146, 224 },
+                    {  25, 117, 191 },
+                    {   9,  87, 149 },
+                    {   3,  56,  99 },
+                    {   1,  33,  57 }
+                }, { /* Coeff Band 2 */
+                    {  83, 167, 237 },
+                    {  68, 145, 222 },
+                    {  10, 103, 177 },
+                    {   2,  72, 131 },
+                    {   1,  41,  79 },
+                    {   1,  20,  39 }
+                }, { /* Coeff Band 3 */
+                    {  99, 167, 239 },
+                    {  47, 141, 224 },
+                    {  10, 104, 178 },
+                    {   2,  73, 133 },
+                    {   1,  44,  85 },
+                    {   1,  22,  47 }
+                }, { /* Coeff Band 4 */
+                    { 127, 145, 243 },
+                    {  71, 129, 228 },
+                    {  17,  93, 177 },
+                    {   3,  61, 124 },
+                    {   1,  41,  84 },
+                    {   1,  21,  52 }
+                }, { /* Coeff Band 5 */
+                    { 157,  78, 244 },
+                    { 140,  72, 231 },
+                    {  69,  58, 184 },
+                    {  31,  44, 137 },
+                    {  14,  38, 105 },
+                    {   8,  23,  61 }
+                }
+            }
+        }
+    }, { /* tx = 8x8 */
+        { /* block Type 0 */
+            { /* Intra */
+                { /* Coeff Band 0 */
+                    { 125,  34, 187 },
+                    {  52,  41, 133 },
+                    {   6,  31,  56 }
+                }, { /* Coeff Band 1 */
+                    {  37, 109, 153 },
+                    {  51, 102, 147 },
+                    {  23,  87, 128 },
+                    {   8,  67, 101 },
+                    {   1,  41,  63 },
+                    {   1,  19,  29 }
+                }, { /* Coeff Band 2 */
+                    {  31, 154, 185 },
+                    {  17, 127, 175 },
+                    {   6,  96, 145 },
+                    {   2,  73, 114 },
+                    {   1,  51,  82 },
+                    {   1,  28,  45 }
+                }, { /* Coeff Band 3 */
+                    {  23, 163, 200 },
+                    {  10, 131, 185 },
+                    {   2,  93, 148 },
+                    {   1,  67, 111 },
+                    {   1,  41,  69 },
+                    {   1,  14,  24 }
+                }, { /* Coeff Band 4 */
+                    {  29, 176, 217 },
+                    {  12, 145, 201 },
+                    {   3, 101, 156 },
+                    {   1,  69, 111 },
+                    {   1,  39,  63 },
+                    {   1,  14,  23 }
+                }, { /* Coeff Band 5 */
+                    {  57, 192, 233 },
+                    {  25, 154, 215 },
+                    {   6, 109, 167 },
+                    {   3,  78, 118 },
+                    {   1,  48,  69 },
+                    {   1,  21,  29 }
+                }
+            }, { /* Inter */
+                { /* Coeff Band 0 */
+                    { 202, 105, 245 },
+                    { 108, 106, 216 },
+                    {  18,  90, 144 }
+                }, { /* Coeff Band 1 */
+                    {  33, 172, 219 },
+                    {  64, 149, 206 },
+                    {  14, 117, 177 },
+                    {   5,  90, 141 },
+                    {   2,  61,  95 },
+                    {   1,  37,  57 }
+                }, { /* Coeff Band 2 */
+                    {  33, 179, 220 },
+                    {  11, 140, 198 },
+                    {   1,  89, 148 },
+                    {   1,  60, 104 },
+                    {   1,  33,  57 },
+                    {   1,  12,  21 }
+                }, { /* Coeff Band 3 */
+                    {  30, 181, 221 },
+                    {   8, 141, 198 },
+                    {   1,  87, 145 },
+                    {   1,  58, 100 },
+                    {   1,  31,  55 },
+                    {   1,  12,  20 }
+                }, { /* Coeff Band 4 */
+                    {  32, 186, 224 },
+                    {   7, 142, 198 },
+                    {   1,  86, 143 },
+                    {   1,  58, 100 },
+                    {   1,  31,  55 },
+                    {   1,  12,  22 }
+                }, { /* Coeff Band 5 */
+                    {  57, 192, 227 },
+                    {  20, 143, 204 },
+                    {   3,  96, 154 },
+                    {   1,  68, 112 },
+                    {   1,  42,  69 },
+                    {   1,  19,  32 }
+                }
+            }
+        }, { /* block Type 1 */
+            { /* Intra */
+                { /* Coeff Band 0 */
+                    { 212,  35, 215 },
+                    { 113,  47, 169 },
+                    {  29,  48, 105 }
+                }, { /* Coeff Band 1 */
+                    {  74, 129, 203 },
+                    { 106, 120, 203 },
+                    {  49, 107, 178 },
+                    {  19,  84, 144 },
+                    {   4,  50,  84 },
+                    {   1,  15,  25 }
+                }, { /* Coeff Band 2 */
+                    {  71, 172, 217 },
+                    {  44, 141, 209 },
+                    {  15, 102, 173 },
+                    {   6,  76, 133 },
+                    {   2,  51,  89 },
+                    {   1,  24,  42 }
+                }, { /* Coeff Band 3 */
+                    {  64, 185, 231 },
+                    {  31, 148, 216 },
+                    {   8, 103, 175 },
+                    {   3,  74, 131 },
+                    {   1,  46,  81 },
+                    {   1,  18,  30 }
+                }, { /* Coeff Band 4 */
+                    {  65, 196, 235 },
+                    {  25, 157, 221 },
+                    {   5, 105, 174 },
+                    {   1,  67, 120 },
+                    {   1,  38,  69 },
+                    {   1,  15,  30 }
+                }, { /* Coeff Band 5 */
+                    {  65, 204, 238 },
+                    {  30, 156, 224 },
+                    {   7, 107, 177 },
+                    {   2,  70, 124 },
+                    {   1,  42,  73 },
+                    {   1,  18,  34 }
+                }
+            }, { /* Inter */
+                { /* Coeff Band 0 */
+                    { 225,  86, 251 },
+                    { 144, 104, 235 },
+                    {  42,  99, 181 }
+                }, { /* Coeff Band 1 */
+                    {  85, 175, 239 },
+                    { 112, 165, 229 },
+                    {  29, 136, 200 },
+                    {  12, 103, 162 },
+                    {   6,  77, 123 },
+                    {   2,  53,  84 }
+                }, { /* Coeff Band 2 */
+                    {  75, 183, 239 },
+                    {  30, 155, 221 },
+                    {   3, 106, 171 },
+                    {   1,  74, 128 },
+                    {   1,  44,  76 },
+                    {   1,  17,  28 }
+                }, { /* Coeff Band 3 */
+                    {  73, 185, 240 },
+                    {  27, 159, 222 },
+                    {   2, 107, 172 },
+                    {   1,  75, 127 },
+                    {   1,  42,  73 },
+                    {   1,  17,  29 }
+                }, { /* Coeff Band 4 */
+                    {  62, 190, 238 },
+                    {  21, 159, 222 },
+                    {   2, 107, 172 },
+                    {   1,  72, 122 },
+                    {   1,  40,  71 },
+                    {   1,  18,  32 }
+                }, { /* Coeff Band 5 */
+                    {  61, 199, 240 },
+                    {  27, 161, 226 },
+                    {   4, 113, 180 },
+                    {   1,  76, 129 },
+                    {   1,  46,  80 },
+                    {   1,  23,  41 }
+                }
+            }
+        }
+    }, { /* tx = 16x16 */
+        { /* block Type 0 */
+            { /* Intra */
+                { /* Coeff Band 0 */
+                    {   7,  27, 153 },
+                    {   5,  30,  95 },
+                    {   1,  16,  30 }
+                }, { /* Coeff Band 1 */
+                    {  50,  75, 127 },
+                    {  57,  75, 124 },
+                    {  27,  67, 108 },
+                    {  10,  54,  86 },
+                    {   1,  33,  52 },
+                    {   1,  12,  18 }
+                }, { /* Coeff Band 2 */
+                    {  43, 125, 151 },
+                    {  26, 108, 148 },
+                    {   7,  83, 122 },
+                    {   2,  59,  89 },
+                    {   1,  38,  60 },
+                    {   1,  17,  27 }
+                }, { /* Coeff Band 3 */
+                    {  23, 144, 163 },
+                    {  13, 112, 154 },
+                    {   2,  75, 117 },
+                    {   1,  50,  81 },
+                    {   1,  31,  51 },
+                    {   1,  14,  23 }
+                }, { /* Coeff Band 4 */
+                    {  18, 162, 185 },
+                    {   6, 123, 171 },
+                    {   1,  78, 125 },
+                    {   1,  51,  86 },
+                    {   1,  31,  54 },
+                    {   1,  14,  23 }
+                }, { /* Coeff Band 5 */
+                    {  15, 199, 227 },
+                    {   3, 150, 204 },
+                    {   1,  91, 146 },
+                    {   1,  55,  95 },
+                    {   1,  30,  53 },
+                    {   1,  11,  20 }
+                }
+            }, { /* Inter */
+                { /* Coeff Band 0 */
+                    {  19,  55, 240 },
+                    {  19,  59, 196 },
+                    {   3,  52, 105 }
+                }, { /* Coeff Band 1 */
+                    {  41, 166, 207 },
+                    { 104, 153, 199 },
+                    {  31, 123, 181 },
+                    {  14, 101, 152 },
+                    {   5,  72, 106 },
+                    {   1,  36,  52 }
+                }, { /* Coeff Band 2 */
+                    {  35, 176, 211 },
+                    {  12, 131, 190 },
+                    {   2,  88, 144 },
+                    {   1,  60, 101 },
+                    {   1,  36,  60 },
+                    {   1,  16,  28 }
+                }, { /* Coeff Band 3 */
+                    {  28, 183, 213 },
+                    {   8, 134, 191 },
+                    {   1,  86, 142 },
+                    {   1,  56,  96 },
+                    {   1,  30,  53 },
+                    {   1,  12,  20 }
+                }, { /* Coeff Band 4 */
+                    {  20, 190, 215 },
+                    {   4, 135, 192 },
+                    {   1,  84, 139 },
+                    {   1,  53,  91 },
+                    {   1,  28,  49 },
+                    {   1,  11,  20 }
+                }, { /* Coeff Band 5 */
+                    {  13, 196, 216 },
+                    {   2, 137, 192 },
+                    {   1,  86, 143 },
+                    {   1,  57,  99 },
+                    {   1,  32,  56 },
+                    {   1,  13,  24 }
+                }
+            }
+        }, { /* block Type 1 */
+            { /* Intra */
+                { /* Coeff Band 0 */
+                    { 211,  29, 217 },
+                    {  96,  47, 156 },
+                    {  22,  43,  87 }
+                }, { /* Coeff Band 1 */
+                    {  78, 120, 193 },
+                    { 111, 116, 186 },
+                    {  46, 102, 164 },
+                    {  15,  80, 128 },
+                    {   2,  49,  76 },
+                    {   1,  18,  28 }
+                }, { /* Coeff Band 2 */
+                    {  71, 161, 203 },
+                    {  42, 132, 192 },
+                    {  10,  98, 150 },
+                    {   3,  69, 109 },
+                    {   1,  44,  70 },
+                    {   1,  18,  29 }
+                }, { /* Coeff Band 3 */
+                    {  57, 186, 211 },
+                    {  30, 140, 196 },
+                    {   4,  93, 146 },
+                    {   1,  62, 102 },
+                    {   1,  38,  65 },
+                    {   1,  16,  27 }
+                }, { /* Coeff Band 4 */
+                    {  47, 199, 217 },
+                    {  14, 145, 196 },
+                    {   1,  88, 142 },
+                    {   1,  57,  98 },
+                    {   1,  36,  62 },
+                    {   1,  15,  26 }
+                }, { /* Coeff Band 5 */
+                    {  26, 219, 229 },
+                    {   5, 155, 207 },
+                    {   1,  94, 151 },
+                    {   1,  60, 104 },
+                    {   1,  36,  62 },
+                    {   1,  16,  28 }
+                }
+            }, { /* Inter */
+                { /* Coeff Band 0 */
+                    { 233,  29, 248 },
+                    { 146,  47, 220 },
+                    {  43,  52, 140 }
+                }, { /* Coeff Band 1 */
+                    { 100, 163, 232 },
+                    { 179, 161, 222 },
+                    {  63, 142, 204 },
+                    {  37, 113, 174 },
+                    {  26,  89, 137 },
+                    {  18,  68,  97 }
+                }, { /* Coeff Band 2 */
+                    {  85, 181, 230 },
+                    {  32, 146, 209 },
+                    {   7, 100, 164 },
+                    {   3,  71, 121 },
+                    {   1,  45,  77 },
+                    {   1,  18,  30 }
+                }, { /* Coeff Band 3 */
+                    {  65, 187, 230 },
+                    {  20, 148, 207 },
+                    {   2,  97, 159 },
+                    {   1,  68, 116 },
+                    {   1,  40,  70 },
+                    {   1,  14,  29 }
+                }, { /* Coeff Band 4 */
+                    {  40, 194, 227 },
+                    {   8, 147, 204 },
+                    {   1,  94, 155 },
+                    {   1,  65, 112 },
+                    {   1,  39,  66 },
+                    {   1,  14,  26 }
+                }, { /* Coeff Band 5 */
+                    {  16, 208, 228 },
+                    {   3, 151, 207 },
+                    {   1,  98, 160 },
+                    {   1,  67, 117 },
+                    {   1,  41,  74 },
+                    {   1,  17,  31 }
+                }
+            }
+        }
+    }, { /* tx = 32x32 */
+        { /* block Type 0 */
+            { /* Intra */
+                { /* Coeff Band 0 */
+                    {  17,  38, 140 },
+                    {   7,  34,  80 },
+                    {   1,  17,  29 }
+                }, { /* Coeff Band 1 */
+                    {  37,  75, 128 },
+                    {  41,  76, 128 },
+                    {  26,  66, 116 },
+                    {  12,  52,  94 },
+                    {   2,  32,  55 },
+                    {   1,  10,  16 }
+                }, { /* Coeff Band 2 */
+                    {  50, 127, 154 },
+                    {  37, 109, 152 },
+                    {  16,  82, 121 },
+                    {   5,  59,  85 },
+                    {   1,  35,  54 },
+                    {   1,  13,  20 }
+                }, { /* Coeff Band 3 */
+                    {  40, 142, 167 },
+                    {  17, 110, 157 },
+                    {   2,  71, 112 },
+                    {   1,  44,  72 },
+                    {   1,  27,  45 },
+                    {   1,  11,  17 }
+                }, { /* Coeff Band 4 */
+                    {  30, 175, 188 },
+                    {   9, 124, 169 },
+                    {   1,  74, 116 },
+                    {   1,  48,  78 },
+                    {   1,  30,  49 },
+                    {   1,  11,  18 }
+                }, { /* Coeff Band 5 */
+                    {  10, 222, 223 },
+                    {   2, 150, 194 },
+                    {   1,  83, 128 },
+                    {   1,  48,  79 },
+                    {   1,  27,  45 },
+                    {   1,  11,  17 }
+                }
+            }, { /* Inter */
+                { /* Coeff Band 0 */
+                    {  36,  41, 235 },
+                    {  29,  36, 193 },
+                    {  10,  27, 111 }
+                }, { /* Coeff Band 1 */
+                    {  85, 165, 222 },
+                    { 177, 162, 215 },
+                    { 110, 135, 195 },
+                    {  57, 113, 168 },
+                    {  23,  83, 120 },
+                    {  10,  49,  61 }
+                }, { /* Coeff Band 2 */
+                    {  85, 190, 223 },
+                    {  36, 139, 200 },
+                    {   5,  90, 146 },
+                    {   1,  60, 103 },
+                    {   1,  38,  65 },
+                    {   1,  18,  30 }
+                }, { /* Coeff Band 3 */
+                    {  72, 202, 223 },
+                    {  23, 141, 199 },
+                    {   2,  86, 140 },
+                    {   1,  56,  97 },
+                    {   1,  36,  61 },
+                    {   1,  16,  27 }
+                }, { /* Coeff Band 4 */
+                    {  55, 218, 225 },
+                    {  13, 145, 200 },
+                    {   1,  86, 141 },
+                    {   1,  57,  99 },
+                    {   1,  35,  61 },
+                    {   1,  13,  22 }
+                }, { /* Coeff Band 5 */
+                    {  15, 235, 212 },
+                    {   1, 132, 184 },
+                    {   1,  84, 139 },
+                    {   1,  57,  97 },
+                    {   1,  34,  56 },
+                    {   1,  14,  23 }
+                }
+            }
+        }, { /* block Type 1 */
+            { /* Intra */
+                { /* Coeff Band 0 */
+                    { 181,  21, 201 },
+                    {  61,  37, 123 },
+                    {  10,  38,  71 }
+                }, { /* Coeff Band 1 */
+                    {  47, 106, 172 },
+                    {  95, 104, 173 },
+                    {  42,  93, 159 },
+                    {  18,  77, 131 },
+                    {   4,  50,  81 },
+                    {   1,  17,  23 }
+                }, { /* Coeff Band 2 */
+                    {  62, 147, 199 },
+                    {  44, 130, 189 },
+                    {  28, 102, 154 },
+                    {  18,  75, 115 },
+                    {   2,  44,  65 },
+                    {   1,  12,  19 }
+                }, { /* Coeff Band 3 */
+                    {  55, 153, 210 },
+                    {  24, 130, 194 },
+                    {   3,  93, 146 },
+                    {   1,  61,  97 },
+                    {   1,  31,  50 },
+                    {   1,  10,  16 }
+                }, { /* Coeff Band 4 */
+                    {  49, 186, 223 },
+                    {  17, 148, 204 },
+                    {   1,  96, 142 },
+                    {   1,  53,  83 },
+                    {   1,  26,  44 },
+                    {   1,  11,  17 }
+                }, { /* Coeff Band 5 */
+                    {  13, 217, 212 },
+                    {   2, 136, 180 },
+                    {   1,  78, 124 },
+                    {   1,  50,  83 },
+                    {   1,  29,  49 },
+                    {   1,  14,  23 }
+                }
+            }, { /* Inter */
+                { /* Coeff Band 0 */
+                    { 197,  13, 247 },
+                    {  82,  17, 222 },
+                    {  25,  17, 162 }
+                }, { /* Coeff Band 1 */
+                    { 126, 186, 247 },
+                    { 234, 191, 243 },
+                    { 176, 177, 234 },
+                    { 104, 158, 220 },
+                    {  66, 128, 186 },
+                    {  55,  90, 137 }
+                }, { /* Coeff Band 2 */
+                    { 111, 197, 242 },
+                    {  46, 158, 219 },
+                    {   9, 104, 171 },
+                    {   2,  65, 125 },
+                    {   1,  44,  80 },
+                    {   1,  17,  91 }
+                }, { /* Coeff Band 3 */
+                    { 104, 208, 245 },
+                    {  39, 168, 224 },
+                    {   3, 109, 162 },
+                    {   1,  79, 124 },
+                    {   1,  50, 102 },
+                    {   1,  43, 102 }
+                }, { /* Coeff Band 4 */
+                    {  84, 220, 246 },
+                    {  31, 177, 231 },
+                    {   2, 115, 180 },
+                    {   1,  79, 134 },
+                    {   1,  55,  77 },
+                    {   1,  60,  79 }
+                }, { /* Coeff Band 5 */
+                    {  43, 243, 240 },
+                    {   8, 180, 217 },
+                    {   1, 115, 166 },
+                    {   1,  84, 121 },
+                    {   1,  51,  67 },
+                    {   1,  16,   6 }
+                }
+            }
+        }
+    }
+};
+
+const int8_t ff_vp9_mv_joint_tree[3][2] = {
+    { -MV_JOINT_ZERO,            1 }, // '0'
+    {    -MV_JOINT_H,            2 }, // '10'
+    {    -MV_JOINT_V, -MV_JOINT_HV }, // '11x'
+};
+
+const int8_t ff_vp9_mv_class_tree[10][2] = {
+    { -0,   1 }, // '0'
+    { -1,   2 }, // '10'
+    {  3,   4 },
+    { -2,  -3 }, // '110x'
+    {  5,   6 },
+    { -4,  -5 }, // '1110x'
+    { -6,   7 }, // '11110'
+    {  8,   9 },
+    { -7,  -8 }, // '111110x'
+    { -9, -10 }, // '111111x'
+};
+
+const int8_t ff_vp9_mv_fp_tree[3][2] = {
+    { -0,  1 },   // '0'
+    { -1,  2 },   // '10'
+    { -2, -3 },   // '11x'
+};
diff --git a/libavcodec/vp9data.h b/libavcodec/vp9data.h
new file mode 100644
index 0000000..a52cc0a
--- /dev/null
+++ b/libavcodec/vp9data.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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_VP9DATA_H
+#define AVCODEC_VP9DATA_H
+
+#include <stdint.h>
+
+#include "vp9.h"
+
+extern const int8_t ff_vp9_partition_tree[3][2];
+extern const uint8_t ff_vp9_default_kf_partition_probs[4][4][3];
+extern const int8_t ff_vp9_segmentation_tree[7][2];
+extern const int8_t ff_vp9_intramode_tree[9][2];
+extern const uint8_t ff_vp9_default_kf_ymode_probs[10][10][9];
+extern const uint8_t ff_vp9_default_kf_uvmode_probs[10][9];
+extern const int8_t ff_vp9_inter_mode_tree[3][2];
+extern const int8_t ff_vp9_filter_tree[2][2];
+extern const enum FilterMode ff_vp9_filter_lut[3];
+extern const int16_t ff_vp9_dc_qlookup[256];
+extern const int16_t ff_vp9_ac_qlookup[256];
+extern const enum TxfmType ff_vp9_intra_txfm_type[14];
+extern const int16_t ff_vp9_default_scan_4x4[16];
+extern const int16_t ff_vp9_col_scan_4x4[16];
+extern const int16_t ff_vp9_row_scan_4x4[16];
+extern const int16_t ff_vp9_default_scan_8x8[64];
+extern const int16_t ff_vp9_col_scan_8x8[64];
+extern const int16_t ff_vp9_row_scan_8x8[64];
+extern const int16_t ff_vp9_default_scan_16x16[256];
+extern const int16_t ff_vp9_col_scan_16x16[256];
+extern const int16_t ff_vp9_row_scan_16x16[256];
+extern const int16_t ff_vp9_default_scan_32x32[1024];
+extern const int16_t *ff_vp9_scans[5][4];
+extern const int16_t ff_vp9_default_scan_4x4_nb[16][2];
+extern const int16_t ff_vp9_col_scan_4x4_nb[16][2];
+extern const int16_t ff_vp9_row_scan_4x4_nb[16][2];
+extern const int16_t ff_vp9_default_scan_8x8_nb[64][2];
+extern const int16_t ff_vp9_col_scan_8x8_nb[64][2];
+extern const int16_t ff_vp9_row_scan_8x8_nb[64][2];
+extern const int16_t ff_vp9_default_scan_16x16_nb[256][2];
+extern const int16_t ff_vp9_col_scan_16x16_nb[256][2];
+extern const int16_t ff_vp9_row_scan_16x16_nb[256][2];
+extern const int16_t ff_vp9_default_scan_32x32_nb[1024][2];
+extern const int16_t (*ff_vp9_scans_nb[5][4])[2];
+extern const uint8_t ff_vp9_model_pareto8[256][8];
+extern const ProbContext ff_vp9_default_probs;
+extern const uint8_t ff_vp9_default_coef_probs[4][2][2][6][6][3];
+extern const int8_t ff_vp9_mv_joint_tree[3][2];
+extern const int8_t ff_vp9_mv_class_tree[10][2];
+extern const int8_t ff_vp9_mv_fp_tree[3][2];
+
+#endif /* AVCODEC_VP9DATA_H */
diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c
new file mode 100644
index 0000000..c83defe
--- /dev/null
+++ b/libavcodec/vp9dsp.c
@@ -0,0 +1,2174 @@
+/*
+ * VP9 compatible video decoder
+ *
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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/common.h"
+#include "libavutil/intreadwrite.h"
+
+#include "rnd_avg.h"
+#include "vp9.h"
+
+// FIXME see whether we can merge parts of this (perhaps at least 4x4 and 8x8)
+// back with h264pred.[ch]
+
+static void vert_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                       const uint8_t *left, const uint8_t *top)
+{
+    unsigned p4 = AV_RN32A(top);
+
+    AV_WN32A(dst + stride * 0, p4);
+    AV_WN32A(dst + stride * 1, p4);
+    AV_WN32A(dst + stride * 2, p4);
+    AV_WN32A(dst + stride * 3, p4);
+}
+
+static void vert_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                       const uint8_t *left, const uint8_t *top)
+{
+    uint64_t p8 = AV_RN64A(top);
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        AV_WN64A(dst, p8);
+        dst += stride;
+    }
+}
+
+static void vert_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    uint64_t p8a = AV_RN64A(top + 0), p8b = AV_RN64A(top + 8);
+    int y;
+
+    for (y = 0; y < 16; y++) {
+        AV_WN64A(dst + 0, p8a);
+        AV_WN64A(dst + 8, p8b);
+        dst += stride;
+    }
+}
+
+static void vert_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    uint64_t p8a = AV_RN64A(top + 0),  p8b = AV_RN64A(top + 8),
+             p8c = AV_RN64A(top + 16), p8d = AV_RN64A(top + 24);
+    int y;
+
+    for (y = 0; y < 32; y++) {
+        AV_WN64A(dst +  0, p8a);
+        AV_WN64A(dst +  8, p8b);
+        AV_WN64A(dst + 16, p8c);
+        AV_WN64A(dst + 24, p8d);
+        dst += stride;
+    }
+}
+
+static void hor_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                      const uint8_t *left, const uint8_t *top)
+{
+    AV_WN32A(dst + stride * 0, left[0] * 0x01010101U);
+    AV_WN32A(dst + stride * 1, left[1] * 0x01010101U);
+    AV_WN32A(dst + stride * 2, left[2] * 0x01010101U);
+    AV_WN32A(dst + stride * 3, left[3] * 0x01010101U);
+}
+
+static void hor_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                      const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        AV_WN64A(dst, left[y] * 0x0101010101010101ULL);
+        dst += stride;
+    }
+}
+
+static void hor_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                        const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 16; y++) {
+        uint64_t p8 = left[y] * 0x0101010101010101ULL;
+
+        AV_WN64A(dst + 0, p8);
+        AV_WN64A(dst + 8, p8);
+        dst += stride;
+    }
+}
+
+static void hor_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                        const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 32; y++) {
+        uint64_t p8 = left[y] * 0x0101010101010101ULL;
+
+        AV_WN64A(dst +  0, p8);
+        AV_WN64A(dst +  8, p8);
+        AV_WN64A(dst + 16, p8);
+        AV_WN64A(dst + 24, p8);
+        dst += stride;
+    }
+}
+
+static void tm_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                     const uint8_t *left, const uint8_t *top)
+{
+    int y, tl = top[-1];
+
+    for (y = 0; y < 4; y++) {
+        int l_m_tl = left[y] - tl;
+
+        dst[0] = av_clip_uint8(top[0] + l_m_tl);
+        dst[1] = av_clip_uint8(top[1] + l_m_tl);
+        dst[2] = av_clip_uint8(top[2] + l_m_tl);
+        dst[3] = av_clip_uint8(top[3] + l_m_tl);
+        dst   += stride;
+    }
+}
+
+static void tm_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                     const uint8_t *left, const uint8_t *top)
+{
+    int y, tl = top[-1];
+
+    for (y = 0; y < 8; y++) {
+        int l_m_tl = left[y] - tl;
+
+        dst[0] = av_clip_uint8(top[0] + l_m_tl);
+        dst[1] = av_clip_uint8(top[1] + l_m_tl);
+        dst[2] = av_clip_uint8(top[2] + l_m_tl);
+        dst[3] = av_clip_uint8(top[3] + l_m_tl);
+        dst[4] = av_clip_uint8(top[4] + l_m_tl);
+        dst[5] = av_clip_uint8(top[5] + l_m_tl);
+        dst[6] = av_clip_uint8(top[6] + l_m_tl);
+        dst[7] = av_clip_uint8(top[7] + l_m_tl);
+        dst   += stride;
+    }
+}
+
+static void tm_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                       const uint8_t *left, const uint8_t *top)
+{
+    int y, tl = top[-1];
+
+    for (y = 0; y < 16; y++) {
+        int l_m_tl = left[y] - tl;
+
+        dst[0]  = av_clip_uint8(top[0]  + l_m_tl);
+        dst[1]  = av_clip_uint8(top[1]  + l_m_tl);
+        dst[2]  = av_clip_uint8(top[2]  + l_m_tl);
+        dst[3]  = av_clip_uint8(top[3]  + l_m_tl);
+        dst[4]  = av_clip_uint8(top[4]  + l_m_tl);
+        dst[5]  = av_clip_uint8(top[5]  + l_m_tl);
+        dst[6]  = av_clip_uint8(top[6]  + l_m_tl);
+        dst[7]  = av_clip_uint8(top[7]  + l_m_tl);
+        dst[8]  = av_clip_uint8(top[8]  + l_m_tl);
+        dst[9]  = av_clip_uint8(top[9]  + l_m_tl);
+        dst[10] = av_clip_uint8(top[10] + l_m_tl);
+        dst[11] = av_clip_uint8(top[11] + l_m_tl);
+        dst[12] = av_clip_uint8(top[12] + l_m_tl);
+        dst[13] = av_clip_uint8(top[13] + l_m_tl);
+        dst[14] = av_clip_uint8(top[14] + l_m_tl);
+        dst[15] = av_clip_uint8(top[15] + l_m_tl);
+        dst    += stride;
+    }
+}
+
+static void tm_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                       const uint8_t *left, const uint8_t *top)
+{
+    int y, tl = top[-1];
+
+    for (y = 0; y < 32; y++) {
+        int l_m_tl = left[y] - tl;
+
+        dst[0]  = av_clip_uint8(top[0]  + l_m_tl);
+        dst[1]  = av_clip_uint8(top[1]  + l_m_tl);
+        dst[2]  = av_clip_uint8(top[2]  + l_m_tl);
+        dst[3]  = av_clip_uint8(top[3]  + l_m_tl);
+        dst[4]  = av_clip_uint8(top[4]  + l_m_tl);
+        dst[5]  = av_clip_uint8(top[5]  + l_m_tl);
+        dst[6]  = av_clip_uint8(top[6]  + l_m_tl);
+        dst[7]  = av_clip_uint8(top[7]  + l_m_tl);
+        dst[8]  = av_clip_uint8(top[8]  + l_m_tl);
+        dst[9]  = av_clip_uint8(top[9]  + l_m_tl);
+        dst[10] = av_clip_uint8(top[10] + l_m_tl);
+        dst[11] = av_clip_uint8(top[11] + l_m_tl);
+        dst[12] = av_clip_uint8(top[12] + l_m_tl);
+        dst[13] = av_clip_uint8(top[13] + l_m_tl);
+        dst[14] = av_clip_uint8(top[14] + l_m_tl);
+        dst[15] = av_clip_uint8(top[15] + l_m_tl);
+        dst[16] = av_clip_uint8(top[16] + l_m_tl);
+        dst[17] = av_clip_uint8(top[17] + l_m_tl);
+        dst[18] = av_clip_uint8(top[18] + l_m_tl);
+        dst[19] = av_clip_uint8(top[19] + l_m_tl);
+        dst[20] = av_clip_uint8(top[20] + l_m_tl);
+        dst[21] = av_clip_uint8(top[21] + l_m_tl);
+        dst[22] = av_clip_uint8(top[22] + l_m_tl);
+        dst[23] = av_clip_uint8(top[23] + l_m_tl);
+        dst[24] = av_clip_uint8(top[24] + l_m_tl);
+        dst[25] = av_clip_uint8(top[25] + l_m_tl);
+        dst[26] = av_clip_uint8(top[26] + l_m_tl);
+        dst[27] = av_clip_uint8(top[27] + l_m_tl);
+        dst[28] = av_clip_uint8(top[28] + l_m_tl);
+        dst[29] = av_clip_uint8(top[29] + l_m_tl);
+        dst[30] = av_clip_uint8(top[30] + l_m_tl);
+        dst[31] = av_clip_uint8(top[31] + l_m_tl);
+        dst    += stride;
+    }
+}
+
+static void dc_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                     const uint8_t *left, const uint8_t *top)
+{
+    unsigned dc = 0x01010101U *
+                  ((left[0] + left[1] + left[2] + left[3] +
+                    top[0]  + top[1]  + top[2]  + top[3]  + 4) >> 3);
+
+    AV_WN32A(dst + stride * 0, dc);
+    AV_WN32A(dst + stride * 1, dc);
+    AV_WN32A(dst + stride * 2, dc);
+    AV_WN32A(dst + stride * 3, dc);
+}
+
+static void dc_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                     const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((left[0] + left[1] + left[2] + left[3] +
+                    left[4] + left[5] + left[6] + left[7] +
+                    top[0]  + top[1]  + top[2]  + top[3]  +
+                    top[4]  + top[5]  + top[6]  + top[7]  + 8) >> 4);
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        AV_WN64A(dst, dc);
+        dst += stride;
+    }
+}
+
+static void dc_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                       const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((left[0]  + left[1]  + left[2]  + left[3]  +
+                    left[4]  + left[5]  + left[6]  + left[7]  +
+                    left[8]  + left[9]  + left[10] + left[11] +
+                    left[12] + left[13] + left[14] + left[15] +
+                    top[0]   + top[1]   + top[2]   + top[3]   +
+                    top[4]   + top[5]   + top[6]   + top[7]   +
+                    top[8]   + top[9]   + top[10]  + top[11]  +
+                    top[12]  + top[13]  + top[14]  + top[15]  + 16) >> 5);
+    int y;
+
+    for (y = 0; y < 16; y++) {
+        AV_WN64A(dst + 0, dc);
+        AV_WN64A(dst + 8, dc);
+        dst += stride;
+    }
+}
+
+static void dc_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                       const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((left[0]  + left[1]  + left[2]  + left[3]  +
+                    left[4]  + left[5]  + left[6]  + left[7]  +
+                    left[8]  + left[9]  + left[10] + left[11] +
+                    left[12] + left[13] + left[14] + left[15] +
+                    left[16] + left[17] + left[18] + left[19] +
+                    left[20] + left[21] + left[22] + left[23] +
+                    left[24] + left[25] + left[26] + left[27] +
+                    left[28] + left[29] + left[30] + left[31] +
+                    top[0]   + top[1]   + top[2]   + top[3]   +
+                    top[4]   + top[5]   + top[6]   + top[7]   +
+                    top[8]   + top[9]   + top[10]  + top[11]  +
+                    top[12]  + top[13]  + top[14]  + top[15]  +
+                    top[16]  + top[17]  + top[18]  + top[19]  +
+                    top[20]  + top[21]  + top[22]  + top[23]  +
+                    top[24]  + top[25]  + top[26]  + top[27]  +
+                    top[28]  + top[29]  + top[30]  + top[31]  + 32) >> 6);
+    int y;
+
+    for (y = 0; y < 32; y++) {
+        AV_WN64A(dst +  0, dc);
+        AV_WN64A(dst +  8, dc);
+        AV_WN64A(dst + 16, dc);
+        AV_WN64A(dst + 24, dc);
+        dst += stride;
+    }
+}
+
+static void dc_left_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                          const uint8_t *left, const uint8_t *top)
+{
+    unsigned dc = 0x01010101U *
+                  ((left[0] + left[1] + left[2] + left[3] + 2) >> 2);
+
+    AV_WN32A(dst + stride * 0, dc);
+    AV_WN32A(dst + stride * 1, dc);
+    AV_WN32A(dst + stride * 2, dc);
+    AV_WN32A(dst + stride * 3, dc);
+}
+
+static void dc_left_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                          const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((left[0] + left[1] + left[2] + left[3] +
+                    left[4] + left[5] + left[6] + left[7] + 4) >> 3);
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        AV_WN64A(dst, dc);
+        dst += stride;
+    }
+}
+
+static void dc_left_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                            const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((left[0]  + left[1]  + left[2]  + left[3]  +
+                    left[4]  + left[5]  + left[6]  + left[7]  +
+                    left[8]  + left[9]  + left[10] + left[11] +
+                    left[12] + left[13] + left[14] + left[15] + 8) >> 4);
+    int y;
+
+    for (y = 0; y < 16; y++) {
+        AV_WN64A(dst + 0, dc);
+        AV_WN64A(dst + 8, dc);
+        dst += stride;
+    }
+}
+
+static void dc_left_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                            const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((left[0]  + left[1]  + left[2]  + left[3]  +
+                    left[4]  + left[5]  + left[6]  + left[7]  +
+                    left[8]  + left[9]  + left[10] + left[11] +
+                    left[12] + left[13] + left[14] + left[15] +
+                    left[16] + left[17] + left[18] + left[19] +
+                    left[20] + left[21] + left[22] + left[23] +
+                    left[24] + left[25] + left[26] + left[27] +
+                    left[28] + left[29] + left[30] + left[31] + 16) >> 5);
+    int y;
+
+    for (y = 0; y < 32; y++) {
+        AV_WN64A(dst +  0, dc);
+        AV_WN64A(dst +  8, dc);
+        AV_WN64A(dst + 16, dc);
+        AV_WN64A(dst + 24, dc);
+        dst += stride;
+    }
+}
+
+static void dc_top_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    unsigned dc = 0x01010101U * ((top[0] + top[1] + top[2] + top[3] + 2) >> 2);
+
+    AV_WN32A(dst + stride * 0, dc);
+    AV_WN32A(dst + stride * 1, dc);
+    AV_WN32A(dst + stride * 2, dc);
+    AV_WN32A(dst + stride * 3, dc);
+}
+
+static void dc_top_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((top[0] + top[1] + top[2] + top[3] +
+                    top[4] + top[5] + top[6] + top[7] + 4) >> 3);
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        AV_WN64A(dst, dc);
+        dst += stride;
+    }
+}
+
+static void dc_top_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((top[0]  + top[1]  + top[2]  + top[3]  +
+                    top[4]  + top[5]  + top[6]  + top[7]  +
+                    top[8]  + top[9]  + top[10] + top[11] +
+                    top[12] + top[13] + top[14] + top[15] + 8) >> 4);
+    int y;
+
+    for (y = 0; y < 16; y++) {
+        AV_WN64A(dst + 0, dc);
+        AV_WN64A(dst + 8, dc);
+        dst += stride;
+    }
+}
+
+static void dc_top_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    uint64_t dc = 0x0101010101010101ULL *
+                  ((top[0]  + top[1]  + top[2]  + top[3]  +
+                    top[4]  + top[5]  + top[6]  + top[7]  +
+                    top[8]  + top[9]  + top[10] + top[11] +
+                    top[12] + top[13] + top[14] + top[15] +
+                    top[16] + top[17] + top[18] + top[19] +
+                    top[20] + top[21] + top[22] + top[23] +
+                    top[24] + top[25] + top[26] + top[27] +
+                    top[28] + top[29] + top[30] + top[31] + 16) >> 5);
+    int y;
+
+    for (y = 0; y < 32; y++) {
+        AV_WN64A(dst +  0, dc);
+        AV_WN64A(dst +  8, dc);
+        AV_WN64A(dst + 16, dc);
+        AV_WN64A(dst + 24, dc);
+        dst += stride;
+    }
+}
+
+static void dc_128_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    AV_WN32A(dst + stride * 0, 0x80808080U);
+    AV_WN32A(dst + stride * 1, 0x80808080U);
+    AV_WN32A(dst + stride * 2, 0x80808080U);
+    AV_WN32A(dst + stride * 3, 0x80808080U);
+}
+
+static void dc_128_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        AV_WN64A(dst, 0x8080808080808080ULL);
+        dst += stride;
+    }
+}
+
+static void dc_128_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 16; y++) {
+        AV_WN64A(dst + 0, 0x8080808080808080ULL);
+        AV_WN64A(dst + 8, 0x8080808080808080ULL);
+        dst += stride;
+    }
+}
+
+static void dc_128_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 32; y++) {
+        AV_WN64A(dst +  0, 0x8080808080808080ULL);
+        AV_WN64A(dst +  8, 0x8080808080808080ULL);
+        AV_WN64A(dst + 16, 0x8080808080808080ULL);
+        AV_WN64A(dst + 24, 0x8080808080808080ULL);
+        dst += stride;
+    }
+}
+
+static void dc_127_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    AV_WN32A(dst + stride * 0, 0x7F7F7F7FU);
+    AV_WN32A(dst + stride * 1, 0x7F7F7F7FU);
+    AV_WN32A(dst + stride * 2, 0x7F7F7F7FU);
+    AV_WN32A(dst + stride * 3, 0x7F7F7F7FU);
+}
+
+static void dc_127_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        AV_WN64A(dst, 0x7F7F7F7F7F7F7F7FULL);
+        dst += stride;
+    }
+}
+
+static void dc_127_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 16; y++) {
+        AV_WN64A(dst + 0, 0x7F7F7F7F7F7F7F7FULL);
+        AV_WN64A(dst + 8, 0x7F7F7F7F7F7F7F7FULL);
+        dst += stride;
+    }
+}
+
+static void dc_127_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 32; y++) {
+        AV_WN64A(dst +  0, 0x7F7F7F7F7F7F7F7FULL);
+        AV_WN64A(dst +  8, 0x7F7F7F7F7F7F7F7FULL);
+        AV_WN64A(dst + 16, 0x7F7F7F7F7F7F7F7FULL);
+        AV_WN64A(dst + 24, 0x7F7F7F7F7F7F7F7FULL);
+        dst += stride;
+    }
+}
+
+static void dc_129_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    AV_WN32A(dst + stride * 0, 0x81818181U);
+    AV_WN32A(dst + stride * 1, 0x81818181U);
+    AV_WN32A(dst + stride * 2, 0x81818181U);
+    AV_WN32A(dst + stride * 3, 0x81818181U);
+}
+
+static void dc_129_8x8_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 8; y++) {
+        AV_WN64A(dst, 0x8181818181818181ULL);
+        dst += stride;
+    }
+}
+
+static void dc_129_16x16_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 16; y++) {
+        AV_WN64A(dst + 0, 0x8181818181818181ULL);
+        AV_WN64A(dst + 8, 0x8181818181818181ULL);
+        dst += stride;
+    }
+}
+
+static void dc_129_32x32_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    int y;
+
+    for (y = 0; y < 32; y++) {
+        AV_WN64A(dst +  0, 0x8181818181818181ULL);
+        AV_WN64A(dst +  8, 0x8181818181818181ULL);
+        AV_WN64A(dst + 16, 0x8181818181818181ULL);
+        AV_WN64A(dst + 24, 0x8181818181818181ULL);
+        dst += stride;
+    }
+}
+
+#define DST(x, y) dst[(x) + (y) * stride]
+
+static void diag_downleft_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                                const uint8_t *left, const uint8_t *top)
+{
+    int a0 = top[0], a1 = top[1], a2 = top[2], a3 = top[3],
+        a4 = top[4], a5 = top[5], a6 = top[6], a7 = top[7];
+
+    DST(0, 0) = (a0 + a1 * 2 + a2 + 2) >> 2;
+    DST(1, 0) =
+    DST(0, 1) = (a1 + a2 * 2 + a3 + 2) >> 2;
+    DST(2, 0) =
+    DST(1, 1) =
+    DST(0, 2) = (a2 + a3 * 2 + a4 + 2) >> 2;
+    DST(3, 0) =
+    DST(2, 1) =
+    DST(1, 2) =
+    DST(0, 3) = (a3 + a4 * 2 + a5 + 2) >> 2;
+    DST(3, 1) =
+    DST(2, 2) =
+    DST(1, 3) = (a4 + a5 * 2 + a6 + 2) >> 2;
+    DST(3, 2) =
+    DST(2, 3) = (a5 + a6 * 2 + a7 + 2) >> 2;
+    DST(3, 3) = a7;  // note: this is different from vp8 and such
+}
+
+#define def_diag_downleft(size)                                             \
+static void diag_downleft_ ## size ## x ## size ## _c(uint8_t *dst,         \
+                                                      ptrdiff_t stride,     \
+                                                      const uint8_t *left,  \
+                                                      const uint8_t *top)   \
+{                                                                           \
+    int i, j;                                                               \
+    uint8_t v[size - 1];                                                    \
+                                                                            \
+    for (i = 0; i < size - 2; i++)                                          \
+        v[i] = (top[i] + top[i + 1] * 2 + top[i + 2] + 2) >> 2;             \
+    v[size - 2] = (top[size - 2] + top[size - 1] * 3 + 2) >> 2;             \
+                                                                            \
+    for (j = 0; j < size; j++) {                                            \
+        memcpy(dst + j * stride, v + j, size - 1 - j);                      \
+        memset(dst + j * stride + size - 1 - j, top[size - 1], j + 1);      \
+    }                                                                       \
+}
+
+def_diag_downleft(8)
+def_diag_downleft(16)
+def_diag_downleft(32)
+
+static void diag_downright_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                                 const uint8_t *left, const uint8_t *top)
+{
+    int tl = top[-1], a0 = top[0], a1 = top[1], a2 = top[2], a3 = top[3],
+        l0 = left[0], l1 = left[1], l2 = left[2], l3 = left[3];
+
+    DST(0, 3) = (l1 + l2 * 2 + l3 + 2) >> 2;
+    DST(0, 2) =
+    DST(1, 3) = (l0 + l1 * 2 + l2 + 2) >> 2;
+    DST(0, 1) =
+    DST(1, 2) =
+    DST(2, 3) = (tl + l0 * 2 + l1 + 2) >> 2;
+    DST(0, 0) =
+    DST(1, 1) =
+    DST(2, 2) =
+    DST(3, 3) = (l0 + tl * 2 + a0 + 2) >> 2;
+    DST(1, 0) =
+    DST(2, 1) =
+    DST(3, 2) = (tl + a0 * 2 + a1 + 2) >> 2;
+    DST(2, 0) =
+    DST(3, 1) = (a0 + a1 * 2 + a2 + 2) >> 2;
+    DST(3, 0) = (a1 + a2 * 2 + a3 + 2) >> 2;
+}
+
+#define def_diag_downright(size)                                            \
+static void diag_downright_ ## size ## x ## size ## _c(uint8_t *dst,        \
+                                                       ptrdiff_t stride,    \
+                                                       const uint8_t *left, \
+                                                       const uint8_t *top)  \
+{                                                                           \
+    int i, j;                                                               \
+    uint8_t v[size + size - 1];                                             \
+                                                                            \
+    for (i = 0; i < size - 2; i++) {                                        \
+        v[i]            = (left[size - 1 - i] +                             \
+                           left[size - 2 - i] * 2 +                         \
+                           left[size - 3 - i] + 2) >> 2;                    \
+        v[size + 1 + i] = (top[i]             +                             \
+                           top[i + 1]         * 2 +                         \
+                           top[i + 2]         + 2) >> 2;                    \
+    }                                                                       \
+    v[size - 2] = (left[1] + left[0] * 2 + top[-1] + 2) >> 2;               \
+    v[size - 1] = (left[0] + top[-1] * 2 + top[0]  + 2) >> 2;               \
+    v[size]     = (top[-1] + top[0]  * 2 + top[1]  + 2) >> 2;               \
+                                                                            \
+    for (j = 0; j < size; j++)                                              \
+        memcpy(dst + j * stride, v + size - 1 - j, size);                   \
+}
+
+def_diag_downright(8)
+def_diag_downright(16)
+def_diag_downright(32)
+
+static void vert_right_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                             const uint8_t *left, const uint8_t *top)
+{
+    int tl = top[-1], a0 = top[0], a1 = top[1], a2 = top[2], a3 = top[3],
+        l0 = left[0], l1 = left[1], l2 = left[2];
+
+    DST(0, 3) = (l0 + l1 * 2 + l2 + 2) >> 2;
+    DST(0, 2) = (tl + l0 * 2 + l1 + 2) >> 2;
+    DST(0, 0) =
+    DST(1, 2) = (tl + a0          + 1) >> 1;
+    DST(0, 1) =
+    DST(1, 3) = (l0 + tl * 2 + a0 + 2) >> 2;
+    DST(1, 0) =
+    DST(2, 2) = (a0 + a1          + 1) >> 1;
+    DST(1, 1) =
+    DST(2, 3) = (tl + a0 * 2 + a1 + 2) >> 2;
+    DST(2, 0) =
+    DST(3, 2) = (a1 + a2          + 1) >> 1;
+    DST(2, 1) =
+    DST(3, 3) = (a0 + a1 * 2 + a2 + 2) >> 2;
+    DST(3, 0) = (a2 + a3          + 1) >> 1;
+    DST(3, 1) = (a1 + a2 * 2 + a3 + 2) >> 2;
+}
+
+#define def_vert_right(size)                                                \
+static void vert_right_ ## size ## x ## size ## _c(uint8_t *dst,            \
+                                                   ptrdiff_t stride,        \
+                                                   const uint8_t *left,     \
+                                                   const uint8_t *top)      \
+{                                                                           \
+    int i, j;                                                               \
+    uint8_t ve[size + size / 2 - 1], vo[size + size / 2 - 1];               \
+                                                                            \
+    for (i = 0; i < size / 2 - 2; i++) {                                    \
+        vo[i] = (left[size - 4 - i * 2] +                                   \
+                 left[size - 3 - i * 2] * 2 +                               \
+                 left[size - 2 - i * 2] + 2) >> 2;                          \
+        ve[i] = (left[size - 5 - i * 2] +                                   \
+                 left[size - 4 - i * 2] * 2 +                               \
+                 left[size - 3 - i * 2] + 2) >> 2;                          \
+    }                                                                       \
+    vo[size / 2 - 2] = (left[0] + left[1] * 2 + left[2] + 2) >> 2;          \
+    ve[size / 2 - 2] = (top[-1] + left[0] * 2 + left[1] + 2) >> 2;          \
+                                                                            \
+    ve[size / 2 - 1] = (top[-1] + top[0] + 1) >> 1;                         \
+    vo[size / 2 - 1] = (left[0] + top[-1] * 2 + top[0] + 2) >> 2;           \
+    for (i = 0; i < size - 1; i++) {                                        \
+        ve[size / 2 + i] = (top[i] + top[i + 1] + 1) >> 1;                  \
+        vo[size / 2 + i] = (top[i - 1] + top[i] * 2 + top[i + 1] + 2) >> 2; \
+    }                                                                       \
+                                                                            \
+    for (j = 0; j < size / 2; j++) {                                        \
+        memcpy(dst +  j * 2      * stride, ve + size / 2 - 1 - j, size);    \
+        memcpy(dst + (j * 2 + 1) * stride, vo + size / 2 - 1 - j, size);    \
+    }                                                                       \
+}
+
+def_vert_right(8)
+def_vert_right(16)
+def_vert_right(32)
+
+static void hor_down_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                           const uint8_t *left, const uint8_t *top)
+{
+    int l0 = left[0], l1 = left[1], l2 = left[2], l3 = left[3],
+        tl = top[-1], a0 = top[0], a1 = top[1], a2 = top[2];
+
+    DST(2, 0) = (tl + a0 * 2 + a1 + 2) >> 2;
+    DST(3, 0) = (a0 + a1 * 2 + a2 + 2) >> 2;
+    DST(0, 0) =
+    DST(2, 1) = (tl + l0          + 1) >> 1;
+    DST(1, 0) =
+    DST(3, 1) = (a0 + tl * 2 + l0 + 2) >> 2;
+    DST(0, 1) =
+    DST(2, 2) = (l0 + l1          + 1) >> 1;
+    DST(1, 1) =
+    DST(3, 2) = (tl + l0 * 2 + l1 + 2) >> 2;
+    DST(0, 2) =
+    DST(2, 3) = (l1 + l2          + 1) >> 1;
+    DST(1, 2) =
+    DST(3, 3) = (l0 + l1 * 2 + l2 + 2) >> 2;
+    DST(0, 3) = (l2 + l3          + 1) >> 1;
+    DST(1, 3) = (l1 + l2 * 2 + l3 + 2) >> 2;
+}
+
+#define def_hor_down(size)                                              \
+static void hor_down_ ## size ## x ## size ## _c(uint8_t *dst,          \
+                                                 ptrdiff_t stride,      \
+                                                 const uint8_t *left,   \
+                                                 const uint8_t *top)    \
+{                                                                       \
+    int i, j;                                                           \
+    uint8_t v[size * 3 - 2];                                            \
+                                                                        \
+    for (i = 0; i < size - 2; i++) {                                    \
+        v[i * 2]        = (left[size - 2 - i] +                         \
+                           left[size - 1 - i] + 1) >> 1;                \
+        v[i * 2    + 1] = (left[size - 3 - i] +                         \
+                           left[size - 2 - i] * 2 +                     \
+                           left[size - 1 - i] + 2) >> 2;                \
+        v[size * 2 + i] = (top[i - 1] +                                 \
+                           top[i] * 2 +                                 \
+                           top[i + 1] + 2) >> 2;                        \
+    }                                                                   \
+    v[size * 2 - 2] = (top[-1] + left[0] + 1) >> 1;                     \
+    v[size * 2 - 4] = (left[0] + left[1] + 1) >> 1;                     \
+    v[size * 2 - 1] = (top[0]  + top[-1] * 2 + left[0] + 2) >> 2;       \
+    v[size * 2 - 3] = (top[-1] + left[0] * 2 + left[1] + 2) >> 2;       \
+                                                                        \
+    for (j = 0; j < size; j++)                                          \
+        memcpy(dst + j * stride, v + size * 2 - 2 - j * 2, size);       \
+}
+
+def_hor_down(8)
+def_hor_down(16)
+def_hor_down(32)
+
+static void vert_left_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                            const uint8_t *left, const uint8_t *top)
+{
+    int a0 = top[0], a1 = top[1], a2 = top[2], a3 = top[3],
+        a4 = top[4], a5 = top[5], a6 = top[6];
+
+    DST(0, 0) = (a0 + a1          + 1) >> 1;
+    DST(0, 1) = (a0 + a1 * 2 + a2 + 2) >> 2;
+    DST(1, 0) =
+    DST(0, 2) = (a1 + a2          + 1) >> 1;
+    DST(1, 1) =
+    DST(0, 3) = (a1 + a2 * 2 + a3 + 2) >> 2;
+    DST(2, 0) =
+    DST(1, 2) = (a2 + a3          + 1) >> 1;
+    DST(2, 1) =
+    DST(1, 3) = (a2 + a3 * 2 + a4 + 2) >> 2;
+    DST(3, 0) =
+    DST(2, 2) = (a3 + a4          + 1) >> 1;
+    DST(3, 1) =
+    DST(2, 3) = (a3 + a4 * 2 + a5 + 2) >> 2;
+    DST(3, 2) = (a4 + a5          + 1) >> 1;
+    DST(3, 3) = (a4 + a5 * 2 + a6 + 2) >> 2;
+}
+
+#define def_vert_left(size)                                             \
+static void vert_left_ ## size ## x ## size ## _c(uint8_t *dst,         \
+                                                  ptrdiff_t stride,     \
+                                                  const uint8_t *left,  \
+                                                  const uint8_t *top)   \
+{                                                                       \
+    int i, j;                                                           \
+    uint8_t ve[size - 1], vo[size - 1];                                 \
+                                                                        \
+    for (i = 0; i < size - 2; i++) {                                    \
+        ve[i] = (top[i] + top[i + 1] + 1) >> 1;                         \
+        vo[i] = (top[i] + top[i + 1] * 2 + top[i + 2] + 2) >> 2;        \
+    }                                                                   \
+    ve[size - 2] = (top[size - 2] + top[size - 1] + 1) >> 1;            \
+    vo[size - 2] = (top[size - 2] + top[size - 1] * 3 + 2) >> 2;        \
+                                                                        \
+    for (j = 0; j < size / 2; j++) {                                    \
+        memcpy(dst +  j * 2      * stride, ve + j, size - (j + 1));     \
+        memset(dst +  j * 2      * stride + size - j - 1,               \
+               top[size - 1], j + 1);                                   \
+        memcpy(dst + (j * 2 + 1) * stride, vo + j, size - (j + 1));     \
+        memset(dst + (j * 2 + 1) * stride + size - j - 1,               \
+               top[size - 1], j + 1);                                   \
+    }                                                                   \
+}
+
+def_vert_left(8)
+def_vert_left(16)
+def_vert_left(32)
+
+static void hor_up_4x4_c(uint8_t *dst, ptrdiff_t stride,
+                         const uint8_t *left, const uint8_t *top)
+{
+    int l0 = left[0], l1 = left[1], l2 = left[2], l3 = left[3];
+
+    DST(0, 0) = (l0 + l1          + 1) >> 1;
+    DST(1, 0) = (l0 + l1 * 2 + l2 + 2) >> 2;
+    DST(0, 1) =
+    DST(2, 0) = (l1 + l2          + 1) >> 1;
+    DST(1, 1) =
+    DST(3, 0) = (l1 + l2 * 2 + l3 + 2) >> 2;
+    DST(0, 2) =
+    DST(2, 1) = (l2 + l3          + 1) >> 1;
+    DST(1, 2) =
+    DST(3, 1) = (l2 + l3 * 3      + 2) >> 2;
+    DST(0, 3) =
+    DST(1, 3) =
+    DST(2, 2) =
+    DST(2, 3) =
+    DST(3, 2) =
+    DST(3, 3) = l3;
+}
+
+#define def_hor_up(size)                                                    \
+static void hor_up_ ## size ## x ## size ## _c(uint8_t *dst,                \
+                                               ptrdiff_t stride,            \
+                                               const uint8_t *left,         \
+                                               const uint8_t *top)          \
+{                                                                           \
+    int i, j;                                                               \
+    uint8_t v[size * 2 - 2];                                                \
+                                                                            \
+    for (i = 0; i < size - 2; i++) {                                        \
+        v[i * 2]     = (left[i] + left[i + 1] + 1) >> 1;                    \
+        v[i * 2 + 1] = (left[i] + left[i + 1] * 2 + left[i + 2] + 2) >> 2;  \
+    }                                                                       \
+    v[size * 2 - 4] = (left[size - 2] + left[size - 1]     + 1) >> 1;       \
+    v[size * 2 - 3] = (left[size - 2] + left[size - 1] * 3 + 2) >> 2;       \
+                                                                            \
+    for (j = 0; j < size / 2; j++)                                          \
+        memcpy(dst + j * stride, v + j * 2, size);                          \
+    for (j = size / 2; j < size; j++) {                                     \
+        memcpy(dst + j * stride, v + j * 2, size * 2 - 2 - j * 2);          \
+        memset(dst + j * stride + size * 2 - 2 - j * 2, left[size - 1],     \
+               2 + j * 2 - size);                                           \
+    }                                                                       \
+}
+
+def_hor_up(8)
+def_hor_up(16)
+def_hor_up(32)
+
+#undef DST
+
+static av_cold void vp9dsp_intrapred_init(VP9DSPContext *dsp)
+{
+#define init_intra_pred(tx, sz)                                              \
+    dsp->intra_pred[tx][VERT_PRED]            = vert_           ## sz ## _c; \
+    dsp->intra_pred[tx][HOR_PRED]             = hor_            ## sz ## _c; \
+    dsp->intra_pred[tx][DC_PRED]              = dc_             ## sz ## _c; \
+    dsp->intra_pred[tx][DIAG_DOWN_LEFT_PRED]  = diag_downleft_  ## sz ## _c; \
+    dsp->intra_pred[tx][DIAG_DOWN_RIGHT_PRED] = diag_downright_ ## sz ## _c; \
+    dsp->intra_pred[tx][VERT_RIGHT_PRED]      = vert_right_     ## sz ## _c; \
+    dsp->intra_pred[tx][HOR_DOWN_PRED]        = hor_down_       ## sz ## _c; \
+    dsp->intra_pred[tx][VERT_LEFT_PRED]       = vert_left_      ## sz ## _c; \
+    dsp->intra_pred[tx][HOR_UP_PRED]          = hor_up_         ## sz ## _c; \
+    dsp->intra_pred[tx][TM_VP8_PRED]          = tm_             ## sz ## _c; \
+    dsp->intra_pred[tx][LEFT_DC_PRED]         = dc_left_        ## sz ## _c; \
+    dsp->intra_pred[tx][TOP_DC_PRED]          = dc_top_         ## sz ## _c; \
+    dsp->intra_pred[tx][DC_128_PRED]          = dc_128_         ## sz ## _c; \
+    dsp->intra_pred[tx][DC_127_PRED]          = dc_127_         ## sz ## _c; \
+    dsp->intra_pred[tx][DC_129_PRED]          = dc_129_         ## sz ## _c
+
+    init_intra_pred(TX_4X4,   4x4);
+    init_intra_pred(TX_8X8,   8x8);
+    init_intra_pred(TX_16X16, 16x16);
+    init_intra_pred(TX_32X32, 32x32);
+
+#undef init_intra_pred
+}
+
+#define itxfm_wrapper(type_a, type_b, sz, bits)                             \
+static void                                                                 \
+type_a ## _ ## type_b ## _ ## sz ## x ## sz ## _add_c(uint8_t *dst,         \
+                                                      ptrdiff_t stride,     \
+                                                      int16_t *block,       \
+                                                      int eob)              \
+{                                                                           \
+    int i, j;                                                               \
+    int16_t tmp[sz * sz], out[sz];                                          \
+    for (i = 0; i < sz; i++)                                                \
+        type_a ## sz ## _1d(tmp + i * sz, block + i, sz, 0);                \
+    memset(block, 0, sz * sz * sizeof(*block));                             \
+    for (i = 0; i < sz; i++) {                                              \
+        type_b ## sz ## _1d(out, tmp + i, sz, 1);                           \
+        for (j = 0; j < sz; j++)                                            \
+            dst[j * stride] =                                               \
+                av_clip_uint8(dst[j * stride] +                             \
+                              (bits ? (out[j] + (1 << (bits - 1))) >> bits  \
+                                    : out[j]));                             \
+        dst++;                                                              \
+    }                                                                       \
+}
+
+#define itxfm_wrap(sz, bits)             \
+    itxfm_wrapper(idct, idct, sz, bits)  \
+    itxfm_wrapper(iadst, idct, sz, bits) \
+    itxfm_wrapper(idct, iadst, sz, bits) \
+    itxfm_wrapper(iadst, iadst, sz, bits)
+
+#define IN(x) in[x * stride]
+
+static av_always_inline void idct4_1d(int16_t *out, const int16_t *in,
+                                      ptrdiff_t stride, int pass)
+{
+    int t0, t1, t2, t3;
+
+    t0 = ((IN(0)        + IN(2)) * 11585 + (1 << 13)) >> 14;
+    t1 = ((IN(0)        - IN(2)) * 11585 + (1 << 13)) >> 14;
+    t2 = (IN(1) *  6270 - IN(3)  * 15137 + (1 << 13)) >> 14;
+    t3 = (IN(1) * 15137 + IN(3)  *  6270 + (1 << 13)) >> 14;
+
+    out[0] = t0 + t3;
+    out[1] = t1 + t2;
+    out[2] = t1 - t2;
+    out[3] = t0 - t3;
+}
+
+static av_always_inline void iadst4_1d(int16_t *out, const int16_t *in,
+                                       ptrdiff_t stride, int pass)
+{
+    int t0, t1, t2, t3;
+
+    t0 =  5283 * IN(0) + 15212 * IN(2) +  9929 * IN(3);
+    t1 =  9929 * IN(0) -  5283 * IN(2) - 15212 * IN(3);
+    t2 = 13377 * (IN(0) - IN(2) + IN(3));
+    t3 = 13377 * IN(1);
+
+    out[0] = (t0 + t3      + (1 << 13)) >> 14;
+    out[1] = (t1 + t3      + (1 << 13)) >> 14;
+    out[2] = (t2           + (1 << 13)) >> 14;
+    out[3] = (t0 + t1 - t3 + (1 << 13)) >> 14;
+}
+
+itxfm_wrap(4, 4)
+
+static av_always_inline void idct8_1d(int16_t *out, const int16_t *in,
+                                      ptrdiff_t stride, int pass)
+{
+    int t0, t0a, t1, t1a, t2, t2a, t3, t3a, t4, t4a, t5, t5a, t6, t6a, t7, t7a;
+
+    t0a = ((IN(0)        + IN(4)) * 11585 + (1 << 13)) >> 14;
+    t1a = ((IN(0)        - IN(4)) * 11585 + (1 << 13)) >> 14;
+    t2a = (IN(2) *  6270 - IN(6)  * 15137 + (1 << 13)) >> 14;
+    t3a = (IN(2) * 15137 + IN(6)  *  6270 + (1 << 13)) >> 14;
+    t4a = (IN(1) *  3196 - IN(7)  * 16069 + (1 << 13)) >> 14;
+    t5a = (IN(5) * 13623 - IN(3)  *  9102 + (1 << 13)) >> 14;
+    t6a = (IN(5) *  9102 + IN(3)  * 13623 + (1 << 13)) >> 14;
+    t7a = (IN(1) * 16069 + IN(7)  *  3196 + (1 << 13)) >> 14;
+
+    t0  = t0a + t3a;
+    t1  = t1a + t2a;
+    t2  = t1a - t2a;
+    t3  = t0a - t3a;
+    t4  = t4a + t5a;
+    t5a = t4a - t5a;
+    t7  = t7a + t6a;
+    t6a = t7a - t6a;
+
+    t5  = ((t6a - t5a) * 11585 + (1 << 13)) >> 14;
+    t6  = ((t6a + t5a) * 11585 + (1 << 13)) >> 14;
+
+    out[0] = t0 + t7;
+    out[1] = t1 + t6;
+    out[2] = t2 + t5;
+    out[3] = t3 + t4;
+    out[4] = t3 - t4;
+    out[5] = t2 - t5;
+    out[6] = t1 - t6;
+    out[7] = t0 - t7;
+}
+
+static av_always_inline void iadst8_1d(int16_t *out, const int16_t *in,
+                                       ptrdiff_t stride, int pass)
+{
+    int t0, t0a, t1, t1a, t2, t2a, t3, t3a, t4, t4a, t5, t5a, t6, t6a, t7, t7a;
+
+    t0a = 16305 * IN(7) +  1606 * IN(0);
+    t1a =  1606 * IN(7) - 16305 * IN(0);
+    t2a = 14449 * IN(5) +  7723 * IN(2);
+    t3a =  7723 * IN(5) - 14449 * IN(2);
+    t4a = 10394 * IN(3) + 12665 * IN(4);
+    t5a = 12665 * IN(3) - 10394 * IN(4);
+    t6a =  4756 * IN(1) + 15679 * IN(6);
+    t7a = 15679 * IN(1) -  4756 * IN(6);
+
+    t0  = (t0a + t4a + (1 << 13)) >> 14;
+    t1  = (t1a + t5a + (1 << 13)) >> 14;
+    t2  = (t2a + t6a + (1 << 13)) >> 14;
+    t3  = (t3a + t7a + (1 << 13)) >> 14;
+    t4  = (t0a - t4a + (1 << 13)) >> 14;
+    t5  = (t1a - t5a + (1 << 13)) >> 14;
+    t6  = (t2a - t6a + (1 << 13)) >> 14;
+    t7  = (t3a - t7a + (1 << 13)) >> 14;
+
+    t4a = 15137 * t4 +  6270 * t5;
+    t5a =  6270 * t4 - 15137 * t5;
+    t6a = 15137 * t7 -  6270 * t6;
+    t7a =  6270 * t7 + 15137 * t6;
+
+    out[0] =   t0 + t2;
+    out[7] = -(t1 + t3);
+    t2     =   t0 - t2;
+    t3     =   t1 - t3;
+
+    out[1] = -((t4a + t6a + (1 << 13)) >> 14);
+    out[6] =   (t5a + t7a + (1 << 13)) >> 14;
+    t6     =   (t4a - t6a + (1 << 13)) >> 14;
+    t7     =   (t5a - t7a + (1 << 13)) >> 14;
+
+    out[3] = -(((t2 + t3) * 11585 + (1 << 13)) >> 14);
+    out[4] =   ((t2 - t3) * 11585 + (1 << 13)) >> 14;
+    out[2] =   ((t6 + t7) * 11585 + (1 << 13)) >> 14;
+    out[5] = -(((t6 - t7) * 11585 + (1 << 13)) >> 14);
+}
+
+itxfm_wrap(8, 5)
+
+static av_always_inline void idct16_1d(int16_t *out, const int16_t *in,
+                                       ptrdiff_t stride, int pass)
+{
+    int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15;
+    int t0a, t1a, t2a, t3a, t4a, t5a, t6a, t7a;
+    int t8a, t9a, t10a, t11a, t12a, t13a, t14a, t15a;
+
+    t0a  = ((IN(0)         + IN(8)) * 11585 + (1 << 13)) >> 14;
+    t1a  = ((IN(0)         - IN(8)) * 11585 + (1 << 13)) >> 14;
+    t2a  = (IN(4)  *  6270 - IN(12) * 15137 + (1 << 13)) >> 14;
+    t3a  = (IN(4)  * 15137 + IN(12) *  6270 + (1 << 13)) >> 14;
+    t4a  = (IN(2)  *  3196 - IN(14) * 16069 + (1 << 13)) >> 14;
+    t7a  = (IN(2)  * 16069 + IN(14) *  3196 + (1 << 13)) >> 14;
+    t5a  = (IN(10) * 13623 - IN(6)  *  9102 + (1 << 13)) >> 14;
+    t6a  = (IN(10) *  9102 + IN(6)  * 13623 + (1 << 13)) >> 14;
+    t8a  = (IN(1)  *  1606 - IN(15) * 16305 + (1 << 13)) >> 14;
+    t15a = (IN(1)  * 16305 + IN(15) *  1606 + (1 << 13)) >> 14;
+    t9a  = (IN(9)  * 12665 - IN(7)  * 10394 + (1 << 13)) >> 14;
+    t14a = (IN(9)  * 10394 + IN(7)  * 12665 + (1 << 13)) >> 14;
+    t10a = (IN(5)  *  7723 - IN(11) * 14449 + (1 << 13)) >> 14;
+    t13a = (IN(5)  * 14449 + IN(11) *  7723 + (1 << 13)) >> 14;
+    t11a = (IN(13) * 15679 - IN(3)  *  4756 + (1 << 13)) >> 14;
+    t12a = (IN(13) *  4756 + IN(3)  * 15679 + (1 << 13)) >> 14;
+
+    t0   = t0a  + t3a;
+    t1   = t1a  + t2a;
+    t2   = t1a  - t2a;
+    t3   = t0a  - t3a;
+    t4   = t4a  + t5a;
+    t5   = t4a  - t5a;
+    t6   = t7a  - t6a;
+    t7   = t7a  + t6a;
+    t8   = t8a  + t9a;
+    t9   = t8a  - t9a;
+    t10  = t11a - t10a;
+    t11  = t11a + t10a;
+    t12  = t12a + t13a;
+    t13  = t12a - t13a;
+    t14  = t15a - t14a;
+    t15  = t15a + t14a;
+
+    t5a  =   ((t6         - t5) * 11585  + (1 << 13)) >> 14;
+    t6a  =   ((t6         + t5) * 11585  + (1 << 13)) >> 14;
+    t9a  =   (t14 *  6270 - t9  * 15137  + (1 << 13)) >> 14;
+    t14a =   (t14 * 15137 + t9  *  6270  + (1 << 13)) >> 14;
+    t10a = (-(t13 * 15137 + t10 *  6270) + (1 << 13)) >> 14;
+    t13a =   (t13 *  6270 - t10 * 15137  + (1 << 13)) >> 14;
+
+    t0a  = t0   + t7;
+    t1a  = t1   + t6a;
+    t2a  = t2   + t5a;
+    t3a  = t3   + t4;
+    t4   = t3   - t4;
+    t5   = t2   - t5a;
+    t6   = t1   - t6a;
+    t7   = t0   - t7;
+    t8a  = t8   + t11;
+    t9   = t9a  + t10a;
+    t10  = t9a  - t10a;
+    t11a = t8   - t11;
+    t12a = t15  - t12;
+    t13  = t14a - t13a;
+    t14  = t14a + t13a;
+    t15a = t15  + t12;
+
+    t10a = ((t13  - t10)  * 11585 + (1 << 13)) >> 14;
+    t13a = ((t13  + t10)  * 11585 + (1 << 13)) >> 14;
+    t11  = ((t12a - t11a) * 11585 + (1 << 13)) >> 14;
+    t12  = ((t12a + t11a) * 11585 + (1 << 13)) >> 14;
+
+    out[0]  = t0a + t15a;
+    out[1]  = t1a + t14;
+    out[2]  = t2a + t13a;
+    out[3]  = t3a + t12;
+    out[4]  = t4  + t11;
+    out[5]  = t5  + t10a;
+    out[6]  = t6  + t9;
+    out[7]  = t7  + t8a;
+    out[8]  = t7  - t8a;
+    out[9]  = t6  - t9;
+    out[10] = t5  - t10a;
+    out[11] = t4  - t11;
+    out[12] = t3a - t12;
+    out[13] = t2a - t13a;
+    out[14] = t1a - t14;
+    out[15] = t0a - t15a;
+}
+
+static av_always_inline void iadst16_1d(int16_t *out, const int16_t *in,
+                                        ptrdiff_t stride, int pass)
+{
+    int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15;
+    int t0a, t1a, t2a, t3a, t4a, t5a, t6a, t7a;
+    int t8a, t9a, t10a, t11a, t12a, t13a, t14a, t15a;
+
+    t0  = IN(15) * 16364 + IN(0)  *   804;
+    t1  = IN(15) *   804 - IN(0)  * 16364;
+    t2  = IN(13) * 15893 + IN(2)  *  3981;
+    t3  = IN(13) *  3981 - IN(2)  * 15893;
+    t4  = IN(11) * 14811 + IN(4)  *  7005;
+    t5  = IN(11) *  7005 - IN(4)  * 14811;
+    t6  = IN(9)  * 13160 + IN(6)  *  9760;
+    t7  = IN(9)  *  9760 - IN(6)  * 13160;
+    t8  = IN(7)  * 11003 + IN(8)  * 12140;
+    t9  = IN(7)  * 12140 - IN(8)  * 11003;
+    t10 = IN(5)  *  8423 + IN(10) * 14053;
+    t11 = IN(5)  * 14053 - IN(10) *  8423;
+    t12 = IN(3)  *  5520 + IN(12) * 15426;
+    t13 = IN(3)  * 15426 - IN(12) *  5520;
+    t14 = IN(1)  *  2404 + IN(14) * 16207;
+    t15 = IN(1)  * 16207 - IN(14) *  2404;
+
+    t0a  = (t0 + t8  + (1 << 13)) >> 14;
+    t1a  = (t1 + t9  + (1 << 13)) >> 14;
+    t2a  = (t2 + t10 + (1 << 13)) >> 14;
+    t3a  = (t3 + t11 + (1 << 13)) >> 14;
+    t4a  = (t4 + t12 + (1 << 13)) >> 14;
+    t5a  = (t5 + t13 + (1 << 13)) >> 14;
+    t6a  = (t6 + t14 + (1 << 13)) >> 14;
+    t7a  = (t7 + t15 + (1 << 13)) >> 14;
+    t8a  = (t0 - t8  + (1 << 13)) >> 14;
+    t9a  = (t1 - t9  + (1 << 13)) >> 14;
+    t10a = (t2 - t10 + (1 << 13)) >> 14;
+    t11a = (t3 - t11 + (1 << 13)) >> 14;
+    t12a = (t4 - t12 + (1 << 13)) >> 14;
+    t13a = (t5 - t13 + (1 << 13)) >> 14;
+    t14a = (t6 - t14 + (1 << 13)) >> 14;
+    t15a = (t7 - t15 + (1 << 13)) >> 14;
+
+    t8   = t8a  * 16069 + t9a  *  3196;
+    t9   = t8a  *  3196 - t9a  * 16069;
+    t10  = t10a *  9102 + t11a * 13623;
+    t11  = t10a * 13623 - t11a *  9102;
+    t12  = t13a * 16069 - t12a *  3196;
+    t13  = t13a *  3196 + t12a * 16069;
+    t14  = t15a *  9102 - t14a * 13623;
+    t15  = t15a * 13623 + t14a *  9102;
+
+    t0   = t0a  + t4a;
+    t1   = t1a  + t5a;
+    t2   = t2a  + t6a;
+    t3   = t3a  + t7a;
+    t4   = t0a  - t4a;
+    t5   = t1a  - t5a;
+    t6   = t2a  - t6a;
+    t7   = t3a  - t7a;
+    t8a  = (t8  + t12 + (1 << 13)) >> 14;
+    t9a  = (t9  + t13 + (1 << 13)) >> 14;
+    t10a = (t10 + t14 + (1 << 13)) >> 14;
+    t11a = (t11 + t15 + (1 << 13)) >> 14;
+    t12a = (t8  - t12 + (1 << 13)) >> 14;
+    t13a = (t9  - t13 + (1 << 13)) >> 14;
+    t14a = (t10 - t14 + (1 << 13)) >> 14;
+    t15a = (t11 - t15 + (1 << 13)) >> 14;
+
+    t4a  = t4   * 15137 + t5   *  6270;
+    t5a  = t4   *  6270 - t5   * 15137;
+    t6a  = t7   * 15137 - t6   *  6270;
+    t7a  = t7   *  6270 + t6   * 15137;
+    t12  = t12a * 15137 + t13a *  6270;
+    t13  = t12a *  6270 - t13a * 15137;
+    t14  = t15a * 15137 - t14a *  6270;
+    t15  = t15a *  6270 + t14a * 15137;
+
+    out[0]  =     t0 + t2;
+    out[15] =   -(t1 + t3);
+    t2a     =     t0 - t2;
+    t3a     =     t1 - t3;
+    out[3]  = -((t4a + t6a + (1 << 13)) >> 14);
+    out[12] =   (t5a + t7a + (1 << 13)) >> 14;
+    t6      =   (t4a - t6a + (1 << 13)) >> 14;
+    t7      =   (t5a - t7a + (1 << 13)) >> 14;
+    out[1]  =  -(t8a + t10a);
+    out[14] =    t9a + t11a;
+    t10     =    t8a - t10a;
+    t11     =    t9a - t11a;
+    out[2]  =   (t12 + t14 + (1 << 13)) >> 14;
+    out[13] = -((t13 + t15 + (1 << 13)) >> 14);
+    t14a    =   (t12 - t14 + (1 << 13)) >> 14;
+    t15a    =   (t13 - t15 + (1 << 13)) >> 14;
+
+    out[7]  = ((t2a  + t3a)  * -11585 + (1 << 13)) >> 14;
+    out[8]  = ((t2a  - t3a)  *  11585 + (1 << 13)) >> 14;
+    out[4]  = ((t7   + t6)   *  11585 + (1 << 13)) >> 14;
+    out[11] = ((t7   - t6)   *  11585 + (1 << 13)) >> 14;
+    out[6]  = ((t11  + t10)  *  11585 + (1 << 13)) >> 14;
+    out[9]  = ((t11  - t10)  *  11585 + (1 << 13)) >> 14;
+    out[5]  = ((t14a + t15a) * -11585 + (1 << 13)) >> 14;
+    out[10] = ((t14a - t15a) *  11585 + (1 << 13)) >> 14;
+}
+
+itxfm_wrap(16, 6)
+
+static av_always_inline void idct32_1d(int16_t *out, const int16_t *in,
+                                       ptrdiff_t stride, int pass)
+{
+    int t0a  = ((IN(0)         + IN(16)) * 11585 + (1 << 13)) >> 14;
+    int t1a  = ((IN(0)         - IN(16)) * 11585 + (1 << 13)) >> 14;
+    int t2a  = (IN(8)  *  6270 - IN(24)  * 15137 + (1 << 13)) >> 14;
+    int t3a  = (IN(8)  * 15137 + IN(24)  *  6270 + (1 << 13)) >> 14;
+    int t4a  = (IN(4)  *  3196 - IN(28)  * 16069 + (1 << 13)) >> 14;
+    int t7a  = (IN(4)  * 16069 + IN(28)  *  3196 + (1 << 13)) >> 14;
+    int t5a  = (IN(20) * 13623 - IN(12)  *  9102 + (1 << 13)) >> 14;
+    int t6a  = (IN(20) *  9102 + IN(12)  * 13623 + (1 << 13)) >> 14;
+    int t8a  = (IN(2)  *  1606 - IN(30)  * 16305 + (1 << 13)) >> 14;
+    int t15a = (IN(2)  * 16305 + IN(30)  *  1606 + (1 << 13)) >> 14;
+    int t9a  = (IN(18) * 12665 - IN(14)  * 10394 + (1 << 13)) >> 14;
+    int t14a = (IN(18) * 10394 + IN(14)  * 12665 + (1 << 13)) >> 14;
+    int t10a = (IN(10) *  7723 - IN(22)  * 14449 + (1 << 13)) >> 14;
+    int t13a = (IN(10) * 14449 + IN(22)  *  7723 + (1 << 13)) >> 14;
+    int t11a = (IN(26) * 15679 - IN(6)   *  4756 + (1 << 13)) >> 14;
+    int t12a = (IN(26) *  4756 + IN(6)   * 15679 + (1 << 13)) >> 14;
+    int t16a = (IN(1)  *   804 - IN(31)  * 16364 + (1 << 13)) >> 14;
+    int t31a = (IN(1)  * 16364 + IN(31)  *   804 + (1 << 13)) >> 14;
+    int t17a = (IN(17) * 12140 - IN(15)  * 11003 + (1 << 13)) >> 14;
+    int t30a = (IN(17) * 11003 + IN(15)  * 12140 + (1 << 13)) >> 14;
+    int t18a = (IN(9)  *  7005 - IN(23)  * 14811 + (1 << 13)) >> 14;
+    int t29a = (IN(9)  * 14811 + IN(23)  *  7005 + (1 << 13)) >> 14;
+    int t19a = (IN(25) * 15426 - IN(7)   *  5520 + (1 << 13)) >> 14;
+    int t28a = (IN(25) *  5520 + IN(7)   * 15426 + (1 << 13)) >> 14;
+    int t20a = (IN(5)  *  3981 - IN(27)  * 15893 + (1 << 13)) >> 14;
+    int t27a = (IN(5)  * 15893 + IN(27)  *  3981 + (1 << 13)) >> 14;
+    int t21a = (IN(21) * 14053 - IN(11)  *  8423 + (1 << 13)) >> 14;
+    int t26a = (IN(21) *  8423 + IN(11)  * 14053 + (1 << 13)) >> 14;
+    int t22a = (IN(13) *  9760 - IN(19)  * 13160 + (1 << 13)) >> 14;
+    int t25a = (IN(13) * 13160 + IN(19)  *  9760 + (1 << 13)) >> 14;
+    int t23a = (IN(29) * 16207 - IN(3)   *  2404 + (1 << 13)) >> 14;
+    int t24a = (IN(29) *  2404 + IN(3)   * 16207 + (1 << 13)) >> 14;
+
+    int t0  = t0a  + t3a;
+    int t1  = t1a  + t2a;
+    int t2  = t1a  - t2a;
+    int t3  = t0a  - t3a;
+    int t4  = t4a  + t5a;
+    int t5  = t4a  - t5a;
+    int t6  = t7a  - t6a;
+    int t7  = t7a  + t6a;
+    int t8  = t8a  + t9a;
+    int t9  = t8a  - t9a;
+    int t10 = t11a - t10a;
+    int t11 = t11a + t10a;
+    int t12 = t12a + t13a;
+    int t13 = t12a - t13a;
+    int t14 = t15a - t14a;
+    int t15 = t15a + t14a;
+    int t16 = t16a + t17a;
+    int t17 = t16a - t17a;
+    int t18 = t19a - t18a;
+    int t19 = t19a + t18a;
+    int t20 = t20a + t21a;
+    int t21 = t20a - t21a;
+    int t22 = t23a - t22a;
+    int t23 = t23a + t22a;
+    int t24 = t24a + t25a;
+    int t25 = t24a - t25a;
+    int t26 = t27a - t26a;
+    int t27 = t27a + t26a;
+    int t28 = t28a + t29a;
+    int t29 = t28a - t29a;
+    int t30 = t31a - t30a;
+    int t31 = t31a + t30a;
+
+    t5a  =   ((t6         - t5) * 11585  + (1 << 13)) >> 14;
+    t6a  =   ((t6         + t5) * 11585  + (1 << 13)) >> 14;
+    t9a  =   (t14 *  6270 - t9  * 15137  + (1 << 13)) >> 14;
+    t14a =   (t14 * 15137 + t9  *  6270  + (1 << 13)) >> 14;
+    t10a = (-(t13 * 15137 + t10 *  6270) + (1 << 13)) >> 14;
+    t13a =   (t13 *  6270 - t10 * 15137  + (1 << 13)) >> 14;
+    t17a =   (t30 *  3196 - t17 * 16069  + (1 << 13)) >> 14;
+    t30a =   (t30 * 16069 + t17 *  3196  + (1 << 13)) >> 14;
+    t18a = (-(t29 * 16069 + t18 *  3196) + (1 << 13)) >> 14;
+    t29a =   (t29 *  3196 - t18 * 16069  + (1 << 13)) >> 14;
+    t21a =   (t26 * 13623 - t21 *  9102  + (1 << 13)) >> 14;
+    t26a =   (t26 *  9102 + t21 * 13623  + (1 << 13)) >> 14;
+    t22a = (-(t25 *  9102 + t22 * 13623) + (1 << 13)) >> 14;
+    t25a =   (t25 * 13623 - t22 *  9102  + (1 << 13)) >> 14;
+
+    t0a  = t0   + t7;
+    t1a  = t1   + t6a;
+    t2a  = t2   + t5a;
+    t3a  = t3   + t4;
+    t4a  = t3   - t4;
+    t5   = t2   - t5a;
+    t6   = t1   - t6a;
+    t7a  = t0   - t7;
+    t8a  = t8   + t11;
+    t9   = t9a  + t10a;
+    t10  = t9a  - t10a;
+    t11a = t8   - t11;
+    t12a = t15  - t12;
+    t13  = t14a - t13a;
+    t14  = t14a + t13a;
+    t15a = t15  + t12;
+    t16a = t16  + t19;
+    t17  = t17a + t18a;
+    t18  = t17a - t18a;
+    t19a = t16  - t19;
+    t20a = t23  - t20;
+    t21  = t22a - t21a;
+    t22  = t22a + t21a;
+    t23a = t23  + t20;
+    t24a = t24  + t27;
+    t25  = t25a + t26a;
+    t26  = t25a - t26a;
+    t27a = t24  - t27;
+    t28a = t31  - t28;
+    t29  = t30a - t29a;
+    t30  = t30a + t29a;
+    t31a = t31  + t28;
+
+    t10a = ((t13           - t10)  * 11585  + (1 << 13)) >> 14;
+    t13a = ((t13           + t10)  * 11585  + (1 << 13)) >> 14;
+    t11  = ((t12a          - t11a) * 11585  + (1 << 13)) >> 14;
+    t12  = ((t12a          + t11a) * 11585  + (1 << 13)) >> 14;
+    t18a =   (t29  *  6270 - t18   * 15137  + (1 << 13)) >> 14;
+    t29a =   (t29  * 15137 + t18   *  6270  + (1 << 13)) >> 14;
+    t19  =   (t28a *  6270 - t19a  * 15137  + (1 << 13)) >> 14;
+    t28  =   (t28a * 15137 + t19a  *  6270  + (1 << 13)) >> 14;
+    t20  = (-(t27a * 15137 + t20a  *  6270) + (1 << 13)) >> 14;
+    t27  =   (t27a *  6270 - t20a  * 15137  + (1 << 13)) >> 14;
+    t21a = (-(t26  * 15137 + t21   *  6270) + (1 << 13)) >> 14;
+    t26a =   (t26  *  6270 - t21   * 15137  + (1 << 13)) >> 14;
+
+    t0   = t0a  + t15a;
+    t1   = t1a  + t14;
+    t2   = t2a  + t13a;
+    t3   = t3a  + t12;
+    t4   = t4a  + t11;
+    t5a  = t5   + t10a;
+    t6a  = t6   + t9;
+    t7   = t7a  + t8a;
+    t8   = t7a  - t8a;
+    t9a  = t6   - t9;
+    t10  = t5   - t10a;
+    t11a = t4a  - t11;
+    t12a = t3a  - t12;
+    t13  = t2a  - t13a;
+    t14a = t1a  - t14;
+    t15  = t0a  - t15a;
+    t16  = t16a + t23a;
+    t17a = t17  + t22;
+    t18  = t18a + t21a;
+    t19a = t19  + t20;
+    t20a = t19  - t20;
+    t21  = t18a - t21a;
+    t22a = t17  - t22;
+    t23  = t16a - t23a;
+    t24  = t31a - t24a;
+    t25a = t30  - t25;
+    t26  = t29a - t26a;
+    t27a = t28  - t27;
+    t28a = t28  + t27;
+    t29  = t29a + t26a;
+    t30a = t30  + t25;
+    t31  = t31a + t24a;
+
+    t20  = ((t27a - t20a) * 11585 + (1 << 13)) >> 14;
+    t27  = ((t27a + t20a) * 11585 + (1 << 13)) >> 14;
+    t21a = ((t26  - t21)  * 11585 + (1 << 13)) >> 14;
+    t26a = ((t26  + t21)  * 11585 + (1 << 13)) >> 14;
+    t22  = ((t25a - t22a) * 11585 + (1 << 13)) >> 14;
+    t25  = ((t25a + t22a) * 11585 + (1 << 13)) >> 14;
+    t23a = ((t24  - t23)  * 11585 + (1 << 13)) >> 14;
+    t24a = ((t24  + t23)  * 11585 + (1 << 13)) >> 14;
+
+    out[0]  = t0   + t31;
+    out[1]  = t1   + t30a;
+    out[2]  = t2   + t29;
+    out[3]  = t3   + t28a;
+    out[4]  = t4   + t27;
+    out[5]  = t5a  + t26a;
+    out[6]  = t6a  + t25;
+    out[7]  = t7   + t24a;
+    out[8]  = t8   + t23a;
+    out[9]  = t9a  + t22;
+    out[10] = t10  + t21a;
+    out[11] = t11a + t20;
+    out[12] = t12a + t19a;
+    out[13] = t13  + t18;
+    out[14] = t14a + t17a;
+    out[15] = t15  + t16;
+    out[16] = t15  - t16;
+    out[17] = t14a - t17a;
+    out[18] = t13  - t18;
+    out[19] = t12a - t19a;
+    out[20] = t11a - t20;
+    out[21] = t10  - t21a;
+    out[22] = t9a  - t22;
+    out[23] = t8   - t23a;
+    out[24] = t7   - t24a;
+    out[25] = t6a  - t25;
+    out[26] = t5a  - t26a;
+    out[27] = t4   - t27;
+    out[28] = t3   - t28a;
+    out[29] = t2   - t29;
+    out[30] = t1   - t30a;
+    out[31] = t0   - t31;
+}
+
+itxfm_wrapper(idct, idct, 32, 6)
+
+static av_always_inline void iwht4_1d(int16_t *out, const int16_t *in,
+                                      ptrdiff_t stride, int pass)
+{
+    int t0, t1, t2, t3, t4;
+
+    if (pass == 0) {
+        t0 = IN(0) >> 2;
+        t1 = IN(3) >> 2;
+        t2 = IN(1) >> 2;
+        t3 = IN(2) >> 2;
+    } else {
+        t0 = IN(0);
+        t1 = IN(3);
+        t2 = IN(1);
+        t3 = IN(2);
+    }
+
+    t0 += t2;
+    t3 -= t1;
+    t4 = (t0 - t3) >> 1;
+    t1 = t4 - t1;
+    t2 = t4 - t2;
+    t0 -= t1;
+    t3 += t2;
+
+    out[0] = t0;
+    out[1] = t1;
+    out[2] = t2;
+    out[3] = t3;
+}
+
+itxfm_wrapper(iwht, iwht, 4, 0)
+
+#undef IN
+#undef itxfm_wrapper
+#undef itxfm_wrap
+
+static av_cold void vp9dsp_itxfm_init(VP9DSPContext *dsp)
+{
+#define init_itxfm(tx, sz)                                        \
+    dsp->itxfm_add[tx][DCT_DCT]   = idct_idct_   ## sz ## _add_c; \
+    dsp->itxfm_add[tx][DCT_ADST]  = iadst_idct_  ## sz ## _add_c; \
+    dsp->itxfm_add[tx][ADST_DCT]  = idct_iadst_  ## sz ## _add_c; \
+    dsp->itxfm_add[tx][ADST_ADST] = iadst_iadst_ ## sz ## _add_c
+
+#define init_idct(tx, nm)                               \
+    dsp->itxfm_add[tx][DCT_DCT]   =                     \
+    dsp->itxfm_add[tx][ADST_DCT]  =                     \
+    dsp->itxfm_add[tx][DCT_ADST]  =                     \
+    dsp->itxfm_add[tx][ADST_ADST] = nm ## _add_c
+
+    init_itxfm(TX_4X4, 4x4);
+    init_itxfm(TX_8X8, 8x8);
+    init_itxfm(TX_16X16, 16x16);
+    init_idct(TX_32X32, idct_idct_32x32);
+    init_idct(4 /* lossless */, iwht_iwht_4x4);
+
+#undef init_itxfm
+#undef init_idct
+}
+
+static av_always_inline void loop_filter(uint8_t *dst, ptrdiff_t stride,
+                                         int E, int I, int H,
+                                         ptrdiff_t stridea, ptrdiff_t strideb,
+                                         int wd)
+{
+    int i;
+
+    for (i = 0; i < 8; i++, dst += stridea) {
+        int p7, p6, p5, p4;
+        int p3 = dst[strideb * -4], p2 = dst[strideb * -3];
+        int p1 = dst[strideb * -2], p0 = dst[strideb * -1];
+        int q0 = dst[strideb * +0], q1 = dst[strideb * +1];
+        int q2 = dst[strideb * +2], q3 = dst[strideb * +3];
+        int q4, q5, q6, q7;
+        int fm = FFABS(p3 - p2) <= I && FFABS(p2 - p1) <= I &&
+                 FFABS(p1 - p0) <= I && FFABS(q1 - q0) <= I &&
+                 FFABS(q2 - q1) <= I && FFABS(q3 - q2) <= I &&
+                 FFABS(p0 - q0) * 2 + (FFABS(p1 - q1) >> 1) <= E;
+        int flat8out, flat8in;
+
+        if (!fm)
+            continue;
+
+        if (wd >= 16) {
+            p7 = dst[strideb * -8];
+            p6 = dst[strideb * -7];
+            p5 = dst[strideb * -6];
+            p4 = dst[strideb * -5];
+            q4 = dst[strideb * +4];
+            q5 = dst[strideb * +5];
+            q6 = dst[strideb * +6];
+            q7 = dst[strideb * +7];
+
+            flat8out = FFABS(p7 - p0) <= 1 && FFABS(p6 - p0) <= 1 &&
+                       FFABS(p5 - p0) <= 1 && FFABS(p4 - p0) <= 1 &&
+                       FFABS(q4 - q0) <= 1 && FFABS(q5 - q0) <= 1 &&
+                       FFABS(q6 - q0) <= 1 && FFABS(q7 - q0) <= 1;
+        }
+
+        if (wd >= 8)
+            flat8in = FFABS(p3 - p0) <= 1 && FFABS(p2 - p0) <= 1 &&
+                      FFABS(p1 - p0) <= 1 && FFABS(q1 - q0) <= 1 &&
+                      FFABS(q2 - q0) <= 1 && FFABS(q3 - q0) <= 1;
+
+        if (wd >= 16 && flat8out && flat8in) {
+            dst[strideb * -7] = (p7 + p7 + p7 + p7 + p7 + p7 + p7 + p6 * 2 +
+                                 p5 + p4 + p3 + p2 + p1 + p0 + q0 + 8) >> 4;
+            dst[strideb * -6] = (p7 + p7 + p7 + p7 + p7 + p7 + p6 + p5 * 2 +
+                                 p4 + p3 + p2 + p1 + p0 + q0 + q1 + 8) >> 4;
+            dst[strideb * -5] = (p7 + p7 + p7 + p7 + p7 + p6 + p5 + p4 * 2 +
+                                 p3 + p2 + p1 + p0 + q0 + q1 + q2 + 8) >> 4;
+            dst[strideb * -4] = (p7 + p7 + p7 + p7 + p6 + p5 + p4 + p3 * 2 +
+                                 p2 + p1 + p0 + q0 + q1 + q2 + q3 + 8) >> 4;
+            dst[strideb * -3] = (p7 + p7 + p7 + p6 + p5 + p4 + p3 + p2 * 2 +
+                                 p1 + p0 + q0 + q1 + q2 + q3 + q4 + 8) >> 4;
+            dst[strideb * -2] = (p7 + p7 + p6 + p5 + p4 + p3 + p2 + p1 * 2 +
+                                 p0 + q0 + q1 + q2 + q3 + q4 + q5 + 8) >> 4;
+            dst[strideb * -1] = (p7 + p6 + p5 + p4 + p3 + p2 + p1 + p0 * 2 +
+                                 q0 + q1 + q2 + q3 + q4 + q5 + q6 + 8) >> 4;
+            dst[strideb * +0] = (p6 + p5 + p4 + p3 + p2 + p1 + p0 + q0 * 2 +
+                                 q1 + q2 + q3 + q4 + q5 + q6 + q7 + 8) >> 4;
+            dst[strideb * +1] = (p5 + p4 + p3 + p2 + p1 + p0 + q0 + q1 * 2 +
+                                 q2 + q3 + q4 + q5 + q6 + q7 + q7 + 8) >> 4;
+            dst[strideb * +2] = (p4 + p3 + p2 + p1 + p0 + q0 + q1 + q2 * 2 +
+                                 q3 + q4 + q5 + q6 + q7 + q7 + q7 + 8) >> 4;
+            dst[strideb * +3] = (p3 + p2 + p1 + p0 + q0 + q1 + q2 + q3 * 2 +
+                                 q4 + q5 + q6 + q7 + q7 + q7 + q7 + 8) >> 4;
+            dst[strideb * +4] = (p2 + p1 + p0 + q0 + q1 + q2 + q3 + q4 * 2 +
+                                 q5 + q6 + q7 + q7 + q7 + q7 + q7 + 8) >> 4;
+            dst[strideb * +5] = (p1 + p0 + q0 + q1 + q2 + q3 + q4 + q5 * 2 +
+                                 q6 + q7 + q7 + q7 + q7 + q7 + q7 + 8) >> 4;
+            dst[strideb * +6] = (p0 + q0 + q1 + q2 + q3 + q4 + q5 + q6 * 2 +
+                                 q7 + q7 + q7 + q7 + q7 + q7 + q7 + 8) >> 4;
+        } else if (wd >= 8 && flat8in) {
+            dst[strideb * -3] = (p3 + p3 + p3 + 2 * p2 + p1 + p0 + q0 + 4) >> 3;
+            dst[strideb * -2] = (p3 + p3 + p2 + 2 * p1 + p0 + q0 + q1 + 4) >> 3;
+            dst[strideb * -1] = (p3 + p2 + p1 + 2 * p0 + q0 + q1 + q2 + 4) >> 3;
+            dst[strideb * +0] = (p2 + p1 + p0 + 2 * q0 + q1 + q2 + q3 + 4) >> 3;
+            dst[strideb * +1] = (p1 + p0 + q0 + 2 * q1 + q2 + q3 + q3 + 4) >> 3;
+            dst[strideb * +2] = (p0 + q0 + q1 + 2 * q2 + q3 + q3 + q3 + 4) >> 3;
+        } else {
+            int hev = FFABS(p1 - p0) > H || FFABS(q1 - q0) > H;
+
+            if (hev) {
+                int f = av_clip_int8(3 * (q0 - p0) + av_clip_int8(p1 - q1));
+                int f1 = FFMIN(f + 4, 127) >> 3;
+                int f2 = FFMIN(f + 3, 127) >> 3;
+
+                dst[strideb * -1] = av_clip_uint8(p0 + f2);
+                dst[strideb * +0] = av_clip_uint8(q0 - f1);
+            } else {
+                int f = av_clip_int8(3 * (q0 - p0));
+                int f1 = FFMIN(f + 4, 127) >> 3;
+                int f2 = FFMIN(f + 3, 127) >> 3;
+
+                dst[strideb * -1] = av_clip_uint8(p0 + f2);
+                dst[strideb * +0] = av_clip_uint8(q0 - f1);
+
+                f = (f1 + 1) >> 1;
+                dst[strideb * -2] = av_clip_uint8(p1 + f);
+                dst[strideb * +1] = av_clip_uint8(q1 - f);
+            }
+        }
+    }
+}
+
+#define lf_8_fn(dir, wd, stridea, strideb)                                  \
+static void loop_filter_ ## dir ## _ ## wd  ## _8_c(uint8_t *dst,           \
+                                                    ptrdiff_t stride,       \
+                                                    int E, int I, int H)    \
+{                                                                           \
+    loop_filter(dst, stride, E, I, H, stridea, strideb, wd);                \
+}
+
+#define lf_8_fns(wd)          \
+    lf_8_fn(h, wd, stride, 1) \
+    lf_8_fn(v, wd, 1, stride)
+
+lf_8_fns(4)
+lf_8_fns(8)
+lf_8_fns(16)
+
+#undef lf_8_fn
+#undef lf_8_fns
+
+#define lf_16_fn(dir, stridea)                                          \
+static void loop_filter_ ## dir ## _16_16_c(uint8_t *dst,               \
+                                            ptrdiff_t stride,           \
+                                            int E, int I, int H)        \
+{                                                                       \
+    loop_filter_ ## dir ## _16_8_c(dst, stride, E, I, H);               \
+    loop_filter_ ## dir ## _16_8_c(dst + 8 * stridea, stride, E, I, H); \
+}
+
+lf_16_fn(h, stride)
+lf_16_fn(v, 1)
+
+#undef lf_16_fn
+
+#define lf_mix_fn(dir, wd1, wd2, stridea)                                     \
+static void loop_filter_ ## dir ## _ ## wd1 ## wd2 ## _16_c(uint8_t *dst,     \
+                                                            ptrdiff_t stride, \
+                                                            int E, int I,     \
+                                                            int H)            \
+{                                                                             \
+    loop_filter_ ## dir ## _ ## wd1 ## _8_c(dst, stride, E & 0xff,            \
+                                            I & 0xff, H & 0xff);              \
+    loop_filter_ ## dir ## _ ## wd2 ## _8_c(dst + 8 * stridea, stride,        \
+                                            E >> 8, I >> 8, H >> 8);          \
+}
+
+#define lf_mix_fns(wd1, wd2)       \
+    lf_mix_fn(h, wd1, wd2, stride) \
+    lf_mix_fn(v, wd1, wd2, 1)
+
+lf_mix_fns(4, 4)
+lf_mix_fns(4, 8)
+lf_mix_fns(8, 4)
+lf_mix_fns(8, 8)
+
+#undef lf_mix_fn
+#undef lf_mix_fns
+
+static av_cold void vp9dsp_loopfilter_init(VP9DSPContext *dsp)
+{
+    dsp->loop_filter_8[0][0] = loop_filter_h_4_8_c;
+    dsp->loop_filter_8[0][1] = loop_filter_v_4_8_c;
+    dsp->loop_filter_8[1][0] = loop_filter_h_8_8_c;
+    dsp->loop_filter_8[1][1] = loop_filter_v_8_8_c;
+    dsp->loop_filter_8[2][0] = loop_filter_h_16_8_c;
+    dsp->loop_filter_8[2][1] = loop_filter_v_16_8_c;
+
+    dsp->loop_filter_16[0] = loop_filter_h_16_16_c;
+    dsp->loop_filter_16[1] = loop_filter_v_16_16_c;
+
+    dsp->loop_filter_mix2[0][0][0] = loop_filter_h_44_16_c;
+    dsp->loop_filter_mix2[0][0][1] = loop_filter_v_44_16_c;
+    dsp->loop_filter_mix2[0][1][0] = loop_filter_h_48_16_c;
+    dsp->loop_filter_mix2[0][1][1] = loop_filter_v_48_16_c;
+    dsp->loop_filter_mix2[1][0][0] = loop_filter_h_84_16_c;
+    dsp->loop_filter_mix2[1][0][1] = loop_filter_v_84_16_c;
+    dsp->loop_filter_mix2[1][1][0] = loop_filter_h_88_16_c;
+    dsp->loop_filter_mix2[1][1][1] = loop_filter_v_88_16_c;
+}
+
+static av_always_inline void copy_c(uint8_t *dst, const uint8_t *src,
+                                    ptrdiff_t dst_stride,
+                                    ptrdiff_t src_stride,
+                                    int w, int h)
+{
+    do {
+        memcpy(dst, src, w);
+
+        dst += dst_stride;
+        src += src_stride;
+    } while (--h);
+}
+
+static av_always_inline void avg_c(uint8_t *dst, const uint8_t *src,
+                                   ptrdiff_t dst_stride,
+                                   ptrdiff_t src_stride,
+                                   int w, int h)
+{
+    do {
+        int x;
+
+        for (x = 0; x < w; x += 4)
+            AV_WN32A(&dst[x], rnd_avg32(AV_RN32A(&dst[x]), AV_RN32(&src[x])));
+
+        dst += dst_stride;
+        src += src_stride;
+    } while (--h);
+}
+
+#define fpel_fn(type, sz)                                      \
+static void type ## sz ## _c(uint8_t *dst, const uint8_t *src, \
+                             ptrdiff_t dst_stride,             \
+                             ptrdiff_t src_stride,             \
+                             int h, int mx, int my)            \
+{                                                              \
+    type ## _c(dst, src, dst_stride, src_stride, sz, h);       \
+}
+
+#define copy_avg_fn(sz) \
+    fpel_fn(copy, sz)   \
+    fpel_fn(avg, sz)
+
+copy_avg_fn(64)
+copy_avg_fn(32)
+copy_avg_fn(16)
+copy_avg_fn(8)
+copy_avg_fn(4)
+
+#undef fpel_fn
+#undef copy_avg_fn
+
+static const int8_t vp9_subpel_filters[3][15][8] = {
+    [FILTER_8TAP_REGULAR] = {
+        {  0,  1,  -5, 126,   8,  -3,  1,  0 },
+        { -1,  3, -10, 122,  18,  -6,  2,  0 },
+        { -1,  4, -13, 118,  27,  -9,  3, -1 },
+        { -1,  4, -16, 112,  37, -11,  4, -1 },
+        { -1,  5, -18, 105,  48, -14,  4, -1 },
+        { -1,  5, -19,  97,  58, -16,  5, -1 },
+        { -1,  6, -19,  88,  68, -18,  5, -1 },
+        { -1,  6, -19,  78,  78, -19,  6, -1 },
+        { -1,  5, -18,  68,  88, -19,  6, -1 },
+        { -1,  5, -16,  58,  97, -19,  5, -1 },
+        { -1,  4, -14,  48, 105, -18,  5, -1 },
+        { -1,  4, -11,  37, 112, -16,  4, -1 },
+        { -1,  3,  -9,  27, 118, -13,  4, -1 },
+        {  0,  2,  -6,  18, 122, -10,  3, -1 },
+        {  0,  1,  -3,   8, 126,  -5,  1,  0 },
+    }, [FILTER_8TAP_SHARP] = {
+        { -1,  3,  -7, 127,   8,  -3,  1,  0 },
+        { -2,  5, -13, 125,  17,  -6,  3, -1 },
+        { -3,  7, -17, 121,  27, -10,  5, -2 },
+        { -4,  9, -20, 115,  37, -13,  6, -2 },
+        { -4, 10, -23, 108,  48, -16,  8, -3 },
+        { -4, 10, -24, 100,  59, -19,  9, -3 },
+        { -4, 11, -24,  90,  70, -21, 10, -4 },
+        { -4, 11, -23,  80,  80, -23, 11, -4 },
+        { -4, 10, -21,  70,  90, -24, 11, -4 },
+        { -3,  9, -19,  59, 100, -24, 10, -4 },
+        { -3,  8, -16,  48, 108, -23, 10, -4 },
+        { -2,  6, -13,  37, 115, -20,  9, -4 },
+        { -2,  5, -10,  27, 121, -17,  7, -3 },
+        { -1,  3,  -6,  17, 125, -13,  5, -2 },
+        {  0,  1,  -3,   8, 127,  -7,  3, -1 },
+    }, [FILTER_8TAP_SMOOTH] = {
+        { -3, -1,  32,  64,  38,   1, -3,  0 },
+        { -2, -2,  29,  63,  41,   2, -3,  0 },
+        { -2, -2,  26,  63,  43,   4, -4,  0 },
+        { -2, -3,  24,  62,  46,   5, -4,  0 },
+        { -2, -3,  21,  60,  49,   7, -4,  0 },
+        { -1, -4,  18,  59,  51,   9, -4,  0 },
+        { -1, -4,  16,  57,  53,  12, -4, -1 },
+        { -1, -4,  14,  55,  55,  14, -4, -1 },
+        { -1, -4,  12,  53,  57,  16, -4, -1 },
+        {  0, -4,   9,  51,  59,  18, -4, -1 },
+        {  0, -4,   7,  49,  60,  21, -3, -2 },
+        {  0, -4,   5,  46,  62,  24, -3, -2 },
+        {  0, -4,   4,  43,  63,  26, -2, -2 },
+        {  0, -3,   2,  41,  63,  29, -2, -2 },
+        {  0, -3,   1,  38,  64,  32, -1, -3 },
+    }
+};
+
+#define FILTER_8TAP(src, x, F, stride)              \
+    av_clip_uint8((F[0] * src[x + -3 * stride] +    \
+                   F[1] * src[x + -2 * stride] +    \
+                   F[2] * src[x + -1 * stride] +    \
+                   F[3] * src[x + +0 * stride] +    \
+                   F[4] * src[x + +1 * stride] +    \
+                   F[5] * src[x + +2 * stride] +    \
+                   F[6] * src[x + +3 * stride] +    \
+                   F[7] * src[x + +4 * stride] + 64) >> 7)
+
+static av_always_inline void do_8tap_1d_c(uint8_t *dst, const uint8_t *src,
+                                          ptrdiff_t dst_stride,
+                                          ptrdiff_t src_stride,
+                                          int w, int h, ptrdiff_t ds,
+                                          const int8_t *filter, int avg)
+{
+    do {
+        int x;
+
+        for (x = 0; x < w; x++)
+            if (avg)
+                dst[x] = (dst[x] + FILTER_8TAP(src, x, filter, ds) + 1) >> 1;
+            else
+                dst[x] = FILTER_8TAP(src, x, filter, ds);
+
+        dst += dst_stride;
+        src += src_stride;
+    } while (--h);
+}
+
+#define filter_8tap_1d_fn(opn, opa, dir, ds)                                \
+static av_noinline void opn ## _8tap_1d_ ## dir ## _c(uint8_t *dst,         \
+                                                      const uint8_t *src,   \
+                                                      ptrdiff_t dst_stride, \
+                                                      ptrdiff_t src_stride, \
+                                                      int w, int h,         \
+                                                      const int8_t *filter) \
+{                                                                           \
+    do_8tap_1d_c(dst, src, dst_stride, src_stride, w, h, ds, filter, opa);  \
+}
+
+filter_8tap_1d_fn(put, 0, v, src_stride)
+filter_8tap_1d_fn(put, 0, h, 1)
+filter_8tap_1d_fn(avg, 1, v, src_stride)
+filter_8tap_1d_fn(avg, 1, h, 1)
+
+#undef filter_8tap_1d_fn
+
+static av_always_inline void do_8tap_2d_c(uint8_t *dst, const uint8_t *src,
+                                          ptrdiff_t dst_stride,
+                                          ptrdiff_t src_stride,
+                                          int w, int h, const int8_t *filterx,
+                                          const int8_t *filtery, int avg)
+{
+    int tmp_h = h + 7;
+    uint8_t tmp[64 * 71], *tmp_ptr = tmp;
+
+    src -= src_stride * 3;
+    do {
+        int x;
+
+        for (x = 0; x < w; x++)
+            tmp_ptr[x] = FILTER_8TAP(src, x, filterx, 1);
+
+        tmp_ptr += 64;
+        src     += src_stride;
+    } while (--tmp_h);
+
+    tmp_ptr = tmp + 64 * 3;
+    do {
+        int x;
+
+        for (x = 0; x < w; x++)
+            if (avg)
+                dst[x] = (dst[x] + FILTER_8TAP(tmp_ptr, x, filtery, 64) + 1) >> 1;
+            else
+                dst[x] = FILTER_8TAP(tmp_ptr, x, filtery, 64);
+
+        tmp_ptr += 64;
+        dst += dst_stride;
+    } while (--h);
+}
+
+#define filter_8tap_2d_fn(opn, opa)                                     \
+static av_noinline void opn ## _8tap_2d_hv_c(uint8_t *dst,              \
+                                             const uint8_t *src,        \
+                                             ptrdiff_t dst_stride,      \
+                                             ptrdiff_t src_stride,      \
+                                             int w, int h,              \
+                                             const int8_t *filterx,     \
+                                             const int8_t *filtery)     \
+{                                                                       \
+    do_8tap_2d_c(dst, src, dst_stride, src_stride,                      \
+                 w, h, filterx, filtery, opa);                          \
+}
+
+filter_8tap_2d_fn(put, 0)
+filter_8tap_2d_fn(avg, 1)
+
+#undef filter_8tap_2d_fn
+
+#undef FILTER_8TAP
+
+#define filter_fn_1d(sz, dir, dir_m, type, type_idx, avg)                   \
+static void                                                                 \
+avg ## _8tap_ ## type ## _ ## sz ## dir ## _c(uint8_t *dst,                 \
+                                              const uint8_t *src,           \
+                                              ptrdiff_t dst_stride,         \
+                                              ptrdiff_t src_stride,         \
+                                              int h, int mx, int my)        \
+{                                                                           \
+    avg ## _8tap_1d_ ## dir ## _c(dst, src, dst_stride, src_stride, sz, h,  \
+                                  vp9_subpel_filters[type_idx][dir_m - 1]); \
+}
+
+#define filter_fn_2d(sz, type, type_idx, avg)                               \
+static void avg ## _8tap_ ## type ## _ ## sz ## hv_c(uint8_t *dst,          \
+                                                     const uint8_t *src,    \
+                                                     ptrdiff_t dst_stride,  \
+                                                     ptrdiff_t src_stride,  \
+                                                     int h, int mx, int my) \
+{                                                                           \
+    avg ## _8tap_2d_hv_c(dst, src, dst_stride, src_stride, sz, h,           \
+                         vp9_subpel_filters[type_idx][mx - 1],              \
+                         vp9_subpel_filters[type_idx][my - 1]);             \
+}
+
+#define FILTER_BILIN(src, x, mxy, stride)                       \
+    (src[x] + ((mxy * (src[x + stride] - src[x]) + 8) >> 4))
+
+static av_always_inline void do_bilin_1d_c(uint8_t *dst,
+                                           const uint8_t *src,
+                                           ptrdiff_t dst_stride,
+                                           ptrdiff_t src_stride,
+                                           int w, int h, ptrdiff_t ds,
+                                           int mxy, int avg)
+{
+    do {
+        int x;
+
+        for (x = 0; x < w; x++)
+            if (avg)
+                dst[x] = (dst[x] + FILTER_BILIN(src, x, mxy, ds) + 1) >> 1;
+            else
+                dst[x] = FILTER_BILIN(src, x, mxy, ds);
+
+        dst += dst_stride;
+        src += src_stride;
+    } while (--h);
+}
+
+#define bilin_1d_fn(opn, opa, dir, ds)                                        \
+static av_noinline void opn ## _bilin_1d_ ## dir ## _c(uint8_t *dst,          \
+                                                       const uint8_t *src,    \
+                                                       ptrdiff_t dst_stride,  \
+                                                       ptrdiff_t src_stride,  \
+                                                       int w, int h, int mxy) \
+{                                                                             \
+    do_bilin_1d_c(dst, src, dst_stride, src_stride, w, h, ds, mxy, opa);      \
+}
+
+bilin_1d_fn(put, 0, v, src_stride)
+bilin_1d_fn(put, 0, h, 1)
+bilin_1d_fn(avg, 1, v, src_stride)
+bilin_1d_fn(avg, 1, h, 1)
+
+#undef bilin_1d_fn
+
+static av_always_inline void do_bilin_2d_c(uint8_t *dst,
+                                           const uint8_t *src,
+                                           ptrdiff_t dst_stride,
+                                           ptrdiff_t src_stride,
+                                           int w, int h, int mx, int my,
+                                           int avg)
+{
+    uint8_t tmp[64 * 65], *tmp_ptr = tmp;
+    int tmp_h = h + 1;
+
+    do {
+        int x;
+
+        for (x = 0; x < w; x++)
+            tmp_ptr[x] = FILTER_BILIN(src, x, mx, 1);
+
+        tmp_ptr += 64;
+        src     += src_stride;
+    } while (--tmp_h);
+
+    tmp_ptr = tmp;
+    do {
+        int x;
+
+        for (x = 0; x < w; x++)
+            if (avg)
+                dst[x] = (dst[x] + FILTER_BILIN(tmp_ptr, x, my, 64) + 1) >> 1;
+            else
+                dst[x] = FILTER_BILIN(tmp_ptr, x, my, 64);
+
+        tmp_ptr += 64;
+        dst += dst_stride;
+    } while (--h);
+}
+
+#define bilin_2d_fn(opn, opa)                                           \
+static av_noinline void opn ## _bilin_2d_hv_c(uint8_t *dst,             \
+                                              const uint8_t *src,       \
+                                              ptrdiff_t dst_stride,     \
+                                              ptrdiff_t src_stride,     \
+                                              int w, int h,             \
+                                              int mx, int my)           \
+{                                                                       \
+    do_bilin_2d_c(dst, src, dst_stride, src_stride, w, h, mx, my, opa); \
+}
+
+bilin_2d_fn(put, 0)
+bilin_2d_fn(avg, 1)
+
+#undef bilin_2d_fn
+
+#undef FILTER_BILIN
+
+#define bilinf_fn_1d(sz, dir, dir_m, avg)                               \
+static void avg ## _bilin_ ## sz ## dir ## _c(uint8_t *dst,             \
+                                              const uint8_t *src,       \
+                                              ptrdiff_t dst_stride,     \
+                                              ptrdiff_t src_stride,     \
+                                              int h, int mx, int my)    \
+{                                                                       \
+    avg ## _bilin_1d_ ## dir ## _c(dst, src, dst_stride, src_stride,    \
+                                   sz, h, dir_m);                       \
+}
+
+#define bilinf_fn_2d(sz, avg)                                        \
+static void avg ## _bilin_ ## sz ## hv_c(uint8_t *dst,               \
+                                         const uint8_t *src,         \
+                                         ptrdiff_t dst_stride,       \
+                                         ptrdiff_t src_stride,       \
+                                         int h, int mx, int my)      \
+{                                                                    \
+    avg ## _bilin_2d_hv_c(dst, src, dst_stride, src_stride,          \
+                          sz, h, mx, my);                            \
+}
+
+#define filter_fn(sz, avg)                                     \
+    filter_fn_1d(sz, h, mx, regular, FILTER_8TAP_REGULAR, avg) \
+    filter_fn_1d(sz, v, my, regular, FILTER_8TAP_REGULAR, avg) \
+    filter_fn_2d(sz, regular, FILTER_8TAP_REGULAR, avg)        \
+    filter_fn_1d(sz, h, mx, smooth, FILTER_8TAP_SMOOTH, avg)   \
+    filter_fn_1d(sz, v, my, smooth, FILTER_8TAP_SMOOTH, avg)   \
+    filter_fn_2d(sz, smooth, FILTER_8TAP_SMOOTH, avg)          \
+    filter_fn_1d(sz, h, mx, sharp, FILTER_8TAP_SHARP, avg)     \
+    filter_fn_1d(sz, v, my, sharp, FILTER_8TAP_SHARP, avg)     \
+    filter_fn_2d(sz, sharp, FILTER_8TAP_SHARP, avg)            \
+    bilinf_fn_1d(sz, h, mx, avg)                               \
+    bilinf_fn_1d(sz, v, my, avg)                               \
+    bilinf_fn_2d(sz, avg)
+
+#define filter_fn_set(avg) \
+    filter_fn(64, avg)     \
+    filter_fn(32, avg)     \
+    filter_fn(16, avg)     \
+    filter_fn(8, avg)      \
+    filter_fn(4, avg)
+
+filter_fn_set(put)
+filter_fn_set(avg)
+
+#undef filter_fn
+#undef filter_fn_set
+#undef filter_fn_1d
+#undef filter_fn_2d
+#undef bilinf_fn_1d
+#undef bilinf_fn_2d
+
+static av_cold void vp9dsp_mc_init(VP9DSPContext *dsp)
+{
+#define init_fpel(idx1, idx2, sz, type)                                \
+    dsp->mc[idx1][FILTER_8TAP_SMOOTH][idx2][0][0]  = type ## sz ## _c; \
+    dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = type ## sz ## _c; \
+    dsp->mc[idx1][FILTER_8TAP_SHARP][idx2][0][0]   = type ## sz ## _c; \
+    dsp->mc[idx1][FILTER_BILINEAR][idx2][0][0]     = type ## sz ## _c
+
+#define init_copy_avg(idx, sz)          \
+    init_fpel(idx, 0, sz, copy);        \
+    init_fpel(idx, 1, sz, avg)
+
+    init_copy_avg(0, 64);
+    init_copy_avg(1, 32);
+    init_copy_avg(2, 16);
+    init_copy_avg(3,  8);
+    init_copy_avg(4,  4);
+
+#undef init_copy_avg
+#undef init_fpel
+
+#define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type)             \
+    dsp->mc[idx1][FILTER_8TAP_SMOOTH][idx2][idxh][idxv]  = type ## _8tap_smooth_  ## sz ## dir ## _c; \
+    dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type ## _8tap_regular_ ## sz ## dir ## _c; \
+    dsp->mc[idx1][FILTER_8TAP_SHARP][idx2][idxh][idxv]   = type ## _8tap_sharp_   ## sz ## dir ## _c; \
+    dsp->mc[idx1][FILTER_BILINEAR][idx2][idxh][idxv]     = type ## _bilin_        ## sz ## dir ## _c
+
+#define init_subpel2(idx, idxh, idxv, dir, type)     \
+    init_subpel1(0, idx, idxh, idxv, 64, dir, type); \
+    init_subpel1(1, idx, idxh, idxv, 32, dir, type); \
+    init_subpel1(2, idx, idxh, idxv, 16, dir, type); \
+    init_subpel1(3, idx, idxh, idxv,  8, dir, type); \
+    init_subpel1(4, idx, idxh, idxv,  4, dir, type)
+
+#define init_subpel3(idx, type)         \
+    init_subpel2(idx, 1, 1, hv, type);  \
+    init_subpel2(idx, 0, 1, v, type);   \
+    init_subpel2(idx, 1, 0, h, type)
+
+    init_subpel3(0, put);
+    init_subpel3(1, avg);
+
+#undef init_subpel1
+#undef init_subpel2
+#undef init_subpel3
+}
+
+av_cold void ff_vp9dsp_init(VP9DSPContext *dsp)
+{
+    vp9dsp_intrapred_init(dsp);
+    vp9dsp_itxfm_init(dsp);
+    vp9dsp_loopfilter_init(dsp);
+    vp9dsp_mc_init(dsp);
+
+    if (ARCH_X86)
+        ff_vp9dsp_init_x86(dsp);
+}
diff --git a/libavcodec/vp9mvs.c b/libavcodec/vp9mvs.c
new file mode 100644
index 0000000..2f37755
--- /dev/null
+++ b/libavcodec/vp9mvs.c
@@ -0,0 +1,344 @@
+/*
+ * VP9 compatible video decoder
+ *
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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 "internal.h"
+#include "vp56.h"
+#include "vp9.h"
+#include "vp9data.h"
+
+static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src,
+                                      VP9Context *s)
+{
+    dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x);
+    dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y);
+}
+
+static void find_ref_mvs(VP9Context *s,
+                         VP56mv *pmv, int ref, int z, int idx, int sb)
+{
+    static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = {
+        [BS_64x64] = { {  3, -1 }, { -1,  3 }, {  4, -1 }, { -1,  4 },
+                       { -1, -1 }, {  0, -1 }, { -1,  0 }, {  6, -1 } },
+        [BS_64x32] = { {  0, -1 }, { -1,  0 }, {  4, -1 }, { -1,  2 },
+                       { -1, -1 }, {  0, -3 }, { -3,  0 }, {  2, -1 } },
+        [BS_32x64] = { { -1,  0 }, {  0, -1 }, { -1,  4 }, {  2, -1 },
+                       { -1, -1 }, { -3,  0 }, {  0, -3 }, { -1,  2 } },
+        [BS_32x32] = { {  1, -1 }, { -1,  1 }, {  2, -1 }, { -1,  2 },
+                       { -1, -1 }, {  0, -3 }, { -3,  0 }, { -3, -3 } },
+        [BS_32x16] = { {  0, -1 }, { -1,  0 }, {  2, -1 }, { -1, -1 },
+                       { -1,  1 }, {  0, -3 }, { -3,  0 }, { -3, -3 } },
+        [BS_16x32] = { { -1,  0 }, {  0, -1 }, { -1,  2 }, { -1, -1 },
+                       {  1, -1 }, { -3,  0 }, {  0, -3 }, { -3, -3 } },
+        [BS_16x16] = { {  0, -1 }, { -1,  0 }, {  1, -1 }, { -1,  1 },
+                       { -1, -1 }, {  0, -3 }, { -3,  0 }, { -3, -3 } },
+        [BS_16x8]  = { {  0, -1 }, { -1,  0 }, {  1, -1 }, { -1, -1 },
+                       {  0, -2 }, { -2,  0 }, { -2, -1 }, { -1, -2 } },
+        [BS_8x16]  = { { -1,  0 }, {  0, -1 }, { -1,  1 }, { -1, -1 },
+                       { -2,  0 }, {  0, -2 }, { -1, -2 }, { -2, -1 } },
+        [BS_8x8]   = { {  0, -1 }, { -1,  0 }, { -1, -1 }, {  0, -2 },
+                       { -2,  0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
+        [BS_8x4]   = { {  0, -1 }, { -1,  0 }, { -1, -1 }, {  0, -2 },
+                       { -2,  0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
+        [BS_4x8]   = { {  0, -1 }, { -1,  0 }, { -1, -1 }, {  0, -2 },
+                       { -2,  0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
+        [BS_4x4]   = { {  0, -1 }, { -1,  0 }, { -1, -1 }, {  0, -2 },
+                       { -2,  0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
+    };
+    VP9Block *const b = &s->b;
+    int row = b->row, col = b->col, row7 = b->row7;
+    const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
+#define INVALID_MV 0x80008000U
+    uint32_t mem = INVALID_MV;
+    int i;
+
+#define RETURN_DIRECT_MV(mv)                    \
+    do {                                        \
+        uint32_t m = AV_RN32A(&mv);             \
+        if (!idx) {                             \
+            AV_WN32A(pmv, m);                   \
+            return;                             \
+        } else if (mem == INVALID_MV) {         \
+            mem = m;                            \
+        } else if (m != mem) {                  \
+            AV_WN32A(pmv, m);                   \
+            return;                             \
+        }                                       \
+    } while (0)
+
+    if (sb >= 0) {
+        if (sb == 2 || sb == 1) {
+            RETURN_DIRECT_MV(b->mv[0][z]);
+        } else if (sb == 3) {
+            RETURN_DIRECT_MV(b->mv[2][z]);
+            RETURN_DIRECT_MV(b->mv[1][z]);
+            RETURN_DIRECT_MV(b->mv[0][z]);
+        }
+
+#define RETURN_MV(mv)                           \
+    do {                                        \
+        if (sb > 0) {                           \
+            VP56mv tmp;                         \
+            uint32_t m;                         \
+            clamp_mv(&tmp, &mv, s);             \
+            m = AV_RN32A(&tmp);                 \
+            if (!idx) {                         \
+                AV_WN32A(pmv, m);               \
+                return;                         \
+            } else if (mem == INVALID_MV) {     \
+                mem = m;                        \
+            } else if (m != mem) {              \
+                AV_WN32A(pmv, m);               \
+                return;                         \
+            }                                   \
+        } else {                                \
+            uint32_t m = AV_RN32A(&mv);         \
+            if (!idx) {                         \
+                clamp_mv(pmv, &mv, s);          \
+                return;                         \
+            } else if (mem == INVALID_MV) {     \
+                mem = m;                        \
+            } else if (m != mem) {              \
+                clamp_mv(pmv, &mv, s);          \
+                return;                         \
+            }                                   \
+        }                                       \
+    } while (0)
+
+        if (row > 0) {
+            VP9MVRefPair *mv = &s->mv[0][(row - 1) * s->sb_cols * 8 + col];
+
+            if (mv->ref[0] == ref)
+                RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
+            else if (mv->ref[1] == ref)
+                RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]);
+        }
+        if (col > s->tiling.tile_col_start) {
+            VP9MVRefPair *mv = &s->mv[0][row * s->sb_cols * 8 + col - 1];
+
+            if (mv->ref[0] == ref)
+                RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
+            else if (mv->ref[1] == ref)
+                RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]);
+        }
+        i = 2;
+    } else {
+        i = 0;
+    }
+
+    // previously coded MVs in the neighborhood, using same reference frame
+    for (; i < 8; i++) {
+        int c = p[i][0] + col, r = p[i][1] + row;
+
+        if (c >= s->tiling.tile_col_start && c < s->cols &&
+            r >= 0 && r < s->rows) {
+            VP9MVRefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c];
+
+            if (mv->ref[0] == ref)
+                RETURN_MV(mv->mv[0]);
+            else if (mv->ref[1] == ref)
+                RETURN_MV(mv->mv[1]);
+        }
+    }
+
+    // MV at this position in previous frame, using same reference frame
+    if (s->use_last_frame_mvs) {
+        VP9MVRefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col];
+
+        if (mv->ref[0] == ref)
+            RETURN_MV(mv->mv[0]);
+        else if (mv->ref[1] == ref)
+            RETURN_MV(mv->mv[1]);
+    }
+
+#define RETURN_SCALE_MV(mv, scale)              \
+    do {                                        \
+        if (scale) {                            \
+            VP56mv mv_temp = { -mv.x, -mv.y };  \
+            RETURN_MV(mv_temp);                 \
+        } else {                                \
+            RETURN_MV(mv);                      \
+        }                                       \
+    } while (0)
+
+    // previously coded MVs in the neighborhood, using different reference frame
+    for (i = 0; i < 8; i++) {
+        int c = p[i][0] + col, r = p[i][1] + row;
+
+        if (c >= s->tiling.tile_col_start && c < s->cols &&
+            r >= 0 && r < s->rows) {
+            VP9MVRefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c];
+
+            if (mv->ref[0] != ref && mv->ref[0] >= 0)
+                RETURN_SCALE_MV(mv->mv[0],
+                                s->signbias[mv->ref[0]] != s->signbias[ref]);
+            if (mv->ref[1] != ref && mv->ref[1] >= 0)
+                RETURN_SCALE_MV(mv->mv[1],
+                                s->signbias[mv->ref[1]] != s->signbias[ref]);
+        }
+    }
+
+    // MV at this position in previous frame, using different reference frame
+    if (s->use_last_frame_mvs) {
+        VP9MVRefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col];
+
+        if (mv->ref[0] != ref && mv->ref[0] >= 0)
+            RETURN_SCALE_MV(mv->mv[0],
+                            s->signbias[mv->ref[0]] != s->signbias[ref]);
+        if (mv->ref[1] != ref && mv->ref[1] >= 0)
+            RETURN_SCALE_MV(mv->mv[1],
+                            s->signbias[mv->ref[1]] != s->signbias[ref]);
+    }
+
+    AV_ZERO32(pmv);
+#undef INVALID_MV
+#undef RETURN_MV
+#undef RETURN_SCALE_MV
+}
+
+static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp)
+{
+    int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign);
+    int n, c = vp8_rac_get_tree(&s->c, ff_vp9_mv_class_tree,
+                                s->prob.p.mv_comp[idx].classes);
+
+    s->counts.mv_comp[idx].sign[sign]++;
+    s->counts.mv_comp[idx].classes[c]++;
+    if (c) {
+        int m;
+
+        for (n = 0, m = 0; m < c; m++) {
+            bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]);
+            n  |= bit << m;
+            s->counts.mv_comp[idx].bits[m][bit]++;
+        }
+        n <<= 3;
+        bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree,
+                               s->prob.p.mv_comp[idx].fp);
+        n  |= bit << 1;
+        s->counts.mv_comp[idx].fp[bit]++;
+        if (hp) {
+            bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp);
+            s->counts.mv_comp[idx].hp[bit]++;
+            n |= bit;
+        } else {
+            n |= 1;
+            // bug in libvpx - we count for bw entropy purposes even if the
+            // bit wasn't coded
+            s->counts.mv_comp[idx].hp[1]++;
+        }
+        n += 8 << c;
+    } else {
+        n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0);
+        s->counts.mv_comp[idx].class0[n]++;
+        bit = vp8_rac_get_tree(&s->c, ff_vp9_mv_fp_tree,
+                               s->prob.p.mv_comp[idx].class0_fp[n]);
+        s->counts.mv_comp[idx].class0_fp[n][bit]++;
+        n = (n << 3) | (bit << 1);
+        if (hp) {
+            bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp);
+            s->counts.mv_comp[idx].class0_hp[bit]++;
+            n |= bit;
+        } else {
+            n |= 1;
+            // bug in libvpx - we count for bw entropy purposes even if the
+            // bit wasn't coded
+            s->counts.mv_comp[idx].class0_hp[1]++;
+        }
+    }
+
+    return sign ? -(n + 1) : (n + 1);
+}
+
+void ff_vp9_fill_mv(VP9Context *s, VP56mv *mv, int mode, int sb)
+{
+    VP9Block *const b = &s->b;
+
+    if (mode == ZEROMV) {
+        memset(mv, 0, sizeof(*mv) * 2);
+    } else {
+        int hp;
+
+        // FIXME cache this value and reuse for other subblocks
+        find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV,
+                     mode == NEWMV ? -1 : sb);
+        // FIXME maybe move this code into find_ref_mvs()
+        if ((mode == NEWMV || sb == -1) &&
+            !(hp = s->highprecisionmvs &&
+              abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) {
+            if (mv[0].y & 1) {
+                if (mv[0].y < 0)
+                    mv[0].y++;
+                else
+                    mv[0].y--;
+            }
+            if (mv[0].x & 1) {
+                if (mv[0].x < 0)
+                    mv[0].x++;
+                else
+                    mv[0].x--;
+            }
+        }
+        if (mode == NEWMV) {
+            enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree,
+                                              s->prob.p.mv_joint);
+
+            s->counts.mv_joint[j]++;
+            if (j >= MV_JOINT_V)
+                mv[0].y += read_mv_component(s, 0, hp);
+            if (j & 1)
+                mv[0].x += read_mv_component(s, 1, hp);
+        }
+
+        if (b->comp) {
+            // FIXME cache this value and reuse for other subblocks
+            find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV,
+                         mode == NEWMV ? -1 : sb);
+            if ((mode == NEWMV || sb == -1) &&
+                !(hp = s->highprecisionmvs &&
+                  abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) {
+                if (mv[1].y & 1) {
+                    if (mv[1].y < 0)
+                        mv[1].y++;
+                    else
+                        mv[1].y--;
+                }
+                if (mv[1].x & 1) {
+                    if (mv[1].x < 0)
+                        mv[1].x++;
+                    else
+                        mv[1].x--;
+                }
+            }
+            if (mode == NEWMV) {
+                enum MVJoint j = vp8_rac_get_tree(&s->c, ff_vp9_mv_joint_tree,
+                                                  s->prob.p.mv_joint);
+
+                s->counts.mv_joint[j]++;
+                if (j >= MV_JOINT_V)
+                    mv[1].y += read_mv_component(s, 0, hp);
+                if (j & 1)
+                    mv[1].x += read_mv_component(s, 1, hp);
+            }
+        }
+    }
+}
diff --git a/libavcodec/vp9prob.c b/libavcodec/vp9prob.c
new file mode 100644
index 0000000..b8a7c22
--- /dev/null
+++ b/libavcodec/vp9prob.c
@@ -0,0 +1,274 @@
+/*
+ * VP9 compatible video decoder
+ *
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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 "vp56.h"
+#include "vp9.h"
+#include "vp9data.h"
+
+static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1,
+                                        int max_count, int update_factor)
+{
+    unsigned ct = ct0 + ct1, p2, p1;
+
+    if (!ct)
+        return;
+
+    p1 = *p;
+    p2 = ((ct0 << 8) + (ct >> 1)) / ct;
+    p2 = av_clip(p2, 1, 255);
+    ct = FFMIN(ct, max_count);
+    update_factor = FASTDIV(update_factor * ct, max_count);
+
+    // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8
+    *p = p1 + (((p2 - p1) * update_factor + 128) >> 8);
+}
+
+void ff_vp9_adapt_probs(VP9Context *s)
+{
+    int i, j, k, l, m;
+    ProbContext *p = &s->prob_ctx[s->framectxid].p;
+    int uf = (s->keyframe || s->intraonly || !s->last_keyframe) ? 112 : 128;
+
+    // coefficients
+    for (i = 0; i < 4; i++)
+        for (j = 0; j < 2; j++)
+            for (k = 0; k < 2; k++)
+                for (l = 0; l < 6; l++)
+                    for (m = 0; m < 6; m++) {
+                        uint8_t *pp = s->prob_ctx[s->framectxid].coef[i][j][k][l][m];
+                        unsigned *e = s->counts.eob[i][j][k][l][m];
+                        unsigned *c = s->counts.coef[i][j][k][l][m];
+
+                        if (l == 0 && m >= 3) // dc only has 3 pt
+                            break;
+
+                        adapt_prob(&pp[0], e[0], e[1], 24, uf);
+                        adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf);
+                        adapt_prob(&pp[2], c[1], c[2], 24, uf);
+                    }
+
+    if (s->keyframe || s->intraonly) {
+        memcpy(p->skip,  s->prob.p.skip,  sizeof(p->skip));
+        memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p));
+        memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p));
+        memcpy(p->tx8p,  s->prob.p.tx8p,  sizeof(p->tx8p));
+        return;
+    }
+
+    // skip flag
+    for (i = 0; i < 3; i++)
+        adapt_prob(&p->skip[i], s->counts.skip[i][0],
+                   s->counts.skip[i][1], 20, 128);
+
+    // intra/inter flag
+    for (i = 0; i < 4; i++)
+        adapt_prob(&p->intra[i], s->counts.intra[i][0],
+                   s->counts.intra[i][1], 20, 128);
+
+    // comppred flag
+    if (s->comppredmode == PRED_SWITCHABLE) {
+        for (i = 0; i < 5; i++)
+            adapt_prob(&p->comp[i], s->counts.comp[i][0],
+                       s->counts.comp[i][1], 20, 128);
+    }
+
+    // reference frames
+    if (s->comppredmode != PRED_SINGLEREF) {
+        for (i = 0; i < 5; i++)
+            adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0],
+                       s->counts.comp_ref[i][1], 20, 128);
+    }
+
+    if (s->comppredmode != PRED_COMPREF) {
+        for (i = 0; i < 5; i++) {
+            uint8_t *pp = p->single_ref[i];
+            unsigned (*c)[2] = s->counts.single_ref[i];
+
+            adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128);
+            adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128);
+        }
+    }
+
+    // block partitioning
+    for (i = 0; i < 4; i++)
+        for (j = 0; j < 4; j++) {
+            uint8_t *pp = p->partition[i][j];
+            unsigned *c = s->counts.partition[i][j];
+
+            adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
+            adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
+            adapt_prob(&pp[2], c[2], c[3], 20, 128);
+        }
+
+    // tx size
+    if (s->txfmmode == TX_SWITCHABLE) {
+        for (i = 0; i < 2; i++) {
+            unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i];
+
+            adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0],
+                       s->counts.tx8p[i][1], 20, 128);
+            adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128);
+            adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128);
+            adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128);
+            adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128);
+            adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128);
+        }
+    }
+
+    // interpolation filter
+    if (s->filtermode == FILTER_SWITCHABLE) {
+        for (i = 0; i < 4; i++) {
+            uint8_t *pp = p->filter[i];
+            unsigned *c = s->counts.filter[i];
+
+            adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128);
+            adapt_prob(&pp[1], c[1], c[2], 20, 128);
+        }
+    }
+
+    // inter modes
+    for (i = 0; i < 7; i++) {
+        uint8_t *pp = p->mv_mode[i];
+        unsigned *c = s->counts.mv_mode[i];
+
+        adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128);
+        adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128);
+        adapt_prob(&pp[2], c[1], c[3], 20, 128);
+    }
+
+    // mv joints
+    {
+        uint8_t *pp = p->mv_joint;
+        unsigned *c = s->counts.mv_joint;
+
+        adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
+        adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
+        adapt_prob(&pp[2], c[2], c[3], 20, 128);
+    }
+
+    // mv components
+    for (i = 0; i < 2; i++) {
+        uint8_t *pp;
+        unsigned *c, (*c2)[2], sum;
+
+        adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0],
+                   s->counts.mv_comp[i].sign[1], 20, 128);
+
+        pp  = p->mv_comp[i].classes;
+        c   = s->counts.mv_comp[i].classes;
+        sum = c[1] + c[2] + c[3] + c[4] + c[5] +
+              c[6] + c[7] + c[8] + c[9] + c[10];
+        adapt_prob(&pp[0], c[0], sum, 20, 128);
+        sum -= c[1];
+        adapt_prob(&pp[1], c[1], sum, 20, 128);
+        sum -= c[2] + c[3];
+        adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128);
+        adapt_prob(&pp[3], c[2], c[3], 20, 128);
+        sum -= c[4] + c[5];
+        adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128);
+        adapt_prob(&pp[5], c[4], c[5], 20, 128);
+        sum -= c[6];
+        adapt_prob(&pp[6], c[6], sum, 20, 128);
+        adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128);
+        adapt_prob(&pp[8], c[7], c[8], 20, 128);
+        adapt_prob(&pp[9], c[9], c[10], 20, 128);
+
+        adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0],
+                   s->counts.mv_comp[i].class0[1], 20, 128);
+        pp = p->mv_comp[i].bits;
+        c2 = s->counts.mv_comp[i].bits;
+        for (j = 0; j < 10; j++)
+            adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128);
+
+        for (j = 0; j < 2; j++) {
+            pp = p->mv_comp[i].class0_fp[j];
+            c  = s->counts.mv_comp[i].class0_fp[j];
+            adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
+            adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
+            adapt_prob(&pp[2], c[2], c[3], 20, 128);
+        }
+        pp = p->mv_comp[i].fp;
+        c  = s->counts.mv_comp[i].fp;
+        adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
+        adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
+        adapt_prob(&pp[2], c[2], c[3], 20, 128);
+
+        if (s->highprecisionmvs) {
+            adapt_prob(&p->mv_comp[i].class0_hp,
+                       s->counts.mv_comp[i].class0_hp[0],
+                       s->counts.mv_comp[i].class0_hp[1], 20, 128);
+            adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0],
+                       s->counts.mv_comp[i].hp[1], 20, 128);
+        }
+    }
+
+    // y intra modes
+    for (i = 0; i < 4; i++) {
+        uint8_t *pp = p->y_mode[i];
+        unsigned *c = s->counts.y_mode[i], sum, s2;
+
+        sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
+        adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
+        sum -= c[TM_VP8_PRED];
+        adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
+        sum -= c[VERT_PRED];
+        adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
+        s2   = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
+        sum -= s2;
+        adapt_prob(&pp[3], s2, sum, 20, 128);
+        s2 -= c[HOR_PRED];
+        adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
+        adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED],
+                   20, 128);
+        sum -= c[DIAG_DOWN_LEFT_PRED];
+        adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
+        sum -= c[VERT_LEFT_PRED];
+        adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
+        adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
+    }
+
+    // uv intra modes
+    for (i = 0; i < 10; i++) {
+        uint8_t *pp = p->uv_mode[i];
+        unsigned *c = s->counts.uv_mode[i], sum, s2;
+
+        sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
+        adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
+        sum -= c[TM_VP8_PRED];
+        adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
+        sum -= c[VERT_PRED];
+        adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
+        s2   = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
+        sum -= s2;
+        adapt_prob(&pp[3], s2, sum, 20, 128);
+        s2 -= c[HOR_PRED];
+        adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
+        adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED],
+                   20, 128);
+        sum -= c[DIAG_DOWN_LEFT_PRED];
+        adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
+        sum -= c[VERT_LEFT_PRED];
+        adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
+        adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
+    }
+}
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index b4656b8..86f2fcf 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -94,7 +94,6 @@
 typedef struct VqaContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
     GetByteContext gb;
 
     uint32_t palette[PALETTE_COUNT];
@@ -122,7 +121,7 @@ typedef struct VqaContext {
 static av_cold int vqa_decode_init(AVCodecContext *avctx)
 {
     VqaContext *s = avctx->priv_data;
-    int i, j, codebook_index;
+    int i, j, codebook_index, ret;
 
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
@@ -130,7 +129,7 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
     /* 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);
-        return -1;
+        return AVERROR(EINVAL);
     }
 
     /* load up the VQA parameters from the header */
@@ -140,17 +139,17 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
     case 2:
         break;
     case 3:
-        av_log_missing_feature(avctx, "VQA Version 3", 0);
+        avpriv_report_missing_feature(avctx, "VQA Version %d", s->vqa_version);
         return AVERROR_PATCHWELCOME;
     default:
-        av_log_missing_feature(avctx, "VQA Version", 1);
+        avpriv_request_sample(avctx, "VQA Version %i", s->vqa_version);
         return AVERROR_PATCHWELCOME;
     }
     s->width = AV_RL16(&s->avctx->extradata[6]);
     s->height = AV_RL16(&s->avctx->extradata[8]);
-    if(av_image_check_size(s->width, s->height, 0, avctx)){
+    if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0) {
         s->width= s->height= 0;
-        return -1;
+        return ret;
     }
     s->vector_width = s->avctx->extradata[10];
     s->vector_height = s->avctx->extradata[11];
@@ -160,7 +159,7 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
     if ((s->vector_width != 4) ||
         ((s->vector_height != 2) && (s->vector_height != 4))) {
         /* return without further initialization */
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (s->width  & (s->vector_width  - 1) ||
@@ -199,8 +198,6 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
     }
     s->next_codebook_buffer_index = 0;
 
-    s->frame.data[0] = NULL;
-
     return 0;
 fail:
     av_freep(&s->codebook);
@@ -314,7 +311,7 @@ static int decode_format80(GetByteContext *gb, int src_size,
     return 0; // let's display what we decoded anyway
 }
 
-static int vqa_decode_chunk(VqaContext *s)
+static int vqa_decode_chunk(VqaContext *s, AVFrame *frame)
 {
     unsigned int chunk_type;
     unsigned int chunk_size;
@@ -482,7 +479,7 @@ static int vqa_decode_chunk(VqaContext *s)
         index_shift = 3;
     for (y = 0; y < s->height; y += s->vector_height) {
         for (x = 0; x < s->width; x += 4, lobytes++, hibytes++) {
-            pixel_ptr = y * s->frame.linesize[0] + x;
+            pixel_ptr = y * frame->linesize[0] + x;
 
             /* get the vector index, the method for which varies according to
              * VQA file version */
@@ -497,11 +494,11 @@ static int vqa_decode_chunk(VqaContext *s)
                 /* uniform color fill - a quick hack */
                 if (hibyte == 0xFF) {
                     while (lines--) {
-                        s->frame.data[0][pixel_ptr + 0] = 255 - lobyte;
-                        s->frame.data[0][pixel_ptr + 1] = 255 - lobyte;
-                        s->frame.data[0][pixel_ptr + 2] = 255 - lobyte;
-                        s->frame.data[0][pixel_ptr + 3] = 255 - lobyte;
-                        pixel_ptr += s->frame.linesize[0];
+                        frame->data[0][pixel_ptr + 0] = 255 - lobyte;
+                        frame->data[0][pixel_ptr + 1] = 255 - lobyte;
+                        frame->data[0][pixel_ptr + 2] = 255 - lobyte;
+                        frame->data[0][pixel_ptr + 3] = 255 - lobyte;
+                        pixel_ptr += frame->linesize[0];
                     }
                     lines=0;
                 }
@@ -522,11 +519,11 @@ static int vqa_decode_chunk(VqaContext *s)
             }
 
             while (lines--) {
-                s->frame.data[0][pixel_ptr + 0] = s->codebook[vector_index++];
-                s->frame.data[0][pixel_ptr + 1] = s->codebook[vector_index++];
-                s->frame.data[0][pixel_ptr + 2] = s->codebook[vector_index++];
-                s->frame.data[0][pixel_ptr + 3] = s->codebook[vector_index++];
-                pixel_ptr += s->frame.linesize[0];
+                frame->data[0][pixel_ptr + 0] = s->codebook[vector_index++];
+                frame->data[0][pixel_ptr + 1] = s->codebook[vector_index++];
+                frame->data[0][pixel_ptr + 2] = s->codebook[vector_index++];
+                frame->data[0][pixel_ptr + 3] = s->codebook[vector_index++];
+                pixel_ptr += frame->linesize[0];
             }
         }
     }
@@ -607,26 +604,23 @@ static int vqa_decode_frame(AVCodecContext *avctx,
                             AVPacket *avpkt)
 {
     VqaContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int res;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    if (ff_get_buffer(avctx, &s->frame)) {
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "  VQA Video: get_buffer() failed\n");
-        return -1;
+        return res;
     }
 
     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
-    if ((res = vqa_decode_chunk(s)) < 0)
+    if ((res = vqa_decode_chunk(s, frame)) < 0)
         return res;
 
     /* make the palette available on the way out */
-    memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
-    s->frame.palette_has_changed = 1;
+    memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
+    frame->palette_has_changed = 1;
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return avpkt->size;
@@ -640,14 +634,12 @@ static av_cold int vqa_decode_end(AVCodecContext *avctx)
     av_freep(&s->next_codebook_buffer);
     av_freep(&s->decode_buffer);
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
     return 0;
 }
 
 AVCodec ff_vqa_decoder = {
     .name           = "vqavideo",
+    .long_name      = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WS_VQA,
     .priv_data_size = sizeof(VqaContext),
@@ -655,5 +647,4 @@ AVCodec ff_vqa_decoder = {
     .close          = vqa_decode_end,
     .decode         = vqa_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Westwood Studios VQA (Vector Quantized Animation) video"),
 };
diff --git a/libavcodec/w32pthreads.h b/libavcodec/w32pthreads.h
deleted file mode 100644
index 91e7353..0000000
--- a/libavcodec/w32pthreads.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2010-2011 x264 project
- *
- * Authors: Steven Walters <kemuri9 at gmail.com>
- *          Pegasys Inc. <http://www.pegasys-inc.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
- */
-
-/**
- * @file
- * w32threads to pthreads wrapper
- */
-
-#ifndef AVCODEC_W32PTHREADS_H
-#define AVCODEC_W32PTHREADS_H
-
-/* Build up a pthread-like API using underlying Windows API. Have only static
- * methods so as to not conflict with a potentially linked in pthread-win32
- * library.
- * As most functions here are used without checking return values,
- * only implement return values as necessary. */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-
-#include "libavutil/internal.h"
-#include "libavutil/mem.h"
-
-typedef struct pthread_t {
-    void *handle;
-    void *(*func)(void* arg);
-    void *arg;
-    void *ret;
-} pthread_t;
-
-/* the conditional variable api for windows 6.0+ uses critical sections and
- * not mutexes */
-typedef CRITICAL_SECTION pthread_mutex_t;
-
-/* This is the CONDITIONAL_VARIABLE typedef for using Window's native
- * conditional variables on kernels 6.0+.
- * MinGW does not currently have this typedef. */
-typedef struct pthread_cond_t {
-    void *ptr;
-} pthread_cond_t;
-
-/* function pointers to conditional variable API on windows 6.0+ kernels */
-static void (WINAPI *cond_broadcast)(pthread_cond_t *cond);
-static void (WINAPI *cond_init)(pthread_cond_t *cond);
-static void (WINAPI *cond_signal)(pthread_cond_t *cond);
-static BOOL (WINAPI *cond_wait)(pthread_cond_t *cond, pthread_mutex_t *mutex,
-                                DWORD milliseconds);
-
-static unsigned __stdcall attribute_align_arg win32thread_worker(void *arg)
-{
-    pthread_t *h = arg;
-    h->ret = h->func(h->arg);
-    return 0;
-}
-
-static int pthread_create(pthread_t *thread, const void *unused_attr,
-                          void *(*start_routine)(void*), void *arg)
-{
-    thread->func   = start_routine;
-    thread->arg    = arg;
-    thread->handle = (void*)_beginthreadex(NULL, 0, win32thread_worker, thread,
-                                           0, NULL);
-    return !thread->handle;
-}
-
-static void pthread_join(pthread_t thread, void **value_ptr)
-{
-    DWORD ret = WaitForSingleObject(thread.handle, INFINITE);
-    if (ret != WAIT_OBJECT_0)
-        return;
-    if (value_ptr)
-        *value_ptr = thread.ret;
-    CloseHandle(thread.handle);
-}
-
-static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
-{
-    InitializeCriticalSection(m);
-    return 0;
-}
-static inline int pthread_mutex_destroy(pthread_mutex_t *m)
-{
-    DeleteCriticalSection(m);
-    return 0;
-}
-static inline int pthread_mutex_lock(pthread_mutex_t *m)
-{
-    EnterCriticalSection(m);
-    return 0;
-}
-static inline int pthread_mutex_unlock(pthread_mutex_t *m)
-{
-    LeaveCriticalSection(m);
-    return 0;
-}
-
-/* for pre-Windows 6.0 platforms we need to define and use our own condition
- * variable and api */
-typedef struct  win32_cond_t {
-    pthread_mutex_t mtx_broadcast;
-    pthread_mutex_t mtx_waiter_count;
-    volatile int waiter_count;
-    HANDLE semaphore;
-    HANDLE waiters_done;
-    volatile int is_broadcast;
-} win32_cond_t;
-
-static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
-{
-    win32_cond_t *win32_cond = NULL;
-    if (cond_init) {
-        cond_init(cond);
-        return;
-    }
-
-    /* non native condition variables */
-    win32_cond = av_mallocz(sizeof(win32_cond_t));
-    if (!win32_cond)
-        return;
-    cond->ptr = win32_cond;
-    win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
-    if (!win32_cond->semaphore)
-        return;
-    win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL);
-    if (!win32_cond->waiters_done)
-        return;
-
-    pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
-    pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
-}
-
-static void pthread_cond_destroy(pthread_cond_t *cond)
-{
-    win32_cond_t *win32_cond = cond->ptr;
-    /* native condition variables do not destroy */
-    if (cond_init)
-        return;
-
-    /* non native condition variables */
-    CloseHandle(win32_cond->semaphore);
-    CloseHandle(win32_cond->waiters_done);
-    pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
-    pthread_mutex_destroy(&win32_cond->mtx_broadcast);
-    av_freep(&win32_cond);
-    cond->ptr = NULL;
-}
-
-static void pthread_cond_broadcast(pthread_cond_t *cond)
-{
-    win32_cond_t *win32_cond = cond->ptr;
-    int have_waiter;
-
-    if (cond_broadcast) {
-        cond_broadcast(cond);
-        return;
-    }
-
-    /* non native condition variables */
-    pthread_mutex_lock(&win32_cond->mtx_broadcast);
-    pthread_mutex_lock(&win32_cond->mtx_waiter_count);
-    have_waiter = 0;
-
-    if (win32_cond->waiter_count) {
-        win32_cond->is_broadcast = 1;
-        have_waiter = 1;
-    }
-
-    if (have_waiter) {
-        ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL);
-        pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
-        WaitForSingleObject(win32_cond->waiters_done, INFINITE);
-        ResetEvent(win32_cond->waiters_done);
-        win32_cond->is_broadcast = 0;
-    } else
-        pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
-    pthread_mutex_unlock(&win32_cond->mtx_broadcast);
-}
-
-static int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
-    win32_cond_t *win32_cond = cond->ptr;
-    int last_waiter;
-    if (cond_wait) {
-        cond_wait(cond, mutex, INFINITE);
-        return 0;
-    }
-
-    /* non native condition variables */
-    pthread_mutex_lock(&win32_cond->mtx_broadcast);
-    pthread_mutex_lock(&win32_cond->mtx_waiter_count);
-    win32_cond->waiter_count++;
-    pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
-    pthread_mutex_unlock(&win32_cond->mtx_broadcast);
-
-    // unlock the external mutex
-    pthread_mutex_unlock(mutex);
-    WaitForSingleObject(win32_cond->semaphore, INFINITE);
-
-    pthread_mutex_lock(&win32_cond->mtx_waiter_count);
-    win32_cond->waiter_count--;
-    last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast;
-    pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
-
-    if (last_waiter)
-        SetEvent(win32_cond->waiters_done);
-
-    // lock the external mutex
-    return pthread_mutex_lock(mutex);
-}
-
-static void pthread_cond_signal(pthread_cond_t *cond)
-{
-    win32_cond_t *win32_cond = cond->ptr;
-    int have_waiter;
-    if (cond_signal) {
-        cond_signal(cond);
-        return;
-    }
-
-    pthread_mutex_lock(&win32_cond->mtx_broadcast);
-
-    /* non-native condition variables */
-    pthread_mutex_lock(&win32_cond->mtx_waiter_count);
-    have_waiter = win32_cond->waiter_count;
-    pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
-
-    if (have_waiter) {
-        ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
-        WaitForSingleObject(win32_cond->waiters_done, INFINITE);
-        ResetEvent(win32_cond->waiters_done);
-    }
-
-    pthread_mutex_unlock(&win32_cond->mtx_broadcast);
-}
-
-static void w32thread_init(void)
-{
-    HANDLE kernel_dll = GetModuleHandle(TEXT("kernel32.dll"));
-    /* if one is available, then they should all be available */
-    cond_init      =
-        (void*)GetProcAddress(kernel_dll, "InitializeConditionVariable");
-    cond_broadcast =
-        (void*)GetProcAddress(kernel_dll, "WakeAllConditionVariable");
-    cond_signal    =
-        (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
-    cond_wait      =
-        (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
-}
-
-#endif /* AVCODEC_W32PTHREADS_H */
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 02cef5f..cbc5b04 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -33,6 +33,8 @@
  * WavPack lossless audio decoder
  */
 
+#define WV_HEADER_SIZE    32
+
 #define WV_MONO           0x00000004
 #define WV_JOINT_STEREO   0x00000010
 #define WV_FALSE_STEREO   0x40000000
@@ -41,6 +43,10 @@
 #define WV_HYBRID_SHAPE   0x00000008
 #define WV_HYBRID_BITRATE 0x00000200
 #define WV_HYBRID_BALANCE 0x00000400
+#define WV_INITIAL_BLOCK  0x00000800
+#define WV_FINAL_BLOCK    0x00001000
+
+#define WV_SINGLE_BLOCK (WV_INITIAL_BLOCK | WV_FINAL_BLOCK)
 
 #define WV_FLT_SHIFT_ONES 0x01
 #define WV_FLT_SHIFT_SAME 0x02
@@ -49,7 +55,7 @@
 #define WV_FLT_ZERO_SIGN  0x10
 
 enum WP_ID_Flags {
-    WP_IDF_MASK   = 0x1F,
+    WP_IDF_MASK   = 0x3F,
     WP_IDF_IGNORE = 0x20,
     WP_IDF_ODD    = 0x40,
     WP_IDF_LONG   = 0x80
@@ -69,7 +75,8 @@ enum WP_ID {
     WP_ID_DATA,
     WP_ID_CORR,
     WP_ID_EXTRABITS,
-    WP_ID_CHANINFO
+    WP_ID_CHANINFO,
+    WP_ID_SAMPLE_RATE = 0x27,
 };
 
 typedef struct SavedContext {
@@ -128,20 +135,22 @@ typedef struct WavpackFrameContext {
 
 typedef struct WavpackContext {
     AVCodecContext *avctx;
-    AVFrame frame;
 
     WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
     int fdec_num;
 
-    int multichannel;
-    int mkv_mode;
     int block;
     int samples;
     int ch_offset;
 } WavpackContext;
 
+static const int wv_rates[16] = {
+     6000,  8000,  9600, 11025, 12000, 16000,  22050, 24000,
+    32000, 44100, 48000, 64000, 88200, 96000, 192000,     0
+};
+
 // exponent table copied from WavPack source
-static const uint8_t wp_exp2_table [256] = {
+static const uint8_t wp_exp2_table[256] = {
     0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
     0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
     0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
@@ -188,9 +197,9 @@ static av_always_inline int wp_exp2(int16_t val)
         neg = 1;
     }
 
-    res = wp_exp2_table[val & 0xFF] | 0x100;
+    res   = wp_exp2_table[val & 0xFF] | 0x100;
     val >>= 8;
-    res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val));
+    res   = (val > 9) ? (res << (val - 9)) : (res >> (9 - val));
     return neg ? -res : res;
 }
 
@@ -231,15 +240,14 @@ static av_always_inline int wp_log2(int32_t val)
         } \
     }
 
-
 static av_always_inline int get_tail(GetBitContext *gb, int k)
 {
     int p, e, res;
 
     if (k < 1)
         return 0;
-    p = av_log2(k);
-    e = (1 << (p + 1)) - k - 1;
+    p   = av_log2(k);
+    e   = (1 << (p + 1)) - k - 1;
     res = p ? get_bits(gb, p) : 0;
     if (res >= e)
         res = (res << 1) - e + get_bits1(gb);
@@ -252,8 +260,8 @@ static void update_error_limit(WavpackFrameContext *ctx)
 
     for (i = 0; i <= ctx->stereo_in; i++) {
         ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta;
-        br[i] = ctx->ch[i].bitrate_acc >> 16;
-        sl[i] = LEVEL_DECAY(ctx->ch[i].slow_level);
+        br[i]                   = ctx->ch[i].bitrate_acc >> 16;
+        sl[i]                   = LEVEL_DECAY(ctx->ch[i].slow_level);
     }
     if (ctx->stereo_in && ctx->hybrid_bitrate) {
         int balance = (sl[1] - sl[0] + br[1] + 1) >> 1;
@@ -262,7 +270,7 @@ static void update_error_limit(WavpackFrameContext *ctx)
             br[0] = 0;
         } else if (-balance > br[0]) {
             br[0] <<= 1;
-            br[1] = 0;
+            br[1]   = 0;
         } else {
             br[1] = br[0] + balance;
             br[0] = br[0] - balance;
@@ -302,7 +310,7 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb,
             if (t >= 2) {
                 if (get_bits_left(gb) < t - 1)
                     goto error;
-                t = get_bits(gb, t - 1) | (1 << (t-1));
+                t = get_bits(gb, t - 1) | (1 << (t - 1));
             } else {
                 if (get_bits_left(gb) < 0)
                     goto error;
@@ -318,7 +326,7 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb,
     }
 
     if (ctx->zero) {
-        t = 0;
+        t         = 0;
         ctx->zero = 0;
     } else {
         t = get_unary_0_33(gb);
@@ -339,10 +347,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb,
 
         if (ctx->one) {
             ctx->one = t & 1;
-            t = (t >> 1) + 1;
+            t        = (t >> 1) + 1;
         } else {
             ctx->one = t & 1;
-            t >>= 1;
+            t      >>= 1;
         }
         ctx->zero = !ctx->one;
     }
@@ -405,11 +413,12 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc,
 {
     int bit;
 
-    if (s->extra_bits){
+    if (s->extra_bits) {
         S <<= s->extra_bits;
 
-        if (s->got_extra_bits && get_bits_left(&s->gb_extra_bits) >= s->extra_bits) {
-            S |= get_bits(&s->gb_extra_bits, s->extra_bits);
+        if (s->got_extra_bits &&
+            get_bits_left(&s->gb_extra_bits) >= s->extra_bits) {
+            S   |= get_bits(&s->gb_extra_bits, s->extra_bits);
             *crc = *crc * 9 + (S & 0xffff) * 3 + ((unsigned)S >> 16);
         }
     }
@@ -442,7 +451,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
     }
 
     if (S) {
-        S <<= s->float_shift;
+        S  <<= s->float_shift;
         sign = S < 0;
         if (sign)
             S = -S;
@@ -462,7 +471,8 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
             if (shift) {
                 S <<= shift;
                 if ((s->float_flag & WV_FLT_SHIFT_ONES) ||
-                    (s->got_extra_bits && (s->float_flag & WV_FLT_SHIFT_SAME) &&
+                    (s->got_extra_bits &&
+                     (s->float_flag & WV_FLT_SHIFT_SAME) &&
                      get_bits1(&s->gb_extra_bits))) {
                     S |= (1 << shift) - 1;
                 } else if (s->got_extra_bits &&
@@ -476,7 +486,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
         S &= 0x7fffff;
     } else {
         sign = 0;
-        exp = 0;
+        exp  = 0;
         if (s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)) {
             if (get_bits1(&s->gb_extra_bits)) {
                 S = get_bits(&s->gb_extra_bits, 23);
@@ -498,7 +508,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
 
 static void wv_reset_saved_context(WavpackFrameContext *s)
 {
-    s->pos = 0;
+    s->pos    = 0;
     s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF;
 }
 
@@ -518,18 +528,20 @@ static inline int wv_check_crc(WavpackFrameContext *s, uint32_t crc,
 }
 
 static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
-                                   void *dst, const int type)
+                                   void *dst_l, void *dst_r, const int type)
 {
     int i, j, count = 0;
     int last, t;
     int A, B, L, L2, R, R2;
-    int pos = s->pos;
-    uint32_t crc = s->sc.crc;
+    int pos                 = s->pos;
+    uint32_t crc            = s->sc.crc;
     uint32_t crc_extra_bits = s->extra_sc.crc;
-    int16_t *dst16 = dst;
-    int32_t *dst32 = dst;
-    float   *dstfl = dst;
-    const int channel_pad = s->avctx->channels - 2;
+    int16_t *dst16_l        = dst_l;
+    int16_t *dst16_r        = dst_r;
+    int32_t *dst32_l        = dst_l;
+    int32_t *dst32_r        = dst_r;
+    float *dstfl_l          = dst_l;
+    float *dstfl_r          = dst_r;
 
     s->one = s->zero = s->zeroes = 0;
     do {
@@ -552,39 +564,41 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
                     }
                     s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
                     s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0];
-                    j = 0;
+                    j                        = 0;
                 } else {
                     A = s->decorr[i].samplesA[pos];
                     B = s->decorr[i].samplesB[pos];
                     j = (pos + t) & 7;
                 }
-                if (type != AV_SAMPLE_FMT_S16) {
+                if (type != AV_SAMPLE_FMT_S16P) {
                     L2 = L + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
                     R2 = R + ((s->decorr[i].weightB * (int64_t)B + 512) >> 10);
                 } else {
                     L2 = L + ((s->decorr[i].weightA * A + 512) >> 10);
                     R2 = R + ((s->decorr[i].weightB * B + 512) >> 10);
                 }
-                if (A && L) s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
-                if (B && R) s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
+                if (A && L)
+                    s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
+                if (B && R)
+                    s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
                 s->decorr[i].samplesA[j] = L = L2;
                 s->decorr[i].samplesB[j] = R = R2;
             } else if (t == -1) {
-                if (type != AV_SAMPLE_FMT_S16)
+                if (type != AV_SAMPLE_FMT_S16P)
                     L2 = L + ((s->decorr[i].weightA * (int64_t)s->decorr[i].samplesA[0] + 512) >> 10);
                 else
                     L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10);
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L);
                 L = L2;
-                if (type != AV_SAMPLE_FMT_S16)
+                if (type != AV_SAMPLE_FMT_S16P)
                     R2 = R + ((s->decorr[i].weightB * (int64_t)L2 + 512) >> 10);
                 else
                     R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10);
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R);
-                R = R2;
+                R                        = R2;
                 s->decorr[i].samplesA[0] = R;
             } else {
-                if (type != AV_SAMPLE_FMT_S16)
+                if (type != AV_SAMPLE_FMT_S16P)
                     R2 = R + ((s->decorr[i].weightB * (int64_t)s->decorr[i].samplesB[0] + 512) >> 10);
                 else
                     R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10);
@@ -592,16 +606,16 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
                 R = R2;
 
                 if (t == -3) {
-                    R2 = s->decorr[i].samplesA[0];
+                    R2                       = s->decorr[i].samplesA[0];
                     s->decorr[i].samplesA[0] = R;
                 }
 
-                if (type != AV_SAMPLE_FMT_S16)
+                if (type != AV_SAMPLE_FMT_S16P)
                     L2 = L + ((s->decorr[i].weightA * (int64_t)R2 + 512) >> 10);
                 else
                     L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10);
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L);
-                L = L2;
+                L                        = L2;
                 s->decorr[i].samplesB[0] = L;
             }
         }
@@ -610,18 +624,15 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
             L += (R -= (L >> 1));
         crc = (crc * 3 + L) * 3 + R;
 
-        if (type == AV_SAMPLE_FMT_FLT) {
-            *dstfl++ = wv_get_value_float(s, &crc_extra_bits, L);
-            *dstfl++ = wv_get_value_float(s, &crc_extra_bits, R);
-            dstfl += channel_pad;
-        } else if (type == AV_SAMPLE_FMT_S32) {
-            *dst32++ = wv_get_value_integer(s, &crc_extra_bits, L);
-            *dst32++ = wv_get_value_integer(s, &crc_extra_bits, R);
-            dst32 += channel_pad;
+        if (type == AV_SAMPLE_FMT_FLTP) {
+            *dstfl_l++ = wv_get_value_float(s, &crc_extra_bits, L);
+            *dstfl_r++ = wv_get_value_float(s, &crc_extra_bits, R);
+        } else if (type == AV_SAMPLE_FMT_S32P) {
+            *dst32_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
+            *dst32_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
         } else {
-            *dst16++ = wv_get_value_integer(s, &crc_extra_bits, L);
-            *dst16++ = wv_get_value_integer(s, &crc_extra_bits, R);
-            dst16 += channel_pad;
+            *dst16_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
+            *dst16_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
         }
         count++;
     } while (!last && count < s->samples);
@@ -631,7 +642,7 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
         wv_check_crc(s, crc, crc_extra_bits))
         return AVERROR_INVALIDDATA;
 
-    return count * 2;
+    return 0;
 }
 
 static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
@@ -640,13 +651,12 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
     int i, j, count = 0;
     int last, t;
     int A, S, T;
-    int pos = s->pos;
-    uint32_t crc = s->sc.crc;
-    uint32_t crc_extra_bits = s->extra_sc.crc;
-    int16_t *dst16 = dst;
-    int32_t *dst32 = dst;
-    float   *dstfl = dst;
-    const int channel_stride = s->avctx->channels;
+    int pos                  = s->pos;
+    uint32_t crc             = s->sc.crc;
+    uint32_t crc_extra_bits  = s->extra_sc.crc;
+    int16_t *dst16           = dst;
+    int32_t *dst32           = dst;
+    float *dstfl             = dst;
 
     s->one = s->zero = s->zeroes = 0;
     do {
@@ -662,12 +672,12 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
                 else
                     A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
                 s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
-                j = 0;
+                j                        = 0;
             } else {
                 A = s->decorr[i].samplesA[pos];
                 j = (pos + t) & 7;
             }
-            if (type != AV_SAMPLE_FMT_S16)
+            if (type != AV_SAMPLE_FMT_S16P)
                 S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
             else
                 S = T + ((s->decorr[i].weightA * A + 512) >> 10);
@@ -678,30 +688,28 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
         pos = (pos + 1) & 7;
         crc = crc * 3 + S;
 
-        if (type == AV_SAMPLE_FMT_FLT) {
-            *dstfl = wv_get_value_float(s, &crc_extra_bits, S);
-            dstfl += channel_stride;
-        } else if (type == AV_SAMPLE_FMT_S32) {
-            *dst32 = wv_get_value_integer(s, &crc_extra_bits, S);
-            dst32 += channel_stride;
+        if (type == AV_SAMPLE_FMT_FLTP) {
+            *dstfl++ = wv_get_value_float(s, &crc_extra_bits, S);
+        } else if (type == AV_SAMPLE_FMT_S32P) {
+            *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S);
         } else {
-            *dst16 = wv_get_value_integer(s, &crc_extra_bits, S);
-            dst16 += channel_stride;
+            *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S);
         }
         count++;
     } while (!last && count < s->samples);
 
     wv_reset_saved_context(s);
-    if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
-        wv_check_crc(s, crc, crc_extra_bits))
-        return AVERROR_INVALIDDATA;
+    if (s->avctx->err_recognition & AV_EF_CRCCHECK) {
+        int ret = wv_check_crc(s, crc, crc_extra_bits);
+        if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE)
+            return ret;
+    }
 
-    return count;
+    return 0;
 }
 
 static av_cold int wv_alloc_frame_context(WavpackContext *c)
 {
-
     if (c->fdec_num == WV_MAX_FRAME_DECODERS)
         return -1;
 
@@ -720,29 +728,9 @@ static av_cold int wavpack_decode_init(AVCodecContext *avctx)
     WavpackContext *s = avctx->priv_data;
 
     s->avctx = avctx;
-    if (avctx->bits_per_coded_sample <= 16)
-        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-    else
-        avctx->sample_fmt = AV_SAMPLE_FMT_S32;
-    if (avctx->channels <= 2 && !avctx->channel_layout)
-        avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO :
-                                                         AV_CH_LAYOUT_MONO;
-
-    s->multichannel = avctx->channels > 2;
-    /* lavf demuxer does not provide extradata, Matroska stores 0x403
-       there, use this to detect decoding mode for multichannel */
-    s->mkv_mode = 0;
-    if (s->multichannel && avctx->extradata && avctx->extradata_size == 2) {
-        int ver = AV_RL16(avctx->extradata);
-        if (ver >= 0x402 && ver <= 0x410)
-            s->mkv_mode = 1;
-    }
 
     s->fdec_num = 0;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -759,23 +747,18 @@ static av_cold int wavpack_decode_end(AVCodecContext *avctx)
 }
 
 static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
-                                void *data, int *got_frame_ptr,
-                                const uint8_t *buf, int buf_size)
+                                AVFrame *frame, const uint8_t *buf, int buf_size)
 {
     WavpackContext *wc = avctx->priv_data;
     WavpackFrameContext *s;
     GetByteContext gb;
-    void *samples = data;
-    int samplecount;
+    void *samples_l, *samples_r;
+    int ret;
     int got_terms   = 0, got_weights = 0, got_samples = 0,
         got_entropy = 0, got_bs      = 0, got_float   = 0, got_hybrid = 0;
     int i, j, id, size, ssize, weights, t;
-    int bpp, chan, chmask, orig_bpp;
-
-    if (buf_size == 0) {
-        *got_frame_ptr = 0;
-        return 0;
-    }
+    int bpp, chan = 0, chmask = 0, orig_bpp, sample_rate = 0;
+    int multiblock;
 
     if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n");
@@ -784,34 +767,29 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
 
     s = wc->fdec[block_no];
     if (!s) {
-        av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n", block_no);
+        av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n",
+               block_no);
         return AVERROR_INVALIDDATA;
     }
 
     memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
     memset(s->ch, 0, sizeof(s->ch));
-    s->extra_bits = 0;
-    s->and = s->or = s->shift = 0;
+    s->extra_bits     = 0;
+    s->and            = s->or = s->shift = 0;
     s->got_extra_bits = 0;
 
     bytestream2_init(&gb, buf, buf_size);
 
-    if (!wc->mkv_mode) {
-        s->samples = bytestream2_get_le32(&gb);
-        if (s->samples != wc->samples)
-            return AVERROR_INVALIDDATA;
-
-        if (!s->samples) {
-            *got_frame_ptr = 0;
-            return 0;
-        }
-    } else {
-        s->samples = wc->samples;
+    s->samples = bytestream2_get_le32(&gb);
+    if (s->samples != wc->samples) {
+        av_log(avctx, AV_LOG_ERROR, "Mismatching number of samples in "
+               "a sequence: %d and %d\n", wc->samples, s->samples);
+        return AVERROR_INVALIDDATA;
     }
     s->frame_flags = bytestream2_get_le32(&gb);
-    bpp = av_get_bytes_per_sample(avctx->sample_fmt);
-    samples = (uint8_t*)samples + bpp * wc->ch_offset;
-    orig_bpp = ((s->frame_flags & 0x03) + 1) << 3;
+    bpp            = av_get_bytes_per_sample(avctx->sample_fmt);
+    orig_bpp       = ((s->frame_flags & 0x03) + 1) << 3;
+    multiblock     = (s->frame_flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK;
 
     s->stereo         = !(s->frame_flags & WV_MONO);
     s->stereo_in      =  (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo;
@@ -819,13 +797,9 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
     s->hybrid         =   s->frame_flags & WV_HYBRID_MODE;
     s->hybrid_bitrate =   s->frame_flags & WV_HYBRID_BITRATE;
     s->post_shift     = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f);
-    s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1);
+    s->hybrid_maxclip =  ((1LL << (orig_bpp - 1)) - 1);
     s->hybrid_minclip = ((-1LL << (orig_bpp - 1)));
     s->CRC            = bytestream2_get_le32(&gb);
-    if (wc->mkv_mode)
-        bytestream2_skip(&gb, 4);  // skip block size;
-
-    wc->ch_offset += 1 + s->stereo;
 
     // parse metadata blocks
     while (bytestream2_get_bytes_left(&gb)) {
@@ -836,11 +810,12 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
             size |= (bytestream2_get_byte(&gb)) << 16;
         }
         size <<= 1; // size is specified in words
-        ssize = size;
+        ssize  = size;
         if (id & WP_IDF_ODD)
             size--;
         if (size < 0) {
-            av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size);
+            av_log(avctx, AV_LOG_ERROR,
+                   "Got incorrect block %02X with size %i\n", id, size);
             break;
         }
         if (bytestream2_get_bytes_left(&gb) < ssize) {
@@ -848,10 +823,6 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
                    "Block size %i is out of bounds\n", size);
             break;
         }
-        if (id & WP_IDF_IGNORE) {
-            bytestream2_skip(&gb, ssize);
-            continue;
-        }
         switch (id & WP_IDF_MASK) {
         case WP_ID_DECTERMS:
             if (size > MAX_TERMS) {
@@ -884,13 +855,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
                 s->decorr[s->terms - i - 1].weightA = t << 3;
                 if (s->decorr[s->terms - i - 1].weightA > 0)
                     s->decorr[s->terms - i - 1].weightA +=
-                            (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
+                        (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
                 if (s->stereo_in) {
                     t = (int8_t)bytestream2_get_byte(&gb);
                     s->decorr[s->terms - i - 1].weightB = t << 3;
                     if (s->decorr[s->terms - i - 1].weightB > 0)
                         s->decorr[s->terms - i - 1].weightB +=
-                                (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
+                            (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
                 }
             }
             got_weights = 1;
@@ -944,11 +915,10 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
                 bytestream2_skip(&gb, ssize);
                 continue;
             }
-            for (j = 0; j <= s->stereo_in; j++) {
+            for (j = 0; j <= s->stereo_in; j++)
                 for (i = 0; i < 3; i++) {
                     s->ch[j].median[i] = wp_exp2(bytestream2_get_le16(&gb));
                 }
-            }
             got_entropy = 1;
             break;
         case WP_ID_HYBRID:
@@ -995,11 +965,10 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
                 s->shift = val[3];
             }
             /* original WavPack decoder forces 32-bit lossy sound to be treated
-             * as 24-bit one in order to have proper clipping
-             */
+             * as 24-bit one in order to have proper clipping */
             if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) {
-                s->post_shift += 8;
-                s->shift      -= 8;
+                s->post_shift      += 8;
+                s->shift           -= 8;
                 s->hybrid_maxclip >>= 8;
                 s->hybrid_minclip >>= 8;
             }
@@ -1024,7 +993,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
             init_get_bits(&s->gb, gb.buffer, size * 8);
             s->data_size = size * 8;
             bytestream2_skip(&gb, size);
-            got_bs = 1;
+            got_bs       = 1;
             break;
         case WP_ID_EXTRABITS:
             if (size <= 4) {
@@ -1042,7 +1011,8 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
             break;
         case WP_ID_CHANINFO:
             if (size <= 1) {
-                av_log(avctx, AV_LOG_ERROR, "Insufficient channel information\n");
+                av_log(avctx, AV_LOG_ERROR,
+                       "Insufficient channel information\n");
                 return AVERROR_INVALIDDATA;
             }
             chan = bytestream2_get_byte(&gb);
@@ -1070,15 +1040,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
                 chan   = avctx->channels;
                 chmask = avctx->channel_layout;
             }
-            if (chan != avctx->channels) {
-                av_log(avctx, AV_LOG_ERROR,
-                       "Block reports total %d channels, "
-                       "decoder believes it's %d channels\n",
-                       chan, avctx->channels);
+            break;
+        case WP_ID_SAMPLE_RATE:
+            if (size != 3) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid custom sample rate.\n");
                 return AVERROR_INVALIDDATA;
             }
-            if (!avctx->channel_layout)
-                avctx->channel_layout = chmask;
+            sample_rate = bytestream2_get_le24(&gb);
             break;
         default:
             bytestream2_skip(&gb, size);
@@ -1111,11 +1079,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
         av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");
         return AVERROR_INVALIDDATA;
     }
-    if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
+    if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
         av_log(avctx, AV_LOG_ERROR, "Float information not found\n");
         return AVERROR_INVALIDDATA;
     }
-    if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLT) {
+    if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) {
         const int size   = get_bits_left(&s->gb_extra_bits);
         const int wanted = s->samples * s->extra_bits << s->stereo_in;
         if (size < wanted) {
@@ -1124,64 +1092,61 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
         }
     }
 
-    if (s->stereo_in) {
-        if (avctx->sample_fmt == AV_SAMPLE_FMT_S16)
-            samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_S16);
-        else if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
-            samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_S32);
-        else
-            samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT);
-
-        if (samplecount < 0)
-            return samplecount;
-
-        samplecount >>= 1;
-    } else {
-        const int channel_stride = avctx->channels;
-
-        if (avctx->sample_fmt == AV_SAMPLE_FMT_S16)
-            samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_S16);
-        else if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
-            samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_S32);
-        else
-            samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT);
-
-        if (samplecount < 0)
-            return samplecount;
-
-        if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
-            int16_t *dst = (int16_t*)samples + 1;
-            int16_t *src = (int16_t*)samples;
-            int cnt = samplecount;
-            while (cnt--) {
-                *dst = *src;
-                src += channel_stride;
-                dst += channel_stride;
-            }
-        } else if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S32) {
-            int32_t *dst = (int32_t*)samples + 1;
-            int32_t *src = (int32_t*)samples;
-            int cnt = samplecount;
-            while (cnt--) {
-                *dst = *src;
-                src += channel_stride;
-                dst += channel_stride;
-            }
-        } else if (s->stereo) {
-            float *dst = (float*)samples + 1;
-            float *src = (float*)samples;
-            int cnt = samplecount;
-            while (cnt--) {
-                *dst = *src;
-                src += channel_stride;
-                dst += channel_stride;
+    if (!wc->ch_offset) {
+        int sr = (s->frame_flags >> 23) & 0xf;
+        if (sr == 0xf) {
+            if (!sample_rate) {
+                av_log(avctx, AV_LOG_ERROR, "Custom sample rate missing.\n");
+                return AVERROR_INVALIDDATA;
             }
+            avctx->sample_rate = sample_rate;
+        } else
+            avctx->sample_rate = wv_rates[sr];
+
+        if (multiblock) {
+            if (chan)
+                avctx->channels = chan;
+            if (chmask)
+                avctx->channel_layout = chmask;
+        } else {
+            avctx->channels       = s->stereo ? 2 : 1;
+            avctx->channel_layout = s->stereo ? AV_CH_LAYOUT_STEREO :
+                                                AV_CH_LAYOUT_MONO;
+        }
+
+        /* get output buffer */
+        frame->nb_samples = s->samples;
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+            return ret;
         }
     }
 
-    *got_frame_ptr = 1;
+    if (wc->ch_offset + s->stereo >= avctx->channels) {
+        av_log(avctx, AV_LOG_WARNING, "Too many channels coded in a packet.\n");
+        return (avctx->err_recognition & AV_EF_EXPLODE) ? AVERROR_INVALIDDATA : 0;
+    }
 
-    return samplecount * bpp;
+    samples_l = frame->extended_data[wc->ch_offset];
+    if (s->stereo)
+        samples_r = frame->extended_data[wc->ch_offset + 1];
+
+    wc->ch_offset += 1 + s->stereo;
+
+    if (s->stereo_in) {
+        ret = wv_unpack_stereo(s, &s->gb, samples_l, samples_r, avctx->sample_fmt);
+        if (ret < 0)
+            return ret;
+    } else {
+        ret = wv_unpack_mono(s, &s->gb, samples_l, avctx->sample_fmt);
+        if (ret < 0)
+            return ret;
+
+        if (s->stereo)
+            memcpy(samples_r, samples_l, bpp * s->samples);
+    }
+
+    return 0;
 }
 
 static void wavpack_decode_flush(AVCodecContext *avctx)
@@ -1199,28 +1164,18 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
     WavpackContext *s  = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
+    AVFrame *frame     = data;
     int frame_size, ret, frame_flags;
-    int samplecount = 0;
 
-    if (avpkt->size < 12 + s->multichannel * 4)
+    if (avpkt->size <= WV_HEADER_SIZE)
         return AVERROR_INVALIDDATA;
 
     s->block     = 0;
     s->ch_offset = 0;
 
     /* determine number of samples */
-    if (s->mkv_mode) {
-        s->samples  = AV_RL32(buf); buf += 4;
-        frame_flags = AV_RL32(buf);
-    } else {
-        if (s->multichannel) {
-            s->samples  = AV_RL32(buf + 4);
-            frame_flags = AV_RL32(buf + 8);
-        } else {
-            s->samples  = AV_RL32(buf);
-            frame_flags = AV_RL32(buf + 4);
-        }
-    }
+    s->samples  = AV_RL32(buf + 20);
+    frame_flags = AV_RL32(buf + 24);
     if (s->samples <= 0) {
         av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n",
                s->samples);
@@ -1228,57 +1183,50 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     if (frame_flags & 0x80) {
-        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+        avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
     } else if ((frame_flags & 0x03) <= 1) {
-        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+        avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
     } else {
-        avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+        avctx->sample_fmt          = AV_SAMPLE_FMT_S32P;
         avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3;
     }
 
-    /* get output buffer */
-    s->frame.nb_samples = s->samples;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return ret;
-    }
-
     while (buf_size > 0) {
-        if (!s->multichannel) {
-            frame_size = buf_size;
-        } else {
-            if (!s->mkv_mode) {
-                frame_size = AV_RL32(buf) - 12; buf += 4; buf_size -= 4;
-            } else {
-                if (buf_size < 12) //MKV files can have zero flags after last block
-                    break;
-                frame_size = AV_RL32(buf + 8) + 12;
-            }
-        }
-        if (frame_size < 0 || frame_size > buf_size) {
-            av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d "
-                   "vs. %d bytes left)\n", s->block, frame_size, buf_size);
+        if (buf_size <= WV_HEADER_SIZE)
+            break;
+        frame_size = AV_RL32(buf + 4) - 12;
+        buf       += 20;
+        buf_size  -= 20;
+        if (frame_size <= 0 || frame_size > buf_size) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Block %d has invalid size (size %d vs. %d bytes left)\n",
+                   s->block, frame_size, buf_size);
             wavpack_decode_flush(avctx);
             return AVERROR_INVALIDDATA;
         }
-        if ((samplecount = wavpack_decode_block(avctx, s->block,
-                                                s->frame.data[0], got_frame_ptr,
-                                                buf, frame_size)) < 0) {
+        if ((ret = wavpack_decode_block(avctx, s->block,
+                                        frame, buf, frame_size)) < 0) {
             wavpack_decode_flush(avctx);
-            return samplecount;
+            return ret;
         }
         s->block++;
-        buf += frame_size; buf_size -= frame_size;
+        buf      += frame_size;
+        buf_size -= frame_size;
     }
 
-    if (*got_frame_ptr)
-        *(AVFrame *)data = s->frame;
+    if (s->ch_offset != avctx->channels) {
+        av_log(avctx, AV_LOG_ERROR, "Not enough channels coded in a packet.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    *got_frame_ptr = 1;
 
     return avpkt->size;
 }
 
 AVCodec ff_wavpack_decoder = {
     .name           = "wavpack",
+    .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WAVPACK,
     .priv_data_size = sizeof(WavpackContext),
@@ -1286,6 +1234,5 @@ AVCodec ff_wavpack_decoder = {
     .close          = wavpack_decode_end,
     .decode         = wavpack_decode_frame,
     .flush          = wavpack_decode_flush,
-    .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
+    .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/webp.c b/libavcodec/webp.c
new file mode 100644
index 0000000..f9f8bfc
--- /dev/null
+++ b/libavcodec/webp.c
@@ -0,0 +1,1467 @@
+/*
+ * WebP (.webp) image decoder
+ * Copyright (c) 2013 Aneesh Dogra <aneesh at sugarlabs.org>
+ * Copyright (c) 2013 Justin Ruggles <justin.ruggles at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * WebP image decoder
+ *
+ * @author Aneesh Dogra <aneesh at sugarlabs.org>
+ * Container and Lossy decoding
+ *
+ * @author Justin Ruggles <justin.ruggles at gmail.com>
+ * Lossless decoder
+ * Compressed alpha for lossy
+ *
+ * Unimplemented:
+ *   - Animation
+ *   - ICC profile
+ *   - Exif and XMP metadata
+ */
+
+#define BITSTREAM_READER_LE
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "thread.h"
+#include "vp8.h"
+
+#define VP8X_FLAG_ANIMATION             0x02
+#define VP8X_FLAG_XMP_METADATA          0x04
+#define VP8X_FLAG_EXIF_METADATA         0x08
+#define VP8X_FLAG_ALPHA                 0x10
+#define VP8X_FLAG_ICC                   0x20
+
+#define MAX_PALETTE_SIZE                256
+#define MAX_CACHE_BITS                  11
+#define NUM_CODE_LENGTH_CODES           19
+#define HUFFMAN_CODES_PER_META_CODE     5
+#define NUM_LITERAL_CODES               256
+#define NUM_LENGTH_CODES                24
+#define NUM_DISTANCE_CODES              40
+#define NUM_SHORT_DISTANCES             120
+#define MAX_HUFFMAN_CODE_LENGTH         15
+
+static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE] = {
+    NUM_LITERAL_CODES + NUM_LENGTH_CODES,
+    NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES,
+    NUM_DISTANCE_CODES
+};
+
+static const uint8_t code_length_code_order[NUM_CODE_LENGTH_CODES] = {
+    17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2] = {
+    {  0, 1 }, {  1, 0 }, {  1, 1 }, { -1, 1 }, {  0, 2 }, {  2, 0 }, {  1, 2 }, { -1, 2 },
+    {  2, 1 }, { -2, 1 }, {  2, 2 }, { -2, 2 }, {  0, 3 }, {  3, 0 }, {  1, 3 }, { -1, 3 },
+    {  3, 1 }, { -3, 1 }, {  2, 3 }, { -2, 3 }, {  3, 2 }, { -3, 2 }, {  0, 4 }, {  4, 0 },
+    {  1, 4 }, { -1, 4 }, {  4, 1 }, { -4, 1 }, {  3, 3 }, { -3, 3 }, {  2, 4 }, { -2, 4 },
+    {  4, 2 }, { -4, 2 }, {  0, 5 }, {  3, 4 }, { -3, 4 }, {  4, 3 }, { -4, 3 }, {  5, 0 },
+    {  1, 5 }, { -1, 5 }, {  5, 1 }, { -5, 1 }, {  2, 5 }, { -2, 5 }, {  5, 2 }, { -5, 2 },
+    {  4, 4 }, { -4, 4 }, {  3, 5 }, { -3, 5 }, {  5, 3 }, { -5, 3 }, {  0, 6 }, {  6, 0 },
+    {  1, 6 }, { -1, 6 }, {  6, 1 }, { -6, 1 }, {  2, 6 }, { -2, 6 }, {  6, 2 }, { -6, 2 },
+    {  4, 5 }, { -4, 5 }, {  5, 4 }, { -5, 4 }, {  3, 6 }, { -3, 6 }, {  6, 3 }, { -6, 3 },
+    {  0, 7 }, {  7, 0 }, {  1, 7 }, { -1, 7 }, {  5, 5 }, { -5, 5 }, {  7, 1 }, { -7, 1 },
+    {  4, 6 }, { -4, 6 }, {  6, 4 }, { -6, 4 }, {  2, 7 }, { -2, 7 }, {  7, 2 }, { -7, 2 },
+    {  3, 7 }, { -3, 7 }, {  7, 3 }, { -7, 3 }, {  5, 6 }, { -5, 6 }, {  6, 5 }, { -6, 5 },
+    {  8, 0 }, {  4, 7 }, { -4, 7 }, {  7, 4 }, { -7, 4 }, {  8, 1 }, {  8, 2 }, {  6, 6 },
+    { -6, 6 }, {  8, 3 }, {  5, 7 }, { -5, 7 }, {  7, 5 }, { -7, 5 }, {  8, 4 }, {  6, 7 },
+    { -6, 7 }, {  7, 6 }, { -7, 6 }, {  8, 5 }, {  7, 7 }, { -7, 7 }, {  8, 6 }, {  8, 7 }
+};
+
+enum AlphaCompression {
+    ALPHA_COMPRESSION_NONE,
+    ALPHA_COMPRESSION_VP8L,
+};
+
+enum AlphaFilter {
+    ALPHA_FILTER_NONE,
+    ALPHA_FILTER_HORIZONTAL,
+    ALPHA_FILTER_VERTICAL,
+    ALPHA_FILTER_GRADIENT,
+};
+
+enum TransformType {
+    PREDICTOR_TRANSFORM      = 0,
+    COLOR_TRANSFORM          = 1,
+    SUBTRACT_GREEN           = 2,
+    COLOR_INDEXING_TRANSFORM = 3,
+};
+
+enum PredictionMode {
+    PRED_MODE_BLACK,
+    PRED_MODE_L,
+    PRED_MODE_T,
+    PRED_MODE_TR,
+    PRED_MODE_TL,
+    PRED_MODE_AVG_T_AVG_L_TR,
+    PRED_MODE_AVG_L_TL,
+    PRED_MODE_AVG_L_T,
+    PRED_MODE_AVG_TL_T,
+    PRED_MODE_AVG_T_TR,
+    PRED_MODE_AVG_AVG_L_TL_AVG_T_TR,
+    PRED_MODE_SELECT,
+    PRED_MODE_ADD_SUBTRACT_FULL,
+    PRED_MODE_ADD_SUBTRACT_HALF,
+};
+
+enum HuffmanIndex {
+    HUFF_IDX_GREEN = 0,
+    HUFF_IDX_RED   = 1,
+    HUFF_IDX_BLUE  = 2,
+    HUFF_IDX_ALPHA = 3,
+    HUFF_IDX_DIST  = 4
+};
+
+/* The structure of WebP lossless is an optional series of transformation data,
+ * followed by the primary image. The primary image also optionally contains
+ * an entropy group mapping if there are multiple entropy groups. There is a
+ * basic image type called an "entropy coded image" that is used for all of
+ * these. The type of each entropy coded image is referred to by the
+ * specification as its role. */
+enum ImageRole {
+    /* Primary Image: Stores the actual pixels of the image. */
+    IMAGE_ROLE_ARGB,
+
+    /* Entropy Image: Defines which Huffman group to use for different areas of
+     *                the primary image. */
+    IMAGE_ROLE_ENTROPY,
+
+    /* Predictors: Defines which predictor type to use for different areas of
+     *             the primary image. */
+    IMAGE_ROLE_PREDICTOR,
+
+    /* Color Transform Data: Defines the color transformation for different
+     *                       areas of the primary image. */
+    IMAGE_ROLE_COLOR_TRANSFORM,
+
+    /* Color Index: Stored as an image of height == 1. */
+    IMAGE_ROLE_COLOR_INDEXING,
+
+    IMAGE_ROLE_NB,
+};
+
+typedef struct HuffReader {
+    VLC vlc;                            /* Huffman decoder context */
+    int simple;                         /* whether to use simple mode */
+    int nb_symbols;                     /* number of coded symbols */
+    uint16_t simple_symbols[2];         /* symbols for simple mode */
+} HuffReader;
+
+typedef struct ImageContext {
+    enum ImageRole role;                /* role of this image */
+    AVFrame *frame;                     /* AVFrame for data */
+    int color_cache_bits;               /* color cache size, log2 */
+    uint32_t *color_cache;              /* color cache data */
+    int nb_huffman_groups;              /* number of huffman groups */
+    HuffReader *huffman_groups;         /* reader for each huffman group */
+    int size_reduction;                 /* relative size compared to primary image, log2 */
+    int is_alpha_primary;
+} ImageContext;
+
+typedef struct WebPContext {
+    VP8Context v;                       /* VP8 Context used for lossy decoding */
+    GetBitContext gb;                   /* bitstream reader for main image chunk */
+    AVFrame *alpha_frame;               /* AVFrame for alpha data decompressed from VP8L */
+    AVCodecContext *avctx;              /* parent AVCodecContext */
+    int initialized;                    /* set once the VP8 context is initialized */
+    int has_alpha;                      /* has a separate alpha chunk */
+    enum AlphaCompression alpha_compression; /* compression type for alpha chunk */
+    enum AlphaFilter alpha_filter;      /* filtering method for alpha chunk */
+    uint8_t *alpha_data;                /* alpha chunk data */
+    int alpha_data_size;                /* alpha chunk data size */
+    int width;                          /* image width */
+    int height;                         /* image height */
+    int lossless;                       /* indicates lossless or lossy */
+
+    int nb_transforms;                  /* number of transforms */
+    enum TransformType transforms[4];   /* transformations used in the image, in order */
+    int reduced_width;                  /* reduced width for index image, if applicable */
+    int nb_huffman_groups;              /* number of huffman groups in the primary image */
+    ImageContext image[IMAGE_ROLE_NB];  /* image context for each role */
+} WebPContext;
+
+#define GET_PIXEL(frame, x, y) \
+    ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x))
+
+#define GET_PIXEL_COMP(frame, x, y, c) \
+    (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c))
+
+static void image_ctx_free(ImageContext *img)
+{
+    int i, j;
+
+    av_free(img->color_cache);
+    if (img->role != IMAGE_ROLE_ARGB && !img->is_alpha_primary)
+        av_frame_free(&img->frame);
+    if (img->huffman_groups) {
+        for (i = 0; i < img->nb_huffman_groups; i++) {
+            for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++)
+                ff_free_vlc(&img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE + j].vlc);
+        }
+        av_free(img->huffman_groups);
+    }
+    memset(img, 0, sizeof(*img));
+}
+
+
+/* Differs from get_vlc2() in the following ways:
+ *   - codes are bit-reversed
+ *   - assumes 8-bit table to make reversal simpler
+ *   - assumes max depth of 2 since the max code length for WebP is 15
+ */
+static av_always_inline int webp_get_vlc(GetBitContext *gb, VLC_TYPE (*table)[2])
+{
+    int n, nb_bits;
+    unsigned int index;
+    int code;
+
+    OPEN_READER(re, gb);
+    UPDATE_CACHE(re, gb);
+
+    index = SHOW_UBITS(re, gb, 8);
+    index = ff_reverse[index];
+    code  = table[index][0];
+    n     = table[index][1];
+
+    if (n < 0) {
+        LAST_SKIP_BITS(re, gb, 8);
+        UPDATE_CACHE(re, gb);
+
+        nb_bits = -n;
+
+        index = SHOW_UBITS(re, gb, nb_bits);
+        index = (ff_reverse[index] >> (8 - nb_bits)) + code;
+        code  = table[index][0];
+        n     = table[index][1];
+    }
+    SKIP_BITS(re, gb, n);
+
+    CLOSE_READER(re, gb);
+
+    return code;
+}
+
+static int huff_reader_get_symbol(HuffReader *r, GetBitContext *gb)
+{
+    if (r->simple) {
+        if (r->nb_symbols == 1)
+            return r->simple_symbols[0];
+        else
+            return r->simple_symbols[get_bits1(gb)];
+    } else
+        return webp_get_vlc(gb, r->vlc.table);
+}
+
+static int huff_reader_build_canonical(HuffReader *r, int *code_lengths,
+                                       int alphabet_size)
+{
+    int len = 0, sym, code = 0, ret;
+    int max_code_length = 0;
+    uint16_t *codes;
+
+    /* special-case 1 symbol since the vlc reader cannot handle it */
+    for (sym = 0; sym < alphabet_size; sym++) {
+        if (code_lengths[sym] > 0) {
+            len++;
+            code = sym;
+            if (len > 1)
+                break;
+        }
+    }
+    if (len == 1) {
+        r->nb_symbols = 1;
+        r->simple_symbols[0] = code;
+        r->simple = 1;
+        return 0;
+    }
+
+    for (sym = 0; sym < alphabet_size; sym++)
+        max_code_length = FFMAX(max_code_length, code_lengths[sym]);
+
+    if (max_code_length == 0 || max_code_length > MAX_HUFFMAN_CODE_LENGTH)
+        return AVERROR(EINVAL);
+
+    codes = av_malloc(alphabet_size * sizeof(*codes));
+    if (!codes)
+        return AVERROR(ENOMEM);
+
+    code = 0;
+    r->nb_symbols = 0;
+    for (len = 1; len <= max_code_length; len++) {
+        for (sym = 0; sym < alphabet_size; sym++) {
+            if (code_lengths[sym] != len)
+                continue;
+            codes[sym] = code++;
+            r->nb_symbols++;
+        }
+        code <<= 1;
+    }
+    if (!r->nb_symbols) {
+        av_free(codes);
+        return AVERROR_INVALIDDATA;
+    }
+
+    ret = init_vlc(&r->vlc, 8, alphabet_size,
+                   code_lengths, sizeof(*code_lengths), sizeof(*code_lengths),
+                   codes, sizeof(*codes), sizeof(*codes), 0);
+    if (ret < 0) {
+        av_free(codes);
+        return ret;
+    }
+    r->simple = 0;
+
+    av_free(codes);
+    return 0;
+}
+
+static void read_huffman_code_simple(WebPContext *s, HuffReader *hc)
+{
+    hc->nb_symbols = get_bits1(&s->gb) + 1;
+
+    if (get_bits1(&s->gb))
+        hc->simple_symbols[0] = get_bits(&s->gb, 8);
+    else
+        hc->simple_symbols[0] = get_bits1(&s->gb);
+
+    if (hc->nb_symbols == 2)
+        hc->simple_symbols[1] = get_bits(&s->gb, 8);
+
+    hc->simple = 1;
+}
+
+static int read_huffman_code_normal(WebPContext *s, HuffReader *hc,
+                                    int alphabet_size)
+{
+    HuffReader code_len_hc = { { 0 }, 0, 0, { 0 } };
+    int *code_lengths = NULL;
+    int code_length_code_lengths[NUM_CODE_LENGTH_CODES] = { 0 };
+    int i, symbol, max_symbol, prev_code_len, ret;
+    int num_codes = 4 + get_bits(&s->gb, 4);
+
+    if (num_codes > NUM_CODE_LENGTH_CODES)
+        return AVERROR_INVALIDDATA;
+
+    for (i = 0; i < num_codes; i++)
+        code_length_code_lengths[code_length_code_order[i]] = get_bits(&s->gb, 3);
+
+    ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths,
+                                      NUM_CODE_LENGTH_CODES);
+    if (ret < 0)
+        goto finish;
+
+    code_lengths = av_mallocz_array(alphabet_size, sizeof(*code_lengths));
+    if (!code_lengths) {
+        ret = AVERROR(ENOMEM);
+        goto finish;
+    }
+
+    if (get_bits1(&s->gb)) {
+        int bits   = 2 + 2 * get_bits(&s->gb, 3);
+        max_symbol = 2 + get_bits(&s->gb, bits);
+        if (max_symbol > alphabet_size) {
+            av_log(s->avctx, AV_LOG_ERROR, "max symbol %d > alphabet size %d\n",
+                   max_symbol, alphabet_size);
+            ret = AVERROR_INVALIDDATA;
+            goto finish;
+        }
+    } else {
+        max_symbol = alphabet_size;
+    }
+
+    prev_code_len = 8;
+    symbol        = 0;
+    while (symbol < alphabet_size) {
+        int code_len;
+
+        if (!max_symbol--)
+            break;
+        code_len = huff_reader_get_symbol(&code_len_hc, &s->gb);
+        if (code_len < 16) {
+            /* Code length code [0..15] indicates literal code lengths. */
+            code_lengths[symbol++] = code_len;
+            if (code_len)
+                prev_code_len = code_len;
+        } else {
+            int repeat = 0, length = 0;
+            switch (code_len) {
+            case 16:
+                /* Code 16 repeats the previous non-zero value [3..6] times,
+                 * i.e., 3 + ReadBits(2) times. If code 16 is used before a
+                 * non-zero value has been emitted, a value of 8 is repeated. */
+                repeat = 3 + get_bits(&s->gb, 2);
+                length = prev_code_len;
+                break;
+            case 17:
+                /* Code 17 emits a streak of zeros [3..10], i.e.,
+                 * 3 + ReadBits(3) times. */
+                repeat = 3 + get_bits(&s->gb, 3);
+                break;
+            case 18:
+                /* Code 18 emits a streak of zeros of length [11..138], i.e.,
+                 * 11 + ReadBits(7) times. */
+                repeat = 11 + get_bits(&s->gb, 7);
+                break;
+            }
+            if (symbol + repeat > alphabet_size) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "invalid symbol %d + repeat %d > alphabet size %d\n",
+                       symbol, repeat, alphabet_size);
+                ret = AVERROR_INVALIDDATA;
+                goto finish;
+            }
+            while (repeat-- > 0)
+                code_lengths[symbol++] = length;
+        }
+    }
+
+    ret = huff_reader_build_canonical(hc, code_lengths, alphabet_size);
+
+finish:
+    ff_free_vlc(&code_len_hc.vlc);
+    av_free(code_lengths);
+    return ret;
+}
+
+static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
+                                      int w, int h);
+
+#define PARSE_BLOCK_SIZE(w, h) do {                                         \
+    block_bits = get_bits(&s->gb, 3) + 2;                                   \
+    blocks_w   = FFALIGN((w), 1 << block_bits) >> block_bits;               \
+    blocks_h   = FFALIGN((h), 1 << block_bits) >> block_bits;               \
+} while (0)
+
+static int decode_entropy_image(WebPContext *s)
+{
+    ImageContext *img;
+    int ret, block_bits, width, blocks_w, blocks_h, x, y, max;
+
+    width = s->width;
+    if (s->reduced_width > 0)
+        width = s->reduced_width;
+
+    PARSE_BLOCK_SIZE(width, s->height);
+
+    ret = decode_entropy_coded_image(s, IMAGE_ROLE_ENTROPY, blocks_w, blocks_h);
+    if (ret < 0)
+        return ret;
+
+    img = &s->image[IMAGE_ROLE_ENTROPY];
+    img->size_reduction = block_bits;
+
+    /* the number of huffman groups is determined by the maximum group number
+     * coded in the entropy image */
+    max = 0;
+    for (y = 0; y < img->frame->height; y++) {
+        for (x = 0; x < img->frame->width; x++) {
+            int p = GET_PIXEL_COMP(img->frame, x, y, 2);
+            max = FFMAX(max, p);
+        }
+    }
+    s->nb_huffman_groups = max + 1;
+
+    return 0;
+}
+
+static int parse_transform_predictor(WebPContext *s)
+{
+    int block_bits, blocks_w, blocks_h, ret;
+
+    PARSE_BLOCK_SIZE(s->width, s->height);
+
+    ret = decode_entropy_coded_image(s, IMAGE_ROLE_PREDICTOR, blocks_w,
+                                     blocks_h);
+    if (ret < 0)
+        return ret;
+
+    s->image[IMAGE_ROLE_PREDICTOR].size_reduction = block_bits;
+
+    return 0;
+}
+
+static int parse_transform_color(WebPContext *s)
+{
+    int block_bits, blocks_w, blocks_h, ret;
+
+    PARSE_BLOCK_SIZE(s->width, s->height);
+
+    ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_TRANSFORM, blocks_w,
+                                     blocks_h);
+    if (ret < 0)
+        return ret;
+
+    s->image[IMAGE_ROLE_COLOR_TRANSFORM].size_reduction = block_bits;
+
+    return 0;
+}
+
+static int parse_transform_color_indexing(WebPContext *s)
+{
+    ImageContext *img;
+    int width_bits, index_size, ret, x;
+    uint8_t *ct;
+
+    index_size = get_bits(&s->gb, 8) + 1;
+
+    if (index_size <= 2)
+        width_bits = 3;
+    else if (index_size <= 4)
+        width_bits = 2;
+    else if (index_size <= 16)
+        width_bits = 1;
+    else
+        width_bits = 0;
+
+    ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_INDEXING,
+                                     index_size, 1);
+    if (ret < 0)
+        return ret;
+
+    img = &s->image[IMAGE_ROLE_COLOR_INDEXING];
+    img->size_reduction = width_bits;
+    if (width_bits > 0)
+        s->reduced_width = (s->width + ((1 << width_bits) - 1)) >> width_bits;
+
+    /* color index values are delta-coded */
+    ct  = img->frame->data[0] + 4;
+    for (x = 4; x < img->frame->width * 4; x++, ct++)
+        ct[0] += ct[-4];
+
+    return 0;
+}
+
+static HuffReader *get_huffman_group(WebPContext *s, ImageContext *img,
+                                     int x, int y)
+{
+    ImageContext *gimg = &s->image[IMAGE_ROLE_ENTROPY];
+    int group = 0;
+
+    if (gimg->size_reduction > 0) {
+        int group_x = x >> gimg->size_reduction;
+        int group_y = y >> gimg->size_reduction;
+        group       = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 2);
+    }
+
+    return &img->huffman_groups[group * HUFFMAN_CODES_PER_META_CODE];
+}
+
+static av_always_inline void color_cache_put(ImageContext *img, uint32_t c)
+{
+    uint32_t cache_idx = (0x1E35A7BD * c) >> (32 - img->color_cache_bits);
+    img->color_cache[cache_idx] = c;
+}
+
+static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
+                                      int w, int h)
+{
+    ImageContext *img;
+    HuffReader *hg;
+    int i, j, ret, x, y, width;
+
+    img       = &s->image[role];
+    img->role = role;
+
+    if (!img->frame) {
+        img->frame = av_frame_alloc();
+        if (!img->frame)
+            return AVERROR(ENOMEM);
+    }
+
+    img->frame->format = AV_PIX_FMT_ARGB;
+    img->frame->width  = w;
+    img->frame->height = h;
+
+    if (role == IMAGE_ROLE_ARGB && !img->is_alpha_primary) {
+        ThreadFrame pt = { .f = img->frame };
+        ret = ff_thread_get_buffer(s->avctx, &pt, 0);
+    } else
+        ret = av_frame_get_buffer(img->frame, 1);
+    if (ret < 0)
+        return ret;
+
+    if (get_bits1(&s->gb)) {
+        img->color_cache_bits = get_bits(&s->gb, 4);
+        if (img->color_cache_bits < 1 || img->color_cache_bits > 11) {
+            av_log(s->avctx, AV_LOG_ERROR, "invalid color cache bits: %d\n",
+                   img->color_cache_bits);
+            return AVERROR_INVALIDDATA;
+        }
+        img->color_cache = av_mallocz_array(1 << img->color_cache_bits,
+                                            sizeof(*img->color_cache));
+        if (!img->color_cache)
+            return AVERROR(ENOMEM);
+    } else {
+        img->color_cache_bits = 0;
+    }
+
+    img->nb_huffman_groups = 1;
+    if (role == IMAGE_ROLE_ARGB && get_bits1(&s->gb)) {
+        ret = decode_entropy_image(s);
+        if (ret < 0)
+            return ret;
+        img->nb_huffman_groups = s->nb_huffman_groups;
+    }
+    img->huffman_groups = av_mallocz_array(img->nb_huffman_groups *
+                                           HUFFMAN_CODES_PER_META_CODE,
+                                           sizeof(*img->huffman_groups));
+    if (!img->huffman_groups)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < img->nb_huffman_groups; i++) {
+        hg = &img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE];
+        for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++) {
+            int alphabet_size = alphabet_sizes[j];
+            if (!j && img->color_cache_bits > 0)
+                alphabet_size += 1 << img->color_cache_bits;
+
+            if (get_bits1(&s->gb)) {
+                read_huffman_code_simple(s, &hg[j]);
+            } else {
+                ret = read_huffman_code_normal(s, &hg[j], alphabet_size);
+                if (ret < 0)
+                    return ret;
+            }
+        }
+    }
+
+    width = img->frame->width;
+    if (role == IMAGE_ROLE_ARGB && s->reduced_width > 0)
+        width = s->reduced_width;
+
+    x = 0; y = 0;
+    while (y < img->frame->height) {
+        int v;
+
+        hg = get_huffman_group(s, img, x, y);
+        v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->gb);
+        if (v < NUM_LITERAL_CODES) {
+            /* literal pixel values */
+            uint8_t *p = GET_PIXEL(img->frame, x, y);
+            p[2] = v;
+            p[1] = huff_reader_get_symbol(&hg[HUFF_IDX_RED],   &s->gb);
+            p[3] = huff_reader_get_symbol(&hg[HUFF_IDX_BLUE],  &s->gb);
+            p[0] = huff_reader_get_symbol(&hg[HUFF_IDX_ALPHA], &s->gb);
+            if (img->color_cache_bits)
+                color_cache_put(img, AV_RB32(p));
+            x++;
+            if (x == width) {
+                x = 0;
+                y++;
+            }
+        } else if (v < NUM_LITERAL_CODES + NUM_LENGTH_CODES) {
+            /* LZ77 backwards mapping */
+            int prefix_code, length, distance, ref_x, ref_y;
+
+            /* parse length and distance */
+            prefix_code = v - NUM_LITERAL_CODES;
+            if (prefix_code < 4) {
+                length = prefix_code + 1;
+            } else {
+                int extra_bits = (prefix_code - 2) >> 1;
+                int offset     = 2 + (prefix_code & 1) << extra_bits;
+                length = offset + get_bits(&s->gb, extra_bits) + 1;
+            }
+            prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb);
+            if (prefix_code < 4) {
+                distance = prefix_code + 1;
+            } else {
+                int extra_bits = prefix_code - 2 >> 1;
+                int offset     = 2 + (prefix_code & 1) << extra_bits;
+                distance = offset + get_bits(&s->gb, extra_bits) + 1;
+            }
+
+            /* find reference location */
+            if (distance <= NUM_SHORT_DISTANCES) {
+                int xi = lz77_distance_offsets[distance - 1][0];
+                int yi = lz77_distance_offsets[distance - 1][1];
+                distance = FFMAX(1, xi + yi * width);
+            } else {
+                distance -= NUM_SHORT_DISTANCES;
+            }
+            ref_x = x;
+            ref_y = y;
+            if (distance <= x) {
+                ref_x -= distance;
+                distance = 0;
+            } else {
+                ref_x = 0;
+                distance -= x;
+            }
+            while (distance >= width) {
+                ref_y--;
+                distance -= width;
+            }
+            if (distance > 0) {
+                ref_x = width - distance;
+                ref_y--;
+            }
+            ref_x = FFMAX(0, ref_x);
+            ref_y = FFMAX(0, ref_y);
+
+            /* copy pixels
+             * source and dest regions can overlap and wrap lines, so just
+             * copy per-pixel */
+            for (i = 0; i < length; i++) {
+                uint8_t *p_ref = GET_PIXEL(img->frame, ref_x, ref_y);
+                uint8_t *p     = GET_PIXEL(img->frame,     x,     y);
+
+                AV_COPY32(p, p_ref);
+                if (img->color_cache_bits)
+                    color_cache_put(img, AV_RB32(p));
+                x++;
+                ref_x++;
+                if (x == width) {
+                    x = 0;
+                    y++;
+                }
+                if (ref_x == width) {
+                    ref_x = 0;
+                    ref_y++;
+                }
+                if (y == img->frame->height || ref_y == img->frame->height)
+                    break;
+            }
+        } else {
+            /* read from color cache */
+            uint8_t *p = GET_PIXEL(img->frame, x, y);
+            int cache_idx = v - (NUM_LITERAL_CODES + NUM_LENGTH_CODES);
+
+            if (!img->color_cache_bits) {
+                av_log(s->avctx, AV_LOG_ERROR, "color cache not found\n");
+                return AVERROR_INVALIDDATA;
+            }
+            if (cache_idx >= 1 << img->color_cache_bits) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "color cache index out-of-bounds\n");
+                return AVERROR_INVALIDDATA;
+            }
+            AV_WB32(p, img->color_cache[cache_idx]);
+            x++;
+            if (x == width) {
+                x = 0;
+                y++;
+            }
+        }
+    }
+
+    return 0;
+}
+
+/* PRED_MODE_BLACK */
+static void inv_predict_0(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    AV_WB32(p, 0xFF000000);
+}
+
+/* PRED_MODE_L */
+static void inv_predict_1(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    AV_COPY32(p, p_l);
+}
+
+/* PRED_MODE_T */
+static void inv_predict_2(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    AV_COPY32(p, p_t);
+}
+
+/* PRED_MODE_TR */
+static void inv_predict_3(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    AV_COPY32(p, p_tr);
+}
+
+/* PRED_MODE_TL */
+static void inv_predict_4(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    AV_COPY32(p, p_tl);
+}
+
+/* PRED_MODE_AVG_T_AVG_L_TR */
+static void inv_predict_5(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    p[0] = p_t[0] + (p_l[0] + p_tr[0] >> 1) >> 1;
+    p[1] = p_t[1] + (p_l[1] + p_tr[1] >> 1) >> 1;
+    p[2] = p_t[2] + (p_l[2] + p_tr[2] >> 1) >> 1;
+    p[3] = p_t[3] + (p_l[3] + p_tr[3] >> 1) >> 1;
+}
+
+/* PRED_MODE_AVG_L_TL */
+static void inv_predict_6(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    p[0] = p_l[0] + p_tl[0] >> 1;
+    p[1] = p_l[1] + p_tl[1] >> 1;
+    p[2] = p_l[2] + p_tl[2] >> 1;
+    p[3] = p_l[3] + p_tl[3] >> 1;
+}
+
+/* PRED_MODE_AVG_L_T */
+static void inv_predict_7(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    p[0] = p_l[0] + p_t[0] >> 1;
+    p[1] = p_l[1] + p_t[1] >> 1;
+    p[2] = p_l[2] + p_t[2] >> 1;
+    p[3] = p_l[3] + p_t[3] >> 1;
+}
+
+/* PRED_MODE_AVG_TL_T */
+static void inv_predict_8(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    p[0] = p_tl[0] + p_t[0] >> 1;
+    p[1] = p_tl[1] + p_t[1] >> 1;
+    p[2] = p_tl[2] + p_t[2] >> 1;
+    p[3] = p_tl[3] + p_t[3] >> 1;
+}
+
+/* PRED_MODE_AVG_T_TR */
+static void inv_predict_9(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                          const uint8_t *p_t, const uint8_t *p_tr)
+{
+    p[0] = p_t[0] + p_tr[0] >> 1;
+    p[1] = p_t[1] + p_tr[1] >> 1;
+    p[2] = p_t[2] + p_tr[2] >> 1;
+    p[3] = p_t[3] + p_tr[3] >> 1;
+}
+
+/* PRED_MODE_AVG_AVG_L_TL_AVG_T_TR */
+static void inv_predict_10(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                           const uint8_t *p_t, const uint8_t *p_tr)
+{
+    p[0] = (p_l[0] + p_tl[0] >> 1) + (p_t[0] + p_tr[0] >> 1) >> 1;
+    p[1] = (p_l[1] + p_tl[1] >> 1) + (p_t[1] + p_tr[1] >> 1) >> 1;
+    p[2] = (p_l[2] + p_tl[2] >> 1) + (p_t[2] + p_tr[2] >> 1) >> 1;
+    p[3] = (p_l[3] + p_tl[3] >> 1) + (p_t[3] + p_tr[3] >> 1) >> 1;
+}
+
+/* PRED_MODE_SELECT */
+static void inv_predict_11(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                           const uint8_t *p_t, const uint8_t *p_tr)
+{
+    int diff = (FFABS(p_l[0] - p_tl[0]) - FFABS(p_t[0] - p_tl[0])) +
+               (FFABS(p_l[1] - p_tl[1]) - FFABS(p_t[1] - p_tl[1])) +
+               (FFABS(p_l[2] - p_tl[2]) - FFABS(p_t[2] - p_tl[2])) +
+               (FFABS(p_l[3] - p_tl[3]) - FFABS(p_t[3] - p_tl[3]));
+    if (diff <= 0)
+        AV_COPY32(p, p_t);
+    else
+        AV_COPY32(p, p_l);
+}
+
+/* PRED_MODE_ADD_SUBTRACT_FULL */
+static void inv_predict_12(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                           const uint8_t *p_t, const uint8_t *p_tr)
+{
+    p[0] = av_clip_uint8(p_l[0] + p_t[0] - p_tl[0]);
+    p[1] = av_clip_uint8(p_l[1] + p_t[1] - p_tl[1]);
+    p[2] = av_clip_uint8(p_l[2] + p_t[2] - p_tl[2]);
+    p[3] = av_clip_uint8(p_l[3] + p_t[3] - p_tl[3]);
+}
+
+static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c)
+{
+    int d = a + b >> 1;
+    return av_clip_uint8(d + (d - c) / 2);
+}
+
+/* PRED_MODE_ADD_SUBTRACT_HALF */
+static void inv_predict_13(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+                           const uint8_t *p_t, const uint8_t *p_tr)
+{
+    p[0] = clamp_add_subtract_half(p_l[0], p_t[0], p_tl[0]);
+    p[1] = clamp_add_subtract_half(p_l[1], p_t[1], p_tl[1]);
+    p[2] = clamp_add_subtract_half(p_l[2], p_t[2], p_tl[2]);
+    p[3] = clamp_add_subtract_half(p_l[3], p_t[3], p_tl[3]);
+}
+
+typedef void (*inv_predict_func)(uint8_t *p, const uint8_t *p_l,
+                                 const uint8_t *p_tl, const uint8_t *p_t,
+                                 const uint8_t *p_tr);
+
+static const inv_predict_func inverse_predict[14] = {
+    inv_predict_0,  inv_predict_1,  inv_predict_2,  inv_predict_3,
+    inv_predict_4,  inv_predict_5,  inv_predict_6,  inv_predict_7,
+    inv_predict_8,  inv_predict_9,  inv_predict_10, inv_predict_11,
+    inv_predict_12, inv_predict_13,
+};
+
+static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y)
+{
+    uint8_t *dec, *p_l, *p_tl, *p_t, *p_tr;
+    uint8_t p[4];
+
+    dec  = GET_PIXEL(frame, x,     y);
+    p_l  = GET_PIXEL(frame, x - 1, y);
+    p_tl = GET_PIXEL(frame, x - 1, y - 1);
+    p_t  = GET_PIXEL(frame, x,     y - 1);
+    if (x == frame->width - 1)
+        p_tr = GET_PIXEL(frame, 0, y);
+    else
+        p_tr = GET_PIXEL(frame, x + 1, y - 1);
+
+    inverse_predict[m](p, p_l, p_tl, p_t, p_tr);
+
+    dec[0] += p[0];
+    dec[1] += p[1];
+    dec[2] += p[2];
+    dec[3] += p[3];
+}
+
+static int apply_predictor_transform(WebPContext *s)
+{
+    ImageContext *img  = &s->image[IMAGE_ROLE_ARGB];
+    ImageContext *pimg = &s->image[IMAGE_ROLE_PREDICTOR];
+    int x, y;
+
+    for (y = 0; y < img->frame->height; y++) {
+        for (x = 0; x < img->frame->width; x++) {
+            int tx = x >> pimg->size_reduction;
+            int ty = y >> pimg->size_reduction;
+            enum PredictionMode m = GET_PIXEL_COMP(pimg->frame, tx, ty, 2);
+
+            if (x == 0) {
+                if (y == 0)
+                    m = PRED_MODE_BLACK;
+                else
+                    m = PRED_MODE_T;
+            } else if (y == 0)
+                m = PRED_MODE_L;
+
+            if (m > 13) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "invalid predictor mode: %d\n", m);
+                return AVERROR_INVALIDDATA;
+            }
+            inverse_prediction(img->frame, m, x, y);
+        }
+    }
+    return 0;
+}
+
+static av_always_inline uint8_t color_transform_delta(uint8_t color_pred,
+                                                      uint8_t color)
+{
+    return (int)ff_u8_to_s8(color_pred) * ff_u8_to_s8(color) >> 5;
+}
+
+static int apply_color_transform(WebPContext *s)
+{
+    ImageContext *img, *cimg;
+    int x, y, cx, cy;
+    uint8_t *p, *cp;
+
+    img  = &s->image[IMAGE_ROLE_ARGB];
+    cimg = &s->image[IMAGE_ROLE_COLOR_TRANSFORM];
+
+    for (y = 0; y < img->frame->height; y++) {
+        for (x = 0; x < img->frame->width; x++) {
+            cx = x >> cimg->size_reduction;
+            cy = y >> cimg->size_reduction;
+            cp = GET_PIXEL(cimg->frame, cx, cy);
+            p  = GET_PIXEL(img->frame,   x,  y);
+
+            p[1] += color_transform_delta(cp[3], p[2]);
+            p[3] += color_transform_delta(cp[2], p[2]) +
+                    color_transform_delta(cp[1], p[1]);
+        }
+    }
+    return 0;
+}
+
+static int apply_subtract_green_transform(WebPContext *s)
+{
+    int x, y;
+    ImageContext *img = &s->image[IMAGE_ROLE_ARGB];
+
+    for (y = 0; y < img->frame->height; y++) {
+        for (x = 0; x < img->frame->width; x++) {
+            uint8_t *p = GET_PIXEL(img->frame, x, y);
+            p[1] += p[2];
+            p[3] += p[2];
+        }
+    }
+    return 0;
+}
+
+static int apply_color_indexing_transform(WebPContext *s)
+{
+    ImageContext *img;
+    ImageContext *pal;
+    int i, x, y;
+    uint8_t *p, *pi;
+
+    img = &s->image[IMAGE_ROLE_ARGB];
+    pal = &s->image[IMAGE_ROLE_COLOR_INDEXING];
+
+    if (pal->size_reduction > 0) {
+        GetBitContext gb_g;
+        uint8_t *line;
+        int pixel_bits = 8 >> pal->size_reduction;
+
+        line = av_malloc(img->frame->linesize[0]);
+        if (!line)
+            return AVERROR(ENOMEM);
+
+        for (y = 0; y < img->frame->height; y++) {
+            p = GET_PIXEL(img->frame, 0, y);
+            memcpy(line, p, img->frame->linesize[0]);
+            init_get_bits(&gb_g, line, img->frame->linesize[0] * 8);
+            skip_bits(&gb_g, 16);
+            i = 0;
+            for (x = 0; x < img->frame->width; x++) {
+                p    = GET_PIXEL(img->frame, x, y);
+                p[2] = get_bits(&gb_g, pixel_bits);
+                i++;
+                if (i == 1 << pal->size_reduction) {
+                    skip_bits(&gb_g, 24);
+                    i = 0;
+                }
+            }
+        }
+        av_free(line);
+    }
+
+    for (y = 0; y < img->frame->height; y++) {
+        for (x = 0; x < img->frame->width; x++) {
+            p = GET_PIXEL(img->frame, x, y);
+            i = p[2];
+            if (i >= pal->frame->width) {
+                av_log(s->avctx, AV_LOG_ERROR, "invalid palette index %d\n", i);
+                return AVERROR_INVALIDDATA;
+            }
+            pi = GET_PIXEL(pal->frame, i, 0);
+            AV_COPY32(p, pi);
+        }
+    }
+
+    return 0;
+}
+
+static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p,
+                                     int *got_frame, uint8_t *data_start,
+                                     unsigned int data_size, int is_alpha_chunk)
+{
+    WebPContext *s = avctx->priv_data;
+    int w, h, ret, i;
+
+    if (!is_alpha_chunk) {
+        s->lossless = 1;
+        avctx->pix_fmt = AV_PIX_FMT_ARGB;
+    }
+
+    ret = init_get_bits(&s->gb, data_start, data_size * 8);
+    if (ret < 0)
+        return ret;
+
+    if (!is_alpha_chunk) {
+        if (get_bits(&s->gb, 8) != 0x2F) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless signature\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        w = get_bits(&s->gb, 14) + 1;
+        h = get_bits(&s->gb, 14) + 1;
+        if (s->width && s->width != w) {
+            av_log(avctx, AV_LOG_WARNING, "Width mismatch. %d != %d\n",
+                   s->width, w);
+        }
+        s->width = w;
+        if (s->height && s->height != h) {
+            av_log(avctx, AV_LOG_WARNING, "Height mismatch. %d != %d\n",
+                   s->width, w);
+        }
+        s->height = h;
+
+        ret = ff_set_dimensions(avctx, s->width, s->height);
+        if (ret < 0)
+            return ret;
+
+        s->has_alpha = get_bits1(&s->gb);
+
+        if (get_bits(&s->gb, 3) != 0x0) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless version\n");
+            return AVERROR_INVALIDDATA;
+        }
+    } else {
+        if (!s->width || !s->height)
+            return AVERROR_BUG;
+        w = s->width;
+        h = s->height;
+    }
+
+    /* parse transformations */
+    s->nb_transforms = 0;
+    s->reduced_width = 0;
+    while (get_bits1(&s->gb)) {
+        enum TransformType transform = get_bits(&s->gb, 2);
+        s->transforms[s->nb_transforms++] = transform;
+        switch (transform) {
+        case PREDICTOR_TRANSFORM:
+            ret = parse_transform_predictor(s);
+            break;
+        case COLOR_TRANSFORM:
+            ret = parse_transform_color(s);
+            break;
+        case COLOR_INDEXING_TRANSFORM:
+            ret = parse_transform_color_indexing(s);
+            break;
+        }
+        if (ret < 0)
+            goto free_and_return;
+    }
+
+    /* decode primary image */
+    s->image[IMAGE_ROLE_ARGB].frame = p;
+    if (is_alpha_chunk)
+        s->image[IMAGE_ROLE_ARGB].is_alpha_primary = 1;
+    ret = decode_entropy_coded_image(s, IMAGE_ROLE_ARGB, w, h);
+    if (ret < 0)
+        goto free_and_return;
+
+    /* apply transformations */
+    for (i = s->nb_transforms - 1; i >= 0; i--) {
+        switch (s->transforms[i]) {
+        case PREDICTOR_TRANSFORM:
+            ret = apply_predictor_transform(s);
+            break;
+        case COLOR_TRANSFORM:
+            ret = apply_color_transform(s);
+            break;
+        case SUBTRACT_GREEN:
+            ret = apply_subtract_green_transform(s);
+            break;
+        case COLOR_INDEXING_TRANSFORM:
+            ret = apply_color_indexing_transform(s);
+            break;
+        }
+        if (ret < 0)
+            goto free_and_return;
+    }
+
+    *got_frame   = 1;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
+    ret          = data_size;
+
+free_and_return:
+    for (i = 0; i < IMAGE_ROLE_NB; i++)
+        image_ctx_free(&s->image[i]);
+
+    return ret;
+}
+
+static void alpha_inverse_prediction(AVFrame *frame, enum AlphaFilter m)
+{
+    int x, y, ls;
+    uint8_t *dec;
+
+    ls = frame->linesize[3];
+
+    /* filter first row using horizontal filter */
+    dec = frame->data[3] + 1;
+    for (x = 1; x < frame->width; x++, dec++)
+        *dec += *(dec - 1);
+
+    /* filter first column using vertical filter */
+    dec = frame->data[3] + ls;
+    for (y = 1; y < frame->height; y++, dec += ls)
+        *dec += *(dec - ls);
+
+    /* filter the rest using the specified filter */
+    switch (m) {
+    case ALPHA_FILTER_HORIZONTAL:
+        for (y = 1; y < frame->height; y++) {
+            dec = frame->data[3] + y * ls + 1;
+            for (x = 1; x < frame->width; x++, dec++)
+                *dec += *(dec - 1);
+        }
+        break;
+    case ALPHA_FILTER_VERTICAL:
+        for (y = 1; y < frame->height; y++) {
+            dec = frame->data[3] + y * ls + 1;
+            for (x = 1; x < frame->width; x++, dec++)
+                *dec += *(dec - ls);
+        }
+        break;
+    case ALPHA_FILTER_GRADIENT:
+        for (y = 1; y < frame->height; y++) {
+            dec = frame->data[3] + y * ls + 1;
+            for (x = 1; x < frame->width; x++, dec++)
+                dec[0] += av_clip_uint8(*(dec - 1) + *(dec - ls) - *(dec - ls - 1));
+        }
+        break;
+    }
+}
+
+static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p,
+                                  uint8_t *data_start,
+                                  unsigned int data_size)
+{
+    WebPContext *s = avctx->priv_data;
+    int x, y, ret;
+
+    if (s->alpha_compression == ALPHA_COMPRESSION_NONE) {
+        GetByteContext gb;
+
+        bytestream2_init(&gb, data_start, data_size);
+        for (y = 0; y < s->height; y++)
+            bytestream2_get_buffer(&gb, p->data[3] + p->linesize[3] * y,
+                                   s->width);
+    } else if (s->alpha_compression == ALPHA_COMPRESSION_VP8L) {
+        uint8_t *ap, *pp;
+        int alpha_got_frame = 0;
+
+        s->alpha_frame = av_frame_alloc();
+        if (!s->alpha_frame)
+            return AVERROR(ENOMEM);
+
+        ret = vp8_lossless_decode_frame(avctx, s->alpha_frame, &alpha_got_frame,
+                                        data_start, data_size, 1);
+        if (ret < 0) {
+            av_frame_free(&s->alpha_frame);
+            return ret;
+        }
+        if (!alpha_got_frame) {
+            av_frame_free(&s->alpha_frame);
+            return AVERROR_INVALIDDATA;
+        }
+
+        /* copy green component of alpha image to alpha plane of primary image */
+        for (y = 0; y < s->height; y++) {
+            ap = GET_PIXEL(s->alpha_frame, 0, y) + 2;
+            pp = p->data[3] + p->linesize[3] * y;
+            for (x = 0; x < s->width; x++) {
+                *pp = *ap;
+                pp++;
+                ap += 4;
+            }
+        }
+        av_frame_free(&s->alpha_frame);
+    }
+
+    /* apply alpha filtering */
+    if (s->alpha_filter)
+        alpha_inverse_prediction(p, s->alpha_filter);
+
+    return 0;
+}
+
+static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p,
+                                  int *got_frame, uint8_t *data_start,
+                                  unsigned int data_size)
+{
+    WebPContext *s = avctx->priv_data;
+    AVPacket pkt;
+    int ret;
+
+    if (!s->initialized) {
+        ff_vp8_decode_init(avctx);
+        s->initialized = 1;
+        if (s->has_alpha)
+            avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
+    }
+    s->lossless = 0;
+
+    if (data_size > INT_MAX) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported chunk size\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    av_init_packet(&pkt);
+    pkt.data = data_start;
+    pkt.size = data_size;
+
+    ret = ff_vp8_decode_frame(avctx, p, got_frame, &pkt);
+    if (s->has_alpha) {
+        ret = vp8_lossy_decode_alpha(avctx, p, s->alpha_data,
+                                     s->alpha_data_size);
+        if (ret < 0)
+            return ret;
+    }
+    return ret;
+}
+
+static int webp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+                             AVPacket *avpkt)
+{
+    AVFrame * const p = data;
+    WebPContext *s = avctx->priv_data;
+    GetByteContext gb;
+    int ret;
+    uint32_t chunk_type, chunk_size;
+    int vp8x_flags = 0;
+
+    s->avctx     = avctx;
+    s->width     = 0;
+    s->height    = 0;
+    *got_frame   = 0;
+    s->has_alpha = 0;
+    bytestream2_init(&gb, avpkt->data, avpkt->size);
+
+    if (bytestream2_get_bytes_left(&gb) < 12)
+        return AVERROR_INVALIDDATA;
+
+    if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) {
+        av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    chunk_size = bytestream2_get_le32(&gb);
+    if (bytestream2_get_bytes_left(&gb) < chunk_size)
+        return AVERROR_INVALIDDATA;
+
+    if (bytestream2_get_le32(&gb) != MKTAG('W', 'E', 'B', 'P')) {
+        av_log(avctx, AV_LOG_ERROR, "missing WEBP tag\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    while (bytestream2_get_bytes_left(&gb) > 0) {
+        char chunk_str[5] = { 0 };
+
+        chunk_type = bytestream2_get_le32(&gb);
+        chunk_size = bytestream2_get_le32(&gb);
+        if (chunk_size == UINT32_MAX)
+            return AVERROR_INVALIDDATA;
+        chunk_size += chunk_size & 1;
+
+        if (bytestream2_get_bytes_left(&gb) < chunk_size)
+            return AVERROR_INVALIDDATA;
+
+        switch (chunk_type) {
+        case MKTAG('V', 'P', '8', ' '):
+            if (!*got_frame) {
+                ret = vp8_lossy_decode_frame(avctx, p, got_frame,
+                                             avpkt->data + bytestream2_tell(&gb),
+                                             chunk_size);
+                if (ret < 0)
+                    return ret;
+            }
+            bytestream2_skip(&gb, chunk_size);
+            break;
+        case MKTAG('V', 'P', '8', 'L'):
+            if (!*got_frame) {
+                ret = vp8_lossless_decode_frame(avctx, p, got_frame,
+                                                avpkt->data + bytestream2_tell(&gb),
+                                                chunk_size, 0);
+                if (ret < 0)
+                    return ret;
+            }
+            bytestream2_skip(&gb, chunk_size);
+            break;
+        case MKTAG('V', 'P', '8', 'X'):
+            vp8x_flags = bytestream2_get_byte(&gb);
+            bytestream2_skip(&gb, 3);
+            s->width  = bytestream2_get_le24(&gb) + 1;
+            s->height = bytestream2_get_le24(&gb) + 1;
+            ret = av_image_check_size(s->width, s->height, 0, avctx);
+            if (ret < 0)
+                return ret;
+            break;
+        case MKTAG('A', 'L', 'P', 'H'): {
+            int alpha_header, filter_m, compression;
+
+            if (!(vp8x_flags & VP8X_FLAG_ALPHA)) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "ALPHA chunk present, but alpha bit not set in the "
+                       "VP8X header\n");
+            }
+            if (chunk_size == 0) {
+                av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n");
+                return AVERROR_INVALIDDATA;
+            }
+            alpha_header       = bytestream2_get_byte(&gb);
+            s->alpha_data      = avpkt->data + bytestream2_tell(&gb);
+            s->alpha_data_size = chunk_size - 1;
+            bytestream2_skip(&gb, s->alpha_data_size);
+
+            filter_m    = (alpha_header >> 2) & 0x03;
+            compression =  alpha_header       & 0x03;
+
+            if (compression > ALPHA_COMPRESSION_VP8L) {
+                av_log(avctx, AV_LOG_VERBOSE,
+                       "skipping unsupported ALPHA chunk\n");
+            } else {
+                s->has_alpha         = 1;
+                s->alpha_compression = compression;
+                s->alpha_filter      = filter_m;
+            }
+
+            break;
+        }
+        case MKTAG('I', 'C', 'C', 'P'):
+        case MKTAG('A', 'N', 'I', 'M'):
+        case MKTAG('A', 'N', 'M', 'F'):
+        case MKTAG('E', 'X', 'I', 'F'):
+        case MKTAG('X', 'M', 'P', ' '):
+            AV_WL32(chunk_str, chunk_type);
+            av_log(avctx, AV_LOG_VERBOSE, "skipping unsupported chunk: %s\n",
+                   chunk_str);
+            bytestream2_skip(&gb, chunk_size);
+            break;
+        default:
+            AV_WL32(chunk_str, chunk_type);
+            av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",
+                   chunk_str);
+            bytestream2_skip(&gb, chunk_size);
+            break;
+        }
+    }
+
+    if (!*got_frame) {
+        av_log(avctx, AV_LOG_ERROR, "image data not found\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    return avpkt->size;
+}
+
+static av_cold int webp_decode_close(AVCodecContext *avctx)
+{
+    WebPContext *s = avctx->priv_data;
+
+    if (s->initialized)
+        return ff_vp8_decode_free(avctx);
+
+    return 0;
+}
+
+AVCodec ff_webp_decoder = {
+    .name           = "webp",
+    .long_name      = NULL_IF_CONFIG_SMALL("WebP image"),
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_WEBP,
+    .priv_data_size = sizeof(WebPContext),
+    .decode         = webp_decode_frame,
+    .close          = webp_decode_close,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+};
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index 9808a16..f5ea64a 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "sinewin.h"
 #include "wma.h"
@@ -30,9 +31,9 @@
 
 /* XXX: use same run/length optimization as mpeg decoders */
 //FIXME maybe split decode / encode or pass flag
-static void init_coef_vlc(VLC *vlc, uint16_t **prun_table,
-                          float **plevel_table, uint16_t **pint_table,
-                          const CoefVLCTable *vlc_table)
+static av_cold void init_coef_vlc(VLC *vlc, uint16_t **prun_table,
+                                  float **plevel_table, uint16_t **pint_table,
+                                  const CoefVLCTable *vlc_table)
 {
     int n = vlc_table->n;
     const uint8_t  *table_bits   = vlc_table->huffbits;
@@ -68,7 +69,7 @@ static void init_coef_vlc(VLC *vlc, uint16_t **prun_table,
     av_free(level_table);
 }
 
-int ff_wma_init(AVCodecContext *avctx, int flags2)
+av_cold int ff_wma_init(AVCodecContext *avctx, int flags2)
 {
     WMACodecContext *s = avctx->priv_data;
     int i;
@@ -82,7 +83,6 @@ int ff_wma_init(AVCodecContext *avctx, int flags2)
         || avctx->bit_rate    <= 0)
         return -1;
 
-    ff_dsputil_init(&s->dsp, avctx);
     ff_fmt_convert_init(&s->fmt_conv, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
@@ -304,7 +304,7 @@ int ff_wma_init(AVCodecContext *avctx, int flags2)
     }
 #endif
 
-    /* init MDCT windows : simple sinus window */
+    /* init MDCT windows : simple sine window */
     for (i = 0; i < s->nb_block_sizes; i++) {
         ff_init_ff_sine_windows(s->frame_len_bits - i);
         s->windows[i] = ff_sine_windows[s->frame_len_bits - i];
diff --git a/libavcodec/wma.h b/libavcodec/wma.h
index fb2aa8b..513ba3f 100644
--- a/libavcodec/wma.h
+++ b/libavcodec/wma.h
@@ -25,7 +25,6 @@
 #include "libavutil/float_dsp.h"
 #include "get_bits.h"
 #include "put_bits.h"
-#include "dsputil.h"
 #include "fft.h"
 #include "fmtconvert.h"
 
@@ -66,7 +65,6 @@ typedef struct CoefVLCTable {
 
 typedef struct WMACodecContext {
     AVCodecContext* avctx;
-    AVFrame frame;
     GetBitContext gb;
     PutBitContext pb;
     int version;                            ///< 1 = 0x160 (WMAV1), 2 = 0x161 (WMAV2)
@@ -132,7 +130,6 @@ typedef struct WMACodecContext {
     float lsp_pow_e_table[256];
     float lsp_pow_m_table1[(1 << LSP_POW_BITS)];
     float lsp_pow_m_table2[(1 << LSP_POW_BITS)];
-    DSPContext dsp;
     FmtConvertContext fmt_conv;
     AVFloatDSPContext fdsp;
 
diff --git a/libavcodec/wma_common.h b/libavcodec/wma_common.h
index 3a786c3..61b1a35 100644
--- a/libavcodec/wma_common.h
+++ b/libavcodec/wma_common.h
@@ -21,9 +21,7 @@
 #ifndef AVCODEC_WMA_COMMON_H
 #define AVCODEC_WMA_COMMON_H
 
-#include "libavutil/attributes.h"
-
-av_cold int ff_wma_get_frame_len_bits(int sample_rate, int version,
-                                      unsigned int decode_flags);
+int ff_wma_get_frame_len_bits(int sample_rate, int version,
+                              unsigned int decode_flags);
 
 #endif /* AVCODEC_WMA_COMMON_H */
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index 2f4afd3..2dd5898 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -33,6 +33,7 @@
  * should be 4 extra bytes for v1 data and 6 extra bytes for v2 data.
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "wma.h"
@@ -66,7 +67,7 @@ static void dump_floats(WMACodecContext *s, const char *name, int prec, const fl
 }
 #endif
 
-static int wma_decode_init(AVCodecContext * avctx)
+static av_cold int wma_decode_init(AVCodecContext * avctx)
 {
     WMACodecContext *s = avctx->priv_data;
     int i, flags2;
@@ -115,9 +116,6 @@ static int wma_decode_init(AVCodecContext * avctx)
 
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -146,7 +144,7 @@ static inline float pow_m1_4(WMACodecContext *s, float x)
     return s->lsp_pow_e_table[e] * (a + b * t.f);
 }
 
-static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len)
+static av_cold void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len)
 {
     float wdel, a, b;
     int i, e, m;
@@ -384,16 +382,16 @@ static void wma_window(WMACodecContext *s, float *out)
         block_len = s->block_len;
         bsize = s->frame_len_bits - s->block_len_bits;
 
-        s->dsp.vector_fmul_add(out, in, s->windows[bsize],
-                               out, block_len);
+        s->fdsp.vector_fmul_add(out, in, s->windows[bsize],
+                                out, block_len);
 
     } else {
         block_len = 1 << s->prev_block_len_bits;
         n = (s->block_len - block_len) / 2;
         bsize = s->frame_len_bits - s->prev_block_len_bits;
 
-        s->dsp.vector_fmul_add(out+n, in+n, s->windows[bsize],
-                               out+n, block_len);
+        s->fdsp.vector_fmul_add(out+n, in+n, s->windows[bsize],
+                                out+n, block_len);
 
         memcpy(out+n+block_len, in+n+block_len, n*sizeof(float));
     }
@@ -406,7 +404,7 @@ static void wma_window(WMACodecContext *s, float *out)
         block_len = s->block_len;
         bsize = s->frame_len_bits - s->block_len_bits;
 
-        s->dsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len);
+        s->fdsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len);
 
     } else {
         block_len = 1 << s->next_block_len_bits;
@@ -415,7 +413,7 @@ static void wma_window(WMACodecContext *s, float *out)
 
         memcpy(out, in, n*sizeof(float));
 
-        s->dsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len);
+        s->fdsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len);
 
         memset(out+n+block_len, 0, n*sizeof(float));
     }
@@ -724,7 +722,7 @@ static int wma_decode_block(WMACodecContext *s)
             s->channel_coded[0] = 1;
         }
 
-        s->dsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len);
+        s->fdsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len);
     }
 
 next:
@@ -793,6 +791,7 @@ static int wma_decode_frame(WMACodecContext *s, float **samples,
 static int wma_decode_superframe(AVCodecContext *avctx, void *data,
                                  int *got_frame_ptr, AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     WMACodecContext *s = avctx->priv_data;
@@ -826,12 +825,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    s->frame.nb_samples = nb_frames * s->frame_len;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = nb_frames * s->frame_len;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples = (float **)s->frame.extended_data;
+    samples = (float **)frame->extended_data;
     samples_offset = 0;
 
     if (s->use_bit_reservoir) {
@@ -910,8 +909,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data,
             s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len,
             (int8_t *)samples - (int8_t *)data, avctx->block_align);
 
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    *got_frame_ptr = 1;
 
     return avctx->block_align;
  fail:
@@ -930,6 +928,7 @@ static av_cold void flush(AVCodecContext *avctx)
 
 AVCodec ff_wmav1_decoder = {
     .name           = "wmav1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WMAV1,
     .priv_data_size = sizeof(WMACodecContext),
@@ -938,13 +937,13 @@ AVCodec ff_wmav1_decoder = {
     .decode         = wma_decode_superframe,
     .flush          = flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
 
 AVCodec ff_wmav2_decoder = {
     .name           = "wmav2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WMAV2,
     .priv_data_size = sizeof(WMACodecContext),
@@ -953,7 +952,6 @@ AVCodec ff_wmav2_decoder = {
     .decode         = wma_decode_superframe,
     .flush          = flush,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c
index 044114b..899cae0 100644
--- a/libavcodec/wmaenc.c
+++ b/libavcodec/wmaenc.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "wma.h"
@@ -27,7 +28,8 @@
 #include <assert.h>
 
 
-static int encode_init(AVCodecContext * avctx){
+static av_cold int encode_init(AVCodecContext *avctx)
+{
     WMACodecContext *s = avctx->priv_data;
     int i, flags1, flags2, block_align;
     uint8_t *extradata;
@@ -88,11 +90,6 @@ static int encode_init(AVCodecContext * avctx){
                          s->frame_len;
     avctx->frame_size = avctx->delay = s->frame_len;
 
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = &s->frame;
-    avcodec_get_frame_defaults(avctx->coded_frame);
-#endif
-
     return 0;
 }
 
@@ -112,7 +109,7 @@ static void apply_window_and_mdct(AVCodecContext * avctx, const AVFrame *frame)
     for (ch = 0; ch < avctx->channels; ch++) {
         memcpy(s->output, s->frame_out[ch], window_len * sizeof(*s->output));
         s->fdsp.vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len);
-        s->dsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], win, len);
+        s->fdsp.vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], win, len);
         s->fdsp.vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len);
         mdct->mdct_calc(mdct, s->coefs[ch], s->output);
     }
@@ -420,6 +417,7 @@ static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt,
 
 AVCodec ff_wmav1_encoder = {
     .name           = "wmav1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WMAV1,
     .priv_data_size = sizeof(WMACodecContext),
@@ -428,11 +426,11 @@ AVCodec ff_wmav1_encoder = {
     .close          = ff_wma_end,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
 };
 
 AVCodec ff_wmav2_encoder = {
     .name           = "wmav2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WMAV2,
     .priv_data_size = sizeof(WMACodecContext),
@@ -441,5 +439,4 @@ AVCodec ff_wmav2_encoder = {
     .close          = ff_wma_end,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
 };
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index 747ac37..2f341c0 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -66,7 +66,7 @@ typedef struct {
 typedef struct WmallDecodeCtx {
     /* generic decoder variables */
     AVCodecContext  *avctx;
-    AVFrame         frame;
+    AVFrame         *frame;
     uint8_t         frame_data[MAX_FRAMESIZE + FF_INPUT_BUFFER_PADDING_SIZE];  ///< compressed frame data
     PutBitContext   pb;                             ///< context for filling the frame_data buffer
 
@@ -189,7 +189,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
             avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
         else if (s->bits_per_sample == 24) {
             avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
-            av_log_missing_feature(avctx, "Bit-depth higher than 16", 0);
+            avpriv_report_missing_feature(avctx, "Bit-depth higher than 16");
             return AVERROR_PATCHWELCOME;
         } else {
             av_log(avctx, AV_LOG_ERROR, "Unknown bit-depth: %d\n",
@@ -202,7 +202,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
         av_dlog(avctx, "\n");
 
     } else {
-        av_log_ask_for_sample(avctx, "Unsupported extradata size\n");
+        avpriv_request_sample(avctx, "Unsupported extradata size");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -256,12 +256,15 @@ static av_cold int decode_init(AVCodecContext *avctx)
                s->num_channels);
         return AVERROR_INVALIDDATA;
     } else if (s->num_channels > WMALL_MAX_CHANNELS) {
-        av_log_ask_for_sample(avctx, "unsupported number of channels\n");
+        avpriv_request_sample(avctx,
+                              "More than %d channels", WMALL_MAX_CHANNELS);
         return AVERROR_PATCHWELCOME;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame    = &s->frame;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     avctx->channel_layout = channel_mask;
     return 0;
 }
@@ -885,7 +888,7 @@ static int decode_subframe(WmallDecodeCtx *s)
 
         s->do_arith_coding    = get_bits1(&s->gb);
         if (s->do_arith_coding) {
-            av_log_missing_feature(s->avctx, "Arithmetic coding", 1);
+            avpriv_request_sample(s->avctx, "Arithmetic coding");
             return AVERROR_PATCHWELCOME;
         }
         s->do_ac_filter       = get_bits1(&s->gb);
@@ -907,7 +910,7 @@ static int decode_subframe(WmallDecodeCtx *s)
     } else if (!s->cdlms[0][0].order) {
         av_log(s->avctx, AV_LOG_DEBUG,
                "Waiting for seekable tile\n");
-        s->frame.nb_samples = 0;
+        av_frame_unref(s->frame);
         return -1;
     }
 
@@ -925,8 +928,8 @@ static int decode_subframe(WmallDecodeCtx *s)
             s->do_lpc = get_bits1(&s->gb);
             if (s->do_lpc) {
                 decode_lpc(s);
-                av_log_ask_for_sample(s->avctx, "Inverse LPC filter not "
-                                      "implemented. Expect wrong output.\n");
+                avpriv_request_sample(s->avctx, "Expect wrong output since "
+                                      "inverse LPC filter");
             }
         } else
             s->do_lpc = 0;
@@ -1014,8 +1017,8 @@ static int decode_frame(WmallDecodeCtx *s)
     GetBitContext* gb = &s->gb;
     int more_frames = 0, len = 0, i, ret;
 
-    s->frame.nb_samples = s->samples_per_frame;
-    if ((ret = ff_get_buffer(s->avctx, &s->frame)) < 0) {
+    s->frame->nb_samples = s->samples_per_frame;
+    if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) {
         /* return an error if no frame could be decoded at all */
         av_log(s->avctx, AV_LOG_ERROR,
                "not enough space for the output samples\n");
@@ -1023,8 +1026,8 @@ static int decode_frame(WmallDecodeCtx *s)
         return ret;
     }
     for (i = 0; i < s->num_channels; i++) {
-        s->samples_16[i] = (int16_t *)s->frame.extended_data[i];
-        s->samples_32[i] = (int32_t *)s->frame.extended_data[i];
+        s->samples_16[i] = (int16_t *)s->frame->extended_data[i];
+        s->samples_32[i] = (int32_t *)s->frame->extended_data[i];
     }
 
     /* get frame length */
@@ -1137,7 +1140,7 @@ static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len,
     buflen = (s->num_saved_bits + len + 8) >> 3;
 
     if (len <= 0 || buflen > MAX_FRAMESIZE) {
-        av_log_ask_for_sample(s->avctx, "input buffer too small\n");
+        avpriv_request_sample(s->avctx, "Too small input buffer");
         s->packet_loss = 1;
         return;
     }
@@ -1171,7 +1174,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr,
     int buf_size       = avpkt->size;
     int num_bits_prev_frame, packet_sequence_number, spliced_packet;
 
-    s->frame.nb_samples = 0;
+    s->frame->nb_samples = 0;
 
     if (s->packet_done || s->packet_loss) {
         s->packet_done = 0;
@@ -1190,7 +1193,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr,
         skip_bits(gb, 1);   // Skip seekable_frame_in_packet, currently ununused
         spliced_packet = get_bits1(gb);
         if (spliced_packet)
-            av_log_missing_feature(avctx, "Bitstream splicing", 1);
+            avpriv_request_sample(avctx, "Bitstream splicing");
 
         /* get number of bits that need to be added to the previous frame */
         num_bits_prev_frame = get_bits(gb, s->log2_frame_size);
@@ -1264,8 +1267,9 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr,
         save_bits(s, gb, remaining_bits(s, gb), 0);
     }
 
-    *(AVFrame *)data = s->frame;
-    *got_frame_ptr   = s->frame.nb_samples > 0;
+    *got_frame_ptr   = s->frame->nb_samples > 0;
+    av_frame_move_ref(data, s->frame);
+
     s->packet_offset = get_bits_count(gb) & 7;
 
     return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3;
@@ -1280,20 +1284,30 @@ static void flush(AVCodecContext *avctx)
     s->frame_offset      = 0;
     s->next_packet_start = 0;
     s->cdlms[0][0].order = 0;
-    s->frame.nb_samples  = 0;
+    s->frame->nb_samples = 0;
     init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
 }
 
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+    WmallDecodeCtx *s = avctx->priv_data;
+
+    av_frame_free(&s->frame);
+
+    return 0;
+}
+
 AVCodec ff_wmalossless_decoder = {
     .name           = "wmalossless",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WMALOSSLESS,
     .priv_data_size = sizeof(WmallDecodeCtx),
     .init           = decode_init,
+    .close          = decode_close,
     .decode         = decode_packet,
     .flush          = flush,
     .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1 | CODEC_CAP_DELAY,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                       AV_SAMPLE_FMT_S32P,
                                                       AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index ed9c6d3..2657a0e 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -94,7 +94,6 @@
 #include "get_bits.h"
 #include "put_bits.h"
 #include "wmaprodata.h"
-#include "dsputil.h"
 #include "sinewin.h"
 #include "wma.h"
 #include "wma_common.h"
@@ -126,7 +125,7 @@ static VLC              vec4_vlc;         ///< 4 coefficients per symbol
 static VLC              vec2_vlc;         ///< 2 coefficients per symbol
 static VLC              vec1_vlc;         ///< 1 coefficient per symbol
 static VLC              coef_vlc[2];      ///< coefficient run length vlc codes
-static float            sin64[33];        ///< sinus table for decorrelation
+static float            sin64[33];        ///< sine table for decorrelation
 
 /**
  * @brief frame specific decoder context for a single channel
@@ -170,8 +169,6 @@ typedef struct {
 typedef struct WMAProDecodeCtx {
     /* generic decoder variables */
     AVCodecContext*  avctx;                         ///< codec context for av_log
-    AVFrame          frame;                         ///< AVFrame for decoded output
-    DSPContext       dsp;                           ///< accelerated DSP functions
     AVFloatDSPContext fdsp;
     uint8_t          frame_data[MAX_FRAMESIZE +
                       FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data
@@ -287,7 +284,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     }
 
     s->avctx = avctx;
-    ff_dsputil_init(&s->dsp, avctx);
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
@@ -304,7 +300,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
         av_dlog(avctx, "\n");
 
     } else {
-        av_log_ask_for_sample(avctx, "Unknown extradata size\n");
+        avpriv_request_sample(avctx, "Unknown extradata size");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -319,7 +315,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     /** get frame len */
     bits = ff_wma_get_frame_len_bits(avctx->sample_rate, 3, s->decode_flags);
     if (bits > WMAPRO_BLOCK_MAX_BITS) {
-        av_log_missing_feature(avctx, "14-bits block sizes", 1);
+        avpriv_request_sample(avctx, "14-bit block sizes");
         return AVERROR_PATCHWELCOME;
     }
     s->samples_per_frame = 1 << bits;
@@ -357,7 +353,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
                avctx->channels);
         return AVERROR_INVALIDDATA;
     } else if (avctx->channels > WMAPRO_MAX_CHANNELS) {
-        av_log_ask_for_sample(avctx, "unsupported number of channels\n");
+        avpriv_request_sample(avctx,
+                              "More than %d channels", WMAPRO_MAX_CHANNELS);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -452,7 +449,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
                      1.0 / (1 << (WMAPRO_BLOCK_MIN_BITS + i - 1))
                      / (1 << (s->bits_per_sample - 1)));
 
-    /** init MDCT windows: simple sinus window */
+    /** init MDCT windows: simple sine window */
     for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) {
         const int win_idx = WMAPRO_BLOCK_MAX_BITS - i;
         ff_init_ff_sine_windows(win_idx);
@@ -476,9 +473,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     avctx->channel_layout = channel_mask;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -691,8 +685,8 @@ static int decode_channel_transform(WMAProDecodeCtx* s)
         int remaining_channels = s->channels_for_cur_subframe;
 
         if (get_bits1(&s->gb)) {
-            av_log_ask_for_sample(s->avctx,
-                                  "unsupported channel transform bit\n");
+            avpriv_request_sample(s->avctx,
+                                  "Channel transform bit");
             return AVERROR_PATCHWELCOME;
         }
 
@@ -728,8 +722,8 @@ static int decode_channel_transform(WMAProDecodeCtx* s)
             if (chgroup->num_channels == 2) {
                 if (get_bits1(&s->gb)) {
                     if (get_bits1(&s->gb)) {
-                        av_log_ask_for_sample(s->avctx,
-                                              "unsupported channel transform type\n");
+                        avpriv_request_sample(s->avctx,
+                                              "Unknown channel transform type");
                         return AVERROR_PATCHWELCOME;
                     }
                 } else {
@@ -755,8 +749,8 @@ static int decode_channel_transform(WMAProDecodeCtx* s)
                     } else {
                         /** FIXME: more than 6 coupled channels not supported */
                         if (chgroup->num_channels > 6) {
-                            av_log_ask_for_sample(s->avctx,
-                                                  "coupled channels > 6\n");
+                            avpriv_request_sample(s->avctx,
+                                                  "Coupled channels > 6");
                         } else {
                             memcpy(chgroup->decorrelation_matrix,
                                    default_decorrelation[chgroup->num_channels],
@@ -1060,8 +1054,8 @@ static void wmapro_window(WMAProDecodeCtx *s)
 
         winlen >>= 1;
 
-        s->dsp.vector_fmul_window(start, start, start + winlen,
-                                  window, winlen);
+        s->fdsp.vector_fmul_window(start, start, start + winlen,
+                                   window, winlen);
 
         s->channel[c].prev_block_len = s->subframe_len;
     }
@@ -1164,7 +1158,7 @@ static int decode_subframe(WMAProDecodeCtx *s)
 
     /** no idea for what the following bit is used */
     if (get_bits1(&s->gb)) {
-        av_log_ask_for_sample(s->avctx, "reserved bit set\n");
+        avpriv_request_sample(s->avctx, "Reserved bit");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -1310,7 +1304,7 @@ static int decode_subframe(WMAProDecodeCtx *s)
  *@return 0 if the trailer bit indicates that this is the last frame,
  *        1 if there are additional frames
  */
-static int decode_frame(WMAProDecodeCtx *s, int *got_frame_ptr)
+static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr)
 {
     AVCodecContext *avctx = s->avctx;
     GetBitContext* gb = &s->gb;
@@ -1383,8 +1377,8 @@ static int decode_frame(WMAProDecodeCtx *s, int *got_frame_ptr)
     }
 
     /* get output buffer */
-    s->frame.nb_samples = s->samples_per_frame;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->samples_per_frame;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         s->packet_loss = 1;
         return 0;
@@ -1392,7 +1386,7 @@ static int decode_frame(WMAProDecodeCtx *s, int *got_frame_ptr)
 
     /** copy samples to the output buffer */
     for (i = 0; i < avctx->channels; i++)
-        memcpy(s->frame.extended_data[i], s->channel[i].out,
+        memcpy(frame->extended_data[i], s->channel[i].out,
                s->samples_per_frame * sizeof(*s->channel[i].out));
 
     for (i = 0; i < avctx->channels; i++) {
@@ -1405,6 +1399,7 @@ static int decode_frame(WMAProDecodeCtx *s, int *got_frame_ptr)
     if (s->skip_frame) {
         s->skip_frame = 0;
         *got_frame_ptr = 0;
+        av_frame_unref(frame);
     } else {
         *got_frame_ptr = 1;
     }
@@ -1469,7 +1464,7 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
     buflen = (s->num_saved_bits + len + 8) >> 3;
 
     if (len <= 0 || buflen > MAX_FRAMESIZE) {
-        av_log_ask_for_sample(s->avctx, "input buffer too small\n");
+        avpriv_request_sample(s->avctx, "Too small input buffer");
         s->packet_loss = 1;
         return;
     }
@@ -1571,7 +1566,7 @@ static int decode_packet(AVCodecContext *avctx, void *data,
 
             /** decode the cross packet frame if it is valid */
             if (!s->packet_loss)
-                decode_frame(s, got_frame_ptr);
+                decode_frame(s, data, got_frame_ptr);
         } else if (s->num_saved_bits - s->frame_offset) {
             av_dlog(avctx, "ignoring %x previously saved bits\n",
                     s->num_saved_bits - s->frame_offset);
@@ -1594,7 +1589,7 @@ static int decode_packet(AVCodecContext *avctx, void *data,
             (frame_size = show_bits(gb, s->log2_frame_size)) &&
             frame_size <= remaining_bits(s, gb)) {
             save_bits(s, gb, frame_size, 0);
-            s->packet_done = !decode_frame(s, got_frame_ptr);
+            s->packet_done = !decode_frame(s, data, got_frame_ptr);
         } else if (!s->len_prefix
                    && s->num_saved_bits > get_bits_count(&s->gb)) {
             /** when the frames do not have a length prefix, we don't know
@@ -1604,7 +1599,7 @@ static int decode_packet(AVCodecContext *avctx, void *data,
                 therefore we save the incoming packet first, then we append
                 the "previous frame" data from the next packet so that
                 we get a buffer that only contains full frames */
-            s->packet_done = !decode_frame(s, got_frame_ptr);
+            s->packet_done = !decode_frame(s, data, got_frame_ptr);
         } else
             s->packet_done = 1;
     }
@@ -1620,9 +1615,6 @@ static int decode_packet(AVCodecContext *avctx, void *data,
     if (s->packet_loss)
         return AVERROR_INVALIDDATA;
 
-    if (*got_frame_ptr)
-        *(AVFrame *)data = s->frame;
-
     return get_bits_count(gb) >> 3;
 }
 
@@ -1648,6 +1640,7 @@ static void flush(AVCodecContext *avctx)
  */
 AVCodec ff_wmapro_decoder = {
     .name           = "wmapro",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WMAPRO,
     .priv_data_size = sizeof(WMAProDecodeCtx),
@@ -1656,7 +1649,6 @@ AVCodec ff_wmapro_decoder = {
     .decode         = decode_packet,
     .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
     .flush          = flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
index e0b7f5b..0d91077 100644
--- a/libavcodec/wmavoice.c
+++ b/libavcodec/wmavoice.c
@@ -30,8 +30,8 @@
 #include <math.h>
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
 #include "libavutil/mem.h"
-#include "dsputil.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
@@ -136,7 +136,6 @@ typedef struct {
      * @name Global values specified in the stream header / extradata or used all over.
      * @{
      */
-    AVFrame frame;
     GetBitContext gb;             ///< packet bitreader. During decoder init,
                                   ///< it contains the extradata from the
                                   ///< demuxer. During decoding, it contains
@@ -306,6 +305,20 @@ typedef struct {
  */
 static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25])
 {
+    int cntr[8] = { 0 }, n, res;
+
+    memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25);
+    for (n = 0; n < 17; n++) {
+        res = get_bits(gb, 3);
+        if (cntr[res] > 3) // should be >= 3 + (res == 7))
+            return -1;
+        vbm_tree[res * 3 + cntr[res]++] = n;
+    }
+    return 0;
+}
+
+static av_cold void wmavoice_init_static_data(AVCodec *codec)
+{
     static const uint8_t bits[] = {
          2,  2,  2,  4,  4,  4,
          6,  6,  6,  8,  8,  8,
@@ -321,18 +334,9 @@ static av_cold int decode_vbmtree(GetBitContext *gb, int8_t vbm_tree[25])
           0x0ffc, 0x0ffd, 0x0ffe,        //   1111111111+00/01/10
           0x3ffc, 0x3ffd, 0x3ffe, 0x3fff // 111111111111+xx
     };
-    int cntr[8] = { 0 }, n, res;
 
-    memset(vbm_tree, 0xff, sizeof(vbm_tree[0]) * 25);
-    for (n = 0; n < 17; n++) {
-        res = get_bits(gb, 3);
-        if (cntr[res] > 3) // should be >= 3 + (res == 7))
-            return -1;
-        vbm_tree[res * 3 + cntr[res]++] = n;
-    }
     INIT_VLC_STATIC(&frame_type_vlc, VLC_NBITS, sizeof(bits),
                     bits, 1, 1, codes, 2, 2, 132);
-    return 0;
 }
 
 /**
@@ -355,7 +359,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
         av_log(ctx, AV_LOG_ERROR,
                "Invalid extradata size %d (should be 46)\n",
                ctx->extradata_size);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     flags                = AV_RL32(ctx->extradata + 18);
     s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align);
@@ -378,7 +382,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
         av_log(ctx, AV_LOG_ERROR,
                "Invalid denoise filter strength %d (max=11)\n",
                s->denoise_strength);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->denoise_tilt_corr = !!(flags & 0x40);
     s->dc_level          =   (flags >> 7) & 0xF;
@@ -400,7 +404,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
     init_get_bits(&s->gb, ctx->extradata + 22, (ctx->extradata_size - 22) << 3);
     if (decode_vbmtree(&s->gb, s->vbm_tree) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid VBM tree; broken extradata?\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     s->min_pitch_val    = ((ctx->sample_rate << 8)      /  400 + 50) >> 8;
@@ -408,7 +412,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
     pitch_range         = s->max_pitch_val - s->min_pitch_val;
     if (pitch_range <= 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid pitch range; broken extradata?\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->pitch_nbits      = av_ceil_log2(pitch_range);
     s->last_pitch_val   = 40;
@@ -423,7 +427,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
                "Unsupported samplerate %d (min=%d, max=%d)\n",
                ctx->sample_rate, min_sr, max_sr); // 322-22097 Hz
 
-        return -1;
+        return AVERROR(ENOSYS);
     }
 
     s->block_conv_table[0]      = s->min_pitch_val;
@@ -433,7 +437,7 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
     s->block_delta_pitch_hrange = (pitch_range >> 3) & ~0xF;
     if (s->block_delta_pitch_hrange <= 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid delta pitch hrange; broken extradata?\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->block_delta_pitch_nbits  = 1 + av_ceil_log2(s->block_delta_pitch_hrange);
     s->block_pitch_range        = s->block_conv_table[2] +
@@ -445,9 +449,6 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx)
     ctx->channel_layout         = AV_CH_LAYOUT_MONO;
     ctx->sample_fmt             = AV_SAMPLE_FMT_FLT;
 
-    avcodec_get_frame_defaults(&s->frame);
-    ctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -523,7 +524,7 @@ static int kalman_smoothen(WMAVoiceContext *s, int pitch,
 
     /* find best fitting point in history */
     do {
-        dot = ff_scalarproduct_float_c(in, ptr, size);
+        dot = avpriv_scalarproduct_float_c(in, ptr, size);
         if (dot > optimal_gain) {
             optimal_gain  = dot;
             best_hist_ptr = ptr;
@@ -532,7 +533,7 @@ static int kalman_smoothen(WMAVoiceContext *s, int pitch,
 
     if (optimal_gain <= 0)
         return -1;
-    dot = ff_scalarproduct_float_c(best_hist_ptr, best_hist_ptr, size);
+    dot = avpriv_scalarproduct_float_c(best_hist_ptr, best_hist_ptr, size);
     if (dot <= 0) // would be 1.0
         return -1;
 
@@ -562,8 +563,8 @@ static float tilt_factor(const float *lpcs, int n_lpcs)
 {
     float rh0, rh1;
 
-    rh0 = 1.0     + ff_scalarproduct_float_c(lpcs,  lpcs,    n_lpcs);
-    rh1 = lpcs[0] + ff_scalarproduct_float_c(lpcs, &lpcs[1], n_lpcs - 1);
+    rh0 = 1.0     + avpriv_scalarproduct_float_c(lpcs,  lpcs,    n_lpcs);
+    rh1 = lpcs[0] + avpriv_scalarproduct_float_c(lpcs, &lpcs[1], n_lpcs - 1);
 
     return rh1 / rh0;
 }
@@ -611,7 +612,7 @@ static void calc_input_response(WMAVoiceContext *s, float *lpcs,
 
         /* 70.57 =~ 1/log10(1.0331663) */
         idx = (pwr * gain_mul - 0.0295) * 70.570526123;
-        if (idx > 127) { // fallback if index falls outside table range
+        if (idx > 127) { // fall back if index falls outside table range
             coeffs[n] = wmavoice_energy_table[127] *
                         powf(1.0331663, idx - 127);
         } else
@@ -619,7 +620,7 @@ static void calc_input_response(WMAVoiceContext *s, float *lpcs,
     }
 
     /* calculate the Hilbert transform of the gains, which we do (since this
-     * is a sinus input) by doing a phase shift (in theory, H(sin())=cos()).
+     * is a sine input) by doing a phase shift (in theory, H(sin())=cos()).
      * Hilbert_Transform(RDFT(x)) = Laplace_Transform(x), which calculates the
      * "moment" of the LPCs in this filter. */
     s->dct.dct_calc(&s->dct, lpcs);
@@ -656,7 +657,8 @@ static void calc_input_response(WMAVoiceContext *s, float *lpcs,
                              -1.8 * tilt_factor(coeffs, remainder - 1),
                              coeffs, remainder);
     }
-    sq = (1.0 / 64.0) * sqrtf(1 / ff_scalarproduct_float_c(coeffs, coeffs, remainder));
+    sq = (1.0 / 64.0) * sqrtf(1 / avpriv_scalarproduct_float_c(coeffs, coeffs,
+                                                               remainder));
     for (n = 0; n < remainder; n++)
         coeffs[n] *= sq;
 }
@@ -1333,7 +1335,8 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb,
     /* Calculate gain for adaptive & fixed codebook signal.
      * see ff_amr_set_fixed_gain(). */
     idx = get_bits(gb, 7);
-    fcb_gain = expf(ff_scalarproduct_float_c(s->gain_pred_err, gain_coeff, 6) -
+    fcb_gain = expf(avpriv_scalarproduct_float_c(s->gain_pred_err,
+                                                 gain_coeff, 6) -
                     5.2409161640 + wmavoice_gain_codebook_fcb[idx]);
     acb_gain = wmavoice_gain_codebook_acb[idx];
     pred_err = av_clipf(wmavoice_gain_codebook_fcb[idx],
@@ -1462,7 +1465,7 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx,
     if (bd_idx < 0) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid frame type VLC code, skipping\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     block_nsamples = MAX_FRAMESIZE / frame_descs[bd_idx].n_blocks;
@@ -1659,7 +1662,7 @@ static void stabilize_lsps(double *lsps, int num)
  *                does not modify the state of the bitreader; it
  *                only uses it to copy the current stream position
  * @param s WMA Voice decoding context private data
- * @return -1 if unsupported, 1 on not enough bits or 0 if OK.
+ * @return < 0 on error, 1 on not enough bits or 0 if OK.
  */
 static int check_bits_for_superframe(GetBitContext *orig_gb,
                                      WMAVoiceContext *s)
@@ -1677,7 +1680,7 @@ static int check_bits_for_superframe(GetBitContext *orig_gb,
     if (get_bits_left(gb) < 14)
         return 1;
     if (!get_bits1(gb))
-        return -1;                        // WMAPro-in-WMAVoice superframe
+        return AVERROR(ENOSYS);           // WMAPro-in-WMAVoice superframe
     if (get_bits1(gb)) skip_bits(gb, 12); // number of  samples in superframe
     if (s->has_residual_lsps) {           // residual LSPs (for all frames)
         if (get_bits_left(gb) < s->sframe_lsp_bitsize)
@@ -1695,7 +1698,7 @@ static int check_bits_for_superframe(GetBitContext *orig_gb,
         }
         bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)];
         if (bd_idx < 0)
-            return -1;                   // invalid frame type VLC code
+            return AVERROR_INVALIDDATA; // invalid frame type VLC code
         frame_desc = &frame_descs[bd_idx];
         if (frame_desc->acb_type == ACB_TYPE_ASYMMETRIC) {
             if (get_bits_left(gb) < s->pitch_nbits)
@@ -1746,7 +1749,8 @@ static int check_bits_for_superframe(GetBitContext *orig_gb,
  * @return 0 on success, <0 on error or 1 if there was not enough data to
  *         fully parse the superframe
  */
-static int synth_superframe(AVCodecContext *ctx, int *got_frame_ptr)
+static int synth_superframe(AVCodecContext *ctx, AVFrame *frame,
+                            int *got_frame_ptr)
 {
     WMAVoiceContext *s = ctx->priv_data;
     GetBitContext *gb = &s->gb, s_gb;
@@ -1772,14 +1776,15 @@ static int synth_superframe(AVCodecContext *ctx, int *got_frame_ptr)
     if ((res = check_bits_for_superframe(gb, s)) == 1) {
         *got_frame_ptr = 0;
         return 1;
-    }
+    } else if (res < 0)
+        return res;
 
     /* First bit is speech/music bit, it differentiates between WMAVoice
      * speech samples (the actual codec) and WMAVoice music samples, which
      * are really WMAPro-in-WMAVoice-superframes. I've never seen those in
      * the wild yet. */
     if (!get_bits1(gb)) {
-        av_log_missing_feature(ctx, "WMAPro-in-WMAVoice", 1);
+        avpriv_request_sample(ctx, "WMAPro-in-WMAVoice");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -1789,7 +1794,7 @@ static int synth_superframe(AVCodecContext *ctx, int *got_frame_ptr)
             av_log(ctx, AV_LOG_ERROR,
                    "Superframe encodes >480 samples (%d), not allowed\n",
                    n_samples);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
     }
     /* Parse LSPs, if global for the superframe (can also be per-frame). */
@@ -1814,13 +1819,13 @@ static int synth_superframe(AVCodecContext *ctx, int *got_frame_ptr)
     }
 
     /* get output buffer */
-    s->frame.nb_samples = 480;
-    if ((res = ff_get_buffer(ctx, &s->frame)) < 0) {
+    frame->nb_samples = 480;
+    if ((res = ff_get_buffer(ctx, frame, 0)) < 0) {
         av_log(ctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
-    s->frame.nb_samples = n_samples;
-    samples = (float *)s->frame.data[0];
+    frame->nb_samples = n_samples;
+    samples = (float *)frame->data[0];
 
     /* Parse frames, optionally preceded by per-frame (independent) LSPs. */
     for (n = 0; n < 3; n++) {
@@ -1977,11 +1982,10 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data,
                 copy_bits(&s->pb, avpkt->data, size, gb, s->spillover_nbits);
                 flush_put_bits(&s->pb);
                 s->sframe_cache_size += s->spillover_nbits;
-                if ((res = synth_superframe(ctx, got_frame_ptr)) == 0 &&
+                if ((res = synth_superframe(ctx, data, got_frame_ptr)) == 0 &&
                     *got_frame_ptr) {
                     cnt += s->spillover_nbits;
                     s->skip_bits_next = cnt & 7;
-                    *(AVFrame *)data = s->frame;
                     return cnt >> 3;
                 } else
                     skip_bits_long (gb, s->spillover_nbits - cnt +
@@ -1996,12 +2000,11 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data,
     s->sframe_cache_size = 0;
     s->skip_bits_next = 0;
     pos = get_bits_left(gb);
-    if ((res = synth_superframe(ctx, got_frame_ptr)) < 0) {
+    if ((res = synth_superframe(ctx, data, got_frame_ptr)) < 0) {
         return res;
     } else if (*got_frame_ptr) {
         int cnt = get_bits_count(gb);
         s->skip_bits_next = cnt & 7;
-        *(AVFrame *)data = s->frame;
         return cnt >> 3;
     } else if ((s->sframe_cache_size = pos) > 0) {
         /* rewind bit reader to start of last (incomplete) superframe... */
@@ -2062,14 +2065,15 @@ static av_cold void wmavoice_flush(AVCodecContext *ctx)
 }
 
 AVCodec ff_wmavoice_decoder = {
-    .name           = "wmavoice",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_WMAVOICE,
-    .priv_data_size = sizeof(WMAVoiceContext),
-    .init           = wmavoice_decode_init,
-    .close          = wmavoice_decode_end,
-    .decode         = wmavoice_decode_packet,
-    .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
-    .flush          = wmavoice_flush,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"),
+    .name             = "wmavoice",
+    .long_name        = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"),
+    .type             = AVMEDIA_TYPE_AUDIO,
+    .id               = AV_CODEC_ID_WMAVOICE,
+    .priv_data_size   = sizeof(WMAVoiceContext),
+    .init             = wmavoice_decode_init,
+    .init_static_data = wmavoice_init_static_data,
+    .close            = wmavoice_decode_end,
+    .decode           = wmavoice_decode_packet,
+    .capabilities     = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
+    .flush            = wmavoice_flush,
 };
diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c
index a3dcbb3..b330776 100644
--- a/libavcodec/wmv2.c
+++ b/libavcodec/wmv2.c
@@ -28,17 +28,34 @@
 av_cold void ff_wmv2_common_init(Wmv2Context * w){
     MpegEncContext * const s= &w->s;
 
-    ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[0], ff_wmv2_scantableA);
-    ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1], ff_wmv2_scantableB);
+    ff_wmv2dsp_init(&w->wdsp);
+    s->dsp.idct_permutation_type = w->wdsp.idct_perm;
+    ff_init_scantable_permutation(s->dsp.idct_permutation,
+                                  w->wdsp.idct_perm);
+    ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[0],
+                      ff_wmv2_scantableA);
+    ff_init_scantable(s->dsp.idct_permutation, &w->abt_scantable[1],
+                      ff_wmv2_scantableB);
+    ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable,
+                      ff_wmv1_scantable[1]);
+    ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable,
+                      ff_wmv1_scantable[2]);
+    ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable,
+                      ff_wmv1_scantable[3]);
+    ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable,
+                      ff_wmv1_scantable[0]);
+    s->dsp.idct_put = w->wdsp.idct_put;
+    s->dsp.idct_add = w->wdsp.idct_add;
+    s->dsp.idct     = NULL;
 }
 
-static void wmv2_add_block(Wmv2Context *w, DCTELEM *block1, uint8_t *dst, int stride, int n){
+static void wmv2_add_block(Wmv2Context *w, int16_t *block1, uint8_t *dst, int stride, int n){
     MpegEncContext * const s= &w->s;
 
   if (s->block_last_index[n] >= 0) {
     switch(w->abt_type_table[n]){
     case 0:
-        s->dsp.idct_add (dst, stride, block1);
+        w->wdsp.idct_add(dst, stride, block1);
         break;
     case 1:
         ff_simple_idct84_add(dst           , stride, block1);
@@ -56,7 +73,7 @@ static void wmv2_add_block(Wmv2Context *w, DCTELEM *block1, uint8_t *dst, int st
   }
 }
 
-void ff_wmv2_add_mb(MpegEncContext *s, DCTELEM block1[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr){
+void ff_wmv2_add_mb(MpegEncContext *s, int16_t block1[6][64], uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr){
     Wmv2Context * const w= (Wmv2Context*)s;
 
     wmv2_add_block(w, block1[0], dest_y                    , s->linesize, 0);
@@ -77,7 +94,8 @@ void ff_mspel_motion(MpegEncContext *s,
 {
     Wmv2Context * const w= (Wmv2Context*)s;
     uint8_t *ptr;
-    int dxy, offset, mx, my, src_x, src_y, v_edge_pos, linesize, uvlinesize;
+    int dxy, offset, mx, my, src_x, src_y, v_edge_pos;
+    ptrdiff_t linesize, uvlinesize;
     int emu=0;
 
     dxy = ((motion_y & 1) << 1) | (motion_x & 1);
@@ -102,8 +120,12 @@ void ff_mspel_motion(MpegEncContext *s,
     if(s->flags&CODEC_FLAG_EMU_EDGE){
         if(src_x<1 || src_y<1 || src_x + 17  >= s->h_edge_pos
                               || src_y + h+1 >= v_edge_pos){
-            s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr - 1 - s->linesize, s->linesize, 19, 19,
-                             src_x-1, src_y-1, s->h_edge_pos, s->v_edge_pos);
+            s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+                                     ptr - 1 - s->linesize,
+                                     s->linesize, s->linesize,
+                                     19, 19,
+                                     src_x - 1, src_y - 1,
+                                     s->h_edge_pos, s->v_edge_pos);
             ptr= s->edge_emu_buffer + 1 + s->linesize;
             emu=1;
         }
@@ -143,16 +165,22 @@ void ff_mspel_motion(MpegEncContext *s,
     offset = (src_y * uvlinesize) + src_x;
     ptr = ref_picture[1] + offset;
     if(emu){
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
-                         src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                                 s->uvlinesize, s->uvlinesize,
+                                 9, 9,
+                                 src_x, src_y,
+                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
         ptr= s->edge_emu_buffer;
     }
     pix_op[1][dxy](dest_cb, ptr, uvlinesize, h >> 1);
 
     ptr = ref_picture[2] + offset;
     if(emu){
-        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9,
-                         src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
+                                 s->uvlinesize, s->uvlinesize,
+                                 9, 9,
+                                 src_x, src_y,
+                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);
         ptr= s->edge_emu_buffer;
     }
     pix_op[1][dxy](dest_cr, ptr, uvlinesize, h >> 1);
diff --git a/libavcodec/wmv2.h b/libavcodec/wmv2.h
index 80f36cc..e01f6c1 100644
--- a/libavcodec/wmv2.h
+++ b/libavcodec/wmv2.h
@@ -22,9 +22,9 @@
 #define AVCODEC_WMV2_H
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "intrax8.h"
+#include "wmv2dsp.h"
 
 #define SKIP_TYPE_NONE 0
 #define SKIP_TYPE_MPEG 1
@@ -35,6 +35,7 @@
 typedef struct Wmv2Context{
     MpegEncContext s;
     IntraX8Context x8;
+    WMV2DSPContext wdsp;
     int j_type_bit;
     int j_type;
     int abt_flag;
@@ -50,7 +51,7 @@ typedef struct Wmv2Context{
     int hshift;
 
     ScanTable abt_scantable[2];
-    DECLARE_ALIGNED(16, DCTELEM, abt_block2)[6][64];
+    DECLARE_ALIGNED(16, int16_t, abt_block2)[6][64];
 }Wmv2Context;
 
 void ff_wmv2_common_init(Wmv2Context * w);
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index c1fd4ee..740636c 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -19,7 +19,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "h263.h"
 #include "mathops.h"
@@ -32,7 +31,7 @@
 static void parse_mb_skip(Wmv2Context * w){
     int mb_x, mb_y;
     MpegEncContext * const s= &w->s;
-    uint32_t * const mb_type = s->current_picture_ptr->f.mb_type;
+    uint32_t * const mb_type = s->current_picture_ptr->mb_type;
 
     w->skip_type= get_bits(&s->gb, 2);
     switch(w->skip_type){
@@ -255,11 +254,11 @@ static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){
     wrap = s->b8_stride;
     xy = s->block_index[0];
 
-    mot_val = s->current_picture.f.motion_val[0][xy];
+    mot_val = s->current_picture.motion_val[0][xy];
 
-    A = s->current_picture.f.motion_val[0][xy - 1];
-    B = s->current_picture.f.motion_val[0][xy - wrap];
-    C = s->current_picture.f.motion_val[0][xy + 2 - wrap];
+    A = s->current_picture.motion_val[0][xy - 1];
+    B = s->current_picture.motion_val[0][xy - wrap];
+    C = s->current_picture.motion_val[0][xy + 2 - wrap];
 
     if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag)
         diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1]));
@@ -291,7 +290,7 @@ static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){
     return mot_val;
 }
 
-static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n, int cbp){
+static inline int wmv2_decode_inter_block(Wmv2Context *w, int16_t *block, int n, int cbp){
     MpegEncContext * const s= &w->s;
     static const int sub_cbp_table[3]= {2,3,1};
     int sub_cbp;
@@ -331,7 +330,7 @@ static inline int wmv2_decode_inter_block(Wmv2Context *w, DCTELEM *block, int n,
 }
 
 
-int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
+int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
     Wmv2Context * const w= (Wmv2Context*)s;
     int cbp, code, i;
@@ -340,7 +339,7 @@ int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
     if(w->j_type) return 0;
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
-        if (IS_SKIP(s->current_picture.f.mb_type[s->mb_y * s->mb_stride + s->mb_x])) {
+        if (IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])) {
             /* skip mb */
             s->mb_intra = 0;
             for(i=0;i<6;i++)
@@ -447,10 +446,6 @@ int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
 static av_cold int wmv2_decode_init(AVCodecContext *avctx){
     Wmv2Context * const w= avctx->priv_data;
 
-    if(avctx->idct_algo==FF_IDCT_AUTO){
-        avctx->idct_algo=FF_IDCT_WMV2;
-    }
-
     if(ff_msmpeg4_decode_init(avctx) < 0)
         return -1;
 
@@ -471,6 +466,7 @@ static av_cold int wmv2_decode_end(AVCodecContext *avctx)
 
 AVCodec ff_wmv2_decoder = {
     .name           = "wmv2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WMV2,
     .priv_data_size = sizeof(Wmv2Context),
@@ -478,6 +474,5 @@ AVCodec ff_wmv2_decoder = {
     .close          = wmv2_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
diff --git a/libavcodec/wmv2dsp.c b/libavcodec/wmv2dsp.c
new file mode 100644
index 0000000..72dfe78
--- /dev/null
+++ b/libavcodec/wmv2dsp.c
@@ -0,0 +1,146 @@
+/*
+ * 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/attributes.h"
+#include "libavutil/common.h"
+#include "avcodec.h"
+#include "dsputil.h"
+#include "wmv2dsp.h"
+
+#define W0 2048
+#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
+#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
+#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
+#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
+#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
+#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
+#define W7 565  /* 2048*sqrt (2)*cos (7*pi/16) */
+
+static void wmv2_idct_row(short * b)
+{
+    int s1, s2;
+    int a0, a1, a2, a3, a4, a5, a6, a7;
+
+    /* step 1 */
+    a1 = W1 * b[1] + W7 * b[7];
+    a7 = W7 * b[1] - W1 * b[7];
+    a5 = W5 * b[5] + W3 * b[3];
+    a3 = W3 * b[5] - W5 * b[3];
+    a2 = W2 * b[2] + W6 * b[6];
+    a6 = W6 * b[2] - W2 * b[6];
+    a0 = W0 * b[0] + W0 * b[4];
+    a4 = W0 * b[0] - W0 * b[4];
+
+    /* step 2 */
+    s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8; // 1, 3, 5, 7
+    s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+    /* step 3 */
+    b[0] = (a0 + a2 + a1 + a5 + (1 << 7)) >> 8;
+    b[1] = (a4 + a6 + s1      + (1 << 7)) >> 8;
+    b[2] = (a4 - a6 + s2      + (1 << 7)) >> 8;
+    b[3] = (a0 - a2 + a7 + a3 + (1 << 7)) >> 8;
+    b[4] = (a0 - a2 - a7 - a3 + (1 << 7)) >> 8;
+    b[5] = (a4 - a6 - s2      + (1 << 7)) >> 8;
+    b[6] = (a4 + a6 - s1      + (1 << 7)) >> 8;
+    b[7] = (a0 + a2 - a1 - a5 + (1 << 7)) >> 8;
+}
+
+static void wmv2_idct_col(short * b)
+{
+    int s1, s2;
+    int a0, a1, a2, a3, a4, a5, a6, a7;
+
+    /* step 1, with extended precision */
+    a1 = (W1 * b[8 * 1] + W7 * b[8 * 7] + 4) >> 3;
+    a7 = (W7 * b[8 * 1] - W1 * b[8 * 7] + 4) >> 3;
+    a5 = (W5 * b[8 * 5] + W3 * b[8 * 3] + 4) >> 3;
+    a3 = (W3 * b[8 * 5] - W5 * b[8 * 3] + 4) >> 3;
+    a2 = (W2 * b[8 * 2] + W6 * b[8 * 6] + 4) >> 3;
+    a6 = (W6 * b[8 * 2] - W2 * b[8 * 6] + 4) >> 3;
+    a0 = (W0 * b[8 * 0] + W0 * b[8 * 4]    ) >> 3;
+    a4 = (W0 * b[8 * 0] - W0 * b[8 * 4]    ) >> 3;
+
+    /* step 2 */
+    s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8;
+    s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+    /* step 3 */
+    b[8 * 0] = (a0 + a2 + a1 + a5 + (1 << 13)) >> 14;
+    b[8 * 1] = (a4 + a6 + s1      + (1 << 13)) >> 14;
+    b[8 * 2] = (a4 - a6 + s2      + (1 << 13)) >> 14;
+    b[8 * 3] = (a0 - a2 + a7 + a3 + (1 << 13)) >> 14;
+
+    b[8 * 4] = (a0 - a2 - a7 - a3 + (1 << 13)) >> 14;
+    b[8 * 5] = (a4 - a6 - s2      + (1 << 13)) >> 14;
+    b[8 * 6] = (a4 + a6 - s1      + (1 << 13)) >> 14;
+    b[8 * 7] = (a0 + a2 - a1 - a5 + (1 << 13)) >> 14;
+}
+
+static void wmv2_idct_add_c(uint8_t *dest, int line_size, int16_t *block)
+{
+    int i;
+
+    for (i = 0; i < 64; i += 8)
+        wmv2_idct_row(block + i);
+    for (i = 0; i < 8; i++)
+        wmv2_idct_col(block + i);
+
+    for (i = 0; i < 8; i++) {
+        dest[0] = av_clip_uint8(dest[0] + block[0]);
+        dest[1] = av_clip_uint8(dest[1] + block[1]);
+        dest[2] = av_clip_uint8(dest[2] + block[2]);
+        dest[3] = av_clip_uint8(dest[3] + block[3]);
+        dest[4] = av_clip_uint8(dest[4] + block[4]);
+        dest[5] = av_clip_uint8(dest[5] + block[5]);
+        dest[6] = av_clip_uint8(dest[6] + block[6]);
+        dest[7] = av_clip_uint8(dest[7] + block[7]);
+        dest += line_size;
+        block += 8;
+    }
+}
+
+static void wmv2_idct_put_c(uint8_t *dest, int line_size, int16_t *block)
+{
+    int i;
+
+    for (i = 0; i < 64; i += 8)
+        wmv2_idct_row(block + i);
+    for (i = 0; i < 8; i++)
+        wmv2_idct_col(block + i);
+
+    for (i = 0; i < 8; i++) {
+        dest[0] = av_clip_uint8(block[0]);
+        dest[1] = av_clip_uint8(block[1]);
+        dest[2] = av_clip_uint8(block[2]);
+        dest[3] = av_clip_uint8(block[3]);
+        dest[4] = av_clip_uint8(block[4]);
+        dest[5] = av_clip_uint8(block[5]);
+        dest[6] = av_clip_uint8(block[6]);
+        dest[7] = av_clip_uint8(block[7]);
+        dest += line_size;
+        block += 8;
+    }
+}
+
+av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
+{
+    c->idct_add  = wmv2_idct_add_c;
+    c->idct_put  = wmv2_idct_put_c;
+    c->idct_perm = FF_NO_IDCT_PERM;
+}
diff --git a/libavcodec/wmv2dsp.h b/libavcodec/wmv2dsp.h
new file mode 100644
index 0000000..3368b3a
--- /dev/null
+++ b/libavcodec/wmv2dsp.h
@@ -0,0 +1,33 @@
+/*
+ * 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_WMV2DSP_H
+#define AVCODEC_WMV2DSP_H
+
+#include <stdint.h>
+
+typedef struct WMV2DSPContext {
+    void (*idct_add)(uint8_t *dest, int line_size, int16_t *block);
+    void (*idct_put)(uint8_t *dest, int line_size, int16_t *block);
+
+    int idct_perm;
+} WMV2DSPContext;
+
+void ff_wmv2dsp_init(WMV2DSPContext *c);
+
+#endif /* AVCODEC_WMV2DSP_H */
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 4643835..256c4e5 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -19,7 +19,6 @@
  */
 
 #include "avcodec.h"
-#include "dsputil.h"
 #include "mpegvideo.h"
 #include "msmpeg4.h"
 #include "msmpeg4data.h"
@@ -148,7 +147,7 @@ int ff_wmv2_encode_picture_header(MpegEncContext * s, int picture_number)
  * useless M$ crap features. It is duplicated here in case someone wants
  * to add support for these crap features. */
 void ff_wmv2_encode_mb(MpegEncContext * s,
-                       DCTELEM block[6][64],
+                       int16_t block[6][64],
                        int motion_x, int motion_y)
 {
     Wmv2Context * const w= (Wmv2Context*)s;
@@ -213,6 +212,7 @@ void ff_wmv2_encode_mb(MpegEncContext * s,
 
 AVCodec ff_wmv2_encoder = {
     .name           = "wmv2",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WMV2,
     .priv_data_size = sizeof(Wmv2Context),
@@ -220,5 +220,4 @@ AVCodec ff_wmv2_encoder = {
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 8"),
 };
diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c
index 362fafc..7676c89 100644
--- a/libavcodec/wnv1.c
+++ b/libavcodec/wnv1.c
@@ -32,7 +32,6 @@
 
 typedef struct WNV1Context {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int shift;
     GetBitContext gb;
@@ -65,9 +64,9 @@ static int decode_frame(AVCodecContext *avctx,
     WNV1Context * const l = avctx->priv_data;
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
-    AVFrame * const p     = &l->pic;
+    AVFrame * const p     = data;
     unsigned char *Y,*U,*V;
-    int i, j;
+    int i, j, ret;
     int prev_y = 0, prev_u = 0, prev_v = 0;
     uint8_t *rbuf;
 
@@ -79,17 +78,13 @@ static int decode_frame(AVCodecContext *avctx,
     rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!rbuf) {
         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
-        return -1;
+        return AVERROR(ENOMEM);
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if(ff_get_buffer(avctx, p) < 0){
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         av_free(rbuf);
-        return -1;
+        return ret;
     }
     p->key_frame = 1;
 
@@ -102,12 +97,14 @@ static int decode_frame(AVCodecContext *avctx,
     else {
         l->shift = 8 - (buf[2] >> 4);
         if (l->shift > 4) {
-            av_log_ask_for_sample(avctx, "Unknown WNV1 frame header value %i\n",
+            avpriv_request_sample(avctx,
+                                  "Unknown WNV1 frame header value %i",
                                   buf[2] >> 4);
             l->shift = 4;
         }
         if (l->shift < 1) {
-            av_log_ask_for_sample(avctx, "Unknown WNV1 frame header value %i\n",
+            avpriv_request_sample(avctx,
+                                  "Unknown WNV1 frame header value %i",
                                   buf[2] >> 4);
             l->shift = 1;
         }
@@ -130,7 +127,6 @@ static int decode_frame(AVCodecContext *avctx,
 
 
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
     av_free(rbuf);
 
     return buf_size;
@@ -153,25 +149,13 @@ static av_cold int decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    WNV1Context * const l = avctx->priv_data;
-    AVFrame *pic = &l->pic;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    return 0;
-}
-
 AVCodec ff_wnv1_decoder = {
     .name           = "wnv1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Winnov WNV1"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WNV1,
     .priv_data_size = sizeof(WNV1Context),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Winnov WNV1"),
 };
diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c
index 62e0c6f..fe6f812 100644
--- a/libavcodec/ws-snd1.c
+++ b/libavcodec/ws-snd1.c
@@ -41,28 +41,19 @@ static const int8_t ws_adpcm_4bit[] = {
      0,  1,  2,  3,  4,  5,  6,  8
 };
 
-typedef struct WSSndContext {
-    AVFrame frame;
-} WSSndContext;
-
 static av_cold int ws_snd_decode_init(AVCodecContext *avctx)
 {
-    WSSndContext *s = avctx->priv_data;
-
     avctx->channels       = 1;
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_U8;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
 static int ws_snd_decode_frame(AVCodecContext *avctx, void *data,
                                int *got_frame_ptr, AVPacket *avpkt)
 {
-    WSSndContext *s = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
 
@@ -89,18 +80,17 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     /* get output buffer */
-    s->frame.nb_samples = out_size;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = out_size;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    samples     = s->frame.data[0];
+    samples     = frame->data[0];
     samples_end = samples + out_size;
 
     if (in_size == out_size) {
         memcpy(samples, buf, out_size);
-        *got_frame_ptr   = 1;
-        *(AVFrame *)data = s->frame;
+        *got_frame_ptr = 1;
         return buf_size;
     }
 
@@ -176,20 +166,18 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    s->frame.nb_samples = samples - s->frame.data[0];
-    *got_frame_ptr   = 1;
-    *(AVFrame *)data = s->frame;
+    frame->nb_samples = samples - frame->data[0];
+    *got_frame_ptr    = 1;
 
     return buf_size;
 }
 
 AVCodec ff_ws_snd1_decoder = {
     .name           = "ws_snd1",
+    .long_name      = NULL_IF_CONFIG_SMALL("Westwood Audio (SND1)"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_WESTWOOD_SND1,
-    .priv_data_size = sizeof(WSSndContext),
     .init           = ws_snd_decode_init,
     .decode         = ws_snd_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Westwood Audio (SND1)"),
 };
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index 4fc7ac0..6f4935b 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -1,15 +1,26 @@
-OBJS                                   += x86/fmtconvert_init.o
+OBJS                                   += x86/constants.o               \
+                                          x86/fmtconvert_init.o         \
 
 OBJS-$(CONFIG_AAC_DECODER)             += x86/sbrdsp_init.o
 OBJS-$(CONFIG_AC3DSP)                  += x86/ac3dsp_init.o
 OBJS-$(CONFIG_CAVS_DECODER)            += x86/cavsdsp.o
+OBJS-$(CONFIG_DCT)                     += x86/dct_init.o
 OBJS-$(CONFIG_DNXHD_ENCODER)           += x86/dnxhdenc.o
+OBJS-$(CONFIG_DSPUTIL)                 += x86/dsputil_init.o            \
+                                          x86/dsputil_x86.o
+OBJS-$(CONFIG_ENCODERS)                += x86/dsputilenc_mmx.o          \
+                                          x86/fdct.o                    \
+                                          x86/motion_est.o
 OBJS-$(CONFIG_FFT)                     += x86/fft_init.o
+OBJS-$(CONFIG_H263DSP)                 += x86/h263dsp_init.o
+OBJS-$(CONFIG_H264CHROMA)              += x86/h264chroma_init.o
 OBJS-$(CONFIG_H264DSP)                 += x86/h264dsp_init.o
 OBJS-$(CONFIG_H264PRED)                += x86/h264_intrapred_init.o
+OBJS-$(CONFIG_H264QPEL)                += x86/h264_qpel.o
+OBJS-$(CONFIG_HPELDSP)                 += x86/hpeldsp_init.o
 OBJS-$(CONFIG_LPC)                     += x86/lpc.o
 OBJS-$(CONFIG_MLP_DECODER)             += x86/mlpdsp.o
-OBJS-$(CONFIG_MPEGAUDIODSP)            += x86/mpegaudiodec.o
+OBJS-$(CONFIG_MPEGAUDIODSP)            += x86/mpegaudiodsp.o
 OBJS-$(CONFIG_MPEGVIDEO)               += x86/mpegvideo.o
 OBJS-$(CONFIG_MPEGVIDEOENC)            += x86/mpegvideoenc.o
 OBJS-$(CONFIG_PNG_DECODER)             += x86/pngdsp_init.o
@@ -20,28 +31,37 @@ OBJS-$(CONFIG_RV40_DECODER)            += x86/rv34dsp_init.o            \
 OBJS-$(CONFIG_TRUEHD_DECODER)          += x86/mlpdsp.o
 OBJS-$(CONFIG_VC1_DECODER)             += x86/vc1dsp_init.o
 OBJS-$(CONFIG_VIDEODSP)                += x86/videodsp_init.o
+OBJS-$(CONFIG_VORBIS_DECODER)          += x86/vorbisdsp_init.o
 OBJS-$(CONFIG_VP3DSP)                  += x86/vp3dsp_init.o
-OBJS-$(CONFIG_VP5_DECODER)             += x86/vp56dsp_init.o
-OBJS-$(CONFIG_VP6_DECODER)             += x86/vp56dsp_init.o
+OBJS-$(CONFIG_VP6_DECODER)             += x86/vp6dsp_init.o
 OBJS-$(CONFIG_VP8_DECODER)             += x86/vp8dsp_init.o
+OBJS-$(CONFIG_VP9_DECODER)             += x86/vp9dsp_init.o
 OBJS-$(CONFIG_XMM_CLOBBER_TEST)        += x86/w64xmmtest.o
 
-MMX-OBJS                               += x86/dsputil_mmx.o             \
-                                          x86/fdct.o                    \
+MMX-OBJS-$(CONFIG_DSPUTIL)             += x86/dsputil_mmx.o             \
+                                          x86/fpel_mmx.o                \
                                           x86/idct_mmx_xvid.o           \
                                           x86/idct_sse2_xvid.o          \
-                                          x86/simple_idct.o             \
-
-MMX-OBJS-$(CONFIG_DWT)                 += x86/snowdsp.o
-MMX-OBJS-$(CONFIG_ENCODERS)            += x86/dsputilenc_mmx.o          \
-                                          x86/motion_est.o
+                                          x86/rnd_mmx.o                 \
+                                          x86/simple_idct.o
+MMX-OBJS-$(CONFIG_HPELDSP)             += x86/fpel_mmx.o                \
+                                          x86/hpeldsp_mmx.o             \
+                                          x86/rnd_mmx.o
 MMX-OBJS-$(CONFIG_VC1_DECODER)         += x86/vc1dsp_mmx.o
 
+YASM-OBJS                              += x86/deinterlace.o             \
+                                          x86/fmtconvert.o              \
+
 YASM-OBJS-$(CONFIG_AAC_DECODER)        += x86/sbrdsp.o
 YASM-OBJS-$(CONFIG_AC3DSP)             += x86/ac3dsp.o
 YASM-OBJS-$(CONFIG_DCT)                += x86/dct32.o
+YASM-OBJS-$(CONFIG_DSPUTIL)            += x86/dsputil.o                 \
+                                          x86/fpel.o                    \
+                                          x86/mpeg4qpel.o               \
+                                          x86/qpel.o
 YASM-OBJS-$(CONFIG_ENCODERS)           += x86/dsputilenc.o
 YASM-OBJS-$(CONFIG_FFT)                += x86/fft.o
+YASM-OBJS-$(CONFIG_H263DSP)            += x86/h263_loopfilter.o
 YASM-OBJS-$(CONFIG_H264CHROMA)         += x86/h264_chromamc.o           \
                                           x86/h264_chromamc_10bit.o
 YASM-OBJS-$(CONFIG_H264DSP)            += x86/h264_deblock.o            \
@@ -53,7 +73,11 @@ YASM-OBJS-$(CONFIG_H264DSP)            += x86/h264_deblock.o            \
 YASM-OBJS-$(CONFIG_H264PRED)           += x86/h264_intrapred.o          \
                                           x86/h264_intrapred_10bit.o
 YASM-OBJS-$(CONFIG_H264QPEL)           += x86/h264_qpel_8bit.o          \
-                                          x86/h264_qpel_10bit.o
+                                          x86/h264_qpel_10bit.o         \
+                                          x86/fpel.o                    \
+                                          x86/qpel.o
+YASM-OBJS-$(CONFIG_HPELDSP)            += x86/fpel.o                    \
+                                          x86/hpeldsp.o
 YASM-OBJS-$(CONFIG_MPEGAUDIODSP)       += x86/imdct36.o
 YASM-OBJS-$(CONFIG_PNG_DECODER)        += x86/pngdsp.o
 YASM-OBJS-$(CONFIG_PRORES_DECODER)     += x86/proresdsp.o
@@ -62,10 +86,9 @@ YASM-OBJS-$(CONFIG_RV40_DECODER)       += x86/rv34dsp.o                 \
                                           x86/rv40dsp.o
 YASM-OBJS-$(CONFIG_VC1_DECODER)        += x86/vc1dsp.o
 YASM-OBJS-$(CONFIG_VIDEODSP)           += x86/videodsp.o
+YASM-OBJS-$(CONFIG_VORBIS_DECODER)     += x86/vorbisdsp.o
 YASM-OBJS-$(CONFIG_VP3DSP)             += x86/vp3dsp.o
-YASM-OBJS-$(CONFIG_VP6_DECODER)        += x86/vp56dsp.o
-YASM-OBJS-$(CONFIG_VP8_DECODER)        += x86/vp8dsp.o
-
-YASM-OBJS                              += x86/dsputil.o                 \
-                                          x86/deinterlace.o             \
-                                          x86/fmtconvert.o              \
+YASM-OBJS-$(CONFIG_VP6_DECODER)        += x86/vp6dsp.o
+YASM-OBJS-$(CONFIG_VP8_DECODER)        += x86/vp8dsp.o                  \
+                                          x86/vp8dsp_loopfilter.o
+YASM-OBJS-$(CONFIG_VP9_DECODER)        += x86/vp9dsp.o
diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm
index 45c30d1..b432318 100644
--- a/libavcodec/x86/ac3dsp.asm
+++ b/libavcodec/x86/ac3dsp.asm
@@ -151,15 +151,12 @@ cglobal ac3_max_msb_abs_int16, 2,2,5, src, len
 %endmacro
 
 INIT_MMX mmx
-%define ABS2 ABS2_MMX
 AC3_MAX_MSB_ABS_INT16 or_abs
 INIT_MMX mmxext
-%define ABS2 ABS2_MMXEXT
 AC3_MAX_MSB_ABS_INT16 min_max
 INIT_XMM sse2
 AC3_MAX_MSB_ABS_INT16 min_max
 INIT_XMM ssse3
-%define ABS2 ABS2_SSSE3
 AC3_MAX_MSB_ABS_INT16 or_abs
 
 ;-----------------------------------------------------------------------------
@@ -382,42 +379,6 @@ cglobal ac3_compute_mantissa_size, 1, 2, 4, mant_cnt, sum
 %endif
 %endmacro
 
-%if HAVE_AMD3DNOW_EXTERNAL
-INIT_MMX 3dnow
-cglobal ac3_extract_exponents, 3, 3, 0, exp, coef, len
-    add      expq, lenq
-    lea     coefq, [coefq+4*lenq]
-    neg      lenq
-    movq       m3, [pd_1]
-    movq       m4, [pd_151]
-.loop:
-    movq       m0, [coefq+4*lenq  ]
-    movq       m1, [coefq+4*lenq+8]
-    PABSD      m0, m2
-    PABSD      m1, m2
-    pslld      m0, 1
-    por        m0, m3
-    pi2fd      m2, m0
-    psrld      m2, 23
-    movq       m0, m4
-    psubd      m0, m2
-    pslld      m1, 1
-    por        m1, m3
-    pi2fd      m2, m1
-    psrld      m2, 23
-    movq       m1, m4
-    psubd      m1, m2
-    packssdw   m0, m0
-    packuswb   m0, m0
-    packssdw   m1, m1
-    packuswb   m1, m1
-    punpcklwd  m0, m1
-    movd  [expq+lenq], m0
-    add      lenq, 4
-    jl .loop
-    REP_RET
-%endif
-
 %macro AC3_EXTRACT_EXPONENTS 0
 cglobal ac3_extract_exponents, 3, 3, 4, exp, coef, len
     add     expq, lenq
diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c
index e8f7304..9fbed3c 100644
--- a/libavcodec/x86/ac3dsp_init.c
+++ b/libavcodec/x86/ac3dsp_init.c
@@ -22,34 +22,47 @@
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 #include "libavcodec/ac3.h"
 #include "libavcodec/ac3dsp.h"
 
-extern void ff_ac3_exponent_min_mmx   (uint8_t *exp, int num_reuse_blocks, int nb_coefs);
-extern void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs);
-extern void ff_ac3_exponent_min_sse2  (uint8_t *exp, int num_reuse_blocks, int nb_coefs);
+void ff_ac3_exponent_min_mmx   (uint8_t *exp, int num_reuse_blocks, int nb_coefs);
+void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs);
+void ff_ac3_exponent_min_sse2  (uint8_t *exp, int num_reuse_blocks, int nb_coefs);
 
-extern int ff_ac3_max_msb_abs_int16_mmx  (const int16_t *src, int len);
-extern int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len);
-extern int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len);
-extern int ff_ac3_max_msb_abs_int16_ssse3(const int16_t *src, int len);
+int ff_ac3_max_msb_abs_int16_mmx  (const int16_t *src, int len);
+int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len);
+int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len);
+int ff_ac3_max_msb_abs_int16_ssse3(const int16_t *src, int len);
 
-extern void ff_ac3_lshift_int16_mmx (int16_t *src, unsigned int len, unsigned int shift);
-extern void ff_ac3_lshift_int16_sse2(int16_t *src, unsigned int len, unsigned int shift);
+void ff_ac3_lshift_int16_mmx (int16_t *src, unsigned int len, unsigned int shift);
+void ff_ac3_lshift_int16_sse2(int16_t *src, unsigned int len, unsigned int shift);
 
-extern void ff_ac3_rshift_int32_mmx (int32_t *src, unsigned int len, unsigned int shift);
-extern void ff_ac3_rshift_int32_sse2(int32_t *src, unsigned int len, unsigned int shift);
+void ff_ac3_rshift_int32_mmx (int32_t *src, unsigned int len, unsigned int shift);
+void ff_ac3_rshift_int32_sse2(int32_t *src, unsigned int len, unsigned int shift);
 
-extern void ff_float_to_fixed24_3dnow(int32_t *dst, const float *src, unsigned int len);
-extern void ff_float_to_fixed24_sse  (int32_t *dst, const float *src, unsigned int len);
-extern void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len);
+void ff_float_to_fixed24_3dnow(int32_t *dst, const float *src, unsigned int len);
+void ff_float_to_fixed24_sse  (int32_t *dst, const float *src, unsigned int len);
+void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len);
 
-extern int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]);
+int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]);
 
-extern void ff_ac3_extract_exponents_3dnow(uint8_t *exp, int32_t *coef, int nb_coefs);
-extern void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs);
-extern void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs);
+void ff_ac3_extract_exponents_3dnow(uint8_t *exp, int32_t *coef, int nb_coefs);
+void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs);
+void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs);
+
+void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
+                                        const int16_t *window, unsigned int len);
+void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
+                                      const int16_t *window, unsigned int len);
+void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
+                                  const int16_t *window, unsigned int len);
+void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
+                                const int16_t *window, unsigned int len);
+void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
+                                 const int16_t *window, unsigned int len);
+void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
+                                      const int16_t *window, unsigned int len);
 
 #if HAVE_SSE_INLINE && HAVE_7REGS
 
@@ -180,47 +193,59 @@ static void ac3_downmix_sse(float **samples, float (*matrix)[2],
 
 av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->ac3_exponent_min = ff_ac3_exponent_min_mmx;
         c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx;
         c->ac3_lshift_int16 = ff_ac3_lshift_int16_mmx;
         c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx;
     }
-    if (EXTERNAL_AMD3DNOW(mm_flags)) {
-        c->extract_exponents = ff_ac3_extract_exponents_3dnow;
+    if (EXTERNAL_AMD3DNOW(cpu_flags)) {
         if (!bit_exact) {
             c->float_to_fixed24 = ff_float_to_fixed24_3dnow;
         }
     }
-    if (EXTERNAL_MMXEXT(mm_flags)) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         c->ac3_exponent_min = ff_ac3_exponent_min_mmxext;
         c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmxext;
+        if (bit_exact) {
+            c->apply_window_int16 = ff_apply_window_int16_mmxext;
+        } else {
+            c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
+        }
     }
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         c->float_to_fixed24 = ff_float_to_fixed24_sse;
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         c->ac3_exponent_min = ff_ac3_exponent_min_sse2;
         c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_sse2;
         c->float_to_fixed24 = ff_float_to_fixed24_sse2;
         c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2;
         c->extract_exponents = ff_ac3_extract_exponents_sse2;
-        if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
+        if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
             c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2;
             c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2;
         }
+        if (bit_exact) {
+            c->apply_window_int16 = ff_apply_window_int16_sse2;
+        } else if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
+            c->apply_window_int16 = ff_apply_window_int16_round_sse2;
+        }
     }
-    if (EXTERNAL_SSSE3(mm_flags)) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3;
-        if (!(mm_flags & AV_CPU_FLAG_ATOM)) {
+        if (cpu_flags & AV_CPU_FLAG_ATOM) {
+            c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
+        } else {
             c->extract_exponents = ff_ac3_extract_exponents_ssse3;
+            c->apply_window_int16 = ff_apply_window_int16_ssse3;
         }
     }
 
 #if HAVE_SSE_INLINE && HAVE_7REGS
-    if (INLINE_SSE(mm_flags)) {
+    if (INLINE_SSE(cpu_flags)) {
         c->downmix = ac3_downmix_sse;
     }
 #endif
diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h
index a74cf0b..fdb0a29 100644
--- a/libavcodec/x86/cabac.h
+++ b/libavcodec/x86/cabac.h
@@ -229,5 +229,45 @@ static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val)
     return val;
 }
 
+#define get_cabac_bypass get_cabac_bypass_x86
+static av_always_inline int get_cabac_bypass_x86(CABACContext *c)
+{
+    x86_reg tmp;
+    int res;
+    __asm__ volatile(
+        "movl        %c6(%2), %k1       \n\t"
+        "movl        %c3(%2), %%eax     \n\t"
+        "shl             $17, %k1       \n\t"
+        "add           %%eax, %%eax     \n\t"
+        "sub             %k1, %%eax     \n\t"
+        "cltd                           \n\t"
+        "and           %%edx, %k1       \n\t"
+        "add             %k1, %%eax     \n\t"
+        "inc           %%edx            \n\t"
+        "test           %%ax, %%ax      \n\t"
+        "jnz              1f            \n\t"
+        "mov         %c4(%2), %1        \n\t"
+        "subl        $0xFFFF, %%eax     \n\t"
+        "movzwl         (%1), %%ecx     \n\t"
+        "bswap         %%ecx            \n\t"
+        "shrl            $15, %%ecx     \n\t"
+        "addl          %%ecx, %%eax     \n\t"
+        "cmp         %c5(%2), %1        \n\t"
+        "jge              1f            \n\t"
+        "add"OPSIZE"      $2, %c4(%2)   \n\t"
+        "1:                             \n\t"
+        "movl          %%eax, %c3(%2)   \n\t"
+
+        : "=&d"(res), "=&r"(tmp)
+        : "r"(c),
+          "i"(offsetof(CABACContext, low)),
+          "i"(offsetof(CABACContext, bytestream)),
+          "i"(offsetof(CABACContext, bytestream_end)),
+          "i"(offsetof(CABACContext, range))
+        : "%eax", "%ecx", "memory"
+    );
+    return res;
+}
+
 #endif /* HAVE_INLINE_ASM */
 #endif /* AVCODEC_X86_CABAC_H */
diff --git a/libavcodec/x86/cavsdsp.c b/libavcodec/x86/cavsdsp.c
index f94e2f3..bc9cbf7 100644
--- a/libavcodec/x86/cavsdsp.c
+++ b/libavcodec/x86/cavsdsp.c
@@ -22,16 +22,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/cavsdsp.h"
-#include "dsputil_mmx.h"
+#include "constants.h"
+#include "dsputil_x86.h"
 #include "config.h"
 
-#if (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE)
+#if HAVE_MMX_INLINE
 
 /* in/out: mma=mma+mmb, mmb=mmb-mma */
 #define SUMSUB_BA( a, b ) \
@@ -122,6 +123,17 @@ static inline void cavs_idct8_1d(int16_t *block, uint64_t bias)
     );
 }
 
+#define SBUTTERFLY(a,b,t,n,m)\
+    "mov" #m " " #a ", " #t "         \n\t" /* abcd */\
+    "punpckl" #n " " #b ", " #a "     \n\t" /* aebf */\
+    "punpckh" #n " " #b ", " #t "     \n\t" /* cgdh */\
+
+#define TRANSPOSE4(a,b,c,d,t)\
+    SBUTTERFLY(a,b,t,wd,q) /* a=aebf t=cgdh */\
+    SBUTTERFLY(c,d,b,wd,q) /* c=imjn b=kolp */\
+    SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\
+    SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */
+
 static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride)
 {
     int i;
@@ -187,6 +199,10 @@ static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride)
     ff_add_pixels_clamped_mmx(b2, dst, stride);
 }
 
+#endif /* HAVE_MMX_INLINE */
+
+#if (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE)
+
 /*****************************************************************************
  *
  * motion compensation
@@ -409,19 +425,23 @@ static void OPNAME ## cavs_qpel16_h_ ## MMX(uint8_t *dst, uint8_t *src, int dstS
 }\
 
 #define CAVS_MC(OPNAME, SIZE, MMX) \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_qpel ## SIZE ## _h_ ## MMX(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_qpel ## SIZE ## _v1_ ## MMX(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_qpel ## SIZE ## _v2_ ## MMX(dst, src, stride, stride);\
 }\
 \
-static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     OPNAME ## cavs_qpel ## SIZE ## _v3_ ## MMX(dst, src, stride, stride);\
 }\
 
@@ -437,6 +457,50 @@ static void ff_ ## OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, ui
 
 #endif /* (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) */
 
+#if HAVE_MMX_INLINE
+static void put_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride)
+{
+    ff_put_pixels8_mmx(dst, src, stride, 8);
+}
+
+static void avg_cavs_qpel8_mc00_mmx(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride)
+{
+    ff_avg_pixels8_mmx(dst, src, stride, 8);
+}
+
+static void put_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src,
+                                     ptrdiff_t stride)
+{
+    ff_put_pixels16_mmx(dst, src, stride, 16);
+}
+
+static void avg_cavs_qpel16_mc00_mmx(uint8_t *dst, uint8_t *src,
+                                     ptrdiff_t stride)
+{
+    ff_avg_pixels16_mmx(dst, src, stride, 16);
+}
+
+static av_cold void cavsdsp_init_mmx(CAVSDSPContext *c,
+                                     AVCodecContext *avctx)
+{
+    c->put_cavs_qpel_pixels_tab[0][0] = put_cavs_qpel16_mc00_mmx;
+    c->put_cavs_qpel_pixels_tab[1][0] = put_cavs_qpel8_mc00_mmx;
+    c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_mmx;
+    c->avg_cavs_qpel_pixels_tab[1][0] = avg_cavs_qpel8_mc00_mmx;
+
+    c->cavs_idct8_add = cavs_idct8_add_mmx;
+    c->idct_perm      = FF_TRANSPOSE_IDCT_PERM;
+}
+#endif /* HAVE_MMX_INLINE */
+
+#define DSPFUNC(PFX, IDX, NUM, EXT)                                                       \
+    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 2] = PFX ## _cavs_qpel ## NUM ## _mc20_ ## EXT; \
+    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 4] = PFX ## _cavs_qpel ## NUM ## _mc01_ ## EXT; \
+    c->PFX ## _cavs_qpel_pixels_tab[IDX][ 8] = PFX ## _cavs_qpel ## NUM ## _mc02_ ## EXT; \
+    c->PFX ## _cavs_qpel_pixels_tab[IDX][12] = PFX ## _cavs_qpel ## NUM ## _mc03_ ## EXT; \
+
 #if HAVE_MMXEXT_INLINE
 QPEL_CAVS(put_,        PUT_OP, mmxext)
 QPEL_CAVS(avg_, AVG_MMXEXT_OP, mmxext)
@@ -446,22 +510,13 @@ CAVS_MC(put_, 16, mmxext)
 CAVS_MC(avg_,  8, mmxext)
 CAVS_MC(avg_, 16, mmxext)
 
-static void ff_cavsdsp_init_mmxext(CAVSDSPContext *c, AVCodecContext *avctx)
+static av_cold void cavsdsp_init_mmxext(CAVSDSPContext *c,
+                                        AVCodecContext *avctx)
 {
-#define dspfunc(PFX, IDX, NUM) \
-    c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_mmxext; \
-    c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_mmxext; \
-    c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_mmxext; \
-    c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_mmxext; \
-    c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_mmxext; \
-
-    dspfunc(put_cavs_qpel, 0, 16);
-    dspfunc(put_cavs_qpel, 1, 8);
-    dspfunc(avg_cavs_qpel, 0, 16);
-    dspfunc(avg_cavs_qpel, 1, 8);
-#undef dspfunc
-    c->cavs_idct8_add = cavs_idct8_add_mmx;
-    c->idct_perm = FF_TRANSPOSE_IDCT_PERM;
+    DSPFUNC(put, 0, 16, mmxext);
+    DSPFUNC(put, 1,  8, mmxext);
+    DSPFUNC(avg, 0, 16, mmxext);
+    DSPFUNC(avg, 1,  8, mmxext);
 }
 #endif /* HAVE_MMXEXT_INLINE */
 
@@ -474,32 +529,30 @@ CAVS_MC(put_, 16,3dnow)
 CAVS_MC(avg_, 8, 3dnow)
 CAVS_MC(avg_, 16,3dnow)
 
-static void ff_cavsdsp_init_3dnow(CAVSDSPContext* c, AVCodecContext *avctx) {
-#define dspfunc(PFX, IDX, NUM) \
-    c->PFX ## _pixels_tab[IDX][ 0] = ff_ ## PFX ## NUM ## _mc00_mmxext; \
-    c->PFX ## _pixels_tab[IDX][ 2] = ff_ ## PFX ## NUM ## _mc20_3dnow; \
-    c->PFX ## _pixels_tab[IDX][ 4] = ff_ ## PFX ## NUM ## _mc01_3dnow; \
-    c->PFX ## _pixels_tab[IDX][ 8] = ff_ ## PFX ## NUM ## _mc02_3dnow; \
-    c->PFX ## _pixels_tab[IDX][12] = ff_ ## PFX ## NUM ## _mc03_3dnow; \
-
-    dspfunc(put_cavs_qpel, 0, 16);
-    dspfunc(put_cavs_qpel, 1, 8);
-    dspfunc(avg_cavs_qpel, 0, 16);
-    dspfunc(avg_cavs_qpel, 1, 8);
-#undef dspfunc
-    c->cavs_idct8_add = cavs_idct8_add_mmx;
-    c->idct_perm = FF_TRANSPOSE_IDCT_PERM;
+static av_cold void cavsdsp_init_3dnow(CAVSDSPContext *c,
+                                       AVCodecContext *avctx)
+{
+    DSPFUNC(put, 0, 16, 3dnow);
+    DSPFUNC(put, 1,  8, 3dnow);
+    DSPFUNC(avg, 0, 16, 3dnow);
+    DSPFUNC(avg, 1,  8, 3dnow);
 }
 #endif /* HAVE_AMD3DNOW_INLINE */
 
 av_cold void ff_cavsdsp_init_x86(CAVSDSPContext *c, AVCodecContext *avctx)
 {
-    int mm_flags = av_get_cpu_flags();
+#if HAVE_MMX_INLINE
+    int cpu_flags = av_get_cpu_flags();
 
-#if HAVE_MMXEXT_INLINE
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) ff_cavsdsp_init_mmxext(c, avctx);
-#endif /* HAVE_MMXEXT_INLINE */
+    if (INLINE_MMX(cpu_flags))
+        cavsdsp_init_mmx(c, avctx);
+#endif /* HAVE_MMX_INLINE */
 #if HAVE_AMD3DNOW_INLINE
-    if (mm_flags & AV_CPU_FLAG_3DNOW) ff_cavsdsp_init_3dnow(c, avctx);
+    if (INLINE_AMD3DNOW(cpu_flags))
+        cavsdsp_init_3dnow(c, avctx);
 #endif /* HAVE_AMD3DNOW_INLINE */
+#if HAVE_MMXEXT_INLINE
+    if (INLINE_MMXEXT(cpu_flags))
+        cavsdsp_init_mmxext(c, avctx);
+#endif /* HAVE_MMXEXT_INLINE */
 }
diff --git a/libavcodec/x86/constants.c b/libavcodec/x86/constants.c
new file mode 100644
index 0000000..5b8d1b2
--- /dev/null
+++ b/libavcodec/x86/constants.c
@@ -0,0 +1,53 @@
+/*
+ * MMX/SSE constants used across x86 dsp optimizations.
+ *
+ * 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/mem.h"
+#include "libavutil/x86/asm.h" // for xmm_reg
+#include "constants.h"
+
+DECLARE_ALIGNED(8,  const uint64_t, ff_wtwo) = 0x0002000200020002ULL;
+
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_1)    = { 0x0001000100010001ULL, 0x0001000100010001ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_2)    = { 0x0002000200020002ULL, 0x0002000200020002ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_3)    = { 0x0003000300030003ULL, 0x0003000300030003ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_4)    = { 0x0004000400040004ULL, 0x0004000400040004ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_5)    = { 0x0005000500050005ULL, 0x0005000500050005ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_8)    = { 0x0008000800080008ULL, 0x0008000800080008ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_9)    = { 0x0009000900090009ULL, 0x0009000900090009ULL };
+DECLARE_ALIGNED(8,  const uint64_t, ff_pw_15)   =   0x000F000F000F000FULL;
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_16)   = { 0x0010001000100010ULL, 0x0010001000100010ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_17)   = { 0x0011001100110011ULL, 0x0011001100110011ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_18)   = { 0x0012001200120012ULL, 0x0012001200120012ULL };
+DECLARE_ALIGNED(8,  const uint64_t, ff_pw_20)   =   0x0014001400140014ULL;
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_32)   = { 0x0020002000200020ULL, 0x0020002000200020ULL };
+DECLARE_ALIGNED(8,  const uint64_t, ff_pw_42)   =   0x002A002A002A002AULL;
+DECLARE_ALIGNED(8,  const uint64_t, ff_pw_53)   =   0x0035003500350035ULL;
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_64)   = { 0x0040004000400040ULL, 0x0040004000400040ULL };
+DECLARE_ALIGNED(8,  const uint64_t, ff_pw_96)   =   0x0060006000600060ULL;
+DECLARE_ALIGNED(8,  const uint64_t, ff_pw_128)  =   0x0080008000800080ULL;
+DECLARE_ALIGNED(8,  const uint64_t, ff_pw_255)  =   0x00ff00ff00ff00ffULL;
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_512)  = { 0x0200020002000200ULL, 0x0200020002000200ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL };
+
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_0)    = { 0x0000000000000000ULL, 0x0000000000000000ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_1)    = { 0x0101010101010101ULL, 0x0101010101010101ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_3)    = { 0x0303030303030303ULL, 0x0303030303030303ULL };
+DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_80)   = { 0x8080808080808080ULL, 0x8080808080808080ULL };
+DECLARE_ALIGNED(8,  const uint64_t, ff_pb_FC)   =   0xFCFCFCFCFCFCFCFCULL;
diff --git a/libavcodec/x86/constants.h b/libavcodec/x86/constants.h
new file mode 100644
index 0000000..f38fbe3
--- /dev/null
+++ b/libavcodec/x86/constants.h
@@ -0,0 +1,51 @@
+/*
+ * MMX/SSE constants used across x86 dsp optimizations.
+ *
+ * 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_X86_CONSTANTS_H
+#define AVCODEC_X86_CONSTANTS_H
+
+#include <stdint.h>
+
+#include "libavutil/x86/asm.h"
+
+extern const uint64_t ff_wtwo;
+
+extern const xmm_reg  ff_pw_3;
+extern const xmm_reg  ff_pw_4;
+extern const xmm_reg  ff_pw_5;
+extern const xmm_reg  ff_pw_8;
+extern const uint64_t ff_pw_15;
+extern const xmm_reg  ff_pw_16;
+extern const xmm_reg  ff_pw_18;
+extern const uint64_t ff_pw_20;
+extern const xmm_reg  ff_pw_32;
+extern const uint64_t ff_pw_42;
+extern const uint64_t ff_pw_53;
+extern const xmm_reg  ff_pw_64;
+extern const uint64_t ff_pw_96;
+extern const uint64_t ff_pw_128;
+extern const uint64_t ff_pw_255;
+
+extern const xmm_reg  ff_pb_1;
+extern const xmm_reg  ff_pb_3;
+extern const xmm_reg  ff_pb_F8;
+extern const uint64_t ff_pb_FC;
+
+#endif /* AVCODEC_X86_CONSTANTS_H */
diff --git a/libavcodec/x86/dct_init.c b/libavcodec/x86/dct_init.c
new file mode 100644
index 0000000..7bda5e8
--- /dev/null
+++ b/libavcodec/x86/dct_init.c
@@ -0,0 +1,39 @@
+/*
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/dct.h"
+
+void ff_dct32_float_sse(FFTSample *out, const FFTSample *in);
+void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in);
+void ff_dct32_float_avx(FFTSample *out, const FFTSample *in);
+
+av_cold void ff_dct_init_x86(DCTContext *s)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (EXTERNAL_SSE(cpu_flags))
+        s->dct32 = ff_dct32_float_sse;
+    if (EXTERNAL_SSE2(cpu_flags))
+        s->dct32 = ff_dct32_float_sse2;
+    if (EXTERNAL_AVX(cpu_flags))
+        s->dct32 = ff_dct32_float_avx;
+}
diff --git a/libavcodec/x86/dnxhdenc.c b/libavcodec/x86/dnxhdenc.c
index 43ee246..0bab69f 100644
--- a/libavcodec/x86/dnxhdenc.c
+++ b/libavcodec/x86/dnxhdenc.c
@@ -21,12 +21,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
 #include "libavcodec/dnxhdenc.h"
 
 #if HAVE_SSE2_INLINE
 
-static void get_pixels_8x4_sym_sse2(DCTELEM *block, const uint8_t *pixels, int line_size)
+static void get_pixels_8x4_sym_sse2(int16_t *block, const uint8_t *pixels, int line_size)
 {
     __asm__ volatile(
         "pxor %%xmm5,      %%xmm5       \n\t"
@@ -54,10 +56,10 @@ static void get_pixels_8x4_sym_sse2(DCTELEM *block, const uint8_t *pixels, int l
 
 #endif /* HAVE_SSE2_INLINE */
 
-void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx)
+av_cold void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx)
 {
 #if HAVE_SSE2_INLINE
-    if (av_get_cpu_flags() & AV_CPU_FLAG_SSE2) {
+    if (INLINE_SSE2(av_get_cpu_flags())) {
         if (ctx->cid_table->bit_depth == 8)
             ctx->get_pixels_8x4_sym = get_pixels_8x4_sym_sse2;
     }
diff --git a/libavcodec/x86/dsputil.asm b/libavcodec/x86/dsputil.asm
index b9990bb..5d73ff8 100644
--- a/libavcodec/x86/dsputil.asm
+++ b/libavcodec/x86/dsputil.asm
@@ -463,32 +463,6 @@ cglobal add_hfyu_left_prediction, 3,3,7, dst, src, w, left
 .src_unaligned:
     ADD_HFYU_LEFT_LOOP 0, 0
 
-
-; float scalarproduct_float_sse(const float *v1, const float *v2, int len)
-INIT_XMM sse
-cglobal scalarproduct_float, 3,3,2, v1, v2, offset
-    neg offsetq
-    shl offsetq, 2
-    sub v1q, offsetq
-    sub v2q, offsetq
-    xorps xmm0, xmm0
-    .loop:
-        movaps   xmm1, [v1q+offsetq]
-        mulps    xmm1, [v2q+offsetq]
-        addps    xmm0, xmm1
-        add      offsetq, 16
-        js       .loop
-    movhlps xmm1, xmm0
-    addps   xmm0, xmm1
-    movss   xmm1, xmm0
-    shufps  xmm0, xmm0, 1
-    addss   xmm0, xmm1
-%if ARCH_X86_64 == 0
-    movss   r0m,  xmm0
-    fld     dword r0m
-%endif
-    RET
-
 ;-----------------------------------------------------------------------------
 ; void ff_vector_clip_int32(int32_t *dst, const int32_t *src, int32_t min,
 ;                           int32_t max, unsigned int len)
@@ -567,115 +541,6 @@ VECTOR_CLIP_INT32 11, 1, 1, 0
 VECTOR_CLIP_INT32 6, 1, 0, 0
 %endif
 
-;-----------------------------------------------------------------------------
-; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
-;                          int len)
-;-----------------------------------------------------------------------------
-%macro VECTOR_FMUL_REVERSE 0
-cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
-    lea       lenq, [lend*4 - 2*mmsize]
-ALIGN 16
-.loop:
-%if cpuflag(avx)
-    vmovaps     xmm0, [src1q + 16]
-    vinsertf128 m0, m0, [src1q], 1
-    vshufps     m0, m0, m0, q0123
-    vmovaps     xmm1, [src1q + mmsize + 16]
-    vinsertf128 m1, m1, [src1q + mmsize], 1
-    vshufps     m1, m1, m1, q0123
-%else
-    mova    m0, [src1q]
-    mova    m1, [src1q + mmsize]
-    shufps  m0, m0, q0123
-    shufps  m1, m1, q0123
-%endif
-    mulps   m0, m0, [src0q + lenq + mmsize]
-    mulps   m1, m1, [src0q + lenq]
-    mova    [dstq + lenq + mmsize], m0
-    mova    [dstq + lenq], m1
-    add     src1q, 2*mmsize
-    sub     lenq,  2*mmsize
-    jge     .loop
-    REP_RET
-%endmacro
-
-INIT_XMM sse
-VECTOR_FMUL_REVERSE
-INIT_YMM avx
-VECTOR_FMUL_REVERSE
-
-;-----------------------------------------------------------------------------
-; vector_fmul_add(float *dst, const float *src0, const float *src1,
-;                 const float *src2, int len)
-;-----------------------------------------------------------------------------
-%macro VECTOR_FMUL_ADD 0
-cglobal vector_fmul_add, 5,5,2, dst, src0, src1, src2, len
-    lea       lenq, [lend*4 - 2*mmsize]
-ALIGN 16
-.loop:
-    mova    m0,   [src0q + lenq]
-    mova    m1,   [src0q + lenq + mmsize]
-    mulps   m0, m0, [src1q + lenq]
-    mulps   m1, m1, [src1q + lenq + mmsize]
-    addps   m0, m0, [src2q + lenq]
-    addps   m1, m1, [src2q + lenq + mmsize]
-    mova    [dstq + lenq], m0
-    mova    [dstq + lenq + mmsize], m1
-
-    sub     lenq,   2*mmsize
-    jge     .loop
-    REP_RET
-%endmacro
-
-INIT_XMM sse
-VECTOR_FMUL_ADD
-INIT_YMM avx
-VECTOR_FMUL_ADD
-
-;-----------------------------------------------------------------------------
-; void ff_butterflies_float_interleave(float *dst, const float *src0,
-;                                      const float *src1, int len);
-;-----------------------------------------------------------------------------
-
-%macro BUTTERFLIES_FLOAT_INTERLEAVE 0
-cglobal butterflies_float_interleave, 4,4,3, dst, src0, src1, len
-%if ARCH_X86_64
-    movsxd    lenq, lend
-%endif
-    test      lenq, lenq
-    jz .end
-    shl       lenq, 2
-    lea      src0q, [src0q +   lenq]
-    lea      src1q, [src1q +   lenq]
-    lea       dstq, [ dstq + 2*lenq]
-    neg       lenq
-.loop:
-    mova        m0, [src0q + lenq]
-    mova        m1, [src1q + lenq]
-    subps       m2, m0, m1
-    addps       m0, m0, m1
-    unpcklps    m1, m0, m2
-    unpckhps    m0, m0, m2
-%if cpuflag(avx)
-    vextractf128 [dstq + 2*lenq     ], m1, 0
-    vextractf128 [dstq + 2*lenq + 16], m0, 0
-    vextractf128 [dstq + 2*lenq + 32], m1, 1
-    vextractf128 [dstq + 2*lenq + 48], m0, 1
-%else
-    mova [dstq + 2*lenq         ], m1
-    mova [dstq + 2*lenq + mmsize], m0
-%endif
-    add       lenq, mmsize
-    jl .loop
-.end:
-    REP_RET
-%endmacro
-
-INIT_XMM sse
-BUTTERFLIES_FLOAT_INTERLEAVE
-INIT_YMM avx
-BUTTERFLIES_FLOAT_INTERLEAVE
-
 ; %1 = aligned/unaligned
 %macro BSWAP_LOOPS  1
     mov      r3, r2
@@ -687,8 +552,8 @@ BUTTERFLIES_FLOAT_INTERLEAVE
 %if cpuflag(ssse3)
     pshufb   m0, m2
     pshufb   m1, m2
-    mova     [r0 +  0], m0
-    mova     [r0 + 16], m1
+    mov%1    [r0 +  0], m0
+    mov%1    [r0 + 16], m1
 %else
     pshuflw  m0, m0, 10110001b
     pshuflw  m1, m1, 10110001b
@@ -702,8 +567,8 @@ BUTTERFLIES_FLOAT_INTERLEAVE
     psrlw    m3, 8
     por      m2, m0
     por      m3, m1
-    mova     [r0 +  0], m2
-    mova     [r0 + 16], m3
+    mov%1    [r0 +  0], m2
+    mov%1    [r0 + 16], m3
 %endif
     add      r0, 32
     add      r1, 32
@@ -716,7 +581,7 @@ BUTTERFLIES_FLOAT_INTERLEAVE
     mov%1    m0, [r1]
 %if cpuflag(ssse3)
     pshufb   m0, m2
-    mova     [r0], m0
+    mov%1    [r0], m0
 %else
     pshuflw  m0, m0, 10110001b
     pshufhw  m0, m0, 10110001b
@@ -724,7 +589,7 @@ BUTTERFLIES_FLOAT_INTERLEAVE
     psllw    m0, 8
     psrlw    m2, 8
     por      m2, m0
-    mova     [r0], m2
+    mov%1    [r0], m2
 %endif
     add      r1, 16
     add      r0, 16
@@ -783,234 +648,3 @@ BSWAP32_BUF
 
 INIT_XMM ssse3
 BSWAP32_BUF
-
-%macro op_avgh 3
-    movh   %3, %2
-    pavgb  %1, %3
-    movh   %2, %1
-%endmacro
-
-%macro op_avg 2
-    pavgb  %1, %2
-    mova   %2, %1
-%endmacro
-
-%macro op_puth 2-3
-    movh   %2, %1
-%endmacro
-
-%macro op_put 2
-    mova   %2, %1
-%endmacro
-
-; void pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-%macro PIXELS4_L2 1
-%define OP op_%1h
-cglobal %1_pixels4_l2, 6,6
-    movsxdifnidn r3, r3d
-    movsxdifnidn r4, r4d
-    test        r5d, 1
-    je        .loop
-    movd         m0, [r1]
-    movd         m1, [r2]
-    add          r1, r4
-    add          r2, 4
-    pavgb        m0, m1
-    OP           m0, [r0], m3
-    add          r0, r3
-    dec         r5d
-.loop:
-    mova         m0, [r1]
-    mova         m1, [r1+r4]
-    lea          r1, [r1+2*r4]
-    pavgb        m0, [r2]
-    pavgb        m1, [r2+4]
-    OP           m0, [r0], m3
-    OP           m1, [r0+r3], m3
-    lea          r0, [r0+2*r3]
-    mova         m0, [r1]
-    mova         m1, [r1+r4]
-    lea          r1, [r1+2*r4]
-    pavgb        m0, [r2+8]
-    pavgb        m1, [r2+12]
-    OP           m0, [r0], m3
-    OP           m1, [r0+r3], m3
-    lea          r0, [r0+2*r3]
-    add          r2, 16
-    sub         r5d, 4
-    jne       .loop
-    REP_RET
-%endmacro
-
-INIT_MMX mmxext
-PIXELS4_L2 put
-PIXELS4_L2 avg
-
-; void pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-%macro PIXELS8_L2 1
-%define OP op_%1
-cglobal %1_pixels8_l2, 6,6
-    movsxdifnidn r3, r3d
-    movsxdifnidn r4, r4d
-    test        r5d, 1
-    je        .loop
-    mova         m0, [r1]
-    mova         m1, [r2]
-    add          r1, r4
-    add          r2, 8
-    pavgb        m0, m1
-    OP           m0, [r0]
-    add          r0, r3
-    dec         r5d
-.loop:
-    mova         m0, [r1]
-    mova         m1, [r1+r4]
-    lea          r1, [r1+2*r4]
-    pavgb        m0, [r2]
-    pavgb        m1, [r2+8]
-    OP           m0, [r0]
-    OP           m1, [r0+r3]
-    lea          r0, [r0+2*r3]
-    mova         m0, [r1]
-    mova         m1, [r1+r4]
-    lea          r1, [r1+2*r4]
-    pavgb        m0, [r2+16]
-    pavgb        m1, [r2+24]
-    OP           m0, [r0]
-    OP           m1, [r0+r3]
-    lea          r0, [r0+2*r3]
-    add          r2, 32
-    sub         r5d, 4
-    jne       .loop
-    REP_RET
-%endmacro
-
-INIT_MMX mmxext
-PIXELS8_L2 put
-PIXELS8_L2 avg
-
-; void pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-%macro PIXELS16_L2 1
-%define OP op_%1
-cglobal %1_pixels16_l2, 6,6
-    movsxdifnidn r3, r3d
-    movsxdifnidn r4, r4d
-    test        r5d, 1
-    je        .loop
-    mova         m0, [r1]
-    mova         m1, [r1+8]
-    pavgb        m0, [r2]
-    pavgb        m1, [r2+8]
-    add          r1, r4
-    add          r2, 16
-    OP           m0, [r0]
-    OP           m1, [r0+8]
-    add          r0, r3
-    dec         r5d
-.loop:
-    mova         m0, [r1]
-    mova         m1, [r1+8]
-    add          r1, r4
-    pavgb        m0, [r2]
-    pavgb        m1, [r2+8]
-    OP           m0, [r0]
-    OP           m1, [r0+8]
-    add          r0, r3
-    mova         m0, [r1]
-    mova         m1, [r1+8]
-    add          r1, r4
-    pavgb        m0, [r2+16]
-    pavgb        m1, [r2+24]
-    OP           m0, [r0]
-    OP           m1, [r0+8]
-    add          r0, r3
-    add          r2, 32
-    sub         r5d, 2
-    jne       .loop
-    REP_RET
-%endmacro
-
-INIT_MMX mmxext
-PIXELS16_L2 put
-PIXELS16_L2 avg
-
-INIT_MMX mmxext
-; void pixels(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-%macro PIXELS48 2
-%if %2 == 4
-%define OP movh
-%else
-%define OP mova
-%endif
-cglobal %1_pixels%2, 4,5
-    movsxdifnidn r2, r2d
-    lea          r4, [r2*3]
-.loop:
-    OP           m0, [r1]
-    OP           m1, [r1+r2]
-    OP           m2, [r1+r2*2]
-    OP           m3, [r1+r4]
-    lea          r1, [r1+r2*4]
-%ifidn %1, avg
-    pavgb        m0, [r0]
-    pavgb        m1, [r0+r2]
-    pavgb        m2, [r0+r2*2]
-    pavgb        m3, [r0+r4]
-%endif
-    OP         [r0], m0
-    OP      [r0+r2], m1
-    OP    [r0+r2*2], m2
-    OP      [r0+r4], m3
-    sub         r3d, 4
-    lea          r0, [r0+r2*4]
-    jne       .loop
-    RET
-%endmacro
-
-PIXELS48 put, 4
-PIXELS48 avg, 4
-PIXELS48 put, 8
-PIXELS48 avg, 8
-
-INIT_XMM sse2
-; void put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-cglobal put_pixels16, 4,5,4
-    movsxdifnidn r2, r2d
-    lea          r4, [r2*3]
-.loop:
-    movu         m0, [r1]
-    movu         m1, [r1+r2]
-    movu         m2, [r1+r2*2]
-    movu         m3, [r1+r4]
-    lea          r1, [r1+r2*4]
-    mova       [r0], m0
-    mova    [r0+r2], m1
-    mova  [r0+r2*2], m2
-    mova    [r0+r4], m3
-    sub         r3d, 4
-    lea          r0, [r0+r2*4]
-    jnz       .loop
-    REP_RET
-
-; void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-cglobal avg_pixels16, 4,5,4
-    movsxdifnidn r2, r2d
-    lea          r4, [r2*3]
-.loop:
-    movu         m0, [r1]
-    movu         m1, [r1+r2]
-    movu         m2, [r1+r2*2]
-    movu         m3, [r1+r4]
-    lea          r1, [r1+r2*4]
-    pavgb        m0, [r0]
-    pavgb        m1, [r0+r2]
-    pavgb        m2, [r0+r2*2]
-    pavgb        m3, [r0+r4]
-    mova       [r0], m0
-    mova    [r0+r2], m1
-    mova  [r0+r2*2], m2
-    mova    [r0+r4], m3
-    sub         r3d, 4
-    lea          r0, [r0+r2*4]
-    jnz       .loop
-    REP_RET
diff --git a/libavcodec/x86/dsputil_avg_template.c b/libavcodec/x86/dsputil_avg_template.c
deleted file mode 100644
index 1a4343d..0000000
--- a/libavcodec/x86/dsputil_avg_template.c
+++ /dev/null
@@ -1,855 +0,0 @@
-/*
- * DSP utils : average functions are compiled twice for 3dnow/mmxext
- * Copyright (c) 2000, 2001 Fabrice Bellard
- * Copyright (c) 2002-2004 Michael Niedermayer
- *
- * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
- * mostly rewritten by Michael Niedermayer <michaelni at gmx.at>
- * and improved by Zdenek Kabelac <kabi at users.sf.net>
- *
- * 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
- */
-
-/* XXX: we use explicit registers to avoid a gcc 2.95.2 register asm
-   clobber bug - now it will work with 2.95.2 and also with -fPIC
- */
-static void DEF(put_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-#ifndef SKIP_FOR_3DNOW
-static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $8, %2                  \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" 16(%2), %%mm0            \n\t"
-        PAVGB" 24(%2), %%mm1            \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-
-static void DEF(put_no_rnd_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "pcmpeqb %%mm6, %%mm6           \n\t"
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $8, %2                  \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%2), %%mm2             \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   16(%2), %%mm2           \n\t"
-        "movq   24(%2), %%mm3           \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-
-static void DEF(avg_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $8, %2                  \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        PAVGB" (%3), %%mm1              \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" 16(%2), %%mm0            \n\t"
-        PAVGB" 24(%2), %%mm1            \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        PAVGB" (%3), %%mm1              \n\t"
-        "movq   %%mm1, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE  //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-#endif /* SKIP_FOR_3DNOW */
-
-static void DEF(put_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq 8(%1), %%mm2              \n\t"
-        "movq 8(%1, %3), %%mm3          \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        PAVGB" 9(%1), %%mm2             \n\t"
-        PAVGB" 9(%1, %3), %%mm3         \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "movq %%mm2, 8(%2)              \n\t"
-        "movq %%mm3, 8(%2, %3)          \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq 8(%1), %%mm2              \n\t"
-        "movq 8(%1, %3), %%mm3          \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        PAVGB" 9(%1), %%mm2             \n\t"
-        PAVGB" 9(%1, %3), %%mm3         \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "movq %%mm2, 8(%2)              \n\t"
-        "movq %%mm3, 8(%2, %3)          \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-#ifndef SKIP_FOR_3DNOW
-static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $16, %2                 \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" 16(%2), %%mm0            \n\t"
-        PAVGB" 24(%2), %%mm1            \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE  //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-
-static void DEF(avg_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $16, %2                 \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        PAVGB" 8(%3), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" 8(%2), %%mm1             \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        PAVGB" 8(%3), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGB" 16(%2), %%mm0            \n\t"
-        PAVGB" 24(%2), %%mm1            \n\t"
-        PAVGB" (%3), %%mm0              \n\t"
-        PAVGB" 8(%3), %%mm1             \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE  //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-
-static void DEF(put_no_rnd_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    __asm__ volatile(
-        "pcmpeqb %%mm6, %%mm6           \n\t"
-        "testl $1, %0                   \n\t"
-            " jz 1f                     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "movq   (%2), %%mm2             \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $16, %2                 \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%2), %%mm2             \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   8(%1), %%mm1            \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   16(%2), %%mm2           \n\t"
-        "movq   24(%2), %%mm3           \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "pxor %%mm6, %%mm2              \n\t"
-        "pxor %%mm6, %%mm3              \n\t"
-        PAVGB" %%mm2, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm1             \n\t"
-        "pxor %%mm6, %%mm0              \n\t"
-        "pxor %%mm6, %%mm1              \n\t"
-        "movq   %%mm0, (%3)             \n\t"
-        "movq   %%mm1, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-//the following should be used, though better not with gcc ...
-/*        :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
-        :"r"(src1Stride), "r"(dstStride)
-        :"memory");*/
-}
-#endif /* SKIP_FOR_3DNOW */
-
-/* GL: this function does incorrect rounding if overflow */
-static void DEF(put_no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BONE(mm6);
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm2           \n\t"
-        "movq 1(%1), %%mm1              \n\t"
-        "movq 1(%1, %3), %%mm3          \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "psubusb %%mm6, %%mm0           \n\t"
-        "psubusb %%mm6, %%mm2           \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq 1(%1), %%mm1              \n\t"
-        "movq (%1, %3), %%mm2           \n\t"
-        "movq 1(%1, %3), %%mm3          \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "psubusb %%mm6, %%mm0           \n\t"
-        "psubusb %%mm6, %%mm2           \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-static void DEF(put_no_rnd_pixels8_x2_exact)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile (
-        "pcmpeqb %%mm6, %%mm6           \n\t"
-        "1:                             \n\t"
-        "movq  (%1),     %%mm0          \n\t"
-        "movq  (%1, %3), %%mm2          \n\t"
-        "movq 1(%1),     %%mm1          \n\t"
-        "movq 1(%1, %3), %%mm3          \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm3             \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "movq  %%mm0, (%2)              \n\t"
-        "movq  %%mm2, (%2, %3)          \n\t"
-        "movq  (%1, %3,2), %%mm0        \n\t"
-        "movq 1(%1, %3,2), %%mm1        \n\t"
-        "movq  (%1, %4),   %%mm2        \n\t"
-        "movq 1(%1, %4),   %%mm3        \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm3             \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "movq  %%mm0, (%2, %3,2)        \n\t"
-        "movq  %%mm2, (%2, %4)          \n\t"
-        "lea   (%1, %3,4), %1           \n\t"
-        "lea   (%2, %3,4), %2           \n\t"
-        "subl  $4, %0                   \n\t"
-        "jg 1b                          \n\t"
-        : "+g"(h), "+r"(pixels), "+r"(block)
-        : "r" ((x86_reg)line_size), "r"((x86_reg)3*line_size)
-        : "memory"
-    );
-}
-
-static void DEF(put_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "sub %3, %2                     \n\t"
-        "1:                             \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm2    \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        "movq %%mm0, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm0    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D" (block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-/* GL: this function does incorrect rounding if overflow */
-static void DEF(put_no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BONE(mm6);
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "sub %3, %2                     \n\t"
-        "1:                             \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm2    \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "psubusb %%mm6, %%mm1           \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        "movq %%mm0, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm0    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "psubusb %%mm6, %%mm1           \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D" (block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-static void DEF(put_no_rnd_pixels8_y2_exact)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile (
-        "movq     (%1), %%mm0           \n\t"
-        "pcmpeqb %%mm6, %%mm6           \n\t"
-        "add        %3, %1              \n\t"
-        "pxor    %%mm6, %%mm0           \n\t"
-        "1:                             \n\t"
-        "movq  (%1),     %%mm1          \n\t"
-        "movq  (%1, %3), %%mm2          \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "movq  %%mm0, (%2)              \n\t"
-        "movq  %%mm1, (%2, %3)          \n\t"
-        "movq  (%1, %3,2), %%mm1        \n\t"
-        "movq  (%1, %4),   %%mm0        \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm0             \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        "pxor  %%mm6, %%mm2             \n\t"
-        "pxor  %%mm6, %%mm1             \n\t"
-        "movq %%mm2, (%2, %3,2)         \n\t"
-        "movq %%mm1, (%2, %4)           \n\t"
-        "lea   (%1, %3,4), %1           \n\t"
-        "lea   (%2, %3,4), %2           \n\t"
-        "subl $4, %0                    \n\t"
-        "jg 1b                          \n\t"
-        :"+g"(h), "+r"(pixels), "+r" (block)
-        :"r" ((x86_reg)line_size), "r"((x86_reg)3*line_size)
-        :"memory"
-    );
-}
-
-static void DEF(avg_pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%2), %%mm0               \n\t"
-        "movq (%2, %3), %%mm1           \n\t"
-        PAVGB" (%1), %%mm0              \n\t"
-        PAVGB" (%1, %3), %%mm1          \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "movq (%2), %%mm0               \n\t"
-        "movq (%2, %3), %%mm1           \n\t"
-        PAVGB" (%1), %%mm0              \n\t"
-        PAVGB" (%1, %3), %%mm1          \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-static void DEF(avg_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "1:                             \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm2           \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm2         \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" (%2, %3), %%mm2          \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "movq (%1, %3), %%mm2           \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-        PAVGB" 1(%1, %3), %%mm2         \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" (%2, %3), %%mm2          \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-static void DEF(avg_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        "sub %3, %2                     \n\t"
-        "1:                             \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm2    \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        "movq (%2, %3), %%mm3           \n\t"
-        "movq (%2, %%"REG_a"), %%mm4    \n\t"
-        PAVGB" %%mm3, %%mm0             \n\t"
-        PAVGB" %%mm4, %%mm1             \n\t"
-        "movq %%mm0, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm0    \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        "movq (%2, %3), %%mm3           \n\t"
-        "movq (%2, %%"REG_a"), %%mm4    \n\t"
-        PAVGB" %%mm3, %%mm2             \n\t"
-        PAVGB" %%mm4, %%mm1             \n\t"
-        "movq %%mm2, (%2, %3)           \n\t"
-        "movq %%mm1, (%2, %%"REG_a")    \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a, "memory");
-}
-
-/* Note this is not correctly rounded, but this function is only
- * used for B-frames so it does not matter. */
-static void DEF(avg_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BONE(mm6);
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        PAVGB" 1(%1), %%mm0             \n\t"
-         ".p2align 3                    \n\t"
-        "1:                             \n\t"
-        "movq (%1, %%"REG_a"), %%mm2    \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "psubusb %%mm6, %%mm2           \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        PAVGB" 1(%1, %%"REG_a"), %%mm2  \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm0             \n\t"
-        PAVGB" %%mm2, %%mm1             \n\t"
-        PAVGB" (%2), %%mm0              \n\t"
-        PAVGB" (%2, %3), %%mm1          \n\t"
-        "movq %%mm0, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "movq (%1, %3), %%mm1           \n\t"
-        "movq (%1, %%"REG_a"), %%mm0    \n\t"
-        PAVGB" 1(%1, %3), %%mm1         \n\t"
-        PAVGB" 1(%1, %%"REG_a"), %%mm0  \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "add %%"REG_a", %1              \n\t"
-        PAVGB" %%mm1, %%mm2             \n\t"
-        PAVGB" %%mm0, %%mm1             \n\t"
-        PAVGB" (%2), %%mm2              \n\t"
-        PAVGB" (%2, %3), %%mm1          \n\t"
-        "movq %%mm2, (%2)               \n\t"
-        "movq %%mm1, (%2, %3)           \n\t"
-        "add %%"REG_a", %2              \n\t"
-        "subl $4, %0                    \n\t"
-        "jnz 1b                         \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r" ((x86_reg)line_size)
-        :"%"REG_a,  "memory");
-}
-
-//FIXME the following could be optimized too ...
-static void DEF(put_no_rnd_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(put_no_rnd_pixels8_x2)(block  , pixels  , line_size, h);
-    DEF(put_no_rnd_pixels8_x2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(put_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(put_pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(put_pixels8_y2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(put_no_rnd_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(put_no_rnd_pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(put_no_rnd_pixels8_y2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(avg_pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg_pixels8)(block  , pixels  , line_size, h);
-    DEF(avg_pixels8)(block+8, pixels+8, line_size, h);
-}
-static void DEF(avg_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg_pixels8_x2)(block  , pixels  , line_size, h);
-    DEF(avg_pixels8_x2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(avg_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg_pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(avg_pixels8_y2)(block+8, pixels+8, line_size, h);
-}
-static void DEF(avg_pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg_pixels8_xy2)(block  , pixels  , line_size, h);
-    DEF(avg_pixels8_xy2)(block+8, pixels+8, line_size, h);
-}
-
-#define QPEL_2TAP_L3(OPNAME) \
-static void DEF(OPNAME ## 2tap_qpel16_l3)(uint8_t *dst, uint8_t *src, int stride, int h, int off1, int off2){\
-    __asm__ volatile(\
-        "1:                    \n\t"\
-        "movq   (%1,%2), %%mm0 \n\t"\
-        "movq  8(%1,%2), %%mm1 \n\t"\
-        PAVGB"  (%1,%3), %%mm0 \n\t"\
-        PAVGB" 8(%1,%3), %%mm1 \n\t"\
-        PAVGB"  (%1),    %%mm0 \n\t"\
-        PAVGB" 8(%1),    %%mm1 \n\t"\
-        STORE_OP( (%1,%4),%%mm0)\
-        STORE_OP(8(%1,%4),%%mm1)\
-        "movq  %%mm0,  (%1,%4) \n\t"\
-        "movq  %%mm1, 8(%1,%4) \n\t"\
-        "add   %5, %1          \n\t"\
-        "decl  %0              \n\t"\
-        "jnz   1b              \n\t"\
-        :"+g"(h), "+r"(src)\
-        :"r"((x86_reg)off1), "r"((x86_reg)off2),\
-         "r"((x86_reg)(dst-src)), "r"((x86_reg)stride)\
-        :"memory"\
-    );\
-}\
-static void DEF(OPNAME ## 2tap_qpel8_l3)(uint8_t *dst, uint8_t *src, int stride, int h, int off1, int off2){\
-    __asm__ volatile(\
-        "1:                    \n\t"\
-        "movq   (%1,%2), %%mm0 \n\t"\
-        PAVGB"  (%1,%3), %%mm0 \n\t"\
-        PAVGB"  (%1),    %%mm0 \n\t"\
-        STORE_OP((%1,%4),%%mm0)\
-        "movq  %%mm0,  (%1,%4) \n\t"\
-        "add   %5, %1          \n\t"\
-        "decl  %0              \n\t"\
-        "jnz   1b              \n\t"\
-        :"+g"(h), "+r"(src)\
-        :"r"((x86_reg)off1), "r"((x86_reg)off2),\
-         "r"((x86_reg)(dst-src)), "r"((x86_reg)stride)\
-        :"memory"\
-    );\
-}
-
-#ifndef SKIP_FOR_3DNOW
-#define STORE_OP(a,b) PAVGB" "#a","#b" \n\t"
-QPEL_2TAP_L3(avg_)
-#undef STORE_OP
-#define STORE_OP(a,b)
-QPEL_2TAP_L3(put_)
-#undef STORE_OP
-#undef QPEL_2TAP_L3
-#endif /* SKIP_FOR_3DNOW */
diff --git a/libavcodec/x86/dsputil_init.c b/libavcodec/x86/dsputil_init.c
new file mode 100644
index 0000000..c339e8f
--- /dev/null
+++ b/libavcodec/x86/dsputil_init.c
@@ -0,0 +1,690 @@
+/*
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/internal.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/dsputil.h"
+#include "libavcodec/simple_idct.h"
+#include "dsputil_x86.h"
+#include "idct_xvid.h"
+
+void ff_put_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                              int dstStride, int src1Stride, int h);
+void ff_put_no_rnd_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1,
+                                     uint8_t *src2, int dstStride,
+                                     int src1Stride, int h);
+void ff_avg_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                              int dstStride, int src1Stride, int h);
+void ff_put_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                               int dstStride, int src1Stride, int h);
+void ff_avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                               int dstStride, int src1Stride, int h);
+void ff_put_no_rnd_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
+                                      int dstStride, int src1Stride, int h);
+void ff_put_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                         int dstStride, int srcStride, int h);
+void ff_avg_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                         int dstStride, int srcStride, int h);
+void ff_put_no_rnd_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                                 int dstStride, int srcStride,
+                                                 int h);
+void ff_put_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                        int dstStride, int srcStride, int h);
+void ff_avg_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                        int dstStride, int srcStride, int h);
+void ff_put_no_rnd_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                                int dstStride, int srcStride,
+                                                int h);
+void ff_put_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                         int dstStride, int srcStride);
+void ff_avg_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                         int dstStride, int srcStride);
+void ff_put_no_rnd_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                                 int dstStride, int srcStride);
+void ff_put_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                        int dstStride, int srcStride);
+void ff_avg_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                        int dstStride, int srcStride);
+void ff_put_no_rnd_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
+                                                int dstStride, int srcStride);
+#define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmxext
+#define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmxext
+
+int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2,
+                                      int order);
+int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2,
+                                    int order);
+int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2,
+                                               const int16_t *v3,
+                                               int order, int mul);
+int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2,
+                                             const int16_t *v3,
+                                             int order, int mul);
+int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2,
+                                              const int16_t *v3,
+                                              int order, int mul);
+
+void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w);
+void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w);
+
+void ff_add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top,
+                                          const uint8_t *diff, int w,
+                                          int *left, int *left_top);
+int  ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src,
+                                       int w, int left);
+int  ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
+                                      int w, int left);
+
+void ff_vector_clip_int32_mmx     (int32_t *dst, const int32_t *src,
+                                   int32_t min, int32_t max, unsigned int len);
+void ff_vector_clip_int32_sse2    (int32_t *dst, const int32_t *src,
+                                   int32_t min, int32_t max, unsigned int len);
+void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src,
+                                   int32_t min, int32_t max, unsigned int len);
+void ff_vector_clip_int32_sse4    (int32_t *dst, const int32_t *src,
+                                   int32_t min, int32_t max, unsigned int len);
+
+#if HAVE_YASM
+
+PIXELS16(static, ff_avg, , , _mmxext)
+PIXELS16(static, ff_put, , , _mmxext)
+
+#define QPEL_OP(OPNAME, RND, MMX)                                       \
+static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8);              \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t temp[8];                                                   \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,        \
+                                                   stride, 8);          \
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half,                 \
+                                        stride, stride, 8);             \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride,    \
+                                                   stride, 8);          \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t temp[8];                                                   \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,        \
+                                                   stride, 8);          \
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride,     \
+                                        stride, 8);                     \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t temp[8];                                                   \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src,           \
+                                                   8, stride);          \
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half,                 \
+                                        stride, stride, 8);             \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src,            \
+                                                   stride, stride);     \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t temp[8];                                                   \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src,           \
+                                                   8, stride);          \
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,\
+                                        stride, 8);                     \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8,           \
+                                        stride, 9);                     \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
+                                        stride, 9);                     \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8,           \
+                                        stride, 9);                     \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
+                                        stride, 9);                     \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
+    ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
+                                        stride, 8, 8);                  \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH,              \
+                                        8, stride, 9);                  \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
+                                                   stride, 8);          \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[8 + 9];                                               \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
+                                        stride, 9);                     \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
+                                                   stride, 8);          \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, uint8_t *src,    \
+                                         ptrdiff_t stride)              \
+{                                                                       \
+    uint64_t half[9];                                                   \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
+                                                   stride, 9);          \
+    ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
+                                                   stride, 8);          \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc00_ ## MMX (uint8_t *dst, uint8_t *src,  \
+                                           ptrdiff_t stride)            \
+{                                                                       \
+    ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16);            \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t temp[32];                                                  \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,      \
+                                                    stride, 16);        \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride,        \
+                                         stride, 16);                   \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src,           \
+                                                    stride, stride, 16);\
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t temp[32];                                                  \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,      \
+                                                    stride, 16);        \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half,            \
+                                         stride, stride, 16);           \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t temp[32];                                                  \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,      \
+                                                    stride);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride,        \
+                                         stride, 16);                   \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src,           \
+                                                    stride, stride);    \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t temp[32];                                                  \
+    uint8_t * const half = (uint8_t*)temp;                              \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,      \
+                                                    stride);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half,         \
+                                         stride, stride, 16);           \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
+                                         stride, 17);                   \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
+                                         stride, 17);                   \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
+                                         stride, 17);                   \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
+                                         stride, 17);                   \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[16 * 2 + 17 * 2];                                     \
+    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
+    uint8_t * const halfHV = ((uint8_t*)half);                          \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
+                                                    16, 16);            \
+    ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
+                                         stride, 16, 16);               \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[17 * 2];                                              \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
+                                         stride, 17);                   \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
+                                                    stride, 16);        \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[17 * 2];                                              \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
+                                         stride, 17);                   \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
+                                                    stride, 16);        \
+}                                                                       \
+                                                                        \
+static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, uint8_t *src,   \
+                                          ptrdiff_t stride)             \
+{                                                                       \
+    uint64_t half[17 * 2];                                              \
+    uint8_t * const halfH = ((uint8_t*)half);                           \
+    ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
+                                                    stride, 17);        \
+    ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
+                                                    stride, 16);        \
+}
+
+QPEL_OP(put_,        _,        mmxext)
+QPEL_OP(avg_,        _,        mmxext)
+QPEL_OP(put_no_rnd_, _no_rnd_, mmxext)
+#endif /* HAVE_YASM */
+
+#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX)                          \
+    do {                                                                     \
+    c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \
+    } while (0)
+
+static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx,
+                                     int cpu_flags)
+{
+#if HAVE_MMX_INLINE
+    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
+
+    c->put_pixels_clamped        = ff_put_pixels_clamped_mmx;
+    c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx;
+    c->add_pixels_clamped        = ff_add_pixels_clamped_mmx;
+
+    if (!high_bit_depth) {
+        c->clear_block  = ff_clear_block_mmx;
+        c->clear_blocks = ff_clear_blocks_mmx;
+        c->draw_edges   = ff_draw_edges_mmx;
+
+        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;
+        }
+    }
+
+    c->gmc = ff_gmc_mmx;
+
+    c->add_bytes = ff_add_bytes_mmx;
+#endif /* HAVE_MMX_INLINE */
+
+#if HAVE_MMX_EXTERNAL
+    c->vector_clip_int32 = ff_vector_clip_int32_mmx;
+#endif /* HAVE_MMX_EXTERNAL */
+}
+
+static av_cold void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx,
+                                        int cpu_flags)
+{
+#if HAVE_MMXEXT_INLINE
+    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
+
+    if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) {
+        c->idct_put = ff_idct_xvid_mmxext_put;
+        c->idct_add = ff_idct_xvid_mmxext_add;
+        c->idct     = ff_idct_xvid_mmxext;
+    }
+#endif /* HAVE_MMXEXT_INLINE */
+
+#if HAVE_MMXEXT_EXTERNAL
+    SET_QPEL_FUNCS(avg_qpel,        0, 16, mmxext, );
+    SET_QPEL_FUNCS(avg_qpel,        1,  8, mmxext, );
+
+    SET_QPEL_FUNCS(put_qpel,        0, 16, mmxext, );
+    SET_QPEL_FUNCS(put_qpel,        1,  8, mmxext, );
+    SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, );
+    SET_QPEL_FUNCS(put_no_rnd_qpel, 1,  8, mmxext, );
+
+    /* slower than cmov version on AMD */
+    if (!(cpu_flags & AV_CPU_FLAG_3DNOW))
+        c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmxext;
+
+    c->scalarproduct_int16          = ff_scalarproduct_int16_mmxext;
+    c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext;
+#endif /* HAVE_MMXEXT_EXTERNAL */
+}
+
+static av_cold void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx,
+                                     int cpu_flags)
+{
+#if HAVE_SSE_INLINE
+    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
+
+    if (!high_bit_depth) {
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
+        if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) {
+            /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+        c->clear_block  = ff_clear_block_sse;
+        c->clear_blocks = ff_clear_blocks_sse;
+#if FF_API_XVMC
+        }
+#endif /* FF_API_XVMC */
+    }
+
+    c->vector_clipf = ff_vector_clipf_sse;
+#endif /* HAVE_SSE_INLINE */
+}
+
+static av_cold void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx,
+                                      int cpu_flags)
+{
+#if HAVE_SSE2_INLINE
+    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
+
+    if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) {
+        c->idct_put              = ff_idct_xvid_sse2_put;
+        c->idct_add              = ff_idct_xvid_sse2_add;
+        c->idct                  = ff_idct_xvid_sse2;
+        c->idct_permutation_type = FF_SSE2_IDCT_PERM;
+    }
+#endif /* HAVE_SSE2_INLINE */
+
+#if HAVE_SSE2_EXTERNAL
+    c->scalarproduct_int16          = ff_scalarproduct_int16_sse2;
+    c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;
+    if (cpu_flags & AV_CPU_FLAG_ATOM) {
+        c->vector_clip_int32 = ff_vector_clip_int32_int_sse2;
+    } else {
+        c->vector_clip_int32 = ff_vector_clip_int32_sse2;
+    }
+    c->bswap_buf = ff_bswap32_buf_sse2;
+#endif /* HAVE_SSE2_EXTERNAL */
+}
+
+static av_cold void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx,
+                                       int cpu_flags)
+{
+#if HAVE_SSSE3_EXTERNAL
+    c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_ssse3;
+    if (cpu_flags & AV_CPU_FLAG_SSE4) // not really SSE4, just slow on Conroe
+        c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4;
+
+    if (!(cpu_flags & (AV_CPU_FLAG_SSE42 | AV_CPU_FLAG_3DNOW))) // cachesplit
+        c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3;
+    c->bswap_buf = ff_bswap32_buf_ssse3;
+#endif /* HAVE_SSSE3_EXTERNAL */
+}
+
+static av_cold void dsputil_init_sse4(DSPContext *c, AVCodecContext *avctx,
+                                      int cpu_flags)
+{
+#if HAVE_SSE4_EXTERNAL
+    c->vector_clip_int32 = ff_vector_clip_int32_sse4;
+#endif /* HAVE_SSE4_EXTERNAL */
+}
+
+av_cold void ff_dsputil_init_x86(DSPContext *c, AVCodecContext *avctx)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+#if HAVE_7REGS && HAVE_INLINE_ASM
+    if (cpu_flags & AV_CPU_FLAG_CMOV)
+        c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_cmov;
+#endif
+
+    if (X86_MMX(cpu_flags))
+        dsputil_init_mmx(c, avctx, cpu_flags);
+
+    if (X86_MMXEXT(cpu_flags))
+        dsputil_init_mmxext(c, avctx, cpu_flags);
+
+    if (X86_SSE(cpu_flags))
+        dsputil_init_sse(c, avctx, cpu_flags);
+
+    if (X86_SSE2(cpu_flags))
+        dsputil_init_sse2(c, avctx, cpu_flags);
+
+    if (EXTERNAL_SSSE3(cpu_flags))
+        dsputil_init_ssse3(c, avctx, cpu_flags);
+
+    if (EXTERNAL_SSE4(cpu_flags))
+        dsputil_init_sse4(c, avctx, cpu_flags);
+
+    if (CONFIG_ENCODERS)
+        ff_dsputilenc_init_mmx(c, avctx);
+}
diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c
index b16f7e4..885c10a 100644
--- a/libavcodec/x86/dsputil_mmx.c
+++ b/libavcodec/x86/dsputil_mmx.c
@@ -22,220 +22,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
-#include "libavcodec/dsputil.h"
-#include "libavcodec/h264dsp.h"
-#include "libavcodec/mpegvideo.h"
-#include "libavcodec/simple_idct.h"
-#include "dsputil_mmx.h"
-#include "idct_xvid.h"
-
-//#undef NDEBUG
-//#include <assert.h>
-
-/* pixel operations */
-DECLARE_ALIGNED(8,  const uint64_t, ff_bone) = 0x0101010101010101ULL;
-DECLARE_ALIGNED(8,  const uint64_t, ff_wtwo) = 0x0002000200020002ULL;
-
-DECLARE_ALIGNED(16, const uint64_t, ff_pdw_80000000)[2] =
-    { 0x8000000080000000ULL, 0x8000000080000000ULL };
-
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_1)    = { 0x0001000100010001ULL, 0x0001000100010001ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_2)    = { 0x0002000200020002ULL, 0x0002000200020002ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_3)    = { 0x0003000300030003ULL, 0x0003000300030003ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_4)    = { 0x0004000400040004ULL, 0x0004000400040004ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_5)    = { 0x0005000500050005ULL, 0x0005000500050005ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_8)    = { 0x0008000800080008ULL, 0x0008000800080008ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_9)    = { 0x0009000900090009ULL, 0x0009000900090009ULL };
-DECLARE_ALIGNED(8,  const uint64_t, ff_pw_15)   =   0x000F000F000F000FULL;
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_16)   = { 0x0010001000100010ULL, 0x0010001000100010ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_17)   = { 0x0011001100110011ULL, 0x0011001100110011ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_18)   = { 0x0012001200120012ULL, 0x0012001200120012ULL };
-DECLARE_ALIGNED(8,  const uint64_t, ff_pw_20)   =   0x0014001400140014ULL;
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_27)   = { 0x001B001B001B001BULL, 0x001B001B001B001BULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_28)   = { 0x001C001C001C001CULL, 0x001C001C001C001CULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_32)   = { 0x0020002000200020ULL, 0x0020002000200020ULL };
-DECLARE_ALIGNED(8,  const uint64_t, ff_pw_42)   =   0x002A002A002A002AULL;
-DECLARE_ALIGNED(8,  const uint64_t, ff_pw_53)   =   0x0035003500350035ULL;
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_63)   = { 0x003F003F003F003FULL, 0x003F003F003F003FULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_64)   = { 0x0040004000400040ULL, 0x0040004000400040ULL };
-DECLARE_ALIGNED(8,  const uint64_t, ff_pw_96)   =   0x0060006000600060ULL;
-DECLARE_ALIGNED(8,  const uint64_t, ff_pw_128)  =   0x0080008000800080ULL;
-DECLARE_ALIGNED(8,  const uint64_t, ff_pw_255)  =   0x00ff00ff00ff00ffULL;
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_512)  = { 0x0200020002000200ULL, 0x0200020002000200ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL };
-
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_0)    = { 0x0000000000000000ULL, 0x0000000000000000ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_1)    = { 0x0101010101010101ULL, 0x0101010101010101ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_3)    = { 0x0303030303030303ULL, 0x0303030303030303ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_4)    = { 0x0404040404040404ULL, 0x0404040404040404ULL };
-DECLARE_ALIGNED(8,  const uint64_t, ff_pb_7)    =   0x0707070707070707ULL;
-DECLARE_ALIGNED(8,  const uint64_t, ff_pb_1F)   =   0x1F1F1F1F1F1F1F1FULL;
-DECLARE_ALIGNED(8,  const uint64_t, ff_pb_3F)   =   0x3F3F3F3F3F3F3F3FULL;
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_80)   = { 0x8080808080808080ULL, 0x8080808080808080ULL };
-DECLARE_ALIGNED(8,  const uint64_t, ff_pb_81)   =   0x8181818181818181ULL;
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_A1)   = { 0xA1A1A1A1A1A1A1A1ULL, 0xA1A1A1A1A1A1A1A1ULL };
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_F8)   = { 0xF8F8F8F8F8F8F8F8ULL, 0xF8F8F8F8F8F8F8F8ULL };
-DECLARE_ALIGNED(8,  const uint64_t, ff_pb_FC)   =   0xFCFCFCFCFCFCFCFCULL;
-DECLARE_ALIGNED(16, const xmm_reg,  ff_pb_FE)   = { 0xFEFEFEFEFEFEFEFEULL, 0xFEFEFEFEFEFEFEFEULL };
-
-DECLARE_ALIGNED(16, const double, ff_pd_1)[2] = { 1.0, 1.0 };
-DECLARE_ALIGNED(16, const double, ff_pd_2)[2] = { 2.0, 2.0 };
+#include "constants.h"
+#include "dsputil_x86.h"
 
 #if HAVE_INLINE_ASM
 
-#define JUMPALIGN()     __asm__ volatile (".p2align 3"::)
-#define MOVQ_ZERO(regd) __asm__ volatile ("pxor %%"#regd", %%"#regd ::)
-
-#define MOVQ_BFE(regd)                                  \
-    __asm__ volatile (                                  \
-        "pcmpeqd %%"#regd", %%"#regd"   \n\t"           \
-        "paddb   %%"#regd", %%"#regd"   \n\t" ::)
-
-#ifndef PIC
-#define MOVQ_BONE(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_bone))
-#define MOVQ_WTWO(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_wtwo))
-#else
-// for shared library it's better to use this way for accessing constants
-// pcmpeqd -> -1
-#define MOVQ_BONE(regd)                                 \
-    __asm__ volatile (                                  \
-        "pcmpeqd  %%"#regd", %%"#regd"  \n\t"           \
-        "psrlw          $15, %%"#regd"  \n\t"           \
-        "packuswb %%"#regd", %%"#regd"  \n\t" ::)
-
-#define MOVQ_WTWO(regd)                                 \
-    __asm__ volatile (                                  \
-        "pcmpeqd %%"#regd", %%"#regd"   \n\t"           \
-        "psrlw         $15, %%"#regd"   \n\t"           \
-        "psllw          $1, %%"#regd"   \n\t"::)
-
-#endif
-
-// using regr as temporary and for the output result
-// first argument is unmodifed and second is trashed
-// regfe is supposed to contain 0xfefefefefefefefe
-#define PAVGB_MMX_NO_RND(rega, regb, regr, regfe)                \
-    "movq   "#rega", "#regr"            \n\t"                    \
-    "pand   "#regb", "#regr"            \n\t"                    \
-    "pxor   "#rega", "#regb"            \n\t"                    \
-    "pand  "#regfe", "#regb"            \n\t"                    \
-    "psrlq       $1, "#regb"            \n\t"                    \
-    "paddb  "#regb", "#regr"            \n\t"
-
-#define PAVGB_MMX(rega, regb, regr, regfe)                       \
-    "movq   "#rega", "#regr"            \n\t"                    \
-    "por    "#regb", "#regr"            \n\t"                    \
-    "pxor   "#rega", "#regb"            \n\t"                    \
-    "pand  "#regfe", "#regb"            \n\t"                    \
-    "psrlq       $1, "#regb"            \n\t"                    \
-    "psubb  "#regb", "#regr"            \n\t"
-
-// mm6 is supposed to contain 0xfefefefefefefefe
-#define PAVGBP_MMX_NO_RND(rega, regb, regr,  regc, regd, regp)   \
-    "movq  "#rega", "#regr"             \n\t"                    \
-    "movq  "#regc", "#regp"             \n\t"                    \
-    "pand  "#regb", "#regr"             \n\t"                    \
-    "pand  "#regd", "#regp"             \n\t"                    \
-    "pxor  "#rega", "#regb"             \n\t"                    \
-    "pxor  "#regc", "#regd"             \n\t"                    \
-    "pand    %%mm6, "#regb"             \n\t"                    \
-    "pand    %%mm6, "#regd"             \n\t"                    \
-    "psrlq      $1, "#regb"             \n\t"                    \
-    "psrlq      $1, "#regd"             \n\t"                    \
-    "paddb "#regb", "#regr"             \n\t"                    \
-    "paddb "#regd", "#regp"             \n\t"
-
-#define PAVGBP_MMX(rega, regb, regr, regc, regd, regp)           \
-    "movq  "#rega", "#regr"             \n\t"                    \
-    "movq  "#regc", "#regp"             \n\t"                    \
-    "por   "#regb", "#regr"             \n\t"                    \
-    "por   "#regd", "#regp"             \n\t"                    \
-    "pxor  "#rega", "#regb"             \n\t"                    \
-    "pxor  "#regc", "#regd"             \n\t"                    \
-    "pand    %%mm6, "#regb"             \n\t"                    \
-    "pand    %%mm6, "#regd"             \n\t"                    \
-    "psrlq      $1, "#regd"             \n\t"                    \
-    "psrlq      $1, "#regb"             \n\t"                    \
-    "psubb "#regb", "#regr"             \n\t"                    \
-    "psubb "#regd", "#regp"             \n\t"
-
-/***********************************/
-/* MMX no rounding */
-#define DEF(x, y) x ## _no_rnd_ ## y ## _mmx
-#define SET_RND  MOVQ_WONE
-#define PAVGBP(a, b, c, d, e, f)        PAVGBP_MMX_NO_RND(a, b, c, d, e, f)
-#define PAVGB(a, b, c, e)               PAVGB_MMX_NO_RND(a, b, c, e)
-#define OP_AVG(a, b, c, e)              PAVGB_MMX(a, b, c, e)
-
-#include "dsputil_rnd_template.c"
-
-#undef DEF
-#undef SET_RND
-#undef PAVGBP
-#undef PAVGB
-/***********************************/
-/* MMX rounding */
-
-#define DEF(x, y) x ## _ ## y ## _mmx
-#define SET_RND  MOVQ_WTWO
-#define PAVGBP(a, b, c, d, e, f)        PAVGBP_MMX(a, b, c, d, e, f)
-#define PAVGB(a, b, c, e)               PAVGB_MMX(a, b, c, e)
-
-#include "dsputil_rnd_template.c"
-
-#undef DEF
-#undef SET_RND
-#undef PAVGBP
-#undef PAVGB
-#undef OP_AVG
-
-/***********************************/
-/* 3Dnow specific */
-
-#define DEF(x) x ## _3dnow
-#define PAVGB "pavgusb"
-#define OP_AVG PAVGB
-#define SKIP_FOR_3DNOW
-
-#include "dsputil_avg_template.c"
-
-#undef DEF
-#undef PAVGB
-#undef OP_AVG
-#undef SKIP_FOR_3DNOW
-
-/***********************************/
-/* MMXEXT specific */
-
-#define DEF(x) x ## _mmxext
-
-/* Introduced only in MMXEXT set */
-#define PAVGB "pavgb"
-#define OP_AVG PAVGB
-
-#include "dsputil_avg_template.c"
-
-#undef DEF
-#undef PAVGB
-#undef OP_AVG
-
-#define put_no_rnd_pixels16_mmx put_pixels16_mmx
-#define put_no_rnd_pixels8_mmx put_pixels8_mmx
-#define put_pixels16_mmxext put_pixels16_mmx
-#define put_pixels8_mmxext put_pixels8_mmx
-#define put_pixels4_mmxext put_pixels4_mmx
-#define put_no_rnd_pixels16_mmxext put_no_rnd_pixels16_mmx
-#define put_no_rnd_pixels8_mmxext put_no_rnd_pixels8_mmx
-
-/***********************************/
-/* standard MMX */
-
-void ff_put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
+void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
                                int line_size)
 {
-    const DCTELEM *p;
+    const int16_t *p;
     uint8_t *pix;
 
     /* read the pixels */
@@ -307,7 +105,7 @@ void ff_put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
     "movq               %%mm3, (%0, %3, 2)  \n\t"           \
     "movq               %%mm4, (%0, %1)     \n\t"
 
-void ff_put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
+void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
                                       int line_size)
 {
     x86_reg line_skip = line_size;
@@ -324,10 +122,10 @@ void ff_put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
         : "memory");
 }
 
-void ff_add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
+void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
                                int line_size)
 {
-    const DCTELEM *p;
+    const int16_t *p;
     uint8_t *pix;
     int i;
 
@@ -366,70 +164,8 @@ void ff_add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,
     } while (--i);
 }
 
-static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
-                            int line_size, int h)
-{
-    __asm__ volatile (
-        "lea   (%3, %3), %%"REG_a"      \n\t"
-        ".p2align     3                 \n\t"
-        "1:                             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq     %%mm0, (%2)           \n\t"
-        "movq     %%mm1, (%2, %3)       \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq     %%mm0, (%2)           \n\t"
-        "movq     %%mm1, (%2, %3)       \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "subl        $4, %0             \n\t"
-        "jnz         1b                 \n\t"
-        : "+g"(h), "+r"(pixels),  "+r"(block)
-        : "r"((x86_reg)line_size)
-        : "%"REG_a, "memory"
-        );
-}
-
-static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
-                             int line_size, int h)
-{
-    __asm__ volatile (
-        "lea   (%3, %3), %%"REG_a"      \n\t"
-        ".p2align     3                 \n\t"
-        "1:                             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq 8(%1    ), %%mm4          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq 8(%1, %3), %%mm5          \n\t"
-        "movq     %%mm0,  (%2)          \n\t"
-        "movq     %%mm4, 8(%2)          \n\t"
-        "movq     %%mm1,  (%2, %3)      \n\t"
-        "movq     %%mm5, 8(%2, %3)      \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "movq  (%1    ), %%mm0          \n\t"
-        "movq 8(%1    ), %%mm4          \n\t"
-        "movq  (%1, %3), %%mm1          \n\t"
-        "movq 8(%1, %3), %%mm5          \n\t"
-        "movq     %%mm0,  (%2)          \n\t"
-        "movq     %%mm4, 8(%2)          \n\t"
-        "movq     %%mm1,  (%2, %3)      \n\t"
-        "movq     %%mm5, 8(%2, %3)      \n\t"
-        "add  %%"REG_a", %1             \n\t"
-        "add  %%"REG_a", %2             \n\t"
-        "subl        $4, %0             \n\t"
-        "jnz         1b                 \n\t"
-        : "+g"(h), "+r"(pixels),  "+r"(block)
-        : "r"((x86_reg)line_size)
-        : "%"REG_a, "memory"
-        );
-}
-
 #define CLEAR_BLOCKS(name, n)                           \
-static void name(DCTELEM *blocks)                       \
+void name(int16_t *blocks)                              \
 {                                                       \
     __asm__ volatile (                                  \
         "pxor %%mm7, %%mm7              \n\t"           \
@@ -446,10 +182,10 @@ static void name(DCTELEM *blocks)                       \
         : "%"REG_a                                      \
         );                                              \
 }
-CLEAR_BLOCKS(clear_blocks_mmx, 6)
-CLEAR_BLOCKS(clear_block_mmx, 1)
+CLEAR_BLOCKS(ff_clear_blocks_mmx, 6)
+CLEAR_BLOCKS(ff_clear_block_mmx, 1)
 
-static void clear_block_sse(DCTELEM *block)
+void ff_clear_block_sse(int16_t *block)
 {
     __asm__ volatile (
         "xorps  %%xmm0, %%xmm0          \n"
@@ -466,7 +202,7 @@ static void clear_block_sse(DCTELEM *block)
     );
 }
 
-static void clear_blocks_sse(DCTELEM *blocks)
+void ff_clear_blocks_sse(int16_t *blocks)
 {
     __asm__ volatile (
         "xorps  %%xmm0, %%xmm0              \n"
@@ -488,7 +224,7 @@ static void clear_blocks_sse(DCTELEM *blocks)
     );
 }
 
-static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w)
+void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, int w)
 {
     x86_reg i = 0;
     __asm__ volatile (
@@ -513,222 +249,10 @@ static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w)
         dst[i + 0] += src[i + 0];
 }
 
-#if HAVE_7REGS
-static void add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top,
-                                            const uint8_t *diff, int w,
-                                            int *left, int *left_top)
-{
-    x86_reg w2 = -w;
-    x86_reg x;
-    int l  = *left     & 0xff;
-    int tl = *left_top & 0xff;
-    int t;
-    __asm__ volatile (
-        "mov          %7, %3            \n"
-        "1:                             \n"
-        "movzbl (%3, %4), %2            \n"
-        "mov          %2, %k3           \n"
-        "sub         %b1, %b3           \n"
-        "add         %b0, %b3           \n"
-        "mov          %2, %1            \n"
-        "cmp          %0, %2            \n"
-        "cmovg        %0, %2            \n"
-        "cmovg        %1, %0            \n"
-        "cmp         %k3, %0            \n"
-        "cmovg       %k3, %0            \n"
-        "mov          %7, %3            \n"
-        "cmp          %2, %0            \n"
-        "cmovl        %2, %0            \n"
-        "add    (%6, %4), %b0           \n"
-        "mov         %b0, (%5, %4)      \n"
-        "inc          %4                \n"
-        "jl           1b                \n"
-        : "+&q"(l), "+&q"(tl), "=&r"(t), "=&q"(x), "+&r"(w2)
-        : "r"(dst + w), "r"(diff + w), "rm"(top + w)
-    );
-    *left     = l;
-    *left_top = tl;
-}
-#endif
-
-static inline void transpose4x4(uint8_t *dst, uint8_t *src, x86_reg dst_stride, x86_reg src_stride){
-    __asm__ volatile( //FIXME could save 1 instruction if done as 8x4 ...
-        "movd  (%1), %%mm0              \n\t"
-        "add   %3, %1                   \n\t"
-        "movd  (%1), %%mm1              \n\t"
-        "movd  (%1,%3,1), %%mm2         \n\t"
-        "movd  (%1,%3,2), %%mm3         \n\t"
-        "punpcklbw %%mm1, %%mm0         \n\t"
-        "punpcklbw %%mm3, %%mm2         \n\t"
-        "movq %%mm0, %%mm1              \n\t"
-        "punpcklwd %%mm2, %%mm0         \n\t"
-        "punpckhwd %%mm2, %%mm1         \n\t"
-        "movd  %%mm0, (%0)              \n\t"
-        "add   %2, %0                   \n\t"
-        "punpckhdq %%mm0, %%mm0         \n\t"
-        "movd  %%mm0, (%0)              \n\t"
-        "movd  %%mm1, (%0,%2,1)         \n\t"
-        "punpckhdq %%mm1, %%mm1         \n\t"
-        "movd  %%mm1, (%0,%2,2)         \n\t"
-
-        :  "+&r" (dst),
-           "+&r" (src)
-        :  "r" (dst_stride),
-           "r" (src_stride)
-        :  "memory"
-    );
-}
-
-#define H263_LOOP_FILTER                        \
-    "pxor      %%mm7, %%mm7             \n\t"   \
-    "movq         %0, %%mm0             \n\t"   \
-    "movq         %0, %%mm1             \n\t"   \
-    "movq         %3, %%mm2             \n\t"   \
-    "movq         %3, %%mm3             \n\t"   \
-    "punpcklbw %%mm7, %%mm0             \n\t"   \
-    "punpckhbw %%mm7, %%mm1             \n\t"   \
-    "punpcklbw %%mm7, %%mm2             \n\t"   \
-    "punpckhbw %%mm7, %%mm3             \n\t"   \
-    "psubw     %%mm2, %%mm0             \n\t"   \
-    "psubw     %%mm3, %%mm1             \n\t"   \
-    "movq         %1, %%mm2             \n\t"   \
-    "movq         %1, %%mm3             \n\t"   \
-    "movq         %2, %%mm4             \n\t"   \
-    "movq         %2, %%mm5             \n\t"   \
-    "punpcklbw %%mm7, %%mm2             \n\t"   \
-    "punpckhbw %%mm7, %%mm3             \n\t"   \
-    "punpcklbw %%mm7, %%mm4             \n\t"   \
-    "punpckhbw %%mm7, %%mm5             \n\t"   \
-    "psubw     %%mm2, %%mm4             \n\t"   \
-    "psubw     %%mm3, %%mm5             \n\t"   \
-    "psllw        $2, %%mm4             \n\t"   \
-    "psllw        $2, %%mm5             \n\t"   \
-    "paddw     %%mm0, %%mm4             \n\t"   \
-    "paddw     %%mm1, %%mm5             \n\t"   \
-    "pxor      %%mm6, %%mm6             \n\t"   \
-    "pcmpgtw   %%mm4, %%mm6             \n\t"   \
-    "pcmpgtw   %%mm5, %%mm7             \n\t"   \
-    "pxor      %%mm6, %%mm4             \n\t"   \
-    "pxor      %%mm7, %%mm5             \n\t"   \
-    "psubw     %%mm6, %%mm4             \n\t"   \
-    "psubw     %%mm7, %%mm5             \n\t"   \
-    "psrlw        $3, %%mm4             \n\t"   \
-    "psrlw        $3, %%mm5             \n\t"   \
-    "packuswb  %%mm5, %%mm4             \n\t"   \
-    "packsswb  %%mm7, %%mm6             \n\t"   \
-    "pxor      %%mm7, %%mm7             \n\t"   \
-    "movd         %4, %%mm2             \n\t"   \
-    "punpcklbw %%mm2, %%mm2             \n\t"   \
-    "punpcklbw %%mm2, %%mm2             \n\t"   \
-    "punpcklbw %%mm2, %%mm2             \n\t"   \
-    "psubusb   %%mm4, %%mm2             \n\t"   \
-    "movq      %%mm2, %%mm3             \n\t"   \
-    "psubusb   %%mm4, %%mm3             \n\t"   \
-    "psubb     %%mm3, %%mm2             \n\t"   \
-    "movq         %1, %%mm3             \n\t"   \
-    "movq         %2, %%mm4             \n\t"   \
-    "pxor      %%mm6, %%mm3             \n\t"   \
-    "pxor      %%mm6, %%mm4             \n\t"   \
-    "paddusb   %%mm2, %%mm3             \n\t"   \
-    "psubusb   %%mm2, %%mm4             \n\t"   \
-    "pxor      %%mm6, %%mm3             \n\t"   \
-    "pxor      %%mm6, %%mm4             \n\t"   \
-    "paddusb   %%mm2, %%mm2             \n\t"   \
-    "packsswb  %%mm1, %%mm0             \n\t"   \
-    "pcmpgtb   %%mm0, %%mm7             \n\t"   \
-    "pxor      %%mm7, %%mm0             \n\t"   \
-    "psubb     %%mm7, %%mm0             \n\t"   \
-    "movq      %%mm0, %%mm1             \n\t"   \
-    "psubusb   %%mm2, %%mm0             \n\t"   \
-    "psubb     %%mm0, %%mm1             \n\t"   \
-    "pand         %5, %%mm1             \n\t"   \
-    "psrlw        $2, %%mm1             \n\t"   \
-    "pxor      %%mm7, %%mm1             \n\t"   \
-    "psubb     %%mm7, %%mm1             \n\t"   \
-    "movq         %0, %%mm5             \n\t"   \
-    "movq         %3, %%mm6             \n\t"   \
-    "psubb     %%mm1, %%mm5             \n\t"   \
-    "paddb     %%mm1, %%mm6             \n\t"
-
-static void h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale)
-{
-    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-        const int strength = ff_h263_loop_filter_strength[qscale];
-
-        __asm__ volatile (
-            H263_LOOP_FILTER
-
-            "movq %%mm3, %1             \n\t"
-            "movq %%mm4, %2             \n\t"
-            "movq %%mm5, %0             \n\t"
-            "movq %%mm6, %3             \n\t"
-            : "+m"(*(uint64_t*)(src - 2 * stride)),
-              "+m"(*(uint64_t*)(src - 1 * stride)),
-              "+m"(*(uint64_t*)(src + 0 * stride)),
-              "+m"(*(uint64_t*)(src + 1 * stride))
-            : "g"(2 * strength), "m"(ff_pb_FC)
-            );
-    }
-}
-
-static void h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale)
-{
-    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-        const int strength = ff_h263_loop_filter_strength[qscale];
-        DECLARE_ALIGNED(8, uint64_t, temp)[4];
-        uint8_t *btemp = (uint8_t*)temp;
-
-        src -= 2;
-
-        transpose4x4(btemp,     src,              8, stride);
-        transpose4x4(btemp + 4, src + 4 * stride, 8, stride);
-        __asm__ volatile (
-            H263_LOOP_FILTER // 5 3 4 6
-
-            : "+m"(temp[0]),
-              "+m"(temp[1]),
-              "+m"(temp[2]),
-              "+m"(temp[3])
-            : "g"(2 * strength), "m"(ff_pb_FC)
-            );
-
-        __asm__ volatile (
-            "movq      %%mm5, %%mm1         \n\t"
-            "movq      %%mm4, %%mm0         \n\t"
-            "punpcklbw %%mm3, %%mm5         \n\t"
-            "punpcklbw %%mm6, %%mm4         \n\t"
-            "punpckhbw %%mm3, %%mm1         \n\t"
-            "punpckhbw %%mm6, %%mm0         \n\t"
-            "movq      %%mm5, %%mm3         \n\t"
-            "movq      %%mm1, %%mm6         \n\t"
-            "punpcklwd %%mm4, %%mm5         \n\t"
-            "punpcklwd %%mm0, %%mm1         \n\t"
-            "punpckhwd %%mm4, %%mm3         \n\t"
-            "punpckhwd %%mm0, %%mm6         \n\t"
-            "movd      %%mm5, (%0)          \n\t"
-            "punpckhdq %%mm5, %%mm5         \n\t"
-            "movd      %%mm5, (%0, %2)      \n\t"
-            "movd      %%mm3, (%0, %2, 2)   \n\t"
-            "punpckhdq %%mm3, %%mm3         \n\t"
-            "movd      %%mm3, (%0, %3)      \n\t"
-            "movd      %%mm1, (%1)          \n\t"
-            "punpckhdq %%mm1, %%mm1         \n\t"
-            "movd      %%mm1, (%1, %2)      \n\t"
-            "movd      %%mm6, (%1, %2, 2)   \n\t"
-            "punpckhdq %%mm6, %%mm6         \n\t"
-            "movd      %%mm6, (%1, %3)      \n\t"
-            :: "r"(src),
-               "r"(src + 4 * stride),
-               "r"((x86_reg)stride),
-               "r"((x86_reg)(3 * stride))
-            );
-    }
-}
-
 /* Draw the edges of width 'w' of an image of size width, height
  * this MMX version can only handle w == 8 || w == 16. */
-static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
-                           int w, int h, int sides)
+void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
+                       int w, int h, int sides)
 {
     uint8_t *ptr, *last_line;
     int i;
@@ -821,824 +345,10 @@ static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
     }
 }
 
-#define QPEL_V_LOW(m3, m4, m5, m6, pw_20, pw_3, rnd,                      \
-                   in0, in1, in2, in7, out, OP)                           \
-    "paddw               "#m4", "#m3"   \n\t" /* x1 */                    \
-    "movq   "MANGLE(ff_pw_20)", %%mm4   \n\t" /* 20 */                    \
-    "pmullw              "#m3", %%mm4   \n\t" /* 20x1 */                  \
-    "movq               "#in7", "#m3"   \n\t" /* d */                     \
-    "movq               "#in0", %%mm5   \n\t" /* D */                     \
-    "paddw               "#m3", %%mm5   \n\t" /* x4 */                    \
-    "psubw               %%mm5, %%mm4   \n\t" /* 20x1 - x4 */             \
-    "movq               "#in1", %%mm5   \n\t" /* C */                     \
-    "movq               "#in2", %%mm6   \n\t" /* B */                     \
-    "paddw               "#m6", %%mm5   \n\t" /* x3 */                    \
-    "paddw               "#m5", %%mm6   \n\t" /* x2 */                    \
-    "paddw               %%mm6, %%mm6   \n\t" /* 2x2 */                   \
-    "psubw               %%mm6, %%mm5   \n\t" /* -2x2 + x3 */             \
-    "pmullw  "MANGLE(ff_pw_3)", %%mm5   \n\t" /* -6x2 + 3x3 */            \
-    "paddw              "#rnd", %%mm4   \n\t" /* x2 */                    \
-    "paddw               %%mm4, %%mm5   \n\t" /* 20x1 - 6x2 + 3x3 - x4 */ \
-    "psraw                  $5, %%mm5   \n\t"                             \
-    "packuswb            %%mm5, %%mm5   \n\t"                             \
-    OP(%%mm5, out, %%mm7, d)
-
-#define QPEL_BASE(OPNAME, ROUNDER, RND, OP_MMXEXT)                        \
-static void OPNAME ## mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst,         \
-                                                    uint8_t *src,         \
-                                                    int dstStride,        \
-                                                    int srcStride,        \
-                                                    int h)                \
-{                                                                         \
-    uint64_t temp;                                                        \
-                                                                          \
-    __asm__ volatile (                                                    \
-        "pxor      %%mm7, %%mm7             \n\t"                         \
-        "1:                                 \n\t"                         \
-        "movq       (%0), %%mm0             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm0, %%mm1             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm0, %%mm2             \n\t" /* ABCDEFGH */          \
-        "punpcklbw %%mm7, %%mm0             \n\t" /* 0A0B0C0D */          \
-        "punpckhbw %%mm7, %%mm1             \n\t" /* 0E0F0G0H */          \
-        "pshufw    $0x90, %%mm0, %%mm5      \n\t" /* 0A0A0B0C */          \
-        "pshufw    $0x41, %%mm0, %%mm6      \n\t" /* 0B0A0A0B */          \
-        "movq      %%mm2, %%mm3             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm2, %%mm4             \n\t" /* ABCDEFGH */          \
-        "psllq        $8, %%mm2             \n\t" /* 0ABCDEFG */          \
-        "psllq       $16, %%mm3             \n\t" /* 00ABCDEF */          \
-        "psllq       $24, %%mm4             \n\t" /* 000ABCDE */          \
-        "punpckhbw %%mm7, %%mm2             \n\t" /* 0D0E0F0G */          \
-        "punpckhbw %%mm7, %%mm3             \n\t" /* 0C0D0E0F */          \
-        "punpckhbw %%mm7, %%mm4             \n\t" /* 0B0C0D0E */          \
-        "paddw     %%mm3, %%mm5             \n\t" /* b */                 \
-        "paddw     %%mm2, %%mm6             \n\t" /* c */                 \
-        "paddw     %%mm5, %%mm5             \n\t" /* 2b */                \
-        "psubw     %%mm5, %%mm6             \n\t" /* c - 2b */            \
-        "pshufw    $0x06, %%mm0, %%mm5      \n\t" /* 0C0B0A0A */          \
-        "pmullw "MANGLE(ff_pw_3)", %%mm6    \n\t" /* 3c - 6b */           \
-        "paddw     %%mm4, %%mm0             \n\t" /* a */                 \
-        "paddw     %%mm1, %%mm5             \n\t" /* d */                 \
-        "pmullw "MANGLE(ff_pw_20)", %%mm0   \n\t" /* 20a */               \
-        "psubw     %%mm5, %%mm0             \n\t" /* 20a - d */           \
-        "paddw        %6, %%mm6             \n\t"                         \
-        "paddw     %%mm6, %%mm0             \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw        $5, %%mm0             \n\t"                         \
-        "movq      %%mm0, %5                \n\t"                         \
-        /* mm1 = EFGH, mm2 = DEFG, mm3 = CDEF, mm4 = BCDE, mm7 = 0 */     \
-                                                                          \
-        "movq      5(%0), %%mm0             \n\t" /* FGHIJKLM */          \
-        "movq      %%mm0, %%mm5             \n\t" /* FGHIJKLM */          \
-        "movq      %%mm0, %%mm6             \n\t" /* FGHIJKLM */          \
-        "psrlq        $8, %%mm0             \n\t" /* GHIJKLM0 */          \
-        "psrlq       $16, %%mm5             \n\t" /* HIJKLM00 */          \
-        "punpcklbw %%mm7, %%mm0             \n\t" /* 0G0H0I0J */          \
-        "punpcklbw %%mm7, %%mm5             \n\t" /* 0H0I0J0K */          \
-        "paddw     %%mm0, %%mm2             \n\t" /* b */                 \
-        "paddw     %%mm5, %%mm3             \n\t" /* c */                 \
-        "paddw     %%mm2, %%mm2             \n\t" /* 2b */                \
-        "psubw     %%mm2, %%mm3             \n\t" /* c - 2b */            \
-        "movq      %%mm6, %%mm2             \n\t" /* FGHIJKLM */          \
-        "psrlq       $24, %%mm6             \n\t" /* IJKLM000 */          \
-        "punpcklbw %%mm7, %%mm2             \n\t" /* 0F0G0H0I */          \
-        "punpcklbw %%mm7, %%mm6             \n\t" /* 0I0J0K0L */          \
-        "pmullw "MANGLE(ff_pw_3)", %%mm3    \n\t" /* 3c - 6b */           \
-        "paddw     %%mm2, %%mm1             \n\t" /* a */                 \
-        "paddw     %%mm6, %%mm4             \n\t" /* d */                 \
-        "pmullw "MANGLE(ff_pw_20)", %%mm1   \n\t" /* 20a */               \
-        "psubw     %%mm4, %%mm3             \n\t" /* - 6b +3c - d */      \
-        "paddw        %6, %%mm1             \n\t"                         \
-        "paddw     %%mm1, %%mm3             \n\t" /* 20a - 6b +3c - d */  \
-        "psraw        $5, %%mm3             \n\t"                         \
-        "movq         %5, %%mm1             \n\t"                         \
-        "packuswb  %%mm3, %%mm1             \n\t"                         \
-        OP_MMXEXT(%%mm1, (%1), %%mm4, q)                                  \
-        /* mm0 = GHIJ, mm2 = FGHI, mm5 = HIJK, mm6 = IJKL, mm7 = 0 */     \
-                                                                          \
-        "movq      9(%0), %%mm1             \n\t" /* JKLMNOPQ */          \
-        "movq      %%mm1, %%mm4             \n\t" /* JKLMNOPQ */          \
-        "movq      %%mm1, %%mm3             \n\t" /* JKLMNOPQ */          \
-        "psrlq        $8, %%mm1             \n\t" /* KLMNOPQ0 */          \
-        "psrlq       $16, %%mm4             \n\t" /* LMNOPQ00 */          \
-        "punpcklbw %%mm7, %%mm1             \n\t" /* 0K0L0M0N */          \
-        "punpcklbw %%mm7, %%mm4             \n\t" /* 0L0M0N0O */          \
-        "paddw     %%mm1, %%mm5             \n\t" /* b */                 \
-        "paddw     %%mm4, %%mm0             \n\t" /* c */                 \
-        "paddw     %%mm5, %%mm5             \n\t" /* 2b */                \
-        "psubw     %%mm5, %%mm0             \n\t" /* c - 2b */            \
-        "movq      %%mm3, %%mm5             \n\t" /* JKLMNOPQ */          \
-        "psrlq       $24, %%mm3             \n\t" /* MNOPQ000 */          \
-        "pmullw "MANGLE(ff_pw_3)", %%mm0    \n\t" /* 3c - 6b */           \
-        "punpcklbw %%mm7, %%mm3             \n\t" /* 0M0N0O0P */          \
-        "paddw     %%mm3, %%mm2             \n\t" /* d */                 \
-        "psubw     %%mm2, %%mm0             \n\t" /* -6b + 3c - d */      \
-        "movq      %%mm5, %%mm2             \n\t" /* JKLMNOPQ */          \
-        "punpcklbw %%mm7, %%mm2             \n\t" /* 0J0K0L0M */          \
-        "punpckhbw %%mm7, %%mm5             \n\t" /* 0N0O0P0Q */          \
-        "paddw     %%mm2, %%mm6             \n\t" /* a */                 \
-        "pmullw "MANGLE(ff_pw_20)", %%mm6   \n\t" /* 20a */               \
-        "paddw        %6, %%mm0             \n\t"                         \
-        "paddw     %%mm6, %%mm0             \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw        $5, %%mm0             \n\t"                         \
-        /* mm1 = KLMN, mm2 = JKLM, mm3 = MNOP, */                         \
-        /* mm4 = LMNO, mm5 = NOPQ mm7 = 0 */                              \
-                                                                          \
-        "paddw    %%mm5, %%mm3              \n\t" /* a */                 \
-        "pshufw   $0xF9, %%mm5, %%mm6       \n\t" /* 0O0P0Q0Q */          \
-        "paddw    %%mm4, %%mm6              \n\t" /* b */                 \
-        "pshufw   $0xBE, %%mm5, %%mm4       \n\t" /* 0P0Q0Q0P */          \
-        "pshufw   $0x6F, %%mm5, %%mm5       \n\t" /* 0Q0Q0P0O */          \
-        "paddw    %%mm1, %%mm4              \n\t" /* c */                 \
-        "paddw    %%mm2, %%mm5              \n\t" /* d */                 \
-        "paddw    %%mm6, %%mm6              \n\t" /* 2b */                \
-        "psubw    %%mm6, %%mm4              \n\t" /* c - 2b */            \
-        "pmullw "MANGLE(ff_pw_20)", %%mm3   \n\t" /* 20a */               \
-        "pmullw  "MANGLE(ff_pw_3)", %%mm4   \n\t" /* 3c - 6b */           \
-        "psubw    %%mm5, %%mm3              \n\t" /* -6b + 3c - d */      \
-        "paddw       %6, %%mm4              \n\t"                         \
-        "paddw    %%mm3, %%mm4              \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw       $5, %%mm4              \n\t"                         \
-        "packuswb %%mm4, %%mm0              \n\t"                         \
-        OP_MMXEXT(%%mm0, 8(%1), %%mm4, q)                                 \
-                                                                          \
-        "add         %3, %0                 \n\t"                         \
-        "add         %4, %1                 \n\t"                         \
-        "decl        %2                     \n\t"                         \
-        "jnz         1b                     \n\t"                         \
-        : "+a"(src), "+c"(dst), "+D"(h)                                   \
-        : "d"((x86_reg)srcStride), "S"((x86_reg)dstStride),               \
-          /* "m"(ff_pw_20), "m"(ff_pw_3), */ "m"(temp), "m"(ROUNDER)      \
-        : "memory"                                                        \
-        );                                                                \
-}                                                                         \
-                                                                          \
-static void OPNAME ## mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst,          \
-                                                   uint8_t *src,          \
-                                                   int dstStride,         \
-                                                   int srcStride,         \
-                                                   int h)                 \
-{                                                                         \
-    __asm__ volatile (                                                    \
-        "pxor      %%mm7, %%mm7             \n\t"                         \
-        "1:                                 \n\t"                         \
-        "movq       (%0), %%mm0             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm0, %%mm1             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm0, %%mm2             \n\t" /* ABCDEFGH */          \
-        "punpcklbw %%mm7, %%mm0             \n\t" /* 0A0B0C0D */          \
-        "punpckhbw %%mm7, %%mm1             \n\t" /* 0E0F0G0H */          \
-        "pshufw    $0x90, %%mm0, %%mm5      \n\t" /* 0A0A0B0C */          \
-        "pshufw    $0x41, %%mm0, %%mm6      \n\t" /* 0B0A0A0B */          \
-        "movq      %%mm2, %%mm3             \n\t" /* ABCDEFGH */          \
-        "movq      %%mm2, %%mm4             \n\t" /* ABCDEFGH */          \
-        "psllq        $8, %%mm2             \n\t" /* 0ABCDEFG */          \
-        "psllq       $16, %%mm3             \n\t" /* 00ABCDEF */          \
-        "psllq       $24, %%mm4             \n\t" /* 000ABCDE */          \
-        "punpckhbw %%mm7, %%mm2             \n\t" /* 0D0E0F0G */          \
-        "punpckhbw %%mm7, %%mm3             \n\t" /* 0C0D0E0F */          \
-        "punpckhbw %%mm7, %%mm4             \n\t" /* 0B0C0D0E */          \
-        "paddw     %%mm3, %%mm5             \n\t" /* b */                 \
-        "paddw     %%mm2, %%mm6             \n\t" /* c */                 \
-        "paddw     %%mm5, %%mm5             \n\t" /* 2b */                \
-        "psubw     %%mm5, %%mm6             \n\t" /* c - 2b */            \
-        "pshufw    $0x06, %%mm0, %%mm5      \n\t" /* 0C0B0A0A */          \
-        "pmullw "MANGLE(ff_pw_3)", %%mm6    \n\t" /* 3c - 6b */           \
-        "paddw     %%mm4, %%mm0             \n\t" /* a */                 \
-        "paddw     %%mm1, %%mm5             \n\t" /* d */                 \
-        "pmullw "MANGLE(ff_pw_20)", %%mm0   \n\t" /* 20a */               \
-        "psubw     %%mm5, %%mm0             \n\t" /* 20a - d */           \
-        "paddw        %5, %%mm6             \n\t"                         \
-        "paddw     %%mm6, %%mm0             \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw        $5, %%mm0             \n\t"                         \
-        /* mm1 = EFGH, mm2 = DEFG, mm3 = CDEF, mm4 = BCDE, mm7 = 0 */     \
-                                                                          \
-        "movd      5(%0), %%mm5             \n\t" /* FGHI */              \
-        "punpcklbw %%mm7, %%mm5             \n\t" /* 0F0G0H0I */          \
-        "pshufw    $0xF9, %%mm5, %%mm6      \n\t" /* 0G0H0I0I */          \
-        "paddw     %%mm5, %%mm1             \n\t" /* a */                 \
-        "paddw     %%mm6, %%mm2             \n\t" /* b */                 \
-        "pshufw    $0xBE, %%mm5, %%mm6      \n\t" /* 0H0I0I0H */          \
-        "pshufw    $0x6F, %%mm5, %%mm5      \n\t" /* 0I0I0H0G */          \
-        "paddw     %%mm6, %%mm3             \n\t" /* c */                 \
-        "paddw     %%mm5, %%mm4             \n\t" /* d */                 \
-        "paddw     %%mm2, %%mm2             \n\t" /* 2b */                \
-        "psubw     %%mm2, %%mm3             \n\t" /* c - 2b */            \
-        "pmullw "MANGLE(ff_pw_20)", %%mm1   \n\t" /* 20a */               \
-        "pmullw  "MANGLE(ff_pw_3)", %%mm3   \n\t" /* 3c - 6b */           \
-        "psubw     %%mm4, %%mm3             \n\t" /* -6b + 3c - d */      \
-        "paddw        %5, %%mm1             \n\t"                         \
-        "paddw     %%mm1, %%mm3             \n\t" /* 20a - 6b + 3c - d */ \
-        "psraw        $5, %%mm3             \n\t"                         \
-        "packuswb  %%mm3, %%mm0             \n\t"                         \
-        OP_MMXEXT(%%mm0, (%1), %%mm4, q)                                  \
-                                                                          \
-        "add          %3, %0                \n\t"                         \
-        "add          %4, %1                \n\t"                         \
-        "decl         %2                    \n\t"                         \
-        "jnz          1b                    \n\t"                         \
-        : "+a"(src), "+c"(dst), "+d"(h)                                   \
-        : "S"((x86_reg)srcStride), "D"((x86_reg)dstStride),               \
-          /* "m"(ff_pw_20), "m"(ff_pw_3), */ "m"(ROUNDER)                 \
-        : "memory"                                                        \
-        );                                                                \
-}
-
-#define QPEL_OP(OPNAME, ROUNDER, RND, OP, MMX)                          \
-static void OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(uint8_t *dst,      \
-                                                     uint8_t *src,      \
-                                                     int dstStride,     \
-                                                     int srcStride)     \
-{                                                                       \
-    uint64_t temp[17 * 4];                                              \
-    uint64_t *temp_ptr = temp;                                          \
-    int count = 17;                                                     \
-                                                                        \
-    /* FIXME unroll */                                                  \
-    __asm__ volatile (                                                  \
-        "pxor      %%mm7, %%mm7             \n\t"                       \
-        "1:                                 \n\t"                       \
-        "movq       (%0), %%mm0             \n\t"                       \
-        "movq       (%0), %%mm1             \n\t"                       \
-        "movq      8(%0), %%mm2             \n\t"                       \
-        "movq      8(%0), %%mm3             \n\t"                       \
-        "punpcklbw %%mm7, %%mm0             \n\t"                       \
-        "punpckhbw %%mm7, %%mm1             \n\t"                       \
-        "punpcklbw %%mm7, %%mm2             \n\t"                       \
-        "punpckhbw %%mm7, %%mm3             \n\t"                       \
-        "movq      %%mm0, (%1)              \n\t"                       \
-        "movq      %%mm1, 17 * 8(%1)        \n\t"                       \
-        "movq      %%mm2, 2 * 17 * 8(%1)    \n\t"                       \
-        "movq      %%mm3, 3 * 17 * 8(%1)    \n\t"                       \
-        "add          $8, %1                \n\t"                       \
-        "add          %3, %0                \n\t"                       \
-        "decl         %2                    \n\t"                       \
-        "jnz          1b                    \n\t"                       \
-        : "+r"(src), "+r"(temp_ptr), "+r"(count)                        \
-        : "r"((x86_reg)srcStride)                                       \
-        : "memory"                                                      \
-        );                                                              \
-                                                                        \
-    temp_ptr = temp;                                                    \
-    count    = 4;                                                       \
-                                                                        \
-    /* FIXME reorder for speed */                                       \
-    __asm__ volatile (                                                  \
-        /* "pxor  %%mm7, %%mm7            \n\t" */                      \
-        "1:                             \n\t"                           \
-        "movq    (%0), %%mm0            \n\t"                           \
-        "movq   8(%0), %%mm1            \n\t"                           \
-        "movq  16(%0), %%mm2            \n\t"                           \
-        "movq  24(%0), %%mm3            \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5, 16(%0),   8(%0),    (%0),  32(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5,  8(%0),    (%0),    (%0),  40(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5,   (%0),    (%0),   8(%0),  48(%0), (%1),     OP) \
-                                                                        \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5,   (%0),   8(%0),  16(%0),  56(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5,  8(%0),  16(%0),  24(%0),  64(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5, 16(%0),  24(%0),  32(%0),  72(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5, 24(%0),  32(%0),  40(%0),  80(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5, 32(%0),  40(%0),  48(%0),  88(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5, 40(%0),  48(%0),  56(%0),  96(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5, 48(%0),  56(%0),  64(%0), 104(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5, 56(%0),  64(%0),  72(%0), 112(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5, 64(%0),  72(%0),  80(%0), 120(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5, 72(%0),  80(%0),  88(%0), 128(%0), (%1),     OP) \
-                                                                        \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5, 80(%0),  88(%0),  96(%0), 128(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5, 88(%0),  96(%0), 104(%0), 120(%0), (%1),     OP) \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5, 96(%0), 104(%0), 112(%0), 112(%0), (%1, %3), OP) \
-                                                                        \
-        "add     $136, %0               \n\t"                           \
-        "add       %6, %1               \n\t"                           \
-        "decl      %2                   \n\t"                           \
-        "jnz       1b                   \n\t"                           \
-                                                                        \
-        : "+r"(temp_ptr), "+r"(dst), "+g"(count)                        \
-        : "r"((x86_reg)dstStride), "r"(2 * (x86_reg)dstStride),         \
-          /* "m"(ff_pw_20), "m"(ff_pw_3), */ "m"(ROUNDER),              \
-          "g"(4 - 14 * (x86_reg)dstStride)                              \
-        : "memory"                                                      \
-        );                                                              \
-}                                                                       \
-                                                                        \
-static void OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(uint8_t *dst,       \
-                                                    uint8_t *src,       \
-                                                    int dstStride,      \
-                                                    int srcStride)      \
-{                                                                       \
-    uint64_t temp[9 * 2];                                               \
-    uint64_t *temp_ptr = temp;                                          \
-    int count = 9;                                                      \
-                                                                        \
-    /* FIXME unroll */                                                  \
-    __asm__ volatile (                                                  \
-        "pxor      %%mm7, %%mm7         \n\t"                           \
-        "1:                             \n\t"                           \
-        "movq       (%0), %%mm0         \n\t"                           \
-        "movq       (%0), %%mm1         \n\t"                           \
-        "punpcklbw %%mm7, %%mm0         \n\t"                           \
-        "punpckhbw %%mm7, %%mm1         \n\t"                           \
-        "movq      %%mm0, (%1)          \n\t"                           \
-        "movq      %%mm1, 9*8(%1)       \n\t"                           \
-        "add          $8, %1            \n\t"                           \
-        "add          %3, %0            \n\t"                           \
-        "decl         %2                \n\t"                           \
-        "jnz          1b                \n\t"                           \
-        : "+r"(src), "+r"(temp_ptr), "+r"(count)                        \
-        : "r"((x86_reg)srcStride)                                       \
-        : "memory"                                                      \
-        );                                                              \
-                                                                        \
-    temp_ptr = temp;                                                    \
-    count    = 2;                                                       \
-                                                                        \
-    /* FIXME reorder for speed */                                       \
-    __asm__ volatile (                                                  \
-        /* "pxor  %%mm7, %%mm7            \n\t" */                      \
-        "1:                             \n\t"                           \
-        "movq    (%0), %%mm0            \n\t"                           \
-        "movq   8(%0), %%mm1            \n\t"                           \
-        "movq  16(%0), %%mm2            \n\t"                           \
-        "movq  24(%0), %%mm3            \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5, 16(%0),  8(%0),   (%0), 32(%0), (%1), OP)     \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5,  8(%0),   (%0),   (%0), 40(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5,   (%0),   (%0),  8(%0), 48(%0), (%1), OP)     \
-                                                                        \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5,   (%0),  8(%0), 16(%0), 56(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm0, %%mm1, %%mm2, %%mm3, %5, %6, %5,  8(%0), 16(%0), 24(%0), 64(%0), (%1), OP)     \
-                                                                        \
-        QPEL_V_LOW(%%mm1, %%mm2, %%mm3, %%mm0, %5, %6, %5, 16(%0), 24(%0), 32(%0), 64(%0), (%1, %3), OP) \
-        "add       %4, %1               \n\t"                           \
-        QPEL_V_LOW(%%mm2, %%mm3, %%mm0, %%mm1, %5, %6, %5, 24(%0), 32(%0), 40(%0), 56(%0), (%1), OP)     \
-        QPEL_V_LOW(%%mm3, %%mm0, %%mm1, %%mm2, %5, %6, %5, 32(%0), 40(%0), 48(%0), 48(%0), (%1, %3), OP) \
-                                                                        \
-        "add      $72, %0               \n\t"                           \
-        "add       %6, %1               \n\t"                           \
-        "decl      %2                   \n\t"                           \
-        "jnz       1b                   \n\t"                           \
-                                                                        \
-        : "+r"(temp_ptr), "+r"(dst), "+g"(count)                        \
-        : "r"((x86_reg)dstStride), "r"(2 * (x86_reg)dstStride),         \
-          /* "m"(ff_pw_20), "m"(ff_pw_3), */ "m"(ROUNDER),              \
-          "g"(4 - 6 * (x86_reg)dstStride)                               \
-        : "memory"                                                      \
-        );                                                              \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    OPNAME ## pixels8_ ## MMX(dst, src, stride, 8);                     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t temp[8];                                                   \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,           \
-                                                stride, 8);             \
-    OPNAME ## pixels8_l2_ ## MMX(dst, src, half, stride, stride, 8);    \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride,           \
-                                            stride, 8);                 \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t temp[8];                                                   \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,           \
-                                                stride, 8);             \
-    OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride,            \
-                                 stride, 8);                            \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t temp[8];                                                   \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, 8, stride);  \
-    OPNAME ## pixels8_l2_ ## MMX(dst, src, half, stride, stride, 8);    \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src, stride, stride);  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t temp[8];                                                   \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, 8, stride);  \
-    OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,       \
-                                 stride, 8);                            \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, stride, 9);  \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, stride, 8, 8);     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,          \
-                                     stride, 9);                        \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, stride, 8, 8);     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, stride, 9);  \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, stride, 8, 8); \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,          \
-                                     stride, 9);                        \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, stride, 8, 8); \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, stride, 8, 8);     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);   \
-    OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, stride, 8, 8); \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, stride, 9);  \
-    OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, stride, 8);     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[8 + 9];                                               \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,          \
-                                     stride, 9);                        \
-    OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, stride, 8);     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, uint8_t *src,    \
-                                         int stride)                    \
-{                                                                       \
-    uint64_t half[9];                                                   \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,          \
-                                                stride, 9);             \
-    OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, stride, 8);     \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc00_ ## MMX (uint8_t *dst, uint8_t *src,  \
-                                           int stride)                  \
-{                                                                       \
-    OPNAME ## pixels16_ ## MMX(dst, src, stride, 16);                   \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t temp[32];                                                  \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,         \
-                                                 stride, 16);           \
-    OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, stride, 16);  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src,                  \
-                                             stride, stride, 16);       \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t temp[32];                                                  \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,         \
-                                                 stride, 16);           \
-    OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half,                   \
-                                  stride, stride, 16);                  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t temp[32];                                                  \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,         \
-                                                 stride);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, stride, 16);  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src, stride, stride); \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t temp[32];                                                  \
-    uint8_t * const half = (uint8_t*)temp;                              \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,         \
-                                                 stride);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half,                \
-                                  stride, stride, 16);                  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,            \
-                                      stride, 17);                      \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, stride, 16, 16);  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,        \
-                                      stride, 17);                      \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, stride, 16, 16);  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,            \
-                                      stride, 17);                      \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, stride,      \
-                                  16, 16);                              \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,        \
-                                      stride, 17);                      \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, stride,      \
-                                  16, 16);                              \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, stride, 16, 16);  \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[16 * 2 + 17 * 2];                                     \
-    uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
-    uint8_t * const halfHV = ((uint8_t*)half);                          \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,         \
-                                                 16, 16);               \
-    OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, stride,      \
-                                  16, 16);                              \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[17 * 2];                                              \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,            \
-                                      stride, 17);                      \
-    OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, stride, 16);   \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[17 * 2];                                              \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,        \
-                                      stride, 17);                      \
-    OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, stride, 16);   \
-}                                                                       \
-                                                                        \
-static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, uint8_t *src,   \
-                                          int stride)                   \
-{                                                                       \
-    uint64_t half[17 * 2];                                              \
-    uint8_t * const halfH = ((uint8_t*)half);                           \
-    put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,        \
-                                                 stride, 17);           \
-    OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, stride, 16);   \
-}
-
-#define PUT_OP(a, b, temp, size)                \
-    "mov"#size"        "#a", "#b"       \n\t"
-
-#define AVG_MMXEXT_OP(a, b, temp, size)         \
-    "mov"#size"        "#b", "#temp"    \n\t"   \
-    "pavgb          "#temp", "#a"       \n\t"   \
-    "mov"#size"        "#a", "#b"       \n\t"
-
-QPEL_BASE(put_,        ff_pw_16, _,        PUT_OP)
-QPEL_BASE(avg_,        ff_pw_16, _,        AVG_MMXEXT_OP)
-QPEL_BASE(put_no_rnd_, ff_pw_15, _no_rnd_, PUT_OP)
-QPEL_OP(put_,          ff_pw_16, _,        PUT_OP,        mmxext)
-QPEL_OP(avg_,          ff_pw_16, _,        AVG_MMXEXT_OP, mmxext)
-QPEL_OP(put_no_rnd_,   ff_pw_15, _no_rnd_, PUT_OP,        mmxext)
-
-/***********************************/
-/* bilinear qpel: not compliant to any spec, only for -lavdopts fast */
-
-#define QPEL_2TAP_XY(OPNAME, SIZE, MMX, XY, HPEL)                              \
-static void OPNAME ## 2tap_qpel ## SIZE ## _mc ## XY ## _ ## MMX(uint8_t *dst, \
-                                                                 uint8_t *src, \
-                                                                 int stride)   \
-{                                                                              \
-    OPNAME ## pixels ## SIZE ## HPEL(dst, src, stride, SIZE);                  \
-}
-
-#define QPEL_2TAP_L3(OPNAME, SIZE, MMX, XY, S0, S1, S2)                        \
-static void OPNAME ## 2tap_qpel ## SIZE ## _mc ## XY ## _ ## MMX(uint8_t *dst, \
-                                                                 uint8_t *src, \
-                                                                 int stride)   \
-{                                                                              \
-    OPNAME ## 2tap_qpel ## SIZE ## _l3_ ## MMX(dst, src + S0, stride, SIZE,    \
-                                               S1, S2);                        \
-}
-
-#define QPEL_2TAP(OPNAME, SIZE, MMX)                                        \
-QPEL_2TAP_XY(OPNAME, SIZE, MMX, 20, _x2_ ## MMX)                            \
-QPEL_2TAP_XY(OPNAME, SIZE, MMX, 02, _y2_ ## MMX)                            \
-QPEL_2TAP_XY(OPNAME, SIZE, MMX, 22, _xy2_mmx)                               \
-static const qpel_mc_func OPNAME ## 2tap_qpel ## SIZE ## _mc00_ ## MMX =    \
-    OPNAME ## qpel ## SIZE ## _mc00_ ## MMX;                                \
-static const qpel_mc_func OPNAME ## 2tap_qpel ## SIZE ## _mc21_ ## MMX =    \
-    OPNAME ## 2tap_qpel ## SIZE ## _mc20_ ## MMX;                           \
-static const qpel_mc_func OPNAME ## 2tap_qpel ## SIZE ## _mc12_ ## MMX =    \
-    OPNAME ## 2tap_qpel ## SIZE ## _mc02_ ## MMX;                           \
-static void OPNAME ## 2tap_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst,      \
-                                                         uint8_t *src,      \
-                                                         int stride)        \
-{                                                                           \
-    OPNAME ## pixels ## SIZE ## _y2_ ## MMX(dst, src + 1, stride, SIZE);    \
-}                                                                           \
-static void OPNAME ## 2tap_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst,      \
-                                                         uint8_t *src,      \
-                                                         int stride)        \
-{                                                                           \
-    OPNAME ## pixels ## SIZE ## _x2_ ## MMX(dst, src + stride,              \
-                                            stride, SIZE);                  \
-}                                                                           \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 10, 0,           1,       0)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 30, 1,          -1,       0)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 01, 0,           stride,  0)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 03, stride,     -stride,  0)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 11, 0,           stride,  1)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 31, 1,           stride, -1)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 13, stride,     -stride,  1)                \
-QPEL_2TAP_L3(OPNAME, SIZE, MMX, 33, stride + 1, -stride, -1)                \
-
-QPEL_2TAP(put_, 16, mmxext)
-QPEL_2TAP(avg_, 16, mmxext)
-QPEL_2TAP(put_,  8, mmxext)
-QPEL_2TAP(avg_,  8, mmxext)
-
-void ff_put_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
-{
-  put_pixels8_xy2_mmx(dst, src, stride, 8);
-}
-void ff_put_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
-{
-  put_pixels16_xy2_mmx(dst, src, stride, 16);
-}
-void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
-{
-  avg_pixels8_xy2_mmx(dst, src, stride, 8);
-}
-void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src, int stride)
-{
-  avg_pixels16_xy2_mmx(dst, src, stride, 16);
-}
-
-static void gmc_mmx(uint8_t *dst, uint8_t *src,
-                    int stride, int h, int ox, int oy,
-                    int dxx, int dxy, int dyx, int dyy,
-                    int shift, int r, int width, int height)
+void ff_gmc_mmx(uint8_t *dst, uint8_t *src,
+                int stride, int h, int ox, int oy,
+                int dxx, int dxy, int dyx, int dyy,
+                int shift, int r, int width, int height)
 {
     const int w    = 8;
     const int ix   = ox  >> (16 + shift);
@@ -1750,216 +460,9 @@ static void gmc_mmx(uint8_t *dst, uint8_t *src,
         src += 4 - h * stride;
     }
 }
-#endif /* HAVE_INLINE_ASM */
-
-#include "h264_qpel.c"
-
-void ff_put_h264_chroma_mc8_rnd_mmx  (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc8_rnd_mmxext(uint8_t *dst, uint8_t *src,
-                                       int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc8_rnd_3dnow(uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-void ff_put_h264_chroma_mc4_mmx      (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc4_mmxext   (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc4_3dnow    (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-void ff_put_h264_chroma_mc2_mmxext   (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc2_mmxext   (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-void ff_put_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_put_h264_chroma_mc4_ssse3    (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
 
-void ff_avg_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-void ff_avg_h264_chroma_mc4_ssse3    (uint8_t *dst, uint8_t *src,
-                                      int stride, int h, int x, int y);
-
-#define CHROMA_MC(OP, NUM, DEPTH, OPT)                                  \
-void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT      \
-                                      (uint8_t *dst, uint8_t *src,      \
-                                       int stride, int h, int x, int y);
-
-CHROMA_MC(put, 2, 10, mmxext)
-CHROMA_MC(avg, 2, 10, mmxext)
-CHROMA_MC(put, 4, 10, mmxext)
-CHROMA_MC(avg, 4, 10, mmxext)
-CHROMA_MC(put, 8, 10, sse2)
-CHROMA_MC(avg, 8, 10, sse2)
-CHROMA_MC(put, 8, 10, avx)
-CHROMA_MC(avg, 8, 10, avx)
-
-#if HAVE_INLINE_ASM
-
-/* CAVS-specific */
-void ff_put_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride)
-{
-    put_pixels8_mmx(dst, src, stride, 8);
-}
-
-void ff_avg_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride)
-{
-    avg_pixels8_mmx(dst, src, stride, 8);
-}
-
-void ff_put_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride)
-{
-    put_pixels16_mmx(dst, src, stride, 16);
-}
-
-void ff_avg_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride)
-{
-    avg_pixels16_mmx(dst, src, stride, 16);
-}
-
-/* VC-1-specific */
-void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src,
-                               int stride, int rnd)
-{
-    put_pixels8_mmx(dst, src, stride, 8);
-}
-
-void ff_avg_vc1_mspel_mc00_mmxext(uint8_t *dst, const uint8_t *src,
-                                  int stride, int rnd)
-{
-    avg_pixels8_mmxext(dst, src, stride, 8);
-}
-
-static void vorbis_inverse_coupling_3dnow(float *mag, float *ang, int blocksize)
-{
-    int i;
-    __asm__ volatile ("pxor %%mm7, %%mm7":);
-    for (i = 0; i < blocksize; i += 2) {
-        __asm__ volatile (
-            "movq       %0, %%mm0   \n\t"
-            "movq       %1, %%mm1   \n\t"
-            "movq    %%mm0, %%mm2   \n\t"
-            "movq    %%mm1, %%mm3   \n\t"
-            "pfcmpge %%mm7, %%mm2   \n\t" // m <= 0.0
-            "pfcmpge %%mm7, %%mm3   \n\t" // a <= 0.0
-            "pslld     $31, %%mm2   \n\t" // keep only the sign bit
-            "pxor    %%mm2, %%mm1   \n\t"
-            "movq    %%mm3, %%mm4   \n\t"
-            "pand    %%mm1, %%mm3   \n\t"
-            "pandn   %%mm1, %%mm4   \n\t"
-            "pfadd   %%mm0, %%mm3   \n\t" // a = m + ((a < 0) & (a ^ sign(m)))
-            "pfsub   %%mm4, %%mm0   \n\t" // m = m + ((a > 0) & (a ^ sign(m)))
-            "movq    %%mm3, %1      \n\t"
-            "movq    %%mm0, %0      \n\t"
-            : "+m"(mag[i]), "+m"(ang[i])
-            :: "memory"
-        );
-    }
-    __asm__ volatile ("femms");
-}
-
-static void vorbis_inverse_coupling_sse(float *mag, float *ang, int blocksize)
-{
-    int i;
-
-    __asm__ volatile (
-        "movaps  %0, %%xmm5 \n\t"
-        :: "m"(ff_pdw_80000000[0])
-    );
-    for (i = 0; i < blocksize; i += 4) {
-        __asm__ volatile (
-            "movaps      %0, %%xmm0 \n\t"
-            "movaps      %1, %%xmm1 \n\t"
-            "xorps   %%xmm2, %%xmm2 \n\t"
-            "xorps   %%xmm3, %%xmm3 \n\t"
-            "cmpleps %%xmm0, %%xmm2 \n\t" // m <= 0.0
-            "cmpleps %%xmm1, %%xmm3 \n\t" // a <= 0.0
-            "andps   %%xmm5, %%xmm2 \n\t" // keep only the sign bit
-            "xorps   %%xmm2, %%xmm1 \n\t"
-            "movaps  %%xmm3, %%xmm4 \n\t"
-            "andps   %%xmm1, %%xmm3 \n\t"
-            "andnps  %%xmm1, %%xmm4 \n\t"
-            "addps   %%xmm0, %%xmm3 \n\t" // a = m + ((a < 0) & (a ^ sign(m)))
-            "subps   %%xmm4, %%xmm0 \n\t" // m = m + ((a > 0) & (a ^ sign(m)))
-            "movaps  %%xmm3, %1     \n\t"
-            "movaps  %%xmm0, %0     \n\t"
-            : "+m"(mag[i]), "+m"(ang[i])
-            :: "memory"
-        );
-    }
-}
-
-#if HAVE_6REGS
-static void vector_fmul_window_3dnowext(float *dst, const float *src0,
-                                        const float *src1, const float *win,
-                                        int len)
-{
-    x86_reg i = -len * 4;
-    x86_reg j =  len * 4 - 8;
-    __asm__ volatile (
-        "1:                             \n"
-        "pswapd (%5, %1), %%mm1         \n"
-        "movq   (%5, %0), %%mm0         \n"
-        "pswapd (%4, %1), %%mm5         \n"
-        "movq   (%3, %0), %%mm4         \n"
-        "movq      %%mm0, %%mm2         \n"
-        "movq      %%mm1, %%mm3         \n"
-        "pfmul     %%mm4, %%mm2         \n" // src0[len + i] * win[len + i]
-        "pfmul     %%mm5, %%mm3         \n" // src1[j]       * win[len + j]
-        "pfmul     %%mm4, %%mm1         \n" // src0[len + i] * win[len + j]
-        "pfmul     %%mm5, %%mm0         \n" // src1[j]       * win[len + i]
-        "pfadd     %%mm3, %%mm2         \n"
-        "pfsub     %%mm0, %%mm1         \n"
-        "pswapd    %%mm2, %%mm2         \n"
-        "movq      %%mm1, (%2, %0)      \n"
-        "movq      %%mm2, (%2, %1)      \n"
-        "sub          $8, %1            \n"
-        "add          $8, %0            \n"
-        "jl           1b                \n"
-        "femms                          \n"
-        : "+r"(i), "+r"(j)
-        : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len)
-    );
-}
-
-static void vector_fmul_window_sse(float *dst, const float *src0,
-                                   const float *src1, const float *win, int len)
-{
-    x86_reg i = -len * 4;
-    x86_reg j =  len * 4 - 16;
-    __asm__ volatile (
-        "1:                             \n"
-        "movaps      (%5, %1), %%xmm1   \n"
-        "movaps      (%5, %0), %%xmm0   \n"
-        "movaps      (%4, %1), %%xmm5   \n"
-        "movaps      (%3, %0), %%xmm4   \n"
-        "shufps $0x1b, %%xmm1, %%xmm1   \n"
-        "shufps $0x1b, %%xmm5, %%xmm5   \n"
-        "movaps        %%xmm0, %%xmm2   \n"
-        "movaps        %%xmm1, %%xmm3   \n"
-        "mulps         %%xmm4, %%xmm2   \n" // src0[len + i] * win[len + i]
-        "mulps         %%xmm5, %%xmm3   \n" // src1[j]       * win[len + j]
-        "mulps         %%xmm4, %%xmm1   \n" // src0[len + i] * win[len + j]
-        "mulps         %%xmm5, %%xmm0   \n" // src1[j]       * win[len + i]
-        "addps         %%xmm3, %%xmm2   \n"
-        "subps         %%xmm0, %%xmm1   \n"
-        "shufps $0x1b, %%xmm2, %%xmm2   \n"
-        "movaps        %%xmm1, (%2, %0) \n"
-        "movaps        %%xmm2, (%2, %1) \n"
-        "sub              $16, %1       \n"
-        "add              $16, %0       \n"
-        "jl                1b           \n"
-        : "+r"(i), "+r"(j)
-        : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len)
-    );
-}
-#endif /* HAVE_6REGS */
-
-static void vector_clipf_sse(float *dst, const float *src,
-                             float min, float max, int len)
+void ff_vector_clipf_sse(float *dst, const float *src,
+                         float min, float max, int len)
 {
     x86_reg i = (len - 16) * 4;
     __asm__ volatile (
@@ -1993,561 +496,3 @@ static void vector_clipf_sse(float *dst, const float *src,
 }
 
 #endif /* HAVE_INLINE_ASM */
-
-int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2,
-                                      int order);
-int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2,
-                                    int order);
-int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2,
-                                               const int16_t *v3,
-                                               int order, int mul);
-int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2,
-                                             const int16_t *v3,
-                                             int order, int mul);
-int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2,
-                                              const int16_t *v3,
-                                              int order, int mul);
-
-void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
-                                        const int16_t *window, unsigned int len);
-void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
-                                      const int16_t *window, unsigned int len);
-void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
-                                  const int16_t *window, unsigned int len);
-void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
-                                const int16_t *window, unsigned int len);
-void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
-                                 const int16_t *window, unsigned int len);
-void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
-                                      const int16_t *window, unsigned int len);
-
-void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w);
-void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w);
-
-void ff_add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top,
-                                          const uint8_t *diff, int w,
-                                          int *left, int *left_top);
-int  ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src,
-                                       int w, int left);
-int  ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
-                                      int w, int left);
-
-float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
-
-void ff_vector_fmul_reverse_sse(float *dst, const float *src0,
-                                const float *src1, int len);
-void ff_vector_fmul_reverse_avx(float *dst, const float *src0,
-                                const float *src1, int len);
-
-void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1,
-                            const float *src2, int len);
-void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1,
-                            const float *src2, int len);
-
-void ff_vector_clip_int32_mmx     (int32_t *dst, const int32_t *src,
-                                   int32_t min, int32_t max, unsigned int len);
-void ff_vector_clip_int32_sse2    (int32_t *dst, const int32_t *src,
-                                   int32_t min, int32_t max, unsigned int len);
-void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src,
-                                   int32_t min, int32_t max, unsigned int len);
-void ff_vector_clip_int32_sse4    (int32_t *dst, const int32_t *src,
-                                   int32_t min, int32_t max, unsigned int len);
-
-extern void ff_butterflies_float_interleave_sse(float *dst, const float *src0,
-                                                const float *src1, int len);
-extern void ff_butterflies_float_interleave_avx(float *dst, const float *src0,
-                                                const float *src1, int len);
-
-#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX)                          \
-    do {                                                                     \
-    c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \
-    c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \
-    } while (0)
-
-#define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU)                                     \
-    do {                                                                        \
-        c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## SIZE ## _     ## CPU; \
-        c->PFX ## _pixels_tab[IDX][1] = PFX ## _pixels ## SIZE ## _x2_  ## CPU; \
-        c->PFX ## _pixels_tab[IDX][2] = PFX ## _pixels ## SIZE ## _y2_  ## CPU; \
-        c->PFX ## _pixels_tab[IDX][3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU; \
-    } while (0)
-
-#define H264_QPEL_FUNCS(x, y, CPU)                                                            \
-    do {                                                                                      \
-        c->put_h264_qpel_pixels_tab[0][x + y * 4] = put_h264_qpel16_mc ## x ## y ## _ ## CPU; \
-        c->put_h264_qpel_pixels_tab[1][x + y * 4] = put_h264_qpel8_mc  ## x ## y ## _ ## CPU; \
-        c->avg_h264_qpel_pixels_tab[0][x + y * 4] = avg_h264_qpel16_mc ## x ## y ## _ ## CPU; \
-        c->avg_h264_qpel_pixels_tab[1][x + y * 4] = avg_h264_qpel8_mc  ## x ## y ## _ ## CPU; \
-    } while (0)
-
-#define H264_QPEL_FUNCS_10(x, y, CPU)                                                               \
-    do {                                                                                            \
-        c->put_h264_qpel_pixels_tab[0][x + y * 4] = ff_put_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \
-        c->put_h264_qpel_pixels_tab[1][x + y * 4] = ff_put_h264_qpel8_mc  ## x ## y ## _10_ ## CPU; \
-        c->avg_h264_qpel_pixels_tab[0][x + y * 4] = ff_avg_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \
-        c->avg_h264_qpel_pixels_tab[1][x + y * 4] = ff_avg_h264_qpel8_mc  ## x ## y ## _10_ ## CPU; \
-    } while (0)
-
-static void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx, int mm_flags)
-{
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-#if HAVE_INLINE_ASM
-    c->put_pixels_clamped        = ff_put_pixels_clamped_mmx;
-    c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx;
-    c->add_pixels_clamped        = ff_add_pixels_clamped_mmx;
-
-    if (!high_bit_depth) {
-        c->clear_block  = clear_block_mmx;
-        c->clear_blocks = clear_blocks_mmx;
-        c->draw_edges   = draw_edges_mmx;
-
-        SET_HPEL_FUNCS(put,        0, 16, mmx);
-        SET_HPEL_FUNCS(put_no_rnd, 0, 16, mmx);
-        SET_HPEL_FUNCS(avg,        0, 16, mmx);
-        SET_HPEL_FUNCS(avg_no_rnd, 0, 16, mmx);
-        SET_HPEL_FUNCS(put,        1,  8, mmx);
-        SET_HPEL_FUNCS(put_no_rnd, 1,  8, mmx);
-        SET_HPEL_FUNCS(avg,        1,  8, mmx);
-        SET_HPEL_FUNCS(avg_no_rnd, 1,  8, mmx);
-
-        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;
-        }
-    }
-
-    c->gmc = gmc_mmx;
-
-    c->add_bytes = add_bytes_mmx;
-
-    if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
-        c->h263_v_loop_filter = h263_v_loop_filter_mmx;
-        c->h263_h_loop_filter = h263_h_loop_filter_mmx;
-    }
-#endif /* HAVE_INLINE_ASM */
-
-#if HAVE_YASM
-    if (!high_bit_depth && CONFIG_H264CHROMA) {
-        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_mmx;
-        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmx;
-    }
-
-    c->vector_clip_int32 = ff_vector_clip_int32_mmx;
-#endif
-
-}
-
-static void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx,
-                                int mm_flags)
-{
-    const int bit_depth      = avctx->bits_per_raw_sample;
-    const int high_bit_depth = bit_depth > 8;
-
-#if HAVE_INLINE_ASM
-    SET_QPEL_FUNCS(avg_qpel,        0, 16, mmxext, );
-    SET_QPEL_FUNCS(avg_qpel,        1,  8, mmxext, );
-    SET_QPEL_FUNCS(avg_2tap_qpel,   0, 16, mmxext, );
-    SET_QPEL_FUNCS(avg_2tap_qpel,   1,  8, mmxext, );
-
-    SET_QPEL_FUNCS(put_qpel,        0, 16, mmxext, );
-    SET_QPEL_FUNCS(put_qpel,        1,  8, mmxext, );
-    SET_QPEL_FUNCS(put_2tap_qpel,   0, 16, mmxext, );
-    SET_QPEL_FUNCS(put_2tap_qpel,   1,  8, mmxext, );
-    SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, );
-    SET_QPEL_FUNCS(put_no_rnd_qpel, 1,  8, mmxext, );
-
-    if (!high_bit_depth) {
-        c->put_pixels_tab[0][1] = put_pixels16_x2_mmxext;
-        c->put_pixels_tab[0][2] = put_pixels16_y2_mmxext;
-
-        c->avg_pixels_tab[0][0] = avg_pixels16_mmxext;
-        c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmxext;
-        c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmxext;
-
-        c->put_pixels_tab[1][1] = put_pixels8_x2_mmxext;
-        c->put_pixels_tab[1][2] = put_pixels8_y2_mmxext;
-
-        c->avg_pixels_tab[1][0] = avg_pixels8_mmxext;
-        c->avg_pixels_tab[1][1] = avg_pixels8_x2_mmxext;
-        c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmxext;
-    }
-
-    if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
-        if (!high_bit_depth) {
-            c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmxext;
-            c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmxext;
-            c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_mmxext;
-            c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_mmxext;
-
-            c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmxext;
-            c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mmxext;
-        }
-    }
-
-    if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) {
-        c->idct_put = ff_idct_xvid_mmxext_put;
-        c->idct_add = ff_idct_xvid_mmxext_add;
-        c->idct     = ff_idct_xvid_mmxext;
-    }
-
-    if (CONFIG_VP3_DECODER && (avctx->codec_id == AV_CODEC_ID_VP3 ||
-                               avctx->codec_id == AV_CODEC_ID_THEORA)) {
-        c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_exact_mmxext;
-        c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_exact_mmxext;
-    }
-#endif /* HAVE_INLINE_ASM */
-
-#if HAVE_MMXEXT_EXTERNAL
-    if (CONFIG_H264QPEL) {
-        if (!high_bit_depth) {
-            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmxext, );
-            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, mmxext, );
-            SET_QPEL_FUNCS(put_h264_qpel, 2,  4, mmxext, );
-            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmxext, );
-            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, mmxext, );
-            SET_QPEL_FUNCS(avg_h264_qpel, 2,  4, mmxext, );
-        } else if (bit_depth == 10) {
-#if !ARCH_X86_64
-            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_mmxext, ff_);
-            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_mmxext, ff_);
-            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_mmxext, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_mmxext, ff_);
-#endif
-            SET_QPEL_FUNCS(put_h264_qpel, 2, 4,  10_mmxext, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 2, 4,  10_mmxext, ff_);
-        }
-    }
-
-    if (!high_bit_depth && CONFIG_H264CHROMA) {
-        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_mmxext;
-        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmxext;
-        c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_mmxext;
-        c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_mmxext;
-    }
-    if (bit_depth == 10 && CONFIG_H264CHROMA) {
-        c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_10_mmxext;
-        c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_10_mmxext;
-        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_10_mmxext;
-        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_10_mmxext;
-    }
-
-    /* slower than cmov version on AMD */
-    if (!(mm_flags & AV_CPU_FLAG_3DNOW))
-        c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmxext;
-
-    c->scalarproduct_int16          = ff_scalarproduct_int16_mmxext;
-    c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext;
-
-    if (avctx->flags & CODEC_FLAG_BITEXACT) {
-        c->apply_window_int16 = ff_apply_window_int16_mmxext;
-    } else {
-        c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
-    }
-#endif /* HAVE_MMXEXT_EXTERNAL */
-}
-
-static void dsputil_init_3dnow(DSPContext *c, AVCodecContext *avctx,
-                               int mm_flags)
-{
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-#if HAVE_INLINE_ASM
-    if (!high_bit_depth) {
-        c->put_pixels_tab[0][1] = put_pixels16_x2_3dnow;
-        c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow;
-
-        c->avg_pixels_tab[0][0] = avg_pixels16_3dnow;
-        c->avg_pixels_tab[0][1] = avg_pixels16_x2_3dnow;
-        c->avg_pixels_tab[0][2] = avg_pixels16_y2_3dnow;
-
-        c->put_pixels_tab[1][1] = put_pixels8_x2_3dnow;
-        c->put_pixels_tab[1][2] = put_pixels8_y2_3dnow;
-
-        c->avg_pixels_tab[1][0] = avg_pixels8_3dnow;
-        c->avg_pixels_tab[1][1] = avg_pixels8_x2_3dnow;
-        c->avg_pixels_tab[1][2] = avg_pixels8_y2_3dnow;
-
-        if (!(avctx->flags & CODEC_FLAG_BITEXACT)){
-            c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_3dnow;
-            c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_3dnow;
-            c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_3dnow;
-            c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_3dnow;
-
-            c->avg_pixels_tab[0][3] = avg_pixels16_xy2_3dnow;
-            c->avg_pixels_tab[1][3] = avg_pixels8_xy2_3dnow;
-        }
-    }
-
-    if (CONFIG_VP3_DECODER && (avctx->codec_id == AV_CODEC_ID_VP3 ||
-                               avctx->codec_id == AV_CODEC_ID_THEORA)) {
-        c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_exact_3dnow;
-        c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_exact_3dnow;
-    }
-
-    c->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow;
-#endif /* HAVE_INLINE_ASM */
-
-#if HAVE_YASM
-    if (!high_bit_depth && CONFIG_H264CHROMA) {
-        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_3dnow;
-        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_3dnow;
-    }
-#endif /* HAVE_YASM */
-}
-
-static void dsputil_init_3dnowext(DSPContext *c, AVCodecContext *avctx,
-                                  int mm_flags)
-{
-#if HAVE_AMD3DNOWEXT_INLINE && HAVE_6REGS
-    c->vector_fmul_window  = vector_fmul_window_3dnowext;
-#endif
-}
-
-static void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx, int mm_flags)
-{
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-
-#if HAVE_INLINE_ASM
-    if (!high_bit_depth) {
-        if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) {
-            /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */
-            c->clear_block  = clear_block_sse;
-            c->clear_blocks = clear_blocks_sse;
-        }
-    }
-
-    c->vorbis_inverse_coupling = vorbis_inverse_coupling_sse;
-
-#if HAVE_6REGS
-    c->vector_fmul_window = vector_fmul_window_sse;
-#endif
-
-    c->vector_clipf = vector_clipf_sse;
-#endif /* HAVE_INLINE_ASM */
-
-#if HAVE_YASM
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_sse;
-    c->vector_fmul_add     = ff_vector_fmul_add_sse;
-
-    c->scalarproduct_float          = ff_scalarproduct_float_sse;
-    c->butterflies_float_interleave = ff_butterflies_float_interleave_sse;
-#endif /* HAVE_YASM */
-}
-
-static void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx,
-                              int mm_flags)
-{
-    const int bit_depth      = avctx->bits_per_raw_sample;
-    const int high_bit_depth = bit_depth > 8;
-
-#if HAVE_SSE2_INLINE
-    if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) {
-        c->idct_put              = ff_idct_xvid_sse2_put;
-        c->idct_add              = ff_idct_xvid_sse2_add;
-        c->idct                  = ff_idct_xvid_sse2;
-        c->idct_permutation_type = FF_SSE2_IDCT_PERM;
-    }
-#endif /* HAVE_SSE2_INLINE */
-
-#if HAVE_SSE2_EXTERNAL
-    if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
-        // these functions are slower than mmx on AMD, but faster on Intel
-        if (!high_bit_depth) {
-            c->put_pixels_tab[0][0]        = ff_put_pixels16_sse2;
-            c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_sse2;
-            c->avg_pixels_tab[0][0]        = ff_avg_pixels16_sse2;
-            if (CONFIG_H264QPEL)
-                H264_QPEL_FUNCS(0, 0, sse2);
-        }
-    }
-
-    if (!high_bit_depth && CONFIG_H264QPEL) {
-        H264_QPEL_FUNCS(0, 1, sse2);
-        H264_QPEL_FUNCS(0, 2, sse2);
-        H264_QPEL_FUNCS(0, 3, sse2);
-        H264_QPEL_FUNCS(1, 1, sse2);
-        H264_QPEL_FUNCS(1, 2, sse2);
-        H264_QPEL_FUNCS(1, 3, sse2);
-        H264_QPEL_FUNCS(2, 1, sse2);
-        H264_QPEL_FUNCS(2, 2, sse2);
-        H264_QPEL_FUNCS(2, 3, sse2);
-        H264_QPEL_FUNCS(3, 1, sse2);
-        H264_QPEL_FUNCS(3, 2, sse2);
-        H264_QPEL_FUNCS(3, 3, sse2);
-    }
-
-    if (bit_depth == 10) {
-        if (CONFIG_H264QPEL) {
-            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_sse2, ff_);
-            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_sse2, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_sse2, ff_);
-            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_sse2, ff_);
-            H264_QPEL_FUNCS_10(1, 0, sse2_cache64);
-            H264_QPEL_FUNCS_10(2, 0, sse2_cache64);
-            H264_QPEL_FUNCS_10(3, 0, sse2_cache64);
-        }
-        if (CONFIG_H264CHROMA) {
-            c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_sse2;
-            c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_sse2;
-        }
-    }
-
-    c->scalarproduct_int16          = ff_scalarproduct_int16_sse2;
-    c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;
-    if (mm_flags & AV_CPU_FLAG_ATOM) {
-        c->vector_clip_int32 = ff_vector_clip_int32_int_sse2;
-    } else {
-        c->vector_clip_int32 = ff_vector_clip_int32_sse2;
-    }
-    if (avctx->flags & CODEC_FLAG_BITEXACT) {
-        c->apply_window_int16 = ff_apply_window_int16_sse2;
-    } else if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
-        c->apply_window_int16 = ff_apply_window_int16_round_sse2;
-    }
-    c->bswap_buf = ff_bswap32_buf_sse2;
-#endif /* HAVE_SSE2_EXTERNAL */
-}
-
-static void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx,
-                               int mm_flags)
-{
-#if HAVE_SSSE3_EXTERNAL
-    const int high_bit_depth = avctx->bits_per_raw_sample > 8;
-    const int bit_depth      = avctx->bits_per_raw_sample;
-
-    if (!high_bit_depth && CONFIG_H264QPEL) {
-        H264_QPEL_FUNCS(1, 0, ssse3);
-        H264_QPEL_FUNCS(1, 1, ssse3);
-        H264_QPEL_FUNCS(1, 2, ssse3);
-        H264_QPEL_FUNCS(1, 3, ssse3);
-        H264_QPEL_FUNCS(2, 0, ssse3);
-        H264_QPEL_FUNCS(2, 1, ssse3);
-        H264_QPEL_FUNCS(2, 2, ssse3);
-        H264_QPEL_FUNCS(2, 3, ssse3);
-        H264_QPEL_FUNCS(3, 0, ssse3);
-        H264_QPEL_FUNCS(3, 1, ssse3);
-        H264_QPEL_FUNCS(3, 2, ssse3);
-        H264_QPEL_FUNCS(3, 3, ssse3);
-    }
-    if (bit_depth == 10 && CONFIG_H264QPEL) {
-        H264_QPEL_FUNCS_10(1, 0, ssse3_cache64);
-        H264_QPEL_FUNCS_10(2, 0, ssse3_cache64);
-        H264_QPEL_FUNCS_10(3, 0, ssse3_cache64);
-    }
-    if (!high_bit_depth && CONFIG_H264CHROMA) {
-        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_ssse3;
-        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_ssse3;
-        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_ssse3;
-        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_ssse3;
-    }
-    c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_ssse3;
-    if (mm_flags & AV_CPU_FLAG_SSE4) // not really sse4, just slow on Conroe
-        c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4;
-
-    if (mm_flags & AV_CPU_FLAG_ATOM)
-        c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
-    else
-        c->apply_window_int16 = ff_apply_window_int16_ssse3;
-    if (!(mm_flags & (AV_CPU_FLAG_SSE42|AV_CPU_FLAG_3DNOW))) // cachesplit
-        c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3;
-    c->bswap_buf = ff_bswap32_buf_ssse3;
-#endif /* HAVE_SSSE3_EXTERNAL */
-}
-
-static void dsputil_init_sse4(DSPContext *c, AVCodecContext *avctx,
-                              int mm_flags)
-{
-#if HAVE_SSE4_EXTERNAL
-    c->vector_clip_int32 = ff_vector_clip_int32_sse4;
-#endif /* HAVE_SSE4_EXTERNAL */
-}
-
-static void dsputil_init_avx(DSPContext *c, AVCodecContext *avctx, int mm_flags)
-{
-#if HAVE_AVX_EXTERNAL
-    const int bit_depth = avctx->bits_per_raw_sample;
-
-    if (bit_depth == 10) {
-        // AVX implies !cache64.
-        // TODO: Port cache(32|64) detection from x264.
-        if (CONFIG_H264QPEL) {
-            H264_QPEL_FUNCS_10(1, 0, sse2);
-            H264_QPEL_FUNCS_10(2, 0, sse2);
-            H264_QPEL_FUNCS_10(3, 0, sse2);
-        }
-
-        if (CONFIG_H264CHROMA) {
-            c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_avx;
-            c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx;
-        }
-    }
-    c->butterflies_float_interleave = ff_butterflies_float_interleave_avx;
-    c->vector_fmul_reverse = ff_vector_fmul_reverse_avx;
-    c->vector_fmul_add = ff_vector_fmul_add_avx;
-#endif /* HAVE_AVX_EXTERNAL */
-}
-
-void ff_dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx)
-{
-    int mm_flags = av_get_cpu_flags();
-
-#if HAVE_7REGS && HAVE_INLINE_ASM
-    if (mm_flags & AV_CPU_FLAG_CMOV)
-        c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
-#endif
-
-    if (mm_flags & AV_CPU_FLAG_MMX)
-        dsputil_init_mmx(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_MMXEXT)
-        dsputil_init_mmxext(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_3DNOW)
-        dsputil_init_3dnow(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_3DNOWEXT)
-        dsputil_init_3dnowext(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_SSE)
-        dsputil_init_sse(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_SSE2)
-        dsputil_init_sse2(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_SSSE3)
-        dsputil_init_ssse3(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_SSE4)
-        dsputil_init_sse4(c, avctx, mm_flags);
-
-    if (mm_flags & AV_CPU_FLAG_AVX)
-        dsputil_init_avx(c, avctx, mm_flags);
-
-    if (CONFIG_ENCODERS)
-        ff_dsputilenc_init_mmx(c, avctx);
-}
diff --git a/libavcodec/x86/dsputil_mmx.h b/libavcodec/x86/dsputil_mmx.h
deleted file mode 100644
index a142406..0000000
--- a/libavcodec/x86/dsputil_mmx.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * MMX optimized DSP utils
- * Copyright (c) 2007  Aurelien Jacobs <aurel at gnuage.org>
- *
- * 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_X86_DSPUTIL_MMX_H
-#define AVCODEC_X86_DSPUTIL_MMX_H
-
-#include <stdint.h>
-#include "libavcodec/dsputil.h"
-#include "libavutil/x86/asm.h"
-
-typedef struct xmm_reg { uint64_t a, b; } xmm_reg;
-
-extern const uint64_t ff_bone;
-extern const uint64_t ff_wtwo;
-
-extern const uint64_t ff_pdw_80000000[2];
-
-extern const xmm_reg  ff_pw_3;
-extern const xmm_reg  ff_pw_4;
-extern const xmm_reg  ff_pw_5;
-extern const xmm_reg  ff_pw_8;
-extern const uint64_t ff_pw_15;
-extern const xmm_reg  ff_pw_16;
-extern const xmm_reg  ff_pw_18;
-extern const uint64_t ff_pw_20;
-extern const xmm_reg  ff_pw_27;
-extern const xmm_reg  ff_pw_28;
-extern const xmm_reg  ff_pw_32;
-extern const uint64_t ff_pw_42;
-extern const uint64_t ff_pw_53;
-extern const xmm_reg  ff_pw_63;
-extern const xmm_reg  ff_pw_64;
-extern const uint64_t ff_pw_96;
-extern const uint64_t ff_pw_128;
-extern const uint64_t ff_pw_255;
-
-extern const xmm_reg  ff_pb_1;
-extern const xmm_reg  ff_pb_3;
-extern const uint64_t ff_pb_7;
-extern const uint64_t ff_pb_1F;
-extern const uint64_t ff_pb_3F;
-extern const uint64_t ff_pb_81;
-extern const xmm_reg  ff_pb_A1;
-extern const xmm_reg  ff_pb_F8;
-extern const uint64_t ff_pb_FC;
-extern const xmm_reg  ff_pb_FE;
-
-extern const double ff_pd_1[2];
-extern const double ff_pd_2[2];
-
-#define SBUTTERFLY(a,b,t,n,m)\
-    "mov" #m " " #a ", " #t "         \n\t" /* abcd */\
-    "punpckl" #n " " #b ", " #a "     \n\t" /* aebf */\
-    "punpckh" #n " " #b ", " #t "     \n\t" /* cgdh */\
-
-#define TRANSPOSE4(a,b,c,d,t)\
-    SBUTTERFLY(a,b,t,wd,q) /* a=aebf t=cgdh */\
-    SBUTTERFLY(c,d,b,wd,q) /* c=imjn b=kolp */\
-    SBUTTERFLY(a,c,d,dq,q) /* a=aeim d=bfjn */\
-    SBUTTERFLY(t,b,c,dq,q) /* t=cgko c=dhlp */
-
-#define MOVQ_WONE(regd) \
-    __asm__ volatile ( \
-    "pcmpeqd %%" #regd ", %%" #regd " \n\t" \
-    "psrlw $15, %%" #regd ::)
-
-void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx);
-void ff_dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx);
-
-void ff_add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
-void ff_put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
-void ff_put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
-
-void ff_put_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride);
-void ff_avg_cavs_qpel8_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride);
-void ff_put_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride);
-void ff_avg_cavs_qpel16_mc00_mmxext(uint8_t *dst, uint8_t *src, int stride);
-
-void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd);
-void ff_avg_vc1_mspel_mc00_mmxext(uint8_t *dst, const uint8_t *src, int stride, int rnd);
-
-void ff_put_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
-void ff_put_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
-void ff_avg_rv40_qpel8_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
-void ff_avg_rv40_qpel16_mc33_mmx(uint8_t *block, uint8_t *pixels, int line_size);
-
-void ff_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,
-                             const uint8_t *lum,
-                             int size);
-
-void ff_deinterlace_line_inplace_mmx(const uint8_t *lum_m4,
-                                     const uint8_t *lum_m3,
-                                     const uint8_t *lum_m2,
-                                     const uint8_t *lum_m1,
-                                     const uint8_t *lum, int size);
-
-#endif /* AVCODEC_X86_DSPUTIL_MMX_H */
diff --git a/libavcodec/x86/dsputil_rnd_template.c b/libavcodec/x86/dsputil_rnd_template.c
deleted file mode 100644
index 34a2c0b..0000000
--- a/libavcodec/x86/dsputil_rnd_template.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * DSP utils mmx functions are compiled twice for rnd/no_rnd
- * Copyright (c) 2000, 2001 Fabrice Bellard
- * Copyright (c) 2003-2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
- * mostly rewritten by Michael Niedermayer <michaelni at gmx.at>
- * and improved by Zdenek Kabelac <kabi at users.sf.net>
- *
- * 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
- */
-
-// put_pixels
-static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    __asm__ volatile(
-        "lea    (%3, %3), %%"REG_a"     \n\t"
-        ".p2align 3                     \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   1(%1), %%mm1            \n\t"
-        "movq   (%1, %3), %%mm2         \n\t"
-        "movq   1(%1, %3), %%mm3        \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%2)             \n\t"
-        "movq   %%mm5, (%2, %3)         \n\t"
-        "add    %%"REG_a", %1           \n\t"
-        "add    %%"REG_a", %2           \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   1(%1), %%mm1            \n\t"
-        "movq   (%1, %3), %%mm2         \n\t"
-        "movq   1(%1, %3), %%mm3        \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%2)             \n\t"
-        "movq   %%mm5, (%2, %3)         \n\t"
-        "add    %%"REG_a", %1           \n\t"
-        "add    %%"REG_a", %2           \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r"((x86_reg)line_size)
-        :REG_a, "memory");
-}
-
-static void av_unused DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    MOVQ_BFE(mm6);
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-        " jz 1f                         \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $8, %2                  \n\t"
-        PAVGB(%%mm0, %%mm1, %%mm4, %%mm6)
-        "movq   %%mm4, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        ".p2align 3                     \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm2             \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm5, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   16(%2), %%mm1           \n\t"
-        "add    %4, %1                  \n\t"
-        "movq   (%1), %%mm2             \n\t"
-        "movq   24(%2), %%mm3           \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $32, %2                 \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   %%mm5, (%3)             \n\t"
-        "add    %5, %3                  \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-}
-
-static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    __asm__ volatile(
-        "lea        (%3, %3), %%"REG_a" \n\t"
-        ".p2align 3                     \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   1(%1), %%mm1            \n\t"
-        "movq   (%1, %3), %%mm2         \n\t"
-        "movq   1(%1, %3), %%mm3        \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%2)             \n\t"
-        "movq   %%mm5, (%2, %3)         \n\t"
-        "movq   8(%1), %%mm0            \n\t"
-        "movq   9(%1), %%mm1            \n\t"
-        "movq   8(%1, %3), %%mm2        \n\t"
-        "movq   9(%1, %3), %%mm3        \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, 8(%2)            \n\t"
-        "movq   %%mm5, 8(%2, %3)        \n\t"
-        "add    %%"REG_a", %1           \n\t"
-        "add    %%"REG_a", %2           \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   1(%1), %%mm1            \n\t"
-        "movq   (%1, %3), %%mm2         \n\t"
-        "movq   1(%1, %3), %%mm3        \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%2)             \n\t"
-        "movq   %%mm5, (%2, %3)         \n\t"
-        "movq   8(%1), %%mm0            \n\t"
-        "movq   9(%1), %%mm1            \n\t"
-        "movq   8(%1, %3), %%mm2        \n\t"
-        "movq   9(%1, %3), %%mm3        \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, 8(%2)            \n\t"
-        "movq   %%mm5, 8(%2, %3)        \n\t"
-        "add    %%"REG_a", %1           \n\t"
-        "add    %%"REG_a", %2           \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r"((x86_reg)line_size)
-        :REG_a, "memory");
-}
-
-static void av_unused DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    MOVQ_BFE(mm6);
-    __asm__ volatile(
-        "testl $1, %0                   \n\t"
-        " jz 1f                         \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "movq   8(%1), %%mm2            \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "add    %4, %1                  \n\t"
-        "add    $16, %2                 \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%3)             \n\t"
-        "movq   %%mm5, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "decl   %0                      \n\t"
-        ".p2align 3                     \n\t"
-        "1:                             \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   (%2), %%mm1             \n\t"
-        "movq   8(%1), %%mm2            \n\t"
-        "movq   8(%2), %%mm3            \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%3)             \n\t"
-        "movq   %%mm5, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        "movq   16(%2), %%mm1           \n\t"
-        "movq   8(%1), %%mm2            \n\t"
-        "movq   24(%2), %%mm3           \n\t"
-        "add    %4, %1                  \n\t"
-        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
-        "movq   %%mm4, (%3)             \n\t"
-        "movq   %%mm5, 8(%3)            \n\t"
-        "add    %5, %3                  \n\t"
-        "add    $32, %2                 \n\t"
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-#if !HAVE_EBX_AVAILABLE  //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cannot be used
-        :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#else
-        :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
-#endif
-        :"S"((x86_reg)src1Stride), "D"((x86_reg)dstStride)
-        :"memory");
-}
-
-static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    __asm__ volatile(
-        "lea (%3, %3), %%"REG_a"        \n\t"
-        "movq (%1), %%mm0               \n\t"
-        ".p2align 3                     \n\t"
-        "1:                             \n\t"
-        "movq   (%1, %3), %%mm1         \n\t"
-        "movq   (%1, %%"REG_a"),%%mm2   \n\t"
-        PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
-        "movq   %%mm4, (%2)             \n\t"
-        "movq   %%mm5, (%2, %3)         \n\t"
-        "add    %%"REG_a", %1           \n\t"
-        "add    %%"REG_a", %2           \n\t"
-        "movq   (%1, %3), %%mm1         \n\t"
-        "movq   (%1, %%"REG_a"),%%mm0   \n\t"
-        PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
-        "movq   %%mm4, (%2)             \n\t"
-        "movq   %%mm5, (%2, %3)         \n\t"
-        "add    %%"REG_a", %1           \n\t"
-        "add    %%"REG_a", %2           \n\t"
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r"((x86_reg)line_size)
-        :REG_a, "memory");
-}
-
-static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_ZERO(mm7);
-    SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
-    __asm__ volatile(
-        "movq   (%1), %%mm0             \n\t"
-        "movq   1(%1), %%mm4            \n\t"
-        "movq   %%mm0, %%mm1            \n\t"
-        "movq   %%mm4, %%mm5            \n\t"
-        "punpcklbw %%mm7, %%mm0         \n\t"
-        "punpcklbw %%mm7, %%mm4         \n\t"
-        "punpckhbw %%mm7, %%mm1         \n\t"
-        "punpckhbw %%mm7, %%mm5         \n\t"
-        "paddusw %%mm0, %%mm4           \n\t"
-        "paddusw %%mm1, %%mm5           \n\t"
-        "xor    %%"REG_a", %%"REG_a"    \n\t"
-        "add    %3, %1                  \n\t"
-        ".p2align 3                     \n\t"
-        "1:                             \n\t"
-        "movq   (%1, %%"REG_a"), %%mm0  \n\t"
-        "movq   1(%1, %%"REG_a"), %%mm2 \n\t"
-        "movq   %%mm0, %%mm1            \n\t"
-        "movq   %%mm2, %%mm3            \n\t"
-        "punpcklbw %%mm7, %%mm0         \n\t"
-        "punpcklbw %%mm7, %%mm2         \n\t"
-        "punpckhbw %%mm7, %%mm1         \n\t"
-        "punpckhbw %%mm7, %%mm3         \n\t"
-        "paddusw %%mm2, %%mm0           \n\t"
-        "paddusw %%mm3, %%mm1           \n\t"
-        "paddusw %%mm6, %%mm4           \n\t"
-        "paddusw %%mm6, %%mm5           \n\t"
-        "paddusw %%mm0, %%mm4           \n\t"
-        "paddusw %%mm1, %%mm5           \n\t"
-        "psrlw  $2, %%mm4               \n\t"
-        "psrlw  $2, %%mm5               \n\t"
-        "packuswb  %%mm5, %%mm4         \n\t"
-        "movq   %%mm4, (%2, %%"REG_a")  \n\t"
-        "add    %3, %%"REG_a"           \n\t"
-
-        "movq   (%1, %%"REG_a"), %%mm2  \n\t" // 0 <-> 2   1 <-> 3
-        "movq   1(%1, %%"REG_a"), %%mm4 \n\t"
-        "movq   %%mm2, %%mm3            \n\t"
-        "movq   %%mm4, %%mm5            \n\t"
-        "punpcklbw %%mm7, %%mm2         \n\t"
-        "punpcklbw %%mm7, %%mm4         \n\t"
-        "punpckhbw %%mm7, %%mm3         \n\t"
-        "punpckhbw %%mm7, %%mm5         \n\t"
-        "paddusw %%mm2, %%mm4           \n\t"
-        "paddusw %%mm3, %%mm5           \n\t"
-        "paddusw %%mm6, %%mm0           \n\t"
-        "paddusw %%mm6, %%mm1           \n\t"
-        "paddusw %%mm4, %%mm0           \n\t"
-        "paddusw %%mm5, %%mm1           \n\t"
-        "psrlw  $2, %%mm0               \n\t"
-        "psrlw  $2, %%mm1               \n\t"
-        "packuswb  %%mm1, %%mm0         \n\t"
-        "movq   %%mm0, (%2, %%"REG_a")  \n\t"
-        "add    %3, %%"REG_a"           \n\t"
-
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-        :"+g"(h), "+S"(pixels)
-        :"D"(block), "r"((x86_reg)line_size)
-        :REG_a, "memory");
-}
-
-// avg_pixels
-static void av_unused DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-             "movd  %0, %%mm0           \n\t"
-             "movd  %1, %%mm1           \n\t"
-             OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6)
-             "movd  %%mm2, %0           \n\t"
-             :"+m"(*block)
-             :"m"(*pixels)
-             :"memory");
-        pixels += line_size;
-        block += line_size;
-    }
-    while (--h);
-}
-
-// in case more speed is needed - unroling would certainly help
-static void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-             "movq  %0, %%mm0           \n\t"
-             "movq  %1, %%mm1           \n\t"
-             OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6)
-             "movq  %%mm2, %0           \n\t"
-             :"+m"(*block)
-             :"m"(*pixels)
-             :"memory");
-        pixels += line_size;
-        block += line_size;
-    }
-    while (--h);
-}
-
-static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-             "movq  %0, %%mm0           \n\t"
-             "movq  %1, %%mm1           \n\t"
-             OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6)
-             "movq  %%mm2, %0           \n\t"
-             "movq  8%0, %%mm0          \n\t"
-             "movq  8%1, %%mm1          \n\t"
-             OP_AVG(%%mm0, %%mm1, %%mm2, %%mm6)
-             "movq  %%mm2, 8%0          \n\t"
-             :"+m"(*block)
-             :"m"(*pixels)
-             :"memory");
-        pixels += line_size;
-        block += line_size;
-    }
-    while (--h);
-}
-
-static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-            "movq  %1, %%mm0            \n\t"
-            "movq  1%1, %%mm1           \n\t"
-            "movq  %0, %%mm3            \n\t"
-            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
-            "movq  %%mm0, %0            \n\t"
-            :"+m"(*block)
-            :"m"(*pixels)
-            :"memory");
-        pixels += line_size;
-        block += line_size;
-    } while (--h);
-}
-
-static av_unused void DEF(avg, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-            "movq  %1, %%mm0            \n\t"
-            "movq  %2, %%mm1            \n\t"
-            "movq  %0, %%mm3            \n\t"
-            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
-            "movq  %%mm0, %0            \n\t"
-            :"+m"(*dst)
-            :"m"(*src1), "m"(*src2)
-            :"memory");
-        dst += dstStride;
-        src1 += src1Stride;
-        src2 += 8;
-    } while (--h);
-}
-
-static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-            "movq  %1, %%mm0            \n\t"
-            "movq  1%1, %%mm1           \n\t"
-            "movq  %0, %%mm3            \n\t"
-            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
-            "movq  %%mm0, %0            \n\t"
-            "movq  8%1, %%mm0           \n\t"
-            "movq  9%1, %%mm1           \n\t"
-            "movq  8%0, %%mm3           \n\t"
-            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
-            "movq  %%mm0, 8%0           \n\t"
-            :"+m"(*block)
-            :"m"(*pixels)
-            :"memory");
-        pixels += line_size;
-        block += line_size;
-    } while (--h);
-}
-
-static av_unused void DEF(avg, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
-{
-    MOVQ_BFE(mm6);
-    JUMPALIGN();
-    do {
-        __asm__ volatile(
-            "movq  %1, %%mm0            \n\t"
-            "movq  %2, %%mm1            \n\t"
-            "movq  %0, %%mm3            \n\t"
-            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
-            "movq  %%mm0, %0            \n\t"
-            "movq  8%1, %%mm0           \n\t"
-            "movq  8%2, %%mm1           \n\t"
-            "movq  8%0, %%mm3           \n\t"
-            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
-            OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
-            "movq  %%mm0, 8%0           \n\t"
-            :"+m"(*dst)
-            :"m"(*src1), "m"(*src2)
-            :"memory");
-        dst += dstStride;
-        src1 += src1Stride;
-        src2 += 16;
-    } while (--h);
-}
-
-static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_BFE(mm6);
-    __asm__ volatile(
-        "lea    (%3, %3), %%"REG_a"     \n\t"
-        "movq   (%1), %%mm0             \n\t"
-        ".p2align 3                     \n\t"
-        "1:                             \n\t"
-        "movq   (%1, %3), %%mm1         \n\t"
-        "movq   (%1, %%"REG_a"), %%mm2  \n\t"
-        PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
-        "movq   (%2), %%mm3             \n\t"
-        OP_AVG(%%mm3, %%mm4, %%mm0, %%mm6)
-        "movq   (%2, %3), %%mm3         \n\t"
-        OP_AVG(%%mm3, %%mm5, %%mm1, %%mm6)
-        "movq   %%mm0, (%2)             \n\t"
-        "movq   %%mm1, (%2, %3)         \n\t"
-        "add    %%"REG_a", %1           \n\t"
-        "add    %%"REG_a", %2           \n\t"
-
-        "movq   (%1, %3), %%mm1         \n\t"
-        "movq   (%1, %%"REG_a"), %%mm0  \n\t"
-        PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
-        "movq   (%2), %%mm3             \n\t"
-        OP_AVG(%%mm3, %%mm4, %%mm2, %%mm6)
-        "movq   (%2, %3), %%mm3         \n\t"
-        OP_AVG(%%mm3, %%mm5, %%mm1, %%mm6)
-        "movq   %%mm2, (%2)             \n\t"
-        "movq   %%mm1, (%2, %3)         \n\t"
-        "add    %%"REG_a", %1           \n\t"
-        "add    %%"REG_a", %2           \n\t"
-
-        "subl   $4, %0                  \n\t"
-        "jnz    1b                      \n\t"
-        :"+g"(h), "+S"(pixels), "+D"(block)
-        :"r"((x86_reg)line_size)
-        :REG_a, "memory");
-}
-
-// this routine is 'slightly' suboptimal but mostly unused
-static void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
-{
-    MOVQ_ZERO(mm7);
-    SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
-    __asm__ volatile(
-        "movq   (%1), %%mm0             \n\t"
-        "movq   1(%1), %%mm4            \n\t"
-        "movq   %%mm0, %%mm1            \n\t"
-        "movq   %%mm4, %%mm5            \n\t"
-        "punpcklbw %%mm7, %%mm0         \n\t"
-        "punpcklbw %%mm7, %%mm4         \n\t"
-        "punpckhbw %%mm7, %%mm1         \n\t"
-        "punpckhbw %%mm7, %%mm5         \n\t"
-        "paddusw %%mm0, %%mm4           \n\t"
-        "paddusw %%mm1, %%mm5           \n\t"
-        "xor    %%"REG_a", %%"REG_a"    \n\t"
-        "add    %3, %1                  \n\t"
-        ".p2align 3                     \n\t"
-        "1:                             \n\t"
-        "movq   (%1, %%"REG_a"), %%mm0  \n\t"
-        "movq   1(%1, %%"REG_a"), %%mm2 \n\t"
-        "movq   %%mm0, %%mm1            \n\t"
-        "movq   %%mm2, %%mm3            \n\t"
-        "punpcklbw %%mm7, %%mm0         \n\t"
-        "punpcklbw %%mm7, %%mm2         \n\t"
-        "punpckhbw %%mm7, %%mm1         \n\t"
-        "punpckhbw %%mm7, %%mm3         \n\t"
-        "paddusw %%mm2, %%mm0           \n\t"
-        "paddusw %%mm3, %%mm1           \n\t"
-        "paddusw %%mm6, %%mm4           \n\t"
-        "paddusw %%mm6, %%mm5           \n\t"
-        "paddusw %%mm0, %%mm4           \n\t"
-        "paddusw %%mm1, %%mm5           \n\t"
-        "psrlw  $2, %%mm4               \n\t"
-        "psrlw  $2, %%mm5               \n\t"
-                "movq   (%2, %%"REG_a"), %%mm3  \n\t"
-        "packuswb  %%mm5, %%mm4         \n\t"
-                "pcmpeqd %%mm2, %%mm2   \n\t"
-                "paddb %%mm2, %%mm2     \n\t"
-                OP_AVG(%%mm3, %%mm4, %%mm5, %%mm2)
-                "movq   %%mm5, (%2, %%"REG_a")  \n\t"
-        "add    %3, %%"REG_a"                \n\t"
-
-        "movq   (%1, %%"REG_a"), %%mm2  \n\t" // 0 <-> 2   1 <-> 3
-        "movq   1(%1, %%"REG_a"), %%mm4 \n\t"
-        "movq   %%mm2, %%mm3            \n\t"
-        "movq   %%mm4, %%mm5            \n\t"
-        "punpcklbw %%mm7, %%mm2         \n\t"
-        "punpcklbw %%mm7, %%mm4         \n\t"
-        "punpckhbw %%mm7, %%mm3         \n\t"
-        "punpckhbw %%mm7, %%mm5         \n\t"
-        "paddusw %%mm2, %%mm4           \n\t"
-        "paddusw %%mm3, %%mm5           \n\t"
-        "paddusw %%mm6, %%mm0           \n\t"
-        "paddusw %%mm6, %%mm1           \n\t"
-        "paddusw %%mm4, %%mm0           \n\t"
-        "paddusw %%mm5, %%mm1           \n\t"
-        "psrlw  $2, %%mm0               \n\t"
-        "psrlw  $2, %%mm1               \n\t"
-                "movq   (%2, %%"REG_a"), %%mm3  \n\t"
-        "packuswb  %%mm1, %%mm0         \n\t"
-                "pcmpeqd %%mm2, %%mm2   \n\t"
-                "paddb %%mm2, %%mm2     \n\t"
-                OP_AVG(%%mm3, %%mm0, %%mm1, %%mm2)
-                "movq   %%mm1, (%2, %%"REG_a")  \n\t"
-        "add    %3, %%"REG_a"           \n\t"
-
-        "subl   $2, %0                  \n\t"
-        "jnz    1b                      \n\t"
-        :"+g"(h), "+S"(pixels)
-        :"D"(block), "r"((x86_reg)line_size)
-        :REG_a, "memory");
-}
-
-//FIXME optimize
-static void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(put, pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(put, pixels8_y2)(block+8, pixels+8, line_size, h);
-}
-
-static void DEF(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(put, pixels8_xy2)(block  , pixels  , line_size, h);
-    DEF(put, pixels8_xy2)(block+8, pixels+8, line_size, h);
-}
-
-static void DEF(avg, pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg, pixels8_y2)(block  , pixels  , line_size, h);
-    DEF(avg, pixels8_y2)(block+8, pixels+8, line_size, h);
-}
-
-static void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
-    DEF(avg, pixels8_xy2)(block  , pixels  , line_size, h);
-    DEF(avg, pixels8_xy2)(block+8, pixels+8, line_size, h);
-}
diff --git a/libavcodec/x86/dsputil_x86.c b/libavcodec/x86/dsputil_x86.c
new file mode 100644
index 0000000..144339b
--- /dev/null
+++ b/libavcodec/x86/dsputil_x86.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009 Loren Merritt <lorenm at u.washington.edu>
+ *
+ * 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 "libavutil/x86/asm.h"
+#include "dsputil_x86.h"
+
+#if HAVE_INLINE_ASM
+
+#if HAVE_7REGS
+void ff_add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top,
+                                        const uint8_t *diff, int w,
+                                        int *left, int *left_top)
+{
+    x86_reg w2 = -w;
+    x86_reg x;
+    int l  = *left     & 0xff;
+    int tl = *left_top & 0xff;
+    int t;
+    __asm__ volatile (
+        "mov          %7, %3            \n"
+        "1:                             \n"
+        "movzbl (%3, %4), %2            \n"
+        "mov          %2, %k3           \n"
+        "sub         %b1, %b3           \n"
+        "add         %b0, %b3           \n"
+        "mov          %2, %1            \n"
+        "cmp          %0, %2            \n"
+        "cmovg        %0, %2            \n"
+        "cmovg        %1, %0            \n"
+        "cmp         %k3, %0            \n"
+        "cmovg       %k3, %0            \n"
+        "mov          %7, %3            \n"
+        "cmp          %2, %0            \n"
+        "cmovl        %2, %0            \n"
+        "add    (%6, %4), %b0           \n"
+        "mov         %b0, (%5, %4)      \n"
+        "inc          %4                \n"
+        "jl           1b                \n"
+        : "+&q"(l), "+&q"(tl), "=&r"(t), "=&q"(x), "+&r"(w2)
+        : "r"(dst + w), "r"(diff + w), "rm"(top + w)
+    );
+    *left     = l;
+    *left_top = tl;
+}
+#endif
+
+#endif /* HAVE_INLINE_ASM */
diff --git a/libavcodec/x86/dsputil_x86.h b/libavcodec/x86/dsputil_x86.h
new file mode 100644
index 0000000..c8615b2
--- /dev/null
+++ b/libavcodec/x86/dsputil_x86.h
@@ -0,0 +1,189 @@
+/*
+ * MMX optimized DSP utils
+ * Copyright (c) 2007  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * 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_X86_DSPUTIL_MMX_H
+#define AVCODEC_X86_DSPUTIL_MMX_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "libavcodec/dsputil.h"
+#include "libavutil/x86/asm.h"
+#include "constants.h"
+
+#define MOVQ_WONE(regd) \
+    __asm__ volatile ( \
+    "pcmpeqd %%" #regd ", %%" #regd " \n\t" \
+    "psrlw $15, %%" #regd ::)
+
+#define JUMPALIGN()     __asm__ volatile (".p2align 3"::)
+#define MOVQ_ZERO(regd) __asm__ volatile ("pxor %%"#regd", %%"#regd ::)
+
+#define MOVQ_BFE(regd)                                  \
+    __asm__ volatile (                                  \
+        "pcmpeqd %%"#regd", %%"#regd"   \n\t"           \
+        "paddb   %%"#regd", %%"#regd"   \n\t" ::)
+
+#ifndef PIC
+#define MOVQ_WTWO(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_wtwo))
+#else
+// for shared library it's better to use this way for accessing constants
+// pcmpeqd -> -1
+#define MOVQ_WTWO(regd)                                 \
+    __asm__ volatile (                                  \
+        "pcmpeqd %%"#regd", %%"#regd"   \n\t"           \
+        "psrlw         $15, %%"#regd"   \n\t"           \
+        "psllw          $1, %%"#regd"   \n\t"::)
+
+#endif
+
+// using regr as temporary and for the output result
+// first argument is unmodifed and second is trashed
+// regfe is supposed to contain 0xfefefefefefefefe
+#define PAVGB_MMX_NO_RND(rega, regb, regr, regfe)                \
+    "movq   "#rega", "#regr"            \n\t"                    \
+    "pand   "#regb", "#regr"            \n\t"                    \
+    "pxor   "#rega", "#regb"            \n\t"                    \
+    "pand  "#regfe", "#regb"            \n\t"                    \
+    "psrlq       $1, "#regb"            \n\t"                    \
+    "paddb  "#regb", "#regr"            \n\t"
+
+#define PAVGB_MMX(rega, regb, regr, regfe)                       \
+    "movq   "#rega", "#regr"            \n\t"                    \
+    "por    "#regb", "#regr"            \n\t"                    \
+    "pxor   "#rega", "#regb"            \n\t"                    \
+    "pand  "#regfe", "#regb"            \n\t"                    \
+    "psrlq       $1, "#regb"            \n\t"                    \
+    "psubb  "#regb", "#regr"            \n\t"
+
+// mm6 is supposed to contain 0xfefefefefefefefe
+#define PAVGBP_MMX_NO_RND(rega, regb, regr,  regc, regd, regp)   \
+    "movq  "#rega", "#regr"             \n\t"                    \
+    "movq  "#regc", "#regp"             \n\t"                    \
+    "pand  "#regb", "#regr"             \n\t"                    \
+    "pand  "#regd", "#regp"             \n\t"                    \
+    "pxor  "#rega", "#regb"             \n\t"                    \
+    "pxor  "#regc", "#regd"             \n\t"                    \
+    "pand    %%mm6, "#regb"             \n\t"                    \
+    "pand    %%mm6, "#regd"             \n\t"                    \
+    "psrlq      $1, "#regb"             \n\t"                    \
+    "psrlq      $1, "#regd"             \n\t"                    \
+    "paddb "#regb", "#regr"             \n\t"                    \
+    "paddb "#regd", "#regp"             \n\t"
+
+#define PAVGBP_MMX(rega, regb, regr, regc, regd, regp)           \
+    "movq  "#rega", "#regr"             \n\t"                    \
+    "movq  "#regc", "#regp"             \n\t"                    \
+    "por   "#regb", "#regr"             \n\t"                    \
+    "por   "#regd", "#regp"             \n\t"                    \
+    "pxor  "#rega", "#regb"             \n\t"                    \
+    "pxor  "#regc", "#regd"             \n\t"                    \
+    "pand    %%mm6, "#regb"             \n\t"                    \
+    "pand    %%mm6, "#regd"             \n\t"                    \
+    "psrlq      $1, "#regd"             \n\t"                    \
+    "psrlq      $1, "#regb"             \n\t"                    \
+    "psubb "#regb", "#regr"             \n\t"                    \
+    "psubb "#regd", "#regp"             \n\t"
+
+void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx);
+void ff_dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx);
+
+void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size);
+void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size);
+void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, int line_size);
+
+void ff_clear_block_mmx(int16_t *block);
+void ff_clear_block_sse(int16_t *block);
+void ff_clear_blocks_mmx(int16_t *blocks);
+void ff_clear_blocks_sse(int16_t *blocks);
+
+void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, int w);
+
+void ff_add_hfyu_median_prediction_cmov(uint8_t *dst, const uint8_t *top,
+                                        const uint8_t *diff, int w,
+                                        int *left, int *left_top);
+
+void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
+                       int w, int h, int sides);
+
+void ff_gmc_mmx(uint8_t *dst, uint8_t *src,
+                int stride, int h, int ox, int oy,
+                int dxx, int dxy, int dyx, int dyy,
+                int shift, int r, int width, int height);
+
+void ff_vector_clipf_sse(float *dst, const float *src,
+                         float min, float max, int len);
+
+void ff_avg_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
+                        ptrdiff_t line_size, int h);
+void ff_avg_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
+                         ptrdiff_t line_size, int h);
+void ff_put_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
+                        ptrdiff_t line_size, int h);
+void ff_put_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
+                         ptrdiff_t line_size, int h);
+void ff_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h);
+void ff_put_pixels8_mmxext(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h);
+void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels,
+                          ptrdiff_t line_size, int h);
+void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels,
+                          ptrdiff_t line_size, int h);
+
+void ff_avg_pixels8_x2_mmx(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h);
+
+void ff_avg_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels,
+                            ptrdiff_t line_size, int h);
+void ff_avg_pixels16_xy2_mmx(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+
+void ff_put_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels,
+                            ptrdiff_t line_size, int h);
+void ff_put_pixels16_xy2_mmx(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+
+void ff_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,
+                             const uint8_t *lum,
+                             int size);
+
+void ff_deinterlace_line_inplace_mmx(const uint8_t *lum_m4,
+                                     const uint8_t *lum_m3,
+                                     const uint8_t *lum_m2,
+                                     const uint8_t *lum_m1,
+                                     const uint8_t *lum, int size);
+
+#define PIXELS16(STATIC, PFX1, PFX2, TYPE, CPUEXT)                      \
+STATIC void PFX1 ## _pixels16 ## TYPE ## CPUEXT(uint8_t *block,         \
+                                                const uint8_t *pixels,  \
+                                                ptrdiff_t line_size,    \
+                                                int h)                  \
+{                                                                       \
+    PFX2 ## PFX1 ## _pixels8 ## TYPE ## CPUEXT(block,      pixels,      \
+                                               line_size, h);           \
+    PFX2 ## PFX1 ## _pixels8 ## TYPE ## CPUEXT(block + 8,  pixels + 8,  \
+                                               line_size, h);           \
+}
+
+#endif /* AVCODEC_X86_DSPUTIL_MMX_H */
diff --git a/libavcodec/x86/dsputilenc.asm b/libavcodec/x86/dsputilenc.asm
index 104ec58..7e4fd81 100644
--- a/libavcodec/x86/dsputilenc.asm
+++ b/libavcodec/x86/dsputilenc.asm
@@ -257,15 +257,12 @@ hadamard8_16_wrapper 0, 14
 %endmacro
 
 INIT_MMX mmx
-%define ABS1 ABS1_MMX
 HADAMARD8_DIFF
 
 INIT_MMX mmxext
-%define ABS1 ABS1_MMXEXT
 HADAMARD8_DIFF
 
 INIT_XMM sse2
-%define ABS2 ABS2_MMXEXT
 %if ARCH_X86_64
 %define ABS_SUM_8x8 ABS_SUM_8x8_64
 %else
@@ -274,7 +271,6 @@ INIT_XMM sse2
 HADAMARD8_DIFF 10
 
 INIT_XMM ssse3
-%define ABS2        ABS2_SSSE3
 %define ABS_SUM_8x8 ABS_SUM_8x8_64
 HADAMARD8_DIFF 9
 
@@ -337,3 +333,155 @@ cglobal sse16, 5, 5, 8
     paddd     m7, m1
     movd     eax, m7         ; return value
     RET
+
+INIT_MMX mmx
+; get_pixels_mmx(int16_t *block, const uint8_t *pixels, int line_size)
+cglobal get_pixels, 3,4
+    movsxdifnidn r2, r2d
+    add          r0, 128
+    mov          r3, -128
+    pxor         m7, m7
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    mova         m1, m0
+    mova         m3, m2
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    mova [r0+r3+ 0], m0
+    mova [r0+r3+ 8], m1
+    mova [r0+r3+16], m2
+    mova [r0+r3+24], m3
+    lea          r1, [r1+r2*2]
+    add          r3, 32
+    js .loop
+    REP_RET
+
+INIT_XMM sse2
+cglobal get_pixels, 3, 4
+    movsxdifnidn r2, r2d
+    lea          r3, [r2*3]
+    pxor         m4, m4
+    movh         m0, [r1]
+    movh         m1, [r1+r2]
+    movh         m2, [r1+r2*2]
+    movh         m3, [r1+r3]
+    lea          r1, [r1+r2*4]
+    punpcklbw    m0, m4
+    punpcklbw    m1, m4
+    punpcklbw    m2, m4
+    punpcklbw    m3, m4
+    mova       [r0], m0
+    mova  [r0+0x10], m1
+    mova  [r0+0x20], m2
+    mova  [r0+0x30], m3
+    movh         m0, [r1]
+    movh         m1, [r1+r2*1]
+    movh         m2, [r1+r2*2]
+    movh         m3, [r1+r3]
+    punpcklbw    m0, m4
+    punpcklbw    m1, m4
+    punpcklbw    m2, m4
+    punpcklbw    m3, m4
+    mova  [r0+0x40], m0
+    mova  [r0+0x50], m1
+    mova  [r0+0x60], m2
+    mova  [r0+0x70], m3
+    RET
+
+INIT_MMX mmx
+; diff_pixels_mmx(int16_t *block, const uint8_t *s1, const unint8_t *s2, stride)
+cglobal diff_pixels, 4,5
+    movsxdifnidn r3, r3d
+    pxor         m7, m7
+    add          r0,  128
+    mov          r4, -128
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r2]
+    mova         m1, m0
+    mova         m3, m2
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    psubw        m0, m2
+    psubw        m1, m3
+    mova  [r0+r4+0], m0
+    mova  [r0+r4+8], m1
+    add          r1, r3
+    add          r2, r3
+    add          r4, 16
+    jne .loop
+    REP_RET
+
+INIT_MMX mmx
+; pix_sum16_mmx(uint8_t * pix, int line_size)
+cglobal pix_sum16, 2, 3
+    movsxdifnidn r1, r1d
+    mov          r2, r1
+    neg          r2
+    shl          r2, 4
+    sub          r0, r2
+    pxor         m7, m7
+    pxor         m6, m6
+.loop:
+    mova         m0, [r0+r2+0]
+    mova         m1, [r0+r2+0]
+    mova         m2, [r0+r2+8]
+    mova         m3, [r0+r2+8]
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    paddw        m1, m0
+    paddw        m3, m2
+    paddw        m3, m1
+    paddw        m6, m3
+    add          r2, r1
+    js .loop
+    mova         m5, m6
+    psrlq        m6, 32
+    paddw        m6, m5
+    mova         m5, m6
+    psrlq        m6, 16
+    paddw        m6, m5
+    movd        eax, m6
+    and         eax, 0xffff
+    RET
+
+INIT_MMX mmx
+; pix_norm1_mmx(uint8_t *pix, int line_size)
+cglobal pix_norm1, 2, 4
+    movsxdifnidn r1, r1d
+    mov          r2, 16
+    pxor         m0, m0
+    pxor         m7, m7
+.loop:
+    mova         m2, [r0+0]
+    mova         m3, [r0+8]
+    mova         m1, m2
+    punpckhbw    m1, m0
+    punpcklbw    m2, m0
+    mova         m4, m3
+    punpckhbw    m3, m0
+    punpcklbw    m4, m0
+    pmaddwd      m1, m1
+    pmaddwd      m2, m2
+    pmaddwd      m3, m3
+    pmaddwd      m4, m4
+    paddd        m2, m1
+    paddd        m4, m3
+    paddd        m7, m2
+    add          r0, r1
+    paddd        m7, m4
+    dec r2
+    jne .loop
+    mova         m1, m7
+    psrlq        m7, 32
+    paddd        m1, m7
+    movd        eax, m1
+    RET
+
diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c
index e5d2473..a1f80af 100644
--- a/libavcodec/x86/dsputilenc_mmx.c
+++ b/libavcodec/x86/dsputilenc_mmx.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
  *
+ * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -18,193 +20,26 @@
  * 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
- *
- * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
+#include "libavcodec/dct.h"
 #include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
 #include "libavcodec/mathops.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
+void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, int line_size);
+void ff_get_pixels_sse2(int16_t *block, const uint8_t *pixels, int line_size);
+void ff_diff_pixels_mmx(int16_t *block, const uint8_t *s1, const uint8_t *s2, int stride);
+int ff_pix_sum16_mmx(uint8_t * pix, int line_size);
+int ff_pix_norm1_mmx(uint8_t *pix, int line_size);
 
 #if HAVE_INLINE_ASM
 
-static void get_pixels_mmx(DCTELEM *block, const uint8_t *pixels, int line_size)
-{
-    __asm__ volatile(
-        "mov $-128, %%"REG_a"           \n\t"
-        "pxor %%mm7, %%mm7              \n\t"
-        ".p2align 4                     \n\t"
-        "1:                             \n\t"
-        "movq (%0), %%mm0               \n\t"
-        "movq (%0, %2), %%mm2           \n\t"
-        "movq %%mm0, %%mm1              \n\t"
-        "movq %%mm2, %%mm3              \n\t"
-        "punpcklbw %%mm7, %%mm0         \n\t"
-        "punpckhbw %%mm7, %%mm1         \n\t"
-        "punpcklbw %%mm7, %%mm2         \n\t"
-        "punpckhbw %%mm7, %%mm3         \n\t"
-        "movq %%mm0, (%1, %%"REG_a")    \n\t"
-        "movq %%mm1, 8(%1, %%"REG_a")   \n\t"
-        "movq %%mm2, 16(%1, %%"REG_a")  \n\t"
-        "movq %%mm3, 24(%1, %%"REG_a")  \n\t"
-        "add %3, %0                     \n\t"
-        "add $32, %%"REG_a"             \n\t"
-        "js 1b                          \n\t"
-        : "+r" (pixels)
-        : "r" (block+64), "r" ((x86_reg)line_size), "r" ((x86_reg)line_size*2)
-        : "%"REG_a
-    );
-}
-
-static void get_pixels_sse2(DCTELEM *block, const uint8_t *pixels, int line_size)
-{
-    __asm__ volatile(
-        "pxor %%xmm4,      %%xmm4         \n\t"
-        "movq (%0),        %%xmm0         \n\t"
-        "movq (%0, %2),    %%xmm1         \n\t"
-        "movq (%0, %2,2),  %%xmm2         \n\t"
-        "movq (%0, %3),    %%xmm3         \n\t"
-        "lea (%0,%2,4), %0                \n\t"
-        "punpcklbw %%xmm4, %%xmm0         \n\t"
-        "punpcklbw %%xmm4, %%xmm1         \n\t"
-        "punpcklbw %%xmm4, %%xmm2         \n\t"
-        "punpcklbw %%xmm4, %%xmm3         \n\t"
-        "movdqa %%xmm0,      (%1)         \n\t"
-        "movdqa %%xmm1,    16(%1)         \n\t"
-        "movdqa %%xmm2,    32(%1)         \n\t"
-        "movdqa %%xmm3,    48(%1)         \n\t"
-        "movq (%0),        %%xmm0         \n\t"
-        "movq (%0, %2),    %%xmm1         \n\t"
-        "movq (%0, %2,2),  %%xmm2         \n\t"
-        "movq (%0, %3),    %%xmm3         \n\t"
-        "punpcklbw %%xmm4, %%xmm0         \n\t"
-        "punpcklbw %%xmm4, %%xmm1         \n\t"
-        "punpcklbw %%xmm4, %%xmm2         \n\t"
-        "punpcklbw %%xmm4, %%xmm3         \n\t"
-        "movdqa %%xmm0,    64(%1)         \n\t"
-        "movdqa %%xmm1,    80(%1)         \n\t"
-        "movdqa %%xmm2,    96(%1)         \n\t"
-        "movdqa %%xmm3,   112(%1)         \n\t"
-        : "+r" (pixels)
-        : "r" (block), "r" ((x86_reg)line_size), "r" ((x86_reg)line_size*3)
-    );
-}
-
-static inline void diff_pixels_mmx(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride)
-{
-    __asm__ volatile(
-        "pxor %%mm7, %%mm7              \n\t"
-        "mov $-128, %%"REG_a"           \n\t"
-        ".p2align 4                     \n\t"
-        "1:                             \n\t"
-        "movq (%0), %%mm0               \n\t"
-        "movq (%1), %%mm2               \n\t"
-        "movq %%mm0, %%mm1              \n\t"
-        "movq %%mm2, %%mm3              \n\t"
-        "punpcklbw %%mm7, %%mm0         \n\t"
-        "punpckhbw %%mm7, %%mm1         \n\t"
-        "punpcklbw %%mm7, %%mm2         \n\t"
-        "punpckhbw %%mm7, %%mm3         \n\t"
-        "psubw %%mm2, %%mm0             \n\t"
-        "psubw %%mm3, %%mm1             \n\t"
-        "movq %%mm0, (%2, %%"REG_a")    \n\t"
-        "movq %%mm1, 8(%2, %%"REG_a")   \n\t"
-        "add %3, %0                     \n\t"
-        "add %3, %1                     \n\t"
-        "add $16, %%"REG_a"             \n\t"
-        "jnz 1b                         \n\t"
-        : "+r" (s1), "+r" (s2)
-        : "r" (block+64), "r" ((x86_reg)stride)
-        : "%"REG_a
-    );
-}
-
-static int pix_sum16_mmx(uint8_t * pix, int line_size){
-    const int h=16;
-    int sum;
-    x86_reg index= -line_size*h;
-
-    __asm__ volatile(
-                "pxor %%mm7, %%mm7              \n\t"
-                "pxor %%mm6, %%mm6              \n\t"
-                "1:                             \n\t"
-                "movq (%2, %1), %%mm0           \n\t"
-                "movq (%2, %1), %%mm1           \n\t"
-                "movq 8(%2, %1), %%mm2          \n\t"
-                "movq 8(%2, %1), %%mm3          \n\t"
-                "punpcklbw %%mm7, %%mm0         \n\t"
-                "punpckhbw %%mm7, %%mm1         \n\t"
-                "punpcklbw %%mm7, %%mm2         \n\t"
-                "punpckhbw %%mm7, %%mm3         \n\t"
-                "paddw %%mm0, %%mm1             \n\t"
-                "paddw %%mm2, %%mm3             \n\t"
-                "paddw %%mm1, %%mm3             \n\t"
-                "paddw %%mm3, %%mm6             \n\t"
-                "add %3, %1                     \n\t"
-                " js 1b                         \n\t"
-                "movq %%mm6, %%mm5              \n\t"
-                "psrlq $32, %%mm6               \n\t"
-                "paddw %%mm5, %%mm6             \n\t"
-                "movq %%mm6, %%mm5              \n\t"
-                "psrlq $16, %%mm6               \n\t"
-                "paddw %%mm5, %%mm6             \n\t"
-                "movd %%mm6, %0                 \n\t"
-                "andl $0xFFFF, %0               \n\t"
-                : "=&r" (sum), "+r" (index)
-                : "r" (pix - index), "r" ((x86_reg)line_size)
-        );
-
-        return sum;
-}
-
-static int pix_norm1_mmx(uint8_t *pix, int line_size) {
-    int tmp;
-  __asm__ volatile (
-      "movl $16,%%ecx\n"
-      "pxor %%mm0,%%mm0\n"
-      "pxor %%mm7,%%mm7\n"
-      "1:\n"
-      "movq (%0),%%mm2\n"       /* mm2 = pix[0-7] */
-      "movq 8(%0),%%mm3\n"      /* mm3 = pix[8-15] */
-
-      "movq %%mm2,%%mm1\n"      /* mm1 = mm2 = pix[0-7] */
-
-      "punpckhbw %%mm0,%%mm1\n" /* mm1 = [pix4-7] */
-      "punpcklbw %%mm0,%%mm2\n" /* mm2 = [pix0-3] */
-
-      "movq %%mm3,%%mm4\n"      /* mm4 = mm3 = pix[8-15] */
-      "punpckhbw %%mm0,%%mm3\n" /* mm3 = [pix12-15] */
-      "punpcklbw %%mm0,%%mm4\n" /* mm4 = [pix8-11] */
-
-      "pmaddwd %%mm1,%%mm1\n"   /* mm1 = (pix0^2+pix1^2,pix2^2+pix3^2) */
-      "pmaddwd %%mm2,%%mm2\n"   /* mm2 = (pix4^2+pix5^2,pix6^2+pix7^2) */
-
-      "pmaddwd %%mm3,%%mm3\n"
-      "pmaddwd %%mm4,%%mm4\n"
-
-      "paddd %%mm1,%%mm2\n"     /* mm2 = (pix0^2+pix1^2+pix4^2+pix5^2,
-                                          pix2^2+pix3^2+pix6^2+pix7^2) */
-      "paddd %%mm3,%%mm4\n"
-      "paddd %%mm2,%%mm7\n"
-
-      "add %2, %0\n"
-      "paddd %%mm4,%%mm7\n"
-      "dec %%ecx\n"
-      "jnz 1b\n"
-
-      "movq %%mm7,%%mm1\n"
-      "psrlq $32, %%mm7\n"      /* shift hi dword to lo */
-      "paddd %%mm7,%%mm1\n"
-      "movd %%mm1,%1\n"
-      : "+r" (pix), "=r"(tmp) : "r" ((x86_reg)line_size) : "%ecx" );
-    return tmp;
-}
-
 static int sse8_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) {
     int tmp;
   __asm__ volatile (
@@ -964,7 +799,7 @@ static void sub_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *src1,
     HSUM(%%xmm0, %%xmm1, %0)
 
 #define DCT_SAD_FUNC(cpu) \
-static int sum_abs_dctelem_##cpu(DCTELEM *block){\
+static int sum_abs_dctelem_##cpu(int16_t *block){\
     int sum;\
     __asm__ volatile(\
         DCT_SAD\
@@ -1108,35 +943,36 @@ hadamard_func(mmxext)
 hadamard_func(sse2)
 hadamard_func(ssse3)
 
-void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputilenc_init_mmx(DSPContext *c, AVCodecContext *avctx)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
+    const int dct_algo = avctx->dct_algo;
 
-#if HAVE_INLINE_ASM
+#if HAVE_YASM
     int bit_depth = avctx->bits_per_raw_sample;
 
-    if (mm_flags & AV_CPU_FLAG_MMX) {
-        const int dct_algo = avctx->dct_algo;
-        if (avctx->bits_per_raw_sample <= 8 &&
-            (dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX)) {
-            if(mm_flags & AV_CPU_FLAG_SSE2){
-                c->fdct = ff_fdct_sse2;
-            } else if (mm_flags & AV_CPU_FLAG_MMXEXT) {
-                c->fdct = ff_fdct_mmxext;
-            }else{
-                c->fdct = ff_fdct_mmx;
-            }
-        }
+    if (EXTERNAL_MMX(cpu_flags)) {
+        if (bit_depth <= 8)
+            c->get_pixels = ff_get_pixels_mmx;
+        c->diff_pixels = ff_diff_pixels_mmx;
+        c->pix_sum = ff_pix_sum16_mmx;
 
+        c->pix_norm1 = ff_pix_norm1_mmx;
+    }
+    if (EXTERNAL_SSE2(cpu_flags))
         if (bit_depth <= 8)
-            c->get_pixels = get_pixels_mmx;
-        c->diff_pixels = diff_pixels_mmx;
-        c->pix_sum = pix_sum16_mmx;
+            c->get_pixels = ff_get_pixels_sse2;
+#endif /* HAVE_YASM */
+
+#if HAVE_INLINE_ASM
+    if (INLINE_MMX(cpu_flags)) {
+        if (avctx->bits_per_raw_sample <= 8 &&
+            (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX))
+            c->fdct = ff_fdct_mmx;
 
         c->diff_bytes= diff_bytes_mmx;
         c->sum_abs_dctelem= sum_abs_dctelem_mmx;
 
-        c->pix_norm1 = pix_norm1_mmx;
         c->sse[0] = sse16_mmx;
         c->sse[1] = sse8_mmx;
         c->vsad[4]= vsad_intra16_mmx;
@@ -1153,65 +989,71 @@ void ff_dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
         c->add_8x8basis= add_8x8basis_mmx;
 
         c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx;
+    }
+
+    if (INLINE_AMD3DNOW(cpu_flags)) {
+        if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
+            c->try_8x8basis = try_8x8basis_3dnow;
+        }
+        c->add_8x8basis = add_8x8basis_3dnow;
+    }
 
-        if (mm_flags & AV_CPU_FLAG_MMXEXT) {
-            c->sum_abs_dctelem = sum_abs_dctelem_mmxext;
-            c->vsad[4]         = vsad_intra16_mmxext;
+    if (INLINE_MMXEXT(cpu_flags)) {
+        if (avctx->bits_per_raw_sample <= 8 &&
+            (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX))
+            c->fdct = ff_fdct_mmxext;
 
-            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
-                c->vsad[0] = vsad16_mmxext;
-            }
+        c->sum_abs_dctelem = sum_abs_dctelem_mmxext;
+        c->vsad[4]         = vsad_intra16_mmxext;
 
-            c->sub_hfyu_median_prediction = sub_hfyu_median_prediction_mmxext;
+        if (!(avctx->flags & CODEC_FLAG_BITEXACT)){
+            c->vsad[0] = vsad16_mmxext;
         }
 
-        if(mm_flags & AV_CPU_FLAG_SSE2){
-            if (bit_depth <= 8)
-                c->get_pixels = get_pixels_sse2;
-            c->sum_abs_dctelem= sum_abs_dctelem_sse2;
-        }
+        c->sub_hfyu_median_prediction = sub_hfyu_median_prediction_mmxext;
+    }
 
-#if HAVE_SSSE3_INLINE
-        if(mm_flags & AV_CPU_FLAG_SSSE3){
-            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
-                c->try_8x8basis= try_8x8basis_ssse3;
-            }
-            c->add_8x8basis= add_8x8basis_ssse3;
-            c->sum_abs_dctelem= sum_abs_dctelem_ssse3;
-        }
-#endif
+    if (INLINE_SSE2(cpu_flags)) {
+        if (avctx->bits_per_raw_sample <= 8 &&
+            (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX))
+            c->fdct = ff_fdct_sse2;
 
-        if(mm_flags & AV_CPU_FLAG_3DNOW){
-            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
-                c->try_8x8basis= try_8x8basis_3dnow;
-            }
-            c->add_8x8basis= add_8x8basis_3dnow;
+        c->sum_abs_dctelem= sum_abs_dctelem_sse2;
+    }
+
+#if HAVE_SSSE3_INLINE
+    if (INLINE_SSSE3(cpu_flags)) {
+        if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
+            c->try_8x8basis = try_8x8basis_ssse3;
         }
+        c->add_8x8basis    = add_8x8basis_ssse3;
+        c->sum_abs_dctelem = sum_abs_dctelem_ssse3;
     }
+#endif
 #endif /* HAVE_INLINE_ASM */
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->hadamard8_diff[0] = ff_hadamard8_diff16_mmx;
         c->hadamard8_diff[1] = ff_hadamard8_diff_mmx;
+    }
 
-        if (EXTERNAL_MMXEXT(mm_flags)) {
-            c->hadamard8_diff[0] = ff_hadamard8_diff16_mmxext;
-            c->hadamard8_diff[1] = ff_hadamard8_diff_mmxext;
-        }
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
+        c->hadamard8_diff[0] = ff_hadamard8_diff16_mmxext;
+        c->hadamard8_diff[1] = ff_hadamard8_diff_mmxext;
+    }
 
-        if (EXTERNAL_SSE2(mm_flags)) {
-            c->sse[0] = ff_sse16_sse2;
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        c->sse[0] = ff_sse16_sse2;
 
 #if HAVE_ALIGNED_STACK
-            c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2;
-            c->hadamard8_diff[1] = ff_hadamard8_diff_sse2;
+        c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2;
+        c->hadamard8_diff[1] = ff_hadamard8_diff_sse2;
 #endif
-        }
+    }
 
-        if (EXTERNAL_SSSE3(mm_flags) && HAVE_ALIGNED_STACK) {
-            c->hadamard8_diff[0] = ff_hadamard8_diff16_ssse3;
-            c->hadamard8_diff[1] = ff_hadamard8_diff_ssse3;
-        }
+    if (EXTERNAL_SSSE3(cpu_flags) && HAVE_ALIGNED_STACK) {
+        c->hadamard8_diff[0] = ff_hadamard8_diff16_ssse3;
+        c->hadamard8_diff[1] = ff_hadamard8_diff_ssse3;
     }
 
     ff_dsputil_init_pix_mmx(c, avctx);
diff --git a/libavcodec/x86/fdct.c b/libavcodec/x86/fdct.c
index b37238d..6d595aa 100644
--- a/libavcodec/x86/fdct.c
+++ b/libavcodec/x86/fdct.c
@@ -32,9 +32,9 @@
 
 #include "libavutil/common.h"
 #include "libavutil/x86/asm.h"
-#include "libavcodec/dsputil.h"
+#include "libavcodec/dct.h"
 
-#if HAVE_INLINE_ASM
+#if HAVE_MMX_INLINE
 
 //////////////////////////////////////////////////////////////////////
 //
@@ -556,6 +556,10 @@ void ff_fdct_mmx(int16_t *block)
     }
 }
 
+#endif /* HAVE_MMX_INLINE */
+
+#if HAVE_MMXEXT_INLINE
+
 void ff_fdct_mmxext(int16_t *block)
 {
     DECLARE_ALIGNED(8, int64_t, align_tmp)[16];
@@ -574,6 +578,10 @@ void ff_fdct_mmxext(int16_t *block)
     }
 }
 
+#endif /* HAVE_MMXEXT_INLINE */
+
+#if HAVE_SSE2_INLINE
+
 void ff_fdct_sse2(int16_t *block)
 {
     DECLARE_ALIGNED(16, int64_t, align_tmp)[16];
@@ -583,4 +591,4 @@ void ff_fdct_sse2(int16_t *block)
     fdct_row_sse2(block1, block);
 }
 
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_SSE2_INLINE */
diff --git a/libavcodec/x86/fft.asm b/libavcodec/x86/fft.asm
index c87752b..e4744a3 100644
--- a/libavcodec/x86/fft.asm
+++ b/libavcodec/x86/fft.asm
@@ -667,13 +667,13 @@ cglobal imdct_calc, 3,5,3
     push    r1
     push    r0
 %else
-    sub     rsp, 8
+    sub     rsp, 8+32*WIN64 ; allocate win64 shadow space
 %endif
     call    r4
 %if ARCH_X86_32
     add     esp, 12
 %else
-    add     rsp, 8
+    add     rsp, 8+32*WIN64
 %endif
     POP     r1
     POP     r3
diff --git a/libavcodec/x86/fft.h b/libavcodec/x86/fft.h
index 6e80b95..a604956 100644
--- a/libavcodec/x86/fft.h
+++ b/libavcodec/x86/fft.h
@@ -34,8 +34,5 @@ void ff_imdct_half_3dnowext(FFTContext *s, FFTSample *output, const FFTSample *i
 void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input);
 void ff_imdct_half_avx(FFTContext *s, FFTSample *output, const FFTSample *input);
-void ff_dct32_float_sse(FFTSample *out, const FFTSample *in);
-void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in);
-void ff_dct32_float_avx(FFTSample *out, const FFTSample *in);
 
 #endif /* AVCODEC_X86_FFT_H */
diff --git a/libavcodec/x86/fft_init.c b/libavcodec/x86/fft_init.c
index 5554b24..7ca72c5 100644
--- a/libavcodec/x86/fft_init.c
+++ b/libavcodec/x86/fft_init.c
@@ -16,30 +16,31 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
-#include "libavcodec/dct.h"
 #include "fft.h"
 
 av_cold void ff_fft_init_x86(FFTContext *s)
 {
-    int has_vectors = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
+
 #if ARCH_X86_32
-    if (EXTERNAL_AMD3DNOW(has_vectors)) {
+    if (EXTERNAL_AMD3DNOW(cpu_flags)) {
         /* 3DNow! for K6-2/3 */
         s->imdct_calc = ff_imdct_calc_3dnow;
         s->imdct_half = ff_imdct_half_3dnow;
         s->fft_calc   = ff_fft_calc_3dnow;
     }
-    if (EXTERNAL_AMD3DNOWEXT(has_vectors)) {
+    if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) {
         /* 3DNowEx for K7 */
         s->imdct_calc = ff_imdct_calc_3dnowext;
         s->imdct_half = ff_imdct_half_3dnowext;
         s->fft_calc   = ff_fft_calc_3dnowext;
     }
 #endif
-    if (EXTERNAL_SSE(has_vectors)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         /* SSE for P3/P4/K8 */
         s->imdct_calc  = ff_imdct_calc_sse;
         s->imdct_half  = ff_imdct_half_sse;
@@ -47,23 +48,10 @@ av_cold void ff_fft_init_x86(FFTContext *s)
         s->fft_calc    = ff_fft_calc_sse;
         s->fft_permutation = FF_FFT_PERM_SWAP_LSBS;
     }
-    if (EXTERNAL_AVX(has_vectors) && s->nbits >= 5) {
+    if (EXTERNAL_AVX(cpu_flags) && s->nbits >= 5) {
         /* AVX for SB */
         s->imdct_half      = ff_imdct_half_avx;
         s->fft_calc        = ff_fft_calc_avx;
         s->fft_permutation = FF_FFT_PERM_AVX;
     }
 }
-
-#if CONFIG_DCT
-av_cold void ff_dct_init_x86(DCTContext *s)
-{
-    int has_vectors = av_get_cpu_flags();
-    if (EXTERNAL_SSE(has_vectors))
-        s->dct32 = ff_dct32_float_sse;
-    if (EXTERNAL_SSE2(has_vectors))
-        s->dct32 = ff_dct32_float_sse2;
-    if (EXTERNAL_AVX(has_vectors))
-        s->dct32 = ff_dct32_float_avx;
-}
-#endif
diff --git a/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm
index 8267bd4..e7803df 100644
--- a/libavcodec/x86/fmtconvert.asm
+++ b/libavcodec/x86/fmtconvert.asm
@@ -32,7 +32,7 @@ SECTION_TEXT
 %endmacro
 
 ;---------------------------------------------------------------------------------
-; void int32_to_float_fmul_scalar(float *dst, const int *src, float mul, int len);
+; void int32_to_float_fmul_scalar(float *dst, const int32_t *src, float mul, int len);
 ;---------------------------------------------------------------------------------
 %macro INT32_TO_FLOAT_FMUL_SCALAR 1
 %if UNIX64
diff --git a/libavcodec/x86/fmtconvert_init.c b/libavcodec/x86/fmtconvert_init.c
index b97fbf9..3d75df9 100644
--- a/libavcodec/x86/fmtconvert_init.c
+++ b/libavcodec/x86/fmtconvert_init.c
@@ -3,6 +3,8 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
  *
+ * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -18,20 +20,18 @@
  * 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
- *
- * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/fmtconvert.h"
-#include "libavcodec/dsputil.h"
 
 #if HAVE_YASM
 
-void ff_int32_to_float_fmul_scalar_sse (float *dst, const int *src, float mul, int len);
-void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int *src, float mul, int len);
+void ff_int32_to_float_fmul_scalar_sse (float *dst, const int32_t *src, float mul, int len);
+void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int32_t *src, float mul, int len);
 
 void ff_float_to_int16_3dnow(int16_t *dst, const float *src, long len);
 void ff_float_to_int16_sse  (int16_t *dst, const float *src, long len);
@@ -113,36 +113,35 @@ static void float_interleave_sse(float *dst, const float **src,
 }
 #endif /* HAVE_YASM */
 
-void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)
+av_cold void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->float_interleave = float_interleave_mmx;
-
-        if (EXTERNAL_AMD3DNOW(mm_flags)) {
-            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
-                c->float_to_int16 = ff_float_to_int16_3dnow;
-                c->float_to_int16_interleave = float_to_int16_interleave_3dnow;
-            }
-        }
-        if (EXTERNAL_AMD3DNOWEXT(mm_flags)) {
-            if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
-                c->float_to_int16_interleave = float_to_int16_interleave_3dnowext;
-            }
-        }
-        if (EXTERNAL_SSE(mm_flags)) {
-            c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse;
-            c->float_to_int16 = ff_float_to_int16_sse;
-            c->float_to_int16_interleave = float_to_int16_interleave_sse;
-            c->float_interleave = float_interleave_sse;
+    }
+    if (EXTERNAL_AMD3DNOW(cpu_flags)) {
+        if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
+            c->float_to_int16            = ff_float_to_int16_3dnow;
+            c->float_to_int16_interleave = float_to_int16_interleave_3dnow;
         }
-        if (EXTERNAL_SSE2(mm_flags)) {
-            c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2;
-            c->float_to_int16 = ff_float_to_int16_sse2;
-            c->float_to_int16_interleave = float_to_int16_interleave_sse2;
+    }
+    if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) {
+        if (!(avctx->flags & CODEC_FLAG_BITEXACT)) {
+            c->float_to_int16_interleave = float_to_int16_interleave_3dnowext;
         }
     }
+    if (EXTERNAL_SSE(cpu_flags)) {
+        c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse;
+        c->float_to_int16             = ff_float_to_int16_sse;
+        c->float_to_int16_interleave  = float_to_int16_interleave_sse;
+        c->float_interleave           = float_interleave_sse;
+    }
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2;
+        c->float_to_int16             = ff_float_to_int16_sse2;
+        c->float_to_int16_interleave  = float_to_int16_interleave_sse2;
+    }
 #endif /* HAVE_YASM */
 }
diff --git a/libavcodec/x86/fpel.asm b/libavcodec/x86/fpel.asm
new file mode 100644
index 0000000..43b039d
--- /dev/null
+++ b/libavcodec/x86/fpel.asm
@@ -0,0 +1,106 @@
+;******************************************************************************
+;* MMX optimized DSP utils
+;* Copyright (c) 2008 Loren Merritt
+;* Copyright (c) 2003-2013 Michael Niedermayer
+;* Copyright (c) 2013 Daniel Kang
+;*
+;* This file is part of 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/x86util.asm"
+
+SECTION .text
+
+INIT_MMX mmxext
+; void pixels(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PIXELS48 2
+%if %2 == 4
+%define OP movh
+%else
+%define OP mova
+%endif
+cglobal %1_pixels%2, 4,5
+    movsxdifnidn r2, r2d
+    lea          r4, [r2*3]
+.loop:
+    OP           m0, [r1]
+    OP           m1, [r1+r2]
+    OP           m2, [r1+r2*2]
+    OP           m3, [r1+r4]
+    lea          r1, [r1+r2*4]
+%ifidn %1, avg
+    pavgb        m0, [r0]
+    pavgb        m1, [r0+r2]
+    pavgb        m2, [r0+r2*2]
+    pavgb        m3, [r0+r4]
+%endif
+    OP         [r0], m0
+    OP      [r0+r2], m1
+    OP    [r0+r2*2], m2
+    OP      [r0+r4], m3
+    sub         r3d, 4
+    lea          r0, [r0+r2*4]
+    jne       .loop
+    RET
+%endmacro
+
+PIXELS48 put, 4
+PIXELS48 avg, 4
+PIXELS48 put, 8
+PIXELS48 avg, 8
+
+
+INIT_XMM sse2
+; void put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+cglobal put_pixels16, 4,5,4
+    lea          r4, [r2*3]
+.loop:
+    movu         m0, [r1]
+    movu         m1, [r1+r2]
+    movu         m2, [r1+r2*2]
+    movu         m3, [r1+r4]
+    lea          r1, [r1+r2*4]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova  [r0+r2*2], m2
+    mova    [r0+r4], m3
+    sub         r3d, 4
+    lea          r0, [r0+r2*4]
+    jnz       .loop
+    REP_RET
+
+; void avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+cglobal avg_pixels16, 4,5,4
+    lea          r4, [r2*3]
+.loop:
+    movu         m0, [r1]
+    movu         m1, [r1+r2]
+    movu         m2, [r1+r2*2]
+    movu         m3, [r1+r4]
+    lea          r1, [r1+r2*4]
+    pavgb        m0, [r0]
+    pavgb        m1, [r0+r2]
+    pavgb        m2, [r0+r2*2]
+    pavgb        m3, [r0+r4]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova  [r0+r2*2], m2
+    mova    [r0+r4], m3
+    sub         r3d, 4
+    lea          r0, [r0+r2*4]
+    jnz       .loop
+    REP_RET
diff --git a/libavcodec/x86/fpel_mmx.c b/libavcodec/x86/fpel_mmx.c
new file mode 100644
index 0000000..1ae8f86
--- /dev/null
+++ b/libavcodec/x86/fpel_mmx.c
@@ -0,0 +1,139 @@
+/*
+ * MMX-optimized avg/put pixel routines
+ *
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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 <stddef.h>
+#include <stdint.h>
+
+#include "config.h"
+#include "dsputil_x86.h"
+
+#if HAVE_MMX_INLINE
+
+// in case more speed is needed - unrolling would certainly help
+void ff_avg_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
+                        ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    JUMPALIGN();
+    do {
+        __asm__ volatile(
+             "movq  %0, %%mm0           \n\t"
+             "movq  %1, %%mm1           \n\t"
+             PAVGB_MMX(%%mm0, %%mm1, %%mm2, %%mm6)
+             "movq  %%mm2, %0           \n\t"
+             :"+m"(*block)
+             :"m"(*pixels)
+             :"memory");
+        pixels += line_size;
+        block += line_size;
+    }
+    while (--h);
+}
+
+void ff_avg_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
+                         ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    JUMPALIGN();
+    do {
+        __asm__ volatile(
+             "movq  %0, %%mm0           \n\t"
+             "movq  %1, %%mm1           \n\t"
+             PAVGB_MMX(%%mm0, %%mm1, %%mm2, %%mm6)
+             "movq  %%mm2, %0           \n\t"
+             "movq  8%0, %%mm0          \n\t"
+             "movq  8%1, %%mm1          \n\t"
+             PAVGB_MMX(%%mm0, %%mm1, %%mm2, %%mm6)
+             "movq  %%mm2, 8%0          \n\t"
+             :"+m"(*block)
+             :"m"(*pixels)
+             :"memory");
+        pixels += line_size;
+        block += line_size;
+    }
+    while (--h);
+}
+
+void ff_put_pixels8_mmx(uint8_t *block, const uint8_t *pixels,
+                        ptrdiff_t line_size, int h)
+{
+    __asm__ volatile (
+        "lea   (%3, %3), %%"REG_a"      \n\t"
+        ".p2align     3                 \n\t"
+        "1:                             \n\t"
+        "movq  (%1    ), %%mm0          \n\t"
+        "movq  (%1, %3), %%mm1          \n\t"
+        "movq     %%mm0, (%2)           \n\t"
+        "movq     %%mm1, (%2, %3)       \n\t"
+        "add  %%"REG_a", %1             \n\t"
+        "add  %%"REG_a", %2             \n\t"
+        "movq  (%1    ), %%mm0          \n\t"
+        "movq  (%1, %3), %%mm1          \n\t"
+        "movq     %%mm0, (%2)           \n\t"
+        "movq     %%mm1, (%2, %3)       \n\t"
+        "add  %%"REG_a", %1             \n\t"
+        "add  %%"REG_a", %2             \n\t"
+        "subl        $4, %0             \n\t"
+        "jnz         1b                 \n\t"
+        : "+g"(h), "+r"(pixels),  "+r"(block)
+        : "r"((x86_reg)line_size)
+        : "%"REG_a, "memory"
+        );
+}
+
+void ff_put_pixels16_mmx(uint8_t *block, const uint8_t *pixels,
+                         ptrdiff_t line_size, int h)
+{
+    __asm__ volatile (
+        "lea   (%3, %3), %%"REG_a"      \n\t"
+        ".p2align     3                 \n\t"
+        "1:                             \n\t"
+        "movq  (%1    ), %%mm0          \n\t"
+        "movq 8(%1    ), %%mm4          \n\t"
+        "movq  (%1, %3), %%mm1          \n\t"
+        "movq 8(%1, %3), %%mm5          \n\t"
+        "movq     %%mm0,  (%2)          \n\t"
+        "movq     %%mm4, 8(%2)          \n\t"
+        "movq     %%mm1,  (%2, %3)      \n\t"
+        "movq     %%mm5, 8(%2, %3)      \n\t"
+        "add  %%"REG_a", %1             \n\t"
+        "add  %%"REG_a", %2             \n\t"
+        "movq  (%1    ), %%mm0          \n\t"
+        "movq 8(%1    ), %%mm4          \n\t"
+        "movq  (%1, %3), %%mm1          \n\t"
+        "movq 8(%1, %3), %%mm5          \n\t"
+        "movq     %%mm0,  (%2)          \n\t"
+        "movq     %%mm4, 8(%2)          \n\t"
+        "movq     %%mm1,  (%2, %3)      \n\t"
+        "movq     %%mm5, 8(%2, %3)      \n\t"
+        "add  %%"REG_a", %1             \n\t"
+        "add  %%"REG_a", %2             \n\t"
+        "subl        $4, %0             \n\t"
+        "jnz         1b                 \n\t"
+        : "+g"(h), "+r"(pixels),  "+r"(block)
+        : "r"((x86_reg)line_size)
+        : "%"REG_a, "memory"
+        );
+}
+
+#endif /* HAVE_MMX_INLINE */
diff --git a/libavcodec/x86/h263_loopfilter.asm b/libavcodec/x86/h263_loopfilter.asm
new file mode 100644
index 0000000..a940aad
--- /dev/null
+++ b/libavcodec/x86/h263_loopfilter.asm
@@ -0,0 +1,187 @@
+;******************************************************************************
+;* MMX-optimized H.263 loop filter
+;*
+;* 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/x86util.asm"
+
+SECTION_RODATA
+cextern pb_FC
+cextern h263_loop_filter_strength
+
+SECTION_TEXT
+
+%macro H263_LOOP_FILTER 5
+    pxor         m7, m7
+    mova         m0, [%1]
+    mova         m1, [%1]
+    mova         m2, [%4]
+    mova         m3, [%4]
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    psubw        m0, m2
+    psubw        m1, m3
+    mova         m2, [%2]
+    mova         m3, [%2]
+    mova         m4, [%3]
+    mova         m5, [%3]
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    punpcklbw    m4, m7
+    punpckhbw    m5, m7
+    psubw        m4, m2
+    psubw        m5, m3
+    psllw        m4, 2
+    psllw        m5, 2
+    paddw        m4, m0
+    paddw        m5, m1
+    pxor         m6, m6
+    pcmpgtw      m6, m4
+    pcmpgtw      m7, m5
+    pxor         m4, m6
+    pxor         m5, m7
+    psubw        m4, m6
+    psubw        m5, m7
+    psrlw        m4, 3
+    psrlw        m5, 3
+    packuswb     m4, m5
+    packsswb     m6, m7
+    pxor         m7, m7
+    movd         m2, %5
+    punpcklbw    m2, m2
+    punpcklbw    m2, m2
+    punpcklbw    m2, m2
+    psubusb      m2, m4
+    mova         m3, m2
+    psubusb      m3, m4
+    psubb        m2, m3
+    mova         m3, [%2]
+    mova         m4, [%3]
+    pxor         m3, m6
+    pxor         m4, m6
+    paddusb      m3, m2
+    psubusb      m4, m2
+    pxor         m3, m6
+    pxor         m4, m6
+    paddusb      m2, m2
+    packsswb     m0, m1
+    pcmpgtb      m7, m0
+    pxor         m0, m7
+    psubb        m0, m7
+    mova         m1, m0
+    psubusb      m0, m2
+    psubb        m1, m0
+    pand         m1, [pb_FC]
+    psrlw        m1, 2
+    pxor         m1, m7
+    psubb        m1, m7
+    mova         m5, [%1]
+    mova         m6, [%4]
+    psubb        m5, m1
+    paddb        m6, m1
+%endmacro
+
+INIT_MMX mmx
+; void h263_v_loop_filter(uint8_t *src, int stride, int qscale)
+cglobal h263_v_loop_filter, 3,5
+    movsxdifnidn r1, r1d
+    movsxdifnidn r2, r2d
+
+    lea          r4, [h263_loop_filter_strength]
+    movzx       r3d, BYTE [r4+r2]
+    movsx        r2, r3b
+    shl          r2, 1
+
+    mov          r3, r0
+    sub          r3, r1
+    mov          r4, r3
+    sub          r4, r1
+    H263_LOOP_FILTER r4, r3, r0, r0+r1, r2d
+
+    mova       [r3], m3
+    mova       [r0], m4
+    mova       [r4], m5
+    mova    [r0+r1], m6
+    RET
+
+%macro TRANSPOSE4X4 2
+    movd      m0, [%1]
+    movd      m1, [%1+r1]
+    movd      m2, [%1+r1*2]
+    movd      m3, [%1+r3]
+    punpcklbw m0, m1
+    punpcklbw m2, m3
+    mova      m1, m0
+    punpcklwd m0, m2
+    punpckhwd m1, m2
+    movd [%2+ 0], m0
+    punpckhdq m0, m0
+    movd [%2+ 8], m0
+    movd [%2+16], m1
+    punpckhdq m1, m1
+    movd [%2+24], m1
+%endmacro
+
+
+; void h263_h_loop_filter(uint8_t *src, int stride, int qscale)
+INIT_MMX mmx
+cglobal h263_h_loop_filter, 3,5,0,32
+    movsxdifnidn r1, r1d
+    movsxdifnidn r2, r2d
+
+    lea          r4, [h263_loop_filter_strength]
+    movzx       r3d, BYTE [r4+r2]
+    movsx        r2, r3b
+    shl          r2, 1
+
+    sub          r0, 2
+    lea          r3, [r1*3]
+
+    TRANSPOSE4X4 r0, rsp
+    lea          r4, [r0+r1*4]
+    TRANSPOSE4X4 r4, rsp+4
+
+    H263_LOOP_FILTER rsp, rsp+8, rsp+16, rsp+24, r2d
+
+    mova         m1, m5
+    mova         m0, m4
+    punpcklbw    m5, m3
+    punpcklbw    m4, m6
+    punpckhbw    m1, m3
+    punpckhbw    m0, m6
+    mova         m3, m5
+    mova         m6, m1
+    punpcklwd    m5, m4
+    punpcklwd    m1, m0
+    punpckhwd    m3, m4
+    punpckhwd    m6, m0
+    movd       [r0], m5
+    punpckhdq    m5, m5
+    movd  [r0+r1*1], m5
+    movd  [r0+r1*2], m3
+    punpckhdq    m3, m3
+    movd    [r0+r3], m3
+    movd       [r4], m1
+    punpckhdq    m1, m1
+    movd  [r4+r1*1], m1
+    movd  [r4+r1*2], m6
+    punpckhdq    m6, m6
+    movd    [r4+r3], m6
+    RET
diff --git a/libavcodec/x86/h263dsp_init.c b/libavcodec/x86/h263dsp_init.c
new file mode 100644
index 0000000..d4fab98
--- /dev/null
+++ b/libavcodec/x86/h263dsp_init.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Diego Biurrun <diego at biurrun.de>
+ *
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/h263dsp.h"
+
+void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale);
+void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale);
+
+av_cold void ff_h263dsp_init_x86(H263DSPContext *c)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (EXTERNAL_MMX(cpu_flags)) {
+        c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx;
+        c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx;
+    }
+}
diff --git a/libavcodec/x86/h264_chromamc.asm b/libavcodec/x86/h264_chromamc.asm
index 1be37de..b7b18e0 100644
--- a/libavcodec/x86/h264_chromamc.asm
+++ b/libavcodec/x86/h264_chromamc.asm
@@ -60,7 +60,7 @@ rnd_rv40_1d_tbl: times 4 dw  0
 cextern pw_3
 cextern pw_4
 cextern pw_8
-cextern pw_28
+pw_28: times 8 dw 28
 cextern pw_32
 cextern pw_64
 
@@ -427,11 +427,11 @@ cglobal %1_%2_chroma_mc2, 6, 7, 0
 %macro NOTHING 2-3
 %endmacro
 %macro DIRECT_AVG 2
-    PAVG          %1, %2
+    PAVGB         %1, %2
 %endmacro
 %macro COPY_AVG 3
     movd          %2, %3
-    PAVG          %1, %2
+    PAVGB         %1, %2
 %endmacro
 
 INIT_MMX mmx
@@ -448,7 +448,6 @@ chroma_mc2_mmx_func put, h264
 
 %define CHROMAMC_AVG  DIRECT_AVG
 %define CHROMAMC_AVG4 COPY_AVG
-%define PAVG          pavgb
 chroma_mc8_mmx_func avg, h264, _rnd
 chroma_mc8_mmx_func avg, vc1,  _nornd
 chroma_mc8_mmx_func avg, rv40
@@ -456,7 +455,6 @@ chroma_mc4_mmx_func avg, h264
 chroma_mc4_mmx_func avg, rv40
 chroma_mc2_mmx_func avg, h264
 
-%define PAVG          pavgusb
 INIT_MMX 3dnow
 chroma_mc8_mmx_func avg, h264, _rnd
 chroma_mc8_mmx_func avg, vc1,  _nornd
@@ -673,7 +671,6 @@ INIT_MMX ssse3
 chroma_mc4_ssse3_func put, h264
 
 %define CHROMAMC_AVG DIRECT_AVG
-%define PAVG         pavgb
 INIT_XMM ssse3
 chroma_mc8_ssse3_func avg, h264, _rnd
 chroma_mc8_ssse3_func avg, vc1,  _nornd
diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm
index 67f9c02..6e29ce7 100644
--- a/libavcodec/x86/h264_deblock.asm
+++ b/libavcodec/x86/h264_deblock.asm
@@ -28,6 +28,7 @@
 
 SECTION_RODATA
 
+pb_A1: times 16 db 0xA1
 pb_3_1: times 4 db 3, 1
 
 SECTION .text
@@ -35,7 +36,6 @@ SECTION .text
 cextern pb_0
 cextern pb_1
 cextern pb_3
-cextern pb_A1
 
 ; expands to [base],...,[base+7*stride]
 %define PASS8ROWS(base, base3, stride, stride3) \
@@ -331,16 +331,14 @@ cglobal deblock_v_luma_8, 5,5,10
 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
 ;-----------------------------------------------------------------------------
 INIT_MMX cpuname
-cglobal deblock_h_luma_8, 5,9
+cglobal deblock_h_luma_8, 5,9,0,0x60+16*WIN64
     movsxd r7,  r1d
     lea    r8,  [r7+r7*2]
     lea    r6,  [r0-4]
     lea    r5,  [r0-4+r8]
 %if WIN64
-    sub    rsp, 0x98
-    %define pix_tmp rsp+0x30
+    %define pix_tmp rsp+0x30 ; shadow space + r4
 %else
-    sub    rsp, 0x68
     %define pix_tmp rsp
 %endif
 
@@ -379,11 +377,6 @@ cglobal deblock_h_luma_8, 5,9
     movq   m3, [pix_tmp+0x40]
     TRANSPOSE8x4B_STORE  PASS8ROWS(r6, r5, r7, r8)
 
-%if WIN64
-    add    rsp, 0x98
-%else
-    add    rsp, 0x68
-%endif
     RET
 %endmacro
 
@@ -704,13 +697,16 @@ INIT_MMX cpuname
 ;-----------------------------------------------------------------------------
 ; void deblock_h_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
 ;-----------------------------------------------------------------------------
-cglobal deblock_h_luma_intra_8, 4,9
+cglobal deblock_h_luma_intra_8, 4,9,0,0x80
     movsxd r7,  r1d
     lea    r8,  [r7*3]
     lea    r6,  [r0-4]
     lea    r5,  [r0-4+r8]
-    sub    rsp, 0x88
+%if WIN64
+    %define pix_tmp rsp+0x20 ; shadow space
+%else
     %define pix_tmp rsp
+%endif
 
     ; transpose 8x16 -> tmp space
     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r7, r8), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
@@ -730,7 +726,6 @@ cglobal deblock_h_luma_intra_8, 4,9
     sub    r5,  r7
     shr    r7,  3
     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r7, r8)
-    add    rsp, 0x88
     RET
 %else
 cglobal deblock_h_luma_intra_8, 2,4,8,0x80
diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm
index 30cecd9..2771291 100644
--- a/libavcodec/x86/h264_idct.asm
+++ b/libavcodec/x86/h264_idct.asm
@@ -30,7 +30,6 @@
 
 SECTION_RODATA
 
-; FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split
 scan8_mem: db  4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
            db  6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8
            db  4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8
@@ -70,6 +69,10 @@ SECTION .text
     paddw        m0, m6
     IDCT4_1D      w, 0, 1, 2, 3, 4, 5
     pxor         m7, m7
+    movq    [%2+ 0], m7
+    movq    [%2+ 8], m7
+    movq    [%2+16], m7
+    movq    [%2+24], m7
 
     STORE_DIFFx2 m0, m1, m4, m5, m7, 6, %1, %3
     lea          %1, [%1+%3*2]
@@ -77,7 +80,7 @@ SECTION .text
 %endmacro
 
 INIT_MMX mmx
-; ff_h264_idct_add_mmx(uint8_t *dst, int16_t *block, int stride)
+; ff_h264_idct_add_8_mmx(uint8_t *dst, int16_t *block, int stride)
 cglobal h264_idct_add_8, 3, 3, 0
     IDCT4_ADD    r0, r1, r2
     RET
@@ -161,13 +164,31 @@ cglobal h264_idct_add_8, 3, 3, 0
 %endmacro
 
 ; %1=uint8_t *dst, %2=int16_t *block, %3=int stride
-%macro IDCT8_ADD_MMX_END 3
+%macro IDCT8_ADD_MMX_END 3-4
     IDCT8_1D_FULL %2
     mova    [%2   ], m5
     mova    [%2+16], m6
     mova    [%2+32], m7
 
     pxor         m7, m7
+%if %0 == 4
+    movq   [%4+  0], m7
+    movq   [%4+  8], m7
+    movq   [%4+ 16], m7
+    movq   [%4+ 24], m7
+    movq   [%4+ 32], m7
+    movq   [%4+ 40], m7
+    movq   [%4+ 48], m7
+    movq   [%4+ 56], m7
+    movq   [%4+ 64], m7
+    movq   [%4+ 72], m7
+    movq   [%4+ 80], m7
+    movq   [%4+ 88], m7
+    movq   [%4+ 96], m7
+    movq   [%4+104], m7
+    movq   [%4+112], m7
+    movq   [%4+120], m7
+%endif
     STORE_DIFFx2 m0, m1, m5, m6, m7, 6, %1, %3
     lea          %1, [%1+%3*2]
     STORE_DIFFx2 m2, m3, m5, m6, m7, 6, %1, %3
@@ -181,7 +202,7 @@ cglobal h264_idct_add_8, 3, 3, 0
 %endmacro
 
 INIT_MMX mmx
-; ff_h264_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride)
+; ff_h264_idct8_add_8_mmx(uint8_t *dst, int16_t *block, int stride)
 cglobal h264_idct8_add_8, 3, 4, 0
     %assign pad 128+4-(stack_offset&7)
     SUB         rsp, pad
@@ -190,7 +211,7 @@ cglobal h264_idct8_add_8, 3, 4, 0
     IDCT8_ADD_MMX_START r1  , rsp
     IDCT8_ADD_MMX_START r1+8, rsp+64
     lea          r3, [r0+4]
-    IDCT8_ADD_MMX_END   r0  , rsp,   r2
+    IDCT8_ADD_MMX_END   r0  , rsp,   r2, r1
     IDCT8_ADD_MMX_END   r3  , rsp+8, r2
 
     ADD         rsp, pad
@@ -233,6 +254,14 @@ cglobal h264_idct8_add_8, 3, 4, 0
     SWAP          0, 8
     SWAP          1, 9
 %endif
+    mova   [%2+  0], m7
+    mova   [%2+ 16], m7
+    mova   [%2+ 32], m7
+    mova   [%2+ 48], m7
+    mova   [%2+ 64], m7
+    mova   [%2+ 80], m7
+    mova   [%2+ 96], m7
+    mova   [%2+112], m7
     lea          %1, [%1+%3*4]
     STORE_DIFF   m4, m6, m7, [%1     ]
     STORE_DIFF   m5, m6, m7, [%1+%3  ]
@@ -241,24 +270,16 @@ cglobal h264_idct8_add_8, 3, 4, 0
 %endmacro
 
 INIT_XMM sse2
-; ff_h264_idct8_add_sse2(uint8_t *dst, int16_t *block, int stride)
+; ff_h264_idct8_add_8_sse2(uint8_t *dst, int16_t *block, int stride)
 cglobal h264_idct8_add_8, 3, 4, 10
     IDCT8_ADD_SSE r0, r1, r2, r3
     RET
 
-%macro DC_ADD_MMXEXT_INIT 2-3
-%if %0 == 2
-    movsx        %1, word [%1]
+%macro DC_ADD_MMXEXT_INIT 2
     add          %1, 32
     sar          %1, 6
     movd         m0, %1d
     lea          %1, [%2*3]
-%else
-    add          %3, 32
-    sar          %3, 6
-    movd         m0, %3d
-    lea          %3, [%2*3]
-%endif
     pshufw       m0, m0, 0
     pxor         m1, m1
     psubw        m1, m0
@@ -286,23 +307,50 @@ cglobal h264_idct8_add_8, 3, 4, 10
 %endmacro
 
 INIT_MMX mmxext
-; ff_h264_idct_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride)
-cglobal h264_idct_dc_add_8, 3, 3, 0
-    DC_ADD_MMXEXT_INIT r1, r2
-    DC_ADD_MMXEXT_OP movh, r0, r2, r1
+; ff_h264_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
+%if ARCH_X86_64
+cglobal h264_idct_dc_add_8, 3, 4, 0
+    movsx        r3, word [r1]
+    mov  dword [r1], 0
+    DC_ADD_MMXEXT_INIT r3, r2
+    DC_ADD_MMXEXT_OP movh, r0, r2, r3
     RET
 
-; ff_h264_idct8_dc_add_mmxext(uint8_t *dst, int16_t *block, int stride)
-cglobal h264_idct8_dc_add_8, 3, 3, 0
-    DC_ADD_MMXEXT_INIT r1, r2
-    DC_ADD_MMXEXT_OP mova, r0, r2, r1
+; ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
+cglobal h264_idct8_dc_add_8, 3, 4, 0
+    movsx        r3, word [r1]
+    mov  dword [r1], 0
+    DC_ADD_MMXEXT_INIT r3, r2
+    DC_ADD_MMXEXT_OP mova, r0, r2, r3
     lea          r0, [r0+r2*4]
-    DC_ADD_MMXEXT_OP mova, r0, r2, r1
+    DC_ADD_MMXEXT_OP mova, r0, r2, r3
     RET
+%else
+; ff_h264_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
+cglobal h264_idct_dc_add_8, 2, 3, 0
+    movsx        r2, word [r1]
+    mov  dword [r1], 0
+    mov          r1, r2m
+    DC_ADD_MMXEXT_INIT r2, r1
+    DC_ADD_MMXEXT_OP movh, r0, r1, r2
+    RET
+
+; ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride)
+cglobal h264_idct8_dc_add_8, 2, 3, 0
+    movsx        r2, word [r1]
+    mov  dword [r1], 0
+    mov          r1, r2m
+    DC_ADD_MMXEXT_INIT r2, r1
+    DC_ADD_MMXEXT_OP mova, r0, r1, r2
+    lea          r0, [r0+r1*4]
+    DC_ADD_MMXEXT_OP mova, r0, r1, r2
+    RET
+%endif
 
 INIT_MMX mmx
-; ff_h264_idct_add16_mmx(uint8_t *dst, const int *block_offset,
-;             DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct_add16_8_mmx(uint8_t *dst, const int *block_offset,
+;                          int16_t *block, int stride,
+;                          const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add16_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
     xor          r5, r5
 %ifdef PIC
@@ -323,8 +371,9 @@ cglobal h264_idct_add16_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride,
     jl .nextblock
     REP_RET
 
-; ff_h264_idct8_add4_mmx(uint8_t *dst, const int *block_offset,
-;                        DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct8_add4_8_mmx(uint8_t *dst, const int *block_offset,
+;                          int16_t *block, int stride,
+;                          const uint8_t nnzc[6 * 8])
 cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
     %assign pad 128+4-(stack_offset&7)
     SUB         rsp, pad
@@ -343,7 +392,7 @@ cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride,
     add   word [r2], 32
     IDCT8_ADD_MMX_START r2  , rsp
     IDCT8_ADD_MMX_START r2+8, rsp+64
-    IDCT8_ADD_MMX_END   r6  , rsp,   r3
+    IDCT8_ADD_MMX_END   r6  , rsp,   r3, r2
     mov         r6d, dword [r1+r5*4]
     lea          r6, [r0+r6+4]
     IDCT8_ADD_MMX_END   r6  , rsp+8, r3
@@ -356,8 +405,9 @@ cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride,
     RET
 
 INIT_MMX mmxext
-; ff_h264_idct_add16_mmxext(uint8_t *dst, const int *block_offset,
-;                           DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct_add16_8_mmxext(uint8_t *dst, const int *block_offset,
+;                             int16_t *block, int stride,
+;                             const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     xor          r5, r5
 %ifdef PIC
@@ -373,7 +423,8 @@ cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride
     movsx        r6, word [r2]
     test         r6, r6
     jz .no_dc
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64 == 0
 %define dst2q r1
 %define dst2d r1d
@@ -401,8 +452,9 @@ cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride
     REP_RET
 
 INIT_MMX mmx
-; ff_h264_idct_add16intra_mmx(uint8_t *dst, const int *block_offset,
-;                             DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct_add16intra_8_mmx(uint8_t *dst, const int *block_offset,
+;                               int16_t *block, int stride,
+;                               const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add16intra_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg
     xor          r5, r5
 %ifdef PIC
@@ -425,9 +477,9 @@ cglobal h264_idct_add16intra_8, 5, 7 + npicregs, 0, dst, block_offset, block, st
     REP_RET
 
 INIT_MMX mmxext
-; ff_h264_idct_add16intra_mmxext(uint8_t *dst, const int *block_offset,
-;                                DCTELEM *block, int stride,
-;                                const uint8_t nnzc[6*8])
+; ff_h264_idct_add16intra_8_mmxext(uint8_t *dst, const int *block_offset,
+;                                  int16_t *block, int stride,
+;                                  const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     xor          r5, r5
 %ifdef PIC
@@ -450,7 +502,8 @@ cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, s
     movsx        r6, word [r2]
     test         r6, r6
     jz .skipblock
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64 == 0
 %define dst2q r1
 %define dst2d r1d
@@ -468,9 +521,9 @@ cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, s
     jl .nextblock
     REP_RET
 
-; ff_h264_idct8_add4_mmxext(uint8_t *dst, const int *block_offset,
-;                           DCTELEM *block, int stride,
-;                           const uint8_t nnzc[6*8])
+; ff_h264_idct8_add4_8_mmxext(uint8_t *dst, const int *block_offset,
+;                             int16_t *block, int stride,
+;                             const uint8_t nnzc[6 * 8])
 cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     %assign pad 128+4-(stack_offset&7)
     SUB         rsp, pad
@@ -489,7 +542,8 @@ cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride
     movsx        r6, word [r2]
     test         r6, r6
     jz .no_dc
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64 == 0
 %define dst2q r1
 %define dst2d r1d
@@ -515,7 +569,7 @@ cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride
     add   word [r2], 32
     IDCT8_ADD_MMX_START r2  , rsp
     IDCT8_ADD_MMX_START r2+8, rsp+64
-    IDCT8_ADD_MMX_END   r6  , rsp,   r3
+    IDCT8_ADD_MMX_END   r6  , rsp,   r3, r2
     mov         r6d, dword [r1+r5*4]
     lea          r6, [r0+r6+4]
     IDCT8_ADD_MMX_END   r6  , rsp+8, r3
@@ -529,8 +583,9 @@ cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride
     RET
 
 INIT_XMM sse2
-; ff_h264_idct8_add4_sse2(uint8_t *dst, const int *block_offset,
-;                         DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct8_add4_8_sse2(uint8_t *dst, const int *block_offset,
+;                           int16_t *block, int stride,
+;                           const uint8_t nnzc[6 * 8])
 cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     xor          r5, r5
 %ifdef PIC
@@ -547,7 +602,8 @@ cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, strid
     test         r6, r6
     jz .no_dc
 INIT_MMX cpuname
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64 == 0
 %define dst2q r1
 %define dst2d r1d
@@ -604,8 +660,8 @@ h264_idct_add8_mmx_plane:
     jnz .nextblock
     rep ret
 
-; ff_h264_idct_add8_mmx(uint8_t **dest, const int *block_offset,
-;                       DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct_add8_8_mmx(uint8_t **dest, const int *block_offset,
+;                         int16_t *block, int stride, const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     mov          r5, 16
     add          r2, 512
@@ -650,7 +706,8 @@ h264_idct_add8_mmxext_plane:
     movsx        r6, word [r2]
     test         r6, r6
     jz .skipblock
-    DC_ADD_MMXEXT_INIT r2, r3, r6
+    mov   word [r2], 0
+    DC_ADD_MMXEXT_INIT r6, r3
 %if ARCH_X86_64
     mov         r0d, dword [r1+r5*4]
     add          r0, [dst2q]
@@ -668,8 +725,9 @@ h264_idct_add8_mmxext_plane:
     rep ret
 
 INIT_MMX mmxext
-; ff_h264_idct_add8_mmxext(uint8_t **dest, const int *block_offset,
-;                          DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct_add8_8_mmxext(uint8_t **dest, const int *block_offset,
+;                            int16_t *block, int stride,
+;                            const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg
     mov          r5, 16
     add          r2, 512
@@ -693,7 +751,9 @@ cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride,
 ; r0 = uint8_t *dst, r2 = int16_t *block, r3 = int stride, r6=clobbered
 h264_idct_dc_add8_mmxext:
     movd         m0, [r2   ]          ;  0 0 X D
+    mov word [r2+ 0], 0
     punpcklwd    m0, [r2+32]          ;  x X d D
+    mov word [r2+32], 0
     paddsw       m0, [pw_32]
     psraw        m0, 6
     punpcklwd    m0, m0               ;  d d D D
@@ -723,6 +783,10 @@ h264_add8x4_idct_sse2:
     paddw m0, [pw_32]
     IDCT4_1D w,0,1,2,3,4,5
     pxor  m7, m7
+    mova [r2+ 0], m7
+    mova [r2+16], m7
+    mova [r2+32], m7
+    mova [r2+48], m7
     STORE_DIFFx2 m0, m1, m4, m5, m7, 6, r0, r3
     lea   r0, [r0+r3*2]
     STORE_DIFFx2 m2, m3, m4, m5, m7, 6, r0, r3
@@ -745,8 +809,9 @@ h264_add8x4_idct_sse2:
 %endif
 %endmacro
 
-; ff_h264_idct_add16_sse2(uint8_t *dst, const int *block_offset,
-;                         DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct_add16_8_sse2(uint8_t *dst, const int *block_offset,
+;                           int16_t *block, int stride,
+;                           const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8
 %if ARCH_X86_64
     mov         r5, r0
@@ -792,8 +857,9 @@ cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8
 %endif
 %endmacro
 
-; ff_h264_idct_add16intra_sse2(uint8_t *dst, const int *block_offset,
-;                              DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct_add16intra_8_sse2(uint8_t *dst, const int *block_offset,
+;                                int16_t *block, int stride,
+;                                const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8
 %if ARCH_X86_64
     mov         r7, r0
@@ -843,8 +909,9 @@ cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8
 %endif
 %endmacro
 
-; ff_h264_idct_add8_sse2(uint8_t **dest, const int *block_offset,
-;                        DCTELEM *block, int stride, const uint8_t nnzc[6*8])
+; ff_h264_idct_add8_8_sse2(uint8_t **dest, const int *block_offset,
+;                          int16_t *block, int stride,
+;                          const uint8_t nnzc[6 * 8])
 cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8
     add          r2, 512
 %if ARCH_X86_64
@@ -861,7 +928,7 @@ cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8
     add8_sse2_cycle 3, 0x64
     RET
 
-;void ff_h264_luma_dc_dequant_idct_mmx(DCTELEM *output, DCTELEM *input, int qmul)
+;void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul)
 
 %macro WALSH4_1D 5
     SUMSUB_BADC w, %4, %3, %2, %1, %5
diff --git a/libavcodec/x86/h264_idct_10bit.asm b/libavcodec/x86/h264_idct_10bit.asm
index 51965f0..4e51d2b 100644
--- a/libavcodec/x86/h264_idct_10bit.asm
+++ b/libavcodec/x86/h264_idct_10bit.asm
@@ -66,6 +66,10 @@ SECTION .text
     paddd m0, [pd_32]
     IDCT4_1D d,0,1,2,3,4,5
     pxor  m5, m5
+    mova [%2+ 0], m5
+    mova [%2+16], m5
+    mova [%2+32], m5
+    mova [%2+48], m5
     STORE_DIFFx2 m0, m1, m4, m5, %1, %3
     lea   %1, [%1+%3*2]
     STORE_DIFFx2 m2, m3, m4, m5, %1, %3
@@ -98,6 +102,10 @@ add4x4_idct %+ SUFFIX:
     paddd m0, [pd_32]
     IDCT4_1D d,0,1,2,3,4,5
     pxor  m5, m5
+    mova  [r2+ 0], m5
+    mova  [r2+16], m5
+    mova  [r2+32], m5
+    mova  [r2+48], m5
     STORE_DIFFx2 m0, m1, m4, m5, r5, r3
     lea   r5, [r5+r3*2]
     STORE_DIFFx2 m2, m3, m4, m5, r5, r3
@@ -181,6 +189,7 @@ IDCT_ADD16_10
 INIT_MMX mmxext
 cglobal h264_idct_dc_add_10,3,3
     movd      m0, [r1]
+    mov dword [r1], 0
     paddd     m0, [pd_32]
     psrad     m0, 6
     lea       r1, [r2*3]
@@ -193,11 +202,11 @@ cglobal h264_idct_dc_add_10,3,3
 ; void h264_idct8_dc_add(pixel *dst, dctcoef *block, int stride)
 ;-----------------------------------------------------------------------------
 %macro IDCT8_DC_ADD 0
-cglobal h264_idct8_dc_add_10,3,3,7
-    mov      r1d, [r1]
-    add       r1, 32
-    sar       r1, 6
-    movd      m0, r1d
+cglobal h264_idct8_dc_add_10,3,4,7
+    movd      m0, [r1]
+    mov dword[r1], 0
+    paddd     m0, [pd_32]
+    psrad     m0, 6
     lea       r1, [r2*3]
     SPLATW    m0, m0, 0
     mova      m6, [pw_pixel_max]
@@ -247,6 +256,8 @@ idct_dc_add %+ SUFFIX:
     add       r5, r0
     movq      m0, [r2+ 0]
     movhps    m0, [r2+64]
+    mov dword [r2+ 0], 0
+    mov dword [r2+64], 0
     paddd     m0, [pd_32]
     psrad     m0, 6
     pshufhw   m0, m0, 0
@@ -461,6 +472,22 @@ h264_idct8_add1_10 %+ SUFFIX:
     packssdw      m8, m0
     paddsw        m8, [r0]
     pxor          m0, m0
+    mova    [r1+  0], m0
+    mova    [r1+ 16], m0
+    mova    [r1+ 32], m0
+    mova    [r1+ 48], m0
+    mova    [r1+ 64], m0
+    mova    [r1+ 80], m0
+    mova    [r1+ 96], m0
+    mova    [r1+112], m0
+    mova    [r1+128], m0
+    mova    [r1+144], m0
+    mova    [r1+160], m0
+    mova    [r1+176], m0
+    mova    [r1+192], m0
+    mova    [r1+208], m0
+    mova    [r1+224], m0
+    mova    [r1+240], m0
     CLIPW         m8, m0, [pw_pixel_max]
     mova        [r0], m8
     mova          m8, [pw_pixel_max]
@@ -480,6 +507,22 @@ h264_idct8_add1_10 %+ SUFFIX:
     lea           r3, [r0+8]
     IDCT8_ADD_SSE_END r0, rsp,    r2
     IDCT8_ADD_SSE_END r3, rsp+16, r2
+    mova    [r1+  0], m7
+    mova    [r1+ 16], m7
+    mova    [r1+ 32], m7
+    mova    [r1+ 48], m7
+    mova    [r1+ 64], m7
+    mova    [r1+ 80], m7
+    mova    [r1+ 96], m7
+    mova    [r1+112], m7
+    mova    [r1+128], m7
+    mova    [r1+144], m7
+    mova    [r1+160], m7
+    mova    [r1+176], m7
+    mova    [r1+192], m7
+    mova    [r1+208], m7
+    mova    [r1+224], m7
+    mova    [r1+240], m7
 %endif ; ARCH_X86_64
 
     add          rsp, pad
diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c
index 454dd3f..6dd98aa 100644
--- a/libavcodec/x86/h264_intrapred_init.c
+++ b/libavcodec/x86/h264_intrapred_init.c
@@ -18,8 +18,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
+#include "libavcodec/avcodec.h"
 #include "libavcodec/h264pred.h"
 
 #define PRED4x4(TYPE, DEPTH, OPT) \
@@ -179,12 +181,14 @@ PRED4x4(tm_vp8, 8, mmxext)
 PRED4x4(tm_vp8, 8, ssse3)
 PRED4x4(vertical_vp8, 8, mmxext)
 
-void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth, const int chroma_format_idc)
+av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id,
+                                   const int bit_depth,
+                                   const int chroma_format_idc)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
     if (bit_depth == 8) {
-        if (EXTERNAL_MMX(mm_flags)) {
+        if (EXTERNAL_MMX(cpu_flags)) {
             h->pred16x16[VERT_PRED8x8         ] = ff_pred16x16_vertical_8_mmx;
             h->pred16x16[HOR_PRED8x8          ] = ff_pred16x16_horizontal_8_mmx;
             if (chroma_format_idc == 1) {
@@ -199,7 +203,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
                 if (chroma_format_idc == 1)
                     h->pred8x8  [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmx;
                 if (codec_id == AV_CODEC_ID_SVQ3) {
-                    if (mm_flags & AV_CPU_FLAG_CMOV)
+                    if (cpu_flags & AV_CPU_FLAG_CMOV)
                         h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_mmx;
                 } else if (codec_id == AV_CODEC_ID_RV40) {
                     h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_mmx;
@@ -209,7 +213,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
             }
         }
 
-        if (EXTERNAL_MMXEXT(mm_flags)) {
+        if (EXTERNAL_MMXEXT(cpu_flags)) {
             h->pred16x16[HOR_PRED8x8            ] = ff_pred16x16_horizontal_8_mmxext;
             h->pred16x16[DC_PRED8x8             ] = ff_pred16x16_dc_8_mmxext;
             if (chroma_format_idc == 1)
@@ -261,11 +265,11 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
             }
         }
 
-        if (EXTERNAL_SSE(mm_flags)) {
+        if (EXTERNAL_SSE(cpu_flags)) {
             h->pred16x16[VERT_PRED8x8] = ff_pred16x16_vertical_8_sse;
         }
 
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             h->pred16x16[DC_PRED8x8           ] = ff_pred16x16_dc_8_sse2;
             h->pred8x8l [DIAG_DOWN_LEFT_PRED  ] = ff_pred8x8l_down_left_8_sse2;
             h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_sse2;
@@ -288,7 +292,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
             }
         }
 
-        if (EXTERNAL_SSSE3(mm_flags)) {
+        if (EXTERNAL_SSSE3(cpu_flags)) {
             h->pred16x16[HOR_PRED8x8          ] = ff_pred16x16_horizontal_8_ssse3;
             h->pred16x16[DC_PRED8x8           ] = ff_pred16x16_dc_8_ssse3;
             if (chroma_format_idc == 1)
@@ -319,7 +323,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
             }
         }
     } else if (bit_depth == 10) {
-        if (EXTERNAL_MMXEXT(mm_flags)) {
+        if (EXTERNAL_MMXEXT(cpu_flags)) {
             h->pred4x4[DC_PRED             ] = ff_pred4x4_dc_10_mmxext;
             h->pred4x4[HOR_UP_PRED         ] = ff_pred4x4_horizontal_up_10_mmxext;
 
@@ -335,7 +339,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
             h->pred16x16[VERT_PRED8x8      ] = ff_pred16x16_vertical_10_mmxext;
             h->pred16x16[HOR_PRED8x8       ] = ff_pred16x16_horizontal_10_mmxext;
         }
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_sse2;
             h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_sse2;
             h->pred4x4[VERT_LEFT_PRED      ] = ff_pred4x4_vertical_left_10_sse2;
@@ -367,7 +371,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
             h->pred16x16[VERT_PRED8x8      ] = ff_pred16x16_vertical_10_sse2;
             h->pred16x16[HOR_PRED8x8       ] = ff_pred16x16_horizontal_10_sse2;
         }
-        if (EXTERNAL_SSSE3(mm_flags)) {
+        if (EXTERNAL_SSSE3(cpu_flags)) {
             h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_ssse3;
             h->pred4x4[VERT_RIGHT_PRED     ] = ff_pred4x4_vertical_right_10_ssse3;
             h->pred4x4[HOR_DOWN_PRED       ] = ff_pred4x4_horizontal_down_10_ssse3;
@@ -378,7 +382,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth
             h->pred8x8l[VERT_RIGHT_PRED     ] = ff_pred8x8l_vertical_right_10_ssse3;
             h->pred8x8l[HOR_UP_PRED         ] = ff_pred8x8l_horizontal_up_10_ssse3;
         }
-        if (EXTERNAL_AVX(mm_flags)) {
+        if (EXTERNAL_AVX(cpu_flags)) {
             h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_avx;
             h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_avx;
             h->pred4x4[VERT_LEFT_PRED      ] = ff_pred4x4_vertical_left_10_avx;
diff --git a/libavcodec/x86/h264_qpel.c b/libavcodec/x86/h264_qpel.c
index bc56d09..90857ce 100644
--- a/libavcodec/x86/h264_qpel.c
+++ b/libavcodec/x86/h264_qpel.c
@@ -19,29 +19,19 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
-#include "libavcodec/dsputil.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/h264qpel.h"
 #include "libavcodec/mpegvideo.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_YASM
-void ff_put_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_put_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-void ff_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, int line_size, int h);
-static void ff_put_pixels16_mmxext(uint8_t *block, const uint8_t *pixels,
-                                   int line_size, int h)
-{
-    ff_put_pixels8_mmxext(block,     pixels,     line_size, h);
-    ff_put_pixels8_mmxext(block + 8, pixels + 8, line_size, h);
-}
-static void ff_avg_pixels16_mmxext(uint8_t *block, const uint8_t *pixels,
-                                   int line_size, int h)
-{
-    ff_avg_pixels8_mmxext(block,     pixels,     line_size, h);
-    ff_avg_pixels8_mmxext(block + 8, pixels + 8, line_size, h);
-}
+void ff_put_pixels4_mmxext(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h);
+void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h);
 void ff_put_pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
                               int dstStride, int src1Stride, int h);
 void ff_avg_pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
@@ -54,15 +44,14 @@ void ff_put_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
                                int dstStride, int src1Stride, int h);
 void ff_avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
                                int dstStride, int src1Stride, int h);
-void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels,
-                          int line_size, int h);
-void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels,
-                          int line_size, int h);
 #define ff_put_pixels8_l2_sse2  ff_put_pixels8_l2_mmxext
 #define ff_avg_pixels8_l2_sse2  ff_avg_pixels8_l2_mmxext
 #define ff_put_pixels16_l2_sse2 ff_put_pixels16_l2_mmxext
 #define ff_avg_pixels16_l2_sse2 ff_avg_pixels16_l2_mmxext
 
+PIXELS16(static, ff_avg, , , _mmxext)
+PIXELS16(static, ff_put, , , _mmxext)
+
 #define DEF_QPEL(OPNAME)\
 void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, int dstStride, int srcStride);\
 void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src, int dstStride, int srcStride);\
@@ -208,7 +197,12 @@ static av_always_inline void ff_ ## OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint
     ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\
 }
 
-static av_always_inline void ff_put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, uint8_t *src, int tmpStride, int srcStride, int size){
+static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp,
+                                                                 uint8_t *src,
+                                                                 int tmpStride,
+                                                                 int srcStride,
+                                                                 int size)
+{
     int w = (size+8)>>3;
     src -= 2*srcStride+2;
     while(w--){
@@ -220,7 +214,7 @@ static av_always_inline void ff_put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp
 
 #define QPEL_H264_HV_XMM(OPNAME, OP, MMX)\
 static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\
-    ff_put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\
+    put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\
     ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\
 }\
 static av_always_inline void ff_ ## OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\
@@ -249,81 +243,98 @@ H264_MC_V(OPNAME, SIZE, MMX, ALIGN)\
 H264_MC_H(OPNAME, SIZE, MMX, ALIGN)\
 H264_MC_HV(OPNAME, SIZE, MMX, ALIGN)\
 
-static void put_h264_qpel16_mc00_sse2 (uint8_t *dst, uint8_t *src, int stride){
+static void put_h264_qpel16_mc00_sse2 (uint8_t *dst, uint8_t *src,
+                                       ptrdiff_t stride)
+{
     ff_put_pixels16_sse2(dst, src, stride, 16);
 }
-static void avg_h264_qpel16_mc00_sse2 (uint8_t *dst, uint8_t *src, int stride){
+static void avg_h264_qpel16_mc00_sse2 (uint8_t *dst, uint8_t *src,
+                                       ptrdiff_t stride)
+{
     ff_avg_pixels16_sse2(dst, src, stride, 16);
 }
 #define put_h264_qpel8_mc00_sse2 put_h264_qpel8_mc00_mmxext
 #define avg_h264_qpel8_mc00_sse2 avg_h264_qpel8_mc00_mmxext
 
 #define H264_MC_C(OPNAME, SIZE, MMX, ALIGN) \
-static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## MMX (uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## MMX (uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     ff_ ## OPNAME ## pixels ## SIZE ## _ ## MMX(dst, src, stride, SIZE);\
 }\
 
 #define H264_MC_H(OPNAME, SIZE, MMX, ALIGN) \
-static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src, stride, stride);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## MMX(dst, src, stride, stride);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src+1, stride, stride);\
 }\
 
 #define H264_MC_V(OPNAME, SIZE, MMX, ALIGN) \
-static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\
     ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\
     ff_ ## OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src, temp, stride, stride, SIZE);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## MMX(dst, src, stride, stride);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\
     ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\
     ff_ ## OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src+stride, temp, stride, stride, SIZE);\
 }\
 
 #define H264_MC_HV(OPNAME, SIZE, MMX, ALIGN) \
-static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\
     ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\
     ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\
     ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*SIZE];\
     ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint16_t, temp)[SIZE*(SIZE<8?12:24)];\
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(dst, temp, src, stride, SIZE, stride);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\
     uint8_t * const halfHV= temp;\
     int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\
@@ -332,7 +343,8 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, uint8_t *
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfHV, stride, SIZE);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\
     uint8_t * const halfHV= temp;\
     int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\
@@ -341,7 +353,8 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst, uint8_t *
     ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfHV, stride, SIZE);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\
     uint8_t * const halfHV= temp;\
     int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\
@@ -350,7 +363,8 @@ static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## MMX(uint8_t *dst, uint8_t *
     ff_ ## OPNAME ## pixels ## SIZE ## _l2_shift5_mmxext(dst, halfV+2, halfHV, stride, SIZE, SIZE);\
 }\
 \
-static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride)\
+{\
     DECLARE_ALIGNED(ALIGN, uint8_t, temp)[SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE];\
     uint8_t * const halfHV= temp;\
     int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\
@@ -373,8 +387,6 @@ QPEL(put_, 16,XMM, 16)\
 QPEL(avg_, 8, XMM, 16)\
 QPEL(avg_, 16,XMM, 16)\
 
-#undef PAVGB
-#define PAVGB "pavgb"
 QPEL_H264(put_,        PUT_OP, mmxext)
 QPEL_H264(avg_, AVG_MMXEXT_OP, mmxext)
 QPEL_H264_V_XMM(put_,       PUT_OP, sse2)
@@ -385,7 +397,6 @@ QPEL_H264_H_XMM(put_,       PUT_OP, ssse3)
 QPEL_H264_H_XMM(avg_,AVG_MMXEXT_OP, ssse3)
 QPEL_H264_HV_XMM(put_,       PUT_OP, ssse3)
 QPEL_H264_HV_XMM(avg_,AVG_MMXEXT_OP, ssse3)
-#undef PAVGB
 
 H264_MC_4816(mmxext)
 H264_MC_816(H264_MC_V, sse2)
@@ -397,7 +408,7 @@ H264_MC_816(H264_MC_HV, ssse3)
 //10bit
 #define LUMA_MC_OP(OP, NUM, DEPTH, TYPE, OPT) \
 void ff_ ## OP ## _h264_qpel ## NUM ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT \
-    (uint8_t *dst, uint8_t *src, int stride);
+    (uint8_t *dst, uint8_t *src, ptrdiff_t stride);
 
 #define LUMA_MC_ALL(DEPTH, TYPE, OPT) \
     LUMA_MC_OP(put,  4, DEPTH, TYPE, OPT) \
@@ -454,7 +465,7 @@ LUMA_MC_816(10, mc23, sse2)
 LUMA_MC_816(10, mc33, sse2)
 
 #define QPEL16_OPMC(OP, MC, MMX)\
-void ff_ ## OP ## _h264_qpel16_ ## MC ## _10_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\
+void ff_ ## OP ## _h264_qpel16_ ## MC ## _10_ ## MMX(uint8_t *dst, uint8_t *src, ptrdiff_t stride){\
     ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst   , src   , stride);\
     ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst+16, src+16, stride);\
     src += 8*stride;\
@@ -490,3 +501,134 @@ QPEL16(mmxext)
 #endif
 
 #endif /* HAVE_YASM */
+
+#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX)                          \
+    do {                                                                     \
+    c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \
+    c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \
+    } while (0)
+
+#define H264_QPEL_FUNCS(x, y, CPU)                                                            \
+    do {                                                                                      \
+        c->put_h264_qpel_pixels_tab[0][x + y * 4] = put_h264_qpel16_mc ## x ## y ## _ ## CPU; \
+        c->put_h264_qpel_pixels_tab[1][x + y * 4] = put_h264_qpel8_mc  ## x ## y ## _ ## CPU; \
+        c->avg_h264_qpel_pixels_tab[0][x + y * 4] = avg_h264_qpel16_mc ## x ## y ## _ ## CPU; \
+        c->avg_h264_qpel_pixels_tab[1][x + y * 4] = avg_h264_qpel8_mc  ## x ## y ## _ ## CPU; \
+    } while (0)
+
+#define H264_QPEL_FUNCS_10(x, y, CPU)                                                               \
+    do {                                                                                            \
+        c->put_h264_qpel_pixels_tab[0][x + y * 4] = ff_put_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \
+        c->put_h264_qpel_pixels_tab[1][x + y * 4] = ff_put_h264_qpel8_mc  ## x ## y ## _10_ ## CPU; \
+        c->avg_h264_qpel_pixels_tab[0][x + y * 4] = ff_avg_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \
+        c->avg_h264_qpel_pixels_tab[1][x + y * 4] = ff_avg_h264_qpel8_mc  ## x ## y ## _10_ ## CPU; \
+    } while (0)
+
+av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth)
+{
+#if HAVE_YASM
+    int high_bit_depth = bit_depth > 8;
+    int cpu_flags = av_get_cpu_flags();
+
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
+        if (!high_bit_depth) {
+            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmxext, );
+            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, mmxext, );
+            SET_QPEL_FUNCS(put_h264_qpel, 2,  4, mmxext, );
+            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmxext, );
+            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, mmxext, );
+            SET_QPEL_FUNCS(avg_h264_qpel, 2,  4, mmxext, );
+        } else if (bit_depth == 10) {
+#if ARCH_X86_32
+            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_mmxext, ff_);
+            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_mmxext, ff_);
+            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_mmxext, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_mmxext, ff_);
+#endif
+            SET_QPEL_FUNCS(put_h264_qpel, 2, 4,  10_mmxext, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 2, 4,  10_mmxext, ff_);
+        }
+    }
+
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && !high_bit_depth) {
+            // these functions are slower than mmx on AMD, but faster on Intel
+            H264_QPEL_FUNCS(0, 0, sse2);
+        }
+
+        if (!high_bit_depth) {
+            H264_QPEL_FUNCS(0, 1, sse2);
+            H264_QPEL_FUNCS(0, 2, sse2);
+            H264_QPEL_FUNCS(0, 3, sse2);
+            H264_QPEL_FUNCS(1, 1, sse2);
+            H264_QPEL_FUNCS(1, 2, sse2);
+            H264_QPEL_FUNCS(1, 3, sse2);
+            H264_QPEL_FUNCS(2, 1, sse2);
+            H264_QPEL_FUNCS(2, 2, sse2);
+            H264_QPEL_FUNCS(2, 3, sse2);
+            H264_QPEL_FUNCS(3, 1, sse2);
+            H264_QPEL_FUNCS(3, 2, sse2);
+            H264_QPEL_FUNCS(3, 3, sse2);
+        }
+
+        if (bit_depth == 10) {
+            SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_sse2, ff_);
+            SET_QPEL_FUNCS(put_h264_qpel, 1,  8, 10_sse2, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_sse2, ff_);
+            SET_QPEL_FUNCS(avg_h264_qpel, 1,  8, 10_sse2, ff_);
+            H264_QPEL_FUNCS_10(1, 0, sse2_cache64);
+            H264_QPEL_FUNCS_10(2, 0, sse2_cache64);
+            H264_QPEL_FUNCS_10(3, 0, sse2_cache64);
+        }
+    }
+
+    if (EXTERNAL_SSSE3(cpu_flags)) {
+        if (!high_bit_depth) {
+            H264_QPEL_FUNCS(1, 0, ssse3);
+            H264_QPEL_FUNCS(1, 1, ssse3);
+            H264_QPEL_FUNCS(1, 2, ssse3);
+            H264_QPEL_FUNCS(1, 3, ssse3);
+            H264_QPEL_FUNCS(2, 0, ssse3);
+            H264_QPEL_FUNCS(2, 1, ssse3);
+            H264_QPEL_FUNCS(2, 2, ssse3);
+            H264_QPEL_FUNCS(2, 3, ssse3);
+            H264_QPEL_FUNCS(3, 0, ssse3);
+            H264_QPEL_FUNCS(3, 1, ssse3);
+            H264_QPEL_FUNCS(3, 2, ssse3);
+            H264_QPEL_FUNCS(3, 3, ssse3);
+        }
+
+        if (bit_depth == 10) {
+            H264_QPEL_FUNCS_10(1, 0, ssse3_cache64);
+            H264_QPEL_FUNCS_10(2, 0, ssse3_cache64);
+            H264_QPEL_FUNCS_10(3, 0, ssse3_cache64);
+        }
+    }
+
+    if (EXTERNAL_AVX(cpu_flags)) {
+        /* AVX implies 64 byte cache lines without the need to avoid unaligned
+         * memory accesses that cross the boundary between two cache lines.
+         * TODO: Port X264_CPU_CACHELINE_32/64 detection from x264 to avoid
+         * having to treat SSE2 functions with such properties as AVX. */
+        if (bit_depth == 10) {
+            H264_QPEL_FUNCS_10(1, 0, sse2);
+            H264_QPEL_FUNCS_10(2, 0, sse2);
+            H264_QPEL_FUNCS_10(3, 0, sse2);
+        }
+    }
+#endif
+}
diff --git a/libavcodec/x86/h264chroma_init.c b/libavcodec/x86/h264chroma_init.c
new file mode 100644
index 0000000..eec1653
--- /dev/null
+++ b/libavcodec/x86/h264chroma_init.c
@@ -0,0 +1,119 @@
+/*
+ * 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 "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/h264chroma.h"
+
+void ff_put_h264_chroma_mc8_rnd_mmx  (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc8_rnd_mmxext(uint8_t *dst, uint8_t *src,
+                                       int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc8_rnd_3dnow(uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+void ff_put_h264_chroma_mc4_mmx      (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc4_mmxext   (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc4_3dnow    (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+void ff_put_h264_chroma_mc2_mmxext   (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc2_mmxext   (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+void ff_put_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_put_h264_chroma_mc4_ssse3    (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+void ff_avg_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+void ff_avg_h264_chroma_mc4_ssse3    (uint8_t *dst, uint8_t *src,
+                                      int stride, int h, int x, int y);
+
+#define CHROMA_MC(OP, NUM, DEPTH, OPT)                                  \
+void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT      \
+                                      (uint8_t *dst, uint8_t *src,      \
+                                       int stride, int h, int x, int y);
+
+CHROMA_MC(put, 2, 10, mmxext)
+CHROMA_MC(avg, 2, 10, mmxext)
+CHROMA_MC(put, 4, 10, mmxext)
+CHROMA_MC(avg, 4, 10, mmxext)
+CHROMA_MC(put, 8, 10, sse2)
+CHROMA_MC(avg, 8, 10, sse2)
+CHROMA_MC(put, 8, 10, avx)
+CHROMA_MC(avg, 8, 10, avx)
+
+av_cold void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth)
+{
+#if HAVE_YASM
+    int high_bit_depth = bit_depth > 8;
+    int cpu_flags      = av_get_cpu_flags();
+
+    if (EXTERNAL_MMX(cpu_flags) && !high_bit_depth) {
+        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_mmx;
+        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmx;
+    }
+
+    if (EXTERNAL_AMD3DNOW(cpu_flags) && !high_bit_depth) {
+        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_3dnow;
+        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_3dnow;
+    }
+
+    if (EXTERNAL_MMXEXT(cpu_flags) && !high_bit_depth) {
+        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_mmxext;
+        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmxext;
+        c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_mmxext;
+        c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_mmxext;
+    }
+
+    if (EXTERNAL_MMXEXT(cpu_flags) && bit_depth > 8 && bit_depth <= 10) {
+        c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_10_mmxext;
+        c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_10_mmxext;
+        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_10_mmxext;
+        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_10_mmxext;
+    }
+
+    if (EXTERNAL_SSE2(cpu_flags) && bit_depth > 8 && bit_depth <= 10) {
+        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_sse2;
+        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_sse2;
+    }
+
+    if (EXTERNAL_SSSE3(cpu_flags) && !high_bit_depth) {
+        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_ssse3;
+        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_ssse3;
+        c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_ssse3;
+        c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_ssse3;
+    }
+
+    if (EXTERNAL_AVX(cpu_flags) && bit_depth > 8 && bit_depth <= 10) {
+        // AVX implies !cache64.
+        // TODO: Port cache(32|64) detection from x264.
+        c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_avx;
+        c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx;
+    }
+#endif
+}
diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c
index 73d4990..4164b83 100644
--- a/libavcodec/x86/h264dsp_init.c
+++ b/libavcodec/x86/h264dsp_init.c
@@ -18,11 +18,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/h264dsp.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 /***********************************/
 /* IDCT */
@@ -48,7 +49,7 @@ IDCT_ADD_FUNC(8, 10, avx)
 #define IDCT_ADD_REP_FUNC(NUM, REP, DEPTH, OPT)                         \
 void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT       \
     (uint8_t *dst, const int *block_offset,                             \
-     DCTELEM *block, int stride, const uint8_t nnzc[6 * 8]);
+     int16_t *block, int stride, const uint8_t nnzc[6 * 8]);
 
 IDCT_ADD_REP_FUNC(8, 4, 8, mmx)
 IDCT_ADD_REP_FUNC(8, 4, 8, mmxext)
@@ -70,7 +71,7 @@ IDCT_ADD_REP_FUNC(, 16intra, 10, avx)
 #define IDCT_ADD_REP_FUNC2(NUM, REP, DEPTH, OPT)                      \
 void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT     \
     (uint8_t **dst, const int *block_offset,                          \
-     DCTELEM *block, int stride, const uint8_t nnzc[6 * 8]);
+     int16_t *block, int stride, const uint8_t nnzc[6 * 8]);
 
 IDCT_ADD_REP_FUNC2(, 8, 8, mmx)
 IDCT_ADD_REP_FUNC2(, 8, 8, mmxext)
@@ -78,8 +79,8 @@ IDCT_ADD_REP_FUNC2(, 8, 8, sse2)
 IDCT_ADD_REP_FUNC2(, 8, 10, sse2)
 IDCT_ADD_REP_FUNC2(, 8, 10, avx)
 
-void ff_h264_luma_dc_dequant_idct_mmx(DCTELEM *output, DCTELEM *input, int qmul);
-void ff_h264_luma_dc_dequant_idct_sse2(DCTELEM *output, DCTELEM *input, int qmul);
+void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul);
+void ff_h264_luma_dc_dequant_idct_sse2(int16_t *output, int16_t *input, int qmul);
 
 /***********************************/
 /* deblocking */
@@ -131,8 +132,8 @@ LF_FUNCS(uint16_t, 10)
 
 #if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL
 LF_FUNC(v8, luma, 8, mmxext)
-static void ff_deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha,
-                                       int beta, int8_t *tc0)
+static void deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha,
+                                    int beta, int8_t *tc0)
 {
     if ((tc0[0] & tc0[1]) >= 0)
         ff_deblock_v8_luma_8_mmxext(pix + 0, stride, alpha, beta, tc0);
@@ -140,8 +141,8 @@ static void ff_deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha,
         ff_deblock_v8_luma_8_mmxext(pix + 8, stride, alpha, beta, tc0 + 2);
 }
 LF_IFUNC(v8, luma_intra, 8, mmxext)
-static void ff_deblock_v_luma_intra_8_mmxext(uint8_t *pix, int stride,
-                                             int alpha, int beta)
+static void deblock_v_luma_intra_8_mmxext(uint8_t *pix, int stride,
+                                          int alpha, int beta)
 {
     ff_deblock_v8_luma_intra_8_mmxext(pix + 0, stride, alpha, beta);
     ff_deblock_v8_luma_intra_8_mmxext(pix + 8, stride, alpha, beta);
@@ -207,16 +208,16 @@ H264_BIWEIGHT_10_SSE(16, 10)
 H264_BIWEIGHT_10_SSE(8,  10)
 H264_BIWEIGHT_10_SSE(4,  10)
 
-void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
-                         const int chroma_format_idc)
+av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
+                                 const int chroma_format_idc)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (chroma_format_idc == 1 && EXTERNAL_MMXEXT(mm_flags))
+    if (chroma_format_idc == 1 && EXTERNAL_MMXEXT(cpu_flags))
         c->h264_loop_filter_strength = ff_h264_loop_filter_strength_mmxext;
 
     if (bit_depth == 8) {
-        if (EXTERNAL_MMX(mm_flags)) {
+        if (EXTERNAL_MMX(cpu_flags)) {
             c->h264_idct_dc_add   =
             c->h264_idct_add      = ff_h264_idct_add_8_mmx;
             c->h264_idct8_dc_add  =
@@ -227,146 +228,142 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth,
             if (chroma_format_idc == 1)
                 c->h264_idct_add8 = ff_h264_idct_add8_8_mmx;
             c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx;
-            if (mm_flags & AV_CPU_FLAG_CMOV)
+            if (cpu_flags & AV_CPU_FLAG_CMOV)
                 c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_mmx;
-
-            if (EXTERNAL_MMXEXT(mm_flags)) {
-                c->h264_idct_dc_add  = ff_h264_idct_dc_add_8_mmxext;
-                c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext;
-                c->h264_idct_add16   = ff_h264_idct_add16_8_mmxext;
-                c->h264_idct8_add4   = ff_h264_idct8_add4_8_mmxext;
-                if (chroma_format_idc == 1)
-                    c->h264_idct_add8 = ff_h264_idct_add8_8_mmxext;
-                c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmxext;
-
-                c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_8_mmxext;
-                c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmxext;
-                if (chroma_format_idc == 1) {
-                    c->h264_h_loop_filter_chroma       = ff_deblock_h_chroma_8_mmxext;
-                    c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_mmxext;
-                }
+        }
+        if (EXTERNAL_MMXEXT(cpu_flags)) {
+            c->h264_idct_dc_add  = ff_h264_idct_dc_add_8_mmxext;
+            c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext;
+            c->h264_idct_add16   = ff_h264_idct_add16_8_mmxext;
+            c->h264_idct8_add4   = ff_h264_idct8_add4_8_mmxext;
+            if (chroma_format_idc == 1)
+                c->h264_idct_add8 = ff_h264_idct_add8_8_mmxext;
+            c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmxext;
+
+            c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_8_mmxext;
+            c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmxext;
+            if (chroma_format_idc == 1) {
+                c->h264_h_loop_filter_chroma       = ff_deblock_h_chroma_8_mmxext;
+                c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_mmxext;
+            }
 #if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL
-                c->h264_v_loop_filter_luma       = ff_deblock_v_luma_8_mmxext;
-                c->h264_h_loop_filter_luma       = ff_deblock_h_luma_8_mmxext;
-                c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_mmxext;
-                c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmxext;
+            c->h264_v_loop_filter_luma       = deblock_v_luma_8_mmxext;
+            c->h264_h_loop_filter_luma       = ff_deblock_h_luma_8_mmxext;
+            c->h264_v_loop_filter_luma_intra = deblock_v_luma_intra_8_mmxext;
+            c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmxext;
 #endif /* ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL */
-                c->weight_h264_pixels_tab[0] = ff_h264_weight_16_mmxext;
-                c->weight_h264_pixels_tab[1] = ff_h264_weight_8_mmxext;
-                c->weight_h264_pixels_tab[2] = ff_h264_weight_4_mmxext;
-
-                c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_mmxext;
-                c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_mmxext;
-                c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_mmxext;
-
-                if (EXTERNAL_SSE2(mm_flags)) {
-                    c->h264_idct8_add  = ff_h264_idct8_add_8_sse2;
-
-                    c->h264_idct_add16 = ff_h264_idct_add16_8_sse2;
-                    c->h264_idct8_add4 = ff_h264_idct8_add4_8_sse2;
-                    if (chroma_format_idc == 1)
-                        c->h264_idct_add8 = ff_h264_idct_add8_8_sse2;
-                    c->h264_idct_add16intra      = ff_h264_idct_add16intra_8_sse2;
-                    c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_sse2;
-
-                    c->weight_h264_pixels_tab[0] = ff_h264_weight_16_sse2;
-                    c->weight_h264_pixels_tab[1] = ff_h264_weight_8_sse2;
-
-                    c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_sse2;
-                    c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_sse2;
-
-                    c->h264_v_loop_filter_luma       = ff_deblock_v_luma_8_sse2;
-                    c->h264_h_loop_filter_luma       = ff_deblock_h_luma_8_sse2;
-                    c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_sse2;
-                    c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_sse2;
-                }
-                if (EXTERNAL_SSSE3(mm_flags)) {
-                    c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_ssse3;
-                    c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_ssse3;
-                }
-                if (EXTERNAL_AVX(mm_flags)) {
-                    c->h264_v_loop_filter_luma       = ff_deblock_v_luma_8_avx;
-                    c->h264_h_loop_filter_luma       = ff_deblock_h_luma_8_avx;
-                    c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_avx;
-                    c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_avx;
-                }
-            }
+            c->weight_h264_pixels_tab[0] = ff_h264_weight_16_mmxext;
+            c->weight_h264_pixels_tab[1] = ff_h264_weight_8_mmxext;
+            c->weight_h264_pixels_tab[2] = ff_h264_weight_4_mmxext;
+
+            c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_mmxext;
+            c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_mmxext;
+            c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_mmxext;
+        }
+        if (EXTERNAL_SSE2(cpu_flags)) {
+            c->h264_idct8_add  = ff_h264_idct8_add_8_sse2;
+
+            c->h264_idct_add16 = ff_h264_idct_add16_8_sse2;
+            c->h264_idct8_add4 = ff_h264_idct8_add4_8_sse2;
+            if (chroma_format_idc == 1)
+                c->h264_idct_add8 = ff_h264_idct_add8_8_sse2;
+            c->h264_idct_add16intra      = ff_h264_idct_add16intra_8_sse2;
+            c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_sse2;
+
+            c->weight_h264_pixels_tab[0] = ff_h264_weight_16_sse2;
+            c->weight_h264_pixels_tab[1] = ff_h264_weight_8_sse2;
+
+            c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_sse2;
+            c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_sse2;
+
+            c->h264_v_loop_filter_luma       = ff_deblock_v_luma_8_sse2;
+            c->h264_h_loop_filter_luma       = ff_deblock_h_luma_8_sse2;
+            c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_sse2;
+            c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_sse2;
+        }
+        if (EXTERNAL_SSSE3(cpu_flags)) {
+            c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_ssse3;
+            c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_ssse3;
+        }
+        if (EXTERNAL_AVX(cpu_flags)) {
+            c->h264_v_loop_filter_luma       = ff_deblock_v_luma_8_avx;
+            c->h264_h_loop_filter_luma       = ff_deblock_h_luma_8_avx;
+            c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_avx;
+            c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_avx;
         }
     } else if (bit_depth == 10) {
-        if (EXTERNAL_MMX(mm_flags)) {
-            if (EXTERNAL_MMXEXT(mm_flags)) {
+        if (EXTERNAL_MMXEXT(cpu_flags)) {
 #if ARCH_X86_32
-                c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_10_mmxext;
-                c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_mmxext;
-                c->h264_v_loop_filter_luma         = ff_deblock_v_luma_10_mmxext;
-                c->h264_h_loop_filter_luma         = ff_deblock_h_luma_10_mmxext;
-                c->h264_v_loop_filter_luma_intra   = ff_deblock_v_luma_intra_10_mmxext;
-                c->h264_h_loop_filter_luma_intra   = ff_deblock_h_luma_intra_10_mmxext;
+            c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_10_mmxext;
+            c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_mmxext;
+            c->h264_v_loop_filter_luma         = ff_deblock_v_luma_10_mmxext;
+            c->h264_h_loop_filter_luma         = ff_deblock_h_luma_10_mmxext;
+            c->h264_v_loop_filter_luma_intra   = ff_deblock_v_luma_intra_10_mmxext;
+            c->h264_h_loop_filter_luma_intra   = ff_deblock_h_luma_intra_10_mmxext;
 #endif /* ARCH_X86_32 */
-                c->h264_idct_dc_add = ff_h264_idct_dc_add_10_mmxext;
-                if (EXTERNAL_SSE2(mm_flags)) {
-                    c->h264_idct_add     = ff_h264_idct_add_10_sse2;
-                    c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2;
-
-                    c->h264_idct_add16 = ff_h264_idct_add16_10_sse2;
-                    if (chroma_format_idc == 1)
-                        c->h264_idct_add8 = ff_h264_idct_add8_10_sse2;
-                    c->h264_idct_add16intra = ff_h264_idct_add16intra_10_sse2;
+            c->h264_idct_dc_add = ff_h264_idct_dc_add_10_mmxext;
+        }
+        if (EXTERNAL_SSE2(cpu_flags)) {
+            c->h264_idct_add     = ff_h264_idct_add_10_sse2;
+            c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2;
+
+            c->h264_idct_add16 = ff_h264_idct_add16_10_sse2;
+            if (chroma_format_idc == 1)
+                c->h264_idct_add8 = ff_h264_idct_add8_10_sse2;
+            c->h264_idct_add16intra = ff_h264_idct_add16intra_10_sse2;
 #if HAVE_ALIGNED_STACK
-                    c->h264_idct8_add  = ff_h264_idct8_add_10_sse2;
-                    c->h264_idct8_add4 = ff_h264_idct8_add4_10_sse2;
+            c->h264_idct8_add  = ff_h264_idct8_add_10_sse2;
+            c->h264_idct8_add4 = ff_h264_idct8_add4_10_sse2;
 #endif /* HAVE_ALIGNED_STACK */
 
-                    c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse2;
-                    c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse2;
-                    c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse2;
+            c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse2;
+            c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse2;
+            c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse2;
 
-                    c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse2;
-                    c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse2;
-                    c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse2;
+            c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse2;
+            c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse2;
+            c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse2;
 
-                    c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_10_sse2;
-                    c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_sse2;
+            c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_10_sse2;
+            c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_sse2;
 #if HAVE_ALIGNED_STACK
-                    c->h264_v_loop_filter_luma       = ff_deblock_v_luma_10_sse2;
-                    c->h264_h_loop_filter_luma       = ff_deblock_h_luma_10_sse2;
-                    c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_sse2;
-                    c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_sse2;
+            c->h264_v_loop_filter_luma       = ff_deblock_v_luma_10_sse2;
+            c->h264_h_loop_filter_luma       = ff_deblock_h_luma_10_sse2;
+            c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_sse2;
+            c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_sse2;
 #endif /* HAVE_ALIGNED_STACK */
-                }
-                if (EXTERNAL_SSE4(mm_flags)) {
-                    c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse4;
-                    c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse4;
-                    c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse4;
-
-                    c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse4;
-                    c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse4;
-                    c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse4;
-                }
-                if (EXTERNAL_AVX(mm_flags)) {
-                    c->h264_idct_dc_add  =
-                    c->h264_idct_add     = ff_h264_idct_add_10_avx;
-                    c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx;
-
-                    c->h264_idct_add16 = ff_h264_idct_add16_10_avx;
-                    if (chroma_format_idc == 1)
-                        c->h264_idct_add8 = ff_h264_idct_add8_10_avx;
-                    c->h264_idct_add16intra = ff_h264_idct_add16intra_10_avx;
+        }
+        if (EXTERNAL_SSE4(cpu_flags)) {
+            c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse4;
+            c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse4;
+            c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse4;
+
+            c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse4;
+            c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse4;
+            c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse4;
+        }
+        if (EXTERNAL_AVX(cpu_flags)) {
+            c->h264_idct_dc_add  =
+            c->h264_idct_add     = ff_h264_idct_add_10_avx;
+            c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx;
+
+            c->h264_idct_add16 = ff_h264_idct_add16_10_avx;
+            if (chroma_format_idc == 1)
+                c->h264_idct_add8 = ff_h264_idct_add8_10_avx;
+            c->h264_idct_add16intra = ff_h264_idct_add16intra_10_avx;
 #if HAVE_ALIGNED_STACK
-                    c->h264_idct8_add  = ff_h264_idct8_add_10_avx;
-                    c->h264_idct8_add4 = ff_h264_idct8_add4_10_avx;
+            c->h264_idct8_add  = ff_h264_idct8_add_10_avx;
+            c->h264_idct8_add4 = ff_h264_idct8_add4_10_avx;
 #endif /* HAVE_ALIGNED_STACK */
 
-                    c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_10_avx;
-                    c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_avx;
+            c->h264_v_loop_filter_chroma       = ff_deblock_v_chroma_10_avx;
+            c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_avx;
 #if HAVE_ALIGNED_STACK
-                    c->h264_v_loop_filter_luma         = ff_deblock_v_luma_10_avx;
-                    c->h264_h_loop_filter_luma         = ff_deblock_h_luma_10_avx;
-                    c->h264_v_loop_filter_luma_intra   = ff_deblock_v_luma_intra_10_avx;
-                    c->h264_h_loop_filter_luma_intra   = ff_deblock_h_luma_intra_10_avx;
+            c->h264_v_loop_filter_luma         = ff_deblock_v_luma_10_avx;
+            c->h264_h_loop_filter_luma         = ff_deblock_h_luma_10_avx;
+            c->h264_v_loop_filter_luma_intra   = ff_deblock_v_luma_intra_10_avx;
+            c->h264_h_loop_filter_luma_intra   = ff_deblock_h_luma_intra_10_avx;
 #endif /* HAVE_ALIGNED_STACK */
-                }
-            }
         }
     }
 }
diff --git a/libavcodec/x86/hpeldsp.asm b/libavcodec/x86/hpeldsp.asm
new file mode 100644
index 0000000..ff6e57a
--- /dev/null
+++ b/libavcodec/x86/hpeldsp.asm
@@ -0,0 +1,454 @@
+;******************************************************************************
+;* MMX optimized hpel functions
+;*
+;* 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/x86util.asm"
+
+SECTION_RODATA
+cextern pb_1
+
+SECTION_TEXT
+
+; put_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_PIXELS8_X2 0
+cglobal put_pixels8_x2, 4,5
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+r2]
+    PAVGB        m0, [r1+1]
+    PAVGB        m1, [r1+r2+1]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    add          r1, r4
+    add          r0, r4
+    mova         m0, [r1]
+    mova         m1, [r1+r2]
+    PAVGB        m0, [r1+1]
+    PAVGB        m1, [r1+r2+1]
+    add          r1, r4
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_PIXELS8_X2
+INIT_MMX 3dnow
+PUT_PIXELS8_X2
+
+
+; put_pixels16_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_PIXELS_16 0
+cglobal put_pixels16_x2, 4,5
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+r2]
+    mova         m2, [r1+8]
+    mova         m3, [r1+r2+8]
+    PAVGB        m0, [r1+1]
+    PAVGB        m1, [r1+r2+1]
+    PAVGB        m2, [r1+9]
+    PAVGB        m3, [r1+r2+9]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova     [r0+8], m2
+    mova  [r0+r2+8], m3
+    add          r1, r4
+    add          r0, r4
+    mova         m0, [r1]
+    mova         m1, [r1+r2]
+    mova         m2, [r1+8]
+    mova         m3, [r1+r2+8]
+    PAVGB        m0, [r1+1]
+    PAVGB        m1, [r1+r2+1]
+    PAVGB        m2, [r1+9]
+    PAVGB        m3, [r1+r2+9]
+    add          r1, r4
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova     [r0+8], m2
+    mova  [r0+r2+8], m3
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_PIXELS_16
+INIT_MMX 3dnow
+PUT_PIXELS_16
+
+
+; put_no_rnd_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_NO_RND_PIXELS8_X2 0
+cglobal put_no_rnd_pixels8_x2, 4,5
+    mova         m6, [pb_1]
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    mova         m1, [r1+1]
+    mova         m3, [r1+r2+1]
+    add          r1, r4
+    psubusb      m0, m6
+    psubusb      m2, m6
+    PAVGB        m0, m1
+    PAVGB        m2, m3
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    mova         m0, [r1]
+    mova         m1, [r1+1]
+    mova         m2, [r1+r2]
+    mova         m3, [r1+r2+1]
+    add          r0, r4
+    add          r1, r4
+    psubusb      m0, m6
+    psubusb      m2, m6
+    PAVGB        m0, m1
+    PAVGB        m2, m3
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_X2
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS8_X2
+
+
+; put_no_rnd_pixels8_x2_exact(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_NO_RND_PIXELS8_X2_EXACT 0
+cglobal put_no_rnd_pixels8_x2_exact, 4,5
+    lea          r4, [r2*3]
+    pcmpeqb      m6, m6
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    mova         m1, [r1+1]
+    mova         m3, [r1+r2+1]
+    pxor         m0, m6
+    pxor         m2, m6
+    pxor         m1, m6
+    pxor         m3, m6
+    PAVGB        m0, m1
+    PAVGB        m2, m3
+    pxor         m0, m6
+    pxor         m2, m6
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    mova         m0, [r1+r2*2]
+    mova         m1, [r1+r2*2+1]
+    mova         m2, [r1+r4]
+    mova         m3, [r1+r4+1]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m1
+    PAVGB        m2, m3
+    pxor         m0, m6
+    pxor         m2, m6
+    mova  [r0+r2*2], m0
+    mova    [r0+r4], m2
+    lea          r1, [r1+r2*4]
+    lea          r0, [r0+r2*4]
+    sub         r3d, 4
+    jg .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_X2_EXACT
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS8_X2_EXACT
+
+
+; put_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_PIXELS8_Y2 0
+cglobal put_pixels8_y2, 4,5
+    lea          r4, [r2*2]
+    mova         m0, [r1]
+    sub          r0, r2
+.loop:
+    mova         m1, [r1+r2]
+    mova         m2, [r1+r4]
+    add          r1, r4
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    mova    [r0+r2], m0
+    mova    [r0+r4], m1
+    mova         m1, [r1+r2]
+    mova         m0, [r1+r4]
+    add          r0, r4
+    add          r1, r4
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    mova    [r0+r2], m2
+    mova    [r0+r4], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_PIXELS8_Y2
+INIT_MMX 3dnow
+PUT_PIXELS8_Y2
+
+
+; put_no_rnd_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_NO_RND_PIXELS8_Y2 0
+cglobal put_no_rnd_pixels8_y2, 4,5
+    mova         m6, [pb_1]
+    lea          r4, [r2+r2]
+    mova         m0, [r1]
+    sub          r0, r2
+.loop:
+    mova         m1, [r1+r2]
+    mova         m2, [r1+r4]
+    add          r1, r4
+    psubusb      m1, m6
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    mova    [r0+r2], m0
+    mova    [r0+r4], m1
+    mova         m1, [r1+r2]
+    mova         m0, [r1+r4]
+    add          r0, r4
+    add          r1, r4
+    psubusb      m1, m6
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    mova    [r0+r2], m2
+    mova    [r0+r4], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_Y2
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS8_Y2
+
+
+; put_no_rnd_pixels8_y2_exact(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro PUT_NO_RND_PIXELS8_Y2_EXACT 0
+cglobal put_no_rnd_pixels8_y2_exact, 4,5
+    lea          r4, [r2*3]
+    mova         m0, [r1]
+    pcmpeqb      m6, m6
+    add          r1, r2
+    pxor         m0, m6
+.loop:
+    mova         m1, [r1]
+    mova         m2, [r1+r2]
+    pxor         m1, m6
+    pxor         m2, m6
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova         m1, [r1+r2*2]
+    mova         m0, [r1+r4]
+    pxor         m1, m6
+    pxor         m0, m6
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    pxor         m2, m6
+    pxor         m1, m6
+    mova  [r0+r2*2], m2
+    mova    [r0+r4], m1
+    lea          r1, [r1+r2*4]
+    lea          r0, [r0+r2*4]
+    sub         r3d, 4
+    jg .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_Y2_EXACT
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS8_Y2_EXACT
+
+
+; avg_pixels8(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro AVG_PIXELS8 0
+cglobal avg_pixels8, 4,5
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r0]
+    mova         m1, [r0+r2]
+    PAVGB        m0, [r1]
+    PAVGB        m1, [r1+r2]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    add          r1, r4
+    add          r0, r4
+    mova         m0, [r0]
+    mova         m1, [r0+r2]
+    PAVGB        m0, [r1]
+    PAVGB        m1, [r1+r2]
+    add          r1, r4
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX 3dnow
+AVG_PIXELS8
+
+
+; avg_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro AVG_PIXELS8_X2 0
+cglobal avg_pixels8_x2, 4,5
+    lea          r4, [r2*2]
+.loop:
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    PAVGB        m0, [r1+1]
+    PAVGB        m2, [r1+r2+1]
+    PAVGB        m0, [r0]
+    PAVGB        m2, [r0+r2]
+    add          r1, r4
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    mova         m0, [r1]
+    mova         m2, [r1+r2]
+    PAVGB        m0, [r1+1]
+    PAVGB        m2, [r1+r2+1]
+    add          r0, r4
+    add          r1, r4
+    PAVGB        m0, [r0]
+    PAVGB        m2, [r0+r2]
+    mova       [r0], m0
+    mova    [r0+r2], m2
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+AVG_PIXELS8_X2
+INIT_MMX 3dnow
+AVG_PIXELS8_X2
+
+
+; avg_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro AVG_PIXELS8_Y2 0
+cglobal avg_pixels8_y2, 4,5
+    lea          r4, [r2*2]
+    mova         m0, [r1]
+    sub          r0, r2
+.loop:
+    mova         m1, [r1+r2]
+    mova         m2, [r1+r4]
+    add          r1, r4
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    mova         m3, [r0+r2]
+    mova         m4, [r0+r4]
+    PAVGB        m0, m3
+    PAVGB        m1, m4
+    mova    [r0+r2], m0
+    mova    [r0+r4], m1
+    mova         m1, [r1+r2]
+    mova         m0, [r1+r4]
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    add          r0, r4
+    add          r1, r4
+    mova         m3, [r0+r2]
+    mova         m4, [r0+r4]
+    PAVGB        m2, m3
+    PAVGB        m1, m4
+    mova    [r0+r2], m2
+    mova    [r0+r4], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+AVG_PIXELS8_Y2
+INIT_MMX 3dnow
+AVG_PIXELS8_Y2
+
+
+; avg_pixels8_xy2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+%macro AVG_PIXELS8_XY2 0
+cglobal avg_pixels8_xy2, 4,5
+    mova         m6, [pb_1]
+    lea          r4, [r2*2]
+    mova         m0, [r1]
+    PAVGB        m0, [r1+1]
+.loop:
+    mova         m2, [r1+r4]
+    mova         m1, [r1+r2]
+    psubusb      m2, m6
+    PAVGB        m1, [r1+r2+1]
+    PAVGB        m2, [r1+r4+1]
+    add          r1, r4
+    PAVGB        m0, m1
+    PAVGB        m1, m2
+    PAVGB        m0, [r0]
+    PAVGB        m1, [r0+r2]
+    mova       [r0], m0
+    mova    [r0+r2], m1
+    mova         m1, [r1+r2]
+    mova         m0, [r1+r4]
+    PAVGB        m1, [r1+r2+1]
+    PAVGB        m0, [r1+r4+1]
+    add          r0, r4
+    add          r1, r4
+    PAVGB        m2, m1
+    PAVGB        m1, m0
+    PAVGB        m2, [r0]
+    PAVGB        m1, [r0+r2]
+    mova       [r0], m2
+    mova    [r0+r2], m1
+    add          r0, r4
+    sub         r3d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+AVG_PIXELS8_XY2
+INIT_MMX 3dnow
+AVG_PIXELS8_XY2
diff --git a/libavcodec/x86/hpeldsp_init.c b/libavcodec/x86/hpeldsp_init.c
new file mode 100644
index 0000000..3bc5601
--- /dev/null
+++ b/libavcodec/x86/hpeldsp_init.c
@@ -0,0 +1,269 @@
+/*
+ * MMX optimized DSP utils
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ *
+ * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
+ */
+
+#include "libavutil/cpu.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/hpeldsp.h"
+#include "dsputil_x86.h"
+
+void ff_put_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_put_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+void ff_put_pixels16_x2_mmxext(uint8_t *block, const uint8_t *pixels,
+                               ptrdiff_t line_size, int h);
+void ff_put_pixels16_x2_3dnow(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels,
+                                     ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels,
+                                    ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_x2_exact_mmxext(uint8_t *block,
+                                           const uint8_t *pixels,
+                                           ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_x2_exact_3dnow(uint8_t *block,
+                                          const uint8_t *pixels,
+                                          ptrdiff_t line_size, int h);
+void ff_put_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_put_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels,
+                                     ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels,
+                                    ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_exact_mmxext(uint8_t *block,
+                                           const uint8_t *pixels,
+                                           ptrdiff_t line_size, int h);
+void ff_put_no_rnd_pixels8_y2_exact_3dnow(uint8_t *block,
+                                          const uint8_t *pixels,
+                                          ptrdiff_t line_size, int h);
+void ff_avg_pixels8_3dnow(uint8_t *block, const uint8_t *pixels,
+                          ptrdiff_t line_size, int h);
+void ff_avg_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_avg_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+void ff_avg_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+void ff_avg_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels,
+                             ptrdiff_t line_size, int h);
+void ff_avg_pixels8_xy2_mmxext(uint8_t *block, const uint8_t *pixels,
+                               ptrdiff_t line_size, int h);
+void ff_avg_pixels8_xy2_3dnow(uint8_t *block, const uint8_t *pixels,
+                              ptrdiff_t line_size, int h);
+
+#define avg_pixels8_mmx         ff_avg_pixels8_mmx
+#define avg_pixels8_x2_mmx      ff_avg_pixels8_x2_mmx
+#define avg_pixels16_mmx        ff_avg_pixels16_mmx
+#define avg_pixels8_xy2_mmx     ff_avg_pixels8_xy2_mmx
+#define avg_pixels16_xy2_mmx    ff_avg_pixels16_xy2_mmx
+#define put_pixels8_mmx         ff_put_pixels8_mmx
+#define put_pixels16_mmx        ff_put_pixels16_mmx
+#define put_pixels8_xy2_mmx     ff_put_pixels8_xy2_mmx
+#define put_pixels16_xy2_mmx    ff_put_pixels16_xy2_mmx
+#define avg_no_rnd_pixels16_mmx ff_avg_pixels16_mmx
+#define put_no_rnd_pixels8_mmx  ff_put_pixels8_mmx
+#define put_no_rnd_pixels16_mmx ff_put_pixels16_mmx
+
+#if HAVE_INLINE_ASM
+
+/***********************************/
+/* MMX no rounding */
+#define DEF(x, y) x ## _no_rnd_ ## y ## _mmx
+#define SET_RND  MOVQ_WONE
+#define PAVGBP(a, b, c, d, e, f)        PAVGBP_MMX_NO_RND(a, b, c, d, e, f)
+#define PAVGB(a, b, c, e)               PAVGB_MMX_NO_RND(a, b, c, e)
+#define STATIC static
+
+#include "rnd_template.c"
+#include "hpeldsp_rnd_template.c"
+
+#undef DEF
+#undef SET_RND
+#undef PAVGBP
+#undef PAVGB
+#undef STATIC
+
+PIXELS16(static, avg_no_rnd, , _y2, _mmx)
+PIXELS16(static, put_no_rnd, , _y2, _mmx)
+
+PIXELS16(static, avg_no_rnd, , _xy2, _mmx)
+PIXELS16(static, put_no_rnd, , _xy2, _mmx)
+
+/***********************************/
+/* MMX rounding */
+
+#define DEF(x, y) x ## _ ## y ## _mmx
+#define SET_RND  MOVQ_WTWO
+#define PAVGBP(a, b, c, d, e, f)        PAVGBP_MMX(a, b, c, d, e, f)
+#define PAVGB(a, b, c, e)               PAVGB_MMX(a, b, c, e)
+
+#include "hpeldsp_rnd_template.c"
+
+#undef DEF
+#undef SET_RND
+#undef PAVGBP
+#undef PAVGB
+
+PIXELS16(static, avg, , _y2, _mmx)
+PIXELS16(static, put, , _y2, _mmx)
+
+#endif /* HAVE_INLINE_ASM */
+
+
+#if HAVE_YASM
+
+#define HPELDSP_AVG_PIXELS16(CPUEXT)                \
+    PIXELS16(static, put_no_rnd, ff_,  _x2, CPUEXT) \
+    PIXELS16(static, put,        ff_,  _y2, CPUEXT) \
+    PIXELS16(static, put_no_rnd, ff_,  _y2, CPUEXT) \
+    PIXELS16(static, avg,        ff_,     , CPUEXT) \
+    PIXELS16(static, avg,        ff_,  _x2, CPUEXT) \
+    PIXELS16(static, avg,        ff_,  _y2, CPUEXT) \
+    PIXELS16(static, avg,        ff_, _xy2, CPUEXT)
+
+HPELDSP_AVG_PIXELS16(_3dnow)
+HPELDSP_AVG_PIXELS16(_mmxext)
+
+#endif /* HAVE_YASM */
+
+#define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU)                                     \
+    do {                                                                        \
+        c->PFX ## _pixels_tab IDX [0] = PFX ## _pixels ## SIZE ## _     ## CPU; \
+        c->PFX ## _pixels_tab IDX [1] = PFX ## _pixels ## SIZE ## _x2_  ## CPU; \
+        c->PFX ## _pixels_tab IDX [2] = PFX ## _pixels ## SIZE ## _y2_  ## CPU; \
+        c->PFX ## _pixels_tab IDX [3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU; \
+    } while (0)
+
+static void hpeldsp_init_mmx(HpelDSPContext *c, int flags, int cpu_flags)
+{
+#if HAVE_MMX_INLINE
+    SET_HPEL_FUNCS(put,        [0], 16, mmx);
+    SET_HPEL_FUNCS(put_no_rnd, [0], 16, mmx);
+    SET_HPEL_FUNCS(avg,        [0], 16, mmx);
+    SET_HPEL_FUNCS(avg_no_rnd,    , 16, mmx);
+    SET_HPEL_FUNCS(put,        [1],  8, mmx);
+    SET_HPEL_FUNCS(put_no_rnd, [1],  8, mmx);
+    SET_HPEL_FUNCS(avg,        [1],  8, mmx);
+#endif /* HAVE_MMX_INLINE */
+}
+
+static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags, int cpu_flags)
+{
+#if HAVE_MMXEXT_EXTERNAL
+    c->put_pixels_tab[0][1] = ff_put_pixels16_x2_mmxext;
+    c->put_pixels_tab[0][2] = put_pixels16_y2_mmxext;
+
+    c->avg_pixels_tab[0][0] = avg_pixels16_mmxext;
+    c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmxext;
+    c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmxext;
+
+    c->put_pixels_tab[1][1] = ff_put_pixels8_x2_mmxext;
+    c->put_pixels_tab[1][2] = ff_put_pixels8_y2_mmxext;
+
+    c->avg_pixels_tab[1][0] = ff_avg_pixels8_mmxext;
+    c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_mmxext;
+    c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_mmxext;
+
+    if (!(flags & CODEC_FLAG_BITEXACT)) {
+        c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmxext;
+        c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmxext;
+        c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_mmxext;
+        c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_mmxext;
+
+        c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmxext;
+        c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_mmxext;
+    }
+
+    if (flags & CODEC_FLAG_BITEXACT && CONFIG_VP3_DECODER) {
+        c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_mmxext;
+        c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_mmxext;
+    }
+#endif /* HAVE_MMXEXT_EXTERNAL */
+}
+
+static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags, int cpu_flags)
+{
+#if HAVE_AMD3DNOW_EXTERNAL
+    c->put_pixels_tab[0][1] = ff_put_pixels16_x2_3dnow;
+    c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow;
+
+    c->avg_pixels_tab[0][0] = avg_pixels16_3dnow;
+    c->avg_pixels_tab[0][1] = avg_pixels16_x2_3dnow;
+    c->avg_pixels_tab[0][2] = avg_pixels16_y2_3dnow;
+
+    c->put_pixels_tab[1][1] = ff_put_pixels8_x2_3dnow;
+    c->put_pixels_tab[1][2] = ff_put_pixels8_y2_3dnow;
+
+    c->avg_pixels_tab[1][0] = ff_avg_pixels8_3dnow;
+    c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_3dnow;
+    c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_3dnow;
+
+    if (!(flags & CODEC_FLAG_BITEXACT)){
+        c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_3dnow;
+        c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_3dnow;
+        c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_3dnow;
+        c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_3dnow;
+
+        c->avg_pixels_tab[0][3] = avg_pixels16_xy2_3dnow;
+        c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_3dnow;
+    }
+
+    if (flags & CODEC_FLAG_BITEXACT && CONFIG_VP3_DECODER) {
+        c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_3dnow;
+        c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_3dnow;
+    }
+#endif /* HAVE_AMD3DNOW_EXTERNAL */
+}
+
+static void hpeldsp_init_sse2(HpelDSPContext *c, int flags, int cpu_flags)
+{
+#if HAVE_SSE2_EXTERNAL
+    if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
+        // these functions are slower than mmx on AMD, but faster on Intel
+        c->put_pixels_tab[0][0]        = ff_put_pixels16_sse2;
+        c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_sse2;
+        c->avg_pixels_tab[0][0]        = ff_avg_pixels16_sse2;
+    }
+#endif /* HAVE_SSE2_EXTERNAL */
+}
+
+void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (INLINE_MMX(cpu_flags))
+        hpeldsp_init_mmx(c, flags, cpu_flags);
+
+    if (EXTERNAL_AMD3DNOW(cpu_flags))
+        hpeldsp_init_3dnow(c, flags, cpu_flags);
+
+    if (EXTERNAL_MMXEXT(cpu_flags))
+        hpeldsp_init_mmxext(c, flags, cpu_flags);
+
+    if (EXTERNAL_SSE2(cpu_flags))
+        hpeldsp_init_sse2(c, flags, cpu_flags);
+}
diff --git a/libavcodec/x86/hpeldsp_mmx.c b/libavcodec/x86/hpeldsp_mmx.c
new file mode 100644
index 0000000..fece265
--- /dev/null
+++ b/libavcodec/x86/hpeldsp_mmx.c
@@ -0,0 +1,52 @@
+/*
+ * MMX-optimized avg/put pixel routines
+ *
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * This file is part of 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 <stddef.h>
+#include <stdint.h>
+
+#include "config.h"
+#include "dsputil_x86.h"
+
+#if HAVE_MMX_INLINE
+
+void ff_avg_pixels8_x2_mmx(uint8_t *block, const uint8_t *pixels,
+                           ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    JUMPALIGN();
+    do {
+        __asm__ volatile(
+            "movq  %1, %%mm0            \n\t"
+            "movq  1%1, %%mm1           \n\t"
+            "movq  %0, %%mm3            \n\t"
+            PAVGB_MMX(%%mm0, %%mm1, %%mm2, %%mm6)
+            PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6)
+            "movq  %%mm0, %0            \n\t"
+            :"+m"(*block)
+            :"m"(*pixels)
+            :"memory");
+        pixels += line_size;
+        block += line_size;
+    } while (--h);
+}
+
+#endif /* HAVE_MMX_INLINE */
diff --git a/libavcodec/x86/hpeldsp_rnd_template.c b/libavcodec/x86/hpeldsp_rnd_template.c
new file mode 100644
index 0000000..516a03a
--- /dev/null
+++ b/libavcodec/x86/hpeldsp_rnd_template.c
@@ -0,0 +1,198 @@
+/*
+ * DSP utils mmx functions are compiled twice for rnd/no_rnd
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2003-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
+ * mostly rewritten by Michael Niedermayer <michaelni at gmx.at>
+ * and improved by Zdenek Kabelac <kabi at users.sf.net>
+ *
+ * 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
+ */
+
+// put_pixels
+static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    __asm__ volatile(
+        "lea    (%3, %3), %%"REG_a"     \n\t"
+        ".p2align 3                     \n\t"
+        "1:                             \n\t"
+        "movq   (%1), %%mm0             \n\t"
+        "movq   1(%1), %%mm1            \n\t"
+        "movq   (%1, %3), %%mm2         \n\t"
+        "movq   1(%1, %3), %%mm3        \n\t"
+        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
+        "movq   %%mm4, (%2)             \n\t"
+        "movq   %%mm5, (%2, %3)         \n\t"
+        "add    %%"REG_a", %1           \n\t"
+        "add    %%"REG_a", %2           \n\t"
+        "movq   (%1), %%mm0             \n\t"
+        "movq   1(%1), %%mm1            \n\t"
+        "movq   (%1, %3), %%mm2         \n\t"
+        "movq   1(%1, %3), %%mm3        \n\t"
+        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
+        "movq   %%mm4, (%2)             \n\t"
+        "movq   %%mm5, (%2, %3)         \n\t"
+        "add    %%"REG_a", %1           \n\t"
+        "add    %%"REG_a", %2           \n\t"
+        "subl   $4, %0                  \n\t"
+        "jnz    1b                      \n\t"
+        :"+g"(h), "+S"(pixels), "+D"(block)
+        :"r"((x86_reg)line_size)
+        :REG_a, "memory");
+}
+
+static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    __asm__ volatile(
+        "lea        (%3, %3), %%"REG_a" \n\t"
+        ".p2align 3                     \n\t"
+        "1:                             \n\t"
+        "movq   (%1), %%mm0             \n\t"
+        "movq   1(%1), %%mm1            \n\t"
+        "movq   (%1, %3), %%mm2         \n\t"
+        "movq   1(%1, %3), %%mm3        \n\t"
+        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
+        "movq   %%mm4, (%2)             \n\t"
+        "movq   %%mm5, (%2, %3)         \n\t"
+        "movq   8(%1), %%mm0            \n\t"
+        "movq   9(%1), %%mm1            \n\t"
+        "movq   8(%1, %3), %%mm2        \n\t"
+        "movq   9(%1, %3), %%mm3        \n\t"
+        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
+        "movq   %%mm4, 8(%2)            \n\t"
+        "movq   %%mm5, 8(%2, %3)        \n\t"
+        "add    %%"REG_a", %1           \n\t"
+        "add    %%"REG_a", %2           \n\t"
+        "movq   (%1), %%mm0             \n\t"
+        "movq   1(%1), %%mm1            \n\t"
+        "movq   (%1, %3), %%mm2         \n\t"
+        "movq   1(%1, %3), %%mm3        \n\t"
+        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
+        "movq   %%mm4, (%2)             \n\t"
+        "movq   %%mm5, (%2, %3)         \n\t"
+        "movq   8(%1), %%mm0            \n\t"
+        "movq   9(%1), %%mm1            \n\t"
+        "movq   8(%1, %3), %%mm2        \n\t"
+        "movq   9(%1, %3), %%mm3        \n\t"
+        PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
+        "movq   %%mm4, 8(%2)            \n\t"
+        "movq   %%mm5, 8(%2, %3)        \n\t"
+        "add    %%"REG_a", %1           \n\t"
+        "add    %%"REG_a", %2           \n\t"
+        "subl   $4, %0                  \n\t"
+        "jnz    1b                      \n\t"
+        :"+g"(h), "+S"(pixels), "+D"(block)
+        :"r"((x86_reg)line_size)
+        :REG_a, "memory");
+}
+
+static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    __asm__ volatile(
+        "lea (%3, %3), %%"REG_a"        \n\t"
+        "movq (%1), %%mm0               \n\t"
+        ".p2align 3                     \n\t"
+        "1:                             \n\t"
+        "movq   (%1, %3), %%mm1         \n\t"
+        "movq   (%1, %%"REG_a"),%%mm2   \n\t"
+        PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
+        "movq   %%mm4, (%2)             \n\t"
+        "movq   %%mm5, (%2, %3)         \n\t"
+        "add    %%"REG_a", %1           \n\t"
+        "add    %%"REG_a", %2           \n\t"
+        "movq   (%1, %3), %%mm1         \n\t"
+        "movq   (%1, %%"REG_a"),%%mm0   \n\t"
+        PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
+        "movq   %%mm4, (%2)             \n\t"
+        "movq   %%mm5, (%2, %3)         \n\t"
+        "add    %%"REG_a", %1           \n\t"
+        "add    %%"REG_a", %2           \n\t"
+        "subl   $4, %0                  \n\t"
+        "jnz    1b                      \n\t"
+        :"+g"(h), "+S"(pixels), "+D"(block)
+        :"r"((x86_reg)line_size)
+        :REG_a, "memory");
+}
+
+static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    JUMPALIGN();
+    do {
+        __asm__ volatile(
+            "movq  %1, %%mm0            \n\t"
+            "movq  1%1, %%mm1           \n\t"
+            "movq  %0, %%mm3            \n\t"
+            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
+            PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6)
+            "movq  %%mm0, %0            \n\t"
+            "movq  8%1, %%mm0           \n\t"
+            "movq  9%1, %%mm1           \n\t"
+            "movq  8%0, %%mm3           \n\t"
+            PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
+            PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6)
+            "movq  %%mm0, 8%0           \n\t"
+            :"+m"(*block)
+            :"m"(*pixels)
+            :"memory");
+        pixels += line_size;
+        block += line_size;
+    } while (--h);
+}
+
+static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    MOVQ_BFE(mm6);
+    __asm__ volatile(
+        "lea    (%3, %3), %%"REG_a"     \n\t"
+        "movq   (%1), %%mm0             \n\t"
+        ".p2align 3                     \n\t"
+        "1:                             \n\t"
+        "movq   (%1, %3), %%mm1         \n\t"
+        "movq   (%1, %%"REG_a"), %%mm2  \n\t"
+        PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
+        "movq   (%2), %%mm3             \n\t"
+        PAVGB_MMX(%%mm3, %%mm4, %%mm0, %%mm6)
+        "movq   (%2, %3), %%mm3         \n\t"
+        PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6)
+        "movq   %%mm0, (%2)             \n\t"
+        "movq   %%mm1, (%2, %3)         \n\t"
+        "add    %%"REG_a", %1           \n\t"
+        "add    %%"REG_a", %2           \n\t"
+
+        "movq   (%1, %3), %%mm1         \n\t"
+        "movq   (%1, %%"REG_a"), %%mm0  \n\t"
+        PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
+        "movq   (%2), %%mm3             \n\t"
+        PAVGB_MMX(%%mm3, %%mm4, %%mm2, %%mm6)
+        "movq   (%2, %3), %%mm3         \n\t"
+        PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6)
+        "movq   %%mm2, (%2)             \n\t"
+        "movq   %%mm1, (%2, %3)         \n\t"
+        "add    %%"REG_a", %1           \n\t"
+        "add    %%"REG_a", %2           \n\t"
+
+        "subl   $4, %0                  \n\t"
+        "jnz    1b                      \n\t"
+        :"+g"(h), "+S"(pixels), "+D"(block)
+        :"r"((x86_reg)line_size)
+        :REG_a, "memory");
+}
diff --git a/libavcodec/x86/idct_mmx_xvid.c b/libavcodec/x86/idct_mmx_xvid.c
index 2cf8b47..2772339 100644
--- a/libavcodec/x86/idct_mmx_xvid.c
+++ b/libavcodec/x86/idct_mmx_xvid.c
@@ -44,10 +44,10 @@
 #include "config.h"
 #include "libavcodec/avcodec.h"
 #include "libavutil/mem.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 #include "idct_xvid.h"
 
-#if HAVE_INLINE_ASM
+#if HAVE_MMX_INLINE
 
 //=============================================================================
 // Macros and other preprocessor constants
@@ -507,6 +507,22 @@ __asm__ volatile(
     :: "r"(block), "r"(rounder_0), "r"(tab_i_04_mmx), "r"(tg_1_16));
 }
 
+void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, int16_t *block)
+{
+    ff_idct_xvid_mmx(block);
+    ff_put_pixels_clamped_mmx(block, dest, line_size);
+}
+
+void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, int16_t *block)
+{
+    ff_idct_xvid_mmx(block);
+    ff_add_pixels_clamped_mmx(block, dest, line_size);
+}
+
+#endif /* HAVE_MMX_INLINE */
+
+#if HAVE_MMXEXT_INLINE
+
 //-----------------------------------------------------------------------------
 // void idct_xmm(uint16_t block[64]);
 //-----------------------------------------------------------------------------
@@ -531,28 +547,16 @@ __asm__ volatile(
     :: "r"(block), "r"(rounder_0), "r"(tab_i_04_xmm), "r"(tg_1_16));
 }
 
-void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, DCTELEM *block)
-{
-    ff_idct_xvid_mmx(block);
-    ff_put_pixels_clamped_mmx(block, dest, line_size);
-}
-
-void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, DCTELEM *block)
-{
-    ff_idct_xvid_mmx(block);
-    ff_add_pixels_clamped_mmx(block, dest, line_size);
-}
-
-void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_idct_xvid_mmxext(block);
     ff_put_pixels_clamped_mmx(block, dest, line_size);
 }
 
-void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, int16_t *block)
 {
     ff_idct_xvid_mmxext(block);
     ff_add_pixels_clamped_mmx(block, dest, line_size);
 }
 
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_MMXEXT_INLINE */
diff --git a/libavcodec/x86/idct_sse2_xvid.c b/libavcodec/x86/idct_sse2_xvid.c
index fe2478e..50655d6 100644
--- a/libavcodec/x86/idct_sse2_xvid.c
+++ b/libavcodec/x86/idct_sse2_xvid.c
@@ -38,14 +38,13 @@
  * 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"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
-#if HAVE_INLINE_ASM
+#if HAVE_SSE2_INLINE
 
 /**
  * @file
@@ -377,7 +376,7 @@ inline void ff_idct_xvid_sse2(short *block)
     JZ("%%esi", "1f")
     "5:                                                          \n\t"
     iMTX_MULT("7*16(%0)", MANGLE(iTab2), ROUND(walkenIdctRounders+5*16), PUT_ODD(ROW7))
-#if !ARCH_X86_64
+#if ARCH_X86_32
     iLLM_HEAD
 #endif
     iLLM_PASS("%0")
@@ -406,4 +405,4 @@ void ff_idct_xvid_sse2_add(uint8_t *dest, int line_size, short *block)
     ff_add_pixels_clamped_mmx(block, dest, line_size);
 }
 
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_SSE2_INLINE */
diff --git a/libavcodec/x86/idct_xvid.h b/libavcodec/x86/idct_xvid.h
index 79d5bf9..aea28ba 100644
--- a/libavcodec/x86/idct_xvid.h
+++ b/libavcodec/x86/idct_xvid.h
@@ -28,15 +28,13 @@
 
 #include <stdint.h>
 
-#include "libavcodec/dsputil.h"
-
 void ff_idct_xvid_mmx(short *block);
-void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, int16_t *block);
+void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, int16_t *block);
 
 void ff_idct_xvid_mmxext(short *block);
-void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, int16_t *block);
+void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, int16_t *block);
 
 void ff_idct_xvid_sse2(short *block);
 void ff_idct_xvid_sse2_put(uint8_t *dest, int line_size, short *block);
diff --git a/libavcodec/x86/lpc.c b/libavcodec/x86/lpc.c
index b8c77e2..12245c4 100644
--- a/libavcodec/x86/lpc.c
+++ b/libavcodec/x86/lpc.c
@@ -19,11 +19,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/x86/asm.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/internal.h"
+#include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
 #include "libavcodec/lpc.h"
 
+DECLARE_ASM_CONST(16, double, pd_1)[2] = { 1.0, 1.0 };
+DECLARE_ASM_CONST(16, double, pd_2)[2] = { 2.0, 2.0 };
+
 #if HAVE_SSE2_INLINE
 
 static void lpc_apply_welch_window_sse2(const int32_t *data, int len,
@@ -35,8 +41,8 @@ static void lpc_apply_welch_window_sse2(const int32_t *data, int len,
     x86_reg j =  n2*sizeof(int32_t);
     __asm__ volatile(
         "movsd   %4,     %%xmm7                \n\t"
-        "movapd  "MANGLE(ff_pd_1)", %%xmm6     \n\t"
-        "movapd  "MANGLE(ff_pd_2)", %%xmm5     \n\t"
+        "movapd  "MANGLE(pd_1)", %%xmm6        \n\t"
+        "movapd  "MANGLE(pd_2)", %%xmm5        \n\t"
         "movlhps %%xmm7, %%xmm7                \n\t"
         "subpd   %%xmm5, %%xmm7                \n\t"
         "addsd   %%xmm6, %%xmm7                \n\t"
@@ -85,9 +91,9 @@ static void lpc_compute_autocorr_sse2(const double *data, int len, int lag,
         x86_reg i = -len*sizeof(double);
         if(j == lag-2) {
             __asm__ volatile(
-                "movsd    "MANGLE(ff_pd_1)", %%xmm0 \n\t"
-                "movsd    "MANGLE(ff_pd_1)", %%xmm1 \n\t"
-                "movsd    "MANGLE(ff_pd_1)", %%xmm2 \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm0    \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm1    \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm2    \n\t"
                 "1:                                 \n\t"
                 "movapd   (%2,%0), %%xmm3           \n\t"
                 "movupd -8(%3,%0), %%xmm4           \n\t"
@@ -115,8 +121,8 @@ static void lpc_compute_autocorr_sse2(const double *data, int len, int lag,
             );
         } else {
             __asm__ volatile(
-                "movsd    "MANGLE(ff_pd_1)", %%xmm0 \n\t"
-                "movsd    "MANGLE(ff_pd_1)", %%xmm1 \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm0    \n\t"
+                "movsd    "MANGLE(pd_1)", %%xmm1    \n\t"
                 "1:                                 \n\t"
                 "movapd   (%3,%0), %%xmm3           \n\t"
                 "movupd -8(%4,%0), %%xmm4           \n\t"
@@ -144,9 +150,9 @@ static void lpc_compute_autocorr_sse2(const double *data, int len, int lag,
 av_cold void ff_lpc_init_x86(LPCContext *c)
 {
 #if HAVE_SSE2_INLINE
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & (AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW)) {
+    if (INLINE_SSE2(cpu_flags) && (cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
         c->lpc_apply_welch_window = lpc_apply_welch_window_sse2;
         c->lpc_compute_autocorr   = lpc_compute_autocorr_sse2;
     }
diff --git a/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h
index cd408ac..a62094e 100644
--- a/libavcodec/x86/mathops.h
+++ b/libavcodec/x86/mathops.h
@@ -68,13 +68,13 @@ static av_always_inline av_const int64_t MUL64(int a, int b)
 
 #endif /* ARCH_X86_32 */
 
-#if HAVE_CMOV
+#if HAVE_I686
 /* median of 3 */
 #define mid_pred mid_pred
 static inline av_const int mid_pred(int a, int b, int c)
 {
     int i=b;
-    __asm__ volatile(
+    __asm__ (
         "cmp    %2, %1 \n\t"
         "cmovg  %1, %0 \n\t"
         "cmovg  %2, %1 \n\t"
@@ -87,9 +87,7 @@ static inline av_const int mid_pred(int a, int b, int c)
     );
     return i;
 }
-#endif
 
-#if HAVE_CMOV
 #define COPY3_IF_LT(x, y, a, b, c, d)\
 __asm__ volatile(\
     "cmpl  %0, %3       \n\t"\
@@ -99,7 +97,7 @@ __asm__ volatile(\
     : "+&r" (x), "+&r" (a), "+r" (c)\
     : "r" (y), "r" (b), "r" (d)\
 );
-#endif
+#endif /* HAVE_I686 */
 
 #define MASK_ABS(mask, level)                   \
     __asm__ ("cltd                   \n\t"      \
diff --git a/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c
index a18e9fa..72fc637 100644
--- a/libavcodec/x86/mlpdsp.c
+++ b/libavcodec/x86/mlpdsp.c
@@ -19,8 +19,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/internal.h"
+#include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
 #include "libavcodec/mlpdsp.h"
 #include "libavcodec/mlp.h"
 
@@ -174,9 +177,11 @@ static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff,
 
 #endif /* HAVE_7REGS && HAVE_INLINE_ASM */
 
-void ff_mlpdsp_init_x86(MLPDSPContext *c)
+av_cold void ff_mlpdsp_init_x86(MLPDSPContext *c)
 {
 #if HAVE_7REGS && HAVE_INLINE_ASM
-    c->mlp_filter_channel = mlp_filter_channel_x86;
+    int cpu_flags = av_get_cpu_flags();
+    if (INLINE_MMX(cpu_flags))
+        c->mlp_filter_channel = mlp_filter_channel_x86;
 #endif
 }
diff --git a/libavcodec/x86/motion_est.c b/libavcodec/x86/motion_est.c
index 0a0cab9..41b9c5c 100644
--- a/libavcodec/x86/motion_est.c
+++ b/libavcodec/x86/motion_est.c
@@ -22,11 +22,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
-#include "libavcodec/dsputil.h"
-#include "dsputil_mmx.h"
+#include "libavutil/x86/cpu.h"
+#include "dsputil_x86.h"
 
 #if HAVE_INLINE_ASM
 
@@ -432,12 +433,12 @@ PIX_SAD(mmxext)
 
 #endif /* HAVE_INLINE_ASM */
 
-void ff_dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx)
+av_cold void ff_dsputil_init_pix_mmx(DSPContext *c, AVCodecContext *avctx)
 {
 #if HAVE_INLINE_ASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (INLINE_MMX(cpu_flags)) {
         c->pix_abs[0][0] = sad16_mmx;
         c->pix_abs[0][1] = sad16_x2_mmx;
         c->pix_abs[0][2] = sad16_y2_mmx;
@@ -450,7 +451,7 @@ void ff_dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx)
         c->sad[0]= sad16_mmx;
         c->sad[1]= sad8_mmx;
     }
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+    if (INLINE_MMXEXT(cpu_flags)) {
         c->pix_abs[0][0] = sad16_mmxext;
         c->pix_abs[1][0] = sad8_mmxext;
 
@@ -466,7 +467,7 @@ void ff_dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx)
             c->pix_abs[1][3] = sad8_xy2_mmxext;
         }
     }
-    if ((mm_flags & AV_CPU_FLAG_SSE2) && !(mm_flags & AV_CPU_FLAG_3DNOW) && avctx->codec_id != AV_CODEC_ID_SNOW) {
+    if (INLINE_SSE2(cpu_flags) && !(cpu_flags & AV_CPU_FLAG_3DNOW)) {
         c->sad[0]= sad16_sse2;
     }
 #endif /* HAVE_INLINE_ASM */
diff --git a/libavcodec/x86/mpeg4qpel.asm b/libavcodec/x86/mpeg4qpel.asm
new file mode 100644
index 0000000..df20ea9
--- /dev/null
+++ b/libavcodec/x86/mpeg4qpel.asm
@@ -0,0 +1,558 @@
+;******************************************************************************
+;* mpeg4 qpel
+;* Copyright (c) 2008 Loren Merritt
+;*
+;* 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/x86util.asm"
+
+SECTION_RODATA
+cextern pb_1
+cextern pw_3
+cextern pw_15
+cextern pw_16
+cextern pw_20
+
+
+SECTION_TEXT
+
+; put_no_rnd_pixels8_l2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+%macro PUT_NO_RND_PIXELS8_L2 0
+cglobal put_no_rnd_pixels8_l2, 6,6
+    movsxdifnidn r4, r4d
+    movsxdifnidn r3, r3d
+    pcmpeqb      m6, m6
+    test        r5d, 1
+    je .loop
+    mova         m0, [r1]
+    mova         m1, [r2]
+    add          r1, r4
+    add          r2, 8
+    pxor         m0, m6
+    pxor         m1, m6
+    PAVGB        m0, m1
+    pxor         m0, m6
+    mova       [r0], m0
+    add          r0, r3
+    dec r5d
+.loop:
+    mova         m0, [r1]
+    add          r1, r4
+    mova         m1, [r1]
+    add          r1, r4
+    mova         m2, [r2]
+    mova         m3, [r2+8]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    add          r0, r3
+    mova       [r0], m1
+    add          r0, r3
+    mova         m0, [r1]
+    add          r1, r4
+    mova         m1, [r1]
+    add          r1, r4
+    mova         m2, [r2+16]
+    mova         m3, [r2+24]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    add          r0, r3
+    mova       [r0], m1
+    add          r0, r3
+    add          r2, 32
+    sub         r5d, 4
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS8_L2
+
+
+; put_no_rnd_pixels16_l2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+%macro PUT_NO_RND_PIXELS16_l2 0
+cglobal put_no_rnd_pixels16_l2, 6,6
+    movsxdifnidn r3, r3d
+    movsxdifnidn r4, r4d
+    pcmpeqb      m6, m6
+    test        r5d, 1
+    je .loop
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    mova         m2, [r2]
+    mova         m3, [r2+8]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    add          r1, r4
+    add          r2, 16
+    mova       [r0], m0
+    mova     [r0+8], m1
+    add          r0, r3
+    dec r5d
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    add          r1, r4
+    mova         m2, [r2]
+    mova         m3, [r2+8]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    mova     [r0+8], m1
+    add          r0, r3
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    add          r1, r4
+    mova         m2, [r2+16]
+    mova         m3, [r2+24]
+    pxor         m0, m6
+    pxor         m1, m6
+    pxor         m2, m6
+    pxor         m3, m6
+    PAVGB        m0, m2
+    PAVGB        m1, m3
+    pxor         m0, m6
+    pxor         m1, m6
+    mova       [r0], m0
+    mova     [r0+8], m1
+    add          r0, r3
+    add          r2, 32
+    sub         r5d, 2
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PUT_NO_RND_PIXELS16_l2
+INIT_MMX 3dnow
+PUT_NO_RND_PIXELS16_l2
+
+%macro MPEG4_QPEL16_H_LOWPASS 1
+cglobal %1_mpeg4_qpel16_h_lowpass, 5, 5, 0, 16
+    movsxdifnidn r2, r2d
+    movsxdifnidn r3, r3d
+    pxor         m7, m7
+.loop:
+    mova         m0, [r1]
+    mova         m1, m0
+    mova         m2, m0
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    pshufw       m5, m0, 0x90
+    pshufw       m6, m0, 0x41
+    mova         m3, m2
+    mova         m4, m2
+    psllq        m2, 8
+    psllq        m3, 16
+    psllq        m4, 24
+    punpckhbw    m2, m7
+    punpckhbw    m3, m7
+    punpckhbw    m4, m7
+    paddw        m5, m3
+    paddw        m6, m2
+    paddw        m5, m5
+    psubw        m6, m5
+    pshufw       m5, m0, 6
+    pmullw       m6, [pw_3]
+    paddw        m0, m4
+    paddw        m5, m1
+    pmullw       m0, [pw_20]
+    psubw        m0, m5
+    paddw        m6, [PW_ROUND]
+    paddw        m0, m6
+    psraw        m0, 5
+    mova    [rsp+8], m0
+    mova         m0, [r1+5]
+    mova         m5, m0
+    mova         m6, m0
+    psrlq        m0, 8
+    psrlq        m5, 16
+    punpcklbw    m0, m7
+    punpcklbw    m5, m7
+    paddw        m2, m0
+    paddw        m3, m5
+    paddw        m2, m2
+    psubw        m3, m2
+    mova         m2, m6
+    psrlq        m6, 24
+    punpcklbw    m2, m7
+    punpcklbw    m6, m7
+    pmullw       m3, [pw_3]
+    paddw        m1, m2
+    paddw        m4, m6
+    pmullw       m1, [pw_20]
+    psubw        m3, m4
+    paddw        m1, [PW_ROUND]
+    paddw        m3, m1
+    psraw        m3, 5
+    mova         m1, [rsp+8]
+    packuswb     m1, m3
+    OP_MOV     [r0], m1, m4
+    mova         m1, [r1+9]
+    mova         m4, m1
+    mova         m3, m1
+    psrlq        m1, 8
+    psrlq        m4, 16
+    punpcklbw    m1, m7
+    punpcklbw    m4, m7
+    paddw        m5, m1
+    paddw        m0, m4
+    paddw        m5, m5
+    psubw        m0, m5
+    mova         m5, m3
+    psrlq        m3, 24
+    pmullw       m0, [pw_3]
+    punpcklbw    m3, m7
+    paddw        m2, m3
+    psubw        m0, m2
+    mova         m2, m5
+    punpcklbw    m2, m7
+    punpckhbw    m5, m7
+    paddw        m6, m2
+    pmullw       m6, [pw_20]
+    paddw        m0, [PW_ROUND]
+    paddw        m0, m6
+    psraw        m0, 5
+    paddw        m3, m5
+    pshufw       m6, m5, 0xf9
+    paddw        m6, m4
+    pshufw       m4, m5, 0xbe
+    pshufw       m5, m5, 0x6f
+    paddw        m4, m1
+    paddw        m5, m2
+    paddw        m6, m6
+    psubw        m4, m6
+    pmullw       m3, [pw_20]
+    pmullw       m4, [pw_3]
+    psubw        m3, m5
+    paddw        m4, [PW_ROUND]
+    paddw        m4, m3
+    psraw        m4, 5
+    packuswb     m0, m4
+    OP_MOV   [r0+8], m0, m4
+    add          r1, r3
+    add          r0, r2
+    dec r4d
+    jne .loop
+    REP_RET
+%endmacro
+
+%macro PUT_OP 2-3
+    mova %1, %2
+%endmacro
+
+%macro AVG_OP 2-3
+    mova  %3, %1
+    pavgb %2, %3
+    mova  %1, %2
+%endmacro
+
+INIT_MMX mmxext
+%define PW_ROUND pw_16
+%define OP_MOV PUT_OP
+MPEG4_QPEL16_H_LOWPASS put
+%define PW_ROUND pw_16
+%define OP_MOV AVG_OP
+MPEG4_QPEL16_H_LOWPASS avg
+%define PW_ROUND pw_15
+%define OP_MOV PUT_OP
+MPEG4_QPEL16_H_LOWPASS put_no_rnd
+
+
+
+%macro MPEG4_QPEL8_H_LOWPASS 1
+cglobal %1_mpeg4_qpel8_h_lowpass, 5, 5, 0, 8
+    movsxdifnidn r2, r2d
+    movsxdifnidn r3, r3d
+    pxor         m7, m7
+.loop:
+    mova         m0, [r1]
+    mova         m1, m0
+    mova         m2, m0
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    pshufw       m5, m0, 0x90
+    pshufw       m6, m0, 0x41
+    mova         m3, m2
+    mova         m4, m2
+    psllq        m2, 8
+    psllq        m3, 16
+    psllq        m4, 24
+    punpckhbw    m2, m7
+    punpckhbw    m3, m7
+    punpckhbw    m4, m7
+    paddw        m5, m3
+    paddw        m6, m2
+    paddw        m5, m5
+    psubw        m6, m5
+    pshufw       m5, m0, 0x6
+    pmullw       m6, [pw_3]
+    paddw        m0, m4
+    paddw        m5, m1
+    pmullw       m0, [pw_20]
+    psubw        m0, m5
+    paddw        m6, [PW_ROUND]
+    paddw        m0, m6
+    psraw        m0, 5
+    movh         m5, [r1+5]
+    punpcklbw    m5, m7
+    pshufw       m6, m5, 0xf9
+    paddw        m1, m5
+    paddw        m2, m6
+    pshufw       m6, m5, 0xbe
+    pshufw       m5, m5, 0x6f
+    paddw        m3, m6
+    paddw        m4, m5
+    paddw        m2, m2
+    psubw        m3, m2
+    pmullw       m1, [pw_20]
+    pmullw       m3, [pw_3]
+    psubw        m3, m4
+    paddw        m1, [PW_ROUND]
+    paddw        m3, m1
+    psraw        m3, 5
+    packuswb     m0, m3
+    OP_MOV     [r0], m0, m4
+    add          r1, r3
+    add          r0, r2
+    dec r4d
+    jne .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+%define PW_ROUND pw_16
+%define OP_MOV PUT_OP
+MPEG4_QPEL8_H_LOWPASS put
+%define PW_ROUND pw_16
+%define OP_MOV AVG_OP
+MPEG4_QPEL8_H_LOWPASS avg
+%define PW_ROUND pw_15
+%define OP_MOV PUT_OP
+MPEG4_QPEL8_H_LOWPASS put_no_rnd
+
+
+
+%macro QPEL_V_LOW 5
+    paddw      m0, m1
+    mova       m4, [pw_20]
+    pmullw     m4, m0
+    mova       m0, %4
+    mova       m5, %1
+    paddw      m5, m0
+    psubw      m4, m5
+    mova       m5, %2
+    mova       m6, %3
+    paddw      m5, m3
+    paddw      m6, m2
+    paddw      m6, m6
+    psubw      m5, m6
+    pmullw     m5, [pw_3]
+    paddw      m4, [PW_ROUND]
+    paddw      m5, m4
+    psraw      m5, 5
+    packuswb   m5, m5
+    OP_MOV     %5, m5, m7
+    SWAP 0,1,2,3
+%endmacro
+
+%macro MPEG4_QPEL16_V_LOWPASS 1
+cglobal %1_mpeg4_qpel16_v_lowpass, 4, 6, 0, 544
+    movsxdifnidn r2, r2d
+    movsxdifnidn r3, r3d
+
+    mov         r4d, 17
+    mov          r5, rsp
+    pxor         m7, m7
+.looph:
+    mova         m0, [r1]
+    mova         m1, [r1]
+    mova         m2, [r1+8]
+    mova         m3, [r1+8]
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    punpcklbw    m2, m7
+    punpckhbw    m3, m7
+    mova       [r5], m0
+    mova  [r5+0x88], m1
+    mova [r5+0x110], m2
+    mova [r5+0x198], m3
+    add          r5, 8
+    add          r1, r3
+    dec r4d
+    jne .looph
+
+
+    ; NOTE: r1 CHANGES VALUES: r1 -> 4 - 14*dstStride
+    mov         r4d, 4
+    mov          r1, 4
+    neg          r2
+    lea          r1, [r1+r2*8]
+    lea          r1, [r1+r2*4]
+    lea          r1, [r1+r2*2]
+    neg          r2
+    mov          r5, rsp
+.loopv:
+    pxor         m7, m7
+    mova         m0, [r5+ 0x0]
+    mova         m1, [r5+ 0x8]
+    mova         m2, [r5+0x10]
+    mova         m3, [r5+0x18]
+    QPEL_V_LOW [r5+0x10], [r5+ 0x8], [r5+ 0x0], [r5+0x20], [r0]
+    QPEL_V_LOW [r5+ 0x8], [r5+ 0x0], [r5+ 0x0], [r5+0x28], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+ 0x0], [r5+ 0x0], [r5+ 0x8], [r5+0x30], [r0]
+    QPEL_V_LOW [r5+ 0x0], [r5+ 0x8], [r5+0x10], [r5+0x38], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+ 0x8], [r5+0x10], [r5+0x18], [r5+0x40], [r0]
+    QPEL_V_LOW [r5+0x10], [r5+0x18], [r5+0x20], [r5+0x48], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x18], [r5+0x20], [r5+0x28], [r5+0x50], [r0]
+    QPEL_V_LOW [r5+0x20], [r5+0x28], [r5+0x30], [r5+0x58], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x28], [r5+0x30], [r5+0x38], [r5+0x60], [r0]
+    QPEL_V_LOW [r5+0x30], [r5+0x38], [r5+0x40], [r5+0x68], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x38], [r5+0x40], [r5+0x48], [r5+0x70], [r0]
+    QPEL_V_LOW [r5+0x40], [r5+0x48], [r5+0x50], [r5+0x78], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x48], [r5+0x50], [r5+0x58], [r5+0x80], [r0]
+    QPEL_V_LOW [r5+0x50], [r5+0x58], [r5+0x60], [r5+0x80], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x58], [r5+0x60], [r5+0x68], [r5+0x78], [r0]
+    QPEL_V_LOW [r5+0x60], [r5+0x68], [r5+0x70], [r5+0x70], [r0+r2]
+
+    add    r5, 0x88
+    add    r0, r1
+    dec r4d
+    jne .loopv
+    REP_RET
+%endmacro
+
+%macro PUT_OPH 2-3
+    movh %1, %2
+%endmacro
+
+%macro AVG_OPH 2-3
+    movh  %3, %1
+    pavgb %2, %3
+    movh  %1, %2
+%endmacro
+
+INIT_MMX mmxext
+%define PW_ROUND pw_16
+%define OP_MOV PUT_OPH
+MPEG4_QPEL16_V_LOWPASS put
+%define PW_ROUND pw_16
+%define OP_MOV AVG_OPH
+MPEG4_QPEL16_V_LOWPASS avg
+%define PW_ROUND pw_15
+%define OP_MOV PUT_OPH
+MPEG4_QPEL16_V_LOWPASS put_no_rnd
+
+
+
+%macro MPEG4_QPEL8_V_LOWPASS 1
+cglobal %1_mpeg4_qpel8_v_lowpass, 4, 6, 0, 288
+    movsxdifnidn r2, r2d
+    movsxdifnidn r3, r3d
+
+    mov         r4d, 9
+    mov          r5, rsp
+    pxor         m7, m7
+.looph:
+    mova         m0, [r1]
+    mova         m1, [r1]
+    punpcklbw    m0, m7
+    punpckhbw    m1, m7
+    mova       [r5], m0
+    mova  [r5+0x48], m1
+    add          r5, 8
+    add          r1, r3
+    dec r4d
+    jne .looph
+
+
+    ; NOTE: r1 CHANGES VALUES: r1 -> 4 - 6*dstStride
+    mov         r4d, 2
+    mov          r1, 4
+    neg          r2
+    lea          r1, [r1+r2*4]
+    lea          r1, [r1+r2*2]
+    neg          r2
+    mov          r5, rsp
+.loopv:
+    pxor         m7, m7
+    mova         m0, [r5+ 0x0]
+    mova         m1, [r5+ 0x8]
+    mova         m2, [r5+0x10]
+    mova         m3, [r5+0x18]
+    QPEL_V_LOW [r5+0x10], [r5+ 0x8], [r5+ 0x0], [r5+0x20], [r0]
+    QPEL_V_LOW [r5+ 0x8], [r5+ 0x0], [r5+ 0x0], [r5+0x28], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+ 0x0], [r5+ 0x0], [r5+ 0x8], [r5+0x30], [r0]
+    QPEL_V_LOW [r5+ 0x0], [r5+ 0x8], [r5+0x10], [r5+0x38], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+ 0x8], [r5+0x10], [r5+0x18], [r5+0x40], [r0]
+    QPEL_V_LOW [r5+0x10], [r5+0x18], [r5+0x20], [r5+0x40], [r0+r2]
+    lea    r0, [r0+r2*2]
+    QPEL_V_LOW [r5+0x18], [r5+0x20], [r5+0x28], [r5+0x38], [r0]
+    QPEL_V_LOW [r5+0x20], [r5+0x28], [r5+0x30], [r5+0x30], [r0+r2]
+
+    add    r5, 0x48
+    add    r0, r1
+    dec r4d
+    jne .loopv
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+%define PW_ROUND pw_16
+%define OP_MOV PUT_OPH
+MPEG4_QPEL8_V_LOWPASS put
+%define PW_ROUND pw_16
+%define OP_MOV AVG_OPH
+MPEG4_QPEL8_V_LOWPASS avg
+%define PW_ROUND pw_15
+%define OP_MOV PUT_OPH
+MPEG4_QPEL8_V_LOWPASS put_no_rnd
diff --git a/libavcodec/x86/mpegaudiodec.c b/libavcodec/x86/mpegaudiodec.c
deleted file mode 100644
index c914fe1..0000000
--- a/libavcodec/x86/mpegaudiodec.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * MMX optimized MP3 decoding functions
- * Copyright (c) 2010 Vitor Sessak
- *
- * 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/cpu.h"
-#include "libavutil/x86/asm.h"
-#include "libavutil/x86/cpu.h"
-#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);
-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,
-                               float *tmpbuf);
-
-DECLARE_ALIGNED(16, static float, mdct_win_sse)[2][4][4*40];
-
-#if HAVE_SSE2_INLINE
-
-#define MACS(rt, ra, rb) rt+=(ra)*(rb)
-#define MLSS(rt, ra, rb) rt-=(ra)*(rb)
-
-#define SUM8(op, sum, w, p)               \
-{                                         \
-    op(sum, (w)[0 * 64], (p)[0 * 64]);    \
-    op(sum, (w)[1 * 64], (p)[1 * 64]);    \
-    op(sum, (w)[2 * 64], (p)[2 * 64]);    \
-    op(sum, (w)[3 * 64], (p)[3 * 64]);    \
-    op(sum, (w)[4 * 64], (p)[4 * 64]);    \
-    op(sum, (w)[5 * 64], (p)[5 * 64]);    \
-    op(sum, (w)[6 * 64], (p)[6 * 64]);    \
-    op(sum, (w)[7 * 64], (p)[7 * 64]);    \
-}
-
-static void apply_window(const float *buf, const float *win1,
-                         const float *win2, float *sum1, float *sum2, int len)
-{
-    x86_reg count = - 4*len;
-    const float *win1a = win1+len;
-    const float *win2a = win2+len;
-    const float *bufa  = buf+len;
-    float *sum1a = sum1+len;
-    float *sum2a = sum2+len;
-
-
-#define MULT(a, b)                                 \
-    "movaps " #a "(%1,%0), %%xmm1           \n\t"  \
-    "movaps " #a "(%3,%0), %%xmm2           \n\t"  \
-    "mulps         %%xmm2, %%xmm1           \n\t"  \
-    "subps         %%xmm1, %%xmm0           \n\t"  \
-    "mulps  " #b "(%2,%0), %%xmm2           \n\t"  \
-    "subps         %%xmm2, %%xmm4           \n\t"  \
-
-    __asm__ volatile(
-            "1:                                   \n\t"
-            "xorps       %%xmm0, %%xmm0           \n\t"
-            "xorps       %%xmm4, %%xmm4           \n\t"
-
-            MULT(   0,   0)
-            MULT( 256,  64)
-            MULT( 512, 128)
-            MULT( 768, 192)
-            MULT(1024, 256)
-            MULT(1280, 320)
-            MULT(1536, 384)
-            MULT(1792, 448)
-
-            "movaps      %%xmm0, (%4,%0)          \n\t"
-            "movaps      %%xmm4, (%5,%0)          \n\t"
-            "add            $16,  %0              \n\t"
-            "jl              1b                   \n\t"
-            :"+&r"(count)
-            :"r"(win1a), "r"(win2a), "r"(bufa), "r"(sum1a), "r"(sum2a)
-            );
-
-#undef MULT
-}
-
-static void apply_window_mp3(float *in, float *win, int *unused, float *out,
-                             int incr)
-{
-    LOCAL_ALIGNED_16(float, suma, [17]);
-    LOCAL_ALIGNED_16(float, sumb, [17]);
-    LOCAL_ALIGNED_16(float, sumc, [17]);
-    LOCAL_ALIGNED_16(float, sumd, [17]);
-
-    float sum;
-
-    /* copy to avoid wrap */
-    __asm__ volatile(
-            "movaps    0(%0), %%xmm0   \n\t" \
-            "movaps   16(%0), %%xmm1   \n\t" \
-            "movaps   32(%0), %%xmm2   \n\t" \
-            "movaps   48(%0), %%xmm3   \n\t" \
-            "movaps   %%xmm0,   0(%1) \n\t" \
-            "movaps   %%xmm1,  16(%1) \n\t" \
-            "movaps   %%xmm2,  32(%1) \n\t" \
-            "movaps   %%xmm3,  48(%1) \n\t" \
-            "movaps   64(%0), %%xmm0   \n\t" \
-            "movaps   80(%0), %%xmm1   \n\t" \
-            "movaps   96(%0), %%xmm2   \n\t" \
-            "movaps  112(%0), %%xmm3   \n\t" \
-            "movaps   %%xmm0,  64(%1) \n\t" \
-            "movaps   %%xmm1,  80(%1) \n\t" \
-            "movaps   %%xmm2,  96(%1) \n\t" \
-            "movaps   %%xmm3, 112(%1) \n\t"
-            ::"r"(in), "r"(in+512)
-            :"memory"
-            );
-
-    apply_window(in + 16, win     , win + 512, suma, sumc, 16);
-    apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16);
-
-    SUM8(MACS, suma[0], win + 32, in + 48);
-
-    sumc[ 0] = 0;
-    sumb[16] = 0;
-    sumd[16] = 0;
-
-#define SUMS(suma, sumb, sumc, sumd, out1, out2)               \
-            "movups " #sumd "(%4),       %%xmm0          \n\t" \
-            "shufps         $0x1b,       %%xmm0, %%xmm0  \n\t" \
-            "subps  " #suma "(%1),       %%xmm0          \n\t" \
-            "movaps        %%xmm0," #out1 "(%0)          \n\t" \
-\
-            "movups " #sumc "(%3),       %%xmm0          \n\t" \
-            "shufps         $0x1b,       %%xmm0, %%xmm0  \n\t" \
-            "addps  " #sumb "(%2),       %%xmm0          \n\t" \
-            "movaps        %%xmm0," #out2 "(%0)          \n\t"
-
-    if (incr == 1) {
-        __asm__ volatile(
-            SUMS( 0, 48,  4, 52,  0, 112)
-            SUMS(16, 32, 20, 36, 16,  96)
-            SUMS(32, 16, 36, 20, 32,  80)
-            SUMS(48,  0, 52,  4, 48,  64)
-
-            :"+&r"(out)
-            :"r"(&suma[0]), "r"(&sumb[0]), "r"(&sumc[0]), "r"(&sumd[0])
-            :"memory"
-            );
-        out += 16*incr;
-    } else {
-        int j;
-        float *out2 = out + 32 * incr;
-        out[0  ]  = -suma[   0];
-        out += incr;
-        out2 -= incr;
-        for(j=1;j<16;j++) {
-            *out  = -suma[   j] + sumd[16-j];
-            *out2 =  sumb[16-j] + sumc[   j];
-            out  += incr;
-            out2 -= incr;
-        }
-    }
-
-    sum = 0;
-    SUM8(MLSS, sum, win + 16 + 32, in + 32);
-    *out = sum;
-}
-
-#endif /* HAVE_SSE2_INLINE */
-
-#if HAVE_YASM
-#define DECL_IMDCT_BLOCKS(CPU1, CPU2)                                       \
-static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in,      \
-                               int count, int switch_point, int block_type) \
-{                                                                           \
-    int align_end = count - (count & 3);                                \
-    int j;                                                              \
-    for (j = 0; j < align_end; j+= 4) {                                 \
-        LOCAL_ALIGNED_16(float, tmpbuf, [1024]);                        \
-        float *win = mdct_win_sse[switch_point && j < 4][block_type];   \
-        /* apply window & overlap with previous buffer */               \
-                                                                        \
-        /* select window */                                             \
-        ff_four_imdct36_float_ ## CPU2(out, buf, in, win, tmpbuf);      \
-        in      += 4*18;                                                \
-        buf     += 4*18;                                                \
-        out     += 4;                                                   \
-    }                                                                   \
-    for (; 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))];       \
-                                                                        \
-        ff_imdct36_float_ ## CPU1(out, buf, in, win);                   \
-                                                                        \
-        in  += 18;                                                      \
-        buf++;                                                          \
-        out++;                                                          \
-    }                                                                   \
-}
-
-DECL_IMDCT_BLOCKS(sse,sse)
-DECL_IMDCT_BLOCKS(sse2,sse)
-DECL_IMDCT_BLOCKS(sse3,sse)
-DECL_IMDCT_BLOCKS(ssse3,sse)
-DECL_IMDCT_BLOCKS(avx,avx)
-#endif /* HAVE_YASM */
-
-void ff_mpadsp_init_x86(MPADSPContext *s)
-{
-    int mm_flags = av_get_cpu_flags();
-
-    int i, j;
-    for (j = 0; j < 4; j++) {
-        for (i = 0; i < 40; i ++) {
-            mdct_win_sse[0][j][4*i    ] = ff_mdct_win_float[j    ][i];
-            mdct_win_sse[0][j][4*i + 1] = ff_mdct_win_float[j + 4][i];
-            mdct_win_sse[0][j][4*i + 2] = ff_mdct_win_float[j    ][i];
-            mdct_win_sse[0][j][4*i + 3] = ff_mdct_win_float[j + 4][i];
-            mdct_win_sse[1][j][4*i    ] = ff_mdct_win_float[0    ][i];
-            mdct_win_sse[1][j][4*i + 1] = ff_mdct_win_float[4    ][i];
-            mdct_win_sse[1][j][4*i + 2] = ff_mdct_win_float[j    ][i];
-            mdct_win_sse[1][j][4*i + 3] = ff_mdct_win_float[j + 4][i];
-        }
-    }
-
-#if HAVE_SSE2_INLINE
-    if (mm_flags & AV_CPU_FLAG_SSE2) {
-        s->apply_window_float = apply_window_mp3;
-    }
-#endif /* HAVE_SSE2_INLINE */
-
-#if HAVE_YASM
-    if (EXTERNAL_AVX(mm_flags)) {
-        s->imdct36_blocks_float = imdct36_blocks_avx;
-    } else if (EXTERNAL_SSSE3(mm_flags)) {
-        s->imdct36_blocks_float = imdct36_blocks_ssse3;
-    } else if (EXTERNAL_SSE3(mm_flags)) {
-        s->imdct36_blocks_float = imdct36_blocks_sse3;
-    } else if (EXTERNAL_SSE2(mm_flags)) {
-        s->imdct36_blocks_float = imdct36_blocks_sse2;
-    } else if (EXTERNAL_SSE(mm_flags)) {
-        s->imdct36_blocks_float = imdct36_blocks_sse;
-    }
-#endif /* HAVE_YASM */
-}
diff --git a/libavcodec/x86/mpegaudiodsp.c b/libavcodec/x86/mpegaudiodsp.c
new file mode 100644
index 0000000..3f0943c
--- /dev/null
+++ b/libavcodec/x86/mpegaudiodsp.c
@@ -0,0 +1,268 @@
+/*
+ * MMX optimized MP3 decoding functions
+ * Copyright (c) 2010 Vitor Sessak
+ *
+ * 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/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/internal.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.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);
+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,
+                               float *tmpbuf);
+
+DECLARE_ALIGNED(16, static float, mdct_win_sse)[2][4][4*40];
+
+#if HAVE_SSE2_INLINE
+
+#define MACS(rt, ra, rb) rt+=(ra)*(rb)
+#define MLSS(rt, ra, rb) rt-=(ra)*(rb)
+
+#define SUM8(op, sum, w, p)               \
+{                                         \
+    op(sum, (w)[0 * 64], (p)[0 * 64]);    \
+    op(sum, (w)[1 * 64], (p)[1 * 64]);    \
+    op(sum, (w)[2 * 64], (p)[2 * 64]);    \
+    op(sum, (w)[3 * 64], (p)[3 * 64]);    \
+    op(sum, (w)[4 * 64], (p)[4 * 64]);    \
+    op(sum, (w)[5 * 64], (p)[5 * 64]);    \
+    op(sum, (w)[6 * 64], (p)[6 * 64]);    \
+    op(sum, (w)[7 * 64], (p)[7 * 64]);    \
+}
+
+static void apply_window(const float *buf, const float *win1,
+                         const float *win2, float *sum1, float *sum2, int len)
+{
+    x86_reg count = - 4*len;
+    const float *win1a = win1+len;
+    const float *win2a = win2+len;
+    const float *bufa  = buf+len;
+    float *sum1a = sum1+len;
+    float *sum2a = sum2+len;
+
+
+#define MULT(a, b)                                 \
+    "movaps " #a "(%1,%0), %%xmm1           \n\t"  \
+    "movaps " #a "(%3,%0), %%xmm2           \n\t"  \
+    "mulps         %%xmm2, %%xmm1           \n\t"  \
+    "subps         %%xmm1, %%xmm0           \n\t"  \
+    "mulps  " #b "(%2,%0), %%xmm2           \n\t"  \
+    "subps         %%xmm2, %%xmm4           \n\t"  \
+
+    __asm__ volatile(
+            "1:                                   \n\t"
+            "xorps       %%xmm0, %%xmm0           \n\t"
+            "xorps       %%xmm4, %%xmm4           \n\t"
+
+            MULT(   0,   0)
+            MULT( 256,  64)
+            MULT( 512, 128)
+            MULT( 768, 192)
+            MULT(1024, 256)
+            MULT(1280, 320)
+            MULT(1536, 384)
+            MULT(1792, 448)
+
+            "movaps      %%xmm0, (%4,%0)          \n\t"
+            "movaps      %%xmm4, (%5,%0)          \n\t"
+            "add            $16,  %0              \n\t"
+            "jl              1b                   \n\t"
+            :"+&r"(count)
+            :"r"(win1a), "r"(win2a), "r"(bufa), "r"(sum1a), "r"(sum2a)
+            );
+
+#undef MULT
+}
+
+static void apply_window_mp3(float *in, float *win, int *unused, float *out,
+                             int incr)
+{
+    LOCAL_ALIGNED_16(float, suma, [17]);
+    LOCAL_ALIGNED_16(float, sumb, [17]);
+    LOCAL_ALIGNED_16(float, sumc, [17]);
+    LOCAL_ALIGNED_16(float, sumd, [17]);
+
+    float sum;
+
+    /* copy to avoid wrap */
+    __asm__ volatile(
+            "movaps    0(%0), %%xmm0   \n\t" \
+            "movaps   16(%0), %%xmm1   \n\t" \
+            "movaps   32(%0), %%xmm2   \n\t" \
+            "movaps   48(%0), %%xmm3   \n\t" \
+            "movaps   %%xmm0,   0(%1) \n\t" \
+            "movaps   %%xmm1,  16(%1) \n\t" \
+            "movaps   %%xmm2,  32(%1) \n\t" \
+            "movaps   %%xmm3,  48(%1) \n\t" \
+            "movaps   64(%0), %%xmm0   \n\t" \
+            "movaps   80(%0), %%xmm1   \n\t" \
+            "movaps   96(%0), %%xmm2   \n\t" \
+            "movaps  112(%0), %%xmm3   \n\t" \
+            "movaps   %%xmm0,  64(%1) \n\t" \
+            "movaps   %%xmm1,  80(%1) \n\t" \
+            "movaps   %%xmm2,  96(%1) \n\t" \
+            "movaps   %%xmm3, 112(%1) \n\t"
+            ::"r"(in), "r"(in+512)
+            :"memory"
+            );
+
+    apply_window(in + 16, win     , win + 512, suma, sumc, 16);
+    apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16);
+
+    SUM8(MACS, suma[0], win + 32, in + 48);
+
+    sumc[ 0] = 0;
+    sumb[16] = 0;
+    sumd[16] = 0;
+
+#define SUMS(suma, sumb, sumc, sumd, out1, out2)               \
+            "movups " #sumd "(%4),       %%xmm0          \n\t" \
+            "shufps         $0x1b,       %%xmm0, %%xmm0  \n\t" \
+            "subps  " #suma "(%1),       %%xmm0          \n\t" \
+            "movaps        %%xmm0," #out1 "(%0)          \n\t" \
+\
+            "movups " #sumc "(%3),       %%xmm0          \n\t" \
+            "shufps         $0x1b,       %%xmm0, %%xmm0  \n\t" \
+            "addps  " #sumb "(%2),       %%xmm0          \n\t" \
+            "movaps        %%xmm0," #out2 "(%0)          \n\t"
+
+    if (incr == 1) {
+        __asm__ volatile(
+            SUMS( 0, 48,  4, 52,  0, 112)
+            SUMS(16, 32, 20, 36, 16,  96)
+            SUMS(32, 16, 36, 20, 32,  80)
+            SUMS(48,  0, 52,  4, 48,  64)
+
+            :"+&r"(out)
+            :"r"(&suma[0]), "r"(&sumb[0]), "r"(&sumc[0]), "r"(&sumd[0])
+            :"memory"
+            );
+        out += 16*incr;
+    } else {
+        int j;
+        float *out2 = out + 32 * incr;
+        out[0  ]  = -suma[   0];
+        out += incr;
+        out2 -= incr;
+        for(j=1;j<16;j++) {
+            *out  = -suma[   j] + sumd[16-j];
+            *out2 =  sumb[16-j] + sumc[   j];
+            out  += incr;
+            out2 -= incr;
+        }
+    }
+
+    sum = 0;
+    SUM8(MLSS, sum, win + 16 + 32, in + 32);
+    *out = sum;
+}
+
+#endif /* HAVE_SSE2_INLINE */
+
+#if HAVE_YASM
+#define DECL_IMDCT_BLOCKS(CPU1, CPU2)                                       \
+static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in,      \
+                               int count, int switch_point, int block_type) \
+{                                                                           \
+    int align_end = count - (count & 3);                                \
+    int j;                                                              \
+    for (j = 0; j < align_end; j+= 4) {                                 \
+        LOCAL_ALIGNED_16(float, tmpbuf, [1024]);                        \
+        float *win = mdct_win_sse[switch_point && j < 4][block_type];   \
+        /* apply window & overlap with previous buffer */               \
+                                                                        \
+        /* select window */                                             \
+        ff_four_imdct36_float_ ## CPU2(out, buf, in, win, tmpbuf);      \
+        in      += 4*18;                                                \
+        buf     += 4*18;                                                \
+        out     += 4;                                                   \
+    }                                                                   \
+    for (; 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))];       \
+                                                                        \
+        ff_imdct36_float_ ## CPU1(out, buf, in, win);                   \
+                                                                        \
+        in  += 18;                                                      \
+        buf++;                                                          \
+        out++;                                                          \
+    }                                                                   \
+}
+
+DECL_IMDCT_BLOCKS(sse,sse)
+DECL_IMDCT_BLOCKS(sse2,sse)
+DECL_IMDCT_BLOCKS(sse3,sse)
+DECL_IMDCT_BLOCKS(ssse3,sse)
+DECL_IMDCT_BLOCKS(avx,avx)
+#endif /* HAVE_YASM */
+
+av_cold void ff_mpadsp_init_x86(MPADSPContext *s)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    int i, j;
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 40; i ++) {
+            mdct_win_sse[0][j][4*i    ] = ff_mdct_win_float[j    ][i];
+            mdct_win_sse[0][j][4*i + 1] = ff_mdct_win_float[j + 4][i];
+            mdct_win_sse[0][j][4*i + 2] = ff_mdct_win_float[j    ][i];
+            mdct_win_sse[0][j][4*i + 3] = ff_mdct_win_float[j + 4][i];
+            mdct_win_sse[1][j][4*i    ] = ff_mdct_win_float[0    ][i];
+            mdct_win_sse[1][j][4*i + 1] = ff_mdct_win_float[4    ][i];
+            mdct_win_sse[1][j][4*i + 2] = ff_mdct_win_float[j    ][i];
+            mdct_win_sse[1][j][4*i + 3] = ff_mdct_win_float[j + 4][i];
+        }
+    }
+
+#if HAVE_SSE2_INLINE
+    if (cpu_flags & AV_CPU_FLAG_SSE2) {
+        s->apply_window_float = apply_window_mp3;
+    }
+#endif /* HAVE_SSE2_INLINE */
+
+#if HAVE_YASM
+    if (EXTERNAL_SSE(cpu_flags)) {
+        s->imdct36_blocks_float = imdct36_blocks_sse;
+    }
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        s->imdct36_blocks_float = imdct36_blocks_sse2;
+    }
+    if (EXTERNAL_SSE3(cpu_flags)) {
+        s->imdct36_blocks_float = imdct36_blocks_sse3;
+    }
+    if (EXTERNAL_SSSE3(cpu_flags)) {
+        s->imdct36_blocks_float = imdct36_blocks_ssse3;
+    }
+    if (EXTERNAL_AVX(cpu_flags)) {
+        s->imdct36_blocks_float = imdct36_blocks_avx;
+    }
+#endif /* HAVE_YASM */
+}
diff --git a/libavcodec/x86/mpegvideo.c b/libavcodec/x86/mpegvideo.c
index 3bc93f3..07fd1e5 100644
--- a/libavcodec/x86/mpegvideo.c
+++ b/libavcodec/x86/mpegvideo.c
@@ -19,17 +19,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_INLINE_ASM
 
 static void dct_unquantize_h263_intra_mmx(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     x86_reg level, qmul, qadd, nCoeffs;
 
@@ -104,7 +105,7 @@ __asm__ volatile(
 
 
 static void dct_unquantize_h263_inter_mmx(MpegEncContext *s,
-                                  DCTELEM *block, int n, int qscale)
+                                  int16_t *block, int n, int qscale)
 {
     x86_reg qmul, qadd, nCoeffs;
 
@@ -164,38 +165,8 @@ __asm__ volatile(
         );
 }
 
-
-/*
-  NK:
-  Note: looking at PARANOID:
-  "enable all paranoid tests for rounding, overflows, etc..."
-
-#ifdef PARANOID
-                if (level < -2048 || level > 2047)
-                    fprintf(stderr, "unquant error %d %d\n", i, level);
-#endif
-  We can suppose that result of two multiplications can't be greater than 0xFFFF
-  i.e. is 16-bit, so we use here only PMULLW instruction and can avoid
-  a complex multiplication.
-=====================================================
- Full formula for multiplication of 2 integer numbers
- which are represent as high:low words:
- input: value1 = high1:low1
-        value2 = high2:low2
- output: value3 = value1*value2
- value3=high3:low3 (on overflow: modulus 2^32 wrap-around)
- this mean that for 0x123456 * 0x123456 correct result is 0x766cb0ce4
- but this algorithm will compute only 0x66cb0ce4
- this limited by 16-bit size of operands
- ---------------------------------
- tlow1 = high1*low2
- tlow2 = high2*low1
- tlow1 = tlow1 + tlow2
- high3:low3 = low1*low2
- high3 += tlow1
-*/
 static void dct_unquantize_mpeg1_intra_mmx(MpegEncContext *s,
-                                     DCTELEM *block, int n, int qscale)
+                                     int16_t *block, int n, int qscale)
 {
     x86_reg nCoeffs;
     const uint16_t *quant_matrix;
@@ -264,7 +235,7 @@ __asm__ volatile(
 }
 
 static void dct_unquantize_mpeg1_inter_mmx(MpegEncContext *s,
-                                     DCTELEM *block, int n, int qscale)
+                                     int16_t *block, int n, int qscale)
 {
     x86_reg nCoeffs;
     const uint16_t *quant_matrix;
@@ -330,7 +301,7 @@ __asm__ volatile(
 }
 
 static void dct_unquantize_mpeg2_intra_mmx(MpegEncContext *s,
-                                     DCTELEM *block, int n, int qscale)
+                                     int16_t *block, int n, int qscale)
 {
     x86_reg nCoeffs;
     const uint16_t *quant_matrix;
@@ -396,7 +367,7 @@ __asm__ volatile(
 }
 
 static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s,
-                                     DCTELEM *block, int n, int qscale)
+                                     int16_t *block, int n, int qscale)
 {
     x86_reg nCoeffs;
     const uint16_t *quant_matrix;
@@ -472,7 +443,7 @@ __asm__ volatile(
         );
 }
 
-static void  denoise_dct_mmx(MpegEncContext *s, DCTELEM *block){
+static void  denoise_dct_mmx(MpegEncContext *s, int16_t *block){
     const int intra= s->mb_intra;
     int *sum= s->dct_error_sum[intra];
     uint16_t *offset= s->dct_offset[intra];
@@ -526,7 +497,7 @@ static void  denoise_dct_mmx(MpegEncContext *s, DCTELEM *block){
     );
 }
 
-static void  denoise_dct_sse2(MpegEncContext *s, DCTELEM *block){
+static void  denoise_dct_sse2(MpegEncContext *s, int16_t *block){
     const int intra= s->mb_intra;
     int *sum= s->dct_error_sum[intra];
     uint16_t *offset= s->dct_offset[intra];
@@ -584,12 +555,12 @@ static void  denoise_dct_sse2(MpegEncContext *s, DCTELEM *block){
 
 #endif /* HAVE_INLINE_ASM */
 
-void ff_MPV_common_init_x86(MpegEncContext *s)
+av_cold void ff_MPV_common_init_x86(MpegEncContext *s)
 {
 #if HAVE_INLINE_ASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (INLINE_MMX(cpu_flags)) {
         s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_mmx;
         s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx;
         s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx;
@@ -597,12 +568,10 @@ void ff_MPV_common_init_x86(MpegEncContext *s)
         if(!(s->flags & CODEC_FLAG_BITEXACT))
             s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx;
         s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx;
-
-        if (mm_flags & AV_CPU_FLAG_SSE2) {
-            s->denoise_dct= denoise_dct_sse2;
-        } else {
-                s->denoise_dct= denoise_dct_mmx;
-        }
+        s->denoise_dct = denoise_dct_mmx;
+    }
+    if (INLINE_SSE2(cpu_flags)) {
+        s->denoise_dct = denoise_dct_sse2;
     }
 #endif /* HAVE_INLINE_ASM */
 }
diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c
index 8f7c2e4..3167ea6 100644
--- a/libavcodec/x86/mpegvideoenc.c
+++ b/libavcodec/x86/mpegvideoenc.c
@@ -19,15 +19,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/avcodec.h"
-#include "libavcodec/dsputil.h"
+#include "libavcodec/dct.h"
 #include "libavcodec/mpegvideo.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
-extern uint16_t ff_inv_zigzag_direct16[64];
+/* not permutated inverse zigzag_direct + 1 for MMX quantizer */
+DECLARE_ALIGNED(16, static uint16_t, inv_zigzag_direct16)[64];
 
 #if HAVE_MMX_INLINE
 #define COMPILE_TEMPLATE_MMXEXT 0
@@ -80,26 +82,30 @@ extern uint16_t ff_inv_zigzag_direct16[64];
 #include "mpegvideoenc_template.c"
 #endif /* HAVE_SSSE3_INLINE */
 
-void ff_MPV_encode_init_x86(MpegEncContext *s)
+av_cold void ff_MPV_encode_init_x86(MpegEncContext *s)
 {
-    int mm_flags = av_get_cpu_flags();
     const int dct_algo = s->avctx->dct_algo;
+    int i;
+
+    for (i = 0; i < 64; i++)
+        inv_zigzag_direct16[ff_zigzag_direct[i]] = i + 1;
 
     if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) {
 #if HAVE_MMX_INLINE
-        if (INLINE_MMX(mm_flags))
+        int cpu_flags = av_get_cpu_flags();
+        if (INLINE_MMX(cpu_flags))
             s->dct_quantize = dct_quantize_MMX;
 #endif
 #if HAVE_MMXEXT_INLINE
-        if (INLINE_MMXEXT(mm_flags))
+        if (INLINE_MMXEXT(cpu_flags))
             s->dct_quantize = dct_quantize_MMXEXT;
 #endif
 #if HAVE_SSE2_INLINE
-        if (INLINE_SSE2(mm_flags))
+        if (INLINE_SSE2(cpu_flags))
             s->dct_quantize = dct_quantize_SSE2;
 #endif
 #if HAVE_SSSE3_INLINE
-        if (INLINE_SSSE3(mm_flags))
+        if (INLINE_SSSE3(cpu_flags))
             s->dct_quantize = dct_quantize_SSSE3;
 #endif
     }
diff --git a/libavcodec/x86/mpegvideoenc_template.c b/libavcodec/x86/mpegvideoenc_template.c
index a6e7ba4..a8d2a2c 100644
--- a/libavcodec/x86/mpegvideoenc_template.c
+++ b/libavcodec/x86/mpegvideoenc_template.c
@@ -92,7 +92,7 @@
 #endif
 
 static int RENAME(dct_quantize)(MpegEncContext *s,
-                            DCTELEM *block, int n,
+                            int16_t *block, int n,
                             int qscale, int *overflow)
 {
     x86_reg last_non_zero_p1;
@@ -168,7 +168,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
             "movzb %%al, %%"REG_a"              \n\t" // last_non_zero_p1
             : "+a" (last_non_zero_p1)
             : "r" (block+64), "r" (qmat), "r" (bias),
-              "r" (ff_inv_zigzag_direct16+64), "r" (temp_block+64)
+              "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64)
               XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3",
                                 "%xmm4", "%xmm5", "%xmm6", "%xmm7")
         );
@@ -202,7 +202,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
             "movzb %%al, %%"REG_a"              \n\t" // last_non_zero_p1
             : "+a" (last_non_zero_p1)
             : "r" (block+64), "r" (qmat+64), "r" (bias+64),
-              "r" (ff_inv_zigzag_direct16+64), "r" (temp_block+64)
+              "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64)
               XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3",
                                 "%xmm4", "%xmm5", "%xmm6", "%xmm7")
         );
diff --git a/libavcodec/x86/pngdsp_init.c b/libavcodec/x86/pngdsp_init.c
index 2e858fa..34a3da3 100644
--- a/libavcodec/x86/pngdsp_init.c
+++ b/libavcodec/x86/pngdsp_init.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/pngdsp.h"
@@ -32,18 +33,18 @@ void ff_add_bytes_l2_mmx (uint8_t *dst, uint8_t *src1,
 void ff_add_bytes_l2_sse2(uint8_t *dst, uint8_t *src1,
                           uint8_t *src2, int w);
 
-void ff_pngdsp_init_x86(PNGDSPContext *dsp)
+av_cold void ff_pngdsp_init_x86(PNGDSPContext *dsp)
 {
-    int flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
 #if ARCH_X86_32
-    if (EXTERNAL_MMX(flags))
+    if (EXTERNAL_MMX(cpu_flags))
         dsp->add_bytes_l2         = ff_add_bytes_l2_mmx;
 #endif
-    if (EXTERNAL_MMXEXT(flags))
+    if (EXTERNAL_MMXEXT(cpu_flags))
         dsp->add_paeth_prediction = ff_add_png_paeth_prediction_mmxext;
-    if (EXTERNAL_SSE2(flags))
+    if (EXTERNAL_SSE2(cpu_flags))
         dsp->add_bytes_l2         = ff_add_bytes_l2_sse2;
-    if (EXTERNAL_SSSE3(flags))
+    if (EXTERNAL_SSSE3(cpu_flags))
         dsp->add_paeth_prediction = ff_add_png_paeth_prediction_ssse3;
 }
diff --git a/libavcodec/x86/proresdsp.asm b/libavcodec/x86/proresdsp.asm
index 91e0800..855f209 100644
--- a/libavcodec/x86/proresdsp.asm
+++ b/libavcodec/x86/proresdsp.asm
@@ -327,7 +327,7 @@ section .text align=16
 %endmacro
 
 ; void prores_idct_put_10_<opt>(uint8_t *pixels, int stride,
-;                               DCTELEM *block, const int16_t *qmat);
+;                               int16_t *block, const int16_t *qmat);
 %macro idct_put_fn 1
 cglobal prores_idct_put_10, 4, 4, %1
     movsxd      r1,  r1d
diff --git a/libavcodec/x86/proresdsp_init.c b/libavcodec/x86/proresdsp_init.c
index 46c26bd..d63382c 100644
--- a/libavcodec/x86/proresdsp_init.c
+++ b/libavcodec/x86/proresdsp_init.c
@@ -20,32 +20,34 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/x86/cpu.h"
+#include "libavcodec/dsputil.h"
 #include "libavcodec/proresdsp.h"
 
 void ff_prores_idct_put_10_sse2(uint16_t *dst, int linesize,
-                                DCTELEM *block, const int16_t *qmat);
+                                int16_t *block, const int16_t *qmat);
 void ff_prores_idct_put_10_sse4(uint16_t *dst, int linesize,
-                                DCTELEM *block, const int16_t *qmat);
+                                int16_t *block, const int16_t *qmat);
 void ff_prores_idct_put_10_avx (uint16_t *dst, int linesize,
-                                DCTELEM *block, const int16_t *qmat);
+                                int16_t *block, const int16_t *qmat);
 
-void ff_proresdsp_x86_init(ProresDSPContext *dsp)
+av_cold void ff_proresdsp_x86_init(ProresDSPContext *dsp)
 {
 #if ARCH_X86_64
-    int flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_SSE2(flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
         dsp->idct_put = ff_prores_idct_put_10_sse2;
     }
 
-    if (EXTERNAL_SSE4(flags)) {
+    if (EXTERNAL_SSE4(cpu_flags)) {
         dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
         dsp->idct_put = ff_prores_idct_put_10_sse4;
     }
 
-    if (EXTERNAL_AVX(flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
         dsp->idct_put = ff_prores_idct_put_10_avx;
     }
diff --git a/libavcodec/x86/qpel.asm b/libavcodec/x86/qpel.asm
new file mode 100644
index 0000000..c90b393
--- /dev/null
+++ b/libavcodec/x86/qpel.asm
@@ -0,0 +1,176 @@
+;******************************************************************************
+;* MMX optimized DSP utils
+;* Copyright (c) 2008 Loren Merritt
+;* Copyright (c) 2003-2013 Michael Niedermayer
+;* Copyright (c) 2013 Daniel Kang
+;*
+;* This file is part of 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/x86util.asm"
+
+SECTION .text
+
+%macro op_avgh 3
+    movh   %3, %2
+    pavgb  %1, %3
+    movh   %2, %1
+%endmacro
+
+%macro op_avg 2
+    pavgb  %1, %2
+    mova   %2, %1
+%endmacro
+
+%macro op_puth 2-3
+    movh   %2, %1
+%endmacro
+
+%macro op_put 2
+    mova   %2, %1
+%endmacro
+
+; void pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+%macro PIXELS4_L2 1
+%define OP op_%1h
+cglobal %1_pixels4_l2, 6,6
+    movsxdifnidn r3, r3d
+    movsxdifnidn r4, r4d
+    test        r5d, 1
+    je        .loop
+    movd         m0, [r1]
+    movd         m1, [r2]
+    add          r1, r4
+    add          r2, 4
+    pavgb        m0, m1
+    OP           m0, [r0], m3
+    add          r0, r3
+    dec         r5d
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+r4]
+    lea          r1, [r1+2*r4]
+    pavgb        m0, [r2]
+    pavgb        m1, [r2+4]
+    OP           m0, [r0], m3
+    OP           m1, [r0+r3], m3
+    lea          r0, [r0+2*r3]
+    mova         m0, [r1]
+    mova         m1, [r1+r4]
+    lea          r1, [r1+2*r4]
+    pavgb        m0, [r2+8]
+    pavgb        m1, [r2+12]
+    OP           m0, [r0], m3
+    OP           m1, [r0+r3], m3
+    lea          r0, [r0+2*r3]
+    add          r2, 16
+    sub         r5d, 4
+    jne       .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PIXELS4_L2 put
+PIXELS4_L2 avg
+
+; void pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+%macro PIXELS8_L2 1
+%define OP op_%1
+cglobal %1_pixels8_l2, 6,6
+    movsxdifnidn r3, r3d
+    movsxdifnidn r4, r4d
+    test        r5d, 1
+    je        .loop
+    mova         m0, [r1]
+    mova         m1, [r2]
+    add          r1, r4
+    add          r2, 8
+    pavgb        m0, m1
+    OP           m0, [r0]
+    add          r0, r3
+    dec         r5d
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+r4]
+    lea          r1, [r1+2*r4]
+    pavgb        m0, [r2]
+    pavgb        m1, [r2+8]
+    OP           m0, [r0]
+    OP           m1, [r0+r3]
+    lea          r0, [r0+2*r3]
+    mova         m0, [r1]
+    mova         m1, [r1+r4]
+    lea          r1, [r1+2*r4]
+    pavgb        m0, [r2+16]
+    pavgb        m1, [r2+24]
+    OP           m0, [r0]
+    OP           m1, [r0+r3]
+    lea          r0, [r0+2*r3]
+    add          r2, 32
+    sub         r5d, 4
+    jne       .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PIXELS8_L2 put
+PIXELS8_L2 avg
+
+; void pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
+%macro PIXELS16_L2 1
+%define OP op_%1
+cglobal %1_pixels16_l2, 6,6
+    movsxdifnidn r3, r3d
+    movsxdifnidn r4, r4d
+    test        r5d, 1
+    je        .loop
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    pavgb        m0, [r2]
+    pavgb        m1, [r2+8]
+    add          r1, r4
+    add          r2, 16
+    OP           m0, [r0]
+    OP           m1, [r0+8]
+    add          r0, r3
+    dec         r5d
+.loop:
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    add          r1, r4
+    pavgb        m0, [r2]
+    pavgb        m1, [r2+8]
+    OP           m0, [r0]
+    OP           m1, [r0+8]
+    add          r0, r3
+    mova         m0, [r1]
+    mova         m1, [r1+8]
+    add          r1, r4
+    pavgb        m0, [r2+16]
+    pavgb        m1, [r2+24]
+    OP           m0, [r0]
+    OP           m1, [r0+8]
+    add          r0, r3
+    add          r2, 32
+    sub         r5d, 2
+    jne       .loop
+    REP_RET
+%endmacro
+
+INIT_MMX mmxext
+PIXELS16_L2 put
+PIXELS16_L2 avg
diff --git a/libavcodec/x86/rnd_mmx.c b/libavcodec/x86/rnd_mmx.c
new file mode 100644
index 0000000..db4515a
--- /dev/null
+++ b/libavcodec/x86/rnd_mmx.c
@@ -0,0 +1,35 @@
+/*
+ * 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 "dsputil_x86.h"
+
+#if HAVE_INLINE_ASM
+
+#define DEF(x, y) ff_ ## x ## _ ## y ## _mmx
+#define SET_RND  MOVQ_WTWO
+#define PAVGBP(a, b, c, d, e, f)        PAVGBP_MMX(a, b, c, d, e, f)
+#define PAVGB(a, b, c, e)               PAVGB_MMX(a, b, c, e)
+#define STATIC
+
+#include "rnd_template.c"
+
+PIXELS16(, ff_avg, , _xy2, _mmx)
+PIXELS16(, ff_put, , _xy2, _mmx)
+
+#endif /* HAVE_INLINE_ASM */
diff --git a/libavcodec/x86/rnd_template.c b/libavcodec/x86/rnd_template.c
new file mode 100644
index 0000000..e9a5a45
--- /dev/null
+++ b/libavcodec/x86/rnd_template.c
@@ -0,0 +1,173 @@
+/*
+ * DSP utils mmx functions are compiled twice for rnd/no_rnd
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2003-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * MMX optimization by Nick Kurshev <nickols_k at mail.ru>
+ * mostly rewritten by Michael Niedermayer <michaelni at gmx.at>
+ * and improved by Zdenek Kabelac <kabi at users.sf.net>
+ *
+ * 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 <stddef.h>
+#include <stdint.h>
+
+// put_pixels
+STATIC void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels,
+                                  ptrdiff_t line_size, int h)
+{
+    MOVQ_ZERO(mm7);
+    SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
+    __asm__ volatile(
+        "movq   (%1), %%mm0             \n\t"
+        "movq   1(%1), %%mm4            \n\t"
+        "movq   %%mm0, %%mm1            \n\t"
+        "movq   %%mm4, %%mm5            \n\t"
+        "punpcklbw %%mm7, %%mm0         \n\t"
+        "punpcklbw %%mm7, %%mm4         \n\t"
+        "punpckhbw %%mm7, %%mm1         \n\t"
+        "punpckhbw %%mm7, %%mm5         \n\t"
+        "paddusw %%mm0, %%mm4           \n\t"
+        "paddusw %%mm1, %%mm5           \n\t"
+        "xor    %%"REG_a", %%"REG_a"    \n\t"
+        "add    %3, %1                  \n\t"
+        ".p2align 3                     \n\t"
+        "1:                             \n\t"
+        "movq   (%1, %%"REG_a"), %%mm0  \n\t"
+        "movq   1(%1, %%"REG_a"), %%mm2 \n\t"
+        "movq   %%mm0, %%mm1            \n\t"
+        "movq   %%mm2, %%mm3            \n\t"
+        "punpcklbw %%mm7, %%mm0         \n\t"
+        "punpcklbw %%mm7, %%mm2         \n\t"
+        "punpckhbw %%mm7, %%mm1         \n\t"
+        "punpckhbw %%mm7, %%mm3         \n\t"
+        "paddusw %%mm2, %%mm0           \n\t"
+        "paddusw %%mm3, %%mm1           \n\t"
+        "paddusw %%mm6, %%mm4           \n\t"
+        "paddusw %%mm6, %%mm5           \n\t"
+        "paddusw %%mm0, %%mm4           \n\t"
+        "paddusw %%mm1, %%mm5           \n\t"
+        "psrlw  $2, %%mm4               \n\t"
+        "psrlw  $2, %%mm5               \n\t"
+        "packuswb  %%mm5, %%mm4         \n\t"
+        "movq   %%mm4, (%2, %%"REG_a")  \n\t"
+        "add    %3, %%"REG_a"           \n\t"
+
+        "movq   (%1, %%"REG_a"), %%mm2  \n\t" // 0 <-> 2   1 <-> 3
+        "movq   1(%1, %%"REG_a"), %%mm4 \n\t"
+        "movq   %%mm2, %%mm3            \n\t"
+        "movq   %%mm4, %%mm5            \n\t"
+        "punpcklbw %%mm7, %%mm2         \n\t"
+        "punpcklbw %%mm7, %%mm4         \n\t"
+        "punpckhbw %%mm7, %%mm3         \n\t"
+        "punpckhbw %%mm7, %%mm5         \n\t"
+        "paddusw %%mm2, %%mm4           \n\t"
+        "paddusw %%mm3, %%mm5           \n\t"
+        "paddusw %%mm6, %%mm0           \n\t"
+        "paddusw %%mm6, %%mm1           \n\t"
+        "paddusw %%mm4, %%mm0           \n\t"
+        "paddusw %%mm5, %%mm1           \n\t"
+        "psrlw  $2, %%mm0               \n\t"
+        "psrlw  $2, %%mm1               \n\t"
+        "packuswb  %%mm1, %%mm0         \n\t"
+        "movq   %%mm0, (%2, %%"REG_a")  \n\t"
+        "add    %3, %%"REG_a"           \n\t"
+
+        "subl   $2, %0                  \n\t"
+        "jnz    1b                      \n\t"
+        :"+g"(h), "+S"(pixels)
+        :"D"(block), "r"((x86_reg)line_size)
+        :REG_a, "memory");
+}
+
+// avg_pixels
+// this routine is 'slightly' suboptimal but mostly unused
+STATIC void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels,
+                                  ptrdiff_t line_size, int h)
+{
+    MOVQ_ZERO(mm7);
+    SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
+    __asm__ volatile(
+        "movq   (%1), %%mm0             \n\t"
+        "movq   1(%1), %%mm4            \n\t"
+        "movq   %%mm0, %%mm1            \n\t"
+        "movq   %%mm4, %%mm5            \n\t"
+        "punpcklbw %%mm7, %%mm0         \n\t"
+        "punpcklbw %%mm7, %%mm4         \n\t"
+        "punpckhbw %%mm7, %%mm1         \n\t"
+        "punpckhbw %%mm7, %%mm5         \n\t"
+        "paddusw %%mm0, %%mm4           \n\t"
+        "paddusw %%mm1, %%mm5           \n\t"
+        "xor    %%"REG_a", %%"REG_a"    \n\t"
+        "add    %3, %1                  \n\t"
+        ".p2align 3                     \n\t"
+        "1:                             \n\t"
+        "movq   (%1, %%"REG_a"), %%mm0  \n\t"
+        "movq   1(%1, %%"REG_a"), %%mm2 \n\t"
+        "movq   %%mm0, %%mm1            \n\t"
+        "movq   %%mm2, %%mm3            \n\t"
+        "punpcklbw %%mm7, %%mm0         \n\t"
+        "punpcklbw %%mm7, %%mm2         \n\t"
+        "punpckhbw %%mm7, %%mm1         \n\t"
+        "punpckhbw %%mm7, %%mm3         \n\t"
+        "paddusw %%mm2, %%mm0           \n\t"
+        "paddusw %%mm3, %%mm1           \n\t"
+        "paddusw %%mm6, %%mm4           \n\t"
+        "paddusw %%mm6, %%mm5           \n\t"
+        "paddusw %%mm0, %%mm4           \n\t"
+        "paddusw %%mm1, %%mm5           \n\t"
+        "psrlw  $2, %%mm4               \n\t"
+        "psrlw  $2, %%mm5               \n\t"
+                "movq   (%2, %%"REG_a"), %%mm3  \n\t"
+        "packuswb  %%mm5, %%mm4         \n\t"
+                "pcmpeqd %%mm2, %%mm2   \n\t"
+                "paddb %%mm2, %%mm2     \n\t"
+                PAVGB_MMX(%%mm3, %%mm4, %%mm5, %%mm2)
+                "movq   %%mm5, (%2, %%"REG_a")  \n\t"
+        "add    %3, %%"REG_a"                \n\t"
+
+        "movq   (%1, %%"REG_a"), %%mm2  \n\t" // 0 <-> 2   1 <-> 3
+        "movq   1(%1, %%"REG_a"), %%mm4 \n\t"
+        "movq   %%mm2, %%mm3            \n\t"
+        "movq   %%mm4, %%mm5            \n\t"
+        "punpcklbw %%mm7, %%mm2         \n\t"
+        "punpcklbw %%mm7, %%mm4         \n\t"
+        "punpckhbw %%mm7, %%mm3         \n\t"
+        "punpckhbw %%mm7, %%mm5         \n\t"
+        "paddusw %%mm2, %%mm4           \n\t"
+        "paddusw %%mm3, %%mm5           \n\t"
+        "paddusw %%mm6, %%mm0           \n\t"
+        "paddusw %%mm6, %%mm1           \n\t"
+        "paddusw %%mm4, %%mm0           \n\t"
+        "paddusw %%mm5, %%mm1           \n\t"
+        "psrlw  $2, %%mm0               \n\t"
+        "psrlw  $2, %%mm1               \n\t"
+                "movq   (%2, %%"REG_a"), %%mm3  \n\t"
+        "packuswb  %%mm1, %%mm0         \n\t"
+                "pcmpeqd %%mm2, %%mm2   \n\t"
+                "paddb %%mm2, %%mm2     \n\t"
+                PAVGB_MMX(%%mm3, %%mm0, %%mm1, %%mm2)
+                "movq   %%mm1, (%2, %%"REG_a")  \n\t"
+        "add    %3, %%"REG_a"           \n\t"
+
+        "subl   $2, %0                  \n\t"
+        "jnz    1b                      \n\t"
+        :"+g"(h), "+S"(pixels)
+        :"D"(block), "r"((x86_reg)line_size)
+        :REG_a, "memory");
+}
diff --git a/libavcodec/x86/rv34dsp.asm b/libavcodec/x86/rv34dsp.asm
index c099ac5..4d9c35b 100644
--- a/libavcodec/x86/rv34dsp.asm
+++ b/libavcodec/x86/rv34dsp.asm
@@ -133,7 +133,7 @@ cglobal rv34_idct_dc_add, 3, 3
     mova        mm5, [pd_512]           ; 0x200
 %endmacro
 
-; ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
+; ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, int16_t *block);
 %macro COL_TRANSFORM  4
     pshufw      mm3, %2, 0xDD        ; col. 1,3,1,3
     pshufw       %2, %2, 0x88        ; col. 0,2,0,2
diff --git a/libavcodec/x86/rv34dsp_init.c b/libavcodec/x86/rv34dsp_init.c
index 6b6cf91..5f284b8 100644
--- a/libavcodec/x86/rv34dsp_init.c
+++ b/libavcodec/x86/rv34dsp_init.c
@@ -22,25 +22,24 @@
 #include "libavutil/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
 #include "libavcodec/rv34dsp.h"
 
-void ff_rv34_idct_dc_mmxext(DCTELEM *block);
-void ff_rv34_idct_dc_noround_mmxext(DCTELEM *block);
+void ff_rv34_idct_dc_mmxext(int16_t *block);
+void ff_rv34_idct_dc_noround_mmxext(int16_t *block);
 void ff_rv34_idct_dc_add_mmx(uint8_t *dst, ptrdiff_t stride, int dc);
 void ff_rv34_idct_dc_add_sse4(uint8_t *dst, ptrdiff_t stride, int dc);
-void ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
+void ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, int16_t *block);
 
-av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c, DSPContext *dsp)
+av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags))
+    if (EXTERNAL_MMX(cpu_flags))
         c->rv34_idct_dc_add = ff_rv34_idct_dc_add_mmx;
-    if (EXTERNAL_MMXEXT(mm_flags)) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         c->rv34_inv_transform_dc = ff_rv34_idct_dc_noround_mmxext;
         c->rv34_idct_add         = ff_rv34_idct_add_mmxext;
     }
-    if (EXTERNAL_SSE4(mm_flags))
+    if (EXTERNAL_SSE4(cpu_flags))
         c->rv34_idct_dc_add = ff_rv34_idct_dc_add_sse4;
 }
diff --git a/libavcodec/x86/rv40dsp.asm b/libavcodec/x86/rv40dsp.asm
index 7ec72be..d12b079 100644
--- a/libavcodec/x86/rv40dsp.asm
+++ b/libavcodec/x86/rv40dsp.asm
@@ -98,11 +98,7 @@ SECTION .text
 %endif
     packuswb  %1, %1
 %ifidn %3, avg
-%if cpuflag(3dnow)
-    pavgusb   %1, %2
-%else
-    pavgb     %1, %2
-%endif
+    PAVGB     %1, %2
 %endif
     movh  [dstq], %1
 %endmacro
diff --git a/libavcodec/x86/rv40dsp_init.c b/libavcodec/x86/rv40dsp_init.c
index a1dc22a..781f467 100644
--- a/libavcodec/x86/rv40dsp_init.c
+++ b/libavcodec/x86/rv40dsp_init.c
@@ -27,9 +27,10 @@
  */
 
 #include "libavcodec/rv34dsp.h"
+#include "libavutil/attributes.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/cpu.h"
-#include "dsputil_mmx.h"
+#include "dsputil_x86.h"
 
 #if HAVE_YASM
 void ff_put_rv40_chroma_mc8_mmx  (uint8_t *dst, uint8_t *src,
@@ -70,7 +71,7 @@ DECLARE_WEIGHT(ssse3)
 #define QPEL_FUNC_DECL(OP, SIZE, PH, PV, OPT)                           \
 static void OP ## rv40_qpel ##SIZE ##_mc ##PH ##PV ##OPT(uint8_t *dst,  \
                                                          uint8_t *src,  \
-                                                         int stride)    \
+                                                         ptrdiff_t stride)  \
 {                                                                       \
     int i;                                                              \
     if (PH && PV) {                                                     \
@@ -187,25 +188,58 @@ QPEL_FUNCS_SET (OP, 3, 2, OPT)
 
 #endif /* HAVE_YASM */
 
-void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp)
+#if HAVE_MMX_INLINE
+static void put_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride)
 {
-#if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    ff_put_pixels8_xy2_mmx(dst, src, stride, 8);
+}
+static void put_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src,
+                                     ptrdiff_t stride)
+{
+    ff_put_pixels16_xy2_mmx(dst, src, stride, 16);
+}
+static void avg_rv40_qpel8_mc33_mmx(uint8_t *dst, uint8_t *src,
+                                    ptrdiff_t stride)
+{
+    ff_avg_pixels8_xy2_mmx(dst, src, stride, 8);
+}
+static void avg_rv40_qpel16_mc33_mmx(uint8_t *dst, uint8_t *src,
+                                     ptrdiff_t stride)
+{
+    ff_avg_pixels16_xy2_mmx(dst, src, stride, 16);
+}
+#endif /* HAVE_MMX_INLINE */
+
+av_cold void ff_rv40dsp_init_x86(RV34DSPContext *c)
+{
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags)) {
-        c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx;
-        c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx;
 #if HAVE_MMX_INLINE
-        c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_mmx;
-        c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_mmx;
-        c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_mmx;
-        c->avg_pixels_tab[1][15] = ff_avg_rv40_qpel8_mc33_mmx;
+    if (INLINE_MMX(cpu_flags)) {
+        c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_mmx;
+        c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_mmx;
+        c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_mmx;
+        c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_mmx;
+    }
 #endif /* HAVE_MMX_INLINE */
+
+#if HAVE_YASM
+    if (EXTERNAL_MMX(cpu_flags)) {
+        c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx;
+        c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx;
 #if ARCH_X86_32
         QPEL_MC_SET(put_, _mmx)
 #endif
     }
-    if (EXTERNAL_MMXEXT(mm_flags)) {
+    if (EXTERNAL_AMD3DNOW(cpu_flags)) {
+        c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow;
+        c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow;
+#if ARCH_X86_32
+        QPEL_MC_SET(avg_, _3dnow)
+#endif
+    }
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         c->avg_chroma_pixels_tab[0]     = ff_avg_rv40_chroma_mc8_mmxext;
         c->avg_chroma_pixels_tab[1]     = ff_avg_rv40_chroma_mc4_mmxext;
         c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_mmxext;
@@ -215,14 +249,8 @@ void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp)
 #if ARCH_X86_32
         QPEL_MC_SET(avg_, _mmxext)
 #endif
-    } else if (EXTERNAL_AMD3DNOW(mm_flags)) {
-        c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow;
-        c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow;
-#if ARCH_X86_32
-        QPEL_MC_SET(avg_, _3dnow)
-#endif
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_sse2;
         c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_sse2;
         c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_sse2;
@@ -230,7 +258,7 @@ void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp)
         QPEL_MC_SET(put_, _sse2)
         QPEL_MC_SET(avg_, _sse2)
     }
-    if (EXTERNAL_SSSE3(mm_flags)) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_ssse3;
         c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_ssse3;
         c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_ssse3;
diff --git a/libavcodec/x86/sbrdsp.asm b/libavcodec/x86/sbrdsp.asm
index b87da4a..36a0918 100644
--- a/libavcodec/x86/sbrdsp.asm
+++ b/libavcodec/x86/sbrdsp.asm
@@ -24,6 +24,8 @@
 SECTION_RODATA
 ; mask equivalent for multiply by -1.0 1.0
 ps_mask         times 2 dd 1<<31, 0
+ps_mask2        times 2 dd 0, 1<<31
+ps_neg          times 4 dd 1<<31
 
 SECTION_TEXT
 
@@ -181,3 +183,123 @@ cglobal sbr_hf_gen, 4,4,8, X_high, X_low, alpha0, alpha1, BW, S, E
     add     start, 16
     jnz         .loop2
     RET
+
+cglobal sbr_sum64x5, 1,2,4,z
+    lea    r1q, [zq+ 256]
+.loop:
+    mova    m0, [zq+   0]
+    mova    m2, [zq+  16]
+    mova    m1, [zq+ 256]
+    mova    m3, [zq+ 272]
+    addps   m0, [zq+ 512]
+    addps   m2, [zq+ 528]
+    addps   m1, [zq+ 768]
+    addps   m3, [zq+ 784]
+    addps   m0, [zq+1024]
+    addps   m2, [zq+1040]
+    addps   m0, m1
+    addps   m2, m3
+    mova  [zq], m0
+    mova  [zq+16], m2
+    add     zq, 32
+    cmp     zq, r1q
+    jne  .loop
+    REP_RET
+
+INIT_XMM sse
+cglobal sbr_qmf_post_shuffle, 2,3,4,W,z
+    lea              r2q, [zq + (64-4)*4]
+    mova              m3, [ps_neg]
+.loop:
+    mova              m1, [zq]
+    xorps             m0, m3, [r2q]
+    shufps            m0, m0, m0, q0123
+    unpcklps          m2, m0, m1
+    unpckhps          m0, m0, m1
+    mova       [Wq +  0], m2
+    mova       [Wq + 16], m0
+    add               Wq, 32
+    sub              r2q, 16
+    add               zq, 16
+    cmp               zq, r2q
+    jl             .loop
+    REP_RET
+
+INIT_XMM sse
+cglobal sbr_neg_odd_64, 1,2,4,z
+    lea        r1q, [zq+256]
+.loop:
+    mova        m0, [zq+ 0]
+    mova        m1, [zq+16]
+    mova        m2, [zq+32]
+    mova        m3, [zq+48]
+    xorps       m0, [ps_mask2]
+    xorps       m1, [ps_mask2]
+    xorps       m2, [ps_mask2]
+    xorps       m3, [ps_mask2]
+    mova   [zq+ 0], m0
+    mova   [zq+16], m1
+    mova   [zq+32], m2
+    mova   [zq+48], m3
+    add         zq, 64
+    cmp         zq, r1q
+    jne      .loop
+    REP_RET
+
+INIT_XMM sse2
+; sbr_qmf_deint_bfly(float *v, const float *src0, const float *src1)
+cglobal sbr_qmf_deint_bfly, 3,5,8, v,src0,src1,vrev,c
+    mov               cq, 64*4-2*mmsize
+    lea            vrevq, [vq + 64*4]
+.loop:
+    mova              m0, [src0q+cq]
+    mova              m1, [src1q]
+    mova              m2, [src0q+cq+mmsize]
+    mova              m3, [src1q+mmsize]
+    pshufd            m4, m0, q0123
+    pshufd            m5, m1, q0123
+    pshufd            m6, m2, q0123
+    pshufd            m7, m3, q0123
+    addps             m3, m4
+    subps             m0, m7
+    addps             m1, m6
+    subps             m2, m5
+    mova         [vrevq], m1
+    mova  [vrevq+mmsize], m3
+    mova         [vq+cq], m0
+    mova  [vq+cq+mmsize], m2
+    add            src1q, 2*mmsize
+    add            vrevq, 2*mmsize
+    sub               cq, 2*mmsize
+    jge            .loop
+    REP_RET
+
+INIT_XMM sse2
+cglobal sbr_qmf_pre_shuffle, 1,4,6,z
+%define OFFSET  (32*4-2*mmsize)
+    mov       r3q, OFFSET
+    lea       r1q, [zq + (32+1)*4]
+    lea       r2q, [zq + 64*4]
+    mova       m5, [ps_neg]
+.loop:
+    movu       m0, [r1q]
+    movu       m2, [r1q + mmsize]
+    movu       m1, [zq + r3q + 4 + mmsize]
+    movu       m3, [zq + r3q + 4]
+
+    pxor       m2, m5
+    pxor       m0, m5
+    pshufd     m2, m2, q0123
+    pshufd     m0, m0, q0123
+    SBUTTERFLY dq, 2, 3, 4
+    SBUTTERFLY dq, 0, 1, 4
+    mova  [r2q + 2*r3q + 0*mmsize], m2
+    mova  [r2q + 2*r3q + 1*mmsize], m3
+    mova  [r2q + 2*r3q + 2*mmsize], m0
+    mova  [r2q + 2*r3q + 3*mmsize], m1
+    add       r1q, 2*mmsize
+    sub       r3q, 2*mmsize
+    jge      .loop
+    movq       m2, [zq]
+    movq    [r2q], m2
+    REP_RET
diff --git a/libavcodec/x86/sbrdsp_init.c b/libavcodec/x86/sbrdsp_init.c
index 51c4bd4..9600852 100644
--- a/libavcodec/x86/sbrdsp_init.c
+++ b/libavcodec/x86/sbrdsp_init.c
@@ -20,24 +20,38 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/sbrdsp.h"
 
 float ff_sbr_sum_square_sse(float (*x)[2], int n);
+void ff_sbr_sum64x5_sse(float *z);
 void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2],
                           const float *g_filt, int m_max, intptr_t ixh);
 void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2],
                        const float alpha0[2], const float alpha1[2],
                        float bw, int start, int end);
+void ff_sbr_neg_odd_64_sse(float *z);
+void ff_sbr_qmf_post_shuffle_sse(float W[32][2], const float *z);
+void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1);
+void ff_sbr_qmf_pre_shuffle_sse2(float *z);
 
-void ff_sbrdsp_init_x86(SBRDSPContext *s)
+av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
+        s->neg_odd_64 = ff_sbr_neg_odd_64_sse;
         s->sum_square = ff_sbr_sum_square_sse;
+        s->sum64x5    = ff_sbr_sum64x5_sse;
         s->hf_g_filt  = ff_sbr_hf_g_filt_sse;
         s->hf_gen     = ff_sbr_hf_gen_sse;
+        s->qmf_post_shuffle = ff_sbr_qmf_post_shuffle_sse;
+    }
+
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        s->qmf_deint_bfly   = ff_sbr_qmf_deint_bfly_sse2;
+        s->qmf_pre_shuffle  = ff_sbr_qmf_pre_shuffle_sse2;
     }
 }
diff --git a/libavcodec/x86/simple_idct.c b/libavcodec/x86/simple_idct.c
index 0e80933..36f0b47 100644
--- a/libavcodec/x86/simple_idct.c
+++ b/libavcodec/x86/simple_idct.c
@@ -19,11 +19,10 @@
  * License along with Libav; 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"
+#include "dsputil_x86.h"
 
 #if HAVE_INLINE_ASM
 
@@ -1155,12 +1154,12 @@ void ff_simple_idct_mmx(int16_t *block)
 
 //FIXME merge add/put into the idct
 
-void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block)
 {
     idct(block);
     ff_put_pixels_clamped_mmx(block, dest, line_size);
 }
-void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block)
+void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block)
 {
     idct(block);
     ff_add_pixels_clamped_mmx(block, dest, line_size);
diff --git a/libavcodec/x86/snowdsp.c b/libavcodec/x86/snowdsp.c
deleted file mode 100644
index fb190d8..0000000
--- a/libavcodec/x86/snowdsp.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/*
- * MMX and SSE2 optimized snow DSP utils
- * Copyright (c) 2005-2006 Robert Edele <yartrebo at earthlink.net>
- *
- * 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/cpu.h"
-#include "libavutil/x86/asm.h"
-#include "libavcodec/avcodec.h"
-#include "libavcodec/snow.h"
-#include "libavcodec/dwt.h"
-#include "dsputil_mmx.h"
-
-#if HAVE_INLINE_ASM
-
-static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, IDWTELEM *temp, int width){
-    const int w2= (width+1)>>1;
-    const int w_l= (width>>1);
-    const int w_r= w2 - 1;
-    int i;
-
-    { // Lift 0
-        IDWTELEM * const ref = b + w2 - 1;
-        IDWTELEM b_0 = b[0]; //By allowing the first entry in b[0] to be calculated twice
-        // (the first time erroneously), we allow the SSE2 code to run an extra pass.
-        // The savings in code and time are well worth having to store this value and
-        // calculate b[0] correctly afterwards.
-
-        i = 0;
-        __asm__ volatile(
-            "pcmpeqd   %%xmm7, %%xmm7         \n\t"
-            "pcmpeqd   %%xmm3, %%xmm3         \n\t"
-            "psllw         $1, %%xmm3         \n\t"
-            "paddw     %%xmm7, %%xmm3         \n\t"
-            "psllw        $13, %%xmm3         \n\t"
-        ::);
-        for(; i<w_l-15; i+=16){
-            __asm__ volatile(
-                "movdqu   (%1), %%xmm1        \n\t"
-                "movdqu 16(%1), %%xmm5        \n\t"
-                "movdqu  2(%1), %%xmm2        \n\t"
-                "movdqu 18(%1), %%xmm6        \n\t"
-                "paddw  %%xmm1, %%xmm2        \n\t"
-                "paddw  %%xmm5, %%xmm6        \n\t"
-                "paddw  %%xmm7, %%xmm2        \n\t"
-                "paddw  %%xmm7, %%xmm6        \n\t"
-                "pmulhw %%xmm3, %%xmm2        \n\t"
-                "pmulhw %%xmm3, %%xmm6        \n\t"
-                "paddw    (%0), %%xmm2        \n\t"
-                "paddw  16(%0), %%xmm6        \n\t"
-                "movdqa %%xmm2, (%0)          \n\t"
-                "movdqa %%xmm6, 16(%0)        \n\t"
-                :: "r"(&b[i]), "r"(&ref[i])
-                : "memory"
-            );
-        }
-        snow_horizontal_compose_lift_lead_out(i, b, b, ref, width, w_l, 0, W_DM, W_DO, W_DS);
-        b[0] = b_0 - ((W_DM * 2 * ref[1]+W_DO)>>W_DS);
-    }
-
-    { // Lift 1
-        IDWTELEM * const dst = b+w2;
-
-        i = 0;
-        for(; (((x86_reg)&dst[i]) & 0x1F) && i<w_r; i++){
-            dst[i] = dst[i] - (b[i] + b[i + 1]);
-        }
-        for(; i<w_r-15; i+=16){
-            __asm__ volatile(
-                "movdqu   (%1), %%xmm1        \n\t"
-                "movdqu 16(%1), %%xmm5        \n\t"
-                "movdqu  2(%1), %%xmm2        \n\t"
-                "movdqu 18(%1), %%xmm6        \n\t"
-                "paddw  %%xmm1, %%xmm2        \n\t"
-                "paddw  %%xmm5, %%xmm6        \n\t"
-                "movdqa   (%0), %%xmm0        \n\t"
-                "movdqa 16(%0), %%xmm4        \n\t"
-                "psubw  %%xmm2, %%xmm0        \n\t"
-                "psubw  %%xmm6, %%xmm4        \n\t"
-                "movdqa %%xmm0, (%0)          \n\t"
-                "movdqa %%xmm4, 16(%0)        \n\t"
-                :: "r"(&dst[i]), "r"(&b[i])
-                : "memory"
-            );
-        }
-        snow_horizontal_compose_lift_lead_out(i, dst, dst, b, width, w_r, 1, W_CM, W_CO, W_CS);
-    }
-
-    { // Lift 2
-        IDWTELEM * const ref = b+w2 - 1;
-        IDWTELEM b_0 = b[0];
-
-        i = 0;
-        __asm__ volatile(
-            "psllw         $15, %%xmm7        \n\t"
-            "pcmpeqw    %%xmm6, %%xmm6        \n\t"
-            "psrlw         $13, %%xmm6        \n\t"
-            "paddw      %%xmm7, %%xmm6        \n\t"
-        ::);
-        for(; i<w_l-15; i+=16){
-            __asm__ volatile(
-                "movdqu   (%1), %%xmm0        \n\t"
-                "movdqu 16(%1), %%xmm4        \n\t"
-                "movdqu  2(%1), %%xmm1        \n\t"
-                "movdqu 18(%1), %%xmm5        \n\t" //FIXME try aligned reads and shifts
-                "paddw  %%xmm6, %%xmm0        \n\t"
-                "paddw  %%xmm6, %%xmm4        \n\t"
-                "paddw  %%xmm7, %%xmm1        \n\t"
-                "paddw  %%xmm7, %%xmm5        \n\t"
-                "pavgw  %%xmm1, %%xmm0        \n\t"
-                "pavgw  %%xmm5, %%xmm4        \n\t"
-                "psubw  %%xmm7, %%xmm0        \n\t"
-                "psubw  %%xmm7, %%xmm4        \n\t"
-                "psraw      $1, %%xmm0        \n\t"
-                "psraw      $1, %%xmm4        \n\t"
-                "movdqa   (%0), %%xmm1        \n\t"
-                "movdqa 16(%0), %%xmm5        \n\t"
-                "paddw  %%xmm1, %%xmm0        \n\t"
-                "paddw  %%xmm5, %%xmm4        \n\t"
-                "psraw      $2, %%xmm0        \n\t"
-                "psraw      $2, %%xmm4        \n\t"
-                "paddw  %%xmm1, %%xmm0        \n\t"
-                "paddw  %%xmm5, %%xmm4        \n\t"
-                "movdqa %%xmm0, (%0)          \n\t"
-                "movdqa %%xmm4, 16(%0)        \n\t"
-                :: "r"(&b[i]), "r"(&ref[i])
-                : "memory"
-            );
-        }
-        snow_horizontal_compose_liftS_lead_out(i, b, b, ref, width, w_l);
-        b[0] = b_0 + ((2 * ref[1] + W_BO-1 + 4 * b_0) >> W_BS);
-    }
-
-    { // Lift 3
-        IDWTELEM * const src = b+w2;
-
-        i = 0;
-        for(; (((x86_reg)&temp[i]) & 0x1F) && i<w_r; i++){
-            temp[i] = src[i] - ((-W_AM*(b[i] + b[i+1]))>>W_AS);
-        }
-        for(; i<w_r-7; i+=8){
-            __asm__ volatile(
-                "movdqu  2(%1), %%xmm2        \n\t"
-                "movdqu 18(%1), %%xmm6        \n\t"
-                "paddw    (%1), %%xmm2        \n\t"
-                "paddw  16(%1), %%xmm6        \n\t"
-                "movdqu   (%0), %%xmm0        \n\t"
-                "movdqu 16(%0), %%xmm4        \n\t"
-                "paddw  %%xmm2, %%xmm0        \n\t"
-                "paddw  %%xmm6, %%xmm4        \n\t"
-                "psraw      $1, %%xmm2        \n\t"
-                "psraw      $1, %%xmm6        \n\t"
-                "paddw  %%xmm0, %%xmm2        \n\t"
-                "paddw  %%xmm4, %%xmm6        \n\t"
-                "movdqa %%xmm2, (%2)          \n\t"
-                "movdqa %%xmm6, 16(%2)        \n\t"
-                :: "r"(&src[i]), "r"(&b[i]), "r"(&temp[i])
-                 : "memory"
-               );
-        }
-        snow_horizontal_compose_lift_lead_out(i, temp, src, b, width, w_r, 1, -W_AM, W_AO+1, W_AS);
-    }
-
-    {
-        snow_interleave_line_header(&i, width, b, temp);
-
-        for (; (i & 0x3E) != 0x3E; i-=2){
-            b[i+1] = temp[i>>1];
-            b[i] = b[i>>1];
-        }
-        for (i-=62; i>=0; i-=64){
-            __asm__ volatile(
-                "movdqa      (%1), %%xmm0       \n\t"
-                "movdqa    16(%1), %%xmm2       \n\t"
-                "movdqa    32(%1), %%xmm4       \n\t"
-                "movdqa    48(%1), %%xmm6       \n\t"
-                "movdqa      (%1), %%xmm1       \n\t"
-                "movdqa    16(%1), %%xmm3       \n\t"
-                "movdqa    32(%1), %%xmm5       \n\t"
-                "movdqa    48(%1), %%xmm7       \n\t"
-                "punpcklwd   (%2), %%xmm0       \n\t"
-                "punpcklwd 16(%2), %%xmm2       \n\t"
-                "punpcklwd 32(%2), %%xmm4       \n\t"
-                "punpcklwd 48(%2), %%xmm6       \n\t"
-                "movdqa    %%xmm0, (%0)         \n\t"
-                "movdqa    %%xmm2, 32(%0)       \n\t"
-                "movdqa    %%xmm4, 64(%0)       \n\t"
-                "movdqa    %%xmm6, 96(%0)       \n\t"
-                "punpckhwd   (%2), %%xmm1       \n\t"
-                "punpckhwd 16(%2), %%xmm3       \n\t"
-                "punpckhwd 32(%2), %%xmm5       \n\t"
-                "punpckhwd 48(%2), %%xmm7       \n\t"
-                "movdqa    %%xmm1, 16(%0)       \n\t"
-                "movdqa    %%xmm3, 48(%0)       \n\t"
-                "movdqa    %%xmm5, 80(%0)       \n\t"
-                "movdqa    %%xmm7, 112(%0)      \n\t"
-                :: "r"(&(b)[i]), "r"(&(b)[i>>1]), "r"(&(temp)[i>>1])
-                 : "memory"
-               );
-        }
-    }
-}
-
-static void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, IDWTELEM *temp, int width){
-    const int w2= (width+1)>>1;
-    const int w_l= (width>>1);
-    const int w_r= w2 - 1;
-    int i;
-
-    { // Lift 0
-        IDWTELEM * const ref = b + w2 - 1;
-
-        i = 1;
-        b[0] = b[0] - ((W_DM * 2 * ref[1]+W_DO)>>W_DS);
-        __asm__ volatile(
-            "pcmpeqw    %%mm7, %%mm7         \n\t"
-            "pcmpeqw    %%mm3, %%mm3         \n\t"
-            "psllw         $1, %%mm3         \n\t"
-            "paddw      %%mm7, %%mm3         \n\t"
-            "psllw        $13, %%mm3         \n\t"
-           ::);
-        for(; i<w_l-7; i+=8){
-            __asm__ volatile(
-                "movq     (%1), %%mm2        \n\t"
-                "movq    8(%1), %%mm6        \n\t"
-                "paddw   2(%1), %%mm2        \n\t"
-                "paddw  10(%1), %%mm6        \n\t"
-                "paddw   %%mm7, %%mm2        \n\t"
-                "paddw   %%mm7, %%mm6        \n\t"
-                "pmulhw  %%mm3, %%mm2        \n\t"
-                "pmulhw  %%mm3, %%mm6        \n\t"
-                "paddw    (%0), %%mm2        \n\t"
-                "paddw   8(%0), %%mm6        \n\t"
-                "movq    %%mm2, (%0)         \n\t"
-                "movq    %%mm6, 8(%0)        \n\t"
-                :: "r"(&b[i]), "r"(&ref[i])
-                 : "memory"
-               );
-        }
-        snow_horizontal_compose_lift_lead_out(i, b, b, ref, width, w_l, 0, W_DM, W_DO, W_DS);
-    }
-
-    { // Lift 1
-        IDWTELEM * const dst = b+w2;
-
-        i = 0;
-        for(; i<w_r-7; i+=8){
-            __asm__ volatile(
-                "movq     (%1), %%mm2        \n\t"
-                "movq    8(%1), %%mm6        \n\t"
-                "paddw   2(%1), %%mm2        \n\t"
-                "paddw  10(%1), %%mm6        \n\t"
-                "movq     (%0), %%mm0        \n\t"
-                "movq    8(%0), %%mm4        \n\t"
-                "psubw   %%mm2, %%mm0        \n\t"
-                "psubw   %%mm6, %%mm4        \n\t"
-                "movq    %%mm0, (%0)         \n\t"
-                "movq    %%mm4, 8(%0)        \n\t"
-                :: "r"(&dst[i]), "r"(&b[i])
-                 : "memory"
-               );
-        }
-        snow_horizontal_compose_lift_lead_out(i, dst, dst, b, width, w_r, 1, W_CM, W_CO, W_CS);
-    }
-
-    { // Lift 2
-        IDWTELEM * const ref = b+w2 - 1;
-
-        i = 1;
-        b[0] = b[0] + (((2 * ref[1] + W_BO) + 4 * b[0]) >> W_BS);
-        __asm__ volatile(
-            "psllw         $15, %%mm7        \n\t"
-            "pcmpeqw     %%mm6, %%mm6        \n\t"
-            "psrlw         $13, %%mm6        \n\t"
-            "paddw       %%mm7, %%mm6        \n\t"
-           ::);
-        for(; i<w_l-7; i+=8){
-            __asm__ volatile(
-                "movq     (%1), %%mm0        \n\t"
-                "movq    8(%1), %%mm4        \n\t"
-                "movq    2(%1), %%mm1        \n\t"
-                "movq   10(%1), %%mm5        \n\t"
-                "paddw   %%mm6, %%mm0        \n\t"
-                "paddw   %%mm6, %%mm4        \n\t"
-                "paddw   %%mm7, %%mm1        \n\t"
-                "paddw   %%mm7, %%mm5        \n\t"
-                "pavgw   %%mm1, %%mm0        \n\t"
-                "pavgw   %%mm5, %%mm4        \n\t"
-                "psubw   %%mm7, %%mm0        \n\t"
-                "psubw   %%mm7, %%mm4        \n\t"
-                "psraw      $1, %%mm0        \n\t"
-                "psraw      $1, %%mm4        \n\t"
-                "movq     (%0), %%mm1        \n\t"
-                "movq    8(%0), %%mm5        \n\t"
-                "paddw   %%mm1, %%mm0        \n\t"
-                "paddw   %%mm5, %%mm4        \n\t"
-                "psraw      $2, %%mm0        \n\t"
-                "psraw      $2, %%mm4        \n\t"
-                "paddw   %%mm1, %%mm0        \n\t"
-                "paddw   %%mm5, %%mm4        \n\t"
-                "movq    %%mm0, (%0)         \n\t"
-                "movq    %%mm4, 8(%0)        \n\t"
-                :: "r"(&b[i]), "r"(&ref[i])
-                 : "memory"
-               );
-        }
-        snow_horizontal_compose_liftS_lead_out(i, b, b, ref, width, w_l);
-    }
-
-    { // Lift 3
-        IDWTELEM * const src = b+w2;
-        i = 0;
-
-        for(; i<w_r-7; i+=8){
-            __asm__ volatile(
-                "movq    2(%1), %%mm2        \n\t"
-                "movq   10(%1), %%mm6        \n\t"
-                "paddw    (%1), %%mm2        \n\t"
-                "paddw   8(%1), %%mm6        \n\t"
-                "movq     (%0), %%mm0        \n\t"
-                "movq    8(%0), %%mm4        \n\t"
-                "paddw   %%mm2, %%mm0        \n\t"
-                "paddw   %%mm6, %%mm4        \n\t"
-                "psraw      $1, %%mm2        \n\t"
-                "psraw      $1, %%mm6        \n\t"
-                "paddw   %%mm0, %%mm2        \n\t"
-                "paddw   %%mm4, %%mm6        \n\t"
-                "movq    %%mm2, (%2)         \n\t"
-                "movq    %%mm6, 8(%2)        \n\t"
-                :: "r"(&src[i]), "r"(&b[i]), "r"(&temp[i])
-                 : "memory"
-               );
-        }
-        snow_horizontal_compose_lift_lead_out(i, temp, src, b, width, w_r, 1, -W_AM, W_AO+1, W_AS);
-    }
-
-    {
-        snow_interleave_line_header(&i, width, b, temp);
-
-        for (; (i & 0x1E) != 0x1E; i-=2){
-            b[i+1] = temp[i>>1];
-            b[i] = b[i>>1];
-        }
-        for (i-=30; i>=0; i-=32){
-            __asm__ volatile(
-                "movq        (%1), %%mm0       \n\t"
-                "movq       8(%1), %%mm2       \n\t"
-                "movq      16(%1), %%mm4       \n\t"
-                "movq      24(%1), %%mm6       \n\t"
-                "movq        (%1), %%mm1       \n\t"
-                "movq       8(%1), %%mm3       \n\t"
-                "movq      16(%1), %%mm5       \n\t"
-                "movq      24(%1), %%mm7       \n\t"
-                "punpcklwd   (%2), %%mm0       \n\t"
-                "punpcklwd  8(%2), %%mm2       \n\t"
-                "punpcklwd 16(%2), %%mm4       \n\t"
-                "punpcklwd 24(%2), %%mm6       \n\t"
-                "movq       %%mm0, (%0)        \n\t"
-                "movq       %%mm2, 16(%0)      \n\t"
-                "movq       %%mm4, 32(%0)      \n\t"
-                "movq       %%mm6, 48(%0)      \n\t"
-                "punpckhwd   (%2), %%mm1       \n\t"
-                "punpckhwd  8(%2), %%mm3       \n\t"
-                "punpckhwd 16(%2), %%mm5       \n\t"
-                "punpckhwd 24(%2), %%mm7       \n\t"
-                "movq       %%mm1, 8(%0)       \n\t"
-                "movq       %%mm3, 24(%0)      \n\t"
-                "movq       %%mm5, 40(%0)      \n\t"
-                "movq       %%mm7, 56(%0)      \n\t"
-                :: "r"(&b[i]), "r"(&b[i>>1]), "r"(&temp[i>>1])
-                 : "memory"
-               );
-        }
-    }
-}
-
-#if HAVE_7REGS
-#define snow_vertical_compose_sse2_load_add(op,r,t0,t1,t2,t3)\
-        ""op" ("r",%%"REG_d"), %%"t0"      \n\t"\
-        ""op" 16("r",%%"REG_d"), %%"t1"    \n\t"\
-        ""op" 32("r",%%"REG_d"), %%"t2"    \n\t"\
-        ""op" 48("r",%%"REG_d"), %%"t3"    \n\t"
-
-#define snow_vertical_compose_sse2_load(r,t0,t1,t2,t3)\
-        snow_vertical_compose_sse2_load_add("movdqa",r,t0,t1,t2,t3)
-
-#define snow_vertical_compose_sse2_add(r,t0,t1,t2,t3)\
-        snow_vertical_compose_sse2_load_add("paddw",r,t0,t1,t2,t3)
-
-#define snow_vertical_compose_r2r_sub(s0,s1,s2,s3,t0,t1,t2,t3)\
-        "psubw %%"s0", %%"t0" \n\t"\
-        "psubw %%"s1", %%"t1" \n\t"\
-        "psubw %%"s2", %%"t2" \n\t"\
-        "psubw %%"s3", %%"t3" \n\t"
-
-#define snow_vertical_compose_sse2_store(w,s0,s1,s2,s3)\
-        "movdqa %%"s0", ("w",%%"REG_d")      \n\t"\
-        "movdqa %%"s1", 16("w",%%"REG_d")    \n\t"\
-        "movdqa %%"s2", 32("w",%%"REG_d")    \n\t"\
-        "movdqa %%"s3", 48("w",%%"REG_d")    \n\t"
-
-#define snow_vertical_compose_sra(n,t0,t1,t2,t3)\
-        "psraw $"n", %%"t0" \n\t"\
-        "psraw $"n", %%"t1" \n\t"\
-        "psraw $"n", %%"t2" \n\t"\
-        "psraw $"n", %%"t3" \n\t"
-
-#define snow_vertical_compose_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\
-        "paddw %%"s0", %%"t0" \n\t"\
-        "paddw %%"s1", %%"t1" \n\t"\
-        "paddw %%"s2", %%"t2" \n\t"\
-        "paddw %%"s3", %%"t3" \n\t"
-
-#define snow_vertical_compose_r2r_pmulhw(s0,s1,s2,s3,t0,t1,t2,t3)\
-        "pmulhw %%"s0", %%"t0" \n\t"\
-        "pmulhw %%"s1", %%"t1" \n\t"\
-        "pmulhw %%"s2", %%"t2" \n\t"\
-        "pmulhw %%"s3", %%"t3" \n\t"
-
-#define snow_vertical_compose_sse2_move(s0,s1,s2,s3,t0,t1,t2,t3)\
-        "movdqa %%"s0", %%"t0" \n\t"\
-        "movdqa %%"s1", %%"t1" \n\t"\
-        "movdqa %%"s2", %%"t2" \n\t"\
-        "movdqa %%"s3", %%"t3" \n\t"
-
-static void ff_snow_vertical_compose97i_sse2(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){
-    x86_reg i = width;
-
-    while(i & 0x1F)
-    {
-        i--;
-        b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS;
-        b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS;
-        b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS;
-        b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
-    }
-    i+=i;
-
-         __asm__ volatile (
-        "jmp 2f                                      \n\t"
-        "1:                                          \n\t"
-        snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%6","xmm0","xmm2","xmm4","xmm6")
-
-
-        "pcmpeqw    %%xmm0, %%xmm0                   \n\t"
-        "pcmpeqw    %%xmm2, %%xmm2                   \n\t"
-        "paddw      %%xmm2, %%xmm2                   \n\t"
-        "paddw      %%xmm0, %%xmm2                   \n\t"
-        "psllw         $13, %%xmm2                   \n\t"
-        snow_vertical_compose_r2r_add("xmm0","xmm0","xmm0","xmm0","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_r2r_pmulhw("xmm2","xmm2","xmm2","xmm2","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_sse2_add("%5","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_sse2_store("%5","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%3","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_r2r_sub("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_store("%4","xmm0","xmm2","xmm4","xmm6")
-
-        "pcmpeqw %%xmm7, %%xmm7                      \n\t"
-        "pcmpeqw %%xmm5, %%xmm5                      \n\t"
-        "psllw $15, %%xmm7                           \n\t"
-        "psrlw $13, %%xmm5                           \n\t"
-        "paddw %%xmm7, %%xmm5                        \n\t"
-        snow_vertical_compose_r2r_add("xmm5","xmm5","xmm5","xmm5","xmm0","xmm2","xmm4","xmm6")
-        "movq   (%2,%%"REG_d"), %%xmm1        \n\t"
-        "movq  8(%2,%%"REG_d"), %%xmm3        \n\t"
-        "paddw %%xmm7, %%xmm1                        \n\t"
-        "paddw %%xmm7, %%xmm3                        \n\t"
-        "pavgw %%xmm1, %%xmm0                        \n\t"
-        "pavgw %%xmm3, %%xmm2                        \n\t"
-        "movq 16(%2,%%"REG_d"), %%xmm1        \n\t"
-        "movq 24(%2,%%"REG_d"), %%xmm3        \n\t"
-        "paddw %%xmm7, %%xmm1                        \n\t"
-        "paddw %%xmm7, %%xmm3                        \n\t"
-        "pavgw %%xmm1, %%xmm4                        \n\t"
-        "pavgw %%xmm3, %%xmm6                        \n\t"
-        snow_vertical_compose_r2r_sub("xmm7","xmm7","xmm7","xmm7","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6")
-
-        snow_vertical_compose_sra("2","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_store("%3","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%1","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7")
-        snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_add("%2","xmm0","xmm2","xmm4","xmm6")
-        snow_vertical_compose_sse2_store("%2","xmm0","xmm2","xmm4","xmm6")
-
-        "2:                                          \n\t"
-        "sub $64, %%"REG_d"                          \n\t"
-        "jge 1b                                      \n\t"
-        :"+d"(i)
-        :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5));
-}
-
-#define snow_vertical_compose_mmx_load_add(op,r,t0,t1,t2,t3)\
-        ""op" ("r",%%"REG_d"), %%"t0"   \n\t"\
-        ""op" 8("r",%%"REG_d"), %%"t1"  \n\t"\
-        ""op" 16("r",%%"REG_d"), %%"t2" \n\t"\
-        ""op" 24("r",%%"REG_d"), %%"t3" \n\t"
-
-#define snow_vertical_compose_mmx_load(r,t0,t1,t2,t3)\
-        snow_vertical_compose_mmx_load_add("movq",r,t0,t1,t2,t3)
-
-#define snow_vertical_compose_mmx_add(r,t0,t1,t2,t3)\
-        snow_vertical_compose_mmx_load_add("paddw",r,t0,t1,t2,t3)
-
-#define snow_vertical_compose_mmx_store(w,s0,s1,s2,s3)\
-        "movq %%"s0", ("w",%%"REG_d")   \n\t"\
-        "movq %%"s1", 8("w",%%"REG_d")  \n\t"\
-        "movq %%"s2", 16("w",%%"REG_d") \n\t"\
-        "movq %%"s3", 24("w",%%"REG_d") \n\t"
-
-#define snow_vertical_compose_mmx_move(s0,s1,s2,s3,t0,t1,t2,t3)\
-        "movq %%"s0", %%"t0" \n\t"\
-        "movq %%"s1", %%"t1" \n\t"\
-        "movq %%"s2", %%"t2" \n\t"\
-        "movq %%"s3", %%"t3" \n\t"
-
-
-static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){
-    x86_reg i = width;
-    while(i & 15)
-    {
-        i--;
-        b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS;
-        b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS;
-        b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS;
-        b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
-    }
-    i+=i;
-    __asm__ volatile(
-        "jmp 2f                                      \n\t"
-        "1:                                          \n\t"
-
-        snow_vertical_compose_mmx_load("%4","mm1","mm3","mm5","mm7")
-        snow_vertical_compose_mmx_add("%6","mm1","mm3","mm5","mm7")
-        "pcmpeqw    %%mm0, %%mm0                     \n\t"
-        "pcmpeqw    %%mm2, %%mm2                     \n\t"
-        "paddw      %%mm2, %%mm2                     \n\t"
-        "paddw      %%mm0, %%mm2                     \n\t"
-        "psllw        $13, %%mm2                     \n\t"
-        snow_vertical_compose_r2r_add("mm0","mm0","mm0","mm0","mm1","mm3","mm5","mm7")
-        snow_vertical_compose_r2r_pmulhw("mm2","mm2","mm2","mm2","mm1","mm3","mm5","mm7")
-        snow_vertical_compose_mmx_add("%5","mm1","mm3","mm5","mm7")
-        snow_vertical_compose_mmx_store("%5","mm1","mm3","mm5","mm7")
-        snow_vertical_compose_mmx_load("%4","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_add("%3","mm1","mm3","mm5","mm7")
-        snow_vertical_compose_r2r_sub("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_store("%4","mm0","mm2","mm4","mm6")
-        "pcmpeqw %%mm7, %%mm7                        \n\t"
-        "pcmpeqw %%mm5, %%mm5                        \n\t"
-        "psllw $15, %%mm7                            \n\t"
-        "psrlw $13, %%mm5                            \n\t"
-        "paddw %%mm7, %%mm5                          \n\t"
-        snow_vertical_compose_r2r_add("mm5","mm5","mm5","mm5","mm0","mm2","mm4","mm6")
-        "movq   (%2,%%"REG_d"), %%mm1         \n\t"
-        "movq  8(%2,%%"REG_d"), %%mm3         \n\t"
-        "paddw %%mm7, %%mm1                          \n\t"
-        "paddw %%mm7, %%mm3                          \n\t"
-        "pavgw %%mm1, %%mm0                          \n\t"
-        "pavgw %%mm3, %%mm2                          \n\t"
-        "movq 16(%2,%%"REG_d"), %%mm1         \n\t"
-        "movq 24(%2,%%"REG_d"), %%mm3         \n\t"
-        "paddw %%mm7, %%mm1                          \n\t"
-        "paddw %%mm7, %%mm3                          \n\t"
-        "pavgw %%mm1, %%mm4                          \n\t"
-        "pavgw %%mm3, %%mm6                          \n\t"
-        snow_vertical_compose_r2r_sub("mm7","mm7","mm7","mm7","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6")
-
-        snow_vertical_compose_sra("2","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_store("%3","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_add("%1","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_move("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7")
-        snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_add("%2","mm0","mm2","mm4","mm6")
-        snow_vertical_compose_mmx_store("%2","mm0","mm2","mm4","mm6")
-
-        "2:                                          \n\t"
-        "sub $32, %%"REG_d"                          \n\t"
-        "jge 1b                                      \n\t"
-        :"+d"(i)
-        :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5));
-}
-#endif //HAVE_7REGS
-
-#define snow_inner_add_yblock_sse2_header \
-    IDWTELEM * * dst_array = sb->line + src_y;\
-    x86_reg tmp;\
-    __asm__ volatile(\
-             "mov  %7, %%"REG_c"             \n\t"\
-             "mov  %6, %2                    \n\t"\
-             "mov  %4, %%"REG_S"             \n\t"\
-             "pxor %%xmm7, %%xmm7            \n\t" /* 0 */\
-             "pcmpeqd %%xmm3, %%xmm3         \n\t"\
-             "psllw $15, %%xmm3              \n\t"\
-             "psrlw $12, %%xmm3              \n\t" /* FRAC_BITS >> 1 */\
-             "1:                             \n\t"\
-             "mov %1, %%"REG_D"              \n\t"\
-             "mov (%%"REG_D"), %%"REG_D"     \n\t"\
-             "add %3, %%"REG_D"              \n\t"
-
-#define snow_inner_add_yblock_sse2_start_8(out_reg1, out_reg2, ptr_offset, s_offset)\
-             "mov "PTR_SIZE"*"ptr_offset"(%%"REG_a"), %%"REG_d"; \n\t"\
-             "movq (%%"REG_d"), %%"out_reg1" \n\t"\
-             "movq (%%"REG_d", %%"REG_c"), %%"out_reg2" \n\t"\
-             "punpcklbw %%xmm7, %%"out_reg1" \n\t"\
-             "punpcklbw %%xmm7, %%"out_reg2" \n\t"\
-             "movq "s_offset"(%%"REG_S"), %%xmm0 \n\t"\
-             "movq "s_offset"+16(%%"REG_S"), %%xmm4 \n\t"\
-             "punpcklbw %%xmm7, %%xmm0       \n\t"\
-             "punpcklbw %%xmm7, %%xmm4       \n\t"\
-             "pmullw %%xmm0, %%"out_reg1"    \n\t"\
-             "pmullw %%xmm4, %%"out_reg2"    \n\t"
-
-#define snow_inner_add_yblock_sse2_start_16(out_reg1, out_reg2, ptr_offset, s_offset)\
-             "mov "PTR_SIZE"*"ptr_offset"(%%"REG_a"), %%"REG_d"; \n\t"\
-             "movq (%%"REG_d"), %%"out_reg1" \n\t"\
-             "movq 8(%%"REG_d"), %%"out_reg2" \n\t"\
-             "punpcklbw %%xmm7, %%"out_reg1" \n\t"\
-             "punpcklbw %%xmm7, %%"out_reg2" \n\t"\
-             "movq "s_offset"(%%"REG_S"), %%xmm0 \n\t"\
-             "movq "s_offset"+8(%%"REG_S"), %%xmm4 \n\t"\
-             "punpcklbw %%xmm7, %%xmm0       \n\t"\
-             "punpcklbw %%xmm7, %%xmm4       \n\t"\
-             "pmullw %%xmm0, %%"out_reg1"    \n\t"\
-             "pmullw %%xmm4, %%"out_reg2"    \n\t"
-
-#define snow_inner_add_yblock_sse2_accum_8(ptr_offset, s_offset) \
-             snow_inner_add_yblock_sse2_start_8("xmm2", "xmm6", ptr_offset, s_offset)\
-             "paddusw %%xmm2, %%xmm1         \n\t"\
-             "paddusw %%xmm6, %%xmm5         \n\t"
-
-#define snow_inner_add_yblock_sse2_accum_16(ptr_offset, s_offset) \
-             snow_inner_add_yblock_sse2_start_16("xmm2", "xmm6", ptr_offset, s_offset)\
-             "paddusw %%xmm2, %%xmm1         \n\t"\
-             "paddusw %%xmm6, %%xmm5         \n\t"
-
-#define snow_inner_add_yblock_sse2_end_common1\
-             "add $32, %%"REG_S"             \n\t"\
-             "add %%"REG_c", %0              \n\t"\
-             "add %%"REG_c", "PTR_SIZE"*3(%%"REG_a");\n\t"\
-             "add %%"REG_c", "PTR_SIZE"*2(%%"REG_a");\n\t"\
-             "add %%"REG_c", "PTR_SIZE"*1(%%"REG_a");\n\t"\
-             "add %%"REG_c", (%%"REG_a")     \n\t"
-
-#define snow_inner_add_yblock_sse2_end_common2\
-             "jnz 1b                         \n\t"\
-             :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\
-             :\
-             "rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\
-             "%"REG_c"","%"REG_S"","%"REG_D"","%"REG_d"");
-
-#define snow_inner_add_yblock_sse2_end_8\
-             "sal $1, %%"REG_c"              \n\t"\
-             "addl $"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"\
-             snow_inner_add_yblock_sse2_end_common1\
-             "dec %2                         \n\t"\
-             snow_inner_add_yblock_sse2_end_common2
-
-static void inner_add_yblock_bw_8_obmc_16_bh_even_sse2(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){
-snow_inner_add_yblock_sse2_header
-snow_inner_add_yblock_sse2_start_8("xmm1", "xmm5", "3", "0")
-snow_inner_add_yblock_sse2_accum_8("2", "8")
-snow_inner_add_yblock_sse2_accum_8("1", "128")
-snow_inner_add_yblock_sse2_accum_8("0", "136")
-
-             "mov %0, %%"REG_d"              \n\t"
-             "movdqa (%%"REG_D"), %%xmm0     \n\t"
-             "movdqa %%xmm1, %%xmm2          \n\t"
-
-             "punpckhwd %%xmm7, %%xmm1       \n\t"
-             "punpcklwd %%xmm7, %%xmm2       \n\t"
-             "paddd %%xmm2, %%xmm0           \n\t"
-             "movdqa 16(%%"REG_D"), %%xmm2   \n\t"
-             "paddd %%xmm1, %%xmm2           \n\t"
-             "paddd %%xmm3, %%xmm0           \n\t"
-             "paddd %%xmm3, %%xmm2           \n\t"
-
-             "mov %1, %%"REG_D"              \n\t"
-             "mov "PTR_SIZE"(%%"REG_D"), %%"REG_D";\n\t"
-             "add %3, %%"REG_D"              \n\t"
-
-             "movdqa (%%"REG_D"), %%xmm4     \n\t"
-             "movdqa %%xmm5, %%xmm6          \n\t"
-             "punpckhwd %%xmm7, %%xmm5       \n\t"
-             "punpcklwd %%xmm7, %%xmm6       \n\t"
-             "paddd %%xmm6, %%xmm4           \n\t"
-             "movdqa 16(%%"REG_D"), %%xmm6   \n\t"
-             "paddd %%xmm5, %%xmm6           \n\t"
-             "paddd %%xmm3, %%xmm4           \n\t"
-             "paddd %%xmm3, %%xmm6           \n\t"
-
-             "psrad $8, %%xmm0               \n\t" /* FRAC_BITS. */
-             "psrad $8, %%xmm2               \n\t" /* FRAC_BITS. */
-             "packssdw %%xmm2, %%xmm0        \n\t"
-             "packuswb %%xmm7, %%xmm0        \n\t"
-             "movq %%xmm0, (%%"REG_d")       \n\t"
-
-             "psrad $8, %%xmm4               \n\t" /* FRAC_BITS. */
-             "psrad $8, %%xmm6               \n\t" /* FRAC_BITS. */
-             "packssdw %%xmm6, %%xmm4        \n\t"
-             "packuswb %%xmm7, %%xmm4        \n\t"
-             "movq %%xmm4, (%%"REG_d",%%"REG_c");\n\t"
-snow_inner_add_yblock_sse2_end_8
-}
-
-static void inner_add_yblock_bw_16_obmc_32_sse2(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){
-snow_inner_add_yblock_sse2_header
-snow_inner_add_yblock_sse2_start_16("xmm1", "xmm5", "3", "0")
-snow_inner_add_yblock_sse2_accum_16("2", "16")
-snow_inner_add_yblock_sse2_accum_16("1", "512")
-snow_inner_add_yblock_sse2_accum_16("0", "528")
-
-             "mov %0, %%"REG_d"              \n\t"
-             "psrlw $4, %%xmm1               \n\t"
-             "psrlw $4, %%xmm5               \n\t"
-             "paddw   (%%"REG_D"), %%xmm1    \n\t"
-             "paddw 16(%%"REG_D"), %%xmm5    \n\t"
-             "paddw %%xmm3, %%xmm1           \n\t"
-             "paddw %%xmm3, %%xmm5           \n\t"
-             "psraw $4, %%xmm1               \n\t" /* FRAC_BITS. */
-             "psraw $4, %%xmm5               \n\t" /* FRAC_BITS. */
-             "packuswb %%xmm5, %%xmm1        \n\t"
-
-             "movdqu %%xmm1, (%%"REG_d")       \n\t"
-
-snow_inner_add_yblock_sse2_end_16
-}
-
-#define snow_inner_add_yblock_mmx_header \
-    IDWTELEM * * dst_array = sb->line + src_y;\
-    x86_reg tmp;\
-    __asm__ volatile(\
-             "mov  %7, %%"REG_c"             \n\t"\
-             "mov  %6, %2                    \n\t"\
-             "mov  %4, %%"REG_S"             \n\t"\
-             "pxor %%mm7, %%mm7              \n\t" /* 0 */\
-             "pcmpeqd %%mm3, %%mm3           \n\t"\
-             "psllw $15, %%mm3               \n\t"\
-             "psrlw $12, %%mm3               \n\t" /* FRAC_BITS >> 1 */\
-             "1:                             \n\t"\
-             "mov %1, %%"REG_D"              \n\t"\
-             "mov (%%"REG_D"), %%"REG_D"     \n\t"\
-             "add %3, %%"REG_D"              \n\t"
-
-#define snow_inner_add_yblock_mmx_start(out_reg1, out_reg2, ptr_offset, s_offset, d_offset)\
-             "mov "PTR_SIZE"*"ptr_offset"(%%"REG_a"), %%"REG_d"; \n\t"\
-             "movd "d_offset"(%%"REG_d"), %%"out_reg1" \n\t"\
-             "movd "d_offset"+4(%%"REG_d"), %%"out_reg2" \n\t"\
-             "punpcklbw %%mm7, %%"out_reg1" \n\t"\
-             "punpcklbw %%mm7, %%"out_reg2" \n\t"\
-             "movd "s_offset"(%%"REG_S"), %%mm0 \n\t"\
-             "movd "s_offset"+4(%%"REG_S"), %%mm4 \n\t"\
-             "punpcklbw %%mm7, %%mm0       \n\t"\
-             "punpcklbw %%mm7, %%mm4       \n\t"\
-             "pmullw %%mm0, %%"out_reg1"    \n\t"\
-             "pmullw %%mm4, %%"out_reg2"    \n\t"
-
-#define snow_inner_add_yblock_mmx_accum(ptr_offset, s_offset, d_offset) \
-             snow_inner_add_yblock_mmx_start("mm2", "mm6", ptr_offset, s_offset, d_offset)\
-             "paddusw %%mm2, %%mm1         \n\t"\
-             "paddusw %%mm6, %%mm5         \n\t"
-
-#define snow_inner_add_yblock_mmx_mix(read_offset, write_offset)\
-             "mov %0, %%"REG_d"              \n\t"\
-             "psrlw $4, %%mm1                \n\t"\
-             "psrlw $4, %%mm5                \n\t"\
-             "paddw "read_offset"(%%"REG_D"), %%mm1 \n\t"\
-             "paddw "read_offset"+8(%%"REG_D"), %%mm5 \n\t"\
-             "paddw %%mm3, %%mm1             \n\t"\
-             "paddw %%mm3, %%mm5             \n\t"\
-             "psraw $4, %%mm1                \n\t"\
-             "psraw $4, %%mm5                \n\t"\
-             "packuswb %%mm5, %%mm1          \n\t"\
-             "movq %%mm1, "write_offset"(%%"REG_d") \n\t"
-
-#define snow_inner_add_yblock_mmx_end(s_step)\
-             "add $"s_step", %%"REG_S"             \n\t"\
-             "add %%"REG_c", "PTR_SIZE"*3(%%"REG_a");\n\t"\
-             "add %%"REG_c", "PTR_SIZE"*2(%%"REG_a");\n\t"\
-             "add %%"REG_c", "PTR_SIZE"*1(%%"REG_a");\n\t"\
-             "add %%"REG_c", (%%"REG_a")     \n\t"\
-             "add"OPSIZE " $"PTR_SIZE"*1, %1 \n\t"\
-             "add %%"REG_c", %0              \n\t"\
-             "dec %2                         \n\t"\
-             "jnz 1b                         \n\t"\
-             :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\
-             :\
-             "rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\
-             "%"REG_c"","%"REG_S"","%"REG_D"","%"REG_d"");
-
-static void inner_add_yblock_bw_8_obmc_16_mmx(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){
-snow_inner_add_yblock_mmx_header
-snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0")
-snow_inner_add_yblock_mmx_accum("2", "8", "0")
-snow_inner_add_yblock_mmx_accum("1", "128", "0")
-snow_inner_add_yblock_mmx_accum("0", "136", "0")
-snow_inner_add_yblock_mmx_mix("0", "0")
-snow_inner_add_yblock_mmx_end("16")
-}
-
-static void inner_add_yblock_bw_16_obmc_32_mmx(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h,
-                      int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){
-snow_inner_add_yblock_mmx_header
-snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0")
-snow_inner_add_yblock_mmx_accum("2", "16", "0")
-snow_inner_add_yblock_mmx_accum("1", "512", "0")
-snow_inner_add_yblock_mmx_accum("0", "528", "0")
-snow_inner_add_yblock_mmx_mix("0", "0")
-
-snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "8", "8")
-snow_inner_add_yblock_mmx_accum("2", "24", "8")
-snow_inner_add_yblock_mmx_accum("1", "520", "8")
-snow_inner_add_yblock_mmx_accum("0", "536", "8")
-snow_inner_add_yblock_mmx_mix("16", "8")
-snow_inner_add_yblock_mmx_end("32")
-}
-
-static void ff_snow_inner_add_yblock_sse2(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){
-
-    if (b_w == 16)
-        inner_add_yblock_bw_16_obmc_32_sse2(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
-    else if (b_w == 8 && obmc_stride == 16) {
-        if (!(b_h & 1))
-            inner_add_yblock_bw_8_obmc_16_bh_even_sse2(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
-        else
-            inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
-    } else
-         ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
-}
-
-static void ff_snow_inner_add_yblock_mmx(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){
-    if (b_w == 16)
-        inner_add_yblock_bw_16_obmc_32_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
-    else if (b_w == 8 && obmc_stride == 16)
-        inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
-    else
-        ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
-}
-
-#endif /* HAVE_INLINE_ASM */
-
-void ff_dwt_init_x86(DWTContext *c)
-{
-#if HAVE_INLINE_ASM
-    int mm_flags = av_get_cpu_flags();
-
-    if (mm_flags & AV_CPU_FLAG_MMX) {
-        if(mm_flags & AV_CPU_FLAG_SSE2 & 0){
-            c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2;
-#if HAVE_7REGS
-            c->vertical_compose97i = ff_snow_vertical_compose97i_sse2;
-#endif
-            c->inner_add_yblock = ff_snow_inner_add_yblock_sse2;
-        }
-        else{
-            if (mm_flags & AV_CPU_FLAG_MMXEXT) {
-            c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx;
-#if HAVE_7REGS
-            c->vertical_compose97i = ff_snow_vertical_compose97i_mmx;
-#endif
-            }
-            c->inner_add_yblock = ff_snow_inner_add_yblock_mmx;
-        }
-    }
-#endif /* HAVE_INLINE_ASM */
-}
diff --git a/libavcodec/x86/vc1dsp_init.c b/libavcodec/x86/vc1dsp_init.c
index 230d06f..9f18131 100644
--- a/libavcodec/x86/vc1dsp_init.c
+++ b/libavcodec/x86/vc1dsp_init.c
@@ -27,6 +27,7 @@
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/vc1dsp.h"
+#include "dsputil_x86.h"
 #include "vc1dsp.h"
 #include "config.h"
 
@@ -60,6 +61,12 @@ static void vc1_h_loop_filter16_sse4(uint8_t *src, int stride, int pq)
     ff_vc1_h_loop_filter8_sse4(src,          stride, pq);
     ff_vc1_h_loop_filter8_sse4(src+8*stride, stride, pq);
 }
+
+static void avg_vc1_mspel_mc00_mmxext(uint8_t *dst, const uint8_t *src,
+                                      ptrdiff_t stride, int rnd)
+{
+    ff_avg_pixels8_mmxext(dst, src, stride, 8);
+}
 #endif /* HAVE_YASM */
 
 void ff_put_vc1_chroma_mc8_nornd_mmx  (uint8_t *dst, uint8_t *src,
@@ -76,12 +83,12 @@ void ff_avg_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, uint8_t *src,
 
 av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (INLINE_MMX(mm_flags))
+    if (INLINE_MMX(cpu_flags))
         ff_vc1dsp_init_mmx(dsp);
 
-    if (INLINE_MMXEXT(mm_flags))
+    if (INLINE_MMXEXT(cpu_flags))
         ff_vc1dsp_init_mmxext(dsp);
 
 #define ASSIGN_LF(EXT) \
@@ -93,29 +100,30 @@ av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp)
         dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_ ## EXT
 
 #if HAVE_YASM
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_mmx;
     }
-
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
-        ASSIGN_LF(mmxext);
-        dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_mmxext;
-    } else if (mm_flags & AV_CPU_FLAG_3DNOW) {
+    if (EXTERNAL_AMD3DNOW(cpu_flags)) {
         dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_3dnow;
     }
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
+        ASSIGN_LF(mmxext);
+        dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_mmxext;
 
-    if (mm_flags & AV_CPU_FLAG_SSE2) {
+        dsp->avg_vc1_mspel_pixels_tab[0]         = avg_vc1_mspel_mc00_mmxext;
+    }
+    if (EXTERNAL_SSE2(cpu_flags)) {
         dsp->vc1_v_loop_filter8  = ff_vc1_v_loop_filter8_sse2;
         dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_sse2;
         dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_sse2;
         dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse2;
     }
-    if (mm_flags & AV_CPU_FLAG_SSSE3) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         ASSIGN_LF(ssse3);
         dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_ssse3;
         dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_ssse3;
     }
-    if (mm_flags & AV_CPU_FLAG_SSE4) {
+    if (EXTERNAL_SSE4(cpu_flags)) {
         dsp->vc1_h_loop_filter8  = ff_vc1_h_loop_filter8_sse4;
         dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse4;
     }
diff --git a/libavcodec/x86/vc1dsp_mmx.c b/libavcodec/x86/vc1dsp_mmx.c
index b02582f..15fd2c8 100644
--- a/libavcodec/x86/vc1dsp_mmx.c
+++ b/libavcodec/x86/vc1dsp_mmx.c
@@ -29,9 +29,9 @@
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
-#include "dsputil_mmx.h"
 #include "libavcodec/vc1dsp.h"
+#include "constants.h"
+#include "dsputil_x86.h"
 #include "vc1dsp.h"
 
 #if HAVE_INLINE_ASM
@@ -464,12 +464,17 @@ VC1_MSPEL_MC(avg_)
 
 /** Macro to ease bicubic filter interpolation functions declarations */
 #define DECLARE_FUNCTION(a, b)                                          \
-static void put_vc1_mspel_mc ## a ## b ## _mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd) { \
+static void put_vc1_mspel_mc ## a ## b ## _mmx(uint8_t *dst,            \
+                                               const uint8_t *src,      \
+                                               ptrdiff_t stride,        \
+                                               int rnd)                 \
+{                                                                       \
      put_vc1_mspel_mc(dst, src, stride, a, b, rnd);                     \
 }\
 static void avg_vc1_mspel_mc ## a ## b ## _mmxext(uint8_t *dst,         \
                                                   const uint8_t *src,   \
-                                                  int stride, int rnd)  \
+                                                  ptrdiff_t stride,     \
+                                                  int rnd)              \
 {                                                                       \
      avg_vc1_mspel_mc(dst, src, stride, a, b, rnd);                     \
 }
@@ -494,7 +499,7 @@ DECLARE_FUNCTION(3, 2)
 DECLARE_FUNCTION(3, 3)
 
 static void vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, int linesize,
-                                        DCTELEM *block)
+                                        int16_t *block)
 {
     int dc = block[0];
     dc = (17 * dc +  4) >> 3;
@@ -533,7 +538,7 @@ static void vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, int linesize,
 }
 
 static void vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, int linesize,
-                                        DCTELEM *block)
+                                        int16_t *block)
 {
     int dc = block[0];
     dc = (17 * dc +  4) >> 3;
@@ -595,7 +600,7 @@ static void vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, int linesize,
 }
 
 static void vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, int linesize,
-                                        DCTELEM *block)
+                                        int16_t *block)
 {
     int dc = block[0];
     dc = ( 3 * dc +  1) >> 1;
@@ -634,7 +639,7 @@ static void vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, int linesize,
 }
 
 static void vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, int linesize,
-                                        DCTELEM *block)
+                                        int16_t *block)
 {
     int dc = block[0];
     dc = (3 * dc +  1) >> 1;
@@ -695,54 +700,59 @@ static void vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, int linesize,
     );
 }
 
+static void put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src,
+                                   ptrdiff_t stride, int rnd)
+{
+    ff_put_pixels8_mmx(dst, src, stride, 8);
+}
+
 av_cold void ff_vc1dsp_init_mmx(VC1DSPContext *dsp)
 {
-        dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_mmx;
-        dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_mmx;
-        dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_mmx;
-        dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_mmx;
-
-        dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_mmx;
-        dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_mmx;
-        dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_mmx;
-        dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_mmx;
-
-        dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_mmx;
-        dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_mmx;
-        dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_mmx;
-        dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_mmx;
-
-        dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_mmx;
-        dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_mmx;
-        dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_mmx;
-        dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_mmx;
+    dsp->put_vc1_mspel_pixels_tab[ 0] = put_vc1_mspel_mc00_mmx;
+    dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_mmx;
+    dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_mmx;
+    dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_mmx;
+
+    dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_mmx;
+    dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_mmx;
+    dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_mmx;
+    dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_mmx;
+
+    dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_mmx;
+    dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_mmx;
+    dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_mmx;
+    dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_mmx;
+
+    dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_mmx;
+    dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_mmx;
+    dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_mmx;
+    dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_mmx;
 }
 
 av_cold void ff_vc1dsp_init_mmxext(VC1DSPContext *dsp)
 {
-        dsp->avg_vc1_mspel_pixels_tab[ 0] = ff_avg_vc1_mspel_mc00_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[ 4] = avg_vc1_mspel_mc01_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[ 8] = avg_vc1_mspel_mc02_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[12] = avg_vc1_mspel_mc03_mmxext;
-
-        dsp->avg_vc1_mspel_pixels_tab[ 1] = avg_vc1_mspel_mc10_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[ 5] = avg_vc1_mspel_mc11_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[ 9] = avg_vc1_mspel_mc12_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[13] = avg_vc1_mspel_mc13_mmxext;
-
-        dsp->avg_vc1_mspel_pixels_tab[ 2] = avg_vc1_mspel_mc20_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[ 6] = avg_vc1_mspel_mc21_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[10] = avg_vc1_mspel_mc22_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[14] = avg_vc1_mspel_mc23_mmxext;
-
-        dsp->avg_vc1_mspel_pixels_tab[ 3] = avg_vc1_mspel_mc30_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[ 7] = avg_vc1_mspel_mc31_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[11] = avg_vc1_mspel_mc32_mmxext;
-        dsp->avg_vc1_mspel_pixels_tab[15] = avg_vc1_mspel_mc33_mmxext;
-
-        dsp->vc1_inv_trans_8x8_dc = vc1_inv_trans_8x8_dc_mmxext;
-        dsp->vc1_inv_trans_4x8_dc = vc1_inv_trans_4x8_dc_mmxext;
-        dsp->vc1_inv_trans_8x4_dc = vc1_inv_trans_8x4_dc_mmxext;
-        dsp->vc1_inv_trans_4x4_dc = vc1_inv_trans_4x4_dc_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[ 4] = avg_vc1_mspel_mc01_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[ 8] = avg_vc1_mspel_mc02_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[12] = avg_vc1_mspel_mc03_mmxext;
+
+    dsp->avg_vc1_mspel_pixels_tab[ 1] = avg_vc1_mspel_mc10_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[ 5] = avg_vc1_mspel_mc11_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[ 9] = avg_vc1_mspel_mc12_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[13] = avg_vc1_mspel_mc13_mmxext;
+
+    dsp->avg_vc1_mspel_pixels_tab[ 2] = avg_vc1_mspel_mc20_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[ 6] = avg_vc1_mspel_mc21_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[10] = avg_vc1_mspel_mc22_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[14] = avg_vc1_mspel_mc23_mmxext;
+
+    dsp->avg_vc1_mspel_pixels_tab[ 3] = avg_vc1_mspel_mc30_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[ 7] = avg_vc1_mspel_mc31_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[11] = avg_vc1_mspel_mc32_mmxext;
+    dsp->avg_vc1_mspel_pixels_tab[15] = avg_vc1_mspel_mc33_mmxext;
+
+    dsp->vc1_inv_trans_8x8_dc = vc1_inv_trans_8x8_dc_mmxext;
+    dsp->vc1_inv_trans_4x8_dc = vc1_inv_trans_4x8_dc_mmxext;
+    dsp->vc1_inv_trans_8x4_dc = vc1_inv_trans_8x4_dc_mmxext;
+    dsp->vc1_inv_trans_4x4_dc = vc1_inv_trans_4x4_dc_mmxext;
 }
 #endif /* HAVE_INLINE_ASM */
diff --git a/libavcodec/x86/videodsp.asm b/libavcodec/x86/videodsp.asm
index 19b910b..59f1937 100644
--- a/libavcodec/x86/videodsp.asm
+++ b/libavcodec/x86/videodsp.asm
@@ -23,576 +23,394 @@
 
 SECTION .text
 
-; extern void ff_emu_edge_core(uint8_t *buf, const uint8_t *src, x86_reg linesize,
-;                              x86_reg start_y, x86_reg end_y, x86_reg block_h,
-;                              x86_reg start_x, x86_reg end_x, x86_reg block_w);
-;
-; The actual function itself is below. It basically wraps a very simple
-; w = end_x - start_x
-; if (w) {
-;   if (w > 22) {
-;     jump to the slow loop functions
-;   } else {
-;     jump to the fast loop functions
-;   }
-; }
-;
-; ... and then the same for left/right extend also. See below for loop
-; function implementations. Fast are fixed-width, slow is variable-width
-
-%macro EMU_EDGE_FUNC 0
-%if ARCH_X86_64
-%define w_reg r7
-cglobal emu_edge_core, 6, 9, 1
-    mov         r8, r5          ; save block_h
-%else
-%define w_reg r6
-cglobal emu_edge_core, 2, 7, 0
-    mov         r4, r4m         ; end_y
-    mov         r5, r5m         ; block_h
-%endif
-
-    ; start with vertical extend (top/bottom) and body pixel copy
-    mov      w_reg, r7m
-    sub      w_reg, r6m         ; w = start_x - end_x
-    sub         r5, r4
-%if ARCH_X86_64
-    sub         r4, r3
-%else
-    sub         r4, dword r3m
-%endif
-    cmp      w_reg, 22
-    jg .slow_v_extend_loop
-%if ARCH_X86_32
-    mov         r2, r2m         ; linesize
-%endif
-    sal      w_reg, 7           ; w * 128
-%ifdef PIC
-    lea        rax, [.emuedge_v_extend_1 - (.emuedge_v_extend_2 - .emuedge_v_extend_1)]
-    add      w_reg, rax
-%else
-    lea      w_reg, [.emuedge_v_extend_1 - (.emuedge_v_extend_2 - .emuedge_v_extend_1)+w_reg]
-%endif
-    call     w_reg              ; fast top extend, body copy and bottom extend
-.v_extend_end:
+; slow vertical extension loop function. Works with variable-width, and
+; does per-line reading/writing of source data
+
+%macro V_COPY_ROW 2 ; type (top/body/bottom), h
+.%1_y_loop:                                     ; do {
+    mov              wq, r7mp                   ;   initialize w (r7mp = wmp)
+.%1_x_loop:                                     ;   do {
+    movu             m0, [srcq+wq]              ;     m0 = read($mmsize)
+    movu      [dstq+wq], m0                     ;     write(m0, $mmsize)
+    add              wq, mmsize                 ;     w -= $mmsize
+    cmp              wq, -mmsize                ;   } while (w > $mmsize);
+    jl .%1_x_loop
+    movu             m0, [srcq-mmsize]          ;     m0 = read($mmsize)
+    movu  [dstq-mmsize], m0                     ;     write(m0, $mmsize)
+%ifidn %1, body                                 ;   if ($type == body) {
+    add            srcq, src_strideq            ;     src += src_stride
+%endif                                          ;   }
+    add            dstq, dst_strideq            ;   dst += dst_stride
+    dec              %2                         ; } while (--$h);
+    jnz .%1_y_loop
+%endmacro
 
-    ; horizontal extend (left/right)
-    mov      w_reg, r6m         ; start_x
-    sub         r0, w_reg
+%macro vvar_fn 0
+; .----. <- zero
+; |    |    <- top is copied from first line in body of source
+; |----| <- start_y
+; |    |    <- body is copied verbatim (line-by-line) from source
+; |----| <- end_y
+; |    |    <- bottom is copied from last line in body of source
+; '----' <- bh
 %if ARCH_X86_64
-    mov         r3, r0          ; backup of buf+block_h*linesize
-    mov         r5, r8
-%else
-    mov        r0m, r0          ; backup of buf+block_h*linesize
-    mov         r5, r5m
+cglobal emu_edge_vvar, 7, 8, 1, dst, src, dst_stride, src_stride, \
+                                start_y, end_y, bh, w
+%else ; x86-32
+cglobal emu_edge_vvar, 1, 6, 1, dst, src, start_y, end_y, bh, w
+%define src_strideq r3mp
+%define dst_strideq r2mp
+    mov            srcq, r1mp
+    mov        start_yq, r4mp
+    mov          end_yq, r5mp
+    mov             bhq, r6mp
 %endif
-    test     w_reg, w_reg
-    jz .right_extend
-    cmp      w_reg, 22
-    jg .slow_left_extend_loop
-    mov         r1, w_reg
-    dec      w_reg
-    ; FIXME we can do a if size == 1 here if that makes any speed difference, test me
-    sar      w_reg, 1
-    sal      w_reg, 6
-    ; r0=buf+block_h*linesize,r7(64)/r6(32)=start_x offset for funcs
-    ; r6(rax)/r3(ebx)=val,r2=linesize,r1=start_x,r5=block_h
-%ifdef PIC
-    lea        rax, [.emuedge_extend_left_2]
-    add      w_reg, rax
-%else
-    lea      w_reg, [.emuedge_extend_left_2+w_reg]
-%endif
-    call     w_reg
+    sub             bhq, end_yq                 ; bh    -= end_q
+    sub          end_yq, start_yq               ; end_q -= start_q
+    add            srcq, r7mp                   ; (r7mp = wmp)
+    add            dstq, r7mp                   ; (r7mp = wmp)
+    neg            r7mp                         ; (r7mp = wmp)
+    test       start_yq, start_yq               ; if (start_q) {
+    jz .body
+    V_COPY_ROW      top, start_yq               ;   v_copy_row(top, start_yq)
+.body:                                          ; }
+    V_COPY_ROW     body, end_yq                 ; v_copy_row(body, end_yq)
+    test            bhq, bhq                    ; if (bh) {
+    jz .end
+    sub            srcq, src_strideq            ;   src -= src_stride
+    V_COPY_ROW   bottom, bhq                    ;   v_copy_row(bottom, bh)
+.end:                                           ; }
+    RET
+%endmacro
 
-    ; now r3(64)/r0(32)=buf,r2=linesize,r8/r5=block_h,r6/r3=val, r7/r6=end_x, r1=block_w
-.right_extend:
 %if ARCH_X86_32
-    mov         r0, r0m
-    mov         r5, r5m
+INIT_MMX mmx
+vvar_fn
 %endif
-    mov      w_reg, r7m         ; end_x
-    mov         r1, r8m         ; block_w
-    mov         r4, r1
-    sub         r1, w_reg
-    jz .h_extend_end            ; if (end_x == block_w) goto h_extend_end
-    cmp         r1, 22
-    jg .slow_right_extend_loop
-    dec         r1
-    ; FIXME we can do a if size == 1 here if that makes any speed difference, test me
-    sar         r1, 1
-    sal         r1, 6
-%ifdef PIC
-    lea        rax, [.emuedge_extend_right_2]
-    add         r1, rax
-%else
-    lea         r1, [.emuedge_extend_right_2+r1]
-%endif
-    call        r1
-.h_extend_end:
+
+INIT_XMM sse
+vvar_fn
+
+%macro hvar_fn 0
+cglobal emu_edge_hvar, 5, 6, 1, dst, dst_stride, start_x, n_words, h, w
+    lea            dstq, [dstq+n_wordsq*2]
+    neg        n_wordsq
+    lea        start_xq, [start_xq+n_wordsq*2]
+.y_loop:                                        ; do {
+    ; FIXME also write a ssse3 version using pshufb
+    movzx            wd, byte [dstq+start_xq]   ;   w = read(1)
+    imul             wd, 0x01010101             ;   w *= 0x01010101
+    movd             m0, wd
+    mov              wq, n_wordsq               ;   initialize w
+%if cpuflag(sse)
+    shufps           m0, m0, q0000              ;   splat
+%else ; mmx
+    punpckldq        m0, m0                     ;   splat
+%endif ; mmx/sse
+.x_loop:                                        ;   do {
+    movu    [dstq+wq*2], m0                     ;     write($reg, $mmsize)
+    add              wq, mmsize/2               ;     w -= $mmsize/2
+    cmp              wq, -mmsize/2              ;   } while (w > $mmsize/2)
+    jl .x_loop
+    movu  [dstq-mmsize], m0                     ;   write($reg, $mmsize)
+    add            dstq, dst_strideq            ;   dst += dst_stride
+    dec              hq                         ; } while (h--)
+    jnz .y_loop
     RET
+%endmacro
 
-%if ARCH_X86_64
-%define vall  al
-%define valh  ah
-%define valw  ax
-%define valw2 r7w
-%define valw3 r3w
-%if WIN64
-%define valw4 r7w
-%else ; unix64
-%define valw4 r3w
-%endif
-%define vald eax
-%else
-%define vall  bl
-%define valh  bh
-%define valw  bx
-%define valw2 r6w
-%define valw3 valw2
-%define valw4 valw3
-%define vald ebx
-%define stack_offset 0x14
+%if ARCH_X86_32
+INIT_MMX mmx
+hvar_fn
 %endif
 
-%endmacro
+INIT_XMM sse
+hvar_fn
 
 ; macro to read/write a horizontal number of pixels (%2) to/from registers
-; on x86-64, - fills xmm0-15 for consecutive sets of 16 pixels
-;            - if (%2 & 15 == 8) fills the last 8 bytes into rax
-;            - else if (%2 & 8)  fills 8 bytes into mm0
-;            - if (%2 & 7 == 4)  fills the last 4 bytes into rax
-;            - else if (%2 & 4)  fills 4 bytes into mm0-1
-;            - if (%2 & 3 == 3)  fills 2 bytes into r7/r3, and 1 into eax
-;              (note that we're using r3 for body/bottom because it's a shorter
-;               opcode, and then the loop fits in 128 bytes)
-;            - else              fills remaining bytes into rax
-; on x86-32, - fills mm0-7 for consecutive sets of 8 pixels
-;            - if (%2 & 7 == 4)  fills 4 bytes into ebx
-;            - else if (%2 & 4)  fills 4 bytes into mm0-7
-;            - if (%2 & 3 == 3)  fills 2 bytes into r6, and 1 into ebx
-;            - else              fills remaining bytes into ebx
+; on sse, - fills xmm0-15 for consecutive sets of 16 pixels
+;         - if (%2 & 8)  fills 8 bytes into xmm$next
+;         - if (%2 & 4)  fills 4 bytes into xmm$next
+;         - if (%2 & 3)  fills 1, 2 or 4 bytes in eax
+; on mmx, - fills mm0-7 for consecutive sets of 8 pixels
+;         - if (%2 & 4)  fills 4 bytes into mm$next
+;         - if (%2 & 3)  fills 1, 2 or 4 bytes in eax
 ; writing data out is in the same way
 %macro READ_NUM_BYTES 2
-%assign %%src_off 0 ; offset in source buffer
-%assign %%smidx   0 ; mmx register idx
-%assign %%sxidx   0 ; xmm register idx
-
-%if cpuflag(sse)
-%rep %2/16
-    movups xmm %+ %%sxidx, [r1+%%src_off]
-%assign %%src_off %%src_off+16
-%assign %%sxidx   %%sxidx+1
-%endrep ; %2/16
+%assign %%off 0 ; offset in source buffer
+%assign %%idx 0 ; mmx/xmm register index
+
+%rep %2/mmsize
+    movu     m %+ %%idx, [srcq+%%off]
+%assign %%off %%off+mmsize
+%assign %%idx %%idx+1
+%endrep ; %2/mmsize
+
+%if mmsize == 16
+%if (%2-%%off) >= 8
+%if %2 > 16 && (%2-%%off) > 8
+    movu     m %+ %%idx, [srcq+%2-16]
+%assign %%off %2
+%else
+    movq     m %+ %%idx, [srcq+%%off]
+%assign %%off %%off+8
+%endif
+%assign %%idx %%idx+1
+%endif ; (%2-%%off) >= 8
 %endif
 
-%if ARCH_X86_64
-%if (%2-%%src_off) == 8
-    mov           rax, [r1+%%src_off]
-%assign %%src_off %%src_off+8
-%endif ; (%2-%%src_off) == 8
-%endif ; x86-64
-
-%rep (%2-%%src_off)/8
-    movq    mm %+ %%smidx, [r1+%%src_off]
-%assign %%src_off %%src_off+8
-%assign %%smidx   %%smidx+1
-%endrep ; (%2-%%dst_off)/8
-
-%if (%2-%%src_off) == 4
-    mov          vald, [r1+%%src_off]
-%elif (%2-%%src_off) & 4
-    movd    mm %+ %%smidx, [r1+%%src_off]
-%assign %%src_off %%src_off+4
-%endif ; (%2-%%src_off) ==/& 4
-
-%if (%2-%%src_off) == 1
-    mov          vall, [r1+%%src_off]
-%elif (%2-%%src_off) == 2
-    mov          valw, [r1+%%src_off]
-%elif (%2-%%src_off) == 3
-%ifidn %1, top
-    mov         valw2, [r1+%%src_off]
+%if (%2-%%off) >= 4
+%if %2 > 8 && (%2-%%off) > 4
+    movq     m %+ %%idx, [srcq+%2-8]
+%assign %%off %2
+%else
+    movd     m %+ %%idx, [srcq+%%off]
+%assign %%off %%off+4
+%endif
+%assign %%idx %%idx+1
+%endif ; (%2-%%off) >= 4
+
+%if (%2-%%off) >= 1
+%if %2 >= 4
+    movd     m %+ %%idx, [srcq+%2-4]
+%elif (%2-%%off) == 1
+    mov            valb, [srcq+%2-1]
+%elif (%2-%%off) == 2
+    mov            valw, [srcq+%2-2]
 %elifidn %1, body
-    mov         valw3, [r1+%%src_off]
-%elifidn %1, bottom
-    mov         valw4, [r1+%%src_off]
-%endif ; %1 ==/!= top
-    mov          vall, [r1+%%src_off+2]
-%endif ; (%2-%%src_off) == 1/2/3
+    mov            vald, [srcq+%2-3]
+%else
+    movd     m %+ %%idx, [srcq+%2-3]
+%endif
+%endif ; (%2-%%off) >= 1
 %endmacro ; READ_NUM_BYTES
 
 %macro WRITE_NUM_BYTES 2
-%assign %%dst_off 0 ; offset in destination buffer
-%assign %%dmidx   0 ; mmx register idx
-%assign %%dxidx   0 ; xmm register idx
-
-%if cpuflag(sse)
-%rep %2/16
-    movups [r0+%%dst_off], xmm %+ %%dxidx
-%assign %%dst_off %%dst_off+16
-%assign %%dxidx   %%dxidx+1
-%endrep ; %2/16
+%assign %%off 0 ; offset in destination buffer
+%assign %%idx 0 ; mmx/xmm register index
+
+%rep %2/mmsize
+    movu   [dstq+%%off], m %+ %%idx
+%assign %%off %%off+mmsize
+%assign %%idx %%idx+1
+%endrep ; %2/mmsize
+
+%if mmsize == 16
+%if (%2-%%off) >= 8
+%if %2 > 16 && (%2-%%off) > 8
+    movu   [dstq+%2-16], m %+ %%idx
+%assign %%off %2
+%else
+    movq   [dstq+%%off], m %+ %%idx
+%assign %%off %%off+8
+%endif
+%assign %%idx %%idx+1
+%endif ; (%2-%%off) >= 8
 %endif
 
-%if ARCH_X86_64
-%if (%2-%%dst_off) == 8
-    mov    [r0+%%dst_off], rax
-%assign %%dst_off %%dst_off+8
-%endif ; (%2-%%dst_off) == 8
-%endif ; x86-64
-
-%rep (%2-%%dst_off)/8
-    movq   [r0+%%dst_off], mm %+ %%dmidx
-%assign %%dst_off %%dst_off+8
-%assign %%dmidx   %%dmidx+1
-%endrep ; (%2-%%dst_off)/8
-
-%if (%2-%%dst_off) == 4
-    mov    [r0+%%dst_off], vald
-%elif (%2-%%dst_off) & 4
-    movd   [r0+%%dst_off], mm %+ %%dmidx
-%assign %%dst_off %%dst_off+4
-%endif ; (%2-%%dst_off) ==/& 4
-
-%if (%2-%%dst_off) == 1
-    mov    [r0+%%dst_off], vall
-%elif (%2-%%dst_off) == 2
-    mov    [r0+%%dst_off], valw
-%elif (%2-%%dst_off) == 3
-%ifidn %1, top
-    mov    [r0+%%dst_off], valw2
+%if (%2-%%off) >= 4
+%if %2 > 8 && (%2-%%off) > 4
+    movq    [dstq+%2-8], m %+ %%idx
+%assign %%off %2
+%else
+    movd   [dstq+%%off], m %+ %%idx
+%assign %%off %%off+4
+%endif
+%assign %%idx %%idx+1
+%endif ; (%2-%%off) >= 4
+
+%if (%2-%%off) >= 1
+%if %2 >= 4
+    movd    [dstq+%2-4], m %+ %%idx
+%elif (%2-%%off) == 1
+    mov     [dstq+%2-1], valb
+%elif (%2-%%off) == 2
+    mov     [dstq+%2-2], valw
 %elifidn %1, body
-    mov    [r0+%%dst_off], valw3
-%elifidn %1, bottom
-    mov    [r0+%%dst_off], valw4
-%endif ; %1 ==/!= top
-    mov  [r0+%%dst_off+2], vall
-%endif ; (%2-%%dst_off) == 1/2/3
+    mov     [dstq+%2-3], valw
+    shr            vald, 16
+    mov     [dstq+%2-1], valb
+%else
+    movd           vald, m %+ %%idx
+    mov     [dstq+%2-3], valw
+    shr            vald, 16
+    mov     [dstq+%2-1], valb
+%endif
+%endif ; (%2-%%off) >= 1
 %endmacro ; WRITE_NUM_BYTES
 
 ; vertical top/bottom extend and body copy fast loops
 ; these are function pointers to set-width line copy functions, i.e.
 ; they read a fixed number of pixels into set registers, and write
 ; those out into the destination buffer
-; r0=buf,r1=src,r2=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h
-; r6(eax/64)/r3(ebx/32)=val_reg
-%macro VERTICAL_EXTEND 0
-%assign %%n 1
-%rep 22
-ALIGN 128
-.emuedge_v_extend_ %+ %%n:
-    ; extend pixels above body
+%macro VERTICAL_EXTEND 2
+%assign %%n %1
+%rep 1+%2-%1
+%if %%n <= 3
 %if ARCH_X86_64
-    test           r3 , r3                   ; if (!start_y)
-    jz .emuedge_copy_body_ %+ %%n %+ _loop   ;   goto body
-%else ; ARCH_X86_32
-    cmp      dword r3m, 0
-    je .emuedge_copy_body_ %+ %%n %+ _loop
-%endif ; ARCH_X86_64/32
-    READ_NUM_BYTES  top,    %%n              ; read bytes
-.emuedge_extend_top_ %+ %%n %+ _loop:        ; do {
-    WRITE_NUM_BYTES top,    %%n              ;   write bytes
-    add            r0 , r2                   ;   dst += linesize
+cglobal emu_edge_vfix %+ %%n, 6, 8, 0, dst, src, dst_stride, src_stride, \
+                                       start_y, end_y, val, bh
+    mov             bhq, r6mp                   ; r6mp = bhmp
+%else ; x86-32
+cglobal emu_edge_vfix %+ %%n, 0, 6, 0, val, dst, src, start_y, end_y, bh
+    mov            dstq, r0mp
+    mov            srcq, r1mp
+    mov        start_yq, r4mp
+    mov          end_yq, r5mp
+    mov             bhq, r6mp
+%define dst_strideq r2mp
+%define src_strideq r3mp
+%endif ; x86-64/32
+%else
 %if ARCH_X86_64
-    dec            r3d
-%else ; ARCH_X86_32
-    dec      dword r3m
-%endif ; ARCH_X86_64/32
-    jnz .emuedge_extend_top_ %+ %%n %+ _loop ; } while (--start_y)
+cglobal emu_edge_vfix %+ %%n, 7, 7, 1, dst, src, dst_stride, src_stride, \
+                                       start_y, end_y, bh
+%else ; x86-32
+cglobal emu_edge_vfix %+ %%n, 1, 5, 1, dst, src, start_y, end_y, bh
+    mov            srcq, r1mp
+    mov        start_yq, r4mp
+    mov          end_yq, r5mp
+    mov             bhq, r6mp
+%define dst_strideq r2mp
+%define src_strideq r3mp
+%endif ; x86-64/32
+%endif
+    ; FIXME move this to c wrapper?
+    sub             bhq, end_yq                 ; bh    -= end_y
+    sub          end_yq, start_yq               ; end_y -= start_y
+
+    ; extend pixels above body
+    test       start_yq, start_yq               ; if (start_y) {
+    jz .body_loop
+    READ_NUM_BYTES  top, %%n                    ;   $variable_regs = read($n)
+.top_loop:                                      ;   do {
+    WRITE_NUM_BYTES top, %%n                    ;     write($variable_regs, $n)
+    add            dstq, dst_strideq            ;     dst += linesize
+    dec        start_yq                         ;   } while (--start_y)
+    jnz .top_loop                               ; }
 
     ; copy body pixels
-.emuedge_copy_body_ %+ %%n %+ _loop:         ; do {
-    READ_NUM_BYTES  body,   %%n              ;   read bytes
-    WRITE_NUM_BYTES body,   %%n              ;   write bytes
-    add            r0 , r2                   ;   dst += linesize
-    add            r1 , r2                   ;   src += linesize
-    dec            r4d
-    jnz .emuedge_copy_body_ %+ %%n %+ _loop  ; } while (--end_y)
+.body_loop:                                     ; do {
+    READ_NUM_BYTES  body, %%n                   ;   $variable_regs = read($n)
+    WRITE_NUM_BYTES body, %%n                   ;   write($variable_regs, $n)
+    add            dstq, dst_strideq            ;   dst += dst_stride
+    add            srcq, src_strideq            ;   src += src_stride
+    dec          end_yq                         ; } while (--end_y)
+    jnz .body_loop
 
     ; copy bottom pixels
-    test           r5 , r5                   ; if (!block_h)
-    jz .emuedge_v_extend_end_ %+ %%n         ;   goto end
-    sub            r1 , r2                   ; src -= linesize
-    READ_NUM_BYTES  bottom, %%n              ; read bytes
-.emuedge_extend_bottom_ %+ %%n %+ _loop:     ; do {
-    WRITE_NUM_BYTES bottom, %%n              ;   write bytes
-    add            r0 , r2                   ;   dst += linesize
-    dec            r5d
-    jnz .emuedge_extend_bottom_ %+ %%n %+ _loop ; } while (--block_h)
-
-.emuedge_v_extend_end_ %+ %%n:
-%if ARCH_X86_64
-    ret
-%else ; ARCH_X86_32
-    rep ret
-%endif ; ARCH_X86_64/32
+    test            bhq, bhq                    ; if (block_h) {
+    jz .end
+    sub            srcq, src_strideq            ;   src -= linesize
+    READ_NUM_BYTES  bottom, %%n                 ;   $variable_regs = read($n)
+.bottom_loop:                                   ;   do {
+    WRITE_NUM_BYTES bottom, %%n                 ;     write($variable_regs, $n)
+    add            dstq, dst_strideq            ;     dst += linesize
+    dec             bhq                         ;   } while (--bh)
+    jnz .bottom_loop                            ; }
+
+.end:
+    RET
 %assign %%n %%n+1
-%endrep
-%endmacro VERTICAL_EXTEND
+%endrep ; 1+%2-%1
+%endmacro ; VERTICAL_EXTEND
+
+INIT_MMX mmx
+VERTICAL_EXTEND 1, 15
+%if ARCH_X86_32
+VERTICAL_EXTEND 16, 22
+%endif
+
+INIT_XMM sse
+VERTICAL_EXTEND 16, 22
 
 ; left/right (horizontal) fast extend functions
 ; these are essentially identical to the vertical extend ones above,
 ; just left/right separated because number of pixels to extend is
 ; obviously not the same on both sides.
-; for reading, pixels are placed in eax (x86-64) or ebx (x86-64) in the
-; lowest two bytes of the register (so val*0x0101), and are splatted
-; into each byte of mm0 as well if n_pixels >= 8
 
 %macro READ_V_PIXEL 2
-    mov        vall, %2
-    mov        valh, vall
-%if %1 >= 8
-    movd        mm0, vald
-%if cpuflag(mmxext)
-    pshufw      mm0, mm0, 0
-%else ; mmx
-    punpcklwd   mm0, mm0
-    punpckldq   mm0, mm0
-%endif ; sse
-%endif ; %1 >= 8
-%endmacro
-
-%macro WRITE_V_PIXEL 2
-%assign %%dst_off 0
-%rep %1/8
-    movq [%2+%%dst_off], mm0
-%assign %%dst_off %%dst_off+8
-%endrep
-%if %1 & 4
+%if %1 == 2
+    movzx          valw, byte %2
+    imul           valw, 0x0101
+%else
+    movzx          vald, byte %2
+    imul           vald, 0x01010101
 %if %1 >= 8
-    movd [%2+%%dst_off], mm0
-%else ; %1 < 8
-    mov  [%2+%%dst_off]  , valw
-    mov  [%2+%%dst_off+2], valw
-%endif ; %1 >=/< 8
-%assign %%dst_off %%dst_off+4
-%endif ; %1 & 4
-%if %1&2
-    mov  [%2+%%dst_off], valw
-%endif ; %1 & 2
-%endmacro
-
-; r0=buf+block_h*linesize, r1=start_x, r2=linesize, r5=block_h, r6/r3=val
-%macro LEFT_EXTEND 0
-%assign %%n 2
-%rep 11
-ALIGN 64
-.emuedge_extend_left_ %+ %%n:          ; do {
-    sub         r0, r2                 ;   dst -= linesize
-    READ_V_PIXEL  %%n, [r0+r1]         ;   read pixels
-    WRITE_V_PIXEL %%n, r0              ;   write pixels
-    dec         r5
-    jnz .emuedge_extend_left_ %+ %%n   ; } while (--block_h)
-%if ARCH_X86_64
-    ret
-%else ; ARCH_X86_32
-    rep ret
-%endif ; ARCH_X86_64/32
-%assign %%n %%n+2
-%endrep
-%endmacro ; LEFT_EXTEND
-
-; r3/r0=buf+block_h*linesize, r2=linesize, r8/r5=block_h, r0/r6=end_x, r6/r3=val
-%macro RIGHT_EXTEND 0
-%assign %%n 2
-%rep 11
-ALIGN 64
-.emuedge_extend_right_ %+ %%n:          ; do {
-%if ARCH_X86_64
-    sub        r3, r2                   ;   dst -= linesize
-    READ_V_PIXEL  %%n, [r3+w_reg-1]     ;   read pixels
-    WRITE_V_PIXEL %%n, r3+r4-%%n        ;   write pixels
-    dec       r8
-%else ; ARCH_X86_32
-    sub        r0, r2                   ;   dst -= linesize
-    READ_V_PIXEL  %%n, [r0+w_reg-1]     ;   read pixels
-    WRITE_V_PIXEL %%n, r0+r4-%%n        ;   write pixels
-    dec     r5
-%endif ; ARCH_X86_64/32
-    jnz .emuedge_extend_right_ %+ %%n   ; } while (--block_h)
-%if ARCH_X86_64
-    ret
-%else ; ARCH_X86_32
-    rep ret
-%endif ; ARCH_X86_64/32
-%assign %%n %%n+2
-%endrep
-
-%if ARCH_X86_32
-%define stack_offset 0x10
-%endif
-%endmacro ; RIGHT_EXTEND
-
-; below follow the "slow" copy/extend functions, these act on a non-fixed
-; width specified in a register, and run a loop to copy the full amount
-; of bytes. They are optimized for copying of large amounts of pixels per
-; line, so they unconditionally splat data into mm registers to copy 8
-; bytes per loop iteration. It could be considered to use xmm for x86-64
-; also, but I haven't optimized this as much (i.e. FIXME)
-%macro V_COPY_NPX 4-5
-%if %0 == 4
-    test     w_reg, %4
-    jz .%1_skip_%4_px
-%else ; %0 == 5
-.%1_%4_px_loop:
+    movd             m0, vald
+%if mmsize == 16
+    shufps           m0, m0, q0000
+%else
+    punpckldq        m0, m0
 %endif
-    %3          %2, [r1+cnt_reg]
-    %3 [r0+cnt_reg], %2
-    add    cnt_reg, %4
-%if %0 == 5
-    sub      w_reg, %4
-    test     w_reg, %5
-    jnz .%1_%4_px_loop
+%endif ; %1 >= 8
 %endif
-.%1_skip_%4_px:
-%endmacro
+%endmacro ; READ_V_PIXEL
 
-%macro V_COPY_ROW 2
-%ifidn %1, bottom
-    sub         r1, linesize
+%macro WRITE_V_PIXEL 2
+%assign %%off 0
+%rep %1/mmsize
+    movu     [%2+%%off], m0
+%assign %%off %%off+mmsize
+%endrep ; %1/mmsize
+
+%if mmsize == 16
+%if %1-%%off >= 8
+%if %1 > 16 && %1-%%off > 8
+    movu     [%2+%1-16], m0
+%assign %%off %1
+%else
+    movq     [%2+%%off], m0
+%assign %%off %%off+8
 %endif
-.%1_copy_loop:
-    xor    cnt_reg, cnt_reg
-%if notcpuflag(sse)
-%define linesize r2m
-    V_COPY_NPX %1,  mm0, movq,    8, 0xFFFFFFF8
-%else ; sse
-    V_COPY_NPX %1, xmm0, movups, 16, 0xFFFFFFF0
-%if ARCH_X86_64
-%define linesize r2
-    V_COPY_NPX %1, rax , mov,     8
-%else ; ARCH_X86_32
-%define linesize r2m
-    V_COPY_NPX %1,  mm0, movq,    8
-%endif ; ARCH_X86_64/32
-%endif ; sse
-    V_COPY_NPX %1, vald, mov,     4
-    V_COPY_NPX %1, valw, mov,     2
-    V_COPY_NPX %1, vall, mov,     1
-    mov      w_reg, cnt_reg
-%ifidn %1, body
-    add         r1, linesize
+%endif ; %1-%%off >= 8
 %endif
-    add         r0, linesize
-    dec         %2
-    jnz .%1_copy_loop
-%endmacro
 
-%macro SLOW_V_EXTEND 0
-.slow_v_extend_loop:
-; r0=buf,r1=src,r2(64)/r2m(32)=linesize,r3(64)/r3m(32)=start_x,r4=end_y,r5=block_h
-; r8(64)/r3(later-64)/r2(32)=cnt_reg,r6(64)/r3(32)=val_reg,r7(64)/r6(32)=w=end_x-start_x
-%if ARCH_X86_64
-    push        r8              ; save old value of block_h
-    test        r3, r3
-%define cnt_reg r8
-    jz .do_body_copy            ; if (!start_y) goto do_body_copy
-    V_COPY_ROW top, r3
+%if %1-%%off >= 4
+%if %1 > 8 %% %1-%%off > 4
+    movq      [%2+%1-8], m0
+%assign %%off %1
+%elif %1 >= 8 && %1-%%off >= 4
+    movd     [%2+%%off], m0
+%assign %%off %%off+4
 %else
-    cmp  dword r3m, 0
-%define cnt_reg r2
-    je .do_body_copy            ; if (!start_y) goto do_body_copy
-    V_COPY_ROW top, dword r3m
+    mov      [%2+%%off], vald
+%assign %%off %%off+4
 %endif
+%endif ; %1-%%off >= 4
 
-.do_body_copy:
-    V_COPY_ROW body, r4
-
-%if ARCH_X86_64
-    pop         r8              ; restore old value of block_h
-%define cnt_reg r3
-%endif
-    test        r5, r5
-%if ARCH_X86_64
-    jz .v_extend_end
+%if %1-%%off >= 2
+%if %1 >= 8
+    movd      [%2+%1-4], m0
 %else
-    jz .skip_bottom_extend
+    mov      [%2+%%off], valw
 %endif
-    V_COPY_ROW bottom, r5
-%if ARCH_X86_32
-.skip_bottom_extend:
-    mov         r2, r2m
-%endif
-    jmp .v_extend_end
-%endmacro
+%endif ; (%1-%%off)/2
+%endmacro ; WRITE_V_PIXEL
+
+%macro H_EXTEND 2
+%assign %%n %1
+%rep 1+(%2-%1)/2
+cglobal emu_edge_hfix %+ %%n, 4, 5, 1, dst, dst_stride, start_x, bh, val
+.loop_y:                                        ; do {
+    READ_V_PIXEL    %%n, [dstq+start_xq]        ;   $variable_regs = read($n)
+    WRITE_V_PIXEL   %%n, dstq                   ;   write($variable_regs, $n)
+    add            dstq, dst_strideq            ;   dst += dst_stride
+    dec             bhq                         ; } while (--bh)
+    jnz .loop_y
+    RET
+%assign %%n %%n+2
+%endrep ; 1+(%2-%1)/2
+%endmacro ; H_EXTEND
 
-%macro SLOW_LEFT_EXTEND 0
-.slow_left_extend_loop:
-; r0=buf+block_h*linesize,r2=linesize,r6(64)/r3(32)=val,r5=block_h,r4=cntr,r7/r6=start_x
-    mov         r4, 8
-    sub         r0, linesize
-    READ_V_PIXEL 8, [r0+w_reg]
-.left_extend_8px_loop:
-    movq [r0+r4-8], mm0
-    add         r4, 8
-    cmp         r4, w_reg
-    jle .left_extend_8px_loop
-    sub         r4, 8
-    cmp         r4, w_reg
-    jge .left_extend_loop_end
-.left_extend_2px_loop:
-    mov    [r0+r4], valw
-    add         r4, 2
-    cmp         r4, w_reg
-    jl .left_extend_2px_loop
-.left_extend_loop_end:
-    dec         r5
-    jnz .slow_left_extend_loop
+INIT_MMX mmx
+H_EXTEND 2, 14
 %if ARCH_X86_32
-    mov         r2, r2m
-%endif
-    jmp .right_extend
-%endmacro
-
-%macro SLOW_RIGHT_EXTEND 0
-.slow_right_extend_loop:
-; r3(64)/r0(32)=buf+block_h*linesize,r2=linesize,r4=block_w,r8(64)/r5(32)=block_h,
-; r7(64)/r6(32)=end_x,r6/r3=val,r1=cntr
-%if ARCH_X86_64
-%define buf_reg r3
-%define bh_reg r8
-%else
-%define buf_reg r0
-%define bh_reg r5
+H_EXTEND 16, 22
 %endif
-    lea         r1, [r4-8]
-    sub    buf_reg, linesize
-    READ_V_PIXEL 8, [buf_reg+w_reg-1]
-.right_extend_8px_loop:
-    movq [buf_reg+r1], mm0
-    sub         r1, 8
-    cmp         r1, w_reg
-    jge .right_extend_8px_loop
-    add         r1, 8
-    cmp         r1, w_reg
-    je .right_extend_loop_end
-.right_extend_2px_loop:
-    sub         r1, 2
-    mov [buf_reg+r1], valw
-    cmp         r1, w_reg
-    jg .right_extend_2px_loop
-.right_extend_loop_end:
-    dec         bh_reg
-    jnz .slow_right_extend_loop
-    jmp .h_extend_end
-%endmacro
-
-%macro emu_edge 1
-INIT_XMM %1
-EMU_EDGE_FUNC
-VERTICAL_EXTEND
-LEFT_EXTEND
-RIGHT_EXTEND
-SLOW_V_EXTEND
-SLOW_LEFT_EXTEND
-SLOW_RIGHT_EXTEND
-%endmacro
 
-emu_edge sse
-%if ARCH_X86_32
-emu_edge mmx
-%endif
+INIT_XMM sse
+H_EXTEND 16, 22
 
 %macro PREFETCH_FN 1
 cglobal prefetch, 3, 3, 0, buf, stride, h
diff --git a/libavcodec/x86/videodsp_init.c b/libavcodec/x86/videodsp_init.c
index 07a0324..79d9801 100644
--- a/libavcodec/x86/videodsp_init.c
+++ b/libavcodec/x86/videodsp_init.c
@@ -19,36 +19,136 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/cpu.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
 #include "libavcodec/videodsp.h"
 
 #if HAVE_YASM
-typedef void emu_edge_core_func(uint8_t *buf, const uint8_t *src,
-                                x86_reg linesize, x86_reg start_y,
-                                x86_reg end_y, x86_reg block_h,
-                                x86_reg start_x, x86_reg end_x,
-                                x86_reg block_w);
-extern emu_edge_core_func ff_emu_edge_core_mmx;
-extern emu_edge_core_func ff_emu_edge_core_sse;
-
-static av_always_inline void emulated_edge_mc(uint8_t *buf, const uint8_t *src,
-                                              ptrdiff_t linesize,
-                                              int block_w, int block_h,
-                                              int src_x, int src_y,
-                                              int w, int h,
-                                              emu_edge_core_func *core_fn)
+typedef void emu_edge_vfix_func(uint8_t *dst, const uint8_t *src,
+                                x86_reg dst_stride, x86_reg src_stride,
+                                x86_reg start_y, x86_reg end_y, x86_reg bh);
+typedef void emu_edge_vvar_func(uint8_t *dst, const uint8_t *src,
+                                x86_reg dst_stride, x86_reg src_stride,
+                                x86_reg start_y, x86_reg end_y, x86_reg bh,
+                                x86_reg w);
+
+extern emu_edge_vfix_func ff_emu_edge_vfix1_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix2_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix3_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix4_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix5_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix6_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix7_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix8_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix9_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix10_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix11_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix12_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix13_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix14_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix15_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix16_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix17_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix18_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix19_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix20_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix21_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix22_mmx;
+#if ARCH_X86_32
+static emu_edge_vfix_func *vfixtbl_mmx[22] = {
+    &ff_emu_edge_vfix1_mmx,  &ff_emu_edge_vfix2_mmx,  &ff_emu_edge_vfix3_mmx,
+    &ff_emu_edge_vfix4_mmx,  &ff_emu_edge_vfix5_mmx,  &ff_emu_edge_vfix6_mmx,
+    &ff_emu_edge_vfix7_mmx,  &ff_emu_edge_vfix8_mmx,  &ff_emu_edge_vfix9_mmx,
+    &ff_emu_edge_vfix10_mmx, &ff_emu_edge_vfix11_mmx, &ff_emu_edge_vfix12_mmx,
+    &ff_emu_edge_vfix13_mmx, &ff_emu_edge_vfix14_mmx, &ff_emu_edge_vfix15_mmx,
+    &ff_emu_edge_vfix16_mmx, &ff_emu_edge_vfix17_mmx, &ff_emu_edge_vfix18_mmx,
+    &ff_emu_edge_vfix19_mmx, &ff_emu_edge_vfix20_mmx, &ff_emu_edge_vfix21_mmx,
+    &ff_emu_edge_vfix22_mmx
+};
+#endif
+extern emu_edge_vvar_func ff_emu_edge_vvar_mmx;
+extern emu_edge_vfix_func ff_emu_edge_vfix16_sse;
+extern emu_edge_vfix_func ff_emu_edge_vfix17_sse;
+extern emu_edge_vfix_func ff_emu_edge_vfix18_sse;
+extern emu_edge_vfix_func ff_emu_edge_vfix19_sse;
+extern emu_edge_vfix_func ff_emu_edge_vfix20_sse;
+extern emu_edge_vfix_func ff_emu_edge_vfix21_sse;
+extern emu_edge_vfix_func ff_emu_edge_vfix22_sse;
+static emu_edge_vfix_func *vfixtbl_sse[22] = {
+    ff_emu_edge_vfix1_mmx,  ff_emu_edge_vfix2_mmx,  ff_emu_edge_vfix3_mmx,
+    ff_emu_edge_vfix4_mmx,  ff_emu_edge_vfix5_mmx,  ff_emu_edge_vfix6_mmx,
+    ff_emu_edge_vfix7_mmx,  ff_emu_edge_vfix8_mmx,  ff_emu_edge_vfix9_mmx,
+    ff_emu_edge_vfix10_mmx, ff_emu_edge_vfix11_mmx, ff_emu_edge_vfix12_mmx,
+    ff_emu_edge_vfix13_mmx, ff_emu_edge_vfix14_mmx, ff_emu_edge_vfix15_mmx,
+    ff_emu_edge_vfix16_sse, ff_emu_edge_vfix17_sse, ff_emu_edge_vfix18_sse,
+    ff_emu_edge_vfix19_sse, ff_emu_edge_vfix20_sse, ff_emu_edge_vfix21_sse,
+    ff_emu_edge_vfix22_sse
+};
+extern emu_edge_vvar_func ff_emu_edge_vvar_sse;
+
+typedef void emu_edge_hfix_func(uint8_t *dst, x86_reg dst_stride,
+                                x86_reg start_x, x86_reg bh);
+typedef void emu_edge_hvar_func(uint8_t *dst, x86_reg dst_stride,
+                                x86_reg start_x, x86_reg n_words, x86_reg bh);
+
+extern emu_edge_hfix_func ff_emu_edge_hfix2_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix4_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix6_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix8_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix10_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix12_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix14_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix16_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix18_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix20_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix22_mmx;
+#if ARCH_X86_32
+static emu_edge_hfix_func *hfixtbl_mmx[11] = {
+    ff_emu_edge_hfix2_mmx,  ff_emu_edge_hfix4_mmx,  ff_emu_edge_hfix6_mmx,
+    ff_emu_edge_hfix8_mmx,  ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx,
+    ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_mmx, ff_emu_edge_hfix18_mmx,
+    ff_emu_edge_hfix20_mmx, ff_emu_edge_hfix22_mmx
+};
+#endif
+extern emu_edge_hvar_func ff_emu_edge_hvar_mmx;
+extern emu_edge_hfix_func ff_emu_edge_hfix16_sse;
+extern emu_edge_hfix_func ff_emu_edge_hfix18_sse;
+extern emu_edge_hfix_func ff_emu_edge_hfix20_sse;
+extern emu_edge_hfix_func ff_emu_edge_hfix22_sse;
+static emu_edge_hfix_func *hfixtbl_sse[11] = {
+    ff_emu_edge_hfix2_mmx,  ff_emu_edge_hfix4_mmx,  ff_emu_edge_hfix6_mmx,
+    ff_emu_edge_hfix8_mmx,  ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx,
+    ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_sse, ff_emu_edge_hfix18_sse,
+    ff_emu_edge_hfix20_sse, ff_emu_edge_hfix22_sse
+};
+extern emu_edge_hvar_func ff_emu_edge_hvar_sse;
+
+static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src,
+                                              ptrdiff_t dst_stride,
+                                              ptrdiff_t src_stride,
+                                              x86_reg block_w, x86_reg block_h,
+                                              x86_reg src_x, x86_reg src_y,
+                                              x86_reg w, x86_reg h,
+                                              emu_edge_vfix_func **vfix_tbl,
+                                              emu_edge_vvar_func *v_extend_var,
+                                              emu_edge_hfix_func **hfix_tbl,
+                                              emu_edge_hvar_func *h_extend_var)
 {
-    int start_y, start_x, end_y, end_x, src_y_add = 0;
+    x86_reg start_y, start_x, end_y, end_x, src_y_add = 0, p;
+
+    if (!w || !h)
+         return;
 
     if (src_y >= h) {
-        src_y_add = h - 1 - src_y;
-        src_y     = h - 1;
+        src  -= src_y * src_stride;
+        src_y = src_y_add = h - 1;
     } else if (src_y <= -block_h) {
-        src_y_add = 1 - block_h - src_y;
-        src_y     = 1 - block_h;
+        src  -= src_y*src_stride;
+        src_y = src_y_add = 1 - block_h;
     }
     if (src_x >= w) {
         src   += w - 1 - src_x;
@@ -66,53 +166,85 @@ static av_always_inline void emulated_edge_mc(uint8_t *buf, const uint8_t *src,
     assert(start_y < end_y && block_h > 0);
 
     // fill in the to-be-copied part plus all above/below
-    src += (src_y_add + start_y) * linesize + start_x;
-    buf += start_x;
-    core_fn(buf, src, linesize, start_y, end_y,
-            block_h, start_x, end_x, block_w);
+    src += (src_y_add + start_y) * src_stride + start_x;
+    w = end_x - start_x;
+    if (w <= 22) {
+        vfix_tbl[w - 1](dst + start_x, src,
+                        dst_stride, src_stride,
+                        start_y, end_y, block_h);
+    } else {
+        v_extend_var(dst + start_x, src, dst_stride, src_stride,
+                     start_y, end_y, block_h, w);
+    }
+
+    // fill left
+    if (start_x) {
+        if (start_x <= 22) {
+            hfix_tbl[(start_x - 1) >> 1](dst, dst_stride, start_x, block_h);
+        } else {
+            h_extend_var(dst, dst_stride,
+                         start_x, (start_x + 1) >> 1, block_h);
+        }
+    }
+
+    // fill right
+    p = block_w - end_x;
+    if (p) {
+        if (p <= 22) {
+            hfix_tbl[(p - 1) >> 1](dst + end_x - (p & 1), dst_stride,
+                                   -!(p & 1), block_h);
+        } else {
+            h_extend_var(dst + end_x - (p & 1), dst_stride,
+                         -!(p & 1), (p + 1) >> 1, block_h);
+        }
+    }
 }
 
 #if ARCH_X86_32
 static av_noinline void emulated_edge_mc_mmx(uint8_t *buf, const uint8_t *src,
-                                             ptrdiff_t linesize,
+                                             ptrdiff_t buf_stride,
+                                             ptrdiff_t src_stride,
                                              int block_w, int block_h,
                                              int src_x, int src_y, int w, int h)
 {
-    emulated_edge_mc(buf, src, linesize, block_w, block_h, src_x, src_y,
-                     w, h, &ff_emu_edge_core_mmx);
+    emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h,
+                     src_x, src_y, w, h, vfixtbl_mmx, &ff_emu_edge_vvar_mmx,
+                     hfixtbl_mmx, &ff_emu_edge_hvar_mmx);
 }
 #endif
 
-static av_noinline void emulated_edge_mc_sse(uint8_t *buf, const uint8_t *src,
-                                             ptrdiff_t linesize,
+static av_noinline void emulated_edge_mc_sse(uint8_t * buf,const uint8_t *src,
+                                             ptrdiff_t buf_stride,
+                                             ptrdiff_t src_stride,
                                              int block_w, int block_h,
                                              int src_x, int src_y, int w, int h)
 {
-    emulated_edge_mc(buf, src, linesize, block_w, block_h, src_x, src_y,
-                     w, h, &ff_emu_edge_core_sse);
+    emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h,
+                     src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse,
+                     hfixtbl_sse, &ff_emu_edge_hvar_sse);
 }
 #endif /* HAVE_YASM */
 
 void ff_prefetch_mmxext(uint8_t *buf, ptrdiff_t stride, int h);
 void ff_prefetch_3dnow(uint8_t *buf, ptrdiff_t stride, int h);
 
-void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc)
+av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
 #if ARCH_X86_32
-    if (bpc <= 8 && mm_flags & AV_CPU_FLAG_MMX) {
+    if (EXTERNAL_MMX(cpu_flags) && bpc <= 8) {
         ctx->emulated_edge_mc = emulated_edge_mc_mmx;
     }
-    if (mm_flags & AV_CPU_FLAG_3DNOW) {
+    if (EXTERNAL_AMD3DNOW(cpu_flags)) {
         ctx->prefetch = ff_prefetch_3dnow;
     }
 #endif /* ARCH_X86_32 */
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         ctx->prefetch = ff_prefetch_mmxext;
     }
-    if (bpc <= 8 && mm_flags & AV_CPU_FLAG_SSE) {
+    if (EXTERNAL_SSE(cpu_flags) && bpc <= 8) {
         ctx->emulated_edge_mc = emulated_edge_mc_sse;
     }
 #endif /* HAVE_YASM */
diff --git a/libavcodec/x86/vorbisdsp.asm b/libavcodec/x86/vorbisdsp.asm
new file mode 100644
index 0000000..c54650e
--- /dev/null
+++ b/libavcodec/x86/vorbisdsp.asm
@@ -0,0 +1,83 @@
+;******************************************************************************
+;* Vorbis x86 optimizations
+;* Copyright (C) 2006 Loren Merritt <lorenm at u.washington.edu>
+;*
+;* 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/x86util.asm"
+
+SECTION_RODATA
+
+pdw_80000000: times 4 dd 0x80000000
+
+SECTION .text
+
+%if ARCH_X86_32
+INIT_MMX 3dnow
+cglobal vorbis_inverse_coupling, 3, 3, 6, mag, ang, block_size
+    pxor                     m7, m7
+    lea                    magq, [magq+block_sizeq*4]
+    lea                    angq, [angq+block_sizeq*4]
+    neg             block_sizeq
+.loop:
+    mova                     m0, [magq+block_sizeq*4]
+    mova                     m1, [angq+block_sizeq*4]
+    mova                     m2, m0
+    mova                     m3, m1
+    pfcmpge                  m2, m7     ; m <= 0.0
+    pfcmpge                  m3, m7     ; a <= 0.0
+    pslld                    m2, 31     ; keep only the sign bit
+    pxor                     m1, m2
+    mova                     m4, m3
+    pand                     m3, m1
+    pandn                    m4, m1
+    pfadd                    m3, m0     ; a = m + ((a < 0) & (a ^ sign(m)))
+    pfsub                    m0, m4     ; m = m + ((a > 0) & (a ^ sign(m)))
+    mova   [angq+block_sizeq*4], m3
+    mova   [magq+block_sizeq*4], m0
+    add             block_sizeq, 2
+    jl .loop
+    femms
+    RET
+%endif
+
+INIT_XMM sse
+cglobal vorbis_inverse_coupling, 3, 4, 6, mag, ang, block_size, cntr
+    mova                     m5, [pdw_80000000]
+    xor                   cntrq, cntrq
+align 16
+.loop:
+    mova                     m0, [magq+cntrq*4]
+    mova                     m1, [angq+cntrq*4]
+    xorps                    m2, m2
+    xorps                    m3, m3
+    cmpleps                  m2, m0     ; m <= 0.0
+    cmpleps                  m3, m1     ; a <= 0.0
+    andps                    m2, m5     ; keep only the sign bit
+    xorps                    m1, m2
+    mova                     m4, m3
+    andps                    m3, m1
+    andnps                   m4, m1
+    addps                    m3, m0     ; a = m + ((a < 0) & (a ^ sign(m)))
+    subps                    m0, m4     ; m = m + ((a > 0) & (a ^ sign(m)))
+    mova         [angq+cntrq*4], m3
+    mova         [magq+cntrq*4], m0
+    add                   cntrq, 4
+    cmp                   cntrq, block_sizeq
+    jl .loop
+    RET
diff --git a/libavcodec/x86/vorbisdsp_init.c b/libavcodec/x86/vorbisdsp_init.c
new file mode 100644
index 0000000..2a978b6
--- /dev/null
+++ b/libavcodec/x86/vorbisdsp_init.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2006 Loren Merritt <lorenm at u.washington.edu>
+ *
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/vorbisdsp.h"
+
+void ff_vorbis_inverse_coupling_3dnow(float *mag, float *ang,
+                                      intptr_t blocksize);
+void ff_vorbis_inverse_coupling_sse(float *mag, float *ang,
+                                    intptr_t blocksize);
+
+av_cold void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp)
+{
+#if HAVE_YASM
+    int cpu_flags = av_get_cpu_flags();
+
+#if ARCH_X86_32
+    if (EXTERNAL_AMD3DNOW(cpu_flags))
+        dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_3dnow;
+#endif /* ARCH_X86_32 */
+    if (EXTERNAL_SSE(cpu_flags))
+        dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_sse;
+#endif /* HAVE_YASM */
+}
diff --git a/libavcodec/x86/vp3dsp.asm b/libavcodec/x86/vp3dsp.asm
index fc1e776..fc8a047 100644
--- a/libavcodec/x86/vp3dsp.asm
+++ b/libavcodec/x86/vp3dsp.asm
@@ -33,12 +33,13 @@ vp3_idct_data: times 8 dw 64277
                times 8 dw 25080
                times 8 dw 12785
 
+pb_7:  times 8 db 0x07
+pb_1F: times 8 db 0x1f
+pb_81: times 8 db 0x81
+
 cextern pb_1
 cextern pb_3
-cextern pb_7
-cextern pb_1F
 cextern pb_80
-cextern pb_81
 
 cextern pw_8
 
@@ -500,22 +501,22 @@ cglobal vp3_h_loop_filter, 3, 4
 
     ; at this point, function has completed dequantization + dezigzag +
     ; partial transposition; now do the idct itself
-%define I(x) [%1+16* x     ]
-%define J(x) [%1+16*(x-4)+8]
+%define I(x) [%1+16*x]
+%define J(x) [%1+16*x]
     RowIDCT
     Transpose
 
-%define I(x) [%1+16* x   +64]
-%define J(x) [%1+16*(x-4)+72]
+%define I(x) [%1+16*x+8]
+%define J(x) [%1+16*x+8]
     RowIDCT
     Transpose
 
-%define I(x) [%1+16*x]
-%define J(x) [%1+16*x]
+%define I(x) [%1+16* x]
+%define J(x) [%1+16*(x-4)+8]
     ColumnIDCT
 
-%define I(x) [%1+16*x+8]
-%define J(x) [%1+16*x+8]
+%define I(x) [%1+16* x   +64]
+%define J(x) [%1+16*(x-4)+72]
     ColumnIDCT
 %endif ; mmsize == 16/8
 %endmacro
@@ -533,10 +534,17 @@ cglobal vp3_idct_put, 3, 4, 9
     mova          m1, [r2+mmsize*2+%%i]
     mova          m2, [r2+mmsize*4+%%i]
     mova          m3, [r2+mmsize*6+%%i]
+%if mmsize == 8
+    packsswb      m0, [r2+mmsize*8+%%i]
+    packsswb      m1, [r2+mmsize*10+%%i]
+    packsswb      m2, [r2+mmsize*12+%%i]
+    packsswb      m3, [r2+mmsize*14+%%i]
+%else
     packsswb      m0, [r2+mmsize*1+%%i]
     packsswb      m1, [r2+mmsize*3+%%i]
     packsswb      m2, [r2+mmsize*5+%%i]
     packsswb      m3, [r2+mmsize*7+%%i]
+%endif
     paddb         m0, m4
     paddb         m1, m4
     paddb         m2, m4
@@ -560,49 +568,95 @@ cglobal vp3_idct_put, 3, 4, 9
     movq   [r0+r1*2], m3
     movhps [r0+r3  ], m3
 %endif
-%assign %%i %%i+64
+%assign %%i %%i+8
+%endrep
+
+    pxor          m0, m0
+%assign %%offset 0
+%rep 128/mmsize
+    mova [r2+%%offset], m0
+%assign %%offset %%offset+mmsize
 %endrep
     RET
 
 cglobal vp3_idct_add, 3, 4, 9
     VP3_IDCT      r2
 
-    mov           r3, 4
-    pxor          m4, m4
     movsxdifnidn  r1, r1d
-.loop:
+    lea           r3, [r1*3]
+    pxor          m4, m4
+%if mmsize == 16
+%assign %%i 0
+%rep 2
     movq          m0, [r0]
     movq          m1, [r0+r1]
-%if mmsize == 8
-    mova          m2, m0
-    mova          m3, m1
-%endif
+    movq          m2, [r0+r1*2]
+    movq          m3, [r0+r3]
     punpcklbw     m0, m4
     punpcklbw     m1, m4
-%if mmsize == 8
-    punpckhbw     m2, m4
-    punpckhbw     m3, m4
-%endif
-    paddsw        m0, [r2+ 0]
-    paddsw        m1, [r2+16]
-%if mmsize == 8
-    paddsw        m2, [r2+ 8]
-    paddsw        m3, [r2+24]
-    packuswb      m0, m2
-    packuswb      m1, m3
-%else ; mmsize == 16
+    punpcklbw     m2, m4
+    punpcklbw     m3, m4
+    paddsw        m0, [r2+ 0+%%i]
+    paddsw        m1, [r2+16+%%i]
+    paddsw        m2, [r2+32+%%i]
+    paddsw        m3, [r2+48+%%i]
     packuswb      m0, m1
+    packuswb      m2, m3
+    movq   [r0     ], m0
+    movhps [r0+r1  ], m0
+    movq   [r0+r1*2], m2
+    movhps [r0+r3  ], m2
+%if %%i == 0
+    lea           r0, [r0+r1*4]
 %endif
-    movq     [r0   ], m0
-%if mmsize == 8
-    movq     [r0+r1], m1
-%else ; mmsize == 16
-    movhps   [r0+r1], m0
+%assign %%i %%i+64
+%endrep
+%else
+%assign %%i 0
+%rep 2
+    movq          m0, [r0]
+    movq          m1, [r0+r1]
+    movq          m2, [r0+r1*2]
+    movq          m3, [r0+r3]
+    movq          m5, m0
+    movq          m6, m1
+    movq          m7, m2
+    punpcklbw     m0, m4
+    punpcklbw     m1, m4
+    punpcklbw     m2, m4
+    punpckhbw     m5, m4
+    punpckhbw     m6, m4
+    punpckhbw     m7, m4
+    paddsw        m0, [r2+ 0+%%i]
+    paddsw        m1, [r2+16+%%i]
+    paddsw        m2, [r2+32+%%i]
+    paddsw        m5, [r2+64+%%i]
+    paddsw        m6, [r2+80+%%i]
+    paddsw        m7, [r2+96+%%i]
+    packuswb      m0, m5
+    movq          m5, m3
+    punpcklbw     m3, m4
+    punpckhbw     m5, m4
+    packuswb      m1, m6
+    paddsw        m3, [r2+48+%%i]
+    paddsw        m5, [r2+112+%%i]
+    packuswb      m2, m7
+    packuswb      m3, m5
+    movq   [r0     ], m0
+    movq   [r0+r1  ], m1
+    movq   [r0+r1*2], m2
+    movq   [r0+r3  ], m3
+%if %%i == 0
+    lea           r0, [r0+r1*4]
+%endif
+%assign %%i %%i+8
+%endrep
 %endif
-    lea           r0, [r0+r1*2]
-    add           r2, 32
-    dec           r3
-    jg .loop
+%assign %%i 0
+%rep 128/mmsize
+    mova    [r2+%%i], m4
+%assign %%i %%i+mmsize
+%endrep
     RET
 %endmacro
 
@@ -620,7 +674,7 @@ vp3_idct_funcs
     paddusb       m2, m0
     movq          m4, [r0+r1*2]
     paddusb       m3, m0
-    movq          m5, [r0+r3  ]
+    movq          m5, [r0+r2  ]
     paddusb       m4, m0
     paddusb       m5, m0
     psubusb       m2, m1
@@ -630,7 +684,7 @@ vp3_idct_funcs
     movq   [r0+r1  ], m3
     psubusb       m5, m1
     movq   [r0+r1*2], m4
-    movq   [r0+r3  ], m5
+    movq   [r0+r2  ], m5
 %endmacro
 
 INIT_MMX mmxext
@@ -638,11 +692,12 @@ cglobal vp3_idct_dc_add, 3, 4
 %if ARCH_X86_64
     movsxd        r1, r1d
 %endif
-    lea           r3, [r1*3]
-    movsx         r2, word [r2]
-    add           r2, 15
-    sar           r2, 5
-    movd          m0, r2d
+    movsx         r3, word [r2]
+    mov    word [r2], 0
+    lea           r2, [r1*3]
+    add           r3, 15
+    sar           r3, 5
+    movd          m0, r3d
     pshufw        m0, m0, 0x0
     pxor          m1, m1
     psubw         m1, m0
diff --git a/libavcodec/x86/vp3dsp_init.c b/libavcodec/x86/vp3dsp_init.c
index bbe74ba..9e38014 100644
--- a/libavcodec/x86/vp3dsp_init.c
+++ b/libavcodec/x86/vp3dsp_init.c
@@ -22,17 +22,18 @@
 #include "libavutil/cpu.h"
 #include "libavutil/x86/cpu.h"
 #include "libavcodec/avcodec.h"
+#include "libavcodec/dsputil.h"
 #include "libavcodec/vp3dsp.h"
 #include "config.h"
 
-void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, int16_t *block);
+void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, int16_t *block);
 
-void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block);
-void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block);
+void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, int16_t *block);
+void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, int16_t *block);
 
 void ff_vp3_idct_dc_add_mmxext(uint8_t *dest, int line_size,
-                               const DCTELEM *block);
+                               int16_t *block);
 
 void ff_vp3_v_loop_filter_mmxext(uint8_t *src, int stride,
                                  int *bounding_values);
@@ -41,17 +42,16 @@ void ff_vp3_h_loop_filter_mmxext(uint8_t *src, int stride,
 
 av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags)
 {
-    int cpuflags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
 #if ARCH_X86_32
-    if (EXTERNAL_MMX(cpuflags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->idct_put  = ff_vp3_idct_put_mmx;
         c->idct_add  = ff_vp3_idct_add_mmx;
-        c->idct_perm = FF_PARTTRANS_IDCT_PERM;
     }
 #endif
 
-    if (EXTERNAL_MMXEXT(cpuflags)) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         c->idct_dc_add = ff_vp3_idct_dc_add_mmxext;
 
         if (!(flags & CODEC_FLAG_BITEXACT)) {
@@ -60,9 +60,8 @@ av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags)
         }
     }
 
-    if (EXTERNAL_SSE2(cpuflags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         c->idct_put  = ff_vp3_idct_put_sse2;
         c->idct_add  = ff_vp3_idct_add_sse2;
-        c->idct_perm = FF_TRANSPOSE_IDCT_PERM;
     }
 }
diff --git a/libavcodec/x86/vp56dsp_init.c b/libavcodec/x86/vp56dsp_init.c
deleted file mode 100644
index 3b49df6..0000000
--- a/libavcodec/x86/vp56dsp_init.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * VP6 MMX/SSE2 optimizations
- * Copyright (C) 2009  Sebastien Lucas <sebastien.lucas at gmail.com>
- * Copyright (C) 2009  Zuxy Meng <zuxy.meng at gmail.com>
- *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Libav is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/cpu.h"
-#include "libavutil/x86/asm.h"
-#include "libavutil/x86/cpu.h"
-#include "libavcodec/dsputil.h"
-#include "libavcodec/vp56dsp.h"
-
-void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, int stride,
-                             const int16_t *h_weights,const int16_t *v_weights);
-void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, int stride,
-                              const int16_t *h_weights,const int16_t *v_weights);
-
-av_cold void ff_vp56dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec)
-{
-    int mm_flags = av_get_cpu_flags();
-
-    if (CONFIG_VP6_DECODER && codec == AV_CODEC_ID_VP6) {
-#if ARCH_X86_32
-        if (EXTERNAL_MMX(mm_flags)) {
-            c->vp6_filter_diag4 = ff_vp6_filter_diag4_mmx;
-        }
-#endif
-
-        if (EXTERNAL_SSE2(mm_flags)) {
-            c->vp6_filter_diag4 = ff_vp6_filter_diag4_sse2;
-        }
-    }
-}
diff --git a/libavcodec/x86/vp56dsp.asm b/libavcodec/x86/vp6dsp.asm
similarity index 100%
rename from libavcodec/x86/vp56dsp.asm
rename to libavcodec/x86/vp6dsp.asm
diff --git a/libavcodec/x86/vp6dsp_init.c b/libavcodec/x86/vp6dsp_init.c
new file mode 100644
index 0000000..c4a500b
--- /dev/null
+++ b/libavcodec/x86/vp6dsp_init.c
@@ -0,0 +1,45 @@
+/*
+ * VP6 MMX/SSE2 optimizations
+ * Copyright (C) 2009  Sebastien Lucas <sebastien.lucas at gmail.com>
+ * Copyright (C) 2009  Zuxy Meng <zuxy.meng at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/cpu.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/vp56dsp.h"
+
+void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, int stride,
+                             const int16_t *h_weights,const int16_t *v_weights);
+void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, int stride,
+                              const int16_t *h_weights,const int16_t *v_weights);
+
+av_cold void ff_vp6dsp_init_x86(VP56DSPContext* c, enum AVCodecID codec)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+#if ARCH_X86_32
+    if (EXTERNAL_MMX(cpu_flags)) {
+        c->vp6_filter_diag4 = ff_vp6_filter_diag4_mmx;
+    }
+#endif
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        c->vp6_filter_diag4 = ff_vp6_filter_diag4_sse2;
+    }
+}
diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm
index af8403e..d41b6b4 100644
--- a/libavcodec/x86/vp8dsp.asm
+++ b/libavcodec/x86/vp8dsp.asm
@@ -143,28 +143,13 @@ filter_h6_shuf1: db 0, 5, 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11,  7, 12
 filter_h6_shuf2: db 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,  7, 7,  8,  8,  9
 filter_h6_shuf3: db 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,  9, 9, 10, 10, 11
 
-pw_256:  times 8 dw 256
-
+pw_256:   times 8 dw 256
 pw_20091: times 4 dw 20091
 pw_17734: times 4 dw 17734
 
-pb_27_63: times 8 db 27, 63
-pb_18_63: times 8 db 18, 63
-pb_9_63:  times 8 db  9, 63
-
-cextern pb_1
 cextern pw_3
-cextern pb_3
 cextern pw_4
-cextern pb_4
-cextern pw_9
-cextern pw_18
-cextern pw_27
-cextern pw_63
 cextern pw_64
-cextern pb_80
-cextern pb_F8
-cextern pb_FE
 
 SECTION .text
 
@@ -899,7 +884,7 @@ cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height
     REP_RET
 
 ;-----------------------------------------------------------------------------
-; void vp8_idct_dc_add_<opt>(uint8_t *dst, DCTELEM block[16], int stride);
+; void vp8_idct_dc_add_<opt>(uint8_t *dst, int16_t block[16], int stride);
 ;-----------------------------------------------------------------------------
 
 %macro ADD_DC 4
@@ -977,7 +962,7 @@ cglobal vp8_idct_dc_add, 3, 3, 6, dst, block, stride
     RET
 
 ;-----------------------------------------------------------------------------
-; void vp8_idct_dc_add4y_<opt>(uint8_t *dst, DCTELEM block[4][16], int stride);
+; void vp8_idct_dc_add4y_<opt>(uint8_t *dst, int16_t block[4][16], int stride);
 ;-----------------------------------------------------------------------------
 
 %if ARCH_X86_32
@@ -1050,7 +1035,7 @@ cglobal vp8_idct_dc_add4y, 3, 3, 6, dst, block, stride
     RET
 
 ;-----------------------------------------------------------------------------
-; void vp8_idct_dc_add4uv_<opt>(uint8_t *dst, DCTELEM block[4][16], int stride);
+; void vp8_idct_dc_add4uv_<opt>(uint8_t *dst, int16_t block[4][16], int stride);
 ;-----------------------------------------------------------------------------
 
 INIT_MMX mmx
@@ -1092,7 +1077,7 @@ cglobal vp8_idct_dc_add4uv, 3, 3, 0, dst, block, stride
     RET
 
 ;-----------------------------------------------------------------------------
-; void vp8_idct_add_<opt>(uint8_t *dst, DCTELEM block[16], int stride);
+; void vp8_idct_add_<opt>(uint8_t *dst, int16_t block[16], int stride);
 ;-----------------------------------------------------------------------------
 
 ; calculate %1=mul_35468(%1)-mul_20091(%2); %2=mul_20091(%1)+mul_35468(%2)
@@ -1172,7 +1157,7 @@ INIT_MMX sse
 VP8_IDCT_ADD
 
 ;-----------------------------------------------------------------------------
-; void vp8_luma_dc_wht_mmxext(DCTELEM block[4][4][16], DCTELEM dc[16])
+; void vp8_luma_dc_wht_mmxext(int16_t block[4][4][16], int16_t dc[16])
 ;-----------------------------------------------------------------------------
 
 %macro SCATTER_WHT 3
@@ -1238,1544 +1223,3 @@ VP8_DC_WHT
 %endif
 INIT_MMX sse
 VP8_DC_WHT
-
-;-----------------------------------------------------------------------------
-; void vp8_h/v_loop_filter_simple_<opt>(uint8_t *dst, int stride, int flim);
-;-----------------------------------------------------------------------------
-
-; macro called with 7 mm register indexes as argument, and 4 regular registers
-;
-; first 4 mm registers will carry the transposed pixel data
-; the other three are scratchspace (one would be sufficient, but this allows
-; for more spreading/pipelining and thus faster execution on OOE CPUs)
-;
-; first two regular registers are buf+4*stride and buf+5*stride
-; third is -stride, fourth is +stride
-%macro READ_8x4_INTERLEAVED 11
-    ; interleave 8 (A-H) rows of 4 pixels each
-    movd          m%1, [%8+%10*4]   ; A0-3
-    movd          m%5, [%9+%10*4]   ; B0-3
-    movd          m%2, [%8+%10*2]   ; C0-3
-    movd          m%6, [%8+%10]     ; D0-3
-    movd          m%3, [%8]         ; E0-3
-    movd          m%7, [%9]         ; F0-3
-    movd          m%4, [%9+%11]     ; G0-3
-    punpcklbw     m%1, m%5          ; A/B interleaved
-    movd          m%5, [%9+%11*2]   ; H0-3
-    punpcklbw     m%2, m%6          ; C/D interleaved
-    punpcklbw     m%3, m%7          ; E/F interleaved
-    punpcklbw     m%4, m%5          ; G/H interleaved
-%endmacro
-
-; macro called with 7 mm register indexes as argument, and 5 regular registers
-; first 11 mean the same as READ_8x4_TRANSPOSED above
-; fifth regular register is scratchspace to reach the bottom 8 rows, it
-; will be set to second regular register + 8*stride at the end
-%macro READ_16x4_INTERLEAVED 12
-    ; transpose 16 (A-P) rows of 4 pixels each
-    lea           %12, [r0+8*r2]
-
-    ; read (and interleave) those addressable by %8 (=r0), A/C/D/E/I/K/L/M
-    movd          m%1, [%8+%10*4]   ; A0-3
-    movd          m%3, [%12+%10*4]  ; I0-3
-    movd          m%2, [%8+%10*2]   ; C0-3
-    movd          m%4, [%12+%10*2]  ; K0-3
-    movd          m%6, [%8+%10]     ; D0-3
-    movd          m%5, [%12+%10]    ; L0-3
-    movd          m%7, [%12]        ; M0-3
-    add           %12, %11
-    punpcklbw     m%1, m%3          ; A/I
-    movd          m%3, [%8]         ; E0-3
-    punpcklbw     m%2, m%4          ; C/K
-    punpcklbw     m%6, m%5          ; D/L
-    punpcklbw     m%3, m%7          ; E/M
-    punpcklbw     m%2, m%6          ; C/D/K/L interleaved
-
-    ; read (and interleave) those addressable by %9 (=r4), B/F/G/H/J/N/O/P
-    movd         m%5, [%9+%10*4]   ; B0-3
-    movd         m%4, [%12+%10*4]  ; J0-3
-    movd         m%7, [%9]         ; F0-3
-    movd         m%6, [%12]        ; N0-3
-    punpcklbw    m%5, m%4          ; B/J
-    punpcklbw    m%7, m%6          ; F/N
-    punpcklbw    m%1, m%5          ; A/B/I/J interleaved
-    punpcklbw    m%3, m%7          ; E/F/M/N interleaved
-    movd         m%4, [%9+%11]     ; G0-3
-    movd         m%6, [%12+%11]    ; O0-3
-    movd         m%5, [%9+%11*2]   ; H0-3
-    movd         m%7, [%12+%11*2]  ; P0-3
-    punpcklbw    m%4, m%6          ; G/O
-    punpcklbw    m%5, m%7          ; H/P
-    punpcklbw    m%4, m%5          ; G/H/O/P interleaved
-%endmacro
-
-; write 4 mm registers of 2 dwords each
-; first four arguments are mm register indexes containing source data
-; last four are registers containing buf+4*stride, buf+5*stride,
-; -stride and +stride
-%macro WRITE_4x2D 8
-    ; write out (2 dwords per register)
-    movd    [%5+%7*4], m%1
-    movd    [%5+%7*2], m%2
-    movd         [%5], m%3
-    movd      [%6+%8], m%4
-    punpckhdq     m%1, m%1
-    punpckhdq     m%2, m%2
-    punpckhdq     m%3, m%3
-    punpckhdq     m%4, m%4
-    movd    [%6+%7*4], m%1
-    movd      [%5+%7], m%2
-    movd         [%6], m%3
-    movd    [%6+%8*2], m%4
-%endmacro
-
-; write 4 xmm registers of 4 dwords each
-; arguments same as WRITE_2x4D, but with an extra register, so that the 5 regular
-; registers contain buf+4*stride, buf+5*stride, buf+12*stride, -stride and +stride
-; we add 1*stride to the third regular registry in the process
-; the 10th argument is 16 if it's a Y filter (i.e. all regular registers cover the
-; same memory region), or 8 if they cover two separate buffers (third one points to
-; a different memory region than the first two), allowing for more optimal code for
-; the 16-width case
-%macro WRITE_4x4D 10
-    ; write out (4 dwords per register), start with dwords zero
-    movd    [%5+%8*4], m%1
-    movd         [%5], m%2
-    movd    [%7+%8*4], m%3
-    movd         [%7], m%4
-
-    ; store dwords 1
-    psrldq        m%1, 4
-    psrldq        m%2, 4
-    psrldq        m%3, 4
-    psrldq        m%4, 4
-    movd    [%6+%8*4], m%1
-    movd         [%6], m%2
-%if %10 == 16
-    movd    [%6+%9*4], m%3
-%endif
-    movd      [%7+%9], m%4
-
-    ; write dwords 2
-    psrldq        m%1, 4
-    psrldq        m%2, 4
-%if %10 == 8
-    movd    [%5+%8*2], m%1
-    movd          %5d, m%3
-%endif
-    psrldq        m%3, 4
-    psrldq        m%4, 4
-%if %10 == 16
-    movd    [%5+%8*2], m%1
-%endif
-    movd      [%6+%9], m%2
-    movd    [%7+%8*2], m%3
-    movd    [%7+%9*2], m%4
-    add            %7, %9
-
-    ; store dwords 3
-    psrldq        m%1, 4
-    psrldq        m%2, 4
-    psrldq        m%3, 4
-    psrldq        m%4, 4
-%if %10 == 8
-    mov     [%7+%8*4], %5d
-    movd    [%6+%8*2], m%1
-%else
-    movd      [%5+%8], m%1
-%endif
-    movd    [%6+%9*2], m%2
-    movd    [%7+%8*2], m%3
-    movd    [%7+%9*2], m%4
-%endmacro
-
-; write 4 or 8 words in the mmx/xmm registers as 8 lines
-; 1 and 2 are the registers to write, this can be the same (for SSE2)
-; for pre-SSE4:
-; 3 is a general-purpose register that we will clobber
-; for SSE4:
-; 3 is a pointer to the destination's 5th line
-; 4 is a pointer to the destination's 4th line
-; 5/6 is -stride and +stride
-%macro WRITE_2x4W 6
-    movd            %3d, %1
-    punpckhdq        %1, %1
-    mov       [%4+%5*4], %3w
-    shr              %3, 16
-    add              %4, %6
-    mov       [%4+%5*4], %3w
-
-    movd            %3d, %1
-    add              %4, %5
-    mov       [%4+%5*2], %3w
-    shr              %3, 16
-    mov       [%4+%5  ], %3w
-
-    movd            %3d, %2
-    punpckhdq        %2, %2
-    mov       [%4     ], %3w
-    shr              %3, 16
-    mov       [%4+%6  ], %3w
-
-    movd            %3d, %2
-    add              %4, %6
-    mov       [%4+%6  ], %3w
-    shr              %3, 16
-    mov       [%4+%6*2], %3w
-    add              %4, %5
-%endmacro
-
-%macro WRITE_8W 5
-%if cpuflag(sse4)
-    pextrw    [%3+%4*4], %1, 0
-    pextrw    [%2+%4*4], %1, 1
-    pextrw    [%3+%4*2], %1, 2
-    pextrw    [%3+%4  ], %1, 3
-    pextrw    [%3     ], %1, 4
-    pextrw    [%2     ], %1, 5
-    pextrw    [%2+%5  ], %1, 6
-    pextrw    [%2+%5*2], %1, 7
-%else
-    movd            %2d, %1
-    psrldq           %1, 4
-    mov       [%3+%4*4], %2w
-    shr              %2, 16
-    add              %3, %5
-    mov       [%3+%4*4], %2w
-
-    movd            %2d, %1
-    psrldq           %1, 4
-    add              %3, %4
-    mov       [%3+%4*2], %2w
-    shr              %2, 16
-    mov       [%3+%4  ], %2w
-
-    movd            %2d, %1
-    psrldq           %1, 4
-    mov       [%3     ], %2w
-    shr              %2, 16
-    mov       [%3+%5  ], %2w
-
-    movd            %2d, %1
-    add              %3, %5
-    mov       [%3+%5  ], %2w
-    shr              %2, 16
-    mov       [%3+%5*2], %2w
-%endif
-%endmacro
-
-%macro SIMPLE_LOOPFILTER 2
-cglobal vp8_%1_loop_filter_simple, 3, %2, 8, dst, stride, flim, cntr
-%if mmsize == 8 ; mmx/mmxext
-    mov         cntrq, 2
-%endif
-%if cpuflag(ssse3)
-    pxor           m0, m0
-%endif
-    SPLATB_REG     m7, flim, m0     ; splat "flim" into register
-
-    ; set up indexes to address 4 rows
-%if mmsize == 8
-    DEFINE_ARGS dst1, mstride, stride, cntr, dst2
-%else
-    DEFINE_ARGS dst1, mstride, stride, dst3, dst2
-%endif
-    mov       strideq, mstrideq
-    neg      mstrideq
-%ifidn %1, h
-    lea         dst1q, [dst1q+4*strideq-2]
-%endif
-
-%if mmsize == 8 ; mmx / mmxext
-.next8px:
-%endif
-%ifidn %1, v
-    ; read 4 half/full rows of pixels
-    mova           m0, [dst1q+mstrideq*2]    ; p1
-    mova           m1, [dst1q+mstrideq]      ; p0
-    mova           m2, [dst1q]               ; q0
-    mova           m3, [dst1q+ strideq]      ; q1
-%else ; h
-    lea         dst2q, [dst1q+ strideq]
-
-%if mmsize == 8 ; mmx/mmxext
-    READ_8x4_INTERLEAVED  0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq
-%else ; sse2
-    READ_16x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq, dst3q
-%endif
-    TRANSPOSE4x4W         0, 1, 2, 3, 4
-%endif
-
-    ; simple_limit
-    mova           m5, m2           ; m5=backup of q0
-    mova           m6, m1           ; m6=backup of p0
-    psubusb        m1, m2           ; p0-q0
-    psubusb        m2, m6           ; q0-p0
-    por            m1, m2           ; FFABS(p0-q0)
-    paddusb        m1, m1           ; m1=FFABS(p0-q0)*2
-
-    mova           m4, m3
-    mova           m2, m0
-    psubusb        m3, m0           ; q1-p1
-    psubusb        m0, m4           ; p1-q1
-    por            m3, m0           ; FFABS(p1-q1)
-    mova           m0, [pb_80]
-    pxor           m2, m0
-    pxor           m4, m0
-    psubsb         m2, m4           ; m2=p1-q1 (signed) backup for below
-    pand           m3, [pb_FE]
-    psrlq          m3, 1            ; m3=FFABS(p1-q1)/2, this can be used signed
-    paddusb        m3, m1
-    psubusb        m3, m7
-    pxor           m1, m1
-    pcmpeqb        m3, m1           ; abs(p0-q0)*2+abs(p1-q1)/2<=flim mask(0xff/0x0)
-
-    ; filter_common (use m2/p1-q1, m4=q0, m6=p0, m5/q0-p0 and m3/mask)
-    mova           m4, m5
-    pxor           m5, m0
-    pxor           m0, m6
-    psubsb         m5, m0           ; q0-p0 (signed)
-    paddsb         m2, m5
-    paddsb         m2, m5
-    paddsb         m2, m5           ; a=(p1-q1) + 3*(q0-p0)
-    pand           m2, m3           ; apply filter mask (m3)
-
-    mova           m3, [pb_F8]
-    mova           m1, m2
-    paddsb         m2, [pb_4]       ; f1<<3=a+4
-    paddsb         m1, [pb_3]       ; f2<<3=a+3
-    pand           m2, m3
-    pand           m1, m3           ; cache f2<<3
-
-    pxor           m0, m0
-    pxor           m3, m3
-    pcmpgtb        m0, m2           ; which values are <0?
-    psubb          m3, m2           ; -f1<<3
-    psrlq          m2, 3            ; +f1
-    psrlq          m3, 3            ; -f1
-    pand           m3, m0
-    pandn          m0, m2
-    psubusb        m4, m0
-    paddusb        m4, m3           ; q0-f1
-
-    pxor           m0, m0
-    pxor           m3, m3
-    pcmpgtb        m0, m1           ; which values are <0?
-    psubb          m3, m1           ; -f2<<3
-    psrlq          m1, 3            ; +f2
-    psrlq          m3, 3            ; -f2
-    pand           m3, m0
-    pandn          m0, m1
-    paddusb        m6, m0
-    psubusb        m6, m3           ; p0+f2
-
-    ; store
-%ifidn %1, v
-    mova      [dst1q], m4
-    mova [dst1q+mstrideq], m6
-%else ; h
-    inc        dst1q
-    SBUTTERFLY    bw, 6, 4, 0
-
-%if mmsize == 16 ; sse2
-%if cpuflag(sse4)
-    inc         dst2q
-%endif
-    WRITE_8W       m6, dst2q, dst1q, mstrideq, strideq
-    lea         dst2q, [dst3q+mstrideq+1]
-%if cpuflag(sse4)
-    inc         dst3q
-%endif
-    WRITE_8W       m4, dst3q, dst2q, mstrideq, strideq
-%else ; mmx/mmxext
-    WRITE_2x4W     m6, m4, dst2q, dst1q, mstrideq, strideq
-%endif
-%endif
-
-%if mmsize == 8 ; mmx/mmxext
-    ; next 8 pixels
-%ifidn %1, v
-    add         dst1q, 8            ; advance 8 cols = pixels
-%else ; h
-    lea         dst1q, [dst1q+strideq*8-1]  ; advance 8 rows = lines
-%endif
-    dec         cntrq
-    jg .next8px
-    REP_RET
-%else ; sse2
-    RET
-%endif
-%endmacro
-
-%if ARCH_X86_32
-INIT_MMX mmx
-SIMPLE_LOOPFILTER v, 4
-SIMPLE_LOOPFILTER h, 5
-INIT_MMX mmxext
-SIMPLE_LOOPFILTER v, 4
-SIMPLE_LOOPFILTER h, 5
-%endif
-
-INIT_XMM sse2
-SIMPLE_LOOPFILTER v, 3
-SIMPLE_LOOPFILTER h, 5
-INIT_XMM ssse3
-SIMPLE_LOOPFILTER v, 3
-SIMPLE_LOOPFILTER h, 5
-INIT_XMM sse4
-SIMPLE_LOOPFILTER h, 5
-
-;-----------------------------------------------------------------------------
-; void vp8_h/v_loop_filter<size>_inner_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
-;                                            int flimE, int flimI, int hev_thr);
-;-----------------------------------------------------------------------------
-
-%macro INNER_LOOPFILTER 2
-%define stack_size 0
-%ifndef m8   ; stack layout: [0]=E, [1]=I, [2]=hev_thr
-%ifidn %1, v ;               [3]=hev() result
-%define stack_size mmsize * -4
-%else ; h    ; extra storage space for transposes
-%define stack_size mmsize * -5
-%endif
-%endif
-
-%if %2 == 8 ; chroma
-cglobal vp8_%1_loop_filter8uv_inner, 6, 6, 13, stack_size, dst, dst8, stride, flimE, flimI, hevthr
-%else ; luma
-cglobal vp8_%1_loop_filter16y_inner, 5, 5, 13, stack_size, dst, stride, flimE, flimI, hevthr
-%endif
-
-%if cpuflag(ssse3)
-    pxor             m7, m7
-%endif
-
-%ifndef m8
-    ; splat function arguments
-    SPLATB_REG       m0, flimEq, m7   ; E
-    SPLATB_REG       m1, flimIq, m7   ; I
-    SPLATB_REG       m2, hevthrq, m7  ; hev_thresh
-
-%define m_flimE    [rsp]
-%define m_flimI    [rsp+mmsize]
-%define m_hevthr   [rsp+mmsize*2]
-%define m_maskres  [rsp+mmsize*3]
-%define m_p0backup [rsp+mmsize*3]
-%define m_q0backup [rsp+mmsize*4]
-
-    mova        m_flimE, m0
-    mova        m_flimI, m1
-    mova       m_hevthr, m2
-%else
-%define m_flimE    m9
-%define m_flimI    m10
-%define m_hevthr   m11
-%define m_maskres  m12
-%define m_p0backup m12
-%define m_q0backup m8
-
-    ; splat function arguments
-    SPLATB_REG  m_flimE, flimEq, m7   ; E
-    SPLATB_REG  m_flimI, flimIq, m7   ; I
-    SPLATB_REG m_hevthr, hevthrq, m7  ; hev_thresh
-%endif
-
-%if %2 == 8 ; chroma
-    DEFINE_ARGS dst1, dst8, mstride, stride, dst2
-%elif mmsize == 8
-    DEFINE_ARGS dst1, mstride, stride, dst2, cntr
-    mov           cntrq, 2
-%else
-    DEFINE_ARGS dst1, mstride, stride, dst2, dst8
-%endif
-    mov         strideq, mstrideq
-    neg        mstrideq
-%ifidn %1, h
-    lea           dst1q, [dst1q+strideq*4-4]
-%if %2 == 8 ; chroma
-    lea           dst8q, [dst8q+strideq*4-4]
-%endif
-%endif
-
-%if mmsize == 8
-.next8px:
-%endif
-    ; read
-    lea           dst2q, [dst1q+strideq]
-%ifidn %1, v
-%if %2 == 8 && mmsize == 16
-%define movrow movh
-%else
-%define movrow mova
-%endif
-    movrow           m0, [dst1q+mstrideq*4] ; p3
-    movrow           m1, [dst2q+mstrideq*4] ; p2
-    movrow           m2, [dst1q+mstrideq*2] ; p1
-    movrow           m5, [dst2q]            ; q1
-    movrow           m6, [dst2q+ strideq*1] ; q2
-    movrow           m7, [dst2q+ strideq*2] ; q3
-%if mmsize == 16 && %2 == 8
-    movhps           m0, [dst8q+mstrideq*4]
-    movhps           m2, [dst8q+mstrideq*2]
-    add           dst8q, strideq
-    movhps           m1, [dst8q+mstrideq*4]
-    movhps           m5, [dst8q]
-    movhps           m6, [dst8q+ strideq  ]
-    movhps           m7, [dst8q+ strideq*2]
-    add           dst8q, mstrideq
-%endif
-%elif mmsize == 8 ; mmx/mmxext (h)
-    ; read 8 rows of 8px each
-    movu             m0, [dst1q+mstrideq*4]
-    movu             m1, [dst2q+mstrideq*4]
-    movu             m2, [dst1q+mstrideq*2]
-    movu             m3, [dst1q+mstrideq  ]
-    movu             m4, [dst1q]
-    movu             m5, [dst2q]
-    movu             m6, [dst2q+ strideq  ]
-
-    ; 8x8 transpose
-    TRANSPOSE4x4B     0, 1, 2, 3, 7
-    mova     m_q0backup, m1
-    movu             m7, [dst2q+ strideq*2]
-    TRANSPOSE4x4B     4, 5, 6, 7, 1
-    SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
-    SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
-    SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
-    mova             m1, m_q0backup
-    mova     m_q0backup, m2          ; store q0
-    SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
-    mova     m_p0backup, m5          ; store p0
-    SWAP              1, 4
-    SWAP              2, 4
-    SWAP              6, 3
-    SWAP              5, 3
-%else ; sse2 (h)
-%if %2 == 16
-    lea           dst8q, [dst1q+ strideq*8]
-%endif
-
-    ; read 16 rows of 8px each, interleave
-    movh             m0, [dst1q+mstrideq*4]
-    movh             m1, [dst8q+mstrideq*4]
-    movh             m2, [dst1q+mstrideq*2]
-    movh             m5, [dst8q+mstrideq*2]
-    movh             m3, [dst1q+mstrideq  ]
-    movh             m6, [dst8q+mstrideq  ]
-    movh             m4, [dst1q]
-    movh             m7, [dst8q]
-    punpcklbw        m0, m1          ; A/I
-    punpcklbw        m2, m5          ; C/K
-    punpcklbw        m3, m6          ; D/L
-    punpcklbw        m4, m7          ; E/M
-
-    add           dst8q, strideq
-    movh             m1, [dst2q+mstrideq*4]
-    movh             m6, [dst8q+mstrideq*4]
-    movh             m5, [dst2q]
-    movh             m7, [dst8q]
-    punpcklbw        m1, m6          ; B/J
-    punpcklbw        m5, m7          ; F/N
-    movh             m6, [dst2q+ strideq  ]
-    movh             m7, [dst8q+ strideq  ]
-    punpcklbw        m6, m7          ; G/O
-
-    ; 8x16 transpose
-    TRANSPOSE4x4B     0, 1, 2, 3, 7
-%ifdef m8
-    SWAP              1, 8
-%else
-    mova     m_q0backup, m1
-%endif
-    movh             m7, [dst2q+ strideq*2]
-    movh             m1, [dst8q+ strideq*2]
-    punpcklbw        m7, m1          ; H/P
-    TRANSPOSE4x4B     4, 5, 6, 7, 1
-    SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
-    SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
-    SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
-%ifdef m8
-    SWAP              1, 8
-    SWAP              2, 8
-%else
-    mova             m1, m_q0backup
-    mova     m_q0backup, m2          ; store q0
-%endif
-    SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
-%ifdef m12
-    SWAP              5, 12
-%else
-    mova     m_p0backup, m5          ; store p0
-%endif
-    SWAP              1, 4
-    SWAP              2, 4
-    SWAP              6, 3
-    SWAP              5, 3
-%endif
-
-    ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
-    mova             m4, m1
-    SWAP              4, 1
-    psubusb          m4, m0          ; p2-p3
-    psubusb          m0, m1          ; p3-p2
-    por              m0, m4          ; abs(p3-p2)
-
-    mova             m4, m2
-    SWAP              4, 2
-    psubusb          m4, m1          ; p1-p2
-    psubusb          m1, m2          ; p2-p1
-    por              m1, m4          ; abs(p2-p1)
-
-    mova             m4, m6
-    SWAP              4, 6
-    psubusb          m4, m7          ; q2-q3
-    psubusb          m7, m6          ; q3-q2
-    por              m7, m4          ; abs(q3-q2)
-
-    mova             m4, m5
-    SWAP              4, 5
-    psubusb          m4, m6          ; q1-q2
-    psubusb          m6, m5          ; q2-q1
-    por              m6, m4          ; abs(q2-q1)
-
-%if notcpuflag(mmxext)
-    mova             m4, m_flimI
-    pxor             m3, m3
-    psubusb          m0, m4
-    psubusb          m1, m4
-    psubusb          m7, m4
-    psubusb          m6, m4
-    pcmpeqb          m0, m3          ; abs(p3-p2) <= I
-    pcmpeqb          m1, m3          ; abs(p2-p1) <= I
-    pcmpeqb          m7, m3          ; abs(q3-q2) <= I
-    pcmpeqb          m6, m3          ; abs(q2-q1) <= I
-    pand             m0, m1
-    pand             m7, m6
-    pand             m0, m7
-%else ; mmxext/sse2
-    pmaxub           m0, m1
-    pmaxub           m6, m7
-    pmaxub           m0, m6
-%endif
-
-    ; normal_limit and high_edge_variance for p1-p0, q1-q0
-    SWAP              7, 3           ; now m7 is zero
-%ifidn %1, v
-    movrow           m3, [dst1q+mstrideq  ] ; p0
-%if mmsize == 16 && %2 == 8
-    movhps           m3, [dst8q+mstrideq  ]
-%endif
-%elifdef m12
-    SWAP              3, 12
-%else
-    mova             m3, m_p0backup
-%endif
-
-    mova             m1, m2
-    SWAP              1, 2
-    mova             m6, m3
-    SWAP              3, 6
-    psubusb          m1, m3          ; p1-p0
-    psubusb          m6, m2          ; p0-p1
-    por              m1, m6          ; abs(p1-p0)
-%if notcpuflag(mmxext)
-    mova             m6, m1
-    psubusb          m1, m4
-    psubusb          m6, m_hevthr
-    pcmpeqb          m1, m7          ; abs(p1-p0) <= I
-    pcmpeqb          m6, m7          ; abs(p1-p0) <= hev_thresh
-    pand             m0, m1
-    mova      m_maskres, m6
-%else ; mmxext/sse2
-    pmaxub           m0, m1          ; max_I
-    SWAP              1, 4           ; max_hev_thresh
-%endif
-
-    SWAP              6, 4           ; now m6 is I
-%ifidn %1, v
-    movrow           m4, [dst1q]     ; q0
-%if mmsize == 16 && %2 == 8
-    movhps           m4, [dst8q]
-%endif
-%elifdef m8
-    SWAP              4, 8
-%else
-    mova             m4, m_q0backup
-%endif
-    mova             m1, m4
-    SWAP              1, 4
-    mova             m7, m5
-    SWAP              7, 5
-    psubusb          m1, m5          ; q0-q1
-    psubusb          m7, m4          ; q1-q0
-    por              m1, m7          ; abs(q1-q0)
-%if notcpuflag(mmxext)
-    mova             m7, m1
-    psubusb          m1, m6
-    psubusb          m7, m_hevthr
-    pxor             m6, m6
-    pcmpeqb          m1, m6          ; abs(q1-q0) <= I
-    pcmpeqb          m7, m6          ; abs(q1-q0) <= hev_thresh
-    mova             m6, m_maskres
-    pand             m0, m1          ; abs([pq][321]-[pq][210]) <= I
-    pand             m6, m7
-%else ; mmxext/sse2
-    pxor             m7, m7
-    pmaxub           m0, m1
-    pmaxub           m6, m1
-    psubusb          m0, m_flimI
-    psubusb          m6, m_hevthr
-    pcmpeqb          m0, m7          ; max(abs(..)) <= I
-    pcmpeqb          m6, m7          ; !(max(abs..) > thresh)
-%endif
-%ifdef m12
-    SWAP              6, 12
-%else
-    mova      m_maskres, m6          ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
-%endif
-
-    ; simple_limit
-    mova             m1, m3
-    SWAP              1, 3
-    mova             m6, m4          ; keep copies of p0/q0 around for later use
-    SWAP              6, 4
-    psubusb          m1, m4          ; p0-q0
-    psubusb          m6, m3          ; q0-p0
-    por              m1, m6          ; abs(q0-p0)
-    paddusb          m1, m1          ; m1=2*abs(q0-p0)
-
-    mova             m7, m2
-    SWAP              7, 2
-    mova             m6, m5
-    SWAP              6, 5
-    psubusb          m7, m5          ; p1-q1
-    psubusb          m6, m2          ; q1-p1
-    por              m7, m6          ; abs(q1-p1)
-    pxor             m6, m6
-    pand             m7, [pb_FE]
-    psrlq            m7, 1           ; abs(q1-p1)/2
-    paddusb          m7, m1          ; abs(q0-p0)*2+abs(q1-p1)/2
-    psubusb          m7, m_flimE
-    pcmpeqb          m7, m6          ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
-    pand             m0, m7          ; normal_limit result
-
-    ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
-%ifdef m8 ; x86-64 && sse2
-    mova             m8, [pb_80]
-%define m_pb_80 m8
-%else ; x86-32 or mmx/mmxext
-%define m_pb_80 [pb_80]
-%endif
-    mova             m1, m4
-    mova             m7, m3
-    pxor             m1, m_pb_80
-    pxor             m7, m_pb_80
-    psubsb           m1, m7          ; (signed) q0-p0
-    mova             m6, m2
-    mova             m7, m5
-    pxor             m6, m_pb_80
-    pxor             m7, m_pb_80
-    psubsb           m6, m7          ; (signed) p1-q1
-    mova             m7, m_maskres
-    pandn            m7, m6
-    paddsb           m7, m1
-    paddsb           m7, m1
-    paddsb           m7, m1          ; 3*(q0-p0)+is4tap?(p1-q1)
-
-    pand             m7, m0
-    mova             m1, [pb_F8]
-    mova             m6, m7
-    paddsb           m7, [pb_3]
-    paddsb           m6, [pb_4]
-    pand             m7, m1
-    pand             m6, m1
-
-    pxor             m1, m1
-    pxor             m0, m0
-    pcmpgtb          m1, m7
-    psubb            m0, m7
-    psrlq            m7, 3           ; +f2
-    psrlq            m0, 3           ; -f2
-    pand             m0, m1
-    pandn            m1, m7
-    psubusb          m3, m0
-    paddusb          m3, m1          ; p0+f2
-
-    pxor             m1, m1
-    pxor             m0, m0
-    pcmpgtb          m0, m6
-    psubb            m1, m6
-    psrlq            m6, 3           ; +f1
-    psrlq            m1, 3           ; -f1
-    pand             m1, m0
-    pandn            m0, m6
-    psubusb          m4, m0
-    paddusb          m4, m1          ; q0-f1
-
-%ifdef m12
-    SWAP              6, 12
-%else
-    mova             m6, m_maskres
-%endif
-%if notcpuflag(mmxext)
-    mova             m7, [pb_1]
-%else ; mmxext/sse2
-    pxor             m7, m7
-%endif
-    pand             m0, m6
-    pand             m1, m6
-%if notcpuflag(mmxext)
-    paddusb          m0, m7
-    pand             m1, [pb_FE]
-    pandn            m7, m0
-    psrlq            m1, 1
-    psrlq            m7, 1
-    SWAP              0, 7
-%else ; mmxext/sse2
-    psubusb          m1, [pb_1]
-    pavgb            m0, m7          ; a
-    pavgb            m1, m7          ; -a
-%endif
-    psubusb          m5, m0
-    psubusb          m2, m1
-    paddusb          m5, m1          ; q1-a
-    paddusb          m2, m0          ; p1+a
-
-    ; store
-%ifidn %1, v
-    movrow [dst1q+mstrideq*2], m2
-    movrow [dst1q+mstrideq  ], m3
-    movrow      [dst1q], m4
-    movrow [dst1q+ strideq  ], m5
-%if mmsize == 16 && %2 == 8
-    movhps [dst8q+mstrideq*2], m2
-    movhps [dst8q+mstrideq  ], m3
-    movhps      [dst8q], m4
-    movhps [dst8q+ strideq  ], m5
-%endif
-%else ; h
-    add           dst1q, 2
-    add           dst2q, 2
-
-    ; 4x8/16 transpose
-    TRANSPOSE4x4B     2, 3, 4, 5, 6
-
-%if mmsize == 8 ; mmx/mmxext (h)
-    WRITE_4x2D        2, 3, 4, 5, dst1q, dst2q, mstrideq, strideq
-%else ; sse2 (h)
-    lea           dst8q, [dst8q+mstrideq  +2]
-    WRITE_4x4D        2, 3, 4, 5, dst1q, dst2q, dst8q, mstrideq, strideq, %2
-%endif
-%endif
-
-%if mmsize == 8
-%if %2 == 8 ; chroma
-%ifidn %1, h
-    sub           dst1q, 2
-%endif
-    cmp           dst1q, dst8q
-    mov           dst1q, dst8q
-    jnz .next8px
-%else
-%ifidn %1, h
-    lea           dst1q, [dst1q+ strideq*8-2]
-%else ; v
-    add           dst1q, 8
-%endif
-    dec           cntrq
-    jg .next8px
-%endif
-    REP_RET
-%else ; mmsize == 16
-    RET
-%endif
-%endmacro
-
-%if ARCH_X86_32
-INIT_MMX mmx
-INNER_LOOPFILTER v, 16
-INNER_LOOPFILTER h, 16
-INNER_LOOPFILTER v,  8
-INNER_LOOPFILTER h,  8
-
-INIT_MMX mmxext
-INNER_LOOPFILTER v, 16
-INNER_LOOPFILTER h, 16
-INNER_LOOPFILTER v,  8
-INNER_LOOPFILTER h,  8
-%endif
-
-INIT_XMM sse2
-INNER_LOOPFILTER v, 16
-INNER_LOOPFILTER h, 16
-INNER_LOOPFILTER v,  8
-INNER_LOOPFILTER h,  8
-
-INIT_XMM ssse3
-INNER_LOOPFILTER v, 16
-INNER_LOOPFILTER h, 16
-INNER_LOOPFILTER v,  8
-INNER_LOOPFILTER h,  8
-
-;-----------------------------------------------------------------------------
-; void vp8_h/v_loop_filter<size>_mbedge_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
-;                                            int flimE, int flimI, int hev_thr);
-;-----------------------------------------------------------------------------
-
-%macro MBEDGE_LOOPFILTER 2
-%define stack_size 0
-%ifndef m8       ; stack layout: [0]=E, [1]=I, [2]=hev_thr
-%if mmsize == 16 ;               [3]=hev() result
-                 ;               [4]=filter tmp result
-                 ;               [5]/[6] = p2/q2 backup
-                 ;               [7]=lim_res sign result
-%define stack_size mmsize * -7
-%else ; 8        ; extra storage space for transposes
-%define stack_size mmsize * -8
-%endif
-%endif
-
-%if %2 == 8 ; chroma
-cglobal vp8_%1_loop_filter8uv_mbedge, 6, 6, 15, stack_size, dst1, dst8, stride, flimE, flimI, hevthr
-%else ; luma
-cglobal vp8_%1_loop_filter16y_mbedge, 5, 5, 15, stack_size, dst1, stride, flimE, flimI, hevthr
-%endif
-
-%if cpuflag(ssse3)
-    pxor             m7, m7
-%endif
-
-%ifndef m8
-    ; splat function arguments
-    SPLATB_REG       m0, flimEq, m7   ; E
-    SPLATB_REG       m1, flimIq, m7   ; I
-    SPLATB_REG       m2, hevthrq, m7  ; hev_thresh
-
-%define m_flimE    [rsp]
-%define m_flimI    [rsp+mmsize]
-%define m_hevthr   [rsp+mmsize*2]
-%define m_maskres  [rsp+mmsize*3]
-%define m_limres   [rsp+mmsize*4]
-%define m_p0backup [rsp+mmsize*3]
-%define m_q0backup [rsp+mmsize*4]
-%define m_p2backup [rsp+mmsize*5]
-%define m_q2backup [rsp+mmsize*6]
-%if mmsize == 16
-%define m_limsign  [rsp]
-%else
-%define m_limsign  [rsp+mmsize*7]
-%endif
-
-    mova        m_flimE, m0
-    mova        m_flimI, m1
-    mova       m_hevthr, m2
-%else ; sse2 on x86-64
-%define m_flimE    m9
-%define m_flimI    m10
-%define m_hevthr   m11
-%define m_maskres  m12
-%define m_limres   m8
-%define m_p0backup m12
-%define m_q0backup m8
-%define m_p2backup m13
-%define m_q2backup m14
-%define m_limsign  m9
-
-    ; splat function arguments
-    SPLATB_REG  m_flimE, flimEq, m7   ; E
-    SPLATB_REG  m_flimI, flimIq, m7   ; I
-    SPLATB_REG m_hevthr, hevthrq, m7  ; hev_thresh
-%endif
-
-%if %2 == 8 ; chroma
-    DEFINE_ARGS dst1, dst8, mstride, stride, dst2
-%elif mmsize == 8
-    DEFINE_ARGS dst1, mstride, stride, dst2, cntr
-    mov           cntrq, 2
-%else
-    DEFINE_ARGS dst1, mstride, stride, dst2, dst8
-%endif
-    mov         strideq, mstrideq
-    neg        mstrideq
-%ifidn %1, h
-    lea           dst1q, [dst1q+strideq*4-4]
-%if %2 == 8 ; chroma
-    lea           dst8q, [dst8q+strideq*4-4]
-%endif
-%endif
-
-%if mmsize == 8
-.next8px:
-%endif
-    ; read
-    lea           dst2q, [dst1q+ strideq  ]
-%ifidn %1, v
-%if %2 == 8 && mmsize == 16
-%define movrow movh
-%else
-%define movrow mova
-%endif
-    movrow           m0, [dst1q+mstrideq*4] ; p3
-    movrow           m1, [dst2q+mstrideq*4] ; p2
-    movrow           m2, [dst1q+mstrideq*2] ; p1
-    movrow           m5, [dst2q]            ; q1
-    movrow           m6, [dst2q+ strideq  ] ; q2
-    movrow           m7, [dst2q+ strideq*2] ; q3
-%if mmsize == 16 && %2 == 8
-    movhps           m0, [dst8q+mstrideq*4]
-    movhps           m2, [dst8q+mstrideq*2]
-    add           dst8q, strideq
-    movhps           m1, [dst8q+mstrideq*4]
-    movhps           m5, [dst8q]
-    movhps           m6, [dst8q+ strideq  ]
-    movhps           m7, [dst8q+ strideq*2]
-    add           dst8q, mstrideq
-%endif
-%elif mmsize == 8 ; mmx/mmxext (h)
-    ; read 8 rows of 8px each
-    movu             m0, [dst1q+mstrideq*4]
-    movu             m1, [dst2q+mstrideq*4]
-    movu             m2, [dst1q+mstrideq*2]
-    movu             m3, [dst1q+mstrideq  ]
-    movu             m4, [dst1q]
-    movu             m5, [dst2q]
-    movu             m6, [dst2q+ strideq  ]
-
-    ; 8x8 transpose
-    TRANSPOSE4x4B     0, 1, 2, 3, 7
-    mova     m_q0backup, m1
-    movu             m7, [dst2q+ strideq*2]
-    TRANSPOSE4x4B     4, 5, 6, 7, 1
-    SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
-    SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
-    SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
-    mova             m1, m_q0backup
-    mova     m_q0backup, m2          ; store q0
-    SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
-    mova     m_p0backup, m5          ; store p0
-    SWAP              1, 4
-    SWAP              2, 4
-    SWAP              6, 3
-    SWAP              5, 3
-%else ; sse2 (h)
-%if %2 == 16
-    lea           dst8q, [dst1q+ strideq*8  ]
-%endif
-
-    ; read 16 rows of 8px each, interleave
-    movh             m0, [dst1q+mstrideq*4]
-    movh             m1, [dst8q+mstrideq*4]
-    movh             m2, [dst1q+mstrideq*2]
-    movh             m5, [dst8q+mstrideq*2]
-    movh             m3, [dst1q+mstrideq  ]
-    movh             m6, [dst8q+mstrideq  ]
-    movh             m4, [dst1q]
-    movh             m7, [dst8q]
-    punpcklbw        m0, m1          ; A/I
-    punpcklbw        m2, m5          ; C/K
-    punpcklbw        m3, m6          ; D/L
-    punpcklbw        m4, m7          ; E/M
-
-    add           dst8q, strideq
-    movh             m1, [dst2q+mstrideq*4]
-    movh             m6, [dst8q+mstrideq*4]
-    movh             m5, [dst2q]
-    movh             m7, [dst8q]
-    punpcklbw        m1, m6          ; B/J
-    punpcklbw        m5, m7          ; F/N
-    movh             m6, [dst2q+ strideq  ]
-    movh             m7, [dst8q+ strideq  ]
-    punpcklbw        m6, m7          ; G/O
-
-    ; 8x16 transpose
-    TRANSPOSE4x4B     0, 1, 2, 3, 7
-%ifdef m8
-    SWAP              1, 8
-%else
-    mova     m_q0backup, m1
-%endif
-    movh             m7, [dst2q+ strideq*2]
-    movh             m1, [dst8q+ strideq*2]
-    punpcklbw        m7, m1          ; H/P
-    TRANSPOSE4x4B     4, 5, 6, 7, 1
-    SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
-    SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
-    SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
-%ifdef m8
-    SWAP              1, 8
-    SWAP              2, 8
-%else
-    mova             m1, m_q0backup
-    mova     m_q0backup, m2          ; store q0
-%endif
-    SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
-%ifdef m12
-    SWAP              5, 12
-%else
-    mova     m_p0backup, m5          ; store p0
-%endif
-    SWAP              1, 4
-    SWAP              2, 4
-    SWAP              6, 3
-    SWAP              5, 3
-%endif
-
-    ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
-    mova             m4, m1
-    SWAP              4, 1
-    psubusb          m4, m0          ; p2-p3
-    psubusb          m0, m1          ; p3-p2
-    por              m0, m4          ; abs(p3-p2)
-
-    mova             m4, m2
-    SWAP              4, 2
-    psubusb          m4, m1          ; p1-p2
-    mova     m_p2backup, m1
-    psubusb          m1, m2          ; p2-p1
-    por              m1, m4          ; abs(p2-p1)
-
-    mova             m4, m6
-    SWAP              4, 6
-    psubusb          m4, m7          ; q2-q3
-    psubusb          m7, m6          ; q3-q2
-    por              m7, m4          ; abs(q3-q2)
-
-    mova             m4, m5
-    SWAP              4, 5
-    psubusb          m4, m6          ; q1-q2
-    mova     m_q2backup, m6
-    psubusb          m6, m5          ; q2-q1
-    por              m6, m4          ; abs(q2-q1)
-
-%if notcpuflag(mmxext)
-    mova             m4, m_flimI
-    pxor             m3, m3
-    psubusb          m0, m4
-    psubusb          m1, m4
-    psubusb          m7, m4
-    psubusb          m6, m4
-    pcmpeqb          m0, m3          ; abs(p3-p2) <= I
-    pcmpeqb          m1, m3          ; abs(p2-p1) <= I
-    pcmpeqb          m7, m3          ; abs(q3-q2) <= I
-    pcmpeqb          m6, m3          ; abs(q2-q1) <= I
-    pand             m0, m1
-    pand             m7, m6
-    pand             m0, m7
-%else ; mmxext/sse2
-    pmaxub           m0, m1
-    pmaxub           m6, m7
-    pmaxub           m0, m6
-%endif
-
-    ; normal_limit and high_edge_variance for p1-p0, q1-q0
-    SWAP              7, 3           ; now m7 is zero
-%ifidn %1, v
-    movrow           m3, [dst1q+mstrideq  ] ; p0
-%if mmsize == 16 && %2 == 8
-    movhps           m3, [dst8q+mstrideq  ]
-%endif
-%elifdef m12
-    SWAP              3, 12
-%else
-    mova             m3, m_p0backup
-%endif
-
-    mova             m1, m2
-    SWAP              1, 2
-    mova             m6, m3
-    SWAP              3, 6
-    psubusb          m1, m3          ; p1-p0
-    psubusb          m6, m2          ; p0-p1
-    por              m1, m6          ; abs(p1-p0)
-%if notcpuflag(mmxext)
-    mova             m6, m1
-    psubusb          m1, m4
-    psubusb          m6, m_hevthr
-    pcmpeqb          m1, m7          ; abs(p1-p0) <= I
-    pcmpeqb          m6, m7          ; abs(p1-p0) <= hev_thresh
-    pand             m0, m1
-    mova      m_maskres, m6
-%else ; mmxext/sse2
-    pmaxub           m0, m1          ; max_I
-    SWAP              1, 4           ; max_hev_thresh
-%endif
-
-    SWAP              6, 4           ; now m6 is I
-%ifidn %1, v
-    movrow           m4, [dst1q]     ; q0
-%if mmsize == 16 && %2 == 8
-    movhps           m4, [dst8q]
-%endif
-%elifdef m8
-    SWAP              4, 8
-%else
-    mova             m4, m_q0backup
-%endif
-    mova             m1, m4
-    SWAP              1, 4
-    mova             m7, m5
-    SWAP              7, 5
-    psubusb          m1, m5          ; q0-q1
-    psubusb          m7, m4          ; q1-q0
-    por              m1, m7          ; abs(q1-q0)
-%if notcpuflag(mmxext)
-    mova             m7, m1
-    psubusb          m1, m6
-    psubusb          m7, m_hevthr
-    pxor             m6, m6
-    pcmpeqb          m1, m6          ; abs(q1-q0) <= I
-    pcmpeqb          m7, m6          ; abs(q1-q0) <= hev_thresh
-    mova             m6, m_maskres
-    pand             m0, m1          ; abs([pq][321]-[pq][210]) <= I
-    pand             m6, m7
-%else ; mmxext/sse2
-    pxor             m7, m7
-    pmaxub           m0, m1
-    pmaxub           m6, m1
-    psubusb          m0, m_flimI
-    psubusb          m6, m_hevthr
-    pcmpeqb          m0, m7          ; max(abs(..)) <= I
-    pcmpeqb          m6, m7          ; !(max(abs..) > thresh)
-%endif
-%ifdef m12
-    SWAP              6, 12
-%else
-    mova      m_maskres, m6          ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
-%endif
-
-    ; simple_limit
-    mova             m1, m3
-    SWAP              1, 3
-    mova             m6, m4          ; keep copies of p0/q0 around for later use
-    SWAP              6, 4
-    psubusb          m1, m4          ; p0-q0
-    psubusb          m6, m3          ; q0-p0
-    por              m1, m6          ; abs(q0-p0)
-    paddusb          m1, m1          ; m1=2*abs(q0-p0)
-
-    mova             m7, m2
-    SWAP              7, 2
-    mova             m6, m5
-    SWAP              6, 5
-    psubusb          m7, m5          ; p1-q1
-    psubusb          m6, m2          ; q1-p1
-    por              m7, m6          ; abs(q1-p1)
-    pxor             m6, m6
-    pand             m7, [pb_FE]
-    psrlq            m7, 1           ; abs(q1-p1)/2
-    paddusb          m7, m1          ; abs(q0-p0)*2+abs(q1-p1)/2
-    psubusb          m7, m_flimE
-    pcmpeqb          m7, m6          ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
-    pand             m0, m7          ; normal_limit result
-
-    ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
-%ifdef m8 ; x86-64 && sse2
-    mova             m8, [pb_80]
-%define m_pb_80 m8
-%else ; x86-32 or mmx/mmxext
-%define m_pb_80 [pb_80]
-%endif
-    mova             m1, m4
-    mova             m7, m3
-    pxor             m1, m_pb_80
-    pxor             m7, m_pb_80
-    psubsb           m1, m7          ; (signed) q0-p0
-    mova             m6, m2
-    mova             m7, m5
-    pxor             m6, m_pb_80
-    pxor             m7, m_pb_80
-    psubsb           m6, m7          ; (signed) p1-q1
-    mova             m7, m_maskres
-    paddsb           m6, m1
-    paddsb           m6, m1
-    paddsb           m6, m1
-    pand             m6, m0
-%ifdef m8
-    mova       m_limres, m6          ; 3*(qp-p0)+(p1-q1) masked for filter_mbedge
-    pand       m_limres, m7
-%else
-    mova             m0, m6
-    pand             m0, m7
-    mova       m_limres, m0
-%endif
-    pandn            m7, m6          ; 3*(q0-p0)+(p1-q1) masked for filter_common
-
-    mova             m1, [pb_F8]
-    mova             m6, m7
-    paddsb           m7, [pb_3]
-    paddsb           m6, [pb_4]
-    pand             m7, m1
-    pand             m6, m1
-
-    pxor             m1, m1
-    pxor             m0, m0
-    pcmpgtb          m1, m7
-    psubb            m0, m7
-    psrlq            m7, 3           ; +f2
-    psrlq            m0, 3           ; -f2
-    pand             m0, m1
-    pandn            m1, m7
-    psubusb          m3, m0
-    paddusb          m3, m1          ; p0+f2
-
-    pxor             m1, m1
-    pxor             m0, m0
-    pcmpgtb          m0, m6
-    psubb            m1, m6
-    psrlq            m6, 3           ; +f1
-    psrlq            m1, 3           ; -f1
-    pand             m1, m0
-    pandn            m0, m6
-    psubusb          m4, m0
-    paddusb          m4, m1          ; q0-f1
-
-    ; filter_mbedge (m2-m5 = p1-q1; lim_res carries w)
-%if cpuflag(ssse3)
-    mova             m7, [pb_1]
-%else
-    mova             m7, [pw_63]
-%endif
-%ifdef m8
-    SWAP              1, 8
-%else
-    mova             m1, m_limres
-%endif
-    pxor             m0, m0
-    mova             m6, m1
-    pcmpgtb          m0, m1         ; which are negative
-%if cpuflag(ssse3)
-    punpcklbw        m6, m7         ; interleave with "1" for rounding
-    punpckhbw        m1, m7
-%else
-    punpcklbw        m6, m0         ; signed byte->word
-    punpckhbw        m1, m0
-%endif
-    mova      m_limsign, m0
-%if cpuflag(ssse3)
-    mova             m7, [pb_27_63]
-%ifndef m8
-    mova       m_limres, m1
-%endif
-%ifdef m10
-    SWAP              0, 10         ; don't lose lim_sign copy
-%endif
-    mova             m0, m7
-    pmaddubsw        m7, m6
-    SWAP              6, 7
-    pmaddubsw        m0, m1
-    SWAP              1, 0
-%ifdef m10
-    SWAP              0, 10
-%else
-    mova             m0, m_limsign
-%endif
-%else
-    mova      m_maskres, m6         ; backup for later in filter
-    mova       m_limres, m1
-    pmullw          m6, [pw_27]
-    pmullw          m1, [pw_27]
-    paddw           m6, m7
-    paddw           m1, m7
-%endif
-    psraw           m6, 7
-    psraw           m1, 7
-    packsswb        m6, m1          ; a0
-    pxor            m1, m1
-    psubb           m1, m6
-    pand            m1, m0          ; -a0
-    pandn           m0, m6          ; +a0
-%if cpuflag(ssse3)
-    mova            m6, [pb_18_63]  ; pipelining
-%endif
-    psubusb         m3, m1
-    paddusb         m4, m1
-    paddusb         m3, m0          ; p0+a0
-    psubusb         m4, m0          ; q0-a0
-
-%if cpuflag(ssse3)
-    SWAP             6, 7
-%ifdef m10
-    SWAP             1, 10
-%else
-    mova            m1, m_limres
-%endif
-    mova            m0, m7
-    pmaddubsw       m7, m6
-    SWAP             6, 7
-    pmaddubsw       m0, m1
-    SWAP             1, 0
-%ifdef m10
-    SWAP             0, 10
-%endif
-    mova            m0, m_limsign
-%else
-    mova            m6, m_maskres
-    mova            m1, m_limres
-    pmullw          m6, [pw_18]
-    pmullw          m1, [pw_18]
-    paddw           m6, m7
-    paddw           m1, m7
-%endif
-    mova            m0, m_limsign
-    psraw           m6, 7
-    psraw           m1, 7
-    packsswb        m6, m1          ; a1
-    pxor            m1, m1
-    psubb           m1, m6
-    pand            m1, m0          ; -a1
-    pandn           m0, m6          ; +a1
-%if cpuflag(ssse3)
-    mova            m6, [pb_9_63]
-%endif
-    psubusb         m2, m1
-    paddusb         m5, m1
-    paddusb         m2, m0          ; p1+a1
-    psubusb         m5, m0          ; q1-a1
-
-%if cpuflag(ssse3)
-    SWAP             6, 7
-%ifdef m10
-    SWAP             1, 10
-%else
-    mova            m1, m_limres
-%endif
-    mova            m0, m7
-    pmaddubsw       m7, m6
-    SWAP             6, 7
-    pmaddubsw       m0, m1
-    SWAP             1, 0
-%else
-%ifdef m8
-    SWAP             6, 12
-    SWAP             1, 8
-%else
-    mova            m6, m_maskres
-    mova            m1, m_limres
-%endif
-    pmullw          m6, [pw_9]
-    pmullw          m1, [pw_9]
-    paddw           m6, m7
-    paddw           m1, m7
-%endif
-%ifdef m9
-    SWAP             7, 9
-%else
-    mova            m7, m_limsign
-%endif
-    psraw           m6, 7
-    psraw           m1, 7
-    packsswb        m6, m1          ; a1
-    pxor            m0, m0
-    psubb           m0, m6
-    pand            m0, m7          ; -a1
-    pandn           m7, m6          ; +a1
-%ifdef m8
-    SWAP             1, 13
-    SWAP             6, 14
-%else
-    mova            m1, m_p2backup
-    mova            m6, m_q2backup
-%endif
-    psubusb         m1, m0
-    paddusb         m6, m0
-    paddusb         m1, m7          ; p1+a1
-    psubusb         m6, m7          ; q1-a1
-
-    ; store
-%ifidn %1, v
-    movrow [dst2q+mstrideq*4], m1
-    movrow [dst1q+mstrideq*2], m2
-    movrow [dst1q+mstrideq  ], m3
-    movrow     [dst1q], m4
-    movrow     [dst2q], m5
-    movrow [dst2q+ strideq  ], m6
-%if mmsize == 16 && %2 == 8
-    add           dst8q, mstrideq
-    movhps [dst8q+mstrideq*2], m1
-    movhps [dst8q+mstrideq  ], m2
-    movhps     [dst8q], m3
-    add          dst8q, strideq
-    movhps     [dst8q], m4
-    movhps [dst8q+ strideq  ], m5
-    movhps [dst8q+ strideq*2], m6
-%endif
-%else ; h
-    inc          dst1q
-    inc          dst2q
-
-    ; 4x8/16 transpose
-    TRANSPOSE4x4B    1, 2, 3, 4, 0
-    SBUTTERFLY      bw, 5, 6, 0
-
-%if mmsize == 8 ; mmx/mmxext (h)
-    WRITE_4x2D       1, 2, 3, 4, dst1q, dst2q, mstrideq, strideq
-    add          dst1q, 4
-    WRITE_2x4W      m5, m6, dst2q, dst1q, mstrideq, strideq
-%else ; sse2 (h)
-    lea          dst8q, [dst8q+mstrideq+1]
-    WRITE_4x4D       1, 2, 3, 4, dst1q, dst2q, dst8q, mstrideq, strideq, %2
-    lea          dst1q, [dst2q+mstrideq+4]
-    lea          dst8q, [dst8q+mstrideq+4]
-%if cpuflag(sse4)
-    add          dst2q, 4
-%endif
-    WRITE_8W        m5, dst2q, dst1q,  mstrideq, strideq
-%if cpuflag(sse4)
-    lea          dst2q, [dst8q+ strideq  ]
-%endif
-    WRITE_8W        m6, dst2q, dst8q, mstrideq, strideq
-%endif
-%endif
-
-%if mmsize == 8
-%if %2 == 8 ; chroma
-%ifidn %1, h
-    sub          dst1q, 5
-%endif
-    cmp          dst1q, dst8q
-    mov          dst1q, dst8q
-    jnz .next8px
-%else
-%ifidn %1, h
-    lea          dst1q, [dst1q+ strideq*8-5]
-%else ; v
-    add          dst1q, 8
-%endif
-    dec          cntrq
-    jg .next8px
-%endif
-    REP_RET
-%else ; mmsize == 16
-    RET
-%endif
-%endmacro
-
-%if ARCH_X86_32
-INIT_MMX mmx
-MBEDGE_LOOPFILTER v, 16
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER v,  8
-MBEDGE_LOOPFILTER h,  8
-
-INIT_MMX mmxext
-MBEDGE_LOOPFILTER v, 16
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER v,  8
-MBEDGE_LOOPFILTER h,  8
-%endif
-
-INIT_XMM sse2
-MBEDGE_LOOPFILTER v, 16
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER v,  8
-MBEDGE_LOOPFILTER h,  8
-
-INIT_XMM ssse3
-MBEDGE_LOOPFILTER v, 16
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER v,  8
-MBEDGE_LOOPFILTER h,  8
-
-INIT_XMM sse4
-MBEDGE_LOOPFILTER h, 16
-MBEDGE_LOOPFILTER h,  8
diff --git a/libavcodec/x86/vp8dsp_init.c b/libavcodec/x86/vp8dsp_init.c
index a9d3541..6d06666 100644
--- a/libavcodec/x86/vp8dsp_init.c
+++ b/libavcodec/x86/vp8dsp_init.c
@@ -23,6 +23,7 @@
 #include "libavutil/cpu.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
 #include "libavcodec/vp8dsp.h"
 
 #if HAVE_YASM
@@ -30,93 +31,93 @@
 /*
  * MC functions
  */
-extern void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-
-extern void ff_put_vp8_epel8_h4_sse2  (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel8_h6_sse2  (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel8_v4_sse2  (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel8_v6_sse2  (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-
-extern void ff_put_vp8_epel4_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel4_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel4_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel4_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-extern void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                       uint8_t *src, ptrdiff_t srcstride,
-                                       int height, int mx, int my);
-
-extern void ff_put_vp8_bilinear4_h_mmxext(uint8_t *dst, ptrdiff_t dststride,
-                                          uint8_t *src, ptrdiff_t srcstride,
-                                          int height, int mx, int my);
-extern void ff_put_vp8_bilinear8_h_sse2  (uint8_t *dst, ptrdiff_t dststride,
-                                          uint8_t *src, ptrdiff_t srcstride,
-                                          int height, int mx, int my);
-extern void ff_put_vp8_bilinear4_h_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                          uint8_t *src, ptrdiff_t srcstride,
-                                          int height, int mx, int my);
-extern void ff_put_vp8_bilinear8_h_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                          uint8_t *src, ptrdiff_t srcstride,
-                                          int height, int mx, int my);
-
-extern void ff_put_vp8_bilinear4_v_mmxext(uint8_t *dst, ptrdiff_t dststride,
-                                          uint8_t *src, ptrdiff_t srcstride,
-                                          int height, int mx, int my);
-extern void ff_put_vp8_bilinear8_v_sse2  (uint8_t *dst, ptrdiff_t dststride,
-                                          uint8_t *src, ptrdiff_t srcstride,
-                                          int height, int mx, int my);
-extern void ff_put_vp8_bilinear4_v_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                          uint8_t *src, ptrdiff_t srcstride,
-                                          int height, int mx, int my);
-extern void ff_put_vp8_bilinear8_v_ssse3 (uint8_t *dst, ptrdiff_t dststride,
-                                          uint8_t *src, ptrdiff_t srcstride,
-                                          int height, int mx, int my);
-
-
-extern void ff_put_vp8_pixels8_mmx (uint8_t *dst, ptrdiff_t dststride,
-                                    uint8_t *src, ptrdiff_t srcstride,
-                                    int height, int mx, int my);
-extern void ff_put_vp8_pixels16_mmx(uint8_t *dst, ptrdiff_t dststride,
-                                    uint8_t *src, ptrdiff_t srcstride,
-                                    int height, int mx, int my);
-extern void ff_put_vp8_pixels16_sse(uint8_t *dst, ptrdiff_t dststride,
-                                    uint8_t *src, ptrdiff_t srcstride,
-                                    int height, int mx, int my);
+void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+
+void ff_put_vp8_epel8_h4_sse2  (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel8_h6_sse2  (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel8_v4_sse2  (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel8_v6_sse2  (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+
+void ff_put_vp8_epel4_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel4_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel4_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel4_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                uint8_t *src, ptrdiff_t srcstride,
+                                int height, int mx, int my);
+
+void ff_put_vp8_bilinear4_h_mmxext(uint8_t *dst, ptrdiff_t dststride,
+                                   uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int mx, int my);
+void ff_put_vp8_bilinear8_h_sse2  (uint8_t *dst, ptrdiff_t dststride,
+                                   uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int mx, int my);
+void ff_put_vp8_bilinear4_h_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                   uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int mx, int my);
+void ff_put_vp8_bilinear8_h_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                   uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int mx, int my);
+
+void ff_put_vp8_bilinear4_v_mmxext(uint8_t *dst, ptrdiff_t dststride,
+                                   uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int mx, int my);
+void ff_put_vp8_bilinear8_v_sse2  (uint8_t *dst, ptrdiff_t dststride,
+                                   uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int mx, int my);
+void ff_put_vp8_bilinear4_v_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                   uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int mx, int my);
+void ff_put_vp8_bilinear8_v_ssse3 (uint8_t *dst, ptrdiff_t dststride,
+                                   uint8_t *src, ptrdiff_t srcstride,
+                                   int height, int mx, int my);
+
+
+void ff_put_vp8_pixels8_mmx (uint8_t *dst, ptrdiff_t dststride,
+                             uint8_t *src, ptrdiff_t srcstride,
+                             int height, int mx, int my);
+void ff_put_vp8_pixels16_mmx(uint8_t *dst, ptrdiff_t dststride,
+                             uint8_t *src, ptrdiff_t srcstride,
+                             int height, int mx, int my);
+void ff_put_vp8_pixels16_sse(uint8_t *dst, ptrdiff_t dststride,
+                             uint8_t *src, ptrdiff_t srcstride,
+                             int height, int mx, int my);
 
 #define TAP_W16(OPT, FILTERTYPE, TAPTYPE) \
 static void ff_put_vp8_ ## FILTERTYPE ## 16_ ## TAPTYPE ## _ ## OPT( \
@@ -230,58 +231,56 @@ HVBILIN(ssse3, 8,  4,  8)
 HVBILIN(ssse3, 8,  8, 16)
 HVBILIN(ssse3, 8, 16, 16)
 
-extern void ff_vp8_idct_dc_add_mmx(uint8_t *dst, DCTELEM block[16],
-                                   ptrdiff_t stride);
-extern void ff_vp8_idct_dc_add_sse4(uint8_t *dst, DCTELEM block[16],
-                                    ptrdiff_t stride);
-extern void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, DCTELEM block[4][16],
-                                      ptrdiff_t stride);
-extern void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, DCTELEM block[4][16],
-                                      ptrdiff_t stride);
-extern void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, DCTELEM block[2][16],
-                                      ptrdiff_t stride);
-extern void ff_vp8_luma_dc_wht_mmx(DCTELEM block[4][4][16], DCTELEM dc[16]);
-extern void ff_vp8_luma_dc_wht_sse(DCTELEM block[4][4][16], DCTELEM dc[16]);
-extern void ff_vp8_idct_add_mmx(uint8_t *dst, DCTELEM block[16],
-                                ptrdiff_t stride);
-extern void ff_vp8_idct_add_sse(uint8_t *dst, DCTELEM block[16],
-                                ptrdiff_t stride);
-
-#define DECLARE_LOOP_FILTER(NAME)\
-extern void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst, \
-                                                 ptrdiff_t stride, \
-                                                 int flim);\
-extern void ff_vp8_h_loop_filter_simple_ ## NAME(uint8_t *dst, \
-                                                 ptrdiff_t stride, \
-                                                 int flim);\
-extern void ff_vp8_v_loop_filter16y_inner_ ## NAME (uint8_t *dst, \
-                                                     ptrdiff_t stride,\
-                                                    int e, int i, int hvt);\
-extern void ff_vp8_h_loop_filter16y_inner_ ## NAME (uint8_t *dst, \
-                                                    ptrdiff_t stride,\
-                                                    int e, int i, int hvt);\
-extern void ff_vp8_v_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \
-                                                    uint8_t *dstV,\
-                                                    ptrdiff_t s, \
-                                                    int e, int i, int hvt);\
-extern void ff_vp8_h_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \
-                                                    uint8_t *dstV,\
-                                                    ptrdiff_t s, \
-                                                    int e, int i, int hvt);\
-extern void ff_vp8_v_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \
-                                                    ptrdiff_t stride,\
-                                                    int e, int i, int hvt);\
-extern void ff_vp8_h_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \
-                                                    ptrdiff_t stride,\
-                                                    int e, int i, int hvt);\
-extern void ff_vp8_v_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \
-                                                    uint8_t *dstV,\
-                                                    ptrdiff_t s, \
-                                                    int e, int i, int hvt);\
-extern void ff_vp8_h_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \
-                                                    uint8_t *dstV,\
-                                                    ptrdiff_t s, \
-                                                    int e, int i, int hvt);
+void ff_vp8_idct_dc_add_mmx(uint8_t *dst, int16_t block[16],
+                            ptrdiff_t stride);
+void ff_vp8_idct_dc_add_sse4(uint8_t *dst, int16_t block[16],
+                             ptrdiff_t stride);
+void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, int16_t block[4][16],
+                               ptrdiff_t stride);
+void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, int16_t block[4][16],
+                               ptrdiff_t stride);
+void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, int16_t block[2][16],
+                               ptrdiff_t stride);
+void ff_vp8_luma_dc_wht_mmx(int16_t block[4][4][16], int16_t dc[16]);
+void ff_vp8_luma_dc_wht_sse(int16_t block[4][4][16], int16_t dc[16]);
+void ff_vp8_idct_add_mmx(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+void ff_vp8_idct_add_sse(uint8_t *dst, int16_t block[16], ptrdiff_t stride);
+
+#define DECLARE_LOOP_FILTER(NAME)                                       \
+void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst,                 \
+                                          ptrdiff_t stride,             \
+                                          int flim);                    \
+void ff_vp8_h_loop_filter_simple_ ## NAME(uint8_t *dst,                 \
+                                          ptrdiff_t stride,             \
+                                          int flim);                    \
+void ff_vp8_v_loop_filter16y_inner_ ## NAME (uint8_t *dst,              \
+                                             ptrdiff_t stride,          \
+                                             int e, int i, int hvt);    \
+void ff_vp8_h_loop_filter16y_inner_ ## NAME (uint8_t *dst,              \
+                                             ptrdiff_t stride,          \
+                                             int e, int i, int hvt);    \
+void ff_vp8_v_loop_filter8uv_inner_ ## NAME (uint8_t *dstU,             \
+                                             uint8_t *dstV,             \
+                                             ptrdiff_t s,               \
+                                             int e, int i, int hvt);    \
+void ff_vp8_h_loop_filter8uv_inner_ ## NAME (uint8_t *dstU,             \
+                                             uint8_t *dstV,             \
+                                             ptrdiff_t s,               \
+                                             int e, int i, int hvt);    \
+void ff_vp8_v_loop_filter16y_mbedge_ ## NAME(uint8_t *dst,              \
+                                             ptrdiff_t stride,          \
+                                             int e, int i, int hvt);    \
+void ff_vp8_h_loop_filter16y_mbedge_ ## NAME(uint8_t *dst,              \
+                                             ptrdiff_t stride,          \
+                                             int e, int i, int hvt);    \
+void ff_vp8_v_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU,             \
+                                             uint8_t *dstV,             \
+                                             ptrdiff_t s,               \
+                                             int e, int i, int hvt);    \
+void ff_vp8_h_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU,             \
+                                             uint8_t *dstV,             \
+                                             ptrdiff_t s,               \
+                                             int e, int i, int hvt);
 
 DECLARE_LOOP_FILTER(mmx)
 DECLARE_LOOP_FILTER(mmxext)
@@ -318,9 +317,9 @@ DECLARE_LOOP_FILTER(sse4)
 av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (mm_flags & AV_CPU_FLAG_MMX) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         c->vp8_idct_dc_add    = ff_vp8_idct_dc_add_mmx;
         c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx;
 #if ARCH_X86_32
@@ -351,7 +350,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
 
     /* note that 4-tap width=16 functions are missing because w=16
      * is only used for luma, and luma is always a copy or sixtap. */
-    if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+    if (EXTERNAL_MMXEXT(cpu_flags)) {
         VP8_MC_FUNC(2, 4, mmxext);
         VP8_BILINEAR_MC_FUNC(2, 4, mmxext);
 #if ARCH_X86_32
@@ -375,14 +374,14 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
 #endif
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSE) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         c->vp8_idct_add                         = ff_vp8_idct_add_sse;
         c->vp8_luma_dc_wht                      = ff_vp8_luma_dc_wht_sse;
         c->put_vp8_epel_pixels_tab[0][0][0]     =
         c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse;
     }
 
-    if (mm_flags & (AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW)) {
+    if (EXTERNAL_SSE2(cpu_flags) && (cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
         VP8_LUMA_MC_FUNC(0, 16, sse2);
         VP8_MC_FUNC(1, 8, sse2);
         VP8_BILINEAR_MC_FUNC(0, 16, sse2);
@@ -397,7 +396,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
         c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_sse2;
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSE2) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         c->vp8_idct_dc_add4y          = ff_vp8_idct_dc_add4y_sse2;
 
         c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2;
@@ -409,7 +408,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
         c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_sse2;
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSSE3) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         VP8_LUMA_MC_FUNC(0, 16, ssse3);
         VP8_MC_FUNC(1, 8, ssse3);
         VP8_MC_FUNC(2, 4, ssse3);
@@ -431,7 +430,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)
         c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_ssse3;
     }
 
-    if (mm_flags & AV_CPU_FLAG_SSE4) {
+    if (EXTERNAL_SSE4(cpu_flags)) {
         c->vp8_idct_dc_add                  = ff_vp8_idct_dc_add_sse4;
 
         c->vp8_h_loop_filter_simple   = ff_vp8_h_loop_filter_simple_sse4;
diff --git a/libavcodec/x86/vp8dsp_loopfilter.asm b/libavcodec/x86/vp8dsp_loopfilter.asm
new file mode 100644
index 0000000..cbad085
--- /dev/null
+++ b/libavcodec/x86/vp8dsp_loopfilter.asm
@@ -0,0 +1,1584 @@
+;******************************************************************************
+;* VP8 MMXEXT optimizations
+;* Copyright (c) 2010 Ronald S. Bultje <rsbultje at gmail.com>
+;* Copyright (c) 2010 Jason Garrett-Glaser <darkshikari at gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+
+pw_27:    times 8 dw 27
+pw_63:    times 8 dw 63
+
+pb_4:     times 16 db 4
+pb_F8:    times 16 db 0xF8
+pb_FE:    times 16 db 0xFE
+pb_27_63: times 8 db 27, 63
+pb_18_63: times 8 db 18, 63
+pb_9_63:  times 8 db  9, 63
+
+cextern pb_1
+cextern pb_3
+cextern pw_9
+cextern pw_18
+cextern pb_80
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+; void vp8_h/v_loop_filter_simple_<opt>(uint8_t *dst, int stride, int flim);
+;-----------------------------------------------------------------------------
+
+; macro called with 7 mm register indexes as argument, and 4 regular registers
+;
+; first 4 mm registers will carry the transposed pixel data
+; the other three are scratchspace (one would be sufficient, but this allows
+; for more spreading/pipelining and thus faster execution on OOE CPUs)
+;
+; first two regular registers are buf+4*stride and buf+5*stride
+; third is -stride, fourth is +stride
+%macro READ_8x4_INTERLEAVED 11
+    ; interleave 8 (A-H) rows of 4 pixels each
+    movd          m%1, [%8+%10*4]   ; A0-3
+    movd          m%5, [%9+%10*4]   ; B0-3
+    movd          m%2, [%8+%10*2]   ; C0-3
+    movd          m%6, [%8+%10]     ; D0-3
+    movd          m%3, [%8]         ; E0-3
+    movd          m%7, [%9]         ; F0-3
+    movd          m%4, [%9+%11]     ; G0-3
+    punpcklbw     m%1, m%5          ; A/B interleaved
+    movd          m%5, [%9+%11*2]   ; H0-3
+    punpcklbw     m%2, m%6          ; C/D interleaved
+    punpcklbw     m%3, m%7          ; E/F interleaved
+    punpcklbw     m%4, m%5          ; G/H interleaved
+%endmacro
+
+; macro called with 7 mm register indexes as argument, and 5 regular registers
+; first 11 mean the same as READ_8x4_TRANSPOSED above
+; fifth regular register is scratchspace to reach the bottom 8 rows, it
+; will be set to second regular register + 8*stride at the end
+%macro READ_16x4_INTERLEAVED 12
+    ; transpose 16 (A-P) rows of 4 pixels each
+    lea           %12, [r0+8*r2]
+
+    ; read (and interleave) those addressable by %8 (=r0), A/C/D/E/I/K/L/M
+    movd          m%1, [%8+%10*4]   ; A0-3
+    movd          m%3, [%12+%10*4]  ; I0-3
+    movd          m%2, [%8+%10*2]   ; C0-3
+    movd          m%4, [%12+%10*2]  ; K0-3
+    movd          m%6, [%8+%10]     ; D0-3
+    movd          m%5, [%12+%10]    ; L0-3
+    movd          m%7, [%12]        ; M0-3
+    add           %12, %11
+    punpcklbw     m%1, m%3          ; A/I
+    movd          m%3, [%8]         ; E0-3
+    punpcklbw     m%2, m%4          ; C/K
+    punpcklbw     m%6, m%5          ; D/L
+    punpcklbw     m%3, m%7          ; E/M
+    punpcklbw     m%2, m%6          ; C/D/K/L interleaved
+
+    ; read (and interleave) those addressable by %9 (=r4), B/F/G/H/J/N/O/P
+    movd         m%5, [%9+%10*4]   ; B0-3
+    movd         m%4, [%12+%10*4]  ; J0-3
+    movd         m%7, [%9]         ; F0-3
+    movd         m%6, [%12]        ; N0-3
+    punpcklbw    m%5, m%4          ; B/J
+    punpcklbw    m%7, m%6          ; F/N
+    punpcklbw    m%1, m%5          ; A/B/I/J interleaved
+    punpcklbw    m%3, m%7          ; E/F/M/N interleaved
+    movd         m%4, [%9+%11]     ; G0-3
+    movd         m%6, [%12+%11]    ; O0-3
+    movd         m%5, [%9+%11*2]   ; H0-3
+    movd         m%7, [%12+%11*2]  ; P0-3
+    punpcklbw    m%4, m%6          ; G/O
+    punpcklbw    m%5, m%7          ; H/P
+    punpcklbw    m%4, m%5          ; G/H/O/P interleaved
+%endmacro
+
+; write 4 mm registers of 2 dwords each
+; first four arguments are mm register indexes containing source data
+; last four are registers containing buf+4*stride, buf+5*stride,
+; -stride and +stride
+%macro WRITE_4x2D 8
+    ; write out (2 dwords per register)
+    movd    [%5+%7*4], m%1
+    movd    [%5+%7*2], m%2
+    movd         [%5], m%3
+    movd      [%6+%8], m%4
+    punpckhdq     m%1, m%1
+    punpckhdq     m%2, m%2
+    punpckhdq     m%3, m%3
+    punpckhdq     m%4, m%4
+    movd    [%6+%7*4], m%1
+    movd      [%5+%7], m%2
+    movd         [%6], m%3
+    movd    [%6+%8*2], m%4
+%endmacro
+
+; write 4 xmm registers of 4 dwords each
+; arguments same as WRITE_2x4D, but with an extra register, so that the 5 regular
+; registers contain buf+4*stride, buf+5*stride, buf+12*stride, -stride and +stride
+; we add 1*stride to the third regular registry in the process
+; the 10th argument is 16 if it's a Y filter (i.e. all regular registers cover the
+; same memory region), or 8 if they cover two separate buffers (third one points to
+; a different memory region than the first two), allowing for more optimal code for
+; the 16-width case
+%macro WRITE_4x4D 10
+    ; write out (4 dwords per register), start with dwords zero
+    movd    [%5+%8*4], m%1
+    movd         [%5], m%2
+    movd    [%7+%8*4], m%3
+    movd         [%7], m%4
+
+    ; store dwords 1
+    psrldq        m%1, 4
+    psrldq        m%2, 4
+    psrldq        m%3, 4
+    psrldq        m%4, 4
+    movd    [%6+%8*4], m%1
+    movd         [%6], m%2
+%if %10 == 16
+    movd    [%6+%9*4], m%3
+%endif
+    movd      [%7+%9], m%4
+
+    ; write dwords 2
+    psrldq        m%1, 4
+    psrldq        m%2, 4
+%if %10 == 8
+    movd    [%5+%8*2], m%1
+    movd          %5d, m%3
+%endif
+    psrldq        m%3, 4
+    psrldq        m%4, 4
+%if %10 == 16
+    movd    [%5+%8*2], m%1
+%endif
+    movd      [%6+%9], m%2
+    movd    [%7+%8*2], m%3
+    movd    [%7+%9*2], m%4
+    add            %7, %9
+
+    ; store dwords 3
+    psrldq        m%1, 4
+    psrldq        m%2, 4
+    psrldq        m%3, 4
+    psrldq        m%4, 4
+%if %10 == 8
+    mov     [%7+%8*4], %5d
+    movd    [%6+%8*2], m%1
+%else
+    movd      [%5+%8], m%1
+%endif
+    movd    [%6+%9*2], m%2
+    movd    [%7+%8*2], m%3
+    movd    [%7+%9*2], m%4
+%endmacro
+
+; write 4 or 8 words in the mmx/xmm registers as 8 lines
+; 1 and 2 are the registers to write, this can be the same (for SSE2)
+; for pre-SSE4:
+; 3 is a general-purpose register that we will clobber
+; for SSE4:
+; 3 is a pointer to the destination's 5th line
+; 4 is a pointer to the destination's 4th line
+; 5/6 is -stride and +stride
+%macro WRITE_2x4W 6
+    movd            %3d, %1
+    punpckhdq        %1, %1
+    mov       [%4+%5*4], %3w
+    shr              %3, 16
+    add              %4, %6
+    mov       [%4+%5*4], %3w
+
+    movd            %3d, %1
+    add              %4, %5
+    mov       [%4+%5*2], %3w
+    shr              %3, 16
+    mov       [%4+%5  ], %3w
+
+    movd            %3d, %2
+    punpckhdq        %2, %2
+    mov       [%4     ], %3w
+    shr              %3, 16
+    mov       [%4+%6  ], %3w
+
+    movd            %3d, %2
+    add              %4, %6
+    mov       [%4+%6  ], %3w
+    shr              %3, 16
+    mov       [%4+%6*2], %3w
+    add              %4, %5
+%endmacro
+
+%macro WRITE_8W 5
+%if cpuflag(sse4)
+    pextrw    [%3+%4*4], %1, 0
+    pextrw    [%2+%4*4], %1, 1
+    pextrw    [%3+%4*2], %1, 2
+    pextrw    [%3+%4  ], %1, 3
+    pextrw    [%3     ], %1, 4
+    pextrw    [%2     ], %1, 5
+    pextrw    [%2+%5  ], %1, 6
+    pextrw    [%2+%5*2], %1, 7
+%else
+    movd            %2d, %1
+    psrldq           %1, 4
+    mov       [%3+%4*4], %2w
+    shr              %2, 16
+    add              %3, %5
+    mov       [%3+%4*4], %2w
+
+    movd            %2d, %1
+    psrldq           %1, 4
+    add              %3, %4
+    mov       [%3+%4*2], %2w
+    shr              %2, 16
+    mov       [%3+%4  ], %2w
+
+    movd            %2d, %1
+    psrldq           %1, 4
+    mov       [%3     ], %2w
+    shr              %2, 16
+    mov       [%3+%5  ], %2w
+
+    movd            %2d, %1
+    add              %3, %5
+    mov       [%3+%5  ], %2w
+    shr              %2, 16
+    mov       [%3+%5*2], %2w
+%endif
+%endmacro
+
+%macro SIMPLE_LOOPFILTER 2
+cglobal vp8_%1_loop_filter_simple, 3, %2, 8, dst, stride, flim, cntr
+%if mmsize == 8 ; mmx/mmxext
+    mov         cntrq, 2
+%endif
+%if cpuflag(ssse3)
+    pxor           m0, m0
+%endif
+    SPLATB_REG     m7, flim, m0     ; splat "flim" into register
+
+    ; set up indexes to address 4 rows
+%if mmsize == 8
+    DEFINE_ARGS dst1, mstride, stride, cntr, dst2
+%else
+    DEFINE_ARGS dst1, mstride, stride, dst3, dst2
+%endif
+    mov       strideq, mstrideq
+    neg      mstrideq
+%ifidn %1, h
+    lea         dst1q, [dst1q+4*strideq-2]
+%endif
+
+%if mmsize == 8 ; mmx / mmxext
+.next8px:
+%endif
+%ifidn %1, v
+    ; read 4 half/full rows of pixels
+    mova           m0, [dst1q+mstrideq*2]    ; p1
+    mova           m1, [dst1q+mstrideq]      ; p0
+    mova           m2, [dst1q]               ; q0
+    mova           m3, [dst1q+ strideq]      ; q1
+%else ; h
+    lea         dst2q, [dst1q+ strideq]
+
+%if mmsize == 8 ; mmx/mmxext
+    READ_8x4_INTERLEAVED  0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq
+%else ; sse2
+    READ_16x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq, dst3q
+%endif
+    TRANSPOSE4x4W         0, 1, 2, 3, 4
+%endif
+
+    ; simple_limit
+    mova           m5, m2           ; m5=backup of q0
+    mova           m6, m1           ; m6=backup of p0
+    psubusb        m1, m2           ; p0-q0
+    psubusb        m2, m6           ; q0-p0
+    por            m1, m2           ; FFABS(p0-q0)
+    paddusb        m1, m1           ; m1=FFABS(p0-q0)*2
+
+    mova           m4, m3
+    mova           m2, m0
+    psubusb        m3, m0           ; q1-p1
+    psubusb        m0, m4           ; p1-q1
+    por            m3, m0           ; FFABS(p1-q1)
+    mova           m0, [pb_80]
+    pxor           m2, m0
+    pxor           m4, m0
+    psubsb         m2, m4           ; m2=p1-q1 (signed) backup for below
+    pand           m3, [pb_FE]
+    psrlq          m3, 1            ; m3=FFABS(p1-q1)/2, this can be used signed
+    paddusb        m3, m1
+    psubusb        m3, m7
+    pxor           m1, m1
+    pcmpeqb        m3, m1           ; abs(p0-q0)*2+abs(p1-q1)/2<=flim mask(0xff/0x0)
+
+    ; filter_common (use m2/p1-q1, m4=q0, m6=p0, m5/q0-p0 and m3/mask)
+    mova           m4, m5
+    pxor           m5, m0
+    pxor           m0, m6
+    psubsb         m5, m0           ; q0-p0 (signed)
+    paddsb         m2, m5
+    paddsb         m2, m5
+    paddsb         m2, m5           ; a=(p1-q1) + 3*(q0-p0)
+    pand           m2, m3           ; apply filter mask (m3)
+
+    mova           m3, [pb_F8]
+    mova           m1, m2
+    paddsb         m2, [pb_4]       ; f1<<3=a+4
+    paddsb         m1, [pb_3]       ; f2<<3=a+3
+    pand           m2, m3
+    pand           m1, m3           ; cache f2<<3
+
+    pxor           m0, m0
+    pxor           m3, m3
+    pcmpgtb        m0, m2           ; which values are <0?
+    psubb          m3, m2           ; -f1<<3
+    psrlq          m2, 3            ; +f1
+    psrlq          m3, 3            ; -f1
+    pand           m3, m0
+    pandn          m0, m2
+    psubusb        m4, m0
+    paddusb        m4, m3           ; q0-f1
+
+    pxor           m0, m0
+    pxor           m3, m3
+    pcmpgtb        m0, m1           ; which values are <0?
+    psubb          m3, m1           ; -f2<<3
+    psrlq          m1, 3            ; +f2
+    psrlq          m3, 3            ; -f2
+    pand           m3, m0
+    pandn          m0, m1
+    paddusb        m6, m0
+    psubusb        m6, m3           ; p0+f2
+
+    ; store
+%ifidn %1, v
+    mova      [dst1q], m4
+    mova [dst1q+mstrideq], m6
+%else ; h
+    inc        dst1q
+    SBUTTERFLY    bw, 6, 4, 0
+
+%if mmsize == 16 ; sse2
+%if cpuflag(sse4)
+    inc         dst2q
+%endif
+    WRITE_8W       m6, dst2q, dst1q, mstrideq, strideq
+    lea         dst2q, [dst3q+mstrideq+1]
+%if cpuflag(sse4)
+    inc         dst3q
+%endif
+    WRITE_8W       m4, dst3q, dst2q, mstrideq, strideq
+%else ; mmx/mmxext
+    WRITE_2x4W     m6, m4, dst2q, dst1q, mstrideq, strideq
+%endif
+%endif
+
+%if mmsize == 8 ; mmx/mmxext
+    ; next 8 pixels
+%ifidn %1, v
+    add         dst1q, 8            ; advance 8 cols = pixels
+%else ; h
+    lea         dst1q, [dst1q+strideq*8-1]  ; advance 8 rows = lines
+%endif
+    dec         cntrq
+    jg .next8px
+    REP_RET
+%else ; sse2
+    RET
+%endif
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmx
+SIMPLE_LOOPFILTER v, 4
+SIMPLE_LOOPFILTER h, 5
+INIT_MMX mmxext
+SIMPLE_LOOPFILTER v, 4
+SIMPLE_LOOPFILTER h, 5
+%endif
+
+INIT_XMM sse2
+SIMPLE_LOOPFILTER v, 3
+SIMPLE_LOOPFILTER h, 5
+INIT_XMM ssse3
+SIMPLE_LOOPFILTER v, 3
+SIMPLE_LOOPFILTER h, 5
+INIT_XMM sse4
+SIMPLE_LOOPFILTER h, 5
+
+;-----------------------------------------------------------------------------
+; void vp8_h/v_loop_filter<size>_inner_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
+;                                            int flimE, int flimI, int hev_thr);
+;-----------------------------------------------------------------------------
+
+%macro INNER_LOOPFILTER 2
+%define stack_size 0
+%ifndef m8   ; stack layout: [0]=E, [1]=I, [2]=hev_thr
+%ifidn %1, v ;               [3]=hev() result
+%define stack_size mmsize * -4
+%else ; h    ; extra storage space for transposes
+%define stack_size mmsize * -5
+%endif
+%endif
+
+%if %2 == 8 ; chroma
+cglobal vp8_%1_loop_filter8uv_inner, 6, 6, 13, stack_size, dst, dst8, stride, flimE, flimI, hevthr
+%else ; luma
+cglobal vp8_%1_loop_filter16y_inner, 5, 5, 13, stack_size, dst, stride, flimE, flimI, hevthr
+%endif
+
+%if cpuflag(ssse3)
+    pxor             m7, m7
+%endif
+
+%ifndef m8
+    ; splat function arguments
+    SPLATB_REG       m0, flimEq, m7   ; E
+    SPLATB_REG       m1, flimIq, m7   ; I
+    SPLATB_REG       m2, hevthrq, m7  ; hev_thresh
+
+%define m_flimE    [rsp]
+%define m_flimI    [rsp+mmsize]
+%define m_hevthr   [rsp+mmsize*2]
+%define m_maskres  [rsp+mmsize*3]
+%define m_p0backup [rsp+mmsize*3]
+%define m_q0backup [rsp+mmsize*4]
+
+    mova        m_flimE, m0
+    mova        m_flimI, m1
+    mova       m_hevthr, m2
+%else
+%define m_flimE    m9
+%define m_flimI    m10
+%define m_hevthr   m11
+%define m_maskres  m12
+%define m_p0backup m12
+%define m_q0backup m8
+
+    ; splat function arguments
+    SPLATB_REG  m_flimE, flimEq, m7   ; E
+    SPLATB_REG  m_flimI, flimIq, m7   ; I
+    SPLATB_REG m_hevthr, hevthrq, m7  ; hev_thresh
+%endif
+
+%if %2 == 8 ; chroma
+    DEFINE_ARGS dst1, dst8, mstride, stride, dst2
+%elif mmsize == 8
+    DEFINE_ARGS dst1, mstride, stride, dst2, cntr
+    mov           cntrq, 2
+%else
+    DEFINE_ARGS dst1, mstride, stride, dst2, dst8
+%endif
+    mov         strideq, mstrideq
+    neg        mstrideq
+%ifidn %1, h
+    lea           dst1q, [dst1q+strideq*4-4]
+%if %2 == 8 ; chroma
+    lea           dst8q, [dst8q+strideq*4-4]
+%endif
+%endif
+
+%if mmsize == 8
+.next8px:
+%endif
+    ; read
+    lea           dst2q, [dst1q+strideq]
+%ifidn %1, v
+%if %2 == 8 && mmsize == 16
+%define movrow movh
+%else
+%define movrow mova
+%endif
+    movrow           m0, [dst1q+mstrideq*4] ; p3
+    movrow           m1, [dst2q+mstrideq*4] ; p2
+    movrow           m2, [dst1q+mstrideq*2] ; p1
+    movrow           m5, [dst2q]            ; q1
+    movrow           m6, [dst2q+ strideq*1] ; q2
+    movrow           m7, [dst2q+ strideq*2] ; q3
+%if mmsize == 16 && %2 == 8
+    movhps           m0, [dst8q+mstrideq*4]
+    movhps           m2, [dst8q+mstrideq*2]
+    add           dst8q, strideq
+    movhps           m1, [dst8q+mstrideq*4]
+    movhps           m5, [dst8q]
+    movhps           m6, [dst8q+ strideq  ]
+    movhps           m7, [dst8q+ strideq*2]
+    add           dst8q, mstrideq
+%endif
+%elif mmsize == 8 ; mmx/mmxext (h)
+    ; read 8 rows of 8px each
+    movu             m0, [dst1q+mstrideq*4]
+    movu             m1, [dst2q+mstrideq*4]
+    movu             m2, [dst1q+mstrideq*2]
+    movu             m3, [dst1q+mstrideq  ]
+    movu             m4, [dst1q]
+    movu             m5, [dst2q]
+    movu             m6, [dst2q+ strideq  ]
+
+    ; 8x8 transpose
+    TRANSPOSE4x4B     0, 1, 2, 3, 7
+    mova     m_q0backup, m1
+    movu             m7, [dst2q+ strideq*2]
+    TRANSPOSE4x4B     4, 5, 6, 7, 1
+    SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
+    SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
+    SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
+    mova             m1, m_q0backup
+    mova     m_q0backup, m2          ; store q0
+    SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
+    mova     m_p0backup, m5          ; store p0
+    SWAP              1, 4
+    SWAP              2, 4
+    SWAP              6, 3
+    SWAP              5, 3
+%else ; sse2 (h)
+%if %2 == 16
+    lea           dst8q, [dst1q+ strideq*8]
+%endif
+
+    ; read 16 rows of 8px each, interleave
+    movh             m0, [dst1q+mstrideq*4]
+    movh             m1, [dst8q+mstrideq*4]
+    movh             m2, [dst1q+mstrideq*2]
+    movh             m5, [dst8q+mstrideq*2]
+    movh             m3, [dst1q+mstrideq  ]
+    movh             m6, [dst8q+mstrideq  ]
+    movh             m4, [dst1q]
+    movh             m7, [dst8q]
+    punpcklbw        m0, m1          ; A/I
+    punpcklbw        m2, m5          ; C/K
+    punpcklbw        m3, m6          ; D/L
+    punpcklbw        m4, m7          ; E/M
+
+    add           dst8q, strideq
+    movh             m1, [dst2q+mstrideq*4]
+    movh             m6, [dst8q+mstrideq*4]
+    movh             m5, [dst2q]
+    movh             m7, [dst8q]
+    punpcklbw        m1, m6          ; B/J
+    punpcklbw        m5, m7          ; F/N
+    movh             m6, [dst2q+ strideq  ]
+    movh             m7, [dst8q+ strideq  ]
+    punpcklbw        m6, m7          ; G/O
+
+    ; 8x16 transpose
+    TRANSPOSE4x4B     0, 1, 2, 3, 7
+%ifdef m8
+    SWAP              1, 8
+%else
+    mova     m_q0backup, m1
+%endif
+    movh             m7, [dst2q+ strideq*2]
+    movh             m1, [dst8q+ strideq*2]
+    punpcklbw        m7, m1          ; H/P
+    TRANSPOSE4x4B     4, 5, 6, 7, 1
+    SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
+    SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
+    SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
+%ifdef m8
+    SWAP              1, 8
+    SWAP              2, 8
+%else
+    mova             m1, m_q0backup
+    mova     m_q0backup, m2          ; store q0
+%endif
+    SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
+%ifdef m12
+    SWAP              5, 12
+%else
+    mova     m_p0backup, m5          ; store p0
+%endif
+    SWAP              1, 4
+    SWAP              2, 4
+    SWAP              6, 3
+    SWAP              5, 3
+%endif
+
+    ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
+    mova             m4, m1
+    SWAP              4, 1
+    psubusb          m4, m0          ; p2-p3
+    psubusb          m0, m1          ; p3-p2
+    por              m0, m4          ; abs(p3-p2)
+
+    mova             m4, m2
+    SWAP              4, 2
+    psubusb          m4, m1          ; p1-p2
+    psubusb          m1, m2          ; p2-p1
+    por              m1, m4          ; abs(p2-p1)
+
+    mova             m4, m6
+    SWAP              4, 6
+    psubusb          m4, m7          ; q2-q3
+    psubusb          m7, m6          ; q3-q2
+    por              m7, m4          ; abs(q3-q2)
+
+    mova             m4, m5
+    SWAP              4, 5
+    psubusb          m4, m6          ; q1-q2
+    psubusb          m6, m5          ; q2-q1
+    por              m6, m4          ; abs(q2-q1)
+
+%if notcpuflag(mmxext)
+    mova             m4, m_flimI
+    pxor             m3, m3
+    psubusb          m0, m4
+    psubusb          m1, m4
+    psubusb          m7, m4
+    psubusb          m6, m4
+    pcmpeqb          m0, m3          ; abs(p3-p2) <= I
+    pcmpeqb          m1, m3          ; abs(p2-p1) <= I
+    pcmpeqb          m7, m3          ; abs(q3-q2) <= I
+    pcmpeqb          m6, m3          ; abs(q2-q1) <= I
+    pand             m0, m1
+    pand             m7, m6
+    pand             m0, m7
+%else ; mmxext/sse2
+    pmaxub           m0, m1
+    pmaxub           m6, m7
+    pmaxub           m0, m6
+%endif
+
+    ; normal_limit and high_edge_variance for p1-p0, q1-q0
+    SWAP              7, 3           ; now m7 is zero
+%ifidn %1, v
+    movrow           m3, [dst1q+mstrideq  ] ; p0
+%if mmsize == 16 && %2 == 8
+    movhps           m3, [dst8q+mstrideq  ]
+%endif
+%elifdef m12
+    SWAP              3, 12
+%else
+    mova             m3, m_p0backup
+%endif
+
+    mova             m1, m2
+    SWAP              1, 2
+    mova             m6, m3
+    SWAP              3, 6
+    psubusb          m1, m3          ; p1-p0
+    psubusb          m6, m2          ; p0-p1
+    por              m1, m6          ; abs(p1-p0)
+%if notcpuflag(mmxext)
+    mova             m6, m1
+    psubusb          m1, m4
+    psubusb          m6, m_hevthr
+    pcmpeqb          m1, m7          ; abs(p1-p0) <= I
+    pcmpeqb          m6, m7          ; abs(p1-p0) <= hev_thresh
+    pand             m0, m1
+    mova      m_maskres, m6
+%else ; mmxext/sse2
+    pmaxub           m0, m1          ; max_I
+    SWAP              1, 4           ; max_hev_thresh
+%endif
+
+    SWAP              6, 4           ; now m6 is I
+%ifidn %1, v
+    movrow           m4, [dst1q]     ; q0
+%if mmsize == 16 && %2 == 8
+    movhps           m4, [dst8q]
+%endif
+%elifdef m8
+    SWAP              4, 8
+%else
+    mova             m4, m_q0backup
+%endif
+    mova             m1, m4
+    SWAP              1, 4
+    mova             m7, m5
+    SWAP              7, 5
+    psubusb          m1, m5          ; q0-q1
+    psubusb          m7, m4          ; q1-q0
+    por              m1, m7          ; abs(q1-q0)
+%if notcpuflag(mmxext)
+    mova             m7, m1
+    psubusb          m1, m6
+    psubusb          m7, m_hevthr
+    pxor             m6, m6
+    pcmpeqb          m1, m6          ; abs(q1-q0) <= I
+    pcmpeqb          m7, m6          ; abs(q1-q0) <= hev_thresh
+    mova             m6, m_maskres
+    pand             m0, m1          ; abs([pq][321]-[pq][210]) <= I
+    pand             m6, m7
+%else ; mmxext/sse2
+    pxor             m7, m7
+    pmaxub           m0, m1
+    pmaxub           m6, m1
+    psubusb          m0, m_flimI
+    psubusb          m6, m_hevthr
+    pcmpeqb          m0, m7          ; max(abs(..)) <= I
+    pcmpeqb          m6, m7          ; !(max(abs..) > thresh)
+%endif
+%ifdef m12
+    SWAP              6, 12
+%else
+    mova      m_maskres, m6          ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
+%endif
+
+    ; simple_limit
+    mova             m1, m3
+    SWAP              1, 3
+    mova             m6, m4          ; keep copies of p0/q0 around for later use
+    SWAP              6, 4
+    psubusb          m1, m4          ; p0-q0
+    psubusb          m6, m3          ; q0-p0
+    por              m1, m6          ; abs(q0-p0)
+    paddusb          m1, m1          ; m1=2*abs(q0-p0)
+
+    mova             m7, m2
+    SWAP              7, 2
+    mova             m6, m5
+    SWAP              6, 5
+    psubusb          m7, m5          ; p1-q1
+    psubusb          m6, m2          ; q1-p1
+    por              m7, m6          ; abs(q1-p1)
+    pxor             m6, m6
+    pand             m7, [pb_FE]
+    psrlq            m7, 1           ; abs(q1-p1)/2
+    paddusb          m7, m1          ; abs(q0-p0)*2+abs(q1-p1)/2
+    psubusb          m7, m_flimE
+    pcmpeqb          m7, m6          ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
+    pand             m0, m7          ; normal_limit result
+
+    ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
+%ifdef m8 ; x86-64 && sse2
+    mova             m8, [pb_80]
+%define m_pb_80 m8
+%else ; x86-32 or mmx/mmxext
+%define m_pb_80 [pb_80]
+%endif
+    mova             m1, m4
+    mova             m7, m3
+    pxor             m1, m_pb_80
+    pxor             m7, m_pb_80
+    psubsb           m1, m7          ; (signed) q0-p0
+    mova             m6, m2
+    mova             m7, m5
+    pxor             m6, m_pb_80
+    pxor             m7, m_pb_80
+    psubsb           m6, m7          ; (signed) p1-q1
+    mova             m7, m_maskres
+    pandn            m7, m6
+    paddsb           m7, m1
+    paddsb           m7, m1
+    paddsb           m7, m1          ; 3*(q0-p0)+is4tap?(p1-q1)
+
+    pand             m7, m0
+    mova             m1, [pb_F8]
+    mova             m6, m7
+    paddsb           m7, [pb_3]
+    paddsb           m6, [pb_4]
+    pand             m7, m1
+    pand             m6, m1
+
+    pxor             m1, m1
+    pxor             m0, m0
+    pcmpgtb          m1, m7
+    psubb            m0, m7
+    psrlq            m7, 3           ; +f2
+    psrlq            m0, 3           ; -f2
+    pand             m0, m1
+    pandn            m1, m7
+    psubusb          m3, m0
+    paddusb          m3, m1          ; p0+f2
+
+    pxor             m1, m1
+    pxor             m0, m0
+    pcmpgtb          m0, m6
+    psubb            m1, m6
+    psrlq            m6, 3           ; +f1
+    psrlq            m1, 3           ; -f1
+    pand             m1, m0
+    pandn            m0, m6
+    psubusb          m4, m0
+    paddusb          m4, m1          ; q0-f1
+
+%ifdef m12
+    SWAP              6, 12
+%else
+    mova             m6, m_maskres
+%endif
+%if notcpuflag(mmxext)
+    mova             m7, [pb_1]
+%else ; mmxext/sse2
+    pxor             m7, m7
+%endif
+    pand             m0, m6
+    pand             m1, m6
+%if notcpuflag(mmxext)
+    paddusb          m0, m7
+    pand             m1, [pb_FE]
+    pandn            m7, m0
+    psrlq            m1, 1
+    psrlq            m7, 1
+    SWAP              0, 7
+%else ; mmxext/sse2
+    psubusb          m1, [pb_1]
+    pavgb            m0, m7          ; a
+    pavgb            m1, m7          ; -a
+%endif
+    psubusb          m5, m0
+    psubusb          m2, m1
+    paddusb          m5, m1          ; q1-a
+    paddusb          m2, m0          ; p1+a
+
+    ; store
+%ifidn %1, v
+    movrow [dst1q+mstrideq*2], m2
+    movrow [dst1q+mstrideq  ], m3
+    movrow      [dst1q], m4
+    movrow [dst1q+ strideq  ], m5
+%if mmsize == 16 && %2 == 8
+    movhps [dst8q+mstrideq*2], m2
+    movhps [dst8q+mstrideq  ], m3
+    movhps      [dst8q], m4
+    movhps [dst8q+ strideq  ], m5
+%endif
+%else ; h
+    add           dst1q, 2
+    add           dst2q, 2
+
+    ; 4x8/16 transpose
+    TRANSPOSE4x4B     2, 3, 4, 5, 6
+
+%if mmsize == 8 ; mmx/mmxext (h)
+    WRITE_4x2D        2, 3, 4, 5, dst1q, dst2q, mstrideq, strideq
+%else ; sse2 (h)
+    lea           dst8q, [dst8q+mstrideq  +2]
+    WRITE_4x4D        2, 3, 4, 5, dst1q, dst2q, dst8q, mstrideq, strideq, %2
+%endif
+%endif
+
+%if mmsize == 8
+%if %2 == 8 ; chroma
+%ifidn %1, h
+    sub           dst1q, 2
+%endif
+    cmp           dst1q, dst8q
+    mov           dst1q, dst8q
+    jnz .next8px
+%else
+%ifidn %1, h
+    lea           dst1q, [dst1q+ strideq*8-2]
+%else ; v
+    add           dst1q, 8
+%endif
+    dec           cntrq
+    jg .next8px
+%endif
+    REP_RET
+%else ; mmsize == 16
+    RET
+%endif
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmx
+INNER_LOOPFILTER v, 16
+INNER_LOOPFILTER h, 16
+INNER_LOOPFILTER v,  8
+INNER_LOOPFILTER h,  8
+
+INIT_MMX mmxext
+INNER_LOOPFILTER v, 16
+INNER_LOOPFILTER h, 16
+INNER_LOOPFILTER v,  8
+INNER_LOOPFILTER h,  8
+%endif
+
+INIT_XMM sse2
+INNER_LOOPFILTER v, 16
+INNER_LOOPFILTER h, 16
+INNER_LOOPFILTER v,  8
+INNER_LOOPFILTER h,  8
+
+INIT_XMM ssse3
+INNER_LOOPFILTER v, 16
+INNER_LOOPFILTER h, 16
+INNER_LOOPFILTER v,  8
+INNER_LOOPFILTER h,  8
+
+;-----------------------------------------------------------------------------
+; void vp8_h/v_loop_filter<size>_mbedge_<opt>(uint8_t *dst, [uint8_t *v,] int stride,
+;                                            int flimE, int flimI, int hev_thr);
+;-----------------------------------------------------------------------------
+
+%macro MBEDGE_LOOPFILTER 2
+%define stack_size 0
+%ifndef m8       ; stack layout: [0]=E, [1]=I, [2]=hev_thr
+%if mmsize == 16 ;               [3]=hev() result
+                 ;               [4]=filter tmp result
+                 ;               [5]/[6] = p2/q2 backup
+                 ;               [7]=lim_res sign result
+%define stack_size mmsize * -7
+%else ; 8        ; extra storage space for transposes
+%define stack_size mmsize * -8
+%endif
+%endif
+
+%if %2 == 8 ; chroma
+cglobal vp8_%1_loop_filter8uv_mbedge, 6, 6, 15, stack_size, dst1, dst8, stride, flimE, flimI, hevthr
+%else ; luma
+cglobal vp8_%1_loop_filter16y_mbedge, 5, 5, 15, stack_size, dst1, stride, flimE, flimI, hevthr
+%endif
+
+%if cpuflag(ssse3)
+    pxor             m7, m7
+%endif
+
+%ifndef m8
+    ; splat function arguments
+    SPLATB_REG       m0, flimEq, m7   ; E
+    SPLATB_REG       m1, flimIq, m7   ; I
+    SPLATB_REG       m2, hevthrq, m7  ; hev_thresh
+
+%define m_flimE    [rsp]
+%define m_flimI    [rsp+mmsize]
+%define m_hevthr   [rsp+mmsize*2]
+%define m_maskres  [rsp+mmsize*3]
+%define m_limres   [rsp+mmsize*4]
+%define m_p0backup [rsp+mmsize*3]
+%define m_q0backup [rsp+mmsize*4]
+%define m_p2backup [rsp+mmsize*5]
+%define m_q2backup [rsp+mmsize*6]
+%if mmsize == 16
+%define m_limsign  [rsp]
+%else
+%define m_limsign  [rsp+mmsize*7]
+%endif
+
+    mova        m_flimE, m0
+    mova        m_flimI, m1
+    mova       m_hevthr, m2
+%else ; sse2 on x86-64
+%define m_flimE    m9
+%define m_flimI    m10
+%define m_hevthr   m11
+%define m_maskres  m12
+%define m_limres   m8
+%define m_p0backup m12
+%define m_q0backup m8
+%define m_p2backup m13
+%define m_q2backup m14
+%define m_limsign  m9
+
+    ; splat function arguments
+    SPLATB_REG  m_flimE, flimEq, m7   ; E
+    SPLATB_REG  m_flimI, flimIq, m7   ; I
+    SPLATB_REG m_hevthr, hevthrq, m7  ; hev_thresh
+%endif
+
+%if %2 == 8 ; chroma
+    DEFINE_ARGS dst1, dst8, mstride, stride, dst2
+%elif mmsize == 8
+    DEFINE_ARGS dst1, mstride, stride, dst2, cntr
+    mov           cntrq, 2
+%else
+    DEFINE_ARGS dst1, mstride, stride, dst2, dst8
+%endif
+    mov         strideq, mstrideq
+    neg        mstrideq
+%ifidn %1, h
+    lea           dst1q, [dst1q+strideq*4-4]
+%if %2 == 8 ; chroma
+    lea           dst8q, [dst8q+strideq*4-4]
+%endif
+%endif
+
+%if mmsize == 8
+.next8px:
+%endif
+    ; read
+    lea           dst2q, [dst1q+ strideq  ]
+%ifidn %1, v
+%if %2 == 8 && mmsize == 16
+%define movrow movh
+%else
+%define movrow mova
+%endif
+    movrow           m0, [dst1q+mstrideq*4] ; p3
+    movrow           m1, [dst2q+mstrideq*4] ; p2
+    movrow           m2, [dst1q+mstrideq*2] ; p1
+    movrow           m5, [dst2q]            ; q1
+    movrow           m6, [dst2q+ strideq  ] ; q2
+    movrow           m7, [dst2q+ strideq*2] ; q3
+%if mmsize == 16 && %2 == 8
+    movhps           m0, [dst8q+mstrideq*4]
+    movhps           m2, [dst8q+mstrideq*2]
+    add           dst8q, strideq
+    movhps           m1, [dst8q+mstrideq*4]
+    movhps           m5, [dst8q]
+    movhps           m6, [dst8q+ strideq  ]
+    movhps           m7, [dst8q+ strideq*2]
+    add           dst8q, mstrideq
+%endif
+%elif mmsize == 8 ; mmx/mmxext (h)
+    ; read 8 rows of 8px each
+    movu             m0, [dst1q+mstrideq*4]
+    movu             m1, [dst2q+mstrideq*4]
+    movu             m2, [dst1q+mstrideq*2]
+    movu             m3, [dst1q+mstrideq  ]
+    movu             m4, [dst1q]
+    movu             m5, [dst2q]
+    movu             m6, [dst2q+ strideq  ]
+
+    ; 8x8 transpose
+    TRANSPOSE4x4B     0, 1, 2, 3, 7
+    mova     m_q0backup, m1
+    movu             m7, [dst2q+ strideq*2]
+    TRANSPOSE4x4B     4, 5, 6, 7, 1
+    SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
+    SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
+    SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
+    mova             m1, m_q0backup
+    mova     m_q0backup, m2          ; store q0
+    SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
+    mova     m_p0backup, m5          ; store p0
+    SWAP              1, 4
+    SWAP              2, 4
+    SWAP              6, 3
+    SWAP              5, 3
+%else ; sse2 (h)
+%if %2 == 16
+    lea           dst8q, [dst1q+ strideq*8  ]
+%endif
+
+    ; read 16 rows of 8px each, interleave
+    movh             m0, [dst1q+mstrideq*4]
+    movh             m1, [dst8q+mstrideq*4]
+    movh             m2, [dst1q+mstrideq*2]
+    movh             m5, [dst8q+mstrideq*2]
+    movh             m3, [dst1q+mstrideq  ]
+    movh             m6, [dst8q+mstrideq  ]
+    movh             m4, [dst1q]
+    movh             m7, [dst8q]
+    punpcklbw        m0, m1          ; A/I
+    punpcklbw        m2, m5          ; C/K
+    punpcklbw        m3, m6          ; D/L
+    punpcklbw        m4, m7          ; E/M
+
+    add           dst8q, strideq
+    movh             m1, [dst2q+mstrideq*4]
+    movh             m6, [dst8q+mstrideq*4]
+    movh             m5, [dst2q]
+    movh             m7, [dst8q]
+    punpcklbw        m1, m6          ; B/J
+    punpcklbw        m5, m7          ; F/N
+    movh             m6, [dst2q+ strideq  ]
+    movh             m7, [dst8q+ strideq  ]
+    punpcklbw        m6, m7          ; G/O
+
+    ; 8x16 transpose
+    TRANSPOSE4x4B     0, 1, 2, 3, 7
+%ifdef m8
+    SWAP              1, 8
+%else
+    mova     m_q0backup, m1
+%endif
+    movh             m7, [dst2q+ strideq*2]
+    movh             m1, [dst8q+ strideq*2]
+    punpcklbw        m7, m1          ; H/P
+    TRANSPOSE4x4B     4, 5, 6, 7, 1
+    SBUTTERFLY       dq, 0, 4, 1     ; p3/p2
+    SBUTTERFLY       dq, 2, 6, 1     ; q0/q1
+    SBUTTERFLY       dq, 3, 7, 1     ; q2/q3
+%ifdef m8
+    SWAP              1, 8
+    SWAP              2, 8
+%else
+    mova             m1, m_q0backup
+    mova     m_q0backup, m2          ; store q0
+%endif
+    SBUTTERFLY       dq, 1, 5, 2     ; p1/p0
+%ifdef m12
+    SWAP              5, 12
+%else
+    mova     m_p0backup, m5          ; store p0
+%endif
+    SWAP              1, 4
+    SWAP              2, 4
+    SWAP              6, 3
+    SWAP              5, 3
+%endif
+
+    ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1
+    mova             m4, m1
+    SWAP              4, 1
+    psubusb          m4, m0          ; p2-p3
+    psubusb          m0, m1          ; p3-p2
+    por              m0, m4          ; abs(p3-p2)
+
+    mova             m4, m2
+    SWAP              4, 2
+    psubusb          m4, m1          ; p1-p2
+    mova     m_p2backup, m1
+    psubusb          m1, m2          ; p2-p1
+    por              m1, m4          ; abs(p2-p1)
+
+    mova             m4, m6
+    SWAP              4, 6
+    psubusb          m4, m7          ; q2-q3
+    psubusb          m7, m6          ; q3-q2
+    por              m7, m4          ; abs(q3-q2)
+
+    mova             m4, m5
+    SWAP              4, 5
+    psubusb          m4, m6          ; q1-q2
+    mova     m_q2backup, m6
+    psubusb          m6, m5          ; q2-q1
+    por              m6, m4          ; abs(q2-q1)
+
+%if notcpuflag(mmxext)
+    mova             m4, m_flimI
+    pxor             m3, m3
+    psubusb          m0, m4
+    psubusb          m1, m4
+    psubusb          m7, m4
+    psubusb          m6, m4
+    pcmpeqb          m0, m3          ; abs(p3-p2) <= I
+    pcmpeqb          m1, m3          ; abs(p2-p1) <= I
+    pcmpeqb          m7, m3          ; abs(q3-q2) <= I
+    pcmpeqb          m6, m3          ; abs(q2-q1) <= I
+    pand             m0, m1
+    pand             m7, m6
+    pand             m0, m7
+%else ; mmxext/sse2
+    pmaxub           m0, m1
+    pmaxub           m6, m7
+    pmaxub           m0, m6
+%endif
+
+    ; normal_limit and high_edge_variance for p1-p0, q1-q0
+    SWAP              7, 3           ; now m7 is zero
+%ifidn %1, v
+    movrow           m3, [dst1q+mstrideq  ] ; p0
+%if mmsize == 16 && %2 == 8
+    movhps           m3, [dst8q+mstrideq  ]
+%endif
+%elifdef m12
+    SWAP              3, 12
+%else
+    mova             m3, m_p0backup
+%endif
+
+    mova             m1, m2
+    SWAP              1, 2
+    mova             m6, m3
+    SWAP              3, 6
+    psubusb          m1, m3          ; p1-p0
+    psubusb          m6, m2          ; p0-p1
+    por              m1, m6          ; abs(p1-p0)
+%if notcpuflag(mmxext)
+    mova             m6, m1
+    psubusb          m1, m4
+    psubusb          m6, m_hevthr
+    pcmpeqb          m1, m7          ; abs(p1-p0) <= I
+    pcmpeqb          m6, m7          ; abs(p1-p0) <= hev_thresh
+    pand             m0, m1
+    mova      m_maskres, m6
+%else ; mmxext/sse2
+    pmaxub           m0, m1          ; max_I
+    SWAP              1, 4           ; max_hev_thresh
+%endif
+
+    SWAP              6, 4           ; now m6 is I
+%ifidn %1, v
+    movrow           m4, [dst1q]     ; q0
+%if mmsize == 16 && %2 == 8
+    movhps           m4, [dst8q]
+%endif
+%elifdef m8
+    SWAP              4, 8
+%else
+    mova             m4, m_q0backup
+%endif
+    mova             m1, m4
+    SWAP              1, 4
+    mova             m7, m5
+    SWAP              7, 5
+    psubusb          m1, m5          ; q0-q1
+    psubusb          m7, m4          ; q1-q0
+    por              m1, m7          ; abs(q1-q0)
+%if notcpuflag(mmxext)
+    mova             m7, m1
+    psubusb          m1, m6
+    psubusb          m7, m_hevthr
+    pxor             m6, m6
+    pcmpeqb          m1, m6          ; abs(q1-q0) <= I
+    pcmpeqb          m7, m6          ; abs(q1-q0) <= hev_thresh
+    mova             m6, m_maskres
+    pand             m0, m1          ; abs([pq][321]-[pq][210]) <= I
+    pand             m6, m7
+%else ; mmxext/sse2
+    pxor             m7, m7
+    pmaxub           m0, m1
+    pmaxub           m6, m1
+    psubusb          m0, m_flimI
+    psubusb          m6, m_hevthr
+    pcmpeqb          m0, m7          ; max(abs(..)) <= I
+    pcmpeqb          m6, m7          ; !(max(abs..) > thresh)
+%endif
+%ifdef m12
+    SWAP              6, 12
+%else
+    mova      m_maskres, m6          ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t)
+%endif
+
+    ; simple_limit
+    mova             m1, m3
+    SWAP              1, 3
+    mova             m6, m4          ; keep copies of p0/q0 around for later use
+    SWAP              6, 4
+    psubusb          m1, m4          ; p0-q0
+    psubusb          m6, m3          ; q0-p0
+    por              m1, m6          ; abs(q0-p0)
+    paddusb          m1, m1          ; m1=2*abs(q0-p0)
+
+    mova             m7, m2
+    SWAP              7, 2
+    mova             m6, m5
+    SWAP              6, 5
+    psubusb          m7, m5          ; p1-q1
+    psubusb          m6, m2          ; q1-p1
+    por              m7, m6          ; abs(q1-p1)
+    pxor             m6, m6
+    pand             m7, [pb_FE]
+    psrlq            m7, 1           ; abs(q1-p1)/2
+    paddusb          m7, m1          ; abs(q0-p0)*2+abs(q1-p1)/2
+    psubusb          m7, m_flimE
+    pcmpeqb          m7, m6          ; abs(q0-p0)*2+abs(q1-p1)/2 <= E
+    pand             m0, m7          ; normal_limit result
+
+    ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask
+%ifdef m8 ; x86-64 && sse2
+    mova             m8, [pb_80]
+%define m_pb_80 m8
+%else ; x86-32 or mmx/mmxext
+%define m_pb_80 [pb_80]
+%endif
+    mova             m1, m4
+    mova             m7, m3
+    pxor             m1, m_pb_80
+    pxor             m7, m_pb_80
+    psubsb           m1, m7          ; (signed) q0-p0
+    mova             m6, m2
+    mova             m7, m5
+    pxor             m6, m_pb_80
+    pxor             m7, m_pb_80
+    psubsb           m6, m7          ; (signed) p1-q1
+    mova             m7, m_maskres
+    paddsb           m6, m1
+    paddsb           m6, m1
+    paddsb           m6, m1
+    pand             m6, m0
+%ifdef m8
+    mova       m_limres, m6          ; 3*(qp-p0)+(p1-q1) masked for filter_mbedge
+    pand       m_limres, m7
+%else
+    mova             m0, m6
+    pand             m0, m7
+    mova       m_limres, m0
+%endif
+    pandn            m7, m6          ; 3*(q0-p0)+(p1-q1) masked for filter_common
+
+    mova             m1, [pb_F8]
+    mova             m6, m7
+    paddsb           m7, [pb_3]
+    paddsb           m6, [pb_4]
+    pand             m7, m1
+    pand             m6, m1
+
+    pxor             m1, m1
+    pxor             m0, m0
+    pcmpgtb          m1, m7
+    psubb            m0, m7
+    psrlq            m7, 3           ; +f2
+    psrlq            m0, 3           ; -f2
+    pand             m0, m1
+    pandn            m1, m7
+    psubusb          m3, m0
+    paddusb          m3, m1          ; p0+f2
+
+    pxor             m1, m1
+    pxor             m0, m0
+    pcmpgtb          m0, m6
+    psubb            m1, m6
+    psrlq            m6, 3           ; +f1
+    psrlq            m1, 3           ; -f1
+    pand             m1, m0
+    pandn            m0, m6
+    psubusb          m4, m0
+    paddusb          m4, m1          ; q0-f1
+
+    ; filter_mbedge (m2-m5 = p1-q1; lim_res carries w)
+%if cpuflag(ssse3)
+    mova             m7, [pb_1]
+%else
+    mova             m7, [pw_63]
+%endif
+%ifdef m8
+    SWAP              1, 8
+%else
+    mova             m1, m_limres
+%endif
+    pxor             m0, m0
+    mova             m6, m1
+    pcmpgtb          m0, m1         ; which are negative
+%if cpuflag(ssse3)
+    punpcklbw        m6, m7         ; interleave with "1" for rounding
+    punpckhbw        m1, m7
+%else
+    punpcklbw        m6, m0         ; signed byte->word
+    punpckhbw        m1, m0
+%endif
+    mova      m_limsign, m0
+%if cpuflag(ssse3)
+    mova             m7, [pb_27_63]
+%ifndef m8
+    mova       m_limres, m1
+%endif
+%ifdef m10
+    SWAP              0, 10         ; don't lose lim_sign copy
+%endif
+    mova             m0, m7
+    pmaddubsw        m7, m6
+    SWAP              6, 7
+    pmaddubsw        m0, m1
+    SWAP              1, 0
+%ifdef m10
+    SWAP              0, 10
+%else
+    mova             m0, m_limsign
+%endif
+%else
+    mova      m_maskres, m6         ; backup for later in filter
+    mova       m_limres, m1
+    pmullw          m6, [pw_27]
+    pmullw          m1, [pw_27]
+    paddw           m6, m7
+    paddw           m1, m7
+%endif
+    psraw           m6, 7
+    psraw           m1, 7
+    packsswb        m6, m1          ; a0
+    pxor            m1, m1
+    psubb           m1, m6
+    pand            m1, m0          ; -a0
+    pandn           m0, m6          ; +a0
+%if cpuflag(ssse3)
+    mova            m6, [pb_18_63]  ; pipelining
+%endif
+    psubusb         m3, m1
+    paddusb         m4, m1
+    paddusb         m3, m0          ; p0+a0
+    psubusb         m4, m0          ; q0-a0
+
+%if cpuflag(ssse3)
+    SWAP             6, 7
+%ifdef m10
+    SWAP             1, 10
+%else
+    mova            m1, m_limres
+%endif
+    mova            m0, m7
+    pmaddubsw       m7, m6
+    SWAP             6, 7
+    pmaddubsw       m0, m1
+    SWAP             1, 0
+%ifdef m10
+    SWAP             0, 10
+%endif
+    mova            m0, m_limsign
+%else
+    mova            m6, m_maskres
+    mova            m1, m_limres
+    pmullw          m6, [pw_18]
+    pmullw          m1, [pw_18]
+    paddw           m6, m7
+    paddw           m1, m7
+%endif
+    mova            m0, m_limsign
+    psraw           m6, 7
+    psraw           m1, 7
+    packsswb        m6, m1          ; a1
+    pxor            m1, m1
+    psubb           m1, m6
+    pand            m1, m0          ; -a1
+    pandn           m0, m6          ; +a1
+%if cpuflag(ssse3)
+    mova            m6, [pb_9_63]
+%endif
+    psubusb         m2, m1
+    paddusb         m5, m1
+    paddusb         m2, m0          ; p1+a1
+    psubusb         m5, m0          ; q1-a1
+
+%if cpuflag(ssse3)
+    SWAP             6, 7
+%ifdef m10
+    SWAP             1, 10
+%else
+    mova            m1, m_limres
+%endif
+    mova            m0, m7
+    pmaddubsw       m7, m6
+    SWAP             6, 7
+    pmaddubsw       m0, m1
+    SWAP             1, 0
+%else
+%ifdef m8
+    SWAP             6, 12
+    SWAP             1, 8
+%else
+    mova            m6, m_maskres
+    mova            m1, m_limres
+%endif
+    pmullw          m6, [pw_9]
+    pmullw          m1, [pw_9]
+    paddw           m6, m7
+    paddw           m1, m7
+%endif
+%ifdef m9
+    SWAP             7, 9
+%else
+    mova            m7, m_limsign
+%endif
+    psraw           m6, 7
+    psraw           m1, 7
+    packsswb        m6, m1          ; a1
+    pxor            m0, m0
+    psubb           m0, m6
+    pand            m0, m7          ; -a1
+    pandn           m7, m6          ; +a1
+%ifdef m8
+    SWAP             1, 13
+    SWAP             6, 14
+%else
+    mova            m1, m_p2backup
+    mova            m6, m_q2backup
+%endif
+    psubusb         m1, m0
+    paddusb         m6, m0
+    paddusb         m1, m7          ; p1+a1
+    psubusb         m6, m7          ; q1-a1
+
+    ; store
+%ifidn %1, v
+    movrow [dst2q+mstrideq*4], m1
+    movrow [dst1q+mstrideq*2], m2
+    movrow [dst1q+mstrideq  ], m3
+    movrow     [dst1q], m4
+    movrow     [dst2q], m5
+    movrow [dst2q+ strideq  ], m6
+%if mmsize == 16 && %2 == 8
+    add           dst8q, mstrideq
+    movhps [dst8q+mstrideq*2], m1
+    movhps [dst8q+mstrideq  ], m2
+    movhps     [dst8q], m3
+    add          dst8q, strideq
+    movhps     [dst8q], m4
+    movhps [dst8q+ strideq  ], m5
+    movhps [dst8q+ strideq*2], m6
+%endif
+%else ; h
+    inc          dst1q
+    inc          dst2q
+
+    ; 4x8/16 transpose
+    TRANSPOSE4x4B    1, 2, 3, 4, 0
+    SBUTTERFLY      bw, 5, 6, 0
+
+%if mmsize == 8 ; mmx/mmxext (h)
+    WRITE_4x2D       1, 2, 3, 4, dst1q, dst2q, mstrideq, strideq
+    add          dst1q, 4
+    WRITE_2x4W      m5, m6, dst2q, dst1q, mstrideq, strideq
+%else ; sse2 (h)
+    lea          dst8q, [dst8q+mstrideq+1]
+    WRITE_4x4D       1, 2, 3, 4, dst1q, dst2q, dst8q, mstrideq, strideq, %2
+    lea          dst1q, [dst2q+mstrideq+4]
+    lea          dst8q, [dst8q+mstrideq+4]
+%if cpuflag(sse4)
+    add          dst2q, 4
+%endif
+    WRITE_8W        m5, dst2q, dst1q,  mstrideq, strideq
+%if cpuflag(sse4)
+    lea          dst2q, [dst8q+ strideq  ]
+%endif
+    WRITE_8W        m6, dst2q, dst8q, mstrideq, strideq
+%endif
+%endif
+
+%if mmsize == 8
+%if %2 == 8 ; chroma
+%ifidn %1, h
+    sub          dst1q, 5
+%endif
+    cmp          dst1q, dst8q
+    mov          dst1q, dst8q
+    jnz .next8px
+%else
+%ifidn %1, h
+    lea          dst1q, [dst1q+ strideq*8-5]
+%else ; v
+    add          dst1q, 8
+%endif
+    dec          cntrq
+    jg .next8px
+%endif
+    REP_RET
+%else ; mmsize == 16
+    RET
+%endif
+%endmacro
+
+%if ARCH_X86_32
+INIT_MMX mmx
+MBEDGE_LOOPFILTER v, 16
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER v,  8
+MBEDGE_LOOPFILTER h,  8
+
+INIT_MMX mmxext
+MBEDGE_LOOPFILTER v, 16
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER v,  8
+MBEDGE_LOOPFILTER h,  8
+%endif
+
+INIT_XMM sse2
+MBEDGE_LOOPFILTER v, 16
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER v,  8
+MBEDGE_LOOPFILTER h,  8
+
+INIT_XMM ssse3
+MBEDGE_LOOPFILTER v, 16
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER v,  8
+MBEDGE_LOOPFILTER h,  8
+
+INIT_XMM sse4
+MBEDGE_LOOPFILTER h, 16
+MBEDGE_LOOPFILTER h,  8
diff --git a/libavcodec/x86/vp9dsp.asm b/libavcodec/x86/vp9dsp.asm
new file mode 100644
index 0000000..6488f30
--- /dev/null
+++ b/libavcodec/x86/vp9dsp.asm
@@ -0,0 +1,277 @@
+;******************************************************************************
+;* VP9 SIMD optimizations
+;*
+;* Copyright (c) 2013 Ronald S. Bultje <rsbultje gmail com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+
+; FIXME share with vp8dsp.asm
+pw_256:   times 8 dw 256
+
+%macro F8_TAPS 8
+times 8 db %1, %2
+times 8 db %3, %4
+times 8 db %5, %6
+times 8 db %7, %8
+%endmacro
+; int8_t ff_filters_ssse3[3][15][4][16]
+const filters_ssse3 ; smooth
+                    F8_TAPS -3, -1,  32,  64,  38,   1, -3,  0
+                    F8_TAPS -2, -2,  29,  63,  41,   2, -3,  0
+                    F8_TAPS -2, -2,  26,  63,  43,   4, -4,  0
+                    F8_TAPS -2, -3,  24,  62,  46,   5, -4,  0
+                    F8_TAPS -2, -3,  21,  60,  49,   7, -4,  0
+                    F8_TAPS -1, -4,  18,  59,  51,   9, -4,  0
+                    F8_TAPS -1, -4,  16,  57,  53,  12, -4, -1
+                    F8_TAPS -1, -4,  14,  55,  55,  14, -4, -1
+                    F8_TAPS -1, -4,  12,  53,  57,  16, -4, -1
+                    F8_TAPS  0, -4,   9,  51,  59,  18, -4, -1
+                    F8_TAPS  0, -4,   7,  49,  60,  21, -3, -2
+                    F8_TAPS  0, -4,   5,  46,  62,  24, -3, -2
+                    F8_TAPS  0, -4,   4,  43,  63,  26, -2, -2
+                    F8_TAPS  0, -3,   2,  41,  63,  29, -2, -2
+                    F8_TAPS  0, -3,   1,  38,  64,  32, -1, -3
+                    ; regular
+                    F8_TAPS  0,  1,  -5, 126,   8,  -3,  1,  0
+                    F8_TAPS -1,  3, -10, 122,  18,  -6,  2,  0
+                    F8_TAPS -1,  4, -13, 118,  27,  -9,  3, -1
+                    F8_TAPS -1,  4, -16, 112,  37, -11,  4, -1
+                    F8_TAPS -1,  5, -18, 105,  48, -14,  4, -1
+                    F8_TAPS -1,  5, -19,  97,  58, -16,  5, -1
+                    F8_TAPS -1,  6, -19,  88,  68, -18,  5, -1
+                    F8_TAPS -1,  6, -19,  78,  78, -19,  6, -1
+                    F8_TAPS -1,  5, -18,  68,  88, -19,  6, -1
+                    F8_TAPS -1,  5, -16,  58,  97, -19,  5, -1
+                    F8_TAPS -1,  4, -14,  48, 105, -18,  5, -1
+                    F8_TAPS -1,  4, -11,  37, 112, -16,  4, -1
+                    F8_TAPS -1,  3,  -9,  27, 118, -13,  4, -1
+                    F8_TAPS  0,  2,  -6,  18, 122, -10,  3, -1
+                    F8_TAPS  0,  1,  -3,   8, 126,  -5,  1,  0
+                    ; sharp
+                    F8_TAPS -1,  3,  -7, 127,   8,  -3,  1,  0
+                    F8_TAPS -2,  5, -13, 125,  17,  -6,  3, -1
+                    F8_TAPS -3,  7, -17, 121,  27, -10,  5, -2
+                    F8_TAPS -4,  9, -20, 115,  37, -13,  6, -2
+                    F8_TAPS -4, 10, -23, 108,  48, -16,  8, -3
+                    F8_TAPS -4, 10, -24, 100,  59, -19,  9, -3
+                    F8_TAPS -4, 11, -24,  90,  70, -21, 10, -4
+                    F8_TAPS -4, 11, -23,  80,  80, -23, 11, -4
+                    F8_TAPS -4, 10, -21,  70,  90, -24, 11, -4
+                    F8_TAPS -3,  9, -19,  59, 100, -24, 10, -4
+                    F8_TAPS -3,  8, -16,  48, 108, -23, 10, -4
+                    F8_TAPS -2,  6, -13,  37, 115, -20,  9, -4
+                    F8_TAPS -2,  5, -10,  27, 121, -17,  7, -3
+                    F8_TAPS -1,  3,  -6,  17, 125, -13,  5, -2
+                    F8_TAPS  0,  1,  -3,   8, 127,  -7,  3, -1
+
+SECTION .text
+
+%macro filter_h_fn 1
+%assign %%px mmsize/2
+cglobal %1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filtery
+    mova        m6, [pw_256]
+    mova        m7, [filteryq+ 0]
+%if ARCH_X86_64 && mmsize > 8
+    mova        m8, [filteryq+16]
+    mova        m9, [filteryq+32]
+    mova       m10, [filteryq+48]
+%endif
+.loop:
+    movh        m0, [srcq-3]
+    movh        m1, [srcq-2]
+    movh        m2, [srcq-1]
+    movh        m3, [srcq+0]
+    movh        m4, [srcq+1]
+    movh        m5, [srcq+2]
+    punpcklbw   m0, m1
+    punpcklbw   m2, m3
+    movh        m1, [srcq+3]
+    movh        m3, [srcq+4]
+    add       srcq, sstrideq
+    punpcklbw   m4, m5
+    punpcklbw   m1, m3
+    pmaddubsw   m0, m7
+%if ARCH_X86_64 && mmsize > 8
+    pmaddubsw   m2, m8
+    pmaddubsw   m4, m9
+    pmaddubsw   m1, m10
+%else
+    pmaddubsw   m2, [filteryq+16]
+    pmaddubsw   m4, [filteryq+32]
+    pmaddubsw   m1, [filteryq+48]
+%endif
+    paddw       m0, m2
+    paddw       m4, m1
+    paddsw      m0, m4
+    pmulhrsw    m0, m6
+%ifidn %1, avg
+    movh        m1, [dstq]
+%endif
+    packuswb    m0, m0
+%ifidn %1, avg
+    pavgb       m0, m1
+%endif
+    movh    [dstq], m0
+    add       dstq, dstrideq
+    dec         hd
+    jg .loop
+    RET
+%endmacro
+
+INIT_MMX ssse3
+filter_h_fn put
+filter_h_fn avg
+
+INIT_XMM ssse3
+filter_h_fn put
+filter_h_fn avg
+
+%macro filter_v_fn 1
+%assign %%px mmsize/2
+%if ARCH_X86_64
+cglobal %1_8tap_1d_v_ %+ %%px, 6, 8, 11, dst, src, dstride, sstride, h, filtery, src4, sstride3
+%else
+cglobal %1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery, src4, sstride3
+    mov   filteryq, r5mp
+%define hd r4mp
+%endif
+    sub       srcq, sstrideq
+    lea  sstride3q, [sstrideq*3]
+    sub       srcq, sstrideq
+    mova        m6, [pw_256]
+    sub       srcq, sstrideq
+    mova        m7, [filteryq+ 0]
+    lea      src4q, [srcq+sstrideq*4]
+%if ARCH_X86_64 && mmsize > 8
+    mova        m8, [filteryq+16]
+    mova        m9, [filteryq+32]
+    mova       m10, [filteryq+48]
+%endif
+.loop:
+    ; FIXME maybe reuse loads from previous rows, or just more generally
+    ; unroll this to prevent multiple loads of the same data?
+    movh        m0, [srcq]
+    movh        m1, [srcq+sstrideq]
+    movh        m2, [srcq+sstrideq*2]
+    movh        m3, [srcq+sstride3q]
+    movh        m4, [src4q]
+    movh        m5, [src4q+sstrideq]
+    punpcklbw   m0, m1
+    punpcklbw   m2, m3
+    movh        m1, [src4q+sstrideq*2]
+    movh        m3, [src4q+sstride3q]
+    add       srcq, sstrideq
+    add      src4q, sstrideq
+    punpcklbw   m4, m5
+    punpcklbw   m1, m3
+    pmaddubsw   m0, m7
+%if ARCH_X86_64 && mmsize > 8
+    pmaddubsw   m2, m8
+    pmaddubsw   m4, m9
+    pmaddubsw   m1, m10
+%else
+    pmaddubsw   m2, [filteryq+16]
+    pmaddubsw   m4, [filteryq+32]
+    pmaddubsw   m1, [filteryq+48]
+%endif
+    paddw       m0, m2
+    paddw       m4, m1
+    paddsw      m0, m4
+    pmulhrsw    m0, m6
+%ifidn %1, avg
+    movh        m1, [dstq]
+%endif
+    packuswb    m0, m0
+%ifidn %1, avg
+    pavgb       m0, m1
+%endif
+    movh    [dstq], m0
+    add       dstq, dstrideq
+    dec         hd
+    jg .loop
+    RET
+%endmacro
+
+INIT_MMX ssse3
+filter_v_fn put
+filter_v_fn avg
+
+INIT_XMM ssse3
+filter_v_fn put
+filter_v_fn avg
+
+%macro fpel_fn 6
+%if %2 == 4
+%define %%srcfn movh
+%define %%dstfn movh
+%else
+%define %%srcfn movu
+%define %%dstfn mova
+%endif
+
+%if %2 <= 16
+cglobal %1%2, 5, 7, 4, dst, src, dstride, sstride, h, dstride3, sstride3
+    lea  sstride3q, [sstrideq*3]
+    lea  dstride3q, [dstrideq*3]
+%else
+cglobal %1%2, 5, 5, 4, dst, src, dstride, sstride, h
+%endif
+.loop:
+    %%srcfn     m0, [srcq]
+    %%srcfn     m1, [srcq+s%3]
+    %%srcfn     m2, [srcq+s%4]
+    %%srcfn     m3, [srcq+s%5]
+    lea       srcq, [srcq+sstrideq*%6]
+%ifidn %1, avg
+    pavgb       m0, [dstq]
+    pavgb       m1, [dstq+d%3]
+    pavgb       m2, [dstq+d%4]
+    pavgb       m3, [dstq+d%5]
+%endif
+    %%dstfn [dstq], m0
+    %%dstfn [dstq+d%3], m1
+    %%dstfn [dstq+d%4], m2
+    %%dstfn [dstq+d%5], m3
+    lea       dstq, [dstq+dstrideq*%6]
+    sub         hd, %6
+    jnz .loop
+    RET
+%endmacro
+
+%define d16 16
+%define s16 16
+INIT_MMX mmx
+fpel_fn put, 4,  strideq, strideq*2, stride3q, 4
+fpel_fn put, 8,  strideq, strideq*2, stride3q, 4
+INIT_MMX sse
+fpel_fn avg, 4,  strideq, strideq*2, stride3q, 4
+fpel_fn avg, 8,  strideq, strideq*2, stride3q, 4
+INIT_XMM sse
+fpel_fn put, 16, strideq, strideq*2, stride3q, 4
+fpel_fn put, 32, mmsize,  strideq,   strideq+mmsize, 2
+fpel_fn put, 64, mmsize,  mmsize*2,  mmsize*3, 1
+INIT_XMM sse2
+fpel_fn avg, 16, strideq, strideq*2, stride3q, 4
+fpel_fn avg, 32, mmsize,  strideq,   strideq+mmsize, 2
+fpel_fn avg, 64, mmsize,  mmsize*2,  mmsize*3, 1
+%undef s16
+%undef d16
diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c
new file mode 100644
index 0000000..540dc38
--- /dev/null
+++ b/libavcodec/x86/vp9dsp_init.c
@@ -0,0 +1,245 @@
+/*
+ * VP9 SIMD optimizations
+ *
+ * Copyright (c) 2013 Ronald S. Bultje <rsbultje at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/cpu.h"
+#include "libavutil/internal.h"
+#include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+#include "libavcodec/vp9.h"
+
+#if HAVE_YASM
+
+#define fpel_func(avg, sz, opt)                                         \
+void ff_ ## avg ## sz ## _ ## opt(uint8_t *dst, const uint8_t *src,     \
+                                  ptrdiff_t dst_stride,                 \
+                                  ptrdiff_t src_stride,                 \
+                                  int h, int mx, int my)
+
+fpel_func(put,  4, mmx);
+fpel_func(put,  8, mmx);
+fpel_func(put, 16, sse);
+fpel_func(put, 32, sse);
+fpel_func(put, 64, sse);
+fpel_func(avg,  4, sse);
+fpel_func(avg,  8, sse);
+fpel_func(avg, 16, sse2);
+fpel_func(avg, 32, sse2);
+fpel_func(avg, 64, sse2);
+#undef fpel_func
+
+#define mc_func(avg, sz, dir, opt)                                          \
+void                                                                        \
+ff_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst,         \
+                                                      const uint8_t *src,   \
+                                                      ptrdiff_t dst_stride, \
+                                                      ptrdiff_t src_stride, \
+                                                      int h,                \
+                                                      const int8_t (*filter)[16])
+
+#define mc_funcs(sz)            \
+    mc_func(put, sz, h, ssse3); \
+    mc_func(avg, sz, h, ssse3); \
+    mc_func(put, sz, v, ssse3); \
+    mc_func(avg, sz, v, ssse3)
+
+mc_funcs(4);
+mc_funcs(8);
+
+#undef mc_funcs
+#undef mc_func
+
+#define mc_rep_func(avg, sz, hsz, dir, opt)                                 \
+static av_always_inline void                                                \
+ff_ ## avg ## _8tap_1d_ ## dir ## _ ## sz ## _ ## opt(uint8_t *dst,         \
+                                                      const uint8_t *src,   \
+                                                      ptrdiff_t dst_stride, \
+                                                      ptrdiff_t src_stride, \
+                                                      int h,                \
+                                                      const int8_t (*filter)[16]) \
+{                                                                           \
+    ff_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst, src,        \
+                                                           dst_stride,      \
+                                                           src_stride,      \
+                                                           h,               \
+                                                           filter);         \
+    ff_ ## avg ## _8tap_1d_ ## dir ## _ ## hsz ## _ ## opt(dst + hsz,       \
+                                                           src + hsz,       \
+                                                           dst_stride,      \
+                                                           src_stride,      \
+                                                           h, filter);      \
+}
+
+#define mc_rep_funcs(sz, hsz)            \
+    mc_rep_func(put, sz, hsz, h, ssse3); \
+    mc_rep_func(avg, sz, hsz, h, ssse3); \
+    mc_rep_func(put, sz, hsz, v, ssse3); \
+    mc_rep_func(avg, sz, hsz, v, ssse3)
+
+mc_rep_funcs(16, 8);
+mc_rep_funcs(32, 16);
+mc_rep_funcs(64, 32);
+
+#undef mc_rep_funcs
+#undef mc_rep_func
+
+extern const int8_t ff_filters_ssse3[3][15][4][16];
+
+#define filter_8tap_2d_fn(op, sz, f, fname)                             \
+static void                                                             \
+op ## _8tap_ ## fname ## _ ## sz ## hv_ssse3(uint8_t *dst,              \
+                                             const uint8_t *src,        \
+                                             ptrdiff_t dst_stride,      \
+                                             ptrdiff_t src_stride,      \
+                                             int h, int mx, int my)     \
+{                                                                       \
+    LOCAL_ALIGNED_16(uint8_t, temp, [71 * 64]);                         \
+    ff_put_8tap_1d_h_ ## sz ## _ssse3(temp, src - 3 * src_stride,       \
+                                      64, src_stride,                   \
+                                      h + 7,                            \
+                                      ff_filters_ssse3[f][mx - 1]);     \
+    ff_ ## op ## _8tap_1d_v_ ## sz ## _ssse3(dst, temp + 3 * 64,        \
+                                             dst_stride, 64,            \
+                                             h,                         \
+                                             ff_filters_ssse3[f][my - 1]); \
+}
+
+#define filters_8tap_2d_fn(op, sz)                          \
+    filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, regular) \
+    filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, sharp)     \
+    filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth)
+
+#define filters_8tap_2d_fn2(op) \
+    filters_8tap_2d_fn(op, 64)  \
+    filters_8tap_2d_fn(op, 32)  \
+    filters_8tap_2d_fn(op, 16)  \
+    filters_8tap_2d_fn(op, 8)   \
+    filters_8tap_2d_fn(op, 4)
+
+filters_8tap_2d_fn2(put)
+filters_8tap_2d_fn2(avg)
+
+#undef filters_8tap_2d_fn2
+#undef filters_8tap_2d_fn
+#undef filter_8tap_2d_fn
+
+#define filter_8tap_1d_fn(op, sz, f, fname, dir, dvar)                  \
+static void                                                             \
+op ## _8tap_ ## fname ## _ ## sz ## dir ## _ssse3(uint8_t *dst,         \
+                                                  const uint8_t *src,   \
+                                                  ptrdiff_t dst_stride, \
+                                                  ptrdiff_t src_stride, \
+                                                  int h, int mx,        \
+                                                  int my)               \
+{                                                                       \
+    ff_ ## op ## _8tap_1d_ ## dir ## _ ## sz ## _ssse3(dst, src,        \
+                                                       dst_stride,      \
+                                                       src_stride, h,   \
+                                                       ff_filters_ssse3[f][dvar - 1]); \
+}
+
+#define filters_8tap_1d_fn(op, sz, dir, dvar)                          \
+    filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, regular, dir, dvar) \
+    filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, sharp, dir, dvar)     \
+    filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, smooth, dir, dvar)
+
+#define filters_8tap_1d_fn2(op, sz)             \
+    filters_8tap_1d_fn(op, sz, h, mx)           \
+    filters_8tap_1d_fn(op, sz, v, my)
+
+#define filters_8tap_1d_fn3(op) \
+    filters_8tap_1d_fn2(op, 64) \
+    filters_8tap_1d_fn2(op, 32) \
+    filters_8tap_1d_fn2(op, 16) \
+    filters_8tap_1d_fn2(op,  8) \
+    filters_8tap_1d_fn2(op,  4)
+
+filters_8tap_1d_fn3(put)
+filters_8tap_1d_fn3(avg)
+
+#undef filters_8tap_1d_fn
+#undef filters_8tap_1d_fn2
+#undef filters_8tap_1d_fn3
+#undef filter_8tap_1d_fn
+
+#endif /* HAVE_YASM */
+
+av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp)
+{
+#if HAVE_YASM
+    int cpu_flags = av_get_cpu_flags();
+
+#define init_fpel(idx1, idx2, sz, type, opt)                            \
+    dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] =                    \
+    dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] =                    \
+    dsp->mc[idx1][FILTER_8TAP_SHARP  ][idx2][0][0] =                    \
+    dsp->mc[idx1][FILTER_BILINEAR    ][idx2][0][0] = ff_ ## type ## sz ## _ ## opt
+
+
+#define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type, opt) \
+    dsp->mc[idx1][FILTER_8TAP_SMOOTH][idx2][idxh][idxv]  = type ## _8tap_smooth_  ## sz ## dir ## _ ## opt; \
+    dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type ## _8tap_regular_ ## sz ## dir ## _ ## opt; \
+    dsp->mc[idx1][FILTER_8TAP_SHARP][idx2][idxh][idxv]   = type ## _8tap_sharp_   ## sz ## dir ## _ ## opt
+
+#define init_subpel2(idx, idxh, idxv, dir, type, opt)     \
+    init_subpel1(0, idx, idxh, idxv, 64, dir, type, opt); \
+    init_subpel1(1, idx, idxh, idxv, 32, dir, type, opt); \
+    init_subpel1(2, idx, idxh, idxv, 16, dir, type, opt); \
+    init_subpel1(3, idx, idxh, idxv,  8, dir, type, opt); \
+    init_subpel1(4, idx, idxh, idxv,  4, dir, type, opt)
+
+#define init_subpel3(idx, type, opt)        \
+    init_subpel2(idx, 1, 1, hv, type, opt); \
+    init_subpel2(idx, 0, 1,  v, type, opt); \
+    init_subpel2(idx, 1, 0,  h, type, opt)
+
+    if (EXTERNAL_MMX(cpu_flags)) {
+        init_fpel(4, 0,  4, put, mmx);
+        init_fpel(3, 0,  8, put, mmx);
+    }
+
+    if (EXTERNAL_SSE(cpu_flags)) {
+        init_fpel(2, 0, 16, put, sse);
+        init_fpel(1, 0, 32, put, sse);
+        init_fpel(0, 0, 64, put, sse);
+        init_fpel(4, 1,  4, avg, sse);
+        init_fpel(3, 1,  8, avg, sse);
+    }
+
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        init_fpel(2, 1, 16, avg, sse2);
+        init_fpel(1, 1, 32, avg, sse2);
+        init_fpel(0, 1, 64, avg, sse2);
+    }
+
+    if (EXTERNAL_SSSE3(cpu_flags)) {
+        init_subpel3(0, put, ssse3);
+        init_subpel3(1, avg, ssse3);
+    }
+
+#undef init_fpel
+#undef init_subpel1
+#undef init_subpel2
+#undef init_subpel3
+
+#endif /* HAVE_YASM */
+}
diff --git a/libavcodec/x86/w64xmmtest.c b/libavcodec/x86/w64xmmtest.c
index f6e3de9..2f064ca 100644
--- a/libavcodec/x86/w64xmmtest.c
+++ b/libavcodec/x86/w64xmmtest.c
@@ -65,16 +65,15 @@ wrap(avcodec_encode_audio2(AVCodecContext *avctx,
                     got_packet_ptr);
 }
 
-wrap(avcodec_encode_video(AVCodecContext *avctx,
-                          uint8_t *buf, int buf_size,
-                          const AVFrame *pict))
-{
-    testxmmclobbers(avcodec_encode_video, avctx, buf, buf_size, pict);
-}
-
 wrap(avcodec_encode_subtitle(AVCodecContext *avctx,
                              uint8_t *buf, int buf_size,
                              const AVSubtitle *sub))
 {
     testxmmclobbers(avcodec_encode_subtitle, avctx, buf, buf_size, sub);
 }
+
+wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
+                           const AVFrame *frame, int *got_packet_ptr))
+{
+    testxmmclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr);
+}
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index 369f89b..4bf1d87 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -52,8 +52,7 @@
 typedef struct XanContext {
 
     AVCodecContext *avctx;
-    AVFrame last_frame;
-    AVFrame current_frame;
+    AVFrame *last_frame;
 
     const unsigned char *buf;
     int size;
@@ -72,6 +71,19 @@ typedef struct XanContext {
 
 } XanContext;
 
+static av_cold int xan_decode_end(AVCodecContext *avctx)
+{
+    XanContext *s = avctx->priv_data;
+
+    av_frame_free(&s->last_frame);
+
+    av_freep(&s->buffer1);
+    av_freep(&s->buffer2);
+    av_freep(&s->palettes);
+
+    return 0;
+}
+
 static av_cold int xan_decode_init(AVCodecContext *avctx)
 {
     XanContext *s = avctx->priv_data;
@@ -92,6 +104,12 @@ static av_cold int xan_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
+    s->last_frame = av_frame_alloc();
+    if (!s->last_frame) {
+        xan_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
@@ -115,7 +133,7 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len,
     while (val != 0x16) {
         unsigned idx = val - 0x17 + get_bits1(&gb) * byte;
         if (idx >= 2 * byte)
-            return -1;
+            return AVERROR_INVALIDDATA;
         val = src[idx];
 
         if (val < 0x16) {
@@ -141,51 +159,54 @@ static void xan_unpack(unsigned char *dest, int dest_len,
     int size;
     unsigned char *dest_org = dest;
     unsigned char *dest_end = dest + dest_len;
-    const unsigned char *src_end = src + src_len;
+    GetByteContext ctx;
 
-    while (dest < dest_end && src < src_end) {
-        opcode = *src++;
+    bytestream2_init(&ctx, src, src_len);
+    while (dest < dest_end && bytestream2_get_bytes_left(&ctx)) {
+        opcode = bytestream2_get_byte(&ctx);
 
         if (opcode < 0xe0) {
             int size2, back;
             if ((opcode & 0x80) == 0) {
                 size = opcode & 3;
 
-                back  = ((opcode & 0x60) << 3) + *src++ + 1;
+                back  = ((opcode & 0x60) << 3) + bytestream2_get_byte(&ctx) + 1;
                 size2 = ((opcode & 0x1c) >> 2) + 3;
             } else if ((opcode & 0x40) == 0) {
-                size = *src >> 6;
+                size = bytestream2_peek_byte(&ctx) >> 6;
 
-                back  = (bytestream_get_be16(&src) & 0x3fff) + 1;
+                back  = (bytestream2_get_be16(&ctx) & 0x3fff) + 1;
                 size2 = (opcode & 0x3f) + 4;
             } else {
                 size = opcode & 3;
 
-                back  = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1;
-                size2 = ((opcode & 0x0c) <<  6) + *src++ + 5;
+                back  = ((opcode & 0x10) << 12) + bytestream2_get_be16(&ctx) + 1;
+                size2 = ((opcode & 0x0c) <<  6) + bytestream2_get_byte(&ctx) + 5;
             }
 
             if (dest_end - dest < size + size2 ||
                 dest + size - dest_org < back ||
-                src_end - src < size)
+                bytestream2_get_bytes_left(&ctx) < size)
                 return;
-            memcpy(dest, src, size);  dest += size;  src += size;
+            bytestream2_get_buffer(&ctx, dest, size);
+            dest += size;
             av_memcpy_backptr(dest, back, size2);
             dest += size2;
         } else {
             int finish = opcode >= 0xfc;
             size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
 
-            if (dest_end - dest < size || src_end - src < size)
+            if (dest_end - dest < size || bytestream2_get_bytes_left(&ctx) < size)
                 return;
-            memcpy(dest, src, size);  dest += size;  src += size;
+            bytestream2_get_buffer(&ctx, dest, size);
+            dest += size;
             if (finish)
                 return;
         }
     }
 }
 
-static inline void xan_wc3_output_pixel_run(XanContext *s,
+static inline void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame,
     const unsigned char *pixel_buffer, int x, int y, int pixel_count)
 {
     int stride;
@@ -195,8 +216,8 @@ static inline void xan_wc3_output_pixel_run(XanContext *s,
     int width = s->avctx->width;
     unsigned char *palette_plane;
 
-    palette_plane = s->current_frame.data[0];
-    stride = s->current_frame.linesize[0];
+    palette_plane = frame->data[0];
+    stride = frame->linesize[0];
     line_inc = stride - width;
     index = y * stride + x;
     current_x = x;
@@ -215,7 +236,8 @@ static inline void xan_wc3_output_pixel_run(XanContext *s,
     }
 }
 
-static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y,
+static inline void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame,
+                                          int x, int y,
                                           int pixel_count, int motion_x,
                                           int motion_y)
 {
@@ -230,11 +252,11 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y,
         x + motion_x < 0 || x + motion_x >= s->avctx->width)
         return;
 
-    palette_plane = s->current_frame.data[0];
-    prev_palette_plane = s->last_frame.data[0];
+    palette_plane = frame->data[0];
+    prev_palette_plane = s->last_frame->data[0];
     if (!prev_palette_plane)
         prev_palette_plane = palette_plane;
-    stride = s->current_frame.linesize[0];
+    stride = frame->linesize[0];
     line_inc = stride - width;
     curframe_index = y * stride + x;
     curframe_x = x;
@@ -266,7 +288,8 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y,
     }
 }
 
-static int xan_wc3_decode_frame(XanContext *s) {
+static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
+{
 
     int width  = s->avctx->width;
     int height = s->avctx->height;
@@ -380,12 +403,12 @@ static int xan_wc3_decode_frame(XanContext *s) {
             flag ^= 1;
             if (flag) {
                 /* run of (size) pixels is unchanged from last frame */
-                xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
+                xan_wc3_copy_pixel_run(s, frame, x, y, size, 0, 0);
             } else {
                 /* output a run of pixels from imagedata_buffer */
                 if (imagedata_size < size)
                     break;
-                xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
+                xan_wc3_output_pixel_run(s, frame, imagedata_buffer, x, y, size);
                 imagedata_buffer += size;
                 imagedata_size -= size;
             }
@@ -396,7 +419,7 @@ static int xan_wc3_decode_frame(XanContext *s) {
             motion_y = sign_extend(vector & 0xF, 4);
 
             /* copy a run of pixels from the previous frame */
-            xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
+            xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y);
 
             flag = 0;
         }
@@ -496,20 +519,22 @@ static int xan_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int ret, buf_size = avpkt->size;
     XanContext *s = avctx->priv_data;
-    const uint8_t *buf_end = buf + buf_size;
+    GetByteContext ctx;
     int tag = 0;
 
-    while (buf_end - buf > 8 && tag != VGA__TAG) {
+    bytestream2_init(&ctx, buf, buf_size);
+    while (bytestream2_get_bytes_left(&ctx) > 8 && tag != VGA__TAG) {
         unsigned *tmpptr;
         uint32_t new_pal;
         int size;
         int i;
-        tag  = bytestream_get_le32(&buf);
-        size = bytestream_get_be32(&buf);
-        size = FFMIN(size, buf_end - buf);
+        tag  = bytestream2_get_le32(&ctx);
+        size = bytestream2_get_be32(&ctx);
+        size = FFMIN(size, bytestream2_get_bytes_left(&ctx));
         switch (tag) {
         case PALT_TAG:
             if (size < PALETTE_SIZE)
@@ -524,13 +549,13 @@ static int xan_decode_frame(AVCodecContext *avctx,
             tmpptr += s->palettes_count * AVPALETTE_COUNT;
             for (i = 0; i < PALETTE_COUNT; i++) {
 #if RUNTIME_GAMMA
-                int r = gamma_corr(*buf++);
-                int g = gamma_corr(*buf++);
-                int b = gamma_corr(*buf++);
+                int r = gamma_corr(bytestream2_get_byteu(&ctx));
+                int g = gamma_corr(bytestream2_get_byteu(&ctx));
+                int b = gamma_corr(bytestream2_get_byteu(&ctx));
 #else
-                int r = gamma_lookup[*buf++];
-                int g = gamma_lookup[*buf++];
-                int b = gamma_lookup[*buf++];
+                int r = gamma_lookup[bytestream2_get_byteu(&ctx)];
+                int g = gamma_lookup[bytestream2_get_byteu(&ctx)];
+                int b = gamma_lookup[bytestream2_get_byteu(&ctx)];
 #endif
                 *tmpptr++ = (r << 16) | (g << 8) | b;
             }
@@ -539,7 +564,7 @@ static int xan_decode_frame(AVCodecContext *avctx,
         case SHOT_TAG:
             if (size < 4)
                 return AVERROR_INVALIDDATA;
-            new_pal = bytestream_get_le32(&buf);
+            new_pal = bytestream2_get_le32(&ctx);
             if (new_pal < s->palettes_count) {
                 s->cur_palette = new_pal;
             } else
@@ -548,68 +573,47 @@ static int xan_decode_frame(AVCodecContext *avctx,
         case VGA__TAG:
             break;
         default:
-            buf += size;
+            bytestream2_skip(&ctx, size);
             break;
         }
     }
-    buf_size = buf_end - buf;
+    buf_size = bytestream2_get_bytes_left(&ctx);
 
     if (s->palettes_count <= 0) {
         av_log(s->avctx, AV_LOG_ERROR, "No palette found\n");
         return AVERROR_INVALIDDATA;
     }
 
-    if ((ret = ff_get_buffer(avctx, &s->current_frame))) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF))) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    s->current_frame.reference = 3;
 
     if (!s->frame_size)
-        s->frame_size = s->current_frame.linesize[0] * s->avctx->height;
+        s->frame_size = frame->linesize[0] * s->avctx->height;
 
-    memcpy(s->current_frame.data[1],
+    memcpy(frame->data[1],
            s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
 
-    s->buf = buf;
+    s->buf = ctx.buffer;
     s->size = buf_size;
 
-    if (xan_wc3_decode_frame(s) < 0)
+    if (xan_wc3_decode_frame(s, frame) < 0)
         return AVERROR_INVALIDDATA;
 
-    /* release the last frame if it is allocated */
-    if (s->last_frame.data[0])
-        avctx->release_buffer(avctx, &s->last_frame);
+    av_frame_unref(s->last_frame);
+    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame*)data = s->current_frame;
-
-    /* shuffle frames */
-    FFSWAP(AVFrame, s->current_frame, s->last_frame);
 
     /* always report that the buffer was completely consumed */
     return buf_size;
 }
 
-static av_cold int xan_decode_end(AVCodecContext *avctx)
-{
-    XanContext *s = avctx->priv_data;
-
-    /* release the frames */
-    if (s->last_frame.data[0])
-        avctx->release_buffer(avctx, &s->last_frame);
-    if (s->current_frame.data[0])
-        avctx->release_buffer(avctx, &s->current_frame);
-
-    av_freep(&s->buffer1);
-    av_freep(&s->buffer2);
-    av_freep(&s->palettes);
-
-    return 0;
-}
-
 AVCodec ff_xan_wc3_decoder = {
     .name           = "xan_wc3",
+    .long_name      = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_XAN_WC3,
     .priv_data_size = sizeof(XanContext),
@@ -617,5 +621,4 @@ AVCodec ff_xan_wc3_decoder = {
     .close          = xan_decode_end,
     .decode         = xan_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"),
 };
diff --git a/libavcodec/xbmenc.c b/libavcodec/xbmenc.c
index e12debe..d6657dc 100644
--- a/libavcodec/xbmenc.c
+++ b/libavcodec/xbmenc.c
@@ -26,7 +26,7 @@
 
 static av_cold int xbm_encode_init(AVCodecContext *avctx)
 {
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame)
         return AVERROR(ENOMEM);
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
@@ -76,6 +76,7 @@ static av_cold int xbm_encode_close(AVCodecContext *avctx)
 
 AVCodec ff_xbm_encoder = {
     .name         = "xbm",
+    .long_name    = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"),
     .type         = AVMEDIA_TYPE_VIDEO,
     .id           = AV_CODEC_ID_XBM,
     .init         = xbm_encode_init,
@@ -83,5 +84,4 @@ AVCodec ff_xbm_encoder = {
     .close        = xbm_encode_close,
     .pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_MONOWHITE,
                                                  AV_PIX_FMT_NONE },
-    .long_name    = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"),
 };
diff --git a/libavcodec/xl.c b/libavcodec/xl.c
index 240339e..8e9bdc6 100644
--- a/libavcodec/xl.c
+++ b/libavcodec/xl.c
@@ -29,48 +29,26 @@
 #include "avcodec.h"
 #include "internal.h"
 
-typedef struct VideoXLContext{
-    AVCodecContext *avctx;
-    AVFrame pic;
-} VideoXLContext;
-
 static const int xl_table[32] = {
    0,   1,   2,   3,   4,   5,   6,   7,
    8,   9,  12,  15,  20,  25,  34,  46,
   64,  82,  94, 103, 108, 113, 116, 119,
- 120, 121, 122, 123, 124, 125, 126, 127};
+ 120, 121, 122, 123, 124, 125, 126, 127
+};
 
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
-    VideoXLContext * const a = avctx->priv_data;
-    AVFrame * const p = &a->pic;
+    int buf_size       = avpkt->size;
+    AVFrame *const p   = data;
     uint8_t *Y, *U, *V;
-    int i, j;
+    int i, j, ret;
     int stride;
     uint32_t val;
     int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if(ff_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;
-
-    Y = a->pic.data[0];
-    U = a->pic.data[1];
-    V = a->pic.data[2];
-
-    stride = avctx->width - 4;
-
     if (avctx->width % 4) {
         av_log(avctx, AV_LOG_ERROR, "Width not a multiple of 4.\n");
         return AVERROR_INVALIDDATA;
@@ -81,33 +59,46 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
+
+    Y = p->data[0];
+    U = p->data[1];
+    V = p->data[2];
+
+    stride = avctx->width - 4;
+
     for (i = 0; i < avctx->height; i++) {
         /* lines are stored in reversed order */
         buf += stride;
 
         for (j = 0; j < avctx->width; j += 4) {
             /* value is stored in LE dword with word swapped */
-            val = AV_RL32(buf);
+            val  = AV_RL32(buf);
             buf -= 4;
-            val = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16);
+            val  = ((val >> 16) & 0xFFFF) | ((val & 0xFFFF) << 16);
 
-            if(!j)
+            if (!j)
                 y0 = (val & 0x1F) << 2;
             else
                 y0 = y3 + xl_table[val & 0x1F];
             val >>= 5;
-            y1 = y0 + xl_table[val & 0x1F];
+            y1    = y0 + xl_table[val & 0x1F];
             val >>= 5;
-            y2 = y1 + xl_table[val & 0x1F];
+            y2    = y1 + xl_table[val & 0x1F];
             val >>= 6; /* align to word */
-            y3 = y2 + xl_table[val & 0x1F];
+            y3    = y2 + xl_table[val & 0x1F];
             val >>= 5;
-            if(!j)
+            if (!j)
                 c0 = (val & 0x1F) << 2;
             else
                 c0 += xl_table[val & 0x1F];
             val >>= 5;
-            if(!j)
+            if (!j)
                 c1 = (val & 0x1F) << 2;
             else
                 c1 += xl_table[val & 0x1F];
@@ -122,43 +113,29 @@ static int decode_frame(AVCodecContext *avctx,
         }
 
         buf += avctx->width + 4;
-        Y += a->pic.linesize[0];
-        U += a->pic.linesize[1];
-        V += a->pic.linesize[2];
+        Y   += p->linesize[0];
+        U   += p->linesize[1];
+        V   += p->linesize[2];
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = a->pic;
 
     return buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx){
-//    VideoXLContext * const a = avctx->priv_data;
-
-    avctx->pix_fmt= AV_PIX_FMT_YUV411P;
-
-    return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx){
-    VideoXLContext * const a = avctx->priv_data;
-    AVFrame *pic = &a->pic;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt = AV_PIX_FMT_YUV411P;
 
     return 0;
 }
 
 AVCodec ff_xl_decoder = {
-    .name           = "xl",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_VIXL,
-    .priv_data_size = sizeof(VideoXLContext),
-    .init           = decode_init,
-    .close          = decode_end,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
+    .name         = "xl",
+    .long_name    = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_VIXL,
+    .init         = decode_init,
+    .decode       = decode_frame,
+    .capabilities = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index 11e1d57..3d85973 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -138,9 +138,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 
 AVCodec ff_xsub_decoder = {
     .name      = "xsub",
+    .long_name = NULL_IF_CONFIG_SMALL("XSUB"),
     .type      = AVMEDIA_TYPE_SUBTITLE,
     .id        = AV_CODEC_ID_XSUB,
     .init      = decode_init,
     .decode    = decode_frame,
-    .long_name = NULL_IF_CONFIG_SMALL("XSUB"),
 };
diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c
index 816e651..fc46fb8 100644
--- a/libavcodec/xsubenc.c
+++ b/libavcodec/xsubenc.c
@@ -211,9 +211,9 @@ static av_cold int xsub_encoder_init(AVCodecContext *avctx)
 
 AVCodec ff_xsub_encoder = {
     .name       = "xsub",
+    .long_name  = NULL_IF_CONFIG_SMALL("DivX subtitles (XSUB)"),
     .type       = AVMEDIA_TYPE_SUBTITLE,
     .id         = AV_CODEC_ID_XSUB,
     .init       = xsub_encoder_init,
     .encode_sub = xsub_encode,
-    .long_name  = NULL_IF_CONFIG_SMALL("DivX subtitles (XSUB)"),
 };
diff --git a/libavcodec/xvmc.h b/libavcodec/xvmc.h
index 1f77e4e..950ed18 100644
--- a/libavcodec/xvmc.h
+++ b/libavcodec/xvmc.h
@@ -29,8 +29,12 @@
 
 #include <X11/extensions/XvMC.h>
 
+#include "libavutil/attributes.h"
+#include "version.h"
 #include "avcodec.h"
 
+#if FF_API_XVMC
+
 /**
  * @defgroup lavc_codec_hwaccel_xvmc XvMC
  * @ingroup lavc_codec_hwaccel
@@ -41,7 +45,7 @@
 #define AV_XVMC_ID                    0x1DC711C0  /**< special value to ensure that regular pixel routines haven't corrupted the struct
                                                        the number is 1337 speak for the letters IDCT MCo (motion compensation) */
 
-struct xvmc_pix_fmt {
+attribute_deprecated struct xvmc_pix_fmt {
     /** The field contains the special constant value AV_XVMC_ID.
         It is used as a test that the application correctly uses the API,
         and that there is no corruption caused by pixel routines.
@@ -165,4 +169,6 @@ struct xvmc_pix_fmt {
  * @}
  */
 
+#endif /* FF_API_XVMC */
+
 #endif /* AVCODEC_XVMC_H */
diff --git a/libavcodec/xvmc_internal.h b/libavcodec/xvmc_internal.h
index 3c6aed8..9018e4a 100644
--- a/libavcodec/xvmc_internal.h
+++ b/libavcodec/xvmc_internal.h
@@ -23,6 +23,9 @@
 
 #include "avcodec.h"
 #include "mpegvideo.h"
+#include "version.h"
+
+#if FF_API_XVMC
 
 void ff_xvmc_init_block(MpegEncContext *s);
 void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp);
@@ -30,4 +33,6 @@ int  ff_xvmc_field_start(MpegEncContext*s, AVCodecContext *avctx);
 void ff_xvmc_field_end(MpegEncContext *s);
 void ff_xvmc_decode_mb(MpegEncContext *s);
 
+#endif /* FF_API_XVMC */
+
 #endif /* AVCODEC_XVMC_INTERNAL_H */
diff --git a/libavcodec/xwddec.c b/libavcodec/xwddec.c
index 274e4fa..8963c96 100644
--- a/libavcodec/xwddec.c
+++ b/libavcodec/xwddec.c
@@ -26,19 +26,10 @@
 #include "internal.h"
 #include "xwd.h"
 
-static av_cold int xwd_decode_init(AVCodecContext *avctx)
-{
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
-    return 0;
-}
-
 static int xwd_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *p = avctx->coded_frame;
+    AVFrame *p = data;
     const uint8_t *buf = avpkt->data;
     int i, ret, buf_size = avpkt->size;
     uint32_t version, header_size, vclass, ncolors;
@@ -101,7 +92,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     if (xoffset) {
-        av_log_ask_for_sample(avctx, "unsupported xoffset %d\n", xoffset);
+        avpriv_request_sample(avctx, "xoffset %d", xoffset);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -201,15 +192,13 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
-        av_log_ask_for_sample(avctx, "unknown file: bpp %d, pixdepth %d, vclass %d\n", bpp, pixdepth, vclass);
+        avpriv_request_sample(avctx,
+                              "Unknown file: bpp %d, pixdepth %d, vclass %d",
+                              bpp, pixdepth, vclass);
         return AVERROR_PATCHWELCOME;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -243,28 +232,15 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame       = 1;
-    *(AVFrame *)data = *p;
 
     return buf_size;
 }
 
-static av_cold int xwd_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_xwd_decoder = {
     .name           = "xwd",
+    .long_name      = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_XWD,
-    .init           = xwd_decode_init,
-    .close          = xwd_decode_close,
     .decode         = xwd_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
 };
diff --git a/libavcodec/xwdenc.c b/libavcodec/xwdenc.c
index c9a2a56..54599a0 100644
--- a/libavcodec/xwdenc.c
+++ b/libavcodec/xwdenc.c
@@ -32,7 +32,7 @@
 
 static av_cold int xwd_encode_init(AVCodecContext *avctx)
 {
-    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame = av_frame_alloc();
     if (!avctx->coded_frame)
         return AVERROR(ENOMEM);
 
@@ -51,7 +51,7 @@ static int xwd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     uint8_t *ptr, *buf;
 
     pixdepth = av_get_bits_per_pixel(desc);
-    if (desc->flags & PIX_FMT_BE)
+    if (desc->flags & AV_PIX_FMT_FLAG_BE)
         be = 1;
     switch (pix_fmt) {
     case AV_PIX_FMT_ARGB:
@@ -222,6 +222,7 @@ static av_cold int xwd_encode_close(AVCodecContext *avctx)
 
 AVCodec ff_xwd_encoder = {
     .name         = "xwd",
+    .long_name    = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
     .type         = AVMEDIA_TYPE_VIDEO,
     .id           = AV_CODEC_ID_XWD,
     .init         = xwd_encode_init,
@@ -248,5 +249,4 @@ AVCodec ff_xwd_encoder = {
                                                  AV_PIX_FMT_PAL8,
                                                  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 7a0cdc4..d77a50f 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -26,10 +26,11 @@
 #include "bytestream.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 
 typedef struct XanContext {
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *pic;
 
     uint8_t *y_buffer;
     uint8_t *scratch_buffer;
@@ -37,6 +38,18 @@ typedef struct XanContext {
     GetByteContext gb;
 } XanContext;
 
+static av_cold int xan_decode_end(AVCodecContext *avctx)
+{
+    XanContext *s = avctx->priv_data;
+
+    av_frame_free(&s->pic);
+
+    av_freep(&s->y_buffer);
+    av_freep(&s->scratch_buffer);
+
+    return 0;
+}
+
 static av_cold int xan_decode_init(AVCodecContext *avctx)
 {
     XanContext *s = avctx->priv_data;
@@ -64,6 +77,12 @@ static av_cold int xan_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
+    s->pic = av_frame_alloc();
+    if (!s->pic) {
+        xan_decode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
@@ -142,7 +161,7 @@ static int xan_unpack(XanContext *s,
             }
             if (dest + size + size2 > dest_end ||
                 dest - orig_dest + size < back)
-                return -1;
+                return AVERROR_INVALIDDATA;
             bytestream2_get_buffer(&s->gb, dest, size);
             dest += size;
             av_memcpy_backptr(dest, back, size2);
@@ -152,7 +171,7 @@ static int xan_unpack(XanContext *s,
 
             size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4;
             if (dest_end - dest < size)
-                return -1;
+                return AVERROR_INVALIDDATA;
             bytestream2_get_buffer(&s->gb, dest, size);
             dest += size;
             if (finish)
@@ -176,7 +195,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
         return 0;
     if (chroma_off + 4 >= bytestream2_get_bytes_left(&s->gb)) {
         av_log(avctx, AV_LOG_ERROR, "Invalid chroma block position\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET);
     mode        = bytestream2_get_le16(&s->gb);
@@ -187,7 +206,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
 
     if (offset >= bytestream2_get_bytes_left(&s->gb)) {
         av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     bytestream2_skip(&s->gb, offset);
@@ -195,11 +214,11 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
     dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
     if (dec_size < 0) {
         av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n");
-        return -1;
+        return dec_size;
     }
 
-    U = s->pic.data[1];
-    V = s->pic.data[2];
+    U = s->pic->data[1];
+    V = s->pic->data[2];
     src     = s->scratch_buffer;
     src_end = src + dec_size;
     if (mode) {
@@ -216,16 +235,16 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
                 if (src == src_end)
                     return 0;
             }
-            U += s->pic.linesize[1];
-            V += s->pic.linesize[2];
+            U += s->pic->linesize[1];
+            V += s->pic->linesize[2];
         }
         if (avctx->height & 1) {
-            memcpy(U, U - s->pic.linesize[1], avctx->width >> 1);
-            memcpy(V, V - s->pic.linesize[2], avctx->width >> 1);
+            memcpy(U, U - s->pic->linesize[1], avctx->width >> 1);
+            memcpy(V, V - s->pic->linesize[2], avctx->width >> 1);
         }
     } else {
-        uint8_t *U2 = U + s->pic.linesize[1];
-        uint8_t *V2 = V + s->pic.linesize[2];
+        uint8_t *U2 = U + s->pic->linesize[1];
+        uint8_t *V2 = V + s->pic->linesize[2];
 
         for (j = 0; j < avctx->height >> 2; j++) {
             for (i = 0; i < avctx->width >> 1; i += 2) {
@@ -238,16 +257,16 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
                     V[i] = V[i+1] = V2[i] = V2[i+1] = vval | (vval >> 5);
                 }
             }
-            U  += s->pic.linesize[1] * 2;
-            V  += s->pic.linesize[2] * 2;
-            U2 += s->pic.linesize[1] * 2;
-            V2 += s->pic.linesize[2] * 2;
+            U  += s->pic->linesize[1] * 2;
+            V  += s->pic->linesize[2] * 2;
+            U2 += s->pic->linesize[1] * 2;
+            V2 += s->pic->linesize[2] * 2;
         }
         if (avctx->height & 3) {
             int lines = ((avctx->height + 1) >> 1) - (avctx->height >> 2) * 2;
 
-            memcpy(U, U - lines * s->pic.linesize[1], lines * s->pic.linesize[1]);
-            memcpy(V, V - lines * s->pic.linesize[2], lines * s->pic.linesize[2]);
+            memcpy(U, U - lines * s->pic->linesize[1], lines * s->pic->linesize[1]);
+            memcpy(V, V - lines * s->pic->linesize[2], lines * s->pic->linesize[2]);
         }
     }
 
@@ -319,12 +338,12 @@ static int xan_decode_frame_type0(AVCodecContext *avctx)
     }
 
     src  = s->y_buffer;
-    ybuf = s->pic.data[0];
+    ybuf = s->pic->data[0];
     for (j = 0; j < avctx->height; j++) {
         for (i = 0; i < avctx->width; i++)
             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
         src  += avctx->width;
-        ybuf += s->pic.linesize[0];
+        ybuf += s->pic->linesize[0];
     }
 
     return 0;
@@ -364,12 +383,12 @@ static int xan_decode_frame_type1(AVCodecContext *avctx)
     }
 
     src = s->y_buffer;
-    ybuf = s->pic.data[0];
+    ybuf = s->pic->data[0];
     for (j = 0; j < avctx->height; j++) {
         for (i = 0; i < avctx->width; i++)
             ybuf[i] = (src[i] << 2) | (src[i] >> 3);
         src  += avctx->width;
-        ybuf += s->pic.linesize[0];
+        ybuf += s->pic->linesize[0];
     }
 
     return 0;
@@ -383,11 +402,7 @@ static int xan_decode_frame(AVCodecContext *avctx,
     int ftype;
     int ret;
 
-    s->pic.reference = 1;
-    s->pic.buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->pic))) {
+    if ((ret = ff_reget_buffer(avctx, s->pic))) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -403,32 +418,22 @@ static int xan_decode_frame(AVCodecContext *avctx,
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (ret)
         return ret;
 
+    if ((ret = av_frame_ref(data, s->pic)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->pic;
 
     return avpkt->size;
 }
 
-static av_cold int xan_decode_end(AVCodecContext *avctx)
-{
-    XanContext *s = avctx->priv_data;
-
-    if (s->pic.data[0])
-        avctx->release_buffer(avctx, &s->pic);
-
-    av_freep(&s->y_buffer);
-    av_freep(&s->scratch_buffer);
-
-    return 0;
-}
-
 AVCodec ff_xan_wc4_decoder = {
     .name           = "xan_wc4",
+    .long_name      = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_XAN_WC4,
     .priv_data_size = sizeof(XanContext),
@@ -436,5 +441,4 @@ AVCodec ff_xan_wc4_decoder = {
     .close          = xan_decode_end,
     .decode         = xan_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"),
 };
diff --git a/libavcodec/yop.c b/libavcodec/yop.c
index e02b9bf..3434fd9 100644
--- a/libavcodec/yop.c
+++ b/libavcodec/yop.c
@@ -30,7 +30,6 @@
 #include "internal.h"
 
 typedef struct YopDecContext {
-    AVFrame frame;
     AVCodecContext *avctx;
 
     int num_pal_colors;
@@ -87,7 +86,7 @@ static av_cold int yop_decode_init(AVCodecContext *avctx)
     if (avctx->width & 1 || avctx->height & 1 ||
         av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
         av_log(avctx, AV_LOG_ERROR, "YOP has invalid dimensions\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (avctx->extradata_size < 3) {
@@ -111,30 +110,22 @@ static av_cold int yop_decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int yop_decode_close(AVCodecContext *avctx)
-{
-    YopDecContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-    return 0;
-}
-
 /**
  * Paint a macroblock using the pattern in paint_lut.
  * @param s codec context
  * @param tag the tag that was in the nibble
  */
-static int yop_paint_block(YopDecContext *s, int tag)
+static int yop_paint_block(YopDecContext *s, int linesize, int tag)
 {
     if (s->src_end - s->srcptr < paint_lut[tag][3]) {
         av_log(s->avctx, AV_LOG_ERROR, "Packet too small.\n");
         return AVERROR_INVALIDDATA;
     }
 
-    s->dstptr[0]                        = s->srcptr[0];
-    s->dstptr[1]                        = s->srcptr[paint_lut[tag][0]];
-    s->dstptr[s->frame.linesize[0]]     = s->srcptr[paint_lut[tag][1]];
-    s->dstptr[s->frame.linesize[0] + 1] = s->srcptr[paint_lut[tag][2]];
+    s->dstptr[0]            = s->srcptr[0];
+    s->dstptr[1]            = s->srcptr[paint_lut[tag][0]];
+    s->dstptr[linesize]     = s->srcptr[paint_lut[tag][1]];
+    s->dstptr[linesize + 1] = s->srcptr[paint_lut[tag][2]];
 
     // The number of src bytes consumed is in the last part of the lut entry.
     s->srcptr += paint_lut[tag][3];
@@ -145,23 +136,23 @@ static int yop_paint_block(YopDecContext *s, int tag)
  * Copy a previously painted macroblock to the current_block.
  * @param copy_tag the tag that was in the nibble
  */
-static int yop_copy_previous_block(YopDecContext *s, int copy_tag)
+static int yop_copy_previous_block(YopDecContext *s, int linesize, int copy_tag)
 {
     uint8_t *bufptr;
 
     // Calculate position for the copy source
     bufptr = s->dstptr + motion_vector[copy_tag][0] +
-             s->frame.linesize[0] * motion_vector[copy_tag][1];
+             linesize * motion_vector[copy_tag][1];
     if (bufptr < s->dstbuf) {
         av_log(s->avctx, AV_LOG_ERROR,
                "YOP: cannot decode, file probably corrupt\n");
         return AVERROR_INVALIDDATA;
     }
 
-    s->dstptr[0]                        = bufptr[0];
-    s->dstptr[1]                        = bufptr[1];
-    s->dstptr[s->frame.linesize[0]]     = bufptr[s->frame.linesize[0]];
-    s->dstptr[s->frame.linesize[0] + 1] = bufptr[s->frame.linesize[0] + 1];
+    s->dstptr[0]            = bufptr[0];
+    s->dstptr[1]            = bufptr[1];
+    s->dstptr[linesize]     = bufptr[linesize];
+    s->dstptr[linesize + 1] = bufptr[linesize + 1];
 
     return 0;
 }
@@ -188,6 +179,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     YopDecContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int tag, firstcolor, is_odd_frame;
     int ret, i, x, y;
     uint32_t *palette;
@@ -197,31 +189,31 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    ret = ff_get_buffer(avctx, &s->frame);
+    ret = ff_get_buffer(avctx, frame, 0);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    s->dstbuf     = s->frame.data[0];
-    s->dstptr     = s->frame.data[0];
+    if (!avctx->frame_number)
+        memset(frame->data[1], 0, AVPALETTE_SIZE);
+
+    s->dstbuf     = frame->data[0];
+    s->dstptr     = frame->data[0];
     s->srcptr     = avpkt->data + 4;
     s->src_end    = avpkt->data + avpkt->size;
     s->low_nibble = NULL;
 
     is_odd_frame = avpkt->data[0];
     firstcolor   = s->first_color[is_odd_frame];
-    palette      = (uint32_t *)s->frame.data[1];
+    palette      = (uint32_t *)frame->data[1];
 
     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);
 
-    s->frame.palette_has_changed = 1;
+    frame->palette_has_changed = 1;
 
     for (y = 0; y < avctx->height; y += 2) {
         for (x = 0; x < avctx->width; x += 2) {
@@ -233,35 +225,31 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             tag = yop_get_next_nibble(s);
 
             if (tag != 0xf) {
-                ret = yop_paint_block(s, tag);
+                ret = yop_paint_block(s, frame->linesize[0], tag);
                 if (ret < 0)
                     return ret;
             } else {
                 tag = yop_get_next_nibble(s);
-                ret = yop_copy_previous_block(s, tag);
-                if (ret < 0) {
-                    avctx->release_buffer(avctx, &s->frame);
+                ret = yop_copy_previous_block(s, frame->linesize[0], tag);
+                if (ret < 0)
                     return ret;
-                }
             }
             s->dstptr += 2;
         }
-        s->dstptr += 2*s->frame.linesize[0] - x;
+        s->dstptr += 2*frame->linesize[0] - x;
     }
 
     *got_frame = 1;
-    *(AVFrame *) data = s->frame;
     return avpkt->size;
 }
 
 AVCodec ff_yop_decoder = {
     .name           = "yop",
+    .long_name      = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_YOP,
     .priv_data_size = sizeof(YopDecContext),
     .init           = yop_decode_init,
-    .close          = yop_decode_close,
     .decode         = yop_decode_frame,
-    .long_name      = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"),
     .capabilities   = CODEC_CAP_DR1,
 };
diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c
index 8122cca..eeba2de 100644
--- a/libavcodec/zerocodec.c
+++ b/libavcodec/zerocodec.c
@@ -23,7 +23,7 @@
 #include "libavutil/common.h"
 
 typedef struct {
-    AVFrame  previous_frame;
+    AVFrame  *previous_frame;
     z_stream zstream;
 } ZeroCodecContext;
 
@@ -31,14 +31,12 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
                                   int *got_frame, AVPacket *avpkt)
 {
     ZeroCodecContext *zc = avctx->priv_data;
-    AVFrame *pic         = avctx->coded_frame;
-    AVFrame *prev_pic    = &zc->previous_frame;
+    AVFrame *pic         = data;
+    AVFrame *prev_pic    = zc->previous_frame;
     z_stream *zstream    = &zc->zstream;
     uint8_t *prev        = prev_pic->data[0];
     uint8_t *dst;
-    int i, j, zret;
-
-    pic->reference = 3;
+    int i, j, zret, ret;
 
     if (avpkt->flags & AV_PKT_FLAG_KEY) {
         pic->key_frame = 1;
@@ -61,7 +59,7 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    if (ff_get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic, AV_GET_BUFFER_FLAG_REF) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -82,7 +80,6 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
 
         zret = inflate(zstream, Z_SYNC_FLUSH);
         if (zret != Z_OK && zret != Z_STREAM_END) {
-            avctx->release_buffer(avctx, pic);
             av_log(avctx, AV_LOG_ERROR,
                    "Inflate failed with return code: %d.\n", zret);
             return AVERROR_INVALIDDATA;
@@ -96,16 +93,11 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
         dst  -= pic->linesize[0];
     }
 
-    /* Release the previous buffer if need be */
-    if (prev_pic->data[0])
-        avctx->release_buffer(avctx, prev_pic);
+    av_frame_unref(zc->previous_frame);
+    if ((ret = av_frame_ref(zc->previous_frame, pic)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame *)data = *pic;
-
-    /* Store the previous frame for use later.
-     * FFSWAP ensures that e.g. pic->data is NULLed. */
-    FFSWAP(AVFrame, *pic, *prev_pic);
 
     return avpkt->size;
 }
@@ -113,15 +105,10 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
 static av_cold int zerocodec_decode_close(AVCodecContext *avctx)
 {
     ZeroCodecContext *zc = avctx->priv_data;
-    AVFrame *prev_pic    = &zc->previous_frame;
-
-    inflateEnd(&zc->zstream);
 
-    /* Release last frame */
-    if (prev_pic->data[0])
-        avctx->release_buffer(avctx, prev_pic);
+    av_frame_free(&zc->previous_frame);
 
-    av_freep(&avctx->coded_frame);
+    inflateEnd(&zc->zstream);
 
     return 0;
 }
@@ -145,9 +132,8 @@ static av_cold int zerocodec_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame buffer.\n");
+    zc->previous_frame = av_frame_alloc();
+    if (!zc->previous_frame) {
         zerocodec_decode_close(avctx);
         return AVERROR(ENOMEM);
     }
@@ -158,11 +144,11 @@ static av_cold int zerocodec_decode_init(AVCodecContext *avctx)
 AVCodec ff_zerocodec_decoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .name           = "zerocodec",
+    .long_name      = NULL_IF_CONFIG_SMALL("ZeroCodec Lossless Video"),
     .id             = AV_CODEC_ID_ZEROCODEC,
     .priv_data_size = sizeof(ZeroCodecContext),
     .init           = zerocodec_decode_init,
     .decode         = zerocodec_decode_frame,
     .close          = zerocodec_decode_close,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("ZeroCodec Lossless Video"),
 };
diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c
index c7a90f0..d17f37a 100644
--- a/libavcodec/zmbv.c
+++ b/libavcodec/zmbv.c
@@ -54,7 +54,6 @@ enum ZmbvFormat {
  */
 typedef struct ZmbvContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int bpp;
     unsigned int decomp_size;
@@ -400,6 +399,7 @@ static int zmbv_decode_intra(ZmbvContext *c)
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     ZmbvContext * const c = avctx->priv_data;
@@ -408,12 +408,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     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.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -437,18 +432,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",
                c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);
         if (hi_ver != 0 || lo_ver != 1) {
-            av_log_ask_for_sample(avctx, "Unsupported version %i.%i\n",
-                                  hi_ver, lo_ver);
+            avpriv_request_sample(avctx, "Version %i.%i", hi_ver, lo_ver);
             return AVERROR_PATCHWELCOME;
         }
         if (c->bw == 0 || c->bh == 0) {
-            av_log_ask_for_sample(avctx, "Unsupported block size %ix%i\n",
-                                  c->bw, c->bh);
+            avpriv_request_sample(avctx, "Block size %ix%i", c->bw, c->bh);
             return AVERROR_PATCHWELCOME;
         }
         if (c->comp != 0 && c->comp != 1) {
-            av_log_ask_for_sample(avctx, "Unsupported compression type %i\n",
-                                  c->comp);
+            avpriv_request_sample(avctx, "Compression type %i", c->comp);
             return AVERROR_PATCHWELCOME;
         }
 
@@ -479,15 +471,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         default:
             c->decode_intra = NULL;
             c->decode_xor = NULL;
-            av_log_ask_for_sample(avctx, "Unsupported (for now) format %i\n",
-                                  c->fmt);
+            avpriv_request_sample(avctx, "Format %i", c->fmt);
             return AVERROR_PATCHWELCOME;
         }
 
         zret = inflateReset(&c->zstream);
         if (zret != Z_OK) {
             av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
-            return -1;
+            return AVERROR_UNKNOWN;
         }
 
         tmp = av_realloc(c->cur,  avctx->width * avctx->height * (c->bpp / 8));
@@ -527,12 +518,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         c->decomp_len = c->zstream.total_out;
     }
     if (c->flags & ZMBV_KEYFRAME) {
-        c->pic.key_frame = 1;
-        c->pic.pict_type = AV_PICTURE_TYPE_I;
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
         c->decode_intra(c);
     } else {
-        c->pic.key_frame = 0;
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
         if (c->decomp_len)
             c->decode_xor(c);
     }
@@ -542,7 +533,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         uint8_t *out, *src;
         int i, j;
 
-        out = c->pic.data[0];
+        out = frame->data[0];
         src = c->cur;
         switch (c->fmt) {
         case ZMBV_FMT_8BPP:
@@ -553,7 +544,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                     out[i * 3 + 2] = c->pal[(*src) * 3 + 2];
                     src++;
                 }
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
         case ZMBV_FMT_15BPP:
@@ -565,7 +556,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                     out[i * 3 + 1] = (tmp & 0x03E0) >> 2;
                     out[i * 3 + 2] = (tmp & 0x001F) << 3;
                 }
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
         case ZMBV_FMT_16BPP:
@@ -577,7 +568,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                     out[i * 3 + 1] = (tmp & 0x07E0) >> 3;
                     out[i * 3 + 2] = (tmp & 0x001F) << 3;
                 }
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
 #ifdef ZMBV_ENABLE_24BPP
@@ -585,7 +576,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
             for (j = 0; j < c->height; j++) {
                 memcpy(out, src, c->width * 3);
                 src += c->width * 3;
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
 #endif //ZMBV_ENABLE_24BPP
@@ -596,7 +587,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                     src += 4;
                     AV_WB24(out+(i*3), tmp);
                 }
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
         default:
@@ -605,7 +596,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         FFSWAP(uint8_t *, c->cur, c->prev);
     }
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -644,7 +634,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     zret = inflateInit(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
-        return -1;
+        return AVERROR_UNKNOWN;
     }
 
     return 0;
@@ -656,8 +646,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
     av_freep(&c->decomp_buf);
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
     inflateEnd(&c->zstream);
     av_freep(&c->cur);
     av_freep(&c->prev);
@@ -667,6 +655,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
 AVCodec ff_zmbv_decoder = {
     .name           = "zmbv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ZMBV,
     .priv_data_size = sizeof(ZmbvContext),
@@ -674,5 +663,4 @@ AVCodec ff_zmbv_decoder = {
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
-    .long_name      = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),
 };
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index 9ac7d6d..785ee0a 100644
--- a/libavcodec/zmbvenc.c
+++ b/libavcodec/zmbvenc.c
@@ -44,7 +44,6 @@
  */
 typedef struct ZmbvEncContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int range;
     uint8_t *comp_buf, *work_buf;
@@ -121,7 +120,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *pict, int *got_packet)
 {
     ZmbvEncContext * const c = avctx->priv_data;
-    AVFrame * const p = &c->pic;
+    const AVFrame * const p = pict;
     uint8_t *src, *prev, *buf;
     uint32_t *palptr;
     int keyframe, chpal;
@@ -134,9 +133,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     c->curfrm++;
     if(c->curfrm == c->keyint)
         c->curfrm = 0;
-    *p = *pict;
-    p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
-    p->key_frame= keyframe;
+    avctx->coded_frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    avctx->coded_frame->key_frame = keyframe;
     chpal = !keyframe && memcmp(p->data[1], c->pal2, 1024);
 
     palptr = (uint32_t*)p->data[1];
@@ -253,6 +251,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
+static av_cold int encode_end(AVCodecContext *avctx)
+{
+    ZmbvEncContext * const c = avctx->priv_data;
+
+    av_freep(&c->comp_buf);
+    av_freep(&c->work_buf);
+
+    deflateEnd(&c->zstream);
+    av_freep(&c->prev);
+
+    av_frame_free(&avctx->coded_frame);
+
+    return 0;
+}
 
 /**
  * Init zmbv encoder
@@ -314,31 +326,18 @@ static av_cold int encode_init(AVCodecContext *avctx)
         return -1;
     }
 
-    avctx->coded_frame = &c->pic;
-
-    return 0;
-}
-
-
-
-/**
- * Uninit zmbv encoder
- */
-static av_cold int encode_end(AVCodecContext *avctx)
-{
-    ZmbvEncContext * const c = avctx->priv_data;
-
-    av_freep(&c->comp_buf);
-    av_freep(&c->work_buf);
-
-    deflateEnd(&c->zstream);
-    av_freep(&c->prev);
+    avctx->coded_frame = av_frame_alloc();
+    if (!avctx->coded_frame) {
+        encode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
     return 0;
 }
 
 AVCodec ff_zmbv_encoder = {
     .name           = "zmbv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_ZMBV,
     .priv_data_size = sizeof(ZmbvEncContext),
@@ -346,5 +345,4 @@ AVCodec ff_zmbv_encoder = {
     .encode2        = encode_frame,
     .close          = encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_PAL8, AV_PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),
 };
diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index 76d11c1..02de216 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -29,6 +29,8 @@ OBJS-$(CONFIG_X11GRAB_INDEV)             += x11grab.o
 OBJS-$(CONFIG_LIBCDIO_INDEV)             += libcdio.o
 OBJS-$(CONFIG_LIBDC1394_INDEV)           += libdc1394.o
 
+OBJS-$(HAVE_LIBC_MSVCRT)                 += file_open.o
+
 SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H)     += alsa-audio.h
 SKIPHEADERS-$(HAVE_SNDIO_H)              += sndio_common.h
 
diff --git a/libavdevice/alsa-audio-dec.c b/libavdevice/alsa-audio-dec.c
index 5b32ed9..0687a4a 100644
--- a/libavdevice/alsa-audio-dec.c
+++ b/libavdevice/alsa-audio-dec.c
@@ -142,7 +142,7 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
     ts_delay += res;
     pkt->pts = timestamp.tv_sec * 1000000LL
                + (timestamp.tv_nsec * st->codec->sample_rate
-                  - ts_delay * 1000000000LL + st->codec->sample_rate * 500LL)
+                  - (int64_t)ts_delay * 1000000000LL + st->codec->sample_rate * 500LL)
                / (st->codec->sample_rate * 1000LL);
 
     pkt->size = res * s->frame_size;
diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c
index d0122d3..06f4d86 100644
--- a/libavdevice/bktr.c
+++ b/libavdevice/bktr.c
@@ -26,9 +26,11 @@
 
 #include "libavformat/avformat.h"
 #include "libavformat/internal.h"
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
+#include "libavutil/time.h"
 #if HAVE_DEV_BKTR_IOCTL_METEOR_H && HAVE_DEV_BKTR_IOCTL_BT848_H
 # include <dev/bktr/ioctl_meteor.h>
 # include <dev/bktr/ioctl_bt848.h>
@@ -135,11 +137,11 @@ static av_cold int bktr_init(const char *video_device, int width, int height,
     act.sa_handler = catchsignal;
     sigaction(SIGUSR1, &act, &old);
 
-    *tuner_fd = open("/dev/tuner0", O_RDONLY);
+    *tuner_fd = avpriv_open("/dev/tuner0", O_RDONLY);
     if (*tuner_fd < 0)
         av_log(NULL, AV_LOG_ERROR, "Warning. Tuner not opened, continuing: %s\n", strerror(errno));
 
-    *video_fd = open(video_device, O_RDONLY);
+    *video_fd = avpriv_open(video_device, O_RDONLY);
     if (*video_fd < 0) {
         av_log(NULL, AV_LOG_ERROR, "%s: %s\n", video_device, strerror(errno));
         return -1;
diff --git a/libavdevice/dv1394.c b/libavdevice/dv1394.c
index ce8efa6..d259e1a 100644
--- a/libavdevice/dv1394.c
+++ b/libavdevice/dv1394.c
@@ -27,6 +27,7 @@
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavformat/avformat.h"
@@ -88,7 +89,7 @@ static int dv1394_read_header(AVFormatContext * context)
         goto failed;
 
     /* Open and initialize DV1394 device */
-    dv->fd = open(context->filename, O_RDONLY);
+    dv->fd = avpriv_open(context->filename, O_RDONLY);
     if (dv->fd < 0) {
         av_log(context, AV_LOG_ERROR, "Failed to open DV interface: %s\n", strerror(errno));
         goto failed;
diff --git a/libavdevice/fbdev.c b/libavdevice/fbdev.c
index 7680b29..22c53a3 100644
--- a/libavdevice/fbdev.c
+++ b/libavdevice/fbdev.c
@@ -27,8 +27,6 @@
  * @see http://linux-fbdev.sourceforge.net/
  */
 
-/* #define DEBUG */
-
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -36,6 +34,7 @@
 #include <time.h>
 #include <linux/fb.h>
 
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
@@ -116,7 +115,7 @@ static av_cold int fbdev_read_header(AVFormatContext *avctx)
     if (avctx->flags & AVFMT_FLAG_NONBLOCK)
         flags |= O_NONBLOCK;
 
-    if ((fbdev->fd = open(avctx->filename, flags)) == -1) {
+    if ((fbdev->fd = avpriv_open(avctx->filename, flags)) == -1) {
         ret = AVERROR(errno);
         av_log(avctx, AV_LOG_ERROR,
                "Could not open framebuffer device '%s': %s\n",
diff --git a/libavdevice/file_open.c b/libavdevice/file_open.c
new file mode 100644
index 0000000..494a5d3
--- /dev/null
+++ b/libavdevice/file_open.c
@@ -0,0 +1 @@
+#include "libavutil/file_open.c"
diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index 280f24d..c261514 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -190,6 +190,10 @@ static int start_jack(AVFormatContext *context)
     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);
+    if (!self->timefilter) {
+        jack_client_close(self->client);
+        return AVERROR(ENOMEM);
+    }
 
     /* Create FIFO buffers */
     self->filled_pkts = av_fifo_alloc(FIFO_PACKETS_NUM * sizeof(AVPacket));
diff --git a/libavdevice/oss_audio.c b/libavdevice/oss_audio.c
index e3b9d67..f1cc91f 100644
--- a/libavdevice/oss_audio.c
+++ b/libavdevice/oss_audio.c
@@ -34,6 +34,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
@@ -63,9 +64,9 @@ static int audio_open(AVFormatContext *s1, int is_output, const char *audio_devi
     char *flip = getenv("AUDIO_FLIP_LEFT");
 
     if (is_output)
-        audio_fd = open(audio_device, O_WRONLY);
+        audio_fd = avpriv_open(audio_device, O_WRONLY);
     else
-        audio_fd = open(audio_device, O_RDONLY);
+        audio_fd = avpriv_open(audio_device, O_RDONLY);
     if (audio_fd < 0) {
         av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno));
         return AVERROR(EIO);
diff --git a/libavdevice/sndio_dec.c b/libavdevice/sndio_dec.c
index a29a088..58caaa1 100644
--- a/libavdevice/sndio_dec.c
+++ b/libavdevice/sndio_dec.c
@@ -25,6 +25,7 @@
 #include "libavformat/avformat.h"
 #include "libavformat/internal.h"
 #include "libavutil/opt.h"
+#include "libavutil/time.h"
 
 #include "sndio_common.h"
 
diff --git a/libavdevice/timefilter.c b/libavdevice/timefilter.c
index 8b98d33..a497351 100644
--- a/libavdevice/timefilter.c
+++ b/libavdevice/timefilter.c
@@ -41,7 +41,11 @@ TimeFilter *ff_timefilter_new(double clock_period,
                               double feedback2_factor,
                               double feedback3_factor)
 {
-    TimeFilter *self       = av_mallocz(sizeof(TimeFilter));
+    TimeFilter *self = av_mallocz(sizeof(TimeFilter));
+
+    if (!self)
+        return NULL;
+
     self->clock_period     = clock_period;
     self->feedback2_factor = feedback2_factor;
     self->feedback3_factor = feedback3_factor;
@@ -105,6 +109,10 @@ int main(void)
                     for (par1 = bestpar1 * 0.8; par1 <= bestpar1 * 1.21; par1 += bestpar1 * 0.05) {
                         double error   = 0;
                         TimeFilter *tf = ff_timefilter_new(1, par0, par1);
+                        if (!tf) {
+                            printf("Could not allocate memory for timefilter.\n");
+                            exit(1);
+                        }
                         for (i = 0; i < SAMPLES; i++) {
                             double filtered;
                             filtered = ff_timefilter_update(tf, samples[i], 1);
diff --git a/libavdevice/timefilter.h b/libavdevice/timefilter.h
index 8cadd8b..2235db6 100644
--- a/libavdevice/timefilter.h
+++ b/libavdevice/timefilter.h
@@ -56,6 +56,8 @@ typedef struct TimeFilter TimeFilter;
  * @param clock_period period of the hardware clock in seconds
  *        (for example 1.0/44100)
  *
+ * @return a pointer to a TimeFilter struct, or NULL on error
+ *
  * For more details about these parameters and background concepts please see:
  * http://www.kokkinizita.net/papers/usingdll.pdf
  */
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 9e71f1d..adb289d 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -42,7 +42,10 @@
 #else
 #include <linux/videodev2.h>
 #endif
+#include "libavutil/atomic.h"
+#include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
@@ -67,6 +70,7 @@ struct video_data {
     int top_field_first;
 
     int buffers;
+    volatile int buffers_queued;
     void **buf_start;
     unsigned int *buf_len;
     char *standard;
@@ -79,6 +83,7 @@ struct video_data {
 };
 
 struct buff_data {
+    struct video_data *s;
     int index;
     int fd;
 };
@@ -119,7 +124,7 @@ static int device_open(AVFormatContext *ctx)
         flags |= O_NONBLOCK;
     }
 
-    fd = open(ctx->filename, flags, 0);
+    fd = avpriv_open(ctx->filename, flags);
     if (fd < 0) {
         err = errno;
 
@@ -405,14 +410,19 @@ static int mmap_init(AVFormatContext *ctx)
     return 0;
 }
 
-static void mmap_release_buffer(AVPacket *pkt)
+#if FF_API_DESTRUCT_PACKET
+static void dummy_release_buffer(AVPacket *pkt)
+{
+    av_assert0(0);
+}
+#endif
+
+static void mmap_release_buffer(void *opaque, uint8_t *data)
 {
     struct v4l2_buffer buf = { 0 };
     int res, fd;
-    struct buff_data *buf_descriptor = pkt->priv;
-
-    if (pkt->data == NULL)
-        return;
+    struct buff_data *buf_descriptor = opaque;
+    struct video_data *s = buf_descriptor->s;
 
     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     buf.memory = V4L2_MEMORY_MMAP;
@@ -424,9 +434,7 @@ static void mmap_release_buffer(AVPacket *pkt)
     if (res < 0)
         av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
                strerror(errno));
-
-    pkt->data = NULL;
-    pkt->size = 0;
+    avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
 }
 
 static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
@@ -436,7 +444,6 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
         .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
         .memory = V4L2_MEMORY_MMAP
     };
-    struct buff_data *buf_descriptor;
     struct pollfd p = { .fd = s->fd, .events = POLLIN };
     int res;
 
@@ -460,7 +467,15 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
 
         return AVERROR(errno);
     }
-    assert (buf.index < s->buffers);
+
+    if (buf.index >= s->buffers) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid buffer index received.\n");
+        return AVERROR(EINVAL);
+    }
+    avpriv_atomic_int_add_and_fetch(&s->buffers_queued, -1);
+    // always keep at least one buffer queued
+    av_assert0(avpriv_atomic_int_get(&s->buffers_queued) >= 1);
+
     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",
@@ -470,23 +485,55 @@ static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
     }
 
     /* Image is at s->buff_start[buf.index] */
-    pkt->data= s->buf_start[buf.index];
-    pkt->size = buf.bytesused;
-    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
-    pkt->destruct = mmap_release_buffer;
-    buf_descriptor = av_malloc(sizeof(struct buff_data));
-    if (buf_descriptor == NULL) {
-        /* Something went wrong... Since av_malloc() failed, we cannot even
-         * allocate a buffer for memcopying into it
-         */
-        av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
+    if (avpriv_atomic_int_get(&s->buffers_queued) == FFMAX(s->buffers / 8, 1)) {
+        /* when we start getting low on queued buffers, fall back on copying data */
+        res = av_new_packet(pkt, buf.bytesused);
+        if (res < 0) {
+            av_log(ctx, AV_LOG_ERROR, "Error allocating a packet.\n");
+            return res;
+        }
+        memcpy(pkt->data, s->buf_start[buf.index], buf.bytesused);
+
         res = ioctl(s->fd, VIDIOC_QBUF, &buf);
+        if (res < 0) {
+            av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF)\n");
+            av_free_packet(pkt);
+            return AVERROR(errno);
+        }
+        avpriv_atomic_int_add_and_fetch(&s->buffers_queued, 1);
+    } else {
+        struct buff_data *buf_descriptor;
+
+        pkt->data     = s->buf_start[buf.index];
+        pkt->size     = buf.bytesused;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+        pkt->destruct = dummy_release_buffer;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
 
-        return AVERROR(ENOMEM);
+        buf_descriptor = av_malloc(sizeof(struct buff_data));
+        if (buf_descriptor == NULL) {
+            /* Something went wrong... Since av_malloc() failed, we cannot even
+             * allocate a buffer for memcpying into it
+             */
+            av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
+            res = ioctl(s->fd, VIDIOC_QBUF, &buf);
+
+            return AVERROR(ENOMEM);
+        }
+        buf_descriptor->fd    = s->fd;
+        buf_descriptor->index = buf.index;
+        buf_descriptor->s     = s;
+
+        pkt->buf = av_buffer_create(pkt->data, pkt->size, mmap_release_buffer,
+                                    buf_descriptor, 0);
+        if (!pkt->buf) {
+            av_freep(&buf_descriptor);
+            return AVERROR(ENOMEM);
+        }
     }
-    buf_descriptor->fd = s->fd;
-    buf_descriptor->index = buf.index;
-    pkt->priv = buf_descriptor;
+    pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
 
     return s->buf_len[buf.index];
 }
@@ -512,6 +559,7 @@ static int mmap_start(AVFormatContext *ctx)
             return AVERROR(errno);
         }
     }
+    s->buffers_queued = s->buffers;
 
     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     res = ioctl(s->fd, VIDIOC_STREAMON, &type);
@@ -634,11 +682,11 @@ static int v4l2_set_parameters(AVFormatContext *s1)
             return AVERROR(errno);
         }
     }
-    s1->streams[0]->codec->time_base.den = tpf->denominator;
-    s1->streams[0]->codec->time_base.num = tpf->numerator;
+    s1->streams[0]->avg_frame_rate.num = tpf->denominator;
+    s1->streams[0]->avg_frame_rate.den = tpf->numerator;
 
     s->timeout = 100 +
-        av_rescale_q(1, s1->streams[0]->codec->time_base,
+        av_rescale_q(1, s1->streams[0]->avg_frame_rate,
                         (AVRational){1, 1000});
 
     return 0;
@@ -687,21 +735,16 @@ static int v4l2_read_header(AVFormatContext *s1)
     enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
 
     st = avformat_new_stream(s1, NULL);
-    if (!st) {
-        res = AVERROR(ENOMEM);
-        goto out;
-    }
+    if (!st)
+        return AVERROR(ENOMEM);
 
     s->fd = device_open(s1);
-    if (s->fd < 0) {
-        res = s->fd;
-        goto out;
-    }
+    if (s->fd < 0)
+        return s->fd;
 
     if (s->list_format) {
         list_formats(s1, s->fd, s->list_format);
-        res = AVERROR_EXIT;
-        goto out;
+        return AVERROR_EXIT;
     }
 
     avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
@@ -710,7 +753,7 @@ static int v4l2_read_header(AVFormatContext *s1)
         (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;
+        return res;
     }
 
     if (s->pixel_format) {
@@ -725,8 +768,7 @@ static int v4l2_read_header(AVFormatContext *s1)
             av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n",
                    s->pixel_format);
 
-            res = AVERROR(EINVAL);
-            goto out;
+            return AVERROR(EINVAL);
         }
     }
 
@@ -739,8 +781,7 @@ static int v4l2_read_header(AVFormatContext *s1)
         if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
             av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",
                    strerror(errno));
-            res = AVERROR(errno);
-            goto out;
+            return AVERROR(errno);
         }
 
         s->width  = fmt.fmt.pix.width;
@@ -756,17 +797,16 @@ static int v4l2_read_header(AVFormatContext *s1)
                "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);
         close(s->fd);
 
-        res = AVERROR(EIO);
-        goto out;
+        return AVERROR(EIO);
     }
 
     if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
-        goto out;
+        return res;
 
     s->frame_format = desired_format;
 
     if ((res = v4l2_set_parameters(s1) < 0))
-        goto out;
+        return res;
 
     st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
     s->frame_size =
@@ -775,7 +815,7 @@ static int v4l2_read_header(AVFormatContext *s1)
     if ((res = mmap_init(s1)) ||
         (res = mmap_start(s1)) < 0) {
         close(s->fd);
-        goto out;
+        return res;
     }
 
     s->top_field_first = first_field(s->fd);
@@ -787,10 +827,9 @@ static int v4l2_read_header(AVFormatContext *s1)
             avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
     st->codec->width = s->width;
     st->codec->height = s->height;
-    st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
+    st->codec->bit_rate = s->frame_size * av_q2d(st->avg_frame_rate) * 8;
 
-out:
-    return res;
+    return 0;
 }
 
 static int v4l2_read_packet(AVFormatContext *s1, AVPacket *pkt)
@@ -816,6 +855,10 @@ static int v4l2_read_close(AVFormatContext *s1)
 {
     struct video_data *s = s1->priv_data;
 
+    if (avpriv_atomic_int_get(&s->buffers_queued) != s->buffers)
+        av_log(s1, AV_LOG_WARNING, "Some buffers are still owned by the caller on "
+               "close.\n");
+
     mmap_close(s);
 
     close(s->fd);
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 52b47db..9731606 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -27,8 +27,8 @@
 
 #include "libavutil/avutil.h"
 
-#define LIBAVDEVICE_VERSION_MAJOR 53
-#define LIBAVDEVICE_VERSION_MINOR  2
+#define LIBAVDEVICE_VERSION_MAJOR 54
+#define LIBAVDEVICE_VERSION_MINOR  0
 #define LIBAVDEVICE_VERSION_MICRO  0
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 4a3331a..96fa8c0 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -27,9 +27,11 @@ OBJS = allfilters.o                                                     \
 OBJS-$(CONFIG_AFORMAT_FILTER)                += af_aformat.o
 OBJS-$(CONFIG_AMIX_FILTER)                   += af_amix.o
 OBJS-$(CONFIG_ANULL_FILTER)                  += af_anull.o
+OBJS-$(CONFIG_ASETPTS_FILTER)                += setpts.o
 OBJS-$(CONFIG_ASHOWINFO_FILTER)              += af_ashowinfo.o
 OBJS-$(CONFIG_ASPLIT_FILTER)                 += split.o
 OBJS-$(CONFIG_ASYNCTS_FILTER)                += af_asyncts.o
+OBJS-$(CONFIG_ATRIM_FILTER)                  += trim.o
 OBJS-$(CONFIG_CHANNELMAP_FILTER)             += af_channelmap.o
 OBJS-$(CONFIG_CHANNELSPLIT_FILTER)           += af_channelsplit.o
 OBJS-$(CONFIG_JOIN_FILTER)                   += af_join.o
@@ -56,6 +58,7 @@ 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_INTERLACE_FILTER)              += vf_interlace.o
 OBJS-$(CONFIG_LUT_FILTER)                    += vf_lut.o
 OBJS-$(CONFIG_LUTRGB_FILTER)                 += vf_lut.o
 OBJS-$(CONFIG_LUTYUV_FILTER)                 += vf_lut.o
@@ -69,12 +72,13 @@ OBJS-$(CONFIG_PIXDESCTEST_FILTER)            += vf_pixdesctest.o
 OBJS-$(CONFIG_SCALE_FILTER)                  += vf_scale.o
 OBJS-$(CONFIG_SELECT_FILTER)                 += vf_select.o
 OBJS-$(CONFIG_SETDAR_FILTER)                 += vf_aspect.o
-OBJS-$(CONFIG_SETPTS_FILTER)                 += vf_setpts.o
+OBJS-$(CONFIG_SETPTS_FILTER)                 += setpts.o
 OBJS-$(CONFIG_SETSAR_FILTER)                 += vf_aspect.o
 OBJS-$(CONFIG_SETTB_FILTER)                  += vf_settb.o
 OBJS-$(CONFIG_SHOWINFO_FILTER)               += vf_showinfo.o
 OBJS-$(CONFIG_SPLIT_FILTER)                  += split.o
 OBJS-$(CONFIG_TRANSPOSE_FILTER)              += vf_transpose.o
+OBJS-$(CONFIG_TRIM_FILTER)                   += trim.o
 OBJS-$(CONFIG_UNSHARP_FILTER)                += vf_unsharp.o
 OBJS-$(CONFIG_VFLIP_FILTER)                  += vf_vflip.o
 OBJS-$(CONFIG_YADIF_FILTER)                  += vf_yadif.o
@@ -88,5 +92,7 @@ OBJS-$(CONFIG_TESTSRC_FILTER)                += vsrc_testsrc.o
 
 OBJS-$(CONFIG_NULLSINK_FILTER)               += vsink_nullsink.o
 
+OBJS-$(HAVE_THREADS)                         += pthread.o
+
 TOOLS     = graph2dot
 TESTPROGS = filtfmts
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index 2059cf2..f074673 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -63,17 +63,24 @@ static const AVClass aformat_class = {
 
 #define PARSE_FORMATS(str, type, list, add_to_list, get_fmt, none, desc)    \
 do {                                                                        \
-    char *next, *cur = str;                                                 \
+    char *next, *cur = str, sep;                                            \
+                                                                            \
+    if (str && strchr(str, ',')) {                                          \
+        av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use '|' to "\
+               "separate %s.\n", desc);                                     \
+        sep = ',';                                                          \
+    } else                                                                  \
+        sep = '|';                                                          \
+                                                                            \
     while (cur) {                                                           \
         type fmt;                                                           \
-        next = strchr(cur, ',');                                            \
+        next = strchr(cur, sep);                                            \
         if (next)                                                           \
             *next++ = 0;                                                    \
                                                                             \
         if ((fmt = get_fmt(cur)) == none) {                                 \
             av_log(ctx, AV_LOG_ERROR, "Error parsing " desc ": %s.\n", cur);\
-            ret = AVERROR(EINVAL);                                          \
-            goto fail;                                                      \
+            return AVERROR(EINVAL);                                         \
         }                                                                   \
         add_to_list(&list, fmt);                                            \
                                                                             \
@@ -87,23 +94,9 @@ static int get_sample_rate(const char *samplerate)
     return FFMAX(ret, 0);
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     AFormatContext *s = ctx->priv;
-    int ret;
-
-    if (!args) {
-        av_log(ctx, AV_LOG_ERROR, "No parameters supplied.\n");
-        return AVERROR(EINVAL);
-    }
-
-    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);
-        return ret;
-    }
 
     PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats,
                   ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format");
@@ -113,9 +106,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
                   ff_add_channel_layout, av_get_channel_layout, 0,
                   "channel layout");
 
-fail:
-    av_opt_free(s);
-    return ret;
+    return 0;
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -123,7 +114,7 @@ static int query_formats(AVFilterContext *ctx)
     AFormatContext *s = ctx->priv;
 
     ff_set_common_formats(ctx, s->formats ? s->formats :
-                                                  ff_all_formats(AVMEDIA_TYPE_AUDIO));
+                                            ff_all_formats(AVMEDIA_TYPE_AUDIO));
     ff_set_common_samplerates(ctx, s->sample_rates ? s->sample_rates :
                                                      ff_all_samplerates());
     ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts :
@@ -148,12 +139,13 @@ static const AVFilterPad avfilter_af_aformat_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_aformat = {
+AVFilter ff_af_aformat = {
     .name          = "aformat",
     .description   = NULL_IF_CONFIG_SMALL("Convert the input audio to one of the specified formats."),
     .init          = init,
     .query_formats = query_formats,
     .priv_size     = sizeof(AFormatContext),
+    .priv_class    = &aformat_class,
 
     .inputs        = avfilter_af_aformat_inputs,
     .outputs       = avfilter_af_aformat_outputs,
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c
index c2fb158..bfba150 100644
--- a/libavfilter/af_amix.c
+++ b/libavfilter/af_amix.c
@@ -28,6 +28,7 @@
  * output.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/audio_fifo.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
@@ -275,18 +276,18 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
 {
     AVFilterContext *ctx = outlink->src;
     MixContext      *s = ctx->priv;
-    AVFilterBufferRef *out_buf, *in_buf;
+    AVFrame *out_buf, *in_buf;
     int i;
 
     calculate_scales(s, nb_samples);
 
-    out_buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
+    out_buf = ff_get_audio_buffer(outlink, nb_samples);
     if (!out_buf)
         return AVERROR(ENOMEM);
 
-    in_buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
+    in_buf = ff_get_audio_buffer(outlink, nb_samples);
     if (!in_buf) {
-        avfilter_unref_buffer(out_buf);
+        av_frame_free(&out_buf);
         return AVERROR(ENOMEM);
     }
 
@@ -308,7 +309,7 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
             }
         }
     }
-    avfilter_unref_buffer(in_buf);
+    av_frame_free(&in_buf);
 
     out_buf->pts = s->next_pts;
     if (s->next_pts != AV_NOPTS_VALUE)
@@ -455,7 +456,7 @@ static int request_frame(AVFilterLink *outlink)
     return output_frame(outlink, available_samples);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
 {
     AVFilterContext  *ctx = inlink->dst;
     MixContext       *s = ctx->priv;
@@ -474,33 +475,24 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
     if (i == 0) {
         int64_t pts = av_rescale_q(buf->pts, inlink->time_base,
                                    outlink->time_base);
-        ret = frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
+        ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts);
         if (ret < 0)
             goto fail;
     }
 
     ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
-                              buf->audio->nb_samples);
+                              buf->nb_samples);
 
 fail:
-    avfilter_unref_buffer(buf);
+    av_frame_free(&buf);
 
     return ret;
 }
 
-static int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     MixContext *s = ctx->priv;
-    int i, ret;
-
-    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);
-        return ret;
-    }
-    av_opt_free(s);
+    int i;
 
     for (i = 0; i < s->nb_inputs; i++) {
         char name[32];
@@ -519,7 +511,7 @@ static int init(AVFilterContext *ctx, const char *args)
     return 0;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     int i;
     MixContext *s = ctx->priv;
@@ -559,10 +551,11 @@ static const AVFilterPad avfilter_af_amix_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_amix = {
+AVFilter ff_af_amix = {
     .name          = "amix",
     .description   = NULL_IF_CONFIG_SMALL("Audio mixing."),
     .priv_size     = sizeof(MixContext),
+    .priv_class    = &amix_class,
 
     .init           = init,
     .uninit         = uninit,
@@ -570,4 +563,6 @@ AVFilter avfilter_af_amix = {
 
     .inputs    = NULL,
     .outputs   = avfilter_af_amix_outputs,
+
+    .flags     = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_anull.c b/libavfilter/af_anull.c
index a791064..6d7caf3 100644
--- a/libavfilter/af_anull.c
+++ b/libavfilter/af_anull.c
@@ -43,7 +43,7 @@ static const AVFilterPad avfilter_af_anull_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_anull = {
+AVFilter ff_af_anull = {
     .name      = "anull",
     .description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
 
diff --git a/libavfilter/af_ashowinfo.c b/libavfilter/af_ashowinfo.c
index c8e830e..2a2edcf 100644
--- a/libavfilter/af_ashowinfo.c
+++ b/libavfilter/af_ashowinfo.c
@@ -27,6 +27,7 @@
 #include <stddef.h>
 
 #include "libavutil/adler32.h"
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/mem.h"
@@ -59,22 +60,22 @@ static int config_input(AVFilterLink *inlink)
     return 0;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     AShowInfoContext *s = ctx->priv;
     av_freep(&s->plane_checksums);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
 {
     AVFilterContext *ctx = inlink->dst;
     AShowInfoContext *s  = ctx->priv;
     char chlayout_str[128];
     uint32_t checksum = 0;
-    int channels    = av_get_channel_layout_nb_channels(buf->audio->channel_layout);
+    int channels    = av_get_channel_layout_nb_channels(buf->channel_layout);
     int planar      = av_sample_fmt_is_planar(buf->format);
     int block_align = av_get_bytes_per_sample(buf->format) * (planar ? 1 : channels);
-    int data_size   = buf->audio->nb_samples * block_align;
+    int data_size   = buf->nb_samples * block_align;
     int planes      = planar ? channels : 1;
     int i;
 
@@ -87,7 +88,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
     }
 
     av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1,
-                                 buf->audio->channel_layout);
+                                 buf->channel_layout);
 
     av_log(ctx, AV_LOG_INFO,
            "n:%"PRIu64" pts:%"PRId64" pts_time:%f "
@@ -95,7 +96,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
            "checksum:%08X ",
            s->frame, buf->pts, buf->pts * av_q2d(inlink->time_base),
            av_get_sample_fmt_name(buf->format), chlayout_str,
-           buf->audio->sample_rate, buf->audio->nb_samples,
+           buf->sample_rate, buf->nb_samples,
            checksum);
 
     av_log(ctx, AV_LOG_INFO, "plane_checksums: [ ");
@@ -114,7 +115,6 @@ static const AVFilterPad inputs[] = {
         .get_audio_buffer = ff_null_get_audio_buffer,
         .config_props     = config_input,
         .filter_frame     = filter_frame,
-        .min_perms        = AV_PERM_READ,
     },
     { NULL },
 };
@@ -127,7 +127,7 @@ static const AVFilterPad outputs[] = {
     { NULL },
 };
 
-AVFilter avfilter_af_ashowinfo = {
+AVFilter ff_af_ashowinfo = {
     .name        = "ashowinfo",
     .description = NULL_IF_CONFIG_SMALL("Show textual information for each audio frame."),
     .priv_size   = sizeof(AShowInfoContext),
diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c
index 3ebe3b5..e662c84 100644
--- a/libavfilter/af_asyncts.c
+++ b/libavfilter/af_asyncts.c
@@ -16,7 +16,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavresample/avresample.h"
+#include "libavutil/attributes.h"
 #include "libavutil/audio_fifo.h"
 #include "libavutil/common.h"
 #include "libavutil/mathematics.h"
@@ -35,6 +38,7 @@ typedef struct ASyncContext {
     int min_delta;          ///< pad/trim min threshold in samples
     int first_frame;        ///< 1 until filter_frame() has processed at least 1 frame with a pts != AV_NOPTS_VALUE
     int64_t first_pts;      ///< user-specified first expected pts, in samples
+    int comp;               ///< current resample compensation
 
     /* options */
     int resample;
@@ -63,19 +67,9 @@ static const AVClass async_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-static int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     ASyncContext *s = ctx->priv;
-    int ret;
-
-    s->class = &async_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);
-        return ret;
-    }
-    av_opt_free(s);
 
     s->pts         = AV_NOPTS_VALUE;
     s->first_frame = 1;
@@ -83,7 +77,7 @@ static int init(AVFilterContext *ctx, const char *args)
     return 0;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
     ASyncContext *s = ctx->priv;
 
@@ -158,14 +152,13 @@ static int request_frame(AVFilterLink *link)
             handle_trimming(ctx);
 
         if (nb_samples = get_delay(s)) {
-            AVFilterBufferRef *buf = ff_get_audio_buffer(link, AV_PERM_WRITE,
-                                                         nb_samples);
+            AVFrame *buf = ff_get_audio_buffer(link, nb_samples);
             if (!buf)
                 return AVERROR(ENOMEM);
             ret = avresample_convert(s->avr, buf->extended_data,
                                      buf->linesize[0], nb_samples, NULL, 0, 0);
             if (ret <= 0) {
-                avfilter_unref_bufferp(&buf);
+                av_frame_free(&buf);
                 return (ret < 0) ? ret : AVERROR_EOF;
             }
 
@@ -177,24 +170,25 @@ static int request_frame(AVFilterLink *link)
     return ret;
 }
 
-static int write_to_fifo(ASyncContext *s, AVFilterBufferRef *buf)
+static int write_to_fifo(ASyncContext *s, AVFrame *buf)
 {
     int ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data,
-                                 buf->linesize[0], buf->audio->nb_samples);
-    avfilter_unref_buffer(buf);
+                                 buf->linesize[0], buf->nb_samples);
+    av_frame_free(&buf);
     return ret;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
 {
     AVFilterContext  *ctx = inlink->dst;
     ASyncContext       *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    int nb_channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout);
+    int nb_channels = av_get_channel_layout_nb_channels(buf->channel_layout);
     int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts :
                   av_rescale_q(buf->pts, inlink->time_base, outlink->time_base);
     int out_size, ret;
     int64_t delta;
+    int64_t new_pts;
 
     /* buffer data until we get the next timestamp */
     if (s->pts == AV_NOPTS_VALUE || pts == AV_NOPTS_VALUE) {
@@ -221,16 +215,24 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
         out_size = av_clipl_int32((int64_t)out_size + delta);
     } else {
         if (s->resample) {
-            int comp = av_clip(delta, -s->max_comp, s->max_comp);
-            av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp);
-            avresample_set_compensation(s->avr, comp, inlink->sample_rate);
+            // adjust the compensation if delta is non-zero
+            int delay = get_delay(s);
+            int comp = s->comp + av_clip(delta * inlink->sample_rate / delay,
+                                         -s->max_comp, s->max_comp);
+            if (comp != s->comp) {
+                av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp);
+                if (avresample_set_compensation(s->avr, comp, inlink->sample_rate) == 0) {
+                    s->comp = comp;
+                }
+            }
         }
+        // adjust PTS to avoid monotonicity errors with input PTS jitter
+        pts -= delta;
         delta = 0;
     }
 
     if (out_size > 0) {
-        AVFilterBufferRef *buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
-                                                         out_size);
+        AVFrame *buf_out = ff_get_audio_buffer(outlink, out_size);
         if (!buf_out) {
             ret = AVERROR(ENOMEM);
             goto fail;
@@ -275,13 +277,21 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
     /* drain any remaining buffered data */
     avresample_read(s->avr, NULL, avresample_available(s->avr));
 
-    s->pts = pts - avresample_get_delay(s->avr);
-    ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data,
-                             buf->linesize[0], buf->audio->nb_samples);
+    new_pts = pts - avresample_get_delay(s->avr);
+    /* check for s->pts monotonicity */
+    if (new_pts > s->pts) {
+        s->pts = new_pts;
+        ret = avresample_convert(s->avr, NULL, 0, 0, buf->extended_data,
+                                 buf->linesize[0], buf->nb_samples);
+    } else {
+        av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping "
+               "whole buffer.\n");
+        ret = 0;
+    }
 
     s->first_frame = 0;
 fail:
-    avfilter_unref_buffer(buf);
+    av_frame_free(&buf);
 
     return ret;
 }
@@ -305,7 +315,7 @@ static const AVFilterPad avfilter_af_asyncts_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_asyncts = {
+AVFilter ff_af_asyncts = {
     .name        = "asyncts",
     .description = NULL_IF_CONFIG_SMALL("Sync audio data to timestamps"),
 
@@ -313,6 +323,7 @@ AVFilter avfilter_af_asyncts = {
     .uninit      = uninit,
 
     .priv_size   = sizeof(ASyncContext),
+    .priv_class  = &async_class,
 
     .inputs      = avfilter_af_asyncts_inputs,
     .outputs     = avfilter_af_asyncts_outputs,
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index c4b87da..71d51e7 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -119,30 +119,16 @@ static int get_channel(char **map, uint64_t *ch, char delim)
     return 0;
 }
 
-static av_cold int channelmap_init(AVFilterContext *ctx, const char *args)
+static av_cold int channelmap_init(AVFilterContext *ctx)
 {
     ChannelMapContext *s = ctx->priv;
-    int ret;
-    char *mapping;
+    char *mapping, separator = '|';
     int map_entries = 0;
     char buf[256];
     enum MappingMode mode;
     uint64_t out_ch_mask = 0;
     int i;
 
-    if (!args) {
-        av_log(ctx, AV_LOG_ERROR, "No parameters supplied.\n");
-        return AVERROR(EINVAL);
-    }
-
-    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);
-        return ret;
-    }
-
     mapping = s->mapping_str;
 
     if (!mapping) {
@@ -150,36 +136,42 @@ static av_cold int channelmap_init(AVFilterContext *ctx, const char *args)
     } else {
         char *dash = strchr(mapping, '-');
         if (!dash) {  // short mapping
-            if (isdigit(*mapping))
+            if (av_isdigit(*mapping))
                 mode = MAP_ONE_INT;
             else
                 mode = MAP_ONE_STR;
-        } else if (isdigit(*mapping)) {
-            if (isdigit(*(dash+1)))
+        } else if (av_isdigit(*mapping)) {
+            if (av_isdigit(*(dash+1)))
                 mode = MAP_PAIR_INT_INT;
             else
                 mode = MAP_PAIR_INT_STR;
         } else {
-            if (isdigit(*(dash+1)))
+            if (av_isdigit(*(dash+1)))
                 mode = MAP_PAIR_STR_INT;
             else
                 mode = MAP_PAIR_STR_STR;
         }
+#if FF_API_OLD_FILTER_OPTS
+        if (strchr(mapping, ',')) {
+            av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use "
+                   "'|' to separate the mappings.\n");
+            separator = ',';
+        }
+#endif
     }
 
     if (mode != MAP_NONE) {
-        char *comma = mapping;
+        char *sep = mapping;
         map_entries = 1;
-        while ((comma = strchr(comma, ','))) {
-            if (*++comma)  // Allow trailing comma
+        while ((sep = strchr(sep, separator))) {
+            if (*++sep)  // Allow trailing comma
                 map_entries++;
         }
     }
 
     if (map_entries > MAX_CH) {
         av_log(ctx, AV_LOG_ERROR, "Too many channels mapped: '%d'.\n", map_entries);
-        ret = AVERROR(EINVAL);
-        goto fail;
+        return AVERROR(EINVAL);
     }
 
     for (i = 0; i < map_entries; i++) {
@@ -188,40 +180,36 @@ static av_cold int channelmap_init(AVFilterContext *ctx, const char *args)
         static const char err[] = "Failed to parse channel map\n";
         switch (mode) {
         case MAP_ONE_INT:
-            if (get_channel_idx(&mapping, &in_ch_idx, ',', MAX_CH) < 0) {
-                ret = AVERROR(EINVAL);
+            if (get_channel_idx(&mapping, &in_ch_idx, separator, MAX_CH) < 0) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel_idx  = in_ch_idx;
             s->map[i].out_channel_idx = i;
             break;
         case MAP_ONE_STR:
-            if (!get_channel(&mapping, &in_ch, ',')) {
+            if (!get_channel(&mapping, &in_ch, separator)) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel      = in_ch;
             s->map[i].out_channel_idx = i;
             break;
         case MAP_PAIR_INT_INT:
             if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
-                get_channel_idx(&mapping, &out_ch_idx, ',', MAX_CH) < 0) {
+                get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel_idx  = in_ch_idx;
             s->map[i].out_channel_idx = out_ch_idx;
             break;
         case MAP_PAIR_INT_STR:
             if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||
-                get_channel(&mapping, &out_ch, ',') < 0 ||
+                get_channel(&mapping, &out_ch, separator) < 0 ||
                 out_ch & out_ch_mask) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel_idx  = in_ch_idx;
             s->map[i].out_channel     = out_ch;
@@ -229,21 +217,19 @@ static av_cold int channelmap_init(AVFilterContext *ctx, const char *args)
             break;
         case MAP_PAIR_STR_INT:
             if (get_channel(&mapping, &in_ch, '-') < 0 ||
-                get_channel_idx(&mapping, &out_ch_idx, ',', MAX_CH) < 0) {
+                get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel      = in_ch;
             s->map[i].out_channel_idx = out_ch_idx;
             break;
         case MAP_PAIR_STR_STR:
             if (get_channel(&mapping, &in_ch, '-') < 0 ||
-                get_channel(&mapping, &out_ch, ',') < 0 ||
+                get_channel(&mapping, &out_ch, separator) < 0 ||
                 out_ch & out_ch_mask) {
                 av_log(ctx, AV_LOG_ERROR, err);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                return AVERROR(EINVAL);
             }
             s->map[i].in_channel = in_ch;
             s->map[i].out_channel = out_ch;
@@ -261,8 +247,7 @@ static av_cold int channelmap_init(AVFilterContext *ctx, const char *args)
         if ((fmt = av_get_channel_layout(s->channel_layout_str)) == 0) {
             av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: '%s'.\n",
                    s->channel_layout_str);
-            ret = AVERROR(EINVAL);
-            goto fail;
+            return AVERROR(EINVAL);
         }
         if (mode == MAP_NONE) {
             int i;
@@ -276,17 +261,21 @@ static av_cold int channelmap_init(AVFilterContext *ctx, const char *args)
             av_log(ctx, AV_LOG_ERROR,
                    "Output channel layout '%s' does not match the list of channel mapped: '%s'.\n",
                    s->channel_layout_str, buf);
-            ret = AVERROR(EINVAL);
-            goto fail;
+            return AVERROR(EINVAL);
         } else if (s->nch != av_get_channel_layout_nb_channels(fmt)) {
             av_log(ctx, AV_LOG_ERROR,
                    "Output channel layout %s does not match the number of channels mapped %d.\n",
                    s->channel_layout_str, s->nch);
-            ret = AVERROR(EINVAL);
-            goto fail;
+            return AVERROR(EINVAL);
         }
         s->output_layout = fmt;
     }
+    if (!s->output_layout) {
+        av_log(ctx, AV_LOG_ERROR, "Output channel layout is not set and "
+               "cannot be guessed from the maps.\n");
+        return AVERROR(EINVAL);
+    }
+
     ff_add_channel_layout(&s->channel_layouts, s->output_layout);
 
     if (mode == MAP_PAIR_INT_STR || mode == MAP_PAIR_STR_STR) {
@@ -296,9 +285,7 @@ static av_cold int channelmap_init(AVFilterContext *ctx, const char *args)
         }
     }
 
-fail:
-    av_opt_free(s);
-    return ret;
+    return 0;
 }
 
 static int channelmap_query_formats(AVFilterContext *ctx)
@@ -313,7 +300,7 @@ static int channelmap_query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static int channelmap_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int channelmap_filter_frame(AVFilterLink *inlink, AVFrame *buf)
 {
     AVFilterContext  *ctx = inlink->dst;
     AVFilterLink *outlink = ctx->outputs[0];
@@ -331,7 +318,7 @@ static int channelmap_filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
             uint8_t **new_extended_data =
                 av_mallocz(nch_out * sizeof(*buf->extended_data));
             if (!new_extended_data) {
-                avfilter_unref_buffer(buf);
+                av_frame_free(&buf);
                 return AVERROR(ENOMEM);
             }
             if (buf->extended_data == buf->data) {
@@ -368,24 +355,25 @@ static int channelmap_config_input(AVFilterLink *inlink)
     char layout_name[256];
 
     for (i = 0; i < s->nch; i++) {
+        struct ChannelMap *m = &s->map[i];
+
         if (s->mode == MAP_PAIR_STR_INT || s->mode == MAP_PAIR_STR_STR) {
-            s->map[i].in_channel_idx = av_get_channel_layout_channel_index(
-                inlink->channel_layout, s->map[i].in_channel);
+            m->in_channel_idx = av_get_channel_layout_channel_index(
+                inlink->channel_layout, m->in_channel);
         }
 
-        if (s->map[i].in_channel_idx < 0 ||
-            s->map[i].in_channel_idx >= nb_channels) {
+        if (m->in_channel_idx < 0 || m->in_channel_idx >= nb_channels) {
             av_get_channel_layout_string(layout_name, sizeof(layout_name),
                                          0, inlink->channel_layout);
-            if (s->map[i].in_channel) {
-                channel_name = av_get_channel_name(s->map[i].in_channel);
+            if (m->in_channel) {
+                channel_name = av_get_channel_name(m->in_channel);
                 av_log(ctx, AV_LOG_ERROR,
                        "input channel '%s' not available from input layout '%s'\n",
                        channel_name, layout_name);
             } else {
                 av_log(ctx, AV_LOG_ERROR,
                        "input channel #%d not available from input layout '%s'\n",
-                       s->map[i].in_channel_idx, layout_name);
+                       m->in_channel_idx, layout_name);
             }
             err = AVERROR(EINVAL);
         }
@@ -412,12 +400,13 @@ static const AVFilterPad avfilter_af_channelmap_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_channelmap = {
+AVFilter ff_af_channelmap = {
     .name          = "channelmap",
     .description   = NULL_IF_CONFIG_SMALL("Remap audio channels."),
     .init          = channelmap_init,
     .query_formats = channelmap_query_formats,
     .priv_size     = sizeof(ChannelMapContext),
+    .priv_class    = &channelmap_class,
 
     .inputs        = avfilter_af_channelmap_inputs,
     .outputs       = avfilter_af_channelmap_outputs,
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
index cc379f3..5b410fd 100644
--- a/libavfilter/af_channelsplit.c
+++ b/libavfilter/af_channelsplit.c
@@ -23,6 +23,7 @@
  * Split an audio stream into per-channel streams.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/internal.h"
 #include "libavutil/opt.h"
@@ -53,18 +54,12 @@ static const AVClass channelsplit_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-static int init(AVFilterContext *ctx, const char *arg)
+static av_cold int init(AVFilterContext *ctx)
 {
     ChannelSplitContext *s = ctx->priv;
     int nb_channels;
     int ret = 0, i;
 
-    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);
-        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);
@@ -84,7 +79,6 @@ static int init(AVFilterContext *ctx, const char *arg)
     }
 
 fail:
-    av_opt_free(s);
     return ret;
 }
 
@@ -111,13 +105,13 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
 {
     AVFilterContext *ctx = inlink->dst;
     int i, ret = 0;
 
     for (i = 0; i < ctx->nb_outputs; i++) {
-        AVFilterBufferRef *buf_out = avfilter_ref_buffer(buf, ~AV_PERM_WRITE);
+        AVFrame *buf_out = av_frame_clone(buf);
 
         if (!buf_out) {
             ret = AVERROR(ENOMEM);
@@ -125,14 +119,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
         }
 
         buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[i];
-        buf_out->audio->channel_layout =
-            av_channel_layout_extract_channel(buf->audio->channel_layout, i);
+        buf_out->channel_layout =
+            av_channel_layout_extract_channel(buf->channel_layout, i);
 
         ret = ff_filter_frame(ctx->outputs[i], buf_out);
         if (ret < 0)
             break;
     }
-    avfilter_unref_buffer(buf);
+    av_frame_free(&buf);
     return ret;
 }
 
@@ -145,14 +139,17 @@ static const AVFilterPad avfilter_af_channelsplit_inputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_channelsplit = {
+AVFilter ff_af_channelsplit = {
     .name           = "channelsplit",
     .description    = NULL_IF_CONFIG_SMALL("Split audio into per-channel streams"),
     .priv_size      = sizeof(ChannelSplitContext),
+    .priv_class     = &channelsplit_class,
 
     .init           = init,
     .query_formats  = query_formats,
 
     .inputs  = avfilter_af_channelsplit_inputs,
     .outputs = NULL,
+
+    .flags   = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
index 2b715d5..ee87340 100644
--- a/libavfilter/af_join.c
+++ b/libavfilter/af_join.c
@@ -56,24 +56,14 @@ typedef struct JoinContext {
     /**
      * Temporary storage for input frames, until we get one on each input.
      */
-    AVFilterBufferRef **input_frames;
+    AVFrame **input_frames;
 
     /**
-     *  Temporary storage for data pointers, for assembling the output buffer.
+     *  Temporary storage for buffer references, for assembling the output frame.
      */
-    uint8_t **data;
+    AVBufferRef **buffers;
 } JoinContext;
 
-/**
- * To avoid copying the data from input buffers, this filter creates
- * a custom output buffer that stores references to all inputs and
- * unrefs them on free.
- */
-typedef struct JoinBufferPriv {
-    AVFilterBufferRef **in_buffers;
-    int              nb_in_buffers;
-} JoinBufferPriv;
-
 #define OFFSET(x) offsetof(JoinContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
 static const AVOption join_options[] = {
@@ -93,7 +83,7 @@ static const AVClass join_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
     AVFilterContext *ctx = link->dst;
     JoinContext       *s = ctx->priv;
@@ -104,7 +94,7 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *buf)
             break;
     av_assert0(i < ctx->nb_inputs);
     av_assert0(!s->input_frames[i]);
-    s->input_frames[i] = buf;
+    s->input_frames[i] = frame;
 
     return 0;
 }
@@ -112,14 +102,23 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *buf)
 static int parse_maps(AVFilterContext *ctx)
 {
     JoinContext *s = ctx->priv;
+    char separator = '|';
     char *cur      = s->map;
 
+#if FF_API_OLD_FILTER_OPTS
+    if (cur && strchr(cur, ',')) {
+        av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use '|' to "
+               "separate the mappings.\n");
+        separator = ',';
+    }
+#endif
+
     while (cur && *cur) {
         char *sep, *next, *p;
         uint64_t in_channel = 0, out_channel = 0;
         int input_idx, out_ch_idx, in_ch_idx;
 
-        next = strchr(cur, ',');
+        next = strchr(cur, separator);
         if (next)
             *next++ = 0;
 
@@ -187,18 +186,11 @@ static int parse_maps(AVFilterContext *ctx)
     return 0;
 }
 
-static int join_init(AVFilterContext *ctx, const char *args)
+static av_cold int join_init(AVFilterContext *ctx)
 {
     JoinContext *s = ctx->priv;
     int ret, i;
 
-    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);
-        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);
@@ -208,9 +200,9 @@ static int join_init(AVFilterContext *ctx, const char *args)
 
     s->nb_channels  = av_get_channel_layout_nb_channels(s->channel_layout);
     s->channels     = av_mallocz(sizeof(*s->channels) * s->nb_channels);
-    s->data         = av_mallocz(sizeof(*s->data)     * s->nb_channels);
+    s->buffers      = av_mallocz(sizeof(*s->buffers)  * s->nb_channels);
     s->input_frames = av_mallocz(sizeof(*s->input_frames) * s->inputs);
-    if (!s->channels || !s->data || !s->input_frames) {
+    if (!s->channels || !s->buffers|| !s->input_frames) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
@@ -242,18 +234,18 @@ fail:
     return ret;
 }
 
-static void join_uninit(AVFilterContext *ctx)
+static av_cold void join_uninit(AVFilterContext *ctx)
 {
     JoinContext *s = ctx->priv;
     int i;
 
     for (i = 0; i < ctx->nb_inputs; i++) {
         av_freep(&ctx->input_pads[i].name);
-        avfilter_unref_bufferp(&s->input_frames[i]);
+        av_frame_free(&s->input_frames[i]);
     }
 
     av_freep(&s->channels);
-    av_freep(&s->data);
+    av_freep(&s->buffers);
     av_freep(&s->input_frames);
 }
 
@@ -395,34 +387,14 @@ fail:
     return ret;
 }
 
-static void join_free_buffer(AVFilterBuffer *buf)
-{
-    JoinBufferPriv *priv = buf->priv;
-
-    if (priv) {
-        int i;
-
-        for (i = 0; i < priv->nb_in_buffers; i++)
-            avfilter_unref_bufferp(&priv->in_buffers[i]);
-
-        av_freep(&priv->in_buffers);
-        av_freep(&buf->priv);
-    }
-
-    if (buf->extended_data != buf->data)
-        av_freep(&buf->extended_data);
-    av_freep(&buf);
-}
-
 static int join_request_frame(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
     JoinContext *s       = ctx->priv;
-    AVFilterBufferRef *buf;
-    JoinBufferPriv *priv;
+    AVFrame *frame;
     int linesize   = INT_MAX;
-    int perms      = ~0;
     int nb_samples = 0;
+    int nb_buffers = 0;
     int i, j, ret;
 
     /* get a frame on each input */
@@ -435,54 +407,96 @@ static int join_request_frame(AVFilterLink *outlink)
 
         /* request the same number of samples on all inputs */
         if (i == 0) {
-            nb_samples = s->input_frames[0]->audio->nb_samples;
+            nb_samples = s->input_frames[0]->nb_samples;
 
             for (j = 1; !i && j < ctx->nb_inputs; j++)
                 ctx->inputs[j]->request_samples = nb_samples;
         }
     }
 
+    /* setup the output frame */
+    frame = av_frame_alloc();
+    if (!frame)
+        return AVERROR(ENOMEM);
+    if (s->nb_channels > FF_ARRAY_ELEMS(frame->data)) {
+        frame->extended_data = av_mallocz(s->nb_channels *
+                                          sizeof(*frame->extended_data));
+        if (!frame->extended_data) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+    }
+
+    /* copy the data pointers */
     for (i = 0; i < s->nb_channels; i++) {
         ChannelMap *ch = &s->channels[i];
-        AVFilterBufferRef *cur_buf = s->input_frames[ch->input];
+        AVFrame *cur   = s->input_frames[ch->input];
+        AVBufferRef *buf;
+
+        frame->extended_data[i] = cur->extended_data[ch->in_channel_idx];
+        linesize = FFMIN(linesize, cur->linesize[0]);
 
-        s->data[i] = cur_buf->extended_data[ch->in_channel_idx];
-        linesize   = FFMIN(linesize, cur_buf->linesize[0]);
-        perms     &= cur_buf->perms;
+        /* add the buffer where this plan is stored to the list if it's
+         * not already there */
+        buf = av_frame_get_plane_buffer(cur, ch->in_channel_idx);
+        if (!buf) {
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+        for (j = 0; j < nb_buffers; j++)
+            if (s->buffers[j]->buffer == buf->buffer)
+                break;
+        if (j == i)
+            s->buffers[nb_buffers++] = buf;
     }
 
-    av_assert0(nb_samples > 0);
-    buf = avfilter_get_audio_buffer_ref_from_arrays(s->data, linesize, perms,
-                                                    nb_samples, outlink->format,
-                                                    outlink->channel_layout);
-    if (!buf)
-        return AVERROR(ENOMEM);
+    /* create references to the buffers we copied to output */
+    if (nb_buffers > FF_ARRAY_ELEMS(frame->buf)) {
+        frame->nb_extended_buf = nb_buffers - FF_ARRAY_ELEMS(frame->buf);
+        frame->extended_buf = av_mallocz(sizeof(*frame->extended_buf) *
+                                         frame->nb_extended_buf);
+        if (!frame->extended_buf) {
+            frame->nb_extended_buf = 0;
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+    }
+    for (i = 0; i < FFMIN(FF_ARRAY_ELEMS(frame->buf), nb_buffers); i++) {
+        frame->buf[i] = av_buffer_ref(s->buffers[i]);
+        if (!frame->buf[i]) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+    }
+    for (i = 0; i < frame->nb_extended_buf; i++) {
+        frame->extended_buf[i] = av_buffer_ref(s->buffers[i +
+                                               FF_ARRAY_ELEMS(frame->buf)]);
+        if (!frame->extended_buf[i]) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+    }
 
-    buf->buf->free = join_free_buffer;
-    buf->pts       = s->input_frames[0]->pts;
+    frame->nb_samples     = nb_samples;
+    frame->channel_layout = outlink->channel_layout;
+    frame->sample_rate    = outlink->sample_rate;
+    frame->pts            = s->input_frames[0]->pts;
+    frame->linesize[0]    = linesize;
+    if (frame->data != frame->extended_data) {
+        memcpy(frame->data, frame->extended_data, sizeof(*frame->data) *
+               FFMIN(FF_ARRAY_ELEMS(frame->data), s->nb_channels));
+    }
 
-    if (!(priv = av_mallocz(sizeof(*priv))))
-        goto fail;
-    if (!(priv->in_buffers = av_mallocz(sizeof(*priv->in_buffers) * ctx->nb_inputs)))
-        goto fail;
+    ret = ff_filter_frame(outlink, frame);
 
     for (i = 0; i < ctx->nb_inputs; i++)
-        priv->in_buffers[i] = s->input_frames[i];
-    priv->nb_in_buffers = ctx->nb_inputs;
-    buf->buf->priv      = priv;
-
-    ret = ff_filter_frame(outlink, buf);
-
-    memset(s->input_frames, 0, sizeof(*s->input_frames) * ctx->nb_inputs);
+        av_frame_free(&s->input_frames[i]);
 
     return ret;
 
 fail:
-    avfilter_unref_buffer(buf);
-    if (priv)
-        av_freep(&priv->in_buffers);
-    av_freep(&priv);
-    return AVERROR(ENOMEM);
+    av_frame_free(&frame);
+    return ret;
 }
 
 static const AVFilterPad avfilter_af_join_outputs[] = {
@@ -495,11 +509,12 @@ static const AVFilterPad avfilter_af_join_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_join = {
+AVFilter ff_af_join = {
     .name           = "join",
     .description    = NULL_IF_CONFIG_SMALL("Join multiple audio streams into "
                                            "multi-channel output"),
     .priv_size      = sizeof(JoinContext),
+    .priv_class     = &join_class,
 
     .init           = join_init,
     .uninit         = join_uninit,
@@ -507,4 +522,6 @@ AVFilter avfilter_af_join = {
 
     .inputs  = NULL,
     .outputs = avfilter_af_join_outputs,
+
+    .flags   = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c
index c712b46..224e0ed 100644
--- a/libavfilter/af_resample.c
+++ b/libavfilter/af_resample.c
@@ -25,6 +25,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
+#include "libavutil/dict.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 
@@ -36,7 +37,9 @@
 #include "internal.h"
 
 typedef struct ResampleContext {
+    const AVClass *class;
     AVAudioResampleContext *avr;
+    AVDictionary *options;
 
     int64_t next_pts;
 
@@ -44,6 +47,33 @@ typedef struct ResampleContext {
     int got_output;
 } ResampleContext;
 
+static av_cold int init(AVFilterContext *ctx, AVDictionary **opts)
+{
+    ResampleContext *s = ctx->priv;
+    const AVClass *avr_class = avresample_get_class();
+    AVDictionaryEntry *e = NULL;
+
+    while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
+        if (av_opt_find(&avr_class, e->key, NULL, 0,
+                        AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN))
+            av_dict_set(&s->options, e->key, e->value, 0);
+    }
+
+    e = NULL;
+    while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
+        av_dict_set(opts, e->key, NULL, 0);
+
+    /* do not allow the user to override basic format options */
+    av_dict_set(&s->options,  "in_channel_layout", NULL, 0);
+    av_dict_set(&s->options, "out_channel_layout", NULL, 0);
+    av_dict_set(&s->options,  "in_sample_fmt",     NULL, 0);
+    av_dict_set(&s->options, "out_sample_fmt",     NULL, 0);
+    av_dict_set(&s->options,  "in_sample_rate",    NULL, 0);
+    av_dict_set(&s->options, "out_sample_rate",    NULL, 0);
+
+    return 0;
+}
+
 static av_cold void uninit(AVFilterContext *ctx)
 {
     ResampleContext *s = ctx->priv;
@@ -52,6 +82,7 @@ static av_cold void uninit(AVFilterContext *ctx)
         avresample_close(s->avr);
         avresample_free(&s->avr);
     }
+    av_dict_free(&s->options);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -103,6 +134,14 @@ static int config_output(AVFilterLink *outlink)
     if (!(s->avr = avresample_alloc_context()))
         return AVERROR(ENOMEM);
 
+    if (s->options) {
+        AVDictionaryEntry *e = NULL;
+        while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
+            av_log(ctx, AV_LOG_VERBOSE, "lavr option: %s=%s\n", e->key, e->value);
+
+        av_opt_set_dict(s->avr, &s->options);
+    }
+
     av_opt_set_int(s->avr,  "in_channel_layout", inlink ->channel_layout, 0);
     av_opt_set_int(s->avr, "out_channel_layout", outlink->channel_layout, 0);
     av_opt_set_int(s->avr,  "in_sample_fmt",     inlink ->format,         0);
@@ -140,7 +179,7 @@ static int request_frame(AVFilterLink *outlink)
 
     /* flush the lavr delay buffer */
     if (ret == AVERROR_EOF && s->avr) {
-        AVFilterBufferRef *buf;
+        AVFrame *frame;
         int nb_samples = av_rescale_rnd(avresample_get_delay(s->avr),
                                         outlink->sample_rate,
                                         ctx->inputs[0]->sample_rate,
@@ -149,25 +188,25 @@ static int request_frame(AVFilterLink *outlink)
         if (!nb_samples)
             return ret;
 
-        buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
-        if (!buf)
+        frame = ff_get_audio_buffer(outlink, nb_samples);
+        if (!frame)
             return AVERROR(ENOMEM);
 
-        ret = avresample_convert(s->avr, buf->extended_data,
-                                 buf->linesize[0], nb_samples,
+        ret = avresample_convert(s->avr, frame->extended_data,
+                                 frame->linesize[0], nb_samples,
                                  NULL, 0, 0);
         if (ret <= 0) {
-            avfilter_unref_buffer(buf);
+            av_frame_free(&frame);
             return (ret == 0) ? AVERROR_EOF : ret;
         }
 
-        buf->pts = s->next_pts;
-        return ff_filter_frame(outlink, buf);
+        frame->pts = s->next_pts;
+        return ff_filter_frame(outlink, frame);
     }
     return ret;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext  *ctx = inlink->dst;
     ResampleContext    *s = ctx->priv;
@@ -175,27 +214,26 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
     int ret;
 
     if (s->avr) {
-        AVFilterBufferRef *buf_out;
+        AVFrame *out;
         int delay, nb_samples;
 
         /* maximum possible samples lavr can output */
         delay      = avresample_get_delay(s->avr);
-        nb_samples = av_rescale_rnd(buf->audio->nb_samples + delay,
+        nb_samples = av_rescale_rnd(in->nb_samples + delay,
                                     outlink->sample_rate, inlink->sample_rate,
                                     AV_ROUND_UP);
 
-        buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
-        if (!buf_out) {
+        out = ff_get_audio_buffer(outlink, nb_samples);
+        if (!out) {
             ret = AVERROR(ENOMEM);
             goto fail;
         }
 
-        ret     = avresample_convert(s->avr, buf_out->extended_data,
-                                     buf_out->linesize[0], nb_samples,
-                                     buf->extended_data, buf->linesize[0],
-                                     buf->audio->nb_samples);
+        ret = avresample_convert(s->avr, out->extended_data, out->linesize[0],
+                                 nb_samples, in->extended_data, in->linesize[0],
+                                 in->nb_samples);
         if (ret <= 0) {
-            avfilter_unref_buffer(buf_out);
+            av_frame_free(&out);
             if (ret < 0)
                 goto fail;
         }
@@ -203,48 +241,66 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
         av_assert0(!avresample_available(s->avr));
 
         if (s->next_pts == AV_NOPTS_VALUE) {
-            if (buf->pts == AV_NOPTS_VALUE) {
+            if (in->pts == AV_NOPTS_VALUE) {
                 av_log(ctx, AV_LOG_WARNING, "First timestamp is missing, "
                        "assuming 0.\n");
                 s->next_pts = 0;
             } else
-                s->next_pts = av_rescale_q(buf->pts, inlink->time_base,
+                s->next_pts = av_rescale_q(in->pts, inlink->time_base,
                                            outlink->time_base);
         }
 
         if (ret > 0) {
-            buf_out->audio->nb_samples = ret;
-            if (buf->pts != AV_NOPTS_VALUE) {
-                buf_out->pts = av_rescale_q(buf->pts, inlink->time_base,
+            out->nb_samples = ret;
+            if (in->pts != AV_NOPTS_VALUE) {
+                out->pts = av_rescale_q(in->pts, inlink->time_base,
                                             outlink->time_base) -
                                av_rescale(delay, outlink->sample_rate,
                                           inlink->sample_rate);
             } else
-                buf_out->pts = s->next_pts;
+                out->pts = s->next_pts;
 
-            s->next_pts = buf_out->pts + buf_out->audio->nb_samples;
+            s->next_pts = out->pts + out->nb_samples;
 
-            ret = ff_filter_frame(outlink, buf_out);
+            ret = ff_filter_frame(outlink, out);
             s->got_output = 1;
         }
 
 fail:
-        avfilter_unref_buffer(buf);
+        av_frame_free(&in);
     } else {
-        buf->format = outlink->format;
-        ret = ff_filter_frame(outlink, buf);
+        in->format = outlink->format;
+        ret = ff_filter_frame(outlink, in);
         s->got_output = 1;
     }
 
     return ret;
 }
 
+static const AVClass *resample_child_class_next(const AVClass *prev)
+{
+    return prev ? NULL : avresample_get_class();
+}
+
+static void *resample_child_next(void *obj, void *prev)
+{
+    ResampleContext *s = obj;
+    return prev ? NULL : s->avr;
+}
+
+static const AVClass resample_class = {
+    .class_name       = "resample",
+    .item_name        = av_default_item_name,
+    .version          = LIBAVUTIL_VERSION_INT,
+    .child_class_next = resample_child_class_next,
+    .child_next       = resample_child_next,
+};
+
 static const AVFilterPad avfilter_af_resample_inputs[] = {
     {
         .name           = "default",
         .type           = AVMEDIA_TYPE_AUDIO,
         .filter_frame   = filter_frame,
-        .min_perms      = AV_PERM_READ
     },
     { NULL }
 };
@@ -259,11 +315,13 @@ static const AVFilterPad avfilter_af_resample_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_resample = {
+AVFilter ff_af_resample = {
     .name          = "resample",
     .description   = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
     .priv_size     = sizeof(ResampleContext),
+    .priv_class    = &resample_class,
 
+    .init_dict      = init,
     .uninit         = uninit,
     .query_formats  = query_formats,
 
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
index 3f3ad47..85d7067 100644
--- a/libavfilter/af_volume.c
+++ b/libavfilter/af_volume.c
@@ -24,7 +24,7 @@
  * audio volume filter
  */
 
-#include "libavutil/audioconvert.h"
+#include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
 #include "libavutil/float_dsp.h"
@@ -60,18 +60,9 @@ static const AVClass volume_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     VolumeContext *vol = ctx->priv;
-    int ret;
-
-    vol->class = &volume_class;
-    av_opt_set_defaults(vol);
-
-    if ((ret = av_set_options_string(vol, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
-        return ret;
-    }
 
     if (vol->precision == PRECISION_FIXED) {
         vol->volume_i = (int)(vol->volume * 256 + 0.5);
@@ -84,8 +75,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
                precision_str[vol->precision]);
     }
 
-    av_opt_free(vol);
-    return ret;
+    return 0;
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -184,7 +174,7 @@ static inline void scale_samples_s32(uint8_t *dst, const uint8_t *src,
 
 
 
-static void volume_init(VolumeContext *vol)
+static av_cold void volume_init(VolumeContext *vol)
 {
     vol->samples_align = 1;
 
@@ -233,21 +223,21 @@ static int config_output(AVFilterLink *outlink)
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
 {
     VolumeContext *vol    = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
-    int nb_samples        = buf->audio->nb_samples;
-    AVFilterBufferRef *out_buf;
+    int nb_samples        = buf->nb_samples;
+    AVFrame *out_buf;
 
     if (vol->volume == 1.0 || vol->volume_i == 256)
         return ff_filter_frame(outlink, buf);
 
     /* do volume scaling in-place if input buffer is writable */
-    if (buf->perms & AV_PERM_WRITE) {
+    if (av_frame_is_writable(buf)) {
         out_buf = buf;
     } else {
-        out_buf = ff_get_audio_buffer(inlink, AV_PERM_WRITE, nb_samples);
+        out_buf = ff_get_audio_buffer(inlink, nb_samples);
         if (!out_buf)
             return AVERROR(ENOMEM);
         out_buf->pts = buf->pts;
@@ -283,7 +273,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
     }
 
     if (buf != out_buf)
-        avfilter_unref_buffer(buf);
+        av_frame_free(&buf);
 
     return ff_filter_frame(outlink, out_buf);
 }
@@ -306,11 +296,12 @@ static const AVFilterPad avfilter_af_volume_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_volume = {
+AVFilter ff_af_volume = {
     .name           = "volume",
     .description    = NULL_IF_CONFIG_SMALL("Change input volume."),
     .query_formats  = query_formats,
     .priv_size      = sizeof(VolumeContext),
+    .priv_class     = &volume_class,
     .init           = init,
     .inputs         = avfilter_af_volume_inputs,
     .outputs        = avfilter_af_volume_outputs,
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index f3ce91c..f041f5c 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -25,15 +25,15 @@
 
 #define REGISTER_FILTER(X, x, y)                                        \
     {                                                                   \
-        extern AVFilter avfilter_##y##_##x;                             \
+        extern AVFilter ff_##y##_##x;                                   \
         if (CONFIG_##X##_FILTER)                                        \
-            avfilter_register(&avfilter_##y##_##x);                     \
+            avfilter_register(&ff_##y##_##x);                           \
     }
 
 #define REGISTER_FILTER_UNCONDITIONAL(x)                                \
     {                                                                   \
-        extern AVFilter avfilter_##x;                                   \
-        avfilter_register(&avfilter_##x);                               \
+        extern AVFilter ff_##x;                                         \
+        avfilter_register(&ff_##x);                                     \
     }
 
 void avfilter_register_all(void)
@@ -47,9 +47,11 @@ void avfilter_register_all(void)
     REGISTER_FILTER(AFORMAT,        aformat,        af);
     REGISTER_FILTER(AMIX,           amix,           af);
     REGISTER_FILTER(ANULL,          anull,          af);
+    REGISTER_FILTER(ASETPTS,        asetpts,        af);
     REGISTER_FILTER(ASHOWINFO,      ashowinfo,      af);
     REGISTER_FILTER(ASPLIT,         asplit,         af);
     REGISTER_FILTER(ASYNCTS,        asyncts,        af);
+    REGISTER_FILTER(ATRIM,          atrim,          af);
     REGISTER_FILTER(CHANNELMAP,     channelmap,     af);
     REGISTER_FILTER(CHANNELSPLIT,   channelsplit,   af);
     REGISTER_FILTER(JOIN,           join,           af);
@@ -76,6 +78,7 @@ void avfilter_register_all(void)
     REGISTER_FILTER(GRADFUN,        gradfun,        vf);
     REGISTER_FILTER(HFLIP,          hflip,          vf);
     REGISTER_FILTER(HQDN3D,         hqdn3d,         vf);
+    REGISTER_FILTER(INTERLACE,      interlace,      vf);
     REGISTER_FILTER(LUT,            lut,            vf);
     REGISTER_FILTER(LUTRGB,         lutrgb,         vf);
     REGISTER_FILTER(LUTYUV,         lutyuv,         vf);
@@ -95,6 +98,7 @@ void avfilter_register_all(void)
     REGISTER_FILTER(SHOWINFO,       showinfo,       vf);
     REGISTER_FILTER(SPLIT,          split,          vf);
     REGISTER_FILTER(TRANSPOSE,      transpose,      vf);
+    REGISTER_FILTER(TRIM,           trim,           vf);
     REGISTER_FILTER(UNSHARP,        unsharp,        vf);
     REGISTER_FILTER(VFLIP,          vflip,          vf);
     REGISTER_FILTER(YADIF,          yadif,          vf);
diff --git a/libavfilter/asink_anullsink.c b/libavfilter/asink_anullsink.c
index ede54c0..44f547d 100644
--- a/libavfilter/asink_anullsink.c
+++ b/libavfilter/asink_anullsink.c
@@ -20,9 +20,9 @@
 #include "avfilter.h"
 #include "internal.h"
 
-static int null_filter_frame(AVFilterLink *link, AVFilterBufferRef *samplesref)
+static int null_filter_frame(AVFilterLink *link, AVFrame *frame)
 {
-    avfilter_unref_bufferp(&samplesref);
+    av_frame_free(&frame);
     return 0;
 }
 
@@ -35,7 +35,7 @@ static const AVFilterPad avfilter_asink_anullsink_inputs[] = {
     { NULL },
 };
 
-AVFilter avfilter_asink_anullsink = {
+AVFilter ff_asink_anullsink = {
     .name        = "anullsink",
     .description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input audio."),
 
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index 4cbaa81..b1a449c 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -29,78 +29,24 @@
 #include "avfilter.h"
 #include "internal.h"
 
-typedef struct {
-    uint64_t channel_layout;
-    int64_t sample_rate;
-} ANullContext;
-
-static int init(AVFilterContext *ctx, const char *args)
-{
-    ANullContext *priv = ctx->priv;
-    char channel_layout_str[128] = "";
-
-    priv->sample_rate = 44100;
-    priv->channel_layout = AV_CH_LAYOUT_STEREO;
-
-    if (args)
-        sscanf(args, "%"PRId64":%s", &priv->sample_rate, channel_layout_str);
-
-    if (priv->sample_rate < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid negative sample rate: %"PRId64"\n", priv->sample_rate);
-        return AVERROR(EINVAL);
-    }
-
-    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);
-        }
-
-    return 0;
-}
-
-static int config_props(AVFilterLink *outlink)
-{
-    ANullContext *priv = outlink->src->priv;
-    char buf[128];
-    int chans_nb;
-
-    outlink->sample_rate = priv->sample_rate;
-    outlink->channel_layout = priv->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);
-    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);
-
-    return 0;
-}
-
 static int request_frame(AVFilterLink *link)
 {
-    return -1;
+    return AVERROR_EOF;
 }
 
 static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = {
     {
         .name          = "default",
         .type          = AVMEDIA_TYPE_AUDIO,
-        .config_props  = config_props,
         .request_frame = request_frame,
     },
     { NULL }
 };
 
-AVFilter avfilter_asrc_anullsrc = {
+AVFilter ff_asrc_anullsrc = {
     .name        = "anullsrc",
     .description = NULL_IF_CONFIG_SMALL("Null audio source, never return audio frames."),
 
-    .init        = init,
-    .priv_size   = sizeof(ANullContext),
-
     .inputs      = NULL,
 
     .outputs     = avfilter_asrc_anullsrc_outputs,
diff --git a/libavfilter/audio.c b/libavfilter/audio.c
index bbe12b2..b332e9e 100644
--- a/libavfilter/audio.c
+++ b/libavfilter/audio.c
@@ -23,60 +23,51 @@
 #include "avfilter.h"
 #include "internal.h"
 
-AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
-                                            int nb_samples)
+AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples)
 {
-    return ff_get_audio_buffer(link->dst->outputs[0], perms, nb_samples);
+    return ff_get_audio_buffer(link->dst->outputs[0], nb_samples);
 }
 
-AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
-                                               int nb_samples)
+AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples)
 {
-    AVFilterBufferRef *samplesref = NULL;
-    uint8_t **data;
-    int planar      = av_sample_fmt_is_planar(link->format);
-    int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
-    int planes      = planar ? nb_channels : 1;
-    int linesize;
-
-    if (!(data = av_mallocz(sizeof(*data) * planes)))
-        goto fail;
-
-    if (av_samples_alloc(data, &linesize, nb_channels, nb_samples, link->format, 0) < 0)
-        goto fail;
+    AVFrame *frame = av_frame_alloc();
+    int channels = av_get_channel_layout_nb_channels(link->channel_layout);
+    int ret;
+
+    if (!frame)
+        return NULL;
+
+    frame->nb_samples     = nb_samples;
+    frame->format         = link->format;
+    frame->channel_layout = link->channel_layout;
+    frame->sample_rate    = link->sample_rate;
+    ret = av_frame_get_buffer(frame, 0);
+    if (ret < 0) {
+        av_frame_free(&frame);
+        return NULL;
+    }
 
-    samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms,
-                                                           nb_samples, link->format,
-                                                           link->channel_layout);
-    if (!samplesref)
-        goto fail;
+    av_samples_set_silence(frame->extended_data, 0, nb_samples, channels,
+                           link->format);
 
-    av_freep(&data);
 
-fail:
-    if (data)
-        av_freep(&data[0]);
-    av_freep(&data);
-    return samplesref;
+    return frame;
 }
 
-AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
-                                       int nb_samples)
+AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
 {
-    AVFilterBufferRef *ret = NULL;
+    AVFrame *ret = NULL;
 
     if (link->dstpad->get_audio_buffer)
-        ret = link->dstpad->get_audio_buffer(link, perms, nb_samples);
+        ret = link->dstpad->get_audio_buffer(link, nb_samples);
 
     if (!ret)
-        ret = ff_default_get_audio_buffer(link, perms, nb_samples);
-
-    if (ret)
-        ret->type = AVMEDIA_TYPE_AUDIO;
+        ret = ff_default_get_audio_buffer(link, nb_samples);
 
     return ret;
 }
 
+#if FF_API_AVFILTERBUFFER
 AVFilterBufferRef* avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
                                                              int linesize,int perms,
                                                              int nb_samples,
@@ -146,3 +137,4 @@ fail:
     av_freep(&samples);
     return NULL;
 }
+#endif
diff --git a/libavfilter/audio.h b/libavfilter/audio.h
index a377503..4684b6c 100644
--- a/libavfilter/audio.h
+++ b/libavfilter/audio.h
@@ -22,24 +22,20 @@
 #include "avfilter.h"
 
 /** default handler for get_audio_buffer() for audio inputs */
-AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
-                                                     int nb_samples);
+AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples);
 
 /** get_audio_buffer() handler for filters which simply pass audio along */
-AVFilterBufferRef *ff_null_get_audio_buffer(AVFilterLink *link, int perms,
-                                                  int nb_samples);
+AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int nb_samples);
 
 /**
  * Request an audio samples buffer with a specific set of permissions.
  *
  * @param link           the output link to the filter from which the buffer will
  *                       be requested
- * @param perms          the required access permissions
  * @param nb_samples     the number of samples per channel
  * @return               A reference to the samples. This must be unreferenced with
  *                       avfilter_unref_buffer when you are finished with it.
  */
-AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
-                                             int nb_samples);
+AVFrame *ff_get_audio_buffer(AVFilterLink *link, int nb_samples);
 
 #endif /* AVFILTER_AUDIO_H */
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 93302cc..b18c0cb 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -19,11 +19,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/* #define DEBUG */
-
+#include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/rational.h"
 #include "libavutil/samplefmt.h"
@@ -34,7 +35,8 @@
 #include "internal.h"
 #include "video.h"
 
-unsigned avfilter_version(void) {
+unsigned avfilter_version(void)
+{
     return LIBAVFILTER_VERSION_INT;
 }
 
@@ -59,13 +61,13 @@ void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
 
     *pads  = av_realloc(*pads,  sizeof(AVFilterPad)   * (*count + 1));
     *links = av_realloc(*links, sizeof(AVFilterLink*) * (*count + 1));
-    memmove(*pads +idx+1, *pads +idx, sizeof(AVFilterPad)   * (*count-idx));
-    memmove(*links+idx+1, *links+idx, sizeof(AVFilterLink*) * (*count-idx));
-    memcpy(*pads+idx, newpad, sizeof(AVFilterPad));
+    memmove(*pads  + idx + 1, *pads  + idx, sizeof(AVFilterPad)   * (*count - idx));
+    memmove(*links + idx + 1, *links + idx, sizeof(AVFilterLink*) * (*count - idx));
+    memcpy(*pads + idx, newpad, sizeof(AVFilterPad));
     (*links)[idx] = NULL;
 
     (*count)++;
-    for (i = idx+1; i < *count; i++)
+    for (i = idx + 1; i < *count; i++)
         if (*links[i])
             (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++;
 }
@@ -86,8 +88,11 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad,
         return AVERROR(EINVAL);
     }
 
-    src->outputs[srcpad] =
-    dst-> inputs[dstpad] = link = av_mallocz(sizeof(AVFilterLink));
+    link = av_mallocz(sizeof(*link));
+    if (!link)
+        return AVERROR(ENOMEM);
+
+    src->outputs[srcpad] = dst->inputs[dstpad] = link;
 
     link->src     = src;
     link->dst     = dst;
@@ -118,18 +123,18 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
     }
 
     /* re-hookup the link to the new destination filter we inserted */
-    link->dst = filt;
-    link->dstpad = &filt->input_pads[filt_srcpad_idx];
+    link->dst                     = filt;
+    link->dstpad                  = &filt->input_pads[filt_srcpad_idx];
     filt->inputs[filt_srcpad_idx] = link;
 
     /* if any information on supported media formats already exists on the
      * link, we need to preserve that */
     if (link->out_formats)
         ff_formats_changeref(&link->out_formats,
-                                   &filt->outputs[filt_dstpad_idx]->out_formats);
+                             &filt->outputs[filt_dstpad_idx]->out_formats);
     if (link->out_samplerates)
         ff_formats_changeref(&link->out_samplerates,
-                                   &filt->outputs[filt_dstpad_idx]->out_samplerates);
+                             &filt->outputs[filt_dstpad_idx]->out_samplerates);
     if (link->out_channel_layouts)
         ff_channel_layouts_changeref(&link->out_channel_layouts,
                                      &filt->outputs[filt_dstpad_idx]->out_channel_layouts);
@@ -265,51 +270,60 @@ int ff_poll_frame(AVFilterLink *link)
     return min;
 }
 
-#define MAX_REGISTERED_AVFILTERS_NB 64
-
-static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];
-
-static int next_registered_avfilter_idx = 0;
+static AVFilter *first_filter;
 
+#if !FF_API_NOCONST_GET_NAME
+const
+#endif
 AVFilter *avfilter_get_by_name(const char *name)
 {
-    int i;
+    const AVFilter *f = NULL;
 
-    for (i = 0; registered_avfilters[i]; i++)
-        if (!strcmp(registered_avfilters[i]->name, name))
-            return registered_avfilters[i];
+    if (!name)
+        return NULL;
+
+    while ((f = avfilter_next(f)))
+        if (!strcmp(f->name, name))
+            return f;
 
     return NULL;
 }
 
 int avfilter_register(AVFilter *filter)
 {
-    if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB)
-        return -1;
-
-    registered_avfilters[next_registered_avfilter_idx++] = filter;
+    AVFilter **f = &first_filter;
+    while (*f)
+        f = &(*f)->next;
+    *f = filter;
+    filter->next = NULL;
     return 0;
 }
 
+const AVFilter *avfilter_next(const AVFilter *prev)
+{
+    return prev ? prev->next : first_filter;
+}
+
+#if FF_API_OLD_FILTER_REGISTER
 AVFilter **av_filter_next(AVFilter **filter)
 {
-    return filter ? ++filter : &registered_avfilters[0];
+    return filter ? &(*filter)->next : &first_filter;
 }
 
 void avfilter_uninit(void)
 {
-    memset(registered_avfilters, 0, sizeof(registered_avfilters));
-    next_registered_avfilter_idx = 0;
 }
+#endif
 
-static int pad_count(const AVFilterPad *pads)
+int avfilter_pad_count(const AVFilterPad *pads)
 {
     int count;
 
     if (!pads)
         return 0;
 
-    for(count = 0; pads->name; count ++) pads ++;
+    for (count = 0; pads->name; count++)
+        pads++;
     return count;
 }
 
@@ -319,24 +333,70 @@ static const char *filter_name(void *p)
     return filter->filter->name;
 }
 
+static void *filter_child_next(void *obj, void *prev)
+{
+    AVFilterContext *ctx = obj;
+    if (!prev && ctx->filter && ctx->filter->priv_class && ctx->priv)
+        return ctx->priv;
+    return NULL;
+}
+
+static const AVClass *filter_child_class_next(const AVClass *prev)
+{
+    const AVFilter *f = NULL;
+
+    while (prev && (f = avfilter_next(f)))
+        if (f->priv_class == prev)
+            break;
+
+    while ((f = avfilter_next(f)))
+        if (f->priv_class)
+            return f->priv_class;
+
+    return NULL;
+}
+
+#define OFFSET(x) offsetof(AVFilterContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption avfilter_options[] = {
+    { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
+        { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" },
+        { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .unit = "thread_type" },
+    { NULL },
+};
+
 static const AVClass avfilter_class = {
-    "AVFilter",
-    filter_name,
-    NULL,
-    LIBAVUTIL_VERSION_INT,
+    .class_name = "AVFilter",
+    .item_name  = filter_name,
+    .version    = LIBAVUTIL_VERSION_INT,
+    .child_next = filter_child_next,
+    .child_class_next = filter_child_class_next,
+    .option           = avfilter_options,
 };
 
-int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
+static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg,
+                           int *ret, int nb_jobs)
+{
+    int i;
+
+    for (i = 0; i < nb_jobs; i++) {
+        int r = func(ctx, arg, i, nb_jobs);
+        if (ret)
+            ret[i] = r;
+    }
+    return 0;
+}
+
+AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name)
 {
     AVFilterContext *ret;
-    *filter_ctx = NULL;
 
     if (!filter)
-        return AVERROR(EINVAL);
+        return NULL;
 
     ret = av_mallocz(sizeof(AVFilterContext));
     if (!ret)
-        return AVERROR(ENOMEM);
+        return NULL;
 
     ret->av_class = &avfilter_class;
     ret->filter   = filter;
@@ -347,7 +407,18 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in
             goto err;
     }
 
-    ret->nb_inputs = pad_count(filter->inputs);
+    av_opt_set_defaults(ret);
+    if (filter->priv_class) {
+        *(const AVClass**)ret->priv = filter->priv_class;
+        av_opt_set_defaults(ret->priv);
+    }
+
+    ret->internal = av_mallocz(sizeof(*ret->internal));
+    if (!ret->internal)
+        goto err;
+    ret->internal->execute = default_execute;
+
+    ret->nb_inputs = avfilter_pad_count(filter->inputs);
     if (ret->nb_inputs ) {
         ret->input_pads   = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs);
         if (!ret->input_pads)
@@ -358,7 +429,7 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in
             goto err;
     }
 
-    ret->nb_outputs = pad_count(filter->outputs);
+    ret->nb_outputs = avfilter_pad_count(filter->outputs);
     if (ret->nb_outputs) {
         ret->output_pads  = av_malloc(sizeof(AVFilterPad) * ret->nb_outputs);
         if (!ret->output_pads)
@@ -369,12 +440,13 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in
             goto err;
     }
 #if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
     ret->output_count = ret->nb_outputs;
     ret->input_count  = ret->nb_inputs;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
-    *filter_ctx = ret;
-    return 0;
+    return ret;
 
 err:
     av_freep(&ret->inputs);
@@ -384,84 +456,280 @@ err:
     av_freep(&ret->output_pads);
     ret->nb_outputs = 0;
     av_freep(&ret->priv);
+    av_freep(&ret->internal);
     av_free(ret);
-    return AVERROR(ENOMEM);
+    return NULL;
+}
+
+#if FF_API_AVFILTER_OPEN
+int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
+{
+    *filter_ctx = ff_filter_alloc(filter, inst_name);
+    return *filter_ctx ? 0 : AVERROR(ENOMEM);
+}
+#endif
+
+static void free_link(AVFilterLink *link)
+{
+    if (!link)
+        return;
+
+    if (link->src)
+        link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
+    if (link->dst)
+        link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
+
+    ff_formats_unref(&link->in_formats);
+    ff_formats_unref(&link->out_formats);
+    ff_formats_unref(&link->in_samplerates);
+    ff_formats_unref(&link->out_samplerates);
+    ff_channel_layouts_unref(&link->in_channel_layouts);
+    ff_channel_layouts_unref(&link->out_channel_layouts);
+    av_freep(&link);
 }
 
 void avfilter_free(AVFilterContext *filter)
 {
     int i;
-    AVFilterLink *link;
+
+    if (filter->graph)
+        ff_filter_graph_remove_filter(filter->graph, filter);
 
     if (filter->filter->uninit)
         filter->filter->uninit(filter);
 
     for (i = 0; i < filter->nb_inputs; i++) {
-        if ((link = filter->inputs[i])) {
-            if (link->src)
-                link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
-            ff_formats_unref(&link->in_formats);
-            ff_formats_unref(&link->out_formats);
-            ff_formats_unref(&link->in_samplerates);
-            ff_formats_unref(&link->out_samplerates);
-            ff_channel_layouts_unref(&link->in_channel_layouts);
-            ff_channel_layouts_unref(&link->out_channel_layouts);
-        }
-        av_freep(&link);
+        free_link(filter->inputs[i]);
     }
     for (i = 0; i < filter->nb_outputs; i++) {
-        if ((link = filter->outputs[i])) {
-            if (link->dst)
-                link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
-            ff_formats_unref(&link->in_formats);
-            ff_formats_unref(&link->out_formats);
-            ff_formats_unref(&link->in_samplerates);
-            ff_formats_unref(&link->out_samplerates);
-            ff_channel_layouts_unref(&link->in_channel_layouts);
-            ff_channel_layouts_unref(&link->out_channel_layouts);
-        }
-        av_freep(&link);
+        free_link(filter->outputs[i]);
     }
 
+    if (filter->filter->priv_class)
+        av_opt_free(filter->priv);
+
     av_freep(&filter->name);
     av_freep(&filter->input_pads);
     av_freep(&filter->output_pads);
     av_freep(&filter->inputs);
     av_freep(&filter->outputs);
     av_freep(&filter->priv);
+    av_freep(&filter->internal);
     av_free(filter);
 }
 
+/* process a list of value1:value2:..., each value corresponding
+ * to subsequent AVOption, in the order they are declared */
+static int process_unnamed_options(AVFilterContext *ctx, AVDictionary **options,
+                                   const char *args)
+{
+    const AVOption *o = NULL;
+    const char *p = args;
+    char *val;
+
+    while (*p) {
+        o = av_opt_next(ctx->priv, o);
+        if (!o) {
+            av_log(ctx, AV_LOG_ERROR, "More options provided than "
+                   "this filter supports.\n");
+            return AVERROR(EINVAL);
+        }
+        if (o->type == AV_OPT_TYPE_CONST)
+            continue;
+
+        val = av_get_token(&p, ":");
+        if (!val)
+            return AVERROR(ENOMEM);
+
+        av_dict_set(options, o->name, val, 0);
+
+        av_freep(&val);
+        if (*p)
+            p++;
+    }
+
+    return 0;
+}
+
+#if FF_API_AVFILTER_INIT_FILTER
 int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
 {
-    int ret=0;
+    return avfilter_init_str(filter, args);
+}
+#endif
+
+int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
+{
+    int ret = 0;
+
+    ret = av_opt_set_dict(ctx, options);
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error applying generic filter options.\n");
+        return ret;
+    }
+
+    if (ctx->filter->flags & AVFILTER_FLAG_SLICE_THREADS &&
+        ctx->thread_type & ctx->graph->thread_type & AVFILTER_THREAD_SLICE &&
+        ctx->graph->internal->thread_execute) {
+        ctx->thread_type       = AVFILTER_THREAD_SLICE;
+        ctx->internal->execute = ctx->graph->internal->thread_execute;
+    } else {
+        ctx->thread_type = 0;
+    }
+
+    if (ctx->filter->priv_class) {
+        ret = av_opt_set_dict(ctx->priv, options);
+        if (ret < 0) {
+            av_log(ctx, AV_LOG_ERROR, "Error applying options to the filter.\n");
+            return ret;
+        }
+    }
+
+    if (ctx->filter->init)
+        ret = ctx->filter->init(ctx);
+    else if (ctx->filter->init_dict)
+        ret = ctx->filter->init_dict(ctx, options);
 
-    if (filter->filter->init)
-        ret = filter->filter->init(filter, args);
     return ret;
 }
 
-const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx)
+int avfilter_init_str(AVFilterContext *filter, const char *args)
+{
+    AVDictionary *options = NULL;
+    AVDictionaryEntry *e;
+    int ret = 0;
+
+    if (args && *args) {
+        if (!filter->filter->priv_class) {
+            av_log(filter, AV_LOG_ERROR, "This filter does not take any "
+                   "options, but options were provided: %s.\n", args);
+            return AVERROR(EINVAL);
+        }
+
+#if FF_API_OLD_FILTER_OPTS
+        if (!strcmp(filter->filter->name, "scale") &&
+            strchr(args, ':') && strchr(args, ':') < strchr(args, '=')) {
+            /* old w:h:flags=<flags> syntax */
+            char *copy = av_strdup(args);
+            char *p;
+
+            av_log(filter, AV_LOG_WARNING, "The <w>:<h>:flags=<flags> option "
+                   "syntax is deprecated. Use either <w>:<h>:<flags> or "
+                   "w=<w>:h=<h>:flags=<flags>.\n");
+
+            if (!copy) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+
+            p = strrchr(copy, ':');
+            if (p) {
+                *p++ = 0;
+                ret = av_dict_parse_string(&options, p, "=", ":", 0);
+            }
+            if (ret >= 0)
+                ret = process_unnamed_options(filter, &options, copy);
+            av_freep(&copy);
+
+            if (ret < 0)
+                goto fail;
+        } else
+#endif
+
+        if (strchr(args, '=')) {
+            /* assume a list of key1=value1:key2=value2:... */
+            ret = av_dict_parse_string(&options, args, "=", ":", 0);
+            if (ret < 0)
+                goto fail;
+#if FF_API_OLD_FILTER_OPTS
+        } else if (!strcmp(filter->filter->name, "format")     ||
+                   !strcmp(filter->filter->name, "noformat")   ||
+                   !strcmp(filter->filter->name, "frei0r")     ||
+                   !strcmp(filter->filter->name, "frei0r_src") ||
+                   !strcmp(filter->filter->name, "ocv")) {
+            /* a hack for compatibility with the old syntax
+             * replace colons with |s */
+            char *copy = av_strdup(args);
+            char *p    = copy;
+            int nb_leading = 0; // number of leading colons to skip
+
+            if (!copy) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+
+            if (!strcmp(filter->filter->name, "frei0r") ||
+                !strcmp(filter->filter->name, "ocv"))
+                nb_leading = 1;
+            else if (!strcmp(filter->filter->name, "frei0r_src"))
+                nb_leading = 3;
+
+            while (nb_leading--) {
+                p = strchr(p, ':');
+                if (!p) {
+                    p = copy + strlen(copy);
+                    break;
+                }
+                p++;
+            }
+
+            if (strchr(p, ':')) {
+                av_log(filter, AV_LOG_WARNING, "This syntax is deprecated. Use "
+                       "'|' to separate the list items.\n");
+            }
+
+            while ((p = strchr(p, ':')))
+                *p++ = '|';
+
+            ret = process_unnamed_options(filter, &options, copy);
+            av_freep(&copy);
+
+            if (ret < 0)
+                goto fail;
+#endif
+        } else {
+            ret = process_unnamed_options(filter, &options, args);
+            if (ret < 0)
+                goto fail;
+        }
+    }
+
+    ret = avfilter_init_dict(filter, &options);
+    if (ret < 0)
+        goto fail;
+
+    if ((e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+        av_log(filter, AV_LOG_ERROR, "No such option: %s.\n", e->key);
+        ret = AVERROR_OPTION_NOT_FOUND;
+        goto fail;
+    }
+
+fail:
+    av_dict_free(&options);
+
+    return ret;
+}
+
+const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx)
 {
     return pads[pad_idx].name;
 }
 
-enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx)
+enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx)
 {
     return pads[pad_idx].type;
 }
 
-static int default_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+static int default_filter_frame(AVFilterLink *link, AVFrame *frame)
 {
     return ff_filter_frame(link->dst->outputs[0], frame);
 }
 
-int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
 {
-    int (*filter_frame)(AVFilterLink *, AVFilterBufferRef *);
+    int (*filter_frame)(AVFilterLink *, AVFrame *);
     AVFilterPad *dst = link->dstpad;
-    AVFilterBufferRef *out;
-    int perms = frame->perms;
+    AVFrame *out;
 
     FF_DPRINTF_START(NULL, filter_frame);
     ff_dlog_link(NULL, link, 1);
@@ -469,49 +737,47 @@ int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
     if (!(filter_frame = dst->filter_frame))
         filter_frame = default_filter_frame;
 
-    if (frame->linesize[0] < 0)
-        perms |= AV_PERM_NEG_LINESIZES;
-    /* prepare to copy the frame if the buffer has insufficient permissions */
-    if ((dst->min_perms & perms) != dst->min_perms ||
-        dst->rej_perms & perms) {
-        av_log(link->dst, AV_LOG_DEBUG,
-               "Copying data in avfilter (have perms %x, need %x, reject %x)\n",
-               perms, link->dstpad->min_perms, link->dstpad->rej_perms);
+    /* copy the frame if needed */
+    if (dst->needs_writable && !av_frame_is_writable(frame)) {
+        av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n");
 
         switch (link->type) {
         case AVMEDIA_TYPE_VIDEO:
-            out = ff_get_video_buffer(link, dst->min_perms,
-                                      link->w, link->h);
+            out = ff_get_video_buffer(link, link->w, link->h);
             break;
         case AVMEDIA_TYPE_AUDIO:
-            out = ff_get_audio_buffer(link, dst->min_perms,
-                                      frame->audio->nb_samples);
+            out = ff_get_audio_buffer(link, frame->nb_samples);
             break;
         default: return AVERROR(EINVAL);
         }
         if (!out) {
-            avfilter_unref_buffer(frame);
+            av_frame_free(&frame);
             return AVERROR(ENOMEM);
         }
-        avfilter_copy_buffer_ref_props(out, frame);
+        av_frame_copy_props(out, frame);
 
         switch (link->type) {
         case AVMEDIA_TYPE_VIDEO:
             av_image_copy(out->data, out->linesize, frame->data, frame->linesize,
-                          frame->format, frame->video->w, frame->video->h);
+                          frame->format, frame->width, frame->height);
             break;
         case AVMEDIA_TYPE_AUDIO:
             av_samples_copy(out->extended_data, frame->extended_data,
-                            0, 0, frame->audio->nb_samples,
-                            av_get_channel_layout_nb_channels(frame->audio->channel_layout),
+                            0, 0, frame->nb_samples,
+                            av_get_channel_layout_nb_channels(frame->channel_layout),
                             frame->format);
             break;
         default: return AVERROR(EINVAL);
         }
 
-        avfilter_unref_buffer(frame);
+        av_frame_free(&frame);
     } else
         out = frame;
 
     return filter_frame(link, out);
 }
+
+const AVClass *avfilter_get_class(void)
+{
+    return &avfilter_class;
+}
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index c5f8d56..9f14afd 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -22,7 +22,20 @@
 #ifndef AVFILTER_AVFILTER_H
 #define AVFILTER_AVFILTER_H
 
+/**
+ * @file
+ * @ingroup lavfi
+ * Main libavfilter public API header
+ */
+
+/**
+ * @defgroup lavfi Libavfilter - graph-based frame editing library
+ * @{
+ */
+
+#include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
+#include "libavutil/frame.h"
 #include "libavutil/log.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/pixfmt.h"
@@ -54,6 +67,7 @@ typedef struct AVFilterLink    AVFilterLink;
 typedef struct AVFilterPad     AVFilterPad;
 typedef struct AVFilterFormats AVFilterFormats;
 
+#if FF_API_AVFILTERBUFFER
 /**
  * A reference-counted buffer data type used by the filter system. Filters
  * should not store pointers to this structure directly, but instead use the
@@ -177,6 +191,7 @@ typedef struct AVFilterBufferRef {
 /**
  * Copy properties of src to dst, without copying the actual data
  */
+attribute_deprecated
 void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src);
 
 /**
@@ -188,6 +203,7 @@ void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *s
  * @return      a new reference to the buffer with the same properties as the
  *              old, excluding any permissions denied by pmask
  */
+attribute_deprecated
 AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask);
 
 /**
@@ -199,6 +215,7 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask);
  * @note it is recommended to use avfilter_unref_bufferp() instead of this
  * function
  */
+attribute_deprecated
 void avfilter_unref_buffer(AVFilterBufferRef *ref);
 
 /**
@@ -208,7 +225,9 @@ void avfilter_unref_buffer(AVFilterBufferRef *ref);
  *
  * @param ref pointer to the buffer reference
  */
+attribute_deprecated
 void avfilter_unref_bufferp(AVFilterBufferRef **ref);
+#endif
 
 #if FF_API_AVFILTERPAD_PUBLIC
 /**
@@ -239,7 +258,7 @@ struct AVFilterPad {
      *
      * Input pads only.
      */
-    int min_perms;
+    attribute_deprecated int min_perms;
 
     /**
      * Permissions which are not accepted on incoming buffers. Any buffer
@@ -250,7 +269,7 @@ struct AVFilterPad {
      *
      * Input pads only.
      */
-    int rej_perms;
+    attribute_deprecated int rej_perms;
 
     /**
      * @deprecated unused
@@ -263,7 +282,7 @@ struct AVFilterPad {
      *
      * Input video pads only.
      */
-    AVFilterBufferRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h);
+    AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h);
 
     /**
      * Callback function to get an audio buffer. If NULL, the filter system will
@@ -271,8 +290,7 @@ struct AVFilterPad {
      *
      * Input audio pads only.
      */
-    AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms,
-                                           int nb_samples);
+    AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples);
 
     /**
      * @deprecated unused
@@ -294,7 +312,7 @@ struct AVFilterPad {
      * must ensure that samplesref is properly unreferenced on error if it
      * hasn't been passed on to another filter.
      */
-    int (*filter_frame)(AVFilterLink *link, AVFilterBufferRef *frame);
+    int (*filter_frame)(AVFilterLink *link, AVFrame *frame);
 
     /**
      * Frame poll callback. This returns the number of immediately available
@@ -339,10 +357,18 @@ struct AVFilterPad {
      * input pads only.
      */
     int needs_fifo;
+
+    int needs_writable;
 };
 #endif
 
 /**
+ * Get the number of elements in a NULL-terminated array of AVFilterPads (e.g.
+ * AVFilter.inputs/outputs).
+ */
+int avfilter_pad_count(const AVFilterPad *pads);
+
+/**
  * Get the name of an AVFilterPad.
  *
  * @param pads an array of AVFilterPads
@@ -351,7 +377,7 @@ struct AVFilterPad {
  *
  * @return name of the pad_idx'th pad in pads
  */
-const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx);
+const char *avfilter_pad_get_name(const AVFilterPad *pads, int pad_idx);
 
 /**
  * Get the type of an AVFilterPad.
@@ -362,23 +388,74 @@ const char *avfilter_pad_get_name(AVFilterPad *pads, int pad_idx);
  *
  * @return type of the pad_idx'th pad in pads
  */
-enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx);
+enum AVMediaType avfilter_pad_get_type(const AVFilterPad *pads, int pad_idx);
+
+/**
+ * The number of the filter inputs is not determined just by AVFilter.inputs.
+ * The filter might add additional inputs during initialization depending on the
+ * options supplied to it.
+ */
+#define AVFILTER_FLAG_DYNAMIC_INPUTS        (1 << 0)
+/**
+ * The number of the filter outputs is not determined just by AVFilter.outputs.
+ * The filter might add additional outputs during initialization depending on
+ * the options supplied to it.
+ */
+#define AVFILTER_FLAG_DYNAMIC_OUTPUTS       (1 << 1)
+/**
+ * The filter supports multithreading by splitting frames into multiple parts
+ * and processing them concurrently.
+ */
+#define AVFILTER_FLAG_SLICE_THREADS         (1 << 2)
 
 /**
  * Filter definition. This defines the pads a filter contains, and all the
  * callback functions used to interact with the filter.
  */
 typedef struct AVFilter {
-    const char *name;         ///< filter name
+    /**
+     * Filter name. Must be non-NULL and unique among filters.
+     */
+    const char *name;
 
     /**
-     * A description for the filter. You should use the
-     * NULL_IF_CONFIG_SMALL() macro to define it.
+     * A description of the filter. May be NULL.
+     *
+     * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
      */
     const char *description;
 
-    const AVFilterPad *inputs;  ///< NULL terminated list of inputs. NULL if none
-    const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none
+    /**
+     * List of inputs, terminated by a zeroed element.
+     *
+     * NULL if there are no (static) inputs. Instances of filters with
+     * AVFILTER_FLAG_DYNAMIC_INPUTS set may have more inputs than present in
+     * this list.
+     */
+    const AVFilterPad *inputs;
+    /**
+     * List of outputs, terminated by a zeroed element.
+     *
+     * NULL if there are no (static) outputs. Instances of filters with
+     * AVFILTER_FLAG_DYNAMIC_OUTPUTS set may have more outputs than present in
+     * this list.
+     */
+    const AVFilterPad *outputs;
+
+    /**
+     * A class for the private data, used to declare filter private AVOptions.
+     * This field is NULL for filters that do not declare any options.
+     *
+     * If this field is non-NULL, the first member of the filter private data
+     * must be a pointer to AVClass, which will be set by libavfilter generic
+     * code to this class.
+     */
+    const AVClass *priv_class;
+
+    /**
+     * A combination of AVFILTER_FLAG_*
+     */
+    int flags;
 
     /*****************************************************************
      * All fields below this line are not part of the public API. They
@@ -389,22 +466,71 @@ typedef struct AVFilter {
      */
 
     /**
-     * Filter initialization function. Args contains the user-supplied
-     * parameters. FIXME: maybe an AVOption-based system would be better?
+     * Filter initialization function.
+     *
+     * This callback will be called only once during the filter lifetime, after
+     * all the options have been set, but before links between filters are
+     * established and format negotiation is done.
+     *
+     * Basic filter initialization should be done here. Filters with dynamic
+     * inputs and/or outputs should create those inputs/outputs here based on
+     * provided options. No more changes to this filter's inputs/outputs can be
+     * done after this callback.
+     *
+     * This callback must not assume that the filter links exist or frame
+     * parameters are known.
+     *
+     * @ref AVFilter.uninit "uninit" is guaranteed to be called even if
+     * initialization fails, so this callback does not have to clean up on
+     * failure.
+     *
+     * @return 0 on success, a negative AVERROR on failure
      */
-    int (*init)(AVFilterContext *ctx, const char *args);
+    int (*init)(AVFilterContext *ctx);
 
     /**
-     * Filter uninitialization function. Should deallocate any memory held
-     * by the filter, release any buffer references, etc. This does not need
-     * to deallocate the AVFilterContext->priv memory itself.
+     * Should be set instead of @ref AVFilter.init "init" by the filters that
+     * want to pass a dictionary of AVOptions to nested contexts that are
+     * allocated during init.
+     *
+     * On return, the options dict should be freed and replaced with one that
+     * contains all the options which could not be processed by this filter (or
+     * with NULL if all the options were processed).
+     *
+     * Otherwise the semantics is the same as for @ref AVFilter.init "init".
+     */
+    int (*init_dict)(AVFilterContext *ctx, AVDictionary **options);
+
+    /**
+     * Filter uninitialization function.
+     *
+     * Called only once right before the filter is freed. Should deallocate any
+     * memory held by the filter, release any buffer references, etc. It does
+     * not need to deallocate the AVFilterContext.priv memory itself.
+     *
+     * This callback may be called even if @ref AVFilter.init "init" was not
+     * called or failed, so it must be prepared to handle such a situation.
      */
     void (*uninit)(AVFilterContext *ctx);
 
     /**
-     * Queries formats 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.
+     * Query formats supported by the filter on its inputs and outputs.
+     *
+     * This callback is called after the filter is initialized (so the inputs
+     * and outputs are fixed), shortly before the format negotiation. This
+     * callback may be called more than once.
+     *
+     * This callback must set AVFilterLink.out_formats on every input link and
+     * AVFilterLink.in_formats on every output link to a list of pixel/sample
+     * formats that the filter supports on that link. For audio links, this
+     * filter must also set @ref AVFilterLink.in_samplerates "in_samplerates" /
+     * @ref AVFilterLink.out_samplerates "out_samplerates" and
+     * @ref AVFilterLink.in_channel_layouts "in_channel_layouts" /
+     * @ref AVFilterLink.out_channel_layouts "out_channel_layouts" analogously.
+     *
+     * This callback may be NULL for filters with one input, in which case
+     * libavfilter assumes that it supports all input formats and preserves
+     * them on output.
      *
      * @return zero on success, a negative value corresponding to an
      * AVERROR code otherwise
@@ -412,31 +538,69 @@ typedef struct AVFilter {
     int (*query_formats)(AVFilterContext *);
 
     int priv_size;      ///< size of private data to allocate for the filter
+
+    /**
+     * Used by the filter registration system. Must not be touched by any other
+     * code.
+     */
+    struct AVFilter *next;
 } AVFilter;
 
+/**
+ * Process multiple parts of the frame concurrently.
+ */
+#define AVFILTER_THREAD_SLICE (1 << 0)
+
+typedef struct AVFilterInternal AVFilterInternal;
+
 /** An instance of a filter */
 struct AVFilterContext {
     const AVClass *av_class;              ///< needed for av_log()
 
-    AVFilter *filter;               ///< the AVFilter of which this is an instance
+    const AVFilter *filter;         ///< the AVFilter of which this is an instance
 
     char *name;                     ///< name of this filter instance
 
     AVFilterPad   *input_pads;      ///< array of input pads
     AVFilterLink **inputs;          ///< array of pointers to input links
 #if FF_API_FOO_COUNT
-    unsigned input_count;           ///< @deprecated use nb_inputs
+    attribute_deprecated unsigned input_count; ///< @deprecated use nb_inputs
 #endif
     unsigned    nb_inputs;          ///< number of input pads
 
     AVFilterPad   *output_pads;     ///< array of output pads
     AVFilterLink **outputs;         ///< array of pointers to output links
 #if FF_API_FOO_COUNT
-    unsigned output_count;          ///< @deprecated use nb_outputs
+    attribute_deprecated unsigned output_count; ///< @deprecated use nb_outputs
 #endif
     unsigned    nb_outputs;         ///< number of output pads
 
     void *priv;                     ///< private data for use by the filter
+
+    struct AVFilterGraph *graph;    ///< filtergraph this filter belongs to
+
+    /**
+     * Type of multithreading being allowed/used. A combination of
+     * AVFILTER_THREAD_* flags.
+     *
+     * May be set by the caller before initializing the filter to forbid some
+     * or all kinds of multithreading for this filter. The default is allowing
+     * everything.
+     *
+     * When the filter is initialized, this field is combined using bit AND with
+     * AVFilterGraph.thread_type to get the final mask used for determining
+     * allowed threading types. I.e. a threading type needs to be set in both
+     * to be allowed.
+     *
+     * After the filter is initialzed, libavfilter sets this field to the
+     * threading type that is actually used (0 for no multithreading).
+     */
+    int thread_type;
+
+    /**
+     * An opaque struct for libavfilter internal use.
+     */
+    AVFilterInternal *internal;
 };
 
 /**
@@ -535,6 +699,7 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad,
  */
 int avfilter_config_links(AVFilterContext *filter);
 
+#if FF_API_AVFILTERBUFFER
 /**
  * Create a buffer reference wrapped around an already allocated image
  * buffer.
@@ -546,6 +711,7 @@ int avfilter_config_links(AVFilterContext *filter);
  * @param h the height of the image specified by the data and linesize arrays
  * @param format the pixel format of the image specified by the data and linesize arrays
  */
+attribute_deprecated
 AVFilterBufferRef *
 avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int perms,
                                           int w, int h, enum AVPixelFormat format);
@@ -561,24 +727,29 @@ avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int
  * @param sample_fmt     the format of each sample in the buffer to allocate
  * @param channel_layout the channel layout of the buffer
  */
+attribute_deprecated
 AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data,
                                                              int linesize,
                                                              int perms,
                                                              int nb_samples,
                                                              enum AVSampleFormat sample_fmt,
                                                              uint64_t channel_layout);
+#endif
 
 /** Initialize the filter system. Register all builtin filters. */
 void avfilter_register_all(void);
 
+#if FF_API_OLD_FILTER_REGISTER
 /** Uninitialize the filter system. Unregister all filters. */
+attribute_deprecated
 void avfilter_uninit(void);
+#endif
 
 /**
  * Register a filter. This is only needed if you plan to use
  * avfilter_get_by_name later to lookup the AVFilter structure by name. A
- * filter can still by instantiated with avfilter_open even if it is not
- * registered.
+ * filter can still by instantiated with avfilter_graph_alloc_filter even if it
+ * is not registered.
  *
  * @param filter the filter to register
  * @return 0 if the registration was succesfull, a negative value
@@ -593,16 +764,31 @@ int avfilter_register(AVFilter *filter);
  * @return     the filter definition, if any matching one is registered.
  *             NULL if none found.
  */
+#if !FF_API_NOCONST_GET_NAME
+const
+#endif
 AVFilter *avfilter_get_by_name(const char *name);
 
 /**
+ * Iterate over all registered filters.
+ * @return If prev is non-NULL, next registered filter after prev or NULL if
+ * prev is the last filter. If prev is NULL, return the first registered filter.
+ */
+const AVFilter *avfilter_next(const AVFilter *prev);
+
+#if FF_API_OLD_FILTER_REGISTER
+/**
  * If filter is NULL, returns a pointer to the first registered filter pointer,
  * if filter is non-NULL, returns the next pointer after filter.
  * If the returned pointer points to NULL, the last registered filter
  * was already reached.
+ * @deprecated use avfilter_next()
  */
+attribute_deprecated
 AVFilter **av_filter_next(AVFilter **filter);
+#endif
 
+#if FF_API_AVFILTER_OPEN
 /**
  * Create a filter instance.
  *
@@ -611,9 +797,14 @@ AVFilter **av_filter_next(AVFilter **filter);
  * @param filter    the filter to create an instance of
  * @param inst_name Name to give to the new instance. Can be NULL for none.
  * @return >= 0 in case of success, a negative error code otherwise
+ * @deprecated use avfilter_graph_alloc_filter() instead
  */
+attribute_deprecated
 int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name);
+#endif
 
+
+#if FF_API_AVFILTER_INIT_FILTER
 /**
  * Initialize a filter.
  *
@@ -624,10 +815,47 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in
  *               of this parameter varies by filter.
  * @return       zero on success
  */
+attribute_deprecated
 int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque);
+#endif
+
+/**
+ * Initialize a filter with the supplied parameters.
+ *
+ * @param ctx  uninitialized filter context to initialize
+ * @param args Options to initialize the filter with. This must be a
+ *             ':'-separated list of options in the 'key=value' form.
+ *             May be NULL if the options have been set directly using the
+ *             AVOptions API or there are no options that need to be set.
+ * @return 0 on success, a negative AVERROR on failure
+ */
+int avfilter_init_str(AVFilterContext *ctx, const char *args);
 
 /**
- * Free a filter context.
+ * Initialize a filter with the supplied dictionary of options.
+ *
+ * @param ctx     uninitialized filter context to initialize
+ * @param options An AVDictionary filled with options for this filter. On
+ *                return this parameter will be destroyed and replaced with
+ *                a dict containing options that were not found. This dictionary
+ *                must be freed by the caller.
+ *                May be NULL, then this function is equivalent to
+ *                avfilter_init_str() with the second parameter set to NULL.
+ * @return 0 on success, a negative AVERROR on failure
+ *
+ * @note This function and avfilter_init_str() do essentially the same thing,
+ * the difference is in manner in which the options are passed. It is up to the
+ * calling code to choose whichever is more preferable. The two functions also
+ * behave differently when some of the provided options are not declared as
+ * supported by the filter. In such a case, avfilter_init_str() will fail, but
+ * this function will leave those extra options in the options AVDictionary and
+ * continue as usual.
+ */
+int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options);
+
+/**
+ * Free a filter context. This will also remove the filter from its
+ * filtergraph's list of filters.
  *
  * @param filter the filter to free
  */
@@ -645,12 +873,14 @@ void avfilter_free(AVFilterContext *filter);
 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
                            unsigned filt_srcpad_idx, unsigned filt_dstpad_idx);
 
+#if FF_API_AVFILTERBUFFER
 /**
  * Copy the frame properties of src to dst, without copying the actual
  * image data.
  *
  * @return 0 on success, a negative number on error.
  */
+attribute_deprecated
 int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
 
 /**
@@ -659,6 +889,275 @@ int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
  *
  * @return 0 on success, a negative number on error.
  */
+attribute_deprecated
 int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src);
+#endif
+
+/**
+ * @return AVClass for AVFilterContext.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avfilter_get_class(void);
+
+typedef struct AVFilterGraphInternal AVFilterGraphInternal;
+
+/**
+ * A function pointer passed to the @ref AVFilterGraph.execute callback to be
+ * executed multiple times, possibly in parallel.
+ *
+ * @param ctx the filter context the job belongs to
+ * @param arg an opaque parameter passed through from @ref
+ *            AVFilterGraph.execute
+ * @param jobnr the index of the job being executed
+ * @param nb_jobs the total number of jobs
+ *
+ * @return 0 on success, a negative AVERROR on error
+ */
+typedef int (avfilter_action_func)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs);
+
+/**
+ * A function executing multiple jobs, possibly in parallel.
+ *
+ * @param ctx the filter context to which the jobs belong
+ * @param func the function to be called multiple times
+ * @param arg the argument to be passed to func
+ * @param ret a nb_jobs-sized array to be filled with return values from each
+ *            invocation of func
+ * @param nb_jobs the number of jobs to execute
+ *
+ * @return 0 on success, a negative AVERROR on error
+ */
+typedef int (avfilter_execute_func)(AVFilterContext *ctx, avfilter_action_func *func,
+                                    void *arg, int *ret, int nb_jobs);
+
+typedef struct AVFilterGraph {
+    const AVClass *av_class;
+#if FF_API_FOO_COUNT
+    attribute_deprecated
+    unsigned filter_count;
+#endif
+    AVFilterContext **filters;
+#if !FF_API_FOO_COUNT
+    unsigned nb_filters;
+#endif
+
+    char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters
+    char *resample_lavr_opts;   ///< libavresample options to use for the auto-inserted resample filters
+#if FF_API_FOO_COUNT
+    unsigned nb_filters;
+#endif
+
+    /**
+     * Type of multithreading allowed for filters in this graph. A combination
+     * of AVFILTER_THREAD_* flags.
+     *
+     * May be set by the caller at any point, the setting will apply to all
+     * filters initialized after that. The default is allowing everything.
+     *
+     * When a filter in this graph is initialized, this field is combined using
+     * bit AND with AVFilterContext.thread_type to get the final mask used for
+     * determining allowed threading types. I.e. a threading type needs to be
+     * set in both to be allowed.
+     */
+    int thread_type;
+
+    /**
+     * Maximum number of threads used by filters in this graph. May be set by
+     * the caller before adding any filters to the filtergraph. Zero (the
+     * default) means that the number of threads is determined automatically.
+     */
+    int nb_threads;
+
+    /**
+     * Opaque object for libavfilter internal use.
+     */
+    AVFilterGraphInternal *internal;
+
+    /**
+     * Opaque user data. May be set by the caller to an arbitrary value, e.g. to
+     * be used from callbacks like @ref AVFilterGraph.execute.
+     * Libavfilter will not touch this field in any way.
+     */
+    void *opaque;
+
+    /**
+     * This callback may be set by the caller immediately after allocating the
+     * graph and before adding any filters to it, to provide a custom
+     * multithreading implementation.
+     *
+     * If set, filters with slice threading capability will call this callback
+     * to execute multiple jobs in parallel.
+     *
+     * If this field is left unset, libavfilter will use its internal
+     * implementation, which may or may not be multithreaded depending on the
+     * platform and build options.
+     */
+    avfilter_execute_func *execute;
+} AVFilterGraph;
+
+/**
+ * Allocate a filter graph.
+ */
+AVFilterGraph *avfilter_graph_alloc(void);
+
+/**
+ * Create a new filter instance in a filter graph.
+ *
+ * @param graph graph in which the new filter will be used
+ * @param filter the filter to create an instance of
+ * @param name Name to give to the new instance (will be copied to
+ *             AVFilterContext.name). This may be used by the caller to identify
+ *             different filters, libavfilter itself assigns no semantics to
+ *             this parameter. May be NULL.
+ *
+ * @return the context of the newly created filter instance (note that it is
+ *         also retrievable directly through AVFilterGraph.filters or with
+ *         avfilter_graph_get_filter()) on success or NULL or failure.
+ */
+AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
+                                             const AVFilter *filter,
+                                             const char *name);
+
+/**
+ * Get a filter instance with name name from graph.
+ *
+ * @return the pointer to the found filter instance or NULL if it
+ * cannot be found.
+ */
+AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name);
+
+#if FF_API_AVFILTER_OPEN
+/**
+ * Add an existing filter instance to a filter graph.
+ *
+ * @param graphctx  the filter graph
+ * @param filter the filter to be added
+ *
+ * @deprecated use avfilter_graph_alloc_filter() to allocate a filter in a
+ * filter graph
+ */
+attribute_deprecated
+int avfilter_graph_add_filter(AVFilterGraph *graphctx, AVFilterContext *filter);
+#endif
+
+/**
+ * Create and add a filter instance into an existing graph.
+ * The filter instance is created from the filter filt and inited
+ * with the parameters args and opaque.
+ *
+ * In case of success put in *filt_ctx the pointer to the created
+ * filter instance, otherwise set *filt_ctx to NULL.
+ *
+ * @param name the instance name to give to the created filter instance
+ * @param graph_ctx the filter graph
+ * @return a negative AVERROR error code in case of failure, a non
+ * negative value otherwise
+ */
+int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
+                                 const char *name, const char *args, void *opaque,
+                                 AVFilterGraph *graph_ctx);
+
+/**
+ * Check validity and configure all the links and formats in the graph.
+ *
+ * @param graphctx the filter graph
+ * @param log_ctx context used for logging
+ * @return 0 in case of success, a negative AVERROR code otherwise
+ */
+int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx);
+
+/**
+ * Free a graph, destroy its links, and set *graph to NULL.
+ * If *graph is NULL, do nothing.
+ */
+void avfilter_graph_free(AVFilterGraph **graph);
+
+/**
+ * A linked-list of the inputs/outputs of the filter chain.
+ *
+ * This is mainly useful for avfilter_graph_parse() / avfilter_graph_parse2(),
+ * where it is used to communicate open (unlinked) inputs and outputs from and
+ * to the caller.
+ * This struct specifies, per each not connected pad contained in the graph, the
+ * filter context and the pad index required for establishing a link.
+ */
+typedef struct AVFilterInOut {
+    /** unique name for this input/output in the list */
+    char *name;
+
+    /** filter context associated to this input/output */
+    AVFilterContext *filter_ctx;
+
+    /** index of the filt_ctx pad to use for linking */
+    int pad_idx;
+
+    /** next input/input in the list, NULL if this is the last */
+    struct AVFilterInOut *next;
+} AVFilterInOut;
+
+/**
+ * Allocate a single AVFilterInOut entry.
+ * Must be freed with avfilter_inout_free().
+ * @return allocated AVFilterInOut on success, NULL on failure.
+ */
+AVFilterInOut *avfilter_inout_alloc(void);
+
+/**
+ * Free the supplied list of AVFilterInOut and set *inout to NULL.
+ * If *inout is NULL, do nothing.
+ */
+void avfilter_inout_free(AVFilterInOut **inout);
+
+/**
+ * Add a graph described by a string to a graph.
+ *
+ * @param graph   the filter graph where to link the parsed graph context
+ * @param filters string to be parsed
+ * @param inputs  linked list to the inputs of the graph
+ * @param outputs linked list to the outputs of the graph
+ * @return zero on success, a negative AVERROR code on error
+ */
+int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
+                         AVFilterInOut *inputs, AVFilterInOut *outputs,
+                         void *log_ctx);
+
+/**
+ * Add a graph described by a string to a graph.
+ *
+ * @param[in]  graph   the filter graph where to link the parsed graph context
+ * @param[in]  filters string to be parsed
+ * @param[out] inputs  a linked list of all free (unlinked) inputs of the
+ *                     parsed graph will be returned here. It is to be freed
+ *                     by the caller using avfilter_inout_free().
+ * @param[out] outputs a linked list of all free (unlinked) outputs of the
+ *                     parsed graph will be returned here. It is to be freed by the
+ *                     caller using avfilter_inout_free().
+ * @return zero on success, a negative AVERROR code on error
+ *
+ * @note the difference between avfilter_graph_parse2() and
+ * avfilter_graph_parse() is that in avfilter_graph_parse(), the caller provides
+ * the lists of inputs and outputs, which therefore must be known before calling
+ * the function. On the other hand, avfilter_graph_parse2() \em returns the
+ * inputs and outputs that are left unlinked after parsing the graph and the
+ * caller then deals with them. Another difference is that in
+ * avfilter_graph_parse(), the inputs parameter describes inputs of the
+ * <em>already existing</em> part of the graph; i.e. from the point of view of
+ * the newly created part, they are outputs. Similarly the outputs parameter
+ * describes outputs of the already existing filters, which are provided as
+ * inputs to the parsed filters.
+ * avfilter_graph_parse2() takes the opposite approach -- it makes no reference
+ * whatsoever to already existing parts of the graph and the inputs parameter
+ * will on return contain inputs of the newly parsed part of the graph.
+ * Analogously the outputs parameter will contain outputs of the newly created
+ * filters.
+ */
+int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters,
+                          AVFilterInOut **inputs,
+                          AVFilterInOut **outputs);
+
+/**
+ * @}
+ */
 
 #endif /* AVFILTER_AVFILTER_H */
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index d27b1b2..0fc385c 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -20,70 +20,139 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <ctype.h>
+#include "config.h"
+
 #include <string.h>
 
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
+#include "libavutil/internal.h"
 #include "libavutil/log.h"
+#include "libavutil/opt.h"
+
 #include "avfilter.h"
-#include "avfiltergraph.h"
 #include "formats.h"
 #include "internal.h"
+#include "thread.h"
+
+#define OFFSET(x) offsetof(AVFilterGraph, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption filtergraph_options[] = {
+    { "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,
+        { .i64 = AVFILTER_THREAD_SLICE }, 0, INT_MAX, FLAGS, "thread_type" },
+        { "slice", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AVFILTER_THREAD_SLICE }, .flags = FLAGS, .unit = "thread_type" },
+    { "threads",     "Maximum number of threads", OFFSET(nb_threads),
+        AV_OPT_TYPE_INT,   { .i64 = 0 }, 0, INT_MAX, FLAGS },
+    { NULL },
+};
 
 static const AVClass filtergraph_class = {
     .class_name = "AVFilterGraph",
     .item_name  = av_default_item_name,
     .version    = LIBAVUTIL_VERSION_INT,
+    .option     = filtergraph_options,
 };
 
+#if !HAVE_THREADS
+void ff_graph_thread_free(AVFilterGraph *graph)
+{
+}
+
+int ff_graph_thread_init(AVFilterGraph *graph)
+{
+    graph->thread_type = 0;
+    graph->nb_threads  = 1;
+    return 0;
+}
+#endif
+
 AVFilterGraph *avfilter_graph_alloc(void)
 {
-    AVFilterGraph *ret = av_mallocz(sizeof(AVFilterGraph));
+    AVFilterGraph *ret = av_mallocz(sizeof(*ret));
     if (!ret)
         return NULL;
+
+    ret->internal = av_mallocz(sizeof(*ret->internal));
+    if (!ret->internal) {
+        av_freep(&ret);
+        return NULL;
+    }
+
     ret->av_class = &filtergraph_class;
+    av_opt_set_defaults(ret);
+
     return ret;
 }
 
+void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
+{
+    int i;
+    for (i = 0; i < graph->nb_filters; i++) {
+        if (graph->filters[i] == filter) {
+            FFSWAP(AVFilterContext*, graph->filters[i],
+                   graph->filters[graph->nb_filters - 1]);
+            graph->nb_filters--;
+            return;
+        }
+    }
+}
+
 void avfilter_graph_free(AVFilterGraph **graph)
 {
     if (!*graph)
         return;
-    for (; (*graph)->filter_count > 0; (*graph)->filter_count--)
-        avfilter_free((*graph)->filters[(*graph)->filter_count - 1]);
+
+    while ((*graph)->nb_filters)
+        avfilter_free((*graph)->filters[0]);
+
+    ff_graph_thread_free(*graph);
+
     av_freep(&(*graph)->scale_sws_opts);
+    av_freep(&(*graph)->resample_lavr_opts);
     av_freep(&(*graph)->filters);
+    av_freep(&(*graph)->internal);
     av_freep(graph);
 }
 
+#if FF_API_AVFILTER_OPEN
 int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
 {
     AVFilterContext **filters = av_realloc(graph->filters,
-                                           sizeof(AVFilterContext*) * (graph->filter_count+1));
+                                           sizeof(*filters) * (graph->nb_filters + 1));
     if (!filters)
         return AVERROR(ENOMEM);
 
     graph->filters = filters;
-    graph->filters[graph->filter_count++] = filter;
+    graph->filters[graph->nb_filters++] = filter;
+
+#if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
+    graph->filter_count = graph->nb_filters;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+    filter->graph = graph;
 
     return 0;
 }
+#endif
 
-int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
+int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
                                  const char *name, const char *args, void *opaque,
                                  AVFilterGraph *graph_ctx)
 {
     int ret;
 
-    if ((ret = avfilter_open(filt_ctx, filt, name)) < 0)
-        goto fail;
-    if ((ret = avfilter_init_filter(*filt_ctx, args, opaque)) < 0)
-        goto fail;
-    if ((ret = avfilter_graph_add_filter(graph_ctx, *filt_ctx)) < 0)
+    *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
+    if (!*filt_ctx)
+        return AVERROR(ENOMEM);
+
+    ret = avfilter_init_str(*filt_ctx, args);
+    if (ret < 0)
         goto fail;
+
     return 0;
 
 fail:
@@ -93,6 +162,48 @@ fail:
     return ret;
 }
 
+AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
+                                             const AVFilter *filter,
+                                             const char *name)
+{
+    AVFilterContext **filters, *s;
+
+    if (graph->thread_type && !graph->internal->thread_execute) {
+        if (graph->execute) {
+            graph->internal->thread_execute = graph->execute;
+        } else {
+            int ret = ff_graph_thread_init(graph);
+            if (ret < 0) {
+                av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
+                return NULL;
+            }
+        }
+    }
+
+    s = ff_filter_alloc(filter, name);
+    if (!s)
+        return NULL;
+
+    filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1));
+    if (!filters) {
+        avfilter_free(s);
+        return NULL;
+    }
+
+    graph->filters = filters;
+    graph->filters[graph->nb_filters++] = s;
+
+#if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
+    graph->filter_count = graph->nb_filters;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+    s->graph = graph;
+
+    return s;
+}
+
 /**
  * Check for the validity of graph.
  *
@@ -106,7 +217,7 @@ static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
     AVFilterContext *filt;
     int i, j;
 
-    for (i = 0; i < graph->filter_count; i++) {
+    for (i = 0; i < graph->nb_filters; i++) {
         filt = graph->filters[i];
 
         for (j = 0; j < filt->nb_inputs; j++) {
@@ -141,7 +252,7 @@ static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
     AVFilterContext *filt;
     int i, ret;
 
-    for (i=0; i < graph->filter_count; i++) {
+    for (i = 0; i < graph->nb_filters; i++) {
         filt = graph->filters[i];
 
         if (!filt->nb_outputs) {
@@ -157,7 +268,7 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
 {
     int i;
 
-    for (i = 0; i < graph->filter_count; i++)
+    for (i = 0; i < graph->nb_filters; i++)
         if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
             return graph->filters[i];
 
@@ -170,7 +281,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
     int scaler_count = 0, resampler_count = 0;
 
     /* ask all the sub-filters for their supported media formats */
-    for (i = 0; i < graph->filter_count; i++) {
+    for (i = 0; i < graph->nb_filters; i++) {
         if (graph->filters[i]->filter->query_formats)
             graph->filters[i]->filter->query_formats(graph->filters[i]);
         else
@@ -178,7 +289,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
     }
 
     /* go through and merge as many format lists as possible */
-    for (i = 0; i < graph->filter_count; i++) {
+    for (i = 0; i < graph->nb_filters; i++) {
         AVFilterContext *filter = graph->filters[i];
 
         for (j = 0; j < filter->nb_inputs; j++) {
@@ -221,13 +332,9 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
 
                     snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
                              scaler_count++);
-                    av_strlcpy(scale_args, "0:0", sizeof(scale_args));
-                    if (graph->scale_sws_opts) {
-                        av_strlcat(scale_args, ":", sizeof(scale_args));
-                        av_strlcat(scale_args, graph->scale_sws_opts, sizeof(scale_args));
-                    }
+
                     if ((ret = avfilter_graph_create_filter(&convert, filter,
-                                                            inst_name, scale_args, NULL,
+                                                            inst_name, graph->scale_sws_opts, NULL,
                                                             graph)) < 0)
                         return ret;
                     break;
@@ -240,8 +347,13 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
 
                     snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
                              resampler_count++);
+                    scale_args[0] = '\0';
+                    if (graph->resample_lavr_opts)
+                        snprintf(scale_args, sizeof(scale_args), "%s",
+                                 graph->resample_lavr_opts);
                     if ((ret = avfilter_graph_create_filter(&convert, filter,
-                                                            inst_name, NULL, NULL, graph)) < 0)
+                                                            inst_name, scale_args,
+                                                            NULL, graph)) < 0)
                         return ret;
                     break;
                 default:
@@ -288,17 +400,17 @@ static int pick_format(AVFilterLink *link)
     if (!link || !link->in_formats)
         return 0;
 
-    link->in_formats->format_count = 1;
+    link->in_formats->nb_formats = 1;
     link->format = link->in_formats->formats[0];
 
     if (link->type == AVMEDIA_TYPE_AUDIO) {
-        if (!link->in_samplerates->format_count) {
+        if (!link->in_samplerates->nb_formats) {
             av_log(link->src, AV_LOG_ERROR, "Cannot select sample rate for"
                    " the link between filters %s and %s.\n", link->src->name,
                    link->dst->name);
             return AVERROR(EINVAL);
         }
-        link->in_samplerates->format_count = 1;
+        link->in_samplerates->nb_formats = 1;
         link->sample_rate = link->in_samplerates->formats[0];
 
         if (!link->in_channel_layouts->nb_channel_layouts) {
@@ -361,9 +473,9 @@ static int reduce_formats_on_filter(AVFilterContext *filter)
     int i, j, k, ret = 0;
 
     REDUCE_FORMATS(int,      AVFilterFormats,        formats,         formats,
-                   format_count, ff_add_format);
+                   nb_formats, ff_add_format);
     REDUCE_FORMATS(int,      AVFilterFormats,        samplerates,     formats,
-                   format_count, ff_add_format);
+                   nb_formats, ff_add_format);
     REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts,
                    channel_layouts, nb_channel_layouts, ff_add_channel_layout);
 
@@ -377,7 +489,7 @@ static void reduce_formats(AVFilterGraph *graph)
     do {
         reduced = 0;
 
-        for (i = 0; i < graph->filter_count; i++)
+        for (i = 0; i < graph->nb_filters; i++)
             reduced |= reduce_formats_on_filter(graph->filters[i]);
     } while (reduced);
 }
@@ -392,7 +504,7 @@ static void swap_samplerates_on_filter(AVFilterContext *filter)
         link = filter->inputs[i];
 
         if (link->type == AVMEDIA_TYPE_AUDIO &&
-            link->out_samplerates->format_count == 1)
+            link->out_samplerates->nb_formats== 1)
             break;
     }
     if (i == filter->nb_inputs)
@@ -405,10 +517,10 @@ static void swap_samplerates_on_filter(AVFilterContext *filter)
         int best_idx, best_diff = INT_MAX;
 
         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
-            outlink->in_samplerates->format_count < 2)
+            outlink->in_samplerates->nb_formats < 2)
             continue;
 
-        for (j = 0; j < outlink->in_samplerates->format_count; j++) {
+        for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
             int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
 
             if (diff < best_diff) {
@@ -425,7 +537,7 @@ static void swap_samplerates(AVFilterGraph *graph)
 {
     int i;
 
-    for (i = 0; i < graph->filter_count; i++)
+    for (i = 0; i < graph->nb_filters; i++)
         swap_samplerates_on_filter(graph->filters[i]);
 }
 
@@ -540,7 +652,7 @@ static void swap_channel_layouts(AVFilterGraph *graph)
 {
     int i;
 
-    for (i = 0; i < graph->filter_count; i++)
+    for (i = 0; i < graph->nb_filters; i++)
         swap_channel_layouts_on_filter(graph->filters[i]);
 }
 
@@ -554,7 +666,7 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter)
         link = filter->inputs[i];
 
         if (link->type == AVMEDIA_TYPE_AUDIO &&
-            link->out_formats->format_count == 1)
+            link->out_formats->nb_formats == 1)
             break;
     }
     if (i == filter->nb_inputs)
@@ -568,10 +680,10 @@ static void swap_sample_fmts_on_filter(AVFilterContext *filter)
         int best_idx = -1, best_score = INT_MIN;
 
         if (outlink->type != AVMEDIA_TYPE_AUDIO ||
-            outlink->in_formats->format_count < 2)
+            outlink->in_formats->nb_formats < 2)
             continue;
 
-        for (j = 0; j < outlink->in_formats->format_count; j++) {
+        for (j = 0; j < outlink->in_formats->nb_formats; j++) {
             int out_format = outlink->in_formats->formats[j];
             int out_bps    = av_get_bytes_per_sample(out_format);
             int score;
@@ -608,7 +720,7 @@ static void swap_sample_fmts(AVFilterGraph *graph)
 {
     int i;
 
-    for (i = 0; i < graph->filter_count; i++)
+    for (i = 0; i < graph->nb_filters; i++)
         swap_sample_fmts_on_filter(graph->filters[i]);
 
 }
@@ -617,7 +729,7 @@ static int pick_formats(AVFilterGraph *graph)
 {
     int i, j, ret;
 
-    for (i = 0; i < graph->filter_count; i++) {
+    for (i = 0; i < graph->nb_filters; i++) {
         AVFilterContext *filter = graph->filters[i];
 
         for (j = 0; j < filter->nb_inputs; j++)
@@ -664,7 +776,7 @@ static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
     int i, j, ret;
     int fifo_count = 0;
 
-    for (i = 0; i < graph->filter_count; i++) {
+    for (i = 0; i < graph->nb_filters; i++) {
         f = graph->filters[i];
 
         for (j = 0; j < f->nb_inputs; j++) {
diff --git a/libavfilter/avfiltergraph.h b/libavfilter/avfiltergraph.h
index 7c4672d..47174ef 100644
--- a/libavfilter/avfiltergraph.h
+++ b/libavfilter/avfiltergraph.h
@@ -25,148 +25,5 @@
 #include "avfilter.h"
 #include "libavutil/log.h"
 
-typedef struct AVFilterGraph {
-    const AVClass *av_class;
-    unsigned filter_count;
-    AVFilterContext **filters;
-
-    char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters
-} AVFilterGraph;
-
-/**
- * Allocate a filter graph.
- */
-AVFilterGraph *avfilter_graph_alloc(void);
-
-/**
- * Get a filter instance with name name from graph.
- *
- * @return the pointer to the found filter instance or NULL if it
- * cannot be found.
- */
-AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name);
-
-/**
- * Add an existing filter instance to a filter graph.
- *
- * @param graphctx  the filter graph
- * @param filter the filter to be added
- */
-int avfilter_graph_add_filter(AVFilterGraph *graphctx, AVFilterContext *filter);
-
-/**
- * Create and add a filter instance into an existing graph.
- * The filter instance is created from the filter filt and inited
- * with the parameters args and opaque.
- *
- * In case of success put in *filt_ctx the pointer to the created
- * filter instance, otherwise set *filt_ctx to NULL.
- *
- * @param name the instance name to give to the created filter instance
- * @param graph_ctx the filter graph
- * @return a negative AVERROR error code in case of failure, a non
- * negative value otherwise
- */
-int avfilter_graph_create_filter(AVFilterContext **filt_ctx, AVFilter *filt,
-                                 const char *name, const char *args, void *opaque,
-                                 AVFilterGraph *graph_ctx);
-
-/**
- * Check validity and configure all the links and formats in the graph.
- *
- * @param graphctx the filter graph
- * @param log_ctx context used for logging
- * @return 0 in case of success, a negative AVERROR code otherwise
- */
-int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx);
-
-/**
- * Free a graph, destroy its links, and set *graph to NULL.
- * If *graph is NULL, do nothing.
- */
-void avfilter_graph_free(AVFilterGraph **graph);
-
-/**
- * A linked-list of the inputs/outputs of the filter chain.
- *
- * This is mainly useful for avfilter_graph_parse() / avfilter_graph_parse2(),
- * where it is used to communicate open (unlinked) inputs and outputs from and
- * to the caller.
- * This struct specifies, per each not connected pad contained in the graph, the
- * filter context and the pad index required for establishing a link.
- */
-typedef struct AVFilterInOut {
-    /** unique name for this input/output in the list */
-    char *name;
-
-    /** filter context associated to this input/output */
-    AVFilterContext *filter_ctx;
-
-    /** index of the filt_ctx pad to use for linking */
-    int pad_idx;
-
-    /** next input/input in the list, NULL if this is the last */
-    struct AVFilterInOut *next;
-} AVFilterInOut;
-
-/**
- * Allocate a single AVFilterInOut entry.
- * Must be freed with avfilter_inout_free().
- * @return allocated AVFilterInOut on success, NULL on failure.
- */
-AVFilterInOut *avfilter_inout_alloc(void);
-
-/**
- * Free the supplied list of AVFilterInOut and set *inout to NULL.
- * If *inout is NULL, do nothing.
- */
-void avfilter_inout_free(AVFilterInOut **inout);
-
-/**
- * Add a graph described by a string to a graph.
- *
- * @param graph   the filter graph where to link the parsed graph context
- * @param filters string to be parsed
- * @param inputs  linked list to the inputs of the graph
- * @param outputs linked list to the outputs of the graph
- * @return zero on success, a negative AVERROR code on error
- */
-int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
-                         AVFilterInOut *inputs, AVFilterInOut *outputs,
-                         void *log_ctx);
-
-/**
- * Add a graph described by a string to a graph.
- *
- * @param[in]  graph   the filter graph where to link the parsed graph context
- * @param[in]  filters string to be parsed
- * @param[out] inputs  a linked list of all free (unlinked) inputs of the
- *                     parsed graph will be returned here. It is to be freed
- *                     by the caller using avfilter_inout_free().
- * @param[out] outputs a linked list of all free (unlinked) outputs of the
- *                     parsed graph will be returned here. It is to be freed by the
- *                     caller using avfilter_inout_free().
- * @return zero on success, a negative AVERROR code on error
- *
- * @note the difference between avfilter_graph_parse2() and
- * avfilter_graph_parse() is that in avfilter_graph_parse(), the caller provides
- * the lists of inputs and outputs, which therefore must be known before calling
- * the function. On the other hand, avfilter_graph_parse2() \em returns the
- * inputs and outputs that are left unlinked after parsing the graph and the
- * caller then deals with them. Another difference is that in
- * avfilter_graph_parse(), the inputs parameter describes inputs of the
- * <em>already existing</em> part of the graph; i.e. from the point of view of
- * the newly created part, they are outputs. Similarly the outputs parameter
- * describes outputs of the already existing filters, which are provided as
- * inputs to the parsed filters.
- * avfilter_graph_parse2() takes the opposite approach -- it makes no reference
- * whatsoever to already existing parts of the graph and the inputs parameter
- * will on return contain inputs of the newly parsed part of the graph.
- * Analogously the outputs parameter will contain outputs of the newly created
- * filters.
- */
-int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters,
-                          AVFilterInOut **inputs,
-                          AVFilterInOut **outputs);
 
 #endif /* AVFILTER_AVFILTERGRAPH_H */
diff --git a/libavfilter/buffer.c b/libavfilter/buffer.c
index 8eb3ce3..fd0b18f 100644
--- a/libavfilter/buffer.c
+++ b/libavfilter/buffer.c
@@ -18,11 +18,14 @@
 
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
+#include "libavutil/internal.h"
 #include "libavcodec/avcodec.h"
 
 #include "avfilter.h"
 #include "internal.h"
+#include "version.h"
 
+#if FF_API_AVFILTERBUFFER
 /* TODO: buffer pool.  see comment for avfilter_default_get_video_buffer() */
 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
 {
@@ -87,7 +90,9 @@ void avfilter_unref_buffer(AVFilterBufferRef *ref)
 
 void avfilter_unref_bufferp(AVFilterBufferRef **ref)
 {
+FF_DISABLE_DEPRECATION_WARNINGS
     avfilter_unref_buffer(*ref);
+FF_ENABLE_DEPRECATION_WARNINGS
     *ref = NULL;
 }
 
@@ -173,3 +178,4 @@ void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *s
     default: break;
     }
 }
+#endif /* FF_API_AVFILTERBUFFER */
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index a315cb3..2a22948 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -27,6 +27,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 
 #include "audio.h"
@@ -35,8 +36,8 @@
 #include "internal.h"
 
 typedef struct {
-    AVFilterBufferRef *cur_buf;  ///< last buffer delivered on the sink
-    AVAudioFifo  *audio_fifo;    ///< FIFO for audio samples
+    AVFrame *cur_frame;          ///< last frame delivered on the sink
+    AVAudioFifo *audio_fifo;     ///< FIFO for audio samples
     int64_t next_pts;            ///< interpolating audio pts
 } BufferSinkContext;
 
@@ -48,59 +49,58 @@ static av_cold void uninit(AVFilterContext *ctx)
         av_audio_fifo_free(sink->audio_fifo);
 }
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
     BufferSinkContext *s = link->dst->priv;
 
-    av_assert0(!s->cur_buf);
-    s->cur_buf    = buf;
+    av_assert0(!s->cur_frame);
+    s->cur_frame = frame;
 
     return 0;
 }
 
-int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
+int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx,
+                                                AVFrame *frame)
 {
     BufferSinkContext *s    = ctx->priv;
     AVFilterLink      *link = ctx->inputs[0];
     int ret;
 
-    if (!buf)
-        return ff_poll_frame(ctx->inputs[0]);
-
     if ((ret = ff_request_frame(link)) < 0)
         return ret;
 
-    if (!s->cur_buf)
+    if (!s->cur_frame)
         return AVERROR(EINVAL);
 
-    *buf       = s->cur_buf;
-    s->cur_buf = NULL;
+    av_frame_move_ref(frame, s->cur_frame);
+    av_frame_free(&s->cur_frame);
 
     return 0;
 }
 
-static int read_from_fifo(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
+static int read_from_fifo(AVFilterContext *ctx, AVFrame *frame,
                           int nb_samples)
 {
     BufferSinkContext *s = ctx->priv;
     AVFilterLink   *link = ctx->inputs[0];
-    AVFilterBufferRef *buf;
+    AVFrame *tmp;
 
-    if (!(buf = ff_get_audio_buffer(link, AV_PERM_WRITE, nb_samples)))
+    if (!(tmp = ff_get_audio_buffer(link, nb_samples)))
         return AVERROR(ENOMEM);
-    av_audio_fifo_read(s->audio_fifo, (void**)buf->extended_data, nb_samples);
+    av_audio_fifo_read(s->audio_fifo, (void**)tmp->extended_data, nb_samples);
 
-    buf->pts = s->next_pts;
+    tmp->pts = s->next_pts;
     s->next_pts += av_rescale_q(nb_samples, (AVRational){1, link->sample_rate},
                                 link->time_base);
 
-    *pbuf = buf;
-    return 0;
+    av_frame_move_ref(frame, tmp);
+    av_frame_free(&tmp);
 
+    return 0;
 }
 
-int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
-                               int nb_samples)
+int attribute_align_arg av_buffersink_get_samples(AVFilterContext *ctx,
+                                                  AVFrame *frame, int nb_samples)
 {
     BufferSinkContext *s = ctx->priv;
     AVFilterLink   *link = ctx->inputs[0];
@@ -113,70 +113,140 @@ int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
     }
 
     while (ret >= 0) {
-        AVFilterBufferRef *buf;
-
         if (av_audio_fifo_size(s->audio_fifo) >= nb_samples)
-            return read_from_fifo(ctx, pbuf, nb_samples);
+            return read_from_fifo(ctx, frame, nb_samples);
 
-        ret = av_buffersink_read(ctx, &buf);
+        ret = ff_request_frame(link);
         if (ret == AVERROR_EOF && av_audio_fifo_size(s->audio_fifo))
-            return read_from_fifo(ctx, pbuf, av_audio_fifo_size(s->audio_fifo));
+            return read_from_fifo(ctx, frame, av_audio_fifo_size(s->audio_fifo));
         else if (ret < 0)
             return ret;
 
-        if (buf->pts != AV_NOPTS_VALUE) {
-            s->next_pts = buf->pts -
+        if (s->cur_frame->pts != AV_NOPTS_VALUE) {
+            s->next_pts = s->cur_frame->pts -
                           av_rescale_q(av_audio_fifo_size(s->audio_fifo),
                                        (AVRational){ 1, link->sample_rate },
                                        link->time_base);
         }
 
-        ret = av_audio_fifo_write(s->audio_fifo, (void**)buf->extended_data,
-                                  buf->audio->nb_samples);
-        avfilter_unref_buffer(buf);
+        ret = av_audio_fifo_write(s->audio_fifo, (void**)s->cur_frame->extended_data,
+                                  s->cur_frame->nb_samples);
+        av_frame_free(&s->cur_frame);
+    }
+
+    return ret;
+}
+
+#if FF_API_AVFILTERBUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
+static void compat_free_buffer(AVFilterBuffer *buf)
+{
+    AVFrame *frame = buf->priv;
+    av_frame_free(&frame);
+    av_free(buf);
+}
+
+static int compat_read(AVFilterContext *ctx,
+                       AVFilterBufferRef **pbuf, int nb_samples)
+{
+    AVFilterBufferRef *buf;
+    AVFrame *frame;
+    int ret;
+
+    if (!pbuf)
+        return ff_poll_frame(ctx->inputs[0]);
+
+    frame = av_frame_alloc();
+    if (!frame)
+        return AVERROR(ENOMEM);
+
+    if (!nb_samples)
+        ret = av_buffersink_get_frame(ctx, frame);
+    else
+        ret = av_buffersink_get_samples(ctx, frame, nb_samples);
+
+    if (ret < 0)
+        goto fail;
+
+    if (ctx->inputs[0]->type == AVMEDIA_TYPE_VIDEO) {
+        buf = avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize,
+                                                        AV_PERM_READ,
+                                                        frame->width, frame->height,
+                                                        frame->format);
+    } else {
+        buf = avfilter_get_audio_buffer_ref_from_arrays(frame->extended_data,
+                                                        frame->linesize[0], AV_PERM_READ,
+                                                        frame->nb_samples,
+                                                        frame->format,
+                                                        frame->channel_layout);
     }
+    if (!buf) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    avfilter_copy_frame_props(buf, frame);
+
+    buf->buf->priv = frame;
+    buf->buf->free = compat_free_buffer;
+
+    *pbuf = buf;
 
+    return 0;
+fail:
+    av_frame_free(&frame);
     return ret;
 }
 
+int attribute_align_arg av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
+{
+    return compat_read(ctx, buf, 0);
+}
+
+int attribute_align_arg av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
+                                                   int nb_samples)
+{
+    return compat_read(ctx, buf, nb_samples);
+}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
 static const AVFilterPad avfilter_vsink_buffer_inputs[] = {
     {
-        .name        = "default",
-        .type        = AVMEDIA_TYPE_VIDEO,
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
-        .min_perms   = AV_PERM_READ,
-        .needs_fifo  = 1
+        .needs_fifo   = 1
     },
     { NULL }
 };
 
-AVFilter avfilter_vsink_buffer = {
-    .name      = "buffersink",
+AVFilter ff_vsink_buffer = {
+    .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),
-    .uninit    = uninit,
+    .priv_size   = sizeof(BufferSinkContext),
+    .uninit      = uninit,
 
-    .inputs    = avfilter_vsink_buffer_inputs,
-    .outputs   = NULL,
+    .inputs      = avfilter_vsink_buffer_inputs,
+    .outputs     = NULL,
 };
 
 static const AVFilterPad avfilter_asink_abuffer_inputs[] = {
     {
-        .name           = "default",
-        .type           = AVMEDIA_TYPE_AUDIO,
-        .filter_frame   = filter_frame,
-        .min_perms      = AV_PERM_READ,
-        .needs_fifo     = 1
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = filter_frame,
+        .needs_fifo   = 1
     },
     { NULL }
 };
 
-AVFilter avfilter_asink_abuffer = {
-    .name      = "abuffersink",
+AVFilter ff_asink_abuffer = {
+    .name        = "abuffersink",
     .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,
+    .priv_size   = sizeof(BufferSinkContext),
+    .uninit      = uninit,
 
-    .inputs    = avfilter_asink_abuffer_inputs,
-    .outputs   = NULL,
+    .inputs      = avfilter_asink_abuffer_inputs,
+    .outputs     = NULL,
 };
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
index e358ac3..75cea35 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -26,6 +26,7 @@
 
 #include "avfilter.h"
 
+#if FF_API_AVFILTERBUFFER
 /**
  * Get a buffer with filtered data from sink and put it in buf.
  *
@@ -38,6 +39,7 @@
  * @return >= 0 in case of success, a negative AVERROR code in case of
  *         failure.
  */
+attribute_deprecated
 int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf);
 
 /**
@@ -56,7 +58,37 @@ int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf);
  * @warning do not mix this function with av_buffersink_read(). Use only one or
  * the other with a single sink, not both.
  */
+attribute_deprecated
 int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
                                int nb_samples);
+#endif
+
+/**
+ * Get a frame with filtered data from sink and put it in frame.
+ *
+ * @param ctx pointer to a context of a buffersink or abuffersink AVFilter.
+ * @param frame pointer to an allocated frame that will be filled with data.
+ *              The data must be freed using av_frame_unref() / av_frame_free()
+ *
+ * @return >= 0 in case of success, a negative AVERROR code in case of
+ *         failure.
+ */
+int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame);
+
+/**
+ * Same as av_buffersink_get_frame(), but with the ability to specify the number
+ * of samples read. This function is less efficient than
+ * av_buffersink_get_frame(), because it copies the data around.
+ *
+ * @param ctx pointer to a context of the abuffersink AVFilter.
+ * @param frame pointer to an allocated frame that will be filled with data.
+ *              The data must be freed using av_frame_unref() / av_frame_free()
+ *              frame will contain exactly nb_samples audio samples, except at
+ *              the end of stream, when it can contain less than nb_samples.
+ *
+ * @warning do not mix this function with av_buffersink_get_frame(). Use only one or
+ * the other with a single sink, not both.
+ */
+int av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples);
 
 #endif /* AVFILTER_BUFFERSINK_H */
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index 3cee68d..1a75990 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -23,10 +23,14 @@
  * memory buffer source filter
  */
 
+#include <float.h>
+
 #include "libavutil/channel_layout.h"
 #include "libavutil/common.h"
 #include "libavutil/fifo.h"
+#include "libavutil/frame.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "libavutil/samplefmt.h"
 #include "audio.h"
@@ -44,6 +48,7 @@ typedef struct {
     /* video only */
     int               h, w;
     enum AVPixelFormat  pix_fmt;
+    char               *pix_fmt_str;
     AVRational        pixel_aspect;
 
     /* audio only */
@@ -69,119 +74,191 @@ typedef struct {
         return AVERROR(EINVAL);\
     }
 
-int av_buffersrc_write_frame(AVFilterContext *buffer_filter, const AVFrame *frame)
+int attribute_align_arg av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame)
+{
+    AVFrame *copy;
+    int ret = 0;
+
+    if (!(copy = av_frame_alloc()))
+        return AVERROR(ENOMEM);
+    ret = av_frame_ref(copy, frame);
+    if (ret >= 0)
+        ret = av_buffersrc_add_frame(ctx, copy);
+
+    av_frame_free(&copy);
+    return ret;
+}
+
+int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx,
+                                               AVFrame *frame)
 {
-    BufferSourceContext *c = buffer_filter->priv;
-    AVFilterBufferRef *buf;
+    BufferSourceContext *s = ctx->priv;
+    AVFrame *copy;
     int ret;
 
     if (!frame) {
-        c->eof = 1;
+        s->eof = 1;
         return 0;
-    } else if (c->eof)
+    } else if (s->eof)
         return AVERROR(EINVAL);
 
-    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) {
+    switch (ctx->outputs[0]->type) {
     case AVMEDIA_TYPE_VIDEO:
-        CHECK_VIDEO_PARAM_CHANGE(buffer_filter, c, frame->width, frame->height,
+        CHECK_VIDEO_PARAM_CHANGE(ctx, s, 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,
+        CHECK_AUDIO_PARAM_CHANGE(ctx, s, 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 (!av_fifo_space(s->fifo) &&
+        (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) +
+                                         sizeof(copy))) < 0)
+        return ret;
 
-    if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
-        avfilter_unref_buffer(buf);
+    if (!(copy = av_frame_alloc()))
+        return AVERROR(ENOMEM);
+    av_frame_move_ref(copy, frame);
+
+    if ((ret = av_fifo_generic_write(s->fifo, &copy, sizeof(copy), NULL)) < 0) {
+        av_frame_move_ref(frame, copy);
+        av_frame_free(&copy);
         return ret;
     }
 
     return 0;
 }
 
-int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
+#if FF_API_AVFILTERBUFFER
+FF_DISABLE_DEPRECATION_WARNINGS
+static void compat_free_buffer(void *opaque, uint8_t *data)
 {
-    BufferSourceContext *c = s->priv;
-    int ret;
+    AVFilterBufferRef *buf = opaque;
+    avfilter_unref_buffer(buf);
+}
+
+static void compat_unref_buffer(void *opaque, uint8_t *data)
+{
+    AVBufferRef *buf = opaque;
+    av_buffer_unref(&buf);
+}
+
+int av_buffersrc_buffer(AVFilterContext *ctx, AVFilterBufferRef *buf)
+{
+    BufferSourceContext *s = ctx->priv;
+    AVFrame *frame = NULL;
+    AVBufferRef *dummy_buf = NULL;
+    int ret = 0, planes, i;
 
     if (!buf) {
-        c->eof = 1;
+        s->eof = 1;
         return 0;
-    } else if (c->eof)
+    } else if (s->eof)
         return AVERROR(EINVAL);
 
-    if (!av_fifo_space(c->fifo) &&
-        (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
-                                         sizeof(buf))) < 0)
-        return ret;
+    frame = av_frame_alloc();
+    if (!frame)
+        return AVERROR(ENOMEM);
 
-    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);
+    dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, buf, 0);
+    if (!dummy_buf) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
     }
 
-    if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0)
-        return ret;
+    if ((ret = avfilter_copy_buf_props(frame, buf)) < 0)
+        goto fail;
 
-    return 0;
+#define WRAP_PLANE(ref_out, data, data_size)                            \
+do {                                                                    \
+    AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf);                  \
+    if (!dummy_ref) {                                                   \
+        ret = AVERROR(ENOMEM);                                          \
+        goto fail;                                                      \
+    }                                                                   \
+    ref_out = av_buffer_create(data, data_size, compat_unref_buffer,    \
+                               dummy_ref, 0);                           \
+    if (!ref_out) {                                                     \
+        av_frame_unref(frame);                                          \
+        ret = AVERROR(ENOMEM);                                          \
+        goto fail;                                                      \
+    }                                                                   \
+} while (0)
+
+    if (ctx->outputs[0]->type  == AVMEDIA_TYPE_VIDEO) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+
+        planes = av_pix_fmt_count_planes(frame->format);
+        if (!desc || planes <= 0) {
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+
+        for (i = 0; i < planes; i++) {
+            int v_shift    = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
+            int plane_size = (frame->height >> v_shift) * frame->linesize[i];
+
+            WRAP_PLANE(frame->buf[i], frame->data[i], plane_size);
+        }
+    } else {
+        int planar = av_sample_fmt_is_planar(frame->format);
+        int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
+
+        planes = planar ? channels : 1;
+
+        if (planes > FF_ARRAY_ELEMS(frame->buf)) {
+            frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf);
+            frame->extended_buf = av_mallocz(sizeof(*frame->extended_buf) *
+                                             frame->nb_extended_buf);
+            if (!frame->extended_buf) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+        }
+
+        for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++)
+            WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]);
+
+        for (i = 0; i < planes - FF_ARRAY_ELEMS(frame->buf); i++)
+            WRAP_PLANE(frame->extended_buf[i],
+                       frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)],
+                       frame->linesize[0]);
+    }
+
+    ret = av_buffersrc_add_frame(ctx, frame);
+
+fail:
+    av_buffer_unref(&dummy_buf);
+    av_frame_free(&frame);
+
+    return ret;
 }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
 
-static av_cold int init_video(AVFilterContext *ctx, const char *args)
+static av_cold int init_video(AVFilterContext *ctx)
 {
     BufferSourceContext *c = ctx->priv;
-    char pix_fmt_str[128];
-    int 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);
+
+    if (!c->pix_fmt_str || !c->w || !c->h || av_q2d(c->time_base) <= 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid parameters provided.\n");
         return AVERROR(EINVAL);
     }
-    if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == AV_PIX_FMT_NONE) {
+
+    if ((c->pix_fmt = av_get_pix_fmt(c->pix_fmt_str)) == AV_PIX_FMT_NONE) {
         char *tail;
-        c->pix_fmt = strtol(pix_fmt_str, &tail, 10);
+        c->pix_fmt = strtol(c->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);
+            av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", c->pix_fmt_str);
             return AVERROR(EINVAL);
         }
     }
 
-    if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*))))
+    if (!(c->fifo = av_fifo_alloc(sizeof(AVFrame*))))
         return AVERROR(ENOMEM);
 
     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));
@@ -190,6 +267,32 @@ static av_cold int init_video(AVFilterContext *ctx, const char *args)
 
 #define OFFSET(x) offsetof(BufferSourceContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
+#define V AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption video_options[] = {
+    { "width",         NULL,                     OFFSET(w),                AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
+    { "height",        NULL,                     OFFSET(h),                AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
+    { "pix_fmt",       NULL,                     OFFSET(pix_fmt_str),      AV_OPT_TYPE_STRING,                    .flags = V },
+#if FF_API_OLD_FILTER_OPTS
+    /* those 4 are for compatibility with the old option passing system where each filter
+     * did its own parsing */
+    { "time_base_num", "deprecated, do not use", OFFSET(time_base.num),    AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
+    { "time_base_den", "deprecated, do not use", OFFSET(time_base.den),    AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
+    { "sar_num",       "deprecated, do not use", OFFSET(pixel_aspect.num), AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
+    { "sar_den",       "deprecated, do not use", OFFSET(pixel_aspect.den), AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, V },
+#endif
+    { "sar",           "sample aspect ratio",    OFFSET(pixel_aspect),     AV_OPT_TYPE_RATIONAL, { .dbl = 1 }, 0, DBL_MAX, V },
+    { "time_base",     NULL,                     OFFSET(time_base),        AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, DBL_MAX, V },
+    { NULL },
+};
+
+static const AVClass buffer_class = {
+    .class_name = "buffer source",
+    .item_name  = av_default_item_name,
+    .option     = video_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 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 },
@@ -205,39 +308,27 @@ static const AVClass abuffer_class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-static av_cold int init_audio(AVFilterContext *ctx, const char *args)
+static av_cold int init_audio(AVFilterContext *ctx)
 {
     BufferSourceContext *s = ctx->priv;
     int ret = 0;
 
-    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);
-        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",
                s->sample_fmt_str);
-        ret = AVERROR(EINVAL);
-        goto fail;
+        return AVERROR(EINVAL);
     }
 
     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",
                s->channel_layout_str);
-        ret = AVERROR(EINVAL);
-        goto fail;
+        return AVERROR(EINVAL);
     }
 
-    if (!(s->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
+    if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*))))
+        return AVERROR(ENOMEM);
 
     if (!s->time_base.num)
         s->time_base = (AVRational){1, s->sample_rate};
@@ -246,8 +337,6 @@ static av_cold int init_audio(AVFilterContext *ctx, const char *args)
            "ch layout:%s\n", s->time_base.num, s->time_base.den, s->sample_fmt_str,
            s->sample_rate, s->channel_layout_str);
 
-fail:
-    av_opt_free(s);
     return ret;
 }
 
@@ -255,9 +344,9 @@ static av_cold void uninit(AVFilterContext *ctx)
 {
     BufferSourceContext *s = ctx->priv;
     while (s->fifo && av_fifo_size(s->fifo)) {
-        AVFilterBufferRef *buf;
-        av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
-        avfilter_unref_buffer(buf);
+        AVFrame *frame;
+        av_fifo_generic_read(s->fifo, &frame, sizeof(frame), NULL);
+        av_frame_free(&frame);
     }
     av_fifo_free(s->fifo);
     s->fifo = NULL;
@@ -317,7 +406,7 @@ static int config_props(AVFilterLink *link)
 static int request_frame(AVFilterLink *link)
 {
     BufferSourceContext *c = link->src->priv;
-    AVFilterBufferRef *buf;
+    AVFrame *frame;
     int ret = 0;
 
     if (!av_fifo_size(c->fifo)) {
@@ -325,9 +414,9 @@ static int request_frame(AVFilterLink *link)
             return AVERROR_EOF;
         return AVERROR(EAGAIN);
     }
-    av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
+    av_fifo_generic_read(c->fifo, &frame, sizeof(frame), NULL);
 
-    ff_filter_frame(link, buf);
+    ff_filter_frame(link, frame);
 
     return ret;
 }
@@ -338,7 +427,7 @@ static int poll_frame(AVFilterLink *link)
     int size = av_fifo_size(c->fifo);
     if (!size && c->eof)
         return AVERROR_EOF;
-    return size/sizeof(AVFilterBufferRef*);
+    return size/sizeof(AVFrame*);
 }
 
 static const AVFilterPad avfilter_vsrc_buffer_outputs[] = {
@@ -352,10 +441,11 @@ static const AVFilterPad avfilter_vsrc_buffer_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_buffer = {
+AVFilter ff_vsrc_buffer = {
     .name      = "buffer",
     .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them accessible to the filterchain."),
     .priv_size = sizeof(BufferSourceContext),
+    .priv_class = &buffer_class,
     .query_formats = query_formats,
 
     .init      = init_video,
@@ -376,10 +466,11 @@ static const AVFilterPad avfilter_asrc_abuffer_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_asrc_abuffer = {
+AVFilter ff_asrc_abuffer = {
     .name          = "abuffer",
     .description   = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them accessible to the filterchain."),
     .priv_size     = sizeof(BufferSourceContext),
+    .priv_class    = &abuffer_class,
     .query_formats = query_formats,
 
     .init      = init_audio,
diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h
index 452c691..c6f7ff9 100644
--- a/libavfilter/buffersrc.h
+++ b/libavfilter/buffersrc.h
@@ -27,24 +27,47 @@
 
 #include "avfilter.h"
 
+#if FF_API_AVFILTERBUFFER
 /**
  * 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_write_frame() or av_buffersrc_add_frame()
  */
+attribute_deprecated
 int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf);
+#endif
 
 /**
  * Add a frame to the buffer source.
  *
  * @param s an instance of the buffersrc filter.
- * @param frame frame to be added.
+ * @param frame frame to be added. If the frame is reference counted, this
+ * function will make a new reference to it. Otherwise the frame data will be
+ * copied.
  *
- * @warning frame data will be memcpy()ed, which may be a big performance
- *          hit. Use av_buffersrc_buffer() to avoid copying the data.
+ * @return 0 on success, a negative AVERROR on error
  */
 int av_buffersrc_write_frame(AVFilterContext *s, const AVFrame *frame);
 
+/**
+ * Add a frame to the buffer source.
+ *
+ * @param s an instance of the buffersrc filter.
+ * @param frame frame to be added. If the frame is reference counted, this
+ * function will take ownership of the reference(s) and reset the frame.
+ * Otherwise the frame data will be copied. If this function returns an error,
+ * the input frame is not touched.
+ *
+ * @return 0 on success, a negative AVERROR on error.
+ *
+ * @note the difference between this function and av_buffersrc_write_frame() is
+ * that av_buffersrc_write_frame() creates a new reference to the input frame,
+ * while this function takes ownership of the reference passed to it.
+ */
+int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame);
+
 #endif /* AVFILTER_BUFFERSRC_H */
diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c
index 3faa84f..30e0b38 100644
--- a/libavfilter/fifo.c
+++ b/libavfilter/fifo.c
@@ -35,7 +35,7 @@
 #include "video.h"
 
 typedef struct Buf {
-    AVFilterBufferRef *buf;
+    AVFrame *frame;
     struct Buf        *next;
 } Buf;
 
@@ -47,11 +47,11 @@ typedef struct {
      * When a specific number of output samples is requested, the partial
      * buffer is stored here
      */
-    AVFilterBufferRef *buf_out;
-    int allocated_samples;      ///< number of samples buf_out was allocated for
+    AVFrame *out;
+    int allocated_samples;      ///< number of samples out was allocated for
 } FifoContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     FifoContext *fifo = ctx->priv;
     fifo->last = &fifo->root;
@@ -66,25 +66,25 @@ static av_cold void uninit(AVFilterContext *ctx)
 
     for (buf = fifo->root.next; buf; buf = tmp) {
         tmp = buf->next;
-        avfilter_unref_bufferp(&buf->buf);
+        av_frame_free(&buf->frame);
         av_free(buf);
     }
 
-    avfilter_unref_bufferp(&fifo->buf_out);
+    av_frame_free(&fifo->out);
 }
 
-static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int add_to_queue(AVFilterLink *inlink, AVFrame *frame)
 {
     FifoContext *fifo = inlink->dst->priv;
 
     fifo->last->next = av_mallocz(sizeof(Buf));
     if (!fifo->last->next) {
-        avfilter_unref_buffer(buf);
+        av_frame_free(&frame);
         return AVERROR(ENOMEM);
     }
 
     fifo->last = fifo->last->next;
-    fifo->last->buf = buf;
+    fifo->last->frame = frame;
 
     return 0;
 }
@@ -101,7 +101,7 @@ static void queue_pop(FifoContext *s)
 /**
  * Move data pointers and pts offset samples forward.
  */
-static void buffer_offset(AVFilterLink *link, AVFilterBufferRef *buf,
+static void buffer_offset(AVFilterLink *link, AVFrame *frame,
                           int offset)
 {
     int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
@@ -110,32 +110,32 @@ static void buffer_offset(AVFilterLink *link, AVFilterBufferRef *buf,
     int block_align = av_get_bytes_per_sample(link->format) * (planar ? 1 : nb_channels);
     int i;
 
-    av_assert0(buf->audio->nb_samples > offset);
+    av_assert0(frame->nb_samples > offset);
 
     for (i = 0; i < planes; i++)
-        buf->extended_data[i] += block_align*offset;
-    if (buf->data != buf->extended_data)
-        memcpy(buf->data, buf->extended_data,
-               FFMIN(planes, FF_ARRAY_ELEMS(buf->data)) * sizeof(*buf->data));
-    buf->linesize[0] -= block_align*offset;
-    buf->audio->nb_samples -= offset;
-
-    if (buf->pts != AV_NOPTS_VALUE) {
-        buf->pts += av_rescale_q(offset, (AVRational){1, link->sample_rate},
-                                 link->time_base);
+        frame->extended_data[i] += block_align * offset;
+    if (frame->data != frame->extended_data)
+        memcpy(frame->data, frame->extended_data,
+               FFMIN(planes, FF_ARRAY_ELEMS(frame->data)) * sizeof(*frame->data));
+    frame->linesize[0] -= block_align*offset;
+    frame->nb_samples -= offset;
+
+    if (frame->pts != AV_NOPTS_VALUE) {
+        frame->pts += av_rescale_q(offset, (AVRational){1, link->sample_rate},
+                                   link->time_base);
     }
 }
 
-static int calc_ptr_alignment(AVFilterBufferRef *buf)
+static int calc_ptr_alignment(AVFrame *frame)
 {
-    int planes = av_sample_fmt_is_planar(buf->format) ?
-                 av_get_channel_layout_nb_channels(buf->audio->channel_layout) : 1;
+    int planes = av_sample_fmt_is_planar(frame->format) ?
+                 av_get_channel_layout_nb_channels(frame->channel_layout) : 1;
     int min_align = 128;
     int p;
 
     for (p = 0; p < planes; p++) {
         int cur_align = 128;
-        while ((intptr_t)buf->extended_data[p] % cur_align)
+        while ((intptr_t)frame->extended_data[p] % cur_align)
             cur_align >>= 1;
         if (cur_align < min_align)
             min_align = cur_align;
@@ -147,35 +147,38 @@ static int return_audio_frame(AVFilterContext *ctx)
 {
     AVFilterLink *link = ctx->outputs[0];
     FifoContext *s = ctx->priv;
-    AVFilterBufferRef *head = s->root.next->buf;
-    AVFilterBufferRef *buf_out;
+    AVFrame *head = s->root.next ? s->root.next->frame : NULL;
+    AVFrame *out;
     int ret;
 
-    if (!s->buf_out &&
-        head->audio->nb_samples >= link->request_samples &&
+    /* if head is NULL then we're flushing the remaining samples in out */
+    if (!head && !s->out)
+        return AVERROR_EOF;
+
+    if (!s->out &&
+        head->nb_samples >= link->request_samples &&
         calc_ptr_alignment(head) >= 32) {
-        if (head->audio->nb_samples == link->request_samples) {
-            buf_out = head;
+        if (head->nb_samples == link->request_samples) {
+            out = head;
             queue_pop(s);
         } else {
-            buf_out = avfilter_ref_buffer(head, AV_PERM_READ);
-            if (!buf_out)
+            out = av_frame_clone(head);
+            if (!out)
                 return AVERROR(ENOMEM);
 
-            buf_out->audio->nb_samples = link->request_samples;
+            out->nb_samples = link->request_samples;
             buffer_offset(link, head, link->request_samples);
         }
     } else {
         int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
 
-        if (!s->buf_out) {
-            s->buf_out = ff_get_audio_buffer(link, AV_PERM_WRITE,
-                                             link->request_samples);
-            if (!s->buf_out)
+        if (!s->out) {
+            s->out = ff_get_audio_buffer(link, link->request_samples);
+            if (!s->out)
                 return AVERROR(ENOMEM);
 
-            s->buf_out->audio->nb_samples = 0;
-            s->buf_out->pts               = head->pts;
+            s->out->nb_samples = 0;
+            s->out->pts                   = head->pts;
             s->allocated_samples          = link->request_samples;
         } else if (link->request_samples != s->allocated_samples) {
             av_log(ctx, AV_LOG_ERROR, "request_samples changed before the "
@@ -183,43 +186,43 @@ static int return_audio_frame(AVFilterContext *ctx)
             return AVERROR(EINVAL);
         }
 
-        while (s->buf_out->audio->nb_samples < s->allocated_samples) {
+        while (s->out->nb_samples < s->allocated_samples) {
             int len;
 
-            if (!s->root.next &&
-                (ret = ff_request_frame(ctx->inputs[0])) < 0) {
+            if (!s->root.next) {
+                ret = ff_request_frame(ctx->inputs[0]);
                 if (ret == AVERROR_EOF) {
-                    av_samples_set_silence(s->buf_out->extended_data,
-                                           s->buf_out->audio->nb_samples,
+                    av_samples_set_silence(s->out->extended_data,
+                                           s->out->nb_samples,
                                            s->allocated_samples -
-                                           s->buf_out->audio->nb_samples,
+                                           s->out->nb_samples,
                                            nb_channels, link->format);
-                    s->buf_out->audio->nb_samples = s->allocated_samples;
+                    s->out->nb_samples = s->allocated_samples;
                     break;
-                }
-                return ret;
+                } else if (ret < 0)
+                    return ret;
             }
-            head = s->root.next->buf;
+            head = s->root.next->frame;
 
-            len = FFMIN(s->allocated_samples - s->buf_out->audio->nb_samples,
-                        head->audio->nb_samples);
+            len = FFMIN(s->allocated_samples - s->out->nb_samples,
+                        head->nb_samples);
 
-            av_samples_copy(s->buf_out->extended_data, head->extended_data,
-                            s->buf_out->audio->nb_samples, 0, len, nb_channels,
+            av_samples_copy(s->out->extended_data, head->extended_data,
+                            s->out->nb_samples, 0, len, nb_channels,
                             link->format);
-            s->buf_out->audio->nb_samples += len;
+            s->out->nb_samples += len;
 
-            if (len == head->audio->nb_samples) {
-                avfilter_unref_buffer(head);
+            if (len == head->nb_samples) {
+                av_frame_free(&head);
                 queue_pop(s);
             } else {
                 buffer_offset(link, head, len);
             }
         }
-        buf_out = s->buf_out;
-        s->buf_out = NULL;
+        out = s->out;
+        s->out = NULL;
     }
-    return ff_filter_frame(link, buf_out);
+    return ff_filter_frame(link, out);
 }
 
 static int request_frame(AVFilterLink *outlink)
@@ -228,14 +231,17 @@ static int request_frame(AVFilterLink *outlink)
     int ret = 0;
 
     if (!fifo->root.next) {
-        if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0)
+        if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0) {
+            if (ret == AVERROR_EOF && outlink->request_samples)
+                return return_audio_frame(outlink->src);
             return ret;
+        }
     }
 
     if (outlink->request_samples) {
         return return_audio_frame(outlink->src);
     } else {
-        ret = ff_filter_frame(outlink, fifo->root.next->buf);
+        ret = ff_filter_frame(outlink, fifo->root.next->frame);
         queue_pop(fifo);
     }
 
@@ -248,7 +254,6 @@ static const AVFilterPad avfilter_vf_fifo_inputs[] = {
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
         .filter_frame     = add_to_queue,
-        .rej_perms        = AV_PERM_REUSE2,
     },
     { NULL }
 };
@@ -262,7 +267,7 @@ static const AVFilterPad avfilter_vf_fifo_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_fifo = {
+AVFilter ff_vf_fifo = {
     .name      = "fifo",
     .description = NULL_IF_CONFIG_SMALL("Buffer input images and send them when they are requested."),
 
@@ -281,7 +286,6 @@ static const AVFilterPad avfilter_af_afifo_inputs[] = {
         .type             = AVMEDIA_TYPE_AUDIO,
         .get_audio_buffer = ff_null_get_audio_buffer,
         .filter_frame     = add_to_queue,
-        .rej_perms        = AV_PERM_REUSE2,
     },
     { NULL }
 };
@@ -295,7 +299,7 @@ static const AVFilterPad avfilter_af_afifo_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_afifo = {
+AVFilter ff_af_afifo = {
     .name        = "afifo",
     .description = NULL_IF_CONFIG_SMALL("Buffer input frames and send them when they are requested."),
 
diff --git a/libavfilter/filtfmts.c b/libavfilter/filtfmts.c
index 480b277..f68287a 100644
--- a/libavfilter/filtfmts.c
+++ b/libavfilter/filtfmts.c
@@ -29,6 +29,7 @@ int main(int argc, char **argv)
 {
     AVFilter *filter;
     AVFilterContext *filter_ctx;
+    AVFilterGraph *graph_ctx;
     const char *filter_name;
     const char *filter_args = NULL;
     int i, j;
@@ -44,6 +45,11 @@ int main(int argc, char **argv)
     if (argv[2])
         filter_args = argv[2];
 
+    /* allocate graph */
+    graph_ctx = avfilter_graph_alloc();
+    if (!graph_ctx)
+        return 1;
+
     avfilter_register_all();
 
     /* get a corresponding filter and open it */
@@ -52,24 +58,25 @@ int main(int argc, char **argv)
         return 1;
     }
 
-    if (avfilter_open(&filter_ctx, filter, NULL) < 0) {
+    /* open filter and add it to the graph */
+    if (!(filter_ctx = avfilter_graph_alloc_filter(graph_ctx, filter, filter_name))) {
         fprintf(stderr, "Impossible to open filter with name '%s'\n",
                 filter_name);
         return 1;
     }
-    if (avfilter_init_filter(filter_ctx, filter_args, NULL) < 0) {
+    if (avfilter_init_str(filter_ctx, filter_args) < 0) {
         fprintf(stderr, "Impossible to init filter '%s' with arguments '%s'\n",
                 filter_name, filter_args);
         return 1;
     }
 
     /* create a link for each of the input pads */
-    for (i = 0; i < filter_ctx->input_count; i++) {
+    for (i = 0; i < filter_ctx->nb_inputs; i++) {
         AVFilterLink *link = av_mallocz(sizeof(AVFilterLink));
         link->type = filter_ctx->filter->inputs[i].type;
         filter_ctx->inputs[i] = link;
     }
-    for (i = 0; i < filter_ctx->output_count; i++) {
+    for (i = 0; i < filter_ctx->nb_outputs; i++) {
         AVFilterLink *link = av_mallocz(sizeof(AVFilterLink));
         link->type = filter_ctx->filter->outputs[i].type;
         filter_ctx->outputs[i] = link;
@@ -81,24 +88,25 @@ int main(int argc, char **argv)
         ff_default_query_formats(filter_ctx);
 
     /* print the supported formats in input */
-    for (i = 0; i < filter_ctx->input_count; i++) {
+    for (i = 0; i < filter_ctx->nb_inputs; i++) {
         AVFilterFormats *fmts = filter_ctx->inputs[i]->out_formats;
-        for (j = 0; j < fmts->format_count; j++)
+        for (j = 0; j < fmts->nb_formats; 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++) {
+    for (i = 0; i < filter_ctx->nb_outputs; i++) {
         AVFilterFormats *fmts = filter_ctx->outputs[i]->in_formats;
-        for (j = 0; j < fmts->format_count; j++)
+        for (j = 0; j < fmts->nb_formats; j++)
             printf("OUTPUT[%d] %s: %s\n",
                    i, filter_ctx->filter->outputs[i].name,
                    av_get_pix_fmt_name(fmts->formats[j]));
     }
 
     avfilter_free(filter_ctx);
+    avfilter_graph_free(&graph_ctx);
     fflush(stdout);
     return 0;
 }
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index 3b890d2..1441161 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -84,7 +84,7 @@ AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
     if (a == b)
         return a;
 
-    MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
+    MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
 
     return ret;
 fail:
@@ -103,9 +103,9 @@ AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
 
     if (a == b) return a;
 
-    if (a->format_count && b->format_count) {
-        MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
-    } else if (a->format_count) {
+    if (a->nb_formats && b->nb_formats) {
+        MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
+    } else if (a->nb_formats) {
         MERGE_REF(a, b, formats, AVFilterFormats, fail);
         ret = a;
     } else {
@@ -173,7 +173,7 @@ AVFilterFormats *ff_make_format_list(const int *fmts)
     formats               = av_mallocz(sizeof(*formats));
     if (count)
         formats->formats  = av_malloc(sizeof(*formats->formats) * count);
-    formats->format_count = count;
+    formats->nb_formats = count;
     memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
 
     return formats;
@@ -198,7 +198,7 @@ do {                                                        \
 
 int ff_add_format(AVFilterFormats **avff, int fmt)
 {
-    ADD_FORMAT(avff, fmt, int, formats, format_count);
+    ADD_FORMAT(avff, fmt, int, formats, nb_formats);
 }
 
 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
@@ -216,7 +216,7 @@ AVFilterFormats *ff_all_formats(enum AVMediaType type)
     for (fmt = 0; fmt < num_formats; fmt++) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
         if ((type != AVMEDIA_TYPE_VIDEO) ||
-            (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & PIX_FMT_HWACCEL)))
+            (type == AVMEDIA_TYPE_VIDEO && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)))
             ff_add_format(&ret, fmt);
     }
 
diff --git a/libavfilter/formats.h b/libavfilter/formats.h
index 0e1628c..2e44792 100644
--- a/libavfilter/formats.h
+++ b/libavfilter/formats.h
@@ -62,7 +62,7 @@
  * pointer to each of the pointers to itself.
  */
 struct AVFilterFormats {
-    unsigned format_count;      ///< number of formats
+    unsigned nb_formats;        ///< number of formats
     int *formats;               ///< list of media formats
 
     unsigned refcount;          ///< number of references to this list
diff --git a/libavfilter/gradfun.h b/libavfilter/gradfun.h
index 876579a..f6f7311 100644
--- a/libavfilter/gradfun.h
+++ b/libavfilter/gradfun.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2010 Nolan Lum <nol888 at gmail.com>
- * Copyright (c) 2009 Loren Merritt <lorenm at u.washignton.edu>
+ * Copyright (c) 2009 Loren Merritt <lorenm at u.washington.edu>
  *
  * This file is part of Libav.
  *
@@ -26,6 +26,8 @@
 
 /// Holds instance-specific information for gradfun.
 typedef struct GradFunContext {
+    const AVClass *class;
+    float strength;
     int thresh;    ///< threshold for gradient algorithm
     int radius;    ///< blur radius
     int chroma_w;  ///< width of the chroma planes
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index 7ce60c1..e20dd62 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -20,14 +20,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <ctype.h>
 #include <string.h>
 #include <stdio.h>
 
 #include "libavutil/avstring.h"
 #include "libavutil/mem.h"
 #include "avfilter.h"
-#include "avfiltergraph.h"
 
 #define WHITESPACES " \n\t"
 
@@ -111,16 +109,11 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind
         return AVERROR(EINVAL);
     }
 
-    ret = avfilter_open(filt_ctx, filt, inst_name);
+    *filt_ctx = avfilter_graph_alloc_filter(ctx, filt, inst_name);
     if (!*filt_ctx) {
         av_log(log_ctx, AV_LOG_ERROR,
                "Error creating filter '%s'\n", filt_name);
-        return ret;
-    }
-
-    if ((ret = avfilter_graph_add_filter(ctx, *filt_ctx)) < 0) {
-        avfilter_free(*filt_ctx);
-        return ret;
+        return AVERROR(ENOMEM);
     }
 
     if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") &&
@@ -130,9 +123,14 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind
         args = tmp_args;
     }
 
-    if ((ret = avfilter_init_filter(*filt_ctx, args, NULL)) < 0) {
+    ret = avfilter_init_str(*filt_ctx, args);
+    if (ret < 0) {
         av_log(log_ctx, AV_LOG_ERROR,
-               "Error initializing filter '%s' with args '%s'\n", filt_name, args);
+               "Error initializing filter '%s'", filt_name);
+        if (args)
+            av_log(log_ctx, AV_LOG_ERROR, " with args '%s'", args);
+        av_log(log_ctx, AV_LOG_ERROR, "\n");
+        avfilter_free(*filt_ctx);
         return ret;
     }
 
@@ -437,8 +435,8 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters,
     return 0;
 
  fail:
-    for (; graph->filter_count > 0; graph->filter_count--)
-        avfilter_free(graph->filters[graph->filter_count - 1]);
+    while (graph->nb_filters)
+        avfilter_free(graph->filters[0]);
     av_freep(&graph->filters);
     avfilter_inout_free(&open_inputs);
     avfilter_inout_free(&open_outputs);
@@ -502,8 +500,8 @@ int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
 
  fail:
     if (ret < 0) {
-        for (; graph->filter_count > 0; graph->filter_count--)
-            avfilter_free(graph->filters[graph->filter_count - 1]);
+        while (graph->nb_filters)
+            avfilter_free(graph->filters[0]);
         av_freep(&graph->filters);
     }
     avfilter_inout_free(&inputs);
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 216a355..44e7583 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -24,7 +24,10 @@
  * internal API functions
  */
 
+#include "libavutil/internal.h"
 #include "avfilter.h"
+#include "thread.h"
+#include "version.h"
 
 #if !FF_API_AVFILTERPAD_PUBLIC
 /**
@@ -44,32 +47,12 @@ struct AVFilterPad {
     enum AVMediaType type;
 
     /**
-     * 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.
-     */
-    int min_perms;
-
-    /**
-     * 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.
-     */
-    int rej_perms;
-
-    /**
      * Callback function to get a video buffer. If NULL, the filter system will
      * use avfilter_default_get_video_buffer().
      *
      * Input video pads only.
      */
-    AVFilterBufferRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h);
+    AVFrame *(*get_video_buffer)(AVFilterLink *link, int w, int h);
 
     /**
      * Callback function to get an audio buffer. If NULL, the filter system will
@@ -77,8 +60,7 @@ struct AVFilterPad {
      *
      * Input audio pads only.
      */
-    AVFilterBufferRef *(*get_audio_buffer)(AVFilterLink *link, int perms,
-                                           int nb_samples);
+    AVFrame *(*get_audio_buffer)(AVFilterLink *link, int nb_samples);
 
     /**
      * Filtering callback. This is where a filter receives a frame with
@@ -90,7 +72,7 @@ struct AVFilterPad {
      * must ensure that samplesref is properly unreferenced on error if it
      * hasn't been passed on to another filter.
      */
-    int (*filter_frame)(AVFilterLink *link, AVFilterBufferRef *frame);
+    int (*filter_frame)(AVFilterLink *link, AVFrame *frame);
 
     /**
      * Frame poll callback. This returns the number of immediately available
@@ -138,8 +120,19 @@ struct AVFilterPad {
 };
 #endif
 
+struct AVFilterGraphInternal {
+    void *thread;
+    avfilter_execute_func *thread_execute;
+};
+
+struct AVFilterInternal {
+    avfilter_execute_func *execute;
+};
+
+#if FF_API_AVFILTERBUFFER
 /** default handler for freeing audio/video buffer when there are no references left */
 void ff_avfilter_default_free_buffer(AVFilterBuffer *buf);
+#endif
 
 /** Tell is a format is contained in the provided list terminated by -1. */
 int ff_fmt_is_in(int fmt, const int *fmts);
@@ -172,7 +165,9 @@ static inline void ff_insert_inpad(AVFilterContext *f, unsigned index,
     ff_insert_pad(index, &f->nb_inputs, offsetof(AVFilterLink, dstpad),
                   &f->input_pads, &f->inputs, p);
 #if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
     f->input_count = f->nb_inputs;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 }
 
@@ -183,7 +178,9 @@ static inline void ff_insert_outpad(AVFilterContext *f, unsigned index,
     ff_insert_pad(index, &f->nb_outputs, offsetof(AVFilterLink, srcpad),
                   &f->output_pads, &f->outputs, p);
 #if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
     f->output_count = f->nb_outputs;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 }
 
@@ -215,6 +212,21 @@ int ff_request_frame(AVFilterLink *link);
  * @return >= 0 on success, a negative AVERROR on error. The receiving filter
  * is responsible for unreferencing frame in case of error.
  */
-int ff_filter_frame(AVFilterLink *link, AVFilterBufferRef *frame);
+int ff_filter_frame(AVFilterLink *link, AVFrame *frame);
+
+/**
+ * Allocate a new filter context and return it.
+ *
+ * @param filter what filter to create an instance of
+ * @param inst_name name to give to the new filter context
+ *
+ * @return newly created filter context or NULL on failure
+ */
+AVFilterContext *ff_filter_alloc(const AVFilter *filter, const char *inst_name);
+
+/**
+ * Remove a filter from a graph;
+ */
+void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter);
 
 #endif /* AVFILTER_INTERNAL_H */
diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c
new file mode 100644
index 0000000..dd3b174
--- /dev/null
+++ b/libavfilter/pthread.c
@@ -0,0 +1,236 @@
+/*
+ *
+ * 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
+ * Libavfilter multithreading support
+ */
+
+#include "config.h"
+
+#include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "thread.h"
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "compat/w32pthreads.h"
+#endif
+
+typedef struct ThreadContext {
+    AVFilterGraph *graph;
+
+    int nb_threads;
+    pthread_t *workers;
+    avfilter_action_func *func;
+
+    /* per-execute perameters */
+    AVFilterContext *ctx;
+    void *arg;
+    int   *rets;
+    int nb_rets;
+    int nb_jobs;
+
+    pthread_cond_t last_job_cond;
+    pthread_cond_t current_job_cond;
+    pthread_mutex_t current_job_lock;
+    int current_job;
+    unsigned int current_execute;
+    int done;
+} ThreadContext;
+
+static void* attribute_align_arg worker(void *v)
+{
+    ThreadContext *c = v;
+    int our_job      = c->nb_jobs;
+    int nb_threads   = c->nb_threads;
+    unsigned int last_execute = 0;
+    int self_id;
+
+    pthread_mutex_lock(&c->current_job_lock);
+    self_id = c->current_job++;
+    for (;;) {
+        while (our_job >= c->nb_jobs) {
+            if (c->current_job == nb_threads + c->nb_jobs)
+                pthread_cond_signal(&c->last_job_cond);
+
+            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) {
+                pthread_mutex_unlock(&c->current_job_lock);
+                return NULL;
+            }
+        }
+        pthread_mutex_unlock(&c->current_job_lock);
+
+        c->rets[our_job % c->nb_rets] = c->func(c->ctx, c->arg, our_job, c->nb_jobs);
+
+        pthread_mutex_lock(&c->current_job_lock);
+        our_job = c->current_job++;
+    }
+}
+
+static void slice_thread_uninit(ThreadContext *c)
+{
+    int i;
+
+    pthread_mutex_lock(&c->current_job_lock);
+    c->done = 1;
+    pthread_cond_broadcast(&c->current_job_cond);
+    pthread_mutex_unlock(&c->current_job_lock);
+
+    for (i = 0; i < c->nb_threads; i++)
+         pthread_join(c->workers[i], NULL);
+
+    pthread_mutex_destroy(&c->current_job_lock);
+    pthread_cond_destroy(&c->current_job_cond);
+    pthread_cond_destroy(&c->last_job_cond);
+    av_freep(&c->workers);
+}
+
+static void slice_thread_park_workers(ThreadContext *c)
+{
+    while (c->current_job != c->nb_threads + c->nb_jobs)
+        pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
+    pthread_mutex_unlock(&c->current_job_lock);
+}
+
+static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func,
+                          void *arg, int *ret, int nb_jobs)
+{
+    ThreadContext *c = ctx->graph->internal->thread;
+    int dummy_ret;
+
+    if (nb_jobs <= 0)
+        return 0;
+
+    pthread_mutex_lock(&c->current_job_lock);
+
+    c->current_job = c->nb_threads;
+    c->nb_jobs     = nb_jobs;
+    c->ctx         = ctx;
+    c->arg         = arg;
+    c->func        = func;
+    if (ret) {
+        c->rets    = ret;
+        c->nb_rets = nb_jobs;
+    } else {
+        c->rets    = &dummy_ret;
+        c->nb_rets = 1;
+    }
+    c->current_execute++;
+
+    pthread_cond_broadcast(&c->current_job_cond);
+
+    slice_thread_park_workers(c);
+
+    return 0;
+}
+
+static int thread_init_internal(ThreadContext *c, int nb_threads)
+{
+    int i, ret;
+
+    if (!nb_threads) {
+        int nb_cpus = av_cpu_count();
+        av_log(c->graph, AV_LOG_DEBUG, "Detected %d logical cores.\n", nb_cpus);
+        // use number of cores + 1 as thread count if there is more than one
+        if (nb_cpus > 1)
+            nb_threads = nb_cpus + 1;
+        else
+            nb_threads = 1;
+    }
+
+    if (nb_threads <= 1)
+        return 1;
+
+    c->nb_threads = nb_threads;
+    c->workers = av_mallocz(sizeof(*c->workers) * nb_threads);
+    if (!c->workers)
+        return AVERROR(ENOMEM);
+
+    c->current_job = 0;
+    c->nb_jobs     = 0;
+    c->done        = 0;
+
+    pthread_cond_init(&c->current_job_cond, NULL);
+    pthread_cond_init(&c->last_job_cond,    NULL);
+
+    pthread_mutex_init(&c->current_job_lock, NULL);
+    pthread_mutex_lock(&c->current_job_lock);
+    for (i = 0; i < nb_threads; i++) {
+        ret = pthread_create(&c->workers[i], NULL, worker, c);
+        if (ret) {
+           pthread_mutex_unlock(&c->current_job_lock);
+           c->nb_threads = i;
+           slice_thread_uninit(c);
+           return AVERROR(ret);
+        }
+    }
+
+    slice_thread_park_workers(c);
+
+    return c->nb_threads;
+}
+
+int ff_graph_thread_init(AVFilterGraph *graph)
+{
+    int ret;
+
+#if HAVE_W32THREADS
+    w32thread_init();
+#endif
+
+    if (graph->nb_threads == 1) {
+        graph->thread_type = 0;
+        return 0;
+    }
+
+    graph->internal->thread = av_mallocz(sizeof(ThreadContext));
+    if (!graph->internal->thread)
+        return AVERROR(ENOMEM);
+
+    ret = thread_init_internal(graph->internal->thread, graph->nb_threads);
+    if (ret <= 1) {
+        av_freep(&graph->internal->thread);
+        graph->thread_type = 0;
+        graph->nb_threads  = 1;
+        return (ret < 0) ? ret : 0;
+    }
+    graph->nb_threads = ret;
+
+    graph->internal->thread_execute = thread_execute;
+
+    return 0;
+}
+
+void ff_graph_thread_free(AVFilterGraph *graph)
+{
+    if (graph->internal->thread)
+        slice_thread_uninit(graph->internal->thread);
+    av_freep(&graph->internal->thread);
+}
diff --git a/libavfilter/setpts.c b/libavfilter/setpts.c
new file mode 100644
index 0000000..be190c0
--- /dev/null
+++ b/libavfilter/setpts.c
@@ -0,0 +1,259 @@
+/*
+ * 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
+ */
+
+#include "libavutil/eval.h"
+#include "libavutil/internal.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/time.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+
+#include "config.h"
+
+static const char *const var_names[] = {
+    "E",           ///< Euler number
+    "INTERLACED",  ///< tell if the current frame is interlaced
+    "N",           ///< frame / sample number (starting at zero)
+    "PHI",         ///< golden ratio
+    "PI",          ///< greek pi
+    "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
+    "RTCTIME",     ///< wallclock (RTC) time in micro seconds
+    "RTCSTART",    ///< wallclock (RTC) time at the start of the movie in micro seconds
+    "S",           //   Number of samples in the current frame
+    "SR",          //   Audio sample rate
+    NULL
+};
+
+enum var_name {
+    VAR_E,
+    VAR_INTERLACED,
+    VAR_N,
+    VAR_PHI,
+    VAR_PI,
+    VAR_PREV_INPTS,
+    VAR_PREV_OUTPTS,
+    VAR_PTS,
+    VAR_STARTPTS,
+    VAR_TB,
+    VAR_RTCTIME,
+    VAR_RTCSTART,
+    VAR_S,
+    VAR_SR,
+    VAR_VARS_NB
+};
+
+typedef struct {
+    const AVClass *class;
+    char *expr_str;
+    AVExpr *expr;
+    double var_values[VAR_VARS_NB];
+} SetPTSContext;
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    SetPTSContext *setpts = ctx->priv;
+    int ret;
+
+    if ((ret = av_expr_parse(&setpts->expr, setpts->expr_str,
+                             var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", setpts->expr_str);
+        return ret;
+    }
+
+    setpts->var_values[VAR_E]           = M_E;
+    setpts->var_values[VAR_N]           = 0.0;
+    setpts->var_values[VAR_S]           = 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);
+    setpts->var_values[VAR_RTCSTART] = av_gettime();
+
+    if (inlink->type == AVMEDIA_TYPE_AUDIO) {
+        setpts->var_values[VAR_SR] = inlink->sample_rate;
+    }
+
+    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 filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    SetPTSContext *setpts = inlink->dst->priv;
+    int64_t in_pts = frame->pts;
+    double d;
+
+    if (isnan(setpts->var_values[VAR_STARTPTS]))
+        setpts->var_values[VAR_STARTPTS] = TS2D(frame->pts);
+
+    setpts->var_values[VAR_PTS       ] = TS2D(frame->pts);
+    setpts->var_values[VAR_RTCTIME   ] = av_gettime();
+
+    if (inlink->type == AVMEDIA_TYPE_VIDEO) {
+        setpts->var_values[VAR_INTERLACED] = frame->interlaced_frame;
+    } else {
+        setpts->var_values[VAR_S] = frame->nb_samples;
+    }
+
+    d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
+    frame->pts = D2TS(d);
+
+#ifdef DEBUG
+    av_log(inlink->dst, AV_LOG_DEBUG,
+           "n:%"PRId64" interlaced:%d pts:%"PRId64" t:%f -> pts:%"PRId64" t:%f\n",
+           (int64_t)setpts->var_values[VAR_N],
+           (int)setpts->var_values[VAR_INTERLACED],
+           in_pts, in_pts * av_q2d(inlink->time_base),
+           frame->pts, frame->pts * av_q2d(inlink->time_base));
+#endif
+
+
+    if (inlink->type == AVMEDIA_TYPE_VIDEO) {
+        setpts->var_values[VAR_N] += 1.0;
+    } else {
+        setpts->var_values[VAR_N] += frame->nb_samples;
+    }
+
+    setpts->var_values[VAR_PREV_INPTS ] = TS2D(in_pts);
+    setpts->var_values[VAR_PREV_OUTPTS] = TS2D(frame->pts);
+    return ff_filter_frame(inlink->dst->outputs[0], frame);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    SetPTSContext *setpts = ctx->priv;
+    av_expr_free(setpts->expr);
+    setpts->expr = NULL;
+}
+
+#define OFFSET(x) offsetof(SetPTSContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+    { "expr", "Expression determining the frame timestamp", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "PTS" }, .flags = FLAGS },
+    { NULL },
+};
+
+#if CONFIG_SETPTS_FILTER
+static const AVClass setpts_class = {
+    .class_name = "setpts",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+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,
+        .filter_frame     = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad avfilter_vf_setpts_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter ff_vf_setpts = {
+    .name      = "setpts",
+    .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
+    .init      = init,
+    .uninit    = uninit,
+
+    .priv_size = sizeof(SetPTSContext),
+    .priv_class = &setpts_class,
+
+    .inputs    = avfilter_vf_setpts_inputs,
+    .outputs   = avfilter_vf_setpts_outputs,
+};
+#endif
+
+#if CONFIG_ASETPTS_FILTER
+static const AVClass asetpts_class = {
+    .class_name = "asetpts",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVFilterPad asetpts_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_AUDIO,
+        .get_audio_buffer = ff_null_get_audio_buffer,
+        .config_props     = config_input,
+        .filter_frame     = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad asetpts_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_AUDIO,
+    },
+    { NULL }
+};
+
+AVFilter ff_af_asetpts = {
+    .name        = "asetpts",
+    .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
+    .init        = init,
+    .uninit      = uninit,
+
+    .priv_size  = sizeof(SetPTSContext),
+    .priv_class = &asetpts_class,
+
+    .inputs    = asetpts_inputs,
+    .outputs   = asetpts_outputs,
+};
+#endif
diff --git a/libavfilter/split.c b/libavfilter/split.c
index c1e1669..41395e7 100644
--- a/libavfilter/split.c
+++ b/libavfilter/split.c
@@ -25,27 +25,27 @@
 
 #include <stdio.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
+#include "libavutil/opt.h"
+
 #include "avfilter.h"
 #include "audio.h"
 #include "internal.h"
 #include "video.h"
 
-static int split_init(AVFilterContext *ctx, const char *args)
+typedef struct SplitContext {
+    const AVClass *class;
+    int nb_outputs;
+} SplitContext;
+
+static av_cold int split_init(AVFilterContext *ctx)
 {
-    int i, nb_outputs = 2;
-
-    if (args) {
-        nb_outputs = strtol(args, NULL, 0);
-        if (nb_outputs <= 0) {
-            av_log(ctx, AV_LOG_ERROR, "Invalid number of outputs specified: %d.\n",
-                   nb_outputs);
-            return AVERROR(EINVAL);
-        }
-    }
+    SplitContext *s = ctx->priv;
+    int i;
 
-    for (i = 0; i < nb_outputs; i++) {
+    for (i = 0; i < s->nb_outputs; i++) {
         char name[32];
         AVFilterPad pad = { 0 };
 
@@ -59,7 +59,7 @@ static int split_init(AVFilterContext *ctx, const char *args)
     return 0;
 }
 
-static void split_uninit(AVFilterContext *ctx)
+static av_cold void split_uninit(AVFilterContext *ctx)
 {
     int i;
 
@@ -67,13 +67,13 @@ static void split_uninit(AVFilterContext *ctx)
         av_freep(&ctx->output_pads[i].name);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
     int i, ret = 0;
 
     for (i = 0; i < ctx->nb_outputs; i++) {
-        AVFilterBufferRef *buf_out = avfilter_ref_buffer(frame, ~AV_PERM_WRITE);
+        AVFrame *buf_out = av_frame_clone(frame);
         if (!buf_out) {
             ret = AVERROR(ENOMEM);
             break;
@@ -83,10 +83,31 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
         if (ret < 0)
             break;
     }
-    avfilter_unref_bufferp(&frame);
+    av_frame_free(&frame);
     return ret;
 }
 
+#define OFFSET(x) offsetof(SplitContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "outputs", "Number of outputs", OFFSET(nb_outputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT_MAX, FLAGS },
+    { NULL },
+};
+
+static const AVClass split_class = {
+    .class_name = "split",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVClass asplit_class = {
+    .class_name = "asplit",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_split_inputs[] = {
     {
         .name             = "default",
@@ -97,15 +118,20 @@ static const AVFilterPad avfilter_vf_split_inputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_split = {
+AVFilter ff_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 to N video outputs."),
+
+    .priv_size  = sizeof(SplitContext),
+    .priv_class = &split_class,
 
     .init   = split_init,
     .uninit = split_uninit,
 
     .inputs    = avfilter_vf_split_inputs,
     .outputs   = NULL,
+
+    .flags     = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
 
 static const AVFilterPad avfilter_af_asplit_inputs[] = {
@@ -118,13 +144,18 @@ static const AVFilterPad avfilter_af_asplit_inputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_af_asplit = {
+AVFilter ff_af_asplit = {
     .name        = "asplit",
     .description = NULL_IF_CONFIG_SMALL("Pass on the audio input to N audio outputs."),
 
+    .priv_size  = sizeof(SplitContext),
+    .priv_class = &asplit_class,
+
     .init   = split_init,
     .uninit = split_uninit,
 
     .inputs  = avfilter_af_asplit_inputs,
     .outputs = NULL,
+
+    .flags   = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
 };
diff --git a/libavfilter/thread.h b/libavfilter/thread.h
new file mode 100644
index 0000000..1cfea3e
--- /dev/null
+++ b/libavfilter/thread.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * 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 AVFILTER_THREAD_H
+#define AVFILTER_THREAD_H
+
+#include "avfilter.h"
+
+int ff_graph_thread_init(AVFilterGraph *graph);
+
+void ff_graph_thread_free(AVFilterGraph *graph);
+
+#endif /* AVFILTER_THREAD_H */
diff --git a/libavfilter/trim.c b/libavfilter/trim.c
new file mode 100644
index 0000000..2b57540
--- /dev/null
+++ b/libavfilter/trim.c
@@ -0,0 +1,408 @@
+/*
+ * 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 <float.h>
+#include <math.h>
+#include <stdint.h>
+
+#include "config.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/common.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct TrimContext {
+    const AVClass *class;
+
+    /*
+     * AVOptions
+     */
+    double duration;
+    double start_time, end_time;
+    int64_t start_frame, end_frame;
+    /*
+     * in the link timebase for video,
+     * in 1/samplerate for audio
+     */
+    int64_t start_pts, end_pts;
+    int64_t start_sample, end_sample;
+
+    /*
+     * number of video frames that arrived on this filter so far
+     */
+    int64_t nb_frames;
+    /*
+     * number of audio samples that arrived on this filter so far
+     */
+    int64_t nb_samples;
+    /*
+     * timestamp of the first frame in the output, in the timebase units
+     */
+    int64_t first_pts;
+    /*
+     * duration in the timebase units
+     */
+    int64_t duration_tb;
+
+    int64_t next_pts;
+
+    int eof;
+    int got_output;
+} TrimContext;
+
+static int init(AVFilterContext *ctx)
+{
+    TrimContext *s = ctx->priv;
+
+    s->first_pts = AV_NOPTS_VALUE;
+
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    TrimContext       *s = ctx->priv;
+    AVRational tb = (inlink->type == AVMEDIA_TYPE_VIDEO) ?
+                     inlink->time_base : (AVRational){ 1, inlink->sample_rate };
+
+    if (s->start_time != DBL_MAX) {
+        int64_t start_pts = lrintf(s->start_time / av_q2d(tb));
+        if (s->start_pts == AV_NOPTS_VALUE || start_pts < s->start_pts)
+            s->start_pts = start_pts;
+    }
+    if (s->end_time != DBL_MAX) {
+        int64_t end_pts = lrintf(s->end_time / av_q2d(tb));
+        if (s->end_pts == AV_NOPTS_VALUE || end_pts > s->end_pts)
+            s->end_pts = end_pts;
+    }
+    if (s->duration)
+        s->duration_tb = lrintf(s->duration / av_q2d(tb));
+
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    TrimContext       *s = ctx->priv;
+    int ret;
+
+    s->got_output = 0;
+    while (!s->got_output) {
+        if (s->eof)
+            return AVERROR_EOF;
+
+        ret = ff_request_frame(ctx->inputs[0]);
+        if (ret < 0)
+            return ret;
+    }
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(TrimContext, x)
+#define COMMON_OPTS                                                                                                                                                         \
+    { "start",       "Timestamp in seconds of the first frame that "                                                                                                        \
+        "should be passed",                                              OFFSET(start_time),  AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX },       -DBL_MAX, DBL_MAX,     FLAGS }, \
+    { "end",         "Timestamp in seconds of the first frame that "                                                                                                        \
+        "should be dropped again",                                       OFFSET(end_time),    AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX },       -DBL_MAX, DBL_MAX,     FLAGS }, \
+    { "start_pts",   "Timestamp of the first frame that should be "                                                                                                         \
+       " passed",                                                        OFFSET(start_pts),   AV_OPT_TYPE_INT64,  { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, FLAGS }, \
+    { "end_pts",     "Timestamp of the first frame that should be "                                                                                                         \
+        "dropped again",                                                 OFFSET(end_pts),     AV_OPT_TYPE_INT64,  { .i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, FLAGS }, \
+    { "duration",    "Maximum duration of the output in seconds",        OFFSET(duration),    AV_OPT_TYPE_DOUBLE, { .dbl = 0 },                      0,   DBL_MAX, FLAGS },
+
+
+#if CONFIG_TRIM_FILTER
+static int trim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    TrimContext       *s = ctx->priv;
+    int drop;
+
+    /* drop everything if EOF has already been returned */
+    if (s->eof) {
+        av_frame_free(&frame);
+        return 0;
+    }
+
+    if (s->start_frame >= 0 || s->start_pts != AV_NOPTS_VALUE) {
+        drop = 1;
+        if (s->start_frame >= 0 && s->nb_frames >= s->start_frame)
+            drop = 0;
+        if (s->start_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE &&
+            frame->pts >= s->start_pts)
+            drop = 0;
+        if (drop)
+            goto drop;
+    }
+
+    if (s->first_pts == AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE)
+        s->first_pts = frame->pts;
+
+    if (s->end_frame != INT64_MAX || s->end_pts != AV_NOPTS_VALUE || s->duration_tb) {
+        drop = 1;
+
+        if (s->end_frame != INT64_MAX && s->nb_frames < s->end_frame)
+            drop = 0;
+        if (s->end_pts != AV_NOPTS_VALUE && frame->pts != AV_NOPTS_VALUE &&
+            frame->pts < s->end_pts)
+            drop = 0;
+        if (s->duration_tb && frame->pts != AV_NOPTS_VALUE &&
+            frame->pts - s->first_pts < s->duration_tb)
+            drop = 0;
+
+        if (drop) {
+            s->eof = 1;
+            goto drop;
+        }
+    }
+
+    s->nb_frames++;
+    s->got_output = 1;
+
+    return ff_filter_frame(ctx->outputs[0], frame);
+
+drop:
+    s->nb_frames++;
+    av_frame_free(&frame);
+    return 0;
+}
+
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption trim_options[] = {
+    COMMON_OPTS
+    { "start_frame", "Number of the first frame that should be passed "
+        "to the output",                                                 OFFSET(start_frame), AV_OPT_TYPE_INT64,  { .i64 = -1 },       -1, INT64_MAX, FLAGS },
+    { "end_frame",   "Number of the first frame that should be dropped "
+        "again",                                                         OFFSET(end_frame),   AV_OPT_TYPE_INT64,  { .i64 = INT64_MAX }, 0, INT64_MAX, FLAGS },
+    { NULL },
+};
+#undef FLAGS
+
+static const AVClass trim_class = {
+    .class_name = "trim",
+    .item_name  = av_default_item_name,
+    .option     = trim_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVFilterPad trim_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = trim_filter_frame,
+        .config_props = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad trim_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+        .request_frame = request_frame,
+    },
+    { NULL }
+};
+
+AVFilter ff_vf_trim = {
+    .name        = "trim",
+    .description = NULL_IF_CONFIG_SMALL("Pick one continuous section from the input, drop the rest."),
+
+    .init        = init,
+
+    .priv_size   = sizeof(TrimContext),
+    .priv_class  = &trim_class,
+
+    .inputs      = trim_inputs,
+    .outputs     = trim_outputs,
+};
+#endif // CONFIG_TRIM_FILTER
+
+#if CONFIG_ATRIM_FILTER
+static int atrim_filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    TrimContext       *s = ctx->priv;
+    int64_t start_sample, end_sample = frame->nb_samples;
+    int64_t pts;
+    int drop;
+
+    /* drop everything if EOF has already been returned */
+    if (s->eof) {
+        av_frame_free(&frame);
+        return 0;
+    }
+
+    if (frame->pts != AV_NOPTS_VALUE)
+        pts = av_rescale_q(frame->pts, inlink->time_base,
+                           (AVRational){ 1, inlink->sample_rate });
+    else
+        pts = s->next_pts;
+    s->next_pts = pts + frame->nb_samples;
+
+    /* check if at least a part of the frame is after the start time */
+    if (s->start_sample < 0 && s->start_pts == AV_NOPTS_VALUE) {
+        start_sample = 0;
+    } else {
+        drop = 1;
+        start_sample = frame->nb_samples;
+
+        if (s->start_sample >= 0 &&
+            s->nb_samples + frame->nb_samples > s->start_sample) {
+            drop         = 0;
+            start_sample = FFMIN(start_sample, s->start_sample - s->nb_samples);
+        }
+
+        if (s->start_pts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE &&
+            pts + frame->nb_samples > s->start_pts) {
+            drop = 0;
+            start_sample = FFMIN(start_sample, s->start_pts - pts);
+        }
+
+        if (drop)
+            goto drop;
+    }
+
+    if (s->first_pts == AV_NOPTS_VALUE)
+        s->first_pts = pts + start_sample;
+
+    /* check if at least a part of the frame is before the end time */
+    if (s->end_sample == INT64_MAX && s->end_pts == AV_NOPTS_VALUE && !s->duration_tb) {
+        end_sample = frame->nb_samples;
+    } else {
+        drop       = 1;
+        end_sample = 0;
+
+        if (s->end_sample != INT64_MAX &&
+            s->nb_samples < s->end_sample) {
+            drop       = 0;
+            end_sample = FFMAX(end_sample, s->end_sample - s->nb_samples);
+        }
+
+        if (s->end_pts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE &&
+            pts < s->end_pts) {
+            drop       = 0;
+            end_sample = FFMAX(end_sample, s->end_pts - pts);
+        }
+
+        if (s->duration_tb && pts - s->first_pts < s->duration_tb) {
+            drop       = 0;
+            end_sample = FFMAX(end_sample, s->first_pts + s->duration_tb - pts);
+        }
+
+        if (drop) {
+            s->eof = 1;
+            goto drop;
+        }
+    }
+
+    s->nb_samples += frame->nb_samples;
+    start_sample   = FFMAX(0, start_sample);
+    end_sample     = FFMIN(frame->nb_samples, end_sample);
+    av_assert0(start_sample < end_sample);
+
+    if (start_sample) {
+        AVFrame *out = ff_get_audio_buffer(ctx->outputs[0], end_sample - start_sample);
+        if (!out) {
+            av_frame_free(&frame);
+            return AVERROR(ENOMEM);
+        }
+
+        av_frame_copy_props(out, frame);
+        av_samples_copy(out->extended_data, frame->extended_data, 0, start_sample,
+                        out->nb_samples, av_get_channel_layout_nb_channels(frame->channel_layout),
+                        frame->format);
+        if (out->pts != AV_NOPTS_VALUE)
+            out->pts += av_rescale_q(start_sample, (AVRational){ 1, out->sample_rate },
+                                     inlink->time_base);
+
+        av_frame_free(&frame);
+        frame = out;
+    } else
+        frame->nb_samples = end_sample;
+
+    s->got_output = 1;
+    return ff_filter_frame(ctx->outputs[0], frame);
+
+drop:
+    s->nb_samples += frame->nb_samples;
+    av_frame_free(&frame);
+    return 0;
+}
+
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption atrim_options[] = {
+    COMMON_OPTS
+    { "start_sample", "Number of the first audio sample that should be "
+        "passed to the output",                                          OFFSET(start_sample), AV_OPT_TYPE_INT64,  { .i64 = -1 },       -1, INT64_MAX, FLAGS },
+    { "end_sample",   "Number of the first audio sample that should be "
+        "dropped again",                                                 OFFSET(end_sample),   AV_OPT_TYPE_INT64,  { .i64 = INT64_MAX }, 0, INT64_MAX, FLAGS },
+    { NULL },
+};
+#undef FLAGS
+
+static const AVClass atrim_class = {
+    .class_name = "atrim",
+    .item_name  = av_default_item_name,
+    .option     = atrim_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVFilterPad atrim_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .filter_frame = atrim_filter_frame,
+        .config_props = config_input,
+    },
+    { NULL }
+};
+
+static const AVFilterPad atrim_outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_AUDIO,
+        .request_frame = request_frame,
+    },
+    { NULL }
+};
+
+AVFilter ff_af_atrim = {
+    .name        = "atrim",
+    .description = NULL_IF_CONFIG_SMALL("Pick one continuous section from the input, drop the rest."),
+
+    .init        = init,
+
+    .priv_size   = sizeof(TrimContext),
+    .priv_class  = &atrim_class,
+
+    .inputs      = atrim_inputs,
+    .outputs     = atrim_outputs,
+};
+#endif // CONFIG_ATRIM_FILTER
diff --git a/libavfilter/version.h b/libavfilter/version.h
index c09d44b..9f00ffe 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -23,13 +23,14 @@
 
 /**
  * @file
+ * @ingroup lavfi
  * Libavfilter version macros
  */
 
 #include "libavutil/avutil.h"
 
-#define LIBAVFILTER_VERSION_MAJOR  3
-#define LIBAVFILTER_VERSION_MINOR  3
+#define LIBAVFILTER_VERSION_MAJOR  4
+#define LIBAVFILTER_VERSION_MINOR  0
 #define LIBAVFILTER_VERSION_MICRO  0
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
@@ -47,10 +48,28 @@
  */
 
 #ifndef FF_API_AVFILTERPAD_PUBLIC
-#define FF_API_AVFILTERPAD_PUBLIC           (LIBAVFILTER_VERSION_MAJOR < 4)
+#define FF_API_AVFILTERPAD_PUBLIC           (LIBAVFILTER_VERSION_MAJOR < 5)
 #endif
 #ifndef FF_API_FOO_COUNT
-#define FF_API_FOO_COUNT                    (LIBAVFILTER_VERSION_MAJOR < 4)
+#define FF_API_FOO_COUNT                    (LIBAVFILTER_VERSION_MAJOR < 5)
+#endif
+#ifndef FF_API_AVFILTERBUFFER
+#define FF_API_AVFILTERBUFFER               (LIBAVFILTER_VERSION_MAJOR < 5)
+#endif
+#ifndef FF_API_OLD_FILTER_OPTS
+#define FF_API_OLD_FILTER_OPTS              (LIBAVFILTER_VERSION_MAJOR < 5)
+#endif
+#ifndef FF_API_AVFILTER_OPEN
+#define FF_API_AVFILTER_OPEN                (LIBAVFILTER_VERSION_MAJOR < 5)
+#endif
+#ifndef FF_API_AVFILTER_INIT_FILTER
+#define FF_API_AVFILTER_INIT_FILTER         (LIBAVFILTER_VERSION_MAJOR < 5)
+#endif
+#ifndef FF_API_OLD_FILTER_REGISTER
+#define FF_API_OLD_FILTER_REGISTER          (LIBAVFILTER_VERSION_MAJOR < 5)
+#endif
+#ifndef FF_API_NOCONST_GET_NAME
+#define FF_API_NOCONST_GET_NAME             (LIBAVFILTER_VERSION_MAJOR < 5)
 #endif
 
 #endif /* AVFILTER_VERSION_H */
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index d7e851c..bb7f15e 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -23,75 +23,164 @@
  * aspect ratio modification video filters
  */
 
+#include <float.h>
+
 #include "libavutil/common.h"
+#include "libavutil/eval.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+
 #include "avfilter.h"
 #include "internal.h"
 #include "video.h"
 
+static const char *const var_names[] = {
+    "PI",
+    "PHI",
+    "E",
+    "w",
+    "h",
+    "a", "dar",
+    "sar",
+    "hsub",
+    "vsub",
+    NULL
+};
+
+enum var_name {
+    VAR_PI,
+    VAR_PHI,
+    VAR_E,
+    VAR_W,
+    VAR_H,
+    VAR_A, VAR_DAR,
+    VAR_SAR,
+    VAR_HSUB,
+    VAR_VSUB,
+    VARS_NB
+};
+
 typedef struct {
-    AVRational aspect;
+    const AVClass *class;
+    AVRational dar;
+    AVRational sar;
+#if FF_API_OLD_FILTER_OPTS
+    float aspect_num, aspect_den;
+#endif
+    char *ratio_expr;
 } AspectContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+#if FF_API_OLD_FILTER_OPTS
+static av_cold int init(AVFilterContext *ctx)
 {
-    AspectContext *aspect = ctx->priv;
-    double  ratio;
-    int64_t gcd;
-    char c = 0;
-
-    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) {
-            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;
-        }
-    }
+    AspectContext *s = ctx->priv;
 
-    if (aspect->aspect.den == 0)
-        aspect->aspect = (AVRational) {0, 1};
+    if (s->aspect_num > 0 && s->aspect_den > 0) {
+        av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use "
+               "dar=<number> or dar=num/den.\n");
+        s->sar = s->dar = av_d2q(s->aspect_num / s->aspect_den, INT_MAX);
+    }
 
-    av_log(ctx, AV_LOG_VERBOSE, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den);
     return 0;
 }
+#endif
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
-    AspectContext *aspect = link->dst->priv;
+    AspectContext *s = link->dst->priv;
 
-    frame->video->pixel_aspect = aspect->aspect;
+    frame->sample_aspect_ratio = s->sar;
     return ff_filter_frame(link->dst->outputs[0], frame);
 }
 
+#define OFFSET(x) offsetof(AspectContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+
+static int get_aspect_ratio(AVFilterLink *inlink, AVRational *aspect_ratio)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AspectContext *s = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    double var_values[VARS_NB], res;
+    int ret;
+
+    var_values[VAR_PI]    = M_PI;
+    var_values[VAR_PHI]   = M_PHI;
+    var_values[VAR_E]     = M_E;
+    var_values[VAR_W]     = inlink->w;
+    var_values[VAR_H]     = 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;
+
+    /* evaluate new aspect ratio*/
+    if ((ret = av_expr_parse_and_eval(&res, s->ratio_expr,
+                                      var_names, var_values,
+                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Error when evaluating the expression '%s'\n", s->ratio_expr);
+        return ret;
+    }
+    *aspect_ratio = av_d2q(res, INT_MAX);
+    return 0;
+}
+
 #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;
-
-    av_reduce(&aspect->aspect.num, &aspect->aspect.den,
-               aspect->aspect.num * inlink->h,
-               aspect->aspect.den * inlink->w, 100);
+    AspectContext *s = inlink->dst->priv;
+    AVRational dar;
+    int ret;
+
+#if FF_API_OLD_FILTER_OPTS
+    if (!(s->aspect_num > 0 && s->aspect_den > 0)) {
+#endif
+    if ((ret = get_aspect_ratio(inlink, &s->dar)))
+        return ret;
+#if FF_API_OLD_FILTER_OPTS
+    }
+#endif
+
+    if (s->dar.num && s->dar.den) {
+        av_reduce(&s->sar.num, &s->sar.den,
+                   s->dar.num * inlink->h,
+                   s->dar.den * inlink->w, 100);
+        inlink->sample_aspect_ratio = s->sar;
+        dar = s->dar;
+    } else {
+        inlink->sample_aspect_ratio = (AVRational){ 1, 1 };
+        dar = (AVRational){ inlink->w, inlink->h };
+    }
 
     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->sample_aspect_ratio = aspect->aspect;
+           inlink->w, inlink->h, dar.num, dar.den,
+           inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den);
 
     return 0;
 }
 
+static const AVOption setdar_options[] = {
+#if FF_API_OLD_FILTER_OPTS
+    { "dar_num", NULL, OFFSET(aspect_num), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
+    { "dar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
+#endif
+    { "dar", "display aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "1" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass setdar_class = {
+    .class_name = "setdar",
+    .item_name  = av_default_item_name,
+    .option     = setdar_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_setdar_inputs[] = {
     {
         .name             = "default",
@@ -111,13 +200,16 @@ static const AVFilterPad avfilter_vf_setdar_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_setdar = {
+AVFilter ff_vf_setdar = {
     .name      = "setdar",
     .description = NULL_IF_CONFIG_SMALL("Set the frame display aspect ratio."),
 
+#if FF_API_OLD_FILTER_OPTS
     .init      = init,
+#endif
 
     .priv_size = sizeof(AspectContext),
+    .priv_class = &setdar_class,
 
     .inputs    = avfilter_vf_setdar_inputs,
 
@@ -129,13 +221,39 @@ AVFilter avfilter_vf_setdar = {
 /* for setdar filter, convert from frame aspect ratio to pixel aspect ratio */
 static int setsar_config_props(AVFilterLink *inlink)
 {
-    AspectContext *aspect = inlink->dst->priv;
+    AspectContext *s = inlink->dst->priv;
+    int ret;
+
+#if FF_API_OLD_FILTER_OPTS
+    if (!(s->aspect_num > 0 && s->aspect_den > 0)) {
+#endif
+    if ((ret = get_aspect_ratio(inlink, &s->sar)))
+        return ret;
+#if FF_API_OLD_FILTER_OPTS
+    }
+#endif
 
-    inlink->sample_aspect_ratio = aspect->aspect;
+    inlink->sample_aspect_ratio = s->sar;
 
     return 0;
 }
 
+static const AVOption setsar_options[] = {
+#if FF_API_OLD_FILTER_OPTS
+    { "sar_num", NULL, OFFSET(aspect_num), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
+    { "sar_den", NULL, OFFSET(aspect_den), AV_OPT_TYPE_FLOAT, { .dbl = 0 }, 0, FLT_MAX, FLAGS },
+#endif
+    { "sar", "sample (pixel) aspect ratio", OFFSET(ratio_expr), AV_OPT_TYPE_STRING, { .str = "1" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass setsar_class = {
+    .class_name = "setsar",
+    .item_name  = av_default_item_name,
+    .option     = setsar_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_setsar_inputs[] = {
     {
         .name             = "default",
@@ -155,13 +273,16 @@ static const AVFilterPad avfilter_vf_setsar_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_setsar = {
+AVFilter ff_vf_setsar = {
     .name      = "setsar",
     .description = NULL_IF_CONFIG_SMALL("Set the pixel sample aspect ratio."),
 
+#if FF_API_OLD_FILTER_OPTS
     .init      = init,
+#endif
 
     .priv_size = sizeof(AspectContext),
+    .priv_class = &setsar_class,
 
     .inputs    = avfilter_vf_setsar_inputs,
 
diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c
index 275ebb2..039f055 100644
--- a/libavfilter/vf_blackframe.c
+++ b/libavfilter/vf_blackframe.c
@@ -31,14 +31,17 @@
 #include <inttypes.h>
 
 #include "libavutil/internal.h"
+#include "libavutil/opt.h"
+
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
 typedef struct {
-    unsigned int bamount; ///< black amount
-    unsigned int bthresh; ///< black threshold
+    const AVClass *class;
+    int bamount;          ///< black amount
+    int bthresh;          ///< black threshold
     unsigned int frame;   ///< frame number
     unsigned int nblack;  ///< number of black pixels counted so far
 } BlackFrameContext;
@@ -55,54 +58,48 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    BlackFrameContext *blackframe = ctx->priv;
-
-    blackframe->bamount = 98;
-    blackframe->bthresh = 32;
-    blackframe->nblack = 0;
-    blackframe->frame = 0;
-
-    if (args)
-        sscanf(args, "%u:%u", &blackframe->bamount, &blackframe->bthresh);
-
-    av_log(ctx, AV_LOG_VERBOSE, "bamount:%u bthresh:%u\n",
-           blackframe->bamount, blackframe->bthresh);
-
-    if (blackframe->bamount > 100 || blackframe->bthresh > 255) {
-        av_log(ctx, AV_LOG_ERROR, "Too big value for bamount (max is 100) or bthresh (max is 255)\n");
-        return AVERROR(EINVAL);
-    }
-
-    return 0;
-}
-
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
-    BlackFrameContext *blackframe = ctx->priv;
+    BlackFrameContext *s = ctx->priv;
     int x, i;
     int pblack = 0;
     uint8_t *p = frame->data[0];
 
-    for (i = 0; i < frame->video->h; i++) {
+    for (i = 0; i < frame->height; i++) {
         for (x = 0; x < inlink->w; x++)
-            blackframe->nblack += p[x] < blackframe->bthresh;
+            s->nblack += p[x] < s->bthresh;
         p += frame->linesize[0];
     }
 
-    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",
-               blackframe->frame, pblack, frame->pos, frame->pts,
+    pblack = s->nblack * 100 / (inlink->w * inlink->h);
+    if (pblack >= s->bamount)
+        av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pts:%"PRId64" t:%f\n",
+               s->frame, pblack, frame->pts,
                frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base));
 
-    blackframe->frame++;
-    blackframe->nblack = 0;
+    s->frame++;
+    s->nblack = 0;
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
 
+#define OFFSET(x) offsetof(BlackFrameContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "amount", "Percentage of the pixels that have to be below the threshold "
+        "for the frame to be considered black.", OFFSET(bamount), AV_OPT_TYPE_INT, { .i64 = 98 }, 0, 100,     FLAGS },
+    { "threshold", "threshold below which a pixel value is considered black",
+                                                 OFFSET(bthresh), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, INT_MAX, FLAGS },
+    { NULL },
+};
+
+static const AVClass blackframe_class = {
+    .class_name = "blackframe",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_blackframe_inputs[] = {
     {
         .name             = "default",
@@ -121,12 +118,12 @@ static const AVFilterPad avfilter_vf_blackframe_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_blackframe = {
+AVFilter ff_vf_blackframe = {
     .name        = "blackframe",
     .description = NULL_IF_CONFIG_SMALL("Detect frames that are (almost) black."),
 
     .priv_size = sizeof(BlackFrameContext),
-    .init      = init,
+    .priv_class = &blackframe_class,
 
     .query_formats = query_formats,
 
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
index d72c602..1f26549 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -28,6 +28,7 @@
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "formats.h"
@@ -60,12 +61,13 @@ typedef struct {
 } FilterParam;
 
 typedef struct {
+    const AVClass *class;
     FilterParam luma_param;
     FilterParam chroma_param;
     FilterParam alpha_param;
-    char luma_radius_expr  [256];
-    char chroma_radius_expr[256];
-    char alpha_radius_expr [256];
+    char *luma_radius_expr;
+    char *chroma_radius_expr;
+    char *alpha_radius_expr;
 
     int hsub, vsub;
     int radius[4];
@@ -78,37 +80,26 @@ typedef struct {
 #define V 2
 #define A 3
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    BoxBlurContext *boxblur = ctx->priv;
-    int e;
+    BoxBlurContext *s = ctx->priv;
 
-    if (!args) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Filter expects 2 or 4 or 6 arguments, none provided\n");
+    if (!s->luma_radius_expr) {
+        av_log(ctx, AV_LOG_ERROR, "Luma radius expression is not set.\n");
         return AVERROR(EINVAL);
     }
 
-    e = sscanf(args, "%255[^:]:%d:%255[^:]:%d:%255[^:]:%d",
-               boxblur->luma_radius_expr,   &boxblur->luma_param  .power,
-               boxblur->chroma_radius_expr, &boxblur->chroma_param.power,
-               boxblur->alpha_radius_expr,  &boxblur->alpha_param .power);
-
-    if (e != 2 && e != 4 && e != 6) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Filter expects 2 or 4 or 6 params, provided %d\n", e);
-        return AVERROR(EINVAL);
-    }
-
-    if (e < 4) {
-        boxblur->chroma_param.power = boxblur->luma_param.power;
-        av_strlcpy(boxblur->chroma_radius_expr, boxblur->luma_radius_expr,
-                   sizeof(boxblur->chroma_radius_expr));
+    if (!s->chroma_radius_expr) {
+        s->chroma_radius_expr = av_strdup(s->luma_radius_expr);
+        if (!s->chroma_radius_expr)
+            return AVERROR(ENOMEM);
+        s->chroma_param.power = s->luma_param.power;
     }
-    if (e < 6) {
-        boxblur->alpha_param.power = boxblur->luma_param.power;
-        av_strlcpy(boxblur->alpha_radius_expr, boxblur->luma_radius_expr,
-                   sizeof(boxblur->alpha_radius_expr));
+    if (!s->alpha_radius_expr) {
+        s->alpha_radius_expr = av_strdup(s->luma_radius_expr);
+        if (!s->alpha_radius_expr)
+            return AVERROR(ENOMEM);
+        s->alpha_param.power = s->luma_param.power;
     }
 
     return 0;
@@ -116,10 +107,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    BoxBlurContext *boxblur = ctx->priv;
+    BoxBlurContext *s = ctx->priv;
 
-    av_freep(&boxblur->temp[0]);
-    av_freep(&boxblur->temp[1]);
+    av_freep(&s->temp[0]);
+    av_freep(&s->temp[1]);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -141,37 +132,37 @@ static int config_input(AVFilterLink *inlink)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     AVFilterContext    *ctx = inlink->dst;
-    BoxBlurContext *boxblur = ctx->priv;
+    BoxBlurContext *s = ctx->priv;
     int w = inlink->w, h = inlink->h;
     int cw, ch;
     double var_values[VARS_NB], res;
     char *expr;
     int ret;
 
-    av_freep(&boxblur->temp[0]);
-    av_freep(&boxblur->temp[1]);
-    if (!(boxblur->temp[0] = av_malloc(FFMAX(w, h))))
+    av_freep(&s->temp[0]);
+    av_freep(&s->temp[1]);
+    if (!(s->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 (!(s->temp[1] = av_malloc(FFMAX(w, h)))) {
+        av_freep(&s->temp[0]);
         return AVERROR(ENOMEM);
     }
 
-    boxblur->hsub = desc->log2_chroma_w;
-    boxblur->vsub = desc->log2_chroma_h;
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
 
     var_values[VAR_W]       = inlink->w;
     var_values[VAR_H]       = inlink->h;
-    var_values[VAR_CW] = cw = w>>boxblur->hsub;
-    var_values[VAR_CH] = ch = h>>boxblur->vsub;
-    var_values[VAR_HSUB]    = 1<<boxblur->hsub;
-    var_values[VAR_VSUB]    = 1<<boxblur->vsub;
+    var_values[VAR_CW] = cw = w>>s->hsub;
+    var_values[VAR_CH] = ch = h>>s->vsub;
+    var_values[VAR_HSUB]    = 1<<s->hsub;
+    var_values[VAR_VSUB]    = 1<<s->vsub;
 
 #define EVAL_RADIUS_EXPR(comp)                                          \
-    expr = boxblur->comp##_radius_expr;                                 \
+    expr = s->comp##_radius_expr;                                       \
     ret = av_expr_parse_and_eval(&res, expr, var_names, var_values,     \
                                  NULL, NULL, NULL, NULL, NULL, 0, ctx); \
-    boxblur->comp##_param.radius = res;                                 \
+    s->comp##_param.radius = res;                                       \
     if (ret < 0) {                                                      \
         av_log(NULL, AV_LOG_ERROR,                                      \
                "Error when evaluating " #comp " radius expression '%s'\n", expr); \
@@ -186,30 +177,30 @@ static int config_input(AVFilterLink *inlink)
            "chroma_radius:%d chroma_power:%d "
            "alpha_radius:%d alpha_power:%d "
            "w:%d chroma_w:%d h:%d chroma_h:%d\n",
-           boxblur->luma_param  .radius, boxblur->luma_param  .power,
-           boxblur->chroma_param.radius, boxblur->chroma_param.power,
-           boxblur->alpha_param .radius, boxblur->alpha_param .power,
+           s->luma_param  .radius, s->luma_param  .power,
+           s->chroma_param.radius, s->chroma_param.power,
+           s->alpha_param .radius, s->alpha_param .power,
            w, cw, h, ch);
 
 #define CHECK_RADIUS_VAL(w_, h_, comp)                                  \
-    if (boxblur->comp##_param.radius < 0 ||                             \
-        2*boxblur->comp##_param.radius > FFMIN(w_, h_)) {               \
+    if (s->comp##_param.radius < 0 ||                                   \
+        2*s->comp##_param.radius > FFMIN(w_, h_)) {                     \
         av_log(ctx, AV_LOG_ERROR,                                       \
                "Invalid " #comp " radius value %d, must be >= 0 and <= %d\n", \
-               boxblur->comp##_param.radius, FFMIN(w_, h_)/2);          \
+               s->comp##_param.radius, FFMIN(w_, h_)/2);                \
         return AVERROR(EINVAL);                                         \
     }
     CHECK_RADIUS_VAL(w,  h,  luma);
     CHECK_RADIUS_VAL(cw, ch, chroma);
     CHECK_RADIUS_VAL(w,  h,  alpha);
 
-    boxblur->radius[Y] = boxblur->luma_param.radius;
-    boxblur->radius[U] = boxblur->radius[V] = boxblur->chroma_param.radius;
-    boxblur->radius[A] = boxblur->alpha_param.radius;
+    s->radius[Y] = s->luma_param.radius;
+    s->radius[U] = s->radius[V] = s->chroma_param.radius;
+    s->radius[A] = s->alpha_param.radius;
 
-    boxblur->power[Y] = boxblur->luma_param.power;
-    boxblur->power[U] = boxblur->power[V] = boxblur->chroma_param.power;
-    boxblur->power[A] = boxblur->alpha_param.power;
+    s->power[Y] = s->luma_param.power;
+    s->power[U] = s->power[V] = s->chroma_param.power;
+    s->power[A] = s->alpha_param.power;
 
     return 0;
 }
@@ -307,48 +298,69 @@ static void vblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_li
                    h, radius, power, temp);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx = inlink->dst;
-    BoxBlurContext *boxblur = ctx->priv;
+    BoxBlurContext *s = ctx->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     int plane;
-    int cw = inlink->w >> boxblur->hsub, ch = in->video->h >> boxblur->vsub;
+    int cw = inlink->w >> s->hsub, ch = in->height >> s->vsub;
     int w[4] = { inlink->w, cw, cw, inlink->w };
-    int h[4] = { in->video->h, ch, ch, in->video->h };
+    int h[4] = { in->height, ch, ch, in->height };
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
-    avfilter_copy_buffer_ref_props(out, in);
+    av_frame_copy_props(out, in);
 
     for (plane = 0; in->data[plane] && plane < 4; plane++)
         hblur(out->data[plane], out->linesize[plane],
               in ->data[plane], in ->linesize[plane],
-              w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
-              boxblur->temp);
+              w[plane], h[plane], s->radius[plane], s->power[plane],
+              s->temp);
 
     for (plane = 0; in->data[plane] && plane < 4; plane++)
         vblur(out->data[plane], out->linesize[plane],
               out->data[plane], out->linesize[plane],
-              w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
-              boxblur->temp);
+              w[plane], h[plane], s->radius[plane], s->power[plane],
+              s->temp);
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
 
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(BoxBlurContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "luma_radius", "Radius of the luma blurring box",     OFFSET(luma_radius_expr),   AV_OPT_TYPE_STRING,               .flags = FLAGS },
+    { "luma_power",  "How many times should the boxblur be applied to luma",
+                                                            OFFSET(luma_param.power),   AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, FLAGS },
+    { "chroma_radius", "Radius of the chroma blurring box", OFFSET(chroma_radius_expr), AV_OPT_TYPE_STRING,               .flags = FLAGS },
+    { "chroma_power",  "How many times should the boxblur be applied to chroma",
+                                                            OFFSET(chroma_param.power), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, FLAGS },
+    { "alpha_radius", "Radius of the alpha blurring box",   OFFSET(alpha_radius_expr),  AV_OPT_TYPE_STRING,               .flags = FLAGS },
+    { "alpha_power",  "How many times should the boxblur be applied to alpha",
+                                                            OFFSET(alpha_param.power),  AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, FLAGS },
+    { NULL },
+};
+
+static const AVClass boxblur_class = {
+    .class_name = "boxblur",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_boxblur_inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
         .filter_frame = filter_frame,
-        .min_perms    = AV_PERM_READ
     },
     { NULL }
 };
@@ -361,10 +373,11 @@ static const AVFilterPad avfilter_vf_boxblur_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_boxblur = {
+AVFilter ff_vf_boxblur = {
     .name          = "boxblur",
     .description   = NULL_IF_CONFIG_SMALL("Blur the input."),
     .priv_size     = sizeof(BoxBlurContext),
+    .priv_class    = &boxblur_class,
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
diff --git a/libavfilter/vf_copy.c b/libavfilter/vf_copy.c
index 8ece5cf..55175a0 100644
--- a/libavfilter/vf_copy.c
+++ b/libavfilter/vf_copy.c
@@ -21,17 +21,35 @@
  * copy video filter
  */
 
+#include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "video.h"
 
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFrame *out = ff_get_video_buffer(outlink, in->width, in->height);
+
+    if (!out) {
+        av_frame_free(&in);
+        return AVERROR(ENOMEM);
+    }
+    av_frame_copy_props(out, in);
+    av_image_copy(out->data, out->linesize, in->data, in->linesize,
+                  in->format, in->width, in->height);
+
+    av_frame_free(&in);
+    return ff_filter_frame(outlink, out);
+}
+
 static const AVFilterPad avfilter_vf_copy_inputs[] = {
     {
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
-        .rej_perms        = ~0
+        .filter_frame     = filter_frame,
     },
     { NULL }
 };
@@ -44,7 +62,7 @@ static const AVFilterPad avfilter_vf_copy_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_copy = {
+AVFilter ff_vf_copy = {
     .name      = "copy",
     .description = NULL_IF_CONFIG_SMALL("Copy the input video unchanged to the output."),
 
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 981dfd6..1aa8466 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -23,8 +23,6 @@
  * video crop filter
  */
 
-/* #define DEBUG */
-
 #include <stdio.h>
 
 #include "avfilter.h"
@@ -37,6 +35,7 @@
 #include "libavutil/libm.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 
 static const char *const var_names[] = {
     "E",
@@ -65,12 +64,12 @@ enum var_name {
     VAR_X,
     VAR_Y,
     VAR_N,
-    VAR_POS,
     VAR_T,
     VAR_VARS_NB
 };
 
 typedef struct {
+    const AVClass *class;
     int  x;             ///< x offset of the non-cropped area with respect to the input area
     int  y;             ///< y offset of the non-cropped area with respect to the input area
     int  w;             ///< width of the cropped area
@@ -78,7 +77,7 @@ typedef struct {
 
     int max_step[4];    ///< max pixel step for each plane, expressed as a number of bytes
     int hsub, vsub;     ///< chroma subsampling
-    char x_expr[256], y_expr[256], ow_expr[256], oh_expr[256];
+    char *x_expr, *y_expr, *ow_expr, *oh_expr;
     AVExpr *x_pexpr, *y_pexpr;  /* parsed expressions for x and y */
     double var_values[VAR_VARS_NB];
 } CropContext;
@@ -116,27 +115,14 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    CropContext *crop = ctx->priv;
-
-    av_strlcpy(crop->ow_expr, "iw", sizeof(crop->ow_expr));
-    av_strlcpy(crop->oh_expr, "ih", sizeof(crop->oh_expr));
-    av_strlcpy(crop->x_expr, "(in_w-out_w)/2", sizeof(crop->x_expr));
-    av_strlcpy(crop->y_expr, "(in_h-out_h)/2", sizeof(crop->y_expr));
-
-    if (args)
-        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]", crop->ow_expr, crop->oh_expr, crop->x_expr, crop->y_expr);
-
-    return 0;
-}
-
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    CropContext *crop = ctx->priv;
+    CropContext *s = ctx->priv;
 
-    av_expr_free(crop->x_pexpr); crop->x_pexpr = NULL;
-    av_expr_free(crop->y_pexpr); crop->y_pexpr = NULL;
+    av_expr_free(s->x_pexpr);
+    s->x_pexpr = NULL;
+    av_expr_free(s->y_pexpr);
+    s->y_pexpr = NULL;
 }
 
 static inline int normalize_double(int *n, double d)
@@ -157,75 +143,81 @@ static inline int normalize_double(int *n, double d)
 static int config_input(AVFilterLink *link)
 {
     AVFilterContext *ctx = link->dst;
-    CropContext *crop = ctx->priv;
+    CropContext *s = ctx->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(link->format);
     int ret;
     const char *expr;
     double res;
 
-    crop->var_values[VAR_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_X]     = NAN;
-    crop->var_values[VAR_Y]     = NAN;
-    crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = NAN;
-    crop->var_values[VAR_OUT_H] = crop->var_values[VAR_OH] = NAN;
-    crop->var_values[VAR_N]     = 0;
-    crop->var_values[VAR_T]     = NAN;
-    crop->var_values[VAR_POS]   = NAN;
-
-    av_image_fill_max_pixsteps(crop->max_step, NULL, pix_desc);
-    crop->hsub = pix_desc->log2_chroma_w;
-    crop->vsub = pix_desc->log2_chroma_h;
-
-    if ((ret = av_expr_parse_and_eval(&res, (expr = crop->ow_expr),
-                                      var_names, crop->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
-    crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = res;
-    if ((ret = av_expr_parse_and_eval(&res, (expr = crop->oh_expr),
-                                      var_names, crop->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
-    crop->var_values[VAR_OUT_H] = crop->var_values[VAR_OH] = res;
+    s->var_values[VAR_E]     = M_E;
+    s->var_values[VAR_PHI]   = M_PHI;
+    s->var_values[VAR_PI]    = M_PI;
+    s->var_values[VAR_IN_W]  = s->var_values[VAR_IW] = ctx->inputs[0]->w;
+    s->var_values[VAR_IN_H]  = s->var_values[VAR_IH] = ctx->inputs[0]->h;
+    s->var_values[VAR_X]     = NAN;
+    s->var_values[VAR_Y]     = NAN;
+    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = NAN;
+    s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = NAN;
+    s->var_values[VAR_N]     = 0;
+    s->var_values[VAR_T]     = NAN;
+
+    av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc);
+    s->hsub = pix_desc->log2_chroma_w;
+    s->vsub = pix_desc->log2_chroma_h;
+
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->ow_expr),
+                                      var_names, s->var_values,
+                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
+        goto fail_expr;
+    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res;
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->oh_expr),
+                                      var_names, s->var_values,
+                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
+        goto fail_expr;
+    s->var_values[VAR_OUT_H] = s->var_values[VAR_OH] = res;
     /* evaluate again ow as it may depend on oh */
-    if ((ret = av_expr_parse_and_eval(&res, (expr = crop->ow_expr),
-                                      var_names, crop->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail_expr;
-    crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = res;
-    if (normalize_double(&crop->w, crop->var_values[VAR_OUT_W]) < 0 ||
-        normalize_double(&crop->h, crop->var_values[VAR_OUT_H]) < 0) {
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->ow_expr),
+                                      var_names, s->var_values,
+                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
+        goto fail_expr;
+
+    s->var_values[VAR_OUT_W] = s->var_values[VAR_OW] = res;
+    if (normalize_double(&s->w, s->var_values[VAR_OUT_W]) < 0 ||
+        normalize_double(&s->h, s->var_values[VAR_OUT_H]) < 0) {
         av_log(ctx, AV_LOG_ERROR,
                "Too big value or invalid expression for out_w/ow or out_h/oh. "
                "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
-               crop->ow_expr, crop->oh_expr);
+               s->ow_expr, s->oh_expr);
         return AVERROR(EINVAL);
     }
-    crop->w &= ~((1 << crop->hsub) - 1);
-    crop->h &= ~((1 << crop->vsub) - 1);
+    s->w &= ~((1 << s->hsub) - 1);
+    s->h &= ~((1 << s->vsub) - 1);
 
-    if ((ret = av_expr_parse(&crop->x_pexpr, crop->x_expr, var_names,
+    av_expr_free(s->x_pexpr);
+    av_expr_free(s->y_pexpr);
+    s->x_pexpr = s->y_pexpr = NULL;
+    if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names,
                              NULL, NULL, NULL, NULL, 0, ctx)) < 0 ||
-        (ret = av_expr_parse(&crop->y_pexpr, crop->y_expr, var_names,
+        (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names,
                              NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         return AVERROR(EINVAL);
 
     av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",
-           link->w, link->h, crop->w, crop->h);
+           link->w, link->h, s->w, s->h);
 
-    if (crop->w <= 0 || crop->h <= 0 ||
-        crop->w > link->w || crop->h > link->h) {
+    if (s->w <= 0 || s->h <= 0 ||
+        s->w > link->w || s->h > link->h) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid too big or non positive size for width '%d' or height '%d'\n",
-               crop->w, crop->h);
+               s->w, s->h);
         return AVERROR(EINVAL);
     }
 
     /* set default, required in the case the first computed value for x/y is NAN */
-    crop->x = (link->w - crop->w) / 2;
-    crop->y = (link->h - crop->h) / 2;
-    crop->x &= ~((1 << crop->hsub) - 1);
-    crop->y &= ~((1 << crop->vsub) - 1);
+    s->x = (link->w - s->w) / 2;
+    s->y = (link->h - s->h) / 2;
+    s->x &= ~((1 << s->hsub) - 1);
+    s->y &= ~((1 << s->vsub) - 1);
     return 0;
 
 fail_expr:
@@ -235,68 +227,90 @@ fail_expr:
 
 static int config_output(AVFilterLink *link)
 {
-    CropContext *crop = link->src->priv;
+    CropContext *s = link->src->priv;
 
-    link->w = crop->w;
-    link->h = crop->h;
+    link->w = s->w;
+    link->h = s->h;
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
     AVFilterContext *ctx = link->dst;
-    CropContext *crop = ctx->priv;
+    CropContext *s = ctx->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
     int i;
 
-    frame->video->w = crop->w;
-    frame->video->h = crop->h;
+    frame->width  = s->w;
+    frame->height = s->h;
 
-    crop->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
+    s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
         NAN : frame->pts * av_q2d(link->time_base);
-    crop->var_values[VAR_POS] = frame->pos == -1 ? NAN : frame->pos;
-    crop->var_values[VAR_X] = av_expr_eval(crop->x_pexpr, crop->var_values, NULL);
-    crop->var_values[VAR_Y] = av_expr_eval(crop->y_pexpr, crop->var_values, NULL);
-    crop->var_values[VAR_X] = av_expr_eval(crop->x_pexpr, crop->var_values, NULL);
-
-    normalize_double(&crop->x, crop->var_values[VAR_X]);
-    normalize_double(&crop->y, crop->var_values[VAR_Y]);
-
-    if (crop->x < 0) crop->x = 0;
-    if (crop->y < 0) crop->y = 0;
-    if ((unsigned)crop->x + (unsigned)crop->w > link->w) crop->x = link->w - crop->w;
-    if ((unsigned)crop->y + (unsigned)crop->h > link->h) crop->y = link->h - crop->h;
-    crop->x &= ~((1 << crop->hsub) - 1);
-    crop->y &= ~((1 << crop->vsub) - 1);
+    s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
+    s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, NULL);
+    s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
+
+    normalize_double(&s->x, s->var_values[VAR_X]);
+    normalize_double(&s->y, s->var_values[VAR_Y]);
+
+    if (s->x < 0)
+        s->x = 0;
+    if (s->y < 0)
+        s->y = 0;
+    if ((unsigned)s->x + (unsigned)s->w > link->w)
+        s->x = link->w - s->w;
+    if ((unsigned)s->y + (unsigned)s->h > link->h)
+        s->y = link->h - s->h;
+    s->x &= ~((1 << s->hsub) - 1);
+    s->y &= ~((1 << s->vsub) - 1);
 
     av_dlog(ctx, "n:%d t:%f x:%d y:%d x+w:%d y+h:%d\n",
-            (int)crop->var_values[VAR_N], crop->var_values[VAR_T], crop->x,
-            crop->y, crop->x+crop->w, crop->y+crop->h);
+            (int)s->var_values[VAR_N], s->var_values[VAR_T], s->x,
+            s->y, s->x+s->w, s->y+s->h);
 
-    frame->data[0] += crop->y * frame->linesize[0];
-    frame->data[0] += crop->x * crop->max_step[0];
+    frame->data[0] += s->y * frame->linesize[0];
+    frame->data[0] += s->x * s->max_step[0];
 
-    if (!(desc->flags & PIX_FMT_PAL || desc->flags & PIX_FMT_PSEUDOPAL)) {
+    if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
         for (i = 1; i < 3; i ++) {
             if (frame->data[i]) {
-                frame->data[i] += (crop->y >> crop->vsub) * frame->linesize[i];
-                frame->data[i] += (crop->x * crop->max_step[i]) >> crop->hsub;
+                frame->data[i] += (s->y >> s->vsub) * frame->linesize[i];
+                frame->data[i] += (s->x * s->max_step[i]) >> s->hsub;
             }
         }
     }
 
     /* alpha plane */
     if (frame->data[3]) {
-        frame->data[3] += crop->y * frame->linesize[3];
-        frame->data[3] += crop->x * crop->max_step[3];
+        frame->data[3] += s->y * frame->linesize[3];
+        frame->data[3] += s->x * s->max_step[3];
     }
 
-    crop->var_values[VAR_N] += 1.0;
+    s->var_values[VAR_N] += 1.0;
 
     return ff_filter_frame(link->dst->outputs[0], frame);
 }
 
+#define OFFSET(x) offsetof(CropContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "out_w", "Output video width",  OFFSET(ow_expr), AV_OPT_TYPE_STRING, { .str = "iw" },                 .flags = FLAGS },
+    { "out_h", "Output video height", OFFSET(oh_expr), AV_OPT_TYPE_STRING, { .str = "ih" },                 .flags = FLAGS },
+    { "x",     "Horizontal position in the input video of the left edge of the cropped output video",
+                                      OFFSET(x_expr),  AV_OPT_TYPE_STRING, { .str = "(in_w - out_w) / 2" }, .flags = FLAGS },
+    { "y",     "Vertical position in the input video of the top edge of the cropped output video",
+                                      OFFSET(y_expr),  AV_OPT_TYPE_STRING, { .str = "(in_h - out_h) / 2" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass crop_class = {
+    .class_name = "crop",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_crop_inputs[] = {
     {
         .name             = "default",
@@ -317,14 +331,14 @@ static const AVFilterPad avfilter_vf_crop_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_crop = {
+AVFilter ff_vf_crop = {
     .name      = "crop",
     .description = NULL_IF_CONFIG_SMALL("Crop the input video to width:height:x:y."),
 
     .priv_size = sizeof(CropContext),
+    .priv_class = &crop_class,
 
     .query_formats = query_formats,
-    .init          = init,
     .uninit        = uninit,
 
     .inputs    = avfilter_vf_crop_inputs,
diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index eebd8bc..ea9e47d 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -27,12 +27,15 @@
 
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
+#include "libavutil/opt.h"
+
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
 typedef struct {
+    const AVClass *class;
     int x1, y1, x2, y2;
     int limit;
     int round;
@@ -83,20 +86,14 @@ static int checkline(void *ctx, const unsigned char *src, int stride, int len, i
     return total;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    CropDetectContext *cd = ctx->priv;
-
-    cd->limit = 24;
-    cd->round = 0;
-    cd->reset_count = 0;
-    cd->frame_nb = -2;
+    CropDetectContext *s = ctx->priv;
 
-    if (args)
-        sscanf(args, "%d:%d:%d", &cd->limit, &cd->round, &cd->reset_count);
+    s->frame_nb = -2;
 
     av_log(ctx, AV_LOG_VERBOSE, "limit:%d round:%d reset_count:%d\n",
-           cd->limit, cd->round, cd->reset_count);
+           s->limit, s->round, s->reset_count);
 
     return 0;
 }
@@ -104,91 +101,91 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    CropDetectContext *cd = ctx->priv;
+    CropDetectContext *s = ctx->priv;
 
-    av_image_fill_max_pixsteps(cd->max_pixsteps, NULL,
+    av_image_fill_max_pixsteps(s->max_pixsteps, NULL,
                                av_pix_fmt_desc_get(inlink->format));
 
-    cd->x1 = inlink->w - 1;
-    cd->y1 = inlink->h - 1;
-    cd->x2 = 0;
-    cd->y2 = 0;
+    s->x1 = inlink->w - 1;
+    s->y1 = inlink->h - 1;
+    s->x2 = 0;
+    s->y2 = 0;
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
-    CropDetectContext *cd = ctx->priv;
-    int bpp = cd->max_pixsteps[0];
+    CropDetectContext *s = ctx->priv;
+    int bpp = s->max_pixsteps[0];
     int w, h, x, y, shrink_by;
 
     // ignore first 2 frames - they may be empty
-    if (++cd->frame_nb > 0) {
+    if (++s->frame_nb > 0) {
         // Reset the crop area every reset_count frames, if reset_count is > 0
-        if (cd->reset_count > 0 && cd->frame_nb > cd->reset_count) {
-            cd->x1 = frame->video->w-1;
-            cd->y1 = frame->video->h-1;
-            cd->x2 = 0;
-            cd->y2 = 0;
-            cd->frame_nb = 1;
+        if (s->reset_count > 0 && s->frame_nb > s->reset_count) {
+            s->x1 = frame->width  - 1;
+            s->y1 = frame->height - 1;
+            s->x2 = 0;
+            s->y2 = 0;
+            s->frame_nb = 1;
         }
 
-        for (y = 0; y < cd->y1; y++) {
-            if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->video->w, bpp) > cd->limit) {
-                cd->y1 = y;
+        for (y = 0; y < s->y1; y++) {
+            if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > s->limit) {
+                s->y1 = y;
                 break;
             }
         }
 
-        for (y = frame->video->h-1; y > cd->y2; y--) {
-            if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->video->w, bpp) > cd->limit) {
-                cd->y2 = y;
+        for (y = frame->height - 1; y > s->y2; y--) {
+            if (checkline(ctx, frame->data[0] + frame->linesize[0] * y, bpp, frame->width, bpp) > s->limit) {
+                s->y2 = y;
                 break;
             }
         }
 
-        for (y = 0; y < cd->x1; y++) {
-            if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->video->h, bpp) > cd->limit) {
-                cd->x1 = y;
+        for (y = 0; y < s->x1; y++) {
+            if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > s->limit) {
+                s->x1 = y;
                 break;
             }
         }
 
-        for (y = frame->video->w-1; y > cd->x2; y--) {
-            if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->video->h, bpp) > cd->limit) {
-                cd->x2 = y;
+        for (y = frame->width - 1; y > s->x2; y--) {
+            if (checkline(ctx, frame->data[0] + bpp*y, frame->linesize[0], frame->height, bpp) > s->limit) {
+                s->x2 = y;
                 break;
             }
         }
 
         // round x and y (up), important for yuv colorspaces
         // make sure they stay rounded!
-        x = (cd->x1+1) & ~1;
-        y = (cd->y1+1) & ~1;
+        x = (s->x1+1) & ~1;
+        y = (s->y1+1) & ~1;
 
-        w = cd->x2 - x + 1;
-        h = cd->y2 - y + 1;
+        w = s->x2 - x + 1;
+        h = s->y2 - y + 1;
 
         // w and h must be divisible by 2 as well because of yuv
         // colorspace problems.
-        if (cd->round <= 1)
-            cd->round = 16;
-        if (cd->round % 2)
-            cd->round *= 2;
+        if (s->round <= 1)
+            s->round = 16;
+        if (s->round % 2)
+            s->round *= 2;
 
-        shrink_by = w % cd->round;
+        shrink_by = w % s->round;
         w -= shrink_by;
         x += (shrink_by/2 + 1) & ~1;
 
-        shrink_by = h % cd->round;
+        shrink_by = h % s->round;
         h -= shrink_by;
         y += (shrink_by/2 + 1) & ~1;
 
         av_log(ctx, AV_LOG_INFO,
-               "x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pos:%"PRId64" pts:%"PRId64" t:%f crop=%d:%d:%d:%d\n",
-               cd->x1, cd->x2, cd->y1, cd->y2, w, h, x, y, frame->pos, frame->pts,
+               "x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pts:%"PRId64" t:%f crop=%d:%d:%d:%d\n",
+               s->x1, s->x2, s->y1, s->y2, w, h, x, y, frame->pts,
                frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base),
                w, h, x, y);
     }
@@ -196,6 +193,22 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
 
+#define OFFSET(x) offsetof(CropDetectContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "limit", "Threshold below which the pixel is considered black", OFFSET(limit),       AV_OPT_TYPE_INT, { .i64 = 24 }, 0, INT_MAX, FLAGS },
+    { "round", "Value by which the width/height should be divisible", OFFSET(round),       AV_OPT_TYPE_INT, { .i64 = 0  }, 0, INT_MAX, FLAGS },
+    { "reset", "Recalculate the crop area after this many frames",    OFFSET(reset_count), AV_OPT_TYPE_INT, { .i64 = 0 },  0, INT_MAX, FLAGS },
+    { NULL },
+};
+
+static const AVClass cropdetect_class = {
+    .class_name = "cropdetect",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_cropdetect_inputs[] = {
     {
         .name             = "default",
@@ -215,11 +228,12 @@ static const AVFilterPad avfilter_vf_cropdetect_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_cropdetect = {
+AVFilter ff_vf_cropdetect = {
     .name        = "cropdetect",
     .description = NULL_IF_CONFIG_SMALL("Auto-detect crop size."),
 
     .priv_size = sizeof(CropDetectContext),
+    .priv_class = &cropdetect_class,
     .init      = init,
 
     .query_formats = query_formats,
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index af479c2..4175e47 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -136,16 +136,17 @@ typedef struct {
 }  DelogoContext;
 
 #define OFFSET(x) offsetof(DelogoContext, x)
+#define FLAGS 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       },
-    {NULL},
+    { "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)
@@ -172,28 +173,13 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    DelogoContext *delogo = ctx->priv;
-    int ret = 0;
-
-    delogo->class = &delogo_class;
-    av_opt_set_defaults(delogo);
-
-    if (args)
-        ret = sscanf(args, "%d:%d:%d:%d:%d",
-                     &delogo->x, &delogo->y, &delogo->w, &delogo->h, &delogo->band);
-    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);
-        return ret;
-    }
+    DelogoContext *s = ctx->priv;
 
 #define CHECK_UNSET_OPT(opt)                                            \
-    if (delogo->opt == -1) {                                            \
-        av_log(delogo, AV_LOG_ERROR, "Option %s was not set.\n", #opt); \
+    if (s->opt == -1) {                                            \
+        av_log(s, AV_LOG_ERROR, "Option %s was not set.\n", #opt); \
         return AVERROR(EINVAL);                                         \
     }
     CHECK_UNSET_OPT(x);
@@ -201,44 +187,44 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
     CHECK_UNSET_OPT(w);
     CHECK_UNSET_OPT(h);
 
-    if (delogo->show)
-        delogo->band = 4;
+    if (s->show)
+        s->band = 4;
 
     av_log(ctx, AV_LOG_DEBUG, "x:%d y:%d, w:%d h:%d band:%d show:%d\n",
-           delogo->x, delogo->y, delogo->w, delogo->h, delogo->band, delogo->show);
+           s->x, s->y, s->w, s->h, s->band, s->show);
 
-    delogo->w += delogo->band*2;
-    delogo->h += delogo->band*2;
-    delogo->x -= delogo->band;
-    delogo->y -= delogo->band;
+    s->w += s->band*2;
+    s->h += s->band*2;
+    s->x -= s->band;
+    s->y -= s->band;
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    DelogoContext *delogo = inlink->dst->priv;
+    DelogoContext *s = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
-    AVFilterBufferRef *out;
+    AVFrame *out;
     int hsub0 = desc->log2_chroma_w;
     int vsub0 = desc->log2_chroma_h;
     int direct = 0;
     int plane;
 
-    if ((in->perms & AV_PERM_WRITE) && !(in->perms & AV_PERM_PRESERVE)) {
+    if (av_frame_is_writable(in)) {
         direct = 1;
         out = in;
     } else {
-        out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
         if (!out) {
-            avfilter_unref_bufferp(&in);
+            av_frame_free(&in);
             return AVERROR(ENOMEM);
         }
 
-        avfilter_copy_buffer_ref_props(out, in);
-        out->video->w = outlink->w;
-        out->video->h = outlink->h;
+        av_frame_copy_props(out, in);
+        out->width  = outlink->w;
+        out->height = outlink->h;
     }
 
     for (plane = 0; plane < 4 && in->data[plane]; plane++) {
@@ -248,14 +234,14 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
         apply_delogo(out->data[plane], out->linesize[plane],
                      in ->data[plane], in ->linesize[plane],
                      inlink->w>>hsub, inlink->h>>vsub,
-                     delogo->x>>hsub, delogo->y>>vsub,
-                     delogo->w>>hsub, delogo->h>>vsub,
-                     delogo->band>>FFMIN(hsub, vsub),
-                     delogo->show, direct);
+                     s->x>>hsub, s->y>>vsub,
+                     s->w>>hsub, s->h>>vsub,
+                     s->band>>FFMIN(hsub, vsub),
+                     s->show, direct);
     }
 
     if (!direct)
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
 
     return ff_filter_frame(outlink, out);
 }
@@ -266,8 +252,6 @@ static const AVFilterPad avfilter_vf_delogo_inputs[] = {
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
         .filter_frame     = filter_frame,
-        .min_perms        = AV_PERM_WRITE | AV_PERM_READ,
-        .rej_perms        = AV_PERM_PRESERVE
     },
     { NULL }
 };
@@ -280,10 +264,11 @@ static const AVFilterPad avfilter_vf_delogo_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_delogo = {
+AVFilter ff_vf_delogo = {
     .name          = "delogo",
     .description   = NULL_IF_CONFIG_SMALL("Remove logo from input video."),
     .priv_size     = sizeof(DelogoContext),
+    .priv_class    = &delogo_class,
     .init          = init,
     .query_formats = query_formats,
 
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index c47422e..2241974 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -26,6 +26,7 @@
 
 #include "libavutil/colorspace.h"
 #include "libavutil/common.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/parseutils.h"
 #include "avfilter.h"
@@ -36,30 +37,25 @@
 enum { Y, U, V, A };
 
 typedef struct {
-    int x, y, w, h;
+    const AVClass *class;
+    int x, y, w_opt, h_opt, w, h;
+    char *color_str;
     unsigned char yuv_color[4];
     int vsub, hsub;   ///< chroma subsampling
 } DrawBoxContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    DrawBoxContext *drawbox= ctx->priv;
-    char color_str[1024] = "black";
+    DrawBoxContext *s = ctx->priv;
     uint8_t rgba_color[4];
 
-    drawbox->x = drawbox->y = drawbox->w = drawbox->h = 0;
-
-    if (args)
-        sscanf(args, "%d:%d:%d:%d:%s",
-               &drawbox->x, &drawbox->y, &drawbox->w, &drawbox->h, color_str);
-
-    if (av_parse_color(rgba_color, color_str, -1, ctx) < 0)
+    if (av_parse_color(rgba_color, s->color_str, -1, ctx) < 0)
         return AVERROR(EINVAL);
 
-    drawbox->yuv_color[Y] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
-    drawbox->yuv_color[U] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
-    drawbox->yuv_color[V] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
-    drawbox->yuv_color[A] = rgba_color[3];
+    s->yuv_color[Y] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
+    s->yuv_color[U] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
+    s->yuv_color[V] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
+    s->yuv_color[A] = rgba_color[3];
 
     return 0;
 }
@@ -80,43 +76,43 @@ static int query_formats(AVFilterContext *ctx)
 
 static int config_input(AVFilterLink *inlink)
 {
-    DrawBoxContext *drawbox = inlink->dst->priv;
+    DrawBoxContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
 
-    drawbox->hsub = desc->log2_chroma_w;
-    drawbox->vsub = desc->log2_chroma_h;
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
 
-    if (drawbox->w == 0) drawbox->w = inlink->w;
-    if (drawbox->h == 0) drawbox->h = inlink->h;
+    s->w = (s->w_opt > 0) ? s->w_opt : inlink->w;
+    s->h = (s->h_opt > 0) ? s->h_opt : 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->yuv_color[Y], drawbox->yuv_color[U], drawbox->yuv_color[V], drawbox->yuv_color[A]);
+           s->w, s->y, s->w, s->h,
+           s->yuv_color[Y], s->yuv_color[U], s->yuv_color[V], s->yuv_color[A]);
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
-    DrawBoxContext *drawbox = inlink->dst->priv;
-    int plane, x, y, xb = drawbox->x, yb = drawbox->y;
+    DrawBoxContext *s = inlink->dst->priv;
+    int plane, x, y, xb = s->x, yb = s->y;
     unsigned char *row[4];
 
-    for (y = FFMAX(yb, 0); y < frame->video->h && y < (yb + drawbox->h); y++) {
+    for (y = FFMAX(yb, 0); y < frame->height && y < (yb + s->h); y++) {
         row[0] = frame->data[0] + y * frame->linesize[0];
 
         for (plane = 1; plane < 3; plane++)
             row[plane] = frame->data[plane] +
-                 frame->linesize[plane] * (y >> drawbox->vsub);
+                 frame->linesize[plane] * (y >> s->vsub);
 
-        for (x = FFMAX(xb, 0); x < (xb + drawbox->w) && x < frame->video->w; x++) {
-            double alpha = (double)drawbox->yuv_color[A] / 255;
+        for (x = FFMAX(xb, 0); x < (xb + s->w) && x < frame->width; x++) {
+            double alpha = (double)s->yuv_color[A] / 255;
 
-            if ((y - yb < 3) || (yb + drawbox->h - y < 4) ||
-                (x - xb < 3) || (xb + drawbox->w - x < 4)) {
-                row[0][x                 ] = (1 - alpha) * row[0][x                 ] + alpha * drawbox->yuv_color[Y];
-                row[1][x >> drawbox->hsub] = (1 - alpha) * row[1][x >> drawbox->hsub] + alpha * drawbox->yuv_color[U];
-                row[2][x >> drawbox->hsub] = (1 - alpha) * row[2][x >> drawbox->hsub] + alpha * drawbox->yuv_color[V];
+            if ((y - yb < 3) || (yb + s->h - y < 4) ||
+                (x - xb < 3) || (xb + s->w - x < 4)) {
+                row[0][x                 ] = (1 - alpha) * row[0][x                 ] + alpha * s->yuv_color[Y];
+                row[1][x >> s->hsub] = (1 - alpha) * row[1][x >> s->hsub] + alpha * s->yuv_color[U];
+                row[2][x >> s->hsub] = (1 - alpha) * row[2][x >> s->hsub] + alpha * s->yuv_color[V];
             }
         }
     }
@@ -124,6 +120,24 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
 
+#define OFFSET(x) offsetof(DrawBoxContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "x",      "Horizontal position of the left box edge", OFFSET(x),         AV_OPT_TYPE_INT,    { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
+    { "y",      "Vertical position of the top box edge",    OFFSET(y),         AV_OPT_TYPE_INT,    { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
+    { "width",  "Width of the box",                         OFFSET(w_opt),     AV_OPT_TYPE_INT,    { .i64 = 0 }, 0,       INT_MAX, FLAGS },
+    { "height", "Height of the box",                        OFFSET(h_opt),     AV_OPT_TYPE_INT,    { .i64 = 0 }, 0,       INT_MAX, FLAGS },
+    { "color",  "Color of the box",                         OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" },    .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass drawbox_class = {
+    .class_name = "drawbox",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_drawbox_inputs[] = {
     {
         .name             = "default",
@@ -131,8 +145,7 @@ static const AVFilterPad avfilter_vf_drawbox_inputs[] = {
         .config_props     = config_input,
         .get_video_buffer = ff_null_get_video_buffer,
         .filter_frame     = filter_frame,
-        .min_perms        = AV_PERM_WRITE | AV_PERM_READ,
-        .rej_perms        = AV_PERM_PRESERVE
+        .needs_writable   = 1,
     },
     { NULL }
 };
@@ -145,10 +158,11 @@ static const AVFilterPad avfilter_vf_drawbox_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_drawbox = {
+AVFilter ff_vf_drawbox = {
     .name      = "drawbox",
     .description = NULL_IF_CONFIG_SMALL("Draw a colored box on the input video."),
     .priv_size = sizeof(DrawBoxContext),
+    .priv_class = &drawbox_class,
     .init      = init,
 
     .query_formats   = query_formats,
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index f8800d2..703b472 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -144,43 +144,44 @@ typedef struct {
 } DrawTextContext;
 
 #define OFFSET(x) offsetof(DrawTextContext, x)
+#define FLAGS 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        },
-
-/* 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" },
-{NULL},
+    { "fontfile",    NULL,                   OFFSET(fontfile),           AV_OPT_TYPE_STRING,                              .flags = FLAGS },
+    { "text",        NULL,                   OFFSET(text),               AV_OPT_TYPE_STRING,                              .flags = FLAGS },
+    { "textfile",    NULL,                   OFFSET(textfile),           AV_OPT_TYPE_STRING,                              .flags = FLAGS },
+    { "fontcolor",   NULL,                   OFFSET(fontcolor_string),   AV_OPT_TYPE_STRING, { .str = "black" },          .flags = FLAGS },
+    { "boxcolor",    NULL,                   OFFSET(boxcolor_string),    AV_OPT_TYPE_STRING, { .str = "white" },          .flags = FLAGS },
+    { "shadowcolor", NULL,                   OFFSET(shadowcolor_string), AV_OPT_TYPE_STRING, { .str = "black" },          .flags = FLAGS },
+    { "box",         NULL,                   OFFSET(draw_box),           AV_OPT_TYPE_INT,    { .i64 = 0       }, 0,       1,       FLAGS },
+    { "fontsize",    NULL,                   OFFSET(fontsize),           AV_OPT_TYPE_INT,    { .i64 = 16      }, 1,       72,      FLAGS },
+    { "x",           NULL,                   OFFSET(x_expr),             AV_OPT_TYPE_STRING, { .str = "0"     },          .flags = FLAGS },
+    { "y",           NULL,                   OFFSET(y_expr),             AV_OPT_TYPE_STRING, { .str = "0"     },          .flags = FLAGS },
+    { "shadowx",     NULL,                   OFFSET(shadowx),            AV_OPT_TYPE_INT,    { .i64 = 0       }, INT_MIN, INT_MAX, FLAGS },
+    { "shadowy",     NULL,                   OFFSET(shadowy),            AV_OPT_TYPE_INT,    { .i64 = 0       }, INT_MIN, INT_MAX, FLAGS },
+    { "tabsize",     NULL,                   OFFSET(tabsize),            AV_OPT_TYPE_INT,    { .i64 = 4       }, 0,       INT_MAX, FLAGS },
+    { "draw",        "if false do not draw", OFFSET(d_expr),             AV_OPT_TYPE_STRING, { .str = "1"     },          .flags = 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, FLAGS, "ft_load_flags" },
+        { "default",                     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_DEFAULT },                     .flags = FLAGS, .unit = "ft_load_flags" },
+        { "no_scale",                    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_SCALE },                    .flags = FLAGS, .unit = "ft_load_flags" },
+        { "no_hinting",                  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_HINTING },                  .flags = FLAGS, .unit = "ft_load_flags" },
+        { "render",                      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_RENDER },                      .flags = FLAGS, .unit = "ft_load_flags" },
+        { "no_bitmap",                   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_BITMAP },                   .flags = FLAGS, .unit = "ft_load_flags" },
+        { "vertical_layout",             NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_VERTICAL_LAYOUT },             .flags = FLAGS, .unit = "ft_load_flags" },
+        { "force_autohint",              NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_FORCE_AUTOHINT },              .flags = FLAGS, .unit = "ft_load_flags" },
+        { "crop_bitmap",                 NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_CROP_BITMAP },                 .flags = FLAGS, .unit = "ft_load_flags" },
+        { "pedantic",                    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_PEDANTIC },                    .flags = FLAGS, .unit = "ft_load_flags" },
+        { "ignore_global_advance_width", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH }, .flags = FLAGS, .unit = "ft_load_flags" },
+        { "no_recurse",                  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_RECURSE },                  .flags = FLAGS, .unit = "ft_load_flags" },
+        { "ignore_transform",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_IGNORE_TRANSFORM },            .flags = FLAGS, .unit = "ft_load_flags" },
+        { "monochrome",                  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_MONOCHROME },                  .flags = FLAGS, .unit = "ft_load_flags" },
+        { "linear_design",               NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_LINEAR_DESIGN },               .flags = FLAGS, .unit = "ft_load_flags" },
+        { "no_autohint",                 NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FT_LOAD_NO_AUTOHINT },                 .flags = FLAGS, .unit = "ft_load_flags" },
+    { NULL},
 };
 
 static const char *drawtext_get_name(void *ctx)
@@ -230,13 +231,13 @@ static int glyph_cmp(void *key, const void *b)
  */
 static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     Glyph *glyph;
     struct AVTreeNode *node = NULL;
     int ret;
 
-    /* load glyph into dtext->face->glyph */
-    if (FT_Load_Char(dtext->face, code, dtext->ft_load_flags))
+    /* load glyph into s->face->glyph */
+    if (FT_Load_Char(s->face, code, s->ft_load_flags))
         return AVERROR(EINVAL);
 
     /* save glyph */
@@ -247,15 +248,15 @@ static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code)
     }
     glyph->code  = code;
 
-    if (FT_Get_Glyph(dtext->face->glyph, glyph->glyph)) {
+    if (FT_Get_Glyph(s->face->glyph, glyph->glyph)) {
         ret = AVERROR(EINVAL);
         goto error;
     }
 
-    glyph->bitmap      = dtext->face->glyph->bitmap;
-    glyph->bitmap_left = dtext->face->glyph->bitmap_left;
-    glyph->bitmap_top  = dtext->face->glyph->bitmap_top;
-    glyph->advance     = dtext->face->glyph->advance.x >> 6;
+    glyph->bitmap      = s->face->glyph->bitmap;
+    glyph->bitmap_left = s->face->glyph->bitmap_left;
+    glyph->bitmap_top  = s->face->glyph->bitmap_top;
+    glyph->advance     = s->face->glyph->advance.x >> 6;
 
     /* measure text height to calculate text_height (or the maximum text height) */
     FT_Glyph_Get_CBox(*glyph->glyph, ft_glyph_bbox_pixels, &glyph->bbox);
@@ -265,7 +266,7 @@ static int load_glyph(AVFilterContext *ctx, Glyph **glyph_ptr, uint32_t code)
         ret = AVERROR(ENOMEM);
         goto error;
     }
-    av_tree_insert(&dtext->glyphs, glyph, glyph_cmp, &node);
+    av_tree_insert(&s->glyphs, glyph, glyph_cmp, &node);
 
     if (glyph_ptr)
         *glyph_ptr = glyph;
@@ -279,94 +280,83 @@ error:
     return ret;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     int err;
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     Glyph *glyph;
 
-    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);
-        return err;
-    }
-
-    if (!dtext->fontfile) {
+    if (!s->fontfile) {
         av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
         return AVERROR(EINVAL);
     }
 
-    if (dtext->textfile) {
+    if (s->textfile) {
         uint8_t *textbuf;
         size_t textbuf_size;
 
-        if (dtext->text) {
+        if (s->text) {
             av_log(ctx, AV_LOG_ERROR,
                    "Both text and text file provided. Please provide only one\n");
             return AVERROR(EINVAL);
         }
-        if ((err = av_file_map(dtext->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) {
+        if ((err = av_file_map(s->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) {
             av_log(ctx, AV_LOG_ERROR,
                    "The text file '%s' could not be read or is empty\n",
-                   dtext->textfile);
+                   s->textfile);
             return err;
         }
 
-        if (!(dtext->text = av_malloc(textbuf_size+1)))
+        if (!(s->text = av_malloc(textbuf_size+1)))
             return AVERROR(ENOMEM);
-        memcpy(dtext->text, textbuf, textbuf_size);
-        dtext->text[textbuf_size] = 0;
+        memcpy(s->text, textbuf, textbuf_size);
+        s->text[textbuf_size] = 0;
         av_file_unmap(textbuf, textbuf_size);
     }
 
-    if (!dtext->text) {
+    if (!s->text) {
         av_log(ctx, AV_LOG_ERROR,
                "Either text or a valid file 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(s->fontcolor_rgba, s->fontcolor_string, -1, ctx))) {
         av_log(ctx, AV_LOG_ERROR,
-               "Invalid font color '%s'\n", dtext->fontcolor_string);
+               "Invalid font color '%s'\n", s->fontcolor_string);
         return err;
     }
 
-    if ((err = av_parse_color(dtext->boxcolor_rgba, dtext->boxcolor_string, -1, ctx))) {
+    if ((err = av_parse_color(s->boxcolor_rgba, s->boxcolor_string, -1, ctx))) {
         av_log(ctx, AV_LOG_ERROR,
-               "Invalid box color '%s'\n", dtext->boxcolor_string);
+               "Invalid box color '%s'\n", s->boxcolor_string);
         return err;
     }
 
-    if ((err = av_parse_color(dtext->shadowcolor_rgba, dtext->shadowcolor_string, -1, ctx))) {
+    if ((err = av_parse_color(s->shadowcolor_rgba, s->shadowcolor_string, -1, ctx))) {
         av_log(ctx, AV_LOG_ERROR,
-               "Invalid shadow color '%s'\n", dtext->shadowcolor_string);
+               "Invalid shadow color '%s'\n", s->shadowcolor_string);
         return err;
     }
 
-    if ((err = FT_Init_FreeType(&(dtext->library)))) {
+    if ((err = FT_Init_FreeType(&(s->library)))) {
         av_log(ctx, AV_LOG_ERROR,
                "Could not load FreeType: %s\n", FT_ERRMSG(err));
         return AVERROR(EINVAL);
     }
 
     /* 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))) {
+    if ((err = FT_New_Face(s->library, s->fontfile, 0, &s->face))) {
         av_log(ctx, AV_LOG_ERROR, "Could not load fontface from file '%s': %s\n",
-               dtext->fontfile, FT_ERRMSG(err));
+               s->fontfile, FT_ERRMSG(err));
         return AVERROR(EINVAL);
     }
-    if ((err = FT_Set_Pixel_Sizes(dtext->face, 0, dtext->fontsize))) {
+    if ((err = FT_Set_Pixel_Sizes(s->face, 0, s->fontsize))) {
         av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels: %s\n",
-               dtext->fontsize, FT_ERRMSG(err));
+               s->fontsize, FT_ERRMSG(err));
         return AVERROR(EINVAL);
     }
 
-    dtext->use_kerning = FT_HAS_KERNING(dtext->face);
+    s->use_kerning = FT_HAS_KERNING(s->face);
 
     /* load the fallback glyph with code 0 */
     load_glyph(ctx, NULL, 0);
@@ -376,7 +366,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
         av_log(ctx, AV_LOG_ERROR, "Could not set tabsize.\n");
         return err;
     }
-    dtext->tabsize *= glyph->advance;
+    s->tabsize *= glyph->advance;
 
 #if !HAVE_LOCALTIME_R
     av_log(ctx, AV_LOG_WARNING, "strftime() expansion unavailable!\n");
@@ -409,25 +399,24 @@ static int glyph_enu_free(void *opaque, void *elem)
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = 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_freep(&dtext->positions);
-    av_freep(&dtext->shadowcolor_string);
-    av_tree_enumerate(dtext->glyphs, NULL, NULL, glyph_enu_free);
-    av_tree_destroy(dtext->glyphs);
-    dtext->glyphs = 0;
-    FT_Done_Face(dtext->face);
-    FT_Done_FreeType(dtext->library);
+    av_expr_free(s->x_pexpr);
+    av_expr_free(s->y_pexpr);
+    av_expr_free(s->d_pexpr);
+    s->x_pexpr = s->y_pexpr = s->d_pexpr = NULL;
+    av_freep(&s->expanded_text);
+    av_freep(&s->positions);
+    av_tree_enumerate(s->glyphs, NULL, NULL, glyph_enu_free);
+    av_tree_destroy(s->glyphs);
+    s->glyphs = 0;
+    FT_Done_Face(s->face);
+    FT_Done_FreeType(s->library);
 
     for (i = 0; i < 4; i++) {
-        av_freep(&dtext->box_line[i]);
-        dtext->pixel_step[i] = 0;
+        av_freep(&s->box_line[i]);
+        s->pixel_step[i] = 0;
     }
 
 }
@@ -439,11 +428,11 @@ static inline int is_newline(uint32_t c)
 
 static int dtext_prepare_text(AVFilterContext *ctx)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = 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;
+    char *text = s->text;
     uint8_t *p;
     int str_w = 0, len;
     int y_min = 32000, y_max = -32000;
@@ -456,37 +445,37 @@ static int dtext_prepare_text(AVFilterContext *ctx)
 #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;
+    uint8_t *buf = s->expanded_text;
+    int buf_size = s->expanded_text_size;
 
     if (!buf)
-        buf_size = 2*strlen(dtext->text)+1;
+        buf_size = 2*strlen(s->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)
+        if (strftime(buf, buf_size, s->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;
+    text = s->expanded_text = buf;
+    s->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 ((len = strlen(text)) > s->nb_positions) {
+        FT_Vector *p = av_realloc(s->positions,
+                                  len * sizeof(*s->positions));
         if (!p) {
-            av_freep(dtext->positions);
-            dtext->nb_positions = 0;
+            av_freep(s->positions);
+            s->nb_positions = 0;
             return AVERROR(ENOMEM);
         } else {
-            dtext->positions = p;
-            dtext->nb_positions = len;
+            s->positions = p;
+            s->nb_positions = len;
         }
     }
 
@@ -496,7 +485,7 @@ static int dtext_prepare_text(AVFilterContext *ctx)
 
         /* get glyph */
         dummy.code = code;
-        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+        glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL);
         if (!glyph) {
             ret = load_glyph(ctx, &glyph, code);
             if (ret)
@@ -520,7 +509,7 @@ static int dtext_prepare_text(AVFilterContext *ctx)
 
         prev_code = code;
         if (is_newline(code)) {
-            str_w = FFMAX(str_w, x - dtext->x);
+            str_w = FFMAX(str_w, x - s->x);
             y += text_height;
             x = 0;
             continue;
@@ -529,11 +518,11 @@ static int dtext_prepare_text(AVFilterContext *ctx)
         /* get glyph */
         prev_glyph = glyph;
         dummy.code = code;
-        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+        glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL);
 
         /* kerning */
-        if (dtext->use_kerning && prev_glyph && glyph->code) {
-            FT_Get_Kerning(dtext->face, prev_glyph->code, glyph->code,
+        if (s->use_kerning && prev_glyph && glyph->code) {
+            FT_Get_Kerning(s->face, prev_glyph->code, glyph->code,
                            ft_kerning_default, &delta);
             x += delta.x >> 6;
         }
@@ -545,19 +534,19 @@ static int dtext_prepare_text(AVFilterContext *ctx)
         }
 
         /* 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;
+        s->positions[i].x = x + glyph->bitmap_left;
+        s->positions[i].y = y - glyph->bitmap_top + baseline;
+        if (code == '\t') x  = (x / s->tabsize + 1)*s->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;
+    s->w = str_w;
+    s->var_values[VAR_TEXT_W] = s->var_values[VAR_TW] = s->w;
+    s->h = y;
+    s->var_values[VAR_TEXT_H] = s->var_values[VAR_TH] = s->h;
 
     return 0;
 }
@@ -566,58 +555,61 @@ static int dtext_prepare_text(AVFilterContext *ctx)
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx  = inlink->dst;
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = 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;
+    s->hsub = pix_desc->log2_chroma_w;
+    s->vsub = pix_desc->log2_chroma_h;
 
-    dtext->var_values[VAR_E  ] = M_E;
-    dtext->var_values[VAR_PHI] = M_PHI;
-    dtext->var_values[VAR_PI ] = M_PI;
+    s->var_values[VAR_E  ] = M_E;
+    s->var_values[VAR_PHI] = M_PHI;
+    s->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;
+    s->var_values[VAR_MAIN_W] =
+        s->var_values[VAR_MW] = ctx->inputs[0]->w;
+    s->var_values[VAR_MAIN_H] =
+        s->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;
+    s->var_values[VAR_X] = 0;
+    s->var_values[VAR_Y] = 0;
+    s->var_values[VAR_T] = NAN;
 
-    av_lfg_init(&dtext->prng, av_get_random_seed());
+    av_lfg_init(&s->prng, av_get_random_seed());
 
-    if ((ret = av_expr_parse(&dtext->x_pexpr, dtext->x_expr, var_names,
+    av_expr_free(s->x_pexpr);
+    av_expr_free(s->y_pexpr);
+    av_expr_free(s->d_pexpr);
+    s->x_pexpr = s->y_pexpr = s->d_pexpr = NULL;
+    if ((ret = av_expr_parse(&s->x_pexpr, s->x_expr, var_names,
                              NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
-        (ret = av_expr_parse(&dtext->y_pexpr, dtext->y_expr, var_names,
+        (ret = av_expr_parse(&s->y_pexpr, s->y_expr, var_names,
                              NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
-        (ret = av_expr_parse(&dtext->d_pexpr, dtext->d_expr, var_names,
+        (ret = av_expr_parse(&s->d_pexpr, s->d_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)
+         ff_fill_line_with_color(s->box_line, s->pixel_step,
+                                 inlink->w, s->boxcolor,
+                                 inlink->format, s->boxcolor_rgba,
+                                 &s->is_packed_rgb, s->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];
+    if (!s->is_packed_rgb) {
+        uint8_t *rgba = s->fontcolor_rgba;
+        s->fontcolor[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
+        s->fontcolor[1] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
+        s->fontcolor[2] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
+        s->fontcolor[3] = rgba[3];
+        rgba = s->shadowcolor_rgba;
+        s->shadowcolor[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
+        s->shadowcolor[1] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
+        s->shadowcolor[2] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
+        s->shadowcolor[3] = rgba[3];
     }
 
-    dtext->draw = 1;
+    s->draw = 1;
 
     return dtext_prepare_text(ctx);
 }
@@ -627,19 +619,19 @@ static int config_input(AVFilterLink *inlink)
         (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]; \
+#define SET_PIXEL_YUV(frame, yuva_color, val, x, y, hsub, vsub) {           \
+    luma_pos    = ((x)          ) + ((y)          ) * frame->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; \
+    frame->data[0][luma_pos]    = (alpha * yuva_color[0] + (255*255*129 - alpha) * frame->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; \
+        chroma_pos1 = ((x) >> (hsub)) + ((y) >> (vsub)) * frame->linesize[1]; \
+        chroma_pos2 = ((x) >> (hsub)) + ((y) >> (vsub)) * frame->linesize[2]; \
+        frame->data[1][chroma_pos1] = (alpha * yuva_color[1] + (255*255*129 - alpha) * frame->data[1][chroma_pos1]) >> 23; \
+        frame->data[2][chroma_pos2] = (alpha * yuva_color[2] + (255*255*129 - alpha) * frame->data[2][chroma_pos2]) >> 23; \
     }\
 }
 
-static inline int draw_glyph_yuv(AVFilterBufferRef *picref, FT_Bitmap *bitmap, unsigned int x,
+static inline int draw_glyph_yuv(AVFrame *frame, 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)
 {
@@ -654,22 +646,22 @@ static inline int draw_glyph_yuv(AVFilterBufferRef *picref, FT_Bitmap *bitmap, u
             if (!src_val)
                 continue;
 
-            SET_PIXEL_YUV(picref, yuva_color, src_val, c+x, y+r, hsub, vsub);
+            SET_PIXEL_YUV(frame, 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]); \
+#define SET_PIXEL_RGB(frame, rgba_color, val, x, y, pixel_step, r_off, g_off, b_off, a_off) { \
+    p   = frame->data[0] + (x) * pixel_step + ((y) * frame->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,
+static inline int draw_glyph_rgb(AVFrame *frame, 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])
@@ -685,7 +677,7 @@ static inline int draw_glyph_rgb(AVFilterBufferRef *picref, FT_Bitmap *bitmap,
             if (!src_val)
                 continue;
 
-            SET_PIXEL_RGB(picref, rgba_color, src_val, c+x, y+r, pixel_step,
+            SET_PIXEL_RGB(frame, rgba_color, src_val, c+x, y+r, pixel_step,
                           rgba_map[0], rgba_map[1], rgba_map[2], rgba_map[3]);
         }
     }
@@ -693,7 +685,7 @@ static inline int draw_glyph_rgb(AVFilterBufferRef *picref, FT_Bitmap *bitmap,
     return 0;
 }
 
-static inline void drawbox(AVFilterBufferRef *picref, unsigned int x, unsigned int y,
+static inline void drawbox(AVFrame *frame, 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])
@@ -705,25 +697,25 @@ static inline void drawbox(AVFilterBufferRef *picref, unsigned int x, unsigned i
             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],
+                    SET_PIXEL_RGB(frame, 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);
+                    SET_PIXEL_YUV(frame, color, 255, i+x, y+j, hsub, vsub);
         }
     } else {
-        ff_draw_rectangle(picref->data, picref->linesize,
+        ff_draw_rectangle(frame->data, frame->linesize,
                           line, pixel_step, hsub, vsub,
                           x, y, width, height);
     }
 }
 
-static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
+static int draw_glyphs(DrawTextContext *s, AVFrame *frame,
                        int width, int height, const uint8_t rgbcolor[4], const uint8_t yuvcolor[4], int x, int y)
 {
-    char *text = HAVE_LOCALTIME_R ? dtext->expanded_text : dtext->text;
+    char *text = HAVE_LOCALTIME_R ? s->expanded_text : s->text;
     uint32_t code = 0;
     int i;
     uint8_t *p;
@@ -738,53 +730,53 @@ static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
             continue;
 
         dummy.code = code;
-        glyph = av_tree_find(dtext->glyphs, &dummy, (void *)glyph_cmp, NULL);
+        glyph = av_tree_find(s->glyphs, &dummy, (void *)glyph_cmp, NULL);
 
         if (glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO &&
             glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
             return AVERROR(EINVAL);
 
-        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);
+        if (s->is_packed_rgb) {
+            draw_glyph_rgb(frame, &glyph->bitmap,
+                           s->positions[i].x+x, s->positions[i].y+y, width, height,
+                           s->pixel_step[0], rgbcolor, s->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);
+            draw_glyph_yuv(frame, &glyph->bitmap,
+                           s->positions[i].x+x, s->positions[i].y+y, width, height,
+                           yuvcolor, s->hsub, s->vsub);
         }
     }
 
     return 0;
 }
 
-static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref,
+static int draw_text(AVFilterContext *ctx, AVFrame *frame,
                      int width, int height)
 {
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     int ret;
 
     /* 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);
-
-    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 (s->draw_box)
+        drawbox(frame, s->x, s->y, s->w, s->h,
+                s->box_line, s->pixel_step, s->boxcolor,
+                s->hsub, s->vsub, s->is_packed_rgb,
+                s->rgba_map);
+
+    if (s->shadowx || s->shadowy) {
+        if ((ret = draw_glyphs(s, frame, width, height,
+                               s->shadowcolor_rgba,
+                               s->shadowcolor,
+                               s->x + s->shadowx,
+                               s->y + s->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(s, frame, width, height,
+                           s->fontcolor_rgba,
+                           s->fontcolor,
+                           s->x,
+                           s->y)) < 0)
         return ret;
 
     return 0;
@@ -805,52 +797,52 @@ static inline int normalize_double(int *n, double d)
     return ret;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
-    DrawTextContext *dtext = ctx->priv;
+    DrawTextContext *s = ctx->priv;
     int ret = 0;
 
     if ((ret = dtext_prepare_text(ctx)) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Can't draw text\n");
-        avfilter_unref_bufferp(&frame);
+        av_frame_free(&frame);
         return ret;
     }
 
-    dtext->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
+    s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
         NAN : frame->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;
+    s->var_values[VAR_X] =
+        av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
+    s->var_values[VAR_Y] =
+        av_expr_eval(s->y_pexpr, s->var_values, &s->prng);
+    s->var_values[VAR_X] =
+        av_expr_eval(s->x_pexpr, s->var_values, &s->prng);
+
+    s->draw = av_expr_eval(s->d_pexpr, s->var_values, &s->prng);
+
+    normalize_double(&s->x, s->var_values[VAR_X]);
+    normalize_double(&s->y, s->var_values[VAR_Y]);
+
+    if (s->fix_bounds) {
+        if (s->x < 0) s->x = 0;
+        if (s->y < 0) s->y = 0;
+        if ((unsigned)s->x + (unsigned)s->w > inlink->w)
+            s->x = inlink->w - s->w;
+        if ((unsigned)s->y + (unsigned)s->h > inlink->h)
+            s->y = inlink->h - s->h;
     }
 
-    dtext->x &= ~((1 << dtext->hsub) - 1);
-    dtext->y &= ~((1 << dtext->vsub) - 1);
+    s->x &= ~((1 << s->hsub) - 1);
+    s->y &= ~((1 << s->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);
+            (int)s->var_values[VAR_N], s->var_values[VAR_T],
+            s->x, s->y, s->x+s->w, s->y+s->h);
 
-    if (dtext->draw)
-        draw_text(inlink->dst, frame, frame->video->w, frame->video->h);
+    if (s->draw)
+        draw_text(inlink->dst, frame, frame->width, frame->height);
 
-    dtext->var_values[VAR_N] += 1.0;
+    s->var_values[VAR_N] += 1.0;
 
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
@@ -862,9 +854,7 @@ static const AVFilterPad avfilter_vf_drawtext_inputs[] = {
         .get_video_buffer = ff_null_get_video_buffer,
         .filter_frame     = filter_frame,
         .config_props     = config_input,
-        .min_perms        = AV_PERM_WRITE |
-                            AV_PERM_READ,
-        .rej_perms = AV_PERM_PRESERVE
+        .needs_writable   = 1,
     },
     { NULL }
 };
@@ -877,10 +867,11 @@ static const AVFilterPad avfilter_vf_drawtext_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_drawtext = {
+AVFilter ff_vf_drawtext = {
     .name          = "drawtext",
     .description   = NULL_IF_CONFIG_SMALL("Draw text on top of video frames using libfreetype library."),
     .priv_size     = sizeof(DrawTextContext),
+    .priv_class    = &drawtext_class,
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
index f609db1..b6bd775 100644
--- a/libavfilter/vf_fade.c
+++ b/libavfilter/vf_fade.c
@@ -26,48 +26,42 @@
  */
 
 #include "libavutil/common.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
+#define FADE_IN  0
+#define FADE_OUT 1
+
 typedef struct {
+    const AVClass *class;
+    int type;
     int factor, fade_per_frame;
-    unsigned int frame_index, start_frame, stop_frame;
+    int start_frame, nb_frames;
+    unsigned int frame_index, stop_frame;
     int hsub, vsub, bpp;
 } FadeContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    FadeContext *fade = ctx->priv;
-    unsigned int nb_frames;
-    char in_out[4];
-
-    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);
-    }
-
-    nb_frames = nb_frames ? nb_frames : 1;
-    fade->fade_per_frame = (1 << 16) / nb_frames;
-    if (!strcmp(in_out, "in"))
-        fade->factor = 0;
-    else if (!strcmp(in_out, "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);
+    FadeContext *s = ctx->priv;
+
+    s->fade_per_frame = (1 << 16) / s->nb_frames;
+    if (s->type == FADE_IN) {
+        s->factor = 0;
+    } else if (s->type == FADE_OUT) {
+        s->fade_per_frame = -s->fade_per_frame;
+        s->factor = (1 << 16);
     }
-    fade->stop_frame = fade->start_frame + nb_frames;
+    s->stop_frame = s->start_frame + s->nb_frames;
 
     av_log(ctx, AV_LOG_VERBOSE,
            "type:%s start_frame:%d nb_frames:%d\n",
-           in_out, fade->start_frame, nb_frames);
+           s->type == FADE_IN ? "in" : "out", s->start_frame,
+           s->nb_frames);
     return 0;
 }
 
@@ -88,61 +82,112 @@ static int query_formats(AVFilterContext *ctx)
 
 static int config_props(AVFilterLink *inlink)
 {
-    FadeContext *fade = inlink->dst->priv;
+    FadeContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(inlink->format);
 
-    fade->hsub = pixdesc->log2_chroma_w;
-    fade->vsub = pixdesc->log2_chroma_h;
+    s->hsub = pixdesc->log2_chroma_w;
+    s->vsub = pixdesc->log2_chroma_h;
+
+    s->bpp = av_get_bits_per_pixel(pixdesc) >> 3;
+    return 0;
+}
+
+static int filter_slice_luma(AVFilterContext *ctx, void *arg, int jobnr,
+                             int nb_jobs)
+{
+    FadeContext *s = ctx->priv;
+    AVFrame *frame = arg;
+    int slice_h     = frame->height / nb_jobs;
+    int slice_start = jobnr * slice_h;
+    int slice_end   = (jobnr == nb_jobs - 1) ? frame->height : (jobnr + 1) * slice_h;
+    int i, j;
+
+    for (i = slice_start; i < slice_end; i++) {
+        uint8_t *p = frame->data[0] + i * frame->linesize[0];
+        for (j = 0; j < frame->width * s->bpp; j++) {
+            /* s->factor is using 16 lower-order bits for decimal
+             * places. 32768 = 1 << 15, it is an integer representation
+             * of 0.5 and is for rounding. */
+            *p = (*p * s->factor + 32768) >> 16;
+            p++;
+        }
+    }
 
-    fade->bpp = av_get_bits_per_pixel(pixdesc) >> 3;
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_slice_chroma(AVFilterContext *ctx, void *arg, int jobnr,
+                               int nb_jobs)
 {
-    FadeContext *fade = inlink->dst->priv;
-    uint8_t *p;
+    FadeContext *s = ctx->priv;
+    AVFrame *frame = arg;
+    int slice_h     = FFALIGN(frame->height / nb_jobs, 1 << s->vsub);
+    int slice_start = jobnr * slice_h;
+    int slice_end   = (jobnr == nb_jobs - 1) ? frame->height : (jobnr + 1) * slice_h;
     int i, j, plane;
 
-    if (fade->factor < UINT16_MAX) {
-        /* luma or rgb plane */
-        for (i = 0; i < frame->video->h; i++) {
-            p = frame->data[0] + i * frame->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;
+    for (plane = 1; plane < 3; plane++) {
+        for (i = slice_start; i < slice_end; i++) {
+            uint8_t *p = frame->data[plane] + (i >> s->vsub) * frame->linesize[plane];
+            for (j = 0; j < frame->width >> s->hsub; j++) {
+                /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
+                 * representation of 128.5. The .5 is for rounding
+                 * purposes. */
+                *p = ((*p - 128) * s->factor + 8421367) >> 16;
                 p++;
             }
         }
+    }
+
+    return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *ctx = inlink->dst;
+    FadeContext *s       = ctx->priv;
+
+    if (s->factor < UINT16_MAX) {
+        /* luma or rgb plane */
+        ctx->internal->execute(ctx, filter_slice_luma, frame, NULL,
+                               FFMIN(frame->height, ctx->graph->nb_threads));
 
         if (frame->data[1] && frame->data[2]) {
             /* chroma planes */
-            for (plane = 1; plane < 3; plane++) {
-                for (i = 0; i < frame->video->h; i++) {
-                    p = frame->data[plane] + (i >> fade->vsub) * frame->linesize[plane];
-                    for (j = 0; j < inlink->w >> fade->hsub; j++) {
-                        /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
-                         * representation of 128.5. The .5 is for rounding
-                         * purposes. */
-                        *p = ((*p - 128) * fade->factor + 8421367) >> 16;
-                        p++;
-                    }
-                }
-            }
+            ctx->internal->execute(ctx, filter_slice_chroma, frame, NULL,
+                                   FFMIN(frame->height, ctx->graph->nb_threads));
         }
     }
 
-    if (fade->frame_index >= fade->start_frame &&
-        fade->frame_index <= fade->stop_frame)
-        fade->factor += fade->fade_per_frame;
-    fade->factor = av_clip_uint16(fade->factor);
-    fade->frame_index++;
+    if (s->frame_index >= s->start_frame &&
+        s->frame_index <= s->stop_frame)
+        s->factor += s->fade_per_frame;
+    s->factor = av_clip_uint16(s->factor);
+    s->frame_index++;
 
     return ff_filter_frame(inlink->dst->outputs[0], frame);
 }
 
+#define OFFSET(x) offsetof(FadeContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "type", "'in' or 'out' for fade-in/fade-out", OFFSET(type), AV_OPT_TYPE_INT, { .i64 = FADE_IN }, FADE_IN, FADE_OUT, FLAGS, "type" },
+        { "in",  "fade-in",  0, AV_OPT_TYPE_CONST, { .i64 = FADE_IN },  .unit = "type" },
+        { "out", "fade-out", 0, AV_OPT_TYPE_CONST, { .i64 = FADE_OUT }, .unit = "type" },
+    { "start_frame", "Number of the first frame to which to apply the effect.",
+                                                    OFFSET(start_frame), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
+    { "nb_frames",   "Number of frames to which the effect should be applied.",
+                                                    OFFSET(nb_frames),   AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, FLAGS },
+    { NULL },
+};
+
+static const AVClass fade_class = {
+    .class_name = "fade",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_fade_inputs[] = {
     {
         .name             = "default",
@@ -150,8 +195,7 @@ static const AVFilterPad avfilter_vf_fade_inputs[] = {
         .config_props     = config_props,
         .get_video_buffer = ff_null_get_video_buffer,
         .filter_frame     = filter_frame,
-        .min_perms        = AV_PERM_READ | AV_PERM_WRITE,
-        .rej_perms        = AV_PERM_PRESERVE,
+        .needs_writable   = 1,
     },
     { NULL }
 };
@@ -164,13 +208,15 @@ static const AVFilterPad avfilter_vf_fade_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_fade = {
+AVFilter ff_vf_fade = {
     .name          = "fade",
     .description   = NULL_IF_CONFIG_SMALL("Fade in/out input video"),
     .init          = init,
     .priv_size     = sizeof(FadeContext),
+    .priv_class    = &fade_class,
     .query_formats = query_formats,
 
     .inputs    = avfilter_vf_fade_inputs,
     .outputs   = avfilter_vf_fade_outputs,
+    .flags     = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
index 5f0cc3b..5185cf4 100644
--- a/libavfilter/vf_fieldorder.c
+++ b/libavfilter/vf_fieldorder.c
@@ -23,51 +23,24 @@
  * video field order filter, heavily influenced by vf_pad.c
  */
 
-/* #define DEBUG */
-
 #include <stdio.h>
 #include <string.h>
 
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
-typedef struct
-{
-    unsigned int dst_tff;      ///< output bff/tff
+typedef struct {
+    const AVClass *class;
+    int dst_tff;               ///< output bff/tff
     int          line_size[4]; ///< bytes of pixel data per line for each plane
 } FieldOrderContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    FieldOrderContext *fieldorder = ctx->priv;
-
-    const char *tff = "tff";
-    const char *bff = "bff";
-
-    if (!args) {
-        fieldorder->dst_tff = 1;
-    } else if (sscanf(args, "%u", &fieldorder->dst_tff) == 1) {
-        fieldorder->dst_tff = !!fieldorder->dst_tff;
-    } else if (!strcmp(tff, args)) {
-        fieldorder->dst_tff = 1;
-    } else if (!strcmp(bff, args)) {
-        fieldorder->dst_tff = 0;
-    } else {
-        av_log(ctx, AV_LOG_ERROR, "Invalid argument '%s'.\n", args);
-        return AVERROR(EINVAL);
-    }
-
-    av_log(ctx, AV_LOG_VERBOSE, "output field order: %s\n",
-            fieldorder->dst_tff ? tff : bff);
-
-    return 0;
-}
-
 static int query_formats(AVFilterContext *ctx)
 {
     AVFilterFormats  *formats;
@@ -80,8 +53,8 @@ static int query_formats(AVFilterContext *ctx)
         formats = NULL;
         for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++) {
             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-            if (!(desc->flags & PIX_FMT_HWACCEL ||
-                  desc->flags & PIX_FMT_BITSTREAM) &&
+            if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL ||
+                  desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) &&
                 desc->nb_components && !desc->log2_chroma_h &&
                 (ret = ff_add_format(&formats, pix_fmt)) < 0) {
                 ff_formats_unref(&formats);
@@ -97,31 +70,21 @@ static int query_formats(AVFilterContext *ctx)
 
 static int config_input(AVFilterLink *inlink)
 {
-    AVFilterContext   *ctx        = inlink->dst;
-    FieldOrderContext *fieldorder = ctx->priv;
+    AVFilterContext   *ctx = inlink->dst;
+    FieldOrderContext *s   = ctx->priv;
     int               plane;
 
     /** full an array with the number of bytes that the video
      *  data occupies per line for each plane of the input video */
     for (plane = 0; plane < 4; plane++) {
-        fieldorder->line_size[plane] = av_image_get_linesize(
-                inlink->format,
-                inlink->w,
-                plane);
+        s->line_size[plane] = av_image_get_linesize(inlink->format, inlink->w,
+                                                    plane);
     }
 
     return 0;
 }
 
-static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
-{
-    AVFilterContext   *ctx        = inlink->dst;
-    AVFilterLink      *outlink    = ctx->outputs[0];
-
-    return ff_get_video_buffer(outlink, perms, w, h);
-}
-
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext   *ctx     = inlink->dst;
     FieldOrderContext *s       = ctx->priv;
@@ -129,14 +92,19 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
     int h, plane, line_step, line_size, line;
     uint8_t *data;
 
-    if (!frame->video->interlaced ||
-        frame->video->top_field_first == s->dst_tff)
+    if (!frame->interlaced_frame ||
+        frame->top_field_first == s->dst_tff) {
+        av_log(ctx, AV_LOG_VERBOSE,
+               "Skipping %s.\n",
+               frame->interlaced_frame ?
+               "frame with same field order" : "progressive frame");
         return ff_filter_frame(outlink, frame);
+    }
 
     av_dlog(ctx,
             "picture will move %s one line\n",
             s->dst_tff ? "up" : "down");
-    h = frame->video->h;
+    h = frame->height;
     for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
         line_step = frame->linesize[plane];
         line_size = s->line_size[plane];
@@ -148,7 +116,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
              *  The new last line is created as a copy of the
              *  penultimate line from that field. */
             for (line = 0; line < h; line++) {
-                if (1 + line < frame->video->h) {
+                if (1 + line < frame->height) {
                     memcpy(data, data + line_step, line_size);
                 } else {
                     memcpy(data, data - line_step - line_step, line_size);
@@ -172,20 +140,34 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
             }
         }
     }
-    frame->video->top_field_first = s->dst_tff;
+    frame->top_field_first = s->dst_tff;
 
     return ff_filter_frame(outlink, frame);
 }
 
+#define OFFSET(x) offsetof(FieldOrderContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "order", "output field order", OFFSET(dst_tff), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS, "order" },
+        { "bff", "bottom field first", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .unit = "order" },
+        { "tff", "top field first",    0, AV_OPT_TYPE_CONST, { .i64 = 1 }, .unit = "order" },
+    { NULL },
+};
+
+static const AVClass fieldorder_class = {
+    .class_name = "fieldorder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_fieldorder_inputs[] = {
     {
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .config_props     = config_input,
-        .get_video_buffer = get_video_buffer,
         .filter_frame     = filter_frame,
-        .min_perms        = AV_PERM_READ | AV_PERM_WRITE,
-        .rej_perms        = AV_PERM_REUSE2 | AV_PERM_PRESERVE,
+        .needs_writable   = 1,
     },
     { NULL }
 };
@@ -198,11 +180,11 @@ static const AVFilterPad avfilter_vf_fieldorder_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_fieldorder = {
+AVFilter ff_vf_fieldorder = {
     .name          = "fieldorder",
     .description   = NULL_IF_CONFIG_SMALL("Set the field order."),
-    .init          = init,
     .priv_size     = sizeof(FieldOrderContext),
+    .priv_class    = &fieldorder_class,
     .query_formats = query_formats,
     .inputs        = avfilter_vf_fieldorder_inputs,
     .outputs       = avfilter_vf_fieldorder_outputs,
diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c
index 7e4a26e..22628d7 100644
--- a/libavfilter/vf_format.c
+++ b/libavfilter/vf_format.c
@@ -28,12 +28,16 @@
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/opt.h"
+
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
 typedef struct {
+    const AVClass *class;
+    char *pix_fmts;
     /**
      * List of flags telling if a given image format has been listed
      * as argument to the filter.
@@ -43,17 +47,17 @@ typedef struct {
 
 #define AV_PIX_FMT_NAME_MAXSIZE 32
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    FormatContext *format = ctx->priv;
+    FormatContext *s = ctx->priv;
     const char *cur, *sep;
     char             pix_fmt_name[AV_PIX_FMT_NAME_MAXSIZE];
     int              pix_fmt_name_len;
     enum AVPixelFormat pix_fmt;
 
     /* parse the list of formats */
-    for (cur = args; cur; cur = sep ? sep+1 : NULL) {
-        if (!(sep = strchr(cur, ':')))
+    for (cur = s->pix_fmts; cur; cur = sep ? sep + 1 : NULL) {
+        if (!(sep = strchr(cur, '|')))
             pix_fmt_name_len = strlen(cur);
         else
             pix_fmt_name_len = sep - cur;
@@ -71,27 +75,35 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
             return -1;
         }
 
-        format->listed_pix_fmt_flags[pix_fmt] = 1;
+        s->listed_pix_fmt_flags[pix_fmt] = 1;
     }
 
     return 0;
 }
 
-static AVFilterFormats *make_format_list(FormatContext *format, int flag)
+static AVFilterFormats *make_format_list(FormatContext *s, int flag)
 {
-    AVFilterFormats *formats;
+    AVFilterFormats *formats = NULL;
     enum AVPixelFormat pix_fmt;
 
-    formats = av_mallocz(sizeof(AVFilterFormats));
-    formats->formats = av_malloc(sizeof(enum AVPixelFormat) * AV_PIX_FMT_NB);
-
     for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++)
-        if (format->listed_pix_fmt_flags[pix_fmt] == flag)
-            formats->formats[formats->format_count++] = pix_fmt;
+        if (s->listed_pix_fmt_flags[pix_fmt] == flag) {
+            int ret = ff_add_format(&formats, pix_fmt);
+            if (ret < 0) {
+                ff_formats_unref(&formats);
+                return NULL;
+            }
+        }
 
     return formats;
 }
 
+#define OFFSET(x) offsetof(FormatContext, x)
+static const AVOption options[] = {
+    { "pix_fmts", "A '|'-separated list of pixel formats", OFFSET(pix_fmts), AV_OPT_TYPE_STRING, .flags = AV_OPT_FLAG_VIDEO_PARAM },
+    { NULL },
+};
+
 #if CONFIG_FORMAT_FILTER
 static int query_formats_format(AVFilterContext *ctx)
 {
@@ -99,6 +111,13 @@ static int query_formats_format(AVFilterContext *ctx)
     return 0;
 }
 
+static const AVClass format_class = {
+    .class_name = "format",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_format_inputs[] = {
     {
         .name             = "default",
@@ -116,7 +135,7 @@ static const AVFilterPad avfilter_vf_format_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_format = {
+AVFilter ff_vf_format = {
     .name      = "format",
     .description = NULL_IF_CONFIG_SMALL("Convert the input video to one of the specified pixel formats."),
 
@@ -125,6 +144,7 @@ AVFilter avfilter_vf_format = {
     .query_formats = query_formats_format,
 
     .priv_size = sizeof(FormatContext),
+    .priv_class = &format_class,
 
     .inputs    = avfilter_vf_format_inputs,
     .outputs   = avfilter_vf_format_outputs,
@@ -138,6 +158,13 @@ static int query_formats_noformat(AVFilterContext *ctx)
     return 0;
 }
 
+static const AVClass noformat_class = {
+    .class_name = "noformat",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_noformat_inputs[] = {
     {
         .name             = "default",
@@ -155,7 +182,7 @@ static const AVFilterPad avfilter_vf_noformat_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_noformat = {
+AVFilter ff_vf_noformat = {
     .name      = "noformat",
     .description = NULL_IF_CONFIG_SMALL("Force libavfilter not to use any of the specified pixel formats for the input to the next filter."),
 
@@ -164,6 +191,7 @@ AVFilter avfilter_vf_noformat = {
     .query_formats = query_formats_noformat,
 
     .priv_size = sizeof(FormatContext),
+    .priv_class = &noformat_class,
 
     .inputs    = avfilter_vf_noformat_inputs,
     .outputs   = avfilter_vf_noformat_outputs,
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index dc20114..5f62ffd 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -21,6 +21,9 @@
  * a filter enforcing given constant framerate
  */
 
+#include <float.h>
+#include <stdint.h>
+
 #include "libavutil/common.h"
 #include "libavutil/fifo.h"
 #include "libavutil/mathematics.h"
@@ -40,6 +43,8 @@ typedef struct FPSContext {
     int64_t first_pts;      ///< pts of the first frame that arrived on this filter
     int64_t pts;            ///< pts of the first frame currently in the fifo
 
+    double start_time;      ///< pts, in seconds, of the expected first frame
+
     AVRational framerate;   ///< target framerate
     char *fps;              ///< a string describing target framerate
 
@@ -54,6 +59,7 @@ typedef struct FPSContext {
 #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 },
+    { "start_time", "Assume the first PTS should be this value.", OFFSET(start_time), AV_OPT_TYPE_DOUBLE, { .dbl = DBL_MAX}, -DBL_MAX, DBL_MAX, V },
     { NULL },
 };
 
@@ -64,29 +70,22 @@ static const AVClass class = {
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     FPSContext *s = ctx->priv;
     int ret;
 
-    s->class = &class;
-    av_opt_set_defaults(s);
-
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing the options string %s.\n",
-               args);
-        return ret;
-    }
-
     if ((ret = av_parse_video_rate(&s->framerate, s->fps)) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Error parsing framerate %s.\n", s->fps);
         return ret;
     }
-    av_opt_free(s);
 
-    if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFilterBufferRef*))))
+    if (!(s->fifo = av_fifo_alloc(2*sizeof(AVFrame*))))
         return AVERROR(ENOMEM);
 
+    s->pts          = AV_NOPTS_VALUE;
+    s->first_pts    = AV_NOPTS_VALUE;
+
     av_log(ctx, AV_LOG_VERBOSE, "fps=%d/%d\n", s->framerate.num, s->framerate.den);
     return 0;
 }
@@ -94,9 +93,9 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
 static void flush_fifo(AVFifoBuffer *fifo)
 {
     while (av_fifo_size(fifo)) {
-        AVFilterBufferRef *tmp;
+        AVFrame *tmp;
         av_fifo_generic_read(fifo, &tmp, sizeof(tmp), NULL);
-        avfilter_unref_buffer(tmp);
+        av_frame_free(&tmp);
     }
 }
 
@@ -104,6 +103,7 @@ static av_cold void uninit(AVFilterContext *ctx)
 {
     FPSContext *s = ctx->priv;
     if (s->fifo) {
+        s->drop += av_fifo_size(s->fifo) / sizeof(AVFilterBufferRef*);
         flush_fifo(s->fifo);
         av_fifo_free(s->fifo);
     }
@@ -119,7 +119,6 @@ static int config_props(AVFilterLink* link)
     link->time_base = (AVRational){ s->framerate.den, s->framerate.num };
     link->w         = link->src->inputs[0]->w;
     link->h         = link->src->inputs[0]->h;
-    s->pts          = AV_NOPTS_VALUE;
 
     return 0;
 }
@@ -138,7 +137,7 @@ static int request_frame(AVFilterLink *outlink)
     if (ret == AVERROR_EOF && av_fifo_size(s->fifo)) {
         int i;
         for (i = 0; av_fifo_size(s->fifo); i++) {
-            AVFilterBufferRef *buf;
+            AVFrame *buf;
 
             av_fifo_generic_read(s->fifo, &buf, sizeof(buf), NULL);
             buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base,
@@ -155,13 +154,13 @@ static int request_frame(AVFilterLink *outlink)
     return ret;
 }
 
-static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf)
+static int write_to_fifo(AVFifoBuffer *fifo, AVFrame *buf)
 {
     int ret;
 
     if (!av_fifo_space(fifo) &&
         (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) {
-        avfilter_unref_bufferp(&buf);
+        av_frame_free(&buf);
         return ret;
     }
 
@@ -169,7 +168,7 @@ static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf)
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
 {
     AVFilterContext    *ctx = inlink->dst;
     FPSContext           *s = ctx->priv;
@@ -185,11 +184,21 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
             if (ret < 0)
                 return ret;
 
-            s->first_pts = s->pts = buf->pts;
+            if (s->start_time != DBL_MAX) {
+                double first_pts = s->start_time * AV_TIME_BASE;
+                first_pts = FFMIN(FFMAX(first_pts, INT64_MIN), INT64_MAX);
+                s->first_pts = s->pts = av_rescale_q(first_pts, AV_TIME_BASE_Q,
+                                                     inlink->time_base);
+                av_log(ctx, AV_LOG_VERBOSE, "Set first pts to (in:%"PRId64" out:%"PRId64")\n",
+                       s->first_pts, av_rescale_q(first_pts, AV_TIME_BASE_Q,
+                                                  outlink->time_base));
+            } else {
+                s->first_pts = s->pts = buf->pts;
+            }
         } else {
             av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no "
                    "timestamp.\n");
-            avfilter_unref_buffer(buf);
+            av_frame_free(&buf);
             s->drop++;
         }
         return 0;
@@ -206,8 +215,8 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
 
     if (delta < 1) {
         /* drop the frame and everything buffered except the first */
-        AVFilterBufferRef *tmp;
-        int drop = av_fifo_size(s->fifo)/sizeof(AVFilterBufferRef*);
+        AVFrame *tmp;
+        int drop = av_fifo_size(s->fifo)/sizeof(AVFrame*);
 
         av_log(ctx, AV_LOG_DEBUG, "Dropping %d frame(s).\n", drop);
         s->drop += drop;
@@ -216,18 +225,18 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
         flush_fifo(s->fifo);
         ret = write_to_fifo(s->fifo, tmp);
 
-        avfilter_unref_buffer(buf);
+        av_frame_free(&buf);
         return ret;
     }
 
     /* can output >= 1 frames */
     for (i = 0; i < delta; i++) {
-        AVFilterBufferRef *buf_out;
+        AVFrame *buf_out;
         av_fifo_generic_read(s->fifo, &buf_out, sizeof(buf_out), NULL);
 
         /* duplicate the frame if needed */
         if (!av_fifo_size(s->fifo) && i < delta - 1) {
-            AVFilterBufferRef *dup = avfilter_ref_buffer(buf_out, AV_PERM_READ);
+            AVFrame *dup = av_frame_clone(buf_out);
 
             av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n");
             if (dup)
@@ -236,8 +245,8 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
                 ret = AVERROR(ENOMEM);
 
             if (ret < 0) {
-                avfilter_unref_bufferp(&buf_out);
-                avfilter_unref_bufferp(&buf);
+                av_frame_free(&buf_out);
+                av_frame_free(&buf);
                 return ret;
             }
 
@@ -248,7 +257,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
                                     outlink->time_base) + s->frames_out;
 
         if ((ret = ff_filter_frame(outlink, buf_out)) < 0) {
-            avfilter_unref_bufferp(&buf);
+            av_frame_free(&buf);
             return ret;
         }
 
@@ -281,7 +290,7 @@ static const AVFilterPad avfilter_vf_fps_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_fps = {
+AVFilter ff_vf_fps = {
     .name        = "fps",
     .description = NULL_IF_CONFIG_SMALL("Force constant framerate"),
 
@@ -289,6 +298,7 @@ AVFilter avfilter_vf_fps = {
     .uninit    = uninit,
 
     .priv_size = sizeof(FPSContext),
+    .priv_class = &class,
 
     .inputs    = avfilter_vf_fps_inputs,
     .outputs   = avfilter_vf_fps_outputs,
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 955d0b9..0d0866a 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -22,8 +22,6 @@
  * frei0r wrapper
  */
 
-/* #define DEBUG */
-
 #include <dlfcn.h>
 #include <frei0r.h>
 #include <stdio.h>
@@ -35,6 +33,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/mem.h"
+#include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "avfilter.h"
 #include "formats.h"
@@ -53,6 +52,7 @@ typedef void (*f0r_set_param_value_f)(f0r_instance_t instance, f0r_param_t param
 typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index);
 
 typedef struct Frei0rContext {
+    const AVClass *class;
     f0r_update_f update;
     void *dl_handle;            /* dynamic library handle   */
     f0r_instance_t instance;
@@ -64,7 +64,11 @@ typedef struct Frei0rContext {
     f0r_construct_f       construct;
     f0r_destruct_f        destruct;
     f0r_deinit_f          deinit;
-    char params[256];
+
+    char *dl_name;
+    char *params;
+    char *size;
+    char *framerate;
 
     /* only used by the source */
     int w, h;
@@ -74,8 +78,8 @@ typedef struct Frei0rContext {
 
 static void *load_sym(AVFilterContext *ctx, const char *sym_name)
 {
-    Frei0rContext *frei0r = ctx->priv;
-    void *sym = dlsym(frei0r->dl_handle, sym_name);
+    Frei0rContext *s = ctx->priv;
+    void *sym = dlsym(s->dl_handle, sym_name);
     if (!sym)
         av_log(ctx, AV_LOG_ERROR, "Could not find symbol '%s' in loaded module\n", sym_name);
     return sym;
@@ -83,7 +87,7 @@ static void *load_sym(AVFilterContext *ctx, const char *sym_name)
 
 static int set_param(AVFilterContext *ctx, f0r_param_info_t info, int index, char *param)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
     union {
         double d;
         f0r_param_color_t col;
@@ -121,7 +125,7 @@ static int set_param(AVFilterContext *ctx, f0r_param_info_t info, int index, cha
         break;
     }
 
-    frei0r->set_param_value(frei0r->instance, &val, index);
+    s->set_param_value(s->instance, &val, index);
     return 0;
 
 fail:
@@ -132,18 +136,18 @@ fail:
 
 static int set_params(AVFilterContext *ctx, const char *params)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
     int i;
 
-    for (i = 0; i < frei0r->plugin_info.num_params; i++) {
+    for (i = 0; i < s->plugin_info.num_params; i++) {
         f0r_param_info_t info;
         char *param;
         int ret;
 
-        frei0r->get_param_info(&info, i);
+        s->get_param_info(&info, i);
 
         if (*params) {
-            if (!(param = av_get_token(&params, ":")))
+            if (!(param = av_get_token(&params, "|")))
                 return AVERROR(ENOMEM);
             params++;               /* skip ':' */
             ret = set_param(ctx, info, i, param);
@@ -173,27 +177,27 @@ static int set_params(AVFilterContext *ctx, const char *params)
 
         case F0R_PARAM_BOOL:
             v = &d;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "%s", d >= 0.5 && d <= 1.0 ? "y" : "n");
             break;
         case F0R_PARAM_DOUBLE:
             v = &d;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "%f", d);
             break;
         case F0R_PARAM_COLOR:
             v = &col;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "%f/%f/%f", col.r, col.g, col.b);
             break;
         case F0R_PARAM_POSITION:
             v = &pos;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "%f/%f", pos.x, pos.y);
             break;
         default: /* F0R_PARAM_STRING */
             v = s;
-            frei0r->get_param_value(frei0r->instance, v, i);
+            s->get_param_value(s->instance, v, i);
             av_log(ctx, AV_LOG_DEBUG, "'%s'\n", s);
             break;
         }
@@ -216,43 +220,48 @@ static void *load_path(AVFilterContext *ctx, const char *prefix, const char *nam
 static av_cold int frei0r_init(AVFilterContext *ctx,
                                const char *dl_name, int type)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
     f0r_init_f            f0r_init;
     f0r_get_plugin_info_f f0r_get_plugin_info;
     f0r_plugin_info_t *pi;
     char *path;
 
+    if (!dl_name) {
+        av_log(ctx, AV_LOG_ERROR, "No filter name provided.\n");
+        return AVERROR(EINVAL);
+    }
+
     /* 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)
-            if (frei0r->dl_handle = load_path(ctx, p, dl_name))
+            if (s->dl_handle = load_path(ctx, p, dl_name))
                 break;
         av_free(path);
     }
-    if (!frei0r->dl_handle && (path = getenv("HOME"))) {
+    if (!s->dl_handle && (path = getenv("HOME"))) {
         char prefix[1024];
         snprintf(prefix, sizeof(prefix), "%s/.frei0r-1/lib/", path);
-        frei0r->dl_handle = load_path(ctx, prefix, dl_name);
+        s->dl_handle = load_path(ctx, prefix, dl_name);
     }
-    if (!frei0r->dl_handle)
-        frei0r->dl_handle = load_path(ctx, "/usr/local/lib/frei0r-1/", dl_name);
-    if (!frei0r->dl_handle)
-        frei0r->dl_handle = load_path(ctx, "/usr/lib/frei0r-1/", dl_name);
-    if (!frei0r->dl_handle) {
+    if (!s->dl_handle)
+        s->dl_handle = load_path(ctx, "/usr/local/lib/frei0r-1/", dl_name);
+    if (!s->dl_handle)
+        s->dl_handle = load_path(ctx, "/usr/lib/frei0r-1/", dl_name);
+    if (!s->dl_handle) {
         av_log(ctx, AV_LOG_ERROR, "Could not find module '%s'\n", dl_name);
         return AVERROR(EINVAL);
     }
 
     if (!(f0r_init                = load_sym(ctx, "f0r_init"           )) ||
         !(f0r_get_plugin_info     = load_sym(ctx, "f0r_get_plugin_info")) ||
-        !(frei0r->get_param_info  = load_sym(ctx, "f0r_get_param_info" )) ||
-        !(frei0r->get_param_value = load_sym(ctx, "f0r_get_param_value")) ||
-        !(frei0r->set_param_value = load_sym(ctx, "f0r_set_param_value")) ||
-        !(frei0r->update          = load_sym(ctx, "f0r_update"         )) ||
-        !(frei0r->construct       = load_sym(ctx, "f0r_construct"      )) ||
-        !(frei0r->destruct        = load_sym(ctx, "f0r_destruct"       )) ||
-        !(frei0r->deinit          = load_sym(ctx, "f0r_deinit"         )))
+        !(s->get_param_info  = load_sym(ctx, "f0r_get_param_info" )) ||
+        !(s->get_param_value = load_sym(ctx, "f0r_get_param_value")) ||
+        !(s->set_param_value = load_sym(ctx, "f0r_set_param_value")) ||
+        !(s->update          = load_sym(ctx, "f0r_update"         )) ||
+        !(s->construct       = load_sym(ctx, "f0r_construct"      )) ||
+        !(s->destruct        = load_sym(ctx, "f0r_destruct"       )) ||
+        !(s->deinit          = load_sym(ctx, "f0r_deinit"         )))
         return AVERROR(EINVAL);
 
     if (f0r_init() < 0) {
@@ -260,8 +269,8 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
         return AVERROR(EINVAL);
     }
 
-    f0r_get_plugin_info(&frei0r->plugin_info);
-    pi = &frei0r->plugin_info;
+    f0r_get_plugin_info(&s->plugin_info);
+    pi = &s->plugin_info;
     if (pi->plugin_type != type) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid type '%s' for the plugin\n",
@@ -284,53 +293,48 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
     return 0;
 }
 
-static av_cold int filter_init(AVFilterContext *ctx, const char *args)
+static av_cold int filter_init(AVFilterContext *ctx)
 {
-    Frei0rContext *frei0r = ctx->priv;
-    char dl_name[1024], c;
-    *frei0r->params = 0;
+    Frei0rContext *s = ctx->priv;
 
-    if (args)
-        sscanf(args, "%1023[^:=]%c%255c", dl_name, &c, frei0r->params);
-
-    return frei0r_init(ctx, dl_name, F0R_PLUGIN_TYPE_FILTER);
+    return frei0r_init(ctx, s->dl_name, F0R_PLUGIN_TYPE_FILTER);
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    Frei0rContext *frei0r = ctx->priv;
-
-    if (frei0r->destruct && frei0r->instance)
-        frei0r->destruct(frei0r->instance);
-    if (frei0r->deinit)
-        frei0r->deinit();
-    if (frei0r->dl_handle)
-        dlclose(frei0r->dl_handle);
-
-    memset(frei0r, 0, sizeof(*frei0r));
+    Frei0rContext *s = ctx->priv;
+
+    if (s->destruct && s->instance)
+        s->destruct(s->instance);
+    if (s->deinit)
+        s->deinit();
+    if (s->dl_handle)
+        dlclose(s->dl_handle);
 }
 
 static int config_input_props(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
 
-    if (!(frei0r->instance = frei0r->construct(inlink->w, inlink->h))) {
+    if (s->destruct && s->instance)
+        s->destruct(s->instance);
+    if (!(s->instance = s->construct(inlink->w, inlink->h))) {
         av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance");
         return AVERROR(EINVAL);
     }
 
-    return set_params(ctx, frei0r->params);
+    return set_params(ctx, s->params);
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
     AVFilterFormats *formats = NULL;
 
-    if        (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) {
+    if        (s->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) {
         ff_add_format(&formats, AV_PIX_FMT_BGRA);
-    } else if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) {
+    } else if (s->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) {
         ff_add_format(&formats, AV_PIX_FMT_RGBA);
     } else {                                   /* F0R_COLOR_MODEL_PACKED32 */
         static const enum AVPixelFormat pix_fmts[] = {
@@ -346,35 +350,49 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    Frei0rContext *frei0r = inlink->dst->priv;
+    Frei0rContext *s = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
-    avfilter_copy_buffer_ref_props(out, in);
+    av_frame_copy_props(out, in);
 
-    frei0r->update(frei0r->instance, in->pts * av_q2d(inlink->time_base) * 1000,
+    s->update(s->instance, in->pts * av_q2d(inlink->time_base) * 1000,
                    (const uint32_t *)in->data[0],
                    (uint32_t *)out->data[0]);
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
 
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(Frei0rContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption filter_options[] = {
+    { "filter_name",   NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS },
+    { "filter_params", NULL, OFFSET(params),  AV_OPT_TYPE_STRING, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass filter_class = {
+    .class_name = "frei0r",
+    .item_name  = av_default_item_name,
+    .option     = filter_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_frei0r_inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_props,
         .filter_frame = filter_frame,
-        .min_perms    = AV_PERM_READ
     },
     { NULL }
 };
@@ -387,7 +405,7 @@ static const AVFilterPad avfilter_vf_frei0r_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_frei0r = {
+AVFilter ff_vf_frei0r = {
     .name      = "frei0r",
     .description = NULL_IF_CONFIG_SMALL("Apply a frei0r effect."),
 
@@ -396,79 +414,87 @@ AVFilter avfilter_vf_frei0r = {
     .uninit = uninit,
 
     .priv_size = sizeof(Frei0rContext),
+    .priv_class = &filter_class,
 
     .inputs    = avfilter_vf_frei0r_inputs,
 
     .outputs   = avfilter_vf_frei0r_outputs,
 };
 
-static av_cold int source_init(AVFilterContext *ctx, const char *args)
+static av_cold int source_init(AVFilterContext *ctx)
 {
-    Frei0rContext *frei0r = ctx->priv;
-    char dl_name[1024], c;
-    char frame_size[128] = "";
-    char frame_rate[128] = "";
+    Frei0rContext *s = ctx->priv;
     AVRational frame_rate_q;
 
-    memset(frei0r->params, 0, sizeof(frei0r->params));
-
-    if (args)
-        sscanf(args, "%127[^:]:%127[^:]:%1023[^:=]%c%255c",
-               frame_size, frame_rate, dl_name, &c, frei0r->params);
-
-    if (av_parse_video_size(&frei0r->w, &frei0r->h, frame_size) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", frame_size);
+    if (av_parse_video_size(&s->w, &s->h, s->size) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", s->size);
         return AVERROR(EINVAL);
     }
 
-    if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 ||
+    if (av_parse_video_rate(&frame_rate_q, s->framerate) < 0 ||
         frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frame_rate);
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", s->framerate);
         return AVERROR(EINVAL);
     }
-    frei0r->time_base.num = frame_rate_q.den;
-    frei0r->time_base.den = frame_rate_q.num;
+    s->time_base.num = frame_rate_q.den;
+    s->time_base.den = frame_rate_q.num;
 
-    return frei0r_init(ctx, dl_name, F0R_PLUGIN_TYPE_SOURCE);
+    return frei0r_init(ctx, s->dl_name, F0R_PLUGIN_TYPE_SOURCE);
 }
 
 static int source_config_props(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
-    Frei0rContext *frei0r = ctx->priv;
+    Frei0rContext *s = ctx->priv;
 
-    if (av_image_check_size(frei0r->w, frei0r->h, 0, ctx) < 0)
+    if (av_image_check_size(s->w, s->h, 0, ctx) < 0)
         return AVERROR(EINVAL);
-    outlink->w = frei0r->w;
-    outlink->h = frei0r->h;
-    outlink->time_base = frei0r->time_base;
+    outlink->w = s->w;
+    outlink->h = s->h;
+    outlink->time_base = s->time_base;
 
-    if (!(frei0r->instance = frei0r->construct(outlink->w, outlink->h))) {
+    if (s->destruct && s->instance)
+        s->destruct(s->instance);
+    if (!(s->instance = s->construct(outlink->w, outlink->h))) {
         av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance");
         return AVERROR(EINVAL);
     }
 
-    return set_params(ctx, frei0r->params);
+    return set_params(ctx, s->params);
 }
 
 static int source_request_frame(AVFilterLink *outlink)
 {
-    Frei0rContext *frei0r = outlink->src->priv;
-    AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    Frei0rContext *s = outlink->src->priv;
+    AVFrame *frame = ff_get_video_buffer(outlink, outlink->w, outlink->h);
 
-    if (!picref)
+    if (!frame)
         return AVERROR(ENOMEM);
 
-    picref->video->pixel_aspect = (AVRational) {1, 1};
-    picref->pts = frei0r->pts++;
-    picref->pos = -1;
+    frame->sample_aspect_ratio = (AVRational) {1, 1};
+    frame->pts = s->pts++;
 
-    frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}),
-                   NULL, (uint32_t *)picref->data[0]);
+    s->update(s->instance, av_rescale_q(frame->pts, s->time_base, (AVRational){1,1000}),
+                   NULL, (uint32_t *)frame->data[0]);
 
-    return ff_filter_frame(outlink, picref);
+    return ff_filter_frame(outlink, frame);
 }
 
+static const AVOption src_options[] = {
+    { "size",          "Dimensions of the generated video.", OFFSET(size),      AV_OPT_TYPE_STRING, { .str = "" },   .flags = FLAGS },
+    { "framerate",     NULL,                                 OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = FLAGS },
+    { "filter_name",   NULL,                                 OFFSET(dl_name),   AV_OPT_TYPE_STRING,                  .flags = FLAGS },
+    { "filter_params", NULL,                                 OFFSET(params),    AV_OPT_TYPE_STRING,                  .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass src_class = {
+    .class_name = "frei0r_src",
+    .item_name  = av_default_item_name,
+    .option     = src_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = {
     {
         .name          = "default",
@@ -479,11 +505,12 @@ static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_frei0r_src = {
+AVFilter ff_vsrc_frei0r_src = {
     .name        = "frei0r_src",
     .description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."),
 
     .priv_size = sizeof(Frei0rContext),
+    .priv_class = &src_class,
     .init      = source_init,
     .uninit    = uninit,
 
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index 79e1490..79f6790 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2010 Nolan Lum <nol888 at gmail.com>
- * Copyright (c) 2009 Loren Merritt <lorenm at u.washignton.edu>
+ * Copyright (c) 2009 Loren Merritt <lorenm at u.washington.edu>
  *
  * This file is part of Libav.
  *
@@ -25,7 +25,7 @@
  * libmpcodecs/vf_gradfun.c
  *
  * Apply a boxblur debanding algorithm (based on the gradfun2db
- * Avisynth filter by prunedtree).
+ * AviSynth filter by prunedtree).
  * Foreach pixel, if it's within threshold of the blurred value, make it closer.
  * So now we have a smoothed and higher bitdepth version of all the shallow
  * gradients, while leaving detailed areas untouched.
@@ -35,6 +35,7 @@
 #include "libavutil/imgutils.h"
 #include "libavutil/common.h"
 #include "libavutil/cpu.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "formats.h"
@@ -56,7 +57,7 @@ DECLARE_ALIGNED(16, static const uint16_t, dither)[8][8] = {
 void ff_gradfun_filter_line_c(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
 {
     int x;
-    for (x = 0; x < width; x++, dc += x & 1) {
+    for (x = 0; x < width; dc += x & 1, x++) {
         int pix = src[x] << 7;
         int delta = dc[0] - pix;
         int m = abs(delta) * thresh >> 16;
@@ -119,34 +120,28 @@ static void filter(GradFunContext *ctx, uint8_t *dst, uint8_t *src, int width, i
     }
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    GradFunContext *gf = ctx->priv;
-    float thresh = 1.2;
-    int radius = 16;
+    GradFunContext *s = ctx->priv;
 
-    if (args)
-        sscanf(args, "%f:%d", &thresh, &radius);
+    s->thresh  = (1 << 15) / s->strength;
+    s->radius &= ~1;
 
-    thresh = av_clipf(thresh, 0.51, 255);
-    gf->thresh = (1 << 15) / thresh;
-    gf->radius = av_clip((radius + 1) & ~1, 4, 32);
-
-    gf->blur_line = ff_gradfun_blur_line_c;
-    gf->filter_line = ff_gradfun_filter_line_c;
+    s->blur_line = ff_gradfun_blur_line_c;
+    s->filter_line = ff_gradfun_filter_line_c;
 
     if (ARCH_X86)
-        ff_gradfun_init_x86(gf);
+        ff_gradfun_init_x86(s);
 
-    av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", thresh, gf->radius);
+    av_log(ctx, AV_LOG_VERBOSE, "threshold:%.2f radius:%d\n", s->strength, s->radius);
 
     return 0;
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    GradFunContext *gf = ctx->priv;
-    av_freep(&gf->buf);
+    GradFunContext *s = ctx->priv;
+    av_freep(&s->buf);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -166,74 +161,89 @@ static int query_formats(AVFilterContext *ctx)
 
 static int config_input(AVFilterLink *inlink)
 {
-    GradFunContext *gf = inlink->dst->priv;
+    GradFunContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     int hsub = desc->log2_chroma_w;
     int vsub = desc->log2_chroma_h;
 
-    gf->buf = av_mallocz((FFALIGN(inlink->w, 16) * (gf->radius + 1) / 2 + 32) * sizeof(uint16_t));
-    if (!gf->buf)
+    av_freep(&s->buf);
+    s->buf = av_mallocz((FFALIGN(inlink->w, 16) * (s->radius + 1) / 2 + 32) * sizeof(uint16_t));
+    if (!s->buf)
         return AVERROR(ENOMEM);
 
-    gf->chroma_w = -((-inlink->w) >> hsub);
-    gf->chroma_h = -((-inlink->h) >> vsub);
-    gf->chroma_r = av_clip(((((gf->radius >> hsub) + (gf->radius >> vsub)) / 2 ) + 1) & ~1, 4, 32);
+    s->chroma_w = -((-inlink->w) >> hsub);
+    s->chroma_h = -((-inlink->h) >> vsub);
+    s->chroma_r = av_clip(((((s->radius >> hsub) + (s->radius >> vsub)) / 2 ) + 1) & ~1, 4, 32);
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    GradFunContext *gf = inlink->dst->priv;
+    GradFunContext *s = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     int p, direct;
 
-    if ((in->perms & AV_PERM_WRITE) && !(in->perms & AV_PERM_PRESERVE)) {
+    if (av_frame_is_writable(in)) {
         direct = 1;
         out = in;
     } else {
         direct = 0;
-        out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
         if (!out) {
-            avfilter_unref_bufferp(&in);
+            av_frame_free(&in);
             return AVERROR(ENOMEM);
         }
 
-        avfilter_copy_buffer_ref_props(out, in);
-        out->video->w = outlink->w;
-        out->video->h = outlink->h;
+        av_frame_copy_props(out, in);
+        out->width  = outlink->w;
+        out->height = outlink->h;
     }
 
     for (p = 0; p < 4 && in->data[p]; p++) {
         int w = inlink->w;
         int h = inlink->h;
-        int r = gf->radius;
+        int r = s->radius;
         if (p) {
-            w = gf->chroma_w;
-            h = gf->chroma_h;
-            r = gf->chroma_r;
+            w = s->chroma_w;
+            h = s->chroma_h;
+            r = s->chroma_r;
         }
 
         if (FFMIN(w, h) > 2 * r)
-            filter(gf, out->data[p], in->data[p], w, h, out->linesize[p], in->linesize[p], r);
+            filter(s, out->data[p], in->data[p], w, h, out->linesize[p], in->linesize[p], r);
         else if (out->data[p] != in->data[p])
             av_image_copy_plane(out->data[p], out->linesize[p], in->data[p], in->linesize[p], w, h);
     }
 
     if (!direct)
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
 
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(GradFunContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "strength", "The maximum amount by which the filter will change any one pixel.", OFFSET(strength), AV_OPT_TYPE_FLOAT, { .dbl = 1.2 }, 0.51, 64, FLAGS },
+    { "radius",   "The neighborhood to fit the gradient to.",                          OFFSET(radius),   AV_OPT_TYPE_INT,   { .i64 = 16  }, 4,    32, FLAGS },
+    { NULL },
+};
+
+static const AVClass gradfun_class = {
+    .class_name = "gradfun",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_gradfun_inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
         .filter_frame = filter_frame,
-        .min_perms    = AV_PERM_READ,
     },
     { NULL }
 };
@@ -246,10 +256,11 @@ static const AVFilterPad avfilter_vf_gradfun_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_gradfun = {
+AVFilter ff_vf_gradfun = {
     .name          = "gradfun",
     .description   = NULL_IF_CONFIG_SMALL("Debands video quickly using gradients."),
     .priv_size     = sizeof(GradFunContext),
+    .priv_class    = &gradfun_class,
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index 85a1d92..6034b68 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -74,40 +74,40 @@ static int query_formats(AVFilterContext *ctx)
 
 static int config_props(AVFilterLink *inlink)
 {
-    FlipContext *flip = inlink->dst->priv;
+    FlipContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
 
-    av_image_fill_max_pixsteps(flip->max_step, NULL, pix_desc);
-    flip->hsub = pix_desc->log2_chroma_w;
-    flip->vsub = pix_desc->log2_chroma_h;
+    av_image_fill_max_pixsteps(s->max_step, NULL, pix_desc);
+    s->hsub = pix_desc->log2_chroma_w;
+    s->vsub = pix_desc->log2_chroma_h;
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx  = inlink->dst;
-    FlipContext *flip     = ctx->priv;
+    FlipContext *s     = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     uint8_t *inrow, *outrow;
     int i, j, plane, step, hsub, vsub;
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
-    avfilter_copy_buffer_ref_props(out, in);
+    av_frame_copy_props(out, in);
 
     for (plane = 0; plane < 4 && in->data[plane]; plane++) {
-        step = flip->max_step[plane];
-        hsub = (plane == 1 || plane == 2) ? flip->hsub : 0;
-        vsub = (plane == 1 || plane == 2) ? flip->vsub : 0;
+        step = s->max_step[plane];
+        hsub = (plane == 1 || plane == 2) ? s->hsub : 0;
+        vsub = (plane == 1 || plane == 2) ? s->vsub : 0;
 
         outrow = out->data[plane];
         inrow  = in ->data[plane] + ((inlink->w >> hsub) - 1) * step;
-        for (i = 0; i < in->video->h >> vsub; i++) {
+        for (i = 0; i < in->height >> vsub; i++) {
             switch (step) {
             case 1:
                 for (j = 0; j < (inlink->w >> hsub); j++)
@@ -153,7 +153,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
         }
     }
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
 
@@ -163,7 +163,6 @@ static const AVFilterPad avfilter_vf_hflip_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
         .config_props = config_props,
-        .min_perms    = AV_PERM_READ,
     },
     { NULL }
 };
@@ -176,7 +175,7 @@ static const AVFilterPad avfilter_vf_hflip_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_hflip = {
+AVFilter ff_vf_hflip = {
     .name      = "hflip",
     .description = NULL_IF_CONFIG_SMALL("Horizontally flip the input video."),
     .priv_size = sizeof(FlipContext),
diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
index e2d90d5..cd9f0d2 100644
--- a/libavfilter/vf_hqdn3d.c
+++ b/libavfilter/vf_hqdn3d.c
@@ -26,28 +26,20 @@
  * libmpcodecs/vf_hqdn3d.c.
  */
 
+#include <float.h>
+
+#include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
-
-typedef struct {
-    int16_t *coefs[4];
-    uint16_t *line;
-    uint16_t *frame_prev[3];
-    double strength[4];
-    int hsub, vsub;
-    int depth;
-    void (*denoise_row[17])(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-} HQDN3DContext;
-
-void ff_hqdn3d_row_8_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_9_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
-void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+#include "vf_hqdn3d.h"
 
 #define LUT_BITS (depth==16 ? 8 : 4)
 #define LOAD(x) (((depth == 8 ? src[x] : AV_RN16A(src + (x) * 2)) << (16 - depth))\
@@ -85,7 +77,7 @@ static void denoise_temporal(uint8_t *src, uint8_t *dst,
 }
 
 av_always_inline
-static void denoise_spatial(HQDN3DContext *hqdn3d,
+static void denoise_spatial(HQDN3DContext *s,
                             uint8_t *src, uint8_t *dst,
                             uint16_t *line_ant, uint16_t *frame_ant,
                             int w, int h, int sstride, int dstride,
@@ -111,8 +103,8 @@ static void denoise_spatial(HQDN3DContext *hqdn3d,
         src += sstride;
         dst += dstride;
         frame_ant += w;
-        if (hqdn3d->denoise_row[depth]) {
-            hqdn3d->denoise_row[depth](src, dst, line_ant, frame_ant, w, spatial, temporal);
+        if (s->denoise_row[depth]) {
+            s->denoise_row[depth](src, dst, line_ant, frame_ant, w, spatial, temporal);
             continue;
         }
         pixel_ant = LOAD(0);
@@ -129,7 +121,7 @@ static void denoise_spatial(HQDN3DContext *hqdn3d,
 }
 
 av_always_inline
-static void denoise_depth(HQDN3DContext *hqdn3d,
+static void denoise_depth(HQDN3DContext *s,
                           uint8_t *src, uint8_t *dst,
                           uint16_t *line_ant, uint16_t **frame_ant_ptr,
                           int w, int h, int sstride, int dstride,
@@ -150,7 +142,7 @@ static void denoise_depth(HQDN3DContext *hqdn3d,
     }
 
     if (spatial[0])
-        denoise_spatial(hqdn3d, src, dst, line_ant, frame_ant,
+        denoise_spatial(s, src, dst, line_ant, frame_ant,
                         w, h, sstride, dstride, spatial, temporal, depth);
     else
         denoise_temporal(src, dst, frame_ant,
@@ -158,7 +150,7 @@ static void denoise_depth(HQDN3DContext *hqdn3d,
 }
 
 #define denoise(...) \
-    switch (hqdn3d->depth) {\
+    switch (s->depth) {\
         case  8: denoise_depth(__VA_ARGS__,  8); break;\
         case  9: denoise_depth(__VA_ARGS__,  9); break;\
         case 10: denoise_depth(__VA_ARGS__, 10); break;\
@@ -190,76 +182,38 @@ static int16_t *precalc_coefs(double dist25, int depth)
 #define PARAM2_DEFAULT 3.0
 #define PARAM3_DEFAULT 6.0
 
-static int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    HQDN3DContext *hqdn3d = ctx->priv;
-    double lum_spac, lum_tmp, chrom_spac, chrom_tmp;
-    double param1, param2, param3, param4;
-
-    lum_spac   = PARAM1_DEFAULT;
-    chrom_spac = PARAM2_DEFAULT;
-    lum_tmp    = PARAM3_DEFAULT;
-    chrom_tmp  = lum_tmp * chrom_spac / lum_spac;
-
-    if (args) {
-        switch (sscanf(args, "%lf:%lf:%lf:%lf",
-                       &param1, &param2, &param3, &param4)) {
-        case 1:
-            lum_spac   = param1;
-            chrom_spac = PARAM2_DEFAULT * param1 / PARAM1_DEFAULT;
-            lum_tmp    = PARAM3_DEFAULT * param1 / PARAM1_DEFAULT;
-            chrom_tmp  = lum_tmp * chrom_spac / lum_spac;
-            break;
-        case 2:
-            lum_spac   = param1;
-            chrom_spac = param2;
-            lum_tmp    = PARAM3_DEFAULT * param1 / PARAM1_DEFAULT;
-            chrom_tmp  = lum_tmp * chrom_spac / lum_spac;
-            break;
-        case 3:
-            lum_spac   = param1;
-            chrom_spac = param2;
-            lum_tmp    = param3;
-            chrom_tmp  = lum_tmp * chrom_spac / lum_spac;
-            break;
-        case 4:
-            lum_spac   = param1;
-            chrom_spac = param2;
-            lum_tmp    = param3;
-            chrom_tmp  = param4;
-            break;
-        }
-    }
+    HQDN3DContext *s = ctx->priv;
 
-    hqdn3d->strength[0] = lum_spac;
-    hqdn3d->strength[1] = lum_tmp;
-    hqdn3d->strength[2] = chrom_spac;
-    hqdn3d->strength[3] = chrom_tmp;
+    if (!s->strength[LUMA_SPATIAL])
+        s->strength[LUMA_SPATIAL] = PARAM1_DEFAULT;
+    if (!s->strength[CHROMA_SPATIAL])
+        s->strength[CHROMA_SPATIAL] = PARAM2_DEFAULT * s->strength[LUMA_SPATIAL] / PARAM1_DEFAULT;
+    if (!s->strength[LUMA_TMP])
+        s->strength[LUMA_TMP]   = PARAM3_DEFAULT * s->strength[LUMA_SPATIAL] / PARAM1_DEFAULT;
+    if (!s->strength[CHROMA_TMP])
+        s->strength[CHROMA_TMP] = s->strength[LUMA_TMP] * s->strength[CHROMA_SPATIAL] / s->strength[LUMA_SPATIAL];
 
     av_log(ctx, AV_LOG_VERBOSE, "ls:%f cs:%f lt:%f ct:%f\n",
-           lum_spac, chrom_spac, lum_tmp, chrom_tmp);
-    if (lum_spac < 0 || chrom_spac < 0 || isnan(chrom_tmp)) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid negative value for luma or chroma spatial strength, "
-               "or resulting value for chroma temporal strength is nan.\n");
-        return AVERROR(EINVAL);
-    }
+           s->strength[LUMA_SPATIAL], s->strength[CHROMA_SPATIAL],
+           s->strength[LUMA_TMP], s->strength[CHROMA_TMP]);
 
     return 0;
 }
 
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
 {
-    HQDN3DContext *hqdn3d = ctx->priv;
-
-    av_freep(&hqdn3d->coefs[0]);
-    av_freep(&hqdn3d->coefs[1]);
-    av_freep(&hqdn3d->coefs[2]);
-    av_freep(&hqdn3d->coefs[3]);
-    av_freep(&hqdn3d->line);
-    av_freep(&hqdn3d->frame_prev[0]);
-    av_freep(&hqdn3d->frame_prev[1]);
-    av_freep(&hqdn3d->frame_prev[2]);
+    HQDN3DContext *s = ctx->priv;
+
+    av_freep(&s->coefs[0]);
+    av_freep(&s->coefs[1]);
+    av_freep(&s->coefs[2]);
+    av_freep(&s->coefs[3]);
+    av_freep(&s->line);
+    av_freep(&s->frame_prev[0]);
+    av_freep(&s->frame_prev[1]);
+    av_freep(&s->frame_prev[2]);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -294,72 +248,87 @@ static int query_formats(AVFilterContext *ctx)
 
 static int config_input(AVFilterLink *inlink)
 {
-    HQDN3DContext *hqdn3d = inlink->dst->priv;
+    HQDN3DContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     int i;
 
-    hqdn3d->hsub  = desc->log2_chroma_w;
-    hqdn3d->vsub  = desc->log2_chroma_h;
-    hqdn3d->depth = desc->comp[0].depth_minus1+1;
+    uninit(inlink->dst);
 
-    hqdn3d->line = av_malloc(inlink->w * sizeof(*hqdn3d->line));
-    if (!hqdn3d->line)
+    s->hsub  = desc->log2_chroma_w;
+    s->vsub  = desc->log2_chroma_h;
+    s->depth = desc->comp[0].depth_minus1+1;
+
+    s->line = av_malloc(inlink->w * sizeof(*s->line));
+    if (!s->line)
         return AVERROR(ENOMEM);
 
     for (i = 0; i < 4; i++) {
-        hqdn3d->coefs[i] = precalc_coefs(hqdn3d->strength[i], hqdn3d->depth);
-        if (!hqdn3d->coefs[i])
+        s->coefs[i] = precalc_coefs(s->strength[i], s->depth);
+        if (!s->coefs[i])
             return AVERROR(ENOMEM);
     }
 
-#if HAVE_YASM
-    hqdn3d->denoise_row[ 8] = ff_hqdn3d_row_8_x86;
-    hqdn3d->denoise_row[ 9] = ff_hqdn3d_row_9_x86;
-    hqdn3d->denoise_row[10] = ff_hqdn3d_row_10_x86;
-    hqdn3d->denoise_row[16] = ff_hqdn3d_row_16_x86;
-#endif
+    if (ARCH_X86)
+        ff_hqdn3d_init_x86(s);
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
-    HQDN3DContext *hqdn3d = inlink->dst->priv;
+    HQDN3DContext *s = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     int direct, c;
 
-    if ((in->perms & AV_PERM_WRITE) && !(in->perms & AV_PERM_PRESERVE)) {
+    if (av_frame_is_writable(in)) {
         direct = 1;
         out = in;
     } else {
         direct = 0;
-        out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
         if (!out) {
-            avfilter_unref_bufferp(&in);
+            av_frame_free(&in);
             return AVERROR(ENOMEM);
         }
 
-        avfilter_copy_buffer_ref_props(out, in);
-        out->video->w = outlink->w;
-        out->video->h = outlink->h;
+        av_frame_copy_props(out, in);
+        out->width  = outlink->w;
+        out->height = outlink->h;
     }
 
     for (c = 0; c < 3; c++) {
-        denoise(hqdn3d, in->data[c], out->data[c],
-                hqdn3d->line, &hqdn3d->frame_prev[c],
-                in->video->w >> (!!c * hqdn3d->hsub),
-                in->video->h >> (!!c * hqdn3d->vsub),
+        denoise(s, in->data[c], out->data[c],
+                s->line, &s->frame_prev[c],
+                in->width  >> (!!c * s->hsub),
+                in->height >> (!!c * s->vsub),
                 in->linesize[c], out->linesize[c],
-                hqdn3d->coefs[c?2:0], hqdn3d->coefs[c?3:1]);
+                s->coefs[c?2:0], s->coefs[c?3:1]);
     }
 
     if (!direct)
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
 
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(HQDN3DContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "luma_spatial",   "spatial luma strength",    OFFSET(strength[LUMA_SPATIAL]),   AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS },
+    { "chroma_spatial", "spatial chroma strength",  OFFSET(strength[CHROMA_SPATIAL]), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS },
+    { "luma_tmp",       "temporal luma strength",   OFFSET(strength[LUMA_TMP]),       AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS },
+    { "chroma_tmp",     "temporal chroma strength", OFFSET(strength[CHROMA_TMP]),     AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0, DBL_MAX, FLAGS },
+    { NULL },
+};
+
+static const AVClass hqdn3d_class = {
+    .class_name = "hqdn3d",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_hqdn3d_inputs[] = {
     {
         .name         = "default",
@@ -378,11 +347,12 @@ static const AVFilterPad avfilter_vf_hqdn3d_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_hqdn3d = {
+AVFilter ff_vf_hqdn3d = {
     .name          = "hqdn3d",
     .description   = NULL_IF_CONFIG_SMALL("Apply a High Quality 3D Denoiser."),
 
     .priv_size     = sizeof(HQDN3DContext),
+    .priv_class    = &hqdn3d_class,
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
diff --git a/libavfilter/vf_hqdn3d.h b/libavfilter/vf_hqdn3d.h
new file mode 100644
index 0000000..5cdbb12
--- /dev/null
+++ b/libavfilter/vf_hqdn3d.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav 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,
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef AVFILTER_VF_HQDN3D_H
+#define AVFILTER_VF_HQDN3D_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/opt.h"
+
+typedef struct {
+    const AVClass *class;
+    int16_t *coefs[4];
+    uint16_t *line;
+    uint16_t *frame_prev[3];
+    double strength[4];
+    int hsub, vsub;
+    int depth;
+    void (*denoise_row[17])(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
+} HQDN3DContext;
+
+#define LUMA_SPATIAL   0
+#define LUMA_TMP       1
+#define CHROMA_SPATIAL 2
+#define CHROMA_TMP     3
+
+void ff_hqdn3d_init_x86(HQDN3DContext *hqdn3d);
+
+#endif /* AVFILTER_VF_HQDN3D_H */
diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c
new file mode 100644
index 0000000..a05ab03
--- /dev/null
+++ b/libavfilter/vf_interlace.c
@@ -0,0 +1,264 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav 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,
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file
+ * progressive to interlaced content filter, inspired by heavy debugging of tinterlace filter
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
+
+#include "formats.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+
+enum ScanMode {
+    MODE_TFF = 0,
+    MODE_BFF = 1,
+};
+
+enum FieldType {
+    FIELD_UPPER = 0,
+    FIELD_LOWER = 1,
+};
+
+typedef struct {
+    const AVClass *class;
+    enum ScanMode scan;    // top or bottom field first scanning
+    int lowpass;           // enable or disable low pass filterning
+    AVFrame *cur, *next;   // the two frames from which the new one is obtained
+    int got_output;        // signal an output frame is reday to request_frame()
+} InterlaceContext;
+
+#define OFFSET(x) offsetof(InterlaceContext, x)
+#define V AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "scan", "scanning mode", OFFSET(scan),
+        AV_OPT_TYPE_INT,   {.i64 = MODE_TFF }, 0, 1, .flags = V, .unit = "scan" },
+    { "tff", "top field first", 0,
+        AV_OPT_TYPE_CONST, {.i64 = MODE_TFF }, INT_MIN, INT_MAX, .flags = V, .unit = "scan" },
+    { "bff", "bottom field first", 0,
+        AV_OPT_TYPE_CONST, {.i64 = MODE_BFF }, INT_MIN, INT_MAX, .flags = V, .unit = "scan" },
+    { "lowpass", "enable vertical low-pass filter", OFFSET(lowpass),
+        AV_OPT_TYPE_INT,   {.i64 = 1 },        0, 1, .flags = V },
+    { NULL }
+};
+
+static const AVClass class = {
+    .class_name = "interlace filter",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+
+static const enum AVPixelFormat formats_supported[] = {
+    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,    AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P,
+    AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_NONE
+};
+
+static int query_formats(AVFilterContext *ctx)
+{
+    ff_set_common_formats(ctx, ff_make_format_list(formats_supported));
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    InterlaceContext *s = ctx->priv;
+
+    av_frame_free(&s->cur);
+    av_frame_free(&s->next);
+
+    av_opt_free(s);
+}
+
+static int config_out_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+    InterlaceContext *s = ctx->priv;
+
+    if (inlink->h < 2) {
+        av_log(ctx, AV_LOG_ERROR, "input video height is too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+    // same input size
+    outlink->w = inlink->w;
+    outlink->h = inlink->h;
+    outlink->time_base = inlink->time_base;
+    // half framerate
+    outlink->time_base.num *= 2;
+
+    av_log(ctx, AV_LOG_VERBOSE, "%s interlacing %s lowpass filter\n",
+           s->scan == MODE_TFF ? "tff" : "bff", (s->lowpass) ? "with" : "without");
+
+    return 0;
+}
+
+static void copy_picture_field(AVFrame *src_frame, AVFrame *dst_frame,
+                               AVFilterLink *inlink, enum FieldType field_type,
+                               int lowpass)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+    int vsub = desc->log2_chroma_h;
+    int plane, i, j;
+
+    for (plane = 0; plane < desc->nb_components; plane++) {
+        int lines = (plane == 1 || plane == 2) ? -(-inlink->h) >> vsub : inlink->h;
+        int linesize = av_image_get_linesize(inlink->format, inlink->w, plane);
+        uint8_t *dstp = dst_frame->data[plane];
+        const uint8_t *srcp = src_frame->data[plane];
+
+        av_assert0(linesize >= 0);
+
+        lines = (lines + (field_type == FIELD_UPPER)) / 2;
+        if (field_type == FIELD_LOWER)
+            srcp += src_frame->linesize[plane];
+        if (field_type == FIELD_LOWER)
+            dstp += dst_frame->linesize[plane];
+        if (lowpass) {
+            int srcp_linesize = src_frame->linesize[plane] * 2;
+            int dstp_linesize = dst_frame->linesize[plane] * 2;
+            for (j = lines; j > 0; j--) {
+                const uint8_t *srcp_above = srcp - src_frame->linesize[plane];
+                const uint8_t *srcp_below = srcp + src_frame->linesize[plane];
+                if (j == lines)
+                    srcp_above = srcp; // there is no line above
+                if (j == 1)
+                    srcp_below = srcp; // there is no line below
+                for (i = 0; i < linesize; i++) {
+                    // this calculation is an integer representation of
+                    // '0.5 * current + 0.25 * above + 0.25 * below'
+                    // '1 +' is for rounding.
+                    dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
+                }
+                dstp += dstp_linesize;
+                srcp += srcp_linesize;
+            }
+        } else {
+            av_image_copy_plane(dstp, dst_frame->linesize[plane] * 2,
+                                srcp, src_frame->linesize[plane] * 2,
+                                linesize, lines);
+        }
+    }
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    InterlaceContext *s = ctx->priv;
+    AVFrame *out;
+    int tff, ret;
+
+    av_frame_free(&s->cur);
+    s->cur  = s->next;
+    s->next = buf;
+
+    /* we need at least two frames */
+    if (!s->cur || !s->next)
+        return 0;
+
+    if (s->cur->interlaced_frame) {
+        av_log(ctx, AV_LOG_WARNING,
+               "video is already interlaced, adjusting framerate only\n");
+        out = av_frame_clone(s->cur);
+        if (!out)
+            return AVERROR(ENOMEM);
+        out->pts /= 2;  // adjust pts to new framerate
+        ret = ff_filter_frame(outlink, out);
+        s->got_output = 1;
+        return ret;
+    }
+
+    tff = (s->scan == MODE_TFF);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
+    if (!out)
+        return AVERROR(ENOMEM);
+
+    av_frame_copy_props(out, s->cur);
+    out->interlaced_frame = 1;
+    out->top_field_first  = tff;
+    out->pts             /= 2;  // adjust pts to new framerate
+
+    /* copy upper/lower field from cur */
+    copy_picture_field(s->cur, out, inlink, tff ? FIELD_UPPER : FIELD_LOWER, s->lowpass);
+    av_frame_free(&s->cur);
+
+    /* copy lower/upper field from next */
+    copy_picture_field(s->next, out, inlink, tff ? FIELD_LOWER : FIELD_UPPER, s->lowpass);
+    av_frame_free(&s->next);
+
+    ret = ff_filter_frame(outlink, out);
+    s->got_output = 1;
+
+    return ret;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    InterlaceContext *s  = ctx->priv;
+    int ret = 0;
+
+    s->got_output = 0;
+    while (ret >= 0 && !s->got_output)
+        ret = ff_request_frame(ctx->inputs[0]);
+
+    return ret;
+}
+
+static const AVFilterPad inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad outputs[] = {
+    {
+        .name          = "default",
+        .type          = AVMEDIA_TYPE_VIDEO,
+        .config_props  = config_out_props,
+        .request_frame = request_frame,
+    },
+    { NULL }
+};
+
+AVFilter ff_vf_interlace = {
+    .name          = "interlace",
+    .description   = NULL_IF_CONFIG_SMALL("Convert progressive video into interlaced."),
+    .uninit        = uninit,
+
+    .priv_class    = &class,
+    .priv_size     = sizeof(InterlaceContext),
+    .query_formats = query_formats,
+
+    .inputs        = inputs,
+    .outputs       = outputs,
+};
+
diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c
index e558a4a..fa913f7 100644
--- a/libavfilter/vf_libopencv.c
+++ b/libavfilter/vf_libopencv.c
@@ -23,19 +23,18 @@
  * libopencv wrapper functions
  */
 
-/* #define DEBUG */
-
 #include <opencv/cv.h>
 #include <opencv/cxcore.h>
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
 #include "libavutil/file.h"
+#include "libavutil/opt.h"
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
-static void fill_iplimage_from_picref(IplImage *img, const AVFilterBufferRef *picref, enum AVPixelFormat pixfmt)
+static void fill_iplimage_from_frame(IplImage *img, const AVFrame *frame, enum AVPixelFormat pixfmt)
 {
     IplImage *tmpimg;
     int depth, channels_nb;
@@ -45,18 +44,18 @@ static void fill_iplimage_from_picref(IplImage *img, const AVFilterBufferRef *pi
     else if (pixfmt == AV_PIX_FMT_BGR24) { depth = IPL_DEPTH_8U;  channels_nb = 3; }
     else return;
 
-    tmpimg = cvCreateImageHeader((CvSize){picref->video->w, picref->video->h}, depth, channels_nb);
+    tmpimg = cvCreateImageHeader((CvSize){frame->width, frame->height}, depth, channels_nb);
     *img = *tmpimg;
-    img->imageData = img->imageDataOrigin = picref->data[0];
+    img->imageData = img->imageDataOrigin = frame->data[0];
     img->dataOrder = IPL_DATA_ORDER_PIXEL;
     img->origin    = IPL_ORIGIN_TL;
-    img->widthStep = picref->linesize[0];
+    img->widthStep = frame->linesize[0];
 }
 
-static void fill_picref_from_iplimage(AVFilterBufferRef *picref, const IplImage *img, enum AVPixelFormat pixfmt)
+static void fill_frame_from_iplimage(AVFrame *frame, const IplImage *img, enum AVPixelFormat pixfmt)
 {
-    picref->linesize[0] = img->widthStep;
-    picref->data[0]     = img->imageData;
+    frame->linesize[0] = img->widthStep;
+    frame->data[0]     = img->imageData;
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -70,7 +69,9 @@ static int query_formats(AVFilterContext *ctx)
 }
 
 typedef struct {
-    const char *name;
+    const AVClass *class;
+    char *name;
+    char *params;
     int (*init)(AVFilterContext *ctx, const char *args);
     void (*uninit)(AVFilterContext *ctx);
     void (*end_frame_filter)(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg);
@@ -85,8 +86,8 @@ typedef struct {
 
 static av_cold int smooth_init(AVFilterContext *ctx, const char *args)
 {
-    OCVContext *ocv = ctx->priv;
-    SmoothContext *smooth = ocv->priv;
+    OCVContext *s = ctx->priv;
+    SmoothContext *smooth = s->priv;
     char type_str[128] = "gaussian";
 
     smooth->param1 = 3;
@@ -95,7 +96,7 @@ static av_cold int smooth_init(AVFilterContext *ctx, const char *args)
     smooth->param4 = 0.0;
 
     if (args)
-        sscanf(args, "%127[^:]:%d:%d:%lf:%lf", type_str, &smooth->param1, &smooth->param2, &smooth->param3, &smooth->param4);
+        sscanf(args, "%127[^|]|%d|%d|%lf|%lf", type_str, &smooth->param1, &smooth->param2, &smooth->param3, &smooth->param4);
 
     if      (!strcmp(type_str, "blur"         )) smooth->type = CV_BLUR;
     else if (!strcmp(type_str, "blur_no_scale")) smooth->type = CV_BLUR_NO_SCALE;
@@ -128,8 +129,8 @@ static av_cold int smooth_init(AVFilterContext *ctx, const char *args)
 
 static void smooth_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg)
 {
-    OCVContext *ocv = ctx->priv;
-    SmoothContext *smooth = ocv->priv;
+    OCVContext *s = ctx->priv;
+    SmoothContext *smooth = s->priv;
     cvSmooth(inimg, outimg, smooth->type, smooth->param1, smooth->param2, smooth->param3, smooth->param4);
 }
 
@@ -177,7 +178,7 @@ static int read_shape_from_file(int *cols, int *rows, int **values, const char *
                 p++;
                 break;
             } else
-                (*values)[*cols*i + j] = !!isgraph(*(p++));
+                (*values)[*cols*i + j] = !!av_isgraph(*(p++));
         }
     }
     av_file_unmap(buf, size);
@@ -251,8 +252,8 @@ typedef struct {
 
 static av_cold int dilate_init(AVFilterContext *ctx, const char *args)
 {
-    OCVContext *ocv = ctx->priv;
-    DilateContext *dilate = ocv->priv;
+    OCVContext *s = ctx->priv;
+    DilateContext *dilate = s->priv;
     char default_kernel_str[] = "3x3+0x0/rect";
     char *kernel_str;
     const char *buf = args;
@@ -261,14 +262,14 @@ static av_cold int dilate_init(AVFilterContext *ctx, const char *args)
     dilate->nb_iterations = 1;
 
     if (args)
-        kernel_str = av_get_token(&buf, ":");
+        kernel_str = av_get_token(&buf, "|");
     if ((ret = parse_iplconvkernel(&dilate->kernel,
                                    *kernel_str ? kernel_str : default_kernel_str,
                                    ctx)) < 0)
         return ret;
     av_free(kernel_str);
 
-    sscanf(buf, ":%d", &dilate->nb_iterations);
+    sscanf(buf, "|%d", &dilate->nb_iterations);
     av_log(ctx, AV_LOG_VERBOSE, "iterations_nb:%d\n", dilate->nb_iterations);
     if (dilate->nb_iterations <= 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid non-positive value '%d' for nb_iterations\n",
@@ -280,23 +281,23 @@ static av_cold int dilate_init(AVFilterContext *ctx, const char *args)
 
 static av_cold void dilate_uninit(AVFilterContext *ctx)
 {
-    OCVContext *ocv = ctx->priv;
-    DilateContext *dilate = ocv->priv;
+    OCVContext *s = ctx->priv;
+    DilateContext *dilate = s->priv;
 
     cvReleaseStructuringElement(&dilate->kernel);
 }
 
 static void dilate_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg)
 {
-    OCVContext *ocv = ctx->priv;
-    DilateContext *dilate = ocv->priv;
+    OCVContext *s = ctx->priv;
+    DilateContext *dilate = s->priv;
     cvDilate(inimg, outimg, dilate->kernel, dilate->nb_iterations);
 }
 
 static void erode_end_frame_filter(AVFilterContext *ctx, IplImage *inimg, IplImage *outimg)
 {
-    OCVContext *ocv = ctx->priv;
-    DilateContext *dilate = ocv->priv;
+    OCVContext *s = ctx->priv;
+    DilateContext *dilate = s->priv;
     cvErode(inimg, outimg, dilate->kernel, dilate->nb_iterations);
 }
 
@@ -314,74 +315,82 @@ static OCVFilterEntry ocv_filter_entries[] = {
     { "smooth", sizeof(SmoothContext), smooth_init, NULL, smooth_end_frame_filter },
 };
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    OCVContext *ocv = ctx->priv;
-    char name[128], priv_args[1024];
+    OCVContext *s = ctx->priv;
     int i;
-    char c;
-
-    sscanf(args, "%127[^=:]%c%1023s", name, &c, priv_args);
 
     for (i = 0; i < FF_ARRAY_ELEMS(ocv_filter_entries); i++) {
         OCVFilterEntry *entry = &ocv_filter_entries[i];
-        if (!strcmp(name, entry->name)) {
-            ocv->name             = entry->name;
-            ocv->init             = entry->init;
-            ocv->uninit           = entry->uninit;
-            ocv->end_frame_filter = entry->end_frame_filter;
+        if (!strcmp(s->name, entry->name)) {
+            s->init             = entry->init;
+            s->uninit           = entry->uninit;
+            s->end_frame_filter = entry->end_frame_filter;
 
-            if (!(ocv->priv = av_mallocz(entry->priv_size)))
+            if (!(s->priv = av_mallocz(entry->priv_size)))
                 return AVERROR(ENOMEM);
-            return ocv->init(ctx, priv_args);
+            return s->init(ctx, s->params);
         }
     }
 
-    av_log(ctx, AV_LOG_ERROR, "No libopencv filter named '%s'\n", name);
+    av_log(ctx, AV_LOG_ERROR, "No libopencv filter named '%s'\n", s->name);
     return AVERROR(EINVAL);
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    OCVContext *ocv = ctx->priv;
+    OCVContext *s = ctx->priv;
 
-    if (ocv->uninit)
-        ocv->uninit(ctx);
-    av_free(ocv->priv);
-    memset(ocv, 0, sizeof(*ocv));
+    if (s->uninit)
+        s->uninit(ctx);
+    av_free(s->priv);
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx = inlink->dst;
-    OCVContext *ocv = ctx->priv;
+    OCVContext *s = ctx->priv;
     AVFilterLink *outlink= inlink->dst->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     IplImage inimg, outimg;
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
-    avfilter_copy_buffer_ref_props(out, in);
+    av_frame_copy_props(out, in);
 
-    fill_iplimage_from_picref(&inimg , in , inlink->format);
-    fill_iplimage_from_picref(&outimg, out, inlink->format);
-    ocv->end_frame_filter(ctx, &inimg, &outimg);
-    fill_picref_from_iplimage(out, &outimg, inlink->format);
+    fill_iplimage_from_frame(&inimg , in , inlink->format);
+    fill_iplimage_from_frame(&outimg, out, inlink->format);
+    s->end_frame_filter(ctx, &inimg, &outimg);
+    fill_frame_from_iplimage(out, &outimg, inlink->format);
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
 
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(OCVContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "filter_name",   NULL, OFFSET(name),   AV_OPT_TYPE_STRING, .flags = FLAGS },
+    { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass ocv_class = {
+    .class_name = "ocv",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_ocv_inputs[] = {
     {
         .name       = "default",
         .type       = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
-        .min_perms  = AV_PERM_READ
     },
     { NULL }
 };
@@ -394,11 +403,12 @@ static const AVFilterPad avfilter_vf_ocv_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_ocv = {
+AVFilter ff_vf_ocv = {
     .name        = "ocv",
     .description = NULL_IF_CONFIG_SMALL("Apply transform using libopencv."),
 
     .priv_size = sizeof(OCVContext),
+    .priv_class = &ocv_class,
 
     .query_formats = query_formats,
     .init = init,
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index f265795..c59dcd6 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -24,6 +24,7 @@
  * value, and apply it to input video.
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
 #include "libavutil/mathematics.h"
@@ -84,62 +85,46 @@ typedef struct {
 #define A 3
 
 #define OFFSET(x) offsetof(LutContext, x)
+#define FLAGS 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},
-    {NULL},
+    { "c0", "set component #0 expression", OFFSET(comp_expr_str[0]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "c1", "set component #1 expression", OFFSET(comp_expr_str[1]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "c2", "set component #2 expression", OFFSET(comp_expr_str[2]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "c3", "set component #3 expression", OFFSET(comp_expr_str[3]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "y",  "set Y expression",            OFFSET(comp_expr_str[Y]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "u",  "set U expression",            OFFSET(comp_expr_str[U]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "v",  "set V expression",            OFFSET(comp_expr_str[V]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "r",  "set R expression",            OFFSET(comp_expr_str[R]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "g",  "set G expression",            OFFSET(comp_expr_str[G]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "b",  "set B expression",            OFFSET(comp_expr_str[B]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { "a",  "set A expression",            OFFSET(comp_expr_str[A]),  AV_OPT_TYPE_STRING, { .str = "val" }, .flags = FLAGS },
+    { NULL },
 };
 
-static const char *lut_get_name(void *ctx)
+static av_cold int init(AVFilterContext *ctx)
 {
-    return "lut";
-}
-
-static const AVClass lut_class = {
-    "LutContext",
-    lut_get_name,
-    lut_options
-};
+    LutContext *s = ctx->priv;
 
-static int init(AVFilterContext *ctx, const char *args)
-{
-    LutContext *lut = ctx->priv;
-    int ret;
+    s->var_values[VAR_PHI] = M_PHI;
+    s->var_values[VAR_PI]  = M_PI;
+    s->var_values[VAR_E ]  = M_E;
 
-    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;
+    s->is_rgb = !strcmp(ctx->filter->name, "lutrgb");
+    s->is_yuv = !strcmp(ctx->filter->name, "lutyuv");
 
     return 0;
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
     int i;
 
     for (i = 0; i < 4; i++) {
-        av_expr_free(lut->comp_expr[i]);
-        lut->comp_expr[i] = NULL;
-        av_freep(&lut->comp_expr_str[i]);
+        av_expr_free(s->comp_expr[i]);
+        s->comp_expr[i] = NULL;
+        av_freep(&s->comp_expr_str[i]);
     }
 }
 
@@ -155,16 +140,17 @@ static av_cold void uninit(AVFilterContext *ctx)
     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;
+    LutContext *s = 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 = s->is_rgb ? rgb_pix_fmts :
+                                                     s->is_yuv ? yuv_pix_fmts :
+                                                                 all_pix_fmts;
 
     ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
     return 0;
@@ -175,9 +161,9 @@ static int query_formats(AVFilterContext *ctx)
  */
 static double clip(void *opaque, double val)
 {
-    LutContext *lut = opaque;
-    double minval = lut->var_values[VAR_MINVAL];
-    double maxval = lut->var_values[VAR_MAXVAL];
+    LutContext *s = opaque;
+    double minval = s->var_values[VAR_MINVAL];
+    double maxval = s->var_values[VAR_MAXVAL];
 
     return av_clip(val, minval, maxval);
 }
@@ -188,10 +174,10 @@ static double clip(void *opaque, double val)
  */
 static double compute_gammaval(void *opaque, double gamma)
 {
-    LutContext *lut = opaque;
-    double val    = lut->var_values[VAR_CLIPVAL];
-    double minval = lut->var_values[VAR_MINVAL];
-    double maxval = lut->var_values[VAR_MAXVAL];
+    LutContext *s = opaque;
+    double val    = s->var_values[VAR_CLIPVAL];
+    double minval = s->var_values[VAR_MINVAL];
+    double maxval = s->var_values[VAR_MAXVAL];
 
     return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval;
 }
@@ -211,16 +197,16 @@ static const char * const funcs1_names[] = {
 static int config_props(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     int min[4], max[4];
     int val, comp, ret;
 
-    lut->hsub = desc->log2_chroma_w;
-    lut->vsub = desc->log2_chroma_h;
+    s->hsub = desc->log2_chroma_w;
+    s->vsub = desc->log2_chroma_h;
 
-    lut->var_values[VAR_W] = inlink->w;
-    lut->var_values[VAR_H] = inlink->h;
+    s->var_values[VAR_W] = inlink->w;
+    s->var_values[VAR_H] = inlink->h;
 
     switch (inlink->format) {
     case AV_PIX_FMT_YUV410P:
@@ -240,90 +226,92 @@ static int config_props(AVFilterLink *inlink)
         max[0] = max[1] = max[2] = max[3] = 255;
     }
 
-    lut->is_yuv = lut->is_rgb = 0;
-    if      (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) lut->is_yuv = 1;
-    else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) lut->is_rgb = 1;
+    s->is_yuv = s->is_rgb = 0;
+    if      (ff_fmt_is_in(inlink->format, yuv_pix_fmts)) s->is_yuv = 1;
+    else if (ff_fmt_is_in(inlink->format, rgb_pix_fmts)) s->is_rgb = 1;
 
-    if (lut->is_rgb) {
+    if (s->is_rgb) {
         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:  s->rgba_map[A] = 0; s->rgba_map[R] = 1; s->rgba_map[G] = 2; s->rgba_map[B] = 3; break;
+        case AV_PIX_FMT_ABGR:  s->rgba_map[A] = 0; s->rgba_map[B] = 1; s->rgba_map[G] = 2; s->rgba_map[R] = 3; 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: s->rgba_map[R] = 0; s->rgba_map[G] = 1; s->rgba_map[B] = 2; s->rgba_map[A] = 3; 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: s->rgba_map[B] = 0; s->rgba_map[G] = 1; s->rgba_map[R] = 2; s->rgba_map[A] = 3; break;
         }
-        lut->step = av_get_bits_per_pixel(desc) >> 3;
+        s->step = av_get_bits_per_pixel(desc) >> 3;
     }
 
     for (comp = 0; comp < desc->nb_components; comp++) {
         double res;
 
         /* create the parsed expression */
-        ret = av_expr_parse(&lut->comp_expr[comp], lut->comp_expr_str[comp],
+        av_expr_free(s->comp_expr[comp]);
+        s->comp_expr[comp] = NULL;
+        ret = av_expr_parse(&s->comp_expr[comp], s->comp_expr_str[comp],
                             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);
+                   s->comp_expr_str[comp], comp);
             return AVERROR(EINVAL);
         }
 
-        /* compute the lut */
-        lut->var_values[VAR_MAXVAL] = max[comp];
-        lut->var_values[VAR_MINVAL] = min[comp];
+        /* compute the s */
+        s->var_values[VAR_MAXVAL] = max[comp];
+        s->var_values[VAR_MINVAL] = min[comp];
 
         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_NEGVAL] =
-                av_clip(min[comp] + max[comp] - lut->var_values[VAR_VAL],
+            s->var_values[VAR_VAL] = val;
+            s->var_values[VAR_CLIPVAL] = av_clip(val, min[comp], max[comp]);
+            s->var_values[VAR_NEGVAL] =
+                av_clip(min[comp] + max[comp] - s->var_values[VAR_VAL],
                         min[comp], max[comp]);
 
-            res = av_expr_eval(lut->comp_expr[comp], lut->var_values, lut);
+            res = av_expr_eval(s->comp_expr[comp], s->var_values, s);
             if (isnan(res)) {
                 av_log(ctx, AV_LOG_ERROR,
                        "Error when evaluating the expression '%s' for the value %d for the component #%d.\n",
-                       lut->comp_expr_str[comp], val, comp);
+                       s->comp_expr_str[comp], val, comp);
                 return AVERROR(EINVAL);
             }
-            lut->lut[comp][val] = av_clip((int)res, min[comp], max[comp]);
-            av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, lut->lut[comp][val]);
+            s->lut[comp][val] = av_clip((int)res, min[comp], max[comp]);
+            av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, s->lut[comp][val]);
         }
     }
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterContext *ctx = inlink->dst;
-    LutContext *lut = ctx->priv;
+    LutContext *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     uint8_t *inrow, *outrow, *inrow0, *outrow0;
     int i, j, k, plane;
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
-    avfilter_copy_buffer_ref_props(out, in);
+    av_frame_copy_props(out, in);
 
-    if (lut->is_rgb) {
+    if (s->is_rgb) {
         /* packed */
         inrow0  = in ->data[0];
         outrow0 = out->data[0];
 
-        for (i = 0; i < in->video->h; i ++) {
+        for (i = 0; i < in->height; i ++) {
             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]];
-                outrow += lut->step;
-                inrow  += lut->step;
+                for (k = 0; k < s->step; k++)
+                    outrow[k] = s->lut[s->rgba_map[k]][inrow[k]];
+                outrow += s->step;
+                inrow  += s->step;
             }
             inrow0  += in ->linesize[0];
             outrow0 += out->linesize[0];
@@ -331,22 +319,22 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
     } else {
         /* planar */
         for (plane = 0; plane < 4 && in->data[plane]; plane++) {
-            int vsub = plane == 1 || plane == 2 ? lut->vsub : 0;
-            int hsub = plane == 1 || plane == 2 ? lut->hsub : 0;
+            int vsub = plane == 1 || plane == 2 ? s->vsub : 0;
+            int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
 
             inrow  = in ->data[plane];
             outrow = out->data[plane];
 
-            for (i = 0; i < in->video->h >> vsub; i ++) {
+            for (i = 0; i < in->height >> vsub; i ++) {
                 for (j = 0; j < inlink->w>>hsub; j++)
-                    outrow[j] = lut->lut[plane][inrow[j]];
+                    outrow[j] = s->lut[plane][inrow[j]];
                 inrow  += in ->linesize[plane];
                 outrow += out->linesize[plane];
             }
         }
     }
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
 
@@ -355,7 +343,7 @@ static const AVFilterPad inputs[] = {
       .type            = AVMEDIA_TYPE_VIDEO,
       .filter_frame    = filter_frame,
       .config_props    = config_props,
-      .min_perms       = AV_PERM_READ, },
+    },
     { .name = NULL}
 };
 static const AVFilterPad outputs[] = {
@@ -363,11 +351,18 @@ static const AVFilterPad outputs[] = {
       .type            = AVMEDIA_TYPE_VIDEO, },
     { .name = NULL}
 };
-#define DEFINE_LUT_FILTER(name_, description_, init_)                   \
-    AVFilter avfilter_vf_##name_ = {                                    \
+#define DEFINE_LUT_FILTER(name_, description_, init_, options)          \
+    static const AVClass name_ ## _class = {                            \
+        .class_name = #name_,                                           \
+        .item_name  = av_default_item_name,                             \
+        .option     = options,                                          \
+        .version    = LIBAVUTIL_VERSION_INT,                            \
+    };                                                                  \
+    AVFilter ff_vf_##name_ = {                                          \
         .name          = #name_,                                        \
         .description   = NULL_IF_CONFIG_SMALL(description_),            \
         .priv_size     = sizeof(LutContext),                            \
+        .priv_class    = &name_ ## _class,                              \
                                                                         \
         .init          = init_,                                         \
         .uninit        = uninit,                                        \
@@ -378,33 +373,41 @@ static const AVFilterPad outputs[] = {
     }
 
 #if CONFIG_LUT_FILTER
-DEFINE_LUT_FILTER(lut,    "Compute and apply a lookup table to the RGB/YUV input video.", init);
+DEFINE_LUT_FILTER(lut,    "Compute and apply a lookup table to the RGB/YUV input video.", init, lut_options);
 #endif
 #if CONFIG_LUTYUV_FILTER
-DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.",     init);
+DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.",     init, lut_options);
 #endif
 #if CONFIG_LUTRGB_FILTER
-DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.",     init);
+DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.",     init, lut_options);
 #endif
 
 #if CONFIG_NEGATE_FILTER
 
-static int negate_init(AVFilterContext *ctx, const char *args)
-{
-    LutContext *lut = ctx->priv;
-    char lut_params[64];
+static const AVOption negate_options[] = {
+    { "negate_alpha", NULL, OFFSET(negate_alpha), AV_OPT_TYPE_INT, { .i64 = 0 }, .flags = FLAGS },
+    { NULL },
+};
 
-    if (args)
-        sscanf(args, "%d", &lut->negate_alpha);
+static av_cold int negate_init(AVFilterContext *ctx)
+{
+    LutContext *s = ctx->priv;
+    int i;
 
-    av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", lut->negate_alpha);
+    av_log(ctx, AV_LOG_DEBUG, "negate_alpha:%d\n", s->negate_alpha);
 
-    snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s",
-             lut->negate_alpha ? "negval" : "val");
+    for (i = 0; i < 4; i++) {
+        s->comp_expr_str[i] = av_strdup((i == 3 && s->negate_alpha) ?
+                                          "val" : "negval");
+        if (!s->comp_expr_str[i]) {
+            uninit(ctx);
+            return AVERROR(ENOMEM);
+        }
+    }
 
-    return init(ctx, lut_params);
+    return init(ctx);
 }
 
-DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init);
+DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init, negate_options);
 
 #endif
diff --git a/libavfilter/vf_null.c b/libavfilter/vf_null.c
index a7abb7a..f872587 100644
--- a/libavfilter/vf_null.c
+++ b/libavfilter/vf_null.c
@@ -43,7 +43,7 @@ static const AVFilterPad avfilter_vf_null_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_null = {
+AVFilter ff_vf_null = {
     .name      = "null",
     .description = NULL_IF_CONFIG_SMALL("Pass the source unchanged to the output."),
 
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 8741d48..5155573 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -34,6 +34,7 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 #include "internal.h"
 #include "video.h"
 
@@ -63,37 +64,25 @@ enum var_name {
 #define OVERLAY 1
 
 typedef struct {
+    const AVClass *class;
     int x, y;                   ///< position of overlayed picture
 
     int max_plane_step[4];      ///< steps per pixel for each plane
     int hsub, vsub;             ///< chroma subsampling values
 
-    char x_expr[256], y_expr[256];
+    char *x_expr, *y_expr;
 
-    AVFilterBufferRef *main;
-    AVFilterBufferRef *over_prev, *over_next;
+    AVFrame *main;
+    AVFrame *over_prev, *over_next;
 } OverlayContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    OverlayContext *over = ctx->priv;
-
-    av_strlcpy(over->x_expr, "0", sizeof(over->x_expr));
-    av_strlcpy(over->y_expr, "0", sizeof(over->y_expr));
-
-    if (args)
-        sscanf(args, "%255[^:]:%255[^:]", over->x_expr, over->y_expr);
-
-    return 0;
-}
-
 static av_cold void uninit(AVFilterContext *ctx)
 {
     OverlayContext *s = ctx->priv;
 
-    avfilter_unref_bufferp(&s->main);
-    avfilter_unref_bufferp(&s->over_prev);
-    avfilter_unref_bufferp(&s->over_next);
+    av_frame_free(&s->main);
+    av_frame_free(&s->over_prev);
+    av_frame_free(&s->over_next);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -112,12 +101,12 @@ static int query_formats(AVFilterContext *ctx)
 
 static int config_input_main(AVFilterLink *inlink)
 {
-    OverlayContext *over = inlink->dst->priv;
+    OverlayContext *s = inlink->dst->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
 
-    av_image_fill_max_pixsteps(over->max_plane_step, NULL, pix_desc);
-    over->hsub = pix_desc->log2_chroma_w;
-    over->vsub = pix_desc->log2_chroma_h;
+    av_image_fill_max_pixsteps(s->max_plane_step, NULL, pix_desc);
+    s->hsub = pix_desc->log2_chroma_w;
+    s->vsub = pix_desc->log2_chroma_h;
 
     return 0;
 }
@@ -125,7 +114,7 @@ static int config_input_main(AVFilterLink *inlink)
 static int config_input_overlay(AVFilterLink *inlink)
 {
     AVFilterContext *ctx  = inlink->dst;
-    OverlayContext  *over = inlink->dst->priv;
+    OverlayContext  *s = inlink->dst->priv;
     char *expr;
     double var_values[VAR_VARS_NB], res;
     int ret;
@@ -141,36 +130,36 @@ static int config_input_overlay(AVFilterLink *inlink)
     var_values[VAR_OVERLAY_W] = var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
     var_values[VAR_OVERLAY_H] = var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;
 
-    if ((ret = av_expr_parse_and_eval(&res, (expr = over->x_expr), var_names, var_values,
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr), var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto fail;
-    over->x = res;
-    if ((ret = av_expr_parse_and_eval(&res, (expr = over->y_expr), var_names, var_values,
+    s->x = res;
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr), var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)))
         goto fail;
-    over->y = res;
+    s->y = res;
     /* x may depend on y */
-    if ((ret = av_expr_parse_and_eval(&res, (expr = over->x_expr), var_names, var_values,
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr), var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto fail;
-    over->x = res;
+    s->x = res;
 
     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,
            av_get_pix_fmt_name(ctx->inputs[MAIN]->format),
-           over->x, over->y,
+           s->x, s->y,
            ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,
            av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format));
 
-    if (over->x < 0 || over->y < 0 ||
-        over->x + var_values[VAR_OVERLAY_W] > var_values[VAR_MAIN_W] ||
-        over->y + var_values[VAR_OVERLAY_H] > var_values[VAR_MAIN_H]) {
+    if (s->x < 0 || s->y < 0 ||
+        s->x + var_values[VAR_OVERLAY_W] > var_values[VAR_MAIN_W] ||
+        s->y + var_values[VAR_OVERLAY_H] > var_values[VAR_MAIN_H]) {
         av_log(ctx, AV_LOG_ERROR,
                "Overlay area (%d,%d)<->(%d,%d) not within the main area (0,0)<->(%d,%d) or zero-sized\n",
-               over->x, over->y,
-               (int)(over->x + var_values[VAR_OVERLAY_W]),
-               (int)(over->y + var_values[VAR_OVERLAY_H]),
+               s->x, s->y,
+               (int)(s->x + var_values[VAR_OVERLAY_W]),
+               (int)(s->y + var_values[VAR_OVERLAY_H]),
                (int)var_values[VAR_MAIN_W], (int)var_values[VAR_MAIN_H]);
         return AVERROR(EINVAL);
     }
@@ -194,17 +183,17 @@ static int config_output(AVFilterLink *outlink)
 }
 
 static void blend_frame(AVFilterContext *ctx,
-                        AVFilterBufferRef *dst, AVFilterBufferRef *src,
+                        AVFrame *dst, AVFrame *src,
                         int x, int y)
 {
-    OverlayContext *over = ctx->priv;
+    OverlayContext *s = ctx->priv;
     int i, j, k;
     int width, height;
-    int overlay_end_y = y + src->video->h;
+    int overlay_end_y = y + src->height;
     int end_y, start_y;
 
-    width = FFMIN(dst->video->w - x, src->video->w);
-    end_y = FFMIN(dst->video->h, overlay_end_y);
+    width = FFMIN(dst->width - x, src->width);
+    end_y = FFMIN(dst->height, overlay_end_y);
     start_y = FFMAX(y, 0);
     height = end_y - start_y;
 
@@ -229,8 +218,8 @@ static void blend_frame(AVFilterContext *ctx,
         }
     } else {
         for (i = 0; i < 3; i++) {
-            int hsub = i ? over->hsub : 0;
-            int vsub = i ? over->vsub : 0;
+            int hsub = i ? s->hsub : 0;
+            int vsub = i ? s->vsub : 0;
             uint8_t *dp = dst->data[i] + (x >> hsub) +
                 (start_y >> vsub) * dst->linesize[i];
             uint8_t *sp = src->data[i];
@@ -269,7 +258,7 @@ static void blend_frame(AVFilterContext *ctx,
     }
 }
 
-static int filter_frame_main(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame_main(AVFilterLink *inlink, AVFrame *frame)
 {
     OverlayContext *s = inlink->dst->priv;
 
@@ -279,7 +268,7 @@ static int filter_frame_main(AVFilterLink *inlink, AVFilterBufferRef *frame)
     return 0;
 }
 
-static int filter_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame_overlay(AVFilterLink *inlink, AVFrame *frame)
 {
     OverlayContext *s = inlink->dst->priv;
 
@@ -335,8 +324,8 @@ static int request_frame(AVFilterLink *outlink)
     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);
+        av_frame_free(&s->over_prev);
+        FFSWAP(AVFrame*, s->over_prev, s->over_next);
 
         ret = ff_request_frame(ctx->inputs[OVERLAY]);
         if (ret == AVERROR_EOF)
@@ -349,8 +338,8 @@ static int request_frame(AVFilterLink *outlink)
         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);
+        av_frame_free(&s->over_prev);
+        FFSWAP(AVFrame*, s->over_prev, s->over_next);
     } else if (s->over_prev) {
         blend_frame(ctx, s->main, s->over_prev, s->x, s->y);
     }
@@ -358,14 +347,30 @@ static int request_frame(AVFilterLink *outlink)
     return output_frame(ctx);
 }
 
+#define OFFSET(x) offsetof(OverlayContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "x", "Horizontal position of the left edge of the overlaid video on the "
+        "main video.",          OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
+    { "y", "Vertical position of the top edge of the overlaid video on the "
+        "main video.",          OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str = "0" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass overlay_class = {
+    .class_name = "overlay",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_overlay_inputs[] = {
     {
         .name         = "main",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_main,
         .filter_frame = filter_frame_main,
-        .min_perms    = AV_PERM_READ,
-        .rej_perms    = AV_PERM_REUSE2 | AV_PERM_PRESERVE,
+        .needs_writable = 1,
         .needs_fifo   = 1,
     },
     {
@@ -373,8 +378,6 @@ static const AVFilterPad avfilter_vf_overlay_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input_overlay,
         .filter_frame = filter_frame_overlay,
-        .min_perms    = AV_PERM_READ,
-        .rej_perms    = AV_PERM_REUSE2,
         .needs_fifo   = 1,
     },
     { NULL }
@@ -390,14 +393,14 @@ static const AVFilterPad avfilter_vf_overlay_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_overlay = {
+AVFilter ff_vf_overlay = {
     .name      = "overlay",
     .description = NULL_IF_CONFIG_SMALL("Overlay a video source on top of the input."),
 
-    .init      = init,
     .uninit    = uninit,
 
     .priv_size = sizeof(OverlayContext),
+    .priv_class = &overlay_class,
 
     .query_formats = query_formats,
 
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index f1a890e..0609767 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -37,6 +37,8 @@
 #include "libavutil/imgutils.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+
 #include "drawutils.h"
 
 static const char *const var_names[] = {
@@ -93,14 +95,16 @@ static int query_formats(AVFilterContext *ctx)
 }
 
 typedef struct {
+    const AVClass *class;
     int w, h;               ///< output dimensions, a value of 0 will result in the input size
     int x, y;               ///< offsets of the input area with respect to the padded area
     int in_w, in_h;         ///< width and height for the padded input video, which has to be aligned to the chroma values in order to avoid chroma issues
 
-    char w_expr[256];       ///< width  expression string
-    char h_expr[256];       ///< height expression string
-    char x_expr[256];       ///< width  expression string
-    char y_expr[256];       ///< height expression string
+    char *w_expr;           ///< width  expression string
+    char *h_expr;           ///< height expression string
+    char *x_expr;           ///< width  expression string
+    char *y_expr;           ///< height expression string
+    char *color_str;
 
     uint8_t color[4];       ///< color expressed either in YUVA or RGBA colorspace for the padding area
     uint8_t *line[4];
@@ -108,21 +112,11 @@ typedef struct {
     int hsub, vsub;         ///< chroma subsampling values
 } PadContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
-    PadContext *pad = ctx->priv;
-    char color_string[128] = "black";
-
-    av_strlcpy(pad->w_expr, "iw", sizeof(pad->w_expr));
-    av_strlcpy(pad->h_expr, "ih", sizeof(pad->h_expr));
-    av_strlcpy(pad->x_expr, "0" , sizeof(pad->w_expr));
-    av_strlcpy(pad->y_expr, "0" , sizeof(pad->h_expr));
+    PadContext *s = ctx->priv;
 
-    if (args)
-        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255s",
-               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(s->color, s->color_str, -1, ctx) < 0)
         return AVERROR(EINVAL);
 
     return 0;
@@ -130,27 +124,27 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    PadContext *pad = ctx->priv;
+    PadContext *s = ctx->priv;
     int i;
 
     for (i = 0; i < 4; i++) {
-        av_freep(&pad->line[i]);
-        pad->line_step[i] = 0;
+        av_freep(&s->line[i]);
+        s->line_step[i] = 0;
     }
 }
 
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    PadContext *pad = ctx->priv;
+    PadContext *s = ctx->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
     uint8_t rgba_color[4];
     int ret, is_packed_rgba;
     double var_values[VARS_NB], res;
     char *expr;
 
-    pad->hsub = pix_desc->log2_chroma_w;
-    pad->vsub = pix_desc->log2_chroma_h;
+    s->hsub = pix_desc->log2_chroma_w;
+    s->vsub = pix_desc->log2_chroma_h;
 
     var_values[VAR_PI]    = M_PI;
     var_values[VAR_PHI]   = M_PHI;
@@ -160,78 +154,78 @@ static int config_input(AVFilterLink *inlink)
     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_HSUB]  = 1<<s->hsub;
+    var_values[VAR_VSUB]  = 1<<s->vsub;
 
     /* evaluate width and height */
-    av_expr_parse_and_eval(&res, (expr = pad->w_expr),
+    av_expr_parse_and_eval(&res, (expr = s->w_expr),
                            var_names, var_values,
                            NULL, NULL, NULL, NULL, NULL, 0, ctx);
-    pad->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
-    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->h_expr),
+    s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),
                                       var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto eval_fail;
-    pad->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
+    s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;
     /* evaluate the width again, as it may depend on the evaluated output height */
-    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->w_expr),
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),
                                       var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto eval_fail;
-    pad->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
+    s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;
 
     /* evaluate x and y */
-    av_expr_parse_and_eval(&res, (expr = pad->x_expr),
+    av_expr_parse_and_eval(&res, (expr = s->x_expr),
                            var_names, var_values,
                            NULL, NULL, NULL, NULL, NULL, 0, ctx);
-    pad->x = var_values[VAR_X] = res;
-    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->y_expr),
+    s->x = var_values[VAR_X] = res;
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),
                                       var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto eval_fail;
-    pad->y = var_values[VAR_Y] = res;
+    s->y = var_values[VAR_Y] = res;
     /* evaluate x again, as it may depend on the evaluated y value */
-    if ((ret = av_expr_parse_and_eval(&res, (expr = pad->x_expr),
+    if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr),
                                       var_names, var_values,
                                       NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         goto eval_fail;
-    pad->x = var_values[VAR_X] = res;
+    s->x = var_values[VAR_X] = res;
 
     /* sanity check params */
-    if (pad->w < 0 || pad->h < 0 || pad->x < 0 || pad->y < 0) {
+    if (s->w < 0 || s->h < 0 || s->x < 0 || s->y < 0) {
         av_log(ctx, AV_LOG_ERROR, "Negative values are not acceptable.\n");
         return AVERROR(EINVAL);
     }
 
-    if (!pad->w)
-        pad->w = inlink->w;
-    if (!pad->h)
-        pad->h = inlink->h;
+    if (!s->w)
+        s->w = inlink->w;
+    if (!s->h)
+        s->h = inlink->h;
 
-    pad->w &= ~((1 << pad->hsub) - 1);
-    pad->h &= ~((1 << pad->vsub) - 1);
-    pad->x &= ~((1 << pad->hsub) - 1);
-    pad->y &= ~((1 << pad->vsub) - 1);
+    s->w &= ~((1 << s->hsub) - 1);
+    s->h &= ~((1 << s->vsub) - 1);
+    s->x &= ~((1 << s->hsub) - 1);
+    s->y &= ~((1 << s->vsub) - 1);
 
-    pad->in_w = inlink->w & ~((1 << pad->hsub) - 1);
-    pad->in_h = inlink->h & ~((1 << pad->vsub) - 1);
+    s->in_w = inlink->w & ~((1 << s->hsub) - 1);
+    s->in_h = inlink->h & ~((1 << s->vsub) - 1);
 
-    memcpy(rgba_color, pad->color, sizeof(rgba_color));
-    ff_fill_line_with_color(pad->line, pad->line_step, pad->w, pad->color,
+    memcpy(rgba_color, s->color, sizeof(rgba_color));
+    ff_fill_line_with_color(s->line, s->line_step, s->w, s->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",
-           inlink->w, inlink->h, pad->w, pad->h, pad->x, pad->y,
-           pad->color[0], pad->color[1], pad->color[2], pad->color[3],
+           inlink->w, inlink->h, s->w, s->h, s->x, s->y,
+           s->color[0], s->color[1], s->color[2], s->color[3],
            is_packed_rgba ? "rgba" : "yuva");
 
-    if (pad->x <  0 || pad->y <  0                      ||
-        pad->w <= 0 || pad->h <= 0                      ||
-        (unsigned)pad->x + (unsigned)inlink->w > pad->w ||
-        (unsigned)pad->y + (unsigned)inlink->h > pad->h) {
+    if (s->x <  0 || s->y <  0                      ||
+        s->w <= 0 || s->h <= 0                      ||
+        (unsigned)s->x + (unsigned)inlink->w > s->w ||
+        (unsigned)s->y + (unsigned)inlink->h > s->h) {
         av_log(ctx, AV_LOG_ERROR,
                "Input area %d:%d:%d:%d not within the padded area 0:0:%d:%d or zero-sized\n",
-               pad->x, pad->y, pad->x + inlink->w, pad->y + inlink->h, pad->w, pad->h);
+               s->x, s->y, s->x + inlink->w, s->y + inlink->h, s->w, s->h);
         return AVERROR(EINVAL);
     }
 
@@ -246,143 +240,193 @@ eval_fail:
 
 static int config_output(AVFilterLink *outlink)
 {
-    PadContext *pad = outlink->src->priv;
+    PadContext *s = outlink->src->priv;
 
-    outlink->w = pad->w;
-    outlink->h = pad->h;
+    outlink->w = s->w;
+    outlink->h = s->h;
     return 0;
 }
 
-static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
+static AVFrame *get_video_buffer(AVFilterLink *inlink, int w, int h)
 {
-    PadContext *pad = inlink->dst->priv;
+    PadContext *s = inlink->dst->priv;
 
-    AVFilterBufferRef *picref = ff_get_video_buffer(inlink->dst->outputs[0], perms,
-                                                    w + (pad->w - pad->in_w),
-                                                    h + (pad->h - pad->in_h));
+    AVFrame *frame = ff_get_video_buffer(inlink->dst->outputs[0],
+                                         w + (s->w - s->in_w),
+                                         h + (s->h - s->in_h));
     int plane;
 
-    if (!picref)
+    if (!frame)
         return NULL;
 
-    picref->video->w = w;
-    picref->video->h = h;
+    frame->width  = w;
+    frame->height = 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;
+    for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
+        int hsub = (plane == 1 || plane == 2) ? s->hsub : 0;
+        int vsub = (plane == 1 || plane == 2) ? s->vsub : 0;
 
-        picref->data[plane] += (pad->x >> hsub) * pad->line_step[plane] +
-            (pad->y >> vsub) * picref->linesize[plane];
+        frame->data[plane] += (s->x >> hsub) * s->line_step[plane] +
+            (s->y >> vsub) * frame->linesize[plane];
     }
 
-    return picref;
+    return frame;
 }
 
-static int does_clip(PadContext *pad, AVFilterBufferRef *outpicref, int plane, int hsub, int vsub, int x, int y)
+/* check whether each plane in this buffer can be padded without copying */
+static int buffer_needs_copy(PadContext *s, AVFrame *frame, AVBufferRef *buf)
 {
-    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];
+    int planes[4] = { -1, -1, -1, -1}, *p = planes;
+    int i, j;
 
-    if(x_in_buf < 0 || x_in_buf % pad->line_step[plane])
-        return 1;
-    x_in_buf /= pad->line_step[plane];
-
-    av_assert0(outpicref->buf->linesize[plane]>0); //while reference can use negative linesize the main buffer should not
+    /* get all planes in this buffer */
+    for (i = 0; i < FF_ARRAY_ELEMS(planes) && frame->data[i]; i++) {
+        if (av_frame_get_plane_buffer(frame, i) == buf)
+            *p++ = i;
+    }
 
-    y_in_buf = x_in_buf / outpicref->buf->linesize[plane];
-    x_in_buf %= outpicref->buf->linesize[plane];
+    /* for each plane in this buffer, check that it can be padded without
+     * going over buffer bounds or other planes */
+    for (i = 0; i < FF_ARRAY_ELEMS(planes) && planes[i] >= 0; i++) {
+        int hsub = (planes[i] == 1 || planes[i] == 2) ? s->hsub : 0;
+        int vsub = (planes[i] == 1 || planes[i] == 2) ? s->vsub : 0;
+
+        uint8_t *start = frame->data[planes[i]];
+        uint8_t *end   = start + (frame->height >> hsub) *
+                                 frame->linesize[planes[i]];
+
+        /* amount of free space needed before the start and after the end
+         * of the plane */
+        ptrdiff_t req_start = (s->x >> hsub) * s->line_step[planes[i]] +
+                              (s->y >> vsub) * frame->linesize[planes[i]];
+        ptrdiff_t req_end   = ((s->w - s->x - frame->width) >> hsub) *
+                              s->line_step[planes[i]] +
+                              (s->y >> vsub) * frame->linesize[planes[i]];
+
+        if (frame->linesize[planes[i]] < (s->w >> hsub) * s->line_step[planes[i]])
+            return 1;
+        if (start - buf->data < req_start ||
+            (buf->data + buf->size) - end < req_end)
+            return 1;
+
+#define SIGN(x) ((x) > 0 ? 1 : -1)
+        for (j = 0; j < FF_ARRAY_ELEMS(planes) && planes[j] >= 0; j++) {
+            int hsub1 = (planes[j] == 1 || planes[j] == 2) ? s->hsub : 0;
+            uint8_t *start1 = frame->data[planes[j]];
+            uint8_t *end1   = start1 + (frame->height >> hsub1) *
+                                       frame->linesize[planes[j]];
+            if (i == j)
+                continue;
+
+            if (SIGN(start - end1) != SIGN(start - end1 - req_start) ||
+                SIGN(end - start1) != SIGN(end - start1 + req_end))
+                return 1;
+        }
+    }
 
-    if(   y_in_buf<<vsub >= outpicref->buf->h
-       || x_in_buf<<hsub >= outpicref->buf->w)
-        return 1;
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int frame_needs_copy(PadContext *s, AVFrame *frame)
 {
-    PadContext *pad = inlink->dst->priv;
-    AVFilterBufferRef *out = avfilter_ref_buffer(in, ~0);
-    int plane, needs_copy;
-
-    if (!out) {
-        avfilter_unref_bufferp(&in);
-        return AVERROR(ENOMEM);
-    }
-
-    for (plane = 0; plane < 4 && out->data[plane]; plane++) {
-        int hsub = (plane == 1 || plane == 2) ? pad->hsub : 0;
-        int vsub = (plane == 1 || plane == 2) ? pad->vsub : 0;
+    int i;
 
-        av_assert0(out->buf->w > 0 && out->buf->h > 0);
+    if (!av_frame_is_writable(frame))
+        return 1;
 
-        if (out->format != out->buf->format) //unsupported currently
-            break;
+    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++)
+        if (buffer_needs_copy(s, frame, frame->buf[i]))
+            return 1;
+    return 0;
+}
 
-        out->data[plane] -= (pad->x  >> hsub) * pad->line_step[plane] +
-                            (pad->y  >> vsub) * out->linesize [plane];
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+    PadContext *s = inlink->dst->priv;
+    AVFrame *out;
+    int needs_copy = frame_needs_copy(s, in);
 
-        if (does_clip(pad, out, plane, hsub, vsub, 0,                   0) ||
-            does_clip(pad, out, plane, hsub, vsub, 0,          pad->h - 1) ||
-            does_clip(pad, out, plane, hsub, vsub, pad->w - 1,          0) ||
-            does_clip(pad, out, plane, hsub, vsub, pad->w - 1, pad->h - 1))
-            break;
-    }
-    needs_copy = plane < 4 && out->data[plane];
     if (needs_copy) {
         av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
-        avfilter_unref_buffer(out);
-        out = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES,
-                                  FFMAX(inlink->w, pad->w),
-                                  FFMAX(inlink->h, pad->h));
+        out = ff_get_video_buffer(inlink->dst->outputs[0],
+                                  FFMAX(inlink->w, s->w),
+                                  FFMAX(inlink->h, s->h));
         if (!out) {
-            avfilter_unref_bufferp(&in);
+            av_frame_free(&in);
             return AVERROR(ENOMEM);
         }
 
-        avfilter_copy_buffer_ref_props(out, in);
-    }
+        av_frame_copy_props(out, in);
+    } else {
+        int i;
 
-    out->video->w = pad->w;
-    out->video->h = pad->h;
+        out = in;
+        for (i = 0; i < FF_ARRAY_ELEMS(out->data) && out->data[i]; i++) {
+            int hsub = (i == 1 || i == 2) ? s->hsub : 0;
+            int vsub = (i == 1 || i == 2) ? s->vsub : 0;
+            out->data[i] -= (s->x >> hsub) * s->line_step[i] +
+                            (s->y >> vsub) * out->linesize[i];
+        }
+    }
 
     /* top bar */
-    if (pad->y) {
+    if (s->y) {
         ff_draw_rectangle(out->data, out->linesize,
-                          pad->line, pad->line_step, pad->hsub, pad->vsub,
-                          0, 0, pad->w, pad->y);
+                          s->line, s->line_step, s->hsub, s->vsub,
+                          0, 0, s->w, s->y);
     }
 
     /* bottom bar */
-    if (pad->h > pad->y + pad->in_h) {
+    if (s->h > s->y + s->in_h) {
         ff_draw_rectangle(out->data, out->linesize,
-                          pad->line, pad->line_step, pad->hsub, pad->vsub,
-                          0, pad->y + pad->in_h, pad->w, pad->h - pad->y - pad->in_h);
+                          s->line, s->line_step, s->hsub, s->vsub,
+                          0, s->y + s->in_h, s->w, s->h - s->y - s->in_h);
     }
 
     /* left border */
-    ff_draw_rectangle(out->data, out->linesize, pad->line, pad->line_step,
-                      pad->hsub, pad->vsub, 0, pad->y, pad->x, in->video->h);
+    ff_draw_rectangle(out->data, out->linesize, s->line, s->line_step,
+                      s->hsub, s->vsub, 0, s->y, s->x, in->height);
 
     if (needs_copy) {
         ff_copy_rectangle(out->data, out->linesize, in->data, in->linesize,
-                          pad->line_step, pad->hsub, pad->vsub,
-                          pad->x, pad->y, 0, in->video->w, in->video->h);
+                          s->line_step, s->hsub, s->vsub,
+                          s->x, s->y, 0, in->width, in->height);
     }
 
     /* right border */
     ff_draw_rectangle(out->data, out->linesize,
-                      pad->line, pad->line_step, pad->hsub, pad->vsub,
-                      pad->x + pad->in_w, pad->y, pad->w - pad->x - pad->in_w,
-                      in->video->h);
+                      s->line, s->line_step, s->hsub, s->vsub,
+                      s->x + s->in_w, s->y, s->w - s->x - s->in_w,
+                      in->height);
+
+    out->width  = s->w;
+    out->height = s->h;
 
-    avfilter_unref_bufferp(&in);
+    if (in != out)
+        av_frame_free(&in);
     return ff_filter_frame(inlink->dst->outputs[0], out);
 }
 
+#define OFFSET(x) offsetof(PadContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "width",  "Output video width",       OFFSET(w_expr),    AV_OPT_TYPE_STRING, { .str = "iw" },    .flags = FLAGS },
+    { "height", "Output video height",      OFFSET(h_expr),    AV_OPT_TYPE_STRING, { .str = "ih" },    .flags = FLAGS },
+    { "x",      "Horizontal position of the left edge of the input video in the "
+        "output video",                     OFFSET(x_expr),    AV_OPT_TYPE_STRING, { .str = "0"  },    .flags = FLAGS },
+    { "y",      "Vertical position of the top edge of the input video in the "
+        "output video",                     OFFSET(y_expr),    AV_OPT_TYPE_STRING, { .str = "0"  },    .flags = FLAGS },
+    { "color",  "Color of the padded area", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass pad_class = {
+    .class_name = "pad",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_pad_inputs[] = {
     {
         .name             = "default",
@@ -403,11 +447,12 @@ static const AVFilterPad avfilter_vf_pad_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_pad = {
+AVFilter ff_vf_pad = {
     .name          = "pad",
     .description   = NULL_IF_CONFIG_SMALL("Pad input image to width:height[:x:y[:color]] (default x and y: 0, default color: black)."),
 
     .priv_size     = sizeof(PadContext),
+    .priv_class    = &pad_class,
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c
index a1e982c..5c6b625 100644
--- a/libavfilter/vf_pixdesctest.c
+++ b/libavfilter/vf_pixdesctest.c
@@ -46,27 +46,27 @@ static int config_props(AVFilterLink *inlink)
 
     priv->pix_desc = av_pix_fmt_desc_get(inlink->format);
 
+    av_freep(&priv->line);
     if (!(priv->line = av_malloc(sizeof(*priv->line) * inlink->w)))
         return AVERROR(ENOMEM);
 
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     PixdescTestContext *priv = inlink->dst->priv;
     AVFilterLink *outlink    = inlink->dst->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     int i, c, w = inlink->w, h = inlink->h;
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE,
-                              outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
 
-    avfilter_copy_buffer_ref_props(out, in);
+    av_frame_copy_props(out, in);
 
     for (i = 0; i < 4; i++) {
         int h = outlink->h;
@@ -79,8 +79,8 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
     }
 
     /* copy palette */
-    if (priv->pix_desc->flags & PIX_FMT_PAL ||
-        priv->pix_desc->flags & PIX_FMT_PSEUDOPAL)
+    if (priv->pix_desc->flags & AV_PIX_FMT_FLAG_PAL ||
+        priv->pix_desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
         memcpy(out->data[1], in->data[1], 256*4);
 
     for (c = 0; c < priv->pix_desc->nb_components; c++) {
@@ -102,7 +102,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
         }
     }
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
 
@@ -112,7 +112,6 @@ static const AVFilterPad avfilter_vf_pixdesctest_inputs[] = {
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
         .config_props = config_props,
-        .min_perms    = AV_PERM_READ,
     },
     { NULL }
 };
@@ -125,7 +124,7 @@ static const AVFilterPad avfilter_vf_pixdesctest_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_pixdesctest = {
+AVFilter ff_vf_pixdesctest = {
     .name        = "pixdesctest",
     .description = NULL_IF_CONFIG_SMALL("Test pixel format definitions."),
 
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 7f189a2..c47c6f3 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -69,6 +69,7 @@ enum var_name {
 };
 
 typedef struct {
+    const AVClass *class;
     struct SwsContext *sws;     ///< software scaler context
 
     /**
@@ -83,31 +84,23 @@ typedef struct {
     int slice_y;                ///< top of current output slice
     int input_is_pal;           ///< set to 1 if the input format is paletted
 
-    char w_expr[256];           ///< width  expression string
-    char h_expr[256];           ///< height expression string
+    char *w_expr;               ///< width  expression string
+    char *h_expr;               ///< height expression string
+    char *flags_str;
 } ScaleContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     ScaleContext *scale = ctx->priv;
-    const char *p;
-
-    av_strlcpy(scale->w_expr, "iw", sizeof(scale->w_expr));
-    av_strlcpy(scale->h_expr, "ih", sizeof(scale->h_expr));
-
-    scale->flags = SWS_BILINEAR;
-    if (args) {
-        sscanf(args, "%255[^:]:%255[^:]", scale->w_expr, scale->h_expr);
-        p = strstr(args,"flags=");
-        if (p) {
-            const AVClass *class = sws_get_class();
-            const AVOption    *o = av_opt_find(&class, "sws_flags", NULL, 0,
-                                               AV_OPT_SEARCH_FAKE_OBJ);
-            int ret = av_opt_eval_flags(&class, o, p + 6, &scale->flags);
-
-            if (ret < 0)
-                return ret;
-        }
+
+    if (scale->flags_str) {
+        const AVClass *class = sws_get_class();
+        const AVOption    *o = av_opt_find(&class, "sws_flags", NULL, 0,
+                                           AV_OPT_SEARCH_FAKE_OBJ);
+        int ret = av_opt_eval_flags(&class, o, scale->flags_str, &scale->flags);
+
+        if (ret < 0)
+            return ret;
     }
 
     return 0;
@@ -129,7 +122,8 @@ static int query_formats(AVFilterContext *ctx)
     if (ctx->inputs[0]) {
         formats = NULL;
         for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++)
-            if (   sws_isSupportedInput(pix_fmt)
+            if ((sws_isSupportedInput(pix_fmt) ||
+                 sws_isSupportedEndiannessConversion(pix_fmt))
                 && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
                 ff_formats_unref(&formats);
                 return ret;
@@ -139,7 +133,8 @@ static int query_formats(AVFilterContext *ctx)
     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) ||
+                 sws_isSupportedEndiannessConversion(pix_fmt))
                 && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
                 ff_formats_unref(&formats);
                 return ret;
@@ -168,9 +163,10 @@ static int config_props(AVFilterLink *outlink)
     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;
 
@@ -225,8 +221,8 @@ static int config_props(AVFilterLink *outlink)
            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;
+    scale->input_is_pal = desc->flags & AV_PIX_FMT_FLAG_PAL ||
+                          desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL;
 
     if (scale->sws)
         sws_freeContext(scale->sws);
@@ -257,11 +253,11 @@ fail:
     return ret;
 }
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *link, AVFrame *in)
 {
     ScaleContext *scale = link->dst->priv;
     AVFilterLink *outlink = link->dst->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
 
     if (!scale->sws)
@@ -270,34 +266,49 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
     scale->hsub = desc->log2_chroma_w;
     scale->vsub = desc->log2_chroma_h;
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
 
-    avfilter_copy_buffer_ref_props(out, in);
-    out->video->w = outlink->w;
-    out->video->h = outlink->h;
+    av_frame_copy_props(out, in);
+    out->width  = outlink->w;
+    out->height = outlink->h;
 
-    av_reduce(&out->video->pixel_aspect.num, &out->video->pixel_aspect.den,
-              (int64_t)in->video->pixel_aspect.num * outlink->h * link->w,
-              (int64_t)in->video->pixel_aspect.den * outlink->w * link->h,
+    av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
+              (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
+              (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
               INT_MAX);
 
-    sws_scale(scale->sws, in->data, in->linesize, 0, in->video->h,
+    sws_scale(scale->sws, in->data, in->linesize, 0, in->height,
               out->data, out->linesize);
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(ScaleContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "w",     "Output video width",          OFFSET(w_expr),    AV_OPT_TYPE_STRING, { .str = "iw" },       .flags = FLAGS },
+    { "h",     "Output video height",         OFFSET(h_expr),    AV_OPT_TYPE_STRING, { .str = "ih" },       .flags = FLAGS },
+    { "flags", "Flags to pass to libswscale", OFFSET(flags_str), AV_OPT_TYPE_STRING, { .str = "bilinear" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass scale_class = {
+    .class_name = "scale",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_scale_inputs[] = {
     {
         .name        = "default",
         .type        = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
-        .min_perms   = AV_PERM_READ,
     },
     { NULL }
 };
@@ -311,7 +322,7 @@ static const AVFilterPad avfilter_vf_scale_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_scale = {
+AVFilter ff_vf_scale = {
     .name      = "scale",
     .description = NULL_IF_CONFIG_SMALL("Scale the input video to width:height size and/or convert the image format."),
 
@@ -321,6 +332,7 @@ AVFilter avfilter_vf_scale = {
     .query_formats = query_formats,
 
     .priv_size = sizeof(ScaleContext),
+    .priv_class = &scale_class,
 
     .inputs    = avfilter_vf_scale_inputs,
     .outputs   = avfilter_vf_scale_outputs,
diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c
index 674151d..fc69c89 100644
--- a/libavfilter/vf_select.c
+++ b/libavfilter/vf_select.c
@@ -27,6 +27,7 @@
 #include "libavutil/fifo.h"
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "video.h"
@@ -108,7 +109,6 @@ enum var_name {
     VAR_PREV_SELECTED_N,
 
     VAR_KEY,
-    VAR_POS,
 
     VAR_VARS_NB
 };
@@ -116,6 +116,8 @@ enum var_name {
 #define FIFO_SIZE 8
 
 typedef struct {
+    const AVClass *class;
+    char *expr_str;
     AVExpr *expr;
     double var_values[VAR_VARS_NB];
     double select;
@@ -123,18 +125,19 @@ typedef struct {
     AVFifoBuffer *pending_frames; ///< FIFO buffer of video frames
 } SelectContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     SelectContext *select = ctx->priv;
     int ret;
 
-    if ((ret = av_expr_parse(&select->expr, args ? args : "1",
+    if ((ret = av_expr_parse(&select->expr, select->expr_str,
                              var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
+        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n",
+               select->expr_str);
         return ret;
     }
 
-    select->pending_frames = av_fifo_alloc(FIFO_SIZE*sizeof(AVFilterBufferRef*));
+    select->pending_frames = av_fifo_alloc(FIFO_SIZE*sizeof(AVFrame*));
     if (!select->pending_frames) {
         av_log(ctx, AV_LOG_ERROR, "Failed to allocate pending frames buffer.\n");
         return AVERROR(ENOMEM);
@@ -181,35 +184,33 @@ static int config_input(AVFilterLink *inlink)
 #define D2TS(d)  (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
 
-static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref)
+static int select_frame(AVFilterContext *ctx, AVFrame *frame)
 {
     SelectContext *select = ctx->priv;
     AVFilterLink *inlink = ctx->inputs[0];
     double res;
 
     if (isnan(select->var_values[VAR_START_PTS]))
-        select->var_values[VAR_START_PTS] = TS2D(picref->pts);
+        select->var_values[VAR_START_PTS] = TS2D(frame->pts);
     if (isnan(select->var_values[VAR_START_T]))
-        select->var_values[VAR_START_T] = TS2D(picref->pts) * av_q2d(inlink->time_base);
+        select->var_values[VAR_START_T] = TS2D(frame->pts) * av_q2d(inlink->time_base);
 
-    select->var_values[VAR_PTS] = TS2D(picref->pts);
-    select->var_values[VAR_T  ] = TS2D(picref->pts) * av_q2d(inlink->time_base);
-    select->var_values[VAR_POS] = picref->pos == -1 ? NAN : picref->pos;
-    select->var_values[VAR_PREV_PTS] = TS2D(picref ->pts);
+    select->var_values[VAR_PTS] = TS2D(frame->pts);
+    select->var_values[VAR_T  ] = TS2D(frame->pts) * av_q2d(inlink->time_base);
+    select->var_values[VAR_PREV_PTS] = TS2D(frame->pts);
 
     select->var_values[VAR_INTERLACE_TYPE] =
-        !picref->video->interlaced     ? INTERLACE_TYPE_P :
-        picref->video->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
-    select->var_values[VAR_PICT_TYPE] = picref->video->pict_type;
+        !frame->interlaced_frame     ? INTERLACE_TYPE_P :
+        frame->top_field_first ? INTERLACE_TYPE_T : INTERLACE_TYPE_B;
+    select->var_values[VAR_PICT_TYPE] = frame->pict_type;
 
     res = av_expr_eval(select->expr, select->var_values, NULL);
     av_log(inlink->dst, AV_LOG_DEBUG,
-           "n:%d pts:%d t:%f pos:%d interlace_type:%c key:%d pict_type:%c "
+           "n:%d pts:%d t:%f interlace_type:%c key:%d pict_type:%c "
            "-> select:%f\n",
            (int)select->var_values[VAR_N],
            (int)select->var_values[VAR_PTS],
            select->var_values[VAR_T],
-           (int)select->var_values[VAR_POS],
            select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_P ? 'P' :
            select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_T ? 'T' :
            select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_B ? 'B' : '?',
@@ -228,7 +229,7 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref)
     return res;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     SelectContext *select = inlink->dst->priv;
 
@@ -239,7 +240,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
             if (!av_fifo_space(select->pending_frames)) {
                 av_log(inlink->dst, AV_LOG_ERROR,
                        "Buffering limit reached, cannot cache more frames\n");
-                avfilter_unref_bufferp(&frame);
+                av_frame_free(&frame);
             } else
                 av_fifo_generic_write(select->pending_frames, &frame,
                                       sizeof(frame), NULL);
@@ -248,7 +249,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
         return ff_filter_frame(inlink->dst->outputs[0], frame);
     }
 
-    avfilter_unref_bufferp(&frame);
+    av_frame_free(&frame);
     return 0;
 }
 
@@ -260,10 +261,10 @@ static int request_frame(AVFilterLink *outlink)
     select->select = 0;
 
     if (av_fifo_size(select->pending_frames)) {
-        AVFilterBufferRef *picref;
+        AVFrame *frame;
 
-        av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL);
-        return ff_filter_frame(outlink, picref);
+        av_fifo_generic_read(select->pending_frames, &frame, sizeof(frame), NULL);
+        return ff_filter_frame(outlink, frame);
     }
 
     while (!select->select) {
@@ -294,24 +295,38 @@ static int poll_frame(AVFilterLink *outlink)
         select->cache_frames = 0;
     }
 
-    return av_fifo_size(select->pending_frames)/sizeof(AVFilterBufferRef *);
+    return av_fifo_size(select->pending_frames)/sizeof(AVFrame*);
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
     SelectContext *select = ctx->priv;
-    AVFilterBufferRef *picref;
+    AVFrame *frame;
 
     av_expr_free(select->expr);
     select->expr = NULL;
 
     while (select->pending_frames &&
-           av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL) == sizeof(picref))
-        avfilter_unref_buffer(picref);
+           av_fifo_generic_read(select->pending_frames, &frame, sizeof(frame), NULL) == sizeof(frame))
+        av_frame_free(&frame);
     av_fifo_free(select->pending_frames);
     select->pending_frames = NULL;
 }
 
+#define OFFSET(x) offsetof(SelectContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "expr", "An expression to use for selecting frames", OFFSET(expr_str), AV_OPT_TYPE_STRING, { .str = "1" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass select_class = {
+    .class_name = "select",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_select_inputs[] = {
     {
         .name             = "default",
@@ -333,13 +348,14 @@ static const AVFilterPad avfilter_vf_select_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_select = {
+AVFilter ff_vf_select = {
     .name      = "select",
     .description = NULL_IF_CONFIG_SMALL("Select frames to pass in output."),
     .init      = init,
     .uninit    = uninit,
 
     .priv_size = sizeof(SelectContext),
+    .priv_class = &select_class,
 
     .inputs    = avfilter_vf_select_inputs,
     .outputs   = avfilter_vf_select_outputs,
diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c
deleted file mode 100644
index 0c4881e..0000000
--- a/libavfilter/vf_setpts.c
+++ /dev/null
@@ -1,173 +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 filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
-{
-    SetPTSContext *setpts = inlink->dst->priv;
-    int64_t in_pts = frame->pts;
-    double d;
-
-    if (isnan(setpts->var_values[VAR_STARTPTS]))
-        setpts->var_values[VAR_STARTPTS] = TS2D(frame->pts);
-
-    setpts->var_values[VAR_INTERLACED] = frame->video->interlaced;
-    setpts->var_values[VAR_PTS       ] = TS2D(frame->pts);
-    setpts->var_values[VAR_POS       ] = frame->pos == -1 ? NAN : frame->pos;
-
-    d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
-    frame->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],
-           frame->pos, in_pts, in_pts * av_q2d(inlink->time_base),
-           frame->pts, frame->pts * av_q2d(inlink->time_base));
-#endif
-
-
-    setpts->var_values[VAR_N] += 1.0;
-    setpts->var_values[VAR_PREV_INPTS ] = TS2D(in_pts);
-    setpts->var_values[VAR_PREV_OUTPTS] = TS2D(frame->pts);
-    return ff_filter_frame(inlink->dst->outputs[0], frame);
-}
-
-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,
-        .filter_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,
-};
diff --git a/libavfilter/vf_settb.c b/libavfilter/vf_settb.c
index a572072..87b60a7 100644
--- a/libavfilter/vf_settb.c
+++ b/libavfilter/vf_settb.c
@@ -30,6 +30,7 @@
 #include "libavutil/eval.h"
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 #include "libavutil/rational.h"
 #include "avfilter.h"
 #include "internal.h"
@@ -54,21 +55,11 @@ enum var_name {
 };
 
 typedef struct {
-    char tb_expr[256];
+    const AVClass *class;
+    char *tb_expr;
     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;
@@ -108,7 +99,7 @@ static int config_output_props(AVFilterLink *outlink)
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
     AVFilterLink *outlink = ctx->outputs[0];
@@ -124,6 +115,20 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
     return ff_filter_frame(outlink, frame);
 }
 
+#define OFFSET(x) offsetof(SetTBContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "expr", "Expression determining the output timebase", OFFSET(tb_expr), AV_OPT_TYPE_STRING, { .str = "intb" }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass settb_class = {
+    .class_name = "settb",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_settb_inputs[] = {
     {
         .name             = "default",
@@ -143,12 +148,12 @@ static const AVFilterPad avfilter_vf_settb_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_settb = {
+AVFilter ff_vf_settb = {
     .name      = "settb",
     .description = NULL_IF_CONFIG_SMALL("Set timebase for the output link."),
-    .init      = init,
 
     .priv_size = sizeof(SetTBContext),
+    .priv_class = &settb_class,
 
     .inputs    = avfilter_vf_settb_inputs,
 
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index c89b028..e89ffe0 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -34,14 +34,7 @@ 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_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *ctx = inlink->dst;
     ShowInfoContext *showinfo = ctx->priv;
@@ -50,7 +43,7 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
     int i, plane, vsub = desc->log2_chroma_h;
 
     for (plane = 0; frame->data[plane] && plane < 4; plane++) {
-        size_t linesize = av_image_get_linesize(frame->format, frame->video->w, plane);
+        size_t linesize = av_image_get_linesize(frame->format, frame->width, plane);
         uint8_t *data = frame->data[plane];
         int h = plane == 1 || plane == 2 ? inlink->h >> vsub : inlink->h;
 
@@ -62,18 +55,18 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *frame)
     }
 
     av_log(ctx, AV_LOG_INFO,
-           "n:%d pts:%"PRId64" pts_time:%f pos:%"PRId64" "
+           "n:%d pts:%"PRId64" pts_time:%f "
            "fmt:%s sar:%d/%d s:%dx%d i:%c iskey:%d type:%c "
            "checksum:%u plane_checksum:[%u %u %u %u]\n",
            showinfo->frame,
-           frame->pts, frame->pts * av_q2d(inlink->time_base), frame->pos,
+           frame->pts, frame->pts * av_q2d(inlink->time_base),
            desc->name,
-           frame->video->pixel_aspect.num, frame->video->pixel_aspect.den,
-           frame->video->w, frame->video->h,
-           !frame->video->interlaced     ? 'P' :         /* Progressive  */
-           frame->video->top_field_first ? 'T' : 'B',    /* Top / Bottom */
-           frame->video->key_frame,
-           av_get_picture_type_char(frame->video->pict_type),
+           frame->sample_aspect_ratio.num, frame->sample_aspect_ratio.den,
+           frame->width, frame->height,
+           !frame->interlaced_frame ? 'P' :         /* Progressive  */
+           frame->top_field_first   ? 'T' : 'B',    /* Top / Bottom */
+           frame->key_frame,
+           av_get_picture_type_char(frame->pict_type),
            checksum, plane_checksum[0], plane_checksum[1], plane_checksum[2], plane_checksum[3]);
 
     showinfo->frame++;
@@ -86,7 +79,6 @@ static const AVFilterPad avfilter_vf_showinfo_inputs[] = {
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
         .filter_frame     = filter_frame,
-        .min_perms        = AV_PERM_READ,
     },
     { NULL }
 };
@@ -99,12 +91,11 @@ static const AVFilterPad avfilter_vf_showinfo_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_showinfo = {
+AVFilter ff_vf_showinfo = {
     .name        = "showinfo",
     .description = NULL_IF_CONFIG_SMALL("Show textual information for each video frame."),
 
     .priv_size = sizeof(ShowInfoContext),
-    .init      = init,
 
     .inputs    = avfilter_vf_showinfo_inputs,
 
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index d7a1739..06a88c7 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -31,38 +31,27 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
+#include "libavutil/opt.h"
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
+enum TransposeDir {
+    TRANSPOSE_CCLOCK_FLIP,
+    TRANSPOSE_CLOCK,
+    TRANSPOSE_CCLOCK,
+    TRANSPOSE_CLOCK_FLIP,
+};
+
 typedef struct {
+    const AVClass *class;
     int hsub, vsub;
     int pixsteps[4];
 
-    /* 0    Rotate by 90 degrees counterclockwise and vflip. */
-    /* 1    Rotate by 90 degrees clockwise.                  */
-    /* 2    Rotate by 90 degrees counterclockwise.           */
-    /* 3    Rotate by 90 degrees clockwise and vflip.        */
-    int dir;
+    enum TransposeDir dir;
 } TransContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    TransContext *trans = ctx->priv;
-    trans->dir = 0;
-
-    if (args)
-        sscanf(args, "%d", &trans->dir);
-
-    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;
-}
-
 static int query_formats(AVFilterContext *ctx)
 {
     enum AVPixelFormat pix_fmts[] = {
@@ -121,35 +110,35 @@ static int config_props_output(AVFilterLink *outlink)
     return 0;
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 {
     AVFilterLink *outlink = inlink->dst->outputs[0];
     TransContext *trans = inlink->dst->priv;
-    AVFilterBufferRef *out;
+    AVFrame *out;
     int plane;
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
 
     out->pts = in->pts;
 
-    if (in->video->pixel_aspect.num == 0) {
-        out->video->pixel_aspect = in->video->pixel_aspect;
+    if (in->sample_aspect_ratio.num == 0) {
+        out->sample_aspect_ratio = in->sample_aspect_ratio;
     } else {
-        out->video->pixel_aspect.num = in->video->pixel_aspect.den;
-        out->video->pixel_aspect.den = in->video->pixel_aspect.num;
+        out->sample_aspect_ratio.num = in->sample_aspect_ratio.den;
+        out->sample_aspect_ratio.den = in->sample_aspect_ratio.num;
     }
 
     for (plane = 0; out->data[plane]; plane++) {
         int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
         int vsub = plane == 1 || plane == 2 ? trans->vsub : 0;
         int pixstep = trans->pixsteps[plane];
-        int inh  = in->video->h>>vsub;
-        int outw = out->video->w>>hsub;
-        int outh = out->video->h>>vsub;
+        int inh  = in->height  >> vsub;
+        int outw = out->width  >> hsub;
+        int outh = out->height >> vsub;
         uint8_t *dst, *src;
         int dstlinesize, srclinesize;
         int x, y;
@@ -194,16 +183,34 @@ static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
         }
     }
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(TransContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "dir", "Transpose direction", OFFSET(dir), AV_OPT_TYPE_INT, { .i64 = TRANSPOSE_CCLOCK_FLIP },
+        TRANSPOSE_CCLOCK_FLIP, TRANSPOSE_CLOCK_FLIP, FLAGS, "dir" },
+        { "cclock_flip", "counter-clockwise with vertical flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .unit = "dir" },
+        { "clock",       "clockwise",                            0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK       }, .unit = "dir" },
+        { "cclock",      "counter-clockwise",                    0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK      }, .unit = "dir" },
+        { "clock_flip",  "clockwise with vertical flip",         0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP  }, .unit = "dir" },
+    { NULL },
+};
+
+static const AVClass transpose_class = {
+    .class_name = "transpose",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_transpose_inputs[] = {
     {
         .name        = "default",
         .type        = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
-        .min_perms   = AV_PERM_READ,
     },
     { NULL }
 };
@@ -217,12 +224,12 @@ static const AVFilterPad avfilter_vf_transpose_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_transpose = {
+AVFilter ff_vf_transpose = {
     .name      = "transpose",
     .description = NULL_IF_CONFIG_SMALL("Transpose input video."),
 
-    .init = init,
     .priv_size = sizeof(TransContext),
+    .priv_class = &transpose_class,
 
     .query_formats = query_formats,
 
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index b446937..842ec7e 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -42,6 +42,7 @@
 #include "video.h"
 #include "libavutil/common.h"
 #include "libavutil/mem.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 
 #define MIN_SIZE 3
@@ -62,6 +63,9 @@ typedef struct FilterParam {
 } FilterParam;
 
 typedef struct {
+    const AVClass *class;
+    int lmsize_x, lmsize_y, cmsize_x, cmsize_y;
+    float lamount, camount;
     FilterParam luma;   ///< luma parameters (width, height, amount)
     FilterParam chroma; ///< chroma parameters (width, height, amount)
     int hsub, vsub;
@@ -120,7 +124,7 @@ static void apply_unsharp(      uint8_t *dst, int dst_stride,
     }
 }
 
-static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double amount)
+static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, float amount)
 {
     fp->msize_x = msize_x;
     fp->msize_y = msize_y;
@@ -132,27 +136,12 @@ static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double a
     fp->halfscale = 1 << (fp->scalebits - 1);
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     UnsharpContext *unsharp = ctx->priv;
-    int lmsize_x = 5, cmsize_x = 5;
-    int lmsize_y = 5, cmsize_y = 5;
-    double lamount = 1.0f, camount = 0.0f;
-
-    if (args)
-        sscanf(args, "%d:%d:%lf:%d:%d:%lf", &lmsize_x, &lmsize_y, &lamount,
-                                            &cmsize_x, &cmsize_y, &camount);
-
-    if ((lamount && (lmsize_x < 2 || lmsize_y < 2)) ||
-        (camount && (cmsize_x < 2 || cmsize_y < 2))) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid value <2 for lmsize_x:%d or lmsize_y:%d or cmsize_x:%d or cmsize_y:%d\n",
-               lmsize_x, lmsize_y, cmsize_x, cmsize_y);
-        return AVERROR(EINVAL);
-    }
 
-    set_filter_param(&unsharp->luma,   lmsize_x, lmsize_y, lamount);
-    set_filter_param(&unsharp->chroma, cmsize_x, cmsize_y, camount);
+    set_filter_param(&unsharp->luma,   unsharp->lmsize_x, unsharp->lmsize_y, unsharp->lamount);
+    set_filter_param(&unsharp->chroma, unsharp->cmsize_x, unsharp->cmsize_y, unsharp->camount);
 
     return 0;
 }
@@ -214,36 +203,54 @@ static av_cold void uninit(AVFilterContext *ctx)
     free_filter_param(&unsharp->chroma);
 }
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *in)
+static int filter_frame(AVFilterLink *link, AVFrame *in)
 {
     UnsharpContext *unsharp = link->dst->priv;
     AVFilterLink *outlink   = link->dst->outputs[0];
-    AVFilterBufferRef *out;
+    AVFrame *out;
     int cw = SHIFTUP(link->w, unsharp->hsub);
     int ch = SHIFTUP(link->h, unsharp->vsub);
 
-    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out) {
-        avfilter_unref_bufferp(&in);
+        av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
-    avfilter_copy_buffer_ref_props(out, in);
+    av_frame_copy_props(out, in);
 
     apply_unsharp(out->data[0], out->linesize[0], in->data[0], in->linesize[0], link->w, link->h, &unsharp->luma);
     apply_unsharp(out->data[1], out->linesize[1], in->data[1], in->linesize[1], cw,      ch,      &unsharp->chroma);
     apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw,      ch,      &unsharp->chroma);
 
-    avfilter_unref_bufferp(&in);
+    av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
 
+#define OFFSET(x) offsetof(UnsharpContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "luma_msize_x",   "luma matrix horizontal size",   OFFSET(lmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "luma_msize_y",   "luma matrix vertical size",     OFFSET(lmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "luma_amount",    "luma effect strength",          OFFSET(lamount),  AV_OPT_TYPE_FLOAT, { .dbl = 1 },       -2,        5, FLAGS },
+    { "chroma_msize_x", "chroma matrix horizontal size", OFFSET(cmsize_x), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "chroma_msize_y", "chroma matrix vertical size",   OFFSET(cmsize_y), AV_OPT_TYPE_INT,   { .i64 = 5 }, MIN_SIZE, MAX_SIZE, FLAGS },
+    { "chroma_amount",  "chroma effect strength",        OFFSET(camount),  AV_OPT_TYPE_FLOAT, { .dbl = 0 },       -2,        5, FLAGS },
+    { NULL },
+};
+
+static const AVClass unsharp_class = {
+    .class_name = "unsharp",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_unsharp_inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
         .filter_frame = filter_frame,
         .config_props = config_props,
-        .min_perms    = AV_PERM_READ,
     },
     { NULL }
 };
@@ -256,11 +263,12 @@ static const AVFilterPad avfilter_vf_unsharp_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_unsharp = {
+AVFilter ff_vf_unsharp = {
     .name      = "unsharp",
     .description = NULL_IF_CONFIG_SMALL("Sharpen or blur the input video."),
 
     .priv_size = sizeof(UnsharpContext),
+    .priv_class = &unsharp_class,
 
     .init = init,
     .uninit = uninit,
diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c
index 5e6e965..ced946e 100644
--- a/libavfilter/vf_vflip.c
+++ b/libavfilter/vf_vflip.c
@@ -43,33 +43,29 @@ static int config_input(AVFilterLink *link)
     return 0;
 }
 
-static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
-                                        int w, int h)
+static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h)
 {
     FlipContext *flip = link->dst->priv;
-    AVFilterBufferRef *picref;
+    AVFrame *frame;
     int i;
 
-    if (!(perms & AV_PERM_NEG_LINESIZES))
-        return ff_default_get_video_buffer(link, perms, w, h);
-
-    picref = ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
-    if (!picref)
+    frame = ff_get_video_buffer(link->dst->outputs[0], w, h);
+    if (!frame)
         return NULL;
 
     for (i = 0; i < 4; i ++) {
         int vsub = i == 1 || i == 2 ? flip->vsub : 0;
 
-        if (picref->data[i]) {
-            picref->data[i] += ((h >> vsub)-1) * picref->linesize[i];
-            picref->linesize[i] = -picref->linesize[i];
+        if (frame->data[i]) {
+            frame->data[i] += ((h >> vsub) - 1) * frame->linesize[i];
+            frame->linesize[i] = -frame->linesize[i];
         }
     }
 
-    return picref;
+    return frame;
 }
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
     FlipContext *flip = link->dst->priv;
     int i;
@@ -104,7 +100,7 @@ static const AVFilterPad avfilter_vf_vflip_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_vflip = {
+AVFilter ff_vf_vflip = {
     .name      = "vflip",
     .description = NULL_IF_CONFIG_SMALL("Flip the input video vertically."),
 
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index db9c71c..fb5d641 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -21,6 +21,7 @@
 
 #include "libavutil/cpu.h"
 #include "libavutil/common.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
 #include "formats.h"
@@ -31,18 +32,27 @@
 #undef NDEBUG
 #include <assert.h>
 
-#define PERM_RWP AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE
+typedef struct ThreadData {
+    AVFrame *frame;
+    int plane;
+    int w, h;
+    int parity;
+    int tff;
+} ThreadData;
 
 #define CHECK(j)\
-    {   int score = FFABS(cur[mrefs-1+(j)] - cur[prefs-1-(j)])\
+    {   int score = FFABS(cur[mrefs - 1 + (j)] - cur[prefs - 1 - (j)])\
                   + FFABS(cur[mrefs  +(j)] - cur[prefs  -(j)])\
-                  + FFABS(cur[mrefs+1+(j)] - cur[prefs+1-(j)]);\
+                  + FFABS(cur[mrefs + 1 + (j)] - cur[prefs + 1 - (j)]);\
         if (score < spatial_score) {\
             spatial_score= score;\
             spatial_pred= (cur[mrefs  +(j)] + cur[prefs  -(j)])>>1;\
 
-#define FILTER \
-    for (x = 0;  x < w; x++) { \
+/* The is_not_edge argument here controls when the code will enter a branch
+ * which reads up to and including x-3 and x+3. */
+
+#define FILTER(start, end, is_not_edge) \
+    for (x = start;  x < end; x++) { \
         int c = cur[mrefs]; \
         int d = (prev2[0] + next2[0])>>1; \
         int e = cur[prefs]; \
@@ -51,11 +61,13 @@
         int temporal_diff2 =(FFABS(next[mrefs] - c) + FFABS(next[prefs] - e) )>>1; \
         int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); \
         int spatial_pred = (c+e) >> 1; \
-        int spatial_score = FFABS(cur[mrefs - 1] - cur[prefs - 1]) + FFABS(c-e) \
-                          + FFABS(cur[mrefs + 1] - cur[prefs + 1]) - 1; \
  \
-        CHECK(-1) CHECK(-2) }} }} \
-        CHECK( 1) CHECK( 2) }} }} \
+        if (is_not_edge) {\
+            int spatial_score = FFABS(cur[mrefs - 1] - cur[prefs - 1]) + FFABS(c-e) \
+                              + FFABS(cur[mrefs + 1] - cur[prefs + 1]) - 1; \
+            CHECK(-1) CHECK(-2) }} }} \
+            CHECK( 1) CHECK( 2) }} }} \
+        }\
  \
         if (mode < 2) { \
             int b = (prev2[2 * mrefs] + next2[2 * mrefs])>>1; \
@@ -81,87 +93,176 @@
         next2++; \
     }
 
-static void filter_line_c(uint8_t *dst,
-                          uint8_t *prev, uint8_t *cur, uint8_t *next,
+static void filter_line_c(void *dst1,
+                          void *prev1, void *cur1, void *next1,
                           int w, int prefs, int mrefs, int parity, int mode)
 {
+    uint8_t *dst  = dst1;
+    uint8_t *prev = prev1;
+    uint8_t *cur  = cur1;
+    uint8_t *next = next1;
+    int x;
+    uint8_t *prev2 = parity ? prev : cur ;
+    uint8_t *next2 = parity ? cur  : next;
+
+    /* The function is called with the pointers already pointing to data[3] and
+     * with 6 subtracted from the width.  This allows the FILTER macro to be
+     * called so that it processes all the pixels normally.  A constant value of
+     * true for is_not_edge lets the compiler ignore the if statement. */
+    FILTER(0, w, 1)
+}
+
+static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1,
+                         int w, int prefs, int mrefs, int parity, int mode)
+{
+    uint8_t *dst  = dst1;
+    uint8_t *prev = prev1;
+    uint8_t *cur  = cur1;
+    uint8_t *next = next1;
     int x;
     uint8_t *prev2 = parity ? prev : cur ;
     uint8_t *next2 = parity ? cur  : next;
 
-    FILTER
+    /* Only edge pixels need to be processed here.  A constant value of false
+     * for is_not_edge should let the compiler ignore the whole branch. */
+    FILTER(0, 3, 0)
+
+    dst  = (uint8_t*)dst1  + w - 3;
+    prev = (uint8_t*)prev1 + w - 3;
+    cur  = (uint8_t*)cur1  + w - 3;
+    next = (uint8_t*)next1 + w - 3;
+    prev2 = (uint8_t*)(parity ? prev : cur);
+    next2 = (uint8_t*)(parity ? cur  : next);
+
+    FILTER(w - 3, w, 0)
 }
 
-static void filter_line_c_16bit(uint16_t *dst,
-                                uint16_t *prev, uint16_t *cur, uint16_t *next,
+
+static void filter_line_c_16bit(void *dst1,
+                                void *prev1, void *cur1, void *next1,
                                 int w, int prefs, int mrefs, int parity,
                                 int mode)
 {
+    uint16_t *dst  = dst1;
+    uint16_t *prev = prev1;
+    uint16_t *cur  = cur1;
+    uint16_t *next = next1;
+    int x;
+    uint16_t *prev2 = parity ? prev : cur ;
+    uint16_t *next2 = parity ? cur  : next;
+    mrefs /= 2;
+    prefs /= 2;
+
+    FILTER(0, w, 1)
+}
+
+static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1,
+                               int w, int prefs, int mrefs, int parity, int mode)
+{
+    uint16_t *dst  = dst1;
+    uint16_t *prev = prev1;
+    uint16_t *cur  = cur1;
+    uint16_t *next = next1;
     int x;
     uint16_t *prev2 = parity ? prev : cur ;
     uint16_t *next2 = parity ? cur  : next;
     mrefs /= 2;
     prefs /= 2;
 
-    FILTER
+    FILTER(0, 3, 0)
+
+    dst   = (uint16_t*)dst1  + w - 3;
+    prev  = (uint16_t*)prev1 + w - 3;
+    cur   = (uint16_t*)cur1  + w - 3;
+    next  = (uint16_t*)next1 + w - 3;
+    prev2 = (uint16_t*)(parity ? prev : cur);
+    next2 = (uint16_t*)(parity ? cur  : next);
+
+    FILTER(w - 3, w, 0)
 }
 
-static void filter(AVFilterContext *ctx, AVFilterBufferRef *dstpic,
+static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    YADIFContext *s = ctx->priv;
+    ThreadData *td  = arg;
+    int refs = s->cur->linesize[td->plane];
+    int df = (s->csp->comp[td->plane].depth_minus1 + 8) / 8;
+    int pix_3 = 3 * df;
+    int slice_h = td->h / nb_jobs;
+    int slice_start = jobnr * slice_h;
+    int slice_end   = (jobnr == nb_jobs - 1) ? td->h : (jobnr + 1) * slice_h;
+    int y;
+
+    /* filtering reads 3 pixels to the left/right; to avoid invalid reads,
+     * we need to call the c variant which avoids this for border pixels
+     */
+    for (y = slice_start; y < slice_end; y++) {
+        if ((y ^ td->parity) & 1) {
+            uint8_t *prev = &s->prev->data[td->plane][y * refs];
+            uint8_t *cur  = &s->cur ->data[td->plane][y * refs];
+            uint8_t *next = &s->next->data[td->plane][y * refs];
+            uint8_t *dst  = &td->frame->data[td->plane][y * td->frame->linesize[td->plane]];
+            int     mode  = y == 1 || y + 2 == td->h ? 2 : s->mode;
+            s->filter_line(dst + pix_3, prev + pix_3, cur + pix_3,
+                           next + pix_3, td->w - 6,
+                           y + 1 < td->h ? refs : -refs,
+                           y ? -refs : refs,
+                           td->parity ^ td->tff, mode);
+            s->filter_edges(dst, prev, cur, next, td->w,
+                            y + 1 < td->h ? refs : -refs,
+                            y ? -refs : refs,
+                            td->parity ^ td->tff, mode);
+        } else {
+            memcpy(&td->frame->data[td->plane][y * td->frame->linesize[td->plane]],
+                   &s->cur->data[td->plane][y * refs], td->w * df);
+        }
+    }
+    return 0;
+}
+
+static void filter(AVFilterContext *ctx, AVFrame *dstpic,
                    int parity, int tff)
 {
     YADIFContext *yadif = ctx->priv;
-    int y, i;
+    ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff };
+    int i;
 
     for (i = 0; i < yadif->csp->nb_components; i++) {
-        int w = dstpic->video->w;
-        int h = dstpic->video->h;
-        int refs = yadif->cur->linesize[i];
-        int df = (yadif->csp->comp[i].depth_minus1 + 8) / 8;
+        int w = dstpic->width;
+        int h = dstpic->height;
 
         if (i == 1 || i == 2) {
-        /* Why is this not part of the per-plane description thing? */
             w >>= yadif->csp->log2_chroma_w;
             h >>= yadif->csp->log2_chroma_h;
         }
 
-        for (y = 0; y < h; y++) {
-            if ((y ^ parity) & 1) {
-                uint8_t *prev = &yadif->prev->data[i][y * refs];
-                uint8_t *cur  = &yadif->cur ->data[i][y * refs];
-                uint8_t *next = &yadif->next->data[i][y * refs];
-                uint8_t *dst  = &dstpic->data[i][y * dstpic->linesize[i]];
-                int     mode  = y == 1 || y + 2 == h ? 2 : yadif->mode;
-                yadif->filter_line(dst, prev, cur, next, w,
-                                   y + 1 < h ? refs : -refs,
-                                   y ? -refs : refs,
-                                   parity ^ tff, mode);
-            } else {
-                memcpy(&dstpic->data[i][y * dstpic->linesize[i]],
-                       &yadif->cur->data[i][y * refs], w * df);
-            }
-        }
+
+        td.w       = w;
+        td.h       = h;
+        td.plane   = i;
+
+        ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ctx->graph->nb_threads));
     }
 
     emms_c();
 }
 
-static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
-                                           int w, int h)
+static AVFrame *get_video_buffer(AVFilterLink *link, int w, int h)
 {
-    AVFilterBufferRef *picref;
+    AVFrame *frame;
     int width  = FFALIGN(w, 32);
     int height = FFALIGN(h + 2, 32);
     int i;
 
-    picref = ff_default_get_video_buffer(link, perms, width, height);
+    frame = ff_default_get_video_buffer(link, width, height);
 
-    picref->video->w = w;
-    picref->video->h = h;
+    frame->width  = w;
+    frame->height = h;
 
     for (i = 0; i < 3; i++)
-        picref->data[i] += picref->linesize[i];
+        frame->data[i] += frame->linesize[i];
 
-    return picref;
+    return frame;
 }
 
 static int return_frame(AVFilterContext *ctx, int is_second)
@@ -171,26 +272,21 @@ static int return_frame(AVFilterContext *ctx, int is_second)
     int tff, ret;
 
     if (yadif->parity == -1) {
-        tff = yadif->cur->video->interlaced ?
-              yadif->cur->video->top_field_first : 1;
+        tff = yadif->cur->interlaced_frame ?
+              yadif->cur->top_field_first : 1;
     } else {
         tff = yadif->parity ^ 1;
     }
 
     if (is_second) {
-        yadif->out = ff_get_video_buffer(link, PERM_RWP, link->w, link->h);
+        yadif->out = ff_get_video_buffer(link, link->w, link->h);
         if (!yadif->out)
             return AVERROR(ENOMEM);
 
-        avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
-        yadif->out->video->interlaced = 0;
+        av_frame_copy_props(yadif->out, yadif->cur);
+        yadif->out->interlaced_frame = 0;
     }
 
-    if (!yadif->csp)
-        yadif->csp = av_pix_fmt_desc_get(link->format);
-    if (yadif->csp->comp[0].depth_minus1 / 8 == 1)
-        yadif->filter_line = filter_line_c_16bit;
-
     filter(ctx, yadif->out, tff ^ !is_second, tff);
 
     if (is_second) {
@@ -209,7 +305,7 @@ static int return_frame(AVFilterContext *ctx, int is_second)
     return ret;
 }
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
     AVFilterContext *ctx = link->dst;
     YADIFContext *yadif = ctx->priv;
@@ -218,36 +314,35 @@ static int filter_frame(AVFilterLink *link, AVFilterBufferRef *picref)
         return_frame(ctx, 1);
 
     if (yadif->prev)
-        avfilter_unref_buffer(yadif->prev);
+        av_frame_free(&yadif->prev);
     yadif->prev = yadif->cur;
     yadif->cur  = yadif->next;
-    yadif->next = picref;
+    yadif->next = frame;
 
     if (!yadif->cur)
         return 0;
 
-    if (yadif->auto_enable && !yadif->cur->video->interlaced) {
-        yadif->out  = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
+    if (yadif->auto_enable && !yadif->cur->interlaced_frame) {
+        yadif->out  = av_frame_clone(yadif->cur);
         if (!yadif->out)
             return AVERROR(ENOMEM);
 
-        avfilter_unref_bufferp(&yadif->prev);
+        av_frame_free(&yadif->prev);
         if (yadif->out->pts != AV_NOPTS_VALUE)
             yadif->out->pts *= 2;
         return ff_filter_frame(ctx->outputs[0], yadif->out);
     }
 
     if (!yadif->prev &&
-        !(yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ)))
+        !(yadif->prev = av_frame_clone(yadif->cur)))
         return AVERROR(ENOMEM);
 
-    yadif->out = ff_get_video_buffer(ctx->outputs[0], PERM_RWP,
-                                     link->w, link->h);
+    yadif->out = ff_get_video_buffer(ctx->outputs[0], link->w, link->h);
     if (!yadif->out)
         return AVERROR(ENOMEM);
 
-    avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);
-    yadif->out->video->interlaced = 0;
+    av_frame_copy_props(yadif->out, yadif->cur);
+    yadif->out->interlaced_frame = 0;
 
     if (yadif->out->pts != AV_NOPTS_VALUE)
         yadif->out->pts *= 2;
@@ -274,8 +369,7 @@ static int request_frame(AVFilterLink *link)
         ret  = ff_request_frame(link->src->inputs[0]);
 
         if (ret == AVERROR_EOF && yadif->next) {
-            AVFilterBufferRef *next =
-                avfilter_ref_buffer(yadif->next, AV_PERM_READ);
+            AVFrame *next = av_frame_clone(yadif->next);
 
             if (!next)
                 return AVERROR(ENOMEM);
@@ -314,7 +408,7 @@ static int poll_frame(AVFilterLink *link)
     }
     assert(yadif->next || !val);
 
-    if (yadif->auto_enable && yadif->next && !yadif->next->video->interlaced)
+    if (yadif->auto_enable && yadif->next && !yadif->next->interlaced_frame)
         return val;
 
     return val * ((yadif->mode&1)+1);
@@ -324,9 +418,9 @@ static av_cold void uninit(AVFilterContext *ctx)
 {
     YADIFContext *yadif = ctx->priv;
 
-    if (yadif->prev) avfilter_unref_bufferp(&yadif->prev);
-    if (yadif->cur ) avfilter_unref_bufferp(&yadif->cur );
-    if (yadif->next) avfilter_unref_bufferp(&yadif->next);
+    if (yadif->prev) av_frame_free(&yadif->prev);
+    if (yadif->cur ) av_frame_free(&yadif->cur );
+    if (yadif->next) av_frame_free(&yadif->next);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -359,40 +453,49 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    YADIFContext *yadif = ctx->priv;
-
-    yadif->mode = 0;
-    yadif->parity = -1;
-    yadif->auto_enable = 0;
-    yadif->csp = NULL;
-
-    if (args)
-        sscanf(args, "%d:%d:%d",
-               &yadif->mode, &yadif->parity, &yadif->auto_enable);
-
-    yadif->filter_line = filter_line_c;
-
-    if (ARCH_X86)
-        ff_yadif_init_x86(yadif);
-
-    av_log(ctx, AV_LOG_VERBOSE, "mode:%d parity:%d auto_enable:%d\n",
-           yadif->mode, yadif->parity, yadif->auto_enable);
-
-    return 0;
-}
-
 static int config_props(AVFilterLink *link)
 {
+    YADIFContext *s = link->src->priv;
+
     link->time_base.num = link->src->inputs[0]->time_base.num;
     link->time_base.den = link->src->inputs[0]->time_base.den * 2;
     link->w             = link->src->inputs[0]->w;
     link->h             = link->src->inputs[0]->h;
 
+    s->csp = av_pix_fmt_desc_get(link->format);
+    if (s->csp->comp[0].depth_minus1 / 8 == 1) {
+        s->filter_line  = filter_line_c_16bit;
+        s->filter_edges = filter_edges_16bit;
+    } else {
+        s->filter_line  = filter_line_c;
+        s->filter_edges = filter_edges;
+
+        if (ARCH_X86)
+            ff_yadif_init_x86(s);
+    }
+
     return 0;
 }
 
+#define OFFSET(x) offsetof(YADIFContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "mode",   NULL, OFFSET(mode),        AV_OPT_TYPE_INT, { .i64 = 0  },  0, 3, FLAGS },
+    { "parity", NULL, OFFSET(parity),      AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, FLAGS, "parity" },
+        { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, .unit = "parity" },
+        { "tff",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0  }, .unit = "parity" },
+        { "bff",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1  }, .unit = "parity" },
+    { "auto",   NULL, OFFSET(auto_enable), AV_OPT_TYPE_INT, { .i64 = 0  },  0, 1, FLAGS },
+    { NULL },
+};
+
+static const AVClass yadif_class = {
+    .class_name = "yadif",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vf_yadif_inputs[] = {
     {
         .name             = "default",
@@ -414,16 +517,18 @@ static const AVFilterPad avfilter_vf_yadif_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vf_yadif = {
+AVFilter ff_vf_yadif = {
     .name          = "yadif",
     .description   = NULL_IF_CONFIG_SMALL("Deinterlace the input image"),
 
     .priv_size     = sizeof(YADIFContext),
-    .init          = init,
+    .priv_class    = &yadif_class,
     .uninit        = uninit,
     .query_formats = query_formats,
 
     .inputs    = avfilter_vf_yadif_inputs,
 
     .outputs   = avfilter_vf_yadif_outputs,
+
+    .flags     = AVFILTER_FLAG_SLICE_THREADS,
 };
diff --git a/libavfilter/video.c b/libavfilter/video.c
index cb68ca4..23bf867 100644
--- a/libavfilter/video.c
+++ b/libavfilter/video.c
@@ -19,6 +19,7 @@
 #include <string.h>
 #include <stdio.h>
 
+#include "libavutil/buffer.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mem.h"
 
@@ -26,77 +27,34 @@
 #include "internal.h"
 #include "video.h"
 
-#ifdef DEBUG
-static char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
+AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h)
 {
-    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);
+    return ff_get_video_buffer(link->dst->outputs[0], 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)
+AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h)
 {
-    int linesize[4];
-    uint8_t *data[4];
-    AVFilterBufferRef *picref = NULL;
+    AVFrame *frame = av_frame_alloc();
+    int ret;
 
-    // +2 is needed for swscaler, +16 to be SIMD-friendly
-    if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0)
+    if (!frame)
         return NULL;
 
-    picref = avfilter_get_video_buffer_ref_from_arrays(data, linesize,
-                                                       perms, w, h, link->format);
-    if (!picref) {
-        av_free(data[0]);
-        return NULL;
-    }
+    frame->width  = w;
+    frame->height = h;
+    frame->format = link->format;
 
-    return picref;
+    ret = av_frame_get_buffer(frame, 32);
+    if (ret < 0)
+        av_frame_free(&frame);
+
+    return frame;
 }
 
+#if FF_API_AVFILTERBUFFER
 AVFilterBufferRef *
 avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int perms,
                                           int w, int h, enum AVPixelFormat format)
@@ -141,25 +99,20 @@ fail:
     av_free(pic);
     return NULL;
 }
+#endif
 
-AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
+AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h)
 {
-    AVFilterBufferRef *ret = NULL;
+    AVFrame *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);
 
     if (link->dstpad->get_video_buffer)
-        ret = link->dstpad->get_video_buffer(link, perms, w, h);
+        ret = link->dstpad->get_video_buffer(link, w, h);
 
     if (!ret)
-        ret = ff_default_get_video_buffer(link, perms, w, h);
-
-    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);
+        ret = ff_default_get_video_buffer(link, w, h);
 
     return ret;
 }
diff --git a/libavfilter/video.h b/libavfilter/video.h
index be93810..f7e8e34 100644
--- a/libavfilter/video.h
+++ b/libavfilter/video.h
@@ -21,22 +21,19 @@
 
 #include "avfilter.h"
 
-AVFilterBufferRef *ff_default_get_video_buffer(AVFilterLink *link,
-                                               int perms, int w, int h);
-AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h);
+AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h);
+AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h);
 
 /**
  * Request a picture buffer with a specific set of permissions.
  *
  * @param link  the output link to the filter from which the buffer will
  *              be requested
- * @param perms the required access permissions
  * @param w     the minimum width of the buffer to allocate
  * @param h     the minimum height of the buffer to allocate
  * @return      A reference to the buffer. This must be unreferenced with
  *              avfilter_unref_buffer when you are finished with it.
  */
-AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms,
-                                       int w, int h);
+AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h);
 
 #endif /* AVFILTER_VIDEO_H */
diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c
index 71d2b3e..14b6b12 100644
--- a/libavfilter/vsink_nullsink.c
+++ b/libavfilter/vsink_nullsink.c
@@ -20,9 +20,9 @@
 #include "internal.h"
 #include "libavutil/internal.h"
 
-static int filter_frame(AVFilterLink *link, AVFilterBufferRef *frame)
+static int filter_frame(AVFilterLink *link, AVFrame *frame)
 {
-    avfilter_unref_bufferp(&frame);
+    av_frame_free(&frame);
     return 0;
 }
 
@@ -35,7 +35,7 @@ static const AVFilterPad avfilter_vsink_nullsink_inputs[] = {
     { NULL },
 };
 
-AVFilter avfilter_vsink_nullsink = {
+AVFilter ff_vsink_nullsink = {
     .name        = "nullsink",
     .description = NULL_IF_CONFIG_SMALL("Do absolutely nothing with the input video."),
 
diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c
index c0a4e1c..d72d072 100644
--- a/libavfilter/vsrc_color.c
+++ b/libavfilter/vsrc_color.c
@@ -36,10 +36,12 @@
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/mem.h"
+#include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "drawutils.h"
 
 typedef struct {
+    const AVClass *class;
     int w, h;
     uint8_t color[4];
     AVRational time_base;
@@ -47,34 +49,31 @@ typedef struct {
     int      line_step[4];
     int hsub, vsub;         ///< chroma subsampling values
     uint64_t pts;
+    char *color_str;
+    char *size_str;
+    char *framerate_str;
 } ColorContext;
 
-static av_cold int color_init(AVFilterContext *ctx, const char *args)
+static av_cold int color_init(AVFilterContext *ctx)
 {
     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);
+    if (av_parse_video_size(&color->w, &color->h, color->size_str) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame size: %s\n", color->size_str);
         return AVERROR(EINVAL);
     }
 
-    if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 ||
+    if (av_parse_video_rate(&frame_rate_q, color->framerate_str) < 0 ||
         frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", frame_rate);
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", color->framerate_str);
         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)
+    if ((ret = av_parse_color(color->color, color->color_str, -1, ctx)) < 0)
         return ret;
 
     return 0;
@@ -146,21 +145,36 @@ static int color_config_props(AVFilterLink *inlink)
 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);
+    AVFrame *frame = ff_get_video_buffer(link, color->w, color->h);
 
-    if (!picref)
+    if (!frame)
         return AVERROR(ENOMEM);
 
-    picref->video->pixel_aspect = (AVRational) {1, 1};
-    picref->pts                 = color->pts++;
-    picref->pos                 = -1;
+    frame->sample_aspect_ratio = (AVRational) {1, 1};
+    frame->pts                 = color->pts++;
 
-    ff_draw_rectangle(picref->data, picref->linesize,
+    ff_draw_rectangle(frame->data, frame->linesize,
                       color->line, color->line_step, color->hsub, color->vsub,
                       0, 0, color->w, color->h);
-    return ff_filter_frame(link, picref);
+    return ff_filter_frame(link, frame);
 }
 
+#define OFFSET(x) offsetof(ColorContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "color",     "Output video color",                         OFFSET(color_str),     AV_OPT_TYPE_STRING, { .str = "black"   }, .flags = FLAGS },
+    { "size",      "Output video size (wxh or an abbreviation)", OFFSET(size_str),      AV_OPT_TYPE_STRING, { .str = "320x240" }, .flags = FLAGS },
+    { "framerate", "Output video framerate",                     OFFSET(framerate_str), AV_OPT_TYPE_STRING, { .str = "25"      }, .flags = FLAGS },
+    { NULL },
+};
+
+static const AVClass color_class = {
+    .class_name = "color",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vsrc_color_outputs[] = {
     {
         .name          = "default",
@@ -171,10 +185,11 @@ static const AVFilterPad avfilter_vsrc_color_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_color = {
+AVFilter ff_vsrc_color = {
     .name        = "color",
     .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input, syntax is: [color[:size[:rate]]]"),
 
+    .priv_class = &color_class,
     .priv_size = sizeof(ColorContext),
     .init      = color_init,
     .uninit    = color_uninit,
diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c
index 0023d55..502f360 100644
--- a/libavfilter/vsrc_movie.c
+++ b/libavfilter/vsrc_movie.c
@@ -28,9 +28,10 @@
  * @todo support more than one output stream
  */
 
-/* #define DEBUG */
-
 #include <float.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
 #include "libavutil/opt.h"
 #include "libavutil/imgutils.h"
@@ -54,19 +55,20 @@ typedef struct {
     AVFrame *frame;   ///< video frame to store the decoded images in
 
     int w, h;
-    AVFilterBufferRef *picref;
 } MovieContext;
 
 #define OFFSET(x) offsetof(MovieContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_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",            "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},
+    { "filename",     NULL,                      OFFSET(file_name),    AV_OPT_TYPE_STRING,                                    .flags = FLAGS },
+    { "format_name",  "set format name",         OFFSET(format_name),  AV_OPT_TYPE_STRING,                                    .flags = FLAGS },
+    { "f",            "set format name",         OFFSET(format_name),  AV_OPT_TYPE_STRING,                                    .flags = FLAGS },
+    { "stream_index", "set stream index",        OFFSET(stream_index), AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX,                 FLAGS  },
+    { "si",           "set stream index",        OFFSET(stream_index), AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX,                 FLAGS  },
+    { "seek_point",   "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, { .dbl =  0 },  0, (INT64_MAX-1) / 1000000, FLAGS },
+    { "sp",           "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, { .dbl =  0 },  0, (INT64_MAX-1) / 1000000, FLAGS },
+    { NULL },
 };
 
 static const char *movie_get_name(void *ctx)
@@ -80,7 +82,7 @@ static const AVClass movie_class = {
     movie_options
 };
 
-static int movie_init(AVFilterContext *ctx)
+static av_cold int movie_init(AVFilterContext *ctx)
 {
     MovieContext *movie = ctx->priv;
     AVInputFormat *iformat = NULL;
@@ -142,16 +144,13 @@ static int movie_init(AVFilterContext *ctx)
         return AVERROR(EINVAL);
     }
 
+    movie->codec_ctx->refcounted_frames = 1;
+
     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;
 
@@ -162,24 +161,9 @@ static int movie_init(AVFilterContext *ctx)
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
 {
     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;
 
@@ -190,14 +174,11 @@ 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);
+    av_frame_free(&movie->frame);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -225,41 +206,29 @@ 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];
+    AVStream av_unused *st = movie->format_ctx->streams[movie->stream_index];
 
     if (movie->is_done == 1)
         return 0;
 
+    movie->frame = av_frame_alloc();
+    if (!movie->frame)
+        return AVERROR(ENOMEM);
+
     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;
+                if (movie->frame->pkt_pts != AV_NOPTS_VALUE)
+                    movie->frame->pts = movie->frame->pkt_pts;
                 av_dlog(outlink->src,
-                        "movie_get_frame(): file:'%s' pts:%"PRId64" time:%f 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);
+                        "movie_get_frame(): file:'%s' pts:%"PRId64" time:%f aspect:%d/%d\n",
+                        movie->file_name, movie->frame->pts,
+                        (double)movie->frame->pts * av_q2d(st->time_base),
+                        movie->frame->sample_aspect_ratio.num,
+                        movie->frame->sample_aspect_ratio.den);
                 // We got it. Free the packet since we are returning
                 av_free_packet(&pkt);
 
@@ -287,8 +256,8 @@ static int request_frame(AVFilterLink *outlink)
     if ((ret = movie_get_frame(outlink)) < 0)
         return ret;
 
-    ret = ff_filter_frame(outlink, movie->picref);
-    movie->picref = NULL;
+    ret = ff_filter_frame(outlink, movie->frame);
+    movie->frame = NULL;
 
     return ret;
 }
@@ -303,10 +272,11 @@ static const AVFilterPad avfilter_vsrc_movie_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_movie = {
+AVFilter ff_vsrc_movie = {
     .name          = "movie",
     .description   = NULL_IF_CONFIG_SMALL("Read from a movie source."),
     .priv_size     = sizeof(MovieContext),
+    .priv_class    = &movie_class,
     .init          = init,
     .uninit        = uninit,
     .query_formats = query_formats,
diff --git a/libavfilter/vsrc_nullsrc.c b/libavfilter/vsrc_nullsrc.c
index 79f6d4b..f7766fa 100644
--- a/libavfilter/vsrc_nullsrc.c
+++ b/libavfilter/vsrc_nullsrc.c
@@ -27,6 +27,7 @@
 #include "libavutil/eval.h"
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "avfilter.h"
 #include "formats.h"
@@ -49,30 +50,12 @@ enum var_name {
 };
 
 typedef struct {
+    const AVClass *class;
     int w, h;
-    char tb_expr[256];
+    char *tb_expr;
     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;
@@ -114,6 +97,22 @@ static int request_frame(AVFilterLink *link)
     return -1;
 }
 
+#define OFFSET(x) offsetof(NullContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption options[] = {
+    { "width",    NULL, OFFSET(w),       AV_OPT_TYPE_INT,    { .i64 = 352    }, 1, INT_MAX, FLAGS },
+    { "height",   NULL, OFFSET(h),       AV_OPT_TYPE_INT,    { .i64 = 288    }, 1, INT_MAX, FLAGS },
+    { "timebase", NULL, OFFSET(tb_expr), AV_OPT_TYPE_STRING, { .str = "AVTB" }, 0, 0,      FLAGS },
+    { NULL },
+};
+
+static const AVClass nullsrc_class = {
+    .class_name = "nullsrc",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVFilterPad avfilter_vsrc_nullsrc_outputs[] = {
     {
         .name          = "default",
@@ -124,12 +123,12 @@ static const AVFilterPad avfilter_vsrc_nullsrc_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_nullsrc = {
+AVFilter ff_vsrc_nullsrc = {
     .name        = "nullsrc",
     .description = NULL_IF_CONFIG_SMALL("Null video source, never return images."),
 
-    .init       = init,
     .priv_size = sizeof(NullContext),
+    .priv_class = &nullsrc_class,
 
     .inputs    = NULL,
 
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 632bd27..9e12852 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -53,38 +53,32 @@ typedef struct {
     char *duration;             ///< total duration of the generated video
     AVRational sar;             ///< sample aspect ratio
 
-    void (* fill_picture_fn)(AVFilterContext *ctx, AVFilterBufferRef *picref);
+    void (* fill_picture_fn)(AVFilterContext *ctx, AVFrame *frame);
 
     /* only used by rgbtest */
     int rgba_map[4];
 } TestSourceContext;
 
 #define OFFSET(x) offsetof(TestSourceContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_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 },
+    { "size",     "set video size",     OFFSET(size),     AV_OPT_TYPE_STRING, {.str = "320x240"},     .flags = FLAGS },
+    { "s",        "set video size",     OFFSET(size),     AV_OPT_TYPE_STRING, {.str = "320x240"},     .flags = FLAGS },
+    { "rate",     "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},          .flags = FLAGS },
+    { "r",        "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},          .flags = FLAGS },
+    { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_STRING, {.str = NULL},          .flags = FLAGS },
+    { "sar",      "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl = 1},  0, INT_MAX, FLAGS },
     { NULL },
 };
 
-static av_cold int init_common(AVFilterContext *ctx, const char *args)
+static av_cold int init_common(AVFilterContext *ctx)
 {
     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);
-        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);
         return ret;
@@ -130,24 +124,23 @@ static int config_props(AVFilterLink *outlink)
 static int request_frame(AVFilterLink *outlink)
 {
     TestSourceContext *test = outlink->src->priv;
-    AVFilterBufferRef *picref;
+    AVFrame *frame;
 
     if (test->max_pts >= 0 && test->pts > test->max_pts)
         return AVERROR_EOF;
-    picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h);
-    if (!picref)
+    frame = ff_get_video_buffer(outlink, test->w, test->h);
+    if (!frame)
         return AVERROR(ENOMEM);
 
-    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;
+    frame->pts                 = test->pts++;
+    frame->key_frame           = 1;
+    frame->interlaced_frame    = 0;
+    frame->pict_type           = AV_PICTURE_TYPE_I;
+    frame->sample_aspect_ratio = test->sar;
     test->nb_frame++;
-    test->fill_picture_fn(outlink->src, picref);
+    test->fill_picture_fn(outlink->src, frame);
 
-    return ff_filter_frame(outlink, picref);
+    return ff_filter_frame(outlink, frame);
 }
 
 #if CONFIG_TESTSRC_FILTER
@@ -235,7 +228,7 @@ static void draw_digit(int digit, uint8_t *dst, unsigned dst_linesize,
 
 #define GRADIENT_SIZE (6 * 256)
 
-static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
+static void test_fill_picture(AVFilterContext *ctx, AVFrame *frame)
 {
     TestSourceContext *test = ctx->priv;
     uint8_t *p, *p0;
@@ -249,9 +242,9 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
     int seg_size;
     int second;
     int i;
-    uint8_t *data = picref->data[0];
-    int width  = picref->video->w;
-    int height = picref->video->h;
+    uint8_t *data = frame->data[0];
+    int width  = frame->width;
+    int height = frame->height;
 
     /* draw colored bars and circle */
     radius = (width + height) / 4;
@@ -281,11 +274,11 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
         }
         quad0 += dquad_y;
         dquad_y += 2;
-        p0 += picref->linesize[0];
+        p0 += frame->linesize[0];
     }
 
     /* draw sliding color line */
-    p = data + picref->linesize[0] * height * 3/4;
+    p = data + frame->linesize[0] * height * 3/4;
     grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) %
         GRADIENT_SIZE;
     rgrad = 0;
@@ -314,8 +307,8 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
             grad -= GRADIENT_SIZE;
     }
     for (y = height / 8; y > 0; y--) {
-        memcpy(p, p - picref->linesize[0], 3 * width);
-        p += picref->linesize[0];
+        memcpy(p, p - frame->linesize[0], 3 * width);
+        p += frame->linesize[0];
     }
 
     /* draw digits */
@@ -324,10 +317,10 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
         second = test->nb_frame * test->time_base.num / test->time_base.den;
         x = width - (width - seg_size * 64) / 2;
         y = (height - seg_size * 13) / 2;
-        p = data + (x*3 + y * picref->linesize[0]);
+        p = data + (x*3 + y * frame->linesize[0]);
         for (i = 0; i < 8; i++) {
             p -= 3 * 8 * seg_size;
-            draw_digit(second % 10, p, picref->linesize[0], seg_size);
+            draw_digit(second % 10, p, frame->linesize[0], seg_size);
             second /= 10;
             if (second == 0)
                 break;
@@ -335,13 +328,12 @@ static void test_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
     }
 }
 
-static av_cold int test_init(AVFilterContext *ctx, const char *args)
+static av_cold int test_init(AVFilterContext *ctx)
 {
     TestSourceContext *test = ctx->priv;
 
-    test->class = &testsrc_class;
     test->fill_picture_fn = test_fill_picture;
-    return init_common(ctx, args);
+    return init_common(ctx);
 }
 
 static int test_query_formats(AVFilterContext *ctx)
@@ -363,10 +355,11 @@ static const AVFilterPad avfilter_vsrc_testsrc_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_testsrc = {
+AVFilter ff_vsrc_testsrc = {
     .name          = "testsrc",
     .description   = NULL_IF_CONFIG_SMALL("Generate test pattern."),
     .priv_size     = sizeof(TestSourceContext),
+    .priv_class    = &testsrc_class,
     .init          = test_init,
 
     .query_formats = test_query_formats,
@@ -427,13 +420,13 @@ static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize,
     }
 }
 
-static void rgbtest_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
+static void rgbtest_fill_picture(AVFilterContext *ctx, AVFrame *frame)
 {
     TestSourceContext *test = ctx->priv;
-    int x, y, w = picref->video->w, h = picref->video->h;
+    int x, y, w = frame->width, h = frame->height;
 
     for (y = 0; y < h; y++) {
-         for (x = 0; x < picref->video->w; x++) {
+         for (x = 0; x < w; x++) {
              int c = 256*x/w;
              int r = 0, g = 0, b = 0;
 
@@ -441,19 +434,18 @@ static void rgbtest_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref
              else if (3*y < 2*h) g = c;
              else                b = c;
 
-             rgbtest_put_pixel(picref->data[0], picref->linesize[0], x, y, r, g, b,
+             rgbtest_put_pixel(frame->data[0], frame->linesize[0], x, y, r, g, b,
                                ctx->outputs[0]->format, test->rgba_map);
          }
      }
 }
 
-static av_cold int rgbtest_init(AVFilterContext *ctx, const char *args)
+static av_cold int rgbtest_init(AVFilterContext *ctx)
 {
     TestSourceContext *test = ctx->priv;
 
-    test->class = &rgbtestsrc_class;
     test->fill_picture_fn = rgbtest_fill_picture;
-    return init_common(ctx, args);
+    return init_common(ctx);
 }
 
 static int rgbtest_query_formats(AVFilterContext *ctx)
@@ -496,10 +488,11 @@ static const AVFilterPad avfilter_vsrc_rgbtestsrc_outputs[] = {
     { NULL }
 };
 
-AVFilter avfilter_vsrc_rgbtestsrc = {
+AVFilter ff_vsrc_rgbtestsrc = {
     .name          = "rgbtestsrc",
     .description   = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
     .priv_size     = sizeof(TestSourceContext),
+    .priv_class    = &rgbtestsrc_class,
     .init          = rgbtest_init,
 
     .query_formats = rgbtest_query_formats,
diff --git a/libavfilter/x86/Makefile b/libavfilter/x86/Makefile
index 0f08e39..16b1307 100644
--- a/libavfilter/x86/Makefile
+++ b/libavfilter/x86/Makefile
@@ -1,6 +1,9 @@
-OBJS-$(CONFIG_GRADFUN_FILTER)                += x86/gradfun.o
+OBJS-$(CONFIG_GRADFUN_FILTER)                += x86/vf_gradfun_init.o
+OBJS-$(CONFIG_HQDN3D_FILTER)                 += x86/vf_hqdn3d_init.o
 OBJS-$(CONFIG_VOLUME_FILTER)                 += x86/af_volume_init.o
-OBJS-$(CONFIG_YADIF_FILTER)                  += x86/yadif.o
+OBJS-$(CONFIG_YADIF_FILTER)                  += x86/vf_yadif_init.o
 
-YASM-OBJS-$(CONFIG_HQDN3D_FILTER)            += x86/hqdn3d.o
+YASM-OBJS-$(CONFIG_GRADFUN_FILTER)           += x86/vf_gradfun.o
+YASM-OBJS-$(CONFIG_HQDN3D_FILTER)            += x86/vf_hqdn3d.o
 YASM-OBJS-$(CONFIG_VOLUME_FILTER)            += x86/af_volume.o
+YASM-OBJS-$(CONFIG_YADIF_FILTER)             += x86/vf_yadif.o
diff --git a/libavfilter/x86/af_volume_init.c b/libavfilter/x86/af_volume_init.c
index 02bedd2..c59e0ed 100644
--- a/libavfilter/x86/af_volume_init.c
+++ b/libavfilter/x86/af_volume_init.c
@@ -17,6 +17,7 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/x86/cpu.h"
@@ -32,26 +33,26 @@ void ff_scale_samples_s32_ssse3_atom(uint8_t *dst, const uint8_t *src, int len,
 void ff_scale_samples_s32_avx(uint8_t *dst, const uint8_t *src, int len,
                               int volume);
 
-void ff_volume_init_x86(VolumeContext *vol)
+av_cold void ff_volume_init_x86(VolumeContext *vol)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
     enum AVSampleFormat sample_fmt = av_get_packed_sample_fmt(vol->sample_fmt);
 
     if (sample_fmt == AV_SAMPLE_FMT_S16) {
-        if (EXTERNAL_SSE2(mm_flags) && vol->volume_i < 32768) {
+        if (EXTERNAL_SSE2(cpu_flags) && vol->volume_i < 32768) {
             vol->scale_samples = ff_scale_samples_s16_sse2;
             vol->samples_align = 8;
         }
     } else if (sample_fmt == AV_SAMPLE_FMT_S32) {
-        if (EXTERNAL_SSE2(mm_flags)) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
             vol->scale_samples = ff_scale_samples_s32_sse2;
             vol->samples_align = 4;
         }
-        if (EXTERNAL_SSSE3(mm_flags) && mm_flags & AV_CPU_FLAG_ATOM) {
+        if (EXTERNAL_SSSE3(cpu_flags) && cpu_flags & AV_CPU_FLAG_ATOM) {
             vol->scale_samples = ff_scale_samples_s32_ssse3_atom;
             vol->samples_align = 4;
         }
-        if (EXTERNAL_AVX(mm_flags)) {
+        if (EXTERNAL_AVX(cpu_flags)) {
             vol->scale_samples = ff_scale_samples_s32_avx;
             vol->samples_align = 8;
         }
diff --git a/libavfilter/x86/gradfun.c b/libavfilter/x86/gradfun.c
deleted file mode 100644
index b4ca86c..0000000
--- a/libavfilter/x86/gradfun.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2009 Loren Merritt <lorenm at u.washignton.edu>
- *
- * 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/attributes.h"
-#include "libavutil/cpu.h"
-#include "libavutil/mem.h"
-#include "libavutil/x86/asm.h"
-#include "libavfilter/gradfun.h"
-
-#if HAVE_INLINE_ASM
-
-DECLARE_ALIGNED(16, static const uint16_t, pw_7f)[8] = {0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F};
-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_mmxext(uint8_t *dst, uint8_t *src, uint16_t *dc,
-                                       int width, int thresh,
-                                       const uint16_t *dithers)
-{
-    intptr_t x;
-    if (width & 3) {
-        x = width & ~3;
-        ff_gradfun_filter_line_c(dst + x, src + x, dc + x / 2, width - x, thresh, dithers);
-        width = x;
-    }
-    x = -width;
-    __asm__ volatile(
-        "movd          %4, %%mm5 \n"
-        "pxor       %%mm7, %%mm7 \n"
-        "pshufw $0, %%mm5, %%mm5 \n"
-        "movq          %6, %%mm6 \n"
-        "movq          %5, %%mm4 \n"
-        "1: \n"
-        "movd     (%2,%0), %%mm0 \n"
-        "movd     (%3,%0), %%mm1 \n"
-        "punpcklbw  %%mm7, %%mm0 \n"
-        "punpcklwd  %%mm1, %%mm1 \n"
-        "psllw         $7, %%mm0 \n"
-        "pxor       %%mm2, %%mm2 \n"
-        "psubw      %%mm0, %%mm1 \n" // delta = dc - pix
-        "psubw      %%mm1, %%mm2 \n"
-        "pmaxsw     %%mm1, %%mm2 \n"
-        "pmulhuw    %%mm5, %%mm2 \n" // m = abs(delta) * thresh >> 16
-        "psubw      %%mm6, %%mm2 \n"
-        "pminsw     %%mm7, %%mm2 \n" // m = -max(0, 127-m)
-        "pmullw     %%mm2, %%mm2 \n"
-        "paddw      %%mm4, %%mm0 \n" // pix += dither
-        "pmulhw     %%mm2, %%mm1 \n"
-        "psllw         $2, %%mm1 \n" // m = m*m*delta >> 14
-        "paddw      %%mm1, %%mm0 \n" // pix += m
-        "psraw         $7, %%mm0 \n"
-        "packuswb   %%mm0, %%mm0 \n"
-        "movd       %%mm0, (%1,%0) \n" // dst = clip(pix>>7)
-        "add           $4, %0 \n"
-        "jl 1b \n"
-        "emms \n"
-        :"+r"(x)
-        :"r"(dst+width), "r"(src+width), "r"(dc+width/2),
-         "rm"(thresh), "m"(*dithers), "m"(*pw_7f)
-        :"memory"
-    );
-}
-#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)
-{
-    intptr_t x;
-    if (width & 7) {
-        // could be 10% faster if I somehow eliminated this
-        x = width & ~7;
-        ff_gradfun_filter_line_c(dst + x, src + x, dc + x / 2, width - x, thresh, dithers);
-        width = x;
-    }
-    x = -width;
-    __asm__ volatile(
-        "movd           %4, %%xmm5 \n"
-        "pxor       %%xmm7, %%xmm7 \n"
-        "pshuflw $0,%%xmm5, %%xmm5 \n"
-        "movdqa         %6, %%xmm6 \n"
-        "punpcklqdq %%xmm5, %%xmm5 \n"
-        "movdqa         %5, %%xmm4 \n"
-        "1: \n"
-        "movq      (%2,%0), %%xmm0 \n"
-        "movq      (%3,%0), %%xmm1 \n"
-        "punpcklbw  %%xmm7, %%xmm0 \n"
-        "punpcklwd  %%xmm1, %%xmm1 \n"
-        "psllw          $7, %%xmm0 \n"
-        "psubw      %%xmm0, %%xmm1 \n" // delta = dc - pix
-        "pabsw      %%xmm1, %%xmm2 \n"
-        "pmulhuw    %%xmm5, %%xmm2 \n" // m = abs(delta) * thresh >> 16
-        "psubw      %%xmm6, %%xmm2 \n"
-        "pminsw     %%xmm7, %%xmm2 \n" // m = -max(0, 127-m)
-        "pmullw     %%xmm2, %%xmm2 \n"
-        "psllw          $1, %%xmm2 \n"
-        "paddw      %%xmm4, %%xmm0 \n" // pix += dither
-        "pmulhrsw   %%xmm2, %%xmm1 \n" // m = m*m*delta >> 14
-        "paddw      %%xmm1, %%xmm0 \n" // pix += m
-        "psraw          $7, %%xmm0 \n"
-        "packuswb   %%xmm0, %%xmm0 \n"
-        "movq       %%xmm0, (%1,%0) \n" // dst = clip(pix>>7)
-        "add            $8, %0 \n"
-        "jl 1b \n"
-        :"+&r"(x)
-        :"r"(dst+width), "r"(src+width), "r"(dc+width/2),
-         "rm"(thresh), "m"(*dithers), "m"(*pw_7f)
-        :"memory"
-    );
-}
-#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)
-{
-#define BLURV(load)\
-    intptr_t x = -2*width;\
-    __asm__ volatile(\
-        "movdqa %6, %%xmm7 \n"\
-        "1: \n"\
-        load"   (%4,%0), %%xmm0 \n"\
-        load"   (%5,%0), %%xmm1 \n"\
-        "movdqa  %%xmm0, %%xmm2 \n"\
-        "movdqa  %%xmm1, %%xmm3 \n"\
-        "psrlw       $8, %%xmm0 \n"\
-        "psrlw       $8, %%xmm1 \n"\
-        "pand    %%xmm7, %%xmm2 \n"\
-        "pand    %%xmm7, %%xmm3 \n"\
-        "paddw   %%xmm1, %%xmm0 \n"\
-        "paddw   %%xmm3, %%xmm2 \n"\
-        "paddw   %%xmm2, %%xmm0 \n"\
-        "paddw  (%2,%0), %%xmm0 \n"\
-        "movdqa (%1,%0), %%xmm1 \n"\
-        "movdqa  %%xmm0, (%1,%0) \n"\
-        "psubw   %%xmm1, %%xmm0 \n"\
-        "movdqa  %%xmm0, (%3,%0) \n"\
-        "add        $16, %0 \n"\
-        "jl 1b \n"\
-        :"+&r"(x)\
-        :"r"(buf+width),\
-         "r"(buf1+width),\
-         "r"(dc+width),\
-         "r"(src+width*2),\
-         "r"(src+width*2+src_linesize),\
-         "m"(*pw_ff)\
-        :"memory"\
-    );
-    if (((intptr_t) src | src_linesize) & 15) {
-        BLURV("movdqu");
-    } else {
-        BLURV("movdqa");
-    }
-}
-#endif /* HAVE_SSE2_INLINE */
-
-#endif /* HAVE_INLINE_ASM */
-
-av_cold void ff_gradfun_init_x86(GradFunContext *gf)
-{
-    int cpu_flags = av_get_cpu_flags();
-
-#if HAVE_MMXEXT_INLINE
-    if (cpu_flags & AV_CPU_FLAG_MMXEXT)
-        gf->filter_line = gradfun_filter_line_mmxext;
-#endif
-#if HAVE_SSSE3_INLINE
-    if (cpu_flags & AV_CPU_FLAG_SSSE3)
-        gf->filter_line = gradfun_filter_line_ssse3;
-#endif
-#if HAVE_SSE2_INLINE
-    if (cpu_flags & AV_CPU_FLAG_SSE2)
-        gf->blur_line = gradfun_blur_line_sse2;
-#endif
-}
diff --git a/libavfilter/x86/vf_gradfun.asm b/libavfilter/x86/vf_gradfun.asm
new file mode 100644
index 0000000..00fcb16
--- /dev/null
+++ b/libavfilter/x86/vf_gradfun.asm
@@ -0,0 +1,110 @@
+;******************************************************************************
+;* x86-optimized functions for gradfun filter
+;*
+;* 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/x86util.asm"
+
+SECTION_RODATA
+
+pw_7f: times 8 dw 0x7F
+pw_ff: times 8 dw 0xFF
+
+SECTION .text
+
+%macro FILTER_LINE 1
+    movh       m0, [r2+r0]
+    movh       m1, [r3+r0]
+    punpcklbw  m0, m7
+    punpcklwd  m1, m1
+    psllw      m0, 7
+    psubw      m1, m0
+    PABSW      m2, m1
+    pmulhuw    m2, m5
+    psubw      m2, m6
+    pminsw     m2, m7
+    pmullw     m2, m2
+    psllw      m1, 2
+    paddw      m0, %1
+    pmulhw     m1, m2
+    paddw      m0, m1
+    psraw      m0, 7
+    packuswb   m0, m0
+    movh  [r1+r0], m0
+%endmacro
+
+INIT_MMX mmxext
+cglobal gradfun_filter_line, 6, 6
+    movh      m5, r4d
+    pxor      m7, m7
+    pshufw    m5, m5,0
+    mova      m6, [pw_7f]
+    mova      m3, [r5]
+    mova      m4, [r5+8]
+.loop:
+    FILTER_LINE m3
+    add       r0, 4
+    jge .end
+    FILTER_LINE m4
+    add       r0, 4
+    jl .loop
+.end:
+    REP_RET
+
+INIT_XMM ssse3
+cglobal gradfun_filter_line, 6, 6, 8
+    movd       m5, r4d
+    pxor       m7, m7
+    pshuflw    m5, m5, 0
+    mova       m6, [pw_7f]
+    punpcklqdq m5, m5
+    mova       m4, [r5]
+.loop:
+    FILTER_LINE m4
+    add        r0, 8
+    jl .loop
+    REP_RET
+
+%macro BLUR_LINE 1
+cglobal gradfun_blur_line_%1, 6, 6, 8
+    mova        m7, [pw_ff]
+.loop:
+    %1          m0, [r4+r0]
+    %1          m1, [r5+r0]
+    mova        m2, m0
+    mova        m3, m1
+    psrlw       m0, 8
+    psrlw       m1, 8
+    pand        m2, m7
+    pand        m3, m7
+    paddw       m0, m1
+    paddw       m2, m3
+    paddw       m0, m2
+    paddw       m0, [r2+r0]
+    mova        m1, [r1+r0]
+    mova   [r1+r0], m0
+    psubw       m0, m1
+    mova   [r3+r0], m0
+    add         r0, 16
+    jl .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse2
+BLUR_LINE movdqa
+BLUR_LINE movdqu
diff --git a/libavfilter/x86/vf_gradfun_init.c b/libavfilter/x86/vf_gradfun_init.c
new file mode 100644
index 0000000..3f23bf6
--- /dev/null
+++ b/libavfilter/x86/vf_gradfun_init.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2009 Loren Merritt <lorenm at u.washington.edu>
+ *
+ * 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 "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem.h"
+#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
+#include "libavfilter/gradfun.h"
+
+void ff_gradfun_filter_line_mmxext(intptr_t x, uint8_t *dst, uint8_t *src,
+                                   uint16_t *dc, int thresh,
+                                   const uint16_t *dithers);
+
+void ff_gradfun_filter_line_ssse3(intptr_t x, uint8_t *dst, uint8_t *src,
+                                  uint16_t *dc, int thresh,
+                                  const uint16_t *dithers);
+
+void ff_gradfun_blur_line_movdqa_sse2(intptr_t x, uint16_t *buf,
+                                      uint16_t *buf1, uint16_t *dc,
+                                      uint8_t *src1, uint8_t *src2);
+void ff_gradfun_blur_line_movdqu_sse2(intptr_t x, uint16_t *buf,
+                                      uint16_t *buf1, uint16_t *dc,
+                                      uint8_t *src1, uint8_t *src2);
+
+#if HAVE_YASM
+static void gradfun_filter_line(uint8_t *dst, uint8_t *src, uint16_t *dc,
+                                int width, int thresh, const uint16_t *dithers,
+                                int alignment)
+{
+    intptr_t x;
+    if (width & alignment) {
+        x = width & ~alignment;
+        ff_gradfun_filter_line_c(dst + x, src + x, dc + x / 2,
+                                 width - x, thresh, dithers);
+        width = x;
+    }
+    x = -width;
+    ff_gradfun_filter_line_mmxext(x, dst + width, src + width, dc + width / 2,
+                                  thresh, dithers);
+}
+
+static void gradfun_filter_line_mmxext(uint8_t *dst, uint8_t *src, uint16_t *dc,
+                                       int width, int thresh,
+                                       const uint16_t *dithers)
+{
+    gradfun_filter_line(dst, src, dc, width, thresh, dithers, 3);
+}
+
+static void gradfun_filter_line_ssse3(uint8_t *dst, uint8_t *src, uint16_t *dc,
+                                      int width, int thresh,
+                                      const uint16_t *dithers)
+{
+    gradfun_filter_line(dst, src, dc, width, thresh, dithers, 7);
+}
+
+static void gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, uint16_t *buf1,
+                                   uint8_t *src, int src_linesize, int width)
+{
+    intptr_t x = -2 * width;
+    if (((intptr_t) src | src_linesize) & 15)
+        ff_gradfun_blur_line_movdqu_sse2(x, buf + width, buf1 + width,
+                                         dc + width, src + width * 2,
+                                         src + width * 2 + src_linesize);
+    else
+        ff_gradfun_blur_line_movdqa_sse2(x, buf + width, buf1 + width,
+                                         dc + width, src + width * 2,
+                                         src + width * 2 + src_linesize);
+}
+#endif /* HAVE_YASM */
+
+av_cold void ff_gradfun_init_x86(GradFunContext *gf)
+{
+#if HAVE_YASM
+    int cpu_flags = av_get_cpu_flags();
+
+    if (EXTERNAL_MMXEXT(cpu_flags))
+        gf->filter_line = gradfun_filter_line_mmxext;
+    if (EXTERNAL_SSSE3(cpu_flags))
+        gf->filter_line = gradfun_filter_line_ssse3;
+
+    if (EXTERNAL_SSE2(cpu_flags))
+        gf->blur_line = gradfun_blur_line_sse2;
+#endif /* HAVE_YASM */
+}
diff --git a/libavfilter/x86/hqdn3d.asm b/libavfilter/x86/vf_hqdn3d.asm
similarity index 100%
rename from libavfilter/x86/hqdn3d.asm
rename to libavfilter/x86/vf_hqdn3d.asm
diff --git a/libavfilter/x86/vf_hqdn3d_init.c b/libavfilter/x86/vf_hqdn3d_init.c
new file mode 100644
index 0000000..06f9e00
--- /dev/null
+++ b/libavfilter/x86/vf_hqdn3d_init.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav 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,
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavfilter/vf_hqdn3d.h"
+#include "config.h"
+
+void ff_hqdn3d_row_8_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant,
+                         uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial,
+                         int16_t *temporal);
+void ff_hqdn3d_row_9_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant,
+                         uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial,
+                         int16_t *temporal);
+void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant,
+                          uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial,
+                          int16_t *temporal);
+void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant,
+                          uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial,
+                          int16_t *temporal);
+
+av_cold void ff_hqdn3d_init_x86(HQDN3DContext *hqdn3d)
+{
+#if HAVE_YASM
+    hqdn3d->denoise_row[8]  = ff_hqdn3d_row_8_x86;
+    hqdn3d->denoise_row[9]  = ff_hqdn3d_row_9_x86;
+    hqdn3d->denoise_row[10] = ff_hqdn3d_row_10_x86;
+    hqdn3d->denoise_row[16] = ff_hqdn3d_row_16_x86;
+#endif /* HAVE_YASM */
+}
diff --git a/libavfilter/x86/vf_yadif.asm b/libavfilter/x86/vf_yadif.asm
new file mode 100644
index 0000000..bc4b3ce
--- /dev/null
+++ b/libavfilter/x86/vf_yadif.asm
@@ -0,0 +1,254 @@
+;*****************************************************************************
+;* x86-optimized functions for yadif filter
+;*
+;* Copyright (C) 2006 Michael Niedermayer <michaelni at gmx.at>
+;* Copyright (c) 2013 Daniel Kang <daniel.d.kang at gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or modify
+;* it under the terms of the GNU 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,
+;* 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.,
+;* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+
+pb_1: times 16 db 1
+pw_1: times  8 dw 1
+
+SECTION .text
+
+%macro CHECK 2
+    movu      m2, [curq+t1+%1]
+    movu      m3, [curq+t0+%2]
+    mova      m4, m2
+    mova      m5, m2
+    pxor      m4, m3
+    pavgb     m5, m3
+    pand      m4, [pb_1]
+    psubusb   m5, m4
+%if mmsize == 16
+    psrldq    m5, 1
+%else
+    psrlq     m5, 8
+%endif
+    punpcklbw m5, m7
+    mova      m4, m2
+    psubusb   m2, m3
+    psubusb   m3, m4
+    pmaxub    m2, m3
+    mova      m3, m2
+    mova      m4, m2
+%if mmsize == 16
+    psrldq    m3, 1
+    psrldq    m4, 2
+%else
+    psrlq     m3, 8
+    psrlq     m4, 16
+%endif
+    punpcklbw m2, m7
+    punpcklbw m3, m7
+    punpcklbw m4, m7
+    paddw     m2, m3
+    paddw     m2, m4
+%endmacro
+
+%macro CHECK1 0
+    mova    m3, m0
+    pcmpgtw m3, m2
+    pminsw  m0, m2
+    mova    m6, m3
+    pand    m5, m3
+    pandn   m3, m1
+    por     m3, m5
+    mova    m1, m3
+%endmacro
+
+%macro CHECK2 0
+    paddw   m6, [pw_1]
+    psllw   m6, 14
+    paddsw  m2, m6
+    mova    m3, m0
+    pcmpgtw m3, m2
+    pminsw  m0, m2
+    pand    m5, m3
+    pandn   m3, m1
+    por     m3, m5
+    mova    m1, m3
+%endmacro
+
+%macro LOAD 2
+    movh      m%1, %2
+    punpcklbw m%1, m7
+%endmacro
+
+%macro FILTER 3
+.loop%1:
+    pxor         m7, m7
+    LOAD          0, [curq+t1]
+    LOAD          1, [curq+t0]
+    LOAD          2, [%2]
+    LOAD          3, [%3]
+    mova         m4, m3
+    paddw        m3, m2
+    psraw        m3, 1
+    mova   [rsp+ 0], m0
+    mova   [rsp+16], m3
+    mova   [rsp+32], m1
+    psubw        m2, m4
+    ABS1         m2, m4
+    LOAD          3, [prevq+t1]
+    LOAD          4, [prevq+t0]
+    psubw        m3, m0
+    psubw        m4, m1
+    ABS1         m3, m5
+    ABS1         m4, m5
+    paddw        m3, m4
+    psrlw        m2, 1
+    psrlw        m3, 1
+    pmaxsw       m2, m3
+    LOAD          3, [nextq+t1]
+    LOAD          4, [nextq+t0]
+    psubw        m3, m0
+    psubw        m4, m1
+    ABS1         m3, m5
+    ABS1         m4, m5
+    paddw        m3, m4
+    psrlw        m3, 1
+    pmaxsw       m2, m3
+    mova   [rsp+48], m2
+
+    paddw        m1, m0
+    paddw        m0, m0
+    psubw        m0, m1
+    psrlw        m1, 1
+    ABS1         m0, m2
+
+    movu         m2, [curq+t1-1]
+    movu         m3, [curq+t0-1]
+    mova         m4, m2
+    psubusb      m2, m3
+    psubusb      m3, m4
+    pmaxub       m2, m3
+%if mmsize == 16
+    mova         m3, m2
+    psrldq       m3, 2
+%else
+    pshufw       m3, m2, q0021
+%endif
+    punpcklbw    m2, m7
+    punpcklbw    m3, m7
+    paddw        m0, m2
+    paddw        m0, m3
+    psubw        m0, [pw_1]
+
+    CHECK -2, 0
+    CHECK1
+    CHECK -3, 1
+    CHECK2
+    CHECK 0, -2
+    CHECK1
+    CHECK 1, -3
+    CHECK2
+
+    mova         m6, [rsp+48]
+    cmp   DWORD r8m, 2
+    jge .end%1
+    LOAD          2, [%2+t1*2]
+    LOAD          4, [%3+t1*2]
+    LOAD          3, [%2+t0*2]
+    LOAD          5, [%3+t0*2]
+    paddw        m2, m4
+    paddw        m3, m5
+    psrlw        m2, 1
+    psrlw        m3, 1
+    mova         m4, [rsp+ 0]
+    mova         m5, [rsp+16]
+    mova         m7, [rsp+32]
+    psubw        m2, m4
+    psubw        m3, m7
+    mova         m0, m5
+    psubw        m5, m4
+    psubw        m0, m7
+    mova         m4, m2
+    pminsw       m2, m3
+    pmaxsw       m3, m4
+    pmaxsw       m2, m5
+    pminsw       m3, m5
+    pmaxsw       m2, m0
+    pminsw       m3, m0
+    pxor         m4, m4
+    pmaxsw       m6, m3
+    psubw        m4, m2
+    pmaxsw       m6, m4
+
+.end%1:
+    mova         m2, [rsp+16]
+    mova         m3, m2
+    psubw        m2, m6
+    paddw        m3, m6
+    pmaxsw       m1, m2
+    pminsw       m1, m3
+    packuswb     m1, m1
+
+    movh     [dstq], m1
+    add        dstq, mmsize/2
+    add       prevq, mmsize/2
+    add        curq, mmsize/2
+    add       nextq, mmsize/2
+    sub   DWORD r4m, mmsize/2
+    jg .loop%1
+%endmacro
+
+%macro YADIF 0
+%if ARCH_X86_32
+cglobal yadif_filter_line, 4, 6, 8, 80, dst, prev, cur, next, w, prefs, \
+                                        mrefs, parity, mode
+%else
+cglobal yadif_filter_line, 4, 7, 8, 80, dst, prev, cur, next, w, prefs, \
+                                        mrefs, parity, mode
+%endif
+    cmp      DWORD wm, 0
+    jle .ret
+%if ARCH_X86_32
+    mov            r4, r5mp
+    mov            r5, r6mp
+    DECLARE_REG_TMP 4,5
+%else
+    movsxd         r5, DWORD r5m
+    movsxd         r6, DWORD r6m
+    DECLARE_REG_TMP 5,6
+%endif
+
+    cmp DWORD paritym, 0
+    je .parity0
+    FILTER 1, prevq, curq
+    jmp .ret
+
+.parity0:
+    FILTER 0, curq, nextq
+
+.ret:
+    RET
+%endmacro
+
+INIT_XMM ssse3
+YADIF
+INIT_XMM sse2
+YADIF
+%if ARCH_X86_32
+INIT_MMX mmxext
+YADIF
+%endif
diff --git a/libavfilter/x86/vf_yadif_init.c b/libavfilter/x86/vf_yadif_init.c
new file mode 100644
index 0000000..5978a4f
--- /dev/null
+++ b/libavfilter/x86/vf_yadif_init.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2006 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of Libav.
+ *
+ * Libav 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,
+ * 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.,
+ * 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 "libavutil/x86/cpu.h"
+#include "libavfilter/yadif.h"
+
+void ff_yadif_filter_line_mmxext(void *dst, void *prev, void *cur,
+                                 void *next, int w, int prefs,
+                                 int mrefs, int parity, int mode);
+void ff_yadif_filter_line_sse2(void *dst, void *prev, void *cur,
+                               void *next, int w, int prefs,
+                               int mrefs, int parity, int mode);
+void ff_yadif_filter_line_ssse3(void *dst, void *prev, void *cur,
+                                void *next, int w, int prefs,
+                                int mrefs, int parity, int mode);
+
+av_cold void ff_yadif_init_x86(YADIFContext *yadif)
+{
+#if HAVE_YASM
+    int cpu_flags = av_get_cpu_flags();
+
+#if ARCH_X86_32
+    if (EXTERNAL_MMXEXT(cpu_flags))
+        yadif->filter_line = ff_yadif_filter_line_mmxext;
+#endif /* ARCH_X86_32 */
+    if (EXTERNAL_SSE2(cpu_flags))
+        yadif->filter_line = ff_yadif_filter_line_sse2;
+    if (EXTERNAL_SSSE3(cpu_flags))
+        yadif->filter_line = ff_yadif_filter_line_ssse3;
+#endif /* HAVE_YASM */
+}
diff --git a/libavfilter/x86/yadif.c b/libavfilter/x86/yadif.c
deleted file mode 100644
index ab1d282..0000000
--- a/libavfilter/x86/yadif.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2006 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of Libav.
- *
- * Libav 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,
- * 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.,
- * 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"
-#include "libavfilter/yadif.h"
-
-#if HAVE_INLINE_ASM
-
-DECLARE_ASM_CONST(16, const xmm_reg, pb_1) = {0x0101010101010101ULL, 0x0101010101010101ULL};
-DECLARE_ASM_CONST(16, const xmm_reg, pw_1) = {0x0001000100010001ULL, 0x0001000100010001ULL};
-
-#if HAVE_SSSE3_INLINE
-#define COMPILE_TEMPLATE_SSE2 1
-#define COMPILE_TEMPLATE_SSSE3 1
-#undef RENAME
-#define RENAME(a) a ## _ssse3
-#include "yadif_template.c"
-#undef COMPILE_TEMPLATE_SSSE3
-#endif
-
-#if HAVE_SSE2_INLINE
-#undef RENAME
-#define RENAME(a) a ## _sse2
-#include "yadif_template.c"
-#undef COMPILE_TEMPLATE_SSE2
-#endif
-
-#if HAVE_MMXEXT_INLINE
-#undef RENAME
-#define RENAME(a) a ## _mmxext
-#include "yadif_template.c"
-#endif
-
-#endif /* HAVE_INLINE_ASM */
-
-av_cold void ff_yadif_init_x86(YADIFContext *yadif)
-{
-    int cpu_flags = av_get_cpu_flags();
-
-#if HAVE_MMXEXT_INLINE
-    if (cpu_flags & AV_CPU_FLAG_MMXEXT)
-        yadif->filter_line = yadif_filter_line_mmxext;
-#endif
-#if HAVE_SSE2_INLINE
-    if (cpu_flags & AV_CPU_FLAG_SSE2)
-        yadif->filter_line = yadif_filter_line_sse2;
-#endif
-#if HAVE_SSSE3_INLINE
-    if (cpu_flags & AV_CPU_FLAG_SSSE3)
-        yadif->filter_line = yadif_filter_line_ssse3;
-#endif
-}
diff --git a/libavfilter/x86/yadif_template.c b/libavfilter/x86/yadif_template.c
deleted file mode 100644
index 02b0c9f..0000000
--- a/libavfilter/x86/yadif_template.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2006 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of Libav.
- *
- * Libav 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,
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef COMPILE_TEMPLATE_SSE2
-#define MM "%%xmm"
-#define MOV  "movq"
-#define MOVQ "movdqa"
-#define MOVQU "movdqu"
-#define STEP 8
-#define LOAD(mem,dst) \
-            MOV"       "mem", "dst" \n\t"\
-            "punpcklbw "MM"7, "dst" \n\t"
-#define PSRL1(reg) "psrldq $1, "reg" \n\t"
-#define PSRL2(reg) "psrldq $2, "reg" \n\t"
-#define PSHUF(src,dst) "movdqa "dst", "src" \n\t"\
-                       "psrldq $2, "src"     \n\t"
-#else
-#define MM "%%mm"
-#define MOV  "movd"
-#define MOVQ "movq"
-#define MOVQU "movq"
-#define STEP 4
-#define LOAD(mem,dst) \
-            MOV"       "mem", "dst" \n\t"\
-            "punpcklbw "MM"7, "dst" \n\t"
-#define PSRL1(reg) "psrlq $8, "reg" \n\t"
-#define PSRL2(reg) "psrlq $16, "reg" \n\t"
-#define PSHUF(src,dst) "pshufw $9, "dst", "src" \n\t"
-#endif
-
-#ifdef COMPILE_TEMPLATE_SSSE3
-#define PABS(tmp,dst) \
-            "pabsw     "dst", "dst" \n\t"
-#else
-#define PABS(tmp,dst) \
-            "pxor     "tmp", "tmp" \n\t"\
-            "psubw    "dst", "tmp" \n\t"\
-            "pmaxsw   "tmp", "dst" \n\t"
-#endif
-
-#define CHECK(pj,mj) \
-            MOVQU" "#pj"(%[cur],%[mrefs]), "MM"2 \n\t" /* cur[x-refs-1+j] */\
-            MOVQU" "#mj"(%[cur],%[prefs]), "MM"3 \n\t" /* cur[x+refs-1-j] */\
-            MOVQ"      "MM"2, "MM"4 \n\t"\
-            MOVQ"      "MM"2, "MM"5 \n\t"\
-            "pxor      "MM"3, "MM"4 \n\t"\
-            "pavgb     "MM"3, "MM"5 \n\t"\
-            "pand     "MANGLE(pb_1)", "MM"4 \n\t"\
-            "psubusb   "MM"4, "MM"5 \n\t"\
-            PSRL1(MM"5")                 \
-            "punpcklbw "MM"7, "MM"5 \n\t" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */\
-            MOVQ"      "MM"2, "MM"4 \n\t"\
-            "psubusb   "MM"3, "MM"2 \n\t"\
-            "psubusb   "MM"4, "MM"3 \n\t"\
-            "pmaxub    "MM"3, "MM"2 \n\t"\
-            MOVQ"      "MM"2, "MM"3 \n\t"\
-            MOVQ"      "MM"2, "MM"4 \n\t" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */\
-            PSRL1(MM"3")                  /* ABS(cur[x-refs  +j] - cur[x+refs  -j]) */\
-            PSRL2(MM"4")                  /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */\
-            "punpcklbw "MM"7, "MM"2 \n\t"\
-            "punpcklbw "MM"7, "MM"3 \n\t"\
-            "punpcklbw "MM"7, "MM"4 \n\t"\
-            "paddw     "MM"3, "MM"2 \n\t"\
-            "paddw     "MM"4, "MM"2 \n\t" /* score */
-
-#define CHECK1 \
-            MOVQ"      "MM"0, "MM"3 \n\t"\
-            "pcmpgtw   "MM"2, "MM"3 \n\t" /* if(score < spatial_score) */\
-            "pminsw    "MM"2, "MM"0 \n\t" /* spatial_score= score; */\
-            MOVQ"      "MM"3, "MM"6 \n\t"\
-            "pand      "MM"3, "MM"5 \n\t"\
-            "pandn     "MM"1, "MM"3 \n\t"\
-            "por       "MM"5, "MM"3 \n\t"\
-            MOVQ"      "MM"3, "MM"1 \n\t" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */
-
-#define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.\
-                  hurts both quality and speed, but matches the C version. */\
-            "paddw    "MANGLE(pw_1)", "MM"6 \n\t"\
-            "psllw     $14,   "MM"6 \n\t"\
-            "paddsw    "MM"6, "MM"2 \n\t"\
-            MOVQ"      "MM"0, "MM"3 \n\t"\
-            "pcmpgtw   "MM"2, "MM"3 \n\t"\
-            "pminsw    "MM"2, "MM"0 \n\t"\
-            "pand      "MM"3, "MM"5 \n\t"\
-            "pandn     "MM"1, "MM"3 \n\t"\
-            "por       "MM"5, "MM"3 \n\t"\
-            MOVQ"      "MM"3, "MM"1 \n\t"
-
-static void RENAME(yadif_filter_line)(uint8_t *dst, uint8_t *prev, uint8_t *cur,
-                                      uint8_t *next, int w, int prefs,
-                                      int mrefs, int parity, int mode)
-{
-    DECLARE_ALIGNED(16, uint8_t, tmp)[16*4];
-    int x;
-
-#define FILTER\
-    for(x=0; x<w; x+=STEP){\
-        __asm__ volatile(\
-            "pxor      "MM"7, "MM"7 \n\t"\
-            LOAD("(%[cur],%[mrefs])", MM"0") /* c = cur[x-refs] */\
-            LOAD("(%[cur],%[prefs])", MM"1") /* e = cur[x+refs] */\
-            LOAD("(%["prev2"])", MM"2") /* prev2[x] */\
-            LOAD("(%["next2"])", MM"3") /* next2[x] */\
-            MOVQ"      "MM"3, "MM"4 \n\t"\
-            "paddw     "MM"2, "MM"3 \n\t"\
-            "psraw     $1,    "MM"3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\
-            MOVQ"      "MM"0,   (%[tmp]) \n\t" /* c */\
-            MOVQ"      "MM"3, 16(%[tmp]) \n\t" /* d */\
-            MOVQ"      "MM"1, 32(%[tmp]) \n\t" /* e */\
-            "psubw     "MM"4, "MM"2 \n\t"\
-            PABS(      MM"4", MM"2") /* temporal_diff0 */\
-            LOAD("(%[prev],%[mrefs])", MM"3") /* prev[x-refs] */\
-            LOAD("(%[prev],%[prefs])", MM"4") /* prev[x+refs] */\
-            "psubw     "MM"0, "MM"3 \n\t"\
-            "psubw     "MM"1, "MM"4 \n\t"\
-            PABS(      MM"5", MM"3")\
-            PABS(      MM"5", MM"4")\
-            "paddw     "MM"4, "MM"3 \n\t" /* temporal_diff1 */\
-            "psrlw     $1,    "MM"2 \n\t"\
-            "psrlw     $1,    "MM"3 \n\t"\
-            "pmaxsw    "MM"3, "MM"2 \n\t"\
-            LOAD("(%[next],%[mrefs])", MM"3") /* next[x-refs] */\
-            LOAD("(%[next],%[prefs])", MM"4") /* next[x+refs] */\
-            "psubw     "MM"0, "MM"3 \n\t"\
-            "psubw     "MM"1, "MM"4 \n\t"\
-            PABS(      MM"5", MM"3")\
-            PABS(      MM"5", MM"4")\
-            "paddw     "MM"4, "MM"3 \n\t" /* temporal_diff2 */\
-            "psrlw     $1,    "MM"3 \n\t"\
-            "pmaxsw    "MM"3, "MM"2 \n\t"\
-            MOVQ"      "MM"2, 48(%[tmp]) \n\t" /* diff */\
-\
-            "paddw     "MM"0, "MM"1 \n\t"\
-            "paddw     "MM"0, "MM"0 \n\t"\
-            "psubw     "MM"1, "MM"0 \n\t"\
-            "psrlw     $1,    "MM"1 \n\t" /* spatial_pred */\
-            PABS(      MM"2", MM"0")      /* ABS(c-e) */\
-\
-            MOVQU" -1(%[cur],%[mrefs]), "MM"2 \n\t" /* cur[x-refs-1] */\
-            MOVQU" -1(%[cur],%[prefs]), "MM"3 \n\t" /* cur[x+refs-1] */\
-            MOVQ"      "MM"2, "MM"4 \n\t"\
-            "psubusb   "MM"3, "MM"2 \n\t"\
-            "psubusb   "MM"4, "MM"3 \n\t"\
-            "pmaxub    "MM"3, "MM"2 \n\t"\
-            PSHUF(MM"3", MM"2") \
-            "punpcklbw "MM"7, "MM"2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\
-            "punpcklbw "MM"7, "MM"3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\
-            "paddw     "MM"2, "MM"0 \n\t"\
-            "paddw     "MM"3, "MM"0 \n\t"\
-            "psubw    "MANGLE(pw_1)", "MM"0 \n\t" /* spatial_score */\
-\
-            CHECK(-2,0)\
-            CHECK1\
-            CHECK(-3,1)\
-            CHECK2\
-            CHECK(0,-2)\
-            CHECK1\
-            CHECK(1,-3)\
-            CHECK2\
-\
-            /* if(p->mode<2) ... */\
-            MOVQ" 48(%[tmp]), "MM"6 \n\t" /* diff */\
-            "cmpl      $2, %[mode] \n\t"\
-            "jge       1f \n\t"\
-            LOAD("(%["prev2"],%[mrefs],2)", MM"2") /* prev2[x-2*refs] */\
-            LOAD("(%["next2"],%[mrefs],2)", MM"4") /* next2[x-2*refs] */\
-            LOAD("(%["prev2"],%[prefs],2)", MM"3") /* prev2[x+2*refs] */\
-            LOAD("(%["next2"],%[prefs],2)", MM"5") /* next2[x+2*refs] */\
-            "paddw     "MM"4, "MM"2 \n\t"\
-            "paddw     "MM"5, "MM"3 \n\t"\
-            "psrlw     $1,    "MM"2 \n\t" /* b */\
-            "psrlw     $1,    "MM"3 \n\t" /* f */\
-            MOVQ"   (%[tmp]), "MM"4 \n\t" /* c */\
-            MOVQ" 16(%[tmp]), "MM"5 \n\t" /* d */\
-            MOVQ" 32(%[tmp]), "MM"7 \n\t" /* e */\
-            "psubw     "MM"4, "MM"2 \n\t" /* b-c */\
-            "psubw     "MM"7, "MM"3 \n\t" /* f-e */\
-            MOVQ"      "MM"5, "MM"0 \n\t"\
-            "psubw     "MM"4, "MM"5 \n\t" /* d-c */\
-            "psubw     "MM"7, "MM"0 \n\t" /* d-e */\
-            MOVQ"      "MM"2, "MM"4 \n\t"\
-            "pminsw    "MM"3, "MM"2 \n\t"\
-            "pmaxsw    "MM"4, "MM"3 \n\t"\
-            "pmaxsw    "MM"5, "MM"2 \n\t"\
-            "pminsw    "MM"5, "MM"3 \n\t"\
-            "pmaxsw    "MM"0, "MM"2 \n\t" /* max */\
-            "pminsw    "MM"0, "MM"3 \n\t" /* min */\
-            "pxor      "MM"4, "MM"4 \n\t"\
-            "pmaxsw    "MM"3, "MM"6 \n\t"\
-            "psubw     "MM"2, "MM"4 \n\t" /* -max */\
-            "pmaxsw    "MM"4, "MM"6 \n\t" /* diff= MAX3(diff, min, -max); */\
-            "1: \n\t"\
-\
-            MOVQ" 16(%[tmp]), "MM"2 \n\t" /* d */\
-            MOVQ"      "MM"2, "MM"3 \n\t"\
-            "psubw     "MM"6, "MM"2 \n\t" /* d-diff */\
-            "paddw     "MM"6, "MM"3 \n\t" /* d+diff */\
-            "pmaxsw    "MM"2, "MM"1 \n\t"\
-            "pminsw    "MM"3, "MM"1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\
-            "packuswb  "MM"1, "MM"1 \n\t"\
-\
-            ::[prev] "r"(prev),\
-             [cur]  "r"(cur),\
-             [next] "r"(next),\
-             [prefs]"r"((x86_reg)prefs),\
-             [mrefs]"r"((x86_reg)mrefs),\
-             [mode] "g"(mode),\
-             [tmp]  "r"(tmp)\
-        );\
-        __asm__ volatile(MOV" "MM"1, %0" :"=m"(*dst));\
-        dst += STEP;\
-        prev+= STEP;\
-        cur += STEP;\
-        next+= STEP;\
-    }
-
-    if (parity) {
-#define prev2 "prev"
-#define next2 "cur"
-        FILTER
-#undef prev2
-#undef next2
-    } else {
-#define prev2 "cur"
-#define next2 "next"
-        FILTER
-#undef prev2
-#undef next2
-    }
-}
-#undef STEP
-#undef MM
-#undef MOV
-#undef MOVQ
-#undef MOVQU
-#undef PSHUF
-#undef PSRL1
-#undef PSRL2
-#undef LOAD
-#undef PABS
-#undef CHECK
-#undef CHECK1
-#undef CHECK2
-#undef FILTER
diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h
index 06b39c6..6936723 100644
--- a/libavfilter/yadif.h
+++ b/libavfilter/yadif.h
@@ -23,6 +23,7 @@
 #include "avfilter.h"
 
 typedef struct YADIFContext {
+    const AVClass *class;
     /**
      * 0: send 1 frame for each frame
      * 1: send 1 frame for each field
@@ -46,13 +47,19 @@ typedef struct YADIFContext {
      */
     int auto_enable;
 
-    AVFilterBufferRef *cur;
-    AVFilterBufferRef *next;
-    AVFilterBufferRef *prev;
-    AVFilterBufferRef *out;
-    void (*filter_line)(uint8_t *dst,
-                        uint8_t *prev, uint8_t *cur, uint8_t *next,
+    AVFrame *cur;
+    AVFrame *next;
+    AVFrame *prev;
+    AVFrame *out;
+
+    /**
+     * Required alignment for filter_line
+     */
+    void (*filter_line)(void *dst,
+                        void *prev, void *cur, void *next,
                         int w, int prefs, int mrefs, int parity, int mode);
+    void (*filter_edges)(void *dst, void *prev, void *cur, void *next,
+                         int w, int prefs, int mrefs, int parity, int mode);
 
     const AVPixFmtDescriptor *csp;
     int eof;
diff --git a/libavformat/4xm.c b/libavformat/4xm.c
index 9dfb956..7a87c36 100644
--- a/libavformat/4xm.c
+++ b/libavformat/4xm.c
@@ -131,19 +131,11 @@ static int parse_strk(AVFormatContext *s,
         return AVERROR_INVALIDDATA;
 
     track = AV_RL32(buf + 8);
-
-    if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) {
-        av_log(s, AV_LOG_ERROR, "current_track too large\n");
-        return AVERROR_INVALIDDATA;
-    }
     if (track < 0)
         return AVERROR_INVALIDDATA;
     if (track + 1 > fourxm->track_count) {
-        AudioTrack *tmp = av_realloc(fourxm->tracks,
-                                     (track + 1) * sizeof(AudioTrack));
-        if (!tmp)
+        if (av_reallocp_array(&fourxm->tracks, track + 1, sizeof(AudioTrack)))
             return AVERROR(ENOMEM);
-        fourxm->tracks = tmp;
         memset(&fourxm->tracks[fourxm->track_count], 0,
                sizeof(AudioTrack) * (track + 1 - fourxm->track_count));
         fourxm->track_count = track + 1;
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 14e3e1e..8605a1c 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -9,6 +9,7 @@ OBJS = allformats.o         \
        avio.o               \
        aviobuf.o            \
        cutils.o             \
+       format.o             \
        id3v1.o              \
        id3v2.o              \
        log2_tab.o           \
@@ -19,9 +20,12 @@ OBJS = allformats.o         \
        riff.o               \
        sdp.o                \
        seek.o               \
+       url.o                \
        utils.o              \
 
 OBJS-$(CONFIG_NETWORK)                   += network.o
+OBJS-$(CONFIG_RIFFDEC)                   += riffdec.o
+OBJS-$(CONFIG_RIFFENC)                   += riffenc.o
 OBJS-$(CONFIG_RTPDEC)                    += rdt.o                       \
                                             rtp.o                       \
                                             rtpdec.o                    \
@@ -34,13 +38,16 @@ OBJS-$(CONFIG_RTPDEC)                    += rdt.o                       \
                                             rtpdec_ilbc.o               \
                                             rtpdec_jpeg.o               \
                                             rtpdec_latm.o               \
+                                            rtpdec_mpeg12.o             \
                                             rtpdec_mpeg4.o              \
+                                            rtpdec_mpegts.o             \
                                             rtpdec_qcelp.o              \
                                             rtpdec_qdm2.o               \
                                             rtpdec_qt.o                 \
                                             rtpdec_svq3.o               \
                                             rtpdec_vp8.o                \
-                                            rtpdec_xiph.o
+                                            rtpdec_xiph.o               \
+                                            srtp.o
 OBJS-$(CONFIG_RTPENC_CHAIN)              += rtpenc_chain.o rtp.o
 
 # muxers/demuxers
@@ -65,7 +72,7 @@ OBJS-$(CONFIG_ASF_MUXER)                 += asfenc.o asf.o
 OBJS-$(CONFIG_ASS_DEMUXER)               += assdec.o
 OBJS-$(CONFIG_ASS_MUXER)                 += assenc.o
 OBJS-$(CONFIG_AU_DEMUXER)                += au.o pcm.o
-OBJS-$(CONFIG_AU_MUXER)                  += au.o
+OBJS-$(CONFIG_AU_MUXER)                  += au.o rawenc.o
 OBJS-$(CONFIG_AVI_DEMUXER)               += avidec.o
 OBJS-$(CONFIG_AVI_MUXER)                 += avienc.o
 OBJS-$(CONFIG_AVISYNTH)                  += avisynth.o
@@ -107,6 +114,7 @@ OBJS-$(CONFIG_FFMETADATA_MUXER)          += ffmetaenc.o
 OBJS-$(CONFIG_FILMSTRIP_DEMUXER)         += filmstripdec.o
 OBJS-$(CONFIG_FILMSTRIP_MUXER)           += filmstripenc.o
 OBJS-$(CONFIG_FLAC_DEMUXER)              += flacdec.o rawdec.o \
+                                            flac_picture.o   \
                                             oggparsevorbis.o \
                                             vorbiscomment.o
 OBJS-$(CONFIG_FLAC_MUXER)                += flacenc.o flacenc_header.o \
@@ -130,8 +138,11 @@ OBJS-$(CONFIG_H263_DEMUXER)              += h263dec.o rawdec.o
 OBJS-$(CONFIG_H263_MUXER)                += rawenc.o
 OBJS-$(CONFIG_H264_DEMUXER)              += h264dec.o rawdec.o
 OBJS-$(CONFIG_H264_MUXER)                += rawenc.o
+OBJS-$(CONFIG_HDS_MUXER)                 += hdsenc.o
+OBJS-$(CONFIG_HEVC_DEMUXER)              += hevcdec.o rawdec.o
 OBJS-$(CONFIG_HLS_DEMUXER)               += hls.o
-OBJS-$(CONFIG_HLS_MUXER)                 += hlsenc.o mpegtsenc.o
+OBJS-$(CONFIG_HLS_MUXER)                 += hlsenc.o
+OBJS-$(CONFIG_HNM_DEMUXER)               += hnm.o
 OBJS-$(CONFIG_IDCIN_DEMUXER)             += idcin.o
 OBJS-$(CONFIG_IFF_DEMUXER)               += iff.o
 OBJS-$(CONFIG_ILBC_DEMUXER)              += ilbc.o
@@ -157,7 +168,7 @@ OBJS-$(CONFIG_MATROSKA_DEMUXER)          += matroskadec.o matroska.o  \
                                             isom.o rmsipr.o
 OBJS-$(CONFIG_MATROSKA_MUXER)            += matroskaenc.o matroska.o \
                                             isom.o avc.o \
-                                            flacenc_header.o avlanguage.o
+                                            flacenc_header.o avlanguage.o wv.o
 OBJS-$(CONFIG_MD5_MUXER)                 += md5enc.o
 OBJS-$(CONFIG_MJPEG_DEMUXER)             += rawdec.o
 OBJS-$(CONFIG_MJPEG_MUXER)               += rawenc.o
@@ -203,11 +214,13 @@ OBJS-$(CONFIG_OGG_DEMUXER)               += oggdec.o         \
                                             oggparsedirac.o  \
                                             oggparseflac.o   \
                                             oggparseogm.o    \
+                                            oggparseopus.o   \
                                             oggparseskeleton.o \
                                             oggparsespeex.o  \
                                             oggparsetheora.o \
                                             oggparsevorbis.o \
-                                            vorbiscomment.o
+                                            vorbiscomment.o  \
+                                            flac_picture.o
 OBJS-$(CONFIG_OGG_MUXER)                 += oggenc.o \
                                             vorbiscomment.o
 OBJS-$(CONFIG_OMA_DEMUXER)               += omadec.o pcm.o oma.o
@@ -326,12 +339,13 @@ OBJS-$(CONFIG_WAV_MUXER)                 += wavenc.o
 OBJS-$(CONFIG_WC3_DEMUXER)               += wc3movie.o
 OBJS-$(CONFIG_WEBM_MUXER)                += matroskaenc.o matroska.o \
                                             isom.o avc.o \
-                                            flacenc_header.o avlanguage.o
+                                            flacenc_header.o avlanguage.o wv.o
 OBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood_aud.o
 OBJS-$(CONFIG_WSVQA_DEMUXER)             += westwood_vqa.o
 OBJS-$(CONFIG_WTV_DEMUXER)               += wtv.o asfdec.o asf.o asfcrypt.o \
                                             avlanguage.o mpegts.o isom.o
-OBJS-$(CONFIG_WV_DEMUXER)                += wv.o apetag.o img2.o
+OBJS-$(CONFIG_WV_DEMUXER)                += wvdec.o wv.o apetag.o img2.o
+OBJS-$(CONFIG_WV_MUXER)                  += wvenc.o wv.o apetag.o img2.o
 OBJS-$(CONFIG_XA_DEMUXER)                += xa.o
 OBJS-$(CONFIG_XMV_DEMUXER)               += xmv.o
 OBJS-$(CONFIG_XWMA_DEMUXER)              += xwma.o
@@ -366,22 +380,26 @@ OBJS-$(CONFIG_RTMPTE_PROTOCOL)           += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTMPTS_PROTOCOL)           += rtmpproto.o rtmppkt.o
 OBJS-$(CONFIG_RTP_PROTOCOL)              += rtpproto.o
 OBJS-$(CONFIG_SCTP_PROTOCOL)             += sctp.o
+OBJS-$(CONFIG_SRTP_PROTOCOL)             += srtpproto.o srtp.o
 OBJS-$(CONFIG_TCP_PROTOCOL)              += tcp.o
 OBJS-$(CONFIG_TLS_PROTOCOL)              += tls.o
 OBJS-$(CONFIG_UDP_PROTOCOL)              += udp.o
+OBJS-$(CONFIG_UNIX_PROTOCOL)             += unix.o
+
+OBJS-$(HAVE_LIBC_MSVCRT)                 += file_open.o
 
 SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
 SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
 
 EXAMPLES  = metadata                                                    \
-            output                                                      \
 
 TESTPROGS = seek                                                        \
+            srtp                                                        \
             url                                                         \
 
+TESTPROGS-$(CONFIG_NETWORK)              += noproxy
+
 TOOLS     = aviocat                                                     \
             ismindex                                                    \
             pktdumper                                                   \
             probetest                                                   \
-
-$(SUBDIR)output-example$(EXESUF): ELIBS = $(patsubst %,$(LD_LIB),swscale)
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index 6f9763f..8d87ce6 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -54,9 +54,9 @@ static int adts_aac_probe(AVProbeData *p)
         if(buf == buf0)
             first_frames= frames;
     }
-    if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
-    else if(max_frames>500)return AVPROBE_SCORE_MAX/2;
-    else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
+    if   (first_frames>=3) return AVPROBE_SCORE_EXTENSION + 1;
+    else if(max_frames>500)return AVPROBE_SCORE_EXTENSION;
+    else if(max_frames>=3) return AVPROBE_SCORE_EXTENSION / 2;
     else if(max_frames>=1) return 1;
     else                   return 0;
 }
diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c
index d3f2ec2..4ceffa5 100644
--- a/libavformat/ac3dec.c
+++ b/libavformat/ac3dec.c
@@ -57,7 +57,7 @@ static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id)
     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 (first_frames >= 4) return AVPROBE_SCORE_EXTENSION + 1;
 
     if (max_frames) {
         int pes = 0, i;
@@ -78,8 +78,8 @@ static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id)
         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;
+    if      (max_frames >  500) return AVPROBE_SCORE_EXTENSION;
+    else if (max_frames >= 4)   return AVPROBE_SCORE_EXTENSION / 2;
     else if (max_frames >= 1)   return 1;
     else                        return 0;
 }
diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c
index 0c91944..e7c9ca6 100644
--- a/libavformat/adtsenc.c
+++ b/libavformat/adtsenc.c
@@ -158,7 +158,6 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt)
         }
     }
     avio_write(pb, pkt->data, pkt->size);
-    avio_flush(pb);
 
     return 0;
 }
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index abcc424..d4bffb3 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavutil/intfloat.h"
 #include "avformat.h"
 #include "internal.h"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 34cf566..3bc128b 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -45,8 +45,7 @@
     {                                                                   \
         extern URLProtocol ff_##x##_protocol;                           \
         if (CONFIG_##X##_PROTOCOL)                                      \
-            ffurl_register_protocol(&ff_##x##_protocol,                 \
-                                    sizeof(ff_##x##_protocol));         \
+            ffurl_register_protocol(&ff_##x##_protocol);                \
     }
 
 void av_register_all(void)
@@ -100,6 +99,7 @@ void av_register_all(void)
     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);
@@ -117,7 +117,10 @@ void av_register_all(void)
     REGISTER_MUXDEMUX(H261,             h261);
     REGISTER_MUXDEMUX(H263,             h263);
     REGISTER_MUXDEMUX(H264,             h264);
+    REGISTER_MUXER   (HDS,              hds);
+    REGISTER_DEMUXER (HEVC,             hevc);
     REGISTER_MUXDEMUX(HLS,              hls);
+    REGISTER_DEMUXER (HNM,              hnm);
     REGISTER_DEMUXER (IDCIN,            idcin);
     REGISTER_DEMUXER (IFF,              iff);
     REGISTER_MUXDEMUX(ILBC,             ilbc);
@@ -209,8 +212,8 @@ void av_register_all(void)
     REGISTER_MUXDEMUX(SAP,              sap);
     REGISTER_DEMUXER (SDP,              sdp);
 #if CONFIG_RTPDEC
-    av_register_rtp_dynamic_payload_handlers();
-    av_register_rdt_dynamic_payload_handlers();
+    ff_register_rtp_dynamic_payload_handlers();
+    ff_register_rdt_dynamic_payload_handlers();
 #endif
     REGISTER_DEMUXER (SEGAFILM,         segafilm);
     REGISTER_MUXER   (SEGMENT,          segment);
@@ -247,7 +250,7 @@ void av_register_all(void)
     REGISTER_DEMUXER (WSAUD,            wsaud);
     REGISTER_DEMUXER (WSVQA,            wsvqa);
     REGISTER_DEMUXER (WTV,              wtv);
-    REGISTER_DEMUXER (WV,               wv);
+    REGISTER_MUXDEMUX(WV,               wv);
     REGISTER_DEMUXER (XA,               xa);
     REGISTER_DEMUXER (XMV,              xmv);
     REGISTER_DEMUXER (XWMA,             xwma);
@@ -255,9 +258,6 @@ void av_register_all(void)
     REGISTER_MUXDEMUX(YUV4MPEGPIPE,     yuv4mpegpipe);
 
     /* protocols */
-#if FF_API_APPLEHTTP_PROTO
-    REGISTER_PROTOCOL(APPLEHTTP,        applehttp);
-#endif
     REGISTER_PROTOCOL(CONCAT,           concat);
     REGISTER_PROTOCOL(CRYPTO,           crypto);
     REGISTER_PROTOCOL(FFRTMPCRYPT,      ffrtmpcrypt);
@@ -280,9 +280,11 @@ void av_register_all(void)
     REGISTER_PROTOCOL(RTMPTS,           rtmpts);
     REGISTER_PROTOCOL(RTP,              rtp);
     REGISTER_PROTOCOL(SCTP,             sctp);
+    REGISTER_PROTOCOL(SRTP,             srtp);
     REGISTER_PROTOCOL(TCP,              tcp);
     REGISTER_PROTOCOL(TLS,              tls);
     REGISTER_PROTOCOL(UDP,              udp);
+    REGISTER_PROTOCOL(UNIX,             unix);
 
     /* external libraries */
     REGISTER_PROTOCOL(LIBRTMP,          librtmp);
diff --git a/libavformat/amr.c b/libavformat/amr.c
index ba91d7c..3b1a468 100644
--- a/libavformat/amr.c
+++ b/libavformat/amr.c
@@ -55,7 +55,6 @@ static int amr_write_header(AVFormatContext *s)
 static int amr_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     avio_write(s->pb, pkt->data, pkt->size);
-    avio_flush(s->pb);
     return 0;
 }
 #endif /* CONFIG_AMR_MUXER */
diff --git a/libavformat/anm.c b/libavformat/anm.c
index 7e52e83..f781492 100644
--- a/libavformat/anm.c
+++ b/libavformat/anm.c
@@ -85,7 +85,7 @@ static int read_header(AVFormatContext *s)
 
     avio_skip(pb, 4); /* magic number */
     if (avio_rl16(pb) != MAX_PAGES) {
-        av_log_ask_for_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES) "\n");
+        avpriv_request_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES));
         return AVERROR_PATCHWELCOME;
     }
 
@@ -135,17 +135,16 @@ static int read_header(AVFormatContext *s)
     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;
+        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];
@@ -157,19 +156,15 @@ static int read_header(AVFormatContext *s)
     /* find page of first frame */
     anm->page = find_record(anm, 0);
     if (anm->page < 0) {
-        ret = anm->page;
-        goto fail;
+        return anm->page;
     }
 
     anm->record = -1;
     return 0;
 
 invalid:
-    av_log_ask_for_sample(s, NULL);
-    ret = AVERROR_PATCHWELCOME;
-
-fail:
-    return ret;
+    avpriv_request_sample(s, "Invalid header element");
+    return AVERROR_PATCHWELCOME;
 }
 
 static int read_packet(AVFormatContext *s,
diff --git a/libavformat/ape.c b/libavformat/ape.c
index 3c25630..d967a5d 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -28,7 +28,7 @@
 #include "apetag.h"
 
 /* The earliest and latest file formats supported by this library */
-#define APE_MIN_VERSION 3950
+#define APE_MIN_VERSION 3800
 #define APE_MAX_VERSION 3990
 
 #define MAC_FORMAT_FLAG_8_BIT                 1 // is 8-bit [OBSOLETE]
@@ -83,6 +83,7 @@ typedef struct {
 
     /* Seektable */
     uint32_t *seektable;
+    uint8_t  *bittable;
 } APEContext;
 
 static int ape_probe(AVProbeData * p)
@@ -130,9 +131,13 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx)
     } else {
         for (i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++) {
             if (i < ape_ctx->totalframes - 1) {
-                av_log(s, AV_LOG_DEBUG, "%8d   %"PRIu32" (%"PRIu32" bytes)\n",
+                av_log(s, AV_LOG_DEBUG, "%8d   %"PRIu32" (%"PRIu32" bytes)",
                        i, ape_ctx->seektable[i],
                        ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]);
+                if (ape_ctx->bittable)
+                    av_log(s, AV_LOG_DEBUG, " + %2d bits\n",
+                           ape_ctx->bittable[i]);
+                av_log(s, AV_LOG_DEBUG, "\n");
             } else {
                 av_log(s, AV_LOG_DEBUG, "%8d   %"PRIu32"\n", i, ape_ctx->seektable[i]);
             }
@@ -265,6 +270,8 @@ static int ape_read_header(AVFormatContext * s)
     if(!ape->frames)
         return AVERROR(ENOMEM);
     ape->firstframe   = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength;
+    if (ape->fileversion < 3810)
+        ape->firstframe += ape->totalframes;
     ape->currentframe = 0;
 
 
@@ -276,10 +283,15 @@ static int ape_read_header(AVFormatContext * s)
         ape->seektable = av_malloc(ape->seektablelength);
         if (!ape->seektable)
             return AVERROR(ENOMEM);
-        for (i = 0;
-             i < ape->seektablelength / sizeof(uint32_t) && !pb->eof_reached;
-             i++)
+        for (i = 0; i < ape->seektablelength / sizeof(uint32_t) && !pb->eof_reached; i++)
             ape->seektable[i] = avio_rl32(pb);
+        if (ape->fileversion < 3810) {
+            ape->bittable = av_malloc(ape->totalframes);
+            if (!ape->bittable)
+                return AVERROR(ENOMEM);
+            for (i = 0; i < ape->totalframes && !pb->eof_reached; i++)
+                ape->bittable[i] = avio_r8(pb);
+        }
     }
 
     ape->frames[0].pos     = ape->firstframe;
@@ -310,7 +322,14 @@ static int ape_read_header(AVFormatContext * s)
         }
         ape->frames[i].size = (ape->frames[i].size + 3) & ~3;
     }
-
+    if (ape->fileversion < 3810) {
+        for (i = 0; i < ape->totalframes; i++) {
+            if (i < ape->totalframes - 1 && ape->bittable[i + 1])
+                ape->frames[i].size += 4;
+            ape->frames[i].skip <<= 3;
+            ape->frames[i].skip  += ape->bittable[i];
+        }
+    }
 
     ape_dumpinfo(s, ape);
 
@@ -413,6 +432,7 @@ static int ape_read_close(AVFormatContext * s)
 
     av_freep(&ape->frames);
     av_freep(&ape->seektable);
+    av_freep(&ape->bittable);
     return 0;
 }
 
diff --git a/libavformat/apetag.c b/libavformat/apetag.c
index bb8b2df..d4be91c 100644
--- a/libavformat/apetag.c
+++ b/libavformat/apetag.c
@@ -23,12 +23,14 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #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_CONTAINS_FOOTER  (1 << 30)
 #define APE_TAG_FLAG_IS_HEADER        (1 << 29)
 #define APE_TAG_FLAG_IS_BINARY        (1 << 1)
 
@@ -169,3 +171,57 @@ int64_t ff_ape_parse_tag(AVFormatContext *s)
 
     return tag_start;
 }
+
+int ff_ape_write_tag(AVFormatContext *s)
+{
+    AVDictionaryEntry *e = NULL;
+    int64_t start, end;
+    int size, count = 0;
+
+    if (!s->pb->seekable)
+        return 0;
+
+    start = avio_tell(s->pb);
+
+    // header
+    avio_write(s->pb, "APETAGEX", 8);   // id
+    avio_wl32 (s->pb, APE_TAG_VERSION); // version
+    avio_wl32(s->pb, 0);                // reserve space for size
+    avio_wl32(s->pb, 0);                // reserve space for tag count
+
+    // flags
+    avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER |
+                     APE_TAG_FLAG_IS_HEADER);
+    ffio_fill(s->pb, 0, 8);             // reserved
+
+    while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
+        int val_len = strlen(e->value);
+
+        avio_wl32(s->pb, val_len);            // value length
+        avio_wl32(s->pb, 0);                  // item flags
+        avio_put_str(s->pb, e->key);          // key
+        avio_write(s->pb, e->value, val_len); // value
+        count++;
+    }
+
+    size = avio_tell(s->pb) - start;
+
+    // footer
+    avio_write(s->pb, "APETAGEX", 8);   // id
+    avio_wl32 (s->pb, APE_TAG_VERSION); // version
+    avio_wl32(s->pb, size);             // size
+    avio_wl32(s->pb, count);            // tag count
+
+    // flags
+    avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER);
+    ffio_fill(s->pb, 0, 8);             // reserved
+
+    // update values in the header
+    end = avio_tell(s->pb);
+    avio_seek(s->pb, start + 12, SEEK_SET);
+    avio_wl32(s->pb, size);
+    avio_wl32(s->pb, count);
+    avio_seek(s->pb, end, SEEK_SET);
+
+    return 0;
+}
diff --git a/libavformat/apetag.h b/libavformat/apetag.h
index 279972f..36e3211 100644
--- a/libavformat/apetag.h
+++ b/libavformat/apetag.h
@@ -32,4 +32,9 @@
  */
 int64_t ff_ape_parse_tag(AVFormatContext *s);
 
+/**
+ * Write an APE tag into a file.
+ */
+int ff_ape_write_tag(AVFormatContext *s);
+
 #endif /* AVFORMAT_APETAG_H */
diff --git a/libavformat/asf.c b/libavformat/asf.c
index cc2833d..ec34b50 100644
--- a/libavformat/asf.c
+++ b/libavformat/asf.c
@@ -20,7 +20,6 @@
 
 #include "asf.h"
 
-
 const ff_asf_guid ff_asf_header = {
     0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C
 };
@@ -48,7 +47,7 @@ const ff_asf_guid ff_asf_audio_conceal_none = {
 };
 
 const ff_asf_guid ff_asf_audio_conceal_spread = {
-     0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20
+    0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20
 };
 
 const ff_asf_guid ff_asf_video_stream = {
@@ -91,31 +90,39 @@ const ff_asf_guid ff_asf_head2_guid = {
 };
 
 const ff_asf_guid ff_asf_extended_content_header = {
-        0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50
+    0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50
 };
 
 const ff_asf_guid ff_asf_simple_index_header = {
-        0x90, 0x08, 0x00, 0x33, 0xB1, 0xE5, 0xCF, 0x11, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB
+    0x90, 0x08, 0x00, 0x33, 0xB1, 0xE5, 0xCF, 0x11, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB
 };
 
 const ff_asf_guid ff_asf_ext_stream_embed_stream_header = {
-        0xe2, 0x65, 0xfb, 0x3a, 0xEF, 0x47, 0xF2, 0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43
+    0xe2, 0x65, 0xfb, 0x3a, 0xEF, 0x47, 0xF2, 0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43
 };
 
 const ff_asf_guid ff_asf_ext_stream_audio_stream = {
-        0x9d, 0x8c, 0x17, 0x31, 0xE1, 0x03, 0x28, 0x45, 0xb5, 0x82, 0x3d, 0xf9, 0xdb, 0x22, 0xf5, 0x03
+    0x9d, 0x8c, 0x17, 0x31, 0xE1, 0x03, 0x28, 0x45, 0xb5, 0x82, 0x3d, 0xf9, 0xdb, 0x22, 0xf5, 0x03
 };
 
 const ff_asf_guid ff_asf_metadata_header = {
-        0xea, 0xcb, 0xf8, 0xc5, 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca
+    0xea, 0xcb, 0xf8, 0xc5, 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca
+};
+
+const ff_asf_guid ff_asf_metadata_library_header = {
+    0x94, 0x1c, 0x23, 0x44, 0x98, 0x94, 0xd1, 0x49, 0xa1, 0x41, 0x1d, 0x13, 0x4e, 0x45, 0x70, 0x54
 };
 
 const ff_asf_guid ff_asf_marker_header = {
-        0x01, 0xCD, 0x87, 0xF4, 0x51, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65
+    0x01, 0xCD, 0x87, 0xF4, 0x51, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65
+};
+
+const ff_asf_guid ff_asf_reserved_4 = {
+        0x20, 0xdb, 0xfe, 0x4c, 0xf6, 0x75, 0xCF, 0x11, 0x9c, 0x0f, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb
 };
 
 /* I am not a number !!! This GUID is the one found on the PC used to
-   generate the stream */
+ * generate the stream */
 const ff_asf_guid ff_asf_my_guid = {
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
@@ -138,23 +145,23 @@ const ff_asf_guid ff_asf_digital_signature = {
 
 /* List of official tags at http://msdn.microsoft.com/en-us/library/dd743066(VS.85).aspx */
 const AVMetadataConv ff_asf_metadata_conv[] = {
-    { "WM/AlbumArtist"     , "album_artist"},
-    { "WM/AlbumTitle"      , "album"       },
-    { "Author"             , "artist"      },
-    { "Description"        , "comment"     },
-    { "WM/Composer"        , "composer"    },
-    { "WM/EncodedBy"       , "encoded_by"  },
-    { "WM/EncodingSettings", "encoder"     },
-    { "WM/Genre"           , "genre"       },
-    { "WM/Language"        , "language"    },
-    { "WM/OriginalFilename", "filename"    },
-    { "WM/PartOfSet"       , "disc"        },
-    { "WM/Publisher"       , "publisher"   },
-    { "WM/Tool"            , "encoder"     },
-    { "WM/TrackNumber"     , "track"       },
-    { "WM/Track"           , "track"       },
+    { "WM/AlbumArtist",          "album_artist"     },
+    { "WM/AlbumTitle",           "album"            },
+    { "Author",                  "artist"           },
+    { "Description",             "comment"          },
+    { "WM/Composer",             "composer"         },
+    { "WM/EncodedBy",            "encoded_by"       },
+    { "WM/EncodingSettings",     "encoder"          },
+    { "WM/Genre",                "genre"            },
+    { "WM/Language",             "language"         },
+    { "WM/OriginalFilename",     "filename"         },
+    { "WM/PartOfSet",            "disc"             },
+    { "WM/Publisher",            "publisher"        },
+    { "WM/Tool",                 "encoder"          },
+    { "WM/TrackNumber",          "track"            },
+    { "WM/Track",                "track"            },
     { "WM/MediaStationCallSign", "service_provider" },
-    { "WM/MediaStationName", "service_name" },
+    { "WM/MediaStationName",     "service_name"     },
 //  { "Year"               , "date"        }, TODO: conversion year<->date
     { 0 }
 };
diff --git a/libavformat/asf.h b/libavformat/asf.h
index 1d94a2c..2f6722a 100644
--- a/libavformat/asf.h
+++ b/libavformat/asf.h
@@ -24,6 +24,7 @@
 #include <stdint.h>
 #include "avformat.h"
 #include "metadata.h"
+#include "riff.h"
 
 #define PACKET_SIZE 3200
 
@@ -48,8 +49,6 @@ typedef struct ASFStream {
     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
@@ -79,6 +78,8 @@ typedef struct ASFMainHeader {
 typedef struct ASFIndex {
     uint32_t packet_number;
     uint16_t packet_count;
+    uint64_t send_time;
+    uint64_t offset;
 } ASFIndex;
 
 extern const ff_asf_guid ff_asf_header;
@@ -103,7 +104,9 @@ extern const ff_asf_guid ff_asf_simple_index_header;
 extern const ff_asf_guid ff_asf_ext_stream_embed_stream_header;
 extern const ff_asf_guid ff_asf_ext_stream_audio_stream;
 extern const ff_asf_guid ff_asf_metadata_header;
+extern const ff_asf_guid ff_asf_metadata_library_header;
 extern const ff_asf_guid ff_asf_marker_header;
+extern const ff_asf_guid ff_asf_reserved_4;
 extern const ff_asf_guid ff_asf_my_guid;
 extern const ff_asf_guid ff_asf_language_guid;
 extern const ff_asf_guid ff_asf_content_encryption;
@@ -175,11 +178,4 @@ extern const AVMetadataConv ff_asf_metadata_conv[];
 
 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);
-
 #endif /* AVFORMAT_ASF_H */
diff --git a/libavformat/asfcrypt.c b/libavformat/asfcrypt.c
index 6c48a19..c261475 100644
--- a/libavformat/asfcrypt.c
+++ b/libavformat/asfcrypt.c
@@ -20,10 +20,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
 #include "libavutil/bswap.h"
+#include "libavutil/common.h"
 #include "libavutil/des.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/rc4.h"
 #include "asfcrypt.h"
 
@@ -32,7 +32,8 @@
  * @param v number to invert, must be odd!
  * @return number so that result * v = 1 (mod 2^32)
  */
-static uint32_t inverse(uint32_t v) {
+static uint32_t inverse(uint32_t v)
+{
     // v ^ 3 gives the inverse (mod 16), could also be implemented
     // as table etc. (only lowest 4 bits matter!)
     uint32_t inverse = v * v * v;
@@ -50,7 +51,8 @@ static uint32_t inverse(uint32_t v) {
  * @param keys output key array containing the keys for encryption in
  *             native endianness
  */
-static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12]) {
+static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12])
+{
     int i;
     for (i = 0; i < 12; i++)
         keys[i] = AV_RL32(keybuf + (i << 2)) | 1;
@@ -61,7 +63,8 @@ static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12]) {
  *        the other way round.
  * @param keys key array of ints to invert
  */
-static void multiswap_invert_keys(uint32_t keys[12]) {
+static void multiswap_invert_keys(uint32_t keys[12])
+{
     int i;
     for (i = 0; i < 5; i++)
         keys[i] = inverse(keys[i]);
@@ -69,23 +72,25 @@ static void multiswap_invert_keys(uint32_t keys[12]) {
         keys[i] = inverse(keys[i]);
 }
 
-static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v) {
+static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v)
+{
     int i;
     v *= keys[0];
     for (i = 1; i < 5; i++) {
-        v = (v >> 16) | (v << 16);
+        v  = (v >> 16) | (v << 16);
         v *= keys[i];
     }
     v += keys[5];
     return v;
 }
 
-static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v) {
+static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v)
+{
     int i;
     v -= keys[5];
     for (i = 4; i > 0; i--) {
         v *= keys[i];
-        v = (v >> 16) | (v << 16);
+        v  = (v >> 16) | (v << 16);
     }
     v *= keys[0];
     return v;
@@ -99,17 +104,19 @@ static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v) {
  * @param data data to encrypt
  * @return encrypted data
  */
-static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t data) {
+static uint64_t multiswap_enc(const uint32_t keys[12],
+                              uint64_t key, uint64_t data)
+{
     uint32_t a = data;
     uint32_t b = data >> 32;
     uint32_t c;
     uint32_t tmp;
-    a += key;
-    tmp = multiswap_step(keys    , a);
-    b += tmp;
-    c = (key >> 32) + tmp;
+    a  += key;
+    tmp = multiswap_step(keys, a);
+    b  += tmp;
+    c   = (key >> 32) + tmp;
     tmp = multiswap_step(keys + 6, b);
-    c += tmp;
+    c  += tmp;
     return ((uint64_t)c << 32) | tmp;
 }
 
@@ -121,25 +128,28 @@ static uint64_t multiswap_enc(const uint32_t keys[12], uint64_t key, uint64_t da
  * @param data data to decrypt
  * @return decrypted data
  */
-static uint64_t multiswap_dec(const uint32_t keys[12], uint64_t key, uint64_t data) {
+static uint64_t multiswap_dec(const uint32_t keys[12],
+                              uint64_t key, uint64_t data)
+{
     uint32_t a;
     uint32_t b;
-    uint32_t c = data >> 32;
+    uint32_t c   = data >> 32;
     uint32_t tmp = data;
-    c -= tmp;
-    b = multiswap_inv_step(keys + 6, tmp);
+    c  -= tmp;
+    b   = multiswap_inv_step(keys + 6, tmp);
     tmp = c - (key >> 32);
-    b -= tmp;
-    a = multiswap_inv_step(keys    , tmp);
-    a -= key;
+    b  -= tmp;
+    a   = multiswap_inv_step(keys, tmp);
+    a  -= key;
     return ((uint64_t)b << 32) | a;
 }
 
-void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len) {
+void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len)
+{
     struct AVDES des;
     struct AVRC4 rc4;
-    int num_qwords = len >> 3;
-    uint8_t *qwords = data;
+    int num_qwords      = len >> 3;
+    uint8_t *qwords     = data;
     uint64_t rc4buff[8] = { 0 };
     uint64_t packetkey;
     uint32_t ms_keys[12];
@@ -155,7 +165,7 @@ void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len) {
     av_rc4_crypt(&rc4, (uint8_t *)rc4buff, NULL, sizeof(rc4buff), NULL, 1);
     multiswap_init((uint8_t *)rc4buff, ms_keys);
 
-    packetkey = AV_RN64(&qwords[num_qwords*8 - 8]);
+    packetkey  = AV_RN64(&qwords[num_qwords * 8 - 8]);
     packetkey ^= rc4buff[7];
     av_des_init(&des, key + 12, 64, 1);
     av_des_crypt(&des, (uint8_t *)&packetkey, (uint8_t *)&packetkey, 1, NULL, 1);
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index e8587af..5b4366e 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -19,23 +19,23 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
 #include "libavutil/bswap.h"
 #include "libavutil/common.h"
-#include "libavutil/avstring.h"
 #include "libavutil/dict.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
-#include "internal.h"
 #include "avio_internal.h"
+#include "avlanguage.h"
 #include "id3v2.h"
+#include "internal.h"
 #include "riff.h"
 #include "asf.h"
 #include "asfcrypt.h"
-#include "avlanguage.h"
 
 typedef struct {
     const AVClass *class;
@@ -75,13 +75,13 @@ typedef struct {
 
     int stream_index;
 
-    ASFStream* asf_st;                   ///< currently decoded stream
+    ASFStream *asf_st;                   ///< currently decoded stream
 
     int no_resync_search;
 } ASFContext;
 
 static const AVOption options[] = {
-    {"no_resync_search", "Don't try to resynchronize by looking for a certain optional start code", offsetof(ASFContext, no_resync_search), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
+    { "no_resync_search", "Don't try to resynchronize by looking for a certain optional start code", offsetof(ASFContext, no_resync_search), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
     { NULL },
 };
 
@@ -108,11 +108,11 @@ static const ff_asf_guid stream_bitrate_guid = { /* (http://get.to/sdp) */
     0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2
 };
 
-#define PRINT_IF_GUID(g,cmp) \
-if (!ff_guidcmp(g, &cmp)) \
-    av_dlog(NULL, "(GUID: %s) ", #cmp)
+#define PRINT_IF_GUID(g, cmp) \
+    if (!ff_guidcmp(g, &cmp)) \
+        av_dlog(NULL, "(GUID: %s) ", # cmp)
 
-static void print_guid(const ff_asf_guid *g)
+static void print_guid(ff_asf_guid *g)
 {
     int i;
     PRINT_IF_GUID(g, ff_asf_header);
@@ -136,12 +136,13 @@ static void print_guid(const ff_asf_guid *g)
     else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header);
     else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream);
     else PRINT_IF_GUID(g, ff_asf_metadata_header);
+    else PRINT_IF_GUID(g, ff_asf_metadata_library_header);
     else PRINT_IF_GUID(g, ff_asf_marker_header);
     else PRINT_IF_GUID(g, stream_bitrate_guid);
     else PRINT_IF_GUID(g, ff_asf_language_guid);
     else
         av_dlog(NULL, "(GUID: unknown) ");
-    for(i=0;i<16;i++)
+    for (i = 0; i < 16; i++)
         av_dlog(NULL, " 0x%02x,", (*g)[i]);
     av_dlog(NULL, "}\n");
 }
@@ -150,12 +151,6 @@ static void print_guid(const ff_asf_guid *g)
 #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 */
@@ -165,13 +160,21 @@ static int asf_probe(AVProbeData *pd)
         return 0;
 }
 
-static int get_value(AVIOContext *pb, int type){
-    switch(type){
-        case 2: return avio_rl32(pb);
-        case 3: return avio_rl32(pb);
-        case 4: return avio_rl64(pb);
-        case 5: return avio_rl16(pb);
-        default:return INT_MIN;
+/* size of type 2 (BOOL) is 32bit for "Extended Content Description Object"
+ * but 16 bit for "Metadata Object" and "Metadata Library Object" */
+static int get_value(AVIOContext *pb, int type, int type2_size)
+{
+    switch (type) {
+    case 2:
+        return (type2_size == 32) ? avio_rl32(pb) : avio_rl16(pb);
+    case 3:
+        return avio_rl32(pb);
+    case 4:
+        return avio_rl64(pb);
+    case 5:
+        return avio_rl16(pb);
+    default:
+        return INT_MIN;
     }
 }
 
@@ -179,12 +182,11 @@ static int get_value(AVIOContext *pb, int type){
  * but in reality this is only loosely similar */
 static int asf_read_picture(AVFormatContext *s, int len)
 {
-    AVPacket pkt = { 0 };
+    AVPacket pkt          = { 0 };
     const CodecMime *mime = ff_id3v2_mime_tags;
-    enum  AVCodecID      id = AV_CODEC_ID_NONE;
+    enum  AVCodecID id    = AV_CODEC_ID_NONE;
     char mimetype[64];
     uint8_t  *desc = NULL;
-    ASFStream *ast = NULL;
     AVStream   *st = NULL;
     int ret, type, picsize, desc_len;
 
@@ -204,7 +206,7 @@ static int asf_read_picture(AVFormatContext *s, int len)
 
     /* picture data size */
     picsize = avio_rl32(s->pb);
-    len -= 4;
+    len    -= 4;
 
     /* picture MIME type */
     len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype));
@@ -238,21 +240,17 @@ static int asf_read_picture(AVFormatContext *s, int len)
     if (ret < 0)
         goto fail;
 
-    st = avformat_new_stream(s, NULL);
-    ast = av_mallocz(sizeof(*ast));
-    if (!st || !ast) {
+    st  = avformat_new_stream(s, NULL);
+    if (!st) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-    st->priv_data = ast;
-
-    st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
-    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-    st->codec->codec_id   = id;
-
-    st->attached_pic      = pkt;
+    st->disposition              |= AV_DISPOSITION_ATTACHED_PIC;
+    st->codec->codec_type         = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_id           = id;
+    st->attached_pic              = pkt;
     st->attached_pic.stream_index = st->index;
-    st->attached_pic.flags |= AV_PKT_FLAG_KEY;
+    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
 
     if (*desc)
         av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL);
@@ -264,38 +262,58 @@ static int asf_read_picture(AVFormatContext *s, int len)
     return 0;
 
 fail:
-    av_freep(&ast);
     av_freep(&desc);
     av_free_packet(&pkt);
     return ret;
 }
 
-static void get_tag(AVFormatContext *s, const char *key, int type, int len)
+static void get_id3_tag(AVFormatContext *s, int len)
+{
+    ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+
+    ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
+    if (id3v2_extra_meta)
+        ff_id3v2_parse_apic(s, &id3v2_extra_meta);
+    ff_id3v2_free_extra_meta(&id3v2_extra_meta);
+}
+
+static void get_tag(AVFormatContext *s, const char *key, int type, int len, int type2_size)
 {
     char *value;
     int64_t off = avio_tell(s->pb);
 
-    if ((unsigned)len >= (UINT_MAX - 1)/2)
+    if ((unsigned)len >= (UINT_MAX - 1) / 2)
         return;
 
-    value = av_malloc(2*len+1);
+    value = av_malloc(2 * len + 1);
     if (!value)
         goto finish;
 
     if (type == 0) {         // UTF16-LE
-        avio_get_str16le(s->pb, len, value, 2*len + 1);
+        avio_get_str16le(s->pb, len, value, 2 * len + 1);
+    } else if (type == 1) {  // byte array
+        if (!strcmp(key, "WM/Picture")) { // handle cover art
+            asf_read_picture(s, len);
+        } else if (!strcmp(key, "ID3")) { // handle ID3 tag
+            get_id3_tag(s, len);
+        } else {
+            av_log(s, AV_LOG_VERBOSE, "Unsupported byte array in tag %s.\n", key);
+        }
+        goto finish;
     } else if (type > 1 && type <= 5) {  // boolean or DWORD or QWORD or WORD
-        uint64_t num = get_value(s->pb, type);
+        uint64_t num = get_value(s->pb, type, type2_size);
         snprintf(value, len, "%"PRIu64, num);
-    } else if (type == 1 && !strcmp(key, "WM/Picture")) { // handle cover art
-        asf_read_picture(s, len);
+    } else if (type == 6) { // (don't) handle GUID
+        av_log(s, AV_LOG_DEBUG, "Unsupported GUID value in tag %s.\n", key);
         goto finish;
     } else {
-        av_log(s, AV_LOG_DEBUG, "Unsupported value type %d in tag %s.\n", type, key);
+        av_log(s, AV_LOG_DEBUG,
+               "Unsupported value type %d in tag %s.\n", type, key);
         goto finish;
     }
     if (*value)
         av_dict_set(&s->metadata, key, value, 0);
+
 finish:
     av_freep(&value);
     avio_seek(s->pb, off + len, SEEK_SET);
@@ -307,20 +325,20 @@ static int asf_read_file_properties(AVFormatContext *s, int64_t size)
     AVIOContext *pb = s->pb;
 
     ff_get_guid(pb, &asf->hdr.guid);
-    asf->hdr.file_size          = avio_rl64(pb);
-    asf->hdr.create_time        = avio_rl64(pb);
+    asf->hdr.file_size   = avio_rl64(pb);
+    asf->hdr.create_time = avio_rl64(pb);
     avio_rl64(pb);                               /* number of packets */
-    asf->hdr.play_time          = avio_rl64(pb);
-    asf->hdr.send_time          = avio_rl64(pb);
-    asf->hdr.preroll            = avio_rl32(pb);
-    asf->hdr.ignore             = avio_rl32(pb);
-    asf->hdr.flags              = avio_rl32(pb);
-    asf->hdr.min_pktsize        = avio_rl32(pb);
-    asf->hdr.max_pktsize        = avio_rl32(pb);
-    if (asf->hdr.min_pktsize >= (1U<<29))
+    asf->hdr.play_time   = avio_rl64(pb);
+    asf->hdr.send_time   = avio_rl64(pb);
+    asf->hdr.preroll     = avio_rl32(pb);
+    asf->hdr.ignore      = avio_rl32(pb);
+    asf->hdr.flags       = avio_rl32(pb);
+    asf->hdr.min_pktsize = avio_rl32(pb);
+    asf->hdr.max_pktsize = avio_rl32(pb);
+    if (asf->hdr.min_pktsize >= (1U << 29))
         return AVERROR_INVALIDDATA;
-    asf->hdr.max_bitrate        = avio_rl32(pb);
-    s->packet_size = asf->hdr.max_pktsize;
+    asf->hdr.max_bitrate = avio_rl32(pb);
+    s->packet_size       = asf->hdr.max_pktsize;
 
     return 0;
 }
@@ -336,7 +354,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
     int type_specific_size, sizeX;
     unsigned int tag1;
     int64_t pos1, pos2, start_time;
-    int test_for_ext_stream_audio, is_dvr_ms_audio=0;
+    int test_for_ext_stream_audio, is_dvr_ms_audio = 0;
 
     if (s->nb_streams == ASF_MAX_STREAMS) {
         av_log(s, AV_LOG_ERROR, "too many streams\n");
@@ -352,15 +370,15 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
     asf_st = av_mallocz(sizeof(ASFStream));
     if (!asf_st)
         return AVERROR(ENOMEM);
-    st->priv_data = asf_st;
+    st->priv_data  = asf_st;
     st->start_time = 0;
-    start_time = asf->hdr.preroll;
+    start_time     = asf->hdr.preroll;
 
     asf_st->stream_language_index = 128; // invalid stream index means no language info
 
-    if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
+    if (!(asf->hdr.flags & 0x01)) { // if we aren't streaming...
         st->duration = asf->hdr.play_time /
-            (10000000 / 1000) - start_time;
+                       (10000000 / 1000) - start_time;
     }
     ff_get_guid(pb, &g);
 
@@ -370,13 +388,13 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
     } else if (!ff_guidcmp(&g, &ff_asf_video_stream)) {
         type = AVMEDIA_TYPE_VIDEO;
     } else if (!ff_guidcmp(&g, &ff_asf_jfif_media)) {
-        type = AVMEDIA_TYPE_VIDEO;
+        type                = AVMEDIA_TYPE_VIDEO;
         st->codec->codec_id = AV_CODEC_ID_MJPEG;
     } else if (!ff_guidcmp(&g, &ff_asf_command_stream)) {
         type = AVMEDIA_TYPE_DATA;
     } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) {
         test_for_ext_stream_audio = 1;
-        type = AVMEDIA_TYPE_UNKNOWN;
+        type                      = AVMEDIA_TYPE_UNKNOWN;
     } else {
         return -1;
     }
@@ -393,8 +411,8 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
     if (test_for_ext_stream_audio) {
         ff_get_guid(pb, &g);
         if (!ff_guidcmp(&g, &ff_asf_ext_stream_audio_stream)) {
-            type = AVMEDIA_TYPE_AUDIO;
-            is_dvr_ms_audio=1;
+            type            = AVMEDIA_TYPE_AUDIO;
+            is_dvr_ms_audio = 1;
             ff_get_guid(pb, &g);
             avio_rl32(pb);
             avio_rl32(pb);
@@ -412,46 +430,46 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
         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->codec->codec_id  = AV_CODEC_ID_PROBE;
             st->codec->codec_tag = 0;
         }
-        if (st->codec->codec_id == AV_CODEC_ID_AAC) {
+        if (st->codec->codec_id == AV_CODEC_ID_AAC)
             st->need_parsing = AVSTREAM_PARSE_NONE;
-        } else {
+        else
             st->need_parsing = AVSTREAM_PARSE_FULL;
-        }
         /* We have to init the frame size at some point .... */
         pos2 = avio_tell(pb);
         if (size >= (pos2 + 8 - pos1 + 24)) {
-            asf_st->ds_span = avio_r8(pb);
+            asf_st->ds_span        = avio_r8(pb);
             asf_st->ds_packet_size = avio_rl16(pb);
-            asf_st->ds_chunk_size = avio_rl16(pb);
-            avio_rl16(pb); //ds_data_size
-            avio_r8(pb);   //ds_silence_data
+            asf_st->ds_chunk_size  = avio_rl16(pb);
+            avio_rl16(pb);  // ds_data_size
+            avio_r8(pb);    // ds_silence_data
         }
         if (asf_st->ds_span > 1) {
-            if (!asf_st->ds_chunk_size
-                    || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)
-                    || asf_st->ds_packet_size % asf_st->ds_chunk_size)
-                asf_st->ds_span = 0; // disable descrambling
+            if (!asf_st->ds_chunk_size                                ||
+                (asf_st->ds_packet_size / asf_st->ds_chunk_size <= 1) ||
+                asf_st->ds_packet_size % asf_st->ds_chunk_size)
+                asf_st->ds_span = 0;  // disable descrambling
         }
     } else if (type == AVMEDIA_TYPE_VIDEO &&
-            size - (avio_tell(pb) - pos1 + 24) >= 51) {
+               size - (avio_tell(pb) - pos1 + 24) >= 51) {
         avio_rl32(pb);
         avio_rl32(pb);
         avio_r8(pb);
         avio_rl16(pb);        /* size */
-        sizeX= avio_rl32(pb); /* size */
-        st->codec->width = avio_rl32(pb);
+        sizeX             = avio_rl32(pb); /* size */
+        st->codec->width  = avio_rl32(pb);
         st->codec->height = avio_rl32(pb);
         /* not available for asf */
         avio_rl16(pb); /* panes */
         st->codec->bits_per_coded_sample = avio_rl16(pb); /* depth */
-        tag1 = avio_rl32(pb);
+        tag1                             = avio_rl32(pb);
         avio_skip(pb, 20);
         if (sizeX > 40) {
             st->codec->extradata_size = sizeX - 40;
-            st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+            st->codec->extradata      = av_mallocz(st->codec->extradata_size +
+                                                   FF_INPUT_BUFFER_PADDING_SIZE);
             avio_read(pb, st->codec->extradata, st->codec->extradata_size);
         }
 
@@ -461,8 +479,8 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
         if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
 #if HAVE_BIGENDIAN
             int i;
-            for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
-                asf_st->palette[i] = av_bswap32(((uint32_t*)st->codec->extradata)[i]);
+            for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE) / 4; i++)
+                asf_st->palette[i] = av_bswap32(((uint32_t *)st->codec->extradata)[i]);
 #else
             memcpy(asf_st->palette, st->codec->extradata,
                    FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
@@ -471,16 +489,18 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
         }
 
         st->codec->codec_tag = tag1;
-        st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
-        if(tag1 == MKTAG('D', 'V', 'R', ' ')){
+        st->codec->codec_id  = ff_codec_get_id(ff_codec_bmp_tags, tag1);
+        if (tag1 == MKTAG('D', 'V', 'R', ' ')) {
             st->need_parsing = AVSTREAM_PARSE_FULL;
-            // issue658 containse wrong w/h and MS even puts a fake seq header with wrong w/h in extradata while a correct one is in te stream. maximum lameness
-            st->codec->width  =
+            /* issue658 contains wrong w/h and MS even puts a fake seq header
+             * with wrong w/h in extradata while a correct one is in the stream.
+             * maximum lameness */
+            st->codec->width      =
                 st->codec->height = 0;
             av_freep(&st->codec->extradata);
-            st->codec->extradata_size=0;
+            st->codec->extradata_size = 0;
         }
-        if(st->codec->codec_id == AV_CODEC_ID_H264)
+        if (st->codec->codec_id == AV_CODEC_ID_H264)
             st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;
     }
     pos2 = avio_tell(pb);
@@ -515,22 +535,22 @@ static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size)
         asf->streams[stream_num].stream_language_index = stream_languageid_index;
 
     avio_rl64(pb); // avg frametime in 100ns units
-    stream_ct = avio_rl16(pb); //stream-name-count
-    payload_ext_ct = avio_rl16(pb); //payload-extension-system-count
+    stream_ct      = avio_rl16(pb); // stream-name-count
+    payload_ext_ct = avio_rl16(pb); // payload-extension-system-count
 
     if (stream_num < 128)
         asf->stream_bitrates[stream_num] = leak_rate;
 
-    for (i=0; i<stream_ct; i++){
+    for (i = 0; i < stream_ct; i++) {
         avio_rl16(pb);
         ext_len = avio_rl16(pb);
         avio_skip(pb, ext_len);
     }
 
-    for (i=0; i<payload_ext_ct; i++){
+    for (i = 0; i < payload_ext_ct; i++) {
         ff_get_guid(pb, &g);
         avio_skip(pb, 2);
-        ext_len=avio_rl32(pb);
+        ext_len = avio_rl32(pb);
         avio_skip(pb, ext_len);
     }
 
@@ -547,10 +567,10 @@ static int asf_read_content_desc(AVFormatContext *s, int64_t size)
     len3 = avio_rl16(pb);
     len4 = avio_rl16(pb);
     len5 = avio_rl16(pb);
-    get_tag(s, "title"    , 0, len1);
-    get_tag(s, "author"   , 0, len2);
-    get_tag(s, "copyright", 0, len3);
-    get_tag(s, "comment"  , 0, len4);
+    get_tag(s, "title", 0, len1, 32);
+    get_tag(s, "author", 0, len2, 32);
+    get_tag(s, "copyright", 0, len3, 32);
+    get_tag(s, "comment", 0, len4, 32);
     avio_skip(pb, len5);
 
     return 0;
@@ -563,29 +583,28 @@ static int asf_read_ext_content_desc(AVFormatContext *s, int64_t size)
     int desc_count, i, ret;
 
     desc_count = avio_rl16(pb);
-    for(i=0;i<desc_count;i++) {
-        int name_len,value_type,value_len;
+    for (i = 0; i < desc_count; i++) {
+        int name_len, value_type, value_len;
         char name[1024];
 
         name_len = avio_rl16(pb);
-        if (name_len%2)     // must be even, broken lavf versions wrote len-1
+        if (name_len % 2)   // must be even, broken lavf versions wrote len-1
             name_len += 1;
         if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len)
             avio_skip(pb, name_len - ret);
         value_type = avio_rl16(pb);
         value_len  = avio_rl16(pb);
-        if (!value_type && value_len%2)
+        if (!value_type && value_len % 2)
             value_len += 1;
-        /**
-         * My sample has that stream set to 0 maybe that mean the container.
-         * Asf stream count start at 1. I am using 0 to the container value since it's unused
-         */
-        if (!strcmp(name, "AspectRatioX")){
-            asf->dar[0].num= get_value(s->pb, value_type);
-        } else if(!strcmp(name, "AspectRatioY")){
-            asf->dar[0].den= get_value(s->pb, value_type);
-        } else
-            get_tag(s, name, value_type, value_len);
+        /* My sample has that stream set to 0 maybe that mean the container.
+         * ASF stream count starts at 1. I am using 0 to the container value
+         * since it's unused. */
+        if (!strcmp(name, "AspectRatioX"))
+            asf->dar[0].num = get_value(s->pb, value_type, 32);
+        else if (!strcmp(name, "AspectRatioY"))
+            asf->dar[0].den = get_value(s->pb, value_type, 32);
+        else
+            get_tag(s, name, value_type, value_len, 32);
     }
 
     return 0;
@@ -597,13 +616,15 @@ static int asf_read_language_list(AVFormatContext *s, int64_t size)
     ASFContext *asf = s->priv_data;
     int j, ret;
     int stream_count = avio_rl16(pb);
-    for(j = 0; j < stream_count; j++) {
+    for (j = 0; j < stream_count; j++) {
         char lang[6];
         unsigned int lang_len = avio_r8(pb);
-        if ((ret = avio_get_str16le(pb, lang_len, lang, sizeof(lang))) < lang_len)
+        if ((ret = avio_get_str16le(pb, lang_len, lang,
+                                    sizeof(lang))) < lang_len)
             avio_skip(pb, lang_len - ret);
         if (j < 128)
-            av_strlcpy(asf->stream_languages[j], lang, sizeof(*asf->stream_languages));
+            av_strlcpy(asf->stream_languages[j], lang,
+                       sizeof(*asf->stream_languages));
     }
 
     return 0;
@@ -613,30 +634,35 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size)
 {
     AVIOContext *pb = s->pb;
     ASFContext *asf = s->priv_data;
-    int n, stream_num, name_len, value_len, value_num;
+    int n, stream_num, name_len, value_len;
     int ret, i;
     n = avio_rl16(pb);
 
-    for(i=0;i<n;i++) {
+    for (i = 0; i < n; i++) {
         char name[1024];
-        int av_unused value_type;
+        int value_type;
 
-        avio_rl16(pb); //lang_list_index
-        stream_num= avio_rl16(pb);
-        name_len=   avio_rl16(pb);
+        avio_rl16(pb);  // lang_list_index
+        stream_num = avio_rl16(pb);
+        name_len   = avio_rl16(pb);
         value_type = avio_rl16(pb); /* value_type */
-        value_len=  avio_rl32(pb);
+        value_len  = avio_rl32(pb);
 
         if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len)
             avio_skip(pb, name_len - ret);
-        av_dlog(s, "%d %d %d %d %d <%s>\n",
+        av_dlog(s, "%d stream %d name_len %2d type %d len %4d <%s>\n",
                 i, stream_num, name_len, value_type, value_len, name);
-        value_num= avio_rl16(pb);//we should use get_value() here but it does not work 2 is le16 here but le32 elsewhere
-        avio_skip(pb, value_len - 2);
 
-        if(stream_num<128){
-            if     (!strcmp(name, "AspectRatioX")) asf->dar[stream_num].num= value_num;
-            else if(!strcmp(name, "AspectRatioY")) asf->dar[stream_num].den= value_num;
+        if (!strcmp(name, "AspectRatioX")){
+            int aspect_x = get_value(s->pb, value_type, 16);
+            if(stream_num < 128)
+                asf->dar[stream_num].num = aspect_x;
+        } else if(!strcmp(name, "AspectRatioY")){
+            int aspect_y = get_value(s->pb, value_type, 16);
+            if(stream_num < 128)
+                asf->dar[stream_num].den = aspect_y;
+        } else {
+            get_tag(s, name, value_type, value_len, 16);
         }
     }
 
@@ -646,6 +672,7 @@ static int asf_read_metadata(AVFormatContext *s, int64_t size)
 static int asf_read_marker(AVFormatContext *s, int64_t size)
 {
     AVIOContext *pb = s->pb;
+    ASFContext *asf = s->priv_data;
     int i, count, name_len, ret;
     char name[1024];
 
@@ -654,23 +681,25 @@ static int asf_read_marker(AVFormatContext *s, int64_t size)
     count = avio_rl32(pb);    // markers count
     avio_rl16(pb);            // reserved 2 bytes
     name_len = avio_rl16(pb); // name length
-    for(i=0;i<name_len;i++){
+    for (i = 0; i < name_len; i++)
         avio_r8(pb); // skip the name
-    }
 
-    for(i=0;i<count;i++){
+    for (i = 0; i < count; i++) {
         int64_t pres_time;
         int name_len;
 
         avio_rl64(pb);             // offset, 8 bytes
         pres_time = avio_rl64(pb); // presentation time
+        pres_time -= asf->hdr.preroll * 10000;
         avio_rl16(pb);             // entry length
         avio_rl32(pb);             // send time
         avio_rl32(pb);             // flags
         name_len = avio_rl32(pb);  // name length
-        if ((ret = avio_get_str16le(pb, name_len * 2, name, sizeof(name))) < name_len)
+        if ((ret = avio_get_str16le(pb, name_len * 2, name,
+                                    sizeof(name))) < name_len)
             avio_skip(pb, name_len - ret);
-        avpriv_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );
+        avpriv_new_chapter(s, i, (AVRational) { 1, 10000000 }, pres_time,
+                           AV_NOPTS_VALUE, name);
     }
 
     return 0;
@@ -692,19 +721,19 @@ static int asf_read_header(AVFormatContext *s)
     avio_r8(pb);
     avio_r8(pb);
     memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
-    for(;;) {
-        uint64_t gpos= avio_tell(pb);
+    for (;;) {
+        uint64_t gpos = avio_tell(pb);
         ff_get_guid(pb, &g);
         gsize = avio_rl64(pb);
         print_guid(&g);
         if (!ff_guidcmp(&g, &ff_asf_data_header)) {
             asf->data_object_offset = avio_tell(pb);
-            // if not streaming, gsize is not unlimited (how?), and there is enough space in the file..
-            if (!(asf->hdr.flags & 0x01) && gsize >= 100) {
+            /* If not streaming, gsize is not unlimited (how?),
+             * and there is enough space in the file.. */
+            if (!(asf->hdr.flags & 0x01) && gsize >= 100)
                 asf->data_object_size = gsize - 24;
-            } else {
+            else
                 asf->data_object_size = (uint64_t)-1;
-            }
             break;
         }
         if (gsize < 24)
@@ -725,6 +754,8 @@ static int asf_read_header(AVFormatContext *s)
             asf_read_ext_content_desc(s, gsize);
         } else if (!ff_guidcmp(&g, &ff_asf_metadata_header)) {
             asf_read_metadata(s, gsize);
+        } else if (!ff_guidcmp(&g, &ff_asf_metadata_library_header)) {
+            asf_read_metadata(s, gsize);
         } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_header)) {
             asf_read_ext_stream_properties(s, gsize);
 
@@ -742,16 +773,21 @@ static int asf_read_header(AVFormatContext *s)
         } else {
             if (!s->keylen) {
                 if (!ff_guidcmp(&g, &ff_asf_content_encryption)) {
-                    av_log(s, AV_LOG_WARNING, "DRM protected stream detected, decoding will likely fail!\n");
+                    av_log(s, AV_LOG_WARNING,
+                           "DRM protected stream detected, decoding will likely fail!\n");
                 } else if (!ff_guidcmp(&g, &ff_asf_ext_content_encryption)) {
-                    av_log(s, AV_LOG_WARNING, "Ext DRM protected stream detected, decoding will likely fail!\n");
+                    av_log(s, AV_LOG_WARNING,
+                           "Ext DRM protected stream detected, decoding will likely fail!\n");
                 } 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_WARNING,
+                           "Digital signature detected, decoding will likely fail!\n");
                 }
             }
         }
-        if(avio_tell(pb) != gpos + gsize)
-            av_log(s, AV_LOG_DEBUG, "gpos mismatch our pos=%"PRIu64", end=%"PRIu64"\n", avio_tell(pb)-gpos, gsize);
+        if (avio_tell(pb) != gpos + gsize)
+            av_log(s, AV_LOG_DEBUG,
+                   "gpos mismatch our pos=%"PRIu64", end=%"PRId64"\n",
+                   avio_tell(pb) - gpos, gsize);
         avio_seek(pb, gpos + gsize, SEEK_SET);
     }
     ff_get_guid(pb, &g);
@@ -760,21 +796,22 @@ static int asf_read_header(AVFormatContext *s)
     avio_r8(pb);
     if (pb->eof_reached)
         return -1;
-    asf->data_offset = avio_tell(pb);
+    asf->data_offset      = avio_tell(pb);
     asf->packet_size_left = 0;
 
-
-    for(i=0; i<128; i++){
-        int stream_num= asf->asfid2avid[i];
-        if(stream_num>=0){
+    for (i = 0; i < 128; i++) {
+        int stream_num = asf->asfid2avid[i];
+        if (stream_num >= 0) {
             AVStream *st = s->streams[stream_num];
             if (!st->codec->bit_rate)
                 st->codec->bit_rate = asf->stream_bitrates[i];
-            if (asf->dar[i].num > 0 && asf->dar[i].den > 0){
+            if (asf->dar[i].num > 0 && asf->dar[i].den > 0) {
                 av_reduce(&st->sample_aspect_ratio.num,
                           &st->sample_aspect_ratio.den,
                           asf->dar[i].num, asf->dar[i].den, INT_MAX);
-            } else if ((asf->dar[0].num > 0) && (asf->dar[0].den > 0) && (st->codec->codec_type==AVMEDIA_TYPE_VIDEO)) // Use ASF container value if the stream doesn't AR set.
+            } else if ((asf->dar[0].num > 0) && (asf->dar[0].den > 0) &&
+                       // Use ASF container value if the stream doesn't set AR.
+                       (st->codec->codec_type == AVMEDIA_TYPE_VIDEO))
                 av_reduce(&st->sample_aspect_ratio.num,
                           &st->sample_aspect_ratio.den,
                           asf->dar[0].num, asf->dar[0].den, INT_MAX);
@@ -788,7 +825,8 @@ static int asf_read_header(AVFormatContext *s)
                 const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index];
                 if (rfc1766 && strlen(rfc1766) > 1) {
                     const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any
-                    const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL);
+                    const char *iso6392       = av_convert_lang_to(primary_tag,
+                                                                   AV_LANG_ISO639_2_BIBL);
                     if (iso6392)
                         av_dict_set(&st->metadata, "language", iso6392, 0);
                 }
@@ -801,13 +839,23 @@ static int asf_read_header(AVFormatContext *s)
     return 0;
 }
 
-#define DO_2BITS(bits, var, defval) \
-    switch (bits & 3) \
-    { \
-    case 3: var = avio_rl32(pb); rsize += 4; break; \
-    case 2: var = avio_rl16(pb); rsize += 2; break; \
-    case 1: var = avio_r8(pb);   rsize++; break; \
-    default: var = defval; break; \
+#define DO_2BITS(bits, var, defval)             \
+    switch (bits & 3) {                         \
+    case 3:                                     \
+        var = avio_rl32(pb);                    \
+        rsize += 4;                             \
+        break;                                  \
+    case 2:                                     \
+        var = avio_rl16(pb);                    \
+        rsize += 2;                             \
+        break;                                  \
+    case 1:                                     \
+        var = avio_r8(pb);                      \
+        rsize++;                                \
+        break;                                  \
+    default:                                    \
+        var = defval;                           \
+        break;                                  \
     }
 
 /**
@@ -816,7 +864,7 @@ static int asf_read_header(AVFormatContext *s)
  * @param pb context to read data from
  * @return 0 on success, <0 on error
  */
-static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
+static int asf_get_packet(AVFormatContext *s, AVIOContext *pb)
 {
     ASFContext *asf = s->priv_data;
     uint32_t packet_length, padsize;
@@ -824,31 +872,31 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
     int c, d, e, off;
 
     // if we do not know packet size, allow skipping up to 32 kB
-    off= 32768;
+    off = 32768;
     if (asf->no_resync_search)
         off = 3;
     else if (s->packet_size > 0)
-        off= (avio_tell(pb) - s->data_offset) % s->packet_size + 3;
-
-    c=d=e=-1;
-    while(off-- > 0){
-        c=d; d=e;
-        e= avio_r8(pb);
-        if(c == 0x82 && !d && !e)
+        off = (avio_tell(pb) - s->data_offset) % s->packet_size + 3;
+
+    c = d = e = -1;
+    while (off-- > 0) {
+        c = d;
+        d = e;
+        e = avio_r8(pb);
+        if (c == 0x82 && !d && !e)
             break;
     }
 
     if (c != 0x82) {
-        /**
-         * This code allows handling of -EAGAIN at packet boundaries (i.e.
+        /* This code allows handling of -EAGAIN at packet boundaries (i.e.
          * if the packet sync code above triggers -EAGAIN). This does not
          * imply complete -EAGAIN handling support at random positions in
-         * the stream.
-         */
+         * the stream. */
         if (pb->error == AVERROR(EAGAIN))
             return AVERROR(EAGAIN);
         if (!pb->eof_reached)
-            av_log(s, AV_LOG_ERROR, "ff asf bad header %x  at:%"PRId64"\n", c, avio_tell(pb));
+            av_log(s, AV_LOG_ERROR,
+                   "ff asf bad header %x  at:%"PRId64"\n", c, avio_tell(pb));
     }
     if ((c & 0x8f) == 0x82) {
         if (d || e) {
@@ -856,11 +904,11 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
                 av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
             return -1;
         }
-        c= avio_r8(pb);
-        d= avio_r8(pb);
-        rsize+=3;
+        c      = avio_r8(pb);
+        d      = avio_r8(pb);
+        rsize += 3;
     } else if (!pb->eof_reached) {
-        avio_seek(pb, -1, SEEK_CUR); //FIXME
+        avio_seek(pb, -1, SEEK_CUR); // FIXME
     }
 
     asf->packet_flags    = c;
@@ -870,13 +918,16 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
     DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored
     DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length
 
-    //the following checks prevent overflows and infinite loops
-    if(!packet_length || packet_length >= (1U<<29)){
-        av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, avio_tell(pb));
+    // the following checks prevent overflows and infinite loops
+    if (!packet_length || packet_length >= (1U << 29)) {
+        av_log(s, AV_LOG_ERROR,
+               "invalid packet_length %d at:%"PRId64"\n",
+               packet_length, avio_tell(pb));
         return -1;
     }
-    if(padsize >= packet_length){
-        av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, avio_tell(pb));
+    if (padsize >= packet_length) {
+        av_log(s, AV_LOG_ERROR,
+               "invalid padsize %d at:%"PRId64"\n", padsize, avio_tell(pb));
         return -1;
     }
 
@@ -885,10 +936,11 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
     // rsize has at least 11 bytes which have to be present
 
     if (asf->packet_flags & 0x01) {
-        asf->packet_segsizetype = avio_r8(pb); rsize++;
+        asf->packet_segsizetype = avio_r8(pb);
+        rsize++;
         asf->packet_segments = asf->packet_segsizetype & 0x3f;
     } else {
-        asf->packet_segments = 1;
+        asf->packet_segments    = 1;
         asf->packet_segsizetype = 0x80;
     }
     if (rsize > packet_length - padsize) {
@@ -902,7 +954,8 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
     if (packet_length < asf->hdr.min_pktsize)
         padsize += asf->hdr.min_pktsize - packet_length;
     asf->packet_padsize = padsize;
-    av_dlog(s, "packet: size=%d padsize=%d  left=%d\n", s->packet_size, asf->packet_padsize, asf->packet_size_left);
+    av_dlog(s, "packet: size=%d padsize=%d  left=%d\n",
+            s->packet_size, asf->packet_padsize, asf->packet_size_left);
     return 0;
 }
 
@@ -910,15 +963,16 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
  *
  * @return <0 if error
  */
-static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
+static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb)
+{
     ASFContext *asf = s->priv_data;
-    int rsize = 1;
-    int num = avio_r8(pb);
+    int rsize       = 1;
+    int num         = avio_r8(pb);
     int64_t ts0;
 
     asf->packet_segments--;
     asf->packet_key_frame = num >> 7;
-    asf->stream_index = asf->asfid2avid[num & 0x7f];
+    asf->stream_index     = asf->asfid2avid[num & 0x7f];
     // sequence should be ignored!
     DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);
     DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);
@@ -928,33 +982,36 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
             asf->packet_frag_offset, asf->packet_replic_size);
     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){
+        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;
         }
         asf->packet_frag_timestamp = avio_rl32(pb); // timestamp
-        if(asf->packet_replic_size >= 8+38+4){
+        if (asf->packet_replic_size >= 8 + 38 + 4) {
             avio_skip(pb, 10);
-            ts0= avio_rl64(pb);
-            avio_skip(pb, 8);;
+            ts0 = avio_rl64(pb);
+            avio_skip(pb, 8);
             avio_skip(pb, 12);
             avio_rl32(pb);
             avio_skip(pb, asf->packet_replic_size - 8 - 38 - 4);
-            if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;
-            else         asf->packet_frag_timestamp= AV_NOPTS_VALUE;
-        }else
+            if (ts0 != -1)
+                asf->packet_frag_timestamp = ts0 / 10000;
+            else
+                asf->packet_frag_timestamp = AV_NOPTS_VALUE;
+        } else
             avio_skip(pb, asf->packet_replic_size - 8);
         rsize += asf->packet_replic_size; // FIXME - check validity
-    } else if (asf->packet_replic_size==1){
+    } else if (asf->packet_replic_size == 1) {
         // multipacket - frag_offset is beginning timestamp
-        asf->packet_time_start = asf->packet_frag_offset;
-        asf->packet_frag_offset = 0;
+        asf->packet_time_start     = asf->packet_frag_offset;
+        asf->packet_frag_offset    = 0;
         asf->packet_frag_timestamp = asf->packet_timestamp;
 
         asf->packet_time_delta = avio_r8(pb);
         rsize++;
-    }else if(asf->packet_replic_size!=0){
-        av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);
+    } else if (asf->packet_replic_size != 0) {
+        av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n",
+               asf->packet_replic_size);
         return -1;
     }
     if (asf->packet_flags & 0x01) {
@@ -962,9 +1019,10 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
         if (rsize > asf->packet_size_left) {
             av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n");
             return -1;
-        } else if(asf->packet_frag_size > asf->packet_size_left - rsize){
+        } else if (asf->packet_frag_size > asf->packet_size_left - rsize) {
             if (asf->packet_frag_size > asf->packet_size_left - rsize + asf->packet_padsize) {
-                av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n", asf->packet_size_left, rsize);
+                av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n",
+                       asf->packet_size_left, rsize);
                 return -1;
             } else {
                 int diff = asf->packet_frag_size - (asf->packet_size_left - rsize);
@@ -998,9 +1056,9 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){
  * @return 0 if data was stored in pkt, <0 on error or 1 if more ASF
  *          packets need to be loaded (through asf_get_packet())
  */
-static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
+static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
 {
-    ASFContext *asf = s->priv_data;
+    ASFContext *asf   = s->priv_data;
     ASFStream *asf_st = 0;
     for (;;) {
         int ret;
@@ -1016,10 +1074,10 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
             /* fail safe */
             avio_skip(pb, ret);
 
-            asf->packet_pos= avio_tell(pb);
+            asf->packet_pos = avio_tell(pb);
             if (asf->data_object_size != (uint64_t)-1 &&
                 (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))
-                return AVERROR_EOF; /* Do not exceed the size of the data object */
+                return AVERROR_EOF;  /* Do not exceed the size of the data object */
             return 1;
         }
         if (asf->packet_time_start == 0) {
@@ -1036,12 +1094,14 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
                 avio_skip(pb, asf->packet_frag_size);
                 asf->packet_size_left -= asf->packet_frag_size;
                 if (asf->stream_index < 0)
-                    av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", asf->packet_frag_size);
+                    av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n",
+                           asf->packet_frag_size);
                 continue;
             }
             asf->asf_st = s->streams[asf->stream_index]->priv_data;
         }
         asf_st = asf->asf_st;
+        av_assert0(asf_st);
 
         if (asf->packet_replic_size == 1) {
             // frag_offset is here used as the beginning timestamp
@@ -1067,11 +1127,12 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
         }
 
         if (asf_st->pkt.size != asf->packet_obj_size ||
-            //FIXME is this condition sufficient?
+            // FIXME is this condition sufficient?
             asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) {
             if (asf_st->pkt.data) {
-                av_log(s, AV_LOG_INFO, "freeing incomplete packet size %d, "
-                       "new %d\n", asf_st->pkt.size, asf->packet_obj_size);
+                av_log(s, AV_LOG_INFO,
+                       "freeing incomplete packet size %d, new %d\n",
+                       asf_st->pkt.size, asf->packet_obj_size);
                 asf_st->frag_offset = 0;
                 av_free_packet(&asf_st->pkt);
             }
@@ -1114,8 +1175,10 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
 
         if (asf->packet_frag_offset >= asf_st->pkt.size ||
             asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset) {
-            av_log(s, AV_LOG_ERROR, "packet fragment position invalid %u,%u not in %u\n",
-                   asf->packet_frag_offset, asf->packet_frag_size, asf_st->pkt.size);
+            av_log(s, AV_LOG_ERROR,
+                   "packet fragment position invalid %u,%u not in %u\n",
+                   asf->packet_frag_offset, asf->packet_frag_size,
+                   asf_st->pkt.size);
             continue;
         }
 
@@ -1143,11 +1206,12 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
         asf_st->frag_offset += ret;
         /* test if whole packet is read */
         if (asf_st->frag_offset == asf_st->pkt.size) {
-            //workaround for macroshit radio DVR-MS files
+            // workaround for macroshit radio DVR-MS files
             if (s->streams[asf->stream_index]->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
                 asf_st->pkt.size > 100) {
                 int i;
-                for (i = 0; i < asf_st->pkt.size && !asf_st->pkt.data[i]; i++);
+                for (i = 0; i < asf_st->pkt.size && !asf_st->pkt.data[i]; i++)
+                    ;
                 if (i == asf_st->pkt.size) {
                     av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");
                     asf_st->frag_offset = 0;
@@ -1158,35 +1222,46 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
 
             /* return packet */
             if (asf_st->ds_span > 1) {
-                if(asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span) {
-                    av_log(s, AV_LOG_ERROR, "pkt.size != ds_packet_size * "
-                           "ds_span (%d %d %d)\n", asf_st->pkt.size,
-                           asf_st->ds_packet_size, asf_st->ds_span);
+                if (asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span) {
+                    av_log(s, AV_LOG_ERROR,
+                           "pkt.size != ds_packet_size * ds_span (%d %d %d)\n",
+                           asf_st->pkt.size, asf_st->ds_packet_size,
+                           asf_st->ds_span);
                 } else {
                     /* packet descrambling */
-                    uint8_t *newdata = av_malloc(asf_st->pkt.size + FF_INPUT_BUFFER_PADDING_SIZE);
-                    if (newdata) {
+                    AVBufferRef *buf = av_buffer_alloc(asf_st->pkt.size +
+                                                       FF_INPUT_BUFFER_PADDING_SIZE);
+                    if (buf) {
+                        uint8_t *newdata = buf->data;
                         int offset = 0;
-                        memset(newdata + asf_st->pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+                        memset(newdata + asf_st->pkt.size, 0,
+                               FF_INPUT_BUFFER_PADDING_SIZE);
                         while (offset < asf_st->pkt.size) {
                             int off = offset / asf_st->ds_chunk_size;
                             int row = off / asf_st->ds_span;
                             int col = off % asf_st->ds_span;
                             int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;
                             assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size);
-                            assert(idx+1 <= asf_st->pkt.size / asf_st->ds_chunk_size);
+                            assert(idx + 1 <= asf_st->pkt.size / asf_st->ds_chunk_size);
                             memcpy(newdata + offset,
                                    asf_st->pkt.data + idx * asf_st->ds_chunk_size,
                                    asf_st->ds_chunk_size);
                             offset += asf_st->ds_chunk_size;
                         }
-                        av_free(asf_st->pkt.data);
-                        asf_st->pkt.data = newdata;
+                        av_buffer_unref(&asf_st->pkt.buf);
+                        asf_st->pkt.buf  = buf;
+                        asf_st->pkt.data = buf->data;
                     }
                 }
             }
             asf_st->frag_offset         = 0;
             *pkt                        = asf_st->pkt;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+            asf_st->pkt.destruct        = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+            asf_st->pkt.buf             = 0;
             asf_st->pkt.size            = 0;
             asf_st->pkt.data            = 0;
             asf_st->pkt.side_data_elems = 0;
@@ -1205,10 +1280,11 @@ static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
         int ret;
 
         /* parse cached packets, if any */
-        if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0)
+        if ((ret = asf_parse_packet(s, s->pb, pkt)) <= 0)
             return ret;
-        if ((ret = ff_asf_get_packet(s, s->pb)) < 0)
-            assert(asf->packet_size_left < FRAME_HEADER_SIZE || asf->packet_segments < 1);
+        if ((ret = asf_get_packet(s, s->pb)) < 0)
+            assert(asf->packet_size_left < FRAME_HEADER_SIZE ||
+                   asf->packet_segments < 1);
         asf->packet_time_start = 0;
     }
 }
@@ -1222,32 +1298,34 @@ static void asf_reset_header(AVFormatContext *s)
     ASFStream *asf_st;
     int i;
 
-    asf->packet_size_left = 0;
-    asf->packet_segments = 0;
-    asf->packet_flags = 0;
-    asf->packet_property = 0;
-    asf->packet_timestamp = 0;
-    asf->packet_segsizetype = 0;
-    asf->packet_segments = 0;
-    asf->packet_seq = 0;
-    asf->packet_replic_size = 0;
-    asf->packet_key_frame = 0;
-    asf->packet_padsize = 0;
-    asf->packet_frag_offset = 0;
-    asf->packet_frag_size = 0;
+    asf->packet_size_left      = 0;
+    asf->packet_segments       = 0;
+    asf->packet_flags          = 0;
+    asf->packet_property       = 0;
+    asf->packet_timestamp      = 0;
+    asf->packet_segsizetype    = 0;
+    asf->packet_segments       = 0;
+    asf->packet_seq            = 0;
+    asf->packet_replic_size    = 0;
+    asf->packet_key_frame      = 0;
+    asf->packet_padsize        = 0;
+    asf->packet_frag_offset    = 0;
+    asf->packet_frag_size      = 0;
     asf->packet_frag_timestamp = 0;
-    asf->packet_multi_size = 0;
-    asf->packet_obj_size = 0;
-    asf->packet_time_delta = 0;
-    asf->packet_time_start = 0;
-
-    for(i=0; i<s->nb_streams; i++){
-        asf_st= s->streams[i]->priv_data;
+    asf->packet_multi_size     = 0;
+    asf->packet_obj_size       = 0;
+    asf->packet_time_delta     = 0;
+    asf->packet_time_start     = 0;
+
+    for (i = 0; i < s->nb_streams; i++) {
+        asf_st = s->streams[i]->priv_data;
+        if (!asf_st)
+            continue;
         av_free_packet(&asf_st->pkt);
-        asf_st->frag_offset=0;
-        asf_st->seq=0;
+        asf_st->frag_offset = 0;
+        asf_st->seq         = 0;
     }
-    asf->asf_st= NULL;
+    asf->asf_st = NULL;
 }
 
 static int asf_read_close(AVFormatContext *s)
@@ -1257,27 +1335,29 @@ static int asf_read_close(AVFormatContext *s)
     return 0;
 }
 
-static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
+static int64_t asf_read_pts(AVFormatContext *s, int stream_index,
+                            int64_t *ppos, int64_t pos_limit)
 {
     AVPacket pkt1, *pkt = &pkt1;
     ASFStream *asf_st;
     int64_t pts;
-    int64_t pos= *ppos;
+    int64_t pos = *ppos;
     int i;
     int64_t start_pos[ASF_MAX_STREAMS];
 
-    for(i=0; i<s->nb_streams; i++){
-        start_pos[i]= pos;
-    }
+    for (i = 0; i < s->nb_streams; i++)
+        start_pos[i] = pos;
 
     if (s->packet_size > 0)
-        pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset;
-    *ppos= pos;
+        pos = (pos + s->packet_size - 1 - s->data_offset) /
+              s->packet_size * s->packet_size +
+              s->data_offset;
+    *ppos = pos;
     avio_seek(s->pb, pos, SEEK_SET);
 
     asf_reset_header(s);
-    for(;;){
-        if (asf_read_packet(s, pkt) < 0){
+    for (;;) {
+        if (asf_read_packet(s, pkt) < 0) {
             av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");
             return AV_NOPTS_VALUE;
         }
@@ -1285,79 +1365,85 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos,
         pts = pkt->dts;
 
         av_free_packet(pkt);
-        if(pkt->flags&AV_PKT_FLAG_KEY){
-            i= pkt->stream_index;
+        if (pkt->flags & AV_PKT_FLAG_KEY) {
+            i = pkt->stream_index;
 
-            asf_st= s->streams[i]->priv_data;
+            asf_st = s->streams[i]->priv_data;
+            av_assert0(asf_st);
 
 //            assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0);
-            pos= asf_st->packet_pos;
+            pos = asf_st->packet_pos;
 
-            av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
-            start_pos[i]= asf_st->packet_pos + 1;
+            av_add_index_entry(s->streams[i], pos, pts, pkt->size,
+                               pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
+            start_pos[i] = asf_st->packet_pos + 1;
 
-            if(pkt->stream_index == stream_index)
-               break;
+            if (pkt->stream_index == stream_index)
+                break;
         }
     }
 
-    *ppos= pos;
+    *ppos = pos;
     return pts;
 }
 
 static void asf_build_simple_index(AVFormatContext *s, int stream_index)
 {
     ff_asf_guid g;
-    ASFContext *asf = s->priv_data;
-    int64_t current_pos= avio_tell(s->pb);
+    ASFContext *asf     = s->priv_data;
+    int64_t current_pos = avio_tell(s->pb);
     int i;
 
     avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
     ff_get_guid(s->pb, &g);
 
     /* the data object can be followed by other top-level objects,
-       skip them until the simple index object is reached */
+     * skip them until the simple index object is reached */
     while (ff_guidcmp(&g, &index_guid)) {
-        int64_t gsize= avio_rl64(s->pb);
+        int64_t gsize = avio_rl64(s->pb);
         if (gsize < 24 || s->pb->eof_reached) {
             avio_seek(s->pb, current_pos, SEEK_SET);
             return;
         }
-        avio_skip(s->pb, gsize-24);
+        avio_skip(s->pb, gsize - 24);
         ff_get_guid(s->pb, &g);
     }
 
     {
-        int64_t itime, last_pos=-1;
+        int64_t itime, last_pos = -1;
         int pct, ict;
-        int64_t av_unused gsize= avio_rl64(s->pb);
+        int64_t av_unused gsize = avio_rl64(s->pb);
         ff_get_guid(s->pb, &g);
-        itime=avio_rl64(s->pb);
-        pct=avio_rl32(s->pb);
-        ict=avio_rl32(s->pb);
-        av_log(s, AV_LOG_DEBUG, "itime:0x%"PRIx64", pct:%d, ict:%d\n",itime,pct,ict);
-
-        for (i=0;i<ict;i++){
-            int pktnum=avio_rl32(s->pb);
-            int pktct =avio_rl16(s->pb);
-            int64_t pos      = s->data_offset + s->packet_size*(int64_t)pktnum;
-            int64_t index_pts= FFMAX(av_rescale(itime, i, 10000) - asf->hdr.preroll, 0);
-
-            if(pos != last_pos){
-            av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d  pts: %"PRId64"\n", pktnum, pktct, index_pts);
-            av_add_index_entry(s->streams[stream_index], pos, index_pts, s->packet_size, 0, AVINDEX_KEYFRAME);
-            last_pos=pos;
+        itime = avio_rl64(s->pb);
+        pct   = avio_rl32(s->pb);
+        ict   = avio_rl32(s->pb);
+        av_log(s, AV_LOG_DEBUG,
+               "itime:0x%"PRIx64", pct:%d, ict:%d\n", itime, pct, ict);
+
+        for (i = 0; i < ict; i++) {
+            int pktnum        = avio_rl32(s->pb);
+            int pktct         = avio_rl16(s->pb);
+            int64_t pos       = s->data_offset + s->packet_size * (int64_t)pktnum;
+            int64_t index_pts = FFMAX(av_rescale(itime, i, 10000) - asf->hdr.preroll, 0);
+
+            if (pos != last_pos) {
+                av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d  pts: %"PRId64"\n",
+                       pktnum, pktct, index_pts);
+                av_add_index_entry(s->streams[stream_index], pos, index_pts,
+                                   s->packet_size, 0, AVINDEX_KEYFRAME);
+                last_pos = pos;
             }
         }
-        asf->index_read= ict > 0;
+        asf->index_read = ict > 0;
     }
     avio_seek(s->pb, current_pos, SEEK_SET);
 }
 
-static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
+static int asf_read_seek(AVFormatContext *s, int stream_index,
+                         int64_t pts, int flags)
 {
     ASFContext *asf = s->priv_data;
-    AVStream *st = s->streams[stream_index];
+    AVStream *st    = s->streams[stream_index];
     int64_t pos;
     int index;
 
@@ -1365,9 +1451,9 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int
         return -1;
 
     /* Try using the protocol's read_seek if available */
-    if(s->pb) {
+    if (s->pb) {
         int ret = avio_seek_time(s->pb, stream_index, pts, flags);
-        if(ret >= 0)
+        if (ret >= 0)
             asf_reset_header(s);
         if (ret != AVERROR(ENOSYS))
             return ret;
@@ -1376,9 +1462,9 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int
     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(index >= 0) {
+    if ((asf->index_read && st->index_entries)) {
+        index = av_index_search_timestamp(st, pts, flags);
+        if (index >= 0) {
             /* find the position */
             pos = st->index_entries[index].pos;
 
diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
index 5c820be..e1a7189 100644
--- a/libavformat/asfenc.c
+++ b/libavformat/asfenc.c
@@ -18,12 +18,14 @@
  * 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/dict.h"
+#include "libavutil/mathematics.h"
 #include "avformat.h"
+#include "avio_internal.h"
 #include "internal.h"
 #include "riff.h"
 #include "asf.h"
-#include "avio_internal.h"
-#include "libavutil/dict.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -33,10 +35,9 @@
 #define ASF_INDEX_BLOCK         600
 
 #define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2
-#define ASF_PACKET_ERROR_CORRECTION_FLAGS (\
-                ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT | \
-                ASF_PACKET_ERROR_CORRECTION_DATA_SIZE\
-                )
+#define ASF_PACKET_ERROR_CORRECTION_FLAGS          \
+    (ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT |    \
+     ASF_PACKET_ERROR_CORRECTION_DATA_SIZE)
 
 #if (ASF_PACKET_ERROR_CORRECTION_FLAGS != 0)
 #   define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 1
@@ -44,12 +45,11 @@
 #   define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 0
 #endif
 
-#define ASF_PPI_PROPERTY_FLAGS (\
-                ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE | \
-                ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD | \
-                ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE | \
-                ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE \
-                )
+#define ASF_PPI_PROPERTY_FLAGS                                       \
+    (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE           |    \
+     ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD |    \
+     ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE       |    \
+     ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE)
 
 #define ASF_PPI_LENGTH_TYPE_FLAGS 0
 
@@ -68,7 +68,6 @@
 #   define ASF_PPI_SEQUENCE_FIELD_SIZE 0
 #endif
 
-
 #if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE))
 #   define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 1
 #endif
@@ -144,51 +143,47 @@
 #   define ASF_PAYLOAD_LENGTH_FIELD_SIZE 0
 #endif
 
-#define PACKET_HEADER_MIN_SIZE (\
-                ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE + \
-                ASF_PACKET_ERROR_CORRECTION_DATA_SIZE + \
-                1 + /*Length Type Flags*/ \
-                1 + /*Property Flags*/ \
-                ASF_PPI_PACKET_LENGTH_FIELD_SIZE + \
-                ASF_PPI_SEQUENCE_FIELD_SIZE + \
-                ASF_PPI_PADDING_LENGTH_FIELD_SIZE + \
-                4 + /*Send Time Field*/ \
-                2   /*Duration Field*/ \
-                )
-
+#define PACKET_HEADER_MIN_SIZE \
+    (ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE +       \
+     ASF_PACKET_ERROR_CORRECTION_DATA_SIZE +              \
+     1 +        /* Length Type Flags */                   \
+     1 +        /* Property Flags */                      \
+     ASF_PPI_PACKET_LENGTH_FIELD_SIZE +                   \
+     ASF_PPI_SEQUENCE_FIELD_SIZE +                        \
+     ASF_PPI_PADDING_LENGTH_FIELD_SIZE +                  \
+     4 +        /* Send Time Field */                     \
+     2)         /* Duration Field */
 
 // Replicated Data shall be at least 8 bytes long.
 #define ASF_PAYLOAD_REPLICATED_DATA_LENGTH 0x08
 
-#define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD (\
-                1 + /*Stream Number*/ \
-                ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \
-                ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \
-                ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \
-                ASF_PAYLOAD_REPLICATED_DATA_LENGTH \
-                )
-
-#define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS (\
-                1 + /*Stream Number*/ \
-                ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \
-                ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \
-                ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \
-                ASF_PAYLOAD_REPLICATED_DATA_LENGTH + \
-                ASF_PAYLOAD_LENGTH_FIELD_SIZE \
-                )
-
-#define SINGLE_PAYLOAD_DATA_LENGTH (\
-                PACKET_SIZE - \
-                PACKET_HEADER_MIN_SIZE - \
-                PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD \
-                )
-
-#define MULTI_PAYLOAD_CONSTANT (\
-                PACKET_SIZE - \
-                PACKET_HEADER_MIN_SIZE - \
-                1 - /*Payload Flags*/ \
-                2*PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS \
-                )
+#define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD                \
+    (1 +     /* Stream Number */                          \
+     ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE +         \
+     ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE +    \
+     ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE +      \
+     ASF_PAYLOAD_REPLICATED_DATA_LENGTH)
+
+#define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS             \
+    (1 +        /* Stream Number */                       \
+     ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE +         \
+     ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE +    \
+     ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE +      \
+     ASF_PAYLOAD_REPLICATED_DATA_LENGTH +                 \
+     ASF_PAYLOAD_LENGTH_FIELD_SIZE)
+
+#define SINGLE_PAYLOAD_DATA_LENGTH                        \
+    (PACKET_SIZE -                                        \
+     PACKET_HEADER_MIN_SIZE -                             \
+     PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD)
+
+#define MULTI_PAYLOAD_CONSTANT                            \
+    (PACKET_SIZE -                                        \
+     PACKET_HEADER_MIN_SIZE -                             \
+     1 -         /* Payload Flags */                      \
+     2 * PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS)
+
+#define DATA_HEADER_SIZE 50
 
 typedef struct {
     uint32_t seqno;
@@ -209,17 +204,17 @@ typedef struct {
     uint64_t data_offset;                ///< beginning of the first data packet
 
     int64_t last_indexed_pts;
-    ASFIndex* index_ptr;
+    ASFIndex *index_ptr;
     uint32_t nb_index_count;
     uint32_t nb_index_memory_alloc;
     uint16_t maximum_packet;
 } 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_MPEG4,     MKTAG('M', '4', 'S', '2') },
     { AV_CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') },
-    { AV_CODEC_ID_NONE, 0 },
+    { AV_CODEC_ID_NONE,      0 },
 };
 
 #define PREROLL_TIME 3100
@@ -267,7 +262,8 @@ static void end_header(AVIOContext *pb, int64_t pos)
 }
 
 /* write an asf chunk (only used in streaming case) */
-static void put_chunk(AVFormatContext *s, int type, int payload_length, int flags)
+static void put_chunk(AVFormatContext *s, int type,
+                      int payload_length, int flags)
 {
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = s->pb;
@@ -275,10 +271,10 @@ static void put_chunk(AVFormatContext *s, int type, int payload_length, int flag
 
     length = payload_length + 8;
     avio_wl16(pb, type);
-    avio_wl16(pb, length);    //size
-    avio_wl32(pb, asf->seqno);//sequence number
-    avio_wl16(pb, flags); /* unknown bytes */
-    avio_wl16(pb, length);    //size_confirm
+    avio_wl16(pb, length);      // size
+    avio_wl32(pb, asf->seqno);  // sequence number
+    avio_wl16(pb, flags);       // unknown bytes
+    avio_wl16(pb, length);      // size_confirm
     asf->seqno++;
 }
 
@@ -287,13 +283,72 @@ static int64_t unix_to_file_time(int ti)
 {
     int64_t t;
 
-    t = ti * INT64_C(10000000);
+    t  = ti * INT64_C(10000000);
     t += INT64_C(116444736000000000);
     return t;
 }
 
+static int32_t get_send_time(ASFContext *asf, int64_t pres_time, uint64_t *offset)
+{
+    int i;
+    int32_t send_time = 0;
+    *offset = asf->data_offset + DATA_HEADER_SIZE;
+    for (i = 0; i < asf->nb_index_count; i++) {
+        if (pres_time <= asf->index_ptr[i].send_time)
+            break;
+        send_time = asf->index_ptr[i].send_time;
+        *offset   = asf->index_ptr[i].offset;
+    }
+
+    return send_time / 10000;
+}
+
+static int asf_write_markers(AVFormatContext *s)
+{
+    ASFContext *asf = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int i;
+    AVRational scale = {1, 10000000};
+    int64_t hpos = put_header(pb, &ff_asf_marker_header);
+
+    put_guid(pb, &ff_asf_reserved_4);  // ASF spec mandates this reserved value
+    avio_wl32(pb, s->nb_chapters);     // markers count
+    avio_wl16(pb, 0);                  // ASF spec mandates 0 for this
+    avio_wl16(pb, 0);                  // name length 0, no name given
+
+    for (i = 0; i < s->nb_chapters; i++) {
+        AVChapter *c = s->chapters[i];
+        AVDictionaryEntry *t = av_dict_get(c->metadata, "title", NULL, 0);
+        int64_t pres_time = av_rescale_q(c->start, c->time_base, scale);
+        uint64_t offset;
+        int32_t send_time = get_send_time(asf, pres_time, &offset);
+        int len = 0;
+        uint8_t *buf;
+        AVIOContext *dyn_buf;
+        if (t) {
+            if (avio_open_dyn_buf(&dyn_buf) < 0)
+                return AVERROR(ENOMEM);
+            avio_put_str16le(dyn_buf, t->value);
+            len = avio_close_dyn_buf(dyn_buf, &buf);
+        }
+        avio_wl64(pb, offset);            // offset of the packet with send_time
+        avio_wl64(pb, pres_time + PREROLL_TIME * 10000); // presentation time
+        avio_wl16(pb, 12 + len);          // entry length
+        avio_wl32(pb, send_time);         // send time
+        avio_wl32(pb, 0);                 // flags, should be 0
+        avio_wl32(pb, len / 2);           // marker desc length in WCHARS!
+        if (t) {
+            avio_write(pb, buf, len);     // marker desc
+            av_freep(&buf);
+        }
+    }
+    end_header(pb, hpos);
+    return 0;
+}
+
 /* write the header (used two times if non streamed) */
-static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data_chunk_size)
+static int asf_write_header1(AVFormatContext *s, int64_t file_size,
+                             int64_t data_chunk_size)
 {
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = s->pb;
@@ -308,18 +363,18 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
 
     ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);
 
-    tags[0] = av_dict_get(s->metadata, "title"    , NULL, 0);
-    tags[1] = av_dict_get(s->metadata, "author"   , NULL, 0);
+    tags[0] = av_dict_get(s->metadata, "title", NULL, 0);
+    tags[1] = av_dict_get(s->metadata, "author", NULL, 0);
     tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0);
-    tags[3] = av_dict_get(s->metadata, "comment"  , NULL, 0);
-    tags[4] = av_dict_get(s->metadata, "rating"   , NULL, 0);
+    tags[3] = av_dict_get(s->metadata, "comment", NULL, 0);
+    tags[4] = av_dict_get(s->metadata, "rating", NULL, 0);
 
-    duration = asf->duration + PREROLL_TIME * 10000;
-    has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
+    duration       = asf->duration + PREROLL_TIME * 10000;
+    has_title      = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
     metadata_count = av_dict_count(s->metadata);
 
     bit_rate = 0;
-    for(n=0;n<s->nb_streams;n++) {
+    for (n = 0; n < s->nb_streams; n++) {
         enc = s->streams[n]->codec;
 
         avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */
@@ -339,7 +394,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
 
     /* file header */
     header_offset = avio_tell(pb);
-    hpos = put_header(pb, &ff_asf_file_header);
+    hpos          = put_header(pb, &ff_asf_file_header);
     put_guid(pb, &ff_asf_my_guid);
     avio_wl64(pb, file_size);
     file_time = 0;
@@ -348,7 +403,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
     avio_wl64(pb, duration); /* end time stamp (in 100ns units) */
     avio_wl64(pb, asf->duration); /* duration (in 100ns units) */
     avio_wl64(pb, PREROLL_TIME); /* start time stamp */
-    avio_wl32(pb, (asf->is_streamed || !pb->seekable ) ? 3 : 2); /* ??? */
+    avio_wl32(pb, (asf->is_streamed || !pb->seekable) ? 3 : 2);  /* ??? */
     avio_wl32(pb, s->packet_size); /* packet size */
     avio_wl32(pb, s->packet_size); /* packet size */
     avio_wl32(pb, bit_rate); /* Nominal data rate in bps */
@@ -392,28 +447,32 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
         }
         end_header(pb, hpos);
     }
-
+    /* chapters using ASF markers */
+    if (!asf->is_streamed && s->nb_chapters) {
+        int ret;
+        if (ret = asf_write_markers(s))
+            return ret;
+    }
     /* stream headers */
-    for(n=0;n<s->nb_streams;n++) {
+    for (n = 0; n < s->nb_streams; n++) {
         int64_t es_pos;
         //        ASFStream *stream = &asf->streams[n];
 
-        enc = s->streams[n]->codec;
+        enc                 = s->streams[n]->codec;
         asf->streams[n].num = n + 1;
         asf->streams[n].seq = 0;
 
-
-        switch(enc->codec_type) {
+        switch (enc->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
             wav_extra_size = 0;
-            extra_size = 18 + wav_extra_size;
-            extra_size2 = 8;
+            extra_size     = 18 + wav_extra_size;
+            extra_size2    = 8;
             break;
         default:
         case AVMEDIA_TYPE_VIDEO:
             wav_extra_size = enc->extradata_size;
-            extra_size = 0x33 + wav_extra_size;
-            extra_size2 = 0;
+            extra_size     = 0x33 + wav_extra_size;
+            extra_size2    = 0;
             break;
         }
 
@@ -446,10 +505,10 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
             }
             /* ERROR Correction */
             avio_w8(pb, 0x01);
-            if(enc->codec_id == AV_CODEC_ID_ADPCM_G726 || !enc->block_align){
+            if (enc->codec_id == AV_CODEC_ID_ADPCM_G726 || !enc->block_align) {
                 avio_wl16(pb, 0x0190);
                 avio_wl16(pb, 0x0190);
-            }else{
+            } else {
                 avio_wl16(pb, enc->block_align);
                 avio_wl16(pb, enc->block_align);
             }
@@ -472,7 +531,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
     hpos = put_header(pb, &ff_asf_codec_comment_header);
     put_guid(pb, &ff_asf_codec_comment1_header);
     avio_wl32(pb, s->nb_streams);
-    for(n=0;n<s->nb_streams;n++) {
+    for (n = 0; n < s->nb_streams; n++) {
         AVCodec *p;
         const char *desc;
         int len;
@@ -480,21 +539,21 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
         AVIOContext *dyn_buf;
 
         enc = s->streams[n]->codec;
-        p = avcodec_find_encoder(enc->codec_id);
+        p   = avcodec_find_encoder(enc->codec_id);
 
-        if(enc->codec_type == AVMEDIA_TYPE_AUDIO)
+        if (enc->codec_type == AVMEDIA_TYPE_AUDIO)
             avio_wl16(pb, 2);
-        else if(enc->codec_type == AVMEDIA_TYPE_VIDEO)
+        else if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
             avio_wl16(pb, 1);
         else
             avio_wl16(pb, -1);
 
-        if(enc->codec_id == AV_CODEC_ID_WMAV2)
+        if (enc->codec_id == AV_CODEC_ID_WMAV2)
             desc = "Windows Media Audio V8";
         else
             desc = p ? p->name : enc->codec_name;
 
-        if ( avio_open_dyn_buf(&dyn_buf) < 0)
+        if (avio_open_dyn_buf(&dyn_buf) < 0)
             return AVERROR(ENOMEM);
 
         avio_put_str16le(dyn_buf, desc);
@@ -506,7 +565,6 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
 
         avio_wl16(pb, 0); /* no parameters */
 
-
         /* id */
         if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
             avio_wl16(pb, 2);
@@ -515,24 +573,24 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
             avio_wl16(pb, 4);
             avio_wl32(pb, enc->codec_tag);
         }
-        if(!enc->codec_tag)
+        if (!enc->codec_tag)
             return -1;
     }
     end_header(pb, hpos);
 
     /* patch the header size fields */
 
-    cur_pos = avio_tell(pb);
+    cur_pos     = avio_tell(pb);
     header_size = cur_pos - header_offset;
     if (asf->is_streamed) {
-        header_size += 8 + 30 + 50;
+        header_size += 8 + 30 + DATA_HEADER_SIZE;
 
         avio_seek(pb, header_offset - 10 - 30, SEEK_SET);
         avio_wl16(pb, header_size);
         avio_seek(pb, header_offset - 2 - 30, SEEK_SET);
         avio_wl16(pb, header_size);
 
-        header_size -= 8 + 30 + 50;
+        header_size -= 8 + 30 + DATA_HEADER_SIZE;
     }
     header_size += 24 + 6;
     avio_seek(pb, header_offset - 14, SEEK_SET);
@@ -557,27 +615,27 @@ static int asf_write_header(AVFormatContext *s)
     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->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;
+    asf->nb_index_count        = 0;
+    asf->maximum_packet        = 0;
 
-    /* the data-chunk-size has to be 50, which is data_size - asf->data_offset
-     *  at the moment this function is done. It is needed to use asf as
-     *  streamable format. */
-    if (asf_write_header1(s, 0, 50) < 0) {
+    /* the data-chunk-size has to be 50 (DATA_HEADER_SIZE), which is
+     * data_size - asf->data_offset at the moment this function is done.
+     * It is needed to use asf as a streamable format. */
+    if (asf_write_header1(s, 0, DATA_HEADER_SIZE) < 0) {
         //av_free(asf);
         return -1;
     }
 
     avio_flush(s->pb);
 
-    asf->packet_nb_payloads = 0;
+    asf->packet_nb_payloads     = 0;
     asf->packet_timestamp_start = -1;
-    asf->packet_timestamp_end = -1;
+    asf->packet_timestamp_end   = -1;
     ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
-                  NULL, NULL, NULL, NULL);
+                      NULL, NULL, NULL, NULL);
 
     return 0;
 }
@@ -591,30 +649,25 @@ static int asf_write_stream_header(AVFormatContext *s)
     return asf_write_header(s);
 }
 
-static int put_payload_parsing_info(
-                                AVFormatContext *s,
-                                unsigned int    sendtime,
-                                unsigned int    duration,
-                                int             nb_payloads,
-                                int             padsize
-            )
+static int put_payload_parsing_info(AVFormatContext *s,
+                                    unsigned sendtime, unsigned duration,
+                                    int nb_payloads, int padsize)
 {
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = s->pb;
     int ppi_size, i;
-    int64_t start= avio_tell(pb);
+    int64_t start = avio_tell(pb);
 
     int iLengthTypeFlags = ASF_PPI_LENGTH_TYPE_FLAGS;
 
     padsize -= PACKET_HEADER_MIN_SIZE;
-    if(asf->multi_payloads_present)
+    if (asf->multi_payloads_present)
         padsize--;
-    assert(padsize>=0);
+    assert(padsize >= 0);
 
     avio_w8(pb, ASF_PACKET_ERROR_CORRECTION_FLAGS);
-    for (i = 0; i < ASF_PACKET_ERROR_CORRECTION_DATA_SIZE; i++){
+    for (i = 0; i < ASF_PACKET_ERROR_CORRECTION_DATA_SIZE; i++)
         avio_w8(pb, 0x0);
-    }
 
     if (asf->multi_payloads_present)
         iLengthTypeFlags |= ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT;
@@ -651,17 +704,15 @@ static void flush_packet(AVFormatContext *s)
 
     assert(asf->packet_timestamp_end >= asf->packet_timestamp_start);
 
-    if (asf->is_streamed) {
+    if (asf->is_streamed)
         put_chunk(s, 0x4424, s->packet_size, 0);
-    }
 
-    packet_hdr_size = put_payload_parsing_info(
-                            s,
-                            asf->packet_timestamp_start,
-                            asf->packet_timestamp_end - asf->packet_timestamp_start,
-                            asf->packet_nb_payloads,
-                            asf->packet_size_left
-                        );
+    packet_hdr_size = put_payload_parsing_info(s,
+                                               asf->packet_timestamp_start,
+                                               asf->packet_timestamp_end -
+                                               asf->packet_timestamp_start,
+                                               asf->packet_nb_payloads,
+                                               asf->packet_size_left);
 
     packet_filled_size = PACKET_SIZE - asf->packet_size_left;
     assert(packet_hdr_size <= asf->packet_size_left);
@@ -671,22 +722,16 @@ static void flush_packet(AVFormatContext *s)
 
     avio_flush(s->pb);
     asf->nb_packets++;
-    asf->packet_nb_payloads = 0;
+    asf->packet_nb_payloads     = 0;
     asf->packet_timestamp_start = -1;
-    asf->packet_timestamp_end = -1;
+    asf->packet_timestamp_end   = -1;
     ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
-                  NULL, NULL, NULL, NULL);
+                      NULL, NULL, NULL, NULL);
 }
 
-static void put_payload_header(
-                                AVFormatContext *s,
-                                ASFStream       *stream,
-                                int             presentation_time,
-                                int             m_obj_size,
-                                int             m_obj_offset,
-                                int             payload_len,
-                                int             flags
-            )
+static void put_payload_header(AVFormatContext *s, ASFStream *stream,
+                               int presentation_time, int m_obj_size,
+                               int m_obj_offset, int payload_len, int flags)
 {
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = &asf->pb;
@@ -697,8 +742,8 @@ static void put_payload_header(
         val |= ASF_PL_FLAG_KEY_FRAME;
     avio_w8(pb, val);
 
-    avio_w8(pb, stream->seq);  //Media object number
-    avio_wl32(pb, m_obj_offset); //Offset Into Media Object
+    avio_w8(pb, stream->seq);     // Media object number
+    avio_wl32(pb, m_obj_offset);  // Offset Into Media Object
 
     // Replicated Data shall be at least 8 bytes long.
     // The first 4 bytes of data shall contain the
@@ -707,23 +752,17 @@ static void put_payload_header(
     // Presentation Time for the media object that the payload belongs to.
     avio_w8(pb, ASF_PAYLOAD_REPLICATED_DATA_LENGTH);
 
-    avio_wl32(pb, m_obj_size);       //Replicated Data - Media Object Size
-    avio_wl32(pb, presentation_time);//Replicated Data - Presentation Time
+    avio_wl32(pb, m_obj_size);        // Replicated Data - Media Object Size
+    avio_wl32(pb, presentation_time); // Replicated Data - Presentation Time
 
-    if (asf->multi_payloads_present){
-        avio_wl16(pb, payload_len);   //payload length
+    if (asf->multi_payloads_present) {
+        avio_wl16(pb, payload_len);   // payload length
     }
 }
 
-static void put_frame(
-                    AVFormatContext *s,
-                    ASFStream       *stream,
-                    AVStream        *avst,
-                    int             timestamp,
-                    const uint8_t   *buf,
-                    int             m_obj_size,
-                    int             flags
-                )
+static void put_frame(AVFormatContext *s, ASFStream *stream, AVStream *avst,
+                      int timestamp, const uint8_t *buf,
+                      int m_obj_size, int flags)
 {
     ASFContext *asf = s->priv_data;
     int m_obj_offset, payload_len, frag_len1;
@@ -735,19 +774,20 @@ static void put_frame(
             asf->multi_payloads_present = (payload_len < MULTI_PAYLOAD_CONSTANT);
 
             asf->packet_size_left = PACKET_SIZE;
-            if (asf->multi_payloads_present){
+            if (asf->multi_payloads_present) {
                 frag_len1 = MULTI_PAYLOAD_CONSTANT - 1;
-            }
-            else {
+            } else {
                 frag_len1 = SINGLE_PAYLOAD_DATA_LENGTH;
             }
             asf->packet_timestamp_start = timestamp;
-        }
-        else {
+        } else {
             // multi payloads
-            frag_len1 = asf->packet_size_left - PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS - PACKET_HEADER_MIN_SIZE - 1;
+            frag_len1 = asf->packet_size_left -
+                        PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS -
+                        PACKET_HEADER_MIN_SIZE - 1;
 
-            if(frag_len1 < payload_len && avst->codec->codec_type == AVMEDIA_TYPE_AUDIO){
+            if (frag_len1 < payload_len &&
+                avst->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
                 flush_packet(s);
                 continue;
             }
@@ -756,9 +796,10 @@ static void put_frame(
             if (payload_len > frag_len1)
                 payload_len = frag_len1;
             else if (payload_len == (frag_len1 - 1))
-                payload_len = frag_len1 - 2;  //additional byte need to put padding length
+                payload_len = frag_len1 - 2;  // additional byte need to put padding length
 
-            put_payload_header(s, stream, timestamp+PREROLL_TIME, m_obj_size, m_obj_offset, payload_len, flags);
+            put_payload_header(s, stream, timestamp + PREROLL_TIME,
+                               m_obj_size, m_obj_offset, payload_len, flags);
             avio_write(&asf->pb, buf, payload_len);
 
             if (asf->multi_payloads_present)
@@ -772,7 +813,7 @@ static void put_frame(
             payload_len = 0;
         }
         m_obj_offset += payload_len;
-        buf += payload_len;
+        buf          += payload_len;
 
         if (!asf->multi_payloads_present)
             flush_packet(s);
@@ -785,61 +826,73 @@ static void put_frame(
 static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     ASFContext *asf = s->priv_data;
+    AVIOContext *pb = s->pb;
     ASFStream *stream;
     int64_t duration;
     AVCodecContext *codec;
-    int64_t packet_st,pts;
-    int start_sec,i;
-    int flags= pkt->flags;
+    int64_t packet_st, pts;
+    int start_sec, i;
+    int flags = pkt->flags;
+    uint64_t offset = avio_tell(pb);
 
-    codec = s->streams[pkt->stream_index]->codec;
+    codec  = s->streams[pkt->stream_index]->codec;
     stream = &asf->streams[pkt->stream_index];
 
-    if(codec->codec_type == AVMEDIA_TYPE_AUDIO)
+    if (codec->codec_type == AVMEDIA_TYPE_AUDIO)
         flags &= ~AV_PKT_FLAG_KEY;
 
     pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts;
     assert(pts != AV_NOPTS_VALUE);
-    duration = pts * 10000;
-    asf->duration= FFMAX(asf->duration, duration + pkt->duration * 10000);
+    duration      = pts * 10000;
+    asf->duration = FFMAX(asf->duration, duration + pkt->duration * 10000);
 
     packet_st = asf->nb_packets;
-    put_frame(s, stream, s->streams[pkt->stream_index], pkt->dts, pkt->data, pkt->size, flags);
+    put_frame(s, stream, s->streams[pkt->stream_index],
+              pkt->dts, pkt->data, pkt->size, flags);
 
     /* 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) {
+            for (i = asf->nb_index_count; i < start_sec; i++) {
+                if (i >= asf->nb_index_memory_alloc) {
+                    int err;
                     asf->nb_index_memory_alloc += ASF_INDEX_BLOCK;
-                    asf->index_ptr = (ASFIndex*)av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc );
+                    if ((err = av_reallocp_array(&asf->index_ptr,
+                                                asf->nb_index_memory_alloc,
+                                                sizeof(*asf->index_ptr))) < 0) {
+                       asf->nb_index_memory_alloc = 0;
+                       return err;
+                   }
                 }
                 // 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->index_ptr[i].packet_count  = (uint16_t)(asf->nb_packets - packet_st);
+                asf->index_ptr[i].send_time     = start_sec * INT64_C(10000000);
+                asf->index_ptr[i].offset        = offset;
+                asf->maximum_packet             = FFMAX(asf->maximum_packet,
+                                                        (uint16_t)(asf->nb_packets - packet_st));
             }
-            asf->nb_index_count = start_sec;
+            asf->nb_index_count   = start_sec;
             asf->last_indexed_pts = duration;
         }
     }
     return 0;
 }
 
-//
-static int asf_write_index(AVFormatContext *s, ASFIndex *index, uint16_t max, uint32_t count)
+static int asf_write_index(AVFormatContext *s, ASFIndex *index,
+                           uint16_t max, uint32_t count)
 {
     AVIOContext *pb = s->pb;
     int i;
 
     put_guid(pb, &ff_asf_simple_index_header);
-    avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2)*count);
+    avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2) * count);
     put_guid(pb, &ff_asf_my_guid);
     avio_wl64(pb, ASF_INDEXED_INTERVAL);
     avio_wl32(pb, max);
     avio_wl32(pb, count);
-    for(i=0; i<count; i++) {
+    for (i = 0; i < count; i++) {
         avio_wl32(pb, index[i].packet_number);
         avio_wl16(pb, index[i].packet_count);
     }
@@ -850,7 +903,7 @@ static int asf_write_index(AVFormatContext *s, ASFIndex *index, uint16_t max, ui
 static int asf_write_trailer(AVFormatContext *s)
 {
     ASFContext *asf = s->priv_data;
-    int64_t file_size,data_size;
+    int64_t file_size, data_size;
 
     /* flush the current packet */
     if (asf->pb.buf_ptr > asf->pb.buffer)
@@ -858,9 +911,8 @@ static int asf_write_trailer(AVFormatContext *s)
 
     /* write index */
     data_size = avio_tell(s->pb);
-    if ((!asf->is_streamed) && (asf->nb_index_count != 0)) {
+    if ((!asf->is_streamed) && (asf->nb_index_count != 0))
         asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->nb_index_count);
-    }
     avio_flush(s->pb);
 
     if (asf->is_streamed || !s->pb->seekable) {
@@ -889,11 +941,11 @@ AVOutputFormat ff_asf_muxer = {
     .write_packet   = asf_write_packet,
     .write_trailer  = asf_write_trailer,
     .flags          = AVFMT_GLOBALHEADER,
-    .codec_tag      = (const AVCodecTag* const []){
+    .codec_tag      = (const AVCodecTag * const []) {
         codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0
     },
 };
-#endif
+#endif /* CONFIG_ASF_MUXER */
 
 #if CONFIG_ASF_STREAM_MUXER
 AVOutputFormat ff_asf_stream_muxer = {
@@ -908,8 +960,8 @@ AVOutputFormat ff_asf_stream_muxer = {
     .write_packet   = asf_write_packet,
     .write_trailer  = asf_write_trailer,
     .flags          = AVFMT_GLOBALHEADER,
-    .codec_tag      = (const AVCodecTag* const []){
+    .codec_tag      = (const AVCodecTag * const []) {
         codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0
     },
 };
-#endif //CONFIG_ASF_STREAM_MUXER
+#endif /* CONFIG_ASF_STREAM_MUXER */
diff --git a/libavformat/assdec.c b/libavformat/assdec.c
index 0041ca4..b994cc1 100644
--- a/libavformat/assdec.c
+++ b/libavformat/assdec.c
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavutil/mathematics.h"
 #include "avformat.h"
 #include "internal.h"
diff --git a/libavformat/assenc.c b/libavformat/assenc.c
index 5bf2e20..751485d 100644
--- a/libavformat/assenc.c
+++ b/libavformat/assenc.c
@@ -58,9 +58,6 @@ static int write_header(AVFormatContext *s)
 static int write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     avio_write(s->pb, pkt->data, pkt->size);
-
-    avio_flush(s->pb);
-
     return 0;
 }
 
diff --git a/libavformat/au.c b/libavformat/au.c
index 8f9a3fa..6b252b2 100644
--- a/libavformat/au.c
+++ b/libavformat/au.c
@@ -2,6 +2,8 @@
  * AU muxer and demuxer
  * Copyright (c) 2001 Fabrice Bellard
  *
+ * first version by Francois Revol <revol at free.fr>
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -20,8 +22,6 @@
  */
 
 /*
- * First version by Francois Revol revol at free.fr
- *
  * Reference documents:
  * http://www.opengroup.org/public/pubs/external/auformat.html
  * http://www.goice.co.jp/member/mo/formats/au.html
@@ -32,24 +32,22 @@
 #include "avio_internal.h"
 #include "pcm.h"
 
-/* The libavcodec codecs we support, and the IDs they have in the file */
 static const AVCodecTag codec_au_tags[] = {
-    { AV_CODEC_ID_PCM_MULAW, 1 },
-    { AV_CODEC_ID_PCM_S8, 2 },
-    { AV_CODEC_ID_PCM_S16BE, 3 },
-    { AV_CODEC_ID_PCM_S24BE, 4 },
-    { AV_CODEC_ID_PCM_S32BE, 5 },
-    { AV_CODEC_ID_PCM_F32BE, 6 },
-    { AV_CODEC_ID_PCM_F64BE, 7 },
-    { AV_CODEC_ID_PCM_ALAW, 27 },
-    { AV_CODEC_ID_NONE, 0 },
+    { AV_CODEC_ID_PCM_MULAW,  1 },
+    { AV_CODEC_ID_PCM_S8,     2 },
+    { AV_CODEC_ID_PCM_S16BE,  3 },
+    { AV_CODEC_ID_PCM_S24BE,  4 },
+    { AV_CODEC_ID_PCM_S32BE,  5 },
+    { AV_CODEC_ID_PCM_F32BE,  6 },
+    { AV_CODEC_ID_PCM_F64BE,  7 },
+    { AV_CODEC_ID_PCM_ALAW,  27 },
+    { AV_CODEC_ID_NONE,       0 },
 };
 
 #if CONFIG_AU_DEMUXER
 
 static int au_probe(AVProbeData *p)
 {
-    /* check file header */
     if (p->buf[0] == '.' && p->buf[1] == 's' &&
         p->buf[2] == 'n' && p->buf[3] == 'd')
         return AVPROBE_SCORE_MAX;
@@ -57,143 +55,149 @@ static int au_probe(AVProbeData *p)
         return 0;
 }
 
-/* au input */
+#define BLOCK_SIZE 1024
+
 static int au_read_header(AVFormatContext *s)
 {
     int size;
     unsigned int tag;
     AVIOContext *pb = s->pb;
     unsigned int id, channels, rate;
+    int bps;
     enum AVCodecID codec;
     AVStream *st;
 
-    /* check ".snd" header */
     tag = avio_rl32(pb);
     if (tag != MKTAG('.', 's', 'n', 'd'))
-        return -1;
+        return AVERROR_INVALIDDATA;
     size = avio_rb32(pb); /* header size */
-    avio_rb32(pb); /* data size */
+    avio_rb32(pb);        /* data size */
 
-    id = avio_rb32(pb);
-    rate = avio_rb32(pb);
+    id       = avio_rb32(pb);
+    rate     = avio_rb32(pb);
     channels = avio_rb32(pb);
 
+    if (size > 24) {
+        /* skip unused data */
+        avio_skip(pb, size - 24);
+    }
+
     codec = ff_codec_get_id(codec_au_tags, id);
 
-    if (!av_get_bits_per_sample(codec)) {
-        av_log_ask_for_sample(s, "could not determine bits per sample\n");
+    if (codec == AV_CODEC_ID_NONE) {
+        avpriv_request_sample(s, "unknown or unsupported codec tag: %u", id);
         return AVERROR_PATCHWELCOME;
     }
 
-    if (channels == 0 || channels > 64) {
-        av_log(s, AV_LOG_ERROR, "Invalid number of channels %d\n", channels);
+    bps = av_get_bits_per_sample(codec);
+    if (!bps) {
+        avpriv_request_sample(s, "Unknown bits per sample");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (channels == 0 || channels >= INT_MAX / (BLOCK_SIZE * bps >> 3)) {
+        av_log(s, AV_LOG_ERROR, "Invalid number of channels %u\n", channels);
         return AVERROR_INVALIDDATA;
     }
 
-    if (size >= 24) {
-        /* skip unused data */
-        avio_skip(pb, size - 24);
+    if (rate == 0 || rate > INT_MAX) {
+        av_log(s, AV_LOG_ERROR, "Invalid sample rate: %u\n", rate);
+        return AVERROR_INVALIDDATA;
     }
 
-    /* now we are ready: build format streams */
     st = avformat_new_stream(s, NULL);
     if (!st)
-        return -1;
-    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_tag = id;
-    st->codec->codec_id = codec;
-    st->codec->channels = channels;
+        return AVERROR(ENOMEM);
+    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_tag   = id;
+    st->codec->codec_id    = codec;
+    st->codec->channels    = channels;
     st->codec->sample_rate = rate;
+    st->codec->bit_rate    = channels * rate * bps;
+    st->codec->block_align = channels * bps >> 3;
+
+    st->start_time = 0;
     avpriv_set_pts_info(st, 64, 1, rate);
+
     return 0;
 }
 
-#define BLOCK_SIZE 1024
-
-static int au_read_packet(AVFormatContext *s,
-                          AVPacket *pkt)
+static int au_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret;
 
-    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);
+    ret = av_get_packet(s->pb, pkt, BLOCK_SIZE *
+                        s->streams[0]->codec->block_align);
     if (ret < 0)
         return ret;
+
     pkt->stream_index = 0;
+    pkt->duration     = ret / s->streams[0]->codec->block_align;
 
-    /* note: we need to modify the packet size here to handle the last
-       packet */
-    pkt->size = ret;
     return 0;
 }
 
 AVInputFormat ff_au_demuxer = {
-    .name           = "au",
-    .long_name      = NULL_IF_CONFIG_SMALL("Sun AU"),
-    .read_probe     = au_probe,
-    .read_header    = au_read_header,
-    .read_packet    = au_read_packet,
-    .read_seek      = ff_pcm_read_seek,
-    .codec_tag      = (const AVCodecTag* const []){ codec_au_tags, 0 },
+    .name        = "au",
+    .long_name   = NULL_IF_CONFIG_SMALL("Sun AU"),
+    .read_probe  = au_probe,
+    .read_header = au_read_header,
+    .read_packet = au_read_packet,
+    .read_seek   = ff_pcm_read_seek,
+    .codec_tag   = (const AVCodecTag* const []) { codec_au_tags, 0 },
 };
+
 #endif /* CONFIG_AU_DEMUXER */
 
 #if CONFIG_AU_MUXER
 
+#include "rawenc.h"
+
 /* if we don't know the size in advance */
 #define AU_UNKNOWN_SIZE ((uint32_t)(~0))
 
 /* AUDIO_FILE header */
 static int put_au_header(AVIOContext *pb, AVCodecContext *enc)
 {
-    if(!enc->codec_tag)
-        return -1;
-    ffio_wfourcc(pb, ".snd");    /* magic number */
-    avio_wb32(pb, 24);           /* header size */
-    avio_wb32(pb, AU_UNKNOWN_SIZE); /* data size */
-    avio_wb32(pb, (uint32_t)enc->codec_tag);     /* codec ID */
+    if (!enc->codec_tag)
+        return AVERROR(EINVAL);
+
+    ffio_wfourcc(pb, ".snd");                   /* magic number */
+    avio_wb32(pb, 24);                          /* header size */
+    avio_wb32(pb, AU_UNKNOWN_SIZE);             /* data size */
+    avio_wb32(pb, enc->codec_tag);              /* codec ID */
     avio_wb32(pb, enc->sample_rate);
-    avio_wb32(pb, (uint32_t)enc->channels);
+    avio_wb32(pb, enc->channels);
+
     return 0;
 }
 
 static int au_write_header(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
+    int ret;
 
     s->priv_data = NULL;
 
-    /* format header */
-    if (put_au_header(pb, s->streams[0]->codec) < 0) {
-        return -1;
-    }
+    if ((ret = put_au_header(pb, s->streams[0]->codec)) < 0)
+        return ret;
 
     avio_flush(pb);
 
     return 0;
 }
 
-static int au_write_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    AVIOContext *pb = s->pb;
-    avio_write(pb, pkt->data, pkt->size);
-    return 0;
-}
-
 static int au_write_trailer(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
     int64_t file_size;
 
     if (s->pb->seekable) {
-
         /* update file size */
         file_size = avio_tell(pb);
         avio_seek(pb, 8, SEEK_SET);
         avio_wb32(pb, (uint32_t)(file_size - 24));
         avio_seek(pb, file_size, SEEK_SET);
-
         avio_flush(pb);
     }
 
@@ -201,15 +205,16 @@ static int au_write_trailer(AVFormatContext *s)
 }
 
 AVOutputFormat ff_au_muxer = {
-    .name              = "au",
-    .long_name         = NULL_IF_CONFIG_SMALL("Sun AU"),
-    .mime_type         = "audio/basic",
-    .extensions        = "au",
-    .audio_codec       = AV_CODEC_ID_PCM_S16BE,
-    .video_codec       = AV_CODEC_ID_NONE,
-    .write_header      = au_write_header,
-    .write_packet      = au_write_packet,
-    .write_trailer     = au_write_trailer,
-    .codec_tag         = (const AVCodecTag* const []){ codec_au_tags, 0 },
+    .name          = "au",
+    .long_name     = NULL_IF_CONFIG_SMALL("Sun AU"),
+    .mime_type     = "audio/basic",
+    .extensions    = "au",
+    .audio_codec   = AV_CODEC_ID_PCM_S16BE,
+    .video_codec   = AV_CODEC_ID_NONE,
+    .write_header  = au_write_header,
+    .write_packet  = ff_raw_write_packet,
+    .write_trailer = au_write_trailer,
+    .codec_tag     = (const AVCodecTag* const []) { codec_au_tags, 0 },
 };
+
 #endif /* CONFIG_AU_MUXER */
diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c
index 5df0bb0..e4cde9d 100644
--- a/libavformat/audiointerleave.c
+++ b/libavformat/audiointerleave.c
@@ -70,8 +70,8 @@ int ff_audio_interleave_init(AVFormatContext *s,
     return 0;
 }
 
-static int ff_interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt,
-                                   int stream_index, int flush)
+static int interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt,
+                                       int stream_index, int flush)
 {
     AVStream *st = s->streams[stream_index];
     AudioInterleaveContext *aic = st->priv_data;
@@ -125,7 +125,7 @@ int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt
         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))
+            while (interleave_new_audio_packet(s, &new_pkt, i, flush))
                 ff_interleave_add_packet(s, &new_pkt, compare_ts);
         }
     }
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 149b66f..50e4f5c 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -158,9 +158,9 @@
  * information will be in AVStream.time_base units, i.e. it has to be
  * multiplied by the timebase to convert them to seconds.
  *
- * If AVPacket.destruct is set on the returned packet, then the packet is
+ * If AVPacket.buf is set on the returned packet, then the packet is
  * allocated dynamically and the user may keep it indefinitely.
- * Otherwise, if AVPacket.destruct is NULL, the packet data is backed by a
+ * Otherwise, if AVPacket.buf is NULL, the packet data is backed by a
  * static storage somewhere inside the demuxer and the packet is only valid
  * until the next av_read_frame() call or closing the file. If the caller
  * requires a longer lifetime, av_dup_packet() will make an av_malloc()ed copy
@@ -207,10 +207,6 @@
 #include "avio.h"
 #include "libavformat/version.h"
 
-#if FF_API_AV_GETTIME
-#include "libavutil/time.h"
-#endif
-
 struct AVFormatContext;
 
 
@@ -341,7 +337,9 @@ typedef struct AVProbeData {
     int buf_size;       /**< Size of buf except extra allocated bytes */
 } AVProbeData;
 
-#define AVPROBE_SCORE_MAX 100               ///< maximum score, half of that is used for file-extension-based detection
+#define AVPROBE_SCORE_EXTENSION  50 ///< score for file extension
+#define AVPROBE_SCORE_MAX       100 ///< maximum score
+
 #define AVPROBE_PADDING_SIZE 32             ///< extra allocated bytes at the end of the probe buffer
 
 /// Demuxer will use avio_open, no opened file should be provided by the caller.
@@ -357,13 +355,18 @@ typedef struct AVProbeData {
 #define AVFMT_VARIABLE_FPS  0x0400 /**< Format allows variable fps. */
 #define AVFMT_NODIMENSIONS  0x0800 /**< Format does not need width/height */
 #define AVFMT_NOSTREAMS     0x1000 /**< Format does not require any streams */
-#define AVFMT_NOBINSEARCH   0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
-#define AVFMT_NOGENSEARCH   0x4000 /**< Format does not allow to fallback to generic search */
+#define AVFMT_NOBINSEARCH   0x2000 /**< Format does not allow to fall back on binary search via read_timestamp */
+#define AVFMT_NOGENSEARCH   0x4000 /**< Format does not allow to fall back on generic search */
 #define AVFMT_NO_BYTE_SEEK  0x8000 /**< Format does not allow seeking by bytes */
 #define AVFMT_ALLOW_FLUSH  0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
 #define AVFMT_TS_NONSTRICT 0x20000 /**< Format does not require strictly
                                         increasing timestamps, but they must
                                         still be monotonic */
+#define AVFMT_TS_NEGATIVE  0x40000 /**< Format allows muxing negative
+                                        timestamps. If not set the timestamp
+                                        will be shifted in av_write_frame and
+                                        av_interleaved_write_frame so they
+                                        start from 0. */
 
 /**
  * @addtogroup lavf_encoding
@@ -636,17 +639,6 @@ typedef struct AVStream {
      *             not actually used for encoding.
      */
     AVCodecContext *codec;
-#if FF_API_R_FRAME_RATE
-    /**
-     * Real base framerate of the stream.
-     * This is the lowest framerate with which all timestamps can be
-     * represented accurately (it is the least common multiple of all
-     * framerates in the stream). Note, this value is just a guess!
-     * For example, if the time base is 1/90000 and all frames have either
-     * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
-     */
-    AVRational r_frame_rate;
-#endif
     void *priv_data;
 
     /**
@@ -722,12 +714,6 @@ typedef struct AVStream {
      */
 #define MAX_STD_TIMEBASES (60*12+5)
     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;
         int found_decoder;
 
@@ -743,15 +729,12 @@ typedef struct AVStream {
 
     int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */
 
+#if FF_API_REFERENCE_DTS
+    /* a hack to keep ABI compatibility for avconv, which accesses parser even
+     * though it should not */
+    int64_t do_not_use;
+#endif
     // Timestamp generation support:
-    /**
-     * Timestamp corresponding to the last dts sync point.
-     *
-     * Initialized when AVCodecParserContext.dts_sync_point >= 0 and
-     * a DTS is received from the underlying container. Otherwise set to
-     * AV_NOPTS_VALUE by default.
-     */
-    int64_t reference_dts;
     int64_t first_dts;
     int64_t cur_dts;
     int64_t last_IP_pts;
@@ -908,6 +891,7 @@ typedef struct AVFormatContext {
 #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_FLUSH_PACKETS    0x0200 ///< Flush the AVIOContext every packet.
 
     /**
      * decoding: size of data to probe; encoding: unused.
@@ -962,6 +946,17 @@ typedef struct AVFormatContext {
      */
     unsigned int max_picture_buffer;
 
+    /**
+     * Number of chapters in AVChapter array.
+     * When muxing, chapters are normally written in the file header,
+     * so nb_chapters should normally be initialized before write_header
+     * is called. Some muxers (e.g. mov and mkv) can also write chapters
+     * in the trailer.  To write chapters in the trailer, nb_chapters
+     * must be zero when write_header is called and non-zero when
+     * write_trailer is called.
+     * muxing  : set by user
+     * demuxing: set by libavformat
+     */
     unsigned int nb_chapters;
     AVChapter **chapters;
 
@@ -1042,6 +1037,18 @@ typedef struct AVFormatContext {
      */
 #define RAW_PACKET_BUFFER_SIZE 2500000
     int raw_packet_buffer_remaining_size;
+
+    /**
+     * Offset to remap timestamps to be non-negative.
+     * Expressed in timebase units.
+     */
+    int64_t offset;
+
+    /**
+     * Timebase for the timestamp offset.
+     */
+    AVRational offset_timebase;
+
 } AVFormatContext;
 
 typedef struct AVPacketList {
@@ -1214,7 +1221,7 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
 
 /**
  * Open an input stream and read the header. The codecs are not opened.
- * The stream must be closed with av_close_input_file().
+ * The stream must be closed with avformat_close_input().
  *
  * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
  *           May be a pointer to NULL, in which case an AVFormatContext is allocated by this
@@ -1287,24 +1294,6 @@ int av_find_best_stream(AVFormatContext *ic,
                         AVCodec **decoder_ret,
                         int flags);
 
-#if FF_API_READ_PACKET
-/**
- * @deprecated use AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE to read raw
- * unprocessed packets
- *
- * Read a transport packet from a media file.
- *
- * This function is obsolete and should never be used.
- * Use av_read_frame() instead.
- *
- * @param s media file handle
- * @param pkt is filled
- * @return 0 if OK, AVERROR_xxx on error
- */
-attribute_deprecated
-int av_read_packet(AVFormatContext *s, AVPacket *pkt);
-#endif
-
 /**
  * Return the next frame of a stream.
  * This function returns what is stored in the file, and does not validate
@@ -1313,9 +1302,9 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt);
  * omit invalid data between valid frames so as to give the decoder the maximum
  * information possible for decoding.
  *
- * If pkt->destruct is NULL, then the packet is valid until the next
- * av_read_frame() or until av_close_input_file(). Otherwise the packet is valid
- * indefinitely. In both cases the packet must be freed with
+ * If pkt->buf is NULL, then the packet is valid until the next
+ * av_read_frame() or until avformat_close_input(). Otherwise the packet
+ * is valid indefinitely. In both cases the packet must be freed with
  * av_free_packet when it is no longer needed. For video, the packet contains
  * exactly one frame. For audio, it contains an integer number of frames if each
  * frame has a known fixed size (e.g. PCM or ADPCM data). If the audio frames
@@ -1386,17 +1375,6 @@ int av_read_play(AVFormatContext *s);
  */
 int av_read_pause(AVFormatContext *s);
 
-#if FF_API_CLOSE_INPUT_FILE
-/**
- * @deprecated use avformat_close_input()
- * Close a media file (but not its codecs).
- *
- * @param s media file handle
- */
-attribute_deprecated
-void av_close_input_file(AVFormatContext *s);
-#endif
-
 /**
  * Close an opened input AVFormatContext. Free it and all its contents
  * and set *s to NULL.
@@ -1421,7 +1399,7 @@ void avformat_close_input(AVFormatContext **s);
  *
  * @param s Media file handle, must be allocated with avformat_alloc_context().
  *          Its oformat field must be set to the desired output format;
- *          Its pb field must be set to an already openened AVIOContext.
+ *          Its pb field must be set to an already opened AVIOContext.
  * @param options  An AVDictionary filled with AVFormatContext and muxer-private options.
  *                 On return this parameter will be destroyed and replaced with a dict containing
  *                 options that were not found. May be NULL.
@@ -1461,10 +1439,10 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt);
  * demuxer level.
  *
  * @param s media file handle
- * @param pkt The packet containing the data to be written. Libavformat takes
- * ownership of the data and will free it when it sees fit using the packet's
- * @ref AVPacket.destruct "destruct" field. The caller must not access the data
- * after this function returns, as it may already be freed.
+ * @param pkt The packet containing the data to be written. pkt->buf must be set
+ * to a valid AVBufferRef describing the packet data. Libavformat takes
+ * ownership of this reference and will unref it when it sees fit. The caller
+ * must not access the data through this reference after this function returns.
  * This can be NULL (at any time, not just at the end), to flush the
  * interleaving queues.
  * Packet's @ref AVPacket.stream_index "stream_index" field must be set to the
@@ -1478,16 +1456,6 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt);
  */
 int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);
 
-#if FF_API_INTERLEAVE_PACKET
-/**
- * @deprecated this function was never meant to be called by the user
- * programs.
- */
-attribute_deprecated
-int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
-                                 AVPacket *pkt, int flush);
-#endif
-
 /**
  * Write the stream trailer to an output media file and free the
  * file private data.
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index e17d932..6f80d21 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -19,37 +19,41 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/intreadwrite.h"
-#include "libavutil/mathematics.h"
+#include <stdint.h>
+
+#include "libavutil/avstring.h"
 #include "libavutil/bswap.h"
 #include "libavutil/dict.h"
-#include "libavutil/avstring.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
 #include "avformat.h"
-#include "internal.h"
 #include "avi.h"
 #include "dv.h"
+#include "internal.h"
 #include "riff.h"
 
 #undef NDEBUG
 #include <assert.h>
 
 typedef struct AVIStream {
-    int64_t frame_offset; /* current frame (video) or byte (audio) counter
-                         (used to compute the pts) */
+    int64_t frame_offset;   /* current frame (video) or byte (audio) counter
+                             * (used to compute the pts) */
     int remaining;
     int packet_size;
 
     uint32_t scale;
     uint32_t rate;
-    int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
-
-    int64_t cum_len; /* temporary storage (used during seek) */
+    int sample_size;        /* size of one sample (or packet)
+                             * (in the rate/scale sense) in bytes */
 
-    int prefix;                       ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
+    int64_t cum_len;        /* temporary storage (used during seek) */
+    int prefix;             /* normally 'd'<<8 + 'c' or 'w'<<8 + 'b' */
     int prefix_count;
     uint32_t pal[256];
     int has_pal;
-    int dshow_block_align;            ///< block align variable used to emulate bugs in the MS dshow demuxer
+    int dshow_block_align;  /* block align variable used to emulate bugs in
+                             * the MS dshow demuxer */
 
     AVFormatContext *sub_ctx;
     AVPacket sub_pkt;
@@ -57,26 +61,26 @@ typedef struct AVIStream {
 } AVIStream;
 
 typedef struct {
-    int64_t  riff_end;
-    int64_t  movi_end;
-    int64_t  fsize;
+    int64_t riff_end;
+    int64_t movi_end;
+    int64_t fsize;
     int64_t movi_list;
     int64_t last_pkt_pos;
     int index_loaded;
     int is_odml;
     int non_interleaved;
     int stream_index;
-    DVDemuxContext* dv_demux;
+    DVDemuxContext *dv_demux;
     int odml_depth;
 #define MAX_ODML_DEPTH 1000
 } AVIContext;
 
 static const char avi_headers[][8] = {
-    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', ' ' },
-    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 'X' },
-    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 0x19},
-    { 'O', 'N', '2', ' ',    'O', 'N', '2', 'f' },
-    { 'R', 'I', 'F', 'F',    'A', 'M', 'V', ' ' },
+    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' '  },
+    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X'  },
+    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19 },
+    { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f'  },
+    { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' '  },
     { 0 }
 };
 
@@ -88,20 +92,21 @@ static const AVMetadataConv avi_metadata_conv[] = {
 static int avi_load_index(AVFormatContext *s);
 static int guess_ni_flag(AVFormatContext *s);
 
-#define print_tag(str, tag, size)                       \
-    av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n",       \
-           str, tag & 0xff,                             \
-           (tag >> 8) & 0xff,                           \
-           (tag >> 16) & 0xff,                          \
-           (tag >> 24) & 0xff,                          \
-           size)
+#define print_tag(str, tag, size)                        \
+    av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n",        \
+            str, tag & 0xff,                             \
+            (tag >> 8) & 0xff,                           \
+            (tag >> 16) & 0xff,                          \
+            (tag >> 24) & 0xff,                          \
+            size)
 
-static inline int get_duration(AVIStream *ast, int len){
-    if(ast->sample_size){
+static inline int get_duration(AVIStream *ast, int len)
+{
+    if (ast->sample_size)
         return len;
-    }else if (ast->dshow_block_align){
-        return (len + ast->dshow_block_align - 1)/ast->dshow_block_align;
-    }else
+    else if (ast->dshow_block_align)
+        return (len + ast->dshow_block_align - 1) / ast->dshow_block_align;
+    else
         return 1;
 }
 
@@ -113,101 +118,113 @@ static int get_riff(AVFormatContext *s, AVIOContext *pb)
 
     /* check RIFF header */
     avio_read(pb, header, 4);
-    avi->riff_end = avio_rl32(pb);  /* RIFF chunk size */
+    avi->riff_end  = avio_rl32(pb); /* RIFF chunk size */
     avi->riff_end += avio_tell(pb); /* RIFF chunk end */
-    avio_read(pb, header+4, 4);
+    avio_read(pb, header + 4, 4);
 
-    for(i=0; avi_headers[i][0]; i++)
-        if(!memcmp(header, avi_headers[i], 8))
+    for (i = 0; avi_headers[i][0]; i++)
+        if (!memcmp(header, avi_headers[i], 8))
             break;
-    if(!avi_headers[i][0])
-        return -1;
+    if (!avi_headers[i][0])
+        return AVERROR_INVALIDDATA;
 
-    if(header[7] == 0x19)
-        av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n");
+    if (header[7] == 0x19)
+        av_log(s, AV_LOG_INFO,
+               "This file has been generated by a totally broken muxer.\n");
 
     return 0;
 }
 
-static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
-    AVIContext *avi = s->priv_data;
-    AVIOContext *pb = s->pb;
-    int longs_pre_entry= avio_rl16(pb);
-    int index_sub_type = avio_r8(pb);
-    int index_type     = avio_r8(pb);
-    int entries_in_use = avio_rl32(pb);
-    int chunk_id       = avio_rl32(pb);
-    int64_t base       = avio_rl64(pb);
-    int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
+static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
+{
+    AVIContext *avi     = s->priv_data;
+    AVIOContext *pb     = s->pb;
+    int longs_pre_entry = avio_rl16(pb);
+    int index_sub_type  = avio_r8(pb);
+    int index_type      = avio_r8(pb);
+    int entries_in_use  = avio_rl32(pb);
+    int chunk_id        = avio_rl32(pb);
+    int64_t base        = avio_rl64(pb);
+    int stream_id       = ((chunk_id      & 0xFF) - '0') * 10 +
+                          ((chunk_id >> 8 & 0xFF) - '0');
     AVStream *st;
     AVIStream *ast;
     int i;
-    int64_t last_pos= -1;
-    int64_t filesize= avio_size(s->pb);
-
-    av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
-            longs_pre_entry,index_type, entries_in_use, chunk_id, base);
-
-    if(stream_id >= s->nb_streams || stream_id < 0)
-        return -1;
-    st= s->streams[stream_id];
+    int64_t last_pos = -1;
+    int64_t filesize = avio_size(s->pb);
+
+    av_dlog(s,
+            "longs_pre_entry:%d index_type:%d entries_in_use:%d "
+            "chunk_id:%X base:%16"PRIX64"\n",
+            longs_pre_entry,
+            index_type,
+            entries_in_use,
+            chunk_id,
+            base);
+
+    if (stream_id >= s->nb_streams || stream_id < 0)
+        return AVERROR_INVALIDDATA;
+    st  = s->streams[stream_id];
     ast = st->priv_data;
 
-    if(index_sub_type)
-        return -1;
+    if (index_sub_type)
+        return AVERROR_INVALIDDATA;
 
     avio_rl32(pb);
 
-    if(index_type && longs_pre_entry != 2)
-        return -1;
-    if(index_type>1)
-        return -1;
+    if (index_type && longs_pre_entry != 2)
+        return AVERROR_INVALIDDATA;
+    if (index_type > 1)
+        return AVERROR_INVALIDDATA;
 
-    if(filesize > 0 && base >= filesize){
+    if (filesize > 0 && base >= filesize) {
         av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
-        if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
+        if (base >> 32 == (base & 0xFFFFFFFF) &&
+            (base & 0xFFFFFFFF) < filesize    &&
+            filesize <= 0xFFFFFFFF)
             base &= 0xFFFFFFFF;
         else
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
-    for(i=0; i<entries_in_use; i++){
-        if(index_type){
-            int64_t pos= avio_rl32(pb) + base - 8;
-            int len    = avio_rl32(pb);
-            int key= len >= 0;
+    for (i = 0; i < entries_in_use; i++) {
+        if (index_type) {
+            int64_t pos = avio_rl32(pb) + base - 8;
+            int len     = avio_rl32(pb);
+            int key     = len >= 0;
             len &= 0x7FFFFFFF;
 
             av_dlog(s, "pos:%"PRId64", len:%X\n", pos, len);
 
-            if(pb->eof_reached)
-                return -1;
+            if (pb->eof_reached)
+                return AVERROR_INVALIDDATA;
 
-            if(last_pos == pos || pos == base - 8)
-                avi->non_interleaved= 1;
-            if(last_pos != pos && (len || !ast->sample_size))
-                av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0);
+            if (last_pos == pos || pos == base - 8)
+                avi->non_interleaved = 1;
+            if (last_pos != pos && (len || !ast->sample_size))
+                av_add_index_entry(st, pos, ast->cum_len, len, 0,
+                                   key ? AVINDEX_KEYFRAME : 0);
 
             ast->cum_len += get_duration(ast, len);
-            last_pos= pos;
-        }else{
+            last_pos      = pos;
+        } else {
             int64_t offset, pos;
             int duration;
             offset = avio_rl64(pb);
             avio_rl32(pb);       /* size */
             duration = avio_rl32(pb);
 
-            if(pb->eof_reached)
-                return -1;
+            if (pb->eof_reached)
+                return AVERROR_INVALIDDATA;
 
             pos = avio_tell(pb);
 
-            if(avi->odml_depth > MAX_ODML_DEPTH){
+            if (avi->odml_depth > MAX_ODML_DEPTH) {
                 av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
-            avio_seek(pb, offset+8, SEEK_SET);
+            avio_seek(pb, offset + 8, SEEK_SET);
             avi->odml_depth++;
             read_braindead_odml_indx(s, frame_num);
             avi->odml_depth--;
@@ -216,55 +233,59 @@ static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
             avio_seek(pb, pos, SEEK_SET);
         }
     }
-    avi->index_loaded=1;
+    avi->index_loaded = 1;
     return 0;
 }
 
-static void clean_index(AVFormatContext *s){
+static void clean_index(AVFormatContext *s)
+{
     int i;
     int64_t j;
 
-    for(i=0; i<s->nb_streams; i++){
-        AVStream *st = s->streams[i];
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st   = s->streams[i];
         AVIStream *ast = st->priv_data;
-        int n= st->nb_index_entries;
-        int max= ast->sample_size;
+        int n          = st->nb_index_entries;
+        int max        = ast->sample_size;
         int64_t pos, size, ts;
 
-        if(n != 1 || ast->sample_size==0)
+        if (n != 1 || ast->sample_size == 0)
             continue;
 
-        while(max < 1024) max+=max;
+        while (max < 1024)
+            max += max;
 
-        pos= st->index_entries[0].pos;
-        size= st->index_entries[0].size;
-        ts= st->index_entries[0].timestamp;
+        pos  = st->index_entries[0].pos;
+        size = st->index_entries[0].size;
+        ts   = st->index_entries[0].timestamp;
 
-        for(j=0; j<size; j+=max){
-            av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
-        }
+        for (j = 0; j < size; j += max)
+            av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0,
+                               AVINDEX_KEYFRAME);
     }
 }
 
-static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size)
+static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag,
+                        uint32_t size)
 {
     AVIOContext *pb = s->pb;
-    char key[5] = {0}, *value;
+    char key[5]     = { 0 };
+    char *value;
 
     size += (size & 1);
 
     if (size == UINT_MAX)
-        return -1;
-    value = av_malloc(size+1);
+        return AVERROR(EINVAL);
+    value = av_malloc(size + 1);
     if (!value)
-        return -1;
+        return AVERROR(ENOMEM);
     avio_read(pb, value, size);
-    value[size]=0;
+    value[size] = 0;
 
     AV_WL32(key, tag);
 
     return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
-                            AV_DICT_DONT_STRDUP_VAL);
+                       AV_DICT_DONT_STRDUP_VAL);
 }
 
 static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
@@ -277,10 +298,10 @@ static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
     /* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */
     if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
                month, &day, time, &year) == 4) {
-        for (i=0; i<12; i++)
+        for (i = 0; i < 12; i++)
             if (!av_strcasecmp(month, months[i])) {
                 snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
-                         year, i+1, day, time);
+                         year, i + 1, day, time);
                 av_dict_set(metadata, "creation_time", buffer, 0);
             }
     } else if (date[4] == '/' && date[7] == '/') {
@@ -295,19 +316,25 @@ static void avi_read_nikon(AVFormatContext *s, uint64_t end)
         uint32_t tag  = avio_rl32(s->pb);
         uint32_t size = avio_rl32(s->pb);
         switch (tag) {
-        case MKTAG('n', 'c', 't', 'g'): {  /* Nikon Tags */
+        case MKTAG('n', 'c', 't', 'g'):  /* Nikon Tags */
+        {
             uint64_t tag_end = avio_tell(s->pb) + size;
             while (avio_tell(s->pb) < tag_end) {
-                uint16_t tag  = avio_rl16(s->pb);
-                uint16_t size = avio_rl16(s->pb);
+                uint16_t tag     = avio_rl16(s->pb);
+                uint16_t size    = avio_rl16(s->pb);
                 const char *name = NULL;
-                char buffer[64] = {0};
+                char buffer[64]  = { 0 };
                 size -= avio_read(s->pb, buffer,
-                                   FFMIN(size, sizeof(buffer)-1));
+                                  FFMIN(size, sizeof(buffer) - 1));
                 switch (tag) {
-                case 0x03:  name = "maker";  break;
-                case 0x04:  name = "model";  break;
-                case 0x13:  name = "creation_time";
+                case 0x03:
+                    name = "maker";
+                    break;
+                case 0x04:
+                    name = "model";
+                    break;
+                case 0x13:
+                    name = "creation_time";
                     if (buffer[4] == ':' && buffer[7] == ':')
                         buffer[4] = buffer[7] = '-';
                     break;
@@ -334,34 +361,35 @@ static int avi_read_header(AVFormatContext *s)
     unsigned int size;
     int i;
     AVStream *st;
-    AVIStream *ast = NULL;
-    int avih_width=0, avih_height=0;
-    int amv_file_format=0;
-    uint64_t list_end = 0;
+    AVIStream *ast      = NULL;
+    int avih_width      = 0, avih_height = 0;
+    int amv_file_format = 0;
+    uint64_t list_end   = 0;
     int ret;
 
-    avi->stream_index= -1;
+    avi->stream_index = -1;
 
-    if (get_riff(s, pb) < 0)
-        return -1;
+    ret = get_riff(s, pb);
+    if (ret < 0)
+        return ret;
 
     avi->fsize = avio_size(pb);
-    if(avi->fsize<=0)
-        avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
+    if (avi->fsize <= 0)
+        avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
 
     /* first list tag */
     stream_index = -1;
-    codec_type = -1;
+    codec_type   = -1;
     frame_period = 0;
-    for(;;) {
+    for (;;) {
         if (pb->eof_reached)
             goto fail;
-        tag = avio_rl32(pb);
+        tag  = avio_rl32(pb);
         size = avio_rl32(pb);
 
         print_tag("tag", tag, size);
 
-        switch(tag) {
+        switch (tag) {
         case MKTAG('L', 'I', 'S', 'T'):
             list_end = avio_tell(pb) + size;
             /* Ignored, except at start of video packets. */
@@ -371,21 +399,23 @@ static int avi_read_header(AVFormatContext *s)
 
             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);
+                if (size)
+                    avi->movi_end = avi->movi_list + size + (size & 1);
+                else
+                    avi->movi_end = avio_size(pb);
                 av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
                 goto end_of_header;
-            }
-            else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
+            } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
                 ff_read_riff_info(s, size - 4);
             else if (tag1 == MKTAG('n', 'c', 'd', 't'))
                 avi_read_nikon(s, list_end);
 
             break;
-        case MKTAG('I', 'D', 'I', 'T'): {
-            unsigned char date[64] = {0};
+        case MKTAG('I', 'D', 'I', 'T'):
+        {
+            unsigned char date[64] = { 0 };
             size += (size & 1);
-            size -= avio_read(pb, date, FFMIN(size, sizeof(date)-1));
+            size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1));
             avio_skip(pb, size);
             avi_metadata_creation_time(&s->metadata, date);
             break;
@@ -395,7 +425,7 @@ static int avi_read_header(AVFormatContext *s)
             avio_skip(pb, size + (size & 1));
             break;
         case MKTAG('a', 'm', 'v', 'h'):
-            amv_file_format=1;
+            amv_file_format = 1;
         case MKTAG('a', 'v', 'i', 'h'):
             /* AVI header */
             /* using frame_period is bad idea */
@@ -407,116 +437,120 @@ static int avi_read_header(AVFormatContext *s)
             avio_skip(pb, 2 * 4);
             avio_rl32(pb);
             avio_rl32(pb);
-            avih_width=avio_rl32(pb);
-            avih_height=avio_rl32(pb);
+            avih_width  = avio_rl32(pb);
+            avih_height = avio_rl32(pb);
 
             avio_skip(pb, size - 10 * 4);
             break;
         case MKTAG('s', 't', 'r', 'h'):
             /* stream header */
 
-            tag1 = avio_rl32(pb);
+            tag1    = avio_rl32(pb);
             handler = avio_rl32(pb); /* codec tag */
 
-            if(tag1 == MKTAG('p', 'a', 'd', 's')){
+            if (tag1 == MKTAG('p', 'a', 'd', 's')) {
                 avio_skip(pb, size - 8);
                 break;
-            }else{
+            } else {
                 stream_index++;
                 st = avformat_new_stream(s, NULL);
                 if (!st)
                     goto fail;
 
                 st->id = stream_index;
-                ast = av_mallocz(sizeof(AVIStream));
+                ast    = av_mallocz(sizeof(AVIStream));
                 if (!ast)
                     goto fail;
                 st->priv_data = ast;
             }
-            if(amv_file_format)
-                tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s');
+            if (amv_file_format)
+                tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')
+                                    : MKTAG('v', 'i', 'd', 's');
 
             print_tag("strh", tag1, -1);
 
-            if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){
+            if (tag1 == MKTAG('i', 'a', 'v', 's') ||
+                tag1 == MKTAG('i', 'v', 'a', 's')) {
                 int64_t dv_dur;
 
-                /*
-                 * After some consideration -- I don't think we
-                 * have to support anything but DV in type1 AVIs.
-                 */
+                /* After some consideration -- I don't think we
+                 * have to support anything but DV in type1 AVIs. */
                 if (s->nb_streams != 1)
                     goto fail;
 
                 if (handler != MKTAG('d', 'v', 's', 'd') &&
                     handler != MKTAG('d', 'v', 'h', 'd') &&
                     handler != MKTAG('d', 'v', 's', 'l'))
-                   goto fail;
+                    goto fail;
 
                 ast = s->streams[0]->priv_data;
                 av_freep(&s->streams[0]->codec->extradata);
                 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) {
                     avi->dv_demux = avpriv_dv_init_demux(s);
                     if (!avi->dv_demux)
                         goto fail;
-                }
+                } else
+                    goto fail;
                 s->streams[0]->priv_data = ast;
                 avio_skip(pb, 3 * 4);
                 ast->scale = avio_rl32(pb);
-                ast->rate = avio_rl32(pb);
+                ast->rate  = avio_rl32(pb);
                 avio_skip(pb, 4);  /* start time */
 
                 dv_dur = avio_rl32(pb);
                 if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
-                    dv_dur *= AV_TIME_BASE;
+                    dv_dur     *= AV_TIME_BASE;
                     s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
                 }
-                /*
-                 * else, leave duration alone; timing estimation in utils.c
-                 *      will make a guess based on bitrate.
-                 */
+                /* else, leave duration alone; timing estimation in utils.c
+                 * will make a guess based on bitrate. */
 
                 stream_index = s->nb_streams - 1;
-                avio_skip(pb, size - 9*4);
+                avio_skip(pb, size - 9 * 4);
                 break;
             }
 
             assert(stream_index < s->nb_streams);
-            st->codec->stream_codec_tag= handler;
+            st->codec->stream_codec_tag = handler;
 
             avio_rl32(pb); /* flags */
             avio_rl16(pb); /* priority */
             avio_rl16(pb); /* language */
             avio_rl32(pb); /* initial frame */
             ast->scale = avio_rl32(pb);
-            ast->rate = avio_rl32(pb);
-            if(!(ast->scale && ast->rate)){
-                av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate);
-                if(frame_period){
-                    ast->rate = 1000000;
+            ast->rate  = avio_rl32(pb);
+            if (!(ast->scale && ast->rate)) {
+                av_log(s, AV_LOG_WARNING,
+                       "scale/rate is %u/%u which is invalid. "
+                       "(This file has been generated by broken software.)\n",
+                       ast->scale,
+                       ast->rate);
+                if (frame_period) {
+                    ast->rate  = 1000000;
                     ast->scale = frame_period;
-                }else{
-                    ast->rate = 25;
+                } else {
+                    ast->rate  = 25;
                     ast->scale = 1;
                 }
             }
             avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
 
-            ast->cum_len=avio_rl32(pb); /* start */
+            ast->cum_len  = avio_rl32(pb); /* start */
             st->nb_frames = avio_rl32(pb);
 
             st->start_time = 0;
             avio_rl32(pb); /* buffer size */
             avio_rl32(pb); /* quality */
             ast->sample_size = avio_rl32(pb); /* sample ssize */
-            ast->cum_len *= FFMAX(1, ast->sample_size);
+            ast->cum_len    *= FFMAX(1, ast->sample_size);
             av_dlog(s, "%"PRIu32" %"PRIu32" %d\n",
                     ast->rate, ast->scale, ast->sample_size);
 
-            switch(tag1) {
+            switch (tag1) {
             case MKTAG('v', 'i', 'd', 's'):
                 codec_type = AVMEDIA_TYPE_VIDEO;
 
@@ -535,9 +569,9 @@ static int avi_read_header(AVFormatContext *s)
                 av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1);
                 goto fail;
             }
-            if(ast->sample_size == 0)
+            if (ast->sample_size == 0)
                 st->duration = st->nb_frames;
-            ast->frame_offset= ast->cum_len;
+            ast->frame_offset = ast->cum_len;
             avio_skip(pb, size - 12 * 4);
             break;
         case MKTAG('s', 't', 'r', 'f'):
@@ -549,50 +583,58 @@ static int avi_read_header(AVFormatContext *s)
                 if (cur_pos < list_end)
                     size = FFMIN(size, list_end - cur_pos);
                 st = s->streams[stream_index];
-                switch(codec_type) {
+                switch (codec_type) {
                 case AVMEDIA_TYPE_VIDEO:
-                    if(amv_file_format){
-                        st->codec->width=avih_width;
-                        st->codec->height=avih_height;
+                    if (amv_file_format) {
+                        st->codec->width      = avih_width;
+                        st->codec->height     = avih_height;
                         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-                        st->codec->codec_id = AV_CODEC_ID_AMV;
+                        st->codec->codec_id   = AV_CODEC_ID_AMV;
                         avio_skip(pb, size);
                         break;
                     }
                     tag1 = ff_get_bmp_header(pb, st);
 
-                    if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) {
+                    if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
+                        tag1 == MKTAG('D', 'X', 'S', 'A')) {
                         st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
-                        st->codec->codec_tag = tag1;
-                        st->codec->codec_id = AV_CODEC_ID_XSUB;
+                        st->codec->codec_tag  = tag1;
+                        st->codec->codec_id   = AV_CODEC_ID_XSUB;
                         break;
                     }
 
-                    if(size > 10*4 && size<(1<<30)){
-                        st->codec->extradata_size= size - 10*4;
-                        st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+                    if (size > 10 * 4 && size < (1 << 30)) {
+                        st->codec->extradata_size = size - 10 * 4;
+                        st->codec->extradata      = av_malloc(st->codec->extradata_size +
+                                                              FF_INPUT_BUFFER_PADDING_SIZE);
                         if (!st->codec->extradata) {
-                            st->codec->extradata_size= 0;
+                            st->codec->extradata_size = 0;
                             return AVERROR(ENOMEM);
                         }
-                        avio_read(pb, st->codec->extradata, st->codec->extradata_size);
+                        avio_read(pb,
+                                  st->codec->extradata,
+                                  st->codec->extradata_size);
                     }
 
-                    if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
+                    // FIXME: check if the encoder really did this correctly
+                    if (st->codec->extradata_size & 1)
                         avio_r8(pb);
 
-                    /* Extract palette from extradata if bpp <= 8. */
-                    /* This code assumes that extradata contains only palette. */
-                    /* This is true for all paletted codecs implemented in Libav. */
-                    if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
+                    /* Extract palette from extradata if bpp <= 8.
+                     * This code assumes that extradata contains only palette.
+                     * This is true for all paletted codecs implemented in
+                     * Libav. */
+                    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;
+                        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]);
+                        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
@@ -602,22 +644,31 @@ static int avi_read_header(AVFormatContext *s)
                     print_tag("video", tag1, 0);
 
                     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-                    st->codec->codec_tag = tag1;
-                    st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
-                    st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
+                    st->codec->codec_tag  = tag1;
+                    st->codec->codec_id   = ff_codec_get_id(ff_codec_bmp_tags,
+                                                            tag1);
+                    /* This is needed to get the pict type which is necessary
+                     * for generating correct pts. */
+                    st->need_parsing = AVSTREAM_PARSE_HEADERS;
                     // 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))
+                    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);
-                        if(st->codec->extradata)
-                            memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
+                    if (st->codec->codec_tag == 0 && st->codec->height > 0 &&
+                        st->codec->extradata_size < 1U << 30) {
+                        st->codec->extradata_size += 9;
+                        if ((ret = av_reallocp(&st->codec->extradata,
+                                               st->codec->extradata_size +
+                                               FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+                            st->codec->extradata_size = 0;
+                            return ret;
+                        } else
+                            memcpy(st->codec->extradata + st->codec->extradata_size - 9,
+                                   "BottomUp", 9);
                     }
-                    st->codec->height= FFABS(st->codec->height);
+                    st->codec->height = FFABS(st->codec->height);
 
 //                    avio_skip(pb, size - 5 * 4);
                     break;
@@ -625,12 +676,19 @@ static int avi_read_header(AVFormatContext *s)
                     ret = ff_get_wav_header(pb, st->codec, size);
                     if (ret < 0)
                         return ret;
-                    ast->dshow_block_align= st->codec->block_align;
-                    if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){
-                        av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align);
-                        ast->sample_size= st->codec->block_align;
+                    ast->dshow_block_align = st->codec->block_align;
+                    if (ast->sample_size && st->codec->block_align &&
+                        ast->sample_size != st->codec->block_align) {
+                        av_log(s,
+                               AV_LOG_WARNING,
+                               "sample size (%d) != block align (%d)\n",
+                               ast->sample_size,
+                               st->codec->block_align);
+                        ast->sample_size = st->codec->block_align;
                     }
-                    if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
+                    /* 2-aligned
+                     * (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
+                    if (size & 1)
                         avio_skip(pb, 1);
                     /* Force parsing as several audio frames can be in
                      * one packet and timestamps refer to packet start. */
@@ -638,16 +696,17 @@ static int avi_read_header(AVFormatContext *s)
                     /* ADTS header is in extradata, AAC without header must be
                      * stored as exact frames. Parser not needed and it will
                      * fail. */
-                    if (st->codec->codec_id == AV_CODEC_ID_AAC && st->codec->extradata_size)
+                    if (st->codec->codec_id == AV_CODEC_ID_AAC &&
+                        st->codec->extradata_size)
                         st->need_parsing = AVSTREAM_PARSE_NONE;
                     /* AVI files with Xan DPCM audio (wrongly) declare PCM
                      * audio in the header but have Axan as stream_code_tag. */
-                    if (st->codec->stream_codec_tag == AV_RL32("Axan")){
+                    if (st->codec->stream_codec_tag == AV_RL32("Axan")) {
                         st->codec->codec_id  = AV_CODEC_ID_XAN_DPCM;
                         st->codec->codec_tag = 0;
                     }
-                    if (amv_file_format){
-                        st->codec->codec_id  = AV_CODEC_ID_ADPCM_IMA_AMV;
+                    if (amv_file_format) {
+                        st->codec->codec_id    = AV_CODEC_ID_ADPCM_IMA_AMV;
                         ast->dshow_block_align = 0;
                     }
                     break;
@@ -657,23 +716,23 @@ static int avi_read_header(AVFormatContext *s)
                     break;
                 default:
                     st->codec->codec_type = AVMEDIA_TYPE_DATA;
-                    st->codec->codec_id= AV_CODEC_ID_NONE;
-                    st->codec->codec_tag= 0;
+                    st->codec->codec_id   = AV_CODEC_ID_NONE;
+                    st->codec->codec_tag  = 0;
                     avio_skip(pb, size);
                     break;
                 }
             }
             break;
         case MKTAG('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))
+            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))
                 goto fail;
-            avio_seek(pb, i+size, SEEK_SET);
+            avio_seek(pb, i + size, SEEK_SET);
             break;
         case MKTAG('v', 'p', 'r', 'p'):
-            if(stream_index < (unsigned)s->nb_streams && size > 9*4){
+            if (stream_index < (unsigned)s->nb_streams && size > 9 * 4) {
                 AVRational active, active_aspect;
 
                 st = s->streams[stream_index];
@@ -683,31 +742,35 @@ static int avi_read_header(AVFormatContext *s)
                 avio_rl32(pb);
                 avio_rl32(pb);
 
-                active_aspect.den= avio_rl16(pb);
-                active_aspect.num= avio_rl16(pb);
-                active.num       = avio_rl32(pb);
-                active.den       = avio_rl32(pb);
-                avio_rl32(pb); //nbFieldsPerFrame
+                active_aspect.den = avio_rl16(pb);
+                active_aspect.num = avio_rl16(pb);
+                active.num        = avio_rl32(pb);
+                active.den        = avio_rl32(pb);
+                avio_rl32(pb); // nbFieldsPerFrame
 
-                if(active_aspect.num && active_aspect.den && active.num && active.den){
-                    st->sample_aspect_ratio= av_div_q(active_aspect, active);
+                if (active_aspect.num && active_aspect.den &&
+                    active.num && active.den) {
+                    st->sample_aspect_ratio = av_div_q(active_aspect, active);
                     av_dlog(s, "vprp %d/%d %d/%d\n",
                             active_aspect.num, active_aspect.den,
                             active.num, active.den);
                 }
-                size -= 9*4;
+                size -= 9 * 4;
             }
             avio_skip(pb, size);
             break;
         case MKTAG('s', 't', 'r', 'n'):
-            if(s->nb_streams){
-                avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
+            if (s->nb_streams) {
+                ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
+                if (ret < 0)
+                    return ret;
                 break;
             }
         default:
-            if(size > 1000000){
-                av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
-                                        "I will ignore it and try to continue anyway.\n");
+            if (size > 1000000) {
+                av_log(s, AV_LOG_ERROR,
+                       "Something went wrong during header parsing, "
+                       "I will ignore it and try to continue anyway.\n");
                 if (s->error_recognition & AV_EF_EXPLODE)
                     goto fail;
                 avi->movi_list = avio_tell(pb) - 4;
@@ -720,28 +783,31 @@ static int avi_read_header(AVFormatContext *s)
             break;
         }
     }
- end_of_header:
+
+end_of_header:
     /* check stream number */
     if (stream_index != s->nb_streams - 1) {
-    fail:
-        return -1;
+
+fail:
+        return AVERROR_INVALIDDATA;
     }
 
-    if(!avi->index_loaded && pb->seekable)
+    if (!avi->index_loaded && pb->seekable)
         avi_load_index(s);
-    avi->index_loaded = 1;
+    avi->index_loaded     = 1;
     avi->non_interleaved |= guess_ni_flag(s);
-    for(i=0; i<s->nb_streams; i++){
+    for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
-        if(st->nb_index_entries)
+        if (st->nb_index_entries)
             break;
     }
-    if(i==s->nb_streams && avi->non_interleaved) {
-        av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n");
-        avi->non_interleaved=0;
+    if (i == s->nb_streams && avi->non_interleaved) {
+        av_log(s, AV_LOG_WARNING,
+               "Non-interleaved AVI without index, switching to interleaved\n");
+        avi->non_interleaved = 0;
     }
 
-    if(avi->non_interleaved) {
+    if (avi->non_interleaved) {
         av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
         clean_index(s);
     }
@@ -757,13 +823,13 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt)
     if (pkt->size >= 7 &&
         !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
         uint8_t desc[256];
-        int score = AVPROBE_SCORE_MAX / 2, ret;
+        int score      = AVPROBE_SCORE_EXTENSION, ret;
         AVIStream *ast = st->priv_data;
         AVInputFormat *sub_demuxer;
         AVRational time_base;
-        AVIOContext *pb = avio_alloc_context( pkt->data + 7,
-                                              pkt->size - 7,
-                                              0, NULL, NULL, NULL, NULL);
+        AVIOContext *pb = avio_alloc_context(pkt->data + 7,
+                                             pkt->size - 7,
+                                             0, NULL, NULL, NULL, NULL);
         AVProbeData pd;
         unsigned int desc_len = avio_rl32(pb);
 
@@ -778,14 +844,15 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt)
         avio_rl16(pb);   /* flags? */
         avio_rl32(pb);   /* data size */
 
-        pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };
+        pd = (AVProbeData) { .buf      = pb->buf_ptr,
+                             .buf_size = pb->buf_end - pb->buf_ptr };
         if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
             goto error;
 
         if (!(ast->sub_ctx = avformat_alloc_context()))
             goto error;
 
-        ast->sub_ctx->pb      = pb;
+        ast->sub_ctx->pb = pb;
         if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
             ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
             *st->codec = *ast->sub_ctx->streams[0]->codec;
@@ -796,6 +863,7 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt)
         ast->sub_buffer = pkt->data;
         memset(pkt, 0, sizeof(*pkt));
         return 1;
+
 error:
         av_freep(&pb);
     }
@@ -813,7 +881,7 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
     next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base,
                            AV_TIME_BASE_Q);
 
-    for (i=0; i<s->nb_streams; i++) {
+    for (i = 0; i < s->nb_streams; i++) {
         st  = s->streams[i];
         ast = st->priv_data;
         if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
@@ -826,21 +894,23 @@ static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
     }
 
     if (sub_st) {
-        ast = sub_st->priv_data;
-        *pkt = ast->sub_pkt;
+        ast               = sub_st->priv_data;
+        *pkt              = ast->sub_pkt;
         pkt->stream_index = sub_st->index;
+
         if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
             ast->sub_pkt.data = NULL;
     }
     return sub_st;
 }
 
-static int get_stream_idx(int *d){
-    if(    d[0] >= '0' && d[0] <= '9'
-        && d[1] >= '0' && d[1] <= '9'){
+static int get_stream_idx(int *d)
+{
+    if (d[0] >= '0' && d[0] <= '9' &&
+        d[1] >= '0' && d[1] <= '9') {
         return (d[0] - '0') * 10 + (d[1] - '0');
-    }else{
-        return 100; //invalid stream ID
+    } else {
+        return 100; // invalid stream ID
     }
 }
 
@@ -855,77 +925,77 @@ static int avi_sync(AVFormatContext *s, int exit_early)
 
 start_sync:
     memset(d, -1, sizeof(d));
-    for(i=sync=avio_tell(pb); !pb->eof_reached; i++) {
+    for (i = sync = avio_tell(pb); !pb->eof_reached; i++) {
         int j;
 
-        for(j=0; j<7; j++)
-            d[j]= d[j+1];
-        d[7]= avio_r8(pb);
+        for (j = 0; j < 7; j++)
+            d[j] = d[j + 1];
+        d[7] = avio_r8(pb);
 
-        size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
+        size = d[4] + (d[5] << 8) + (d[6] << 16) + (d[7] << 24);
 
-        n= get_stream_idx(d+2);
+        n = get_stream_idx(d + 2);
         av_dlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
                 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
-        if(i + (uint64_t)size > avi->fsize || d[0] > 127)
+        if (i + (uint64_t)size > avi->fsize || d[0] > 127)
             continue;
 
-        //parse ix##
-        if(  (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
-        //parse JUNK
-           ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
-           ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
+        // parse ix##
+        if ((d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) ||
+            // parse JUNK
+            (d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') ||
+            (d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')) {
             avio_skip(pb, size);
             goto start_sync;
         }
 
-        //parse stray LIST
-        if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
+        // parse stray LIST
+        if (d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T') {
             avio_skip(pb, 4);
             goto start_sync;
         }
 
-        n= get_stream_idx(d);
+        n = avi->dv_demux ? 0 : get_stream_idx(d);
 
-        if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams)
+        if (!((i - avi->last_pkt_pos) & 1) &&
+            get_stream_idx(d + 1) < s->nb_streams)
             continue;
 
-        //detect ##ix chunk and skip
-        if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
+        // detect ##ix chunk and skip
+        if (d[2] == 'i' && d[3] == 'x' && n < s->nb_streams) {
             avio_skip(pb, size);
             goto start_sync;
         }
 
-        //parse ##dc/##wb
-        if(n < s->nb_streams){
+        // parse ##dc/##wb
+        if (n < s->nb_streams) {
             AVStream *st;
             AVIStream *ast;
-            st = s->streams[n];
+            st  = s->streams[n];
             ast = st->priv_data;
 
-            if(s->nb_streams>=2){
-                AVStream *st1  = s->streams[1];
-                AVIStream *ast1= st1->priv_data;
-                //workaround for broken small-file-bug402.avi
-                if(   d[2] == 'w' && d[3] == 'b'
-                   && n==0
-                   && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
-                   && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
-                   && ast->prefix == 'd'*256+'c'
-                   && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
-                  ){
-                    n=1;
-                    st = st1;
+            if (s->nb_streams >= 2) {
+                AVStream *st1   = s->streams[1];
+                AVIStream *ast1 = st1->priv_data;
+                // workaround for broken small-file-bug402.avi
+                if (d[2] == 'w' && d[3] == 'b' && n == 0 &&
+                    st->codec->codec_type  == AVMEDIA_TYPE_VIDEO &&
+                    st1->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                    ast->prefix == 'd' * 256 + 'c' &&
+                    (d[2] * 256 + d[3] == ast1->prefix ||
+                     !ast1->prefix_count)) {
+                    n   = 1;
+                    st  = st1;
                     ast = ast1;
-                    av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n");
+                    av_log(s, AV_LOG_WARNING,
+                           "Invalid stream + prefix combination, assuming audio.\n");
                 }
             }
 
-
             if (!avi->dv_demux &&
-                ((st->discard >= AVDISCARD_DEFAULT && size==0) /* ||
-                //FIXME needs a little reordering
-                (st->discard >= AVDISCARD_NONKEY &&
+                ((st->discard >= AVDISCARD_DEFAULT && size == 0) /* ||
+                 // FIXME: needs a little reordering
+                 (st->discard >= AVDISCARD_NONKEY &&
                  !(pkt->flags & AV_PKT_FLAG_KEY)) */
                 || st->discard >= AVDISCARD_ALL)) {
                 if (!exit_early) {
@@ -935,38 +1005,42 @@ start_sync:
                 goto start_sync;
             }
 
-            if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
-                int k = avio_r8(pb);
+            if (d[2] == 'p' && d[3] == 'c' && size <= 4 * 256 + 4) {
+                int k    = avio_r8(pb);
                 int last = (k + avio_r8(pb) - 1) & 0xFF;
 
-                avio_rl16(pb); //flags
+                avio_rl16(pb); // flags
 
+                // b + (g << 8) + (r << 16);
                 for (; k <= last; k++)
-                    ast->pal[k] = avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
-                ast->has_pal= 1;
-                goto start_sync;
-            } else if(   ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
-                         d[2]*256+d[3] == ast->prefix /*||
-                         (d[2] == 'd' && d[3] == 'c') ||
-                         (d[2] == 'w' && d[3] == 'b')*/) {
+                    ast->pal[k] = avio_rb32(pb) >> 8;
 
+                ast->has_pal = 1;
+                goto start_sync;
+            } else if (((ast->prefix_count < 5 || sync + 9 > i) &&
+                        d[2] < 128 && d[3] < 128) ||
+                       d[2] * 256 + d[3] == ast->prefix /* ||
+                       (d[2] == 'd' && d[3] == 'c') ||
+                       (d[2] == 'w' && d[3] == 'b') */) {
                 if (exit_early)
                     return 0;
-                if(d[2]*256+d[3] == ast->prefix)
+                if (d[2] * 256 + d[3] == ast->prefix)
                     ast->prefix_count++;
-                else{
-                    ast->prefix= d[2]*256+d[3];
-                    ast->prefix_count= 0;
+                else {
+                    ast->prefix       = d[2] * 256 + d[3];
+                    ast->prefix_count = 0;
                 }
 
-                avi->stream_index= n;
-                ast->packet_size= size + 8;
-                ast->remaining= size;
+                avi->stream_index = n;
+                ast->packet_size  = size + 8;
+                ast->remaining    = size;
 
-                if(size || !ast->sample_size){
-                    uint64_t pos= avio_tell(pb) - 8;
-                    if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
-                        av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
+                if (size || !ast->sample_size) {
+                    uint64_t pos = avio_tell(pb) - 8;
+                    if (!st->index_entries || !st->nb_index_entries ||
+                        st->index_entries[st->nb_index_entries - 1].pos < pos) {
+                        av_add_index_entry(st, pos, ast->frame_offset, size,
+                                           0, AVINDEX_KEYFRAME);
                     }
                 }
                 return 0;
@@ -982,129 +1056,163 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
     AVIContext *avi = s->priv_data;
     AVIOContext *pb = s->pb;
     int err;
-    void* dstr;
+#if FF_API_DESTRUCT_PACKET
+    void *dstr;
+#endif
 
     if (CONFIG_DV_DEMUXER && avi->dv_demux) {
         int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
         if (size >= 0)
             return size;
+        else
+            goto resync;
     }
 
-    if(avi->non_interleaved){
+    if (avi->non_interleaved) {
         int best_stream_index = 0;
-        AVStream *best_st= NULL;
+        AVStream *best_st     = NULL;
         AVIStream *best_ast;
-        int64_t best_ts= INT64_MAX;
+        int64_t best_ts = INT64_MAX;
         int i;
 
-        for(i=0; i<s->nb_streams; i++){
-            AVStream *st = s->streams[i];
+        for (i = 0; i < s->nb_streams; i++) {
+            AVStream *st   = s->streams[i];
             AVIStream *ast = st->priv_data;
-            int64_t ts= ast->frame_offset;
+            int64_t ts     = ast->frame_offset;
             int64_t last_ts;
 
-            if(!st->nb_index_entries)
+            if (!st->nb_index_entries)
                 continue;
 
             last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
-            if(!ast->remaining && ts > last_ts)
+            if (!ast->remaining && ts > last_ts)
                 continue;
 
-            ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE});
+            ts = av_rescale_q(ts, st->time_base,
+                              (AVRational) { FFMAX(1, ast->sample_size),
+                                             AV_TIME_BASE });
 
             av_dlog(s, "%"PRId64" %d/%d %"PRId64"\n", ts,
                     st->time_base.num, st->time_base.den, ast->frame_offset);
-            if(ts < best_ts){
-                best_ts= ts;
-                best_st= st;
-                best_stream_index= i;
+            if (ts < best_ts) {
+                best_ts           = ts;
+                best_st           = st;
+                best_stream_index = i;
             }
         }
-        if(!best_st)
-            return -1;
+        if (!best_st)
+            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);
-        if(best_ast->remaining)
-            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
-        else{
-            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
-            if(i>=0)
-                best_ast->frame_offset= best_st->index_entries[i].timestamp;
+        best_ts  = av_rescale_q(best_ts,
+                                (AVRational) { FFMAX(1, best_ast->sample_size),
+                                               AV_TIME_BASE },
+                                best_st->time_base);
+        if (best_ast->remaining) {
+            i = av_index_search_timestamp(best_st,
+                                          best_ts,
+                                          AVSEEK_FLAG_ANY |
+                                          AVSEEK_FLAG_BACKWARD);
+        } else {
+            i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
+            if (i >= 0)
+                best_ast->frame_offset = best_st->index_entries[i].timestamp;
         }
 
-        if(i>=0){
-            int64_t pos= best_st->index_entries[i].pos;
+        if (i >= 0) {
+            int64_t pos = best_st->index_entries[i].pos;
             pos += best_ast->packet_size - best_ast->remaining;
             avio_seek(s->pb, pos + 8, SEEK_SET);
 
             assert(best_ast->remaining <= best_ast->packet_size);
 
-            avi->stream_index= best_stream_index;
-            if(!best_ast->remaining)
-                best_ast->packet_size=
-                best_ast->remaining= best_st->index_entries[i].size;
+            avi->stream_index = best_stream_index;
+            if (!best_ast->remaining)
+                best_ast->packet_size =
+                best_ast->remaining   = best_st->index_entries[i].size;
         }
     }
 
 resync:
-    if(avi->stream_index >= 0){
-        AVStream *st= s->streams[ avi->stream_index ];
-        AVIStream *ast= st->priv_data;
+    if (avi->stream_index >= 0) {
+        AVStream *st   = s->streams[avi->stream_index];
+        AVIStream *ast = st->priv_data;
         int size, err;
 
-        if(get_subtitle_pkt(s, st, pkt))
+        if (get_subtitle_pkt(s, st, pkt))
             return 0;
 
-        if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
-            size= INT_MAX;
-        else if(ast->sample_size < 32)
+        // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
+        if (ast->sample_size <= 1)
+            size = INT_MAX;
+        else if (ast->sample_size < 32)
             // arbitrary multiplier to avoid tiny packets for raw PCM data
-            size= 1024*ast->sample_size;
+            size = 1024 * ast->sample_size;
         else
-            size= ast->sample_size;
+            size = ast->sample_size;
 
-        if(size > ast->remaining)
-            size= ast->remaining;
-        avi->last_pkt_pos= avio_tell(pb);
-        err= av_get_packet(pb, pkt, size);
-        if(err<0)
+        if (size > ast->remaining)
+            size = ast->remaining;
+        avi->last_pkt_pos = avio_tell(pb);
+        err               = av_get_packet(pb, pkt, size);
+        if (err < 0)
             return err;
 
-        if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){
+        if (ast->has_pal && pkt->data && pkt->size < (unsigned)INT_MAX / 2) {
             uint8_t *pal;
-            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
-            if(!pal){
-                av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n");
-            }else{
+            pal = av_packet_new_side_data(pkt,
+                                          AV_PKT_DATA_PALETTE,
+                                          AVPALETTE_SIZE);
+            if (!pal) {
+                av_log(s, AV_LOG_ERROR,
+                       "Failed to allocate data for palette\n");
+            } else {
                 memcpy(pal, ast->pal, AVPALETTE_SIZE);
                 ast->has_pal = 0;
             }
         }
 
         if (CONFIG_DV_DEMUXER && avi->dv_demux) {
+            AVBufferRef *avbuf = pkt->buf;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
             dstr = pkt->destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
             size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
-                                    pkt->data, pkt->size);
+                                            pkt->data, pkt->size);
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
             pkt->destruct = dstr;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+            pkt->buf    = avbuf;
             pkt->flags |= AV_PKT_FLAG_KEY;
             if (size < 0)
                 av_free_packet(pkt);
-        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
-                   && !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
+                   !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
             ast->frame_offset++;
             avi->stream_index = -1;
-            ast->remaining = 0;
+            ast->remaining    = 0;
             goto resync;
         } else {
             /* XXX: How to handle B-frames in AVI? */
             pkt->dts = ast->frame_offset;
 //                pkt->dts += ast->start;
-            if(ast->sample_size)
+            if (ast->sample_size)
                 pkt->dts /= ast->sample_size;
-            av_dlog(s, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n",
-                    pkt->dts, ast->frame_offset, ast->scale, ast->rate,
-                    ast->sample_size, AV_TIME_BASE, avi->stream_index, size);
+            av_dlog(s,
+                    "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d "
+                    "base:%d st:%d size:%d\n",
+                    pkt->dts,
+                    ast->frame_offset,
+                    ast->scale,
+                    ast->rate,
+                    ast->sample_size,
+                    AV_TIME_BASE,
+                    avi->stream_index,
+                    size);
             pkt->stream_index = avi->stream_index;
 
             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -1112,22 +1220,21 @@ resync:
                 int index;
                 assert(st->index_entries);
 
-                index= av_index_search_timestamp(st, ast->frame_offset, 0);
-                e= &st->index_entries[index];
+                index = av_index_search_timestamp(st, ast->frame_offset, 0);
+                e     = &st->index_entries[index];
 
-                if(index >= 0 && e->timestamp == ast->frame_offset){
+                if (index >= 0 && e->timestamp == ast->frame_offset)
                     if (e->flags & AVINDEX_KEYFRAME)
                         pkt->flags |= AV_PKT_FLAG_KEY;
-                }
             } else {
                 pkt->flags |= AV_PKT_FLAG_KEY;
             }
             ast->frame_offset += get_duration(ast, pkt->size);
         }
         ast->remaining -= err;
-        if(!ast->remaining){
-            avi->stream_index= -1;
-            ast->packet_size= 0;
+        if (!ast->remaining) {
+            avi->stream_index = -1;
+            ast->packet_size  = 0;
         }
 
         return 0;
@@ -1139,7 +1246,7 @@ resync:
 }
 
 /* XXX: We make the implicit supposition that the positions are sorted
-   for each stream. */
+ * for each stream. */
 static int avi_read_idx1(AVFormatContext *s, int size)
 {
     AVIContext *avi = s->priv_data;
@@ -1148,84 +1255,85 @@ static int avi_read_idx1(AVFormatContext *s, int size)
     AVStream *st;
     AVIStream *ast;
     unsigned int index, tag, flags, pos, len, first_packet = 1;
-    unsigned last_pos= -1;
+    unsigned last_pos = -1;
     int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
 
     nb_index_entries = size / 16;
     if (nb_index_entries <= 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     idx1_pos = avio_tell(pb);
-    avio_seek(pb, avi->movi_list+4, SEEK_SET);
-    if (avi_sync(s, 1) == 0) {
+    avio_seek(pb, avi->movi_list + 4, SEEK_SET);
+    if (avi_sync(s, 1) == 0)
         first_packet_pos = avio_tell(pb) - 8;
-    }
     avi->stream_index = -1;
     avio_seek(pb, idx1_pos, SEEK_SET);
 
     /* Read the entries and sort them in each stream component. */
-    for(i = 0; i < nb_index_entries; i++) {
-        tag = avio_rl32(pb);
+    for (i = 0; i < nb_index_entries; i++) {
+        tag   = avio_rl32(pb);
         flags = avio_rl32(pb);
-        pos = avio_rl32(pb);
-        len = avio_rl32(pb);
+        pos   = avio_rl32(pb);
+        len   = avio_rl32(pb);
         av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
                 i, tag, flags, pos, len);
 
-        index = ((tag & 0xff) - '0') * 10;
-        index += ((tag >> 8) & 0xff) - '0';
+        index  = ((tag      & 0xff) - '0') * 10;
+        index +=  (tag >> 8 & 0xff) - '0';
         if (index >= s->nb_streams)
             continue;
-        st = s->streams[index];
+        st  = s->streams[index];
         ast = st->priv_data;
 
-        if(first_packet && first_packet_pos && len) {
-            data_offset = first_packet_pos - pos;
+        if (first_packet && first_packet_pos && len) {
+            data_offset  = first_packet_pos - pos;
             first_packet = 0;
         }
         pos += data_offset;
 
         av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
 
-        if(pb->eof_reached)
-            return -1;
+        if (pb->eof_reached)
+            return AVERROR_INVALIDDATA;
 
-        if(last_pos == pos)
-            avi->non_interleaved= 1;
-        else if(len || !ast->sample_size)
-            av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
+        if (last_pos == pos)
+            avi->non_interleaved = 1;
+        else if (len || !ast->sample_size)
+            av_add_index_entry(st, pos, ast->cum_len, len, 0,
+                               (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
         ast->cum_len += get_duration(ast, len);
-        last_pos= pos;
+        last_pos      = pos;
     }
     return 0;
 }
 
-static int guess_ni_flag(AVFormatContext *s){
+static int guess_ni_flag(AVFormatContext *s)
+{
     int i;
-    int64_t last_start=0;
-    int64_t first_end= INT64_MAX;
-    int64_t oldpos= avio_tell(s->pb);
+    int64_t last_start = 0;
+    int64_t first_end  = INT64_MAX;
+    int64_t oldpos     = avio_tell(s->pb);
 
-    for(i=0; i<s->nb_streams; i++){
+    for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
-        int n= st->nb_index_entries;
+        int n        = st->nb_index_entries;
         unsigned int size;
 
-        if(n <= 0)
+        if (n <= 0)
             continue;
 
-        if(n >= 2){
-            int64_t pos= st->index_entries[0].pos;
+        if (n >= 2) {
+            int64_t pos = st->index_entries[0].pos;
             avio_seek(s->pb, pos + 4, SEEK_SET);
-            size= avio_rl32(s->pb);
-            if(pos + size > st->index_entries[1].pos)
-                last_start= INT64_MAX;
+            size = avio_rl32(s->pb);
+            if (pos + size > st->index_entries[1].pos)
+                last_start = INT64_MAX;
         }
 
-        if(st->index_entries[0].pos > last_start)
-            last_start= st->index_entries[0].pos;
-        if(st->index_entries[n-1].pos < first_end)
-            first_end= st->index_entries[n-1].pos;
+        if (st->index_entries[0].pos > last_start)
+            last_start = st->index_entries[0].pos;
+        if (st->index_entries[n - 1].pos < first_end)
+            first_end = st->index_entries[n - 1].pos;
     }
     avio_seek(s->pb, oldpos, SEEK_SET);
     return last_start > first_end;
@@ -1236,16 +1344,16 @@ static int avi_load_index(AVFormatContext *s)
     AVIContext *avi = s->priv_data;
     AVIOContext *pb = s->pb;
     uint32_t tag, size;
-    int64_t pos= avio_tell(pb);
-    int ret = -1;
+    int64_t pos = avio_tell(pb);
+    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(;;) {
+    for (;;) {
         if (pb->eof_reached)
             break;
-        tag = avio_rl32(pb);
+        tag  = avio_rl32(pb);
         size = avio_rl32(pb);
         av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
                  tag        & 0xff,
@@ -1264,7 +1372,8 @@ static int avi_load_index(AVFormatContext *s)
         if (avio_skip(pb, size) < 0)
             break; // something is wrong here
     }
- the_end:
+
+the_end:
     avio_seek(pb, pos, SEEK_SET);
     return ret;
 }
@@ -1272,14 +1381,15 @@ static int avi_load_index(AVFormatContext *s)
 static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
 {
     AVIStream *ast2 = st2->priv_data;
-    int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base);
+    int64_t ts2     = av_rescale_q(timestamp, st->time_base, st2->time_base);
     av_free_packet(&ast2->sub_pkt);
     if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 ||
         avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0)
         ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
 }
 
-static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+static int avi_read_seek(AVFormatContext *s, int stream_index,
+                         int64_t timestamp, int flags)
 {
     AVIContext *avi = s->priv_data;
     AVStream *st;
@@ -1287,21 +1397,28 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
     int64_t pos;
     AVIStream *ast;
 
+    /* Does not matter which stream is requested dv in avi has the
+     * stream information in the first video stream.
+     */
+    if (avi->dv_demux)
+        stream_index = 0;
+
     if (!avi->index_loaded) {
         /* we only load the index on demand */
         avi_load_index(s);
         avi->index_loaded = 1;
     }
-    assert(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)
-        return -1;
+    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)
+        return AVERROR_INVALIDDATA;
 
     /* find the position */
-    pos = st->index_entries[index].pos;
+    pos       = st->index_entries[index].pos;
     timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
 
     av_dlog(s, "XX %"PRId64" %d %"PRId64"\n",
@@ -1311,23 +1428,22 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
         /* 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);
 
         /* 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;
+        avi->stream_index = -1;
         return 0;
     }
 
-    for(i = 0; i < s->nb_streams; i++) {
-        AVStream *st2 = s->streams[i];
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st2   = s->streams[i];
         AVIStream *ast2 = st2->priv_data;
 
-        ast2->packet_size=
-        ast2->remaining= 0;
+        ast2->packet_size =
+        ast2->remaining   = 0;
 
         if (ast2->sub_ctx) {
             seek_subtitle(st, st2, timestamp);
@@ -1338,18 +1454,22 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
             continue;
 
 //        assert(st2->codec->block_align);
-        assert((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);
-        if(index<0)
-            index=0;
-
-        if(!avi->non_interleaved){
-            while(index>0 && st2->index_entries[index].pos > pos)
+        assert((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);
+        if (index < 0)
+            index = 0;
+
+        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)
+            while (index + 1 < st2->nb_index_entries &&
+                   st2->index_entries[index].pos < pos)
                 index++;
         }
 
@@ -1361,7 +1481,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp
 
     /* do the seek */
     avio_seek(s->pb, pos, SEEK_SET);
-    avi->stream_index= -1;
+    avi->stream_index = -1;
     return 0;
 }
 
@@ -1370,8 +1490,8 @@ static int avi_read_close(AVFormatContext *s)
     int i;
     AVIContext *avi = s->priv_data;
 
-    for(i=0;i<s->nb_streams;i++) {
-        AVStream *st = s->streams[i];
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st   = s->streams[i];
         AVIStream *ast = st->priv_data;
         if (ast) {
             if (ast->sub_ctx) {
@@ -1393,9 +1513,9 @@ static int avi_probe(AVProbeData *p)
     int i;
 
     /* check file header */
-    for(i=0; avi_headers[i][0]; i++)
-        if(!memcmp(p->buf  , avi_headers[i]  , 4) &&
-           !memcmp(p->buf+8, avi_headers[i]+4, 4))
+    for (i = 0; avi_headers[i][0]; i++)
+        if (!memcmp(p->buf,     avi_headers[i],     4) &&
+            !memcmp(p->buf + 8, avi_headers[i] + 4, 4))
             return AVPROBE_SCORE_MAX;
 
     return 0;
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 9d1f510..0b1d578 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -533,13 +533,16 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
     }
 
     if (s->pb->seekable) {
+        int err;
         AVIIndex* idx = &avist->indexes;
         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*));
-            if (!idx->cluster)
-                return -1;
+            if ((err = av_reallocp(&idx->cluster, (cl + 1) * sizeof(*idx->cluster))) < 0) {
+                idx->ents_allocated = 0;
+                idx->entry = 0;
+                return err;
+            }
             idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(AVIIentry));
             if (!idx->cluster[cl])
                 return -1;
@@ -558,7 +561,6 @@ static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
     if (size & 1)
         avio_w8(pb, 0);
 
-    avio_flush(pb);
     return 0;
 }
 
@@ -630,5 +632,4 @@ AVOutputFormat ff_avi_muxer = {
     .codec_tag         = (const AVCodecTag* const []){
         ff_codec_bmp_tags, ff_codec_wav_tags, 0
     },
-    .flags             = AVFMT_VARIABLE_FPS,
 };
diff --git a/libavformat/avio.c b/libavformat/avio.c
index ad39e6f..fe42974 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -42,8 +42,10 @@ URLProtocol *ffurl_protocol_next(URLProtocol *prev)
 static const char *urlcontext_to_name(void *ptr)
 {
     URLContext *h = (URLContext *)ptr;
-    if(h->prot) return h->prot->name;
-    else        return "NULL";
+    if (h->prot)
+        return h->prot->name;
+    else
+        return "NULL";
 }
 
 static void *urlcontext_child_next(void *obj, void *prev)
@@ -68,49 +70,44 @@ static const AVClass *urlcontext_child_class_next(const AVClass *prev)
         if (p->priv_data_class)
             return p->priv_data_class;
     return NULL;
-
 }
 
-static const AVOption options[] = {{NULL}};
+static const AVOption options[] = { { NULL } };
 const AVClass ffurl_context_class = {
-    .class_name     = "URLContext",
-    .item_name      = urlcontext_to_name,
-    .option         = options,
-    .version        = LIBAVUTIL_VERSION_INT,
-    .child_next     = urlcontext_child_next,
+    .class_name       = "URLContext",
+    .item_name        = urlcontext_to_name,
+    .option           = options,
+    .version          = LIBAVUTIL_VERSION_INT,
+    .child_next       = urlcontext_child_next,
     .child_class_next = urlcontext_child_class_next,
 };
 /*@}*/
 
-
 const char *avio_enum_protocols(void **opaque, int output)
 {
     URLProtocol *p;
     *opaque = ffurl_protocol_next(*opaque);
-    if (!(p = *opaque)) return NULL;
+    if (!(p = *opaque))
+        return NULL;
     if ((output && p->url_write) || (!output && p->url_read))
         return p->name;
     return avio_enum_protocols(opaque, output);
 }
 
-int ffurl_register_protocol(URLProtocol *protocol, int size)
+int ffurl_register_protocol(URLProtocol *protocol)
 {
     URLProtocol **p;
-    if (size < sizeof(URLProtocol)) {
-        URLProtocol* temp = av_mallocz(sizeof(URLProtocol));
-        memcpy(temp, protocol, size);
-        protocol = temp;
-    }
     p = &first_protocol;
-    while (*p != NULL) p = &(*p)->next;
-    *p = protocol;
+    while (*p != NULL)
+        p = &(*p)->next;
+    *p             = protocol;
     protocol->next = NULL;
     return 0;
 }
 
-static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
-                                   const char *filename, int flags,
-                                   const AVIOInterruptCB *int_cb)
+static int url_alloc_for_protocol(URLContext **puc, struct URLProtocol *up,
+                                  const char *filename, int flags,
+                                  const AVIOInterruptCB *int_cb)
 {
     URLContext *uc;
     int err;
@@ -125,16 +122,20 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
         goto fail;
     }
     uc->av_class = &ffurl_context_class;
-    uc->filename = (char *) &uc[1];
+    uc->filename = (char *)&uc[1];
     strcpy(uc->filename, filename);
-    uc->prot = up;
-    uc->flags = flags;
-    uc->is_streamed = 0; /* default = not streamed */
+    uc->prot            = up;
+    uc->flags           = flags;
+    uc->is_streamed     = 0; /* default = not streamed */
     uc->max_packet_size = 0; /* default: stream file */
     if (up->priv_data_size) {
         uc->priv_data = av_mallocz(up->priv_data_size);
+        if (!uc->priv_data) {
+            err = AVERROR(ENOMEM);
+            goto fail;
+        }
         if (up->priv_data_class) {
-            *(const AVClass**)uc->priv_data = up->priv_data_class;
+            *(const AVClass **)uc->priv_data = up->priv_data_class;
             av_opt_set_defaults(uc->priv_data);
         }
     }
@@ -143,8 +144,11 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
 
     *puc = uc;
     return 0;
- fail:
+fail:
     *puc = NULL;
+    if (uc)
+        av_freep(&uc->priv_data);
+    av_freep(&uc);
 #if CONFIG_NETWORK
     if (up->flags & URL_PROTOCOL_FLAG_NETWORK)
         ff_network_close();
@@ -152,19 +156,22 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
     return err;
 }
 
-int ffurl_connect(URLContext* uc, AVDictionary **options)
+int ffurl_connect(URLContext *uc, AVDictionary **options)
 {
     int err =
-        uc->prot->url_open2 ? uc->prot->url_open2(uc, uc->filename, uc->flags, options) :
+        uc->prot->url_open2 ? uc->prot->url_open2(uc,
+                                                  uc->filename,
+                                                  uc->flags,
+                                                  options) :
         uc->prot->url_open(uc, uc->filename, uc->flags);
     if (err)
         return err;
     uc->is_connected = 1;
-    //We must be careful here as ffurl_seek() could be slow, for example for http
-    if(   (uc->flags & AVIO_FLAG_WRITE)
-       || !strcmp(uc->prot->name, "file"))
-        if(!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
-            uc->is_streamed= 1;
+    /* We must be careful here as ffurl_seek() could be slow,
+     * for example for http */
+    if ((uc->flags & AVIO_FLAG_WRITE) || !strcmp(uc->prot->name, "file"))
+        if (!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
+            uc->is_streamed = 1;
     return 0;
 }
 
@@ -183,7 +190,8 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags,
     if (filename[proto_len] != ':' || is_dos_path(filename))
         strcpy(proto_str, "file");
     else
-        av_strlcpy(proto_str, filename, FFMIN(proto_len+1, sizeof(proto_str)));
+        av_strlcpy(proto_str, filename,
+                   FFMIN(proto_len + 1, sizeof(proto_str)));
 
     av_strlcpy(proto_nested, proto_str, sizeof(proto_nested));
     if ((ptr = strchr(proto_nested, '+')))
@@ -191,13 +199,13 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags,
 
     while (up = ffurl_protocol_next(up)) {
         if (!strcmp(proto_str, up->name))
-            return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
+            return url_alloc_for_protocol(puc, up, filename, flags, int_cb);
         if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME &&
             !strcmp(proto_nested, up->name))
-            return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
+            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,
@@ -218,15 +226,18 @@ fail:
     return ret;
 }
 
-static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int size, int size_min,
-                                         int (*transfer_func)(URLContext *h, unsigned char *buf, int size))
+static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
+                                         int size, int size_min,
+                                         int (*transfer_func)(URLContext *h,
+                                                              uint8_t *buf,
+                                                              int size))
 {
     int ret, len;
     int fast_retries = 5;
 
     len = 0;
     while (len < size_min) {
-        ret = transfer_func(h, buf+len, size-len);
+        ret = transfer_func(h, buf + len, size - len);
         if (ret == AVERROR(EINTR))
             continue;
         if (h->flags & AVIO_FLAG_NONBLOCK)
@@ -240,7 +251,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int
         } else if (ret < 1)
             return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
         if (ret)
-           fast_retries = FFMAX(fast_retries, 2);
+            fast_retries = FFMAX(fast_retries, 2);
         len += ret;
         if (ff_check_interrupt(&h->interrupt_callback))
             return AVERROR_EXIT;
@@ -286,7 +297,8 @@ int64_t ffurl_seek(URLContext *h, int64_t pos, int whence)
 int ffurl_close(URLContext *h)
 {
     int ret = 0;
-    if (!h) return 0; /* can happen when ffurl_open fails */
+    if (!h)
+        return 0;     /* can happen when ffurl_open fails */
 
     if (h->is_connected && h->prot->url_close)
         ret = h->prot->url_close(h);
@@ -326,8 +338,8 @@ int64_t ffurl_size(URLContext *h)
 {
     int64_t pos, size;
 
-    size= ffurl_seek(h, 0, AVSEEK_SIZE);
-    if(size<0){
+    size = ffurl_seek(h, 0, AVSEEK_SIZE);
+    if (size < 0) {
         pos = ffurl_seek(h, 0, SEEK_CUR);
         if ((size = ffurl_seek(h, -1, SEEK_END)) < 0)
             return size;
diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index 3da2fc8..fdc98ec 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -38,6 +38,23 @@ int ffio_init_context(AVIOContext *s,
 
 
 /**
+ * Read size bytes from AVIOContext, returning a pointer.
+ * Note that the data pointed at by the returned pointer is only
+ * valid until the next call that references the same IO context.
+ * @param s IO context
+ * @param buf pointer to buffer into which to assemble the requested
+ *    data if it is not available in contiguous addresses in the
+ *    underlying buffer
+ * @param size number of bytes requested
+ * @param data address at which to store pointer: this will be a
+ *    a direct pointer into the underlying buffer if the requested
+ *    number of bytes are available at contiguous addresses, otherwise
+ *    will be a copy of buf
+ * @return number of bytes read or AVERROR
+ */
+int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data);
+
+/**
  * Read size bytes from AVIOContext into buf.
  * This reads at most 1 packet. If that is not enough fewer bytes will be
  * returned.
@@ -102,4 +119,22 @@ int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size);
  */
 int ffio_fdopen(AVIOContext **s, URLContext *h);
 
+/**
+ * Open a write-only fake memory stream. The written data is not stored
+ * anywhere - this is only used for measuring the amount of data
+ * written.
+ *
+ * @param s new IO context
+ * @return zero if no error.
+ */
+int ffio_open_null_buf(AVIOContext **s);
+
+/**
+ * Close a null buffer.
+ *
+ * @param s an IO context opened by ffio_open_null_buf
+ * @return the number of bytes written to the null buffer
+ */
+int ffio_close_null_buf(AVIOContext *s);
+
 #endif /* AVFORMAT_AVIO_INTERNAL_H */
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index d2eaf36..0024f9e 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -90,7 +90,7 @@ int ffio_init_context(AVIOContext *s,
     s->must_flush      = 0;
     s->eof_reached     = 0;
     s->error           = 0;
-    s->seekable        = AVIO_SEEKABLE_NORMAL;
+    s->seekable        = seek ? AVIO_SEEKABLE_NORMAL : 0;
     s->max_packet_size = 0;
     s->update_checksum = NULL;
 
@@ -490,6 +490,18 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
     return size1 - size;
 }
 
+int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
+{
+    if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
+        *data = s->buf_ptr;
+        s->buf_ptr += size;
+        return size;
+    } else {
+        *data = buf;
+        return avio_read(s, buf, size);
+    }
+}
+
 int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
 {
     int len;
@@ -867,9 +879,12 @@ static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
     }
 
     if (new_allocated_size > d->allocated_size) {
-        d->buffer = av_realloc(d->buffer, new_allocated_size);
-        if(d->buffer == NULL)
-             return AVERROR(ENOMEM);
+        int err;
+        if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
+            d->allocated_size = 0;
+            d->size = 0;
+            return err;
+        }
         d->allocated_size = new_allocated_size;
     }
     memcpy(d->buffer + d->pos, buf, buf_size);
@@ -949,6 +964,11 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
     static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0};
     int padding = 0;
 
+    if (!s) {
+        *pbuffer = NULL;
+        return 0;
+    }
+
     /* don't attempt to pad fixed-size packet buffers */
     if (!s->max_packet_size) {
         avio_write(s, padbuf, sizeof(padbuf));
@@ -963,3 +983,36 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
     av_free(s);
     return size - padding;
 }
+
+static int null_buf_write(void *opaque, uint8_t *buf, int buf_size)
+{
+    DynBuffer *d = opaque;
+
+    d->pos += buf_size;
+    if (d->pos > d->size)
+        d->size = d->pos;
+    return buf_size;
+}
+
+int ffio_open_null_buf(AVIOContext **s)
+{
+    int ret = url_open_dyn_buf_internal(s, 0);
+    if (ret >= 0) {
+        AVIOContext *pb = *s;
+        pb->write_packet = null_buf_write;
+    }
+    return ret;
+}
+
+int ffio_close_null_buf(AVIOContext *s)
+{
+    DynBuffer *d = s->opaque;
+    int size;
+
+    avio_flush(s);
+
+    size = d->size;
+    av_free(d);
+    av_free(s);
+    return size;
+}
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index d31c427..10a0740 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -1,6 +1,6 @@
 /*
- * AVISynth support
- * Copyright (c) 2006 DivX, Inc.
+ * AviSynth/AvxSynth support
+ * Copyright (c) 2012 AvxSynth Team.
  *
  * This file is part of Libav.
  *
@@ -19,209 +19,671 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/internal.h"
+#include "libavcodec/internal.h"
 #include "avformat.h"
 #include "internal.h"
-#include "riff.h"
-
-#include <windows.h>
-#include <vfw.h>
-
-typedef struct {
-  PAVISTREAM handle;
-  AVISTREAMINFO info;
-  DWORD read;
-  LONG chunck_size;
-  LONG chunck_samples;
-} AVISynthStream;
-
-typedef struct {
-  PAVIFILE file;
-  AVISynthStream *streams;
-  int nb_streams;
-  int next_stream;
-} AVISynthContext;
-
-static int avisynth_read_header(AVFormatContext *s)
+
+/* Enable function pointer definitions for runtime loading. */
+#define AVSC_NO_DECLSPEC
+
+/* Platform-specific directives for AviSynth vs AvxSynth.
+ *
+ * avisynth_c.h needs to be the one provided with x264, as
+ * the one in AviSynth's CVS hasn't been updated to support
+ * 2.6's extra colorspaces. A temporary source of that header,
+ * installable from a GNU-style Makefile is available from
+ * github.com/qyot27/avisynth_headers -- AvxSynth doesn't
+ * require this kind of special treatment because like any
+ * standard *nix application, it installs its headers
+ * alongside its libs. */
+#ifdef _WIN32
+  #include <windows.h>
+  #undef EXTERN_C
+  #include <avisynth/avisynth_c.h>
+  #define AVISYNTH_LIB "avisynth"
+  #define USING_AVISYNTH
+#else
+  #include <dlfcn.h>
+  #include <avxsynth/avxsynth_c.h>
+    #if defined (__APPLE__)
+      #define AVISYNTH_LIB "libavxsynth.dylib"
+    #else
+      #define AVISYNTH_LIB "libavxsynth.so"
+    #endif
+
+  #define LoadLibrary(x) dlopen(x, RTLD_NOW | RTLD_GLOBAL)
+  #define GetProcAddress dlsym
+  #define FreeLibrary dlclose
+#endif
+
+typedef struct AviSynthLibrary {
+    void *library;
+#define AVSC_DECLARE_FUNC(name) name ## _func name
+    AVSC_DECLARE_FUNC(avs_bit_blt);
+    AVSC_DECLARE_FUNC(avs_clip_get_error);
+    AVSC_DECLARE_FUNC(avs_create_script_environment);
+    AVSC_DECLARE_FUNC(avs_delete_script_environment);
+    AVSC_DECLARE_FUNC(avs_get_audio);
+    AVSC_DECLARE_FUNC(avs_get_error);
+    AVSC_DECLARE_FUNC(avs_get_frame);
+    AVSC_DECLARE_FUNC(avs_get_version);
+    AVSC_DECLARE_FUNC(avs_get_video_info);
+    AVSC_DECLARE_FUNC(avs_invoke);
+    AVSC_DECLARE_FUNC(avs_release_clip);
+    AVSC_DECLARE_FUNC(avs_release_value);
+    AVSC_DECLARE_FUNC(avs_release_video_frame);
+    AVSC_DECLARE_FUNC(avs_take_clip);
+#undef AVSC_DECLARE_FUNC
+} AviSynthLibrary;
+
+typedef struct AviSynthContext {
+    AVS_ScriptEnvironment *env;
+    AVS_Clip *clip;
+    const AVS_VideoInfo *vi;
+
+    /* avisynth_read_packet_video() iterates over this. */
+    int n_planes;
+    const int *planes;
+
+    int curr_stream;
+    int curr_frame;
+    int64_t curr_sample;
+
+    int error;
+
+    /* Linked list pointers. */
+    struct AviSynthContext *next;
+} AviSynthContext;
+
+static const int avs_planes_packed[1] = { 0 };
+static const int avs_planes_grey[1]   = { AVS_PLANAR_Y };
+static const int avs_planes_yuv[3]    = { AVS_PLANAR_Y, AVS_PLANAR_U,
+                                          AVS_PLANAR_V };
+
+/* A conflict between C++ global objects, atexit, and dynamic loading requires
+ * us to register our own atexit handler to prevent double freeing. */
+static AviSynthLibrary avs_library;
+static int avs_atexit_called        = 0;
+
+/* Linked list of AviSynthContexts. An atexit handler destroys this list. */
+static AviSynthContext *avs_ctx_list = NULL;
+
+static av_cold void avisynth_atexit_handler(void);
+
+static av_cold int avisynth_load_library(void)
+{
+    avs_library.library = LoadLibrary(AVISYNTH_LIB);
+    if (!avs_library.library)
+        return AVERROR_UNKNOWN;
+
+#define LOAD_AVS_FUNC(name, continue_on_fail)                          \
+        avs_library.name =                                             \
+            (void *)GetProcAddress(avs_library.library, #name);        \
+        if (!continue_on_fail && !avs_library.name)                    \
+            goto fail;
+
+    LOAD_AVS_FUNC(avs_bit_blt, 0);
+    LOAD_AVS_FUNC(avs_clip_get_error, 0);
+    LOAD_AVS_FUNC(avs_create_script_environment, 0);
+    LOAD_AVS_FUNC(avs_delete_script_environment, 0);
+    LOAD_AVS_FUNC(avs_get_audio, 0);
+    LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6
+    LOAD_AVS_FUNC(avs_get_frame, 0);
+    LOAD_AVS_FUNC(avs_get_version, 0);
+    LOAD_AVS_FUNC(avs_get_video_info, 0);
+    LOAD_AVS_FUNC(avs_invoke, 0);
+    LOAD_AVS_FUNC(avs_release_clip, 0);
+    LOAD_AVS_FUNC(avs_release_value, 0);
+    LOAD_AVS_FUNC(avs_release_video_frame, 0);
+    LOAD_AVS_FUNC(avs_take_clip, 0);
+#undef LOAD_AVS_FUNC
+
+    atexit(avisynth_atexit_handler);
+    return 0;
+
+fail:
+    FreeLibrary(avs_library.library);
+    return AVERROR_UNKNOWN;
+}
+
+/* Note that avisynth_context_create and avisynth_context_destroy
+ * do not allocate or free the actual context! That is taken care of
+ * by libavformat. */
+static av_cold int avisynth_context_create(AVFormatContext *s)
+{
+    AviSynthContext *avs = s->priv_data;
+    int ret;
+
+    if (!avs_library.library)
+        if (ret = avisynth_load_library())
+            return ret;
+
+    avs->env = avs_library.avs_create_script_environment(3);
+    if (avs_library.avs_get_error) {
+        const char *error = avs_library.avs_get_error(avs->env);
+        if (error) {
+            av_log(s, AV_LOG_ERROR, "%s\n", error);
+            return AVERROR_UNKNOWN;
+        }
+    }
+
+    if (!avs_ctx_list) {
+        avs_ctx_list = avs;
+    } else {
+        avs->next    = avs_ctx_list;
+        avs_ctx_list = avs;
+    }
+
+    return 0;
+}
+
+static av_cold void avisynth_context_destroy(AviSynthContext *avs)
+{
+    if (avs_atexit_called)
+        return;
+
+    if (avs == avs_ctx_list) {
+        avs_ctx_list = avs->next;
+    } else {
+        AviSynthContext *prev = avs_ctx_list;
+        while (prev->next != avs)
+            prev = prev->next;
+        prev->next = avs->next;
+    }
+
+    if (avs->clip) {
+        avs_library.avs_release_clip(avs->clip);
+        avs->clip = NULL;
+    }
+    if (avs->env) {
+        avs_library.avs_delete_script_environment(avs->env);
+        avs->env = NULL;
+    }
+}
+
+static av_cold void avisynth_atexit_handler(void)
+{
+    AviSynthContext *avs = avs_ctx_list;
+
+    while (avs) {
+        AviSynthContext *next = avs->next;
+        avisynth_context_destroy(avs);
+        avs = next;
+    }
+    FreeLibrary(avs_library.library);
+
+    avs_atexit_called = 1;
+}
+
+/* Create AVStream from audio and video data. */
+static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st)
 {
-  AVISynthContext *avs = s->priv_data;
-  HRESULT res;
-  AVIFILEINFO info;
-  DWORD id;
-  AVStream *st;
-  AVISynthStream *stream;
-  wchar_t filename_wchar[1024] = { 0 };
-  char filename_char[1024] = { 0 };
-
-  AVIFileInit();
-
-  /* avisynth can't accept UTF-8 filename */
-  MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wchar, 1024);
-  WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wchar, -1, filename_char, 1024, NULL, NULL);
-  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);
-      AVIFileExit();
-      return -1;
-    }
-
-  res = AVIFileInfo(avs->file, &info, sizeof(info));
-  if (res != S_OK)
-    {
-      av_log(s, AV_LOG_ERROR, "AVIFileInfo failed with error %ld", res);
-      AVIFileExit();
-      return -1;
-    }
-
-  avs->streams = av_mallocz(info.dwStreams * sizeof(AVISynthStream));
-
-  for (id=0; id<info.dwStreams; id++)
-    {
-      stream = &avs->streams[id];
-      stream->read = 0;
-      if (AVIFileGetStream(avs->file, &stream->handle, 0, id) == S_OK)
-        {
-          if (AVIStreamInfo(stream->handle, &stream->info, sizeof(stream->info)) == S_OK)
-            {
-              if (stream->info.fccType == streamtypeAUDIO)
-                {
-                  WAVEFORMATEX wvfmt;
-                  LONG struct_size = sizeof(WAVEFORMATEX);
-                  if (AVIStreamReadFormat(stream->handle, 0, &wvfmt, &struct_size) != S_OK)
-                    continue;
-
-                  st = avformat_new_stream(s, NULL);
-                  st->id = id;
-                  st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-
-                  st->codec->block_align = wvfmt.nBlockAlign;
-                  st->codec->channels = wvfmt.nChannels;
-                  st->codec->sample_rate = wvfmt.nSamplesPerSec;
-                  st->codec->bit_rate = wvfmt.nAvgBytesPerSec * 8;
-                  st->codec->bits_per_coded_sample = wvfmt.wBitsPerSample;
-
-                  stream->chunck_samples = wvfmt.nSamplesPerSec * (uint64_t)info.dwScale / (uint64_t)info.dwRate;
-                  stream->chunck_size = stream->chunck_samples * wvfmt.nChannels * wvfmt.wBitsPerSample / 8;
-
-                  st->codec->codec_tag = wvfmt.wFormatTag;
-                  st->codec->codec_id = ff_wav_codec_get_id(wvfmt.wFormatTag, st->codec->bits_per_coded_sample);
-                }
-              else if (stream->info.fccType == streamtypeVIDEO)
-                {
-                  BITMAPINFO imgfmt;
-                  LONG struct_size = sizeof(BITMAPINFO);
-
-                  stream->chunck_size = stream->info.dwSampleSize;
-                  stream->chunck_samples = 1;
-
-                  if (AVIStreamReadFormat(stream->handle, 0, &imgfmt, &struct_size) != S_OK)
-                    continue;
-
-                  st = avformat_new_stream(s, NULL);
-                  st->id = id;
-                  st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-                  st->avg_frame_rate.num = stream->info.dwRate;
-                  st->avg_frame_rate.den = stream->info.dwScale;
-#if FF_API_R_FRAME_RATE
-                  st->r_frame_rate = st->avg_frame_rate;
+    AviSynthContext *avs = s->priv_data;
+    int planar = 0; // 0: packed, 1: YUV, 2: Y8
+
+    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_id   = AV_CODEC_ID_RAWVIDEO;
+    st->codec->width      = avs->vi->width;
+    st->codec->height     = avs->vi->height;
+
+    st->time_base         = (AVRational) { avs->vi->fps_denominator,
+                                           avs->vi->fps_numerator };
+    st->avg_frame_rate    = (AVRational) { avs->vi->fps_numerator,
+                                           avs->vi->fps_denominator };
+    st->start_time        = 0;
+    st->duration          = avs->vi->num_frames;
+    st->nb_frames         = avs->vi->num_frames;
+
+    switch (avs->vi->pixel_type) {
+#ifdef USING_AVISYNTH
+    case AVS_CS_YV24:
+        st->codec->pix_fmt = AV_PIX_FMT_YUV444P;
+        planar             = 1;
+        break;
+    case AVS_CS_YV16:
+        st->codec->pix_fmt = AV_PIX_FMT_YUV422P;
+        planar             = 1;
+        break;
+    case AVS_CS_YV411:
+        st->codec->pix_fmt = AV_PIX_FMT_YUV411P;
+        planar             = 1;
+        break;
+    case AVS_CS_Y8:
+        st->codec->pix_fmt = AV_PIX_FMT_GRAY8;
+        planar             = 2;
+        break;
 #endif
+    case AVS_CS_BGR24:
+        st->codec->pix_fmt = AV_PIX_FMT_BGR24;
+        break;
+    case AVS_CS_BGR32:
+        st->codec->pix_fmt = AV_PIX_FMT_RGB32;
+        break;
+    case AVS_CS_YUY2:
+        st->codec->pix_fmt = AV_PIX_FMT_YUYV422;
+        break;
+    case AVS_CS_YV12:
+        st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
+        planar             = 1;
+        break;
+    case AVS_CS_I420: // Is this even used anywhere?
+        st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
+        planar             = 1;
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR,
+               "unknown AviSynth colorspace %d\n", avs->vi->pixel_type);
+        avs->error = 1;
+        return AVERROR_UNKNOWN;
+    }
 
-                  st->codec->width = imgfmt.bmiHeader.biWidth;
-                  st->codec->height = imgfmt.bmiHeader.biHeight;
+    switch (planar) {
+    case 2: // Y8
+        avs->n_planes = 1;
+        avs->planes   = avs_planes_grey;
+        break;
+    case 1: // YUV
+        avs->n_planes = 3;
+        avs->planes   = avs_planes_yuv;
+        break;
+    default:
+        avs->n_planes = 1;
+        avs->planes   = avs_planes_packed;
+    }
+    return 0;
+}
+
+static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st)
+{
+    AviSynthContext *avs = s->priv_data;
+
+    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    st->codec->sample_rate = avs->vi->audio_samples_per_second;
+    st->codec->channels    = avs->vi->nchannels;
+    st->time_base          = (AVRational) { 1,
+                                            avs->vi->audio_samples_per_second };
+
+    switch (avs->vi->sample_type) {
+    case AVS_SAMPLE_INT8:
+        st->codec->codec_id = AV_CODEC_ID_PCM_U8;
+        break;
+    case AVS_SAMPLE_INT16:
+        st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+        break;
+    case AVS_SAMPLE_INT24:
+        st->codec->codec_id = AV_CODEC_ID_PCM_S24LE;
+        break;
+    case AVS_SAMPLE_INT32:
+        st->codec->codec_id = AV_CODEC_ID_PCM_S32LE;
+        break;
+    case AVS_SAMPLE_FLOAT:
+        st->codec->codec_id = AV_CODEC_ID_PCM_F32LE;
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR,
+               "unknown AviSynth sample type %d\n", avs->vi->sample_type);
+        avs->error = 1;
+        return AVERROR_UNKNOWN;
+    }
+    return 0;
+}
+
+static int avisynth_create_stream(AVFormatContext *s)
+{
+    AviSynthContext *avs = s->priv_data;
+    AVStream *st;
+    int ret;
+    int id = 0;
+
+    if (avs_has_video(avs->vi)) {
+        st = avformat_new_stream(s, NULL);
+        if (!st)
+            return AVERROR_UNKNOWN;
+        st->id = id++;
+        if (ret = avisynth_create_stream_video(s, st))
+            return ret;
+    }
+    if (avs_has_audio(avs->vi)) {
+        st = avformat_new_stream(s, NULL);
+        if (!st)
+            return AVERROR_UNKNOWN;
+        st->id = id++;
+        if (ret = avisynth_create_stream_audio(s, st))
+            return ret;
+    }
+    return 0;
+}
 
-                  st->codec->bits_per_coded_sample = imgfmt.bmiHeader.biBitCount;
-                  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);
+static int avisynth_open_file(AVFormatContext *s)
+{
+    AviSynthContext *avs = s->priv_data;
+    AVS_Value arg, val;
+    int ret;
+#ifdef USING_AVISYNTH
+    char filename_ansi[MAX_PATH * 4];
+    wchar_t filename_wc[MAX_PATH * 4];
+#endif
 
-                  st->duration = stream->info.dwLength;
-                }
-              else
-                {
-                  AVIStreamRelease(stream->handle);
-                  continue;
-                }
+    if (ret = avisynth_context_create(s))
+        return ret;
+
+#ifdef USING_AVISYNTH
+    /* Convert UTF-8 to ANSI code page */
+    MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wc, MAX_PATH * 4);
+    WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi,
+                        MAX_PATH * 4, NULL, NULL);
+    arg = avs_new_value_string(filename_ansi);
+#else
+    arg = avs_new_value_string(s->filename);
+#endif
+    val = avs_library.avs_invoke(avs->env, "Import", arg, 0);
+    if (avs_is_error(val)) {
+        av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val));
+        ret = AVERROR_UNKNOWN;
+        goto fail;
+    }
+    if (!avs_is_clip(val)) {
+        av_log(s, AV_LOG_ERROR, "AviSynth script did not return a clip\n");
+        ret = AVERROR_UNKNOWN;
+        goto fail;
+    }
 
-              avs->nb_streams++;
+    avs->clip = avs_library.avs_take_clip(val, avs->env);
+    avs->vi   = avs_library.avs_get_video_info(avs->clip);
 
-              st->codec->stream_codec_tag = stream->info.fccHandler;
+#ifdef USING_AVISYNTH
+    /* libav only supports AviSynth 2.6 on Windows. Since AvxSynth
+     * identifies itself as interface version 3 like 2.5.8, this
+     * needs to be special-cased. */
 
-              avpriv_set_pts_info(st, 64, info.dwScale, info.dwRate);
-              st->start_time = stream->info.dwStart;
-            }
-        }
+    if (avs_library.avs_get_version(avs->clip) == 3) {
+        av_log(s, AV_LOG_ERROR,
+               "AviSynth 2.5.8 not supported. Please upgrade to 2.6.\n");
+        ret = AVERROR_UNKNOWN;
+        goto fail;
     }
+#endif
+
+    /* Release the AVS_Value as it will go out of scope. */
+    avs_library.avs_release_value(val);
+
+    if (ret = avisynth_create_stream(s))
+        goto fail;
 
-  return 0;
+    return 0;
+
+fail:
+    avisynth_context_destroy(avs);
+    return ret;
 }
 
-static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt)
+static void avisynth_next_stream(AVFormatContext *s, AVStream **st,
+                                 AVPacket *pkt, int *discard)
+{
+    AviSynthContext *avs = s->priv_data;
+
+    pkt->stream_index = avs->curr_stream++;
+    avs->curr_stream %= s->nb_streams;
+
+    *st = s->streams[pkt->stream_index];
+    if ((*st)->discard == AVDISCARD_ALL)
+        *discard = 1;
+    else
+        *discard = 0;
+
+    return;
+}
+
+/* Copy AviSynth clip data into an AVPacket. */
+static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt,
+                                      int discard)
 {
-  AVISynthContext *avs = s->priv_data;
-  HRESULT res;
-  AVISynthStream *stream;
-  int stream_id = avs->next_stream;
-  LONG read_size;
+    AviSynthContext *avs = s->priv_data;
+    AVS_VideoFrame *frame;
+    unsigned char *dst_p;
+    const unsigned char *src_p;
+    int n, i, plane, rowsize, planeheight, pitch, bits;
+    const char *error;
+
+    if (avs->curr_frame >= avs->vi->num_frames)
+        return AVERROR_EOF;
+
+    /* This must happen even if the stream is discarded to prevent desync. */
+    n = avs->curr_frame++;
+    if (discard)
+        return 0;
+
+    pkt->pts      = n;
+    pkt->dts      = n;
+    pkt->duration = 1;
+
+#ifdef USING_AVISYNTH
+    /* Define the bpp values for the new AviSynth 2.6 colorspaces.
+     * Since AvxSynth doesn't have these functions, special-case
+     * it in order to avoid implicit declaration errors. */
+
+    if (avs_is_yv24(avs->vi))
+        bits = 24;
+    else if (avs_is_yv16(avs->vi))
+        bits = 16;
+    else if (avs_is_yv411(avs->vi))
+        bits = 12;
+    else if (avs_is_y8(avs->vi))
+        bits = 8;
+    else
+#endif
+        bits = avs_bits_per_pixel(avs->vi);
+
+    /* Without the cast to int64_t, calculation overflows at about 9k x 9k
+     * resolution. */
+    pkt->size = (((int64_t)avs->vi->width *
+                  (int64_t)avs->vi->height) * bits) / 8;
+    if (!pkt->size)
+        return AVERROR_UNKNOWN;
+
+    if (av_new_packet(pkt, pkt->size) < 0)
+        return AVERROR(ENOMEM);
+
+    frame = avs_library.avs_get_frame(avs->clip, n);
+    error = avs_library.avs_clip_get_error(avs->clip);
+    if (error) {
+        av_log(s, AV_LOG_ERROR, "%s\n", error);
+        avs->error = 1;
+        av_packet_unref(pkt);
+        return AVERROR_UNKNOWN;
+    }
 
-  // handle interleaving manually...
-  stream = &avs->streams[stream_id];
+    dst_p = pkt->data;
+    for (i = 0; i < avs->n_planes; i++) {
+        plane = avs->planes[i];
+        src_p = avs_get_read_ptr_p(frame, plane);
+        pitch = avs_get_pitch_p(frame, plane);
 
-  if (stream->read >= stream->info.dwLength)
-    return AVERROR(EIO);
+        rowsize     = avs_get_row_size_p(frame, plane);
+        planeheight = avs_get_height_p(frame, plane);
 
-  if (av_new_packet(pkt, stream->chunck_size))
-    return AVERROR(EIO);
-  pkt->stream_index = stream_id;
-  pkt->pts = avs->streams[stream_id].read / avs->streams[stream_id].chunck_samples;
+        /* Flip RGB video. */
+        if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) {
+            src_p = src_p + (planeheight - 1) * pitch;
+            pitch = -pitch;
+        }
 
-  res = AVIStreamRead(stream->handle, stream->read, stream->chunck_samples, pkt->data, stream->chunck_size, &read_size, NULL);
+        avs_library.avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch,
+                                 rowsize, planeheight);
+        dst_p += rowsize * planeheight;
+    }
 
-  pkt->pts = stream->read;
-  pkt->size = read_size;
+    avs_library.avs_release_video_frame(frame);
+    return 0;
+}
 
-  stream->read += stream->chunck_samples;
+static int avisynth_read_packet_audio(AVFormatContext *s, AVPacket *pkt,
+                                      int discard)
+{
+    AviSynthContext *avs = s->priv_data;
+    AVRational fps, samplerate;
+    int samples;
+    int64_t n;
+    const char *error;
+
+    if (avs->curr_sample >= avs->vi->num_audio_samples)
+        return AVERROR_EOF;
+
+    fps.num        = avs->vi->fps_numerator;
+    fps.den        = avs->vi->fps_denominator;
+    samplerate.num = avs->vi->audio_samples_per_second;
+    samplerate.den = 1;
+
+    if (avs_has_video(avs->vi)) {
+        if (avs->curr_frame < avs->vi->num_frames)
+            samples = av_rescale_q(avs->curr_frame, samplerate, fps) -
+                      avs->curr_sample;
+        else
+            samples = av_rescale_q(1, samplerate, fps);
+    } else {
+        samples = 1000;
+    }
 
-  // prepare for the next stream to read
-  do {
-    avs->next_stream = (avs->next_stream+1) % avs->nb_streams;
-  } while (avs->next_stream != stream_id && s->streams[avs->next_stream]->discard >= AVDISCARD_ALL);
+    /* After seeking, audio may catch up with video. */
+    if (samples <= 0) {
+        pkt->size = 0;
+        pkt->data = NULL;
+        return 0;
+    }
 
-  return (res == S_OK) ? pkt->size : -1;
+    if (avs->curr_sample + samples > avs->vi->num_audio_samples)
+        samples = avs->vi->num_audio_samples - avs->curr_sample;
+
+    /* This must happen even if the stream is discarded to prevent desync. */
+    n                 = avs->curr_sample;
+    avs->curr_sample += samples;
+    if (discard)
+        return 0;
+
+    pkt->pts      = n;
+    pkt->dts      = n;
+    pkt->duration = samples;
+
+    pkt->size = avs_bytes_per_channel_sample(avs->vi) *
+                samples * avs->vi->nchannels;
+    if (!pkt->size)
+        return AVERROR_UNKNOWN;
+
+    if (av_new_packet(pkt, pkt->size) < 0)
+        return AVERROR(ENOMEM);
+
+    avs_library.avs_get_audio(avs->clip, pkt->data, n, samples);
+    error = avs_library.avs_clip_get_error(avs->clip);
+    if (error) {
+        av_log(s, AV_LOG_ERROR, "%s\n", error);
+        avs->error = 1;
+        av_packet_unref(pkt);
+        return AVERROR_UNKNOWN;
+    }
+    return 0;
 }
 
-static int avisynth_read_close(AVFormatContext *s)
+static av_cold int avisynth_read_header(AVFormatContext *s)
 {
-  AVISynthContext *avs = s->priv_data;
-  int i;
+    int ret;
+
+    // Calling library must implement a lock for thread-safe opens.
+    if (ret = avpriv_lock_avformat())
+        return ret;
+
+    if (ret = avisynth_open_file(s)) {
+        avpriv_unlock_avformat();
+        return ret;
+    }
 
-  for (i=0;i<avs->nb_streams;i++)
-    {
-      AVIStreamRelease(avs->streams[i].handle);
+    avpriv_unlock_avformat();
+    return 0;
+}
+
+static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AviSynthContext *avs = s->priv_data;
+    AVStream *st;
+    int discard = 0;
+    int ret;
+
+    if (avs->error)
+        return AVERROR_UNKNOWN;
+
+    /* If either stream reaches EOF, try to read the other one before
+     * giving up. */
+    avisynth_next_stream(s, &st, pkt, &discard);
+    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+        ret = avisynth_read_packet_video(s, pkt, discard);
+        if (ret == AVERROR_EOF && avs_has_audio(avs->vi)) {
+            avisynth_next_stream(s, &st, pkt, &discard);
+            return avisynth_read_packet_audio(s, pkt, discard);
+        }
+    } else {
+        ret = avisynth_read_packet_audio(s, pkt, discard);
+        if (ret == AVERROR_EOF && avs_has_video(avs->vi)) {
+            avisynth_next_stream(s, &st, pkt, &discard);
+            return avisynth_read_packet_video(s, pkt, discard);
+        }
     }
 
-  av_free(avs->streams);
-  AVIFileRelease(avs->file);
-  AVIFileExit();
-  return 0;
+    return ret;
 }
 
-static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flags)
+static av_cold int avisynth_read_close(AVFormatContext *s)
 {
-  AVISynthContext *avs = s->priv_data;
-  int stream_id;
+    if (avpriv_lock_avformat())
+        return AVERROR_UNKNOWN;
+
+    avisynth_context_destroy(s->priv_data);
+    avpriv_unlock_avformat();
+    return 0;
+}
 
-  for (stream_id = 0; stream_id < avs->nb_streams; stream_id++)
-    {
-      avs->streams[stream_id].read = pts * avs->streams[stream_id].chunck_samples;
+static int avisynth_read_seek(AVFormatContext *s, int stream_index,
+                              int64_t timestamp, int flags)
+{
+    AviSynthContext *avs = s->priv_data;
+    AVStream *st;
+    AVRational fps, samplerate;
+
+    if (avs->error)
+        return AVERROR_UNKNOWN;
+
+    fps        = (AVRational) { avs->vi->fps_numerator,
+                                avs->vi->fps_denominator };
+    samplerate = (AVRational) { avs->vi->audio_samples_per_second, 1 };
+
+    st = s->streams[stream_index];
+    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+        /* AviSynth frame counts are signed int. */
+        if ((timestamp >= avs->vi->num_frames) ||
+            (timestamp > INT_MAX)              ||
+            (timestamp < 0))
+            return AVERROR_EOF;
+        avs->curr_frame = timestamp;
+        if (avs_has_audio(avs->vi))
+            avs->curr_sample = av_rescale_q(timestamp, samplerate, fps);
+    } else {
+        if ((timestamp >= avs->vi->num_audio_samples) || (timestamp < 0))
+            return AVERROR_EOF;
+        /* Force frame granularity for seeking. */
+        if (avs_has_video(avs->vi)) {
+            avs->curr_frame  = av_rescale_q(timestamp, fps, samplerate);
+            avs->curr_sample = av_rescale_q(avs->curr_frame, samplerate, fps);
+        } else {
+            avs->curr_sample = timestamp;
+        }
     }
 
-  return 0;
+    return 0;
 }
 
 AVInputFormat ff_avisynth_demuxer = {
-    .name           = "avs",
-    .long_name      = NULL_IF_CONFIG_SMALL("AVISynth"),
-    .priv_data_size = sizeof(AVISynthContext),
+    .name           = "avisynth",
+    .long_name      = NULL_IF_CONFIG_SMALL("AviSynth script"),
+    .priv_data_size = sizeof(AviSynthContext),
     .read_header    = avisynth_read_header,
     .read_packet    = avisynth_read_packet,
     .read_close     = avisynth_read_close,
diff --git a/libavformat/avs.c b/libavformat/avs.c
index a6a90dd..3e95a36 100644
--- a/libavformat/avs.c
+++ b/libavformat/avs.c
@@ -50,7 +50,9 @@ static int avs_probe(AVProbeData * p)
 
     d = p->buf;
     if (d[0] == 'w' && d[1] == 'W' && d[2] == 0x10 && d[3] == 0)
-        return 50;
+        /* Ensure the buffer probe scores higher than the extension probe.
+         * This avoids problems with misdetection as AviSynth scripts. */
+        return AVPROBE_SCORE_EXTENSION + 1;
 
     return 0;
 }
@@ -188,9 +190,6 @@ static int avs_read_packet(AVFormatContext * s, AVPacket * pkt)
                     avs->st_video->codec->height = avs->height;
                     avs->st_video->codec->bits_per_coded_sample=avs->bits_per_sample;
                     avs->st_video->nb_frames = avs->nb_frames;
-#if FF_API_R_FRAME_RATE
-                    avs->st_video->r_frame_rate =
-#endif
                     avs->st_video->avg_frame_rate = (AVRational){avs->fps, 1};
                 }
                 return avs_read_video_packet(s, pkt, type, sub_type, size,
diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c
index f41ef52..120e145 100644
--- a/libavformat/bethsoftvid.c
+++ b/libavformat/bethsoftvid.c
@@ -108,8 +108,9 @@ static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt,
             return AVERROR(ENOMEM);
         vid->video_index = st->index;
         if (vid->audio_index < 0) {
-            av_log_ask_for_sample(s, "No audio packet before first video "
-                                  "packet. Using default video time base.\n");
+            avpriv_request_sample(s, "Using default video time base since "
+                                  "having no audio packet before the first "
+                                  "video packet");
         }
         avpriv_set_pts_info(st, 64, 185, vid->sample_rate);
         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
diff --git a/libavformat/bink.c b/libavformat/bink.c
index 5d3de14..f093e7c 100644
--- a/libavformat/bink.c
+++ b/libavformat/bink.c
@@ -112,10 +112,13 @@ static int read_header(AVFormatContext *s)
         return AVERROR(EIO);
     }
     avpriv_set_pts_info(vst, 64, fps_den, fps_num);
+    vst->avg_frame_rate = av_inv_q(vst->time_base);
 
     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     vst->codec->codec_id   = AV_CODEC_ID_BINKVIDEO;
     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/bmv.c b/libavformat/bmv.c
index ce157e8..b5572af 100644
--- a/libavformat/bmv.c
+++ b/libavformat/bmv.c
@@ -71,8 +71,7 @@ static int bmv_read_header(AVFormatContext *s)
 static int bmv_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     BMVContext *c = s->priv_data;
-    int type;
-    void *tmp;
+    int type, err;
 
     while (c->get_next) {
         if (s->pb->eof_reached)
@@ -85,10 +84,8 @@ static int bmv_read_packet(AVFormatContext *s, AVPacket *pkt)
         c->size = avio_rl24(s->pb);
         if (!c->size)
             return AVERROR_INVALIDDATA;
-        tmp = av_realloc(c->packet, c->size + 1);
-        if (!tmp)
-            return AVERROR(ENOMEM);
-        c->packet = tmp;
+        if ((err = av_reallocp(&c->packet, c->size + 1)) < 0)
+            return err;
         c->packet[0] = type;
         if (avio_read(s->pb, c->packet + 1, c->size) != c->size)
             return AVERROR(EIO);
diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c
index ed9cdb2..fcca9e1 100644
--- a/libavformat/cavsvideodec.c
+++ b/libavformat/cavsvideodec.c
@@ -61,7 +61,7 @@ static int cavsvideo_probe(AVProbeData *p)
         }
     }
     if(seq && seq*9<=pic*10)
-        return AVPROBE_SCORE_MAX/2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
diff --git a/libavformat/concat.c b/libavformat/concat.c
index 24c50c1..416bbf5 100644
--- a/libavformat/concat.c
+++ b/libavformat/concat.c
@@ -56,7 +56,7 @@ static av_cold int concat_close(URLContext *h)
 
 static av_cold int concat_open(URLContext *h, const char *uri, int flags)
 {
-    char *node_uri = NULL, *tmp_uri;
+    char *node_uri = NULL;
     int err = 0;
     int64_t size;
     size_t  len, i;
@@ -74,7 +74,7 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags)
                 return AVERROR(ENAMETOOLONG);
             }
 
-    if (!(nodes = av_malloc(sizeof(*nodes) * len))) {
+    if (!(nodes = av_realloc(NULL, sizeof(*nodes) * len))) {
         return AVERROR(ENOMEM);
     } else
         data->nodes = nodes;
@@ -85,11 +85,8 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags)
     for (i = 0; *uri; i++) {
         /* parsing uri */
         len = strcspn(uri, AV_CAT_SEPARATOR);
-        if (!(tmp_uri = av_realloc(node_uri, len+1))) {
-            err = AVERROR(ENOMEM);
+        if ((err = av_reallocp(&node_uri, len + 1)) < 0)
             break;
-        } else
-            node_uri = tmp_uri;
         av_strlcpy(node_uri, uri, len+1);
         uri += len + strspn(uri+len, AV_CAT_SEPARATOR);
 
@@ -114,10 +111,9 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags)
 
     if (err < 0)
         concat_close(h);
-    else if (!(nodes = av_realloc(nodes, data->length * sizeof(*nodes)))) {
+    else if ((err = av_reallocp(&nodes, data->length * sizeof(*nodes))) < 0)
         concat_close(h);
-        err = AVERROR(ENOMEM);
-    } else
+    else
         data->nodes = nodes;
     return err;
 }
diff --git a/libavformat/daud.c b/libavformat/daud.c
index 3ceb958..bb7ab7f 100644
--- a/libavformat/daud.c
+++ b/libavformat/daud.c
@@ -68,7 +68,6 @@ static int daud_write_packet(struct AVFormatContext *s, AVPacket *pkt)
     avio_wb16(s->pb, pkt->size);
     avio_wb16(s->pb, 0x8010); // unknown
     avio_write(s->pb, pkt->data, pkt->size);
-    avio_flush(s->pb);
     return 0;
 }
 
diff --git a/libavformat/dtsdec.c b/libavformat/dtsdec.c
index 28cccd3..9010711 100644
--- a/libavformat/dtsdec.c
+++ b/libavformat/dtsdec.c
@@ -60,7 +60,7 @@ static int dts_probe(AVProbeData *p)
     max = markers[2] > markers[max] ? 2 : max;
     if (markers[max] > 3 && p->buf_size / markers[max] < 32*1024 &&
         markers[max] * 4 > sum * 3)
-        return AVPROBE_SCORE_MAX/2+1;
+        return AVPROBE_SCORE_EXTENSION + 1;
 
     return 0;
 }
diff --git a/libavformat/dv.c b/libavformat/dv.c
index ea2805e..5a1261a 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -32,7 +32,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "libavcodec/dv_profile.h"
-#include "libavcodec/dvdata.h"
+#include "libavcodec/dv.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
@@ -63,7 +63,7 @@ static inline uint16_t dv_audio_12to16(uint16_t sample)
         shift--;
         result = (sample - (256 * shift)) << shift;
     } else {
-        shift = 0xe - shift;
+        shift  = 0xe - shift;
         result = ((sample + ((256 * shift) + 1)) << shift) - 1;
     }
 
@@ -75,19 +75,19 @@ static inline uint16_t dv_audio_12to16(uint16_t sample)
  * a fixed offset and if pack isn't there -- fails. We might want
  * to have a fallback mechanism for complete search of missing packs.
  */
-static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
+static const uint8_t *dv_extract_pack(uint8_t *frame, enum dv_pack_type t)
 {
     int offs;
 
     switch (t) {
     case dv_audio_source:
-        offs = (80*6 + 80*16*3 + 3);
+        offs = (80 * 6 + 80 * 16 * 3 + 3);
         break;
     case dv_audio_control:
-        offs = (80*6 + 80*16*4 + 3);
+        offs = (80 * 6 + 80 * 16 * 4 + 3);
         break;
     case dv_video_control:
-        offs = (80*5 + 48 + 5);
+        offs = (80 * 5 + 48 + 5);
         break;
     default:
         return NULL;
@@ -113,24 +113,24 @@ static int dv_extract_audio(uint8_t *frame, uint8_t **ppcm,
 {
     int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
     uint16_t lc, rc;
-    const uint8_t* as_pack;
+    const uint8_t *as_pack;
     uint8_t *pcm, ipcm;
 
     as_pack = dv_extract_pack(frame, dv_audio_source);
     if (!as_pack)    /* No audio ? */
         return 0;
 
-    smpls =  as_pack[1] & 0x3f;       /* samples in this frame - min. samples */
-    freq  = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
-    quant =  as_pack[4] & 0x07;       /* 0 - 16bit linear, 1 - 12bit nonlinear */
+    smpls = as_pack[1]      & 0x3f; /* samples in this frame - min. samples */
+    freq  = as_pack[4] >> 3 & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
+    quant = as_pack[4]      & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
 
     if (quant > 1)
-        return -1; /* unsupported quantization */
+        return -1;  /* unsupported quantization */
 
     if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
         return AVERROR_INVALIDDATA;
 
-    size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
+    size    = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
     half_ch = sys->difseg_size / 2;
 
     /* We work with 720p frames split in half, thus even frames have
@@ -158,32 +158,41 @@ static int dv_extract_audio(uint8_t *frame, uint8_t **ppcm,
             for (j = 0; j < 9; j++) {
                 for (d = 8; d < 80; d += 2) {
                     if (quant == 0) {  /* 16bit quantization */
-                        of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
-                        if (of*2 >= size)
+                        of = sys->audio_shuffle[i][j] +
+                             (d - 8) / 2 * sys->audio_stride;
+                        if (of * 2 >= size)
                             continue;
 
-                        pcm[of*2]   = frame[d+1]; // FIXME: maybe we have to admit
-                        pcm[of*2+1] = frame[d];   //        that DV is a big-endian PCM
-                        if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
-                            pcm[of*2+1] = 0;
+                        /* FIXME: maybe we have to admit that DV is a
+                         * big-endian PCM */
+                        pcm[of * 2]     = frame[d + 1];
+                        pcm[of * 2 + 1] = frame[d];
+
+                        if (pcm[of * 2 + 1] == 0x80 && pcm[of * 2] == 0x00)
+                            pcm[of * 2 + 1] = 0;
                     } else {           /* 12bit quantization */
-                        lc = ((uint16_t)frame[d]   << 4) |
-                             ((uint16_t)frame[d+2] >> 4);
-                        rc = ((uint16_t)frame[d+1] << 4) |
-                             ((uint16_t)frame[d+2] & 0x0f);
+                        lc = ((uint16_t)frame[d]     << 4) |
+                             ((uint16_t)frame[d + 2] >> 4);
+                        rc = ((uint16_t)frame[d + 1] << 4) |
+                             ((uint16_t)frame[d + 2] & 0x0f);
                         lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
                         rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
 
-                        of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
-                        if (of*2 >= size)
+                        of = sys->audio_shuffle[i % half_ch][j] +
+                             (d - 8) / 3 * sys->audio_stride;
+                        if (of * 2 >= size)
                             continue;
 
-                        pcm[of*2]   = lc & 0xff; // FIXME: maybe we have to admit
-                        pcm[of*2+1] = lc >> 8;   //        that DV is a big-endian PCM
-                        of = sys->audio_shuffle[i%half_ch+half_ch][j] +
-                            (d - 8) / 3 * sys->audio_stride;
-                        pcm[of*2]   = rc & 0xff; // FIXME: maybe we have to admit
-                        pcm[of*2+1] = rc >> 8;   //        that DV is a big-endian PCM
+                        /* FIXME: maybe we have to admit that DV is a
+                         * big-endian PCM */
+                        pcm[of * 2]     = lc & 0xff;
+                        pcm[of * 2 + 1] = lc >> 8;
+                        of = sys->audio_shuffle[i % half_ch + half_ch][j] +
+                             (d - 8) / 3 * sys->audio_stride;
+                        /* FIXME: maybe we have to admit that DV is a
+                         * big-endian PCM */
+                        pcm[of * 2]     = rc & 0xff;
+                        pcm[of * 2 + 1] = rc >> 8;
                         ++d;
                     }
                 }
@@ -196,9 +205,9 @@ static int dv_extract_audio(uint8_t *frame, uint8_t **ppcm,
     return size;
 }
 
-static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
+static int dv_extract_audio_info(DVDemuxContext *c, uint8_t *frame)
 {
-    const uint8_t* as_pack;
+    const uint8_t *as_pack;
     int freq, stype, smpls, quant, i, ach;
 
     as_pack = dv_extract_pack(frame, dv_audio_source);
@@ -207,10 +216,10 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
         return 0;
     }
 
-    smpls =  as_pack[1] & 0x3f;       /* samples in this frame - min. samples */
-    freq  = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
-    stype = (as_pack[3] & 0x1f);      /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
-    quant =  as_pack[4] & 0x07;       /* 0 - 16bit linear, 1 - 12bit nonlinear */
+    smpls = as_pack[1]      & 0x3f; /* samples in this frame - min. samples */
+    freq  = as_pack[4] >> 3 & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */
+    stype = as_pack[3]      & 0x1f; /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
+    quant = as_pack[4]      & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
 
     if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) {
         av_log(c->fctx, AV_LOG_ERROR,
@@ -225,7 +234,7 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
     }
 
     /* note: ach counts PAIRS of channels (i.e. stereo channels) */
-    ach = ((int[4]){  1,  0,  2,  4})[stype];
+    ach = ((int[4]) { 1, 0, 2, 4 })[stype];
     if (ach == 1 && quant && freq == 2)
         ach = 2;
 
@@ -245,21 +254,21 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
             c->audio_pkt[i].stream_index = c->ast[i]->index;
             c->audio_pkt[i].flags       |= AV_PKT_FLAG_KEY;
         }
-        c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
-        c->ast[i]->codec->channels    = 2;
+        c->ast[i]->codec->sample_rate    = dv_audio_frequency[freq];
+        c->ast[i]->codec->channels       = 2;
         c->ast[i]->codec->channel_layout = AV_CH_LAYOUT_STEREO;
-        c->ast[i]->codec->bit_rate    = 2 * dv_audio_frequency[freq] * 16;
-        c->ast[i]->start_time         = 0;
+        c->ast[i]->codec->bit_rate       = 2 * dv_audio_frequency[freq] * 16;
+        c->ast[i]->start_time            = 0;
     }
     c->ach = i;
 
-    return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */;
+    return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
 }
 
-static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
+static int dv_extract_video_info(DVDemuxContext *c, uint8_t *frame)
 {
-    const uint8_t* vsc_pack;
-    AVCodecContext* avctx;
+    const uint8_t *vsc_pack;
+    AVCodecContext *avctx;
     int apt, is16_9;
     int size = 0;
 
@@ -268,9 +277,9 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
 
         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->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;
@@ -281,18 +290,17 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
         is16_9   = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
                                  (!apt && (vsc_pack[2] & 0x07) == 0x07)));
         c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
-        avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
+        avctx->bit_rate = av_rescale_q(c->sys->frame_size,
+                                       (AVRational) { 8, 1 },
                                        c->sys->time_base);
         size = c->sys->frame_size;
     }
     return size;
 }
 
-/*
- * The following 3 functions constitute our interface to the world
- */
+/* The following 3 functions constitute our interface to the world */
 
-DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
+DVDemuxContext *avpriv_dv_init_demux(AVFormatContext *s)
 {
     DVDemuxContext *c;
 
@@ -322,9 +330,9 @@ int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
 
     for (i = 0; i < c->ach; i++) {
         if (c->ast[i] && c->audio_pkt[i].size) {
-            *pkt = c->audio_pkt[i];
+            *pkt                 = c->audio_pkt[i];
             c->audio_pkt[i].size = 0;
-            size = pkt->size;
+            size                 = pkt->size;
             break;
         }
     }
@@ -333,7 +341,7 @@ int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
 }
 
 int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
-                      uint8_t* buf, int buf_size)
+                             uint8_t *buf, int buf_size)
 {
     int size, i;
     uint8_t *ppcm[5] = { 0 };
@@ -349,7 +357,8 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
     size = dv_extract_audio_info(c, buf);
     for (i = 0; i < c->ach; i++) {
         c->audio_pkt[i].size = size;
-        c->audio_pkt[i].pts  = c->abytes * 30000 * 8 / c->ast[i]->codec->bit_rate;
+        c->audio_pkt[i].pts  = c->abytes * 30000 * 8 /
+                               c->ast[i]->codec->bit_rate;
         ppcm[i] = c->audio_buf[i];
     }
     if (c->ach)
@@ -362,7 +371,7 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
             c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
         } else {
             c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
-            c->abytes += size;
+            c->abytes           += size;
         }
     } else {
         c->abytes += size;
@@ -383,28 +392,31 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
 }
 
 static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
-                              int64_t timestamp, int flags)
+                               int64_t timestamp, int flags)
 {
     // FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk)
-    const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
+    const DVprofile *sys = avpriv_dv_codec_profile(c->vst->codec);
     int64_t offset;
-    int64_t size = avio_size(s->pb) - s->data_offset;
-    int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
+    int64_t size       = avio_size(s->pb) - s->data_offset;
+    int64_t max_offset = ((size - 1) / sys->frame_size) * sys->frame_size;
 
     offset = sys->frame_size * timestamp;
 
-    if (size >= 0 && offset > max_offset) offset = max_offset;
-    else if (offset < 0) offset = 0;
+    if (size >= 0 && offset > max_offset)
+        offset = max_offset;
+    else if (offset < 0)
+        offset = 0;
 
     return offset + s->data_offset;
 }
 
 void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
 {
-    c->frames= frame_offset;
+    c->frames = frame_offset;
     if (c->ach)
-        c->abytes= av_rescale_q(c->frames, c->sys->time_base,
-                                (AVRational){8, c->ast[0]->codec->bit_rate});
+        c->abytes = av_rescale_q(c->frames, c->sys->time_base,
+                                 (AVRational) { 8, c->ast[0]->codec->bit_rate });
+
     c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
     c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
 }
@@ -414,7 +426,7 @@ void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
  ************************************************************/
 
 typedef struct RawDVContext {
-    DVDemuxContext* dv_demux;
+    DVDemuxContext *dv_demux;
     uint8_t         buf[DV_MAX_FRAME_SIZE];
 } RawDVContext;
 
@@ -448,19 +460,22 @@ static int dv_read_header(AVFormatContext *s)
         avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
         return AVERROR(EIO);
 
-    c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
+    c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys,
+                                               c->buf,
+                                               DV_PROFILE_BYTES);
     if (!c->dv_demux->sys) {
-        av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
+        av_log(s, AV_LOG_ERROR,
+               "Can't determine profile of DV input stream.\n");
         return -1;
     }
 
-    s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
+    s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size,
+                               (AVRational) { 8, 1 },
                                c->dv_demux->sys->time_base);
 
     return 0;
 }
 
-
 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int size;
@@ -482,7 +497,7 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
 }
 
 static int dv_read_seek(AVFormatContext *s, int stream_index,
-                       int64_t timestamp, int flags)
+                        int64_t timestamp, int flags)
 {
     RawDVContext *r   = s->priv_data;
     DVDemuxContext *c = r->dv_demux;
@@ -506,7 +521,7 @@ static int dv_probe(AVProbeData *p)
 {
     unsigned state, marker_pos = 0;
     int i;
-    int matches = 0;
+    int matches           = 0;
     int secondary_matches = 0;
 
     if (p->buf_size < 5)
@@ -527,10 +542,13 @@ static int dv_probe(AVProbeData *p)
         state = (state << 8) | p->buf[i];
     }
 
-    if (matches && p->buf_size / matches < 1024*1024) {
-        if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000))
-            return AVPROBE_SCORE_MAX*3/4; // not max to avoid dv in mov to match
-        return AVPROBE_SCORE_MAX/4;
+    if (matches && p->buf_size / matches < 1024 * 1024) {
+        if (matches > 4 ||
+            (secondary_matches >= 10 &&
+             p->buf_size / secondary_matches < 24000))
+            // not max to avoid dv in mov to match
+            return AVPROBE_SCORE_MAX * 3 / 4;
+        return AVPROBE_SCORE_MAX / 4;
     }
     return 0;
 }
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index a991cc6..66d848c 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -33,7 +33,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "libavcodec/dv_profile.h"
-#include "libavcodec/dvdata.h"
+#include "libavcodec/dv.h"
 #include "dv.h"
 #include "libavutil/fifo.h"
 #include "libavutil/mathematics.h"
@@ -388,7 +388,6 @@ static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt)
                               pkt->data, pkt->size, &frame);
     if (fsize > 0) {
         avio_write(s->pb, frame, fsize);
-        avio_flush(s->pb);
     }
     return 0;
 }
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index b85b4c2..9d00c2d 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -30,35 +30,35 @@
 #include "internal.h"
 
 #define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
-#define SEAD_TAG MKTAG('S', 'E', 'A', 'D')    /* Sxxx header */
-#define SNDC_TAG MKTAG('S', 'N', 'D', 'C')    /* Sxxx data */
-#define SEND_TAG MKTAG('S', 'E', 'N', 'D')    /* Sxxx end */
-#define SHEN_TAG MKTAG('S', 'H', 'E', 'N')    /* SxEN header */
-#define SDEN_TAG MKTAG('S', 'D', 'E', 'N')    /* SxEN data */
-#define SEEN_TAG MKTAG('S', 'E', 'E', 'N')    /* SxEN end */
-#define ISNh_TAG MKTAG('1', 'S', 'N', 'h')    /* 1SNx header */
+#define SEAD_TAG MKTAG('S', 'E', 'A', 'D')  /* Sxxx header */
+#define SNDC_TAG MKTAG('S', 'N', 'D', 'C')  /* Sxxx data */
+#define SEND_TAG MKTAG('S', 'E', 'N', 'D')  /* Sxxx end */
+#define SHEN_TAG MKTAG('S', 'H', 'E', 'N')  /* SxEN header */
+#define SDEN_TAG MKTAG('S', 'D', 'E', 'N')  /* SxEN data */
+#define SEEN_TAG MKTAG('S', 'E', 'E', 'N')  /* SxEN end */
+#define ISNh_TAG MKTAG('1', 'S', 'N', 'h')  /* 1SNx header */
 #define EACS_TAG MKTAG('E', 'A', 'C', 'S')
-#define ISNd_TAG MKTAG('1', 'S', 'N', 'd')    /* 1SNx data */
-#define ISNe_TAG MKTAG('1', 'S', 'N', 'e')    /* 1SNx end */
+#define ISNd_TAG MKTAG('1', 'S', 'N', 'd')  /* 1SNx data */
+#define ISNe_TAG MKTAG('1', 'S', 'N', 'e')  /* 1SNx end */
 #define PT00_TAG MKTAG('P', 'T', 0x0, 0x0)
 #define GSTR_TAG MKTAG('G', 'S', 'T', 'R')
 #define SCDl_TAG MKTAG('S', 'C', 'D', 'l')
 #define SCEl_TAG MKTAG('S', 'C', 'E', 'l')
-#define kVGT_TAG MKTAG('k', 'V', 'G', 'T')    /* TGV i-frame */
-#define fVGT_TAG MKTAG('f', 'V', 'G', 'T')    /* TGV p-frame */
-#define mTCD_TAG MKTAG('m', 'T', 'C', 'D')    /* MDEC */
-#define MADk_TAG MKTAG('M', 'A', 'D', 'k')    /* MAD i-frame */
-#define MADm_TAG MKTAG('M', 'A', 'D', 'm')    /* MAD p-frame */
-#define MADe_TAG MKTAG('M', 'A', 'D', 'e')    /* MAD lqp-frame */
-#define MPCh_TAG MKTAG('M', 'P', 'C', 'h')    /* MPEG2 */
-#define TGQs_TAG MKTAG('T', 'G', 'Q', 's')    /* TGQ i-frame (appears in .TGQ files) */
-#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T')    /* TGQ i-frame (appears in .UV files) */
-#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T')    /* TQI/UV2 i-frame (.UV2/.WVE) */
+#define kVGT_TAG MKTAG('k', 'V', 'G', 'T')  /* TGV I-frame */
+#define fVGT_TAG MKTAG('f', 'V', 'G', 'T')  /* TGV P-frame */
+#define mTCD_TAG MKTAG('m', 'T', 'C', 'D')  /* MDEC */
+#define MADk_TAG MKTAG('M', 'A', 'D', 'k')  /* MAD I-frame */
+#define MADm_TAG MKTAG('M', 'A', 'D', 'm')  /* MAD P-frame */
+#define MADe_TAG MKTAG('M', 'A', 'D', 'e')  /* MAD lqp-frame */
+#define MPCh_TAG MKTAG('M', 'P', 'C', 'h')  /* MPEG-2 */
+#define TGQs_TAG MKTAG('T', 'G', 'Q', 's')  /* TGQ I-frame (appears in .TGQ files) */
+#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T')  /* TGQ I-frame (appears in .UV files) */
+#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T')  /* TQI/UV2 I-frame (.UV2/.WVE) */
 #define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
 #define MV0K_TAG MKTAG('M', 'V', '0', 'K')
 #define MV0F_TAG MKTAG('M', 'V', '0', 'F')
-#define MVIh_TAG MKTAG('M', 'V', 'I', 'h')    /* CMV header */
-#define MVIf_TAG MKTAG('M', 'V', 'I', 'f')    /* CMV i-frame */
+#define MVIh_TAG MKTAG('M', 'V', 'I', 'h')  /* CMV header */
+#define MVIf_TAG MKTAG('M', 'V', 'I', 'f')  /* CMV I-frame */
 
 typedef struct EaDemuxContext {
     int big_endian;
@@ -77,7 +77,8 @@ typedef struct EaDemuxContext {
     int num_samples;
 } EaDemuxContext;
 
-static uint32_t read_arbitary(AVIOContext *pb) {
+static uint32_t read_arbitrary(AVIOContext *pb)
+{
     uint8_t size, byte;
     int i;
     uint32_t word;
@@ -86,136 +87,168 @@ static uint32_t read_arbitary(AVIOContext *pb) {
 
     word = 0;
     for (i = 0; i < size; i++) {
-        byte = avio_r8(pb);
+        byte   = avio_r8(pb);
         word <<= 8;
-        word |= byte;
+        word  |= byte;
     }
 
     return word;
 }
 
-/*
- * Process PT/GSTR sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
 static int process_audio_header_elements(AVFormatContext *s)
 {
-    int inHeader = 1;
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext    *pb = s->pb;
+    int in_header = 1;
     int compression_type = -1, revision = -1, revision2 = -1;
 
-    ea->bytes = 2;
-    ea->sample_rate = -1;
+    ea->bytes        = 2;
+    ea->sample_rate  = -1;
     ea->num_channels = 1;
 
-    while (!pb->eof_reached && inHeader) {
-        int inSubheader;
+    while (!pb->eof_reached && in_header) {
+        int in_subheader;
         uint8_t byte;
         byte = avio_r8(pb);
 
         switch (byte) {
         case 0xFD:
-            av_log (s, AV_LOG_DEBUG, "entered audio subheader\n");
-            inSubheader = 1;
-            while (!pb->eof_reached && inSubheader) {
+            av_log(s, AV_LOG_DEBUG, "entered audio subheader\n");
+            in_subheader = 1;
+            while (!pb->eof_reached && in_subheader) {
                 uint8_t subbyte;
                 subbyte = avio_r8(pb);
 
                 switch (subbyte) {
                 case 0x80:
-                    revision = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "revision (element 0x80) set to 0x%08x\n", revision);
+                    revision = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "revision (element 0x80) set to 0x%08x\n", revision);
                     break;
                 case 0x82:
-                    ea->num_channels = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels);
+                    ea->num_channels = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "num_channels (element 0x82) set to 0x%08x\n",
+                           ea->num_channels);
                     break;
                 case 0x83:
-                    compression_type = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "compression_type (element 0x83) set to 0x%08x\n", compression_type);
+                    compression_type = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "compression_type (element 0x83) set to 0x%08x\n",
+                           compression_type);
                     break;
                 case 0x84:
-                    ea->sample_rate = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "sample_rate (element 0x84) set to %i\n", ea->sample_rate);
+                    ea->sample_rate = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "sample_rate (element 0x84) set to %i\n",
+                           ea->sample_rate);
                     break;
                 case 0x85:
-                    ea->num_samples = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples);
+                    ea->num_samples = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "num_samples (element 0x85) set to 0x%08x\n",
+                           ea->num_samples);
                     break;
                 case 0x8A:
-                    av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
-                    av_log (s, AV_LOG_DEBUG, "exited audio subheader\n");
-                    inSubheader = 0;
+                    av_log(s, AV_LOG_DEBUG,
+                           "element 0x%02x set to 0x%08x\n",
+                           subbyte, read_arbitrary(pb));
+                    av_log(s, AV_LOG_DEBUG, "exited audio subheader\n");
+                    in_subheader = 0;
                     break;
                 case 0xA0:
-                    revision2 = read_arbitary(pb);
-                    av_log (s, AV_LOG_DEBUG, "revision2 (element 0xA0) set to 0x%08x\n", revision2);
+                    revision2 = read_arbitrary(pb);
+                    av_log(s, AV_LOG_DEBUG,
+                           "revision2 (element 0xA0) set to 0x%08x\n",
+                           revision2);
                     break;
                 case 0xFF:
-                    av_log (s, AV_LOG_DEBUG, "end of header block reached (within audio subheader)\n");
-                    inSubheader = 0;
-                    inHeader = 0;
+                    av_log(s, AV_LOG_DEBUG,
+                           "end of header block reached (within audio subheader)\n");
+                    in_subheader = 0;
+                    in_header    = 0;
                     break;
                 default:
-                    av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
+                    av_log(s, AV_LOG_DEBUG,
+                           "element 0x%02x set to 0x%08x\n",
+                           subbyte, read_arbitrary(pb));
                     break;
                 }
             }
             break;
         case 0xFF:
-            av_log (s, AV_LOG_DEBUG, "end of header block reached\n");
-            inHeader = 0;
+            av_log(s, AV_LOG_DEBUG, "end of header block reached\n");
+            in_header = 0;
             break;
         default:
-            av_log (s, AV_LOG_DEBUG, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb));
+            av_log(s, AV_LOG_DEBUG,
+                   "header element 0x%02x set to 0x%08x\n",
+                   byte, read_arbitrary(pb));
             break;
         }
     }
 
     switch (compression_type) {
-    case  0: ea->audio_codec = AV_CODEC_ID_PCM_S16LE; break;
-    case  7: ea->audio_codec = AV_CODEC_ID_ADPCM_EA; break;
+    case  0:
+        ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
+        break;
+    case  7:
+        ea->audio_codec = AV_CODEC_ID_ADPCM_EA;
+        break;
     case -1:
         switch (revision) {
-        case  1: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1; break;
-        case  2: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break;
-        case  3: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3; break;
-        case -1: break;
+        case  1:
+            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1;
+            break;
+        case  2:
+            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2;
+            break;
+        case  3:
+            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3;
+            break;
+        case -1:
+            break;
         default:
-            av_log(s, AV_LOG_ERROR, "unsupported stream type; revision=%i\n", revision);
+            av_log(s, AV_LOG_ERROR,
+                   "unsupported stream type; revision=%i\n", revision);
             return 0;
         }
         switch (revision2) {
-        case  8: ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR; break;
-        case 10: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break;
-        case 16: ea->audio_codec = AV_CODEC_ID_MP3; break;
-        case -1: break;
+        case  8:
+            ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR;
+            break;
+        case 10:
+            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2;
+            break;
+        case 16:
+            ea->audio_codec = AV_CODEC_ID_MP3;
+            break;
+        case -1:
+            break;
         default:
             ea->audio_codec = AV_CODEC_ID_NONE;
-            av_log(s, AV_LOG_ERROR, "unsupported stream type; revision2=%i\n", revision2);
+            av_log(s, AV_LOG_ERROR,
+                   "unsupported stream type; revision2=%i\n", revision2);
             return 0;
         }
         break;
     default:
-        av_log(s, AV_LOG_ERROR, "unsupported stream type; compression_type=%i\n", compression_type);
+        av_log(s, AV_LOG_ERROR,
+               "unsupported stream type; compression_type=%i\n",
+               compression_type);
         return 0;
     }
 
     if (ea->sample_rate == -1)
-        ea->sample_rate = revision==3 ? 48000 : 22050;
+        ea->sample_rate = revision == 3 ? 48000 : 22050;
 
     return 1;
 }
 
-/*
- * Process EACS sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
-static int process_audio_header_eacs(AVFormatContext *s)
+static void process_audio_header_eacs(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
     int compression_type;
 
     ea->sample_rate  = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
@@ -227,62 +260,62 @@ static int process_audio_header_eacs(AVFormatContext *s)
     switch (compression_type) {
     case 0:
         switch (ea->bytes) {
-        case 1: ea->audio_codec = AV_CODEC_ID_PCM_S8;    break;
-        case 2: ea->audio_codec = AV_CODEC_ID_PCM_S16LE; break;
+        case 1:
+            ea->audio_codec = AV_CODEC_ID_PCM_S8;
+            break;
+        case 2:
+            ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
+            break;
         }
         break;
-    case 1: ea->audio_codec = AV_CODEC_ID_PCM_MULAW; ea->bytes = 1; break;
-    case 2: ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS; break;
+    case 1:
+        ea->audio_codec = AV_CODEC_ID_PCM_MULAW;
+        ea->bytes       = 1;
+        break;
+    case 2:
+        ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS;
+        break;
     default:
-        av_log (s, AV_LOG_ERROR, "unsupported stream type; audio compression_type=%i\n", compression_type);
+        av_log(s, AV_LOG_ERROR,
+               "unsupported stream type; audio compression_type=%i\n",
+               compression_type);
     }
-
-    return 1;
 }
 
-/*
- * Process SEAD sound header
- * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
- */
-static int process_audio_header_sead(AVFormatContext *s)
+static void process_audio_header_sead(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
 
     ea->sample_rate  = avio_rl32(pb);
     ea->bytes        = avio_rl32(pb);  /* 1=8-bit, 2=16-bit */
     ea->num_channels = avio_rl32(pb);
     ea->audio_codec  = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
-
-    return 1;
 }
 
-static int process_video_header_mdec(AVFormatContext *s)
+static void process_video_header_mdec(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
     avio_skip(pb, 4);
-    ea->width  = avio_rl16(pb);
-    ea->height = avio_rl16(pb);
-    ea->time_base = (AVRational){1,15};
+    ea->width       = avio_rl16(pb);
+    ea->height      = avio_rl16(pb);
+    ea->time_base   = (AVRational) { 1, 15 };
     ea->video_codec = AV_CODEC_ID_MDEC;
-    return 1;
 }
 
-static int process_video_header_vp6(AVFormatContext *s)
+static void process_video_header_vp6(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
 
     avio_skip(pb, 16);
     ea->time_base.den = avio_rl32(pb);
     ea->time_base.num = avio_rl32(pb);
-    ea->video_codec = AV_CODEC_ID_VP6;
-
-    return 1;
+    ea->video_codec   = AV_CODEC_ID_VP6;
 }
 
-static int process_video_header_cmv(AVFormatContext *s)
+static void process_video_header_cmv(AVFormatContext *s)
 {
     EaDemuxContext *ea = s->priv_data;
     int fps;
@@ -290,91 +323,88 @@ static int process_video_header_cmv(AVFormatContext *s)
     avio_skip(s->pb, 10);
     fps = avio_rl16(s->pb);
     if (fps)
-        ea->time_base = (AVRational){1, fps};
+        ea->time_base = (AVRational) { 1, fps };
     ea->video_codec = AV_CODEC_ID_CMV;
-
-    return 0;
 }
 
-/*
- * Process EA file header
- * Returns 1 if the EA file is valid and successfully opened, 0 otherwise
- */
-static int process_ea_header(AVFormatContext *s) {
+/* Process EA file header.
+ * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
+static int process_ea_header(AVFormatContext *s)
+{
     uint32_t blockid, size = 0;
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
+    AVIOContext *pb    = s->pb;
     int i;
 
-    for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) {
+    for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) {
         unsigned int startpos = avio_tell(pb);
-        int err = 0;
+        int err               = 0;
 
         blockid = avio_rl32(pb);
-        size = avio_rl32(pb);
+        size    = avio_rl32(pb);
         if (i == 0)
             ea->big_endian = size > 0x000FFFFF;
         if (ea->big_endian)
             size = av_bswap32(size);
 
         switch (blockid) {
-            case ISNh_TAG:
-                if (avio_rl32(pb) != EACS_TAG) {
-                    av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n");
-                    return 0;
-                }
-                err = process_audio_header_eacs(s);
-                break;
+        case ISNh_TAG:
+            if (avio_rl32(pb) != EACS_TAG) {
+                av_log(s, AV_LOG_ERROR, "unknown 1SNh headerid\n");
+                return 0;
+            }
+            process_audio_header_eacs(s);
+            break;
 
-            case SCHl_TAG :
-            case SHEN_TAG :
-                blockid = avio_rl32(pb);
-                if (blockid == GSTR_TAG) {
-                    avio_skip(pb, 4);
-                } else if ((blockid & 0xFFFF)!=PT00_TAG) {
-                    av_log (s, AV_LOG_ERROR, "unknown SCHl headerid\n");
-                    return 0;
-                }
-                err = process_audio_header_elements(s);
-                break;
+        case SCHl_TAG:
+        case SHEN_TAG:
+            blockid = avio_rl32(pb);
+            if (blockid == GSTR_TAG) {
+                avio_skip(pb, 4);
+            } else if ((blockid & 0xFFFF) != PT00_TAG) {
+                av_log(s, AV_LOG_ERROR, "unknown SCHl headerid\n");
+                return 0;
+            }
+            err = process_audio_header_elements(s);
+            break;
 
-            case SEAD_TAG:
-                err = process_audio_header_sead(s);
-                break;
+        case SEAD_TAG:
+            process_audio_header_sead(s);
+            break;
 
-            case MVIh_TAG :
-                err = process_video_header_cmv(s);
-                break;
+        case MVIh_TAG:
+            process_video_header_cmv(s);
+            break;
 
-            case kVGT_TAG:
-                ea->video_codec = AV_CODEC_ID_TGV;
-                ea->time_base = (AVRational){1, 15};
-                break;
+        case kVGT_TAG:
+            ea->video_codec = AV_CODEC_ID_TGV;
+            ea->time_base   = (AVRational) { 1, 15 };
+            break;
 
-            case mTCD_TAG :
-                err = process_video_header_mdec(s);
-                break;
+        case mTCD_TAG:
+            process_video_header_mdec(s);
+            break;
 
-            case MPCh_TAG:
-                ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
-                break;
+        case MPCh_TAG:
+            ea->video_codec = AV_CODEC_ID_MPEG2VIDEO;
+            break;
 
-            case pQGT_TAG:
-            case TGQs_TAG:
-                ea->video_codec = AV_CODEC_ID_TGQ;
-                break;
+        case pQGT_TAG:
+        case TGQs_TAG:
+            ea->video_codec = AV_CODEC_ID_TGQ;
+            break;
 
-            case pIQT_TAG:
-                ea->video_codec = AV_CODEC_ID_TQI;
-                break;
+        case pIQT_TAG:
+            ea->video_codec = AV_CODEC_ID_TQI;
+            break;
 
-            case MADk_TAG :
-                ea->video_codec = AV_CODEC_ID_MAD;
-                break;
+        case MADk_TAG:
+            ea->video_codec = AV_CODEC_ID_MAD;
+            break;
 
-            case MVhd_TAG :
-                err = process_video_header_vp6(s);
-                break;
+        case MVhd_TAG:
+            process_video_header_vp6(s);
+            break;
         }
 
         if (err < 0) {
@@ -390,7 +420,6 @@ static int process_ea_header(AVFormatContext *s) {
     return 1;
 }
 
-
 static int ea_probe(AVProbeData *p)
 {
     switch (AV_RL32(&p->buf[0])) {
@@ -409,6 +438,7 @@ static int ea_probe(AVProbeData *p)
     }
     if (AV_RL32(&p->buf[4]) > 0xfffff && AV_RB32(&p->buf[4]) > 0xfffff)
         return 0;
+
     return AVPROBE_SCORE_MAX;
 }
 
@@ -426,16 +456,14 @@ static int ea_read_header(AVFormatContext *s)
         if (!st)
             return AVERROR(ENOMEM);
         ea->video_stream_index = st->index;
-        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-        st->codec->codec_id = ea->video_codec;
-        st->codec->codec_tag = 0;  /* no fourcc */
-        st->codec->width = ea->width;
-        st->codec->height = ea->height;
+        st->codec->codec_type  = AVMEDIA_TYPE_VIDEO;
+        st->codec->codec_id    = ea->video_codec;
+        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->r_frame_rate =
-#endif
-        st->avg_frame_rate = (AVRational){ea->time_base.den, ea->time_base.num};
+        st->avg_frame_rate     = (AVRational) { ea->time_base.den,
+                                                ea->time_base.num };
     }
 
     if (ea->audio_codec) {
@@ -446,12 +474,14 @@ static int ea_read_header(AVFormatContext *s)
             return 1;
         }
         if (ea->sample_rate <= 0) {
-            av_log(s, AV_LOG_ERROR, "Unsupported sample rate: %d\n", ea->sample_rate);
+            av_log(s, AV_LOG_ERROR,
+                   "Unsupported sample rate: %d\n", ea->sample_rate);
             ea->audio_codec = 0;
             return 1;
         }
         if (ea->bytes <= 0) {
-            av_log(s, AV_LOG_ERROR, "Invalid number of bytes per sample: %d\n", ea->bytes);
+            av_log(s, AV_LOG_ERROR,
+                   "Invalid number of bytes per sample: %d\n", ea->bytes);
             ea->audio_codec = AV_CODEC_ID_NONE;
             return 1;
         }
@@ -461,31 +491,30 @@ static int ea_read_header(AVFormatContext *s)
         if (!st)
             return AVERROR(ENOMEM);
         avpriv_set_pts_info(st, 33, 1, ea->sample_rate);
-        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-        st->codec->codec_id = ea->audio_codec;
-        st->codec->codec_tag = 0;  /* no tag */
-        st->codec->channels = ea->num_channels;
-        st->codec->sample_rate = ea->sample_rate;
+        st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
+        st->codec->codec_id              = ea->audio_codec;
+        st->codec->codec_tag             = 0;   /* no tag */
+        st->codec->channels              = ea->num_channels;
+        st->codec->sample_rate           = ea->sample_rate;
         st->codec->bits_per_coded_sample = ea->bytes * 8;
-        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
-            st->codec->bits_per_coded_sample / 4;
-        st->codec->block_align = st->codec->channels*st->codec->bits_per_coded_sample;
-        ea->audio_stream_index = st->index;
-        st->start_time = 0;
+        st->codec->bit_rate              = st->codec->channels *
+                                           st->codec->sample_rate *
+                                           st->codec->bits_per_coded_sample / 4;
+        st->codec->block_align           = st->codec->channels *
+                                           st->codec->bits_per_coded_sample;
+        ea->audio_stream_index           = st->index;
+        st->start_time                   = 0;
     }
 
     return 1;
 }
 
-static int ea_read_packet(AVFormatContext *s,
-                          AVPacket *pkt)
+static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     EaDemuxContext *ea = s->priv_data;
-    AVIOContext *pb = s->pb;
-    int ret = 0;
-    int packet_read = 0;
+    AVIOContext *pb    = s->pb;
     unsigned int chunk_type, chunk_size;
-    int key = 0;
+    int ret = 0, packet_read = 0, key = 0;
     int av_uninit(num_samples);
 
     while (!packet_read) {
@@ -498,7 +527,7 @@ static int ea_read_packet(AVFormatContext *s,
         switch (chunk_type) {
         /* audio data */
         case ISNh_TAG:
-            /* header chunk also contains data; skip over the header portion*/
+            /* header chunk also contains data; skip over the header portion */
             if (chunk_size < 32)
                 return AVERROR_INVALIDDATA;
             avio_skip(pb, 32);
@@ -557,7 +586,7 @@ static int ea_read_packet(AVFormatContext *s,
         case SCEl_TAG:
         case SEND_TAG:
         case SEEN_TAG:
-            ret = AVERROR(EIO);
+            ret         = AVERROR(EIO);
             packet_read = 1;
             break;
 
@@ -571,12 +600,12 @@ static int ea_read_packet(AVFormatContext *s,
         case fVGT_TAG:
         case MADm_TAG:
         case MADe_TAG:
-            avio_seek(pb, -8, SEEK_CUR);     // include chunk preamble
+            avio_seek(pb, -8, SEEK_CUR);    // include chunk preamble
             chunk_size += 8;
             goto get_video_packet;
 
         case mTCD_TAG:
-            avio_skip(pb, 8);  // skip ea dct header
+            avio_skip(pb, 8);               // skip ea DCT header
             chunk_size -= 8;
             goto get_video_packet;
 
@@ -590,8 +619,8 @@ get_video_packet:
             if (ret < 0)
                 return ret;
             pkt->stream_index = ea->video_stream_index;
-            pkt->flags |= key;
-            packet_read = 1;
+            pkt->flags       |= key;
+            packet_read       = 1;
             break;
 
         default:
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index e6730eb..acc1dc4 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavutil/intreadwrite.h"
 #include "libavutil/intfloat.h"
 #include "avformat.h"
diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index 386487f..91658e1 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -245,4 +245,5 @@ AVOutputFormat ff_ffm_muxer = {
     .write_header      = ffm_write_header,
     .write_packet      = ffm_write_packet,
     .write_trailer     = ffm_write_trailer,
+    .flags             = AVFMT_TS_NEGATIVE,
 };
diff --git a/libavformat/file.c b/libavformat/file.c
index c552a9e..2837e9f 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/avstring.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
 #include <fcntl.h>
@@ -110,7 +111,7 @@ static int file_open(URLContext *h, const char *filename, int flags)
 #ifdef O_BINARY
     access |= O_BINARY;
 #endif
-    fd = open(filename, access, 0666);
+    fd = avpriv_open(filename, access, 0666);
     if (fd == -1)
         return AVERROR(errno);
     c->fd = fd;
diff --git a/libavformat/file_open.c b/libavformat/file_open.c
new file mode 100644
index 0000000..494a5d3
--- /dev/null
+++ b/libavformat/file_open.c
@@ -0,0 +1 @@
+#include "libavutil/file_open.c"
diff --git a/libavformat/filmstripdec.c b/libavformat/filmstripdec.c
index 97cecfa..3fa6842 100644
--- a/libavformat/filmstripdec.c
+++ b/libavformat/filmstripdec.c
@@ -55,7 +55,7 @@ static int read_header(AVFormatContext *s)
 
     st->nb_frames = avio_rb32(pb);
     if (avio_rb16(pb) != 0) {
-        av_log_ask_for_sample(s, "unsupported packing method\n");
+        avpriv_request_sample(s, "Unsupported packing method");
         return AVERROR_PATCHWELCOME;
     }
 
diff --git a/libavformat/flac_picture.c b/libavformat/flac_picture.c
new file mode 100644
index 0000000..69d2724
--- /dev/null
+++ b/libavformat/flac_picture.c
@@ -0,0 +1,152 @@
+/*
+ * Raw FLAC picture parser
+ *
+ * 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 "avformat.h"
+#include "flac_picture.h"
+#include "id3v2.h"
+#include "internal.h"
+
+int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
+{
+    const CodecMime *mime = ff_id3v2_mime_tags;
+    enum AVCodecID id = AV_CODEC_ID_NONE;
+    AVBufferRef *data = NULL;
+    uint8_t mimetype[64], *desc = NULL;
+    AVIOContext *pb = NULL;
+    AVStream *st;
+    int type, width, height;
+    int len, ret = 0;
+
+    pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);
+    if (!pb)
+        return AVERROR(ENOMEM);
+
+    /* read the picture type */
+    type = avio_rb32(pb);
+    if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
+        av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
+        if (s->error_recognition & AV_EF_EXPLODE) {
+            ret = AVERROR_INVALIDDATA;
+            goto fail;
+        }
+        type = 0;
+    }
+
+    /* picture mimetype */
+    len = avio_rb32(pb);
+    if (len <= 0 ||
+        avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {
+        av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "
+               "picture.\n");
+        if (s->error_recognition & AV_EF_EXPLODE)
+            ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+    mimetype[len] = 0;
+
+    while (mime->id != AV_CODEC_ID_NONE) {
+        if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
+            id = mime->id;
+            break;
+        }
+        mime++;
+    }
+    if (id == AV_CODEC_ID_NONE) {
+        av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
+               mimetype);
+        if (s->error_recognition & AV_EF_EXPLODE)
+            ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+
+    /* picture description */
+    len = avio_rb32(pb);
+    if (len > 0) {
+        if (!(desc = av_malloc(len + 1))) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+
+        if (avio_read(pb, desc, len) != len) {
+            av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n");
+            if (s->error_recognition & AV_EF_EXPLODE)
+                ret = AVERROR(EIO);
+            goto fail;
+        }
+        desc[len] = 0;
+    }
+
+    /* picture metadata */
+    width  = avio_rb32(pb);
+    height = avio_rb32(pb);
+    avio_skip(pb, 8);
+
+    /* picture data */
+    len = avio_rb32(pb);
+    if (len <= 0) {
+        av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
+        if (s->error_recognition & AV_EF_EXPLODE)
+            ret = AVERROR_INVALIDDATA;
+        goto fail;
+    }
+    if (!(data = av_buffer_alloc(len))) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+    if (avio_read(pb, data->data, len) != len) {
+        av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n");
+        if (s->error_recognition & AV_EF_EXPLODE)
+            ret = AVERROR(EIO);
+        goto fail;
+    }
+
+    st = avformat_new_stream(s, NULL);
+    if (!st) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    av_init_packet(&st->attached_pic);
+    st->attached_pic.buf          = data;
+    st->attached_pic.data         = data->data;
+    st->attached_pic.size         = len;
+    st->attached_pic.stream_index = st->index;
+    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
+
+    st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
+    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_id   = id;
+    st->codec->width      = width;
+    st->codec->height     = height;
+    av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
+    if (desc)
+        av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL);
+
+    av_freep(&pb);
+
+    return 0;
+
+fail:
+    av_buffer_unref(&data);
+    av_freep(&desc);
+    av_freep(&pb);
+
+    return ret;
+}
diff --git a/libavformat/flac_picture.h b/libavformat/flac_picture.h
new file mode 100644
index 0000000..c700582
--- /dev/null
+++ b/libavformat/flac_picture.h
@@ -0,0 +1,28 @@
+/*
+ * Raw FLAC picture parser
+ *
+ * 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 AVFORMAT_FLAC_PICTURE_H
+#define AVFORMAT_FLAC_PICTURE_H
+
+#include "avformat.h"
+
+int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size);
+
+#endif /* AVFORMAT_FLAC_PICTURE_H */
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index fcacf19..ecbb7ec 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -21,140 +21,13 @@
 
 #include "libavcodec/flac.h"
 #include "avformat.h"
-#include "id3v2.h"
+#include "flac_picture.h"
 #include "internal.h"
 #include "rawdec.h"
 #include "oggdec.h"
 #include "vorbiscomment.h"
 #include "libavcodec/bytestream.h"
 
-static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
-{
-    const CodecMime *mime = ff_id3v2_mime_tags;
-    enum  AVCodecID      id = AV_CODEC_ID_NONE;
-    uint8_t mimetype[64], *desc = NULL, *data = NULL;
-    AVIOContext *pb = NULL;
-    AVStream *st;
-    int type, width, height;
-    int len, ret = 0;
-
-    pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);
-    if (!pb)
-        return AVERROR(ENOMEM);
-
-    /* read the picture type */
-    type      = avio_rb32(pb);
-    if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
-        av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
-        if (s->error_recognition & AV_EF_EXPLODE) {
-            ret = AVERROR_INVALIDDATA;
-            goto fail;
-        }
-        type = 0;
-    }
-
-    /* picture mimetype */
-    len  = avio_rb32(pb);
-    if (len <= 0 ||
-        avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {
-        av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "
-               "picture.\n");
-        if (s->error_recognition & AV_EF_EXPLODE)
-            ret = AVERROR_INVALIDDATA;
-        goto fail;
-    }
-    mimetype[len] = 0;
-
-    while (mime->id != AV_CODEC_ID_NONE) {
-        if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {
-            id = mime->id;
-            break;
-        }
-        mime++;
-    }
-    if (id == AV_CODEC_ID_NONE) {
-        av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",
-               mimetype);
-        if (s->error_recognition & AV_EF_EXPLODE)
-            ret = AVERROR_INVALIDDATA;
-        goto fail;
-    }
-
-    /* picture description */
-    len = avio_rb32(pb);
-    if (len > 0) {
-        if (!(desc = av_malloc(len + 1))) {
-            ret = AVERROR(ENOMEM);
-            goto fail;
-        }
-
-        if (avio_read(pb, desc, len) != len) {
-            av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n");
-            if (s->error_recognition & AV_EF_EXPLODE)
-                ret = AVERROR(EIO);
-            goto fail;
-        }
-        desc[len] = 0;
-    }
-
-    /* picture metadata */
-    width  = avio_rb32(pb);
-    height = avio_rb32(pb);
-    avio_skip(pb, 8);
-
-    /* picture data */
-    len = avio_rb32(pb);
-    if (len <= 0) {
-        av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len);
-        if (s->error_recognition & AV_EF_EXPLODE)
-            ret = AVERROR_INVALIDDATA;
-        goto fail;
-    }
-    if (!(data = av_malloc(len))) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-    if (avio_read(pb, data, len) != len) {
-        av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n");
-        if (s->error_recognition & AV_EF_EXPLODE)
-            ret = AVERROR(EIO);
-        goto fail;
-    }
-
-    st = avformat_new_stream(s, NULL);
-    if (!st) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    av_init_packet(&st->attached_pic);
-    st->attached_pic.data         = data;
-    st->attached_pic.size         = len;
-    st->attached_pic.destruct     = av_destruct_packet;
-    st->attached_pic.stream_index = st->index;
-    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
-
-    st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
-    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-    st->codec->codec_id   = id;
-    st->codec->width      = width;
-    st->codec->height     = height;
-    av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);
-    if (desc)
-        av_dict_set(&st->metadata, "title",   desc, AV_DICT_DONT_STRDUP_VAL);
-
-    av_freep(&pb);
-
-    return 0;
-
-fail:
-    av_freep(&desc);
-    av_freep(&data);
-    av_freep(&pb);
-    return ret;
-
-}
-
 static int flac_read_header(AVFormatContext *s)
 {
     int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
@@ -251,7 +124,7 @@ static int flac_read_header(AVFormatContext *s)
                 avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);
             }
         } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
-            ret = parse_picture(s, buffer, metadata_size);
+            ret = ff_flac_parse_picture(s, buffer, metadata_size);
             av_freep(&buffer);
             if (ret < 0) {
                 av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n");
@@ -280,7 +153,7 @@ static int flac_probe(AVProbeData *p)
 {
     if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4))
         return 0;
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 AVInputFormat ff_flac_demuxer = {
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index b770623..1e4042e 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -113,7 +113,6 @@ static int flac_write_trailer(struct AVFormatContext *s)
 static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
 {
     avio_write(s->pb, pkt->data, pkt->size);
-    avio_flush(s->pb);
     return 0;
 }
 
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 2f68653..c65c90c 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -45,12 +45,12 @@
 
 typedef struct {
     const AVClass *class; ///< Class for private options.
-    int trust_metadata; ///< configure streams according onMetaData
-    int wrong_dts; ///< wrong dts due to negative cts
+    int trust_metadata;   ///< configure streams according onMetaData
+    int wrong_dts;        ///< wrong dts due to negative cts
     uint8_t *new_extradata[2];
-    int      new_extradata_size[2];
-    int      last_sample_rate;
-    int      last_channels;
+    int new_extradata_size[2];
+    int last_sample_rate;
+    int last_channels;
     struct {
         int64_t dts;
         int64_t pos;
@@ -64,7 +64,11 @@ static int flv_probe(AVProbeData *p)
     const uint8_t *d;
 
     d = p->buf;
-    if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0 && AV_RB32(d+5)>8) {
+    if (d[0] == 'F' &&
+        d[1] == 'L' &&
+        d[2] == 'V' &&
+        d[3] < 5 && d[5] == 0 &&
+        AV_RB32(d + 5) > 8) {
         return AVPROBE_SCORE_MAX;
     }
     return 0;
@@ -79,10 +83,11 @@ static AVStream *create_stream(AVFormatContext *s, int codec_type)
     avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
     return st;
 }
+
 static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
 {
     int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
-    int flv_codecid = flags & FLV_AUDIO_CODECID_MASK;
+    int flv_codecid           = flags & FLV_AUDIO_CODECID_MASK;
     int codec_id;
 
     if (!acodec->codec_id && !acodec->codec_tag)
@@ -91,18 +96,21 @@ static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
     if (acodec->bits_per_coded_sample != bits_per_coded_sample)
         return 0;
 
-    switch(flv_codecid) {
-        //no distinction between S16 and S8 PCM codec flags
+    switch (flv_codecid) {
+    // no distinction between S16 and S8 PCM codec flags
     case FLV_CODECID_PCM:
-        codec_id = bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 :
+        codec_id = bits_per_coded_sample == 8
+                   ? AV_CODEC_ID_PCM_U8
 #if HAVE_BIGENDIAN
-                            AV_CODEC_ID_PCM_S16BE;
+                   : AV_CODEC_ID_PCM_S16BE;
 #else
-                            AV_CODEC_ID_PCM_S16LE;
+                   : AV_CODEC_ID_PCM_S16LE;
 #endif
         return codec_id == acodec->codec_id;
     case FLV_CODECID_PCM_LE:
-        codec_id = bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : AV_CODEC_ID_PCM_S16LE;
+        codec_id = bits_per_coded_sample == 8
+                   ? AV_CODEC_ID_PCM_U8
+                   : AV_CODEC_ID_PCM_S16LE;
         return codec_id == acodec->codec_id;
     case FLV_CODECID_AAC:
         return acodec->codec_id == AV_CODEC_ID_AAC;
@@ -118,59 +126,72 @@ static int flv_same_audio_codec(AVCodecContext *acodec, int flags)
         return acodec->codec_id == AV_CODEC_ID_NELLYMOSER;
     case FLV_CODECID_PCM_MULAW:
         return acodec->sample_rate == 8000 &&
-               acodec->codec_id == AV_CODEC_ID_PCM_MULAW;
+               acodec->codec_id    == AV_CODEC_ID_PCM_MULAW;
     case FLV_CODECID_PCM_ALAW:
-        return acodec->sample_rate = 8000 &&
-               acodec->codec_id == AV_CODEC_ID_PCM_ALAW;
+        return acodec->sample_rate == 8000 &&
+               acodec->codec_id    == AV_CODEC_ID_PCM_ALAW;
     default:
         return acodec->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
     }
-
-    return 0;
 }
 
-static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecContext *acodec, int flv_codecid) {
-    switch(flv_codecid) {
-        //no distinction between S16 and S8 PCM codec flags
-        case FLV_CODECID_PCM:
-            acodec->codec_id = acodec->bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 :
+static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
+                                AVCodecContext *acodec, int flv_codecid)
+{
+    switch (flv_codecid) {
+    // no distinction between S16 and S8 PCM codec flags
+    case FLV_CODECID_PCM:
+        acodec->codec_id = acodec->bits_per_coded_sample == 8
+                           ? AV_CODEC_ID_PCM_U8
 #if HAVE_BIGENDIAN
-                                AV_CODEC_ID_PCM_S16BE;
+                           : AV_CODEC_ID_PCM_S16BE;
 #else
-                                AV_CODEC_ID_PCM_S16LE;
+                           : AV_CODEC_ID_PCM_S16LE;
 #endif
-            break;
-        case FLV_CODECID_PCM_LE:
-            acodec->codec_id = acodec->bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : AV_CODEC_ID_PCM_S16LE; break;
-        case FLV_CODECID_AAC  : acodec->codec_id = AV_CODEC_ID_AAC;                                    break;
-        case FLV_CODECID_ADPCM: acodec->codec_id = AV_CODEC_ID_ADPCM_SWF;                              break;
-        case FLV_CODECID_SPEEX:
-            acodec->codec_id = AV_CODEC_ID_SPEEX;
-            acodec->sample_rate = 16000;
-            break;
-        case FLV_CODECID_MP3  : acodec->codec_id = AV_CODEC_ID_MP3      ; astream->need_parsing = AVSTREAM_PARSE_FULL; break;
-        case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
-            acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate
-            acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
-            break;
-        case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
-            acodec->sample_rate = 16000;
-            acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
-            break;
-        case FLV_CODECID_NELLYMOSER:
-            acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
-            break;
-        case FLV_CODECID_PCM_MULAW:
-            acodec->sample_rate = 8000;
-            acodec->codec_id = AV_CODEC_ID_PCM_MULAW;
-            break;
-        case FLV_CODECID_PCM_ALAW:
-            acodec->sample_rate = 8000;
-            acodec->codec_id = AV_CODEC_ID_PCM_ALAW;
-            break;
-        default:
-            av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
-            acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
+        break;
+    case FLV_CODECID_PCM_LE:
+        acodec->codec_id = acodec->bits_per_coded_sample == 8
+                           ? AV_CODEC_ID_PCM_U8
+                           : AV_CODEC_ID_PCM_S16LE;
+        break;
+    case FLV_CODECID_AAC:
+        acodec->codec_id = AV_CODEC_ID_AAC;
+        break;
+    case FLV_CODECID_ADPCM:
+        acodec->codec_id = AV_CODEC_ID_ADPCM_SWF;
+        break;
+    case FLV_CODECID_SPEEX:
+        acodec->codec_id    = AV_CODEC_ID_SPEEX;
+        acodec->sample_rate = 16000;
+        break;
+    case FLV_CODECID_MP3:
+        acodec->codec_id      = AV_CODEC_ID_MP3;
+        astream->need_parsing = AVSTREAM_PARSE_FULL;
+        break;
+    case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
+        // in case metadata does not otherwise declare samplerate
+        acodec->sample_rate = 8000;
+        acodec->codec_id    = AV_CODEC_ID_NELLYMOSER;
+        break;
+    case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
+        acodec->sample_rate = 16000;
+        acodec->codec_id    = AV_CODEC_ID_NELLYMOSER;
+        break;
+    case FLV_CODECID_NELLYMOSER:
+        acodec->codec_id = AV_CODEC_ID_NELLYMOSER;
+        break;
+    case FLV_CODECID_PCM_MULAW:
+        acodec->sample_rate = 8000;
+        acodec->codec_id    = AV_CODEC_ID_PCM_MULAW;
+        break;
+    case FLV_CODECID_PCM_ALAW:
+        acodec->sample_rate = 8000;
+        acodec->codec_id    = AV_CODEC_ID_PCM_ALAW;
+        break;
+    default:
+        av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n",
+               flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
+        acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
     }
 }
 
@@ -182,61 +203,69 @@ static int flv_same_video_codec(AVCodecContext *vcodec, int flags)
         return 1;
 
     switch (flv_codecid) {
-        case FLV_CODECID_H263:
-            return vcodec->codec_id == AV_CODEC_ID_FLV1;
-        case FLV_CODECID_SCREEN:
-            return vcodec->codec_id == AV_CODEC_ID_FLASHSV;
-        case FLV_CODECID_SCREEN2:
-            return vcodec->codec_id == AV_CODEC_ID_FLASHSV2;
-        case FLV_CODECID_VP6:
-            return vcodec->codec_id == AV_CODEC_ID_VP6F;
-        case FLV_CODECID_VP6A:
-            return vcodec->codec_id == AV_CODEC_ID_VP6A;
-        case FLV_CODECID_H264:
-            return vcodec->codec_id == AV_CODEC_ID_H264;
-        default:
-            return vcodec->codec_tag == flv_codecid;
+    case FLV_CODECID_H263:
+        return vcodec->codec_id == AV_CODEC_ID_FLV1;
+    case FLV_CODECID_SCREEN:
+        return vcodec->codec_id == AV_CODEC_ID_FLASHSV;
+    case FLV_CODECID_SCREEN2:
+        return vcodec->codec_id == AV_CODEC_ID_FLASHSV2;
+    case FLV_CODECID_VP6:
+        return vcodec->codec_id == AV_CODEC_ID_VP6F;
+    case FLV_CODECID_VP6A:
+        return vcodec->codec_id == AV_CODEC_ID_VP6A;
+    case FLV_CODECID_H264:
+        return vcodec->codec_id == AV_CODEC_ID_H264;
+    default:
+        return vcodec->codec_tag == flv_codecid;
     }
-
-    return 0;
 }
 
-static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid, int read) {
+static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
+                               int flv_codecid, int read)
+{
     AVCodecContext *vcodec = vstream->codec;
-    switch(flv_codecid) {
-        case FLV_CODECID_H263  : vcodec->codec_id = AV_CODEC_ID_FLV1   ; break;
-        case FLV_CODECID_SCREEN: vcodec->codec_id = AV_CODEC_ID_FLASHSV; break;
-        case FLV_CODECID_SCREEN2: vcodec->codec_id = AV_CODEC_ID_FLASHSV2; break;
-        case FLV_CODECID_VP6   : vcodec->codec_id = AV_CODEC_ID_VP6F   ;
-        case FLV_CODECID_VP6A  :
-            if(flv_codecid == FLV_CODECID_VP6A)
-                vcodec->codec_id = AV_CODEC_ID_VP6A;
-            if (read) {
-                if (vcodec->extradata_size != 1) {
-                    vcodec->extradata = av_malloc(1);
-                    if (vcodec->extradata)
-                        vcodec->extradata_size = 1;
-                }
+    switch (flv_codecid) {
+    case FLV_CODECID_H263:
+        vcodec->codec_id = AV_CODEC_ID_FLV1;
+        break;
+    case FLV_CODECID_SCREEN:
+        vcodec->codec_id = AV_CODEC_ID_FLASHSV;
+        break;
+    case FLV_CODECID_SCREEN2:
+        vcodec->codec_id = AV_CODEC_ID_FLASHSV2;
+        break;
+    case FLV_CODECID_VP6:
+        vcodec->codec_id = AV_CODEC_ID_VP6F;
+    case FLV_CODECID_VP6A:
+        if (flv_codecid == FLV_CODECID_VP6A)
+            vcodec->codec_id = AV_CODEC_ID_VP6A;
+        if (read) {
+            if (vcodec->extradata_size != 1) {
+                vcodec->extradata = av_malloc(1);
                 if (vcodec->extradata)
-                    vcodec->extradata[0] = avio_r8(s->pb);
-                else
-                    avio_skip(s->pb, 1);
+                    vcodec->extradata_size = 1;
             }
-            return 1; // 1 byte body size adjustment for flv_read_packet()
-        case FLV_CODECID_H264:
-            vcodec->codec_id = AV_CODEC_ID_H264;
-            return 3; // not 4, reading packet type will consume one byte
-        default:
-            av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
-            vcodec->codec_tag = flv_codecid;
+            if (vcodec->extradata)
+                vcodec->extradata[0] = avio_r8(s->pb);
+            else
+                avio_skip(s->pb, 1);
+        }
+        return 1;     // 1 byte body size adjustment for flv_read_packet()
+    case FLV_CODECID_H264:
+        vcodec->codec_id = AV_CODEC_ID_H264;
+        return 3;     // not 4, reading packet type will consume one byte
+    default:
+        av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
+        vcodec->codec_tag = flv_codecid;
     }
 
     return 0;
 }
 
-static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) {
+static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize)
+{
     int length = avio_rb16(ioc);
-    if(length >= buffsize) {
+    if (length >= buffsize) {
         avio_skip(ioc, length);
         return -1;
     }
@@ -248,21 +277,24 @@ static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) {
     return length;
 }
 
-static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) {
-    FLVContext *flv = s->priv_data;
+static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc,
+                                 AVStream *vstream, int64_t max_pos)
+{
+    FLVContext *flv       = s->priv_data;
     unsigned int arraylen = 0, timeslen = 0, fileposlen = 0, i;
     double num_val;
     char str_val[256];
-    int64_t *times = NULL;
+    int64_t *times         = NULL;
     int64_t *filepositions = NULL;
-    int ret = AVERROR(ENOSYS);
-    int64_t initial_pos = avio_tell(ioc);
+    int ret                = AVERROR(ENOSYS);
+    int64_t initial_pos    = avio_tell(ioc);
 
     if (s->flags & AVFMT_FLAG_IGNIDX)
         return 0;
 
-    while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
-        int64_t* current_array;
+    while (avio_tell(ioc) < max_pos - 2 &&
+           amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
+        int64_t *current_array;
 
         // Expect array object in context
         if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY)
@@ -272,31 +304,32 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
         if (arraylen >> 28)
             break;
 
-        /*
-         * Expect only 'times' or 'filepositions' sub-arrays in other case refuse to use such metadata
-         * for indexing
-         */
+        /* 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;
+            timeslen      = arraylen;
             current_array = times;
-        } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions) {
+        } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) &&
+                   !filepositions) {
             if (!(filepositions = av_mallocz(sizeof(*filepositions) * arraylen))) {
                 ret = AVERROR(ENOMEM);
                 goto finish;
             }
-            fileposlen = arraylen;
+            fileposlen    = arraylen;
             current_array = filepositions;
-        } else // unexpected metatag inside keyframes, will not use such metadata for indexing
+        } else
+            // unexpected metatag inside keyframes, will not use such
+            // metadata for indexing
             break;
 
         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));
+            num_val          = av_int2double(avio_rb64(ioc));
             current_array[i] = num_val;
         }
         if (times && filepositions) {
@@ -309,12 +342,12 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
 
     if (!ret && timeslen == fileposlen) {
         for (i = 0; i < fileposlen; i++) {
-            av_add_index_entry(vstream, filepositions[i], times[i]*1000,
+            av_add_index_entry(vstream, filepositions[i], times[i] * 1000,
                                0, 0, AVINDEX_KEYFRAME);
             if (i < 2) {
                 flv->validate_index[i].pos = filepositions[i];
                 flv->validate_index[i].dts = times[i] * 1000;
-                flv->validate_count = i + 1;
+                flv->validate_count        = i + 1;
             }
         }
     } else
@@ -330,7 +363,10 @@ finish:
     return ret;
 }
 
-static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) {
+static int amf_parse_object(AVFormatContext *s, AVStream *astream,
+                            AVStream *vstream, const char *key,
+                            int64_t max_pos, int depth)
+{
     AVCodecContext *acodec, *vcodec;
     FLVContext *flv = s->priv_data;
     AVIOContext *ioc;
@@ -338,74 +374,84 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
     char str_val[256];
     double num_val;
 
-    num_val = 0;
-    ioc = s->pb;
-
+    num_val  = 0;
+    ioc      = s->pb;
     amf_type = avio_r8(ioc);
 
-    switch(amf_type) {
-        case AMF_DATA_TYPE_NUMBER:
-            num_val = av_int2double(avio_rb64(ioc)); break;
-        case AMF_DATA_TYPE_BOOL:
-            num_val = avio_r8(ioc); break;
-        case AMF_DATA_TYPE_STRING:
-            if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0)
-                return -1;
-            break;
-        case AMF_DATA_TYPE_OBJECT:
-            if ((vstream || astream) && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
-                if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
-                                          max_pos) < 0)
-                    return -1;
-
-            while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
-                if (amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
-                    return -1; //if we couldn't skip, bomb out.
-            }
-            if(avio_r8(ioc) != AMF_END_OF_OBJECT)
-                return -1;
-            break;
-        case AMF_DATA_TYPE_NULL:
-        case AMF_DATA_TYPE_UNDEFINED:
-        case AMF_DATA_TYPE_UNSUPPORTED:
-            break; //these take up no additional space
-        case AMF_DATA_TYPE_MIXEDARRAY:
-            avio_skip(ioc, 4); //skip 32-bit max array index
-            while(avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
-                //this is the only case in which we would want a nested parse to not skip over the object
-                if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
-                    return -1;
-            }
-            if(avio_r8(ioc) != AMF_END_OF_OBJECT)
+    switch (amf_type) {
+    case AMF_DATA_TYPE_NUMBER:
+        num_val = av_int2double(avio_rb64(ioc));
+        break;
+    case AMF_DATA_TYPE_BOOL:
+        num_val = avio_r8(ioc);
+        break;
+    case AMF_DATA_TYPE_STRING:
+        if (amf_get_string(ioc, str_val, sizeof(str_val)) < 0)
+            return -1;
+        break;
+    case AMF_DATA_TYPE_OBJECT:
+        if ((vstream || astream) && key &&
+            !strcmp(KEYFRAMES_TAG, key) && depth == 1)
+            if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
+                                      max_pos) < 0)
                 return -1;
-            break;
-        case AMF_DATA_TYPE_ARRAY: {
-            unsigned int arraylen, i;
 
-            arraylen = avio_rb32(ioc);
-            for(i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
-                if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)
-                    return -1; //if we couldn't skip, bomb out.
-            }
-        }
-            break;
-        case AMF_DATA_TYPE_DATE:
-            avio_skip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16)
-            break;
-        default: //unsupported type, we couldn't skip
+        while (avio_tell(ioc) < max_pos - 2 &&
+               amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
+            if (amf_parse_object(s, astream, vstream, str_val, max_pos,
+                                 depth + 1) < 0)
+                return -1;     // if we couldn't skip, bomb out.
+        if (avio_r8(ioc) != AMF_END_OF_OBJECT)
+            return -1;
+        break;
+    case AMF_DATA_TYPE_NULL:
+    case AMF_DATA_TYPE_UNDEFINED:
+    case AMF_DATA_TYPE_UNSUPPORTED:
+        break;     // these take up no additional space
+    case AMF_DATA_TYPE_MIXEDARRAY:
+        avio_skip(ioc, 4);     // skip 32-bit max array index
+        while (avio_tell(ioc) < max_pos - 2 &&
+               amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
+            // this is the only case in which we would want a nested
+            // parse to not skip over the object
+            if (amf_parse_object(s, astream, vstream, str_val, max_pos,
+                                 depth + 1) < 0)
+                return -1;
+        if (avio_r8(ioc) != AMF_END_OF_OBJECT)
             return -1;
+        break;
+    case AMF_DATA_TYPE_ARRAY:
+    {
+        unsigned int arraylen, i;
+
+        arraylen = avio_rb32(ioc);
+        for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++)
+            if (amf_parse_object(s, NULL, NULL, NULL, max_pos,
+                                 depth + 1) < 0)
+                return -1;      // if we couldn't skip, bomb out.
+    }
+    break;
+    case AMF_DATA_TYPE_DATE:
+        avio_skip(ioc, 8 + 2);  // timestamp (double) and UTC offset (int16)
+        break;
+    default:                    // unsupported type, we couldn't skip
+        return -1;
     }
 
-    if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL
+    // only look for metadata values when we are not nested and key != NULL
+    if (depth == 1 && key) {
         acodec = astream ? astream->codec : NULL;
         vcodec = vstream ? vstream->codec : NULL;
 
-        if (amf_type == AMF_DATA_TYPE_NUMBER || amf_type == AMF_DATA_TYPE_BOOL) {
+        if (amf_type == AMF_DATA_TYPE_NUMBER ||
+            amf_type == AMF_DATA_TYPE_BOOL) {
             if (!strcmp(key, "duration"))
                 s->duration = num_val * AV_TIME_BASE;
-            else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
+            else if (!strcmp(key, "videodatarate") && vcodec &&
+                     0 <= (int)(num_val * 1024.0))
                 vcodec->bit_rate = num_val * 1024.0;
-            else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
+            else if (!strcmp(key, "audiodatarate") && acodec &&
+                     0 <= (int)(num_val * 1024.0))
                 acodec->bit_rate = num_val * 1024.0;
             else if (!strcmp(key, "datastream")) {
                 AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA);
@@ -415,25 +461,21 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
             } else if (flv->trust_metadata) {
                 if (!strcmp(key, "videocodecid") && vcodec) {
                     flv_set_video_codec(s, vstream, num_val, 0);
-                } else
-                if (!strcmp(key, "audiocodecid") && acodec) {
+                } else if (!strcmp(key, "audiocodecid") && acodec) {
                     int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;
                     flv_set_audio_codec(s, astream, acodec, id);
-                } else
-                if (!strcmp(key, "audiosamplerate") && acodec) {
+                } else if (!strcmp(key, "audiosamplerate") && acodec) {
                     acodec->sample_rate = num_val;
                 } else if (!strcmp(key, "audiosamplesize") && acodec) {
                     acodec->bits_per_coded_sample = num_val;
                 } else if (!strcmp(key, "stereo") && acodec) {
-                    acodec->channels = num_val + 1;
+                    acodec->channels       = num_val + 1;
                     acodec->channel_layout = acodec->channels == 2 ?
                                              AV_CH_LAYOUT_STEREO :
                                              AV_CH_LAYOUT_MONO;
-                } else
-                if (!strcmp(key, "width") && vcodec) {
+                } else if (!strcmp(key, "width") && vcodec) {
                     vcodec->width = num_val;
-                } else
-                if (!strcmp(key, "height") && vcodec) {
+                } else if (!strcmp(key, "height") && vcodec) {
                     vcodec->height = num_val;
                 }
             }
@@ -450,13 +492,15 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
             !strcmp(key, "audiosamplerate") ||
             !strcmp(key, "audiosamplesize") ||
             !strcmp(key, "stereo")          ||
-            !strcmp(key, "audiocodecid"))
+            !strcmp(key, "audiocodecid")    ||
+            !strcmp(key, "datastream"))
             return 0;
 
-        if(amf_type == AMF_DATA_TYPE_BOOL) {
-            av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val));
+        if (amf_type == AMF_DATA_TYPE_BOOL) {
+            av_strlcpy(str_val, num_val > 0 ? "true" : "false",
+                       sizeof(str_val));
             av_dict_set(&s->metadata, key, str_val, 0);
-        } else if(amf_type == AMF_DATA_TYPE_NUMBER) {
+        } else if (amf_type == AMF_DATA_TYPE_NUMBER) {
             snprintf(str_val, sizeof(str_val), "%.f", num_val);
             av_dict_set(&s->metadata, key, str_val, 0);
         } else if (amf_type == AMF_DATA_TYPE_STRING)
@@ -466,18 +510,21 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vst
     return 0;
 }
 
-static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
+static int flv_read_metabody(AVFormatContext *s, int64_t next_pos)
+{
     AMFDataType type;
     AVStream *stream, *astream, *vstream;
     AVIOContext *ioc;
     int i;
-    char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want.
+    // only needs to hold the string "onMetaData".
+    // Anything longer is something we don't want.
+    char buffer[11];
 
     astream = NULL;
     vstream = NULL;
-    ioc = s->pb;
+    ioc     = s->pb;
 
-    //first object needs to be "onMetaData" string
+    // first object needs to be "onMetaData" string
     type = avio_r8(ioc);
     if (type != AMF_DATA_TYPE_STRING ||
         amf_get_string(ioc, buffer, sizeof(buffer)) < 0)
@@ -489,15 +536,18 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
     if (strcmp(buffer, "onMetaData"))
         return -1;
 
-    //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
-    for(i = 0; i < s->nb_streams; i++) {
+    // find the streams now so that amf_parse_object doesn't need to do
+    // the lookup every time it is called.
+    for (i = 0; i < s->nb_streams; i++) {
         stream = s->streams[i];
-        if     (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
-        else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
+        if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+            astream = stream;
+        else if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+            vstream = stream;
     }
 
-    //parse the second object (we want a mixed array)
-    if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
+    // parse the second object (we want a mixed array)
+    if (amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
         return -1;
 
     return 0;
@@ -513,19 +563,19 @@ static int flv_read_header(AVFormatContext *s)
     /* FIXME: better fix needed */
     if (!flags) {
         flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO;
-        av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n");
+        av_log(s, AV_LOG_WARNING,
+               "Broken FLV file, which says no streams present, "
+               "this might fail\n");
     }
 
     s->ctx_flags |= AVFMTCTX_NOHEADER;
 
-    if(flags & FLV_HEADER_FLAG_HASVIDEO){
-        if(!create_stream(s, AVMEDIA_TYPE_VIDEO))
+    if (flags & FLV_HEADER_FLAG_HASVIDEO)
+        if (!create_stream(s, AVMEDIA_TYPE_VIDEO))
             return AVERROR(ENOMEM);
-    }
-    if(flags & FLV_HEADER_FLAG_HASAUDIO){
-        if(!create_stream(s, AVMEDIA_TYPE_AUDIO))
+    if (flags & FLV_HEADER_FLAG_HASAUDIO)
+        if (!create_stream(s, AVMEDIA_TYPE_AUDIO))
             return AVERROR(ENOMEM);
-    }
 
     offset = avio_rb32(s->pb);
     avio_seek(s->pb, offset, SEEK_SET);
@@ -559,7 +609,8 @@ static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream,
                                int size)
 {
     av_free(flv->new_extradata[stream]);
-    flv->new_extradata[stream] = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
+    flv->new_extradata[stream] = av_mallocz(size +
+                                            FF_INPUT_BUFFER_PADDING_SIZE);
     if (!flv->new_extradata[stream])
         return AVERROR(ENOMEM);
     flv->new_extradata_size[stream] = size;
@@ -570,51 +621,96 @@ static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream,
 static void clear_index_entries(AVFormatContext *s, int64_t pos)
 {
     int i, j, out;
-    av_log(s, AV_LOG_WARNING, "Found invalid index entries, clearing the index.\n");
+    av_log(s, AV_LOG_WARNING,
+           "Found invalid index entries, clearing the index.\n");
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         /* Remove all index entries that point to >= pos */
         out = 0;
-        for (j = 0; j < st->nb_index_entries; j++) {
+        for (j = 0; j < st->nb_index_entries; j++)
             if (st->index_entries[j].pos < pos)
                 st->index_entries[out++] = st->index_entries[j];
-        }
         st->nb_index_entries = out;
     }
 }
 
+static int amf_skip_tag(AVIOContext *pb, AMFDataType type)
+{
+    int nb = -1, ret, parse_name = 1;
+
+    switch (type) {
+    case AMF_DATA_TYPE_NUMBER:
+        avio_skip(pb, 8);
+        break;
+    case AMF_DATA_TYPE_BOOL:
+        avio_skip(pb, 1);
+        break;
+    case AMF_DATA_TYPE_STRING:
+        avio_skip(pb, avio_rb16(pb));
+        break;
+    case AMF_DATA_TYPE_ARRAY:
+        parse_name = 0;
+    case AMF_DATA_TYPE_MIXEDARRAY:
+        nb = avio_rb32(pb);
+    case AMF_DATA_TYPE_OBJECT:
+        while(!pb->eof_reached && (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY)) {
+            if (parse_name) {
+                int size = avio_rb16(pb);
+                if (!size) {
+                    avio_skip(pb, 1);
+                    break;
+                }
+                avio_skip(pb, size);
+            }
+            if ((ret = amf_skip_tag(pb, avio_r8(pb))) < 0)
+                return ret;
+        }
+        break;
+    case AMF_DATA_TYPE_NULL:
+    case AMF_DATA_TYPE_OBJECT_END:
+        break;
+    default:
+        return AVERROR_INVALIDDATA;
+    }
+    return 0;
+}
 
 static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
                            int64_t dts, int64_t next)
 {
-    int ret = AVERROR_INVALIDDATA, i;
     AVIOContext *pb = s->pb;
-    AVStream *st = NULL;
-    AMFDataType type;
+    AVStream *st    = NULL;
     char buf[20];
-    int length;
+    int ret = AVERROR_INVALIDDATA;
+    int i, length = -1;
 
-    type = avio_r8(pb);
-    if (type == AMF_DATA_TYPE_MIXEDARRAY)
+    switch (avio_r8(pb)) {
+    case AMF_DATA_TYPE_MIXEDARRAY:
         avio_seek(pb, 4, SEEK_CUR);
-    else if (type != AMF_DATA_TYPE_OBJECT)
-        goto out;
-
-    amf_get_string(pb, buf, sizeof(buf));
-    if (strcmp(buf, "type") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-        goto out;
-
-    amf_get_string(pb, buf, sizeof(buf));
-    //FIXME parse it as codec_id
-    amf_get_string(pb, buf, sizeof(buf));
-    if (strcmp(buf, "text") || avio_r8(pb) != AMF_DATA_TYPE_STRING)
-        goto out;
-
-    length = avio_rb16(pb);
-    ret = av_get_packet(s->pb, pkt, length);
-    if (ret < 0) {
-        ret = AVERROR(EIO);
-        goto out;
+    case AMF_DATA_TYPE_OBJECT:
+        break;
+    default:
+        goto skip;
+    }
+
+    while ((ret = amf_get_string(pb, buf, sizeof(buf))) > 0) {
+        AMFDataType type = avio_r8(pb);
+        if (type == AMF_DATA_TYPE_STRING && !strcmp(buf, "text")) {
+            length = avio_rb16(pb);
+            ret    = av_get_packet(pb, pkt, length);
+            if (ret < 0)
+                goto skip;
+            else
+                break;
+        } else {
+            if ((ret = amf_skip_tag(pb, type)) < 0)
+                goto skip;
+        }
+    }
+
+    if (length < 0) {
+        ret = AVERROR_INVALIDDATA;
+        goto skip;
     }
 
     for (i = 0; i < s->nb_streams; i++) {
@@ -626,7 +722,7 @@ static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
     if (i == s->nb_streams) {
         st = create_stream(s, AVMEDIA_TYPE_DATA);
         if (!st)
-            goto out;
+            return AVERROR_INVALIDDATA;
         st->codec->codec_id = AV_CODEC_ID_TEXT;
     }
 
@@ -635,10 +731,11 @@ static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
     pkt->size = ret;
 
     pkt->stream_index = st->index;
-    pkt->flags |= AV_PKT_FLAG_KEY;
+    pkt->flags       |= AV_PKT_FLAG_KEY;
 
+skip:
     avio_seek(s->pb, next + 4, SEEK_SET);
-out:
+
     return ret;
 }
 
@@ -649,137 +746,145 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
     int64_t next, pos;
     int64_t dts, pts = AV_NOPTS_VALUE;
     int sample_rate = 0, channels = 0;
-    AVStream *st = NULL;
-
- for(;;avio_skip(s->pb, 4)){ /* pkt size is repeated at end. skip it */
-    pos = avio_tell(s->pb);
-    type = avio_r8(s->pb);
-    size = avio_rb24(s->pb);
-    dts = avio_rb24(s->pb);
-    dts |= avio_r8(s->pb) << 24;
-    av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
-    if (s->pb->eof_reached)
-        return AVERROR_EOF;
-    avio_skip(s->pb, 3); /* stream id, always 0 */
-    flags = 0;
-
-    if (flv->validate_next < flv->validate_count) {
-        int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
-        if (pos == validate_pos) {
-            if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
-                VALIDATE_INDEX_TS_THRESH) {
-                flv->validate_next++;
-            } else {
+    AVStream *st    = NULL;
+
+    /* pkt size is repeated at end. skip it */
+    for (;; avio_skip(s->pb, 4)) {
+        pos  = avio_tell(s->pb);
+        type = avio_r8(s->pb);
+        size = avio_rb24(s->pb);
+        dts  = avio_rb24(s->pb);
+        dts |= avio_r8(s->pb) << 24;
+        av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
+        if (s->pb->eof_reached)
+            return AVERROR_EOF;
+        avio_skip(s->pb, 3); /* stream id, always 0 */
+        flags = 0;
+
+        if (flv->validate_next < flv->validate_count) {
+            int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
+            if (pos == validate_pos) {
+                if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
+                    VALIDATE_INDEX_TS_THRESH) {
+                    flv->validate_next++;
+                } else {
+                    clear_index_entries(s, validate_pos);
+                    flv->validate_count = 0;
+                }
+            } else if (pos > validate_pos) {
                 clear_index_entries(s, validate_pos);
                 flv->validate_count = 0;
             }
-        } else if (pos > validate_pos) {
-            clear_index_entries(s, validate_pos);
-            flv->validate_count = 0;
         }
-    }
-
-    if(size == 0)
-        continue;
-
-    next= size + avio_tell(s->pb);
-
-    if (type == FLV_TAG_TYPE_AUDIO) {
-        is_audio=1;
-        flags = avio_r8(s->pb);
-        size--;
-    } else if (type == FLV_TAG_TYPE_VIDEO) {
-        is_audio=0;
-        flags = avio_r8(s->pb);
-        size--;
-        if ((flags & 0xf0) == 0x50) /* video info / command frame */
-            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);
-    skip:
-        avio_seek(s->pb, next, SEEK_SET);
-        continue;
-    }
 
-    /* skip empty data packets */
-    if (!size)
-        continue;
+        if (size == 0)
+            continue;
+
+        next = size + avio_tell(s->pb);
+
+        if (type == FLV_TAG_TYPE_AUDIO) {
+            is_audio = 1;
+            flags    = avio_r8(s->pb);
+            size--;
+        } else if (type == FLV_TAG_TYPE_VIDEO) {
+            is_audio = 0;
+            flags    = avio_r8(s->pb);
+            size--;
+            if ((flags & 0xf0) == 0x50) /* video info / command frame */
+                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);
+
+skip:
+            avio_seek(s->pb, next, SEEK_SET);
+            continue;
+        }
 
-    /* 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)) {
-                break;
-            }
-        } else
-        if (!is_audio && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-            if (flv_same_video_codec(st->codec, flags)) {
-                break;
+        /* skip empty data packets */
+        if (!size)
+            continue;
+
+        /* 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))
+                    break;
+            } else if (!is_audio &&
+                       st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+                if (flv_same_video_codec(st->codec, flags))
+                    break;
             }
         }
+        if (i == s->nb_streams)
+            st = create_stream(s, is_audio ? AVMEDIA_TYPE_AUDIO
+                                           : AVMEDIA_TYPE_VIDEO);
+        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)) ||
+            st->discard >= AVDISCARD_ALL) {
+            avio_seek(s->pb, next, SEEK_SET);
+            continue;
+        }
+        if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)
+            av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
+        break;
     }
-    if(i == s->nb_streams){
-        st = create_stream(s,
-            is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO);
-    }
-    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))
-       || st->discard >= AVDISCARD_ALL
-       ){
-        avio_seek(s->pb, next, SEEK_SET);
-        continue;
-    }
-    if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)
-        av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
-    break;
- }
 
-    // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps
-    if(s->pb->seekable && (!s->duration || s->duration==AV_NOPTS_VALUE)){
+    // 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)) {
         int size;
-        const int64_t pos= avio_tell(s->pb);
-        const int64_t fsize= avio_size(s->pb);
-        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){
+        const int64_t pos   = avio_tell(s->pb);
+        const int64_t fsize = avio_size(s->pb);
+        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;
+            ts         |= avio_r8(s->pb) << 24;
             s->duration = ts * (int64_t)AV_TIME_BASE / 1000;
         }
         avio_seek(s->pb, pos, SEEK_SET);
     }
 
-    if(is_audio){
+    if (is_audio) {
         int bits_per_coded_sample;
-        channels    = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
-        sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
+        channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
+        sample_rate = 44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >>
+                                FLV_AUDIO_SAMPLERATE_OFFSET) >> 3;
         bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
-        if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) {
+        if (!st->codec->channels || !st->codec->sample_rate ||
+            !st->codec->bits_per_coded_sample) {
             st->codec->channels              = channels;
-            st->codec->channel_layout        = channels == 1 ? AV_CH_LAYOUT_MONO :
-                                                               AV_CH_LAYOUT_STEREO;
+            st->codec->channel_layout        = channels == 1
+                                               ? AV_CH_LAYOUT_MONO
+                                               : AV_CH_LAYOUT_STEREO;
             st->codec->sample_rate           = sample_rate;
             st->codec->bits_per_coded_sample = bits_per_coded_sample;
         }
-        if(!st->codec->codec_id){
-            flv_set_audio_codec(s, st, st->codec, flags & FLV_AUDIO_CODECID_MASK);
-            flv->last_sample_rate = sample_rate = st->codec->sample_rate;
-            flv->last_channels    = channels    = st->codec->channels;
+        if (!st->codec->codec_id) {
+            flv_set_audio_codec(s, st, st->codec,
+                                flags & FLV_AUDIO_CODECID_MASK);
+            flv->last_sample_rate =
+            sample_rate           = st->codec->sample_rate;
+            flv->last_channels    =
+            channels              = st->codec->channels;
         } else {
             AVCodecContext ctx;
             ctx.sample_rate = sample_rate;
             flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK);
             sample_rate = ctx.sample_rate;
         }
-    }else{
+    } else {
         size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
     }
 
@@ -788,11 +893,13 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
         int type = avio_r8(s->pb);
         size--;
         if (st->codec->codec_id == AV_CODEC_ID_H264) {
-            int32_t cts = (avio_rb24(s->pb)+0xff800000)^0xff800000; // sign extension
+            // sign extension
+            int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
             pts = dts + cts;
             if (cts < 0) { // dts are wrong
                 flv->wrong_dts = 1;
-                av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n");
+                av_log(s, AV_LOG_WARNING,
+                       "negative cts, previous timestamps might be wrong\n");
             }
             if (flv->wrong_dts)
                 dts = AV_NOPTS_VALUE;
@@ -810,7 +917,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
                 MPEG4AudioConfig cfg;
                 avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
                                              st->codec->extradata_size * 8, 1);
-                st->codec->channels = cfg.channels;
+                st->codec->channels       = cfg.channels;
                 st->codec->channel_layout = 0;
                 if (cfg.ext_sample_rate)
                     st->codec->sample_rate = cfg.ext_sample_rate;
@@ -831,15 +938,14 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
         goto leave;
     }
 
-    ret= av_get_packet(s->pb, pkt, size);
-    if (ret < 0) {
+    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;
-    pkt->dts = dts;
-    pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
+     * packet */
+    pkt->size         = ret;
+    pkt->dts          = dts;
+    pkt->pts          = pts == AV_NOPTS_VALUE ? dts : pts;
     pkt->stream_index = st->index;
     if (flv->new_extradata[is_audio]) {
         uint8_t *side = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
@@ -852,7 +958,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
         }
     }
     if (is_audio && (sample_rate != flv->last_sample_rate ||
-                     channels != flv->last_channels)) {
+                     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);
@@ -867,7 +973,7 @@ leave:
 }
 
 static int flv_read_seek(AVFormatContext *s, int stream_index,
-    int64_t ts, int flags)
+                         int64_t ts, int flags)
 {
     FLVContext *flv = s->priv_data;
     flv->validate_count = 0;
@@ -877,7 +983,7 @@ static int flv_read_seek(AVFormatContext *s, int stream_index,
 #define OFFSET(x) offsetof(FLVContext, x)
 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
-    { "flv_metadata", "Allocate streams according the onMetaData array",      OFFSET(trust_metadata), AV_OPT_TYPE_INT,    { .i64 = 0 }, 0, 1, VD},
+    { "flv_metadata", "Allocate streams according to the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD },
     { NULL }
 };
 
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index ff6d14a..ca453f6 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -35,7 +35,7 @@ static const AVCodecTag flv_video_codec_ids[] = {
     { 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 }
 };
@@ -208,6 +208,11 @@ static int flv_write_header(AVFormatContext *s)
             } else {
                 framerate = 1 / av_q2d(s->streams[i]->codec->time_base);
             }
+            if (video_enc) {
+                av_log(s, AV_LOG_ERROR,
+                       "at most one video stream is supported in flv\n");
+                return AVERROR(EINVAL);
+            }
             video_enc = enc;
             if (enc->codec_tag == 0) {
                 av_log(s, AV_LOG_ERROR, "video codec not compatible with flv\n");
@@ -215,6 +220,11 @@ static int flv_write_header(AVFormatContext *s)
             }
             break;
         case AVMEDIA_TYPE_AUDIO:
+            if (audio_enc) {
+                av_log(s, AV_LOG_ERROR,
+                       "at most one audio stream is supported in flv\n");
+                return AVERROR(EINVAL);
+            }
             audio_enc = enc;
             if (get_audio_flags(s, enc) < 0)
                 return AVERROR_INVALIDDATA;
@@ -427,7 +437,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
     uint8_t *data = NULL;
     int flags = 0, flags_size;
 
-    if (enc->codec_id == AV_CODEC_ID_VP6 || enc->codec_id == AV_CODEC_ID_VP6F ||
+    if (enc->codec_id == AV_CODEC_ID_VP6F || 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)
@@ -517,11 +527,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
         avio_wb32(pb, data_size + 11);
     } else {
         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, enc->extradata_size ? enc->extradata[0] : 0);
-        else if (enc->codec_id == AV_CODEC_ID_AAC)
+        if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A) {
+            if (enc->extradata_size)
+                avio_w8(pb, enc->extradata[0]);
+            else
+                avio_w8(pb, ((FFALIGN(enc->width,  16) - enc->width) << 4) |
+                             (FFALIGN(enc->height, 16) - enc->height));
+        } 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
@@ -535,7 +547,6 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
                               pkt->pts + flv->delay + pkt->duration);
     }
 
-    avio_flush(pb);
     av_free(data);
 
     return pb->error;
diff --git a/libavformat/format.c b/libavformat/format.c
new file mode 100644
index 0000000..3a510cd
--- /dev/null
+++ b/libavformat/format.c
@@ -0,0 +1,183 @@
+/*
+ * Format register and lookup
+ * 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 "avformat.h"
+#include "internal.h"
+#include "libavutil/avstring.h"
+
+/**
+ * @file
+ * Format register and lookup
+ */
+/** head of registered input format linked list */
+static AVInputFormat *first_iformat = NULL;
+/** head of registered output format linked list */
+static AVOutputFormat *first_oformat = NULL;
+
+AVInputFormat *av_iformat_next(AVInputFormat *f)
+{
+    if (f)
+        return f->next;
+    else
+        return first_iformat;
+}
+
+AVOutputFormat *av_oformat_next(AVOutputFormat *f)
+{
+    if (f)
+        return f->next;
+    else
+        return first_oformat;
+}
+
+void av_register_input_format(AVInputFormat *format)
+{
+    AVInputFormat **p = &first_iformat;
+
+    while (*p != NULL)
+        p = &(*p)->next;
+
+    *p = format;
+    format->next = NULL;
+}
+
+void av_register_output_format(AVOutputFormat *format)
+{
+    AVOutputFormat **p = &first_oformat;
+
+    while (*p != NULL)
+        p = &(*p)->next;
+
+    *p = format;
+    format->next = NULL;
+}
+
+int av_match_ext(const char *filename, const char *extensions)
+{
+    const char *ext, *p;
+    char ext1[32], *q;
+
+    if (!filename)
+        return 0;
+
+    ext = strrchr(filename, '.');
+    if (ext) {
+        ext++;
+        p = extensions;
+        for (;;) {
+            q = ext1;
+            while (*p != '\0' && *p != ','  && q - ext1 < sizeof(ext1) - 1)
+                *q++ = *p++;
+            *q = '\0';
+            if (!av_strcasecmp(ext1, ext))
+                return 1;
+            if (*p == '\0')
+                break;
+            p++;
+        }
+    }
+    return 0;
+}
+
+static int match_format(const char *name, const char *names)
+{
+    const char *p;
+    int len, namelen;
+
+    if (!name || !names)
+        return 0;
+
+    namelen = strlen(name);
+    while ((p = strchr(names, ','))) {
+        len = FFMAX(p - names, namelen);
+        if (!av_strncasecmp(name, names, len))
+            return 1;
+        names = p + 1;
+    }
+    return !av_strcasecmp(name, names);
+}
+
+AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
+                                const char *mime_type)
+{
+    AVOutputFormat *fmt = NULL, *fmt_found;
+    int score_max, score;
+
+    /* specific test for image sequences */
+#if CONFIG_IMAGE2_MUXER
+    if (!short_name && filename &&
+        av_filename_number_test(filename) &&
+        ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
+        return av_guess_format("image2", NULL, NULL);
+    }
+#endif
+    /* Find the proper file type. */
+    fmt_found = NULL;
+    score_max = 0;
+    while ((fmt = av_oformat_next(fmt))) {
+        score = 0;
+        if (fmt->name && short_name && !av_strcasecmp(fmt->name, short_name))
+            score += 100;
+        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
+            score += 10;
+        if (filename && fmt->extensions &&
+            av_match_ext(filename, fmt->extensions)) {
+            score += 5;
+        }
+        if (score > score_max) {
+            score_max = score;
+            fmt_found = fmt;
+        }
+    }
+    return fmt_found;
+}
+
+enum AVCodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
+                              const char *filename, const char *mime_type,
+                              enum AVMediaType type)
+{
+    if (type == AVMEDIA_TYPE_VIDEO) {
+        enum AVCodecID codec_id = AV_CODEC_ID_NONE;
+
+#if CONFIG_IMAGE2_MUXER
+        if (!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")) {
+            codec_id = ff_guess_image2_codec(filename);
+        }
+#endif
+        if (codec_id == AV_CODEC_ID_NONE)
+            codec_id = fmt->video_codec;
+        return codec_id;
+    } else if (type == AVMEDIA_TYPE_AUDIO)
+        return fmt->audio_codec;
+    else if (type == AVMEDIA_TYPE_SUBTITLE)
+        return fmt->subtitle_codec;
+    else
+        return AV_CODEC_ID_NONE;
+}
+
+AVInputFormat *av_find_input_format(const char *short_name)
+{
+    AVInputFormat *fmt = NULL;
+    while ((fmt = av_iformat_next(fmt)))
+        if (match_format(short_name, fmt->name))
+            return fmt;
+    return NULL;
+}
diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
index de6fa2b..dd55c12 100644
--- a/libavformat/framecrcenc.c
+++ b/libavformat/framecrcenc.c
@@ -31,7 +31,6 @@ static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt)
     snprintf(buf, sizeof(buf), "%d, %10"PRId64", %10"PRId64", %8d, %8d, 0x%08x\n",
              pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size, crc);
     avio_write(s->pb, buf, strlen(buf));
-    avio_flush(s->pb);
     return 0;
 }
 
@@ -43,5 +42,6 @@ AVOutputFormat ff_framecrc_muxer = {
     .video_codec       = AV_CODEC_ID_RAWVIDEO,
     .write_header      = ff_framehash_write_header,
     .write_packet      = framecrc_write_packet,
-    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
+    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+                         AVFMT_TS_NEGATIVE,
 };
diff --git a/libavformat/g723_1.c b/libavformat/g723_1.c
index 0b92702..b67c07c 100644
--- a/libavformat/g723_1.c
+++ b/libavformat/g723_1.c
@@ -24,13 +24,14 @@
  * G.723.1 demuxer
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/channel_layout.h"
 #include "avformat.h"
 #include "internal.h"
 
 static const uint8_t frame_size[4] = { 24, 20, 4, 1 };
 
-static int g723_1_init(AVFormatContext *s)
+static av_cold int g723_1_init(AVFormatContext *s)
 {
     AVStream *st;
 
diff --git a/libavformat/gif.c b/libavformat/gif.c
index eb2db46..085c2e0 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -2,6 +2,8 @@
  * Animated GIF muxer
  * Copyright (c) 2000 Fabrice Bellard
  *
+ * first version by Francois Revol <revol at free.fr>
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -20,8 +22,6 @@
  */
 
 /*
- * First version by Francois Revol revol at free.fr
- *
  * Features and limitations:
  * - currently no compression is performed,
  *   in fact the size of the data is 9/8 the size of the image in 8bpp
@@ -329,7 +329,6 @@ static int gif_write_video(AVFormatContext *s, AVCodecContext *enc,
     gif_image_write_image(pb, 0, 0, enc->width, enc->height,
                           buf, enc->width * 3, AV_PIX_FMT_RGB24);
 
-    avio_flush(s->pb);
     return 0;
 }
 
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index 128122f..fea1d5d 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -342,11 +342,13 @@ static int gxf_write_map_packet(AVFormatContext *s, int rewrite)
 
     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));
-            if (!gxf->map_offsets) {
+            int err;
+            if ((err = av_reallocp_array(&gxf->map_offsets,
+                                         gxf->map_offsets_nb + 30,
+                                         sizeof(*gxf->map_offsets))) < 0) {
+                gxf->map_offsets_nb = 0;
                 av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n");
-                return -1;
+                return err;
             }
         }
         gxf->map_offsets[gxf->map_offsets_nb++] = pos; // do not increment here
@@ -873,11 +875,13 @@ static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     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));
-            if (!gxf->flt_entries) {
+            int err;
+            if ((err = av_reallocp_array(&gxf->flt_entries,
+                                         gxf->flt_entries_nb + 500,
+                                         sizeof(*gxf->flt_entries))) < 0) {
+                gxf->flt_entries_nb = 0;
                 av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n");
-                return -1;
+                return err;
             }
         }
         gxf->flt_entries[gxf->flt_entries_nb++] = packet_start_offset;
@@ -892,8 +896,6 @@ static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
         gxf->packet_count = 0;
     }
 
-    avio_flush(pb);
-
     return 0;
 }
 
diff --git a/libavformat/h261dec.c b/libavformat/h261dec.c
index 9b9e3f4..4a58050 100644
--- a/libavformat/h261dec.c
+++ b/libavformat/h261dec.c
@@ -56,9 +56,9 @@ static int h261_probe(AVProbeData *p)
         }
     }
     if(valid_psc > 2*invalid_psc + 6){
-        return 50;
+        return AVPROBE_SCORE_EXTENSION;
     }else if(valid_psc > 2*invalid_psc + 2)
-        return 25;
+        return AVPROBE_SCORE_EXTENSION / 2;
     return 0;
 }
 
diff --git a/libavformat/h263dec.c b/libavformat/h263dec.c
index 101ef51..4d826d8 100644
--- a/libavformat/h263dec.c
+++ b/libavformat/h263dec.c
@@ -56,9 +56,9 @@ static int h263_probe(AVProbeData *p)
         }
     }
     if(valid_psc > 2*invalid_psc + 2*res_change + 3){
-        return 50;
+        return AVPROBE_SCORE_EXTENSION;
     }else if(valid_psc > 2*invalid_psc)
-        return 25;
+        return AVPROBE_SCORE_EXTENSION / 2;
     return 0;
 }
 
diff --git a/libavformat/h264dec.c b/libavformat/h264dec.c
index 0c85bae..6fd45c1 100644
--- a/libavformat/h264dec.c
+++ b/libavformat/h264dec.c
@@ -24,47 +24,55 @@
 
 static int h264_probe(AVProbeData *p)
 {
-    uint32_t code= -1;
-    int sps=0, pps=0, idr=0, res=0, sli=0;
+    uint32_t code = -1;
+    int sps = 0, pps = 0, idr = 0, res = 0, sli = 0;
     int i;
 
-    for(i=0; i<p->buf_size; i++){
-        code = (code<<8) + p->buf[i];
+    for (i = 0; i < p->buf_size; i++) {
+        code = (code << 8) + p->buf[i];
         if ((code & 0xffffff00) == 0x100) {
-            int ref_idc= (code>>5)&3;
-            int type   = code & 0x1F;
-            static const int8_t ref_zero[32]={
-                2, 0, 0, 0, 0,-1, 1,-1,
-               -1, 1, 1, 1, 1,-1, 2, 2,
-                2, 2, 2, 0, 2, 2, 2, 2,
-                2, 2, 2, 2, 2, 2, 2, 2
+            int ref_idc = (code >> 5) & 3;
+            int type    = code & 0x1F;
+            static const int8_t ref_zero[] = {
+                 2,  0,  0,  0,  0, -1,  1, -1,
+                -1,  1,  1,  1,  1, -1,  2,  2,
+                 2,  2,  2,  0,  2,  2,  2,  2,
+                 2,  2,  2,  2,  2,  2,  2,  2
             };
 
-            if(code & 0x80) //forbidden bit
+            if (code & 0x80) // forbidden_bit
                 return 0;
 
-            if(ref_zero[type] == 1 && ref_idc)
+            if (ref_zero[type] == 1 && ref_idc)
                 return 0;
-            if(ref_zero[type] ==-1 && !ref_idc)
+            if (ref_zero[type] == -1 && !ref_idc)
                 return 0;
-            if(ref_zero[type] == 2)
+            if (ref_zero[type] == 2)
                 res++;
 
-            switch(type){
-            case     1:   sli++; break;
-            case     5:   idr++; break;
-            case     7:
+            switch (type) {
+            case 1:
+                sli++;
+                break;
+            case 5:
+                idr++;
+                break;
+            case 7:
                 if (p->buf[i + 2] & 0x03)
                     return 0;
                 sps++;
                 break;
-            case     8:   pps++; break;
+            case 8:
+                pps++;
+                break;
             }
         }
     }
-    if(sps && pps && (idr||sli>3) && res<(sps+pps+idr))
-        return AVPROBE_SCORE_MAX/2+1; // +1 for .mpg
+
+    if (sps && pps && (idr || sli > 3) && res < (sps + pps + idr))
+        return AVPROBE_SCORE_EXTENSION + 1;  // 1 more than .mpg
+
     return 0;
 }
 
-FF_DEF_RAWVIDEO_DEMUXER(h264 , "raw H.264 video", h264_probe, "h26l,h264,264", AV_CODEC_ID_H264)
+FF_DEF_RAWVIDEO_DEMUXER(h264, "raw H.264 video", h264_probe, "h26l,h264,264,avc", AV_CODEC_ID_H264)
diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c
new file mode 100644
index 0000000..6217c1f
--- /dev/null
+++ b/libavformat/hdsenc.c
@@ -0,0 +1,591 @@
+/*
+ * Live HDS fragmenter
+ * Copyright (c) 2013 Martin Storsjo
+ *
+ * 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 <float.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "avformat.h"
+#include "internal.h"
+#include "os_support.h"
+
+#include "libavutil/avstring.h"
+#include "libavutil/base64.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+
+typedef struct Fragment {
+    char file[1024];
+    int64_t start_time, duration;
+    int n;
+} Fragment;
+
+typedef struct OutputStream {
+    int bitrate;
+    int first_stream;
+    AVFormatContext *ctx;
+    int ctx_inited;
+    uint8_t iobuf[32768];
+    char temp_filename[1024];
+    int64_t frag_start_ts, last_ts;
+    AVIOContext *out;
+    int packets_written;
+    int nb_fragments, fragments_size, fragment_index;
+    Fragment **fragments;
+
+    int has_audio, has_video;
+
+    uint8_t *metadata;
+    int metadata_size;
+
+    uint8_t *extra_packets[2];
+    int extra_packet_sizes[2];
+    int nb_extra_packets;
+} OutputStream;
+
+typedef struct HDSContext {
+    const AVClass *class;  /* Class for private options. */
+    int window_size;
+    int extra_window_size;
+    int min_frag_duration;
+    int remove_at_exit;
+
+    OutputStream *streams;
+    int nb_streams;
+} HDSContext;
+
+static int parse_header(OutputStream *os, const uint8_t *buf, int buf_size)
+{
+    if (buf_size < 13)
+        return AVERROR_INVALIDDATA;
+    if (memcmp(buf, "FLV", 3))
+        return AVERROR_INVALIDDATA;
+    buf      += 13;
+    buf_size -= 13;
+    while (buf_size >= 11 + 4) {
+        int type = buf[0];
+        int size = AV_RB24(&buf[1]) + 11 + 4;
+        if (size > buf_size)
+            return AVERROR_INVALIDDATA;
+        if (type == 8 || type == 9) {
+            if (os->nb_extra_packets >= FF_ARRAY_ELEMS(os->extra_packets))
+                return AVERROR_INVALIDDATA;
+            os->extra_packet_sizes[os->nb_extra_packets] = size;
+            os->extra_packets[os->nb_extra_packets] = av_malloc(size);
+            if (!os->extra_packets[os->nb_extra_packets])
+                return AVERROR(ENOMEM);
+            memcpy(os->extra_packets[os->nb_extra_packets], buf, size);
+            os->nb_extra_packets++;
+        } else if (type == 0x12) {
+            if (os->metadata)
+                return AVERROR_INVALIDDATA;
+            os->metadata_size = size - 11 - 4;
+            os->metadata      = av_malloc(os->metadata_size);
+            if (!os->metadata)
+                return AVERROR(ENOMEM);
+            memcpy(os->metadata, buf + 11, os->metadata_size);
+        }
+        buf      += size;
+        buf_size -= size;
+    }
+    if (!os->metadata)
+        return AVERROR_INVALIDDATA;
+    return 0;
+}
+
+static int hds_write(void *opaque, uint8_t *buf, int buf_size)
+{
+    OutputStream *os = opaque;
+    if (os->out) {
+        avio_write(os->out, buf, buf_size);
+    } else {
+        if (!os->metadata_size) {
+            int ret;
+            // Assuming the IO buffer is large enough to fit the
+            // FLV header and all metadata and extradata packets
+            if ((ret = parse_header(os, buf, buf_size)) < 0)
+                return ret;
+        }
+    }
+    return buf_size;
+}
+
+static void hds_free(AVFormatContext *s)
+{
+    HDSContext *c = s->priv_data;
+    int i, j;
+    if (!c->streams)
+        return;
+    for (i = 0; i < s->nb_streams; i++) {
+        OutputStream *os = &c->streams[i];
+        if (os->out)
+            avio_close(os->out);
+        os->out = NULL;
+        if (os->ctx && os->ctx_inited)
+            av_write_trailer(os->ctx);
+        if (os->ctx && os->ctx->pb)
+            av_free(os->ctx->pb);
+        if (os->ctx)
+            avformat_free_context(os->ctx);
+        av_free(os->metadata);
+        for (j = 0; j < os->nb_extra_packets; j++)
+            av_free(os->extra_packets[j]);
+        for (j = 0; j < os->nb_fragments; j++)
+            av_free(os->fragments[j]);
+        av_free(os->fragments);
+    }
+    av_freep(&c->streams);
+}
+
+static int write_manifest(AVFormatContext *s, int final)
+{
+    HDSContext *c = s->priv_data;
+    AVIOContext *out;
+    char filename[1024], temp_filename[1024];
+    int ret, i;
+    float duration = 0;
+
+    if (c->nb_streams > 0)
+        duration = c->streams[0].last_ts * av_q2d(s->streams[0]->time_base);
+
+    snprintf(filename, sizeof(filename), "%s/index.f4m", s->filename);
+    snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->filename);
+    ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE,
+                     &s->interrupt_callback, NULL);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", filename);
+        return ret;
+    }
+    avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+    avio_printf(out, "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n");
+    avio_printf(out, "\t<id>%s</id>\n", av_basename(s->filename));
+    avio_printf(out, "\t<streamType>%s</streamType>\n",
+                     final ? "recorded" : "live");
+    avio_printf(out, "\t<deliveryType>streaming</deliveryType>\n");
+    if (final)
+        avio_printf(out, "\t<duration>%f</duration>\n", duration);
+    for (i = 0; i < c->nb_streams; i++) {
+        OutputStream *os = &c->streams[i];
+        int b64_size = AV_BASE64_SIZE(os->metadata_size);
+        char *base64 = av_malloc(b64_size);
+        if (!base64) {
+            avio_close(out);
+            return AVERROR(ENOMEM);
+        }
+        av_base64_encode(base64, b64_size, os->metadata, os->metadata_size);
+
+        avio_printf(out, "\t<bootstrapInfo profile=\"named\" url=\"stream%d.abst\" id=\"bootstrap%d\" />\n", i, i);
+        avio_printf(out, "\t<media bitrate=\"%d\" url=\"stream%d\" bootstrapInfoId=\"bootstrap%d\">\n", os->bitrate/1000, i, i);
+        avio_printf(out, "\t\t<metadata>%s</metadata>\n", base64);
+        avio_printf(out, "\t</media>\n");
+        av_free(base64);
+    }
+    avio_printf(out, "</manifest>\n");
+    avio_flush(out);
+    avio_close(out);
+    rename(temp_filename, filename);
+    return 0;
+}
+
+static void update_size(AVIOContext *out, int64_t pos)
+{
+    int64_t end = avio_tell(out);
+    avio_seek(out, pos, SEEK_SET);
+    avio_wb32(out, end - pos);
+    avio_seek(out, end, SEEK_SET);
+}
+
+/* Note, the .abst files need to be served with the "binary/octet"
+ * mime type, otherwise at least the OSMF player can easily fail
+ * with "stream not found" when polling for the next fragment. */
+static int write_abst(AVFormatContext *s, OutputStream *os, int final)
+{
+    HDSContext *c = s->priv_data;
+    AVIOContext *out;
+    char filename[1024], temp_filename[1024];
+    int i, ret;
+    int64_t asrt_pos, afrt_pos;
+    int start = 0, fragments;
+    int index = s->streams[os->first_stream]->id;
+    int64_t cur_media_time = 0;
+    if (c->window_size)
+        start = FFMAX(os->nb_fragments - c->window_size, 0);
+    fragments = os->nb_fragments - start;
+    if (final)
+        cur_media_time = os->last_ts;
+    else if (os->nb_fragments)
+        cur_media_time = os->fragments[os->nb_fragments - 1]->start_time;
+
+    snprintf(filename, sizeof(filename),
+             "%s/stream%d.abst", s->filename, index);
+    snprintf(temp_filename, sizeof(temp_filename),
+             "%s/stream%d.abst.tmp", s->filename, index);
+    ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE,
+                     &s->interrupt_callback, NULL);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
+        return ret;
+    }
+    avio_wb32(out, 0); // abst size
+    avio_wl32(out, MKTAG('a','b','s','t'));
+    avio_wb32(out, 0); // version + flags
+    avio_wb32(out, os->fragment_index - 1); // BootstrapinfoVersion
+    avio_w8(out, final ? 0 : 0x20); // profile, live, update
+    avio_wb32(out, 1000); // timescale
+    avio_wb64(out, cur_media_time);
+    avio_wb64(out, 0); // SmpteTimeCodeOffset
+    avio_w8(out, 0); // MovieIdentifer (null string)
+    avio_w8(out, 0); // ServerEntryCount
+    avio_w8(out, 0); // QualityEntryCount
+    avio_w8(out, 0); // DrmData (null string)
+    avio_w8(out, 0); // MetaData (null string)
+    avio_w8(out, 1); // SegmentRunTableCount
+    asrt_pos = avio_tell(out);
+    avio_wb32(out, 0); // asrt size
+    avio_wl32(out, MKTAG('a','s','r','t'));
+    avio_wb32(out, 0); // version + flags
+    avio_w8(out, 0); // QualityEntryCount
+    avio_wb32(out, 1); // SegmentRunEntryCount
+    avio_wb32(out, 1); // FirstSegment
+    avio_wb32(out, final ? (os->fragment_index - 1) : 0xffffffff); // FragmentsPerSegment
+    update_size(out, asrt_pos);
+    avio_w8(out, 1); // FragmentRunTableCount
+    afrt_pos = avio_tell(out);
+    avio_wb32(out, 0); // afrt size
+    avio_wl32(out, MKTAG('a','f','r','t'));
+    avio_wb32(out, 0); // version + flags
+    avio_wb32(out, 1000); // timescale
+    avio_w8(out, 0); // QualityEntryCount
+    avio_wb32(out, fragments); // FragmentRunEntryCount
+    for (i = start; i < os->nb_fragments; i++) {
+        avio_wb32(out, os->fragments[i]->n);
+        avio_wb64(out, os->fragments[i]->start_time);
+        avio_wb32(out, os->fragments[i]->duration);
+    }
+    update_size(out, afrt_pos);
+    update_size(out, 0);
+    avio_close(out);
+    rename(temp_filename, filename);
+    return 0;
+}
+
+static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts)
+{
+    int ret, i;
+    ret = avio_open2(&os->out, os->temp_filename, AVIO_FLAG_WRITE,
+                     &s->interrupt_callback, NULL);
+    if (ret < 0)
+        return ret;
+    avio_wb32(os->out, 0);
+    avio_wl32(os->out, MKTAG('m','d','a','t'));
+    for (i = 0; i < os->nb_extra_packets; i++) {
+        AV_WB24(os->extra_packets[i] + 4, start_ts);
+        os->extra_packets[i][7] = (start_ts >> 24) & 0x7f;
+        avio_write(os->out, os->extra_packets[i], os->extra_packet_sizes[i]);
+    }
+    return 0;
+}
+
+static void close_file(OutputStream *os)
+{
+    int64_t pos = avio_tell(os->out);
+    avio_seek(os->out, 0, SEEK_SET);
+    avio_wb32(os->out, pos);
+    avio_flush(os->out);
+    avio_close(os->out);
+    os->out = NULL;
+}
+
+static int hds_write_header(AVFormatContext *s)
+{
+    HDSContext *c = s->priv_data;
+    int ret = 0, i;
+    AVOutputFormat *oformat;
+
+    mkdir(s->filename, 0777);
+
+    oformat = av_guess_format("flv", NULL, NULL);
+    if (!oformat) {
+        ret = AVERROR_MUXER_NOT_FOUND;
+        goto fail;
+    }
+
+    c->streams = av_mallocz(sizeof(*c->streams) * s->nb_streams);
+    if (!c->streams) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    for (i = 0; i < s->nb_streams; i++) {
+        OutputStream *os = &c->streams[c->nb_streams];
+        AVFormatContext *ctx;
+        AVStream *st = s->streams[i];
+
+        if (!st->codec->bit_rate) {
+            av_log(s, AV_LOG_ERROR, "No bit rate set for stream %d\n", i);
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+            if (os->has_video) {
+                c->nb_streams++;
+                os++;
+            }
+            os->has_video = 1;
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            if (os->has_audio) {
+                c->nb_streams++;
+                os++;
+            }
+            os->has_audio = 1;
+        } else {
+            av_log(s, AV_LOG_ERROR, "Unsupported stream type in stream %d\n", i);
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+        os->bitrate += s->streams[i]->codec->bit_rate;
+
+        if (!os->ctx) {
+            os->first_stream = i;
+            ctx = avformat_alloc_context();
+            if (!ctx) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+            os->ctx = ctx;
+            ctx->oformat = oformat;
+            ctx->interrupt_callback = s->interrupt_callback;
+
+            ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf),
+                                         AVIO_FLAG_WRITE, os,
+                                         NULL, hds_write, NULL);
+            if (!ctx->pb) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+        } else {
+            ctx = os->ctx;
+        }
+        s->streams[i]->id = c->nb_streams;
+
+        if (!(st = avformat_new_stream(ctx, NULL))) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        avcodec_copy_context(st->codec, s->streams[i]->codec);
+        st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
+    }
+    if (c->streams[c->nb_streams].ctx)
+        c->nb_streams++;
+
+    for (i = 0; i < c->nb_streams; i++) {
+        OutputStream *os = &c->streams[i];
+        int j;
+        if ((ret = avformat_write_header(os->ctx, NULL)) < 0) {
+             goto fail;
+        }
+        os->ctx_inited = 1;
+        avio_flush(os->ctx->pb);
+        for (j = 0; j < os->ctx->nb_streams; j++)
+            s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
+
+        snprintf(os->temp_filename, sizeof(os->temp_filename),
+                 "%s/stream%d_temp", s->filename, i);
+        ret = init_file(s, os, 0);
+        if (ret < 0)
+            goto fail;
+
+        if (!os->has_video && c->min_frag_duration <= 0) {
+            av_log(s, AV_LOG_WARNING,
+                   "No video stream in output stream %d and no min frag duration set\n", i);
+            ret = AVERROR(EINVAL);
+        }
+        os->fragment_index = 1;
+        write_abst(s, os, 0);
+    }
+    ret = write_manifest(s, 0);
+
+fail:
+    if (ret)
+        hds_free(s);
+    return ret;
+}
+
+static int add_fragment(OutputStream *os, const char *file,
+                        int64_t start_time, int64_t duration)
+{
+    Fragment *frag;
+    if (duration == 0)
+        duration = 1;
+    if (os->nb_fragments >= os->fragments_size) {
+        int ret;
+        os->fragments_size = (os->fragments_size + 1) * 2;
+        if ((ret = av_reallocp_array(&os->fragments, os->fragments_size,
+                                     sizeof(*os->fragments))) < 0) {
+            os->fragments_size = 0;
+            os->nb_fragments   = 0;
+            return ret;
+        }
+    }
+    frag = av_mallocz(sizeof(*frag));
+    if (!frag)
+        return AVERROR(ENOMEM);
+    av_strlcpy(frag->file, file, sizeof(frag->file));
+    frag->start_time = start_time;
+    frag->duration   = duration;
+    frag->n          = os->fragment_index;
+    os->fragments[os->nb_fragments++] = frag;
+    os->fragment_index++;
+    return 0;
+}
+
+static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
+                     int64_t end_ts)
+{
+    HDSContext *c = s->priv_data;
+    int i, ret = 0;
+    char target_filename[1024];
+    int index = s->streams[os->first_stream]->id;
+
+    if (!os->packets_written)
+        return 0;
+
+    avio_flush(os->ctx->pb);
+    os->packets_written = 0;
+    close_file(os);
+
+    snprintf(target_filename, sizeof(target_filename),
+             "%s/stream%dSeg1-Frag%d", s->filename, index, os->fragment_index);
+    rename(os->temp_filename, target_filename);
+    add_fragment(os, target_filename, os->frag_start_ts, end_ts - os->frag_start_ts);
+
+    if (!final) {
+        ret = init_file(s, os, end_ts);
+        if (ret < 0)
+            return ret;
+    }
+
+    if (c->window_size || (final && c->remove_at_exit)) {
+        int remove = os->nb_fragments - c->window_size - c->extra_window_size;
+        if (final && c->remove_at_exit)
+            remove = os->nb_fragments;
+        if (remove > 0) {
+            for (i = 0; i < remove; i++) {
+                unlink(os->fragments[i]->file);
+                av_free(os->fragments[i]);
+            }
+            os->nb_fragments -= remove;
+            memmove(os->fragments, os->fragments + remove,
+                    os->nb_fragments * sizeof(*os->fragments));
+        }
+    }
+
+    if (ret >= 0)
+        ret = write_abst(s, os, final);
+    return ret;
+}
+
+static int hds_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    HDSContext *c = s->priv_data;
+    AVStream *st = s->streams[pkt->stream_index];
+    OutputStream *os = &c->streams[s->streams[pkt->stream_index]->id];
+    int64_t end_dts = os->fragment_index * (int64_t) c->min_frag_duration;
+    int ret;
+
+    if (st->first_dts == AV_NOPTS_VALUE)
+        st->first_dts = pkt->dts;
+
+    if ((!os->has_video || st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+        av_compare_ts(pkt->dts - st->first_dts, st->time_base,
+                      end_dts, AV_TIME_BASE_Q) >= 0 &&
+        pkt->flags & AV_PKT_FLAG_KEY && os->packets_written) {
+
+        if ((ret = hds_flush(s, os, 0, pkt->dts)) < 0)
+            return ret;
+    }
+
+    // Note, these fragment start timestamps, that represent a whole
+    // OutputStream, assume all streams in it have the same time base.
+    if (!os->packets_written)
+        os->frag_start_ts = pkt->dts;
+    os->last_ts = pkt->dts;
+
+    os->packets_written++;
+    return ff_write_chained(os->ctx, pkt->stream_index - os->first_stream, pkt, s);
+}
+
+static int hds_write_trailer(AVFormatContext *s)
+{
+    HDSContext *c = s->priv_data;
+    int i;
+
+    for (i = 0; i < c->nb_streams; i++)
+        hds_flush(s, &c->streams[i], 1, c->streams[i].last_ts);
+    write_manifest(s, 1);
+
+    if (c->remove_at_exit) {
+        char filename[1024];
+        snprintf(filename, sizeof(filename), "%s/index.f4m", s->filename);
+        unlink(filename);
+        for (i = 0; i < c->nb_streams; i++) {
+            snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->filename, i);
+            unlink(filename);
+        }
+        rmdir(s->filename);
+    }
+
+    hds_free(s);
+    return 0;
+}
+
+#define OFFSET(x) offsetof(HDSContext, x)
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "window_size", "number of fragments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
+    { "extra_window_size", "number of fragments kept outside of the manifest before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E },
+    { "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT_MAX, E },
+    { "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, E },
+    { NULL },
+};
+
+static const AVClass hds_class = {
+    .class_name = "HDS muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_hds_muxer = {
+    .name           = "hds",
+    .long_name      = NULL_IF_CONFIG_SMALL("HDS Muxer"),
+    .priv_data_size = sizeof(HDSContext),
+    .audio_codec    = AV_CODEC_ID_AAC,
+    .video_codec    = AV_CODEC_ID_H264,
+    .flags          = AVFMT_GLOBALHEADER | AVFMT_NOFILE,
+    .write_header   = hds_write_header,
+    .write_packet   = hds_write_packet,
+    .write_trailer  = hds_write_trailer,
+    .priv_class     = &hds_class,
+};
diff --git a/libavformat/hevcdec.c b/libavformat/hevcdec.c
new file mode 100644
index 0000000..65a3cdf
--- /dev/null
+++ b/libavformat/hevcdec.c
@@ -0,0 +1,64 @@
+/*
+ * RAW HEVC video demuxer
+ * Copyright (c) 2013 Dirk Farin <dirk.farin at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavcodec/hevc.h"
+
+#include "avformat.h"
+#include "rawdec.h"
+
+static int hevc_probe(AVProbeData *p)
+{
+    uint32_t code = -1;
+    int vps = 0, sps = 0, pps = 0, irap = 0;
+    int i;
+
+    for (i = 0; i < p->buf_size - 1; i++) {
+        code = (code << 8) + p->buf[i];
+        if ((code & 0xffffff00) == 0x100) {
+            uint8_t nal2 = p->buf[i + 1];
+            int type = (code & 0x7E) >> 1;
+
+            if (code & 0x81) // forbidden and reserved zero bits
+                return 0;
+
+            if (nal2 & 0xf8) // reserved zero
+                return 0;
+
+            switch (type) {
+            case NAL_VPS:        vps++;  break;
+            case NAL_SPS:        sps++;  break;
+            case NAL_PPS:        pps++;  break;
+            case NAL_BLA_N_LP:
+            case NAL_BLA_W_LP:
+            case NAL_BLA_W_RADL:
+            case NAL_CRA_NUT:
+            case NAL_IDR_N_LP:
+            case NAL_IDR_W_RADL: irap++; break;
+            }
+        }
+    }
+
+    if (vps && sps && pps && irap)
+        return AVPROBE_SCORE_EXTENSION + 1; // 1 more than .mpg
+    return 0;
+}
+
+FF_DEF_RAWVIDEO_DEMUXER(hevc, "raw HEVC video", hevc_probe, "hevc,h265,265", AV_CODEC_ID_HEVC)
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 4c0e0c0..290f12e 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -56,7 +56,7 @@ enum KeyType {
 };
 
 struct segment {
-    int duration;
+    int64_t duration;
     char url[MAX_URL_SIZE];
     char key[MAX_URL_SIZE];
     enum KeyType key_type;
@@ -81,7 +81,7 @@ struct variant {
     int stream_offset;
 
     int finished;
-    int target_duration;
+    int64_t target_duration;
     int start_seq_no;
     int n_segments;
     struct segment **segments;
@@ -108,7 +108,7 @@ typedef struct HLSContext {
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
 {
     int len = ff_get_line(s, buf, maxlen);
-    while (len > 0 && isspace(buf[len - 1]))
+    while (len > 0 && av_isspace(buf[len - 1]))
         buf[--len] = '\0';
     return len;
 }
@@ -202,7 +202,8 @@ static void handle_key_args(struct key_info *info, const char *key,
 static int parse_playlist(HLSContext *c, const char *url,
                           struct variant *var, AVIOContext *in)
 {
-    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+    int64_t duration = 0;
     enum KeyType key_type = KEY_NONE;
     uint8_t iv[16] = "";
     int has_iv = 0;
@@ -210,6 +211,7 @@ static int parse_playlist(HLSContext *c, const char *url,
     char line[1024];
     const char *ptr;
     int close_in = 0;
+    uint8_t *new_url = NULL;
 
     if (!in) {
         close_in = 1;
@@ -218,6 +220,9 @@ static int parse_playlist(HLSContext *c, const char *url,
             return ret;
     }
 
+    if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
+        url = new_url;
+
     read_chomp_line(in, line, sizeof(line));
     if (strcmp(line, "#EXTM3U")) {
         ret = AVERROR_INVALIDDATA;
@@ -257,7 +262,7 @@ static int parse_playlist(HLSContext *c, const char *url,
                     goto fail;
                 }
             }
-            var->target_duration = atoi(ptr);
+            var->target_duration = atoi(ptr) * AV_TIME_BASE;
         } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
             if (!var) {
                 var = new_variant(c, 0, url, NULL);
@@ -272,7 +277,7 @@ static int parse_playlist(HLSContext *c, const char *url,
                 var->finished = 1;
         } else if (av_strstart(line, "#EXTINF:", &ptr)) {
             is_segment = 1;
-            duration   = atoi(ptr);
+            duration   = atof(ptr) * AV_TIME_BASE;
         } else if (av_strstart(line, "#", NULL)) {
             continue;
         } else if (line[0]) {
@@ -318,6 +323,7 @@ static int parse_playlist(HLSContext *c, const char *url,
         var->last_load_time = av_gettime();
 
 fail:
+    av_free(new_url);
     if (close_in)
         avio_close(in);
     return ret;
@@ -383,7 +389,6 @@ restart:
         int64_t reload_interval = v->n_segments > 0 ?
                                   v->segments[v->n_segments - 1]->duration :
                                   v->target_duration;
-        reload_interval *= 1000000;
 
 reload:
         if (!v->finished &&
@@ -393,7 +398,7 @@ reload:
             /* If we need to reload the playlist again below (if
              * there's still no more segments), switch to a reload
              * interval of half the target duration. */
-            reload_interval = v->target_duration * 500000;
+            reload_interval = v->target_duration / 2;
         }
         if (v->cur_seq_no < v->start_seq_no) {
             av_log(NULL, AV_LOG_WARNING,
@@ -427,7 +432,8 @@ reload:
     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++) {
@@ -480,7 +486,7 @@ static int hls_read_header(AVFormatContext *s)
         int64_t duration = 0;
         for (i = 0; i < c->variants[0]->n_segments; i++)
             duration += c->variants[0]->segments[i]->duration;
-        s->duration = duration * AV_TIME_BASE;
+        s->duration = duration;
     }
 
     /* Open the demuxer for each variant */
@@ -488,6 +494,8 @@ static int hls_read_header(AVFormatContext *s)
         struct variant *v = c->variants[i];
         AVInputFormat *in_fmt = NULL;
         char bitrate_str[20];
+        AVProgram *program;
+
         if (v->n_segments == 0)
             continue;
 
@@ -522,19 +530,33 @@ static int hls_read_header(AVFormatContext *s)
             goto fail;
         }
         v->ctx->pb       = &v->pb;
+        v->stream_offset = stream_offset;
         ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
         if (ret < 0)
             goto fail;
-        v->stream_offset = stream_offset;
+
+        v->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
+        ret = avformat_find_stream_info(v->ctx, NULL);
+        if (ret < 0)
+            goto fail;
         snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
+
+        program = av_new_program(s, i);
+        if (!program)
+            goto fail;
+        av_dict_set(&program->metadata, "variant_bitrate", bitrate_str, 0);
+
         /* Create new AVStreams for each stream in this variant */
         for (j = 0; j < v->ctx->nb_streams; j++) {
             AVStream *st = avformat_new_stream(s, NULL);
+            AVStream *ist = v->ctx->streams[j];
             if (!st) {
                 ret = AVERROR(ENOMEM);
                 goto fail;
             }
+            ff_program_add_stream_index(s, i, stream_offset + j);
             st->id = i;
+            avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
             avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
             if (v->bandwidth)
                 av_dict_set(&st->metadata, "variant_bitrate", bitrate_str,
@@ -615,8 +637,11 @@ start:
                     reset_packet(&var->pkt);
                     break;
                 } else {
-                    if (c->first_timestamp == AV_NOPTS_VALUE)
-                        c->first_timestamp = var->pkt.dts;
+                    if (c->first_timestamp == AV_NOPTS_VALUE &&
+                        var->pkt.dts       != AV_NOPTS_VALUE)
+                        c->first_timestamp = av_rescale_q(var->pkt.dts,
+                            var->ctx->streams[var->pkt.stream_index]->time_base,
+                            AV_TIME_BASE_Q);
                 }
 
                 if (c->seek_timestamp == AV_NOPTS_VALUE)
@@ -636,13 +661,36 @@ start:
                     c->seek_timestamp = AV_NOPTS_VALUE;
                     break;
                 }
+                av_free_packet(&var->pkt);
+                reset_packet(&var->pkt);
             }
         }
-        /* Check if this stream has the packet with the lowest dts */
+        /* Check if this stream still is on an earlier segment number, or
+         * has the packet with the lowest dts */
         if (var->pkt.data) {
-            if (minvariant < 0 ||
-                var->pkt.dts < c->variants[minvariant]->pkt.dts)
+            struct variant *minvar = minvariant < 0 ?
+                                     NULL : c->variants[minvariant];
+            if (minvariant < 0 || var->cur_seq_no < minvar->cur_seq_no) {
                 minvariant = i;
+            } else if (var->cur_seq_no == minvar->cur_seq_no) {
+                int64_t dts     =    var->pkt.dts;
+                int64_t mindts  = minvar->pkt.dts;
+                AVStream *st    =    var->ctx->streams[var->pkt.stream_index];
+                AVStream *minst = minvar->ctx->streams[minvar->pkt.stream_index];
+
+                if (dts == AV_NOPTS_VALUE) {
+                    minvariant = i;
+                } else if (mindts != AV_NOPTS_VALUE) {
+                    if (st->start_time    != AV_NOPTS_VALUE)
+                        dts    -= st->start_time;
+                    if (minst->start_time != AV_NOPTS_VALUE)
+                        mindts -= minst->start_time;
+
+                    if (av_compare_ts(dts, st->time_base,
+                                      mindts, minst->time_base) < 0)
+                        minvariant = i;
+                }
+            }
         }
     }
     if (c->end_of_segment) {
@@ -682,7 +730,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
                                        s->streams[stream_index]->time_base.den,
                                        flags & AVSEEK_FLAG_BACKWARD ?
                                        AV_ROUND_DOWN : AV_ROUND_UP);
-    timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
+    timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE, stream_index >= 0 ?
                                s->streams[stream_index]->time_base.den :
                                AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                                AV_ROUND_DOWN : AV_ROUND_UP);
@@ -695,10 +743,8 @@ static int hls_read_seek(AVFormatContext *s, int stream_index,
     for (i = 0; i < c->n_variants; i++) {
         /* Reset reading */
         struct variant *var = c->variants[i];
-        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
-                      av_rescale_rnd(c->first_timestamp, 1,
-                          stream_index >= 0 ? s->streams[stream_index]->time_base.den : AV_TIME_BASE,
-                          flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
+        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
+                      0 : c->first_timestamp;
         if (var->input) {
             ffurl_close(var->input);
             var->input = NULL;
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index c4c0217..f9e9678 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -20,6 +20,7 @@
  */
 
 #include <float.h>
+#include <stdint.h>
 
 #include "libavutil/mathematics.h"
 #include "libavutil/parseutils.h"
@@ -49,6 +50,7 @@ typedef struct HLSContext {
     int has_video;
     int64_t start_pts;
     int64_t end_pts;
+    int64_t duration;      // last segment duration computed so far, in seconds
     int nb_entries;
     ListEntry *list;
     ListEntry *end_list;
@@ -163,12 +165,10 @@ static int hls_start(AVFormatContext *s)
     AVFormatContext *oc = c->avf;
     int err = 0;
 
-    if (c->wrap)
-        c->number %= c->wrap;
-
     if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
-                              c->basename, c->number++) < 0)
+                              c->basename, c->wrap ? c->number % c->wrap : c->number) < 0)
         return AVERROR(EINVAL);
+    c->number++;
 
     if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
                           &s->interrupt_callback, NULL)) < 0)
@@ -261,16 +261,20 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
         can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
                     pkt->flags & AV_PKT_FLAG_KEY;
     }
+    if (pkt->pts == AV_NOPTS_VALUE)
+        can_split = 0;
+    else
+        hls->duration = av_rescale(pkt->pts - hls->end_pts,
+                                   st->time_base.num, st->time_base.den);
 
     if (can_split && av_compare_ts(pkt->pts - hls->start_pts, st->time_base,
                                    end_pts, AV_TIME_BASE_Q) >= 0) {
-        ret = append_entry(hls, av_rescale(pkt->pts - hls->end_pts,
-                                           st->time_base.num,
-                                           st->time_base.den));
+        ret = append_entry(hls, hls->duration);
         if (ret)
             return ret;
 
         hls->end_pts = pkt->pts;
+        hls->duration = 0;
 
         av_write_frame(oc, NULL); /* Flush any buffered data */
         avio_close(oc->pb);
@@ -300,6 +304,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
     avio_closep(&oc->pb);
     avformat_free_context(oc);
     av_free(hls->basename);
+    append_entry(hls, hls->duration);
     hls_window(s, 1);
 
     free_entries(hls);
@@ -310,7 +315,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
 #define OFFSET(x) offsetof(HLSContext, x)
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "start_number", "first number in the sequence",            OFFSET(number),  AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_MAX, E},
+    {"start_number",  "first number in the sequence",            OFFSET(sequence),AV_OPT_TYPE_INT64,  {.i64 = 0},     0, INT64_MAX, E},
     {"hls_time",      "segment length in seconds",               OFFSET(time),    AV_OPT_TYPE_FLOAT,  {.dbl = 2},     0, FLT_MAX, E},
     {"hls_list_size", "maximum number of playlist entries",      OFFSET(size),    AV_OPT_TYPE_INT,    {.i64 = 5},     0, INT_MAX, E},
     {"hls_wrap",      "number after which the index wraps",      OFFSET(wrap),    AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_MAX, E},
diff --git a/libavformat/hlsproto.c b/libavformat/hlsproto.c
index b750501..ec357de 100644
--- a/libavformat/hlsproto.c
+++ b/libavformat/hlsproto.c
@@ -45,7 +45,7 @@
  */
 
 struct segment {
-    int duration;
+    int64_t duration;
     char url[MAX_URL_SIZE];
 };
 
@@ -56,7 +56,7 @@ struct variant {
 
 typedef struct HLSContext {
     char playlisturl[MAX_URL_SIZE];
-    int target_duration;
+    int64_t target_duration;
     int start_seq_no;
     int finished;
     int n_segments;
@@ -71,7 +71,7 @@ typedef struct HLSContext {
 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
 {
     int len = ff_get_line(s, buf, maxlen);
-    while (len > 0 && isspace(buf[len - 1]))
+    while (len > 0 && av_isspace(buf[len - 1]))
         buf[--len] = '\0';
     return len;
 }
@@ -111,7 +111,8 @@ static int parse_playlist(URLContext *h, const char *url)
 {
     HLSContext *s = h->priv_data;
     AVIOContext *in;
-    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+    int ret = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
+    int64_t duration = 0;
     char line[1024];
     const char *ptr;
 
@@ -134,14 +135,14 @@ static int parse_playlist(URLContext *h, const char *url)
                                &info);
             bandwidth = atoi(info.bandwidth);
         } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
-            s->target_duration = atoi(ptr);
+            s->target_duration = atoi(ptr) * AV_TIME_BASE;
         } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
             s->start_seq_no = atoi(ptr);
         } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
             s->finished = 1;
         } else if (av_strstart(line, "#EXTINF:", &ptr)) {
             is_segment = 1;
-            duration = atoi(ptr);
+            duration = atof(ptr) * AV_TIME_BASE;
         } else if (av_strstart(line, "#", NULL)) {
             continue;
         } else if (line[0]) {
@@ -204,19 +205,6 @@ static int hls_open(URLContext *h, const char *uri, int flags)
                nested_url);
         ret = AVERROR(EINVAL);
         goto fail;
-#if FF_API_APPLEHTTP_PROTO
-    } else if (av_strstart(uri, "applehttp+", &nested_url)) {
-        av_strlcpy(s->playlisturl, nested_url, sizeof(s->playlisturl));
-        av_log(h, AV_LOG_WARNING,
-               "The applehttp protocol is deprecated, use hls+%s as url "
-               "instead.\n", nested_url);
-    } else if (av_strstart(uri, "applehttp://", &nested_url)) {
-        av_strlcpy(s->playlisturl, "http://", sizeof(s->playlisturl));
-        av_strlcat(s->playlisturl, nested_url, sizeof(s->playlisturl));
-        av_log(h, AV_LOG_WARNING,
-               "The applehttp protocol is deprecated, use hls+http://%s as url "
-               "instead.\n", nested_url);
-#endif
     } else {
         av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri);
         ret = AVERROR(EINVAL);
@@ -283,7 +271,6 @@ start:
     reload_interval = s->n_segments > 0 ?
                       s->segments[s->n_segments - 1]->duration :
                       s->target_duration;
-    reload_interval *= 1000000;
 retry:
     if (!s->finished) {
         int64_t now = av_gettime();
@@ -293,7 +280,7 @@ retry:
             /* If we need to reload the playlist again below (if
              * there's still no more segments), switch to a reload
              * interval of half the target duration. */
-            reload_interval = s->target_duration * 500000;
+            reload_interval = s->target_duration / 2;
         }
     }
     if (s->cur_seq_no < s->start_seq_no) {
@@ -326,17 +313,6 @@ retry:
     goto start;
 }
 
-#if FF_API_APPLEHTTP_PROTO
-URLProtocol ff_applehttp_protocol = {
-    .name           = "applehttp",
-    .url_open       = hls_open,
-    .url_read       = hls_read,
-    .url_close      = hls_close,
-    .flags          = URL_PROTOCOL_FLAG_NESTED_SCHEME,
-    .priv_data_size = sizeof(HLSContext),
-};
-#endif
-
 URLProtocol ff_hls_protocol = {
     .name           = "hls",
     .url_open       = hls_open,
diff --git a/libavformat/hnm.c b/libavformat/hnm.c
new file mode 100644
index 0000000..ee34a14
--- /dev/null
+++ b/libavformat/hnm.c
@@ -0,0 +1,204 @@
+/*
+ * Cryo Interactive Entertainment HNM4 demuxer
+ *
+ * Copyright (c) 2012 David Kment
+ *
+ * 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/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+
+#define HNM4_TAG MKTAG('H', 'N', 'M', '4')
+
+#define HNM4_SAMPLE_RATE 22050
+#define HNM4_FRAME_FPS 24
+
+#define HNM4_CHUNK_ID_PL 19536
+#define HNM4_CHUNK_ID_IZ 23113
+#define HNM4_CHUNK_ID_IU 21833
+#define HNM4_CHUNK_ID_SD 17491
+
+typedef struct Hnm4DemuxContext {
+    uint8_t version;
+    uint16_t width;
+    uint16_t height;
+    uint32_t filesize;
+    uint32_t frames;
+    uint32_t taboffset;
+    uint16_t bits;
+    uint16_t channels;
+    uint32_t framesize;
+    uint32_t currentframe;
+    int64_t pts;
+    uint32_t superchunk_remaining;
+    AVPacket vpkt;
+} Hnm4DemuxContext;
+
+static int hnm_probe(AVProbeData *p)
+{
+    if (p->buf_size < 4)
+        return 0;
+
+    // check for HNM4 header.
+    // currently only HNM v4/v4A is supported
+    if (AV_RL32(&p->buf[0]) == HNM4_TAG)
+        return AVPROBE_SCORE_MAX;
+
+    return 0;
+}
+
+static int hnm_read_header(AVFormatContext *s)
+{
+    Hnm4DemuxContext *hnm = s->priv_data;
+    AVIOContext *pb = s->pb;
+    AVStream *vst;
+
+    /* default context members */
+    hnm->pts = 0;
+    av_init_packet(&hnm->vpkt);
+    hnm->vpkt.data = NULL;
+    hnm->vpkt.size = 0;
+
+    hnm->superchunk_remaining = 0;
+
+    avio_skip(pb, 8);
+    hnm->width     = avio_rl16(pb);
+    hnm->height    = avio_rl16(pb);
+    hnm->filesize  = avio_rl32(pb);
+    hnm->frames    = avio_rl32(pb);
+    hnm->taboffset = avio_rl32(pb);
+    hnm->bits      = avio_rl16(pb);
+    hnm->channels  = avio_rl16(pb);
+    hnm->framesize = avio_rl32(pb);
+    avio_skip(pb, 32);
+
+    hnm->currentframe = 0;
+
+    if (hnm->width  < 320 || hnm->width  > 640 ||
+        hnm->height < 150 || hnm->height > 480) {
+        av_log(s, AV_LOG_ERROR,
+               "invalid resolution: %ux%u\n", hnm->width, hnm->height);
+        return AVERROR_INVALIDDATA;
+    }
+
+    // TODO: find a better way to detect HNM4A
+    if (hnm->width == 640)
+        hnm->version = 0x4a;
+    else
+        hnm->version = 0x40;
+
+    if (!(vst = avformat_new_stream(s, NULL)))
+        return AVERROR(ENOMEM);
+
+    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    vst->codec->codec_id   = AV_CODEC_ID_HNM4_VIDEO;
+    vst->codec->codec_tag  = 0;
+    vst->codec->width      = hnm->width;
+    vst->codec->height     = hnm->height;
+    vst->codec->extradata  = av_mallocz(1);
+
+    vst->codec->extradata_size = 1;
+    memcpy(vst->codec->extradata, &hnm->version, 1);
+
+    vst->start_time = 0;
+
+    avpriv_set_pts_info(vst, 33, 1, HNM4_FRAME_FPS);
+
+    return 0;
+}
+
+static int hnm_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    Hnm4DemuxContext *hnm = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int ret = 0;
+
+    uint32_t superchunk_size, chunk_size;
+    uint16_t chunk_id;
+
+    if (hnm->currentframe == hnm->frames || pb->eof_reached)
+        return AVERROR_EOF;
+
+    if (hnm->superchunk_remaining == 0) {
+        /* parse next superchunk */
+        superchunk_size = avio_rl24(pb);
+        avio_skip(pb, 1);
+
+        hnm->superchunk_remaining = superchunk_size - 4;
+    }
+
+    chunk_size = avio_rl24(pb);
+    avio_skip(pb, 1);
+    chunk_id = avio_rl16(pb);
+    avio_skip(pb, 2);
+
+    if (chunk_size > hnm->superchunk_remaining) {
+        av_log(s, AV_LOG_ERROR, "invalid chunk size: %u, offset: %u\n",
+               chunk_size, (int) avio_tell(pb));
+        avio_skip(pb, hnm->superchunk_remaining - 8);
+        hnm->superchunk_remaining = 0;
+    }
+
+    switch (chunk_id) {
+    case HNM4_CHUNK_ID_PL:
+    case HNM4_CHUNK_ID_IZ:
+    case HNM4_CHUNK_ID_IU:
+        avio_seek(pb, -8, SEEK_CUR);
+        ret += av_get_packet(pb, pkt, chunk_size);
+        hnm->superchunk_remaining -= chunk_size;
+        if (chunk_id == HNM4_CHUNK_ID_IZ || chunk_id == HNM4_CHUNK_ID_IU)
+            hnm->currentframe++;
+        break;
+
+    case HNM4_CHUNK_ID_SD:
+        avio_skip(pb, chunk_size - 8);
+        hnm->superchunk_remaining -= chunk_size;
+        break;
+
+    default:
+        av_log(s, AV_LOG_WARNING, "unknown chunk found: %d, offset: %d\n",
+               chunk_id, (int) avio_tell(pb));
+        avio_skip(pb, chunk_size - 8);
+        hnm->superchunk_remaining -= chunk_size;
+        break;
+    }
+
+    return ret;
+}
+
+static int hnm_read_close(AVFormatContext *s)
+{
+    Hnm4DemuxContext *hnm = s->priv_data;
+
+    if (hnm->vpkt.size > 0)
+        av_free_packet(&hnm->vpkt);
+
+    return 0;
+}
+
+AVInputFormat ff_hnm_demuxer = {
+    .name           = "hnm",
+    .long_name      = NULL_IF_CONFIG_SMALL("Cryo HNM v4"),
+    .priv_data_size = sizeof(Hnm4DemuxContext),
+    .read_probe     = hnm_probe,
+    .read_header    = hnm_read_header,
+    .read_packet    = hnm_read_packet,
+    .read_close     = hnm_read_close,
+    .flags          = AVFMT_NO_BYTE_SEEK | AVFMT_NOGENSEARCH | AVFMT_NOBINSEARCH
+};
diff --git a/libavformat/http.c b/libavformat/http.c
index 9666ca3..96f56f8 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -29,6 +29,10 @@
 #include "url.h"
 #include "libavutil/opt.h"
 
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif
+
 /* XXX: POST protocol is not completely implemented because avconv uses
    only a subset of it. */
 
@@ -47,7 +51,7 @@ typedef struct {
     int http_code;
     int64_t chunksize;      /**< Used if "Transfer-Encoding: chunked" otherwise -1. */
     int64_t off, filesize;
-    char location[MAX_URL_SIZE];
+    char *location;
     HTTPAuthState auth_state;
     HTTPAuthState proxy_auth_state;
     char *headers;
@@ -58,6 +62,13 @@ typedef struct {
     int multiple_requests;  /**< A flag which indicates if we use persistent connections. */
     uint8_t *post_data;
     int post_datalen;
+#if CONFIG_ZLIB
+    int compressed;
+    z_stream inflate_stream;
+    uint8_t *inflate_buffer;
+#endif
+    AVDictionary *chained_options;
+    int send_expect_100;
 } HTTPContext;
 
 #define OFFSET(x) offsetof(HTTPContext, x)
@@ -68,6 +79,11 @@ static const AVOption options[] = {
 {"headers", "custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
 {"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 },
+{"auth_type", "HTTP authentication type", OFFSET(auth_state.auth_type), AV_OPT_TYPE_INT, {.i64 = HTTP_AUTH_NONE}, HTTP_AUTH_NONE, HTTP_AUTH_BASIC, D|E, "auth_type" },
+{"none", "No auth method set, autodetect", 0, AV_OPT_TYPE_CONST, {.i64 = HTTP_AUTH_NONE}, 0, 0, D|E, "auth_type" },
+{"basic", "HTTP basic authentication", 0, AV_OPT_TYPE_CONST, {.i64 = HTTP_AUTH_BASIC}, 0, 0, D|E, "auth_type" },
+{"send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
+{"location", "The actual location of the data received", OFFSET(location), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
 {NULL}
 };
 #define HTTP_CLASS(flavor)\
@@ -95,7 +111,7 @@ void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
 }
 
 /* return non zero if error */
-static int http_open_cnx(URLContext *h)
+static int http_open_cnx(URLContext *h, AVDictionary **options)
 {
     const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
     char hostname[1024], hoststr[1024], proto[10];
@@ -106,10 +122,6 @@ static int http_open_cnx(URLContext *h)
     HTTPAuthType cur_auth_type, cur_proxy_auth_type;
     HTTPContext *s = h->priv_data;
 
-    proxy_path = getenv("http_proxy");
-    use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
-        av_strstart(proxy_path, "http://", NULL);
-
     /* fill the dest addr */
  redo:
     /* needed in any case to build the host string */
@@ -118,6 +130,10 @@ static int http_open_cnx(URLContext *h)
                  path1, sizeof(path1), s->location);
     ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
 
+    proxy_path = getenv("http_proxy");
+    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) &&
+                proxy_path != NULL && av_strstart(proxy_path, "http://", NULL);
+
     if (!strcmp(proto, "https")) {
         lower_proto = "tls";
         use_proxy = 0;
@@ -146,7 +162,7 @@ static int http_open_cnx(URLContext *h)
 
     if (!s->hd) {
         err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
-                         &h->interrupt_callback, NULL);
+                         &h->interrupt_callback, options);
         if (err < 0)
             goto fail;
     }
@@ -199,21 +215,35 @@ static int http_open_cnx(URLContext *h)
 int ff_http_do_new_request(URLContext *h, const char *uri)
 {
     HTTPContext *s = h->priv_data;
+    AVDictionary *options = NULL;
+    int ret;
 
     s->off = 0;
-    av_strlcpy(s->location, uri, sizeof(s->location));
-
-    return http_open_cnx(h);
+    av_free(s->location);
+    s->location = av_strdup(uri);
+    if (!s->location)
+        return AVERROR(ENOMEM);
+
+    av_dict_copy(&options, s->chained_options, 0);
+    ret = http_open_cnx(h, &options);
+    av_dict_free(&options);
+    return ret;
 }
 
-static int http_open(URLContext *h, const char *uri, int flags)
+static int http_open(URLContext *h, const char *uri, int flags,
+                     AVDictionary **options)
 {
     HTTPContext *s = h->priv_data;
+    int ret;
 
     h->is_streamed = 1;
 
     s->filesize = -1;
-    av_strlcpy(s->location, uri, sizeof(s->location));
+    s->location = av_strdup(uri);
+    if (!s->location)
+        return AVERROR(ENOMEM);
+    if (options)
+        av_dict_copy(&s->chained_options, *options, 0);
 
     if (s->headers) {
         int len = strlen(s->headers);
@@ -221,7 +251,10 @@ static int http_open(URLContext *h, const char *uri, int flags)
             av_log(h, AV_LOG_WARNING, "No trailing CRLF found in HTTP header.\n");
     }
 
-    return http_open_cnx(h);
+    ret = http_open_cnx(h, options);
+    if (ret < 0)
+        av_dict_free(&s->chained_options);
+    return ret;
 }
 static int http_getc(HTTPContext *s)
 {
@@ -278,9 +311,9 @@ static int process_line(URLContext *h, char *line, int line_count,
 
     p = line;
     if (line_count == 0) {
-        while (!isspace(*p) && *p != '\0')
+        while (!av_isspace(*p) && *p != '\0')
             p++;
-        while (isspace(*p))
+        while (av_isspace(*p))
             p++;
         s->http_code = strtol(p, &end, 10);
 
@@ -305,10 +338,17 @@ static int process_line(URLContext *h, char *line, int line_count,
         *p = '\0';
         tag = line;
         p++;
-        while (isspace(*p))
+        while (av_isspace(*p))
             p++;
         if (!av_strcasecmp(tag, "Location")) {
-            av_strlcpy(s->location, p, sizeof(s->location));
+            char redirected_location[MAX_URL_SIZE], *new_loc;
+            ff_make_absolute_url(redirected_location, sizeof(redirected_location),
+                                 s->location, p);
+            new_loc = av_strdup(redirected_location);
+            if (!new_loc)
+                return AVERROR(ENOMEM);
+            av_free(s->location);
+            s->location = new_loc;
             *new_location = 1;
         } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
             s->filesize = strtoll(p, NULL, 10);
@@ -336,6 +376,31 @@ static int process_line(URLContext *h, char *line, int line_count,
         } else if (!av_strcasecmp (tag, "Connection")) {
             if (!strcmp(p, "close"))
                 s->willclose = 1;
+        } else if (!av_strcasecmp (tag, "Content-Encoding")) {
+            if (!av_strncasecmp(p, "gzip", 4) || !av_strncasecmp(p, "deflate", 7)) {
+#if CONFIG_ZLIB
+                s->compressed = 1;
+                inflateEnd(&s->inflate_stream);
+                if (inflateInit2(&s->inflate_stream, 32 + 15) != Z_OK) {
+                    av_log(h, AV_LOG_WARNING, "Error during zlib initialisation: %s\n",
+                           s->inflate_stream.msg);
+                    return AVERROR(ENOSYS);
+                }
+                if (zlibCompileFlags() & (1 << 17)) {
+                    av_log(h, AV_LOG_WARNING, "Your zlib was compiled without gzip support.\n");
+                    return AVERROR(ENOSYS);
+                }
+#else
+                av_log(h, AV_LOG_WARNING, "Compressed (%s) content, need zlib with gzip support\n", p);
+                return AVERROR(ENOSYS);
+#endif
+            } else if (!av_strncasecmp(p, "identity", 8)) {
+                // The normal, no-encoding case (although servers shouldn't include
+                // the header at all if this is the case).
+            } else {
+                av_log(h, AV_LOG_WARNING, "Unknown content coding: %s\n", p);
+                return AVERROR(ENOSYS);
+            }
         }
     }
     return 1;
@@ -385,6 +450,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     int64_t off = s->off;
     int len = 0;
     const char *method;
+    int send_expect_100 = 0;
 
 
     /* send http header */
@@ -402,6 +468,17 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
                                            method);
     proxyauthstr = ff_http_auth_create_response(&s->proxy_auth_state, proxyauth,
                                                 local_path, method);
+    if (post && !s->post_data) {
+        send_expect_100 = s->send_expect_100;
+        /* The user has supplied authentication but we don't know the auth type,
+         * send Expect: 100-continue to get the 401 response including the
+         * WWW-Authenticate header, or an 100 continue if no auth actually
+         * is needed. */
+        if (auth && *auth &&
+            s->auth_state.auth_type == HTTP_AUTH_NONE &&
+            s->http_code != 401)
+            send_expect_100 = 1;
+    }
 
     /* set default headers if needed */
     if (!has_header(s->headers, "\r\nUser-Agent: "))
@@ -413,6 +490,9 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     if (!has_header(s->headers, "\r\nRange: ") && !post)
         len += av_strlcatf(headers + len, sizeof(headers) - len,
                            "Range: bytes=%"PRId64"-\r\n", s->off);
+    if (send_expect_100 && !has_header(s->headers, "\r\nExpect: "))
+        len += av_strlcatf(headers + len, sizeof(headers) - len,
+                           "Expect: 100-continue\r\n");
 
     if (!has_header(s->headers, "\r\nConnection: ")) {
         if (s->multiple_requests) {
@@ -467,7 +547,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path,
     s->willclose = 0;
     s->end_chunked_post = 0;
     s->end_header = 0;
-    if (post && !s->post_data) {
+    if (post && !s->post_data && !send_expect_100) {
         /* Pretend that it did work. We didn't read any header yet, since
          * we've still to send the POST data, but the code calling this
          * function will check http_code after we return. */
@@ -508,6 +588,38 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
     return len;
 }
 
+#if CONFIG_ZLIB
+#define DECOMPRESS_BUF_SIZE (256 * 1024)
+static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size)
+{
+    HTTPContext *s = h->priv_data;
+    int ret;
+
+    if (!s->inflate_buffer) {
+        s->inflate_buffer = av_malloc(DECOMPRESS_BUF_SIZE);
+        if (!s->inflate_buffer)
+            return AVERROR(ENOMEM);
+    }
+
+    if (s->inflate_stream.avail_in == 0) {
+        int read = http_buf_read(h, s->inflate_buffer, DECOMPRESS_BUF_SIZE);
+        if (read <= 0)
+            return read;
+        s->inflate_stream.next_in  = s->inflate_buffer;
+        s->inflate_stream.avail_in = read;
+    }
+
+    s->inflate_stream.avail_out = size;
+    s->inflate_stream.next_out  = buf;
+
+    ret = inflate(&s->inflate_stream, Z_SYNC_FLUSH);
+    if (ret != Z_OK && ret != Z_STREAM_END)
+        av_log(h, AV_LOG_WARNING, "inflate return value: %d, %s\n", ret, s->inflate_stream.msg);
+
+    return size - s->inflate_stream.avail_out;
+}
+#endif
+
 static int http_read(URLContext *h, uint8_t *buf, int size)
 {
     HTTPContext *s = h->priv_data;
@@ -543,6 +655,10 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
         }
         size = FFMIN(size, s->chunksize);
     }
+#if CONFIG_ZLIB
+    if (s->compressed)
+        return http_buf_read_compressed(h, buf, size);
+#endif
     return http_buf_read(h, buf, size);
 }
 
@@ -594,6 +710,11 @@ static int http_close(URLContext *h)
     int ret = 0;
     HTTPContext *s = h->priv_data;
 
+#if CONFIG_ZLIB
+    inflateEnd(&s->inflate_stream);
+    av_freep(&s->inflate_buffer);
+#endif
+
     if (!s->end_chunked_post) {
         /* Close the write direction by sending the end of chunked encoding. */
         ret = http_shutdown(h, h->flags);
@@ -601,6 +722,7 @@ static int http_close(URLContext *h)
 
     if (s->hd)
         ffurl_close(s->hd);
+    av_dict_free(&s->chained_options);
     return ret;
 }
 
@@ -611,6 +733,7 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence)
     int64_t old_off = s->off;
     uint8_t old_buf[BUFFER_SIZE];
     int old_buf_size;
+    AVDictionary *options = NULL;
 
     if (whence == AVSEEK_SIZE)
         return s->filesize;
@@ -628,7 +751,9 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence)
     s->off = off;
 
     /* if it fails, continue on old connection */
-    if (http_open_cnx(h) < 0) {
+    av_dict_copy(&options, s->chained_options, 0);
+    if (http_open_cnx(h, &options) < 0) {
+        av_dict_free(&options);
         memcpy(s->buffer, old_buf, old_buf_size);
         s->buf_ptr = s->buffer;
         s->buf_end = s->buffer + old_buf_size;
@@ -636,6 +761,7 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence)
         s->off = old_off;
         return -1;
     }
+    av_dict_free(&options);
     ffurl_close(old_hd);
     return off;
 }
@@ -650,7 +776,7 @@ http_get_file_handle(URLContext *h)
 #if CONFIG_HTTP_PROTOCOL
 URLProtocol ff_http_protocol = {
     .name                = "http",
-    .url_open            = http_open,
+    .url_open2           = http_open,
     .url_read            = http_read,
     .url_write           = http_write,
     .url_seek            = http_seek,
@@ -665,7 +791,7 @@ URLProtocol ff_http_protocol = {
 #if CONFIG_HTTPS_PROTOCOL
 URLProtocol ff_https_protocol = {
     .name                = "https",
-    .url_open            = http_open,
+    .url_open2           = http_open,
     .url_read            = http_read,
     .url_write           = http_write,
     .url_seek            = http_seek,
diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c
index 774ee21..b96da3e 100644
--- a/libavformat/httpauth.c
+++ b/libavformat/httpauth.c
@@ -27,7 +27,6 @@
 #include "libavutil/md5.h"
 #include "urldecode.h"
 #include "avformat.h"
-#include <ctype.h>
 
 static void handle_basic_params(HTTPAuthState *state, const char *key,
                                 int key_len, char **dest, int *dest_len)
@@ -80,8 +79,8 @@ static void choose_qop(char *qop, int size)
     char *ptr = strstr(qop, "auth");
     char *end = ptr + strlen("auth");
 
-    if (ptr && (!*end || isspace(*end) || *end == ',') &&
-        (ptr == qop || isspace(ptr[-1]) || ptr[-1] == ',')) {
+    if (ptr && (!*end || av_isspace(*end) || *end == ',') &&
+        (ptr == qop || av_isspace(ptr[-1]) || ptr[-1] == ',')) {
         av_strlcpy(qop, "auth", size);
     } else {
         qop[0] = 0;
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 5cc17c4..e5f7486 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -19,72 +19,71 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "id3v2.h"
-#include "id3v1.h"
 #include "libavutil/avstring.h"
-#include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
 #include "avio_internal.h"
 #include "internal.h"
+#include "id3v1.h"
+#include "id3v2.h"
 
 const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
-    { "TALB", "album"},
-    { "TCOM", "composer"},
-    { "TCON", "genre"},
-    { "TCOP", "copyright"},
-    { "TENC", "encoded_by"},
-    { "TIT2", "title"},
-    { "TLAN", "language"},
-    { "TPE1", "artist"},
-    { "TPE2", "album_artist"},
-    { "TPE3", "performer"},
-    { "TPOS", "disc"},
-    { "TPUB", "publisher"},
-    { "TRCK", "track"},
-    { "TSSE", "encoder"},
+    { "TALB", "album"        },
+    { "TCOM", "composer"     },
+    { "TCON", "genre"        },
+    { "TCOP", "copyright"    },
+    { "TENC", "encoded_by"   },
+    { "TIT2", "title"        },
+    { "TLAN", "language"     },
+    { "TPE1", "artist"       },
+    { "TPE2", "album_artist" },
+    { "TPE3", "performer"    },
+    { "TPOS", "disc"         },
+    { "TPUB", "publisher"    },
+    { "TRCK", "track"        },
+    { "TSSE", "encoder"      },
     { 0 }
 };
 
 const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
-    { "TDRL", "date"},
-    { "TDRC", "date"},
-    { "TDEN", "creation_time"},
-    { "TSOA", "album-sort"},
-    { "TSOP", "artist-sort"},
-    { "TSOT", "title-sort"},
+    { "TDRL", "date"          },
+    { "TDRC", "date"          },
+    { "TDEN", "creation_time" },
+    { "TSOA", "album-sort"    },
+    { "TSOP", "artist-sort"   },
+    { "TSOT", "title-sort"    },
     { 0 }
 };
 
 static const AVMetadataConv id3v2_2_metadata_conv[] = {
-    { "TAL",  "album"},
-    { "TCO",  "genre"},
-    { "TT2",  "title"},
-    { "TEN",  "encoded_by"},
-    { "TP1",  "artist"},
-    { "TP2",  "album_artist"},
-    { "TP3",  "performer"},
-    { "TRK",  "track"},
+    { "TAL", "album"        },
+    { "TCO", "genre"        },
+    { "TT2", "title"        },
+    { "TEN", "encoded_by"   },
+    { "TP1", "artist"       },
+    { "TP2", "album_artist" },
+    { "TP3", "performer"    },
+    { "TRK", "track"        },
     { 0 }
 };
 
-
 const char ff_id3v2_tags[][4] = {
-   "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
-   "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
-   "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
-   "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
-   { 0 },
+    "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
+    "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
+    "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
+    "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
+    { 0 },
 };
 
 const char ff_id3v2_4_tags[][4] = {
-   "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
-   "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
-   { 0 },
+    "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
+    "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
+    { 0 },
 };
 
 const char ff_id3v2_3_tags[][4] = {
-   "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
-   { 0 },
+    "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
+    { 0 },
 };
 
 const char *ff_id3v2_picture_types[21] = {
@@ -112,36 +111,36 @@ const char *ff_id3v2_picture_types[21] = {
 };
 
 const CodecMime ff_id3v2_mime_tags[] = {
-    {"image/gif" , AV_CODEC_ID_GIF},
-    {"image/jpeg", AV_CODEC_ID_MJPEG},
-    {"image/jpg",  AV_CODEC_ID_MJPEG},
-    {"image/png" , AV_CODEC_ID_PNG},
-    {"image/tiff", AV_CODEC_ID_TIFF},
-    {"image/bmp",  AV_CODEC_ID_BMP},
-    {"JPG",        AV_CODEC_ID_MJPEG}, /* ID3v2.2  */
-    {"PNG" ,       AV_CODEC_ID_PNG},   /* ID3v2.2  */
-    {"",           AV_CODEC_ID_NONE},
+    { "image/gif",  AV_CODEC_ID_GIF   },
+    { "image/jpeg", AV_CODEC_ID_MJPEG },
+    { "image/jpg",  AV_CODEC_ID_MJPEG },
+    { "image/png",  AV_CODEC_ID_PNG   },
+    { "image/tiff", AV_CODEC_ID_TIFF  },
+    { "image/bmp",  AV_CODEC_ID_BMP   },
+    { "JPG",        AV_CODEC_ID_MJPEG }, /* ID3v2.2  */
+    { "PNG",        AV_CODEC_ID_PNG   }, /* ID3v2.2  */
+    { "",           AV_CODEC_ID_NONE  },
 };
 
-int ff_id3v2_match(const uint8_t *buf, const char * magic)
+int ff_id3v2_match(const uint8_t *buf, const char *magic)
 {
     return  buf[0]         == magic[0] &&
             buf[1]         == magic[1] &&
             buf[2]         == magic[2] &&
-            buf[3]         != 0xff &&
-            buf[4]         != 0xff &&
-           (buf[6] & 0x80) ==    0 &&
-           (buf[7] & 0x80) ==    0 &&
-           (buf[8] & 0x80) ==    0 &&
-           (buf[9] & 0x80) ==    0;
+            buf[3]         != 0xff     &&
+            buf[4]         != 0xff     &&
+           (buf[6] & 0x80) == 0        &&
+           (buf[7] & 0x80) == 0        &&
+           (buf[8] & 0x80) == 0        &&
+           (buf[9] & 0x80) == 0;
 }
 
-int ff_id3v2_tag_len(const uint8_t * buf)
+int ff_id3v2_tag_len(const uint8_t *buf)
 {
     int len = ((buf[6] & 0x7f) << 21) +
               ((buf[7] & 0x7f) << 14) +
               ((buf[8] & 0x7f) << 7) +
-               (buf[9] & 0x7f) +
+              (buf[9] & 0x7f) +
               ID3v2_HEADER_SIZE;
     if (buf[5] & 0x10)
         len += ID3v2_HEADER_SIZE;
@@ -197,7 +196,6 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
     }
 
     switch (encoding) {
-
     case ID3v2_ENCODING_ISO8859:
         while (left && ch) {
             ch = avio_r8(pb);
@@ -233,7 +231,7 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
             PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
         }
         if (left < 0)
-            left += 2; /* did not read last char from pb */
+            left += 2;  /* did not read last char from pb */
         break;
 
     case ID3v2_ENCODING_UTF8:
@@ -259,7 +257,8 @@ static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
 /**
  * Parse a text tag.
  */
-static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key)
+static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
+                      const char *key)
 {
     uint8_t *dst;
     int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
@@ -276,9 +275,9 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const cha
         return;
     }
 
-    if (!(strcmp(key, "TCON") && strcmp(key, "TCO"))
-        && (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1)
-        && genre <= ID3v1_GENRE_MAX) {
+    if (!(strcmp(key, "TCON") && strcmp(key, "TCO"))                         &&
+        (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) &&
+        genre <= ID3v1_GENRE_MAX) {
         av_freep(&dst);
         dst = av_strdup(ff_id3v1_genre_str[genre]);
     } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
@@ -300,10 +299,11 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const cha
 /**
  * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
  */
-static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
+                         char *tag, ID3v2ExtraMeta **extra_meta)
 {
     ID3v2ExtraMetaGEOB *geob_data = NULL;
-    ID3v2ExtraMeta *new_extra = NULL;
+    ID3v2ExtraMeta *new_extra     = NULL;
     char encoding;
     unsigned int len;
 
@@ -312,13 +312,15 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
 
     geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
     if (!geob_data) {
-        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMetaGEOB));
+        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n",
+               sizeof(ID3v2ExtraMetaGEOB));
         return;
     }
 
     new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
     if (!new_extra) {
-        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMeta));
+        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n",
+               sizeof(ID3v2ExtraMeta));
         goto fail;
     }
 
@@ -327,18 +329,19 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
     taglen--;
 
     /* read MIME type (always ISO-8859) */
-    if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, &taglen) < 0
-        || taglen <= 0)
+    if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type,
+                   &taglen) < 0 ||
+        taglen <= 0)
         goto fail;
 
     /* read file name */
-    if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0
-        || taglen <= 0)
+    if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 ||
+        taglen <= 0)
         goto fail;
 
     /* read content description */
-    if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0
-        || taglen < 0)
+    if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 ||
+        taglen < 0)
         goto fail;
 
     if (taglen) {
@@ -349,18 +352,19 @@ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *
             goto fail;
         }
         if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
-            av_log(s, AV_LOG_WARNING, "Error reading GEOB frame, data truncated.\n");
+            av_log(s, AV_LOG_WARNING,
+                   "Error reading GEOB frame, data truncated.\n");
         geob_data->datasize = len;
     } else {
-        geob_data->data = NULL;
+        geob_data->data     = NULL;
         geob_data->datasize = 0;
     }
 
     /* add data to the list */
-    new_extra->tag = "GEOB";
+    new_extra->tag  = "GEOB";
     new_extra->data = geob_data;
     new_extra->next = *extra_meta;
-    *extra_meta = new_extra;
+    *extra_meta     = new_extra;
 
     return;
 
@@ -373,11 +377,12 @@ fail:
 
 static int is_number(const char *str)
 {
-    while (*str >= '0' && *str <= '9') str++;
+    while (*str >= '0' && *str <= '9')
+        str++;
     return !*str;
 }
 
-static AVDictionaryEntry* get_date_tag(AVDictionary *m, const char *tag)
+static AVDictionaryEntry *get_date_tag(AVDictionary *m, const char *tag)
 {
     AVDictionaryEntry *t;
     if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) &&
@@ -389,28 +394,29 @@ static AVDictionaryEntry* get_date_tag(AVDictionary *m, const char *tag)
 static void merge_date(AVDictionary **m)
 {
     AVDictionaryEntry *t;
-    char date[17] = {0};      // YYYY-MM-DD hh:mm
+    char date[17] = { 0 };      // YYYY-MM-DD hh:mm
 
     if (!(t = get_date_tag(*m, "TYER")) &&
         !(t = get_date_tag(*m, "TYE")))
         return;
     av_strlcpy(date, t->value, 5);
     av_dict_set(m, "TYER", NULL, 0);
-    av_dict_set(m, "TYE",  NULL, 0);
+    av_dict_set(m, "TYE", NULL, 0);
 
     if (!(t = get_date_tag(*m, "TDAT")) &&
         !(t = get_date_tag(*m, "TDA")))
         goto finish;
     snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value);
     av_dict_set(m, "TDAT", NULL, 0);
-    av_dict_set(m, "TDA",  NULL, 0);
+    av_dict_set(m, "TDA", NULL, 0);
 
     if (!(t = get_date_tag(*m, "TIME")) &&
         !(t = get_date_tag(*m, "TIM")))
         goto finish;
-    snprintf(date + 10, sizeof(date) - 10, " %.2s:%.2s", t->value, t->value + 2);
+    snprintf(date + 10, sizeof(date) - 10,
+             " %.2s:%.2s", t->value, t->value + 2);
     av_dict_set(m, "TIME", NULL, 0);
-    av_dict_set(m, "TIM",  NULL, 0);
+    av_dict_set(m, "TIM", NULL, 0);
 
 finish:
     if (date[0])
@@ -420,20 +426,21 @@ finish:
 static void free_apic(void *obj)
 {
     ID3v2ExtraMetaAPIC *apic = obj;
-    av_freep(&apic->data);
+    av_buffer_unref(&apic->buf);
     av_freep(&apic->description);
     av_freep(&apic);
 }
 
-static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)
+static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
+                      char *tag, ID3v2ExtraMeta **extra_meta)
 {
     int enc, pic_type;
-    char             mimetype[64];
-    const CodecMime     *mime = ff_id3v2_mime_tags;
-    enum AVCodecID           id = AV_CODEC_ID_NONE;
-    ID3v2ExtraMetaAPIC  *apic = NULL;
+    char mimetype[64];
+    const CodecMime *mime     = ff_id3v2_mime_tags;
+    enum AVCodecID id         = AV_CODEC_ID_NONE;
+    ID3v2ExtraMetaAPIC *apic  = NULL;
     ID3v2ExtraMeta *new_extra = NULL;
-    int64_t               end = avio_tell(pb) + taglen;
+    int64_t end               = avio_tell(pb) + taglen;
 
     if (taglen <= 4)
         goto fail;
@@ -456,7 +463,8 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
         mime++;
     }
     if (id == AV_CODEC_ID_NONE) {
-        av_log(s, AV_LOG_WARNING, "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
+        av_log(s, AV_LOG_WARNING,
+               "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
         goto fail;
     }
     apic->id = id;
@@ -465,27 +473,28 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag
     pic_type = avio_r8(pb);
     taglen--;
     if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
-        av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n", pic_type);
+        av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n",
+               pic_type);
         pic_type = 0;
     }
     apic->type = ff_id3v2_picture_types[pic_type];
 
     /* description and picture data */
     if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {
-        av_log(s, AV_LOG_ERROR, "Error decoding attached picture description.\n");
+        av_log(s, AV_LOG_ERROR,
+               "Error decoding attached picture description.\n");
         goto fail;
     }
 
-    apic->len   = taglen;
-    apic->data  = av_malloc(taglen + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!apic->data || avio_read(pb, apic->data, taglen) != taglen)
+    apic->buf = av_buffer_alloc(taglen + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!apic->buf || avio_read(pb, apic->buf->data, taglen) != taglen)
         goto fail;
-    memset(apic->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    memset(apic->buf->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE);
 
-    new_extra->tag    = "APIC";
-    new_extra->data   = apic;
-    new_extra->next   = *extra_meta;
-    *extra_meta       = new_extra;
+    new_extra->tag  = "APIC";
+    new_extra->data = apic;
+    new_extra->next = *extra_meta;
+    *extra_meta     = new_extra;
 
     return;
 
@@ -499,13 +508,14 @@ fail:
 typedef struct ID3v2EMFunc {
     const char *tag3;
     const char *tag4;
-    void (*read)(AVFormatContext*, AVIOContext*, int, char*, ID3v2ExtraMeta **);
+    void (*read)(AVFormatContext *, AVIOContext *, int, char *,
+                 ID3v2ExtraMeta **);
     void (*free)(void *obj);
 } ID3v2EMFunc;
 
 static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
     { "GEO", "GEOB", read_geobtag, free_geobtag },
-    { "PIC", "APIC", read_apic,    free_apic },
+    { "PIC", "APIC", read_apic,    free_apic    },
     { NULL }
 };
 
@@ -528,7 +538,8 @@ static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
     return NULL;
 }
 
-static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta)
+static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
+                        uint8_t flags, ID3v2ExtraMeta **extra_meta)
 {
     int isv34, tlen, unsync;
     char tag[5];
@@ -538,7 +549,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
     AVIOContext pb;
     AVIOContext *pbx;
     unsigned char *buffer = NULL;
-    int buffer_size = 0;
+    int buffer_size       = 0;
     const ID3v2EMFunc *extra_func;
 
     switch (version) {
@@ -547,13 +558,13 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
             reason = "compression";
             goto error;
         }
-        isv34 = 0;
+        isv34     = 0;
         taghdrlen = 6;
         break;
 
     case 3:
     case 4:
-        isv34 = 1;
+        isv34     = 1;
         taghdrlen = 10;
         break;
 
@@ -567,7 +578,8 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
     if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */
         int extlen = get_size(s->pb, 4);
         if (version == 4)
-            extlen -= 4;     // in v2.4 the length includes the length field we just read
+            /* In v2.4 the length includes the length field we just read. */
+            extlen -= 4;
 
         if (extlen < 0) {
             reason = "invalid extended header length";
@@ -578,24 +590,26 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
 
     while (len >= taghdrlen) {
         unsigned int tflags = 0;
-        int tunsync = 0;
+        int tunsync         = 0;
 
         if (isv34) {
             avio_read(s->pb, tag, 4);
             tag[4] = 0;
-            if(version==3){
+            if (version == 3) {
                 tlen = avio_rb32(s->pb);
-            }else
+            } else
                 tlen = get_size(s->pb, 4);
-            tflags = avio_rb16(s->pb);
+            tflags  = avio_rb16(s->pb);
             tunsync = tflags & ID3v2_FLAG_UNSYNCH;
         } else {
             avio_read(s->pb, tag, 3);
             tag[3] = 0;
-            tlen = avio_rb24(s->pb);
+            tlen   = avio_rb24(s->pb);
         }
         if (tlen < 0 || tlen > len - taghdrlen) {
-            av_log(s, AV_LOG_WARNING, "Invalid size in frame %s, skipping the rest of tag.\n", tag);
+            av_log(s, AV_LOG_WARNING,
+                   "Invalid size in frame %s, skipping the rest of tag.\n",
+                   tag);
             break;
         }
         len -= taghdrlen + tlen;
@@ -603,7 +617,8 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
 
         if (!tlen) {
             if (tag[0])
-                av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n", tag);
+                av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n",
+                       tag);
             continue;
         }
 
@@ -613,10 +628,13 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
         }
 
         if (tflags & (ID3v2_FLAG_ENCRYPTION | ID3v2_FLAG_COMPRESSION)) {
-            av_log(s, AV_LOG_WARNING, "Skipping encrypted/compressed ID3v2 frame %s.\n", tag);
+            av_log(s, AV_LOG_WARNING,
+                   "Skipping encrypted/compressed ID3v2 frame %s.\n", tag);
             avio_skip(s->pb, tlen);
         /* check for text tag or supported special meta tag */
-        } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) {
+        } else if (tag[0] == 'T' ||
+                   (extra_meta &&
+                    (extra_func = get_extra_meta_func(tag, isv34)))) {
             if (unsync || tunsync) {
                 int64_t end = avio_tell(s->pb) + tlen;
                 uint8_t *b;
@@ -634,9 +652,10 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
                         *b++ = val ? val : avio_r8(s->pb);
                     }
                 }
-                ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL, NULL);
+                ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL,
+                                  NULL);
                 tlen = b - buffer;
-                pbx = &pb; // read from sync buffer
+                pbx  = &pb; // read from sync buffer
             } else {
                 pbx = s->pb; // read straight from input
             }
@@ -646,8 +665,7 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
             else
                 /* parse special meta tag */
                 extra_func->read(s, pbx, tlen, tag, extra_meta);
-        }
-        else if (!tag[0]) {
+        } else if (!tag[0]) {
             if (tag[1])
                 av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding");
             avio_skip(s->pb, tlen);
@@ -658,22 +676,25 @@ seek:
         avio_seek(s->pb, next, SEEK_SET);
     }
 
-    if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */
+    /* Footer preset, always 10 bytes, skip over it */
+    if (version == 4 && flags & 0x10)
         end += 10;
 
-  error:
+error:
     if (reason)
-        av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason);
+        av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n",
+               version, reason);
     avio_seek(s->pb, end, SEEK_SET);
     av_free(buffer);
     return;
 }
 
-void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta)
+void ff_id3v2_read(AVFormatContext *s, const char *magic,
+                   ID3v2ExtraMeta **extra_meta)
 {
     int len, ret;
     uint8_t buf[ID3v2_HEADER_SIZE];
-    int     found_header;
+    int found_header;
     int64_t off;
 
     do {
@@ -682,14 +703,14 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra
         ret = avio_read(s->pb, buf, ID3v2_HEADER_SIZE);
         if (ret != ID3v2_HEADER_SIZE)
             break;
-            found_header = ff_id3v2_match(buf, magic);
-            if (found_header) {
+        found_header = ff_id3v2_match(buf, magic);
+        if (found_header) {
             /* parse ID3v2 header */
             len = ((buf[6] & 0x7f) << 21) |
                   ((buf[7] & 0x7f) << 14) |
                   ((buf[8] & 0x7f) << 7) |
                    (buf[9] & 0x7f);
-            ff_id3v2_parse(s, len, buf[3], buf[5], extra_meta);
+            id3v2_parse(s, len, buf[3], buf[5], extra_meta);
         } else {
             avio_seek(s->pb, off, SEEK_SET);
         }
@@ -736,14 +757,13 @@ int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
         av_dict_set(&st->metadata, "comment", apic->type, 0);
 
         av_init_packet(&st->attached_pic);
-        st->attached_pic.data         = apic->data;
-        st->attached_pic.size         = apic->len;
-        st->attached_pic.destruct     = av_destruct_packet;
+        st->attached_pic.buf          = apic->buf;
+        st->attached_pic.data         = apic->buf->data;
+        st->attached_pic.size         = apic->buf->size - FF_INPUT_BUFFER_PADDING_SIZE;
         st->attached_pic.stream_index = st->index;
         st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
 
-        apic->data = NULL;
-        apic->len  = 0;
+        apic->buf = NULL;
     }
 
     return 0;
diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h
index cb2fb02..7cb4296 100644
--- a/libavformat/id3v2.h
+++ b/libavformat/id3v2.h
@@ -67,8 +67,7 @@ typedef struct ID3v2ExtraMetaGEOB {
 } ID3v2ExtraMetaGEOB;
 
 typedef struct ID3v2ExtraMetaAPIC {
-    uint8_t     *data;
-    int          len;
+    AVBufferRef *buf;
     const char  *type;
     uint8_t     *description;
     enum AVCodecID id;
diff --git a/libavformat/idcin.c b/libavformat/idcin.c
index fde8666..2536e8b 100644
--- a/libavformat/idcin.c
+++ b/libavformat/idcin.c
@@ -68,6 +68,8 @@
  *       transmitting them to the video decoder
  */
 
+#include "libavutil/channel_layout.h"
+#include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
@@ -80,13 +82,13 @@ typedef struct IdcinDemuxContext {
     int audio_stream_index;
     int audio_chunk_size1;
     int audio_chunk_size2;
+    int block_align;
 
     /* demux state variables */
     int current_audio_chunk;
     int next_chunk_is_video;
     int audio_present;
-
-    int64_t pts;
+    int64_t first_pkt_pos;
 } IdcinDemuxContext;
 
 static int idcin_probe(AVProbeData *p)
@@ -134,8 +136,8 @@ static int idcin_probe(AVProbeData *p)
     if (number > 2)
         return 0;
 
-    /* return half certainly since this check is a bit sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    /* return half certainty since this check is a bit sketchy */
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int idcin_read_header(AVFormatContext *s)
@@ -145,6 +147,7 @@ static int idcin_read_header(AVFormatContext *s)
     AVStream *st;
     unsigned int width, height;
     unsigned int sample_rate, bytes_per_sample, channels;
+    int ret;
 
     /* get the 5 header parameters */
     width = avio_rl32(pb);
@@ -153,10 +156,38 @@ static int idcin_read_header(AVFormatContext *s)
     bytes_per_sample = avio_rl32(pb);
     channels = avio_rl32(pb);
 
+    if (s->pb->eof_reached) {
+        av_log(s, AV_LOG_ERROR, "incomplete header\n");
+        return s->pb->error ? s->pb->error : AVERROR_EOF;
+    }
+
+    if (av_image_check_size(width, height, 0, s) < 0)
+        return AVERROR_INVALIDDATA;
+    if (sample_rate > 0) {
+        if (sample_rate < 14 || sample_rate > INT_MAX) {
+            av_log(s, AV_LOG_ERROR, "invalid sample rate: %u\n", sample_rate);
+            return AVERROR_INVALIDDATA;
+        }
+        if (bytes_per_sample < 1 || bytes_per_sample > 2) {
+            av_log(s, AV_LOG_ERROR, "invalid bytes per sample: %u\n",
+                   bytes_per_sample);
+            return AVERROR_INVALIDDATA;
+        }
+        if (channels < 1 || channels > 2) {
+            av_log(s, AV_LOG_ERROR, "invalid channels: %u\n", channels);
+            return AVERROR_INVALIDDATA;
+        }
+        idcin->audio_present = 1;
+    } else {
+        /* if sample rate is 0, assume no audio */
+        idcin->audio_present = 0;
+    }
+
     st = avformat_new_stream(s, NULL);
     if (!st)
         return AVERROR(ENOMEM);
     avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);
+    st->start_time = 0;
     idcin->video_stream_index = st->index;
     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codec->codec_id = AV_CODEC_ID_IDCIN;
@@ -167,25 +198,31 @@ static int idcin_read_header(AVFormatContext *s)
     /* load up the Huffman tables into extradata */
     st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
     st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);
-    if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) !=
-        HUFFMAN_TABLE_SIZE)
+    ret = avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE);
+    if (ret < 0) {
+        return ret;
+    } else if (ret != HUFFMAN_TABLE_SIZE) {
+        av_log(s, AV_LOG_ERROR, "incomplete header\n");
         return AVERROR(EIO);
+    }
 
-    /* if sample rate is 0, assume no audio */
-    if (sample_rate) {
+    if (idcin->audio_present) {
         idcin->audio_present = 1;
         st = avformat_new_stream(s, NULL);
         if (!st)
             return AVERROR(ENOMEM);
-        avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);
+        avpriv_set_pts_info(st, 63, 1, sample_rate);
+        st->start_time = 0;
         idcin->audio_stream_index = st->index;
         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
         st->codec->codec_tag = 1;
         st->codec->channels = channels;
+        st->codec->channel_layout = channels > 1 ? AV_CH_LAYOUT_STEREO :
+                                                   AV_CH_LAYOUT_MONO;
         st->codec->sample_rate = sample_rate;
         st->codec->bits_per_coded_sample = bytes_per_sample * 8;
         st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels;
-        st->codec->block_align = bytes_per_sample * channels;
+        st->codec->block_align = idcin->block_align = bytes_per_sample * channels;
         if (bytes_per_sample == 1)
             st->codec->codec_id = AV_CODEC_ID_PCM_U8;
         else
@@ -201,11 +238,10 @@ static int idcin_read_header(AVFormatContext *s)
                 (sample_rate / 14) * bytes_per_sample * channels;
         }
         idcin->current_audio_chunk = 0;
-    } else
-        idcin->audio_present = 1;
+    }
 
     idcin->next_chunk_is_video = 1;
-    idcin->pts = 0;
+    idcin->first_pkt_pos = avio_tell(s->pb);
 
     return 0;
 }
@@ -225,7 +261,7 @@ static int idcin_read_packet(AVFormatContext *s,
     uint32_t palette[256];
 
     if (s->pb->eof_reached)
-        return AVERROR(EIO);
+        return s->pb->error ? s->pb->error : AVERROR_EOF;
 
     if (idcin->next_chunk_is_video) {
         command = avio_rl32(pb);
@@ -233,8 +269,13 @@ static int idcin_read_packet(AVFormatContext *s,
             return AVERROR(EIO);
         } else if (command == 1) {
             /* trigger a palette change */
-            if (avio_read(pb, palette_buffer, 768) != 768)
+            ret = avio_read(pb, palette_buffer, 768);
+            if (ret < 0) {
+                return ret;
+            } else if (ret != 768) {
+                av_log(s, AV_LOG_ERROR, "incomplete packet\n");
                 return AVERROR(EIO);
+            }
             /* scale the palette as necessary */
             palette_scale = 2;
             for (i = 0; i < 768; i++)
@@ -251,24 +292,40 @@ static int idcin_read_packet(AVFormatContext *s,
             }
         }
 
+        if (s->pb->eof_reached) {
+            av_log(s, AV_LOG_ERROR, "incomplete packet\n");
+            return s->pb->error ? s->pb->error : AVERROR_EOF;
+        }
         chunk_size = avio_rl32(pb);
+        if (chunk_size < 4 || chunk_size > INT_MAX - 4) {
+            av_log(s, AV_LOG_ERROR, "invalid chunk size: %u\n", chunk_size);
+            return AVERROR_INVALIDDATA;
+        }
         /* skip the number of decoded bytes (always equal to width * height) */
         avio_skip(pb, 4);
         chunk_size -= 4;
         ret= av_get_packet(pb, pkt, chunk_size);
         if (ret < 0)
             return ret;
+        else if (ret != chunk_size) {
+            av_log(s, AV_LOG_ERROR, "incomplete packet\n");
+            av_free_packet(pkt);
+            return AVERROR(EIO);
+        }
         if (command == 1) {
             uint8_t *pal;
 
             pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
                                           AVPALETTE_SIZE);
-            if (ret < 0)
+            if (ret < 0) {
+                av_free_packet(pkt);
                 return ret;
+            }
             memcpy(pal, palette, AVPALETTE_SIZE);
+            pkt->flags |= AV_PKT_FLAG_KEY;
         }
         pkt->stream_index = idcin->video_stream_index;
-        pkt->pts = idcin->pts;
+        pkt->duration     = 1;
     } else {
         /* send out the audio chunk */
         if (idcin->current_audio_chunk)
@@ -279,16 +336,32 @@ static int idcin_read_packet(AVFormatContext *s,
         if (ret < 0)
             return ret;
         pkt->stream_index = idcin->audio_stream_index;
-        pkt->pts = idcin->pts;
+        pkt->duration     = chunk_size / idcin->block_align;
 
         idcin->current_audio_chunk ^= 1;
-        idcin->pts++;
     }
 
     if (idcin->audio_present)
         idcin->next_chunk_is_video ^= 1;
 
-    return ret;
+    return 0;
+}
+
+static int idcin_read_seek(AVFormatContext *s, int stream_index,
+                           int64_t timestamp, int flags)
+{
+    IdcinDemuxContext *idcin = s->priv_data;
+
+    if (idcin->first_pkt_pos > 0) {
+        int ret = avio_seek(s->pb, idcin->first_pkt_pos, SEEK_SET);
+        if (ret < 0)
+            return ret;
+        ff_update_cur_dts(s, s->streams[idcin->video_stream_index], 0);
+        idcin->next_chunk_is_video = 1;
+        idcin->current_audio_chunk = 0;
+        return 0;
+    }
+    return -1;
 }
 
 AVInputFormat ff_idcin_demuxer = {
@@ -298,4 +371,6 @@ AVInputFormat ff_idcin_demuxer = {
     .read_probe     = idcin_probe,
     .read_header    = idcin_read_header,
     .read_packet    = idcin_read_packet,
+    .read_seek      = idcin_read_seek,
+    .flags          = AVFMT_NO_BYTE_SEEK,
 };
diff --git a/libavformat/ilbc.c b/libavformat/ilbc.c
index c01eb6f..e44af48 100644
--- a/libavformat/ilbc.c
+++ b/libavformat/ilbc.c
@@ -56,7 +56,6 @@ static int ilbc_write_header(AVFormatContext *s)
 static int ilbc_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     avio_write(s->pb, pkt->data, pkt->size);
-    avio_flush(s->pb);
     return 0;
 }
 
diff --git a/libavformat/img2.c b/libavformat/img2.c
index 6ee8f81..493df6d 100644
--- a/libavformat/img2.c
+++ b/libavformat/img2.c
@@ -31,8 +31,11 @@ typedef struct {
 static const IdStrMap img_tags[] = {
     { AV_CODEC_ID_MJPEG,      "jpeg"     },
     { AV_CODEC_ID_MJPEG,      "jpg"      },
+    { AV_CODEC_ID_MJPEG,      "jps"      },
+    { AV_CODEC_ID_MJPEG,      "mpo"      },
     { AV_CODEC_ID_LJPEG,      "ljpg"     },
     { 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"      },
@@ -62,8 +65,10 @@ static const IdStrMap img_tags[] = {
     { AV_CODEC_ID_SUNRAST,    "sunras"   },
     { AV_CODEC_ID_JPEG2000,   "jp2"      },
     { AV_CODEC_ID_JPEG2000,   "jpc"      },
+    { AV_CODEC_ID_JPEG2000,   "j2k"      },
     { AV_CODEC_ID_DPX,        "dpx"      },
     { AV_CODEC_ID_PICTOR,     "pic"      },
+    { AV_CODEC_ID_WEBP,       "webp"     },
     { 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 1d437f5..9acb6f6 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -130,7 +130,7 @@ static int img_read_probe(AVProbeData *p)
         if (av_filename_number_test(p->filename))
             return AVPROBE_SCORE_MAX;
         else
-            return AVPROBE_SCORE_MAX / 2;
+            return AVPROBE_SCORE_EXTENSION;
     }
     return 0;
 }
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index aed61d9..7b94869 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -33,6 +33,7 @@ typedef struct {
     int img_number;
     int is_pipe;
     char path[1024];
+    int update;
 } VideoMuxData;
 
 static int write_header(AVFormatContext *s)
@@ -59,8 +60,10 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
     int i;
 
     if (!img->is_pipe) {
-        if (av_get_frame_filename(filename, sizeof(filename),
-                                  img->path, img->img_number) < 0 && img->img_number > 1) {
+        if (img->update) {
+            av_strlcpy(filename, img->path, sizeof(filename));
+        } else if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 &&
+                   img->img_number > 1) {
             av_log(s, AV_LOG_ERROR,
                    "Could not get frame filename number %d from pattern '%s'\n",
                    img->img_number, img->path);
@@ -128,6 +131,7 @@ error:
 #define ENC AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption muxoptions[] = {
     { "start_number", "first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, ENC },
+    { "update",       "continuously overwrite one file", OFFSET(update),  AV_OPT_TYPE_INT, { .i64 = 0 }, 0,       1, ENC },
     { NULL },
 };
 
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 3ca2d8f..e92f476 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -91,31 +91,6 @@ void ff_read_frame_flush(AVFormatContext *s);
 uint64_t ff_ntp_time(void);
 
 /**
- * Assemble a URL string from components. This is the reverse operation
- * of av_url_split.
- *
- * Note, this requires networking to be initialized, so the caller must
- * ensure ff_network_init has been called.
- *
- * @see av_url_split
- *
- * @param str the buffer to fill with the url
- * @param size the size of the str buffer
- * @param proto the protocol identifier, if null, the separator
- *              after the identifier is left out, too
- * @param authorization an optional authorization string, may be null.
- *                      An empty string is treated the same as a null string.
- * @param hostname the host name string
- * @param port the port number, left out from the string if negative
- * @param fmt a generic format string for everything to add after the
- *            host/port, may be null
- * @return the number of characters written to the destination buffer
- */
-int ff_url_join(char *str, int size, const char *proto,
-                const char *authorization, const char *hostname,
-                int port, const char *fmt, ...) av_printf_format(7, 8);
-
-/**
  * Append the media-specific SDP fragment for the media stream c
  * to the buffer buff.
  *
@@ -241,17 +216,6 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base,
  */
 void ff_reduce_index(AVFormatContext *s, int stream_index);
 
-/*
- * Convert a relative url into an absolute url, given a base url.
- *
- * @param buf the buffer where output absolute url is written
- * @param size the size of buf
- * @param base the base url, may be equal to buf.
- * @param rel the new url, which is interpreted relative to base
- */
-void ff_make_absolute_url(char *buf, int size, const char *base,
-                          const char *rel);
-
 enum AVCodecID ff_guess_image2_codec(const char *filename);
 
 /**
@@ -375,4 +339,10 @@ enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag);
  */
 enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags);
 
+/**
+ * Generate standard extradata for AVC-Intra based on width/height and field
+ * order.
+ */
+int ff_generate_avci_extradata(AVStream *st);
+
 #endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/isom.c b/libavformat/isom.c
index ccf4ca1..9b32b7d 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -21,8 +21,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "avformat.h"
 #include "internal.h"
 #include "isom.h"
@@ -138,6 +136,9 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
 
     { AV_CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') },
 
+    { AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') }, /* HEVC/H.265 which indicates parameter sets shall not be in ES */
+    { AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') }, /* HEVC/H.265 which indicates parameter sets may be in ES */
+
     { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */
     { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') }, /* AVC-Intra  50M 720p24/30/60 */
     { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC-Intra  50M 720p25/50 */
@@ -151,6 +152,7 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
     { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '3') }, /* AVC-Intra 100M 1080p24/30/60 */
     { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC-Intra 100M 1080i50 */
     { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '6') }, /* AVC-Intra 100M 1080i60 */
+    { AV_CODEC_ID_H264, MKTAG('A', 'V', 'i', 'n') }, /* AVC-Intra with implicit SPS/PPS */
 
     { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */
     { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
@@ -224,6 +226,8 @@ const AVCodecTag ff_codec_movvideo_tags[] = {
     { 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_AIC, MKTAG('i', 'c', 'o', 'd') },
+
     { AV_CODEC_ID_NONE, 0 },
 };
 
diff --git a/libavformat/isom.h b/libavformat/isom.h
index 932b1d0..bf0792c 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -190,6 +190,27 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
 #define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO                0x02000000
 #define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES               0x01000000
 
+#define MOV_TKHD_FLAG_ENABLED       0x0001
+#define MOV_TKHD_FLAG_IN_MOVIE      0x0002
+#define MOV_TKHD_FLAG_IN_PREVIEW    0x0004
+#define MOV_TKHD_FLAG_IN_POSTER     0x0008
+
+#define TAG_IS_AVCI(tag)                    \
+    ((tag) == MKTAG('a', 'i', '5', 'p') ||  \
+     (tag) == MKTAG('a', 'i', '5', 'q') ||  \
+     (tag) == MKTAG('a', 'i', '5', '2') ||  \
+     (tag) == MKTAG('a', 'i', '5', '3') ||  \
+     (tag) == MKTAG('a', 'i', '5', '5') ||  \
+     (tag) == MKTAG('a', 'i', '5', '6') ||  \
+     (tag) == MKTAG('a', 'i', '1', 'p') ||  \
+     (tag) == MKTAG('a', 'i', '1', 'q') ||  \
+     (tag) == MKTAG('a', 'i', '1', '2') ||  \
+     (tag) == MKTAG('a', 'i', '1', '3') ||  \
+     (tag) == MKTAG('a', 'i', '1', '5') ||  \
+     (tag) == MKTAG('a', 'i', '1', '6') ||  \
+     (tag) == MKTAG('A', 'V', 'i', 'n'))
+
+
 int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom);
 enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags);
 
diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c
index e045597..3cd1616 100644
--- a/libavformat/ivfenc.c
+++ b/libavformat/ivfenc.c
@@ -53,7 +53,6 @@ static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt)
     avio_wl32(pb, pkt->size);
     avio_wl64(pb, pkt->pts);
     avio_write(pb, pkt->data, pkt->size);
-    avio_flush(pb);
 
     return 0;
 }
diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c
index a10dcca..859fc71 100644
--- a/libavformat/lxfdec.c
+++ b/libavformat/lxfdec.c
@@ -20,15 +20,15 @@
  */
 
 #include "libavutil/intreadwrite.h"
+#include "libavcodec/bytestream.h"
 #include "avformat.h"
 #include "internal.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
 #define LXF_SAMPLERATE          48000
-#define LXF_MAX_AUDIO_PACKET    (8008*15*4) ///< 15-channel 32-bit NTSC audio frame
 
 static const AVCodecTag lxf_tags[] = {
     { AV_CODEC_ID_MJPEG,       0 },
@@ -46,8 +46,8 @@ static const AVCodecTag lxf_tags[] = {
 
 typedef struct {
     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)
@@ -64,12 +64,12 @@ static int lxf_probe(AVProbeData *p)
  * @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;
@@ -105,70 +105,94 @@ static int sync(AVFormatContext *s, uint8_t *header)
 /**
  * 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 = header + LXF_IDENT_LENGTH;
 
     //find and read the ident
     if ((ret = sync(s, header)) < 0)
         return ret;
 
-    //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) {
+    ret = avio_read(pb, header + LXF_IDENT_LENGTH, 8);
+    if (ret != 8)
         return ret < 0 ? ret : AVERROR_EOF;
+
+    version     = bytestream_get_le32(&p);
+    header_size = bytestream_get_le32(&p);
+    if (version > 1)
+        avpriv_request_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;
     }
 
-    if (check_checksum(header))
+    //read the rest of the packet header
+    ret = avio_read(pb, header + (p - header), header_size - (p - header));
+    if (ret != header_size - (p - header))
+        return ret < 0 ? ret : AVERROR_EOF;
+
+    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
-        if (!(st = s->streams[1])) {
+        if (s->nb_streams < 2) {
             av_log(s, AV_LOG_INFO, "got audio packet, but no audio stream present\n");
             break;
         }
 
+        if (version == 0)
+            p += 8;
+        audio_format = bytestream_get_le32(&p);
+        channels     = bytestream_get_le32(&p);
+        track_size   = bytestream_get_le32(&p);
+
+        st = s->streams[1];
+
         //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;
         }
 
         switch (st->codec->bits_per_coded_sample) {
-        case 16: st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; break;
+        case 16: st->codec->codec_id = AV_CODEC_ID_PCM_S16LE_PLANAR; break;
         case 20: st->codec->codec_id = AV_CODEC_ID_PCM_LXF;   break;
-        case 24: st->codec->codec_id = AV_CODEC_ID_PCM_S24LE; break;
-        case 32: st->codec->codec_id = AV_CODEC_ID_PCM_S32LE; break;
+        case 24: st->codec->codec_id = AV_CODEC_ID_PCM_S24LE_PLANAR; break;
+        case 32: st->codec->codec_id = AV_CODEC_ID_PCM_S32LE_PLANAR; break;
         default:
             av_log(s, AV_LOG_WARNING,
                    "only 16-, 20-, 24- and 32-bit PCM currently supported\n");
             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
@@ -185,10 +209,14 @@ static int get_packet_header(AVFormatContext *s, uint8_t *header, uint32_t *form
         }
 
         //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;
     }
 
@@ -199,13 +227,13 @@ static int lxf_read_header(AVFormatContext *s)
 {
     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) {
@@ -242,7 +270,7 @@ static int lxf_read_header(AVFormatContext *s)
     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);
 
@@ -253,81 +281,46 @@ static int lxf_read_header(AVFormatContext *s)
         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;
 }
 
-/**
- * De-planerize the PCM data in lxf->temp
- * FIXME: remove this once support for planar audio is added to libavcodec
- *
- * @param[out] out where to write the de-planerized data to
- * @param[in] bytes the total size of the PCM data
- */
-static void deplanarize(LXFDemuxContext *lxf, AVStream *ast, uint8_t *out, int bytes)
-{
-    int x, y, z, i, bytes_per_sample = ast->codec->bits_per_coded_sample >> 3;
-
-    for (z = i = 0; z < lxf->channels; z++)
-        for (y = 0; y < bytes / bytes_per_sample / lxf->channels; y++)
-            for (x = 0; x < bytes_per_sample; x++, i++)
-                out[x + bytes_per_sample*(z + y*lxf->channels)] = lxf->temp[i];
-}
-
 static int lxf_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     LXFDemuxContext *lxf = s->priv_data;
     AVIOContext   *pb  = s->pb;
-    uint8_t header[LXF_PACKET_HEADER_SIZE], *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);
         return AVERROR(EAGAIN);
     }
 
-    if (stream == 1 && !(ast = s->streams[1])) {
+    if (stream == 1 && s->nb_streams < 2) {
         av_log(s, AV_LOG_ERROR, "got audio packet without having an audio stream\n");
         return AVERROR_INVALIDDATA;
     }
 
-    //make sure the data fits in the de-planerization buffer
-    if (ast && ret > LXF_MAX_AUDIO_PACKET) {
-        av_log(s, AV_LOG_ERROR, "audio packet too large (%i > %i)\n",
-            ret, LXF_MAX_AUDIO_PACKET);
-        return AVERROR_INVALIDDATA;
-    }
-
     if ((ret2 = av_new_packet(pkt, ret)) < 0)
         return ret2;
 
-    //read non-20-bit audio data into lxf->temp so we can deplanarize it
-    buf = ast && ast->codec->codec_id != AV_CODEC_ID_PCM_LXF ? lxf->temp : pkt->data;
-
-    if ((ret2 = avio_read(pb, buf, ret)) != ret) {
+    if ((ret2 = avio_read(pb, pkt->data, ret)) != ret) {
         av_free_packet(pkt);
         return ret2 < 0 ? ret2 : AVERROR_EOF;
     }
 
     pkt->stream_index = stream;
 
-    if (ast) {
-        if(ast->codec->codec_id != AV_CODEC_ID_PCM_LXF)
-            deplanarize(lxf, ast, pkt->data, ret);
-    } else {
+    if (!stream) {
         //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..04bd062 100644
--- a/libavformat/m4vdec.c
+++ b/libavformat/m4vdec.c
@@ -45,7 +45,7 @@ static int mpeg4video_probe(AVProbeData *probe_packet)
     }
 
     if (VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res==0)
-        return AVPROBE_SCORE_MAX/2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index edb7ab7..410e2f4 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -70,16 +70,17 @@ const CodecTags ff_mkv_codec_tags[]={
     {"V_MPEG4/ISO/AP"   , AV_CODEC_ID_MPEG4},
     {"V_MPEG4/ISO/SP"   , AV_CODEC_ID_MPEG4},
     {"V_MPEG4/ISO/AVC"  , AV_CODEC_ID_H264},
+    {"V_MPEGH/ISO/HEVC" , AV_CODEC_ID_HEVC},
     {"V_MPEG4/MS/V3"    , AV_CODEC_ID_MSMPEG4V3},
     {"V_PRORES"         , AV_CODEC_ID_PRORES},
     {"V_REAL/RV10"      , AV_CODEC_ID_RV10},
     {"V_REAL/RV20"      , AV_CODEC_ID_RV20},
     {"V_REAL/RV30"      , AV_CODEC_ID_RV30},
     {"V_REAL/RV40"      , AV_CODEC_ID_RV40},
-    {"V_SNOW"           , AV_CODEC_ID_SNOW},
     {"V_THEORA"         , AV_CODEC_ID_THEORA},
     {"V_UNCOMPRESSED"   , AV_CODEC_ID_RAWVIDEO},
     {"V_VP8"            , AV_CODEC_ID_VP8},
+    {"V_VP9"            , AV_CODEC_ID_VP9},
 
     {""                 , AV_CODEC_ID_NONE}
 };
diff --git a/libavformat/matroska.h b/libavformat/matroska.h
index b1f7ae4..0dbc724 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -176,6 +176,7 @@
 #define MATROSKA_ID_BLOCK      0xA1
 #define MATROSKA_ID_BLOCKDURATION 0x9B
 #define MATROSKA_ID_BLOCKREFERENCE 0xFB
+#define MATROSKA_ID_CODECSTATE 0xA4
 
 /* IDs in the attachments master */
 #define MATROSKA_ID_ATTACHEDFILE        0x61A7
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 8a0c91b..bcd7d1a 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -500,6 +500,7 @@ static EbmlSyntax matroska_blockgroup[] = {
     { MATROSKA_ID_SIMPLEBLOCK,    EBML_BIN,  0, offsetof(MatroskaBlock,bin) },
     { MATROSKA_ID_BLOCKDURATION,  EBML_UINT, 0, offsetof(MatroskaBlock,duration), {.u=AV_NOPTS_VALUE} },
     { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) },
+    { MATROSKA_ID_CODECSTATE,     EBML_NONE },
     { 1,                          EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} },
     { 0 }
 };
@@ -556,6 +557,35 @@ static EbmlSyntax matroska_clusters_incremental[] = {
 
 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)
+        goto eof;
+
+    id = avio_rb32(pb);
+
+    // try to find a toplevel element
+    while (!pb->eof_reached) {
+        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.
  */
@@ -704,9 +734,11 @@ static int ebml_read_ascii(AVIOContext *pb, int size, char **str)
 static int ebml_read_binary(AVIOContext *pb, int length, EbmlBin *bin)
 {
     av_free(bin->data);
-    if (!(bin->data = av_malloc(length)))
+    if (!(bin->data = av_malloc(length + FF_INPUT_BUFFER_PADDING_SIZE)))
         return AVERROR(ENOMEM);
 
+    memset(bin->data + length, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
     bin->size = length;
     bin->pos  = avio_tell(pb);
     if (avio_read(pb, bin->data, length) != length) {
@@ -821,7 +853,13 @@ static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
             break;
         case EBML_STR:
         case EBML_UTF8:
-            *(char    **)((char *)data+syntax[i].data_offset) = av_strdup(syntax[i].def.s);
+            // the default may be NULL
+            if (syntax[i].def.s) {
+                uint8_t **dst = (uint8_t**)((uint8_t*)data + syntax[i].data_offset);
+                *dst = av_strdup(syntax[i].def.s);
+                if (!*dst)
+                    return AVERROR(ENOMEM);
+            }
             break;
         }
 
@@ -848,15 +886,16 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska,
     uint32_t id = syntax->id;
     uint64_t length;
     int res;
-    void *newelem;
 
     data = (char *)data + syntax->data_offset;
     if (syntax->list_elem_size) {
         EbmlList *list = data;
-        newelem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size);
-        if (!newelem)
-            return AVERROR(ENOMEM);
-        list->elem = newelem;
+        if ((res = av_reallocp_array(&list->elem,
+                                     list->nb_elem + 1,
+                                     syntax->list_elem_size)) < 0) {
+            list->nb_elem = 0;
+            return res;
+        }
         data = (char*)list->elem + list->nb_elem*syntax->list_elem_size;
         memset(data, 0, syntax->list_elem_size);
         list->nb_elem++;
@@ -962,7 +1001,7 @@ static int matroska_probe(AVProbeData *p)
     }
 
     // probably valid EBML header but no recognized doctype
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska,
@@ -1107,7 +1146,8 @@ static int matroska_decode_buffer(uint8_t** buf, int* buf_size,
 static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska,
                                     AVPacket *pkt, uint64_t display_duration)
 {
-    char *line, *layer, *ptr = pkt->data, *end = ptr+pkt->size;
+    AVBufferRef *line;
+    char *layer, *ptr = pkt->data, *end = ptr+pkt->size;
     for (; *ptr!=',' && ptr<end-1; ptr++);
     if (*ptr == ',')
         layer = ++ptr;
@@ -1125,13 +1165,14 @@ static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska,
         es = ec/   100;  ec -=    100*es;
         *ptr++ = '\0';
         len = 50 + end-ptr + FF_INPUT_BUFFER_PADDING_SIZE;
-        if (!(line = av_malloc(len)))
+        if (!(line = av_buffer_alloc(len)))
             return;
-        snprintf(line,len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n",
+        snprintf(line->data, len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n",
                  layer, sh, sm, ss, sc, eh, em, es, ec, ptr);
-        av_free(pkt->data);
-        pkt->data = line;
-        pkt->size = strlen(line);
+        av_buffer_unref(&pkt->buf);
+        pkt->buf  = line;
+        pkt->data = line->data;
+        pkt->size = strlen(line->data);
     }
 }
 
@@ -1360,6 +1401,7 @@ static int matroska_read_header(AVFormatContext *s)
     MatroskaChapter *chapters;
     MatroskaTrack *tracks;
     uint64_t max_start = 0;
+    int64_t pos;
     Ebml ebml = { 0 };
     AVStream *st;
     int i, j, res;
@@ -1390,8 +1432,16 @@ static int matroska_read_header(AVFormatContext *s)
     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)
@@ -1405,7 +1455,7 @@ static int matroska_read_header(AVFormatContext *s)
     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;
@@ -1495,7 +1545,7 @@ static int matroska_read_header(AVFormatContext *s)
                    && track->codec_priv.data != NULL) {
             int ret;
             ffio_init_context(&b, track->codec_priv.data, track->codec_priv.size,
-                          AVIO_FLAG_READ, NULL, NULL, NULL, NULL);
+                              0, NULL, NULL, NULL, NULL);
             ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size);
             if (ret < 0)
                 return ret;
@@ -1645,14 +1695,12 @@ static int matroska_read_header(AVFormatContext *s)
                       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 (st->codec->codec_id != AV_CODEC_ID_H264 &&
+                st->codec->codec_id != AV_CODEC_ID_HEVC)
+                st->need_parsing = AVSTREAM_PARSE_HEADERS;
             if (track->default_duration) {
                 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
                           1000000000, track->default_duration, 30000);
-#if FF_API_R_FRAME_RATE
-                st->r_frame_rate = st->avg_frame_rate;
-#endif
             }
         } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
             st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -1934,6 +1982,88 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska,
 
     return 0;
 }
+
+/* reconstruct full wavpack blocks from mangled matroska ones */
+static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src,
+                                  uint8_t **pdst, int *size)
+{
+    uint8_t *dst = NULL;
+    int dstlen   = 0;
+    int srclen   = *size;
+    uint32_t samples;
+    uint16_t ver;
+    int ret, offset = 0;
+
+    if (srclen < 12 || track->stream->codec->extradata_size < 2)
+        return AVERROR_INVALIDDATA;
+
+    ver = AV_RL16(track->stream->codec->extradata);
+
+    samples = AV_RL32(src);
+    src    += 4;
+    srclen -= 4;
+
+    while (srclen >= 8) {
+        int multiblock;
+        uint32_t blocksize;
+        uint8_t *tmp;
+
+        uint32_t flags = AV_RL32(src);
+        uint32_t crc   = AV_RL32(src + 4);
+        src    += 8;
+        srclen -= 8;
+
+        multiblock = (flags & 0x1800) != 0x1800;
+        if (multiblock) {
+            if (srclen < 4) {
+                ret = AVERROR_INVALIDDATA;
+                goto fail;
+            }
+            blocksize = AV_RL32(src);
+            src    += 4;
+            srclen -= 4;
+        } else
+            blocksize = srclen;
+
+        if (blocksize > srclen) {
+            ret = AVERROR_INVALIDDATA;
+            goto fail;
+        }
+
+        tmp = av_realloc(dst, dstlen + blocksize + 32);
+        if (!tmp) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        dst     = tmp;
+        dstlen += blocksize + 32;
+
+        AV_WL32(dst + offset,      MKTAG('w', 'v', 'p', 'k')); // tag
+        AV_WL32(dst + offset + 4,  blocksize + 24);            // blocksize - 8
+        AV_WL16(dst + offset + 8,  ver);                       // version
+        AV_WL16(dst + offset + 10, 0);                         // track/index_no
+        AV_WL32(dst + offset + 12, 0);                         // total samples
+        AV_WL32(dst + offset + 16, 0);                         // block index
+        AV_WL32(dst + offset + 20, samples);                   // number of samples
+        AV_WL32(dst + offset + 24, flags);                     // flags
+        AV_WL32(dst + offset + 28, crc);                       // crc
+        memcpy (dst + offset + 32, src, blocksize);            // block data
+
+        src    += blocksize;
+        srclen -= blocksize;
+        offset += blocksize + 32;
+    }
+
+    *pdst = dst;
+    *size = dstlen;
+
+    return 0;
+
+fail:
+    av_freep(&dst);
+    return ret;
+}
+
 static int matroska_parse_frame(MatroskaDemuxContext *matroska,
                                 MatroskaTrack *track,
                                 AVStream *st,
@@ -1952,6 +2082,18 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
             return res;
     }
 
+    if (st->codec->codec_id == AV_CODEC_ID_WAVPACK) {
+        uint8_t *wv_data;
+        res = matroska_parse_wavpack(track, pkt_data, &wv_data, &pkt_size);
+        if (res < 0) {
+            av_log(matroska->ctx, AV_LOG_ERROR, "Error parsing a wavpack block.\n");
+            goto fail;
+        }
+        if (pkt_data != data)
+            av_freep(&pkt_data);
+        pkt_data = wv_data;
+    }
+
     if (st->codec->codec_id == AV_CODEC_ID_PRORES)
         offset = 8;
 
@@ -2001,6 +2143,10 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
     }
 
     return 0;
+fail:
+    if (pkt_data != data)
+        av_freep(&pkt_data);
+    return res;
 }
 
 static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
@@ -2193,7 +2339,6 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
                                      pos);
         }
     ebml_free(matroska_cluster, &cluster);
-    if (res < 0)  matroska->done = 1;
     return res;
 }
 
@@ -2203,9 +2348,11 @@ static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
     int ret = 0;
 
     while (!ret && 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)
+            ret = matroska_resync(matroska, pos);
     }
 
     if (ret == AVERROR_INVALIDDATA && pkt->data) {
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index b37d10c..cc645a5 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -19,22 +19,28 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
+#include "avc.h"
 #include "avformat.h"
+#include "avlanguage.h"
+#include "flacenc.h"
 #include "internal.h"
-#include "riff.h"
 #include "isom.h"
 #include "matroska.h"
-#include "avc.h"
-#include "flacenc.h"
-#include "avlanguage.h"
-#include "libavutil/samplefmt.h"
-#include "libavutil/intreadwrite.h"
+#include "riff.h"
+#include "wv.h"
+
+#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
 #include "libavutil/intfloat.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/lfg.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
 #include "libavutil/random_seed.h"
-#include "libavutil/lfg.h"
-#include "libavutil/dict.h"
-#include "libavutil/avstring.h"
+#include "libavutil/samplefmt.h"
+
 #include "libavcodec/xiph.h"
 #include "libavcodec/mpeg4audio.h"
 
@@ -77,6 +83,7 @@ typedef struct {
 #define MODE_WEBM       0x02
 
 typedef struct MatroskaMuxContext {
+    const AVClass  *class;
     int             mode;
     AVIOContext   *dyn_bc;
     ebml_master     segment;
@@ -90,10 +97,15 @@ typedef struct MatroskaMuxContext {
     mkv_cues        *cues;
     mkv_track       *tracks;
 
-    unsigned int    audio_buffer_size;
     AVPacket        cur_audio_pkt;
 
     int have_attachments;
+
+    int reserve_cues_space;
+    int cluster_size_limit;
+    int64_t cues_pos;
+    int64_t cluster_time_limit;
+    int wrote_chapters;
 } MatroskaMuxContext;
 
 
@@ -284,20 +296,21 @@ static mkv_seekhead * mkv_start_seekhead(AVIOContext *pb, int64_t segment_offset
 
 static int mkv_add_seekhead_entry(mkv_seekhead *seekhead, unsigned int elementid, uint64_t filepos)
 {
-    mkv_seekhead_entry *entries = seekhead->entries;
+    int err;
 
     // don't store more elements than we reserved space for
     if (seekhead->max_entries > 0 && seekhead->max_entries <= seekhead->num_entries)
         return -1;
 
-    entries = av_realloc(entries, (seekhead->num_entries + 1) * sizeof(mkv_seekhead_entry));
-    if (entries == NULL)
-        return AVERROR(ENOMEM);
+    if ((err = av_reallocp_array(&seekhead->entries, seekhead->num_entries + 1,
+                                 sizeof(*seekhead->entries))) < 0) {
+        seekhead->num_entries = 0;
+        return err;
+    }
 
-    entries[seekhead->num_entries  ].elementid = elementid;
-    entries[seekhead->num_entries++].segmentpos = filepos - seekhead->segment_offset;
+    seekhead->entries[seekhead->num_entries].elementid    = elementid;
+    seekhead->entries[seekhead->num_entries++].segmentpos = filepos - seekhead->segment_offset;
 
-    seekhead->entries = entries;
     return 0;
 }
 
@@ -366,20 +379,21 @@ static mkv_cues * mkv_start_cues(int64_t segment_offset)
 
 static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos)
 {
-    mkv_cuepoint *entries = cues->entries;
+    int err;
 
     if (ts < 0)
         return 0;
 
-    entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint));
-    if (entries == NULL)
-        return AVERROR(ENOMEM);
+    if ((err = av_reallocp_array(&cues->entries, cues->num_entries + 1,
+                                 sizeof(*cues->entries))) < 0) {
+        cues->num_entries = 0;
+        return err;
+    }
 
-    entries[cues->num_entries  ].pts = ts;
-    entries[cues->num_entries  ].tracknum = stream + 1;
-    entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset;
+    cues->entries[cues->num_entries].pts           = ts;
+    cues->entries[cues->num_entries].tracknum      = stream + 1;
+    cues->entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset;
 
-    cues->entries = entries;
     return 0;
 }
 
@@ -444,6 +458,15 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, AVCodecContex
     return 0;
 }
 
+static int put_wv_codecpriv(AVIOContext *pb, AVCodecContext *codec)
+{
+    if (codec->extradata && codec->extradata_size == 2)
+        avio_write(pb, codec->extradata, 2);
+    else
+        avio_wl16(pb, 0x403); // fallback to the version mentioned in matroska specs
+    return 0;
+}
+
 static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int *sample_rate, int *output_sample_rate)
 {
     MPEG4AudioConfig mp4ac;
@@ -473,6 +496,8 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo
             ret = put_xiph_codecpriv(s, dyn_cp, codec);
         else if (codec->codec_id == AV_CODEC_ID_FLAC)
             ret = ff_flac_write_header(dyn_cp, codec, 1);
+        else if (codec->codec_id == AV_CODEC_ID_WAVPACK)
+            ret = put_wv_codecpriv(dyn_cp, codec);
         else if (codec->codec_id == AV_CODEC_ID_H264)
             ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size);
         else if (codec->codec_id == AV_CODEC_ID_ALAC) {
@@ -567,7 +592,9 @@ static int mkv_write_tracks(AVFormatContext *s)
         tag = av_dict_get(st->metadata, "language", NULL, 0);
         put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
 
-        if (st->disposition)
+        // The default value for TRACKFLAGDEFAULT is 1, so add element
+        // if we need to clear it.
+        if (!(st->disposition & AV_DISPOSITION_DEFAULT))
             put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT));
 
         // look for a codec ID string specific to mkv to use,
@@ -688,7 +715,7 @@ static int mkv_write_chapters(AVFormatContext *s)
     AVRational scale = {1, 1E9};
     int i, ret;
 
-    if (!s->nb_chapters)
+    if (!s->nb_chapters || mkv->wrote_chapters)
         return 0;
 
     ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CHAPTERS, avio_tell(pb));
@@ -721,6 +748,8 @@ static int mkv_write_chapters(AVFormatContext *s)
     }
     end_ebml_master(pb, editionentry);
     end_ebml_master(pb, chapters);
+
+    mkv->wrote_chapters = 1;
     return 0;
 }
 
@@ -967,11 +996,30 @@ static int mkv_write_header(AVFormatContext *s)
     if (mkv->cues == NULL)
         return AVERROR(ENOMEM);
 
+    if (pb->seekable && mkv->reserve_cues_space) {
+        mkv->cues_pos = avio_tell(pb);
+        put_ebml_void(pb, mkv->reserve_cues_space);
+    }
+
     av_init_packet(&mkv->cur_audio_pkt);
     mkv->cur_audio_pkt.size = 0;
-    mkv->audio_buffer_size  = 0;
 
     avio_flush(pb);
+
+    // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
+    // after 4k and on a keyframe
+    if (pb->seekable) {
+        if (mkv->cluster_time_limit < 0)
+            mkv->cluster_time_limit = 5000;
+        if (mkv->cluster_size_limit < 0)
+            mkv->cluster_size_limit = 5 * 1024 * 1024;
+    } else {
+        if (mkv->cluster_time_limit < 0)
+            mkv->cluster_time_limit = 1000;
+        if (mkv->cluster_size_limit < 0)
+            mkv->cluster_size_limit = 32 * 1024;
+    }
+
     return 0;
 }
 
@@ -1044,6 +1092,59 @@ static int mkv_write_ass_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p
     return max_duration;
 }
 
+static int mkv_strip_wavpack(const uint8_t *src, uint8_t **pdst, int *size)
+{
+    uint8_t *dst;
+    int srclen = *size;
+    int offset = 0;
+    int ret;
+
+    dst = av_malloc(srclen);
+    if (!dst)
+        return AVERROR(ENOMEM);
+
+    while (srclen >= WV_HEADER_SIZE) {
+        WvHeader header;
+
+        ret = ff_wv_parse_header(&header, src);
+        if (ret < 0)
+            goto fail;
+        src    += WV_HEADER_SIZE;
+        srclen -= WV_HEADER_SIZE;
+
+        if (srclen < header.blocksize) {
+            ret = AVERROR_INVALIDDATA;
+            goto fail;
+        }
+
+        if (header.initial) {
+            AV_WL32(dst + offset, header.samples);
+            offset += 4;
+        }
+        AV_WL32(dst + offset,     header.flags);
+        AV_WL32(dst + offset + 4, header.crc);
+        offset += 8;
+
+        if (!(header.initial && header.final)) {
+            AV_WL32(dst + offset, header.blocksize);
+            offset += 4;
+        }
+
+        memcpy(dst + offset, src, header.blocksize);
+        src    += header.blocksize;
+        srclen -= header.blocksize;
+        offset += header.blocksize;
+    }
+
+    *pdst = dst;
+    *size = offset;
+
+    return 0;
+fail:
+    av_freep(&dst);
+    return ret;
+}
+
 static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
                             unsigned int blockid, AVPacket *pkt, int flags)
 {
@@ -1059,7 +1160,13 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
     if (codec->codec_id == AV_CODEC_ID_H264 && codec->extradata_size > 0 &&
         (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1))
         ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
-    else
+    else if (codec->codec_id == AV_CODEC_ID_WAVPACK) {
+        int ret = mkv_strip_wavpack(pkt->data, &data, &size);
+        if (ret < 0) {
+            av_log(s, AV_LOG_ERROR, "Error stripping a WavPack packet.\n");
+            return;
+        }
+    } else
         data = pkt->data;
 
     if (codec->codec_id == AV_CODEC_ID_PRORES) {
@@ -1180,46 +1287,50 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
     return 0;
 }
 
-static int mkv_copy_packet(MatroskaMuxContext *mkv, const AVPacket *pkt)
-{
-    uint8_t *data           = mkv->cur_audio_pkt.data;
-    mkv->cur_audio_pkt      = *pkt;
-    mkv->cur_audio_pkt.data = av_fast_realloc(data, &mkv->audio_buffer_size, pkt->size);
-    if (!mkv->cur_audio_pkt.data)
-        return AVERROR(ENOMEM);
-
-    memcpy(mkv->cur_audio_pkt.data, pkt->data, pkt->size);
-    mkv->cur_audio_pkt.size = pkt->size;
-    return 0;
-}
-
 static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     MatroskaMuxContext *mkv = s->priv_data;
-    AVIOContext *pb = s->pb->seekable ? s->pb : mkv->dyn_bc;
-    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
-    int ret, keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);
-    int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
-    int cluster_size = avio_tell(pb) - (s->pb->seekable ? mkv->cluster_pos : 0);
+    int codec_type          = s->streams[pkt->stream_index]->codec->codec_type;
+    int keyframe            = !!(pkt->flags & AV_PKT_FLAG_KEY);
+    int cluster_size;
+    int64_t cluster_time;
+    AVIOContext *pb;
+    int ret;
+
+    if (mkv->tracks[pkt->stream_index].write_dts)
+        cluster_time = pkt->dts - mkv->cluster_pts;
+    else
+        cluster_time = pkt->pts - mkv->cluster_pts;
 
     // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
     // after 4k and on a keyframe
+    if (s->pb->seekable) {
+        pb = s->pb;
+        cluster_size = avio_tell(pb) - mkv->cluster_pos;
+    } else {
+        pb = mkv->dyn_bc;
+        cluster_size = avio_tell(pb);
+    }
+
     if (mkv->cluster_pos &&
-        ((!s->pb->seekable && (cluster_size > 32*1024 || ts > mkv->cluster_pts + 1000))
-         ||                      cluster_size > 5*1024*1024 || ts > mkv->cluster_pts + 5000
-         || (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe && cluster_size > 4*1024))) {
+        (cluster_size > mkv->cluster_size_limit ||
+         cluster_time > mkv->cluster_time_limit ||
+         (codec_type == AVMEDIA_TYPE_VIDEO && keyframe &&
+          cluster_size > 4 * 1024))) {
         av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64
-               " bytes, pts %" PRIu64 "\n", avio_tell(pb), ts);
+               " bytes, pts %" PRIu64 "dts %" PRIu64 "\n",
+               avio_tell(pb), pkt->pts, pkt->dts);
         end_ebml_master(pb, mkv->cluster);
         mkv->cluster_pos = 0;
         if (mkv->dyn_bc)
             mkv_flush_dynbuf(s);
+        avio_flush(s->pb);
     }
 
     // check if we have an audio packet cached
     if (mkv->cur_audio_pkt.size > 0) {
         ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt);
-        mkv->cur_audio_pkt.size = 0;
+        av_free_packet(&mkv->cur_audio_pkt);
         if (ret < 0) {
             av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret);
             return ret;
@@ -1228,13 +1339,41 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     // buffer an audio packet to ensure the packet containing the video
     // keyframe's timecode is contained in the same cluster for WebM
-    if (codec->codec_type == AVMEDIA_TYPE_AUDIO)
-        ret = mkv_copy_packet(mkv, pkt);
-    else
+    if (codec_type == AVMEDIA_TYPE_AUDIO) {
+        mkv->cur_audio_pkt = *pkt;
+        if (pkt->buf) {
+            mkv->cur_audio_pkt.buf = av_buffer_ref(pkt->buf);
+            ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM);
+        } else
+            ret = av_dup_packet(&mkv->cur_audio_pkt);
+    } else
         ret = mkv_write_packet_internal(s, pkt);
     return ret;
 }
 
+static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    MatroskaMuxContext *mkv = s->priv_data;
+    AVIOContext *pb;
+    if (s->pb->seekable)
+        pb = s->pb;
+    else
+        pb = mkv->dyn_bc;
+    if (!pkt) {
+        if (mkv->cluster_pos) {
+            av_log(s, AV_LOG_DEBUG, "Flushing cluster at offset %" PRIu64
+                   " bytes\n", avio_tell(pb));
+            end_ebml_master(pb, mkv->cluster);
+            mkv->cluster_pos = 0;
+            if (mkv->dyn_bc)
+                mkv_flush_dynbuf(s);
+            avio_flush(s->pb);
+        }
+        return 0;
+    }
+    return mkv_write_packet(s, pkt);
+}
+
 static int mkv_write_trailer(AVFormatContext *s)
 {
     MatroskaMuxContext *mkv = s->priv_data;
@@ -1245,7 +1384,7 @@ static int mkv_write_trailer(AVFormatContext *s)
     // check if we have an audio packet cached
     if (mkv->cur_audio_pkt.size > 0) {
         ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt);
-        mkv->cur_audio_pkt.size = 0;
+        av_free_packet(&mkv->cur_audio_pkt);
         if (ret < 0) {
             av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret);
             return ret;
@@ -1259,9 +1398,35 @@ static int mkv_write_trailer(AVFormatContext *s)
         end_ebml_master(pb, mkv->cluster);
     }
 
+    if (mkv->mode != MODE_WEBM) {
+        ret = mkv_write_chapters(s);
+        if (ret < 0) return ret;
+    }
+
     if (pb->seekable) {
         if (mkv->cues->num_entries) {
-            cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
+            if (mkv->reserve_cues_space) {
+                int64_t cues_end;
+
+                currentpos = avio_tell(pb);
+                avio_seek(pb, mkv->cues_pos, SEEK_SET);
+
+                cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
+                cues_end = avio_tell(pb);
+                if (cues_end > cuespos + mkv->reserve_cues_space) {
+                    av_log(s, AV_LOG_ERROR, "Insufficient space reserved for cues: %d "
+                           "(needed: %"PRId64").\n", mkv->reserve_cues_space,
+                           cues_end - cuespos);
+                    return AVERROR(EINVAL);
+                }
+
+                if (cues_end < cuespos + mkv->reserve_cues_space)
+                    put_ebml_void(pb, mkv->reserve_cues_space - (cues_end - cuespos));
+
+                avio_seek(pb, currentpos, SEEK_SET);
+            } else {
+                cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
+            }
 
             ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES, cuespos);
             if (ret < 0) return ret;
@@ -1282,7 +1447,6 @@ static int mkv_write_trailer(AVFormatContext *s)
     av_free(mkv->tracks);
     av_freep(&mkv->cues->entries);
     av_freep(&mkv->cues);
-    av_destruct_packet(&mkv->cur_audio_pkt);
 
     return 0;
 }
@@ -1303,7 +1467,23 @@ static int mkv_query_codec(enum AVCodecID codec_id, int std_compliance)
     return 0;
 }
 
+#define OFFSET(x) offsetof(MatroskaMuxContext, x)
+#define FLAGS AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "reserve_index_space", "Reserve a given amount of space (in bytes) at the beginning of the file for the index (cues).", OFFSET(reserve_cues_space), AV_OPT_TYPE_INT,   { .i64 = 0 },   0, INT_MAX,   FLAGS },
+    { "cluster_size_limit",  "Store at most the provided amount of bytes in a cluster. ",                                     OFFSET(cluster_size_limit), AV_OPT_TYPE_INT  , { .i64 = -1 }, -1, INT_MAX,   FLAGS },
+    { "cluster_time_limit",  "Store at most the provided number of milliseconds in a cluster.",                               OFFSET(cluster_time_limit), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, FLAGS },
+    { NULL },
+};
+
 #if CONFIG_MATROSKA_MUXER
+static const AVClass matroska_class = {
+    .class_name = "matroska muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVOutputFormat ff_matroska_muxer = {
     .name              = "matroska",
     .long_name         = NULL_IF_CONFIG_SMALL("Matroska"),
@@ -1315,19 +1495,27 @@ AVOutputFormat ff_matroska_muxer = {
     .video_codec       = CONFIG_LIBX264_ENCODER ?
                          AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
     .write_header      = mkv_write_header,
-    .write_packet      = mkv_write_packet,
+    .write_packet      = mkv_write_flush_packet,
     .write_trailer     = mkv_write_trailer,
     .flags             = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
-                         AVFMT_TS_NONSTRICT,
+                         AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,
     .codec_tag         = (const AVCodecTag* const []){
          ff_codec_bmp_tags, ff_codec_wav_tags, 0
     },
     .subtitle_codec    = AV_CODEC_ID_SSA,
     .query_codec       = mkv_query_codec,
+    .priv_class        = &matroska_class,
 };
 #endif
 
 #if CONFIG_WEBM_MUXER
+static const AVClass webm_class = {
+    .class_name = "webm muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVOutputFormat ff_webm_muxer = {
     .name              = "webm",
     .long_name         = NULL_IF_CONFIG_SMALL("WebM"),
@@ -1337,14 +1525,21 @@ AVOutputFormat ff_webm_muxer = {
     .audio_codec       = AV_CODEC_ID_VORBIS,
     .video_codec       = AV_CODEC_ID_VP8,
     .write_header      = mkv_write_header,
-    .write_packet      = mkv_write_packet,
+    .write_packet      = mkv_write_flush_packet,
     .write_trailer     = mkv_write_trailer,
     .flags             = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
-                         AVFMT_TS_NONSTRICT,
+                         AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH,
+    .priv_class        = &webm_class,
 };
 #endif
 
 #if CONFIG_MATROSKA_AUDIO_MUXER
+static const AVClass mka_class = {
+    .class_name = "matroska audio muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
 AVOutputFormat ff_matroska_audio_muxer = {
     .name              = "matroska",
     .long_name         = NULL_IF_CONFIG_SMALL("Matroska"),
@@ -1355,9 +1550,11 @@ AVOutputFormat ff_matroska_audio_muxer = {
                          AV_CODEC_ID_VORBIS : AV_CODEC_ID_AC3,
     .video_codec       = AV_CODEC_ID_NONE,
     .write_header      = mkv_write_header,
-    .write_packet      = mkv_write_packet,
+    .write_packet      = mkv_write_flush_packet,
     .write_trailer     = mkv_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT |
+                         AVFMT_ALLOW_FLUSH,
     .codec_tag         = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+    .priv_class        = &mka_class,
 };
 #endif
diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
index 16412c9..9249704 100644
--- a/libavformat/md5enc.c
+++ b/libavformat/md5enc.c
@@ -127,6 +127,7 @@ AVOutputFormat ff_framemd5_muxer = {
     .write_header      = framemd5_write_header,
     .write_packet      = framemd5_write_packet,
     .write_trailer     = framemd5_write_trailer,
-    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT,
+    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
+                         AVFMT_TS_NEGATIVE,
 };
 #endif
diff --git a/libavformat/mm.c b/libavformat/mm.c
index 83539fa..8c9cbd7 100644
--- a/libavformat/mm.c
+++ b/libavformat/mm.c
@@ -79,7 +79,7 @@ static int probe(AVProbeData *p)
         return 0;
 
     /* only return half certainty since this check is a bit sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int read_header(AVFormatContext *s)
diff --git a/libavformat/mmf.c b/libavformat/mmf.c
index 20570f2..61f1d7a 100644
--- a/libavformat/mmf.c
+++ b/libavformat/mmf.c
@@ -21,8 +21,8 @@
 
 #include "libavutil/channel_layout.h"
 #include "avformat.h"
-#include "internal.h"
 #include "avio_internal.h"
+#include "internal.h"
 #include "pcm.h"
 #include "riff.h"
 
@@ -35,7 +35,7 @@ static const int mmf_rates[] = { 4000, 8000, 11025, 22050, 44100 };
 
 static int mmf_rate(int code)
 {
-    if((code < 0) || (code > 4))
+    if ((code < 0) || (code > 4))
         return -1;
     return mmf_rates[code];
 }
@@ -44,8 +44,8 @@ static int mmf_rate(int code)
 static int mmf_rate_code(int rate)
 {
     int i;
-    for(i = 0; i < 5; i++)
-        if(mmf_rates[i] == rate)
+    for (i = 0; i < 5; i++)
+        if (mmf_rates[i] == rate)
             return i;
     return -1;
 }
@@ -69,8 +69,9 @@ static int mmf_write_header(AVFormatContext *s)
     int rate;
 
     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);
+    if (rate < 0) {
+        av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d\n",
+               s->streams[0]->codec->sample_rate);
         return -1;
     }
 
@@ -82,6 +83,9 @@ static int mmf_write_header(AVFormatContext *s)
     avio_w8(pb, 0); /* code type */
     avio_w8(pb, 0); /* status */
     avio_w8(pb, 0); /* counts */
+    end_tag_be(pb, pos);
+
+    pos = ff_start_tag(pb, "OPDA");
     avio_write(pb, "VN:libavcodec,", sizeof("VN:libavcodec,") -1); /* metadata ("ST:songtitle,VN:version,...") */
     end_tag_be(pb, pos);
 
@@ -120,7 +124,7 @@ static int mmf_write_packet(AVFormatContext *s, AVPacket *pkt)
 /* Write a variable-length symbol */
 static void put_varlength(AVIOContext *pb, int val)
 {
-    if(val < 128)
+    if (val < 128)
         avio_w8(pb, val);
     else {
         val -= 128;
@@ -142,7 +146,7 @@ static int mmf_write_trailer(AVFormatContext *s)
         end_tag_be(pb, mmf->atrpos);
         end_tag_be(pb, 8);
 
-        pos = avio_tell(pb);
+        pos  = avio_tell(pb);
         size = pos - mmf->awapos;
 
         /* Fill Atsq chunk */
@@ -197,11 +201,13 @@ static int mmf_read_header(AVFormatContext *s)
     avio_skip(pb, 4); /* file_size */
 
     /* Skip some unused chunks that may or may not be present */
-    for(;; avio_skip(pb, size)) {
-        tag = avio_rl32(pb);
+    for (;; avio_skip(pb, size)) {
+        tag  = avio_rl32(pb);
         size = avio_rb32(pb);
-        if(tag == MKTAG('C','N','T','I')) continue;
-        if(tag == MKTAG('O','P','D','A')) continue;
+        if (tag == MKTAG('C', 'N', 'T', 'I'))
+            continue;
+        if (tag == MKTAG('O', 'P', 'D', 'A'))
+            continue;
         break;
     }
 
@@ -218,8 +224,8 @@ static int mmf_read_header(AVFormatContext *s)
     avio_r8(pb); /* format type */
     avio_r8(pb); /* sequence type */
     params = avio_r8(pb); /* (channel << 7) | (format << 4) | rate */
-    rate = mmf_rate(params & 0x0f);
-    if(rate  < 0) {
+    rate   = mmf_rate(params & 0x0f);
+    if (rate < 0) {
         av_log(s, AV_LOG_ERROR, "Invalid sample rate\n");
         return -1;
     }
@@ -228,11 +234,13 @@ static int mmf_read_header(AVFormatContext *s)
     avio_r8(pb); /* time base g */
 
     /* Skip some unused chunks that may or may not be present */
-    for(;; avio_skip(pb, size)) {
-        tag = avio_rl32(pb);
+    for (;; avio_skip(pb, size)) {
+        tag  = avio_rl32(pb);
         size = avio_rb32(pb);
-        if(tag == MKTAG('A','t','s','q')) continue;
-        if(tag == MKTAG('A','s','p','I')) continue;
+        if (tag == MKTAG('A', 't', 's', 'q'))
+            continue;
+        if (tag == MKTAG('A', 's', 'p', 'I'))
+            continue;
         break;
     }
 
@@ -247,13 +255,14 @@ static int mmf_read_header(AVFormatContext *s)
     if (!st)
         return AVERROR(ENOMEM);
 
-    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_id = AV_CODEC_ID_ADPCM_YAMAHA;
-    st->codec->sample_rate = rate;
-    st->codec->channels = 1;
-    st->codec->channel_layout = AV_CH_LAYOUT_MONO;
+    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id              = AV_CODEC_ID_ADPCM_YAMAHA;
+    st->codec->sample_rate           = rate;
+    st->codec->channels              = 1;
+    st->codec->channel_layout        = AV_CH_LAYOUT_MONO;
     st->codec->bits_per_coded_sample = 4;
-    st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample;
+    st->codec->bit_rate              = st->codec->sample_rate *
+                                       st->codec->bits_per_coded_sample;
 
     avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
 
@@ -262,8 +271,7 @@ static int mmf_read_header(AVFormatContext *s)
 
 #define MAX_SIZE 4096
 
-static int mmf_read_packet(AVFormatContext *s,
-                           AVPacket *pkt)
+static int mmf_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     MMFContext *mmf = s->priv_data;
     int ret, size;
@@ -272,10 +280,10 @@ static int mmf_read_packet(AVFormatContext *s,
         return AVERROR(EIO);
 
     size = MAX_SIZE;
-    if(size > mmf->data_size)
+    if (size > mmf->data_size)
         size = mmf->data_size;
 
-    if(!size)
+    if (!size)
         return AVERROR(EIO);
 
     if (av_new_packet(pkt, size))
@@ -303,17 +311,18 @@ AVInputFormat ff_mmf_demuxer = {
     .read_seek      = ff_pcm_read_seek,
 };
 #endif
+
 #if CONFIG_MMF_MUXER
 AVOutputFormat ff_mmf_muxer = {
-    .name              = "mmf",
-    .long_name         = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
-    .mime_type         = "application/vnd.smaf",
-    .extensions        = "mmf",
-    .priv_data_size    = sizeof(MMFContext),
-    .audio_codec       = AV_CODEC_ID_ADPCM_YAMAHA,
-    .video_codec       = AV_CODEC_ID_NONE,
-    .write_header      = mmf_write_header,
-    .write_packet      = mmf_write_packet,
-    .write_trailer     = mmf_write_trailer,
+    .name           = "mmf",
+    .long_name      = NULL_IF_CONFIG_SMALL("Yamaha SMAF"),
+    .mime_type      = "application/vnd.smaf",
+    .extensions     = "mmf",
+    .priv_data_size = sizeof(MMFContext),
+    .audio_codec    = AV_CODEC_ID_ADPCM_YAMAHA,
+    .video_codec    = AV_CODEC_ID_NONE,
+    .write_header   = mmf_write_header,
+    .write_packet   = mmf_write_packet,
+    .write_trailer  = mmf_write_trailer,
 };
 #endif
diff --git a/libavformat/mmst.c b/libavformat/mmst.c
index 4b96f5d..a17b4c1 100644
--- a/libavformat/mmst.c
+++ b/libavformat/mmst.c
@@ -331,16 +331,16 @@ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst)
 
             // if we successfully read everything.
             if(packet_id_type == mmst->header_packet_id) {
+                int err;
                 packet_type = SC_PKT_ASF_HEADER;
                 // Store the asf header
                 if(!mms->header_parsed) {
-                    void *p = av_realloc(mms->asf_header,
-                                  mms->asf_header_size + mms->remaining_in_len);
-                    if (!p) {
-                        av_freep(&mms->asf_header);
-                        return AVERROR(ENOMEM);
+                    if ((err = av_reallocp(&mms->asf_header,
+                                           mms->asf_header_size +
+                                           mms->remaining_in_len)) < 0) {
+                        mms->asf_header_size = 0;
+                        return err;
                     }
-                    mms->asf_header = p;
                     memcpy(mms->asf_header + mms->asf_header_size,
                            mms->read_in_ptr, mms->remaining_in_len);
                     mms->asf_header_size += mms->remaining_in_len;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 6b89a2d..9b019e1 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3,6 +3,9 @@
  * Copyright (c) 2001 Fabrice Bellard
  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
+ * first version by Francois Revol <revol at free.fr>
+ * seek function by Gael Chardon <gael.dev at 4now.net>
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -21,8 +24,8 @@
  */
 
 #include <limits.h>
+#include <stdint.h>
 
-//#define DEBUG
 //#define MOV_EXPORT_ALL_METADATA
 
 #include "libavutil/attributes.h"
@@ -46,11 +49,6 @@
 #include <zlib.h>
 #endif
 
-/*
- * First version by Francois Revol revol at free.fr
- * Seek function by Gael Chardon gael.dev at 4now.net
- */
-
 #include "qtpalette.h"
 
 
@@ -723,7 +721,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     version = avio_r8(pb);
     if (version > 1) {
-        av_log_ask_for_sample(c->fc, "unsupported version %d\n", version);
+        avpriv_request_sample(c->fc, "Version %d", version);
         return AVERROR_PATCHWELCOME;
     }
     avio_rb24(pb); /* flags */
@@ -881,6 +879,7 @@ static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     AVStream *st;
     uint64_t size;
     uint8_t *buf;
+    int err;
 
     if (c->fc->nb_streams < 1) // will happen with jp2 files
         return 0;
@@ -888,11 +887,11 @@ static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     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;
-    buf= av_realloc(st->codec->extradata, size);
-    if (!buf)
-        return AVERROR(ENOMEM);
-    st->codec->extradata= buf;
-    buf+= st->codec->extradata_size;
+    if ((err = av_reallocp(&st->codec->extradata, size)) < 0) {
+        st->codec->extradata_size = 0;
+        return err;
+    }
+    buf = st->codec->extradata + st->codec->extradata_size;
     st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE;
     AV_WB32(       buf    , atom.size + 8);
     AV_WL32(       buf + 4, atom.type);
@@ -1072,321 +1071,290 @@ enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
     return ff_get_pcm_codec_id(bps, flags & 1, flags & 2, flags & 4 ? -1 : 0);
 }
 
-int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
+static int mov_codec_id(AVStream *st, uint32_t format)
 {
-    AVStream *st;
-    MOVStreamContext *sc;
-    int j, pseudo_stream_id;
+    int id = ff_codec_get_id(ff_codec_movaudio_tags, format);
 
-    if (c->fc->nb_streams < 1)
-        return 0;
-    st = c->fc->streams[c->fc->nb_streams-1];
-    sc = st->priv_data;
-
-    for (pseudo_stream_id = 0;
-         pseudo_stream_id < entries && !pb->eof_reached;
-         pseudo_stream_id++) {
-        //Parsing Sample description table
-        enum AVCodecID id;
-        int dref_id = 1;
-        MOVAtom a = { AV_RL32("stsd") };
-        int64_t start_pos = avio_tell(pb);
-        uint32_t size = avio_rb32(pb); /* size */
-        uint32_t format = avio_rl32(pb); /* data format */
+    if (id <= 0 &&
+        ((format & 0xFFFF) == 'm' + ('s' << 8) ||
+         (format & 0xFFFF) == 'T' + ('S' << 8)))
+        id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);
 
-        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);
-            return AVERROR_INVALIDDATA;
+    if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
+        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    } else if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO &&
+               /* skip old asf mpeg4 tag */
+               format && format != MKTAG('m','p','4','s')) {
+        id = ff_codec_get_id(ff_codec_movvideo_tags, format);
+        if (id <= 0)
+            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) {
+            id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
+            if (id > 0)
+                st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
         }
+    }
 
-        if (st->codec->codec_tag &&
-            st->codec->codec_tag != format &&
-            (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id
-                                   : st->codec->codec_tag != MKTAG('j','p','e','g'))
-           ){
-            /* 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;
-        sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
-        sc->dref_id= dref_id;
+    st->codec->codec_tag = format;
+
+    return id;
+}
+
+static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
+                                 AVStream *st, MOVStreamContext *sc)
+{
+    unsigned int color_depth, len, j;
+    int color_greyscale;
+    int color_table_id;
+
+    avio_rb16(pb); /* version */
+    avio_rb16(pb); /* revision level */
+    avio_rb32(pb); /* vendor */
+    avio_rb32(pb); /* temporal quality */
+    avio_rb32(pb); /* spatial quality */
+
+    st->codec->width  = avio_rb16(pb); /* width */
+    st->codec->height = avio_rb16(pb); /* height */
+
+    avio_rb32(pb); /* horiz resolution */
+    avio_rb32(pb); /* vert resolution */
+    avio_rb32(pb); /* data size, always 0 */
+    avio_rb16(pb); /* frames per samples */
+
+    len = avio_r8(pb); /* codec name, pascal string */
+    if (len > 31)
+        len = 31;
+    mov_read_mac_string(c, pb, len, st->codec->codec_name, 32);
+    if (len < 31)
+        avio_skip(pb, 31 - len);
+    /* codec_tag YV12 triggers an UV swap in rawdec.c */
+    if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25))
+        st->codec->codec_tag = MKTAG('I', '4', '2', '0');
+    /* Flash Media Server uses tag H263 with Sorenson Spark */
+    if (st->codec->codec_tag == MKTAG('H','2','6','3') &&
+        !memcmp(st->codec->codec_name, "Sorenson H263", 13))
+        st->codec->codec_id = AV_CODEC_ID_FLV1;
+
+    st->codec->bits_per_coded_sample = avio_rb16(pb); /* depth */
+    color_table_id = avio_rb16(pb); /* colortable id */
+    av_dlog(c->fc, "depth %d, ctab id %d\n",
+            st->codec->bits_per_coded_sample, color_table_id);
+    /* figure out the palette situation */
+    color_depth     = st->codec->bits_per_coded_sample & 0x1F;
+    color_greyscale = st->codec->bits_per_coded_sample & 0x20;
+
+    /* if the depth is 2, 4, or 8 bpp, file is palettized */
+    if ((color_depth == 2) || (color_depth == 4) || (color_depth == 8)) {
+        /* for palette traversal */
+        unsigned int color_start, color_count, color_end;
+        unsigned char r, g, b;
+
+        if (color_greyscale) {
+            int color_index, color_dec;
+            /* compute the greyscale palette */
+            st->codec->bits_per_coded_sample = color_depth;
+            color_count = 1 << color_depth;
+            color_index = 255;
+            color_dec   = 256 / (color_count - 1);
+            for (j = 0; j < color_count; j++) {
+                r = g = b = color_index;
+                sc->palette[j] = (r << 16) | (g << 8) | (b);
+                color_index -= color_dec;
+                if (color_index < 0)
+                    color_index = 0;
+            }
+        } else if (color_table_id) {
+            const uint8_t *color_table;
+            /* if flag bit 3 is set, use the default palette */
+            color_count = 1 << color_depth;
+            if (color_depth == 2)
+                color_table = ff_qt_default_palette_4;
+            else if (color_depth == 4)
+                color_table = ff_qt_default_palette_16;
+            else
+                color_table = ff_qt_default_palette_256;
 
-        st->codec->codec_tag = format;
-        id = ff_codec_get_id(ff_codec_movaudio_tags, format);
-        if (id<=0 && ((format&0xFFFF) == 'm'+('s'<<8) || (format&0xFFFF) == 'T'+('S'<<8)))
-            id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format)&0xFFFF);
-
-        if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
-            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-        } else if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO && /* do not overwrite codec type */
-                   format && format != MKTAG('m','p','4','s')) { /* skip old asf mpeg4 tag */
-            id = ff_codec_get_id(ff_codec_movvideo_tags, format);
-            if (id <= 0)
-                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){
-                id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
-                if (id > 0)
-                    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+            for (j = 0; j < color_count; j++) {
+                r = color_table[j * 3 + 0];
+                g = color_table[j * 3 + 1];
+                b = color_table[j * 3 + 2];
+                sc->palette[j] = (r << 16) | (g << 8) | (b);
+            }
+        } else {
+            /* load the palette from the file */
+            color_start = avio_rb32(pb);
+            color_count = avio_rb16(pb);
+            color_end   = avio_rb16(pb);
+            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);
+                    avio_r8(pb);
+                    r = avio_r8(pb);
+                    avio_r8(pb);
+                    g = avio_r8(pb);
+                    avio_r8(pb);
+                    b = avio_r8(pb);
+                    avio_r8(pb);
+                    sc->palette[j] = (r << 16) | (g << 8) | (b);
+                }
             }
         }
+        sc->has_palette = 1;
+    }
+}
 
-        av_dlog(c->fc, "size=%d 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);
+static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
+                                 AVStream *st, MOVStreamContext *sc)
+{
+    int bits_per_sample, flags;
+    uint16_t version = avio_rb16(pb);
 
-        if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
-            unsigned int color_depth, len;
-            int color_greyscale;
-            int color_table_id;
+    avio_rb16(pb); /* revision level */
+    avio_rb32(pb); /* vendor */
 
-            st->codec->codec_id = id;
-            avio_rb16(pb); /* version */
-            avio_rb16(pb); /* revision level */
-            avio_rb32(pb); /* vendor */
-            avio_rb32(pb); /* temporal quality */
-            avio_rb32(pb); /* spatial quality */
-
-            st->codec->width = avio_rb16(pb); /* width */
-            st->codec->height = avio_rb16(pb); /* height */
-
-            avio_rb32(pb); /* horiz resolution */
-            avio_rb32(pb); /* vert resolution */
-            avio_rb32(pb); /* data size, always 0 */
-            avio_rb16(pb); /* frames per samples */
-
-            len = avio_r8(pb); /* codec name, pascal string */
-            if (len > 31)
-                len = 31;
-            mov_read_mac_string(c, pb, len, st->codec->codec_name, 32);
-            if (len < 31)
-                avio_skip(pb, 31 - len);
-            /* codec_tag YV12 triggers an UV swap in rawdec.c */
-            if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25))
-                st->codec->codec_tag=MKTAG('I', '4', '2', '0');
-            /* Flash Media Server uses tag H263 with Sorenson Spark */
-            if (format == MKTAG('H','2','6','3') &&
-                !memcmp(st->codec->codec_name, "Sorenson H263", 13))
-                st->codec->codec_id = AV_CODEC_ID_FLV1;
-
-            st->codec->bits_per_coded_sample = avio_rb16(pb); /* depth */
-            color_table_id = avio_rb16(pb); /* colortable id */
-            av_dlog(c->fc, "depth %d, ctab id %d\n",
-                   st->codec->bits_per_coded_sample, color_table_id);
-            /* figure out the palette situation */
-            color_depth = st->codec->bits_per_coded_sample & 0x1F;
-            color_greyscale = st->codec->bits_per_coded_sample & 0x20;
-
-            /* if the depth is 2, 4, or 8 bpp, file is palettized */
-            if ((color_depth == 2) || (color_depth == 4) ||
-                (color_depth == 8)) {
-                /* for palette traversal */
-                unsigned int color_start, color_count, color_end;
-                unsigned char r, g, b;
-
-                if (color_greyscale) {
-                    int color_index, color_dec;
-                    /* compute the greyscale palette */
-                    st->codec->bits_per_coded_sample = color_depth;
-                    color_count = 1 << color_depth;
-                    color_index = 255;
-                    color_dec = 256 / (color_count - 1);
-                    for (j = 0; j < color_count; j++) {
-                        r = g = b = color_index;
-                        sc->palette[j] =
-                            (r << 16) | (g << 8) | (b);
-                        color_index -= color_dec;
-                        if (color_index < 0)
-                            color_index = 0;
-                    }
-                } else if (color_table_id) {
-                    const uint8_t *color_table;
-                    /* if flag bit 3 is set, use the default palette */
-                    color_count = 1 << color_depth;
-                    if (color_depth == 2)
-                        color_table = ff_qt_default_palette_4;
-                    else if (color_depth == 4)
-                        color_table = ff_qt_default_palette_16;
-                    else
-                        color_table = ff_qt_default_palette_256;
-
-                    for (j = 0; j < color_count; j++) {
-                        r = color_table[j * 3 + 0];
-                        g = color_table[j * 3 + 1];
-                        b = color_table[j * 3 + 2];
-                        sc->palette[j] =
-                            (r << 16) | (g << 8) | (b);
-                    }
-                } else {
-                    /* load the palette from the file */
-                    color_start = avio_rb32(pb);
-                    color_count = avio_rb16(pb);
-                    color_end = avio_rb16(pb);
-                    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);
-                            avio_r8(pb);
-                            r = avio_r8(pb);
-                            avio_r8(pb);
-                            g = avio_r8(pb);
-                            avio_r8(pb);
-                            b = avio_r8(pb);
-                            avio_r8(pb);
-                            sc->palette[j] =
-                                (r << 16) | (g << 8) | (b);
-                        }
-                    }
-                }
-                sc->has_palette = 1;
-            }
-        } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
-            int bits_per_sample, flags;
-            uint16_t version = avio_rb16(pb);
+    st->codec->channels              = avio_rb16(pb); /* channel count */
+    st->codec->bits_per_coded_sample = avio_rb16(pb); /* sample size */
+    av_dlog(c->fc, "audio channels %d\n", st->codec->channels);
 
-            st->codec->codec_id = id;
-            avio_rb16(pb); /* revision level */
-            avio_rb32(pb); /* vendor */
-
-            st->codec->channels = avio_rb16(pb);             /* channel count */
-            av_dlog(c->fc, "audio channels %d\n", st->codec->channels);
-            st->codec->bits_per_coded_sample = avio_rb16(pb);      /* sample size */
-
-            sc->audio_cid = avio_rb16(pb);
-            avio_rb16(pb); /* packet size = 0 */
-
-            st->codec->sample_rate = ((avio_rb32(pb) >> 16));
-
-            //Read QT version 1 fields. In version 0 these do not exist.
-            av_dlog(c->fc, "version =%d, isom =%d\n",version,c->isom);
-            if (!c->isom) {
-                if (version==1) {
-                    sc->samples_per_frame = avio_rb32(pb);
-                    avio_rb32(pb); /* bytes per packet */
-                    sc->bytes_per_frame = avio_rb32(pb);
-                    avio_rb32(pb); /* bytes per sample */
-                } else if (version==2) {
-                    avio_rb32(pb); /* sizeof struct only */
-                    st->codec->sample_rate = av_int2double(avio_rb64(pb)); /* float 64 */
-                    st->codec->channels = avio_rb32(pb);
-                    avio_rb32(pb); /* always 0x7F000000 */
-                    st->codec->bits_per_coded_sample = avio_rb32(pb); /* bits per channel if sound is uncompressed */
-                    flags = avio_rb32(pb); /* lpcm format specific flag */
-                    sc->bytes_per_frame = avio_rb32(pb); /* bytes per audio packet if constant */
-                    sc->samples_per_frame = avio_rb32(pb); /* lpcm frames per audio packet if constant */
-                    if (format == MKTAG('l','p','c','m'))
-                        st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, flags);
-                }
-            }
+    sc->audio_cid = avio_rb16(pb);
+    avio_rb16(pb); /* packet size = 0 */
 
-            switch (st->codec->codec_id) {
-            case AV_CODEC_ID_PCM_S8:
-            case AV_CODEC_ID_PCM_U8:
-                if (st->codec->bits_per_coded_sample == 16)
-                    st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
-                break;
-            case AV_CODEC_ID_PCM_S16LE:
-            case AV_CODEC_ID_PCM_S16BE:
-                if (st->codec->bits_per_coded_sample == 8)
-                    st->codec->codec_id = AV_CODEC_ID_PCM_S8;
-                else if (st->codec->bits_per_coded_sample == 24)
-                    st->codec->codec_id =
-                        st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
-                        AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
-                break;
-            /* set values for old format before stsd version 1 appeared */
-            case AV_CODEC_ID_MACE3:
-                sc->samples_per_frame = 6;
-                sc->bytes_per_frame = 2*st->codec->channels;
-                break;
-            case AV_CODEC_ID_MACE6:
-                sc->samples_per_frame = 6;
-                sc->bytes_per_frame = 1*st->codec->channels;
-                break;
-            case AV_CODEC_ID_ADPCM_IMA_QT:
-                sc->samples_per_frame = 64;
-                sc->bytes_per_frame = 34*st->codec->channels;
-                break;
-            case AV_CODEC_ID_GSM:
-                sc->samples_per_frame = 160;
-                sc->bytes_per_frame = 33;
-                break;
-            default:
-                break;
-            }
+    st->codec->sample_rate = ((avio_rb32(pb) >> 16));
 
-            bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
-            if (bits_per_sample) {
-                st->codec->bits_per_coded_sample = bits_per_sample;
-                sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
-            }
-        } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
-            // ttxt stsd contains display flags, justification, background
-            // color, fonts, and default styles, so fake an atom to read it
-            MOVAtom fake_atom = { .size = size - (avio_tell(pb) - start_pos) };
-            if (format != AV_RL32("mp4s")) // mp4s contains a regular esds atom
-                mov_read_glbl(c, pb, fake_atom);
-            st->codec->codec_id= id;
-            st->codec->width = sc->width;
-            st->codec->height = sc->height;
-        } else {
-            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
-            avio_skip(pb, size - (avio_tell(pb) - start_pos));
+    // Read QT version 1 fields. In version 0 these do not exist.
+    av_dlog(c->fc, "version =%d, isom =%d\n", version, c->isom);
+    if (!c->isom) {
+        if (version == 1) {
+            sc->samples_per_frame = avio_rb32(pb);
+            avio_rb32(pb); /* bytes per packet */
+            sc->bytes_per_frame = avio_rb32(pb);
+            avio_rb32(pb); /* bytes per sample */
+        } else if (version == 2) {
+            avio_rb32(pb); /* sizeof struct only */
+            st->codec->sample_rate = av_int2double(avio_rb64(pb));
+            st->codec->channels    = avio_rb32(pb);
+            avio_rb32(pb); /* always 0x7F000000 */
+            st->codec->bits_per_coded_sample = avio_rb32(pb);
+
+            flags = avio_rb32(pb); /* lpcm format specific flag */
+            sc->bytes_per_frame   = avio_rb32(pb);
+            sc->samples_per_frame = avio_rb32(pb);
+            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);
         }
-        /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
-        a.size = size - (avio_tell(pb) - start_pos);
-        if (a.size > 8) {
-            int ret;
-            if ((ret = mov_read_default(c, pb, a)) < 0)
-                return ret;
-        } else if (a.size > 0)
-            avio_skip(pb, a.size);
     }
 
-    if (pb->eof_reached)
-        return AVERROR_EOF;
+    switch (st->codec->codec_id) {
+    case AV_CODEC_ID_PCM_S8:
+    case AV_CODEC_ID_PCM_U8:
+        if (st->codec->bits_per_coded_sample == 16)
+            st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
+        break;
+    case AV_CODEC_ID_PCM_S16LE:
+    case AV_CODEC_ID_PCM_S16BE:
+        if (st->codec->bits_per_coded_sample == 8)
+            st->codec->codec_id = AV_CODEC_ID_PCM_S8;
+        else if (st->codec->bits_per_coded_sample == 24)
+            st->codec->codec_id =
+                st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
+                AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
+        break;
+    /* set values for old format before stsd version 1 appeared */
+    case AV_CODEC_ID_MACE3:
+        sc->samples_per_frame = 6;
+        sc->bytes_per_frame   = 2 * st->codec->channels;
+        break;
+    case AV_CODEC_ID_MACE6:
+        sc->samples_per_frame = 6;
+        sc->bytes_per_frame   = 1 * st->codec->channels;
+        break;
+    case AV_CODEC_ID_ADPCM_IMA_QT:
+        sc->samples_per_frame = 64;
+        sc->bytes_per_frame   = 34 * st->codec->channels;
+        break;
+    case AV_CODEC_ID_GSM:
+        sc->samples_per_frame = 160;
+        sc->bytes_per_frame   = 33;
+        break;
+    default:
+        break;
+    }
+
+    bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
+    if (bits_per_sample) {
+        st->codec->bits_per_coded_sample = bits_per_sample;
+        sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
+    }
+}
 
-    if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
-        st->codec->sample_rate= sc->time_scale;
+static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
+                                    AVStream *st, MOVStreamContext *sc,
+                                    int size)
+{
+    // ttxt stsd contains display flags, justification, background
+    // color, fonts, and default styles, so fake an atom to read it
+    MOVAtom fake_atom = { .size = size };
+    // mp4s contains a regular esds atom
+    if (st->codec->codec_tag != AV_RL32("mp4s"))
+        mov_read_glbl(c, pb, fake_atom);
+    st->codec->width  = sc->width;
+    st->codec->height = sc->height;
+}
+
+static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
+                                AVStream *st, MOVStreamContext *sc,
+                                int size)
+{
+    if (st->codec->codec_tag == MKTAG('t','m','c','d')) {
+        st->codec->extradata_size = size;
+        st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!st->codec->extradata)
+            return AVERROR(ENOMEM);
+        avio_read(pb, st->codec->extradata, size);
+    } else {
+        /* other codec type, just skip (rtp, mp4s ...) */
+        avio_skip(pb, size);
+    }
+    return 0;
+}
+
+static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
+                                   AVStream *st, MOVStreamContext *sc)
+{
+    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+        !st->codec->sample_rate && sc->time_scale > 1)
+        st->codec->sample_rate = sc->time_scale;
 
     /* special codec parameters handling */
     switch (st->codec->codec_id) {
 #if CONFIG_DV_DEMUXER
     case AV_CODEC_ID_DVAUDIO:
-        c->dv_fctx = avformat_alloc_context();
+        c->dv_fctx  = avformat_alloc_context();
         c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
         if (!c->dv_demux) {
             av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
             return AVERROR(ENOMEM);
         }
         sc->dv_audio_container = 1;
-        st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
+        st->codec->codec_id    = AV_CODEC_ID_PCM_S16LE;
         break;
 #endif
     /* no ifdef since parameters are always those */
     case AV_CODEC_ID_QCELP:
+        st->codec->channels = 1;
         // force sample rate for qcelp when not stored in mov
         if (st->codec->codec_tag != MKTAG('Q','c','l','p'))
             st->codec->sample_rate = 8000;
-        st->codec->channels= 1; /* really needed */
         break;
     case AV_CODEC_ID_AMR_NB:
-        st->codec->channels= 1; /* really needed */
+        st->codec->channels    = 1;
         /* force sample rate for amr, stsd in 3gp does not store sample rate */
         st->codec->sample_rate = 8000;
         break;
@@ -1396,8 +1364,9 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
         break;
     case AV_CODEC_ID_MP2:
     case AV_CODEC_ID_MP3:
-        st->codec->codec_type = AVMEDIA_TYPE_AUDIO; /* force type after stsd for m1a hdlr */
-        st->need_parsing = AVSTREAM_PARSE_FULL;
+        /* force type after stsd for m1a hdlr */
+        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+        st->need_parsing      = AVSTREAM_PARSE_FULL;
         break;
     case AV_CODEC_ID_GSM:
     case AV_CODEC_ID_ADPCM_MS:
@@ -1407,8 +1376,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
         break;
     case AV_CODEC_ID_ALAC:
         if (st->codec->extradata_size == 36) {
-            st->codec->channels   = AV_RB8 (st->codec->extradata+21);
-            st->codec->sample_rate = AV_RB32(st->codec->extradata+32);
+            st->codec->channels    = AV_RB8 (st->codec->extradata + 21);
+            st->codec->sample_rate = AV_RB32(st->codec->extradata + 32);
         }
         break;
     case AV_CODEC_ID_VC1:
@@ -1417,10 +1386,109 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
     default:
         break;
     }
+    return 0;
+}
+
+static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
+                                  int codec_tag, int format,
+                                  int size)
+{
+    int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);
+
+    if (codec_tag &&
+        (codec_tag == AV_RL32("avc1") ||
+         codec_tag == AV_RL32("hvc1") ||
+         codec_tag == AV_RL32("hev1") ||
+         (codec_tag != format &&
+          (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
+                                 : codec_tag != MKTAG('j','p','e','g'))))) {
+        /* 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. */
+
+        av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
+        avio_skip(pb, size);
+        return 1;
+    }
 
     return 0;
 }
 
+int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
+{
+    AVStream *st;
+    MOVStreamContext *sc;
+    int pseudo_stream_id;
+
+    if (c->fc->nb_streams < 1)
+        return 0;
+    st = c->fc->streams[c->fc->nb_streams-1];
+    sc = st->priv_data;
+
+    for (pseudo_stream_id = 0;
+         pseudo_stream_id < entries && !pb->eof_reached;
+         pseudo_stream_id++) {
+        //Parsing Sample description table
+        enum AVCodecID id;
+        int ret, dref_id = 1;
+        MOVAtom a = { AV_RL32("stsd") };
+        int64_t start_pos = avio_tell(pb);
+        uint32_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);
+            return AVERROR_INVALIDDATA;
+        }
+
+        if (mov_skip_multiple_stsd(c, pb, st->codec->codec_tag, format,
+                                   size - (avio_tell(pb) - start_pos)))
+            continue;
+
+        sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
+        sc->dref_id= dref_id;
+
+        id = mov_codec_id(st, format);
+
+        av_dlog(c->fc, "size=%d 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);
+
+        if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
+            st->codec->codec_id = id;
+            mov_parse_stsd_video(c, pb, st, sc);
+        } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
+            st->codec->codec_id = id;
+            mov_parse_stsd_audio(c, pb, st, sc);
+        } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
+            st->codec->codec_id = id;
+            mov_parse_stsd_subtitle(c, pb, st, sc,
+                                    size - (avio_tell(pb) - start_pos));
+        } else {
+            ret = mov_parse_stsd_data(c, pb, st, sc,
+                                      size - (avio_tell(pb) - start_pos));
+            if (ret < 0)
+                return ret;
+        }
+        /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
+        a.size = size - (avio_tell(pb) - start_pos);
+        if (a.size > 8) {
+            if ((ret = mov_read_default(c, pb, a)) < 0)
+                return ret;
+        } else if (a.size > 0)
+            avio_skip(pb, a.size);
+    }
+
+    if (pb->eof_reached)
+        return AVERROR_EOF;
+
+    return mov_finalize_stsd_codec(c, pb, st, sc);
+}
+
 static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     int entries;
@@ -1781,7 +1849,6 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
     unsigned int stps_index = 0;
     unsigned int i, j;
     uint64_t stream_size = 0;
-    AVIndexEntry *mem;
 
     /* adjust first dts according to edit list */
     if (sc->time_offset && mov->time_scale > 0) {
@@ -1815,10 +1882,12 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
             return;
         if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
             return;
-        mem = av_realloc(st->index_entries, (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries));
-        if (!mem)
+        if (av_reallocp_array(&st->index_entries,
+                              st->nb_index_entries + sc->sample_count,
+                              sizeof(*st->index_entries)) < 0) {
+            st->nb_index_entries = 0;
             return;
-        st->index_entries = mem;
+        }
         st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
 
         for (i = 0; i < sc->chunk_count; i++) {
@@ -1913,10 +1982,12 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
         av_dlog(mov->fc, "chunk count %d\n", total);
         if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
             return;
-        mem = av_realloc(st->index_entries, (st->nb_index_entries + total) * sizeof(*st->index_entries));
-        if (!mem)
+        if (av_reallocp_array(&st->index_entries,
+                              st->nb_index_entries + total,
+                              sizeof(*st->index_entries)) < 0) {
+            st->nb_index_entries = 0;
             return;
-        st->index_entries = mem;
+        }
         st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
 
         // populate index
@@ -2070,12 +2141,14 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         if (st->duration != AV_NOPTS_VALUE && st->duration > 0)
             av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
                       sc->time_scale*st->nb_frames, st->duration, INT_MAX);
+    }
 
-#if FF_API_R_FRAME_RATE
-        if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
-            av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
-                      sc->time_scale, sc->stts_data[0].duration, INT_MAX);
-#endif
+    // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
+    if (!st->codec->extradata_size && st->codec->codec_id == AV_CODEC_ID_H264 &&
+        TAG_IS_AVCI(st->codec->codec_tag)) {
+        ret = ff_generate_avci_extradata(st);
+        if (ret < 0)
+            return ret;
     }
 
     switch (st->codec->codec_id) {
@@ -2138,6 +2211,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     AVStream *st;
     MOVStreamContext *sc;
     int version;
+    int flags;
 
     if (c->fc->nb_streams < 1)
         return 0;
@@ -2145,13 +2219,8 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     sc = st->priv_data;
 
     version = avio_r8(pb);
-    avio_rb24(pb); /* flags */
-    /*
-    MOV_TRACK_ENABLED 0x0001
-    MOV_TRACK_IN_MOVIE 0x0002
-    MOV_TRACK_IN_PREVIEW 0x0004
-    MOV_TRACK_IN_POSTER 0x0008
-    */
+    flags = avio_rb24(pb);
+    st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
 
     if (version == 1) {
         avio_rb64(pb);
@@ -2257,13 +2326,15 @@ static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     MOVTrackExt *trex;
+    int err;
 
     if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
         return AVERROR_INVALIDDATA;
-    trex = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data));
-    if (!trex)
-        return AVERROR(ENOMEM);
-    c->trex_data = trex;
+    if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
+                                 sizeof(*c->trex_data))) < 0) {
+        c->trex_count = 0;
+        return err;
+    }
     trex = &c->trex_data[c->trex_count++];
     avio_r8(pb); /* version */
     avio_rb24(pb); /* flags */
@@ -2285,7 +2356,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     int64_t dts;
     int data_offset = 0;
     unsigned entries, first_sample_flags = frag->flags;
-    int flags, distance, i, found_keyframe = 0;
+    int flags, distance, i, found_keyframe = 0, err;
 
     for (i = 0; i < c->fc->nb_streams; i++) {
         if (c->fc->streams[i]->id == frag->track_id) {
@@ -2313,7 +2384,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (!sc->ctts_count && sc->sample_count)
     {
         /* Complement ctts table if moov atom doesn't have ctts atom. */
-        ctts_data = av_malloc(sizeof(*sc->ctts_data));
+        ctts_data = av_realloc(NULL, sizeof(*sc->ctts_data));
         if (!ctts_data)
             return AVERROR(ENOMEM);
         sc->ctts_data = ctts_data;
@@ -2323,12 +2394,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     }
     if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
         return AVERROR_INVALIDDATA;
-    ctts_data = av_realloc(sc->ctts_data,
-                           (entries+sc->ctts_count)*sizeof(*sc->ctts_data));
-    if (!ctts_data)
-        return AVERROR(ENOMEM);
-    sc->ctts_data = ctts_data;
-
+    if ((err = av_reallocp_array(&sc->ctts_data, entries + sc->ctts_count,
+                                 sizeof(*sc->ctts_data))) < 0) {
+        sc->ctts_count = 0;
+        return err;
+    }
     if (flags & MOV_TRUN_DATA_OFFSET)        data_offset        = avio_rb32(pb);
     if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
     dts    = sc->track_end - sc->time_offset;
@@ -2545,6 +2615,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = {
 { MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
 { MKTAG('d','v','c','1'), mov_read_dvc1 },
 { MKTAG('s','b','g','p'), mov_read_sbgp },
+{ MKTAG('h','v','c','C'), mov_read_glbl },
 { 0, NULL }
 };
 
@@ -2662,7 +2733,7 @@ static int mov_probe(AVProbeData *p)
         case MKTAG('p','r','f','l'):
             offset = AV_RB32(p->buf+offset) + offset;
             /* if we only find those cause probedata is too small at least rate them */
-            score = AVPROBE_SCORE_MAX - 50;
+            score = AVPROBE_SCORE_EXTENSION;
             break;
         default:
             /* unrecognized tag */
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 3949520..43a1647 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -21,6 +21,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "movenc.h"
 #include "avformat.h"
 #include "avio_internal.h"
@@ -51,6 +53,8 @@ static const AVOption options[] = {
     { "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 index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+    { "omit_tfhd_offset", "Omit the base data offset in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_OMIT_TFHD_OFFSET}, 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},
     { "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},
@@ -81,22 +85,28 @@ static int64_t update_size(AVIOContext *pb, int64_t pos)
     return curpos - pos;
 }
 
+static int co64_required(const MOVTrack *track)
+{
+    if (track->entry > 0 && track->cluster[track->entry - 1].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 = 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
         ffio_wfourcc(pb, "stco");
     avio_wb32(pb, 0); /* version & flags */
     avio_wb32(pb, track->entry); /* entry count */
-    for (i=0; i<track->entry; i++) {
-        if(mode64 == 1)
+    for (i = 0; i < track->entry; i++) {
+        if (mode64 == 1)
             avio_wb64(pb, track->cluster[i].pos + track->data_offset);
         else
             avio_wb32(pb, track->cluster[i].pos + track->data_offset);
@@ -115,27 +125,25 @@ static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
     ffio_wfourcc(pb, "stsz");
     avio_wb32(pb, 0); /* version & flags */
 
-    for (i=0; i<track->entry; i++) {
-        tst = track->cluster[i].size/track->cluster[i].entries;
-        if(oldtst != -1 && tst != oldtst) {
+    for (i = 0; i < track->entry; i++) {
+        tst = track->cluster[i].size / track->cluster[i].entries;
+        if (oldtst != -1 && tst != oldtst)
             equalChunks = 0;
-        }
         oldtst = tst;
         entries += track->cluster[i].entries;
     }
     if (equalChunks && track->entry) {
-        int sSize = track->entry ? track->cluster[0].size/track->cluster[0].entries : 0;
+        int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
         sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
         avio_wb32(pb, sSize); // sample size
         avio_wb32(pb, entries); // sample count
-    }
-    else {
+    } else {
         avio_wb32(pb, 0); // sample size
         avio_wb32(pb, entries); // sample count
-        for (i=0; i<track->entry; i++) {
-            for (j=0; j<track->cluster[i].entries; j++) {
+        for (i = 0; i < track->entry; i++) {
+            for (j = 0; j < track->cluster[i].entries; j++) {
                 avio_wb32(pb, track->cluster[i].size /
-                         track->cluster[i].entries);
+                          track->cluster[i].entries);
             }
         }
     }
@@ -154,10 +162,9 @@ static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb32(pb, 0); // version & flags
     entryPos = avio_tell(pb);
     avio_wb32(pb, track->entry); // entry count
-    for (i=0; i<track->entry; i++) {
-        if (oldval != track->cluster[i].samples_in_chunk)
-        {
-            avio_wb32(pb, i+1); // first chunk
+    for (i = 0; i < track->entry; i++) {
+        if (oldval != track->cluster[i].samples_in_chunk) {
+            avio_wb32(pb, i + 1); // 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;
@@ -183,9 +190,9 @@ static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
     avio_wb32(pb, 0); // version & flags
     entryPos = avio_tell(pb);
     avio_wb32(pb, track->entry); // entry count
-    for (i=0; i<track->entry; i++) {
+    for (i = 0; i < track->entry; i++) {
         if (track->cluster[i].flags & flag) {
-            avio_wb32(pb, i+1);
+            avio_wb32(pb, i + 1);
             index++;
         }
     }
@@ -245,7 +252,7 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track)
     put_bits(&pbc, 3, bsmod);
     put_bits(&pbc, 3, acmod);
     put_bits(&pbc, 1, lfeon);
-    put_bits(&pbc, 5, frmsizecod>>1); // bit_rate_code
+    put_bits(&pbc, 5, frmsizecod >> 1); // bit_rate_code
     put_bits(&pbc, 5, 0); // reserved
 
     flush_put_bits(&pbc);
@@ -268,8 +275,8 @@ static void put_descr(AVIOContext *pb, int tag, unsigned int size)
 {
     int i = 3;
     avio_w8(pb, tag);
-    for(; i>0; i--)
-        avio_w8(pb, (size>>(7*i)) | 0x80);
+    for (; i > 0; i--)
+        avio_w8(pb, (size >> (7 * i)) | 0x80);
     avio_w8(pb, size & 0x7F);
 }
 
@@ -300,16 +307,16 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
 
     // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
     // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
-    if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+    if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
         avio_w8(pb, 0x15); // flags (= Audiostream)
     else
         avio_w8(pb, 0x11); // flags (= Visualstream)
 
-    avio_w8(pb,  track->enc->rc_buffer_size>>(3+16));      // Buffersize DB (24 bits)
-    avio_wb16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF); // Buffersize DB
+    avio_wb24(pb, track->enc->rc_buffer_size >> 3); // Buffersize DB
 
     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)
+    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
@@ -616,21 +623,21 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
         avio_wb16(pb, 0); /* Reserved */
     }
 
-    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))
+    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))
         mov_write_wave_tag(pb, track);
-    else if(track->tag == MKTAG('m','p','4','a'))
+    else if (track->tag == MKTAG('m','p','4','a'))
         mov_write_esds_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_AMR_NB)
+    else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB)
         mov_write_amr_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_AC3)
+    else if (track->enc->codec_id == AV_CODEC_ID_AC3)
         mov_write_ac3_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_ALAC)
+    else if (track->enc->codec_id == AV_CODEC_ID_ALAC)
         mov_write_extradata_tag(pb, track);
     else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO)
         mov_write_wfex_tag(pb, track);
@@ -704,7 +711,7 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb32(pb, track->enc->width);
     /* values below are based on samples created with quicktime and avid codecs */
     if (track->vos_data[5] & 2) { // interlaced
-        avio_wb32(pb, track->enc->height/2);
+        avio_wb32(pb, track->enc->height / 2);
         avio_wb32(pb, 2); /* unknown */
         avio_wb32(pb, 0); /* unknown */
         avio_wb32(pb, 4); /* unknown */
@@ -738,18 +745,18 @@ static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track)
     else if (track->enc->codec_id == AV_CODEC_ID_DIRAC)     tag = MKTAG('d','r','a','c');
     else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT)  tag = MKTAG('t','x','3','g');
     else if (track->enc->codec_id == AV_CODEC_ID_VC1)       tag = MKTAG('v','c','-','1');
-    else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
-    else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
+    else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)  tag = MKTAG('m','p','4','v');
+    else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)  tag = MKTAG('m','p','4','a');
 
     return tag;
 }
 
 static const AVCodecTag codec_ipod_tags[] = {
-    { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
-    { AV_CODEC_ID_MPEG4,  MKTAG('m','p','4','v') },
-    { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
-    { AV_CODEC_ID_ALAC,   MKTAG('a','l','a','c') },
-    { AV_CODEC_ID_AC3,    MKTAG('a','c','-','3') },
+    { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
+    { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
+    { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
+    { AV_CODEC_ID_ALAC,     MKTAG('a','l','a','c') },
+    { AV_CODEC_ID_AC3,      MKTAG('a','c','-','3') },
     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
     { AV_CODEC_ID_NONE, 0 },
@@ -761,8 +768,8 @@ static int ipod_get_codec_tag(AVFormatContext *s, MOVTrack *track)
 
     // keep original tag for subs, ipod supports both formats
     if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE &&
-        (tag == MKTAG('t','x','3','g') ||
-         tag == MKTAG('t','e','x','t'))))
+          (tag == MKTAG('t', 'x', '3', 'g') ||
+           tag == MKTAG('t', 'e', 'x', 't'))))
         tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id);
 
     if (!av_match_ext(s->filename, "m4a") && !av_match_ext(s->filename, "m4v"))
@@ -779,16 +786,16 @@ static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
     if (track->enc->width == 720) /* SD */
         if (track->enc->height == 480) /* NTSC */
             if  (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
-            else                                         tag = MKTAG('d','v','c',' ');
+            else                                            tag = MKTAG('d','v','c',' ');
         else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
         else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
-        else                                             tag = MKTAG('d','v','p','p');
+        else                                                tag = MKTAG('d','v','p','p');
     else if (track->enc->height == 720) /* HD 720 line */
-        if  (track->enc->time_base.den == 50)            tag = MKTAG('d','v','h','q');
-        else                                             tag = MKTAG('d','v','h','p');
+        if  (track->enc->time_base.den == 50)               tag = MKTAG('d','v','h','q');
+        else                                                tag = MKTAG('d','v','h','p');
     else if (track->enc->height == 1080) /* HD 1080 line */
-        if  (track->enc->time_base.den == 25)            tag = MKTAG('d','v','h','5');
-        else                                             tag = MKTAG('d','v','h','6');
+        if  (track->enc->time_base.den == 25)               tag = MKTAG('d','v','h','5');
+        else                                                tag = MKTAG('d','v','h','6');
     else {
         av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
         return 0;
@@ -873,16 +880,25 @@ static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
 }
 
 static const AVCodecTag codec_3gp_tags[] = {
-    { AV_CODEC_ID_H263,   MKTAG('s','2','6','3') },
-    { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
-    { AV_CODEC_ID_MPEG4,  MKTAG('m','p','4','v') },
-    { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
-    { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
-    { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
+    { AV_CODEC_ID_H263,     MKTAG('s','2','6','3') },
+    { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
+    { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
+    { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
+    { AV_CODEC_ID_AMR_NB,   MKTAG('s','a','m','r') },
+    { AV_CODEC_ID_AMR_WB,   MKTAG('s','a','w','b') },
     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
     { AV_CODEC_ID_NONE, 0 },
 };
 
+static const AVCodecTag codec_f4v_tags[] = {
+    { 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_VP6A,   MKTAG('V','P','6','A') },
+    { 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 +913,8 @@ static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
         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);
 
@@ -979,7 +997,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb16(pb, 0); /* Codec stream revision (=0) */
     if (track->mode == MODE_MOV) {
         ffio_wfourcc(pb, "FFMP"); /* Vendor */
-        if(track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
+        if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
             avio_wb32(pb, 0); /* Temporal Quality */
             avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
         } else {
@@ -1000,7 +1018,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
 
     /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
     if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
-        av_strlcpy(compressor_name,track->enc->codec->name,32);
+        av_strlcpy(compressor_name, track->enc->codec->name, 32);
     avio_w8(pb, strlen(compressor_name));
     avio_write(pb, compressor_name, 31);
 
@@ -1009,23 +1027,27 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
     else
         avio_wb16(pb, 0x18); /* Reserved */
     avio_wb16(pb, 0xffff); /* Reserved */
-    if(track->tag == MKTAG('m','p','4','v'))
+    if (track->tag == MKTAG('m','p','4','v'))
         mov_write_esds_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_H263)
+    else if (track->enc->codec_id == AV_CODEC_ID_H263)
         mov_write_d263_tag(pb);
-    else if(track->enc->codec_id == AV_CODEC_ID_SVQ3)
+    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_DNXHD)
         mov_write_avid_tag(pb, track);
-    else if(track->enc->codec_id == AV_CODEC_ID_H264) {
+    else if (track->enc->codec_id == AV_CODEC_ID_H264) {
         mov_write_avcc_tag(pb, track);
-        if(track->mode == MODE_IPOD)
+        if (track->mode == MODE_IPOD)
             mov_write_uuid_tag_ipod(pb);
     } else if (track->enc->field_order != AV_FIELD_UNKNOWN)
         mov_write_fiel_tag(pb, track);
     else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
         mov_write_dvc1_tag(pb, track);
-    else if (track->vos_len > 0)
+    else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
+             track->enc->codec_id == AV_CODEC_ID_VP6A) {
+        /* Don't write any potential extradata here - the cropping
+         * is signalled via the normal width/height fields. */
+    } else if (track->vos_len > 0)
         mov_write_glbl_tag(pb, track);
 
     if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num &&
@@ -1056,6 +1078,19 @@ static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
     return update_size(pb, pos);
 }
 
+static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
+{
+    int64_t pos = avio_tell(pb);
+
+    avio_wb32(pb, 0); /* size */
+    ffio_wfourcc(pb, "tmcd");               /* Data format */
+    avio_wb32(pb, 0);                       /* Reserved */
+    avio_wb32(pb, 1);                       /* Data reference index */
+    if (track->enc->extradata_size)
+        avio_write(pb, track->enc->extradata, track->enc->extradata_size);
+    return update_size(pb, pos);
+}
+
 static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -1071,6 +1106,8 @@ static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack *track)
         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);
 }
 
@@ -1084,7 +1121,7 @@ static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track)
     ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */
     ctts_entries[0].count = 1;
     ctts_entries[0].duration = track->cluster[0].cts;
-    for (i=1; i<track->entry; i++) {
+    for (i = 1; i < track->entry; i++) {
         if (track->cluster[i].cts == ctts_entries[entries].duration) {
             ctts_entries[entries].count++; /* compress */
         } else {
@@ -1099,7 +1136,7 @@ static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track)
     ffio_wfourcc(pb, "ctts");
     avio_wb32(pb, 0); /* version & flags */
     avio_wb32(pb, entries); /* entry count */
-    for (i=0; i<entries; i++) {
+    for (i = 0; i < entries; i++) {
         avio_wb32(pb, ctts_entries[i].count);
         avio_wb32(pb, ctts_entries[i].duration);
     }
@@ -1124,7 +1161,7 @@ static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
         stts_entries = track->entry ?
                        av_malloc(track->entry * sizeof(*stts_entries)) : /* worst case */
                        NULL;
-        for (i=0; i<track->entry; i++) {
+        for (i = 0; i < track->entry; i++) {
             int duration = get_cluster_duration(track, i);
             if (i && duration == stts_entries[entries].duration) {
                 stts_entries[entries].count++; /* compress */
@@ -1141,7 +1178,7 @@ static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
     ffio_wfourcc(pb, "stts");
     avio_wb32(pb, 0); /* version & flags */
     avio_wb32(pb, entries); /* entry count */
-    for (i=0; i<entries; i++) {
+    for (i = 0; i < entries; i++) {
         avio_wb32(pb, stts_entries[i].count);
         avio_wb32(pb, stts_entries[i].duration);
     }
@@ -1242,25 +1279,36 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
     const char *hdlr, *descr = NULL, *hdlr_type = NULL;
     int64_t pos = avio_tell(pb);
 
-    if (!track) { /* no media --> data handler */
-        hdlr = "dhlr";
-        hdlr_type = "url ";
-        descr = "DataHandler";
-    } else {
+    hdlr      = "dhlr";
+    hdlr_type = "url ";
+    descr     = "DataHandler";
+
+    if (track) {
         hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
             hdlr_type = "vide";
-            descr = "VideoHandler";
+            descr     = "VideoHandler";
         } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
             hdlr_type = "soun";
-            descr = "SoundHandler";
+            descr     = "SoundHandler";
         } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
             if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
             else                                      hdlr_type = "text";
             descr = "SubtitleHandler";
         } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
             hdlr_type = "hint";
-            descr = "HintHandler";
+            descr     = "HintHandler";
+        } else if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
+            hdlr_type = "tmcd";
+            descr = "TimeCodeHandler";
+        } else {
+            char tag_buf[32];
+            av_get_codec_tag_string(tag_buf, sizeof(tag_buf),
+                                    track->enc->codec_tag);
+
+            av_log(track->enc, AV_LOG_WARNING,
+                   "Unknown hldr_type for %s / 0x%04X, writing dummy values\n",
+                   tag_buf, track->enc->codec_tag);
         }
     }
 
@@ -1269,9 +1317,9 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb32(pb, 0); /* Version & flags */
     avio_write(pb, hdlr, 4); /* handler */
     ffio_wfourcc(pb, hdlr_type); /* handler type */
-    avio_wb32(pb ,0); /* reserved */
-    avio_wb32(pb ,0); /* reserved */
-    avio_wb32(pb ,0); /* reserved */
+    avio_wb32(pb, 0); /* reserved */
+    avio_wb32(pb, 0); /* reserved */
+    avio_wb32(pb, 0); /* reserved */
     if (!track || track->mode == MODE_MOV)
         avio_w8(pb, strlen(descr)); /* pascal string */
     avio_write(pb, descr, strlen(descr)); /* handler description */
@@ -1300,7 +1348,7 @@ static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track)
     int64_t pos = avio_tell(pb);
     avio_wb32(pb, 0); /* size */
     ffio_wfourcc(pb, "minf");
-    if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
+    if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
         mov_write_vmhd_tag(pb);
     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
         mov_write_smhd_tag(pb);
@@ -1309,6 +1357,8 @@ static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track)
         else                                      mov_write_nmhd_tag(pb);
     } else if (track->tag == MKTAG('r','t','p',' ')) {
         mov_write_hmhd_tag(pb);
+    } else if (track->tag == MKTAG('t','m','c','d')) {
+        mov_write_gmhd_tag(pb);
     }
     if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
         mov_write_hdlr_tag(pb, NULL);
@@ -1343,11 +1393,11 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb16(pb, track->language); /* language */
     avio_wb16(pb, 0); /* reserved (quality) */
 
-    if(version!=0 && track->mode == MODE_MOV){
+    if (version != 0 && track->mode == MODE_MOV) {
         av_log(NULL, AV_LOG_ERROR,
-            "FATAL error, file duration too long for timebase, this file will not be\n"
-            "playable with quicktime. Choose a different timebase or a different\n"
-            "container format\n");
+               "FATAL error, file duration too long for timebase, this file will not be\n"
+               "playable with quicktime. Choose a different timebase or a different\n"
+               "container format\n");
     }
 
     return 32;
@@ -1376,7 +1426,9 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
     (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
     ffio_wfourcc(pb, "tkhd");
     avio_w8(pb, version);
-    avio_wb24(pb, 0xf); /* flags (track enabled) */
+    avio_wb24(pb, (track->flags & MOV_TRACK_ENABLED) ?
+                  MOV_TKHD_FLAG_ENABLED | MOV_TKHD_FLAG_IN_MOVIE :
+                  MOV_TKHD_FLAG_IN_MOVIE);
     if (version == 1) {
         avio_wb64(pb, track->time);
         avio_wb64(pb, track->time);
@@ -1396,7 +1448,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
     avio_wb16(pb, 0); /* layer */
     avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */
     /* Volume, only for audio */
-    if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
+    if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
         avio_wb16(pb, 0x0100);
     else
         avio_wb16(pb, 0);
@@ -1414,20 +1466,19 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
     avio_wb32(pb, 0x40000000); /* reserved */
 
     /* Track width and height, for visual only */
-    if(st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
-              track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
-        if(track->mode == MODE_MOV) {
+    if (st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
+               track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
+        if (track->mode == MODE_MOV) {
             avio_wb32(pb, track->enc->width << 16);
             avio_wb32(pb, track->height << 16);
         } else {
             double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
-            if(!sample_aspect_ratio || track->height != track->enc->height)
+            if (!sample_aspect_ratio || track->height != track->enc->height)
                 sample_aspect_ratio = 1;
-            avio_wb32(pb, sample_aspect_ratio * track->enc->width*0x10000);
-            avio_wb32(pb, track->height*0x10000);
+            avio_wb32(pb, sample_aspect_ratio * track->enc->width * 0x10000);
+            avio_wb32(pb, track->height * 0x10000);
         }
-    }
-    else {
+    } else {
         avio_wb32(pb, 0);
         avio_wb32(pb, 0);
     }
@@ -1538,7 +1589,6 @@ static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
 
 static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
 {
-
     AVFormatContext *ctx = track->rtp_ctx;
     char buf[1000] = "";
     int len;
@@ -1574,14 +1624,14 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov,
         mov_write_tref_tag(pb, track);
     mov_write_mdia_tag(pb, track);
     if (track->mode == MODE_PSP)
-        mov_write_uuid_tag_psp(pb,track);  // PSP Movies require this uuid box
+        mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
     if (track->tag == MKTAG('r','t','p',' '))
         mov_write_udta_sdp(pb, track);
     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
         double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
         if (0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio)
             mov_write_tapt_tag(pb, track);
-    };
+    }
     return update_size(pb, pos);
 }
 
@@ -1592,7 +1642,7 @@ static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
     int audio_profile = mov->iods_audio_profile;
     int video_profile = mov->iods_video_profile;
     for (i = 0; i < mov->nb_streams; i++) {
-        if(mov->tracks[i].entry > 0) {
+        if (mov->tracks[i].entry > 0) {
             has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
             has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
         }
@@ -1644,8 +1694,8 @@ static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
     int64_t max_track_len_temp, max_track_len = 0;
     int version;
 
-    for (i=0; i<mov->nb_streams; i++) {
-        if(mov->tracks[i].entry > 0) {
+    for (i = 0; i < mov->nb_streams; i++) {
+        if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
             max_track_len_temp = av_rescale_rnd(mov->tracks[i].track_duration,
                                                 MOV_TIMESCALE,
                                                 mov->tracks[i].timescale,
@@ -1717,7 +1767,7 @@ static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov,
 /* helper function to write a data tag with the specified string as data */
 static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
 {
-    if(long_style){
+    if (long_style) {
         int size = 16 + strlen(data);
         avio_wb32(pb, size); /* size */
         ffio_wfourcc(pb, "data");
@@ -1725,7 +1775,7 @@ static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang
         avio_wb32(pb, 0);
         avio_write(pb, data, strlen(data));
         return size;
-    }else{
+    } else {
         if (!lang)
             lang = ff_mov_iso639_to_lang("und", 1);
         avio_wb16(pb, strlen(data)); /* string length */
@@ -1735,7 +1785,9 @@ static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang
     }
 }
 
-static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style){
+static int mov_write_string_tag(AVIOContext *pb, const char *name,
+                                const char *value, int lang, int long_style)
+{
     int size = 0;
     if (value && value[0]) {
         int64_t pos = avio_tell(pb);
@@ -1762,8 +1814,8 @@ static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb,
     snprintf(tag2, sizeof(tag2), "%s-", tag);
     while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
         len2 = strlen(t2->key);
-        if (len2 == len+4 && !strcmp(t->value, t2->value)
-            && (l=ff_mov_iso639_to_lang(&t2->key[len2-3], 1)) >= 0) {
+        if (len2 == len + 4 && !strcmp(t->value, t2->value)
+            && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
             lang = l;
             break;
         }
@@ -1780,14 +1832,14 @@ static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov,
     if (track) {
         avio_wb32(pb, 32); /* size */
         ffio_wfourcc(pb, "trkn");
-            avio_wb32(pb, 24); /* size */
-            ffio_wfourcc(pb, "data");
-            avio_wb32(pb, 0);        // 8 bytes empty
-            avio_wb32(pb, 0);
-            avio_wb16(pb, 0);        // empty
-            avio_wb16(pb, track);    // track number
-            avio_wb16(pb, 0);        // total track number
-            avio_wb16(pb, 0);        // empty
+        avio_wb32(pb, 24); /* size */
+        ffio_wfourcc(pb, "data");
+        avio_wb32(pb, 0);        // 8 bytes empty
+        avio_wb32(pb, 0);
+        avio_wb16(pb, 0);        // empty
+        avio_wb16(pb, track);    // track number
+        avio_wb16(pb, 0);        // total track number
+        avio_wb16(pb, 0);        // empty
         size = 32;
     }
     return size;
@@ -1838,9 +1890,9 @@ static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov,
 
 static int utf8len(const uint8_t *b)
 {
-    int len=0;
+    int len = 0;
     int val;
-    while(*b){
+    while (*b) {
         GET_UTF8(val, *b++, return -1;)
         len++;
     }
@@ -1850,7 +1902,7 @@ static int utf8len(const uint8_t *b)
 static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
 {
     int val;
-    while(*b){
+    while (*b) {
         GET_UTF8(val, *b++, return -1;)
         avio_wb16(pb, val);
     }
@@ -1860,7 +1912,9 @@ static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
 
 static uint16_t language_code(const char *str)
 {
-    return (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F);
+    return (((str[0] - 0x60) & 0x1F) << 10) +
+           (((str[1] - 0x60) & 0x1F) <<  5) +
+           (( str[2] - 0x60) & 0x1F);
 }
 
 static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
@@ -1877,7 +1931,7 @@ static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
         avio_wb16(pb, atoi(t->value));
     else {
         avio_wb16(pb, language_code("eng")); /* language */
-        avio_write(pb, t->value, strlen(t->value)+1); /* UTF8 string value */
+        avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
         if (!strcmp(tag, "albm") &&
             (t = av_dict_get(s->metadata, "track", NULL, 0)))
             avio_w8(pb, atoi(t->value));
@@ -1924,38 +1978,38 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
         }
 
     ret = avio_open_dyn_buf(&pb_buf);
-    if(ret < 0)
+    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);
+        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 (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);
+        avio_wb32(pb, size + 8);
         ffio_wfourcc(pb, "udta");
         avio_write(pb, buf, size);
     }
@@ -1965,12 +2019,12 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
 }
 
 static void mov_write_psp_udta_tag(AVIOContext *pb,
-                                  const char *str, const char *lang, int type)
+                                   const char *str, const char *lang, int type)
 {
-    int len = utf8len(str)+1;
-    if(len<=0)
+    int len = utf8len(str) + 1;
+    if (len <= 0)
         return;
-    avio_wb16(pb, len*2+10);            /* size */
+    avio_wb16(pb, len * 2 + 10);        /* size */
     avio_wb32(pb, type);                /* type */
     avio_wb16(pb, language_code(lang)); /* language */
     avio_wb16(pb, 0x01);                /* ? */
@@ -2022,18 +2076,18 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
     avio_wb32(pb, 0); /* size placeholder*/
     ffio_wfourcc(pb, "moov");
 
-    for (i=0; i<mov->nb_streams; i++) {
+    for (i = 0; i < mov->nb_streams; i++) {
         if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
             continue;
 
-        mov->tracks[i].time = mov->time;
-        mov->tracks[i].track_id = i+1;
+        mov->tracks[i].time     = mov->time;
+        mov->tracks[i].track_id = i + 1;
     }
 
     if (mov->chapter_track)
-        for (i=0; i<s->nb_streams; i++) {
+        for (i = 0; i < s->nb_streams; i++) {
             mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
-            mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id;
+            mov->tracks[i].tref_id  = mov->tracks[mov->chapter_track].track_id;
         }
     for (i = 0; i < mov->nb_streams; i++) {
         if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) {
@@ -2046,7 +2100,7 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
     mov_write_mvhd_tag(pb, mov);
     if (mov->mode != MODE_MOV && !mov->iods_skip)
         mov_write_iods_tag(pb, mov);
-    for (i=0; i<mov->nb_streams; i++) {
+    for (i = 0; i < mov->nb_streams; i++) {
         if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
             mov_write_trak_tag(pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
         }
@@ -2075,9 +2129,9 @@ static void param_write_string(AVIOContext *pb, const char *name, const char *va
 static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
 {
     char buf[150];
-    len = FFMIN(sizeof(buf)/2 - 1, len);
+    len = FFMIN(sizeof(buf) / 2 - 1, len);
     ff_data_to_hex(buf, value, len, 0);
-    buf[2*len] = '\0';
+    buf[2 * len] = '\0';
     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
 }
 
@@ -2151,7 +2205,7 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
             param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
                             track->enc->extradata_size);
             param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
-                                                track->enc->codec_id));
+                                                             track->enc->codec_id));
             param_write_int(pb, "Channels", track->enc->channels);
             param_write_int(pb, "SamplingRate", track->enc->sample_rate);
             param_write_int(pb, "BitsPerSample", 16);
@@ -2176,8 +2230,8 @@ static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
     return 0;
 }
 
-static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
-                              int64_t moof_offset)
+static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov,
+                              MOVTrack *track, int64_t moof_offset)
 {
     int64_t pos = avio_tell(pb);
     uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
@@ -2187,12 +2241,16 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
     } else {
         flags |= MOV_TFHD_DEFAULT_FLAGS;
     }
+    if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET)
+        flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
 
     /* Don't set a default sample size, the silverlight player refuses
      * to play files with that set. Don't set a default sample duration,
-     * WMP freaks out if it is set. */
+     * WMP freaks out if it is set. Don't set a base data offset, PIFF
+     * file format says it MUST NOT be set. */
     if (track->mode == MODE_ISM)
-        flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION);
+        flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
+                   MOV_TFHD_BASE_DATA_OFFSET);
 
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "tfhd");
@@ -2229,7 +2287,8 @@ static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
            (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
 }
 
-static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
+static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov,
+                              MOVTrack *track, int moof_size)
 {
     int64_t pos = avio_tell(pb);
     uint32_t flags = MOV_TRUN_DATA_OFFSET;
@@ -2254,8 +2313,13 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
     avio_wb24(pb, flags);
 
     avio_wb32(pb, track->entry); /* sample count */
-    track->moof_size_offset = avio_tell(pb);
-    avio_wb32(pb, 0); /* data offset */
+    if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
+        !(mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) &&
+        track->track_id != 1)
+        avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
+    else
+        avio_wb32(pb, moof_size + 8 + track->data_offset +
+                      track->cluster[0].pos); /* data offset */
     if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
         avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
 
@@ -2319,7 +2383,7 @@ static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov,
         avio_wb64(pb, track->frag_info[index].duration);
     }
     if (n < mov->ism_lookahead) {
-        int free_size = 16*(mov->ism_lookahead - n);
+        int free_size = 16 * (mov->ism_lookahead - n);
         avio_wb32(pb, free_size);
         ffio_wfourcc(pb, "free");
         for (i = 0; i < free_size - 8; i++)
@@ -2344,19 +2408,20 @@ static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov,
 }
 
 static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
-                              MOVTrack *track, int64_t moof_offset)
+                              MOVTrack *track, int64_t moof_offset,
+                              int moof_size)
 {
     int64_t pos = avio_tell(pb);
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "traf");
 
-    mov_write_tfhd_tag(pb, track, moof_offset);
-    mov_write_trun_tag(pb, track);
+    mov_write_tfhd_tag(pb, mov, track, moof_offset);
+    mov_write_trun_tag(pb, mov, track, moof_size);
     if (mov->mode == MODE_ISM) {
         mov_write_tfxd_tag(pb, track);
 
         if (mov->ism_lookahead) {
-            int i, size = 16 + 4 + 1 + 16*mov->ism_lookahead;
+            int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
 
             track->tfrf_offset = avio_tell(pb);
             avio_wb32(pb, 8 + size);
@@ -2369,10 +2434,11 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
     return update_size(pb, pos);
 }
 
-static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
+static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov,
+                                       int tracks, int moof_size)
 {
-    int64_t pos = avio_tell(pb), end;
-    int i, moof_size;
+    int64_t pos = avio_tell(pb);
+    int i;
 
     avio_wb32(pb, 0); /* size placeholder */
     ffio_wfourcc(pb, "moof");
@@ -2384,25 +2450,24 @@ static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
             continue;
         if (!track->entry)
             continue;
-        mov_write_traf_tag(pb, mov, track, pos);
+        mov_write_traf_tag(pb, mov, track, pos, moof_size);
     }
 
-    end = avio_tell(pb);
-    moof_size = end - pos;
-    for (i = 0; i < mov->nb_streams; i++) {
-        MOVTrack *track = &mov->tracks[i];
-        if (tracks >= 0 && i != tracks)
-            continue;
-        if (!track->entry)
-            continue;
-        avio_seek(pb, mov->tracks[i].moof_size_offset, SEEK_SET);
-        avio_wb32(pb, moof_size + 8 + mov->tracks[i].data_offset);
-    }
-    avio_seek(pb, end, SEEK_SET);
-
     return update_size(pb, pos);
 }
 
+static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
+{
+    AVIOContext *avio_buf;
+    int ret, moof_size;
+
+    if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
+        return ret;
+    mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
+    moof_size = ffio_close_null_buf(avio_buf);
+    return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
+}
+
 static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -2490,7 +2555,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
     } else if (mov->mode & MODE_3G2) {
         ffio_wfourcc(pb, has_h264 ? "3g2b"  : "3g2a");
         minor =     has_h264 ? 0x20000 : 0x10000;
-    }else if (mov->mode == MODE_PSP)
+    } else if (mov->mode == MODE_PSP)
         ffio_wfourcc(pb, "MSNV");
     else if (mov->mode == MODE_MP4)
         ffio_wfourcc(pb, "isom");
@@ -2498,12 +2563,14 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
         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  ");
 
     avio_wb32(pb, minor);
 
-    if(mov->mode == MODE_MOV)
+    if (mov->mode == MODE_MOV)
         ffio_wfourcc(pb, "qt  ");
     else if (mov->mode == MODE_ISM) {
         ffio_wfourcc(pb, "piff");
@@ -2511,7 +2578,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
     } else {
         ffio_wfourcc(pb, "isom");
         ffio_wfourcc(pb, "iso2");
-        if(has_h264)
+        if (has_h264)
             ffio_wfourcc(pb, "avc1");
     }
 
@@ -2531,7 +2598,7 @@ static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
     AVCodecContext *video_codec = s->streams[0]->codec;
     AVCodecContext *audio_codec = s->streams[1]->codec;
     int audio_rate = audio_codec->sample_rate;
-    int frame_rate = ((video_codec->time_base.den) * (0x10000))/ (video_codec->time_base.num);
+    int frame_rate = ((video_codec->time_base.den) * (0x10000)) / (video_codec->time_base.num);
     int audio_kbitrate = audio_codec->bit_rate / 1000;
     int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate);
 
@@ -2553,7 +2620,7 @@ static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
     avio_wb32(pb, 0x0);  /* ? */
 
     avio_wb32(pb, 0x2c);  /* size */
-    ffio_wfourcc(pb, "APRF");/* audio */
+    ffio_wfourcc(pb, "APRF"); /* audio */
     avio_wb32(pb, 0x0);
     avio_wb32(pb, 0x2);   /* TrackID */
     ffio_wfourcc(pb, "mp4a");
@@ -2593,11 +2660,11 @@ static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
     int i, closed_gop = 0;
 
     for (i = 0; i < pkt->size - 4; i++) {
-        c = (c<<8) + pkt->data[i];
+        c = (c << 8) + pkt->data[i];
         if (c == 0x1b8) { // gop
-            closed_gop = pkt->data[i+4]>>6 & 0x01;
+            closed_gop = pkt->data[i + 4] >> 6 & 0x01;
         } else if (c == 0x100) { // pic
-            int temp_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
+            int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
             if (!temp_ref || closed_gop) // I picture is not reordered
                 *flags = MOV_SYNC_SAMPLE;
             else
@@ -2688,11 +2755,10 @@ static int mov_flush_fragment(AVFormatContext *s)
         if (i < mov->nb_streams)
             return 0;
 
-        if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
+        if ((ret = ffio_open_null_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);
+        buf_size = ffio_close_null_buf(moov_buf);
         for (i = 0; i < mov->nb_streams; i++)
             mov->tracks[i].data_offset = pos + buf_size + 8;
 
@@ -2756,9 +2822,14 @@ static int mov_flush_fragment(AVFormatContext *s)
             MOVFragmentInfo *info;
             avio_flush(s->pb);
             track->nb_frag_info++;
-            track->frag_info = av_realloc(track->frag_info,
-                                          sizeof(*track->frag_info) *
-                                          track->nb_frag_info);
+            if (track->nb_frag_info >= track->frag_info_capacity) {
+                unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
+                if (av_reallocp_array(&track->frag_info,
+                                      new_capacity,
+                                      sizeof(*track->frag_info)))
+                    return AVERROR(ENOMEM);
+                track->frag_info_capacity = new_capacity;
+            }
             info = &track->frag_info[track->nb_frag_info - 1];
             info->offset   = avio_tell(s->pb);
             info->time     = mov->tracks[i].frag_start;
@@ -2798,7 +2869,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     MOVTrack *trk = &mov->tracks[pkt->stream_index];
     AVCodecContext *enc = trk->enc;
     unsigned int samples_in_chunk = 0;
-    int size= pkt->size;
+    int size = pkt->size;
     uint8_t *reformatted_data = NULL;
 
     if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
@@ -2839,7 +2910,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     /* copy extradata if it exists */
     if (trk->vos_len == 0 && enc->extradata_size > 0) {
-        trk->vos_len = enc->extradata_size;
+        trk->vos_len  = enc->extradata_size;
         trk->vos_data = av_malloc(trk->vos_len);
         memcpy(trk->vos_data, enc->extradata, trk->vos_len);
     }
@@ -2861,24 +2932,26 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     if ((enc->codec_id == AV_CODEC_ID_DNXHD ||
          enc->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) {
         /* copy frame to create needed atoms */
-        trk->vos_len = size;
+        trk->vos_len  = size;
         trk->vos_data = av_malloc(size);
         if (!trk->vos_data)
             return AVERROR(ENOMEM);
         memcpy(trk->vos_data, pkt->data, size);
     }
 
-    if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
-        trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster));
-        if (!trk->cluster)
-            return -1;
+    if (trk->entry >= trk->cluster_capacity) {
+        unsigned new_capacity = 2 * (trk->entry + MOV_INDEX_CLUSTER_SIZE);
+        if (av_reallocp_array(&trk->cluster, new_capacity,
+                              sizeof(*trk->cluster)))
+            return AVERROR(ENOMEM);
+        trk->cluster_capacity = new_capacity;
     }
 
-    trk->cluster[trk->entry].pos = avio_tell(pb) - size;
+    trk->cluster[trk->entry].pos              = avio_tell(pb) - size;
     trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
-    trk->cluster[trk->entry].size = size;
-    trk->cluster[trk->entry].entries = samples_in_chunk;
-    trk->cluster[trk->entry].dts = pkt->dts;
+    trk->cluster[trk->entry].size             = size;
+    trk->cluster[trk->entry].entries          = samples_in_chunk;
+    trk->cluster[trk->entry].dts              = pkt->dts;
     if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
         /* First packet of a new fragment. We already wrote the duration
          * of the last packet of the previous fragment based on track_duration,
@@ -2896,7 +2969,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     }
     if (pkt->dts != pkt->pts)
         trk->flags |= MOV_TRACK_CTTS;
-    trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
+    trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
     trk->cluster[trk->entry].flags = 0;
     if (enc->codec_id == AV_CODEC_ID_VC1) {
         mov_parse_vc1_frame(pkt, trk, mov->fragments);
@@ -2914,9 +2987,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     }
     trk->entry++;
     trk->sample_count += samples_in_chunk;
-    mov->mdat_size += size;
-
-    avio_flush(pb);
+    mov->mdat_size    += size;
 
     if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
         ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry,
@@ -2937,7 +3008,8 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
         int64_t frag_duration = 0;
         int size = pkt->size;
 
-        if (!pkt->size) return 0; /* Discard 0 sized packets */
+        if (!pkt->size)
+            return 0;             /* Discard 0 sized packets */
 
         if (trk->entry)
             frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
@@ -2959,18 +3031,27 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
 
 // QuickTime chapters involve an additional text track with the chapter names
 // as samples, and a tref pointing from the other tracks to the chapter one.
-static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
+static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
 {
     MOVMuxContext *mov = s->priv_data;
     MOVTrack *track = &mov->tracks[tracknum];
     AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
     int i, len;
+    // These properties are required to make QT recognize the chapter track
+    uint8_t chapter_properties[43] = { 0, 0, 0, 0, 0, 0, 0, 1, };
 
     track->mode = mov->mode;
     track->tag = MKTAG('t','e','x','t');
     track->timescale = MOV_TIMESCALE;
     track->enc = avcodec_alloc_context3(NULL);
+    if (!track->enc)
+        return AVERROR(ENOMEM);
     track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
+    track->enc->extradata = av_malloc(sizeof(chapter_properties));
+    if (track->enc->extradata == NULL)
+        return AVERROR(ENOMEM);
+    track->enc->extradata_size = sizeof(chapter_properties);
+    memcpy(track->enc->extradata, chapter_properties, sizeof(chapter_properties));
 
     for (i = 0; i < s->nb_chapters; i++) {
         AVChapter *c = s->chapters[i];
@@ -2981,15 +3062,93 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
         pkt.duration = end - pkt.dts;
 
         if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
-            len = strlen(t->value);
-            pkt.size = len+2;
+            len      = strlen(t->value);
+            pkt.size = len + 2;
             pkt.data = av_malloc(pkt.size);
+            if (!pkt.data)
+                return AVERROR(ENOMEM);
             AV_WB16(pkt.data, len);
-            memcpy(pkt.data+2, t->value, len);
+            memcpy(pkt.data + 2, t->value, len);
             ff_mov_write_packet(s, &pkt);
             av_freep(&pkt.data);
         }
     }
+
+    return 0;
+}
+
+/*
+ * st->disposition controls the "enabled" flag in the tkhd tag.
+ * QuickTime will not play a track if it is not enabled.  So make sure
+ * that one track of each type (audio, video, subtitle) is enabled.
+ *
+ * Subtitles are special.  For audio and video, setting "enabled" also
+ * makes the track "default" (i.e. it is rendered when played). For
+ * subtitles, an "enabled" subtitle is not rendered by default, but
+ * if no subtitle is enabled, the subtitle menu in QuickTime will be
+ * empty!
+ */
+static void enable_tracks(AVFormatContext *s)
+{
+    MOVMuxContext *mov = s->priv_data;
+    int i;
+    uint8_t enabled[AVMEDIA_TYPE_NB];
+    int first[AVMEDIA_TYPE_NB];
+
+    for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
+        enabled[i] = 0;
+        first[i] = -1;
+    }
+
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+
+        if (st->codec->codec_type <= AVMEDIA_TYPE_UNKNOWN ||
+            st->codec->codec_type >= AVMEDIA_TYPE_NB)
+            continue;
+
+        if (first[st->codec->codec_type] < 0)
+            first[st->codec->codec_type] = i;
+        if (st->disposition & AV_DISPOSITION_DEFAULT) {
+            mov->tracks[i].flags |= MOV_TRACK_ENABLED;
+            enabled[st->codec->codec_type] = 1;
+        }
+    }
+
+    for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
+        switch (i) {
+        case AVMEDIA_TYPE_VIDEO:
+        case AVMEDIA_TYPE_AUDIO:
+        case AVMEDIA_TYPE_SUBTITLE:
+            if (!enabled[i] && first[i] >= 0)
+                mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
+            break;
+        }
+    }
+}
+
+static void mov_free(AVFormatContext *s)
+{
+    MOVMuxContext *mov = s->priv_data;
+    int i;
+
+    if (mov->chapter_track) {
+        if (mov->tracks[mov->chapter_track].enc)
+            av_free(mov->tracks[mov->chapter_track].enc->extradata);
+        av_freep(&mov->tracks[mov->chapter_track].enc);
+    }
+
+    for (i = 0; i < mov->nb_streams; i++) {
+        if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
+            ff_mov_close_hinting(&mov->tracks[i]);
+        av_freep(&mov->tracks[i].cluster);
+        av_freep(&mov->tracks[i].frag_info);
+
+        if (mov->tracks[i].vos_len)
+            av_free(mov->tracks[i].vos_data);
+    }
+
+    av_freep(&mov->tracks);
 }
 
 static int mov_write_header(AVFormatContext *s)
@@ -2999,6 +3158,19 @@ static int mov_write_header(AVFormatContext *s)
     AVDictionaryEntry *t;
     int i, hint_track = 0;
 
+    /* Default mode == MP4 */
+    mov->mode = MODE_MP4;
+
+    if (s->oformat != NULL) {
+        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
+        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
+        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
+        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
+        else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
+        else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
+        else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
+    }
+
     /* Set the FRAGMENT flag if any of the fragmentation methods are
      * enabled. */
     if (mov->max_fragment_duration || mov->max_fragment_size ||
@@ -3007,39 +3179,41 @@ static int mov_write_header(AVFormatContext *s)
                       FF_MOV_FLAG_FRAG_CUSTOM))
         mov->flags |= FF_MOV_FLAG_FRAGMENT;
 
+    /* Set other implicit flags immediately */
+    if (mov->mode == MODE_ISM)
+        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
+                      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) ||
+            (s->flags & AVFMT_FLAG_CUSTOM_IO)) {
+            av_log(s, AV_LOG_WARNING, "The faststart flag is incompatible "
+                   "with fragmentation and custom IO, disabling faststart\n");
+            mov->flags &= ~FF_MOV_FLAG_FASTSTART;
+        }
+    }
+
     /* 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 &&
-        ((!(mov->flags & FF_MOV_FLAG_FRAGMENT) &&
-          !(s->oformat && !strcmp(s->oformat->name, "ismv")))
-         || mov->ism_lookahead)) {
+        (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {
         av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
-        return -1;
+        return AVERROR(EINVAL);
     }
 
-    /* Default mode == MP4 */
-    mov->mode = MODE_MP4;
 
-    if (s->oformat != NULL) {
-        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
-        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
-        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
-        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
-        else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
-        else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
-
-        mov_write_ftyp_tag(pb,s);
-        if (mov->mode == MODE_PSP) {
-            if (s->nb_streams != 2) {
-                av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
-                return -1;
-            }
-            mov_write_uuidprof_tag(pb,s);
+    mov_write_ftyp_tag(pb,s);
+    if (mov->mode == MODE_PSP) {
+        if (s->nb_streams != 2) {
+            av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
+            return AVERROR(EINVAL);
         }
+        mov_write_uuidprof_tag(pb, s);
     }
 
     mov->nb_streams = s->nb_streams;
-    if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters)
+    if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
         mov->chapter_track = mov->nb_streams++;
 
     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
@@ -3054,11 +3228,13 @@ static int mov_write_header(AVFormatContext *s)
         }
     }
 
-    mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks));
+    // Reserve an extra stream for chapters for the case where chapters
+    // are written in the trailer
+    mov->tracks = av_mallocz((mov->nb_streams + 1) * sizeof(*mov->tracks));
     if (!mov->tracks)
         return AVERROR(ENOMEM);
 
-    for(i=0; i<s->nb_streams; i++){
+    for (i = 0; i < s->nb_streams; i++) {
         AVStream *st= s->streams[i];
         MOVTrack *track= &mov->tracks[i];
         AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
@@ -3068,7 +3244,7 @@ static int mov_write_header(AVFormatContext *s)
         if (track->language < 0)
             track->language = 0;
         track->mode = mov->mode;
-        track->tag = mov_find_codec_tag(s, track);
+        track->tag  = mov_find_codec_tag(s, track);
         if (!track->tag) {
             av_log(s, AV_LOG_ERROR, "track %d: could not find tag, "
                    "codec not currently supported in container\n", i);
@@ -3077,8 +3253,8 @@ static int mov_write_header(AVFormatContext *s)
         /* If hinting of this track is enabled by a later hint track,
          * this is updated. */
         track->hint_track = -1;
-        track->start_dts = AV_NOPTS_VALUE;
-        if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
+        track->start_dts  = AV_NOPTS_VALUE;
+        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
             if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
                 track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
                 track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
@@ -3086,7 +3262,7 @@ static int mov_write_header(AVFormatContext *s)
                     av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
                     goto error;
                 }
-                track->height = track->tag>>24 == 'n' ? 486 : 576;
+                track->height = track->tag >> 24 == 'n' ? 486 : 576;
             }
             track->timescale = st->codec->time_base.den;
             if (track->mode == MODE_MOV && track->timescale > 100000)
@@ -3094,7 +3270,7 @@ static int mov_write_header(AVFormatContext *s)
                        "WARNING codec timebase is very high. If duration is too long,\n"
                        "file may not be playable by quicktime. Specify a shorter timebase\n"
                        "or choose different container.\n");
-        }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             track->timescale = st->codec->sample_rate;
             /* set sample_size for PCM and ADPCM */
             if (av_get_bits_per_sample(st->codec->codec_id) ||
@@ -3115,7 +3291,9 @@ static int mov_write_header(AVFormatContext *s)
                        i, track->enc->sample_rate);
                 goto error;
             }
-        }else if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE){
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+            track->timescale = st->codec->time_base.den;
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) {
             track->timescale = st->codec->time_base.den;
         }
         if (!track->height)
@@ -3135,18 +3313,21 @@ static int mov_write_header(AVFormatContext *s)
         }
     }
 
+    enable_tracks(s);
+
     if (mov->mode == MODE_ISM) {
         /* If no fragmentation options have been set, set a default. */
         if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
                             FF_MOV_FLAG_FRAG_CUSTOM)) &&
             !mov->max_fragment_duration && !mov->max_fragment_size)
-            mov->max_fragment_duration = 5000000;
-        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
-                      FF_MOV_FLAG_FRAGMENT;
+            mov->flags |= FF_MOV_FLAG_FRAG_KEYFRAME;
     }
 
-    if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
+    if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+        if (mov->flags & FF_MOV_FLAG_FASTSTART)
+            mov->reserved_moov_pos = avio_tell(pb);
         mov_write_mdat_tag(pb, mov);
+    }
 
     if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
         mov->time = ff_iso8601_to_unix_time(t->value);
@@ -3154,7 +3335,8 @@ static int mov_write_header(AVFormatContext *s)
         mov->time += 0x7C25B080; // 1970 based -> 1904 based
 
     if (mov->chapter_track)
-        mov_create_chapter_track(s, mov->chapter_track);
+        if (mov_create_chapter_track(s, mov->chapter_track) < 0)
+            goto error;
 
     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
         /* Initialize the hint tracks for each audio and video stream */
@@ -3180,20 +3362,138 @@ static int mov_write_header(AVFormatContext *s)
 
     return 0;
  error:
-    av_freep(&mov->tracks);
+    mov_free(s);
     return -1;
 }
 
+static int get_moov_size(AVFormatContext *s)
+{
+    int ret;
+    AVIOContext *moov_buf;
+    MOVMuxContext *mov = s->priv_data;
+
+    if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
+        return ret;
+    mov_write_moov_tag(moov_buf, mov, s);
+    return ffio_close_null_buf(moov_buf);
+}
+
+/*
+ * 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 beginning, 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 need 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;
     int res = 0;
     int i;
-
-    int64_t moov_pos = avio_tell(pb);
+    int64_t moov_pos;
+
+    // If there were no chapters when the header was written, but there
+    // are chapters now, write them in the trailer.  This only works
+    // when we are not doing fragments.
+    if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+        if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
+            mov->chapter_track = mov->nb_streams++;
+            if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
+                goto error;
+        }
+    }
 
     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+        moov_pos = avio_tell(pb);
+
         /* Write size of mdat tag */
         if (mov->mdat_size + 8 <= UINT32_MAX) {
             avio_seek(pb, mov->mdat_pos, SEEK_SET);
@@ -3209,18 +3509,22 @@ static int mov_write_trailer(AVFormatContext *s)
         }
         avio_seek(pb, moov_pos, SEEK_SET);
 
-        mov_write_moov_tag(pb, mov, s);
+        if (mov->flags & FF_MOV_FLAG_FASTSTART) {
+            av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
+            res = shift_data(s);
+            if (res == 0) {
+                avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET);
+                mov_write_moov_tag(pb, mov, s);
+            }
+        } else {
+            mov_write_moov_tag(pb, mov, s);
+        }
     } else {
         mov_flush_fragment(s);
         mov_write_mfra_tag(pb, mov);
     }
 
-    if (mov->chapter_track)
-        av_freep(&mov->tracks[mov->chapter_track].enc);
-
-    for (i=0; i<mov->nb_streams; i++) {
-        if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
-            ff_mov_close_hinting(&mov->tracks[i]);
+    for (i = 0; i < mov->nb_streams; i++) {
         if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
             mov->tracks[i].vc1_info.struct_offset && s->pb->seekable) {
             int64_t off = avio_tell(pb);
@@ -3231,15 +3535,10 @@ static int mov_write_trailer(AVFormatContext *s)
                 avio_seek(pb, off, SEEK_SET);
             }
         }
-        av_freep(&mov->tracks[i].cluster);
-        av_freep(&mov->tracks[i].frag_info);
-
-        if (mov->tracks[i].vos_len)
-            av_free(mov->tracks[i].vos_data);
-
     }
 
-    av_freep(&mov->tracks);
+error:
+    mov_free(s);
 
     return res;
 }
@@ -3257,7 +3556,7 @@ AVOutputFormat ff_mov_muxer = {
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){
         ff_codec_movvideo_tags, ff_codec_movaudio_tags, 0
     },
@@ -3276,7 +3575,7 @@ AVOutputFormat ff_tgp_muxer = {
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
     .priv_class        = &tgp_muxer_class,
 };
@@ -3295,7 +3594,7 @@ AVOutputFormat ff_mp4_muxer = {
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
     .priv_class        = &mp4_muxer_class,
 };
@@ -3313,7 +3612,7 @@ AVOutputFormat ff_psp_muxer = {
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
     .priv_class        = &psp_muxer_class,
 };
@@ -3330,7 +3629,7 @@ AVOutputFormat ff_tg2_muxer = {
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
     .priv_class        = &tg2_muxer_class,
 };
@@ -3348,7 +3647,7 @@ AVOutputFormat ff_ipod_muxer = {
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
     .priv_class        = &ipod_muxer_class,
 };
@@ -3366,8 +3665,26 @@ AVOutputFormat ff_ismv_muxer = {
     .write_header      = mov_write_header,
     .write_packet      = mov_write_packet,
     .write_trailer     = mov_write_trailer,
-    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
     .priv_class        = &ismv_muxer_class,
 };
 #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 | AVFMT_TS_NEGATIVE,
+    .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..1b669e8 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -26,7 +26,8 @@
 
 #include "avformat.h"
 
-#define MOV_INDEX_CLUSTER_SIZE 16384
+#define MOV_FRAG_INFO_ALLOC_INCREMENT 64
+#define MOV_INDEX_CLUSTER_SIZE 1024
 #define MOV_TIMESCALE 1000
 
 #define RTP_MAX_PACKET_SIZE 1450
@@ -39,6 +40,7 @@
 #define MODE_3G2  0x10
 #define MODE_IPOD 0x20
 #define MODE_ISM  0x40
+#define MODE_F4V  0x80
 
 typedef struct MOVIentry {
     uint64_t     pos;
@@ -73,7 +75,7 @@ typedef struct MOVFragmentInfo {
     int64_t tfrf_offset;
 } MOVFragmentInfo;
 
-typedef struct MOVIndex {
+typedef struct MOVTrack {
     int         mode;
     int         entry;
     unsigned    timescale;
@@ -84,6 +86,7 @@ typedef struct MOVIndex {
     int         has_keyframes;
 #define MOV_TRACK_CTTS         0x0001
 #define MOV_TRACK_STPS         0x0002
+#define MOV_TRACK_ENABLED      0x0004
     uint32_t    flags;
     int         language;
     int         track_id;
@@ -93,6 +96,7 @@ typedef struct MOVIndex {
     int         vos_len;
     uint8_t     *vos_data;
     MOVIentry   *cluster;
+    unsigned    cluster_capacity;
     int         audio_vbr;
     int         height; ///< active picture (w/o VBI) height for D-10/IMX
     uint32_t    tref_tag;
@@ -113,13 +117,13 @@ typedef struct MOVIndex {
     HintSampleQueue sample_queue;
 
     AVIOContext *mdat_buf;
-    int64_t     moof_size_offset;
     int64_t     data_offset;
     int64_t     frag_start;
     int64_t     tfrf_offset;
 
     int         nb_frag_info;
     MOVFragmentInfo *frag_info;
+    unsigned    frag_info_capacity;
 
     struct {
         int64_t struct_offset;
@@ -153,6 +157,8 @@ typedef struct MOVMuxContext {
     int max_fragment_size;
     int ism_lookahead;
     AVIOContext *mdat_buf;
+
+    int64_t reserved_moov_pos;
 } MOVMuxContext;
 
 #define FF_MOV_FLAG_RTP_HINT 1
@@ -162,6 +168,8 @@ typedef struct MOVMuxContext {
 #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
+#define FF_MOV_FLAG_OMIT_TFHD_OFFSET 256
 
 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
 
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index 02391b5..a8f5f34 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -87,7 +87,7 @@ static void sample_queue_free(HintSampleQueue *queue)
         if (queue->samples[i].own_data)
             av_free(queue->samples[i].data);
     av_freep(&queue->samples);
-    queue->len = 0;
+    queue->len  = 0;
     queue->size = 0;
 }
 
@@ -104,17 +104,16 @@ static void sample_queue_push(HintSampleQueue *queue, uint8_t *data, int size,
     if (size <= 14)
         return;
     if (!queue->samples || queue->len >= queue->size) {
-        HintSample* samples;
         queue->size += 10;
-        samples = av_realloc(queue->samples, sizeof(HintSample)*queue->size);
-        if (!samples)
+        if (av_reallocp(&queue->samples, sizeof(*queue->samples) * queue->size) < 0) {
+            queue->len = queue->size = 0;
             return;
-        queue->samples = samples;
+        }
     }
     queue->samples[queue->len].data = data;
     queue->samples[queue->len].size = size;
     queue->samples[queue->len].sample_number = sample;
-    queue->samples[queue->len].offset = 0;
+    queue->samples[queue->len].offset   = 0;
     queue->samples[queue->len].own_data = 0;
     queue->len++;
 }
@@ -128,7 +127,7 @@ static void sample_queue_retain(HintSampleQueue *queue)
     for (i = 0; i < queue->len; ) {
         HintSample *sample = &queue->samples[i];
         if (!sample->own_data) {
-            uint8_t* ptr = av_malloc(sample->size);
+            uint8_t *ptr = av_malloc(sample->size);
             if (!ptr) {
                 /* Unable to allocate memory for this one, remove it */
                 memmove(queue->samples + i, queue->samples + i + 1,
@@ -309,11 +308,11 @@ static void describe_payload(const uint8_t *data, int size,
  * @param data buffer containing RTP packets
  * @param size the size of the data buffer
  * @param trk the MOVTrack for the hint track
- * @param pts pointer where the timestamp for the written RTP hint is stored
+ * @param dts pointer where the timestamp for the written RTP hint is stored
  * @return the number of RTP packets in the written hint
  */
 static int write_hint_packets(AVIOContext *out, const uint8_t *data,
-                              int size, MOVTrack *trk, int64_t *pts)
+                              int size, MOVTrack *trk, int64_t *dts)
 {
     int64_t curpos;
     int64_t count_pos, entries_pos;
@@ -328,6 +327,7 @@ static int write_hint_packets(AVIOContext *out, const uint8_t *data,
         uint32_t packet_len = AV_RB32(data);
         uint16_t seq;
         uint32_t ts;
+        int32_t  ts_diff;
 
         data += 4;
         size -= 4;
@@ -344,25 +344,35 @@ static int write_hint_packets(AVIOContext *out, const uint8_t *data,
             trk->max_packet_size = packet_len;
 
         seq = AV_RB16(&data[2]);
-        ts = AV_RB32(&data[4]);
+        ts  = AV_RB32(&data[4]);
 
         if (trk->prev_rtp_ts == 0)
             trk->prev_rtp_ts = ts;
         /* Unwrap the 32-bit RTP timestamp that wraps around often
          * into a not (as often) wrapping 64-bit timestamp. */
-        trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts);
-        trk->prev_rtp_ts = ts;
-        if (*pts == AV_NOPTS_VALUE)
-            *pts = trk->cur_rtp_ts_unwrapped;
+        ts_diff = ts - trk->prev_rtp_ts;
+        if (ts_diff > 0) {
+            trk->cur_rtp_ts_unwrapped += ts_diff;
+            trk->prev_rtp_ts = ts;
+            ts_diff = 0;
+        }
+        if (*dts == AV_NOPTS_VALUE)
+            *dts = trk->cur_rtp_ts_unwrapped;
 
         count++;
         /* RTPpacket header */
         avio_wb32(out, 0); /* relative_time */
         avio_write(out, data, 2); /* RTP header */
         avio_wb16(out, seq); /* RTPsequenceseed */
-        avio_wb16(out, 0); /* reserved + flags */
+        avio_wb16(out, ts_diff ? 4 : 0); /* reserved + flags (extra_flag) */
         entries_pos = avio_tell(out);
         avio_wb16(out, 0); /* entry count */
+        if (ts_diff) { /* if extra_flag is set */
+            avio_wb32(out, 16); /* extra_information_length */
+            avio_wb32(out, 12); /* rtpoffsetTLV box */
+            avio_write(out, "rtpo", 4);
+            avio_wb32(out, ts_diff);
+        }
 
         data += 12;
         size -= 12;
@@ -417,7 +427,7 @@ int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt,
      * for next time. */
     size = avio_close_dyn_buf(rtp_ctx->pb, &buf);
     if ((ret = ffio_open_dyn_packet_buf(&rtp_ctx->pb,
-                                       RTP_MAX_PACKET_SIZE)) < 0)
+                                        RTP_MAX_PACKET_SIZE)) < 0)
         goto done;
 
     if (size <= 0)
@@ -445,8 +455,9 @@ done:
     return ret;
 }
 
-void ff_mov_close_hinting(MOVTrack *track) {
-    AVFormatContext* rtp_ctx = track->rtp_ctx;
+void ff_mov_close_hinting(MOVTrack *track)
+{
+    AVFormatContext *rtp_ctx = track->rtp_ctx;
     uint8_t *ptr;
 
     av_freep(&track->enc);
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 9da9aa8..5c263ed 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -73,7 +73,7 @@ static int mp3_read_probe(AVProbeData *p)
     }
     // 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 (first_frames >= 4) return AVPROBE_SCORE_EXTENSION + 1;
 
     if (max_frames) {
         int pes = 0, i;
@@ -94,8 +94,8 @@ static int mp3_read_probe(AVProbeData *p)
         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;
+    if      (max_frames >  500) return AVPROBE_SCORE_EXTENSION;
+    else if (max_frames >= 4)   return AVPROBE_SCORE_EXTENSION / 2;
     else if (max_frames >= 1)   return 1;
     else                        return 0;
 //mpegps_mp3_unrecognized_format.mpg has max_frames=3
@@ -282,5 +282,5 @@ AVInputFormat ff_mp3_demuxer = {
     .read_seek      = mp3_seek,
     .priv_data_size = sizeof(MP3DecContext),
     .flags          = AVFMT_GENERIC_INDEX,
-    .extensions     = "mp2,mp3,m2a", /* XXX: use probe */
+    .extensions     = "mp2,mp3,m2a,mpa", /* XXX: use probe */
 };
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index c969777..574a3b2 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -306,7 +306,7 @@ AVOutputFormat ff_mp2_muxer = {
     .name              = "mp2",
     .long_name         = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
     .mime_type         = "audio/x-mpeg",
-    .extensions        = "mp2,m2a",
+    .extensions        = "mp2,m2a,mpa",
     .audio_codec       = AV_CODEC_ID_MP2,
     .video_codec       = AV_CODEC_ID_NONE,
     .write_packet      = ff_raw_write_packet,
@@ -343,7 +343,11 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt)
                 return AVERROR(ENOMEM);
 
             pktl->pkt     = *pkt;
-            pkt->destruct = NULL;
+            pktl->pkt.buf = av_buffer_ref(pkt->buf);
+            if (!pktl->pkt.buf) {
+                av_freep(&pktl);
+                return AVERROR(ENOMEM);
+            }
 
             if (mp3->queue_end)
                 mp3->queue_end->next = pktl;
diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c
index c7aa875..3564e81 100644
--- a/libavformat/mpc8.c
+++ b/libavformat/mpc8.c
@@ -92,7 +92,7 @@ static int mpc8_probe(AVProbeData *p)
         if (size < 2)
             return 0;
         if (bs + size - 2 >= bs_end)
-            return AVPROBE_SCORE_MAX / 4 - 1; //seems to be valid MPC but no header yet
+            return AVPROBE_SCORE_EXTENSION - 1; // seems to be valid MPC but no header yet
         if (header_found) {
             if (size < 11 || size > 28)
                 return 0;
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 2d08b17..7430bb0 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -82,14 +82,14 @@ static int mpegps_probe(AVProbeData *p)
     }
 
     if(vid+audio > invalid)     /* invalid VDR files nd short PES streams */
-        score= AVPROBE_SCORE_MAX/4;
+        score = AVPROBE_SCORE_EXTENSION / 2;
 
     if(sys>invalid && sys*9 <= pspack*10)
-        return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+        return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
     if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9)
-        return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+        return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
     if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */
-        return (audio > 12 || vid > 3) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4;
+        return (audio > 12 || vid > 3) ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2;
 
     //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
     //mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
@@ -453,7 +453,6 @@ static int mpegps_read_packet(AVFormatContext *s,
         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;
     } else if (startcode >= 0xb0 && startcode <= 0xbf) {
         type = AVMEDIA_TYPE_AUDIO;
@@ -494,35 +493,10 @@ static int mpegps_read_packet(AVFormatContext *s,
     st->id = startcode;
     st->codec->codec_type = type;
     st->codec->codec_id = codec_id;
-    if (codec_id != AV_CODEC_ID_PCM_S16BE)
-        st->need_parsing = AVSTREAM_PARSE_FULL;
+    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))) {
-        int b1, freq;
-
-        /* for LPCM, we just skip the header and consider it is raw
-           audio data */
-        if (len <= 3)
-            goto skip;
-        avio_r8(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */
-        b1 = avio_r8(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */
-        avio_r8(s->pb); /* dynamic range control (0x80 = off) */
-        len -= 3;
-        freq = (b1 >> 4) & 3;
-        st->codec->sample_rate = lpcm_freq_tab[freq];
-        st->codec->channels = 1 + (b1 & 7);
-        st->codec->bits_per_coded_sample = 16 + ((b1 >> 6) & 3) * 4;
-        st->codec->bit_rate = st->codec->channels *
-                              st->codec->sample_rate *
-                              st->codec->bits_per_coded_sample;
-        if (st->codec->bits_per_coded_sample == 16)
-            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;
     pkt->dts = dts;
diff --git a/libavformat/mpeg.h b/libavformat/mpeg.h
index 75dddf3..629f2f0 100644
--- a/libavformat/mpeg.h
+++ b/libavformat/mpeg.h
@@ -54,6 +54,7 @@
 #define STREAM_TYPE_AUDIO_AAC       0x0f
 #define STREAM_TYPE_VIDEO_MPEG4     0x10
 #define STREAM_TYPE_VIDEO_H264      0x1b
+#define STREAM_TYPE_VIDEO_CAVS      0x42
 
 #define STREAM_TYPE_AUDIO_AC3       0x81
 #define STREAM_TYPE_AUDIO_DTS       0x8a
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index 4f7bde8..13d5b03 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -19,6 +19,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
 #include "libavutil/fifo.h"
 #include "libavutil/log.h"
 #include "libavutil/mathematics.h"
@@ -292,7 +295,7 @@ static int get_system_header_size(AVFormatContext *ctx)
     return buf_index;
 }
 
-static int mpeg_mux_init(AVFormatContext *ctx)
+static av_cold int mpeg_mux_init(AVFormatContext *ctx)
 {
     MpegMuxContext *s = ctx->priv_data;
     int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j;
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 7c4d447..3f828b4 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -19,6 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/buffer.h"
 #include "libavutil/crc.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
@@ -27,6 +28,7 @@
 #include "libavutil/opt.h"
 #include "libavcodec/bytestream.h"
 #include "libavcodec/get_bits.h"
+#include "libavcodec/mathops.h"
 #include "avformat.h"
 #include "mpegts.h"
 #include "internal.h"
@@ -97,6 +99,8 @@ struct MpegTSContext {
     int raw_packet_size;
 
     int pos47;
+    /** position corresponding to pos47, or 0 if pos47 invalid */
+    int64_t pos;
 
     /** if true, all pids are analyzed to find streams       */
     int auto_guess;
@@ -173,7 +177,7 @@ typedef struct PESContext {
     int64_t pts, dts;
     int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */
     uint8_t header[MAX_PES_HEADER_SIZE];
-    uint8_t *buffer;
+    AVBufferRef *buffer;
     SLConfigDescr sl;
 } PESContext;
 
@@ -197,10 +201,10 @@ static void clear_programs(MpegTSContext *ts)
 static void add_pat_entry(MpegTSContext *ts, unsigned int programid)
 {
     struct Program *p;
-    void *tmp = av_realloc(ts->prg, (ts->nb_prg+1)*sizeof(struct Program));
-    if(!tmp)
+    if (av_reallocp_array(&ts->prg, ts->nb_prg + 1, sizeof(*ts->prg)) < 0) {
+        ts->nb_prg = 0;
         return;
-    ts->prg = tmp;
+    }
     p = &ts->prg[ts->nb_prg];
     p->id = programid;
     p->nb_pids = 0;
@@ -238,6 +242,17 @@ static int discard_pid(MpegTSContext *ts, unsigned int pid)
     int i, j, k;
     int used = 0, discarded = 0;
     struct Program *p;
+
+    /* If none of the programs have .discard=AVDISCARD_ALL then there's
+     * no way we have to discard this packet
+     */
+    for (k = 0; k < ts->stream->nb_programs; k++) {
+        if (ts->stream->programs[k]->discard == AVDISCARD_ALL)
+            break;
+    }
+    if (k == ts->stream->nb_programs)
+        return 0;
+
     for(i=0; i<ts->nb_prg; i++) {
         p = &ts->prg[i];
         for(j=0; j<p->nb_pids; j++) {
@@ -364,7 +379,7 @@ static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
         av_freep(&filter->u.section_filter.section_buf);
     else if (filter->type == MPEGTS_PES) {
         PESContext *pes = filter->u.pes_filter.opaque;
-        av_freep(&pes->buffer);
+        av_buffer_unref(&pes->buffer);
         /* referenced private data will be freed later in
          * avformat_close_input */
         if (!((PESContext *)filter->u.pes_filter.opaque)->st) {
@@ -522,6 +537,8 @@ static const StreamType ISO_types[] = {
     { 0x10, AVMEDIA_TYPE_VIDEO,      AV_CODEC_ID_MPEG4 },
     { 0x11, AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_AAC_LATM }, /* LATM syntax */
     { 0x1b, AVMEDIA_TYPE_VIDEO,       AV_CODEC_ID_H264 },
+    { 0x24, AVMEDIA_TYPE_VIDEO,       AV_CODEC_ID_HEVC },
+    { 0x42, AVMEDIA_TYPE_VIDEO,       AV_CODEC_ID_CAVS },
     { 0xd1, AVMEDIA_TYPE_VIDEO,      AV_CODEC_ID_DIRAC },
     { 0xea, AVMEDIA_TYPE_VIDEO,        AV_CODEC_ID_VC1 },
     { 0 },
@@ -553,6 +570,7 @@ static const StreamType REGD_types[] = {
     { MKTAG('D','T','S','1'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
     { MKTAG('D','T','S','2'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
     { MKTAG('D','T','S','3'), AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_DTS },
+    { MKTAG('H','E','V','C'), AVMEDIA_TYPE_VIDEO,  AV_CODEC_ID_HEVC },
     { MKTAG('V','C','-','1'), AVMEDIA_TYPE_VIDEO,   AV_CODEC_ID_VC1 },
     { 0 },
 };
@@ -635,8 +653,8 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt)
 {
     av_init_packet(pkt);
 
-    pkt->destruct = av_destruct_packet;
-    pkt->data = pes->buffer;
+    pkt->buf  = pes->buffer;
+    pkt->data = pes->buffer->data;
     pkt->size = pes->data_index;
 
     if(pes->total_size != MAX_PES_PAYLOAD &&
@@ -793,7 +811,8 @@ static int mpegts_push_data(MpegTSFilter *filter,
                         pes->total_size = MAX_PES_PAYLOAD;
 
                     /* allocate pes buffer */
-                    pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE);
+                    pes->buffer = av_buffer_alloc(pes->total_size +
+                                                  FF_INPUT_BUFFER_PADDING_SIZE);
                     if (!pes->buffer)
                         return AVERROR(ENOMEM);
 
@@ -895,7 +914,7 @@ static int mpegts_push_data(MpegTSFilter *filter,
                 if (pes->data_index > 0 && pes->data_index+buf_size > pes->total_size) {
                     new_pes_packet(pes, ts->pkt);
                     pes->total_size = MAX_PES_PAYLOAD;
-                    pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE);
+                    pes->buffer = av_buffer_alloc(pes->total_size + FF_INPUT_BUFFER_PADDING_SIZE);
                     if (!pes->buffer)
                         return AVERROR(ENOMEM);
                     ts->stop_parse = 1;
@@ -904,7 +923,7 @@ static int mpegts_push_data(MpegTSFilter *filter,
                     // not sure if this is legal in ts but see issue #2392
                     buf_size = pes->total_size;
                 }
-                memcpy(pes->buffer+pes->data_index, p, buf_size);
+                memcpy(pes->buffer->data + pes->data_index, p, buf_size);
                 pes->data_index += buf_size;
             }
             buf_size = 0;
@@ -1089,7 +1108,7 @@ static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len)
         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);
+        avpriv_report_missing_feature(d->s, "Predefined SLConfigDescriptor");
     }
     return 0;
 }
@@ -1311,7 +1330,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
         }
         if (st->codec->extradata) {
             if (st->codec->extradata_size == 4 && memcmp(st->codec->extradata, *pp, 4))
-                av_log_ask_for_sample(fc, "DVB sub with multiple IDs\n");
+                avpriv_request_sample(fc, "DVB sub with multiple IDs");
         } else {
             st->codec->extradata = av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE);
             if (st->codec->extradata) {
@@ -1680,7 +1699,7 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
         return 0;
 
     pos = avio_tell(ts->stream->pb);
-    ts->pos47= pos % ts->raw_packet_size;
+    MOD_UNLIKELY(ts->pos47, pos, ts->raw_packet_size, ts->pos);
 
     if (tss->type == MPEGTS_SECTION) {
         if (is_start) {
@@ -1740,17 +1759,17 @@ static int mpegts_resync(AVFormatContext *s)
 }
 
 /* return -1 if error or EOF. Return 0 if OK. */
-static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size)
+static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size, const uint8_t **data)
 {
     AVIOContext *pb = s->pb;
-    int skip, len;
+    int len;
 
     for(;;) {
-        len = avio_read(pb, buf, TS_PACKET_SIZE);
+        len = ffio_read_indirect(pb, buf, TS_PACKET_SIZE, data);
         if (len != TS_PACKET_SIZE)
             return len < 0 ? len : AVERROR_EOF;
         /* check packet sync byte */
-        if (buf[0] != 0x47) {
+        if ((*data)[0] != 0x47) {
             /* find a new packet start */
             avio_seek(pb, -TS_PACKET_SIZE, SEEK_CUR);
             if (mpegts_resync(s) < 0)
@@ -1758,19 +1777,25 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size)
             else
                 continue;
         } else {
-            skip = raw_packet_size - TS_PACKET_SIZE;
-            if (skip > 0)
-                avio_skip(pb, skip);
             break;
         }
     }
     return 0;
 }
 
+static void finished_reading_packet(AVFormatContext *s, int raw_packet_size)
+{
+    AVIOContext *pb = s->pb;
+    int skip = raw_packet_size - TS_PACKET_SIZE;
+    if (skip > 0)
+        avio_skip(pb, skip);
+}
+
 static int handle_packets(MpegTSContext *ts, int nb_packets)
 {
     AVFormatContext *s = ts->stream;
     uint8_t packet[TS_PACKET_SIZE+FF_INPUT_BUFFER_PADDING_SIZE];
+    const uint8_t *data;
     int packet_num, ret = 0;
 
     if (avio_tell(s->pb) != ts->last_pos) {
@@ -1781,7 +1806,7 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
             if (ts->pids[i]) {
                 if (ts->pids[i]->type == MPEGTS_PES) {
                    PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
-                   av_freep(&pes->buffer);
+                   av_buffer_unref(&pes->buffer);
                    pes->data_index = 0;
                    pes->state = MPEGTS_SKIP; /* skip until pes header */
                 }
@@ -1799,10 +1824,11 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
         packet_num++;
         if (nb_packets != 0 && packet_num >= nb_packets)
             break;
-        ret = read_packet(s, packet, ts->raw_packet_size);
+        ret = read_packet(s, packet, ts->raw_packet_size, &data);
         if (ret != 0)
             break;
-        ret = handle_packet(ts, packet);
+        ret = handle_packet(ts, data);
+        finished_reading_packet(s, ts->raw_packet_size);
         if (ret != 0)
             break;
     }
@@ -1906,6 +1932,7 @@ static int mpegts_read_header(AVFormatContext *s)
         int64_t pcrs[2], pcr_h;
         int packet_count[2];
         uint8_t packet[TS_PACKET_SIZE];
+        const uint8_t *data;
 
         /* only read packets */
 
@@ -1921,18 +1948,21 @@ static int mpegts_read_header(AVFormatContext *s)
         nb_pcrs = 0;
         nb_packets = 0;
         for(;;) {
-            ret = read_packet(s, packet, ts->raw_packet_size);
+            ret = read_packet(s, packet, ts->raw_packet_size, &data);
             if (ret < 0)
                 return -1;
-            pid = AV_RB16(packet + 1) & 0x1fff;
+            pid = AV_RB16(data + 1) & 0x1fff;
             if ((pcr_pid == -1 || pcr_pid == pid) &&
-                parse_pcr(&pcr_h, &pcr_l, packet) == 0) {
+                parse_pcr(&pcr_h, &pcr_l, data) == 0) {
+                finished_reading_packet(s, ts->raw_packet_size);
                 pcr_pid = pid;
                 packet_count[nb_pcrs] = nb_packets;
                 pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;
                 nb_pcrs++;
                 if (nb_pcrs >= 2)
                     break;
+            } else {
+                finished_reading_packet(s, ts->raw_packet_size);
             }
             nb_packets++;
         }
@@ -1964,15 +1994,19 @@ static int mpegts_raw_read_packet(AVFormatContext *s,
     int64_t pcr_h, next_pcr_h, pos;
     int pcr_l, next_pcr_l;
     uint8_t pcr_buf[12];
+    const uint8_t *data;
 
     if (av_new_packet(pkt, TS_PACKET_SIZE) < 0)
         return AVERROR(ENOMEM);
     pkt->pos= avio_tell(s->pb);
-    ret = read_packet(s, pkt->data, ts->raw_packet_size);
+    ret = read_packet(s, pkt->data, ts->raw_packet_size, &data);
     if (ret < 0) {
         av_free_packet(pkt);
         return ret;
     }
+    if (data != pkt->data)
+        memcpy(pkt->data, data, ts->raw_packet_size);
+    finished_reading_packet(s, ts->raw_packet_size);
     if (ts->mpeg2ts_compute_pcr) {
         /* compute exact PCR for each packet */
         if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) {
@@ -2029,16 +2063,20 @@ static int mpegts_read_packet(AVFormatContext *s,
     return ret;
 }
 
-static int mpegts_read_close(AVFormatContext *s)
+static void mpegts_free(MpegTSContext *ts)
 {
-    MpegTSContext *ts = s->priv_data;
     int i;
 
     clear_programs(ts);
 
     for(i=0;i<NB_PID_MAX;i++)
         if (ts->pids[i]) mpegts_close_filter(ts, ts->pids[i]);
+}
 
+static int mpegts_read_close(AVFormatContext *s)
+{
+    MpegTSContext *ts = s->priv_data;
+    mpegts_free(ts);
     return 0;
 }
 
@@ -2150,10 +2188,7 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,
 
 void ff_mpegts_parse_close(MpegTSContext *ts)
 {
-    int i;
-
-    for(i=0;i<NB_PID_MAX;i++)
-        av_free(ts->pids[i]);
+    mpegts_free(ts);
     av_free(ts);
 }
 
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 89544f0..fafe98f 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -52,6 +52,7 @@
 #define STREAM_TYPE_AUDIO_AAC_LATM  0x11
 #define STREAM_TYPE_VIDEO_MPEG4     0x10
 #define STREAM_TYPE_VIDEO_H264      0x1b
+#define STREAM_TYPE_VIDEO_CAVS      0x42
 #define STREAM_TYPE_VIDEO_VC1       0xea
 #define STREAM_TYPE_VIDEO_DIRAC     0xd1
 
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 29d83c6..8efd93e 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -22,9 +22,10 @@
 #include "libavutil/bswap.h"
 #include "libavutil/crc.h"
 #include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
-#include "libavcodec/mpegvideo.h"
+#include "libavcodec/internal.h"
 #include "avformat.h"
 #include "internal.h"
 #include "mpegts.h"
@@ -279,6 +280,9 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
         case AV_CODEC_ID_H264:
             stream_type = STREAM_TYPE_VIDEO_H264;
             break;
+        case AV_CODEC_ID_CAVS:
+            stream_type = STREAM_TYPE_VIDEO_CAVS;
+            break;
         case AV_CODEC_ID_DIRAC:
             stream_type = STREAM_TYPE_VIDEO_DIRAC;
             break;
@@ -1016,7 +1020,7 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
         }
 
         do {
-            p = avpriv_mpv_find_start_code(p, buf_end, &state);
+            p = avpriv_find_start_code(p, buf_end, &state);
             av_dlog(s, "nal %d\n", state & 0x1f);
         } while (p < buf_end && (state & 0x1f) != 9 &&
                  (state & 0x1f) != 5 && (state & 0x1f) != 1);
diff --git a/libavformat/mpegvideodec.c b/libavformat/mpegvideodec.c
index 87e5e03..96b95a5 100644
--- a/libavformat/mpegvideodec.c
+++ b/libavformat/mpegvideodec.c
@@ -51,7 +51,7 @@ static int mpegvideo_probe(AVProbeData *p)
         }
     }
     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
+        return pic>1 ? AVPROBE_SCORE_EXTENSION + 1 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
     return 0;
 }
 
diff --git a/libavformat/mpjpeg.c b/libavformat/mpjpeg.c
index 6c8bd0c..2114189 100644
--- a/libavformat/mpjpeg.c
+++ b/libavformat/mpjpeg.c
@@ -44,7 +44,6 @@ static int mpjpeg_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     snprintf(buf1, sizeof(buf1), "\n--%s\n", BOUNDARY_TAG);
     avio_write(s->pb, buf1, strlen(buf1));
-    avio_flush(s->pb);
     return 0;
 }
 
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index 1566faa..ed250bc 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -64,13 +64,13 @@ static int mtv_probe(AVProbeData *p)
     if(!AV_RL16(&p->buf[52]) || !AV_RL16(&p->buf[54]))
     {
         if(!!AV_RL16(&p->buf[56]))
-            return AVPROBE_SCORE_MAX/2;
+            return AVPROBE_SCORE_EXTENSION;
         else
             return 0;
     }
 
     if(p->buf[51] != 16)
-        return AVPROBE_SCORE_MAX/4; // But we are going to assume 16bpp anyway ..
+        return AVPROBE_SCORE_EXTENSION / 2; // But we are going to assume 16bpp anyway ..
 
     return AVPROBE_SCORE_MAX;
 }
@@ -108,7 +108,7 @@ static int mtv_read_header(AVFormatContext *s)
     audio_subsegments = avio_rl16(pb);
 
     if (audio_subsegments == 0) {
-        av_log_ask_for_sample(s, "MTV files without audio are not supported\n");
+        avpriv_request_sample(s, "MTV files without audio");
         return AVERROR_PATCHWELCOME;
     }
 
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 96eecb5..505ed2e 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -19,8 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/* #define DEBUG */
-
 #include "avformat.h"
 #include "avio_internal.h"
 #include "internal.h"
@@ -33,6 +31,7 @@
 #include "id3v2.h"
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
+#include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/time.h"
@@ -189,13 +188,18 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
 
             if (av_cmp_q(st->sample_aspect_ratio,
                          codec->sample_aspect_ratio)) {
-                av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
-                                        "(%d/%d) and encoder layer (%d/%d)\n",
-                       st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
-                       codec->sample_aspect_ratio.num,
-                       codec->sample_aspect_ratio.den);
-                ret = AVERROR(EINVAL);
-                goto fail;
+                if (st->sample_aspect_ratio.num != 0 &&
+                    st->sample_aspect_ratio.den != 0 &&
+                    codec->sample_aspect_ratio.den != 0 &&
+                    codec->sample_aspect_ratio.den != 0) {
+                    av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
+                            "(%d/%d) and encoder layer (%d/%d)\n",
+                            st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
+                            codec->sample_aspect_ratio.num,
+                            codec->sample_aspect_ratio.den);
+                    ret = AVERROR(EINVAL);
+                    goto fail;
+                }
             }
             break;
         }
@@ -305,7 +309,7 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
             return ret;
     }
 
-    if ((ret = init_pts(s) < 0))
+    if ((ret = init_pts(s)) < 0)
         return ret;
 
     return 0;
@@ -391,6 +395,40 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
     return 0;
 }
 
+/*
+ * FIXME: this function should NEVER get undefined pts/dts beside when the
+ * AVFMT_NOTIMESTAMPS is set.
+ * Those additional safety checks should be dropped once the correct checks
+ * are set in the callers.
+ */
+
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    int ret;
+    if (!(s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS))) {
+        AVRational time_base = s->streams[pkt->stream_index]->time_base;
+        int64_t offset = 0;
+
+        if (!s->offset && pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) {
+            s->offset = -pkt->dts;
+            s->offset_timebase = time_base;
+        }
+        if (s->offset)
+            offset = av_rescale_q(s->offset, s->offset_timebase, time_base);
+
+        if (pkt->dts != AV_NOPTS_VALUE)
+            pkt->dts += offset;
+        if (pkt->pts != AV_NOPTS_VALUE)
+            pkt->pts += offset;
+    }
+    ret = s->oformat->write_packet(s, pkt);
+
+    if (s->pb && ret >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
+        avio_flush(s->pb);
+
+    return ret;
+}
+
 int av_write_frame(AVFormatContext *s, AVPacket *pkt)
 {
     int ret;
@@ -406,7 +444,7 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt)
     if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
         return ret;
 
-    ret = s->oformat->write_packet(s, pkt);
+    ret = write_packet(s, pkt);
 
     if (ret >= 0)
         s->streams[pkt->stream_index]->nb_frames++;
@@ -420,7 +458,12 @@ void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
 
     this_pktl      = av_mallocz(sizeof(AVPacketList));
     this_pktl->pkt = *pkt;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
     pkt->destruct  = NULL;           // do not free original but only the copy
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+    pkt->buf       = NULL;
     av_dup_packet(&this_pktl->pkt);  // duplicate the packet if it uses non-alloced memory
 
     if (s->streams[pkt->stream_index]->last_in_packet_buffer) {
@@ -448,7 +491,8 @@ next_non_null:
         *next_point                                      = this_pktl;
 }
 
-static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
+static int interleave_compare_dts(AVFormatContext *s, AVPacket *next,
+                                  AVPacket *pkt)
 {
     AVStream *st  = s->streams[pkt->stream_index];
     AVStream *st2 = s->streams[next->stream_index];
@@ -468,7 +512,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
     int i;
 
     if (pkt) {
-        ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+        ff_interleave_add_packet(s, pkt, interleave_compare_dts);
     }
 
     for (i = 0; i < s->nb_streams; i++)
@@ -492,15 +536,6 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
     }
 }
 
-#if FF_API_INTERLEAVE_PACKET
-int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
-                                 AVPacket *pkt, int flush)
-{
-    return ff_interleave_packet_per_dts(s, out, pkt, flush);
-}
-
-#endif
-
 /**
  * Interleave an AVPacket correctly so it can be muxed.
  * @param out the interleaved packet will be output here
@@ -550,7 +585,7 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
         if (ret <= 0) //FIXME cleanup needed for ret<0 ?
             return ret;
 
-        ret = s->oformat->write_packet(s, &opkt);
+        ret = write_packet(s, &opkt);
         if (ret >= 0)
             s->streams[opkt.stream_index]->nb_frames++;
 
@@ -574,7 +609,7 @@ int av_write_trailer(AVFormatContext *s)
         if (!ret)
             break;
 
-        ret = s->oformat->write_packet(s, &pkt);
+        ret = write_packet(s, &pkt);
         if (ret >= 0)
             s->streams[pkt.stream_index]->nb_frames++;
 
@@ -600,3 +635,21 @@ fail:
     av_freep(&s->priv_data);
     return ret;
 }
+
+int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
+                     AVFormatContext *src)
+{
+    AVPacket local_pkt;
+
+    local_pkt = *pkt;
+    local_pkt.stream_index = dst_stream;
+    if (pkt->pts != AV_NOPTS_VALUE)
+        local_pkt.pts = av_rescale_q(pkt->pts,
+                                     src->streams[pkt->stream_index]->time_base,
+                                     dst->streams[dst_stream]->time_base);
+    if (pkt->dts != AV_NOPTS_VALUE)
+        local_pkt.dts = av_rescale_q(pkt->dts,
+                                     src->streams[pkt->stream_index]->time_base,
+                                     dst->streams[dst_stream]->time_base);
+    return av_write_frame(dst, &local_pkt);
+}
diff --git a/libavformat/mvi.c b/libavformat/mvi.c
index 65096f1..69b0aed 100644
--- a/libavformat/mvi.c
+++ b/libavformat/mvi.c
@@ -87,6 +87,7 @@ static int read_header(AVFormatContext *s)
     ast->codec->bit_rate        = ast->codec->sample_rate * 8;
 
     avpriv_set_pts_info(vst, 64, msecs_per_frame, 1000000);
+    vst->avg_frame_rate    = av_inv_q(vst->time_base);
     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     vst->codec->codec_id   = AV_CODEC_ID_MOTIONPIXELS;
 
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index d380b36..0dd3f75 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -43,7 +43,7 @@
  * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
  */
 
-//#define DEBUG
+#include <stdint.h>
 
 #include "libavutil/aes.h"
 #include "libavutil/mathematics.h"
@@ -396,8 +396,7 @@ static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, U
     int item_len = avio_rb32(pb);
 
     if (item_len != 18) {
-        av_log_ask_for_sample(pb, "unsupported primer pack item length %d\n",
-                              item_len);
+        avpriv_request_sample(pb, "Primer pack item length %d", item_len);
         return AVERROR_PATCHWELCOME;
     }
     if (item_num > UINT_MAX / item_len)
@@ -413,18 +412,20 @@ static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, U
 static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
 {
     MXFContext *mxf = arg;
-    MXFPartition *partition, *tmp_part;
+    MXFPartition *partition;
     UID op;
     uint64_t footer_partition;
     uint32_t nb_essence_containers;
+    int err;
 
     if (mxf->partitions_count+1 >= UINT_MAX / sizeof(*mxf->partitions))
         return AVERROR(ENOMEM);
 
-    tmp_part = av_realloc(mxf->partitions, (mxf->partitions_count + 1) * sizeof(*mxf->partitions));
-    if (!tmp_part)
-        return AVERROR(ENOMEM);
-    mxf->partitions = tmp_part;
+    if ((err = av_reallocp_array(&mxf->partitions, mxf->partitions_count + 1,
+                                 sizeof(*mxf->partitions))) < 0) {
+        mxf->partitions_count = 0;
+        return err;
+    }
 
     if (mxf->parsing_backward) {
         /* insert the new partition pack in the middle
@@ -549,13 +550,15 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size
 
 static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
 {
-    MXFMetadataSet **tmp;
+    int err;
+
     if (mxf->metadata_sets_count+1 >= UINT_MAX / sizeof(*mxf->metadata_sets))
         return AVERROR(ENOMEM);
-    tmp = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets));
-    if (!tmp)
-        return AVERROR(ENOMEM);
-    mxf->metadata_sets = tmp;
+    if ((err = av_reallocp_array(&mxf->metadata_sets, mxf->metadata_sets_count + 1,
+                                 sizeof(*mxf->metadata_sets))) < 0) {
+        mxf->metadata_sets_count = 0;
+        return err;
+    }
     mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
     mxf->metadata_sets_count++;
     return 0;
@@ -927,6 +930,7 @@ static const MXFCodecUL mxf_intra_only_essence_container_uls[] = {
 /* intra-only PictureEssenceCoding ULs, where no corresponding EC UL exists */
 static const MXFCodecUL mxf_intra_only_picture_essence_coding_uls[] = {
     { { 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 Profiles */
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,   AV_CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */
     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       AV_CODEC_ID_NONE },
 };
 
@@ -1464,10 +1468,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
         /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
         codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);
         st->codec->codec_id = codec_ul->id;
-        if (descriptor->extradata) {
-            st->codec->extradata = descriptor->extradata;
-            st->codec->extradata_size = descriptor->extradata_size;
-        }
+
         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
             source_track->intra_only = mxf_is_intra_only(descriptor);
             container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
@@ -1553,6 +1554,17 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
                 st->need_parsing = AVSTREAM_PARSE_FULL;
             }
         }
+        if (descriptor->extradata) {
+            st->codec->extradata = av_mallocz(descriptor->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (st->codec->extradata) {
+                memcpy(st->codec->extradata, descriptor->extradata, descriptor->extradata_size);
+                st->codec->extradata_size = descriptor->extradata_size;
+            }
+        } else if (st->codec->codec_id == AV_CODEC_ID_H264) {
+            ret = ff_generate_avci_extradata(st);
+            if (ret < 0)
+                return ret;
+        }
         if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
             /* TODO: decode timestamps */
             st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
@@ -2035,10 +2047,10 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
                 /* 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",
+                avpriv_request_sample(s,
+                                      "OPAtom misinterpreted as OP1a?"
+                                      "KLV for edit unit %i extending into "
+                                      "next edit unit",
                                       mxf->current_edit_unit);
                 klv.length = next_ofs - avio_tell(s->pb);
             }
@@ -2228,6 +2240,7 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
     if ((ret = avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET)) < 0)
         return ret;
     ff_update_cur_dts(s, st, sample_time);
+    mxf->current_edit_unit = sample_time;
     } else {
         t = &mxf->index_tables[0];
 
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 995e411..4fd5687 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -30,8 +30,7 @@
  * SMPTE RP224: Registry of SMPTE Universal Labels
  */
 
-//#define DEBUG
-
+#include <inttypes.h>
 #include <math.h>
 #include <time.h>
 
@@ -1183,7 +1182,7 @@ static void mxf_write_klv_fill(AVFormatContext *s)
     }
 }
 
-static void mxf_write_partition(AVFormatContext *s, int bodysid,
+static int mxf_write_partition(AVFormatContext *s, int bodysid,
                                 int indexsid,
                                 const uint8_t *key, int write_metadata)
 {
@@ -1192,6 +1191,7 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid,
     int64_t header_byte_count_offset;
     unsigned index_byte_count = 0;
     uint64_t partition_offset = avio_tell(pb);
+    int err;
 
     if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
         index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
@@ -1206,10 +1206,11 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid,
     }
 
     if (!memcmp(key, body_partition_key, 16)) {
-        mxf->body_partition_offset =
-            av_realloc(mxf->body_partition_offset,
-                       (mxf->body_partitions_count+1)*
-                       sizeof(*mxf->body_partition_offset));
+        if ((err = av_reallocp_array(&mxf->body_partition_offset, mxf->body_partitions_count + 1,
+                                     sizeof(*mxf->body_partition_offset))) < 0) {
+            mxf->body_partitions_count = 0;
+            return err;
+        }
         mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset;
     }
 
@@ -1274,6 +1275,8 @@ static void mxf_write_partition(AVFormatContext *s, int bodysid,
     }
 
     avio_flush(pb);
+
+    return 0;
 }
 
 static const UID mxf_mpeg2_codec_uls[] = {
@@ -1545,7 +1548,7 @@ static int mxf_write_header(AVFormatContext *s)
 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)
+static uint32_t framenum_to_12m_time_code(unsigned frame, int drop, int fps)
 {
     return (0                                    << 31) | // color frame flag
            (drop                                 << 30) | // drop  frame flag
@@ -1591,7 +1594,8 @@ static void mxf_write_system_item(AVFormatContext *s)
     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 = framenum_to_12m_time_code(frame, mxf->timecode_drop_frame,
+                                          mxf->timecode_base);
     avio_wb32(pb, time_code);
     avio_wb32(pb, 0); // binary group data
     avio_wb64(pb, 0);
@@ -1673,13 +1677,14 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
     AVStream *st = s->streams[pkt->stream_index];
     MXFStreamContext *sc = st->priv_data;
     MXFIndexEntry ie = {0};
+    int err;
 
     if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) {
-        mxf->index_entries = av_realloc(mxf->index_entries,
-            (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries));
-        if (!mxf->index_entries) {
+        if ((err = av_reallocp_array(&mxf->index_entries, mxf->edit_units_count
+                                     + EDIT_UNITS_PER_BODY, sizeof(*mxf->index_entries))) < 0) {
+            mxf->edit_units_count = 0;
             av_log(s, AV_LOG_ERROR, "could not allocate index entries\n");
-            return -1;
+            return err;
         }
     }
 
@@ -1692,11 +1697,13 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     if (!mxf->header_written) {
         if (mxf->edit_unit_byte_count) {
-            mxf_write_partition(s, 1, 2, header_open_partition_key, 1);
+            if ((err = mxf_write_partition(s, 1, 2, header_open_partition_key, 1)) < 0)
+                return err;
             mxf_write_klv_fill(s);
             mxf_write_index_table_segment(s);
         } else {
-            mxf_write_partition(s, 0, 0, header_open_partition_key, 1);
+            if ((err = mxf_write_partition(s, 0, 0, header_open_partition_key, 1)) < 0)
+                return err;
         }
         mxf->header_written = 1;
     }
@@ -1706,8 +1713,8 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
             (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) &&
             !(ie.flags & 0x33)) { // I frame, Gop start
             mxf_write_klv_fill(s);
-            mxf_write_partition(s, 1, 2, body_partition_key, 0);
-
+            if ((err = mxf_write_partition(s, 1, 2, body_partition_key, 0)) < 0)
+                return err;
             mxf_write_klv_fill(s);
             mxf_write_index_table_segment(s);
         }
@@ -1776,16 +1783,18 @@ static int mxf_write_footer(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
     AVIOContext *pb = s->pb;
+    int err;
 
     mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;
 
     mxf_write_klv_fill(s);
     mxf->footer_partition_offset = avio_tell(pb);
     if (mxf->edit_unit_byte_count) { // no need to repeat index
-        mxf_write_partition(s, 0, 0, footer_partition_key, 0);
+        if ((err = mxf_write_partition(s, 0, 0, footer_partition_key, 0)) < 0)
+            return err;
     } else {
-        mxf_write_partition(s, 0, 2, footer_partition_key, 0);
-
+        if ((err = mxf_write_partition(s, 0, 2, footer_partition_key, 0)) < 0)
+            return err;
         mxf_write_klv_fill(s);
         mxf_write_index_table_segment(s);
     }
@@ -1796,11 +1805,13 @@ static int mxf_write_footer(AVFormatContext *s)
     if (s->pb->seekable) {
         avio_seek(pb, 0, SEEK_SET);
         if (mxf->edit_unit_byte_count) {
-            mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
+            if ((err = mxf_write_partition(s, 1, 2, header_closed_partition_key, 1)) < 0)
+                return err;
             mxf_write_klv_fill(s);
             mxf_write_index_table_segment(s);
         } else {
-            mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
+            if ((err = mxf_write_partition(s, 0, 0, header_closed_partition_key, 1)) < 0)
+                return err;
         }
     }
 
@@ -1856,7 +1867,7 @@ static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket
         }
 
         *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 8959134..1d1488c 100644
--- a/libavformat/mxg.c
+++ b/libavformat/mxg.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/mjpeg.h"
 #include "avformat.h"
@@ -168,7 +169,12 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
 
                 pkt->pts = pkt->dts = mxg->dts;
                 pkt->stream_index = 0;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
                 pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+                pkt->buf  = NULL;
                 pkt->size = mxg->buffer_ptr - mxg->soi_ptr;
                 pkt->data = mxg->soi_ptr;
 
@@ -206,7 +212,12 @@ static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
                     /* time (GMT) of first sample in usec since 1970, little-endian */
                     pkt->pts = pkt->dts = AV_RL64(startmarker_ptr + 8);
                     pkt->stream_index = 1;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
                     pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+                    pkt->buf  = NULL;
                     pkt->size = size - 14;
                     pkt->data = startmarker_ptr + 16;
 
diff --git a/libavformat/network.c b/libavformat/network.c
index 1f6bc10..6d308eb 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -18,7 +18,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <fcntl.h>
 #include "network.h"
+#include "url.h"
 #include "libavcodec/internal.h"
 #include "libavutil/mem.h"
 
@@ -26,7 +28,7 @@
 #if HAVE_PTHREADS
 #include <pthread.h>
 #else
-#include "libavcodec/w32pthreads.h"
+#include "compat/w32pthreads.h"
 #endif
 #endif
 
@@ -187,3 +189,169 @@ int ff_is_multicast_address(struct sockaddr *addr)
 
     return 0;
 }
+
+static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout,
+                             AVIOInterruptCB *cb)
+{
+    int runs = timeout / POLLING_TIME;
+    int ret = 0;
+
+    do {
+        if (ff_check_interrupt(cb))
+            return AVERROR_EXIT;
+        ret = poll(p, nfds, POLLING_TIME);
+        if (ret != 0)
+            break;
+    } while (timeout < 0 || runs-- > 0);
+
+    if (!ret)
+        return AVERROR(ETIMEDOUT);
+    if (ret < 0)
+        return AVERROR(errno);
+    return ret;
+}
+
+int ff_socket(int af, int type, int proto)
+{
+    int fd;
+
+#ifdef SOCK_CLOEXEC
+    fd = socket(af, type | SOCK_CLOEXEC, proto);
+    if (fd == -1 && errno == EINVAL)
+#endif
+    {
+        fd = socket(af, type, proto);
+#if HAVE_FCNTL
+        if (fd != -1)
+            fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+    }
+    return fd;
+}
+
+int ff_listen_bind(int fd, const struct sockaddr *addr,
+                   socklen_t addrlen, int timeout, URLContext *h)
+{
+    int ret;
+    int reuse = 1;
+    struct pollfd lp = { fd, POLLIN, 0 };
+    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
+    ret = bind(fd, addr, addrlen);
+    if (ret)
+        return ff_neterrno();
+
+    ret = listen(fd, 1);
+    if (ret)
+        return ff_neterrno();
+
+    ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback);
+    if (ret < 0)
+        return ret;
+
+    ret = accept(fd, NULL, NULL);
+    if (ret < 0)
+        return ff_neterrno();
+
+    closesocket(fd);
+
+    ff_socket_nonblock(ret, 1);
+    return ret;
+}
+
+int ff_listen_connect(int fd, const struct sockaddr *addr,
+                      socklen_t addrlen, int timeout, URLContext *h,
+                      int will_try_next)
+{
+    struct pollfd p = {fd, POLLOUT, 0};
+    int ret;
+    socklen_t optlen;
+
+    ff_socket_nonblock(fd, 1);
+
+    while ((ret = connect(fd, addr, addrlen))) {
+        ret = ff_neterrno();
+        switch (ret) {
+        case AVERROR(EINTR):
+            if (ff_check_interrupt(&h->interrupt_callback))
+                return AVERROR_EXIT;
+            continue;
+        case AVERROR(EINPROGRESS):
+        case AVERROR(EAGAIN):
+            ret = ff_poll_interrupt(&p, 1, timeout, &h->interrupt_callback);
+            if (ret < 0)
+                return ret;
+            optlen = sizeof(ret);
+            if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
+                ret = AVUNERROR(ff_neterrno());
+            if (ret != 0) {
+                char errbuf[100];
+                ret = AVERROR(ret);
+                av_strerror(ret, errbuf, sizeof(errbuf));
+                if (will_try_next)
+                    av_log(h, AV_LOG_WARNING,
+                           "Connection to %s failed (%s), trying next address\n",
+                           h->filename, errbuf);
+                else
+                    av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
+                           h->filename, errbuf);
+            }
+        default:
+            return ret;
+        }
+    }
+    return ret;
+}
+
+static int match_host_pattern(const char *pattern, const char *hostname)
+{
+    int len_p, len_h;
+    if (!strcmp(pattern, "*"))
+        return 1;
+    // Skip a possible *. at the start of the pattern
+    if (pattern[0] == '*')
+        pattern++;
+    if (pattern[0] == '.')
+        pattern++;
+    len_p = strlen(pattern);
+    len_h = strlen(hostname);
+    if (len_p > len_h)
+        return 0;
+    // Simply check if the end of hostname is equal to 'pattern'
+    if (!strcmp(pattern, &hostname[len_h - len_p])) {
+        if (len_h == len_p)
+            return 1; // Exact match
+        if (hostname[len_h - len_p - 1] == '.')
+            return 1; // The matched substring is a domain and not just a substring of a domain
+    }
+    return 0;
+}
+
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
+{
+    char *buf, *start;
+    int ret = 0;
+    if (!no_proxy)
+        return 0;
+    if (!hostname)
+        return 0;
+    buf = av_strdup(no_proxy);
+    if (!buf)
+        return 0;
+    start = buf;
+    while (start) {
+        char *sep, *next = NULL;
+        start += strspn(start, " ,");
+        sep = start + strcspn(start, " ,");
+        if (*sep) {
+            next = sep + 1;
+            *sep = '\0';
+        }
+        if (match_host_pattern(start, hostname)) {
+            ret = 1;
+            break;
+        }
+        start = next;
+    }
+    av_free(buf);
+    return ret;
+}
diff --git a/libavformat/network.h b/libavformat/network.h
index 5160767..1d3fb7b 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "libavutil/error.h"
 #include "os_support.h"
+#include "url.h"
 
 #if HAVE_UNISTD_H
 #include <unistd.h>
@@ -209,4 +210,45 @@ const char *ff_gai_strerror(int ecode);
 
 int ff_is_multicast_address(struct sockaddr *addr);
 
+#define POLLING_TIME 100 /// Time in milliseconds between interrupt check
+
+/**
+ * Bind to a file descriptor and poll for a connection.
+ *
+ * @param fd      First argument of bind().
+ * @param addr    Second argument of bind().
+ * @param addrlen Third argument of bind().
+ * @param timeout Polling timeout in milliseconds.
+ * @param h       URLContext providing interrupt check
+ *                callback and logging context.
+ * @return        A non-blocking file descriptor on success
+ *                or an AVERROR on failure.
+ */
+int ff_listen_bind(int fd, const struct sockaddr *addr,
+                   socklen_t addrlen, int timeout,
+                   URLContext *h);
+
+/**
+ * Connect to a file descriptor and poll for result.
+ *
+ * @param fd       First argument of connect(),
+ *                 will be set as non-blocking.
+ * @param addr     Second argument of connect().
+ * @param addrlen  Third argument of connect().
+ * @param timeout  Polling timeout in milliseconds.
+ * @param h        URLContext providing interrupt check
+ *                 callback and logging context.
+ * @param will_try_next Whether the caller will try to connect to another
+ *                 address for the same host name, affecting the form of
+ *                 logged errors.
+ * @return         0 on success, AVERROR on failure.
+ */
+int ff_listen_connect(int fd, const struct sockaddr *addr,
+                      socklen_t addrlen, int timeout,
+                      URLContext *h, int will_try_next);
+
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname);
+
+int ff_socket(int domain, int type, int protocol);
+
 #endif /* AVFORMAT_NETWORK_H */
diff --git a/libavformat/noproxy-test.c b/libavformat/noproxy-test.c
new file mode 100644
index 0000000..e6cc421
--- /dev/null
+++ b/libavformat/noproxy-test.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013 Martin Storsjo
+ *
+ * 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 "network.h"
+
+static void test(const char *pattern, const char *host)
+{
+    int res = ff_http_match_no_proxy(pattern, host);
+    printf("The pattern \"%s\" %s the hostname %s\n",
+           pattern ? pattern : "(null)", res ? "matches" : "does not match",
+           host);
+}
+
+int main(void)
+{
+    test(NULL, "domain.com");
+    test("example.com domain.com", "domain.com");
+    test("example.com other.com", "domain.com");
+    test("example.com,domain.com", "domain.com");
+    test("example.com,domain.com", "otherdomain.com");
+    test("example.com, *.domain.com", "sub.domain.com");
+    test("example.com, *.domain.com", "domain.com");
+    test("example.com, .domain.com", "domain.com");
+    test("*", "domain.com");
+    return 0;
+}
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index 4193ed2..18ebbe3 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -2,6 +2,8 @@
  * NSV demuxer
  * Copyright (c) 2004 The Libav Project
  *
+ * first version by Francois Revol <revol at free.fr>
+ *
  * This file is part of Libav.
  *
  * Libav is free software; you can redistribute it and/or
@@ -25,10 +27,6 @@
 #include "internal.h"
 #include "libavutil/dict.h"
 
-//#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!!
-#define CHECK_SUBSEQUENT_NSVS
-//#define DISABLE_AUDIO
-
 /* max bytes to crawl for trying to resync
  * stupid streaming servers don't start at chunk boundaries...
  */
@@ -36,7 +34,6 @@
 #define NSV_MAX_RESYNC_TRIES 300
 
 /*
- * First version by Francois Revol - revol at free.fr
  * References:
  * (1) http://www.multimedia.cx/nsv-format.txt
  * seems someone came to the same conclusions as me, and updated it:
@@ -370,25 +367,6 @@ static int nsv_parse_NSVf_header(AVFormatContext *s)
 
     av_dlog(s, "NSV got index; filepos %"PRId64"\n", avio_tell(pb));
 
-#ifdef DEBUG_DUMP_INDEX
-#define V(v) ((v<0x20 || v > 127)?'.':v)
-    /* dump index */
-    av_dlog(s, "NSV %d INDEX ENTRIES:\n", table_entries);
-    av_dlog(s, "NSV [dataoffset][fileoffset]\n", table_entries);
-    for (i = 0; i < table_entries; i++) {
-        unsigned char b[8];
-        avio_seek(pb, size + nsv->nsvs_file_offset[i], SEEK_SET);
-        avio_read(pb, b, 8);
-        av_dlog(s, "NSV [0x%08lx][0x%08lx]: %02x %02x %02x %02x %02x %02x %02x %02x"
-           "%c%c%c%c%c%c%c%c\n",
-           nsv->nsvs_file_offset[i], size + nsv->nsvs_file_offset[i],
-           b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
-           V(b[0]), V(b[1]), V(b[2]), V(b[3]), V(b[4]), V(b[5]), V(b[6]), V(b[7]) );
-    }
-    //avio_seek(pb, size, SEEK_SET); /* go back to end of header */
-#undef V
-#endif
-
     avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */
 
     if (pb->eof_reached)
@@ -479,7 +457,6 @@ static int nsv_parse_NSVs_header(AVFormatContext *s)
             }
         }
         if (atag != T_NONE) {
-#ifndef DISABLE_AUDIO
             st = avformat_new_stream(s, NULL);
             if (!st)
                 goto fail;
@@ -499,15 +476,12 @@ static int nsv_parse_NSVs_header(AVFormatContext *s)
             avpriv_set_pts_info(st, 64, 1, framerate.num*1000);
             st->start_time = 0;
             st->duration = (int64_t)nsv->duration * framerate.num;
-#endif
         }
-#ifdef CHECK_SUBSEQUENT_NSVS
     } else {
         if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) {
             av_dlog(s, "NSV NSVs header values differ from the first one!!!\n");
             //return -1;
         }
-#endif /* CHECK_SUBSEQUENT_NSVS */
     }
 
     nsv->state = NSV_HAS_READ_NSVS;
@@ -790,7 +764,7 @@ static int nsv_probe(AVProbeData *p)
     }
     /* so we'll have more luck on extension... */
     if (av_match_ext(p->filename, "nsv"))
-        return AVPROBE_SCORE_MAX/2;
+        return AVPROBE_SCORE_EXTENSION;
     /* FIXME: add mime-type check */
     return score;
 }
diff --git a/libavformat/nut.c b/libavformat/nut.c
index 196e04e..d9a042b 100644
--- a/libavformat/nut.c
+++ b/libavformat/nut.c
@@ -26,127 +26,130 @@
 #include "internal.h"
 
 const AVCodecTag ff_nut_subtitle_tags[] = {
-    { AV_CODEC_ID_TEXT        , MKTAG('U', 'T', 'F', '8') },
-    { AV_CODEC_ID_SSA         , MKTAG('S', 'S', 'A',  0 ) },
-    { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('D', 'V', 'D', 'S') },
-    { AV_CODEC_ID_DVB_SUBTITLE, MKTAG('D', 'V', 'B', 'S') },
-    { AV_CODEC_ID_NONE        , 0                         }
+    { AV_CODEC_ID_TEXT,             MKTAG('U', 'T', 'F', '8') },
+    { AV_CODEC_ID_SSA,              MKTAG('S', 'S', 'A',   0) },
+    { AV_CODEC_ID_DVD_SUBTITLE,     MKTAG('D', 'V', 'D', 'S') },
+    { AV_CODEC_ID_DVB_SUBTITLE,     MKTAG('D', 'V', 'B', 'S') },
+    { AV_CODEC_ID_NONE,             0                         }
 };
 
 const AVCodecTag ff_nut_data_tags[] = {
-    { AV_CODEC_ID_TEXT        , MKTAG('U', 'T', 'F', '8') },
-    { AV_CODEC_ID_NONE        , 0                         }
+    { AV_CODEC_ID_TEXT,             MKTAG('U', 'T', 'F', '8') },
+    { AV_CODEC_ID_NONE,             0 }
 };
 
 const AVCodecTag ff_nut_video_tags[] = {
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 15 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 15 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 12 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 12 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 24 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 24 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '1', '1', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '1', 'W', '0') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '0', 'W', '1') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R',  8 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B',  8 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R',  4 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B',  4 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '4', 'B', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', 'B', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 48 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 48 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'B', 'G', 'R') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'R', 'G', 'B') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('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', '1',  0 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '1', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '3', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 ,  8 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '2',  0 ,  8 ) },
-
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1',  0 ,  9 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 ,  0 , '1', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 ,  9 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 11 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 ,  9 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 10 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4',  0 ,  9 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 ,  0 , '4', 'Y') },
-
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1',  0 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 ,  0 , '1', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4',  0 , 10 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(10 ,  0 , '4', 'Y') },
-
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1',  0 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '1', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '4', 'Y') },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4',  0 , 16 ) },
-    { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '4', 'Y') },
-
-    { AV_CODEC_ID_NONE    , 0                         }
+    { AV_CODEC_ID_VP9,              MKTAG('V', 'P', '9', '0') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',  15) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',  15) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(15,  'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(15,  'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,  'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,  'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',  12) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',  12) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(12,  'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(12,  'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B', 'A') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R', 'A') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('A', 'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('A', 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',  24) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',  24) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '1', '1', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '2', '2', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '2', '2', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '4', '0', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '4', '0', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '4', '4', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('4', '4', '4', 'P') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', '1', 'W', '0') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', '0', 'W', '1') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',   8) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',   8) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',   4) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',   4) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', '4', 'B', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', '4', 'B', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('B', 'G', 'R',  48) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('R', 'G', 'B',  48) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(48,  'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(48,  'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('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', '1',   0,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,    0, '1', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3',  11,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,   11, '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3',  10,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,   10, '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '3',   0,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,    0, '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  11,   8) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '2',   0,   8) },
+
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '1',   0,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(9,     0, '1', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  11,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(9,    11, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  10,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(9,    10, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',   0,   9) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(9,     0, '4', 'Y') },
+
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '1',   0,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,    0, '1', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  11,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,   11, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  10,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,   10, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',   0,  10) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(10,    0, '4', 'Y') },
+
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '1',   0,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,    0, '1', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  11,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,   11, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',  10,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,   10, '4', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG('Y', '4',   0,  16) },
+    { AV_CODEC_ID_RAWVIDEO,         MKTAG(16,    0, '4', 'Y') },
+
+    { AV_CODEC_ID_NONE,             0 }
 };
 
 const AVCodecTag ff_nut_audio_tags[] = {
     { AV_CODEC_ID_PCM_ALAW,         MKTAG('A', 'L', 'A', 'W') },
     { AV_CODEC_ID_PCM_MULAW,        MKTAG('U', 'L', 'A', 'W') },
-    { AV_CODEC_ID_PCM_F32BE,        MKTAG(32 , 'D', 'F', 'P') },
-    { AV_CODEC_ID_PCM_F32LE,        MKTAG('P', 'F', 'D', 32 ) },
-    { AV_CODEC_ID_PCM_F64BE,        MKTAG(64 , 'D', 'F', 'P') },
-    { AV_CODEC_ID_PCM_F64LE,        MKTAG('P', 'F', 'D', 64 ) },
-    { AV_CODEC_ID_PCM_S16BE,        MKTAG(16 , 'D', 'S', 'P') },
-    { AV_CODEC_ID_PCM_S16LE,        MKTAG('P', 'S', 'D', 16 ) },
-    { AV_CODEC_ID_PCM_S24BE,        MKTAG(24 , 'D', 'S', 'P') },
-    { AV_CODEC_ID_PCM_S24LE,        MKTAG('P', 'S', 'D', 24 ) },
-    { AV_CODEC_ID_PCM_S32BE,        MKTAG(32 , 'D', 'S', 'P') },
-    { AV_CODEC_ID_PCM_S32LE,        MKTAG('P', 'S', 'D', 32 ) },
-    { AV_CODEC_ID_PCM_S8,           MKTAG('P', 'S', 'D',  8 ) },
-    { AV_CODEC_ID_PCM_U16BE,        MKTAG(16 , 'D', 'U', 'P') },
-    { AV_CODEC_ID_PCM_U16LE,        MKTAG('P', 'U', 'D', 16 ) },
-    { AV_CODEC_ID_PCM_U24BE,        MKTAG(24 , 'D', 'U', 'P') },
-    { AV_CODEC_ID_PCM_U24LE,        MKTAG('P', 'U', 'D', 24 ) },
-    { AV_CODEC_ID_PCM_U32BE,        MKTAG(32 , 'D', 'U', 'P') },
-    { AV_CODEC_ID_PCM_U32LE,        MKTAG('P', 'U', 'D', 32 ) },
-    { AV_CODEC_ID_PCM_U8,           MKTAG('P', 'U', 'D',  8 ) },
-    { AV_CODEC_ID_PCM_S16LE_PLANAR, MKTAG('P', 'S', 'P', 16 ) },
+    { AV_CODEC_ID_PCM_F32BE,        MKTAG(32,  'D', 'F', 'P') },
+    { AV_CODEC_ID_PCM_F32LE,        MKTAG('P', 'F', 'D',  32) },
+    { AV_CODEC_ID_PCM_F64BE,        MKTAG(64,  'D', 'F', 'P') },
+    { AV_CODEC_ID_PCM_F64LE,        MKTAG('P', 'F', 'D',  64) },
+    { AV_CODEC_ID_PCM_S16BE,        MKTAG(16,  'D', 'S', 'P') },
+    { AV_CODEC_ID_PCM_S16LE,        MKTAG('P', 'S', 'D',  16) },
+    { AV_CODEC_ID_PCM_S24BE,        MKTAG(24,  'D', 'S', 'P') },
+    { AV_CODEC_ID_PCM_S24LE,        MKTAG('P', 'S', 'D',  24) },
+    { AV_CODEC_ID_PCM_S32BE,        MKTAG(32,  'D', 'S', 'P') },
+    { AV_CODEC_ID_PCM_S32LE,        MKTAG('P', 'S', 'D',  32) },
+    { AV_CODEC_ID_PCM_S8,           MKTAG('P', 'S', 'D',   8) },
+    { AV_CODEC_ID_PCM_U16BE,        MKTAG(16,  'D', 'U', 'P') },
+    { AV_CODEC_ID_PCM_U16LE,        MKTAG('P', 'U', 'D',  16) },
+    { AV_CODEC_ID_PCM_U24BE,        MKTAG(24,  'D', 'U', 'P') },
+    { AV_CODEC_ID_PCM_U24LE,        MKTAG('P', 'U', 'D',  24) },
+    { AV_CODEC_ID_PCM_U32BE,        MKTAG(32,  'D', 'U', 'P') },
+    { AV_CODEC_ID_PCM_U32LE,        MKTAG('P', 'U', 'D',  32) },
+    { AV_CODEC_ID_PCM_U8,           MKTAG('P', 'U', 'D',   8) },
+    { AV_CODEC_ID_PCM_S16LE_PLANAR, MKTAG('P', 'S', 'P',  16) },
+    { AV_CODEC_ID_PCM_S24LE_PLANAR, MKTAG('P', 'S', 'P',  24) },
+    { AV_CODEC_ID_PCM_S32LE_PLANAR, MKTAG('P', 'S', 'P',  32) },
     { AV_CODEC_ID_MP3,              MKTAG('M', 'P', '3', ' ') },
-    { AV_CODEC_ID_NONE,             0                         }
+    { AV_CODEC_ID_NONE,             0 }
 };
 
 const AVCodecTag * const ff_nut_codec_tags[] = {
@@ -154,43 +157,55 @@ const AVCodecTag * const ff_nut_codec_tags[] = {
     ff_codec_bmp_tags, ff_codec_wav_tags, ff_nut_data_tags, 0
 };
 
-void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val){
+void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val)
+{
     int i;
-    for(i=0; i<nut->avf->nb_streams; i++){
-        nut->stream[i].last_pts= av_rescale_rnd(
-            val,
-            time_base.num * (int64_t)nut->stream[i].time_base->den,
-            time_base.den * (int64_t)nut->stream[i].time_base->num,
-            AV_ROUND_DOWN);
-    }
+    for (i = 0; i < nut->avf->nb_streams; i++)
+        nut->stream[i].last_pts =
+            av_rescale_rnd(val,
+                           time_base.num * (int64_t)nut->stream[i].time_base->den,
+                           time_base.den * (int64_t)nut->stream[i].time_base->num,
+                           AV_ROUND_DOWN);
 }
 
-int64_t ff_lsb2full(StreamContext *stream, int64_t lsb){
-    int64_t mask = (1<<stream->msb_pts_shift)-1;
-    int64_t delta= stream->last_pts - mask/2;
-    return  ((lsb - delta)&mask) + delta;
+int64_t ff_lsb2full(StreamContext *stream, int64_t lsb)
+{
+    int64_t mask  = (1 << stream->msb_pts_shift) - 1;
+    int64_t delta = stream->last_pts - mask / 2;
+    return ((lsb - delta) & mask) + delta;
 }
 
-int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b){
+int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b)
+{
     return ((a->pos - b->pos) >> 32) - ((b->pos - a->pos) >> 32);
 }
 
-int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b){
+int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b)
+{
     return ((a->ts - b->ts) >> 32) - ((b->ts - a->ts) >> 32);
 }
 
-void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts){
-    Syncpoint *sp= av_mallocz(sizeof(Syncpoint));
+int ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts)
+{
+    Syncpoint *sp           = av_mallocz(sizeof(Syncpoint));
     struct AVTreeNode *node = av_tree_node_alloc();
 
-    sp->pos= pos;
-    sp->back_ptr= back_ptr;
-    sp->ts= ts;
+    if (!sp || !node) {
+        av_freep(&sp);
+        av_freep(&node);
+        return AVERROR(ENOMEM);
+    }
+
+    sp->pos      = pos;
+    sp->back_ptr = back_ptr;
+    sp->ts       = ts;
     av_tree_insert(&nut->syncpoints, sp, (void *) ff_nut_sp_pos_cmp, &node);
-    if(node){
+    if (node) {
         av_free(sp);
         av_free(node);
     }
+
+    return 0;
 }
 
 static int enu_free(void *opaque, void *elem)
@@ -206,13 +221,13 @@ void ff_nut_free_sp(NUTContext *nut)
 }
 
 const Dispositions ff_nut_dispositions[] = {
-    {"default"     , AV_DISPOSITION_DEFAULT},
-    {"dub"         , AV_DISPOSITION_DUB},
-    {"original"    , AV_DISPOSITION_ORIGINAL},
-    {"comment"     , AV_DISPOSITION_COMMENT},
-    {"lyrics"      , AV_DISPOSITION_LYRICS},
-    {"karaoke"     , AV_DISPOSITION_KARAOKE},
-    {""            , 0}
+    { "default",        AV_DISPOSITION_DEFAULT  },
+    { "dub",            AV_DISPOSITION_DUB      },
+    { "original",       AV_DISPOSITION_ORIGINAL },
+    { "comment",        AV_DISPOSITION_COMMENT  },
+    { "lyrics",         AV_DISPOSITION_LYRICS   },
+    { "karaoke",        AV_DISPOSITION_KARAOKE  },
+    { "",               0                       }
 };
 
 const AVMetadataConv ff_nut_metadata_conv[] = {
diff --git a/libavformat/nut.h b/libavformat/nut.h
index 89b0248..6357b3d 100644
--- a/libavformat/nut.h
+++ b/libavformat/nut.h
@@ -22,9 +22,6 @@
 #ifndef AVFORMAT_NUT_H
 #define AVFORMAT_NUT_H
 
-//#include <limits.h>
-//#include "libavutil/adler32.h"
-//#include "libavcodec/mpegaudio.h"
 #include "avformat.h"
 #include "internal.h"
 #include "metadata.h"
@@ -39,6 +36,8 @@
 
 #define MAX_DISTANCE (1024*32-1)
 
+#define NUT_VERSION 3
+
 typedef enum{
     FLAG_KEY        =   1, ///<if set, frame is keyframe
     FLAG_EOR        =   2, ///<if set, stream has no relevance on presentation. (EOR)
@@ -119,7 +118,7 @@ void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val);
 int64_t ff_lsb2full(StreamContext *stream, int64_t lsb);
 int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b);
 int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b);
-void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts);
+int ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts);
 void ff_nut_free_sp(NUTContext *nut);
 
 extern const Dispositions ff_nut_dispositions[];
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index b705987..6328549 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -183,7 +183,7 @@ static int nut_probe(AVProbeData *p)
         tmp = ffio_read_varlen(bc);                                           \
         if (!(check)) {                                                       \
             av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp);  \
-            return -1;                                                        \
+            return AVERROR_INVALIDDATA;                                       \
         }                                                                     \
         dst = tmp;                                                            \
     } while (0)
@@ -193,7 +193,7 @@ static int skip_reserved(AVIOContext *bc, int64_t pos)
     pos -= avio_tell(bc);
     if (pos < 0) {
         avio_seek(bc, pos, SEEK_CUR);
-        return -1;
+        return AVERROR_INVALIDDATA;
     } else {
         while (pos--)
             avio_r8(bc);
@@ -213,7 +213,13 @@ static int decode_main_header(NUTContext *nut)
     end  = get_packetheader(nut, bc, 1, MAIN_STARTCODE);
     end += avio_tell(bc);
 
-    GET_V(tmp, tmp >= 2 && tmp <= 3);
+    tmp = ffio_read_varlen(bc);
+    if (tmp < 2 && tmp > NUT_VERSION) {
+        av_log(s, AV_LOG_ERROR, "Version %"PRId64" not supported.\n",
+               tmp);
+        return AVERROR(ENOSYS);
+    }
+
     GET_V(stream_count, tmp > 0 && tmp <= NUT_MAX_STREAMS);
 
     nut->max_distance = ffio_read_varlen(bc);
@@ -376,7 +382,7 @@ static int decode_stream_header(NUTContext *nut)
         break;
     default:
         av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class);
-        return -1;
+        return AVERROR(ENOSYS);
     }
     if (class < 3 && st->codec->codec_id == AV_CODEC_ID_NONE)
         av_log(s, AV_LOG_ERROR,
@@ -405,7 +411,7 @@ static int decode_stream_header(NUTContext *nut)
         if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) {
             av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n",
                    st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         ffio_read_varlen(bc); /* csp type */
     } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -416,7 +422,7 @@ static int decode_stream_header(NUTContext *nut)
     if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
         av_log(s, AV_LOG_ERROR,
                "stream header %d checksum mismatch\n", stream_id);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     stc->time_base = &nut->time_base[stc->time_base_id];
     avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num,
@@ -516,7 +522,7 @@ static int decode_info_header(NUTContext *nut)
 
     if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
         av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     return 0;
 }
@@ -526,6 +532,7 @@ static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr)
     AVFormatContext *s = nut->avf;
     AVIOContext *bc    = s->pb;
     int64_t end, tmp;
+    int ret;
 
     nut->last_syncpoint_pos = avio_tell(bc) - 8;
 
@@ -542,12 +549,14 @@ static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr)
 
     if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
         av_log(s, AV_LOG_ERROR, "sync point checksum mismatch\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     *ts = tmp / s->nb_streams *
           av_q2d(nut->time_base[tmp % s->nb_streams]) * AV_TIME_BASE;
-    ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts);
+
+    if ((ret = ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts)) < 0)
+        return ret;
 
     return 0;
 }
@@ -561,13 +570,13 @@ static int find_and_decode_index(NUTContext *nut)
     int64_t filesize = avio_size(bc);
     int64_t *syncpoints;
     int8_t *has_keyframe;
-    int ret = -1;
+    int ret = AVERROR_INVALIDDATA;
 
     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");
-        return -1;
+        return ret;
     }
 
     end  = get_packetheader(nut, bc, 1, INDEX_STARTCODE);
@@ -843,7 +852,7 @@ static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
         } else {
             frame_code = avio_r8(bc);
             if (bc->eof_reached)
-                return -1;
+                return AVERROR_EOF;
             if (frame_code == 'N') {
                 tmp = frame_code;
                 for (i = 1; i < 8; i++)
@@ -910,7 +919,7 @@ static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index,
     else if (stream_index == -2)
         return back_ptr;
 
-    assert(0);
+    return AV_NOPTS_VALUE;
 }
 
 static int read_seek(AVFormatContext *s, int stream_index,
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index df70f94..2d3862d 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/tree.h"
@@ -93,7 +95,7 @@ static int find_expected_header(AVCodecContext *c, int size, int key_frame,
         header |= (bitrate_index & 1) << 9;
 
         return 2; //FIXME actually put the needed ones in build_elision_headers()
-        return 3; //we guess that the private bit is not set
+        //return 3; //we guess that the private bit is not set
 //FIXME the above assumptions should be checked, if these turn out false too often something should be done
     }
     return 0;
@@ -323,7 +325,7 @@ static void write_mainheader(NUTContext *nut, AVIOContext *bc)
         tmp_head_idx;
     int64_t tmp_match;
 
-    ff_put_v(bc, 3); /* version */
+    ff_put_v(bc, NUT_VERSION);
     ff_put_v(bc, nut->avf->nb_streams);
     ff_put_v(bc, nut->max_distance);
     ff_put_v(bc, nut->time_base_count);
@@ -815,7 +817,8 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt)
         ff_put_v(dyn_bc, sp ? (nut->last_syncpoint_pos - sp->pos) >> 4 : 0);
         put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE);
 
-        ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0 /*unused*/, pkt->dts);
+        if ((ret = ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0 /*unused*/, pkt->dts)) < 0)
+            return ret;
     }
     assert(nus->last_pts != AV_NOPTS_VALUE);
 
diff --git a/libavformat/nuv.c b/libavformat/nuv.c
index 5e9666f..9336912 100644
--- a/libavformat/nuv.c
+++ b/libavformat/nuv.c
@@ -195,9 +195,6 @@ static int nuv_header(AVFormatContext *s)
         vst->codec->bits_per_coded_sample = 10;
         vst->sample_aspect_ratio          = av_d2q(aspect * height / width,
                                                    10000);
-#if FF_API_R_FRAME_RATE
-        vst->r_frame_rate =
-#endif
         vst->avg_frame_rate = av_d2q(fps, 60000);
         avpriv_set_pts_info(vst, 32, 1, 1000);
     } else
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 03ec50e..ae9da3a 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -46,6 +46,7 @@ static const struct ogg_codec * const ogg_codecs[] = {
     &ff_theora_codec,
     &ff_flac_codec,
     &ff_celt_codec,
+    &ff_opus_codec,
     &ff_old_dirac_codec,
     &ff_old_flac_codec,
     &ff_ogm_video_codec,
@@ -84,7 +85,7 @@ static int ogg_restore(AVFormatContext *s, int discard)
     struct ogg *ogg = s->priv_data;
     AVIOContext *bc = s->pb;
     struct ogg_state *ost = ogg->state;
-    int i;
+    int i, err;
 
     if (!ost)
         return 0;
@@ -92,7 +93,6 @@ static int ogg_restore(AVFormatContext *s, int discard)
     ogg->state = ost->next;
 
     if (!discard) {
-        struct ogg_stream *old_streams = ogg->streams;
 
         for (i = 0; i < ogg->nstreams; i++)
             av_free(ogg->streams[i].buf);
@@ -100,16 +100,13 @@ static int ogg_restore(AVFormatContext *s, int discard)
         avio_seek(bc, ost->pos, SEEK_SET);
         ogg->curidx   = ost->curidx;
         ogg->nstreams = ost->nstreams;
-        ogg->streams  = av_realloc(ogg->streams,
-                                   ogg->nstreams * sizeof(*ogg->streams));
-
-        if (ogg->streams) {
+        if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,
+                                     sizeof(*ogg->streams))) < 0) {
+            ogg->nstreams = 0;
+            return err;
+        } else
             memcpy(ogg->streams, ost->streams,
                    ost->nstreams * sizeof(*ogg->streams));
-        } else {
-            av_free(old_streams);
-            ogg->nstreams = 0;
-        }
     }
 
     av_free(ost);
@@ -482,8 +479,11 @@ static int ogg_get_headers(AVFormatContext *s)
         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;
+                   "Headers mismatch for stream %d: "
+                   "expected %d received %d.\n",
+                   i, os->codec->nb_header, os->nb_header);
+            if (s->error_recognition & AV_EF_EXPLODE)
+                return AVERROR_INVALIDDATA;
         }
         if (os->start_granule != OGG_NOGRANULE_VALUE)
             os->lastpts = s->streams[i]->start_time =
@@ -705,5 +705,5 @@ AVInputFormat ff_ogg_demuxer = {
     .read_seek      = ogg_read_seek,
     .read_timestamp = ogg_read_timestamp,
     .extensions     = "ogg",
-    .flags          = AVFMT_GENERIC_INDEX,
+    .flags          = AVFMT_GENERIC_INDEX | AVFMT_NOBINSEARCH,
 };
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index d11ff9f..918378d 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -116,6 +116,7 @@ extern const struct ogg_codec ff_ogm_text_codec;
 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..e96cde7 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavutil/crc.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
@@ -34,6 +36,7 @@
 #define MAX_PAGE_SIZE 65025
 
 typedef struct {
+    int64_t start_granule;
     int64_t granule;
     int stream_index;
     uint8_t flags;
@@ -67,14 +70,17 @@ typedef struct {
     const AVClass *class;
     OGGPageList *page_list;
     int pref_size; ///< preferred page size (0 => fill all segments)
+    int64_t pref_duration;      ///< preferred page duration (0 => fill all segments)
 } OGGContext;
 
 #define OFFSET(x) offsetof(OGGContext, x)
 #define PARAM AV_OPT_FLAG_ENCODING_PARAM
 
 static const AVOption options[] = {
-    { "pagesize", "preferred page size in bytes",
+    { "pagesize", "preferred page size in bytes (deprecated)",
         OFFSET(pref_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_PAGE_SIZE, PARAM },
+    { "page_duration", "preferred page duration, in microseconds",
+        OFFSET(pref_duration), AV_OPT_TYPE_INT, { .i64 = 1000000 }, 0, INT64_MAX, PARAM },
     { NULL },
 };
 
@@ -177,6 +183,7 @@ static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream)
         return AVERROR(ENOMEM);
     l->page = oggstream->page;
 
+    oggstream->page.start_granule = oggstream->page.granule;
     oggstream->page_count++;
     ogg_reset_cur_page(oggstream);
 
@@ -210,6 +217,12 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
         flush = 1;
     }
 
+    // avoid a continued page
+    if (!header && oggstream->page.size > 0 &&
+        MAX_PAGE_SIZE - oggstream->page.size < size) {
+        ogg_buffer_page(s, oggstream);
+    }
+
     for (i = 0; i < total_segments; ) {
         OGGPage *page = &oggstream->page;
 
@@ -232,9 +245,19 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
         if (i == total_segments)
             page->granule = granule;
 
-        if (!header && (page->segments_count == 255 ||
-            (ogg->pref_size > 0 && page->size >= ogg->pref_size))) {
-           ogg_buffer_page(s, oggstream);
+        if (!header) {
+            AVStream *st = s->streams[page->stream_index];
+
+            int64_t start = av_rescale_q(page->start_granule, st->time_base,
+                                         AV_TIME_BASE_Q);
+            int64_t next  = av_rescale_q(page->granule, st->time_base,
+                                         AV_TIME_BASE_Q);
+
+            if (page->segments_count == 255 ||
+                (ogg->pref_size     > 0 && page->size   >= ogg->pref_size) ||
+                (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) {
+                ogg_buffer_page(s, oggstream);
+            }
         }
     }
 
@@ -367,9 +390,13 @@ static int ogg_build_opus_headers(AVCodecContext *avctx,
 
 static int ogg_write_header(AVFormatContext *s)
 {
+    OGGContext *ogg = s->priv_data;
     OGGStreamContext *oggstream;
     int i, j;
 
+    if (ogg->pref_size)
+        av_log(s, AV_LOG_WARNING, "The pagesize option is deprecated\n");
+
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         unsigned serial_num = i;
@@ -489,6 +516,9 @@ static int ogg_write_header(AVFormatContext *s)
         }
         ogg_buffer_page(s, oggstream);
     }
+
+    oggstream->page.start_granule = AV_NOPTS_VALUE;
+
     return 0;
 }
 
@@ -538,6 +568,9 @@ static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt)
     else
         granule = pkt->pts + pkt->duration;
 
+    if (oggstream->page.start_granule == AV_NOPTS_VALUE)
+        oggstream->page.start_granule = pkt->pts;
+
     ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule, 0);
     if (ret < 0)
         return ret;
@@ -553,9 +586,13 @@ static int ogg_write_trailer(AVFormatContext *s)
 {
     int i;
 
-    /* flush current page */
-    for (i = 0; i < s->nb_streams; i++)
-        ogg_buffer_page(s, s->streams[i]->priv_data);
+    /* flush current page if needed */
+    for (i = 0; i < s->nb_streams; i++) {
+        OGGStreamContext *oggstream = s->streams[i]->priv_data;
+
+        if (oggstream->page.size > 0)
+            ogg_buffer_page(s, oggstream);
+    }
 
     ogg_write_pages(s, 1);
 
@@ -584,5 +621,6 @@ AVOutputFormat ff_ogg_muxer = {
     .write_header      = ogg_write_header,
     .write_packet      = ogg_write_packet,
     .write_trailer     = ogg_write_trailer,
+    .flags             = AVFMT_TS_NEGATIVE,
     .priv_class        = &ogg_muxer_class,
 };
diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c
new file mode 100644
index 0000000..babd0f0
--- /dev/null
+++ b/libavformat/oggparseopus.c
@@ -0,0 +1,142 @@
+/*
+ * Opus parser for Ogg
+ * Copyright (c) 2012 Nicolas George
+ *
+ * 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 <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);
+
+        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 is truncated to %d (because of unimplemented end trim support).\n",
+                   os->pduration);
+            return AVERROR_PATCHWELCOME;
+        }
+    }
+
+    return 0;
+}
+
+const struct ogg_codec ff_opus_codec = {
+    .name             = "Opus",
+    .magic            = "OpusHead",
+    .magicsize        = 8,
+    .header           = opus_header,
+    .packet           = opus_packet,
+    .granule_is_start = 1,
+    .nb_header        = 1,
+};
diff --git a/libavformat/oggparseskeleton.c b/libavformat/oggparseskeleton.c
index 2de067d..f437c69 100644
--- a/libavformat/oggparseskeleton.c
+++ b/libavformat/oggparseskeleton.c
@@ -75,8 +75,8 @@ static int skeleton_header(AVFormatContext *s, int idx)
         target_idx = ogg_find_stream(ogg, AV_RL32(buf+12));
         start_granule = AV_RL64(buf+36);
         if (os->start_granule != OGG_NOGRANULE_VALUE) {
-            av_log_missing_feature(s,
-                                   "Multiple fisbone for the same stream", 0);
+            avpriv_report_missing_feature(s,
+                                          "Multiple fisbone for the same stream");
             return 1;
         }
         if (target_idx >= 0 && start_granule != OGG_NOGRANULE_VALUE) {
diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c
index dfb73c9..035bdc2 100644
--- a/libavformat/oggparsetheora.c
+++ b/libavformat/oggparsetheora.c
@@ -1,26 +1,26 @@
 /**
-      Copyright (C) 2005  Matthieu CASTET, Alex Beregszaszi
-
-      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.
-**/
+ *    Copyright (C) 2005  Matthieu CASTET, Alex Beregszaszi
+ *
+ *    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.
+ **/
 
 #include <stdlib.h>
 #include "libavutil/bswap.h"
@@ -29,64 +29,67 @@
 #include "internal.h"
 #include "oggdec.h"
 
-struct theora_params {
+typedef struct TheoraParams {
     int gpshift;
     int gpmask;
     unsigned version;
-};
+} TheoraParams;
 
-static int
-theora_header (AVFormatContext * s, int idx)
+static int theora_header(AVFormatContext *s, int idx)
 {
-    struct ogg *ogg = s->priv_data;
+    struct ogg *ogg       = s->priv_data;
     struct ogg_stream *os = ogg->streams + idx;
-    AVStream *st = s->streams[idx];
-    struct theora_params *thp = os->private;
-    int cds = st->codec->extradata_size + os->psize + 2;
+    AVStream *st          = s->streams[idx];
+    TheoraParams *thp     = os->private;
+    int cds               = st->codec->extradata_size + os->psize + 2;
+    int err;
     uint8_t *cdp;
 
-    if(!(os->buf[os->pstart] & 0x80))
+    if (!(os->buf[os->pstart] & 0x80))
         return 0;
 
-    if(!thp){
+    if (!thp) {
         thp = av_mallocz(sizeof(*thp));
+        if (!thp)
+            return AVERROR(ENOMEM);
         os->private = thp;
     }
 
     switch (os->buf[os->pstart]) {
     case 0x80: {
         GetBitContext gb;
-        int width, height;
         AVRational timebase;
 
-        init_get_bits(&gb, os->buf + os->pstart, os->psize*8);
+        init_get_bits(&gb, os->buf + os->pstart, os->psize * 8);
 
-        skip_bits_long(&gb, 7*8); /* 0x80"theora" */
+        /* 0x80"theora" */
+        skip_bits_long(&gb, 7 * 8);
 
         thp->version = get_bits_long(&gb, 24);
-        if (thp->version < 0x030100)
-        {
+        if (thp->version < 0x030100) {
             av_log(s, AV_LOG_ERROR,
-                "Too old or unsupported Theora (%x)\n", thp->version);
-            return -1;
+                   "Too old or unsupported Theora (%x)\n", thp->version);
+            return AVERROR(ENOSYS);
         }
 
-        width  = get_bits(&gb, 16) << 4;
-        height = get_bits(&gb, 16) << 4;
-        avcodec_set_dimensions(st->codec, width, height);
+        st->codec->width  = get_bits(&gb, 16) << 4;
+        st->codec->height = get_bits(&gb, 16) << 4;
 
         if (thp->version >= 0x030400)
             skip_bits(&gb, 100);
 
         if (thp->version >= 0x030200) {
-            width  = get_bits_long(&gb, 24);
-            height = get_bits_long(&gb, 24);
-            if (   width  <= st->codec->width  && width  > st->codec->width-16
-                && height <= st->codec->height && height > st->codec->height-16)
-                avcodec_set_dimensions(st->codec, width, height);
+            int width  = get_bits_long(&gb, 24);
+            int height = get_bits_long(&gb, 24);
+            if (width  <= st->codec->width  && width  > st->codec->width  - 16 &&
+                height <= st->codec->height && height > st->codec->height - 16) {
+                st->codec->width  = width;
+                st->codec->height = height;
+            }
 
             skip_bits(&gb, 16);
         }
+
         timebase.den = get_bits_long(&gb, 32);
         timebase.num = get_bits_long(&gb, 32);
         if (!(timebase.num > 0 && timebase.den > 0)) {
@@ -105,41 +108,43 @@ theora_header (AVFormatContext * s, int idx)
             skip_bits(&gb, 2);
 
         thp->gpshift = get_bits(&gb, 5);
-        thp->gpmask = (1 << thp->gpshift) - 1;
+        thp->gpmask  = (1 << thp->gpshift) - 1;
 
         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-        st->codec->codec_id = AV_CODEC_ID_THEORA;
-        st->need_parsing = AVSTREAM_PARSE_HEADERS;
-
+        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;
+            return AVERROR_INVALIDDATA;
         break;
     default:
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    st->codec->extradata = av_realloc (st->codec->extradata,
-                                       cds + FF_INPUT_BUFFER_PADDING_SIZE);
-    cdp = st->codec->extradata + st->codec->extradata_size;
+    if ((err = av_reallocp(&st->codec->extradata,
+                           cds + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+        st->codec->extradata_size = 0;
+        return err;
+    }
+    cdp    = st->codec->extradata + st->codec->extradata_size;
     *cdp++ = os->psize >> 8;
     *cdp++ = os->psize & 0xff;
-    memcpy (cdp, os->buf + os->pstart, os->psize);
+    memcpy(cdp, os->buf + os->pstart, os->psize);
     st->codec->extradata_size = cds;
 
     return 1;
 }
 
-static uint64_t
-theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
+static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp,
+                               int64_t *dts)
 {
-    struct ogg *ogg = ctx->priv_data;
+    struct ogg *ogg       = ctx->priv_data;
     struct ogg_stream *os = ogg->streams + idx;
-    struct theora_params *thp = os->private;
+    TheoraParams *thp     = os->private;
     uint64_t iframe, pframe;
 
     if (!thp)
@@ -151,7 +156,7 @@ theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
     if (thp->version < 0x030201)
         iframe++;
 
-    if(!pframe)
+    if (!pframe)
         os->pflags |= AV_PKT_FLAG_KEY;
 
     if (dts)
@@ -161,9 +166,9 @@ theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
 }
 
 const struct ogg_codec ff_theora_codec = {
-    .magic = "\200theora",
+    .magic     = "\200theora",
     .magicsize = 7,
-    .header = theora_header,
-    .gptopts = theora_gptopts,
+    .header    = theora_header,
+    .gptopts   = theora_gptopts,
     .nb_header = 3,
 };
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 9d0ffce..c19b545 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -1,35 +1,38 @@
-/**
-      Copyright (C) 2005  Michael Ahlberg, Måns Rullgård
-
-      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.
-**/
+/*
+ * Copyright (C) 2005  Michael Ahlberg, Måns Rullgård
+ *
+ * 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.
+ */
 
 #include <stdlib.h>
+
 #include "libavutil/avstring.h"
+#include "libavutil/base64.h"
 #include "libavutil/bswap.h"
 #include "libavutil/dict.h"
-#include "libavcodec/get_bits.h"
 #include "libavcodec/bytestream.h"
+#include "libavcodec/get_bits.h"
 #include "libavcodec/vorbis_parser.h"
 #include "avformat.h"
+#include "flac_picture.h"
 #include "internal.h"
 #include "oggdec.h"
 #include "vorbiscomment.h"
@@ -39,19 +42,19 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
     int i, cnum, h, m, s, ms, keylen = strlen(key);
     AVChapter *chapter = NULL;
 
-    if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1)
+    if (keylen < 9 || sscanf(key, "CHAPTER%03d", &cnum) != 1)
         return 0;
 
-    if (keylen == 9) {
+    if (keylen <= 10) {
         if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
             return 0;
 
-        avpriv_new_chapter(as, cnum, (AVRational){1,1000},
-                       ms + 1000*(s + 60*(m + 60*h)),
-                       AV_NOPTS_VALUE, NULL);
+        avpriv_new_chapter(as, cnum, (AVRational) { 1, 1000 },
+                           ms + 1000 * (s + 60 * (m + 60 * h)),
+                           AV_NOPTS_VALUE, NULL);
         av_free(val);
-    } else if (!strcmp(key+9, "NAME")) {
-        for(i = 0; i < as->nb_chapters; i++)
+    } else if (!strcmp(key + keylen - 4, "NAME")) {
+        for (i = 0; i < as->nb_chapters; i++)
             if (as->chapters[i]->id == cnum) {
                 chapter = as->chapters[i];
                 break;
@@ -59,8 +62,7 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
         if (!chapter)
             return 0;
 
-        av_dict_set(&chapter->metadata, "title", val,
-                         AV_DICT_DONT_STRDUP_VAL);
+        av_dict_set(&chapter->metadata, "title", val, AV_DICT_DONT_STRDUP_VAL);
     } else
         return 0;
 
@@ -68,21 +70,22 @@ static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
     return 1;
 }
 
-int
-ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, int size)
+int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m,
+                      const uint8_t *buf, int size)
 {
-    const uint8_t *p = buf;
+    const uint8_t *p   = buf;
     const uint8_t *end = buf + size;
     unsigned n, j;
     int s;
 
-    if (size < 8) /* must have vendor_length and user_comment_list_length */
-        return -1;
+    /* must have vendor_length and user_comment_list_length */
+    if (size < 8)
+        return AVERROR_INVALIDDATA;
 
     s = bytestream_get_le32(&p);
 
     if (end - p - 4 < s || s < 0)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     p += s;
 
@@ -97,7 +100,7 @@ ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, in
         if (end - p < s || s < 0)
             break;
 
-        t = p;
+        t  = p;
         p += s;
         n--;
 
@@ -117,26 +120,50 @@ ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, in
             if (!tt || !ct) {
                 av_freep(&tt);
                 av_freep(&ct);
-                av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n");
-                continue;
+                return AVERROR(ENOMEM);
             }
 
             for (j = 0; j < tl; j++)
-                tt[j] = toupper(t[j]);
+                tt[j] = av_toupper(t[j]);
             tt[tl] = 0;
 
             memcpy(ct, v, vl);
             ct[vl] = 0;
 
-            if (!ogm_chapter(as, tt, ct))
+            /* The format in which the pictures are stored is the FLAC format.
+             * Xiph says: "The binary FLAC picture structure is base64 encoded
+             * and placed within a VorbisComment with the tag name
+             * 'METADATA_BLOCK_PICTURE'. This is the preferred and
+             * recommended way of embedding cover art within VorbisComments."
+             */
+            if (!strcmp(tt, "METADATA_BLOCK_PICTURE")) {
+                int ret;
+                char *pict = av_malloc(vl);
+
+                if (!pict) {
+                    av_freep(&tt);
+                    av_freep(&ct);
+                    return AVERROR(ENOMEM);
+                }
+                if ((ret = av_base64_decode(pict, ct, vl)) > 0)
+                    ret = ff_flac_parse_picture(as, pict, ret);
+                av_freep(&tt);
+                av_freep(&ct);
+                av_freep(&pict);
+                if (ret < 0) {
+                    av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
+                    continue;
+                }
+            } else if (!ogm_chapter(as, tt, ct))
                 av_dict_set(m, tt, ct,
-                                   AV_DICT_DONT_STRDUP_KEY |
-                                   AV_DICT_DONT_STRDUP_VAL);
+                            AV_DICT_DONT_STRDUP_KEY |
+                            AV_DICT_DONT_STRDUP_VAL);
         }
     }
 
     if (p != end)
-        av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p);
+        av_log(as, AV_LOG_INFO,
+               "%ti bytes of comment header remain\n", end - p);
     if (n > 0)
         av_log(as, AV_LOG_INFO,
                "truncated comment header, %i comments not found\n", n);
@@ -146,8 +173,9 @@ ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, in
     return 0;
 }
 
-
-/** Parse the vorbis header
+/*
+ * Parse the vorbis header
+ *
  * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
  * [vorbis_version] = read 32 bits as unsigned integer | Not used
  * [audio_channels] = read 8 bit integer as unsigned | Used
@@ -158,7 +186,7 @@ ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, in
  * [blocksize_0] = read 4 bits as unsigned integer | Not Used
  * [blocksize_1] = read 4 bits as unsigned integer | Not Used
  * [framing_flag] = read one bit | Not Used
- *    */
+ */
 
 struct oggvorbis_private {
     unsigned int len[3];
@@ -168,19 +196,20 @@ struct oggvorbis_private {
     int final_duration;
 };
 
-
-static unsigned int
-fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
-                     uint8_t **buf)
+static int fixup_vorbis_headers(AVFormatContext *as,
+                                struct oggvorbis_private *priv,
+                                uint8_t **buf)
 {
-    int i,offset, len;
+    int i, offset, len, err;
     unsigned char *ptr;
 
     len = priv->len[0] + priv->len[1] + priv->len[2];
-    ptr = *buf = av_mallocz(len + len/255 + 64);
+    ptr = *buf = av_mallocz(len + len / 255 + 64);
+    if (!ptr)
+        return AVERROR(ENOMEM);
 
-    ptr[0] = 2;
-    offset = 1;
+    ptr[0]  = 2;
+    offset  = 1;
     offset += av_xiphlacing(&ptr[offset], priv->len[0]);
     offset += av_xiphlacing(&ptr[offset], priv->len[1]);
     for (i = 0; i < 3; i++) {
@@ -188,7 +217,8 @@ fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
         offset += priv->len[i];
         av_freep(&priv->packet[i]);
     }
-    *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);
+    if ((err = av_reallocp(buf, offset + FF_INPUT_BUFFER_PADDING_SIZE)) < 0)
+        return err;
     return offset;
 }
 
@@ -203,36 +233,37 @@ static void vorbis_cleanup(AVFormatContext *s, int idx)
             av_freep(&priv->packet[i]);
 }
 
-static int
-vorbis_header (AVFormatContext * s, int idx)
+static int vorbis_header(AVFormatContext *s, int idx)
 {
     struct ogg *ogg = s->priv_data;
+    AVStream *st    = s->streams[idx];
     struct ogg_stream *os = ogg->streams + idx;
-    AVStream *st = s->streams[idx];
     struct oggvorbis_private *priv;
     int pkt_type = os->buf[os->pstart];
 
     if (!os->private) {
         os->private = av_mallocz(sizeof(struct oggvorbis_private));
         if (!os->private)
-            return 0;
+            return AVERROR(ENOMEM);
     }
 
     if (!(pkt_type & 1))
         return 0;
 
     if (os->psize < 1 || pkt_type > 5)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     priv = os->private;
 
-    if (priv->packet[pkt_type>>1])
-        return -1;
+    if (priv->packet[pkt_type >> 1])
+        return AVERROR_INVALIDDATA;
     if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
-        return -1;
+        return AVERROR_INVALIDDATA;
 
-    priv->len[pkt_type >> 1] = os->psize;
+    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 */
@@ -240,31 +271,31 @@ vorbis_header (AVFormatContext * s, int idx)
         int srate;
 
         if (os->psize != 30)
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         if (bytestream_get_le32(&p) != 0) /* vorbis_version */
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         st->codec->channels = bytestream_get_byte(&p);
-        srate = bytestream_get_le32(&p);
+        srate               = bytestream_get_le32(&p);
         p += 4; // skip maximum bitrate
         st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
         p += 4; // skip minimum bitrate
 
         blocksize = bytestream_get_byte(&p);
-        bs0 = blocksize & 15;
-        bs1 = blocksize >> 4;
+        bs0       = blocksize & 15;
+        bs1       = blocksize >> 4;
 
         if (bs0 > bs1)
-            return -1;
+            return AVERROR_INVALIDDATA;
         if (bs0 < 6 || bs1 > 13)
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         if (bytestream_get_byte(&p) != 1) /* framing_flag */
-            return -1;
+            return AVERROR_INVALIDDATA;
 
         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-        st->codec->codec_id = AV_CODEC_ID_VORBIS;
+        st->codec->codec_id   = AV_CODEC_ID_VORBIS;
 
         if (srate > 0) {
             st->codec->sample_rate = srate;
@@ -272,19 +303,23 @@ vorbis_header (AVFormatContext * s, int idx)
         }
     } else if (os->buf[os->pstart] == 3) {
         if (os->psize > 8 &&
-            ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) {
+            ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7,
+                              os->psize - 8) >= 0) {
             // drop all metadata we parsed and which is not required by libvorbis
             unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
             if (new_len >= 16 && new_len < os->psize) {
                 AV_WL32(priv->packet[1] + new_len - 5, 0);
                 priv->packet[1][new_len - 1] = 1;
-                priv->len[1] = new_len;
+                priv->len[1]                 = new_len;
             }
         }
     } else {
-        int ret;
-        st->codec->extradata_size =
-            fixup_vorbis_headers(s, priv, &st->codec->extradata);
+        int ret = fixup_vorbis_headers(s, priv, &st->codec->extradata);
+        if (ret < 0) {
+            st->codec->extradata_size = 0;
+            return ret;
+        }
+        st->codec->extradata_size = ret;
         if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) {
             av_freep(&st->codec->extradata);
             st->codec->extradata_size = 0;
@@ -303,13 +338,13 @@ static int vorbis_packet(AVFormatContext *s, int 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 */
+     * 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;
-        uint8_t *last_pkt = os->buf + os->pstart;
-        uint8_t *next_pkt = last_pkt;
+        uint8_t *last_pkt  = os->buf + os->pstart;
+        uint8_t *next_pkt  = last_pkt;
         int first_duration = 0;
 
         avpriv_vorbis_parse_reset(&priv->vp);
@@ -324,16 +359,17 @@ static int vorbis_packet(AVFormatContext *s, int idx)
                 if (!duration)
                     first_duration = d;
                 duration += d;
-                last_pkt = next_pkt + os->segments[seg];
+                last_pkt  = next_pkt + os->segments[seg];
             }
             next_pkt += os->segments[seg];
         }
-        os->lastpts = os->lastdts   = os->granule - duration;
+        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;
-        priv->final_pts             = AV_NOPTS_VALUE;
+        s->streams[idx]->cur_dts = AV_NOPTS_VALUE;
+        priv->final_pts          = AV_NOPTS_VALUE;
         avpriv_vorbis_parse_reset(&priv->vp);
     }
 
@@ -348,12 +384,12 @@ static int vorbis_packet(AVFormatContext *s, int idx)
     }
 
     /* final packet handling
-       here we save the pts of the first packet in the final page, sum up all
-       packet durations in the final page except for the last one, and compare
-       to the page granule to find the duration of the final packet */
+     * here we save the pts of the first packet in the final page, sum up all
+     * packet durations in the final page except for the last one, and compare
+     * to the page granule to find the duration of the final packet */
     if (os->flags & OGG_FLAG_EOS) {
         if (os->lastpts != AV_NOPTS_VALUE) {
-            priv->final_pts = os->lastpts;
+            priv->final_pts      = os->lastpts;
             priv->final_duration = 0;
         }
         if (os->segp == os->nsegs)
@@ -365,10 +401,10 @@ static int vorbis_packet(AVFormatContext *s, int idx)
 }
 
 const struct ogg_codec ff_vorbis_codec = {
-    .magic = "\001vorbis",
+    .magic     = "\001vorbis",
     .magicsize = 7,
-    .header = vorbis_header,
-    .packet = vorbis_packet,
-    .cleanup= vorbis_cleanup,
+    .header    = vorbis_header,
+    .packet    = vorbis_packet,
+    .cleanup   = vorbis_cleanup,
     .nb_header = 3,
 };
diff --git a/libavformat/oma.c b/libavformat/oma.c
index aaaf0b2..27b5988 100644
--- a/libavformat/oma.c
+++ b/libavformat/oma.c
@@ -21,6 +21,7 @@
 #include "internal.h"
 #include "oma.h"
 #include "libavcodec/avcodec.h"
+#include "libavutil/channel_layout.h"
 
 const uint16_t ff_oma_srate_tab[8] = { 320, 441, 480, 882, 960, 0 };
 
@@ -31,3 +32,17 @@ const AVCodecTag ff_oma_codec_tags[] = {
     { AV_CODEC_ID_PCM_S16BE,   OMA_CODECID_LPCM    },
     { 0 },
 };
+
+/** map ATRAC-X channel id to internal channel layout */
+const uint64_t ff_oma_chid_to_native_layout[7] = {
+    AV_CH_LAYOUT_MONO,
+    AV_CH_LAYOUT_STEREO,
+    AV_CH_LAYOUT_SURROUND,
+    AV_CH_LAYOUT_4POINT0,
+    AV_CH_LAYOUT_5POINT1_BACK,
+    AV_CH_LAYOUT_6POINT1_BACK,
+    AV_CH_LAYOUT_7POINT1
+};
+
+/** map ATRAC-X channel id to total number of channels */
+const int ff_oma_chid_to_num_channels[7] = {1, 2, 3, 4, 6, 7, 8};
diff --git a/libavformat/oma.h b/libavformat/oma.h
index 1f0ddf9..9a35da2 100644
--- a/libavformat/oma.h
+++ b/libavformat/oma.h
@@ -41,4 +41,7 @@ extern const uint16_t ff_oma_srate_tab[8];
 
 extern const AVCodecTag ff_oma_codec_tags[];
 
+extern const uint64_t ff_oma_chid_to_native_layout[7];
+extern const int ff_oma_chid_to_num_channels[7];
+
 #endif /* AVFORMAT_OMA_H */
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index 0403451..709a60b 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -1,7 +1,7 @@
 /*
  * Sony OpenMG (OMA) demuxer
  *
- * Copyright (c) 2008 Maxim Poliakovski
+ * Copyright (c) 2008, 2013 Maxim Poliakovski
  *               2008 Benjamin Larsson
  *               2011 David Goldwich
  *
@@ -74,18 +74,20 @@ typedef struct OMAContext {
     struct AVDES av_des;
 } OMAContext;
 
-static void hex_log(AVFormatContext *s, int level, const char *name, const uint8_t *value, int len)
+static void hex_log(AVFormatContext *s, int level,
+                    const char *name, const uint8_t *value, int len)
 {
     char buf[33];
     len = FFMIN(len, 16);
     if (av_log_get_level() < level)
         return;
     ff_data_to_hex(buf, value, len, 1);
-    buf[len<<1] = '\0';
+    buf[len << 1] = '\0';
     av_log(s, level, "%s: %s\n", name, buf);
 }
 
-static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, int len)
+static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val,
+                int len)
 {
     OMAContext *oc = s->priv_data;
 
@@ -167,8 +169,8 @@ static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,
     if (AV_RB32(&enc_header[pos]) != oc->rid)
         av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");
 
-    taglen = AV_RB32(&enc_header[pos+32]);
-    datalen = AV_RB32(&enc_header[pos+36]) >> 4;
+    taglen  = AV_RB32(&enc_header[pos + 32]);
+    datalen = AV_RB32(&enc_header[pos + 36]) >> 4;
 
     pos += 44;
     if (size - pos < taglen)
@@ -212,12 +214,13 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
     }
     if (!em) {
         av_log(s, AV_LOG_ERROR, "No encryption header found\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     if (geob->datasize < 64) {
-        av_log(s, AV_LOG_ERROR, "Invalid GEOB data size: %u\n", geob->datasize);
-        return -1;
+        av_log(s, AV_LOG_ERROR,
+               "Invalid GEOB data size: %u\n", geob->datasize);
+        return AVERROR_INVALIDDATA;
     }
 
     gdata = geob->data;
@@ -232,7 +235,12 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
 
     if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING     ", 12)) {
         av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
+    }
+    if (OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize ||
+        OMA_ENC_HEADER_SIZE + 48 > geob->datasize) {
+        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);
@@ -240,7 +248,9 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
     memcpy(oc->iv, &header[0x58], 8);
     hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8);
 
-    hex_log(s, AV_LOG_DEBUG, "CBC-MAC", &gdata[OMA_ENC_HEADER_SIZE+oc->k_size+oc->e_size+oc->i_size], 8);
+    hex_log(s, AV_LOG_DEBUG, "CBC-MAC",
+            &gdata[OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size],
+            8);
 
     if (s->keylen > 0) {
         kset(s, s->key, s->key, s->keylen);
@@ -251,22 +261,23 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
         int i;
         for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) {
             uint8_t buf[16];
-            AV_WL64(buf, leaf_table[i]);
-            AV_WL64(&buf[8], leaf_table[i+1]);
+            AV_WL64(buf,     leaf_table[i]);
+            AV_WL64(&buf[8], leaf_table[i + 1]);
             kset(s, buf, buf, 16);
             if (!rprobe(s, gdata, geob->datasize, 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;
+            return AVERROR_INVALIDDATA;
         }
     }
 
     /* e_val */
     av_des_init(&oc->av_des, oc->m_val, 64, 0);
-    av_des_crypt(&oc->av_des, oc->e_val, &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
+    av_des_crypt(&oc->av_des, oc->e_val,
+                 &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0);
     hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8);
 
     /* init e_val */
@@ -278,7 +289,7 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header)
 static int oma_read_header(AVFormatContext *s)
 {
     int     ret, framesize, jsflag, samplerate;
-    uint32_t codec_params;
+    uint32_t codec_params, channel_id;
     int16_t eid;
     uint8_t buf[EA3_HEADER_SIZE];
     uint8_t *edata;
@@ -291,9 +302,10 @@ static int oma_read_header(AVFormatContext *s)
     if (ret < EA3_HEADER_SIZE)
         return -1;
 
-    if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
+    if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}), 3) ||
+        buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
         av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     oc->content_start = avio_tell(s->pb);
@@ -314,75 +326,87 @@ static int oma_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
 
     st->start_time = 0;
-    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_tag   = buf[32];
-    st->codec->codec_id    = ff_codec_get_id(ff_oma_codec_tags, st->codec->codec_tag);
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_tag  = buf[32];
+    st->codec->codec_id   = ff_codec_get_id(ff_oma_codec_tags,
+                                            st->codec->codec_tag);
 
     switch (buf[32]) {
-        case OMA_CODECID_ATRAC3:
-            samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
-            if (!samplerate) {
-                av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
-                return AVERROR_INVALIDDATA;
-            }
-            if (samplerate != 44100)
-                av_log_ask_for_sample(s, "Unsupported sample rate: %d\n",
-                                      samplerate);
-
-            framesize = (codec_params & 0x3FF) * 8;
-            jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */
-            st->codec->channels    = 2;
-            st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
-            st->codec->sample_rate = samplerate;
-            st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;
-
-            /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */
-            st->codec->extradata_size = 14;
-            edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!edata)
-                return AVERROR(ENOMEM);
-
-            st->codec->extradata = edata;
-            AV_WL16(&edata[0],  1);             // always 1
-            AV_WL32(&edata[2],  samplerate);    // samples rate
-            AV_WL16(&edata[6],  jsflag);        // coding mode
-            AV_WL16(&edata[8],  jsflag);        // coding mode
-            AV_WL16(&edata[10], 1);             // always 1
-            // AV_WL16(&edata[12], 0);          // always 0
-
-            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
-            break;
-        case OMA_CODECID_ATRAC3P:
-            st->codec->channels = (codec_params >> 10) & 7;
-            framesize = ((codec_params & 0x3FF) * 8) + 8;
-            samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
-            if (!samplerate) {
-                av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
-                return AVERROR_INVALIDDATA;
-            }
-            st->codec->sample_rate = samplerate;
-            st->codec->bit_rate    = samplerate * framesize * 8 / 1024;
-            avpriv_set_pts_info(st, 64, 1, samplerate);
-            av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
-            break;
-        case OMA_CODECID_MP3:
-            st->need_parsing = AVSTREAM_PARSE_FULL;
-            framesize = 1024;
-            break;
-        case OMA_CODECID_LPCM:
-            /* PCM 44.1 kHz 16 bit stereo big-endian */
-            st->codec->channels = 2;
-            st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
-            st->codec->sample_rate = 44100;
-            framesize = 1024;
-            /* bit rate = sample rate x PCM block align (= 4) x 8 */
-            st->codec->bit_rate = st->codec->sample_rate * 32;
-            st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
-            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
-            break;
-        default:
-            av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]);
-            return -1;
+    case OMA_CODECID_ATRAC3:
+        samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
+        if (!samplerate) {
+            av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
+            return AVERROR_INVALIDDATA;
+        }
+        if (samplerate != 44100)
+            avpriv_request_sample(s, "Sample rate %d", samplerate);
+
+        framesize = (codec_params & 0x3FF) * 8;
+
+        /* get stereo coding mode, 1 for joint-stereo */
+        jsflag = (codec_params >> 17) & 1;
+
+        st->codec->channels    = 2;
+        st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+        st->codec->sample_rate = samplerate;
+        st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;
+
+        /* fake the ATRAC3 extradata
+         * (wav format, makes stream copy to wav work) */
+        st->codec->extradata_size = 14;
+        edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!edata)
+            return AVERROR(ENOMEM);
+
+        st->codec->extradata = edata;
+        AV_WL16(&edata[0],  1);             // always 1
+        AV_WL32(&edata[2],  samplerate);    // samples rate
+        AV_WL16(&edata[6],  jsflag);        // coding mode
+        AV_WL16(&edata[8],  jsflag);        // coding mode
+        AV_WL16(&edata[10], 1);             // always 1
+        // AV_WL16(&edata[12], 0);          // always 0
+
+        avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+        break;
+    case OMA_CODECID_ATRAC3P:
+        channel_id = (codec_params >> 10) & 7;
+        if (!channel_id) {
+            av_log(s, AV_LOG_ERROR,
+                   "Invalid ATRAC-X channel id: %d\n", channel_id);
+            return AVERROR_INVALIDDATA;
+        }
+        st->codec->channel_layout = ff_oma_chid_to_native_layout[channel_id - 1];
+        st->codec->channels       = ff_oma_chid_to_num_channels[channel_id - 1];
+        framesize = ((codec_params & 0x3FF) * 8) + 8;
+        samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100;
+        if (!samplerate) {
+            av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n");
+            return AVERROR_INVALIDDATA;
+        }
+        st->codec->sample_rate = samplerate;
+        st->codec->bit_rate    = samplerate * framesize * 8 / 2048;
+        avpriv_set_pts_info(st, 64, 1, samplerate);
+        av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
+        break;
+    case OMA_CODECID_MP3:
+        st->need_parsing = AVSTREAM_PARSE_FULL;
+        framesize = 1024;
+        break;
+    case OMA_CODECID_LPCM:
+        /* PCM 44.1 kHz 16 bit stereo big-endian */
+        st->codec->channels = 2;
+        st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+        st->codec->sample_rate = 44100;
+        framesize = 1024;
+        /* bit rate = sample rate x PCM block align (= 4) x 8 */
+        st->codec->bit_rate = st->codec->sample_rate * 32;
+        st->codec->bits_per_coded_sample =
+            av_get_bits_per_sample(st->codec->codec_id);
+        avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n", buf[32]);
+        return AVERROR(ENOSYS);
     }
 
     st->codec->block_align = framesize;
@@ -422,23 +446,16 @@ static int oma_read_packet(AVFormatContext *s, AVPacket *pkt)
 
 static int oma_read_probe(AVProbeData *p)
 {
-    const uint8_t *buf;
+    const uint8_t *buf = p->buf;
     unsigned tag_len = 0;
 
-    buf = p->buf;
-
-    if (p->buf_size < ID3v2_HEADER_SIZE ||
-        !ff_id3v2_match(buf, ID3v2_EA3_MAGIC) ||
-        buf[3] != 3 || // version must be 3
-        buf[4]) // flags byte zero
-        return 0;
-
-    tag_len = ff_id3v2_tag_len(buf);
+    if (p->buf_size >= ID3v2_HEADER_SIZE && ff_id3v2_match(buf, ID3v2_EA3_MAGIC))
+        tag_len = ff_id3v2_tag_len(buf);
 
     /* This check cannot overflow as tag_len has at most 28 bits */
     if (p->buf_size < tag_len + 5)
         /* EA3 header comes late, might be outside of the probe buffer */
-        return AVPROBE_SCORE_MAX / 2;
+        return tag_len ? AVPROBE_SCORE_EXTENSION : 0;
 
     buf += tag_len;
 
@@ -448,7 +465,8 @@ static int oma_read_probe(AVProbeData *p)
         return 0;
 }
 
-static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
+static int oma_read_seek(struct AVFormatContext *s,
+                         int stream_index, int64_t timestamp, int flags)
 {
     OMAContext *oc = s->priv_data;
     int err = ff_pcm_read_seek(s, stream_index, timestamp, flags);
diff --git a/libavformat/options.c b/libavformat/options.c
index 3399dd4..d99f04a 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -79,7 +79,7 @@ static const AVClass *format_child_class_next(const AVClass *prev)
 static const AVClass av_format_context_class = {
     .class_name     = "AVFormatContext",
     .item_name      = format_to_name,
-    .option         = options,
+    .option         = avformat_options,
     .version        = LIBAVUTIL_VERSION_INT,
     .child_next     = format_child_next,
     .child_class_next = format_child_class_next,
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index d1e2a0c..54bf25f 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -30,10 +30,11 @@
 #define E AV_OPT_FLAG_ENCODING_PARAM
 #define D AV_OPT_FLAG_DECODING_PARAM
 
-static const AVOption options[]={
+static const AVOption avformat_options[] = {
 {"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"},
+{"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = AVFMT_FLAG_FLUSH_PACKETS }, INT_MIN, INT_MAX, D|E, "fflags"},
+{"flush_packets", "reduce the latency by flushing out packets immediately", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_FLUSH_PACKETS }, INT_MIN, INT_MAX, D, "fflags"},
 {"ignidx", "ignore index", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"},
 {"genpts", "generate pts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_GENPTS }, INT_MIN, INT_MAX, D, "fflags"},
 {"nofillin", "do not fill in missing values that can be exactly calculated", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOFILLIN }, INT_MIN, INT_MAX, D, "fflags"},
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index 451801f..650baea 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.c
@@ -27,48 +27,18 @@
 #include "avformat.h"
 #include "os_support.h"
 
-#if defined(_WIN32) && !defined(__MINGW32CE__)
-#undef open
-#include <fcntl.h>
-#include <io.h>
-#include <windows.h>
-
-int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
-{
-    int fd;
-    int num_chars;
-    wchar_t *filename_w;
-
-    /* convert UTF-8 to wide chars */
-    num_chars = MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, NULL, 0);
-    if (num_chars <= 0)
-        return -1;
-    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);
-    av_freep(&filename_w);
-
-    /* filename maybe be in CP_ACP */
-    if (fd == -1 && !(oflag & O_CREAT))
-        return open(filename_utf8, oflag, pmode);
-
-    return fd;
-}
-#endif
-
 #if CONFIG_NETWORK
 #include <fcntl.h>
 #if !HAVE_POLL_H
 #if HAVE_SYS_TIME_H
 #include <sys/time.h>
-#endif
+#endif /* HAVE_SYS_TIME_H */
 #if HAVE_WINSOCK2_H
 #include <winsock2.h>
 #elif HAVE_SYS_SELECT_H
 #include <sys/select.h>
-#endif
-#endif
+#endif /* HAVE_WINSOCK2_H */
+#endif /* !HAVE_POLL_H */
 
 #include "network.h"
 
@@ -112,7 +82,7 @@ int ff_getaddrinfo(const char *node, const char *service,
     win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");
     if (win_getaddrinfo)
         return win_getaddrinfo(node, service, hints, res);
-#endif
+#endif /* HAVE_WINSOCK2_H */
 
     *res = NULL;
     sin  = av_mallocz(sizeof(struct sockaddr_in));
@@ -186,7 +156,7 @@ void ff_freeaddrinfo(struct addrinfo *res)
         win_freeaddrinfo(res);
         return;
     }
-#endif
+#endif /* HAVE_WINSOCK2_H */
 
     av_free(res->ai_canonname);
     av_free(res->ai_addr);
@@ -207,7 +177,7 @@ int ff_getnameinfo(const struct sockaddr *sa, int salen,
     win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo");
     if (win_getnameinfo)
         return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
-#endif
+#endif /* HAVE_WINSOCK2_H */
 
     if (sa->sa_family != AF_INET)
         return EAI_FAMILY;
@@ -238,7 +208,7 @@ int ff_getnameinfo(const struct sockaddr *sa, int salen,
 #if HAVE_GETSERVBYPORT
         if (!(flags & NI_NUMERICSERV))
             ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp");
-#endif
+#endif /* HAVE_GETSERVBYPORT */
 
         if (ent)
             snprintf(serv, servlen, "%s", ent->s_name);
@@ -268,7 +238,7 @@ const char *ff_gai_strerror(int ecode)
 #if EAI_NODATA != EAI_NONAME
     case EAI_NODATA:
         return "No address associated with hostname";
-#endif
+#endif /* EAI_NODATA != EAI_NONAME */
     case EAI_NONAME:
         return "The name does not resolve for the supplied parameters";
     case EAI_SERVICE:
@@ -291,7 +261,7 @@ int ff_socket_nonblock(int socket, int enable)
         return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
     else
         return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
-#endif
+#endif /* HAVE_WINSOCK2_H */
 }
 
 #if !HAVE_POLL_H
@@ -309,7 +279,7 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout)
         errno = EINVAL;
         return -1;
     }
-#endif
+#endif /* HAVE_WINSOCK2_H */
 
     FD_ZERO(&read_set);
     FD_ZERO(&write_set);
@@ -324,7 +294,7 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout)
             errno = EINVAL;
             return -1;
         }
-#endif
+#endif /* !HAVE_WINSOCK2_H */
 
         if (fds[i].events & POLLIN)
             FD_SET(fds[i].fd, &read_set);
@@ -366,5 +336,6 @@ int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout)
 
     return rc;
 }
-#endif /* HAVE_POLL_H */
+#endif /* !HAVE_POLL_H */
+
 #endif /* CONFIG_NETWORK */
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index c5d3ab4..ae8cef7 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -31,7 +31,7 @@
 
 #include <sys/stat.h>
 
-#if defined(__MINGW32__) && !defined(__MINGW32CE__)
+#if defined(_WIN32) && !defined(__MINGW32CE__)
 #  include <fcntl.h>
 #  define lseek(f,p,w) _lseeki64((f), (p), (w))
 #  define stat _stati64
@@ -77,11 +77,6 @@ static inline int is_dos_path(const char *path)
 #endif
 #endif
 
-#if defined(_WIN32) && !defined(__MINGW32CE__)
-int ff_win32_open(const char *filename, int oflag, int pmode);
-#define open ff_win32_open
-#endif
-
 #if CONFIG_NETWORK
 #if !HAVE_SOCKLEN_T
 typedef int socklen_t;
diff --git a/libavformat/output-example.c b/libavformat/output-example.c
deleted file mode 100644
index 2f83990..0000000
--- a/libavformat/output-example.c
+++ /dev/null
@@ -1,540 +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"
-
-/* 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/pmpdec.c b/libavformat/pmpdec.c
index 6cdce10..484be43 100644
--- a/libavformat/pmpdec.c
+++ b/libavformat/pmpdec.c
@@ -157,7 +157,7 @@ static int pmp_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
 {
     PMPContext *pmp = s->priv_data;
     pmp->cur_stream = 0;
-    // fallback to default seek now
+    // fall back on default seek now
     return -1;
 }
 
diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c
index 633d61d..e662ed7 100644
--- a/libavformat/psxstr.c
+++ b/libavformat/psxstr.c
@@ -30,6 +30,7 @@
  */
 
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
@@ -94,7 +95,7 @@ static int str_probe(AVProbeData *p)
 
     /* MPEG files (like those ripped from VCDs) can also look like this;
      * only return half certainty */
-    return 50;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int str_read_header(AVFormatContext *s)
@@ -201,6 +202,12 @@ static int str_read_packet(AVFormatContext *s,
                     *ret_pkt = *pkt;
                     pkt->data= NULL;
                     pkt->size= -1;
+                    pkt->buf = NULL;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+                    pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
                     return 0;
                 }
 
diff --git a/libavformat/pva.c b/libavformat/pva.c
index 53041ba..3abfc18 100644
--- a/libavformat/pva.c
+++ b/libavformat/pva.c
@@ -36,7 +36,7 @@ static int pva_probe(AVProbeData * pd) {
     unsigned char *buf = pd->buf;
 
     if (AV_RB16(buf) == PVA_MAGIC && buf[2] && buf[2] < 3 && buf[4] == 0x55)
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
 
     return 0;
 }
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 543043e..74a1f2b 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -19,8 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-//#define DEBUG
-
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "libavutil/mathematics.h"
@@ -88,9 +86,6 @@ static int r3d_read_red1(AVFormatContext *s)
     framerate.num = avio_rb16(s->pb);
     framerate.den = avio_rb16(s->pb);
     if (framerate.num > 0 && framerate.den > 0) {
-#if FF_API_R_FRAME_RATE
-        st->r_frame_rate =
-#endif
         st->avg_frame_rate = framerate;
     }
 
diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c
index 5e95d10..41e1700 100644
--- a/libavformat/rawdec.c
+++ b/libavformat/rawdec.c
@@ -92,9 +92,6 @@ int ff_raw_video_read_header(AVFormatContext *s)
         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);
 
diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c
index 171c603..852a27d 100644
--- a/libavformat/rawenc.c
+++ b/libavformat/rawenc.c
@@ -26,7 +26,6 @@
 int ff_raw_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     avio_write(s->pb, pkt->data, pkt->size);
-    avio_flush(s->pb);
     return 0;
 }
 
diff --git a/libavformat/rdt.c b/libavformat/rdt.c
index 77c1c8c..a90c168 100644
--- a/libavformat/rdt.c
+++ b/libavformat/rdt.c
@@ -419,15 +419,16 @@ rdt_parse_sdp_line (AVFormatContext *s, int st_index,
 
         for (n = 0; n < s->nb_streams; n++)
             if (s->streams[n]->id == stream->id) {
-                int count = s->streams[n]->index + 1;
+                int count = s->streams[n]->index + 1, err;
                 if (first == -1) first = n;
                 if (rdt->nb_rmst < count) {
-                    RMStream **rmst= av_realloc(rdt->rmst, count*sizeof(*rmst));
-                    if (!rmst)
-                        return AVERROR(ENOMEM);
-                    memset(rmst + rdt->nb_rmst, 0,
-                           (count - rdt->nb_rmst) * sizeof(*rmst));
-                    rdt->rmst    = rmst;
+                    if ((err = av_reallocp(&rdt->rmst,
+                                           count * sizeof(*rdt->rmst))) < 0) {
+                        rdt->nb_rmst = 0;
+                        return err;
+                    }
+                    memset(rdt->rmst + rdt->nb_rmst, 0,
+                           (count - rdt->nb_rmst) * sizeof(*rdt->rmst));
                     rdt->nb_rmst = count;
                 }
                 rdt->rmst[s->streams[n]->index] = ff_rm_alloc_rmstream();
@@ -548,7 +549,7 @@ rdt_free_context (PayloadContext *rdt)
 }
 
 #define RDT_HANDLER(n, s, t) \
-static RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \
+static RTPDynamicProtocolHandler rdt_ ## n ## _handler = { \
     .enc_name         = s, \
     .codec_type       = t, \
     .codec_id         = AV_CODEC_ID_NONE, \
@@ -563,10 +564,10 @@ RDT_HANDLER(live_audio, "x-pn-multirate-realaudio-live", AVMEDIA_TYPE_AUDIO);
 RDT_HANDLER(video,      "x-pn-realvideo",                AVMEDIA_TYPE_VIDEO);
 RDT_HANDLER(audio,      "x-pn-realaudio",                AVMEDIA_TYPE_AUDIO);
 
-void av_register_rdt_dynamic_payload_handlers(void)
+void ff_register_rdt_dynamic_payload_handlers(void)
 {
-    ff_register_dynamic_payload_handler(&ff_rdt_video_handler);
-    ff_register_dynamic_payload_handler(&ff_rdt_audio_handler);
-    ff_register_dynamic_payload_handler(&ff_rdt_live_video_handler);
-    ff_register_dynamic_payload_handler(&ff_rdt_live_audio_handler);
+    ff_register_dynamic_payload_handler(&rdt_video_handler);
+    ff_register_dynamic_payload_handler(&rdt_audio_handler);
+    ff_register_dynamic_payload_handler(&rdt_live_video_handler);
+    ff_register_dynamic_payload_handler(&rdt_live_audio_handler);
 }
diff --git a/libavformat/rdt.h b/libavformat/rdt.h
index a393299..bd16890 100644
--- a/libavformat/rdt.h
+++ b/libavformat/rdt.h
@@ -62,7 +62,7 @@ void ff_rdt_calc_response_and_checksum(char response[41], char chksum[9],
 /**
  * Register RDT-related dynamic payload handlers with our cache.
  */
-void av_register_rdt_dynamic_payload_handlers(void);
+void ff_register_rdt_dynamic_payload_handlers(void);
 
 /**
  * Add subscription information to Subscribe parameter string.
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 09d8dbb..536ba43 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -19,15 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/mathematics.h"
+#include "libavutil/error.h"
 #include "libavcodec/avcodec.h"
 #include "avformat.h"
-#include "avio_internal.h"
 #include "riff.h"
-#include "libavcodec/bytestream.h"
 
-/* Note: when encoding, the first matching tag is used, so order is
-   important if multiple tags possible for a given codec. */
+/* Note: When encoding, the first matching tag is used, so order is
+ * important if multiple tags are possible for a given codec. */
 const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_H264,         MKTAG('H', '2', '6', '4') },
     { AV_CODEC_ID_H264,         MKTAG('h', '2', '6', '4') },
@@ -44,7 +42,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_H263,         MKTAG('Z', 'y', 'G', 'o') },
     { AV_CODEC_ID_H263,         MKTAG('M', '2', '6', '3') },
     { AV_CODEC_ID_H263P,        MKTAG('H', '2', '6', '3') },
-    { AV_CODEC_ID_H263I,        MKTAG('I', '2', '6', '3') }, /* intel h263 */
+    { AV_CODEC_ID_H263I,        MKTAG('I', '2', '6', '3') }, /* Intel H.263 */
     { 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') },
@@ -54,7 +52,10 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_MPEG4,        MKTAG('X', 'V', 'I', 'D') },
     { AV_CODEC_ID_MPEG4,        MKTAG('M', 'P', '4', 'S') },
     { AV_CODEC_ID_MPEG4,        MKTAG('M', '4', 'S', '2') },
-    { AV_CODEC_ID_MPEG4,        MKTAG( 4 ,  0 ,  0 ,  0 ) }, /* some broken avi use this */
+    /* some broken AVIs use this */
+    { AV_CODEC_ID_MPEG4,        MKTAG( 4 ,  0 ,  0 ,  0 ) },
+    /* some broken AVIs use this */
+    { AV_CODEC_ID_MPEG4,        MKTAG('Z', 'M', 'P', '4') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'I', 'V', '1') },
     { AV_CODEC_ID_MPEG4,        MKTAG('B', 'L', 'Z', '0') },
     { AV_CODEC_ID_MPEG4,        MKTAG('m', 'p', '4', 'v') },
@@ -63,7 +64,8 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_MPEG4,        MKTAG('S', 'E', 'D', 'G') },
     { AV_CODEC_ID_MPEG4,        MKTAG('R', 'M', 'P', '4') },
     { AV_CODEC_ID_MPEG4,        MKTAG('3', 'I', 'V', '2') },
-    { AV_CODEC_ID_MPEG4,        MKTAG('W', 'A', 'W', 'V') }, /* WaWv MPEG-4 Video Codec */
+    /* WaWv MPEG-4 Video Codec */
+    { AV_CODEC_ID_MPEG4,        MKTAG('W', 'A', 'W', 'V') },
     { AV_CODEC_ID_MPEG4,        MKTAG('F', 'F', 'D', 'S') },
     { AV_CODEC_ID_MPEG4,        MKTAG('F', 'V', 'F', 'W') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'C', 'O', 'D') },
@@ -74,18 +76,22 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_MPEG4,        MKTAG('V', 'I', 'D', 'M') },
     { AV_CODEC_ID_MPEG4,        MKTAG('M', '4', 'T', '3') },
     { AV_CODEC_ID_MPEG4,        MKTAG('G', 'E', 'O', 'X') },
-    { AV_CODEC_ID_MPEG4,        MKTAG('H', 'D', 'X', '4') }, /* flipped video */
+    /* flipped video */
+    { AV_CODEC_ID_MPEG4,        MKTAG('H', 'D', 'X', '4') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'M', 'K', '2') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'I', 'G', 'I') },
     { AV_CODEC_ID_MPEG4,        MKTAG('I', 'N', 'M', 'C') },
-    { AV_CODEC_ID_MPEG4,        MKTAG('E', 'P', 'H', 'V') }, /* Ephv MPEG-4 */
+    /* Ephv MPEG-4 */
+    { AV_CODEC_ID_MPEG4,        MKTAG('E', 'P', 'H', 'V') },
     { AV_CODEC_ID_MPEG4,        MKTAG('E', 'M', '4', 'A') },
-    { AV_CODEC_ID_MPEG4,        MKTAG('M', '4', 'C', 'C') }, /* Divio MPEG-4 */
+    /* Divio MPEG-4 */
+    { AV_CODEC_ID_MPEG4,        MKTAG('M', '4', 'C', 'C') },
     { AV_CODEC_ID_MPEG4,        MKTAG('S', 'N', '4', '0') },
     { AV_CODEC_ID_MPEG4,        MKTAG('V', 'S', 'P', 'X') },
     { 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 */
+    /* Samsung SHR-6040 */
+    { AV_CODEC_ID_MPEG4,        MKTAG('S', 'I', 'P', 'P') },
     { AV_CODEC_ID_MPEG4,        MKTAG('X', 'V', 'I', 'X') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'r', 'e', 'X') },
     { AV_CODEC_ID_MSMPEG4V3,    MKTAG('M', 'P', '4', '3') },
@@ -110,9 +116,12 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_DVVIDEO,      MKTAG('d', 'v', 's', 'l') },
     { AV_CODEC_ID_DVVIDEO,      MKTAG('d', 'v', '2', '5') },
     { AV_CODEC_ID_DVVIDEO,      MKTAG('d', 'v', '5', '0') },
-    { AV_CODEC_ID_DVVIDEO,      MKTAG('c', 'd', 'v', 'c') }, /* Canopus DV */
-    { AV_CODEC_ID_DVVIDEO,      MKTAG('C', 'D', 'V', 'H') }, /* Canopus DV */
-    { AV_CODEC_ID_DVVIDEO,      MKTAG('C', 'D', 'V', '5') }, /* Canopus DV */
+    /* Canopus DV */
+    { AV_CODEC_ID_DVVIDEO,      MKTAG('c', 'd', 'v', 'c') },
+    /* Canopus DV */
+    { AV_CODEC_ID_DVVIDEO,      MKTAG('C', 'D', 'V', 'H') },
+    /* Canopus DV */
+    { AV_CODEC_ID_DVVIDEO,      MKTAG('C', 'D', 'V', '5') },
     { 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') },
@@ -128,33 +137,43 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_MPEG4,        MKTAG( 4 ,  0 ,  0 ,  16) },
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('D', 'V', 'R', ' ') },
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('M', 'M', 'E', 'S') },
-    { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('L', 'M', 'P', '2') }, /* Lead MPEG2 in avi */
+    /* Lead MPEG-2 in AVI */
+    { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('L', 'M', 'P', '2') },
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('s', 'l', 'i', 'f') },
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('E', 'M', '2', 'V') },
-    { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('M', '7', '0', '1') }, /* Matrox MPEG2 intra-only */
+    /* Matrox MPEG-2 intra-only */
+    { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('M', '7', '0', '1') },
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('m', 'p', 'g', 'v') },
     { 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') },
     { AV_CODEC_ID_MJPEG,        MKTAG('m', 'j', 'p', 'a') },
     { AV_CODEC_ID_LJPEG,        MKTAG('L', 'J', 'P', 'G') },
-    { AV_CODEC_ID_MJPEG,        MKTAG('J', 'P', 'G', 'L') }, /* Pegasus lossless JPEG */
-    { AV_CODEC_ID_JPEGLS,       MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - encoder */
+    /* Pegasus lossless JPEG */
+    { AV_CODEC_ID_MJPEG,        MKTAG('J', 'P', 'G', 'L') },
+    /* JPEG-LS custom FOURCC for AVI - encoder */
+    { AV_CODEC_ID_JPEGLS,       MKTAG('M', 'J', 'L', 'S') },
     { AV_CODEC_ID_JPEGLS,       MKTAG('M', 'J', 'P', 'G') },
-    { AV_CODEC_ID_MJPEG,        MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */
+    /* JPEG-LS custom FOURCC for AVI - decoder */
+    { AV_CODEC_ID_MJPEG,        MKTAG('M', 'J', 'L', 'S') },
     { 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_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 */
-    { AV_CODEC_ID_MJPEG,        MKTAG('C', 'J', 'P', 'G') }, /* Creative Webcam JPEG */
-    { AV_CODEC_ID_MJPEG,        MKTAG('I', 'J', 'L', 'V') }, /* Intel JPEG Library Video Codec */
-    { AV_CODEC_ID_MJPEG,        MKTAG('M', 'V', 'J', 'P') }, /* Midvid JPEG Video Codec */
+    /* SL M-JPEG */
+    { AV_CODEC_ID_MJPEG,        MKTAG('S', 'L', 'M', 'J') },
+    /* Creative Webcam JPEG */
+    { AV_CODEC_ID_MJPEG,        MKTAG('C', 'J', 'P', 'G') },
+    /* Intel JPEG Library Video Codec */
+    { AV_CODEC_ID_MJPEG,        MKTAG('I', 'J', 'L', 'V') },
+    /* Midvid JPEG Video Codec */
+    { AV_CODEC_ID_MJPEG,        MKTAG('M', 'V', 'J', 'P') },
     { AV_CODEC_ID_MJPEG,        MKTAG('A', 'V', 'I', '1') },
     { AV_CODEC_ID_MJPEG,        MKTAG('A', 'V', 'I', '2') },
     { AV_CODEC_ID_MJPEG,        MKTAG('M', 'T', 'S', 'J') },
-    { AV_CODEC_ID_MJPEG,        MKTAG('Z', 'J', 'P', 'G') }, /* Paradigm Matrix M-JPEG Codec */
+    /* Paradigm Matrix M-JPEG Codec */
+    { AV_CODEC_ID_MJPEG,        MKTAG('Z', 'J', 'P', 'G') },
     { AV_CODEC_ID_MJPEG,        MKTAG('M', 'M', 'J', 'P') },
     { AV_CODEC_ID_HUFFYUV,      MKTAG('H', 'F', 'Y', 'U') },
     { AV_CODEC_ID_FFVHUFF,      MKTAG('F', 'F', 'V', 'H') },
@@ -184,7 +203,8 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('Y', '8', ' ', ' ') },
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('H', 'D', 'Y', 'C') },
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('Y', 'V', 'U', '9') },
-    { AV_CODEC_ID_RAWVIDEO,     MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */
+    /* SoftLab-NSK VideoTizer */
+    { AV_CODEC_ID_RAWVIDEO,     MKTAG('V', 'D', 'T', 'Z') },
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('Y', '4', '1', '1') },
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('N', 'V', '1', '2') },
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('N', 'V', '2', '1') },
@@ -208,6 +228,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { 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_VP6A,         MKTAG('V', 'P', '6', 'A') },
     { AV_CODEC_ID_VP6F,         MKTAG('V', 'P', '6', 'F') },
     { AV_CODEC_ID_VP6F,         MKTAG('F', 'L', 'V', '4') },
     { AV_CODEC_ID_VP8,          MKTAG('V', 'P', '8', '0') },
@@ -231,7 +252,6 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_TRUEMOTION1,  MKTAG('P', 'V', 'E', 'Z') },
     { AV_CODEC_ID_MSZH,         MKTAG('M', 'S', 'Z', 'H') },
     { AV_CODEC_ID_ZLIB,         MKTAG('Z', 'L', 'I', 'B') },
-    { 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_FLASHSV,      MKTAG('F', 'S', 'V', '1') },
@@ -281,6 +301,8 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { 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_UTVIDEO,      MKTAG('U', 'L', 'H', '0') },
+    { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'H', '2') },
     { AV_CODEC_ID_VBLE,         MKTAG('V', 'B', 'L', 'E') },
     { AV_CODEC_ID_DXTORY,       MKTAG('x', 't', 'o', 'r') },
     { AV_CODEC_ID_ZEROCODEC,    MKTAG('Z', 'E', 'C', 'O') },
@@ -291,34 +313,43 @@ const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_CLLC,         MKTAG('C', 'L', 'L', 'C') },
     { AV_CODEC_ID_MSS2,         MKTAG('M', 'S', 'S', '2') },
     { AV_CODEC_ID_SVQ3,         MKTAG('S', 'V', 'Q', '3') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '2') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '3') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '4') },
     { AV_CODEC_ID_NONE,         0 }
 };
 
 const AVCodecTag ff_codec_wav_tags[] = {
     { AV_CODEC_ID_PCM_S16LE,       0x0001 },
-    { AV_CODEC_ID_PCM_U8,          0x0001 }, /* must come after s16le in this list */
+    /* must come after s16le in this list */
+    { AV_CODEC_ID_PCM_U8,          0x0001 },
     { AV_CODEC_ID_PCM_S24LE,       0x0001 },
     { AV_CODEC_ID_PCM_S32LE,       0x0001 },
     { AV_CODEC_ID_ADPCM_MS,        0x0002 },
     { AV_CODEC_ID_PCM_F32LE,       0x0003 },
-    { AV_CODEC_ID_PCM_F64LE,       0x0003 }, /* must come after f32le in this list */
+    /* must come after f32le in this list */
+    { AV_CODEC_ID_PCM_F64LE,       0x0003 },
     { AV_CODEC_ID_PCM_ALAW,        0x0006 },
     { AV_CODEC_ID_PCM_MULAW,       0x0007 },
     { AV_CODEC_ID_WMAVOICE,        0x000A },
     { AV_CODEC_ID_ADPCM_IMA_WAV,   0x0011 },
-    { AV_CODEC_ID_PCM_ZORK,        0x0011 }, /* must come after adpcm_ima_wav in this list */
+    /* must come after adpcm_ima_wav in this list */
+    { AV_CODEC_ID_PCM_ZORK,        0x0011 },
     { AV_CODEC_ID_ADPCM_YAMAHA,    0x0020 },
     { AV_CODEC_ID_TRUESPEECH,      0x0022 },
     { AV_CODEC_ID_GSM_MS,          0x0031 },
+    { AV_CODEC_ID_GSM_MS,          0x0032 },
     { AV_CODEC_ID_ADPCM_G726,      0x0045 },
     { AV_CODEC_ID_MP2,             0x0050 },
     { AV_CODEC_ID_MP3,             0x0055 },
     { AV_CODEC_ID_AMR_NB,          0x0057 },
     { AV_CODEC_ID_AMR_WB,          0x0058 },
-    { AV_CODEC_ID_ADPCM_IMA_DK4,   0x0061 },  /* rogue format number */
-    { AV_CODEC_ID_ADPCM_IMA_DK3,   0x0062 },  /* rogue format number */
+    /* rogue format number */
+    { AV_CODEC_ID_ADPCM_IMA_DK4,   0x0061 },
+    /* rogue format number */
+    { AV_CODEC_ID_ADPCM_IMA_DK3,   0x0062 },
     { AV_CODEC_ID_ADPCM_IMA_WAV,   0x0069 },
-    { AV_CODEC_ID_VOXWARE,         0x0075 },
+    { AV_CODEC_ID_METASOUND,       0x0075 },
     { AV_CODEC_ID_AAC,             0x00ff },
     { AV_CODEC_ID_SIPR,            0x0130 },
     { AV_CODEC_ID_WMAV1,           0x0160 },
@@ -332,7 +363,8 @@ const AVCodecTag ff_codec_wav_tags[] = {
     { AV_CODEC_ID_IAC,             0x0402 },
     { AV_CODEC_ID_GSM_MS,          0x1500 },
     { AV_CODEC_ID_TRUESPEECH,      0x1501 },
-    { AV_CODEC_ID_AAC,             0x1600 }, /* ADTS AAC */
+    /* ADTS AAC */
+    { AV_CODEC_ID_AAC,             0x1600 },
     { AV_CODEC_ID_AAC_LATM,        0x1602 },
     { AV_CODEC_ID_AC3,             0x2000 },
     { AV_CODEC_ID_DTS,             0x2001 },
@@ -341,424 +373,33 @@ const AVCodecTag ff_codec_wav_tags[] = {
     { AV_CODEC_ID_AAC,             0x4143 },
     { AV_CODEC_ID_SPEEX,           0xA109 },
     { AV_CODEC_ID_FLAC,            0xF1AC },
-    { AV_CODEC_ID_ADPCM_SWF,       ('S'<<8)+'F' },
-    { AV_CODEC_ID_VORBIS,          ('V'<<8)+'o' }, //HACK/FIXME, does vorbis in WAV/AVI have an (in)official id?
+    { AV_CODEC_ID_ADPCM_SWF,       ('S' << 8) + 'F' },
+    /* HACK/FIXME: Does Vorbis in WAV/AVI have an (in)official ID? */
+    { AV_CODEC_ID_VORBIS,          ('V' << 8) + 'o' },
     { AV_CODEC_ID_NONE,      0 },
 };
 
 const AVMetadataConv ff_riff_info_conv[] = {
-    { "IART", "artist"    },
-    { "ICMT", "comment"   },
-    { "ICOP", "copyright" },
-    { "ICRD", "date"      },
-    { "IGNR", "genre"     },
-    { "ILNG", "language"  },
-    { "INAM", "title"     },
-    { "IPRD", "album"     },
-    { "IPRT", "track"     },
-    { "ISFT", "encoder"   },
-    { "ITCH", "encoded_by"},
+    { "IART", "artist"     },
+    { "ICMT", "comment"    },
+    { "ICOP", "copyright"  },
+    { "ICRD", "date"       },
+    { "IGNR", "genre"      },
+    { "ILNG", "language"   },
+    { "INAM", "title"      },
+    { "IPRD", "album"      },
+    { "IPRT", "track"      },
+    { "ISFT", "encoder"    },
+    { "ITCH", "encoded_by" },
     { 0 },
 };
 
-#if CONFIG_MUXERS
-int64_t ff_start_tag(AVIOContext *pb, const char *tag)
+const struct AVCodecTag *avformat_get_riff_video_tags(void)
 {
-    ffio_wfourcc(pb, tag);
-    avio_wl32(pb, 0);
-    return avio_tell(pb);
+    return ff_codec_bmp_tags;
 }
 
-void ff_end_tag(AVIOContext *pb, int64_t start)
+const struct AVCodecTag *avformat_get_riff_audio_tags(void)
 {
-    int64_t pos;
-
-    pos = avio_tell(pb);
-    avio_seek(pb, start - 4, SEEK_SET);
-    avio_wl32(pb, (uint32_t)(pos - start));
-    avio_seek(pb, pos, SEEK_SET);
-}
-
-/* WAVEFORMATEX header */
-/* returns the size or -1 on error */
-int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
-{
-    int bps, blkalign, bytespersec, frame_size;
-    int hdrsize = 18;
-    int waveformatextensible;
-    uint8_t temp[256];
-    uint8_t *riff_extradata= temp;
-    uint8_t *riff_extradata_start= temp;
-
-    if(!enc->codec_tag || enc->codec_tag > 0xffff)
-        return -1;
-
-    /* We use the known constant frame size for the codec if known, otherwise
-       fallback to using AVCodecContext.frame_size, which is not as reliable
-       for indicating packet duration */
-    frame_size = av_get_audio_frame_duration(enc, 0);
-    if (!frame_size)
-        frame_size = enc->frame_size;
-
-    waveformatextensible =   (enc->channels > 2 && enc->channel_layout)
-                          || enc->sample_rate > 48000
-                          || av_get_bits_per_sample(enc->codec_id) > 16;
-
-    if (waveformatextensible) {
-        avio_wl16(pb, 0xfffe);
-    } else {
-        avio_wl16(pb, enc->codec_tag);
-    }
-    avio_wl16(pb, enc->channels);
-    avio_wl32(pb, enc->sample_rate);
-    if (enc->codec_id == AV_CODEC_ID_MP2 || enc->codec_id == AV_CODEC_ID_MP3 || enc->codec_id == AV_CODEC_ID_GSM_MS) {
-        bps = 0;
-    } else {
-        if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
-            if (enc->bits_per_coded_sample)
-                bps = enc->bits_per_coded_sample;
-            else
-                bps = 16; // default to 16
-        }
-    }
-    if(bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample){
-        av_log(enc, AV_LOG_WARNING, "requested bits_per_coded_sample (%d) and actually stored (%d) differ\n", enc->bits_per_coded_sample, bps);
-    }
-
-    if (enc->codec_id == AV_CODEC_ID_MP2 || enc->codec_id == AV_CODEC_ID_MP3) {
-        /* this is wrong, but it seems many demuxers do not work if this is set
-           correctly */
-        blkalign = frame_size;
-        //blkalign = 144 * enc->bit_rate/enc->sample_rate;
-    } else if (enc->codec_id == AV_CODEC_ID_AC3) {
-            blkalign = 3840; //maximum bytes per frame
-    } else if (enc->block_align != 0) { /* specified by the codec */
-        blkalign = enc->block_align;
-    } else
-        blkalign = bps * enc->channels / av_gcd(8, bps);
-    if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
-        enc->codec_id == AV_CODEC_ID_PCM_S24LE ||
-        enc->codec_id == AV_CODEC_ID_PCM_S32LE ||
-        enc->codec_id == AV_CODEC_ID_PCM_F32LE ||
-        enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
-        enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
-        bytespersec = enc->sample_rate * blkalign;
-    } else {
-        bytespersec = enc->bit_rate / 8;
-    }
-    avio_wl32(pb, bytespersec); /* bytes per second */
-    avio_wl16(pb, blkalign); /* block align */
-    avio_wl16(pb, bps); /* bits per sample */
-    if (enc->codec_id == AV_CODEC_ID_MP3) {
-        hdrsize += 12;
-        bytestream_put_le16(&riff_extradata, 1);    /* wID */
-        bytestream_put_le32(&riff_extradata, 2);    /* fdwFlags */
-        bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
-        bytestream_put_le16(&riff_extradata, 1);    /* nFramesPerBlock */
-        bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
-    } else if (enc->codec_id == AV_CODEC_ID_MP2) {
-        hdrsize += 22;
-        bytestream_put_le16(&riff_extradata, 2);                          /* fwHeadLayer */
-        bytestream_put_le32(&riff_extradata, enc->bit_rate);              /* dwHeadBitrate */
-        bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8); /* fwHeadMode */
-        bytestream_put_le16(&riff_extradata, 0);                          /* fwHeadModeExt */
-        bytestream_put_le16(&riff_extradata, 1);                          /* wHeadEmphasis */
-        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_GSM_MS || enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
-        hdrsize += 2;
-        bytestream_put_le16(&riff_extradata, frame_size); /* wSamplesPerBlock */
-    } else if(enc->extradata_size){
-        riff_extradata_start= enc->extradata;
-        riff_extradata= enc->extradata + enc->extradata_size;
-        hdrsize += enc->extradata_size;
-    }
-    if(waveformatextensible) {                                    /* write WAVEFORMATEXTENSIBLE extensions */
-        hdrsize += 22;
-        avio_wl16(pb, riff_extradata - riff_extradata_start + 22); /* 22 is WAVEFORMATEXTENSIBLE size */
-        avio_wl16(pb, bps);                                        /* ValidBitsPerSample || SamplesPerBlock || Reserved */
-        avio_wl32(pb, enc->channel_layout);                        /* dwChannelMask */
-        avio_wl32(pb, enc->codec_tag);                             /* GUID + next 3 */
-        avio_wl32(pb, 0x00100000);
-        avio_wl32(pb, 0xAA000080);
-        avio_wl32(pb, 0x719B3800);
-    } else {
-        avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
-    }
-    avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
-    if(hdrsize&1){
-        hdrsize++;
-        avio_w8(pb, 0);
-    }
-
-    return hdrsize;
-}
-
-/* BITMAPINFOHEADER header */
-void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf)
-{
-    avio_wl32(pb, 40 + enc->extradata_size); /* size */
-    avio_wl32(pb, enc->width);
-    //We always store RGB TopDown
-    avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
-    avio_wl16(pb, 1); /* planes */
-
-    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, 0);
-    avio_wl32(pb, 0);
-    avio_wl32(pb, 0);
-    avio_wl32(pb, 0);
-
-    avio_write(pb, enc->extradata, enc->extradata_size);
-
-    if (!for_asf && enc->extradata_size & 1)
-        avio_w8(pb, 0);
-}
-
-void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale)
-{
-    int gcd;
-    int audio_frame_size;
-
-    /* We use the known constant frame size for the codec if known, otherwise
-       fallback to using AVCodecContext.frame_size, which is not as reliable
-       for indicating packet duration */
-    audio_frame_size = av_get_audio_frame_duration(stream, 0);
-    if (!audio_frame_size)
-        audio_frame_size = stream->frame_size;
-
-    *au_ssize= stream->block_align;
-    if (audio_frame_size && stream->sample_rate) {
-        *au_scale = audio_frame_size;
-        *au_rate= stream->sample_rate;
-    }else if(stream->codec_type == AVMEDIA_TYPE_VIDEO ||
-             stream->codec_type == AVMEDIA_TYPE_DATA ||
-             stream->codec_type == AVMEDIA_TYPE_SUBTITLE){
-        *au_scale= stream->time_base.num;
-        *au_rate = stream->time_base.den;
-    }else{
-        *au_scale= stream->block_align ? stream->block_align*8 : 8;
-        *au_rate = stream->bit_rate ? stream->bit_rate : 8*stream->sample_rate;
-    }
-    gcd= av_gcd(*au_scale, *au_rate);
-    *au_scale /= gcd;
-    *au_rate /= gcd;
-}
-
-void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
-{
-    int len = strlen(str);
-    if (len > 0) {
-        len++;
-        ffio_wfourcc(pb, tag);
-        avio_wl32(pb, len);
-        avio_put_str(pb, str);
-        if (len & 1)
-            avio_w8(pb, 0);
-    }
-}
-
-static const char riff_tags[][5] = {
-    "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
-    "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
-    "IPRT", "ISBJ", "ISFT", "ISHP", "ISRC", "ISRF", "ITCH",
-    {0}
-};
-
-static int riff_has_valid_tags(AVFormatContext *s)
-{
-    int i;
-
-    for (i = 0; *riff_tags[i]; i++) {
-        if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
-            return 1;
-    }
-
-    return 0;
-}
-
-void ff_riff_write_info(AVFormatContext *s)
-{
-    AVIOContext *pb = s->pb;
-    int i;
-    int64_t list_pos;
-    AVDictionaryEntry *t = NULL;
-
-    ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
-
-    /* writing empty LIST is not nice and may cause problems */
-    if (!riff_has_valid_tags(s))
-        return;
-
-    list_pos = ff_start_tag(pb, "LIST");
-    ffio_wfourcc(pb, "INFO");
-    for (i = 0; *riff_tags[i]; i++) {
-        if ((t = av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE)))
-            ff_riff_write_info_tag(s->pb, t->key, t->value);
-    }
-    ff_end_tag(pb, list_pos);
-}
-#endif //CONFIG_MUXERS
-
-#if CONFIG_DEMUXERS
-/* We could be given one of the three possible structures here:
- * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure
- * is an expansion of the previous one with the fields added
- * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and
- * WAVEFORMATEX adds 'WORD  cbSize' and basically makes itself
- * an openended structure.
- */
-int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
-{
-    int id;
-
-    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;
-    codec->block_align = avio_rl16(pb);
-    if (size == 14) {  /* We're dealing with plain vanilla WAVEFORMAT */
-        codec->bits_per_coded_sample = 8;
-    }else
-        codec->bits_per_coded_sample = avio_rl16(pb);
-    if (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);
-            codec->channel_layout = avio_rl32(pb); /* dwChannelMask */
-            id = avio_rl32(pb); /* 4 first bytes of GUID */
-            avio_skip(pb, 12); /* skip end of GUID */
-            cbSize -= 22;
-            size -= 22;
-        }
-        codec->extradata_size = cbSize;
-        if (cbSize > 0) {
-            av_free(codec->extradata);
-            codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!codec->extradata)
-                return AVERROR(ENOMEM);
-            avio_read(pb, codec->extradata, codec->extradata_size);
-            size -= cbSize;
-        }
-
-        /* It is possible for the chunk to contain garbage at the end */
-        if (size > 0)
-            avio_skip(pb, size);
-    }
-    if (codec->sample_rate <= 0) {
-        av_log(NULL, AV_LOG_ERROR,
-               "Invalid sample rate: %d\n", codec->sample_rate);
-        return AVERROR_INVALIDDATA;
-    }
-    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;
-        codec->sample_rate = 0;
-    }
-    /* override bits_per_coded_sample for G.726 */
-    if (codec->codec_id == AV_CODEC_ID_ADPCM_G726)
-        codec->bits_per_coded_sample = codec->bit_rate / codec->sample_rate;
-
-    return 0;
-}
-
-
-enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps)
-{
-    enum AVCodecID id;
-    id = ff_codec_get_id(ff_codec_wav_tags, tag);
-    if (id <= 0)
-        return id;
-
-    if (id == AV_CODEC_ID_PCM_S16LE)
-        id = ff_get_pcm_codec_id(bps, 0, 0, ~1);
-    else if (id == AV_CODEC_ID_PCM_F32LE)
-        id = ff_get_pcm_codec_id(bps, 1, 0, 0);
-
-    if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8)
-        id = AV_CODEC_ID_PCM_ZORK;
-    return id;
-}
-
-int ff_get_bmp_header(AVIOContext *pb, AVStream *st)
-{
-    int tag1;
-    avio_rl32(pb); /* size */
-    st->codec->width = avio_rl32(pb);
-    st->codec->height = (int32_t)avio_rl32(pb);
-    avio_rl16(pb); /* planes */
-    st->codec->bits_per_coded_sample= avio_rl16(pb); /* depth */
-    tag1 = avio_rl32(pb);
-    avio_rl32(pb); /* ImageSize */
-    avio_rl32(pb); /* XPelsPerMeter */
-    avio_rl32(pb); /* YPelsPerMeter */
-    avio_rl32(pb); /* ClrUsed */
-    avio_rl32(pb); /* ClrImportant */
-    return tag1;
-}
-
-int ff_read_riff_info(AVFormatContext *s, int64_t size)
-{
-    int64_t start, end, cur;
-    AVIOContext *pb = s->pb;
-
-    start = avio_tell(pb);
-    end = start + size;
-
-    while ((cur = avio_tell(pb)) >= 0 && cur <= end - 8 /* = tag + size */) {
-        uint32_t chunk_code;
-        int64_t chunk_size;
-        char key[5] = {0};
-        char *value;
-
-        chunk_code = avio_rl32(pb);
-        chunk_size = avio_rl32(pb);
-
-        if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) {
-            av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n");
-            break;
-        }
-
-        chunk_size += (chunk_size & 1);
-
-        if (!chunk_code) {
-            if (chunk_size)
-                avio_skip(pb, chunk_size);
-            else if (pb->eof_reached) {
-                av_log(s, AV_LOG_WARNING, "truncated file\n");
-                return AVERROR_EOF;
-            }
-            continue;
-        }
-
-        value = av_malloc(chunk_size + 1);
-        if (!value) {
-            av_log(s, AV_LOG_ERROR, "out of memory, unable to read INFO tag\n");
-            return AVERROR(ENOMEM);
-        }
-
-        AV_WL32(key, chunk_code);
-
-        if (avio_read(pb, value, chunk_size) != chunk_size) {
-            av_free(value);
-            av_log(s, AV_LOG_WARNING, "premature end of file while reading INFO tag\n");
-            break;
-        }
-
-        value[chunk_size] = 0;
-
-        av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
-    }
-
-    return 0;
+    return ff_codec_wav_tags;
 }
-#endif // CONFIG_DEMUXERS
diff --git a/libavformat/riff.h b/libavformat/riff.h
index 761f92e..f458f26 100644
--- a/libavformat/riff.h
+++ b/libavformat/riff.h
@@ -34,7 +34,6 @@
 #include "metadata.h"
 
 extern const AVMetadataConv ff_riff_info_conv[];
-extern const char ff_riff_tags[][5];
 
 int64_t ff_start_tag(AVIOContext *pb, const char *tag);
 void ff_end_tag(AVIOContext *pb, int64_t start);
@@ -68,4 +67,35 @@ void ff_riff_write_info(AVFormatContext *s);
  */
 void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str);
 
+typedef uint8_t ff_asf_guid[16];
+
+typedef struct AVCodecGuid {
+    enum AVCodecID id;
+    ff_asf_guid guid;
+} AVCodecGuid;
+
+extern const AVCodecGuid ff_codec_wav_guids[];
+
+#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]
+
+#define FF_MEDIASUBTYPE_BASE_GUID \
+    0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
+
+static av_always_inline int ff_guidcmp(const void *g1, const void *g2)
+{
+    return memcmp(g1, g2, sizeof(ff_asf_guid));
+}
+
+static av_always_inline int ff_get_guid(AVIOContext *s, ff_asf_guid *g)
+{
+    return avio_read(s, *g, sizeof(*g));
+}
+
+enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid);
+
 #endif /* AVFORMAT_RIFF_H */
diff --git a/libavformat/riffdec.c b/libavformat/riffdec.c
new file mode 100644
index 0000000..74f93ac
--- /dev/null
+++ b/libavformat/riffdec.c
@@ -0,0 +1,234 @@
+/*
+ * RIFF demuxing functions and data
+ * Copyright (c) 2000 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 "libavutil/dict.h"
+#include "libavutil/error.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/bytestream.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "riff.h"
+
+const AVCodecGuid ff_codec_wav_guids[] = {
+    { AV_CODEC_ID_AC3,      { 0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
+    { AV_CODEC_ID_ATRAC3P,  { 0xBF, 0xAA, 0x23, 0xE9, 0x58, 0xCB, 0x71, 0x44, 0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62 } },
+    { AV_CODEC_ID_EAC3,     { 0xAF, 0x87, 0xFB, 0xA7, 0x02, 0x2D, 0xFB, 0x42, 0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD } },
+    { AV_CODEC_ID_MP2,      { 0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } },
+    { AV_CODEC_ID_NONE }
+};
+
+enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
+{
+    int i;
+    for (i = 0; guids[i].id != AV_CODEC_ID_NONE; i++)
+        if (!ff_guidcmp(guids[i].guid, guid))
+            return guids[i].id;
+    return AV_CODEC_ID_NONE;
+}
+
+/* We could be given one of the three possible structures here:
+ * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure
+ * is an expansion of the previous one with the fields added
+ * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and
+ * WAVEFORMATEX adds 'WORD  cbSize' and basically makes itself
+ * an openended structure.
+ */
+
+static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c)
+{
+    ff_asf_guid subformat;
+    c->bits_per_coded_sample = avio_rl16(pb);
+    c->channel_layout        = avio_rl32(pb); /* dwChannelMask */
+
+    ff_get_guid(pb, &subformat);
+    if (!memcmp(subformat + 4,
+                (const uint8_t[]){ FF_MEDIASUBTYPE_BASE_GUID }, 12)) {
+        c->codec_tag = AV_RL32(subformat);
+        c->codec_id  = ff_wav_codec_get_id(c->codec_tag,
+                                           c->bits_per_coded_sample);
+    } else {
+        c->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subformat);
+        if (!c->codec_id)
+            av_log(c, AV_LOG_WARNING,
+                   "unknown subformat:"FF_PRI_GUID"\n",
+                   FF_ARG_GUID(subformat));
+    }
+}
+
+int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size)
+{
+    int id;
+
+    id                 = avio_rl16(pb);
+    codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    codec->channels    = avio_rl16(pb);
+    codec->sample_rate = avio_rl32(pb);
+    codec->bit_rate    = avio_rl32(pb) * 8;
+    codec->block_align = avio_rl16(pb);
+    if (size == 14) {  /* We're dealing with plain vanilla WAVEFORMAT */
+        codec->bits_per_coded_sample = 8;
+    } else
+        codec->bits_per_coded_sample = avio_rl16(pb);
+    if (id == 0xFFFE) {
+        codec->codec_tag = 0;
+    } else {
+        codec->codec_tag = id;
+        codec->codec_id  = ff_wav_codec_get_id(id,
+                                               codec->bits_per_coded_sample);
+    }
+    if (size >= 18) {  /* We're obviously dealing with WAVEFORMATEX */
+        int cbSize = avio_rl16(pb); /* cbSize */
+        size  -= 18;
+        cbSize = FFMIN(size, cbSize);
+        if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */
+            parse_waveformatex(pb, codec);
+            cbSize -= 22;
+            size   -= 22;
+        }
+        codec->extradata_size = cbSize;
+        if (cbSize > 0) {
+            av_free(codec->extradata);
+            codec->extradata = av_mallocz(codec->extradata_size +
+                                          FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!codec->extradata)
+                return AVERROR(ENOMEM);
+            avio_read(pb, codec->extradata, codec->extradata_size);
+            size -= cbSize;
+        }
+
+        /* It is possible for the chunk to contain garbage at the end */
+        if (size > 0)
+            avio_skip(pb, size);
+    }
+    if (codec->sample_rate <= 0) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Invalid sample rate: %d\n", codec->sample_rate);
+        return AVERROR_INVALIDDATA;
+    }
+    if (codec->codec_id == AV_CODEC_ID_AAC_LATM) {
+        /* Channels and sample_rate values are those prior to applying SBR
+         * and/or PS. */
+        codec->channels    = 0;
+        codec->sample_rate = 0;
+    }
+    /* override bits_per_coded_sample for G.726 */
+    if (codec->codec_id == AV_CODEC_ID_ADPCM_G726)
+        codec->bits_per_coded_sample = codec->bit_rate / codec->sample_rate;
+
+    return 0;
+}
+
+enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps)
+{
+    enum AVCodecID id;
+    id = ff_codec_get_id(ff_codec_wav_tags, tag);
+    if (id <= 0)
+        return id;
+
+    if (id == AV_CODEC_ID_PCM_S16LE)
+        id = ff_get_pcm_codec_id(bps, 0, 0, ~1);
+    else if (id == AV_CODEC_ID_PCM_F32LE)
+        id = ff_get_pcm_codec_id(bps, 1, 0,  0);
+
+    if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8)
+        id = AV_CODEC_ID_PCM_ZORK;
+    return id;
+}
+
+int ff_get_bmp_header(AVIOContext *pb, AVStream *st)
+{
+    int tag1;
+    avio_rl32(pb); /* size */
+    st->codec->width  = avio_rl32(pb);
+    st->codec->height = (int32_t)avio_rl32(pb);
+    avio_rl16(pb); /* planes */
+    st->codec->bits_per_coded_sample = avio_rl16(pb); /* depth */
+    tag1                             = avio_rl32(pb);
+    avio_rl32(pb); /* ImageSize */
+    avio_rl32(pb); /* XPelsPerMeter */
+    avio_rl32(pb); /* YPelsPerMeter */
+    avio_rl32(pb); /* ClrUsed */
+    avio_rl32(pb); /* ClrImportant */
+    return tag1;
+}
+
+int ff_read_riff_info(AVFormatContext *s, int64_t size)
+{
+    int64_t start, end, cur;
+    AVIOContext *pb = s->pb;
+
+    start = avio_tell(pb);
+    end   = start + size;
+
+    while ((cur = avio_tell(pb)) >= 0 &&
+           cur <= end - 8 /* = tag + size */) {
+        uint32_t chunk_code;
+        int64_t chunk_size;
+        char key[5] = { 0 };
+        char *value;
+
+        chunk_code = avio_rl32(pb);
+        chunk_size = avio_rl32(pb);
+
+        if (chunk_size > end ||
+            end - chunk_size < cur ||
+            chunk_size == UINT_MAX) {
+            av_log(s, AV_LOG_WARNING, "too big INFO subchunk\n");
+            break;
+        }
+
+        chunk_size += (chunk_size & 1);
+
+        if (!chunk_code) {
+            if (chunk_size)
+                avio_skip(pb, chunk_size);
+            else if (pb->eof_reached) {
+                av_log(s, AV_LOG_WARNING, "truncated file\n");
+                return AVERROR_EOF;
+            }
+            continue;
+        }
+
+        value = av_malloc(chunk_size + 1);
+        if (!value) {
+            av_log(s, AV_LOG_ERROR,
+                   "out of memory, unable to read INFO tag\n");
+            return AVERROR(ENOMEM);
+        }
+
+        AV_WL32(key, chunk_code);
+
+        if (avio_read(pb, value, chunk_size) != chunk_size) {
+            av_free(value);
+            av_log(s, AV_LOG_WARNING,
+                   "premature end of file while reading INFO tag\n");
+            break;
+        }
+
+        value[chunk_size] = 0;
+
+        av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
+    }
+
+    return 0;
+}
diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c
new file mode 100644
index 0000000..98e97c0
--- /dev/null
+++ b/libavformat/riffenc.c
@@ -0,0 +1,295 @@
+/*
+ * RIFF muxing functions
+ * Copyright (c) 2000 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 "libavutil/dict.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/bytestream.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "riff.h"
+
+int64_t ff_start_tag(AVIOContext *pb, const char *tag)
+{
+    ffio_wfourcc(pb, tag);
+    avio_wl32(pb, 0);
+    return avio_tell(pb);
+}
+
+void ff_end_tag(AVIOContext *pb, int64_t start)
+{
+    int64_t pos;
+
+    pos = avio_tell(pb);
+    avio_seek(pb, start - 4, SEEK_SET);
+    avio_wl32(pb, (uint32_t)(pos - start));
+    avio_seek(pb, pos, SEEK_SET);
+}
+
+/* WAVEFORMATEX header */
+/* returns the size or -1 on error */
+int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc)
+{
+    int bps, blkalign, bytespersec, frame_size;
+    int hdrsize = 18;
+    int waveformatextensible;
+    uint8_t temp[256];
+    uint8_t *riff_extradata       = temp;
+    uint8_t *riff_extradata_start = temp;
+
+    if (!enc->codec_tag || enc->codec_tag > 0xffff)
+        return -1;
+
+    /* We use the known constant frame size for the codec if known, otherwise
+     * fall back on using AVCodecContext.frame_size, which is not as reliable
+     * for indicating packet duration. */
+    frame_size = av_get_audio_frame_duration(enc, 0);
+    if (!frame_size)
+        frame_size = enc->frame_size;
+
+    waveformatextensible = (enc->channels > 2 && enc->channel_layout) ||
+                           enc->sample_rate > 48000 ||
+                           av_get_bits_per_sample(enc->codec_id) > 16;
+
+    if (waveformatextensible)
+        avio_wl16(pb, 0xfffe);
+    else
+        avio_wl16(pb, enc->codec_tag);
+
+    avio_wl16(pb, enc->channels);
+    avio_wl32(pb, enc->sample_rate);
+    if (enc->codec_id == AV_CODEC_ID_MP2 ||
+        enc->codec_id == AV_CODEC_ID_MP3 ||
+        enc->codec_id == AV_CODEC_ID_GSM_MS) {
+        bps = 0;
+    } else {
+        if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
+            if (enc->bits_per_coded_sample)
+                bps = enc->bits_per_coded_sample;
+            else
+                bps = 16;  // default to 16
+        }
+    }
+    if (bps != enc->bits_per_coded_sample && enc->bits_per_coded_sample) {
+        av_log(enc, AV_LOG_WARNING,
+               "requested bits_per_coded_sample (%d) "
+               "and actually stored (%d) differ\n",
+               enc->bits_per_coded_sample, bps);
+    }
+
+    if (enc->codec_id == AV_CODEC_ID_MP2 ||
+        enc->codec_id == AV_CODEC_ID_MP3) {
+        /* This is wrong, but it seems many demuxers do not work if this
+         * is set correctly. */
+        blkalign = frame_size;
+        // blkalign = 144 * enc->bit_rate/enc->sample_rate;
+    } else if (enc->codec_id == AV_CODEC_ID_AC3) {
+        blkalign = 3840;                /* maximum bytes per frame */
+    } else if (enc->block_align != 0) { /* specified by the codec */
+        blkalign = enc->block_align;
+    } else
+        blkalign = bps * enc->channels / av_gcd(8, bps);
+    if (enc->codec_id == AV_CODEC_ID_PCM_U8 ||
+        enc->codec_id == AV_CODEC_ID_PCM_S24LE ||
+        enc->codec_id == AV_CODEC_ID_PCM_S32LE ||
+        enc->codec_id == AV_CODEC_ID_PCM_F32LE ||
+        enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
+        enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
+        bytespersec = enc->sample_rate * blkalign;
+    } else {
+        bytespersec = enc->bit_rate / 8;
+    }
+    avio_wl32(pb, bytespersec); /* bytes per second */
+    avio_wl16(pb, blkalign);    /* block align */
+    avio_wl16(pb, bps);         /* bits per sample */
+    if (enc->codec_id == AV_CODEC_ID_MP3) {
+        hdrsize += 12;
+        bytestream_put_le16(&riff_extradata, 1);    /* wID */
+        bytestream_put_le32(&riff_extradata, 2);    /* fdwFlags */
+        bytestream_put_le16(&riff_extradata, 1152); /* nBlockSize */
+        bytestream_put_le16(&riff_extradata, 1);    /* nFramesPerBlock */
+        bytestream_put_le16(&riff_extradata, 1393); /* nCodecDelay */
+    } else if (enc->codec_id == AV_CODEC_ID_MP2) {
+        hdrsize += 22;
+        /* fwHeadLayer */
+        bytestream_put_le16(&riff_extradata, 2);
+        /* dwHeadBitrate */
+        bytestream_put_le32(&riff_extradata, enc->bit_rate);
+        /* fwHeadMode */
+        bytestream_put_le16(&riff_extradata, enc->channels == 2 ? 1 : 8);
+        /* fwHeadModeExt */
+        bytestream_put_le16(&riff_extradata, 0);
+        /* wHeadEmphasis */
+        bytestream_put_le16(&riff_extradata, 1);
+        /* fwHeadFlags */
+        bytestream_put_le16(&riff_extradata, 16);
+        /* dwPTSLow */
+        bytestream_put_le32(&riff_extradata, 0);
+        /* dwPTSHigh */
+        bytestream_put_le32(&riff_extradata, 0);
+    } else if (enc->codec_id == AV_CODEC_ID_GSM_MS ||
+               enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
+        hdrsize += 2;
+        /* wSamplesPerBlock */
+        bytestream_put_le16(&riff_extradata, frame_size);
+    } else if (enc->extradata_size) {
+        riff_extradata_start = enc->extradata;
+        riff_extradata       = enc->extradata + enc->extradata_size;
+        hdrsize             += enc->extradata_size;
+    }
+    /* write WAVEFORMATEXTENSIBLE extensions */
+    if (waveformatextensible) {
+        hdrsize += 22;
+        /* 22 is WAVEFORMATEXTENSIBLE size */
+        avio_wl16(pb, riff_extradata - riff_extradata_start + 22);
+        /* ValidBitsPerSample || SamplesPerBlock || Reserved */
+        avio_wl16(pb, bps);
+        /* dwChannelMask */
+        avio_wl32(pb, enc->channel_layout);
+        /* GUID + next 3 */
+        avio_wl32(pb, enc->codec_tag);
+        avio_wl32(pb, 0x00100000);
+        avio_wl32(pb, 0xAA000080);
+        avio_wl32(pb, 0x719B3800);
+    } else {
+        avio_wl16(pb, riff_extradata - riff_extradata_start); /* cbSize */
+    }
+    avio_write(pb, riff_extradata_start, riff_extradata - riff_extradata_start);
+    if (hdrsize & 1) {
+        hdrsize++;
+        avio_w8(pb, 0);
+    }
+
+    return hdrsize;
+}
+
+/* BITMAPINFOHEADER header */
+void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc,
+                       const AVCodecTag *tags, int for_asf)
+{
+    /* size */
+    avio_wl32(pb, 40 + enc->extradata_size);
+    avio_wl32(pb, enc->width);
+    //We always store RGB TopDown
+    avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height);
+    /* planes */
+    avio_wl16(pb, 1);
+    /* depth */
+    avio_wl16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24);
+    /* compression type */
+    avio_wl32(pb, enc->codec_tag);
+    avio_wl32(pb, enc->width * enc->height * 3);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+
+    avio_write(pb, enc->extradata, enc->extradata_size);
+
+    if (!for_asf && enc->extradata_size & 1)
+        avio_w8(pb, 0);
+}
+
+void ff_parse_specific_params(AVCodecContext *stream, int *au_rate,
+                              int *au_ssize, int *au_scale)
+{
+    int gcd;
+    int audio_frame_size;
+
+    /* We use the known constant frame size for the codec if known, otherwise
+     * fall back on using AVCodecContext.frame_size, which is not as reliable
+     * for indicating packet duration. */
+    audio_frame_size = av_get_audio_frame_duration(stream, 0);
+    if (!audio_frame_size)
+        audio_frame_size = stream->frame_size;
+
+    *au_ssize = stream->block_align;
+    if (audio_frame_size && stream->sample_rate) {
+        *au_scale = audio_frame_size;
+        *au_rate  = stream->sample_rate;
+    } else if (stream->codec_type == AVMEDIA_TYPE_VIDEO ||
+               stream->codec_type == AVMEDIA_TYPE_DATA ||
+               stream->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+        *au_scale = stream->time_base.num;
+        *au_rate  = stream->time_base.den;
+    } else {
+        *au_scale = stream->block_align ? stream->block_align * 8 : 8;
+        *au_rate  = stream->bit_rate ? stream->bit_rate :
+                    8 * stream->sample_rate;
+    }
+    gcd        = av_gcd(*au_scale, *au_rate);
+    *au_scale /= gcd;
+    *au_rate  /= gcd;
+}
+
+void ff_riff_write_info_tag(AVIOContext *pb, const char *tag, const char *str)
+{
+    int len = strlen(str);
+    if (len > 0) {
+        len++;
+        ffio_wfourcc(pb, tag);
+        avio_wl32(pb, len);
+        avio_put_str(pb, str);
+        if (len & 1)
+            avio_w8(pb, 0);
+    }
+}
+
+static const char riff_tags[][5] = {
+    "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
+    "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
+    "IPRT", "ISBJ", "ISFT", "ISHP", "ISRC", "ISRF", "ITCH",
+    { 0 }
+};
+
+static int riff_has_valid_tags(AVFormatContext *s)
+{
+    int i;
+
+    for (i = 0; *riff_tags[i]; i++)
+        if (av_dict_get(s->metadata, riff_tags[i], NULL, AV_DICT_MATCH_CASE))
+            return 1;
+
+    return 0;
+}
+
+void ff_riff_write_info(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    int i;
+    int64_t list_pos;
+    AVDictionaryEntry *t = NULL;
+
+    ff_metadata_conv(&s->metadata, ff_riff_info_conv, NULL);
+
+    /* writing empty LIST is not nice and may cause problems */
+    if (!riff_has_valid_tags(s))
+        return;
+
+    list_pos = ff_start_tag(pb, "LIST");
+    ffio_wfourcc(pb, "INFO");
+    for (i = 0; *riff_tags[i]; i++)
+        if ((t = av_dict_get(s->metadata, riff_tags[i],
+                             NULL, AV_DICT_MATCH_CASE)))
+            ff_riff_write_info_tag(s->pb, t->key, t->value);
+    ff_end_tag(pb, list_pos);
+}
diff --git a/libavformat/rl2.c b/libavformat/rl2.c
index ab33aab..5d30bf8 100644
--- a/libavformat/rl2.c
+++ b/libavformat/rl2.c
@@ -32,6 +32,8 @@
  * optional background_frame
  */
 
+#include <stdint.h>
+
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "avformat.h"
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index f8362c0..d61f569 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -21,6 +21,7 @@
 
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "avformat.h"
@@ -28,7 +29,7 @@
 #include "rmsipr.h"
 #include "rm.h"
 
-#define DEINT_ID_GENR MKTAG('g', 'e', 'n', 'r') ///< interleaving for Cooker/Atrac
+#define DEINT_ID_GENR MKTAG('g', 'e', 'n', 'r') ///< interleaving for Cooker/ATRAC
 #define DEINT_ID_INT0 MKTAG('I', 'n', 't', '0') ///< no interleaving needed
 #define DEINT_ID_INT4 MKTAG('I', 'n', 't', '4') ///< interleaving for 28.8
 #define DEINT_ID_SIPR MKTAG('s', 'i', 'p', 'r') ///< interleaving for Sipro
@@ -338,9 +339,6 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
             av_log(s, AV_LOG_ERROR, "Invalid framerate\n");
             return AVERROR_INVALIDDATA;
         }
-#if FF_API_R_FRAME_RATE
-        st->r_frame_rate = st->avg_frame_rate;
-#endif
     }
 
 skip:
@@ -683,6 +681,12 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,
         *pkt= vst->pkt;
         vst->pkt.data= NULL;
         vst->pkt.size= 0;
+        vst->pkt.buf = NULL;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+        vst->pkt.destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
         if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin
             memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,
                 vst->videobufpos - 1 - 8*vst->slices);
diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c
index ed1ba7c..fba8feb 100644
--- a/libavformat/rmenc.c
+++ b/libavformat/rmenc.c
@@ -369,7 +369,6 @@ static int rm_write_audio(AVFormatContext *s, const uint8_t *buf, int size, int
     } else {
         avio_write(pb, buf, size);
     }
-    avio_flush(pb);
     stream->nb_frames++;
     av_free(buf1);
     return 0;
@@ -414,7 +413,6 @@ static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int
     avio_w8(pb, stream->nb_frames & 0xff);
 
     avio_write(pb, buf, size);
-    avio_flush(pb);
 
     stream->nb_frames++;
     return 0;
diff --git a/libavformat/rpl.c b/libavformat/rpl.c
index a5b1e6e..0b22d8a 100644
--- a/libavformat/rpl.c
+++ b/libavformat/rpl.c
@@ -19,11 +19,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+#include <stdlib.h>
+
 #include "libavutil/avstring.h"
 #include "libavutil/dict.h"
 #include "avformat.h"
 #include "internal.h"
-#include <stdlib.h>
 
 #define RPL_SIGNATURE "ARMovie\x0A"
 #define RPL_SIGNATURE_SIZE 8
@@ -164,11 +166,9 @@ static int rpl_read_header(AVFormatContext *s)
             // 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",
diff --git a/libavformat/rsodec.c b/libavformat/rsodec.c
index 2d57a96..1612572 100644
--- a/libavformat/rsodec.c
+++ b/libavformat/rsodec.c
@@ -43,13 +43,13 @@ static int rso_read_header(AVFormatContext *s)
     codec = ff_codec_get_id(ff_codec_rso_tags, id);
 
     if (codec == AV_CODEC_ID_ADPCM_IMA_WAV) {
-        av_log(s, AV_LOG_ERROR, "ADPCM in RSO not implemented\n");
+        avpriv_report_missing_feature(s, "ADPCM in RSO");
         return AVERROR_PATCHWELCOME;
     }
 
     bps = av_get_bits_per_sample(codec);
     if (!bps) {
-        av_log_ask_for_sample(s, "could not determine bits per sample\n");
+        avpriv_request_sample(s, "Unknown bits per sample");
         return AVERROR_PATCHWELCOME;
     }
 
diff --git a/libavformat/rtmp.h b/libavformat/rtmp.h
index b9c5f1e..dc7ba5b 100644
--- a/libavformat/rtmp.h
+++ b/libavformat/rtmp.h
@@ -1,6 +1,6 @@
 /*
  * RTMP definitions
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of Libav.
  *
diff --git a/libavformat/rtmphttp.c b/libavformat/rtmphttp.c
index 80a983b..34c68fb 100644
--- a/libavformat/rtmphttp.c
+++ b/libavformat/rtmphttp.c
@@ -85,14 +85,15 @@ static int rtmp_http_send_cmd(URLContext *h, const char *cmd)
 static int rtmp_http_write(URLContext *h, const uint8_t *buf, int size)
 {
     RTMP_HTTPContext *rt = h->priv_data;
-    void *ptr;
 
     if (rt->out_size + size > rt->out_capacity) {
+        int err;
         rt->out_capacity = (rt->out_size + size) * 2;
-        ptr = av_realloc(rt->out_data, rt->out_capacity);
-        if (!ptr)
-            return AVERROR(ENOMEM);
-        rt->out_data = ptr;
+        if ((err = av_reallocp(&rt->out_data, rt->out_capacity)) < 0) {
+            rt->out_size = 0;
+            rt->out_capacity = 0;
+            return err;
+        }
     }
 
     memcpy(rt->out_data + rt->out_size, buf, size);
@@ -112,7 +113,7 @@ static int rtmp_http_read(URLContext *h, uint8_t *buf, int size)
         if (ret < 0 && ret != AVERROR_EOF)
             return ret;
 
-        if (ret == AVERROR_EOF) {
+        if (!ret || ret == AVERROR_EOF) {
             if (rt->finishing) {
                 /* Do not send new requests when the client wants to
                  * close the connection. */
@@ -226,7 +227,7 @@ static int rtmp_http_open(URLContext *h, const char *uri, int flags)
     /* read the server reply which contains a unique ID */
     for (;;) {
         ret = ffurl_read(rt->stream, rt->client_id + off, sizeof(rt->client_id) - off);
-        if (ret == AVERROR_EOF)
+        if (!ret || ret == AVERROR_EOF)
             break;
         if (ret < 0)
             goto fail;
@@ -236,7 +237,7 @@ static int rtmp_http_open(URLContext *h, const char *uri, int flags)
             goto fail;
         }
     }
-    while (off > 0 && isspace(rt->client_id[off - 1]))
+    while (off > 0 && av_isspace(rt->client_id[off - 1]))
         off--;
     rt->client_id[off] = '\0';
 
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index ace7729..f58f668 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -1,6 +1,6 @@
 /*
  * RTMP input format
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of Libav.
  *
@@ -129,27 +129,51 @@ int ff_amf_read_null(GetByteContext *bc)
     return 0;
 }
 
+int ff_rtmp_check_alloc_array(RTMPPacket **prev_pkt, int *nb_prev_pkt,
+                              int channel)
+{
+    int nb_alloc;
+    RTMPPacket *ptr;
+    if (channel < *nb_prev_pkt)
+        return 0;
+
+    nb_alloc = channel + 16;
+    // This can't use the av_reallocp family of functions, since we
+    // would need to free each element in the array before the array
+    // itself is freed.
+    ptr = av_realloc_array(*prev_pkt, nb_alloc, sizeof(**prev_pkt));
+    if (!ptr)
+        return AVERROR(ENOMEM);
+    memset(ptr + *nb_prev_pkt, 0, (nb_alloc - *nb_prev_pkt) * sizeof(*ptr));
+    *prev_pkt = ptr;
+    *nb_prev_pkt = nb_alloc;
+    return 0;
+}
+
 int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
-                        int chunk_size, RTMPPacket *prev_pkt)
+                        int chunk_size, RTMPPacket **prev_pkt, int *nb_prev_pkt)
 {
     uint8_t hdr;
 
     if (ffurl_read(h, &hdr, 1) != 1)
         return AVERROR(EIO);
 
-    return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt, hdr);
+    return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt,
+                                        nb_prev_pkt, hdr);
 }
 
-int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
-                                 RTMPPacket *prev_pkt, uint8_t hdr)
+static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p,
+                                      int chunk_size, RTMPPacket **prev_pkt_ptr,
+                                      int *nb_prev_pkt, uint8_t hdr)
 {
 
-    uint8_t t, buf[16];
-    int channel_id, timestamp, size, offset = 0;
+    uint8_t buf[16];
+    int channel_id, timestamp, size;
     uint32_t extra = 0;
     enum RTMPPacketType type;
     int written = 0;
-    int ret;
+    int ret, toread;
+    RTMPPacket *prev_pkt;
 
     written++;
     channel_id = hdr & 0x3F;
@@ -161,6 +185,10 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
         written += channel_id + 1;
         channel_id = AV_RL16(buf) + 64;
     }
+    if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt,
+                                         channel_id)) < 0)
+        return ret;
+    prev_pkt = *prev_pkt_ptr;
     size  = prev_pkt[channel_id].size;
     type  = prev_pkt[channel_id].type;
     extra = prev_pkt[channel_id].extra;
@@ -198,47 +226,88 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
     if (hdr != RTMP_PS_TWELVEBYTES)
         timestamp += prev_pkt[channel_id].timestamp;
 
-    if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
-                                     size)) < 0)
-        return ret;
+    if (!prev_pkt[channel_id].read) {
+        if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,
+                                         size)) < 0)
+            return ret;
+        p->read = written;
+        p->offset = 0;
+        prev_pkt[channel_id].ts_delta   = timestamp -
+                                          prev_pkt[channel_id].timestamp;
+        prev_pkt[channel_id].timestamp  = timestamp;
+    } else {
+        // previous packet in this channel hasn't completed reading
+        RTMPPacket *prev = &prev_pkt[channel_id];
+        p->data          = prev->data;
+        p->size          = prev->size;
+        p->channel_id    = prev->channel_id;
+        p->type          = prev->type;
+        p->ts_delta      = prev->ts_delta;
+        p->extra         = prev->extra;
+        p->offset        = prev->offset;
+        p->read          = prev->read + written;
+        p->timestamp     = prev->timestamp;
+        prev->data       = NULL;
+    }
     p->extra = extra;
     // save history
     prev_pkt[channel_id].channel_id = channel_id;
     prev_pkt[channel_id].type       = type;
     prev_pkt[channel_id].size       = size;
-    prev_pkt[channel_id].ts_delta   = timestamp - prev_pkt[channel_id].timestamp;
-    prev_pkt[channel_id].timestamp  = timestamp;
     prev_pkt[channel_id].extra      = extra;
-    while (size > 0) {
-        int toread = FFMIN(size, chunk_size);
-        if (ffurl_read_complete(h, p->data + offset, toread) != toread) {
-            ff_rtmp_packet_destroy(p);
+    size = size - p->offset;
+
+    toread = FFMIN(size, chunk_size);
+    if (ffurl_read_complete(h, p->data + p->offset, toread) != toread) {
+        ff_rtmp_packet_destroy(p);
+        return AVERROR(EIO);
+    }
+    size      -= toread;
+    p->read   += toread;
+    p->offset += toread;
+
+    if (size > 0) {
+       RTMPPacket *prev = &prev_pkt[channel_id];
+       prev->data = p->data;
+       prev->read = p->read;
+       prev->offset = p->offset;
+       return AVERROR(EAGAIN);
+    }
+
+    prev_pkt[channel_id].read = 0; // read complete; reset if needed
+    return p->read;
+}
+
+int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
+                                 RTMPPacket **prev_pkt, int *nb_prev_pkt,
+                                 uint8_t hdr)
+{
+    while (1) {
+        int ret = rtmp_packet_read_one_chunk(h, p, chunk_size, prev_pkt,
+                                             nb_prev_pkt, hdr);
+        if (ret > 0 || ret != AVERROR(EAGAIN))
+            return ret;
+
+        if (ffurl_read(h, &hdr, 1) != 1)
             return AVERROR(EIO);
-        }
-        size    -= chunk_size;
-        offset  += chunk_size;
-        written += chunk_size;
-        if (size > 0) {
-            if ((ret = ffurl_read_complete(h, &t, 1)) < 0) { // marker
-                ff_rtmp_packet_destroy(p);
-                return ret;
-            }
-            written++;
-            if (t != (0xC0 + channel_id))
-                return -1;
-        }
     }
-    return written;
 }
 
 int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
-                         int chunk_size, RTMPPacket *prev_pkt)
+                         int chunk_size, RTMPPacket **prev_pkt_ptr,
+                         int *nb_prev_pkt)
 {
     uint8_t pkt_hdr[16], *p = pkt_hdr;
     int mode = RTMP_PS_TWELVEBYTES;
     int off = 0;
     int written = 0;
     int ret;
+    RTMPPacket *prev_pkt;
+
+    if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt,
+                                         pkt->channel_id)) < 0)
+        return ret;
+    prev_pkt = *prev_pkt_ptr;
 
     pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
 
@@ -337,30 +406,37 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt)
 int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end)
 {
     const uint8_t *base = data;
+    AMFDataType type;
+    unsigned nb   = -1;
+    int parse_key = 1;
 
     if (data >= data_end)
         return -1;
-    switch (*data++) {
+    switch ((type = *data++)) {
     case AMF_DATA_TYPE_NUMBER:      return 9;
     case AMF_DATA_TYPE_BOOL:        return 2;
     case AMF_DATA_TYPE_STRING:      return 3 + AV_RB16(data);
     case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
     case AMF_DATA_TYPE_NULL:        return 1;
     case AMF_DATA_TYPE_ARRAY:
-        data += 4;
+        parse_key = 0;
+    case AMF_DATA_TYPE_MIXEDARRAY:
+        nb = bytestream_get_be32(&data);
     case AMF_DATA_TYPE_OBJECT:
-        for (;;) {
-            int size = bytestream_get_be16(&data);
+        while (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY) {
             int t;
-            if (!size) {
-                data++;
-                break;
+            if (parse_key) {
+                int size = bytestream_get_be16(&data);
+                if (!size) {
+                    data++;
+                    break;
+                }
+                if (size < 0 || size >= data_end - data)
+                    return -1;
+                data += size;
             }
-            if (data + size >= data_end || data + size < data)
-                return -1;
-            data += size;
             t = ff_amf_tag_size(data, data_end);
-            if (t < 0 || data + t >= data_end)
+            if (t < 0 || t >= data_end - data)
                 return -1;
             data += t;
         }
@@ -389,7 +465,7 @@ int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end,
         int size = bytestream_get_be16(&data);
         if (!size)
             break;
-        if (data + size >= data_end || data + size < data)
+        if (size < 0 || size >= data_end - data)
             return -1;
         data += size;
         if (size == namelen && !memcmp(data-size, name, namelen)) {
@@ -410,7 +486,7 @@ int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end,
             return 0;
         }
         len = ff_amf_tag_size(data, data_end);
-        if (len < 0 || data + len >= data_end || data + len < data)
+        if (len < 0 || len >= data_end - data)
             return -1;
         data += len;
     }
@@ -438,14 +514,17 @@ static const char* rtmp_packet_type(int type)
     }
 }
 
-static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end)
+static void amf_tag_contents(void *ctx, const uint8_t *data,
+                             const uint8_t *data_end)
 {
-    int size;
+    unsigned int size, nb = -1;
     char buf[1024];
+    AMFDataType type;
+    int parse_key = 1;
 
     if (data >= data_end)
         return;
-    switch (*data++) {
+    switch ((type = *data++)) {
     case AMF_DATA_TYPE_NUMBER:
         av_log(ctx, AV_LOG_DEBUG, " number %g\n", av_int2double(AV_RB64(data)));
         return;
@@ -454,12 +533,12 @@ static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *d
         return;
     case AMF_DATA_TYPE_STRING:
     case AMF_DATA_TYPE_LONG_STRING:
-        if (data[-1] == AMF_DATA_TYPE_STRING) {
+        if (type == AMF_DATA_TYPE_STRING) {
             size = bytestream_get_be16(&data);
         } else {
             size = bytestream_get_be32(&data);
         }
-        size = FFMIN(size, 1023);
+        size = FFMIN(size, sizeof(buf) - 1);
         memcpy(buf, data, size);
         buf[size] = 0;
         av_log(ctx, AV_LOG_DEBUG, " string '%s'\n", buf);
@@ -468,26 +547,31 @@ static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *d
         av_log(ctx, AV_LOG_DEBUG, " NULL\n");
         return;
     case AMF_DATA_TYPE_ARRAY:
-        data += 4;
+        parse_key = 0;
+    case AMF_DATA_TYPE_MIXEDARRAY:
+        nb = bytestream_get_be32(&data);
     case AMF_DATA_TYPE_OBJECT:
         av_log(ctx, AV_LOG_DEBUG, " {\n");
-        for (;;) {
-            int size = bytestream_get_be16(&data);
+        while (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY) {
             int t;
-            memcpy(buf, data, size);
-            buf[size] = 0;
-            if (!size) {
-                av_log(ctx, AV_LOG_DEBUG, " }\n");
-                data++;
-                break;
+            if (parse_key) {
+                size = bytestream_get_be16(&data);
+                size = FFMIN(size, sizeof(buf) - 1);
+                if (!size) {
+                    av_log(ctx, AV_LOG_DEBUG, " }\n");
+                    data++;
+                    break;
+                }
+                memcpy(buf, data, size);
+                buf[size] = 0;
+                if (size >= data_end - data)
+                    return;
+                data += size;
+                av_log(ctx, AV_LOG_DEBUG, "  %s: ", buf);
             }
-            if (data + size >= data_end || data + size < data)
-                return;
-            data += size;
-            av_log(ctx, AV_LOG_DEBUG, "  %s: ", buf);
-            ff_amf_tag_contents(ctx, data, data_end);
+            amf_tag_contents(ctx, data, data_end);
             t = ff_amf_tag_size(data, data_end);
-            if (t < 0 || data + t >= data_end)
+            if (t < 0 || t >= data_end - data)
                 return;
             data += t;
         }
@@ -508,7 +592,7 @@ void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p)
         uint8_t *src = p->data, *src_end = p->data + p->size;
         while (src < src_end) {
             int sz;
-            ff_amf_tag_contents(ctx, src, src_end);
+            amf_tag_contents(ctx, src, src_end);
             sz = ff_amf_tag_size(src, src_end);
             if (sz < 0)
                 break;
diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h
index ba6696b..7121d7e 100644
--- a/libavformat/rtmppkt.h
+++ b/libavformat/rtmppkt.h
@@ -1,6 +1,6 @@
 /*
  * RTMP packet utilities
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of Libav.
  *
@@ -36,9 +36,9 @@
 enum RTMPChannel {
     RTMP_NETWORK_CHANNEL = 2,   ///< channel for network-related messages (bandwidth report, ping, etc)
     RTMP_SYSTEM_CHANNEL,        ///< channel for sending server control messages
-    RTMP_SOURCE_CHANNEL,        ///< channel for sending a/v to server
-    RTMP_VIDEO_CHANNEL = 8,     ///< channel for video data
     RTMP_AUDIO_CHANNEL,         ///< channel for audio data
+    RTMP_VIDEO_CHANNEL   = 6,   ///< channel for video data
+    RTMP_SOURCE_CHANNEL  = 8,   ///< channel for a/v invokes
 };
 
 /**
@@ -82,6 +82,8 @@ typedef struct RTMPPacket {
     uint32_t       extra;      ///< probably an additional channel ID used during streaming data
     uint8_t        *data;      ///< packet payload
     int            size;       ///< packet payload size
+    int            offset;     ///< amount of data read so far
+    int            read;       ///< amount read, including headers
 } RTMPPacket;
 
 /**
@@ -112,10 +114,12 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt);
  * @param chunk_size current chunk size
  * @param prev_pkt   previously read packet headers for all channels
  *                   (may be needed for restoring incomplete packet header)
+ * @param nb_prev_pkt number of allocated elements in prev_pkt
  * @return number of bytes read on success, negative value otherwise
  */
 int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
-                        int chunk_size, RTMPPacket *prev_pkt);
+                        int chunk_size, RTMPPacket **prev_pkt,
+                        int *nb_prev_pkt);
 /**
  * Read internal RTMP packet sent by the server.
  *
@@ -124,11 +128,13 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
  * @param chunk_size current chunk size
  * @param prev_pkt   previously read packet headers for all channels
  *                   (may be needed for restoring incomplete packet header)
+ * @param nb_prev_pkt number of allocated elements in prev_pkt
  * @param c          the first byte already read
  * @return number of bytes read on success, negative value otherwise
  */
 int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
-                                 RTMPPacket *prev_pkt, uint8_t c);
+                                 RTMPPacket **prev_pkt, int *nb_prev_pkt,
+                                 uint8_t c);
 
 /**
  * Send RTMP packet to the server.
@@ -138,10 +144,12 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
  * @param chunk_size current chunk size
  * @param prev_pkt   previously sent packet headers for all channels
  *                   (may be used for packet header compressing)
+ * @param nb_prev_pkt number of allocated elements in prev_pkt
  * @return number of bytes written on success, negative value otherwise
  */
 int ff_rtmp_packet_write(URLContext *h, RTMPPacket *p,
-                         int chunk_size, RTMPPacket *prev_pkt);
+                         int chunk_size, RTMPPacket **prev_pkt,
+                         int *nb_prev_pkt);
 
 /**
  * Print information and contents of RTMP packet.
@@ -152,6 +160,16 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *p,
 void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p);
 
 /**
+ * Enlarge the prev_pkt array to fit the given channel
+ *
+ * @param prev_pkt    array with previously sent packet headers
+ * @param nb_prev_pkt number of allocated elements in prev_pkt
+ * @param channel     the channel number that needs to be allocated
+ */
+int ff_rtmp_check_alloc_array(RTMPPacket **prev_pkt, int *nb_prev_pkt,
+                              int channel);
+
+/**
  * @name Functions used to work with the AMF format (which is also used in .flv)
  * @see amf_* funcs in libavformat/flvdec.c
  * @{
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 9989b28..135af82 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -1,6 +1,6 @@
 /*
  * RTMP network protocol
- * Copyright (c) 2009 Kostya Shishkov
+ * Copyright (c) 2009 Konstantin Shishkov
  *
  * This file is part of Libav.
  *
@@ -48,13 +48,12 @@
 #include <zlib.h>
 #endif
 
-//#define DEBUG
-
 #define APP_MAX_LENGTH 128
 #define PLAYPATH_MAX_LENGTH 256
 #define TCURL_MAX_LENGTH 512
 #define FLASHVER_MAX_LENGTH 64
 #define RTMP_PKTDATA_DEFAULT_SIZE 4096
+#define RTMP_HEADER 11
 
 /** RTMP protocol handler state */
 typedef enum {
@@ -62,8 +61,10 @@ typedef enum {
     STATE_HANDSHAKED, ///< client has performed handshake
     STATE_FCPUBLISH,  ///< client FCPublishing stream (for output)
     STATE_PLAYING,    ///< client has started receiving multimedia data from server
+    STATE_SEEKING,    ///< client has started the seek operation. Back on STATE_PLAYING when the time comes
     STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
     STATE_RECEIVING,  ///< received a publish command (for input)
+    STATE_SENDING,    ///< received a play command (for output)
     STATE_STOPPED,    ///< the broadcast has been stopped
 } ClientState;
 
@@ -76,7 +77,8 @@ typedef struct TrackedMethod {
 typedef struct RTMPContext {
     const AVClass *class;
     URLContext*   stream;                     ///< TCP stream used in interactions with RTMP server
-    RTMPPacket    prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets
+    RTMPPacket    *prev_pkt[2];               ///< packet history used when reading and sending packets ([0] for reading, [1] for writing)
+    int           nb_prev_pkt[2];             ///< number of elements in prev_pkt
     int           in_chunk_size;              ///< size of the chunks incoming RTMP packets are divided into
     int           out_chunk_size;             ///< size of the chunks outgoing RTMP packets are divided into
     int           is_input;                   ///< input/output flag
@@ -85,7 +87,7 @@ typedef struct RTMPContext {
     char          *app;                       ///< name of application
     char          *conn;                      ///< append arbitrary AMF data to the Connect message
     ClientState   state;                      ///< current state
-    int           main_channel_id;            ///< an additional channel ID which is used for some invocations
+    int           stream_id;                  ///< ID assigned by the server for the stream
     uint8_t*      flv_data;                   ///< buffer with data for demuxer
     int           flv_size;                   ///< current buffer size
     int           flv_off;                    ///< number of bytes read from current buffer
@@ -95,7 +97,7 @@ typedef struct RTMPContext {
     uint32_t      bytes_read;                 ///< number of bytes read from server
     uint32_t      last_bytes_read;            ///< number of bytes read last reported to server
     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
-    uint8_t       flv_header[11];             ///< partial incoming flv packet header
+    uint8_t       flv_header[RTMP_HEADER];    ///< partial incoming flv packet header
     int           flv_header_bytes;           ///< number of initialized bytes in flv_header
     int           nb_invokes;                 ///< keeps track of invoke messages
     char*         tcurl;                      ///< url of the target stream
@@ -150,15 +152,16 @@ static const uint8_t rtmp_server_key[] = {
 
 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
 {
-    void *ptr;
+    int err;
 
     if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
         rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
-        ptr = av_realloc(rt->tracked_methods,
-                         rt->tracked_methods_size * sizeof(*rt->tracked_methods));
-        if (!ptr)
-            return AVERROR(ENOMEM);
-        rt->tracked_methods = ptr;
+        if ((err = av_reallocp(&rt->tracked_methods, rt->tracked_methods_size *
+                               sizeof(*rt->tracked_methods))) < 0) {
+            rt->nb_tracked_methods = 0;
+            rt->tracked_methods_size = 0;
+            return err;
+        }
     }
 
     rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
@@ -236,7 +239,7 @@ static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
     }
 
     ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
-                               rt->prev_pkt[1]);
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
 fail:
     ff_rtmp_packet_destroy(pkt);
     return ret;
@@ -406,7 +409,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
     GetByteContext gbc;
 
     if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
-                                   rt->prev_pkt[1])) < 0)
+                                   &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
         return ret;
     cp = pkt.data;
     bytestream2_init(&gbc, cp, pkt.size);
@@ -442,7 +445,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
     bytestream_put_be32(&p, rt->server_bw);
     pkt.size = p - pkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
-                               rt->prev_pkt[1]);
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
     if (ret < 0)
         return ret;
@@ -455,7 +458,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
     bytestream_put_byte(&p, 2); // dynamic
     pkt.size = p - pkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
-                               rt->prev_pkt[1]);
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
     if (ret < 0)
         return ret;
@@ -469,7 +472,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
     bytestream_put_be16(&p, 0); // 0 -> Stream Begin
     bytestream_put_be32(&p, 0);
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
-                               rt->prev_pkt[1]);
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
     if (ret < 0)
         return ret;
@@ -482,7 +485,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
     p = pkt.data;
     bytestream_put_be32(&p, rt->out_chunk_size);
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
-                               rt->prev_pkt[1]);
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
     if (ret < 0)
         return ret;
@@ -517,7 +520,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
 
     pkt.size = p - pkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
-                               rt->prev_pkt[1]);
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
     if (ret < 0)
         return ret;
@@ -532,7 +535,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
     ff_amf_write_number(&p, 8192);
     pkt.size = p - pkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
-                               rt->prev_pkt[1]);
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
     ff_rtmp_packet_destroy(&pkt);
 
     return ret;
@@ -655,7 +658,7 @@ static int gen_delete_stream(URLContext *s, RTMPContext *rt)
     ff_amf_write_string(&p, "deleteStream");
     ff_amf_write_number(&p, ++rt->nb_invokes);
     ff_amf_write_null(&p);
-    ff_amf_write_number(&p, rt->main_channel_id);
+    ff_amf_write_number(&p, rt->stream_id);
 
     return rtmp_send_packet(rt, &pkt, 0);
 }
@@ -675,7 +678,7 @@ static int gen_buffer_time(URLContext *s, RTMPContext *rt)
 
     p = pkt.data;
     bytestream_put_be16(&p, 3);
-    bytestream_put_be32(&p, rt->main_channel_id);
+    bytestream_put_be32(&p, rt->stream_id);
     bytestream_put_be32(&p, rt->client_buffer_time);
 
     return rtmp_send_packet(rt, &pkt, 0);
@@ -693,18 +696,41 @@ static int gen_play(URLContext *s, RTMPContext *rt)
 
     av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
 
-    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE,
+    if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
                                      0, 29 + strlen(rt->playpath))) < 0)
         return ret;
 
-    pkt.extra = rt->main_channel_id;
+    pkt.extra = rt->stream_id;
 
     p = pkt.data;
     ff_amf_write_string(&p, "play");
     ff_amf_write_number(&p, ++rt->nb_invokes);
     ff_amf_write_null(&p);
     ff_amf_write_string(&p, rt->playpath);
-    ff_amf_write_number(&p, rt->live);
+    ff_amf_write_number(&p, rt->live * 1000);
+
+    return rtmp_send_packet(rt, &pkt, 1);
+}
+
+static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
+{
+    RTMPPacket pkt;
+    uint8_t *p;
+    int ret;
+
+    av_log(s, AV_LOG_DEBUG, "Sending seek command for timestamp %"PRId64"\n",
+           timestamp);
+
+    if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 26)) < 0)
+        return ret;
+
+    pkt.extra = rt->stream_id;
+
+    p = pkt.data;
+    ff_amf_write_string(&p, "seek");
+    ff_amf_write_number(&p, 0); //no tracking back responses
+    ff_amf_write_null(&p); //as usual, the first null param
+    ff_amf_write_number(&p, timestamp); //where we want to jump
 
     return rtmp_send_packet(rt, &pkt, 1);
 }
@@ -724,7 +750,7 @@ static int gen_publish(URLContext *s, RTMPContext *rt)
                                      0, 30 + strlen(rt->playpath))) < 0)
         return ret;
 
-    pkt.extra = rt->main_channel_id;
+    pkt.extra = rt->stream_id;
 
     p = pkt.data;
     ff_amf_write_string(&p, "publish");
@@ -1145,7 +1171,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
     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. */
@@ -1223,7 +1249,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
         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,
@@ -1253,7 +1279,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
         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,
@@ -1265,13 +1291,13 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
                                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,
@@ -1289,7 +1315,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
                                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;
@@ -1326,7 +1352,7 @@ static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
     int inoutsize;
 
     AV_WB32(arraydata, first_int);
-    AV_WB32(arraydata + 4, first_int);
+    AV_WB32(arraydata + 4, second_int);
     inoutsize = ffurl_write(rt->stream, arraydata,
                             RTMP_HANDSHAKE_PACKET_SIZE);
     if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
@@ -1375,8 +1401,6 @@ static int rtmp_server_handshake(URLContext *s, RTMPContext *rt)
         av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
         return ret;
     }
-    if (zeroes)
-        av_log(s, AV_LOG_WARNING, "Erroneous C1 Message zero != 0\n");
     /* Send S1 */
     /* By now same epoch will be sent */
     hs_my_epoch = hs_epoch;
@@ -1432,7 +1456,7 @@ static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
         /* Send the same chunk size change packet back to the server,
          * setting the outgoing chunk size to the same as the incoming one. */
         if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
-                                        rt->prev_pkt[1])) < 0)
+                                        &rt->prev_pkt[1], &rt->nb_prev_pkt[1])) < 0)
             return ret;
         rt->out_chunk_size = AV_RB32(pkt->data);
     }
@@ -1590,6 +1614,8 @@ static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
     av_md5_update(md5, method, strlen(method));
     av_md5_update(md5, ":/", 2);
     av_md5_update(md5, rt->app, strlen(rt->app));
+    if (!strchr(rt->app, '/'))
+        av_md5_update(md5, "/_definst_", strlen("/_definst_"));
     av_md5_final(md5, hash);
     ff_data_to_hex(hashstr2, hash, 16, 1);
     hashstr2[32] = '\0';
@@ -1693,7 +1719,7 @@ static int handle_connect_error(URLContext *s, const char *desc)
     }
 
     if (!strcmp(authmod, "adobe")) {
-        if ((ret = do_adobe_auth(rt, user, salt, challenge, opaque)) < 0)
+        if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
             return ret;
     } else {
         if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
@@ -1740,13 +1766,84 @@ static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
     return ret;
 }
 
+static int write_begin(URLContext *s)
+{
+    RTMPContext *rt = s->priv_data;
+    PutByteContext pbc;
+    RTMPPacket spkt = { 0 };
+    int ret;
+
+    // Send Stream Begin 1
+    if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
+                                     RTMP_PT_PING, 0, 6)) < 0) {
+        av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
+        return ret;
+    }
+
+    bytestream2_init_writer(&pbc, spkt.data, spkt.size);
+    bytestream2_put_be16(&pbc, 0);          // 0 -> Stream Begin
+    bytestream2_put_be32(&pbc, rt->nb_streamid);
+
+    ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
+
+    ff_rtmp_packet_destroy(&spkt);
+
+    return ret;
+}
+
+static int write_status(URLContext *s, RTMPPacket *pkt,
+                        const char *status, const char *filename)
+{
+    RTMPContext *rt = s->priv_data;
+    RTMPPacket spkt = { 0 };
+    char statusmsg[128];
+    uint8_t *pp;
+    int ret;
+
+    if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
+                                     RTMP_PT_INVOKE, 0,
+                                     RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
+        av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
+        return ret;
+    }
+
+    pp = spkt.data;
+    spkt.extra = pkt->extra;
+    ff_amf_write_string(&pp, "onStatus");
+    ff_amf_write_number(&pp, 0);
+    ff_amf_write_null(&pp);
+
+    ff_amf_write_object_start(&pp);
+    ff_amf_write_field_name(&pp, "level");
+    ff_amf_write_string(&pp, "status");
+    ff_amf_write_field_name(&pp, "code");
+    ff_amf_write_string(&pp, status);
+    ff_amf_write_field_name(&pp, "description");
+    snprintf(statusmsg, sizeof(statusmsg),
+             "%s is now published", filename);
+    ff_amf_write_string(&pp, statusmsg);
+    ff_amf_write_field_name(&pp, "details");
+    ff_amf_write_string(&pp, filename);
+    ff_amf_write_field_name(&pp, "clientid");
+    snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
+    ff_amf_write_string(&pp, statusmsg);
+    ff_amf_write_object_end(&pp);
+
+    spkt.size = pp - spkt.data;
+    ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
+    ff_rtmp_packet_destroy(&spkt);
+
+    return ret;
+}
+
 static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
 {
     RTMPContext *rt = s->priv_data;
     double seqnum;
     char filename[64];
     char command[64];
-    char statusmsg[128];
     int stringlen;
     char *pchar;
     const uint8_t *p = pkt->data;
@@ -1799,52 +1896,20 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
         pp = spkt.data;
         ff_amf_write_string(&pp, "onFCPublish");
     } else if (!strcmp(command, "publish")) {
-        PutByteContext pbc;
-        // Send Stream Begin 1
-        if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
-                                         RTMP_PT_PING, 0, 6)) < 0) {
-            av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
-            return ret;
-        }
-        pp = spkt.data;
-        bytestream2_init_writer(&pbc, pp, spkt.size);
-        bytestream2_put_be16(&pbc, 0);          // 0 -> Stream Begin
-        bytestream2_put_be32(&pbc, rt->nb_streamid);
-        ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
-                                   rt->prev_pkt[1]);
-        ff_rtmp_packet_destroy(&spkt);
+        ret = write_begin(s);
         if (ret < 0)
             return ret;
 
         // Send onStatus(NetStream.Publish.Start)
-        if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
-                                         RTMP_PT_INVOKE, 0,
-                                         RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
-            av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
+        return write_status(s, pkt, "NetStream.Publish.Start",
+                           filename);
+    } else if (!strcmp(command, "play")) {
+        ret = write_begin(s);
+        if (ret < 0)
             return ret;
-        }
-        spkt.extra = pkt->extra;
-        pp = spkt.data;
-        ff_amf_write_string(&pp, "onStatus");
-        ff_amf_write_number(&pp, 0);
-        ff_amf_write_null(&pp);
-
-        ff_amf_write_object_start(&pp);
-        ff_amf_write_field_name(&pp, "level");
-        ff_amf_write_string(&pp, "status");
-        ff_amf_write_field_name(&pp, "code");
-        ff_amf_write_string(&pp, "NetStream.Publish.Start");
-        ff_amf_write_field_name(&pp, "description");
-        snprintf(statusmsg, sizeof(statusmsg),
-                 "%s is now published", filename);
-        ff_amf_write_string(&pp, statusmsg);
-        ff_amf_write_field_name(&pp, "details");
-        ff_amf_write_string(&pp, filename);
-        ff_amf_write_field_name(&pp, "clientid");
-        snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
-        ff_amf_write_string(&pp, statusmsg);
-        ff_amf_write_object_end(&pp);
-
+        rt->state = STATE_SENDING;
+        return write_status(s, pkt, "NetStream.Play.Start",
+                            filename);
     } else {
         if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
                                          RTMP_PT_INVOKE, 0,
@@ -1868,7 +1933,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
     }
     spkt.size = pp - spkt.data;
     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
-                               rt->prev_pkt[1]);
+                               &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
     ff_rtmp_packet_destroy(&spkt);
     return ret;
 }
@@ -1918,7 +1983,7 @@ static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
         if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
             av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
         } else {
-            rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
+            rt->stream_id = av_int2double(AV_RB64(pkt->data + 21));
         }
 
         if (!rt->is_input) {
@@ -1941,7 +2006,7 @@ static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
 {
     RTMPContext *rt = s->priv_data;
     const uint8_t *data_end = pkt->data + pkt->size;
-    const uint8_t *ptr = pkt->data + 11;
+    const uint8_t *ptr = pkt->data + RTMP_HEADER;
     uint8_t tmpstr[256];
     int i, t;
 
@@ -1954,8 +2019,12 @@ static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
 
     t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
     if (!t && !strcmp(tmpstr, "error")) {
-        if (!ff_amf_get_field_value(ptr, data_end,
-                                    "description", tmpstr, sizeof(tmpstr)))
+        t = ff_amf_get_field_value(ptr, data_end,
+                                   "description", tmpstr, sizeof(tmpstr));
+        if (t || !tmpstr[0])
+            t = ff_amf_get_field_value(ptr, data_end, "code",
+                                       tmpstr, sizeof(tmpstr));
+        if (!t)
             av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
         return -1;
     }
@@ -1965,6 +2034,7 @@ static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
     if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
     if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
     if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
+    if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
 
     return 0;
 }
@@ -1990,6 +2060,7 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt)
     } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
                ff_amf_match_string(pkt->data, pkt->size, "FCPublish")     ||
                ff_amf_match_string(pkt->data, pkt->size, "publish")       ||
+               ff_amf_match_string(pkt->data, pkt->size, "play")          ||
                ff_amf_match_string(pkt->data, pkt->size, "_checkbw")      ||
                ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
         if ((ret = send_invoke_response(s, pkt)) < 0)
@@ -1999,65 +2070,75 @@ static int handle_invoke(URLContext *s, RTMPPacket *pkt)
     return ret;
 }
 
-static int handle_notify(URLContext *s, RTMPPacket *pkt) {
+static int update_offset(RTMPContext *rt, int size)
+{
+    int old_flv_size;
+
+    // generate packet header and put data into buffer for FLV demuxer
+    if (rt->flv_off < rt->flv_size) {
+        // There is old unread data in the buffer, thus append at the end
+        old_flv_size  = rt->flv_size;
+        rt->flv_size += size;
+    } else {
+        // All data has been read, write the new data at the start of the buffer
+        old_flv_size = 0;
+        rt->flv_size = size;
+        rt->flv_off  = 0;
+    }
+
+    return old_flv_size;
+}
+
+static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
+{
+    int old_flv_size, ret;
+    PutByteContext pbc;
+    const uint8_t *data = pkt->data + skip;
+    const int size      = pkt->size - skip;
+    uint32_t ts         = pkt->timestamp;
+
+    old_flv_size = update_offset(rt, size + 15);
+
+    if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
+        rt->flv_size = rt->flv_off = 0;
+        return ret;
+    }
+    bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size);
+    bytestream2_skip_p(&pbc, old_flv_size);
+    bytestream2_put_byte(&pbc, pkt->type);
+    bytestream2_put_be24(&pbc, size);
+    bytestream2_put_be24(&pbc, ts);
+    bytestream2_put_byte(&pbc, ts >> 24);
+    bytestream2_put_be24(&pbc, 0);
+    bytestream2_put_buffer(&pbc, data, size);
+    bytestream2_put_be32(&pbc, 0);
+
+    return 0;
+}
+
+static int handle_notify(URLContext *s, RTMPPacket *pkt)
+{
     RTMPContext *rt  = s->priv_data;
-    const uint8_t *p = NULL;
-    uint8_t *cp      = NULL;
     uint8_t commandbuffer[64];
     char statusmsg[128];
-    int stringlen;
+    int stringlen, ret, skip = 0;
     GetByteContext gbc;
-    PutByteContext pbc;
-    uint32_t ts;
-    int old_flv_size;
-    const uint8_t *datatowrite;
-    unsigned datatowritelength;
 
-    p = pkt->data;
-    bytestream2_init(&gbc, p, pkt->size);
+    bytestream2_init(&gbc, pkt->data, pkt->size);
     if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
                            &stringlen))
         return AVERROR_INVALIDDATA;
+
+    // Skip the @setDataFrame string and validate it is a notification
     if (!strcmp(commandbuffer, "@setDataFrame")) {
-        datatowrite       = gbc.buffer;
-        datatowritelength = bytestream2_get_bytes_left(&gbc);
-        if (ff_amf_read_string(&gbc, statusmsg,
-                               sizeof(statusmsg), &stringlen))
+        skip = gbc.buffer - pkt->data;
+        ret = ff_amf_read_string(&gbc, statusmsg,
+                                 sizeof(statusmsg), &stringlen);
+        if (ret < 0)
             return AVERROR_INVALIDDATA;
-        if (strcmp(statusmsg, "onMetaData")) {
-            av_log(s, AV_LOG_INFO, "Expecting onMetadata but got %s\n",
-                   statusmsg);
-            return 0;
-        }
-
-        /* Provide ECMAArray to flv */
-        ts = pkt->timestamp;
-
-        // generate packet header and put data into buffer for FLV demuxer
-        if (rt->flv_off < rt->flv_size) {
-            old_flv_size  = rt->flv_size;
-            rt->flv_size += datatowritelength + 15;
-        } else {
-            old_flv_size = 0;
-            rt->flv_size = datatowritelength + 15;
-            rt->flv_off  = 0;
-        }
-
-        cp = av_realloc(rt->flv_data, rt->flv_size);
-        if (!cp)
-            return AVERROR(ENOMEM);
-        rt->flv_data = cp;
-        bytestream2_init_writer(&pbc, cp, rt->flv_size);
-        bytestream2_skip_p(&pbc, old_flv_size);
-        bytestream2_put_byte(&pbc, pkt->type);
-        bytestream2_put_be24(&pbc, datatowritelength);
-        bytestream2_put_be24(&pbc, ts);
-        bytestream2_put_byte(&pbc, ts >> 24);
-        bytestream2_put_be24(&pbc, 0);
-        bytestream2_put_buffer(&pbc, datatowrite, datatowritelength);
-        bytestream2_put_be32(&pbc, 0);
     }
-    return 0;
+
+    return append_flv_data(rt, pkt, skip);
 }
 
 /**
@@ -2111,6 +2192,55 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
     return 0;
 }
 
+static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
+{
+    int ret, old_flv_size, type;
+    const uint8_t *next;
+    uint8_t *p;
+    uint32_t size;
+    uint32_t ts, cts, pts = 0;
+
+    old_flv_size = update_offset(rt, pkt->size);
+
+    if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
+        rt->flv_size = rt->flv_off = 0;
+        return ret;
+    }
+
+    next = pkt->data;
+    p    = rt->flv_data + old_flv_size;
+
+    /* copy data while rewriting timestamps */
+    ts = pkt->timestamp;
+
+    while (next - pkt->data < pkt->size - RTMP_HEADER) {
+        type = bytestream_get_byte(&next);
+        size = bytestream_get_be24(&next);
+        cts  = bytestream_get_be24(&next);
+        cts |= bytestream_get_byte(&next) << 24;
+        if (!pts)
+            pts = cts;
+        ts += cts - pts;
+        pts = cts;
+        if (size + 3 + 4 > pkt->data + pkt->size - next)
+            break;
+        bytestream_put_byte(&p, type);
+        bytestream_put_be24(&p, size);
+        bytestream_put_be24(&p, ts);
+        bytestream_put_byte(&p, ts >> 24);
+        memcpy(p, next, size + 3 + 4);
+        next += size + 3 + 4;
+        p    += size + 3 + 4;
+    }
+    if (p != rt->flv_data + rt->flv_size) {
+        av_log(NULL, AV_LOG_WARNING, "Incomplete flv packets in "
+                                     "RTMP_PT_METADATA packet\n");
+        rt->flv_size = p - rt->flv_data;
+    }
+
+    return 0;
+}
+
 /**
  * Interact with the server by receiving and sending RTMP packets until
  * there is some significant data (media data or expected status notification).
@@ -2126,10 +2256,6 @@ static int get_packet(URLContext *s, int for_header)
 {
     RTMPContext *rt = s->priv_data;
     int ret;
-    uint8_t *p;
-    const uint8_t *next;
-    uint32_t size;
-    uint32_t ts, cts, pts=0;
 
     if (rt->state == STATE_STOPPED)
         return AVERROR_EOF;
@@ -2137,7 +2263,8 @@ static int get_packet(URLContext *s, int for_header)
     for (;;) {
         RTMPPacket rpkt = { 0 };
         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
-                                       rt->in_chunk_size, rt->prev_pkt[0])) <= 0) {
+                                       rt->in_chunk_size, &rt->prev_pkt[0],
+                                       &rt->nb_prev_pkt[0])) <= 0) {
             if (ret == 0) {
                 return AVERROR(EAGAIN);
             } else {
@@ -2153,6 +2280,17 @@ static int get_packet(URLContext *s, int for_header)
         }
 
         ret = rtmp_parse_result(s, rt, &rpkt);
+
+        // At this point we must check if we are in the seek state and continue
+        // with the next packet. handle_invoke will get us out of this state
+        // when the right message is encountered
+        if (rt->state == STATE_SEEKING) {
+            ff_rtmp_packet_destroy(&rpkt);
+            // We continue, let the natural flow of things happen:
+            // AVERROR(EAGAIN) or handle_invoke gets us out of here
+            continue;
+        }
+
         if (ret < 0) {//serious error in current packet
             ff_rtmp_packet_destroy(&rpkt);
             return ret;
@@ -2167,6 +2305,7 @@ static int get_packet(URLContext *s, int for_header)
         }
         if (for_header && (rt->state == STATE_PLAYING    ||
                            rt->state == STATE_PUBLISHING ||
+                           rt->state == STATE_SENDING    ||
                            rt->state == STATE_RECEIVING)) {
             ff_rtmp_packet_destroy(&rpkt);
             return 0;
@@ -2175,55 +2314,16 @@ static int get_packet(URLContext *s, int for_header)
             ff_rtmp_packet_destroy(&rpkt);
             continue;
         }
-        if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
-           (rpkt.type == RTMP_PT_NOTIFY &&
-            ff_amf_match_string(rpkt.data, rpkt.size, "onMetaData"))) {
-            ts = rpkt.timestamp;
-
-            // generate packet header and put data into buffer for FLV demuxer
-            rt->flv_off  = 0;
-            rt->flv_size = rpkt.size + 15;
-            rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
-            bytestream_put_byte(&p, rpkt.type);
-            bytestream_put_be24(&p, rpkt.size);
-            bytestream_put_be24(&p, ts);
-            bytestream_put_byte(&p, ts >> 24);
-            bytestream_put_be24(&p, 0);
-            bytestream_put_buffer(&p, rpkt.data, rpkt.size);
-            bytestream_put_be32(&p, 0);
+        if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO) {
+            ret = append_flv_data(rt, &rpkt, 0);
             ff_rtmp_packet_destroy(&rpkt);
-            return 0;
+            return ret;
         } else if (rpkt.type == RTMP_PT_NOTIFY) {
             ret = handle_notify(s, &rpkt);
             ff_rtmp_packet_destroy(&rpkt);
-            if (ret) {
-                av_log(s, AV_LOG_ERROR, "Handle notify error\n");
-                return ret;
-            }
-            return 0;
+            return ret;
         } else if (rpkt.type == RTMP_PT_METADATA) {
-            // we got raw FLV data, make it available for FLV demuxer
-            rt->flv_off  = 0;
-            rt->flv_size = rpkt.size;
-            rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
-            /* rewrite timestamps */
-            next = rpkt.data;
-            ts = rpkt.timestamp;
-            while (next - rpkt.data < rpkt.size - 11) {
-                next++;
-                size = bytestream_get_be24(&next);
-                p=next;
-                cts = bytestream_get_be24(&next);
-                cts |= bytestream_get_byte(&next) << 24;
-                if (pts==0)
-                    pts=cts;
-                ts += cts - pts;
-                pts = cts;
-                bytestream_put_be24(&p, ts);
-                bytestream_put_byte(&p, ts >> 24);
-                next += size + 3 + 4;
-            }
-            memcpy(rt->flv_data, rpkt.data, rpkt.size);
+            ret = handle_metadata(rt, &rpkt);
             ff_rtmp_packet_destroy(&rpkt);
             return 0;
         }
@@ -2234,7 +2334,7 @@ static int get_packet(URLContext *s, int for_header)
 static int rtmp_close(URLContext *h)
 {
     RTMPContext *rt = h->priv_data;
-    int ret = 0;
+    int ret = 0, i, j;
 
     if (!rt->is_input) {
         rt->flv_data = NULL;
@@ -2245,6 +2345,11 @@ static int rtmp_close(URLContext *h)
     }
     if (rt->state > STATE_HANDSHAKED)
         ret = gen_delete_stream(h, rt);
+    for (i = 0; i < 2; i++) {
+        for (j = 0; j < rt->nb_prev_pkt[i]; j++)
+            ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
+        av_freep(&rt->prev_pkt[i]);
+    }
 
     free_tracked_methods(rt);
     av_freep(&rt->flv_data);
@@ -2280,6 +2385,13 @@ static int rtmp_open(URLContext *s, const char *uri, int flags)
                  hostname, sizeof(hostname), &port,
                  path, sizeof(path), s->filename);
 
+    if (strchr(path, ' ')) {
+        av_log(s, AV_LOG_WARNING,
+               "Detected librtmp style URL parameters, these aren't supported "
+               "by the libavformat internal RTMP handler currently enabled. "
+               "See the documentation for the correct way to pass parameters.\n");
+    }
+
     if (auth[0]) {
         char *ptr = strchr(auth, ':');
         if (ptr) {
@@ -2445,29 +2557,33 @@ reconnect:
     } else {
         if (read_connect(s, s->priv_data) < 0)
             goto fail;
-        rt->is_input = 1;
     }
 
     do {
         ret = get_packet(s, 1);
-    } while (ret == EAGAIN);
+    } while (ret == AVERROR(EAGAIN));
     if (ret < 0)
         goto fail;
 
     if (rt->do_reconnect) {
+        int i;
         ffurl_close(rt->stream);
         rt->stream       = NULL;
         rt->do_reconnect = 0;
         rt->nb_invokes   = 0;
-        memset(rt->prev_pkt, 0, sizeof(rt->prev_pkt));
+        for (i = 0; i < 2; i++)
+            memset(rt->prev_pkt[i], 0,
+                   sizeof(**rt->prev_pkt) * rt->nb_prev_pkt[i]);
         free_tracked_methods(rt);
         goto reconnect;
     }
 
     if (rt->is_input) {
+        int err;
         // generate FLV header for demuxer
         rt->flv_size = 13;
-        rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
+        if ((err = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
+            return err;
         rt->flv_off  = 0;
         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
     } else {
@@ -2514,6 +2630,26 @@ static int rtmp_read(URLContext *s, uint8_t *buf, int size)
     return orig_size;
 }
 
+static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
+                         int flags)
+{
+    RTMPContext *rt = s->priv_data;
+    int ret;
+    av_log(s, AV_LOG_DEBUG,
+           "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
+           stream_index, timestamp, flags);
+    if ((ret = gen_seek(s, rt, timestamp)) < 0) {
+        av_log(s, AV_LOG_ERROR,
+               "Unable to send seek command on stream index %d at timestamp "
+               "%"PRId64" with flags %08x\n",
+               stream_index, timestamp, flags);
+        return ret;
+    }
+    rt->flv_off = rt->flv_size;
+    rt->state = STATE_SEEKING;
+    return timestamp;
+}
+
 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
 {
     RTMPContext *rt = s->priv_data;
@@ -2533,13 +2669,14 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
             continue;
         }
 
-        if (rt->flv_header_bytes < 11) {
+        if (rt->flv_header_bytes < RTMP_HEADER) {
             const uint8_t *header = rt->flv_header;
-            int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
+            int copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
+            int channel = RTMP_AUDIO_CHANNEL;
             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
             rt->flv_header_bytes += copy;
             size_temp            -= copy;
-            if (rt->flv_header_bytes < 11)
+            if (rt->flv_header_bytes < RTMP_HEADER)
                 break;
 
             pkttype = bytestream_get_byte(&header);
@@ -2549,20 +2686,27 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
             bytestream_get_be24(&header);
             rt->flv_size = pktsize;
 
+            if (pkttype == RTMP_PT_VIDEO)
+                channel = RTMP_VIDEO_CHANNEL;
+
             //force 12bytes header
             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
                 pkttype == RTMP_PT_NOTIFY) {
                 if (pkttype == RTMP_PT_NOTIFY)
                     pktsize += 16;
-                rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
+                if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
+                                                     &rt->nb_prev_pkt[1],
+                                                     channel)) < 0)
+                    return ret;
+                rt->prev_pkt[1][channel].channel_id = 0;
             }
 
             //this can be a big packet, it's better to send it right here
-            if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
+            if ((ret = ff_rtmp_packet_create(&rt->out_pkt, channel,
                                              pkttype, ts, pktsize)) < 0)
                 return ret;
 
-            rt->out_pkt.extra = rt->main_channel_id;
+            rt->out_pkt.extra = rt->stream_id;
             rt->flv_data = rt->out_pkt.data;
 
             if (pkttype == RTMP_PT_NOTIFY)
@@ -2614,7 +2758,8 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
 
         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
                                                 rt->in_chunk_size,
-                                                rt->prev_pkt[0], c)) <= 0)
+                                                &rt->prev_pkt[0],
+                                                &rt->nb_prev_pkt[0], c)) <= 0)
              return ret;
 
         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
@@ -2649,6 +2794,7 @@ static const AVOption rtmp_options[] = {
     {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
     {"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
     {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
+    {"listen",      "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
     {"timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1",  OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
     { NULL },
 };
@@ -2665,6 +2811,7 @@ URLProtocol ff_##flavor##_protocol = {           \
     .name           = #flavor,                   \
     .url_open       = rtmp_open,                 \
     .url_read       = rtmp_read,                 \
+    .url_read_seek  = rtmp_seek,                 \
     .url_write      = rtmp_write,                \
     .url_close      = rtmp_close,                \
     .priv_data_size = sizeof(RTMPContext),       \
diff --git a/libavformat/rtp.c b/libavformat/rtp.c
index eab8271..0a3c411 100644
--- a/libavformat/rtp.c
+++ b/libavformat/rtp.c
@@ -19,29 +19,25 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <libavutil/opt.h>
+#include "libavutil/opt.h"
 #include "avformat.h"
 
 #include "rtp.h"
 
-//#define DEBUG
-
 /* from http://www.iana.org/assignments/rtp-parameters last updated 05 January 2005 */
 /* payload types >= 96 are dynamic;
  * payload types between 72 and 76 are reserved for RTCP conflict avoidance;
  * all the other payload types not present in the table are unassigned or
  * reserved
  */
-static const struct
-{
+static const struct {
     int pt;
     const char enc_name[6];
     enum AVMediaType codec_type;
     enum AVCodecID codec_id;
     int clock_rate;
     int audio_channels;
-} AVRtpPayloadTypes[]=
-{
+} rtp_payload_types[] = {
   {0, "PCMU",        AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_PCM_MULAW, 8000, 1},
   {3, "GSM",         AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_NONE, 8000, 1},
   {4, "G723",        AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_G723_1, 8000, 1},
@@ -75,15 +71,15 @@ int ff_rtp_get_codec_info(AVCodecContext *codec, int payload_type)
 {
     int i = 0;
 
-    for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++)
-        if (AVRtpPayloadTypes[i].pt == payload_type) {
-            if (AVRtpPayloadTypes[i].codec_id != AV_CODEC_ID_NONE) {
-                codec->codec_type = AVRtpPayloadTypes[i].codec_type;
-                codec->codec_id = AVRtpPayloadTypes[i].codec_id;
-                if (AVRtpPayloadTypes[i].audio_channels > 0)
-                    codec->channels = AVRtpPayloadTypes[i].audio_channels;
-                if (AVRtpPayloadTypes[i].clock_rate > 0)
-                    codec->sample_rate = AVRtpPayloadTypes[i].clock_rate;
+    for (i = 0; rtp_payload_types[i].pt >= 0; i++)
+        if (rtp_payload_types[i].pt == payload_type) {
+            if (rtp_payload_types[i].codec_id != AV_CODEC_ID_NONE) {
+                codec->codec_type = rtp_payload_types[i].codec_type;
+                codec->codec_id = rtp_payload_types[i].codec_id;
+                if (rtp_payload_types[i].audio_channels > 0)
+                    codec->channels = rtp_payload_types[i].audio_channels;
+                if (rtp_payload_types[i].clock_rate > 0)
+                    codec->sample_rate = rtp_payload_types[i].clock_rate;
                 return 0;
             }
         }
@@ -105,8 +101,8 @@ int ff_rtp_get_payload_type(AVFormatContext *fmt,
     }
 
     /* static payload type */
-    for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
-        if (AVRtpPayloadTypes[i].codec_id == codec->codec_id) {
+    for (i = 0; rtp_payload_types[i].pt >= 0; ++i)
+        if (rtp_payload_types[i].codec_id == codec->codec_id) {
             if (codec->codec_id == AV_CODEC_ID_H263 && (!fmt || !fmt->oformat ||
                 !fmt->oformat->priv_class || !fmt->priv_data ||
                 !av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190")))
@@ -115,14 +111,14 @@ int ff_rtp_get_payload_type(AVFormatContext *fmt,
              * see section 4.5.2 in RFC 3551. */
             if (codec->codec_id == AV_CODEC_ID_ADPCM_G722 &&
                 codec->sample_rate == 16000 && codec->channels == 1)
-                return AVRtpPayloadTypes[i].pt;
+                return rtp_payload_types[i].pt;
             if (codec->codec_type == AVMEDIA_TYPE_AUDIO &&
-                ((AVRtpPayloadTypes[i].clock_rate > 0 &&
-                  codec->sample_rate != AVRtpPayloadTypes[i].clock_rate) ||
-                 (AVRtpPayloadTypes[i].audio_channels > 0 &&
-                  codec->channels != AVRtpPayloadTypes[i].audio_channels)))
+                ((rtp_payload_types[i].clock_rate > 0 &&
+                  codec->sample_rate != rtp_payload_types[i].clock_rate) ||
+                 (rtp_payload_types[i].audio_channels > 0 &&
+                  codec->channels != rtp_payload_types[i].audio_channels)))
                 continue;
-            return AVRtpPayloadTypes[i].pt;
+            return rtp_payload_types[i].pt;
         }
 
     if (idx < 0)
@@ -136,10 +132,9 @@ const char *ff_rtp_enc_name(int payload_type)
 {
     int i;
 
-    for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++)
-        if (AVRtpPayloadTypes[i].pt == payload_type) {
-            return AVRtpPayloadTypes[i].enc_name;
-        }
+    for (i = 0; rtp_payload_types[i].pt >= 0; i++)
+        if (rtp_payload_types[i].pt == payload_type)
+            return rtp_payload_types[i].enc_name;
 
     return "";
 }
@@ -148,10 +143,9 @@ enum AVCodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type)
 {
     int i;
 
-    for (i = 0; AVRtpPayloadTypes[i].pt >= 0; i++)
-        if (!strcmp(buf, AVRtpPayloadTypes[i].enc_name) && (codec_type == AVRtpPayloadTypes[i].codec_type)){
-            return AVRtpPayloadTypes[i].codec_id;
-        }
+    for (i = 0; rtp_payload_types[i].pt >= 0; i++)
+        if (!strcmp(buf, rtp_payload_types[i].enc_name) && (codec_type == rtp_payload_types[i].codec_type))
+            return rtp_payload_types[i].codec_id;
 
     return AV_CODEC_ID_NONE;
 }
diff --git a/libavformat/rtp.h b/libavformat/rtp.h
index f8d406e..feaf167 100644
--- a/libavformat/rtp.h
+++ b/libavformat/rtp.h
@@ -23,6 +23,7 @@
 
 #include "libavformat/avformat.h"
 #include "libavcodec/avcodec.h"
+#include "libavutil/mathematics.h"
 
 /**
  * Return the payload type for a given stream used in the given format context.
@@ -109,4 +110,6 @@ enum RTCPType {
 #define RTP_PT_IS_RTCP(x) (((x) >= RTCP_FIR && (x) <= RTCP_IJ) || \
                            ((x) >= RTCP_SR  && (x) <= RTCP_TOKEN))
 
+#define NTP_TO_RTP_FORMAT(x) av_rescale((x), INT64_C(1) << 32, 1000000)
+
 #endif /* AVFORMAT_RTP_H */
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 08150b7..3984489 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -24,12 +24,14 @@
 #include "libavutil/time.h"
 #include "libavcodec/get_bits.h"
 #include "avformat.h"
-#include "mpegts.h"
 #include "network.h"
+#include "srtp.h"
 #include "url.h"
 #include "rtpdec.h"
 #include "rtpdec_formats.h"
 
+#define MIN_FEEDBACK_INTERVAL 200000 /* 200 ms in us */
+
 static RTPDynamicProtocolHandler realmedia_mp3_dynamic_handler = {
     .enc_name   = "X-MP3-draft-00",
     .codec_type = AVMEDIA_TYPE_AUDIO,
@@ -48,7 +50,6 @@ static RTPDynamicProtocolHandler opus_dynamic_handler = {
     .codec_id   = AV_CODEC_ID_OPUS,
 };
 
-/* statistics functions */
 static RTPDynamicProtocolHandler *rtp_first_dynamic_payload_handler = NULL;
 
 void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
@@ -57,41 +58,41 @@ void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
     rtp_first_dynamic_payload_handler = handler;
 }
 
-void av_register_rtp_dynamic_payload_handlers(void)
+void ff_register_rtp_dynamic_payload_handlers(void)
 {
-    ff_register_dynamic_payload_handler(&ff_mp4v_es_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_amr_nb_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_amr_wb_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_jpeg_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_svq3_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_mp4a_latm_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
-    ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
-    ff_register_dynamic_payload_handler(&speex_dynamic_handler);
-    ff_register_dynamic_payload_handler(&opus_dynamic_handler);
-
-    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
+    ff_register_dynamic_payload_handler(&ff_mp4v_es_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_mpeg_audio_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_mpeg_video_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_mpegts_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler);
-
+    ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
+    ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
     ff_register_dynamic_payload_handler(&ff_qt_rtp_aud_handler);
     ff_register_dynamic_payload_handler(&ff_qt_rtp_vid_handler);
     ff_register_dynamic_payload_handler(&ff_quicktime_rtp_aud_handler);
     ff_register_dynamic_payload_handler(&ff_quicktime_rtp_vid_handler);
-
-    ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler);
-    ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_svq3_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
+    ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler);
+    ff_register_dynamic_payload_handler(&opus_dynamic_handler);
+    ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
+    ff_register_dynamic_payload_handler(&speex_dynamic_handler);
 }
 
 RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
@@ -133,6 +134,7 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf,
                 return AVERROR_INVALIDDATA;
             }
 
+            s->last_rtcp_reception_time = av_gettime();
             s->last_rtcp_ntp_time  = AV_RB64(buf + 8);
             s->last_rtcp_timestamp = AV_RB32(buf + 16);
             if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
@@ -226,6 +228,24 @@ static int rtp_valid_packet_in_sequence(RTPStatistics *s, uint16_t seq)
     return 1;
 }
 
+static void rtcp_update_jitter(RTPStatistics *s, uint32_t sent_timestamp,
+                               uint32_t arrival_timestamp)
+{
+    // Most of this is pretty straight from RFC 3550 appendix A.8
+    uint32_t transit = arrival_timestamp - sent_timestamp;
+    uint32_t prev_transit = s->transit;
+    int32_t d = transit - prev_transit;
+    // Doing the FFABS() call directly on the "transit - prev_transit"
+    // expression doesn't work, since it's an unsigned expression. Doing the
+    // transit calculation in unsigned is desired though, since it most
+    // probably will need to wrap around.
+    d = FFABS(d);
+    s->transit = transit;
+    if (!prev_transit)
+        return;
+    s->jitter += d - (int32_t) ((s->jitter + 8) >> 4);
+}
+
 int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
                                   AVIOContext *avio, int count)
 {
@@ -238,10 +258,9 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
     uint32_t extended_max;
     uint32_t expected_interval;
     uint32_t received_interval;
-    uint32_t lost_interval;
+    int32_t  lost_interval;
     uint32_t expected;
     uint32_t fraction;
-    uint64_t ntp_time = s->last_rtcp_ntp_time; // TODO: Get local ntp time?
 
     if ((!fd && !avio) || (count < 1))
         return -1;
@@ -271,7 +290,7 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
     // some placeholders we should really fill...
     // RFC 1889/p64
     extended_max          = stats->cycles + stats->max_seq;
-    expected              = extended_max - stats->base_seq + 1;
+    expected              = extended_max - stats->base_seq;
     lost                  = expected - stats->received;
     lost                  = FFMIN(lost, 0xffffff); // clamp it since it's only 24 bits...
     expected_interval     = expected - stats->expected_prior;
@@ -295,7 +314,8 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
         avio_wb32(pb, 0); /* delay since last SR */
     } else {
         uint32_t middle_32_bits   = s->last_rtcp_ntp_time >> 16; // this is valid, right? do we need to handle 64 bit values special?
-        uint32_t delay_since_last = ntp_time - s->last_rtcp_ntp_time;
+        uint32_t delay_since_last = av_rescale(av_gettime() - s->last_rtcp_reception_time,
+                                               65536, AV_TIME_BASE);
 
         avio_wb32(pb, middle_32_bits); /* last SR timestamp */
         avio_wb32(pb, delay_since_last); /* delay since last SR */
@@ -305,13 +325,14 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
     avio_w8(pb, (RTP_VERSION << 6) + 1); /* 1 report block */
     avio_w8(pb, RTCP_SDES);
     len = strlen(s->hostname);
-    avio_wb16(pb, (6 + len + 3) / 4); /* length in words - 1 */
+    avio_wb16(pb, (7 + len + 3) / 4); /* length in words - 1 */
     avio_wb32(pb, s->ssrc + 1);
     avio_w8(pb, 0x01);
     avio_w8(pb, len);
     avio_write(pb, s->hostname, len);
+    avio_w8(pb, 0); /* END */
     // padding
-    for (len = (6 + len) % 4; len % 4; len++)
+    for (len = (7 + len) % 4; len % 4; len++)
         avio_w8(pb, 0);
 
     avio_flush(pb);
@@ -366,10 +387,103 @@ void ff_rtp_send_punch_packets(URLContext *rtp_handle)
     av_free(buf);
 }
 
+static int find_missing_packets(RTPDemuxContext *s, uint16_t *first_missing,
+                                uint16_t *missing_mask)
+{
+    int i;
+    uint16_t next_seq = s->seq + 1;
+    RTPPacket *pkt = s->queue;
+
+    if (!pkt || pkt->seq == next_seq)
+        return 0;
+
+    *missing_mask = 0;
+    for (i = 1; i <= 16; i++) {
+        uint16_t missing_seq = next_seq + i;
+        while (pkt) {
+            int16_t diff = pkt->seq - missing_seq;
+            if (diff >= 0)
+                break;
+            pkt = pkt->next;
+        }
+        if (!pkt)
+            break;
+        if (pkt->seq == missing_seq)
+            continue;
+        *missing_mask |= 1 << (i - 1);
+    }
+
+    *first_missing = next_seq;
+    return 1;
+}
+
+int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
+                              AVIOContext *avio)
+{
+    int len, need_keyframe, missing_packets;
+    AVIOContext *pb;
+    uint8_t *buf;
+    int64_t now;
+    uint16_t first_missing = 0, missing_mask = 0;
+
+    if (!fd && !avio)
+        return -1;
+
+    need_keyframe = s->handler && s->handler->need_keyframe &&
+                    s->handler->need_keyframe(s->dynamic_protocol_context);
+    missing_packets = find_missing_packets(s, &first_missing, &missing_mask);
+
+    if (!need_keyframe && !missing_packets)
+        return 0;
+
+    /* Send new feedback if enough time has elapsed since the last
+     * feedback packet. */
+
+    now = av_gettime();
+    if (s->last_feedback_time &&
+        (now - s->last_feedback_time) < MIN_FEEDBACK_INTERVAL)
+        return 0;
+    s->last_feedback_time = now;
+
+    if (!fd)
+        pb = avio;
+    else if (avio_open_dyn_buf(&pb) < 0)
+        return -1;
+
+    if (need_keyframe) {
+        avio_w8(pb, (RTP_VERSION << 6) | 1); /* PLI */
+        avio_w8(pb, RTCP_PSFB);
+        avio_wb16(pb, 2); /* length in words - 1 */
+        // our own SSRC: we use the server's SSRC + 1 to avoid conflicts
+        avio_wb32(pb, s->ssrc + 1);
+        avio_wb32(pb, s->ssrc); // server SSRC
+    }
+
+    if (missing_packets) {
+        avio_w8(pb, (RTP_VERSION << 6) | 1); /* NACK */
+        avio_w8(pb, RTCP_RTPFB);
+        avio_wb16(pb, 3); /* length in words - 1 */
+        avio_wb32(pb, s->ssrc + 1);
+        avio_wb32(pb, s->ssrc); // server SSRC
+
+        avio_wb16(pb, first_missing);
+        avio_wb16(pb, missing_mask);
+    }
+
+    avio_flush(pb);
+    if (!fd)
+        return 0;
+    len = avio_close_dyn_buf(pb, &buf);
+    if (len > 0 && buf) {
+        ffurl_write(fd, buf, len);
+        av_free(buf);
+    }
+    return 0;
+}
+
 /**
  * open a new RTP parse context for stream 'st'. 'st' can be NULL for
- * MPEG2-TS streams to indicate that they should be demuxed inside the
- * rtp demux (otherwise AV_CODEC_ID_MPEG2TS packets are returned)
+ * MPEG2-TS streams.
  */
 RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
                                    int payload_type, int queue_size)
@@ -385,27 +499,9 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
     s->ic                  = s1;
     s->st                  = st;
     s->queue_size          = queue_size;
-    rtp_init_statistics(&s->statistics, 0); // do we know the initial sequence from sdp?
-    if (!strcmp(ff_rtp_enc_name(payload_type), "MP2T")) {
-        s->ts = ff_mpegts_parse_open(s->ic);
-        if (s->ts == NULL) {
-            av_free(s);
-            return NULL;
-        }
-    } else if (st) {
+    rtp_init_statistics(&s->statistics, 0);
+    if (st) {
         switch (st->codec->codec_id) {
-        case AV_CODEC_ID_MPEG1VIDEO:
-        case AV_CODEC_ID_MPEG2VIDEO:
-        case AV_CODEC_ID_MP2:
-        case AV_CODEC_ID_MP3:
-        case AV_CODEC_ID_MPEG4:
-        case AV_CODEC_ID_H263:
-        case AV_CODEC_ID_H264:
-            st->need_parsing = AVSTREAM_PARSE_FULL;
-            break;
-        case AV_CODEC_ID_VORBIS:
-            st->need_parsing = AVSTREAM_PARSE_HEADERS;
-            break;
         case AV_CODEC_ID_ADPCM_G722:
             /* According to RFC 3551, the stream clock rate is 8000
              * even if the sample rate is 16000. */
@@ -425,7 +521,14 @@ void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
                                        RTPDynamicProtocolHandler *handler)
 {
     s->dynamic_protocol_context = ctx;
-    s->parse_packet             = handler->parse_packet;
+    s->handler                  = handler;
+}
+
+void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite,
+                             const char *params)
+{
+    if (!ff_srtp_set_crypto(&s->srtp, suite, params))
+        s->srtp_enabled = 1;
 }
 
 /**
@@ -470,13 +573,14 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam
 static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,
                                      const uint8_t *buf, int len)
 {
-    unsigned int ssrc, h;
-    int payload_type, seq, ret, flags = 0;
-    int ext;
+    unsigned int ssrc;
+    int payload_type, seq, flags = 0;
+    int ext, csrc;
     AVStream *st;
     uint32_t timestamp;
     int rv = 0;
 
+    csrc         = buf[0] & 0x0f;
     ext          = buf[0] & 0x10;
     payload_type = buf[1] & 0x7f;
     if (buf[1] & 0x80)
@@ -510,6 +614,11 @@ static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,
     len   -= 12;
     buf   += 12;
 
+    len   -= 4 * csrc;
+    buf   += 4 * csrc;
+    if (len < 0)
+        return AVERROR_INVALIDDATA;
+
     /* RFC 3550 Section 5.3.1 RTP Header Extension handling */
     if (ext) {
         if (len < 4)
@@ -525,64 +634,17 @@ static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,
         buf += ext;
     }
 
-    if (!st) {
-        /* specific MPEG2-TS demux support */
-        ret = ff_mpegts_parse_packet(s->ts, pkt, buf, len);
-        /* The only error that can be returned from ff_mpegts_parse_packet
-         * is "no more data to return from the provided buffer", so return
-         * AVERROR(EAGAIN) for all errors */
-        if (ret < 0)
-            return AVERROR(EAGAIN);
-        if (ret < len) {
-            s->read_buf_size = FFMIN(len - ret, sizeof(s->buf));
-            memcpy(s->buf, buf + ret, s->read_buf_size);
-            s->read_buf_index = 0;
-            return 1;
-        }
-        return 0;
-    } else if (s->parse_packet) {
-        rv = s->parse_packet(s->ic, s->dynamic_protocol_context,
-                             s->st, pkt, &timestamp, buf, len, seq, flags);
-    } else {
-        /* At this point, the RTP header has been stripped;
-         * This is ASSUMING that there is only 1 CSRC, which isn't wise. */
-        switch (st->codec->codec_id) {
-        case AV_CODEC_ID_MP2:
-        case AV_CODEC_ID_MP3:
-            /* better than nothing: skip MPEG audio RTP header */
-            if (len <= 4)
-                return -1;
-            h    = AV_RB32(buf);
-            len -= 4;
-            buf += 4;
-            av_new_packet(pkt, len);
-            memcpy(pkt->data, buf, len);
-            break;
-        case AV_CODEC_ID_MPEG1VIDEO:
-        case AV_CODEC_ID_MPEG2VIDEO:
-            /* better than nothing: skip MPEG video RTP header */
-            if (len <= 4)
-                return -1;
-            h    = AV_RB32(buf);
-            buf += 4;
-            len -= 4;
-            if (h & (1 << 26)) {
-                /* MPEG-2 */
-                if (len <= 4)
-                    return -1;
-                buf += 4;
-                len -= 4;
-            }
-            av_new_packet(pkt, len);
-            memcpy(pkt->data, buf, len);
-            break;
-        default:
-            av_new_packet(pkt, len);
-            memcpy(pkt->data, buf, len);
-            break;
-        }
-
+    if (s->handler && s->handler->parse_packet) {
+        rv = s->handler->parse_packet(s->ic, s->dynamic_protocol_context,
+                                      s->st, pkt, &timestamp, buf, len, seq,
+                                      flags);
+    } else if (st) {
+        if ((rv = av_new_packet(pkt, len)) < 0)
+            return rv;
+        memcpy(pkt->data, buf, len);
         pkt->stream_index = st->index;
+    } else {
+        return AVERROR(EINVAL);
     }
 
     // now perform timestamp things....
@@ -607,15 +669,14 @@ void ff_rtp_reset_packet_queue(RTPDemuxContext *s)
 static void enqueue_packet(RTPDemuxContext *s, uint8_t *buf, int len)
 {
     uint16_t seq   = AV_RB16(buf + 2);
-    RTPPacket *cur = s->queue, *prev = NULL, *packet;
+    RTPPacket **cur = &s->queue, *packet;
 
     /* Find the correct place in the queue to insert the packet */
-    while (cur) {
-        int16_t diff = seq - cur->seq;
+    while (*cur) {
+        int16_t diff = seq - (*cur)->seq;
         if (diff < 0)
             break;
-        prev = cur;
-        cur  = cur->next;
+        cur = &(*cur)->next;
     }
 
     packet = av_mallocz(sizeof(*packet));
@@ -625,11 +686,8 @@ static void enqueue_packet(RTPDemuxContext *s, uint8_t *buf, int len)
     packet->seq      = seq;
     packet->len      = len;
     packet->buf      = buf;
-    packet->next     = cur;
-    if (prev)
-        prev->next = packet;
-    else
-        s->queue = packet;
+    packet->next     = *cur;
+    *cur = packet;
     s->queue_len++;
 }
 
@@ -669,7 +727,7 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
                                 uint8_t **bufptr, int len)
 {
     uint8_t *buf = bufptr ? *bufptr : NULL;
-    int ret, flags = 0;
+    int flags = 0;
     uint32_t timestamp;
     int rv = 0;
 
@@ -680,28 +738,15 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
         if (s->prev_ret <= 0)
             return rtp_parse_queued_packet(s, pkt);
         /* return the next packets, if any */
-        if (s->st && s->parse_packet) {
+        if (s->handler && s->handler->parse_packet) {
             /* timestamp should be overwritten by parse_packet, if not,
              * the packet is left with pts == AV_NOPTS_VALUE */
             timestamp = RTP_NOTS_VALUE;
-            rv        = s->parse_packet(s->ic, s->dynamic_protocol_context,
-                                        s->st, pkt, &timestamp, NULL, 0, 0,
-                                        flags);
+            rv        = s->handler->parse_packet(s->ic, s->dynamic_protocol_context,
+                                                 s->st, pkt, &timestamp, NULL, 0, 0,
+                                                 flags);
             finalize_packet(s, pkt, timestamp);
             return rv;
-        } else {
-            // TODO: Move to a dynamic packet handler (like above)
-            if (s->read_buf_index >= s->read_buf_size)
-                return AVERROR(EAGAIN);
-            ret = ff_mpegts_parse_packet(s->ts, pkt, s->buf + s->read_buf_index,
-                                         s->read_buf_size - s->read_buf_index);
-            if (ret < 0)
-                return AVERROR(EAGAIN);
-            s->read_buf_index += ret;
-            if (s->read_buf_index < s->read_buf_size)
-                return 1;
-            else
-                return 0;
         }
     }
 
@@ -714,6 +759,16 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
         return rtcp_parse_packet(s, buf, len);
     }
 
+    if (s->st) {
+        int64_t received = av_gettime();
+        uint32_t arrival_ts = av_rescale_q(received, AV_TIME_BASE_Q,
+                                           s->st->time_base);
+        timestamp = AV_RB32(buf + 4);
+        // Calculate the jitter immediately, before queueing the packet
+        // into the reordering queue.
+        rtcp_update_jitter(&s->statistics, timestamp, arrival_ts);
+    }
+
     if ((s->seq == 0 && !s->queue) || s->queue_size <= 1) {
         /* First packet, or no reordering */
         return rtp_parse_packet_internal(s, pkt, buf, len);
@@ -754,7 +809,10 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
 int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
                         uint8_t **bufptr, int len)
 {
-    int rv = rtp_parse_one_packet(s, pkt, bufptr, len);
+    int rv;
+    if (s->srtp_enabled && bufptr && ff_srtp_decrypt(&s->srtp, *bufptr, &len) < 0)
+        return -1;
+    rv = rtp_parse_one_packet(s, pkt, bufptr, len);
     s->prev_ret = rv;
     while (rv == AVERROR(EAGAIN) && has_next_packet(s))
         rv = rtp_parse_queued_packet(s, pkt);
@@ -764,9 +822,7 @@ int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
 void ff_rtp_parse_close(RTPDemuxContext *s)
 {
     ff_rtp_reset_packet_queue(s);
-    if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) {
-        ff_mpegts_parse_close(s->ts);
-    }
+    ff_srtp_free(&s->srtp);
     av_free(s);
 }
 
@@ -808,11 +864,15 @@ int ff_parse_fmtp(AVStream *stream, PayloadContext *data, const char *p,
 
 int ff_rtp_finalize_packet(AVPacket *pkt, AVIOContext **dyn_buf, int stream_idx)
 {
+    int ret;
     av_init_packet(pkt);
 
     pkt->size         = avio_close_dyn_buf(*dyn_buf, &pkt->data);
     pkt->stream_index = stream_idx;
-    pkt->destruct     = av_destruct_packet;
-    *dyn_buf          = NULL;
+    *dyn_buf = NULL;
+    if ((ret = av_packet_from_data(pkt, pkt->data, pkt->size)) < 0) {
+        av_freep(&pkt->data);
+        return ret;
+    }
     return pkt->size;
 }
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 7c51f5a..6b16117 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -27,12 +27,13 @@
 #include "avformat.h"
 #include "rtp.h"
 #include "url.h"
+#include "srtp.h"
 
 typedef struct PayloadContext PayloadContext;
 typedef struct RTPDynamicProtocolHandler RTPDynamicProtocolHandler;
 
 #define RTP_MIN_PACKET_LENGTH 12
-#define RTP_MAX_PACKET_LENGTH 1500
+#define RTP_MAX_PACKET_LENGTH 8192
 
 #define RTP_REORDER_QUEUE_DEFAULT_SIZE 10
 
@@ -43,15 +44,13 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
                                    int payload_type, int queue_size);
 void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx,
                                        RTPDynamicProtocolHandler *handler);
+void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite,
+                             const char *params);
 int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
                         uint8_t **buf, int len);
 void ff_rtp_parse_close(RTPDemuxContext *s);
 int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s);
 void ff_rtp_reset_packet_queue(RTPDemuxContext *s);
-int ff_rtp_get_local_rtp_port(URLContext *h);
-int ff_rtp_get_local_rtcp_port(URLContext *h);
-
-int ff_rtp_set_remote_url(URLContext *h, const char *uri);
 
 /**
  * Send a dummy packet on both port pairs to set up the connection
@@ -73,6 +72,8 @@ void ff_rtp_send_punch_packets(URLContext* rtp_handle);
  */
 int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
                                   AVIOContext *avio, int count);
+int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
+                              AVIOContext *avio);
 
 // these statistics are used for rtcp receiver reports...
 typedef struct RTPStatistics {
@@ -81,9 +82,9 @@ typedef struct RTPStatistics {
     uint32_t base_seq;          ///< base sequence number
     uint32_t bad_seq;           ///< last bad sequence number + 1
     int probation;              ///< sequence packets till source is valid
-    int received;               ///< packets received
-    int expected_prior;         ///< packets expected in last interval
-    int received_prior;         ///< packets received in last interval
+    uint32_t received;          ///< packets received
+    uint32_t expected_prior;    ///< packets expected in last interval
+    uint32_t received_prior;    ///< packets received in last interval
     uint32_t transit;           ///< relative transit time for previous packet
     uint32_t jitter;            ///< estimated jitter.
 } RTPStatistics;
@@ -130,6 +131,7 @@ struct RTPDynamicProtocolHandler {
     void (*free)(PayloadContext *protocol_data);
     /** Parse handler for this dynamic packet */
     DynamicPayloadPacketHandlerProc parse_packet;
+    int (*need_keyframe)(PayloadContext *context);
 
     struct RTPDynamicProtocolHandler *next;
 };
@@ -154,12 +156,12 @@ struct RTPDemuxContext {
     int64_t  unwrapped_timestamp;
     int64_t  range_start_offset;
     int max_payload_size;
-    struct MpegTSContext *ts;   /* only used for MP2T payloads */
-    int read_buf_index;
-    int read_buf_size;
     /* used to send back RTCP RR */
     char hostname[256];
 
+    int srtp_enabled;
+    struct SRTPContext srtp;
+
     /** Statistics for this stream (used by RTCP receiver reports) */
     RTPStatistics statistics;
 
@@ -172,6 +174,7 @@ struct RTPDemuxContext {
 
     /* rtcp sender statistics receive */
     int64_t last_rtcp_ntp_time;
+    int64_t last_rtcp_reception_time;
     int64_t first_rtcp_ntp_time;
     uint32_t last_rtcp_timestamp;
     int64_t rtcp_ts_offset;
@@ -180,11 +183,10 @@ struct RTPDemuxContext {
     unsigned int packet_count;
     unsigned int octet_count;
     unsigned int last_octet_count;
-    /* buffer for partially parsed packets */
-    uint8_t buf[RTP_MAX_PACKET_LENGTH];
+    int64_t last_feedback_time;
 
     /* dynamic payload stuff */
-    DynamicPayloadPacketHandlerProc parse_packet;
+    const RTPDynamicProtocolHandler *handler;
     PayloadContext *dynamic_protocol_context;
 };
 
@@ -203,7 +205,7 @@ int ff_parse_fmtp(AVStream *stream, PayloadContext *data, const char *p,
                                     PayloadContext *data,
                                     char *attr, char *value));
 
-void av_register_rtp_dynamic_payload_handlers(void);
+void ff_register_rtp_dynamic_payload_handlers(void);
 
 /**
  * Close the dynamic buffer and make a packet from it.
diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
index e425650..7c893af 100644
--- a/libavformat/rtpdec_asf.c
+++ b/libavformat/rtpdec_asf.c
@@ -239,14 +239,11 @@ static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
 
                 int cur_len = start_off + len_off - off;
                 int prev_len = out_len;
-                void *newmem;
                 out_len += cur_len;
                 if (FFMIN(cur_len, len - off) < 0)
                     return -1;
-                newmem = av_realloc(asf->buf, out_len);
-                if (!newmem)
-                    return -1;
-                asf->buf = newmem;
+                if ((res = av_reallocp(&asf->buf, out_len)) < 0)
+                    return res;
                 memcpy(asf->buf + prev_len, buf + off,
                        FFMIN(cur_len, len - off));
                 avio_skip(pb, cur_len);
diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h
index e449ddf..e5f4ccb 100644
--- a/libavformat/rtpdec_formats.h
+++ b/libavformat/rtpdec_formats.h
@@ -49,7 +49,10 @@ extern RTPDynamicProtocolHandler ff_ilbc_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_jpeg_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_mpeg_audio_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_mpeg_video_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler;
+extern RTPDynamicProtocolHandler ff_mpegts_dynamic_handler;
 extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfa_handler;
 extern RTPDynamicProtocolHandler ff_ms_rtp_asf_pfv_handler;
 extern RTPDynamicProtocolHandler ff_qcelp_dynamic_handler;
diff --git a/libavformat/rtpdec_g726.c b/libavformat/rtpdec_g726.c
index adb4ab3..7b3f6cb 100644
--- a/libavformat/rtpdec_g726.c
+++ b/libavformat/rtpdec_g726.c
@@ -18,11 +18,13 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "avformat.h"
 #include "rtpdec_formats.h"
 
 #define RTP_G726_HANDLER(bitrate) \
-static int g726_ ## bitrate ##_init(AVFormatContext *s, int st_index, PayloadContext *data) \
+static av_cold int g726_ ## bitrate ##_init(AVFormatContext *s, int st_index, \
+                                            PayloadContext *data) \
 { \
     AVStream *stream = s->streams[st_index]; \
     AVCodecContext *codec = stream->codec; \
diff --git a/libavformat/rtpdec_h263.c b/libavformat/rtpdec_h263.c
index bdb5195..b371491 100644
--- a/libavformat/rtpdec_h263.c
+++ b/libavformat/rtpdec_h263.c
@@ -21,8 +21,18 @@
 
 #include "avformat.h"
 #include "rtpdec_formats.h"
+#include "libavutil/attributes.h"
 #include "libavutil/intreadwrite.h"
 
+static av_cold int h263_init(AVFormatContext *ctx, int st_index,
+                             PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
 int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                           AVStream *st, AVPacket *pkt, uint32_t *timestamp,
                           const uint8_t *buf, int len, uint16_t seq, int flags)
@@ -92,6 +102,7 @@ RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler = {
     .enc_name         = "H263-1998",
     .codec_type       = AVMEDIA_TYPE_VIDEO,
     .codec_id         = AV_CODEC_ID_H263,
+    .init             = h263_init,
     .parse_packet     = ff_h263_handle_packet,
 };
 
@@ -99,5 +110,6 @@ RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler = {
     .enc_name         = "H263-2000",
     .codec_type       = AVMEDIA_TYPE_VIDEO,
     .codec_id         = AV_CODEC_ID_H263,
+    .init             = h263_init,
     .parse_packet     = ff_h263_handle_packet,
 };
diff --git a/libavformat/rtpdec_h263_rfc2190.c b/libavformat/rtpdec_h263_rfc2190.c
index 4792a9f..116db75 100644
--- a/libavformat/rtpdec_h263_rfc2190.c
+++ b/libavformat/rtpdec_h263_rfc2190.c
@@ -27,6 +27,7 @@
 
 #include "avformat.h"
 #include "rtpdec_formats.h"
+#include "libavutil/attributes.h"
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/get_bits.h"
 
@@ -55,6 +56,14 @@ static void h263_free_context(PayloadContext *data)
     av_free(data);
 }
 
+static av_cold int h263_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
 static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                               AVStream *st, AVPacket *pkt, uint32_t *timestamp,
                               const uint8_t *buf, int len, uint16_t seq,
@@ -198,6 +207,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
 RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler = {
     .codec_type        = AVMEDIA_TYPE_VIDEO,
     .codec_id          = AV_CODEC_ID_H263,
+    .init              = h263_init,
     .parse_packet      = h263_handle_packet,
     .alloc             = h263_new_context,
     .free              = h263_free_context,
diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c
index 2df0930..982eb72 100644
--- a/libavformat/rtpdec_h264.c
+++ b/libavformat/rtpdec_h264.c
@@ -33,6 +33,7 @@
  *                        FU-B packet types)
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/base64.h"
 #include "libavutil/avstring.h"
 #include "libavcodec/get_bits.h"
@@ -189,7 +190,8 @@ static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data,
     switch (type) {
     case 0:                    // undefined, but pass them through
     case 1:
-        av_new_packet(pkt, len + sizeof(start_sequence));
+        if ((result = av_new_packet(pkt, len + sizeof(start_sequence))) < 0)
+            return result;
         memcpy(pkt->data, start_sequence, sizeof(start_sequence));
         memcpy(pkt->data + sizeof(start_sequence), buf, len);
         COUNT_NAL_TYPE(data, nal);
@@ -246,7 +248,8 @@ static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                 if (pass == 0) {
                     /* now we know the total size of the packet (with the
                      * start sequences added) */
-                    av_new_packet(pkt, total_length);
+                    if ((result = av_new_packet(pkt, total_length)) < 0)
+                        return result;
                     dst = pkt->data;
                 } else {
                     assert(dst - pkt->data == total_length);
@@ -291,12 +294,14 @@ static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                 COUNT_NAL_TYPE(data, nal_type);
             if (start_bit) {
                 /* copy in the start sequence, and the reconstructed nal */
-                av_new_packet(pkt, sizeof(start_sequence) + sizeof(nal) + len);
+                if ((result = av_new_packet(pkt, sizeof(start_sequence) + sizeof(nal) + len)) < 0)
+                    return result;
                 memcpy(pkt->data, start_sequence, sizeof(start_sequence));
                 pkt->data[sizeof(start_sequence)] = reconstructed_nal;
                 memcpy(pkt->data + sizeof(start_sequence) + sizeof(nal), buf, len);
             } else {
-                av_new_packet(pkt, len);
+                if ((result = av_new_packet(pkt, len)) < 0)
+                    return result;
                 memcpy(pkt->data, buf, len);
             }
         } else {
@@ -338,6 +343,15 @@ static void h264_free_context(PayloadContext *data)
     av_free(data);
 }
 
+static av_cold int h264_init(AVFormatContext *s, int st_index,
+                             PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
 static int parse_h264_sdp_line(AVFormatContext *s, int st_index,
                                PayloadContext *h264_data, const char *line)
 {
@@ -383,6 +397,7 @@ RTPDynamicProtocolHandler ff_h264_dynamic_handler = {
     .enc_name         = "H264",
     .codec_type       = AVMEDIA_TYPE_VIDEO,
     .codec_id         = AV_CODEC_ID_H264,
+    .init             = h264_init,
     .parse_sdp_a_line = parse_h264_sdp_line,
     .alloc            = h264_new_context,
     .free             = h264_free_context,
diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c
index 7d4ae1e..050595c 100644
--- a/libavformat/rtpdec_latm.c
+++ b/libavformat/rtpdec_latm.c
@@ -157,8 +157,8 @@ static int parse_fmtp(AVStream *stream, PayloadContext *data,
     } else if (!strcmp(attr, "cpresent")) {
         int cpresent = atoi(value);
         if (cpresent != 0)
-            av_log_missing_feature(NULL, "RTP MP4A-LATM with in-band "
-                                         "configuration", 1);
+            avpriv_request_sample(NULL,
+                                  "RTP MP4A-LATM with in-band configuration");
     }
 
     return 0;
diff --git a/libavformat/rtpdec_mpeg12.c b/libavformat/rtpdec_mpeg12.c
new file mode 100644
index 0000000..b059fcf
--- /dev/null
+++ b/libavformat/rtpdec_mpeg12.c
@@ -0,0 +1,73 @@
+/*
+ * Common code for the RTP depacketization of MPEG-1/2 formats.
+ * Copyright (c) 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 "libavutil/attributes.h"
+#include "libavutil/intreadwrite.h"
+#include "rtpdec_formats.h"
+
+static av_cold int mpeg_init(AVFormatContext *ctx, int st_index, PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
+static int mpeg_parse_packet(AVFormatContext *ctx, PayloadContext *data,
+                             AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                             const uint8_t *buf, int len, uint16_t seq,
+                             int flags)
+{
+    unsigned int h;
+    if (len <= 4)
+        return AVERROR_INVALIDDATA;
+    h    = AV_RB32(buf);
+    buf += 4;
+    len -= 4;
+    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && h & (1 << 26)) {
+        /* MPEG-2 */
+        if (len <= 4)
+            return AVERROR_INVALIDDATA;
+        buf += 4;
+        len -= 4;
+    }
+    if (av_new_packet(pkt, len) < 0)
+        return AVERROR(ENOMEM);
+    memcpy(pkt->data, buf, len);
+    pkt->stream_index = st->index;
+    return 0;
+}
+
+RTPDynamicProtocolHandler ff_mpeg_audio_dynamic_handler = {
+    .codec_type        = AVMEDIA_TYPE_AUDIO,
+    .codec_id          = AV_CODEC_ID_MP3,
+    .init              = mpeg_init,
+    .parse_packet      = mpeg_parse_packet,
+    .static_payload_id = 14,
+};
+
+RTPDynamicProtocolHandler ff_mpeg_video_dynamic_handler = {
+    .codec_type        = AVMEDIA_TYPE_VIDEO,
+    .codec_id          = AV_CODEC_ID_MPEG2VIDEO,
+    .init              = mpeg_init,
+    .parse_packet      = mpeg_parse_packet,
+    .static_payload_id = 32,
+};
diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
index 13d051a..bec5c7d 100644
--- a/libavformat/rtpdec_mpeg4.c
+++ b/libavformat/rtpdec_mpeg4.c
@@ -29,6 +29,7 @@
 
 #include "rtpdec_formats.h"
 #include "internal.h"
+#include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
 #include "libavcodec/get_bits.h"
 
@@ -57,6 +58,9 @@ struct PayloadContext {
     int nb_au_headers;
     int au_headers_length_bytes;
     int cur_au_index;
+
+    uint8_t buf[RTP_MAX_PACKET_LENGTH];
+    int buf_pos, buf_size;
 };
 
 typedef struct {
@@ -109,11 +113,14 @@ static int parse_fmtp_config(AVCodecContext *codec, char *value)
     return 0;
 }
 
-static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf)
+static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf, int len)
 {
     int au_headers_length, au_header_size, i;
     GetBitContext getbitcontext;
 
+    if (len < 2)
+        return AVERROR_INVALIDDATA;
+
     /* decode the first 2 bytes where the AUHeader sections are stored
        length in bits */
     au_headers_length = AV_RB16(buf);
@@ -125,6 +132,10 @@ static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf)
 
     /* skip AU headers length section (2 bytes) */
     buf += 2;
+    len -= 2;
+
+    if (len < data->au_headers_length_bytes)
+        return AVERROR_INVALIDDATA;
 
     init_get_bits(&getbitcontext, buf, data->au_headers_length_bytes * 8);
 
@@ -137,21 +148,16 @@ static int rtp_parse_mp4_au(PayloadContext *data, const uint8_t *buf)
     if (!data->au_headers || data->au_headers_allocated < data->nb_au_headers) {
         av_free(data->au_headers);
         data->au_headers = av_malloc(sizeof(struct AUHeaders) * data->nb_au_headers);
+        if (!data->au_headers)
+            return AVERROR(ENOMEM);
         data->au_headers_allocated = data->nb_au_headers;
     }
 
-    /* XXX: We handle multiple AU Section as only one (need to fix this for interleaving)
-       In my test, the FAAD decoder does not behave correctly when sending each AU one by one
-       but does when sending the whole as one big packet...  */
-    data->au_headers[0].size = 0;
-    data->au_headers[0].index = 0;
     for (i = 0; i < data->nb_au_headers; ++i) {
-        data->au_headers[0].size += get_bits_long(&getbitcontext, data->sizelength);
-        data->au_headers[0].index = get_bits_long(&getbitcontext, data->indexlength);
+        data->au_headers[i].size  = get_bits_long(&getbitcontext, data->sizelength);
+        data->au_headers[i].index = get_bits_long(&getbitcontext, data->indexlength);
     }
 
-    data->nb_au_headers = 1;
-
     return 0;
 }
 
@@ -162,18 +168,45 @@ static int aac_parse_packet(AVFormatContext *ctx, PayloadContext *data,
                             const uint8_t *buf, int len, uint16_t seq,
                             int flags)
 {
-    if (rtp_parse_mp4_au(data, buf))
+    int ret;
+
+    if (!buf) {
+        if (data->cur_au_index > data->nb_au_headers)
+            return AVERROR_INVALIDDATA;
+        if (data->buf_size - data->buf_pos < data->au_headers[data->cur_au_index].size)
+            return AVERROR_INVALIDDATA;
+        if ((ret = av_new_packet(pkt, data->au_headers[data->cur_au_index].size)) < 0)
+            return ret;
+        memcpy(pkt->data, &data->buf[data->buf_pos], data->au_headers[data->cur_au_index].size);
+        data->buf_pos += data->au_headers[data->cur_au_index].size;
+        pkt->stream_index = st->index;
+        data->cur_au_index++;
+        return data->cur_au_index < data->nb_au_headers;
+    }
+
+    if (rtp_parse_mp4_au(data, buf, len))
         return -1;
 
     buf += data->au_headers_length_bytes + 2;
     len -= data->au_headers_length_bytes + 2;
 
-    /* XXX: Fixme we only handle the case where rtp_parse_mp4_au define
-                    one au_header */
-    av_new_packet(pkt, data->au_headers[0].size);
+    if (len < data->au_headers[0].size)
+        return AVERROR_INVALIDDATA;
+    if ((ret = av_new_packet(pkt, data->au_headers[0].size)) < 0)
+        return ret;
     memcpy(pkt->data, buf, data->au_headers[0].size);
-
+    len -= data->au_headers[0].size;
+    buf += data->au_headers[0].size;
     pkt->stream_index = st->index;
+
+    if (len > 0 && data->nb_au_headers > 1) {
+        data->buf_size = FFMIN(len, sizeof(data->buf));
+        memcpy(data->buf, buf, data->buf_size);
+        data->cur_au_index = 1;
+        data->buf_pos = 0;
+        return 1;
+    }
+
     return 0;
 }
 
@@ -220,10 +253,20 @@ static int parse_sdp_line(AVFormatContext *s, int st_index,
     return 0;
 }
 
+static av_cold int init_video(AVFormatContext *s, int st_index,
+                              PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    s->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
+    return 0;
+}
+
 RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler = {
     .enc_name           = "MP4V-ES",
     .codec_type         = AVMEDIA_TYPE_VIDEO,
     .codec_id           = AV_CODEC_ID_MPEG4,
+    .init               = init_video,
     .parse_sdp_a_line   = parse_sdp_line,
 };
 
diff --git a/libavformat/rtpdec_mpegts.c b/libavformat/rtpdec_mpegts.c
new file mode 100644
index 0000000..b3ef261
--- /dev/null
+++ b/libavformat/rtpdec_mpegts.c
@@ -0,0 +1,108 @@
+/*
+ * RTP MPEG2TS depacketizer
+ * 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 "libavutil/attributes.h"
+#include "mpegts.h"
+#include "rtpdec_formats.h"
+
+struct PayloadContext {
+    struct MpegTSContext *ts;
+    int read_buf_index;
+    int read_buf_size;
+    uint8_t buf[RTP_MAX_PACKET_LENGTH];
+};
+
+static PayloadContext *mpegts_new_context(void)
+{
+    return av_mallocz(sizeof(PayloadContext));
+}
+
+static void mpegts_free_context(PayloadContext *data)
+{
+    if (!data)
+        return;
+    if (data->ts)
+        ff_mpegts_parse_close(data->ts);
+    av_free(data);
+}
+
+static av_cold int mpegts_init(AVFormatContext *ctx, int st_index,
+                               PayloadContext *data)
+{
+    data->ts = ff_mpegts_parse_open(ctx);
+    if (!data->ts)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
+static int mpegts_handle_packet(AVFormatContext *ctx, PayloadContext *data,
+                                AVStream *st, AVPacket *pkt, uint32_t *timestamp,
+                                const uint8_t *buf, int len, uint16_t seq,
+                                int flags)
+{
+    int ret;
+
+    // We don't want to use the RTP timestamps at all. If the mpegts demuxer
+    // doesn't set any pts/dts, the generic rtpdec code shouldn't try to
+    // fill it in either, since the mpegts and RTP timestamps are in totally
+    // different ranges.
+    *timestamp = RTP_NOTS_VALUE;
+
+    if (!data->ts)
+        return AVERROR(EINVAL);
+
+    if (!buf) {
+        if (data->read_buf_index >= data->read_buf_size)
+            return AVERROR(EAGAIN);
+        ret = ff_mpegts_parse_packet(data->ts, pkt, data->buf + data->read_buf_index,
+                                     data->read_buf_size - data->read_buf_index);
+        if (ret < 0)
+            return AVERROR(EAGAIN);
+        data->read_buf_index += ret;
+        if (data->read_buf_index < data->read_buf_size)
+            return 1;
+        else
+            return 0;
+    }
+
+    ret = ff_mpegts_parse_packet(data->ts, pkt, buf, len);
+    /* The only error that can be returned from ff_mpegts_parse_packet
+     * is "no more data to return from the provided buffer", so return
+     * AVERROR(EAGAIN) for all errors */
+    if (ret < 0)
+        return AVERROR(EAGAIN);
+    if (ret < len) {
+        data->read_buf_size = FFMIN(len - ret, sizeof(data->buf));
+        memcpy(data->buf, buf + ret, data->read_buf_size);
+        data->read_buf_index = 0;
+        return 1;
+    }
+    return 0;
+}
+
+RTPDynamicProtocolHandler ff_mpegts_dynamic_handler = {
+    .codec_type        = AVMEDIA_TYPE_DATA,
+    .parse_packet      = mpegts_handle_packet,
+    .alloc             = mpegts_new_context,
+    .init              = mpegts_init,
+    .free              = mpegts_free_context,
+    .static_payload_id = 33,
+};
diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c
index 6350507..2d9c603 100644
--- a/libavformat/rtpdec_qt.c
+++ b/libavformat/rtpdec_qt.c
@@ -97,8 +97,8 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
         is_start  = get_bits1(&gb);
         is_finish = get_bits1(&gb);
         if (!is_start || !is_finish) {
-            av_log_missing_feature(s, "RTP-X-QT with payload description "
-                                      "split over several packets", 1);
+            avpriv_request_sample(s, "RTP-X-QT with payload description "
+                                  "split over several packets");
             return AVERROR_PATCHWELCOME;
         }
         skip_bits(&gb, 12); // reserved
@@ -161,7 +161,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
         avio_seek(&pb, 4, SEEK_SET);
 
     if (has_packet_info) {
-        av_log_missing_feature(s, "RTP-X-QT with packet specific info", 1);
+        avpriv_request_sample(s, "RTP-X-QT with packet-specific info");
         return AVERROR_PATCHWELCOME;
     }
 
@@ -172,26 +172,32 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
     switch (packing_scheme) {
     case 3: /* one data packet spread over 1 or multiple RTP packets */
         if (qt->pkt.size > 0 && qt->timestamp == *timestamp) {
-            qt->pkt.data = av_realloc(qt->pkt.data, qt->pkt.size + alen +
-                                      FF_INPUT_BUFFER_PADDING_SIZE);
+            int err;
+            if ((err = av_reallocp(&qt->pkt.data, qt->pkt.size + alen +
+                                   FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+                qt->pkt.size = 0;
+                return err;
+            }
         } else {
             av_freep(&qt->pkt.data);
             av_init_packet(&qt->pkt);
-            qt->pkt.data = av_malloc(alen + FF_INPUT_BUFFER_PADDING_SIZE);
+            qt->pkt.data = av_realloc(NULL, alen + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!qt->pkt.data)
+                return AVERROR(ENOMEM);
             qt->pkt.size = 0;
             qt->timestamp = *timestamp;
         }
-        if (!qt->pkt.data)
-            return AVERROR(ENOMEM);
         memcpy(qt->pkt.data + qt->pkt.size, buf + avio_tell(&pb), alen);
         qt->pkt.size += alen;
         if (has_marker_bit) {
-            *pkt = qt->pkt;
+            int ret = av_packet_from_data(pkt, qt->pkt.data, qt->pkt.size);
+            if (ret < 0)
+                return ret;
+
             qt->pkt.size = 0;
             qt->pkt.data = NULL;
             pkt->flags        = flags & RTP_FLAG_KEY ? AV_PKT_FLAG_KEY : 0;
             pkt->stream_index = st->index;
-            pkt->destruct     = av_destruct_packet;
             memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
             return 0;
         }
@@ -209,7 +215,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
         pkt->stream_index = st->index;
         if (qt->remaining > 0) {
             av_freep(&qt->pkt.data);
-            qt->pkt.data = av_malloc(qt->remaining * qt->bytes_per_frame);
+            qt->pkt.data = av_realloc(NULL, qt->remaining * qt->bytes_per_frame);
             if (!qt->pkt.data) {
                 av_free_packet(pkt);
                 return AVERROR(ENOMEM);
@@ -224,7 +230,7 @@ static int qt_rtp_parse_packet(AVFormatContext *s, PayloadContext *qt,
         return 0;
 
     default:  /* unimplemented */
-        av_log_missing_feature(NULL, "RTP-X-QT with packing scheme 2", 1);
+        avpriv_request_sample(NULL, "RTP-X-QT with packing scheme 2");
         return AVERROR_PATCHWELCOME;
     }
 }
diff --git a/libavformat/rtpdec_vp8.c b/libavformat/rtpdec_vp8.c
index 18275a5..fc86ac1 100644
--- a/libavformat/rtpdec_vp8.c
+++ b/libavformat/rtpdec_vp8.c
@@ -35,11 +35,21 @@ struct PayloadContext {
     AVIOContext *data;
     uint32_t     timestamp;
     int          is_keyframe;
+    /* If sequence_ok is set, we keep returning data (even if we might have
+     * lost some data, but we haven't lost any too critical data that would
+     * cause the decoder to desynchronize and output random garbage).
+     */
     int          sequence_ok;
     int          first_part_size;
     uint16_t     prev_seq;
     int          prev_pictureid;
     int          broken_frame;
+    /* If sequence_dirty is set, we have lost some data (critical or
+     * non-critical) and decoding will have some sort of artefacts, and
+     * we thus should request a new keyframe.
+     */
+    int          sequence_dirty;
+    int          got_keyframe;
 };
 
 static void vp8_free_buffer(PayloadContext *vp8)
@@ -70,15 +80,18 @@ static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,
     int extended_bits, part_id;
     int pictureid_present = 0, tl0picidx_present = 0, tid_present = 0,
         keyidx_present = 0;
-    int pictureid = -1, pictureid_mask;
+    int pictureid = -1, pictureid_mask = 0;
     int returned_old_frame = 0;
-    uint32_t old_timestamp;
+    uint32_t old_timestamp = 0;
 
     if (!buf) {
         if (vp8->data) {
             int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);
             if (ret < 0)
                 return ret;
+            *timestamp = vp8->timestamp;
+            if (vp8->sequence_dirty)
+                pkt->flags |= AV_PKT_FLAG_CORRUPT;
             return 0;
         }
         return AVERROR(EAGAIN);
@@ -140,11 +153,15 @@ static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,
             vp8_free_buffer(vp8);
             // Keyframe, decoding ok again
             vp8->sequence_ok = 1;
+            vp8->sequence_dirty = 0;
+            vp8->got_keyframe = 1;
         } else {
             int can_continue = vp8->data && !vp8->is_keyframe &&
                                avio_tell(vp8->data) >= vp8->first_part_size;
             if (!vp8->sequence_ok)
                 return AVERROR(EAGAIN);
+            if (!vp8->got_keyframe)
+                return vp8_broken_sequence(ctx, vp8, "Keyframe missing\n");
             if (pictureid >= 0) {
                 if (pictureid != ((vp8->prev_pictureid + 1) & pictureid_mask)) {
                     return vp8_broken_sequence(ctx, vp8,
@@ -178,11 +195,12 @@ static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,
                 }
             }
             if (vp8->data) {
+                vp8->sequence_dirty = 1;
                 if (avio_tell(vp8->data) >= vp8->first_part_size) {
                     int ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);
                     if (ret < 0)
                         return ret;
-                    pkt->size = vp8->first_part_size;
+                    pkt->flags |= AV_PKT_FLAG_CORRUPT;
                     returned_old_frame = 1;
                     old_timestamp = vp8->timestamp;
                 } else {
@@ -206,11 +224,8 @@ static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,
 
         if (vp8->timestamp != *timestamp) {
             // Missed the start of the new frame, sequence broken
-            vp8->sequence_ok = 0;
-            av_log(ctx, AV_LOG_WARNING,
-                   "Received no start marker; dropping frame\n");
-            vp8_free_buffer(vp8);
-            return AVERROR(EAGAIN);
+            return vp8_broken_sequence(ctx, vp8,
+                                       "Received no start marker; dropping frame\n");
         }
 
         if (seq != expected_seq) {
@@ -219,6 +234,7 @@ static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,
                                            "Missed part of a keyframe, sequence broken\n");
             } else if (vp8->data && avio_tell(vp8->data) >= vp8->first_part_size) {
                 vp8->broken_frame = 1;
+                vp8->sequence_dirty = 1;
             } else {
                 return vp8_broken_sequence(ctx, vp8,
                                            "Missed part of the first partition, sequence broken\n");
@@ -230,19 +246,21 @@ static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,
         return vp8_broken_sequence(ctx, vp8, "Received no start marker\n");
 
     vp8->prev_seq = seq;
-    avio_write(vp8->data, buf, len);
+    if (!vp8->broken_frame)
+        avio_write(vp8->data, buf, len);
+
+    if (returned_old_frame) {
+        *timestamp = old_timestamp;
+        return end_packet ? 1 : 0;
+    }
 
     if (end_packet) {
         int ret;
-        if (returned_old_frame) {
-            *timestamp = old_timestamp;
-            return 1;
-        }
         ret = ff_rtp_finalize_packet(pkt, &vp8->data, st->index);
         if (ret < 0)
             return ret;
-        if (vp8->broken_frame)
-            pkt->size = vp8->first_part_size;
+        if (vp8->sequence_dirty)
+            pkt->flags |= AV_PKT_FLAG_CORRUPT;
         return 0;
     }
 
@@ -251,7 +269,11 @@ static int vp8_handle_packet(AVFormatContext *ctx, PayloadContext *vp8,
 
 static PayloadContext *vp8_new_context(void)
 {
-    return av_mallocz(sizeof(PayloadContext));
+    PayloadContext *vp8 = av_mallocz(sizeof(PayloadContext));
+    if (!vp8)
+        return NULL;
+    vp8->sequence_ok = 1;
+    return vp8;
 }
 
 static void vp8_free_context(PayloadContext *vp8)
@@ -260,6 +282,11 @@ static void vp8_free_context(PayloadContext *vp8)
     av_free(vp8);
 }
 
+static int vp8_need_keyframe(PayloadContext *vp8)
+{
+    return vp8->sequence_dirty || !vp8->sequence_ok;
+}
+
 RTPDynamicProtocolHandler ff_vp8_dynamic_handler = {
     .enc_name       = "VP8",
     .codec_type     = AVMEDIA_TYPE_VIDEO,
@@ -267,4 +294,5 @@ RTPDynamicProtocolHandler ff_vp8_dynamic_handler = {
     .alloc          = vp8_new_context,
     .free           = vp8_free_context,
     .parse_packet   = vp8_handle_packet,
+    .need_keyframe  = vp8_need_keyframe,
 };
diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c
index db39462..2049e4f 100644
--- a/libavformat/rtpdec_xiph.c
+++ b/libavformat/rtpdec_xiph.c
@@ -27,6 +27,7 @@
  * @author Josh Allmann <joshua.allmann at gmail.com>
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
 #include "libavutil/base64.h"
 #include "libavcodec/bytestream.h"
@@ -70,6 +71,16 @@ static void xiph_free_context(PayloadContext * data)
     av_free(data);
 }
 
+static av_cold int xiph_vorbis_init(AVFormatContext *ctx, int st_index,
+                                    PayloadContext *data)
+{
+    if (st_index < 0)
+        return 0;
+    ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_HEADERS;
+    return 0;
+}
+
+
 static int xiph_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                               AVStream *st, AVPacket *pkt, uint32_t *timestamp,
                               const uint8_t *buf, int len, uint16_t seq,
@@ -392,6 +403,7 @@ RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = {
     .enc_name         = "vorbis",
     .codec_type       = AVMEDIA_TYPE_AUDIO,
     .codec_id         = AV_CODEC_ID_VORBIS,
+    .init             = xiph_vorbis_init,
     .parse_sdp_a_line = xiph_parse_sdp_line,
     .alloc            = xiph_new_context,
     .free             = xiph_free_context,
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 0f5307d..83167eb 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -28,13 +28,12 @@
 
 #include "rtpenc.h"
 
-//#define DEBUG
-
 static const AVOption options[] = {
     FF_RTP_FLAG_OPTS(RTPMuxContext, flags),
     { "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM },
     { "ssrc", "Stream identifier", offsetof(RTPMuxContext, ssrc), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
     { "cname", "CNAME to include in RTCP SR packets", offsetof(RTPMuxContext, cname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+    { "seq", "Starting sequence number", offsetof(RTPMuxContext, seq), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 65535, AV_OPT_FLAG_ENCODING_PARAM },
     { NULL },
 };
 
@@ -124,6 +123,13 @@ static int rtp_write_header(AVFormatContext *s1)
         /* Round the NTP time to whole milliseconds. */
         s->first_rtcp_ntp_time = (s1->start_time_realtime / 1000) * 1000 +
                                  NTP_OFFSET_US;
+    // Pick a random sequence start number, but in the lower end of the
+    // available range, so that any wraparound doesn't happen immediately.
+    // (Immediate wraparound would be an issue for SRTP.)
+    if (s->seq < 0)
+        s->seq = av_get_random_seed() & 0x0fff;
+    else
+        s->seq &= 0xffff; // Use the given parameter, wrapped to the right interval
 
     if (s1->packet_size) {
         if (s1->pb->max_packet_size)
@@ -253,7 +259,7 @@ fail:
 }
 
 /* send an rtcp sender report packet */
-static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
+static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time, int bye)
 {
     RTPMuxContext *s = s1->priv_data;
     uint32_t rtp_ts;
@@ -263,12 +269,11 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
     s->last_rtcp_ntp_time = ntp_time;
     rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000},
                           s1->streams[0]->time_base) + s->base_timestamp;
-    avio_w8(s1->pb, (RTP_VERSION << 6));
+    avio_w8(s1->pb, RTP_VERSION << 6);
     avio_w8(s1->pb, RTCP_SR);
     avio_wb16(s1->pb, 6); /* length in words - 1 */
     avio_wb32(s1->pb, s->ssrc);
-    avio_wb32(s1->pb, ntp_time / 1000000);
-    avio_wb32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000);
+    avio_wb64(s1->pb, NTP_TO_RTP_FORMAT(ntp_time));
     avio_wb32(s1->pb, rtp_ts);
     avio_wb32(s1->pb, s->packet_count);
     avio_wb32(s1->pb, s->octet_count);
@@ -288,6 +293,13 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
             avio_w8(s1->pb, 0);
     }
 
+    if (bye) {
+        avio_w8(s1->pb, (RTP_VERSION << 6) | 1);
+        avio_w8(s1->pb, RTCP_BYE);
+        avio_wb16(s1->pb, 1); /* length in words - 1 */
+        avio_wb32(s1->pb, s->ssrc);
+    }
+
     avio_flush(s1->pb);
 }
 
@@ -300,7 +312,7 @@ void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
     av_dlog(s1, "rtp_send_data size=%d\n", len);
 
     /* build the RTP header */
-    avio_w8(s1->pb, (RTP_VERSION << 6));
+    avio_w8(s1->pb, RTP_VERSION << 6);
     avio_w8(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
     avio_wb16(s1->pb, s->seq);
     avio_wb32(s1->pb, s->timestamp);
@@ -309,7 +321,7 @@ void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
     avio_write(s1->pb, buf1, len);
     avio_flush(s1->pb);
 
-    s->seq++;
+    s->seq = (s->seq + 1) & 0xffff;
     s->octet_count += len;
     s->packet_count++;
 }
@@ -486,7 +498,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
     if ((s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) &&
                             (ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) &&
         !(s->flags & FF_RTP_FLAG_SKIP_RTCP)) {
-        rtcp_send_sr(s1, ff_ntp_time());
+        rtcp_send_sr(s1, ff_ntp_time(), 0);
         s->last_octet_count = s->octet_count;
         s->first_packet = 0;
     }
@@ -582,6 +594,10 @@ static int rtp_write_trailer(AVFormatContext *s1)
 {
     RTPMuxContext *s = s1->priv_data;
 
+    /* If the caller closes and recreates ->pb, this might actually
+     * be NULL here even if it was successfully allocated at the start. */
+    if (s1->pb && (s->flags & FF_RTP_FLAG_SEND_BYE))
+        rtcp_send_sr(s1, ff_ntp_time(), 1);
     av_freep(&s->buf);
 
     return 0;
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index f797348..35ee151 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -31,18 +31,16 @@ struct RTPMuxContext {
     int payload_type;
     uint32_t ssrc;
     const char *cname;
-    uint16_t seq;
+    int seq;
     uint32_t timestamp;
     uint32_t base_timestamp;
     uint32_t cur_timestamp;
     int max_payload_size;
     int num_frames;
 
-    /* rtcp sender statistics receive */
+    /* rtcp sender statistics */
     int64_t last_rtcp_ntp_time;
     int64_t first_rtcp_ntp_time;
-
-    /* rtcp sender statistics */
     unsigned int packet_count;
     unsigned int octet_count;
     unsigned int last_octet_count;
@@ -70,13 +68,15 @@ typedef struct RTPMuxContext RTPMuxContext;
 #define FF_RTP_FLAG_RFC2190   2
 #define FF_RTP_FLAG_SKIP_RTCP 4
 #define FF_RTP_FLAG_H264_MODE0 8
+#define FF_RTP_FLAG_SEND_BYE  16
 
 #define FF_RTP_FLAG_OPTS(ctx, fieldname) \
     { "rtpflags", "RTP muxer flags", offsetof(ctx, fieldname), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
     { "latm", "Use MP4A-LATM packetization instead of MPEG4-GENERIC for AAC", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_MP4A_LATM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
     { "rfc2190", "Use RFC 2190 packetization instead of RFC 4629 for H.263", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_RFC2190}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
     { "skip_rtcp", "Don't send RTCP sender reports", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_SKIP_RTCP}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
-    { "h264_mode0", "Use mode 0 for H264 in RTP", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_H264_MODE0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \
+    { "h264_mode0", "Use mode 0 for H264 in RTP", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_H264_MODE0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" }, \
+    { "send_bye", "Send RTCP BYE packets when finishing", 0, AV_OPT_TYPE_CONST, {.i64 = FF_RTP_FLAG_SEND_BYE}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "rtpflags" } \
 
 void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m);
 
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index 935dd6c..10c4020 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -75,16 +75,19 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
     avcodec_copy_context(rtpctx->streams[0]->codec, st->codec);
 
     if (handle) {
-        ffio_fdopen(&rtpctx->pb, handle);
+        ret = ffio_fdopen(&rtpctx->pb, handle);
+        if (ret < 0)
+            ffurl_close(handle);
     } else
-        ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
-    ret = avformat_write_header(rtpctx, &opts);
+        ret = ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
+    if (!ret)
+        ret = avformat_write_header(rtpctx, &opts);
     av_dict_free(&opts);
 
     if (ret) {
-        if (handle) {
+        if (handle && rtpctx->pb) {
             avio_close(rtpctx->pb);
-        } else {
+        } else if (rtpctx->pb) {
             uint8_t *ptr;
             avio_close_dyn_buf(rtpctx->pb, &ptr);
             av_free(ptr);
diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c
index ac74074..206d9ba 100644
--- a/libavformat/rtpenc_h264.c
+++ b/libavformat/rtpenc_h264.c
@@ -31,14 +31,14 @@
 
 static const uint8_t *avc_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)
 {
-    int res = 0;
+    unsigned int res = 0;
 
     if (end - start < nal_length_size)
         return NULL;
     while (nal_length_size--)
         res = (res << 8) | *start++;
 
-    if (start + res > end || res < 0 || start + res < start)
+    if (res > end - start)
         return NULL;
 
     return start + res;
diff --git a/libavformat/rtpenc_mpv.c b/libavformat/rtpenc_mpv.c
index 37dedc3..70248c4 100644
--- a/libavformat/rtpenc_mpv.c
+++ b/libavformat/rtpenc_mpv.c
@@ -20,7 +20,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavcodec/mpegvideo.h"
+#include "libavcodec/internal.h"
 #include "avformat.h"
 #include "rtpenc.h"
 
@@ -56,7 +56,7 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size)
             r1 = buf1;
             while (1) {
                 start_code = -1;
-                r = avpriv_mpv_find_start_code(r1, end, &start_code);
+                r = avpriv_find_start_code(r1, end, &start_code);
                 if((start_code & 0xFFFFFF00) == 0x100) {
                     /* New start code found */
                     if (start_code == 0x100) {
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index 190dff4..0f31539 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -28,7 +28,8 @@
 #include "libavutil/avstring.h"
 #include "avformat.h"
 #include "avio_internal.h"
-#include "rtpdec.h"
+#include "rtp.h"
+#include "rtpproto.h"
 #include "url.h"
 
 #include <stdarg.h>
@@ -42,7 +43,11 @@
 
 typedef struct RTPContext {
     URLContext *rtp_hd, *rtcp_hd;
-    int rtp_fd, rtcp_fd;
+    int rtp_fd, rtcp_fd, nb_ssm_include_addrs, nb_ssm_exclude_addrs;
+    struct sockaddr_storage **ssm_include_addrs, **ssm_exclude_addrs;
+    int write_to_source;
+    struct sockaddr_storage last_rtp_source, last_rtcp_source;
+    socklen_t last_rtp_source_len, last_rtcp_source_len;
 } RTPContext;
 
 /**
@@ -59,22 +64,109 @@ int ff_rtp_set_remote_url(URLContext *h, const char *uri)
 {
     RTPContext *s = h->priv_data;
     char hostname[256];
-    int port;
+    int port, rtcp_port;
+    const char *p;
 
     char buf[1024];
     char path[1024];
 
     av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port,
                  path, sizeof(path), uri);
+    rtcp_port = port + 1;
+
+    p = strchr(uri, '?');
+    if (p) {
+        if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
+            rtcp_port = strtol(buf, NULL, 10);
+        }
+    }
 
     ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port, "%s", path);
     ff_udp_set_remote_url(s->rtp_hd, buf);
 
-    ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port + 1, "%s", path);
+    ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, rtcp_port, "%s", path);
     ff_udp_set_remote_url(s->rtcp_hd, buf);
     return 0;
 }
 
+static struct addrinfo* rtp_resolve_host(const char *hostname, int port,
+                                         int type, int family, int flags)
+{
+    struct addrinfo hints = { 0 }, *res = 0;
+    int error;
+    char service[16];
+
+    snprintf(service, sizeof(service), "%d", port);
+    hints.ai_socktype = type;
+    hints.ai_family   = family;
+    hints.ai_flags    = flags;
+    if ((error = getaddrinfo(hostname, service, &hints, &res))) {
+        res = NULL;
+        av_log(NULL, AV_LOG_ERROR, "rtp_resolve_host: %s\n", gai_strerror(error));
+    }
+
+    return res;
+}
+
+static int compare_addr(const struct sockaddr_storage *a,
+                        const struct sockaddr_storage *b)
+{
+    if (a->ss_family != b->ss_family)
+        return 1;
+    if (a->ss_family == AF_INET) {
+        return (((const struct sockaddr_in *)a)->sin_addr.s_addr !=
+                ((const struct sockaddr_in *)b)->sin_addr.s_addr);
+    }
+
+#if HAVE_STRUCT_SOCKADDR_IN6
+    if (a->ss_family == AF_INET6) {
+        const uint8_t *s6_addr_a = ((const struct sockaddr_in6 *)a)->sin6_addr.s6_addr;
+        const uint8_t *s6_addr_b = ((const struct sockaddr_in6 *)b)->sin6_addr.s6_addr;
+        return memcmp(s6_addr_a, s6_addr_b, 16);
+    }
+#endif
+    return 1;
+}
+
+static int get_port(const struct sockaddr_storage *ss)
+{
+    if (ss->ss_family == AF_INET)
+        return ntohs(((const struct sockaddr_in *)ss)->sin_port);
+#if HAVE_STRUCT_SOCKADDR_IN6
+    if (ss->ss_family == AF_INET6)
+        return ntohs(((const struct sockaddr_in6 *)ss)->sin6_port);
+#endif
+    return 0;
+}
+
+static void set_port(struct sockaddr_storage *ss, int port)
+{
+    if (ss->ss_family == AF_INET)
+        ((struct sockaddr_in *)ss)->sin_port = htons(port);
+#if HAVE_STRUCT_SOCKADDR_IN6
+    else if (ss->ss_family == AF_INET6)
+        ((struct sockaddr_in6 *)ss)->sin6_port = htons(port);
+#endif
+}
+
+static int rtp_check_source_lists(RTPContext *s, struct sockaddr_storage *source_addr_ptr)
+{
+    int i;
+    if (s->nb_ssm_exclude_addrs) {
+        for (i = 0; i < s->nb_ssm_exclude_addrs; i++) {
+            if (!compare_addr(source_addr_ptr, s->ssm_exclude_addrs[i]))
+                return 1;
+        }
+    }
+    if (s->nb_ssm_include_addrs) {
+        for (i = 0; i < s->nb_ssm_include_addrs; i++) {
+            if (!compare_addr(source_addr_ptr, s->ssm_include_addrs[i]))
+                return 0;
+        }
+        return 1;
+    }
+    return 0;
+}
 
 /**
  * add option to url of the form:
@@ -99,7 +191,9 @@ static av_printf_format(3, 4) void url_add_option(char *buf, int buf_size, const
 static void build_udp_url(char *buf, int buf_size,
                           const char *hostname, int port,
                           int local_port, int ttl,
-                          int max_packet_size, int connect)
+                          int max_packet_size, int connect,
+                          const char *include_sources,
+                          const char *exclude_sources)
 {
     ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL);
     if (local_port >= 0)
@@ -110,6 +204,50 @@ static void build_udp_url(char *buf, int buf_size,
         url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size);
     if (connect)
         url_add_option(buf, buf_size, "connect=1");
+    if (include_sources && include_sources[0])
+        url_add_option(buf, buf_size, "sources=%s", include_sources);
+    if (exclude_sources && exclude_sources[0])
+        url_add_option(buf, buf_size, "block=%s", exclude_sources);
+}
+
+static void rtp_parse_addr_list(URLContext *h, char *buf,
+                                struct sockaddr_storage ***address_list_ptr,
+                                int *address_list_size_ptr)
+{
+    struct addrinfo *ai = NULL;
+    struct sockaddr_storage *source_addr;
+    char tmp = '\0', *p = buf, *next;
+
+    /* Resolve all of the IPs */
+
+    while (p && p[0]) {
+        next = strchr(p, ',');
+
+        if (next) {
+            tmp = *next;
+            *next = '\0';
+        }
+
+        ai = rtp_resolve_host(p, 0, SOCK_DGRAM, AF_UNSPEC, 0);
+        if (ai) {
+            source_addr = av_mallocz(sizeof(struct sockaddr_storage));
+            if (!source_addr)
+                break;
+
+            memcpy(source_addr, ai->ai_addr, ai->ai_addrlen);
+            freeaddrinfo(ai);
+            dynarray_add(address_list_ptr, address_list_size_ptr, source_addr);
+        } else {
+            av_log(h, AV_LOG_WARNING, "Unable to resolve %s\n", p);
+        }
+
+        if (next) {
+            *next = tmp;
+            p = next + 1;
+        } else {
+            p = NULL;
+        }
+    }
 }
 
 /**
@@ -120,6 +258,9 @@ static void build_udp_url(char *buf, int buf_size,
  *         'localrtcpport=n'  : set the local rtcp port to n
  *         'pkt_size=n'       : set max packet size
  *         'connect=0/1'      : do a connect() on the UDP socket
+ *         'sources=ip[,ip]'  : list allowed source IP addresses
+ *         'block=ip[,ip]'    : list disallowed source IP addresses
+ *         'write_to_source=0/1' : send packets to the source address of the latest received packet
  * deprecated option:
  *         'localport=n'      : set the local port to n
  *
@@ -135,7 +276,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
     int rtp_port, rtcp_port,
         ttl, connect,
         local_rtp_port, local_rtcp_port, max_packet_size;
-    char hostname[256];
+    char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "";
     char buf[1024];
     char path[1024];
     const char *p;
@@ -173,11 +314,22 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
         if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
             connect = strtol(buf, NULL, 10);
         }
+        if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
+            s->write_to_source = strtol(buf, NULL, 10);
+        }
+        if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
+            av_strlcpy(include_sources, buf, sizeof(include_sources));
+            rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
+        }
+        if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
+            av_strlcpy(exclude_sources, buf, sizeof(exclude_sources));
+            rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
+        }
     }
 
     build_udp_url(buf, sizeof(buf),
                   hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
-                  connect);
+                  connect, include_sources, exclude_sources);
     if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
         goto fail;
     if (local_rtp_port>=0 && local_rtcp_port<0)
@@ -185,7 +337,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
 
     build_udp_url(buf, sizeof(buf),
                   hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
-                  connect);
+                  connect, include_sources, exclude_sources);
     if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
         goto fail;
 
@@ -209,48 +361,41 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
 static int rtp_read(URLContext *h, uint8_t *buf, int size)
 {
     RTPContext *s = h->priv_data;
-    struct sockaddr_storage from;
-    socklen_t from_len;
-    int len, n;
+    int len, n, i;
     struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
+    int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : 100;
+    struct sockaddr_storage *addrs[2] = { &s->last_rtp_source, &s->last_rtcp_source };
+    socklen_t *addr_lens[2] = { &s->last_rtp_source_len, &s->last_rtcp_source_len };
 
     for(;;) {
         if (ff_check_interrupt(&h->interrupt_callback))
             return AVERROR_EXIT;
-        /* build fdset to listen to RTP and RTCP packets */
-        n = poll(p, 2, 100);
+        n = poll(p, 2, poll_delay);
         if (n > 0) {
-            /* first try RTCP */
-            if (p[1].revents & POLLIN) {
-                from_len = sizeof(from);
-                len = recvfrom (s->rtcp_fd, buf, size, 0,
-                                (struct sockaddr *)&from, &from_len);
-                if (len < 0) {
-                    if (ff_neterrno() == AVERROR(EAGAIN) ||
-                        ff_neterrno() == AVERROR(EINTR))
-                        continue;
-                    return AVERROR(EIO);
-                }
-                break;
-            }
-            /* then RTP */
-            if (p[0].revents & POLLIN) {
-                from_len = sizeof(from);
-                len = recvfrom (s->rtp_fd, buf, size, 0,
-                                (struct sockaddr *)&from, &from_len);
+            /* first try RTCP, then RTP */
+            for (i = 1; i >= 0; i--) {
+                if (!(p[i].revents & POLLIN))
+                    continue;
+                *addr_lens[i] = sizeof(*addrs[i]);
+                len = recvfrom(p[i].fd, buf, size, 0,
+                                (struct sockaddr *)addrs[i], addr_lens[i]);
                 if (len < 0) {
                     if (ff_neterrno() == AVERROR(EAGAIN) ||
                         ff_neterrno() == AVERROR(EINTR))
                         continue;
                     return AVERROR(EIO);
                 }
-                break;
+                if (rtp_check_source_lists(s, addrs[i]))
+                    continue;
+                return len;
             }
         } else if (n < 0) {
             if (ff_neterrno() == AVERROR(EINTR))
                 continue;
             return AVERROR(EIO);
         }
+        if (h->flags & AVIO_FLAG_NONBLOCK)
+            return AVERROR(EAGAIN);
     }
     return len;
 }
@@ -261,6 +406,60 @@ static int rtp_write(URLContext *h, const uint8_t *buf, int size)
     int ret;
     URLContext *hd;
 
+    if (size < 2)
+        return AVERROR(EINVAL);
+
+    if (s->write_to_source) {
+        int fd;
+        struct sockaddr_storage *source, temp_source;
+        socklen_t *source_len, temp_len;
+        if (!s->last_rtp_source.ss_family && !s->last_rtcp_source.ss_family) {
+            av_log(h, AV_LOG_ERROR,
+                   "Unable to send packet to source, no packets received yet\n");
+            // Intentionally not returning an error here
+            return size;
+        }
+
+        if (RTP_PT_IS_RTCP(buf[1])) {
+            fd = s->rtcp_fd;
+            source     = &s->last_rtcp_source;
+            source_len = &s->last_rtcp_source_len;
+        } else {
+            fd = s->rtp_fd;
+            source     = &s->last_rtp_source;
+            source_len = &s->last_rtp_source_len;
+        }
+        if (!source->ss_family) {
+            source      = &temp_source;
+            source_len  = &temp_len;
+            if (RTP_PT_IS_RTCP(buf[1])) {
+                temp_source = s->last_rtp_source;
+                temp_len    = s->last_rtp_source_len;
+                set_port(source, get_port(source) + 1);
+                av_log(h, AV_LOG_INFO,
+                       "Not received any RTCP packets yet, inferring peer port "
+                       "from the RTP port\n");
+            } else {
+                temp_source = s->last_rtcp_source;
+                temp_len    = s->last_rtcp_source_len;
+                set_port(source, get_port(source) - 1);
+                av_log(h, AV_LOG_INFO,
+                       "Not received any RTP packets yet, inferring peer port "
+                       "from the RTCP port\n");
+            }
+        }
+
+        if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+            ret = ff_network_wait_fd(fd, 1);
+            if (ret < 0)
+                return ret;
+        }
+        ret = sendto(fd, buf, size, 0, (struct sockaddr *) source,
+                     *source_len);
+
+        return ret < 0 ? ff_neterrno() : ret;
+    }
+
     if (RTP_PT_IS_RTCP(buf[1])) {
         /* RTCP payload type */
         hd = s->rtcp_hd;
@@ -276,6 +475,14 @@ static int rtp_write(URLContext *h, const uint8_t *buf, int size)
 static int rtp_close(URLContext *h)
 {
     RTPContext *s = h->priv_data;
+    int i;
+
+    for (i = 0; i < s->nb_ssm_include_addrs; i++)
+        av_free(s->ssm_include_addrs[i]);
+    av_freep(&s->ssm_include_addrs);
+    for (i = 0; i < s->nb_ssm_exclude_addrs; i++)
+        av_free(s->ssm_exclude_addrs[i]);
+    av_freep(&s->ssm_exclude_addrs);
 
     ffurl_close(s->rtp_hd);
     ffurl_close(s->rtcp_hd);
diff --git a/libavformat/rtpproto.h b/libavformat/rtpproto.h
new file mode 100644
index 0000000..7acc80e
--- /dev/null
+++ b/libavformat/rtpproto.h
@@ -0,0 +1,31 @@
+/*
+ * RTP network protocol
+ *
+ * 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 AVFORMAT_RTPPROTO_H
+#define AVFORMAT_RTPPROTO_H
+
+#include "url.h"
+
+int ff_rtp_set_remote_url(URLContext *h, const char *uri);
+
+int ff_rtp_get_local_rtp_port(URLContext *h);
+int ff_rtp_get_local_rtcp_port(URLContext *h);
+
+#endif /* AVFORMAT_RTPPROTO_H */
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 134b322..b95be46 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -41,6 +41,7 @@
 #include "rtsp.h"
 
 #include "rtpdec.h"
+#include "rtpproto.h"
 #include "rdt.h"
 #include "rtpdec_formats.h"
 #include "rtpenc_chain.h"
@@ -48,8 +49,6 @@
 #include "rtpenc.h"
 #include "mpegts.h"
 
-//#define DEBUG
-
 /* Timeout values for socket poll, in ms,
  * and read_packet(), in seconds  */
 #define POLL_TIMEOUT_MS 100
@@ -65,8 +64,7 @@
 
 #define RTSP_FLAG_OPTS(name, longname) \
     { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
-    { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }, \
-    { "listen", "Wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" }
+    { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }
 
 #define RTSP_MEDIATYPE_OPTS(name, longname) \
     { name, longname, OFFSET(media_type_mask), AV_OPT_TYPE_FLAGS, { .i64 = (1 << (AVMEDIA_TYPE_DATA+1)) - 1 }, INT_MIN, INT_MAX, DEC, "allowed_media_types" }, \
@@ -86,6 +84,7 @@ const AVOption ff_rtsp_options[] = {
     { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
     { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
     RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"),
+    { "listen", "Wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" },
     RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
     { "min_port", "Minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC },
     { "max_port", "Maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC },
@@ -97,6 +96,7 @@ const AVOption ff_rtsp_options[] = {
 static const AVOption sdp_options[] = {
     RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
     { "custom_io", "Use custom IO", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, "rtsp_flags" },
+    { "rtcp_to_source", "Send RTCP packets to the source address of received packets", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_RTCP_TO_SOURCE}, 0, 0, DEC, "rtsp_flags" },
     RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
     RTSP_REORDERING_OPTS(),
     { NULL },
@@ -180,7 +180,8 @@ static void init_rtp_handler(RTPDynamicProtocolHandler *handler,
 {
     if (!handler)
         return;
-    codec->codec_id          = handler->codec_id;
+    if (codec)
+        codec->codec_id          = handler->codec_id;
     rtsp_st->dynamic_handler = handler;
     if (handler->alloc) {
         rtsp_st->dynamic_protocol_context = handler->alloc();
@@ -200,8 +201,7 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
     AVCodec *c;
     const char *c_name;
 
-    /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and
-     * see if we can handle this kind of payload.
+    /* See if we can handle this kind of payload.
      * The space should normally not be there but some Real streams or
      * particular servers ("RealServer Version 6.1.3.970", see issue 1658)
      * have a trailing space. */
@@ -209,7 +209,6 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
     if (payload_type < RTP_PT_PRIVATE) {
         /* We are in a standard case
          * (from http://www.iana.org/assignments/rtp-parameters). */
-        /* search into AVRtpPayloadTypes[] */
         codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
     }
 
@@ -245,10 +244,6 @@ static int sdp_parse_rtpmap(AVFormatContext *s,
             i = atoi(buf);
             if (i > 0)
                 codec->channels = i;
-            // TODO: there is a bug here; if it is a mono stream, and
-            // less than 22000Hz, faad upconverts to stereo and twice
-            // the frequency.  No problem, but the sample rate is being
-            // set here by the sdp line. Patch on its way. (rdm)
         }
         av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n",
                codec->sample_rate);
@@ -293,8 +288,27 @@ typedef struct SDPParseState {
     struct sockaddr_storage default_ip;
     int            default_ttl;
     int            skip_media;  ///< set if an unknown m= line occurs
+    int nb_default_include_source_addrs; /**< Number of source-specific multicast include source IP address (from SDP content) */
+    struct RTSPSource **default_include_source_addrs; /**< Source-specific multicast include source IP address (from SDP content) */
+    int nb_default_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP address (from SDP content) */
+    struct RTSPSource **default_exclude_source_addrs; /**< Source-specific multicast exclude source IP address (from SDP content) */
 } SDPParseState;
 
+static void copy_default_source_addrs(struct RTSPSource **addrs, int count,
+                                      struct RTSPSource ***dest, int *dest_count)
+{
+    RTSPSource *rtsp_src, *rtsp_src2;
+    int i;
+    for (i = 0; i < count; i++) {
+        rtsp_src = addrs[i];
+        rtsp_src2 = av_malloc(sizeof(*rtsp_src2));
+        if (!rtsp_src2)
+            continue;
+        memcpy(rtsp_src2, rtsp_src, sizeof(*rtsp_src));
+        dynarray_add(dest, dest_count, rtsp_src2);
+    }
+}
+
 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
                            int letter, const char *buf)
 {
@@ -305,6 +319,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
     int payload_type, i;
     AVStream *st;
     RTSPStream *rtsp_st;
+    RTSPSource *rtsp_src;
     struct sockaddr_storage sdp_ip;
     int ttl;
 
@@ -373,12 +388,23 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
         rtsp_st->sdp_ip = s1->default_ip;
         rtsp_st->sdp_ttl = s1->default_ttl;
 
+        copy_default_source_addrs(s1->default_include_source_addrs,
+                                  s1->nb_default_include_source_addrs,
+                                  &rtsp_st->include_source_addrs,
+                                  &rtsp_st->nb_include_source_addrs);
+        copy_default_source_addrs(s1->default_exclude_source_addrs,
+                                  s1->nb_default_exclude_source_addrs,
+                                  &rtsp_st->exclude_source_addrs,
+                                  &rtsp_st->nb_exclude_source_addrs);
+
         get_word(buf1, sizeof(buf1), &p); /* port */
         rtsp_st->sdp_port = atoi(buf1);
 
         get_word(buf1, sizeof(buf1), &p); /* protocol */
         if (!strcmp(buf1, "udp"))
             rt->transport = RTSP_TRANSPORT_RAW;
+        else if (strstr(buf1, "/AVPF") || strstr(buf1, "/SAVPF"))
+            rtsp_st->feedback = 1;
 
         /* XXX: handle list of formats */
         get_word(buf1, sizeof(buf1), &p); /* format list */
@@ -386,8 +412,17 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
 
         if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
             /* no corresponding stream */
-            if (rt->transport == RTSP_TRANSPORT_RAW && !rt->ts && CONFIG_RTPDEC)
-                rt->ts = ff_mpegts_parse_open(s);
+            if (rt->transport == RTSP_TRANSPORT_RAW) {
+                if (!rt->ts && CONFIG_RTPDEC)
+                    rt->ts = ff_mpegts_parse_open(s);
+            } else {
+                RTPDynamicProtocolHandler *handler;
+                handler = ff_rtp_handler_find_by_id(
+                              rtsp_st->sdp_payload_type, AVMEDIA_TYPE_DATA);
+                init_rtp_handler(handler, rtsp_st, NULL);
+                if (handler && handler->init)
+                    handler->init(s, -1, rtsp_st->dynamic_protocol_context);
+            }
         } else if (rt->server_type == RTSP_SERVER_WMS &&
                    codec_type == AVMEDIA_TYPE_DATA) {
             /* RTX stream, a stream that carries all the other actual
@@ -483,6 +518,51 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
                    s->nb_streams > 0) {
             st = s->streams[s->nb_streams - 1];
             st->codec->sample_rate = atoi(p);
+        } else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
+            // RFC 4568
+            rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+            get_word(buf1, sizeof(buf1), &p); // ignore tag
+            get_word(rtsp_st->crypto_suite, sizeof(rtsp_st->crypto_suite), &p);
+            p += strspn(p, SPACE_CHARS);
+            if (av_strstart(p, "inline:", &p))
+                get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p);
+        } else if (av_strstart(p, "source-filter:", &p)) {
+            int exclude = 0;
+            get_word(buf1, sizeof(buf1), &p);
+            if (strcmp(buf1, "incl") && strcmp(buf1, "excl"))
+                return;
+            exclude = !strcmp(buf1, "excl");
+
+            get_word(buf1, sizeof(buf1), &p);
+            if (strcmp(buf1, "IN") != 0)
+                return;
+            get_word(buf1, sizeof(buf1), &p);
+            if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6") && strcmp(buf1, "*"))
+                return;
+            // not checking that the destination address actually matches or is wildcard
+            get_word(buf1, sizeof(buf1), &p);
+
+            while (*p != '\0') {
+                rtsp_src = av_mallocz(sizeof(*rtsp_src));
+                if (!rtsp_src)
+                    return;
+                get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
+                if (exclude) {
+                    if (s->nb_streams == 0) {
+                        dynarray_add(&s1->default_exclude_source_addrs, &s1->nb_default_exclude_source_addrs, rtsp_src);
+                    } else {
+                        rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+                        dynarray_add(&rtsp_st->exclude_source_addrs, &rtsp_st->nb_exclude_source_addrs, rtsp_src);
+                    }
+                } else {
+                    if (s->nb_streams == 0) {
+                        dynarray_add(&s1->default_include_source_addrs, &s1->nb_default_include_source_addrs, rtsp_src);
+                    } else {
+                        rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+                        dynarray_add(&rtsp_st->include_source_addrs, &rtsp_st->nb_include_source_addrs, rtsp_src);
+                    }
+                }
+            }
         } else {
             if (rt->server_type == RTSP_SERVER_WMS)
                 ff_wms_parse_sdp_a_line(s, p);
@@ -507,7 +587,7 @@ int ff_sdp_parse(AVFormatContext *s, const char *content)
 {
     RTSPState *rt = s->priv_data;
     const char *p;
-    int letter;
+    int letter, i;
     /* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
      * contain long SDP lines containing complete ASF Headers (several
      * kB) or arrays of MDPR (RM stream descriptor) headers plus
@@ -544,13 +624,21 @@ int ff_sdp_parse(AVFormatContext *s, const char *content)
         if (*p == '\n')
             p++;
     }
+
+    for (i = 0; i < s1->nb_default_include_source_addrs; i++)
+        av_free(s1->default_include_source_addrs[i]);
+    av_freep(&s1->default_include_source_addrs);
+    for (i = 0; i < s1->nb_default_exclude_source_addrs; i++)
+        av_free(s1->default_exclude_source_addrs[i]);
+    av_freep(&s1->default_exclude_source_addrs);
+
     rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1));
     if (!rt->p) return AVERROR(ENOMEM);
     return 0;
 }
 #endif /* CONFIG_RTPDEC */
 
-void ff_rtsp_undo_setup(AVFormatContext *s)
+void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
 {
     RTSPState *rt = s->priv_data;
     int i;
@@ -565,6 +653,8 @@ void ff_rtsp_undo_setup(AVFormatContext *s)
                 av_write_trailer(rtpctx);
                 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
                     uint8_t *ptr;
+                    if (CONFIG_RTSP_MUXER && rtpctx->pb && send_packets)
+                        ff_rtsp_tcp_write_packet(s, rtsp_st);
                     avio_close_dyn_buf(rtpctx->pb, &ptr);
                     av_free(ptr);
                 } else {
@@ -587,16 +677,23 @@ void ff_rtsp_undo_setup(AVFormatContext *s)
 void ff_rtsp_close_streams(AVFormatContext *s)
 {
     RTSPState *rt = s->priv_data;
-    int i;
+    int i, j;
     RTSPStream *rtsp_st;
 
-    ff_rtsp_undo_setup(s);
+    ff_rtsp_undo_setup(s, 0);
     for (i = 0; i < rt->nb_rtsp_streams; i++) {
         rtsp_st = rt->rtsp_streams[i];
         if (rtsp_st) {
             if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
                 rtsp_st->dynamic_handler->free(
                     rtsp_st->dynamic_protocol_context);
+            for (j = 0; j < rtsp_st->nb_include_source_addrs; j++)
+                av_free(rtsp_st->include_source_addrs[j]);
+            av_freep(&rtsp_st->include_source_addrs);
+            for (j = 0; j < rtsp_st->nb_exclude_source_addrs; j++)
+                av_free(rtsp_st->exclude_source_addrs[j]);
+            av_freep(&rtsp_st->exclude_source_addrs);
+
             av_free(rtsp_st);
         }
     }
@@ -629,8 +726,8 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
         s->ctx_flags |= AVFMTCTX_NOHEADER;
 
     if (s->oformat && CONFIG_RTSP_MUXER) {
-        int ret = ff_rtp_chain_mux_open(&rtsp_st->transport_priv, s, st,
-                                        rtsp_st->rtp_handle,
+        int ret = ff_rtp_chain_mux_open((AVFormatContext **)&rtsp_st->transport_priv,
+                                        s, st, rtsp_st->rtp_handle,
                                         RTSP_TCP_MAX_PACKET_SIZE,
                                         rtsp_st->stream_index);
         /* Ownership of rtp_handle is passed to the rtp mux context */
@@ -656,6 +753,10 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
                                               rtsp_st->dynamic_protocol_context,
                                               rtsp_st->dynamic_handler);
         }
+        if (rtsp_st->crypto_suite[0])
+            ff_rtp_parse_set_crypto(rtsp_st->transport_priv,
+                                    rtsp_st->crypto_suite,
+                                    rtsp_st->crypto_params);
     }
 
     return 0;
@@ -1100,11 +1201,11 @@ start:
  *
  * @return zero if success, nonzero otherwise
  */
-static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
-                                               const char *method, const char *url,
-                                               const char *headers,
-                                               const unsigned char *send_content,
-                                               int send_content_length)
+static int rtsp_send_cmd_with_content_async(AVFormatContext *s,
+                                            const char *method, const char *url,
+                                            const char *headers,
+                                            const unsigned char *send_content,
+                                            int send_content_length)
 {
     RTSPState *rt = s->priv_data;
     char buf[4096], *out_buf;
@@ -1117,6 +1218,7 @@ static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
     if (headers)
         av_strlcat(buf, headers, sizeof(buf));
     av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
+    av_strlcatf(buf, sizeof(buf), "User-Agent: %s\r\n", LIBAVFORMAT_IDENT);
     if (rt->session_id[0] != '\0' && (!headers ||
         !strstr(headers, "\nIf-Match:"))) {
         av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
@@ -1157,7 +1259,7 @@ static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
 int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
                            const char *url, const char *headers)
 {
-    return ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
+    return rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
 }
 
 int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
@@ -1182,9 +1284,9 @@ int ff_rtsp_send_cmd_with_content(AVFormatContext *s,
 
 retry:
     cur_auth_type = rt->auth_state.auth_type;
-    if ((ret = ff_rtsp_send_cmd_with_content_async(s, method, url, header,
-                                                   send_content,
-                                                   send_content_length)))
+    if ((ret = rtsp_send_cmd_with_content_async(s, method, url, header,
+                                                send_content,
+                                                send_content_length)))
         return ret;
 
     if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0)
@@ -1384,18 +1486,15 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
 
         case RTSP_LOWER_TRANSPORT_UDP: {
             char url[1024], options[30] = "";
+            const char *peer = host;
 
             if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
                 av_strlcpy(options, "?connect=1", sizeof(options));
             /* Use source address if specified */
-            if (reply->transports[0].source[0]) {
-                ff_url_join(url, sizeof(url), "rtp", NULL,
-                            reply->transports[0].source,
-                            reply->transports[0].server_port_min, "%s", options);
-            } else {
-                ff_url_join(url, sizeof(url), "rtp", NULL, host,
-                            reply->transports[0].server_port_min, "%s", options);
-            }
+            if (reply->transports[0].source[0])
+                peer = reply->transports[0].source;
+            ff_url_join(url, sizeof(url), "rtp", NULL, peer,
+                        reply->transports[0].server_port_min, "%s", options);
             if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
                 ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
                 err = AVERROR_INVALIDDATA;
@@ -1452,7 +1551,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
     return 0;
 
 fail:
-    ff_rtsp_undo_setup(s);
+    ff_rtsp_undo_setup(s, 0);
     return err;
 }
 
@@ -1867,6 +1966,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
             rt->cur_transport_priv = NULL;
     }
 
+redo:
     if (rt->transport == RTSP_TRANSPORT_RTP) {
         int i;
         int64_t first_queue_time = 0;
@@ -1882,12 +1982,15 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
                 first_queue_st   = rt->rtsp_streams[i];
             }
         }
-        if (first_queue_time)
+        if (first_queue_time) {
             wait_end = first_queue_time + s->max_delay;
+        } else {
+            wait_end = 0;
+            first_queue_st = NULL;
+        }
     }
 
     /* read next RTP packet */
- redo:
     if (!rt->recvbuf) {
         rt->recvbuf = av_malloc(RECVBUF_SIZE);
         if (!rt->recvbuf)
@@ -1908,7 +2011,11 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
             ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, rtsp_st->rtp_handle, NULL, len);
         break;
     case RTSP_LOWER_TRANSPORT_CUSTOM:
-        len = ffio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE);
+        if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
+            wait_end && wait_end < av_gettime())
+            len = AVERROR(EAGAIN);
+        else
+            len = ffio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE);
         len = pick_stream(s, &rtsp_st, rt->recvbuf, len);
         if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
             ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, NULL, s->pb, len);
@@ -1928,6 +2035,12 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
         ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
     } else if (rt->transport == RTSP_TRANSPORT_RTP) {
         ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
+        if (rtsp_st->feedback) {
+            AVIOContext *pb = NULL;
+            if (rt->lower_transport == RTSP_LOWER_TRANSPORT_CUSTOM)
+                pb = s->pb;
+            ff_rtp_send_rtcp_feedback(rtsp_st->transport_priv, rtsp_st->rtp_handle, pb);
+        }
         if (ret < 0) {
             /* Either bad packet, or a RTCP packet. Check if the
              * first_rtcp_ntp_time field was initialized. */
@@ -2000,7 +2113,7 @@ static int sdp_probe(AVProbeData *p1)
     while (p < p_end && *p != '\0') {
         if (p + sizeof("c=IN IP") - 1 < p_end &&
             av_strstart(p, "c=IN IP", NULL))
-            return AVPROBE_SCORE_MAX / 2;
+            return AVPROBE_SCORE_EXTENSION;
 
         while (p < p_end - 1 && *p != '\n') p++;
         if (++p >= p_end)
@@ -2011,6 +2124,17 @@ static int sdp_probe(AVProbeData *p1)
     return 0;
 }
 
+static void append_source_addrs(char *buf, int size, const char *name,
+                                int count, struct RTSPSource **addrs)
+{
+    int i;
+    if (!count)
+        return;
+    av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
+    for (i = 1; i < count; i++)
+        av_strlcatf(buf, size, ",%s", addrs[i]->addr);
+}
+
 static int sdp_read_header(AVFormatContext *s)
 {
     RTSPState *rt = s->priv_data;
@@ -2051,9 +2175,17 @@ static int sdp_read_header(AVFormatContext *s)
                         namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
             ff_url_join(url, sizeof(url), "rtp", NULL,
                         namebuf, rtsp_st->sdp_port,
-                        "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
-                        rtsp_st->sdp_ttl,
-                        rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0);
+                        "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
+                        rtsp_st->sdp_port, rtsp_st->sdp_ttl,
+                        rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
+                        rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
+
+            append_source_addrs(url, sizeof(url), "sources",
+                                rtsp_st->nb_include_source_addrs,
+                                rtsp_st->include_source_addrs);
+            append_source_addrs(url, sizeof(url), "block",
+                                rtsp_st->nb_exclude_source_addrs,
+                                rtsp_st->exclude_source_addrs);
             if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
                            &s->interrupt_callback, NULL) < 0) {
                 err = AVERROR_INVALIDDATA;
@@ -2106,7 +2238,7 @@ static int rtp_probe(AVProbeData *p)
 
 static int rtp_read_header(AVFormatContext *s)
 {
-    uint8_t recvbuf[1500];
+    uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
     char host[500], sdp[500];
     int ret, port;
     URLContext* in = NULL;
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 3260f6c..7a910b0 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -401,6 +401,12 @@ typedef struct RTSPState {
                                           source address and port. */
 #define RTSP_FLAG_LISTEN      0x2    /**< Wait for incoming connections. */
 #define RTSP_FLAG_CUSTOM_IO   0x4    /**< Do all IO via the AVIOContext. */
+#define RTSP_FLAG_RTCP_TO_SOURCE 0x8 /**< Send RTCP packets to the source
+                                          address of received packets. */
+
+typedef struct RTSPSource {
+    char addr[128]; /**< Source-specific multicast include source IP address (from SDP content) */
+} RTSPSource;
 
 /**
  * Describe a single stream, as identified by a single m= line block in the
@@ -425,6 +431,10 @@ typedef struct RTSPStream {
     //@{
     int sdp_port;             /**< port (from SDP content) */
     struct sockaddr_storage sdp_ip; /**< IP address (from SDP content) */
+    int nb_include_source_addrs; /**< Number of source-specific multicast include source IP addresses (from SDP content) */
+    struct RTSPSource **include_source_addrs; /**< Source-specific multicast include source IP addresses (from SDP content) */
+    int nb_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP addresses (from SDP content) */
+    struct RTSPSource **exclude_source_addrs; /**< Source-specific multicast exclude source IP addresses (from SDP content) */
     int sdp_ttl;              /**< IP Time-To-Live (from SDP content) */
     int sdp_payload_type;     /**< payload type */
     //@}
@@ -437,6 +447,12 @@ typedef struct RTSPStream {
     /** private data associated with the dynamic protocol */
     PayloadContext *dynamic_protocol_context;
     //@}
+
+    /** Enable sending RTCP feedback messages according to RFC 4585 */
+    int feedback;
+
+    char crypto_suite[40];
+    char crypto_params[100];
 } RTSPStream;
 
 void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
@@ -572,6 +588,11 @@ int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                             uint8_t *buf, int buf_size);
 
 /**
+ * Send buffered packets over TCP.
+ */
+int ff_rtsp_tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st);
+
+/**
  * Receive one packet from the RTSPStreams set up in the AVFormatContext
  * (which should contain a RTSPState struct as priv_data).
  */
@@ -589,7 +610,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
  * Undo the effect of ff_rtsp_make_setup_request, close the
  * transport_priv and rtp_handle fields.
  */
-void ff_rtsp_undo_setup(AVFormatContext *s);
+void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets);
 
 /**
  * Open RTSP transport context.
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 7e7fb2d..583070a 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -29,6 +29,7 @@
 #include "internal.h"
 #include "network.h"
 #include "os_support.h"
+#include "rtpproto.h"
 #include "rtsp.h"
 #include "rdt.h"
 #include "url.h"
@@ -768,7 +769,7 @@ static int resetup_tcp(AVFormatContext *s)
 
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
                  s->filename);
-    ff_rtsp_undo_setup(s);
+    ff_rtsp_undo_setup(s, 0);
     return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
                                       rt->real_challenge);
 }
@@ -876,7 +877,7 @@ retry:
                  rt->get_parameter_supported)) {
                 ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
             } else {
-                ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);
+                ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);
             }
             /* The stale flag should be reset when creating the auth response in
              * ff_rtsp_send_cmd_async, but reset it here just in case we never
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index 9b3c7c9..8a334ec 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -136,7 +136,7 @@ static int rtsp_write_header(AVFormatContext *s)
     return 0;
 }
 
-static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
+int ff_rtsp_tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
 {
     RTSPState *rt = s->priv_data;
     AVFormatContext *rtpctx = rtsp_st->transport_priv;
@@ -145,6 +145,7 @@ static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
     uint8_t *interleave_header, *interleaved_packet;
 
     size = avio_close_dyn_buf(rtpctx->pb, &buf);
+    rtpctx->pb = NULL;
     ptr = buf;
     while (size > 4) {
         uint32_t packet_len = AV_RB32(ptr);
@@ -171,8 +172,7 @@ static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
         size -= packet_len;
     }
     av_free(buf);
-    ffio_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE);
-    return 0;
+    return ffio_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE);
 }
 
 static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
@@ -217,7 +217,7 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
      * packets, so we need to send them out on the TCP connection separately.
      */
     if (!ret && rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP)
-        ret = tcp_write_packet(s, rtsp_st);
+        ret = ff_rtsp_tcp_write_packet(s, rtsp_st);
     return ret;
 }
 
@@ -225,6 +225,11 @@ static int rtsp_write_close(AVFormatContext *s)
 {
     RTSPState *rt = s->priv_data;
 
+    // If we want to send RTCP_BYE packets, these are sent by av_write_trailer.
+    // Thus call this on all streams before doing the teardown. This is
+    // done within ff_rtsp_undo_setup.
+    ff_rtsp_undo_setup(s, 1);
+
     ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
 
     ff_rtsp_close_streams(s);
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index c1cdc8f..0280cea 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -27,6 +27,7 @@
 #include "internal.h"
 #include "avio_internal.h"
 #include "url.h"
+#include "rtpdec.h"
 #if HAVE_POLL_H
 #include <poll.h>
 #endif
@@ -63,7 +64,7 @@ static int sap_read_header(AVFormatContext *s)
 {
     struct SAPState *sap = s->priv_data;
     char host[1024], path[1024], url[1024];
-    uint8_t recvbuf[1500];
+    uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
     int port;
     int ret, i;
     AVInputFormat* infmt;
@@ -186,7 +187,7 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt)
     int fd = ffurl_get_file_handle(sap->ann_fd);
     int n, ret;
     struct pollfd p = {fd, POLLIN, 0};
-    uint8_t recvbuf[1500];
+    uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
 
     if (sap->eof)
         return AVERROR_EOF;
diff --git a/libavformat/sctp.c b/libavformat/sctp.c
index b8ab63e..66b31cc 100644
--- a/libavformat/sctp.c
+++ b/libavformat/sctp.c
@@ -56,10 +56,10 @@
 
 /*
  * The sctp_recvmsg and sctp_sendmsg functions are part of the user
- * library that offers support
- * for the SCTP kernel Implementation. The main purpose of this
- * code is to provide the SCTP Socket API mappings for user
- * application to interface with the SCTP in kernel.
+ * library that offers support for the SCTP kernel Implementation.
+ * To avoid build-time clashes the functions sport an ff_-prefix here.
+ * The main purpose of this code is to provide the SCTP Socket API
+ * mappings for user applications to interface with SCTP in the kernel.
  *
  * This implementation is based on the Socket API Extensions for SCTP
  * defined in <draft-ietf-tsvwg-sctpsocket-10.txt>
@@ -198,7 +198,7 @@ static int sctp_open(URLContext *h, const char *uri, int flags)
 
     cur_ai = ai;
 
-    fd = socket(cur_ai->ai_family, SOCK_STREAM, IPPROTO_SCTP);
+    fd = ff_socket(cur_ai->ai_family, SOCK_STREAM, IPPROTO_SCTP);
     if (fd < 0)
         goto fail;
 
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index 57044d4..ec7e2f4 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -128,7 +128,7 @@ static int sdp_get_address(char *dest_addr, int size, int *ttl, const char *url)
 
     *ttl = 0;
 
-    if (strcmp(proto, "rtp")) {
+    if (strcmp(proto, "rtp") && strcmp(proto, "srtp")) {
         /* The url isn't for the actual rtp sessions,
          * don't parse out anything else than the destination.
          */
@@ -513,13 +513,6 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
             break;
         case AV_CODEC_ID_THEORA: {
             const char *pix_fmt;
-            if (c->extradata_size)
-                config = xiph_extradata2config(c);
-            else
-                av_log(c, AV_LOG_ERROR, "Theora configuation info missing\n");
-            if (!config)
-                return NULL;
-
             switch (c->pix_fmt) {
             case AV_PIX_FMT_YUV420P:
                 pix_fmt = "YCbCr-4:2:0";
@@ -535,6 +528,13 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
                 return NULL;
             }
 
+            if (c->extradata_size)
+                config = xiph_extradata2config(c);
+            else
+                av_log(c, AV_LOG_ERROR, "Theora configuation info missing\n");
+            if (!config)
+                return NULL;
+
             av_strlcatf(buff, size, "a=rtpmap:%d theora/90000\r\n"
                                     "a=fmtp:%d delivery-method=inline; "
                                     "width=%d; height=%d; sampling=%s; "
@@ -667,6 +667,19 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
                 av_strlcatf(buf, size,
                                    "a=control:streamid=%d\r\n", i + j);
             }
+            if (ac[i]->pb && ac[i]->pb->av_class) {
+                uint8_t *crypto_suite = NULL, *crypto_params = NULL;
+                av_opt_get(ac[i]->pb, "srtp_out_suite",  AV_OPT_SEARCH_CHILDREN,
+                           &crypto_suite);
+                av_opt_get(ac[i]->pb, "srtp_out_params", AV_OPT_SEARCH_CHILDREN,
+                           &crypto_params);
+                if (crypto_suite && crypto_suite[0])
+                    av_strlcatf(buf, size,
+                                "a=crypto:1 %s inline:%s\r\n",
+                                crypto_suite, crypto_params);
+                av_free(crypto_suite);
+                av_free(crypto_params);
+            }
         }
     }
 
diff --git a/libavformat/seek.c b/libavformat/seek.c
index 524cd87..9be8db9 100644
--- a/libavformat/seek.c
+++ b/libavformat/seek.c
@@ -20,6 +20,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "seek.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/mem.h"
@@ -428,13 +430,11 @@ AVParserState *ff_store_parser_state(AVFormatContext *s)
         ss->parser        = st->parser;
         ss->last_IP_pts   = st->last_IP_pts;
         ss->cur_dts       = st->cur_dts;
-        ss->reference_dts = st->reference_dts;
         ss->probe_packets = st->probe_packets;
 
         st->parser        = NULL;
         st->last_IP_pts   = AV_NOPTS_VALUE;
         st->cur_dts       = AV_NOPTS_VALUE;
-        st->reference_dts = AV_NOPTS_VALUE;
         st->probe_packets = MAX_PROBE_PACKETS;
     }
 
@@ -467,7 +467,6 @@ void ff_restore_parser_state(AVFormatContext *s, AVParserState *state)
         st->parser        = ss->parser;
         st->last_IP_pts   = ss->last_IP_pts;
         st->cur_dts       = ss->cur_dts;
-        st->reference_dts = ss->reference_dts;
         st->probe_packets = ss->probe_packets;
     }
 
diff --git a/libavformat/seek.h b/libavformat/seek.h
index e79d7bd..44cd369 100644
--- a/libavformat/seek.h
+++ b/libavformat/seek.h
@@ -33,7 +33,6 @@ typedef struct AVParserStreamState {
     AVCodecParserContext   *parser;
     int64_t                 last_IP_pts;
     int64_t                 cur_dts;
-    int64_t                 reference_dts;
     int                     probe_packets;
 } AVParserStreamState;
 
diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c
index a8534be..8316388 100644
--- a/libavformat/sierravmd.c
+++ b/libavformat/sierravmd.c
@@ -76,7 +76,7 @@ static int vmd_probe(AVProbeData *p)
         return 0;
 
     /* only return half certainty since this check is a bit sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int vmd_read_header(AVFormatContext *s)
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index a6a6933..5af5e50 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -275,7 +275,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
                 } else if(t & 0x40){ /* copy with offset */
                     off = avio_r8(s->pb);
                     j = (t & 0x3F) + 1;
-                    if (off + j > 0xff) {
+                    if (off + j > 0x100) {
                         av_log(s, AV_LOG_ERROR,
                                "Invalid palette update, offset=%d length=%d extends beyond palette size\n",
                                off, j);
@@ -305,7 +305,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
         for(i = 0; i < 7; i++) {
             if(flags & 1) {
                 uint32_t size;
-                uint8_t *tmpbuf;
+                int err;
 
                 size = avio_rl32(s->pb) - 4;
                 if (!size || size > frame_size) {
@@ -315,10 +315,10 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
                 frame_size -= size;
                 frame_size -= 4;
                 smk->curstream++;
-                tmpbuf = av_realloc(smk->bufs[smk->curstream], size);
-                if (!tmpbuf)
-                    return AVERROR(ENOMEM);
-                smk->bufs[smk->curstream] = tmpbuf;
+                if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) {
+                    smk->buf_sizes[smk->curstream] = 0;
+                    return err;
+                }
                 smk->buf_sizes[smk->curstream] = size;
                 ret = avio_read(s->pb, smk->bufs[smk->curstream], size);
                 if(ret != size)
@@ -339,6 +339,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
         if(ret != frame_size)
             return AVERROR(EIO);
         pkt->stream_index = smk->videoindex;
+        pkt->pts          = smk->cur_frame;
         pkt->size = ret + 769;
         smk->cur_frame++;
         smk->nextpos = avio_tell(s->pb);
diff --git a/libavformat/smjpegdec.c b/libavformat/smjpegdec.c
index 39bb1b4..623df71 100644
--- a/libavformat/smjpegdec.c
+++ b/libavformat/smjpegdec.c
@@ -52,7 +52,7 @@ static int smjpeg_read_header(AVFormatContext *s)
     avio_skip(pb, 8); // magic
     version = avio_rb32(pb);
     if (version)
-        av_log_ask_for_sample(s, "unknown version %d\n", version);
+        avpriv_request_sample(s, "Unknown version %d", version);
 
     duration = avio_rb32(pb); // in msec
 
@@ -77,7 +77,7 @@ static int smjpeg_read_header(AVFormatContext *s)
             break;
         case SMJPEG_SND:
             if (ast) {
-                av_log_ask_for_sample(s, "multiple audio streams not supported\n");
+                avpriv_request_sample(s, "Multiple audio streams");
                 return AVERROR_PATCHWELCOME;
             }
             hlength = avio_rb32(pb);
@@ -100,7 +100,7 @@ static int smjpeg_read_header(AVFormatContext *s)
             break;
         case SMJPEG_VID:
             if (vst) {
-                av_log_ask_for_sample(s, "multiple video streams not supported\n");
+                avpriv_request_sample(s, "Multiple video streams");
                 return AVERROR_INVALIDDATA;
             }
             hlength = avio_rb32(pb);
diff --git a/libavformat/smjpegenc.c b/libavformat/smjpegenc.c
index 5c64e84..551af89 100644
--- a/libavformat/smjpegenc.c
+++ b/libavformat/smjpegenc.c
@@ -109,7 +109,6 @@ static int smjpeg_write_packet(AVFormatContext *s, AVPacket *pkt)
     avio_wb32(pb, pkt->pts);
     avio_wb32(pb, pkt->size);
     avio_write(pb, pkt->data, pkt->size);
-    avio_flush(pb);
 
     smc->duration = FFMAX(smc->duration, pkt->pts + pkt->duration);
     return 0;
diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c
index d26af05..2fe01b1 100644
--- a/libavformat/smoothstreamingenc.c
+++ b/libavformat/smoothstreamingenc.c
@@ -210,14 +210,15 @@ static int write_manifest(AVFormatContext *s, int final)
 {
     SmoothStreamingContext *c = s->priv_data;
     AVIOContext *out;
-    char filename[1024];
+    char filename[1024], temp_filename[1024];
     int ret, i, video_chunks = 0, audio_chunks = 0, video_streams = 0, audio_streams = 0;
     int64_t duration = 0;
 
     snprintf(filename, sizeof(filename), "%s/Manifest", s->filename);
-    ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
+    snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->filename);
+    ret = avio_open2(&out, temp_filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL);
     if (ret < 0) {
-        av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", filename);
+        av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
         return ret;
     }
     avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
@@ -278,6 +279,7 @@ static int write_manifest(AVFormatContext *s, int final)
     avio_printf(out, "</SmoothStreamingMedia>\n");
     avio_flush(out);
     avio_close(out);
+    rename(temp_filename, filename);
     return 0;
 }
 
@@ -443,12 +445,16 @@ fail:
 
 static int add_fragment(OutputStream *os, const char *file, const char *infofile, int64_t start_time, int64_t duration, int64_t start_pos, int64_t size)
 {
+    int err;
     Fragment *frag;
     if (os->nb_fragments >= os->fragments_size) {
         os->fragments_size = (os->fragments_size + 1) * 2;
-        os->fragments = av_realloc(os->fragments, sizeof(*os->fragments)*os->fragments_size);
-        if (!os->fragments)
-            return AVERROR(ENOMEM);
+        if ((err = av_reallocp(&os->fragments, sizeof(*os->fragments) *
+                               os->fragments_size)) < 0) {
+            os->fragments_size = 0;
+            os->nb_fragments = 0;
+            return err;
+        }
     }
     frag = av_mallocz(sizeof(*frag));
     if (!frag)
diff --git a/libavformat/spdif.h b/libavformat/spdif.h
index b2a6b63..f5b15eb 100644
--- a/libavformat/spdif.h
+++ b/libavformat/spdif.h
@@ -40,9 +40,9 @@ enum IEC61937DataType {
     IEC61937_DTS1               = 0x0B,          ///< DTS type I   (512 samples)
     IEC61937_DTS2               = 0x0C,          ///< DTS type II  (1024 samples)
     IEC61937_DTS3               = 0x0D,          ///< DTS type III (2048 samples)
-    IEC61937_ATRAC              = 0x0E,          ///< Atrac data
-    IEC61937_ATRAC3             = 0x0F,          ///< Atrac 3 data
-    IEC61937_ATRACX             = 0x10,          ///< Atrac 3 plus data
+    IEC61937_ATRAC              = 0x0E,          ///< ATRAC data
+    IEC61937_ATRAC3             = 0x0F,          ///< ATRAC3 data
+    IEC61937_ATRACX             = 0x10,          ///< ATRAC3+ data
     IEC61937_DTSHD              = 0x11,          ///< DTS HD data
     IEC61937_WMAPRO             = 0x12,          ///< WMA 9 Professional data
     IEC61937_MPEG2_AAC_LSF_2048 = 0x13,          ///< MPEG-2 AAC ADTS half-rate low sampling frequency
diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c
index 6d37c94..2fb9477 100644
--- a/libavformat/spdifdec.c
+++ b/libavformat/spdifdec.c
@@ -91,8 +91,8 @@ static int spdif_get_offset_and_codec(AVFormatContext *s,
         break;
     default:
         if (s) { /* be silent during a probe */
-            av_log(s, AV_LOG_WARNING, "Data type 0x%04x", data_type);
-            av_log_missing_feature(s, " in IEC 61937", 1);
+            avpriv_request_sample(s, "Data type 0x%04x in IEC 61937",
+                                  data_type);
         }
         return AVERROR_PATCHWELCOME;
     }
@@ -149,10 +149,10 @@ static int spdif_probe(AVProbeData *p)
 
     if (sync_codes >= 6)
         /* good amount of sync codes but with unexpected offsets */
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
 
     /* some sync codes were found */
-    return AVPROBE_SCORE_MAX / 8;
+    return AVPROBE_SCORE_EXTENSION / 4;
 }
 
 static int spdif_read_header(AVFormatContext *s)
@@ -179,7 +179,7 @@ static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
     pkt_size_bits = avio_rl16(pb);
 
     if (pkt_size_bits % 16)
-        av_log_ask_for_sample(s, "Packet does not end to a 16-bit boundary.");
+        avpriv_request_sample(s, "Packet not ending at a 16-bit boundary");
 
     ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3);
     if (ret)
@@ -213,7 +213,7 @@ static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
         st->codec->codec_id = codec_id;
     } else if (codec_id != s->streams[0]->codec->codec_id) {
-        av_log_missing_feature(s, "Codec change in IEC 61937", 0);
+        avpriv_report_missing_feature(s, "Codec change in IEC 61937");
         return AVERROR_PATCHWELCOME;
     }
 
diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
index cf421a7..c350f72 100644
--- a/libavformat/spdifenc.c
+++ b/libavformat/spdifenc.c
@@ -307,7 +307,7 @@ static int spdif_header_dts(AVFormatContext *s, AVPacket *pkt)
          * discs and dts-in-wav. */
         ctx->use_preamble = 0;
     } else if (ctx->out_bytes > ctx->pkt_offset - BURST_HEADER_SIZE) {
-        av_log_ask_for_sample(s, "Unrecognized large DTS frame.");
+        avpriv_request_sample(s, "Unrecognized large DTS frame");
         /* This will fail with a "bitrate too high" in the caller */
     }
 
@@ -412,8 +412,8 @@ static int spdif_header_truehd(AVFormatContext *s, AVPacket *pkt)
     if (pkt->size > TRUEHD_FRAME_OFFSET - mat_code_length) {
         /* if such frames exist, we'd need some more complex logic to
          * distribute the TrueHD frames in the MAT frame */
-        av_log(s, AV_LOG_ERROR, "TrueHD frame too big, %d bytes\n", pkt->size);
-        av_log_ask_for_sample(s, NULL);
+        avpriv_request_sample(s, "Too large TrueHD frame of %d bytes",
+                              pkt->size);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -538,7 +538,6 @@ static int spdif_write_packet(struct AVFormatContext *s, AVPacket *pkt)
     av_log(s, AV_LOG_DEBUG, "type=%x len=%i pkt_offset=%i\n",
            ctx->data_type, ctx->out_bytes, ctx->pkt_offset);
 
-    avio_flush(s->pb);
     return 0;
 }
 
diff --git a/libavformat/srtp.c b/libavformat/srtp.c
new file mode 100644
index 0000000..6659bfc
--- /dev/null
+++ b/libavformat/srtp.c
@@ -0,0 +1,472 @@
+/*
+ * SRTP encryption/decryption
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * 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/base64.h"
+#include "libavutil/aes.h"
+#include "libavutil/hmac.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "rtp.h"
+#include "rtpdec.h"
+#include "srtp.h"
+
+void ff_srtp_free(struct SRTPContext *s)
+{
+    if (!s)
+        return;
+    av_freep(&s->aes);
+    if (s->hmac)
+        av_hmac_free(s->hmac);
+    s->hmac = NULL;
+}
+
+static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf,
+                            int outlen)
+{
+    int i, j, outpos;
+    for (i = 0, outpos = 0; outpos < outlen; i++) {
+        uint8_t keystream[16];
+        AV_WB16(&iv[14], i);
+        av_aes_crypt(aes, keystream, iv, 1, NULL, 0);
+        for (j = 0; j < 16 && outpos < outlen; j++, outpos++)
+            outbuf[outpos] ^= keystream[j];
+    }
+}
+
+static void derive_key(struct AVAES *aes, const uint8_t *salt, int label,
+                       uint8_t *out, int outlen)
+{
+    uint8_t input[16] = { 0 };
+    memcpy(input, salt, 14);
+    // Key derivation rate assumed to be zero
+    input[14 - 7] ^= label;
+    memset(out, 0, outlen);
+    encrypt_counter(aes, input, out, outlen);
+}
+
+int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
+                       const char *params)
+{
+    uint8_t buf[30];
+
+    ff_srtp_free(s);
+
+    // RFC 4568
+    if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80") ||
+        !strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_80")) {
+        s->rtp_hmac_size = s->rtcp_hmac_size = 10;
+    } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
+        s->rtp_hmac_size = s->rtcp_hmac_size = 4;
+    } else if (!strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_32")) {
+        // RFC 5764 section 4.1.2
+        s->rtp_hmac_size  = 4;
+        s->rtcp_hmac_size = 10;
+    } else {
+        av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
+                                     suite);
+        return AVERROR(EINVAL);
+    }
+    if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) {
+        av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n");
+        return AVERROR(EINVAL);
+    }
+    // MKI and lifetime not handled yet
+    s->aes  = av_aes_alloc();
+    s->hmac = av_hmac_alloc(AV_HMAC_SHA1);
+    if (!s->aes || !s->hmac)
+        return AVERROR(ENOMEM);
+    memcpy(s->master_key, buf, 16);
+    memcpy(s->master_salt, buf + 16, 14);
+
+    // RFC 3711
+    av_aes_init(s->aes, s->master_key, 128, 0);
+
+    derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key));
+    derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt));
+    derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth));
+
+    derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key));
+    derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt));
+    derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth));
+    return 0;
+}
+
+static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index,
+                      uint32_t ssrc)
+{
+    uint8_t indexbuf[8];
+    int i;
+    memset(iv, 0, 16);
+    AV_WB32(&iv[4], ssrc);
+    AV_WB64(indexbuf, index);
+    for (i = 0; i < 8; i++) // index << 16
+        iv[6 + i] ^= indexbuf[i];
+    for (i = 0; i < 14; i++)
+        iv[i] ^= salt[i];
+}
+
+int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
+{
+    uint8_t iv[16] = { 0 }, hmac[20];
+    int len = *lenptr;
+    int av_uninit(seq_largest);
+    uint32_t ssrc, av_uninit(roc);
+    uint64_t index;
+    int rtcp, hmac_size;
+
+    // TODO: Missing replay protection
+
+    if (len < 2)
+        return AVERROR_INVALIDDATA;
+
+    rtcp = RTP_PT_IS_RTCP(buf[1]);
+    hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
+
+    if (len < hmac_size)
+        return AVERROR_INVALIDDATA;
+
+    // Authentication HMAC
+    av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
+    // If MKI is used, this should exclude the MKI as well
+    av_hmac_update(s->hmac, buf, len - hmac_size);
+
+    if (!rtcp) {
+        int seq = AV_RB16(buf + 2);
+        uint32_t v;
+        uint8_t rocbuf[4];
+
+        // RFC 3711 section 3.3.1, appendix A
+        seq_largest = s->seq_initialized ? s->seq_largest : seq;
+        v = roc = s->roc;
+        if (seq_largest < 32768) {
+            if (seq - seq_largest > 32768)
+                v = roc - 1;
+        } else {
+            if (seq_largest - 32768 > seq)
+                v = roc + 1;
+        }
+        if (v == roc) {
+            seq_largest = FFMAX(seq_largest, seq);
+        } else if (v == roc + 1) {
+            seq_largest = seq;
+            roc = v;
+        }
+        index = seq + (((uint64_t)v) << 16);
+
+        AV_WB32(rocbuf, roc);
+        av_hmac_update(s->hmac, rocbuf, 4);
+    }
+
+    av_hmac_final(s->hmac, hmac, sizeof(hmac));
+    if (memcmp(hmac, buf + len - hmac_size, hmac_size)) {
+        av_log(NULL, AV_LOG_WARNING, "HMAC mismatch\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    len -= hmac_size;
+    *lenptr = len;
+
+    if (len < 12)
+        return AVERROR_INVALIDDATA;
+
+    if (rtcp) {
+        uint32_t srtcp_index = AV_RB32(buf + len - 4);
+        len -= 4;
+        *lenptr = len;
+
+        ssrc = AV_RB32(buf + 4);
+        index = srtcp_index & 0x7fffffff;
+
+        buf += 8;
+        len -= 8;
+        if (!(srtcp_index & 0x80000000))
+            return 0;
+    } else {
+        int ext, csrc;
+        s->seq_initialized = 1;
+        s->seq_largest     = seq_largest;
+        s->roc             = roc;
+
+        csrc = buf[0] & 0x0f;
+        ext  = buf[0] & 0x10;
+        ssrc = AV_RB32(buf + 8);
+
+        buf += 12;
+        len -= 12;
+
+        buf += 4 * csrc;
+        len -= 4 * csrc;
+        if (len < 0)
+            return AVERROR_INVALIDDATA;
+
+        if (ext) {
+            if (len < 4)
+                return AVERROR_INVALIDDATA;
+            ext = (AV_RB16(buf + 2) + 1) * 4;
+            if (len < ext)
+                return AVERROR_INVALIDDATA;
+            len -= ext;
+            buf += ext;
+        }
+    }
+
+    create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
+    av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
+    encrypt_counter(s->aes, iv, buf, len);
+
+    return 0;
+}
+
+int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
+                    uint8_t *out, int outlen)
+{
+    uint8_t iv[16] = { 0 }, hmac[20];
+    uint64_t index;
+    uint32_t ssrc;
+    int rtcp, hmac_size, padding;
+    uint8_t *buf;
+
+    if (len < 8)
+        return AVERROR_INVALIDDATA;
+
+    rtcp = RTP_PT_IS_RTCP(in[1]);
+    hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
+    padding = hmac_size;
+    if (rtcp)
+        padding += 4; // For the RTCP index
+
+    if (len + padding > outlen)
+        return 0;
+
+    memcpy(out, in, len);
+    buf = out;
+
+    if (rtcp) {
+        ssrc = AV_RB32(buf + 4);
+        index = s->rtcp_index++;
+
+        buf += 8;
+        len -= 8;
+    } else {
+        int ext, csrc;
+        int seq = AV_RB16(buf + 2);
+
+        if (len < 12)
+            return AVERROR_INVALIDDATA;
+
+        ssrc = AV_RB32(buf + 8);
+
+        if (seq < s->seq_largest)
+            s->roc++;
+        s->seq_largest = seq;
+        index = seq + (((uint64_t)s->roc) << 16);
+
+        csrc = buf[0] & 0x0f;
+        ext = buf[0] & 0x10;
+
+        buf += 12;
+        len -= 12;
+
+        buf += 4 * csrc;
+        len -= 4 * csrc;
+        if (len < 0)
+            return AVERROR_INVALIDDATA;
+
+        if (ext) {
+            if (len < 4)
+                return AVERROR_INVALIDDATA;
+            ext = (AV_RB16(buf + 2) + 1) * 4;
+            if (len < ext)
+                return AVERROR_INVALIDDATA;
+            len -= ext;
+            buf += ext;
+        }
+    }
+
+    create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
+    av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
+    encrypt_counter(s->aes, iv, buf, len);
+
+    if (rtcp) {
+        AV_WB32(buf + len, 0x80000000 | index);
+        len += 4;
+    }
+
+    av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
+    av_hmac_update(s->hmac, out, buf + len - out);
+    if (!rtcp) {
+        uint8_t rocbuf[4];
+        AV_WB32(rocbuf, s->roc);
+        av_hmac_update(s->hmac, rocbuf, 4);
+    }
+    av_hmac_final(s->hmac, hmac, sizeof(hmac));
+
+    memcpy(buf + len, hmac, hmac_size);
+    len += hmac_size;
+    return buf + len - out;
+}
+
+#ifdef TEST
+#include <stdio.h>
+
+static const char *aes128_80_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+
+static const uint8_t rtp_aes128_80[] = {
+    // RTP header
+    0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x62, 0x69, 0x76, 0xca, 0xc5,
+    // HMAC
+    0xa1, 0xac, 0x1b, 0xb4, 0xa0, 0x1c, 0xd5, 0x49, 0x28, 0x99,
+};
+
+static const uint8_t rtcp_aes128_80[] = {
+    // RTCP header
+    0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x8a, 0xac, 0xdc, 0xa5, 0x4c, 0xf6, 0x78, 0xa6, 0x62, 0x8f, 0x24, 0xda,
+    0x6c, 0x09, 0x3f, 0xa9, 0x28, 0x7a, 0xb5, 0x7f, 0x1f, 0x0f, 0xc9, 0x35,
+    // RTCP index
+    0x80, 0x00, 0x00, 0x03,
+    // HMAC
+    0xe9, 0x3b, 0xc0, 0x5c, 0x0c, 0x06, 0x9f, 0xab, 0xc0, 0xde,
+};
+
+static const char *aes128_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+
+static const uint8_t rtp_aes128_32[] = {
+    // RTP header
+    0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x62, 0x69, 0x76, 0xca, 0xc5,
+    // HMAC
+    0xa1, 0xac, 0x1b, 0xb4,
+};
+
+static const uint8_t rtcp_aes128_32[] = {
+    // RTCP header
+    0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x35, 0xe9, 0xb5, 0xff, 0x0d, 0xd1, 0xde, 0x70, 0x74, 0x10, 0xaa, 0x1b,
+    0xb2, 0x8d, 0xf0, 0x20, 0x02, 0x99, 0x6b, 0x1b, 0x0b, 0xd0, 0x47, 0x34,
+    // RTCP index
+    0x80, 0x00, 0x00, 0x04,
+    // HMAC
+    0x5b, 0xd2, 0xa9, 0x9d,
+};
+
+static const char *aes128_80_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
+
+static const uint8_t rtp_aes128_80_32[] = {
+    // RTP header
+    0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0x62, 0x69, 0x76, 0xca, 0xc5,
+    // HMAC
+    0xa1, 0xac, 0x1b, 0xb4,
+};
+
+static const uint8_t rtcp_aes128_80_32[] = {
+    // RTCP header
+    0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
+    // encrypted payload
+    0xd6, 0xae, 0xc1, 0x58, 0x63, 0x70, 0xc9, 0x88, 0x66, 0x26, 0x1c, 0x53,
+    0xff, 0x5d, 0x5d, 0x2b, 0x0f, 0x8c, 0x72, 0x3e, 0xc9, 0x1d, 0x43, 0xf9,
+    // RTCP index
+    0x80, 0x00, 0x00, 0x05,
+    // HMAC
+    0x09, 0x16, 0xb4, 0x27, 0x9a, 0xe9, 0x92, 0x26, 0x4e, 0x10,
+};
+
+static void print_data(const uint8_t *buf, int len)
+{
+    int i;
+    for (i = 0; i < len; i++)
+        printf("%02x", buf[i]);
+    printf("\n");
+}
+
+static int test_decrypt(struct SRTPContext *srtp, const uint8_t *in, int len,
+                        uint8_t *out)
+{
+    memcpy(out, in, len);
+    if (!ff_srtp_decrypt(srtp, out, &len)) {
+        print_data(out, len);
+        return len;
+    } else
+        return -1;
+}
+
+static void test_encrypt(const uint8_t *data, int in_len, const char *suite,
+                         const char *key)
+{
+    struct SRTPContext enc = { 0 }, dec = { 0 };
+    int len;
+    char buf[RTP_MAX_PACKET_LENGTH];
+    ff_srtp_set_crypto(&enc, suite, key);
+    ff_srtp_set_crypto(&dec, suite, key);
+    len = ff_srtp_encrypt(&enc, data, in_len, buf, sizeof(buf));
+    if (!ff_srtp_decrypt(&dec, buf, &len)) {
+        if (len == in_len && !memcmp(buf, data, len))
+            printf("Decrypted content matches input\n");
+        else
+            printf("Decrypted content doesn't match input\n");
+    } else {
+        printf("Decryption failed\n");
+    }
+    ff_srtp_free(&enc);
+    ff_srtp_free(&dec);
+}
+
+int main(void)
+{
+    static const char *aes128_80_suite = "AES_CM_128_HMAC_SHA1_80";
+    static const char *aes128_32_suite = "AES_CM_128_HMAC_SHA1_32";
+    static const char *aes128_80_32_suite = "SRTP_AES128_CM_HMAC_SHA1_32";
+    static const char *test_key = "abcdefghijklmnopqrstuvwxyz1234567890ABCD";
+    uint8_t buf[RTP_MAX_PACKET_LENGTH];
+    struct SRTPContext srtp = { 0 };
+    int len;
+    ff_srtp_set_crypto(&srtp, aes128_80_suite, aes128_80_key);
+    len = test_decrypt(&srtp, rtp_aes128_80, sizeof(rtp_aes128_80), buf);
+    test_encrypt(buf, len, aes128_80_suite, test_key);
+    test_encrypt(buf, len, aes128_32_suite, test_key);
+    test_encrypt(buf, len, aes128_80_32_suite, test_key);
+    test_decrypt(&srtp, rtcp_aes128_80, sizeof(rtcp_aes128_80), buf);
+    test_encrypt(buf, len, aes128_80_suite, test_key);
+    test_encrypt(buf, len, aes128_32_suite, test_key);
+    test_encrypt(buf, len, aes128_80_32_suite, test_key);
+    ff_srtp_free(&srtp);
+
+    memset(&srtp, 0, sizeof(srtp)); // Clear the context
+    ff_srtp_set_crypto(&srtp, aes128_32_suite, aes128_32_key);
+    test_decrypt(&srtp, rtp_aes128_32, sizeof(rtp_aes128_32), buf);
+    test_decrypt(&srtp, rtcp_aes128_32, sizeof(rtcp_aes128_32), buf);
+    ff_srtp_free(&srtp);
+
+    memset(&srtp, 0, sizeof(srtp)); // Clear the context
+    ff_srtp_set_crypto(&srtp, aes128_80_32_suite, aes128_80_32_key);
+    test_decrypt(&srtp, rtp_aes128_80_32, sizeof(rtp_aes128_80_32), buf);
+    test_decrypt(&srtp, rtcp_aes128_80_32, sizeof(rtcp_aes128_80_32), buf);
+    ff_srtp_free(&srtp);
+    return 0;
+}
+#endif /* TEST */
diff --git a/libavformat/srtp.h b/libavformat/srtp.h
new file mode 100644
index 0000000..18ed177
--- /dev/null
+++ b/libavformat/srtp.h
@@ -0,0 +1,52 @@
+/*
+ * SRTP encryption/decryption
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * 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 AVFORMAT_SRTP_H
+#define AVFORMAT_SRTP_H
+
+#include <stdint.h>
+
+struct AVAES;
+struct AVHMAC;
+
+struct SRTPContext {
+    struct AVAES *aes;
+    struct AVHMAC *hmac;
+    int rtp_hmac_size, rtcp_hmac_size;
+    uint8_t master_key[16];
+    uint8_t master_salt[14];
+    uint8_t rtp_key[16],  rtcp_key[16];
+    uint8_t rtp_salt[14], rtcp_salt[14];
+    uint8_t rtp_auth[20], rtcp_auth[20];
+    int seq_largest, seq_initialized;
+    uint32_t roc;
+
+    uint32_t rtcp_index;
+};
+
+int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
+                       const char *params);
+void ff_srtp_free(struct SRTPContext *s);
+int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr);
+int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
+                    uint8_t *out, int outlen);
+
+#endif /* AVFORMAT_SRTP_H */
diff --git a/libavformat/srtpproto.c b/libavformat/srtpproto.c
new file mode 100644
index 0000000..f9b94d7
--- /dev/null
+++ b/libavformat/srtpproto.c
@@ -0,0 +1,145 @@
+/*
+ * SRTP network protocol
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * 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 "avformat.h"
+#include "avio_internal.h"
+#include "url.h"
+
+#include "internal.h"
+#include "rtpdec.h"
+#include "srtp.h"
+
+typedef struct SRTPProtoContext {
+    const AVClass *class;
+    URLContext *rtp_hd;
+    const char *out_suite, *out_params;
+    const char *in_suite, *in_params;
+    struct SRTPContext srtp_out, srtp_in;
+    uint8_t encryptbuf[RTP_MAX_PACKET_LENGTH];
+} SRTPProtoContext;
+
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "srtp_out_suite", "", offsetof(SRTPProtoContext, out_suite), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+    { "srtp_out_params", "", offsetof(SRTPProtoContext, out_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+    { "srtp_in_suite", "", offsetof(SRTPProtoContext, in_suite), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+    { "srtp_in_params", "", offsetof(SRTPProtoContext, in_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+    { NULL }
+};
+
+static const AVClass srtp_context_class = {
+    .class_name     = "srtp",
+    .item_name      = av_default_item_name,
+    .option         = options,
+    .version        = LIBAVUTIL_VERSION_INT,
+};
+
+static int srtp_close(URLContext *h)
+{
+    SRTPProtoContext *s = h->priv_data;
+    ff_srtp_free(&s->srtp_out);
+    ff_srtp_free(&s->srtp_in);
+    ffurl_close(s->rtp_hd);
+    s->rtp_hd = NULL;
+    return 0;
+}
+
+static int srtp_open(URLContext *h, const char *uri, int flags)
+{
+    SRTPProtoContext *s = h->priv_data;
+    char hostname[256], buf[1024], path[1024];
+    int rtp_port, ret;
+
+    if (s->out_suite && s->out_params)
+        if ((ret = ff_srtp_set_crypto(&s->srtp_out, s->out_suite, s->out_params)) < 0)
+            goto fail;
+    if (s->in_suite && s->in_params)
+        if ((ret = ff_srtp_set_crypto(&s->srtp_in, s->in_suite, s->in_params)) < 0)
+            goto fail;
+
+    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
+                 path, sizeof(path), uri);
+    ff_url_join(buf, sizeof(buf), "rtp", NULL, hostname, rtp_port, "%s", path);
+    if ((ret = ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL)) < 0)
+        goto fail;
+
+    h->max_packet_size = FFMIN(s->rtp_hd->max_packet_size,
+                               sizeof(s->encryptbuf)) - 14;
+    h->is_streamed = 1;
+    return 0;
+
+fail:
+    srtp_close(h);
+    return ret;
+}
+
+static int srtp_read(URLContext *h, uint8_t *buf, int size)
+{
+    SRTPProtoContext *s = h->priv_data;
+    int ret;
+start:
+    ret = ffurl_read(s->rtp_hd, buf, size);
+    if (ret > 0 && s->srtp_in.aes) {
+        if (ff_srtp_decrypt(&s->srtp_in, buf, &ret) < 0)
+            goto start;
+    }
+    return ret;
+}
+
+static int srtp_write(URLContext *h, const uint8_t *buf, int size)
+{
+    SRTPProtoContext *s = h->priv_data;
+    if (!s->srtp_out.aes)
+        return ffurl_write(s->rtp_hd, buf, size);
+    size = ff_srtp_encrypt(&s->srtp_out, buf, size, s->encryptbuf,
+                           sizeof(s->encryptbuf));
+    if (size < 0)
+        return size;
+    return ffurl_write(s->rtp_hd, s->encryptbuf, size);
+}
+
+static int srtp_get_file_handle(URLContext *h)
+{
+    SRTPProtoContext *s = h->priv_data;
+    return ffurl_get_file_handle(s->rtp_hd);
+}
+
+static int srtp_get_multi_file_handle(URLContext *h, int **handles,
+                                      int *numhandles)
+{
+    SRTPProtoContext *s = h->priv_data;
+    return ffurl_get_multi_file_handle(s->rtp_hd, handles, numhandles);
+}
+
+URLProtocol ff_srtp_protocol = {
+    .name                      = "srtp",
+    .url_open                  = srtp_open,
+    .url_read                  = srtp_read,
+    .url_write                 = srtp_write,
+    .url_close                 = srtp_close,
+    .url_get_file_handle       = srtp_get_file_handle,
+    .url_get_multi_file_handle = srtp_get_multi_file_handle,
+    .priv_data_size            = sizeof(SRTPProtoContext),
+    .priv_data_class           = &srtp_context_class,
+    .flags                     = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c
index 31f405d..be2e5cd 100644
--- a/libavformat/swfenc.c
+++ b/libavformat/swfenc.c
@@ -229,7 +229,7 @@ static int swf_write_header(AVFormatContext *s)
     }
 
     if (!swf->audio_enc)
-        swf->samples_per_frame = (44100. * rate_base) / rate;
+        swf->samples_per_frame = (44100.0 * rate_base) / rate;
     else
         swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate;
 
@@ -436,8 +436,6 @@ static int swf_write_video(AVFormatContext *s,
     put_swf_tag(s, TAG_SHOWFRAME);
     put_swf_end_tag(s);
 
-    avio_flush(s->pb);
-
     return 0;
 }
 
diff --git a/libavformat/takdec.c b/libavformat/takdec.c
index 13bc49b..584cbcc 100644
--- a/libavformat/takdec.c
+++ b/libavformat/takdec.c
@@ -33,7 +33,7 @@ typedef struct TAKDemuxContext {
 static int tak_probe(AVProbeData *p)
 {
     if (!memcmp(p->buf, "tBaK", 4))
-        return AVPROBE_SCORE_MAX / 2;
+        return AVPROBE_SCORE_EXTENSION;
     return 0;
 }
 
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index bdaab7f..cbd5142 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -42,7 +42,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
     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];
@@ -85,87 +84,31 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
     cur_ai = ai;
 
  restart:
-    ret = AVERROR(EIO);
-    fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
-    if (fd < 0)
+    fd = ff_socket(cur_ai->ai_family,
+                   cur_ai->ai_socktype,
+                   cur_ai->ai_protocol);
+    if (fd < 0) {
+        ret = ff_neterrno();
         goto fail;
+    }
 
     if (listen_socket) {
-        int fd1;
-        int reuse = 1;
-        struct pollfd lp = { fd, POLLIN, 0 };
-        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
-        ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
-        if (ret) {
-            ret = ff_neterrno();
+        if ((fd = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+                                 listen_timeout, h)) < 0) {
+            ret = fd;
             goto fail1;
         }
-        ret = listen(fd, 1);
-        if (ret) {
-            ret = ff_neterrno();
-            goto fail1;
-        }
-        ret = poll(&lp, 1, listen_timeout >= 0 ? listen_timeout : -1);
-        if (ret <= 0) {
-            ret = AVERROR(ETIMEDOUT);
-            goto fail1;
-        }
-        fd1 = accept(fd, NULL, NULL);
-        if (fd1 < 0) {
-            ret = ff_neterrno();
-            goto fail1;
-        }
-        closesocket(fd);
-        fd = fd1;
-        ff_socket_nonblock(fd, 1);
     } else {
- redo:
-        ff_socket_nonblock(fd, 1);
-        ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
-    }
-
-    if (ret < 0) {
-        struct pollfd p = {fd, POLLOUT, 0};
-        ret = ff_neterrno();
-        if (ret == AVERROR(EINTR)) {
-            if (ff_check_interrupt(&h->interrupt_callback)) {
-                ret = AVERROR_EXIT;
-                goto fail1;
-            }
-            goto redo;
-        }
-        if (ret != AVERROR(EINPROGRESS) &&
-            ret != AVERROR(EAGAIN))
-            goto fail;
+        if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+                                     timeout * 100, h, !!cur_ai->ai_next)) < 0) {
 
-        /* wait until we are connected or until abort */
-        while(timeout--) {
-            if (ff_check_interrupt(&h->interrupt_callback)) {
-                ret = AVERROR_EXIT;
+            if (ret == AVERROR_EXIT)
                 goto fail1;
-            }
-            ret = poll(&p, 1, 100);
-            if (ret > 0)
-                break;
-        }
-        if (ret <= 0) {
-            ret = AVERROR(ETIMEDOUT);
-            goto fail;
-        }
-        /* test error */
-        optlen = sizeof(ret);
-        if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
-            ret = AVUNERROR(ff_neterrno());
-        if (ret != 0) {
-            char errbuf[100];
-            ret = AVERROR(ret);
-            av_strerror(ret, errbuf, sizeof(errbuf));
-            av_log(h, AV_LOG_ERROR,
-                   "TCP connection to %s:%d failed: %s\n",
-                   hostname, port, errbuf);
-            goto fail;
+            else
+                goto fail;
         }
     }
+
     h->is_streamed = 1;
     s->fd = fd;
     freeaddrinfo(ai);
@@ -177,6 +120,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
         cur_ai = cur_ai->ai_next;
         if (fd >= 0)
             closesocket(fd);
+        ret = 0;
         goto restart;
     }
  fail1:
diff --git a/libavformat/tls.c b/libavformat/tls.c
index 866e55f..1baecf4 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -22,8 +22,11 @@
 #include "avformat.h"
 #include "url.h"
 #include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
 #if CONFIG_GNUTLS
 #include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
 #define TLS_read(c, buf, size)  gnutls_record_recv(c->session, buf, size)
 #define TLS_write(c, buf, size) gnutls_record_send(c->session, buf, size)
 #define TLS_shutdown(c)         gnutls_bye(c->session, GNUTLS_SHUT_RDWR)
@@ -65,14 +68,45 @@ typedef struct {
     SSL *ssl;
 #endif
     int fd;
+    char *ca_file;
+    int verify;
+    char *cert_file;
+    char *key_file;
+    int listen;
 } TLSContext;
 
+#define OFFSET(x) offsetof(TLSContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    {"ca_file",    "Certificate Authority database file", OFFSET(ca_file),   AV_OPT_TYPE_STRING, .flags = D|E },
+    {"tls_verify", "Verify the peer certificate",         OFFSET(verify),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = D|E },
+    {"cert_file",  "Certificate file",                    OFFSET(cert_file), AV_OPT_TYPE_STRING, .flags = D|E },
+    {"key_file",   "Private key file",                    OFFSET(key_file),  AV_OPT_TYPE_STRING, .flags = D|E },
+    {"listen",     "Listen for incoming connections",     OFFSET(listen),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = D|E },
+    { NULL }
+};
+
+static const AVClass tls_class = {
+    .class_name = "tls",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static int do_tls_poll(URLContext *h, int ret)
 {
     TLSContext *c = h->priv_data;
     struct pollfd p = { c->fd, 0, 0 };
 #if CONFIG_GNUTLS
-    if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED) {
+    switch (ret) {
+    case GNUTLS_E_AGAIN:
+    case GNUTLS_E_INTERRUPTED:
+        break;
+    case GNUTLS_E_WARNING_ALERT_RECEIVED:
+        av_log(h, AV_LOG_WARNING, "%s\n", gnutls_strerror(ret));
+        break;
+    default:
         av_log(h, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret));
         return AVERROR(EIO);
     }
@@ -108,7 +142,7 @@ 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], opts[50] = "";
     int numerichost = 0;
     struct addrinfo hints = { 0 }, *ai = NULL;
     const char *proxy_path;
@@ -116,12 +150,11 @@ static int tls_open(URLContext *h, const char *uri, int flags)
 
     ff_tls_init();
 
-    proxy_path = getenv("http_proxy");
-    use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
-        av_strstart(proxy_path, "http://", NULL);
+    if (c->listen)
+        snprintf(opts, sizeof(opts), "?listen=1");
 
     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);
+    ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, "%s", opts);
 
     hints.ai_flags = AI_NUMERICHOST;
     if (!getaddrinfo(host, NULL, &hints, &ai)) {
@@ -129,6 +162,10 @@ static int tls_open(URLContext *h, const char *uri, int flags)
         freeaddrinfo(ai);
     }
 
+    proxy_path = getenv("http_proxy");
+    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), host) &&
+                proxy_path != NULL && av_strstart(proxy_path, "http://", NULL);
+
     if (use_proxy) {
         char proxy_host[200], proxy_auth[200], dest[200];
         int proxy_port;
@@ -147,11 +184,30 @@ static int tls_open(URLContext *h, const char *uri, int flags)
     c->fd = ffurl_get_file_handle(c->tcp);
 
 #if CONFIG_GNUTLS
-    gnutls_init(&c->session, GNUTLS_CLIENT);
-    if (!numerichost)
+    gnutls_init(&c->session, c->listen ? GNUTLS_SERVER : GNUTLS_CLIENT);
+    if (!c->listen && !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);
+    if (c->ca_file)
+        gnutls_certificate_set_x509_trust_file(c->cred, c->ca_file, GNUTLS_X509_FMT_PEM);
+#if GNUTLS_VERSION_MAJOR >= 3
+    else
+        gnutls_certificate_set_x509_system_trust(c->cred);
+#endif
+    gnutls_certificate_set_verify_flags(c->cred, c->verify ?
+                                        GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT : 0);
+    if (c->cert_file && c->key_file) {
+        ret = gnutls_certificate_set_x509_key_file(c->cred,
+                                                   c->cert_file, c->key_file,
+                                                   GNUTLS_X509_FMT_PEM);
+        if (ret < 0) {
+            av_log(h, AV_LOG_ERROR,
+                   "Unable to set cert/key files %s and %s: %s\n",
+                   c->cert_file, c->key_file, gnutls_strerror(ret));
+            ret = AVERROR(EIO);
+            goto fail;
+        }
+    }
     gnutls_credentials_set(c->session, GNUTLS_CRD_CERTIFICATE, c->cred);
     gnutls_transport_set_ptr(c->session, (gnutls_transport_ptr_t)
                                          (intptr_t) c->fd);
@@ -163,13 +219,63 @@ static int tls_open(URLContext *h, const char *uri, int flags)
         if ((ret = do_tls_poll(h, ret)) < 0)
             goto fail;
     }
+    if (c->verify) {
+        unsigned int status, cert_list_size;
+        gnutls_x509_crt_t cert;
+        const gnutls_datum_t *cert_list;
+        if ((ret = gnutls_certificate_verify_peers2(c->session, &status)) < 0) {
+            av_log(h, AV_LOG_ERROR, "Unable to verify peer certificate: %s\n",
+                                    gnutls_strerror(ret));
+            ret = AVERROR(EIO);
+            goto fail;
+        }
+        if (status & GNUTLS_CERT_INVALID) {
+            av_log(h, AV_LOG_ERROR, "Peer certificate failed verification\n");
+            ret = AVERROR(EIO);
+            goto fail;
+        }
+        if (gnutls_certificate_type_get(c->session) != GNUTLS_CRT_X509) {
+            av_log(h, AV_LOG_ERROR, "Unsupported certificate type\n");
+            ret = AVERROR(EIO);
+            goto fail;
+        }
+        gnutls_x509_crt_init(&cert);
+        cert_list = gnutls_certificate_get_peers(c->session, &cert_list_size);
+        gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER);
+        ret = gnutls_x509_crt_check_hostname(cert, host);
+        gnutls_x509_crt_deinit(cert);
+        if (!ret) {
+            av_log(h, AV_LOG_ERROR,
+                   "The certificate's owner does not match hostname %s\n", host);
+            ret = AVERROR(EIO);
+            goto fail;
+        }
+    }
 #elif CONFIG_OPENSSL
-    c->ctx = SSL_CTX_new(TLSv1_client_method());
+    c->ctx = SSL_CTX_new(c->listen ? 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;
     }
+    if (c->ca_file)
+        SSL_CTX_load_verify_locations(c->ctx, c->ca_file, NULL);
+    if (c->cert_file && !SSL_CTX_use_certificate_chain_file(c->ctx, c->cert_file)) {
+        av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n",
+               c->cert_file, ERR_error_string(ERR_get_error(), NULL));
+        ret = AVERROR(EIO);
+        goto fail;
+    }
+    if (c->key_file && !SSL_CTX_use_PrivateKey_file(c->ctx, c->key_file, SSL_FILETYPE_PEM)) {
+        av_log(h, AV_LOG_ERROR, "Unable to load key file %s: %s\n",
+               c->key_file, ERR_error_string(ERR_get_error(), NULL));
+        ret = AVERROR(EIO);
+        goto fail;
+    }
+    // Note, this doesn't check that the peer certificate actually matches
+    // the requested hostname.
+    if (c->verify)
+        SSL_CTX_set_verify(c->ctx, SSL_VERIFY_PEER, NULL);
     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 +283,10 @@ static int tls_open(URLContext *h, const char *uri, int flags)
         goto fail;
     }
     SSL_set_fd(c->ssl, c->fd);
-    if (!numerichost)
+    if (!c->listen && !numerichost)
         SSL_set_tlsext_host_name(c->ssl, host);
     while (1) {
-        ret = SSL_connect(c->ssl);
+        ret = c->listen ? SSL_accept(c->ssl) : SSL_connect(c->ssl);
         if (ret > 0)
             break;
         if (ret == 0) {
@@ -249,4 +355,5 @@ URLProtocol ff_tls_protocol = {
     .url_close      = tls_close,
     .priv_data_size = sizeof(TLSContext),
     .flags          = URL_PROTOCOL_FLAG_NETWORK,
+    .priv_data_class = &tls_class,
 };
diff --git a/libavformat/tta.c b/libavformat/tta.c
index 9d3d295..e5e6e71 100644
--- a/libavformat/tta.c
+++ b/libavformat/tta.c
@@ -36,7 +36,7 @@ static int tta_probe(AVProbeData *p)
     const uint8_t *d = p->buf;
 
     if (d[0] == 'T' && d[1] == 'T' && d[2] == 'A' && d[3] == '1')
-        return 80;
+        return AVPROBE_SCORE_EXTENSION + 30;
     return 0;
 }
 
diff --git a/libavformat/tty.c b/libavformat/tty.c
index f85f230..0ae1510 100644
--- a/libavformat/tty.c
+++ b/libavformat/tty.c
@@ -98,6 +98,7 @@ static int read_header(AVFormatContext *avctx)
     st->codec->width  = width;
     st->codec->height = height;
     avpriv_set_pts_info(st, 60, framerate.den, framerate.num);
+    st->avg_frame_rate = framerate;
 
     /* simulate tty display speed */
     s->chars_per_frame = FFMAX(av_q2d(st->time_base)*s->chars_per_frame, 1);
diff --git a/libavformat/udp.c b/libavformat/udp.c
index 373a4c9..bfa8cf2 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -181,7 +181,7 @@ static int udp_set_multicast_sources(int sockfd, struct sockaddr *addr,
         int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
         struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
                                                        SOCK_DGRAM, AF_UNSPEC,
-                                                       AI_NUMERICHOST);
+                                                       0);
         if (!sourceaddr)
             return AVERROR(ENOENT);
 
@@ -211,7 +211,7 @@ static int udp_set_multicast_sources(int sockfd, struct sockaddr *addr,
         struct ip_mreq_source mreqs;
         struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
                                                        SOCK_DGRAM, AF_UNSPEC,
-                                                       AI_NUMERICHOST);
+                                                       0);
         if (!sourceaddr)
             return AVERROR(ENOENT);
         if (sourceaddr->ai_addr->sa_family != AF_INET) {
@@ -270,7 +270,7 @@ static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr,
     if (res0 == 0)
         goto fail;
     for (res = res0; res; res=res->ai_next) {
-        udp_fd = socket(res->ai_family, SOCK_DGRAM, 0);
+        udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0);
         if (udp_fd != -1) break;
         log_net_error(NULL, AV_LOG_ERROR, "socket");
     }
@@ -378,6 +378,27 @@ static int udp_get_file_handle(URLContext *h)
     return s->udp_fd;
 }
 
+static int parse_source_list(char *buf, char **sources, int *num_sources,
+                             int max_sources)
+{
+    char *source_start;
+
+    source_start = buf;
+    while (1) {
+        char *next = strchr(source_start, ',');
+        if (next)
+            *next = '\0';
+        sources[*num_sources] = av_strdup(source_start);
+        if (!sources[*num_sources])
+            return AVERROR(ENOMEM);
+        source_start = next + 1;
+        (*num_sources)++;
+        if (*num_sources >= max_sources || !next)
+            break;
+    }
+    return 0;
+}
+
 /* put it in UDP context */
 /* return non zero if error */
 static int udp_open(URLContext *h, const char *uri, int flags)
@@ -391,8 +412,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
     struct sockaddr_storage my_addr;
     socklen_t len;
     int reuse_specified = 0;
-    int i, include = 0, num_sources = 0;
-    char *sources[32];
+    int i, num_include_sources = 0, num_exclude_sources = 0;
+    char *include_sources[32], *exclude_sources[32];
 
     h->is_streamed = 1;
     h->max_packet_size = 1472;
@@ -430,24 +451,15 @@ static int udp_open(URLContext *h, const char *uri, int flags)
         if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
             av_strlcpy(localaddr, buf, sizeof(localaddr));
         }
-        if (av_find_info_tag(buf, sizeof(buf), "sources", p))
-            include = 1;
-        if (include || av_find_info_tag(buf, sizeof(buf), "block", p)) {
-            char *source_start;
-
-            source_start = buf;
-            while (1) {
-                char *next = strchr(source_start, ',');
-                if (next)
-                    *next = '\0';
-                sources[num_sources] = av_strdup(source_start);
-                if (!sources[num_sources])
-                    goto fail;
-                source_start = next + 1;
-                num_sources++;
-                if (num_sources >= FF_ARRAY_ELEMS(sources) || !next)
-                    break;
-            }
+        if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
+            if (parse_source_list(buf, include_sources, &num_include_sources,
+                                  FF_ARRAY_ELEMS(include_sources)))
+                goto fail;
+        }
+        if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
+            if (parse_source_list(buf, exclude_sources, &num_exclude_sources,
+                                  FF_ARRAY_ELEMS(exclude_sources)))
+                goto fail;
         }
     }
 
@@ -506,20 +518,20 @@ static int udp_open(URLContext *h, const char *uri, int flags)
         }
         if (h->flags & AVIO_FLAG_READ) {
             /* input */
-            if (num_sources == 0 || !include) {
+            if (num_include_sources && num_exclude_sources) {
+                av_log(h, AV_LOG_ERROR, "Simultaneously including and excluding multicast sources is not supported\n");
+                goto fail;
+            }
+            if (num_include_sources) {
+                if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, include_sources, num_include_sources, 1) < 0)
+                    goto fail;
+            } else {
                 if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
                     goto fail;
-
-                if (num_sources) {
-                    if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 0) < 0)
-                        goto fail;
-                }
-            } else if (include && num_sources) {
-                if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 1) < 0)
+            }
+            if (num_exclude_sources) {
+                if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, exclude_sources, num_exclude_sources, 0) < 0)
                     goto fail;
-            } else {
-                av_log(NULL, AV_LOG_ERROR, "invalid udp settings: inclusive multicast but no sources given\n");
-                goto fail;
             }
         }
     }
@@ -548,16 +560,20 @@ static int udp_open(URLContext *h, const char *uri, int flags)
         }
     }
 
-    for (i = 0; i < num_sources; i++)
-        av_free(sources[i]);
+    for (i = 0; i < num_include_sources; i++)
+        av_freep(&include_sources[i]);
+    for (i = 0; i < num_exclude_sources; i++)
+        av_freep(&exclude_sources[i]);
 
     s->udp_fd = udp_fd;
     return 0;
  fail:
     if (udp_fd >= 0)
         closesocket(udp_fd);
-    for (i = 0; i < num_sources; i++)
-        av_free(sources[i]);
+    for (i = 0; i < num_include_sources; i++)
+        av_freep(&include_sources[i]);
+    for (i = 0; i < num_exclude_sources; i++)
+        av_freep(&exclude_sources[i]);
     return AVERROR(EIO);
 }
 
diff --git a/libavformat/unix.c b/libavformat/unix.c
new file mode 100644
index 0000000..ab57c68
--- /dev/null
+++ b/libavformat/unix.c
@@ -0,0 +1,156 @@
+/*
+ * Unix socket protocol
+ * Copyright (c) 2013 Luca Barbato
+ *
+ * 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
+ *
+ * Unix socket url_protocol
+ *
+ */
+
+#include <sys/un.h>
+
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "os_support.h"
+#include "network.h"
+#include "url.h"
+
+typedef struct UnixContext {
+    const AVClass *class;
+    struct sockaddr_un addr;
+    int timeout;
+    int listen;
+    int type;
+    int fd;
+} UnixContext;
+
+#define OFFSET(x) offsetof(UnixContext, x)
+#define ED AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption unix_options[] = {
+    { "listen",    "Open socket for listening",             OFFSET(listen),  AV_OPT_TYPE_INT,   { .i64 = 0 },                    0,       1, ED },
+    { "timeout",   "Timeout in ms",                         OFFSET(timeout), AV_OPT_TYPE_INT,   { .i64 = -1 },                  -1, INT_MAX, ED },
+    { "type",      "Socket type",                           OFFSET(type),    AV_OPT_TYPE_INT,   { .i64 = SOCK_STREAM },    INT_MIN, INT_MAX, ED, "type" },
+    { "stream",    "Stream (reliable stream-oriented)",     0,               AV_OPT_TYPE_CONST, { .i64 = SOCK_STREAM },    INT_MIN, INT_MAX, ED, "type" },
+    { "datagram",  "Datagram (unreliable packet-oriented)", 0,               AV_OPT_TYPE_CONST, { .i64 = SOCK_DGRAM },     INT_MIN, INT_MAX, ED, "type" },
+    { "seqpacket", "Seqpacket (reliable packet-oriented",   0,               AV_OPT_TYPE_CONST, { .i64 = SOCK_SEQPACKET }, INT_MIN, INT_MAX, ED, "type" },
+    { NULL }
+};
+
+static const AVClass unix_class = {
+    .class_name = "unix",
+    .item_name  = av_default_item_name,
+    .option     = unix_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static int unix_open(URLContext *h, const char *filename, int flags)
+{
+    UnixContext *s = h->priv_data;
+    int fd, ret;
+
+    av_strstart(filename, "unix:", &filename);
+    s->addr.sun_family = AF_UNIX;
+    av_strlcpy(s->addr.sun_path, filename, sizeof(s->addr.sun_path));
+
+    if ((fd = ff_socket(AF_UNIX, s->type, 0)) < 0)
+        return ff_neterrno();
+
+    if (s->listen) {
+        fd = ff_listen_bind(fd, (struct sockaddr *)&s->addr,
+                            sizeof(s->addr), s->timeout, h);
+        if (fd < 0) {
+            ret = fd;
+            goto fail;
+        }
+    } else {
+        ret = ff_listen_connect(fd, (struct sockaddr *)&s->addr,
+                                sizeof(s->addr), s->timeout, h, 0);
+        if (ret < 0)
+            goto fail;
+    }
+
+    s->fd = fd;
+
+    return 0;
+
+fail:
+    if (s->listen && AVUNERROR(ret) != EADDRINUSE)
+        unlink(s->addr.sun_path);
+    if (fd >= 0)
+        closesocket(fd);
+    return ret;
+}
+
+static int unix_read(URLContext *h, uint8_t *buf, int size)
+{
+    UnixContext *s = h->priv_data;
+    int ret;
+
+    if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+        ret = ff_network_wait_fd(s->fd, 0);
+        if (ret < 0)
+            return ret;
+    }
+    ret = recv(s->fd, buf, size, 0);
+    return ret < 0 ? ff_neterrno() : ret;
+}
+
+static int unix_write(URLContext *h, const uint8_t *buf, int size)
+{
+    UnixContext *s = h->priv_data;
+    int ret;
+
+    if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+        ret = ff_network_wait_fd(s->fd, 1);
+        if (ret < 0)
+            return ret;
+    }
+    ret = send(s->fd, buf, size, 0);
+    return ret < 0 ? ff_neterrno() : ret;
+}
+
+static int unix_close(URLContext *h)
+{
+    UnixContext *s = h->priv_data;
+    if (s->listen)
+        unlink(s->addr.sun_path);
+    closesocket(s->fd);
+    return 0;
+}
+
+static int unix_get_file_handle(URLContext *h)
+{
+    UnixContext *s = h->priv_data;
+    return s->fd;
+}
+
+URLProtocol ff_unix_protocol = {
+    .name                = "unix",
+    .url_open            = unix_open,
+    .url_read            = unix_read,
+    .url_write           = unix_write,
+    .url_close           = unix_close,
+    .url_get_file_handle = unix_get_file_handle,
+    .priv_data_size      = sizeof(UnixContext),
+    .priv_data_class     = &unix_class,
+    .flags               = URL_PROTOCOL_FLAG_NETWORK,
+};
diff --git a/libavformat/url-test.c b/libavformat/url-test.c
index 6639ccf..503b36e 100644
--- a/libavformat/url-test.c
+++ b/libavformat/url-test.c
@@ -18,7 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "internal.h"
+#include "url.h"
 
 static void test(const char *base, const char *rel)
 {
diff --git a/libavformat/url.c b/libavformat/url.c
new file mode 100644
index 0000000..eeda1f0
--- /dev/null
+++ b/libavformat/url.c
@@ -0,0 +1,147 @@
+/*
+ * URL utility functions
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of 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 "avformat.h"
+#include "config.h"
+#include "url.h"
+#if CONFIG_NETWORK
+#include "network.h"
+#endif
+#include "libavutil/avstring.h"
+
+/**
+ * @file
+ * URL utility functions.
+ */
+
+int ff_url_join(char *str, int size, const char *proto,
+                const char *authorization, const char *hostname,
+                int port, const char *fmt, ...)
+{
+#if CONFIG_NETWORK
+    struct addrinfo hints = { 0 }, *ai;
+#endif
+
+    str[0] = '\0';
+    if (proto)
+        av_strlcatf(str, size, "%s://", proto);
+    if (authorization && authorization[0])
+        av_strlcatf(str, size, "%s@", authorization);
+#if CONFIG_NETWORK && defined(AF_INET6)
+    /* Determine if hostname is a numerical IPv6 address,
+     * properly escape it within [] in that case. */
+    hints.ai_flags = AI_NUMERICHOST;
+    if (!getaddrinfo(hostname, NULL, &hints, &ai)) {
+        if (ai->ai_family == AF_INET6) {
+            av_strlcat(str, "[", size);
+            av_strlcat(str, hostname, size);
+            av_strlcat(str, "]", size);
+        } else {
+            av_strlcat(str, hostname, size);
+        }
+        freeaddrinfo(ai);
+    } else
+#endif
+        /* Not an IPv6 address, just output the plain string. */
+        av_strlcat(str, hostname, size);
+
+    if (port >= 0)
+        av_strlcatf(str, size, ":%d", port);
+    if (fmt) {
+        va_list vl;
+        int len = strlen(str);
+
+        va_start(vl, fmt);
+        vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
+        va_end(vl);
+    }
+    return strlen(str);
+}
+
+void ff_make_absolute_url(char *buf, int size, const char *base,
+                          const char *rel)
+{
+    char *sep, *path_query;
+    /* Absolute path, relative to the current server */
+    if (base && strstr(base, "://") && rel[0] == '/') {
+        if (base != buf)
+            av_strlcpy(buf, base, size);
+        sep = strstr(buf, "://");
+        if (sep) {
+            /* Take scheme from base url */
+            if (rel[1] == '/') {
+                sep[1] = '\0';
+            } else {
+                /* Take scheme and host from base url */
+                sep += 3;
+                sep = strchr(sep, '/');
+                if (sep)
+                    *sep = '\0';
+            }
+        }
+        av_strlcat(buf, rel, size);
+        return;
+    }
+    /* If rel actually is an absolute url, just copy it */
+    if (!base || strstr(rel, "://") || rel[0] == '/') {
+        av_strlcpy(buf, rel, size);
+        return;
+    }
+    if (base != buf)
+        av_strlcpy(buf, base, size);
+
+    /* Strip off any query string from base */
+    path_query = strchr(buf, '?');
+    if (path_query != NULL)
+        *path_query = '\0';
+
+    /* Is relative path just a new query part? */
+    if (rel[0] == '?') {
+        av_strlcat(buf, rel, size);
+        return;
+    }
+
+    /* Remove the file name from the base url */
+    sep = strrchr(buf, '/');
+    if (sep)
+        sep[1] = '\0';
+    else
+        buf[0] = '\0';
+    while (av_strstart(rel, "../", NULL) && sep) {
+        /* Remove the path delimiter at the end */
+        sep[0] = '\0';
+        sep = strrchr(buf, '/');
+        /* If the next directory name to pop off is "..", break here */
+        if (!strcmp(sep ? &sep[1] : buf, "..")) {
+            /* Readd the slash we just removed */
+            av_strlcat(buf, "/", size);
+            break;
+        }
+        /* Cut off the directory name */
+        if (sep)
+            sep[1] = '\0';
+        else
+            buf[0] = '\0';
+        rel += 3;
+    }
+    av_strlcat(buf, rel, size);
+}
diff --git a/libavformat/url.h b/libavformat/url.h
index 195a8ff..ff1e21b 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -224,10 +224,8 @@ int ffurl_shutdown(URLContext *h, int flags);
 
 /**
  * Register the URLProtocol protocol.
- *
- * @param size the size of the URLProtocol struct referenced
  */
-int ffurl_register_protocol(URLProtocol *protocol, int size);
+int ffurl_register_protocol(URLProtocol *protocol);
 
 /**
  * Check if the user has requested to interrup a blocking function
@@ -246,4 +244,41 @@ URLProtocol *ffurl_protocol_next(URLProtocol *prev);
 int ff_udp_set_remote_url(URLContext *h, const char *uri);
 int ff_udp_get_local_port(URLContext *h);
 
+/**
+ * Assemble a URL string from components. This is the reverse operation
+ * of av_url_split.
+ *
+ * Note, this requires networking to be initialized, so the caller must
+ * ensure ff_network_init has been called.
+ *
+ * @see av_url_split
+ *
+ * @param str the buffer to fill with the url
+ * @param size the size of the str buffer
+ * @param proto the protocol identifier, if null, the separator
+ *              after the identifier is left out, too
+ * @param authorization an optional authorization string, may be null.
+ *                      An empty string is treated the same as a null string.
+ * @param hostname the host name string
+ * @param port the port number, left out from the string if negative
+ * @param fmt a generic format string for everything to add after the
+ *            host/port, may be null
+ * @return the number of characters written to the destination buffer
+ */
+int ff_url_join(char *str, int size, const char *proto,
+                const char *authorization, const char *hostname,
+                int port, const char *fmt, ...) av_printf_format(7, 8);
+
+/*
+ * Convert a relative url into an absolute url, given a base url.
+ *
+ * @param buf the buffer where output absolute url is written
+ * @param size the size of buf
+ * @param base the base url, may be equal to buf.
+ * @param rel the new url, which is interpreted relative to base
+ */
+void ff_make_absolute_url(char *buf, int size, const char *base,
+                          const char *rel);
+
+
 #endif /* AVFORMAT_URL_H */
diff --git a/libavformat/urldecode.c b/libavformat/urldecode.c
index 32460da..49af9ba 100644
--- a/libavformat/urldecode.c
+++ b/libavformat/urldecode.c
@@ -26,7 +26,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <ctype.h>
 #include <string.h>
 
 #include "libavutil/mem.h"
@@ -54,7 +53,7 @@ char *ff_urldecode(const char *url)
         if (c == '%' && s + 2 < url_len) {
             char c2 = url[s++];
             char c3 = url[s++];
-            if (isxdigit(c2) && isxdigit(c3)) {
+            if (av_isxdigit(c2) && av_isxdigit(c3)) {
                 c2 = av_tolower(c2);
                 c3 = av_tolower(c3);
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index b0bfea2..0b715e4 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -19,7 +19,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/* #define DEBUG */
+#include <stdint.h>
 
 #include "avformat.h"
 #include "avio_internal.h"
@@ -28,6 +28,7 @@
 #include "libavcodec/bytestream.h"
 #include "libavutil/opt.h"
 #include "libavutil/dict.h"
+#include "libavutil/internal.h"
 #include "libavutil/pixdesc.h"
 #include "metadata.h"
 #include "id3v2.h"
@@ -68,184 +69,68 @@ const char *avformat_license(void)
     return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
 }
 
-/** head of registered input format linked list */
-static AVInputFormat *first_iformat = NULL;
-/** head of registered output format linked list */
-static AVOutputFormat *first_oformat = NULL;
+/* an arbitrarily chosen "sane" max packet size -- 50M */
+#define SANE_CHUNK_SIZE (50000000)
 
-AVInputFormat  *av_iformat_next(AVInputFormat  *f)
-{
-    if(f) return f->next;
-    else  return first_iformat;
-}
-
-AVOutputFormat *av_oformat_next(AVOutputFormat *f)
-{
-    if(f) return f->next;
-    else  return first_oformat;
-}
-
-void av_register_input_format(AVInputFormat *format)
-{
-    AVInputFormat **p;
-    p = &first_iformat;
-    while (*p != NULL) p = &(*p)->next;
-    *p = format;
-    format->next = NULL;
-}
-
-void av_register_output_format(AVOutputFormat *format)
-{
-    AVOutputFormat **p;
-    p = &first_oformat;
-    while (*p != NULL) p = &(*p)->next;
-    *p = format;
-    format->next = NULL;
-}
-
-int av_match_ext(const char *filename, const char *extensions)
+/*
+ * Read the data in sane-sized chunks and append to pkt.
+ * Return the number of bytes read or an error.
+ */
+static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
 {
-    const char *ext, *p;
-    char ext1[32], *q;
+    int64_t chunk_size = size;
+    int64_t orig_pos   = pkt->pos; // av_grow_packet might reset pos
+    int orig_size      = pkt->size;
+    int ret = 0;
 
-    if(!filename)
-        return 0;
+    do {
+        int prev_size = pkt->size;
+        int read_size;
 
-    ext = strrchr(filename, '.');
-    if (ext) {
-        ext++;
-        p = extensions;
-        for(;;) {
-            q = ext1;
-            while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
-                *q++ = *p++;
-            *q = '\0';
-            if (!av_strcasecmp(ext1, ext))
-                return 1;
-            if (*p == '\0')
-                break;
-            p++;
+        /*
+         * When the caller requests a lot of data, limit it to the amount left
+         * in file or SANE_CHUNK_SIZE when it is not known
+         */
+        if (size > SANE_CHUNK_SIZE) {
+            int64_t filesize = avio_size(s) - avio_tell(s);
+            chunk_size = FFMAX(filesize, SANE_CHUNK_SIZE);
         }
-    }
-    return 0;
-}
-
-static int match_format(const char *name, const char *names)
-{
-    const char *p;
-    int len, namelen;
-
-    if (!name || !names)
-        return 0;
-
-    namelen = strlen(name);
-    while ((p = strchr(names, ','))) {
-        len = FFMAX(p - names, namelen);
-        if (!av_strncasecmp(name, names, len))
-            return 1;
-        names = p+1;
-    }
-    return !av_strcasecmp(name, names);
-}
+        read_size = FFMIN(size, chunk_size);
 
-AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
-                                const char *mime_type)
-{
-    AVOutputFormat *fmt = NULL, *fmt_found;
-    int score_max, score;
+        ret = av_grow_packet(pkt, read_size);
+        if (ret < 0)
+            break;
 
-    /* specific test for image sequences */
-#if CONFIG_IMAGE2_MUXER
-    if (!short_name && filename &&
-        av_filename_number_test(filename) &&
-        ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {
-        return av_guess_format("image2", NULL, NULL);
-    }
-#endif
-    /* Find the proper file type. */
-    fmt_found = NULL;
-    score_max = 0;
-    while ((fmt = av_oformat_next(fmt))) {
-        score = 0;
-        if (fmt->name && short_name && !av_strcasecmp(fmt->name, short_name))
-            score += 100;
-        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
-            score += 10;
-        if (filename && fmt->extensions &&
-            av_match_ext(filename, fmt->extensions)) {
-            score += 5;
-        }
-        if (score > score_max) {
-            score_max = score;
-            fmt_found = fmt;
+        ret = avio_read(s, pkt->data + prev_size, read_size);
+        if (ret != read_size) {
+            av_shrink_packet(pkt, prev_size + FFMAX(ret, 0));
+            break;
         }
-    }
-    return fmt_found;
-}
 
-enum AVCodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
-                            const char *filename, const char *mime_type, enum AVMediaType type){
-    if(type == AVMEDIA_TYPE_VIDEO){
-        enum AVCodecID codec_id= AV_CODEC_ID_NONE;
+        size -= read_size;
+    } while (size > 0);
 
-#if CONFIG_IMAGE2_MUXER
-        if(!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")){
-            codec_id= ff_guess_image2_codec(filename);
-        }
-#endif
-        if(codec_id == AV_CODEC_ID_NONE)
-            codec_id= fmt->video_codec;
-        return codec_id;
-    }else if(type == AVMEDIA_TYPE_AUDIO)
-        return fmt->audio_codec;
-    else if (type == AVMEDIA_TYPE_SUBTITLE)
-        return fmt->subtitle_codec;
-    else
-        return AV_CODEC_ID_NONE;
-}
-
-AVInputFormat *av_find_input_format(const char *short_name)
-{
-    AVInputFormat *fmt = NULL;
-    while ((fmt = av_iformat_next(fmt))) {
-        if (match_format(short_name, fmt->name))
-            return fmt;
-    }
-    return NULL;
+    pkt->pos = orig_pos;
+    if (!pkt->size)
+        av_free_packet(pkt);
+    return pkt->size > orig_size ? pkt->size - orig_size : ret;
 }
 
-
 int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
 {
-    int ret= av_new_packet(pkt, size);
-
-    if(ret<0)
-        return ret;
-
-    pkt->pos= avio_tell(s);
-
-    ret= avio_read(s, pkt->data, size);
-    if(ret<=0)
-        av_free_packet(pkt);
-    else
-        av_shrink_packet(pkt, ret);
+    av_init_packet(pkt);
+    pkt->data = NULL;
+    pkt->size = 0;
+    pkt->pos  = avio_tell(s);
 
-    return ret;
+    return append_packet_chunked(s, pkt, size);
 }
 
 int av_append_packet(AVIOContext *s, AVPacket *pkt, int size)
 {
-    int ret;
-    int old_size;
     if (!pkt->size)
         return av_get_packet(s, pkt, size);
-    old_size = pkt->size;
-    ret = av_grow_packet(pkt, size);
-    if (ret < 0)
-        return ret;
-    ret = avio_read(s, pkt->data + old_size, size);
-    av_shrink_packet(pkt, old_size + FFMAX(ret, 0));
-    return ret;
+    return append_packet_chunked(s, pkt, size);
 }
 
 
@@ -279,7 +164,7 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score
             score = fmt1->read_probe(&lpd);
         } else if (fmt1->extensions) {
             if (av_match_ext(lpd.filename, fmt1->extensions)) {
-                score = 50;
+                score = AVPROBE_SCORE_EXTENSION;
             }
         }
         if (score > *score_max) {
@@ -290,18 +175,18 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score
     }
 
     /* a hack for files with huge id3v2 tags -- try to guess by file extension. */
-    if (!fmt && is_opened && *score_max < AVPROBE_SCORE_MAX/4) {
+    if (!fmt && is_opened && *score_max < AVPROBE_SCORE_EXTENSION / 2) {
         while ((fmt = av_iformat_next(fmt)))
             if (fmt->extensions && av_match_ext(lpd.filename, fmt->extensions)) {
-                *score_max = AVPROBE_SCORE_MAX/4;
+                *score_max = AVPROBE_SCORE_EXTENSION / 2;
                 break;
             }
     }
 
-    if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4-1) {
+    if (!fmt && id3 && *score_max < AVPROBE_SCORE_EXTENSION / 2 - 1) {
         while ((fmt = av_iformat_next(fmt)))
             if (fmt->extensions && av_match_ext("mp3", fmt->extensions)) {
-                *score_max = AVPROBE_SCORE_MAX/4-1;
+                *score_max = AVPROBE_SCORE_EXTENSION / 2 - 1;
                 break;
             }
     }
@@ -383,7 +268,8 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
         }
 
         /* read probe data */
-        buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
+        if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0)
+            return ret;
         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) {
@@ -464,16 +350,20 @@ static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
     return &pktl->pkt;
 }
 
-static void queue_attached_pictures(AVFormatContext *s)
+static int queue_attached_pictures(AVFormatContext *s)
 {
     int i;
     for (i = 0; i < s->nb_streams; i++)
         if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
             s->streams[i]->discard < AVDISCARD_ALL) {
             AVPacket copy = s->streams[i]->attached_pic;
-            copy.destruct = NULL;
+            copy.buf      = av_buffer_ref(copy.buf);
+            if (!copy.buf)
+                return AVERROR(ENOMEM);
+
             add_to_pktbuf(&s->raw_packet_buffer, &copy, &s->raw_packet_buffer_end);
         }
+    return 0;
 }
 
 int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
@@ -535,7 +425,8 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma
         goto fail;
     ff_id3v2_free_extra_meta(&id3v2_extra_meta);
 
-    queue_attached_pictures(s);
+    if ((ret = queue_attached_pictures(s)) < 0)
+        goto fail;
 
     if (s->pb && !s->data_offset)
         s->data_offset = avio_tell(s->pb);
@@ -561,7 +452,7 @@ fail:
 
 /*******************************************************/
 
-static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
+static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
 {
     if(st->codec->codec_id == AV_CODEC_ID_PROBE){
         AVProbeData *pd = &st->probe_data;
@@ -569,7 +460,10 @@ static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
         --st->probe_packets;
 
         if (pkt) {
-            pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
+            int err;
+            if ((err = av_reallocp(&pd->buf, pd->buf_size + pkt->size +
+                                   AVPROBE_PADDING_SIZE)) < 0)
+                return err;
             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);
@@ -578,7 +472,7 @@ static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
             if (!pd->buf_size) {
                 av_log(s, AV_LOG_ERROR, "nothing to probe for stream %d\n",
                        st->index);
-                return;
+                return 0;
             }
         }
 
@@ -592,11 +486,12 @@ static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
             }
         }
     }
+    return 0;
 }
 
 int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    int ret, i;
+    int ret, i, err;
     AVStream *st;
 
     for(;;){
@@ -609,7 +504,8 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
                 s->raw_packet_buffer_remaining_size < pkt->size) {
                 AVProbeData *pd;
                 if (st->probe_packets) {
-                    probe_codec(s, st, NULL);
+                    if ((err = probe_codec(s, st, NULL)) < 0)
+                        return err;
                 }
                 pd = &st->probe_data;
                 av_freep(&pd->buf);
@@ -631,7 +527,8 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
             for (i = 0; i < s->nb_streams; i++) {
                 st = s->streams[i];
                 if (st->probe_packets) {
-                    probe_codec(s, st, NULL);
+                    if ((err = probe_codec(s, st, NULL)) < 0)
+                        return err;
                 }
             }
             continue;
@@ -667,18 +564,11 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
         add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
         s->raw_packet_buffer_remaining_size -= pkt->size;
 
-        probe_codec(s, st, pkt);
+        if ((err = probe_codec(s, st, pkt)) < 0)
+            return err;
     }
 }
 
-#if FF_API_READ_PACKET
-int av_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    return ff_read_packet(s, pkt);
-}
-#endif
-
-
 /**********************************************************/
 
 /**
@@ -695,7 +585,7 @@ int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux)
     if ((frame_size = av_get_audio_frame_duration(enc, size)) > 0)
         return frame_size;
 
-    /* fallback to using frame_size if muxing */
+    /* Fall back on using frame_size if muxing. */
     if (enc->frame_size > 1)
         return enc->frame_size;
 
@@ -848,8 +738,9 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
         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*/){
+    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) {
         pkt->dts -= 1LL<<st->pts_wrap_bits;
     }
 
@@ -882,25 +773,6 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
             pkt->dts += offset;
     }
 
-    if (pc && pc->dts_sync_point >= 0) {
-        // we have synchronization info from the parser
-        int64_t den = st->codec->time_base.den * (int64_t) st->time_base.num;
-        if (den > 0) {
-            int64_t num = st->codec->time_base.num * (int64_t) st->time_base.den;
-            if (pkt->dts != AV_NOPTS_VALUE) {
-                // got DTS from the stream, update reference timestamp
-                st->reference_dts = pkt->dts - pc->dts_ref_dts_delta * num / den;
-                pkt->pts = pkt->dts + pc->pts_dts_delta * num / den;
-            } else if (st->reference_dts != AV_NOPTS_VALUE) {
-                // compute DTS based on reference timestamp
-                pkt->dts = st->reference_dts + pc->dts_ref_dts_delta * num / den;
-                pkt->pts = pkt->dts + pc->pts_dts_delta * num / den;
-            }
-            if (pc->dts_sync_point > 0)
-                st->reference_dts = pkt->dts; // new reference
-        }
-    }
-
     /* This may be redundant, but it should not hurt. */
     if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
         presentation_delayed = 1;
@@ -1037,6 +909,13 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
         if (!out_pkt.size)
             continue;
 
+        if (pkt->side_data) {
+            out_pkt.side_data       = pkt->side_data;
+            out_pkt.side_data_elems = pkt->side_data_elems;
+            pkt->side_data       = NULL;
+            pkt->side_data_elems = 0;
+        }
+
         /* set the duration */
         out_pkt.duration = 0;
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -1074,8 +953,14 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
         }
 
         if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) {
+            out_pkt.buf   = pkt->buf;
+            pkt->buf      = NULL;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
             out_pkt.destruct = pkt->destruct;
             pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
         }
         if ((ret = av_dup_packet(&out_pkt)) < 0)
             goto fail;
@@ -1312,7 +1197,6 @@ void ff_read_frame_flush(AVFormatContext *s)
         }
         st->last_IP_pts = AV_NOPTS_VALUE;
         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;
 
@@ -1735,7 +1619,7 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f
     int ret = seek_frame_internal(s, stream_index, timestamp, flags);
 
     if (ret >= 0)
-        queue_attached_pictures(s);
+        ret = queue_attached_pictures(s);
 
     return ret;
 }
@@ -1751,7 +1635,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
         ret = s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags);
 
         if (ret >= 0)
-            queue_attached_pictures(s);
+            ret = queue_attached_pictures(s);
         return ret;
     }
 
@@ -1759,8 +1643,8 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int
         //try to seek via read_timestamp()
     }
 
-    //Fallback to old API if new is not implemented but old is
-    //Note the old has somewat different sematics
+    // Fall back on old API if new is not implemented but old is.
+    // Note the old API has somewhat different semantics.
     if(s->iformat->read_seek || 1)
         return av_seek_frame(s, stream_index, ts, flags | ((uint64_t)ts - min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0));
 
@@ -1855,12 +1739,12 @@ static void fill_all_stream_timings(AVFormatContext *ic)
 static void estimate_timings_from_bit_rate(AVFormatContext *ic)
 {
     int64_t filesize, duration;
-    int bit_rate, i;
+    int i;
     AVStream *st;
 
     /* if bit_rate is already set, we believe it */
     if (ic->bit_rate <= 0) {
-        bit_rate = 0;
+        int bit_rate = 0;
         for(i=0;i<ic->nb_streams;i++) {
             st = ic->streams[i];
             if (st->codec->bit_rate > 0) {
@@ -1966,7 +1850,6 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
         st= ic->streams[i];
         st->cur_dts= st->first_dts;
         st->last_IP_pts = AV_NOPTS_VALUE;
-        st->reference_dts = AV_NOPTS_VALUE;
     }
 }
 
@@ -2047,7 +1930,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option
 {
     const AVCodec *codec;
     int got_picture = 1, ret = 0;
-    AVFrame *frame = avcodec_alloc_frame();
+    AVFrame *frame = av_frame_alloc();
     AVPacket pkt = *avpkt;
 
     if (!frame)
@@ -2090,7 +1973,6 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option
            !has_decode_delay_been_guessed(st) ||
            (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) {
         got_picture = 0;
-        avcodec_get_frame_defaults(frame);
         switch(st->codec->codec_type) {
         case AVMEDIA_TYPE_VIDEO:
             ret = avcodec_decode_video2(st->codec, frame,
@@ -2112,7 +1994,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option
     }
 
 fail:
-    avcodec_free_frame(&frame);
+    av_frame_free(&frame);
     return ret;
 }
 
@@ -2280,9 +2162,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
     }
 
     for (i=0; i<ic->nb_streams; i++) {
-#if FF_API_R_FRAME_RATE
-        ic->streams[i]->info->last_dts = AV_NOPTS_VALUE;
-#endif
         ic->streams[i]->info->fps_first_dts = AV_NOPTS_VALUE;
         ic->streams[i]->info->fps_last_dts  = AV_NOPTS_VALUE;
     }
@@ -2431,31 +2310,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
                 break;
             }
         }
-#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){
-                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++) {
-                    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;
-                }
-                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)
-                st->info->last_dts = pkt->dts;
-        }
-#endif
         if(st->parser && st->parser->parser->split && !st->codec->extradata){
             int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
             if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
@@ -2522,30 +2376,6 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
                               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)
-                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;
-
-                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);
-                    }
-                }
-                // 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
         }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);
@@ -2706,13 +2536,6 @@ void avformat_free_context(AVFormatContext *s)
     av_free(s);
 }
 
-#if FF_API_CLOSE_INPUT_FILE
-void av_close_input_file(AVFormatContext *s)
-{
-    avformat_close_input(&s);
-}
-#endif
-
 void avformat_close_input(AVFormatContext **ps)
 {
     AVFormatContext *s = *ps;
@@ -2740,14 +2563,11 @@ AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
 {
     AVStream *st;
     int i;
-    AVStream **streams;
 
-    if (s->nb_streams >= INT_MAX/sizeof(*streams))
+    if (av_reallocp_array(&s->streams, s->nb_streams + 1, sizeof(*s->streams)) < 0) {
+        s->nb_streams = 0;
         return NULL;
-    streams = av_realloc(s->streams, (s->nb_streams + 1) * sizeof(*streams));
-    if (!streams)
-        return NULL;
-    s->streams = streams;
+    }
 
     st = av_mallocz(sizeof(AVStream));
     if (!st)
@@ -2778,13 +2598,9 @@ AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
     st->last_IP_pts = AV_NOPTS_VALUE;
     for(i=0; i<MAX_REORDER_DELAY+1; i++)
         st->pts_buffer[i]= AV_NOPTS_VALUE;
-    st->reference_dts = AV_NOPTS_VALUE;
 
     st->sample_aspect_ratio = (AVRational){0,1};
 
-#if FF_API_R_FRAME_RATE
-    st->info->last_dts      = AV_NOPTS_VALUE;
-#endif
     st->info->fps_first_dts = AV_NOPTS_VALUE;
     st->info->fps_last_dts  = AV_NOPTS_VALUE;
 
@@ -2843,7 +2659,6 @@ void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int i
 {
     int i, j;
     AVProgram *program=NULL;
-    void *tmp;
 
     if (idx >= ac->nb_streams) {
         av_log(ac, AV_LOG_ERROR, "stream index %d is not valid\n", idx);
@@ -2858,10 +2673,12 @@ void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int i
             if(program->stream_index[j] == idx)
                 return;
 
-        tmp = av_realloc(program->stream_index, sizeof(unsigned int)*(program->nb_stream_indexes+1));
-        if(!tmp)
+        if (av_reallocp_array(&program->stream_index,
+                              program->nb_stream_indexes + 1,
+                              sizeof(*program->stream_index)) < 0) {
+            program->nb_stream_indexes = 0;
             return;
-        program->stream_index = tmp;
+        }
         program->stream_index[program->nb_stream_indexes++] = idx;
         return;
     }
@@ -2919,10 +2736,6 @@ static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_out
     if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
         if(st->avg_frame_rate.den && st->avg_frame_rate.num)
             print_fps(av_q2d(st->avg_frame_rate), "fps");
-#if FF_API_R_FRAME_RATE
-        if(st->r_frame_rate.den && st->r_frame_rate.num)
-            print_fps(av_q2d(st->r_frame_rate), "tbr");
-#endif
         if(st->time_base.den && st->time_base.num)
             print_fps(1/av_q2d(st->time_base), "tbn");
         if(st->codec->time_base.den && st->codec->time_base.num)
@@ -3031,13 +2844,6 @@ void av_dump_format(AVFormatContext *ic,
     av_free(printed);
 }
 
-#if FF_API_AV_GETTIME && CONFIG_SHARED && HAVE_SYMVER
-FF_SYMVER(int64_t, av_gettime, (void), "LIBAVFORMAT_54")
-{
-    return av_gettime();
-}
-#endif
-
 uint64_t ff_ntp_time(void)
 {
   return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
@@ -3060,11 +2866,11 @@ int av_get_frame_filename(char *buf, int buf_size,
         if (c == '%') {
             do {
                 nd = 0;
-                while (isdigit(*p)) {
+                while (av_isdigit(*p)) {
                     nd = nd * 10 + *p++ - '0';
                 }
                 c = *p++;
-            } while (isdigit(c));
+            } while (av_isdigit(c));
 
             switch(c) {
             case '%':
@@ -3265,7 +3071,7 @@ int ff_hex_to_data(uint8_t *data, const char *p)
         p += strspn(p, SPACE_CHARS);
         if (*p == '\0')
             break;
-        c = toupper((unsigned char) *p++);
+        c = av_toupper((unsigned char) *p++);
         if (c >= '0' && c <= '9')
             c = c - '0';
         else if (c >= 'A' && c <= 'F')
@@ -3301,68 +3107,6 @@ void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
     s->pts_wrap_bits = pts_wrap_bits;
 }
 
-int ff_url_join(char *str, int size, const char *proto,
-                const char *authorization, const char *hostname,
-                int port, const char *fmt, ...)
-{
-#if CONFIG_NETWORK
-    struct addrinfo hints = { 0 }, *ai;
-#endif
-
-    str[0] = '\0';
-    if (proto)
-        av_strlcatf(str, size, "%s://", proto);
-    if (authorization && authorization[0])
-        av_strlcatf(str, size, "%s@", authorization);
-#if CONFIG_NETWORK && defined(AF_INET6)
-    /* Determine if hostname is a numerical IPv6 address,
-     * properly escape it within [] in that case. */
-    hints.ai_flags = AI_NUMERICHOST;
-    if (!getaddrinfo(hostname, NULL, &hints, &ai)) {
-        if (ai->ai_family == AF_INET6) {
-            av_strlcat(str, "[", size);
-            av_strlcat(str, hostname, size);
-            av_strlcat(str, "]", size);
-        } else {
-            av_strlcat(str, hostname, size);
-        }
-        freeaddrinfo(ai);
-    } else
-#endif
-        /* Not an IPv6 address, just output the plain string. */
-        av_strlcat(str, hostname, size);
-
-    if (port >= 0)
-        av_strlcatf(str, size, ":%d", port);
-    if (fmt) {
-        va_list vl;
-        int len = strlen(str);
-
-        va_start(vl, fmt);
-        vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
-        va_end(vl);
-    }
-    return strlen(str);
-}
-
-int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
-                     AVFormatContext *src)
-{
-    AVPacket local_pkt;
-
-    local_pkt = *pkt;
-    local_pkt.stream_index = dst_stream;
-    if (pkt->pts != AV_NOPTS_VALUE)
-        local_pkt.pts = av_rescale_q(pkt->pts,
-                                     src->streams[pkt->stream_index]->time_base,
-                                     dst->streams[dst_stream]->time_base);
-    if (pkt->dts != AV_NOPTS_VALUE)
-        local_pkt.dts = av_rescale_q(pkt->dts,
-                                     src->streams[pkt->stream_index]->time_base,
-                                     dst->streams[dst_stream]->time_base);
-    return av_write_frame(dst, &local_pkt);
-}
-
 void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
                         void *context)
 {
@@ -3375,7 +3119,7 @@ void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
         int key_len, dest_len = 0;
 
         /* Skip whitespace and potential commas. */
-        while (*ptr && (isspace(*ptr) || *ptr == ','))
+        while (*ptr && (av_isspace(*ptr) || *ptr == ','))
             ptr++;
         if (!*ptr)
             break;
@@ -3408,7 +3152,7 @@ void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
             if (*ptr == '\"')
                 ptr++;
         } else {
-            for (; *ptr && !(isspace(*ptr) || *ptr == ','); ptr++)
+            for (; *ptr && !(av_isspace(*ptr) || *ptr == ','); ptr++)
                 if (dest && dest < dest_end)
                     *dest++ = *ptr;
         }
@@ -3427,75 +3171,6 @@ int ff_find_stream_index(AVFormatContext *s, int id)
     return -1;
 }
 
-void ff_make_absolute_url(char *buf, int size, const char *base,
-                          const char *rel)
-{
-    char *sep, *path_query;
-    /* Absolute path, relative to the current server */
-    if (base && strstr(base, "://") && rel[0] == '/') {
-        if (base != buf)
-            av_strlcpy(buf, base, size);
-        sep = strstr(buf, "://");
-        if (sep) {
-            /* Take scheme from base url */
-            if (rel[1] == '/') {
-                sep[1] = '\0';
-            } else {
-                /* Take scheme and host from base url */
-                sep += 3;
-                sep = strchr(sep, '/');
-                if (sep)
-                    *sep = '\0';
-            }
-        }
-        av_strlcat(buf, rel, size);
-        return;
-    }
-    /* If rel actually is an absolute url, just copy it */
-    if (!base || strstr(rel, "://") || rel[0] == '/') {
-        av_strlcpy(buf, rel, size);
-        return;
-    }
-    if (base != buf)
-        av_strlcpy(buf, base, size);
-
-    /* Strip off any query string from base */
-    path_query = strchr(buf, '?');
-    if (path_query != NULL)
-        *path_query = '\0';
-
-    /* Is relative path just a new query part? */
-    if (rel[0] == '?') {
-        av_strlcat(buf, rel, size);
-        return;
-    }
-
-    /* Remove the file name from the base url */
-    sep = strrchr(buf, '/');
-    if (sep)
-        sep[1] = '\0';
-    else
-        buf[0] = '\0';
-    while (av_strstart(rel, "../", NULL) && sep) {
-        /* Remove the path delimiter at the end */
-        sep[0] = '\0';
-        sep = strrchr(buf, '/');
-        /* If the next directory name to pop off is "..", break here */
-        if (!strcmp(sep ? &sep[1] : buf, "..")) {
-            /* Readd the slash we just removed */
-            av_strlcat(buf, "/", size);
-            break;
-        }
-        /* Cut off the directory name */
-        if (sep)
-            sep[1] = '\0';
-        else
-            buf[0] = '\0';
-        rel += 3;
-    }
-    av_strlcat(buf, rel, size);
-}
-
 int64_t ff_iso8601_to_unix_time(const char *datestr)
 {
 #if HAVE_STRPTIME
@@ -3591,11 +3266,104 @@ int ff_add_param_change(AVPacket *pkt, int32_t channels,
     return 0;
 }
 
-const struct AVCodecTag *avformat_get_riff_video_tags(void)
-{
-    return ff_codec_bmp_tags;
-}
-const struct AVCodecTag *avformat_get_riff_audio_tags(void)
-{
-    return ff_codec_wav_tags;
+int ff_generate_avci_extradata(AVStream *st)
+{
+    static const uint8_t avci100_1080p_extradata[] = {
+        // SPS
+        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+        0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
+        0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
+        0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
+        0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
+        0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
+        0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
+        0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
+        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        // PPS
+        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
+        0xd0
+    };
+    static const uint8_t avci100_1080i_extradata[] = {
+        // SPS
+        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+        0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
+        0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
+        0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
+        0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
+        0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
+        0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
+        0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
+        0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
+        0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
+        0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x00,
+        // PPS
+        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
+        0xd0
+    };
+    static const uint8_t avci50_1080i_extradata[] = {
+        // SPS
+        0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
+        0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
+        0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
+        0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
+        0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
+        0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
+        0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
+        0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
+        0x81, 0x13, 0xf7, 0xff, 0x80, 0x01, 0x80, 0x02,
+        0x71, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
+        0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
+        // PPS
+        0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
+        0x11
+    };
+    static const uint8_t avci100_720p_extradata[] = {
+        // SPS
+        0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+        0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
+        0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
+        0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
+        0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
+        0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
+        0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
+        0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
+        0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
+        0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
+        // PPS
+        0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
+        0x11
+    };
+
+    const uint8_t *data = NULL;
+    int size = 0;
+
+    if (st->codec->width == 1920) {
+        if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
+            data = avci100_1080p_extradata;
+            size = sizeof(avci100_1080p_extradata);
+        } else {
+            data = avci100_1080i_extradata;
+            size = sizeof(avci100_1080i_extradata);
+        }
+    } else if (st->codec->width == 1440) {
+        data = avci50_1080i_extradata;
+        size = sizeof(avci50_1080i_extradata);
+    } else if (st->codec->width == 1280) {
+        data = avci100_720p_extradata;
+        size = sizeof(avci100_720p_extradata);
+    }
+
+    if (!size)
+        return 0;
+
+    av_freep(&st->codec->extradata);
+    st->codec->extradata_size = 0;
+    st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!st->codec->extradata)
+        return AVERROR(ENOMEM);
+
+    memcpy(st->codec->extradata, data, size);
+    st->codec->extradata_size = size;
+
+    return 0;
 }
diff --git a/libavformat/vc1test.c b/libavformat/vc1test.c
index 1895fc4..859188f 100644
--- a/libavformat/vc1test.c
+++ b/libavformat/vc1test.c
@@ -39,7 +39,7 @@ static int vc1t_probe(AVProbeData *p)
     if (p->buf[3] != 0xC5 || AV_RL32(&p->buf[4]) != 4 || AV_RL32(&p->buf[20]) != 0xC)
         return 0;
 
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int vc1t_read_header(AVFormatContext *s)
diff --git a/libavformat/vc1testenc.c b/libavformat/vc1testenc.c
index abe8c6b..9d55fee 100644
--- a/libavformat/vc1testenc.c
+++ b/libavformat/vc1testenc.c
@@ -63,7 +63,6 @@ static int vc1test_write_packet(AVFormatContext *s, AVPacket *pkt)
     avio_wl32(pb, pkt->size | ((pkt->flags & AV_PKT_FLAG_KEY) ? 0x80000000 : 0));
     avio_wl32(pb, pkt->pts);
     avio_write(pb, pkt->data, pkt->size);
-    avio_flush(pb);
     ctx->frames++;
 
     return 0;
diff --git a/libavformat/version.h b/libavformat/version.h
index c2c1e3a..23a9d67 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -29,9 +29,9 @@
 
 #include "libavutil/avutil.h"
 
-#define LIBAVFORMAT_VERSION_MAJOR 54
-#define LIBAVFORMAT_VERSION_MINOR 20
-#define LIBAVFORMAT_VERSION_MICRO  3
+#define LIBAVFORMAT_VERSION_MAJOR 55
+#define LIBAVFORMAT_VERSION_MINOR 10
+#define LIBAVFORMAT_VERSION_MICRO  1
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
@@ -48,24 +48,8 @@
  * 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_CLOSE_INPUT_FILE
-#define FF_API_CLOSE_INPUT_FILE        (LIBAVFORMAT_VERSION_MAJOR < 55)
-#endif
-#ifndef FF_API_APPLEHTTP_PROTO
-#define FF_API_APPLEHTTP_PROTO         (LIBAVFORMAT_VERSION_MAJOR < 55)
-#endif
-#ifndef FF_API_READ_PACKET
-#define FF_API_READ_PACKET             (LIBAVFORMAT_VERSION_MAJOR < 55)
-#endif
-#ifndef FF_API_INTERLEAVE_PACKET
-#define FF_API_INTERLEAVE_PACKET       (LIBAVFORMAT_VERSION_MAJOR < 55)
-#endif
-#ifndef FF_API_AV_GETTIME
-#define FF_API_AV_GETTIME              (LIBAVFORMAT_VERSION_MAJOR < 55)
-#endif
-#ifndef FF_API_R_FRAME_RATE
-#define FF_API_R_FRAME_RATE            (LIBAVFORMAT_VERSION_MAJOR < 55)
+#ifndef FF_API_REFERENCE_DTS
+#define FF_API_REFERENCE_DTS            (LIBAVFORMAT_VERSION_MAJOR < 56)
 #endif
 
 #endif /* AVFORMAT_VERSION_H */
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index aba6ab1..a43829b 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -43,7 +43,7 @@ static int vqf_probe(AVProbeData *probe_packet)
     if (!memcmp(probe_packet->buf + 4, "00052200", 8))
         return AVPROBE_SCORE_MAX;
 
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static void add_metadata(AVFormatContext *s, uint32_t tag,
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index e9dda92..f65a66a 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -23,25 +23,26 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavutil/avassert.h"
 #include "libavutil/dict.h"
 #include "libavutil/log.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
-#include "internal.h"
+#include "avio.h"
 #include "avio_internal.h"
+#include "internal.h"
+#include "metadata.h"
 #include "pcm.h"
 #include "riff.h"
-#include "avio.h"
-#include "metadata.h"
 
 typedef struct WAVDemuxContext {
     int64_t data_end;
     int w64;
 } WAVDemuxContext;
 
-
 #if CONFIG_WAV_DEMUXER
 
 static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
@@ -80,11 +81,9 @@ static int wav_probe(AVProbeData *p)
         return 0;
     if (!memcmp(p->buf + 8, "WAVE", 4)) {
         if (!memcmp(p->buf, "RIFF", 4))
-            /*
-              Since ACT demuxer has standard WAV header at top of it's own,
-              returning score is decreased to avoid probe conflict
-              between ACT and WAV.
-            */
+            /* Since the ACT demuxer has a standard WAV header at the top of
+             * its own, the returned score is decreased to avoid a probe
+             * conflict between ACT and WAV. */
             return AVPROBE_SCORE_MAX - 1;
         else if (!memcmp(p->buf,      "RF64", 4) &&
                  !memcmp(p->buf + 12, "ds64", 4))
@@ -157,16 +156,22 @@ static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
 
         if (umid_mask) {
             /* the string formatting below is per SMPTE 330M-2004 Annex C */
-            if (umid_parts[4] == 0 && umid_parts[5] == 0 && umid_parts[6] == 0 && umid_parts[7] == 0) {
+            if (umid_parts[4] == 0 && umid_parts[5] == 0 &&
+                umid_parts[6] == 0 && umid_parts[7] == 0) {
                 /* basic UMID */
-                snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
-                         umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3]);
+                snprintf(temp, sizeof(temp),
+                         "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+                         umid_parts[0], umid_parts[1],
+                         umid_parts[2], umid_parts[3]);
             } else {
                 /* extended UMID */
-                snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
-                                             "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
-                         umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3],
-                         umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]);
+                snprintf(temp, sizeof(temp),
+                         "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
+                         "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+                         umid_parts[0], umid_parts[1],
+                         umid_parts[2], umid_parts[3],
+                         umid_parts[4], umid_parts[5],
+                         umid_parts[6], umid_parts[7]);
             }
 
             if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
@@ -181,7 +186,7 @@ static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
         /* CodingHistory present */
         size -= 602;
 
-        if (!(coding_history = av_malloc(size+1)))
+        if (!(coding_history = av_malloc(size + 1)))
             return AVERROR(ENOMEM);
 
         if ((ret = avio_read(s->pb, coding_history, size)) < 0)
@@ -197,22 +202,22 @@ static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
 }
 
 static const AVMetadataConv wav_metadata_conv[] = {
-    {"description",      "comment"      },
-    {"originator",       "encoded_by"   },
-    {"origination_date", "date"         },
-    {"origination_time", "creation_time"},
-    {0},
+    { "description",      "comment"       },
+    { "originator",       "encoded_by"    },
+    { "origination_date", "date"          },
+    { "origination_time", "creation_time" },
+    { 0 },
 };
 
 /* wav input */
 static int wav_read_header(AVFormatContext *s)
 {
     int64_t size, av_uninit(data_size);
-    int64_t sample_count=0;
+    int64_t sample_count = 0;
     int rf64;
     uint32_t tag;
-    AVIOContext *pb = s->pb;
-    AVStream *st = NULL;
+    AVIOContext *pb      = s->pb;
+    AVStream *st         = NULL;
     WAVDemuxContext *wav = s->priv_data;
     int ret, got_fmt = 0;
     int64_t next_tag_ofs, data_ofs = -1;
@@ -222,21 +227,23 @@ static int wav_read_header(AVFormatContext *s)
 
     rf64 = tag == MKTAG('R', 'F', '6', '4');
     if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
-        return -1;
+        return AVERROR_INVALIDDATA;
     avio_rl32(pb); /* file size */
     tag = avio_rl32(pb);
     if (tag != MKTAG('W', 'A', 'V', 'E'))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (rf64) {
         if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
-            return -1;
+            return AVERROR_INVALIDDATA;
         size = avio_rl32(pb);
         if (size < 16)
-            return -1;
+            return AVERROR_INVALIDDATA;
         avio_rl64(pb); /* RIFF size */
-        data_size = avio_rl64(pb);
+
+        data_size    = avio_rl64(pb);
         sample_count = avio_rl64(pb);
+
         if (data_size < 0 || sample_count < 0) {
             av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
                    "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
@@ -247,7 +254,7 @@ static int wav_read_header(AVFormatContext *s)
     }
 
     for (;;) {
-        size = next_tag(pb, &tag);
+        size         = next_tag(pb, &tag);
         next_tag_ofs = avio_tell(pb) + size;
 
         if (pb->eof_reached)
@@ -265,14 +272,15 @@ static int wav_read_header(AVFormatContext *s)
             break;
         case MKTAG('d', 'a', 't', 'a'):
             if (!got_fmt) {
-                av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'data' tag\n");
+                av_log(s, AV_LOG_ERROR,
+                       "found no 'fmt ' tag before the 'data' tag\n");
                 return AVERROR_INVALIDDATA;
             }
 
             if (rf64) {
                 next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
             } else {
-                data_size = size;
+                data_size    = size;
                 next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
             }
 
@@ -284,11 +292,11 @@ static int wav_read_header(AVFormatContext *s)
             if (!pb->seekable || (!rf64 && !size))
                 goto break_loop;
             break;
-        case MKTAG('f','a','c','t'):
+        case MKTAG('f', 'a', 'c', 't'):
             if (!sample_count)
                 sample_count = avio_rl32(pb);
             break;
-        case MKTAG('b','e','x','t'):
+        case MKTAG('b', 'e', 'x', 't'):
             if ((ret = wav_parse_bext_tag(s, size)) < 0)
                 return ret;
             break;
@@ -311,6 +319,7 @@ static int wav_read_header(AVFormatContext *s)
             break;
         }
     }
+
 break_loop:
     if (data_ofs < 0) {
         av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
@@ -319,8 +328,11 @@ break_loop:
 
     avio_seek(pb, data_ofs, SEEK_SET);
 
-    if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id))
-        sample_count = (data_size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+    if (!sample_count && st->codec->channels &&
+        av_get_bits_per_sample(st->codec->codec_id))
+        sample_count = (data_size << 3) /
+                       (st->codec->channels *
+                        (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
     if (sample_count)
         st->duration = sample_count;
 
@@ -330,7 +342,8 @@ break_loop:
     return 0;
 }
 
-/** Find chunk with w64 GUID by skipping over other chunks
+/**
+ * Find chunk with w64 GUID by skipping over other chunks.
  * @return the size of the found chunk
  */
 static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
@@ -350,13 +363,14 @@ static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
     return -1;
 }
 
-static const uint8_t guid_data[16] = { 'd', 'a', 't', 'a',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+static const uint8_t guid_data[16] = {
+    'd',  'a',  't',  'a',
+    0xF3, 0xAC, 0xD3, 0x11,0x8C,  0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
 
 #define MAX_SIZE 4096
 
-static int wav_read_packet(AVFormatContext *s,
-                           AVPacket *pkt)
+static int wav_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     int ret, size;
     int64_t left;
@@ -366,14 +380,14 @@ static int wav_read_packet(AVFormatContext *s,
     st = s->streams[0];
 
     left = wav->data_end - avio_tell(s->pb);
-    if (left <= 0){
+    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)
             return AVERROR_EOF;
-        wav->data_end= avio_tell(s->pb) + left;
+        wav->data_end = avio_tell(s->pb) + left;
     }
 
     size = MAX_SIZE;
@@ -419,20 +433,25 @@ AVInputFormat ff_wav_demuxer = {
     .read_packet    = wav_read_packet,
     .read_seek      = wav_read_seek,
     .flags          = AVFMT_GENERIC_INDEX,
-    .codec_tag      = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+    .codec_tag      = (const AVCodecTag * const []) { ff_codec_wav_tags,  0 },
 };
 #endif /* CONFIG_WAV_DEMUXER */
 
-
 #if CONFIG_W64_DEMUXER
-static const uint8_t guid_riff[16] = { 'r', 'i', 'f', 'f',
-    0x2E, 0x91, 0xCF, 0x11, 0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00 };
+static const uint8_t guid_riff[16] = {
+    'r',  'i',  'f',  'f',
+    0x2E, 0x91, 0xCF, 0x11,0xA5,  0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00
+};
 
-static const uint8_t guid_wave[16] = { 'w', 'a', 'v', 'e',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+static const uint8_t guid_wave[16] = {
+    'w',  'a',  'v',  'e',
+    0xF3, 0xAC, 0xD3, 0x11,0x8C,  0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
 
-static const uint8_t guid_fmt [16] = { 'f', 'm', 't', ' ',
-    0xF3, 0xAC, 0xD3, 0x11, 0x8C, 0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A };
+static const uint8_t guid_fmt[16] = {
+    'f',  'm',  't',  ' ',
+    0xF3, 0xAC, 0xD3, 0x11,0x8C,  0xD1, 0x00, 0xC0, 0x4F, 0x8E, 0xDB, 0x8A
+};
 
 static int w64_probe(AVProbeData *p)
 {
@@ -448,29 +467,30 @@ static int w64_probe(AVProbeData *p)
 static int w64_read_header(AVFormatContext *s)
 {
     int64_t size;
-    AVIOContext *pb  = s->pb;
-    WAVDemuxContext    *wav = s->priv_data;
+    AVIOContext *pb      = s->pb;
+    WAVDemuxContext *wav = s->priv_data;
     AVStream *st;
     uint8_t guid[16];
     int ret;
 
     avio_read(pb, guid, 16);
     if (memcmp(guid, guid_riff, 16))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
-    if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) /* riff + wave + fmt + sizes */
-        return -1;
+    /* riff + wave + fmt + sizes */
+    if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
+        return AVERROR_INVALIDDATA;
 
     avio_read(pb, guid, 16);
     if (memcmp(guid, guid_wave, 16)) {
         av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     size = find_guid(pb, guid_fmt);
     if (size < 0) {
         av_log(s, AV_LOG_ERROR, "could not find fmt guid\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     st = avformat_new_stream(s, NULL);
@@ -490,7 +510,7 @@ static int w64_read_header(AVFormatContext *s)
     size = find_guid(pb, guid_data);
     if (size < 0) {
         av_log(s, AV_LOG_ERROR, "could not find data guid\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     wav->data_end = avio_tell(pb) + size - 24;
     wav->w64      = 1;
@@ -507,6 +527,6 @@ AVInputFormat ff_w64_demuxer = {
     .read_packet    = wav_read_packet,
     .read_seek      = wav_read_seek,
     .flags          = AVFMT_GENERIC_INDEX,
-    .codec_tag      = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+    .codec_tag      = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
 };
 #endif /* CONFIG_W64_DEMUXER */
diff --git a/libavformat/westwood_aud.c b/libavformat/westwood_aud.c
index 2a06c29..611d223 100644
--- a/libavformat/westwood_aud.c
+++ b/libavformat/westwood_aud.c
@@ -79,7 +79,7 @@ static int wsaud_probe(AVProbeData *p)
         return 0;
 
     /* return 1/2 certainty since this file check is a little sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int wsaud_read_header(AVFormatContext *s)
@@ -104,7 +104,7 @@ static int wsaud_read_header(AVFormatContext *s)
     switch (codec) {
     case  1:
         if (channels != 1) {
-            av_log_ask_for_sample(s, "Stereo WS-SND1 is not supported.\n");
+            avpriv_request_sample(s, "Stereo WS-SND1");
             return AVERROR_PATCHWELCOME;
         }
         st->codec->codec_id = AV_CODEC_ID_WESTWOOD_SND1;
@@ -115,7 +115,7 @@ static int wsaud_read_header(AVFormatContext *s)
         st->codec->bit_rate = channels * sample_rate * 4;
         break;
     default:
-        av_log_ask_for_sample(s, "Unknown codec: %d\n", codec);
+        avpriv_request_sample(s, "Unknown codec: %d", codec);
         return AVERROR_PATCHWELCOME;
     }
     avpriv_set_pts_info(st, 64, 1, sample_rate);
diff --git a/libavformat/wtv.c b/libavformat/wtv.c
index 7f029ff..0c24fd7 100644
--- a/libavformat/wtv.c
+++ b/libavformat/wtv.c
@@ -36,11 +36,6 @@
 #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) \
@@ -57,6 +52,8 @@
 #define WTV_SECTOR_SIZE    (1 << WTV_SECTOR_BITS)
 #define WTV_BIGSECTOR_BITS 18
 
+#define SHIFT_SECTOR_BITS(a) ((int64_t)(a) << WTV_SECTOR_BITS)
+
 typedef struct {
     AVIOContext *pb_filesystem;  /** file system (AVFormatContext->pb) */
 
@@ -69,6 +66,11 @@ typedef struct {
     int64_t length;
 } WtvFile;
 
+static int64_t seek_by_sector(AVIOContext *pb, int64_t sector, int64_t offset)
+{
+    return avio_seek(pb, SHIFT_SECTOR_BITS(sector) + offset, SEEK_SET);
+}
+
 /**
  * @return bytes read, 0 on end of file, or <0 on error
  */
@@ -99,7 +101,7 @@ static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
             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)) {
+                seek_by_sector(pb, wf->sectors[i], 0) < 0)) {
                 wf->error = 1;
                 break;
             }
@@ -124,8 +126,8 @@ static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence)
         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;
+                seek_by_sector(pb, wf->sectors[offset >> wf->sector_bits],
+                               offset & ((1 << wf->sector_bits) - 1)) < 0;
     wf->position = offset;
     return offset;
 }
@@ -160,7 +162,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int
     WtvFile *wf;
     uint8_t *buffer;
 
-    if (avio_seek(s->pb, first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
+    if (seek_by_sector(s->pb, first_sector, 0) < 0)
         return NULL;
 
     wf = av_mallocz(sizeof(WtvFile));
@@ -189,14 +191,14 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int
         int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4);
         int i;
 
-        wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS);
+        wf->sectors = av_malloc(SHIFT_SECTOR_BITS(nb_sectors1));
         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)
+            if (seek_by_sector(s->pb, sectors1[i], 0) < 0)
                 break;
             wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
         }
@@ -223,7 +225,7 @@ static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int
 
     /* seek to initial sector */
     wf->position = 0;
-    if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
+    if (seek_by_sector(s->pb, wf->sectors[0], 0) < 0) {
         av_free(wf->sectors);
         av_free(wf);
         return NULL;
@@ -267,8 +269,8 @@ static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int b
         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));
+            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);
@@ -336,21 +338,6 @@ typedef struct {
     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 =
     {0xB7,0xD8,0x00,0x20,0x37,0x49,0xDA,0x11,0xA6,0x4E,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
@@ -385,14 +372,11 @@ static const ff_asf_guid EVENTID_AudioTypeSpanningEvent =
 
 /* 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};
+    {'a','u','d','s',FF_MEDIASUBTYPE_BASE_GUID};
 static const ff_asf_guid mediatype_video =
-    {'v','i','d','s',MEDIASUBTYPE_BASE_GUID};
+    {'v','i','d','s',FF_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 =
@@ -431,13 +415,6 @@ static const AVCodecGuid video_guids[] = {
     {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;
@@ -548,7 +525,7 @@ static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int ty
         else
             snprintf(buf, buf_size, "%"PRIi64, num);
     } else if (type == 5 && length == 2) {
-        snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb));
+        snprintf(buf, buf_size, "%u", avio_rl16(pb));
     } else if (type == 6 && length == 16) {
         ff_asf_guid guid;
         avio_read(pb, guid, 16);
@@ -583,8 +560,8 @@ static void parse_legacy_attrib(AVFormatContext *s, AVIOContext *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));
+            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));
@@ -708,11 +685,11 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
                 return NULL;
         } else {
             if (ff_guidcmp(formattype, format_none))
-                av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
+                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[]){MEDIASUBTYPE_BASE_GUID}, 12)) {
+        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)
@@ -720,9 +697,9 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
             else
                 av_log(s, AV_LOG_WARNING, "MPEG1WAVEFORMATEX underflow\n");
         } else {
-            st->codec->codec_id = ff_codec_guid_get_id(audio_guids, subtype);
+            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:"PRI_GUID"\n", ARG_GUID(subtype));
+                av_log(s, AV_LOG_WARNING, "unknown subtype:"FF_PRI_GUID"\n", FF_ARG_GUID(subtype));
         }
         return st;
     } else if (!ff_guidcmp(mediatype, mediatype_video)) {
@@ -737,17 +714,17 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
             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));
+                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[]){MEDIASUBTYPE_BASE_GUID}, 12)) {
+        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(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));
+            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)) {
@@ -755,7 +732,7 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
         if (!st)
             return NULL;
         if (ff_guidcmp(formattype, format_none))
-            av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
+            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;
@@ -765,21 +742,21 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
         if (!st)
             return NULL;
         if (ff_guidcmp(formattype, format_none))
-            av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
+            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_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));
+            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:"PRI_GUID
-                              ", subtype:"PRI_GUID", formattype:"PRI_GUID"\n",
-                              ARG_GUID(mediatype), ARG_GUID(subtype), ARG_GUID(formattype));
+    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;
 }
@@ -951,7 +928,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p
             !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));
+            av_log(s, AV_LOG_WARNING, "unsupported chunk:"FF_PRI_GUID"\n", FF_ARG_GUID(g));
 
         avio_skip(pb, WTV_PAD8(len) - consumed);
     }
@@ -993,7 +970,7 @@ static int read_header(AVFormatContext *s)
     avio_skip(s->pb, 4);
     root_sector = avio_rl32(s->pb);
 
-    avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET);
+    seek_by_sector(s->pb, root_sector, 0);
     root_size = avio_read(s->pb, root, root_size);
     if (root_size < 0)
         return AVERROR_INVALIDDATA;
diff --git a/libavformat/wv.c b/libavformat/wv.c
index f6b96d5..724256b 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -1,6 +1,5 @@
 /*
- * WavPack demuxer
- * Copyright (c) 2006,2011 Konstantin Shishkov
+ * WavPack shared functions
  *
  * This file is part of Libav.
  *
@@ -19,378 +18,35 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/channel_layout.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/dict.h"
-#include "avformat.h"
-#include "internal.h"
-#include "apetag.h"
-#include "id3v1.h"
-
-// specs say that maximum block size is 1Mb
-#define WV_BLOCK_LIMIT 1047576
-
-#define WV_EXTRA_SIZE 12
-
-#define WV_START_BLOCK  0x0800
-#define WV_END_BLOCK    0x1000
-#define WV_SINGLE_BLOCK (WV_START_BLOCK | WV_END_BLOCK)
-
-enum WV_FLAGS {
-    WV_MONO   = 0x0004,
-    WV_HYBRID = 0x0008,
-    WV_JOINT  = 0x0010,
-    WV_CROSSD = 0x0020,
-    WV_HSHAPE = 0x0040,
-    WV_FLOAT  = 0x0080,
-    WV_INT32  = 0x0100,
-    WV_HBR    = 0x0200,
-    WV_HBAL   = 0x0400,
-    WV_MCINIT = 0x0800,
-    WV_MCEND  = 0x1000,
-};
+#include <stdint.h>
+#include <string.h>
 
-static const int wv_rates[16] = {
-     6000,  8000,  9600, 11025, 12000, 16000,  22050, 24000,
-    32000, 44100, 48000, 64000, 88200, 96000, 192000,    -1
-};
-
-typedef struct {
-    uint32_t blksize, flags;
-    int rate, chan, bpp;
-    uint32_t chmask;
-    uint32_t samples, soff;
-    int multichannel;
-    int block_parsed;
-    uint8_t extra[WV_EXTRA_SIZE];
-    int64_t pos;
-
-    int64_t apetag_start;
-} WVContext;
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
 
-static int wv_probe(AVProbeData *p)
-{
-    /* check file header */
-    if (p->buf_size <= 32)
-        return 0;
-    if (p->buf[0] == 'w' && p->buf[1] == 'v' &&
-        p->buf[2] == 'p' && p->buf[3] == 'k')
-        return AVPROBE_SCORE_MAX;
-    else
-        return 0;
-}
+#include "wv.h"
 
-static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb,
-                                int append)
+int ff_wv_parse_header(WvHeader *wv, const uint8_t *data)
 {
-    WVContext *wc = ctx->priv_data;
-    uint32_t tag, ver;
-    int size;
-    int rate, bpp, chan;
-    uint32_t chmask;
-
-    wc->pos = avio_tell(pb);
-
-    /* don't return bogus packets with the ape tag data */
-    if (wc->apetag_start && wc->pos >= wc->apetag_start)
-        return AVERROR_EOF;
+    memset(wv, 0, sizeof(*wv));
 
-    if (!append) {
-        tag = avio_rl32(pb);
-        if (tag != MKTAG('w', 'v', 'p', 'k'))
-            return AVERROR_INVALIDDATA;
-        size = avio_rl32(pb);
-        if (size < 24 || size > WV_BLOCK_LIMIT) {
-            av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size);
-            return AVERROR_INVALIDDATA;
-        }
-        wc->blksize = size;
-        ver = avio_rl16(pb);
-        if (ver < 0x402 || ver > 0x410) {
-            av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
-            return AVERROR_PATCHWELCOME;
-        }
-        avio_r8(pb); // track no
-        avio_r8(pb); // track sub index
-        wc->samples = avio_rl32(pb); // total samples in file
-        wc->soff    = avio_rl32(pb); // offset in samples of current block
-        avio_read(pb, wc->extra, WV_EXTRA_SIZE);
-    } else {
-        size = wc->blksize;
-    }
-    wc->flags = AV_RL32(wc->extra + 4);
-    /* Blocks with zero samples don't contain actual audio information
-     * and should be ignored */
-    if (!AV_RN32(wc->extra))
-        return 0;
-    // parse flags
-    bpp    = ((wc->flags & 3) + 1) << 3;
-    chan   = 1 + !(wc->flags & WV_MONO);
-    chmask = wc->flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
-    rate   = wv_rates[(wc->flags >> 23) & 0xF];
-    wc->multichannel = !!((wc->flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK);
-    if (wc->multichannel) {
-        chan   = wc->chan;
-        chmask = wc->chmask;
-    }
-    if ((rate == -1 || !chan) && !wc->block_parsed) {
-        int64_t block_end = avio_tell(pb) + wc->blksize - 24;
-        if (!pb->seekable) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Cannot determine additional parameters\n");
-            return AVERROR_INVALIDDATA;
-        }
-        while (avio_tell(pb) < block_end) {
-            int id, size;
-            id   = avio_r8(pb);
-            size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
-            size <<= 1;
-            if (id & 0x40)
-                size--;
-            switch (id & 0x3F) {
-            case 0xD:
-                if (size <= 1) {
-                    av_log(ctx, AV_LOG_ERROR,
-                           "Insufficient channel information\n");
-                    return AVERROR_INVALIDDATA;
-                }
-                chan = avio_r8(pb);
-                switch (size - 2) {
-                case 0:
-                    chmask = avio_r8(pb);
-                    break;
-                case 1:
-                    chmask = avio_rl16(pb);
-                    break;
-                case 2:
-                    chmask = avio_rl24(pb);
-                    break;
-                case 3:
-                    chmask = avio_rl32(pb);
-                    break;
-                case 5:
-                    avio_skip(pb, 1);
-                    chan  |= (avio_r8(pb) & 0xF) << 8;
-                    chmask = avio_rl24(pb);
-                    break;
-                default:
-                    av_log(ctx, AV_LOG_ERROR,
-                           "Invalid channel info size %d\n", size);
-                    return AVERROR_INVALIDDATA;
-                }
-                break;
-            case 0x27:
-                rate = avio_rl24(pb);
-                break;
-            default:
-                avio_skip(pb, size);
-            }
-            if (id & 0x40)
-                avio_skip(pb, 1);
-        }
-        if (rate == -1) {
-            av_log(ctx, AV_LOG_ERROR,
-                   "Cannot determine custom sampling rate\n");
-            return AVERROR_INVALIDDATA;
-        }
-        avio_seek(pb, block_end - wc->blksize + 24, SEEK_SET);
-    }
-    if (!wc->bpp)
-        wc->bpp    = bpp;
-    if (!wc->chan)
-        wc->chan   = chan;
-    if (!wc->chmask)
-        wc->chmask = chmask;
-    if (!wc->rate)
-        wc->rate   = rate;
-
-    if (wc->flags && bpp != wc->bpp) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Bits per sample differ, this block: %i, header block: %i\n",
-               bpp, wc->bpp);
-        return AVERROR_INVALIDDATA;
-    }
-    if (wc->flags && !wc->multichannel && chan != wc->chan) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Channels differ, this block: %i, header block: %i\n",
-               chan, wc->chan);
+    if (AV_RL32(data) != MKTAG('w', 'v', 'p', 'k'))
         return AVERROR_INVALIDDATA;
-    }
-    if (wc->flags && rate != -1 && rate != wc->rate) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Sampling rate differ, this block: %i, header block: %i\n",
-               rate, wc->rate);
-        return AVERROR_INVALIDDATA;
-    }
-    wc->blksize = size - 24;
-    return 0;
-}
 
-static int wv_read_header(AVFormatContext *s)
-{
-    AVIOContext *pb = s->pb;
-    WVContext *wc = s->priv_data;
-    AVStream *st;
-    int ret;
-
-    wc->block_parsed = 0;
-    for (;;) {
-        if ((ret = wv_read_block_header(s, pb, 0)) < 0)
-            return ret;
-        if (!AV_RN32(wc->extra))
-            avio_skip(pb, wc->blksize - 24);
-        else
-            break;
-    }
-
-    /* now we are ready: build format streams */
-    st = avformat_new_stream(s, NULL);
-    if (!st)
-        return AVERROR(ENOMEM);
-    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_id              = AV_CODEC_ID_WAVPACK;
-    st->codec->channels              = wc->chan;
-    st->codec->channel_layout        = wc->chmask;
-    st->codec->sample_rate           = wc->rate;
-    st->codec->bits_per_coded_sample = wc->bpp;
-    avpriv_set_pts_info(st, 64, 1, wc->rate);
-    st->start_time = 0;
-    st->duration   = wc->samples;
-
-    if (s->pb->seekable) {
-        int64_t cur = avio_tell(s->pb);
-        wc->apetag_start = ff_ape_parse_tag(s);
-        if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
-            ff_id3v1_read(s);
-        avio_seek(s->pb, cur, SEEK_SET);
-    }
-
-    return 0;
-}
-
-static int wv_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    WVContext *wc = s->priv_data;
-    int ret;
-    int size, ver, off;
-    int64_t pos;
-    uint32_t block_samples;
-
-    if (s->pb->eof_reached)
-        return AVERROR_EOF;
-    if (wc->block_parsed) {
-        if ((ret = wv_read_block_header(s, s->pb, 0)) < 0)
-            return ret;
-    }
-
-    pos = wc->pos;
-    off = wc->multichannel ? 4 : 0;
-    if (av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0)
-        return AVERROR(ENOMEM);
-    if (wc->multichannel)
-        AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12);
-    memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE);
-    ret = avio_read(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize);
-    if (ret != wc->blksize) {
-        av_free_packet(pkt);
-        return AVERROR(EIO);
-    }
-    while (!(wc->flags & WV_END_BLOCK)) {
-        if (avio_rl32(s->pb) != MKTAG('w', 'v', 'p', 'k')) {
-            av_free_packet(pkt);
-            return AVERROR_INVALIDDATA;
-        }
-        if ((ret = av_append_packet(s->pb, pkt, 4)) < 0) {
-            av_free_packet(pkt);
-            return ret;
-        }
-        size = AV_RL32(pkt->data + pkt->size - 4);
-        if (size < 24 || size > WV_BLOCK_LIMIT) {
-            av_free_packet(pkt);
-            av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size);
-            return AVERROR_INVALIDDATA;
-        }
-        wc->blksize = size;
-        ver         = avio_rl16(s->pb);
-        if (ver < 0x402 || ver > 0x410) {
-            av_free_packet(pkt);
-            av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
-            return AVERROR_PATCHWELCOME;
-        }
-        avio_r8(s->pb); // track no
-        avio_r8(s->pb); // track sub index
-        wc->samples = avio_rl32(s->pb); // total samples in file
-        wc->soff    = avio_rl32(s->pb); // offset in samples of current block
-        if ((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0) {
-            av_free_packet(pkt);
-            return ret;
-        }
-        memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE);
-
-        if ((ret = wv_read_block_header(s, s->pb, 1)) < 0) {
-            av_free_packet(pkt);
-            return ret;
-        }
-        ret = av_append_packet(s->pb, pkt, wc->blksize);
-        if (ret < 0) {
-            av_free_packet(pkt);
-            return ret;
-        }
-    }
-    pkt->stream_index = 0;
-    wc->block_parsed  = 1;
-    pkt->pts          = wc->soff;
-    block_samples     = AV_RN32(wc->extra);
-    if (block_samples > INT32_MAX)
-        av_log(s, AV_LOG_WARNING,
-               "Too many samples in block: %"PRIu32"\n", block_samples);
-    else
-        pkt->duration = block_samples;
-
-    av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
-    return 0;
-}
+    wv->blocksize     = AV_RL32(data + 4);
+    if (wv->blocksize < 24 || wv->blocksize > WV_BLOCK_LIMIT)
+        return AVERROR_INVALIDDATA;
+    wv->blocksize -= 24;
 
-static int wv_read_seek(AVFormatContext *s, int stream_index,
-                        int64_t timestamp, int flags)
-{
-    AVStream  *st = s->streams[stream_index];
-    WVContext *wc = s->priv_data;
-    AVPacket pkt1, *pkt = &pkt1;
-    int ret;
-    int index = av_index_search_timestamp(st, timestamp, flags);
-    int64_t pos, pts;
+    wv->version       = AV_RL16(data + 8);
+    wv->total_samples = AV_RL32(data + 12);
+    wv->block_idx     = AV_RL32(data + 16);
+    wv->samples       = AV_RL32(data + 20);
+    wv->flags         = AV_RL32(data + 24);
+    wv->crc           = AV_RL32(data + 28);
 
-    /* if found, seek there */
-    if (index >= 0 &&
-        timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
-        wc->block_parsed = 1;
-        avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
-        return 0;
-    }
-    /* if timestamp is out of bounds, return error */
-    if (timestamp < 0 || timestamp >= s->duration)
-        return AVERROR(EINVAL);
+    wv->initial = !!(wv->flags & WV_FLAG_INITIAL_BLOCK);
+    wv->final   = !!(wv->flags & WV_FLAG_FINAL_BLOCK);
 
-    pos = avio_tell(s->pb);
-    do {
-        ret = av_read_frame(s, pkt);
-        if (ret < 0) {
-            avio_seek(s->pb, pos, SEEK_SET);
-            return ret;
-        }
-        pts = pkt->pts;
-        av_free_packet(pkt);
-    } while(pts < timestamp);
     return 0;
 }
-
-AVInputFormat ff_wv_demuxer = {
-    .name           = "wv",
-    .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
-    .priv_data_size = sizeof(WVContext),
-    .read_probe     = wv_probe,
-    .read_header    = wv_read_header,
-    .read_packet    = wv_read_packet,
-    .read_seek      = wv_read_seek,
-};
diff --git a/libavformat/wv.h b/libavformat/wv.h
new file mode 100644
index 0000000..ef285d2
--- /dev/null
+++ b/libavformat/wv.h
@@ -0,0 +1,56 @@
+/*
+ * WavPack shared functions
+ *
+ * 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 AVFORMAT_WV_H
+#define AVFORMAT_WV_H
+
+#include <stdint.h>
+
+#define WV_HEADER_SIZE 32
+
+#define WV_FLAG_INITIAL_BLOCK (1 << 11)
+#define WV_FLAG_FINAL_BLOCK   (1 << 12)
+
+// specs say that maximum block size is 1Mb
+#define WV_BLOCK_LIMIT 1048576
+
+typedef struct WvHeader {
+    uint32_t blocksize;     //< size of the block data (excluding the header)
+    uint16_t version;       //< bitstream version
+    uint32_t total_samples; //< total number of samples in the stream
+    uint32_t block_idx;     //< index of the first sample in this block
+    uint32_t samples;       //< number of samples in this block
+    uint32_t flags;
+    uint32_t crc;
+
+    int initial, final;
+} WvHeader;
+
+/**
+ * Parse a WavPack block header.
+ *
+ * @param wv   this struct will be filled with parse header information
+ * @param data header data, must be WV_HEADER_SIZE bytes long
+ *
+ * @return 0 on success, a negative AVERROR code on failure
+ */
+int ff_wv_parse_header(WvHeader *wv, const uint8_t *data);
+
+#endif /* AVFORMAT_WV_H */
diff --git a/libavformat/wvdec.c b/libavformat/wvdec.c
new file mode 100644
index 0000000..1a2a722
--- /dev/null
+++ b/libavformat/wvdec.c
@@ -0,0 +1,350 @@
+/*
+ * WavPack demuxer
+ * Copyright (c) 2006,2011 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/channel_layout.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
+#include "avformat.h"
+#include "internal.h"
+#include "apetag.h"
+#include "id3v1.h"
+#include "wv.h"
+
+enum WV_FLAGS {
+    WV_MONO   = 0x0004,
+    WV_HYBRID = 0x0008,
+    WV_JOINT  = 0x0010,
+    WV_CROSSD = 0x0020,
+    WV_HSHAPE = 0x0040,
+    WV_FLOAT  = 0x0080,
+    WV_INT32  = 0x0100,
+    WV_HBR    = 0x0200,
+    WV_HBAL   = 0x0400,
+    WV_MCINIT = 0x0800,
+    WV_MCEND  = 0x1000,
+};
+
+static const int wv_rates[16] = {
+     6000,  8000,  9600, 11025, 12000, 16000,  22050, 24000,
+    32000, 44100, 48000, 64000, 88200, 96000, 192000,    -1
+};
+
+typedef struct {
+    uint8_t block_header[WV_HEADER_SIZE];
+    WvHeader header;
+    int rate, chan, bpp;
+    uint32_t chmask;
+    int multichannel;
+    int block_parsed;
+    int64_t pos;
+
+    int64_t apetag_start;
+} WVContext;
+
+static int wv_probe(AVProbeData *p)
+{
+    /* check file header */
+    if (p->buf_size <= 32)
+        return 0;
+    if (p->buf[0] == 'w' && p->buf[1] == 'v' &&
+        p->buf[2] == 'p' && p->buf[3] == 'k')
+        return AVPROBE_SCORE_MAX;
+    else
+        return 0;
+}
+
+static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb)
+{
+    WVContext *wc = ctx->priv_data;
+    int ret;
+    int rate, bpp, chan;
+    uint32_t chmask, flags;
+
+    wc->pos = avio_tell(pb);
+
+    /* don't return bogus packets with the ape tag data */
+    if (wc->apetag_start && wc->pos >= wc->apetag_start)
+        return AVERROR_EOF;
+
+    ret = avio_read(pb, wc->block_header, WV_HEADER_SIZE);
+    if (ret != WV_HEADER_SIZE)
+        return (ret < 0) ? ret : AVERROR_EOF;
+
+    ret = ff_wv_parse_header(&wc->header, wc->block_header);
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid block header.\n");
+        return ret;
+    }
+
+    if (wc->header.version < 0x402 || wc->header.version > 0x410) {
+        av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", wc->header.version);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    /* Blocks with zero samples don't contain actual audio information
+     * and should be ignored */
+    if (!wc->header.samples)
+        return 0;
+    // parse flags
+    flags  = wc->header.flags;
+    bpp    = ((flags & 3) + 1) << 3;
+    chan   = 1 + !(flags & WV_MONO);
+    chmask = flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+    rate   = wv_rates[(flags >> 23) & 0xF];
+    wc->multichannel = !(wc->header.initial && wc->header.final);
+    if (wc->multichannel) {
+        chan   = wc->chan;
+        chmask = wc->chmask;
+    }
+    if ((rate == -1 || !chan) && !wc->block_parsed) {
+        int64_t block_end = avio_tell(pb) + wc->header.blocksize;
+        if (!pb->seekable) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Cannot determine additional parameters\n");
+            return AVERROR_INVALIDDATA;
+        }
+        while (avio_tell(pb) < block_end) {
+            int id, size;
+            id   = avio_r8(pb);
+            size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb);
+            size <<= 1;
+            if (id & 0x40)
+                size--;
+            switch (id & 0x3F) {
+            case 0xD:
+                if (size <= 1) {
+                    av_log(ctx, AV_LOG_ERROR,
+                           "Insufficient channel information\n");
+                    return AVERROR_INVALIDDATA;
+                }
+                chan = avio_r8(pb);
+                switch (size - 2) {
+                case 0:
+                    chmask = avio_r8(pb);
+                    break;
+                case 1:
+                    chmask = avio_rl16(pb);
+                    break;
+                case 2:
+                    chmask = avio_rl24(pb);
+                    break;
+                case 3:
+                    chmask = avio_rl32(pb);
+                    break;
+                case 5:
+                    avio_skip(pb, 1);
+                    chan  |= (avio_r8(pb) & 0xF) << 8;
+                    chmask = avio_rl24(pb);
+                    break;
+                default:
+                    av_log(ctx, AV_LOG_ERROR,
+                           "Invalid channel info size %d\n", size);
+                    return AVERROR_INVALIDDATA;
+                }
+                break;
+            case 0x27:
+                rate = avio_rl24(pb);
+                break;
+            default:
+                avio_skip(pb, size);
+            }
+            if (id & 0x40)
+                avio_skip(pb, 1);
+        }
+        if (rate == -1) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Cannot determine custom sampling rate\n");
+            return AVERROR_INVALIDDATA;
+        }
+        avio_seek(pb, block_end - wc->header.blocksize, SEEK_SET);
+    }
+    if (!wc->bpp)
+        wc->bpp    = bpp;
+    if (!wc->chan)
+        wc->chan   = chan;
+    if (!wc->chmask)
+        wc->chmask = chmask;
+    if (!wc->rate)
+        wc->rate   = rate;
+
+    if (flags && bpp != wc->bpp) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Bits per sample differ, this block: %i, header block: %i\n",
+               bpp, wc->bpp);
+        return AVERROR_INVALIDDATA;
+    }
+    if (flags && !wc->multichannel && chan != wc->chan) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Channels differ, this block: %i, header block: %i\n",
+               chan, wc->chan);
+        return AVERROR_INVALIDDATA;
+    }
+    if (flags && rate != -1 && rate != wc->rate) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Sampling rate differ, this block: %i, header block: %i\n",
+               rate, wc->rate);
+        return AVERROR_INVALIDDATA;
+    }
+    return 0;
+}
+
+static int wv_read_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    WVContext *wc = s->priv_data;
+    AVStream *st;
+    int ret;
+
+    wc->block_parsed = 0;
+    for (;;) {
+        if ((ret = wv_read_block_header(s, pb)) < 0)
+            return ret;
+        if (!wc->header.samples)
+            avio_skip(pb, wc->header.blocksize);
+        else
+            break;
+    }
+
+    /* now we are ready: build format streams */
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id              = AV_CODEC_ID_WAVPACK;
+    st->codec->channels              = wc->chan;
+    st->codec->channel_layout        = wc->chmask;
+    st->codec->sample_rate           = wc->rate;
+    st->codec->bits_per_coded_sample = wc->bpp;
+    avpriv_set_pts_info(st, 64, 1, wc->rate);
+    st->start_time = 0;
+    st->duration   = wc->header.total_samples;
+
+    if (s->pb->seekable) {
+        int64_t cur = avio_tell(s->pb);
+        wc->apetag_start = ff_ape_parse_tag(s);
+        if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
+            ff_id3v1_read(s);
+        avio_seek(s->pb, cur, SEEK_SET);
+    }
+
+    return 0;
+}
+
+static int wv_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    WVContext *wc = s->priv_data;
+    int ret;
+    int off;
+    int64_t pos;
+    uint32_t block_samples;
+
+    if (s->pb->eof_reached)
+        return AVERROR_EOF;
+    if (wc->block_parsed) {
+        if ((ret = wv_read_block_header(s, s->pb)) < 0)
+            return ret;
+    }
+
+    pos = wc->pos;
+    if (av_new_packet(pkt, wc->header.blocksize + WV_HEADER_SIZE) < 0)
+        return AVERROR(ENOMEM);
+    memcpy(pkt->data, wc->block_header, WV_HEADER_SIZE);
+    ret = avio_read(s->pb, pkt->data + WV_HEADER_SIZE, wc->header.blocksize);
+    if (ret != wc->header.blocksize) {
+        av_free_packet(pkt);
+        return AVERROR(EIO);
+    }
+    while (!(wc->header.flags & WV_FLAG_FINAL_BLOCK)) {
+        if ((ret = wv_read_block_header(s, s->pb)) < 0) {
+            av_free_packet(pkt);
+            return ret;
+        }
+
+        off = pkt->size;
+        if ((ret = av_grow_packet(pkt, WV_HEADER_SIZE + wc->header.blocksize)) < 0) {
+            av_free_packet(pkt);
+            return ret;
+        }
+        memcpy(pkt->data + off, wc->block_header, WV_HEADER_SIZE);
+
+        ret = avio_read(s->pb, pkt->data + off + WV_HEADER_SIZE, wc->header.blocksize);
+        if (ret != wc->header.blocksize) {
+            av_free_packet(pkt);
+            return (ret < 0) ? ret : AVERROR_EOF;
+        }
+    }
+    pkt->stream_index = 0;
+    wc->block_parsed  = 1;
+    pkt->pts          = wc->header.block_idx;
+    block_samples     = wc->header.samples;
+    if (block_samples > INT32_MAX)
+        av_log(s, AV_LOG_WARNING,
+               "Too many samples in block: %"PRIu32"\n", block_samples);
+    else
+        pkt->duration = block_samples;
+
+    av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
+    return 0;
+}
+
+static int wv_read_seek(AVFormatContext *s, int stream_index,
+                        int64_t timestamp, int flags)
+{
+    AVStream  *st = s->streams[stream_index];
+    WVContext *wc = s->priv_data;
+    AVPacket pkt1, *pkt = &pkt1;
+    int ret;
+    int index = av_index_search_timestamp(st, timestamp, flags);
+    int64_t pos, pts;
+
+    /* if found, seek there */
+    if (index >= 0 &&
+        timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) {
+        wc->block_parsed = 1;
+        avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
+        return 0;
+    }
+    /* if timestamp is out of bounds, return error */
+    if (timestamp < 0 || timestamp >= s->duration)
+        return AVERROR(EINVAL);
+
+    pos = avio_tell(s->pb);
+    do {
+        ret = av_read_frame(s, pkt);
+        if (ret < 0) {
+            avio_seek(s->pb, pos, SEEK_SET);
+            return ret;
+        }
+        pts = pkt->pts;
+        av_free_packet(pkt);
+    } while(pts < timestamp);
+    return 0;
+}
+
+AVInputFormat ff_wv_demuxer = {
+    .name           = "wv",
+    .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
+    .priv_data_size = sizeof(WVContext),
+    .read_probe     = wv_probe,
+    .read_header    = wv_read_header,
+    .read_packet    = wv_read_packet,
+    .read_seek      = wv_read_seek,
+};
diff --git a/libavformat/wvenc.c b/libavformat/wvenc.c
new file mode 100644
index 0000000..2e150e1
--- /dev/null
+++ b/libavformat/wvenc.c
@@ -0,0 +1,87 @@
+/*
+ * 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/attributes.h"
+
+#include "apetag.h"
+#include "avformat.h"
+#include "wv.h"
+
+typedef struct WvMuxContext {
+    int64_t samples;
+} WvMuxContext;
+
+static av_cold int wv_write_header(AVFormatContext *ctx)
+{
+    if (ctx->nb_streams > 1 ||
+        ctx->streams[0]->codec->codec_id != AV_CODEC_ID_WAVPACK) {
+        av_log(ctx, AV_LOG_ERROR, "This muxer only supports a single WavPack stream.\n");
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+static int wv_write_packet(AVFormatContext *ctx, AVPacket *pkt)
+{
+    WvMuxContext *s = ctx->priv_data;
+    WvHeader header;
+    int ret;
+
+    if (pkt->size < WV_HEADER_SIZE ||
+        (ret = ff_wv_parse_header(&header, pkt->data)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid WavPack packet.\n");
+        return AVERROR(EINVAL);
+    }
+    s->samples += header.samples;
+
+    avio_write(ctx->pb, pkt->data, pkt->size);
+
+    return 0;
+}
+
+static av_cold int wv_write_trailer(AVFormatContext *ctx)
+{
+    WvMuxContext *s = ctx->priv_data;
+
+    /* update total number of samples in the first block */
+    if (ctx->pb->seekable && s->samples &&
+        s->samples < UINT32_MAX) {
+        int64_t pos = avio_tell(ctx->pb);
+        avio_seek(ctx->pb, 12, SEEK_SET);
+        avio_wl32(ctx->pb, s->samples);
+        avio_seek(ctx->pb, pos, SEEK_SET);
+    }
+
+    ff_ape_write_tag(ctx);
+    return 0;
+}
+
+AVOutputFormat ff_wv_muxer = {
+    .name              = "wv",
+    .long_name         = NULL_IF_CONFIG_SMALL("raw WavPack"),
+    .mime_type         = "audio/x-wavpack",
+    .extensions        = "wv",
+    .priv_data_size    = sizeof(WvMuxContext),
+    .audio_codec       = AV_CODEC_ID_WAVPACK,
+    .video_codec       = AV_CODEC_ID_NONE,
+    .write_header      = wv_write_header,
+    .write_packet      = wv_write_packet,
+    .write_trailer     = wv_write_trailer,
+    .flags             = AVFMT_NOTIMESTAMPS,
+};
diff --git a/libavformat/xa.c b/libavformat/xa.c
index 02d66c5..57a36bc 100644
--- a/libavformat/xa.c
+++ b/libavformat/xa.c
@@ -59,7 +59,7 @@ static int xa_probe(AVProbeData *p)
     if (!channels || channels > 8 || !srate || srate > 192000 ||
         bits_per_sample < 4 || bits_per_sample > 32)
         return 0;
-    return AVPROBE_SCORE_MAX/2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
 static int xa_read_header(AVFormatContext *s)
diff --git a/libavformat/xmv.c b/libavformat/xmv.c
index 201dc3a..2b2fd45 100644
--- a/libavformat/xmv.c
+++ b/libavformat/xmv.c
@@ -158,7 +158,7 @@ static int xmv_read_header(AVFormatContext *s)
 
     file_version = avio_rl32(pb);
     if ((file_version != 4) && (file_version != 2))
-        av_log_ask_for_sample(s, "Found uncommon version %d\n", file_version);
+        avpriv_request_sample(s, "Uncommon version %d", file_version);
 
 
     /* Video track */
diff --git a/libavformat/xwma.c b/libavformat/xwma.c
index 5500db8..45d74de 100644
--- a/libavformat/xwma.c
+++ b/libavformat/xwma.c
@@ -20,6 +20,7 @@
  */
 
 #include <inttypes.h>
+#include <stdint.h>
 
 #include "avformat.h"
 #include "internal.h"
@@ -42,7 +43,7 @@ static int xwma_probe(AVProbeData *p)
 
 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;
@@ -85,9 +86,8 @@ static int xwma_read_header(AVFormatContext *s)
      * anyway.
      */
     if (st->codec->codec_id != AV_CODEC_ID_WMAV2) {
-        av_log(s, AV_LOG_WARNING, "unexpected codec (tag 0x04%x; id %d)\n",
+        avpriv_request_sample(s, "Unexpected codec (tag 0x04%x; id %d)",
                               st->codec->codec_tag, st->codec->codec_id);
-        av_log_ask_for_sample(s, NULL);
     } else {
         /* In all xWMA files I have seen, there is no extradata. But the WMA
          * codecs require extradata, so we provide our own fake extradata.
@@ -101,9 +101,8 @@ static int xwma_read_header(AVFormatContext *s)
              * if it will work, but just go on and try it, after asking
              * the user for a sample.
              */
-            av_log(s, AV_LOG_WARNING, "unexpected extradata (%d bytes)\n",
+            avpriv_request_sample(s, "Unexpected extradata (%d bytes)",
                                   st->codec->extradata_size);
-            av_log_ask_for_sample(s, NULL);
         } else {
             st->codec->extradata_size = 6;
             st->codec->extradata      = av_mallocz(6 + FF_INPUT_BUFFER_PADDING_SIZE);
diff --git a/libavformat/yop.c b/libavformat/yop.c
index 5fe6bdc..8caeb07 100644
--- a/libavformat/yop.c
+++ b/libavformat/yop.c
@@ -127,6 +127,12 @@ static int yop_read_packet(AVFormatContext *s, AVPacket *pkt)
     if (yop->video_packet.data) {
         *pkt                   =  yop->video_packet;
         yop->video_packet.data =  NULL;
+        yop->video_packet.buf  =  NULL;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+        yop->video_packet.destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
         yop->video_packet.size =  0;
         pkt->data[0]           =  yop->odd_frame;
         pkt->flags             |= AV_PKT_FLAG_KEY;
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index a8077a0..cc2755f 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -18,6 +18,8 @@
  * 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/pixdesc.h"
 #include "avformat.h"
 #include "internal.h"
 
@@ -128,10 +130,11 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     if (st->codec->pix_fmt != AV_PIX_FMT_GRAY8) {
         // Adjust for smaller Cb and Cr planes
-        avcodec_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
-                                      &v_chroma_shift);
-        width  >>= h_chroma_shift;
-        height >>= v_chroma_shift;
+        av_pix_fmt_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
+                                         &v_chroma_shift);
+        // Shift right, rounding up
+        width  = -(-width  >> h_chroma_shift);
+        height = -(-height >> v_chroma_shift);
 
         ptr1 = picture->data[1];
         ptr2 = picture->data[2];
@@ -144,7 +147,6 @@ static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
             ptr2 += picture->linesize[2];
         }
     }
-    avio_flush(pb);
     return 0;
 }
 
diff --git a/libavresample/audio_convert.c b/libavresample/audio_convert.c
index eb3bc1f..371617c 100644
--- a/libavresample/audio_convert.c
+++ b/libavresample/audio_convert.c
@@ -30,7 +30,6 @@
 #include "audio_convert.h"
 #include "audio_data.h"
 #include "dither.h"
-#include "internal.h"
 
 enum ConvFuncType {
     CONV_FUNC_TYPE_FLAT,
@@ -51,6 +50,7 @@ struct AudioConvert {
     DitherContext *dc;
     enum AVSampleFormat in_fmt;
     enum AVSampleFormat out_fmt;
+    int apply_map;
     int channels;
     int planes;
     int ptr_align;
@@ -260,7 +260,8 @@ void ff_audio_convert_free(AudioConvert **ac)
 AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
                                      enum AVSampleFormat out_fmt,
                                      enum AVSampleFormat in_fmt,
-                                     int channels, int sample_rate)
+                                     int channels, int sample_rate,
+                                     int apply_map)
 {
     AudioConvert *ac;
     int in_planar, out_planar;
@@ -273,11 +274,13 @@ AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
     ac->out_fmt  = out_fmt;
     ac->in_fmt   = in_fmt;
     ac->channels = channels;
+    ac->apply_map = apply_map;
 
     if (avr->dither_method != AV_RESAMPLE_DITHER_NONE          &&
         av_get_packed_sample_fmt(out_fmt) == AV_SAMPLE_FMT_S16 &&
         av_get_bytes_per_sample(in_fmt) > 2) {
-        ac->dc = ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate);
+        ac->dc = ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate,
+                                 apply_map);
         if (!ac->dc) {
             av_free(ac);
             return NULL;
@@ -310,6 +313,7 @@ int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
 {
     int use_generic = 1;
     int len         = in->nb_samples;
+    int p;
 
     if (ac->dc) {
         /* dithered conversion */
@@ -336,32 +340,73 @@ int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
             av_get_sample_fmt_name(ac->out_fmt),
             use_generic ? ac->func_descr_generic : ac->func_descr);
 
-    switch (ac->func_type) {
-    case CONV_FUNC_TYPE_FLAT: {
-        int p;
-        if (!in->is_planar)
-            len *= in->channels;
-        if (use_generic) {
-            for (p = 0; p < ac->planes; p++)
-                ac->conv_flat_generic(out->data[p], in->data[p], len);
-        } else {
-            for (p = 0; p < ac->planes; p++)
-                ac->conv_flat(out->data[p], in->data[p], len);
+    if (ac->apply_map) {
+        ChannelMapInfo *map = &ac->avr->ch_map_info;
+
+        if (!av_sample_fmt_is_planar(ac->out_fmt)) {
+            av_log(ac->avr, AV_LOG_ERROR, "cannot remap packed format during conversion\n");
+            return AVERROR(EINVAL);
+        }
+
+        if (map->do_remap) {
+            if (av_sample_fmt_is_planar(ac->in_fmt)) {
+                conv_func_flat *convert = use_generic ? ac->conv_flat_generic :
+                                                        ac->conv_flat;
+
+                for (p = 0; p < ac->planes; p++)
+                    if (map->channel_map[p] >= 0)
+                        convert(out->data[p], in->data[map->channel_map[p]], len);
+            } else {
+                uint8_t *data[AVRESAMPLE_MAX_CHANNELS];
+                conv_func_deinterleave *convert = use_generic ?
+                                                  ac->conv_deinterleave_generic :
+                                                  ac->conv_deinterleave;
+
+                for (p = 0; p < ac->channels; p++)
+                    data[map->input_map[p]] = out->data[p];
+
+                convert(data, in->data[0], len, ac->channels);
+            }
+        }
+        if (map->do_copy || map->do_zero) {
+            for (p = 0; p < ac->planes; p++) {
+                if (map->channel_copy[p])
+                    memcpy(out->data[p], out->data[map->channel_copy[p]],
+                           len * out->stride);
+                else if (map->channel_zero[p])
+                    av_samples_set_silence(&out->data[p], 0, len, 1, ac->out_fmt);
+            }
+        }
+    } else {
+        switch (ac->func_type) {
+        case CONV_FUNC_TYPE_FLAT: {
+            if (!in->is_planar)
+                len *= in->channels;
+            if (use_generic) {
+                for (p = 0; p < ac->planes; p++)
+                    ac->conv_flat_generic(out->data[p], in->data[p], len);
+            } else {
+                for (p = 0; p < ac->planes; p++)
+                    ac->conv_flat(out->data[p], in->data[p], len);
+            }
+            break;
+        }
+        case CONV_FUNC_TYPE_INTERLEAVE:
+            if (use_generic)
+                ac->conv_interleave_generic(out->data[0], in->data, len,
+                                            ac->channels);
+            else
+                ac->conv_interleave(out->data[0], in->data, len, ac->channels);
+            break;
+        case CONV_FUNC_TYPE_DEINTERLEAVE:
+            if (use_generic)
+                ac->conv_deinterleave_generic(out->data, in->data[0], len,
+                                              ac->channels);
+            else
+                ac->conv_deinterleave(out->data, in->data[0], len,
+                                      ac->channels);
+            break;
         }
-        break;
-    }
-    case CONV_FUNC_TYPE_INTERLEAVE:
-        if (use_generic)
-            ac->conv_interleave_generic(out->data[0], in->data, len, ac->channels);
-        else
-            ac->conv_interleave(out->data[0], in->data, len, ac->channels);
-        break;
-    case CONV_FUNC_TYPE_DEINTERLEAVE:
-        if (use_generic)
-            ac->conv_deinterleave_generic(out->data, in->data[0], len, ac->channels);
-        else
-            ac->conv_deinterleave(out->data, in->data[0], len, ac->channels);
-        break;
     }
 
     out->nb_samples = in->nb_samples;
diff --git a/libavresample/audio_convert.h b/libavresample/audio_convert.h
index b8808f1..6a3089d 100644
--- a/libavresample/audio_convert.h
+++ b/libavresample/audio_convert.h
@@ -23,10 +23,9 @@
 
 #include "libavutil/samplefmt.h"
 #include "avresample.h"
+#include "internal.h"
 #include "audio_data.h"
 
-typedef struct AudioConvert AudioConvert;
-
 /**
  * Set conversion function if the parameters match.
  *
@@ -59,12 +58,14 @@ void ff_audio_convert_set_func(AudioConvert *ac, enum AVSampleFormat out_fmt,
  * @param in_fmt      input sample format
  * @param channels    number of channels
  * @param sample_rate sample rate (used for dithering)
+ * @param apply_map   apply channel map during conversion
  * @return            newly-allocated AudioConvert context
  */
 AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
                                      enum AVSampleFormat out_fmt,
                                      enum AVSampleFormat in_fmt,
-                                     int channels, int sample_rate);
+                                     int channels, int sample_rate,
+                                     int apply_map);
 
 /**
  * Free AudioConvert.
diff --git a/libavresample/audio_data.c b/libavresample/audio_data.c
index 199a68c..c52f518 100644
--- a/libavresample/audio_data.c
+++ b/libavresample/audio_data.c
@@ -213,7 +213,7 @@ void ff_audio_data_free(AudioData **a)
     av_freep(a);
 }
 
-int ff_audio_data_copy(AudioData *dst, AudioData *src)
+int ff_audio_data_copy(AudioData *dst, AudioData *src, ChannelMapInfo *map)
 {
     int ret, p;
 
@@ -221,6 +221,11 @@ int ff_audio_data_copy(AudioData *dst, AudioData *src)
     if (dst->sample_fmt != src->sample_fmt || dst->channels < src->channels)
         return AVERROR(EINVAL);
 
+    if (map && !src->is_planar) {
+        av_log(src, AV_LOG_ERROR, "cannot remap packed format during copy\n");
+        return AVERROR(EINVAL);
+    }
+
     /* if the input is empty, just empty the output */
     if (!src->nb_samples) {
         dst->nb_samples = 0;
@@ -233,8 +238,29 @@ int ff_audio_data_copy(AudioData *dst, AudioData *src)
         return ret;
 
     /* copy data */
-    for (p = 0; p < src->planes; p++)
-        memcpy(dst->data[p], src->data[p], src->nb_samples * src->stride);
+    if (map) {
+        if (map->do_remap) {
+            for (p = 0; p < src->planes; p++) {
+                if (map->channel_map[p] >= 0)
+                    memcpy(dst->data[p], src->data[map->channel_map[p]],
+                           src->nb_samples * src->stride);
+            }
+        }
+        if (map->do_copy || map->do_zero) {
+            for (p = 0; p < src->planes; p++) {
+                if (map->channel_copy[p])
+                    memcpy(dst->data[p], dst->data[map->channel_copy[p]],
+                           src->nb_samples * src->stride);
+                else if (map->channel_zero[p])
+                    av_samples_set_silence(&dst->data[p], 0, src->nb_samples,
+                                           1, dst->sample_fmt);
+            }
+        }
+    } else {
+        for (p = 0; p < src->planes; p++)
+            memcpy(dst->data[p], src->data[p], src->nb_samples * src->stride);
+    }
+
     dst->nb_samples = src->nb_samples;
 
     return 0;
diff --git a/libavresample/audio_data.h b/libavresample/audio_data.h
index 558e7e6..97236bb 100644
--- a/libavresample/audio_data.h
+++ b/libavresample/audio_data.h
@@ -27,11 +27,12 @@
 #include "libavutil/log.h"
 #include "libavutil/samplefmt.h"
 #include "avresample.h"
+#include "internal.h"
 
 /**
  * Audio buffer used for intermediate storage between conversion phases.
  */
-typedef struct AudioData {
+struct AudioData {
     const AVClass *class;               /**< AVClass for logging            */
     uint8_t *data[AVRESAMPLE_MAX_CHANNELS]; /**< data plane pointers        */
     uint8_t *buffer;                    /**< data buffer                    */
@@ -50,7 +51,7 @@ typedef struct AudioData {
     int ptr_align;                      /**< minimum data pointer alignment */
     int samples_align;                  /**< allocated samples alignment    */
     const char *name;                   /**< name for debug logging         */
-} AudioData;
+};
 
 int ff_audio_data_set_channels(AudioData *a, int channels);
 
@@ -117,9 +118,10 @@ void ff_audio_data_free(AudioData **a);
  *
  * @param out  output AudioData
  * @param in   input AudioData
+ * @param map  channel map, NULL if not remapping
  * @return     0 on success, negative AVERROR value on error
  */
-int ff_audio_data_copy(AudioData *out, AudioData *in);
+int ff_audio_data_copy(AudioData *out, AudioData *in, ChannelMapInfo *map);
 
 /**
  * Append data from one AudioData to the end of another.
diff --git a/libavresample/audio_mix.c b/libavresample/audio_mix.c
index c056028..073609e 100644
--- a/libavresample/audio_mix.c
+++ b/libavresample/audio_mix.c
@@ -47,6 +47,11 @@ struct AudioMix {
     mix_func *mix;
     mix_func *mix_generic;
 
+    int in_matrix_channels;
+    int out_matrix_channels;
+    int output_zero[AVRESAMPLE_MAX_CHANNELS];
+    int input_skip[AVRESAMPLE_MAX_CHANNELS];
+    int output_skip[AVRESAMPLE_MAX_CHANNELS];
     int16_t *matrix_q8[AVRESAMPLE_MAX_CHANNELS];
     int32_t *matrix_q15[AVRESAMPLE_MAX_CHANNELS];
     float   *matrix_flt[AVRESAMPLE_MAX_CHANNELS];
@@ -59,8 +64,8 @@ void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt,
                            const char *descr, void *mix_func)
 {
     if (fmt == am->fmt && coeff_type == am->coeff_type &&
-        ( in_channels ==  am->in_channels ||  in_channels == 0) &&
-        (out_channels == am->out_channels || out_channels == 0)) {
+        ( in_channels ==  am->in_matrix_channels ||  in_channels == 0) &&
+        (out_channels == am->out_matrix_channels || out_channels == 0)) {
         char chan_str[16];
         am->mix           = mix_func;
         am->func_descr    = descr;
@@ -82,11 +87,12 @@ void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt,
         } else if (out_channels) {
                 snprintf(chan_str, sizeof(chan_str), "[any to %d] ",
                          out_channels);
+        } else {
+            snprintf(chan_str, sizeof(chan_str), "[any to any] ");
         }
         av_log(am->avr, AV_LOG_DEBUG, "audio_mix: found function: [fmt=%s] "
                "[c=%s] %s(%s)\n", av_get_sample_fmt_name(fmt),
-               coeff_type_names[coeff_type],
-               (in_channels || out_channels) ? chan_str : "", descr);
+               coeff_type_names[coeff_type], chan_str, descr);
     }
 }
 
@@ -195,23 +201,23 @@ static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len,
 
     while (len > 4) {
         v = *src++;
-        *dst0++ = v * m1;
-        *dst1++ = v * m0;
+        *dst0++ = v * m0;
+        *dst1++ = v * m1;
         v = *src++;
-        *dst0++ = v * m1;
-        *dst1++ = v * m0;
+        *dst0++ = v * m0;
+        *dst1++ = v * m1;
         v = *src++;
-        *dst0++ = v * m1;
-        *dst1++ = v * m0;
+        *dst0++ = v * m0;
+        *dst1++ = v * m1;
         v = *src++;
-        *dst0++ = v * m1;
-        *dst1++ = v * m0;
+        *dst0++ = v * m0;
+        *dst1++ = v * m1;
         len -= 4;
     }
     while (len > 0) {
         v = *src++;
-        *dst0++ = v * m1;
-        *dst1++ = v * m0;
+        *dst0++ = v * m0;
+        *dst1++ = v * m1;
         len--;
     }
 }
@@ -276,8 +282,15 @@ static void mix_2_to_6_fltp_flt_c(float **samples, float **matrix, int len,
     }
 }
 
-static int mix_function_init(AudioMix *am)
+static av_cold int mix_function_init(AudioMix *am)
 {
+    am->func_descr = am->func_descr_generic = "n/a";
+    am->mix = am->mix_generic = NULL;
+
+    /* no need to set a mix function when we're skipping mixing */
+    if (!am->in_matrix_channels || !am->out_matrix_channels)
+        return 0;
+
     /* any-to-any C versions */
 
     ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
@@ -357,9 +370,6 @@ AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr)
             goto error;
         av_freep(&avr->mix_matrix);
     } else {
-        int i, j;
-        char in_layout_name[128];
-        char out_layout_name[128];
         double *matrix_dbl = av_mallocz(avr->out_channels * avr->in_channels *
                                         sizeof(*matrix_dbl));
         if (!matrix_dbl)
@@ -379,25 +389,13 @@ AudioMix *ff_audio_mix_alloc(AVAudioResampleContext *avr)
             goto error;
         }
 
-        av_get_channel_layout_string(in_layout_name, sizeof(in_layout_name),
-                                     avr->in_channels, avr->in_channel_layout);
-        av_get_channel_layout_string(out_layout_name, sizeof(out_layout_name),
-                                     avr->out_channels, avr->out_channel_layout);
-        av_log(avr, AV_LOG_DEBUG, "audio_mix: %s to %s\n",
-               in_layout_name, out_layout_name);
-        for (i = 0; i < avr->out_channels; i++) {
-            for (j = 0; j < avr->in_channels; j++) {
-                av_log(avr, AV_LOG_DEBUG, "  %0.3f ",
-                       matrix_dbl[i * avr->in_channels + j]);
-            }
-            av_log(avr, AV_LOG_DEBUG, "\n");
-        }
-
         ret = ff_audio_mix_set_matrix(am, matrix_dbl, avr->in_channels);
         if (ret < 0) {
+            av_log(avr, AV_LOG_ERROR, "error setting mix matrix\n");
             av_free(matrix_dbl);
             goto error;
         }
+
         av_free(matrix_dbl);
     }
 
@@ -431,6 +429,7 @@ int ff_audio_mix(AudioMix *am, AudioData *src)
 {
     int use_generic = 1;
     int len = src->nb_samples;
+    int i, j;
 
     /* determine whether to use the optimized function based on pointer and
        samples alignment in both the input and output */
@@ -446,11 +445,35 @@ int ff_audio_mix(AudioMix *am, AudioData *src)
             src->nb_samples, am->in_channels, am->out_channels,
             use_generic ? am->func_descr_generic : am->func_descr);
 
-    if (use_generic)
-        am->mix_generic(src->data, am->matrix, len, am->out_channels,
-                        am->in_channels);
-    else
-        am->mix(src->data, am->matrix, len, am->out_channels, am->in_channels);
+    if (am->in_matrix_channels && am->out_matrix_channels) {
+        uint8_t **data;
+        uint8_t *data0[AVRESAMPLE_MAX_CHANNELS];
+
+        if (am->out_matrix_channels < am->out_channels ||
+             am->in_matrix_channels <  am->in_channels) {
+            for (i = 0, j = 0; i < FFMAX(am->in_channels, am->out_channels); i++) {
+                if (am->input_skip[i] || am->output_skip[i] || am->output_zero[i])
+                    continue;
+                data0[j++] = src->data[i];
+            }
+            data = data0;
+        } else {
+            data = src->data;
+        }
+
+        if (use_generic)
+            am->mix_generic(data, am->matrix, len, am->out_matrix_channels,
+                            am->in_matrix_channels);
+        else
+            am->mix(data, am->matrix, len, am->out_matrix_channels,
+                    am->in_matrix_channels);
+    }
+
+    if (am->out_matrix_channels < am->out_channels) {
+        for (i = 0; i < am->out_channels; i++)
+            if (am->output_zero[i])
+                av_samples_set_silence(&src->data[i], 0, len, 1, am->fmt);
+    }
 
     ff_audio_data_set_channels(src, am->out_channels);
 
@@ -459,7 +482,7 @@ int ff_audio_mix(AudioMix *am, AudioData *src)
 
 int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
 {
-    int i, o;
+    int i, o, i0, o0;
 
     if ( am->in_channels <= 0 ||  am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
         am->out_channels <= 0 || am->out_channels > AVRESAMPLE_MAX_CHANNELS) {
@@ -472,9 +495,19 @@ int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
         av_log(am->avr, AV_LOG_ERROR, "matrix is not set\n");               \
         return AVERROR(EINVAL);                                             \
     }                                                                       \
-    for (o = 0; o < am->out_channels; o++)                                  \
-        for (i = 0; i < am->in_channels; i++)                               \
-            matrix[o * stride + i] = am->matrix_ ## suffix[o][i] * (scale);
+    for (o = 0, o0 = 0; o < am->out_channels; o++) {                        \
+        for (i = 0, i0 = 0; i < am->in_channels; i++) {                     \
+            if (am->input_skip[i] || am->output_zero[o])                    \
+                matrix[o * stride + i] = 0.0;                               \
+            else                                                            \
+                matrix[o * stride + i] = am->matrix_ ## suffix[o0][i0] *    \
+                                         (scale);                           \
+            if (!am->input_skip[i])                                         \
+                i0++;                                                       \
+        }                                                                   \
+        if (!am->output_zero[o])                                            \
+            o0++;                                                           \
+    }
 
     switch (am->coeff_type) {
     case AV_MIX_COEFF_TYPE_Q8:
@@ -494,10 +527,132 @@ int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
     return 0;
 }
 
-int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
+static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
 {
     int i, o;
 
+    memset(am->output_zero, 0, sizeof(am->output_zero));
+    memset(am->input_skip,  0, sizeof(am->input_skip));
+    memset(am->output_skip, 0, sizeof(am->output_skip));
+
+    /* exclude output channels if they can be zeroed instead of mixed */
+    for (o = 0; o < am->out_channels; o++) {
+        int zero = 1;
+
+        /* check if the output is always silent */
+        for (i = 0; i < am->in_channels; i++) {
+            if (matrix[o * stride + i] != 0.0) {
+                zero = 0;
+                break;
+            }
+        }
+        /* check if the corresponding input channel makes a contribution to
+           any output channel */
+        if (o < am->in_channels) {
+            for (i = 0; i < am->out_channels; i++) {
+                if (matrix[i * stride + o] != 0.0) {
+                    zero = 0;
+                    break;
+                }
+            }
+        }
+        if (zero) {
+            am->output_zero[o] = 1;
+            am->out_matrix_channels--;
+        }
+    }
+    if (am->out_matrix_channels == 0) {
+        am->in_matrix_channels = 0;
+        return;
+    }
+
+    /* skip input channels that contribute fully only to the corresponding
+       output channel */
+    for (i = 0; i < FFMIN(am->in_channels, am->out_channels); i++) {
+        int skip = 1;
+
+        for (o = 0; o < am->out_channels; o++) {
+            int i0;
+            if ((o != i && matrix[o * stride + i] != 0.0) ||
+                (o == i && matrix[o * stride + i] != 1.0)) {
+                skip = 0;
+                break;
+            }
+            /* if the input contributes fully to the output, also check that no
+               other inputs contribute to this output */
+            if (o == i) {
+                for (i0 = 0; i0 < am->in_channels; i0++) {
+                    if (i0 != i && matrix[o * stride + i0] != 0.0) {
+                        skip = 0;
+                        break;
+                    }
+                }
+            }
+        }
+        if (skip) {
+            am->input_skip[i] = 1;
+            am->in_matrix_channels--;
+        }
+    }
+    /* skip input channels that do not contribute to any output channel */
+    for (; i < am->in_channels; i++) {
+        int contrib = 0;
+
+        for (o = 0; o < am->out_channels; o++) {
+            if (matrix[o * stride + i] != 0.0) {
+                contrib = 1;
+                break;
+            }
+        }
+        if (!contrib) {
+            am->input_skip[i] = 1;
+            am->in_matrix_channels--;
+        }
+    }
+    if (am->in_matrix_channels == 0) {
+        am->out_matrix_channels = 0;
+        return;
+    }
+
+    /* skip output channels that only get full contribution from the
+       corresponding input channel */
+    for (o = 0; o < FFMIN(am->in_channels, am->out_channels); o++) {
+        int skip = 1;
+        int o0;
+
+        for (i = 0; i < am->in_channels; i++) {
+            if ((o != i && matrix[o * stride + i] != 0.0) ||
+                (o == i && matrix[o * stride + i] != 1.0)) {
+                skip = 0;
+                break;
+            }
+        }
+        /* check if the corresponding input channel makes a contribution to
+           any other output channel */
+        i = o;
+        for (o0 = 0; o0 < am->out_channels; o0++) {
+            if (o0 != i && matrix[o0 * stride + i] != 0.0) {
+                skip = 0;
+                break;
+            }
+        }
+        if (skip) {
+            am->output_skip[o] = 1;
+            am->out_matrix_channels--;
+        }
+    }
+    if (am->out_matrix_channels == 0) {
+        am->in_matrix_channels = 0;
+        return;
+    }
+}
+
+int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
+{
+    int i, o, i0, o0, ret;
+    char in_layout_name[128];
+    char out_layout_name[128];
+
     if ( am->in_channels <= 0 ||  am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
         am->out_channels <= 0 || am->out_channels > AVRESAMPLE_MAX_CHANNELS) {
         av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
@@ -509,36 +664,76 @@ int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
         am->matrix = NULL;
     }
 
+    am->in_matrix_channels  = am->in_channels;
+    am->out_matrix_channels = am->out_channels;
+
+    reduce_matrix(am, matrix, stride);
+
 #define CONVERT_MATRIX(type, expr)                                          \
-    am->matrix_## type[0] = av_mallocz(am->out_channels * am->in_channels * \
+    am->matrix_## type[0] = av_mallocz(am->out_matrix_channels *            \
+                                       am->in_matrix_channels  *            \
                                        sizeof(*am->matrix_## type[0]));     \
     if (!am->matrix_## type[0])                                             \
         return AVERROR(ENOMEM);                                             \
-    for (o = 0; o < am->out_channels; o++) {                                \
-        if (o > 0)                                                          \
-            am->matrix_## type[o] = am->matrix_## type[o - 1] +             \
-                                    am->in_channels;                        \
-        for (i = 0; i < am->in_channels; i++) {                             \
-            double v = matrix[o * stride + i];                              \
-            am->matrix_## type[o][i] = expr;                                \
+    for (o = 0, o0 = 0; o < am->out_channels; o++) {                        \
+        if (am->output_zero[o] || am->output_skip[o])                       \
+            continue;                                                       \
+        if (o0 > 0)                                                         \
+            am->matrix_## type[o0] = am->matrix_## type[o0 - 1] +           \
+                                     am->in_matrix_channels;                \
+        for (i = 0, i0 = 0; i < am->in_channels; i++) {                     \
+            double v;                                                       \
+            if (am->input_skip[i])                                          \
+                continue;                                                   \
+            v = matrix[o * stride + i];                                     \
+            am->matrix_## type[o0][i0] = expr;                              \
+            i0++;                                                           \
         }                                                                   \
+        o0++;                                                               \
     }                                                                       \
     am->matrix = (void **)am->matrix_## type;
 
-    switch (am->coeff_type) {
-    case AV_MIX_COEFF_TYPE_Q8:
-        CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
-        break;
-    case AV_MIX_COEFF_TYPE_Q15:
-        CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
-        break;
-    case AV_MIX_COEFF_TYPE_FLT:
-        CONVERT_MATRIX(flt, v)
-        break;
-    default:
-        av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
-        return AVERROR(EINVAL);
+    if (am->in_matrix_channels && am->out_matrix_channels) {
+        switch (am->coeff_type) {
+        case AV_MIX_COEFF_TYPE_Q8:
+            CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
+            break;
+        case AV_MIX_COEFF_TYPE_Q15:
+            CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
+            break;
+        case AV_MIX_COEFF_TYPE_FLT:
+            CONVERT_MATRIX(flt, v)
+            break;
+        default:
+            av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
+            return AVERROR(EINVAL);
+        }
     }
 
-    return mix_function_init(am);
+    ret = mix_function_init(am);
+    if (ret < 0)
+        return ret;
+
+    av_get_channel_layout_string(in_layout_name, sizeof(in_layout_name),
+                                 am->in_channels, am->in_layout);
+    av_get_channel_layout_string(out_layout_name, sizeof(out_layout_name),
+                                 am->out_channels, am->out_layout);
+    av_log(am->avr, AV_LOG_DEBUG, "audio_mix: %s to %s\n",
+           in_layout_name, out_layout_name);
+    av_log(am->avr, AV_LOG_DEBUG, "matrix size: %d x %d\n",
+           am->in_matrix_channels, am->out_matrix_channels);
+    for (o = 0; o < am->out_channels; o++) {
+        for (i = 0; i < am->in_channels; i++) {
+            if (am->output_zero[o])
+                av_log(am->avr, AV_LOG_DEBUG, "  (ZERO)");
+            else if (am->input_skip[i] || am->output_skip[o])
+                av_log(am->avr, AV_LOG_DEBUG, "  (SKIP)");
+            else
+                av_log(am->avr, AV_LOG_DEBUG, "  %0.3f ",
+                       matrix[o * am->in_channels + i]);
+        }
+        av_log(am->avr, AV_LOG_DEBUG, "\n");
+    }
+
+    return 0;
 }
diff --git a/libavresample/audio_mix.h b/libavresample/audio_mix.h
index 4ccfc1f..5bae5ab 100644
--- a/libavresample/audio_mix.h
+++ b/libavresample/audio_mix.h
@@ -25,13 +25,12 @@
 
 #include "libavutil/samplefmt.h"
 #include "avresample.h"
+#include "internal.h"
 #include "audio_data.h"
 
 typedef void (mix_func)(uint8_t **src, void **matrix, int len, int out_ch,
                         int in_ch);
 
-typedef struct AudioMix AudioMix;
-
 /**
  * Set mixing function if the parameters match.
  *
diff --git a/libavresample/avresample-test.c b/libavresample/avresample-test.c
index 81e9bf0..697b4ba 100644
--- a/libavresample/avresample-test.c
+++ b/libavresample/avresample-test.c
@@ -91,7 +91,7 @@ static void audiogen(AVLFG *rnd, void **data, enum AVSampleFormat sample_fmt,
 
     k = 0;
 
-    /* 1 second of single freq sinus at 1000 Hz */
+    /* 1 second of single freq sine at 1000 Hz */
     a = 0;
     for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
         v = sin(a) * 0.30;
diff --git a/libavresample/avresample.h b/libavresample/avresample.h
index 0012787..d26f2ca 100644
--- a/libavresample/avresample.h
+++ b/libavresample/avresample.h
@@ -259,6 +259,36 @@ int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
                           int stride);
 
 /**
+ * Set a customized input channel mapping.
+ *
+ * This function can only be called when the allocated context is not open.
+ * Also, the input channel layout must have already been set.
+ *
+ * Calling avresample_close() on the context will clear the channel mapping.
+ *
+ * The map for each input channel specifies the channel index in the source to
+ * use for that particular channel, or -1 to mute the channel. Source channels
+ * can be duplicated by using the same index for multiple input channels.
+ *
+ * Examples:
+ *
+ * Reordering 5.1 AAC order (C,L,R,Ls,Rs,LFE) to Libav order (L,R,C,LFE,Ls,Rs):
+ * { 1, 2, 0, 5, 3, 4 }
+ *
+ * Muting the 3rd channel in 4-channel input:
+ * { 0, 1, -1, 3 }
+ *
+ * Duplicating the left channel of stereo input:
+ * { 0, 0 }
+ *
+ * @param avr         audio resample context
+ * @param channel_map customized input channel mapping
+ * @return            0 on success, negative AVERROR code on failure
+ */
+int avresample_set_channel_mapping(AVAudioResampleContext *avr,
+                                   const int *channel_map);
+
+/**
  * Set compensation for resampling.
  *
  * This can be called anytime after avresample_open(). If resampling is not
diff --git a/libavresample/dither.c b/libavresample/dither.c
index 9c1e1c1..17de829 100644
--- a/libavresample/dither.c
+++ b/libavresample/dither.c
@@ -31,6 +31,7 @@
 #include <math.h>
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/common.h"
 #include "libavutil/lfg.h"
 #include "libavutil/mem.h"
@@ -53,6 +54,8 @@ typedef struct DitherState {
 struct DitherContext {
     DitherDSPContext  ddsp;
     enum AVResampleDitherMethod method;
+    int apply_map;
+    ChannelMapInfo *ch_map_info;
 
     int mute_dither_threshold;  // threshold for disabling dither
     int mute_reset_threshold;   // threshold for resetting noise shaping
@@ -251,17 +254,23 @@ int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src)
             return ret;
     }
 
-    if (src->sample_fmt != AV_SAMPLE_FMT_FLTP) {
+    if (src->sample_fmt != AV_SAMPLE_FMT_FLTP || c->apply_map) {
         /* make sure flt_data is large enough for the input */
         ret = ff_audio_data_realloc(c->flt_data, src->nb_samples);
         if (ret < 0)
             return ret;
         flt_data = c->flt_data;
+    }
 
+    if (src->sample_fmt != AV_SAMPLE_FMT_FLTP) {
         /* convert input samples to fltp and scale to s16 range */
         ret = ff_audio_convert(c->ac_in, flt_data, src);
         if (ret < 0)
             return ret;
+    } else if (c->apply_map) {
+        ret = ff_audio_data_copy(flt_data, src, c->ch_map_info);
+        if (ret < 0)
+            return ret;
     } else {
         flt_data = src;
     }
@@ -317,8 +326,8 @@ void ff_dither_free(DitherContext **cp)
     av_freep(cp);
 }
 
-static void dither_init(DitherDSPContext *ddsp,
-                        enum AVResampleDitherMethod method)
+static av_cold void dither_init(DitherDSPContext *ddsp,
+                                enum AVResampleDitherMethod method)
 {
     ddsp->quantize      = quantize_c;
     ddsp->ptr_align     = 1;
@@ -328,12 +337,15 @@ static void dither_init(DitherDSPContext *ddsp,
         ddsp->dither_int_to_float = dither_int_to_float_rectangular_c;
     else
         ddsp->dither_int_to_float = dither_int_to_float_triangular_c;
+
+    if (ARCH_X86)
+        ff_dither_init_x86(ddsp, method);
 }
 
 DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
                                enum AVSampleFormat out_fmt,
                                enum AVSampleFormat in_fmt,
-                               int channels, int sample_rate)
+                               int channels, int sample_rate, int apply_map)
 {
     AVLFG seed_gen;
     DitherContext *c;
@@ -350,6 +362,10 @@ DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
     if (!c)
         return NULL;
 
+    c->apply_map = apply_map;
+    if (apply_map)
+        c->ch_map_info = &avr->ch_map_info;
+
     if (avr->dither_method == AV_RESAMPLE_DITHER_TRIANGULAR_NS &&
         sample_rate != 48000 && sample_rate != 44100) {
         av_log(avr, AV_LOG_WARNING, "sample rate must be 48000 or 44100 Hz "
@@ -379,19 +395,20 @@ DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
             goto fail;
 
         c->ac_out = ff_audio_convert_alloc(avr, out_fmt, AV_SAMPLE_FMT_S16P,
-                                           channels, sample_rate);
+                                           channels, sample_rate, 0);
         if (!c->ac_out)
             goto fail;
     }
 
-    if (in_fmt != AV_SAMPLE_FMT_FLTP) {
+    if (in_fmt != AV_SAMPLE_FMT_FLTP || c->apply_map) {
         c->flt_data = ff_audio_data_alloc(channels, 1024, AV_SAMPLE_FMT_FLTP,
                                           "dither flt buffer");
         if (!c->flt_data)
             goto fail;
-
+    }
+    if (in_fmt != AV_SAMPLE_FMT_FLTP) {
         c->ac_in = ff_audio_convert_alloc(avr, AV_SAMPLE_FMT_FLTP, in_fmt,
-                                          channels, sample_rate);
+                                          channels, sample_rate, c->apply_map);
         if (!c->ac_in)
             goto fail;
     }
diff --git a/libavresample/dither.h b/libavresample/dither.h
index 8b30dd2..8db3714 100644
--- a/libavresample/dither.h
+++ b/libavresample/dither.h
@@ -66,7 +66,7 @@ typedef struct DitherDSPContext {
 DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
                                enum AVSampleFormat out_fmt,
                                enum AVSampleFormat in_fmt,
-                               int channels, int sample_rate);
+                               int channels, int sample_rate, int apply_map);
 
 /**
  * Free a DitherContext.
@@ -85,4 +85,9 @@ void ff_dither_free(DitherContext **c);
  */
 int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src);
 
+/* arch-specific initialization functions */
+
+void ff_dither_init_x86(DitherDSPContext *ddsp,
+                        enum AVResampleDitherMethod method);
+
 #endif /* AVRESAMPLE_DITHER_H */
diff --git a/libavresample/internal.h b/libavresample/internal.h
index 2e139ab..057f89a 100644
--- a/libavresample/internal.h
+++ b/libavresample/internal.h
@@ -26,10 +26,29 @@
 #include "libavutil/opt.h"
 #include "libavutil/samplefmt.h"
 #include "avresample.h"
-#include "audio_convert.h"
-#include "audio_data.h"
-#include "audio_mix.h"
-#include "resample.h"
+
+typedef struct AudioData AudioData;
+typedef struct AudioConvert AudioConvert;
+typedef struct AudioMix AudioMix;
+typedef struct ResampleContext ResampleContext;
+
+enum RemapPoint {
+    REMAP_NONE,
+    REMAP_IN_COPY,
+    REMAP_IN_CONVERT,
+    REMAP_OUT_COPY,
+    REMAP_OUT_CONVERT,
+};
+
+typedef struct ChannelMapInfo {
+    int channel_map[AVRESAMPLE_MAX_CHANNELS];   /**< source index of each output channel, -1 if not remapped */
+    int do_remap;                               /**< remap needed */
+    int channel_copy[AVRESAMPLE_MAX_CHANNELS];  /**< dest index to copy from */
+    int do_copy;                                /**< copy needed */
+    int channel_zero[AVRESAMPLE_MAX_CHANNELS];  /**< dest index to zero */
+    int do_zero;                                /**< zeroing needed */
+    int input_map[AVRESAMPLE_MAX_CHANNELS];     /**< dest index of each input channel */
+} ChannelMapInfo;
 
 struct AVAudioResampleContext {
     const AVClass *av_class;        /**< AVClass for logging and AVOptions  */
@@ -64,6 +83,7 @@ struct AVAudioResampleContext {
     int resample_needed;    /**< resampling is needed                       */
     int in_convert_needed;  /**< input sample format conversion is needed   */
     int out_convert_needed; /**< output sample format conversion is needed  */
+    int in_copy_needed;     /**< input data copy is needed                  */
 
     AudioData *in_buffer;           /**< buffer for converted input         */
     AudioData *resample_out_buffer; /**< buffer for output from resampler   */
@@ -81,6 +101,10 @@ struct AVAudioResampleContext {
      * only used if avresample_set_matrix() is called before avresample_open()
      */
     double *mix_matrix;
+
+    int use_channel_map;
+    enum RemapPoint remap_point;
+    ChannelMapInfo ch_map_info;
 };
 
 #endif /* AVRESAMPLE_INTERNAL_H */
diff --git a/libavresample/options.c b/libavresample/options.c
index 68548f0..6249f90 100644
--- a/libavresample/options.c
+++ b/libavresample/options.c
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavutil/mathematics.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
@@ -33,14 +35,24 @@
 #define OFFSET(x) offsetof(AVAudioResampleContext, x)
 #define PARAM AV_OPT_FLAG_AUDIO_PARAM
 
-static const AVOption options[] = {
+static const AVOption avresample_options[] = {
     { "in_channel_layout",      "Input Channel Layout",     OFFSET(in_channel_layout),      AV_OPT_TYPE_INT64,  { .i64 = 0              }, INT64_MIN,            INT64_MAX,              PARAM },
     { "in_sample_fmt",          "Input Sample Format",      OFFSET(in_sample_fmt),          AV_OPT_TYPE_INT,    { .i64 = AV_SAMPLE_FMT_S16 }, AV_SAMPLE_FMT_U8,     AV_SAMPLE_FMT_NB-1,     PARAM },
     { "in_sample_rate",         "Input Sample Rate",        OFFSET(in_sample_rate),         AV_OPT_TYPE_INT,    { .i64 = 48000          }, 1,                    INT_MAX,                PARAM },
     { "out_channel_layout",     "Output Channel Layout",    OFFSET(out_channel_layout),     AV_OPT_TYPE_INT64,  { .i64 = 0              }, INT64_MIN,            INT64_MAX,              PARAM },
     { "out_sample_fmt",         "Output Sample Format",     OFFSET(out_sample_fmt),         AV_OPT_TYPE_INT,    { .i64 = AV_SAMPLE_FMT_S16 }, AV_SAMPLE_FMT_U8,     AV_SAMPLE_FMT_NB-1,     PARAM },
     { "out_sample_rate",        "Output Sample Rate",       OFFSET(out_sample_rate),        AV_OPT_TYPE_INT,    { .i64 = 48000          }, 1,                    INT_MAX,                PARAM },
-    { "internal_sample_fmt",    "Internal Sample Format",   OFFSET(internal_sample_fmt),    AV_OPT_TYPE_INT,    { .i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE,   AV_SAMPLE_FMT_NB-1,     PARAM },
+    { "internal_sample_fmt",    "Internal Sample Format",   OFFSET(internal_sample_fmt),    AV_OPT_TYPE_INT,    { .i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE,   AV_SAMPLE_FMT_NB-1,     PARAM, "internal_sample_fmt" },
+        {"u8" ,  "8-bit unsigned integer",        0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_U8   }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"s16",  "16-bit signed integer",         0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S16  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"s32",  "32-bit signed integer",         0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"flt",  "32-bit float",                  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLT  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"dbl",  "64-bit double",                 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBL  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"u8p" , "8-bit unsigned integer planar", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_U8P  }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"s16p", "16-bit signed integer planar",  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S16P }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"s32p", "32-bit signed integer planar",  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"fltp", "32-bit float planar",           0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
+        {"dblp", "64-bit double planar",          0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, PARAM, "internal_sample_fmt"},
     { "mix_coeff_type",         "Mixing Coefficient Type",  OFFSET(mix_coeff_type),         AV_OPT_TYPE_INT,    { .i64 = AV_MIX_COEFF_TYPE_FLT }, AV_MIX_COEFF_TYPE_Q8, AV_MIX_COEFF_TYPE_NB-1, PARAM, "mix_coeff_type" },
         { "q8",  "16-bit 8.8 Fixed-Point",   0, AV_OPT_TYPE_CONST, { .i64 = AV_MIX_COEFF_TYPE_Q8  }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
         { "q15", "32-bit 17.15 Fixed-Point", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MIX_COEFF_TYPE_Q15 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
@@ -54,6 +66,8 @@ static const AVOption options[] = {
     { "phase_shift",            "Resampling Phase Shift",   OFFSET(phase_shift),            AV_OPT_TYPE_INT,    { .i64 = 10             }, 0,                    30, /* ??? */           PARAM },
     { "linear_interp",          "Use Linear Interpolation", OFFSET(linear_interp),          AV_OPT_TYPE_INT,    { .i64 = 0              }, 0,                    1,                      PARAM },
     { "cutoff",                 "Cutoff Frequency Ratio",   OFFSET(cutoff),                 AV_OPT_TYPE_DOUBLE, { .dbl = 0.8            }, 0.0,                  1.0,                    PARAM },
+    /* duplicate option in order to work with avconv */
+    { "resample_cutoff",        "Cutoff Frequency Ratio",   OFFSET(cutoff),                 AV_OPT_TYPE_DOUBLE, { .dbl = 0.8            }, 0.0,                  1.0,                    PARAM },
     { "matrix_encoding",        "Matrixed Stereo Encoding", OFFSET(matrix_encoding),        AV_OPT_TYPE_INT,    {.i64 =  AV_MATRIX_ENCODING_NONE}, AV_MATRIX_ENCODING_NONE,     AV_MATRIX_ENCODING_NB-1, PARAM, "matrix_encoding" },
         { "none",  "None",               0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_NONE  }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
         { "dolby", "Dolby",              0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
@@ -75,7 +89,7 @@ static const AVOption options[] = {
 static const AVClass av_resample_context_class = {
     .class_name = "AVAudioResampleContext",
     .item_name  = av_default_item_name,
-    .option     = options,
+    .option     = avresample_options,
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
diff --git a/libavresample/resample.c b/libavresample/resample.c
index dc121fe..69c9bab 100644
--- a/libavresample/resample.c
+++ b/libavresample/resample.c
@@ -23,6 +23,7 @@
 #include "libavutil/libm.h"
 #include "libavutil/log.h"
 #include "internal.h"
+#include "resample.h"
 #include "audio_data.h"
 
 struct ResampleContext {
diff --git a/libavresample/resample.h b/libavresample/resample.h
index 7534e26..4544dab 100644
--- a/libavresample/resample.h
+++ b/libavresample/resample.h
@@ -22,10 +22,9 @@
 #define AVRESAMPLE_RESAMPLE_H
 
 #include "avresample.h"
+#include "internal.h"
 #include "audio_data.h"
 
-typedef struct ResampleContext ResampleContext;
-
 /**
  * Allocate and initialize a ResampleContext.
  *
diff --git a/libavresample/utils.c b/libavresample/utils.c
index ed7f470..2dd3d06 100644
--- a/libavresample/utils.c
+++ b/libavresample/utils.c
@@ -26,8 +26,11 @@
 #include "libavutil/opt.h"
 
 #include "avresample.h"
-#include "audio_data.h"
 #include "internal.h"
+#include "audio_data.h"
+#include "audio_convert.h"
+#include "audio_mix.h"
+#include "resample.h"
 
 int avresample_open(AVAudioResampleContext *avr)
 {
@@ -93,20 +96,84 @@ int avresample_open(AVAudioResampleContext *avr)
                av_get_sample_fmt_name(avr->internal_sample_fmt));
     }
 
-    /* set sample format conversion parameters */
+    /* treat all mono as planar for easier comparison */
     if (avr->in_channels == 1)
         avr->in_sample_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);
     if (avr->out_channels == 1)
         avr->out_sample_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
-    avr->in_convert_needed = (avr->resample_needed || avr->mixing_needed) &&
-                              avr->in_sample_fmt != avr->internal_sample_fmt;
+
+    /* we may need to add an extra conversion in order to remap channels if
+       the output format is not planar */
+    if (avr->use_channel_map && !avr->mixing_needed && !avr->resample_needed &&
+        !av_sample_fmt_is_planar(avr->out_sample_fmt)) {
+        avr->internal_sample_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
+    }
+
+    /* set sample format conversion parameters */
     if (avr->resample_needed || avr->mixing_needed)
+        avr->in_convert_needed = avr->in_sample_fmt != avr->internal_sample_fmt;
+    else
+        avr->in_convert_needed = avr->use_channel_map &&
+                                 !av_sample_fmt_is_planar(avr->out_sample_fmt);
+
+    if (avr->resample_needed || avr->mixing_needed || avr->in_convert_needed)
         avr->out_convert_needed = avr->internal_sample_fmt != avr->out_sample_fmt;
     else
         avr->out_convert_needed = avr->in_sample_fmt != avr->out_sample_fmt;
 
+    avr->in_copy_needed = !avr->in_convert_needed && (avr->mixing_needed ||
+                          (avr->use_channel_map && avr->resample_needed));
+
+    if (avr->use_channel_map) {
+        if (avr->in_copy_needed) {
+            avr->remap_point = REMAP_IN_COPY;
+            av_dlog(avr, "remap channels during in_copy\n");
+        } else if (avr->in_convert_needed) {
+            avr->remap_point = REMAP_IN_CONVERT;
+            av_dlog(avr, "remap channels during in_convert\n");
+        } else if (avr->out_convert_needed) {
+            avr->remap_point = REMAP_OUT_CONVERT;
+            av_dlog(avr, "remap channels during out_convert\n");
+        } else {
+            avr->remap_point = REMAP_OUT_COPY;
+            av_dlog(avr, "remap channels during out_copy\n");
+        }
+
+#ifdef DEBUG
+        {
+            int ch;
+            av_dlog(avr, "output map: ");
+            if (avr->ch_map_info.do_remap)
+                for (ch = 0; ch < avr->in_channels; ch++)
+                    av_dlog(avr, " % 2d", avr->ch_map_info.channel_map[ch]);
+            else
+                av_dlog(avr, "n/a");
+            av_dlog(avr, "\n");
+            av_dlog(avr, "copy map:   ");
+            if (avr->ch_map_info.do_copy)
+                for (ch = 0; ch < avr->in_channels; ch++)
+                    av_dlog(avr, " % 2d", avr->ch_map_info.channel_copy[ch]);
+            else
+                av_dlog(avr, "n/a");
+            av_dlog(avr, "\n");
+            av_dlog(avr, "zero map:   ");
+            if (avr->ch_map_info.do_zero)
+                for (ch = 0; ch < avr->in_channels; ch++)
+                    av_dlog(avr, " % 2d", avr->ch_map_info.channel_zero[ch]);
+            else
+                av_dlog(avr, "n/a");
+            av_dlog(avr, "\n");
+            av_dlog(avr, "input map:  ");
+            for (ch = 0; ch < avr->in_channels; ch++)
+                av_dlog(avr, " % 2d", avr->ch_map_info.input_map[ch]);
+            av_dlog(avr, "\n");
+        }
+#endif
+    } else
+        avr->remap_point = REMAP_NONE;
+
     /* allocate buffers */
-    if (avr->mixing_needed || avr->in_convert_needed) {
+    if (avr->in_copy_needed || avr->in_convert_needed) {
         avr->in_buffer = ff_audio_data_alloc(FFMAX(avr->in_channels, avr->out_channels),
                                              0, avr->internal_sample_fmt,
                                              "in_buffer");
@@ -143,7 +210,8 @@ int avresample_open(AVAudioResampleContext *avr)
     if (avr->in_convert_needed) {
         avr->ac_in = ff_audio_convert_alloc(avr, avr->internal_sample_fmt,
                                             avr->in_sample_fmt, avr->in_channels,
-                                            avr->in_sample_rate);
+                                            avr->in_sample_rate,
+                                            avr->remap_point == REMAP_IN_CONVERT);
         if (!avr->ac_in) {
             ret = AVERROR(ENOMEM);
             goto error;
@@ -157,7 +225,8 @@ int avresample_open(AVAudioResampleContext *avr)
             src_fmt = avr->in_sample_fmt;
         avr->ac_out = ff_audio_convert_alloc(avr, avr->out_sample_fmt, src_fmt,
                                              avr->out_channels,
-                                             avr->out_sample_rate);
+                                             avr->out_sample_rate,
+                                             avr->remap_point == REMAP_OUT_CONVERT);
         if (!avr->ac_out) {
             ret = AVERROR(ENOMEM);
             goto error;
@@ -197,6 +266,8 @@ void avresample_close(AVAudioResampleContext *avr)
     ff_audio_resample_free(&avr->resample);
     ff_audio_mix_free(&avr->am);
     av_freep(&avr->mix_matrix);
+
+    avr->use_channel_map = 0;
 }
 
 void avresample_free(AVAudioResampleContext **avr)
@@ -239,7 +310,9 @@ static int handle_buffered_output(AVAudioResampleContext *avr,
            data in the output FIFO */
         av_dlog(avr, "[copy] %s to output\n", converted->name);
         output->nb_samples = 0;
-        ret = ff_audio_data_copy(output, converted);
+        ret = ff_audio_data_copy(output, converted,
+                                 avr->remap_point == REMAP_OUT_COPY ?
+                                 &avr->ch_map_info : NULL);
         if (ret < 0)
             return ret;
         av_dlog(avr, "[end conversion]\n");
@@ -303,11 +376,24 @@ int attribute_align_arg avresample_convert(AVAudioResampleContext *avr,
             /* in some rare cases we can copy input to output and upmix
                directly in the output buffer */
             av_dlog(avr, "[copy] %s to output\n", current_buffer->name);
-            ret = ff_audio_data_copy(&output_buffer, current_buffer);
+            ret = ff_audio_data_copy(&output_buffer, current_buffer,
+                                     avr->remap_point == REMAP_OUT_COPY ?
+                                     &avr->ch_map_info : NULL);
             if (ret < 0)
                 return ret;
             current_buffer = &output_buffer;
-        } else if (avr->mixing_needed || avr->in_convert_needed) {
+        } else if (avr->remap_point == REMAP_OUT_COPY &&
+                   (!direct_output || out_samples < in_samples)) {
+            /* if remapping channels during output copy, we may need to
+             * use an intermediate buffer in order to remap before adding
+             * samples to the output fifo */
+            av_dlog(avr, "[copy] %s to out_buffer\n", current_buffer->name);
+            ret = ff_audio_data_copy(avr->out_buffer, current_buffer,
+                                     &avr->ch_map_info);
+            if (ret < 0)
+                return ret;
+            current_buffer = avr->out_buffer;
+        } else if (avr->in_copy_needed || avr->in_convert_needed) {
             /* if needed, copy or convert input to in_buffer, and downmix if
                applicable */
             if (avr->in_convert_needed) {
@@ -322,7 +408,9 @@ int attribute_align_arg avresample_convert(AVAudioResampleContext *avr,
                     return ret;
             } else {
                 av_dlog(avr, "[copy] %s to in_buffer\n", current_buffer->name);
-                ret = ff_audio_data_copy(avr->in_buffer, current_buffer);
+                ret = ff_audio_data_copy(avr->in_buffer, current_buffer,
+                                         avr->remap_point == REMAP_IN_COPY ?
+                                         &avr->ch_map_info : NULL);
                 if (ret < 0)
                     return ret;
             }
@@ -350,7 +438,8 @@ int attribute_align_arg avresample_convert(AVAudioResampleContext *avr,
             resample_out = &output_buffer;
         else
             resample_out = avr->resample_out_buffer;
-        av_dlog(avr, "[resample] %s to %s\n", current_buffer->name,
+        av_dlog(avr, "[resample] %s to %s\n",
+                current_buffer ? current_buffer->name : "null",
                 resample_out->name);
         ret = ff_audio_resample(avr->resample, resample_out,
                                 current_buffer);
@@ -467,6 +556,57 @@ int avresample_set_matrix(AVAudioResampleContext *avr, const double *matrix,
     return 0;
 }
 
+int avresample_set_channel_mapping(AVAudioResampleContext *avr,
+                                   const int *channel_map)
+{
+    ChannelMapInfo *info = &avr->ch_map_info;
+    int in_channels, ch, i;
+
+    in_channels = av_get_channel_layout_nb_channels(avr->in_channel_layout);
+    if (in_channels <= 0 ||  in_channels > AVRESAMPLE_MAX_CHANNELS) {
+        av_log(avr, AV_LOG_ERROR, "Invalid input channel layout\n");
+        return AVERROR(EINVAL);
+    }
+
+    memset(info, 0, sizeof(*info));
+    memset(info->input_map, -1, sizeof(info->input_map));
+
+    for (ch = 0; ch < in_channels; ch++) {
+        if (channel_map[ch] >= in_channels) {
+            av_log(avr, AV_LOG_ERROR, "Invalid channel map\n");
+            return AVERROR(EINVAL);
+        }
+        if (channel_map[ch] < 0) {
+            info->channel_zero[ch] =  1;
+            info->channel_map[ch]  = -1;
+            info->do_zero          =  1;
+        } else if (info->input_map[channel_map[ch]] >= 0) {
+            info->channel_copy[ch] = info->input_map[channel_map[ch]];
+            info->channel_map[ch]  = -1;
+            info->do_copy          =  1;
+        } else {
+            info->channel_map[ch]            = channel_map[ch];
+            info->input_map[channel_map[ch]] = ch;
+            info->do_remap                   =  1;
+        }
+    }
+    /* Fill-in unmapped input channels with unmapped output channels.
+       This is used when remapping during conversion from interleaved to
+       planar format. */
+    for (ch = 0, i = 0; ch < in_channels && i < in_channels; ch++, i++) {
+        while (ch < in_channels && info->input_map[ch] >= 0)
+            ch++;
+        while (i < in_channels && info->channel_map[i] >= 0)
+            i++;
+        if (ch >= in_channels || i >= in_channels)
+            break;
+        info->input_map[ch] = i;
+    }
+
+    avr->use_channel_map = 1;
+    return 0;
+}
+
 int avresample_available(AVAudioResampleContext *avr)
 {
     return av_audio_fifo_size(avr->out_fifo);
diff --git a/libavresample/version.h b/libavresample/version.h
index ebcd07f..3cc4441 100644
--- a/libavresample/version.h
+++ b/libavresample/version.h
@@ -19,9 +19,15 @@
 #ifndef AVRESAMPLE_VERSION_H
 #define AVRESAMPLE_VERSION_H
 
+/**
+ * @file
+ * @ingroup lavr
+ * Libavresample version macros.
+ */
+
 #define LIBAVRESAMPLE_VERSION_MAJOR  1
-#define LIBAVRESAMPLE_VERSION_MINOR  0
-#define LIBAVRESAMPLE_VERSION_MICRO  1
+#define LIBAVRESAMPLE_VERSION_MINOR  1
+#define LIBAVRESAMPLE_VERSION_MICRO  0
 
 #define LIBAVRESAMPLE_VERSION_INT  AV_VERSION_INT(LIBAVRESAMPLE_VERSION_MAJOR, \
                                                   LIBAVRESAMPLE_VERSION_MINOR, \
diff --git a/libavresample/x86/Makefile b/libavresample/x86/Makefile
index 65bed89..2e8786f 100644
--- a/libavresample/x86/Makefile
+++ b/libavresample/x86/Makefile
@@ -1,5 +1,7 @@
 OBJS      += x86/audio_convert_init.o                                   \
              x86/audio_mix_init.o                                       \
+             x86/dither_init.o                                          \
 
 YASM-OBJS += x86/audio_convert.o                                        \
              x86/audio_mix.o                                            \
+             x86/dither.o                                               \
diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c
index 879108d..d85ca84 100644
--- a/libavresample/x86/audio_convert_init.c
+++ b/libavresample/x86/audio_convert_init.c
@@ -25,135 +25,135 @@
 
 /* flat conversions */
 
-extern void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len);
+void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len);
 
-extern void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len);
-extern void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len);
+void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len);
+void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len);
 
-extern void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len);
-extern void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len);
+void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len);
+void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len);
 
-extern void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len);
-extern void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len);
+void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len);
+void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len);
 
-extern void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len);
+void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len);
 
-extern void ff_conv_flt_to_s32_sse2(int32_t *dst, const float *src, int len);
-extern void ff_conv_flt_to_s32_avx (int32_t *dst, const float *src, int len);
+void ff_conv_flt_to_s32_sse2(int32_t *dst, const float *src, int len);
+void ff_conv_flt_to_s32_avx (int32_t *dst, const float *src, int len);
 
 /* interleave conversions */
 
-extern void ff_conv_s16p_to_s16_2ch_sse2(int16_t *dst, int16_t *const *src,
-                                         int len, int channels);
-extern void ff_conv_s16p_to_s16_2ch_avx (int16_t *dst, int16_t *const *src,
-                                         int len, int channels);
+void ff_conv_s16p_to_s16_2ch_sse2(int16_t *dst, int16_t *const *src,
+                                  int len, int channels);
+void ff_conv_s16p_to_s16_2ch_avx (int16_t *dst, int16_t *const *src,
+                                  int len, int channels);
 
-extern void ff_conv_s16p_to_s16_6ch_sse2(int16_t *dst, int16_t *const *src,
-                                         int len, int channels);
-extern void ff_conv_s16p_to_s16_6ch_sse2slow(int16_t *dst, int16_t *const *src,
-                                             int len, int channels);
-extern void ff_conv_s16p_to_s16_6ch_avx (int16_t *dst, int16_t *const *src,
-                                         int len, int channels);
+void ff_conv_s16p_to_s16_6ch_sse2(int16_t *dst, int16_t *const *src,
+                                  int len, int channels);
+void ff_conv_s16p_to_s16_6ch_sse2slow(int16_t *dst, int16_t *const *src,
+                                      int len, int channels);
+void ff_conv_s16p_to_s16_6ch_avx (int16_t *dst, int16_t *const *src,
+                                  int len, int channels);
 
-extern void ff_conv_s16p_to_flt_2ch_sse2(float *dst, int16_t *const *src,
-                                         int len, int channels);
-extern void ff_conv_s16p_to_flt_2ch_avx (float *dst, int16_t *const *src,
-                                         int len, int channels);
+void ff_conv_s16p_to_flt_2ch_sse2(float *dst, int16_t *const *src,
+                                  int len, int channels);
+void ff_conv_s16p_to_flt_2ch_avx (float *dst, int16_t *const *src,
+                                  int len, int channels);
 
-extern void ff_conv_s16p_to_flt_6ch_sse2 (float *dst, int16_t *const *src,
-                                          int len, int channels);
-extern void ff_conv_s16p_to_flt_6ch_ssse3(float *dst, int16_t *const *src,
-                                         int len, int channels);
-extern void ff_conv_s16p_to_flt_6ch_avx  (float *dst, int16_t *const *src,
-                                          int len, int channels);
+void ff_conv_s16p_to_flt_6ch_sse2 (float *dst, int16_t *const *src,
+                                   int len, int channels);
+void ff_conv_s16p_to_flt_6ch_ssse3(float *dst, int16_t *const *src,
+                                  int len, int channels);
+void ff_conv_s16p_to_flt_6ch_avx  (float *dst, int16_t *const *src,
+                                   int len, int channels);
 
-extern void ff_conv_fltp_to_s16_2ch_sse2 (int16_t *dst, float *const *src,
-                                          int len, int channels);
-extern void ff_conv_fltp_to_s16_2ch_ssse3(int16_t *dst, float *const *src,
-                                          int len, int channels);
+void ff_conv_fltp_to_s16_2ch_sse2 (int16_t *dst, float *const *src,
+                                   int len, int channels);
+void ff_conv_fltp_to_s16_2ch_ssse3(int16_t *dst, float *const *src,
+                                   int len, int channels);
 
-extern void ff_conv_fltp_to_s16_6ch_sse (int16_t *dst, float *const *src,
-                                         int len, int channels);
-extern void ff_conv_fltp_to_s16_6ch_sse2(int16_t *dst, float *const *src,
-                                         int len, int channels);
-extern void ff_conv_fltp_to_s16_6ch_avx (int16_t *dst, float *const *src,
-                                         int len, int channels);
+void ff_conv_fltp_to_s16_6ch_sse (int16_t *dst, float *const *src,
+                                  int len, int channels);
+void ff_conv_fltp_to_s16_6ch_sse2(int16_t *dst, float *const *src,
+                                  int len, int channels);
+void ff_conv_fltp_to_s16_6ch_avx (int16_t *dst, float *const *src,
+                                  int len, int channels);
 
-extern void ff_conv_fltp_to_flt_2ch_sse(float *dst, float *const *src, int len,
-                                        int channels);
-extern void ff_conv_fltp_to_flt_2ch_avx(float *dst, float *const *src, int len,
-                                        int channels);
+void ff_conv_fltp_to_flt_2ch_sse(float *dst, float *const *src, int len,
+                                 int channels);
+void ff_conv_fltp_to_flt_2ch_avx(float *dst, float *const *src, int len,
+                                 int channels);
 
-extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len,
-                                         int channels);
-extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len,
-                                         int channels);
-extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len,
-                                         int channels);
+void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len,
+                                  int channels);
+void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len,
+                                  int channels);
+void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len,
+                                  int channels);
 
 /* deinterleave conversions */
 
-extern void ff_conv_s16_to_s16p_2ch_sse2(int16_t *const *dst, int16_t *src,
-                                         int len, int channels);
-extern void ff_conv_s16_to_s16p_2ch_ssse3(int16_t *const *dst, int16_t *src,
-                                          int len, int channels);
-extern void ff_conv_s16_to_s16p_2ch_avx (int16_t *const *dst, int16_t *src,
-                                         int len, int channels);
+void ff_conv_s16_to_s16p_2ch_sse2(int16_t *const *dst, int16_t *src,
+                                  int len, int channels);
+void ff_conv_s16_to_s16p_2ch_ssse3(int16_t *const *dst, int16_t *src,
+                                   int len, int channels);
+void ff_conv_s16_to_s16p_2ch_avx (int16_t *const *dst, int16_t *src,
+                                  int len, int channels);
 
-extern void ff_conv_s16_to_s16p_6ch_sse2 (int16_t *const *dst, int16_t *src,
-                                          int len, int channels);
-extern void ff_conv_s16_to_s16p_6ch_ssse3(int16_t *const *dst, int16_t *src,
-                                          int len, int channels);
-extern void ff_conv_s16_to_s16p_6ch_avx  (int16_t *const *dst, int16_t *src,
-                                          int len, int channels);
+void ff_conv_s16_to_s16p_6ch_sse2 (int16_t *const *dst, int16_t *src,
+                                   int len, int channels);
+void ff_conv_s16_to_s16p_6ch_ssse3(int16_t *const *dst, int16_t *src,
+                                   int len, int channels);
+void ff_conv_s16_to_s16p_6ch_avx  (int16_t *const *dst, int16_t *src,
+                                   int len, int channels);
 
-extern void ff_conv_s16_to_fltp_2ch_sse2(float *const *dst, int16_t *src,
-                                         int len, int channels);
-extern void ff_conv_s16_to_fltp_2ch_avx (float *const *dst, int16_t *src,
-                                         int len, int channels);
+void ff_conv_s16_to_fltp_2ch_sse2(float *const *dst, int16_t *src,
+                                  int len, int channels);
+void ff_conv_s16_to_fltp_2ch_avx (float *const *dst, int16_t *src,
+                                  int len, int channels);
 
-extern void ff_conv_s16_to_fltp_6ch_sse2 (float *const *dst, int16_t *src,
-                                          int len, int channels);
-extern void ff_conv_s16_to_fltp_6ch_ssse3(float *const *dst, int16_t *src,
-                                          int len, int channels);
-extern void ff_conv_s16_to_fltp_6ch_sse4 (float *const *dst, int16_t *src,
-                                          int len, int channels);
-extern void ff_conv_s16_to_fltp_6ch_avx  (float *const *dst, int16_t *src,
-                                          int len, int channels);
+void ff_conv_s16_to_fltp_6ch_sse2 (float *const *dst, int16_t *src,
+                                   int len, int channels);
+void ff_conv_s16_to_fltp_6ch_ssse3(float *const *dst, int16_t *src,
+                                   int len, int channels);
+void ff_conv_s16_to_fltp_6ch_sse4 (float *const *dst, int16_t *src,
+                                   int len, int channels);
+void ff_conv_s16_to_fltp_6ch_avx  (float *const *dst, int16_t *src,
+                                   int len, int channels);
 
-extern void ff_conv_flt_to_s16p_2ch_sse2(int16_t *const *dst, float *src,
-                                         int len, int channels);
-extern void ff_conv_flt_to_s16p_2ch_avx (int16_t *const *dst, float *src,
-                                         int len, int channels);
+void ff_conv_flt_to_s16p_2ch_sse2(int16_t *const *dst, float *src,
+                                  int len, int channels);
+void ff_conv_flt_to_s16p_2ch_avx (int16_t *const *dst, float *src,
+                                  int len, int channels);
 
-extern void ff_conv_flt_to_s16p_6ch_sse2 (int16_t *const *dst, float *src,
-                                          int len, int channels);
-extern void ff_conv_flt_to_s16p_6ch_ssse3(int16_t *const *dst, float *src,
-                                          int len, int channels);
-extern void ff_conv_flt_to_s16p_6ch_avx  (int16_t *const *dst, float *src,
-                                          int len, int channels);
+void ff_conv_flt_to_s16p_6ch_sse2 (int16_t *const *dst, float *src,
+                                   int len, int channels);
+void ff_conv_flt_to_s16p_6ch_ssse3(int16_t *const *dst, float *src,
+                                   int len, int channels);
+void ff_conv_flt_to_s16p_6ch_avx  (int16_t *const *dst, float *src,
+                                   int len, int channels);
 
-extern void ff_conv_flt_to_fltp_2ch_sse(float *const *dst, float *src, int len,
-                                        int channels);
-extern void ff_conv_flt_to_fltp_2ch_avx(float *const *dst, float *src, int len,
-                                        int channels);
+void ff_conv_flt_to_fltp_2ch_sse(float *const *dst, float *src, int len,
+                                 int channels);
+void ff_conv_flt_to_fltp_2ch_avx(float *const *dst, float *src, int len,
+                                 int channels);
 
-extern void ff_conv_flt_to_fltp_6ch_sse2(float *const *dst, float *src, int len,
-                                         int channels);
-extern void ff_conv_flt_to_fltp_6ch_avx (float *const *dst, float *src, int len,
-                                         int channels);
+void ff_conv_flt_to_fltp_6ch_sse2(float *const *dst, float *src, int len,
+                                  int channels);
+void ff_conv_flt_to_fltp_6ch_avx (float *const *dst, float *src, int len,
+                                  int channels);
 
 av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
 {
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_MMX(mm_flags)) {
+    if (EXTERNAL_MMX(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
                                   0, 1, 8, "MMX", ff_conv_s32_to_s16_mmx);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
                                   6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx);
     }
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
                                   6, 1, 2, "SSE", ff_conv_fltp_to_s16_6ch_sse);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
@@ -161,8 +161,8 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
                                   2, 16, 4, "SSE", ff_conv_flt_to_fltp_2ch_sse);
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
-        if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
             ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
                                       0, 16, 16, "SSE2", ff_conv_s32_to_s16_sse2);
             ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P,
@@ -206,7 +206,7 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_FLT,
                                   6, 16, 4, "SSE2", ff_conv_flt_to_fltp_6ch_sse2);
     }
-    if (EXTERNAL_SSSE3(mm_flags)) {
+    if (EXTERNAL_SSSE3(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16P,
                                   6, 16, 4, "SSSE3", ff_conv_s16p_to_flt_6ch_ssse3);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP,
@@ -220,13 +220,13 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_FLT,
                                   6, 16, 4, "SSSE3", ff_conv_flt_to_s16p_6ch_ssse3);
     }
-    if (EXTERNAL_SSE4(mm_flags)) {
+    if (EXTERNAL_SSE4(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
                                   0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
                                   6, 16, 4, "SSE4", ff_conv_fltp_to_flt_6ch_sse4);
     }
-    if (EXTERNAL_AVX(mm_flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
                                   0, 32, 16, "AVX", ff_conv_s32_to_flt_avx);
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
diff --git a/libavresample/x86/audio_mix.asm b/libavresample/x86/audio_mix.asm
index 8a298e2..2c657b5 100644
--- a/libavresample/x86/audio_mix.asm
+++ b/libavresample/x86/audio_mix.asm
@@ -384,10 +384,10 @@ cglobal mix_%1_to_%2_%3_flt, 3,in_channels+2,needed_mmregs+matrix_elements_mm, n
     S16_TO_S32_SX   4, 5
     cvtdq2ps       m4, m4
     cvtdq2ps       m5, m5
-    fmaddps        m2, m4, mx_1_ %+ %%i, m2, m6
-    fmaddps        m3, m5, mx_1_ %+ %%i, m3, m6
-    fmaddps        m0, m4, mx_0_ %+ %%i, m0, m4
-    fmaddps        m1, m5, mx_0_ %+ %%i, m1, m5
+    FMULADD_PS     m2, m4, mx_1_ %+ %%i, m2, m6
+    FMULADD_PS     m3, m5, mx_1_ %+ %%i, m3, m6
+    FMULADD_PS     m0, m4, mx_0_ %+ %%i, m0, m4
+    FMULADD_PS     m1, m5, mx_0_ %+ %%i, m1, m5
     %else
     %if copy_src_from_stack
     mov       src_ptr, src %+ %%i %+ m
@@ -396,8 +396,8 @@ cglobal mix_%1_to_%2_%3_flt, 3,in_channels+2,needed_mmregs+matrix_elements_mm, n
     S16_TO_S32_SX   2, 3
     cvtdq2ps       m2, m2
     cvtdq2ps       m3, m3
-    fmaddps        m0, m2, mx_0_ %+ %%i, m0, m4
-    fmaddps        m1, m3, mx_0_ %+ %%i, m1, m4
+    FMULADD_PS     m0, m2, mx_0_ %+ %%i, m0, m4
+    FMULADD_PS     m1, m3, mx_0_ %+ %%i, m1, m4
     %endif
     %assign %%i %%i+1
 %endrep
@@ -422,7 +422,7 @@ cglobal mix_%1_to_%2_%3_flt, 3,in_channels+2,needed_mmregs+matrix_elements_mm, n
     %if stereo || mx_stack_0_0
     mulps          m0, m0, mx_0_0
     %else
-    mulps          m0, [src0q+lenq], mx_0_0
+    mulps          m0, mx_0_0, [src0q+lenq]
     %endif
 %assign %%i 1
 %rep (in_channels - 1)
@@ -437,12 +437,12 @@ cglobal mix_%1_to_%2_%3_flt, 3,in_channels+2,needed_mmregs+matrix_elements_mm, n
     mova           m2, [src_ptr+lenq]
     %endif
     %if stereo
-    fmaddps        m1, m2, mx_1_ %+ %%i, m1, m3
+    FMULADD_PS     m1, m2, mx_1_ %+ %%i, m1, m3
     %endif
     %if stereo || mx_stack_0_ %+ %%i
-    fmaddps        m0, m2, mx_0_ %+ %%i, m0, m2
+    FMULADD_PS     m0, m2, mx_0_ %+ %%i, m0, m2
     %else
-    fmaddps        m0, mx_0_ %+ %%i, [src_ptr+lenq], m0, m1
+    FMULADD_PS     m0, mx_0_ %+ %%i, [src_ptr+lenq], m0, m1
     %endif
     %assign %%i %%i+1
 %endrep
diff --git a/libavresample/x86/audio_mix_init.c b/libavresample/x86/audio_mix_init.c
index 72b2397..932f6f2 100644
--- a/libavresample/x86/audio_mix_init.c
+++ b/libavresample/x86/audio_mix_init.c
@@ -23,80 +23,80 @@
 #include "libavutil/x86/cpu.h"
 #include "libavresample/audio_mix.h"
 
-extern void ff_mix_2_to_1_fltp_flt_sse(float **src, float **matrix, int len,
-                                       int out_ch, int in_ch);
-extern void ff_mix_2_to_1_fltp_flt_avx(float **src, float **matrix, int len,
-                                       int out_ch, int in_ch);
+void ff_mix_2_to_1_fltp_flt_sse(float **src, float **matrix, int len,
+                                int out_ch, int in_ch);
+void ff_mix_2_to_1_fltp_flt_avx(float **src, float **matrix, int len,
+                                int out_ch, int in_ch);
 
-extern void ff_mix_2_to_1_s16p_flt_sse2(int16_t **src, float **matrix, int len,
-                                        int out_ch, int in_ch);
-extern void ff_mix_2_to_1_s16p_flt_sse4(int16_t **src, float **matrix, int len,
-                                        int out_ch, int in_ch);
+void ff_mix_2_to_1_s16p_flt_sse2(int16_t **src, float **matrix, int len,
+                                 int out_ch, int in_ch);
+void ff_mix_2_to_1_s16p_flt_sse4(int16_t **src, float **matrix, int len,
+                                 int out_ch, int in_ch);
 
-extern void ff_mix_2_to_1_s16p_q8_sse2(int16_t **src, int16_t **matrix,
-                                       int len, int out_ch, int in_ch);
+void ff_mix_2_to_1_s16p_q8_sse2(int16_t **src, int16_t **matrix,
+                                int len, int out_ch, int in_ch);
 
-extern void ff_mix_1_to_2_fltp_flt_sse(float **src, float **matrix, int len,
-                                       int out_ch, int in_ch);
-extern void ff_mix_1_to_2_fltp_flt_avx(float **src, float **matrix, int len,
-                                       int out_ch, int in_ch);
+void ff_mix_1_to_2_fltp_flt_sse(float **src, float **matrix, int len,
+                                int out_ch, int in_ch);
+void ff_mix_1_to_2_fltp_flt_avx(float **src, float **matrix, int len,
+                                int out_ch, int in_ch);
 
-extern void ff_mix_1_to_2_s16p_flt_sse2(int16_t **src, float **matrix, int len,
-                                        int out_ch, int in_ch);
-extern void ff_mix_1_to_2_s16p_flt_sse4(int16_t **src, float **matrix, int len,
-                                        int out_ch, int in_ch);
-extern void ff_mix_1_to_2_s16p_flt_avx (int16_t **src, float **matrix, int len,
-                                        int out_ch, int in_ch);
+void ff_mix_1_to_2_s16p_flt_sse2(int16_t **src, float **matrix, int len,
+                                 int out_ch, int in_ch);
+void ff_mix_1_to_2_s16p_flt_sse4(int16_t **src, float **matrix, int len,
+                                 int out_ch, int in_ch);
+void ff_mix_1_to_2_s16p_flt_avx (int16_t **src, float **matrix, int len,
+                                 int out_ch, int in_ch);
 
-#define DEFINE_MIX_3_8_TO_1_2(chan)                                         \
-extern void ff_mix_ ## chan ## _to_1_fltp_flt_sse(float **src,              \
-                                                  float **matrix, int len,  \
-                                                  int out_ch, int in_ch);   \
-extern void ff_mix_ ## chan ## _to_2_fltp_flt_sse(float **src,              \
-                                                  float **matrix, int len,  \
-                                                  int out_ch, int in_ch);   \
-                                                                            \
-extern void ff_mix_ ## chan ## _to_1_s16p_flt_sse2(int16_t **src,           \
-                                                   float **matrix, int len, \
-                                                   int out_ch, int in_ch);  \
-extern void ff_mix_ ## chan ## _to_2_s16p_flt_sse2(int16_t **src,           \
-                                                   float **matrix, int len, \
-                                                   int out_ch, int in_ch);  \
-                                                                            \
-extern void ff_mix_ ## chan ## _to_1_s16p_flt_sse4(int16_t **src,           \
-                                                   float **matrix, int len, \
-                                                   int out_ch, int in_ch);  \
-extern void ff_mix_ ## chan ## _to_2_s16p_flt_sse4(int16_t **src,           \
-                                                   float **matrix, int len, \
-                                                   int out_ch, int in_ch);  \
-                                                                            \
-extern void ff_mix_ ## chan ## _to_1_fltp_flt_avx(float **src,              \
-                                                  float **matrix, int len,  \
-                                                  int out_ch, int in_ch);   \
-extern void ff_mix_ ## chan ## _to_2_fltp_flt_avx(float **src,              \
-                                                  float **matrix, int len,  \
-                                                  int out_ch, int in_ch);   \
-                                                                            \
-extern void ff_mix_ ## chan ## _to_1_s16p_flt_avx(int16_t **src,            \
-                                                  float **matrix, int len,  \
-                                                  int out_ch, int in_ch);   \
-extern void ff_mix_ ## chan ## _to_2_s16p_flt_avx(int16_t **src,            \
-                                                  float **matrix, int len,  \
-                                                  int out_ch, int in_ch);   \
-                                                                            \
-extern void ff_mix_ ## chan ## _to_1_fltp_flt_fma4(float **src,             \
-                                                   float **matrix, int len, \
-                                                   int out_ch, int in_ch);  \
-extern void ff_mix_ ## chan ## _to_2_fltp_flt_fma4(float **src,             \
-                                                   float **matrix, int len, \
-                                                   int out_ch, int in_ch);  \
-                                                                            \
-extern void ff_mix_ ## chan ## _to_1_s16p_flt_fma4(int16_t **src,           \
-                                                   float **matrix, int len, \
-                                                   int out_ch, int in_ch);  \
-extern void ff_mix_ ## chan ## _to_2_s16p_flt_fma4(int16_t **src,           \
-                                                   float **matrix, int len, \
-                                                   int out_ch, int in_ch);
+#define DEFINE_MIX_3_8_TO_1_2(chan)                                     \
+void ff_mix_ ## chan ## _to_1_fltp_flt_sse(float **src,                 \
+                                           float **matrix, int len,     \
+                                           int out_ch, int in_ch);      \
+void ff_mix_ ## chan ## _to_2_fltp_flt_sse(float **src,                 \
+                                           float **matrix, int len,     \
+                                           int out_ch, int in_ch);      \
+                                                                        \
+void ff_mix_ ## chan ## _to_1_s16p_flt_sse2(int16_t **src,              \
+                                            float **matrix, int len,    \
+                                            int out_ch, int in_ch);     \
+void ff_mix_ ## chan ## _to_2_s16p_flt_sse2(int16_t **src,              \
+                                            float **matrix, int len,    \
+                                            int out_ch, int in_ch);     \
+                                                                        \
+void ff_mix_ ## chan ## _to_1_s16p_flt_sse4(int16_t **src,              \
+                                            float **matrix, int len,    \
+                                            int out_ch, int in_ch);     \
+void ff_mix_ ## chan ## _to_2_s16p_flt_sse4(int16_t **src,              \
+                                            float **matrix, int len,    \
+                                            int out_ch, int in_ch);     \
+                                                                        \
+void ff_mix_ ## chan ## _to_1_fltp_flt_avx(float **src,                 \
+                                           float **matrix, int len,     \
+                                           int out_ch, int in_ch);      \
+void ff_mix_ ## chan ## _to_2_fltp_flt_avx(float **src,                 \
+                                           float **matrix, int len,     \
+                                           int out_ch, int in_ch);      \
+                                                                        \
+void ff_mix_ ## chan ## _to_1_s16p_flt_avx(int16_t **src,               \
+                                           float **matrix, int len,     \
+                                           int out_ch, int in_ch);      \
+void ff_mix_ ## chan ## _to_2_s16p_flt_avx(int16_t **src,               \
+                                           float **matrix, int len,     \
+                                           int out_ch, int in_ch);      \
+                                                                        \
+void ff_mix_ ## chan ## _to_1_fltp_flt_fma4(float **src,                \
+                                            float **matrix, int len,    \
+                                            int out_ch, int in_ch);     \
+void ff_mix_ ## chan ## _to_2_fltp_flt_fma4(float **src,                \
+                                            float **matrix, int len,    \
+                                            int out_ch, int in_ch);     \
+                                                                        \
+void ff_mix_ ## chan ## _to_1_s16p_flt_fma4(int16_t **src,              \
+                                            float **matrix, int len,    \
+                                            int out_ch, int in_ch);     \
+void ff_mix_ ## chan ## _to_2_s16p_flt_fma4(int16_t **src,              \
+                                            float **matrix, int len,    \
+                                            int out_ch, int in_ch);
 
 DEFINE_MIX_3_8_TO_1_2(3)
 DEFINE_MIX_3_8_TO_1_2(4)
@@ -106,7 +106,7 @@ DEFINE_MIX_3_8_TO_1_2(7)
 DEFINE_MIX_3_8_TO_1_2(8)
 
 #define SET_MIX_3_8_TO_1_2(chan)                                            \
-    if (EXTERNAL_SSE(mm_flags)) {                                           \
+    if (EXTERNAL_SSE(cpu_flags)) {                                          \
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,\
                               chan, 1, 16, 4, "SSE",                        \
                               ff_mix_ ## chan ## _to_1_fltp_flt_sse);       \
@@ -114,7 +114,7 @@ DEFINE_MIX_3_8_TO_1_2(8)
                               chan, 2, 16, 4, "SSE",                        \
                               ff_mix_## chan ##_to_2_fltp_flt_sse);         \
     }                                                                       \
-    if (EXTERNAL_SSE2(mm_flags)) {                                          \
+    if (EXTERNAL_SSE2(cpu_flags)) {                                         \
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
                               chan, 1, 16, 8, "SSE2",                       \
                               ff_mix_ ## chan ## _to_1_s16p_flt_sse2);      \
@@ -122,7 +122,7 @@ DEFINE_MIX_3_8_TO_1_2(8)
                               chan, 2, 16, 8, "SSE2",                       \
                               ff_mix_ ## chan ## _to_2_s16p_flt_sse2);      \
     }                                                                       \
-    if (EXTERNAL_SSE4(mm_flags)) {                                          \
+    if (EXTERNAL_SSE4(cpu_flags)) {                                         \
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,\
                               chan, 1, 16, 8, "SSE4",                       \
                               ff_mix_ ## chan ## _to_1_s16p_flt_sse4);      \
@@ -130,7 +130,7 @@ DEFINE_MIX_3_8_TO_1_2(8)
                               chan, 2, 16, 8, "SSE4",                       \
                               ff_mix_ ## chan ## _to_2_s16p_flt_sse4);      \
     }                                                                       \
-    if (EXTERNAL_AVX(mm_flags)) {                                           \
+    if (EXTERNAL_AVX(cpu_flags)) {                                          \
         int ptr_align = 32;                                                 \
         int smp_align = 8;                                                  \
         if (ARCH_X86_32 || chan >= 6) {                                     \
@@ -150,7 +150,7 @@ DEFINE_MIX_3_8_TO_1_2(8)
                               chan, 2, 16, 8, "AVX",                        \
                               ff_mix_ ## chan ## _to_2_s16p_flt_avx);       \
     }                                                                       \
-    if (EXTERNAL_FMA4(mm_flags)) {                                          \
+    if (EXTERNAL_FMA4(cpu_flags)) {                                         \
         int ptr_align = 32;                                                 \
         int smp_align = 8;                                                  \
         if (ARCH_X86_32 || chan >= 6) {                                     \
@@ -174,15 +174,15 @@ DEFINE_MIX_3_8_TO_1_2(8)
 av_cold void ff_audio_mix_init_x86(AudioMix *am)
 {
 #if HAVE_YASM
-    int mm_flags = av_get_cpu_flags();
+    int cpu_flags = av_get_cpu_flags();
 
-    if (EXTERNAL_SSE(mm_flags)) {
+    if (EXTERNAL_SSE(cpu_flags)) {
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
                               2, 1, 16, 8, "SSE", ff_mix_2_to_1_fltp_flt_sse);
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
                               1, 2, 16, 4, "SSE", ff_mix_1_to_2_fltp_flt_sse);
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
                               2, 1, 16, 8, "SSE2", ff_mix_2_to_1_s16p_flt_sse2);
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_Q8,
@@ -190,13 +190,13 @@ av_cold void ff_audio_mix_init_x86(AudioMix *am)
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
                               1, 2, 16, 8, "SSE2", ff_mix_1_to_2_s16p_flt_sse2);
     }
-    if (EXTERNAL_SSE4(mm_flags)) {
+    if (EXTERNAL_SSE4(cpu_flags)) {
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
                               2, 1, 16, 8, "SSE4", ff_mix_2_to_1_s16p_flt_sse4);
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_S16P, AV_MIX_COEFF_TYPE_FLT,
                               1, 2, 16, 8, "SSE4", ff_mix_1_to_2_s16p_flt_sse4);
     }
-    if (EXTERNAL_AVX(mm_flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
                               2, 1, 32, 16, "AVX", ff_mix_2_to_1_fltp_flt_avx);
         ff_audio_mix_set_func(am, AV_SAMPLE_FMT_FLTP, AV_MIX_COEFF_TYPE_FLT,
diff --git a/libavresample/x86/dither.asm b/libavresample/x86/dither.asm
new file mode 100644
index 0000000..2192e98
--- /dev/null
+++ b/libavresample/x86/dither.asm
@@ -0,0 +1,117 @@
+;******************************************************************************
+;* x86 optimized dithering format conversion
+;* Copyright (c) 2012 Justin Ruggles <justin.ruggles at gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav is free software; you can redistribute it and/or
+;* modify it under the terms of the GNU Lesser General Public
+;* License as published by the Free Software Foundation; either
+;* version 2.1 of the License, or (at your option) any later version.
+;*
+;* Libav is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;* Lesser General Public License for more details.
+;*
+;* You should have received a copy of the GNU Lesser General Public
+;* License along with Libav; if not, write to the Free Software
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA 32
+
+; 1.0f / (2.0f * INT32_MAX)
+pf_dither_scale: times 8 dd 2.32830643762e-10
+
+pf_s16_scale: times 4 dd 32753.0
+
+SECTION_TEXT
+
+;------------------------------------------------------------------------------
+; void ff_quantize(int16_t *dst, float *src, float *dither, int len);
+;------------------------------------------------------------------------------
+
+INIT_XMM sse2
+cglobal quantize, 4,4,3, dst, src, dither, len
+    lea         lenq, [2*lend]
+    add         dstq, lenq
+    lea         srcq, [srcq+2*lenq]
+    lea      ditherq, [ditherq+2*lenq]
+    neg         lenq
+    mova          m2, [pf_s16_scale]
+.loop:
+    mulps         m0, m2, [srcq+2*lenq]
+    mulps         m1, m2, [srcq+2*lenq+mmsize]
+    addps         m0, [ditherq+2*lenq]
+    addps         m1, [ditherq+2*lenq+mmsize]
+    cvtps2dq      m0, m0
+    cvtps2dq      m1, m1
+    packssdw      m0, m1
+    mova     [dstq+lenq], m0
+    add         lenq, mmsize
+    jl .loop
+    REP_RET
+
+;------------------------------------------------------------------------------
+; void ff_dither_int_to_float_rectangular(float *dst, int *src, int len)
+;------------------------------------------------------------------------------
+
+%macro DITHER_INT_TO_FLOAT_RECTANGULAR 0
+cglobal dither_int_to_float_rectangular, 3,3,3, dst, src, len
+    lea         lenq, [4*lend]
+    add         srcq, lenq
+    add         dstq, lenq
+    neg         lenq
+    mova          m0, [pf_dither_scale]
+.loop:
+    cvtdq2ps      m1, [srcq+lenq]
+    cvtdq2ps      m2, [srcq+lenq+mmsize]
+    mulps         m1, m1, m0
+    mulps         m2, m2, m0
+    mova  [dstq+lenq], m1
+    mova  [dstq+lenq+mmsize], m2
+    add         lenq, 2*mmsize
+    jl .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse2
+DITHER_INT_TO_FLOAT_RECTANGULAR
+INIT_YMM avx
+DITHER_INT_TO_FLOAT_RECTANGULAR
+
+;------------------------------------------------------------------------------
+; void ff_dither_int_to_float_triangular(float *dst, int *src0, int len)
+;------------------------------------------------------------------------------
+
+%macro DITHER_INT_TO_FLOAT_TRIANGULAR 0
+cglobal dither_int_to_float_triangular, 3,4,5, dst, src0, len, src1
+    lea         lenq, [4*lend]
+    lea        src1q, [src0q+2*lenq]
+    add        src0q, lenq
+    add         dstq, lenq
+    neg         lenq
+    mova          m0, [pf_dither_scale]
+.loop:
+    cvtdq2ps      m1, [src0q+lenq]
+    cvtdq2ps      m2, [src0q+lenq+mmsize]
+    cvtdq2ps      m3, [src1q+lenq]
+    cvtdq2ps      m4, [src1q+lenq+mmsize]
+    addps         m1, m1, m3
+    addps         m2, m2, m4
+    mulps         m1, m1, m0
+    mulps         m2, m2, m0
+    mova  [dstq+lenq], m1
+    mova  [dstq+lenq+mmsize], m2
+    add         lenq, 2*mmsize
+    jl .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse2
+DITHER_INT_TO_FLOAT_TRIANGULAR
+INIT_YMM avx
+DITHER_INT_TO_FLOAT_TRIANGULAR
diff --git a/libavresample/x86/dither_init.c b/libavresample/x86/dither_init.c
new file mode 100644
index 0000000..8349d5e
--- /dev/null
+++ b/libavresample/x86/dither_init.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012 Justin Ruggles <justin.ruggles at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavresample/dither.h"
+
+void ff_quantize_sse2(int16_t *dst, const float *src, float *dither, int len);
+
+void ff_dither_int_to_float_rectangular_sse2(float *dst, int *src, int len);
+void ff_dither_int_to_float_rectangular_avx(float *dst, int *src, int len);
+
+void ff_dither_int_to_float_triangular_sse2(float *dst, int *src0, int len);
+void ff_dither_int_to_float_triangular_avx(float *dst, int *src0, int len);
+
+av_cold void ff_dither_init_x86(DitherDSPContext *ddsp,
+                                enum AVResampleDitherMethod method)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        ddsp->quantize      = ff_quantize_sse2;
+        ddsp->ptr_align     = 16;
+        ddsp->samples_align = 8;
+    }
+
+    if (method == AV_RESAMPLE_DITHER_RECTANGULAR) {
+        if (EXTERNAL_SSE2(cpu_flags)) {
+            ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_sse2;
+        }
+        if (EXTERNAL_AVX(cpu_flags)) {
+            ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_avx;
+        }
+    } else {
+        if (EXTERNAL_SSE2(cpu_flags)) {
+            ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_sse2;
+        }
+        if (EXTERNAL_AVX(cpu_flags)) {
+            ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_avx;
+        }
+    }
+}
diff --git a/libavutil/Makefile b/libavutil/Makefile
index 48a0e16..cfe8d84 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -11,6 +11,7 @@ HEADERS = adler32.h                                                     \
           base64.h                                                      \
           blowfish.h                                                    \
           bswap.h                                                       \
+          buffer.h                                                      \
           channel_layout.h                                              \
           common.h                                                      \
           cpu.h                                                         \
@@ -19,9 +20,10 @@ HEADERS = adler32.h                                                     \
           eval.h                                                        \
           fifo.h                                                        \
           file.h                                                        \
+          frame.h                                                       \
+          hmac.h                                                        \
           imgutils.h                                                    \
           intfloat.h                                                    \
-          intfloat_readwrite.h                                          \
           intreadwrite.h                                                \
           lfg.h                                                         \
           log.h                                                         \
@@ -38,6 +40,7 @@ HEADERS = adler32.h                                                     \
           rational.h                                                    \
           samplefmt.h                                                   \
           sha.h                                                         \
+          stereo3d.h                                                    \
           time.h                                                        \
           version.h                                                     \
           xtea.h                                                        \
@@ -53,10 +56,12 @@ BUILT_HEADERS = avconfig.h
 
 OBJS = adler32.o                                                        \
        aes.o                                                            \
+       atomic.o                                                         \
        audio_fifo.o                                                     \
        avstring.o                                                       \
        base64.o                                                         \
        blowfish.o                                                       \
+       buffer.o                                                         \
        channel_layout.o                                                 \
        cpu.o                                                            \
        crc.o                                                            \
@@ -65,9 +70,11 @@ OBJS = adler32.o                                                        \
        eval.o                                                           \
        fifo.o                                                           \
        file.o                                                           \
+       file_open.o                                                      \
        float_dsp.o                                                      \
+       frame.o                                                          \
+       hmac.o                                                           \
        imgutils.o                                                       \
-       intfloat_readwrite.o                                             \
        intmath.o                                                        \
        lfg.o                                                            \
        lls.o                                                            \
@@ -85,6 +92,7 @@ OBJS = adler32.o                                                        \
        rc4.o                                                            \
        samplefmt.o                                                      \
        sha.o                                                            \
+       stereo3d.o                                                       \
        time.o                                                           \
        tree.o                                                           \
        utils.o                                                          \
@@ -96,8 +104,13 @@ OBJS += $(COMPAT_OBJS:%=../compat/%)
 
 SKIPHEADERS          = old_pix_fmts.h
 
+SKIPHEADERS-$(HAVE_ATOMICS_GCC)        += atomic_gcc.h
+SKIPHEADERS-$(HAVE_ATOMICS_SUNCC)      += atomic_suncc.h
+SKIPHEADERS-$(HAVE_ATOMICS_WIN32)      += atomic_win32.h
+
 TESTPROGS = adler32                                                     \
             aes                                                         \
+            atomic                                                      \
             avstring                                                    \
             base64                                                      \
             blowfish                                                    \
@@ -106,6 +119,7 @@ TESTPROGS = adler32                                                     \
             des                                                         \
             eval                                                        \
             fifo                                                        \
+            hmac                                                        \
             lfg                                                         \
             lls                                                         \
             md5                                                         \
diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S
index a181789..4638200 100644
--- a/libavutil/arm/asm.S
+++ b/libavutil/arm/asm.S
@@ -291,7 +291,7 @@ T       sub             \rn, \rn, \rm
 .endm
 
 #if HAVE_VFP_ARGS
-        .eabi_attribute 28, 1
+ELF     .eabi_attribute 28, 1
 #   define VFP
 #   define NOVFP @
 #else
diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c
index b4aabc3..85ea662 100644
--- a/libavutil/arm/cpu.c
+++ b/libavutil/arm/cpu.c
@@ -17,6 +17,7 @@
  */
 
 #include "libavutil/cpu.h"
+#include "libavutil/cpu_internal.h"
 #include "config.h"
 
 #define CORE_FLAG(f) \
diff --git a/libavutil/arm/cpu.h b/libavutil/arm/cpu.h
index 91c959a..52e839c 100644
--- a/libavutil/arm/cpu.h
+++ b/libavutil/arm/cpu.h
@@ -21,12 +21,13 @@
 
 #include "config.h"
 #include "libavutil/cpu.h"
+#include "libavutil/cpu_internal.h"
 
-#define have_armv5te(flags) (HAVE_ARMV5TE && ((flags) & AV_CPU_FLAG_ARMV5TE))
-#define have_armv6(flags)   (HAVE_ARMV6   && ((flags) & AV_CPU_FLAG_ARMV6))
-#define have_armv6t2(flags) (HAVE_ARMV6T2 && ((flags) & AV_CPU_FLAG_ARMV6T2))
-#define have_vfp(flags)     (HAVE_VFP     && ((flags) & AV_CPU_FLAG_VFP))
-#define have_vfpv3(flags)   (HAVE_VFPV3   && ((flags) & AV_CPU_FLAG_VFPV3))
-#define have_neon(flags)    (HAVE_NEON    && ((flags) & AV_CPU_FLAG_NEON))
+#define have_armv5te(flags) CPUEXT(flags, ARMV5TE)
+#define have_armv6(flags)   CPUEXT(flags, ARMV6)
+#define have_armv6t2(flags) CPUEXT(flags, ARMV6T2)
+#define have_vfp(flags)     CPUEXT(flags, VFP)
+#define have_vfpv3(flags)   CPUEXT(flags, VFPV3)
+#define have_neon(flags)    CPUEXT(flags, NEON)
 
-#endif
+#endif /* AVUTIL_ARM_CPU_H */
diff --git a/libavutil/arm/float_dsp_arm.h b/libavutil/arm/float_dsp_arm.h
index 81fad3e..ec925ec 100644
--- a/libavutil/arm/float_dsp_arm.h
+++ b/libavutil/arm/float_dsp_arm.h
@@ -23,7 +23,7 @@
 
 #include "libavutil/float_dsp.h"
 
-void ff_float_dsp_init_vfp (AVFloatDSPContext *fdsp);
+void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags);
 void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp);
 
 #endif /* AVUTIL_ARM_FLOAT_DSP_ARM_H */
diff --git a/libavutil/arm/float_dsp_init_arm.c b/libavutil/arm/float_dsp_init_arm.c
index b133d32..39a5e95 100644
--- a/libavutil/arm/float_dsp_init_arm.c
+++ b/libavutil/arm/float_dsp_init_arm.c
@@ -18,16 +18,17 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
 #include "cpu.h"
 #include "float_dsp_arm.h"
 
-void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp)
+av_cold void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp)
 {
     int cpu_flags = av_get_cpu_flags();
 
     if (have_vfp(cpu_flags))
-        ff_float_dsp_init_vfp(fdsp);
+        ff_float_dsp_init_vfp(fdsp, cpu_flags);
     if (have_neon(cpu_flags))
         ff_float_dsp_init_neon(fdsp);
 }
diff --git a/libavutil/arm/float_dsp_init_neon.c b/libavutil/arm/float_dsp_init_neon.c
index 88eb4b3..617bf5d 100644
--- a/libavutil/arm/float_dsp_init_neon.c
+++ b/libavutil/arm/float_dsp_init_neon.c
@@ -21,6 +21,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
 #include "float_dsp_arm.h"
 
@@ -32,9 +33,27 @@ void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul,
 void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul,
                                 int len);
 
-void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
+void ff_vector_fmul_window_neon(float *dst, const float *src0,
+                                const float *src1, const float *win, int len);
+
+void ff_vector_fmul_add_neon(float *dst, const float *src0, const float *src1,
+                             const float *src2, int len);
+
+void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
+                                 const float *src1, int len);
+
+void ff_butterflies_float_neon(float *v1, float *v2, int len);
+
+float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
+
+av_cold void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
 {
     fdsp->vector_fmul = ff_vector_fmul_neon;
     fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
     fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_neon;
+    fdsp->vector_fmul_window = ff_vector_fmul_window_neon;
+    fdsp->vector_fmul_add    = ff_vector_fmul_add_neon;
+    fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_neon;
+    fdsp->butterflies_float = ff_butterflies_float_neon;
+    fdsp->scalarproduct_float = ff_scalarproduct_float_neon;
 }
diff --git a/libavutil/arm/float_dsp_init_vfp.c b/libavutil/arm/float_dsp_init_vfp.c
index ef808d8..31cb6ae 100644
--- a/libavutil/arm/float_dsp_init_vfp.c
+++ b/libavutil/arm/float_dsp_init_vfp.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/attributes.h"
 #include "libavutil/float_dsp.h"
 #include "cpu.h"
 #include "float_dsp_arm.h"
@@ -25,10 +26,12 @@
 void ff_vector_fmul_vfp(float *dst, const float *src0, const float *src1,
                         int len);
 
-void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp)
-{
-    int cpu_flags = av_get_cpu_flags();
+void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
+                                const float *src1, int len);
 
+av_cold void ff_float_dsp_init_vfp(AVFloatDSPContext *fdsp, int cpu_flags)
+{
     if (!have_vfpv3(cpu_flags))
         fdsp->vector_fmul = ff_vector_fmul_vfp;
+    fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_vfp;
 }
diff --git a/libavutil/arm/float_dsp_neon.S b/libavutil/arm/float_dsp_neon.S
index 6d7bd52..559b565 100644
--- a/libavutil/arm/float_dsp_neon.S
+++ b/libavutil/arm/float_dsp_neon.S
@@ -146,3 +146,126 @@ NOVFP   vdup.32         q8,  r2
         bx              lr
         .unreq          len
 endfunc
+
+function ff_vector_fmul_window_neon, export=1
+        push            {r4,r5,lr}
+        ldr             lr,  [sp, #12]
+        sub             r2,  r2,  #8
+        sub             r5,  lr,  #2
+        add             r2,  r2,  r5, lsl #2
+        add             r4,  r3,  r5, lsl #3
+        add             ip,  r0,  r5, lsl #3
+        mov             r5,  #-16
+        vld1.32         {d0,d1},  [r1,:128]!
+        vld1.32         {d2,d3},  [r2,:128], r5
+        vld1.32         {d4,d5},  [r3,:128]!
+        vld1.32         {d6,d7},  [r4,:128], r5
+1:      subs            lr,  lr,  #4
+        vmul.f32        d22, d0,  d4
+        vrev64.32       q3,  q3
+        vmul.f32        d23, d1,  d5
+        vrev64.32       q1,  q1
+        vmul.f32        d20, d0,  d7
+        vmul.f32        d21, d1,  d6
+        beq             2f
+        vmla.f32        d22, d3,  d7
+        vld1.32         {d0,d1},  [r1,:128]!
+        vmla.f32        d23, d2,  d6
+        vld1.32         {d18,d19},[r2,:128], r5
+        vmls.f32        d20, d3,  d4
+        vld1.32         {d24,d25},[r3,:128]!
+        vmls.f32        d21, d2,  d5
+        vld1.32         {d6,d7},  [r4,:128], r5
+        vmov            q1,  q9
+        vrev64.32       q11, q11
+        vmov            q2,  q12
+        vswp            d22, d23
+        vst1.32         {d20,d21},[r0,:128]!
+        vst1.32         {d22,d23},[ip,:128], r5
+        b               1b
+2:      vmla.f32        d22, d3,  d7
+        vmla.f32        d23, d2,  d6
+        vmls.f32        d20, d3,  d4
+        vmls.f32        d21, d2,  d5
+        vrev64.32       q11, q11
+        vswp            d22, d23
+        vst1.32         {d20,d21},[r0,:128]!
+        vst1.32         {d22,d23},[ip,:128], r5
+        pop             {r4,r5,pc}
+endfunc
+
+function ff_vector_fmul_add_neon, export=1
+        ldr             r12, [sp]
+        vld1.32         {q0-q1},  [r1,:128]!
+        vld1.32         {q8-q9},  [r2,:128]!
+        vld1.32         {q2-q3},  [r3,:128]!
+        vmul.f32        q10, q0,  q8
+        vmul.f32        q11, q1,  q9
+1:      vadd.f32        q12, q2,  q10
+        vadd.f32        q13, q3,  q11
+        pld             [r1, #16]
+        pld             [r2, #16]
+        pld             [r3, #16]
+        subs            r12, r12, #8
+        beq             2f
+        vld1.32         {q0},     [r1,:128]!
+        vld1.32         {q8},     [r2,:128]!
+        vmul.f32        q10, q0,  q8
+        vld1.32         {q1},     [r1,:128]!
+        vld1.32         {q9},     [r2,:128]!
+        vmul.f32        q11, q1,  q9
+        vld1.32         {q2-q3},  [r3,:128]!
+        vst1.32         {q12-q13},[r0,:128]!
+        b               1b
+2:      vst1.32         {q12-q13},[r0,:128]!
+        bx              lr
+endfunc
+
+function ff_vector_fmul_reverse_neon, export=1
+        add             r2,  r2,  r3,  lsl #2
+        sub             r2,  r2,  #32
+        mov             r12, #-32
+        vld1.32         {q0-q1},  [r1,:128]!
+        vld1.32         {q2-q3},  [r2,:128], r12
+1:      pld             [r1, #32]
+        vrev64.32       q3,  q3
+        vmul.f32        d16, d0,  d7
+        vmul.f32        d17, d1,  d6
+        pld             [r2, #-32]
+        vrev64.32       q2,  q2
+        vmul.f32        d18, d2,  d5
+        vmul.f32        d19, d3,  d4
+        subs            r3,  r3,  #8
+        beq             2f
+        vld1.32         {q0-q1},  [r1,:128]!
+        vld1.32         {q2-q3},  [r2,:128], r12
+        vst1.32         {q8-q9},  [r0,:128]!
+        b               1b
+2:      vst1.32         {q8-q9},  [r0,:128]!
+        bx              lr
+endfunc
+
+function ff_butterflies_float_neon, export=1
+1:      vld1.32         {q0},[r0,:128]
+        vld1.32         {q1},[r1,:128]
+        vsub.f32        q2,  q0,  q1
+        vadd.f32        q1,  q0,  q1
+        vst1.32         {q2},[r1,:128]!
+        vst1.32         {q1},[r0,:128]!
+        subs            r2,  r2,  #4
+        bgt             1b
+        bx              lr
+endfunc
+
+function ff_scalarproduct_float_neon, export=1
+        vmov.f32        q2,  #0.0
+1:      vld1.32         {q0},[r0,:128]!
+        vld1.32         {q1},[r1,:128]!
+        vmla.f32        q2,  q0,  q1
+        subs            r2,  r2,  #4
+        bgt             1b
+        vadd.f32        d0,  d4,  d5
+        vpadd.f32       d0,  d0,  d0
+NOVFP   vmov.32         r0,  d0[0]
+        bx              lr
+endfunc
diff --git a/libavutil/arm/float_dsp_vfp.S b/libavutil/arm/float_dsp_vfp.S
index 3931828..8295280 100644
--- a/libavutil/arm/float_dsp_vfp.S
+++ b/libavutil/arm/float_dsp_vfp.S
@@ -66,3 +66,72 @@ function ff_vector_fmul_vfp, export=1
         vpop            {d8-d15}
         bx              lr
 endfunc
+
+/**
+ * ARM VFP optimized implementation of 'vector_fmul_reverse_c' function.
+ * Assume that len is a positive number and is multiple of 8
+ */
+@ void ff_vector_fmul_reverse_vfp(float *dst, const float *src0,
+@                                 const float *src1, int len)
+function ff_vector_fmul_reverse_vfp, export=1
+        vpush           {d8-d15}
+        add             r2,  r2,  r3, lsl #2
+        vldmdb          r2!, {s0-s3}
+        vldmia          r1!, {s8-s11}
+        vldmdb          r2!, {s4-s7}
+        vldmia          r1!, {s12-s15}
+        vmul.f32        s8,  s3,  s8
+        vmul.f32        s9,  s2,  s9
+        vmul.f32        s10, s1,  s10
+        vmul.f32        s11, s0,  s11
+1:
+        subs            r3,  r3,  #16
+        it              ge
+        vldmdbge        r2!, {s16-s19}
+        vmul.f32        s12, s7,  s12
+        it              ge
+        vldmiage        r1!, {s24-s27}
+        vmul.f32        s13, s6,  s13
+        it              ge
+        vldmdbge        r2!, {s20-s23}
+        vmul.f32        s14, s5,  s14
+        it              ge
+        vldmiage        r1!, {s28-s31}
+        vmul.f32        s15, s4,  s15
+        it              ge
+        vmulge.f32      s24, s19, s24
+        it              gt
+        vldmdbgt        r2!, {s0-s3}
+        it              ge
+        vmulge.f32      s25, s18, s25
+        vstmia          r0!, {s8-s13}
+        it              ge
+        vmulge.f32      s26, s17, s26
+        it              gt
+        vldmiagt        r1!, {s8-s11}
+        itt             ge
+        vmulge.f32      s27, s16, s27
+        vmulge.f32      s28, s23, s28
+        it              gt
+        vldmdbgt        r2!, {s4-s7}
+        it              ge
+        vmulge.f32      s29, s22, s29
+        vstmia          r0!, {s14-s15}
+        ittt            ge
+        vmulge.f32      s30, s21, s30
+        vmulge.f32      s31, s20, s31
+        vmulge.f32      s8,  s3,  s8
+        it              gt
+        vldmiagt        r1!, {s12-s15}
+        itttt           ge
+        vmulge.f32      s9,  s2,  s9
+        vmulge.f32      s10, s1,  s10
+        vstmiage        r0!, {s24-s27}
+        vmulge.f32      s11, s0,  s11
+        it              ge
+        vstmiage        r0!, {s28-s31}
+        bgt             1b
+
+        vpop            {d8-d15}
+        bx              lr
+endfunc
diff --git a/libavutil/atomic.c b/libavutil/atomic.c
new file mode 100644
index 0000000..add489a
--- /dev/null
+++ b/libavutil/atomic.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2012 Ronald S. Bultje <rsbultje at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "atomic.h"
+
+#if !HAVE_ATOMICS_NATIVE
+
+#if HAVE_PTHREADS
+
+#include <pthread.h>
+
+static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER;
+
+int avpriv_atomic_int_get(volatile int *ptr)
+{
+    int res;
+
+    pthread_mutex_lock(&atomic_lock);
+    res = *ptr;
+    pthread_mutex_unlock(&atomic_lock);
+
+    return res;
+}
+
+void avpriv_atomic_int_set(volatile int *ptr, int val)
+{
+    pthread_mutex_lock(&atomic_lock);
+    *ptr = val;
+    pthread_mutex_unlock(&atomic_lock);
+}
+
+int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc)
+{
+    int res;
+
+    pthread_mutex_lock(&atomic_lock);
+    *ptr += inc;
+    res = *ptr;
+    pthread_mutex_unlock(&atomic_lock);
+
+    return res;
+}
+
+void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
+{
+    void *ret;
+    pthread_mutex_lock(&atomic_lock);
+    ret = *ptr;
+    if (*ptr == oldval)
+        *ptr = newval;
+    pthread_mutex_unlock(&atomic_lock);
+    return ret;
+}
+
+#elif !HAVE_THREADS
+
+int avpriv_atomic_int_get(volatile int *ptr)
+{
+    return *ptr;
+}
+
+void avpriv_atomic_int_set(volatile int *ptr, int val)
+{
+    *ptr = val;
+}
+
+int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc)
+{
+    *ptr += inc;
+    return *ptr;
+}
+
+void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
+{
+    if (*ptr == oldval) {
+        *ptr = newval;
+        return oldval;
+    }
+    return *ptr;
+}
+
+#else
+
+#error "Threading is enabled, but there is no implementation of atomic operations available"
+
+#endif /* HAVE_PTHREADS */
+
+#endif /* !HAVE_MEMORYBARRIER && !HAVE_SYNC_VAL_COMPARE_AND_SWAP && !HAVE_MACHINE_RW_BARRIER */
+
+#ifdef TEST
+#include <assert.h>
+
+int main(void)
+{
+    volatile int val = 1;
+    int res;
+
+    res = avpriv_atomic_int_add_and_fetch(&val, 1);
+    assert(res == 2);
+    avpriv_atomic_int_set(&val, 3);
+    res = avpriv_atomic_int_get(&val);
+    assert(res == 3);
+
+    return 0;
+}
+#endif
diff --git a/libavutil/atomic.h b/libavutil/atomic.h
new file mode 100644
index 0000000..a5c5fe8
--- /dev/null
+++ b/libavutil/atomic.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012 Ronald S. Bultje <rsbultje at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_ATOMIC_H
+#define AVUTIL_ATOMIC_H
+
+#include "config.h"
+
+#if HAVE_ATOMICS_GCC
+#include "atomic_gcc.h"
+#elif HAVE_ATOMICS_WIN32
+#include "atomic_win32.h"
+#elif HAVE_ATOMICS_SUNCC
+#include "atomic_suncc.h"
+#else
+
+/**
+ * Load the current value stored in an atomic integer.
+ *
+ * @param ptr atomic integer
+ * @return the current value of the atomic integer
+ * @note This acts as a memory barrier.
+ */
+int avpriv_atomic_int_get(volatile int *ptr);
+
+/**
+ * Store a new value in an atomic integer.
+ *
+ * @param ptr atomic integer
+ * @param val the value to store in the atomic integer
+ * @note This acts as a memory barrier.
+ */
+void avpriv_atomic_int_set(volatile int *ptr, int val);
+
+/**
+ * Add a value to an atomic integer.
+ *
+ * @param ptr atomic integer
+ * @param inc the value to add to the atomic integer (may be negative)
+ * @return the new value of the atomic integer.
+ * @note This does NOT act as a memory barrier. This is primarily
+ *       intended for reference counting.
+ */
+int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc);
+
+/**
+ * Atomic pointer compare and swap.
+ *
+ * @param ptr pointer to the pointer to operate on
+ * @param oldval do the swap if the current value of *ptr equals to oldval
+ * @param newval value to replace *ptr with
+ * @return the value of *ptr before comparison
+ */
+void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval);
+
+#endif /* HAVE_MEMORYBARRIER */
+#endif /* AVUTIL_ATOMIC_H */
diff --git a/libavutil/atomic_gcc.h b/libavutil/atomic_gcc.h
new file mode 100644
index 0000000..9470e8e
--- /dev/null
+++ b/libavutil/atomic_gcc.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012 Ronald S. Bultje <rsbultje at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_ATOMIC_GCC_H
+#define AVUTIL_ATOMIC_GCC_H
+
+#include <stdint.h>
+
+#include "atomic.h"
+
+#define avpriv_atomic_int_get atomic_int_get_gcc
+static inline int atomic_int_get_gcc(volatile int *ptr)
+{
+    __sync_synchronize();
+    return *ptr;
+}
+
+#define avpriv_atomic_int_set atomic_int_set_gcc
+static inline void atomic_int_set_gcc(volatile int *ptr, int val)
+{
+    *ptr = val;
+    __sync_synchronize();
+}
+
+#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_gcc
+static inline int atomic_int_add_and_fetch_gcc(volatile int *ptr, int inc)
+{
+    return __sync_add_and_fetch(ptr, inc);
+}
+
+#define avpriv_atomic_ptr_cas atomic_ptr_cas_gcc
+static inline void *atomic_ptr_cas_gcc(void * volatile *ptr,
+                                       void *oldval, void *newval)
+{
+#ifdef __ARMCC_VERSION
+    // armcc will throw an error if ptr is not an integer type
+    volatile uintptr_t *tmp = (volatile uintptr_t*)ptr;
+    return (void*)__sync_val_compare_and_swap(tmp, oldval, newval);
+#else
+    return __sync_val_compare_and_swap(ptr, oldval, newval);
+#endif
+}
+
+#endif /* AVUTIL_ATOMIC_GCC_H */
diff --git a/libavutil/atomic_suncc.h b/libavutil/atomic_suncc.h
new file mode 100644
index 0000000..5c11b57
--- /dev/null
+++ b/libavutil/atomic_suncc.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * 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 AVUTIL_ATOMIC_SUNCC_H
+#define AVUTIL_ATOMIC_SUNCC_H
+
+#include <atomic.h>
+#include <mbarrier.h>
+
+#include "atomic.h"
+
+#define avpriv_atomic_int_get atomic_int_get_suncc
+static inline int atomic_int_get_suncc(volatile int *ptr)
+{
+    __machine_rw_barrier();
+    return *ptr;
+}
+
+#define avpriv_atomic_int_set atomic_int_set_suncc
+static inline void atomic_int_set_suncc(volatile int *ptr, int val)
+{
+    *ptr = val;
+    __machine_rw_barrier();
+}
+
+#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_suncc
+static inline int atomic_int_add_and_fetch_suncc(volatile int *ptr, int inc)
+{
+    return atomic_add_int_nv(ptr, inc);
+}
+
+#define avpriv_atomic_ptr_cas atomic_ptr_cas_suncc
+static inline void *atomic_ptr_cas_suncc(void * volatile *ptr,
+                                         void *oldval, void *newval)
+{
+    return atomic_cas_ptr(ptr, oldval, newval);
+}
+
+#endif /* AVUTIL_ATOMIC_SUNCC_H */
diff --git a/libavutil/atomic_win32.h b/libavutil/atomic_win32.h
new file mode 100644
index 0000000..84e8b7f
--- /dev/null
+++ b/libavutil/atomic_win32.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 Ronald S. Bultje <rsbultje at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_ATOMIC_WIN32_H
+#define AVUTIL_ATOMIC_WIN32_H
+
+#include <windows.h>
+
+#include "atomic.h"
+
+#define avpriv_atomic_int_get atomic_int_get_win32
+static inline int atomic_int_get_win32(volatile int *ptr)
+{
+    MemoryBarrier();
+    return *ptr;
+}
+
+#define avpriv_atomic_int_set atomic_int_set_win32
+static inline void atomic_int_set_win32(volatile int *ptr, int val)
+{
+    *ptr = val;
+    MemoryBarrier();
+}
+
+#define avpriv_atomic_int_add_and_fetch atomic_int_add_and_fetch_win32
+static inline int atomic_int_add_and_fetch_win32(volatile int *ptr, int inc)
+{
+    return inc + InterlockedExchangeAdd(ptr, inc);
+}
+
+#define avpriv_atomic_ptr_cas atomic_ptr_cas_win32
+static inline void *atomic_ptr_cas_win32(void * volatile *ptr,
+                                         void *oldval, void *newval)
+{
+    return InterlockedCompareExchangePointer(ptr, newval, oldval);
+}
+
+#endif /* AVUTIL_ATOMIC_WIN32_H */
diff --git a/libavutil/attributes.h b/libavutil/attributes.h
index 292a0a1..d7f2bb5 100644
--- a/libavutil/attributes.h
+++ b/libavutil/attributes.h
@@ -42,6 +42,8 @@
 
 #if AV_GCC_VERSION_AT_LEAST(3,1)
 #    define av_noinline __attribute__((noinline))
+#elif defined(_MSC_VER)
+#    define av_noinline __declspec(noinline)
 #else
 #    define av_noinline
 #endif
@@ -64,7 +66,7 @@
 #    define av_cold
 #endif
 
-#if AV_GCC_VERSION_AT_LEAST(4,1)
+#if AV_GCC_VERSION_AT_LEAST(4,1) && !defined(__llvm__)
 #    define av_flatten __attribute__((flatten))
 #else
 #    define av_flatten
@@ -72,6 +74,8 @@
 
 #if AV_GCC_VERSION_AT_LEAST(3,1)
 #    define attribute_deprecated __attribute__((deprecated))
+#elif defined(_MSC_VER)
+#    define attribute_deprecated __declspec(deprecated)
 #else
 #    define attribute_deprecated
 #endif
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 2c88bd3..3ea7be0 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -23,11 +23,11 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
-#include <ctype.h>
-#include "avstring.h"
+
 #include "config.h"
 #include "common.h"
 #include "mem.h"
+#include "avstring.h"
 
 int av_strstart(const char *str, const char *pfx, const char **ptr)
 {
@@ -42,7 +42,7 @@ int av_strstart(const char *str, const char *pfx, const char **ptr)
 
 int av_stristart(const char *str, const char *pfx, const char **ptr)
 {
-    while (*pfx && toupper((unsigned)*pfx) == toupper((unsigned)*str)) {
+    while (*pfx && av_toupper((unsigned)*pfx) == av_toupper((unsigned)*str)) {
         pfx++;
         str++;
     }
@@ -56,11 +56,25 @@ char *av_stristr(const char *s1, const char *s2)
     if (!*s2)
         return s1;
 
-    do {
+    do
         if (av_stristart(s1, s2, NULL))
             return s1;
-    } while (*s1++);
+    while (*s1++);
+
+    return NULL;
+}
 
+char *av_strnstr(const char *haystack, const char *needle, size_t hay_length)
+{
+    size_t needle_len = strlen(needle);
+    if (!needle_len)
+        return haystack;
+    while (hay_length >= needle_len) {
+        hay_length--;
+        if (!memcmp(haystack, needle, needle_len))
+            return haystack;
+        haystack++;
+    }
     return NULL;
 }
 
@@ -96,8 +110,9 @@ size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...)
 
 char *av_d2str(double d)
 {
-    char *str= av_malloc(16);
-    if(str) snprintf(str, 16, "%f", d);
+    char *str = av_malloc(16);
+    if (str)
+        snprintf(str, 16, "%f", d);
     return str;
 }
 
@@ -105,32 +120,33 @@ char *av_d2str(double d)
 
 char *av_get_token(const char **buf, const char *term)
 {
-    char *out = av_malloc(strlen(*buf) + 1);
-    char *ret= out, *end= out;
+    char *out     = av_malloc(strlen(*buf) + 1);
+    char *ret     = out, *end = out;
     const char *p = *buf;
-    if (!out) return NULL;
+    if (!out)
+        return NULL;
     p += strspn(p, WHITESPACES);
 
-    while(*p && !strspn(p, term)) {
+    while (*p && !strspn(p, term)) {
         char c = *p++;
-        if(c == '\\' && *p){
+        if (c == '\\' && *p) {
             *out++ = *p++;
-            end= out;
-        }else if(c == '\''){
-            while(*p && *p != '\'')
+            end    = out;
+        } else if (c == '\'') {
+            while (*p && *p != '\'')
                 *out++ = *p++;
-            if(*p){
+            if (*p) {
                 p++;
-                end= out;
+                end = out;
             }
-        }else{
+        } else {
             *out++ = c;
         }
     }
 
-    do{
+    do
         *out-- = 0;
-    }while(out >= end && strspn(out, WHITESPACES));
+    while (out >= end && strspn(out, WHITESPACES));
 
     *buf = p;
 
@@ -196,54 +212,71 @@ const char *av_dirname(char *path)
     return path;
 }
 
+int av_isdigit(int c)
+{
+    return c >= '0' && c <= '9';
+}
 
-#ifdef TEST
+int av_isgraph(int c)
+{
+    return c > 32 && c < 127;
+}
 
-#include "common.h"
+int av_isspace(int c)
+{
+    return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' ||
+           c == '\v';
+}
+
+int av_isxdigit(int c)
+{
+    c = av_tolower(c);
+    return av_isdigit(c) || (c >= 'a' && c <= 'f');
+}
+
+#ifdef TEST
 
 int main(void)
 {
     int i;
+    const char *strings[] = {
+        "''",
+        "",
+        ":",
+        "\\",
+        "'",
+        "    ''    :",
+        "    ''  ''  :",
+        "foo   '' :",
+        "'foo'",
+        "foo     ",
+        "  '  foo  '  ",
+        "foo\\",
+        "foo':  blah:blah",
+        "foo\\:  blah:blah",
+        "foo\'",
+        "'foo :  '  :blahblah",
+        "\\ :blah",
+        "     foo",
+        "      foo       ",
+        "      foo     \\ ",
+        "foo ':blah",
+        " foo   bar    :   blahblah",
+        "\\f\\o\\o",
+        "'foo : \\ \\  '   : blahblah",
+        "'\\fo\\o:': blahblah",
+        "\\'fo\\o\\:':  foo  '  :blahblah"
+    };
 
     printf("Testing av_get_token()\n");
-    {
-        const char *strings[] = {
-            "''",
-            "",
-            ":",
-            "\\",
-            "'",
-            "    ''    :",
-            "    ''  ''  :",
-            "foo   '' :",
-            "'foo'",
-            "foo     ",
-            "  '  foo  '  ",
-            "foo\\",
-            "foo':  blah:blah",
-            "foo\\:  blah:blah",
-            "foo\'",
-            "'foo :  '  :blahblah",
-            "\\ :blah",
-            "     foo",
-            "      foo       ",
-            "      foo     \\ ",
-            "foo ':blah",
-            " foo   bar    :   blahblah",
-            "\\f\\o\\o",
-            "'foo : \\ \\  '   : blahblah",
-            "'\\fo\\o:': blahblah",
-            "\\'fo\\o\\:':  foo  '  :blahblah"
-        };
-
-        for (i=0; i < FF_ARRAY_ELEMS(strings); i++) {
-            const char *p = strings[i], *q;
-            printf("|%s|", p);
-            q = av_get_token(&p, ":");
-            printf(" -> |%s|", q);
-            printf(" + |%s|\n", p);
-            av_free(q);
-        }
+    for (i = 0; i < FF_ARRAY_ELEMS(strings); i++) {
+        const char *p = strings[i];
+        char *q;
+        printf("|%s|", p);
+        q = av_get_token(&p, ":");
+        printf(" -> |%s|", q);
+        printf(" + |%s|\n", p);
+        av_free(q);
     }
 
     return 0;
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index acd6610..b7d1098 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -67,6 +67,21 @@ int av_stristart(const char *str, const char *pfx, const char **ptr);
 char *av_stristr(const char *haystack, const char *needle);
 
 /**
+ * Locate the first occurrence of the string needle in the string haystack
+ * where not more than hay_length characters are searched. A zero-length
+ * string needle is considered to match at the start of haystack.
+ *
+ * This function is a length-limited version of the standard strstr().
+ *
+ * @param haystack   string to search in
+ * @param needle     string to search for
+ * @param hay_length length of string to search in
+ * @return           pointer to the located match within haystack
+ *                   or a null pointer if no match
+ */
+char *av_strnstr(const char *haystack, const char *needle, size_t hay_length);
+
+/**
  * Copy the string src to dst, but no more than size - 1 bytes, and
  * null-terminate dst.
  *
@@ -137,6 +152,21 @@ char *av_d2str(double d);
 char *av_get_token(const char **buf, const char *term);
 
 /**
+ * Locale-independent conversion of ASCII isdigit.
+ */
+int av_isdigit(int c);
+
+/**
+ * Locale-independent conversion of ASCII isgraph.
+ */
+int av_isgraph(int c);
+
+/**
+ * Locale-independent conversion of ASCII isspace.
+ */
+int av_isspace(int c);
+
+/**
  * Locale-independent conversion of ASCII characters to uppercase.
  */
 static inline int av_toupper(int c)
@@ -156,6 +186,11 @@ static inline int av_tolower(int c)
     return c;
 }
 
+/**
+ * Locale-independent conversion of ASCII isxdigit.
+ */
+int av_isxdigit(int 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 33f9bea..782284d 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -35,12 +35,45 @@
  * provided by Libav.
  *
  * @li @ref libavc "libavcodec" encoding/decoding library
- * @li @subpage libavfilter graph based frame editing library
+ * @li @ref lavfi "libavfilter" graph-based frame editing library
  * @li @ref libavf "libavformat" I/O and muxing/demuxing library
  * @li @ref lavd "libavdevice" special devices muxing/demuxing library
  * @li @ref lavu "libavutil" common utility library
  * @li @ref lavr "libavresample" audio resampling, format conversion and mixing
- * @li @subpage libswscale  color conversion and scaling library
+ * @li @ref libsws "libswscale"  color conversion and scaling library
+ *
+ * @section libav_versioning Versioning and compatibility
+ *
+ * Each of the Libav libraries contains a version.h header, which defines a
+ * major, minor and micro version number with the
+ * <em>LIBRARYNAME_VERSION_{MAJOR,MINOR,MICRO}</em> macros. The major version
+ * number is incremented with backward incompatible changes - e.g. removing
+ * parts of the public API, reordering public struct members, etc. The minor
+ * version number is incremented for backward compatible API changes or major
+ * new features - e.g. adding a new public function or a new decoder. The micro
+ * version number is incremented for smaller changes that a calling program
+ * might still want to check for - e.g. changing behavior in a previously
+ * unspecified situation.
+ *
+ * Libav guarantees backward API and ABI compatibility for each library as long
+ * as its major version number is unchanged. This means that no public symbols
+ * will be removed or renamed. Types and names of the public struct members and
+ * values of public macros and enums will remain the same (unless they were
+ * explicitly declared as not part of the public API). Documented behavior will
+ * not change.
+ *
+ * In other words, any correct program that works with a given Libav snapshot
+ * should work just as well without any changes with any later snapshot with the
+ * same major versions. This applies to both rebuilding the program against new
+ * Libav versions or to replacing the dynamic Libav libraries that a program
+ * links against.
+ *
+ * However, new public symbols may be added and new members may be appended to
+ * public structs whose size is not part of public ABI (most public structs in
+ * Libav). New macros and enum values may be added. Behavior in undocumented
+ * situations may change slightly (and be documented). All those are accompanied
+ * by an entry in doc/APIchanges and incrementing either the minor or micro
+ * version number.
  */
 
 /**
@@ -94,6 +127,12 @@
  *
  * @}
  *
+ * @defgroup lavu_log Logging Facility
+ *
+ * @{
+ *
+ * @}
+ *
  * @defgroup lavu_misc Other
  *
  * @{
diff --git a/libavutil/base64.c b/libavutil/base64.c
index d16195f..725b035 100644
--- a/libavutil/base64.c
+++ b/libavutil/base64.c
@@ -156,7 +156,10 @@ int main(void)
     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);
 
-    return error_count;
+    if (error_count)
+        printf("Error Count: %d.\n", error_count);
+
+    return !!error_count;
 }
 
 #endif
diff --git a/libavutil/blowfish.c b/libavutil/blowfish.c
index 63cc404..8437dd6 100644
--- a/libavutil/blowfish.c
+++ b/libavutil/blowfish.c
@@ -21,10 +21,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/intreadwrite.h"
-
 #include "avutil.h"
 #include "common.h"
+#include "intreadwrite.h"
 #include "blowfish.h"
 
 static const uint32_t orig_p[AV_BF_ROUNDS + 2] = {
diff --git a/libavutil/buffer.c b/libavutil/buffer.c
new file mode 100644
index 0000000..2b38081
--- /dev/null
+++ b/libavutil/buffer.c
@@ -0,0 +1,337 @@
+/*
+ * 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 <string.h>
+
+#include "atomic.h"
+#include "buffer_internal.h"
+#include "common.h"
+#include "mem.h"
+
+AVBufferRef *av_buffer_create(uint8_t *data, int size,
+                              void (*free)(void *opaque, uint8_t *data),
+                              void *opaque, int flags)
+{
+    AVBufferRef *ref = NULL;
+    AVBuffer    *buf = NULL;
+
+    buf = av_mallocz(sizeof(*buf));
+    if (!buf)
+        return NULL;
+
+    buf->data     = data;
+    buf->size     = size;
+    buf->free     = free ? free : av_buffer_default_free;
+    buf->opaque   = opaque;
+    buf->refcount = 1;
+
+    if (flags & AV_BUFFER_FLAG_READONLY)
+        buf->flags |= BUFFER_FLAG_READONLY;
+
+    ref = av_mallocz(sizeof(*ref));
+    if (!ref) {
+        av_freep(&buf);
+        return NULL;
+    }
+
+    ref->buffer = buf;
+    ref->data   = data;
+    ref->size   = size;
+
+    return ref;
+}
+
+void av_buffer_default_free(void *opaque, uint8_t *data)
+{
+    av_free(data);
+}
+
+AVBufferRef *av_buffer_alloc(int size)
+{
+    AVBufferRef *ret = NULL;
+    uint8_t    *data = NULL;
+
+    data = av_malloc(size);
+    if (!data)
+        return NULL;
+
+    ret = av_buffer_create(data, size, av_buffer_default_free, NULL, 0);
+    if (!ret)
+        av_freep(&data);
+
+    return ret;
+}
+
+AVBufferRef *av_buffer_allocz(int size)
+{
+    AVBufferRef *ret = av_buffer_alloc(size);
+    if (!ret)
+        return NULL;
+
+    memset(ret->data, 0, size);
+    return ret;
+}
+
+AVBufferRef *av_buffer_ref(AVBufferRef *buf)
+{
+    AVBufferRef *ret = av_mallocz(sizeof(*ret));
+
+    if (!ret)
+        return NULL;
+
+    *ret = *buf;
+
+    avpriv_atomic_int_add_and_fetch(&buf->buffer->refcount, 1);
+
+    return ret;
+}
+
+void av_buffer_unref(AVBufferRef **buf)
+{
+    AVBuffer *b;
+
+    if (!buf || !*buf)
+        return;
+    b = (*buf)->buffer;
+    av_freep(buf);
+
+    if (!avpriv_atomic_int_add_and_fetch(&b->refcount, -1)) {
+        b->free(b->opaque, b->data);
+        av_freep(&b);
+    }
+}
+
+int av_buffer_is_writable(const AVBufferRef *buf)
+{
+    if (buf->buffer->flags & AV_BUFFER_FLAG_READONLY)
+        return 0;
+
+    return avpriv_atomic_int_add_and_fetch(&buf->buffer->refcount, 0) == 1;
+}
+
+int av_buffer_make_writable(AVBufferRef **pbuf)
+{
+    AVBufferRef *newbuf, *buf = *pbuf;
+
+    if (av_buffer_is_writable(buf))
+        return 0;
+
+    newbuf = av_buffer_alloc(buf->size);
+    if (!newbuf)
+        return AVERROR(ENOMEM);
+
+    memcpy(newbuf->data, buf->data, buf->size);
+    av_buffer_unref(pbuf);
+    *pbuf = newbuf;
+
+    return 0;
+}
+
+int av_buffer_realloc(AVBufferRef **pbuf, int size)
+{
+    AVBufferRef *buf = *pbuf;
+    uint8_t *tmp;
+
+    if (!buf) {
+        /* allocate a new buffer with av_realloc(), so it will be reallocatable
+         * later */
+        uint8_t *data = av_realloc(NULL, size);
+        if (!data)
+            return AVERROR(ENOMEM);
+
+        buf = av_buffer_create(data, size, av_buffer_default_free, NULL, 0);
+        if (!buf) {
+            av_freep(&data);
+            return AVERROR(ENOMEM);
+        }
+
+        buf->buffer->flags |= BUFFER_FLAG_REALLOCATABLE;
+        *pbuf = buf;
+
+        return 0;
+    } else if (buf->size == size)
+        return 0;
+
+    if (!(buf->buffer->flags & BUFFER_FLAG_REALLOCATABLE) ||
+        !av_buffer_is_writable(buf)) {
+        /* cannot realloc, allocate a new reallocable buffer and copy data */
+        AVBufferRef *new = NULL;
+
+        av_buffer_realloc(&new, size);
+        if (!new)
+            return AVERROR(ENOMEM);
+
+        memcpy(new->data, buf->data, FFMIN(size, buf->size));
+
+        av_buffer_unref(pbuf);
+        *pbuf = new;
+        return 0;
+    }
+
+    tmp = av_realloc(buf->buffer->data, size);
+    if (!tmp)
+        return AVERROR(ENOMEM);
+
+    buf->buffer->data = buf->data = tmp;
+    buf->buffer->size = buf->size = size;
+    return 0;
+}
+
+AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size))
+{
+    AVBufferPool *pool = av_mallocz(sizeof(*pool));
+    if (!pool)
+        return NULL;
+
+    pool->size     = size;
+    pool->alloc    = alloc ? alloc : av_buffer_alloc;
+
+    avpriv_atomic_int_set(&pool->refcount, 1);
+
+    return pool;
+}
+
+/*
+ * This function gets called when the pool has been uninited and
+ * all the buffers returned to it.
+ */
+static void buffer_pool_free(AVBufferPool *pool)
+{
+    while (pool->pool) {
+        BufferPoolEntry *buf = pool->pool;
+        pool->pool = buf->next;
+
+        buf->free(buf->opaque, buf->data);
+        av_freep(&buf);
+    }
+    av_freep(&pool);
+}
+
+void av_buffer_pool_uninit(AVBufferPool **ppool)
+{
+    AVBufferPool *pool;
+
+    if (!ppool || !*ppool)
+        return;
+    pool   = *ppool;
+    *ppool = NULL;
+
+    if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1))
+        buffer_pool_free(pool);
+}
+
+/* remove the whole buffer list from the pool and return it */
+static BufferPoolEntry *get_pool(AVBufferPool *pool)
+{
+    BufferPoolEntry *cur = NULL, *last = NULL;
+
+    do {
+        FFSWAP(BufferPoolEntry*, cur, last);
+        cur = avpriv_atomic_ptr_cas((void * volatile *)&pool->pool, last, NULL);
+        if (!cur)
+            return NULL;
+    } while (cur != last);
+
+    return cur;
+}
+
+static void add_to_pool(BufferPoolEntry *buf)
+{
+    AVBufferPool *pool;
+    BufferPoolEntry *cur, *end = buf;
+
+    if (!buf)
+        return;
+    pool = buf->pool;
+
+    while (end->next)
+        end = end->next;
+
+    while ((cur = avpriv_atomic_ptr_cas((void * volatile *)&pool->pool, NULL, buf))) {
+        /* pool is not empty, retrieve it and append it to our list */
+        cur = get_pool(pool);
+        end->next = cur;
+        while (end->next)
+            end = end->next;
+    }
+}
+
+static void pool_release_buffer(void *opaque, uint8_t *data)
+{
+    BufferPoolEntry *buf = opaque;
+    AVBufferPool *pool = buf->pool;
+    add_to_pool(buf);
+    if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1))
+        buffer_pool_free(pool);
+}
+
+/* allocate a new buffer and override its free() callback so that
+ * it is returned to the pool on free */
+static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool)
+{
+    BufferPoolEntry *buf;
+    AVBufferRef     *ret;
+
+    ret = pool->alloc(pool->size);
+    if (!ret)
+        return NULL;
+
+    buf = av_mallocz(sizeof(*buf));
+    if (!buf) {
+        av_buffer_unref(&ret);
+        return NULL;
+    }
+
+    buf->data   = ret->buffer->data;
+    buf->opaque = ret->buffer->opaque;
+    buf->free   = ret->buffer->free;
+    buf->pool   = pool;
+
+    ret->buffer->opaque = buf;
+    ret->buffer->free   = pool_release_buffer;
+
+    avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
+
+    return ret;
+}
+
+AVBufferRef *av_buffer_pool_get(AVBufferPool *pool)
+{
+    AVBufferRef *ret;
+    BufferPoolEntry *buf;
+
+    /* check whether the pool is empty */
+    buf = get_pool(pool);
+    if (!buf)
+        return pool_alloc_buffer(pool);
+
+    /* keep the first entry, return the rest of the list to the pool */
+    add_to_pool(buf->next);
+    buf->next = NULL;
+
+    ret = av_buffer_create(buf->data, pool->size, pool_release_buffer,
+                           buf, 0);
+    if (!ret) {
+        add_to_pool(buf);
+        return NULL;
+    }
+    avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
+
+    return ret;
+}
diff --git a/libavutil/buffer.h b/libavutil/buffer.h
new file mode 100644
index 0000000..56b4d02
--- /dev/null
+++ b/libavutil/buffer.h
@@ -0,0 +1,267 @@
+/*
+ * 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
+ * @ingroup lavu_buffer
+ * refcounted data buffer API
+ */
+
+#ifndef AVUTIL_BUFFER_H
+#define AVUTIL_BUFFER_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavu_buffer AVBuffer
+ * @ingroup lavu_data
+ *
+ * @{
+ * AVBuffer is an API for reference-counted data buffers.
+ *
+ * There are two core objects in this API -- AVBuffer and AVBufferRef. AVBuffer
+ * represents the data buffer itself; it is opaque and not meant to be accessed
+ * by the caller directly, but only through AVBufferRef. However, the caller may
+ * e.g. compare two AVBuffer pointers to check whether two different references
+ * are describing the same data buffer. AVBufferRef represents a single
+ * reference to an AVBuffer and it is the object that may be manipulated by the
+ * caller directly.
+ *
+ * There are two functions provided for creating a new AVBuffer with a single
+ * reference -- av_buffer_alloc() to just allocate a new buffer, and
+ * av_buffer_create() to wrap an existing array in an AVBuffer. From an existing
+ * reference, additional references may be created with av_buffer_ref().
+ * Use av_buffer_unref() to free a reference (this will automatically free the
+ * data once all the references are freed).
+ *
+ * The convention throughout this API and the rest of Libav is such that the
+ * buffer is considered writable if there exists only one reference to it (and
+ * it has not been marked as read-only). The av_buffer_is_writable() function is
+ * provided to check whether this is true and av_buffer_make_writable() will
+ * automatically create a new writable buffer when necessary.
+ * Of course nothing prevents the calling code from violating this convention,
+ * however that is safe only when all the existing references are under its
+ * control.
+ *
+ * @note Referencing and unreferencing the buffers is thread-safe and thus
+ * may be done from multiple threads simultaneously without any need for
+ * additional locking.
+ *
+ * @note Two different references to the same buffer can point to different
+ * parts of the buffer (i.e. their AVBufferRef.data will not be equal).
+ */
+
+/**
+ * A reference counted buffer type. It is opaque and is meant to be used through
+ * references (AVBufferRef).
+ */
+typedef struct AVBuffer AVBuffer;
+
+/**
+ * A reference to a data buffer.
+ *
+ * The size of this struct is not a part of the public ABI and it is not meant
+ * to be allocated directly.
+ */
+typedef struct AVBufferRef {
+    AVBuffer *buffer;
+
+    /**
+     * The data buffer. It is considered writable if and only if
+     * this is the only reference to the buffer, in which case
+     * av_buffer_is_writable() returns 1.
+     */
+    uint8_t *data;
+    /**
+     * Size of data in bytes.
+     */
+    int      size;
+} AVBufferRef;
+
+/**
+ * Allocate an AVBuffer of the given size using av_malloc().
+ *
+ * @return an AVBufferRef of given size or NULL when out of memory
+ */
+AVBufferRef *av_buffer_alloc(int size);
+
+/**
+ * Same as av_buffer_alloc(), except the returned buffer will be initialized
+ * to zero.
+ */
+AVBufferRef *av_buffer_allocz(int size);
+
+/**
+ * Always treat the buffer as read-only, even when it has only one
+ * reference.
+ */
+#define AV_BUFFER_FLAG_READONLY (1 << 0)
+
+/**
+ * Create an AVBuffer from an existing array.
+ *
+ * If this function is successful, data is owned by the AVBuffer. The caller may
+ * only access data through the returned AVBufferRef and references derived from
+ * it.
+ * If this function fails, data is left untouched.
+ * @param data   data array
+ * @param size   size of data in bytes
+ * @param free   a callback for freeing this buffer's data
+ * @param opaque parameter to be passed to free
+ * @param flags  a combination of AV_BUFFER_FLAG_*
+ *
+ * @return an AVBufferRef referring to data on success, NULL on failure.
+ */
+AVBufferRef *av_buffer_create(uint8_t *data, int size,
+                              void (*free)(void *opaque, uint8_t *data),
+                              void *opaque, int flags);
+
+/**
+ * Default free callback, which calls av_free() on the buffer data.
+ * This function is meant to be passed to av_buffer_create(), not called
+ * directly.
+ */
+void av_buffer_default_free(void *opaque, uint8_t *data);
+
+/**
+ * Create a new reference to an AVBuffer.
+ *
+ * @return a new AVBufferRef referring to the same AVBuffer as buf or NULL on
+ * failure.
+ */
+AVBufferRef *av_buffer_ref(AVBufferRef *buf);
+
+/**
+ * Free a given reference and automatically free the buffer if there are no more
+ * references to it.
+ *
+ * @param buf the reference to be freed. The pointer is set to NULL on return.
+ */
+void av_buffer_unref(AVBufferRef **buf);
+
+/**
+ * @return 1 if the caller may write to the data referred to by buf (which is
+ * true if and only if buf is the only reference to the underlying AVBuffer).
+ * Return 0 otherwise.
+ * A positive answer is valid until av_buffer_ref() is called on buf.
+ */
+int av_buffer_is_writable(const AVBufferRef *buf);
+
+/**
+ * Create a writable reference from a given buffer reference, avoiding data copy
+ * if possible.
+ *
+ * @param buf buffer reference to make writable. On success, buf is either left
+ *            untouched, or it is unreferenced and a new writable AVBufferRef is
+ *            written in its place. On failure, buf is left untouched.
+ * @return 0 on success, a negative AVERROR on failure.
+ */
+int av_buffer_make_writable(AVBufferRef **buf);
+
+/**
+ * Reallocate a given buffer.
+ *
+ * @param buf  a buffer reference to reallocate. On success, buf will be
+ *             unreferenced and a new reference with the required size will be
+ *             written in its place. On failure buf will be left untouched. *buf
+ *             may be NULL, then a new buffer is allocated.
+ * @param size required new buffer size.
+ * @return 0 on success, a negative AVERROR on failure.
+ *
+ * @note the buffer is actually reallocated with av_realloc() only if it was
+ * initially allocated through av_buffer_realloc(NULL) and there is only one
+ * reference to it (i.e. the one passed to this function). In all other cases
+ * a new buffer is allocated and the data is copied.
+ */
+int av_buffer_realloc(AVBufferRef **buf, int size);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lavu_bufferpool AVBufferPool
+ * @ingroup lavu_data
+ *
+ * @{
+ * AVBufferPool is an API for a lock-free thread-safe pool of AVBuffers.
+ *
+ * Frequently allocating and freeing large buffers may be slow. AVBufferPool is
+ * meant to solve this in cases when the caller needs a set of buffers of the
+ * same size (the most obvious use case being buffers for raw video or audio
+ * frames).
+ *
+ * At the beginning, the user must call av_buffer_pool_init() to create the
+ * buffer pool. Then whenever a buffer is needed, call av_buffer_pool_get() to
+ * get a reference to a new buffer, similar to av_buffer_alloc(). This new
+ * reference works in all aspects the same way as the one created by
+ * av_buffer_alloc(). However, when the last reference to this buffer is
+ * unreferenced, it is returned to the pool instead of being freed and will be
+ * reused for subsequent av_buffer_pool_get() calls.
+ *
+ * When the caller is done with the pool and no longer needs to allocate any new
+ * buffers, av_buffer_pool_uninit() must be called to mark the pool as freeable.
+ * Once all the buffers are released, it will automatically be freed.
+ *
+ * Allocating and releasing buffers with this API is thread-safe as long as
+ * either the default alloc callback is used, or the user-supplied one is
+ * thread-safe.
+ */
+
+/**
+ * The buffer pool. This structure is opaque and not meant to be accessed
+ * directly. It is allocated with av_buffer_pool_init() and freed with
+ * av_buffer_pool_uninit().
+ */
+typedef struct AVBufferPool AVBufferPool;
+
+/**
+ * Allocate and initialize a buffer pool.
+ *
+ * @param size size of each buffer in this pool
+ * @param alloc a function that will be used to allocate new buffers when the
+ * pool is empty. May be NULL, then the default allocator will be used
+ * (av_buffer_alloc()).
+ * @return newly created buffer pool on success, NULL on error.
+ */
+AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size));
+
+/**
+ * Mark the pool as being available for freeing. It will actually be freed only
+ * once all the allocated buffers associated with the pool are released. Thus it
+ * is safe to call this function while some of the allocated buffers are still
+ * in use.
+ *
+ * @param pool pointer to the pool to be freed. It will be set to NULL.
+ * @see av_buffer_pool_can_uninit()
+ */
+void av_buffer_pool_uninit(AVBufferPool **pool);
+
+/**
+ * Allocate a new AVBuffer, reusing an old buffer from the pool when available.
+ * This function may be called simultaneously from multiple threads.
+ *
+ * @return a reference to the new buffer on success, NULL on error.
+ */
+AVBufferRef *av_buffer_pool_get(AVBufferPool *pool);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_BUFFER_H */
diff --git a/libavutil/buffer_internal.h b/libavutil/buffer_internal.h
new file mode 100644
index 0000000..cce83c3
--- /dev/null
+++ b/libavutil/buffer_internal.h
@@ -0,0 +1,92 @@
+/*
+ * 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 AVUTIL_BUFFER_INTERNAL_H
+#define AVUTIL_BUFFER_INTERNAL_H
+
+#include <stdint.h>
+
+#include "buffer.h"
+
+/**
+ * The buffer is always treated as read-only.
+ */
+#define BUFFER_FLAG_READONLY      (1 << 0)
+/**
+ * The buffer was av_realloc()ed, so it is reallocatable.
+ */
+#define BUFFER_FLAG_REALLOCATABLE (1 << 1)
+
+struct AVBuffer {
+    uint8_t *data; /**< data described by this buffer */
+    int      size; /**< size of data in bytes */
+
+    /**
+     *  number of existing AVBufferRef instances referring to this buffer
+     */
+    volatile int refcount;
+
+    /**
+     * a callback for freeing the data
+     */
+    void (*free)(void *opaque, uint8_t *data);
+
+    /**
+     * an opaque pointer, to be used by the freeing callback
+     */
+    void *opaque;
+
+    /**
+     * A combination of BUFFER_FLAG_*
+     */
+    int flags;
+};
+
+typedef struct BufferPoolEntry {
+    uint8_t *data;
+
+    /*
+     * Backups of the original opaque/free of the AVBuffer corresponding to
+     * data. They will be used to free the buffer when the pool is freed.
+     */
+    void *opaque;
+    void (*free)(void *opaque, uint8_t *data);
+
+    AVBufferPool *pool;
+    struct BufferPoolEntry * volatile next;
+} BufferPoolEntry;
+
+struct AVBufferPool {
+    BufferPoolEntry * volatile pool;
+
+    /*
+     * This is used to track when the pool is to be freed.
+     * The pointer to the pool itself held by the caller is considered to
+     * be one reference. Each buffer requested by the caller increases refcount
+     * by one, returning the buffer to the pool decreases it by one.
+     * refcount reaches zero when the buffer has been uninited AND all the
+     * buffers have been released, then it's safe to free the pool and all
+     * the buffers in it.
+     */
+    volatile int refcount;
+
+    int size;
+    AVBufferRef* (*alloc)(int size);
+};
+
+#endif /* AVUTIL_BUFFER_INTERNAL_H */
diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c
index 79e398e..253c495 100644
--- a/libavutil/channel_layout.c
+++ b/libavutil/channel_layout.c
@@ -23,6 +23,8 @@
  * audio channel layout utility functions
  */
 
+#include <stdint.h>
+
 #include "avstring.h"
 #include "avutil.h"
 #include "channel_layout.h"
diff --git a/libavutil/common.h b/libavutil/common.h
index cc4df16..eb40e12 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -26,11 +26,11 @@
 #ifndef AVUTIL_COMMON_H
 #define AVUTIL_COMMON_H
 
-#include <ctype.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
 #include <math.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 23016d6..25af4c5 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -16,9 +16,31 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "cpu.h"
+#include "cpu_internal.h"
 #include "config.h"
 #include "opt.h"
+#include "common.h"
+
+#if HAVE_SCHED_GETAFFINITY
+#define _GNU_SOURCE
+#include <sched.h>
+#endif
+#if HAVE_GETPROCESSAFFINITYMASK
+#include <windows.h>
+#endif
+#if HAVE_SYSCTL
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+#if HAVE_SYSCONF
+#include <unistd.h>
+#endif
 
 static int cpuflags_mask = -1, checked;
 
@@ -61,6 +83,7 @@ int av_parse_cpu_flags(const char *s)
 #define CPUFLAG_AVX      (AV_CPU_FLAG_AVX      | CPUFLAG_SSE42)
 #define CPUFLAG_XOP      (AV_CPU_FLAG_XOP      | CPUFLAG_AVX)
 #define CPUFLAG_FMA4     (AV_CPU_FLAG_FMA4     | CPUFLAG_AVX)
+#define CPUFLAG_AVX2     (AV_CPU_FLAG_AVX2     | CPUFLAG_AVX)
     static const AVOption cpuflags_opts[] = {
         { "flags"   , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
 #if   ARCH_PPC
@@ -80,6 +103,7 @@ int av_parse_cpu_flags(const char *s)
         { "avx"     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX          },    .unit = "flags" },
         { "xop"     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_XOP          },    .unit = "flags" },
         { "fma4"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA4         },    .unit = "flags" },
+        { "avx2"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX2         },    .unit = "flags" },
         { "3dnow"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOW        },    .unit = "flags" },
         { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOWEXT     },    .unit = "flags" },
         { "cmov",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV     },    .unit = "flags" },
@@ -109,6 +133,35 @@ int av_parse_cpu_flags(const char *s)
     return flags & INT_MAX;
 }
 
+int av_cpu_count(void)
+{
+    int nb_cpus = 1;
+#if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
+    cpu_set_t cpuset;
+
+    CPU_ZERO(&cpuset);
+
+    if (!sched_getaffinity(0, sizeof(cpuset), &cpuset))
+        nb_cpus = CPU_COUNT(&cpuset);
+#elif HAVE_GETPROCESSAFFINITYMASK
+    DWORD_PTR proc_aff, sys_aff;
+    if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff))
+        nb_cpus = av_popcount64(proc_aff);
+#elif HAVE_SYSCTL && defined(HW_NCPU)
+    int mib[2] = { CTL_HW, HW_NCPU };
+    size_t len = sizeof(nb_cpus);
+
+    if (sysctl(mib, 2, &nb_cpus, &len, NULL, 0) == -1)
+        nb_cpus = 0;
+#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
+    nb_cpus = sysconf(_SC_NPROC_ONLN);
+#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
+    nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+
+    return nb_cpus;
+}
+
 #ifdef TEST
 
 #include <stdio.h>
@@ -144,6 +197,7 @@ static const struct {
     { AV_CPU_FLAG_3DNOW,     "3dnow"      },
     { AV_CPU_FLAG_3DNOWEXT,  "3dnowext"   },
     { AV_CPU_FLAG_CMOV,      "cmov"       },
+    { AV_CPU_FLAG_AVX2,      "avx2"       },
 #endif
     { 0 }
 };
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 4929512..29036e3 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -35,9 +35,11 @@
 #define AV_CPU_FLAG_SSE          0x0008 ///< SSE functions
 #define AV_CPU_FLAG_SSE2         0x0010 ///< PIV SSE2 functions
 #define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster
+                                        ///< than regular MMX/SSE (e.g. Core1)
 #define AV_CPU_FLAG_3DNOWEXT     0x0020 ///< AMD 3DNowExt
 #define AV_CPU_FLAG_SSE3         0x0040 ///< Prescott SSE3 functions
 #define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster
+                                        ///< than regular MMX/SSE (e.g. Core1)
 #define AV_CPU_FLAG_SSSE3        0x0080 ///< Conroe SSSE3 functions
 #define AV_CPU_FLAG_ATOM     0x10000000 ///< Atom processor, some SSSE3 instructions are slower
 #define AV_CPU_FLAG_SSE4         0x0100 ///< Penryn SSE4.1 functions
@@ -46,6 +48,7 @@
 #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
+#define AV_CPU_FLAG_AVX2         0x8000 ///< AVX2 functions: requires OS support even if YMM registers aren't used
 
 #define AV_CPU_FLAG_ALTIVEC      0x0001 ///< standard
 
@@ -76,9 +79,9 @@ void av_set_cpu_flags_mask(int mask);
  */
 int av_parse_cpu_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);
-int ff_get_cpu_flags_x86(void);
+/**
+ * @return the number of logical CPU cores present.
+ */
+int av_cpu_count(void);
 
 #endif /* AVUTIL_CPU_H */
diff --git a/libavutil/cpu_internal.h b/libavutil/cpu_internal.h
new file mode 100644
index 0000000..08f6e85
--- /dev/null
+++ b/libavutil/cpu_internal.h
@@ -0,0 +1,33 @@
+/*
+ * 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 AVUTIL_CPU_INTERNAL_H
+#define AVUTIL_CPU_INTERNAL_H
+
+#include "cpu.h"
+
+#define CPUEXT_SUFFIX(flags, suffix, cpuext)                            \
+    (HAVE_ ## cpuext ## suffix && ((flags) & AV_CPU_FLAG_ ## cpuext))
+
+#define CPUEXT(flags, cpuext) CPUEXT_SUFFIX(flags, , cpuext)
+
+int ff_get_cpu_flags_arm(void);
+int ff_get_cpu_flags_ppc(void);
+int ff_get_cpu_flags_x86(void);
+
+#endif /* AVUTIL_CPU_INTERNAL_H */
diff --git a/libavutil/crc.c b/libavutil/crc.c
index 3d1d876..2cdf588 100644
--- a/libavutil/crc.c
+++ b/libavutil/crc.c
@@ -24,7 +24,192 @@
 #include "crc.h"
 
 #if CONFIG_HARDCODED_TABLES
-#include "crc_data.h"
+static const AVCRC av_crc_table[AV_CRC_MAX][257] = {
+    [AV_CRC_8_ATM] = {
+        0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31,
+        0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
+        0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9,
+        0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
+        0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1,
+        0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
+        0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE,
+        0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
+        0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16,
+        0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
+        0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80,
+        0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
+        0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8,
+        0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
+        0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10,
+        0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
+        0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F,
+        0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
+        0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7,
+        0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
+        0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF,
+        0xFA, 0xFD, 0xF4, 0xF3, 0x01
+    },
+    [AV_CRC_16_ANSI] = {
+        0x0000, 0x0580, 0x0F80, 0x0A00, 0x1B80, 0x1E00, 0x1400, 0x1180,
+        0x3380, 0x3600, 0x3C00, 0x3980, 0x2800, 0x2D80, 0x2780, 0x2200,
+        0x6380, 0x6600, 0x6C00, 0x6980, 0x7800, 0x7D80, 0x7780, 0x7200,
+        0x5000, 0x5580, 0x5F80, 0x5A00, 0x4B80, 0x4E00, 0x4400, 0x4180,
+        0xC380, 0xC600, 0xCC00, 0xC980, 0xD800, 0xDD80, 0xD780, 0xD200,
+        0xF000, 0xF580, 0xFF80, 0xFA00, 0xEB80, 0xEE00, 0xE400, 0xE180,
+        0xA000, 0xA580, 0xAF80, 0xAA00, 0xBB80, 0xBE00, 0xB400, 0xB180,
+        0x9380, 0x9600, 0x9C00, 0x9980, 0x8800, 0x8D80, 0x8780, 0x8200,
+        0x8381, 0x8601, 0x8C01, 0x8981, 0x9801, 0x9D81, 0x9781, 0x9201,
+        0xB001, 0xB581, 0xBF81, 0xBA01, 0xAB81, 0xAE01, 0xA401, 0xA181,
+        0xE001, 0xE581, 0xEF81, 0xEA01, 0xFB81, 0xFE01, 0xF401, 0xF181,
+        0xD381, 0xD601, 0xDC01, 0xD981, 0xC801, 0xCD81, 0xC781, 0xC201,
+        0x4001, 0x4581, 0x4F81, 0x4A01, 0x5B81, 0x5E01, 0x5401, 0x5181,
+        0x7381, 0x7601, 0x7C01, 0x7981, 0x6801, 0x6D81, 0x6781, 0x6201,
+        0x2381, 0x2601, 0x2C01, 0x2981, 0x3801, 0x3D81, 0x3781, 0x3201,
+        0x1001, 0x1581, 0x1F81, 0x1A01, 0x0B81, 0x0E01, 0x0401, 0x0181,
+        0x0383, 0x0603, 0x0C03, 0x0983, 0x1803, 0x1D83, 0x1783, 0x1203,
+        0x3003, 0x3583, 0x3F83, 0x3A03, 0x2B83, 0x2E03, 0x2403, 0x2183,
+        0x6003, 0x6583, 0x6F83, 0x6A03, 0x7B83, 0x7E03, 0x7403, 0x7183,
+        0x5383, 0x5603, 0x5C03, 0x5983, 0x4803, 0x4D83, 0x4783, 0x4203,
+        0xC003, 0xC583, 0xCF83, 0xCA03, 0xDB83, 0xDE03, 0xD403, 0xD183,
+        0xF383, 0xF603, 0xFC03, 0xF983, 0xE803, 0xED83, 0xE783, 0xE203,
+        0xA383, 0xA603, 0xAC03, 0xA983, 0xB803, 0xBD83, 0xB783, 0xB203,
+        0x9003, 0x9583, 0x9F83, 0x9A03, 0x8B83, 0x8E03, 0x8403, 0x8183,
+        0x8002, 0x8582, 0x8F82, 0x8A02, 0x9B82, 0x9E02, 0x9402, 0x9182,
+        0xB382, 0xB602, 0xBC02, 0xB982, 0xA802, 0xAD82, 0xA782, 0xA202,
+        0xE382, 0xE602, 0xEC02, 0xE982, 0xF802, 0xFD82, 0xF782, 0xF202,
+        0xD002, 0xD582, 0xDF82, 0xDA02, 0xCB82, 0xCE02, 0xC402, 0xC182,
+        0x4382, 0x4602, 0x4C02, 0x4982, 0x5802, 0x5D82, 0x5782, 0x5202,
+        0x7002, 0x7582, 0x7F82, 0x7A02, 0x6B82, 0x6E02, 0x6402, 0x6182,
+        0x2002, 0x2582, 0x2F82, 0x2A02, 0x3B82, 0x3E02, 0x3402, 0x3182,
+        0x1382, 0x1602, 0x1C02, 0x1982, 0x0802, 0x0D82, 0x0782, 0x0202,
+        0x0001
+    },
+    [AV_CRC_16_CCITT] = {
+        0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xA550, 0xC660, 0xE770,
+        0x0881, 0x2991, 0x4AA1, 0x6BB1, 0x8CC1, 0xADD1, 0xCEE1, 0xEFF1,
+        0x3112, 0x1002, 0x7332, 0x5222, 0xB552, 0x9442, 0xF772, 0xD662,
+        0x3993, 0x1883, 0x7BB3, 0x5AA3, 0xBDD3, 0x9CC3, 0xFFF3, 0xDEE3,
+        0x6224, 0x4334, 0x2004, 0x0114, 0xE664, 0xC774, 0xA444, 0x8554,
+        0x6AA5, 0x4BB5, 0x2885, 0x0995, 0xEEE5, 0xCFF5, 0xACC5, 0x8DD5,
+        0x5336, 0x7226, 0x1116, 0x3006, 0xD776, 0xF666, 0x9556, 0xB446,
+        0x5BB7, 0x7AA7, 0x1997, 0x3887, 0xDFF7, 0xFEE7, 0x9DD7, 0xBCC7,
+        0xC448, 0xE558, 0x8668, 0xA778, 0x4008, 0x6118, 0x0228, 0x2338,
+        0xCCC9, 0xEDD9, 0x8EE9, 0xAFF9, 0x4889, 0x6999, 0x0AA9, 0x2BB9,
+        0xF55A, 0xD44A, 0xB77A, 0x966A, 0x711A, 0x500A, 0x333A, 0x122A,
+        0xFDDB, 0xDCCB, 0xBFFB, 0x9EEB, 0x799B, 0x588B, 0x3BBB, 0x1AAB,
+        0xA66C, 0x877C, 0xE44C, 0xC55C, 0x222C, 0x033C, 0x600C, 0x411C,
+        0xAEED, 0x8FFD, 0xECCD, 0xCDDD, 0x2AAD, 0x0BBD, 0x688D, 0x499D,
+        0x977E, 0xB66E, 0xD55E, 0xF44E, 0x133E, 0x322E, 0x511E, 0x700E,
+        0x9FFF, 0xBEEF, 0xDDDF, 0xFCCF, 0x1BBF, 0x3AAF, 0x599F, 0x788F,
+        0x8891, 0xA981, 0xCAB1, 0xEBA1, 0x0CD1, 0x2DC1, 0x4EF1, 0x6FE1,
+        0x8010, 0xA100, 0xC230, 0xE320, 0x0450, 0x2540, 0x4670, 0x6760,
+        0xB983, 0x9893, 0xFBA3, 0xDAB3, 0x3DC3, 0x1CD3, 0x7FE3, 0x5EF3,
+        0xB102, 0x9012, 0xF322, 0xD232, 0x3542, 0x1452, 0x7762, 0x5672,
+        0xEAB5, 0xCBA5, 0xA895, 0x8985, 0x6EF5, 0x4FE5, 0x2CD5, 0x0DC5,
+        0xE234, 0xC324, 0xA014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544,
+        0xDBA7, 0xFAB7, 0x9987, 0xB897, 0x5FE7, 0x7EF7, 0x1DC7, 0x3CD7,
+        0xD326, 0xF236, 0x9106, 0xB016, 0x5766, 0x7676, 0x1546, 0x3456,
+        0x4CD9, 0x6DC9, 0x0EF9, 0x2FE9, 0xC899, 0xE989, 0x8AB9, 0xABA9,
+        0x4458, 0x6548, 0x0678, 0x2768, 0xC018, 0xE108, 0x8238, 0xA328,
+        0x7DCB, 0x5CDB, 0x3FEB, 0x1EFB, 0xF98B, 0xD89B, 0xBBAB, 0x9ABB,
+        0x754A, 0x545A, 0x376A, 0x167A, 0xF10A, 0xD01A, 0xB32A, 0x923A,
+        0x2EFD, 0x0FED, 0x6CDD, 0x4DCD, 0xAABD, 0x8BAD, 0xE89D, 0xC98D,
+        0x267C, 0x076C, 0x645C, 0x454C, 0xA23C, 0x832C, 0xE01C, 0xC10C,
+        0x1FEF, 0x3EFF, 0x5DCF, 0x7CDF, 0x9BAF, 0xBABF, 0xD98F, 0xF89F,
+        0x176E, 0x367E, 0x554E, 0x745E, 0x932E, 0xB23E, 0xD10E, 0xF01E,
+        0x0001
+    },
+    [AV_CRC_32_IEEE] = {
+        0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517,
+        0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B,
+        0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048,
+        0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652,
+        0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D,
+        0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095,
+        0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA,
+        0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0,
+        0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3,
+        0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF,
+        0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730,
+        0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A,
+        0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05,
+        0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475,
+        0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A,
+        0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840,
+        0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB,
+        0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87,
+        0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4,
+        0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE,
+        0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1,
+        0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64,
+        0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B,
+        0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351,
+        0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832,
+        0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E,
+        0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5,
+        0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF,
+        0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0,
+        0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0,
+        0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F,
+        0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185,
+        0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A,
+        0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176,
+        0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15,
+        0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F,
+        0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620,
+        0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8,
+        0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7,
+        0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD,
+        0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E,
+        0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2,
+        0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1, 0x00000001
+    },
+    [AV_CRC_32_IEEE_LE] = {
+        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
+        0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+        0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
+        0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+        0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
+        0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+        0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
+        0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+        0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
+        0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+        0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
+        0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+        0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
+        0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+        0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
+        0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+        0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
+        0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+        0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
+        0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
+        0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+        0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
+        0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+        0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
+        0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+        0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
+        0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+        0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
+        0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+        0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
+        0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
+        0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+        0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+        0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+        0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
+        0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+        0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
+        0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+        0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
+        0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 0x00000001
+    },
+};
 #else
 static struct {
     uint8_t  le;
diff --git a/libavutil/crc_data.h b/libavutil/crc_data.h
deleted file mode 100644
index 8e4e6af..0000000
--- a/libavutil/crc_data.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * copyright (c) 2008 Aurelien Jacobs <aurel at gnuage.org>
- *
- * 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 AVUTIL_CRC_DATA_H
-#define AVUTIL_CRC_DATA_H
-
-#include "crc.h"
-
-static const AVCRC av_crc_table[AV_CRC_MAX][257] = {
-    [AV_CRC_8_ATM] = {
-        0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31,
-        0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
-        0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9,
-        0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
-        0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1,
-        0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
-        0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE,
-        0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
-        0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16,
-        0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
-        0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80,
-        0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
-        0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8,
-        0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
-        0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10,
-        0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
-        0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F,
-        0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
-        0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7,
-        0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
-        0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF,
-        0xFA, 0xFD, 0xF4, 0xF3, 0x01
-    },
-    [AV_CRC_16_ANSI] = {
-        0x0000, 0x0580, 0x0F80, 0x0A00, 0x1B80, 0x1E00, 0x1400, 0x1180,
-        0x3380, 0x3600, 0x3C00, 0x3980, 0x2800, 0x2D80, 0x2780, 0x2200,
-        0x6380, 0x6600, 0x6C00, 0x6980, 0x7800, 0x7D80, 0x7780, 0x7200,
-        0x5000, 0x5580, 0x5F80, 0x5A00, 0x4B80, 0x4E00, 0x4400, 0x4180,
-        0xC380, 0xC600, 0xCC00, 0xC980, 0xD800, 0xDD80, 0xD780, 0xD200,
-        0xF000, 0xF580, 0xFF80, 0xFA00, 0xEB80, 0xEE00, 0xE400, 0xE180,
-        0xA000, 0xA580, 0xAF80, 0xAA00, 0xBB80, 0xBE00, 0xB400, 0xB180,
-        0x9380, 0x9600, 0x9C00, 0x9980, 0x8800, 0x8D80, 0x8780, 0x8200,
-        0x8381, 0x8601, 0x8C01, 0x8981, 0x9801, 0x9D81, 0x9781, 0x9201,
-        0xB001, 0xB581, 0xBF81, 0xBA01, 0xAB81, 0xAE01, 0xA401, 0xA181,
-        0xE001, 0xE581, 0xEF81, 0xEA01, 0xFB81, 0xFE01, 0xF401, 0xF181,
-        0xD381, 0xD601, 0xDC01, 0xD981, 0xC801, 0xCD81, 0xC781, 0xC201,
-        0x4001, 0x4581, 0x4F81, 0x4A01, 0x5B81, 0x5E01, 0x5401, 0x5181,
-        0x7381, 0x7601, 0x7C01, 0x7981, 0x6801, 0x6D81, 0x6781, 0x6201,
-        0x2381, 0x2601, 0x2C01, 0x2981, 0x3801, 0x3D81, 0x3781, 0x3201,
-        0x1001, 0x1581, 0x1F81, 0x1A01, 0x0B81, 0x0E01, 0x0401, 0x0181,
-        0x0383, 0x0603, 0x0C03, 0x0983, 0x1803, 0x1D83, 0x1783, 0x1203,
-        0x3003, 0x3583, 0x3F83, 0x3A03, 0x2B83, 0x2E03, 0x2403, 0x2183,
-        0x6003, 0x6583, 0x6F83, 0x6A03, 0x7B83, 0x7E03, 0x7403, 0x7183,
-        0x5383, 0x5603, 0x5C03, 0x5983, 0x4803, 0x4D83, 0x4783, 0x4203,
-        0xC003, 0xC583, 0xCF83, 0xCA03, 0xDB83, 0xDE03, 0xD403, 0xD183,
-        0xF383, 0xF603, 0xFC03, 0xF983, 0xE803, 0xED83, 0xE783, 0xE203,
-        0xA383, 0xA603, 0xAC03, 0xA983, 0xB803, 0xBD83, 0xB783, 0xB203,
-        0x9003, 0x9583, 0x9F83, 0x9A03, 0x8B83, 0x8E03, 0x8403, 0x8183,
-        0x8002, 0x8582, 0x8F82, 0x8A02, 0x9B82, 0x9E02, 0x9402, 0x9182,
-        0xB382, 0xB602, 0xBC02, 0xB982, 0xA802, 0xAD82, 0xA782, 0xA202,
-        0xE382, 0xE602, 0xEC02, 0xE982, 0xF802, 0xFD82, 0xF782, 0xF202,
-        0xD002, 0xD582, 0xDF82, 0xDA02, 0xCB82, 0xCE02, 0xC402, 0xC182,
-        0x4382, 0x4602, 0x4C02, 0x4982, 0x5802, 0x5D82, 0x5782, 0x5202,
-        0x7002, 0x7582, 0x7F82, 0x7A02, 0x6B82, 0x6E02, 0x6402, 0x6182,
-        0x2002, 0x2582, 0x2F82, 0x2A02, 0x3B82, 0x3E02, 0x3402, 0x3182,
-        0x1382, 0x1602, 0x1C02, 0x1982, 0x0802, 0x0D82, 0x0782, 0x0202,
-        0x0001
-    },
-    [AV_CRC_16_CCITT] = {
-        0x0000, 0x2110, 0x4220, 0x6330, 0x8440, 0xA550, 0xC660, 0xE770,
-        0x0881, 0x2991, 0x4AA1, 0x6BB1, 0x8CC1, 0xADD1, 0xCEE1, 0xEFF1,
-        0x3112, 0x1002, 0x7332, 0x5222, 0xB552, 0x9442, 0xF772, 0xD662,
-        0x3993, 0x1883, 0x7BB3, 0x5AA3, 0xBDD3, 0x9CC3, 0xFFF3, 0xDEE3,
-        0x6224, 0x4334, 0x2004, 0x0114, 0xE664, 0xC774, 0xA444, 0x8554,
-        0x6AA5, 0x4BB5, 0x2885, 0x0995, 0xEEE5, 0xCFF5, 0xACC5, 0x8DD5,
-        0x5336, 0x7226, 0x1116, 0x3006, 0xD776, 0xF666, 0x9556, 0xB446,
-        0x5BB7, 0x7AA7, 0x1997, 0x3887, 0xDFF7, 0xFEE7, 0x9DD7, 0xBCC7,
-        0xC448, 0xE558, 0x8668, 0xA778, 0x4008, 0x6118, 0x0228, 0x2338,
-        0xCCC9, 0xEDD9, 0x8EE9, 0xAFF9, 0x4889, 0x6999, 0x0AA9, 0x2BB9,
-        0xF55A, 0xD44A, 0xB77A, 0x966A, 0x711A, 0x500A, 0x333A, 0x122A,
-        0xFDDB, 0xDCCB, 0xBFFB, 0x9EEB, 0x799B, 0x588B, 0x3BBB, 0x1AAB,
-        0xA66C, 0x877C, 0xE44C, 0xC55C, 0x222C, 0x033C, 0x600C, 0x411C,
-        0xAEED, 0x8FFD, 0xECCD, 0xCDDD, 0x2AAD, 0x0BBD, 0x688D, 0x499D,
-        0x977E, 0xB66E, 0xD55E, 0xF44E, 0x133E, 0x322E, 0x511E, 0x700E,
-        0x9FFF, 0xBEEF, 0xDDDF, 0xFCCF, 0x1BBF, 0x3AAF, 0x599F, 0x788F,
-        0x8891, 0xA981, 0xCAB1, 0xEBA1, 0x0CD1, 0x2DC1, 0x4EF1, 0x6FE1,
-        0x8010, 0xA100, 0xC230, 0xE320, 0x0450, 0x2540, 0x4670, 0x6760,
-        0xB983, 0x9893, 0xFBA3, 0xDAB3, 0x3DC3, 0x1CD3, 0x7FE3, 0x5EF3,
-        0xB102, 0x9012, 0xF322, 0xD232, 0x3542, 0x1452, 0x7762, 0x5672,
-        0xEAB5, 0xCBA5, 0xA895, 0x8985, 0x6EF5, 0x4FE5, 0x2CD5, 0x0DC5,
-        0xE234, 0xC324, 0xA014, 0x8104, 0x6674, 0x4764, 0x2454, 0x0544,
-        0xDBA7, 0xFAB7, 0x9987, 0xB897, 0x5FE7, 0x7EF7, 0x1DC7, 0x3CD7,
-        0xD326, 0xF236, 0x9106, 0xB016, 0x5766, 0x7676, 0x1546, 0x3456,
-        0x4CD9, 0x6DC9, 0x0EF9, 0x2FE9, 0xC899, 0xE989, 0x8AB9, 0xABA9,
-        0x4458, 0x6548, 0x0678, 0x2768, 0xC018, 0xE108, 0x8238, 0xA328,
-        0x7DCB, 0x5CDB, 0x3FEB, 0x1EFB, 0xF98B, 0xD89B, 0xBBAB, 0x9ABB,
-        0x754A, 0x545A, 0x376A, 0x167A, 0xF10A, 0xD01A, 0xB32A, 0x923A,
-        0x2EFD, 0x0FED, 0x6CDD, 0x4DCD, 0xAABD, 0x8BAD, 0xE89D, 0xC98D,
-        0x267C, 0x076C, 0x645C, 0x454C, 0xA23C, 0x832C, 0xE01C, 0xC10C,
-        0x1FEF, 0x3EFF, 0x5DCF, 0x7CDF, 0x9BAF, 0xBABF, 0xD98F, 0xF89F,
-        0x176E, 0x367E, 0x554E, 0x745E, 0x932E, 0xB23E, 0xD10E, 0xF01E,
-        0x0001
-    },
-    [AV_CRC_32_IEEE] = {
-        0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517,
-        0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B,
-        0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048,
-        0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652,
-        0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D,
-        0x7A7B9F70, 0xCD665E74, 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095,
-        0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486, 0x585B2BBE, 0xEF46EABA,
-        0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0,
-        0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3,
-        0x2220B4CE, 0x953D75CA, 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF,
-        0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC, 0x77708634, 0xC06D4730,
-        0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A,
-        0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05,
-        0x7DD00808, 0xCACDC90C, 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475,
-        0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066, 0xBF469F5E, 0x085B5E5A,
-        0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840,
-        0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB,
-        0x258B23B6, 0x9296E2B2, 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87,
-        0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94, 0xE71DB4E0, 0x500075E4,
-        0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE,
-        0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1,
-        0xEDBD3ADC, 0x5AA0FBD8, 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64,
-        0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77, 0x560D044F, 0xE110C54B,
-        0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351,
-        0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832,
-        0x2C769B3F, 0x9B6B5A3B, 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E,
-        0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D, 0x0E562FF1, 0xB94BEEF5,
-        0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF,
-        0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0,
-        0x04F6A1CD, 0xB3EB60C9, 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0,
-        0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3, 0xC660369B, 0x717DF79F,
-        0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185,
-        0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A,
-        0x2BDD0C47, 0x9CC0CD43, 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176,
-        0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565, 0xE94B9B11, 0x5E565A15,
-        0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F,
-        0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620,
-        0xE3EB152D, 0x54F6D429, 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8,
-        0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB, 0xC1CBA1E3, 0x76D660E7,
-        0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD,
-        0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E,
-        0xBBB03E93, 0x0CADFF97, 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2,
-        0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1, 0x00000001
-    },
-    [AV_CRC_32_IEEE_LE] = {
-        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
-        0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
-        0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
-        0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
-        0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
-        0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
-        0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
-        0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
-        0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
-        0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
-        0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
-        0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
-        0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
-        0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
-        0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
-        0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
-        0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
-        0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
-        0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
-        0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
-        0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
-        0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
-        0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
-        0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
-        0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
-        0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
-        0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
-        0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
-        0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
-        0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
-        0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
-        0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
-        0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
-        0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
-        0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
-        0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
-        0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
-        0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
-        0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
-        0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
-        0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
-        0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
-        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 0x00000001
-    },
-};
-
-#endif /* AVUTIL_CRC_DATA_H */
diff --git a/libavutil/des.c b/libavutil/des.c
index 01cb10b..ab0fc2f 100644
--- a/libavutil/des.c
+++ b/libavutil/des.c
@@ -339,7 +339,9 @@ void av_des_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count) {
 #ifdef TEST
 #include <stdlib.h>
 #include <stdio.h>
-#include "libavutil/time.h"
+
+#include "time.h"
+
 static uint64_t rand64(void) {
     uint64_t r = rand();
     r = (r << 32) | rand();
diff --git a/libavutil/dict.c b/libavutil/dict.c
index 3c3194c..9ac4831 100644
--- a/libavutil/dict.c
+++ b/libavutil/dict.c
@@ -18,7 +18,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <ctype.h>
 #include <string.h>
 
 #include "avstring.h"
@@ -50,7 +49,7 @@ av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int
     for(; i<m->count; i++){
         const char *s= m->elems[i].key;
         if(flags & AV_DICT_MATCH_CASE) for(j=0;         s[j]  ==         key[j]  && key[j]; j++);
-        else                               for(j=0; toupper(s[j]) == toupper(key[j]) && key[j]; j++);
+        else                               for(j=0; av_toupper(s[j]) == av_toupper(key[j]) && key[j]; j++);
         if(key[j])
             continue;
         if(s[j] && !(flags & AV_DICT_IGNORE_SUFFIX))
@@ -110,6 +109,53 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags
     return 0;
 }
 
+static int parse_key_value_pair(AVDictionary **pm, const char **buf,
+                                const char *key_val_sep, const char *pairs_sep,
+                                int flags)
+{
+    char *key = av_get_token(buf, key_val_sep);
+    char *val = NULL;
+    int ret;
+
+    if (key && *key && strspn(*buf, key_val_sep)) {
+        (*buf)++;
+        val = av_get_token(buf, pairs_sep);
+    }
+
+    if (key && *key && val && *val)
+        ret = av_dict_set(pm, key, val, flags);
+    else
+        ret = AVERROR(EINVAL);
+
+    av_freep(&key);
+    av_freep(&val);
+
+    return ret;
+}
+
+int av_dict_parse_string(AVDictionary **pm, const char *str,
+                         const char *key_val_sep, const char *pairs_sep,
+                         int flags)
+{
+    int ret;
+
+    if (!str)
+        return 0;
+
+    /* ignore STRDUP flags */
+    flags &= ~(AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
+
+    while (*str) {
+        if ((ret = parse_key_value_pair(pm, &str, key_val_sep, pairs_sep, flags)) < 0)
+            return ret;
+
+        if (*str)
+            str++;
+    }
+
+    return 0;
+}
+
 void av_dict_free(AVDictionary **pm)
 {
     AVDictionary *m = *pm;
diff --git a/libavutil/dict.h b/libavutil/dict.h
index 492da9a..ab23f26 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -107,6 +107,23 @@ int av_dict_count(const AVDictionary *m);
 int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags);
 
 /**
+ * Parse the key/value pairs list and add to a dictionary.
+ *
+ * @param key_val_sep  a 0-terminated list of characters used to separate
+ *                     key from value
+ * @param pairs_sep    a 0-terminated list of characters used to separate
+ *                     two pairs from each other
+ * @param flags        flags to use when adding to dictionary.
+ *                     AV_DICT_DONT_STRDUP_KEY and AV_DICT_DONT_STRDUP_VAL
+ *                     are ignored since the key/value tokens will always
+ *                     be duplicated.
+ * @return             0 on success, negative AVERROR code on failure
+ */
+int av_dict_parse_string(AVDictionary **pm, const char *str,
+                         const char *key_val_sep, const char *pairs_sep,
+                         int flags);
+
+/**
  * Copy entries from one AVDictionary struct into another.
  * @param dst pointer to a pointer to a AVDictionary struct. If *dst is NULL,
  *            this function will allocate a struct for you and put it in *dst
diff --git a/libavutil/eval.c b/libavutil/eval.c
index a0e968d..48f8e66 100644
--- a/libavutil/eval.c
+++ b/libavutil/eval.c
@@ -26,11 +26,13 @@
  * see http://joe.hotchkiss.com/programming/eval/eval.html
  */
 
+#include "attributes.h"
 #include "avutil.h"
 #include "common.h"
 #include "eval.h"
 #include "log.h"
 #include "mathematics.h"
+#include "avstring.h"
 
 typedef struct Parser {
     const AVClass *class;
@@ -349,7 +351,7 @@ static int parse_dB(AVExpr **e, Parser *p, int *sign)
        for example, -3dB is not the same as -(3dB) */
     if (*p->s == '-') {
         char *next;
-        strtod(p->s, &next);
+        double av_unused ignored = strtod(p->s, &next);
         if (next != p->s && next[0] == 'd' && next[1] == 'B') {
             *sign = 0;
             return parse_primary(e, p);
@@ -503,7 +505,7 @@ int av_expr_parse(AVExpr **expr, const char *s,
         return AVERROR(ENOMEM);
 
     while (*s)
-        if (!isspace(*s++)) *wp++ = s[-1];
+        if (!av_isspace(*s++)) *wp++ = s[-1];
     *wp++ = 0;
 
     p.class      = &class;
diff --git a/libavutil/fifo.c b/libavutil/fifo.c
index 2684899..dffaf54 100644
--- a/libavutil/fifo.c
+++ b/libavutil/fifo.c
@@ -24,11 +24,11 @@
 
 AVFifoBuffer *av_fifo_alloc(unsigned int size)
 {
-    AVFifoBuffer *f= av_mallocz(sizeof(AVFifoBuffer));
-    if(!f)
+    AVFifoBuffer *f = av_mallocz(sizeof(AVFifoBuffer));
+    if (!f)
         return NULL;
     f->buffer = av_malloc(size);
-    f->end = f->buffer + size;
+    f->end    = f->buffer + size;
     av_fifo_reset(f);
     if (!f->buffer)
         av_freep(&f);
@@ -37,7 +37,7 @@ AVFifoBuffer *av_fifo_alloc(unsigned int size)
 
 void av_fifo_free(AVFifoBuffer *f)
 {
-    if(f){
+    if (f) {
         av_free(f->buffer);
         av_free(f);
     }
@@ -59,12 +59,13 @@ int av_fifo_space(AVFifoBuffer *f)
     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;
@@ -72,45 +73,48 @@ int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) {
         f2->wptr += len;
         f2->wndx += len;
         av_free(f->buffer);
-        *f= *f2;
+        *f = *f2;
         av_free(f2);
     }
     return 0;
 }
 
-// src must NOT be const as it can be a context for func that may need updating (like a pointer or byte counter)
-int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int))
+/* src must NOT be const as it can be a context for func that may need
+ * updating (like a pointer or byte counter) */
+int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size,
+                          int (*func)(void *, void *, int))
 {
     int total = size;
     do {
         int len = FFMIN(f->end - f->wptr, size);
-        if(func) {
-            if(func(src, f->wptr, len) <= 0)
+        if (func) {
+            if (func(src, f->wptr, len) <= 0)
                 break;
         } else {
             memcpy(f->wptr, src, len);
-            src = (uint8_t*)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;
-        size -= len;
+        size    -= len;
     } while (size > 0);
     return total - size;
 }
 
-
-int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void (*func)(void*, void*, int))
+int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size,
+                         void (*func)(void *, void *, int))
 {
 // Read memory barrier needed for SMP here in theory
     do {
         int len = FFMIN(f->end - f->rptr, buf_size);
-        if(func) func(dest, f->rptr, len);
-        else{
+        if (func)
+            func(dest, f->rptr, len);
+        else {
             memcpy(dest, f->rptr, len);
-            dest = (uint8_t*)dest + len;
+            dest = (uint8_t *)dest + len;
         }
 // memory barrier needed for SMP here in theory
         av_fifo_drain(f, len);
@@ -141,9 +145,9 @@ int main(void)
         av_fifo_generic_write(fifo, &i, sizeof(int), NULL);
 
     /* peek at FIFO */
-    n = av_fifo_size(fifo)/sizeof(int);
-    for (i = -n+1; i < n; i++) {
-        int *v = (int *)av_fifo_peek2(fifo, i*sizeof(int));
+    n = av_fifo_size(fifo) / sizeof(int);
+    for (i = -n + 1; i < n; i++) {
+        int *v = (int *)av_fifo_peek2(fifo, i * sizeof(int));
         printf("%d: %d\n", i, *v);
     }
     printf("\n");
diff --git a/libavutil/file.c b/libavutil/file.c
index ce02487..d2765b8 100644
--- a/libavutil/file.c
+++ b/libavutil/file.c
@@ -18,6 +18,7 @@
 
 #include "config.h"
 #include "file.h"
+#include "internal.h"
 #include "log.h"
 #include "mem.h"
 #include <fcntl.h>
@@ -49,7 +50,7 @@ int av_file_map(const char *filename, uint8_t **bufptr, size_t *size,
                 int log_offset, void *log_ctx)
 {
     FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
-    int err, fd = open(filename, O_RDONLY);
+    int err, fd = avpriv_open(filename, O_RDONLY);
     struct stat st;
     av_unused void *ptr;
     off_t off_size;
diff --git a/libavutil/file_open.c b/libavutil/file_open.c
new file mode 100644
index 0000000..765eb60
--- /dev/null
+++ b/libavutil/file_open.c
@@ -0,0 +1,93 @@
+/*
+ * 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 "internal.h"
+#include "mem.h"
+#include <stdarg.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_IO_H
+#include <io.h>
+#endif
+
+#if defined(_WIN32) && !defined(__MINGW32CE__)
+#undef open
+#undef lseek
+#undef stat
+#undef fstat
+#include <windows.h>
+#include <share.h>
+#include <errno.h>
+
+static int win32_open(const char *filename_utf8, int oflag, int pmode)
+{
+    int fd;
+    int num_chars;
+    wchar_t *filename_w;
+
+    /* convert UTF-8 to wide chars */
+    num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
+    if (num_chars <= 0)
+        goto fallback;
+    filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
+    if (!filename_w) {
+        errno = ENOMEM;
+        return -1;
+    }
+    MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
+
+    fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode);
+    av_freep(&filename_w);
+
+    if (fd != -1 || (oflag & O_CREAT))
+        return fd;
+
+fallback:
+    /* filename may be be in CP_ACP */
+    return _sopen(filename_utf8, oflag, SH_DENYNO, pmode);
+}
+#define open win32_open
+#endif
+
+int avpriv_open(const char *filename, int flags, ...)
+{
+    int fd;
+    unsigned int mode = 0;
+    va_list ap;
+
+    va_start(ap, flags);
+    if (flags & O_CREAT)
+        mode = va_arg(ap, unsigned int);
+    va_end(ap);
+
+#ifdef O_CLOEXEC
+    flags |= O_CLOEXEC;
+#endif
+
+    fd = open(filename, flags, mode);
+#if HAVE_FCNTL
+    if (fd != -1)
+        fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+    return fd;
+}
diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c
index 22139de..3707e06 100644
--- a/libavutil/float_dsp.c
+++ b/libavutil/float_dsp.c
@@ -17,7 +17,7 @@
  */
 
 #include "config.h"
-
+#include "attributes.h"
 #include "float_dsp.h"
 
 static void vector_fmul_c(float *dst, const float *src0, const float *src1,
@@ -52,12 +52,77 @@ static void vector_dmul_scalar_c(double *dst, const double *src, double mul,
         dst[i] = src[i] * mul;
 }
 
-void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
+static void vector_fmul_window_c(float *dst, const float *src0,
+                                 const float *src1, const float *win, int len)
+{
+    int i, j;
+
+    dst  += len;
+    win  += len;
+    src0 += len;
+
+    for (i = -len, j = len - 1; i < 0; i++, j--) {
+        float s0 = src0[i];
+        float s1 = src1[j];
+        float wi = win[i];
+        float wj = win[j];
+        dst[i] = s0 * wj - s1 * wi;
+        dst[j] = s0 * wi + s1 * wj;
+    }
+}
+
+static void vector_fmul_add_c(float *dst, const float *src0, const float *src1,
+                              const float *src2, int len){
+    int i;
+
+    for (i = 0; i < len; i++)
+        dst[i] = src0[i] * src1[i] + src2[i];
+}
+
+static void vector_fmul_reverse_c(float *dst, const float *src0,
+                                  const float *src1, int len)
+{
+    int i;
+
+    src1 += len-1;
+    for (i = 0; i < len; i++)
+        dst[i] = src0[i] * src1[-i];
+}
+
+static void butterflies_float_c(float *restrict v1, float *restrict v2,
+                                int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++) {
+        float t = v1[i] - v2[i];
+        v1[i] += v2[i];
+        v2[i] = t;
+    }
+}
+
+float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len)
+{
+    float p = 0.0;
+    int i;
+
+    for (i = 0; i < len; i++)
+        p += v1[i] * v2[i];
+
+    return p;
+}
+
+av_cold void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
 {
     fdsp->vector_fmul = vector_fmul_c;
     fdsp->vector_fmac_scalar = vector_fmac_scalar_c;
     fdsp->vector_fmul_scalar = vector_fmul_scalar_c;
     fdsp->vector_dmul_scalar = vector_dmul_scalar_c;
+    fdsp->vector_fmul_window = vector_fmul_window_c;
+    fdsp->vector_fmul_add = vector_fmul_add_c;
+    fdsp->vector_fmul_reverse = vector_fmul_reverse_c;
+    fdsp->butterflies_float = butterflies_float_c;
+    fdsp->scalarproduct_float = avpriv_scalarproduct_float_c;
 
 #if ARCH_ARM
     ff_float_dsp_init_arm(fdsp);
diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h
index 41b73c5..b215dad 100644
--- a/libavutil/float_dsp.h
+++ b/libavutil/float_dsp.h
@@ -19,6 +19,8 @@
 #ifndef AVUTIL_FLOAT_DSP_H
 #define AVUTIL_FLOAT_DSP_H
 
+#include "config.h"
+
 typedef struct AVFloatDSPContext {
     /**
      * Calculate the product of two vectors of floats and store the result in
@@ -81,9 +83,96 @@ typedef struct AVFloatDSPContext {
      */
     void (*vector_dmul_scalar)(double *dst, const double *src, double mul,
                                int len);
+
+    /**
+     * Overlap/add with window function.
+     * Used primarily by MDCT-based audio codecs.
+     * Source and destination vectors must overlap exactly or not at all.
+     *
+     * @param dst  result vector
+     *             constraints: 16-byte aligned
+     * @param src0 first source vector
+     *             constraints: 16-byte aligned
+     * @param src1 second source vector
+     *             constraints: 16-byte aligned
+     * @param win  half-window vector
+     *             constraints: 16-byte aligned
+     * @param len  length of vector
+     *             constraints: multiple of 4
+     */
+    void (*vector_fmul_window)(float *dst, const float *src0,
+                               const float *src1, const float *win, int len);
+
+    /**
+     * Calculate the product of two vectors of floats, add a third vector of
+     * floats and store the result in a vector of floats.
+     *
+     * @param dst  output vector
+     *             constraints: 32-byte aligned
+     * @param src0 first input vector
+     *             constraints: 32-byte aligned
+     * @param src1 second input vector
+     *             constraints: 32-byte aligned
+     * @param src1 third input vector
+     *             constraints: 32-byte aligned
+     * @param len  number of elements in the input
+     *             constraints: multiple of 16
+     */
+    void (*vector_fmul_add)(float *dst, const float *src0, const float *src1,
+                            const float *src2, int len);
+
+    /**
+     * Calculate the product of two vectors of floats, and store the result
+     * in a vector of floats. The second vector of floats is iterated over
+     * in reverse order.
+     *
+     * @param dst  output vector
+     *             constraints: 32-byte aligned
+     * @param src0 first input vector
+     *             constraints: 32-byte aligned
+     * @param src1 second input vector
+     *             constraints: 32-byte aligned
+     * @param src1 third input vector
+     *             constraints: 32-byte aligned
+     * @param len  number of elements in the input
+     *             constraints: multiple of 16
+     */
+    void (*vector_fmul_reverse)(float *dst, const float *src0,
+                                const float *src1, int len);
+
+    /**
+     * Calculate the sum and difference of two vectors of floats.
+     *
+     * @param v1  first input vector, sum output, 16-byte aligned
+     * @param v2  second input vector, difference output, 16-byte aligned
+     * @param len length of vectors, multiple of 4
+     */
+    void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);
+
+    /**
+     * Calculate the scalar product of two vectors of floats.
+     *
+     * @param v1  first vector, 16-byte aligned
+     * @param v2  second vector, 16-byte aligned
+     * @param len length of vectors, multiple of 4
+     *
+     * @return sum of elementwise products
+     */
+    float (*scalarproduct_float)(const float *v1, const float *v2, int len);
 } AVFloatDSPContext;
 
 /**
+ * Return the scalar product of two vectors.
+ *
+ * @param v1  first input vector
+ * @param v2  first input vector
+ * @param len number of elements
+ *
+ * @return sum of elementwise products
+ */
+float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len);
+
+/**
  * Initialize a float DSP context.
  *
  * @param fdsp    float DSP context
diff --git a/libavutil/frame.c b/libavutil/frame.c
new file mode 100644
index 0000000..2529ae5
--- /dev/null
+++ b/libavutil/frame.c
@@ -0,0 +1,479 @@
+/*
+ *
+ * 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 "channel_layout.h"
+#include "buffer.h"
+#include "common.h"
+#include "dict.h"
+#include "frame.h"
+#include "imgutils.h"
+#include "mem.h"
+#include "samplefmt.h"
+
+static void get_frame_defaults(AVFrame *frame)
+{
+    if (frame->extended_data != frame->data)
+        av_freep(&frame->extended_data);
+
+    memset(frame, 0, sizeof(*frame));
+
+    frame->pts                 = AV_NOPTS_VALUE;
+    frame->key_frame           = 1;
+    frame->sample_aspect_ratio = (AVRational){ 0, 1 };
+    frame->format              = -1; /* unknown */
+    frame->extended_data       = frame->data;
+}
+
+AVFrame *av_frame_alloc(void)
+{
+    AVFrame *frame = av_mallocz(sizeof(*frame));
+
+    if (!frame)
+        return NULL;
+
+    get_frame_defaults(frame);
+
+    return frame;
+}
+
+void av_frame_free(AVFrame **frame)
+{
+    if (!frame || !*frame)
+        return;
+
+    av_frame_unref(*frame);
+    av_freep(frame);
+}
+
+static int get_video_buffer(AVFrame *frame, int align)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+    int ret, i;
+
+    if (!desc)
+        return AVERROR(EINVAL);
+
+    if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
+        return ret;
+
+    if (!frame->linesize[0]) {
+        ret = av_image_fill_linesizes(frame->linesize, frame->format,
+                                      frame->width);
+        if (ret < 0)
+            return ret;
+
+        for (i = 0; i < 4 && frame->linesize[i]; i++)
+            frame->linesize[i] = FFALIGN(frame->linesize[i], align);
+    }
+
+    for (i = 0; i < 4 && frame->linesize[i]; i++) {
+        int h = frame->height;
+        if (i == 1 || i == 2)
+            h = -((-h) >> desc->log2_chroma_h);
+
+        frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h);
+        if (!frame->buf[i])
+            goto fail;
+
+        frame->data[i] = frame->buf[i]->data;
+    }
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
+        av_buffer_unref(&frame->buf[1]);
+        frame->buf[1] = av_buffer_alloc(1024);
+        if (!frame->buf[1])
+            goto fail;
+        frame->data[1] = frame->buf[1]->data;
+    }
+
+    frame->extended_data = frame->data;
+
+    return 0;
+fail:
+    av_frame_unref(frame);
+    return AVERROR(ENOMEM);
+}
+
+static int get_audio_buffer(AVFrame *frame, int align)
+{
+    int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
+    int planar   = av_sample_fmt_is_planar(frame->format);
+    int planes   = planar ? channels : 1;
+    int ret, i;
+
+    if (!frame->linesize[0]) {
+        ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
+                                         frame->nb_samples, frame->format,
+                                         align);
+        if (ret < 0)
+            return ret;
+    }
+
+    if (planes > AV_NUM_DATA_POINTERS) {
+        frame->extended_data = av_mallocz(planes *
+                                          sizeof(*frame->extended_data));
+        frame->extended_buf  = av_mallocz((planes - AV_NUM_DATA_POINTERS) *
+                                          sizeof(*frame->extended_buf));
+        if (!frame->extended_data || !frame->extended_buf) {
+            av_freep(&frame->extended_data);
+            av_freep(&frame->extended_buf);
+            return AVERROR(ENOMEM);
+        }
+        frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS;
+    } else
+        frame->extended_data = frame->data;
+
+    for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) {
+        frame->buf[i] = av_buffer_alloc(frame->linesize[0]);
+        if (!frame->buf[i]) {
+            av_frame_unref(frame);
+            return AVERROR(ENOMEM);
+        }
+        frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
+    }
+    for (i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) {
+        frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]);
+        if (!frame->extended_buf[i]) {
+            av_frame_unref(frame);
+            return AVERROR(ENOMEM);
+        }
+        frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
+    }
+    return 0;
+
+}
+
+int av_frame_get_buffer(AVFrame *frame, int align)
+{
+    if (frame->format < 0)
+        return AVERROR(EINVAL);
+
+    if (frame->width > 0 && frame->height > 0)
+        return get_video_buffer(frame, align);
+    else if (frame->nb_samples > 0 && frame->channel_layout)
+        return get_audio_buffer(frame, align);
+
+    return AVERROR(EINVAL);
+}
+
+int av_frame_ref(AVFrame *dst, const AVFrame *src)
+{
+    int i, ret = 0;
+
+    dst->format         = src->format;
+    dst->width          = src->width;
+    dst->height         = src->height;
+    dst->channel_layout = src->channel_layout;
+    dst->nb_samples     = src->nb_samples;
+
+    ret = av_frame_copy_props(dst, src);
+    if (ret < 0)
+        return ret;
+
+    /* duplicate the frame data if it's not refcounted */
+    if (!src->buf[0]) {
+        ret = av_frame_get_buffer(dst, 32);
+        if (ret < 0)
+            return ret;
+
+        if (src->nb_samples) {
+            int ch = av_get_channel_layout_nb_channels(src->channel_layout);
+            av_samples_copy(dst->extended_data, src->extended_data, 0, 0,
+                            dst->nb_samples, ch, dst->format);
+        } else {
+            av_image_copy(dst->data, dst->linesize, src->data, src->linesize,
+                          dst->format, dst->width, dst->height);
+        }
+        return 0;
+    }
+
+    /* ref the buffers */
+    for (i = 0; i < FF_ARRAY_ELEMS(src->buf) && src->buf[i]; i++) {
+        dst->buf[i] = av_buffer_ref(src->buf[i]);
+        if (!dst->buf[i]) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+    }
+
+    if (src->extended_buf) {
+        dst->extended_buf = av_mallocz(sizeof(*dst->extended_buf) *
+                                       src->nb_extended_buf);
+        if (!dst->extended_buf) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        dst->nb_extended_buf = src->nb_extended_buf;
+
+        for (i = 0; i < src->nb_extended_buf; i++) {
+            dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]);
+            if (!dst->extended_buf[i]) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
+        }
+    }
+
+    /* duplicate extended data */
+    if (src->extended_data != src->data) {
+        int ch = av_get_channel_layout_nb_channels(src->channel_layout);
+
+        if (!ch) {
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+
+        dst->extended_data = av_malloc(sizeof(*dst->extended_data) * ch);
+        if (!dst->extended_data) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch);
+    } else
+        dst->extended_data = dst->data;
+
+    memcpy(dst->data,     src->data,     sizeof(src->data));
+    memcpy(dst->linesize, src->linesize, sizeof(src->linesize));
+
+    return 0;
+
+fail:
+    av_frame_unref(dst);
+    return ret;
+}
+
+AVFrame *av_frame_clone(const AVFrame *src)
+{
+    AVFrame *ret = av_frame_alloc();
+
+    if (!ret)
+        return NULL;
+
+    if (av_frame_ref(ret, src) < 0)
+        av_frame_free(&ret);
+
+    return ret;
+}
+
+void av_frame_unref(AVFrame *frame)
+{
+    int i;
+
+    for (i = 0; i < frame->nb_side_data; i++) {
+        av_freep(&frame->side_data[i]->data);
+        av_dict_free(&frame->side_data[i]->metadata);
+        av_freep(&frame->side_data[i]);
+    }
+    av_freep(&frame->side_data);
+
+    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
+        av_buffer_unref(&frame->buf[i]);
+    for (i = 0; i < frame->nb_extended_buf; i++)
+        av_buffer_unref(&frame->extended_buf[i]);
+    av_freep(&frame->extended_buf);
+    get_frame_defaults(frame);
+}
+
+void av_frame_move_ref(AVFrame *dst, AVFrame *src)
+{
+    *dst = *src;
+    if (src->extended_data == src->data)
+        dst->extended_data = dst->data;
+    memset(src, 0, sizeof(*src));
+    get_frame_defaults(src);
+}
+
+int av_frame_is_writable(AVFrame *frame)
+{
+    int i, ret = 1;
+
+    /* assume non-refcounted frames are not writable */
+    if (!frame->buf[0])
+        return 0;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++)
+        ret &= !!av_buffer_is_writable(frame->buf[i]);
+    for (i = 0; i < frame->nb_extended_buf; i++)
+        ret &= !!av_buffer_is_writable(frame->extended_buf[i]);
+
+    return ret;
+}
+
+int av_frame_make_writable(AVFrame *frame)
+{
+    AVFrame tmp;
+    int ret;
+
+    if (!frame->buf[0])
+        return AVERROR(EINVAL);
+
+    if (av_frame_is_writable(frame))
+        return 0;
+
+    memset(&tmp, 0, sizeof(tmp));
+    tmp.format         = frame->format;
+    tmp.width          = frame->width;
+    tmp.height         = frame->height;
+    tmp.channel_layout = frame->channel_layout;
+    tmp.nb_samples     = frame->nb_samples;
+    ret = av_frame_get_buffer(&tmp, 32);
+    if (ret < 0)
+        return ret;
+
+    if (tmp.nb_samples) {
+        int ch = av_get_channel_layout_nb_channels(tmp.channel_layout);
+        av_samples_copy(tmp.extended_data, frame->extended_data, 0, 0,
+                        frame->nb_samples, ch, frame->format);
+    } else {
+        av_image_copy(tmp.data, tmp.linesize, frame->data, frame->linesize,
+                      frame->format, frame->width, frame->height);
+    }
+
+    ret = av_frame_copy_props(&tmp, frame);
+    if (ret < 0) {
+        av_frame_unref(&tmp);
+        return ret;
+    }
+
+    av_frame_unref(frame);
+
+    *frame = tmp;
+    if (tmp.data == tmp.extended_data)
+        frame->extended_data = frame->data;
+
+    return 0;
+}
+
+int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
+{
+    int i;
+
+    dst->key_frame              = src->key_frame;
+    dst->pict_type              = src->pict_type;
+    dst->sample_aspect_ratio    = src->sample_aspect_ratio;
+    dst->pts                    = src->pts;
+    dst->repeat_pict            = src->repeat_pict;
+    dst->interlaced_frame       = src->interlaced_frame;
+    dst->top_field_first        = src->top_field_first;
+    dst->palette_has_changed    = src->palette_has_changed;
+    dst->sample_rate            = src->sample_rate;
+    dst->opaque                 = src->opaque;
+    dst->pkt_pts                = src->pkt_pts;
+    dst->pkt_dts                = src->pkt_dts;
+    dst->reordered_opaque       = src->reordered_opaque;
+    dst->quality                = src->quality;
+    dst->coded_picture_number   = src->coded_picture_number;
+    dst->display_picture_number = src->display_picture_number;
+    dst->flags                  = src->flags;
+
+    memcpy(dst->error, src->error, sizeof(dst->error));
+
+    for (i = 0; i < src->nb_side_data; i++) {
+        const AVFrameSideData *sd_src = src->side_data[i];
+        AVFrameSideData *sd_dst = av_frame_new_side_data(dst, sd_src->type,
+                                                         sd_src->size);
+        if (!sd_dst) {
+            for (i = 0; i < dst->nb_side_data; i++) {
+                av_freep(&dst->side_data[i]->data);
+                av_freep(&dst->side_data[i]);
+                av_dict_free(&dst->side_data[i]->metadata);
+            }
+            av_freep(&dst->side_data);
+            return AVERROR(ENOMEM);
+        }
+        memcpy(sd_dst->data, sd_src->data, sd_src->size);
+        av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
+    }
+
+    return 0;
+}
+
+AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane)
+{
+    uint8_t *data;
+    int planes, i;
+
+    if (frame->nb_samples) {
+        int channels = av_get_channel_layout_nb_channels(frame->channel_layout);
+        if (!channels)
+            return NULL;
+        planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
+    } else
+        planes = 4;
+
+    if (plane < 0 || plane >= planes || !frame->extended_data[plane])
+        return NULL;
+    data = frame->extended_data[plane];
+
+    for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) {
+        AVBufferRef *buf = frame->buf[i];
+        if (data >= buf->data && data < buf->data + buf->size)
+            return buf;
+    }
+    for (i = 0; i < frame->nb_extended_buf; i++) {
+        AVBufferRef *buf = frame->extended_buf[i];
+        if (data >= buf->data && data < buf->data + buf->size)
+            return buf;
+    }
+    return NULL;
+}
+
+AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
+                                        enum AVFrameSideDataType type,
+                                        int size)
+{
+    AVFrameSideData *ret, **tmp;
+
+    if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1)
+        return NULL;
+
+    tmp = av_realloc(frame->side_data,
+                     (frame->nb_side_data + 1) * sizeof(*frame->side_data));
+    if (!tmp)
+        return NULL;
+    frame->side_data = tmp;
+
+    ret = av_mallocz(sizeof(*ret));
+    if (!ret)
+        return NULL;
+
+    ret->data = av_malloc(size);
+    if (!ret->data) {
+        av_freep(&ret);
+        return NULL;
+    }
+
+    ret->size = size;
+    ret->type = type;
+
+    frame->side_data[frame->nb_side_data++] = ret;
+
+    return ret;
+}
+
+AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
+                                        enum AVFrameSideDataType type)
+{
+    int i;
+
+    for (i = 0; i < frame->nb_side_data; i++) {
+        if (frame->side_data[i]->type == type)
+            return frame->side_data[i];
+    }
+    return NULL;
+}
diff --git a/libavutil/frame.h b/libavutil/frame.h
new file mode 100644
index 0000000..1b3db98
--- /dev/null
+++ b/libavutil/frame.h
@@ -0,0 +1,515 @@
+/*
+ *
+ * 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 AVUTIL_FRAME_H
+#define AVUTIL_FRAME_H
+
+#include <stdint.h>
+
+#include "libavcodec/version.h"
+
+#include "avutil.h"
+#include "buffer.h"
+#include "dict.h"
+#include "rational.h"
+#include "samplefmt.h"
+
+enum AVFrameSideDataType {
+    /**
+     * The data is the AVPanScan struct defined in libavcodec.
+     */
+    AV_FRAME_DATA_PANSCAN,
+    /**
+     * ATSC A53 Part 4 Closed Captions.
+     * A53 CC bitstream is stored as uint8_t in AVFrameSideData.data.
+     * The number of bytes of CC data is AVFrameSideData.size.
+     */
+    AV_FRAME_DATA_A53_CC,
+    /**
+     * Stereoscopic 3d metadata.
+     * The data is the AVStereo3D struct defined in libavutil/stereo3d.h.
+     */
+    AV_FRAME_DATA_STEREO3D,
+};
+
+typedef struct AVFrameSideData {
+    enum AVFrameSideDataType type;
+    uint8_t *data;
+    int      size;
+    AVDictionary *metadata;
+} AVFrameSideData;
+
+/**
+ * This structure describes decoded (raw) audio or video data.
+ *
+ * AVFrame must be allocated using av_frame_alloc(). Not that this only
+ * allocates the AVFrame itself, the buffers for the data must be managed
+ * through other means (see below).
+ * AVFrame must be freed with av_frame_free().
+ *
+ * AVFrame is typically allocated once and then reused multiple times to hold
+ * different data (e.g. a single AVFrame to hold frames received from a
+ * decoder). In such a case, av_frame_unref() will free any references held by
+ * the frame and reset it to its original clean state before it
+ * is reused again.
+ *
+ * The data described by an AVFrame is usually reference counted through the
+ * AVBuffer API. The underlying buffer references are stored in AVFrame.buf /
+ * AVFrame.extended_buf. An AVFrame is considered to be reference counted if at
+ * least one reference is set, i.e. if AVFrame.buf[0] != NULL. In such a case,
+ * every single data plane must be contained in one of the buffers in
+ * AVFrame.buf or AVFrame.extended_buf.
+ * There may be a single buffer for all the data, or one separate buffer for
+ * each plane, or anything in between.
+ *
+ * sizeof(AVFrame) is not a part of the public ABI, so new fields may be added
+ * to the end with a minor bump.
+ */
+typedef struct AVFrame {
+#define AV_NUM_DATA_POINTERS 8
+    /**
+     * pointer to the picture/channel planes.
+     * This might be different from the first allocated byte
+     */
+    uint8_t *data[AV_NUM_DATA_POINTERS];
+
+    /**
+     * For video, size in bytes of each picture line.
+     * For audio, size in bytes of each plane.
+     *
+     * For audio, only linesize[0] may be set. For planar audio, each channel
+     * plane must be the same size.
+     *
+     * @note The linesize may be larger than the size of usable data -- there
+     * may be extra padding present for performance reasons.
+     */
+    int linesize[AV_NUM_DATA_POINTERS];
+
+    /**
+     * pointers to the data planes/channels.
+     *
+     * For video, this should simply point to data[].
+     *
+     * For planar audio, each channel has a separate data pointer, and
+     * linesize[0] contains the size of each channel buffer.
+     * For packed audio, there is just one data pointer, and linesize[0]
+     * contains the total size of the buffer for all channels.
+     *
+     * Note: Both data and extended_data should always be set in a valid frame,
+     * but for planar audio with more channels that can fit in data,
+     * extended_data must be used in order to access all channels.
+     */
+    uint8_t **extended_data;
+
+    /**
+     * width and height of the video frame
+     */
+    int width, height;
+
+    /**
+     * number of audio samples (per channel) described by this frame
+     */
+    int nb_samples;
+
+    /**
+     * format of the frame, -1 if unknown or unset
+     * Values correspond to enum AVPixelFormat for video frames,
+     * enum AVSampleFormat for audio)
+     */
+    int format;
+
+    /**
+     * 1 -> keyframe, 0-> not
+     */
+    int key_frame;
+
+    /**
+     * Picture type of the frame.
+     */
+    enum AVPictureType pict_type;
+
+#if FF_API_AVFRAME_LAVC
+    attribute_deprecated
+    uint8_t *base[AV_NUM_DATA_POINTERS];
+#endif
+
+    /**
+     * Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
+     */
+    AVRational sample_aspect_ratio;
+
+    /**
+     * Presentation timestamp in time_base units (time when frame should be shown to user).
+     */
+    int64_t pts;
+
+    /**
+     * PTS copied from the AVPacket that was decoded to produce this frame.
+     */
+    int64_t pkt_pts;
+
+    /**
+     * DTS copied from the AVPacket that triggered returning this frame.
+     */
+    int64_t pkt_dts;
+
+    /**
+     * picture number in bitstream order
+     */
+    int coded_picture_number;
+    /**
+     * picture number in display order
+     */
+    int display_picture_number;
+
+    /**
+     * quality (between 1 (good) and FF_LAMBDA_MAX (bad))
+     */
+    int quality;
+
+#if FF_API_AVFRAME_LAVC
+    attribute_deprecated
+    int reference;
+
+    /**
+     * QP table
+     */
+    attribute_deprecated
+    int8_t *qscale_table;
+    /**
+     * QP store stride
+     */
+    attribute_deprecated
+    int qstride;
+
+    attribute_deprecated
+    int qscale_type;
+
+    /**
+     * mbskip_table[mb]>=1 if MB didn't change
+     * stride= mb_width = (width+15)>>4
+     */
+    attribute_deprecated
+    uint8_t *mbskip_table;
+
+    /**
+     * motion vector table
+     * @code
+     * example:
+     * int mv_sample_log2= 4 - motion_subsample_log2;
+     * int mb_width= (width+15)>>4;
+     * int mv_stride= (mb_width << mv_sample_log2) + 1;
+     * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];
+     * @endcode
+     */
+    attribute_deprecated
+    int16_t (*motion_val[2])[2];
+
+    /**
+     * macroblock type table
+     * mb_type_base + mb_width + 2
+     */
+    attribute_deprecated
+    uint32_t *mb_type;
+
+    /**
+     * DCT coefficients
+     */
+    attribute_deprecated
+    short *dct_coeff;
+
+    /**
+     * motion reference frame index
+     * the order in which these are stored can depend on the codec.
+     */
+    attribute_deprecated
+    int8_t *ref_index[2];
+#endif
+
+    /**
+     * for some private data of the user
+     */
+    void *opaque;
+
+    /**
+     * error
+     */
+    uint64_t error[AV_NUM_DATA_POINTERS];
+
+#if FF_API_AVFRAME_LAVC
+    attribute_deprecated
+    int type;
+#endif
+
+    /**
+     * When decoding, this signals how much the picture must be delayed.
+     * extra_delay = repeat_pict / (2*fps)
+     */
+    int repeat_pict;
+
+    /**
+     * The content of the picture is interlaced.
+     */
+    int interlaced_frame;
+
+    /**
+     * If the content is interlaced, is top field displayed first.
+     */
+    int top_field_first;
+
+    /**
+     * Tell user application that palette has changed from previous frame.
+     */
+    int palette_has_changed;
+
+#if FF_API_AVFRAME_LAVC
+    attribute_deprecated
+    int buffer_hints;
+
+    /**
+     * Pan scan.
+     */
+    attribute_deprecated
+    struct AVPanScan *pan_scan;
+#endif
+
+    /**
+     * reordered opaque 64bit (generally an integer or a double precision float
+     * PTS but can be anything).
+     * The user sets AVCodecContext.reordered_opaque to represent the input at
+     * that time,
+     * the decoder reorders values as needed and sets AVFrame.reordered_opaque
+     * to exactly one of the values provided by the user through AVCodecContext.reordered_opaque
+     * @deprecated in favor of pkt_pts
+     */
+    int64_t reordered_opaque;
+
+#if FF_API_AVFRAME_LAVC
+    /**
+     * @deprecated this field is unused
+     */
+    attribute_deprecated void *hwaccel_picture_private;
+
+    attribute_deprecated
+    struct AVCodecContext *owner;
+    attribute_deprecated
+    void *thread_opaque;
+
+    /**
+     * log2 of the size of the block which a single vector in motion_val represents:
+     * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
+     */
+    attribute_deprecated
+    uint8_t motion_subsample_log2;
+#endif
+
+    /**
+     * Sample rate of the audio data.
+     */
+    int sample_rate;
+
+    /**
+     * Channel layout of the audio data.
+     */
+    uint64_t channel_layout;
+
+    /**
+     * AVBuffer references backing the data for this frame. If all elements of
+     * this array are NULL, then this frame is not reference counted.
+     *
+     * There may be at most one AVBuffer per data plane, so for video this array
+     * always contains all the references. For planar audio with more than
+     * AV_NUM_DATA_POINTERS channels, there may be more buffers than can fit in
+     * this array. Then the extra AVBufferRef pointers are stored in the
+     * extended_buf array.
+     */
+    AVBufferRef *buf[AV_NUM_DATA_POINTERS];
+
+    /**
+     * For planar audio which requires more than AV_NUM_DATA_POINTERS
+     * AVBufferRef pointers, this array will hold all the references which
+     * cannot fit into AVFrame.buf.
+     *
+     * Note that this is different from AVFrame.extended_data, which always
+     * contains all the pointers. This array only contains the extra pointers,
+     * which cannot fit into AVFrame.buf.
+     *
+     * This array is always allocated using av_malloc() by whoever constructs
+     * the frame. It is freed in av_frame_unref().
+     */
+    AVBufferRef **extended_buf;
+    /**
+     * Number of elements in extended_buf.
+     */
+    int        nb_extended_buf;
+
+    AVFrameSideData **side_data;
+    int            nb_side_data;
+
+/**
+ * The frame data may be corrupted, e.g. due to decoding errors.
+ */
+#define AV_FRAME_FLAG_CORRUPT       (1 << 0)
+
+    /**
+     * Frame flags, a combination of AV_FRAME_FLAG_*
+     */
+    int flags;
+} AVFrame;
+
+/**
+ * Allocate an AVFrame and set its fields to default values.  The resulting
+ * struct must be freed using av_frame_free().
+ *
+ * @return An AVFrame filled with default values or NULL on failure.
+ *
+ * @note this only allocates the AVFrame itself, not the data buffers. Those
+ * must be allocated through other means, e.g. with av_frame_get_buffer() or
+ * manually.
+ */
+AVFrame *av_frame_alloc(void);
+
+/**
+ * Free the frame and any dynamically allocated objects in it,
+ * e.g. extended_data. If the frame is reference counted, it will be
+ * unreferenced first.
+ *
+ * @param frame frame to be freed. The pointer will be set to NULL.
+ */
+void av_frame_free(AVFrame **frame);
+
+/**
+ * Setup a new reference to the data described by an given frame.
+ *
+ * Copy frame properties from src to dst and create a new reference for each
+ * AVBufferRef from src.
+ *
+ * If src is not reference counted, new buffers are allocated and the data is
+ * copied.
+ *
+ * @return 0 on success, a negative AVERROR on error
+ */
+int av_frame_ref(AVFrame *dst, const AVFrame *src);
+
+/**
+ * Create a new frame that references the same data as src.
+ *
+ * This is a shortcut for av_frame_alloc()+av_frame_ref().
+ *
+ * @return newly created AVFrame on success, NULL on error.
+ */
+AVFrame *av_frame_clone(const AVFrame *src);
+
+/**
+ * Unreference all the buffers referenced by frame and reset the frame fields.
+ */
+void av_frame_unref(AVFrame *frame);
+
+/**
+ * Move everythnig contained in src to dst and reset src.
+ */
+void av_frame_move_ref(AVFrame *dst, AVFrame *src);
+
+/**
+ * Allocate new buffer(s) for audio or video data.
+ *
+ * The following fields must be set on frame before calling this function:
+ * - format (pixel format for video, sample format for audio)
+ * - width and height for video
+ * - nb_samples and channel_layout for audio
+ *
+ * This function will fill AVFrame.data and AVFrame.buf arrays and, if
+ * necessary, allocate and fill AVFrame.extended_data and AVFrame.extended_buf.
+ * For planar formats, one buffer will be allocated for each plane.
+ *
+ * @param frame frame in which to store the new buffers.
+ * @param align required buffer size alignment
+ *
+ * @return 0 on success, a negative AVERROR on error.
+ */
+int av_frame_get_buffer(AVFrame *frame, int align);
+
+/**
+ * Check if the frame data is writable.
+ *
+ * @return A positive value if the frame data is writable (which is true if and
+ * only if each of the underlying buffers has only one reference, namely the one
+ * stored in this frame). Return 0 otherwise.
+ *
+ * If 1 is returned the answer is valid until av_buffer_ref() is called on any
+ * of the underlying AVBufferRefs (e.g. through av_frame_ref() or directly).
+ *
+ * @see av_frame_make_writable(), av_buffer_is_writable()
+ */
+int av_frame_is_writable(AVFrame *frame);
+
+/**
+ * Ensure that the frame data is writable, avoiding data copy if possible.
+ *
+ * Do nothing if the frame is writable, allocate new buffers and copy the data
+ * if it is not.
+ *
+ * @return 0 on success, a negative AVERROR on error.
+ *
+ * @see av_frame_is_writable(), av_buffer_is_writable(),
+ * av_buffer_make_writable()
+ */
+int av_frame_make_writable(AVFrame *frame);
+
+/**
+ * Copy only "metadata" fields from src to dst.
+ *
+ * Metadata for the purpose of this function are those fields that do not affect
+ * the data layout in the buffers.  E.g. pts, sample rate (for audio) or sample
+ * aspect ratio (for video), but not width/height or channel layout.
+ * Side data is also copied.
+ */
+int av_frame_copy_props(AVFrame *dst, const AVFrame *src);
+
+/**
+ * Get the buffer reference a given data plane is stored in.
+ *
+ * @param plane index of the data plane of interest in frame->extended_data.
+ *
+ * @return the buffer reference that contains the plane or NULL if the input
+ * frame is not valid.
+ */
+AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane);
+
+/**
+ * Add a new side data to a frame.
+ *
+ * @param frame a frame to which the side data should be added
+ * @param type type of the added side data
+ * @param size size of the side data
+ *
+ * @return newly added side data on success, NULL on error
+ */
+AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
+                                        enum AVFrameSideDataType type,
+                                        int size);
+
+/**
+ * @return a pointer to the side data of a given type on success, NULL if there
+ * is no side data with such type in this frame.
+ */
+AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
+                                        enum AVFrameSideDataType type);
+
+#endif /* AVUTIL_FRAME_H */
diff --git a/libavutil/hmac.c b/libavutil/hmac.c
new file mode 100644
index 0000000..f87728e
--- /dev/null
+++ b/libavutil/hmac.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2012 Martin Storsjo
+ *
+ * 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 <string.h>
+
+#include "attributes.h"
+#include "hmac.h"
+#include "md5.h"
+#include "sha.h"
+#include "mem.h"
+
+#define MAX_HASHLEN 20
+#define MAX_BLOCKLEN 64
+
+struct AVHMAC {
+    void *hash;
+    int blocklen, hashlen;
+    void (*final)(void*, uint8_t*);
+    void (*update)(void*, const uint8_t*, int len);
+    void (*init)(void*);
+    uint8_t key[MAX_BLOCKLEN];
+    int keylen;
+};
+
+static av_cold void sha1_init(void *ctx)
+{
+    av_sha_init(ctx, 160);
+}
+
+AVHMAC *av_hmac_alloc(enum AVHMACType type)
+{
+    AVHMAC *c = av_mallocz(sizeof(*c));
+    if (!c)
+        return NULL;
+    switch (type) {
+    case AV_HMAC_MD5:
+        c->blocklen = 64;
+        c->hashlen  = 16;
+        c->init     = av_md5_init;
+        c->update   = av_md5_update;
+        c->final    = av_md5_final;
+        c->hash     = av_md5_alloc();
+        break;
+    case AV_HMAC_SHA1:
+        c->blocklen = 64;
+        c->hashlen  = 20;
+        c->init     = sha1_init;
+        c->update   = av_sha_update;
+        c->final    = av_sha_final;
+        c->hash     = av_sha_alloc();
+        break;
+    default:
+        av_free(c);
+        return NULL;
+    }
+    if (!c->hash) {
+        av_free(c);
+        return NULL;
+    }
+    return c;
+}
+
+void av_hmac_free(AVHMAC *c)
+{
+    if (!c)
+        return;
+    av_free(c->hash);
+    av_free(c);
+}
+
+void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
+{
+    int i;
+    uint8_t block[MAX_BLOCKLEN];
+    if (keylen > c->blocklen) {
+        c->init(c->hash);
+        c->update(c->hash, key, keylen);
+        c->final(c->hash, c->key);
+        c->keylen = c->hashlen;
+    } else {
+        memcpy(c->key, key, keylen);
+        c->keylen = keylen;
+    }
+    c->init(c->hash);
+    for (i = 0; i < c->keylen; i++)
+        block[i] = c->key[i] ^ 0x36;
+    for (i = c->keylen; i < c->blocklen; i++)
+        block[i] = 0x36;
+    c->update(c->hash, block, c->blocklen);
+}
+
+void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
+{
+    c->update(c->hash, data, len);
+}
+
+int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
+{
+    uint8_t block[MAX_BLOCKLEN];
+    int i;
+    if (outlen < c->hashlen)
+        return AVERROR(EINVAL);
+    c->final(c->hash, out);
+    c->init(c->hash);
+    for (i = 0; i < c->keylen; i++)
+        block[i] = c->key[i] ^ 0x5C;
+    for (i = c->keylen; i < c->blocklen; i++)
+        block[i] = 0x5C;
+    c->update(c->hash, block, c->blocklen);
+    c->update(c->hash, out, c->hashlen);
+    c->final(c->hash, out);
+    return c->hashlen;
+}
+
+int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len,
+                 const uint8_t *key, unsigned int keylen,
+                 uint8_t *out, unsigned int outlen)
+{
+    av_hmac_init(c, key, keylen);
+    av_hmac_update(c, data, len);
+    return av_hmac_final(c, out, outlen);
+}
+
+#ifdef TEST
+#include <stdio.h>
+
+static void test(AVHMAC *hmac, const uint8_t *key, int keylen,
+                 const uint8_t *data, int datalen)
+{
+    uint8_t buf[MAX_HASHLEN];
+    int out, i;
+    // Some of the test vectors are strings, where sizeof() includes the
+    // trailing null byte - remove that.
+    if (!key[keylen - 1])
+        keylen--;
+    if (!data[datalen - 1])
+        datalen--;
+    out = av_hmac_calc(hmac, data, datalen, key, keylen, buf, sizeof(buf));
+    for (i = 0; i < out; i++)
+        printf("%02x", buf[i]);
+    printf("\n");
+}
+
+int main(void)
+{
+    uint8_t key1[16], key3[16], data3[50], key4[63], key5[64], key6[65];
+    const uint8_t key2[]  = "Jefe";
+    const uint8_t data1[] = "Hi There";
+    const uint8_t data2[] = "what do ya want for nothing?";
+    AVHMAC *hmac = av_hmac_alloc(AV_HMAC_MD5);
+    if (!hmac)
+        return 1;
+    memset(key1, 0x0b, sizeof(key1));
+    memset(key3, 0xaa, sizeof(key3));
+    memset(key4, 0x44, sizeof(key4));
+    memset(key5, 0x55, sizeof(key5));
+    memset(key6, 0x66, sizeof(key6));
+    memset(data3, 0xdd, sizeof(data3));
+    // RFC 2104 test vectors
+    test(hmac, key1, sizeof(key1), data1, sizeof(data1));
+    test(hmac, key2, sizeof(key2), data2, sizeof(data2));
+    test(hmac, key3, sizeof(key3), data3, sizeof(data3));
+    // Additional tests, to test cases where the key is too long
+    test(hmac, key4, sizeof(key4), data1, sizeof(data1));
+    test(hmac, key5, sizeof(key5), data2, sizeof(data2));
+    test(hmac, key6, sizeof(key6), data3, sizeof(data3));
+    av_hmac_free(hmac);
+    return 0;
+}
+#endif /* TEST */
diff --git a/libavutil/hmac.h b/libavutil/hmac.h
new file mode 100644
index 0000000..28c2062
--- /dev/null
+++ b/libavutil/hmac.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012 Martin Storsjo
+ *
+ * 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 AVUTIL_HMAC_H
+#define AVUTIL_HMAC_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup lavu_hmac HMAC
+ * @ingroup lavu_crypto
+ * @{
+ */
+
+enum AVHMACType {
+    AV_HMAC_MD5,
+    AV_HMAC_SHA1,
+};
+
+typedef struct AVHMAC AVHMAC;
+
+/**
+ * Allocate an AVHMAC context.
+ * @param type The hash function used for the HMAC.
+ */
+AVHMAC *av_hmac_alloc(enum AVHMACType type);
+
+/**
+ * Free an AVHMAC context.
+ * @param ctx The context to free, may be NULL
+ */
+void av_hmac_free(AVHMAC *ctx);
+
+/**
+ * Initialize an AVHMAC context with an authentication key.
+ * @param ctx    The HMAC context
+ * @param key    The authentication key
+ * @param keylen The length of the key, in bytes
+ */
+void av_hmac_init(AVHMAC *ctx, const uint8_t *key, unsigned int keylen);
+
+/**
+ * Hash data with the HMAC.
+ * @param ctx  The HMAC context
+ * @param data The data to hash
+ * @param len  The length of the data, in bytes
+ */
+void av_hmac_update(AVHMAC *ctx, const uint8_t *data, unsigned int len);
+
+/**
+ * Finish hashing and output the HMAC digest.
+ * @param ctx    The HMAC context
+ * @param out    The output buffer to write the digest into
+ * @param outlen The length of the out buffer, in bytes
+ * @return       The number of bytes written to out, or a negative error code.
+ */
+int av_hmac_final(AVHMAC *ctx, uint8_t *out, unsigned int outlen);
+
+/**
+ * Hash an array of data with a key.
+ * @param ctx    The HMAC context
+ * @param data   The data to hash
+ * @param len    The length of the data, in bytes
+ * @param key    The authentication key
+ * @param keylen The length of the key, in bytes
+ * @param out    The output buffer to write the digest into
+ * @param outlen The length of the out buffer, in bytes
+ * @return       The number of bytes written to out, or a negative error code.
+ */
+int av_hmac_calc(AVHMAC *ctx, const uint8_t *data, unsigned int len,
+                 const uint8_t *key, unsigned int keylen,
+                 uint8_t *out, unsigned int outlen);
+
+/**
+ * @}
+ */
+
+#endif /* AVUTIL_HMAC_H */
diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c
index 413329d..a8b4d2a 100644
--- a/libavutil/imgutils.c
+++ b/libavutil/imgutils.c
@@ -55,7 +55,7 @@ int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
     if (!desc)
         return AVERROR(EINVAL);
 
-    if (desc->flags & PIX_FMT_BITSTREAM)
+    if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
         return (width * (desc->comp[0].step_minus1+1) + 7) >> 3;
 
     av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
@@ -72,10 +72,10 @@ int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int wi
 
     memset(linesizes, 0, 4*sizeof(linesizes[0]));
 
-    if (!desc || desc->flags & PIX_FMT_HWACCEL)
+    if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
         return AVERROR(EINVAL);
 
-    if (desc->flags & PIX_FMT_BITSTREAM) {
+    if (desc->flags & AV_PIX_FMT_FLAG_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;
@@ -102,7 +102,7 @@ int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int hei
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     memset(data     , 0, sizeof(data[0])*4);
 
-    if (!desc || desc->flags & PIX_FMT_HWACCEL)
+    if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
         return AVERROR(EINVAL);
 
     data[0] = ptr;
@@ -110,8 +110,8 @@ int av_image_fill_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt, int hei
         return AVERROR(EINVAL);
     size[0] = linesizes[0] * height;
 
-    if (desc->flags & PIX_FMT_PAL ||
-        desc->flags & PIX_FMT_PSEUDOPAL) {
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
+        desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
         size[0] = (size[0] + 3) & ~3;
         data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */
         return size[0] + 256 * 4;
@@ -203,7 +203,7 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4],
         av_free(buf);
         return ret;
     }
-    if (desc->flags & PIX_FMT_PAL || desc->flags & PIX_FMT_PSEUDOPAL)
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
         avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt);
 
     return ret;
@@ -247,11 +247,11 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
 
-    if (!desc || desc->flags & PIX_FMT_HWACCEL)
+    if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
         return;
 
-    if (desc->flags & PIX_FMT_PAL ||
-        desc->flags & PIX_FMT_PSEUDOPAL) {
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
+        desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
         av_image_copy_plane(dst_data[0], dst_linesizes[0],
                             src_data[0], src_linesizes[0],
                             width, height);
diff --git a/libavutil/internal.h b/libavutil/internal.h
index f0f5a63..33a5226 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -39,6 +39,14 @@
 #include "timer.h"
 #include "dict.h"
 
+#if ARCH_X86
+#   include "x86/emms.h"
+#endif
+
+#ifndef emms_c
+#   define emms_c()
+#endif
+
 #ifndef attribute_align_arg
 #if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
 #    define attribute_align_arg __attribute__((force_align_arg_pointer))
@@ -53,10 +61,52 @@
 #    define av_export
 #endif
 
+#if HAVE_PRAGMA_DEPRECATED
+#    if defined(__ICL)
+#        define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478))
+#        define FF_ENABLE_DEPRECATION_WARNINGS  __pragma(warning(pop))
+#    elif defined(_MSC_VER)
+#        define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996))
+#        define FF_ENABLE_DEPRECATION_WARNINGS  __pragma(warning(pop))
+#    else
+#        define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#        define FF_ENABLE_DEPRECATION_WARNINGS  _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"")
+#    endif
+#else
+#    define FF_DISABLE_DEPRECATION_WARNINGS
+#    define FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
 #ifndef INT_BIT
 #    define INT_BIT (CHAR_BIT * sizeof(int))
 #endif
 
+// Some broken preprocessors need a second expansion
+// to be forced to tokenize __VA_ARGS__
+#define E1(x) x
+
+#define LOCAL_ALIGNED_A(a, t, v, s, o, ...)             \
+    uint8_t la_##v[sizeof(t s o) + (a)];                \
+    t (*v) o = (void *)FFALIGN((uintptr_t)la_##v, a)
+
+#define LOCAL_ALIGNED_D(a, t, v, s, o, ...)             \
+    DECLARE_ALIGNED(a, t, la_##v) s o;                  \
+    t (*v) o = la_##v
+
+#define LOCAL_ALIGNED(a, t, v, ...) E1(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,))
+
+#if HAVE_LOCAL_ALIGNED_8
+#   define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
+#else
+#   define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__)
+#endif
+
+#if HAVE_LOCAL_ALIGNED_16
+#   define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
+#else
+#   define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__)
+#endif
+
 #define FF_ALLOC_OR_GOTO(ctx, p, size, label)\
 {\
     p = av_malloc(size);\
@@ -77,6 +127,11 @@
 
 #include "libm.h"
 
+#if defined(_MSC_VER)
+#pragma comment(linker, "/include:"EXTERN_PREFIX"avpriv_strtod")
+#pragma comment(linker, "/include:"EXTERN_PREFIX"avpriv_snprintf")
+#endif
+
 /**
  * Return NULL if CONFIG_SMALL is true, otherwise the argument
  * without modification. Used to disable the definition of strings
@@ -128,21 +183,34 @@
 #   define ONLY_IF_THREADS_ENABLED(x) NULL
 #endif
 
-#if HAVE_MMX_INLINE
 /**
- * Empty mmx state.
- * this must be called between any dsp function and float/double code.
- * for example sin(); dsp->idct_put(); emms_c(); cos()
+ * Log a generic warning message about a missing feature.
+ *
+ * @param[in] avc a pointer to an arbitrary struct of which the first
+ *                field is a pointer to an AVClass struct
+ * @param[in] msg string containing the name of the missing feature
  */
-static av_always_inline void emms_c(void)
-{
-    __asm__ volatile ("emms" ::: "memory");
-}
-#elif HAVE_MMX && HAVE_MM_EMPTY
-#   include <mmintrin.h>
-#   define emms_c _mm_empty
-#else
-#   define emms_c()
-#endif /* HAVE_MMX_INLINE */
+void avpriv_report_missing_feature(void *avc,
+                                   const char *msg, ...) av_printf_format(2, 3);
+
+/**
+ * Log a generic warning message about a missing feature.
+ * Additionally request that a sample showcasing the feature be uploaded.
+ *
+ * @param[in] avc a pointer to an arbitrary struct of which the first field is
+ *                a pointer to an AVClass struct
+ * @param[in] msg string containing the name of the missing feature
+ */
+void avpriv_request_sample(void *avc,
+                           const char *msg, ...) av_printf_format(2, 3);
+
+#if HAVE_LIBC_MSVCRT
+#define avpriv_open ff_open
+#endif
+
+/**
+ * A wrapper for open() setting O_CLOEXEC.
+ */
+int avpriv_open(const char *filename, int flags, ...);
 
 #endif /* AVUTIL_INTERNAL_H */
diff --git a/libavutil/intfloat_readwrite.c b/libavutil/intfloat_readwrite.c
deleted file mode 100644
index 6838563..0000000
--- a/libavutil/intfloat_readwrite.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * portable IEEE float/double read/write functions
- *
- * Copyright (c) 2005 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- * portable IEEE float/double read/write functions
- */
-
-#include <stdint.h>
-#include "mathematics.h"
-#include "intfloat_readwrite.h"
-
-double av_int2dbl(int64_t v){
-    if((uint64_t)v+v > 0xFFEULL<<52)
-        return NAN;
-    return ldexp(((v&((1LL<<52)-1)) + (1LL<<52)) * (v>>63|1), (v>>52&0x7FF)-1075);
-}
-
-float av_int2flt(int32_t v){
-    if((uint32_t)v+v > 0xFF000000U)
-        return NAN;
-    return ldexp(((v&0x7FFFFF) + (1<<23)) * (v>>31|1), (v>>23&0xFF)-150);
-}
-
-double av_ext2dbl(const AVExtFloat ext){
-    uint64_t m = 0;
-    int e, i;
-
-    for (i = 0; i < 8; i++)
-        m = (m<<8) + ext.mantissa[i];
-    e = (((int)ext.exponent[0]&0x7f)<<8) | ext.exponent[1];
-    if (e == 0x7fff && m)
-        return NAN;
-    e -= 16383 + 63;        /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
-                             * mantissa bit is written as opposed to the
-                             * single and double precision formats. */
-    if (ext.exponent[0]&0x80)
-        m= -m;
-    return ldexp(m, e);
-}
-
-int64_t av_dbl2int(double d){
-    int e;
-    if     ( !d) return 0;
-    else if(d-d) return 0x7FF0000000000000LL + ((int64_t)(d<0)<<63) + (d!=d);
-    d= frexp(d, &e);
-    return (int64_t)(d<0)<<63 | (e+1022LL)<<52 | (int64_t)((fabs(d)-0.5)*(1LL<<53));
-}
-
-int32_t av_flt2int(float d){
-    int e;
-    if     ( !d) return 0;
-    else if(d-d) return 0x7F800000 + ((d<0)<<31) + (d!=d);
-    d= frexp(d, &e);
-    return (d<0)<<31 | (e+126)<<23 | (int64_t)((fabs(d)-0.5)*(1<<24));
-}
-
-AVExtFloat av_dbl2ext(double d){
-    struct AVExtFloat ext= {{0}};
-    int e, i; double f; uint64_t m;
-
-    f = fabs(frexp(d, &e));
-    if (f >= 0.5 && f < 1) {
-        e += 16382;
-        ext.exponent[0] = e>>8;
-        ext.exponent[1] = e;
-        m = (uint64_t)ldexp(f, 64);
-        for (i=0; i < 8; i++)
-            ext.mantissa[i] = m>>(56-(i<<3));
-    } else if (f != 0.0) {
-        ext.exponent[0] = 0x7f; ext.exponent[1] = 0xff;
-        if (f != INFINITY)
-            ext.mantissa[0] = ~0;
-    }
-    if (d < 0)
-        ext.exponent[0] |= 0x80;
-    return ext;
-}
diff --git a/libavutil/intfloat_readwrite.h b/libavutil/intfloat_readwrite.h
deleted file mode 100644
index f093b92..0000000
--- a/libavutil/intfloat_readwrite.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * copyright (c) 2005 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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 AVUTIL_INTFLOAT_READWRITE_H
-#define AVUTIL_INTFLOAT_READWRITE_H
-
-#include <stdint.h>
-#include "attributes.h"
-
-/* IEEE 80 bits extended float */
-typedef struct AVExtFloat  {
-    uint8_t exponent[2];
-    uint8_t mantissa[8];
-} AVExtFloat;
-
-attribute_deprecated double av_int2dbl(int64_t v) av_const;
-attribute_deprecated float av_int2flt(int32_t v) av_const;
-attribute_deprecated double av_ext2dbl(const AVExtFloat ext) av_const;
-attribute_deprecated int64_t av_dbl2int(double d) av_const;
-attribute_deprecated int32_t av_flt2int(float d) av_const;
-attribute_deprecated AVExtFloat av_dbl2ext(double d) av_const;
-
-#endif /* AVUTIL_INTFLOAT_READWRITE_H */
diff --git a/libavutil/lls.c b/libavutil/lls.c
index b29fc96..f87c2cd 100644
--- a/libavutil/lls.c
+++ b/libavutil/lls.c
@@ -28,31 +28,26 @@
 #include <math.h>
 #include <string.h>
 
+#include "attributes.h"
+#include "version.h"
 #include "lls.h"
 
-void av_init_lls(LLSModel *m, int indep_count)
-{
-    memset(m, 0, sizeof(LLSModel));
-    m->indep_count = indep_count;
-}
-
-void av_update_lls(LLSModel *m, double *var, double decay)
+static void update_lls(LLSModel *m, double *var)
 {
     int i, j;
 
     for (i = 0; i <= m->indep_count; i++) {
         for (j = i; j <= m->indep_count; j++) {
-            m->covariance[i][j] *= decay;
             m->covariance[i][j] += var[i] * var[j];
         }
     }
 }
 
-void av_solve_lls(LLSModel *m, double threshold, int min_order)
+void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order)
 {
     int i, j, k;
-    double (*factor)[MAX_VARS + 1] = (void *) &m->covariance[1][0];
-    double (*covar) [MAX_VARS + 1] = (void *) &m->covariance[1][1];
+    double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0];
+    double (*covar) [MAX_VARS_ALIGN] = (void *) &m->covariance[1][1];
     double *covar_y                = m->covariance[0];
     int count                      = m->indep_count;
 
@@ -105,7 +100,7 @@ void av_solve_lls(LLSModel *m, double threshold, int min_order)
     }
 }
 
-double av_evaluate_lls(LLSModel *m, double *param, int order)
+static double evaluate_lls(LLSModel *m, double *param, int order)
 {
     int i;
     double out = 0;
@@ -116,6 +111,35 @@ double av_evaluate_lls(LLSModel *m, double *param, int order)
     return out;
 }
 
+av_cold void avpriv_init_lls(LLSModel *m, int indep_count)
+{
+    memset(m, 0, sizeof(LLSModel));
+    m->indep_count = indep_count;
+    m->update_lls = update_lls;
+    m->evaluate_lls = evaluate_lls;
+    if (ARCH_X86)
+        ff_init_lls_x86(m);
+}
+
+#if FF_API_LLS_PRIVATE
+av_cold void av_init_lls(LLSModel *m, int indep_count)
+{
+    avpriv_init_lls(m, indep_count);
+}
+void av_update_lls(LLSModel *m, double *param, double decay)
+{
+    m->update_lls(m, param);
+}
+void av_solve_lls(LLSModel *m, double threshold, int min_order)
+{
+    avpriv_solve_lls(m, threshold, min_order);
+}
+double av_evaluate_lls(LLSModel *m, double *param, int order)
+{
+    return m->evaluate_lls(m, param, order);
+}
+#endif /* FF_API_LLS_PRIVATE */
+
 #ifdef TEST
 
 #include <stdio.h>
@@ -129,20 +153,20 @@ int main(void)
     AVLFG lfg;
 
     av_lfg_init(&lfg, 1);
-    av_init_lls(&m, 3);
+    avpriv_init_lls(&m, 3);
 
     for (i = 0; i < 100; i++) {
-        double var[4];
+        LOCAL_ALIGNED(32, double, var, [4]);
         double eval;
 
         var[0] = (av_lfg_get(&lfg) / (double) UINT_MAX - 0.5) * 2;
         var[1] = var[0] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
         var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
         var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
-        av_update_lls(&m, var, 0.99);
-        av_solve_lls(&m, 0.001, 0);
+        m.update_lls(&m, var);
+        avpriv_solve_lls(&m, 0.001, 0);
         for (order = 0; order < 3; order++) {
-            eval = av_evaluate_lls(&m, var + 1, order);
+            eval = m.evaluate_lls(&m, var + 1, order);
             printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n",
                    var[0], order, eval, sqrt(m.variance[order] / (i + 1)),
                    m.coeff[order][0], m.coeff[order][1],
diff --git a/libavutil/lls.h b/libavutil/lls.h
index 3db391b..27c0d5e 100644
--- a/libavutil/lls.h
+++ b/libavutil/lls.h
@@ -23,23 +23,49 @@
 #ifndef AVUTIL_LLS_H
 #define AVUTIL_LLS_H
 
+#include "common.h"
+#include "mem.h"
+#include "version.h"
+
 #define MAX_VARS 32
+#define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4)
 
 //FIXME avoid direct access to LLSModel from outside
 
 /**
  * Linear least squares model.
  */
-typedef struct LLSModel{
-    double covariance[MAX_VARS+1][MAX_VARS+1];
-    double coeff[MAX_VARS][MAX_VARS];
+typedef struct LLSModel {
+    DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]);
+    DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]);
     double variance[MAX_VARS];
     int indep_count;
-}LLSModel;
+    /**
+     * Take the outer-product of var[] with itself, and add to the covariance matrix.
+     * @param m this context
+     * @param var training samples, starting with the value to be predicted
+     *            32-byte aligned, and any padding elements must be initialized
+     *            (i.e not denormal/nan).
+     */
+    void (*update_lls)(struct LLSModel *m, double *var);
+    /**
+     * Inner product of var[] and the LPC coefs.
+     * @param m this context
+     * @param var training samples, excluding the value to be predicted. unaligned.
+     * @param order lpc order
+     */
+    double (*evaluate_lls)(struct LLSModel *m, double *var, int order);
+} LLSModel;
+
+void avpriv_init_lls(LLSModel *m, int indep_count);
+void ff_init_lls_x86(LLSModel *m);
+void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order);
 
+#if FF_API_LLS_PRIVATE
 void av_init_lls(LLSModel *m, int indep_count);
 void av_update_lls(LLSModel *m, double *param, double decay);
 void av_solve_lls(LLSModel *m, double threshold, int min_order);
 double av_evaluate_lls(LLSModel *m, double *param, int order);
+#endif /* FF_API_LLS_PRIVATE */
 
 #endif /* AVUTIL_LLS_H */
diff --git a/libavutil/log.c b/libavutil/log.c
index 8012976..7d574f6 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -32,10 +32,12 @@
 #if HAVE_IO_H
 #include <io.h>
 #endif
+#include <stdarg.h>
 #include <stdlib.h>
 #include "avstring.h"
 #include "avutil.h"
 #include "common.h"
+#include "internal.h"
 #include "log.h"
 
 static int av_log_level = AV_LOG_INFO;
@@ -179,3 +181,35 @@ void av_log_set_callback(void (*callback)(void*, int, const char*, va_list))
 {
     av_log_callback = callback;
 }
+
+static void missing_feature_sample(int sample, void *avc, const char *msg,
+                                   va_list argument_list)
+{
+    av_vlog(avc, AV_LOG_WARNING, msg, argument_list);
+    av_log(avc, AV_LOG_WARNING, " is not implemented. Update your Libav "
+           "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");
+    if (sample)
+        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");
+}
+
+void avpriv_request_sample(void *avc, const char *msg, ...)
+{
+    va_list argument_list;
+
+    va_start(argument_list, msg);
+    missing_feature_sample(1, avc, msg, argument_list);
+    va_end(argument_list);
+}
+
+void avpriv_report_missing_feature(void *avc, const char *msg, ...)
+{
+    va_list argument_list;
+
+    va_start(argument_list, msg);
+    missing_feature_sample(0, avc, msg, argument_list);
+    va_end(argument_list);
+}
diff --git a/libavutil/log.h b/libavutil/log.h
index 7b17330..05d2826 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -89,8 +89,19 @@ typedef struct AVClass {
     const struct AVClass* (*child_class_next)(const struct AVClass *prev);
 } AVClass;
 
-/* av_log API */
+/**
+ * @addtogroup lavu_log
+ *
+ * @{
+ *
+ * @defgroup lavu_log_constants Logging Constants
+ *
+ * @{
+ */
 
+/**
+ * Print no output.
+ */
 #define AV_LOG_QUIET    -8
 
 /**
@@ -117,7 +128,14 @@ typedef struct AVClass {
  */
 #define AV_LOG_WARNING  24
 
+/**
+ * Standard information.
+ */
 #define AV_LOG_INFO     32
+
+/**
+ * Detailed information.
+ */
 #define AV_LOG_VERBOSE  40
 
 /**
@@ -126,26 +144,92 @@ typedef struct AVClass {
 #define AV_LOG_DEBUG    48
 
 /**
+ * @}
+ */
+
+/**
  * 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
- * stderr. This behavior can be altered by setting a different av_vlog callback
+ * stderr. This behavior can be altered by setting a different logging callback
  * function.
+ * @see av_log_set_callback
  *
  * @param avcl A pointer to an arbitrary struct of which the first field is a
- * pointer to an AVClass struct.
- * @param level The importance level of the message, lower values signifying
- * higher importance.
+ *        pointer to an AVClass struct.
+ * @param level The importance level of the message expressed using a @ref
+ *        lavu_log_constants "Logging Constant".
  * @param fmt The format string (printf-compatible) that specifies how
- * subsequent arguments are converted to output.
- * @see av_vlog
+ *        subsequent arguments are converted to output.
  */
 void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4);
 
-void av_vlog(void *avcl, int level, const char *fmt, va_list);
+
+/**
+ * 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
+ * stderr. This behavior can be altered by setting a different logging callback
+ * function.
+ * @see av_log_set_callback
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ *        pointer to an AVClass struct.
+ * @param level The importance level of the message expressed using a @ref
+ *        lavu_log_constants "Logging Constant".
+ * @param fmt The format string (printf-compatible) that specifies how
+ *        subsequent arguments are converted to output.
+ * @param vl The arguments referenced by the format string.
+ */
+void av_vlog(void *avcl, int level, const char *fmt, va_list vl);
+
+/**
+ * Get the current log level
+ *
+ * @see lavu_log_constants
+ *
+ * @return Current log level
+ */
 int av_log_get_level(void);
-void av_log_set_level(int);
-void av_log_set_callback(void (*)(void*, int, const char*, va_list));
+
+/**
+ * Set the log level
+ *
+ * @see lavu_log_constants
+ *
+ * @param level Logging level
+ */
+void av_log_set_level(int level);
+
+/**
+ * Set the logging callback
+ *
+ * @see av_log_default_callback
+ *
+ * @param callback A logging function with a compatible signature.
+ */
+void av_log_set_callback(void (*callback)(void*, int, const char*, va_list));
+
+/**
+ * Default logging callback
+ *
+ * It prints the message to stderr, optionally colorizing it.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ *        pointer to an AVClass struct.
+ * @param level The importance level of the message expressed using a @ref
+ *        lavu_log_constants "Logging Constant".
+ * @param fmt The format string (printf-compatible) that specifies how
+ *        subsequent arguments are converted to output.
+ * @param ap The arguments referenced by the format string.
+ */
 void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl);
+
+/**
+ * Return the context name
+ *
+ * @param  ctx The AVClass context
+ *
+ * @return The AVClass class_name
+ */
 const char* av_default_item_name(void* ctx);
 
 /**
@@ -170,4 +254,8 @@ const char* av_default_item_name(void* ctx);
 #define AV_LOG_SKIP_REPEATED 1
 void av_log_set_flags(int arg);
 
+/**
+ * @}
+ */
+
 #endif /* AVUTIL_LOG_H */
diff --git a/libavutil/mem.c b/libavutil/mem.c
index 391eb7d..be42342 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
@@ -35,6 +35,7 @@
 #endif
 
 #include "avutil.h"
+#include "common.h"
 #include "intreadwrite.h"
 #include "mem.h"
 
@@ -65,7 +66,7 @@ void *av_malloc(size_t size)
     long diff;
 #endif
 
-    /* let's disallow possible ambiguous cases */
+    /* let's disallow possibly ambiguous cases */
     if (size > (INT_MAX - 32) || !size)
         return NULL;
 
@@ -119,7 +120,7 @@ void *av_realloc(void *ptr, size_t size)
     int diff;
 #endif
 
-    /* let's disallow possible ambiguous cases */
+    /* let's disallow possibly ambiguous cases */
     if (size > (INT_MAX - 16))
         return NULL;
 
@@ -136,6 +137,52 @@ void *av_realloc(void *ptr, size_t size)
 #endif
 }
 
+int av_reallocp(void *ptr, size_t size)
+{
+    void **ptrptr = ptr;
+    void *ret;
+
+    if (!size) {
+        av_freep(ptr);
+        return 0;
+    }
+    ret = av_realloc(*ptrptr, size);
+
+    if (!ret) {
+        av_freep(ptr);
+        return AVERROR(ENOMEM);
+    }
+
+    *ptrptr = ret;
+    return 0;
+}
+
+void *av_realloc_array(void *ptr, size_t nmemb, size_t size)
+{
+    if (!size || nmemb >= INT_MAX / size)
+        return NULL;
+    return av_realloc(ptr, nmemb * size);
+}
+
+int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
+{
+    void **ptrptr = ptr;
+    void *ret;
+    if (!size || nmemb >= INT_MAX / size)
+        return AVERROR(ENOMEM);
+    if (!nmemb) {
+        av_freep(ptr);
+        return 0;
+    }
+    ret = av_realloc(*ptrptr, nmemb * size);
+    if (!ret) {
+        av_freep(ptr);
+        return AVERROR(ENOMEM);
+    }
+    *ptrptr = ret;
+    return 0;
+}
+
 void av_free(void *ptr)
 {
 #if CONFIG_MEMALIGN_HACK
@@ -168,7 +215,7 @@ char *av_strdup(const char *s)
     char *ptr = NULL;
     if (s) {
         int len = strlen(s) + 1;
-        ptr = av_malloc(len);
+        ptr = av_realloc(NULL, len);
         if (ptr)
             memcpy(ptr, s, len);
     }
@@ -298,3 +345,35 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
             *dst = *src;
     }
 }
+
+void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
+{
+    if (min_size < *size)
+        return ptr;
+
+    min_size = FFMAX(17 * min_size / 16 + 32, min_size);
+
+    ptr = av_realloc(ptr, min_size);
+    /* we could set this to the unmodified min_size but this is safer
+     * if the user lost the ptr and uses NULL now
+     */
+    if (!ptr)
+        min_size = 0;
+
+    *size = min_size;
+
+    return ptr;
+}
+
+void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
+{
+    void **p = ptr;
+    if (min_size < *size)
+        return;
+    min_size = FFMAX(17 * min_size / 16 + 32, min_size);
+    av_free(*p);
+    *p = av_malloc(min_size);
+    if (!*p)
+        min_size = 0;
+    *size = min_size;
+}
diff --git a/libavutil/mem.h b/libavutil/mem.h
index 8f47224..4a5e362 100644
--- a/libavutil/mem.h
+++ b/libavutil/mem.h
@@ -82,8 +82,7 @@
 void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1);
 
 /**
- * Helper function to allocate a block of size * nmemb bytes with
- * using av_malloc()
+ * Allocate a block of size * nmemb bytes with av_malloc().
  * @param nmemb Number of elements
  * @param size Size of the single element
  * @return Pointer to the allocated block, NULL if the block cannot
@@ -92,7 +91,7 @@ void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1);
  */
 av_alloc_size(1, 2) static inline void *av_malloc_array(size_t nmemb, size_t size)
 {
-    if (size <= 0 || nmemb >= INT_MAX / size)
+    if (!size || nmemb >= INT_MAX / size)
         return NULL;
     return av_malloc(nmemb * size);
 }
@@ -102,16 +101,79 @@ av_alloc_size(1, 2) static inline void *av_malloc_array(size_t nmemb, size_t siz
  * If ptr is NULL and size > 0, allocate a new block. If
  * size is zero, free the memory block pointed to by ptr.
  * @param ptr Pointer to a memory block already allocated with
- * av_malloc(z)() or av_realloc() or NULL.
- * @param size Size in bytes for the memory block to be allocated or
+ * av_realloc() or NULL.
+ * @param size Size in bytes of the memory block to be allocated or
  * reallocated.
- * @return Pointer to a newly reallocated block or NULL if the block
+ * @return Pointer to a newly-reallocated block or NULL if the block
  * cannot be reallocated or the function is used to free the memory block.
+ * @warning Pointers originating from the av_malloc() family of functions must
+ *          not be passed to av_realloc(). The former can be implemented using
+ *          memalign() (or other functions), and there is no guarantee that
+ *          pointers from such functions can be passed to realloc() at all.
+ *          The situation is undefined according to POSIX and may crash with
+ *          some libc implementations.
  * @see av_fast_realloc()
  */
 void *av_realloc(void *ptr, size_t size) av_alloc_size(2);
 
 /**
+ * Allocate or reallocate a block of memory.
+ * If *ptr is NULL and size > 0, allocate a new block. If
+ * size is zero, free the memory block pointed to by ptr.
+ * @param   ptr Pointer to a pointer to a memory block already allocated
+ *          with av_realloc(), or pointer to a pointer to NULL.
+ *          The pointer is updated on success, or freed on failure.
+ * @param   size Size in bytes for the memory block to be allocated or
+ *          reallocated
+ * @return  Zero on success, an AVERROR error code on failure.
+ * @warning Pointers originating from the av_malloc() family of functions must
+ *          not be passed to av_reallocp(). The former can be implemented using
+ *          memalign() (or other functions), and there is no guarantee that
+ *          pointers from such functions can be passed to realloc() at all.
+ *          The situation is undefined according to POSIX and may crash with
+ *          some libc implementations.
+ */
+int av_reallocp(void *ptr, size_t size);
+
+/**
+ * Allocate or reallocate an array.
+ * If ptr is NULL and nmemb > 0, allocate a new block. If
+ * nmemb is zero, free the memory block pointed to by ptr.
+ * @param ptr Pointer to a memory block already allocated with
+ * av_realloc() or NULL.
+ * @param nmemb Number of elements
+ * @param size Size of the single element
+ * @return Pointer to a newly-reallocated block or NULL if the block
+ * cannot be reallocated or the function is used to free the memory block.
+ * @warning Pointers originating from the av_malloc() family of functions must
+ *          not be passed to av_realloc(). The former can be implemented using
+ *          memalign() (or other functions), and there is no guarantee that
+ *          pointers from such functions can be passed to realloc() at all.
+ *          The situation is undefined according to POSIX and may crash with
+ *          some libc implementations.
+ */
+av_alloc_size(2, 3) void *av_realloc_array(void *ptr, size_t nmemb, size_t size);
+
+/**
+ * Allocate or reallocate an array through a pointer to a pointer.
+ * If *ptr is NULL and nmemb > 0, allocate a new block. If
+ * nmemb is zero, free the memory block pointed to by ptr.
+ * @param ptr Pointer to a pointer to a memory block already allocated
+ * with av_realloc(), or pointer to a pointer to NULL.
+ * The pointer is updated on success, or freed on failure.
+ * @param nmemb Number of elements
+ * @param size Size of the single element
+ * @return Zero on success, an AVERROR error code on failure.
+ * @warning Pointers originating from the av_malloc() family of functions must
+ *          not be passed to av_realloc(). The former can be implemented using
+ *          memalign() (or other functions), and there is no guarantee that
+ *          pointers from such functions can be passed to realloc() at all.
+ *          The situation is undefined according to POSIX and may crash with
+ *          some libc implementations.
+ */
+av_alloc_size(2, 3) int av_reallocp_array(void *ptr, size_t nmemb, size_t size);
+
+/**
  * Free a memory block which has been allocated with av_malloc(z)() or
  * av_realloc().
  * @param ptr Pointer to the memory block which should be freed.
@@ -132,8 +194,7 @@ void av_free(void *ptr);
 void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1);
 
 /**
- * Helper function to allocate a block of size * nmemb bytes with
- * using av_mallocz()
+ * Allocate a block of size * nmemb bytes with av_mallocz().
  * @param nmemb Number of elements
  * @param size Size of the single element
  * @return Pointer to the allocated block, NULL if the block cannot
@@ -143,7 +204,7 @@ void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1);
  */
 av_alloc_size(1, 2) static inline void *av_mallocz_array(size_t nmemb, size_t size)
 {
-    if (size <= 0 || nmemb >= INT_MAX / size)
+    if (!size || nmemb >= INT_MAX / size)
         return NULL;
     return av_mallocz(nmemb * size);
 }
@@ -151,7 +212,7 @@ av_alloc_size(1, 2) static inline void *av_mallocz_array(size_t nmemb, size_t si
 /**
  * Duplicate the string s.
  * @param s string to be duplicated
- * @return Pointer to a newly allocated string containing a
+ * @return Pointer to a newly-allocated string containing a
  * copy of s or NULL if the string cannot be allocated.
  */
 char *av_strdup(const char *s) av_malloc_attrib;
@@ -166,7 +227,7 @@ char *av_strdup(const char *s) av_malloc_attrib;
 void av_freep(void *ptr);
 
 /**
- * @brief deliberately overlapping memcpy implementation
+ * deliberately overlapping memcpy implementation
  * @param dst destination buffer
  * @param back how many bytes back we start (the initial size of the overlapping window)
  * @param cnt number of bytes to copy, must be >= 0
@@ -177,6 +238,27 @@ void av_freep(void *ptr);
 void av_memcpy_backptr(uint8_t *dst, int back, int cnt);
 
 /**
+ * Reallocate the given block if it is not large enough, otherwise do nothing.
+ *
+ * @see av_realloc
+ */
+void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size);
+
+/**
+ * Allocate a buffer, reusing the given one if large enough.
+ *
+ * Contrary to av_fast_realloc the current buffer contents might not be
+ * preserved and on error the old buffer is freed, thus no special
+ * handling to avoid memleaks is necessary.
+ *
+ * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer
+ * @param size size of the buffer *ptr points to
+ * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and
+ *                 *size 0 if an error occurred.
+ */
+void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size);
+
+/**
  * @}
  */
 
diff --git a/libavutil/old_pix_fmts.h b/libavutil/old_pix_fmts.h
index 31765ae..d3e1e5b 100644
--- a/libavutil/old_pix_fmts.h
+++ b/libavutil/old_pix_fmts.h
@@ -42,8 +42,10 @@
     PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
     PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
     PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+#if FF_API_XVMC
     PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
     PIX_FMT_XVMC_MPEG2_IDCT,
+#endif /* FF_API_XVMC */
     PIX_FMT_UYVY422,   ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
     PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
     PIX_FMT_BGR8,      ///< packed RGB 3:3:2,  8bpp, (msb)2B 3G 3R(lsb)
@@ -65,11 +67,13 @@
     PIX_FMT_YUV440P,   ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
     PIX_FMT_YUVJ440P,  ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range
     PIX_FMT_YUVA420P,  ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+#if FF_API_VDPAU
     PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+#endif
     PIX_FMT_RGB48BE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
     PIX_FMT_RGB48LE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
 
@@ -93,7 +97,9 @@
     PIX_FMT_YUV422P16BE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
     PIX_FMT_YUV444P16LE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
     PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+#if FF_API_VDPAU
     PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+#endif
     PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
 
     PIX_FMT_RGB444LE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
diff --git a/libavutil/opt.c b/libavutil/opt.c
index 04f4413..ede4a49 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -61,7 +61,8 @@ static int read_number(const AVOption *o, void *dst, double *num, int *den, int6
 
 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) {
+    if (o->type != AV_OPT_TYPE_FLAGS &&
+        (o->max * den < num * intnum || o->min * den > num * intnum)) {
         av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range\n",
                num*intnum/den, o->name);
         return AVERROR(ERANGE);
@@ -146,7 +147,7 @@ static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **d
                               opt->type == AV_OPT_TYPE_INT) ? \
                              opt->default_val.i64 : opt->default_val.dbl)
 
-static int set_string_number(void *obj, const AVOption *o, const char *val, void *dst)
+static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst)
 {
     int ret = 0, notfirst = 0;
     for (;;) {
@@ -169,7 +170,7 @@ static int set_string_number(void *obj, const AVOption *o, const char *val, void
         buf[i] = 0;
 
         {
-            const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);
+            const AVOption *o_named = av_opt_find(target_obj, buf, o->unit, 0, 0);
             if (o_named && o_named->type == AV_OPT_TYPE_CONST)
                 d = DEFAULT_NUMVAL(o_named);
             else if (!strcmp(buf, "default")) d = DEFAULT_NUMVAL(o);
@@ -224,7 +225,7 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
     case AV_OPT_TYPE_INT64:
     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_RATIONAL: return set_string_number(obj, target_obj, o, val, dst);
     }
 
     av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
@@ -236,7 +237,7 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
     {\
         if (!o || o->type != opttype)\
             return AVERROR(EINVAL);\
-        return set_string_number(obj, o, val, name ## _out);\
+        return set_string_number(obj, obj, o, val, name ## _out);\
     }
 
 OPT_EVAL_NUMBER(flags,  AV_OPT_TYPE_FLAGS,    int)
@@ -349,7 +350,7 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
     return 0;
 }
 
-static int get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum,
+static int get_number(void *obj, const char *name, double *num, int *den, int64_t *intnum,
                       int search_flags)
 {
     void *dst, *target_obj;
@@ -359,8 +360,6 @@ static int get_number(void *obj, const char *name, const AVOption **o_out, doubl
 
     dst = ((uint8_t*)target_obj) + o->offset;
 
-    if (o_out) *o_out= o;
-
     return read_number(o, dst, num, den, intnum);
 
 error:
@@ -374,7 +373,7 @@ int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_v
     double     num = 1;
     int   ret, den = 1;
 
-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+    if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
         return ret;
     *out_val = num*intnum/den;
     return 0;
@@ -386,7 +385,7 @@ int av_opt_get_double(void *obj, const char *name, int search_flags, double *out
     double     num = 1;
     int   ret, den = 1;
 
-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+    if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
         return ret;
     *out_val = num*intnum/den;
     return 0;
@@ -398,7 +397,7 @@ int av_opt_get_q(void *obj, const char *name, int search_flags, AVRational *out_
     double     num = 1;
     int   ret, den = 1;
 
-    if ((ret = get_number(obj, name, NULL, &num, &den, &intnum, search_flags)) < 0)
+    if ((ret = get_number(obj, name, &num, &den, &intnum, search_flags)) < 0)
         return ret;
 
     if (num == 1.0 && (int)intnum == intnum)
@@ -564,9 +563,16 @@ static int parse_key_value_pair(void *ctx, const char **buf,
     char *val;
     int ret;
 
+    if (!key)
+        return AVERROR(ENOMEM);
+
     if (*key && strspn(*buf, key_val_sep)) {
         (*buf)++;
         val = av_get_token(buf, pairs_sep);
+        if (!val) {
+            av_freep(&key);
+            return AVERROR(ENOMEM);
+        }
     } else {
         av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
         av_free(key);
@@ -575,7 +581,7 @@ static int parse_key_value_pair(void *ctx, const char **buf,
 
     av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key);
 
-    ret = av_opt_set(ctx, key, val, 0);
+    ret = av_opt_set(ctx, key, val, AV_OPT_SEARCH_CHILDREN);
     if (ret == AVERROR_OPTION_NOT_FOUND)
         av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
 
@@ -645,6 +651,9 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
     const AVClass  *c = *(AVClass**)obj;
     const AVOption *o = NULL;
 
+    if (!c)
+        return NULL;
+
     if (search_flags & AV_OPT_SEARCH_CHILDREN) {
         if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
             const AVClass *child = NULL;
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 2d3cc73..0181379 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -62,7 +62,7 @@
  *     int      bin_len;
  * } test_struct;
  *
- * static const AVOption options[] = {
+ * static const AVOption test_options[] = {
  *   { "test_int", "This is a test option of int type.", offsetof(test_struct, int_opt),
  *     AV_OPT_TYPE_INT, { .i64 = -1 }, INT_MIN, INT_MAX },
  *   { "test_str", "This is a test option of string type.", offsetof(test_struct, str_opt),
@@ -75,7 +75,7 @@
  * static const AVClass test_class = {
  *     .class_name = "test class",
  *     .item_name  = av_default_item_name,
- *     .option     = options,
+ *     .option     = test_options,
  *     .version    = LIBAVUTIL_VERSION_INT,
  * };
  * @endcode
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index 917451e..414cd47 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -385,7 +385,7 @@ static int date_get_num(const char **pp,
     val = 0;
     for(i = 0; i < len_max; i++) {
         c = *p;
-        if (!isdigit(c))
+        if (!av_isdigit(c))
             break;
         val = (val * 10) + c - '0';
         p++;
@@ -555,15 +555,17 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
         /* parse timestr as HH:MM:SS */
         q = small_strptime(p, time_fmt[0], &dt);
         if (!q) {
+            char *o;
             /* parse timestr as S+ */
-            dt.tm_sec = strtol(p, (char **)&q, 10);
-            if (q == p) {
+            dt.tm_sec = strtol(p, &o, 10);
+            if (o == p) {
                 /* the parsing didn't succeed */
                 *timeval = INT64_MIN;
                 return AVERROR(EINVAL);
             }
             dt.tm_min = 0;
             dt.tm_hour = 0;
+            q = o;
         }
     }
 
@@ -591,7 +593,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
         int val, n;
         q++;
         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
-            if (!isdigit(*q))
+            if (!av_isdigit(*q))
                 break;
             val += n * (*q - '0');
         }
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 31b7cf5..37ce173 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -25,8 +25,9 @@
 #include "common.h"
 #include "pixfmt.h"
 #include "pixdesc.h"
-
+#include "internal.h"
 #include "intreadwrite.h"
+#include "version.h"
 
 void av_read_image_line(uint16_t *dst,
                         const uint8_t *data[4], const int linesize[4],
@@ -42,7 +43,7 @@ void av_read_image_line(uint16_t *dst,
     int step  = comp.step_minus1 + 1;
     int flags = desc->flags;
 
-    if (flags & PIX_FMT_BITSTREAM) {
+    if (flags & AV_PIX_FMT_FLAG_BITSTREAM) {
         int skip = x * step + comp.offset_plus1 - 1;
         const uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3);
         int shift = 8 - depth - (skip & 7);
@@ -62,11 +63,11 @@ void av_read_image_line(uint16_t *dst,
         int is_8bit = shift + depth <= 8;
 
         if (is_8bit)
-            p += !!(flags & PIX_FMT_BE);
+            p += !!(flags & AV_PIX_FMT_FLAG_BE);
 
         while (w--) {
             int val = is_8bit ? *p :
-                flags & PIX_FMT_BE ? AV_RB16(p) : AV_RL16(p);
+                flags & AV_PIX_FMT_FLAG_BE ? AV_RB16(p) : AV_RL16(p);
             val = (val >> shift) & mask;
             if (read_pal_component)
                 val = data[1][4 * val + c];
@@ -87,7 +88,7 @@ void av_write_image_line(const uint16_t *src,
     int step  = comp.step_minus1 + 1;
     int flags = desc->flags;
 
-    if (flags & PIX_FMT_BITSTREAM) {
+    if (flags & AV_PIX_FMT_FLAG_BITSTREAM) {
         int skip = x * step + comp.offset_plus1 - 1;
         uint8_t *p = data[plane] + y * linesize[plane] + (skip >> 3);
         int shift = 8 - depth - (skip & 7);
@@ -104,14 +105,14 @@ void av_write_image_line(const uint16_t *src,
                      x * step + comp.offset_plus1 - 1;
 
         if (shift + depth <= 8) {
-            p += !!(flags & PIX_FMT_BE);
+            p += !!(flags & AV_PIX_FMT_FLAG_BE);
             while (w--) {
                 *p |= (*src++ << shift);
                 p += step;
             }
         } else {
             while (w--) {
-                if (flags & PIX_FMT_BE) {
+                if (flags & AV_PIX_FMT_FLAG_BE) {
                     uint16_t val = AV_RB16(p) | (*src++ << shift);
                     AV_WB16(p, val);
                 } else {
@@ -138,7 +139,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUYV422] = {
         .name = "yuyv422",
@@ -161,7 +162,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 2, 2, 0, 7 },        /* G */
             { 0, 2, 3, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR24] = {
         .name = "bgr24",
@@ -173,7 +174,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 2, 2, 0, 7 },        /* G */
             { 0, 2, 3, 0, 7 },        /* R */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_YUV422P] = {
         .name = "yuv422p",
@@ -185,7 +186,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P] = {
         .name = "yuv444p",
@@ -197,7 +198,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV410P] = {
         .name = "yuv410p",
@@ -209,7 +210,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV411P] = {
         .name = "yuv411p",
@@ -221,7 +222,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_GRAY8] = {
         .name = "gray",
@@ -231,7 +232,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         .comp = {
             { 0, 0, 1, 0, 7 },        /* Y */
         },
-        .flags = PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_MONOWHITE] = {
         .name = "monow",
@@ -241,7 +242,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         .comp = {
             { 0, 0, 1, 0, 0 },        /* Y */
         },
-        .flags = PIX_FMT_BITSTREAM,
+        .flags = AV_PIX_FMT_FLAG_BITSTREAM,
     },
     [AV_PIX_FMT_MONOBLACK] = {
         .name = "monob",
@@ -251,7 +252,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         .comp = {
             { 0, 0, 1, 7, 0 },        /* Y */
         },
-        .flags = PIX_FMT_BITSTREAM,
+        .flags = AV_PIX_FMT_FLAG_BITSTREAM,
     },
     [AV_PIX_FMT_PAL8] = {
         .name = "pal8",
@@ -261,7 +262,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         .comp = {
             { 0, 0, 1, 0, 7 },
         },
-        .flags = PIX_FMT_PAL,
+        .flags = AV_PIX_FMT_FLAG_PAL,
     },
     [AV_PIX_FMT_YUVJ420P] = {
         .name = "yuvj420p",
@@ -273,7 +274,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVJ422P] = {
         .name = "yuvj422p",
@@ -285,7 +286,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVJ444P] = {
         .name = "yuvj444p",
@@ -297,16 +298,18 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             {1, 0, 1, 0, 7},        /* U */
             {2, 0, 1, 0, 7},        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
+#if FF_API_XVMC
     [AV_PIX_FMT_XVMC_MPEG2_MC] = {
         .name = "xvmcmc",
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_XVMC_MPEG2_IDCT] = {
         .name = "xvmcidct",
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
+#endif /* FF_API_XVMC */
     [AV_PIX_FMT_UYVY422] = {
         .name = "uyvy422",
         .nb_components = 3,
@@ -339,7 +342,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 0, 1, 3, 2 },        /* G */
             { 0, 0, 1, 0, 2 },        /* R */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_BGR4] = {
         .name = "bgr4",
@@ -351,7 +354,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 3, 2, 0, 1 },        /* G */
             { 0, 3, 4, 0, 0 },        /* R */
         },
-        .flags = PIX_FMT_BITSTREAM | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR4_BYTE] = {
         .name = "bgr4_byte",
@@ -363,7 +366,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 0, 1, 1, 1 },        /* G */
             { 0, 0, 1, 0, 0 },        /* R */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_RGB8] = {
         .name = "rgb8",
@@ -375,7 +378,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 0, 1, 3, 2 },        /* G */
             { 0, 0, 1, 0, 2 },        /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_RGB4] = {
         .name = "rgb4",
@@ -387,7 +390,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 3, 2, 0, 1 },        /* G */
             { 0, 3, 4, 0, 0 },        /* B */
         },
-        .flags = PIX_FMT_BITSTREAM | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB4_BYTE] = {
         .name = "rgb4_byte",
@@ -399,7 +402,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 0, 1, 1, 1 },        /* G */
             { 0, 0, 1, 0, 0 },        /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_PSEUDOPAL,
     },
     [AV_PIX_FMT_NV12] = {
         .name = "nv12",
@@ -411,7 +414,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 7 },        /* U */
             { 1, 1, 2, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_NV21] = {
         .name = "nv21",
@@ -423,7 +426,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 7 },        /* V */
             { 1, 1, 2, 0, 7 },        /* U */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_ARGB] = {
         .name = "argb",
@@ -436,7 +439,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 3, 3, 0, 7 },        /* G */
             { 0, 3, 4, 0, 7 },        /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_RGBA] = {
         .name = "rgba",
@@ -449,7 +452,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 3, 3, 0, 7 },        /* B */
             { 0, 3, 4, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_ABGR] = {
         .name = "abgr",
@@ -462,7 +465,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 3, 3, 0, 7 },        /* G */
             { 0, 3, 4, 0, 7 },        /* R */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_BGRA] = {
         .name = "bgra",
@@ -475,7 +478,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 3, 3, 0, 7 },        /* R */
             { 0, 3, 4, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_GRAY16BE] = {
         .name = "gray16be",
@@ -485,7 +488,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         .comp = {
             { 0, 1, 1, 0, 15 },       /* Y */
         },
-        .flags = PIX_FMT_BE,
+        .flags = AV_PIX_FMT_FLAG_BE,
     },
     [AV_PIX_FMT_GRAY16LE] = {
         .name = "gray16le",
@@ -506,7 +509,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVJ440P] = {
         .name = "yuvj440p",
@@ -518,7 +521,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* U */
             { 2, 0, 1, 0, 7 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVA420P] = {
         .name = "yuva420p",
@@ -531,7 +534,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 0, 1, 0, 7 },        /* V */
             { 3, 0, 1, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
         [AV_PIX_FMT_YUVA422P] = {
         .name = "yuva422p",
@@ -544,7 +547,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 0, 1, 0, 7 },        /* V */
             { 3, 0, 1, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P] = {
         .name = "yuva444p",
@@ -557,7 +560,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 0, 1, 0, 7 },        /* V */
             { 3, 0, 1, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P9BE] = {
         .name = "yuva420p9be",
@@ -570,7 +573,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUVA420P9LE] = {
         .name = "yuva420p9le",
@@ -583,7 +586,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P9BE] = {
         .name = "yuva422p9be",
@@ -596,7 +599,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P9LE] = {
         .name = "yuva422p9le",
@@ -609,7 +612,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P9BE] = {
         .name = "yuva444p9be",
@@ -622,7 +625,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P9LE] = {
         .name = "yuva444p9le",
@@ -635,7 +638,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 8 },        /* V */
             { 3, 1, 1, 0, 8 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P10BE] = {
         .name = "yuva420p10be",
@@ -648,7 +651,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P10LE] = {
         .name = "yuva420p10le",
@@ -661,7 +664,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P10BE] = {
         .name = "yuva422p10be",
@@ -674,7 +677,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P10LE] = {
         .name = "yuva422p10le",
@@ -687,7 +690,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P10BE] = {
         .name = "yuva444p10be",
@@ -700,7 +703,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P10LE] = {
         .name = "yuva444p10le",
@@ -713,7 +716,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 9 },        /* V */
             { 3, 1, 1, 0, 9 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P16BE] = {
         .name = "yuva420p16be",
@@ -726,7 +729,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA420P16LE] = {
         .name = "yuva420p16le",
@@ -739,7 +742,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P16BE] = {
         .name = "yuva422p16be",
@@ -752,7 +755,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA422P16LE] = {
         .name = "yuva422p16le",
@@ -765,7 +768,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P16BE] = {
         .name = "yuva444p16be",
@@ -778,7 +781,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_YUVA444P16LE] = {
         .name = "yuva444p16le",
@@ -791,44 +794,46 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 2, 1, 1, 0, 15 },        /* V */
             { 3, 1, 1, 0, 15 },        /* A */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_ALPHA,
     },
+#if FF_API_VDPAU
     [AV_PIX_FMT_VDPAU_H264] = {
         .name = "vdpau_h264",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_MPEG1] = {
         .name = "vdpau_mpeg1",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_MPEG2] = {
         .name = "vdpau_mpeg2",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_WMV3] = {
         .name = "vdpau_wmv3",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_VC1] = {
         .name = "vdpau_vc1",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDPAU_MPEG4] = {
         .name = "vdpau_mpeg4",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
+#endif
     [AV_PIX_FMT_RGB48BE] = {
         .name = "rgb48be",
         .nb_components = 3,
@@ -839,7 +844,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 5, 0, 15 },       /* B */
         },
-        .flags = PIX_FMT_RGB | PIX_FMT_BE,
+        .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE,
     },
     [AV_PIX_FMT_RGB48LE] = {
         .name = "rgb48le",
@@ -851,7 +856,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 5, 0, 15 },       /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB565BE] = {
         .name = "rgb565be",
@@ -863,7 +868,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 1, 0, 4 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB565LE] = {
         .name = "rgb565le",
@@ -875,7 +880,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 1, 0, 4 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB555BE] = {
         .name = "rgb555be",
@@ -887,7 +892,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 5, 4 },        /* G */
             { 0, 1, 1, 0, 4 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB555LE] = {
         .name = "rgb555le",
@@ -899,7 +904,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 5, 4 },        /* G */
             { 0, 1, 1, 0, 4 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB444BE] = {
         .name = "rgb444be",
@@ -911,7 +916,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 4, 3 },        /* G */
             { 0, 1, 1, 0, 3 },        /* B */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_RGB444LE] = {
         .name = "rgb444le",
@@ -923,7 +928,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 4, 3 },        /* G */
             { 0, 1, 1, 0, 3 },        /* B */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR48BE] = {
         .name = "bgr48be",
@@ -935,7 +940,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 5, 0, 15 },       /* R */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR48LE] = {
         .name = "bgr48le",
@@ -947,7 +952,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 5, 0, 15 },       /* R */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR565BE] = {
         .name = "bgr565be",
@@ -959,7 +964,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 1, 0, 4 },        /* R */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR565LE] = {
         .name = "bgr565le",
@@ -971,7 +976,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 1, 0, 4 },        /* R */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR555BE] = {
         .name = "bgr555be",
@@ -983,7 +988,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 5, 4 },       /* G */
             { 0, 1, 1, 0, 4 },       /* R */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
      },
     [AV_PIX_FMT_BGR555LE] = {
         .name = "bgr555le",
@@ -995,7 +1000,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 5, 4 },        /* G */
             { 0, 1, 1, 0, 4 },        /* R */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_BGR444BE] = {
         .name = "bgr444be",
@@ -1007,7 +1012,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 4, 3 },       /* G */
             { 0, 1, 1, 0, 3 },       /* R */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB,
      },
     [AV_PIX_FMT_BGR444LE] = {
         .name = "bgr444le",
@@ -1019,31 +1024,31 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 4, 3 },        /* G */
             { 0, 1, 1, 0, 3 },        /* R */
         },
-        .flags = PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_VAAPI_MOCO] = {
         .name = "vaapi_moco",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VAAPI_IDCT] = {
         .name = "vaapi_idct",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VAAPI_VLD] = {
         .name = "vaapi_vld",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_VDA_VLD] = {
         .name = "vda_vld",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_YUV420P9LE] = {
         .name = "yuv420p9le",
@@ -1055,7 +1060,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P9BE] = {
         .name = "yuv420p9be",
@@ -1067,7 +1072,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P10LE] = {
         .name = "yuv420p10le",
@@ -1079,7 +1084,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P10BE] = {
         .name = "yuv420p10be",
@@ -1091,7 +1096,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P16LE] = {
         .name = "yuv420p16le",
@@ -1103,7 +1108,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV420P16BE] = {
         .name = "yuv420p16be",
@@ -1115,7 +1120,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P9LE] = {
         .name = "yuv422p9le",
@@ -1127,7 +1132,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P9BE] = {
         .name = "yuv422p9be",
@@ -1139,7 +1144,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P10LE] = {
         .name = "yuv422p10le",
@@ -1151,7 +1156,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P10BE] = {
         .name = "yuv422p10be",
@@ -1163,7 +1168,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P16LE] = {
         .name = "yuv422p16le",
@@ -1175,7 +1180,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV422P16BE] = {
         .name = "yuv422p16be",
@@ -1187,7 +1192,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P16LE] = {
         .name = "yuv444p16le",
@@ -1199,7 +1204,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P16BE] = {
         .name = "yuv444p16be",
@@ -1211,7 +1216,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 15 },        /* U */
             { 2, 1, 1, 0, 15 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P10LE] = {
         .name = "yuv444p10le",
@@ -1223,7 +1228,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P10BE] = {
         .name = "yuv444p10be",
@@ -1235,7 +1240,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 9 },        /* U */
             { 2, 1, 1, 0, 9 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P9LE] = {
         .name = "yuv444p9le",
@@ -1247,7 +1252,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_YUV444P9BE] = {
         .name = "yuv444p9be",
@@ -1259,13 +1264,13 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 8 },        /* U */
             { 2, 1, 1, 0, 8 },        /* V */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
     [AV_PIX_FMT_DXVA2_VLD] = {
         .name = "dxva2_vld",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
     },
     [AV_PIX_FMT_Y400A] = {
         .name = "y400a",
@@ -1274,7 +1279,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 0, 1, 1, 0, 7 },        /* Y */
             { 0, 1, 2, 0, 7 },        /* A */
         },
-        .flags = PIX_FMT_ALPHA,
+        .flags = AV_PIX_FMT_FLAG_ALPHA,
     },
     [AV_PIX_FMT_GBRP] = {
         .name = "gbrp",
@@ -1286,7 +1291,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 0, 1, 0, 7 },        /* B */
             { 2, 0, 1, 0, 7 },        /* R */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP9LE] = {
         .name = "gbrp9le",
@@ -1298,7 +1303,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 8 },        /* B */
             { 2, 1, 1, 0, 8 },        /* R */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP9BE] = {
         .name = "gbrp9be",
@@ -1310,7 +1315,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 8 },        /* B */
             { 2, 1, 1, 0, 8 },        /* R */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP10LE] = {
         .name = "gbrp10le",
@@ -1322,7 +1327,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 9 },        /* B */
             { 2, 1, 1, 0, 9 },        /* R */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP10BE] = {
         .name = "gbrp10be",
@@ -1334,7 +1339,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 9 },        /* B */
             { 2, 1, 1, 0, 9 },        /* R */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP16LE] = {
         .name = "gbrp16le",
@@ -1346,7 +1351,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 15 },       /* B */
             { 2, 1, 1, 0, 15 },       /* R */
         },
-        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
     },
     [AV_PIX_FMT_GBRP16BE] = {
         .name = "gbrp16be",
@@ -1358,10 +1363,77 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
             { 1, 1, 1, 0, 15 },       /* B */
             { 2, 1, 1, 0, 15 },       /* R */
         },
-        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB,
+    },
+    [AV_PIX_FMT_VDPAU] = {
+        .name = "vdpau",
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
+    },
+    [AV_PIX_FMT_XYZ12LE] = {
+        .name = "xyz12le",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 5, 1, 4, 11 },       /* X */
+            { 0, 5, 3, 4, 11 },       /* Y */
+            { 0, 5, 5, 4, 11 },       /* Z */
+      },
+      /*.flags = -- not used*/
+    },
+    [AV_PIX_FMT_XYZ12BE] = {
+        .name = "xyz12be",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 5, 1, 4, 11 },       /* X */
+            { 0, 5, 3, 4, 11 },       /* Y */
+            { 0, 5, 5, 4, 11 },       /* Z */
+       },
+        .flags = AV_PIX_FMT_FLAG_BE,
+    },
+    [AV_PIX_FMT_NV16] = {
+        .name = "nv16",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 0, 1, 0, 7 },        /* Y */
+            { 1, 1, 1, 0, 7 },        /* U */
+            { 1, 1, 2, 0, 7 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
+    },
+    [AV_PIX_FMT_NV20LE] = {
+        .name = "nv20le",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 9 },        /* Y */
+            { 1, 3, 1, 0, 9 },        /* U */
+            { 1, 3, 3, 0, 9 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
+    },
+    [AV_PIX_FMT_NV20BE] = {
+        .name = "nv20be",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 9 },        /* Y */
+            { 1, 3, 1, 0, 9 },        /* U */
+            { 1, 3, 3, 0, 9 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE,
     },
 };
 
+FF_DISABLE_DEPRECATION_WARNINGS
 static enum AVPixelFormat get_pix_fmt_internal(const char *name)
 {
     enum AVPixelFormat pix_fmt;
@@ -1456,6 +1528,7 @@ enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc)
 
     return desc - av_pix_fmt_descriptors;
 }
+FF_ENABLE_DEPRECATION_WARNINGS
 
 int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt,
                                      int *h_shift, int *v_shift)
@@ -1468,3 +1541,66 @@ int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt,
 
     return 0;
 }
+
+int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    int i, planes[4] = { 0 }, ret = 0;
+
+    if (!desc)
+        return AVERROR(EINVAL);
+
+    for (i = 0; i < desc->nb_components; i++)
+        planes[desc->comp[i].plane] = 1;
+    for (i = 0; i < FF_ARRAY_ELEMS(planes); i++)
+        ret += planes[i];
+    return ret;
+}
+
+
+enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt)
+{
+#define PIX_FMT_SWAP_ENDIANNESS(fmt)                                           \
+    case AV_PIX_FMT_ ## fmt ## BE: return AV_PIX_FMT_ ## fmt ## LE;            \
+    case AV_PIX_FMT_ ## fmt ## LE: return AV_PIX_FMT_ ## fmt ## BE
+
+    switch (pix_fmt) {
+    PIX_FMT_SWAP_ENDIANNESS(GRAY16);
+    PIX_FMT_SWAP_ENDIANNESS(RGB48);
+    PIX_FMT_SWAP_ENDIANNESS(RGB565);
+    PIX_FMT_SWAP_ENDIANNESS(RGB555);
+    PIX_FMT_SWAP_ENDIANNESS(RGB444);
+    PIX_FMT_SWAP_ENDIANNESS(BGR48);
+    PIX_FMT_SWAP_ENDIANNESS(BGR565);
+    PIX_FMT_SWAP_ENDIANNESS(BGR555);
+    PIX_FMT_SWAP_ENDIANNESS(BGR444);
+
+    PIX_FMT_SWAP_ENDIANNESS(YUV420P9);
+    PIX_FMT_SWAP_ENDIANNESS(YUV422P9);
+    PIX_FMT_SWAP_ENDIANNESS(YUV444P9);
+    PIX_FMT_SWAP_ENDIANNESS(YUV420P10);
+    PIX_FMT_SWAP_ENDIANNESS(YUV422P10);
+    PIX_FMT_SWAP_ENDIANNESS(YUV444P10);
+    PIX_FMT_SWAP_ENDIANNESS(YUV420P16);
+    PIX_FMT_SWAP_ENDIANNESS(YUV422P16);
+    PIX_FMT_SWAP_ENDIANNESS(YUV444P16);
+
+    PIX_FMT_SWAP_ENDIANNESS(GBRP9);
+    PIX_FMT_SWAP_ENDIANNESS(GBRP10);
+    PIX_FMT_SWAP_ENDIANNESS(GBRP16);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA420P9);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA422P9);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA444P9);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA420P10);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA422P10);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA444P10);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA420P16);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA422P16);
+    PIX_FMT_SWAP_ENDIANNESS(YUVA444P16);
+
+    PIX_FMT_SWAP_ENDIANNESS(XYZ12);
+    default:
+        return AV_PIX_FMT_NONE;
+    }
+#undef PIX_FMT_SWAP_ENDIANNESS
+}
diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h
index 47e6bb8..e5a16f4 100644
--- a/libavutil/pixdesc.h
+++ b/libavutil/pixdesc.h
@@ -23,6 +23,8 @@
 #define AVUTIL_PIXDESC_H
 
 #include <inttypes.h>
+
+#include "attributes.h"
 #include "pixfmt.h"
 
 typedef struct AVComponentDescriptor{
@@ -83,27 +85,60 @@ typedef struct AVPixFmtDescriptor{
     AVComponentDescriptor comp[4];
 }AVPixFmtDescriptor;
 
-#define PIX_FMT_BE        1 ///< Pixel format is big-endian.
-#define PIX_FMT_PAL       2 ///< Pixel format has a palette in data[1], values are indexes in this palette.
-#define PIX_FMT_BITSTREAM 4 ///< All values of a component are bit-wise packed end to end.
-#define PIX_FMT_HWACCEL   8 ///< Pixel format is an HW accelerated format.
-#define PIX_FMT_PLANAR   16 ///< At least one pixel component is not in the first data plane
-#define PIX_FMT_RGB      32 ///< The pixel format contains RGB-like data (as opposed to YUV/grayscale)
+/**
+ * Pixel format is big-endian.
+ */
+#define AV_PIX_FMT_FLAG_BE           (1 << 0)
+/**
+ * Pixel format has a palette in data[1], values are indexes in this palette.
+ */
+#define AV_PIX_FMT_FLAG_PAL          (1 << 1)
+/**
+ * All values of a component are bit-wise packed end to end.
+ */
+#define AV_PIX_FMT_FLAG_BITSTREAM    (1 << 2)
+/**
+ * Pixel format is an HW accelerated format.
+ */
+#define AV_PIX_FMT_FLAG_HWACCEL      (1 << 3)
+/**
+ * At least one pixel component is not in the first data plane.
+ */
+#define AV_PIX_FMT_FLAG_PLANAR       (1 << 4)
+/**
+ * The pixel format contains RGB-like data (as opposed to YUV/grayscale).
+ */
+#define AV_PIX_FMT_FLAG_RGB          (1 << 5)
 /**
  * The pixel format is "pseudo-paletted". This means that Libav treats it as
  * paletted internally, but the palette is generated by the decoder and is not
  * stored in the file.
  */
-#define PIX_FMT_PSEUDOPAL 64
-
-#define PIX_FMT_ALPHA   128 ///< The pixel format has an alpha channel
+#define AV_PIX_FMT_FLAG_PSEUDOPAL    (1 << 6)
+/**
+ * The pixel format has an alpha channel.
+ */
+#define AV_PIX_FMT_FLAG_ALPHA        (1 << 7)
 
+#if FF_API_PIX_FMT
+/**
+ * @deprecated use the AV_PIX_FMT_FLAG_* flags
+ */
+#define PIX_FMT_BE        AV_PIX_FMT_FLAG_BE
+#define PIX_FMT_PAL       AV_PIX_FMT_FLAG_PAL
+#define PIX_FMT_BITSTREAM AV_PIX_FMT_FLAG_BITSTREAM
+#define PIX_FMT_HWACCEL   AV_PIX_FMT_FLAG_HWACCEL
+#define PIX_FMT_PLANAR    AV_PIX_FMT_FLAG_PLANAR
+#define PIX_FMT_RGB       AV_PIX_FMT_FLAG_RGB
+#define PIX_FMT_PSEUDOPAL AV_PIX_FMT_FLAG_PSEUDOPAL
+#define PIX_FMT_ALPHA     AV_PIX_FMT_FLAG_ALPHA
+#endif
 
 #if FF_API_PIX_FMT_DESC
 /**
  * The array of all the pixel format descriptors.
  */
-extern const AVPixFmtDescriptor av_pix_fmt_descriptors[];
+extern attribute_deprecated const AVPixFmtDescriptor av_pix_fmt_descriptors[];
 #endif
 
 /**
@@ -177,7 +212,8 @@ char *av_get_pix_fmt_string (char *buf, int buf_size, enum AVPixelFormat pix_fmt
 
 /**
  * Return the number of bits per pixel used by the pixel format
- * described by pixdesc.
+ * described by pixdesc. Note that this is not the same as the number
+ * of bits per sample.
  *
  * The returned number of bits refers to the number of bits actually
  * used for storing the pixel information, that is padding bits are
@@ -219,5 +255,22 @@ enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc);
 int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt,
                                      int *h_shift, int *v_shift);
 
+/**
+ * @return number of planes in pix_fmt, a negative AVERROR if pix_fmt is not a
+ * valid pixel format.
+ */
+int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt);
+
+
+/**
+ * Utility function to swap the endianness of a pixel format.
+ *
+ * @param[in]  pix_fmt the pixel format
+ *
+ * @return pixel format with swapped endianness if it exists,
+ * otherwise AV_PIX_FMT_NONE
+ */
+enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt);
+
 
 #endif /* AVUTIL_PIXDESC_H */
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 1072f00..0d6e0a3 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -28,7 +28,7 @@
  */
 
 #include "libavutil/avconfig.h"
-#include "libavutil/version.h"
+#include "version.h"
 
 /**
  * Pixel format.
@@ -77,8 +77,10 @@ enum AVPixelFormat {
     AV_PIX_FMT_YUVJ420P,  ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
     AV_PIX_FMT_YUVJ422P,  ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
     AV_PIX_FMT_YUVJ444P,  ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+#if FF_API_XVMC
     AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
     AV_PIX_FMT_XVMC_MPEG2_IDCT,
+#endif /* FF_API_XVMC */
     AV_PIX_FMT_UYVY422,   ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
     AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
     AV_PIX_FMT_BGR8,      ///< packed RGB 3:3:2,  8bpp, (msb)2B 3G 3R(lsb)
@@ -100,11 +102,13 @@ enum AVPixelFormat {
     AV_PIX_FMT_YUV440P,   ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
     AV_PIX_FMT_YUVJ440P,  ///< planar YUV 4:4:0 full scale (JPEG), deprecated in favor of PIX_FMT_YUV440P and setting color_range
     AV_PIX_FMT_YUVA420P,  ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
+#if FF_API_VDPAU
     AV_PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     AV_PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     AV_PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     AV_PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
     AV_PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+#endif
     AV_PIX_FMT_RGB48BE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian
     AV_PIX_FMT_RGB48LE,   ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian
 
@@ -128,7 +132,9 @@ enum AVPixelFormat {
     AV_PIX_FMT_YUV422P16BE,  ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
     AV_PIX_FMT_YUV444P16LE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
     AV_PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+#if FF_API_VDPAU
     AV_PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers
+#endif
     AV_PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
 
     AV_PIX_FMT_RGB444LE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
@@ -178,6 +184,12 @@ enum AVPixelFormat {
     AV_PIX_FMT_YUVA422P16LE, ///< planar YUV 4:2:2 48bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
     AV_PIX_FMT_YUVA444P16BE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, big-endian)
     AV_PIX_FMT_YUVA444P16LE, ///< planar YUV 4:4:4 64bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
+    AV_PIX_FMT_VDPAU,     ///< HW acceleration through VDPAU, Picture.data[3] contains a VdpVideoSurface
+    AV_PIX_FMT_XYZ12LE,      ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as little-endian, the 4 lower bits are set to 0
+    AV_PIX_FMT_XYZ12BE,      ///< packed XYZ 4:4:4, 36 bpp, (msb) 12X, 12Y, 12Z (lsb), the 2-byte value for each X/Y/Z is stored as big-endian, the 4 lower bits are set to 0
+    AV_PIX_FMT_NV16,         ///< interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
+    AV_PIX_FMT_NV20LE,       ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    AV_PIX_FMT_NV20BE,       ///< interleaved chroma YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), big-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
@@ -230,6 +242,9 @@ enum AVPixelFormat {
 #define AV_PIX_FMT_YUVA422P16 AV_PIX_FMT_NE(YUVA422P16BE, YUVA422P16LE)
 #define AV_PIX_FMT_YUVA444P16 AV_PIX_FMT_NE(YUVA444P16BE, YUVA444P16LE)
 
+#define AV_PIX_FMT_XYZ12      AV_PIX_FMT_NE(XYZ12BE, XYZ12LE)
+#define AV_PIX_FMT_NV20       AV_PIX_FMT_NE(NV20BE,  NV20LE)
+
 #if FF_API_PIX_FMT
 #define PixelFormat AVPixelFormat
 
diff --git a/libavutil/ppc/cpu.c b/libavutil/ppc/cpu.c
index 0025711..50107e1 100644
--- a/libavutil/ppc/cpu.c
+++ b/libavutil/ppc/cpu.c
@@ -29,6 +29,7 @@
 #endif /* __APPLE__ */
 
 #include "libavutil/cpu.h"
+#include "libavutil/cpu_internal.h"
 #include "config.h"
 
 /**
diff --git a/libavutil/ppc/cpu.h b/libavutil/ppc/cpu.h
new file mode 100644
index 0000000..f8fae58
--- /dev/null
+++ b/libavutil/ppc/cpu.h
@@ -0,0 +1,28 @@
+/*
+ * 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 AVUTIL_PPC_CPU_H
+#define AVUTIL_PPC_CPU_H
+
+#include "config.h"
+#include "libavutil/cpu.h"
+#include "libavutil/cpu_internal.h"
+
+#define PPC_ALTIVEC(flags) CPUEXT(flags, ALTIVEC)
+
+#endif /* AVUTIL_PPC_CPU_H */
diff --git a/libavutil/ppc/float_dsp_altivec.c b/libavutil/ppc/float_dsp_altivec.c
index 55e3fbe..fee4e7c 100644
--- a/libavutil/ppc/float_dsp_altivec.c
+++ b/libavutil/ppc/float_dsp_altivec.c
@@ -36,3 +36,89 @@ void ff_vector_fmul_altivec(float *dst, const float *src0, const float *src1,
         vec_st(d1, 16, dst + i);
     }
 }
+
+void ff_vector_fmul_window_altivec(float *dst, const float *src0,
+                                   const float *src1, const float *win, int len)
+{
+    vector float zero, t0, t1, s0, s1, wi, wj;
+    const vector unsigned char reverse = vcprm(3, 2, 1, 0);
+    int i, j;
+
+    dst  += len;
+    win  += len;
+    src0 += len;
+
+    zero = (vector float)vec_splat_u32(0);
+
+    for (i = -len * 4, j = len * 4 - 16; i < 0; i += 16, j -= 16) {
+        s0 = vec_ld(i, src0);
+        s1 = vec_ld(j, src1);
+        wi = vec_ld(i, win);
+        wj = vec_ld(j, win);
+
+        s1 = vec_perm(s1, s1, reverse);
+        wj = vec_perm(wj, wj, reverse);
+
+        t0 = vec_madd(s0, wj, zero);
+        t0 = vec_nmsub(s1, wi, t0);
+        t1 = vec_madd(s0, wi, zero);
+        t1 = vec_madd(s1, wj, t1);
+        t1 = vec_perm(t1, t1, reverse);
+
+        vec_st(t0, i, dst);
+        vec_st(t1, j, dst);
+    }
+}
+
+void ff_vector_fmul_add_altivec(float *dst, const float *src0,
+                                const float *src1, const float *src2,
+                                int len)
+{
+    int i;
+    vector float d, s0, s1, s2, t0, t1, edges;
+    vector unsigned char align = vec_lvsr(0,dst),
+                         mask = vec_lvsl(0, dst);
+
+    for (i = 0; i < len - 3; i += 4) {
+        t0 = vec_ld(0, dst + i);
+        t1 = vec_ld(15, dst + i);
+        s0 = vec_ld(0, src0 + i);
+        s1 = vec_ld(0, src1 + i);
+        s2 = vec_ld(0, src2 + i);
+        edges = vec_perm(t1, t0, mask);
+        d = vec_madd(s0, s1, s2);
+        t1 = vec_perm(d, edges, align);
+        t0 = vec_perm(edges, d, align);
+        vec_st(t1, 15, dst + i);
+        vec_st(t0, 0, dst + i);
+    }
+}
+
+void ff_vector_fmul_reverse_altivec(float *dst, const float *src0,
+                                    const float *src1, int len)
+{
+    int i;
+    vector float d, s0, s1, h0, l0,
+                s2, s3, zero = (vector float) vec_splat_u32(0);
+
+    src1 += len-4;
+    for(i = 0; i < len - 7; i += 8) {
+        s1 = vec_ld(0, src1 - i);              // [a,b,c,d]
+        s0 = vec_ld(0, src0 + i);
+        l0 = vec_mergel(s1, s1);               // [c,c,d,d]
+        s3 = vec_ld(-16, src1 - i);
+        h0 = vec_mergeh(s1, s1);               // [a,a,b,b]
+        s2 = vec_ld(16, src0 + i);
+        s1 = vec_mergeh(vec_mergel(l0, h0),    // [d,b,d,b]
+                        vec_mergeh(l0, h0));   // [c,a,c,a]
+        // [d,c,b,a]
+        l0 = vec_mergel(s3, s3);
+        d = vec_madd(s0, s1, zero);
+        h0 = vec_mergeh(s3, s3);
+        vec_st(d, 0, dst + i);
+        s3 = vec_mergeh(vec_mergel(l0, h0),
+                        vec_mergeh(l0, h0));
+        d = vec_madd(s2, s3, zero);
+        vec_st(d, 16, dst + i);
+    }
+}
diff --git a/libavutil/ppc/float_dsp_altivec.h b/libavutil/ppc/float_dsp_altivec.h
index 0b9425b..87d50a8 100644
--- a/libavutil/ppc/float_dsp_altivec.h
+++ b/libavutil/ppc/float_dsp_altivec.h
@@ -21,7 +21,18 @@
 #ifndef AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H
 #define AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H
 
-extern void ff_vector_fmul_altivec(float *dst, const float *src0,
-                                   const float *src1, int len);
+void ff_vector_fmul_altivec(float *dst, const float *src0,
+                            const float *src1, int len);
+
+void ff_vector_fmul_window_altivec(float *dst, const float *src0,
+                                   const float *src1, const float *win,
+                                   int len);
+
+void ff_vector_fmul_add_altivec(float *dst, const float *src0,
+                                const float *src1, const float *src2,
+                                int len);
+
+void ff_vector_fmul_reverse_altivec(float *dst, const float *src0,
+                                    const float *src1, int len);
 
 #endif /* AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H */
diff --git a/libavutil/ppc/float_dsp_init.c b/libavutil/ppc/float_dsp_init.c
index 2052764..60d0f19 100644
--- a/libavutil/ppc/float_dsp_init.c
+++ b/libavutil/ppc/float_dsp_init.c
@@ -19,18 +19,22 @@
  */
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/float_dsp.h"
+#include "libavutil/ppc/cpu.h"
 #include "float_dsp_altivec.h"
 
-void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact)
+av_cold void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact)
 {
-#if HAVE_ALTIVEC
-    int mm_flags = av_get_cpu_flags();
-
-    if (!(mm_flags & AV_CPU_FLAG_ALTIVEC))
+    if (!PPC_ALTIVEC(av_get_cpu_flags()))
         return;
 
     fdsp->vector_fmul = ff_vector_fmul_altivec;
-#endif
+    fdsp->vector_fmul_add = ff_vector_fmul_add_altivec;
+    fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_altivec;
+
+    if (!bit_exact) {
+        fdsp->vector_fmul_window = ff_vector_fmul_window_altivec;
+    }
 }
diff --git a/libavutil/ppc/timer.h b/libavutil/ppc/timer.h
index 0981d0c..8d08d28 100644
--- a/libavutil/ppc/timer.h
+++ b/libavutil/ppc/timer.h
@@ -23,6 +23,10 @@
 
 #include <stdint.h>
 
+#include "config.h"
+
+#if HAVE_INLINE_ASM_LABELS
+
 #define AV_READ_TIME read_time
 
 static inline uint64_t read_time(void)
@@ -44,4 +48,6 @@ static inline uint64_t read_time(void)
      return (((uint64_t)tbu)<<32) | (uint64_t)tbl;
 }
 
+#endif /* HAVE_INLINE_ASM_LABELS */
+
 #endif /* AVUTIL_PPC_TIMER_H */
diff --git a/libavutil/ppc/util_altivec.h b/libavutil/ppc/util_altivec.h
index bdbf862..f2e0b13 100644
--- a/libavutil/ppc/util_altivec.h
+++ b/libavutil/ppc/util_altivec.h
@@ -34,6 +34,8 @@
 
 #include "types_altivec.h"
 
+#if HAVE_ALTIVEC
+
 // used to build registers permutation vectors (vcprm)
 // the 's' are for words in the _s_econd vector
 #define WORD_0 0x00,0x01,0x02,0x03
@@ -115,4 +117,6 @@ static inline vec_u8 load_with_perm_vec(int offset, uint8_t *src, vec_u8 perm_ve
     return vec_perm(a, b, perm_vec);
 }
 
+#endif /* HAVE_ALTIVEC */
+
 #endif /* AVUTIL_PPC_UTIL_ALTIVEC_H */
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index ec9caa7..4680081 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -30,13 +30,14 @@
 #include <fcntl.h>
 #include <math.h>
 #include <time.h>
+#include "internal.h"
 #include "timer.h"
 #include "random_seed.h"
 
 static int read_random(uint32_t *dst, const char *file)
 {
 #if HAVE_UNISTD_H
-    int fd = open(file, O_RDONLY);
+    int fd = avpriv_open(file, O_RDONLY);
     int err = -1;
 
     if (fd == -1)
diff --git a/libavutil/rational.c b/libavutil/rational.c
index 4770c54..4053936 100644
--- a/libavutil/rational.c
+++ b/libavutil/rational.c
@@ -26,7 +26,6 @@
  */
 
 #include "avassert.h"
-//#include <math.h>
 #include <limits.h>
 
 #include "common.h"
diff --git a/libavutil/sha.c b/libavutil/sha.c
index c7c6ce3..2d9b58c 100644
--- a/libavutil/sha.c
+++ b/libavutil/sha.c
@@ -22,6 +22,8 @@
  */
 
 #include <string.h>
+
+#include "attributes.h"
 #include "avutil.h"
 #include "bswap.h"
 #include "sha.h"
@@ -251,7 +253,7 @@ static void sha256_transform(uint32_t *state, const uint8_t buffer[64])
 }
 
 
-int av_sha_init(AVSHA* ctx, int bits)
+av_cold int av_sha_init(AVSHA *ctx, int bits)
 {
     ctx->digest_len = bits >> 5;
     switch (bits) {
diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c
new file mode 100644
index 0000000..850fd75
--- /dev/null
+++ b/libavutil/stereo3d.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "mem.h"
+#include "stereo3d.h"
+
+AVStereo3D *av_stereo3d_alloc(void)
+{
+    return av_mallocz(sizeof(AVStereo3D));
+}
+
+AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame)
+{
+    AVFrameSideData *side_data = av_frame_new_side_data(frame,
+                                                        AV_FRAME_DATA_STEREO3D,
+                                                        sizeof(AVStereo3D));
+    if (!side_data)
+        return NULL;
+
+    return (AVStereo3D *)side_data->data;
+}
diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
new file mode 100644
index 0000000..695d6f1
--- /dev/null
+++ b/libavutil/stereo3d.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2013 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "frame.h"
+
+/**
+ * List of possible 3D Types
+ */
+enum AVStereo3DType {
+    /**
+     * Video is not stereoscopic (and metadata has to be there).
+     */
+    AV_STEREO3D_2D,
+
+    /**
+     * Views are next to each other.
+     *
+     *    LLLLRRRR
+     *    LLLLRRRR
+     *    LLLLRRRR
+     *    ...
+     */
+    AV_STEREO3D_SIDEBYSIDE,
+
+    /**
+     * Views are on top of each other.
+     *
+     *    LLLLLLLL
+     *    LLLLLLLL
+     *    RRRRRRRR
+     *    RRRRRRRR
+     */
+    AV_STEREO3D_TOPBOTTOM,
+
+    /**
+     * Views are alternated temporally.
+     *
+     *     frame0   frame1   frame2   ...
+     *    LLLLLLLL RRRRRRRR LLLLLLLL
+     *    LLLLLLLL RRRRRRRR LLLLLLLL
+     *    LLLLLLLL RRRRRRRR LLLLLLLL
+     *    ...      ...      ...
+     */
+    AV_STEREO3D_FRAMESEQUENCE,
+
+    /**
+     * Views are packed in a checkerboard-like structure per pixel.
+     *
+     *    LRLRLRLR
+     *    RLRLRLRL
+     *    LRLRLRLR
+     *    ...
+     */
+    AV_STEREO3D_CHECKERBOARD,
+
+    /**
+     * Views are next to each other, but when upscaling
+     * apply a checkerboard pattern.
+     *
+     *     LLLLRRRR          L L L L    R R R R
+     *     LLLLRRRR    =>     L L L L  R R R R
+     *     LLLLRRRR          L L L L    R R R R
+     *     LLLLRRRR           L L L L  R R R R
+     */
+    AV_STEREO3D_SIDEBYSIDE_QUINCUNX,
+
+    /**
+     * Views are packed per line, as if interlaced.
+     *
+     *    LLLLLLLL
+     *    RRRRRRRR
+     *    LLLLLLLL
+     *    ...
+     */
+    AV_STEREO3D_LINES,
+
+    /**
+     * Views are packed per column.
+     *
+     *    LRLRLRLR
+     *    LRLRLRLR
+     *    LRLRLRLR
+     *    ...
+     */
+    AV_STEREO3D_COLUMNS,
+};
+
+
+/**
+ * Inverted views, Right/Bottom represents the left view.
+ */
+#define AV_STEREO3D_FLAG_INVERT     (1 << 0)
+
+/**
+ * Stereo 3D type: this structure describes how two videos are packed
+ * within a single video surface, with additional information as needed.
+ *
+ * @note The struct must be allocated with av_stereo3d_alloc() and
+ *       its size is not a part of the public ABI.
+ */
+typedef struct AVStereo3D {
+    /**
+     * How views are packed within the video.
+     */
+    enum AVStereo3DType type;
+
+    /**
+     * Additional information about the frame packing.
+     */
+    int flags;
+} AVStereo3D;
+
+/**
+ * Allocate an AVStereo3D structure and set its fields to default values.
+ * The resulting struct can be freed using av_freep().
+ *
+ * @return An AVStereo3D filled with default values or NULL on failure.
+ */
+AVStereo3D *av_stereo3d_alloc(void);
+
+/**
+ * Allocate a complete AVFrameSideData and add it to the frame.
+ *
+ * @param frame The frame which side data is added to.
+ *
+ * @return The AVStereo3D structure to be filled by caller.
+ */
+AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame);
diff --git a/libavutil/time.c b/libavutil/time.c
index 51779c5..62cd445 100644
--- a/libavutil/time.c
+++ b/libavutil/time.c
@@ -31,7 +31,7 @@
 #include <windows.h>
 #endif
 
-#include "libavutil/time.h"
+#include "time.h"
 #include "error.h"
 
 int64_t av_gettime(void)
diff --git a/libavutil/tomi/intreadwrite.h b/libavutil/tomi/intreadwrite.h
index 9295004..baf592a 100644
--- a/libavutil/tomi/intreadwrite.h
+++ b/libavutil/tomi/intreadwrite.h
@@ -22,7 +22,9 @@
 #define AVUTIL_TOMI_INTREADWRITE_H
 
 #include <stdint.h>
+
 #include "config.h"
+#include "libavutil/attributes.h"
 
 #define AV_RB16 AV_RB16
 static av_always_inline uint16_t AV_RB16(const void *p)
diff --git a/libavutil/tree.c b/libavutil/tree.c
index fd51a74..d48d01a 100644
--- a/libavutil/tree.c
+++ b/libavutil/tree.c
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "error.h"
 #include "log.h"
 #include "mem.h"
 #include "tree.h"
@@ -43,7 +44,8 @@ void *av_tree_find(const AVTreeNode *t, void *key,
     if (t) {
         unsigned int v = cmp(key, t->elem);
         if (v) {
-            if (next) next[v >> 31] = t->elem;
+            if (next)
+                next[v >> 31] = t->elem;
             return av_tree_find(t->child[(v >> 31) ^ 1], key, cmp, next);
         } else {
             if (next) {
@@ -71,56 +73,60 @@ void *av_tree_insert(AVTreeNode **tp, void *key,
                 void *next_elem[2];
                 av_tree_find(t->child[i], key, cmp, next_elem);
                 key = t->elem = next_elem[i];
-                v = -i;
+                v   = -i;
             } else {
                 *next = t;
-                *tp = NULL;
+                *tp   = NULL;
                 return NULL;
             }
         }
         ret = av_tree_insert(&t->child[v >> 31], key, cmp, next);
         if (!ret) {
-            int i = (v >> 31) ^ !!*next;
+            int i              = (v >> 31) ^ !!*next;
             AVTreeNode **child = &t->child[i];
             t->state += 2 * i - 1;
 
             if (!(t->state & 1)) {
                 if (t->state) {
                     /* The following code is equivalent to
-                    if((*child)->state*2 == -t->state)
-                        rotate(child, i^1);
-                    rotate(tp, i);
-
-                    with rotate():
-                    static void rotate(AVTreeNode **tp, int i) {
-                        AVTreeNode *t= *tp;
-
-                        *tp= t->child[i];
-                        t->child[i]= t->child[i]->child[i^1];
-                        (*tp)->child[i^1]= t;
-                        i= 4*t->state + 2*(*tp)->state + 12;
-                          t  ->state=                     ((0x614586 >> i) & 3)-1;
-                        (*tp)->state= ((*tp)->state>>1) + ((0x400EEA >> i) & 3)-1;
-                    }
-                    but such a rotate function is both bigger and slower
-                    */
-                    if (( *child )->state * 2 == -t->state) {
+                     * if ((*child)->state * 2 == -t->state)
+                     *     rotate(child, i ^ 1);
+                     * rotate(tp, i);
+                     *
+                     * with rotate():
+                     * static void rotate(AVTreeNode **tp, int i)
+                     * {
+                     *     AVTreeNode *t= *tp;
+                     *
+                     *     *tp = t->child[i];
+                     *     t->child[i] = t->child[i]->child[i ^ 1];
+                     *     (*tp)->child[i ^ 1] = t;
+                     *     i = 4 * t->state + 2 * (*tp)->state + 12;
+                     *     t->state     = ((0x614586 >> i) & 3) - 1;
+                     *     (*tp)->state = ((0x400EEA >> i) & 3) - 1 +
+                     *                    ((*tp)->state >> 1);
+                     * }
+                     * but such a rotate function is both bigger and slower
+                     */
+                    if ((*child)->state * 2 == -t->state) {
                         *tp                    = (*child)->child[i ^ 1];
                         (*child)->child[i ^ 1] = (*tp)->child[i];
                         (*tp)->child[i]        = *child;
-                        *child                 = ( *tp )->child[i ^ 1];
+                        *child                 = (*tp)->child[i ^ 1];
                         (*tp)->child[i ^ 1]    = t;
 
                         (*tp)->child[0]->state = -((*tp)->state > 0);
-                        (*tp)->child[1]->state =   (*tp)->state < 0;
+                        (*tp)->child[1]->state = (*tp)->state < 0;
                         (*tp)->state           = 0;
                     } else {
-                        *tp                    = *child;
-                        *child                 = (*child)->child[i ^ 1];
-                        (*tp)->child[i ^ 1]    = t;
-                        if ((*tp)->state) t->state = 0;
-                        else              t->state >>= 1;
-                        (*tp)->state           = -t->state;
+                        *tp                 = *child;
+                        *child              = (*child)->child[i ^ 1];
+                        (*tp)->child[i ^ 1] = t;
+                        if ((*tp)->state)
+                            t->state = 0;
+                        else
+                            t->state >>= 1;
+                        (*tp)->state = -t->state;
                     }
                 }
             }
@@ -174,11 +180,11 @@ static int check(AVTreeNode *t)
         int left  = check(t->child[0]);
         int right = check(t->child[1]);
 
-        if (left>999 || right>999)
+        if (left > 999 || right > 999)
             return 1000;
         if (right - left != t->state)
             return 1000;
-        if (t->state>1 || t->state<-1)
+        if (t->state > 1 || t->state < -1)
             return 1000;
         return FFMAX(left, right) + 1;
     }
@@ -188,7 +194,8 @@ static int check(AVTreeNode *t)
 static void print(AVTreeNode *t, int depth)
 {
     int i;
-    for (i = 0; i < depth * 4; i++) av_log(NULL, AV_LOG_ERROR, " ");
+    for (i = 0; i < depth * 4; i++)
+        av_log(NULL, AV_LOG_ERROR, " ");
     if (t) {
         av_log(NULL, AV_LOG_ERROR, "Node %p %2d %p\n", t, t->state, t->elem);
         print(t->child[0], depth + 1);
@@ -202,37 +209,53 @@ static int cmp(void *a, const void *b)
     return (uint8_t *) a - (const uint8_t *) b;
 }
 
-int main (void)
+int main(void)
 {
     int i;
-    void *k;
     AVTreeNode *root = NULL, *node = NULL;
     AVLFG prng;
 
     av_lfg_init(&prng, 1);
 
     for (i = 0; i < 10000; i++) {
-        int j = av_lfg_get(&prng) % 86294;
+        AVTreeNode *node2 = NULL;
+        intptr_t j = av_lfg_get(&prng) % 86294;
+        void *ret, *jj = (void *)(j + 1);
+
+        while (ret = av_tree_find(root, jj, cmp, NULL)) {
+            j  = av_lfg_get(&prng) % 86294;
+            jj = (void *)(j + 1);
+        }
+
         if (check(root) > 999) {
             av_log(NULL, AV_LOG_ERROR, "FATAL error %d\n", i);
-        print(root, 0);
-            return -1;
+            print(root, 0);
+            return 1;
         }
-        av_log(NULL, AV_LOG_ERROR, "inserting %4d\n", j);
+
         if (!node)
             node = av_tree_node_alloc();
-        av_tree_insert(&root, (void *) (j + 1), cmp, &node);
-
-        j = av_lfg_get(&prng) % 86294;
-        {
-            AVTreeNode *node2 = NULL;
-            av_log(NULL, AV_LOG_ERROR, "removing %4d\n", j);
-            av_tree_insert(&root, (void *) (j + 1), cmp, &node2);
-            k = av_tree_find(root, (void *) (j + 1), cmp, NULL);
-            if (k)
-                av_log(NULL, AV_LOG_ERROR, "removal failure %d\n", i);
+        if (!node) {
+            av_log(NULL, AV_LOG_ERROR, "Memory allocation failure.\n");
+            return 1;
         }
+        av_tree_insert(&root, jj, cmp, &node);
+
+        while (ret = av_tree_find(root, jj, cmp, NULL)) {
+            j  = av_lfg_get(&prng) % 86294;
+            jj = (void *)(j + 1);
+        }
+
+        ret = av_tree_insert(&root, jj, cmp, &node2);
+        if (ret != jj)
+            av_tree_destroy(node2);
+        ret = av_tree_find(root, jj, cmp, NULL);
+        if (ret)
+            av_log(NULL, AV_LOG_ERROR, "removal failure %d\n", i);
     }
+
+    av_tree_destroy(root);
+
     return 0;
 }
 #endif
diff --git a/libavutil/tree.h b/libavutil/tree.h
index 623280f..424656e 100644
--- a/libavutil/tree.h
+++ b/libavutil/tree.h
@@ -34,10 +34,10 @@
  * @addtogroup lavu_tree AVTree
  * @ingroup lavu_data
  *
- * Low complexity tree container
+ * Low-complexity tree container
  *
  * Insertion, removal, finding equal, largest which is smaller than and
- * smallest which is larger than, all have O(log n) worst case complexity.
+ * smallest which is larger than, all have O(log n) worst-case complexity.
  * @{
  */
 
@@ -58,10 +58,11 @@ struct AVTreeNode *av_tree_node_alloc(void);
  * @param next If next is not NULL, then next[0] will contain the previous
  *             element and next[1] the next element. If either does not exist,
  *             then the corresponding entry in next is unchanged.
- * @return An element with cmp(key, elem)==0 or NULL if no such element exists in
- *         the tree.
+ * @return An element with cmp(key, elem) == 0 or NULL if no such element
+ *         exists in the tree.
  */
-void *av_tree_find(const struct AVTreeNode *root, void *key, int (*cmp)(void *key, const void *b), void *next[2]);
+void *av_tree_find(const struct AVTreeNode *root, void *key,
+                   int (*cmp)(void *key, const void *b), void *next[2]);
 
 /**
  * Insert or remove an element.
@@ -82,11 +83,17 @@ void *av_tree_find(const struct AVTreeNode *root, void *key, int (*cmp)(void *ke
  *             lower overhead compared to many malloced elements.
  *             You might want to define a function like:
  *             @code
- *             void *tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b), AVTreeNode **next){
- *                 if(!*next) *next= av_mallocz(av_tree_node_size);
+ *             void *tree_insert(struct AVTreeNode **rootp, void *key,
+ *                               int (*cmp)(void *key, const void *b),
+ *                               AVTreeNode **next)
+ *             {
+ *                 if (!*next)
+ *                     *next = av_mallocz(av_tree_node_size);
  *                 return av_tree_insert(rootp, key, cmp, next);
  *             }
- *             void *tree_remove(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b, AVTreeNode **next)){
+ *             void *tree_remove(struct AVTreeNode **rootp, void *key,
+ *                               int (*cmp)(void *key, const void *b, AVTreeNode **next))
+ *             {
  *                 av_freep(next);
  *                 return av_tree_insert(rootp, key, cmp, next);
  *             }
@@ -96,7 +103,10 @@ void *av_tree_find(const struct AVTreeNode *root, void *key, int (*cmp)(void *ke
  *         Which one it is depends on the tree state and the implementation. You
  *         should make no assumptions that it's one or the other in the code.
  */
-void *av_tree_insert(struct AVTreeNode **rootp, void *key, int (*cmp)(void *key, const void *b), struct AVTreeNode **next);
+void *av_tree_insert(struct AVTreeNode **rootp, void *key,
+                     int (*cmp)(void *key, const void *b),
+                     struct AVTreeNode **next);
+
 void av_tree_destroy(struct AVTreeNode *t);
 
 /**
@@ -109,7 +119,9 @@ void av_tree_destroy(struct AVTreeNode *t);
  * @note The cmp function should use the same ordering used to construct the
  *       tree.
  */
-void av_tree_enumerate(struct AVTreeNode *t, void *opaque, int (*cmp)(void *opaque, void *elem), int (*enu)(void *opaque, void *elem));
+void av_tree_enumerate(struct AVTreeNode *t, void *opaque,
+                       int (*cmp)(void *opaque, void *elem),
+                       int (*enu)(void *opaque, void *elem));
 
 /**
  * @}
diff --git a/libavutil/version.h b/libavutil/version.h
index 1dbb11c..9e1f2d8 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -36,8 +36,8 @@
  * @{
  */
 
-#define LIBAVUTIL_VERSION_MAJOR 52
-#define LIBAVUTIL_VERSION_MINOR  3
+#define LIBAVUTIL_VERSION_MAJOR 53
+#define LIBAVUTIL_VERSION_MINOR  0
 #define LIBAVUTIL_VERSION_MICRO  0
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
@@ -62,22 +62,34 @@
  */
 
 #ifndef FF_API_PIX_FMT
-#define FF_API_PIX_FMT                  (LIBAVUTIL_VERSION_MAJOR < 53)
+#define FF_API_PIX_FMT                  (LIBAVUTIL_VERSION_MAJOR < 54)
 #endif
 #ifndef FF_API_CONTEXT_SIZE
-#define FF_API_CONTEXT_SIZE             (LIBAVUTIL_VERSION_MAJOR < 53)
+#define FF_API_CONTEXT_SIZE             (LIBAVUTIL_VERSION_MAJOR < 54)
 #endif
 #ifndef FF_API_PIX_FMT_DESC
-#define FF_API_PIX_FMT_DESC             (LIBAVUTIL_VERSION_MAJOR < 53)
+#define FF_API_PIX_FMT_DESC             (LIBAVUTIL_VERSION_MAJOR < 54)
 #endif
 #ifndef FF_API_AV_REVERSE
-#define FF_API_AV_REVERSE               (LIBAVUTIL_VERSION_MAJOR < 53)
+#define FF_API_AV_REVERSE               (LIBAVUTIL_VERSION_MAJOR < 54)
 #endif
 #ifndef FF_API_AUDIOCONVERT
-#define FF_API_AUDIOCONVERT             (LIBAVUTIL_VERSION_MAJOR < 53)
+#define FF_API_AUDIOCONVERT             (LIBAVUTIL_VERSION_MAJOR < 54)
 #endif
 #ifndef FF_API_CPU_FLAG_MMX2
-#define FF_API_CPU_FLAG_MMX2            (LIBAVUTIL_VERSION_MAJOR < 53)
+#define FF_API_CPU_FLAG_MMX2            (LIBAVUTIL_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_LLS_PRIVATE
+#define FF_API_LLS_PRIVATE              (LIBAVUTIL_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_AVFRAME_LAVC
+#define FF_API_AVFRAME_LAVC             (LIBAVUTIL_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_VDPAU
+#define FF_API_VDPAU                    (LIBAVUTIL_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_XVMC
+#define FF_API_XVMC                     (LIBAVUTIL_VERSION_MAJOR < 54)
 #endif
 
 /**
diff --git a/libavutil/x86/Makefile b/libavutil/x86/Makefile
index 3dd696c..1e19082 100644
--- a/libavutil/x86/Makefile
+++ b/libavutil/x86/Makefile
@@ -1,5 +1,8 @@
 OBJS += x86/cpu.o                                                       \
         x86/float_dsp_init.o                                            \
+        x86/lls_init.o                                                  \
 
 YASM-OBJS += x86/cpuid.o                                                \
+             x86/emms.o                                                 \
              x86/float_dsp.o                                            \
+             x86/lls.o                                                  \
diff --git a/libavutil/x86/asm.h b/libavutil/x86/asm.h
index a43ab3c..e30f5db 100644
--- a/libavutil/x86/asm.h
+++ b/libavutil/x86/asm.h
@@ -24,6 +24,8 @@
 #include <stdint.h>
 #include "config.h"
 
+typedef struct xmm_reg { uint64_t a, b; } xmm_reg;
+
 #if ARCH_X86_64
 #    define OPSIZE "q"
 #    define REG_a "rax"
diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c
index 3b36fd0..0e06d5d 100644
--- a/libavutil/x86/cpu.c
+++ b/libavutil/x86/cpu.c
@@ -26,6 +26,7 @@
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "libavutil/cpu.h"
+#include "libavutil/cpu_internal.h"
 
 #if HAVE_YASM
 
@@ -133,6 +134,14 @@ int ff_get_cpu_flags_x86(void)
             if ((eax & 0x6) == 0x6)
                 rval |= AV_CPU_FLAG_AVX;
         }
+#if HAVE_AVX2
+    if (max_std_level >= 7) {
+        cpuid(7, eax, ebx, ecx, edx);
+        if (ebx&0x00000020)
+            rval |= AV_CPU_FLAG_AVX2;
+        /* TODO: BMI1/2 */
+    }
+#endif /* HAVE_AVX2 */
 #endif /* HAVE_AVX */
 #endif /* HAVE_SSE */
     }
diff --git a/libavutil/x86/cpu.h b/libavutil/x86/cpu.h
index e4f6f0b..5303c5a 100644
--- a/libavutil/x86/cpu.h
+++ b/libavutil/x86/cpu.h
@@ -21,38 +21,52 @@
 
 #include "config.h"
 #include "libavutil/cpu.h"
-
-#define CPUEXT(flags, suffix, cpuext)                                   \
-    (HAVE_ ## cpuext ## suffix && ((flags) & AV_CPU_FLAG_ ## cpuext))
+#include "libavutil/cpu_internal.h"
 
 #define AV_CPU_FLAG_AMD3DNOW    AV_CPU_FLAG_3DNOW
 #define AV_CPU_FLAG_AMD3DNOWEXT AV_CPU_FLAG_3DNOWEXT
 
-#define EXTERNAL_AMD3DNOW(flags)    CPUEXT(flags, _EXTERNAL, AMD3DNOW)
-#define EXTERNAL_AMD3DNOWEXT(flags) CPUEXT(flags, _EXTERNAL, AMD3DNOWEXT)
-#define EXTERNAL_MMX(flags)         CPUEXT(flags, _EXTERNAL, MMX)
-#define EXTERNAL_MMXEXT(flags)      CPUEXT(flags, _EXTERNAL, MMXEXT)
-#define EXTERNAL_SSE(flags)         CPUEXT(flags, _EXTERNAL, SSE)
-#define EXTERNAL_SSE2(flags)        CPUEXT(flags, _EXTERNAL, SSE2)
-#define EXTERNAL_SSE3(flags)        CPUEXT(flags, _EXTERNAL, SSE3)
-#define EXTERNAL_SSSE3(flags)       CPUEXT(flags, _EXTERNAL, SSSE3)
-#define EXTERNAL_SSE4(flags)        CPUEXT(flags, _EXTERNAL, SSE4)
-#define EXTERNAL_SSE42(flags)       CPUEXT(flags, _EXTERNAL, SSE42)
-#define EXTERNAL_AVX(flags)         CPUEXT(flags, _EXTERNAL, AVX)
-#define EXTERNAL_FMA4(flags)        CPUEXT(flags, _EXTERNAL, FMA4)
-
-#define INLINE_AMD3DNOW(flags)      CPUEXT(flags, _INLINE, AMD3DNOW)
-#define INLINE_AMD3DNOWEXT(flags)   CPUEXT(flags, _INLINE, AMD3DNOWEXT)
-#define INLINE_MMX(flags)           CPUEXT(flags, _INLINE, MMX)
-#define INLINE_MMXEXT(flags)        CPUEXT(flags, _INLINE, MMXEXT)
-#define INLINE_SSE(flags)           CPUEXT(flags, _INLINE, SSE)
-#define INLINE_SSE2(flags)          CPUEXT(flags, _INLINE, SSE2)
-#define INLINE_SSE3(flags)          CPUEXT(flags, _INLINE, SSE3)
-#define INLINE_SSSE3(flags)         CPUEXT(flags, _INLINE, SSSE3)
-#define INLINE_SSE4(flags)          CPUEXT(flags, _INLINE, SSE4)
-#define INLINE_SSE42(flags)         CPUEXT(flags, _INLINE, SSE42)
-#define INLINE_AVX(flags)           CPUEXT(flags, _INLINE, AVX)
-#define INLINE_FMA4(flags)          CPUEXT(flags, _INLINE, FMA4)
+#define X86_AMD3DNOW(flags)         CPUEXT(flags, AMD3DNOW)
+#define X86_AMD3DNOWEXT(flags)      CPUEXT(flags, AMD3DNOWEXT)
+#define X86_MMX(flags)              CPUEXT(flags, MMX)
+#define X86_MMXEXT(flags)           CPUEXT(flags, MMXEXT)
+#define X86_SSE(flags)              CPUEXT(flags, SSE)
+#define X86_SSE2(flags)             CPUEXT(flags, SSE2)
+#define X86_SSE3(flags)             CPUEXT(flags, SSE3)
+#define X86_SSSE3(flags)            CPUEXT(flags, SSSE3)
+#define X86_SSE4(flags)             CPUEXT(flags, SSE4)
+#define X86_SSE42(flags)            CPUEXT(flags, SSE42)
+#define X86_AVX(flags)              CPUEXT(flags, AVX)
+#define X86_FMA4(flags)             CPUEXT(flags, FMA4)
+#define X86_AVX2(flags)             CPUEXT(flags, AVX2)
+
+#define EXTERNAL_AMD3DNOW(flags)    CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOW)
+#define EXTERNAL_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOWEXT)
+#define EXTERNAL_MMX(flags)         CPUEXT_SUFFIX(flags, _EXTERNAL, MMX)
+#define EXTERNAL_MMXEXT(flags)      CPUEXT_SUFFIX(flags, _EXTERNAL, MMXEXT)
+#define EXTERNAL_SSE(flags)         CPUEXT_SUFFIX(flags, _EXTERNAL, SSE)
+#define EXTERNAL_SSE2(flags)        CPUEXT_SUFFIX(flags, _EXTERNAL, SSE2)
+#define EXTERNAL_SSE3(flags)        CPUEXT_SUFFIX(flags, _EXTERNAL, SSE3)
+#define EXTERNAL_SSSE3(flags)       CPUEXT_SUFFIX(flags, _EXTERNAL, SSSE3)
+#define EXTERNAL_SSE4(flags)        CPUEXT_SUFFIX(flags, _EXTERNAL, SSE4)
+#define EXTERNAL_SSE42(flags)       CPUEXT_SUFFIX(flags, _EXTERNAL, SSE42)
+#define EXTERNAL_AVX(flags)         CPUEXT_SUFFIX(flags, _EXTERNAL, AVX)
+#define EXTERNAL_FMA4(flags)        CPUEXT_SUFFIX(flags, _EXTERNAL, FMA4)
+#define EXTERNAL_AVX2(flags)        CPUEXT_SUFFIX(flags, _EXTERNAL, AVX2)
+
+#define INLINE_AMD3DNOW(flags)      CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOW)
+#define INLINE_AMD3DNOWEXT(flags)   CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOWEXT)
+#define INLINE_MMX(flags)           CPUEXT_SUFFIX(flags, _INLINE, MMX)
+#define INLINE_MMXEXT(flags)        CPUEXT_SUFFIX(flags, _INLINE, MMXEXT)
+#define INLINE_SSE(flags)           CPUEXT_SUFFIX(flags, _INLINE, SSE)
+#define INLINE_SSE2(flags)          CPUEXT_SUFFIX(flags, _INLINE, SSE2)
+#define INLINE_SSE3(flags)          CPUEXT_SUFFIX(flags, _INLINE, SSE3)
+#define INLINE_SSSE3(flags)         CPUEXT_SUFFIX(flags, _INLINE, SSSE3)
+#define INLINE_SSE4(flags)          CPUEXT_SUFFIX(flags, _INLINE, SSE4)
+#define INLINE_SSE42(flags)         CPUEXT_SUFFIX(flags, _INLINE, SSE42)
+#define INLINE_AVX(flags)           CPUEXT_SUFFIX(flags, _INLINE, AVX)
+#define INLINE_FMA4(flags)          CPUEXT_SUFFIX(flags, _INLINE, FMA4)
+#define INLINE_AVX2(flags)          CPUEXT_SUFFIX(flags, _INLINE, AVX2)
 
 void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx);
 void ff_cpu_xgetbv(int op, int *eax, int *edx);
diff --git a/libavutil/x86/emms.asm b/libavutil/x86/emms.asm
new file mode 100644
index 0000000..a6851ac
--- /dev/null
+++ b/libavutil/x86/emms.asm
@@ -0,0 +1,30 @@
+;*****************************************************************************
+;* Copyright (C) 2013 Martin Storsjo
+;*
+;* 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 "x86util.asm"
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+; void avpriv_emms_yasm(void)
+;-----------------------------------------------------------------------------
+cvisible emms_yasm, 0, 0
+    emms
+    RET
diff --git a/libavutil/x86/emms.h b/libavutil/x86/emms.h
new file mode 100644
index 0000000..2ed9e5d
--- /dev/null
+++ b/libavutil/x86/emms.h
@@ -0,0 +1,45 @@
+/*
+ * 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 AVUTIL_X86_EMMS_H
+#define AVUTIL_X86_EMMS_H
+
+#include "config.h"
+#include "libavutil/attributes.h"
+
+void avpriv_emms_yasm(void);
+
+#if HAVE_MMX_INLINE
+#   define emms_c emms_c
+/**
+ * Empty mmx state.
+ * this must be called between any dsp function and float/double code.
+ * for example sin(); dsp->idct_put(); emms_c(); cos()
+ */
+static av_always_inline void emms_c(void)
+{
+    __asm__ volatile ("emms" ::: "memory");
+}
+#elif HAVE_MMX && HAVE_MM_EMPTY
+#   include <mmintrin.h>
+#   define emms_c _mm_empty
+#elif HAVE_MMX_EXTERNAL
+#   define emms_c avpriv_emms_yasm
+#endif /* HAVE_MMX_INLINE */
+
+#endif /* AVUTIL_X86_EMMS_H */
diff --git a/libavutil/x86/float_dsp.asm b/libavutil/x86/float_dsp.asm
index 4113fd9..10330ff 100644
--- a/libavutil/x86/float_dsp.asm
+++ b/libavutil/x86/float_dsp.asm
@@ -162,3 +162,119 @@ VECTOR_DMUL_SCALAR
 INIT_YMM avx
 VECTOR_DMUL_SCALAR
 %endif
+
+;-----------------------------------------------------------------------------
+; vector_fmul_add(float *dst, const float *src0, const float *src1,
+;                 const float *src2, int len)
+;-----------------------------------------------------------------------------
+%macro VECTOR_FMUL_ADD 0
+cglobal vector_fmul_add, 5,5,2, dst, src0, src1, src2, len
+    lea       lenq, [lend*4 - 2*mmsize]
+ALIGN 16
+.loop:
+    mova    m0,   [src0q + lenq]
+    mova    m1,   [src0q + lenq + mmsize]
+    mulps   m0, m0, [src1q + lenq]
+    mulps   m1, m1, [src1q + lenq + mmsize]
+    addps   m0, m0, [src2q + lenq]
+    addps   m1, m1, [src2q + lenq + mmsize]
+    mova    [dstq + lenq], m0
+    mova    [dstq + lenq + mmsize], m1
+
+    sub     lenq,   2*mmsize
+    jge     .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse
+VECTOR_FMUL_ADD
+INIT_YMM avx
+VECTOR_FMUL_ADD
+
+;-----------------------------------------------------------------------------
+; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
+;                          int len)
+;-----------------------------------------------------------------------------
+%macro VECTOR_FMUL_REVERSE 0
+cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
+    lea       lenq, [lend*4 - 2*mmsize]
+ALIGN 16
+.loop:
+%if cpuflag(avx)
+    vmovaps     xmm0, [src1q + 16]
+    vinsertf128 m0, m0, [src1q], 1
+    vshufps     m0, m0, m0, q0123
+    vmovaps     xmm1, [src1q + mmsize + 16]
+    vinsertf128 m1, m1, [src1q + mmsize], 1
+    vshufps     m1, m1, m1, q0123
+%else
+    mova    m0, [src1q]
+    mova    m1, [src1q + mmsize]
+    shufps  m0, m0, q0123
+    shufps  m1, m1, q0123
+%endif
+    mulps   m0, m0, [src0q + lenq + mmsize]
+    mulps   m1, m1, [src0q + lenq]
+    mova    [dstq + lenq + mmsize], m0
+    mova    [dstq + lenq], m1
+    add     src1q, 2*mmsize
+    sub     lenq,  2*mmsize
+    jge     .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse
+VECTOR_FMUL_REVERSE
+INIT_YMM avx
+VECTOR_FMUL_REVERSE
+
+; float scalarproduct_float_sse(const float *v1, const float *v2, int len)
+INIT_XMM sse
+cglobal scalarproduct_float, 3,3,2, v1, v2, offset
+    neg   offsetq
+    shl   offsetq, 2
+    sub       v1q, offsetq
+    sub       v2q, offsetq
+    xorps    xmm0, xmm0
+.loop:
+    movaps   xmm1, [v1q+offsetq]
+    mulps    xmm1, [v2q+offsetq]
+    addps    xmm0, xmm1
+    add   offsetq, 16
+    js .loop
+    movhlps  xmm1, xmm0
+    addps    xmm0, xmm1
+    movss    xmm1, xmm0
+    shufps   xmm0, xmm0, 1
+    addss    xmm0, xmm1
+%if ARCH_X86_64 == 0
+    movss     r0m,  xmm0
+    fld dword r0m
+%endif
+    RET
+
+;-----------------------------------------------------------------------------
+; void ff_butterflies_float(float *src0, float *src1, int len);
+;-----------------------------------------------------------------------------
+INIT_XMM sse
+cglobal butterflies_float, 3,3,3, src0, src1, len
+%if ARCH_X86_64
+    movsxd    lenq, lend
+%endif
+    test      lenq, lenq
+    jz .end
+    shl       lenq, 2
+    lea      src0q, [src0q +   lenq]
+    lea      src1q, [src1q +   lenq]
+    neg       lenq
+.loop:
+    mova        m0, [src0q + lenq]
+    mova        m1, [src1q + lenq]
+    subps       m2, m0, m1
+    addps       m0, m0, m1
+    mova        [src1q + lenq], m2
+    mova        [src0q + lenq], m0
+    add       lenq, mmsize
+    jl .loop
+.end:
+    REP_RET
diff --git a/libavutil/x86/float_dsp_init.c b/libavutil/x86/float_dsp_init.c
index b3b7ff4..a04d91c 100644
--- a/libavutil/x86/float_dsp_init.c
+++ b/libavutil/x86/float_dsp_init.c
@@ -18,43 +18,139 @@
 
 #include "config.h"
 
+#include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
 #include "libavutil/float_dsp.h"
 #include "cpu.h"
+#include "asm.h"
 
-extern void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
+void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
+                        int len);
+void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1,
+                        int len);
+
+void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul,
+                               int len);
+void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul,
                                int len);
-extern void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1,
+
+void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul,
                                int len);
 
-extern void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul,
-                                      int len);
-extern void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul,
-                                      int len);
+void ff_vector_dmul_scalar_sse2(double *dst, const double *src,
+                                double mul, int len);
+void ff_vector_dmul_scalar_avx(double *dst, const double *src,
+                               double mul, int len);
+
+void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1,
+                            const float *src2, int len);
+void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1,
+                            const float *src2, int len);
 
-extern void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul,
-                                      int len);
+void ff_vector_fmul_reverse_sse(float *dst, const float *src0,
+                                const float *src1, int len);
+void ff_vector_fmul_reverse_avx(float *dst, const float *src0,
+                                const float *src1, int len);
 
-extern void ff_vector_dmul_scalar_sse2(double *dst, const double *src,
-                                       double mul, int len);
-extern void ff_vector_dmul_scalar_avx(double *dst, const double *src,
-                                      double mul, int len);
+float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order);
 
-void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
+void ff_butterflies_float_sse(float *src0, float *src1, int len);
+
+#if HAVE_6REGS && HAVE_INLINE_ASM
+static void vector_fmul_window_3dnowext(float *dst, const float *src0,
+                                        const float *src1, const float *win,
+                                        int len)
 {
-    int mm_flags = av_get_cpu_flags();
+    x86_reg i = -len * 4;
+    x86_reg j =  len * 4 - 8;
+    __asm__ volatile (
+        "1:                             \n"
+        "pswapd (%5, %1), %%mm1         \n"
+        "movq   (%5, %0), %%mm0         \n"
+        "pswapd (%4, %1), %%mm5         \n"
+        "movq   (%3, %0), %%mm4         \n"
+        "movq      %%mm0, %%mm2         \n"
+        "movq      %%mm1, %%mm3         \n"
+        "pfmul     %%mm4, %%mm2         \n" // src0[len + i] * win[len + i]
+        "pfmul     %%mm5, %%mm3         \n" // src1[j]       * win[len + j]
+        "pfmul     %%mm4, %%mm1         \n" // src0[len + i] * win[len + j]
+        "pfmul     %%mm5, %%mm0         \n" // src1[j]       * win[len + i]
+        "pfadd     %%mm3, %%mm2         \n"
+        "pfsub     %%mm0, %%mm1         \n"
+        "pswapd    %%mm2, %%mm2         \n"
+        "movq      %%mm1, (%2, %0)      \n"
+        "movq      %%mm2, (%2, %1)      \n"
+        "sub          $8, %1            \n"
+        "add          $8, %0            \n"
+        "jl           1b                \n"
+        "femms                          \n"
+        : "+r"(i), "+r"(j)
+        : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len)
+    );
+}
 
-    if (EXTERNAL_SSE(mm_flags)) {
+static void vector_fmul_window_sse(float *dst, const float *src0,
+                                   const float *src1, const float *win, int len)
+{
+    x86_reg i = -len * 4;
+    x86_reg j =  len * 4 - 16;
+    __asm__ volatile (
+        "1:                             \n"
+        "movaps      (%5, %1), %%xmm1   \n"
+        "movaps      (%5, %0), %%xmm0   \n"
+        "movaps      (%4, %1), %%xmm5   \n"
+        "movaps      (%3, %0), %%xmm4   \n"
+        "shufps $0x1b, %%xmm1, %%xmm1   \n"
+        "shufps $0x1b, %%xmm5, %%xmm5   \n"
+        "movaps        %%xmm0, %%xmm2   \n"
+        "movaps        %%xmm1, %%xmm3   \n"
+        "mulps         %%xmm4, %%xmm2   \n" // src0[len + i] * win[len + i]
+        "mulps         %%xmm5, %%xmm3   \n" // src1[j]       * win[len + j]
+        "mulps         %%xmm4, %%xmm1   \n" // src0[len + i] * win[len + j]
+        "mulps         %%xmm5, %%xmm0   \n" // src1[j]       * win[len + i]
+        "addps         %%xmm3, %%xmm2   \n"
+        "subps         %%xmm0, %%xmm1   \n"
+        "shufps $0x1b, %%xmm2, %%xmm2   \n"
+        "movaps        %%xmm1, (%2, %0) \n"
+        "movaps        %%xmm2, (%2, %1) \n"
+        "sub              $16, %1       \n"
+        "add              $16, %0       \n"
+        "jl                1b           \n"
+        : "+r"(i), "+r"(j)
+        : "r"(dst + len), "r"(src0 + len), "r"(src1), "r"(win + len)
+    );
+}
+#endif /* HAVE_6REGS && HAVE_INLINE_ASM */
+
+av_cold void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+#if HAVE_6REGS && HAVE_INLINE_ASM
+    if (INLINE_AMD3DNOWEXT(cpu_flags)) {
+        fdsp->vector_fmul_window  = vector_fmul_window_3dnowext;
+    }
+    if (INLINE_SSE(cpu_flags)) {
+        fdsp->vector_fmul_window = vector_fmul_window_sse;
+    }
+#endif
+    if (EXTERNAL_SSE(cpu_flags)) {
         fdsp->vector_fmul = ff_vector_fmul_sse;
         fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse;
         fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse;
+        fdsp->vector_fmul_add    = ff_vector_fmul_add_sse;
+        fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_sse;
+        fdsp->scalarproduct_float = ff_scalarproduct_float_sse;
+        fdsp->butterflies_float   = ff_butterflies_float_sse;
     }
-    if (EXTERNAL_SSE2(mm_flags)) {
+    if (EXTERNAL_SSE2(cpu_flags)) {
         fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2;
     }
-    if (EXTERNAL_AVX(mm_flags)) {
+    if (EXTERNAL_AVX(cpu_flags)) {
         fdsp->vector_fmul = ff_vector_fmul_avx;
         fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx;
         fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx;
+        fdsp->vector_fmul_add    = ff_vector_fmul_add_avx;
+        fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx;
     }
 }
diff --git a/libavutil/x86/lls.asm b/libavutil/x86/lls.asm
new file mode 100644
index 0000000..eab85ed
--- /dev/null
+++ b/libavutil/x86/lls.asm
@@ -0,0 +1,234 @@
+;******************************************************************************
+;* linear least squares model
+;*
+;* Copyright (c) 2013 Loren Merritt
+;*
+;* 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 "x86util.asm"
+
+SECTION .text
+
+%define MAX_VARS 32
+%define MAX_VARS_ALIGN (MAX_VARS+4)
+%define COVAR_STRIDE MAX_VARS_ALIGN*8
+%define COVAR(x,y) [covarq + (x)*8 + (y)*COVAR_STRIDE]
+
+struc LLSModel
+    .covariance:  resq MAX_VARS_ALIGN*MAX_VARS_ALIGN
+    .coeff:       resq MAX_VARS*MAX_VARS
+    .variance:    resq MAX_VARS
+    .indep_count: resd 1
+endstruc
+
+%macro ADDPD_MEM 2
+%if cpuflag(avx)
+    vaddpd %2, %2, %1
+%else
+    addpd  %2, %1
+%endif
+    mova   %1, %2
+%endmacro
+
+INIT_XMM sse2
+%define movdqa movaps
+cglobal update_lls, 2,5,8, ctx, var, i, j, covar2
+    %define covarq ctxq
+    mov     id, [ctxq + LLSModel.indep_count]
+    lea   varq, [varq + iq*8]
+    neg     iq
+    mov covar2q, covarq
+.loopi:
+    ; Compute all 3 pairwise products of a 2x2 block that lies on the diagonal
+    mova    m1, [varq + iq*8]
+    mova    m3, [varq + iq*8 + 16]
+    pshufd  m4, m1, q1010
+    pshufd  m5, m1, q3232
+    pshufd  m6, m3, q1010
+    pshufd  m7, m3, q3232
+    mulpd   m0, m1, m4
+    mulpd   m1, m1, m5
+    lea covarq, [covar2q + 16]
+    ADDPD_MEM COVAR(-2,0), m0
+    ADDPD_MEM COVAR(-2,1), m1
+    lea     jq, [iq + 2]
+    cmp     jd, -2
+    jg .skip4x4
+.loop4x4:
+    ; Compute all 16 pairwise products of a 4x4 block
+    mulpd   m0, m4, m3
+    mulpd   m1, m5, m3
+    mulpd   m2, m6, m3
+    mulpd   m3, m3, m7
+    ADDPD_MEM COVAR(0,0), m0
+    ADDPD_MEM COVAR(0,1), m1
+    ADDPD_MEM COVAR(0,2), m2
+    ADDPD_MEM COVAR(0,3), m3
+    mova    m3, [varq + jq*8 + 16]
+    mulpd   m0, m4, m3
+    mulpd   m1, m5, m3
+    mulpd   m2, m6, m3
+    mulpd   m3, m3, m7
+    ADDPD_MEM COVAR(2,0), m0
+    ADDPD_MEM COVAR(2,1), m1
+    ADDPD_MEM COVAR(2,2), m2
+    ADDPD_MEM COVAR(2,3), m3
+    mova    m3, [varq + jq*8 + 32]
+    add covarq, 32
+    add     jq, 4
+    cmp     jd, -2
+    jle .loop4x4
+.skip4x4:
+    test    jd, jd
+    jg .skip2x4
+    mulpd   m4, m3
+    mulpd   m5, m3
+    mulpd   m6, m3
+    mulpd   m7, m3
+    ADDPD_MEM COVAR(0,0), m4
+    ADDPD_MEM COVAR(0,1), m5
+    ADDPD_MEM COVAR(0,2), m6
+    ADDPD_MEM COVAR(0,3), m7
+.skip2x4:
+    add     iq, 4
+    add covar2q, 4*COVAR_STRIDE+32
+    cmp     id, -2
+    jle .loopi
+    test    id, id
+    jg .ret
+    mov     jq, iq
+    %define covarq covar2q
+.loop2x1:
+    movsd   m0, [varq + iq*8]
+    movlhps m0, m0
+    mulpd   m0, [varq + jq*8]
+    ADDPD_MEM COVAR(0,0), m0
+    inc     iq
+    add covarq, COVAR_STRIDE
+    test    id, id
+    jle .loop2x1
+.ret:
+    REP_RET
+
+INIT_YMM avx
+cglobal update_lls, 3,6,8, ctx, var, count, i, j, count2
+    %define covarq ctxq
+    mov  countd, [ctxq + LLSModel.indep_count]
+    lea count2d, [countq-2]
+    xor     id, id
+.loopi:
+    ; Compute all 10 pairwise products of a 4x4 block that lies on the diagonal
+    mova    ymm1, [varq + iq*8]
+    vbroadcastsd ymm4, [varq + iq*8]
+    vbroadcastsd ymm5, [varq + iq*8 + 8]
+    vbroadcastsd ymm6, [varq + iq*8 + 16]
+    vbroadcastsd ymm7, [varq + iq*8 + 24]
+    vextractf128 xmm3, ymm1, 1
+    vmulpd  ymm0, ymm1, ymm4
+    vmulpd  ymm1, ymm1, ymm5
+    vmulpd  xmm2, xmm3, xmm6
+    vmulpd  xmm3, xmm3, xmm7
+    ADDPD_MEM COVAR(iq  ,0), ymm0
+    ADDPD_MEM COVAR(iq  ,1), ymm1
+    ADDPD_MEM COVAR(iq+2,2), xmm2
+    ADDPD_MEM COVAR(iq+2,3), xmm3
+    lea     jd, [iq + 4]
+    cmp     jd, count2d
+    jg .skip4x4
+.loop4x4:
+    ; Compute all 16 pairwise products of a 4x4 block
+    mova    ymm3, [varq + jq*8]
+    vmulpd  ymm0, ymm3, ymm4
+    vmulpd  ymm1, ymm3, ymm5
+    vmulpd  ymm2, ymm3, ymm6
+    vmulpd  ymm3, ymm3, ymm7
+    ADDPD_MEM COVAR(jq,0), ymm0
+    ADDPD_MEM COVAR(jq,1), ymm1
+    ADDPD_MEM COVAR(jq,2), ymm2
+    ADDPD_MEM COVAR(jq,3), ymm3
+    add     jd, 4
+    cmp     jd, count2d
+    jle .loop4x4
+.skip4x4:
+    cmp     jd, countd
+    jg .skip2x4
+    mova    xmm3, [varq + jq*8]
+    vmulpd  xmm0, xmm3, xmm4
+    vmulpd  xmm1, xmm3, xmm5
+    vmulpd  xmm2, xmm3, xmm6
+    vmulpd  xmm3, xmm3, xmm7
+    ADDPD_MEM COVAR(jq,0), xmm0
+    ADDPD_MEM COVAR(jq,1), xmm1
+    ADDPD_MEM COVAR(jq,2), xmm2
+    ADDPD_MEM COVAR(jq,3), xmm3
+.skip2x4:
+    add     id, 4
+    add covarq, 4*COVAR_STRIDE
+    cmp     id, count2d
+    jle .loopi
+    cmp     id, countd
+    jg .ret
+    mov     jd, id
+.loop2x1:
+    vmovddup xmm0, [varq + iq*8]
+    vmulpd   xmm0, [varq + jq*8]
+    ADDPD_MEM COVAR(jq,0), xmm0
+    inc     id
+    add covarq, COVAR_STRIDE
+    cmp     id, countd
+    jle .loop2x1
+.ret:
+    REP_RET
+
+
+INIT_XMM sse2
+cglobal evaluate_lls, 3,4,2, ctx, var, order, i
+    ; This function is often called on the same buffer as update_lls, but with
+    ; an offset. They can't both be aligned.
+    ; Load halves rather than movu to avoid store-forwarding stalls, since the
+    ; input was initialized immediately prior to this function using scalar math.
+    %define coefsq ctxq
+    mov     id, orderd
+    imul    orderd, MAX_VARS
+    lea     coefsq, [ctxq + LLSModel.coeff + orderq*8]
+    movsd   m0, [varq]
+    movhpd  m0, [varq + 8]
+    mulpd   m0, [coefsq]
+    lea coefsq, [coefsq + iq*8]
+    lea   varq, [varq + iq*8]
+    neg     iq
+    add     iq, 2
+.loop:
+    movsd   m1, [varq + iq*8]
+    movhpd  m1, [varq + iq*8 + 8]
+    mulpd   m1, [coefsq + iq*8]
+    addpd   m0, m1
+    add     iq, 2
+    jl .loop
+    jg .skip1
+    movsd   m1, [varq + iq*8]
+    mulsd   m1, [coefsq + iq*8]
+    addpd   m0, m1
+.skip1:
+    movhlps m1, m0
+    addsd   m0, m1
+%if ARCH_X86_32
+    movsd  r0m, m0
+    fld   qword r0m
+%endif
+    RET
diff --git a/libavutil/x86/lls_init.c b/libavutil/x86/lls_init.c
new file mode 100644
index 0000000..888bc54
--- /dev/null
+++ b/libavutil/x86/lls_init.c
@@ -0,0 +1,41 @@
+/*
+ * linear least squares model
+ *
+ * Copyright (c) 2013 Loren Merritt
+ *
+ * This file is part of 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/lls.h"
+#include "libavutil/x86/cpu.h"
+
+void ff_update_lls_sse2(LLSModel *m, double *var);
+void ff_update_lls_avx(LLSModel *m, double *var);
+double ff_evaluate_lls_sse2(LLSModel *m, double *var, int order);
+
+av_cold void ff_init_lls_x86(LLSModel *m)
+{
+    int cpu_flags = av_get_cpu_flags();
+    if (EXTERNAL_SSE2(cpu_flags)) {
+        m->update_lls = ff_update_lls_sse2;
+        if (m->indep_count >= 4)
+            m->evaluate_lls = ff_evaluate_lls_sse2;
+    }
+    if (EXTERNAL_AVX(cpu_flags)) {
+        m->update_lls = ff_update_lls_avx;
+    }
+}
diff --git a/libavutil/x86/timer.h b/libavutil/x86/timer.h
index 35e614d..cdd67dd 100644
--- a/libavutil/x86/timer.h
+++ b/libavutil/x86/timer.h
@@ -36,6 +36,7 @@ static inline uint64_t read_time(void)
 
 #elif HAVE_RDTSC
 
+#include <intrin.h>
 #define AV_READ_TIME __rdtsc
 
 #endif /* HAVE_INLINE_ASM */
diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm
index 2617cdf..6350a5c 100644
--- a/libavutil/x86/x86inc.asm
+++ b/libavutil/x86/x86inc.asm
@@ -1,12 +1,12 @@
 ;*****************************************************************************
 ;* x86inc.asm: x264asm abstraction layer
 ;*****************************************************************************
-;* Copyright (C) 2005-2012 x264 project
+;* Copyright (C) 2005-2013 x264 project
 ;*
 ;* Authors: Loren Merritt <lorenm at u.washington.edu>
 ;*          Anton Mitrofanov <BugMaster at narod.ru>
 ;*          Jason Garrett-Glaser <darkshikari at gmail.com>
-;*          Henrik Gramner <hengar-6 at student.ltu.se>
+;*          Henrik Gramner <henrik at gramner.com>
 ;*
 ;* Permission to use, copy, modify, and/or distribute this software for any
 ;* purpose with or without fee is hereby granted, provided that the above
@@ -34,8 +34,12 @@
 ; as this feature might be useful for others as well.  Send patches or ideas
 ; to x264-devel at videolan.org .
 
-%ifndef program_name
-    %define program_name x264
+%ifndef private_prefix
+    %define private_prefix x264
+%endif
+
+%ifndef public_prefix
+    %define public_prefix private_prefix
 %endif
 
 %define WIN64  0
@@ -45,6 +49,8 @@
         %define WIN64  1
     %elifidn __OUTPUT_FORMAT__,win64
         %define WIN64  1
+    %elifidn __OUTPUT_FORMAT__,x64
+        %define WIN64  1
     %else
         %define UNIX64 1
     %endif
@@ -56,23 +62,17 @@
     %define mangle(x) x
 %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.
+; aout does not support align=
+; NOTE: This section is out of sync with x264, in order to
+; keep supporting OS/2.
 %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
+    %ifidn __OUTPUT_FORMAT__,aout
         section .text
     %else
         SECTION .rodata align=%1
     %endif
 %endmacro
 
-; aout does not support align=
 %macro SECTION_TEXT 0-1 16
     %ifidn __OUTPUT_FORMAT__,aout
         SECTION .text
@@ -131,8 +131,7 @@ CPUNOP amdnop
 ; Pops anything that was pushed by PROLOGUE, and returns.
 
 ; REP_RET:
-; Same, but if it doesn't pop anything it becomes a 2-byte ret, for athlons
-; which are slow when a normal ret follows a branch.
+; Use this instead of RET if it's a branch target.
 
 ; registers:
 ; rN and rNq are the native-size register holding function argument N
@@ -331,14 +330,18 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
             %if stack_size < 0
                 %assign stack_size -stack_size
             %endif
-            %if mmsize != 8
-                %assign xmm_regs_used %2
+            %assign stack_size_padded stack_size
+            %if WIN64
+                %assign stack_size_padded stack_size_padded + 32 ; reserve 32 bytes for shadow space
+                %if mmsize != 8
+                    %assign xmm_regs_used %2
+                    %if xmm_regs_used > 8
+                        %assign stack_size_padded stack_size_padded + (xmm_regs_used-8)*16
+                    %endif
+                %endif
             %endif
             %if mmsize <= 16 && HAVE_ALIGNED_STACK
-                %assign stack_size_padded stack_size + %%stack_alignment - gprsize - (stack_offset & (%%stack_alignment - 1))
-                %if xmm_regs_used > 6
-                    %assign stack_size_padded stack_size_padded + (xmm_regs_used - 6) * 16
-                %endif
+                %assign stack_size_padded stack_size_padded + %%stack_alignment - gprsize - (stack_offset & (%%stack_alignment - 1))
                 SUB rsp, stack_size_padded
             %else
                 %assign %%reg_num (regs_used - 1)
@@ -348,14 +351,6 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
                 ; stack in a single instruction (i.e. mov rsp, rstk or mov
                 ; rsp, [rsp+stack_size_padded])
                 mov  rstk, rsp
-                %assign stack_size_padded stack_size
-                %if xmm_regs_used > 6
-                    %assign stack_size_padded stack_size_padded + (xmm_regs_used - 6) * 16
-                    %if mmsize == 32 && xmm_regs_used & 1
-                        ; re-align to 32 bytes
-                        %assign stack_size_padded (stack_size_padded + 16)
-                    %endif
-                %endif
                 %if %1 < 0 ; need to store rsp on stack
                     sub  rsp, gprsize+stack_size_padded
                     and  rsp, ~(%%stack_alignment-1)
@@ -367,9 +362,7 @@ DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
                     %xdefine rstkm rstk
                 %endif
             %endif
-            %if xmm_regs_used > 6
-                WIN64_PUSH_XMM
-            %endif
+            WIN64_PUSH_XMM
         %endif
     %endif
 %endmacro
@@ -430,40 +423,55 @@ DECLARE_REG 14, R15, 120
 %endmacro
 
 %macro WIN64_PUSH_XMM 0
-    %assign %%i xmm_regs_used
-    %rep (xmm_regs_used-6)
-        %assign %%i %%i-1
-        movdqa [rsp + (%%i-6)*16 + stack_size + (~stack_offset&8)], xmm %+ %%i
-    %endrep
+    ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated.
+    %if xmm_regs_used > 6
+        movaps [rstk + stack_offset +  8], xmm6
+    %endif
+    %if xmm_regs_used > 7
+        movaps [rstk + stack_offset + 24], xmm7
+    %endif
+    %if xmm_regs_used > 8
+        %assign %%i 8
+        %rep xmm_regs_used-8
+            movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i
+            %assign %%i %%i+1
+        %endrep
+    %endif
 %endmacro
 
 %macro WIN64_SPILL_XMM 1
     %assign xmm_regs_used %1
     ASSERT xmm_regs_used <= 16
-    %if xmm_regs_used > 6
-        SUB rsp, (xmm_regs_used-6)*16+16
-        WIN64_PUSH_XMM
+    %if xmm_regs_used > 8
+        %assign stack_size_padded (xmm_regs_used-8)*16 + (~stack_offset&8) + 32
+        SUB rsp, stack_size_padded
     %endif
+    WIN64_PUSH_XMM
 %endmacro
 
 %macro WIN64_RESTORE_XMM_INTERNAL 1
-    %if xmm_regs_used > 6
+    %assign %%pad_size 0
+    %if xmm_regs_used > 8
         %assign %%i xmm_regs_used
-        %rep (xmm_regs_used-6)
+        %rep xmm_regs_used-8
             %assign %%i %%i-1
-            movdqa xmm %+ %%i, [%1 + (%%i-6)*16+stack_size+(~stack_offset&8)]
+            movaps xmm %+ %%i, [%1 + (%%i-8)*16 + stack_size + 32]
         %endrep
-        %if stack_size_padded == 0
-            add %1, (xmm_regs_used-6)*16+16
-        %endif
     %endif
     %if stack_size_padded > 0
         %if stack_size > 0 && (mmsize == 32 || HAVE_ALIGNED_STACK == 0)
             mov rsp, rstkm
         %else
             add %1, stack_size_padded
+            %assign %%pad_size stack_size_padded
         %endif
     %endif
+    %if xmm_regs_used > 7
+        movaps xmm7, [%1 + stack_offset - %%pad_size + 24]
+    %endif
+    %if xmm_regs_used > 6
+        movaps xmm6, [%1 + stack_offset - %%pad_size +  8]
+    %endif
 %endmacro
 
 %macro WIN64_RESTORE_XMM 1
@@ -480,7 +488,7 @@ DECLARE_REG 14, R15, 120
 %if mmsize == 32
     vzeroupper
 %endif
-    ret
+    AUTO_REP_RET
 %endmacro
 
 %elif ARCH_X86_64 ; *nix x64 ;=============================================
@@ -527,7 +535,7 @@ DECLARE_REG 14, R15, 72
 %if mmsize == 32
     vzeroupper
 %endif
-    ret
+    AUTO_REP_RET
 %endmacro
 
 %else ; X86_32 ;==============================================================
@@ -583,7 +591,7 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
 %if mmsize == 32
     vzeroupper
 %endif
-    ret
+    AUTO_REP_RET
 %endmacro
 
 %endif ;======================================================================
@@ -597,6 +605,10 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
 %endmacro
 %endif
 
+; On AMD cpus <=K10, an ordinary ret is slow if it immediately follows either
+; a branch or a branch target. So switch to a 2-byte form of ret in that case.
+; We can automatically detect "follows a branch", but not a branch target.
+; (SSSE3 is a sufficient condition to know that your cpu doesn't have this problem.)
 %macro REP_RET 0
     %if has_epilogue
         RET
@@ -605,6 +617,29 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
     %endif
 %endmacro
 
+%define last_branch_adr $$
+%macro AUTO_REP_RET 0
+    %ifndef cpuflags
+        times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ != last_branch_adr.
+    %elif notcpuflag(ssse3)
+        times ((last_branch_adr-$)>>31)+1 rep
+    %endif
+    ret
+%endmacro
+
+%macro BRANCH_INSTR 0-*
+    %rep %0
+        %macro %1 1-2 %1
+            %2 %1
+            %%branch_instr:
+            %xdefine last_branch_adr %%branch_instr
+        %endmacro
+        %rotate 1
+    %endrep
+%endmacro
+
+BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, jna, jnae, jb, jbe, jnb, jnbe, jc, jnc, js, jns, jo, jno, jp, jnp
+
 %macro TAIL_CALL 2 ; callee, is_nonadjacent
     %if has_epilogue
         call %1
@@ -624,38 +659,48 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
 ; Applies any symbol mangling needed for C linkage, and sets up a define such that
 ; subsequent uses of the function name automatically refer to the mangled version.
 ; Appends cpuflags to the function name if cpuflags has been specified.
+; The "" empty default parameter is a workaround for nasm, which fails if SUFFIX
+; is empty and we call cglobal_internal with just %1 %+ SUFFIX (without %2).
 %macro cglobal 1-2+ "" ; name, [PROLOGUE args]
-    ; the "" is a workaround for nasm, which fails if SUFFIX is empty
-    ; and we call cglobal_internal with just %1 %+ SUFFIX (without %2)
-    cglobal_internal %1 %+ SUFFIX, %2
-%endmacro
-%macro cglobal_internal 1-2+
-    %ifndef cglobaled_%1
-        %xdefine %1 mangle(program_name %+ _ %+ %1)
-        %xdefine %1.skip_prologue %1 %+ .skip_prologue
-        CAT_XDEFINE cglobaled_, %1, 1
+    cglobal_internal 1, %1 %+ SUFFIX, %2
+%endmacro
+%macro cvisible 1-2+ "" ; name, [PROLOGUE args]
+    cglobal_internal 0, %1 %+ SUFFIX, %2
+%endmacro
+%macro cglobal_internal 2-3+
+    %if %1
+        %xdefine %%FUNCTION_PREFIX private_prefix
+        %xdefine %%VISIBILITY hidden
+    %else
+        %xdefine %%FUNCTION_PREFIX public_prefix
+        %xdefine %%VISIBILITY
+    %endif
+    %ifndef cglobaled_%2
+        %xdefine %2 mangle(%%FUNCTION_PREFIX %+ _ %+ %2)
+        %xdefine %2.skip_prologue %2 %+ .skip_prologue
+        CAT_XDEFINE cglobaled_, %2, 1
     %endif
-    %xdefine current_function %1
+    %xdefine current_function %2
     %ifidn __OUTPUT_FORMAT__,elf
-        global %1:function hidden
+        global %2:function %%VISIBILITY
     %else
-        global %1
+        global %2
     %endif
     align function_align
-    %1:
-    RESET_MM_PERMUTATION ; not really needed, but makes disassembly somewhat nicer
-    %xdefine rstk rsp
-    %assign stack_offset 0
-    %assign stack_size 0
-    %assign stack_size_padded 0
-    %assign xmm_regs_used 0
-    %ifnidn %2, ""
-        PROLOGUE %2
+    %2:
+    RESET_MM_PERMUTATION        ; needed for x86-64, also makes disassembly somewhat nicer
+    %xdefine rstk rsp           ; copy of the original stack pointer, used when greater alignment than the known stack alignment is required
+    %assign stack_offset 0      ; stack pointer offset relative to the return address
+    %assign stack_size 0        ; amount of stack space that can be freely used inside a function
+    %assign stack_size_padded 0 ; total amount of allocated stack space, including space for callee-saved xmm registers on WIN64 and alignment padding
+    %assign xmm_regs_used 0     ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64
+    %ifnidn %3, ""
+        PROLOGUE %3
     %endif
 %endmacro
 
 %macro cextern 1
-    %xdefine %1 mangle(program_name %+ _ %+ %1)
+    %xdefine %1 mangle(private_prefix %+ _ %+ %1)
     CAT_XDEFINE cglobaled_, %1, 1
     extern %1
 %endmacro
@@ -667,9 +712,13 @@ DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14
     extern %1
 %endmacro
 
-%macro const 2+
-    %xdefine %1 mangle(program_name %+ _ %+ %1)
-    global %1
+%macro const 1-2+
+    %xdefine %1 mangle(private_prefix %+ _ %+ %1)
+    %ifidn __OUTPUT_FORMAT__,elf
+        global %1:data hidden
+    %else
+        global %1
+    %endif
     %1: %2
 %endmacro
 
@@ -702,12 +751,10 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
 %assign cpuflags_cache64  (1<<17)
 %assign cpuflags_slowctz  (1<<18)
 %assign cpuflags_lzcnt    (1<<19)
-%assign cpuflags_misalign (1<<20)
-%assign cpuflags_aligned  (1<<21) ; not a cpu feature, but a function variant
-%assign cpuflags_atom     (1<<22)
-%assign cpuflags_bmi1     (1<<23)
-%assign cpuflags_bmi2     (1<<24)|cpuflags_bmi1
-%assign cpuflags_tbm      (1<<25)|cpuflags_bmi1
+%assign cpuflags_aligned  (1<<20) ; not a cpu feature, but a function variant
+%assign cpuflags_atom     (1<<21)
+%assign cpuflags_bmi1     (1<<22)|cpuflags_lzcnt
+%assign cpuflags_bmi2     (1<<23)|cpuflags_bmi1
 
 %define    cpuflag(x) ((cpuflags & (cpuflags_ %+ x)) == (cpuflags_ %+ x))
 %define notcpuflag(x) ((cpuflags & (cpuflags_ %+ x)) != (cpuflags_ %+ x))
@@ -728,7 +775,7 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
         %if cpuflag(avx)
             %assign avx_enabled 1
         %endif
-        %if mmsize == 16 && notcpuflag(sse2)
+        %if (mmsize == 16 && notcpuflag(sse2)) || (mmsize == 32 && notcpuflag(avx2))
             %define mova movaps
             %define movu movups
             %define movnta movntps
@@ -738,7 +785,7 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
         %elifidn %1, sse3
             %define movu lddqu
         %endif
-        %if notcpuflag(mmx2)
+        %if notcpuflag(sse2)
             CPUNOP basicnop
         %endif
     %else
@@ -748,7 +795,11 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
     %endif
 %endmacro
 
-; merge mmx and sse*
+; Merge mmx and sse*
+; m# is a simd regsiter of the currently selected size
+; xm# is the corresponding xmmreg (if selcted xmm or ymm size), or mmreg (if selected mmx)
+; ym# is the corresponding ymmreg (if selcted xmm or ymm size), or mmreg (if selected mmx)
+; (All 3 remain in sync through SWAP.)
 
 %macro CAT_XDEFINE 3
     %xdefine %1%2 %3
@@ -810,10 +861,10 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
     %if ARCH_X86_64
     %define num_mmregs 16
     %endif
-    %define mova vmovaps
-    %define movu vmovups
+    %define mova movdqa
+    %define movu movdqu
     %undef movh
-    %define movnta vmovntps
+    %define movnta movntdq
     %assign %%i 0
     %rep num_mmregs
     CAT_XDEFINE m, %%i, ymm %+ %%i
@@ -825,6 +876,26 @@ SECTION .note.GNU-stack noalloc noexec nowrite progbits
 
 INIT_XMM
 
+%macro DECLARE_MMCAST 1
+    %define  mmmm%1   mm%1
+    %define  mmxmm%1  mm%1
+    %define  mmymm%1  mm%1
+    %define xmmmm%1   mm%1
+    %define xmmxmm%1 xmm%1
+    %define xmmymm%1 xmm%1
+    %define ymmmm%1   mm%1
+    %define ymmxmm%1 ymm%1
+    %define ymmymm%1 ymm%1
+    %define xm%1 xmm %+ m%1
+    %define ym%1 ymm %+ m%1
+%endmacro
+
+%assign i 0
+%rep 16
+    DECLARE_MMCAST i
+%assign i i+1
+%endrep
+
 ; I often want to use macros that permute their arguments. e.g. there's no
 ; efficient way to implement butterfly or transpose or dct without swapping some
 ; arguments.
@@ -841,42 +912,42 @@ INIT_XMM
 
 %macro PERMUTE 2-* ; takes a list of pairs to swap
 %rep %0/2
-    %xdefine tmp%2 m%2
-    %xdefine ntmp%2 nm%2
+    %xdefine %%tmp%2 m%2
     %rotate 2
 %endrep
 %rep %0/2
-    %xdefine m%1 tmp%2
-    %xdefine nm%1 ntmp%2
-    %undef tmp%2
-    %undef ntmp%2
+    %xdefine m%1 %%tmp%2
+    CAT_XDEFINE n, m%1, %1
     %rotate 2
 %endrep
 %endmacro
 
-%macro SWAP 2-* ; swaps a single chain (sometimes more concise than pairs)
-%rep %0-1
-%ifdef m%1
-    %xdefine tmp m%1
-    %xdefine m%1 m%2
-    %xdefine m%2 tmp
-    CAT_XDEFINE n, m%1, %1
-    CAT_XDEFINE n, m%2, %2
-%else
-    ; If we were called as "SWAP m0,m1" rather than "SWAP 0,1" infer the original numbers here.
-    ; Be careful using this mode in nested macros though, as in some cases there may be
-    ; other copies of m# that have already been dereferenced and don't get updated correctly.
-    %xdefine %%n1 n %+ %1
-    %xdefine %%n2 n %+ %2
-    %xdefine tmp m %+ %%n1
-    CAT_XDEFINE m, %%n1, m %+ %%n2
-    CAT_XDEFINE m, %%n2, tmp
-    CAT_XDEFINE n, m %+ %%n1, %%n1
-    CAT_XDEFINE n, m %+ %%n2, %%n2
+%macro SWAP 2+ ; swaps a single chain (sometimes more concise than pairs)
+%ifnum %1 ; SWAP 0, 1, ...
+    SWAP_INTERNAL_NUM %1, %2
+%else ; SWAP m0, m1, ...
+    SWAP_INTERNAL_NAME %1, %2
 %endif
-    %undef tmp
+%endmacro
+
+%macro SWAP_INTERNAL_NUM 2-*
+    %rep %0-1
+        %xdefine %%tmp m%1
+        %xdefine m%1 m%2
+        %xdefine m%2 %%tmp
+        CAT_XDEFINE n, m%1, %1
+        CAT_XDEFINE n, m%2, %2
     %rotate 1
-%endrep
+    %endrep
+%endmacro
+
+%macro SWAP_INTERNAL_NAME 2-*
+    %xdefine %%args n %+ %1
+    %rep %0-1
+        %xdefine %%args %%args, n %+ %2
+    %rotate 1
+    %endrep
+    SWAP_INTERNAL_NUM %%args
 %endmacro
 
 ; If SAVE_MM_PERMUTATION is placed at the end of a function, then any later
@@ -974,122 +1045,148 @@ INIT_XMM
 
 ;%1 == instruction
 ;%2 == 1 if float, 0 if int
-;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 2- or 3-operand (xmm, xmm, xmm)
-;%4 == number of operands given
+;%3 == 1 if non-destructive or 4-operand (xmm, xmm, xmm, imm), 0 otherwise
+;%4 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not
 ;%5+: operands
-%macro RUN_AVX_INSTR 6-7+
-    %ifid %6
-        %define %%sizeofreg sizeof%6
-    %elifid %5
-        %define %%sizeofreg sizeof%5
+%macro RUN_AVX_INSTR 5-8+
+    %ifnum sizeof%6
+        %assign %%sizeofreg sizeof%6
+    %elifnum sizeof%5
+        %assign %%sizeofreg sizeof%5
     %else
-        %define %%sizeofreg mmsize
+        %assign %%sizeofreg mmsize
     %endif
-    %if %%sizeofreg==32
-        %if %4>=3
-            v%1 %5, %6, %7
-        %else
-            v%1 %5, %6
-        %endif
+    %assign %%emulate_avx 0
+    %if avx_enabled && %%sizeofreg >= 16
+        %xdefine %%instr v%1
     %else
-        %if %%sizeofreg==8
-            %define %%regmov movq
-        %elif %2
-            %define %%regmov movaps
-        %else
-            %define %%regmov movdqa
+        %xdefine %%instr %1
+        %if %0 >= 7+%3
+            %assign %%emulate_avx 1
         %endif
+    %endif
 
-        %if %4>=3+%3
-            %ifnidn %5, %6
-                %if avx_enabled && %%sizeofreg==16
-                    v%1 %5, %6, %7
-                %else
-                    CHECK_AVX_INSTR_EMU {%1 %5, %6, %7}, %5, %7
-                    %%regmov %5, %6
-                    %1 %5, %7
+    %if %%emulate_avx
+        %xdefine %%src1 %6
+        %xdefine %%src2 %7
+        %ifnidn %5, %6
+            %if %0 >= 8
+                CHECK_AVX_INSTR_EMU {%1 %5, %6, %7, %8}, %5, %7, %8
+            %else
+                CHECK_AVX_INSTR_EMU {%1 %5, %6, %7}, %5, %7
+            %endif
+            %if %4 && %3 == 0
+                %ifnid %7
+                    ; 3-operand AVX instructions with a memory arg can only have it in src2,
+                    ; whereas SSE emulation prefers to have it in src1 (i.e. the mov).
+                    ; So, if the instruction is commutative with a memory arg, swap them.
+                    %xdefine %%src1 %7
+                    %xdefine %%src2 %6
                 %endif
+            %endif
+            %if %%sizeofreg == 8
+                MOVQ %5, %%src1
+            %elif %2
+                MOVAPS %5, %%src1
             %else
-                %1 %5, %7
+                MOVDQA %5, %%src1
             %endif
-        %elif %4>=3
-            %1 %5, %6, %7
-        %else
-            %1 %5, %6
-        %endif
-    %endif
-%endmacro
-
-; 3arg AVX ops with a memory arg can only have it in src2,
-; whereas SSE emulation of 3arg prefers to have it in src1 (i.e. the mov).
-; So, if the op is symmetric and the wrong one is memory, swap them.
-%macro RUN_AVX_INSTR1 8
-    %assign %%swap 0
-    %if avx_enabled
-        %ifnid %6
-            %assign %%swap 1
         %endif
-    %elifnidn %5, %6
-        %ifnid %7
-            %assign %%swap 1
+        %if %0 >= 8
+            %1 %5, %%src2, %8
+        %else
+            %1 %5, %%src2
         %endif
-    %endif
-    %if %%swap && %3 == 0 && %8 == 1
-        RUN_AVX_INSTR %1, %2, %3, %4, %5, %7, %6
+    %elif %0 >= 8
+        %%instr %5, %6, %7, %8
+    %elif %0 == 7
+        %%instr %5, %6, %7
+    %elif %0 == 6
+        %%instr %5, %6
     %else
-        RUN_AVX_INSTR %1, %2, %3, %4, %5, %6, %7
+        %%instr %5
     %endif
 %endmacro
 
 ;%1 == instruction
 ;%2 == 1 if float, 0 if int
-;%3 == 1 if 4-operand (xmm, xmm, xmm, imm), 0 if 2- or 3-operand (xmm, xmm, xmm)
-;%4 == 1 if symmetric (i.e. doesn't matter which src arg is which), 0 if not
-%macro AVX_INSTR 4
-    %macro %1 2-9 fnord, fnord, fnord, %1, %2, %3, %4
-        %ifidn %3, fnord
-            RUN_AVX_INSTR %6, %7, %8, 2, %1, %2
+;%3 == 1 if non-destructive or 4-operand (xmm, xmm, xmm, imm), 0 otherwise
+;%4 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not
+%macro AVX_INSTR 1-4 0, 1, 0
+    %macro %1 1-9 fnord, fnord, fnord, fnord, %1, %2, %3, %4
+        %ifidn %2, fnord
+            RUN_AVX_INSTR %6, %7, %8, %9, %1
+        %elifidn %3, fnord
+            RUN_AVX_INSTR %6, %7, %8, %9, %1, %2
         %elifidn %4, fnord
-            RUN_AVX_INSTR1 %6, %7, %8, 3, %1, %2, %3, %9
+            RUN_AVX_INSTR %6, %7, %8, %9, %1, %2, %3
         %elifidn %5, fnord
-            RUN_AVX_INSTR %6, %7, %8, 4, %1, %2, %3, %4
+            RUN_AVX_INSTR %6, %7, %8, %9, %1, %2, %3, %4
         %else
-            RUN_AVX_INSTR %6, %7, %8, 5, %1, %2, %3, %4, %5
+            RUN_AVX_INSTR %6, %7, %8, %9, %1, %2, %3, %4, %5
         %endif
     %endmacro
 %endmacro
 
+; Instructions with both VEX and non-VEX encodings
+; Non-destructive instructions are written without parameters
 AVX_INSTR addpd, 1, 0, 1
 AVX_INSTR addps, 1, 0, 1
 AVX_INSTR addsd, 1, 0, 1
 AVX_INSTR addss, 1, 0, 1
 AVX_INSTR addsubpd, 1, 0, 0
 AVX_INSTR addsubps, 1, 0, 0
-AVX_INSTR andpd, 1, 0, 1
-AVX_INSTR andps, 1, 0, 1
+AVX_INSTR aesdec, 0, 0, 0
+AVX_INSTR aesdeclast, 0, 0, 0
+AVX_INSTR aesenc, 0, 0, 0
+AVX_INSTR aesenclast, 0, 0, 0
+AVX_INSTR aesimc
+AVX_INSTR aeskeygenassist
 AVX_INSTR andnpd, 1, 0, 0
 AVX_INSTR andnps, 1, 0, 0
+AVX_INSTR andpd, 1, 0, 1
+AVX_INSTR andps, 1, 0, 1
 AVX_INSTR blendpd, 1, 0, 0
 AVX_INSTR blendps, 1, 0, 0
 AVX_INSTR blendvpd, 1, 0, 0
 AVX_INSTR blendvps, 1, 0, 0
-AVX_INSTR cmppd, 1, 0, 0
-AVX_INSTR cmpps, 1, 0, 0
-AVX_INSTR cmpsd, 1, 0, 0
-AVX_INSTR cmpss, 1, 0, 0
-AVX_INSTR cvtdq2ps, 1, 0, 0
-AVX_INSTR cvtpd2dq, 1, 0, 0
-AVX_INSTR cvtps2dq, 1, 0, 0
+AVX_INSTR cmppd, 1, 1, 0
+AVX_INSTR cmpps, 1, 1, 0
+AVX_INSTR cmpsd, 1, 1, 0
+AVX_INSTR cmpss, 1, 1, 0
+AVX_INSTR comisd
+AVX_INSTR comiss
+AVX_INSTR cvtdq2pd
+AVX_INSTR cvtdq2ps
+AVX_INSTR cvtpd2dq
+AVX_INSTR cvtpd2ps
+AVX_INSTR cvtps2dq
+AVX_INSTR cvtps2pd
+AVX_INSTR cvtsd2si
+AVX_INSTR cvtsd2ss
+AVX_INSTR cvtsi2sd
+AVX_INSTR cvtsi2ss
+AVX_INSTR cvtss2sd
+AVX_INSTR cvtss2si
+AVX_INSTR cvttpd2dq
+AVX_INSTR cvttps2dq
+AVX_INSTR cvttsd2si
+AVX_INSTR cvttss2si
 AVX_INSTR divpd, 1, 0, 0
 AVX_INSTR divps, 1, 0, 0
 AVX_INSTR divsd, 1, 0, 0
 AVX_INSTR divss, 1, 0, 0
 AVX_INSTR dppd, 1, 1, 0
 AVX_INSTR dpps, 1, 1, 0
+AVX_INSTR extractps
 AVX_INSTR haddpd, 1, 0, 0
 AVX_INSTR haddps, 1, 0, 0
 AVX_INSTR hsubpd, 1, 0, 0
 AVX_INSTR hsubps, 1, 0, 0
+AVX_INSTR insertps, 1, 1, 0
+AVX_INSTR lddqu
+AVX_INSTR ldmxcsr
+AVX_INSTR maskmovdqu
 AVX_INSTR maxpd, 1, 0, 1
 AVX_INSTR maxps, 1, 0, 1
 AVX_INSTR maxsd, 1, 0, 1
@@ -1098,10 +1195,31 @@ AVX_INSTR minpd, 1, 0, 1
 AVX_INSTR minps, 1, 0, 1
 AVX_INSTR minsd, 1, 0, 1
 AVX_INSTR minss, 1, 0, 1
+AVX_INSTR movapd
+AVX_INSTR movaps
+AVX_INSTR movd
+AVX_INSTR movddup
+AVX_INSTR movdqa
+AVX_INSTR movdqu
 AVX_INSTR movhlps, 1, 0, 0
+AVX_INSTR movhpd, 1, 0, 0
+AVX_INSTR movhps, 1, 0, 0
 AVX_INSTR movlhps, 1, 0, 0
+AVX_INSTR movlpd, 1, 0, 0
+AVX_INSTR movlps, 1, 0, 0
+AVX_INSTR movmskpd
+AVX_INSTR movmskps
+AVX_INSTR movntdq
+AVX_INSTR movntdqa
+AVX_INSTR movntpd
+AVX_INSTR movntps
+AVX_INSTR movq
 AVX_INSTR movsd, 1, 0, 0
+AVX_INSTR movshdup
+AVX_INSTR movsldup
 AVX_INSTR movss, 1, 0, 0
+AVX_INSTR movupd
+AVX_INSTR movups
 AVX_INSTR mpsadbw, 0, 1, 0
 AVX_INSTR mulpd, 1, 0, 1
 AVX_INSTR mulps, 1, 0, 1
@@ -1109,9 +1227,9 @@ AVX_INSTR mulsd, 1, 0, 1
 AVX_INSTR mulss, 1, 0, 1
 AVX_INSTR orpd, 1, 0, 1
 AVX_INSTR orps, 1, 0, 1
-AVX_INSTR pabsb, 0, 0, 0
-AVX_INSTR pabsw, 0, 0, 0
-AVX_INSTR pabsd, 0, 0, 0
+AVX_INSTR pabsb
+AVX_INSTR pabsd
+AVX_INSTR pabsw
 AVX_INSTR packsswb, 0, 0, 0
 AVX_INSTR packssdw, 0, 0, 0
 AVX_INSTR packuswb, 0, 0, 0
@@ -1131,10 +1249,11 @@ AVX_INSTR pavgb, 0, 0, 1
 AVX_INSTR pavgw, 0, 0, 1
 AVX_INSTR pblendvb, 0, 0, 0
 AVX_INSTR pblendw, 0, 1, 0
-AVX_INSTR pcmpestri, 0, 0, 0
-AVX_INSTR pcmpestrm, 0, 0, 0
-AVX_INSTR pcmpistri, 0, 0, 0
-AVX_INSTR pcmpistrm, 0, 0, 0
+AVX_INSTR pclmulqdq, 0, 1, 0
+AVX_INSTR pcmpestri
+AVX_INSTR pcmpestrm
+AVX_INSTR pcmpistri
+AVX_INSTR pcmpistrm
 AVX_INSTR pcmpeqb, 0, 0, 1
 AVX_INSTR pcmpeqw, 0, 0, 1
 AVX_INSTR pcmpeqd, 0, 0, 1
@@ -1143,12 +1262,21 @@ AVX_INSTR pcmpgtb, 0, 0, 0
 AVX_INSTR pcmpgtw, 0, 0, 0
 AVX_INSTR pcmpgtd, 0, 0, 0
 AVX_INSTR pcmpgtq, 0, 0, 0
+AVX_INSTR pextrb
+AVX_INSTR pextrd
+AVX_INSTR pextrq
+AVX_INSTR pextrw
 AVX_INSTR phaddw, 0, 0, 0
 AVX_INSTR phaddd, 0, 0, 0
 AVX_INSTR phaddsw, 0, 0, 0
+AVX_INSTR phminposuw
 AVX_INSTR phsubw, 0, 0, 0
 AVX_INSTR phsubd, 0, 0, 0
 AVX_INSTR phsubsw, 0, 0, 0
+AVX_INSTR pinsrb, 0, 1, 0
+AVX_INSTR pinsrd, 0, 1, 0
+AVX_INSTR pinsrq, 0, 1, 0
+AVX_INSTR pinsrw, 0, 1, 0
 AVX_INSTR pmaddwd, 0, 0, 1
 AVX_INSTR pmaddubsw, 0, 0, 0
 AVX_INSTR pmaxsb, 0, 0, 1
@@ -1163,20 +1291,32 @@ AVX_INSTR pminsd, 0, 0, 1
 AVX_INSTR pminub, 0, 0, 1
 AVX_INSTR pminuw, 0, 0, 1
 AVX_INSTR pminud, 0, 0, 1
-AVX_INSTR pmovmskb, 0, 0, 0
-AVX_INSTR pmulhuw, 0, 0, 1
+AVX_INSTR pmovmskb
+AVX_INSTR pmovsxbw
+AVX_INSTR pmovsxbd
+AVX_INSTR pmovsxbq
+AVX_INSTR pmovsxwd
+AVX_INSTR pmovsxwq
+AVX_INSTR pmovsxdq
+AVX_INSTR pmovzxbw
+AVX_INSTR pmovzxbd
+AVX_INSTR pmovzxbq
+AVX_INSTR pmovzxwd
+AVX_INSTR pmovzxwq
+AVX_INSTR pmovzxdq
+AVX_INSTR pmuldq, 0, 0, 1
 AVX_INSTR pmulhrsw, 0, 0, 1
+AVX_INSTR pmulhuw, 0, 0, 1
 AVX_INSTR pmulhw, 0, 0, 1
 AVX_INSTR pmullw, 0, 0, 1
 AVX_INSTR pmulld, 0, 0, 1
 AVX_INSTR pmuludq, 0, 0, 1
-AVX_INSTR pmuldq, 0, 0, 1
 AVX_INSTR por, 0, 0, 1
 AVX_INSTR psadbw, 0, 0, 1
 AVX_INSTR pshufb, 0, 0, 0
-AVX_INSTR pshufd, 0, 1, 0
-AVX_INSTR pshufhw, 0, 1, 0
-AVX_INSTR pshuflw, 0, 1, 0
+AVX_INSTR pshufd
+AVX_INSTR pshufhw
+AVX_INSTR pshuflw
 AVX_INSTR psignb, 0, 0, 0
 AVX_INSTR psignw, 0, 0, 0
 AVX_INSTR psignd, 0, 0, 0
@@ -1198,7 +1338,7 @@ AVX_INSTR psubsb, 0, 0, 0
 AVX_INSTR psubsw, 0, 0, 0
 AVX_INSTR psubusb, 0, 0, 0
 AVX_INSTR psubusw, 0, 0, 0
-AVX_INSTR ptest, 0, 0, 0
+AVX_INSTR ptest
 AVX_INSTR punpckhbw, 0, 0, 0
 AVX_INSTR punpckhwd, 0, 0, 0
 AVX_INSTR punpckhdq, 0, 0, 0
@@ -1208,11 +1348,27 @@ AVX_INSTR punpcklwd, 0, 0, 0
 AVX_INSTR punpckldq, 0, 0, 0
 AVX_INSTR punpcklqdq, 0, 0, 0
 AVX_INSTR pxor, 0, 0, 1
+AVX_INSTR rcpps, 1, 0, 0
+AVX_INSTR rcpss, 1, 0, 0
+AVX_INSTR roundpd
+AVX_INSTR roundps
+AVX_INSTR roundsd
+AVX_INSTR roundss
+AVX_INSTR rsqrtps, 1, 0, 0
+AVX_INSTR rsqrtss, 1, 0, 0
+AVX_INSTR shufpd, 1, 1, 0
 AVX_INSTR shufps, 1, 1, 0
+AVX_INSTR sqrtpd, 1, 0, 0
+AVX_INSTR sqrtps, 1, 0, 0
+AVX_INSTR sqrtsd, 1, 0, 0
+AVX_INSTR sqrtss, 1, 0, 0
+AVX_INSTR stmxcsr
 AVX_INSTR subpd, 1, 0, 0
 AVX_INSTR subps, 1, 0, 0
 AVX_INSTR subsd, 1, 0, 0
 AVX_INSTR subss, 1, 0, 0
+AVX_INSTR ucomisd
+AVX_INSTR ucomiss
 AVX_INSTR unpckhpd, 1, 0, 0
 AVX_INSTR unpckhps, 1, 0, 0
 AVX_INSTR unpcklpd, 1, 0, 0
@@ -1244,22 +1400,16 @@ AVX_INSTR pfmul, 1, 0, 1
 %undef j
 
 %macro FMA_INSTR 3
-    %macro %1 5-8 %1, %2, %3
-        %if cpuflag(xop) || cpuflag(fma4)
-            v%6 %1, %2, %3, %4
+    %macro %1 4-7 %1, %2, %3
+        %if cpuflag(xop)
+            v%5 %1, %2, %3, %4
         %else
-            %ifidn %1, %4
-                %7 %5, %2, %3
-                %8 %1, %4, %5
-            %else
-                %7 %1, %2, %3
-                %8 %1, %4
-            %endif
+            %6 %1, %2, %3
+            %7 %1, %4
         %endif
     %endmacro
 %endmacro
 
-FMA_INSTR  fmaddps,   mulps, addps
 FMA_INSTR  pmacsdd,  pmulld, paddd
 FMA_INSTR  pmacsww,  pmullw, paddw
 FMA_INSTR pmadcswd, pmaddwd, paddd
@@ -1267,3 +1417,56 @@ FMA_INSTR pmadcswd, pmaddwd, paddd
 ; tzcnt is equivalent to "rep bsf" and is backwards-compatible with bsf.
 ; This lets us use tzcnt without bumping the yasm version requirement yet.
 %define tzcnt rep bsf
+
+; convert FMA4 to FMA3 if possible
+%macro FMA4_INSTR 4
+    %macro %1 4-8 %1, %2, %3, %4
+        %if cpuflag(fma4)
+            v%5 %1, %2, %3, %4
+        %elifidn %1, %2
+            v%6 %1, %4, %3 ; %1 = %1 * %3 + %4
+        %elifidn %1, %3
+            v%7 %1, %2, %4 ; %1 = %2 * %1 + %4
+        %elifidn %1, %4
+            v%8 %1, %2, %3 ; %1 = %2 * %3 + %1
+        %else
+            %error fma3 emulation of ``%5 %1, %2, %3, %4'' is not supported
+        %endif
+    %endmacro
+%endmacro
+
+FMA4_INSTR fmaddpd, fmadd132pd, fmadd213pd, fmadd231pd
+FMA4_INSTR fmaddps, fmadd132ps, fmadd213ps, fmadd231ps
+FMA4_INSTR fmaddsd, fmadd132sd, fmadd213sd, fmadd231sd
+FMA4_INSTR fmaddss, fmadd132ss, fmadd213ss, fmadd231ss
+
+FMA4_INSTR fmaddsubpd, fmaddsub132pd, fmaddsub213pd, fmaddsub231pd
+FMA4_INSTR fmaddsubps, fmaddsub132ps, fmaddsub213ps, fmaddsub231ps
+FMA4_INSTR fmsubaddpd, fmsubadd132pd, fmsubadd213pd, fmsubadd231pd
+FMA4_INSTR fmsubaddps, fmsubadd132ps, fmsubadd213ps, fmsubadd231ps
+
+FMA4_INSTR fmsubpd, fmsub132pd, fmsub213pd, fmsub231pd
+FMA4_INSTR fmsubps, fmsub132ps, fmsub213ps, fmsub231ps
+FMA4_INSTR fmsubsd, fmsub132sd, fmsub213sd, fmsub231sd
+FMA4_INSTR fmsubss, fmsub132ss, fmsub213ss, fmsub231ss
+
+FMA4_INSTR fnmaddpd, fnmadd132pd, fnmadd213pd, fnmadd231pd
+FMA4_INSTR fnmaddps, fnmadd132ps, fnmadd213ps, fnmadd231ps
+FMA4_INSTR fnmaddsd, fnmadd132sd, fnmadd213sd, fnmadd231sd
+FMA4_INSTR fnmaddss, fnmadd132ss, fnmadd213ss, fnmadd231ss
+
+FMA4_INSTR fnmsubpd, fnmsub132pd, fnmsub213pd, fnmsub231pd
+FMA4_INSTR fnmsubps, fnmsub132ps, fnmsub213ps, fnmsub231ps
+FMA4_INSTR fnmsubsd, fnmsub132sd, fnmsub213sd, fnmsub231sd
+FMA4_INSTR fnmsubss, fnmsub132ss, fnmsub213ss, fnmsub231ss
+
+; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug
+%if ARCH_X86_64 == 0
+%macro vpbroadcastq 2
+%if sizeof%1 == 16
+    movddup %1, %2
+%else
+    vbroadcastsd %1, %2
+%endif
+%endmacro
+%endif
diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm
index 16ee6cf..11779cf 100644
--- a/libavutil/x86/x86util.asm
+++ b/libavutil/x86/x86util.asm
@@ -23,7 +23,8 @@
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%define program_name ff
+%define private_prefix ff
+%define public_prefix  avpriv
 %define cpuflags_mmxext cpuflags_mmx2
 
 %include "libavutil/x86/x86inc.asm"
@@ -172,14 +173,33 @@
     psignw     %1, %2
 %endmacro
 
-%macro ABS1_MMX 2    ; a, tmp
+%macro ABS1 2
+%if cpuflag(ssse3)
+    pabsw   %1, %1
+%elif cpuflag(mmxext) ; a, tmp
+    pxor    %2, %2
+    psubw   %2, %1
+    pmaxsw  %1, %2
+%else ; a, tmp
     pxor       %2, %2
     pcmpgtw    %2, %1
     pxor       %1, %2
     psubw      %1, %2
+%endif
 %endmacro
 
-%macro ABS2_MMX 4    ; a, b, tmp0, tmp1
+%macro ABS2 4
+%if cpuflag(ssse3)
+    pabsw   %1, %1
+    pabsw   %2, %2
+%elif cpuflag(mmxext) ; a, b, tmp0, tmp1
+    pxor    %3, %3
+    pxor    %4, %4
+    psubw   %3, %1
+    psubw   %4, %2
+    pmaxsw  %1, %3
+    pmaxsw  %2, %4
+%else ; a, b, tmp0, tmp1
     pxor       %3, %3
     pxor       %4, %4
     pcmpgtw    %3, %1
@@ -188,45 +208,31 @@
     pxor       %2, %4
     psubw      %1, %3
     psubw      %2, %4
+%endif
 %endmacro
 
-%macro ABS1_MMXEXT 2 ; a, tmp
-    pxor    %2, %2
-    psubw   %2, %1
-    pmaxsw  %1, %2
-%endmacro
-
-%macro ABS2_MMXEXT 4 ; a, b, tmp0, tmp1
-    pxor    %3, %3
-    pxor    %4, %4
-    psubw   %3, %1
-    psubw   %4, %2
-    pmaxsw  %1, %3
-    pmaxsw  %2, %4
-%endmacro
-
-%macro ABS1_SSSE3 2
-    pabsw   %1, %1
-%endmacro
-
-%macro ABS2_SSSE3 4
-    pabsw   %1, %1
-    pabsw   %2, %2
-%endmacro
-
-%macro ABSB_MMX 2
+%macro ABSB 2 ; source mmreg, temp mmreg (unused for ssse3)
+%if cpuflag(ssse3)
+    pabsb   %1, %1
+%else
     pxor    %2, %2
     psubb   %2, %1
     pminub  %1, %2
+%endif
 %endmacro
 
-%macro ABSB2_MMX 4
+%macro ABSB2 4 ; src1, src2, tmp1, tmp2 (tmp1/2 unused for SSSE3)
+%if cpuflag(ssse3)
+    pabsb   %1, %1
+    pabsb   %2, %2
+%else
     pxor    %3, %3
     pxor    %4, %4
     psubb   %3, %1
     psubb   %4, %2
     pminub  %1, %3
     pminub  %2, %4
+%endif
 %endmacro
 
 %macro ABSD2_MMX 4
@@ -240,25 +246,11 @@
     psubd   %2, %4
 %endmacro
 
-%macro ABSB_SSSE3 2
-    pabsb   %1, %1
-%endmacro
-
-%macro ABSB2_SSSE3 4
-    pabsb   %1, %1
-    pabsb   %2, %2
-%endmacro
-
 %macro ABS4 6
     ABS2 %1, %2, %5, %6
     ABS2 %3, %4, %5, %6
 %endmacro
 
-%define ABS1 ABS1_MMX
-%define ABS2 ABS2_MMX
-%define ABSB ABSB_MMX
-%define ABSB2 ABSB2_MMX
-
 %macro SPLATB_LOAD 3
 %if cpuflag(ssse3)
     movd      %1, [%2-3]
@@ -310,6 +302,14 @@
 %endif
 %endmacro
 
+%macro PAVGB 2
+%if cpuflag(mmxext)
+    pavgb   %1, %2
+%elif cpuflag(3dnow)
+    pavgusb %1, %2
+%endif
+%endmacro
+
 %macro PSHUFLW 1+
     %if mmsize == 8
         pshufw %1
@@ -665,3 +665,16 @@
     psrad        %1, 16
 %endif
 %endmacro
+
+; Wrapper for non-FMA version of fmaddps
+%macro FMULADD_PS 5
+    %if cpuflag(fma3) || cpuflag(fma4)
+        fmaddps %1, %2, %3, %4
+    %elifidn %1, %4
+        mulps   %5, %2, %3
+        addps   %1, %4, %5
+    %else
+        mulps   %1, %2, %3
+        addps   %1, %4
+    %endif
+%endmacro
diff --git a/libavutil/xtea.c b/libavutil/xtea.c
index 1187662..d1efebf 100644
--- a/libavutil/xtea.c
+++ b/libavutil/xtea.c
@@ -21,10 +21,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/intreadwrite.h"
-
 #include "avutil.h"
 #include "common.h"
+#include "intreadwrite.h"
 #include "xtea.h"
 
 void av_xtea_init(AVXTEA *ctx, const uint8_t key[16])
diff --git a/library.mak b/library.mak
index 3b4bd2d..3876fe3 100644
--- a/library.mak
+++ b/library.mak
@@ -1,9 +1,8 @@
-SRC_DIR := $(SRC_PATH)/lib$(NAME)
-
 include $(SRC_PATH)/common.mak
 
 LIBVERSION := $(lib$(NAME)_VERSION)
 LIBMAJOR   := $(lib$(NAME)_VERSION_MAJOR)
+LIBMINOR   := $(lib$(NAME)_VERSION_MINOR)
 INCINSTDIR := $(INCDIR)/lib$(NAME)
 
 INSTHEADERS := $(INSTHEADERS) $(HEADERS:%=$(SUBDIR)%)
@@ -26,6 +25,7 @@ $(SUBDIR)%-test.i: $(SUBDIR)%.c
 $(SUBDIR)x86/%.o: $(SUBDIR)x86/%.asm
 	$(DEPYASM) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d)
 	$(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $<
+	-$(STRIP) $(STRIPFLAGS) $@
 
 LIBOBJS := $(OBJS) $(SUBDIR)%.h.o $(TESTOBJS)
 $(LIBOBJS) $(LIBOBJS:.o=.i):   CPPFLAGS += -DHAVE_AV_CONFIG_H
diff --git a/libswscale/bfin/swscale_bfin.c b/libswscale/bfin/swscale_bfin.c
index 9d0bbe3..43c23b4 100644
--- a/libswscale/bfin/swscale_bfin.c
+++ b/libswscale/bfin/swscale_bfin.c
@@ -23,6 +23,7 @@
 #include <stdint.h>
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libswscale/swscale_internal.h"
 
 #if defined (__FDPIC__) && CONFIG_SRAM
@@ -71,16 +72,16 @@ static int yuyvtoyv12_unscaled(SwsContext *c, const uint8_t *src[],
     return srcSliceH;
 }
 
-void ff_bfin_get_unscaled_swscale(SwsContext *c)
+av_cold void ff_get_unscaled_swscale_bfin(SwsContext *c)
 {
     if (c->dstFormat == AV_PIX_FMT_YUV420P && c->srcFormat == AV_PIX_FMT_UYVY422) {
         av_log(NULL, AV_LOG_VERBOSE,
                "selecting Blackfin optimized uyvytoyv12_unscaled\n");
-        c->swScale = uyvytoyv12_unscaled;
+        c->swscale = uyvytoyv12_unscaled;
     }
     if (c->dstFormat == AV_PIX_FMT_YUV420P && c->srcFormat == AV_PIX_FMT_YUYV422) {
         av_log(NULL, AV_LOG_VERBOSE,
                "selecting Blackfin optimized yuyvtoyv12_unscaled\n");
-        c->swScale = yuyvtoyv12_unscaled;
+        c->swscale = yuyvtoyv12_unscaled;
     }
 }
diff --git a/libswscale/bfin/yuv2rgb_bfin.c b/libswscale/bfin/yuv2rgb_bfin.c
index 5b74c7a..603a33a 100644
--- a/libswscale/bfin/yuv2rgb_bfin.c
+++ b/libswscale/bfin/yuv2rgb_bfin.c
@@ -24,6 +24,7 @@
 #include <stdint.h>
 
 #include "config.h"
+#include "libavutil/attributes.h"
 #include "libswscale/swscale_internal.h"
 
 #if defined(__FDPIC__) && CONFIG_SRAM
@@ -167,7 +168,7 @@ static int bfin_yuv420_bgr565(SwsContext *c, const uint8_t **in, int *instrides,
                            outstrides, ff_bfin_yuv2rgb565_line, 0, 565);
 }
 
-SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c)
+av_cold SwsFunc ff_yuv2rgb_init_bfin(SwsContext *c)
 {
     SwsFunc f;
 
diff --git a/libswscale/options.c b/libswscale/options.c
index daf013c..e7765d6 100644
--- a/libswscale/options.c
+++ b/libswscale/options.c
@@ -33,7 +33,7 @@ static const char *sws_context_to_name(void *ptr)
 #define DEFAULT 0
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 
-static const AVOption options[] = {
+static const AVOption swscale_options[] = {
     { "sws_flags",       "scaler flags",                  OFFSET(flags),     AV_OPT_TYPE_FLAGS,  { .i64 = DEFAULT            }, 0,       UINT_MAX,       VE, "sws_flags" },
     { "fast_bilinear",   "fast bilinear",                 0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_FAST_BILINEAR  }, INT_MIN, INT_MAX,        VE, "sws_flags" },
     { "bilinear",        "bilinear",                      0,                 AV_OPT_TYPE_CONST,  { .i64  = SWS_BILINEAR       }, INT_MIN, INT_MAX,        VE, "sws_flags" },
@@ -66,7 +66,7 @@ static const AVOption options[] = {
     { NULL }
 };
 
-const AVClass sws_context_class = { "SWScaler", sws_context_to_name, options };
+const AVClass sws_context_class = { "SWScaler", sws_context_to_name, swscale_options };
 
 const AVClass *sws_get_class(void)
 {
diff --git a/libswscale/output.c b/libswscale/output.c
index 4953290..e1d01b0 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -46,14 +46,14 @@ DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
 {  0,   4,   0,   4,   0,   4,   0,   4, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_4x4_16)[4][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, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_32)[8][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, },
@@ -64,7 +64,7 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
 {  1,  25,   7,  31,   0,  24,   6,  30, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_73)[8][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, },
@@ -76,7 +76,7 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
 };
 
 #if 1
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_220)[8][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, },
@@ -88,7 +88,7 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
 };
 #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, ff_dither_8x8_220)[8][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, },
@@ -100,7 +100,7 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
 };
 #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, ff_dither_8x8_220)[8][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, },
@@ -112,7 +112,7 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
 };
 #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, ff_dither_8x8_220)[8][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, },
@@ -314,7 +314,7 @@ yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
                       const int16_t **alpSrc, uint8_t *dest, int dstW,
                       int y, enum AVPixelFormat target)
 {
-    const uint8_t * const d128=dither_8x8_220[y&7];
+    const uint8_t * const d128 = ff_dither_8x8_220[y&7];
     int i;
     unsigned acc = 0;
 
@@ -353,7 +353,7 @@ yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2],
                       enum AVPixelFormat target)
 {
     const int16_t *buf0  = buf[0],  *buf1  = buf[1];
-    const uint8_t * const d128 = dither_8x8_220[y & 7];
+    const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
     int  yalpha1 = 4096 - yalpha;
     int i;
 
@@ -387,7 +387,7 @@ yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0,
                       const int16_t *abuf0, uint8_t *dest, int dstW,
                       int uvalpha, int y, enum AVPixelFormat target)
 {
-    const uint8_t * const d128 = dither_8x8_220[y & 7];
+    const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
     int i;
 
     for (i = 0; i < dstW; i += 8) {
@@ -880,12 +880,12 @@ yuv2rgb_write(uint8_t *_dest, int i, unsigned Y1, unsigned Y2,
             dg2 = dither_2x2_8[ y & 1     ][0];
             db2 = dither_2x2_8[(y & 1) ^ 1][1];
         } else {
-            dr1 = dither_4x4_16[ y & 3     ][0];
-            dg1 = dither_4x4_16[ y & 3     ][1];
-            db1 = dither_4x4_16[(y & 3) ^ 3][0];
-            dr2 = dither_4x4_16[ y & 3     ][1];
-            dg2 = dither_4x4_16[ y & 3     ][0];
-            db2 = dither_4x4_16[(y & 3) ^ 3][1];
+            dr1 = ff_dither_4x4_16[ y & 3     ][0];
+            dg1 = ff_dither_4x4_16[ y & 3     ][1];
+            db1 = ff_dither_4x4_16[(y & 3) ^ 3][0];
+            dr2 = ff_dither_4x4_16[ y & 3     ][1];
+            dg2 = ff_dither_4x4_16[ y & 3     ][0];
+            db2 = ff_dither_4x4_16[(y & 3) ^ 3][1];
         }
 
         dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1];
@@ -898,15 +898,15 @@ yuv2rgb_write(uint8_t *_dest, int i, unsigned Y1, unsigned Y2,
         int dr1, dg1, db1, dr2, dg2, db2;
 
         if (target == AV_PIX_FMT_RGB8 || target == AV_PIX_FMT_BGR8) {
-            const uint8_t * const d64 = dither_8x8_73[y & 7];
-            const uint8_t * const d32 = dither_8x8_32[y & 7];
+            const uint8_t * const d64 = ff_dither_8x8_73[y & 7];
+            const uint8_t * const d32 = ff_dither_8x8_32[y & 7];
             dr1 = dg1 = d32[(i * 2 + 0) & 7];
             db1 =       d64[(i * 2 + 0) & 7];
             dr2 = dg2 = d32[(i * 2 + 1) & 7];
             db2 =       d64[(i * 2 + 1) & 7];
         } else {
-            const uint8_t * const d64  = dither_8x8_73 [y & 7];
-            const uint8_t * const d128 = dither_8x8_220[y & 7];
+            const uint8_t * const d64  = ff_dither_8x8_73 [y & 7];
+            const uint8_t * const d128 = ff_dither_8x8_220[y & 7];
             dr1 = db1 = d128[(i * 2 + 0) & 7];
             dg1 =        d64[(i * 2 + 0) & 7];
             dr2 = db2 = d128[(i * 2 + 1) & 7];
@@ -1261,13 +1261,91 @@ YUV2RGBWRAPPERX(yuv2, rgb_full, xrgb32_full, AV_PIX_FMT_ARGB,  0)
 YUV2RGBWRAPPERX(yuv2, rgb_full, bgr24_full,  AV_PIX_FMT_BGR24, 0)
 YUV2RGBWRAPPERX(yuv2, rgb_full, rgb24_full,  AV_PIX_FMT_RGB24, 0)
 
+static void
+yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter,
+                  const int16_t **lumSrc, int lumFilterSize,
+                  const int16_t *chrFilter, const int16_t **chrUSrc,
+                  const int16_t **chrVSrc, int chrFilterSize,
+                  const int16_t **alpSrc, uint8_t **dest,
+                  int dstW, int y)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->dstFormat);
+    int i;
+    int hasAlpha = 0;
+    uint16_t **dest16 = (uint16_t**)dest;
+    int SH = 22 + 7 - desc->comp[0].depth_minus1;
+
+    for (i = 0; i < dstW; i++) {
+        int j;
+        int Y = 1 << 9;
+        int U = (1 << 9) - (128 << 19);
+        int V = (1 << 9) - (128 << 19);
+        int R, G, B, A;
+
+        for (j = 0; j < lumFilterSize; j++)
+            Y += lumSrc[j][i] * lumFilter[j];
+
+        for (j = 0; j < chrFilterSize; j++) {
+            U += chrUSrc[j][i] * chrFilter[j];
+            V += chrVSrc[j][i] * chrFilter[j];
+        }
+
+        Y >>= 10;
+        U >>= 10;
+        V >>= 10;
+
+        if (hasAlpha) {
+            A = 1 << 18;
+
+            for (j = 0; j < lumFilterSize; j++)
+                A += alpSrc[j][i] * lumFilter[j];
+
+            A >>= 19;
+
+            if (A & 0x100)
+                A = av_clip_uint8(A);
+        }
+
+        Y -= c->yuv2rgb_y_offset;
+        Y *= c->yuv2rgb_y_coeff;
+        Y += 1 << 21;
+        R = Y + V * c->yuv2rgb_v2r_coeff;
+        G = Y + V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;
+        B = Y +                            U * c->yuv2rgb_u2b_coeff;
+
+        if ((R | G | B) & 0xC0000000) {
+            R = av_clip_uintp2(R, 30);
+            G = av_clip_uintp2(G, 30);
+            B = av_clip_uintp2(B, 30);
+        }
+
+        if (SH != 22) {
+            dest16[0][i] = G >> SH;
+            dest16[1][i] = B >> SH;
+            dest16[2][i] = R >> SH;
+        } else {
+            dest[0][i] = G >> 22;
+            dest[1][i] = B >> 22;
+            dest[2][i] = R >> 22;
+        }
+    }
+    if (SH != 22 && (!isBE(c->dstFormat)) != (!HAVE_BIGENDIAN)) {
+        for (i = 0; i < dstW; i++) {
+            dest16[0][i] = av_bswap16(dest16[0][i]);
+            dest16[1][i] = av_bswap16(dest16[1][i]);
+            dest16[2][i] = av_bswap16(dest16[2][i]);
+        }
+    }
+}
+
 av_cold void ff_sws_init_output_funcs(SwsContext *c,
                                       yuv2planar1_fn *yuv2plane1,
                                       yuv2planarX_fn *yuv2planeX,
                                       yuv2interleavedX_fn *yuv2nv12cX,
                                       yuv2packed1_fn *yuv2packed1,
                                       yuv2packed2_fn *yuv2packed2,
-                                      yuv2packedX_fn *yuv2packedX)
+                                      yuv2packedX_fn *yuv2packedX,
+                                      yuv2anyX_fn *yuv2anyX)
 {
     enum AVPixelFormat dstFormat = c->dstFormat;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
@@ -1354,6 +1432,15 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
         case AV_PIX_FMT_BGR24:
             *yuv2packedX = yuv2bgr24_full_X_c;
             break;
+        case AV_PIX_FMT_GBRP:
+        case AV_PIX_FMT_GBRP9BE:
+        case AV_PIX_FMT_GBRP9LE:
+        case AV_PIX_FMT_GBRP10BE:
+        case AV_PIX_FMT_GBRP10LE:
+        case AV_PIX_FMT_GBRP16BE:
+        case AV_PIX_FMT_GBRP16LE:
+            *yuv2anyX = yuv2gbrp_full_X_c;
+            break;
         }
     } else {
         switch (dstFormat) {
diff --git a/libswscale/ppc/Makefile b/libswscale/ppc/Makefile
index 018955b..d1b596e 100644
--- a/libswscale/ppc/Makefile
+++ b/libswscale/ppc/Makefile
@@ -1,3 +1,3 @@
-ALTIVEC-OBJS +=  ppc/swscale_altivec.o                                  \
-                 ppc/yuv2rgb_altivec.o                                  \
-                 ppc/yuv2yuv_altivec.o                                  \
+OBJS += ppc/swscale_altivec.o                                           \
+        ppc/yuv2rgb_altivec.o                                           \
+        ppc/yuv2yuv_altivec.o                                           \
diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c
index b0e25d0..7e00488 100644
--- a/libswscale/ppc/swscale_altivec.c
+++ b/libswscale/ppc/swscale_altivec.c
@@ -30,6 +30,7 @@
 #include "libavutil/cpu.h"
 #include "yuv2rgb_altivec.h"
 
+#if HAVE_ALTIVEC
 #define vzero vec_splat_s32(0)
 
 #define yuv2planeX_8(d1, d2, l1, src, x, perm, filter) do {     \
@@ -284,9 +285,11 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
             }
         }
 }
+#endif /* HAVE_ALTIVEC */
 
-av_cold void ff_sws_init_swScale_altivec(SwsContext *c)
+av_cold void ff_sws_init_swscale_ppc(SwsContext *c)
 {
+#if HAVE_ALTIVEC
     enum AVPixelFormat dstFormat = c->dstFormat;
 
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
@@ -325,4 +328,5 @@ av_cold void ff_sws_init_swScale_altivec(SwsContext *c)
             break;
         }
     }
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
index 94e87fe..74b0f18 100644
--- a/libswscale/ppc/yuv2rgb_altivec.c
+++ b/libswscale/ppc/yuv2rgb_altivec.c
@@ -99,6 +99,8 @@
 #include "libavutil/cpu.h"
 #include "yuv2rgb_altivec.h"
 
+#if HAVE_ALTIVEC
+
 #undef PROFILE_THE_BEAST
 #undef INC_SCALING
 
@@ -245,8 +247,6 @@ static const vector unsigned char
                   (vector unsigned short)                               \
                       vec_max(y, ((vector signed short) { 0 })))
 
-//#define out_pixels(a, b, c, ptr) vec_mstrgb32(__typeof__(a), ((__typeof__(a)) { 255 }), a, a, a, ptr)
-
 static inline void cvtyuvtoRGB(SwsContext *c, vector signed short Y,
                                vector signed short U, vector signed short V,
                                vector signed short *R, vector signed short *G,
@@ -530,14 +530,17 @@ static int altivec_uyvy_rgb32(SwsContext *c, const unsigned char **in,
     return srcSliceH;
 }
 
+#endif /* HAVE_ALTIVEC */
+
 /* Ok currently the acceleration routine only supports
  * inputs of widths a multiple of 16
  * and heights a multiple 2
  *
  * So we just fall back to the C codes for this.
  */
-av_cold SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c)
+av_cold SwsFunc ff_yuv2rgb_init_ppc(SwsContext *c)
 {
+#if HAVE_ALTIVEC
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return NULL;
 
@@ -593,20 +596,26 @@ av_cold SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c)
         }
         break;
     }
+#endif /* HAVE_ALTIVEC */
+
     return NULL;
 }
 
-av_cold void ff_yuv2rgb_init_tables_altivec(SwsContext *c,
-                                            const int inv_table[4],
-                                            int brightness,
-                                            int contrast,
-                                            int saturation)
+av_cold void ff_yuv2rgb_init_tables_ppc(SwsContext *c,
+                                        const int inv_table[4],
+                                        int brightness,
+                                        int contrast,
+                                        int saturation)
 {
+#if HAVE_ALTIVEC
     union {
         DECLARE_ALIGNED(16, signed short, tmp)[8];
         vector signed short vec;
     } buf;
 
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
     buf.tmp[0] = ((0xffffLL) * contrast >> 8) >> 9;                               // cy
     buf.tmp[1] = -256 * brightness;                                               // oy
     buf.tmp[2] =   (inv_table[0] >> 3) * (contrast >> 16) * (saturation >> 16);   // crv
@@ -622,20 +631,23 @@ av_cold void ff_yuv2rgb_init_tables_altivec(SwsContext *c,
     c->CGU    = vec_splat((vector signed short) buf.vec, 4);
     c->CGV    = vec_splat((vector signed short) buf.vec, 5);
     return;
+#endif /* HAVE_ALTIVEC */
 }
 
-static av_always_inline void ff_yuv2packedX_altivec(SwsContext *c,
-                                                    const int16_t *lumFilter,
-                                                    const int16_t **lumSrc,
-                                                    int lumFilterSize,
-                                                    const int16_t *chrFilter,
-                                                    const int16_t **chrUSrc,
-                                                    const int16_t **chrVSrc,
-                                                    int chrFilterSize,
-                                                    const int16_t **alpSrc,
-                                                    uint8_t *dest,
-                                                    int dstW, int dstY,
-                                                    enum AVPixelFormat target)
+#if HAVE_ALTIVEC
+
+static av_always_inline void yuv2packedX_altivec(SwsContext *c,
+                                                 const int16_t *lumFilter,
+                                                 const int16_t **lumSrc,
+                                                 int lumFilterSize,
+                                                 const int16_t *chrFilter,
+                                                 const int16_t **chrUSrc,
+                                                 const int16_t **chrVSrc,
+                                                 int chrFilterSize,
+                                                 const int16_t **alpSrc,
+                                                 uint8_t *dest,
+                                                 int dstW, int dstY,
+                                                 enum AVPixelFormat target)
 {
     int i, j;
     vector signed short X, X0, X1, Y0, U0, V0, Y1, U1, V1, U, V;
@@ -844,10 +856,10 @@ void ff_yuv2 ## suffix ## _X_altivec(SwsContext *c,                     \
                                      const int16_t **alpSrc,            \
                                      uint8_t *dest, int dstW, int dstY) \
 {                                                                       \
-    ff_yuv2packedX_altivec(c, lumFilter, lumSrc, lumFilterSize,         \
-                           chrFilter, chrUSrc, chrVSrc,                 \
-                           chrFilterSize, alpSrc,                       \
-                           dest, dstW, dstY, pixfmt);                   \
+    yuv2packedX_altivec(c, lumFilter, lumSrc, lumFilterSize,            \
+                        chrFilter, chrUSrc, chrVSrc,                    \
+                        chrFilterSize, alpSrc,                          \
+                        dest, dstW, dstY, pixfmt);                      \
 }
 
 YUV2PACKEDX_WRAPPER(abgr,  AV_PIX_FMT_ABGR);
@@ -856,3 +868,5 @@ YUV2PACKEDX_WRAPPER(argb,  AV_PIX_FMT_ARGB);
 YUV2PACKEDX_WRAPPER(rgba,  AV_PIX_FMT_RGBA);
 YUV2PACKEDX_WRAPPER(rgb24, AV_PIX_FMT_RGB24);
 YUV2PACKEDX_WRAPPER(bgr24, AV_PIX_FMT_BGR24);
+
+#endif /* HAVE_ALTIVEC */
diff --git a/libswscale/ppc/yuv2yuv_altivec.c b/libswscale/ppc/yuv2yuv_altivec.c
index 5aa1820..08545b3 100644
--- a/libswscale/ppc/yuv2yuv_altivec.c
+++ b/libswscale/ppc/yuv2yuv_altivec.c
@@ -24,9 +24,12 @@
 #include <inttypes.h>
 
 #include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
 #include "libswscale/swscale.h"
 #include "libswscale/swscale_internal.h"
-#include "libavutil/cpu.h"
+
+#if HAVE_ALTIVEC
 
 static int yv12toyuy2_unscaled_altivec(SwsContext *c, const uint8_t *src[],
                                        int srcStride[], int srcSliceY,
@@ -179,16 +182,23 @@ static int yv12touyvy_unscaled_altivec(SwsContext *c, const uint8_t *src[],
     return srcSliceH;
 }
 
-void ff_swscale_get_unscaled_altivec(SwsContext *c)
+#endif /* HAVE_ALTIVEC */
+
+av_cold void ff_get_unscaled_swscale_ppc(SwsContext *c)
 {
-    if ((av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) && !(c->srcW & 15) &&
-        !(c->flags & SWS_BITEXACT) && c->srcFormat == AV_PIX_FMT_YUV420P) {
+#if HAVE_ALTIVEC
+    if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
+        return;
+
+    if (!(c->srcW & 15) && !(c->flags & SWS_BITEXACT) &&
+        c->srcFormat == AV_PIX_FMT_YUV420P) {
         enum AVPixelFormat dstFormat = c->dstFormat;
 
         // unscaled YV12 -> packed YUV, we want speed
         if (dstFormat == AV_PIX_FMT_YUYV422)
-            c->swScale = yv12toyuy2_unscaled_altivec;
+            c->swscale = yv12toyuy2_unscaled_altivec;
         else if (dstFormat == AV_PIX_FMT_UYVY422)
-            c->swScale = yv12touyvy_unscaled_altivec;
+            c->swscale = yv12touyvy_unscaled_altivec;
     }
+#endif /* HAVE_ALTIVEC */
 }
diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c
index c261fe6..21adfe1 100644
--- a/libswscale/rgb2rgb.c
+++ b/libswscale/rgb2rgb.c
@@ -129,7 +129,7 @@ void (*yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
 av_cold void sws_rgb2rgb_init(void)
 {
     rgb2rgb_init_c();
-    if (HAVE_MMX)
+    if (ARCH_X86)
         rgb2rgb_init_x86();
 }
 
diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h
index 42f468f..79c378d 100644
--- a/libswscale/rgb2rgb.h
+++ b/libswscale/rgb2rgb.h
@@ -28,8 +28,8 @@
 
 #include <inttypes.h>
 
-#include "libswscale/swscale.h"
 #include "libavutil/avutil.h"
+#include "swscale.h"
 
 /* A full collection of RGB to RGB(BGR) converters */
 extern void (*rgb24tobgr32)(const uint8_t *src, uint8_t *dst, int src_size);
diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c
index 3785ef9..3da2b0b 100644
--- a/libswscale/rgb2rgb_template.c
+++ b/libswscale/rgb2rgb_template.c
@@ -26,6 +26,8 @@
 
 #include <stddef.h>
 
+#include "libavutil/attributes.h"
+
 static inline void rgb24tobgr32_c(const uint8_t *src, uint8_t *dst,
                                   int src_size)
 {
@@ -907,7 +909,7 @@ static void uyvytoyuv422_c(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
     }
 }
 
-static inline void rgb2rgb_init_c(void)
+static av_cold void rgb2rgb_init_c(void)
 {
     rgb15to16          = rgb15to16_c;
     rgb15tobgr24       = rgb15tobgr24_c;
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index dac8b37..7756e1b 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -35,7 +35,7 @@
 #include "swscale_internal.h"
 #include "swscale.h"
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = {
+DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_128)[8][8] = {
     {  36, 68,  60, 92,  34, 66,  58, 90, },
     { 100,  4, 124, 28,  98,  2, 122, 26, },
     {  52, 84,  44, 76,  50, 82,  42, 74, },
@@ -46,7 +46,7 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_128)[8][8] = {
     { 112, 16, 104,  8, 118, 22, 110, 14, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, ff_sws_pb_64)[8] = {
+DECLARE_ALIGNED(8, static const uint8_t, sws_pb_64)[8] = {
     64, 64, 64, 64, 64, 64, 64, 64
 };
 
@@ -337,7 +337,7 @@ static av_always_inline void hcscale(SwsContext *c, int16_t *dst1,
     if (DEBUG_SWSCALE_BUFFERS)                  \
         av_log(c, AV_LOG_DEBUG, __VA_ARGS__)
 
-static int swScale(SwsContext *c, const uint8_t *src[],
+static int swscale(SwsContext *c, const uint8_t *src[],
                    int srcStride[], int srcSliceY,
                    int srcSliceH, uint8_t *dst[], int dstStride[])
 {
@@ -380,6 +380,7 @@ static int swScale(SwsContext *c, const uint8_t *src[],
     yuv2packed1_fn yuv2packed1       = c->yuv2packed1;
     yuv2packed2_fn yuv2packed2       = c->yuv2packed2;
     yuv2packedX_fn yuv2packedX       = c->yuv2packedX;
+    yuv2anyX_fn yuv2anyX             = c->yuv2anyX;
     const int chrSrcSliceY           =     srcSliceY  >> c->chrSrcVSubSample;
     const int chrSrcSliceH           = -((-srcSliceH) >> c->chrSrcVSubSample);
     int should_dither                = is9_OR_10BPS(c->srcFormat) ||
@@ -406,7 +407,7 @@ static int swScale(SwsContext *c, const uint8_t *src[],
     srcStride[1] <<= c->vChrDrop;
     srcStride[2] <<= c->vChrDrop;
 
-    DEBUG_BUFFERS("swScale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
+    DEBUG_BUFFERS("swscale() %p[%d] %p[%d] %p[%d] %p[%d] -> %p[%d] %p[%d] %p[%d] %p[%d]\n",
                   src[0], srcStride[0], src[1], srcStride[1],
                   src[2], srcStride[2], src[3], srcStride[3],
                   dst[0], dstStride[0], dst[1], dstStride[1],
@@ -439,7 +440,7 @@ static int swScale(SwsContext *c, const uint8_t *src[],
     }
 
     if (!should_dither) {
-        c->chrDither8 = c->lumDither8 = ff_sws_pb_64;
+        c->chrDither8 = c->lumDither8 = sws_pb_64;
     }
     lastDstY = dstY;
 
@@ -547,14 +548,14 @@ static int swScale(SwsContext *c, const uint8_t *src[],
                               lastInLumBuf, lastInChrBuf);
 #endif
         if (should_dither) {
-            c->chrDither8 = dither_8x8_128[chrDstY & 7];
-            c->lumDither8 = dither_8x8_128[dstY    & 7];
+            c->chrDither8 = ff_dither_8x8_128[chrDstY & 7];
+            c->lumDither8 = ff_dither_8x8_128[dstY    & 7];
         }
         if (dstY >= dstH - 2) {
             /* hmm looks like we can't use MMX here without overwriting
              * this array's tail */
             ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
-                                     &yuv2packed1, &yuv2packed2, &yuv2packedX);
+                                     &yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX);
         }
 
         {
@@ -651,7 +652,7 @@ static int swScale(SwsContext *c, const uint8_t *src[],
                                    dstW, c->lumDither8, 0);
                     }
                 }
-            } else {
+            } else if (yuv2packedX) {
                 if (c->yuv2packed1 && vLumFilterSize == 1 &&
                     vChrFilterSize <= 2) { // unscaled RGB
                     int chrAlpha = vChrFilterSize == 1 ? 0 : vChrFilter[2 * dstY + 1];
@@ -676,6 +677,12 @@ static int swScale(SwsContext *c, const uint8_t *src[],
                                 chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
                                 alpSrcPtr, dest[0], dstW, dstY);
                 }
+            } else {
+                yuv2anyX(c, vLumFilter + dstY * vLumFilterSize,
+                         lumSrcPtr, vLumFilterSize,
+                         vChrFilter + dstY * vChrFilterSize,
+                         chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
+                         alpSrcPtr, dest, dstW, dstY);
             }
         }
     }
@@ -711,13 +718,13 @@ static int swScale(SwsContext *c, const uint8_t *src[],
     return dstY - lastDstY;
 }
 
-static av_cold void sws_init_swScale_c(SwsContext *c)
+static av_cold void sws_init_swscale(SwsContext *c)
 {
     enum AVPixelFormat srcFormat = c->srcFormat;
 
     ff_sws_init_output_funcs(c, &c->yuv2plane1, &c->yuv2planeX,
                              &c->yuv2nv12cX, &c->yuv2packed1,
-                             &c->yuv2packed2, &c->yuv2packedX);
+                             &c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX);
 
     ff_sws_init_input_funcs(c);
 
@@ -763,12 +770,12 @@ static av_cold void sws_init_swScale_c(SwsContext *c)
 
 SwsFunc ff_getSwsFunc(SwsContext *c)
 {
-    sws_init_swScale_c(c);
+    sws_init_swscale(c);
 
-    if (HAVE_MMX)
-        ff_sws_init_swScale_mmx(c);
-    if (HAVE_ALTIVEC)
-        ff_sws_init_swScale_altivec(c);
+    if (ARCH_PPC)
+        ff_sws_init_swscale_ppc(c);
+    if (ARCH_X86)
+        ff_sws_init_swscale_x86(c);
 
-    return swScale;
+    return swscale;
 }
diff --git a/libswscale/swscale.h b/libswscale/swscale.h
index 8ba09e6..8fe27df 100644
--- a/libswscale/swscale.h
+++ b/libswscale/swscale.h
@@ -23,6 +23,7 @@
 
 /**
  * @file
+ * @ingroup libsws
  * @brief
  *     external api for the swscale stuff
  */
@@ -35,6 +36,9 @@
 #include "version.h"
 
 /**
+ * @defgroup libsws Color conversion and scaling
+ * @{
+ *
  * Return the LIBSWSCALE_VERSION_INT constant.
  */
 unsigned swscale_version(void);
@@ -141,6 +145,13 @@ int sws_isSupportedInput(enum AVPixelFormat pix_fmt);
 int sws_isSupportedOutput(enum AVPixelFormat pix_fmt);
 
 /**
+ * @param[in]  pix_fmt the pixel format
+ * @return a positive value if an endianness conversion for pix_fmt is
+ * supported, 0 otherwise.
+ */
+int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt);
+
+/**
  * Allocate an empty SwsContext. This must be filled and passed to
  * sws_init_context(). For filling see AVOptions, options.c and
  * sws_setColorspaceDetails().
@@ -336,4 +347,8 @@ void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, int num_pix
  */
 const AVClass *sws_get_class(void);
 
+/**
+ * @}
+ */
+
 #endif /* SWSCALE_SWSCALE_H */
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 8752672..5737724 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -218,6 +218,40 @@ typedef void (*yuv2packedX_fn)(struct SwsContext *c, const int16_t *lumFilter,
                                const int16_t **alpSrc, uint8_t *dest,
                                int dstW, int y);
 
+/**
+ * Write one line of horizontally scaled Y/U/V/A to YUV/RGB
+ * output by doing multi-point vertical scaling between input pixels.
+ *
+ * @param c             SWS scaling context
+ * @param lumFilter     vertical luma/alpha scaling coefficients, 12bit [0,4096]
+ * @param lumSrc        scaled luma (Y) source data, 15bit for 8-10bit output,
+ *                      19-bit for 16bit output (in int32_t)
+ * @param lumFilterSize number of vertical luma/alpha input lines to scale
+ * @param chrFilter     vertical chroma scaling coefficients, 12bit [0,4096]
+ * @param chrUSrc       scaled chroma (U) source data, 15bit for 8-10bit output,
+ *                      19-bit for 16bit output (in int32_t)
+ * @param chrVSrc       scaled chroma (V) source data, 15bit for 8-10bit output,
+ *                      19-bit for 16bit output (in int32_t)
+ * @param chrFilterSize number of vertical chroma input lines to scale
+ * @param alpSrc        scaled alpha (A) source data, 15bit for 8-10bit output,
+ *                      19-bit for 16bit output (in int32_t)
+ * @param dest          pointer to the output planes. For 16bit output, this is
+ *                      uint16_t
+ * @param dstW          width of lumSrc and alpSrc in pixels, number of pixels
+ *                      to write into dest[]
+ * @param y             vertical line number for this output. This does not need
+ *                      to be used to calculate the offset in the destination,
+ *                      but can be used to generate comfort noise using dithering
+ *                      or some output formats.
+ */
+typedef void (*yuv2anyX_fn)(struct SwsContext *c, const int16_t *lumFilter,
+                            const int16_t **lumSrc, int lumFilterSize,
+                            const int16_t *chrFilter,
+                            const int16_t **chrUSrc,
+                            const int16_t **chrVSrc, int chrFilterSize,
+                            const int16_t **alpSrc, uint8_t **dest,
+                            int dstW, int y);
+
 /* This struct should be aligned on at least a 32-byte boundary. */
 typedef struct SwsContext {
     /**
@@ -229,7 +263,7 @@ typedef struct SwsContext {
      * Note that src, dst, srcStride, dstStride will be copied in the
      * sws_scale() wrapper so they can be freely modified here.
      */
-    SwsFunc swScale;
+    SwsFunc swscale;
     int srcW;                     ///< Width  of source      luma/alpha planes.
     int srcH;                     ///< Height of source      luma/alpha planes.
     int dstH;                     ///< Height of destination luma/alpha planes.
@@ -420,13 +454,14 @@ typedef struct SwsContext {
     DECLARE_ALIGNED(8, uint64_t, sparc_coeffs)[10];
 #endif
 
-    /* function pointers for swScale() */
+    /* function pointers for swscale() */
     yuv2planar1_fn yuv2plane1;
     yuv2planarX_fn yuv2planeX;
     yuv2interleavedX_fn yuv2nv12cX;
     yuv2packed1_fn yuv2packed1;
     yuv2packed2_fn yuv2packed2;
     yuv2packedX_fn yuv2packedX;
+    yuv2anyX_fn yuv2anyX;
 
     /// Unscaled conversion of luma plane to YV12 for horizontal scaler.
     void (*lumToYV12)(uint8_t *dst, const uint8_t *src,
@@ -529,17 +564,16 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c);
 int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4],
                              int fullRange, int brightness,
                              int contrast, int saturation);
+void ff_yuv2rgb_init_tables_ppc(SwsContext *c, const int inv_table[4],
+                                int brightness, int contrast, int saturation);
 
-void ff_yuv2rgb_init_tables_altivec(SwsContext *c, const int inv_table[4],
-                                    int brightness, int contrast, int saturation);
 void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufIndex,
                            int lastInLumBuf, int lastInChrBuf);
 
-SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c);
+SwsFunc ff_yuv2rgb_init_x86(SwsContext *c);
 SwsFunc ff_yuv2rgb_init_vis(SwsContext *c);
-SwsFunc ff_yuv2rgb_init_altivec(SwsContext *c);
-SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c);
-void ff_bfin_get_unscaled_swscale(SwsContext *c);
+SwsFunc ff_yuv2rgb_init_ppc(SwsContext *c);
+SwsFunc ff_yuv2rgb_init_bfin(SwsContext *c);
 
 const char *sws_format_name(enum AVPixelFormat format);
 
@@ -561,33 +595,33 @@ static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return desc->flags & PIX_FMT_BE;
+    return desc->flags & AV_PIX_FMT_FLAG_BE;
 }
 
 static av_always_inline int isYUV(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return !(desc->flags & PIX_FMT_RGB) && desc->nb_components >= 2;
+    return !(desc->flags & AV_PIX_FMT_FLAG_RGB) && desc->nb_components >= 2;
 }
 
 static av_always_inline int isPlanarYUV(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->flags & PIX_FMT_PLANAR) && isYUV(pix_fmt));
+    return ((desc->flags & AV_PIX_FMT_FLAG_PLANAR) && isYUV(pix_fmt));
 }
 
 static av_always_inline int isRGB(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return (desc->flags & PIX_FMT_RGB);
+    return (desc->flags & AV_PIX_FMT_FLAG_RGB);
 }
 
 #if 0 // FIXME
 #define isGray(x) \
-    (!(av_pix_fmt_descriptors[x].flags & PIX_FMT_PAL) && \
+    (!(av_pix_fmt_descriptors[x].flags & AV_PIX_FMT_FLAG_PAL) && \
      av_pix_fmt_descriptors[x].nb_components <= 2)
 #else
 #define isGray(x)                      \
@@ -648,7 +682,7 @@ static av_always_inline int isPacked(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->nb_components >= 2 && !(desc->flags & PIX_FMT_PLANAR)) ||
+    return ((desc->nb_components >= 2 && !(desc->flags & AV_PIX_FMT_FLAG_PLANAR)) ||
             pix_fmt == AV_PIX_FMT_PAL8);
 }
 
@@ -656,44 +690,52 @@ static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return (desc->nb_components >= 2 && (desc->flags & PIX_FMT_PLANAR));
+    return (desc->nb_components >= 2 && (desc->flags & AV_PIX_FMT_FLAG_PLANAR));
 }
 
 static av_always_inline int isPackedRGB(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->flags & (PIX_FMT_PLANAR | PIX_FMT_RGB)) == PIX_FMT_RGB);
+    return ((desc->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) == AV_PIX_FMT_FLAG_RGB);
 }
 
 static av_always_inline int isPlanarRGB(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->flags & (PIX_FMT_PLANAR | PIX_FMT_RGB)) ==
-            (PIX_FMT_PLANAR | PIX_FMT_RGB));
+    return ((desc->flags & (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB)) ==
+            (AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB));
 }
 
 static av_always_inline int usePal(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->flags & PIX_FMT_PAL) || (desc->flags & PIX_FMT_PSEUDOPAL) ||
+    return ((desc->flags & AV_PIX_FMT_FLAG_PAL) || (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) ||
             pix_fmt == AV_PIX_FMT_Y400A);
 }
 
 extern const uint64_t ff_dither4[2];
 extern const uint64_t ff_dither8[2];
 
+extern const uint8_t ff_dither_4x4_16[4][8];
+extern const uint8_t ff_dither_8x8_32[8][8];
+extern const uint8_t ff_dither_8x8_73[8][8];
+extern const uint8_t ff_dither_8x8_128[8][8];
+extern const uint8_t ff_dither_8x8_220[8][8];
+
+extern const int32_t ff_yuv2rgb_coeffs[8][4];
+
 extern const AVClass sws_context_class;
 
 /**
- * Set c->swScale to an unscaled converter if one exists for the specific
+ * Set c->swscale to an unscaled converter if one exists for the specific
  * source and destination formats, bit depths, flags, etc.
  */
 void ff_get_unscaled_swscale(SwsContext *c);
-
-void ff_swscale_get_unscaled_altivec(SwsContext *c);
+void ff_get_unscaled_swscale_bfin(SwsContext *c);
+void ff_get_unscaled_swscale_ppc(SwsContext *c);
 
 /**
  * Return function pointer to fastest main scaler path function depending
@@ -708,8 +750,9 @@ void ff_sws_init_output_funcs(SwsContext *c,
                               yuv2interleavedX_fn *yuv2nv12cX,
                               yuv2packed1_fn *yuv2packed1,
                               yuv2packed2_fn *yuv2packed2,
-                              yuv2packedX_fn *yuv2packedX);
-void ff_sws_init_swScale_altivec(SwsContext *c);
-void ff_sws_init_swScale_mmx(SwsContext *c);
+                              yuv2packedX_fn *yuv2packedX,
+                              yuv2anyX_fn *yuv2anyX);
+void ff_sws_init_swscale_ppc(SwsContext *c);
+void ff_sws_init_swscale_x86(SwsContext *c);
 
 #endif /* SWSCALE_SWSCALE_INTERNAL_H */
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 9b919f8..3e5f49e 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -34,7 +34,7 @@
 #include "libavutil/bswap.h"
 #include "libavutil/pixdesc.h"
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_1)[8][8] = {
+DECLARE_ALIGNED(8, static 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,},
@@ -44,7 +44,7 @@ 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,},
 };
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_3)[8][8] = {
+DECLARE_ALIGNED(8, static 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,},
@@ -54,7 +54,7 @@ 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,},
 };
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_64)[8][8] = {
+DECLARE_ALIGNED(8, static 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,},
@@ -64,8 +64,7 @@ DECLARE_ALIGNED(8, const uint8_t, dither_8x8_64)[8][8] = {
     {  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] = {
+DECLARE_ALIGNED(8, static 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,},
@@ -468,6 +467,80 @@ static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t *src[],
     return srcSliceH;
 }
 
+static void packedtogbr24p(const uint8_t *src, int srcStride,
+                           uint8_t *dst[], int dstStride[], int srcSliceH,
+                           int alpha_first, int inc_size, int width)
+{
+    uint8_t *dest[3];
+    int x, h;
+
+    dest[0] = dst[0];
+    dest[1] = dst[1];
+    dest[2] = dst[2];
+
+    if (alpha_first)
+        src++;
+
+    for (h = 0; h < srcSliceH; h++) {
+        for (x = 0; x < width; x++) {
+            dest[0][x] = src[0];
+            dest[1][x] = src[1];
+            dest[2][x] = src[2];
+
+            src += inc_size;
+        }
+        src     += srcStride - width * inc_size;
+        dest[0] += dstStride[0];
+        dest[1] += dstStride[1];
+        dest[2] += dstStride[2];
+    }
+}
+
+static int rgbToPlanarRgbWrapper(SwsContext *c, const uint8_t *src[],
+                                 int srcStride[], int srcSliceY, int srcSliceH,
+                                 uint8_t *dst[], int dstStride[])
+{
+    int alpha_first = 0;
+    int stride102[] = { dstStride[1], dstStride[0], dstStride[2] };
+    int stride201[] = { dstStride[2], dstStride[0], dstStride[1] };
+    uint8_t *dst102[] = { dst[1] + srcSliceY * dstStride[1],
+                          dst[0] + srcSliceY * dstStride[0],
+                          dst[2] + srcSliceY * dstStride[2] };
+    uint8_t *dst201[] = { dst[2] + srcSliceY * dstStride[2],
+                          dst[0] + srcSliceY * dstStride[0],
+                          dst[1] + srcSliceY * dstStride[1] };
+
+    switch (c->srcFormat) {
+    case AV_PIX_FMT_RGB24:
+        packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
+                       stride201, srcSliceH, alpha_first, 3, c->srcW);
+        break;
+    case AV_PIX_FMT_BGR24:
+        packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
+                       stride102, srcSliceH, alpha_first, 3, c->srcW);
+        break;
+    case AV_PIX_FMT_ARGB:
+        alpha_first = 1;
+    case AV_PIX_FMT_RGBA:
+        packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst201,
+                       stride201, srcSliceH, alpha_first, 4, c->srcW);
+        break;
+    case AV_PIX_FMT_ABGR:
+        alpha_first = 1;
+    case AV_PIX_FMT_BGRA:
+        packedtogbr24p((const uint8_t *) src[0], srcStride[0], dst102,
+                       stride102, srcSliceH, alpha_first, 4, c->srcW);
+        break;
+    default:
+        av_log(c, AV_LOG_ERROR,
+               "unsupported planar RGB conversion %s -> %s\n",
+               av_get_pix_fmt_name(c->srcFormat),
+               av_get_pix_fmt_name(c->dstFormat));
+    }
+
+    return srcSliceH;
+}
+
 #define isRGBA32(x) (            \
            (x) == AV_PIX_FMT_ARGB   \
         || (x) == AV_PIX_FMT_RGBA   \
@@ -489,7 +562,7 @@ static rgbConvFn findRgbConvFn(SwsContext *c)
 
 #define IS_NOT_NE(bpp, desc) \
     (((bpp + 7) >> 3) == 2 && \
-     (!(desc->flags & PIX_FMT_BE) != !HAVE_BIGENDIAN))
+     (!(desc->flags & AV_PIX_FMT_FLAG_BE) != !HAVE_BIGENDIAN))
 
     /* 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))
@@ -801,7 +874,7 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
                     if (dst_depth == 9) { \
                         DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
                                     srcPtr2, srcStride[plane] / 2, rfunc, \
-                                    dither_8x8_128, 7, clip9); \
+                                    ff_dither_8x8_128, 7, clip9); \
                     } else { \
                         DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
                                     srcPtr2, srcStride[plane] / 2, rfunc, \
@@ -906,34 +979,46 @@ void ff_get_unscaled_swscale(SwsContext *c)
     /* yv12_to_nv12 */
     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) &&
         (dstFormat == AV_PIX_FMT_NV12 || dstFormat == AV_PIX_FMT_NV21)) {
-        c->swScale = planarToNv12Wrapper;
+        c->swscale = planarToNv12Wrapper;
     }
     /* yuv2bgr */
     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUV422P ||
          srcFormat == AV_PIX_FMT_YUVA420P) && isAnyRGB(dstFormat) &&
         !(flags & SWS_ACCURATE_RND) && !(dstH & 1)) {
-        c->swScale = ff_yuv2rgb_get_func_ptr(c);
+        c->swscale = ff_yuv2rgb_get_func_ptr(c);
     }
 
     if (srcFormat == AV_PIX_FMT_YUV410P &&
         (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
         !(flags & SWS_BITEXACT)) {
-        c->swScale = yvu9ToYv12Wrapper;
+        c->swscale = yvu9ToYv12Wrapper;
     }
 
     /* bgr24toYV12 */
     if (srcFormat == AV_PIX_FMT_BGR24 &&
         (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) &&
         !(flags & SWS_ACCURATE_RND))
-        c->swScale = bgr24ToYv12Wrapper;
+        c->swscale = bgr24ToYv12Wrapper;
 
     /* RGB/BGR -> RGB/BGR (no dither needed forms) */
     if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
-        c->swScale= rgbToRgbWrapper;
+        c->swscale = rgbToRgbWrapper;
+
+#define isByteRGB(f) (             \
+        f == AV_PIX_FMT_RGB32   || \
+        f == AV_PIX_FMT_RGB32_1 || \
+        f == AV_PIX_FMT_RGB24   || \
+        f == AV_PIX_FMT_BGR32   || \
+        f == AV_PIX_FMT_BGR32_1 || \
+        f == AV_PIX_FMT_BGR24)
+
+    if (srcFormat == AV_PIX_FMT_GBRP && isPlanar(srcFormat) && isByteRGB(dstFormat))
+        c->swscale = planarRgbToRgbWrapper;
 
-    if (isPlanarRGB(srcFormat) && isPackedRGB(dstFormat))
-        c->swScale = planarRgbToRgbWrapper;
+    if (av_pix_fmt_desc_get(srcFormat)->comp[0].depth_minus1 == 7 &&
+        isPackedRGB(srcFormat) && dstFormat == AV_PIX_FMT_GBRP)
+        c->swscale = rgbToPlanarRgbWrapper;
 
     /* bswap 16 bits per pixel/component packed formats */
     if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR444) ||
@@ -944,8 +1029,9 @@ void ff_get_unscaled_swscale(SwsContext *c)
         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_RGB555) ||
-        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565))
-        c->swScale = packed_16bpc_bswap;
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565) ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_XYZ12))
+        c->swscale = packed_16bpc_bswap;
 
     if ((usePal(srcFormat) && (
         dstFormat == AV_PIX_FMT_RGB32   ||
@@ -954,13 +1040,13 @@ void ff_get_unscaled_swscale(SwsContext *c)
         dstFormat == AV_PIX_FMT_BGR32   ||
         dstFormat == AV_PIX_FMT_BGR32_1 ||
         dstFormat == AV_PIX_FMT_BGR24)))
-        c->swScale = palToRgbWrapper;
+        c->swscale = palToRgbWrapper;
 
     if (srcFormat == AV_PIX_FMT_YUV422P) {
         if (dstFormat == AV_PIX_FMT_YUYV422)
-            c->swScale = yuv422pToYuy2Wrapper;
+            c->swscale = yuv422pToYuy2Wrapper;
         else if (dstFormat == AV_PIX_FMT_UYVY422)
-            c->swScale = yuv422pToUyvyWrapper;
+            c->swscale = yuv422pToUyvyWrapper;
     }
 
     /* LQ converters if -sws 0 or -sws 4*/
@@ -968,21 +1054,21 @@ void ff_get_unscaled_swscale(SwsContext *c)
         /* yv12_to_yuy2 */
         if (srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) {
             if (dstFormat == AV_PIX_FMT_YUYV422)
-                c->swScale = planarToYuy2Wrapper;
+                c->swscale = planarToYuy2Wrapper;
             else if (dstFormat == AV_PIX_FMT_UYVY422)
-                c->swScale = planarToUyvyWrapper;
+                c->swscale = planarToUyvyWrapper;
         }
     }
     if (srcFormat == AV_PIX_FMT_YUYV422 &&
        (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
-        c->swScale = yuyvToYuv420Wrapper;
+        c->swscale = yuyvToYuv420Wrapper;
     if (srcFormat == AV_PIX_FMT_UYVY422 &&
        (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P))
-        c->swScale = uyvyToYuv420Wrapper;
+        c->swscale = uyvyToYuv420Wrapper;
     if (srcFormat == AV_PIX_FMT_YUYV422 && dstFormat == AV_PIX_FMT_YUV422P)
-        c->swScale = yuyvToYuv422Wrapper;
+        c->swscale = yuyvToYuv422Wrapper;
     if (srcFormat == AV_PIX_FMT_UYVY422 && dstFormat == AV_PIX_FMT_YUV422P)
-        c->swScale = uyvyToYuv422Wrapper;
+        c->swscale = uyvyToYuv422Wrapper;
 
     /* simple copy */
     if ( srcFormat == dstFormat ||
@@ -998,15 +1084,15 @@ void ff_get_unscaled_swscale(SwsContext *c)
          srcFormat != AV_PIX_FMT_NV12 && srcFormat != AV_PIX_FMT_NV21))
     {
         if (isPacked(c->srcFormat))
-            c->swScale = packedCopyWrapper;
+            c->swscale = packedCopyWrapper;
         else /* Planar YUV or gray */
-            c->swScale = planarCopyWrapper;
+            c->swscale = planarCopyWrapper;
     }
 
     if (ARCH_BFIN)
-        ff_bfin_get_unscaled_swscale(c);
-    if (HAVE_ALTIVEC)
-        ff_swscale_get_unscaled_altivec(c);
+        ff_get_unscaled_swscale_bfin(c);
+    if (ARCH_PPC)
+        ff_get_unscaled_swscale_ppc(c);
 }
 
 static void reset_ptr(const uint8_t *src[], int format)
@@ -1149,7 +1235,7 @@ int attribute_align_arg sws_scale(struct SwsContext *c,
         if (srcSliceY + srcSliceH == c->srcH)
             c->sliceDir = 0;
 
-        return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
+        return c->swscale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
                           dstStride2);
     } else {
         // slices go from bottom to top => we flip the image internally
@@ -1175,7 +1261,7 @@ int attribute_align_arg sws_scale(struct SwsContext *c,
         if (!srcSliceY)
             c->sliceDir = 0;
 
-        return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
+        return c->swscale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
                           srcSliceH, dst2, dstStride2);
     }
 }
diff --git a/libswscale/utils.c b/libswscale/utils.c
index f0a2b46..2111fc2 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -45,6 +45,7 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/ppc/cpu.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
 #include "rgb2rgb.h"
@@ -70,7 +71,9 @@ const char *swscale_license(void)
 #define RET 0xC3 // near return opcode for x86
 
 typedef struct FormatEntry {
-    int is_supported_in, is_supported_out;
+    uint8_t is_supported_in         :1;
+    uint8_t is_supported_out        :1;
+    uint8_t is_supported_endianness :1;
 } FormatEntry;
 
 static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
@@ -163,13 +166,15 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
     [AV_PIX_FMT_YUV444P9LE]  = { 1, 1 },
     [AV_PIX_FMT_YUV444P10BE] = { 1, 1 },
     [AV_PIX_FMT_YUV444P10LE] = { 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_GBRP]        = { 1, 1 },
+    [AV_PIX_FMT_GBRP9LE]     = { 1, 1 },
+    [AV_PIX_FMT_GBRP9BE]     = { 1, 1 },
+    [AV_PIX_FMT_GBRP10LE]    = { 1, 1 },
+    [AV_PIX_FMT_GBRP10BE]    = { 1, 1 },
     [AV_PIX_FMT_GBRP16LE]    = { 1, 0 },
     [AV_PIX_FMT_GBRP16BE]    = { 1, 0 },
+    [AV_PIX_FMT_XYZ12BE]     = { 0, 0, 1 },
+    [AV_PIX_FMT_XYZ12LE]     = { 0, 0, 1 },
 };
 
 int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
@@ -184,7 +189,11 @@ int sws_isSupportedOutput(enum AVPixelFormat pix_fmt)
            format_entries[pix_fmt].is_supported_out : 0;
 }
 
-extern const int32_t ff_yuv2rgb_coeffs[8][4];
+int sws_isSupportedEndiannessConversion(enum AVPixelFormat pix_fmt)
+{
+    return (unsigned)pix_fmt < AV_PIX_FMT_NB ?
+           format_entries[pix_fmt].is_supported_endianness : 0;
+}
 
 const char *sws_format_name(enum AVPixelFormat format)
 {
@@ -208,11 +217,12 @@ static double getSplineCoeff(double a, double b, double c, double d,
                               dist - 1.0);
 }
 
-static int initFilter(int16_t **outFilter, int32_t **filterPos,
-                      int *outFilterSize, int xInc, int srcW, int dstW,
-                      int filterAlign, int one, int flags, int cpu_flags,
-                      SwsVector *srcFilter, SwsVector *dstFilter,
-                      double param[2], int is_horizontal)
+static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos,
+                              int *outFilterSize, int xInc, int srcW,
+                              int dstW, int filterAlign, int one,
+                              int flags, int cpu_flags,
+                              SwsVector *srcFilter, SwsVector *dstFilter,
+                              double param[2], int is_horizontal)
 {
     int i;
     int filterSize;
@@ -483,7 +493,7 @@ static int initFilter(int16_t **outFilter, int32_t **filterPos,
             minFilterSize = min;
     }
 
-    if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) {
+    if (PPC_ALTIVEC(cpu_flags)) {
         // we can handle the special case 4, so we don't want to go the full 8
         if (minFilterSize < 5)
             filterAlign = 4;
@@ -600,9 +610,9 @@ fail:
 }
 
 #if HAVE_MMXEXT_INLINE
-static int init_hscaler_mmxext(int dstW, int xInc, uint8_t *filterCode,
-                               int16_t *filter, int32_t *filterPos,
-                               int numSplits)
+static av_cold int init_hscaler_mmxext(int dstW, int xInc, uint8_t *filterCode,
+                                       int16_t *filter, int32_t *filterPos,
+                                       int numSplits)
 {
     uint8_t *fragmentA;
     x86_reg imm8OfPShufW1A;
@@ -796,9 +806,9 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
                              contrast, saturation);
     // FIXME factorize
 
-    if (HAVE_ALTIVEC && av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC)
-        ff_yuv2rgb_init_tables_altivec(c, inv_table, brightness,
-                                       contrast, saturation);
+    if (ARCH_PPC)
+        ff_yuv2rgb_init_tables_ppc(c, inv_table, brightness,
+                                   contrast, saturation);
     return 0;
 }
 
@@ -879,6 +889,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
 
     unscaled = (srcW == dstW && srcH == dstH);
 
+    if (!(unscaled && sws_isSupportedEndiannessConversion(srcFormat) &&
+          av_pix_fmt_swap_endianness(srcFormat) == dstFormat)) {
     if (!sws_isSupportedInput(srcFormat)) {
         av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n",
                sws_format_name(srcFormat));
@@ -889,6 +901,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
                sws_format_name(dstFormat));
         return AVERROR(EINVAL);
     }
+    }
 
     i = flags & (SWS_POINT         |
                  SWS_AREA          |
@@ -901,7 +914,17 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
                  SWS_SINC          |
                  SWS_SPLINE        |
                  SWS_BICUBLIN);
-    if (!i || (i & (i - 1))) {
+
+    /* provide a default scaler if not set by caller */
+    if (!i) {
+        if (dstW < srcW && dstH < srcH)
+            flags |= SWS_GAUSS;
+        else if (dstW > srcW && dstH > srcH)
+            flags |= SWS_SINC;
+        else
+            flags |= SWS_LANCZOS;
+        c->flags = flags;
+    } else if (i & (i - 1)) {
         av_log(c, AV_LOG_ERROR,
                "Exactly one scaler algorithm must be chosen\n");
         return AVERROR(EINVAL);
@@ -938,10 +961,21 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
     getSubSampleFactors(&c->chrSrcHSubSample, &c->chrSrcVSubSample, srcFormat);
     getSubSampleFactors(&c->chrDstHSubSample, &c->chrDstVSubSample, dstFormat);
 
+    if (isPlanarRGB(dstFormat)) {
+        if (!(flags & SWS_FULL_CHR_H_INT)) {
+            av_log(c, AV_LOG_DEBUG,
+                   "%s output is not supported with half chroma resolution, switching to full\n",
+                   av_get_pix_fmt_name(dstFormat));
+            flags   |= SWS_FULL_CHR_H_INT;
+            c->flags = flags;
+        }
+    }
+
     /* reuse chroma for 2 pixels RGB/BGR unless user wants full
      * chroma interpolation */
     if (flags & SWS_FULL_CHR_H_INT &&
         isAnyRGB(dstFormat)        &&
+        !isPlanarRGB(dstFormat)    &&
         dstFormat != AV_PIX_FMT_RGBA  &&
         dstFormat != AV_PIX_FMT_ARGB  &&
         dstFormat != AV_PIX_FMT_BGRA  &&
@@ -968,6 +1002,9 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
         srcFormat != AV_PIX_FMT_RGB8 && srcFormat != AV_PIX_FMT_BGR8 &&
         srcFormat != AV_PIX_FMT_RGB4 && srcFormat != AV_PIX_FMT_BGR4 &&
         srcFormat != AV_PIX_FMT_RGB4_BYTE && srcFormat != AV_PIX_FMT_BGR4_BYTE &&
+        srcFormat != AV_PIX_FMT_GBRP9BE   && srcFormat != AV_PIX_FMT_GBRP9LE  &&
+        srcFormat != AV_PIX_FMT_GBRP10BE  && srcFormat != AV_PIX_FMT_GBRP10LE &&
+        srcFormat != AV_PIX_FMT_GBRP16BE  && srcFormat != AV_PIX_FMT_GBRP16LE &&
         ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) ||
          (flags & SWS_FAST_BILINEAR)))
         c->chrSrcHSubSample = 1;
@@ -983,7 +1020,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
         (c->srcRange == c->dstRange || isAnyRGB(dstFormat))) {
         ff_get_unscaled_swscale(c);
 
-        if (c->swScale) {
+        if (c->swscale) {
             if (flags & SWS_PRINT_INFO)
                 av_log(c, AV_LOG_INFO,
                        "using unscaled %s -> %s special converter\n",
@@ -1093,10 +1130,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
         } else
 #endif /* HAVE_MMXEXT_INLINE */
         {
-            const int filterAlign =
-                (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 4 :
-                (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
-                1;
+            const int filterAlign = X86_MMX(cpu_flags)     ? 4 :
+                                    PPC_ALTIVEC(cpu_flags) ? 8 : 1;
 
             if (initFilter(&c->hLumFilter, &c->hLumFilterPos,
                            &c->hLumFilterSize, c->lumXInc,
@@ -1117,10 +1152,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
 
     /* precalculate vertical scaler filter coefficients */
     {
-        const int filterAlign =
-            (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) ? 2 :
-            (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) ? 8 :
-            1;
+        const int filterAlign = X86_MMX(cpu_flags)     ? 2 :
+                                PPC_ALTIVEC(cpu_flags) ? 8 : 1;
 
         if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize,
                        c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
@@ -1257,7 +1290,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
             av_log(c, AV_LOG_INFO, "using 3DNOW\n");
         else if (INLINE_MMX(cpu_flags))
             av_log(c, AV_LOG_INFO, "using MMX\n");
-        else if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC)
+        else if (PPC_ALTIVEC(cpu_flags))
             av_log(c, AV_LOG_INFO, "using AltiVec\n");
         else
             av_log(c, AV_LOG_INFO, "using C\n");
@@ -1272,7 +1305,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
                c->chrXInc, c->chrYInc);
     }
 
-    c->swScale = ff_getSwsFunc(c);
+    c->swscale = ff_getSwsFunc(c);
     return 0;
 fail: // FIXME replace things by appropriate error codes
     return -1;
diff --git a/libswscale/version.h b/libswscale/version.h
index acbdf6b..5483673 100644
--- a/libswscale/version.h
+++ b/libswscale/version.h
@@ -28,7 +28,7 @@
 
 #define LIBSWSCALE_VERSION_MAJOR 2
 #define LIBSWSCALE_VERSION_MINOR 1
-#define LIBSWSCALE_VERSION_MICRO 1
+#define LIBSWSCALE_VERSION_MICRO 2
 
 #define LIBSWSCALE_VERSION_INT  AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
                                                LIBSWSCALE_VERSION_MINOR, \
diff --git a/libswscale/x86/Makefile b/libswscale/x86/Makefile
index 5416d48..b94b14a 100644
--- a/libswscale/x86/Makefile
+++ b/libswscale/x86/Makefile
@@ -1,9 +1,9 @@
-OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o
-
-MMX-OBJS                        += x86/rgb2rgb.o                        \
+OBJS                            += x86/rgb2rgb.o                        \
                                    x86/swscale.o                        \
                                    x86/yuv2rgb.o                        \
 
+OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o
+
 YASM-OBJS                       += x86/input.o                          \
                                    x86/output.o                         \
                                    x86/scale.o                          \
diff --git a/libswscale/x86/input.asm b/libswscale/x86/input.asm
index a8d5a5a..6f5677e 100644
--- a/libswscale/x86/input.asm
+++ b/libswscale/x86/input.asm
@@ -98,7 +98,7 @@ cglobal %2 %+ 24ToY, 3, 3, %1, dst, src, w
 %define coeff2 [%2_Ycoeff_3x56]
 %endif ; x86-32/64 && mmsize == 8/16
 %if (ARCH_X86_64 || mmsize == 8) && %0 == 3
-    jmp mangle(program_name %+ _ %+ %3 %+ 24ToY %+ SUFFIX).body
+    jmp mangle(private_prefix %+ _ %+ %3 %+ 24ToY %+ SUFFIX).body
 %else ; (ARCH_X86_64 && %0 == 3) || mmsize == 8
 .body:
 %if cpuflag(ssse3)
@@ -188,7 +188,7 @@ cglobal %2 %+ 24ToUV, 3, 4, %1, dstU, dstV, src, w
 %define coeffV2 [%2_Vcoeff_3x56]
 %endif ; x86-32/64
 %if ARCH_X86_64 && %0 == 3
-    jmp mangle(program_name %+ _ %+ %3 %+ 24ToUV %+ SUFFIX).body
+    jmp mangle(private_prefix %+ _ %+ %3 %+ 24ToUV %+ SUFFIX).body
 %else ; ARCH_X86_64 && %0 == 3
 .body:
 %if cpuflag(ssse3)
@@ -315,7 +315,7 @@ cglobal %2%3%4%5 %+ ToY, 3, 3, %1, dst, src, w
     mova           m5, [rgba_Ycoeff_%2%4]
     mova           m6, [rgba_Ycoeff_%3%5]
 %if %0 == 6
-    jmp mangle(program_name %+ _ %+ %6 %+ ToY %+ SUFFIX).body
+    jmp mangle(private_prefix %+ _ %+ %6 %+ ToY %+ SUFFIX).body
 %else ; %0 == 6
 .body:
 %if ARCH_X86_64
@@ -371,7 +371,7 @@ cglobal %2%3%4%5 %+ ToUV, 3, 4, %1, dstU, dstV, src, w
 %define coeffV2 [rgba_Vcoeff_%3%5]
 %endif ; x86-64/32
 %if ARCH_X86_64 && %0 == 6
-    jmp mangle(program_name %+ _ %+ %6 %+ ToUV %+ SUFFIX).body
+    jmp mangle(private_prefix %+ _ %+ %6 %+ ToUV %+ SUFFIX).body
 %else ; ARCH_X86_64 && %0 == 6
 .body:
 %if ARCH_X86_64
diff --git a/libswscale/x86/rgb2rgb.c b/libswscale/x86/rgb2rgb.c
index d4f2580..98cf1ff 100644
--- a/libswscale/x86/rgb2rgb.c
+++ b/libswscale/x86/rgb2rgb.c
@@ -92,21 +92,21 @@ DECLARE_ASM_CONST(8, uint64_t, blue_15mask)  = 0x0000001f0000001fULL;
 
 //MMX versions
 #undef RENAME
-#define RENAME(a) a ## _MMX
+#define RENAME(a) a ## _mmx
 #include "rgb2rgb_template.c"
 
 // MMXEXT versions
 #undef RENAME
 #undef COMPILE_TEMPLATE_MMXEXT
 #define COMPILE_TEMPLATE_MMXEXT 1
-#define RENAME(a) a ## _MMXEXT
+#define RENAME(a) a ## _mmxext
 #include "rgb2rgb_template.c"
 
 //SSE2 versions
 #undef RENAME
 #undef COMPILE_TEMPLATE_SSE2
 #define COMPILE_TEMPLATE_SSE2 1
-#define RENAME(a) a ## _SSE2
+#define RENAME(a) a ## _sse2
 #include "rgb2rgb_template.c"
 
 //3DNOW versions
@@ -117,7 +117,7 @@ DECLARE_ASM_CONST(8, uint64_t, blue_15mask)  = 0x0000001f0000001fULL;
 #define COMPILE_TEMPLATE_MMXEXT 0
 #define COMPILE_TEMPLATE_SSE2 0
 #define COMPILE_TEMPLATE_AMD3DNOW 1
-#define RENAME(a) a ## _3DNOW
+#define RENAME(a) a ## _3dnow
 #include "rgb2rgb_template.c"
 
 /*
@@ -135,12 +135,12 @@ av_cold void rgb2rgb_init_x86(void)
     int cpu_flags = av_get_cpu_flags();
 
     if (INLINE_MMX(cpu_flags))
-        rgb2rgb_init_MMX();
+        rgb2rgb_init_mmx();
     if (INLINE_AMD3DNOW(cpu_flags))
-        rgb2rgb_init_3DNOW();
+        rgb2rgb_init_3dnow();
     if (INLINE_MMXEXT(cpu_flags))
-        rgb2rgb_init_MMXEXT();
+        rgb2rgb_init_mmxext();
     if (INLINE_SSE2(cpu_flags))
-        rgb2rgb_init_SSE2();
+        rgb2rgb_init_sse2();
 #endif /* HAVE_INLINE_ASM */
 }
diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c
index 205b749..5aeef8c 100644
--- a/libswscale/x86/rgb2rgb_template.c
+++ b/libswscale/x86/rgb2rgb_template.c
@@ -26,6 +26,8 @@
 
 #include <stddef.h>
 
+#include "libavutil/attributes.h"
+
 #undef PREFETCH
 #undef MOVNTQ
 #undef EMMS
@@ -2465,7 +2467,7 @@ static void RENAME(uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, co
 #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
 #endif /* !COMPILE_TEMPLATE_SSE2 */
 
-static inline void RENAME(rgb2rgb_init)(void)
+static av_cold void RENAME(rgb2rgb_init)(void)
 {
 #if !COMPILE_TEMPLATE_SSE2
 #if !COMPILE_TEMPLATE_AMD3DNOW
diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c
index c48e56d..b14d97d 100644
--- a/libswscale/x86/swscale.c
+++ b/libswscale/x86/swscale.c
@@ -74,7 +74,7 @@ DECLARE_ALIGNED(8, const uint64_t, ff_w1111)        = 0x0001000100010001ULL;
 #if HAVE_MMX_INLINE
 #undef RENAME
 #define COMPILE_TEMPLATE_MMXEXT 0
-#define RENAME(a) a ## _MMX
+#define RENAME(a) a ## _mmx
 #include "swscale_template.c"
 #endif
 
@@ -83,7 +83,7 @@ DECLARE_ALIGNED(8, const uint64_t, ff_w1111)        = 0x0001000100010001ULL;
 #undef RENAME
 #undef COMPILE_TEMPLATE_MMXEXT
 #define COMPILE_TEMPLATE_MMXEXT 1
-#define RENAME(a) a ## _MMXEXT
+#define RENAME(a) a ## _mmxext
 #include "swscale_template.c"
 #endif
 
@@ -206,7 +206,7 @@ void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufI
 #endif /* HAVE_INLINE_ASM */
 
 #define SCALE_FUNC(filter_n, from_bpc, to_bpc, opt) \
-extern void ff_hscale ## from_bpc ## to ## to_bpc ## _ ## filter_n ## _ ## opt( \
+void ff_hscale ## from_bpc ## to ## to_bpc ## _ ## filter_n ## _ ## opt( \
                                                 SwsContext *c, int16_t *data, \
                                                 int dstW, const uint8_t *src, \
                                                 const int16_t *filter, \
@@ -241,9 +241,9 @@ SCALE_FUNCS_SSE(ssse3);
 SCALE_FUNCS_SSE(sse4);
 
 #define VSCALEX_FUNC(size, opt) \
-extern void ff_yuv2planeX_ ## size ## _ ## opt(const int16_t *filter, int filterSize, \
-                                               const int16_t **src, uint8_t *dest, int dstW, \
-                                               const uint8_t *dither, int offset)
+void ff_yuv2planeX_ ## size ## _ ## opt(const int16_t *filter, int filterSize, \
+                                        const int16_t **src, uint8_t *dest, int dstW, \
+                                        const uint8_t *dither, int offset)
 #define VSCALEX_FUNCS(opt) \
     VSCALEX_FUNC(8,  opt); \
     VSCALEX_FUNC(9,  opt); \
@@ -258,8 +258,8 @@ VSCALEX_FUNC(16, sse4);
 VSCALEX_FUNCS(avx);
 
 #define VSCALE_FUNC(size, opt) \
-extern void ff_yuv2plane1_ ## size ## _ ## opt(const int16_t *src, uint8_t *dst, int dstW, \
-                                               const uint8_t *dither, int offset)
+void ff_yuv2plane1_ ## size ## _ ## opt(const int16_t *src, uint8_t *dst, int dstW, \
+                                        const uint8_t *dither, int offset)
 #define VSCALE_FUNCS(opt1, opt2) \
     VSCALE_FUNC(8,  opt1); \
     VSCALE_FUNC(9,  opt2); \
@@ -274,12 +274,12 @@ VSCALE_FUNC(16, sse4);
 VSCALE_FUNCS(avx, avx);
 
 #define INPUT_Y_FUNC(fmt, opt) \
-extern void ff_ ## fmt ## ToY_  ## opt(uint8_t *dst, const uint8_t *src, \
-                                       int w, uint32_t *unused)
+void ff_ ## fmt ## ToY_  ## opt(uint8_t *dst, const uint8_t *src, \
+                                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)
+void ff_ ## fmt ## ToUV_ ## opt(uint8_t *dstU, uint8_t *dstV, \
+                                const uint8_t *src, const uint8_t *unused1, \
+                                int w, uint32_t *unused2)
 #define INPUT_FUNC(fmt, opt) \
     INPUT_Y_FUNC(fmt, opt); \
     INPUT_UV_FUNC(fmt, opt)
@@ -302,18 +302,18 @@ INPUT_FUNCS(sse2);
 INPUT_FUNCS(ssse3);
 INPUT_FUNCS(avx);
 
-av_cold void ff_sws_init_swScale_mmx(SwsContext *c)
+av_cold void ff_sws_init_swscale_x86(SwsContext *c)
 {
     int cpu_flags = av_get_cpu_flags();
 
-#if HAVE_INLINE_ASM
+#if HAVE_MMX_INLINE
     if (cpu_flags & AV_CPU_FLAG_MMX)
-        sws_init_swScale_MMX(c);
+        sws_init_swscale_mmx(c);
+#endif
 #if HAVE_MMXEXT_INLINE
     if (cpu_flags & AV_CPU_FLAG_MMXEXT)
-        sws_init_swScale_MMXEXT(c);
+        sws_init_swscale_mmxext(c);
 #endif
-#endif /* HAVE_INLINE_ASM */
 
 #define ASSIGN_SCALE_FUNC2(hscalefn, filtersize, opt1, opt2) do { \
     if (c->srcBpc == 8) { \
diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c
index d89a26f..80a3ad9 100644
--- a/libswscale/x86/swscale_template.c
+++ b/libswscale/x86/swscale_template.c
@@ -1555,7 +1555,7 @@ static void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst1, int16_t *dst2,
 }
 #endif /* COMPILE_TEMPLATE_MMXEXT */
 
-static av_cold void RENAME(sws_init_swScale)(SwsContext *c)
+static av_cold void RENAME(sws_init_swscale)(SwsContext *c)
 {
     enum AVPixelFormat dstFormat = c->dstFormat;
 
diff --git a/libswscale/x86/yuv2rgb.c b/libswscale/x86/yuv2rgb.c
index 419d513..6f4f7f5 100644
--- a/libswscale/x86/yuv2rgb.c
+++ b/libswscale/x86/yuv2rgb.c
@@ -54,7 +54,7 @@ DECLARE_ASM_CONST(8, uint64_t, pb_07) = 0x0707070707070707ULL;
 #undef RENAME
 #undef COMPILE_TEMPLATE_MMXEXT
 #define COMPILE_TEMPLATE_MMXEXT 0
-#define RENAME(a) a ## _MMX
+#define RENAME(a) a ## _mmx
 #include "yuv2rgb_template.c"
 #endif /* HAVE_MMX_INLINE */
 
@@ -63,15 +63,15 @@ DECLARE_ASM_CONST(8, uint64_t, pb_07) = 0x0707070707070707ULL;
 #undef RENAME
 #undef COMPILE_TEMPLATE_MMXEXT
 #define COMPILE_TEMPLATE_MMXEXT 1
-#define RENAME(a) a ## _MMXEXT
+#define RENAME(a) a ## _mmxext
 #include "yuv2rgb_template.c"
 #endif /* HAVE_MMXEXT_INLINE */
 
 #endif /* HAVE_INLINE_ASM */
 
-av_cold SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c)
+av_cold SwsFunc ff_yuv2rgb_init_x86(SwsContext *c)
 {
-#if HAVE_INLINE_ASM
+#if HAVE_MMX_INLINE
     int cpu_flags = av_get_cpu_flags();
 
     if (c->srcFormat != AV_PIX_FMT_YUV420P &&
@@ -82,9 +82,9 @@ av_cold SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c)
     if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
         switch (c->dstFormat) {
         case AV_PIX_FMT_RGB24:
-            return yuv420_rgb24_MMXEXT;
+            return yuv420_rgb24_mmxext;
         case AV_PIX_FMT_BGR24:
-            return yuv420_bgr24_MMXEXT;
+            return yuv420_bgr24_mmxext;
         }
     }
 #endif
@@ -94,24 +94,30 @@ av_cold SwsFunc ff_yuv2rgb_init_mmx(SwsContext *c)
             case AV_PIX_FMT_RGB32:
                 if (c->srcFormat == AV_PIX_FMT_YUVA420P) {
 #if HAVE_7REGS && CONFIG_SWSCALE_ALPHA
-                    return yuva420_rgb32_MMX;
+                    return yuva420_rgb32_mmx;
 #endif
                     break;
-                } else return yuv420_rgb32_MMX;
+                } else
+                    return yuv420_rgb32_mmx;
             case AV_PIX_FMT_BGR32:
                 if (c->srcFormat == AV_PIX_FMT_YUVA420P) {
 #if HAVE_7REGS && CONFIG_SWSCALE_ALPHA
-                    return yuva420_bgr32_MMX;
+                    return yuva420_bgr32_mmx;
 #endif
                     break;
-                } else return yuv420_bgr32_MMX;
-            case AV_PIX_FMT_RGB24:  return yuv420_rgb24_MMX;
-            case AV_PIX_FMT_BGR24:  return yuv420_bgr24_MMX;
-            case AV_PIX_FMT_RGB565: return yuv420_rgb16_MMX;
-            case AV_PIX_FMT_RGB555: return yuv420_rgb15_MMX;
+                } else
+                    return yuv420_bgr32_mmx;
+            case AV_PIX_FMT_RGB24:
+                return yuv420_rgb24_mmx;
+            case AV_PIX_FMT_BGR24:
+                return yuv420_bgr24_mmx;
+            case AV_PIX_FMT_RGB565:
+                return yuv420_rgb16_mmx;
+            case AV_PIX_FMT_RGB555:
+                return yuv420_rgb15_mmx;
         }
     }
-#endif /* HAVE_INLINE_ASM */
+#endif /* HAVE_MMX_INLINE */
 
     return NULL;
 }
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index 2ffbf5b..f939bbe 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -35,11 +35,6 @@
 #include "swscale.h"
 #include "swscale_internal.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];
-
 const int32_t ff_yuv2rgb_coeffs[8][4] = {
     { 117504, 138453, 13954, 34903 }, /* no sequence_display_extension */
     { 117504, 138453, 13954, 34903 }, /* ITU-R Rec. 709 (1990) */
@@ -274,8 +269,8 @@ YUV2RGBFUNC(yuva2rgba_c, uint32_t, 1)
     LOADCHROMA(3);
     PUTRGBA(dst_2, py_2, pa_2, 3, 24);
     PUTRGBA(dst_1, py_1, pa_1, 3, 24);
-    pa_1 += 8; \
-    pa_2 += 8; \
+    pa_1 += 8;
+    pa_2 += 8;
 ENDYUV2RGBLINE(8, 0)
     LOADCHROMA(0);
     PUTRGBA(dst_1, py_1, pa_1, 0, 24);
@@ -284,8 +279,8 @@ ENDYUV2RGBLINE(8, 0)
     LOADCHROMA(1);
     PUTRGBA(dst_2, py_2, pa_2, 1, 24);
     PUTRGBA(dst_1, py_1, pa_1, 1, 24);
-    pa_1 += 4; \
-    pa_2 += 4; \
+    pa_1 += 4;
+    pa_2 += 4;
 ENDYUV2RGBLINE(8, 1)
     LOADCHROMA(0);
     PUTRGBA(dst_1, py_1, pa_1, 0, 24);
@@ -308,8 +303,8 @@ YUV2RGBFUNC(yuva2argb_c, uint32_t, 1)
     LOADCHROMA(3);
     PUTRGBA(dst_2, py_2, pa_2, 3, 0);
     PUTRGBA(dst_1, py_1, pa_1, 3, 0);
-    pa_1 += 8; \
-    pa_2 += 8; \
+    pa_1 += 8;
+    pa_2 += 8;
 ENDYUV2RGBLINE(8, 0)
     LOADCHROMA(0);
     PUTRGBA(dst_1, py_1, pa_1, 0, 0);
@@ -318,8 +313,8 @@ ENDYUV2RGBLINE(8, 0)
     LOADCHROMA(1);
     PUTRGBA(dst_2, py_2, pa_2, 1, 0);
     PUTRGBA(dst_1, py_1, pa_1, 1, 0);
-    pa_1 += 4; \
-    pa_2 += 4; \
+    pa_1 += 4;
+    pa_2 += 4;
 ENDYUV2RGBLINE(8, 1)
     LOADCHROMA(0);
     PUTRGBA(dst_1, py_1, pa_1, 0, 0);
@@ -409,7 +404,7 @@ CLOSEYUV2RGBFUNC(8)
 
 // r, g, b, dst_1, dst_2
 YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
-    const uint8_t *d16 = dither_4x4_16[y & 3];
+    const uint8_t *d16 = ff_dither_4x4_16[y & 3];
 
 #define PUTRGB12(dst, src, i, o)                    \
     Y              = src[2 * i];                    \
@@ -440,8 +435,8 @@ CLOSEYUV2RGBFUNC(8)
 
 // r, g, b, dst_1, dst_2
 YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
-    const uint8_t *d32 = dither_8x8_32[y & 7];
-    const uint8_t *d64 = dither_8x8_73[y & 7];
+    const uint8_t *d32 = ff_dither_8x8_32[y & 7];
+    const uint8_t *d64 = ff_dither_8x8_73[y & 7];
 
 #define PUTRGB8(dst, src, i, o)                     \
     Y              = src[2 * i];                    \
@@ -471,8 +466,8 @@ YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
 CLOSEYUV2RGBFUNC(8)
 
 YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
-    const uint8_t * d64 = dither_8x8_73[y & 7];
-    const uint8_t *d128 = dither_8x8_220[y & 7];
+    const uint8_t * d64 = ff_dither_8x8_73[y & 7];
+    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
     int acc;
 
 #define PUTRGB4D(dst, src, i, o)                    \
@@ -504,8 +499,8 @@ YUV2RGBFUNC(yuv2rgb_c_4_ordered_dither, uint8_t, 0)
 CLOSEYUV2RGBFUNC(4)
 
 YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
-    const uint8_t *d64  = dither_8x8_73[y & 7];
-    const uint8_t *d128 = dither_8x8_220[y & 7];
+    const uint8_t *d64  = ff_dither_8x8_73[y & 7];
+    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
 
 #define PUTRGB4DB(dst, src, i, o)                   \
     Y              = src[2 * i];                    \
@@ -535,7 +530,7 @@ YUV2RGBFUNC(yuv2rgb_c_4b_ordered_dither, uint8_t, 0)
 CLOSEYUV2RGBFUNC(8)
 
 YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
-    const uint8_t *d128 = dither_8x8_220[y & 7];
+    const uint8_t *d128 = ff_dither_8x8_220[y & 7];
     char out_1 = 0, out_2 = 0;
     g = c->table_gU[128] + c->table_gV[128];
 
@@ -565,14 +560,14 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
 {
     SwsFunc t = NULL;
 
-    if (HAVE_MMX)
-        t = ff_yuv2rgb_init_mmx(c);
-    else if (HAVE_VIS)
+    if (ARCH_BFIN)
+        t = ff_yuv2rgb_init_bfin(c);
+    if (ARCH_PPC)
+        t = ff_yuv2rgb_init_ppc(c);
+    if (HAVE_VIS)
         t = ff_yuv2rgb_init_vis(c);
-    else if (HAVE_ALTIVEC)
-        t = ff_yuv2rgb_init_altivec(c);
-    else if (ARCH_BFIN)
-        t = ff_yuv2rgb_get_func_ptr_bfin(c);
+    if (ARCH_X86)
+        t = ff_yuv2rgb_init_x86(c);
 
     if (t)
         return t;
@@ -882,7 +877,8 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4],
         break;
     default:
         c->yuvTable = NULL;
-        av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
+        if(!isPlanar(c->dstFormat) || bpp <= 24)
+            av_log(c, AV_LOG_ERROR, "%ibpp not supported by yuv2rgb\n", bpp);
         return -1;
     }
     return 0;
diff --git a/tests/Makefile b/tests/Makefile
index 8b56b4c..eb31ed1 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,12 +1,12 @@
 VREF = tests/vsynth1/00.pgm
 AREF = tests/data/asynth1.sw
 
-OBJDIRS += tests/data tests/vsynth1
+OBJDIRS += tests/data tests/vsynth1 tests/data/filtergraphs
 
-tests/vsynth1/00.pgm: tests/videogen$(HOSTEXESUF) | tests/vsynth1
+$(VREF): tests/videogen$(HOSTEXESUF) | tests/vsynth1
 	$(M)./$< 'tests/vsynth1/'
 
-tests/data/asynth1.sw: tests/audiogen$(HOSTEXESUF) | tests/data
+$(AREF): tests/audiogen$(HOSTEXESUF) | tests/data
 	$(M)./$< $@
 
 tests/data/asynth-%.wav: tests/audiogen$(HOSTEXESUF) | tests/data
@@ -20,7 +20,14 @@ tests/data/vsynth2.yuv: tests/rotozoom$(HOSTEXESUF) | tests/data
 
 tests/data/asynth% tests/data/vsynth%.yuv tests/vsynth%/00.pgm: TAG = GEN
 
+tests/data/filtergraphs/%: TAG = COPY
+tests/data/filtergraphs/%: $(SRC_PATH)/tests/filtergraphs/% | tests/data/filtergraphs
+	$(M)cp $< $@
+
+# Check sanity of dependencies when running FATE tests.
+ifneq (,$(filter check fate%,$(filter-out fate-rsync,$(MAKECMDGOALS))))
 CHKCFG  = $(if $($(1))$(!$(1)),$($(1)), $(error No such config: $(1)))
+endif
 
 ALLYES  = $(strip $(call XYES, $(1)))
 XYES    = $(if $(strip $(1)),                                           \
@@ -38,10 +45,17 @@ ENCDEC2 = $(call ALLYES, $(firstword $(1))_ENCODER $(lastword $(1))_DECODER  \
 DEMDEC  = $(call ALLYES, $(1)_DEMUXER $(2:%=%_DECODER))
 ENCMUX  = $(call ALLYES, $(1:%=%_ENCODER) $(2)_MUXER)
 
+DEMMUX  = $(call ALLYES, $(1)_DEMUXER $(2)_MUXER)
+
+FILTERDEMDEC       = $(call ALLYES, $(1)_FILTER $(2)_DEMUXER $(3)_DECODER)
+FILTERDEMDECMUX    = $(call ALLYES, $(1)_FILTER $(2)_DEMUXER $(3)_DECODER $(4)_MUXER)
+FILTERDEMDECENCMUX = $(call ALLYES, $(1)_FILTER $(2)_DEMUXER $(3)_DECODER $(4)_ENCODER $(5)_MUXER)
+
+PARSERDEMDEC       = $(call ALLYES, $(1)_PARSER $(2)_DEMUXER $(3)_DECODER)
+
 include $(SRC_PATH)/tests/fate/acodec.mak
 include $(SRC_PATH)/tests/fate/vcodec.mak
 include $(SRC_PATH)/tests/fate/avformat.mak
-include $(SRC_PATH)/tests/fate/avfilter.mak
 include $(SRC_PATH)/tests/fate/seek.mak
 
 include $(SRC_PATH)/tests/fate/aac.mak
@@ -60,18 +74,23 @@ include $(SRC_PATH)/tests/fate/demux.mak
 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/filter.mak
+include $(SRC_PATH)/tests/fate/filter-audio.mak
+include $(SRC_PATH)/tests/fate/filter-video.mak
 include $(SRC_PATH)/tests/fate/flac.mak
 include $(SRC_PATH)/tests/fate/fft.mak
 include $(SRC_PATH)/tests/fate/h264.mak
+include $(SRC_PATH)/tests/fate/hevc.mak
 include $(SRC_PATH)/tests/fate/image.mak
 include $(SRC_PATH)/tests/fate/indeo.mak
 include $(SRC_PATH)/tests/fate/libavcodec.mak
+include $(SRC_PATH)/tests/fate/libavdevice.mak
 include $(SRC_PATH)/tests/fate/libavformat.mak
+include $(SRC_PATH)/tests/fate/libavresample.mak
 include $(SRC_PATH)/tests/fate/libavutil.mak
 include $(SRC_PATH)/tests/fate/lossless-audio.mak
 include $(SRC_PATH)/tests/fate/lossless-video.mak
 include $(SRC_PATH)/tests/fate/microsoft.mak
+include $(SRC_PATH)/tests/fate/monkeysaudio.mak
 include $(SRC_PATH)/tests/fate/mp3.mak
 include $(SRC_PATH)/tests/fate/mpc.mak
 include $(SRC_PATH)/tests/fate/pcm.mak
@@ -104,7 +123,7 @@ $(FATE_AVCONV) $(FATE_SAMPLES_AVCONV): avconv$(EXESUF)
 ifdef SAMPLES
 FATE += $(FATE_SAMPLES)
 fate-rsync:
-	rsync -vaLW rsync://fate-suite.libav.org/fate-suite-9/ $(SAMPLES)
+	rsync -vaLW rsync://fate-suite.libav.org/fate-suite/ $(SAMPLES)
 else
 fate-rsync:
 	@echo "use 'make fate-rsync SAMPLES=/path/to/samples' to sync the fate suite"
@@ -118,11 +137,26 @@ fate: $(FATE)
 
 $(FATE): $(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)'
+	$(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)' '$(GEN)'
 
 fate-list:
 	@printf '%s\n' $(sort $(FATE))
 
+coverage.info: TAG = LCOV
+coverage.info:
+	$(M)lcov -q -d $(CURDIR) -b $(SRC_PATH) --capture | \
+	    sed "s,$(CURDIR)/\./,$(CURDIR)/," > $@
+	$(M)lcov -q --remove $@ "/usr/include*" -o $@
+
+lcov:  TAG = GENHTML
+lcov: coverage.info
+	$(M)genhtml -q -o $(CURDIR)/lcov $<
+
+lcov-reset: TAG = LCOV
+lcov-reset:
+	$(M)lcov -d $(CURDIR) --zerocounters
+	$(Q)$(RM) -f coverage.info
+
 clean:: testclean
 
 testclean:
@@ -132,4 +166,5 @@ testclean:
 
 -include $(wildcard tests/*.d)
 
-.PHONY: fate*
+.PHONY: fate* lcov lcov-reset
+.INTERMEDIATE: coverage.info
diff --git a/tests/audiogen.c b/tests/audiogen.c
index 4fa4656..ce6f785 100644
--- a/tests/audiogen.c
+++ b/tests/audiogen.c
@@ -48,7 +48,7 @@ static unsigned int myrnd(unsigned int *seed_ptr, int n)
 
 #define COS_TABLE_BITS 7
 
-/* integer cosinus */
+/* integer cosine */
 static const unsigned short cos_table[(1 << COS_TABLE_BITS) + 2] = {
     0x8000, 0x7ffe, 0x7ff6, 0x7fea, 0x7fd9, 0x7fc2, 0x7fa7, 0x7f87,
     0x7f62, 0x7f38, 0x7f0a, 0x7ed6, 0x7e9d, 0x7e60, 0x7e1e, 0x7dd6,
@@ -180,7 +180,7 @@ int main(int argc, char **argv)
     if ((ext = strrchr(argv[1], '.')) != NULL && !strcmp(ext, ".wav"))
         put_wav_header(sample_rate, nb_channels, 6 * sample_rate);
 
-    /* 1 second of single freq sinus at 1000 Hz */
+    /* 1 second of single freq sine at 1000 Hz */
     a = 0;
     for (i = 0; i < 1 * sample_rate; i++) {
         v = (int_cos(a) * 10000) >> FRAC_BITS;
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index d1633e8..b6c7384 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -22,6 +22,7 @@ cmp_shift=${12:-0}
 cmp_target=${13:-0}
 size_tolerance=${14:-0}
 cmp_unit=${15:-2}
+gen=${16:-no}
 
 outdir="tests/data/fate"
 outfile="${outdir}/${test}"
@@ -145,19 +146,49 @@ enc_dec(){
     tests/tiny_psnr $srcfile $decfile $cmp_unit $cmp_shift
 }
 
-regtest(){
-    t="${test#$2-}"
-    ref=${base}/ref/$2/$t
-    ${base}/${1}-regression.sh $t $2 $3 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags"
-}
-
 lavftest(){
-    regtest lavf lavf tests/vsynth1
+    t="${test#lavf-}"
+    ref=${base}/ref/lavf/$t
+    ${base}/lavf-regression.sh $t lavf tests/vsynth1 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags"
+}
+
+video_filter(){
+    filters=$1
+    shift
+    label=${test#filter-}
+    raw_src="${target_path}/tests/vsynth1/%02d.pgm"
+    printf '%-20s' $label
+    avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src \
+        $FLAGS $ENC_OPTS -vf "$filters" -vcodec rawvideo $* -f nut md5:
+}
+
+pixdesc(){
+    pix_fmts="$(avconv -pix_fmts list 2>/dev/null | awk 'NR > 8 && /^IO/ { print $2 }' | sort)"
+    for pix_fmt in $pix_fmts; do
+        test=$pix_fmt
+        video_filter "format=$pix_fmt,pixdesctest" -pix_fmt $pix_fmt
+    done
 }
 
-lavfitest(){
-    cleanfiles="tests/data/lavfi/${test#lavfi-}.nut"
-    regtest lavfi lavfi tests/vsynth1
+pixfmts(){
+    filter=${test#filter-pixfmts-}
+    filter_args=$1
+
+    showfiltfmts="$target_exec $target_path/libavfilter/filtfmts-test"
+    exclude_fmts=${outfile}${filter}_exclude_fmts
+    out_fmts=${outfile}${filter}_out_fmts
+
+    # exclude pixel formats which are not supported as input
+    avconv -pix_fmts list 2>/dev/null | awk 'NR > 8 && /^\..\./ { print $2 }' | sort >$exclude_fmts
+    $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ print $3 }' | sort | comm -23 - $exclude_fmts >$out_fmts
+
+    pix_fmts=$($showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ print $3 }' | sort | comm -12 - $out_fmts)
+    for pix_fmt in $pix_fmts; do
+        test=$pix_fmt
+        video_filter "format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt
+    done
+
+    rm $exclude_fmts $out_fmts
 }
 
 mkdir -p "$outdir"
@@ -189,5 +220,11 @@ fi
 
 echo "${test}:${sig:-$err}:$($base64 <$cmpfile):$($base64 <$errfile)" >$repfile
 
+if test $err != 0 && test $gen != "no" ; then
+    echo "GEN     $ref"
+    cp -f "$outfile" "$ref"
+    err=$?
+fi
+
 test $err = 0 && rm -f $outfile $errfile $cmpfile $cleanfiles
 exit $err
diff --git a/tests/fate.sh b/tests/fate.sh
index 86e4178..6e0c0c6 100755
--- a/tests/fate.sh
+++ b/tests/fate.sh
@@ -28,14 +28,14 @@ lock(){
 checkout(){
     case "$repo" in
         file:*|/*) src="${repo#file:}"      ;;
-        git:*)     git clone "$repo" "$src" ;;
+        git:*)     git clone --quiet "$repo" "$src" ;;
     esac
 }
 
 update()(
     cd ${src} || return
     case "$repo" in
-        git:*) git pull --quiet ;;
+        git:*) git fetch --force; git reset --hard origin/master ;;
     esac
 )
 
@@ -48,12 +48,14 @@ configure()(
         ${arch:+--arch=$arch}                                           \
         ${cpu:+--cpu="$cpu"}                                            \
         ${cross_prefix:+--cross-prefix="$cross_prefix"}                 \
+        ${as:+--as="$as"}                                               \
         ${cc:+--cc="$cc"}                                               \
         ${ld:+--ld="$ld"}                                               \
         ${target_os:+--target-os="$target_os"}                          \
         ${sysroot:+--sysroot="$sysroot"}                                \
         ${target_exec:+--target-exec="$target_exec"}                    \
         ${target_path:+--target-path="$target_path"}                    \
+        ${target_samples:+--target-samples="$target_samples"}           \
         ${extra_cflags:+--extra-cflags="$extra_cflags"}                 \
         ${extra_ldflags:+--extra-ldflags="$extra_ldflags"}              \
         ${extra_libs:+--extra-libs="$extra_libs"}                       \
@@ -66,6 +68,7 @@ compile()(
 )
 
 fate()(
+    test "$build_only" = "yes" && return
     cd ${build} || return
     ${make} ${makeopts} -k fate
 )
diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak
index e840bf0..c49106b 100644
--- a/tests/fate/aac.mak
+++ b/tests/fate/aac.mak
@@ -1,56 +1,65 @@
 FATE_AAC += fate-aac-al04_44
-fate-aac-al04_44: CMD = pcm -i $(SAMPLES)/aac/al04_44.mp4
+fate-aac-al04_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al04_44.mp4
 fate-aac-al04_44: REF = $(SAMPLES)/aac/al04_44.s16
 
 FATE_AAC += fate-aac-al05_44
-fate-aac-al05_44: CMD = pcm -i $(SAMPLES)/aac/al05_44.mp4
+fate-aac-al05_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al05_44.mp4
 fate-aac-al05_44: REF = $(SAMPLES)/aac/al05_44.s16
 
 FATE_AAC += fate-aac-al06_44
-fate-aac-al06_44: CMD = pcm -i $(SAMPLES)/aac/al06_44.mp4
+fate-aac-al06_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al06_44.mp4
 fate-aac-al06_44: REF = $(SAMPLES)/aac/al06_44_reorder.s16
 
 FATE_AAC += fate-aac-al07_96
-fate-aac-al07_96: CMD = pcm -i $(SAMPLES)/aac/al07_96.mp4
+fate-aac-al07_96: CMD = pcm -i $(TARGET_SAMPLES)/aac/al07_96.mp4
 fate-aac-al07_96: REF = $(SAMPLES)/aac/al07_96_reorder.s16
 
 FATE_AAC += fate-aac-al15_44
-fate-aac-al15_44: CMD = pcm -i $(SAMPLES)/aac/al15_44.mp4
+fate-aac-al15_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al15_44.mp4
 fate-aac-al15_44: REF = $(SAMPLES)/aac/al15_44_reorder.s16
 
 FATE_AAC += fate-aac-al17_44
-fate-aac-al17_44: CMD = pcm -i $(SAMPLES)/aac/al17_44.mp4
+fate-aac-al17_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al17_44.mp4
 fate-aac-al17_44: REF = $(SAMPLES)/aac/al17_44.s16
 
 FATE_AAC += fate-aac-al18_44
-fate-aac-al18_44: CMD = pcm -i $(SAMPLES)/aac/al18_44.mp4
+fate-aac-al18_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/al18_44.mp4
 fate-aac-al18_44: REF = $(SAMPLES)/aac/al18_44.s16
 
 FATE_AAC += fate-aac-am00_88
-fate-aac-am00_88: CMD = pcm -i $(SAMPLES)/aac/am00_88.mp4
+fate-aac-am00_88: CMD = pcm -i $(TARGET_SAMPLES)/aac/am00_88.mp4
 fate-aac-am00_88: REF = $(SAMPLES)/aac/am00_88.s16
 
 FATE_AAC += fate-aac-am05_44
-fate-aac-am05_44: CMD = pcm -i $(SAMPLES)/aac/am05_44.mp4
+fate-aac-am05_44: CMD = pcm -i $(TARGET_SAMPLES)/aac/am05_44.mp4
 fate-aac-am05_44: REF = $(SAMPLES)/aac/am05_44_reorder.s16
 
 FATE_AAC += fate-aac-al_sbr_hq_cm_48_2
-fate-aac-al_sbr_hq_cm_48_2: CMD = pcm -i $(SAMPLES)/aac/al_sbr_cm_48_2.mp4
+fate-aac-al_sbr_hq_cm_48_2: CMD = pcm -i $(TARGET_SAMPLES)/aac/al_sbr_cm_48_2.mp4
 fate-aac-al_sbr_hq_cm_48_2: REF = $(SAMPLES)/aac/al_sbr_hq_cm_48_2.s16
 
 FATE_AAC += fate-aac-al_sbr_hq_cm_48_5.1
-fate-aac-al_sbr_hq_cm_48_5.1: CMD = pcm -i $(SAMPLES)/aac/al_sbr_cm_48_5.1.mp4
+fate-aac-al_sbr_hq_cm_48_5.1: CMD = pcm -i $(TARGET_SAMPLES)/aac/al_sbr_cm_48_5.1.mp4
 fate-aac-al_sbr_hq_cm_48_5.1: REF = $(SAMPLES)/aac/al_sbr_hq_cm_48_5.1_reorder.s16
 
 FATE_AAC += fate-aac-al_sbr_ps_06_ur
-fate-aac-al_sbr_ps_06_ur: CMD = pcm -i $(SAMPLES)/aac/al_sbr_ps_06_new.mp4
+fate-aac-al_sbr_ps_06_ur: CMD = pcm -i $(TARGET_SAMPLES)/aac/al_sbr_ps_06_new.mp4
 fate-aac-al_sbr_ps_06_ur: REF = $(SAMPLES)/aac/al_sbr_ps_06_ur.s16
 
 FATE_AAC += fate-aac-ap05_48
-fate-aac-ap05_48: CMD = pcm -i $(SAMPLES)/aac/ap05_48.mp4
+fate-aac-ap05_48: CMD = pcm -i $(TARGET_SAMPLES)/aac/ap05_48.mp4
 fate-aac-ap05_48: REF = $(SAMPLES)/aac/ap05_48.s16
 
-fate-aac-ct%: CMD = pcm -i $(SAMPLES)/aac/CT_DecoderCheck/$(@:fate-aac-ct-%=%)
+FATE_AAC += fate-aac-er_ad6000np_44_ep0
+fate-aac-er_ad6000np_44_ep0: CMD = pcm -i $(TARGET_SAMPLES)/aac/er_ad6000np_44_ep0.mp4
+fate-aac-er_ad6000np_44_ep0: REF = $(SAMPLES)/aac/er_ad6000np_44_ep0.s16
+
+FATE_AAC += fate-aac-er_eld2000np_48_ep0
+fate-aac-er_eld2000np_48_ep0: CMD = pcm -i $(TARGET_SAMPLES)/aac/er_eld2000np_48_ep0.mp4
+fate-aac-er_eld2000np_48_ep0: REF = $(SAMPLES)/aac/er_eld2000np_48_ep0.s16
+
+
+fate-aac-ct%: CMD = pcm -i $(TARGET_SAMPLES)/aac/CT_DecoderCheck/$(@:fate-aac-ct-%=%)
 fate-aac-ct%: REF = $(SAMPLES)/aac/CT_DecoderCheck/aacPlusv2.wav
 
 FATE_AAC_CT_RAW = fate-aac-ct-sbr_i-ps_i.aac
@@ -65,11 +74,11 @@ FATE_AAC_CT = sbr_bc-ps_i.3gp  \
 FATE_AAC += $(FATE_AAC_CT:%=fate-aac-ct-%)
 
 FATE_AAC_LATM += fate-aac-latm_000000001180bc60
-fate-aac-latm_000000001180bc60: CMD = pcm -i $(SAMPLES)/aac/latm_000000001180bc60.mpg
+fate-aac-latm_000000001180bc60: CMD = pcm -i $(TARGET_SAMPLES)/aac/latm_000000001180bc60.mpg
 fate-aac-latm_000000001180bc60: REF = $(SAMPLES)/aac/latm_000000001180bc60.s16
 
 FATE_AAC_LATM += fate-aac-latm_stereo_to_51
-fate-aac-latm_stereo_to_51: CMD = pcm -i $(SAMPLES)/aac/latm_stereo_to_51.ts -channel_layout 5.1
+fate-aac-latm_stereo_to_51: CMD = pcm -i $(TARGET_SAMPLES)/aac/latm_stereo_to_51.ts -channel_layout 5.1
 fate-aac-latm_stereo_to_51: REF = $(SAMPLES)/aac/latm_stereo_to_51_ref.s16
 
 FATE_AAC-$(call      DEMDEC, AAC,    AAC)      += $(FATE_AAC_CT_RAW)
diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak
index 46e7a38..3841240 100644
--- a/tests/fate/ac3.mak
+++ b/tests/fate/ac3.mak
@@ -1,46 +1,46 @@
 FATE_AC3 += fate-ac3-2.0
-fate-ac3-2.0: CMD = pcm -i $(SAMPLES)/ac3/monsters_inc_2.0_192_small.ac3
-fate-ac3-2.0: REF = $(SAMPLES)/ac3/monsters_inc_2.0_192_small.pcm
+fate-ac3-2.0: CMD = pcm -i $(TARGET_SAMPLES)/ac3/monsters_inc_2.0_192_small.ac3
+fate-ac3-2.0: REF = $(SAMPLES)/ac3/monsters_inc_2.0_192_small_v2.pcm
 
 FATE_AC3 += fate-ac3-4.0
-fate-ac3-4.0: CMD = pcm -i $(SAMPLES)/ac3/millers_crossing_4.0.ac3
-fate-ac3-4.0: REF = $(SAMPLES)/ac3/millers_crossing_4.0.pcm
+fate-ac3-4.0: CMD = pcm -i $(TARGET_SAMPLES)/ac3/millers_crossing_4.0.ac3
+fate-ac3-4.0: REF = $(SAMPLES)/ac3/millers_crossing_4.0_v2.pcm
 
 FATE_AC3 += fate-ac3-4.0-downmix-mono
-fate-ac3-4.0-downmix-mono: CMD = pcm -request_channels 1 -i $(SAMPLES)/ac3/millers_crossing_4.0.ac3
-fate-ac3-4.0-downmix-mono: REF = $(SAMPLES)/ac3/millers_crossing_4.0_mono.pcm
+fate-ac3-4.0-downmix-mono: CMD = pcm -request_channels 1 -i $(TARGET_SAMPLES)/ac3/millers_crossing_4.0.ac3
+fate-ac3-4.0-downmix-mono: REF = $(SAMPLES)/ac3/millers_crossing_4.0_mono_v2.pcm
 
 FATE_AC3 += fate-ac3-4.0-downmix-stereo
-fate-ac3-4.0-downmix-stereo: CMD = pcm -request_channels 2 -i $(SAMPLES)/ac3/millers_crossing_4.0.ac3
-fate-ac3-4.0-downmix-stereo: REF = $(SAMPLES)/ac3/millers_crossing_4.0_stereo.pcm
+fate-ac3-4.0-downmix-stereo: CMD = pcm -request_channels 2 -i $(TARGET_SAMPLES)/ac3/millers_crossing_4.0.ac3
+fate-ac3-4.0-downmix-stereo: REF = $(SAMPLES)/ac3/millers_crossing_4.0_stereo_v2.pcm
 
 FATE_AC3 += fate-ac3-5.1
-fate-ac3-5.1: CMD = pcm -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
-fate-ac3-5.1: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small.pcm
+fate-ac3-5.1: CMD = pcm -i $(TARGET_SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
+fate-ac3-5.1: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_v2.pcm
 
 FATE_AC3 += fate-ac3-5.1-downmix-mono
-fate-ac3-5.1-downmix-mono: CMD = pcm -request_channels 1 -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
-fate-ac3-5.1-downmix-mono: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_mono.pcm
+fate-ac3-5.1-downmix-mono: CMD = pcm -request_channels 1 -i $(TARGET_SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
+fate-ac3-5.1-downmix-mono: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_mono_v2.pcm
 
 FATE_AC3 += fate-ac3-5.1-downmix-stereo
-fate-ac3-5.1-downmix-stereo: CMD = pcm -request_channels 2 -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
-fate-ac3-5.1-downmix-stereo: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_stereo.pcm
+fate-ac3-5.1-downmix-stereo: CMD = pcm -request_channels 2 -i $(TARGET_SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3
+fate-ac3-5.1-downmix-stereo: REF = $(SAMPLES)/ac3/monsters_inc_5.1_448_small_stereo_v2.pcm
 
 FATE_EAC3 += fate-eac3-1
-fate-eac3-1: CMD = pcm -i $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small.eac3
-fate-eac3-1: REF = $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small.pcm
+fate-eac3-1: CMD = pcm -i $(TARGET_SAMPLES)/eac3/csi_miami_5.1_256_spx_small.eac3
+fate-eac3-1: REF = $(SAMPLES)/eac3/csi_miami_5.1_256_spx_small_v2.pcm
 
 FATE_EAC3 += fate-eac3-2
-fate-eac3-2: CMD = pcm -i $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small.eac3
-fate-eac3-2: REF = $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small.pcm
+fate-eac3-2: CMD = pcm -i $(TARGET_SAMPLES)/eac3/csi_miami_stereo_128_spx_small.eac3
+fate-eac3-2: REF = $(SAMPLES)/eac3/csi_miami_stereo_128_spx_small_v2.pcm
 
 FATE_EAC3 += fate-eac3-3
-fate-eac3-3: CMD = pcm -i $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.eac3
-fate-eac3-3: REF = $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.pcm
+fate-eac3-3: CMD = pcm -i $(TARGET_SAMPLES)/eac3/matrix2_commentary1_stereo_192_small.eac3
+fate-eac3-3: REF = $(SAMPLES)/eac3/matrix2_commentary1_stereo_192_small_v2.pcm
 
 FATE_EAC3 += fate-eac3-4
-fate-eac3-4: CMD = pcm -i $(SAMPLES)/eac3/serenity_english_5.1_1536_small.eac3
-fate-eac3-4: REF = $(SAMPLES)/eac3/serenity_english_5.1_1536_small.pcm
+fate-eac3-4: CMD = pcm -i $(TARGET_SAMPLES)/eac3/serenity_english_5.1_1536_small.eac3
+fate-eac3-4: REF = $(SAMPLES)/eac3/serenity_english_5.1_1536_small_v2.pcm
 
 $(FATE_AC3) $(FATE_EAC3): CMP = oneoff
 
@@ -48,18 +48,16 @@ FATE_AC3-$(call  DEMDEC, AC3,  AC3)  += $(FATE_AC3)
 FATE_EAC3-$(call DEMDEC, EAC3, EAC3) += $(FATE_EAC3)
 
 FATE_AC3-$(call ENCDEC, AC3, AC3) += fate-ac3-encode
-fate-ac3-encode: CMD = enc_dec_pcm ac3 wav s16le $(REF) -c:a ac3 -b:a 128k
+fate-ac3-encode: CMD = enc_dec_pcm ac3 wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a ac3 -b:a 128k
 fate-ac3-encode: CMP_SHIFT = -1024
-fate-ac3-encode: CMP_TARGET = 399.62
+fate-ac3-encode: CMP_TARGET = 404.53
 fate-ac3-encode: SIZE_TOLERANCE = 488
-fate-ac3-encode: FUZZ = 3
 
 FATE_EAC3-$(call ENCDEC, EAC3, EAC3) += fate-eac3-encode
-fate-eac3-encode: CMD = enc_dec_pcm eac3 wav s16le $(REF) -c:a eac3 -b:a 128k
+fate-eac3-encode: CMD = enc_dec_pcm eac3 wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a eac3 -b:a 128k
 fate-eac3-encode: CMP_SHIFT = -1024
-fate-eac3-encode: CMP_TARGET = 514.02
+fate-eac3-encode: CMP_TARGET = 516.94
 fate-eac3-encode: SIZE_TOLERANCE = 488
-fate-eac3-encode: FUZZ = 3
 
 fate-ac3-encode fate-eac3-encode: CMP = stddev
 fate-ac3-encode fate-eac3-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
diff --git a/tests/fate/adpcm.mak b/tests/fate/adpcm.mak
index bb4745b..55f2556 100644
--- a/tests/fate/adpcm.mak
+++ b/tests/fate/adpcm.mak
@@ -1,74 +1,74 @@
 FATE_ADPCM-$(call DEMDEC, WAV, ADPCM_CT) += fate-adpcm-creative
-fate-adpcm-creative: CMD = md5 -i $(SAMPLES)/creative/intro-partial.wav -f s16le
+fate-adpcm-creative: CMD = md5 -i $(TARGET_SAMPLES)/creative/intro-partial.wav -f s16le
 
 FATE_ADPCM-$(call DEMDEC, VOC, ADPCM_SBPRO_2) += fate-adpcm-creative-8-2bit
-fate-adpcm-creative-8-2bit: CMD = md5 -i $(SAMPLES)/creative/BBC_2BIT.VOC -f s16le
+fate-adpcm-creative-8-2bit: CMD = md5 -i $(TARGET_SAMPLES)/creative/BBC_2BIT.VOC -f s16le
 
 FATE_ADPCM-$(call DEMDEC, VOC, ADPCM_SBPRO_3) += fate-adpcm-creative-8-2.6bit
-fate-adpcm-creative-8-2.6bit: CMD = md5 -i $(SAMPLES)/creative/BBC_3BIT.VOC -f s16le
+fate-adpcm-creative-8-2.6bit: CMD = md5 -i $(TARGET_SAMPLES)/creative/BBC_3BIT.VOC -f s16le
 
 FATE_ADPCM-$(call DEMDEC, VOC, ADPCM_SBPRO_4) += fate-adpcm-creative-8-4bit
-fate-adpcm-creative-8-4bit: CMD = md5 -i $(SAMPLES)/creative/BBC_4BIT.VOC -f s16le
+fate-adpcm-creative-8-4bit: CMD = md5 -i $(TARGET_SAMPLES)/creative/BBC_4BIT.VOC -f s16le
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA) += fate-adpcm-ea-1
-fate-adpcm-ea-1: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:a 26 -vn
+fate-adpcm-ea-1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:a 26 -vn
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA) += fate-adpcm-ea-2
-fate-adpcm-ea-2: CMD = framecrc -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct -vn
+fate-adpcm-ea-2: CMD = framecrc -i $(TARGET_SAMPLES)/ea-dct/NFS2Esprit-partial.dct -vn
 
 FATE_ADPCM-$(call DEMDEC, XA, ADPCM_EA_MAXIS_XA) += fate-adpcm-ea-maxis-xa
-fate-adpcm-ea-maxis-xa: CMD = framecrc -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30
+fate-adpcm-ea-maxis-xa: CMD = framecrc -i $(TARGET_SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R1) += fate-adpcm-ea-r1
-fate-adpcm-ea-r1: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad -vn
+fate-adpcm-ea-r1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/NFS6LogoE.mad -vn
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R2) += fate-adpcm-ea-r2
-fate-adpcm-ea-r2: CMD = crc -i $(SAMPLES)/ea-mpc/THX_logo.mpc -vn
+fate-adpcm-ea-r2: CMD = crc -i $(TARGET_SAMPLES)/ea-mpc/THX_logo.mpc -vn
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_EA_R3) += fate-adpcm-ea-r3
-fate-adpcm-ea-r3: CMD = crc -i $(SAMPLES)/ea-vp6/THX_logo.vp6 -vn
+fate-adpcm-ea-r3: CMD = crc -i $(TARGET_SAMPLES)/ea-vp6/THX_logo.vp6 -vn
 
 FATE_ADPCM-$(call DEMDEC, AVI, ADPCM_IMA_AMV) += fate-adpcm-ima-amv
-fate-adpcm-ima-amv: CMD = framecrc -i $(SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -vn
+fate-adpcm-ima-amv: CMD = framecrc -i $(TARGET_SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -vn
 
 FATE_ADPCM-$(call DEMDEC, APC, ADPCM_IMA_APC) += fate-adpcm-ima-apc
-fate-adpcm-ima-apc: CMD = md5 -i $(SAMPLES)/cryo-apc/cine007.APC -f s16le
+fate-adpcm-ima-apc: CMD = md5 -i $(TARGET_SAMPLES)/cryo-apc/cine007.APC -f s16le
 
 FATE_ADPCM-$(call DEMDEC, AVI, ADPCM_IMA_DK3) += fate-adpcm-ima-dk3
-fate-adpcm-ima-dk3: CMD = md5 -i $(SAMPLES)/duck/sop-audio-only.avi -f s16le
+fate-adpcm-ima-dk3: CMD = md5 -i $(TARGET_SAMPLES)/duck/sop-audio-only.avi -f s16le
 
 FATE_ADPCM-$(call DEMDEC, AVI, ADPCM_IMA_DK4) += fate-adpcm-ima-dk4
-fate-adpcm-ima-dk4: CMD = md5 -i $(SAMPLES)/duck/salsa-audio-only.avi -f s16le
+fate-adpcm-ima-dk4: CMD = md5 -i $(TARGET_SAMPLES)/duck/salsa-audio-only.avi -f s16le
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_IMA_EA_EACS) += fate-adpcm-ima-ea-eacs
-fate-adpcm-ima-ea-eacs: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -vn
+fate-adpcm-ima-ea-eacs: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTRO8K-partial.TGV -vn
 
 FATE_ADPCM-$(call DEMDEC, EA, ADPCM_IMA_EA_SEAD) += fate-adpcm-ima-ea-sead
-fate-adpcm-ima-ea-sead: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -vn
+fate-adpcm-ima-ea-sead: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTEL_S.TGV -vn
 
 FATE_ADPCM-$(call DEMDEC, ISS, ADPCM_IMA_ISS) += fate-adpcm-ima-iss
-fate-adpcm-ima-iss: CMD = md5 -i $(SAMPLES)/funcom-iss/0004010100.iss -f s16le
+fate-adpcm-ima-iss: CMD = md5 -i $(TARGET_SAMPLES)/funcom-iss/0004010100.iss -f s16le
 
 FATE_ADPCM-$(call DEMDEC, SMJPEG, ADPCM_IMA_SMJPEG) += fate-adpcm-ima-smjpeg
-fate-adpcm-ima-smjpeg: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -vn
+fate-adpcm-ima-smjpeg: CMD = framecrc -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -vn
 
 FATE_ADPCM-$(call DEMDEC, MOV, ADPCM_IMA_WAV) += fate-adpcm-ima_wav-stereo
-fate-adpcm-ima_wav-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le
+fate-adpcm-ima_wav-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le
 
 FATE_ADPCM-$(call DEMDEC, WSVQA, ADPCM_IMA_WS) += fate-adpcm-ima-ws
-fate-adpcm-ima-ws: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -vn
+fate-adpcm-ima-ws: CMD = framecrc -i $(TARGET_SAMPLES)/vqa/cc-demo1-partial.vqa -vn
 
 FATE_ADPCM-$(call DEMDEC, DXA, ADPCM_MS) += fate-adpcm-ms-mono
-fate-adpcm-ms-mono: CMD = framecrc -i $(SAMPLES)/dxa/meetsquid.dxa -t 2 -vn
+fate-adpcm-ms-mono: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/meetsquid.dxa -t 2 -vn
 
 FATE_ADPCM-$(call DEMDEC, MOV, ADPCM_MS) += fate-adpcm_ms-stereo
-fate-adpcm_ms-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le
+fate-adpcm_ms-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le
 
 FATE_ADPCM-$(call DEMDEC, THP, ADPCM_THP) += fate-adpcm-thp
-fate-adpcm-thp: CMD = framecrc -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp -vn
+fate-adpcm-thp: CMD = framecrc -i $(TARGET_SAMPLES)/thp/pikmin2-opening1-partial.thp -vn
 
 FATE_ADPCM-$(call DEMDEC, STR, ADPCM_XA) += fate-adpcm-xa
-fate-adpcm-xa: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -vn
+fate-adpcm-xa: CMD = framecrc -i $(TARGET_SAMPLES)/psx-str/abc000_cut.str -vn
 
 FATE_SAMPLES_AVCONV += $(FATE_ADPCM-yes)
 fate-adpcm: $(FATE_ADPCM-yes)
diff --git a/tests/fate/alac.mak b/tests/fate/alac.mak
index d724837..5e29e90 100644
--- a/tests/fate/alac.mak
+++ b/tests/fate/alac.mak
@@ -12,10 +12,10 @@ fate-alac-24-level-%:    OPTS = -compression_level $(@:fate-alac-24-level-%=%)
 fate-alac-%-lpc-orders:  OPTS = -min_prediction_order 1 -max_prediction_order 30
 
 fate-alac-16-%: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
-fate-alac-16-%: CMD = enc_dec_pcm mov wav s16le $(REF) -c alac $(OPTS)
+fate-alac-16-%: CMD = enc_dec_pcm mov wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c alac $(OPTS)
 
 fate-alac-24-%: REF = $(SAMPLES)/audio-reference/divertimenti_2ch_96kHz_s24.wav
-fate-alac-24-%: CMD = enc_dec_pcm mov wav s24le $(REF) -c alac $(OPTS)
+fate-alac-24-%: CMD = enc_dec_pcm mov wav s24le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c alac $(OPTS)
 
 fate-alac-%: CMP = oneoff
 fate-alac-%: FUZZ = 0
diff --git a/tests/fate/als.mak b/tests/fate/als.mak
index 5ec1189..ff2badf 100644
--- a/tests/fate/als.mak
+++ b/tests/fate/als.mak
@@ -2,7 +2,7 @@ ALS_SUITE = 00 01 02 03 04 05
 
 define FATE_ALS_SUITE
 FATE_ALS += fate-mpeg4-als-conformance-$(1)
-fate-mpeg4-als-conformance-$(1): CMD = crc -i $(SAMPLES)/lossless-audio/als_$(1)_2ch48k16b.mp4
+fate-mpeg4-als-conformance-$(1): CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/als_$(1)_2ch48k16b.mp4
 endef
 
 $(foreach N,$(ALS_SUITE),$(eval $(call FATE_ALS_SUITE,$(N))))
diff --git a/tests/fate/amrnb.mak b/tests/fate/amrnb.mak
index 6dbba58..c0feec2 100644
--- a/tests/fate/amrnb.mak
+++ b/tests/fate/amrnb.mak
@@ -1,33 +1,33 @@
 FATE_AMRNB += fate-amrnb-4k75
-fate-amrnb-4k75: CMD = pcm -i $(SAMPLES)/amrnb/4.75k.amr
+fate-amrnb-4k75: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/4.75k.amr
 fate-amrnb-4k75: REF = $(SAMPLES)/amrnb/4.75k.pcm
 
 FATE_AMRNB += fate-amrnb-5k15
-fate-amrnb-5k15: CMD = pcm -i $(SAMPLES)/amrnb/5.15k.amr
+fate-amrnb-5k15: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/5.15k.amr
 fate-amrnb-5k15: REF = $(SAMPLES)/amrnb/5.15k.pcm
 
 FATE_AMRNB += fate-amrnb-5k9
-fate-amrnb-5k9: CMD = pcm -i $(SAMPLES)/amrnb/5.9k.amr
+fate-amrnb-5k9: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/5.9k.amr
 fate-amrnb-5k9: REF = $(SAMPLES)/amrnb/5.9k.pcm
 
 FATE_AMRNB += fate-amrnb-6k7
-fate-amrnb-6k7: CMD = pcm -i $(SAMPLES)/amrnb/6.7k.amr
+fate-amrnb-6k7: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/6.7k.amr
 fate-amrnb-6k7: REF = $(SAMPLES)/amrnb/6.7k.pcm
 
 FATE_AMRNB += fate-amrnb-7k4
-fate-amrnb-7k4: CMD = pcm -i $(SAMPLES)/amrnb/7.4k.amr
+fate-amrnb-7k4: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/7.4k.amr
 fate-amrnb-7k4: REF = $(SAMPLES)/amrnb/7.4k.pcm
 
 FATE_AMRNB += fate-amrnb-7k95
-fate-amrnb-7k95: CMD = pcm -i $(SAMPLES)/amrnb/7.95k.amr
+fate-amrnb-7k95: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/7.95k.amr
 fate-amrnb-7k95: REF = $(SAMPLES)/amrnb/7.95k.pcm
 
 FATE_AMRNB += fate-amrnb-10k2
-fate-amrnb-10k2: CMD = pcm -i $(SAMPLES)/amrnb/10.2k.amr
+fate-amrnb-10k2: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/10.2k.amr
 fate-amrnb-10k2: REF = $(SAMPLES)/amrnb/10.2k.pcm
 
 FATE_AMRNB += fate-amrnb-12k2
-fate-amrnb-12k2: CMD = pcm -i $(SAMPLES)/amrnb/12.2k.amr
+fate-amrnb-12k2: CMD = pcm -i $(TARGET_SAMPLES)/amrnb/12.2k.amr
 fate-amrnb-12k2: REF = $(SAMPLES)/amrnb/12.2k.pcm
 
 $(FATE_AMRNB): CMP = stddev
diff --git a/tests/fate/amrwb.mak b/tests/fate/amrwb.mak
index 99c2737..b93835d 100644
--- a/tests/fate/amrwb.mak
+++ b/tests/fate/amrwb.mak
@@ -1,44 +1,44 @@
 FATE_AMRWB += fate-amrwb-6k60
-fate-amrwb-6k60: CMD = pcm -i $(SAMPLES)/amrwb/seed-6k60.awb
+fate-amrwb-6k60: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-6k60.awb
 fate-amrwb-6k60: REF = $(SAMPLES)/amrwb/seed-6k60.pcm
 
 FATE_AMRWB += fate-amrwb-8k85
-fate-amrwb-8k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-8k85.awb
+fate-amrwb-8k85: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-8k85.awb
 fate-amrwb-8k85: REF = $(SAMPLES)/amrwb/seed-8k85.pcm
 
 FATE_AMRWB += fate-amrwb-12k65
-fate-amrwb-12k65: CMD = pcm -i $(SAMPLES)/amrwb/seed-12k65.awb
+fate-amrwb-12k65: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-12k65.awb
 fate-amrwb-12k65: REF = $(SAMPLES)/amrwb/seed-12k65.pcm
 
 FATE_AMRWB += fate-amrwb-14k25
-fate-amrwb-14k25: CMD = pcm -i $(SAMPLES)/amrwb/seed-14k25.awb
+fate-amrwb-14k25: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-14k25.awb
 fate-amrwb-14k25: REF = $(SAMPLES)/amrwb/seed-14k25.pcm
 fate-amrwb-14k25: FUZZ = 2.6
 
 FATE_AMRWB += fate-amrwb-15k85
-fate-amrwb-15k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-15k85.awb
+fate-amrwb-15k85: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-15k85.awb
 fate-amrwb-15k85: REF = $(SAMPLES)/amrwb/seed-15k85.pcm
 
 FATE_AMRWB += fate-amrwb-18k25
-fate-amrwb-18k25: CMD = pcm -i $(SAMPLES)/amrwb/seed-18k25.awb
+fate-amrwb-18k25: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-18k25.awb
 fate-amrwb-18k25: REF = $(SAMPLES)/amrwb/seed-18k25.pcm
 
 FATE_AMRWB += fate-amrwb-19k85
-fate-amrwb-19k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-19k85.awb
+fate-amrwb-19k85: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-19k85.awb
 fate-amrwb-19k85: REF = $(SAMPLES)/amrwb/seed-19k85.pcm
 
 FATE_AMRWB += fate-amrwb-23k05
-fate-amrwb-23k05: CMD = pcm -i $(SAMPLES)/amrwb/seed-23k05.awb
+fate-amrwb-23k05: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-23k05.awb
 fate-amrwb-23k05: REF = $(SAMPLES)/amrwb/seed-23k05.pcm
 fate-amrwb-23k05: FUZZ = 2
 
 FATE_AMRWB += fate-amrwb-23k85
-fate-amrwb-23k85: CMD = pcm -i $(SAMPLES)/amrwb/seed-23k85.awb
+fate-amrwb-23k85: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/seed-23k85.awb
 fate-amrwb-23k85: REF = $(SAMPLES)/amrwb/seed-23k85.pcm
 fate-amrwb-23k85: FUZZ = 2
 
 FATE_AMRWB += fate-amrwb-23k85-2
-fate-amrwb-23k85-2: CMD = pcm -i $(SAMPLES)/amrwb/deus-23k85.awb
+fate-amrwb-23k85-2: CMD = pcm -i $(TARGET_SAMPLES)/amrwb/deus-23k85.awb
 fate-amrwb-23k85-2: REF = $(SAMPLES)/amrwb/deus-23k85.pcm
 
 $(FATE_AMRWB): CMP = stddev
diff --git a/tests/fate/atrac.mak b/tests/fate/atrac.mak
index 3ac5553..94dbe38 100644
--- a/tests/fate/atrac.mak
+++ b/tests/fate/atrac.mak
@@ -1,17 +1,17 @@
 FATE_ATRAC1-$(call DEMDEC, AEA, ATRAC1) += fate-atrac1
-fate-atrac1: CMD = pcm -i $(SAMPLES)/atrac1/test_tones_small.aea
+fate-atrac1: CMD = pcm -i $(TARGET_SAMPLES)/atrac1/test_tones_small.aea
 fate-atrac1: REF = $(SAMPLES)/atrac1/test_tones_small.pcm
 
 FATE_ATRAC3 += fate-atrac3-1
-fate-atrac3-1: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_066_small.wav
+fate-atrac3-1: CMD = pcm -i $(TARGET_SAMPLES)/atrac3/mc_sich_at3_066_small.wav
 fate-atrac3-1: REF = $(SAMPLES)/atrac3/mc_sich_at3_066_small.pcm
 
 FATE_ATRAC3 += fate-atrac3-2
-fate-atrac3-2: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_105_small.wav
+fate-atrac3-2: CMD = pcm -i $(TARGET_SAMPLES)/atrac3/mc_sich_at3_105_small.wav
 fate-atrac3-2: REF = $(SAMPLES)/atrac3/mc_sich_at3_105_small.pcm
 
 FATE_ATRAC3 += fate-atrac3-3
-fate-atrac3-3: CMD = pcm -i $(SAMPLES)/atrac3/mc_sich_at3_132_small.wav
+fate-atrac3-3: CMD = pcm -i $(TARGET_SAMPLES)/atrac3/mc_sich_at3_132_small.wav
 fate-atrac3-3: REF = $(SAMPLES)/atrac3/mc_sich_at3_132_small.pcm
 
 FATE_ATRAC3-$(call DEMDEC, WAV, ATRAC3) += $(FATE_ATRAC3)
diff --git a/tests/fate/audio.mak b/tests/fate/audio.mak
index 7e08c2a..a0e0caf 100644
--- a/tests/fate/audio.mak
+++ b/tests/fate/audio.mak
@@ -1,10 +1,10 @@
 FATE_BINKAUDIO-$(call DEMDEC, BINK, BINKAUDIO_DCT) += fate-binkaudio-dct
-fate-binkaudio-dct: CMD = pcm -i $(SAMPLES)/bink/binkaudio_dct.bik
+fate-binkaudio-dct: CMD = pcm -i $(TARGET_SAMPLES)/bink/binkaudio_dct.bik
 fate-binkaudio-dct: REF = $(SAMPLES)/bink/binkaudio_dct.pcm
 fate-binkaudio-dct: FUZZ = 2
 
 FATE_BINKAUDIO-$(call DEMDEC, BINK, BINKAUDIO_RDFT) += fate-binkaudio-rdft
-fate-binkaudio-rdft: CMD = pcm -i $(SAMPLES)/bink/binkaudio_rdft.bik
+fate-binkaudio-rdft: CMD = pcm -i $(TARGET_SAMPLES)/bink/binkaudio_rdft.bik
 fate-binkaudio-rdft: REF = $(SAMPLES)/bink/binkaudio_rdft.pcm
 fate-binkaudio-rdft: FUZZ = 2
 
@@ -14,31 +14,31 @@ FATE_SAMPLES_AVCONV += $(FATE_BINKAUDIO-yes)
 fate-binkaudio: $(FATE_BINKAUDIO-yes)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, BMV, BMV_AUDIO) += fate-bmv-audio
-fate-bmv-audio: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -vn
+fate-bmv-audio: CMD = framecrc -i $(TARGET_SAMPLES)/bmv/SURFING-partial.BMV -vn
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, DSICIN, DSICINAUDIO) += fate-delphine-cin-audio
-fate-delphine-cin-audio: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -vn
+fate-delphine-cin-audio: CMD = framecrc -i $(TARGET_SAMPLES)/delphine-cin/LOGO-partial.CIN -vn
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MPEGTS, DCA) += fate-dts
-fate-dts: CMD = pcm -i $(SAMPLES)/dts/dts.ts
+fate-dts: CMD = pcm -i $(TARGET_SAMPLES)/dts/dts.ts
 fate-dts: CMP = oneoff
 fate-dts: REF = $(SAMPLES)/dts/dts.pcm
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, IMC) += fate-imc
-fate-imc: CMD = pcm -i $(SAMPLES)/imc/imc.avi
+fate-imc: CMD = pcm -i $(TARGET_SAMPLES)/imc/imc.avi
 fate-imc: CMP = oneoff
 fate-imc: REF = $(SAMPLES)/imc/imc.pcm
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, FLV, NELLYMOSER) += fate-nellymoser
-fate-nellymoser: CMD = pcm -i $(SAMPLES)/nellymoser/nellymoser.flv
+fate-nellymoser: CMD = pcm -i $(TARGET_SAMPLES)/nellymoser/nellymoser.flv
 fate-nellymoser: CMP = oneoff
 fate-nellymoser: REF = $(SAMPLES)/nellymoser/nellymoser.pcm
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, VMD, VMDAUDIO) += fate-sierra-vmd-audio
-fate-sierra-vmd-audio: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -vn
+fate-sierra-vmd-audio: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -vn
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, SMACKER, SMACKAUD) += fate-smacker-audio
-fate-smacker-audio: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -vn
+fate-smacker-audio: CMD = framecrc -i $(TARGET_SAMPLES)/smacker/wetlogo.smk -vn
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, WSVQA, WS_SND1) += fate-ws_snd
-fate-ws_snd: CMD = md5 -i $(SAMPLES)/vqa/ws_snd.vqa -f s16le
+fate-ws_snd: CMD = md5 -i $(TARGET_SAMPLES)/vqa/ws_snd.vqa -f s16le
diff --git a/tests/fate/avfilter.mak b/tests/fate/avfilter.mak
deleted file mode 100644
index de5e9d1..0000000
--- a/tests/fate/avfilter.mak
+++ /dev/null
@@ -1,24 +0,0 @@
-FATE_LAVFI = fate-lavfi-crop                                            \
-             fate-lavfi-crop_scale                                      \
-             fate-lavfi-crop_scale_vflip                                \
-             fate-lavfi-crop_vflip                                      \
-             fate-lavfi-null                                            \
-             fate-lavfi-pixdesc                                         \
-             fate-lavfi-pixfmts_copy                                    \
-             fate-lavfi-pixfmts_crop                                    \
-             fate-lavfi-pixfmts_hflip                                   \
-             fate-lavfi-pixfmts_null                                    \
-             fate-lavfi-pixfmts_pad                                     \
-             fate-lavfi-pixfmts_scale                                   \
-             fate-lavfi-pixfmts_vflip                                   \
-             fate-lavfi-scale200                                        \
-             fate-lavfi-scale500                                        \
-             fate-lavfi-vflip                                           \
-             fate-lavfi-vflip_crop                                      \
-             fate-lavfi-vflip_vflip                                     \
-
-$(FATE_LAVFI): $(VREF) libavfilter/filtfmts-test$(EXESUF)
-$(FATE_LAVFI): CMD = lavfitest
-
-FATE_AVCONV += $(FATE_LAVFI)
-fate-lavfi:    $(FATE_LAVFI)
diff --git a/tests/fate/bmp.mak b/tests/fate/bmp.mak
index 9e52ac0..923c70d 100644
--- a/tests/fate/bmp.mak
+++ b/tests/fate/bmp.mak
@@ -1,41 +1,41 @@
 FATE_BMP += fate-bmp-1bit
-fate-bmp-1bit: CMD = framecrc -i $(SAMPLES)/bmp/test1.bmp -pix_fmt rgb24
+fate-bmp-1bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test1.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-4bit
-fate-bmp-4bit: CMD = framecrc -i $(SAMPLES)/bmp/test4.bmp -pix_fmt rgb24
+fate-bmp-4bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test4.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-4bit-os2
-fate-bmp-4bit-os2: CMD = framecrc -i $(SAMPLES)/bmp/test4os2v2.bmp -pix_fmt rgb24
+fate-bmp-4bit-os2: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test4os2v2.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-8bit
-fate-bmp-8bit: CMD = framecrc -i $(SAMPLES)/bmp/test8.bmp -pix_fmt rgb24
+fate-bmp-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test8.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-8bit-os2
-fate-bmp-8bit-os2: CMD = framecrc -i $(SAMPLES)/bmp/test8os2.bmp -pix_fmt rgb24
+fate-bmp-8bit-os2: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test8os2.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-15bit
-fate-bmp-15bit: CMD = framecrc -i $(SAMPLES)/bmp/test16.bmp -pix_fmt rgb555le
+fate-bmp-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16.bmp -pix_fmt rgb555le
 
 FATE_BMP += fate-bmp-15bit-mask
-fate-bmp-15bit-mask: CMD = framecrc -i $(SAMPLES)/bmp/test16bf555.bmp -pix_fmt rgb555le
+fate-bmp-15bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16bf555.bmp -pix_fmt rgb555le
 
 FATE_BMP += fate-bmp-16bit-mask
-fate-bmp-16bit-mask: CMD = framecrc -i $(SAMPLES)/bmp/test16bf565.bmp -pix_fmt rgb565le
+fate-bmp-16bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test16bf565.bmp -pix_fmt rgb565le
 
 FATE_BMP += fate-bmp-24bit
-fate-bmp-24bit: CMD = framecrc -i $(SAMPLES)/bmp/test24.bmp
+fate-bmp-24bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test24.bmp
 
 FATE_BMP += fate-bmp-32bit
-fate-bmp-32bit: CMD = framecrc -i $(SAMPLES)/bmp/test32.bmp -pix_fmt bgr24
+fate-bmp-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test32.bmp -pix_fmt bgr24
 
 FATE_BMP += fate-bmp-32bit-mask
-fate-bmp-32bit-mask: CMD = framecrc -i $(SAMPLES)/bmp/test32bf.bmp -pix_fmt bgr24
+fate-bmp-32bit-mask: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/test32bf.bmp -pix_fmt bgr24
 
 FATE_BMP += fate-bmp-rle4
-fate-bmp-rle4: CMD = framecrc -i $(SAMPLES)/bmp/testcompress4.bmp -pix_fmt rgb24
+fate-bmp-rle4: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/testcompress4.bmp -pix_fmt rgb24
 
 FATE_BMP += fate-bmp-rle8
-fate-bmp-rle8: CMD = framecrc -i $(SAMPLES)/bmp/testcompress8.bmp -pix_fmt rgb24
+fate-bmp-rle8: CMD = framecrc -i $(TARGET_SAMPLES)/bmp/testcompress8.bmp -pix_fmt rgb24
 
 FATE_BMP-$(call DEMDEC, IMAGE2, BMP) += $(FATE_BMP)
 
diff --git a/tests/fate/cdxl.mak b/tests/fate/cdxl.mak
index 2c69e39..8144f96 100644
--- a/tests/fate/cdxl.mak
+++ b/tests/fate/cdxl.mak
@@ -1,17 +1,17 @@
+FATE_CDXL += fate-cdxl-bitline-ham6
+fate-cdxl-bitline-ham6: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/bitline.cdxl -frames:v 10
+
 FATE_CDXL += fate-cdxl-ham6
-fate-cdxl-ham6: CMD = framecrc -i $(SAMPLES)/cdxl/cat.cdxl -an -frames:v 16
+fate-cdxl-ham6: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/cat.cdxl -an -frames:v 16
 
 FATE_CDXL += fate-cdxl-ham8
-fate-cdxl-ham8: CMD = framecrc -i $(SAMPLES)/cdxl/mirage.cdxl -an -frames:v 1
+fate-cdxl-ham8: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/mirage.cdxl -an -frames:v 1
 
 FATE_CDXL += fate-cdxl-pal8
-fate-cdxl-pal8: CMD = framecrc -i $(SAMPLES)/cdxl/maku.cdxl -pix_fmt rgb24 -frames:v 11
+fate-cdxl-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/maku.cdxl -pix_fmt rgb24 -frames:v 11
 
 FATE_CDXL += fate-cdxl-pal8-small
-fate-cdxl-pal8-small: CMD = framecrc -i $(SAMPLES)/cdxl/fruit.cdxl -an -pix_fmt rgb24 -frames:v 46
-
-FATE_CDXL += fate-cdxl-bitline-ham6
-fate-cdxl-bitline-ham6: CMD = framecrc -i $(SAMPLES)/cdxl/bitline.cdxl -frames:v 10
+fate-cdxl-pal8-small: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/fruit.cdxl -an -pix_fmt rgb24 -frames:v 46
 
 FATE_CDXL-$(call DEMDEC, CDXL, CDXL) += $(FATE_CDXL)
 
diff --git a/tests/fate/cover-art.mak b/tests/fate/cover-art.mak
index dadfcd8..54dc0ba 100644
--- a/tests/fate/cover-art.mak
+++ b/tests/fate/cover-art.mak
@@ -1,21 +1,33 @@
 FATE_COVER_ART += fate-cover-art-ape
-fate-cover-art-ape: CMD = md5 -i $(SAMPLES)/cover_art/luckynight_cover.ape -an -c:v copy -f rawvideo
+fate-cover-art-ape: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/luckynight_cover.ape -an -c:v copy -f rawvideo
 fate-cover-art-ape: REF = 45333c983c45af54449dff10af144317
 
 FATE_COVER_ART += fate-cover-art-flac
-fate-cover-art-flac: CMD = md5 -i $(SAMPLES)/cover_art/cover_art.flac -an -c:v copy -f rawvideo
+fate-cover-art-flac: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/cover_art.flac -an -c:v copy -f rawvideo
 fate-cover-art-flac: REF = 0de1fc6200596fa32b8f7300a14c0261
 
 FATE_COVER_ART += fate-cover-art-m4a
-fate-cover-art-m4a: CMD = md5 -i $(SAMPLES)/cover_art/Owner-iTunes_9.0.3.15.m4a -an -c:v copy -f rawvideo
+fate-cover-art-m4a: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/Owner-iTunes_9.0.3.15.m4a -an -c:v copy -f rawvideo
 fate-cover-art-m4a: REF = 08ba70a3b594ff6345a93965e96a9d3e
 
+FATE_COVER_ART += fate-cover-art-ogg
+fate-cover-art-ogg: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/ogg_vorbiscomment_cover.opus -an -c:v copy -f rawvideo
+fate-cover-art-ogg: REF = b796d33363dbfed1868523b5c751b7b1
+
 FATE_COVER_ART += fate-cover-art-wma
-fate-cover-art-wma: CMD = md5 -i $(SAMPLES)/cover_art/Californication_cover.wma -an -c:v copy -f rawvideo
+fate-cover-art-wma: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/Californication_cover.wma -an -c:v copy -f rawvideo
 fate-cover-art-wma: REF = 0808bd0e1b61542a16e1906812dd924b
 
+FATE_COVER_ART += fate-cover-art-wma-id3
+fate-cover-art-wma-id3: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/wma_with_ID3_APIC_trimmed.wma -an -c:v copy -f rawvideo
+fate-cover-art-wma-id3: REF = e6a8dd03687d5178bc13fc7d3316696e
+
+FATE_COVER_ART += fate-cover-art-wma-metadatalib
+fate-cover-art-wma-metadatalib: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/wma_with_metadata_library_object_tag_trimmed.wma -map 0:v -c:v copy -f rawvideo
+fate-cover-art-wma-metadatalib: REF = 32e8bd4fad546f63d881a0256f083aea
+
 FATE_COVER_ART += fate-cover-art-wv
-fate-cover-art-wv: CMD = md5 -i $(SAMPLES)/cover_art/luckynight_cover.wv -an -c:v copy -f rawvideo
+fate-cover-art-wv: CMD = md5 -i $(TARGET_SAMPLES)/cover_art/luckynight_cover.wv -an -c:v copy -f rawvideo
 fate-cover-art-wv: REF = 45333c983c45af54449dff10af144317
 
 $(FATE_COVER_ART): CMP = oneline
diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak
index d917cca..2446b90 100644
--- a/tests/fate/demux.mak
+++ b/tests/fate/demux.mak
@@ -1,71 +1,71 @@
 FATE_SAMPLES_AVCONV-$(CONFIG_AAC_DEMUXER) += fate-adts-demux
-fate-adts-demux: CMD = crc -i $(SAMPLES)/aac/ct_faac-adts.aac -acodec copy
+fate-adts-demux: CMD = crc -i $(TARGET_SAMPLES)/aac/ct_faac-adts.aac -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_AEA_DEMUXER) += fate-aea-demux
-fate-aea-demux: CMD = crc -i $(SAMPLES)/aea/chirp.aea -acodec copy
+fate-aea-demux: CMD = crc -i $(TARGET_SAMPLES)/aea/chirp.aea -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_BINK_DEMUXER) += fate-bink-demux
-fate-bink-demux: CMD = crc -i $(SAMPLES)/bink/Snd0a7d9b58.dee -vn -acodec copy
+fate-bink-demux: CMD = crc -i $(TARGET_SAMPLES)/bink/Snd0a7d9b58.dee -vn -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_CAF_DEMUXER) += fate-caf
-fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf -c copy
+fate-caf: CMD = crc -i $(TARGET_SAMPLES)/caf/caf-pcm16.caf -c copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_CDXL_DEMUXER) += fate-cdxl-demux
-fate-cdxl-demux: CMD = framecrc -i $(SAMPLES)/cdxl/mirage.cdxl -vcodec copy -acodec copy
+fate-cdxl-demux: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/mirage.cdxl -vcodec copy -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_DAUD_DEMUXER) += fate-d-cinema-demux
-fate-d-cinema-demux: CMD = framecrc -i $(SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy
+fate-d-cinema-demux: CMD = framecrc -i $(TARGET_SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_IV8_DEMUXER) += fate-iv8-demux
-fate-iv8-demux: CMD = framecrc -i $(SAMPLES)/iv8/zzz-partial.mpg -vcodec copy
+fate-iv8-demux: CMD = framecrc -i $(TARGET_SAMPLES)/iv8/zzz-partial.mpg -vcodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_LMLM4_DEMUXER) += fate-lmlm4-demux
-fate-lmlm4-demux: CMD = framecrc -i $(SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy
+fate-lmlm4-demux: CMD = framecrc -i $(TARGET_SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_XA_DEMUXER) += fate-maxis-xa
-fate-maxis-xa: CMD = framecrc -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30 -c:a copy
+fate-maxis-xa: CMD = framecrc -i $(TARGET_SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30 -c:a copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_MTV_DEMUXER) += fate-mtv
-fate-mtv: CMD = framecrc -i $(SAMPLES)/mtv/comedian_auto-partial.mtv -c copy
+fate-mtv: CMD = framecrc -i $(TARGET_SAMPLES)/mtv/comedian_auto-partial.mtv -c copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_MXF_DEMUXER) += fate-mxf-demux
-fate-mxf-demux: CMD = framecrc -i $(SAMPLES)/mxf/C0023S01.mxf -acodec copy -vcodec copy
+fate-mxf-demux: CMD = framecrc -i $(TARGET_SAMPLES)/mxf/C0023S01.mxf -acodec copy -vcodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_NC_DEMUXER) += fate-nc-demux
-fate-nc-demux: CMD = framecrc -i $(SAMPLES)/nc-camera/nc-sample-partial -vcodec copy
+fate-nc-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nc-camera/nc-sample-partial -vcodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_NSV_DEMUXER) += fate-nsv-demux
-fate-nsv-demux: CMD = framecrc -i $(SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -vcodec copy -acodec copy
+fate-nsv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -vcodec copy -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_OMA_DEMUXER) += fate-oma-demux
-fate-oma-demux: CMD = crc -i $(SAMPLES)/oma/01-Untitled-partial.oma -acodec copy
+fate-oma-demux: CMD = crc -i $(TARGET_SAMPLES)/oma/01-Untitled-partial.oma -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_STR_DEMUXER) += fate-psx-str-demux
-fate-psx-str-demux: CMD = framecrc -i $(SAMPLES)/psx-str/descent-partial.str -c copy
+fate-psx-str-demux: CMD = framecrc -i $(TARGET_SAMPLES)/psx-str/descent-partial.str -c copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_PVA_DEMUXER) += fate-pva-demux
-fate-pva-demux: CMD = framecrc -idct simple -i $(SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy -vn
+fate-pva-demux: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy -vn
 
 FATE_SAMPLES_AVCONV-$(CONFIG_QCP_DEMUXER) += fate-qcp-demux
-fate-qcp-demux: CMD = crc -i $(SAMPLES)/qcp/0036580847.QCP -acodec copy
+fate-qcp-demux: CMD = crc -i $(TARGET_SAMPLES)/qcp/0036580847.QCP -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_R3D_DEMUXER) += fate-redcode-demux
-fate-redcode-demux: CMD = framecrc -i $(SAMPLES)/r3d/4MB-sample.r3d -vcodec copy -acodec copy
+fate-redcode-demux: CMD = framecrc -i $(TARGET_SAMPLES)/r3d/4MB-sample.r3d -vcodec copy -acodec copy
 
-FATE_SAMPLES_AVCONV-$(CONFIG_SIFF_DEMUXER) += fate-siff
-fate-siff: CMD = framecrc -i $(SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24
+FATE_SAMPLES_AVCONV-$(CONFIG_SIFF_DEMUXER) += fate-siff-demux
+fate-siff-demux: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -c copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_SMJPEG_DEMUXER) += fate-smjpeg-demux
-fate-smjpeg-demux: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -c copy
+fate-smjpeg-demux: CMD = framecrc -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -c copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_WSAUD_DEMUXER) += fate-westwood-aud
-fate-westwood-aud: CMD = framecrc -i $(SAMPLES)/westwood-aud/excellent.aud -c copy
+fate-westwood-aud: CMD = framecrc -i $(TARGET_SAMPLES)/westwood-aud/excellent.aud -c copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_WTV_DEMUXER) += fate-wtv-demux
-fate-wtv-demux: CMD = framecrc -i $(SAMPLES)/wtv/law-and-order-partial.wtv -vcodec copy -acodec copy
+fate-wtv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/wtv/law-and-order-partial.wtv -vcodec copy -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_XMV_DEMUXER) += fate-xmv-demux
-fate-xmv-demux: CMD = framecrc -i $(SAMPLES)/xmv/logos1p.fmv -vcodec copy -acodec copy
+fate-xmv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/xmv/logos1p.fmv -vcodec copy -acodec copy
 
 FATE_SAMPLES_AVCONV-$(CONFIG_XWMA_DEMUXER) += fate-xwma-demux
-fate-xwma-demux: CMD = crc -i $(SAMPLES)/xwma/ergon.xwma -acodec copy
+fate-xwma-demux: CMD = crc -i $(TARGET_SAMPLES)/xwma/ergon.xwma -acodec copy
diff --git a/tests/fate/dfa.mak b/tests/fate/dfa.mak
index 4800d8a..f4b6057 100644
--- a/tests/fate/dfa.mak
+++ b/tests/fate/dfa.mak
@@ -1,35 +1,35 @@
 FATE_DFA += fate-dfa1
-fate-dfa1: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0000.dfa -pix_fmt rgb24
+fate-dfa1: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0000.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa2
-fate-dfa2: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0001.dfa -pix_fmt rgb24
+fate-dfa2: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0001.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa3
-fate-dfa3: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0002.dfa -pix_fmt rgb24
+fate-dfa3: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0002.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa4
-fate-dfa4: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0003.dfa -pix_fmt rgb24
+fate-dfa4: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0003.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa5
-fate-dfa5: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0004.dfa -pix_fmt rgb24
+fate-dfa5: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0004.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa6
-fate-dfa6: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0005.dfa -pix_fmt rgb24
+fate-dfa6: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0005.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa7
-fate-dfa7: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0006.dfa -pix_fmt rgb24
+fate-dfa7: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0006.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa8
-fate-dfa8: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0007.dfa -pix_fmt rgb24
+fate-dfa8: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0007.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa9
-fate-dfa9: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0008.dfa -pix_fmt rgb24
+fate-dfa9: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0008.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa10
-fate-dfa10: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0009.dfa -pix_fmt rgb24
+fate-dfa10: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0009.dfa -pix_fmt rgb24
 
 FATE_DFA += fate-dfa11
-fate-dfa11: CMD = framecrc -i $(SAMPLES)/chronomaster-dfa/0010.dfa -pix_fmt rgb24
+fate-dfa11: CMD = framecrc -i $(TARGET_SAMPLES)/chronomaster-dfa/0010.dfa -pix_fmt rgb24
 
 FATE_DFA-$(call DEMDEC, DFA, DFA) += $(FATE_DFA)
 
diff --git a/tests/fate/dpcm.mak b/tests/fate/dpcm.mak
index abc25ed..dd27246 100644
--- a/tests/fate/dpcm.mak
+++ b/tests/fate/dpcm.mak
@@ -1,14 +1,14 @@
 FATE_DPCM-$(call DEMDEC, ROQ, ROQ_DPCM) += fate-dpcm-idroq
-fate-dpcm-idroq: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -vn
+fate-dpcm-idroq: CMD = framecrc -i $(TARGET_SAMPLES)/idroq/idlogo.roq -vn
 
 FATE_DPCM-$(call DEMDEC, IPMOVIE, INTERPLAY_DPCM) += fate-dpcm-interplay
-fate-dpcm-interplay: CMD = framecrc -i $(SAMPLES)/interplay-mve/interplay-logo-2MB.mve -vn
+fate-dpcm-interplay: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/interplay-logo-2MB.mve -vn
 
 FATE_DPCM-$(call DEMDEC, SOL, SOL_DPCM) += fate-dpcm-sierra
-fate-dpcm-sierra: CMD = md5 -i $(SAMPLES)/sol/lsl7sample.sol -f s16le
+fate-dpcm-sierra: CMD = md5 -i $(TARGET_SAMPLES)/sol/lsl7sample.sol -f s16le
 
 FATE_DPCM-$(call DEMDEC, AVI, XAN_DPCM) += fate-dpcm-xan
-fate-dpcm-xan: CMD = md5 -i $(SAMPLES)/wc4-xan/wc4_2.avi -vn -f s16le
+fate-dpcm-xan: CMD = md5 -i $(TARGET_SAMPLES)/wc4-xan/wc4_2.avi -vn -f s16le
 
 FATE_SAMPLES_AVCONV += $(FATE_DPCM-yes)
 fate-dpcm: $(FATE_DPCM-yes)
diff --git a/tests/fate/ea.mak b/tests/fate/ea.mak
index d333042..2bffd47 100644
--- a/tests/fate/ea.mak
+++ b/tests/fate/ea.mak
@@ -1,23 +1,23 @@
 FATE_SAMPLES_AVCONV-$(call DEMDEC, EA_CDATA, ADPCM_EA_XAS) += fate-ea-cdata
-fate-ea-cdata: CMD = md5 -i $(SAMPLES)/ea-cdata/166b084d.46410f77.0009b440.24be960c.cdata -f s16le
+fate-ea-cdata: CMD = md5 -i $(TARGET_SAMPLES)/ea-cdata/166b084d.46410f77.0009b440.24be960c.cdata -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, EA, EACMV) += fate-ea-cmv
-fate-ea-cmv: CMD = framecrc -i $(SAMPLES)/ea-cmv/TITLE.CMV -pix_fmt rgb24
+fate-ea-cmv: CMD = framecrc -i $(TARGET_SAMPLES)/ea-cmv/TITLE.CMV -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, EA, EAMAD) += fate-ea-mad
-fate-ea-mad: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad -an
+fate-ea-mad: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/NFS6LogoE.mad -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, EA, EATGQ) += fate-ea-tgq
-fate-ea-tgq: CMD = framecrc -i $(SAMPLES)/ea-tgq/v27.tgq -an
+fate-ea-tgq: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgq/v27.tgq -an
 
 FATE_EA_TGV += fate-ea-tgv-1
-fate-ea-tgv-1: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an
+fate-ea-tgv-1: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an
 
 FATE_EA_TGV += fate-ea-tgv-2
-fate-ea-tgv-2: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24 -an
+fate-ea-tgv-2: CMD = framecrc -i $(TARGET_SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, EA, EATGV) += $(FATE_EA_TGV)
 fate-ea-tgv: $(FATE_EA_TGV)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, EA, EATQI) += fate-ea-tqi
-fate-ea-tqi: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26 -an
+fate-ea-tqi: CMD = framecrc -i $(TARGET_SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26 -an
diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
new file mode 100644
index 0000000..9bf148c
--- /dev/null
+++ b/tests/fate/filter-audio.mak
@@ -0,0 +1,75 @@
+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: 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: 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: REF = $(SAMPLES)/filter/amix_transition.pcm
+
+FATE_AFILTER-$(call FILTERDEMDECENCMUX, AMIX, WAV, PCM_S16LE, PCM_F32LE, PCM_F32LE) += $(FATE_AMIX)
+$(FATE_AMIX): tests/data/asynth-44100-2.wav tests/data/asynth-44100-2-2.wav
+$(FATE_AMIX): SRC  = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
+$(FATE_AMIX): SRC1 = $(TARGET_PATH)/tests/data/asynth-44100-2-2.wav
+$(FATE_AMIX): CMP  = oneoff
+$(FATE_AMIX): CMP_UNIT = f32
+
+FATE_AFILTER-$(call FILTERDEMDECMUX, ASYNCTS, FLV, NELLYMOSER, PCM_S16LE) += fate-filter-asyncts
+fate-filter-asyncts: SRC = $(TARGET_SAMPLES)/nellymoser/nellymoser-discont.flv
+fate-filter-asyncts: CMD = pcm -analyzeduration 10000000 -i $(SRC) -af asyncts
+fate-filter-asyncts: CMP = oneoff
+fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont.pcm
+
+FATE_ATRIM += fate-filter-atrim-duration
+fate-filter-atrim-duration: CMD = framecrc -i $(SRC) -af atrim=start=0.1:duration=0.01
+FATE_ATRIM += fate-filter-atrim-mixed
+fate-filter-atrim-mixed: CMD = framecrc -i $(SRC) -af atrim=start=0.05:start_sample=1025:end=0.1:end_sample=4411
+
+FATE_ATRIM += fate-filter-atrim-samples
+fate-filter-atrim-samples: CMD = framecrc -i $(SRC) -af atrim=start_sample=26:end_sample=80
+
+FATE_ATRIM += fate-filter-atrim-time
+fate-filter-atrim-time: CMD = framecrc -i $(SRC) -af atrim=0.1:0.2
+
+$(FATE_ATRIM): tests/data/asynth-44100-2.wav
+$(FATE_ATRIM): SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
+
+FATE_FILTER-$(call FILTERDEMDECENCMUX, ATRIM, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_ATRIM)
+
+FATE_AFILTER-$(call FILTERDEMDECENCMUX, CHANNELMAP, WAV, PCM_S16LE, PCM_S16LE, WAV) += fate-filter-channelmap
+fate-filter-channelmap: tests/data/filtergraphs/channelmap
+fate-filter-channelmap: SRC = $(TARGET_PATH)/tests/data/asynth-44100-6.wav
+fate-filter-channelmap: tests/data/asynth-44100-6.wav
+fate-filter-channelmap: CMD = md5 -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap -f wav -flags +bitexact
+fate-filter-channelmap: CMP = oneline
+fate-filter-channelmap: REF = 21f1977c4f9705e2057083f84764e685
+
+FATE_AFILTER-$(call FILTERDEMDECENCMUX, CHANNELSPLIT, WAV, PCM_S16LE, PCM_S16LE, PCM_S16LE) += fate-filter-channelsplit
+fate-filter-channelsplit: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
+fate-filter-channelsplit: tests/data/asynth-44100-2.wav
+fate-filter-channelsplit: CMD = md5 -i $(SRC) -filter_complex channelsplit -f s16le
+fate-filter-channelsplit: CMP = oneline
+fate-filter-channelsplit: REF = d92988d0fe2dd92236763f47b07ab597
+
+FATE_AFILTER-$(call FILTERDEMDECENCMUX, JOIN, WAV, PCM_S16LE, PCM_S16LE, PCM_S16LE) += fate-filter-join
+fate-filter-join: SRC1 = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
+fate-filter-join: SRC2 = $(TARGET_PATH)/tests/data/asynth-44100-3.wav
+fate-filter-join: tests/data/asynth-44100-2.wav tests/data/asynth-44100-3.wav
+fate-filter-join: CMD = md5 -i $(SRC1) -i $(SRC2) -filter_complex join=channel_layout=5 -f s16le
+fate-filter-join: CMP = oneline
+fate-filter-join: REF = 409e66fc5ece4ddea4aa16bc47026bb0
+
+FATE_AFILTER-$(call FILTERDEMDECENCMUX, VOLUME, WAV, PCM_S16LE, PCM_S16LE, PCM_S16LE) += fate-filter-volume
+fate-filter-volume: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
+fate-filter-volume: tests/data/asynth-44100-2.wav
+fate-filter-volume: CMD = md5 -i $(SRC) -af volume=precision=fixed:volume=0.5 -f s16le
+fate-filter-volume: CMP = oneline
+fate-filter-volume: REF = 4d6ba75ef3e32d305d066b9bc771d6f4
+
+FATE_SAMPLES_AVCONV += $(FATE_AFILTER-yes)
+fate-afilter: $(FATE_AFILTER-yes)
diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
new file mode 100644
index 0000000..4191af3
--- /dev/null
+++ b/tests/fate/filter-video.mak
@@ -0,0 +1,139 @@
+FATE_FILTER-$(call FILTERDEMDEC, DELOGO, RM, RV30) += fate-filter-delogo
+fate-filter-delogo: CMD = framecrc -i $(TARGET_SAMPLES)/real/rv30.rm -vf delogo=show=0:x=290:y=25:w=26:h=16 -an
+
+FATE_YADIF += fate-filter-yadif-mode0
+fate-filter-yadif-mode0: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vf yadif=0
+
+FATE_YADIF += fate-filter-yadif-mode1
+fate-filter-yadif-mode1: CMD = framecrc -flags bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vf yadif=1
+
+FATE_FILTER-$(call FILTERDEMDEC, YADIF, MPEGTS, MPEG2VIDEO) += $(FATE_YADIF)
+
+FATE_SAMPLES_AVCONV += $(FATE_FILTER-yes)
+
+
+FATE_FILTER_VSYNTH-$(CONFIG_BOXBLUR_FILTER) += fate-filter-boxblur
+fate-filter-boxblur: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf boxblur=2:1
+
+FATE_FILTER_VSYNTH-$(CONFIG_DRAWBOX_FILTER) += fate-filter-drawbox
+fate-filter-drawbox: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf drawbox=10:20:200:60:red at 0.5
+
+FATE_FILTER_VSYNTH-$(CONFIG_FADE_FILTER) += fate-filter-fade
+fate-filter-fade: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf fade=in:0:25,fade=out:25:25
+
+FATE_FILTER_VSYNTH-$(call ALLYES, INTERLACE_FILTER FIELDORDER_FILTER) += fate-filter-fieldorder
+fate-filter-fieldorder: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace=tff,fieldorder=bff -sws_flags +accurate_rnd+bitexact
+
+FATE_FILTER_VSYNTH-$(CONFIG_GRADFUN_FILTER) += fate-filter-gradfun
+fate-filter-gradfun: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf gradfun
+
+FATE_FILTER_VSYNTH-$(CONFIG_HQDN3D_FILTER) += fate-filter-hqdn3d
+fate-filter-hqdn3d: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf hqdn3d
+
+FATE_FILTER_VSYNTH-$(CONFIG_INTERLACE_FILTER) += fate-filter-interlace
+fate-filter-interlace: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf interlace
+
+FATE_FILTER_VSYNTH-$(CONFIG_NEGATE_FILTER) += fate-filter-negate
+fate-filter-negate: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf negate
+
+FATE_FILTER_VSYNTH-$(CONFIG_OVERLAY_FILTER) += fate-filter-overlay
+fate-filter-overlay: tests/data/filtergraphs/overlay
+fate-filter-overlay: CMD = framecrc -c:v pgmyuv -i $(SRC) -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay
+
+FATE_FILTER_VSYNTH-$(CONFIG_SELECT_FILTER) += fate-filter-select-alternate
+fate-filter-select-alternate: tests/data/filtergraphs/select-alternate
+fate-filter-select-alternate: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_script $(TARGET_PATH)/tests/data/filtergraphs/select-alternate
+
+FATE_FILTER_VSYNTH-$(call ALLYES, SETPTS_FILTER  SETTB_FILTER) += fate-filter-setpts
+fate-filter-setpts: tests/data/filtergraphs/setpts
+fate-filter-setpts: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_script $(TARGET_PATH)/tests/data/filtergraphs/setpts
+
+FATE_FILTER_VSYNTH-$(CONFIG_TRANSPOSE_FILTER) += fate-filter-transpose
+fate-filter-transpose: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf transpose
+
+FATE_TRIM += fate-filter-trim-duration
+fate-filter-trim-duration: CMD = framecrc -i $(SRC) -vf trim=start=0.4:duration=0.05
+
+FATE_TRIM += fate-filter-trim-frame
+fate-filter-trim-frame: CMD = framecrc -i $(SRC) -vf trim=start_frame=3:end_frame=10
+
+FATE_TRIM += fate-filter-trim-mixed
+fate-filter-trim-mixed: CMD = framecrc -i $(SRC) -vf trim=start=0.2:end=0.4:start_frame=1:end_frame=3
+
+FATE_TRIM += fate-filter-trim-time
+fate-filter-trim-time: CMD = framecrc -i $(SRC) -vf trim=0:0.09
+
+FATE_FILTER_VSYNTH-$(CONFIG_TRIM_FILTER) += $(FATE_TRIM)
+
+FATE_FILTER_VSYNTH-$(CONFIG_UNSHARP_FILTER) += fate-filter-unsharp
+fate-filter-unsharp: CMD = framecrc -c:v pgmyuv -i $(SRC) -vf unsharp
+
+
+FATE_FILTER_VSYNTH-$(CONFIG_CROP_FILTER) += fate-filter-crop
+fate-filter-crop: CMD = video_filter "crop=iw-100:ih-100:100:100"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, CROP_FILTER SCALE_FILTER) += fate-filter-crop_scale
+fate-filter-crop_scale: CMD = video_filter "crop=iw-100:ih-100:100:100,scale=w=400:h=-1"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, CROP_FILTER SCALE_FILTER VFLIP_FILTER) += fate-filter-crop_scale_vflip
+fate-filter-crop_scale_vflip: CMD = video_filter "null,null,crop=iw-200:ih-200:200:200,crop=iw-20:ih-20:20:20,scale=w=200:h=200,scale=w=250:h=250,vflip,vflip,null,scale=w=200:h=200,crop=iw-100:ih-100:100:100,vflip,scale=w=200:h=200,null,vflip,crop=iw-100:ih-100:100:100,null"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, CROP_FILTER VFLIP_FILTER) += fate-filter-crop_vflip
+fate-filter-crop_vflip: CMD = video_filter "crop=iw-100:ih-100:100:100,vflip"
+
+FATE_FILTER_VSYNTH-$(CONFIG_NULL_FILTER) += fate-filter-null
+fate-filter-null: CMD = video_filter "null"
+
+FATE_FILTER_VSYNTH-$(CONFIG_SCALE_FILTER) += fate-filter-scale200
+fate-filter-scale200: CMD = video_filter "scale=w=200:h=200"
+
+FATE_FILTER_VSYNTH-$(CONFIG_SCALE_FILTER) += fate-filter-scale500
+fate-filter-scale500: CMD = video_filter "scale=w=500:h=500"
+
+FATE_FILTER_VSYNTH-$(CONFIG_VFLIP_FILTER) += fate-filter-vflip
+fate-filter-vflip: CMD = video_filter "vflip"
+
+FATE_FILTER_VSYNTH-$(call ALLYES, CROP_FILTER VFLIP_FILTER) += fate-filter-vflip_crop
+fate-filter-vflip_crop: CMD = video_filter "vflip,crop=iw-100:ih-100:100:100"
+
+FATE_FILTER_VSYNTH-$(CONFIG_VFLIP_FILTER) += fate-filter-vflip_vflip
+fate-filter-vflip_vflip: CMD = video_filter "vflip,vflip"
+
+
+FATE_FILTER_VSYNTH-$(CONFIG_FORMAT_FILTER) += fate-filter-pixdesc
+fate-filter-pixdesc: CMD = pixdesc
+
+
+FATE_FILTER_PIXFMTS += fate-filter-pixfmts-copy
+fate-filter-pixfmts-copy:  CMD = pixfmts
+
+FATE_FILTER_PIXFMTS += fate-filter-pixfmts-crop
+fate-filter-pixfmts-crop:  CMD = pixfmts "100:100:100:100"
+
+FATE_FILTER_PIXFMTS += fate-filter-pixfmts-hflip
+fate-filter-pixfmts-hflip: CMD = pixfmts
+
+FATE_FILTER_PIXFMTS += fate-filter-pixfmts-null
+fate-filter-pixfmts-null:  CMD = pixfmts
+
+FATE_FILTER_PIXFMTS += fate-filter-pixfmts-pad
+fate-filter-pixfmts-pad:   CMD = pixfmts "500:400:20:20"
+
+FATE_FILTER_PIXFMTS += fate-filter-pixfmts-scale
+fate-filter-pixfmts-scale: CMD = pixfmts "200:100"
+
+FATE_FILTER_PIXFMTS += fate-filter-pixfmts-vflip
+fate-filter-pixfmts-vflip: CMD = pixfmts
+
+$(FATE_FILTER_PIXFMTS): libavfilter/filtfmts-test$(EXESUF)
+FATE_FILTER_VSYNTH-$(CONFIG_FORMAT_FILTER) += $(FATE_FILTER_PIXFMTS)
+
+
+$(FATE_FILTER_VSYNTH-yes): $(VREF)
+$(FATE_FILTER_VSYNTH-yes): SRC = $(TARGET_PATH)/tests/vsynth1/%02d.pgm
+
+FATE_AVCONV-$(call DEMDEC, IMAGE2, PGMYUV) += $(FATE_FILTER_VSYNTH-yes)
+
+fate-vfilter: $(FATE_FILTER-yes) $(FATE_FILTER_VSYNTH-yes)
+
+fate-filter: fate-afilter fate-vfilter
diff --git a/tests/fate/filter.mak b/tests/fate/filter.mak
deleted file mode 100644
index f16aee1..0000000
--- a/tests/fate/filter.mak
+++ /dev/null
@@ -1,42 +0,0 @@
-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: 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: 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: REF = $(SAMPLES)/filter/amix_transition.pcm
-
-$(FATE_AMIX): tests/data/asynth-44100-2.wav tests/data/asynth-44100-2-2.wav
-$(FATE_AMIX): SRC  = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
-$(FATE_AMIX): SRC1 = $(TARGET_PATH)/tests/data/asynth-44100-2-2.wav
-$(FATE_AMIX): CMP  = oneoff
-$(FATE_AMIX): CMP_UNIT = f32
-
-FATE_FILTER-$(CONFIG_AMIX_FILTER) += $(FATE_AMIX)
-
-FATE_FILTER-$(CONFIG_ASYNCTS_FILTER) += fate-filter-asyncts
-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-delogo: CMD = framecrc -i $(SAMPLES)/real/rv30.rm -vf delogo=show=0:x=290:y=25:w=26:h=16 -an
-
-FATE_FILTER-$(CONFIG_DELOGO_FILTER) += fate-filter-delogo
-
-FATE_YADIF += fate-filter-yadif-mode0
-fate-filter-yadif-mode0: CMD = framecrc -flags bitexact -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vf yadif=0
-
-FATE_YADIF += fate-filter-yadif-mode1
-fate-filter-yadif-mode1: CMD = framecrc -flags bitexact -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -vf yadif=1
-
-FATE_FILTER-$(CONFIG_YADIF_FILTER) += $(FATE_YADIF)
-
-FATE_SAMPLES_AVCONV += $(FATE_FILTER-yes)
-fate-filter: $(FATE_FILTER-yes)
diff --git a/tests/fate/flac.mak b/tests/fate/flac.mak
index 92eb743..e28f45f 100644
--- a/tests/fate/flac.mak
+++ b/tests/fate/flac.mak
@@ -12,12 +12,12 @@ fate-flac-16-fixed:    OPTS = -lpc_type fixed
 fate-flac-16-lpc-%:    OPTS = -lpc_type $(@:fate-flac-16-lpc-%=%)
 
 fate-flac-16-%: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
-fate-flac-16-%: CMD = enc_dec_pcm flac wav s16le $(REF) -c flac $(OPTS)
+fate-flac-16-%: CMD = enc_dec_pcm flac wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c flac $(OPTS)
 
 fate-flac-24-comp-%: OPTS = -compression_level $(@:fate-flac-24-comp-%=%)
 
 fate-flac-24-%: REF = $(SAMPLES)/audio-reference/divertimenti_2ch_96kHz_s24.wav
-fate-flac-24-%: CMD = enc_dec_pcm flac wav s24le $(REF) -c flac $(OPTS)
+fate-flac-24-%: CMD = enc_dec_pcm flac wav s24le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c flac $(OPTS)
 
 fate-flac-%: CMP = oneoff
 fate-flac-%: FUZZ = 0
diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak
index 02ed110..13bbd11 100644
--- a/tests/fate/h264.mak
+++ b/tests/fate/h264.mak
@@ -64,6 +64,7 @@ FATE_H264 = aud_mw_e                                                    \
             ci_mw_d                                                     \
             cvbs3_sony_c                                                \
             cvcanlma2_sony_c                                            \
+            cvfc1_sony_c                                                \
             cvfi1_sony_d                                                \
             cvfi1_sva_c                                                 \
             cvfi2_sony_h                                                \
@@ -171,191 +172,202 @@ FATE_H264 = aud_mw_e                                                    \
             sva_nl1_b                                                   \
             sva_nl2_e                                                   \
 
+FATE_H264_REINIT_TESTS := large_420_8-to-small_420_8                    \
+                          small_420_8-to-large_444_10                   \
+                          small_420_9-to-small_420_8                    \
+                          small_422_9-to-small_420_9                    \
+
 FATE_H264  := $(FATE_H264:%=fate-h264-conformance-%)                    \
+              $(FATE_H264_REINIT_TESTS:%=fate-h264-reinit-%)            \
               fate-h264-extreme-plane-pred                              \
               fate-h264-lossless                                        \
 
 FATE_H264-$(call DEMDEC, H264, H264) += $(FATE_H264)
+FATE_H264-$(call DEMDEC,  MOV, H264) += fate-h264-crop-to-container
 FATE_H264-$(call DEMDEC,  MOV, H264) += fate-h264-interlace-crop
 FATE_H264-$(call ALLYES, MOV_DEMUXER H264_MP4TOANNEXB_BSF) += fate-h264-bsf-mp4toannexb
 
 FATE_SAMPLES_AVCONV += $(FATE_H264-yes)
 fate-h264: $(FATE_H264-yes)
 
-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 -i $(TARGET_SAMPLES)/h264-conformance/AUD_MW_E.264
+fate-h264-conformance-ba1_ft_c:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BA1_FT_C.264
+fate-h264-conformance-ba1_sony_d:                 CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BA1_Sony_D.jsv
+fate-h264-conformance-ba2_sony_f:                 CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BA2_Sony_F.jsv
+fate-h264-conformance-ba3_sva_c:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BA3_SVA_C.264
+fate-h264-conformance-ba_mw_d:                    CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BA_MW_D.264
+fate-h264-conformance-bamq1_jvc_c:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BAMQ1_JVC_C.264
+fate-h264-conformance-bamq2_jvc_c:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BAMQ2_JVC_C.264
+fate-h264-conformance-banm_mw_d:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BANM_MW_D.264
+fate-h264-conformance-basqp1_sony_c:              CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/BASQP1_Sony_C.jsv
+fate-h264-conformance-caba1_sony_d:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA1_Sony_D.jsv
+fate-h264-conformance-caba1_sva_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA1_SVA_B.264
+fate-h264-conformance-caba2_sony_e:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA2_Sony_E.jsv
+fate-h264-conformance-caba2_sva_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA2_SVA_B.264
+fate-h264-conformance-caba3_sony_c:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA3_Sony_C.jsv
+fate-h264-conformance-caba3_sva_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA3_SVA_B.264
+fate-h264-conformance-caba3_toshiba_e:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABA3_TOSHIBA_E.264
+fate-h264-conformance-cabac_mot_fld0_full:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_fld0_full.26l
+fate-h264-conformance-cabac_mot_frm0_full:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_frm0_full.26l
+fate-h264-conformance-cabac_mot_mbaff0_full:      CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l
+fate-h264-conformance-cabac_mot_picaff0_full:     CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l
+fate-h264-conformance-cabaci3_sony_b:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv
+fate-h264-conformance-cabast3_sony_e:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv
+fate-h264-conformance-cabastbr3_sony_b:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv
+fate-h264-conformance-cabref3_sand_d:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CABREF3_Sand_D.264
+fate-h264-conformance-cacqp3_sony_d:              CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv
+fate-h264-conformance-cafi1_sva_c:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAFI1_SVA_C.264
+fate-h264-conformance-cama1_sony_c:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMA1_Sony_C.jsv
+fate-h264-conformance-cama1_toshiba_b:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264
+fate-h264-conformance-cama1_vtc_c:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cama1_vtc_c.avc
+fate-h264-conformance-cama2_vtc_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cama2_vtc_b.avc
+fate-h264-conformance-cama3_sand_e:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMA3_Sand_E.264
+fate-h264-conformance-cama3_vtc_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cama3_vtc_b.avc
+fate-h264-conformance-camaci3_sony_c:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv
+fate-h264-conformance-camanl1_toshiba_b:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264
+fate-h264-conformance-camanl2_toshiba_b:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264
+fate-h264-conformance-camanl3_sand_e:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMANL3_Sand_E.264
+fate-h264-conformance-camasl3_sony_b:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv
+fate-h264-conformance-camp_mot_mbaff_l30:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l
+fate-h264-conformance-camp_mot_mbaff_l31:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l
+fate-h264-conformance-canl1_sony_e:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL1_Sony_E.jsv
+fate-h264-conformance-canl1_sva_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL1_SVA_B.264
+fate-h264-conformance-canl1_toshiba_g:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL1_TOSHIBA_G.264
+fate-h264-conformance-canl2_sony_e:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL2_Sony_E.jsv
+fate-h264-conformance-canl2_sva_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL2_SVA_B.264
+fate-h264-conformance-canl3_sony_c:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL3_Sony_C.jsv
+fate-h264-conformance-canl3_sva_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL3_SVA_B.264
+fate-h264-conformance-canl4_sva_b:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANL4_SVA_B.264
+fate-h264-conformance-canlma2_sony_c:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANLMA2_Sony_C.jsv
+fate-h264-conformance-canlma3_sony_c:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CANLMA3_Sony_C.jsv
+fate-h264-conformance-capa1_toshiba_b:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264
+fate-h264-conformance-capama3_sand_f:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264
+fate-h264-conformance-capcm1_sand_e:              CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPCM1_Sand_E.264
+fate-h264-conformance-capcmnl1_sand_e:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPCMNL1_Sand_E.264
+fate-h264-conformance-capm3_sony_d:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv
+fate-h264-conformance-caqp1_sony_b:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAQP1_Sony_B.jsv
+fate-h264-conformance-cavlc_mot_fld0_full_b:      CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l
+fate-h264-conformance-cavlc_mot_frm0_full_b:      CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l
+fate-h264-conformance-cavlc_mot_mbaff0_full_b:    CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l
+fate-h264-conformance-cavlc_mot_picaff0_full_b:   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l
+fate-h264-conformance-cawp1_toshiba_e:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAWP1_TOSHIBA_E.264
+fate-h264-conformance-cawp5_toshiba_e:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264
+fate-h264-conformance-ci1_ft_b:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CI1_FT_B.264
+fate-h264-conformance-ci_mw_d:                    CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CI_MW_D.264
+fate-h264-conformance-cvbs3_sony_c:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv
+fate-h264-conformance-cvcanlma2_sony_c:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVCANLMA2_Sony_C.jsv
+fate-h264-conformance-cvfc1_sony_c:               CMD = framecrc -flags unaligned -i $(TARGET_SAMPLES)/h264-conformance/CVFC1_Sony_C.jsv
+fate-h264-conformance-cvfi1_sony_d:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv
+fate-h264-conformance-cvfi1_sva_c:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVFI1_SVA_C.264
+fate-h264-conformance-cvfi2_sony_h:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv
+fate-h264-conformance-cvfi2_sva_c:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVFI2_SVA_C.264
+fate-h264-conformance-cvma1_sony_d:               CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMA1_Sony_D.jsv
+fate-h264-conformance-cvma1_toshiba_b:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264
+fate-h264-conformance-cvmanl1_toshiba_b:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264
+fate-h264-conformance-cvmanl2_toshiba_b:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264
+fate-h264-conformance-cvmapaqp3_sony_e:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv
+fate-h264-conformance-cvmaqp2_sony_g:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv
+fate-h264-conformance-cvmaqp3_sony_d:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv
+fate-h264-conformance-cvmp_mot_fld_l30_b:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l
+fate-h264-conformance-cvmp_mot_frm_l31_b:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l
+fate-h264-conformance-cvnlfi1_sony_c:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVNLFI1_Sony_C.jsv
+fate-h264-conformance-cvnlfi2_sony_h:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv
+fate-h264-conformance-cvpa1_toshiba_b:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264
+fate-h264-conformance-cvpcmnl1_sva_c:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVPCMNL1_SVA_C.264
+fate-h264-conformance-cvpcmnl2_sva_c:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVPCMNL2_SVA_C.264
+fate-h264-conformance-cvwp1_toshiba_e:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVWP1_TOSHIBA_E.264
+fate-h264-conformance-cvwp2_toshiba_e:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264
+fate-h264-conformance-cvwp3_toshiba_e:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264
+fate-h264-conformance-cvwp5_toshiba_e:            CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264
+fate-h264-conformance-fi1_sony_e:                 CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FI1_Sony_E.jsv
+fate-h264-conformance-frext-alphaconformanceg:    CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/test8b43.264
+fate-h264-conformance-frext-bcrm_freh10:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh10.264 -vsync 0
+fate-h264-conformance-frext-brcm_freh11:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh11.264 -vsync 0
+fate-h264-conformance-frext-brcm_freh3:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh3.264
+fate-h264-conformance-frext-brcm_freh4:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh4.264 -vsync 0
+fate-h264-conformance-frext-brcm_freh5:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh5.264
+fate-h264-conformance-frext-brcm_freh8:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh8.264
+fate-h264-conformance-frext-brcm_freh9:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh9.264
+fate-h264-conformance-frext-freh12_b:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh12_B.264
+fate-h264-conformance-frext-freh1_b:              CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh1_B.264
+fate-h264-conformance-frext-freh2_b:              CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh2_B.264
+fate-h264-conformance-frext-freh6:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/freh6.264 -vsync 0
+fate-h264-conformance-frext-freh7_b:              CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/Freh7_B.264 -vsync 0
+fate-h264-conformance-frext-frext01_jvc_d:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FREXT01_JVC_D.264
+fate-h264-conformance-frext-frext02_jvc_c:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FREXT02_JVC_C.264
+fate-h264-conformance-frext-frext1_panasonic_c:   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt1_Panasonic.avc
+fate-h264-conformance-frext-frext2_panasonic_b:   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt2_Panasonic.avc -vsync 0
+fate-h264-conformance-frext-frext3_panasonic_d:   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt3_Panasonic.avc
+fate-h264-conformance-frext-frext4_panasonic_a:   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt4_Panasonic.avc
+fate-h264-conformance-frext-frext_mmco4_sony_b:   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/FRExt_MMCO4_Sony_B.264
+fate-h264-conformance-frext-hcaff1_hhi_b:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFF1_HHI.264
+fate-h264-conformance-frext-hcafr1_hhi_c:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR1_HHI.264
+fate-h264-conformance-frext-hcafr2_hhi_a:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR2_HHI.264
+fate-h264-conformance-frext-hcafr3_hhi_a:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR3_HHI.264
+fate-h264-conformance-frext-hcafr4_hhi_a:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAFR4_HHI.264
+fate-h264-conformance-frext-hcamff1_hhi_b:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HCAMFF1_HHI.264
+fate-h264-conformance-frext-hpca_brcm_c:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCA_BRCM_C.264
+fate-h264-conformance-frext-hpcadq_brcm_b:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCADQ_BRCM_B.264
+fate-h264-conformance-frext-hpcafl_bcrm_c:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAFL_BRCM_C.264 -vsync 0
+fate-h264-conformance-frext-hpcaflnl_bcrm_c:      CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAFLNL_BRCM_C.264 -vsync 0
+fate-h264-conformance-frext-hpcalq_brcm_b:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCALQ_BRCM_B.264
+fate-h264-conformance-frext-hpcamapalq_bcrm_b:    CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAMAPALQ_BRCM_B.264 -vsync 0
+fate-h264-conformance-frext-hpcamolq_brcm_b:      CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAMOLQ_BRCM_B.264
+fate-h264-conformance-frext-hpcanl_brcm_c:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCANL_BRCM_C.264
+fate-h264-conformance-frext-hpcaq2lq_brcm_b:      CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCAQ2LQ_BRCM_B.264
+fate-h264-conformance-frext-hpcv_brcm_a:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCV_BRCM_A.264
+fate-h264-conformance-frext-hpcvfl_bcrm_a:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVFL_BRCM_A.264 -vsync 0
+fate-h264-conformance-frext-hpcvflnl_bcrm_a:      CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVFLNL_BRCM_A.264 -vsync 0
+fate-h264-conformance-frext-hpcvmolq_brcm_b:      CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVMOLQ_BRCM_B.264
+fate-h264-conformance-frext-hpcvnl_brcm_a:        CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/HPCVNL_BRCM_A.264
+fate-h264-conformance-frext-pph10i1_panasonic_a:  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I1_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i2_panasonic_a:  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I2_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i3_panasonic_a:  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I3_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i4_panasonic_a:  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I4_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i5_panasonic_a:  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i6_panasonic_a:  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i7_panasonic_a:  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-hcbp2_hhi_a:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/HCBP2_HHI_A.264
+fate-h264-conformance-hcmp1_hhi_a:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/HCMP1_HHI_A.264
+fate-h264-conformance-ls_sva_d:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/LS_SVA_D.264
+fate-h264-conformance-midr_mw_d:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MIDR_MW_D.264
+fate-h264-conformance-mps_mw_a:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MPS_MW_A.264
+fate-h264-conformance-mr1_bt_a:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR1_BT_A.h264
+fate-h264-conformance-mr1_mw_a:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR1_MW_A.264
+fate-h264-conformance-mr2_mw_a:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR2_MW_A.264
+fate-h264-conformance-mr2_tandberg_e:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR2_TANDBERG_E.264
+fate-h264-conformance-mr3_tandberg_b:             CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR3_TANDBERG_B.264
+fate-h264-conformance-mr4_tandberg_c:             CMD = framecrc -strict 1 -i $(TARGET_SAMPLES)/h264-conformance/MR4_TANDBERG_C.264
+fate-h264-conformance-mr5_tandberg_c:             CMD = framecrc -strict 1 -i $(TARGET_SAMPLES)/h264-conformance/MR5_TANDBERG_C.264
+fate-h264-conformance-mr6_bt_b:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR6_BT_B.h264
+fate-h264-conformance-mr7_bt_b:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR7_BT_B.h264
+fate-h264-conformance-mr8_bt_b:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR8_BT_B.h264
+fate-h264-conformance-mr9_bt_b:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/MR9_BT_B.h264
+fate-h264-conformance-mv1_brcm_d:                 CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/src19td.IBP.264
+fate-h264-conformance-nl1_sony_d:                 CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NL1_Sony_D.jsv
+fate-h264-conformance-nl2_sony_h:                 CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NL2_Sony_H.jsv
+fate-h264-conformance-nl3_sva_e:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NL3_SVA_E.264
+fate-h264-conformance-nlmq1_jvc_c:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NLMQ1_JVC_C.264
+fate-h264-conformance-nlmq2_jvc_c:                CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NLMQ2_JVC_C.264
+fate-h264-conformance-nrf_mw_e:                   CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/NRF_MW_E.264
+fate-h264-conformance-sharp_mp_field_1_b:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_1_B.jvt
+fate-h264-conformance-sharp_mp_field_2_b:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_2_B.jvt
+fate-h264-conformance-sharp_mp_field_3_b:         CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_Field_3_B.jvt
+fate-h264-conformance-sharp_mp_paff_1r2:          CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt
+fate-h264-conformance-sharp_mp_paff_2r:           CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt
+fate-h264-conformance-sl1_sva_b:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SL1_SVA_B.264
+fate-h264-conformance-sva_ba1_b:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_BA1_B.264
+fate-h264-conformance-sva_ba2_d:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_BA2_D.264
+fate-h264-conformance-sva_base_b:                 CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_Base_B.264
+fate-h264-conformance-sva_cl1_e:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_CL1_E.264
+fate-h264-conformance-sva_fm1_e:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_FM1_E.264
+fate-h264-conformance-sva_nl1_b:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL1_B.264
+fate-h264-conformance-sva_nl2_e:                  CMD = framecrc -i $(TARGET_SAMPLES)/h264-conformance/SVA_NL2_E.264
+
+fate-h264-bsf-mp4toannexb:                        CMD = md5 -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f h264
+fate-h264-crop-to-container:                      CMD = framemd5 -i $(TARGET_SAMPLES)/h264/crop-to-container-dims-canon.mov
+fate-h264-extreme-plane-pred:                     CMD = framemd5 -i $(TARGET_SAMPLES)/h264/extreme-plane-pred.h264
+fate-h264-interlace-crop:                         CMD = framecrc -i $(TARGET_SAMPLES)/h264/interlaced_crop.mp4 -vframes 3
+fate-h264-lossless:                               CMD = framecrc -i $(TARGET_SAMPLES)/h264/lossless.h264
 
-fate-h264-bsf-mp4toannexb:                        CMD = md5 -i $(SAMPLES)/h264/interlaced_crop.mp4 -vcodec copy -bsf h264_mp4toannexb -f h264
-fate-h264-extreme-plane-pred:                     CMD = framemd5 -i $(SAMPLES)/h264/extreme-plane-pred.h264
-fate-h264-interlace-crop:                         CMD = framecrc -i $(SAMPLES)/h264/interlaced_crop.mp4 -vframes 3
-fate-h264-lossless:                               CMD = framecrc -i $(SAMPLES)/h264/lossless.h264
+fate-h264-reinit-%:                               CMD = framecrc -i $(TARGET_SAMPLES)/h264/$(@:fate-h264-%=%).h264 -vf format=yuv444p10le,scale=w=352:h=288
diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak
new file mode 100644
index 0000000..d5d49ce
--- /dev/null
+++ b/tests/fate/hevc.mak
@@ -0,0 +1,156 @@
+HEVC_SAMPLES =                  \
+    AMP_A_Samsung_4             \
+    AMP_B_Samsung_4             \
+    AMVP_C_Samsung_4            \
+    AMP_D_Hisilicon             \
+    AMP_E_Hisilicon             \
+    AMP_F_Hisilicon_3           \
+    AMVP_A_MTK_4                \
+    AMVP_B_MTK_4                \
+    CAINIT_A_SHARP_4            \
+    CAINIT_B_SHARP_4            \
+    CAINIT_C_SHARP_3            \
+    CAINIT_D_SHARP_3            \
+    CAINIT_E_SHARP_3            \
+    CAINIT_F_SHARP_3            \
+    CAINIT_G_SHARP_3            \
+    CAINIT_H_SHARP_3            \
+    CIP_A_Panasonic_3           \
+    cip_B_NEC_2                 \
+    CIP_C_Panasonic_2           \
+    DBLK_A_SONY_3               \
+    DBLK_B_SONY_3               \
+    DBLK_C_SONY_3               \
+    DBLK_D_VIXS_1               \
+    DBLK_D_VIXS_2               \
+    DBLK_E_VIXS_1               \
+    DBLK_E_VIXS_2               \
+    DBLK_F_VIXS_1               \
+    DBLK_F_VIXS_2               \
+    DBLK_G_VIXS_1               \
+    DBLK_G_VIXS_2               \
+    DELTAQP_B_SONY_3            \
+    DELTAQP_C_SONY_3            \
+    DSLICE_A_HHI_5              \
+    DSLICE_B_HHI_5              \
+    DSLICE_C_HHI_5              \
+    ENTP_A_LG_2                 \
+    ENTP_B_LG_2                 \
+    ENTP_C_LG_3                 \
+    EXT_A_ericsson_3            \
+    ipcm_A_NEC_2                \
+    ipcm_B_NEC_2                \
+    ipcm_C_NEC_2                \
+    ipcm_D_NEC_2                \
+    IPRED_A_docomo_2            \
+    IPRED_B_Nokia_3             \
+    IPRED_C_Mitsubishi_2        \
+    LS_A_Orange_2               \
+    LS_B_ORANGE_3               \
+    MAXBINS_A_TI_4              \
+    MAXBINS_B_TI_4              \
+    MAXBINS_C_TI_4              \
+    MERGE_A_TI_3                \
+    MERGE_B_TI_3                \
+    MERGE_C_TI_3                \
+    MERGE_D_TI_3                \
+    MERGE_E_TI_3                \
+    MERGE_F_MTK_4               \
+    MERGE_G_HHI_4               \
+    MVCLIP_A_qualcomm_3         \
+    MVDL1ZERO_A_docomo_3        \
+    MVEDGE_A_qualcomm_3         \
+    NUT_A_ericsson_4            \
+    PICSIZE_A_Bossen_1          \
+    PICSIZE_B_Bossen_1          \
+    PICSIZE_C_Bossen_1          \
+    PICSIZE_D_Bossen_1          \
+    PMERGE_A_TI_3               \
+    PMERGE_B_TI_3               \
+    PMERGE_C_TI_3               \
+    PMERGE_D_TI_3               \
+    PMERGE_E_TI_3               \
+    POC_A_Bossen_3              \
+    PPS_A_qualcomm_7            \
+    RAP_A_docomo_4              \
+    PS_A_VIDYO_3                \
+    PS_B_VIDYO_3                \
+    RAP_B_Bossen_1              \
+    RPLM_A_qualcomm_4           \
+    RPLM_B_qualcomm_4           \
+    RPS_A_docomo_4              \
+    RPS_B_qualcomm_5            \
+    RPS_C_ericsson_4            \
+    RPS_D_ericsson_5            \
+    RPS_E_qualcomm_5            \
+    RQT_A_HHI_4                 \
+    RQT_B_HHI_4                 \
+    RQT_C_HHI_4                 \
+    RQT_D_HHI_4                 \
+    RQT_E_HHI_4                 \
+    RQT_F_HHI_4                 \
+    RQT_G_HHI_4                 \
+    SAO_A_MediaTek_4            \
+    SAO_B_MediaTek_5            \
+    SAO_C_Samsung_4             \
+    SAO_D_Samsung_4             \
+    SAO_E_Canon_4               \
+    SAO_F_Canon_3               \
+    SAO_G_Canon_3               \
+    SDH_A_Orange_3              \
+    SLICES_A_Rovi_3             \
+    SLIST_A_Sony_4              \
+    SLIST_B_Sony_8              \
+    SLIST_C_Sony_3              \
+    SLIST_D_Sony_9              \
+    STRUCT_A_Samsung_5          \
+    STRUCT_B_Samsung_4          \
+    TILES_A_Cisco_2             \
+    TILES_B_Cisco_1             \
+    TMVP_A_MS_2                 \
+    TSCL_A_VIDYO_5              \
+    TSCL_B_VIDYO_4              \
+    TSKIP_A_MS_2                \
+    WP_A_Toshiba_3              \
+    WP_B_Toshiba_3              \
+    WPP_A_ericsson_MAIN_2       \
+    WPP_B_ericsson_MAIN_2       \
+    WPP_C_ericsson_MAIN_2       \
+    WPP_D_ericsson_MAIN_2       \
+    WPP_E_ericsson_MAIN_2       \
+    WPP_F_ericsson_MAIN_2       \
+
+HEVC_SAMPLES_10BIT =            \
+    DBLK_A_MAIN10_VIXS_2        \
+    WP_A_MAIN10_Toshiba_3       \
+    WP_MAIN10_B_Toshiba_3       \
+    WPP_A_ericsson_MAIN10_2     \
+    WPP_B_ericsson_MAIN10_2     \
+    WPP_C_ericsson_MAIN10_2     \
+    WPP_D_ericsson_MAIN10_2     \
+    WPP_E_ericsson_MAIN10_2     \
+    WPP_F_ericsson_MAIN10_2     \
+
+# do not pass:
+# DELTAQP_A_BRCM_4.bit -- TODO uses CRC instead of MD5
+# HRD_A_Fujitsu_2.bin -- TODO uses hash 2 ("checksum")
+# TSUNEQBD_A_MAIN10_Technicolor_2.bit (segfault)
+
+define FATE_HEVC_TEST
+FATE_HEVC += fate-hevc-conformance-$(1)
+fate-hevc-conformance-$(1): CMD = framecrc -vsync 0 -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit
+endef
+
+define FATE_HEVC_TEST_10BIT
+FATE_HEVC += fate-hevc-conformance-$(1)
+fate-hevc-conformance-$(1): CMD = framecrc -vsync 0 -i $(TARGET_SAMPLES)/hevc-conformance/$(1).bit -pix_fmt yuv420p10le
+endef
+
+$(foreach N,$(HEVC_SAMPLES),$(eval $(call FATE_HEVC_TEST,$(N))))
+$(foreach N,$(HEVC_SAMPLES_10BIT),$(eval $(call FATE_HEVC_TEST_10BIT,$(N))))
+
+FATE_HEVC-$(call DEMDEC, HEVC, HEVC) += $(FATE_HEVC)
+
+FATE_SAMPLES_AVCONV += $(FATE_HEVC-yes)
+
+fate-hevc: $(FATE_HEVC-yes)
diff --git a/tests/fate/image.mak b/tests/fate/image.mak
index 1e4bc56..61d85cd 100644
--- a/tests/fate/image.mak
+++ b/tests/fate/image.mak
@@ -1,32 +1,35 @@
 FATE_SAMPLES_AVCONV-$(call DEMDEC, IMAGE2, DPX) += fate-dpx
-fate-dpx: CMD = framecrc -i $(SAMPLES)/dpx/lighthouse_rgb48.dpx
+fate-dpx: CMD = framecrc -i $(TARGET_SAMPLES)/dpx/lighthouse_rgb48.dpx
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, IMAGE2, PICTOR) += fate-pictor
-fate-pictor: CMD = framecrc -i $(SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24
+fate-pictor: CMD = framecrc -i $(TARGET_SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24
+
+FATE_SAMPLES_AVCONV-$(call PARSERDEMDEC, PNG, IMAGE2PIPE, PNG) += fate-pngparser
+fate-pngparser: CMD = framecrc -f image2pipe -i $(TARGET_SAMPLES)/png1/libav_4x_concat.png
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, IMAGE2, PTX) += fate-ptx
-fate-ptx: CMD = framecrc -i $(SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
+fate-ptx: CMD = framecrc -i $(TARGET_SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
 
 FATE_SUNRASTER += fate-sunraster-1bit-raw
-fate-sunraster-1bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-1bit-raw.sun
+fate-sunraster-1bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-1bit-raw.sun
 
 FATE_SUNRASTER += fate-sunraster-1bit-rle
-fate-sunraster-1bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-1bit-rle.sun
+fate-sunraster-1bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-1bit-rle.sun
 
 FATE_SUNRASTER += fate-sunraster-8bit-raw
-fate-sunraster-8bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-8bit-raw.sun -pix_fmt rgb24
+fate-sunraster-8bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-8bit-raw.sun -pix_fmt rgb24
 
 FATE_SUNRASTER += fate-sunraster-8bit_gray-raw
-fate-sunraster-8bit_gray-raw: CMD = framecrc -i $(SAMPLES)/sunraster/gray.ras
+fate-sunraster-8bit_gray-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/gray.ras
 
 FATE_SUNRASTER += fate-sunraster-8bit-rle
-fate-sunraster-8bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-8bit-rle.sun -pix_fmt rgb24
+fate-sunraster-8bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-8bit-rle.sun -pix_fmt rgb24
 
 FATE_SUNRASTER += fate-sunraster-24bit-raw
-fate-sunraster-24bit-raw: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-raw.sun
+fate-sunraster-24bit-raw: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-24bit-raw.sun
 
 FATE_SUNRASTER += fate-sunraster-24bit-rle
-fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun
+fate-sunraster-24bit-rle: CMD = framecrc -i $(TARGET_SAMPLES)/sunraster/lena-24bit-rle.sun
 
 FATE_SUNRASTER-$(call DEMDEC, IMAGE2, SUNRAST) += $(FATE_SUNRASTER)
 
@@ -52,24 +55,24 @@ FATE_TARGA-$(call DEMDEC, IMAGE2, TARGA) += $(FATE_TARGA)
 FATE_SAMPLES_AVCONV += $(FATE_TARGA-yes)
 fate-targa: $(FATE_TARGA-yes)
 
-fate-targa-conformance-CBW8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/CBW8.TGA
-fate-targa-conformance-CCM8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/CCM8.TGA  -pix_fmt rgba
-fate-targa-conformance-CTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC16.TGA -pix_fmt rgb555le
-fate-targa-conformance-CTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC24.TGA
-fate-targa-conformance-CTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/CTC32.TGA -pix_fmt bgra
-fate-targa-conformance-UBW8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/UBW8.TGA
-fate-targa-conformance-UCM8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/UCM8.TGA  -pix_fmt rgba
-fate-targa-conformance-UTC16: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC16.TGA -pix_fmt rgb555le
-fate-targa-conformance-UTC24: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC24.TGA
-fate-targa-conformance-UTC32: CMD = framecrc -i $(SAMPLES)/targa-conformance/UTC32.TGA -pix_fmt bgra
+fate-targa-conformance-CBW8:  CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CBW8.TGA
+fate-targa-conformance-CCM8:  CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CCM8.TGA  -pix_fmt rgba
+fate-targa-conformance-CTC16: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC16.TGA -pix_fmt rgb555le
+fate-targa-conformance-CTC24: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC24.TGA
+fate-targa-conformance-CTC32: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/CTC32.TGA -pix_fmt bgra
+fate-targa-conformance-UBW8:  CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UBW8.TGA
+fate-targa-conformance-UCM8:  CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UCM8.TGA  -pix_fmt rgba
+fate-targa-conformance-UTC16: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC16.TGA -pix_fmt rgb555le
+fate-targa-conformance-UTC24: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC24.TGA
+fate-targa-conformance-UTC32: CMD = framecrc -i $(TARGET_SAMPLES)/targa-conformance/UTC32.TGA -pix_fmt bgra
 
-fate-targa-top-to-bottom: CMD = framecrc -i $(SAMPLES)/targa/lena-top-to-bottom.tga
+fate-targa-top-to-bottom: CMD = framecrc -i $(TARGET_SAMPLES)/targa/lena-top-to-bottom.tga
 
 FATE_TIFF += fate-tiff-fax-g3
-fate-tiff-fax-g3: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31D.TIF
+fate-tiff-fax-g3: CMD = framecrc -i $(TARGET_SAMPLES)/CCITT_fax/G31D.TIF
 
 FATE_TIFF += fate-tiff-fax-g3s
-fate-tiff-fax-g3s: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31DS.TIF
+fate-tiff-fax-g3s: CMD = framecrc -i $(TARGET_SAMPLES)/CCITT_fax/G31DS.TIF
 
 FATE_TIFF-$(call DEMDEC, IMAGE2, TIFF) += $(FATE_TIFF)
 
diff --git a/tests/fate/indeo.mak b/tests/fate/indeo.mak
index 5a99b46..e725a6b 100644
--- a/tests/fate/indeo.mak
+++ b/tests/fate/indeo.mak
@@ -1,14 +1,17 @@
 FATE_INDEO-$(call DEMDEC, AVI, INDEO2) += fate-indeo2
-fate-indeo2: CMD = framecrc -i $(SAMPLES)/rt21/VPAR0026.AVI
+fate-indeo2: CMD = framecrc -i $(TARGET_SAMPLES)/rt21/VPAR0026.AVI
 
 FATE_INDEO-$(call DEMDEC, MOV, INDEO3) += fate-indeo3
-fate-indeo3: CMD = framecrc -i $(SAMPLES)/iv32/cubes.mov
+fate-indeo3: CMD = framecrc -i $(TARGET_SAMPLES)/iv32/cubes.mov
+
+FATE_INDEO-$(call DEMDEC, AVI, INDEO3) += fate-indeo3-2
+fate-indeo3-2: CMD = framecrc -i $(TARGET_SAMPLES)/iv32/OPENINGH.avi
 
 FATE_INDEO-$(call DEMDEC, AVI, INDEO4) += fate-indeo4
-fate-indeo4: CMD = framecrc -i $(SAMPLES)/iv41/indeo41-partial.avi -an
+fate-indeo4: CMD = framecrc -i $(TARGET_SAMPLES)/iv41/indeo41-partial.avi -an
 
 FATE_INDEO-$(call DEMDEC, AVI, INDEO5) += fate-indeo5
-fate-indeo5: CMD = framecrc -i $(SAMPLES)/iv50/Educ_Movie_DeadlyForce.avi -an
+fate-indeo5: CMD = framecrc -i $(TARGET_SAMPLES)/iv50/Educ_Movie_DeadlyForce.avi -an
 
 FATE_SAMPLES_AVCONV += $(FATE_INDEO-yes)
 fate-indeo: $(FATE_INDEO-yes)
diff --git a/tests/fate/libavdevice.mak b/tests/fate/libavdevice.mak
new file mode 100644
index 0000000..cb6af51
--- /dev/null
+++ b/tests/fate/libavdevice.mak
@@ -0,0 +1,6 @@
+FATE_LIBAVDEVICE-yes += fate-timefilter
+fate-timefilter: libavdevice/timefilter-test$(EXESUF)
+fate-timefilter: CMD = run libavdevice/timefilter-test
+
+FATE-$(CONFIG_AVDEVICE) += $(FATE_LIBAVDEVICE-yes)
+fate-libavdevice: $(FATE_LIBAVDEVICE-yes)
diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak
index b6eda42..d532adc 100644
--- a/tests/fate/libavformat.mak
+++ b/tests/fate/libavformat.mak
@@ -1,6 +1,14 @@
-FATE_LIBAVFORMAT += fate-url
+FATE_LIBAVFORMAT-$(CONFIG_NETWORK) += fate-noproxy
+fate-noproxy: libavformat/noproxy-test$(EXESUF)
+fate-noproxy: CMD = run libavformat/noproxy-test
+
+FATE_LIBAVFORMAT-yes += fate-srtp
+fate-srtp: libavformat/srtp-test$(EXESUF)
+fate-srtp: CMD = run libavformat/srtp-test
+
+FATE_LIBAVFORMAT-yes += fate-url
 fate-url: libavformat/url-test$(EXESUF)
 fate-url: CMD = run libavformat/url-test
 
-FATE-$(CONFIG_AVFORMAT) += $(FATE_LIBAVFORMAT)
+FATE-$(CONFIG_AVFORMAT) += $(FATE_LIBAVFORMAT-yes)
 fate-libavformat: $(FATE_LIBAVFORMAT)
diff --git a/tests/fate/libavresample.mak b/tests/fate/libavresample.mak
new file mode 100644
index 0000000..6ae2ddc
--- /dev/null
+++ b/tests/fate/libavresample.mak
@@ -0,0 +1,47 @@
+CROSS_TEST = $(foreach I,$(1),                                        \
+                 $(foreach J,$(1),                                    \
+                     $(if $(filter-out $(I),$(J)),                    \
+                         $(eval $(call $(2),$(I),$(J),$(3),$(4),$(5))),    \
+                     )))
+
+MIX_CHANNELS = 1 2 3 4 5 6 7 8
+
+define MIX
+FATE_LAVR_MIX += fate-lavr-mix-$(3)-$(1)-$(2)
+fate-lavr-mix-$(3)-$(1)-$(2): tests/data/asynth-44100-$(1).wav
+fate-lavr-mix-$(3)-$(1)-$(2): CMD = avconv -i $(TARGET_PATH)/tests/data/asynth-44100-$(1).wav -ac $(2) -mix_coeff_type $(3) -internal_sample_fmt $(4) -f s16le -af atrim=end_sample=1024 -
+fate-lavr-mix-$(3)-$(1)-$(2): CMP = oneoff
+fate-lavr-mix-$(3)-$(1)-$(2): REF = $(SAMPLES)/lavr/lavr-mix-$(3)-$(1)-$(2)
+endef
+
+$(call CROSS_TEST,$(MIX_CHANNELS),MIX,q8,s16p)
+$(call CROSS_TEST,$(MIX_CHANNELS),MIX,q15,s16p)
+$(call CROSS_TEST,$(MIX_CHANNELS),MIX,flt,fltp)
+
+FATE_LAVR_MIX-$(call FILTERDEMDECENCMUX, RESAMPLE, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_LAVR_MIX)
+fate-lavr-mix: $(FATE_LAVR_MIX-yes)
+FATE_LAVR += $(FATE_LAVR_MIX-yes)
+
+SAMPLERATES = 2626 8000 44100 48000 96000
+
+define RESAMPLE
+FATE_LAVR_RESAMPLE += fate-lavr-resample-$(3)-$(1)-$(2)
+fate-lavr-resample-$(3)-$(1)-$(2): tests/data/asynth-$(1)-1.wav
+fate-lavr-resample-$(3)-$(1)-$(2): CMD = avconv -i $(TARGET_PATH)/tests/data/asynth-$(1)-1.wav -ar $(2) -internal_sample_fmt $(3) -f $(4) -af atrim=end_sample=10240 -
+fate-lavr-resample-$(3)-$(1)-$(2): CMP = oneoff
+fate-lavr-resample-$(3)-$(1)-$(2): CMP_UNIT = $(5)
+fate-lavr-resample-$(3)-$(1)-$(2): FUZZ = 6
+fate-lavr-resample-$(3)-$(1)-$(2): REF = $(SAMPLES)/lavr/lavr-resample-$(3)-$(1)-$(2)
+endef
+
+$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,s16p,s16le,s16)
+$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,s32p,s32le,s16)
+$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,fltp,f32le,f32)
+$(call CROSS_TEST,$(SAMPLERATES),RESAMPLE,dblp,f64le,f64)
+
+FATE_LAVR_RESAMPLE-$(call FILTERDEMDECENCMUX, RESAMPLE, WAV, PCM_S16LE, PCM_S16LE, WAV) += $(FATE_LAVR_RESAMPLE)
+fate-lavr-resample: $(FATE_LAVR_RESAMPLE-yes)
+FATE_LAVR += $(FATE_LAVR_RESAMPLE-yes)
+
+FATE_SAMPLES_AVCONV += $(FATE_LAVR)
+fate-lavr: $(FATE_LAVR)
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index 9e57162..6f24496 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -8,6 +8,11 @@ fate-aes: libavutil/aes-test$(EXESUF)
 fate-aes: CMD = run libavutil/aes-test
 fate-aes: REF = /dev/null
 
+FATE_LIBAVUTIL += fate-atomic
+fate-atomic: libavutil/atomic-test$(EXESUF)
+fate-atomic: CMD = run libavutil/atomic-test
+fate-atomic: REF = /dev/null
+
 FATE_LIBAVUTIL += fate-avstring
 fate-avstring: libavutil/avstring-test$(EXESUF)
 fate-avstring: CMD = run libavutil/avstring-test
@@ -37,6 +42,10 @@ FATE_LIBAVUTIL += fate-fifo
 fate-fifo: libavutil/fifo-test$(EXESUF)
 fate-fifo: CMD = run libavutil/fifo-test
 
+FATE_LIBAVUTIL += fate-hmac
+fate-hmac: libavutil/hmac-test$(EXESUF)
+fate-hmac: CMD = run libavutil/hmac-test
+
 FATE_LIBAVUTIL += fate-md5
 fate-md5: libavutil/md5-test$(EXESUF)
 fate-md5: CMD = run libavutil/md5-test
@@ -49,6 +58,11 @@ FATE_LIBAVUTIL += fate-sha
 fate-sha: libavutil/sha-test$(EXESUF)
 fate-sha: CMD = run libavutil/sha-test
 
+FATE_LIBAVUTIL += fate-tree
+fate-tree: libavutil/tree-test$(EXESUF)
+fate-tree: CMD = run libavutil/tree-test
+fate-tree: REF = /dev/null
+
 FATE_LIBAVUTIL += fate-xtea
 fate-xtea: libavutil/xtea-test$(EXESUF)
 fate-xtea: CMD = run libavutil/xtea-test
diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak
index 0794241..3638f17 100644
--- a/tests/fate/lossless-audio.mak
+++ b/tests/fate/lossless-audio.mak
@@ -1,20 +1,22 @@
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, ALAC) += fate-lossless-alac
-fate-lossless-alac: CMD = md5 -i $(SAMPLES)/lossless-audio/inside.m4a -f s16le
+fate-lossless-alac: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/inside.m4a -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MLP, MLP) += fate-lossless-meridianaudio
-fate-lossless-meridianaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le
-
-FATE_SAMPLES_AVCONV-$(call DEMDEC, APE, APE) += fate-lossless-monkeysaudio
-fate-lossless-monkeysaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le
+fate-lossless-meridianaudio: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, RM, RALF) += fate-ralf
-fate-ralf: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le
+fate-ralf: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, SHORTEN, SHORTEN) += fate-lossless-shorten
-fate-lossless-shorten: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le
+fate-lossless-shorten: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le
+
+FATE_SAMPLES_AVCONV-$(call DEMDEC, TAK, TAK) += fate-lossless-tak
+fate-lossless-tak: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.tak -f s16le
+fate-lossless-tak: CMP = oneline
+fate-lossless-tak: REF = a28d4e5f2192057f7d4bece870f40bd0
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, TTA, TTA) += fate-lossless-tta
-fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta
+fate-lossless-tta: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/inside.tta
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, WMALOSSLESS) += fate-lossless-wma
-fate-lossless-wma: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le
+fate-lossless-wma: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le
diff --git a/tests/fate/lossless-video.mak b/tests/fate/lossless-video.mak
index 06b6dd5..bf1a971 100644
--- a/tests/fate/lossless-video.mak
+++ b/tests/fate/lossless-video.mak
@@ -1,47 +1,50 @@
+FATE_CLLC += fate-cllc-argb
+fate-cllc-argb: CMD = framecrc -i $(TARGET_SAMPLES)/cllc/sample-cllc-argb.avi
+
 FATE_CLLC += fate-cllc-rgb
-fate-cllc-rgb: CMD = framecrc -i $(SAMPLES)/cllc/sample-cllc-rgb.avi
+fate-cllc-rgb: CMD = framecrc -i $(TARGET_SAMPLES)/cllc/sample-cllc-rgb.avi
 
-FATE_CLLC += fate-cllc-argb
-fate-cllc-argb: CMD = framecrc -i $(SAMPLES)/cllc/sample-cllc-argb.avi
+FATE_CLLC += fate-cllc-yuy2-noblock
+fate-cllc-yuy2-noblock: CMD = framecrc -i $(TARGET_SAMPLES)/cllc/sample-cllc-yuy2-noblock.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, CLLC) += $(FATE_CLLC)
 fate-cllc: $(FATE_CLLC)
 
 FATE_LAGARITH += fate-lagarith-rgb24
-fate-lagarith-rgb24: CMD = framecrc -i $(SAMPLES)/lagarith/lag-rgb24.avi
+fate-lagarith-rgb24: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-rgb24.avi
 
 FATE_LAGARITH += fate-lagarith-rgb32
-fate-lagarith-rgb32: CMD = framecrc -i $(SAMPLES)/lagarith/lag-rgb32.avi -pix_fmt bgra
+fate-lagarith-rgb32: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-rgb32.avi -pix_fmt bgra
 
 FATE_LAGARITH += fate-lagarith-yuy2
-fate-lagarith-yuy2: CMD = framecrc -i $(SAMPLES)/lagarith/lag-yuy2.avi
+fate-lagarith-yuy2: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-yuy2.avi
 
 FATE_LAGARITH += fate-lagarith-yv12
-fate-lagarith-yv12: CMD = framecrc -i $(SAMPLES)/lagarith/lag-yv12.avi
+fate-lagarith-yv12: CMD = framecrc -i $(TARGET_SAMPLES)/lagarith/lag-yv12.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, LAGARITH) += $(FATE_LAGARITH)
 fate-lagarith: $(FATE_LAGARITH)
 
 FATE_LOCO += fate-loco-rgb
-fate-loco-rgb: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-rgb.avi
+fate-loco-rgb: CMD = framecrc -i $(TARGET_SAMPLES)/loco/pig-loco-rgb.avi
 
 FATE_LOCO += fate-loco-yuy2
-fate-loco-yuy2: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-0.avi
+fate-loco-yuy2: CMD = framecrc -i $(TARGET_SAMPLES)/loco/pig-loco-0.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, LOCO) += $(FATE_LOCO)
 fate-loco: $(FATE_LOCO)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, MSRLE) += fate-msrle-8bit
-fate-msrle-8bit: CMD = framecrc -i $(SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24
+fate-msrle-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, MSZH) += fate-mszh
-fate-mszh: CMD = framecrc -i $(SAMPLES)/lcl/mszh-1frame.avi
+fate-mszh: CMD = framecrc -i $(TARGET_SAMPLES)/lcl/mszh-1frame.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, VBLE) += fate-vble
-fate-vble: CMD = framecrc -i $(SAMPLES)/vble/flowers-partial-2MB.avi
-
-FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, ZLIB) += fate-zlib
-fate-zlib: CMD = framecrc -i $(SAMPLES)/lcl/zlib-1frame.avi
+fate-vble: CMD = framecrc -i $(TARGET_SAMPLES)/vble/flowers-partial-2MB.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, ZEROCODEC) += fate-zerocodec
-fate-zerocodec: CMD = framecrc -i $(SAMPLES)/zerocodec/sample-zeco.avi
+fate-zerocodec: CMD = framecrc -i $(TARGET_SAMPLES)/zerocodec/sample-zeco.avi
+
+FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, ZLIB) += fate-zlib
+fate-zlib: CMD = framecrc -i $(TARGET_SAMPLES)/lcl/zlib-1frame.avi
diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak
index a3ca3ed..195fd3b 100644
--- a/tests/fate/microsoft.mak
+++ b/tests/fate/microsoft.mak
@@ -1,42 +1,42 @@
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, MSMPEG4V1) += fate-msmpeg4v1
-fate-msmpeg4v1: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/msmpeg4v1/mpg4.avi -an
-
-FATE_MSVIDEO1 += fate-msvideo1-16bit
-fate-msvideo1-16bit: CMD = framecrc -i $(SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24
+fate-msmpeg4v1: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/msmpeg4v1/mpg4.avi -an
 
 FATE_MSVIDEO1 += fate-msvideo1-8bit
-fate-msvideo1-8bit: CMD = framecrc -i $(SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24
+fate-msvideo1-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24
+
+FATE_MSVIDEO1 += fate-msvideo1-16bit
+fate-msvideo1-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/cram/clock-cram16.avi -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, MSVIDEO1) += $(FATE_MSVIDEO1)
 fate-msvideo1: $(FATE_MSVIDEO1)
 
 FATE_WMV8_DRM += fate-wmv8-drm
 # discard last packet to avoid fails due to overread of VC-1 decoder
-fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -an -vframes 162
+fate-wmv8-drm: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -an -frames:v 129
 
 FATE_WMV8_DRM += fate-wmv8-drm-nodec
-fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
+fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(TARGET_SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, ASF, WMV3) += $(FATE_WMV8_DRM)
 fate-wmv8_drm: $(FATE_WMV8_DRM)
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa00040
-fate-vc1_sa00040: CMD = framecrc -i $(SAMPLES)/vc1/SA00040.vc1
+fate-vc1_sa00040: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA00040.vc1
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa00050
-fate-vc1_sa00050: CMD = framecrc -i $(SAMPLES)/vc1/SA00050.vc1
+fate-vc1_sa00050: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA00050.vc1
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa10091
-fate-vc1_sa10091: CMD = framecrc -i $(SAMPLES)/vc1/SA10091.vc1
-
-FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa20021
-fate-vc1_sa20021: CMD = framecrc -i $(SAMPLES)/vc1/SA20021.vc1
+fate-vc1_sa10091: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA10091.vc1
 
 FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa10143
-fate-vc1_sa10143: CMD = framecrc -i $(SAMPLES)/vc1/SA10143.vc1
+fate-vc1_sa10143: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA10143.vc1
+
+FATE_VC1-$(CONFIG_VC1_DEMUXER) += fate-vc1_sa20021
+fate-vc1_sa20021: CMD = framecrc -i $(TARGET_SAMPLES)/vc1/SA20021.vc1
 
 FATE_VC1-$(CONFIG_MOV_DEMUXER) += fate-vc1-ism
-fate-vc1-ism: CMD = framecrc -i $(SAMPLES)/isom/vc1-wmapro.ism -an
+fate-vc1-ism: CMD = framecrc -i $(TARGET_SAMPLES)/isom/vc1-wmapro.ism -an
 
 FATE_SAMPLES_AVCONV-$(CONFIG_VC1_DECODER) += $(FATE_VC1-yes)
 fate-vc1: $(FATE_VC1-yes)
diff --git a/tests/fate/monkeysaudio.mak b/tests/fate/monkeysaudio.mak
new file mode 100644
index 0000000..9ce872a
--- /dev/null
+++ b/tests/fate/monkeysaudio.mak
@@ -0,0 +1,20 @@
+APE_VERSIONS = 380 388 389b1 391b1 392b2 394b1
+
+define FATE_APE_SUITE
+FATE_APE += fate-lossless-monkeysaudio-$(1)-normal
+fate-lossless-monkeysaudio-$(1)-normal: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-mac$(1)-c2000.ape -af atrim=end_sample=73728
+fate-lossless-monkeysaudio-$(1)-normal: REF = CRC=0x5d08c17e
+fate-lossless-monkeysaudio-$(1)-normal: CMP = oneline
+FATE_APE += fate-lossless-monkeysaudio-$(1)-extrahigh
+fate-lossless-monkeysaudio-$(1)-extrahigh: CMD = crc -i $(TARGET_SAMPLES)/lossless-audio/luckynight-mac$(1)-c4000.ape -af atrim=end_sample=73728
+fate-lossless-monkeysaudio-$(1)-extrahigh: REF = CRC=0x5d08c17e
+fate-lossless-monkeysaudio-$(1)-extrahigh: CMP = oneline
+endef
+
+$(foreach N,$(APE_VERSIONS),$(eval $(call FATE_APE_SUITE,$(N))))
+
+FATE_APE += fate-lossless-monkeysaudio-399
+fate-lossless-monkeysaudio-399: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le
+
+FATE_SAMPLES_AVCONV-$(call DEMDEC, APE, APE) += $(FATE_APE)
+fate-lossless-monkeysaudio: $(FATE_APE)
diff --git a/tests/fate/mp3.mak b/tests/fate/mp3.mak
index 663f14e..fe6a0e1 100644
--- a/tests/fate/mp3.mak
+++ b/tests/fate/mp3.mak
@@ -1,33 +1,33 @@
 FATE_MP3 += fate-mp3-float-conf-compl
-fate-mp3-float-conf-compl: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/compl.bit
+fate-mp3-float-conf-compl: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/compl.bit
 fate-mp3-float-conf-compl: REF = $(SAMPLES)/mp3-conformance/compl.pcm
 
 FATE_MP3 += fate-mp3-float-conf-he_32khz
-fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_32khz.bit -fs 343296
+fate-mp3-float-conf-he_32khz: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_32khz.bit -fs 343296
 fate-mp3-float-conf-he_32khz: REF = $(SAMPLES)/mp3-conformance/he_32khz.pcm
 
 FATE_MP3 += fate-mp3-float-conf-he_44khz
-fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_44khz.bit -fs 942336
+fate-mp3-float-conf-he_44khz: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_44khz.bit -fs 942336
 fate-mp3-float-conf-he_44khz: REF = $(SAMPLES)/mp3-conformance/he_44khz.pcm
 
 FATE_MP3 += fate-mp3-float-conf-he_48khz
-fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/he_48khz.bit -fs 343296
+fate-mp3-float-conf-he_48khz: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/he_48khz.bit -fs 343296
 fate-mp3-float-conf-he_48khz: REF = $(SAMPLES)/mp3-conformance/he_48khz.pcm
 
 FATE_MP3 += fate-mp3-float-conf-hecommon
-fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/hecommon.bit -fs 133632
+fate-mp3-float-conf-hecommon: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/hecommon.bit -fs 133632
 fate-mp3-float-conf-hecommon: REF = $(SAMPLES)/mp3-conformance/hecommon.pcm
 
 FATE_MP3 += fate-mp3-float-conf-si
-fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si.bit -fs 269568
+fate-mp3-float-conf-si: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si.bit -fs 269568
 fate-mp3-float-conf-si: REF = $(SAMPLES)/mp3-conformance/si.pcm
 
 FATE_MP3 += fate-mp3-float-conf-si_block
-fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -i $(SAMPLES)/mp3-conformance/si_block.bit -fs 145152
+fate-mp3-float-conf-si_block: CMD = pcm -acodec mp3float -i $(TARGET_SAMPLES)/mp3-conformance/si_block.bit -fs 145152
 fate-mp3-float-conf-si_block: REF = $(SAMPLES)/mp3-conformance/si_block.pcm
 
 FATE_MP3 += fate-mp3-float-extra_overread
-fate-mp3-float-extra_overread: CMD = pcm -c:a mp3float -i $(SAMPLES)/mpegaudio/extra_overread.mp3
+fate-mp3-float-extra_overread: CMD = pcm -c:a mp3float -i $(TARGET_SAMPLES)/mpegaudio/extra_overread.mp3
 fate-mp3-float-extra_overread: REF = $(SAMPLES)/mpegaudio/extra_overread.pcm
 
 $(FATE_MP3): CMP = stddev
diff --git a/tests/fate/mpc.mak b/tests/fate/mpc.mak
index 53d236e..4a01273 100644
--- a/tests/fate/mpc.mak
+++ b/tests/fate/mpc.mak
@@ -1,11 +1,11 @@
 FATE_MPC-$(CONFIG_MPC_DEMUXER) += fate-mpc7-demux
-fate-mpc7-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp7.mpc -acodec copy
+fate-mpc7-demux: CMD = crc -i $(TARGET_SAMPLES)/musepack/inside-mp7.mpc -acodec copy
 
 FATE_MPC-$(CONFIG_MPC8_DEMUXER) += fate-mpc8-demux
-fate-mpc8-demux: CMD = crc -i $(SAMPLES)/musepack/inside-mp8.mpc -acodec copy
+fate-mpc8-demux: CMD = crc -i $(TARGET_SAMPLES)/musepack/inside-mp8.mpc -acodec copy
 
 FATE_MPC-$(call DEMDEC, MPC, MPC7) += fate-musepack7
-fate-musepack7: CMD = pcm -i $(SAMPLES)/musepack/inside-mp7.mpc
+fate-musepack7: CMD = pcm -i $(TARGET_SAMPLES)/musepack/inside-mp7.mpc
 fate-musepack7: CMP = oneoff
 fate-musepack7: REF = $(SAMPLES)/musepack/inside-mp7.pcm
 
diff --git a/tests/fate/pcm.mak b/tests/fate/pcm.mak
index c84de9e..116b50f 100644
--- a/tests/fate/pcm.mak
+++ b/tests/fate/pcm.mak
@@ -1,26 +1,26 @@
 FATE_SAMPLES_PCM += fate-iff-pcm
-fate-iff-pcm: CMD = md5 -i $(SAMPLES)/iff/Bells -f s16le
+fate-iff-pcm: CMD = md5 -i $(TARGET_SAMPLES)/iff/Bells -f s16le
 
 FATE_SAMPLES_PCM += fate-pcm_dvd
-fate-pcm_dvd: CMD = framecrc -i $(SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn
+fate-pcm_dvd: CMD = framecrc -i $(TARGET_SAMPLES)/pcm-dvd/coolitnow-partial.vob -vn
 
 FATE_SAMPLES_PCM += fate-pcm-planar
-fate-pcm-planar: CMD = framecrc -i $(SAMPLES)/ea-mad/xeasport.mad -vn
+fate-pcm-planar: CMD = framecrc -i $(TARGET_SAMPLES)/ea-mad/xeasport.mad -vn
 
 FATE_SAMPLES_PCM += fate-pcm_s16be-stereo
-fate-pcm_s16be-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-twos.mov -f s16le
+fate-pcm_s16be-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-twos.mov -f s16le
 
 FATE_SAMPLES_PCM += fate-pcm_s16le-stereo
-fate-pcm_s16le-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-sowt.mov -f s16le
+fate-pcm_s16le-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-L-sowt.mov -f s16le
 
 FATE_SAMPLES_PCM += fate-pcm_u8-mono
-fate-pcm_u8-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le
+fate-pcm_u8-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-raw.mov -f s16le
 
 FATE_SAMPLES_PCM += fate-pcm_u8-stereo
-fate-pcm_u8-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le
+fate-pcm_u8-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-raw.mov -f s16le
 
 FATE_SAMPLES_PCM += fate-w64
-fate-w64: CMD = crc -i $(SAMPLES)/w64/w64-pcm16.w64
+fate-w64: CMD = crc -i $(TARGET_SAMPLES)/w64/w64-pcm16.w64
 
 FATE_PCM += fate-dcinema-encode
 fate-dcinema-encode: tests/data/asynth-96000-6.wav
diff --git a/tests/fate/probe.mak b/tests/fate/probe.mak
index 73bc5cb..376dfdd 100644
--- a/tests/fate/probe.mak
+++ b/tests/fate/probe.mak
@@ -15,4 +15,4 @@ fate-probe-format: $(FATE_PROBE_FORMAT)
 
 $(FATE_PROBE_FORMAT): avprobe$(EXESUF)
 $(FATE_PROBE_FORMAT): CMP = oneline
-fate-probe-format-%: CMD = probefmt $(SAMPLES)/probe-format/$(@:fate-probe-format-%=%)
+fate-probe-format-%: CMD = probefmt $(TARGET_SAMPLES)/probe-format/$(@:fate-probe-format-%=%)
diff --git a/tests/fate/prores.mak b/tests/fate/prores.mak
index 9c1a1b1..8d4b6ac 100644
--- a/tests/fate/prores.mak
+++ b/tests/fate/prores.mak
@@ -7,8 +7,8 @@ FATE_PRORES = fate-prores-422                                           \
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PRORES) += $(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 -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
+fate-prores-422_hq:    CMD = framecrc -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le
+fate-prores-422_lt:    CMD = framecrc -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le
+fate-prores-422_proxy: CMD = framecrc -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le
+fate-prores-alpha:     CMD = framecrc -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuva444p10le
diff --git a/tests/fate/qt.mak b/tests/fate/qt.mak
index 79155f5..ac95d64 100644
--- a/tests/fate/qt.mak
+++ b/tests/fate/qt.mak
@@ -1,50 +1,50 @@
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, EIGHTBPS) += fate-8bps
-fate-8bps: CMD = framecrc -i $(SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24
+fate-8bps: CMD = framecrc -i $(TARGET_SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, QDM2) += fate-qdm2
-fate-qdm2: CMD = pcm -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.mov
+fate-qdm2: CMD = pcm -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.mov
 fate-qdm2: CMP = oneoff
 fate-qdm2: REF = $(SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.pcm
 fate-qdm2: FUZZ = 2
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PCM_ALAW) += fate-qt-alaw-mono
-fate-qt-alaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-alaw.mov -f s16le
+fate-qt-alaw-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-alaw.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PCM_ALAW) += fate-qt-alaw-stereo
-fate-qt-alaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-alaw.mov -f s16le
+fate-qt-alaw-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-alaw.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, ADPCM_IMA_QT) += fate-qt-ima4-mono
-fate-qt-ima4-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ima4.mov -f s16le
+fate-qt-ima4-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-ima4.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, ADPCM_IMA_QT) += fate-qt-ima4-stereo
-fate-qt-ima4-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ima4.mov -f s16le
+fate-qt-ima4-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-ima4.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, MACE3) += fate-qt-mac3-mono
-fate-qt-mac3-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC3.mov -f s16le
+fate-qt-mac3-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-MAC3.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, MACE3) += fate-qt-mac3-stereo
-fate-qt-mac3-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC3.mov -f s16le
+fate-qt-mac3-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-MAC3.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, MACE6) += fate-qt-mac6-mono
-fate-qt-mac6-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le
+fate-qt-mac6-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, MACE6) += fate-qt-mac6-stereo
-fate-qt-mac6-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le
+fate-qt-mac6-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PCM_MULAW) += fate-qt-ulaw-mono
-fate-qt-ulaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ulaw.mov -f s16le
+fate-qt-ulaw-mono: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-1-16-B-ulaw.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PCM_MULAW) += fate-qt-ulaw-stereo
-fate-qt-ulaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ulaw.mov -f s16le
+fate-qt-ulaw-stereo: CMD = md5 -i $(TARGET_SAMPLES)/qt-surge-suite/surge-2-16-B-ulaw.mov -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, QDRAW) += fate-quickdraw
-fate-quickdraw: CMD = framecrc -i $(SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24
+fate-quickdraw: CMD = framecrc -i $(TARGET_SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, RPZA) += fate-rpza
-fate-rpza: CMD = framecrc -i $(SAMPLES)/rpza/rpza2.mov -t 2 -pix_fmt rgb24
+fate-rpza: CMD = framecrc -i $(TARGET_SAMPLES)/rpza/rpza2.mov -t 2 -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, SVQ1) += fate-svq1
-fate-svq1: CMD = framecrc -i $(SAMPLES)/svq1/marymary-shackles.mov -an -t 10
+fate-svq1: CMD = framecrc -i $(TARGET_SAMPLES)/svq1/marymary-shackles.mov -an -t 10
 
 FATE_SAMPLES_AVCONV-$(call ALLYES, MOV_DEMUXER SVQ3_DECODER ZLIB) += fate-svq3
-fate-svq3: CMD = framecrc -i $(SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an
+fate-svq3: CMD = framecrc -i $(TARGET_SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an
diff --git a/tests/fate/qtrle.mak b/tests/fate/qtrle.mak
index d8a6ecf..774a816 100644
--- a/tests/fate/qtrle.mak
+++ b/tests/fate/qtrle.mak
@@ -1,23 +1,23 @@
 FATE_QTRLE += fate-qtrle-1bit
-fate-qtrle-1bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-Monochrome.mov -an
+fate-qtrle-1bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-Monochrome.mov -an
 
 FATE_QTRLE += fate-qtrle-2bit
-fate-qtrle-2bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24 -an
+fate-qtrle-2bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-4Greys.mov -pix_fmt rgb24 -an
 
 FATE_QTRLE += fate-qtrle-4bit
-fate-qtrle-4bit: CMD = framecrc -i $(SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an
+fate-qtrle-4bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/Animation-16Greys.mov -pix_fmt rgb24 -an
 
 FATE_QTRLE += fate-qtrle-8bit
-fate-qtrle-8bit: CMD = framecrc -i $(SAMPLES)/qtrle/criticalpath-credits.mov -pix_fmt rgb24 -an
+fate-qtrle-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/criticalpath-credits.mov -pix_fmt rgb24 -an
 
 FATE_QTRLE += fate-qtrle-16bit
-fate-qtrle-16bit: CMD = framecrc -i $(SAMPLES)/qtrle/mr-cork-rle.mov -pix_fmt rgb24
+fate-qtrle-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/mr-cork-rle.mov -pix_fmt rgb24
 
 FATE_QTRLE += fate-qtrle-24bit
-fate-qtrle-24bit: CMD = framecrc -i $(SAMPLES)/qtrle/aletrek-rle.mov
+fate-qtrle-24bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/aletrek-rle.mov
 
 FATE_QTRLE += fate-qtrle-32bit
-fate-qtrle-32bit: CMD = framecrc -i $(SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt rgb24
+fate-qtrle-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/qtrle/ultra_demo_720_480_32bpp_rle.mov -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, QTRLE) += $(FATE_QTRLE)
 fate-qtrle: $(FATE_QTRLE)
diff --git a/tests/fate/real.mak b/tests/fate/real.mak
index f3866b6..8481f28 100644
--- a/tests/fate/real.mak
+++ b/tests/fate/real.mak
@@ -1,37 +1,37 @@
 FATE_SAMPLES_AVCONV-$(call DEMDEC, RM, RA_144) += fate-ra-144
-fate-ra-144: CMD = md5 -i $(SAMPLES)/real/ra3_in_rm_file.rm -f s16le
+fate-ra-144: CMD = md5 -i $(TARGET_SAMPLES)/real/ra3_in_rm_file.rm -f s16le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, RM, RA_288) += fate-ra-288
-fate-ra-288: CMD = pcm -i $(SAMPLES)/real/ra_288.rm
+fate-ra-288: CMD = pcm -i $(TARGET_SAMPLES)/real/ra_288.rm
 fate-ra-288: CMP = oneoff
 fate-ra-288: REF = $(SAMPLES)/real/ra_288.pcm
 fate-ra-288: FUZZ = 2
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, RM, COOK) += fate-ra-cook
-fate-ra-cook: CMD = pcm -i $(SAMPLES)/real/ra_cook.rm
+fate-ra-cook: CMD = pcm -i $(TARGET_SAMPLES)/real/ra_cook.rm
 fate-ra-cook: CMP = oneoff
 fate-ra-cook: REF = $(SAMPLES)/real/ra_cook.pcm
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, RM, RV30) += fate-rv30
-fate-rv30: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/real/rv30.rm -an
+fate-rv30: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/real/rv30.rm -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, RM, RV40) += fate-rv40
-fate-rv40: CMD = framecrc -i $(SAMPLES)/real/spygames-2MB.rmvb -t 10 -an -vsync 0
+fate-rv40: CMD = framecrc -i $(TARGET_SAMPLES)/real/spygames-2MB.rmvb -t 10 -an -vsync 0
 
 FATE_SIPR += fate-sipr-5k0
-fate-sipr-5k0: CMD = pcm -i $(SAMPLES)/sipr/sipr_5k0.rm
+fate-sipr-5k0: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_5k0.rm
 fate-sipr-5k0: REF = $(SAMPLES)/sipr/sipr_5k0.pcm
 
 FATE_SIPR += fate-sipr-6k5
-fate-sipr-6k5: CMD = pcm -i $(SAMPLES)/sipr/sipr_6k5.rm
+fate-sipr-6k5: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_6k5.rm
 fate-sipr-6k5: REF = $(SAMPLES)/sipr/sipr_6k5.pcm
 
 FATE_SIPR += fate-sipr-8k5
-fate-sipr-8k5: CMD = pcm -i $(SAMPLES)/sipr/sipr_8k5.rm
+fate-sipr-8k5: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_8k5.rm
 fate-sipr-8k5: REF = $(SAMPLES)/sipr/sipr_8k5.pcm
 
 FATE_SIPR += fate-sipr-16k
-fate-sipr-16k: CMD = pcm -i $(SAMPLES)/sipr/sipr_16k.rm
+fate-sipr-16k: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_16k.rm
 fate-sipr-16k: REF = $(SAMPLES)/sipr/sipr_16k.pcm
 
 $(FATE_SIPR): CMP = oneoff
diff --git a/tests/fate/screen.mak b/tests/fate/screen.mak
index 3dc69c5..5c30ed7 100644
--- a/tests/fate/screen.mak
+++ b/tests/fate/screen.mak
@@ -1,60 +1,63 @@
 # FIXME dropped frames in this test because of coarse timebase
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, CSCD) += fate-cscd
-fate-cscd: CMD = framecrc -i $(SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24
+fate-cscd: CMD = framecrc -i $(TARGET_SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, DXTORY) += fate-dxtory
-fate-dxtory: CMD = framecrc -i $(SAMPLES)/dxtory/dxtory_mic.avi
+fate-dxtory: CMD = framecrc -i $(TARGET_SAMPLES)/dxtory/dxtory_mic.avi
 
 FATE_FRAPS += fate-fraps-v0
-fate-fraps-v0: CMD = framecrc -i $(SAMPLES)/fraps/Griffin_Ragdoll01-partial.avi
+fate-fraps-v0: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/Griffin_Ragdoll01-partial.avi
 
 FATE_FRAPS += fate-fraps-v1
-fate-fraps-v1: CMD = framecrc -i $(SAMPLES)/fraps/sample-v1.avi -an
+fate-fraps-v1: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/sample-v1.avi -an
 
 FATE_FRAPS += fate-fraps-v2
-fate-fraps-v2: CMD = framecrc -i $(SAMPLES)/fraps/test3-nosound-partial.avi
+fate-fraps-v2: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/test3-nosound-partial.avi
 
 FATE_FRAPS += fate-fraps-v3
-fate-fraps-v3: CMD = framecrc -i $(SAMPLES)/fraps/psclient-partial.avi -pix_fmt rgb24
+fate-fraps-v3: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/psclient-partial.avi -pix_fmt rgb24
 
 FATE_FRAPS += fate-fraps-v4
-fate-fraps-v4: CMD = framecrc -i $(SAMPLES)/fraps/WoW_2006-11-03_14-58-17-19-nosound-partial.avi
+fate-fraps-v4: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/WoW_2006-11-03_14-58-17-19-nosound-partial.avi
 
 FATE_FRAPS += fate-fraps-v5
-fate-fraps-v5: CMD = framecrc -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi
+fate-fraps-v5: CMD = framecrc -i $(TARGET_SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, FRAPS) += $(FATE_FRAPS)
 fate-fraps: $(FATE_FRAPS)
 
 FATE_TSCC += fate-tscc-15bit
-fate-tscc-15bit: CMD = framecrc -i $(SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt rgb24
+fate-tscc-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/oneminute.avi -t 15 -pix_fmt rgb24
 
 FATE_TSCC += fate-tscc-32bit
-fate-tscc-32bit: CMD = framecrc -i $(SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an
+fate-tscc-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, TSCC) += $(FATE_TSCC)
 fate-tscc: $(FATE_TSCC)
 
+FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, TSCC2) += fate-tscc2
+fate-tscc2: CMD = framecrc -i $(TARGET_SAMPLES)/tscc/tsc2_16bpp.avi
+
 FATE_VMNC += fate-vmnc-16bit
-fate-vmnc-16bit: CMD = framecrc -i $(SAMPLES)/VMnc/test.avi -pix_fmt rgb24
+fate-vmnc-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/VMnc/test.avi -pix_fmt rgb24
 
 FATE_VMNC += fate-vmnc-32bit
-fate-vmnc-32bit: CMD = framecrc -i $(SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24
+fate-vmnc-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, VMNC) += $(FATE_VMNC)
 fate-vmnc: $(FATE_VMNC)
 
 FATE_ZMBV += fate-zmbv-8bit
-fate-zmbv-8bit: CMD = framecrc -i $(SAMPLES)/zmbv/wc2_001-partial.avi -an -pix_fmt rgb24
+fate-zmbv-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/wc2_001-partial.avi -an -pix_fmt rgb24
 
 FATE_ZMBV += fate-zmbv-15bit
-fate-zmbv-15bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_15bit.avi -pix_fmt rgb24 -t 25
+fate-zmbv-15bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_15bit.avi -pix_fmt rgb24 -t 25
 
 FATE_ZMBV += fate-zmbv-16bit
-fate-zmbv-16bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24 -t 25
+fate-zmbv-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_16bit.avi -pix_fmt rgb24 -t 25
 
 FATE_ZMBV += fate-zmbv-32bit
-fate-zmbv-32bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25
+fate-zmbv-32bit: CMD = framecrc -i $(TARGET_SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, ZMBV) += $(FATE_ZMBV)
 fate-zmbv: $(FATE_ZMBV)
diff --git a/tests/fate/seek.mak b/tests/fate/seek.mak
index f9d25bf..a423711 100644
--- a/tests/fate/seek.mak
+++ b/tests/fate/seek.mak
@@ -1,5 +1,13 @@
 # files from fate-acodec
 
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_IMA_QT,  AIFF)    += adpcm-ima_qt
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_IMA_WAV, WAV)     += adpcm-ima_wav
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_MS,      WAV)     += adpcm-ms
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_SWF,     FLV)     += adpcm-swf
+FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_YAMAHA,  WAV)     += adpcm-yamaha
+FATE_SEEK_ACODEC-$(call ENCDEC, ALAC,          MOV)     += alac
+FATE_SEEK_ACODEC-$(call ENCDEC, FLAC,          FLAC)    += flac
+FATE_SEEK_ACODEC-$(call ENCDEC, MP2,           MP2 MP3) += mp2
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_ALAW,      WAV)     += pcm-alaw
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_MULAW,     WAV)     += pcm-mulaw
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_S8,        MOV)     += pcm-s8
@@ -14,14 +22,6 @@ FATE_SEEK_ACODEC-$(call ENCDEC, PCM_F32BE,     AU)      += pcm-f32be
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_F32LE,     WAV)     += pcm-f32le
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_F64BE,     AU)      += pcm-f64be
 FATE_SEEK_ACODEC-$(call ENCDEC, PCM_F64LE,     WAV)     += pcm-f64le
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_IMA_QT,  AIFF)    += adpcm-ima_qt
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_IMA_WAV, WAV)     += adpcm-ima_wav
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_MS,      WAV)     += adpcm-ms
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_SWF,     FLV)     += adpcm-swf
-FATE_SEEK_ACODEC-$(call ENCDEC, ADPCM_YAMAHA,  WAV)     += adpcm-yamaha
-FATE_SEEK_ACODEC-$(call ENCDEC, ALAC,          MOV)     += alac
-FATE_SEEK_ACODEC-$(call ENCDEC, FLAC,          FLAC)    += flac
-FATE_SEEK_ACODEC-$(call ENCDEC, MP2,           MP2 MP3) += mp2
 
 fate-seek-acodec-adpcm-ima_qt:  SRC = fate/acodec-adpcm-ima_qt.aiff
 fate-seek-acodec-adpcm-ima_wav: SRC = fate/acodec-adpcm-ima_wav.wav
@@ -89,8 +89,6 @@ FATE_SEEK_VSYNTH2-$(call ENCDEC, RAWVIDEO,      AVI)     += rgb
 FATE_SEEK_VSYNTH2-$(call ENCDEC, ROQ,           ROQ)     += roqvideo
 FATE_SEEK_VSYNTH2-$(call ENCDEC, RV10,          RM)      += rv10
 FATE_SEEK_VSYNTH2-$(call ENCDEC, RV20,          RM)      += rv20
-FATE_SEEK_VSYNTH2-$(call ENCDEC, SNOW,          AVI)     += snow
-FATE_SEEK_VSYNTH2-$(call ENCDEC, SNOW,          AVI)     += snow-ll
 FATE_SEEK_VSYNTH2-$(call ENCDEC, SVQ1,          MOV)     += svq1
 FATE_SEEK_VSYNTH2-$(call ENCDEC, WMV1,          AVI)     += wmv1
 FATE_SEEK_VSYNTH2-$(call ENCDEC, WMV2,          AVI)     += wmv2
diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak
index 004d8e0..161674f 100644
--- a/tests/fate/utvideo.mak
+++ b/tests/fate/utvideo.mak
@@ -1,46 +1,43 @@
+FATE_UTVIDEO += fate-utvideo_rgb_left
+fate-utvideo_rgb_left: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgb_left.avi
+
+FATE_UTVIDEO += fate-utvideo_rgb_median
+fate-utvideo_rgb_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgb_median.avi
+
 FATE_UTVIDEO += fate-utvideo_rgba_left
-fate-utvideo_rgba_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_left.avi
+fate-utvideo_rgba_left: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgba_left.avi
 
 FATE_UTVIDEO += fate-utvideo_rgba_median
-fate-utvideo_rgba_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_median.avi
+fate-utvideo_rgba_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgba_median.avi
 
 FATE_UTVIDEO += fate-utvideo_rgba_single_symbol
-fate-utvideo_rgba_single_symbol: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_single_symbol.avi
-
-FATE_UTVIDEO += fate-utvideo_rgb_left
-fate-utvideo_rgb_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_left.avi
-
-FATE_UTVIDEO += fate-utvideo_rgb_median
-fate-utvideo_rgb_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_median.avi
+fate-utvideo_rgba_single_symbol: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_rgba_single_symbol.avi
 
 FATE_UTVIDEO += fate-utvideo_yuv420_left
-fate-utvideo_yuv420_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv420_left.avi
+fate-utvideo_yuv420_left: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_yuv420_left.avi
 
 FATE_UTVIDEO += fate-utvideo_yuv420_median
-fate-utvideo_yuv420_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv420_median.avi
+fate-utvideo_yuv420_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_yuv420_median.avi
 
 FATE_UTVIDEO += fate-utvideo_yuv422_left
-fate-utvideo_yuv422_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv422_left.avi
+fate-utvideo_yuv422_left: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_yuv422_left.avi
 
 FATE_UTVIDEO += fate-utvideo_yuv422_median
-fate-utvideo_yuv422_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_yuv422_median.avi
+fate-utvideo_yuv422_median: CMD = framecrc -i $(TARGET_SAMPLES)/utvideo/utvideo_yuv422_median.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, UTVIDEO) += $(FATE_UTVIDEO)
 fate-utvideo: $(FATE_UTVIDEO)
 
 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 += fate-utvideoenc_rgba_none
-fate-utvideoenc_rgba_none: OPTS = -pix_fmt rgba -pred 3
-
 FATE_UTVIDEOENC += fate-utvideoenc_rgba_left
 fate-utvideoenc_rgba_left: OPTS = -pix_fmt rgba -pred left
 
 FATE_UTVIDEOENC += fate-utvideoenc_rgba_median
 fate-utvideoenc_rgba_median: OPTS = -pix_fmt rgba -pred median
 
-FATE_UTVIDEOENC += fate-utvideoenc_rgb_none
-fate-utvideoenc_rgb_none: OPTS = -pix_fmt rgb24 -pred 3
+FATE_UTVIDEOENC += fate-utvideoenc_rgba_none
+fate-utvideoenc_rgba_none: OPTS = -pix_fmt rgba -pred 3
 
 FATE_UTVIDEOENC += fate-utvideoenc_rgb_left
 fate-utvideoenc_rgb_left: OPTS = -pix_fmt rgb24 -pred left
@@ -48,8 +45,8 @@ fate-utvideoenc_rgb_left: OPTS = -pix_fmt rgb24 -pred left
 FATE_UTVIDEOENC += fate-utvideoenc_rgb_median
 fate-utvideoenc_rgb_median: OPTS = -pix_fmt rgb24 -pred median
 
-FATE_UTVIDEOENC += fate-utvideoenc_yuv420_none
-fate-utvideoenc_yuv420_none: OPTS = -pix_fmt yuv420p -pred 3
+FATE_UTVIDEOENC += fate-utvideoenc_rgb_none
+fate-utvideoenc_rgb_none: OPTS = -pix_fmt rgb24 -pred 3
 
 FATE_UTVIDEOENC += fate-utvideoenc_yuv420_left
 fate-utvideoenc_yuv420_left: OPTS = -pix_fmt yuv420p -pred left
@@ -57,8 +54,8 @@ fate-utvideoenc_yuv420_left: OPTS = -pix_fmt yuv420p -pred left
 FATE_UTVIDEOENC += fate-utvideoenc_yuv420_median
 fate-utvideoenc_yuv420_median: OPTS = -pix_fmt yuv420p -pred median
 
-FATE_UTVIDEOENC += fate-utvideoenc_yuv422_none
-fate-utvideoenc_yuv422_none: OPTS = -pix_fmt yuv422p -pred 3
+FATE_UTVIDEOENC += fate-utvideoenc_yuv420_none
+fate-utvideoenc_yuv420_none: OPTS = -pix_fmt yuv420p -pred 3
 
 FATE_UTVIDEOENC += fate-utvideoenc_yuv422_left
 fate-utvideoenc_yuv422_left: OPTS = -pix_fmt yuv422p -pred left
@@ -66,7 +63,10 @@ fate-utvideoenc_yuv422_left: OPTS = -pix_fmt yuv422p -pred left
 FATE_UTVIDEOENC += fate-utvideoenc_yuv422_median
 fate-utvideoenc_yuv422_median: OPTS = -pix_fmt yuv422p -pred median
 
-$(FATE_UTVIDEOENC): tests/vsynth1/00.pgm
+FATE_UTVIDEOENC += fate-utvideoenc_yuv422_none
+fate-utvideoenc_yuv422_none: OPTS = -pix_fmt yuv422p -pred 3
+
+$(FATE_UTVIDEOENC): $(VREF)
 
 FATE_AVCONV-$(call ENCMUX, UTVIDEO, AVI) += $(FATE_UTVIDEOENC)
 fate-utvideoenc: $(FATE_UTVIDEOENC)
diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak
index 36b9658..ed9fa2e 100644
--- a/tests/fate/vcodec.mak
+++ b/tests/fate/vcodec.mak
@@ -53,7 +53,7 @@ fate-vsynth%-dv-50:              DECOPTS = -sws_flags neighbor
 fate-vsynth%-dv-50:              FMT     = dv
 
 FATE_VCODEC-$(call ENCDEC, FFV1, AVI)   += ffv1
-fate-vsynth%-ffv1:               ENCOPTS = -strict -2
+fate-vsynth%-ffv1:               ENCOPTS = -slices 4 -strict -2
 
 FATE_VCODEC-$(call ENCDEC, FFVHUFF, AVI) += ffvhuff
 
@@ -111,7 +111,7 @@ $(FATE_MPEG2:%=fate-vsynth\%-%): FMT    = mpeg2video
 $(FATE_MPEG2:%=fate-vsynth\%-%): CODEC  = mpeg2video
 
 fate-vsynth%-mpeg2:              ENCOPTS = -qscale 10
-fate-vsynth%-mpeg2-422:          ENCOPTS = -vb 1000k                    \
+fate-vsynth%-mpeg2-422:          ENCOPTS = -b:v 1000k                   \
                                            -bf 2                        \
                                            -trellis 1                   \
                                            -flags +mv0+ildct+ilme       \
@@ -121,7 +121,7 @@ fate-vsynth%-mpeg2-422:          ENCOPTS = -vb 1000k                    \
                                            -pix_fmt yuv422p
 fate-vsynth%-mpeg2-idct-int:     ENCOPTS = -qscale 10 -idct int -dct int
 fate-vsynth%-mpeg2-ilace:        ENCOPTS = -qscale 10 -flags +ildct+ilme
-fate-vsynth%-mpeg2-ivlc-qprd:    ENCOPTS = -vb 500k                     \
+fate-vsynth%-mpeg2-ivlc-qprd:    ENCOPTS = -b:v 500k                    \
                                            -bf 2                        \
                                            -trellis 1                   \
                                            -flags +mv0                  \
@@ -150,34 +150,34 @@ FATE_VCODEC-$(call ENCDEC, MPEG4, AVI)     += $(FATE_MPEG4_AVI)
 fate-vsynth%-mpeg4:              ENCOPTS = -qscale 10 -flags +mv4 -mbd bits
 fate-vsynth%-mpeg4:              FMT     = mp4
 
-fate-vsynth%-mpeg4-rc:           ENCOPTS = -b 400k -bf 2
+fate-vsynth%-mpeg4-adap:         ENCOPTS = -b 550k -bf 2 -flags +mv4+mv0 \
+                                           -trellis 1 -cmp 1 -subcmp 2   \
+                                           -mbd rd -scplx_mask 0.3
 
 fate-vsynth%-mpeg4-adv:          ENCOPTS = -qscale 9 -flags +mv4+aic       \
                                            -data_partitioning 1 -trellis 1 \
                                            -mbd bits -ps 200
 
-fate-vsynth%-mpeg4-qprd:         ENCOPTS = -b 450k -bf 2 -trellis 1          \
-                                           -flags +mv4+mv0 -mpv_flags +qp_rd \
-                                           -cmp 2 -subcmp 2 -mbd rd
+fate-vsynth%-mpeg4-error:        ENCOPTS = -qscale 7 -flags +mv4+aic    \
+                                           -data_partitioning 1 -mbd rd \
+                                           -ps 250 -error 10
 
-fate-vsynth%-mpeg4-adap:         ENCOPTS = -b 550k -bf 2 -flags +mv4+mv0 \
-                                           -trellis 1 -cmp 1 -subcmp 2   \
-                                           -mbd rd -scplx_mask 0.3
+fate-vsynth%-mpeg4-nr:           ENCOPTS = -qscale 8 -flags +mv4 -mbd rd -nr 200
 
 fate-vsynth%-mpeg4-qpel:         ENCOPTS = -qscale 7 -flags +mv4+qpel -mbd 2 \
                                            -bf 2 -cmp 1 -subcmp 2
 
+fate-vsynth%-mpeg4-qprd:         ENCOPTS = -b 450k -bf 2 -trellis 1          \
+                                           -flags +mv4+mv0 -mpv_flags +qp_rd \
+                                           -cmp 2 -subcmp 2 -mbd rd
+
+fate-vsynth%-mpeg4-rc:           ENCOPTS = -b 400k -bf 2
+
 fate-vsynth%-mpeg4-thread:       ENCOPTS = -b 500k -flags +mv4+aic         \
                                            -data_partitioning 1 -trellis 1 \
                                            -mbd bits -ps 200 -bf 2         \
                                            -threads 2 -slices 2
 
-fate-vsynth%-mpeg4-error:        ENCOPTS = -qscale 7 -flags +mv4+aic    \
-                                           -data_partitioning 1 -mbd rd \
-                                           -ps 250 -error 10
-
-fate-vsynth%-mpeg4-nr:           ENCOPTS = -qscale 8 -flags +mv4 -mbd rd -nr 200
-
 FATE_VCODEC-$(call ENCDEC, MSMPEG4V3, AVI) += msmpeg4
 fate-vsynth%-msmpeg4:            ENCOPTS = -qscale 10
 
@@ -208,18 +208,6 @@ FATE_VCODEC-$(call ENCDEC, RV20, RM)    += rv20
 fate-vsynth%-rv20:               ENCOPTS = -qscale 10
 fate-vsynth%-rv20:               FMT     = rm
 
-FATE_VCODEC-$(call ENCDEC, SNOW, AVI)   += snow snow-hpel snow-ll
-fate-vsynth%-snow:               ENCOPTS = -strict -2 -qscale 2 -flags +qpel \
-                                           -me_method iter -dia_size 2       \
-                                           -cmp 12 -subcmp 12 -s 128x64
-
-fate-vsynth%-snow-hpel:          ENCOPTS = -strict -2 -qscale 2              \
-                                           -me_method iter -dia_size 2       \
-                                           -cmp 12 -subcmp 12 -s 128x64
-
-fate-vsynth%-snow-ll:            ENCOPTS = -strict -2 -qscale .001 -pred 1 \
-                                           -flags +mv4+qpel
-
 FATE_VCODEC-$(call ENCDEC, SVQ1, MOV)   += svq1
 fate-vsynth%-svq1:               ENCOPTS = -qscale 3 -pix_fmt yuv410p
 fate-vsynth%-svq1:               FMT     = mov
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index 51315df..34b385a 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -1,265 +1,277 @@
 FATE_4XM += fate-4xm-1
-fate-4xm-1: CMD = framecrc -i $(SAMPLES)/4xm/version1.4xm -pix_fmt rgb24 -an
+fate-4xm-1: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/version1.4xm -pix_fmt rgb24 -an
 
 FATE_4XM += fate-4xm-2
-fate-4xm-2: CMD = framecrc -i $(SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an
+fate-4xm-2: CMD = framecrc -i $(TARGET_SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, FOURXM, FOURXM) += $(FATE_4XM)
 fate-4xm: $(FATE_4XM)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, AASC) += fate-aasc
-fate-aasc: CMD = framecrc -i $(SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24
+fate-aasc: CMD = framecrc -i $(TARGET_SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MM, MMVIDEO) += fate-alg-mm
-fate-alg-mm: CMD = framecrc -i $(SAMPLES)/alg-mm/ibmlogo.mm -an -pix_fmt rgb24
+fate-alg-mm: CMD = framecrc -i $(TARGET_SAMPLES)/alg-mm/ibmlogo.mm -an -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, AMV) += fate-amv
-fate-amv: CMD = framecrc -idct simple -i $(SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -an
+fate-amv: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, TTY, ANSI) += fate-ansi
-fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24
+fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(TARGET_SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, RPL, ESCAPE124) += fate-armovie-escape124
-fate-armovie-escape124: CMD = framecrc -i $(SAMPLES)/rpl/ESCAPE.RPL -pix_fmt rgb24
+fate-armovie-escape124: CMD = framecrc -i $(TARGET_SAMPLES)/rpl/ESCAPE.RPL -pix_fmt rgb24
+
+FATE_SAMPLES_AVCONV-$(call DEMDEC, RPL, ESCAPE130) += fate-armovie-escape130
+fate-armovie-escape130: CMD = framecrc -i $(TARGET_SAMPLES)/rpl/landing.rpl -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, AURA) += fate-auravision-v1
-fate-auravision-v1: CMD = framecrc -i $(SAMPLES)/auravision/SOUVIDEO.AVI -an
+fate-auravision-v1: CMD = framecrc -i $(TARGET_SAMPLES)/auravision/SOUVIDEO.AVI -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, AURA2) += fate-auravision-v2
-fate-auravision-v2: CMD = framecrc -i $(SAMPLES)/auravision/salma-hayek-in-ugly-betty-partial-avi -an
+fate-auravision-v2: CMD = framecrc -i $(TARGET_SAMPLES)/auravision/salma-hayek-in-ugly-betty-partial-avi -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, BETHSOFTVID, BETHSOFTVID) += fate-bethsoft-vid
-fate-bethsoft-vid: CMD = framecrc -i $(SAMPLES)/bethsoft-vid/ANIM0001.VID -t 5 -pix_fmt rgb24
+fate-bethsoft-vid: CMD = framecrc -i $(TARGET_SAMPLES)/bethsoft-vid/ANIM0001.VID -t 5 -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, BFI, BFI) += fate-bfi
-fate-bfi: CMD = framecrc -i $(SAMPLES)/bfi/2287.bfi -pix_fmt rgb24
+fate-bfi: CMD = framecrc -i $(TARGET_SAMPLES)/bfi/2287.bfi -pix_fmt rgb24
 
 FATE_BINK_VIDEO += fate-bink-video-b
-fate-bink-video-b: CMD = framecrc -i $(SAMPLES)/bink/RISE.BIK -frames 30
+fate-bink-video-b: CMD = framecrc -i $(TARGET_SAMPLES)/bink/RISE.BIK -frames 30
 
 FATE_BINK_VIDEO += fate-bink-video-f
-fate-bink-video-f: CMD = framecrc -i $(SAMPLES)/bink/hol2br.bik
+fate-bink-video-f: CMD = framecrc -i $(TARGET_SAMPLES)/bink/hol2br.bik
 
 FATE_BINK_VIDEO += fate-bink-video-i
-fate-bink-video-i: CMD = framecrc -i $(SAMPLES)/bink/RazOnBull.bik -an
+fate-bink-video-i: CMD = framecrc -i $(TARGET_SAMPLES)/bink/RazOnBull.bik -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, BINK, BINK) += $(FATE_BINK_VIDEO)
 fate-bink-video: $(FATE_BINK_VIDEO)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, BMV, BMV_VIDEO) += fate-bmv-video
-fate-bmv-video: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24 -an
+fate-bmv-video: CMD = framecrc -i $(TARGET_SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MPEGPS, CAVS) += fate-cavs
-fate-cavs: CMD = framecrc -i $(SAMPLES)/cavs/cavs.mpg -an
+fate-cavs: CMD = framecrc -i $(TARGET_SAMPLES)/cavs/cavs.mpg -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, CDG, CDGRAPHICS) += fate-cdgraphics
-fate-cdgraphics: CMD = framecrc -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1
+fate-cdgraphics: CMD = framecrc -i $(TARGET_SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, CLJR) += fate-cljr
-fate-cljr: CMD = framecrc -i $(SAMPLES)/cljr/testcljr-partial.avi
+fate-cljr: CMD = framecrc -i $(TARGET_SAMPLES)/cljr/testcljr-partial.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, PNG) += fate-corepng
-fate-corepng: CMD = framecrc -i $(SAMPLES)/png1/corepng-partial.avi
+fate-corepng: CMD = framecrc -i $(TARGET_SAMPLES)/png1/corepng-partial.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVS, AVS) += fate-creatureshock-avs
-fate-creatureshock-avs: CMD = framecrc -i $(SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24
-
-FATE_CVID-$(CONFIG_AVI_DEMUXER) += fate-cvid-partial
-fate-cvid-partial: CMD = framecrc -i $(SAMPLES)/cvid/laracroft-cinepak-partial.avi -an
+fate-creatureshock-avs: CMD = framecrc -i $(TARGET_SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24
 
 FATE_CVID-$(CONFIG_MOV_DEMUXER) += fate-cvid-palette
-fate-cvid-palette: CMD = framecrc -i $(SAMPLES)/cvid/catfight-cvid-pal8-partial.mov -pix_fmt rgb24 -an
+fate-cvid-palette: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/catfight-cvid-pal8-partial.mov -pix_fmt rgb24 -an
+
+FATE_CVID-$(CONFIG_AVI_DEMUXER) += fate-cvid-partial
+fate-cvid-partial: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/laracroft-cinepak-partial.avi -an
 
 FATE_CVID-$(CONFIG_AVI_DEMUXER) += fate-cvid-grayscale
-fate-cvid-grayscale: CMD = framecrc -i $(SAMPLES)/cvid/pcitva15.avi -an
+fate-cvid-grayscale: CMD = framecrc -i $(TARGET_SAMPLES)/cvid/pcitva15.avi -an
 
 FATE_SAMPLES_AVCONV-$(CONFIG_CINEPAK_DECODER) += $(FATE_CVID-yes)
 fate-cvid: $(FATE_CVID-yes)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, C93, C93) += fate-cyberia-c93
-fate-cyberia-c93: CMD = framecrc -i $(SAMPLES)/cyberia-c93/intro1.c93 -t 3 -pix_fmt rgb24
+fate-cyberia-c93: CMD = framecrc -i $(TARGET_SAMPLES)/cyberia-c93/intro1.c93 -t 3 -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, CYUV) += fate-cyuv
-fate-cyuv: CMD = framecrc -i $(SAMPLES)/cyuv/cyuv.avi
+fate-cyuv: CMD = framecrc -i $(TARGET_SAMPLES)/cyuv/cyuv.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, DSICIN, DSICINVIDEO) += fate-delphine-cin-video
-fate-delphine-cin-video: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -an
+fate-delphine-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, ANM, ANM) += fate-deluxepaint-anm
-fate-deluxepaint-anm: CMD = framecrc -i $(SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24
+fate-deluxepaint-anm: CMD = framecrc -i $(TARGET_SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24
 
 FATE_TRUEMOTION1 += fate-truemotion1-15
-fate-truemotion1-15: CMD = framecrc -i $(SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24 -an
+fate-truemotion1-15: CMD = framecrc -i $(TARGET_SAMPLES)/duck/phant2-940.duk -pix_fmt rgb24 -an
 
 FATE_TRUEMOTION1 += fate-truemotion1-24
-fate-truemotion1-24: CMD = framecrc -i $(SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24 -an
+fate-truemotion1-24: CMD = framecrc -i $(TARGET_SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, TRUEMOTION1) += $(FATE_TRUEMOTION1)
 fate-truemotion1: $(FATE_TRUEMOTION1)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, TRUEMOTION2) += fate-truemotion2
-fate-truemotion2: CMD = framecrc -i $(SAMPLES)/duck/tm20.avi
+fate-truemotion2: CMD = framecrc -i $(TARGET_SAMPLES)/duck/tm20.avi
 
 FATE_DXA += fate-dxa-feeble
-fate-dxa-feeble: CMD = framecrc -i $(SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24 -an
+fate-dxa-feeble: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/meetsquid.dxa -t 2 -pix_fmt rgb24 -an
 
 FATE_DXA += fate-dxa-scummvm
-fate-dxa-scummvm: CMD = framecrc -i $(SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24
+fate-dxa-scummvm: CMD = framecrc -i $(TARGET_SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, DXA, DXA) += $(FATE_DXA)
 fate-dxa: $(FATE_DXA)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, SEGAFILM, CINEPAK) += fate-film-cvid
-fate-film-cvid: CMD = framecrc -i $(SAMPLES)/film/logo-capcom.cpk -an
+fate-film-cvid: CMD = framecrc -i $(TARGET_SAMPLES)/film/logo-capcom.cpk -an
 
 FATE_FLIC += fate-flic-af11-palette-change
-fate-flic-af11-palette-change: CMD = framecrc -i $(SAMPLES)/fli/fli-engines.fli -t 3.3 -pix_fmt rgb24
+fate-flic-af11-palette-change: CMD = framecrc -i $(TARGET_SAMPLES)/fli/fli-engines.fli -t 3.3 -pix_fmt rgb24
 
 FATE_FLIC += fate-flic-af12
-fate-flic-af12: CMD = framecrc -i $(SAMPLES)/fli/jj00c2.fli -pix_fmt rgb24
+fate-flic-af12: CMD = framecrc -i $(TARGET_SAMPLES)/fli/jj00c2.fli -pix_fmt rgb24
 
 FATE_FLIC += fate-flic-magiccarpet
-fate-flic-magiccarpet: CMD = framecrc -i $(SAMPLES)/fli/intel.dat -pix_fmt rgb24
+fate-flic-magiccarpet: CMD = framecrc -i $(TARGET_SAMPLES)/fli/intel.dat -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, FLIC, FLIC) += $(FATE_FLIC)
 fate-flic: $(FATE_FLIC)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, FRWU) += fate-frwu
-fate-frwu: CMD = framecrc -i $(SAMPLES)/frwu/frwu.avi
+fate-frwu: CMD = framecrc -i $(TARGET_SAMPLES)/frwu/frwu.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, IDCIN, IDCIN) += fate-id-cin-video
-fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
+fate-id-cin-video: CMD = framecrc -i $(TARGET_SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call ENCDEC, ROQ PGMYUV, ROQ IMAGE2) += fate-idroq-video-encode
-fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2
+fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2
 
 FATE_IFF-$(CONFIG_IFF_BYTERUN1_DECODER) += fate-iff-byterun1
-fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24
+fate-iff-byterun1: CMD = framecrc -i $(TARGET_SAMPLES)/iff/ASH.LBM -pix_fmt rgb24
 
 FATE_IFF-$(CONFIG_EIGHTSVX_FIB_DECODER) += fate-iff-fibonacci
-fate-iff-fibonacci: CMD = md5 -i $(SAMPLES)/iff/dasboot-in-compressed -f s16le
+fate-iff-fibonacci: CMD = md5 -i $(TARGET_SAMPLES)/iff/dasboot-in-compressed -f s16le
 
 FATE_IFF-$(CONFIG_IFF_ILBM_DECODER) += fate-iff-ilbm
-fate-iff-ilbm: CMD = framecrc -i $(SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24
+fate-iff-ilbm: CMD = framecrc -i $(TARGET_SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(CONFIG_IFF_DEMUXER)  += $(FATE_IFF-yes)
 fate-iff: $(FATE_IFF-yes)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, IPMOVIE, INTERPLAY_VIDEO) += fate-interplay-mve-8bit
-fate-interplay-mve-8bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24 -an
+fate-interplay-mve-8bit: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, IPMOVIE, INTERPLAY_VIDEO) += fate-interplay-mve-16bit
-fate-interplay-mve-16bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24 -an
+fate-interplay-mve-16bit: CMD = framecrc -i $(TARGET_SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24 -an
+
+FATE_SAMPLES_AVCONV-$(call DEMDEC, MXF, JPEG2000) += fate-jpeg2000-dcinema
+fate-jpeg2000-dcinema: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/jpeg2000/chiens_dcinema2K.mxf -pix_fmt xyz12le
+
+FATE_SAMPLES_AVCONV-$(call DEMDEC, JV, JV) += fate-jv
+fate-jv: CMD = framecrc -i $(TARGET_SAMPLES)/jv/intro.jv -an -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, KGV1) += fate-kgv1
-fate-kgv1: CMD = framecrc -i $(SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an
+fate-kgv1: CMD = framecrc -i $(TARGET_SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, KMVC) += fate-kmvc
-fate-kmvc: CMD = framecrc -i $(SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24
+fate-kmvc: CMD = framecrc -i $(TARGET_SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, EA, MDEC) += fate-mdec
-fate-mdec: CMD = framecrc -idct simple -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct -an
+fate-mdec: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/ea-dct/NFS2Esprit-partial.dct -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, STR, MDEC) += fate-mdec-v3
-fate-mdec-v3: CMD = framecrc -idct simple -i $(SAMPLES)/psx-str/abc000_cut.str -an
+fate-mdec-v3: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/psx-str/abc000_cut.str -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MSNWC_TCP, MIMIC) += fate-mimic
-fate-mimic: CMD = framecrc -idct simple -i $(SAMPLES)/mimic/mimic2-womanloveffmpeg.cam
+fate-mimic: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/mimic/mimic2-womanloveffmpeg.cam
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, MJPEGB) += fate-mjpegb
-fate-mjpegb: CMD = framecrc -idct simple -flags +bitexact -i $(SAMPLES)/mjpegb/mjpegb_part.mov -an
+fate-mjpegb: CMD = framecrc -idct simple -flags +bitexact -i $(TARGET_SAMPLES)/mjpegb/mjpegb_part.mov -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MVI, MOTIONPIXELS) += fate-motionpixels
-fate-motionpixels: CMD = framecrc -i $(SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111
+fate-motionpixels: CMD = framecrc -i $(TARGET_SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MPEGTS, MPEG2VIDEO) += fate-mpeg2-field-enc
-fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an
+fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -idct simple -i $(TARGET_SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an -vframes 30
 
 # FIXME dropped frames in this test because of coarse timebase
 FATE_NUV += fate-nuv-rtjpeg
-fate-nuv-rtjpeg: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/Today.nuv -an
+fate-nuv-rtjpeg: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/nuv/Today.nuv -an
 
 FATE_NUV += fate-nuv-rtjpeg-fh
-fate-nuv-rtjpeg-fh: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/rtjpeg_frameheader.nuv -an
+fate-nuv-rtjpeg-fh: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/nuv/rtjpeg_frameheader.nuv -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, NUV, NUV) += $(FATE_NUV)
 fate-nuv: $(FATE_NUV)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, QPEG) += fate-qpeg
-fate-qpeg: CMD = framecrc -i $(SAMPLES)/qpeg/Clock.avi -an -pix_fmt rgb24
+fate-qpeg: CMD = framecrc -i $(TARGET_SAMPLES)/qpeg/Clock.avi -an -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, R210) += fate-r210
-fate-r210: CMD = framecrc -i $(SAMPLES)/r210/r210.avi -pix_fmt rgb48le
+fate-r210: CMD = framecrc -i $(TARGET_SAMPLES)/r210/r210.avi -pix_fmt rgb48le
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, RL2, RL2) += fate-rl2
-fate-rl2: CMD = framecrc -i $(SAMPLES)/rl2/Z4915300.RL2 -pix_fmt rgb24 -an
+fate-rl2: CMD = framecrc -i $(TARGET_SAMPLES)/rl2/Z4915300.RL2 -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, ROQ, ROQ) += fate-roqvideo
-fate-roqvideo: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -an
+fate-roqvideo: CMD = framecrc -i $(TARGET_SAMPLES)/idroq/idlogo.roq -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, VMD, VMDVIDEO) += fate-sierra-vmd-video
-fate-sierra-vmd-video: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -pix_fmt rgb24 -an
+fate-sierra-vmd-video: CMD = framecrc -i $(TARGET_SAMPLES)/vmd/12.vmd -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, SMACKER, SMACKER) += fate-smacker-video
-fate-smacker-video: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24 -an
+fate-smacker-video: CMD = framecrc -i $(TARGET_SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, SMC) += fate-smc
-fate-smc: CMD = framecrc -i $(SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24
+fate-smc: CMD = framecrc -i $(TARGET_SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, SP5X) += fate-sp5x
-fate-sp5x: CMD = framecrc -idct simple -i $(SAMPLES)/sp5x/sp5x_problem.avi
+fate-sp5x: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/sp5x/sp5x_problem.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, SRT, SRT) += fate-sub-srt
-fate-sub-srt: CMD = md5 -i $(SAMPLES)/sub/SubRip_capability_tester.srt -f ass
+fate-sub-srt: CMD = md5 -i $(TARGET_SAMPLES)/sub/SubRip_capability_tester.srt -f ass
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, THP, THP) += fate-thp
-fate-thp: CMD = framecrc -idct simple -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp -an
+fate-thp: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/thp/pikmin2-opening1-partial.thp -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, TIERTEXSEQ, TIERTEXSEQVIDEO) += fate-tiertex-seq
-fate-tiertex-seq: CMD = framecrc -i $(SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24
+fate-tiertex-seq: CMD = framecrc -i $(TARGET_SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, TMV, TMV) += fate-tmv
-fate-tmv: CMD = framecrc -i $(SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24
+fate-tmv: CMD = framecrc -i $(TARGET_SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24
 
 FATE_TXD += fate-txd-16bpp
-fate-txd-16bpp: CMD = framecrc -i $(SAMPLES)/txd/misc.txd -pix_fmt bgra -an
+fate-txd-16bpp: CMD = framecrc -i $(TARGET_SAMPLES)/txd/misc.txd -pix_fmt bgra -an
 
 FATE_TXD += fate-txd-pal8
-fate-txd-pal8: CMD = framecrc -i $(SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an
+fate-txd-pal8: CMD = framecrc -i $(TARGET_SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, TXD, TXD) += $(FATE_TXD)
 fate-txd: $(FATE_TXD)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, ULTI) += fate-ulti
-fate-ulti: CMD = framecrc -i $(SAMPLES)/ulti/hit12w.avi -an
+fate-ulti: CMD = framecrc -i $(TARGET_SAMPLES)/ulti/hit12w.avi -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, V210) += fate-v210
-fate-v210: CMD = framecrc -i $(SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an
+fate-v210: CMD = framecrc -i $(TARGET_SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, V410) += fate-v410dec
-fate-v410dec: CMD = framecrc -i $(SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le
+fate-v410dec: CMD = framecrc -i $(TARGET_SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le
 
 FATE_SAMPLES_AVCONV-$(call ENCDEC, V410 PGMYUV, AVI IMAGE2) += fate-v410enc
-fate-v410enc: tests/vsynth1/00.pgm
+fate-v410enc: $(VREF)
 fate-v410enc: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -flags +bitexact -vcodec v410 -f avi
 
+FATE_SAMPLES_AVCONV-$(call DEMDEC, SIFF, VB) += fate-vb
+fate-vb: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24 -an
+
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, VCR1) += fate-vcr1
-fate-vcr1: CMD = framecrc -i $(SAMPLES)/vcr1/VCR1test.avi -an
+fate-vcr1: CMD = framecrc -i $(TARGET_SAMPLES)/vcr1/VCR1test.avi -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, XL) += fate-videoxl
-fate-videoxl: CMD = framecrc -i $(SAMPLES)/vixl/pig-vixl.avi
+fate-videoxl: CMD = framecrc -i $(TARGET_SAMPLES)/vixl/pig-vixl.avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, WSVQA, VQA) += fate-vqa-cc
-fate-vqa-cc: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24 -an
+fate-vqa-cc: CMD = framecrc -i $(TARGET_SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, WC3, XAN_WC3) += fate-wc3movie-xan
-fate-wc3movie-xan: CMD = framecrc -i $(SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24
+fate-wc3movie-xan: CMD = framecrc -i $(TARGET_SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, WNV1) += fate-wnv1
-fate-wnv1: CMD = framecrc -i $(SAMPLES)/wnv1/wnv1-codec.avi -an
+fate-wnv1: CMD = framecrc -i $(TARGET_SAMPLES)/wnv1/wnv1-codec.avi -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, YOP, YOP) += fate-yop
-fate-yop: CMD = framecrc -i $(SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an
+fate-yop: CMD = framecrc -i $(TARGET_SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, XAN_WC4) += fate-xxan-wc4
-fate-xxan-wc4: CMD = framecrc -i $(SAMPLES)/wc4-xan/wc4trailer-partial.avi -an
+fate-xxan-wc4: CMD = framecrc -i $(TARGET_SAMPLES)/wc4-xan/wc4trailer-partial.avi -an
diff --git a/tests/fate/voice.mak b/tests/fate/voice.mak
index 8fe445a..975936c 100644
--- a/tests/fate/voice.mak
+++ b/tests/fate/voice.mak
@@ -1,5 +1,5 @@
 FATE_G722 += fate-g722dec-1
-fate-g722dec-1: CMD = framecrc -i $(SAMPLES)/g722/conf-adminmenu-162.g722
+fate-g722dec-1: CMD = framecrc -i $(TARGET_SAMPLES)/g722/conf-adminmenu-162.g722
 
 FATE_G722 += fate-g722-encode
 fate-g722-encode: tests/data/asynth-16000-1.wav
@@ -10,28 +10,28 @@ FATE_SAMPLES_AVCONV += $(FATE_G722)
 fate-g722: $(FATE_G722)
 
 FATE_G723_1 += fate-g723_1-dec-1
-fate-g723_1-dec-1: CMD = framecrc -postfilter 0 -i $(SAMPLES)/g723_1/ineqd53.tco
+fate-g723_1-dec-1: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/ineqd53.tco
 
 FATE_G723_1 += fate-g723_1-dec-2
-fate-g723_1-dec-2: CMD = framecrc -postfilter 0 -i $(SAMPLES)/g723_1/overd53.tco
+fate-g723_1-dec-2: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/overd53.tco
 
 FATE_G723_1 += fate-g723_1-dec-3
-fate-g723_1-dec-3: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/overd63p.tco
+fate-g723_1-dec-3: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/overd63p.tco
 
 FATE_G723_1 += fate-g723_1-dec-4
-fate-g723_1-dec-4: CMD = framecrc -postfilter 0 -i $(SAMPLES)/g723_1/pathd53.tco
+fate-g723_1-dec-4: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/pathd53.tco
 
 FATE_G723_1 += fate-g723_1-dec-5
-fate-g723_1-dec-5: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/pathd63p.tco
+fate-g723_1-dec-5: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/pathd63p.tco
 
 FATE_G723_1 += fate-g723_1-dec-6
-fate-g723_1-dec-6: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/tamed63p.tco
+fate-g723_1-dec-6: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/tamed63p.tco
 
 FATE_G723_1 += fate-g723_1-dec-7
-fate-g723_1-dec-7: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/dtx63b.tco
+fate-g723_1-dec-7: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63b.tco
 
 FATE_G723_1 += fate-g723_1-dec-8
-fate-g723_1-dec-8: CMD = framecrc -postfilter 1 -i $(SAMPLES)/g723_1/dtx63e.tco
+fate-g723_1-dec-8: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63e.tco
 
 FATE_SAMPLES_AVCONV += $(FATE_G723_1)
 fate-g723_1: $(FATE_G723_1)
@@ -55,20 +55,20 @@ FATE_SAMPLES_AVCONV += $(FATE_G726)
 fate-g726: $(FATE_G726)
 
 FATE_GSM += fate-gsm-ms
-fate-gsm-ms: CMD = framecrc -i $(SAMPLES)/gsm/ciao.wav
+fate-gsm-ms: CMD = framecrc -i $(TARGET_SAMPLES)/gsm/ciao.wav
 
 FATE_GSM += fate-gsm-toast
-fate-gsm-toast: CMD = framecrc -i $(SAMPLES)/gsm/sample-gsm-8000.mov -t 10
+fate-gsm-toast: CMD = framecrc -i $(TARGET_SAMPLES)/gsm/sample-gsm-8000.mov -t 10
 
 FATE_SAMPLES_AVCONV += $(FATE_GSM)
 fate-gsm: $(FATE_GSM)
 
 FATE_SAMPLES_AVCONV += fate-qcelp
-fate-qcelp: CMD = pcm -i $(SAMPLES)/qcp/0036580847.QCP
+fate-qcelp: CMD = pcm -i $(TARGET_SAMPLES)/qcp/0036580847.QCP
 fate-qcelp: CMP = oneoff
 fate-qcelp: REF = $(SAMPLES)/qcp/0036580847.pcm
 
 FATE_SAMPLES_AVCONV += fate-truespeech
-fate-truespeech: CMD = pcm -i $(SAMPLES)/truespeech/a6.wav
+fate-truespeech: CMD = pcm -i $(TARGET_SAMPLES)/truespeech/a6.wav
 fate-truespeech: CMP = oneoff
 fate-truespeech: REF = $(SAMPLES)/truespeech/a6.pcm
diff --git a/tests/fate/vorbis.mak b/tests/fate/vorbis.mak
index 39a9724..4b72373 100644
--- a/tests/fate/vorbis.mak
+++ b/tests/fate/vorbis.mak
@@ -1,83 +1,83 @@
 FATE_VORBIS += fate-vorbis-1
-fate-vorbis-1: CMD = pcm -i $(SAMPLES)/vorbis/1.0.1-test_small.ogg
+fate-vorbis-1: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/1.0.1-test_small.ogg
 fate-vorbis-1: REF = $(SAMPLES)/vorbis/1.0.1-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-2
-fate-vorbis-2: CMD = pcm -i $(SAMPLES)/vorbis/1.0-test_small.ogg
+fate-vorbis-2: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/1.0-test_small.ogg
 fate-vorbis-2: REF = $(SAMPLES)/vorbis/1.0-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-3
-fate-vorbis-3: CMD = pcm -i $(SAMPLES)/vorbis/beta3-test_small.ogg
+fate-vorbis-3: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/beta3-test_small.ogg
 fate-vorbis-3: REF = $(SAMPLES)/vorbis/beta3-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-4
-fate-vorbis-4: CMD = pcm -i $(SAMPLES)/vorbis/beta4-test_small.ogg
+fate-vorbis-4: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/beta4-test_small.ogg
 fate-vorbis-4: REF = $(SAMPLES)/vorbis/beta4-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-5
-fate-vorbis-5: CMD = pcm -i $(SAMPLES)/vorbis/chain-test1_small.ogg
+fate-vorbis-5: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/chain-test1_small.ogg
 fate-vorbis-5: REF = $(SAMPLES)/vorbis/chain-test1_small.pcm
 
 FATE_VORBIS += fate-vorbis-6
-fate-vorbis-6: CMD = pcm -i $(SAMPLES)/vorbis/chain-test2_small.ogg
+fate-vorbis-6: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/chain-test2_small.ogg
 fate-vorbis-6: REF = $(SAMPLES)/vorbis/chain-test2_small.pcm
 
 FATE_VORBIS += fate-vorbis-7
-fate-vorbis-7: CMD = pcm -i $(SAMPLES)/vorbis/highrate-test_small.ogg
+fate-vorbis-7: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/highrate-test_small.ogg
 fate-vorbis-7: REF = $(SAMPLES)/vorbis/highrate-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-8
-fate-vorbis-8: CMD = pcm -i $(SAMPLES)/vorbis/lsp-test2_small.ogg
+fate-vorbis-8: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/lsp-test2_small.ogg
 fate-vorbis-8: REF = $(SAMPLES)/vorbis/lsp-test2_small.pcm
 
 FATE_VORBIS += fate-vorbis-9
-fate-vorbis-9: CMD = pcm -i $(SAMPLES)/vorbis/lsp-test3_small.ogg
+fate-vorbis-9: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/lsp-test3_small.ogg
 fate-vorbis-9: REF = $(SAMPLES)/vorbis/lsp-test3_small.pcm
 
 FATE_VORBIS += fate-vorbis-10
-fate-vorbis-10: CMD = pcm -i $(SAMPLES)/vorbis/lsp-test4_small.ogg
+fate-vorbis-10: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/lsp-test4_small.ogg
 fate-vorbis-10: REF = $(SAMPLES)/vorbis/lsp-test4_small.pcm
 
 FATE_VORBIS += fate-vorbis-11
-fate-vorbis-11: CMD = pcm -i $(SAMPLES)/vorbis/lsp-test_small.ogg
+fate-vorbis-11: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/lsp-test_small.ogg
 fate-vorbis-11: REF = $(SAMPLES)/vorbis/lsp-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-12
-fate-vorbis-12: CMD = pcm -i $(SAMPLES)/vorbis/mono_small.ogg
+fate-vorbis-12: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/mono_small.ogg
 fate-vorbis-12: REF = $(SAMPLES)/vorbis/mono_small.pcm
 
 FATE_VORBIS += fate-vorbis-13
-fate-vorbis-13: CMD = pcm -i $(SAMPLES)/vorbis/moog_small.ogg
+fate-vorbis-13: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/moog_small.ogg
 fate-vorbis-13: REF = $(SAMPLES)/vorbis/moog_small.pcm
 fate-vorbis-13: FUZZ = 2
 
 FATE_VORBIS += fate-vorbis-14
-fate-vorbis-14: CMD = pcm -i $(SAMPLES)/vorbis/rc1-test_small.ogg
+fate-vorbis-14: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/rc1-test_small.ogg
 fate-vorbis-14: REF = $(SAMPLES)/vorbis/rc1-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-15
-fate-vorbis-15: CMD = pcm -i $(SAMPLES)/vorbis/rc2-test2_small.ogg
+fate-vorbis-15: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/rc2-test2_small.ogg
 fate-vorbis-15: REF = $(SAMPLES)/vorbis/rc2-test2_small.pcm
 
 FATE_VORBIS += fate-vorbis-16
-fate-vorbis-16: CMD = pcm -i $(SAMPLES)/vorbis/rc2-test_small.ogg
+fate-vorbis-16: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/rc2-test_small.ogg
 fate-vorbis-16: REF = $(SAMPLES)/vorbis/rc2-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-17
-fate-vorbis-17: CMD = pcm -i $(SAMPLES)/vorbis/rc3-test_small.ogg
+fate-vorbis-17: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/rc3-test_small.ogg
 fate-vorbis-17: REF = $(SAMPLES)/vorbis/rc3-test_small.pcm
 
 FATE_VORBIS += fate-vorbis-18
-fate-vorbis-18: CMD = pcm -i $(SAMPLES)/vorbis/sleepzor_small.ogg
+fate-vorbis-18: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/sleepzor_small.ogg
 fate-vorbis-18: REF = $(SAMPLES)/vorbis/sleepzor_small.pcm
 fate-vorbis-18: FUZZ = 2
 
 FATE_VORBIS += fate-vorbis-19
-fate-vorbis-19: CMD = pcm -i $(SAMPLES)/vorbis/test-short2_small.ogg
+fate-vorbis-19: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/test-short2_small.ogg
 fate-vorbis-19: REF = $(SAMPLES)/vorbis/test-short2_small.pcm
 
 FATE_VORBIS += fate-vorbis-20
-fate-vorbis-20: CMD = pcm -i $(SAMPLES)/vorbis/6.ogg
+fate-vorbis-20: CMD = pcm -i $(TARGET_SAMPLES)/vorbis/6.ogg
 fate-vorbis-20: REF = $(SAMPLES)/vorbis/6.pcm
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, OGG, VORBIS) += $(FATE_VORBIS)
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index a870ea5..5df020e 100644
--- a/tests/fate/vpx.mak
+++ b/tests/fate/vpx.mak
@@ -1,26 +1,26 @@
-FATE_VP3-$(CONFIG_AVI_DEMUXER) += fate-vp31
-fate-vp31: CMD = framecrc -i $(SAMPLES)/vp3/vp31.avi
+FATE_VP3-$(call DEMDEC, MATROSKA, THEORA) += fate-theora-coeff-level64
+fate-theora-coeff-level64: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/vp3/coeff_level64.mkv
 
-FATE_VP3-$(CONFIG_MATROSKA_DEMUXER) += fate-vp3-coeff-level64
-fate-vp3-coeff-level64: CMD = framecrc -i $(SAMPLES)/vp3/coeff_level64.mkv
+FATE_VP3-$(call DEMDEC, AVI, VP3) += fate-vp31
+fate-vp31: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/vp3/vp31.avi
 
-FATE_SAMPLES_AVCONV-$(CONFIG_VP3_DECODER) += $(FATE_VP3-yes)
+FATE_SAMPLES_AVCONV += $(FATE_VP3-yes)
 fate-vp3: $(FATE_VP3-yes)
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, VP5) += fate-vp5
-fate-vp5: CMD = framecrc -i $(SAMPLES)/vp5/potter512-400-partial.avi -an
+fate-vp5: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/vp5/potter512-400-partial.avi -an
 
 FATE_VP6-$(call DEMDEC, EA, VP6) += fate-vp60
-fate-vp60: CMD = framecrc -i $(SAMPLES)/ea-vp6/g36.vp6
+fate-vp60: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/ea-vp6/g36.vp6
 
 FATE_VP6-$(call DEMDEC, EA, VP6) += fate-vp61
-fate-vp61: CMD = framecrc -i $(SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
+fate-vp61: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/ea-vp6/MovieSkirmishGondor.vp6 -t 4
 
 FATE_VP6-$(call DEMDEC, FLV, VP6A) += fate-vp6a
-fate-vp6a: CMD = framecrc -i $(SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv
+fate-vp6a: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv
 
 FATE_VP6-$(call DEMDEC, FLV, VP6F) += fate-vp6f
-fate-vp6f: CMD = framecrc -i $(SAMPLES)/flash-vp6/clip1024.flv
+fate-vp6f: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/flash-vp6/clip1024.flv
 
 FATE_SAMPLES_AVCONV += $(FATE_VP6-yes)
 fate-vp6: $(FATE_VP6-yes)
@@ -29,7 +29,7 @@ VP8_SUITE = 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017
 
 define FATE_VP8_SUITE
 FATE_VP8-$(CONFIG_IVF_DEMUXER) += fate-vp8-test-vector$(2)-$(1)
-fate-vp8-test-vector$(2)-$(1): CMD = framemd5 $(3) -i $(SAMPLES)/vp8-test-vectors-r1/vp80-00-comprehensive-$(1).ivf
+fate-vp8-test-vector$(2)-$(1): CMD = framemd5 $(3) -i $(TARGET_SAMPLES)/vp8-test-vectors-r1/vp80-00-comprehensive-$(1).ivf
 fate-vp8-test-vector$(2)-$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-test-vector-$(1)
 endef
 
@@ -39,15 +39,47 @@ $(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
 FATE_VP8-$(CONFIG_IVF_DEMUXER) += fate-vp8-sign-bias$(1)
-fate-vp8-sign-bias$(1): CMD = framemd5 $(2) -i $(SAMPLES)/vp8/sintel-signbias.ivf
+fate-vp8-sign-bias$(1): CMD = framemd5 $(2) -i $(TARGET_SAMPLES)/vp8/sintel-signbias.ivf
 fate-vp8-sign-bias$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-sign-bias
 
 FATE_VP8-$(CONFIG_MATROSKA_DEMUXER) += fate-vp8-size-change$(1)
-fate-vp8-size-change$(1): CMD = framemd5 $(2) -i $(SAMPLES)/vp8/frame_size_change.webm -frames:v 30
+fate-vp8-size-change$(1): CMD = framemd5 $(2) -i $(TARGET_SAMPLES)/vp8/frame_size_change.webm -frames:v 30
 fate-vp8-size-change$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-size-change
 endef
 
-$(eval $(call FATE_VP8_FULL))
-$(eval $(call FATE_VP8_FULL,-emu-edge,-flags +emu_edge))
+$(call FATE_VP8_FULL)
+$(call FATE_VP8_FULL,-emu-edge,-flags +emu_edge)
+
 FATE_SAMPLES_AVCONV-$(CONFIG_VP8_DECODER) += $(FATE_VP8-yes)
 fate-vp8: $(FATE_VP8-yes)
+
+define FATE_VP9_SUITE
+FATE_VP9-$(CONFIG_MATROSKA_DEMUXER) += fate-vp9$(2)-$(1)
+fate-vp9$(2)-$(1): CMD = framemd5 $(3) -i $(TARGET_SAMPLES)/vp9-test-vectors/vp90-2-$(1).webm
+fate-vp9$(2)-$(1): REF = $(SRC_PATH)/tests/ref/fate/vp9-$(1)
+endef
+
+VP9_Q = 00 01 02 03 04 05 06 07 08 09 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
+VP9_SHARP = 1 2 3 4 5 6 7
+VP9_SIZE_A = 08 10 16 18 32 34 64 66
+VP9_SIZE_B = 196 198 200 202 208 210 224 226
+
+define FATE_VP9_FULL
+$(foreach Q,$(VP9_Q),$(eval $(call FATE_VP9_SUITE,00-quantizer-$(Q),$(1),$(2))))
+$(foreach SHARP,$(VP9_SHARP),$(eval $(call FATE_VP9_SUITE,01-sharpness-$(SHARP),$(1),$(2))))
+$(foreach W,$(VP9_SIZE_A),$(eval $(foreach H,$(VP9_SIZE_A),$(eval $(call FATE_VP9_SUITE,02-size-$(W)x$(H),$(1),$(2))))))
+$(foreach W,$(VP9_SIZE_B),$(eval $(foreach H,$(VP9_SIZE_B),$(eval $(call FATE_VP9_SUITE,03-size-$(W)x$(H),$(1),$(2))))))
+$(eval $(call FATE_VP9_SUITE,03-deltaq,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,2pass-akiyo,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,segmentation-akiyo,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,tiling-pedestrian,$(1),$(2)))
+endef
+
+$(eval $(call FATE_VP9_FULL))
+$(eval $(call FATE_VP9_FULL,-emu-edge,-flags +emu_edge))
+
+FATE_SAMPLES_AVCONV-$(CONFIG_VP9_DECODER) += $(FATE_VP9-yes)
+fate-vp9: $(FATE_VP9-yes)
diff --git a/tests/fate/vqf.mak b/tests/fate/vqf.mak
index 6256941..355bab0 100644
--- a/tests/fate/vqf.mak
+++ b/tests/fate/vqf.mak
@@ -1,7 +1,7 @@
 FATE_SAMPLES_AVCONV-$(call DEMDEC, VQF, TWINVQ) += fate-twinvq
-fate-twinvq: CMD = pcm -i $(SAMPLES)/vqf/achterba.vqf
+fate-twinvq: CMD = pcm -i $(TARGET_SAMPLES)/vqf/achterba.vqf
 fate-twinvq: CMP = oneoff
 fate-twinvq: REF = $(SAMPLES)/vqf/achterba.pcm
 
 FATE_SAMPLES_AVCONV-$(CONFIG_VQF_DEMUXER) += fate-vqf-demux
-fate-vqf-demux: CMD = md5 -i $(SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
+fate-vqf-demux: CMD = md5 -i $(TARGET_SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
diff --git a/tests/fate/wavpack.mak b/tests/fate/wavpack.mak
index ef190fa..912c64a 100644
--- a/tests/fate/wavpack.mak
+++ b/tests/fate/wavpack.mak
@@ -1,92 +1,102 @@
 # lossless
 
-FATE_WAVPACK += fate-wavpack-lossless-float
-fate-wavpack-lossless-float: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le
-
 FATE_WAVPACK += fate-wavpack-lossless-8bit
-fate-wavpack-lossless-8bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/8bit-partial.wv -f s8
+fate-wavpack-lossless-8bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/8bit-partial.wv -f s8
 
 FATE_WAVPACK += fate-wavpack-lossless-12bit
-fate-wavpack-lossless-12bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/12bit-partial.wv -f s16le
+fate-wavpack-lossless-12bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/12bit-partial.wv -f s16le
 
 FATE_WAVPACK += fate-wavpack-lossless-16bit
-fate-wavpack-lossless-16bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/16bit-partial.wv -f s16le
+fate-wavpack-lossless-16bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/16bit-partial.wv -f s16le
 
 FATE_WAVPACK += fate-wavpack-lossless-24bit
-fate-wavpack-lossless-24bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/24bit-partial.wv -f s24le
+fate-wavpack-lossless-24bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/24bit-partial.wv -f s24le
 
 FATE_WAVPACK += fate-wavpack-lossless-32bit
-fate-wavpack-lossless-32bit: CMD = md5 -i $(SAMPLES)/wavpack/lossless/32bit_int-partial.wv -f s32le
+fate-wavpack-lossless-32bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/32bit_int-partial.wv -f s32le
 
-# lossy
+FATE_WAVPACK += fate-wavpack-lossless-float
+fate-wavpack-lossless-float: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossless/32bit_float-partial.wv -f f32le
 
-FATE_WAVPACK += fate-wavpack-lossy-float
-fate-wavpack-lossy-float: CMD = md5 -i $(SAMPLES)/wavpack/lossy/2.0_32-bit_float.wv -f f32le
+# lossy
 
 FATE_WAVPACK += fate-wavpack-lossy-8bit
-fate-wavpack-lossy-8bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_8-bit.wv -f s8
+fate-wavpack-lossy-8bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_8-bit.wv -f s8
 
 FATE_WAVPACK += fate-wavpack-lossy-16bit
-fate-wavpack-lossy-16bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_16-bit.wv -f s16le
+fate-wavpack-lossy-16bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_16-bit.wv -f s16le
 
 FATE_WAVPACK += fate-wavpack-lossy-24bit
-fate-wavpack-lossy-24bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_24-bit.wv -f s24le
+fate-wavpack-lossy-24bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_24-bit.wv -f s24le
 
 FATE_WAVPACK += fate-wavpack-lossy-32bit
-fate-wavpack-lossy-32bit: CMD = md5 -i $(SAMPLES)/wavpack/lossy/4.0_32-bit_int.wv -f s32le
+fate-wavpack-lossy-32bit: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/4.0_32-bit_int.wv -f s32le
+
+FATE_WAVPACK += fate-wavpack-lossy-float
+fate-wavpack-lossy-float: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/lossy/2.0_32-bit_float.wv -f f32le
 
 # channel configurations
 
 FATE_WAVPACK += fate-wavpack-channels-monofloat
-fate-wavpack-channels-monofloat: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/mono_float-partial.wv -f f32le
+fate-wavpack-channels-monofloat: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_float-partial.wv -f f32le
 
 FATE_WAVPACK += fate-wavpack-channels-monoint
-fate-wavpack-channels-monoint: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -f s16le
+fate-wavpack-channels-monoint: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -f s16le
 
 FATE_WAVPACK += fate-wavpack-channels-4.0
-fate-wavpack-channels-4.0: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/edward_4.0_16bit-partial.wv -f s16le
+fate-wavpack-channels-4.0: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/edward_4.0_16bit-partial.wv -f s16le
 
 FATE_WAVPACK += fate-wavpack-channels-5.1
-fate-wavpack-channels-5.1: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/panslab_sample_5.1_16bit-partial.wv -f s16le
+fate-wavpack-channels-5.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/panslab_sample_5.1_16bit-partial.wv -f s16le
 
 FATE_WAVPACK += fate-wavpack-channels-6.1
-fate-wavpack-channels-6.1: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -f s16le
+fate-wavpack-channels-6.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -f s16le
 
 FATE_WAVPACK += fate-wavpack-channels-7.1
-fate-wavpack-channels-7.1: CMD = md5 -i $(SAMPLES)/wavpack/num_channels/panslab_sample_7.1_16bit-partial.wv -f s16le
+fate-wavpack-channels-7.1: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/panslab_sample_7.1_16bit-partial.wv -f s16le
 
 # speed modes
 
 FATE_WAVPACK += fate-wavpack-speed-default
-fate-wavpack-speed-default: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/default-partial.wv  -f s16le
+fate-wavpack-speed-default: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/default-partial.wv  -f s16le
 
 FATE_WAVPACK += fate-wavpack-speed-fast
-fate-wavpack-speed-fast: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/fast-partial.wv  -f s16le
+fate-wavpack-speed-fast: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/fast-partial.wv  -f s16le
 
 FATE_WAVPACK += fate-wavpack-speed-high
-fate-wavpack-speed-high: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/high-partial.wv  -f s16le
+fate-wavpack-speed-high: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/high-partial.wv  -f s16le
 
 FATE_WAVPACK += fate-wavpack-speed-vhigh
-fate-wavpack-speed-vhigh: CMD = md5 -i $(SAMPLES)/wavpack/speed_modes/vhigh-partial.wv  -f s16le
+fate-wavpack-speed-vhigh: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/speed_modes/vhigh-partial.wv  -f s16le
 
 # special cases
 
-FATE_WAVPACK += fate-wavpack-cuesheet
-fate-wavpack-cuesheet: CMD = md5 -i $(SAMPLES)/wavpack/special/cue_sheet.wv -f s16le
-
-FATE_WAVPACK += fate-wavpack-zerolsbs
-fate-wavpack-zerolsbs: CMD = md5 -i $(SAMPLES)/wavpack/special/zero_lsbs.wv -f s16le
-
 FATE_WAVPACK += fate-wavpack-clipping
-fate-wavpack-clipping: CMD = md5 -i $(SAMPLES)/wavpack/special/clipping.wv -f s16le
+fate-wavpack-clipping: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/clipping.wv -f s16le
+
+FATE_WAVPACK += fate-wavpack-cuesheet
+fate-wavpack-cuesheet: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/cue_sheet.wv -f s16le
 
 FATE_WAVPACK += fate-wavpack-falsestereo
-fate-wavpack-falsestereo: CMD = md5 -i $(SAMPLES)/wavpack/special/false_stereo.wv -f s16le
+fate-wavpack-falsestereo: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/false_stereo.wv -f s16le
+
+FATE_WAVPACK += fate-wavpack-zerolsbs
+fate-wavpack-zerolsbs: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/zero_lsbs.wv -f s16le
 
 FATE_WAVPACK-$(call DEMDEC, WV, WAVPACK) += $(FATE_WAVPACK)
 
 FATE_WAVPACK-$(call DEMDEC, MATROSKA, WAVPACK) += fate-wavpack-matroskamode
-fate-wavpack-matroskamode: CMD = md5 -i $(SAMPLES)/wavpack/special/matroska_mode.mka -f s16le
+fate-wavpack-matroskamode: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/matroska_mode.mka -f s16le
+
+FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-mono
+fate-wavpack-matroska_mux-mono: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -c copy -flags +bitexact -f matroska
+fate-wavpack-matroska_mux-mono: CMP = oneline
+fate-wavpack-matroska_mux-mono: REF = 6bd769b3f0e9d7fa6261c3b73a53eb7d
+
+FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-61
+fate-wavpack-matroska_mux-61: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -c copy -flags +bitexact -f matroska
+fate-wavpack-matroska_mux-61: CMP = oneline
+fate-wavpack-matroska_mux-61: REF = 2d2f1e7f81a8b1983fcffc7f24de8a11
 
 FATE_SAMPLES_AVCONV += $(FATE_WAVPACK-yes)
 fate-wavpack: $(FATE_WAVPACK-yes)
diff --git a/tests/fate/wma.mak b/tests/fate/wma.mak
index b9a856c..1b8c5f9 100644
--- a/tests/fate/wma.mak
+++ b/tests/fate/wma.mak
@@ -1,13 +1,13 @@
 FATE_WMAPRO-$(call DEMDEC, ASF, WMAPRO) += fate-wmapro-2ch
-fate-wmapro-2ch: CMD = pcm -i $(SAMPLES)/wmapro/Beethovens_9th-1_small.wma
+fate-wmapro-2ch: CMD = pcm -i $(TARGET_SAMPLES)/wmapro/Beethovens_9th-1_small.wma
 fate-wmapro-2ch: REF = $(SAMPLES)/wmapro/Beethovens_9th-1_small.pcm
 
 FATE_WMAPRO-$(call DEMDEC, ASF, WMAPRO) += fate-wmapro-5.1
-fate-wmapro-5.1: CMD = pcm -i $(SAMPLES)/wmapro/latin_192_mulitchannel_cut.wma
+fate-wmapro-5.1: CMD = pcm -i $(TARGET_SAMPLES)/wmapro/latin_192_mulitchannel_cut.wma
 fate-wmapro-5.1: REF = $(SAMPLES)/wmapro/latin_192_mulitchannel_cut.pcm
 
 FATE_WMAPRO-$(call DEMDEC, MOV, WMAPRO) += fate-wmapro-ism
-fate-wmapro-ism: CMD = pcm -i $(SAMPLES)/isom/vc1-wmapro.ism -vn
+fate-wmapro-ism: CMD = pcm -i $(TARGET_SAMPLES)/isom/vc1-wmapro.ism -vn
 fate-wmapro-ism: REF = $(SAMPLES)/isom/vc1-wmapro.pcm
 
 $(FATE_WMAPRO-yes): CMP = oneoff
@@ -16,17 +16,17 @@ FATE_SAMPLES_AVCONV += $(FATE_WMAPRO-yes)
 fate-wmapro: $(FATE_WMAPRO-yes)
 
 FATE_WMAVOICE-$(call DEMDEC, ASF, WMAVOICE) += fate-wmavoice-7k
-fate-wmavoice-7k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-7K.wma
+fate-wmavoice-7k: CMD = pcm -i $(TARGET_SAMPLES)/wmavoice/streaming_CBR-7K.wma
 fate-wmavoice-7k: REF = $(SAMPLES)/wmavoice/streaming_CBR-7K.pcm
 fate-wmavoice-7k: FUZZ = 3
 
 FATE_WMAVOICE-$(call DEMDEC, ASF, WMAVOICE) += fate-wmavoice-11k
-fate-wmavoice-11k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-11K.wma
+fate-wmavoice-11k: CMD = pcm -i $(TARGET_SAMPLES)/wmavoice/streaming_CBR-11K.wma
 fate-wmavoice-11k: REF = $(SAMPLES)/wmavoice/streaming_CBR-11K.pcm
 fate-wmavoice-11k: FUZZ = 3
 
 FATE_WMAVOICE-$(call DEMDEC, ASF, WMAVOICE) += fate-wmavoice-19k
-fate-wmavoice-19k: CMD = pcm -i $(SAMPLES)/wmavoice/streaming_CBR-19K.wma
+fate-wmavoice-19k: CMD = pcm -i $(TARGET_SAMPLES)/wmavoice/streaming_CBR-19K.wma
 fate-wmavoice-19k: REF = $(SAMPLES)/wmavoice/streaming_CBR-19K.pcm
 fate-wmavoice-19k: FUZZ = 3
 
@@ -36,13 +36,13 @@ FATE_SAMPLES_AVCONV += $(FATE_WMAVOICE-yes)
 fate-wmavoice: $(FATE_WMAVOICE-yes)
 
 FATE_WMA_ENCODE-$(call ENCDEC, WMAV1, ASF) += fate-wmav1-encode
-fate-wmav1-encode: CMD = enc_dec_pcm asf wav s16le $(REF) -c:a wmav1 -b:a 128k
+fate-wmav1-encode: CMD = enc_dec_pcm asf wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a wmav1 -b:a 128k
 fate-wmav1-encode: CMP_SHIFT = -8192
 fate-wmav1-encode: CMP_TARGET = 291.06
 fate-wmav1-encode: SIZE_TOLERANCE = 4632
 
 FATE_WMA_ENCODE-$(call ENCDEC, WMAV2, ASF) += fate-wmav2-encode
-fate-wmav2-encode: CMD = enc_dec_pcm asf wav s16le $(REF) -c:a wmav2 -b:a 128k
+fate-wmav2-encode: CMD = enc_dec_pcm asf wav s16le $(subst $(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a wmav2 -b:a 128k
 fate-wmav2-encode: CMP_SHIFT = -8192
 fate-wmav2-encode: CMP_TARGET = 258.32
 fate-wmav2-encode: SIZE_TOLERANCE = 4632
diff --git a/tests/filtergraphs/channelmap b/tests/filtergraphs/channelmap
new file mode 100644
index 0000000..e2b6143
--- /dev/null
+++ b/tests/filtergraphs/channelmap
@@ -0,0 +1 @@
+channelmap=map=1|2|0|5|3|4:channel_layout=5.1
diff --git a/tests/filtergraphs/overlay b/tests/filtergraphs/overlay
new file mode 100644
index 0000000..d646463
--- /dev/null
+++ b/tests/filtergraphs/overlay
@@ -0,0 +1,2 @@
+[1:v] scale=50:50 [over];
+[0:v][over] overlay=20:20
diff --git a/tests/filtergraphs/select-alternate b/tests/filtergraphs/select-alternate
new file mode 100644
index 0000000..1302e42
--- /dev/null
+++ b/tests/filtergraphs/select-alternate
@@ -0,0 +1 @@
+select=not(mod(n\,2))
diff --git a/tests/filtergraphs/setpts b/tests/filtergraphs/setpts
new file mode 100644
index 0000000..79037d1
--- /dev/null
+++ b/tests/filtergraphs/setpts
@@ -0,0 +1,2 @@
+settb=1/1000,
+setpts=1/(35*TB) * (N + 0.05 * sin(N*2*PI/25))
diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh
index a198306..d9c8a8f 100755
--- a/tests/lavf-regression.sh
+++ b/tests/lavf-regression.sh
@@ -30,7 +30,7 @@ do_image_formats()
     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 $3 -frames 12 -y -qscale 10 $target_path/$file
     do_md5sum ${outfile}02.$1
     do_avconv_crc $file $DEC_OPTS $3 -i $target_path/$file
     echo $(wc -c ${outfile}02.$1)
diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh
deleted file mode 100755
index fc7c153..0000000
--- a/tests/lavfi-regression.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/sh
-#
-# automatic regression test for libavfilter
-#
-#
-#set -x
-
-set -e
-
-. $(dirname $0)/regression-funcs.sh
-
-eval do_$test=y
-
-do_video_filter() {
-    label=$1
-    filters=$2
-    shift 2
-    printf '%-20s' $label
-    run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src    \
-        $ENC_OPTS -vf "$filters" -vcodec rawvideo $* -f nut md5:
-}
-
-do_lavfi() {
-    if [ $test = $1 ] ; then
-        do_video_filter $test "$2"
-    fi
-}
-
-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 "null"               "null"
-do_lavfi "scale200"           "scale=200:200"
-do_lavfi "scale500"           "scale=500:500"
-do_lavfi "vflip"              "vflip"
-do_lavfi "vflip_crop"         "vflip,crop=iw-100:ih-100:100:100"
-do_lavfi "vflip_vflip"        "vflip,vflip"
-
-do_lavfi_pixfmts(){
-    test ${test%_[bl]e} = pixfmts_$1 || 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
-
-    # exclude pixel formats which are not supported as input
-    $avconv -pix_fmts list 2>/dev/null | awk 'NR > 8 && /^\..\./ { print $2 }' | sort >$exclude_fmts
-    $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ print $3 }' | sort | comm -23 - $exclude_fmts >$out_fmts
-
-    pix_fmts=$($showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ print $3 }' | sort | comm -12 - $out_fmts)
-    for pix_fmt in $pix_fmts; do
-        do_video_filter $pix_fmt "format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt
-    done
-
-    rm $exclude_fmts $out_fmts
-}
-
-# all these filters have exactly one input and exactly one output
-do_lavfi_pixfmts "copy"    ""
-do_lavfi_pixfmts "crop"    "100:100:100:100"
-do_lavfi_pixfmts "hflip"   ""
-do_lavfi_pixfmts "null"    ""
-do_lavfi_pixfmts "pad"     "500:400:20:20"
-do_lavfi_pixfmts "scale"   "200:100"
-do_lavfi_pixfmts "vflip"   ""
-
-if [ -n "$do_pixdesc" ]; then
-    pix_fmts="$($avconv -pix_fmts list 2>/dev/null | awk 'NR > 8 && /^IO/ { print $2 }' | sort)"
-    for pix_fmt in $pix_fmts; do
-        do_video_filter $pix_fmt "format=$pix_fmt,pixdesctest" -pix_fmt $pix_fmt
-    done
-fi
-
-# TODO: add tests for
-# direct rendering,
-# chains with feedback loops
diff --git a/tests/ref/acodec/alac b/tests/ref/acodec/alac
index bb7a202..dde0e36 100644
--- a/tests/ref/acodec/alac
+++ b/tests/ref/acodec/alac
@@ -1,4 +1,4 @@
-8ad790d3a0bbda81cd23c15ab8ba760d *tests/data/fate/acodec-alac.mov
+98cfcf6cf139844ca27d16f1fc64f62c *tests/data/fate/acodec-alac.mov
 389258 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/acodec/pcm-s16be b/tests/ref/acodec/pcm-s16be
index 39c3838..61e5664 100644
--- a/tests/ref/acodec/pcm-s16be
+++ b/tests/ref/acodec/pcm-s16be
@@ -1,4 +1,4 @@
-009a446579dd4cba793723b5e2b93c39 *tests/data/fate/acodec-pcm-s16be.mov
+b650d16f5ac191c41d5fa3657cf4c1ac *tests/data/fate/acodec-pcm-s16be.mov
 1060097 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/acodec/pcm-s24be b/tests/ref/acodec/pcm-s24be
index 20bc4e0..f673040 100644
--- a/tests/ref/acodec/pcm-s24be
+++ b/tests/ref/acodec/pcm-s24be
@@ -1,4 +1,4 @@
-de27dae0dff0359d8f39449b17d5607f *tests/data/fate/acodec-pcm-s24be.mov
+0bd99d1273fb1fb78055cf97f3efe299 *tests/data/fate/acodec-pcm-s24be.mov
 1589297 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/acodec/pcm-s32be b/tests/ref/acodec/pcm-s32be
index 302bc1a..1b6dec9 100644
--- a/tests/ref/acodec/pcm-s32be
+++ b/tests/ref/acodec/pcm-s32be
@@ -1,4 +1,4 @@
-2db1e7fe92d4006103691a4b59064dc6 *tests/data/fate/acodec-pcm-s32be.mov
+7ebffb0bd01c02b9953ee5b1e2f47910 *tests/data/fate/acodec-pcm-s32be.mov
 2118497 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/acodec/pcm-s8 b/tests/ref/acodec/pcm-s8
index f830d2f..c947729 100644
--- a/tests/ref/acodec/pcm-s8
+++ b/tests/ref/acodec/pcm-s8
@@ -1,4 +1,4 @@
-9ee95a7fff38831a1cad3b49c33e6ed9 *tests/data/fate/acodec-pcm-s8.mov
+3b52f563e8e99aa26253eff154980a93 *tests/data/fate/acodec-pcm-s8.mov
 530897 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/adpcm-ms-mono b/tests/ref/fate/adpcm-ms-mono
index 3bf44f8..c456708 100644
--- a/tests/ref/fate/adpcm-ms-mono
+++ b/tests/ref/fate/adpcm-ms-mono
@@ -43,4 +43,4 @@
 0,      20500,      20500,      500,     1000, 0xf195eb44
 0,      21000,      21000,      500,     1000, 0xa491f3ef
 0,      21500,      21500,      500,     1000, 0x2c036e18
-0,      22000,      22000,      500,     1000, 0x52d65e2a
+0,      22000,      22000,       50,      100, 0x0bd81f05
diff --git a/tests/ref/fate/armovie-escape130 b/tests/ref/fate/armovie-escape130
new file mode 100644
index 0000000..ee4ec26
--- /dev/null
+++ b/tests/ref/fate/armovie-escape130
@@ -0,0 +1,360 @@
+#tb 0: 1/15
+0,          0,          0,        1,    76800, 0x860502ee
+0,          1,          1,        1,    76800, 0x055da755
+0,          2,          2,        1,    76800, 0x67969220
+0,          3,          3,        1,    76800, 0xbb28885c
+0,          4,          4,        1,    76800, 0x4000a5dd
+0,          5,          5,        1,    76800, 0xfe1f6b04
+0,          6,          6,        1,    76800, 0x334cbe5d
+0,          7,          7,        1,    76800, 0x87d15088
+0,          8,          8,        1,    76800, 0x70248ad3
+0,          9,          9,        1,    76800, 0x29bcaea0
+0,         10,         10,        1,    76800, 0xee81d3e2
+0,         11,         11,        1,    76800, 0x5bdd3cbc
+0,         12,         12,        1,    76800, 0xd7a5e42e
+0,         13,         13,        1,    76800, 0xbb354f7c
+0,         14,         14,        1,    76800, 0x4c86e881
+0,         15,         15,        1,    76800, 0xc6acb7f4
+0,         16,         16,        1,    76800, 0x7701ca9c
+0,         17,         17,        1,    76800, 0x5555d472
+0,         18,         18,        1,    76800, 0xa8fbc2d6
+0,         19,         19,        1,    76800, 0x558ab4f2
+0,         20,         20,        1,    76800, 0x9eb5ab72
+0,         21,         21,        1,    76800, 0x4711a894
+0,         22,         22,        1,    76800, 0xd649c04c
+0,         23,         23,        1,    76800, 0x26b9d6cc
+0,         24,         24,        1,    76800, 0x6217e494
+0,         25,         25,        1,    76800, 0x85d7e232
+0,         26,         26,        1,    76800, 0x4059ddb0
+0,         27,         27,        1,    76800, 0x3581cae2
+0,         28,         28,        1,    76800, 0x1885c99e
+0,         29,         29,        1,    76800, 0xc87dcd66
+0,         30,         30,        1,    76800, 0x8645e084
+0,         31,         31,        1,    76800, 0xe17ed6b4
+0,         32,         32,        1,    76800, 0x2709c7b6
+0,         33,         33,        1,    76800, 0xded3ab34
+0,         34,         34,        1,    76800, 0x3e69a364
+0,         35,         35,        1,    76800, 0x90c7ae7e
+0,         36,         36,        1,    76800, 0x7dffba9a
+0,         37,         37,        1,    76800, 0x1311ce7a
+0,         38,         38,        1,    76800, 0x6663e5ce
+0,         39,         39,        1,    76800, 0x597d0173
+0,         40,         40,        1,    76800, 0x936b1ab3
+0,         41,         41,        1,    76800, 0x860f2157
+0,         42,         42,        1,    76800, 0x69cd2ffd
+0,         43,         43,        1,    76800, 0xd0a24429
+0,         44,         44,        1,    76800, 0x6fbd49b3
+0,         45,         45,        1,    76800, 0x6e866211
+0,         46,         46,        1,    76800, 0x8ed9615d
+0,         47,         47,        1,    76800, 0x5ef45ab1
+0,         48,         48,        1,    76800, 0x72174a5d
+0,         49,         49,        1,    76800, 0x9e1346e1
+0,         50,         50,        1,    76800, 0xbe2046ef
+0,         51,         51,        1,    76800, 0x6417511d
+0,         52,         52,        1,    76800, 0xdc7d59d7
+0,         53,         53,        1,    76800, 0xea8f5569
+0,         54,         54,        1,    76800, 0x77b45d67
+0,         55,         55,        1,    76800, 0x949566bf
+0,         56,         56,        1,    76800, 0x644c6e39
+0,         57,         57,        1,    76800, 0xe8e47155
+0,         58,         58,        1,    76800, 0x84eb80d3
+0,         59,         59,        1,    76800, 0x6ade8f99
+0,         60,         60,        1,    76800, 0x1359adf5
+0,         61,         61,        1,    76800, 0x3b8ab849
+0,         62,         62,        1,    76800, 0xb761c9af
+0,         63,         63,        1,    76800, 0x89f0ccf5
+0,         64,         64,        1,    76800, 0xf50dc989
+0,         65,         65,        1,    76800, 0xc9e8c37f
+0,         66,         66,        1,    76800, 0x91b1c6fb
+0,         67,         67,        1,    76800, 0x30accc59
+0,         68,         68,        1,    76800, 0x4dbbd735
+0,         69,         69,        1,    76800, 0x06ece049
+0,         70,         70,        1,    76800, 0x9112ebef
+0,         71,         71,        1,    76800, 0x4b9af209
+0,         72,         72,        1,    76800, 0x1063f2d5
+0,         73,         73,        1,    76800, 0xc00ef0eb
+0,         74,         74,        1,    76800, 0xfc76efa1
+0,         75,         75,        1,    76800, 0xd85cff3b
+0,         76,         76,        1,    76800, 0x2dc9fc19
+0,         77,         77,        1,    76800, 0xe5610674
+0,         78,         78,        1,    76800, 0xdfa5fdb5
+0,         79,         79,        1,    76800, 0xb7eef1d9
+0,         80,         80,        1,    76800, 0x3743ed2b
+0,         81,         81,        1,    76800, 0xaaf6a11d
+0,         82,         82,        1,    76800, 0xbd3dba25
+0,         83,         83,        1,    76800, 0x0d5a84c2
+0,         84,         84,        1,    76800, 0x04d3cede
+0,         85,         85,        1,    76800, 0xd0ed078b
+0,         86,         86,        1,    76800, 0x712c4257
+0,         87,         87,        1,    76800, 0x0866f074
+0,         88,         88,        1,    76800, 0x7bcbd610
+0,         89,         89,        1,    76800, 0xcfb16193
+0,         90,         90,        1,    76800, 0x08b2bf53
+0,         91,         91,        1,    76800, 0x8a89d293
+0,         92,         92,        1,    76800, 0xdceb169e
+0,         93,         93,        1,    76800, 0x91b53522
+0,         94,         94,        1,    76800, 0xc6f36e86
+0,         95,         95,        1,    76800, 0x64849fae
+0,         96,         96,        1,    76800, 0x7f060705
+0,         97,         97,        1,    76800, 0x100c7c79
+0,         98,         98,        1,    76800, 0xe6d3df05
+0,         99,         99,        1,    76800, 0x3947f65d
+0,        100,        100,        1,    76800, 0xfe52d0e1
+0,        101,        101,        1,    76800, 0x5a81b935
+0,        102,        102,        1,    76800, 0x3dabcb31
+0,        103,        103,        1,    76800, 0x0ae6dea9
+0,        104,        104,        1,    76800, 0x214c2dec
+0,        105,        105,        1,    76800, 0xeb526560
+0,        106,        106,        1,    76800, 0xbb618418
+0,        107,        107,        1,    76800, 0x61d9cbd0
+0,        108,        108,        1,    76800, 0x9d2660bb
+0,        109,        109,        1,    76800, 0xf4f5dc33
+0,        110,        110,        1,    76800, 0xe2551ec2
+0,        111,        111,        1,    76800, 0x5f971e3a
+0,        112,        112,        1,    76800, 0xa96c0cea
+0,        113,        113,        1,    76800, 0xd904cdeb
+0,        114,        114,        1,    76800, 0x0443a227
+0,        115,        115,        1,    76800, 0xf3e92457
+0,        116,        116,        1,    76800, 0x2df4d5b0
+0,        117,        117,        1,    76800, 0x72d4b018
+0,        118,        118,        1,    76800, 0x260ac3dc
+0,        119,        119,        1,    76800, 0x30160163
+0,        120,        120,        1,    76800, 0x76c7656f
+0,        121,        121,        1,    76800, 0xdc42bb23
+0,        122,        122,        1,    76800, 0xdbab366a
+0,        123,        123,        1,    76800, 0xf998ae66
+0,        124,        124,        1,    76800, 0x3b6afb62
+0,        125,        125,        1,    76800, 0x3fb3f76e
+0,        126,        126,        1,    76800, 0xc4f4d89a
+0,        127,        127,        1,    76800, 0xf448aa5a
+0,        128,        128,        1,    76800, 0xf9fed3c2
+0,        129,        129,        1,    76800, 0x8e4526bd
+0,        130,        130,        1,    76800, 0xa4be7a39
+0,        131,        131,        1,    76800, 0x07d376b9
+0,        132,        132,        1,    76800, 0x47993f51
+0,        133,        133,        1,    76800, 0x2f5816ad
+0,        134,        134,        1,    76800, 0x0f78187d
+0,        135,        135,        1,    76800, 0x5129e47e
+0,        136,        136,        1,    76800, 0x1050b9e2
+0,        137,        137,        1,    76800, 0x5ba278d2
+0,        138,        138,        1,    76800, 0xc5f5278e
+0,        139,        139,        1,    76800, 0xe406e093
+0,        140,        140,        1,    76800, 0x1b03c34f
+0,        141,        141,        1,    76800, 0xaad8b463
+0,        142,        142,        1,    76800, 0x4f90ad0d
+0,        143,        143,        1,    76800, 0x83a1b8b3
+0,        144,        144,        1,    76800, 0x682ccba1
+0,        145,        145,        1,    76800, 0xf44f0d22
+0,        146,        146,        1,    76800, 0x19c02d14
+0,        147,        147,        1,    76800, 0x01148baa
+0,        148,        148,        1,    76800, 0xff45dfbe
+0,        149,        149,        1,    76800, 0x05f8db6e
+0,        150,        150,        1,    76800, 0x9a129a6e
+0,        151,        151,        1,    76800, 0x93f8749e
+0,        152,        152,        1,    76800, 0x7dd1f89b
+0,        153,        153,        1,    76800, 0x3c81b16f
+0,        154,        154,        1,    76800, 0xefc3e567
+0,        155,        155,        1,    76800, 0x9fe26222
+0,        156,        156,        1,    76800, 0x85018ef4
+0,        157,        157,        1,    76800, 0x0aa984a4
+0,        158,        158,        1,    76800, 0xea45538e
+0,        159,        159,        1,    76800, 0x8e112454
+0,        160,        160,        1,    76800, 0xab76bf13
+0,        161,        161,        1,    76800, 0x9c1e32a1
+0,        162,        162,        1,    76800, 0xedb88ef8
+0,        163,        163,        1,    76800, 0x5371d475
+0,        164,        164,        1,    76800, 0x631a36eb
+0,        165,        165,        1,    76800, 0x6d4403ef
+0,        166,        166,        1,    76800, 0xdd67190b
+0,        167,        167,        1,    76800, 0x41b054a5
+0,        168,        168,        1,    76800, 0x53f55a99
+0,        169,        169,        1,    76800, 0x93182147
+0,        170,        170,        1,    76800, 0xcce0dd8c
+0,        171,        171,        1,    76800, 0x51f68932
+0,        172,        172,        1,    76800, 0x3d5e2f4a
+0,        173,        173,        1,    76800, 0x8baed3b3
+0,        174,        174,        1,    76800, 0xdc66509b
+0,        175,        175,        1,    76800, 0x1b81fb6c
+0,        176,        176,        1,    76800, 0x63e1f954
+0,        177,        177,        1,    76800, 0x75fd36a1
+0,        178,        178,        1,    76800, 0x68f1a18f
+0,        179,        179,        1,    76800, 0x8b0a1c76
+0,        180,        180,        1,    76800, 0x6d7b9810
+0,        181,        181,        1,    76800, 0x5dcdee4a
+0,        182,        182,        1,    76800, 0xf97c2187
+0,        183,        183,        1,    76800, 0x3e575d0d
+0,        184,        184,        1,    76800, 0x4fc6a723
+0,        185,        185,        1,    76800, 0xf5dcde6d
+0,        186,        186,        1,    76800, 0xc42204d2
+0,        187,        187,        1,    76800, 0x12cff747
+0,        188,        188,        1,    76800, 0xa11ae405
+0,        189,        189,        1,    76800, 0x7cd8d07f
+0,        190,        190,        1,    76800, 0xa100a8fb
+0,        191,        191,        1,    76800, 0x7e9e945b
+0,        192,        192,        1,    76800, 0x2ead8009
+0,        193,        193,        1,    76800, 0x755a7399
+0,        194,        194,        1,    76800, 0x25324c65
+0,        195,        195,        1,    76800, 0xe12ad1a4
+0,        196,        196,        1,    76800, 0x02366ec8
+0,        197,        197,        1,    76800, 0x1e8f0d5a
+0,        198,        198,        1,    76800, 0x0235d45b
+0,        199,        199,        1,    76800, 0x26d2b581
+0,        200,        200,        1,    76800, 0x304f1ccb
+0,        201,        201,        1,    76800, 0x4e1625ff
+0,        202,        202,        1,    76800, 0xfecc1f5b
+0,        203,        203,        1,    76800, 0x499714ff
+0,        204,        204,        1,    76800, 0xff240d1b
+0,        205,        205,        1,    76800, 0xc257ebf8
+0,        206,        206,        1,    76800, 0xf752cdfc
+0,        207,        207,        1,    76800, 0xb031b7cc
+0,        208,        208,        1,    76800, 0xb3f29c84
+0,        209,        209,        1,    76800, 0x77f66fd4
+0,        210,        210,        1,    76800, 0x9ef247ec
+0,        211,        211,        1,    76800, 0xdc32180c
+0,        212,        212,        1,    76800, 0x41bed8e5
+0,        213,        213,        1,    76800, 0x931b8b05
+0,        214,        214,        1,    76800, 0xe45b36f9
+0,        215,        215,        1,    76800, 0xc71bd626
+0,        216,        216,        1,    76800, 0x5b637aca
+0,        217,        217,        1,    76800, 0x3e8d1752
+0,        218,        218,        1,    76800, 0x5f9ca28b
+0,        219,        219,        1,    76800, 0x56d937bf
+0,        220,        220,        1,    76800, 0xe811c010
+0,        221,        221,        1,    76800, 0xca414fe8
+0,        222,        222,        1,    76800, 0x774ef141
+0,        223,        223,        1,    76800, 0xa44282f9
+0,        224,        224,        1,    76800, 0x30690641
+0,        225,        225,        1,    76800, 0xa833ad96
+0,        226,        226,        1,    76800, 0xe18d4932
+0,        227,        227,        1,    76800, 0xf934c0af
+0,        228,        228,        1,    76800, 0xdbc361b7
+0,        229,        229,        1,    76800, 0x7e0d0077
+0,        230,        230,        1,    76800, 0x2d3faaa4
+0,        231,        231,        1,    76800, 0xfa1a7708
+0,        232,        232,        1,    76800, 0xb60870a0
+0,        233,        233,        1,    76800, 0x5f5f7682
+0,        234,        234,        1,    76800, 0x47dc7564
+0,        235,        235,        1,    76800, 0x48f984c8
+0,        236,        236,        1,    76800, 0x7b0892a8
+0,        237,        237,        1,    76800, 0x56a0c014
+0,        238,        238,        1,    76800, 0x5dd1d854
+0,        239,        239,        1,    76800, 0xdfb0f698
+0,        240,        240,        1,    76800, 0xda051775
+0,        241,        241,        1,    76800, 0xa19c3eb1
+0,        242,        242,        1,    76800, 0xda74780d
+0,        243,        243,        1,    76800, 0x5dd28f7f
+0,        244,        244,        1,    76800, 0xf23fa74b
+0,        245,        245,        1,    76800, 0x4014c817
+0,        246,        246,        1,    76800, 0x0954ead7
+0,        247,        247,        1,    76800, 0xa8e319fe
+0,        248,        248,        1,    76800, 0x722e3f2c
+0,        249,        249,        1,    76800, 0xbee3702c
+0,        250,        250,        1,    76800, 0x19599172
+0,        251,        251,        1,    76800, 0x61c18ef0
+0,        252,        252,        1,    76800, 0xfb13780e
+0,        253,        253,        1,    76800, 0xd86e6b80
+0,        254,        254,        1,    76800, 0xf5cc6abc
+0,        255,        255,        1,    76800, 0x5fe86912
+0,        256,        256,        1,    76800, 0xba3d6efe
+0,        257,        257,        1,    76800, 0x23927f3e
+0,        258,        258,        1,    76800, 0x6947b124
+0,        259,        259,        1,    76800, 0x80e9f682
+0,        260,        260,        1,    76800, 0x6a393a9b
+0,        261,        261,        1,    76800, 0x5aff928b
+0,        262,        262,        1,    76800, 0xd81dfbab
+0,        263,        263,        1,    76800, 0x950166ca
+0,        264,        264,        1,    76800, 0xc7e6c6f0
+0,        265,        265,        1,    76800, 0x9aa328a1
+0,        266,        266,        1,    76800, 0x17de849b
+0,        267,        267,        1,    76800, 0xc4f7d9e3
+0,        268,        268,        1,    76800, 0x3f372bee
+0,        269,        269,        1,    76800, 0xaffc6e06
+0,        270,        270,        1,    76800, 0x94b8875c
+0,        271,        271,        1,    76800, 0xb713a42a
+0,        272,        272,        1,    76800, 0x8a89c232
+0,        273,        273,        1,    76800, 0xde65db42
+0,        274,        274,        1,    76800, 0x2c7dfaac
+0,        275,        275,        1,    76800, 0xa9202a71
+0,        276,        276,        1,    76800, 0x78715817
+0,        277,        277,        1,    76800, 0x3c0d8bb9
+0,        278,        278,        1,    76800, 0xa4cdbb61
+0,        279,        279,        1,    76800, 0xb9abd6ad
+0,        280,        280,        1,    76800, 0xecef0146
+0,        281,        281,        1,    76800, 0x82f22350
+0,        282,        282,        1,    76800, 0x17f442f2
+0,        283,        283,        1,    76800, 0xa6ea59e4
+0,        284,        284,        1,    76800, 0x62e452e6
+0,        285,        285,        1,    76800, 0xce2c454e
+0,        286,        286,        1,    76800, 0x27a821b4
+0,        287,        287,        1,    76800, 0x899f0f98
+0,        288,        288,        1,    76800, 0xe25dffb7
+0,        289,        289,        1,    76800, 0xa288ff17
+0,        290,        290,        1,    76800, 0x678500b0
+0,        291,        291,        1,    76800, 0xfe9c1216
+0,        292,        292,        1,    76800, 0x56da27a0
+0,        293,        293,        1,    76800, 0x62f239be
+0,        294,        294,        1,    76800, 0xa0a74b90
+0,        295,        295,        1,    76800, 0xc2f969a0
+0,        296,        296,        1,    76800, 0xe1ca7ad4
+0,        297,        297,        1,    76800, 0xf7938a7e
+0,        298,        298,        1,    76800, 0x3a339640
+0,        299,        299,        1,    76800, 0x44b79e0c
+0,        300,        300,        1,    76800, 0xd6e78ee6
+0,        301,        301,        1,    76800, 0xeecd91b6
+0,        302,        302,        1,    76800, 0x3ea99774
+0,        303,        303,        1,    76800, 0xd399967e
+0,        304,        304,        1,    76800, 0xc1e38de6
+0,        305,        305,        1,    76800, 0xd8ec7958
+0,        306,        306,        1,    76800, 0xe9e26992
+0,        307,        307,        1,    76800, 0xb6ee580a
+0,        308,        308,        1,    76800, 0xd56852f4
+0,        309,        309,        1,    76800, 0x997f4b9c
+0,        310,        310,        1,    76800, 0xc62841a6
+0,        311,        311,        1,    76800, 0x58063cee
+0,        312,        312,        1,    76800, 0xbaaf3e16
+0,        313,        313,        1,    76800, 0xac043a50
+0,        314,        314,        1,    76800, 0xa6c73a14
+0,        315,        315,        1,    76800, 0x1d614480
+0,        316,        316,        1,    76800, 0xc4e63b4c
+0,        317,        317,        1,    76800, 0x9d393b06
+0,        318,        318,        1,    76800, 0x9a902ef4
+0,        319,        319,        1,    76800, 0x6f872c74
+0,        320,        320,        1,    76800, 0x288a2f92
+0,        321,        321,        1,    76800, 0xb4832d76
+0,        322,        322,        1,    76800, 0x99e21c30
+0,        323,        323,        1,    76800, 0x287f0c90
+0,        324,        324,        1,    76800, 0xfd8bfe3f
+0,        325,        325,        1,    76800, 0x0a62f1d3
+0,        326,        326,        1,    76800, 0x2928eb4d
+0,        327,        327,        1,    76800, 0x2acfe487
+0,        328,        328,        1,    76800, 0x2b2ce339
+0,        329,        329,        1,    76800, 0x25d2e4c5
+0,        330,        330,        1,    76800, 0x0c14dd95
+0,        331,        331,        1,    76800, 0xfe8fdf29
+0,        332,        332,        1,    76800, 0x3afedd29
+0,        333,        333,        1,    76800, 0x3c85dd05
+0,        334,        334,        1,    76800, 0x9981db4d
+0,        335,        335,        1,    76800, 0xc4f9d501
+0,        336,        336,        1,    76800, 0xccd4d2d5
+0,        337,        337,        1,    76800, 0x229fdc41
+0,        338,        338,        1,    76800, 0x305de4ad
+0,        339,        339,        1,    76800, 0xb40eaef6
+0,        340,        340,        1,    76800, 0xb14f0431
+0,        341,        341,        1,    76800, 0x346b9280
+0,        342,        342,        1,    76800, 0x9198b4c0
+0,        343,        343,        1,    76800, 0xba1fde8f
+0,        344,        344,        1,    76800, 0x45260fa2
+0,        345,        345,        1,    76800, 0x69dd33cb
+0,        346,        346,        1,    76800, 0x6e10c599
+0,        347,        347,        1,    76800, 0x9dd33a40
+0,        348,        348,        1,    76800, 0x9dc7eb47
+0,        349,        349,        1,    76800, 0x8776f7df
+0,        350,        350,        1,    76800, 0xfd674e91
+0,        351,        351,        1,    76800, 0xcd69d151
+0,        352,        352,        1,    76800, 0xa8f69f9e
+0,        353,        353,        1,    76800, 0xf83587a2
+0,        354,        354,        1,    76800, 0xcb656e2a
+0,        355,        355,        1,    76800, 0x8c5e6b82
+0,        356,        356,        1,    76800, 0x880d5f56
+0,        357,        357,        1,    76800, 0x93405cce
+0,        358,        358,        1,    76800, 0x51345c1e
diff --git a/tests/ref/fate/bethsoft-vid b/tests/ref/fate/bethsoft-vid
index a4c049e..535888b 100644
--- a/tests/ref/fate/bethsoft-vid
+++ b/tests/ref/fate/bethsoft-vid
@@ -140,5 +140,4 @@
 1,      53835,      53835,      925,     1850, 0x5a303d1a
 0,        296,        296,        1,   192000, 0x79b7417b
 1,      54760,      54760,      537,     1074, 0x142ce7ba
-1,      55297,      55297,      925,     1850, 0x7ff682f7
-0,        300,        300,        1,   192000, 0x468d8db4
+1,      55297,      55297,      258,      516, 0x98885b26
diff --git a/tests/ref/fate/cdgraphics b/tests/ref/fate/cdgraphics
index 78a8f28..dccb2b5 100644
--- a/tests/ref/fate/cdgraphics
+++ b/tests/ref/fate/cdgraphics
@@ -1,20 +1,20 @@
 #tb 0: 1/300
-0,          0,          0,        1,   194400, 0xd919c635
-0,          1,          1,        1,   194400, 0xd919c635
-0,          2,          2,        1,   194400, 0x516a1007
-0,          3,          3,        1,   194400, 0x516a1007
-0,          4,          4,        1,   194400, 0x516a1007
-0,          5,          5,        1,   194400, 0x516a1007
-0,          6,          6,        1,   194400, 0x516a1007
-0,          7,          7,        1,   194400, 0x516a1007
-0,          8,          8,        1,   194400, 0x516a1007
-0,          9,          9,        1,   194400, 0x516a1007
-0,         10,         10,        1,   194400, 0x516a1007
-0,         11,         11,        1,   194400, 0x516a1007
-0,         12,         12,        1,   194400, 0x516a1007
-0,         13,         13,        1,   194400, 0x516a1007
-0,         14,         14,        1,   194400, 0x516a1007
-0,         15,         15,        1,   194400, 0x516a1007
+0,          0,          0,        1,   194400, 0x46ad80da
+0,          1,          1,        1,   194400, 0x46ad80da
+0,          2,          2,        1,   194400, 0x9392c3b9
+0,          3,          3,        1,   194400, 0x9392c3b9
+0,          4,          4,        1,   194400, 0x9392c3b9
+0,          5,          5,        1,   194400, 0x9392c3b9
+0,          6,          6,        1,   194400, 0x9392c3b9
+0,          7,          7,        1,   194400, 0x9392c3b9
+0,          8,          8,        1,   194400, 0x9392c3b9
+0,          9,          9,        1,   194400, 0x9392c3b9
+0,         10,         10,        1,   194400, 0x9392c3b9
+0,         11,         11,        1,   194400, 0x9392c3b9
+0,         12,         12,        1,   194400, 0x9392c3b9
+0,         13,         13,        1,   194400, 0x9392c3b9
+0,         14,         14,        1,   194400, 0x9392c3b9
+0,         15,         15,        1,   194400, 0x9392c3b9
 0,         16,         16,        1,   194400, 0x46ad80da
 0,         17,         17,        1,   194400, 0x46ad80da
 0,         18,         18,        1,   194400, 0x46ad80da
diff --git a/tests/ref/fate/cllc-yuy2-noblock b/tests/ref/fate/cllc-yuy2-noblock
new file mode 100644
index 0000000..2cb9e78
--- /dev/null
+++ b/tests/ref/fate/cllc-yuy2-noblock
@@ -0,0 +1,16 @@
+#tb 0: 1001/30000
+0,          0,          0,        1,   614400, 0x088c51de
+0,          1,          1,        1,   614400, 0x93fff662
+0,          2,          2,        1,   614400, 0x90ba6c28
+0,          3,          3,        1,   614400, 0x55b7ae46
+0,          4,          4,        1,   614400, 0xef4fc678
+0,          5,          5,        1,   614400, 0xc838a54c
+0,          6,          6,        1,   614400, 0xb6016823
+0,          7,          7,        1,   614400, 0x7fd65ea7
+0,          8,          8,        1,   614400, 0xca9c35b9
+0,          9,          9,        1,   614400, 0x33f902ee
+0,         10,         10,        1,   614400, 0x53f2ea7a
+0,         11,         11,        1,   614400, 0x3ecae1c7
+0,         12,         12,        1,   614400, 0x2d8fd7cc
+0,         13,         13,        1,   614400, 0xd9dfc2ef
+0,         14,         14,        1,   614400, 0xaf95cef0
diff --git a/tests/ref/fate/cyberia-c93 b/tests/ref/fate/cyberia-c93
index 2c71e50..f02435c 100644
--- a/tests/ref/fate/cyberia-c93
+++ b/tests/ref/fate/cyberia-c93
@@ -36,7 +36,7 @@
 0,         30,         30,        1,   184320, 0x54975910
 0,         31,         31,        1,   184320, 0xf4857db9
 0,         32,         32,        1,   184320, 0x82d18161
-1,      42552,      42552,    14184,    28368, 0x9101e519
+1,      42552,      42552,     5835,    11670, 0x04aa0b1e
 0,         33,         33,        1,   184320, 0x06d93bd0
 0,         34,         34,        1,   184320, 0xa4304c00
 0,         35,         35,        1,   184320, 0x5f77d9cd
diff --git a/tests/ref/fate/filter-atrim-duration b/tests/ref/fate/filter-atrim-duration
new file mode 100644
index 0000000..a51dff7
--- /dev/null
+++ b/tests/ref/fate/filter-atrim-duration
@@ -0,0 +1,2 @@
+#tb 0: 1/44100
+0,       4410,       4410,      441,     1764, 0x61e374f7
diff --git a/tests/ref/fate/filter-atrim-mixed b/tests/ref/fate/filter-atrim-mixed
new file mode 100644
index 0000000..ae3281a
--- /dev/null
+++ b/tests/ref/fate/filter-atrim-mixed
@@ -0,0 +1,5 @@
+#tb 0: 1/44100
+0,       1025,       1025,     1023,     4092, 0x78560a4c
+0,       2048,       2048,     1024,     4096, 0xc477fa99
+0,       3072,       3072,     1024,     4096, 0x3bc0f14f
+0,       4096,       4096,      315,     1260, 0xe4b26b50
diff --git a/tests/ref/fate/filter-atrim-samples b/tests/ref/fate/filter-atrim-samples
new file mode 100644
index 0000000..3461666
--- /dev/null
+++ b/tests/ref/fate/filter-atrim-samples
@@ -0,0 +1,2 @@
+#tb 0: 1/44100
+0,         26,         26,       54,      216, 0x6b376c6c
diff --git a/tests/ref/fate/filter-atrim-time b/tests/ref/fate/filter-atrim-time
new file mode 100644
index 0000000..a368210
--- /dev/null
+++ b/tests/ref/fate/filter-atrim-time
@@ -0,0 +1,6 @@
+#tb 0: 1/44100
+0,       4410,       4410,      710,     2840, 0x658982a3
+0,       5120,       5120,     1024,     4096, 0xfd6a0070
+0,       6144,       6144,     1024,     4096, 0x0b01f4cf
+0,       7168,       7168,     1024,     4096, 0x6716fd93
+0,       8192,       8192,      628,     2512, 0xda5ddff8
diff --git a/tests/ref/fate/filter-boxblur b/tests/ref/fate/filter-boxblur
new file mode 100644
index 0000000..acb2beb
--- /dev/null
+++ b/tests/ref/fate/filter-boxblur
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0x113489f8
+0,          1,          1,        1,   152064, 0x650a64ca
+0,          2,          2,        1,   152064, 0x29ecf6b1
+0,          3,          3,        1,   152064, 0x5cb98169
+0,          4,          4,        1,   152064, 0x4f46b6d7
+0,          5,          5,        1,   152064, 0x793ba919
+0,          6,          6,        1,   152064, 0x6caf7c14
+0,          7,          7,        1,   152064, 0xca638b2e
+0,          8,          8,        1,   152064, 0xf6df803d
+0,          9,          9,        1,   152064, 0x907b386f
+0,         10,         10,        1,   152064, 0xbb8d47f9
+0,         11,         11,        1,   152064, 0x17befd28
+0,         12,         12,        1,   152064, 0xf29eae1e
+0,         13,         13,        1,   152064, 0xb08ba1e6
+0,         14,         14,        1,   152064, 0x39948df7
+0,         15,         15,        1,   152064, 0x841d0e7e
+0,         16,         16,        1,   152064, 0x21d64dd6
+0,         17,         17,        1,   152064, 0x18af38e9
+0,         18,         18,        1,   152064, 0x1f946a26
+0,         19,         19,        1,   152064, 0x0d9cdc4e
+0,         20,         20,        1,   152064, 0xaf2af54d
+0,         21,         21,        1,   152064, 0x09e724e1
+0,         22,         22,        1,   152064, 0xff7d1e4b
+0,         23,         23,        1,   152064, 0xd49d68ad
+0,         24,         24,        1,   152064, 0x7ea4f96b
+0,         25,         25,        1,   152064, 0xd2f698b9
+0,         26,         26,        1,   152064, 0xc2a696ac
+0,         27,         27,        1,   152064, 0x1e8ed7b4
+0,         28,         28,        1,   152064, 0x980ba498
+0,         29,         29,        1,   152064, 0x47c364f2
+0,         30,         30,        1,   152064, 0x1a196ada
+0,         31,         31,        1,   152064, 0x4847c564
+0,         32,         32,        1,   152064, 0xa959fc15
+0,         33,         33,        1,   152064, 0x7d1a79d3
+0,         34,         34,        1,   152064, 0xae7e438d
+0,         35,         35,        1,   152064, 0xc32794b4
+0,         36,         36,        1,   152064, 0x6ef43744
+0,         37,         37,        1,   152064, 0xa06a01d0
+0,         38,         38,        1,   152064, 0xc94b5847
+0,         39,         39,        1,   152064, 0xb7514f04
+0,         40,         40,        1,   152064, 0xf0c959e8
+0,         41,         41,        1,   152064, 0xe6439e5e
+0,         42,         42,        1,   152064, 0xd347bf8d
+0,         43,         43,        1,   152064, 0x40822107
+0,         44,         44,        1,   152064, 0xe0ad044a
+0,         45,         45,        1,   152064, 0x05f77e73
+0,         46,         46,        1,   152064, 0xbeaa536d
+0,         47,         47,        1,   152064, 0xb0edc576
+0,         48,         48,        1,   152064, 0x35fcb4fa
+0,         49,         49,        1,   152064, 0x8d9ad8fa
diff --git a/tests/ref/lavfi/crop b/tests/ref/fate/filter-crop
similarity index 100%
rename from tests/ref/lavfi/crop
rename to tests/ref/fate/filter-crop
diff --git a/tests/ref/lavfi/crop_scale b/tests/ref/fate/filter-crop_scale
similarity index 100%
rename from tests/ref/lavfi/crop_scale
rename to tests/ref/fate/filter-crop_scale
diff --git a/tests/ref/lavfi/crop_scale_vflip b/tests/ref/fate/filter-crop_scale_vflip
similarity index 100%
rename from tests/ref/lavfi/crop_scale_vflip
rename to tests/ref/fate/filter-crop_scale_vflip
diff --git a/tests/ref/lavfi/crop_vflip b/tests/ref/fate/filter-crop_vflip
similarity index 100%
rename from tests/ref/lavfi/crop_vflip
rename to tests/ref/fate/filter-crop_vflip
diff --git a/tests/ref/fate/filter-drawbox b/tests/ref/fate/filter-drawbox
new file mode 100644
index 0000000..869b9f3
--- /dev/null
+++ b/tests/ref/fate/filter-drawbox
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0x7eee5ca3
+0,          1,          1,        1,   152064, 0x61125759
+0,          2,          2,        1,   152064, 0x2a64f47f
+0,          3,          3,        1,   152064, 0xc1089594
+0,          4,          4,        1,   152064, 0xd9e18830
+0,          5,          5,        1,   152064, 0xeb135e03
+0,          6,          6,        1,   152064, 0x6a5b40d7
+0,          7,          7,        1,   152064, 0x0a356a16
+0,          8,          8,        1,   152064, 0xfc1d7858
+0,          9,          9,        1,   152064, 0xa04bfeb8
+0,         10,         10,        1,   152064, 0x2d952ef0
+0,         11,         11,        1,   152064, 0x7f360233
+0,         12,         12,        1,   152064, 0xdd2bd142
+0,         13,         13,        1,   152064, 0xd231ad4a
+0,         14,         14,        1,   152064, 0x0543400e
+0,         15,         15,        1,   152064, 0x8252be2b
+0,         16,         16,        1,   152064, 0xd9f702be
+0,         17,         17,        1,   152064, 0xed5cf787
+0,         18,         18,        1,   152064, 0xf9472f8e
+0,         19,         19,        1,   152064, 0x89e4a60b
+0,         20,         20,        1,   152064, 0x1f12c1f5
+0,         21,         21,        1,   152064, 0x76eaf390
+0,         22,         22,        1,   152064, 0x60b5eba3
+0,         23,         23,        1,   152064, 0xf09e348c
+0,         24,         24,        1,   152064, 0x1afabf8a
+0,         25,         25,        1,   152064, 0xd16c558e
+0,         26,         26,        1,   152064, 0x78634796
+0,         27,         27,        1,   152064, 0xcd13b1e3
+0,         28,         28,        1,   152064, 0x59c2c6e5
+0,         29,         29,        1,   152064, 0x265e6beb
+0,         30,         30,        1,   152064, 0x82c656af
+0,         31,         31,        1,   152064, 0x919e923c
+0,         32,         32,        1,   152064, 0xc428fc15
+0,         33,         33,        1,   152064, 0x488760cd
+0,         34,         34,        1,   152064, 0x0a080c93
+0,         35,         35,        1,   152064, 0xaab649e6
+0,         36,         36,        1,   152064, 0x9b34edaa
+0,         37,         37,        1,   152064, 0x44e12816
+0,         38,         38,        1,   152064, 0x03777927
+0,         39,         39,        1,   152064, 0x6644573e
+0,         40,         40,        1,   152064, 0x18574df7
+0,         41,         41,        1,   152064, 0x5dce82f6
+0,         42,         42,        1,   152064, 0xb8be9205
+0,         43,         43,        1,   152064, 0xb927eacb
+0,         44,         44,        1,   152064, 0x303ec874
+0,         45,         45,        1,   152064, 0x05eb3c6f
+0,         46,         46,        1,   152064, 0x74a614d6
+0,         47,         47,        1,   152064, 0x6d078969
+0,         48,         48,        1,   152064, 0xe57a7ae0
+0,         49,         49,        1,   152064, 0xd6fca9ec
diff --git a/tests/ref/fate/filter-fade b/tests/ref/fate/filter-fade
new file mode 100644
index 0000000..131b614
--- /dev/null
+++ b/tests/ref/fate/filter-fade
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0xeb8105cd
+0,          1,          1,        1,   152064, 0x0bc0a27d
+0,          2,          2,        1,   152064, 0x9dcd3a04
+0,          3,          3,        1,   152064, 0xecd9e8ec
+0,          4,          4,        1,   152064, 0xdcc09bca
+0,          5,          5,        1,   152064, 0xbf1537ad
+0,          6,          6,        1,   152064, 0xf32214db
+0,          7,          7,        1,   152064, 0x9584ce5e
+0,          8,          8,        1,   152064, 0xbaa930e7
+0,          9,          9,        1,   152064, 0xce411a6c
+0,         10,         10,        1,   152064, 0xdbc2c004
+0,         11,         11,        1,   152064, 0x635a55df
+0,         12,         12,        1,   152064, 0x49d5807f
+0,         13,         13,        1,   152064, 0xd18734a6
+0,         14,         14,        1,   152064, 0xf9d3581f
+0,         15,         15,        1,   152064, 0x423dbdf7
+0,         16,         16,        1,   152064, 0x0c52a4a2
+0,         17,         17,        1,   152064, 0xf7a6a90e
+0,         18,         18,        1,   152064, 0x472441c2
+0,         19,         19,        1,   152064, 0x9470c09a
+0,         20,         20,        1,   152064, 0xce7da1a3
+0,         21,         21,        1,   152064, 0xdb01a0c9
+0,         22,         22,        1,   152064, 0x052e74cb
+0,         23,         23,        1,   152064, 0xab0eab85
+0,         24,         24,        1,   152064, 0x069c1d15
+0,         25,         25,        1,   152064, 0x95579936
+0,         26,         26,        1,   152064, 0x292dc6d4
+0,         27,         27,        1,   152064, 0x951d382d
+0,         28,         28,        1,   152064, 0x9ce23e7d
+0,         29,         29,        1,   152064, 0x5ceb17dd
+0,         30,         30,        1,   152064, 0xe0835003
+0,         31,         31,        1,   152064, 0x7b8a03ba
+0,         32,         32,        1,   152064, 0x1531b18c
+0,         33,         33,        1,   152064, 0xa4a2ee9a
+0,         34,         34,        1,   152064, 0xa5b0e442
+0,         35,         35,        1,   152064, 0x47e0554d
+0,         36,         36,        1,   152064, 0x9443792e
+0,         37,         37,        1,   152064, 0x1a3316ce
+0,         38,         38,        1,   152064, 0xbe8088d7
+0,         39,         39,        1,   152064, 0xd3013824
+0,         40,         40,        1,   152064, 0x342f2f5d
+0,         41,         41,        1,   152064, 0x638a816f
+0,         42,         42,        1,   152064, 0x0cf11a0f
+0,         43,         43,        1,   152064, 0xc4d87159
+0,         44,         44,        1,   152064, 0xa5c36b72
+0,         45,         45,        1,   152064, 0x17a9970d
+0,         46,         46,        1,   152064, 0x5479e51c
+0,         47,         47,        1,   152064, 0x2ae4382a
+0,         48,         48,        1,   152064, 0xab7097a6
+0,         49,         49,        1,   152064, 0xbc97d4bb
diff --git a/tests/ref/fate/filter-fieldorder b/tests/ref/fate/filter-fieldorder
new file mode 100644
index 0000000..6bb647a
--- /dev/null
+++ b/tests/ref/fate/filter-fieldorder
@@ -0,0 +1,26 @@
+#tb 0: 2/25
+0,          0,          0,        1,   202752, 0x789424b6
+0,          1,          1,        1,   202752, 0x7a1f47a9
+0,          2,          2,        1,   202752, 0xa55a9aba
+0,          3,          3,        1,   202752, 0x71aa394c
+0,          4,          4,        1,   202752, 0xa5d9d0a7
+0,          5,          5,        1,   202752, 0x192d92ff
+0,          6,          6,        1,   202752, 0xa66d9bdd
+0,          7,          7,        1,   202752, 0x29a256bf
+0,          8,          8,        1,   202752, 0x75910eed
+0,          9,          9,        1,   202752, 0x99de19d7
+0,         10,         10,        1,   202752, 0x3a5a16e4
+0,         11,         11,        1,   202752, 0x262ce461
+0,         12,         12,        1,   202752, 0x08da338f
+0,         13,         13,        1,   202752, 0xfb515dbe
+0,         14,         14,        1,   202752, 0x984a8697
+0,         15,         15,        1,   202752, 0xbbd58420
+0,         16,         16,        1,   202752, 0xdd7e560b
+0,         17,         17,        1,   202752, 0x49b94d23
+0,         18,         18,        1,   202752, 0xb679bec7
+0,         19,         19,        1,   202752, 0xe6cffad0
+0,         20,         20,        1,   202752, 0x29a65535
+0,         21,         21,        1,   202752, 0x32851117
+0,         22,         22,        1,   202752, 0x35feb7d1
+0,         23,         23,        1,   202752, 0x96ad33b0
+0,         24,         24,        1,   202752, 0x7ec60b7d
diff --git a/tests/ref/fate/filter-gradfun b/tests/ref/fate/filter-gradfun
new file mode 100644
index 0000000..794fae9
--- /dev/null
+++ b/tests/ref/fate/filter-gradfun
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0xaebf898f
+0,          1,          1,        1,   152064, 0x217b6560
+0,          2,          2,        1,   152064, 0x0269f62d
+0,          3,          3,        1,   152064, 0x12168087
+0,          4,          4,        1,   152064, 0x42f9b5fb
+0,          5,          5,        1,   152064, 0xa653a8b3
+0,          6,          6,        1,   152064, 0x2e317bc3
+0,          7,          7,        1,   152064, 0xf3c28b63
+0,          8,          8,        1,   152064, 0x12e57fce
+0,          9,          9,        1,   152064, 0xeac238dd
+0,         10,         10,        1,   152064, 0x8fe74772
+0,         11,         11,        1,   152064, 0x982afc9c
+0,         12,         12,        1,   152064, 0xd82ead51
+0,         13,         13,        1,   152064, 0xf83ca211
+0,         14,         14,        1,   152064, 0xc01f8de2
+0,         15,         15,        1,   152064, 0x7ec60ec6
+0,         16,         16,        1,   152064, 0x1beb4dd3
+0,         17,         17,        1,   152064, 0x5a513899
+0,         18,         18,        1,   152064, 0x8c766a7b
+0,         19,         19,        1,   152064, 0x8bcddbb0
+0,         20,         20,        1,   152064, 0x01f6f558
+0,         21,         21,        1,   152064, 0xac7e240f
+0,         22,         22,        1,   152064, 0xe8811d38
+0,         23,         23,        1,   152064, 0x4ea268c9
+0,         24,         24,        1,   152064, 0xadc5f950
+0,         25,         25,        1,   152064, 0xdbf498fb
+0,         26,         26,        1,   152064, 0x1b999678
+0,         27,         27,        1,   152064, 0x085dd810
+0,         28,         28,        1,   152064, 0x4665a44f
+0,         29,         29,        1,   152064, 0x674764cf
+0,         30,         30,        1,   152064, 0x65e96a72
+0,         31,         31,        1,   152064, 0x44e0c539
+0,         32,         32,        1,   152064, 0xb124fc9e
+0,         33,         33,        1,   152064, 0x5cff79e3
+0,         34,         34,        1,   152064, 0x7dd94359
+0,         35,         35,        1,   152064, 0x3ec294b6
+0,         36,         36,        1,   152064, 0x675d3767
+0,         37,         37,        1,   152064, 0x9efa01cb
+0,         38,         38,        1,   152064, 0x321058d2
+0,         39,         39,        1,   152064, 0xe0d04e9c
+0,         40,         40,        1,   152064, 0xa4dd58d4
+0,         41,         41,        1,   152064, 0x4cc19dc5
+0,         42,         42,        1,   152064, 0x30a1bf77
+0,         43,         43,        1,   152064, 0x2c9d20f2
+0,         44,         44,        1,   152064, 0x55cb0447
+0,         45,         45,        1,   152064, 0x4daa7e4f
+0,         46,         46,        1,   152064, 0x2a4f53c7
+0,         47,         47,        1,   152064, 0x9fb8c583
+0,         48,         48,        1,   152064, 0x072eb401
+0,         49,         49,        1,   152064, 0xa203d8b7
diff --git a/tests/ref/fate/filter-hqdn3d b/tests/ref/fate/filter-hqdn3d
new file mode 100644
index 0000000..6f121c3
--- /dev/null
+++ b/tests/ref/fate/filter-hqdn3d
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0x0c09883a
+0,          1,          1,        1,   152064, 0xfc2748a0
+0,          2,          2,        1,   152064, 0xb746eea8
+0,          3,          3,        1,   152064, 0xf14192d7
+0,          4,          4,        1,   152064, 0xae26db7f
+0,          5,          5,        1,   152064, 0xe1a7da48
+0,          6,          6,        1,   152064, 0x5196b387
+0,          7,          7,        1,   152064, 0x20eac7ff
+0,          8,          8,        1,   152064, 0x4896c7f5
+0,          9,          9,        1,   152064, 0x97ba6468
+0,         10,         10,        1,   152064, 0x29b19884
+0,         11,         11,        1,   152064, 0x591e4e14
+0,         12,         12,        1,   152064, 0xb692fc98
+0,         13,         13,        1,   152064, 0x3457ed57
+0,         14,         14,        1,   152064, 0xbb10d71d
+0,         15,         15,        1,   152064, 0x47f45b57
+0,         16,         16,        1,   152064, 0xddbd8bc6
+0,         17,         17,        1,   152064, 0x1ef36e02
+0,         18,         18,        1,   152064, 0x55a363d2
+0,         19,         19,        1,   152064, 0x11c1c2f4
+0,         20,         20,        1,   152064, 0x553bdc2b
+0,         21,         21,        1,   152064, 0x2101d886
+0,         22,         22,        1,   152064, 0xe8f77998
+0,         23,         23,        1,   152064, 0x39bac7ff
+0,         24,         24,        1,   152064, 0x09a4172e
+0,         25,         25,        1,   152064, 0x6121f57f
+0,         26,         26,        1,   152064, 0x60e7525c
+0,         27,         27,        1,   152064, 0xd7895259
+0,         28,         28,        1,   152064, 0x12b2153b
+0,         29,         29,        1,   152064, 0x6119a22e
+0,         30,         30,        1,   152064, 0xf1969bd5
+0,         31,         31,        1,   152064, 0x7b03fc83
+0,         32,         32,        1,   152064, 0x17383667
+0,         33,         33,        1,   152064, 0x332bbfba
+0,         34,         34,        1,   152064, 0x253998a8
+0,         35,         35,        1,   152064, 0x2614c984
+0,         36,         36,        1,   152064, 0x50c86e8d
+0,         37,         37,        1,   152064, 0x9ff23b55
+0,         38,         38,        1,   152064, 0xc4589665
+0,         39,         39,        1,   152064, 0x5e7d86c7
+0,         40,         40,        1,   152064, 0xdda07f2f
+0,         41,         41,        1,   152064, 0xa1dacf4a
+0,         42,         42,        1,   152064, 0x3c83fb32
+0,         43,         43,        1,   152064, 0xa43da916
+0,         44,         44,        1,   152064, 0x0e767b80
+0,         45,         45,        1,   152064, 0xa18c5f82
+0,         46,         46,        1,   152064, 0xdb21c249
+0,         47,         47,        1,   152064, 0xb126341e
+0,         48,         48,        1,   152064, 0xc14742be
+0,         49,         49,        1,   152064, 0x582f631d
diff --git a/tests/ref/fate/filter-interlace b/tests/ref/fate/filter-interlace
new file mode 100644
index 0000000..4659942
--- /dev/null
+++ b/tests/ref/fate/filter-interlace
@@ -0,0 +1,26 @@
+#tb 0: 2/25
+0,          0,          0,        1,   152064, 0x6077db38
+0,          1,          1,        1,   152064, 0x3d4f1b15
+0,          2,          2,        1,   152064, 0x447594f6
+0,          3,          3,        1,   152064, 0xb6258a38
+0,          4,          4,        1,   152064, 0x296abb09
+0,          5,          5,        1,   152064, 0x0fad069d
+0,          6,          6,        1,   152064, 0x92c78c0d
+0,          7,          7,        1,   152064, 0x645531fd
+0,          8,          8,        1,   152064, 0xe7652880
+0,          9,          9,        1,   152064, 0x496e1151
+0,         10,         10,        1,   152064, 0x7f7cfb06
+0,         11,         11,        1,   152064, 0x45e9affe
+0,         12,         12,        1,   152064, 0xaedb2d3a
+0,         13,         13,        1,   152064, 0x03fd9ae6
+0,         14,         14,        1,   152064, 0x2084e84d
+0,         15,         15,        1,   152064, 0xcf05faf6
+0,         16,         16,        1,   152064, 0x84c746c2
+0,         17,         17,        1,   152064, 0x898a6321
+0,         18,         18,        1,   152064, 0xe12b7fe9
+0,         19,         19,        1,   152064, 0x12feb756
+0,         20,         20,        1,   152064, 0xd813601a
+0,         21,         21,        1,   152064, 0xc0f3d385
+0,         22,         22,        1,   152064, 0xfca3a63f
+0,         23,         23,        1,   152064, 0xa0796f44
+0,         24,         24,        1,   152064, 0x1d26af11
diff --git a/tests/ref/fate/filter-negate b/tests/ref/fate/filter-negate
new file mode 100644
index 0000000..1d2ea73
--- /dev/null
+++ b/tests/ref/fate/filter-negate
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0xef20e1ec
+0,          1,          1,        1,   152064, 0x899606ec
+0,          2,          2,        1,   152064, 0xaea175d2
+0,          3,          3,        1,   152064, 0x5201eb55
+0,          4,          4,        1,   152064, 0xf02bb525
+0,          5,          5,        1,   152064, 0x99fdc305
+0,          6,          6,        1,   152064, 0x3a8fefe7
+0,          7,          7,        1,   152064, 0x005edfbf
+0,          8,          8,        1,   152064, 0xe37aea50
+0,          9,          9,        1,   152064, 0xa5ad32f9
+0,         10,         10,        1,   152064, 0xb1e52485
+0,         11,         11,        1,   152064, 0x55b06e56
+0,         12,         12,        1,   152064, 0xdfb7be97
+0,         13,         13,        1,   152064, 0x191bca13
+0,         14,         14,        1,   152064, 0xa554dd3c
+0,         15,         15,        1,   152064, 0x36075b77
+0,         16,         16,        1,   152064, 0xbf6b1cbd
+0,         17,         17,        1,   152064, 0xf33432b6
+0,         18,         18,        1,   152064, 0x5d7100c3
+0,         19,         19,        1,   152064, 0x376f8f0c
+0,         20,         20,        1,   152064, 0x07ca75fa
+0,         21,         21,        1,   152064, 0xe3984704
+0,         22,         22,        1,   152064, 0xa8fb4e4c
+0,         23,         23,        1,   152064, 0xe8e102d8
+0,         24,         24,        1,   152064, 0xcc6771c9
+0,         25,         25,        1,   152064, 0xf646d238
+0,         26,         26,        1,   152064, 0xa52cd41e
+0,         27,         27,        1,   152064, 0x536d92c2
+0,         28,         28,        1,   152064, 0x7058c6a1
+0,         29,         29,        1,   152064, 0xcc6c05d0
+0,         30,         30,        1,   152064, 0x1fc2ffb8
+0,         31,         31,        1,   152064, 0x041ea59c
+0,         32,         32,        1,   152064, 0xfc006e07
+0,         33,         33,        1,   152064, 0x0246efe1
+0,         34,         34,        1,   152064, 0x079428e5
+0,         35,         35,        1,   152064, 0x64d9d773
+0,         36,         36,        1,   152064, 0x914d3454
+0,         37,         37,        1,   152064, 0xef69686e
+0,         38,         38,        1,   152064, 0x3c91129f
+0,         39,         39,        1,   152064, 0x2a611ca7
+0,         40,         40,        1,   152064, 0xaf56124f
+0,         41,         41,        1,   152064, 0xce48cd45
+0,         42,         42,        1,   152064, 0x75feac29
+0,         43,         43,        1,   152064, 0xfd2b4b5b
+0,         44,         44,        1,   152064, 0x8d2f675c
+0,         45,         45,        1,   152064, 0x1573ed3b
+0,         46,         46,        1,   152064, 0xb0fc17ca
+0,         47,         47,        1,   152064, 0x53e5a654
+0,         48,         48,        1,   152064, 0xe0cbb786
+0,         49,         49,        1,   152064, 0xcaa092fe
diff --git a/tests/ref/lavfi/null b/tests/ref/fate/filter-null
similarity index 100%
rename from tests/ref/lavfi/null
rename to tests/ref/fate/filter-null
diff --git a/tests/ref/fate/filter-overlay b/tests/ref/fate/filter-overlay
new file mode 100644
index 0000000..d988a2e
--- /dev/null
+++ b/tests/ref/fate/filter-overlay
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0xf6f773b6
+0,          1,          1,        1,   152064, 0x8e67618e
+0,          2,          2,        1,   152064, 0xc8eff2ef
+0,          3,          3,        1,   152064, 0xcf39936c
+0,          4,          4,        1,   152064, 0xaf18c4d1
+0,          5,          5,        1,   152064, 0x7e69911e
+0,          6,          6,        1,   152064, 0x1b70214f
+0,          7,          7,        1,   152064, 0xc8032176
+0,          8,          8,        1,   152064, 0xefb42ecc
+0,          9,          9,        1,   152064, 0xfb210e4b
+0,         10,         10,        1,   152064, 0x2ee24b11
+0,         11,         11,        1,   152064, 0x0dac02a5
+0,         12,         12,        1,   152064, 0x9a5ce483
+0,         13,         13,        1,   152064, 0x6bb7c758
+0,         14,         14,        1,   152064, 0xcbb545e5
+0,         15,         15,        1,   152064, 0x81c1b339
+0,         16,         16,        1,   152064, 0xfa38d624
+0,         17,         17,        1,   152064, 0x56c5e63e
+0,         18,         18,        1,   152064, 0x419d194d
+0,         19,         19,        1,   152064, 0xed1a92b8
+0,         20,         20,        1,   152064, 0xd2c0aa39
+0,         21,         21,        1,   152064, 0x6214ddd5
+0,         22,         22,        1,   152064, 0xa978e19f
+0,         23,         23,        1,   152064, 0x676422a2
+0,         24,         24,        1,   152064, 0x5213dd62
+0,         25,         25,        1,   152064, 0x13c1a404
+0,         26,         26,        1,   152064, 0xa543a1a2
+0,         27,         27,        1,   152064, 0x8d0d0bed
+0,         28,         28,        1,   152064, 0x000304cf
+0,         29,         29,        1,   152064, 0x7f75b0ab
+0,         30,         30,        1,   152064, 0x68d07ce6
+0,         31,         31,        1,   152064, 0xb88c9852
+0,         32,         32,        1,   152064, 0x4be5ae13
+0,         33,         33,        1,   152064, 0x85b3f7b1
+0,         34,         34,        1,   152064, 0x9facb7d5
+0,         35,         35,        1,   152064, 0x9f11617e
+0,         36,         36,        1,   152064, 0x43393f46
+0,         37,         37,        1,   152064, 0xd45c3b92
+0,         38,         38,        1,   152064, 0x53de7e1b
+0,         39,         39,        1,   152064, 0xd1c685a7
+0,         40,         40,        1,   152064, 0x21e1778f
+0,         41,         41,        1,   152064, 0xe2b1abe1
+0,         42,         42,        1,   152064, 0x8623b5aa
+0,         43,         43,        1,   152064, 0xfc700aa3
+0,         44,         44,        1,   152064, 0x30a2d120
+0,         45,         45,        1,   152064, 0xa35e4d15
+0,         46,         46,        1,   152064, 0xa3fb11c5
+0,         47,         47,        1,   152064, 0x034f8fb7
+0,         48,         48,        1,   152064, 0x921c7d85
+0,         49,         49,        1,   152064, 0x7a94b9bf
diff --git a/tests/ref/fate/filter-pixdesc b/tests/ref/fate/filter-pixdesc
new file mode 100644
index 0000000..23452ae
--- /dev/null
+++ b/tests/ref/fate/filter-pixdesc
@@ -0,0 +1,89 @@
+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
+gbrp                76204621e200a3cc633012f6720c7005
+gbrp10be            2ca4a4a589a7dc461ff186913c7a69e5
+gbrp10le            46176f1fcc6e67f9862115fe373f73d3
+gbrp9be             981c2c1b0ef1791824b4c7518331bc2e
+gbrp9le             25fb915ed11d07d631e0e7b78d54bebf
+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
+yuva420p10be        145366ff1632de3e300d947f49844284
+yuva420p10le        d797038552d7f698e4d1db4dfa18ceb0
+yuva420p16be        25a335f66a0670911ced818aa42fb670
+yuva420p16le        97bf252e6c030f0f0412d3826c2ea259
+yuva420p9be         06b764d85bd3c22e9b7ca4babed84d4f
+yuva420p9le         1f01cdd4fc46f98d4c11b2947307a0e3
+yuva422p            92b6815f465297284cdb843711682cee
+yuva422p10be        fb240ff9ac49b45b1b3d40df2c89e39d
+yuva422p10le        f767ede9ba1d427faadc963cf41d2412
+yuva422p16be        ef442b11b26e5e61f3c958fa309576dd
+yuva422p16le        5789009759d7a44dacc6da2194e402b1
+yuva422p9be         e0d2f45f7f5541eee988137c7ebb3495
+yuva422p9le         a4ec81f328efd3856dec430fb27f2f56
+yuva444p            c523716e4900cfe515eaab1d7124fdd9
+yuva444p10be        f5791a75fdb86da0c243511ef9ab8fbd
+yuva444p10le        578e88dfbe4ab07f280fcc7554f3a5c4
+yuva444p16be        ee7b9dd854e36b165d5b7cffb646ba6c
+yuva444p16le        ec93b2907923d5655e9fb085479260ef
+yuva444p9be         03414257d78e72c28d03e3c247319b7c
+yuva444p9le         e421d753257e36a79c2c0ec1607ac9e6
+yuvj420p            32eec78ba51857b16ce9b813a49b7189
+yuvj422p            0dfa0ed434f73be51428758c69e082cb
+yuvj440p            657501a28004e27a592757a7509f5189
+yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
+yuyv422             f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy
new file mode 100644
index 0000000..23452ae
--- /dev/null
+++ b/tests/ref/fate/filter-pixfmts-copy
@@ -0,0 +1,89 @@
+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
+gbrp                76204621e200a3cc633012f6720c7005
+gbrp10be            2ca4a4a589a7dc461ff186913c7a69e5
+gbrp10le            46176f1fcc6e67f9862115fe373f73d3
+gbrp9be             981c2c1b0ef1791824b4c7518331bc2e
+gbrp9le             25fb915ed11d07d631e0e7b78d54bebf
+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
+yuva420p10be        145366ff1632de3e300d947f49844284
+yuva420p10le        d797038552d7f698e4d1db4dfa18ceb0
+yuva420p16be        25a335f66a0670911ced818aa42fb670
+yuva420p16le        97bf252e6c030f0f0412d3826c2ea259
+yuva420p9be         06b764d85bd3c22e9b7ca4babed84d4f
+yuva420p9le         1f01cdd4fc46f98d4c11b2947307a0e3
+yuva422p            92b6815f465297284cdb843711682cee
+yuva422p10be        fb240ff9ac49b45b1b3d40df2c89e39d
+yuva422p10le        f767ede9ba1d427faadc963cf41d2412
+yuva422p16be        ef442b11b26e5e61f3c958fa309576dd
+yuva422p16le        5789009759d7a44dacc6da2194e402b1
+yuva422p9be         e0d2f45f7f5541eee988137c7ebb3495
+yuva422p9le         a4ec81f328efd3856dec430fb27f2f56
+yuva444p            c523716e4900cfe515eaab1d7124fdd9
+yuva444p10be        f5791a75fdb86da0c243511ef9ab8fbd
+yuva444p10le        578e88dfbe4ab07f280fcc7554f3a5c4
+yuva444p16be        ee7b9dd854e36b165d5b7cffb646ba6c
+yuva444p16le        ec93b2907923d5655e9fb085479260ef
+yuva444p9be         03414257d78e72c28d03e3c247319b7c
+yuva444p9le         e421d753257e36a79c2c0ec1607ac9e6
+yuvj420p            32eec78ba51857b16ce9b813a49b7189
+yuvj422p            0dfa0ed434f73be51428758c69e082cb
+yuvj440p            657501a28004e27a592757a7509f5189
+yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
+yuyv422             f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_crop b/tests/ref/fate/filter-pixfmts-crop
similarity index 100%
rename from tests/ref/lavfi/pixfmts_crop
rename to tests/ref/fate/filter-pixfmts-crop
diff --git a/tests/ref/lavfi/pixfmts_hflip b/tests/ref/fate/filter-pixfmts-hflip
similarity index 100%
rename from tests/ref/lavfi/pixfmts_hflip
rename to tests/ref/fate/filter-pixfmts-hflip
diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null
new file mode 100644
index 0000000..23452ae
--- /dev/null
+++ b/tests/ref/fate/filter-pixfmts-null
@@ -0,0 +1,89 @@
+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
+gbrp                76204621e200a3cc633012f6720c7005
+gbrp10be            2ca4a4a589a7dc461ff186913c7a69e5
+gbrp10le            46176f1fcc6e67f9862115fe373f73d3
+gbrp9be             981c2c1b0ef1791824b4c7518331bc2e
+gbrp9le             25fb915ed11d07d631e0e7b78d54bebf
+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
+yuva420p10be        145366ff1632de3e300d947f49844284
+yuva420p10le        d797038552d7f698e4d1db4dfa18ceb0
+yuva420p16be        25a335f66a0670911ced818aa42fb670
+yuva420p16le        97bf252e6c030f0f0412d3826c2ea259
+yuva420p9be         06b764d85bd3c22e9b7ca4babed84d4f
+yuva420p9le         1f01cdd4fc46f98d4c11b2947307a0e3
+yuva422p            92b6815f465297284cdb843711682cee
+yuva422p10be        fb240ff9ac49b45b1b3d40df2c89e39d
+yuva422p10le        f767ede9ba1d427faadc963cf41d2412
+yuva422p16be        ef442b11b26e5e61f3c958fa309576dd
+yuva422p16le        5789009759d7a44dacc6da2194e402b1
+yuva422p9be         e0d2f45f7f5541eee988137c7ebb3495
+yuva422p9le         a4ec81f328efd3856dec430fb27f2f56
+yuva444p            c523716e4900cfe515eaab1d7124fdd9
+yuva444p10be        f5791a75fdb86da0c243511ef9ab8fbd
+yuva444p10le        578e88dfbe4ab07f280fcc7554f3a5c4
+yuva444p16be        ee7b9dd854e36b165d5b7cffb646ba6c
+yuva444p16le        ec93b2907923d5655e9fb085479260ef
+yuva444p9be         03414257d78e72c28d03e3c247319b7c
+yuva444p9le         e421d753257e36a79c2c0ec1607ac9e6
+yuvj420p            32eec78ba51857b16ce9b813a49b7189
+yuvj422p            0dfa0ed434f73be51428758c69e082cb
+yuvj440p            657501a28004e27a592757a7509f5189
+yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
+yuyv422             f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_pad b/tests/ref/fate/filter-pixfmts-pad
similarity index 100%
rename from tests/ref/lavfi/pixfmts_pad
rename to tests/ref/fate/filter-pixfmts-pad
diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale
new file mode 100644
index 0000000..80816ec
--- /dev/null
+++ b/tests/ref/fate/filter-pixfmts-scale
@@ -0,0 +1,89 @@
+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
+gbrp                205c50f8359cb4ba2827a7711dea2cc6
+gbrp10be            30b7f9d5ef5da474fb794743146236aa
+gbrp10le            2e9949a01fe4c38774728e34795165cc
+gbrp9be             6bac01a7f64a381521b2149fc46f4178
+gbrp9le             4b6cba7acf7886c13db122e590ec6b1f
+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
+yuva420p10be        d92a95061809f251175f5d5e3074930e
+yuva420p10le        bad90ba2d4c260e379a7aa6dc7760853
+yuva420p16be        a61d8ddb646e2d26020fc7ed2a48c1a9
+yuva420p16le        90ef774f86ad3177ec57eca8744b4e09
+yuva420p9be         f7655546446bfdc875243d7cdeb13b30
+yuva420p9le         ada2b719827059d70ebc57e2a3f9da92
+yuva422p            3c76ebeca0a7d3aa5f8e31ef80a86ffe
+yuva422p10be        01dd539e4a62762a3c97e965c76bb6f7
+yuva422p10le        76355d9d8fdcd085a24d48832b72e40b
+yuva422p16be        c21afa31ac18bd92e8e596b81552b52b
+yuva422p16le        0bc3720dba6076dcce3b74b1d3c6c4b7
+yuva422p9be         a60ac5b8026e9621724c033fbf79dbda
+yuva422p9le         c3eda8831e9b9c94a3eb487d33114103
+yuva444p            3268c6abe5e3cdbd16552a1eddced816
+yuva444p10be        856b37c1ee53459f46b9359d329ac9b5
+yuva444p10le        22790592361c007406d4ca9a9e0954a5
+yuva444p16be        ed5b07fe4d5b1137604568786777af1d
+yuva444p16le        3a3df23feb60d8832b566fd9765983d0
+yuva444p9be         4fc479c5b1044ad37b4e6fc6488b4f7f
+yuva444p9le         c41849b0134670d6f6253c337defbb04
+yuvj420p            30427bd6caf5bda93a173dbebe759e09
+yuvj422p            fc8288f64fd149573f73cf8da05d8e6d
+yuvj440p            508ac7a9ddeb6d1794a1100ba7a1664c
+yuvj444p            73aebe144085b22d1189caf6ca07e18c
+yuyv422             169e19ac91b257bd84ace0fdf56559ad
diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip
new file mode 100644
index 0000000..f0ad5eb
--- /dev/null
+++ b/tests/ref/fate/filter-pixfmts-vflip
@@ -0,0 +1,89 @@
+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
+gbrp                25c1bce192daefab910d51a56b52199e
+gbrp10be            6fe980f9ca94cbcdb9e01f4e906fdf19
+gbrp10le            f793a1d96d3524c6a17e53356c415c4e
+gbrp9be             e10dc3a2566b065260a45356ef08c1cd
+gbrp9le             f25105a33f18d6bcca3205c67ec106be
+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
+yuva420p10be        baa5e3b0ff6d0ebbb0958560cd763c6e
+yuva420p10le        a36dc59ad55b406e5fee475236e9753c
+yuva420p16be        bf3b134eb70878df9afba61d03e930b8
+yuva420p16le        105d375154329a381aa58379a0a6ec46
+yuva420p9be         8273d591e055f48990c29dd905a6cdfd
+yuva420p9le         95ced0bb07e422d98db61a35cdb3fb8f
+yuva422p            6aed0ea657ed51cc047a4fbdd981aec8
+yuva422p10be        d69a3404984c5fd30c0fc548532bcb6b
+yuva422p10le        a40c8e6f50e12d94bf7484107ec98559
+yuva422p16be        39552c259ca242f2417e913ffc602fde
+yuva422p16le        16faa558a34291ca32f6d94dce211ee2
+yuva422p9be         a951eafb62c092c63f7566b6803f60df
+yuva422p9le         00b39cfca78666e057ee527f5e174a04
+yuva444p            da5d64f2b2bd2013c186456f595fad65
+yuva444p10be        00e74a9c0c7818a9bbd9fee95b961ee8
+yuva444p10le        cbe30f44b63cf7ed27fc2dde40315b5e
+yuva444p16be        7e9b799b057e1446dabbf0f738480cfb
+yuva444p16le        556d58b91a617fe4a83af99a4aea1c2e
+yuva444p9be         b5a31de4fac408eeecaf3aff11f40e55
+yuva444p9le         67467f1e1d9edbd59d3984ebbfe24be6
+yuvj420p            41fd02b204da0ab62452cd14b595e2e4
+yuvj422p            7f6ca9bc1812cde02036d7d29a7cce43
+yuvj440p            25711c3c0fd15ec19c59a10784fcfb96
+yuvj444p            e45dee2ac02276dfab92e8ebfbe52e00
+yuyv422             e944ff7316cd03c42c091717ce74f602
diff --git a/tests/ref/lavfi/scale200 b/tests/ref/fate/filter-scale200
similarity index 100%
rename from tests/ref/lavfi/scale200
rename to tests/ref/fate/filter-scale200
diff --git a/tests/ref/lavfi/scale500 b/tests/ref/fate/filter-scale500
similarity index 100%
rename from tests/ref/lavfi/scale500
rename to tests/ref/fate/filter-scale500
diff --git a/tests/ref/fate/filter-select-alternate b/tests/ref/fate/filter-select-alternate
new file mode 100644
index 0000000..0776694
--- /dev/null
+++ b/tests/ref/fate/filter-select-alternate
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0x05b789ef
+0,          2,          2,        1,   152064, 0x9dddf64a
+0,          4,          4,        1,   152064, 0x4de3b652
+0,          6,          6,        1,   152064, 0xe20f7c23
+0,          8,          8,        1,   152064, 0x1f1b8026
+0,         10,         10,        1,   152064, 0x02344760
+0,         12,         12,        1,   152064, 0xc711ad61
+0,         14,         14,        1,   152064, 0x52a48ddd
+0,         16,         16,        1,   152064, 0x8e364e18
+0,         18,         18,        1,   152064, 0xf25f6acc
+0,         20,         20,        1,   152064, 0xfc7bf570
+0,         22,         22,        1,   152064, 0x445d1d59
+0,         24,         24,        1,   152064, 0xce09f9d6
+0,         26,         26,        1,   152064, 0x43d796b5
+0,         28,         28,        1,   152064, 0x76d2a455
+0,         30,         30,        1,   152064, 0x0f9d6aca
+0,         32,         32,        1,   152064, 0xd766fc8d
+0,         34,         34,        1,   152064, 0x7fea4378
+0,         36,         36,        1,   152064, 0x4c9737ab
+0,         38,         38,        1,   152064, 0x0b07594c
+0,         40,         40,        1,   152064, 0xd2735925
+0,         42,         42,        1,   152064, 0x20cebfa9
+0,         44,         44,        1,   152064, 0xfd500471
+0,         46,         46,        1,   152064, 0x09ef53ff
+0,         48,         48,        1,   152064, 0xbb87b483
diff --git a/tests/ref/fate/filter-setpts b/tests/ref/fate/filter-setpts
new file mode 100644
index 0000000..14aa613
--- /dev/null
+++ b/tests/ref/fate/filter-setpts
@@ -0,0 +1,51 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 0x05b789ef
+0,         28,         28,        0,   152064, 0x4bb46551
+0,         57,         57,        0,   152064, 0x9dddf64a
+0,         86,         86,        0,   152064, 0x2a8380b0
+0,        115,        115,        0,   152064, 0x4de3b652
+0,        144,        144,        0,   152064, 0xedb5a8e6
+0,        172,        172,        0,   152064, 0xe20f7c23
+0,        201,        201,        0,   152064, 0x5ab58bac
+0,        229,        229,        0,   152064, 0x1f1b8026
+0,        258,        258,        0,   152064, 0x91373915
+0,        286,        286,        0,   152064, 0x02344760
+0,        314,        314,        0,   152064, 0x30f5fcd5
+0,        343,        343,        0,   152064, 0xc711ad61
+0,        371,        371,        0,   152064, 0x24eca223
+0,        399,        399,        0,   152064, 0x52a48ddd
+0,        427,        427,        0,   152064, 0xa91c0f05
+0,        456,        456,        0,   152064, 0x8e364e18
+0,        484,        484,        0,   152064, 0xb15d38c8
+0,        512,        512,        0,   152064, 0xf25f6acc
+0,        541,        541,        0,   152064, 0xf34ddbff
+0,        570,        570,        0,   152064, 0xfc7bf570
+0,        598,        598,        0,   152064, 0x9dc72412
+0,        627,        627,        0,   152064, 0x445d1d59
+0,        656,        656,        0,   152064, 0x2f2768ef
+0,        685,        685,        0,   152064, 0xce09f9d6
+0,        714,        714,        0,   152064, 0x95579936
+0,        743,        743,        0,   152064, 0x43d796b5
+0,        772,        772,        0,   152064, 0xd780d887
+0,        800,        800,        0,   152064, 0x76d2a455
+0,        829,        829,        0,   152064, 0x6dc3650e
+0,        858,        858,        0,   152064, 0x0f9d6aca
+0,        887,        887,        0,   152064, 0xe295c51e
+0,        915,        915,        0,   152064, 0xd766fc8d
+0,        944,        944,        0,   152064, 0xe22f7a30
+0,        972,        972,        0,   152064, 0x7fea4378
+0,       1000,       1000,        0,   152064, 0xfa8d94fb
+0,       1029,       1029,        0,   152064, 0x4c9737ab
+0,       1057,       1057,        0,   152064, 0xa50d01f8
+0,       1085,       1085,        0,   152064, 0x0b07594c
+0,       1113,       1113,        0,   152064, 0x88734edd
+0,       1142,       1142,        0,   152064, 0xd2735925
+0,       1170,       1170,        0,   152064, 0xd4e49e08
+0,       1198,       1198,        0,   152064, 0x20cebfa9
+0,       1227,       1227,        0,   152064, 0x575c20ec
+0,       1255,       1255,        0,   152064, 0xfd500471
+0,       1284,       1284,        0,   152064, 0x61b47e73
+0,       1313,       1313,        0,   152064, 0x09ef53ff
+0,       1341,       1341,        0,   152064, 0x6e88c5c2
+0,       1370,       1370,        0,   152064, 0xbb87b483
+0,       1399,       1399,        0,   152064, 0x4bbad8ea
diff --git a/tests/ref/fate/filter-transpose b/tests/ref/fate/filter-transpose
new file mode 100644
index 0000000..0f23423
--- /dev/null
+++ b/tests/ref/fate/filter-transpose
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0xab5889ef
+0,          1,          1,        1,   152064, 0x898b6551
+0,          2,          2,        1,   152064, 0x231bf64a
+0,          3,          3,        1,   152064, 0x0b8c80b0
+0,          4,          4,        1,   152064, 0x8b3cb652
+0,          5,          5,        1,   152064, 0x0100a8e6
+0,          6,          6,        1,   152064, 0x55df7c23
+0,          7,          7,        1,   152064, 0x91bd8bac
+0,          8,          8,        1,   152064, 0xf5508026
+0,          9,          9,        1,   152064, 0xa7ec3915
+0,         10,         10,        1,   152064, 0x4e304760
+0,         11,         11,        1,   152064, 0x98ccfcd5
+0,         12,         12,        1,   152064, 0x00edad61
+0,         13,         13,        1,   152064, 0x01a0a223
+0,         14,         14,        1,   152064, 0x840e8ddd
+0,         15,         15,        1,   152064, 0x52280f05
+0,         16,         16,        1,   152064, 0x75064e18
+0,         17,         17,        1,   152064, 0xf41638c8
+0,         18,         18,        1,   152064, 0x258d6acc
+0,         19,         19,        1,   152064, 0x9d73dbff
+0,         20,         20,        1,   152064, 0x80e0f570
+0,         21,         21,        1,   152064, 0x3a912412
+0,         22,         22,        1,   152064, 0xaf241d59
+0,         23,         23,        1,   152064, 0xe73568ef
+0,         24,         24,        1,   152064, 0xc739f9d6
+0,         25,         25,        1,   152064, 0xc8c19936
+0,         26,         26,        1,   152064, 0x47dd96b5
+0,         27,         27,        1,   152064, 0x5329d887
+0,         28,         28,        1,   152064, 0x5b46a455
+0,         29,         29,        1,   152064, 0xfd8c650e
+0,         30,         30,        1,   152064, 0x85c86aca
+0,         31,         31,        1,   152064, 0x46a6c51e
+0,         32,         32,        1,   152064, 0x220dfc8d
+0,         33,         33,        1,   152064, 0xdbe27a30
+0,         34,         34,        1,   152064, 0xb8cc4378
+0,         35,         35,        1,   152064, 0xb6cf94fb
+0,         36,         36,        1,   152064, 0xeaa937ab
+0,         37,         37,        1,   152064, 0x335401f8
+0,         38,         38,        1,   152064, 0xdb3d594c
+0,         39,         39,        1,   152064, 0x211c4edd
+0,         40,         40,        1,   152064, 0xc3725925
+0,         41,         41,        1,   152064, 0x8f389e08
+0,         42,         42,        1,   152064, 0xc62cbfa9
+0,         43,         43,        1,   152064, 0x803820ec
+0,         44,         44,        1,   152064, 0x0d860471
+0,         45,         45,        1,   152064, 0xf6997e73
+0,         46,         46,        1,   152064, 0x6c2153ff
+0,         47,         47,        1,   152064, 0x1bb2c5c2
+0,         48,         48,        1,   152064, 0x39d1b483
+0,         49,         49,        1,   152064, 0x2b50d8ea
diff --git a/tests/ref/fate/filter-trim-duration b/tests/ref/fate/filter-trim-duration
new file mode 100644
index 0000000..db74add
--- /dev/null
+++ b/tests/ref/fate/filter-trim-duration
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,         10,         10,        1,   152064, 0xb45c4760
diff --git a/tests/ref/fate/filter-trim-frame b/tests/ref/fate/filter-trim-frame
new file mode 100644
index 0000000..1749afd
--- /dev/null
+++ b/tests/ref/fate/filter-trim-frame
@@ -0,0 +1,8 @@
+#tb 0: 1/25
+0,          3,          3,        1,   152064, 0xceb080b0
+0,          4,          4,        1,   152064, 0x473db652
+0,          5,          5,        1,   152064, 0x287da8e6
+0,          6,          6,        1,   152064, 0x68b47c23
+0,          7,          7,        1,   152064, 0xe9028bac
+0,          8,          8,        1,   152064, 0x28ff8026
+0,          9,          9,        1,   152064, 0x2d7c3915
diff --git a/tests/ref/fate/filter-trim-mixed b/tests/ref/fate/filter-trim-mixed
new file mode 100644
index 0000000..5e003f6
--- /dev/null
+++ b/tests/ref/fate/filter-trim-mixed
@@ -0,0 +1,10 @@
+#tb 0: 1/25
+0,          1,          1,        1,   152064, 0x7f5f6551
+0,          2,          2,        1,   152064, 0xc566f64a
+0,          3,          3,        1,   152064, 0xceb080b0
+0,          4,          4,        1,   152064, 0x473db652
+0,          5,          5,        1,   152064, 0x287da8e6
+0,          6,          6,        1,   152064, 0x68b47c23
+0,          7,          7,        1,   152064, 0xe9028bac
+0,          8,          8,        1,   152064, 0x28ff8026
+0,          9,          9,        1,   152064, 0x2d7c3915
diff --git a/tests/ref/fate/filter-trim-time b/tests/ref/fate/filter-trim-time
new file mode 100644
index 0000000..2f86025
--- /dev/null
+++ b/tests/ref/fate/filter-trim-time
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0x6e4f89ef
+0,          1,          1,        1,   152064, 0x7f5f6551
diff --git a/tests/ref/fate/filter-unsharp b/tests/ref/fate/filter-unsharp
new file mode 100644
index 0000000..5dcf40f
--- /dev/null
+++ b/tests/ref/fate/filter-unsharp
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   152064, 0x19a94798
+0,          1,          1,        1,   152064, 0xc88b24f4
+0,          2,          2,        1,   152064, 0xd027b44b
+0,          3,          3,        1,   152064, 0xa9fb3e54
+0,          4,          4,        1,   152064, 0x2991747d
+0,          5,          5,        1,   152064, 0x1dc267fc
+0,          6,          6,        1,   152064, 0xe9063293
+0,          7,          7,        1,   152064, 0xc23e41a4
+0,          8,          8,        1,   152064, 0xaa433dc5
+0,          9,          9,        1,   152064, 0x22b0f0a3
+0,         10,         10,        1,   152064, 0x796d08d8
+0,         11,         11,        1,   152064, 0xa2babd6b
+0,         12,         12,        1,   152064, 0x531e6a62
+0,         13,         13,        1,   152064, 0xc8fa5b9d
+0,         14,         14,        1,   152064, 0x33e54ae8
+0,         15,         15,        1,   152064, 0x86dfd0b8
+0,         16,         16,        1,   152064, 0x101f1170
+0,         17,         17,        1,   152064, 0x230eef00
+0,         18,         18,        1,   152064, 0xa5ee1c5e
+0,         19,         19,        1,   152064, 0x241893c6
+0,         20,         20,        1,   152064, 0x86a0a883
+0,         21,         21,        1,   152064, 0x12b4d8f7
+0,         22,         22,        1,   152064, 0xb220d497
+0,         23,         23,        1,   152064, 0xbaea200e
+0,         24,         24,        1,   152064, 0x6d96b7f3
+0,         25,         25,        1,   152064, 0xc70d4ebb
+0,         26,         26,        1,   152064, 0x20df50af
+0,         27,         27,        1,   152064, 0xfce89174
+0,         28,         28,        1,   152064, 0x74be5c8e
+0,         29,         29,        1,   152064, 0x51f419a6
+0,         30,         30,        1,   152064, 0x790621e7
+0,         31,         31,        1,   152064, 0x37387da2
+0,         32,         32,        1,   152064, 0x8228baa4
+0,         33,         33,        1,   152064, 0xdd2a42b7
+0,         34,         34,        1,   152064, 0xa28bfc63
+0,         35,         35,        1,   152064, 0xe8284337
+0,         36,         36,        1,   152064, 0xb1dae9fe
+0,         37,         37,        1,   152064, 0x0378c0af
+0,         38,         38,        1,   152064, 0x79c514d4
+0,         39,         39,        1,   152064, 0x043e0347
+0,         40,         40,        1,   152064, 0x4d11131b
+0,         41,         41,        1,   152064, 0xb2a05924
+0,         42,         42,        1,   152064, 0xd0097464
+0,         43,         43,        1,   152064, 0x32dfd8c0
+0,         44,         44,        1,   152064, 0xd9ecbf03
+0,         45,         45,        1,   152064, 0x8dcc403f
+0,         46,         46,        1,   152064, 0x95e81af7
+0,         47,         47,        1,   152064, 0xb8018b25
+0,         48,         48,        1,   152064, 0xeecf7281
+0,         49,         49,        1,   152064, 0x23e49602
diff --git a/tests/ref/lavfi/vflip b/tests/ref/fate/filter-vflip
similarity index 100%
rename from tests/ref/lavfi/vflip
rename to tests/ref/fate/filter-vflip
diff --git a/tests/ref/lavfi/vflip_crop b/tests/ref/fate/filter-vflip_crop
similarity index 100%
rename from tests/ref/lavfi/vflip_crop
rename to tests/ref/fate/filter-vflip_crop
diff --git a/tests/ref/lavfi/vflip_vflip b/tests/ref/fate/filter-vflip_vflip
similarity index 100%
rename from tests/ref/lavfi/vflip_vflip
rename to tests/ref/fate/filter-vflip_vflip
diff --git a/tests/ref/fate/filter-yadif-mode0 b/tests/ref/fate/filter-yadif-mode0
index e260977..d2c14d3 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
+0,      64800,      64800,        0,   622080, 0x6331caee
+0,      72000,      72000,        0,   622080, 0xa459e690
+0,      79200,      79200,        0,   622080, 0x6429c648
+0,      86400,      86400,        0,   622080, 0xa49891ca
+0,      93600,      93600,        0,   622080, 0x2a887404
+0,     100800,     100800,        0,   622080, 0xe8d49705
+0,     108000,     108000,        0,   622080, 0x1b627835
+0,     115200,     115200,        0,   622080, 0x686858fd
+0,     122400,     122400,        0,   622080, 0x2675174f
+0,     129600,     129600,        0,   622080, 0x78470e7f
+0,     136800,     136800,        0,   622080, 0xffb366ec
+0,     144000,     144000,        0,   622080, 0xd575da72
+0,     151200,     151200,        0,   622080, 0x5fb297f7
+0,     158400,     158400,        0,   622080, 0xbac77ca0
+0,     165600,     165600,        0,   622080, 0x3276ed72
+0,     172800,     172800,        0,   622080, 0x264092b2
+0,     180000,     180000,        0,   622080, 0x20ba1094
+0,     187200,     187200,        0,   622080, 0x76cc3139
+0,     194400,     194400,        0,   622080, 0x469a4902
+0,     201600,     201600,        0,   622080, 0x0ed7b8f5
+0,     208800,     208800,        0,   622080, 0xdc51aeac
+0,     216000,     216000,        0,   622080, 0xee06aa36
+0,     223200,     223200,        0,   622080, 0x7372405f
+0,     230400,     230400,        0,   622080, 0x9e0ee776
+0,     237600,     237600,        0,   622080, 0x39e6d8c9
+0,     244800,     244800,        0,   622080, 0x51d9ac9a
+0,     252000,     252000,        0,   622080, 0x2b63441d
+0,     259200,     259200,        0,   622080, 0x58afbd5e
+0,     266400,     266400,        0,   622080, 0xb972f716
+0,     273600,     273600,        0,   622080, 0x6a6df129
+0,     280800,     280800,        0,   622080, 0x28b1373d
diff --git a/tests/ref/fate/filter-yadif-mode1 b/tests/ref/fate/filter-yadif-mode1
index b498137..ca5f290 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
+0,      64800,      64800,        0,   622080, 0x6331caee
+0,      68400,      68400,        0,   622080, 0x625da883
+0,      72000,      72000,        0,   622080, 0xa459e690
+0,      75600,      75600,        0,   622080, 0xce5d891e
+0,      79200,      79200,        0,   622080, 0x6429c648
+0,      82800,      82800,        0,   622080, 0x608cc0ba
+0,      86400,      86400,        0,   622080, 0xa49891ca
+0,      90000,      90000,        0,   622080, 0x9721987f
+0,      93600,      93600,        0,   622080, 0x2a887404
+0,      97200,      97200,        0,   622080, 0x60d71d47
+0,     100800,     100800,        0,   622080, 0xe8d49705
+0,     104400,     104400,        0,   622080, 0x821e13cb
+0,     108000,     108000,        0,   622080, 0x1b627835
+0,     111600,     111600,        0,   622080, 0x1806c5f4
+0,     115200,     115200,        0,   622080, 0x686858fd
+0,     118800,     118800,        0,   622080, 0xab865773
+0,     122400,     122400,        0,   622080, 0x2675174f
+0,     126000,     126000,        0,   622080, 0x43a61a14
+0,     129600,     129600,        0,   622080, 0x78470e7f
+0,     133200,     133200,        0,   622080, 0xeb877bc6
+0,     136800,     136800,        0,   622080, 0xffb366ec
+0,     140400,     140400,        0,   622080, 0xda0906e7
+0,     144000,     144000,        0,   622080, 0xd575da72
+0,     147600,     147600,        0,   622080, 0x23ae25a4
+0,     151200,     151200,        0,   622080, 0x5fb297f7
+0,     154800,     154800,        0,   622080, 0x99b32978
+0,     158400,     158400,        0,   622080, 0xbac77ca0
+0,     162000,     162000,        0,   622080, 0xc1cdcbf9
+0,     165600,     165600,        0,   622080, 0x3276ed72
+0,     169200,     169200,        0,   622080, 0x4061f5ab
+0,     172800,     172800,        0,   622080, 0x264092b2
+0,     176400,     176400,        0,   622080, 0xa4e2039e
+0,     180000,     180000,        0,   622080, 0x20ba1094
+0,     183600,     183600,        0,   622080, 0x984e906e
+0,     187200,     187200,        0,   622080, 0x76cc3139
+0,     190800,     190800,        0,   622080, 0xf70e2cf6
+0,     194400,     194400,        0,   622080, 0x469a4902
+0,     198000,     198000,        0,   622080, 0x235312e6
+0,     201600,     201600,        0,   622080, 0x0ed7b8f5
+0,     205200,     205200,        0,   622080, 0xd0269cc3
+0,     208800,     208800,        0,   622080, 0xdc51aeac
+0,     212400,     212400,        0,   622080, 0x1aa5f76e
+0,     216000,     216000,        0,   622080, 0xee06aa36
+0,     219600,     219600,        0,   622080, 0xa7103230
+0,     223200,     223200,        0,   622080, 0x7372405f
+0,     226800,     226800,        0,   622080, 0x8d7a44b5
+0,     230400,     230400,        0,   622080, 0x9e0ee776
+0,     234000,     234000,        0,   622080, 0xd41e8560
+0,     237600,     237600,        0,   622080, 0x39e6d8c9
+0,     241200,     241200,        0,   622080, 0x7a23d70c
+0,     244800,     244800,        0,   622080, 0x51d9ac9a
+0,     248400,     248400,        0,   622080, 0x8eacf7f2
+0,     252000,     252000,        0,   622080, 0x2b63441d
+0,     255600,     255600,        0,   622080, 0x9f71b742
+0,     259200,     259200,        0,   622080, 0x58afbd5e
+0,     262800,     262800,        0,   622080, 0x4d645292
+0,     266400,     266400,        0,   622080, 0xb972f716
+0,     270000,     270000,        0,   622080, 0xbb5d01a2
+0,     273600,     273600,        0,   622080, 0x6a6df129
+0,     277200,     277200,        0,   622080, 0x9e45371e
+0,     280800,     280800,        0,   622080, 0x28b1373d
+0,     284400,     284400,        0,   622080, 0xa1cdb1f2
diff --git a/tests/ref/fate/h264-conformance-cvfc1_sony_c b/tests/ref/fate/h264-conformance-cvfc1_sony_c
new file mode 100644
index 0000000..1abe67f
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-cvfc1_sony_c
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,    75600, 0x6f6a8c48
+0,          1,          1,        1,    75600, 0x4b7ac558
+0,          2,          2,        1,    75600, 0x907feda3
+0,          3,          3,        1,    75600, 0x7b2b17d2
+0,          4,          4,        1,    75600, 0x46d038e7
+0,          5,          5,        1,    75600, 0x90d463b3
+0,          6,          6,        1,    75600, 0xc00d7ec1
+0,          7,          7,        1,    75600, 0x10f69a60
+0,          8,          8,        1,    75600, 0x676aad50
+0,          9,          9,        1,    75600, 0x0a3fd3e0
+0,         10,         10,        1,    75600, 0xaee8fc87
+0,         11,         11,        1,    75600, 0xc9f41fbb
+0,         12,         12,        1,    75600, 0x183743dd
+0,         13,         13,        1,    75600, 0xf0385aa2
+0,         14,         14,        1,    75600, 0xad63782e
+0,         15,         15,        1,    75600, 0x9ed08c01
+0,         16,         16,        1,    75600, 0x79aba20e
+0,         17,         17,        1,    75600, 0x53d6c34c
+0,         18,         18,        1,    75600, 0x4cead515
+0,         19,         19,        1,    75600, 0xc701e3c8
+0,         20,         20,        1,    75600, 0xb278e37d
+0,         21,         21,        1,    75600, 0x02e6f95e
+0,         22,         22,        1,    75600, 0x5cdffef4
+0,         23,         23,        1,    75600, 0x6e0a1089
+0,         24,         24,        1,    75600, 0x23a919b5
+0,         25,         25,        1,    75600, 0x31f5391c
+0,         26,         26,        1,    75600, 0xaa2c3445
+0,         27,         27,        1,    75600, 0x42204340
+0,         28,         28,        1,    75600, 0x55924031
+0,         29,         29,        1,    75600, 0x6bc94d1b
+0,         30,         30,        1,    75600, 0x3e1a1e21
+0,         31,         31,        1,    75600, 0xaf4816fc
+0,         32,         32,        1,    75600, 0x322c1d18
+0,         33,         33,        1,    75600, 0xf59c1746
+0,         34,         34,        1,    75600, 0x875cfc24
+0,         35,         35,        1,    75600, 0x8657f65b
+0,         36,         36,        1,    75600, 0x7e78f95f
+0,         37,         37,        1,    75600, 0x7639e983
+0,         38,         38,        1,    75600, 0xcdaac5fa
+0,         39,         39,        1,    75600, 0x2b7ac473
+0,         40,         40,        1,    75600, 0x028cb98f
+0,         41,         41,        1,    75600, 0x023abda4
+0,         42,         42,        1,    75600, 0x9733ad92
+0,         43,         43,        1,    75600, 0xfb4f8cfe
+0,         44,         44,        1,    75600, 0xfef071b6
+0,         45,         45,        1,    75600, 0xf7513219
+0,         46,         46,        1,    75600, 0x9d6e3c98
+0,         47,         47,        1,    75600, 0xd5501ac7
+0,         48,         48,        1,    75600, 0xa00201f1
+0,         49,         49,        1,    75600, 0xee84e8c6
diff --git a/tests/ref/fate/h264-crop-to-container b/tests/ref/fate/h264-crop-to-container
new file mode 100644
index 0000000..5dfa441
--- /dev/null
+++ b/tests/ref/fate/h264-crop-to-container
@@ -0,0 +1,2 @@
+#tb 0: 1/30000
+0,          0,          0,        0,  3110400, 43a312e1eebc7dca1bd23456302a44e3
diff --git a/tests/ref/fate/h264-reinit-large_420_8-to-small_420_8 b/tests/ref/fate/h264-reinit-large_420_8-to-small_420_8
new file mode 100644
index 0000000..8518855
--- /dev/null
+++ b/tests/ref/fate/h264-reinit-large_420_8-to-small_420_8
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,   608256, 0x65574c43
+0,          1,          1,        1,   608256, 0x5e5a1aa4
+0,          2,          2,        1,   608256, 0xa9a5cbc5
+0,          3,          3,        1,   608256, 0x4e462c02
+0,          4,          4,        1,   608256, 0xf8215f14
+0,          5,          5,        1,   608256, 0x4f332ccd
+0,          6,          6,        1,   608256, 0x5dac18a3
+0,          7,          7,        1,   608256, 0x81196f38
+0,          8,          8,        1,   608256, 0xd4cb4ffc
+0,          9,          9,        1,   608256, 0x839af1a4
+0,         10,         10,        1,   608256, 0x15ab7a99
+0,         11,         11,        1,   608256, 0x7496aec8
+0,         12,         12,        1,   608256, 0xfe974593
+0,         13,         13,        1,   608256, 0x702a94b7
+0,         14,         14,        1,   608256, 0x0f74cd7a
+0,         15,         15,        1,   608256, 0x3b35b667
+0,         16,         16,        1,   608256, 0x22083d70
+0,         17,         17,        1,   608256, 0xab77f6e1
+0,         18,         18,        1,   608256, 0x51513651
+0,         19,         19,        1,   608256, 0x06ff4ef1
+0,         20,         20,        1,   608256, 0xdf2ed7d3
+0,         21,         21,        1,   608256, 0x3107421b
+0,         22,         22,        1,   608256, 0x975823fe
+0,         23,         23,        1,   608256, 0xe40d9894
+0,         24,         24,        1,   608256, 0x8fb1fead
+0,         25,         25,        1,   608256, 0x56e5056b
+0,         26,         26,        1,   608256, 0x3346b970
+0,         27,         27,        1,   608256, 0x7e3c5b82
+0,         28,         28,        1,   608256, 0x6a86c482
+0,         29,         29,        1,   608256, 0x3e800e13
+0,         30,         30,        1,   608256, 0xd6c4589e
+0,         31,         31,        1,   608256, 0xcdfa7d94
+0,         32,         32,        1,   608256, 0xdc91cfce
+0,         33,         33,        1,   608256, 0x8aa5fd0e
+0,         34,         34,        1,   608256, 0x85c190be
+0,         35,         35,        1,   608256, 0xe7563061
+0,         36,         36,        1,   608256, 0x7fd501ec
+0,         37,         37,        1,   608256, 0x088d0df3
+0,         38,         38,        1,   608256, 0x08129a2f
+0,         39,         39,        1,   608256, 0x7bed8d9c
+0,         40,         40,        1,   608256, 0x16ce64c6
+0,         41,         41,        1,   608256, 0x6a120a3a
+0,         42,         42,        1,   608256, 0xfe0b889e
+0,         43,         43,        1,   608256, 0x57f4efcd
+0,         44,         44,        1,   608256, 0xc363ca91
+0,         45,         45,        1,   608256, 0x92237dce
+0,         46,         46,        1,   608256, 0x77bab64f
+0,         47,         47,        1,   608256, 0x29118201
+0,         48,         48,        1,   608256, 0x6f8e8e53
+0,         49,         49,        1,   608256, 0x4a13c4a3
+0,         50,         50,        1,   608256, 0x27a069a3
+0,         51,         51,        1,   608256, 0x22a5ff96
+0,         52,         52,        1,   608256, 0x29ad753f
+0,         53,         53,        1,   608256, 0x955788a6
+0,         54,         54,        1,   608256, 0xb73599c5
+0,         55,         55,        1,   608256, 0x73765aca
+0,         56,         56,        1,   608256, 0x39118f45
+0,         57,         57,        1,   608256, 0xfb0f8b96
+0,         58,         58,        1,   608256, 0xfcf71085
+0,         59,         59,        1,   608256, 0xccaaca7d
+0,         60,         60,        1,   608256, 0xde873299
+0,         61,         61,        1,   608256, 0x5d904202
+0,         62,         62,        1,   608256, 0x1e92c9b8
+0,         63,         63,        1,   608256, 0xdb8ec231
+0,         64,         64,        1,   608256, 0x388e2b9f
+0,         65,         65,        1,   608256, 0x1d190c39
+0,         66,         66,        1,   608256, 0xb6609efd
+0,         67,         67,        1,   608256, 0x0c6bf1d0
+0,         68,         68,        1,   608256, 0x178e0a3c
+0,         69,         69,        1,   608256, 0x439509f7
+0,         70,         70,        1,   608256, 0x00eb29ec
+0,         71,         71,        1,   608256, 0xee45f2a0
+0,         72,         72,        1,   608256, 0xae62eb8c
+0,         73,         73,        1,   608256, 0x3bb7510d
+0,         74,         74,        1,   608256, 0x03f08d02
+0,         75,         75,        1,   608256, 0x4beffc2a
+0,         76,         76,        1,   608256, 0x6071eb56
+0,         77,         77,        1,   608256, 0xbcb4e4e5
+0,         78,         78,        1,   608256, 0x775864aa
+0,         79,         79,        1,   608256, 0x3cfa0a94
+0,         80,         80,        1,   608256, 0x4652d529
+0,         81,         81,        1,   608256, 0xc5be07e2
+0,         82,         82,        1,   608256, 0xe7b480a2
+0,         83,         83,        1,   608256, 0x83b11945
+0,         84,         84,        1,   608256, 0x25ff0458
+0,         85,         85,        1,   608256, 0x5a780cda
+0,         86,         86,        1,   608256, 0x3448077c
+0,         87,         87,        1,   608256, 0x0f9c6f09
+0,         88,         88,        1,   608256, 0x05ece146
+0,         89,         89,        1,   608256, 0x3b02b504
+0,         90,         90,        1,   608256, 0xf3a8e2a6
+0,         91,         91,        1,   608256, 0xd4544847
+0,         92,         92,        1,   608256, 0x49bd2a3f
+0,         93,         93,        1,   608256, 0x22a42082
+0,         94,         94,        1,   608256, 0x8d8d1923
+0,         95,         95,        1,   608256, 0x2ba6877f
+0,         96,         96,        1,   608256, 0x494d481b
+0,         97,         97,        1,   608256, 0x28c99c35
+0,         98,         98,        1,   608256, 0x80128077
+0,         99,         99,        1,   608256, 0x887c2fb0
diff --git a/tests/ref/fate/h264-reinit-small_420_8-to-large_444_10 b/tests/ref/fate/h264-reinit-small_420_8-to-large_444_10
new file mode 100644
index 0000000..7e7631a
--- /dev/null
+++ b/tests/ref/fate/h264-reinit-small_420_8-to-large_444_10
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,   608256, 0x27a069a3
+0,          1,          1,        1,   608256, 0x22a5ff96
+0,          2,          2,        1,   608256, 0x29ad753f
+0,          3,          3,        1,   608256, 0x955788a6
+0,          4,          4,        1,   608256, 0xb73599c5
+0,          5,          5,        1,   608256, 0x73765aca
+0,          6,          6,        1,   608256, 0x39118f45
+0,          7,          7,        1,   608256, 0xfb0f8b96
+0,          8,          8,        1,   608256, 0xfcf71085
+0,          9,          9,        1,   608256, 0xccaaca7d
+0,         10,         10,        1,   608256, 0xde873299
+0,         11,         11,        1,   608256, 0x5d904202
+0,         12,         12,        1,   608256, 0x1e92c9b8
+0,         13,         13,        1,   608256, 0xdb8ec231
+0,         14,         14,        1,   608256, 0x388e2b9f
+0,         15,         15,        1,   608256, 0x1d190c39
+0,         16,         16,        1,   608256, 0xb6609efd
+0,         17,         17,        1,   608256, 0x0c6bf1d0
+0,         18,         18,        1,   608256, 0x178e0a3c
+0,         19,         19,        1,   608256, 0x439509f7
+0,         20,         20,        1,   608256, 0x00eb29ec
+0,         21,         21,        1,   608256, 0xee45f2a0
+0,         22,         22,        1,   608256, 0xae62eb8c
+0,         23,         23,        1,   608256, 0x3bb7510d
+0,         24,         24,        1,   608256, 0x03f08d02
+0,         25,         25,        1,   608256, 0x4beffc2a
+0,         26,         26,        1,   608256, 0x6071eb56
+0,         27,         27,        1,   608256, 0xbcb4e4e5
+0,         28,         28,        1,   608256, 0x775864aa
+0,         29,         29,        1,   608256, 0x3cfa0a94
+0,         30,         30,        1,   608256, 0x4652d529
+0,         31,         31,        1,   608256, 0xc5be07e2
+0,         32,         32,        1,   608256, 0xe7b480a2
+0,         33,         33,        1,   608256, 0x83b11945
+0,         34,         34,        1,   608256, 0x25ff0458
+0,         35,         35,        1,   608256, 0x5a780cda
+0,         36,         36,        1,   608256, 0x3448077c
+0,         37,         37,        1,   608256, 0x0f9c6f09
+0,         38,         38,        1,   608256, 0x05ece146
+0,         39,         39,        1,   608256, 0x3b02b504
+0,         40,         40,        1,   608256, 0xf3a8e2a6
+0,         41,         41,        1,   608256, 0xd4544847
+0,         42,         42,        1,   608256, 0x49bd2a3f
+0,         43,         43,        1,   608256, 0x22a42082
+0,         44,         44,        1,   608256, 0x8d8d1923
+0,         45,         45,        1,   608256, 0x2ba6877f
+0,         46,         46,        1,   608256, 0x494d481b
+0,         47,         47,        1,   608256, 0x28c99c35
+0,         48,         48,        1,   608256, 0x80128077
+0,         49,         49,        1,   608256, 0x887c2fb0
+0,         50,         50,        1,   608256, 0xfaba3fe4
+0,         51,         51,        1,   608256, 0x0369a227
+0,         52,         52,        1,   608256, 0xe62cb2b1
+0,         53,         53,        1,   608256, 0x851d9e78
+0,         54,         54,        1,   608256, 0x6847b938
+0,         55,         55,        1,   608256, 0x48eb702e
+0,         56,         56,        1,   608256, 0x3eb52eec
+0,         57,         57,        1,   608256, 0xf880edf8
+0,         58,         58,        1,   608256, 0xf7ac1860
+0,         59,         59,        1,   608256, 0x3ead29f3
+0,         60,         60,        1,   608256, 0x6db1860a
+0,         61,         61,        1,   608256, 0x72ee9271
+0,         62,         62,        1,   608256, 0xa8b643e4
+0,         63,         63,        1,   608256, 0x22a95a3e
+0,         64,         64,        1,   608256, 0x4e8aa877
+0,         65,         65,        1,   608256, 0x9545cfcf
+0,         66,         66,        1,   608256, 0x42d820e0
+0,         67,         67,        1,   608256, 0xe701ea6f
+0,         68,         68,        1,   608256, 0x05f61a49
+0,         69,         69,        1,   608256, 0xc1de9f65
+0,         70,         70,        1,   608256, 0x2b121933
+0,         71,         71,        1,   608256, 0x4de4e185
+0,         72,         72,        1,   608256, 0x01c6fb05
+0,         73,         73,        1,   608256, 0x1fbf8603
+0,         74,         74,        1,   608256, 0x9d8f2fd4
+0,         75,         75,        1,   608256, 0xb7d6f14e
+0,         76,         76,        1,   608256, 0x503c33a9
+0,         77,         77,        1,   608256, 0x051e8b02
+0,         78,         78,        1,   608256, 0xeff7c286
+0,         79,         79,        1,   608256, 0xeb80088a
+0,         80,         80,        1,   608256, 0xffbc6cec
+0,         81,         81,        1,   608256, 0x42d55e9d
+0,         82,         82,        1,   608256, 0x4898c507
+0,         83,         83,        1,   608256, 0x2c2411b5
+0,         84,         84,        1,   608256, 0xd70a34a4
+0,         85,         85,        1,   608256, 0xce5e64f5
+0,         86,         86,        1,   608256, 0x7790d293
+0,         87,         87,        1,   608256, 0xac5b44fb
+0,         88,         88,        1,   608256, 0xae4c2921
+0,         89,         89,        1,   608256, 0x373a26bb
+0,         90,         90,        1,   608256, 0x3aa3fed4
+0,         91,         91,        1,   608256, 0x4f4b1496
+0,         92,         92,        1,   608256, 0x4760fe2b
+0,         93,         93,        1,   608256, 0x9e38af43
+0,         94,         94,        1,   608256, 0xd7c66f6e
+0,         95,         95,        1,   608256, 0xf6cb1649
+0,         96,         96,        1,   608256, 0xb0591bf1
+0,         97,         97,        1,   608256, 0xb507b282
+0,         98,         98,        1,   608256, 0xfb53c6e5
+0,         99,         99,        1,   608256, 0x5410f10f
diff --git a/tests/ref/fate/h264-reinit-small_420_9-to-small_420_8 b/tests/ref/fate/h264-reinit-small_420_9-to-small_420_8
new file mode 100644
index 0000000..662db29
--- /dev/null
+++ b/tests/ref/fate/h264-reinit-small_420_9-to-small_420_8
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,   608256, 0xee06377f
+0,          1,          1,        1,   608256, 0x9c22c5ee
+0,          2,          2,        1,   608256, 0x322abee2
+0,          3,          3,        1,   608256, 0x82745ed3
+0,          4,          4,        1,   608256, 0xe7b9248b
+0,          5,          5,        1,   608256, 0xc8c1ce0e
+0,          6,          6,        1,   608256, 0x8451eba9
+0,          7,          7,        1,   608256, 0xece9412d
+0,          8,          8,        1,   608256, 0xffbc2c24
+0,          9,          9,        1,   608256, 0xf58c117e
+0,         10,         10,        1,   608256, 0x7853f334
+0,         11,         11,        1,   608256, 0x1acd6465
+0,         12,         12,        1,   608256, 0xb668856c
+0,         13,         13,        1,   608256, 0x3f52c230
+0,         14,         14,        1,   608256, 0xd7e8b5b6
+0,         15,         15,        1,   608256, 0xf663681d
+0,         16,         16,        1,   608256, 0x07ef670c
+0,         17,         17,        1,   608256, 0x1d5084f4
+0,         18,         18,        1,   608256, 0x0ea3fe04
+0,         19,         19,        1,   608256, 0xf095d1e0
+0,         20,         20,        1,   608256, 0xbdac37fb
+0,         21,         21,        1,   608256, 0x2cbfdf91
+0,         22,         22,        1,   608256, 0x8da7190f
+0,         23,         23,        1,   608256, 0x08bf6fc9
+0,         24,         24,        1,   608256, 0xa2368e5c
+0,         25,         25,        1,   608256, 0x36d38f81
+0,         26,         26,        1,   608256, 0x94d344cc
+0,         27,         27,        1,   608256, 0x1cf33f86
+0,         28,         28,        1,   608256, 0x98d6341f
+0,         29,         29,        1,   608256, 0xb04e3a3a
+0,         30,         30,        1,   608256, 0x74e52483
+0,         31,         31,        1,   608256, 0x6acc8d96
+0,         32,         32,        1,   608256, 0x136d6c4e
+0,         33,         33,        1,   608256, 0x50efa37a
+0,         34,         34,        1,   608256, 0x53170421
+0,         35,         35,        1,   608256, 0x2ed5210e
+0,         36,         36,        1,   608256, 0x5f471854
+0,         37,         37,        1,   608256, 0xd6ff7856
+0,         38,         38,        1,   608256, 0x446bf456
+0,         39,         39,        1,   608256, 0x872b95b1
+0,         40,         40,        1,   608256, 0xc9e5e827
+0,         41,         41,        1,   608256, 0xdab3eb04
+0,         42,         42,        1,   608256, 0xccd6347e
+0,         43,         43,        1,   608256, 0xd7dfd0a9
+0,         44,         44,        1,   608256, 0x60b834c3
+0,         45,         45,        1,   608256, 0x0b822676
+0,         46,         46,        1,   608256, 0x0e5d3d5a
+0,         47,         47,        1,   608256, 0x1fa0233d
+0,         48,         48,        1,   608256, 0xb853b650
+0,         49,         49,        1,   608256, 0x30d8d033
+0,         50,         50,        1,   608256, 0x27a069a3
+0,         51,         51,        1,   608256, 0x22a5ff96
+0,         52,         52,        1,   608256, 0x29ad753f
+0,         53,         53,        1,   608256, 0x955788a6
+0,         54,         54,        1,   608256, 0xb73599c5
+0,         55,         55,        1,   608256, 0x73765aca
+0,         56,         56,        1,   608256, 0x39118f45
+0,         57,         57,        1,   608256, 0xfb0f8b96
+0,         58,         58,        1,   608256, 0xfcf71085
+0,         59,         59,        1,   608256, 0xccaaca7d
+0,         60,         60,        1,   608256, 0xde873299
+0,         61,         61,        1,   608256, 0x5d904202
+0,         62,         62,        1,   608256, 0x1e92c9b8
+0,         63,         63,        1,   608256, 0xdb8ec231
+0,         64,         64,        1,   608256, 0x388e2b9f
+0,         65,         65,        1,   608256, 0x1d190c39
+0,         66,         66,        1,   608256, 0xb6609efd
+0,         67,         67,        1,   608256, 0x0c6bf1d0
+0,         68,         68,        1,   608256, 0x178e0a3c
+0,         69,         69,        1,   608256, 0x439509f7
+0,         70,         70,        1,   608256, 0x00eb29ec
+0,         71,         71,        1,   608256, 0xee45f2a0
+0,         72,         72,        1,   608256, 0xae62eb8c
+0,         73,         73,        1,   608256, 0x3bb7510d
+0,         74,         74,        1,   608256, 0x03f08d02
+0,         75,         75,        1,   608256, 0x4beffc2a
+0,         76,         76,        1,   608256, 0x6071eb56
+0,         77,         77,        1,   608256, 0xbcb4e4e5
+0,         78,         78,        1,   608256, 0x775864aa
+0,         79,         79,        1,   608256, 0x3cfa0a94
+0,         80,         80,        1,   608256, 0x4652d529
+0,         81,         81,        1,   608256, 0xc5be07e2
+0,         82,         82,        1,   608256, 0xe7b480a2
+0,         83,         83,        1,   608256, 0x83b11945
+0,         84,         84,        1,   608256, 0x25ff0458
+0,         85,         85,        1,   608256, 0x5a780cda
+0,         86,         86,        1,   608256, 0x3448077c
+0,         87,         87,        1,   608256, 0x0f9c6f09
+0,         88,         88,        1,   608256, 0x05ece146
+0,         89,         89,        1,   608256, 0x3b02b504
+0,         90,         90,        1,   608256, 0xf3a8e2a6
+0,         91,         91,        1,   608256, 0xd4544847
+0,         92,         92,        1,   608256, 0x49bd2a3f
+0,         93,         93,        1,   608256, 0x22a42082
+0,         94,         94,        1,   608256, 0x8d8d1923
+0,         95,         95,        1,   608256, 0x2ba6877f
+0,         96,         96,        1,   608256, 0x494d481b
+0,         97,         97,        1,   608256, 0x28c99c35
+0,         98,         98,        1,   608256, 0x80128077
+0,         99,         99,        1,   608256, 0x887c2fb0
diff --git a/tests/ref/fate/h264-reinit-small_422_9-to-small_420_9 b/tests/ref/fate/h264-reinit-small_422_9-to-small_420_9
new file mode 100644
index 0000000..b5a9505
--- /dev/null
+++ b/tests/ref/fate/h264-reinit-small_422_9-to-small_420_9
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,   608256, 0x3aef31f3
+0,          1,          1,        1,   608256, 0x05afe4e8
+0,          2,          2,        1,   608256, 0x9d7dc9b1
+0,          3,          3,        1,   608256, 0x60b3efec
+0,          4,          4,        1,   608256, 0x7dc51741
+0,          5,          5,        1,   608256, 0xb3bfb413
+0,          6,          6,        1,   608256, 0x0a2738b3
+0,          7,          7,        1,   608256, 0xfd3f8f1b
+0,          8,          8,        1,   608256, 0x922d413f
+0,          9,          9,        1,   608256, 0x775b4cfb
+0,         10,         10,        1,   608256, 0xcbfaec82
+0,         11,         11,        1,   608256, 0x1f1903a2
+0,         12,         12,        1,   608256, 0xdd246528
+0,         13,         13,        1,   608256, 0xe3d8afdc
+0,         14,         14,        1,   608256, 0xb29c4235
+0,         15,         15,        1,   608256, 0xa230e654
+0,         16,         16,        1,   608256, 0xe0246276
+0,         17,         17,        1,   608256, 0xd47b6b3c
+0,         18,         18,        1,   608256, 0xa5593d23
+0,         19,         19,        1,   608256, 0x01cd5642
+0,         20,         20,        1,   608256, 0x0c451611
+0,         21,         21,        1,   608256, 0xc4833ff5
+0,         22,         22,        1,   608256, 0xbed881fc
+0,         23,         23,        1,   608256, 0x709e77e6
+0,         24,         24,        1,   608256, 0x9815dad3
+0,         25,         25,        1,   608256, 0x55c1fe5f
+0,         26,         26,        1,   608256, 0xd89ff770
+0,         27,         27,        1,   608256, 0xc636abf7
+0,         28,         28,        1,   608256, 0x17d3f5b1
+0,         29,         29,        1,   608256, 0x0389cd38
+0,         30,         30,        1,   608256, 0x502eea66
+0,         31,         31,        1,   608256, 0xcb697a48
+0,         32,         32,        1,   608256, 0xd4f6c694
+0,         33,         33,        1,   608256, 0x734a5163
+0,         34,         34,        1,   608256, 0xa53f5187
+0,         35,         35,        1,   608256, 0x64d2c1c7
+0,         36,         36,        1,   608256, 0x41a170d0
+0,         37,         37,        1,   608256, 0x6f671fe1
+0,         38,         38,        1,   608256, 0x56983008
+0,         39,         39,        1,   608256, 0x95911957
+0,         40,         40,        1,   608256, 0x027f2a7a
+0,         41,         41,        1,   608256, 0xcd22d70f
+0,         42,         42,        1,   608256, 0x268beec0
+0,         43,         43,        1,   608256, 0xcf14123e
+0,         44,         44,        1,   608256, 0xfc8e3bff
+0,         45,         45,        1,   608256, 0x6974ad54
+0,         46,         46,        1,   608256, 0x8fbd9cdd
+0,         47,         47,        1,   608256, 0x66110ef8
+0,         48,         48,        1,   608256, 0x84b4b1f1
+0,         49,         49,        1,   608256, 0xf0d4949b
+0,         50,         50,        1,   608256, 0xee06377f
+0,         51,         51,        1,   608256, 0x9c22c5ee
+0,         52,         52,        1,   608256, 0x322abee2
+0,         53,         53,        1,   608256, 0x82745ed3
+0,         54,         54,        1,   608256, 0xe7b9248b
+0,         55,         55,        1,   608256, 0xc8c1ce0e
+0,         56,         56,        1,   608256, 0x8451eba9
+0,         57,         57,        1,   608256, 0xece9412d
+0,         58,         58,        1,   608256, 0xffbc2c24
+0,         59,         59,        1,   608256, 0xf58c117e
+0,         60,         60,        1,   608256, 0x7853f334
+0,         61,         61,        1,   608256, 0x1acd6465
+0,         62,         62,        1,   608256, 0xb668856c
+0,         63,         63,        1,   608256, 0x3f52c230
+0,         64,         64,        1,   608256, 0xd7e8b5b6
+0,         65,         65,        1,   608256, 0xf663681d
+0,         66,         66,        1,   608256, 0x07ef670c
+0,         67,         67,        1,   608256, 0x1d5084f4
+0,         68,         68,        1,   608256, 0x0ea3fe04
+0,         69,         69,        1,   608256, 0xf095d1e0
+0,         70,         70,        1,   608256, 0xbdac37fb
+0,         71,         71,        1,   608256, 0x2cbfdf91
+0,         72,         72,        1,   608256, 0x8da7190f
+0,         73,         73,        1,   608256, 0x08bf6fc9
+0,         74,         74,        1,   608256, 0xa2368e5c
+0,         75,         75,        1,   608256, 0x36d38f81
+0,         76,         76,        1,   608256, 0x94d344cc
+0,         77,         77,        1,   608256, 0x1cf33f86
+0,         78,         78,        1,   608256, 0x98d6341f
+0,         79,         79,        1,   608256, 0xb04e3a3a
+0,         80,         80,        1,   608256, 0x74e52483
+0,         81,         81,        1,   608256, 0x6acc8d96
+0,         82,         82,        1,   608256, 0x136d6c4e
+0,         83,         83,        1,   608256, 0x50efa37a
+0,         84,         84,        1,   608256, 0x53170421
+0,         85,         85,        1,   608256, 0x2ed5210e
+0,         86,         86,        1,   608256, 0x5f471854
+0,         87,         87,        1,   608256, 0xd6ff7856
+0,         88,         88,        1,   608256, 0x446bf456
+0,         89,         89,        1,   608256, 0x872b95b1
+0,         90,         90,        1,   608256, 0xc9e5e827
+0,         91,         91,        1,   608256, 0xdab3eb04
+0,         92,         92,        1,   608256, 0xccd6347e
+0,         93,         93,        1,   608256, 0xd7dfd0a9
+0,         94,         94,        1,   608256, 0x60b834c3
+0,         95,         95,        1,   608256, 0x0b822676
+0,         96,         96,        1,   608256, 0x0e5d3d5a
+0,         97,         97,        1,   608256, 0x1fa0233d
+0,         98,         98,        1,   608256, 0xb853b650
+0,         99,         99,        1,   608256, 0x30d8d033
diff --git a/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4 b/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4
new file mode 100644
index 0000000..84487a5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,  6144000, 0xf7da9a00
+0,          1,          1,        1,  6144000, 0xf5cfc76f
+0,          2,          2,        1,  6144000, 0x20663e82
+0,          3,          3,        1,  6144000, 0xbff3d1e7
+0,          4,          4,        1,  6144000, 0x6f1b824d
+0,          5,          5,        1,  6144000, 0x4d75e5c9
+0,          6,          6,        1,  6144000, 0xb4443853
+0,          7,          7,        1,  6144000, 0x6943bbcb
+0,          8,          8,        1,  6144000, 0x1748b8d3
+0,          9,          9,        1,  6144000, 0x0e15caec
+0,         10,         10,        1,  6144000, 0xf7553ff4
+0,         11,         11,        1,  6144000, 0x34007146
+0,         12,         12,        1,  6144000, 0xd115a7ad
+0,         13,         13,        1,  6144000, 0x1adc8d27
+0,         14,         14,        1,  6144000, 0x2c3a43a6
+0,         15,         15,        1,  6144000, 0x1820500a
+0,         16,         16,        1,  6144000, 0xb33cf5af
+0,         17,         17,        1,  6144000, 0x5ba58d5a
+0,         18,         18,        1,  6144000, 0x453f35bc
+0,         19,         19,        1,  6144000, 0x4e6ac2ab
+0,         20,         20,        1,  6144000, 0xfab2b132
+0,         21,         21,        1,  6144000, 0xf903b7bf
+0,         22,         22,        1,  6144000, 0x160ebf13
+0,         23,         23,        1,  6144000, 0xd147c884
+0,         24,         24,        1,  6144000, 0x266abc04
+0,         25,         25,        1,  6144000, 0x9fabf642
+0,         26,         26,        1,  6144000, 0x1ad4f6c7
+0,         27,         27,        1,  6144000, 0x41fa1e6f
+0,         28,         28,        1,  6144000, 0x14b2b3b4
+0,         29,         29,        1,  6144000, 0x19c6d13e
+0,         30,         30,        1,  6144000, 0x414f5a36
+0,         31,         31,        1,  6144000, 0x439278aa
+0,         32,         32,        1,  6144000, 0xf8e73a55
+0,         33,         33,        1,  6144000, 0xf4cf7779
+0,         34,         34,        1,  6144000, 0x86ac3a16
+0,         35,         35,        1,  6144000, 0xdc9abdb8
+0,         36,         36,        1,  6144000, 0x9ab68a62
+0,         37,         37,        1,  6144000, 0xcd290547
+0,         38,         38,        1,  6144000, 0xd2eb88bb
+0,         39,         39,        1,  6144000, 0x126e084e
+0,         40,         40,        1,  6144000, 0x1aa5302c
+0,         41,         41,        1,  6144000, 0x689cb93e
+0,         42,         42,        1,  6144000, 0xaa9e3be6
+0,         43,         43,        1,  6144000, 0x33dc9ead
+0,         44,         44,        1,  6144000, 0xcb943dd3
+0,         45,         45,        1,  6144000, 0x22a67b19
+0,         46,         46,        1,  6144000, 0x3bfb741a
+0,         47,         47,        1,  6144000, 0x9238e595
+0,         48,         48,        1,  6144000, 0xf0fb6381
+0,         49,         49,        1,  6144000, 0x6ea42af1
+0,         50,         50,        1,  6144000, 0x47d9c3a7
+0,         51,         51,        1,  6144000, 0x9f73966b
+0,         52,         52,        1,  6144000, 0xdf777adc
+0,         53,         53,        1,  6144000, 0xf51f206e
+0,         54,         54,        1,  6144000, 0x465c350a
+0,         55,         55,        1,  6144000, 0x9253a45a
+0,         56,         56,        1,  6144000, 0x72c89751
+0,         57,         57,        1,  6144000, 0x0405cdfc
+0,         58,         58,        1,  6144000, 0xc5ede0c7
+0,         59,         59,        1,  6144000, 0xcf1c2b5e
diff --git a/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4 b/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4
new file mode 100644
index 0000000..034f7b8
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,  6144000, 0xcd32ef33
+0,          1,          1,        1,  6144000, 0x58ce681d
+0,          2,          2,        1,  6144000, 0x77a732b6
+0,          3,          3,        1,  6144000, 0xa95418d0
+0,          4,          4,        1,  6144000, 0xa1593606
+0,          5,          5,        1,  6144000, 0x0d5429bc
+0,          6,          6,        1,  6144000, 0xe7cd205c
+0,          7,          7,        1,  6144000, 0x52c30ff4
+0,          8,          8,        1,  6144000, 0xf0a0f686
+0,          9,          9,        1,  6144000, 0xa6371d86
+0,         10,         10,        1,  6144000, 0x18bf1478
+0,         11,         11,        1,  6144000, 0xb84c6322
+0,         12,         12,        1,  6144000, 0x12f35f80
+0,         13,         13,        1,  6144000, 0xa9009e83
+0,         14,         14,        1,  6144000, 0x08568380
+0,         15,         15,        1,  6144000, 0xb01e98e8
+0,         16,         16,        1,  6144000, 0x0796ee90
+0,         17,         17,        1,  6144000, 0x3bb7cbef
+0,         18,         18,        1,  6144000, 0x7c3d6929
+0,         19,         19,        1,  6144000, 0x62c0e56c
+0,         20,         20,        1,  6144000, 0xd05907f7
+0,         21,         21,        1,  6144000, 0x9aa33b33
+0,         22,         22,        1,  6144000, 0xc47a0195
+0,         23,         23,        1,  6144000, 0xa5a5db13
+0,         24,         24,        1,  6144000, 0x54fda44b
+0,         25,         25,        1,  6144000, 0x7695be2f
+0,         26,         26,        1,  6144000, 0x247228e1
+0,         27,         27,        1,  6144000, 0xec38b2f7
+0,         28,         28,        1,  6144000, 0x223b098d
+0,         29,         29,        1,  6144000, 0xdd13f4bf
+0,         30,         30,        1,  6144000, 0x42651b46
+0,         31,         31,        1,  6144000, 0xc0b2ac9a
+0,         32,         32,        1,  6144000, 0x574908ee
+0,         33,         33,        1,  6144000, 0x070f0d88
+0,         34,         34,        1,  6144000, 0xc68ee679
+0,         35,         35,        1,  6144000, 0x4d571c82
+0,         36,         36,        1,  6144000, 0xec7f28cb
+0,         37,         37,        1,  6144000, 0x07ca3ccd
+0,         38,         38,        1,  6144000, 0xa5161fd7
+0,         39,         39,        1,  6144000, 0xb0908b25
+0,         40,         40,        1,  6144000, 0x4fa56c5e
+0,         41,         41,        1,  6144000, 0x1ad84207
+0,         42,         42,        1,  6144000, 0xc862a32b
+0,         43,         43,        1,  6144000, 0x341b9b0a
+0,         44,         44,        1,  6144000, 0xa940cdab
+0,         45,         45,        1,  6144000, 0x57521b2d
+0,         46,         46,        1,  6144000, 0x31969dee
+0,         47,         47,        1,  6144000, 0x7a09e240
+0,         48,         48,        1,  6144000, 0x14e6c360
+0,         49,         49,        1,  6144000, 0x0dfd6085
+0,         50,         50,        1,  6144000, 0xdf231a1e
+0,         51,         51,        1,  6144000, 0x6d1e9ce1
+0,         52,         52,        1,  6144000, 0xc6c2fb26
+0,         53,         53,        1,  6144000, 0xd4bc5e3e
+0,         54,         54,        1,  6144000, 0xa4a56b9e
+0,         55,         55,        1,  6144000, 0x8ba6349f
+0,         56,         56,        1,  6144000, 0x0683757f
+0,         57,         57,        1,  6144000, 0xe3840d8b
+0,         58,         58,        1,  6144000, 0x2fdf2ae6
+0,         59,         59,        1,  6144000, 0xea877e27
diff --git a/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon b/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon
new file mode 100644
index 0000000..6e17b83
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0x1559c293
+0,          1,          1,        1,  3110400, 0xd0802706
+0,          2,          2,        1,  3110400, 0xb48cf229
+0,          3,          3,        1,  3110400, 0x4108509b
+0,          4,          4,        1,  3110400, 0xd1cec277
+0,          5,          5,        1,  3110400, 0x3e68c589
+0,          6,          6,        1,  3110400, 0x1543a517
+0,          7,          7,        1,  3110400, 0x5ddcd669
+0,          8,          8,        1,  3110400, 0x09bd4c27
+0,          9,          9,        1,  3110400, 0xd583bfa1
+0,         10,         10,        1,  3110400, 0xe9411279
+0,         11,         11,        1,  3110400, 0xe07e6f3f
+0,         12,         12,        1,  3110400, 0xcfd23191
+0,         13,         13,        1,  3110400, 0x24276734
+0,         14,         14,        1,  3110400, 0x485aeafe
+0,         15,         15,        1,  3110400, 0xb8039a85
+0,         16,         16,        1,  3110400, 0x1d154e19
+0,         17,         17,        1,  3110400, 0xaa3ce800
+0,         18,         18,        1,  3110400, 0xe2601cba
+0,         19,         19,        1,  3110400, 0xb6657a57
+0,         20,         20,        1,  3110400, 0x34dbda52
+0,         21,         21,        1,  3110400, 0x921e218a
+0,         22,         22,        1,  3110400, 0x7de5262f
+0,         23,         23,        1,  3110400, 0x1a97e083
+0,         24,         24,        1,  3110400, 0x4bfc81d0
+0,         25,         25,        1,  3110400, 0x583396e6
+0,         26,         26,        1,  3110400, 0xc96bcd39
+0,         27,         27,        1,  3110400, 0x483cf7cf
+0,         28,         28,        1,  3110400, 0x20882e52
+0,         29,         29,        1,  3110400, 0x93d352fe
+0,         30,         30,        1,  3110400, 0x0c932722
+0,         31,         31,        1,  3110400, 0x78c5a9f0
+0,         32,         32,        1,  3110400, 0xcea3bddd
+0,         33,         33,        1,  3110400, 0x3e4e7c77
+0,         34,         34,        1,  3110400, 0xbe048a0a
+0,         35,         35,        1,  3110400, 0x1cf7ea0d
+0,         36,         36,        1,  3110400, 0xeb60343a
+0,         37,         37,        1,  3110400, 0x2158ed1f
+0,         38,         38,        1,  3110400, 0x3a7126b1
+0,         39,         39,        1,  3110400, 0x282804ff
+0,         40,         40,        1,  3110400, 0x292ed438
+0,         41,         41,        1,  3110400, 0x49a9769d
+0,         42,         42,        1,  3110400, 0xdfc12632
+0,         43,         43,        1,  3110400, 0xff3da16a
+0,         44,         44,        1,  3110400, 0x134b68c6
+0,         45,         45,        1,  3110400, 0x717e6f1d
+0,         46,         46,        1,  3110400, 0x283293f5
+0,         47,         47,        1,  3110400, 0x3d401456
+0,         48,         48,        1,  3110400, 0x500eddac
+0,         49,         49,        1,  3110400, 0x2a96fbff
+0,         50,         50,        1,  3110400, 0x9d75f303
+0,         51,         51,        1,  3110400, 0x08d1fa48
+0,         52,         52,        1,  3110400, 0xa685a8da
+0,         53,         53,        1,  3110400, 0xc19216d8
+0,         54,         54,        1,  3110400, 0x61ebd7f2
+0,         55,         55,        1,  3110400, 0x866c9002
+0,         56,         56,        1,  3110400, 0x3edda174
+0,         57,         57,        1,  3110400, 0x4e848db7
+0,         58,         58,        1,  3110400, 0x1dd822ba
+0,         59,         59,        1,  3110400, 0x8157b534
+0,         60,         60,        1,  3110400, 0x72637dbe
+0,         61,         61,        1,  3110400, 0xc6fc1305
+0,         62,         62,        1,  3110400, 0xbfadeee4
+0,         63,         63,        1,  3110400, 0xad20c230
+0,         64,         64,        1,  3110400, 0x5afff02b
+0,         65,         65,        1,  3110400, 0x5e533c71
+0,         66,         66,        1,  3110400, 0x52e10588
+0,         67,         67,        1,  3110400, 0x13a6dbb1
+0,         68,         68,        1,  3110400, 0xc74de5ae
+0,         69,         69,        1,  3110400, 0x382aafb8
+0,         70,         70,        1,  3110400, 0x5e0a11b2
+0,         71,         71,        1,  3110400, 0x049fe7cc
+0,         72,         72,        1,  3110400, 0x9d79484e
+0,         73,         73,        1,  3110400, 0x1116ced8
+0,         74,         74,        1,  3110400, 0x5d8d075d
+0,         75,         75,        1,  3110400, 0x49392496
+0,         76,         76,        1,  3110400, 0x5f24b3b3
+0,         77,         77,        1,  3110400, 0x6ca1c16d
+0,         78,         78,        1,  3110400, 0x131a16d2
+0,         79,         79,        1,  3110400, 0x39e2f9a1
+0,         80,         80,        1,  3110400, 0x988bd0ee
+0,         81,         81,        1,  3110400, 0xa6c050ec
+0,         82,         82,        1,  3110400, 0x5275142a
+0,         83,         83,        1,  3110400, 0x5705923d
+0,         84,         84,        1,  3110400, 0x3098d52d
+0,         85,         85,        1,  3110400, 0xb16e2eb7
+0,         86,         86,        1,  3110400, 0x0dee6bc8
+0,         87,         87,        1,  3110400, 0x577acf61
+0,         88,         88,        1,  3110400, 0x2b70d954
+0,         89,         89,        1,  3110400, 0x26b5f1c5
+0,         90,         90,        1,  3110400, 0x2351ad88
+0,         91,         91,        1,  3110400, 0xe5bdf6ad
+0,         92,         92,        1,  3110400, 0xaf0d83de
+0,         93,         93,        1,  3110400, 0xaee86799
+0,         94,         94,        1,  3110400, 0xe73fe067
+0,         95,         95,        1,  3110400, 0x46b90697
+0,         96,         96,        1,  3110400, 0xb270f77a
+0,         97,         97,        1,  3110400, 0xf33aa535
+0,         98,         98,        1,  3110400, 0xcafe6eec
+0,         99,         99,        1,  3110400, 0xcf051a31
diff --git a/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon b/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon
new file mode 100644
index 0000000..c1b7f2e
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0xf9342188
+0,          1,          1,        1,  3110400, 0x46638dc4
+0,          2,          2,        1,  3110400, 0x96da436e
+0,          3,          3,        1,  3110400, 0xae9ee064
+0,          4,          4,        1,  3110400, 0x03fc9d17
+0,          5,          5,        1,  3110400, 0xd7ba9ab8
+0,          6,          6,        1,  3110400, 0x9f3cc881
+0,          7,          7,        1,  3110400, 0x911c9e2a
+0,          8,          8,        1,  3110400, 0x2c1bdec1
+0,          9,          9,        1,  3110400, 0xffc2cfb2
+0,         10,         10,        1,  3110400, 0x34136d4c
+0,         11,         11,        1,  3110400, 0x400dca0c
+0,         12,         12,        1,  3110400, 0x5a3d3c71
+0,         13,         13,        1,  3110400, 0x5bd262f9
+0,         14,         14,        1,  3110400, 0x27bbec47
+0,         15,         15,        1,  3110400, 0x53ca3f78
+0,         16,         16,        1,  3110400, 0x7fee4170
+0,         17,         17,        1,  3110400, 0x393d318c
+0,         18,         18,        1,  3110400, 0x203f26f1
+0,         19,         19,        1,  3110400, 0x35e00c3e
+0,         20,         20,        1,  3110400, 0x995afdde
+0,         21,         21,        1,  3110400, 0xa8b623b9
+0,         22,         22,        1,  3110400, 0x047e53bd
+0,         23,         23,        1,  3110400, 0xc7e69515
+0,         24,         24,        1,  3110400, 0x7e5ade49
+0,         25,         25,        1,  3110400, 0x863cddc9
+0,         26,         26,        1,  3110400, 0xb1f6189c
+0,         27,         27,        1,  3110400, 0x622d6d1d
+0,         28,         28,        1,  3110400, 0x1e82ef1a
+0,         29,         29,        1,  3110400, 0x06a7054a
+0,         30,         30,        1,  3110400, 0x736bd4a9
+0,         31,         31,        1,  3110400, 0x1db8ead3
+0,         32,         32,        1,  3110400, 0x1d872697
+0,         33,         33,        1,  3110400, 0x86b11604
+0,         34,         34,        1,  3110400, 0x54bee045
+0,         35,         35,        1,  3110400, 0x3577fa15
+0,         36,         36,        1,  3110400, 0x717b6c0b
+0,         37,         37,        1,  3110400, 0x5e0f0b6e
+0,         38,         38,        1,  3110400, 0x054ecc86
+0,         39,         39,        1,  3110400, 0x9ec29ad1
+0,         40,         40,        1,  3110400, 0x7c3b56e4
+0,         41,         41,        1,  3110400, 0xcf4cf721
+0,         42,         42,        1,  3110400, 0x43c01adb
+0,         43,         43,        1,  3110400, 0x6abb4879
+0,         44,         44,        1,  3110400, 0x90473c9f
+0,         45,         45,        1,  3110400, 0x5f5bb9a9
+0,         46,         46,        1,  3110400, 0x08678e6b
+0,         47,         47,        1,  3110400, 0xf4ad0c9b
+0,         48,         48,        1,  3110400, 0x22870cc8
+0,         49,         49,        1,  3110400, 0xb417cf63
+0,         50,         50,        1,  3110400, 0xb7a1588e
+0,         51,         51,        1,  3110400, 0x7a35ac81
+0,         52,         52,        1,  3110400, 0xcd1c6d82
+0,         53,         53,        1,  3110400, 0x181b9920
+0,         54,         54,        1,  3110400, 0xf2417d5e
+0,         55,         55,        1,  3110400, 0x8a67e02b
+0,         56,         56,        1,  3110400, 0xe7b99077
+0,         57,         57,        1,  3110400, 0x6814e5c2
+0,         58,         58,        1,  3110400, 0xd8bce44d
+0,         59,         59,        1,  3110400, 0x9faf4ebc
+0,         60,         60,        1,  3110400, 0x3daa5fbf
+0,         61,         61,        1,  3110400, 0x747921ba
+0,         62,         62,        1,  3110400, 0xbe30214e
+0,         63,         63,        1,  3110400, 0x8f5533fe
+0,         64,         64,        1,  3110400, 0x835a4545
+0,         65,         65,        1,  3110400, 0xfa99f4c8
+0,         66,         66,        1,  3110400, 0x9559c5db
+0,         67,         67,        1,  3110400, 0xd0d096f8
+0,         68,         68,        1,  3110400, 0x7b24dbb0
+0,         69,         69,        1,  3110400, 0x4a8aa189
+0,         70,         70,        1,  3110400, 0x876bab32
+0,         71,         71,        1,  3110400, 0xc930bec9
+0,         72,         72,        1,  3110400, 0x009841d8
+0,         73,         73,        1,  3110400, 0x93e5be89
+0,         74,         74,        1,  3110400, 0x82260331
+0,         75,         75,        1,  3110400, 0x7ef2e971
+0,         76,         76,        1,  3110400, 0x606b638a
+0,         77,         77,        1,  3110400, 0xf08b84df
+0,         78,         78,        1,  3110400, 0x8a609222
+0,         79,         79,        1,  3110400, 0xa76cb2f3
+0,         80,         80,        1,  3110400, 0x2b611cb3
+0,         81,         81,        1,  3110400, 0x81d5b315
+0,         82,         82,        1,  3110400, 0x6f385e43
+0,         83,         83,        1,  3110400, 0x5959a754
+0,         84,         84,        1,  3110400, 0x1cf4935c
+0,         85,         85,        1,  3110400, 0xc8da3639
+0,         86,         86,        1,  3110400, 0x50a2ee3d
+0,         87,         87,        1,  3110400, 0xd33ad53a
+0,         88,         88,        1,  3110400, 0xe7ed4eff
+0,         89,         89,        1,  3110400, 0x7d72d260
+0,         90,         90,        1,  3110400, 0x16ca295b
+0,         91,         91,        1,  3110400, 0xf126df1d
+0,         92,         92,        1,  3110400, 0x0aca09d1
+0,         93,         93,        1,  3110400, 0x6aefb52b
+0,         94,         94,        1,  3110400, 0xf797ee6d
+0,         95,         95,        1,  3110400, 0xf1053ace
+0,         96,         96,        1,  3110400, 0xf7f91618
+0,         97,         97,        1,  3110400, 0xc711acf8
+0,         98,         98,        1,  3110400, 0x31123f40
+0,         99,         99,        1,  3110400, 0xc7b703dc
diff --git a/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3 b/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3
new file mode 100644
index 0000000..71ce9c7
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0xa5d2b8b0
+0,          1,          1,        1,  3110400, 0x13035cfa
+0,          2,          2,        1,  3110400, 0x96b16f86
+0,          3,          3,        1,  3110400, 0x09e96331
+0,          4,          4,        1,  3110400, 0xd2662da8
+0,          5,          5,        1,  3110400, 0x77d3db00
+0,          6,          6,        1,  3110400, 0xaa025e5b
+0,          7,          7,        1,  3110400, 0x77284bc5
+0,          8,          8,        1,  3110400, 0x625b165e
+0,          9,          9,        1,  3110400, 0x69c0b4c8
+0,         10,         10,        1,  3110400, 0x52e627a4
+0,         11,         11,        1,  3110400, 0x774eaf6a
+0,         12,         12,        1,  3110400, 0xa9042cad
+0,         13,         13,        1,  3110400, 0xf367e96a
+0,         14,         14,        1,  3110400, 0x4687e2d9
+0,         15,         15,        1,  3110400, 0xe57d46b8
+0,         16,         16,        1,  3110400, 0x074da0b5
+0,         17,         17,        1,  3110400, 0xbf8dd856
+0,         18,         18,        1,  3110400, 0xb9cae21e
+0,         19,         19,        1,  3110400, 0xa43687fc
+0,         20,         20,        1,  3110400, 0x83cce559
+0,         21,         21,        1,  3110400, 0xb19963d9
+0,         22,         22,        1,  3110400, 0x636d69b7
+0,         23,         23,        1,  3110400, 0xfcfe1a00
+0,         24,         24,        1,  3110400, 0x0a804c37
+0,         25,         25,        1,  3110400, 0x6af0c5ec
+0,         26,         26,        1,  3110400, 0xccec0692
+0,         27,         27,        1,  3110400, 0x0547e98d
+0,         28,         28,        1,  3110400, 0xc4dc2caa
+0,         29,         29,        1,  3110400, 0x43473ac6
+0,         30,         30,        1,  3110400, 0xd5e9a795
+0,         31,         31,        1,  3110400, 0x3227df7b
+0,         32,         32,        1,  3110400, 0x087e57bb
+0,         33,         33,        1,  3110400, 0x892f5ad0
+0,         34,         34,        1,  3110400, 0xeeb23459
+0,         35,         35,        1,  3110400, 0xd1efe2a6
+0,         36,         36,        1,  3110400, 0x5abd5104
+0,         37,         37,        1,  3110400, 0x6b018b83
+0,         38,         38,        1,  3110400, 0x91617ca7
+0,         39,         39,        1,  3110400, 0x601cd6ad
+0,         40,         40,        1,  3110400, 0xf81cb126
+0,         41,         41,        1,  3110400, 0x4bb949df
+0,         42,         42,        1,  3110400, 0xed94fea0
+0,         43,         43,        1,  3110400, 0x39ba8fec
+0,         44,         44,        1,  3110400, 0xc65e113c
+0,         45,         45,        1,  3110400, 0x627344cb
+0,         46,         46,        1,  3110400, 0x5680c16a
+0,         47,         47,        1,  3110400, 0x12d02cfc
+0,         48,         48,        1,  3110400, 0x2e409afa
+0,         49,         49,        1,  3110400, 0xfd4142f2
+0,         50,         50,        1,  3110400, 0x6db3965a
+0,         51,         51,        1,  3110400, 0x578962c5
+0,         52,         52,        1,  3110400, 0x68d75bd1
+0,         53,         53,        1,  3110400, 0x568fbb72
+0,         54,         54,        1,  3110400, 0xf3c03b95
+0,         55,         55,        1,  3110400, 0xeb67b532
+0,         56,         56,        1,  3110400, 0x0e445b34
+0,         57,         57,        1,  3110400, 0x32c04ad2
+0,         58,         58,        1,  3110400, 0x239d1a14
+0,         59,         59,        1,  3110400, 0xcb295635
+0,         60,         60,        1,  3110400, 0x7e347c1d
+0,         61,         61,        1,  3110400, 0x74e1fcf7
+0,         62,         62,        1,  3110400, 0x6e399603
+0,         63,         63,        1,  3110400, 0xe3bbdbcd
+0,         64,         64,        1,  3110400, 0xddd336f3
+0,         65,         65,        1,  3110400, 0x7834e9f7
+0,         66,         66,        1,  3110400, 0xb53a7f1f
+0,         67,         67,        1,  3110400, 0x1f52cbb6
+0,         68,         68,        1,  3110400, 0xea26692a
+0,         69,         69,        1,  3110400, 0xa4e1765f
+0,         70,         70,        1,  3110400, 0x6367794d
+0,         71,         71,        1,  3110400, 0x69bff6d1
+0,         72,         72,        1,  3110400, 0xdf52ef08
+0,         73,         73,        1,  3110400, 0x002892b7
+0,         74,         74,        1,  3110400, 0x1ca49791
+0,         75,         75,        1,  3110400, 0x8de95d1d
+0,         76,         76,        1,  3110400, 0x9c9c38cf
+0,         77,         77,        1,  3110400, 0x9f9947cd
+0,         78,         78,        1,  3110400, 0xe5da908b
+0,         79,         79,        1,  3110400, 0x032415ae
+0,         80,         80,        1,  3110400, 0x0fef3a03
+0,         81,         81,        1,  3110400, 0xd04c1b77
+0,         82,         82,        1,  3110400, 0x5d46813b
+0,         83,         83,        1,  3110400, 0x1dbeaa76
+0,         84,         84,        1,  3110400, 0x2b2eea1a
+0,         85,         85,        1,  3110400, 0x7138da47
+0,         86,         86,        1,  3110400, 0xe9a43ef8
+0,         87,         87,        1,  3110400, 0x02f7b1bf
+0,         88,         88,        1,  3110400, 0xd1cdf8b1
+0,         89,         89,        1,  3110400, 0x2e924022
+0,         90,         90,        1,  3110400, 0x59d68bcf
+0,         91,         91,        1,  3110400, 0x3dc70503
+0,         92,         92,        1,  3110400, 0x26aeb1fa
+0,         93,         93,        1,  3110400, 0x91434f9d
+0,         94,         94,        1,  3110400, 0x91411f14
+0,         95,         95,        1,  3110400, 0xd99a172a
+0,         96,         96,        1,  3110400, 0x19678f5a
+0,         97,         97,        1,  3110400, 0xc6c357ae
+0,         98,         98,        1,  3110400, 0xba6cd89f
+0,         99,         99,        1,  3110400, 0x657af6cf
diff --git a/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4 b/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4
new file mode 100644
index 0000000..59115fb
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x88619f80
+0,          1,          1,        1,   149760, 0x550bdaf0
+0,          2,          2,        1,   149760, 0xb769fa4c
+0,          3,          3,        1,   149760, 0x3c2c2e9a
+0,          4,          4,        1,   149760, 0x75316bcc
+0,          5,          5,        1,   149760, 0x7b9ba7ff
+0,          6,          6,        1,   149760, 0x9981ea7b
+0,          7,          7,        1,   149760, 0x3f682105
+0,          8,          8,        1,   149760, 0x63252c25
+0,          9,          9,        1,   149760, 0x44427967
+0,         10,         10,        1,   149760, 0x24199a9e
+0,         11,         11,        1,   149760, 0xaa30c241
+0,         12,         12,        1,   149760, 0xf24faaaf
+0,         13,         13,        1,   149760, 0x0291c766
+0,         14,         14,        1,   149760, 0xb826e44f
+0,         15,         15,        1,   149760, 0xbc2310b8
+0,         16,         16,        1,   149760, 0xcfd81d4a
+0,         17,         17,        1,   149760, 0xb356484a
+0,         18,         18,        1,   149760, 0x02bf515a
+0,         19,         19,        1,   149760, 0x729d778c
+0,         20,         20,        1,   149760, 0x3ade8453
+0,         21,         21,        1,   149760, 0xfedead3d
+0,         22,         22,        1,   149760, 0x46bfc8db
+0,         23,         23,        1,   149760, 0x8590f422
+0,         24,         24,        1,   149760, 0x6d2dfd9d
+0,         25,         25,        1,   149760, 0x373f2c82
+0,         26,         26,        1,   149760, 0xa12f3ca1
+0,         27,         27,        1,   149760, 0x34be4b0d
+0,         28,         28,        1,   149760, 0x24f538b9
+0,         29,         29,        1,   149760, 0xd1616303
diff --git a/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4 b/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4
new file mode 100644
index 0000000..1f998c4
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4
@@ -0,0 +1,42 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xcfffa013
+0,          1,          1,        1,   149760, 0x5166146a
+0,          2,          2,        1,   149760, 0xc3cc318e
+0,          3,          3,        1,   149760, 0x5bb465f9
+0,          4,          4,        1,   149760, 0x10c97bd4
+0,          5,          5,        1,   149760, 0xd9d5c4ab
+0,          6,          6,        1,   149760, 0x5112e11d
+0,          7,          7,        1,   149760, 0xde3803d6
+0,          8,          8,        1,   149760, 0x82c62409
+0,          9,          9,        1,   149760, 0x28f88d53
+0,         10,         10,        1,   149760, 0x796fb89d
+0,         11,         11,        1,   149760, 0x1b95dd75
+0,         12,         12,        1,   149760, 0xfcc9ced4
+0,         13,         13,        1,   149760, 0x6b00ee9c
+0,         14,         14,        1,   149760, 0xdb72e81a
+0,         15,         15,        1,   149760, 0x0c771a25
+0,         16,         16,        1,   149760, 0x959a2215
+0,         17,         17,        1,   149760, 0xf1d672ce
+0,         18,         18,        1,   149760, 0x2f407a06
+0,         19,         19,        1,   149760, 0xee389f83
+0,         20,         20,        1,   149760, 0x2e0695dd
+0,         21,         21,        1,   149760, 0xf80ac1eb
+0,         22,         22,        1,   149760, 0x29decec4
+0,         23,         23,        1,   149760, 0xff34eb5e
+0,         24,         24,        1,   149760, 0x1c85fe71
+0,         25,         25,        1,   149760, 0x056dae51
+0,         26,         26,        1,   149760, 0x78a99f1d
+0,         27,         27,        1,   149760, 0xe507b40c
+0,         28,         28,        1,   149760, 0xbd3fa06c
+0,         29,         29,        1,   149760, 0x3475d95b
+0,         30,         30,        1,   149760, 0x9b25d416
+0,         31,         31,        1,   149760, 0x73c4ec88
+0,         32,         32,        1,   149760, 0xd4437e12
+0,         33,         33,        1,   149760, 0xcf08c736
+0,         34,         34,        1,   149760, 0x0cedd0d6
+0,         35,         35,        1,   149760, 0xc317e9bc
+0,         36,         36,        1,   149760, 0x0dcbd636
+0,         37,         37,        1,   149760, 0x4e6501b0
+0,         38,         38,        1,   149760, 0x5f9c02bb
+0,         39,         39,        1,   149760, 0x43052939
+0,         40,         40,        1,   149760, 0x8ec12318
diff --git a/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4 b/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4
new file mode 100644
index 0000000..16d3446
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x8087662a
+0,          1,          1,        1,   599040, 0x5278d8db
+0,          2,          2,        1,   599040, 0x73c74090
+0,          3,          3,        1,   599040, 0xde0d8317
+0,          4,          4,        1,   599040, 0xd9d4c26c
+0,          5,          5,        1,   599040, 0x603a10bd
+0,          6,          6,        1,   599040, 0xa91e9b91
+0,          7,          7,        1,   599040, 0x73567e6a
+0,          8,          8,        1,   599040, 0x67912cc6
+0,          9,          9,        1,   599040, 0x98d3fb2c
+0,         10,         10,        1,   599040, 0x50c6d7fc
+0,         11,         11,        1,   599040, 0x8ae23020
+0,         12,         12,        1,   599040, 0x9eaa976f
+0,         13,         13,        1,   599040, 0x3cadf6c0
+0,         14,         14,        1,   599040, 0x7d498902
+0,         15,         15,        1,   599040, 0x525decac
+0,         16,         16,        1,   599040, 0x081485cc
+0,         17,         17,        1,   599040, 0x3fd6ba7a
+0,         18,         18,        1,   599040, 0x8bbbaa4c
+0,         19,         19,        1,   599040, 0x9e60a407
+0,         20,         20,        1,   599040, 0x394becb9
+0,         21,         21,        1,   599040, 0x068dffb5
+0,         22,         22,        1,   599040, 0x531fd221
+0,         23,         23,        1,   599040, 0x3aa6922e
+0,         24,         24,        1,   599040, 0x089d2456
+0,         25,         25,        1,   599040, 0x7c432995
+0,         26,         26,        1,   599040, 0x3693613d
+0,         27,         27,        1,   599040, 0x8b6d902f
+0,         28,         28,        1,   599040, 0x7c9a947b
+0,         29,         29,        1,   599040, 0x51d9e4c6
+0,         30,         30,        1,   599040, 0xdc7f62f3
+0,         31,         31,        1,   599040, 0x9da6cba0
+0,         32,         32,        1,   599040, 0x1bef8581
+0,         33,         33,        1,   599040, 0xc19c4211
+0,         34,         34,        1,   599040, 0x7824188e
+0,         35,         35,        1,   599040, 0xd0511050
+0,         36,         36,        1,   599040, 0x39d93e78
+0,         37,         37,        1,   599040, 0x1e0dc88e
+0,         38,         38,        1,   599040, 0x2cd7522e
+0,         39,         39,        1,   599040, 0x538928a5
+0,         40,         40,        1,   599040, 0x95549fb2
+0,         41,         41,        1,   599040, 0x1f57d5c1
+0,         42,         42,        1,   599040, 0xc99fa8c6
+0,         43,         43,        1,   599040, 0x567f4e7e
+0,         44,         44,        1,   599040, 0x23d3d54f
+0,         45,         45,        1,   599040, 0xe8f74d97
+0,         46,         46,        1,   599040, 0xd2b03a4d
+0,         47,         47,        1,   599040, 0xe59c4faf
+0,         48,         48,        1,   599040, 0x46da921d
+0,         49,         49,        1,   599040, 0x7a344fa3
+0,         50,         50,        1,   599040, 0xbc736fd4
+0,         51,         51,        1,   599040, 0xfe5c362c
+0,         52,         52,        1,   599040, 0x115ed271
+0,         53,         53,        1,   599040, 0x3c4913fc
+0,         54,         54,        1,   599040, 0x1e1f8114
+0,         55,         55,        1,   599040, 0x08c06e58
+0,         56,         56,        1,   599040, 0x599f07f6
+0,         57,         57,        1,   599040, 0xc922a0c9
+0,         58,         58,        1,   599040, 0xc77b5201
+0,         59,         59,        1,   599040, 0x4c2cde6d
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4 b/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4
new file mode 100644
index 0000000..53b621b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x001f0c48
+0,          1,          1,        1,   599040, 0x83120d87
+0,          2,          2,        1,   599040, 0x10c267aa
+0,          3,          3,        1,   599040, 0xef591aef
+0,          4,          4,        1,   599040, 0xded62c79
+0,          5,          5,        1,   599040, 0xe7c1c748
+0,          6,          6,        1,   599040, 0x14db55d0
+0,          7,          7,        1,   599040, 0x73c4156b
+0,          8,          8,        1,   599040, 0x0cec903c
+0,          9,          9,        1,   599040, 0x791029a0
+0,         10,         10,        1,   599040, 0x0fe72908
+0,         11,         11,        1,   599040, 0xd0ebe0be
+0,         12,         12,        1,   599040, 0x473cb5aa
+0,         13,         13,        1,   599040, 0xe774cf8c
+0,         14,         14,        1,   599040, 0x3d63909f
+0,         15,         15,        1,   599040, 0xe05af465
+0,         16,         16,        1,   599040, 0x9679aa54
+0,         17,         17,        1,   599040, 0xe9d2ef49
+0,         18,         18,        1,   599040, 0x1e797cac
+0,         19,         19,        1,   599040, 0xf3d51077
+0,         20,         20,        1,   599040, 0x74e3b5e0
+0,         21,         21,        1,   599040, 0xb97e5178
+0,         22,         22,        1,   599040, 0x7c79a425
+0,         23,         23,        1,   599040, 0xfeeedb62
+0,         24,         24,        1,   599040, 0x8d5a3686
+0,         25,         25,        1,   599040, 0x3f6109e4
+0,         26,         26,        1,   599040, 0x365df50e
+0,         27,         27,        1,   599040, 0xd65876a1
+0,         28,         28,        1,   599040, 0xfa21e766
+0,         29,         29,        1,   599040, 0x2f24ed68
+0,         30,         30,        1,   599040, 0x0e90e5d4
+0,         31,         31,        1,   599040, 0xd044eb9c
+0,         32,         32,        1,   599040, 0xe55e8b18
+0,         33,         33,        1,   599040, 0xa92b93b6
+0,         34,         34,        1,   599040, 0x9b6827c6
+0,         35,         35,        1,   599040, 0x486e155b
+0,         36,         36,        1,   599040, 0xbff46adc
+0,         37,         37,        1,   599040, 0x61637615
+0,         38,         38,        1,   599040, 0xc0423ea9
+0,         39,         39,        1,   599040, 0xda80f8d8
+0,         40,         40,        1,   599040, 0xe0f77fcc
+0,         41,         41,        1,   599040, 0x68bef4cf
+0,         42,         42,        1,   599040, 0xd2e0699b
+0,         43,         43,        1,   599040, 0xcc6cd663
+0,         44,         44,        1,   599040, 0x00ed2594
+0,         45,         45,        1,   599040, 0x140b6efb
+0,         46,         46,        1,   599040, 0xa418f9d0
+0,         47,         47,        1,   599040, 0x500083a3
+0,         48,         48,        1,   599040, 0x619045ec
+0,         49,         49,        1,   599040, 0xdf0ce1e6
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4 b/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4
new file mode 100644
index 0000000..9aeb3b1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x001f0c48
+0,          1,          1,        1,   599040, 0xf8160d82
+0,          2,          2,        1,   599040, 0x5f2060e2
+0,          3,          3,        1,   599040, 0x421104a7
+0,          4,          4,        1,   599040, 0xded62c79
+0,          5,          5,        1,   599040, 0x782b4517
+0,          6,          6,        1,   599040, 0xcf47861d
+0,          7,          7,        1,   599040, 0xd401373c
+0,          8,          8,        1,   599040, 0x0cec903c
+0,          9,          9,        1,   599040, 0x2dec6230
+0,         10,         10,        1,   599040, 0xe8d25791
+0,         11,         11,        1,   599040, 0x243af0ad
+0,         12,         12,        1,   599040, 0x4f77c47b
+0,         13,         13,        1,   599040, 0x9777f7c4
+0,         14,         14,        1,   599040, 0xc5c5be51
+0,         15,         15,        1,   599040, 0xb9b27b63
+0,         16,         16,        1,   599040, 0xc333f76b
+0,         17,         17,        1,   599040, 0x6bd00f09
+0,         18,         18,        1,   599040, 0x7f76875d
+0,         19,         19,        1,   599040, 0xc9e80bec
+0,         20,         20,        1,   599040, 0x8681b48f
+0,         21,         21,        1,   599040, 0xefaa5077
+0,         22,         22,        1,   599040, 0x73cc72a4
+0,         23,         23,        1,   599040, 0x55c8bc27
+0,         24,         24,        1,   599040, 0x9d84419d
+0,         25,         25,        1,   599040, 0x89db2dfe
+0,         26,         26,        1,   599040, 0x39a012fe
+0,         27,         27,        1,   599040, 0x9ae88b01
+0,         28,         28,        1,   599040, 0x0928f3d0
+0,         29,         29,        1,   599040, 0x39359eb1
+0,         30,         30,        1,   599040, 0x3e00a5b5
+0,         31,         31,        1,   599040, 0xaf1b1809
+0,         32,         32,        1,   599040, 0xe55e8b18
+0,         33,         33,        1,   599040, 0xa4739b3d
+0,         34,         34,        1,   599040, 0x224d47d4
+0,         35,         35,        1,   599040, 0x3ce1d830
+0,         36,         36,        1,   599040, 0xd3b33990
+0,         37,         37,        1,   599040, 0x15c3ae0e
+0,         38,         38,        1,   599040, 0xcce735aa
+0,         39,         39,        1,   599040, 0x173d8406
+0,         40,         40,        1,   599040, 0xe0f77fcc
+0,         41,         41,        1,   599040, 0xbeefe9eb
+0,         42,         42,        1,   599040, 0xb3d761cf
+0,         43,         43,        1,   599040, 0x75ffe5f0
+0,         44,         44,        1,   599040, 0xf446226e
+0,         45,         45,        1,   599040, 0xf425475a
+0,         46,         46,        1,   599040, 0x5180ee65
+0,         47,         47,        1,   599040, 0x5edb78f9
+0,         48,         48,        1,   599040, 0x28eb41c5
+0,         49,         49,        1,   599040, 0x0d65d9d3
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3
new file mode 100644
index 0000000..c891c44
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x2b58dee2
+0,          1,          1,        1,   599040, 0x2b58dee2
+0,          2,          2,        1,   599040, 0xcd9295f4
+0,          3,          3,        1,   599040, 0xc052f81f
+0,          4,          4,        1,   599040, 0xfe5932ed
+0,          5,          5,        1,   599040, 0x8a8aa4b9
+0,          6,          6,        1,   599040, 0x6ac33b24
+0,          7,          7,        1,   599040, 0xd053bb83
+0,          8,          8,        1,   599040, 0xa9cf6ba6
+0,          9,          9,        1,   599040, 0x3d5a1a3b
+0,         10,         10,        1,   599040, 0x90997f48
+0,         11,         11,        1,   599040, 0xc99390bd
+0,         12,         12,        1,   599040, 0x9723079d
+0,         13,         13,        1,   599040, 0x7f0fe29b
+0,         14,         14,        1,   599040, 0x778afdb4
+0,         15,         15,        1,   599040, 0x72963905
+0,         16,         16,        1,   599040, 0xa677b29c
+0,         17,         17,        1,   599040, 0x88bdccd8
+0,         18,         18,        1,   599040, 0x8be37199
+0,         19,         19,        1,   599040, 0x6628117a
+0,         20,         20,        1,   599040, 0xefa701b0
+0,         21,         21,        1,   599040, 0x75d6705d
+0,         22,         22,        1,   599040, 0x85242d6f
+0,         23,         23,        1,   599040, 0xd559eaa6
+0,         24,         24,        1,   599040, 0xe0663879
+0,         25,         25,        1,   599040, 0x3255d67c
+0,         26,         26,        1,   599040, 0xf41a4d73
+0,         27,         27,        1,   599040, 0xda630d57
+0,         28,         28,        1,   599040, 0x7b8eec79
+0,         29,         29,        1,   599040, 0x70dff7a6
+0,         30,         30,        1,   599040, 0x4b600806
+0,         31,         31,        1,   599040, 0xdcbbc54d
+0,         32,         32,        1,   599040, 0x7e6e66b4
+0,         33,         33,        1,   599040, 0x645ce246
+0,         34,         34,        1,   599040, 0x03d3117c
+0,         35,         35,        1,   599040, 0x7c3cab88
+0,         36,         36,        1,   599040, 0x5cdaeeef
+0,         37,         37,        1,   599040, 0x4cce6d93
+0,         38,         38,        1,   599040, 0x78c28e4c
+0,         39,         39,        1,   599040, 0x8acbe642
+0,         40,         40,        1,   599040, 0xcd0a39f8
+0,         41,         41,        1,   599040, 0x9c580311
+0,         42,         42,        1,   599040, 0x668eab11
+0,         43,         43,        1,   599040, 0xc76f6206
+0,         44,         44,        1,   599040, 0xe0baf2a2
+0,         45,         45,        1,   599040, 0x430db206
+0,         46,         46,        1,   599040, 0x9c1565ad
+0,         47,         47,        1,   599040, 0xfc302be0
+0,         48,         48,        1,   599040, 0x6ccfc206
+0,         49,         49,        1,   599040, 0x46c7722d
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3
new file mode 100644
index 0000000..0294a7e
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x2b58dee2
+0,          1,          1,        1,   599040, 0x2b58dee2
+0,          2,          2,        1,   599040, 0xb055b638
+0,          3,          3,        1,   599040, 0x3e2b06c9
+0,          4,          4,        1,   599040, 0xa0e53610
+0,          5,          5,        1,   599040, 0x5f6eca50
+0,          6,          6,        1,   599040, 0x516e679d
+0,          7,          7,        1,   599040, 0xdbbbf791
+0,          8,          8,        1,   599040, 0x04be5abc
+0,          9,          9,        1,   599040, 0x85283636
+0,         10,         10,        1,   599040, 0x1bcdb857
+0,         11,         11,        1,   599040, 0x258bb8a8
+0,         12,         12,        1,   599040, 0x33340003
+0,         13,         13,        1,   599040, 0xa2cc0dc3
+0,         14,         14,        1,   599040, 0x2b83400f
+0,         15,         15,        1,   599040, 0xf33ba886
+0,         16,         16,        1,   599040, 0x73f43f10
+0,         17,         17,        1,   599040, 0x63ff4628
+0,         18,         18,        1,   599040, 0x41170243
+0,         19,         19,        1,   599040, 0x84f34b72
+0,         20,         20,        1,   599040, 0x4913e415
+0,         21,         21,        1,   599040, 0x38cfaac3
+0,         22,         22,        1,   599040, 0xb2f0650c
+0,         23,         23,        1,   599040, 0xe0d12249
+0,         24,         24,        1,   599040, 0xca931ca0
+0,         25,         25,        1,   599040, 0xfc14d1cb
+0,         26,         26,        1,   599040, 0xb74667d8
+0,         27,         27,        1,   599040, 0xfdc22b8b
+0,         28,         28,        1,   599040, 0x30b425eb
+0,         29,         29,        1,   599040, 0xc31f3b73
+0,         30,         30,        1,   599040, 0xefda0062
+0,         31,         31,        1,   599040, 0x8fe0d742
+0,         32,         32,        1,   599040, 0xdaa54d1d
+0,         33,         33,        1,   599040, 0x2188ae4b
+0,         34,         34,        1,   599040, 0x7ef0f088
+0,         35,         35,        1,   599040, 0xcfd2619f
+0,         36,         36,        1,   599040, 0x3b0fca50
+0,         37,         37,        1,   599040, 0x78746df2
+0,         38,         38,        1,   599040, 0xdc917e1b
+0,         39,         39,        1,   599040, 0xc6cf2732
+0,         40,         40,        1,   599040, 0xdbd2f5f2
+0,         41,         41,        1,   599040, 0x45a8cba3
+0,         42,         42,        1,   599040, 0xe276b712
+0,         43,         43,        1,   599040, 0x36057004
+0,         44,         44,        1,   599040, 0xe0da7e77
+0,         45,         45,        1,   599040, 0x823e7c30
+0,         46,         46,        1,   599040, 0x62c9457a
+0,         47,         47,        1,   599040, 0xf6743a30
+0,         48,         48,        1,   599040, 0x8db4f476
+0,         49,         49,        1,   599040, 0x79537927
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3
new file mode 100644
index 0000000..430426b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x1cf21d79
+0,          1,          1,        1,   599040, 0x1cf21d79
+0,          2,          2,        1,   599040, 0xb54ee9e0
+0,          3,          3,        1,   599040, 0x757f33f0
+0,          4,          4,        1,   599040, 0x783e06bc
+0,          5,          5,        1,   599040, 0x73127ae7
+0,          6,          6,        1,   599040, 0x52f86193
+0,          7,          7,        1,   599040, 0x8e8afa2c
+0,          8,          8,        1,   599040, 0x29359620
+0,          9,          9,        1,   599040, 0x23f46fd3
+0,         10,         10,        1,   599040, 0x00c9d47d
+0,         11,         11,        1,   599040, 0xcabcca8d
+0,         12,         12,        1,   599040, 0x02e92d89
+0,         13,         13,        1,   599040, 0x3e97268f
+0,         14,         14,        1,   599040, 0xba6230c2
+0,         15,         15,        1,   599040, 0x4393aa3b
+0,         16,         16,        1,   599040, 0x06b1b9c8
+0,         17,         17,        1,   599040, 0xcc2aa30b
+0,         18,         18,        1,   599040, 0x3e029a11
+0,         19,         19,        1,   599040, 0x0ec1fc36
+0,         20,         20,        1,   599040, 0xd61dd438
+0,         21,         21,        1,   599040, 0xa7b1816b
+0,         22,         22,        1,   599040, 0xa98ef225
+0,         23,         23,        1,   599040, 0x368912ca
+0,         24,         24,        1,   599040, 0x1ae95cbe
+0,         25,         25,        1,   599040, 0x0e01f8ed
+0,         26,         26,        1,   599040, 0x05497937
+0,         27,         27,        1,   599040, 0x735c2420
+0,         28,         28,        1,   599040, 0x0ef80004
+0,         29,         29,        1,   599040, 0xd744091b
+0,         30,         30,        1,   599040, 0x0f3b1576
+0,         31,         31,        1,   599040, 0x24e4fab9
+0,         32,         32,        1,   599040, 0x6b5d7fca
+0,         33,         33,        1,   599040, 0x2afcdaec
+0,         34,         34,        1,   599040, 0x39dfd5b6
+0,         35,         35,        1,   599040, 0xe5844f4e
+0,         36,         36,        1,   599040, 0xf26920d9
+0,         37,         37,        1,   599040, 0x8feb56e2
+0,         38,         38,        1,   599040, 0x6433712f
+0,         39,         39,        1,   599040, 0xba311758
+0,         40,         40,        1,   599040, 0x09f87643
+0,         41,         41,        1,   599040, 0x68562c28
+0,         42,         42,        1,   599040, 0x9465e267
+0,         43,         43,        1,   599040, 0x03e2802f
+0,         44,         44,        1,   599040, 0xa61ed250
+0,         45,         45,        1,   599040, 0x5ab680db
+0,         46,         46,        1,   599040, 0xc4663840
+0,         47,         47,        1,   599040, 0xefe83a4f
+0,         48,         48,        1,   599040, 0x7bfb4ecd
+0,         49,         49,        1,   599040, 0xcafdbfd0
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3
new file mode 100644
index 0000000..aeba53b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x1cf21d79
+0,          1,          1,        1,   599040, 0x1cf21d79
+0,          2,          2,        1,   599040, 0xc182eaa8
+0,          3,          3,        1,   599040, 0x260358ee
+0,          4,          4,        1,   599040, 0x381e5b16
+0,          5,          5,        1,   599040, 0x329dacd8
+0,          6,          6,        1,   599040, 0x7306d51c
+0,          7,          7,        1,   599040, 0x869d359b
+0,          8,          8,        1,   599040, 0xf8fc941a
+0,          9,          9,        1,   599040, 0x0798842b
+0,         10,         10,        1,   599040, 0xe6e1f54e
+0,         11,         11,        1,   599040, 0xc7d5ba9e
+0,         12,         12,        1,   599040, 0xc8c5507a
+0,         13,         13,        1,   599040, 0x97ae604a
+0,         14,         14,        1,   599040, 0x14dd4139
+0,         15,         15,        1,   599040, 0xb2f998dc
+0,         16,         16,        1,   599040, 0xc3a3a6bc
+0,         17,         17,        1,   599040, 0x1f95be77
+0,         18,         18,        1,   599040, 0xb7fd124b
+0,         19,         19,        1,   599040, 0x25703b3c
+0,         20,         20,        1,   599040, 0x3bddeba7
+0,         21,         21,        1,   599040, 0xffcc9b6d
+0,         22,         22,        1,   599040, 0x3dd66a0a
+0,         23,         23,        1,   599040, 0xe9607af7
+0,         24,         24,        1,   599040, 0x218cdc65
+0,         25,         25,        1,   599040, 0x88f97761
+0,         26,         26,        1,   599040, 0x62e1f5d4
+0,         27,         27,        1,   599040, 0xcc3cd429
+0,         28,         28,        1,   599040, 0xb4290272
+0,         29,         29,        1,   599040, 0x4f73142c
+0,         30,         30,        1,   599040, 0x753eefd9
+0,         31,         31,        1,   599040, 0xea77e837
+0,         32,         32,        1,   599040, 0xfa927e55
+0,         33,         33,        1,   599040, 0x3dff1295
+0,         34,         34,        1,   599040, 0x513c2088
+0,         35,         35,        1,   599040, 0x9822b7f0
+0,         36,         36,        1,   599040, 0xc4770af6
+0,         37,         37,        1,   599040, 0x7cb576fb
+0,         38,         38,        1,   599040, 0x2af8ca3a
+0,         39,         39,        1,   599040, 0x0a324910
+0,         40,         40,        1,   599040, 0x1aeb3d7a
+0,         41,         41,        1,   599040, 0x82de1408
+0,         42,         42,        1,   599040, 0x7ebad7f4
+0,         43,         43,        1,   599040, 0xd100bcc1
+0,         44,         44,        1,   599040, 0x4719dc40
+0,         45,         45,        1,   599040, 0xd82f658b
+0,         46,         46,        1,   599040, 0x8c596a54
+0,         47,         47,        1,   599040, 0xd0b4572c
+0,         48,         48,        1,   599040, 0xdc3c5a89
+0,         49,         49,        1,   599040, 0x4f0ad888
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3
new file mode 100644
index 0000000..e0501be
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xd9b73cbe
+0,          1,          1,        1,   599040, 0xd9b73cbe
+0,          2,          2,        1,   599040, 0xe4e5dd7c
+0,          3,          3,        1,   599040, 0xa7333d7e
+0,          4,          4,        1,   599040, 0x6b82552b
+0,          5,          5,        1,   599040, 0x4f02e2a4
+0,          6,          6,        1,   599040, 0x8fdcc50a
+0,          7,          7,        1,   599040, 0x2481542d
+0,          8,          8,        1,   599040, 0x73d0dfad
+0,          9,          9,        1,   599040, 0x842b8cd2
+0,         10,         10,        1,   599040, 0x87b3a3b2
+0,         11,         11,        1,   599040, 0xe4decf78
+0,         12,         12,        1,   599040, 0xfba7dd51
+0,         13,         13,        1,   599040, 0x3dc1e85c
+0,         14,         14,        1,   599040, 0xea8a4987
+0,         15,         15,        1,   599040, 0xa3cc5c8c
+0,         16,         16,        1,   599040, 0x10a09cd8
+0,         17,         17,        1,   599040, 0x6739c5f7
+0,         18,         18,        1,   599040, 0x819af14a
+0,         19,         19,        1,   599040, 0xe9d65a5c
+0,         20,         20,        1,   599040, 0x09def54e
+0,         21,         21,        1,   599040, 0x8595aa5d
+0,         22,         22,        1,   599040, 0xc3f134d7
+0,         23,         23,        1,   599040, 0xdac9496a
+0,         24,         24,        1,   599040, 0x760f0897
+0,         25,         25,        1,   599040, 0x8daddaf5
+0,         26,         26,        1,   599040, 0xed313947
+0,         27,         27,        1,   599040, 0xc875ed4d
+0,         28,         28,        1,   599040, 0xdb5d0b3b
+0,         29,         29,        1,   599040, 0x7cbc0e6a
+0,         30,         30,        1,   599040, 0x193bbc9f
+0,         31,         31,        1,   599040, 0x4f20d599
+0,         32,         32,        1,   599040, 0x09e545e8
+0,         33,         33,        1,   599040, 0x0637d524
+0,         34,         34,        1,   599040, 0x11a3bd85
+0,         35,         35,        1,   599040, 0x304155ce
+0,         36,         36,        1,   599040, 0x6636291b
+0,         37,         37,        1,   599040, 0xc4039e80
+0,         38,         38,        1,   599040, 0xd73ca756
+0,         39,         39,        1,   599040, 0x96a68426
+0,         40,         40,        1,   599040, 0xd945391c
+0,         41,         41,        1,   599040, 0x95a83264
+0,         42,         42,        1,   599040, 0x6356a243
+0,         43,         43,        1,   599040, 0xb9b8973e
+0,         44,         44,        1,   599040, 0xf361d0d9
+0,         45,         45,        1,   599040, 0x2783b0e2
+0,         46,         46,        1,   599040, 0x870ac424
+0,         47,         47,        1,   599040, 0xa8397c01
+0,         48,         48,        1,   599040, 0xf1bc2ac0
+0,         49,         49,        1,   599040, 0x82fbb428
diff --git a/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3 b/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3
new file mode 100644
index 0000000..01ab258
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xd9b73cbe
+0,          1,          1,        1,   599040, 0xd9b73cbe
+0,          2,          2,        1,   599040, 0x93a3fabf
+0,          3,          3,        1,   599040, 0x245a522e
+0,          4,          4,        1,   599040, 0xff1e8bb4
+0,          5,          5,        1,   599040, 0x03390b9a
+0,          6,          6,        1,   599040, 0x27030635
+0,          7,          7,        1,   599040, 0x431c6312
+0,          8,          8,        1,   599040, 0xeddc5f83
+0,          9,          9,        1,   599040, 0x34168a1e
+0,         10,         10,        1,   599040, 0xf4d795a4
+0,         11,         11,        1,   599040, 0xe716ea67
+0,         12,         12,        1,   599040, 0xf3b8446d
+0,         13,         13,        1,   599040, 0x082d12d0
+0,         14,         14,        1,   599040, 0x68e12e99
+0,         15,         15,        1,   599040, 0x3fd079df
+0,         16,         16,        1,   599040, 0x6087fb37
+0,         17,         17,        1,   599040, 0x12c2142e
+0,         18,         18,        1,   599040, 0xb3bcf682
+0,         19,         19,        1,   599040, 0xcec84ee7
+0,         20,         20,        1,   599040, 0x12a4fb43
+0,         21,         21,        1,   599040, 0x85749580
+0,         22,         22,        1,   599040, 0x6df99536
+0,         23,         23,        1,   599040, 0x377282a6
+0,         24,         24,        1,   599040, 0xe296f874
+0,         25,         25,        1,   599040, 0x1b29cd1a
+0,         26,         26,        1,   599040, 0x1cf633c9
+0,         27,         27,        1,   599040, 0xf8cd2544
+0,         28,         28,        1,   599040, 0x61c05325
+0,         29,         29,        1,   599040, 0x87646c89
+0,         30,         30,        1,   599040, 0x5b840711
+0,         31,         31,        1,   599040, 0x5bc4c181
+0,         32,         32,        1,   599040, 0x91ce695a
+0,         33,         33,        1,   599040, 0xed54dcca
+0,         34,         34,        1,   599040, 0xc41fef8e
+0,         35,         35,        1,   599040, 0x9da8830b
+0,         36,         36,        1,   599040, 0xb76cec12
+0,         37,         37,        1,   599040, 0xef9661f0
+0,         38,         38,        1,   599040, 0xe1d38227
+0,         39,         39,        1,   599040, 0xce440134
+0,         40,         40,        1,   599040, 0x41a54dd1
+0,         41,         41,        1,   599040, 0xdd83da8e
+0,         42,         42,        1,   599040, 0xf9cee595
+0,         43,         43,        1,   599040, 0x6f5db54d
+0,         44,         44,        1,   599040, 0x00b6f064
+0,         45,         45,        1,   599040, 0xfbaa978d
+0,         46,         46,        1,   599040, 0x2c9ee1d7
+0,         47,         47,        1,   599040, 0xe8c4be1f
+0,         48,         48,        1,   599040, 0x132a260f
+0,         49,         49,        1,   599040, 0x8571a213
diff --git a/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3 b/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3
new file mode 100644
index 0000000..afa4854
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x6e1f16d0
+0,          1,          1,        1,   149760, 0x5be5bde9
diff --git a/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2 b/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2
new file mode 100644
index 0000000..3346e20
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xcd1019b2
+0,          1,          1,        1,   149760, 0xeb39efeb
diff --git a/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_2
new file mode 100644
index 0000000..50be4f1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,    76032, 0x4313935b
+0,          1,          1,        1,    76032, 0x4c8071b5
+0,          2,          2,        1,    76032, 0x5e627edc
+0,          3,          3,        1,    76032, 0xb51a996d
+0,          4,          4,        1,    76032, 0x77d1800b
+0,          5,          5,        1,    76032, 0x4fb9bf3f
+0,          6,          6,        1,    76032, 0x838f8c05
+0,          7,          7,        1,    76032, 0xa87aabb6
diff --git a/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3 b/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3
new file mode 100644
index 0000000..0750bb3
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x154e6dd9
+0,          2,          2,        1,   599040, 0xcce25693
+0,          3,          3,        1,   599040, 0x3dd84e88
+0,          4,          4,        1,   599040, 0xca197027
+0,          5,          5,        1,   599040, 0xc9af0241
+0,          6,          6,        1,   599040, 0x510470de
+0,          7,          7,        1,   599040, 0xac8c0a7c
+0,          8,          8,        1,   599040, 0x04cbed5e
+0,          9,          9,        1,   599040, 0x514ce2f1
+0,         10,         10,        1,   599040, 0xf37a4eec
+0,         11,         11,        1,   599040, 0xabfd7f2f
+0,         12,         12,        1,   599040, 0x944458a1
+0,         13,         13,        1,   599040, 0xf4f81db2
+0,         14,         14,        1,   599040, 0xdde236fb
+0,         15,         15,        1,   599040, 0x6b0132be
+0,         16,         16,        1,   599040, 0x641683a3
+0,         17,         17,        1,   599040, 0x81d6be90
+0,         18,         18,        1,   599040, 0xf1e04e55
+0,         19,         19,        1,   599040, 0x63c4dc0a
+0,         20,         20,        1,   599040, 0x47170db8
+0,         21,         21,        1,   599040, 0xdc22f27b
+0,         22,         22,        1,   599040, 0xd5b63800
+0,         23,         23,        1,   599040, 0x07b76936
+0,         24,         24,        1,   599040, 0x5215eee2
+0,         25,         25,        1,   599040, 0xb5b2c9b1
+0,         26,         26,        1,   599040, 0x79bee732
+0,         27,         27,        1,   599040, 0x14c1f436
+0,         28,         28,        1,   599040, 0x384f7f05
+0,         29,         29,        1,   599040, 0x44229c42
+0,         30,         30,        1,   599040, 0x5dea88e9
diff --git a/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3 b/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3
new file mode 100644
index 0000000..83f9b4a
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xda0cb5d4
+0,          2,          2,        1,   599040, 0x352bc397
+0,          3,          3,        1,   599040, 0x72bc28fe
+0,          4,          4,        1,   599040, 0x22294f68
+0,          5,          5,        1,   599040, 0x1f6415a7
+0,          6,          6,        1,   599040, 0xa9f6b0d7
+0,          7,          7,        1,   599040, 0x6b7c1f2d
+0,          8,          8,        1,   599040, 0xb93857f5
+0,          9,          9,        1,   599040, 0xb0d752d3
+0,         10,         10,        1,   599040, 0x0622e689
+0,         11,         11,        1,   599040, 0x23d8780a
+0,         12,         12,        1,   599040, 0x4844581b
+0,         13,         13,        1,   599040, 0x791322f9
+0,         14,         14,        1,   599040, 0x82f6cf43
+0,         15,         15,        1,   599040, 0xcace3aba
+0,         16,         16,        1,   599040, 0x68a68427
+0,         17,         17,        1,   599040, 0x23fa500a
+0,         18,         18,        1,   599040, 0x7d78b77d
+0,         19,         19,        1,   599040, 0x8d295032
+0,         20,         20,        1,   599040, 0x16fa266c
+0,         21,         21,        1,   599040, 0x37d8173b
+0,         22,         22,        1,   599040, 0x8a4f90e1
+0,         23,         23,        1,   599040, 0x40f98f6d
+0,         24,         24,        1,   599040, 0xc060b193
+0,         25,         25,        1,   599040, 0xa53c3bc1
+0,         26,         26,        1,   599040, 0x5a9556d6
+0,         27,         27,        1,   599040, 0x37582393
+0,         28,         28,        1,   599040, 0x376acd14
+0,         29,         29,        1,   599040, 0x81ee1e64
+0,         30,         30,        1,   599040, 0xff2a600c
diff --git a/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3 b/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3
new file mode 100644
index 0000000..1087148
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x57369bf4
+0,          2,          2,        1,   599040, 0x319aab9c
+0,          3,          3,        1,   599040, 0xbc1b7698
+0,          4,          4,        1,   599040, 0x05cea248
+0,          5,          5,        1,   599040, 0xdca73743
+0,          6,          6,        1,   599040, 0x5b5a9f70
+0,          7,          7,        1,   599040, 0x16c51b34
+0,          8,          8,        1,   599040, 0x734fe724
+0,          9,          9,        1,   599040, 0x48e4e0ba
+0,         10,         10,        1,   599040, 0xf1423cc1
+0,         11,         11,        1,   599040, 0xb4bb68b1
+0,         12,         12,        1,   599040, 0x54a77ad6
+0,         13,         13,        1,   599040, 0x6e0dfce3
+0,         14,         14,        1,   599040, 0x7ca687e3
+0,         15,         15,        1,   599040, 0xf9ac2443
+0,         16,         16,        1,   599040, 0xe35b8d34
+0,         17,         17,        1,   599040, 0xef4bbe9f
+0,         18,         18,        1,   599040, 0x21eb418e
+0,         19,         19,        1,   599040, 0xae6df30f
+0,         20,         20,        1,   599040, 0x743500af
+0,         21,         21,        1,   599040, 0x7fba1ce1
+0,         22,         22,        1,   599040, 0x45793eae
+0,         23,         23,        1,   599040, 0x1f7e3467
+0,         24,         24,        1,   599040, 0x7400c7c3
+0,         25,         25,        1,   599040, 0xcf79806d
+0,         26,         26,        1,   599040, 0x324ea91d
+0,         27,         27,        1,   599040, 0x9c8cae92
+0,         28,         28,        1,   599040, 0x70bfc368
+0,         29,         29,        1,   599040, 0x46a0f8ff
+0,         30,         30,        1,   599040, 0xd864208a
diff --git a/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_1 b/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_1
new file mode 100644
index 0000000..3d9e43b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_1
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0x6ef5c76e
+0,          1,          1,        1,  1382400, 0x975238be
+0,          2,          2,        1,  1382400, 0xe5529a79
+0,          3,          3,        1,  1382400, 0x639641d4
+0,          4,          4,        1,  1382400, 0x566eb1df
+0,          5,          5,        1,  1382400, 0x4fd4b46a
+0,          6,          6,        1,  1382400, 0xfb4a6a0e
+0,          7,          7,        1,  1382400, 0x4485af32
diff --git a/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2
new file mode 100644
index 0000000..2bdc548
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0x6ef5c76e
+0,          1,          1,        1,  1382400, 0x1e1926b1
+0,          2,          2,        1,  1382400, 0x69888786
+0,          3,          3,        1,  1382400, 0x1f193659
+0,          4,          4,        1,  1382400, 0x566eb1df
+0,          5,          5,        1,  1382400, 0x49b3a668
+0,          6,          6,        1,  1382400, 0x1b774ed8
+0,          7,          7,        1,  1382400, 0x2296a2bc
diff --git a/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_1 b/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_1
new file mode 100644
index 0000000..c3ebaf2
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_1
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0x7119bbe5
+0,          1,          1,        1,  1382400, 0xbeda2c83
+0,          2,          2,        1,  1382400, 0x2cbe6669
+0,          3,          3,        1,  1382400, 0x3cee2619
+0,          4,          4,        1,  1382400, 0x93e388e3
+0,          5,          5,        1,  1382400, 0x5e286889
+0,          6,          6,        1,  1382400, 0x4718f29c
+0,          7,          7,        1,  1382400, 0xbedf4dbd
diff --git a/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2
new file mode 100644
index 0000000..4c8b07d
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0xecfdf606
+0,          1,          1,        1,  1382400, 0x0b0382e1
+0,          2,          2,        1,  1382400, 0xbef3afd6
+0,          3,          3,        1,  1382400, 0x6a2bcabb
+0,          4,          4,        1,  1382400, 0x663f991c
+0,          5,          5,        1,  1382400, 0xb49b94d8
+0,          6,          6,        1,  1382400, 0x07399433
+0,          7,          7,        1,  1382400, 0x9cca09df
diff --git a/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_1 b/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_1
new file mode 100644
index 0000000..59f51ef
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_1
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0xea27f7bd
+0,          1,          1,        1,  1382400, 0xce3d7b4c
+0,          2,          2,        1,  1382400, 0xaea4970e
+0,          3,          3,        1,  1382400, 0xcbc7c89f
+0,          4,          4,        1,  1382400, 0xe5367019
+0,          5,          5,        1,  1382400, 0xb92ca18e
+0,          6,          6,        1,  1382400, 0xde046be1
+0,          7,          7,        1,  1382400, 0x1ae6e393
diff --git a/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2
new file mode 100644
index 0000000..3ff62e5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0xea27f7bd
+0,          1,          1,        1,  1382400, 0x423e555b
+0,          2,          2,        1,  1382400, 0x87898ae0
+0,          3,          3,        1,  1382400, 0xfee4beab
+0,          4,          4,        1,  1382400, 0xe5367019
+0,          5,          5,        1,  1382400, 0x3e74b3aa
+0,          6,          6,        1,  1382400, 0x4d8ab61a
+0,          7,          7,        1,  1382400, 0x22500e13
diff --git a/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_1 b/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_1
new file mode 100644
index 0000000..4b9793b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_1
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0xecfdf606
+0,          1,          1,        1,  1382400, 0x7607799b
+0,          2,          2,        1,  1382400, 0x67fb98e4
+0,          3,          3,        1,  1382400, 0xf2dce07f
+0,          4,          4,        1,  1382400, 0x663f991c
+0,          5,          5,        1,  1382400, 0x3877aeb0
+0,          6,          6,        1,  1382400, 0x73409282
+0,          7,          7,        1,  1382400, 0x766c10b1
diff --git a/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2 b/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2
new file mode 100644
index 0000000..4c8b07d
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0xecfdf606
+0,          1,          1,        1,  1382400, 0x0b0382e1
+0,          2,          2,        1,  1382400, 0xbef3afd6
+0,          3,          3,        1,  1382400, 0x6a2bcabb
+0,          4,          4,        1,  1382400, 0x663f991c
+0,          5,          5,        1,  1382400, 0xb49b94d8
+0,          6,          6,        1,  1382400, 0x07399433
+0,          7,          7,        1,  1382400, 0x9cca09df
diff --git a/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3 b/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3
new file mode 100644
index 0000000..a8427d1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x7ea9597c
+0,          2,          2,        1,   599040, 0x3e7365e4
+0,          3,          3,        1,   599040, 0x4a9149c9
+0,          4,          4,        1,   599040, 0x3b1f6549
+0,          5,          5,        1,   599040, 0x3e35f616
+0,          6,          6,        1,   599040, 0x843c7951
+0,          7,          7,        1,   599040, 0xa2adb299
+0,          8,          8,        1,   599040, 0xb9dda682
+0,          9,          9,        1,   599040, 0x9a5e7355
+0,         10,         10,        1,   599040, 0xc4bafa8c
+0,         11,         11,        1,   599040, 0xc4ec160e
+0,         12,         12,        1,   599040, 0x538421a3
+0,         13,         13,        1,   599040, 0xb294a96e
+0,         14,         14,        1,   599040, 0x9bb217df
+0,         15,         15,        1,   599040, 0xbe70c870
+0,         16,         16,        1,   599040, 0xa4e319a8
+0,         17,         17,        1,   599040, 0x3a4c702d
+0,         18,         18,        1,   599040, 0x9f790906
+0,         19,         19,        1,   599040, 0xbbfdb8d6
+0,         20,         20,        1,   599040, 0x0965c0ed
+0,         21,         21,        1,   599040, 0x6993e1f1
+0,         22,         22,        1,   599040, 0xc1cc1df9
+0,         23,         23,        1,   599040, 0xe570c390
+0,         24,         24,        1,   599040, 0x422f6fd7
+0,         25,         25,        1,   599040, 0x9c89298c
+0,         26,         26,        1,   599040, 0x5ece4193
+0,         27,         27,        1,   599040, 0x142a4f2f
+0,         28,         28,        1,   599040, 0xa5356c63
+0,         29,         29,        1,   599040, 0x8458a378
+0,         30,         30,        1,   599040, 0xc149ed56
diff --git a/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3 b/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3
new file mode 100644
index 0000000..8037e9c
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3
@@ -0,0 +1,31 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xcb2969c5
+0,          2,          2,        1,   599040, 0xd9825d1f
+0,          3,          3,        1,   599040, 0x5ff4245a
+0,          4,          4,        1,   599040, 0xd34e7bcb
+0,          5,          5,        1,   599040, 0x032e1b8b
+0,          6,          6,        1,   599040, 0x5ba1873c
+0,          7,          7,        1,   599040, 0xa0b725ad
+0,          8,          8,        1,   599040, 0x9cade6a6
+0,          9,          9,        1,   599040, 0xe41bee5a
+0,         10,         10,        1,   599040, 0x9de4340f
+0,         11,         11,        1,   599040, 0xb966282a
+0,         12,         12,        1,   599040, 0x52fd5300
+0,         13,         13,        1,   599040, 0x8e6d6753
+0,         14,         14,        1,   599040, 0x2011759b
+0,         15,         15,        1,   599040, 0x5da5b7af
+0,         16,         16,        1,   599040, 0x090e298c
+0,         17,         17,        1,   599040, 0xfd618263
+0,         18,         18,        1,   599040, 0xdaf4ef69
+0,         19,         19,        1,   599040, 0x0349d1a0
+0,         20,         20,        1,   599040, 0x75a35caf
+0,         21,         21,        1,   599040, 0x4544918e
+0,         22,         22,        1,   599040, 0xbca15836
+0,         23,         23,        1,   599040, 0x443bc611
+0,         24,         24,        1,   599040, 0xc380beaf
+0,         25,         25,        1,   599040, 0x01a581ca
+0,         26,         26,        1,   599040, 0x1690835f
+0,         27,         27,        1,   599040, 0x871e9c3b
+0,         28,         28,        1,   599040, 0xf4c20a25
+0,         29,         29,        1,   599040, 0x86d8f2df
+0,         30,         30,        1,   599040, 0x7690bd56
diff --git a/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5 b/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5
new file mode 100644
index 0000000..6cd113b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0xdc18cd12
+0,          1,          1,        1,  3110400, 0x42f7020d
+0,          2,          2,        1,  3110400, 0x6ac4421a
+0,          3,          3,        1,  3110400, 0xdbf78c86
+0,          4,          4,        1,  3110400, 0x123f9c50
+0,          5,          5,        1,  3110400, 0x9356a73f
+0,          6,          6,        1,  3110400, 0xc54a446b
+0,          7,          7,        1,  3110400, 0xdfa92401
+0,          8,          8,        1,  3110400, 0xd3226c6a
+0,          9,          9,        1,  3110400, 0xa0bd149a
+0,         10,         10,        1,  3110400, 0xc38c58cc
+0,         11,         11,        1,  3110400, 0xf1871f13
+0,         12,         12,        1,  3110400, 0xfdf151d5
+0,         13,         13,        1,  3110400, 0x65ca7286
+0,         14,         14,        1,  3110400, 0xac2d80dc
+0,         15,         15,        1,  3110400, 0x3e024908
+0,         16,         16,        1,  3110400, 0x22a66454
+0,         17,         17,        1,  3110400, 0x83b6cac8
+0,         18,         18,        1,  3110400, 0xe1bccc50
+0,         19,         19,        1,  3110400, 0x76be567e
+0,         20,         20,        1,  3110400, 0x743c4335
+0,         21,         21,        1,  3110400, 0xd3d28565
+0,         22,         22,        1,  3110400, 0x2ab3a5a2
+0,         23,         23,        1,  3110400, 0x9141f68e
+0,         24,         24,        1,  3110400, 0xe90fac3b
+0,         25,         25,        1,  3110400, 0xdc8e496d
+0,         26,         26,        1,  3110400, 0x4ea216b9
+0,         27,         27,        1,  3110400, 0xd1f8a08e
+0,         28,         28,        1,  3110400, 0x2b512b98
+0,         29,         29,        1,  3110400, 0x6af060b6
+0,         30,         30,        1,  3110400, 0x69389c02
+0,         31,         31,        1,  3110400, 0x7a8cef2f
+0,         32,         32,        1,  3110400, 0x8f5bd7eb
+0,         33,         33,        1,  3110400, 0x3960d741
+0,         34,         34,        1,  3110400, 0x86c2c23b
+0,         35,         35,        1,  3110400, 0x6d0d258a
+0,         36,         36,        1,  3110400, 0xaff6795b
+0,         37,         37,        1,  3110400, 0x97b9cb1e
+0,         38,         38,        1,  3110400, 0x5966d391
+0,         39,         39,        1,  3110400, 0xb9c90726
+0,         40,         40,        1,  3110400, 0x3ab5836d
+0,         41,         41,        1,  3110400, 0xcc3c95e7
+0,         42,         42,        1,  3110400, 0x190df1ce
+0,         43,         43,        1,  3110400, 0x64e6f266
+0,         44,         44,        1,  3110400, 0x98dfdcdd
+0,         45,         45,        1,  3110400, 0xd8889aff
+0,         46,         46,        1,  3110400, 0x969775b8
+0,         47,         47,        1,  3110400, 0x8f3dec20
+0,         48,         48,        1,  3110400, 0xbd2b80ca
+0,         49,         49,        1,  3110400, 0x68baa6f7
diff --git a/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5 b/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5
new file mode 100644
index 0000000..7626d76
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0x96995c57
+0,          1,          1,        1,  3110400, 0x2924a10f
+0,          2,          2,        1,  3110400, 0x892e146c
+0,          3,          3,        1,  3110400, 0x9b0b8733
+0,          4,          4,        1,  3110400, 0xb09ffc2d
+0,          5,          5,        1,  3110400, 0x588e04a0
+0,          6,          6,        1,  3110400, 0xa9ed178c
+0,          7,          7,        1,  3110400, 0x54254788
+0,          8,          8,        1,  3110400, 0x4fa444bc
+0,          9,          9,        1,  3110400, 0xe97d958a
+0,         10,         10,        1,  3110400, 0x8e168461
+0,         11,         11,        1,  3110400, 0xc39e551f
+0,         12,         12,        1,  3110400, 0xb5649a69
+0,         13,         13,        1,  3110400, 0x64eb3085
+0,         14,         14,        1,  3110400, 0xb4485019
+0,         15,         15,        1,  3110400, 0x989e4c47
+0,         16,         16,        1,  3110400, 0x0ff21984
+0,         17,         17,        1,  3110400, 0xe81b3ddd
+0,         18,         18,        1,  3110400, 0x6404610f
+0,         19,         19,        1,  3110400, 0xa61c3403
+0,         20,         20,        1,  3110400, 0x033ca068
+0,         21,         21,        1,  3110400, 0x3513dff4
+0,         22,         22,        1,  3110400, 0xe903a3c2
+0,         23,         23,        1,  3110400, 0xd40b3248
+0,         24,         24,        1,  3110400, 0xa257fb35
+0,         25,         25,        1,  3110400, 0x6fcab221
+0,         26,         26,        1,  3110400, 0x079a34c7
+0,         27,         27,        1,  3110400, 0x7308ecbc
+0,         28,         28,        1,  3110400, 0x1cf2dffb
+0,         29,         29,        1,  3110400, 0x59a0a84d
+0,         30,         30,        1,  3110400, 0x6b76450f
+0,         31,         31,        1,  3110400, 0x27de01f3
+0,         32,         32,        1,  3110400, 0x8541fe8b
+0,         33,         33,        1,  3110400, 0x07b740d9
+0,         34,         34,        1,  3110400, 0x735d36e9
+0,         35,         35,        1,  3110400, 0x0336ac98
+0,         36,         36,        1,  3110400, 0xab9f7d33
+0,         37,         37,        1,  3110400, 0xc5f62e67
+0,         38,         38,        1,  3110400, 0x68d6c250
+0,         39,         39,        1,  3110400, 0xaf26c339
+0,         40,         40,        1,  3110400, 0xfa920d0f
+0,         41,         41,        1,  3110400, 0xac9c6a89
+0,         42,         42,        1,  3110400, 0xa0d0cbd0
+0,         43,         43,        1,  3110400, 0x9d517b81
+0,         44,         44,        1,  3110400, 0x3c3b2b89
+0,         45,         45,        1,  3110400, 0x3cf50b0c
+0,         46,         46,        1,  3110400, 0xee319ebe
+0,         47,         47,        1,  3110400, 0x5b7c3397
+0,         48,         48,        1,  3110400, 0x1a089921
+0,         49,         49,        1,  3110400, 0x69718487
diff --git a/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5 b/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5
new file mode 100644
index 0000000..c4275cb
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0x62a2ceab
+0,          1,          1,        1,  3110400, 0x5e4d6adc
+0,          2,          2,        1,  3110400, 0x4ad0955d
+0,          3,          3,        1,  3110400, 0x17fd7b7c
+0,          4,          4,        1,  3110400, 0xe8270ac1
+0,          5,          5,        1,  3110400, 0xbc32bf86
+0,          6,          6,        1,  3110400, 0x13cc365c
+0,          7,          7,        1,  3110400, 0xef503eb5
+0,          8,          8,        1,  3110400, 0xcc9506f4
+0,          9,          9,        1,  3110400, 0xdc213a9e
+0,         10,         10,        1,  3110400, 0xe567c736
+0,         11,         11,        1,  3110400, 0x0a79aad4
+0,         12,         12,        1,  3110400, 0x61773cff
+0,         13,         13,        1,  3110400, 0x2e93a037
+0,         14,         14,        1,  3110400, 0xf419a7bf
+0,         15,         15,        1,  3110400, 0xa57b06bf
+0,         16,         16,        1,  3110400, 0x6e94960a
+0,         17,         17,        1,  3110400, 0x11f22564
+0,         18,         18,        1,  3110400, 0x850e5f7c
+0,         19,         19,        1,  3110400, 0xdfad06af
+0,         20,         20,        1,  3110400, 0xf2912aee
+0,         21,         21,        1,  3110400, 0x57e1c391
+0,         22,         22,        1,  3110400, 0xc8976a8f
+0,         23,         23,        1,  3110400, 0x88fb8b68
+0,         24,         24,        1,  3110400, 0xbe0e314b
+0,         25,         25,        1,  3110400, 0x33ae23f8
+0,         26,         26,        1,  3110400, 0x4db83c5c
+0,         27,         27,        1,  3110400, 0xa5f71a9d
+0,         28,         28,        1,  3110400, 0x34bb4f19
+0,         29,         29,        1,  3110400, 0xb1fee8d9
+0,         30,         30,        1,  3110400, 0x369990b7
+0,         31,         31,        1,  3110400, 0x6bfdbd4a
+0,         32,         32,        1,  3110400, 0x709dd60d
+0,         33,         33,        1,  3110400, 0x4213781c
+0,         34,         34,        1,  3110400, 0x7810dadd
+0,         35,         35,        1,  3110400, 0x1bc02bc6
+0,         36,         36,        1,  3110400, 0x760ed4aa
+0,         37,         37,        1,  3110400, 0xe2b45e4d
+0,         38,         38,        1,  3110400, 0x517b8d0a
+0,         39,         39,        1,  3110400, 0xf145ed7e
+0,         40,         40,        1,  3110400, 0xd8cbc454
+0,         41,         41,        1,  3110400, 0xa80f26f7
+0,         42,         42,        1,  3110400, 0x340a418d
+0,         43,         43,        1,  3110400, 0x5a0f7264
+0,         44,         44,        1,  3110400, 0xf2936a6d
+0,         45,         45,        1,  3110400, 0x841e715b
+0,         46,         46,        1,  3110400, 0xb17e4131
+0,         47,         47,        1,  3110400, 0x40e3ba7b
+0,         48,         48,        1,  3110400, 0x610254f7
+0,         49,         49,        1,  3110400, 0x76aa8b44
diff --git a/tests/ref/fate/hevc-conformance-ENTP_A_LG_2 b/tests/ref/fate/hevc-conformance-ENTP_A_LG_2
new file mode 100644
index 0000000..5697619
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ENTP_A_LG_2
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x866449d5
+0,          1,          1,        1,   599040, 0x6a8919f0
+0,          2,          2,        1,   599040, 0x5bec3742
+0,          3,          3,        1,   599040, 0x0e66f78b
+0,          4,          4,        1,   599040, 0x798e543b
+0,          5,          5,        1,   599040, 0x342467e0
+0,          6,          6,        1,   599040, 0x2cb393e1
+0,          7,          7,        1,   599040, 0x2f326539
+0,          8,          8,        1,   599040, 0x8ac6eb6a
+0,          9,          9,        1,   599040, 0x810a887b
+0,         10,         10,        1,   599040, 0x4feb2d60
+0,         11,         11,        1,   599040, 0xd32165ff
+0,         12,         12,        1,   599040, 0x46e505e1
+0,         13,         13,        1,   599040, 0x2d917014
+0,         14,         14,        1,   599040, 0xb504f112
+0,         15,         15,        1,   599040, 0x0fca37ce
+0,         16,         16,        1,   599040, 0x2d5a269d
+0,         17,         17,        1,   599040, 0x3928ef6d
+0,         18,         18,        1,   599040, 0x94397312
+0,         19,         19,        1,   599040, 0xc1c1257b
+0,         20,         20,        1,   599040, 0x4e23adcc
+0,         21,         21,        1,   599040, 0x3eaef1e0
+0,         22,         22,        1,   599040, 0x5e66fa14
+0,         23,         23,        1,   599040, 0x2adfa0c2
+0,         24,         24,        1,   599040, 0xf888db90
+0,         25,         25,        1,   599040, 0xab3a6418
+0,         26,         26,        1,   599040, 0x7689d0a2
+0,         27,         27,        1,   599040, 0x2f5746bf
+0,         28,         28,        1,   599040, 0xad2cf3da
+0,         29,         29,        1,   599040, 0x32f2854e
+0,         30,         30,        1,   599040, 0xb73cf7db
+0,         31,         31,        1,   599040, 0xbe996991
+0,         32,         32,        1,   599040, 0xe66501c8
+0,         33,         33,        1,   599040, 0x12d1bc13
+0,         34,         34,        1,   599040, 0x06e103d5
+0,         35,         35,        1,   599040, 0x49af0680
+0,         36,         36,        1,   599040, 0xdbf128b0
+0,         37,         37,        1,   599040, 0xa1ac770d
+0,         38,         38,        1,   599040, 0x99156429
+0,         39,         39,        1,   599040, 0x8ce1a9a7
+0,         40,         40,        1,   599040, 0x14067700
+0,         41,         41,        1,   599040, 0xcdedccee
+0,         42,         42,        1,   599040, 0x09c12765
+0,         43,         43,        1,   599040, 0x7979a1be
+0,         44,         44,        1,   599040, 0xbd3148d1
+0,         45,         45,        1,   599040, 0xc83f9aac
+0,         46,         46,        1,   599040, 0x91acbae4
+0,         47,         47,        1,   599040, 0xd230907a
+0,         48,         48,        1,   599040, 0x3f6c31f6
+0,         49,         49,        1,   599040, 0x84496e55
diff --git a/tests/ref/fate/hevc-conformance-ENTP_B_LG_2 b/tests/ref/fate/hevc-conformance-ENTP_B_LG_2
new file mode 100644
index 0000000..0251f30
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ENTP_B_LG_2
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x95a24137
+0,          1,          1,        1,   599040, 0x7d7f2b75
+0,          2,          2,        1,   599040, 0xd9fb2120
+0,          3,          3,        1,   599040, 0x14d50590
+0,          4,          4,        1,   599040, 0xe3d1b70e
+0,          5,          5,        1,   599040, 0x57708a86
+0,          6,          6,        1,   599040, 0xae56a720
+0,          7,          7,        1,   599040, 0x74c18679
+0,          8,          8,        1,   599040, 0x6422d2a7
+0,          9,          9,        1,   599040, 0xf587702b
+0,         10,         10,        1,   599040, 0x0f630fe0
+0,         11,         11,        1,   599040, 0x4e3537dd
+0,         12,         12,        1,   599040, 0xa645e9c1
+0,         13,         13,        1,   599040, 0x35ab4155
+0,         14,         14,        1,   599040, 0x4b78ba34
+0,         15,         15,        1,   599040, 0xa9a9e572
+0,         16,         16,        1,   599040, 0x6d57f10f
+0,         17,         17,        1,   599040, 0xffb8e333
+0,         18,         18,        1,   599040, 0x7b2d6319
+0,         19,         19,        1,   599040, 0xcf3319aa
+0,         20,         20,        1,   599040, 0xb0d097ee
+0,         21,         21,        1,   599040, 0xf042f780
+0,         22,         22,        1,   599040, 0xfafafdcb
+0,         23,         23,        1,   599040, 0xc8c1c452
+0,         24,         24,        1,   599040, 0x83c4d488
+0,         25,         25,        1,   599040, 0x81a8fd08
+0,         26,         26,        1,   599040, 0x2cb0c333
+0,         27,         27,        1,   599040, 0xa7bf4e52
+0,         28,         28,        1,   599040, 0x5b7ed8e9
+0,         29,         29,        1,   599040, 0x4ff03464
+0,         30,         30,        1,   599040, 0x54a700c2
+0,         31,         31,        1,   599040, 0x7dbb63aa
+0,         32,         32,        1,   599040, 0xda26288e
+0,         33,         33,        1,   599040, 0x8074da41
+0,         34,         34,        1,   599040, 0xa32b2ab2
+0,         35,         35,        1,   599040, 0x51b457fb
+0,         36,         36,        1,   599040, 0x05e34953
+0,         37,         37,        1,   599040, 0x68c762d6
+0,         38,         38,        1,   599040, 0x11bf469e
+0,         39,         39,        1,   599040, 0xc2fdadaf
+0,         40,         40,        1,   599040, 0x05588da0
+0,         41,         41,        1,   599040, 0x8855f927
+0,         42,         42,        1,   599040, 0x11c85d5a
+0,         43,         43,        1,   599040, 0x7a0aede5
+0,         44,         44,        1,   599040, 0x39dc4f7d
+0,         45,         45,        1,   599040, 0x388f81d6
+0,         46,         46,        1,   599040, 0x2afa830d
+0,         47,         47,        1,   599040, 0xd7f26886
+0,         48,         48,        1,   599040, 0xb8e12aef
+0,         49,         49,        1,   599040, 0x73f7582c
diff --git a/tests/ref/fate/hevc-conformance-ENTP_C_LG_3 b/tests/ref/fate/hevc-conformance-ENTP_C_LG_3
new file mode 100644
index 0000000..3c0946e
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ENTP_C_LG_3
@@ -0,0 +1,51 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0xaea1c3d6
+0,          1,          1,        1,  3110400, 0x665b4f52
+0,          2,          2,        1,  3110400, 0xc7da58a2
+0,          3,          3,        1,  3110400, 0x1dda6461
+0,          4,          4,        1,  3110400, 0x1d8d6eaf
+0,          5,          5,        1,  3110400, 0x7a29911a
+0,          6,          6,        1,  3110400, 0x0dce92c9
+0,          7,          7,        1,  3110400, 0x79c84570
+0,          8,          8,        1,  3110400, 0x736ef1e7
+0,          9,          9,        1,  3110400, 0x9dd86492
+0,         10,         10,        1,  3110400, 0x0ea31a1b
+0,         11,         11,        1,  3110400, 0x0d84fdc8
+0,         12,         12,        1,  3110400, 0x06ed89a7
+0,         13,         13,        1,  3110400, 0xfaea4fd6
+0,         14,         14,        1,  3110400, 0xe787abe8
+0,         15,         15,        1,  3110400, 0x050b653a
+0,         16,         16,        1,  3110400, 0x35cc1ec1
+0,         17,         17,        1,  3110400, 0x86a43e07
+0,         18,         18,        1,  3110400, 0xa6ab021e
+0,         19,         19,        1,  3110400, 0x491e0efa
+0,         20,         20,        1,  3110400, 0x8f210c38
+0,         21,         21,        1,  3110400, 0x637af0d0
+0,         22,         22,        1,  3110400, 0x47a59197
+0,         23,         23,        1,  3110400, 0x53e04637
+0,         24,         24,        1,  3110400, 0x7b99325e
+0,         25,         25,        1,  3110400, 0x972aa252
+0,         26,         26,        1,  3110400, 0xe76ef917
+0,         27,         27,        1,  3110400, 0x7a25babc
+0,         28,         28,        1,  3110400, 0x3bee3c5c
+0,         29,         29,        1,  3110400, 0xbae82bcb
+0,         30,         30,        1,  3110400, 0x5b65c1e5
+0,         31,         31,        1,  3110400, 0xa546266f
+0,         32,         32,        1,  3110400, 0x5c5b9b8e
+0,         33,         33,        1,  3110400, 0xec29c804
+0,         34,         34,        1,  3110400, 0x384efc7d
+0,         35,         35,        1,  3110400, 0x6c1aaa23
+0,         36,         36,        1,  3110400, 0x55494f9f
+0,         37,         37,        1,  3110400, 0xa9c56fec
+0,         38,         38,        1,  3110400, 0x49c29ef2
+0,         39,         39,        1,  3110400, 0xac24fdd4
+0,         40,         40,        1,  3110400, 0x403d8213
+0,         41,         41,        1,  3110400, 0xf2d8aefe
+0,         42,         42,        1,  3110400, 0x2884f0e1
+0,         43,         43,        1,  3110400, 0x69a0a781
+0,         44,         44,        1,  3110400, 0x3ab6114c
+0,         45,         45,        1,  3110400, 0x1d4425a2
+0,         46,         46,        1,  3110400, 0x59f8970a
+0,         47,         47,        1,  3110400, 0xfe0a05a9
+0,         48,         48,        1,  3110400, 0x50b9be4f
+0,         49,         49,        1,  3110400, 0x3e1b65bd
diff --git a/tests/ref/fate/hevc-conformance-EXT_A_ericsson_3 b/tests/ref/fate/hevc-conformance-EXT_A_ericsson_3
new file mode 100644
index 0000000..bf4616a
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-EXT_A_ericsson_3
@@ -0,0 +1,4 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8ce7200b
+0,          1,          1,        1,   149760, 0xf97412f6
+0,          2,          2,        1,   149760, 0x0ea132c4
diff --git a/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2 b/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2
new file mode 100644
index 0000000..33878fd
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2
@@ -0,0 +1,21 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xac658d10
+0,          1,          1,        1,   599040, 0xe3f65389
+0,          2,          2,        1,   599040, 0xfbd644b0
+0,          3,          3,        1,   599040, 0x3ac49569
+0,          4,          4,        1,   599040, 0x75abc5e2
+0,          5,          5,        1,   599040, 0xe787ddcd
+0,          6,          6,        1,   599040, 0x1df5f293
+0,          7,          7,        1,   599040, 0xa87774aa
+0,          8,          8,        1,   599040, 0x42b2bec6
+0,          9,          9,        1,   599040, 0x89f22378
+0,         10,         10,        1,   599040, 0x0d4e5397
+0,         11,         11,        1,   599040, 0xf4430d13
+0,         12,         12,        1,   599040, 0xfd2ff520
+0,         13,         13,        1,   599040, 0x21bf374b
+0,         14,         14,        1,   599040, 0xcba1032e
+0,         15,         15,        1,   599040, 0x58247f24
+0,         16,         16,        1,   599040, 0x7985788a
+0,         17,         17,        1,   599040, 0x3306488e
+0,         18,         18,        1,   599040, 0x8bcbf22e
+0,         19,         19,        1,   599040, 0xb7a7ae5c
diff --git a/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3 b/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3
new file mode 100644
index 0000000..4de7c3c
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0x11ef5ddd
diff --git a/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_2 b/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_2
new file mode 100644
index 0000000..bff448b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_2
@@ -0,0 +1,5 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x9a8664e6
+0,          1,          1,        1,   599040, 0x72f15982
+0,          2,          2,        1,   599040, 0xc6610a7b
+0,          3,          3,        1,   599040, 0x091d3a93
diff --git a/tests/ref/fate/hevc-conformance-LS_A_Orange_2 b/tests/ref/fate/hevc-conformance-LS_A_Orange_2
new file mode 100644
index 0000000..4dd4ad4
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-LS_A_Orange_2
@@ -0,0 +1,10 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x94a51701
+0,          1,          1,        1,   149760, 0x67c71885
+0,          2,          2,        1,   149760, 0x218f1751
+0,          3,          3,        1,   149760, 0x56951bef
+0,          4,          4,        1,   149760, 0x76aec81e
+0,          5,          5,        1,   149760, 0x20df61ac
+0,          6,          6,        1,   149760, 0x2eacf616
+0,          7,          7,        1,   149760, 0x06322ce2
+0,          8,          8,        1,   149760, 0xf14aa104
diff --git a/tests/ref/fate/hevc-conformance-LS_B_ORANGE_3 b/tests/ref/fate/hevc-conformance-LS_B_ORANGE_3
new file mode 100644
index 0000000..34dc379
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-LS_B_ORANGE_3
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x25267761
+0,          1,          1,        1,   599040, 0x4b4b6846
+0,          2,          2,        1,   599040, 0x78e251e8
+0,          3,          3,        1,   599040, 0xd5b261b0
+0,          4,          4,        1,   599040, 0x2c4cf4e1
+0,          5,          5,        1,   599040, 0x67dc648f
+0,          6,          6,        1,   599040, 0x3c43bffc
+0,          7,          7,        1,   599040, 0x43dca917
+0,          8,          8,        1,   599040, 0x86c9915e
+0,          9,          9,        1,   599040, 0xcfc4f95c
+0,         10,         10,        1,   599040, 0x1ad40bab
+0,         11,         11,        1,   599040, 0x88b5419e
+0,         12,         12,        1,   599040, 0x94e89a06
+0,         13,         13,        1,   599040, 0x3c68f4a6
+0,         14,         14,        1,   599040, 0xc573ac93
+0,         15,         15,        1,   599040, 0x3c401779
+0,         16,         16,        1,   599040, 0x33358319
+0,         17,         17,        1,   599040, 0xbecb022e
+0,         18,         18,        1,   599040, 0x824ca6c1
+0,         19,         19,        1,   599040, 0x9d13a2b8
+0,         20,         20,        1,   599040, 0xbdd4b44b
+0,         21,         21,        1,   599040, 0x7e43e7e9
+0,         22,         22,        1,   599040, 0x88c39a97
+0,         23,         23,        1,   599040, 0xe0462f05
+0,         24,         24,        1,   599040, 0xc5651fd1
diff --git a/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4 b/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4
new file mode 100644
index 0000000..9110cf6
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x9cad90f9
+0,          1,          1,        1,   149760, 0x7deeab1c
diff --git a/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4 b/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4
new file mode 100644
index 0000000..5cad961
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4
@@ -0,0 +1,4 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x211e8487
+0,          1,          1,        1,   149760, 0xa53b13d8
+0,          2,          2,        1,   149760, 0xb63cc103
diff --git a/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4 b/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4
new file mode 100644
index 0000000..2eb3843
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4
@@ -0,0 +1,4 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xa8d7adfa
+0,          1,          1,        1,   149760, 0x76d1ddfe
+0,          2,          2,        1,   149760, 0x56599cae
diff --git a/tests/ref/fate/hevc-conformance-MERGE_A_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_A_TI_3
new file mode 100644
index 0000000..0ab6acc
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_A_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0x16eb25a8
+0,          2,          2,        1,   149760, 0xcfff29c8
+0,          3,          3,        1,   149760, 0x4c9721e9
+0,          4,          4,        1,   149760, 0xee52e28d
+0,          5,          5,        1,   149760, 0xc25d9657
+0,          6,          6,        1,   149760, 0x0f644c82
+0,          7,          7,        1,   149760, 0x6f57aea1
diff --git a/tests/ref/fate/hevc-conformance-MERGE_B_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_B_TI_3
new file mode 100644
index 0000000..2f9395f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_B_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0xb5932505
+0,          2,          2,        1,   149760, 0xa5b20e66
+0,          3,          3,        1,   149760, 0x0d9f17cb
+0,          4,          4,        1,   149760, 0xf2b1dc80
+0,          5,          5,        1,   149760, 0xab8c8272
+0,          6,          6,        1,   149760, 0x50662cf4
+0,          7,          7,        1,   149760, 0x83cc8d5f
diff --git a/tests/ref/fate/hevc-conformance-MERGE_C_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_C_TI_3
new file mode 100644
index 0000000..bcc5a1a
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_C_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0x88cb1216
+0,          2,          2,        1,   149760, 0x6d1024da
+0,          3,          3,        1,   149760, 0x90b13981
+0,          4,          4,        1,   149760, 0x4296ed51
+0,          5,          5,        1,   149760, 0x4da5926f
+0,          6,          6,        1,   149760, 0xa74b4368
+0,          7,          7,        1,   149760, 0x518fb0fc
diff --git a/tests/ref/fate/hevc-conformance-MERGE_D_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_D_TI_3
new file mode 100644
index 0000000..7b4df26
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_D_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0x3220183c
+0,          2,          2,        1,   149760, 0x43a21acc
+0,          3,          3,        1,   149760, 0x7bde17f9
+0,          4,          4,        1,   149760, 0x98a1cece
+0,          5,          5,        1,   149760, 0x3d7b64b9
+0,          6,          6,        1,   149760, 0xd9311172
+0,          7,          7,        1,   149760, 0x90d192a3
diff --git a/tests/ref/fate/hevc-conformance-MERGE_E_TI_3 b/tests/ref/fate/hevc-conformance-MERGE_E_TI_3
new file mode 100644
index 0000000..8491172
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_E_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0x187419b5
+0,          2,          2,        1,   149760, 0x61100980
+0,          3,          3,        1,   149760, 0xd799123e
+0,          4,          4,        1,   149760, 0x9011c8d0
+0,          5,          5,        1,   149760, 0xeafe7d99
+0,          6,          6,        1,   149760, 0x94f32245
+0,          7,          7,        1,   149760, 0x8185910a
diff --git a/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4 b/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4
new file mode 100644
index 0000000..34a0979
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4
@@ -0,0 +1,42 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xcfffa013
+0,          1,          1,        1,   149760, 0xec800e71
+0,          2,          2,        1,   149760, 0x9fb014c7
+0,          3,          3,        1,   149760, 0xfd7a48a8
+0,          4,          4,        1,   149760, 0x99816bb5
+0,          5,          5,        1,   149760, 0x8645acaa
+0,          6,          6,        1,   149760, 0xd2a8e04b
+0,          7,          7,        1,   149760, 0xf96f038d
+0,          8,          8,        1,   149760, 0x82c62409
+0,          9,          9,        1,   149760, 0x64907b29
+0,         10,         10,        1,   149760, 0xfe29990e
+0,         11,         11,        1,   149760, 0xce2dc52d
+0,         12,         12,        1,   149760, 0x164fb2c5
+0,         13,         13,        1,   149760, 0xbcf8ca2d
+0,         14,         14,        1,   149760, 0xe59dc9bc
+0,         15,         15,        1,   149760, 0x2ab10400
+0,         16,         16,        1,   149760, 0xef111c81
+0,         17,         17,        1,   149760, 0xd08466b1
+0,         18,         18,        1,   149760, 0x6d356ff0
+0,         19,         19,        1,   149760, 0x16a59175
+0,         20,         20,        1,   149760, 0xd7888866
+0,         21,         21,        1,   149760, 0x2b22b943
+0,         22,         22,        1,   149760, 0x3b4fc3fe
+0,         23,         23,        1,   149760, 0x4ec8ee47
+0,         24,         24,        1,   149760, 0x0126f17b
+0,         25,         25,        1,   149760, 0x1176ad14
+0,         26,         26,        1,   149760, 0x2d4da75f
+0,         27,         27,        1,   149760, 0x144bb9e4
+0,         28,         28,        1,   149760, 0x5176a21b
+0,         29,         29,        1,   149760, 0x5e3fe673
+0,         30,         30,        1,   149760, 0xa533db65
+0,         31,         31,        1,   149760, 0x3009f3f8
+0,         32,         32,        1,   149760, 0xd4437e12
+0,         33,         33,        1,   149760, 0x5b03cd64
+0,         34,         34,        1,   149760, 0xdc40d49b
+0,         35,         35,        1,   149760, 0xf8cef0f6
+0,         36,         36,        1,   149760, 0x241be1b7
+0,         37,         37,        1,   149760, 0x23830404
+0,         38,         38,        1,   149760, 0x6ef7087e
+0,         39,         39,        1,   149760, 0xaf351e5b
+0,         40,         40,        1,   149760, 0x4cf40a64
diff --git a/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4 b/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4
new file mode 100644
index 0000000..2e88350
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x65433cfe
+0,          1,          1,        1,   599040, 0x9309e2c5
diff --git a/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3 b/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3
new file mode 100644
index 0000000..6756221
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xa5b11720
+0,          1,          1,        1,   149760, 0x42e52c6e
+0,          2,          2,        1,   149760, 0x27b15a30
+0,          3,          3,        1,   149760, 0x4d759826
+0,          4,          4,        1,   149760, 0xfb6daf0c
diff --git a/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3 b/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3
new file mode 100644
index 0000000..2019db2
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3
@@ -0,0 +1,501 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x9b27dc7d
+0,          1,          1,        1,   599040, 0x796cdd26
+0,          2,          2,        1,   599040, 0xd3c9dca9
+0,          3,          3,        1,   599040, 0xf7b2876a
+0,          4,          4,        1,   599040, 0x296701c8
+0,          5,          5,        1,   599040, 0xf9a80f9a
+0,          6,          6,        1,   599040, 0x7cbe9656
+0,          7,          7,        1,   599040, 0x17093be8
+0,          8,          8,        1,   599040, 0x2a0e196e
+0,          9,          9,        1,   599040, 0x3492c809
+0,         10,         10,        1,   599040, 0xbc5523f3
+0,         11,         11,        1,   599040, 0xf618ff66
+0,         12,         12,        1,   599040, 0x07060c9d
+0,         13,         13,        1,   599040, 0xd5a8fb5d
+0,         14,         14,        1,   599040, 0x780e18b9
+0,         15,         15,        1,   599040, 0xff553fbd
+0,         16,         16,        1,   599040, 0x715cce2d
+0,         17,         17,        1,   599040, 0x8a834c19
+0,         18,         18,        1,   599040, 0xbc4a0c21
+0,         19,         19,        1,   599040, 0xc85fed31
+0,         20,         20,        1,   599040, 0xcbb97b56
+0,         21,         21,        1,   599040, 0x518111dd
+0,         22,         22,        1,   599040, 0x5a680f48
+0,         23,         23,        1,   599040, 0x02956f28
+0,         24,         24,        1,   599040, 0x10845ef6
+0,         25,         25,        1,   599040, 0x2ad3c6d7
+0,         26,         26,        1,   599040, 0xa9f725e9
+0,         27,         27,        1,   599040, 0xb835f470
+0,         28,         28,        1,   599040, 0x693bf01d
+0,         29,         29,        1,   599040, 0x50bf3b77
+0,         30,         30,        1,   599040, 0x304873e3
+0,         31,         31,        1,   599040, 0x707a6af9
+0,         32,         32,        1,   599040, 0x50bf2017
+0,         33,         33,        1,   599040, 0x2c583f11
+0,         34,         34,        1,   599040, 0xe738080b
+0,         35,         35,        1,   599040, 0x549984e6
+0,         36,         36,        1,   599040, 0xa22e8a96
+0,         37,         37,        1,   599040, 0xc9f222cd
+0,         38,         38,        1,   599040, 0x28d944bc
+0,         39,         39,        1,   599040, 0x2e366350
+0,         40,         40,        1,   599040, 0xbcc2eb12
+0,         41,         41,        1,   599040, 0x074d3fdd
+0,         42,         42,        1,   599040, 0x0e0bd820
+0,         43,         43,        1,   599040, 0xf078af68
+0,         44,         44,        1,   599040, 0xaeed7222
+0,         45,         45,        1,   599040, 0xb66100cd
+0,         46,         46,        1,   599040, 0x848cd1c5
+0,         47,         47,        1,   599040, 0xa6bf930c
+0,         48,         48,        1,   599040, 0x32501b56
+0,         49,         49,        1,   599040, 0x2498d992
+0,         50,         50,        1,   599040, 0x03481b78
+0,         51,         51,        1,   599040, 0x551d7c11
+0,         52,         52,        1,   599040, 0xfbdc629d
+0,         53,         53,        1,   599040, 0x1f438ded
+0,         54,         54,        1,   599040, 0x4d25ce07
+0,         55,         55,        1,   599040, 0x4fe8f8aa
+0,         56,         56,        1,   599040, 0x5d65d790
+0,         57,         57,        1,   599040, 0xfcba4efb
+0,         58,         58,        1,   599040, 0x50b483a3
+0,         59,         59,        1,   599040, 0x12fd4b31
+0,         60,         60,        1,   599040, 0x71014417
+0,         61,         61,        1,   599040, 0xeed88bc4
+0,         62,         62,        1,   599040, 0xb2d4710d
+0,         63,         63,        1,   599040, 0xbe4dfe69
+0,         64,         64,        1,   599040, 0x9b7844b6
+0,         65,         65,        1,   599040, 0xe2e691bf
+0,         66,         66,        1,   599040, 0xb24200dc
+0,         67,         67,        1,   599040, 0xf29cb5bf
+0,         68,         68,        1,   599040, 0x90350310
+0,         69,         69,        1,   599040, 0xbe1cc3c1
+0,         70,         70,        1,   599040, 0xaae58f97
+0,         71,         71,        1,   599040, 0x0d5cb388
+0,         72,         72,        1,   599040, 0x0fa734e3
+0,         73,         73,        1,   599040, 0xaa41543a
+0,         74,         74,        1,   599040, 0x3e6e1d4b
+0,         75,         75,        1,   599040, 0x6426e543
+0,         76,         76,        1,   599040, 0xe65ad058
+0,         77,         77,        1,   599040, 0xf7f1744d
+0,         78,         78,        1,   599040, 0xa8fa32da
+0,         79,         79,        1,   599040, 0xa2c80e49
+0,         80,         80,        1,   599040, 0x22b972e9
+0,         81,         81,        1,   599040, 0x2462823b
+0,         82,         82,        1,   599040, 0xa7fd0432
+0,         83,         83,        1,   599040, 0x38d22ea4
+0,         84,         84,        1,   599040, 0xb472f4d6
+0,         85,         85,        1,   599040, 0x36c107a0
+0,         86,         86,        1,   599040, 0x9abb5ce0
+0,         87,         87,        1,   599040, 0x74b2861c
+0,         88,         88,        1,   599040, 0xba3d04d3
+0,         89,         89,        1,   599040, 0x65132373
+0,         90,         90,        1,   599040, 0x63585754
+0,         91,         91,        1,   599040, 0xa6c0f4d4
+0,         92,         92,        1,   599040, 0xc2cf9c33
+0,         93,         93,        1,   599040, 0xdf6d16af
+0,         94,         94,        1,   599040, 0x94566b11
+0,         95,         95,        1,   599040, 0x8070818d
+0,         96,         96,        1,   599040, 0x4acc92c1
+0,         97,         97,        1,   599040, 0xb520033c
+0,         98,         98,        1,   599040, 0xc82e7058
+0,         99,         99,        1,   599040, 0xb23367bc
+0,        100,        100,        1,   599040, 0x1fa25586
+0,        101,        101,        1,   599040, 0x2b2abbb8
+0,        102,        102,        1,   599040, 0xb9b74546
+0,        103,        103,        1,   599040, 0x4c4a2ef9
+0,        104,        104,        1,   599040, 0x5eb54025
+0,        105,        105,        1,   599040, 0x1e1cbcc6
+0,        106,        106,        1,   599040, 0xc3bf1017
+0,        107,        107,        1,   599040, 0xdbda1761
+0,        108,        108,        1,   599040, 0x19241b7c
+0,        109,        109,        1,   599040, 0x791dda93
+0,        110,        110,        1,   599040, 0x444a152f
+0,        111,        111,        1,   599040, 0x0b69d08b
+0,        112,        112,        1,   599040, 0xd024abae
+0,        113,        113,        1,   599040, 0x724e0d78
+0,        114,        114,        1,   599040, 0x648f9c09
+0,        115,        115,        1,   599040, 0xee114298
+0,        116,        116,        1,   599040, 0x92d1e98f
+0,        117,        117,        1,   599040, 0xb623cb10
+0,        118,        118,        1,   599040, 0xf8e9b414
+0,        119,        119,        1,   599040, 0xe47a0981
+0,        120,        120,        1,   599040, 0xdc78d28d
+0,        121,        121,        1,   599040, 0xd36d9ad5
+0,        122,        122,        1,   599040, 0xe7bea48e
+0,        123,        123,        1,   599040, 0x0dd39d1d
+0,        124,        124,        1,   599040, 0xb66a18ee
+0,        125,        125,        1,   599040, 0x6085d265
+0,        126,        126,        1,   599040, 0xb9ef646b
+0,        127,        127,        1,   599040, 0x544140a4
+0,        128,        128,        1,   599040, 0x9c546327
+0,        129,        129,        1,   599040, 0xd74d4a8e
+0,        130,        130,        1,   599040, 0x98a504e0
+0,        131,        131,        1,   599040, 0x88849351
+0,        132,        132,        1,   599040, 0xa519f6c7
+0,        133,        133,        1,   599040, 0xc548df7f
+0,        134,        134,        1,   599040, 0x8e690444
+0,        135,        135,        1,   599040, 0x5edbdced
+0,        136,        136,        1,   599040, 0xd3e189c2
+0,        137,        137,        1,   599040, 0x286d44a2
+0,        138,        138,        1,   599040, 0xe946f83e
+0,        139,        139,        1,   599040, 0xdc94ae6d
+0,        140,        140,        1,   599040, 0x5d4e95dc
+0,        141,        141,        1,   599040, 0x2c03280f
+0,        142,        142,        1,   599040, 0x368c6b23
+0,        143,        143,        1,   599040, 0x2fc5d2ee
+0,        144,        144,        1,   599040, 0x85e8f3ec
+0,        145,        145,        1,   599040, 0xd1fdcf69
+0,        146,        146,        1,   599040, 0xa663cf5a
+0,        147,        147,        1,   599040, 0x5d644057
+0,        148,        148,        1,   599040, 0xfdd039e0
+0,        149,        149,        1,   599040, 0x9cdb6369
+0,        150,        150,        1,   599040, 0x3c4ca86b
+0,        151,        151,        1,   599040, 0x27ac4d91
+0,        152,        152,        1,   599040, 0x3f13a8bb
+0,        153,        153,        1,   599040, 0xbcd984c5
+0,        154,        154,        1,   599040, 0xa55eb124
+0,        155,        155,        1,   599040, 0xb09c4a47
+0,        156,        156,        1,   599040, 0x0da7fd48
+0,        157,        157,        1,   599040, 0xa01dc374
+0,        158,        158,        1,   599040, 0xe428b3b0
+0,        159,        159,        1,   599040, 0xff3fcc43
+0,        160,        160,        1,   599040, 0xbc5491c1
+0,        161,        161,        1,   599040, 0x34e51a66
+0,        162,        162,        1,   599040, 0xb63f5acd
+0,        163,        163,        1,   599040, 0xe12f417d
+0,        164,        164,        1,   599040, 0x789bb191
+0,        165,        165,        1,   599040, 0x5fdeaa57
+0,        166,        166,        1,   599040, 0x65034250
+0,        167,        167,        1,   599040, 0xab577632
+0,        168,        168,        1,   599040, 0x1338c7eb
+0,        169,        169,        1,   599040, 0x5a84b078
+0,        170,        170,        1,   599040, 0x9f3fd6c2
+0,        171,        171,        1,   599040, 0x23cd7f3f
+0,        172,        172,        1,   599040, 0x43701c5c
+0,        173,        173,        1,   599040, 0x72eff5aa
+0,        174,        174,        1,   599040, 0x858a7280
+0,        175,        175,        1,   599040, 0x5d1da2b1
+0,        176,        176,        1,   599040, 0x2b6fae7b
+0,        177,        177,        1,   599040, 0x3d96cd3f
+0,        178,        178,        1,   599040, 0x5d6d48e5
+0,        179,        179,        1,   599040, 0x829023ee
+0,        180,        180,        1,   599040, 0xeafa5127
+0,        181,        181,        1,   599040, 0x1adf2830
+0,        182,        182,        1,   599040, 0x35f07617
+0,        183,        183,        1,   599040, 0x7aa691e2
+0,        184,        184,        1,   599040, 0xd11b3ed2
+0,        185,        185,        1,   599040, 0x69c12b52
+0,        186,        186,        1,   599040, 0x34fb8557
+0,        187,        187,        1,   599040, 0xd06c84ff
+0,        188,        188,        1,   599040, 0x26338170
+0,        189,        189,        1,   599040, 0x3d24f1e9
+0,        190,        190,        1,   599040, 0x28a99f46
+0,        191,        191,        1,   599040, 0x22421eea
+0,        192,        192,        1,   599040, 0xc53b57eb
+0,        193,        193,        1,   599040, 0x752433b8
+0,        194,        194,        1,   599040, 0x6332eaaa
+0,        195,        195,        1,   599040, 0x559d273f
+0,        196,        196,        1,   599040, 0xe9811056
+0,        197,        197,        1,   599040, 0x61acf706
+0,        198,        198,        1,   599040, 0x3893c930
+0,        199,        199,        1,   599040, 0x5d6d3f58
+0,        200,        200,        1,   599040, 0xb645df35
+0,        201,        201,        1,   599040, 0x6af7f2eb
+0,        202,        202,        1,   599040, 0xeb456cc5
+0,        203,        203,        1,   599040, 0x32abac64
+0,        204,        204,        1,   599040, 0x1327da04
+0,        205,        205,        1,   599040, 0x73ca53b9
+0,        206,        206,        1,   599040, 0xe940d23e
+0,        207,        207,        1,   599040, 0xc6fdf611
+0,        208,        208,        1,   599040, 0xc72e4309
+0,        209,        209,        1,   599040, 0xecab46a1
+0,        210,        210,        1,   599040, 0xb248b91e
+0,        211,        211,        1,   599040, 0xe9aeb62c
+0,        212,        212,        1,   599040, 0x5827cf39
+0,        213,        213,        1,   599040, 0x763a74d6
+0,        214,        214,        1,   599040, 0x232e397c
+0,        215,        215,        1,   599040, 0xe2ef8213
+0,        216,        216,        1,   599040, 0xddcbe94f
+0,        217,        217,        1,   599040, 0xe8a8919a
+0,        218,        218,        1,   599040, 0x5860fae0
+0,        219,        219,        1,   599040, 0x525b1a95
+0,        220,        220,        1,   599040, 0x50e36027
+0,        221,        221,        1,   599040, 0xd05ee599
+0,        222,        222,        1,   599040, 0xc1e7b87b
+0,        223,        223,        1,   599040, 0x2edfa52c
+0,        224,        224,        1,   599040, 0xca147244
+0,        225,        225,        1,   599040, 0x9e0a77b7
+0,        226,        226,        1,   599040, 0x88ac8035
+0,        227,        227,        1,   599040, 0xe34c890a
+0,        228,        228,        1,   599040, 0xbe4feadd
+0,        229,        229,        1,   599040, 0xd5a7503d
+0,        230,        230,        1,   599040, 0xae18e82d
+0,        231,        231,        1,   599040, 0x66cf3881
+0,        232,        232,        1,   599040, 0x9f08a65c
+0,        233,        233,        1,   599040, 0xeb3e1a58
+0,        234,        234,        1,   599040, 0x2b83004a
+0,        235,        235,        1,   599040, 0x65be32c9
+0,        236,        236,        1,   599040, 0x231586fa
+0,        237,        237,        1,   599040, 0x7e5724fb
+0,        238,        238,        1,   599040, 0xfebe47b6
+0,        239,        239,        1,   599040, 0xfeeb9a38
+0,        240,        240,        1,   599040, 0x44e90683
+0,        241,        241,        1,   599040, 0x546d03f4
+0,        242,        242,        1,   599040, 0x211a534e
+0,        243,        243,        1,   599040, 0x12d2a800
+0,        244,        244,        1,   599040, 0xa6022d19
+0,        245,        245,        1,   599040, 0x6bedd152
+0,        246,        246,        1,   599040, 0x6f7de80b
+0,        247,        247,        1,   599040, 0x778f0771
+0,        248,        248,        1,   599040, 0xe63e4241
+0,        249,        249,        1,   599040, 0xa0298023
+0,        250,        250,        1,   599040, 0xc4c5b8b2
+0,        251,        251,        1,   599040, 0xcca64f1c
+0,        252,        252,        1,   599040, 0xfec4d1a0
+0,        253,        253,        1,   599040, 0xcb7c4b80
+0,        254,        254,        1,   599040, 0x0795f7b7
+0,        255,        255,        1,   599040, 0x5f45706c
+0,        256,        256,        1,   599040, 0x927f04d8
+0,        257,        257,        1,   599040, 0x4c201f08
+0,        258,        258,        1,   599040, 0xdb447b37
+0,        259,        259,        1,   599040, 0xae33725e
+0,        260,        260,        1,   599040, 0x474281af
+0,        261,        261,        1,   599040, 0xe198764e
+0,        262,        262,        1,   599040, 0xb226916f
+0,        263,        263,        1,   599040, 0x8a7156a5
+0,        264,        264,        1,   599040, 0x5fe639ab
+0,        265,        265,        1,   599040, 0xaa62b79e
+0,        266,        266,        1,   599040, 0x94618e23
+0,        267,        267,        1,   599040, 0x47ba12f0
+0,        268,        268,        1,   599040, 0xd33c215e
+0,        269,        269,        1,   599040, 0x581e0537
+0,        270,        270,        1,   599040, 0x19dce924
+0,        271,        271,        1,   599040, 0x95329055
+0,        272,        272,        1,   599040, 0x6d2eb80f
+0,        273,        273,        1,   599040, 0x11d5e940
+0,        274,        274,        1,   599040, 0x30aec978
+0,        275,        275,        1,   599040, 0xd742df04
+0,        276,        276,        1,   599040, 0xef9ef4ae
+0,        277,        277,        1,   599040, 0x51d8fb34
+0,        278,        278,        1,   599040, 0xbb6e070a
+0,        279,        279,        1,   599040, 0x785a9813
+0,        280,        280,        1,   599040, 0xb94d8771
+0,        281,        281,        1,   599040, 0x8bd2fe53
+0,        282,        282,        1,   599040, 0x6b600868
+0,        283,        283,        1,   599040, 0x4b1d6a6f
+0,        284,        284,        1,   599040, 0x974f6365
+0,        285,        285,        1,   599040, 0xebefa21d
+0,        286,        286,        1,   599040, 0x8ce62dad
+0,        287,        287,        1,   599040, 0x7a6e6e1b
+0,        288,        288,        1,   599040, 0x3746d218
+0,        289,        289,        1,   599040, 0xc1aa50d9
+0,        290,        290,        1,   599040, 0xda60f976
+0,        291,        291,        1,   599040, 0x98274aa8
+0,        292,        292,        1,   599040, 0xdf09c760
+0,        293,        293,        1,   599040, 0xeb485b8f
+0,        294,        294,        1,   599040, 0xad76453b
+0,        295,        295,        1,   599040, 0x6eaee19a
+0,        296,        296,        1,   599040, 0x464e9cc8
+0,        297,        297,        1,   599040, 0xccd0bd12
+0,        298,        298,        1,   599040, 0xc7345e2b
+0,        299,        299,        1,   599040, 0xe51dd0a9
+0,        300,        300,        1,   599040, 0x11b9586b
+0,        301,        301,        1,   599040, 0xcb2c85b8
+0,        302,        302,        1,   599040, 0x024ce62d
+0,        303,        303,        1,   599040, 0x8c1da4eb
+0,        304,        304,        1,   599040, 0x9924ed3f
+0,        305,        305,        1,   599040, 0xc8f89a61
+0,        306,        306,        1,   599040, 0x52db38f2
+0,        307,        307,        1,   599040, 0xf1baca44
+0,        308,        308,        1,   599040, 0x8d1b322e
+0,        309,        309,        1,   599040, 0x5e8a990e
+0,        310,        310,        1,   599040, 0xfe281b7c
+0,        311,        311,        1,   599040, 0x065ced47
+0,        312,        312,        1,   599040, 0x962087db
+0,        313,        313,        1,   599040, 0x2e932805
+0,        314,        314,        1,   599040, 0x9a4b4946
+0,        315,        315,        1,   599040, 0x504bea02
+0,        316,        316,        1,   599040, 0xff97cf64
+0,        317,        317,        1,   599040, 0xcca9a61c
+0,        318,        318,        1,   599040, 0x1ab70ff5
+0,        319,        319,        1,   599040, 0x99ed2919
+0,        320,        320,        1,   599040, 0xa02f40d2
+0,        321,        321,        1,   599040, 0x8a1d83c2
+0,        322,        322,        1,   599040, 0xaacec6c2
+0,        323,        323,        1,   599040, 0x4f6fe261
+0,        324,        324,        1,   599040, 0x1dde4745
+0,        325,        325,        1,   599040, 0xa17bdf95
+0,        326,        326,        1,   599040, 0xcb5b56b3
+0,        327,        327,        1,   599040, 0x7088cdd4
+0,        328,        328,        1,   599040, 0xca02bafb
+0,        329,        329,        1,   599040, 0x3c5ca543
+0,        330,        330,        1,   599040, 0x4ab80de3
+0,        331,        331,        1,   599040, 0x75edb57b
+0,        332,        332,        1,   599040, 0x772ef858
+0,        333,        333,        1,   599040, 0xd7fa8d9f
+0,        334,        334,        1,   599040, 0xbc515acc
+0,        335,        335,        1,   599040, 0xb1b66d54
+0,        336,        336,        1,   599040, 0x40290b6a
+0,        337,        337,        1,   599040, 0xd1ff952e
+0,        338,        338,        1,   599040, 0x5641abf7
+0,        339,        339,        1,   599040, 0x3411e0fd
+0,        340,        340,        1,   599040, 0xed4abbaf
+0,        341,        341,        1,   599040, 0x34d40ea4
+0,        342,        342,        1,   599040, 0xa9983db0
+0,        343,        343,        1,   599040, 0x58dc8d9a
+0,        344,        344,        1,   599040, 0x24a989a2
+0,        345,        345,        1,   599040, 0xc9d1dcdd
+0,        346,        346,        1,   599040, 0x6df3031f
+0,        347,        347,        1,   599040, 0xa67339d9
+0,        348,        348,        1,   599040, 0x545b3ed1
+0,        349,        349,        1,   599040, 0xb4d98187
+0,        350,        350,        1,   599040, 0xdd2f8588
+0,        351,        351,        1,   599040, 0x2aee5737
+0,        352,        352,        1,   599040, 0xe7c90c87
+0,        353,        353,        1,   599040, 0xb547f0bc
+0,        354,        354,        1,   599040, 0x69cc594a
+0,        355,        355,        1,   599040, 0xa01adf9c
+0,        356,        356,        1,   599040, 0x77021bc9
+0,        357,        357,        1,   599040, 0x1cd7e74b
+0,        358,        358,        1,   599040, 0x4d284292
+0,        359,        359,        1,   599040, 0xe57fd832
+0,        360,        360,        1,   599040, 0x76992cf7
+0,        361,        361,        1,   599040, 0x88156158
+0,        362,        362,        1,   599040, 0xc872db18
+0,        363,        363,        1,   599040, 0xc0487bf4
+0,        364,        364,        1,   599040, 0x9f3aab7b
+0,        365,        365,        1,   599040, 0xfddd1c86
+0,        366,        366,        1,   599040, 0x2a991cff
+0,        367,        367,        1,   599040, 0x97e3623f
+0,        368,        368,        1,   599040, 0x69e5900a
+0,        369,        369,        1,   599040, 0x7a5167ec
+0,        370,        370,        1,   599040, 0x74bf045a
+0,        371,        371,        1,   599040, 0x5b2c1554
+0,        372,        372,        1,   599040, 0xc7e9c2e1
+0,        373,        373,        1,   599040, 0x9d76e364
+0,        374,        374,        1,   599040, 0x2c365ed8
+0,        375,        375,        1,   599040, 0x3b7bb213
+0,        376,        376,        1,   599040, 0x00a34fa9
+0,        377,        377,        1,   599040, 0x0a82f6b8
+0,        378,        378,        1,   599040, 0x34f8cf6b
+0,        379,        379,        1,   599040, 0x283a256f
+0,        380,        380,        1,   599040, 0x89dfe63a
+0,        381,        381,        1,   599040, 0x757c7bc3
+0,        382,        382,        1,   599040, 0xbcbf4f4a
+0,        383,        383,        1,   599040, 0x45fe93d3
+0,        384,        384,        1,   599040, 0xa93c4724
+0,        385,        385,        1,   599040, 0x25862ef7
+0,        386,        386,        1,   599040, 0xff94b8eb
+0,        387,        387,        1,   599040, 0x9d350c21
+0,        388,        388,        1,   599040, 0x90d6cce5
+0,        389,        389,        1,   599040, 0x5c3e51c8
+0,        390,        390,        1,   599040, 0x8f966096
+0,        391,        391,        1,   599040, 0xddc8ad04
+0,        392,        392,        1,   599040, 0xb64a170a
+0,        393,        393,        1,   599040, 0xfb8fa0c6
+0,        394,        394,        1,   599040, 0x99fa48dc
+0,        395,        395,        1,   599040, 0xd62e9344
+0,        396,        396,        1,   599040, 0x55ff8d51
+0,        397,        397,        1,   599040, 0x1e9809bd
+0,        398,        398,        1,   599040, 0x00f0122d
+0,        399,        399,        1,   599040, 0x5af2911e
+0,        400,        400,        1,   599040, 0xbfcd6c1d
+0,        401,        401,        1,   599040, 0xd809c652
+0,        402,        402,        1,   599040, 0xee36969a
+0,        403,        403,        1,   599040, 0x9c0ed842
+0,        404,        404,        1,   599040, 0x4e07a2b0
+0,        405,        405,        1,   599040, 0xa5b3202b
+0,        406,        406,        1,   599040, 0x4c1add0e
+0,        407,        407,        1,   599040, 0x489b2fa9
+0,        408,        408,        1,   599040, 0xa088c512
+0,        409,        409,        1,   599040, 0x4f6121ac
+0,        410,        410,        1,   599040, 0x1959f62b
+0,        411,        411,        1,   599040, 0x2d51a5c4
+0,        412,        412,        1,   599040, 0x95e70f4f
+0,        413,        413,        1,   599040, 0x4eab3c11
+0,        414,        414,        1,   599040, 0xf2c2b9b5
+0,        415,        415,        1,   599040, 0x62f50ffe
+0,        416,        416,        1,   599040, 0x2104d2f8
+0,        417,        417,        1,   599040, 0x42a8b39f
+0,        418,        418,        1,   599040, 0x857f1fe6
+0,        419,        419,        1,   599040, 0x6ac5190d
+0,        420,        420,        1,   599040, 0x228d7a0b
+0,        421,        421,        1,   599040, 0x0042ef94
+0,        422,        422,        1,   599040, 0x4a83e001
+0,        423,        423,        1,   599040, 0xc43fec08
+0,        424,        424,        1,   599040, 0x5e029548
+0,        425,        425,        1,   599040, 0xbc89dea9
+0,        426,        426,        1,   599040, 0x6c5d88cf
+0,        427,        427,        1,   599040, 0x3a5dabfb
+0,        428,        428,        1,   599040, 0x876e1e54
+0,        429,        429,        1,   599040, 0x55715da8
+0,        430,        430,        1,   599040, 0x199c039b
+0,        431,        431,        1,   599040, 0x0286f71e
+0,        432,        432,        1,   599040, 0xf9a244a1
+0,        433,        433,        1,   599040, 0xf5655275
+0,        434,        434,        1,   599040, 0xde3dba0c
+0,        435,        435,        1,   599040, 0x617f8963
+0,        436,        436,        1,   599040, 0x0fe0e661
+0,        437,        437,        1,   599040, 0x8ba905ea
+0,        438,        438,        1,   599040, 0xb2812b34
+0,        439,        439,        1,   599040, 0x32d61c8b
+0,        440,        440,        1,   599040, 0xb7603400
+0,        441,        441,        1,   599040, 0x232c278f
+0,        442,        442,        1,   599040, 0xdf61c27d
+0,        443,        443,        1,   599040, 0xa053482f
+0,        444,        444,        1,   599040, 0x109724d3
+0,        445,        445,        1,   599040, 0x49d36800
+0,        446,        446,        1,   599040, 0x4a103bff
+0,        447,        447,        1,   599040, 0x7cd3813b
+0,        448,        448,        1,   599040, 0xeef677d7
+0,        449,        449,        1,   599040, 0xc5ad66c2
+0,        450,        450,        1,   599040, 0xa06e472d
+0,        451,        451,        1,   599040, 0x53182cc5
+0,        452,        452,        1,   599040, 0x9e62bfc0
+0,        453,        453,        1,   599040, 0x93515843
+0,        454,        454,        1,   599040, 0x5e0778d7
+0,        455,        455,        1,   599040, 0x957a6d55
+0,        456,        456,        1,   599040, 0x0bc26b3d
+0,        457,        457,        1,   599040, 0x5e0bc514
+0,        458,        458,        1,   599040, 0x7f717a98
+0,        459,        459,        1,   599040, 0x8497968c
+0,        460,        460,        1,   599040, 0x8fb527b8
+0,        461,        461,        1,   599040, 0x8580e487
+0,        462,        462,        1,   599040, 0x59b2d7cc
+0,        463,        463,        1,   599040, 0x5fbc38d7
+0,        464,        464,        1,   599040, 0xb1ba014e
+0,        465,        465,        1,   599040, 0x10481d8f
+0,        466,        466,        1,   599040, 0xd42e42e0
+0,        467,        467,        1,   599040, 0x14a361c1
+0,        468,        468,        1,   599040, 0x58378917
+0,        469,        469,        1,   599040, 0xaeb99a82
+0,        470,        470,        1,   599040, 0x5666ef55
+0,        471,        471,        1,   599040, 0xbd0ce495
+0,        472,        472,        1,   599040, 0xf13af36c
+0,        473,        473,        1,   599040, 0x55e8b101
+0,        474,        474,        1,   599040, 0x4e2966b4
+0,        475,        475,        1,   599040, 0xd973e873
+0,        476,        476,        1,   599040, 0x72d55685
+0,        477,        477,        1,   599040, 0x48eee8c2
+0,        478,        478,        1,   599040, 0x61291b38
+0,        479,        479,        1,   599040, 0x91f839f8
+0,        480,        480,        1,   599040, 0x0a4e9585
+0,        481,        481,        1,   599040, 0x02e0f1f0
+0,        482,        482,        1,   599040, 0xc104009c
+0,        483,        483,        1,   599040, 0x9417127e
+0,        484,        484,        1,   599040, 0x4630302e
+0,        485,        485,        1,   599040, 0x692141ea
+0,        486,        486,        1,   599040, 0x1ebed0bd
+0,        487,        487,        1,   599040, 0x362544a8
+0,        488,        488,        1,   599040, 0xd9cbef36
+0,        489,        489,        1,   599040, 0x54cda997
+0,        490,        490,        1,   599040, 0x79463ed1
+0,        491,        491,        1,   599040, 0xe95b66eb
+0,        492,        492,        1,   599040, 0x5bdaa63e
+0,        493,        493,        1,   599040, 0x72ced562
+0,        494,        494,        1,   599040, 0xcb2bdc53
+0,        495,        495,        1,   599040, 0x4ff80855
+0,        496,        496,        1,   599040, 0x68515ba6
+0,        497,        497,        1,   599040, 0x56228d2d
+0,        498,        498,        1,   599040, 0xb72a68ed
+0,        499,        499,        1,   599040, 0x111cc604
diff --git a/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3 b/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3
new file mode 100644
index 0000000..0db06c5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3
@@ -0,0 +1,18 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x1d68213a
+0,          1,          1,        1,   149760, 0x9cc81d30
+0,          2,          2,        1,   149760, 0xa3cf6438
+0,          3,          3,        1,   149760, 0x6acf213a
+0,          4,          4,        1,   149760, 0x0f75ce7b
+0,          5,          5,        1,   149760, 0x5e0286a7
+0,          6,          6,        1,   149760, 0xc62cd2b0
+0,          7,          7,        1,   149760, 0x7d9af3ac
+0,          8,          8,        1,   149760, 0x9d58afc7
+0,          9,          9,        1,   149760, 0x91c5ad7f
+0,         10,         10,        1,   149760, 0xc43c5b0a
+0,         11,         11,        1,   149760, 0x6b8cc1a5
+0,         12,         12,        1,   149760, 0x4cebb13e
+0,         13,         13,        1,   149760, 0xca136846
+0,         14,         14,        1,   149760, 0xba22e581
+0,         15,         15,        1,   149760, 0x2844ddd3
+0,         16,         16,        1,   149760, 0xf943399e
diff --git a/tests/ref/fate/hevc-conformance-NUT_A_ericsson_4 b/tests/ref/fate/hevc-conformance-NUT_A_ericsson_4
new file mode 100644
index 0000000..fe65880
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-NUT_A_ericsson_4
@@ -0,0 +1,35 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8ce7200b
+0,          1,          1,        1,   149760, 0x73610669
+0,          2,          2,        1,   149760, 0x42942047
+0,          3,          3,        1,   149760, 0x57334d85
+0,          4,          4,        1,   149760, 0xdd97fbb3
+0,          5,          5,        1,   149760, 0x10469b12
+0,          6,          6,        1,   149760, 0x9b4231f0
+0,          7,          7,        1,   149760, 0x2b295a52
+0,          8,          8,        1,   149760, 0xdaf7c29f
+0,          9,          9,        1,   149760, 0x6798d072
+0,         10,         10,        1,   149760, 0xf77ae91e
+0,         11,         11,        1,   149760, 0xe2d516c9
+0,         12,         12,        1,   149760, 0x5cf0b221
+0,         13,         13,        1,   149760, 0x1d34991e
+0,         14,         14,        1,   149760, 0xb730d93a
+0,         15,         15,        1,   149760, 0x643b1861
+0,         16,         16,        1,   149760, 0x436586ff
+0,         17,         17,        1,   149760, 0xa65d9b80
+0,         18,         18,        1,   149760, 0x1d395210
+0,         19,         19,        1,   149760, 0x0580f2be
+0,         20,         20,        1,   149760, 0x8e4cea96
+0,         21,         21,        1,   149760, 0x6c98d019
+0,         22,         22,        1,   149760, 0x842803c8
+0,         23,         23,        1,   149760, 0xddc196ee
+0,         24,         24,        1,   149760, 0x89e45523
+0,         25,         25,        1,   149760, 0x2a36b008
+0,         26,         26,        1,   149760, 0x14a319f7
+0,         27,         27,        1,   149760, 0x7394854c
+0,         28,         28,        1,   149760, 0x26dcf933
+0,         29,         29,        1,   149760, 0x5b000b7e
+0,         30,         30,        1,   149760, 0x6e76bded
+0,         31,         31,        1,   149760, 0x0284d92d
+0,         32,         32,        1,   149760, 0xf14a25e0
+0,         33,         33,        1,   149760, 0x10c03d98
diff --git a/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1 b/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1
new file mode 100644
index 0000000..4c09ca5
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1, 13368960, 0x830b3a1d
+0,          1,          1,        1, 13368960, 0x120ca009
+0,          2,          2,        1, 13368960, 0xc94e0d86
+0,          3,          3,        1, 13368960, 0x3e97d237
+0,          4,          4,        1, 13368960, 0x1caaa873
+0,          5,          5,        1, 13368960, 0xc6af86c6
+0,          6,          6,        1, 13368960, 0x277ee61a
+0,          7,          7,        1, 13368960, 0x7832ef4e
+0,          8,          8,        1, 13368960, 0x328142e9
+0,          9,          9,        1, 13368960, 0xbe22f686
diff --git a/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1 b/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1
new file mode 100644
index 0000000..a3ab7c8
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1, 13368960, 0xe1e32c3d
+0,          1,          1,        1, 13368960, 0x75a503d3
+0,          2,          2,        1, 13368960, 0x71f33a0a
+0,          3,          3,        1, 13368960, 0xd9fe5306
+0,          4,          4,        1, 13368960, 0x2528926a
+0,          5,          5,        1, 13368960, 0x4ae4e500
+0,          6,          6,        1, 13368960, 0x01949c16
+0,          7,          7,        1, 13368960, 0x57b6ea2f
+0,          8,          8,        1, 13368960, 0xfd2b2055
+0,          9,          9,        1, 13368960, 0xc4246a9b
diff --git a/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1 b/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1
new file mode 100644
index 0000000..10520d1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3339072, 0x28be238d
+0,          1,          1,        1,  3339072, 0x43b62aae
+0,          2,          2,        1,  3339072, 0x36259da6
+0,          3,          3,        1,  3339072, 0xd0dbbc1e
+0,          4,          4,        1,  3339072, 0x20df7c7c
+0,          5,          5,        1,  3339072, 0xb8872e77
+0,          6,          6,        1,  3339072, 0xceb4cce4
+0,          7,          7,        1,  3339072, 0x4ffa1dab
+0,          8,          8,        1,  3339072, 0x1c687703
+0,          9,          9,        1,  3339072, 0x5a0fa46f
diff --git a/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1 b/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1
new file mode 100644
index 0000000..6f1c4fb
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3339072, 0xcb16f53e
+0,          1,          1,        1,  3339072, 0x6f1da8ec
+0,          2,          2,        1,  3339072, 0x978dae98
+0,          3,          3,        1,  3339072, 0x34becc01
+0,          4,          4,        1,  3339072, 0x9c900137
+0,          5,          5,        1,  3339072, 0x02fe1d40
+0,          6,          6,        1,  3339072, 0xda9703b6
+0,          7,          7,        1,  3339072, 0x73e5ff5a
+0,          8,          8,        1,  3339072, 0xeec94fab
+0,          9,          9,        1,  3339072, 0xf4a36fc5
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3
new file mode 100644
index 0000000..8491172
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0x187419b5
+0,          2,          2,        1,   149760, 0x61100980
+0,          3,          3,        1,   149760, 0xd799123e
+0,          4,          4,        1,   149760, 0x9011c8d0
+0,          5,          5,        1,   149760, 0xeafe7d99
+0,          6,          6,        1,   149760, 0x94f32245
+0,          7,          7,        1,   149760, 0x8185910a
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3
new file mode 100644
index 0000000..1f15a02
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0xcebf1b76
+0,          2,          2,        1,   149760, 0x33930fb0
+0,          3,          3,        1,   149760, 0xb2933277
+0,          4,          4,        1,   149760, 0x2ff5fd5d
+0,          5,          5,        1,   149760, 0x6616a17a
+0,          6,          6,        1,   149760, 0x3abc48ad
+0,          7,          7,        1,   149760, 0xc12491ef
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3
new file mode 100644
index 0000000..bf474cc
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0x2c271a9b
+0,          2,          2,        1,   149760, 0x53e419f3
+0,          3,          3,        1,   149760, 0x96c92a29
+0,          4,          4,        1,   149760, 0x62d5e85b
+0,          5,          5,        1,   149760, 0xea307d47
+0,          6,          6,        1,   149760, 0x9cc40dec
+0,          7,          7,        1,   149760, 0x37d977fa
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3
new file mode 100644
index 0000000..2af0e1f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0xf11a32ce
+0,          2,          2,        1,   149760, 0x0802237c
+0,          3,          3,        1,   149760, 0x366621a7
+0,          4,          4,        1,   149760, 0x89aacefd
+0,          5,          5,        1,   149760, 0xb3837d16
+0,          6,          6,        1,   149760, 0x5f822072
+0,          7,          7,        1,   149760, 0x24cb9377
diff --git a/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3 b/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3
new file mode 100644
index 0000000..df97237
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0xea7b30bf
+0,          2,          2,        1,   149760, 0x273d092a
+0,          3,          3,        1,   149760, 0xef4e0ff0
+0,          4,          4,        1,   149760, 0x9805e02c
+0,          5,          5,        1,   149760, 0xdeb17cbc
+0,          6,          6,        1,   149760, 0xe5c903a4
+0,          7,          7,        1,   149760, 0x838d66b9
diff --git a/tests/ref/fate/hevc-conformance-POC_A_Bossen_3 b/tests/ref/fate/hevc-conformance-POC_A_Bossen_3
new file mode 100644
index 0000000..bcfa7fa
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-POC_A_Bossen_3
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xda17acd4
+0,          0,          0,        1,   149760, 0x1691b47f
+0,          1,          1,        1,   149760, 0xeebeac0c
+0,          2,          2,        1,   149760, 0x895c9f62
+0,          3,          3,        1,   149760, 0x9e2077e8
diff --git a/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7 b/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7
new file mode 100644
index 0000000..ef57f74
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7
@@ -0,0 +1,82 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x87159328
+0,          1,          1,        1,   599040, 0x825672ff
+0,          2,          2,        1,   599040, 0x2f4224ff
+0,          3,          3,        1,   599040, 0x4be431ff
+0,          4,          4,        1,   599040, 0xa0118b14
+0,          5,          5,        1,   599040, 0x488aac33
+0,          6,          6,        1,   599040, 0x1edd0d4e
+0,          7,          7,        1,   599040, 0x7f4562a2
+0,          8,          8,        1,   599040, 0xe177a7d4
+0,          9,          9,        1,   599040, 0x32d2fd58
+0,         10,         10,        1,   599040, 0x81d50c36
+0,         11,         11,        1,   599040, 0xdf32810d
+0,         12,         12,        1,   599040, 0xc4f50543
+0,         13,         13,        1,   599040, 0x777bfdce
+0,         14,         14,        1,   599040, 0x01db8731
+0,         15,         15,        1,   599040, 0x74ae2b2c
+0,         16,         16,        1,   599040, 0x424e130a
+0,         17,         17,        1,   599040, 0x7002f7c8
+0,         18,         18,        1,   599040, 0xde098c5b
+0,         19,         19,        1,   599040, 0x072ca0e3
+0,         20,         20,        1,   599040, 0x6c50e3ba
+0,         21,         21,        1,   599040, 0xa398c530
+0,         22,         22,        1,   599040, 0xcd8a780a
+0,         23,         23,        1,   599040, 0x7c849e63
+0,         24,         24,        1,   599040, 0xb70e2a1f
+0,         25,         25,        1,   599040, 0xc00d893c
+0,         26,         26,        1,   599040, 0x5da32c94
+0,         27,         27,        1,   599040, 0xc3177b8c
+0,         28,         28,        1,   599040, 0x06668480
+0,         29,         29,        1,   599040, 0xbceeac78
+0,         30,         30,        1,   599040, 0x162d5cd1
+0,         31,         31,        1,   599040, 0x071b71c4
+0,         32,         32,        1,   599040, 0xfe61e0b2
+0,         33,         33,        1,   599040, 0xe78c121f
+0,         34,         34,        1,   599040, 0x3b47c051
+0,         35,         35,        1,   599040, 0x10c1eedd
+0,         36,         36,        1,   599040, 0x09cf2d2c
+0,         37,         37,        1,   599040, 0xc4272450
+0,         38,         38,        1,   599040, 0x3a9e0db7
+0,         39,         39,        1,   599040, 0xe62595ad
+0,         40,         40,        1,   599040, 0xc03669a5
+0,         41,         41,        1,   599040, 0x4fbb058e
+0,         42,         42,        1,   599040, 0xaaee8771
+0,         43,         43,        1,   599040, 0xcc4f3a71
+0,         44,         44,        1,   599040, 0xc5717c31
+0,         45,         45,        1,   599040, 0xe2bc02fc
+0,         46,         46,        1,   599040, 0x380e06eb
+0,         47,         47,        1,   599040, 0x15d4ba04
+0,         48,         48,        1,   599040, 0xb9204342
+0,         49,         49,        1,   599040, 0xb9d9a246
+0,         50,         50,        1,   599040, 0xb5611280
+0,         51,         51,        1,   599040, 0xc80e3909
+0,         52,         52,        1,   599040, 0xef93ecbd
+0,         53,         53,        1,   599040, 0xdd6b435e
+0,         54,         54,        1,   599040, 0x1622f253
+0,         55,         55,        1,   599040, 0x41cd55a6
+0,         56,         56,        1,   599040, 0x7ed864e7
+0,         57,         57,        1,   599040, 0x1604c563
+0,         58,         58,        1,   599040, 0x1d5a3dc9
+0,         59,         59,        1,   599040, 0xa904a8a5
+0,         60,         60,        1,   599040, 0x19c43226
+0,         61,         61,        1,   599040, 0x60d803e0
+0,         62,         62,        1,   599040, 0xe862b0e0
+0,         63,         63,        1,   599040, 0x37c76c51
+0,         64,         64,        1,   599040, 0x8528cc3c
+0,         65,         65,        1,   599040, 0x03ece1f9
+0,         66,         66,        1,   599040, 0x8f0ef28e
+0,         67,         67,        1,   599040, 0x92164007
+0,         68,         68,        1,   599040, 0x9d3c2ecf
+0,         69,         69,        1,   599040, 0xacf536d4
+0,         70,         70,        1,   599040, 0xbdf6165f
+0,         71,         71,        1,   599040, 0xbc19f80a
+0,         72,         72,        1,   599040, 0x128a6480
+0,         73,         73,        1,   599040, 0xb487c333
+0,         74,         74,        1,   599040, 0x8dc350fa
+0,         75,         75,        1,   599040, 0x0043fe96
+0,         76,         76,        1,   599040, 0x47b502a5
+0,         77,         77,        1,   599040, 0xf62b761f
+0,         78,         78,        1,   599040, 0x608f63c3
+0,         79,         79,        1,   599040, 0xe285d93d
+0,         80,         80,        1,   599040, 0x1c3404cf
diff --git a/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3 b/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3
new file mode 100644
index 0000000..8f7e5e6
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x88619f80
+0,          1,          1,        1,   149760, 0x550bdaf0
+0,          2,          2,        1,   149760, 0x4121f7a2
+0,          3,          3,        1,   149760, 0x210b1d07
+0,          4,          4,        1,   149760, 0x731b7758
+0,          5,          5,        1,   149760, 0x17adb789
+0,          6,          6,        1,   149760, 0x98b2f080
+0,          7,          7,        1,   149760, 0xc0be1f2a
+0,          8,          8,        1,   149760, 0xc01e387a
+0,          9,          9,        1,   149760, 0xd932822b
+0,         10,         10,        1,   149760, 0x16c0a1df
+0,         11,         11,        1,   149760, 0x5aa6c005
+0,         12,         12,        1,   149760, 0xd3aab602
+0,         13,         13,        1,   149760, 0x4e6ecab1
+0,         14,         14,        1,   149760, 0x8a86f1f2
+0,         15,         15,        1,   149760, 0x2ed21e1b
+0,         16,         16,        1,   149760, 0x80892f24
+0,         17,         17,        1,   149760, 0xb8a952ef
+0,         18,         18,        1,   149760, 0x557e57fb
+0,         19,         19,        1,   149760, 0x2b825b2c
+0,         20,         20,        1,   149760, 0x30b69b5e
+0,         21,         21,        1,   149760, 0x802ebf08
+0,         22,         22,        1,   149760, 0x95aadc8e
+0,         23,         23,        1,   149760, 0x4d4c02b7
+0,         24,         24,        1,   149760, 0x3fdd1762
diff --git a/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3 b/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3
new file mode 100644
index 0000000..8f7e5e6
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3
@@ -0,0 +1,26 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x88619f80
+0,          1,          1,        1,   149760, 0x550bdaf0
+0,          2,          2,        1,   149760, 0x4121f7a2
+0,          3,          3,        1,   149760, 0x210b1d07
+0,          4,          4,        1,   149760, 0x731b7758
+0,          5,          5,        1,   149760, 0x17adb789
+0,          6,          6,        1,   149760, 0x98b2f080
+0,          7,          7,        1,   149760, 0xc0be1f2a
+0,          8,          8,        1,   149760, 0xc01e387a
+0,          9,          9,        1,   149760, 0xd932822b
+0,         10,         10,        1,   149760, 0x16c0a1df
+0,         11,         11,        1,   149760, 0x5aa6c005
+0,         12,         12,        1,   149760, 0xd3aab602
+0,         13,         13,        1,   149760, 0x4e6ecab1
+0,         14,         14,        1,   149760, 0x8a86f1f2
+0,         15,         15,        1,   149760, 0x2ed21e1b
+0,         16,         16,        1,   149760, 0x80892f24
+0,         17,         17,        1,   149760, 0xb8a952ef
+0,         18,         18,        1,   149760, 0x557e57fb
+0,         19,         19,        1,   149760, 0x2b825b2c
+0,         20,         20,        1,   149760, 0x30b69b5e
+0,         21,         21,        1,   149760, 0x802ebf08
+0,         22,         22,        1,   149760, 0x95aadc8e
+0,         23,         23,        1,   149760, 0x4d4c02b7
+0,         24,         24,        1,   149760, 0x3fdd1762
diff --git a/tests/ref/fate/hevc-conformance-RAP_A_docomo_4 b/tests/ref/fate/hevc-conformance-RAP_A_docomo_4
new file mode 100644
index 0000000..268f4cd
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RAP_A_docomo_4
@@ -0,0 +1,87 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x1ae5f13d
+0,          1,          1,        1,   149760, 0x0a6ad0e3
+0,          2,          2,        1,   149760, 0x2415af05
+0,          3,          3,        1,   149760, 0xf50f6eef
+0,          4,          4,        1,   149760, 0xef65835c
+0,          5,          5,        1,   149760, 0x4929b5cb
+0,          6,          6,        1,   149760, 0x165c6f55
+0,          7,          7,        1,   149760, 0x9caaa249
+0,          8,          8,        1,   149760, 0x6c25c4cf
+0,          9,          9,        1,   149760, 0x4678cef0
+0,         10,         10,        1,   149760, 0x72e04433
+0,         11,         11,        1,   149760, 0x36f8aa9d
+0,         12,         12,        1,   149760, 0x255189ad
+0,         13,         13,        1,   149760, 0x712d7f7f
+0,         14,         14,        1,   149760, 0x4d088988
+0,         15,         15,        1,   149760, 0xc0da3925
+0,         16,         16,        1,   149760, 0x9990db7c
+0,         17,         17,        1,   149760, 0xb02cc0e8
+0,         18,         18,        1,   149760, 0x3e859d8f
+0,         19,         19,        1,   149760, 0xce786bc1
+0,         20,         20,        1,   149760, 0x87555e5f
+0,         21,         21,        1,   149760, 0x3c95fb7e
+0,         22,         22,        1,   149760, 0xf092b65e
+0,         23,         23,        1,   149760, 0x7db2c04c
+0,         24,         24,        1,   149760, 0x7d39eb21
+0,         25,         25,        1,   149760, 0x2cfd7d57
+0,         26,         26,        1,   149760, 0xb1902c06
+0,         27,         27,        1,   149760, 0xe0eae1d7
+0,         28,         28,        1,   149760, 0xf8212977
+0,         29,         29,        1,   149760, 0x6cb31328
+0,         30,         30,        1,   149760, 0x862ab736
+0,         31,         31,        1,   149760, 0xc7a87f44
+0,         32,         32,        1,   149760, 0x8ff7a1a1
+0,         33,         33,        1,   149760, 0xd7bee49b
+0,         34,         34,        1,   149760, 0x1925db84
+0,         35,         35,        1,   149760, 0xf32a7dc6
+0,         36,         36,        1,   149760, 0x02a1e3b6
+0,         37,         37,        1,   149760, 0xb6398aad
+0,         38,         38,        1,   149760, 0xa3756e2d
+0,         39,         39,        1,   149760, 0xf90f3732
+0,         40,         40,        1,   149760, 0x3b05115a
+0,         41,         41,        1,   149760, 0x81ca9bdb
+0,         42,         42,        1,   149760, 0xa75ee938
+0,         43,         43,        1,   149760, 0x9e5c232f
+0,         44,         44,        1,   149760, 0x64cb04e9
+0,         45,         45,        1,   149760, 0x4064df52
+0,         46,         46,        1,   149760, 0x47fa0afc
+0,         47,         47,        1,   149760, 0xd209252e
+0,         48,         48,        1,   149760, 0x2f811f02
+0,         49,         49,        1,   149760, 0x733b6721
+0,         50,         50,        1,   149760, 0x30b12427
+0,         51,         51,        1,   149760, 0xdf58d3e2
+0,         52,         52,        1,   149760, 0xc144d7be
+0,         53,         53,        1,   149760, 0x48f0ac79
+0,         54,         54,        1,   149760, 0xb8d8a2c6
+0,         55,         55,        1,   149760, 0x2a7d916d
+0,         56,         56,        1,   149760, 0xd9d38cd5
+0,         57,         57,        1,   149760, 0xd7c7f9a6
+0,         58,         58,        1,   149760, 0x64d0df7a
+0,         59,         59,        1,   149760, 0x4e365cff
+0,         60,         60,        1,   149760, 0x74bc2a8b
+0,         61,         61,        1,   149760, 0x70a7cd2b
+0,         62,         62,        1,   149760, 0x0836b51e
+0,         63,         63,        1,   149760, 0xbc37b5d7
+0,         64,         64,        1,   149760, 0xb6d651e5
+0,         65,         65,        1,   149760, 0x7aa0e35f
+0,         66,         66,        1,   149760, 0x0fbc89a3
+0,         67,         67,        1,   149760, 0x2ca2f2a6
+0,         68,         68,        1,   149760, 0xf742c5c5
+0,         69,         69,        1,   149760, 0x4117208f
+0,         70,         70,        1,   149760, 0xec392efb
+0,         71,         71,        1,   149760, 0xbfba5063
+0,         72,         72,        1,   149760, 0xb2499f48
+0,         73,         73,        1,   149760, 0xf1183244
+0,         74,         74,        1,   149760, 0x364a6400
+0,         75,         75,        1,   149760, 0xfcfddf36
+0,         76,         76,        1,   149760, 0xbcc1b37e
+0,         77,         77,        1,   149760, 0xab364748
+0,         78,         78,        1,   149760, 0xebb27fcd
+0,         79,         79,        1,   149760, 0xe2e7a723
+0,         80,         80,        1,   149760, 0xf671b5e0
+0,         81,         81,        1,   149760, 0xbf0cc349
+0,         82,         82,        1,   149760, 0xf195d868
+0,         83,         83,        1,   149760, 0xe0097460
+0,         84,         84,        1,   149760, 0x3d4c1812
+0,         85,         85,        1,   149760, 0x133cd867
diff --git a/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1 b/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1
new file mode 100644
index 0000000..4bea997
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1
@@ -0,0 +1,84 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xb989ae7a
+0,          1,          1,        1,   149760, 0x4765caed
+0,          2,          2,        1,   149760, 0xd908c148
+0,          3,          3,        1,   149760, 0xf6ebd66c
+0,          4,          4,        1,   149760, 0x5d5ea14b
+0,          5,          5,        1,   149760, 0xcc939a7c
+0,          6,          6,        1,   149760, 0xa91b8243
+0,          7,          7,        1,   149760, 0x61926618
+0,          8,          8,        1,   149760, 0xe440099c
+0,          9,          9,        1,   149760, 0x18b88a73
+0,         10,         10,        1,   149760, 0xa669f2a9
+0,         11,         11,        1,   149760, 0xc2f6af3a
+0,         12,         12,        1,   149760, 0x02465354
+0,         13,         13,        1,   149760, 0x54e51ff9
+0,         14,         14,        1,   149760, 0xb9f3c056
+0,         15,         15,        1,   149760, 0x050274f9
+0,         16,         16,        1,   149760, 0xd7a413c1
+0,         17,         17,        1,   149760, 0x6e92cda4
+0,         18,         18,        1,   149760, 0x9cb86d4d
+0,         19,         19,        1,   149760, 0x95f440a3
+0,         20,         20,        1,   149760, 0x6dabd616
+0,         21,         21,        1,   149760, 0xd6a0b62d
+0,         22,         22,        1,   149760, 0x585c811b
+0,         23,         23,        1,   149760, 0x50a4d6fc
+0,         24,         24,        1,   149760, 0xe419eb23
+0,         25,         25,        1,   149760, 0x1f0fc316
+0,         26,         26,        1,   149760, 0xf61dc981
+0,         27,         27,        1,   149760, 0xff34d001
+0,         28,         28,        1,   149760, 0x598be76c
+0,         29,         29,        1,   149760, 0xbb50a4d6
+0,         30,         30,        1,   149760, 0x2add9abd
+0,         31,         31,        1,   149760, 0xd74185c7
+0,         32,         32,        1,   149760, 0xcdad6e8e
+0,         33,         33,        1,   149760, 0x54d704ad
+0,         34,         34,        1,   149760, 0xe52e7fc0
+0,         35,         35,        1,   149760, 0xdb331061
+0,         36,         36,        1,   149760, 0x7dacb973
+0,         37,         37,        1,   149760, 0xfc8d5670
+0,         38,         38,        1,   149760, 0xca9024cd
+0,         39,         39,        1,   149760, 0x7fc9bbc2
+0,         40,         40,        1,   149760, 0xe9c386a9
+0,         41,         41,        1,   149760, 0xd0dd1a21
+0,         42,         42,        1,   149760, 0x4b57d734
+0,         43,         43,        1,   149760, 0x55607afc
+0,         44,         44,        1,   149760, 0x567c3e8b
+0,         45,         45,        1,   149760, 0x312eda16
+0,         46,         46,        1,   149760, 0xafcbacf8
+0,         47,         47,        1,   149760, 0xcbde8420
+0,         48,         48,        1,   149760, 0x88a2f29e
+0,         49,         49,        1,   149760, 0x417bf220
+0,         50,         50,        1,   149760, 0xa454835a
+0,         51,         51,        1,   149760, 0x16bf2871
+0,         52,         52,        1,   149760, 0x51253402
+0,         53,         53,        1,   149760, 0x13822dfd
+0,         54,         54,        1,   149760, 0x5e099d3d
+0,         55,         55,        1,   149760, 0xcc19fe87
+0,         56,         56,        1,   149760, 0x7f5f6ce2
+0,         57,         57,        1,   149760, 0x79797a94
+0,         58,         58,        1,   149760, 0x16f26086
+0,         59,         59,        1,   149760, 0x01aedea3
+0,         60,         60,        1,   149760, 0xcafd3221
+0,         61,         61,        1,   149760, 0xcbd61c1f
+0,         62,         62,        1,   149760, 0xf46839e5
+0,         63,         63,        1,   149760, 0x87fb61ee
+0,         64,         64,        1,   149760, 0x3362678b
+0,         65,         65,        1,   149760, 0x6e7fc851
+0,         66,         66,        1,   149760, 0x33f96449
+0,         67,         67,        1,   149760, 0xd9d05007
+0,         68,         68,        1,   149760, 0x477f2cf2
+0,         69,         69,        1,   149760, 0xe1f9ccd0
+0,         70,         70,        1,   149760, 0xb3ba8cfb
+0,         71,         71,        1,   149760, 0x64787995
+0,         72,         72,        1,   149760, 0xc10de4c4
+0,         73,         73,        1,   149760, 0x18dd343f
+0,         74,         74,        1,   149760, 0xa1c51358
+0,         75,         75,        1,   149760, 0x91fe6361
+0,         76,         76,        1,   149760, 0xeec85f94
+0,         77,         77,        1,   149760, 0x00a57402
+0,         78,         78,        1,   149760, 0x4e88cc16
+0,         79,         79,        1,   149760, 0xdbd51976
+0,         80,         80,        1,   149760, 0xfebf6b1a
+0,         81,         81,        1,   149760, 0x052546d2
+0,         82,         82,        1,   149760, 0x046cd73b
diff --git a/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4 b/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4
new file mode 100644
index 0000000..372d120
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4
@@ -0,0 +1,301 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xdb5e3b56
+0,          1,          1,        1,   149760, 0xd5320970
+0,          2,          2,        1,   149760, 0x9387ed18
+0,          3,          3,        1,   149760, 0x3ab6fde8
+0,          4,          4,        1,   149760, 0xf5d39a39
+0,          5,          5,        1,   149760, 0xf8c15b34
+0,          6,          6,        1,   149760, 0x12261fdc
+0,          7,          7,        1,   149760, 0x8ed03f57
+0,          8,          8,        1,   149760, 0x04d29f74
+0,          9,          9,        1,   149760, 0x86daf75e
+0,         10,         10,        1,   149760, 0x85d817a4
+0,         11,         11,        1,   149760, 0xf9c97006
+0,         12,         12,        1,   149760, 0x60baf6ad
+0,         13,         13,        1,   149760, 0x7272aa6b
+0,         14,         14,        1,   149760, 0x18e00ede
+0,         15,         15,        1,   149760, 0x60592cfe
+0,         16,         16,        1,   149760, 0x7d49650d
+0,         17,         17,        1,   149760, 0x865e7b22
+0,         18,         18,        1,   149760, 0xad6a33e4
+0,         19,         19,        1,   149760, 0x7c8ab573
+0,         20,         20,        1,   149760, 0x0c7d8afa
+0,         21,         21,        1,   149760, 0xb0e567a3
+0,         22,         22,        1,   149760, 0x3c2ccbf1
+0,         23,         23,        1,   149760, 0x0804aead
+0,         24,         24,        1,   149760, 0x0dcb6756
+0,         25,         25,        1,   149760, 0x99bc82dd
+0,         26,         26,        1,   149760, 0x4d2907f1
+0,         27,         27,        1,   149760, 0xc4c330ff
+0,         28,         28,        1,   149760, 0x6c73cef4
+0,         29,         29,        1,   149760, 0xbaa82ab1
+0,         30,         30,        1,   149760, 0xeea3d591
+0,         31,         31,        1,   149760, 0x8240d007
+0,         32,         32,        1,   149760, 0x698f11e4
+0,         33,         33,        1,   149760, 0x46700948
+0,         34,         34,        1,   149760, 0x819e62d9
+0,         35,         35,        1,   149760, 0x0cfe1471
+0,         36,         36,        1,   149760, 0xf30dc9da
+0,         37,         37,        1,   149760, 0x81ea3390
+0,         38,         38,        1,   149760, 0x85bc8dec
+0,         39,         39,        1,   149760, 0x01d3451a
+0,         40,         40,        1,   149760, 0x626dc94b
+0,         41,         41,        1,   149760, 0xf50f2a66
+0,         42,         42,        1,   149760, 0x6294bc3e
+0,         43,         43,        1,   149760, 0x41427bc1
+0,         44,         44,        1,   149760, 0xe200ecf3
+0,         45,         45,        1,   149760, 0xc44785c5
+0,         46,         46,        1,   149760, 0xadc8c3cf
+0,         47,         47,        1,   149760, 0x6c57fb6d
+0,         48,         48,        1,   149760, 0x139cddc1
+0,         49,         49,        1,   149760, 0xc5c9def6
+0,         50,         50,        1,   149760, 0xa8da3f7b
+0,         51,         51,        1,   149760, 0x21823d13
+0,         52,         52,        1,   149760, 0x00e265fd
+0,         53,         53,        1,   149760, 0x289f21d2
+0,         54,         54,        1,   149760, 0xa96d8d0b
+0,         55,         55,        1,   149760, 0x4e50b434
+0,         56,         56,        1,   149760, 0x4e469eae
+0,         57,         57,        1,   149760, 0x62a258af
+0,         58,         58,        1,   149760, 0xc61beb2b
+0,         59,         59,        1,   149760, 0x15d7853b
+0,         60,         60,        1,   149760, 0xd5b8941b
+0,         61,         61,        1,   149760, 0x6312a7c5
+0,         62,         62,        1,   149760, 0x2da74d59
+0,         63,         63,        1,   149760, 0x5fd72bc7
+0,         64,         64,        1,   149760, 0x4035f027
+0,         65,         65,        1,   149760, 0xbe9992e2
+0,         66,         66,        1,   149760, 0xb96093b8
+0,         67,         67,        1,   149760, 0x1024bd43
+0,         68,         68,        1,   149760, 0x1376a3fe
+0,         69,         69,        1,   149760, 0xdf93ec7f
+0,         70,         70,        1,   149760, 0x17d27bfa
+0,         71,         71,        1,   149760, 0x440cb7aa
+0,         72,         72,        1,   149760, 0x8b230df3
+0,         73,         73,        1,   149760, 0x2526130e
+0,         74,         74,        1,   149760, 0x77926a77
+0,         75,         75,        1,   149760, 0x8562bddc
+0,         76,         76,        1,   149760, 0xda86bb2e
+0,         77,         77,        1,   149760, 0x2b4f921b
+0,         78,         78,        1,   149760, 0xf13bca77
+0,         79,         79,        1,   149760, 0x53e76b99
+0,         80,         80,        1,   149760, 0x29a2f5bb
+0,         81,         81,        1,   149760, 0x83a8c4f8
+0,         82,         82,        1,   149760, 0xbe6d8f45
+0,         83,         83,        1,   149760, 0x03d3bf96
+0,         84,         84,        1,   149760, 0x3a0bd29e
+0,         85,         85,        1,   149760, 0xdb656a22
+0,         86,         86,        1,   149760, 0x557b020e
+0,         87,         87,        1,   149760, 0x573ee5f2
+0,         88,         88,        1,   149760, 0x5484faea
+0,         89,         89,        1,   149760, 0x06bb73ae
+0,         90,         90,        1,   149760, 0x3d4049fa
+0,         91,         91,        1,   149760, 0xe574eedb
+0,         92,         92,        1,   149760, 0x1c46205d
+0,         93,         93,        1,   149760, 0x0c5c322e
+0,         94,         94,        1,   149760, 0x2bbeed95
+0,         95,         95,        1,   149760, 0x225897dc
+0,         96,         96,        1,   149760, 0x0a39aa8b
+0,         97,         97,        1,   149760, 0x3242e156
+0,         98,         98,        1,   149760, 0x1790ee85
+0,         99,         99,        1,   149760, 0x55ef9dac
+0,        100,        100,        1,   149760, 0x98e1c49e
+0,        101,        101,        1,   149760, 0x479a84b5
+0,        102,        102,        1,   149760, 0x1711b4f9
+0,        103,        103,        1,   149760, 0xd7d25fce
+0,        104,        104,        1,   149760, 0x7bde1977
+0,        105,        105,        1,   149760, 0x25777a4d
+0,        106,        106,        1,   149760, 0x7b55ed5f
+0,        107,        107,        1,   149760, 0xb28e59e6
+0,        108,        108,        1,   149760, 0x8314281a
+0,        109,        109,        1,   149760, 0x3a5ceeb3
+0,        110,        110,        1,   149760, 0x33760ed8
+0,        111,        111,        1,   149760, 0x19332370
+0,        112,        112,        1,   149760, 0xf25d1f68
+0,        113,        113,        1,   149760, 0x4d665712
+0,        114,        114,        1,   149760, 0x3e310eb7
+0,        115,        115,        1,   149760, 0xafa3c1bb
+0,        116,        116,        1,   149760, 0xf0b7a7ec
+0,        117,        117,        1,   149760, 0xa88a747a
+0,        118,        118,        1,   149760, 0x7b7e6e85
+0,        119,        119,        1,   149760, 0xbc8f8ede
+0,        120,        120,        1,   149760, 0x449f7d2f
+0,        121,        121,        1,   149760, 0x9bc70c53
+0,        122,        122,        1,   149760, 0x8544dc98
+0,        123,        123,        1,   149760, 0xef687641
+0,        124,        124,        1,   149760, 0x0c962219
+0,        125,        125,        1,   149760, 0x4325ae76
+0,        126,        126,        1,   149760, 0xcec7a18c
+0,        127,        127,        1,   149760, 0x941ee8a2
+0,        128,        128,        1,   149760, 0x3eaf3f55
+0,        129,        129,        1,   149760, 0x5b571274
+0,        130,        130,        1,   149760, 0x0532488a
+0,        131,        131,        1,   149760, 0x893fbaf7
+0,        132,        132,        1,   149760, 0xd0155ddf
+0,        133,        133,        1,   149760, 0x83ec86ee
+0,        134,        134,        1,   149760, 0xedffba86
+0,        135,        135,        1,   149760, 0x838c19de
+0,        136,        136,        1,   149760, 0x8482639d
+0,        137,        137,        1,   149760, 0x9501004d
+0,        138,        138,        1,   149760, 0x1db0525f
+0,        139,        139,        1,   149760, 0x8b431467
+0,        140,        140,        1,   149760, 0x972e7d24
+0,        141,        141,        1,   149760, 0xd8151b94
+0,        142,        142,        1,   149760, 0x1ded6a85
+0,        143,        143,        1,   149760, 0x03497fe2
+0,        144,        144,        1,   149760, 0x07427bb7
+0,        145,        145,        1,   149760, 0x33c085ef
+0,        146,        146,        1,   149760, 0x0feda1d0
+0,        147,        147,        1,   149760, 0xf86930e7
+0,        148,        148,        1,   149760, 0x42c2ea09
+0,        149,        149,        1,   149760, 0xcfb76b86
+0,        150,        150,        1,   149760, 0x672e2fce
+0,        151,        151,        1,   149760, 0xb006ec79
+0,        152,        152,        1,   149760, 0xdbc8511c
+0,        153,        153,        1,   149760, 0x3278b299
+0,        154,        154,        1,   149760, 0xd19fe063
+0,        155,        155,        1,   149760, 0x13bb8951
+0,        156,        156,        1,   149760, 0xec5cfe36
+0,        157,        157,        1,   149760, 0x9381a0e7
+0,        158,        158,        1,   149760, 0x304cf3c0
+0,        159,        159,        1,   149760, 0xd380511c
+0,        160,        160,        1,   149760, 0xbd1abe11
+0,        161,        161,        1,   149760, 0x7b220293
+0,        162,        162,        1,   149760, 0xbbe85931
+0,        163,        163,        1,   149760, 0x316e422a
+0,        164,        164,        1,   149760, 0x5e5db530
+0,        165,        165,        1,   149760, 0xc48d6ddb
+0,        166,        166,        1,   149760, 0x9adf5d65
+0,        167,        167,        1,   149760, 0x2adb94de
+0,        168,        168,        1,   149760, 0xbc052746
+0,        169,        169,        1,   149760, 0xac4d3569
+0,        170,        170,        1,   149760, 0x3cd8fdee
+0,        171,        171,        1,   149760, 0x34bfd6ed
+0,        172,        172,        1,   149760, 0xf72fec4b
+0,        173,        173,        1,   149760, 0xf8c5b374
+0,        174,        174,        1,   149760, 0x28ff7382
+0,        175,        175,        1,   149760, 0xac3b49f4
+0,        176,        176,        1,   149760, 0x9d995a62
+0,        177,        177,        1,   149760, 0xe0b292f1
+0,        178,        178,        1,   149760, 0x4edbd05d
+0,        179,        179,        1,   149760, 0x4fd5038b
+0,        180,        180,        1,   149760, 0x899d2101
+0,        181,        181,        1,   149760, 0x0733f804
+0,        182,        182,        1,   149760, 0xe4297100
+0,        183,        183,        1,   149760, 0x5aff9292
+0,        184,        184,        1,   149760, 0x41eda25c
+0,        185,        185,        1,   149760, 0xb4d7aaf2
+0,        186,        186,        1,   149760, 0xbd99fade
+0,        187,        187,        1,   149760, 0xdea6d265
+0,        188,        188,        1,   149760, 0xa2d3bdcd
+0,        189,        189,        1,   149760, 0x38f8a729
+0,        190,        190,        1,   149760, 0x0a356f1b
+0,        191,        191,        1,   149760, 0x865411a5
+0,        192,        192,        1,   149760, 0xd6720a40
+0,        193,        193,        1,   149760, 0xf40589f9
+0,        194,        194,        1,   149760, 0x0646106d
+0,        195,        195,        1,   149760, 0x88e55688
+0,        196,        196,        1,   149760, 0xda2fce82
+0,        197,        197,        1,   149760, 0xc823200b
+0,        198,        198,        1,   149760, 0xc9513041
+0,        199,        199,        1,   149760, 0x798d0e88
+0,        200,        200,        1,   149760, 0xb6d4f15a
+0,        201,        201,        1,   149760, 0xab5b24a4
+0,        202,        202,        1,   149760, 0x9888aa8d
+0,        203,        203,        1,   149760, 0xbf13bbf4
+0,        204,        204,        1,   149760, 0x5450bb23
+0,        205,        205,        1,   149760, 0x12aec398
+0,        206,        206,        1,   149760, 0xa5e1579a
+0,        207,        207,        1,   149760, 0xbeeb07e1
+0,        208,        208,        1,   149760, 0x209a9f1b
+0,        209,        209,        1,   149760, 0x4d3d1c1a
+0,        210,        210,        1,   149760, 0xb4edd703
+0,        211,        211,        1,   149760, 0xc71adf66
+0,        212,        212,        1,   149760, 0x40006d36
+0,        213,        213,        1,   149760, 0x1c5485c9
+0,        214,        214,        1,   149760, 0xa3d8c9a1
+0,        215,        215,        1,   149760, 0x9bfac6de
+0,        216,        216,        1,   149760, 0xed3b0782
+0,        217,        217,        1,   149760, 0x8f075ce2
+0,        218,        218,        1,   149760, 0xb744fa07
+0,        219,        219,        1,   149760, 0xa9356722
+0,        220,        220,        1,   149760, 0xd792bd01
+0,        221,        221,        1,   149760, 0xa124618b
+0,        222,        222,        1,   149760, 0x7492bb54
+0,        223,        223,        1,   149760, 0x67dcefca
+0,        224,        224,        1,   149760, 0x8a7f716d
+0,        225,        225,        1,   149760, 0x7775bb01
+0,        226,        226,        1,   149760, 0xe4a845e5
+0,        227,        227,        1,   149760, 0x79a3962d
+0,        228,        228,        1,   149760, 0x4f395ad7
+0,        229,        229,        1,   149760, 0x3948ce05
+0,        230,        230,        1,   149760, 0x037e6c07
+0,        231,        231,        1,   149760, 0x91881ae9
+0,        232,        232,        1,   149760, 0x937e2545
+0,        233,        233,        1,   149760, 0xdc892763
+0,        234,        234,        1,   149760, 0x96ebd47f
+0,        235,        235,        1,   149760, 0xfecbf8c6
+0,        236,        236,        1,   149760, 0xe1443808
+0,        237,        237,        1,   149760, 0xe0cd36c0
+0,        238,        238,        1,   149760, 0xb485eb4d
+0,        239,        239,        1,   149760, 0x36edf31f
+0,        240,        240,        1,   149760, 0x988bb97f
+0,        241,        241,        1,   149760, 0xc266c616
+0,        242,        242,        1,   149760, 0x7ec4c3f4
+0,        243,        243,        1,   149760, 0xedf5e2ff
+0,        244,        244,        1,   149760, 0xbdd351e3
+0,        245,        245,        1,   149760, 0x900e194e
+0,        246,        246,        1,   149760, 0x5dc7daad
+0,        247,        247,        1,   149760, 0x1ce37e7e
+0,        248,        248,        1,   149760, 0x15982333
+0,        249,        249,        1,   149760, 0x976bb72e
+0,        250,        250,        1,   149760, 0x0b42e05e
+0,        251,        251,        1,   149760, 0xffbcc758
+0,        252,        252,        1,   149760, 0x6377782d
+0,        253,        253,        1,   149760, 0x8aa42a80
+0,        254,        254,        1,   149760, 0x8e0ab3fd
+0,        255,        255,        1,   149760, 0xdfdd49d4
+0,        256,        256,        1,   149760, 0x2659a6cb
+0,        257,        257,        1,   149760, 0x1e9a3d51
+0,        258,        258,        1,   149760, 0x7a66d80d
+0,        259,        259,        1,   149760, 0x5756a9e9
+0,        260,        260,        1,   149760, 0x0fa8d6dd
+0,        261,        261,        1,   149760, 0x885799a5
+0,        262,        262,        1,   149760, 0xb8d02df7
+0,        263,        263,        1,   149760, 0xd2e2800c
+0,        264,        264,        1,   149760, 0xa26ee27a
+0,        265,        265,        1,   149760, 0x7c86750f
+0,        266,        266,        1,   149760, 0xb4694ea1
+0,        267,        267,        1,   149760, 0x89d0b75a
+0,        268,        268,        1,   149760, 0x92b9af80
+0,        269,        269,        1,   149760, 0x107dd610
+0,        270,        270,        1,   149760, 0x8ad35f55
+0,        271,        271,        1,   149760, 0xccc32cb1
+0,        272,        272,        1,   149760, 0xd08ce4ff
+0,        273,        273,        1,   149760, 0x30bd8d0a
+0,        274,        274,        1,   149760, 0x01b74d14
+0,        275,        275,        1,   149760, 0x79aa7a3b
+0,        276,        276,        1,   149760, 0x5f7a40fc
+0,        277,        277,        1,   149760, 0x8837643e
+0,        278,        278,        1,   149760, 0xb6b66baa
+0,        279,        279,        1,   149760, 0xf4ae17cd
+0,        280,        280,        1,   149760, 0xe0d2546a
+0,        281,        281,        1,   149760, 0x0e118751
+0,        282,        282,        1,   149760, 0x0732e19c
+0,        283,        283,        1,   149760, 0x9cfe27b3
+0,        284,        284,        1,   149760, 0x1c77b242
+0,        285,        285,        1,   149760, 0x25be3938
+0,        286,        286,        1,   149760, 0x735ce859
+0,        287,        287,        1,   149760, 0x2bca0f6e
+0,        288,        288,        1,   149760, 0xcce3eb48
+0,        289,        289,        1,   149760, 0xf3556dd8
+0,        290,        290,        1,   149760, 0xcb2cecb4
+0,        291,        291,        1,   149760, 0x9c489742
+0,        292,        292,        1,   149760, 0xbe25370d
+0,        293,        293,        1,   149760, 0x798ff17f
+0,        294,        294,        1,   149760, 0x2f1a46c4
+0,        295,        295,        1,   149760, 0x7d119bd6
+0,        296,        296,        1,   149760, 0x42ceab74
+0,        297,        297,        1,   149760, 0x6fcbe2ef
+0,        298,        298,        1,   149760, 0x290fe6da
+0,        299,        299,        1,   149760, 0x6b280a24
diff --git a/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4 b/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4
new file mode 100644
index 0000000..a34dcc0
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4
@@ -0,0 +1,301 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x82ff0cca
+0,          1,          1,        1,   149760, 0xcd05ba17
+0,          2,          2,        1,   149760, 0x33a5b924
+0,          3,          3,        1,   149760, 0xc0a8d82f
+0,          4,          4,        1,   149760, 0xa18c8ce6
+0,          5,          5,        1,   149760, 0x4d3c4902
+0,          6,          6,        1,   149760, 0xf118cb2a
+0,          7,          7,        1,   149760, 0xb37643c0
+0,          8,          8,        1,   149760, 0x0d6f8a70
+0,          9,          9,        1,   149760, 0xeaebd0f0
+0,         10,         10,        1,   149760, 0x81cce277
+0,         11,         11,        1,   149760, 0x85f216cc
+0,         12,         12,        1,   149760, 0x799cc7c7
+0,         13,         13,        1,   149760, 0x575f76da
+0,         14,         14,        1,   149760, 0x79e10395
+0,         15,         15,        1,   149760, 0x80f62423
+0,         16,         16,        1,   149760, 0x13657087
+0,         17,         17,        1,   149760, 0xcd147ae1
+0,         18,         18,        1,   149760, 0xcee71159
+0,         19,         19,        1,   149760, 0x6fa7b8d5
+0,         20,         20,        1,   149760, 0xd90bd038
+0,         21,         21,        1,   149760, 0x13eead73
+0,         22,         22,        1,   149760, 0xe2eddfc8
+0,         23,         23,        1,   149760, 0x1f07a4f6
+0,         24,         24,        1,   149760, 0x90b25f59
+0,         25,         25,        1,   149760, 0xd0dd86ba
+0,         26,         26,        1,   149760, 0x3008066c
+0,         27,         27,        1,   149760, 0x74ec54dd
+0,         28,         28,        1,   149760, 0xa423046c
+0,         29,         29,        1,   149760, 0x8a410bca
+0,         30,         30,        1,   149760, 0x55337573
+0,         31,         31,        1,   149760, 0x55d3623c
+0,         32,         32,        1,   149760, 0x699d234b
+0,         33,         33,        1,   149760, 0xbcd029b6
+0,         34,         34,        1,   149760, 0xa56e6600
+0,         35,         35,        1,   149760, 0x1dfc4a28
+0,         36,         36,        1,   149760, 0x9a72d671
+0,         37,         37,        1,   149760, 0xc01812ae
+0,         38,         38,        1,   149760, 0x8ef428c2
+0,         39,         39,        1,   149760, 0x6e79de92
+0,         40,         40,        1,   149760, 0xf315ba7c
+0,         41,         41,        1,   149760, 0xa678caff
+0,         42,         42,        1,   149760, 0xbd2049c0
+0,         43,         43,        1,   149760, 0x649323ea
+0,         44,         44,        1,   149760, 0x686eb3a4
+0,         45,         45,        1,   149760, 0x89725136
+0,         46,         46,        1,   149760, 0xc4db7e6f
+0,         47,         47,        1,   149760, 0xf6f0d823
+0,         48,         48,        1,   149760, 0x44b3a07a
+0,         49,         49,        1,   149760, 0xf23c221d
+0,         50,         50,        1,   149760, 0x858f11ef
+0,         51,         51,        1,   149760, 0xcd5311c4
+0,         52,         52,        1,   149760, 0x72c9297d
+0,         53,         53,        1,   149760, 0xf6acd772
+0,         54,         54,        1,   149760, 0x8c0f91ed
+0,         55,         55,        1,   149760, 0x7ef6f2be
+0,         56,         56,        1,   149760, 0x1237a677
+0,         57,         57,        1,   149760, 0x66e461f9
+0,         58,         58,        1,   149760, 0x3e06e1b3
+0,         59,         59,        1,   149760, 0xa6f6065c
+0,         60,         60,        1,   149760, 0x16e38cc0
+0,         61,         61,        1,   149760, 0x05762de1
+0,         62,         62,        1,   149760, 0xbda617c5
+0,         63,         63,        1,   149760, 0x75b904a9
+0,         64,         64,        1,   149760, 0x2f8bf179
+0,         65,         65,        1,   149760, 0x9be6a533
+0,         66,         66,        1,   149760, 0xf4eb99e8
+0,         67,         67,        1,   149760, 0xf3a68b9a
+0,         68,         68,        1,   149760, 0x34b86f19
+0,         69,         69,        1,   149760, 0x6a71cc04
+0,         70,         70,        1,   149760, 0xe206a202
+0,         71,         71,        1,   149760, 0xdfa8dea6
+0,         72,         72,        1,   149760, 0x8ef7fb73
+0,         73,         73,        1,   149760, 0x67a8de32
+0,         74,         74,        1,   149760, 0xc8c16870
+0,         75,         75,        1,   149760, 0xf5e5d04d
+0,         76,         76,        1,   149760, 0x79d0cc8d
+0,         77,         77,        1,   149760, 0xcd80a22b
+0,         78,         78,        1,   149760, 0x12dce452
+0,         79,         79,        1,   149760, 0x0586aa3d
+0,         80,         80,        1,   149760, 0x5a4d0c1e
+0,         81,         81,        1,   149760, 0x25dbe94e
+0,         82,         82,        1,   149760, 0x3236bbe8
+0,         83,         83,        1,   149760, 0x3b4bc068
+0,         84,         84,        1,   149760, 0x3f32c299
+0,         85,         85,        1,   149760, 0x5b0738e5
+0,         86,         86,        1,   149760, 0x0c1d0c80
+0,         87,         87,        1,   149760, 0x76ace6f5
+0,         88,         88,        1,   149760, 0xc738ff39
+0,         89,         89,        1,   149760, 0x0f078335
+0,         90,         90,        1,   149760, 0x0e941631
+0,         91,         91,        1,   149760, 0x284ee7d6
+0,         92,         92,        1,   149760, 0xce9b49b8
+0,         93,         93,        1,   149760, 0x7c132570
+0,         94,         94,        1,   149760, 0xa983dc5e
+0,         95,         95,        1,   149760, 0x994e4d69
+0,         96,         96,        1,   149760, 0xb8f599ed
+0,         97,         97,        1,   149760, 0xee81b454
+0,         98,         98,        1,   149760, 0xf27bdeee
+0,         99,         99,        1,   149760, 0xc7628895
+0,        100,        100,        1,   149760, 0x003521d1
+0,        101,        101,        1,   149760, 0x7ed9b167
+0,        102,        102,        1,   149760, 0x47598b95
+0,        103,        103,        1,   149760, 0x879b347e
+0,        104,        104,        1,   149760, 0x55f8f8c1
+0,        105,        105,        1,   149760, 0xdddc5dda
+0,        106,        106,        1,   149760, 0xc531c9a1
+0,        107,        107,        1,   149760, 0x28ef0e7e
+0,        108,        108,        1,   149760, 0x4c090cbd
+0,        109,        109,        1,   149760, 0x5818f270
+0,        110,        110,        1,   149760, 0x89ea1f0e
+0,        111,        111,        1,   149760, 0x263925ef
+0,        112,        112,        1,   149760, 0x4e7d45b8
+0,        113,        113,        1,   149760, 0xa98dbf77
+0,        114,        114,        1,   149760, 0xaa0239b3
+0,        115,        115,        1,   149760, 0x4eaa2226
+0,        116,        116,        1,   149760, 0x9927c7f9
+0,        117,        117,        1,   149760, 0x17f09e34
+0,        118,        118,        1,   149760, 0x45cc73e9
+0,        119,        119,        1,   149760, 0x21836e14
+0,        120,        120,        1,   149760, 0x14c38cf6
+0,        121,        121,        1,   149760, 0x18ee35ee
+0,        122,        122,        1,   149760, 0x4f55f781
+0,        123,        123,        1,   149760, 0x85556339
+0,        124,        124,        1,   149760, 0xc41e3261
+0,        125,        125,        1,   149760, 0xed34ba27
+0,        126,        126,        1,   149760, 0x91e7841c
+0,        127,        127,        1,   149760, 0x1605bd75
+0,        128,        128,        1,   149760, 0xb5af2fbc
+0,        129,        129,        1,   149760, 0x9024b2d8
+0,        130,        130,        1,   149760, 0xda8d3c03
+0,        131,        131,        1,   149760, 0xc23a9686
+0,        132,        132,        1,   149760, 0xf9c8686b
+0,        133,        133,        1,   149760, 0xec09b569
+0,        134,        134,        1,   149760, 0x398df9bb
+0,        135,        135,        1,   149760, 0x716c2934
+0,        136,        136,        1,   149760, 0x0a6ea078
+0,        137,        137,        1,   149760, 0x777739fe
+0,        138,        138,        1,   149760, 0x80417304
+0,        139,        139,        1,   149760, 0xe0a5c378
+0,        140,        140,        1,   149760, 0x9565a659
+0,        141,        141,        1,   149760, 0xdf6f1938
+0,        142,        142,        1,   149760, 0xe60d5639
+0,        143,        143,        1,   149760, 0xa89fa739
+0,        144,        144,        1,   149760, 0xd1529b40
+0,        145,        145,        1,   149760, 0x48a7d440
+0,        146,        146,        1,   149760, 0x5946afbb
+0,        147,        147,        1,   149760, 0x2cad2855
+0,        148,        148,        1,   149760, 0x7ac1d993
+0,        149,        149,        1,   149760, 0x0841a016
+0,        150,        150,        1,   149760, 0x35ea4bd2
+0,        151,        151,        1,   149760, 0x5371effa
+0,        152,        152,        1,   149760, 0xd6445a37
+0,        153,        153,        1,   149760, 0x782ea184
+0,        154,        154,        1,   149760, 0x919c2013
+0,        155,        155,        1,   149760, 0x0ea79614
+0,        156,        156,        1,   149760, 0x1ac0e835
+0,        157,        157,        1,   149760, 0x32a36ada
+0,        158,        158,        1,   149760, 0x6b0ad17c
+0,        159,        159,        1,   149760, 0xcd442d19
+0,        160,        160,        1,   149760, 0x0dd1df50
+0,        161,        161,        1,   149760, 0xe26b248f
+0,        162,        162,        1,   149760, 0x490348bb
+0,        163,        163,        1,   149760, 0x638b547e
+0,        164,        164,        1,   149760, 0xb2cbe2ca
+0,        165,        165,        1,   149760, 0xc6cfaa86
+0,        166,        166,        1,   149760, 0xe2317842
+0,        167,        167,        1,   149760, 0xe6e7cd9b
+0,        168,        168,        1,   149760, 0x55bf48cb
+0,        169,        169,        1,   149760, 0xefee6ea0
+0,        170,        170,        1,   149760, 0x2bb127fa
+0,        171,        171,        1,   149760, 0xebbf0725
+0,        172,        172,        1,   149760, 0xb40718a1
+0,        173,        173,        1,   149760, 0x33c8e7da
+0,        174,        174,        1,   149760, 0xfeea8d03
+0,        175,        175,        1,   149760, 0x52f47fa9
+0,        176,        176,        1,   149760, 0xb08fa2f6
+0,        177,        177,        1,   149760, 0xc9adcd96
+0,        178,        178,        1,   149760, 0xb8981cc2
+0,        179,        179,        1,   149760, 0x547b1eaa
+0,        180,        180,        1,   149760, 0x10733813
+0,        181,        181,        1,   149760, 0x14edfa3d
+0,        182,        182,        1,   149760, 0x28ae8eb3
+0,        183,        183,        1,   149760, 0x9b94a69c
+0,        184,        184,        1,   149760, 0x42f67a2a
+0,        185,        185,        1,   149760, 0x1ead65e6
+0,        186,        186,        1,   149760, 0x30b99840
+0,        187,        187,        1,   149760, 0xafdebbda
+0,        188,        188,        1,   149760, 0xc31cda7f
+0,        189,        189,        1,   149760, 0xe7afdfa8
+0,        190,        190,        1,   149760, 0xc8358146
+0,        191,        191,        1,   149760, 0xb8ea3a3b
+0,        192,        192,        1,   149760, 0xebbb2c0e
+0,        193,        193,        1,   149760, 0xe911c057
+0,        194,        194,        1,   149760, 0x843f3082
+0,        195,        195,        1,   149760, 0xd18f6dcb
+0,        196,        196,        1,   149760, 0xd0f67de3
+0,        197,        197,        1,   149760, 0xa7077645
+0,        198,        198,        1,   149760, 0xb7432bef
+0,        199,        199,        1,   149760, 0x9e3284ee
+0,        200,        200,        1,   149760, 0x931ec601
+0,        201,        201,        1,   149760, 0xd0f92a35
+0,        202,        202,        1,   149760, 0x2141c549
+0,        203,        203,        1,   149760, 0x46abf101
+0,        204,        204,        1,   149760, 0x92069ea7
+0,        205,        205,        1,   149760, 0xbf0dd536
+0,        206,        206,        1,   149760, 0xc0c34245
+0,        207,        207,        1,   149760, 0xd9f60e8b
+0,        208,        208,        1,   149760, 0xe20cb181
+0,        209,        209,        1,   149760, 0xdf58fbd2
+0,        210,        210,        1,   149760, 0xe047e805
+0,        211,        211,        1,   149760, 0xe6dd0520
+0,        212,        212,        1,   149760, 0xa7a1a7dd
+0,        213,        213,        1,   149760, 0x6bd6d799
+0,        214,        214,        1,   149760, 0x9fcbda54
+0,        215,        215,        1,   149760, 0xe9b8bf5a
+0,        216,        216,        1,   149760, 0x818d2b8d
+0,        217,        217,        1,   149760, 0x021c5b55
+0,        218,        218,        1,   149760, 0x0da93d94
+0,        219,        219,        1,   149760, 0x7d66b00d
+0,        220,        220,        1,   149760, 0xf84ab99e
+0,        221,        221,        1,   149760, 0xbc866ed2
+0,        222,        222,        1,   149760, 0x8075f6fa
+0,        223,        223,        1,   149760, 0x64540cad
+0,        224,        224,        1,   149760, 0xf3e28d9a
+0,        225,        225,        1,   149760, 0xb88fef8b
+0,        226,        226,        1,   149760, 0x1c782c83
+0,        227,        227,        1,   149760, 0xb89e4047
+0,        228,        228,        1,   149760, 0x593815a7
+0,        229,        229,        1,   149760, 0xa41a68d1
+0,        230,        230,        1,   149760, 0x7fdc56e5
+0,        231,        231,        1,   149760, 0xea8a0533
+0,        232,        232,        1,   149760, 0xc74709cc
+0,        233,        233,        1,   149760, 0xecca373c
+0,        234,        234,        1,   149760, 0x1dae228f
+0,        235,        235,        1,   149760, 0xbb900da8
+0,        236,        236,        1,   149760, 0xf71e4935
+0,        237,        237,        1,   149760, 0x8587d747
+0,        238,        238,        1,   149760, 0x5382afdd
+0,        239,        239,        1,   149760, 0x4075dea6
+0,        240,        240,        1,   149760, 0x1ccde8f2
+0,        241,        241,        1,   149760, 0x8065ed82
+0,        242,        242,        1,   149760, 0x0726bb8a
+0,        243,        243,        1,   149760, 0xedf2172c
+0,        244,        244,        1,   149760, 0x552cce61
+0,        245,        245,        1,   149760, 0x32851927
+0,        246,        246,        1,   149760, 0x15e8ae45
+0,        247,        247,        1,   149760, 0x9265625c
+0,        248,        248,        1,   149760, 0x11612465
+0,        249,        249,        1,   149760, 0x9f5586fa
+0,        250,        250,        1,   149760, 0x77f295a1
+0,        251,        251,        1,   149760, 0xb0757b88
+0,        252,        252,        1,   149760, 0xa0bd3d9c
+0,        253,        253,        1,   149760, 0x12471db6
+0,        254,        254,        1,   149760, 0x5c329d6b
+0,        255,        255,        1,   149760, 0x62f32654
+0,        256,        256,        1,   149760, 0xeafeb1f0
+0,        257,        257,        1,   149760, 0x707f6647
+0,        258,        258,        1,   149760, 0xe8acda33
+0,        259,        259,        1,   149760, 0x1e9dcb1b
+0,        260,        260,        1,   149760, 0x984a4a40
+0,        261,        261,        1,   149760, 0x066b9585
+0,        262,        262,        1,   149760, 0x5e2d2091
+0,        263,        263,        1,   149760, 0x6a6a5172
+0,        264,        264,        1,   149760, 0xc4c4fe94
+0,        265,        265,        1,   149760, 0x6ed2c46b
+0,        266,        266,        1,   149760, 0x810f27f8
+0,        267,        267,        1,   149760, 0xc27ca970
+0,        268,        268,        1,   149760, 0xfd3dae79
+0,        269,        269,        1,   149760, 0x9744ce6d
+0,        270,        270,        1,   149760, 0x45772f2a
+0,        271,        271,        1,   149760, 0x482ed805
+0,        272,        272,        1,   149760, 0x9606c429
+0,        273,        273,        1,   149760, 0x79a9ca8a
+0,        274,        274,        1,   149760, 0xf625806e
+0,        275,        275,        1,   149760, 0x0c9eed01
+0,        276,        276,        1,   149760, 0xb0007687
+0,        277,        277,        1,   149760, 0x620a7b35
+0,        278,        278,        1,   149760, 0x5d6fa9dc
+0,        279,        279,        1,   149760, 0x92c86275
+0,        280,        280,        1,   149760, 0xca1886f0
+0,        281,        281,        1,   149760, 0x6363a557
+0,        282,        282,        1,   149760, 0x32ab19ca
+0,        283,        283,        1,   149760, 0xa6113c10
+0,        284,        284,        1,   149760, 0x257fd46a
+0,        285,        285,        1,   149760, 0xb8af4e28
+0,        286,        286,        1,   149760, 0x9716d086
+0,        287,        287,        1,   149760, 0x0cc14c4d
+0,        288,        288,        1,   149760, 0xd194f150
+0,        289,        289,        1,   149760, 0xb7cd7cf8
+0,        290,        290,        1,   149760, 0xae1bb1a3
+0,        291,        291,        1,   149760, 0xb4cc355f
+0,        292,        292,        1,   149760, 0x617c1ecb
+0,        293,        293,        1,   149760, 0xf2d1f288
+0,        294,        294,        1,   149760, 0x109bcb52
+0,        295,        295,        1,   149760, 0xe61a97dd
+0,        296,        296,        1,   149760, 0xc629ac10
+0,        297,        297,        1,   149760, 0xb91acded
+0,        298,        298,        1,   149760, 0x54ccb321
+0,        299,        299,        1,   149760, 0x1ad3c115
diff --git a/tests/ref/fate/hevc-conformance-RPS_A_docomo_4 b/tests/ref/fate/hevc-conformance-RPS_A_docomo_4
new file mode 100644
index 0000000..e29a74b
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_A_docomo_4
@@ -0,0 +1,45 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0x0bdf13f8
+0,          2,          2,        1,   149760, 0x45e702c7
+0,          3,          3,        1,   149760, 0x7a3a0c9a
+0,          4,          4,        1,   149760, 0xab0ed81d
+0,          5,          5,        1,   149760, 0xe2d4722a
+0,          6,          6,        1,   149760, 0x1df1f103
+0,          7,          7,        1,   149760, 0xdde42fb8
+0,          8,          8,        1,   149760, 0xfe2eb624
+0,          9,          9,        1,   149760, 0x121ff262
+0,         10,         10,        1,   149760, 0x64e5e7ba
+0,         11,         11,        1,   149760, 0x61b40e67
+0,         12,         12,        1,   149760, 0x8ceeb33f
+0,         13,         13,        1,   149760, 0xcbff6fc5
+0,         14,         14,        1,   149760, 0x07d6f767
+0,         15,         15,        1,   149760, 0x5cff14a5
+0,         16,         16,        1,   149760, 0x5c336ca3
+0,         17,         17,        1,   149760, 0x424990cd
+0,         18,         18,        1,   149760, 0x2c423459
+0,         19,         19,        1,   149760, 0xaff700ac
+0,         20,         20,        1,   149760, 0xaab9e6f4
+0,         21,         21,        1,   149760, 0x7979bfd4
+0,         22,         22,        1,   149760, 0x5096ee11
+0,         23,         23,        1,   149760, 0x4f02d1d0
+0,         24,         24,        1,   149760, 0x0c6468d2
+0,         25,         25,        1,   149760, 0x707e9307
+0,         26,         26,        1,   149760, 0xf4a71dc8
+0,         27,         27,        1,   149760, 0xbefc67f0
+0,         28,         28,        1,   149760, 0x05b8f3a9
+0,         29,         29,        1,   149760, 0xcd080a46
+0,         30,         30,        1,   149760, 0x1b5ab043
+0,         31,         31,        1,   149760, 0xd4b896e2
+0,         32,         32,        1,   149760, 0xbd342d08
+0,         33,         33,        1,   149760, 0x0b993f3c
+0,         34,         34,        1,   149760, 0xd89190e2
+0,         35,         35,        1,   149760, 0x507f2663
+0,         36,         36,        1,   149760, 0x6994c08f
+0,         37,         37,        1,   149760, 0xcf0209b2
+0,         38,         38,        1,   149760, 0x9695327c
+0,         39,         39,        1,   149760, 0x7116fdb3
+0,         40,         40,        1,   149760, 0x1294b154
+0,         41,         41,        1,   149760, 0x7ed1f716
+0,         42,         42,        1,   149760, 0xdc4880da
+0,         43,         43,        1,   149760, 0xa5955d35
diff --git a/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5 b/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5
new file mode 100644
index 0000000..3b24e75
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5
@@ -0,0 +1,301 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xdb5e3b56
+0,          1,          1,        1,   149760, 0xe328e677
+0,          2,          2,        1,   149760, 0x8f18f4c0
+0,          3,          3,        1,   149760, 0xf48de64c
+0,          4,          4,        1,   149760, 0x2937ad23
+0,          5,          5,        1,   149760, 0x93f166d2
+0,          6,          6,        1,   149760, 0x80e4e9c2
+0,          7,          7,        1,   149760, 0xb2a35da7
+0,          8,          8,        1,   149760, 0xf4fbb5c2
+0,          9,          9,        1,   149760, 0x2193bd91
+0,         10,         10,        1,   149760, 0xd4eec3b4
+0,         11,         11,        1,   149760, 0xb2e20b91
+0,         12,         12,        1,   149760, 0xaf8d17dc
+0,         13,         13,        1,   149760, 0x2189ac78
+0,         14,         14,        1,   149760, 0x52b8130f
+0,         15,         15,        1,   149760, 0xdfbc2f0a
+0,         16,         16,        1,   149760, 0x4c0269cf
+0,         17,         17,        1,   149760, 0xf99bb7d2
+0,         18,         18,        1,   149760, 0xada1495f
+0,         19,         19,        1,   149760, 0x57c42893
+0,         20,         20,        1,   149760, 0x022d29ca
+0,         21,         21,        1,   149760, 0x9883a271
+0,         22,         22,        1,   149760, 0xc8c132d7
+0,         23,         23,        1,   149760, 0xa97f8b43
+0,         24,         24,        1,   149760, 0x1bc187fa
+0,         25,         25,        1,   149760, 0x7b93951b
+0,         26,         26,        1,   149760, 0x88fd367c
+0,         27,         27,        1,   149760, 0x29471b92
+0,         28,         28,        1,   149760, 0x3ba820f1
+0,         29,         29,        1,   149760, 0x0a223169
+0,         30,         30,        1,   149760, 0x70fee1d5
+0,         31,         31,        1,   149760, 0x5f5cf053
+0,         32,         32,        1,   149760, 0x698f11e4
+0,         33,         33,        1,   149760, 0x65314fd4
+0,         34,         34,        1,   149760, 0x7a689450
+0,         35,         35,        1,   149760, 0x28774ca0
+0,         36,         36,        1,   149760, 0x0751f804
+0,         37,         37,        1,   149760, 0x875a6fb9
+0,         38,         38,        1,   149760, 0xde1f5309
+0,         39,         39,        1,   149760, 0x82701dd6
+0,         40,         40,        1,   149760, 0x13a2f45e
+0,         41,         41,        1,   149760, 0xfc3b140c
+0,         42,         42,        1,   149760, 0x4518ab47
+0,         43,         43,        1,   149760, 0xe5459482
+0,         44,         44,        1,   149760, 0x4cfafc6e
+0,         45,         45,        1,   149760, 0xc7cd5e43
+0,         46,         46,        1,   149760, 0x1ee79746
+0,         47,         47,        1,   149760, 0xccc73c83
+0,         48,         48,        1,   149760, 0xd9ecafc7
+0,         49,         49,        1,   149760, 0x65221c9d
+0,         50,         50,        1,   149760, 0x219b0b4b
+0,         51,         51,        1,   149760, 0x9d1e2010
+0,         52,         52,        1,   149760, 0x11685e16
+0,         53,         53,        1,   149760, 0x37eb1297
+0,         54,         54,        1,   149760, 0x99088778
+0,         55,         55,        1,   149760, 0xb41cbf25
+0,         56,         56,        1,   149760, 0x56f78bda
+0,         57,         57,        1,   149760, 0x6c284868
+0,         58,         58,        1,   149760, 0x37f245b9
+0,         59,         59,        1,   149760, 0x79682de2
+0,         60,         60,        1,   149760, 0x5a04f379
+0,         61,         61,        1,   149760, 0xfecc668b
+0,         62,         62,        1,   149760, 0x29328d8c
+0,         63,         63,        1,   149760, 0x8aff3ad7
+0,         64,         64,        1,   149760, 0x4035f027
+0,         65,         65,        1,   149760, 0xe7cead1d
+0,         66,         66,        1,   149760, 0x18578492
+0,         67,         67,        1,   149760, 0xd3ab3f9d
+0,         68,         68,        1,   149760, 0x6f866e38
+0,         69,         69,        1,   149760, 0x6a47800c
+0,         70,         70,        1,   149760, 0x01c6305e
+0,         71,         71,        1,   149760, 0x489ab5a8
+0,         72,         72,        1,   149760, 0xb2570787
+0,         73,         73,        1,   149760, 0xb0d5d478
+0,         74,         74,        1,   149760, 0x88484ccc
+0,         75,         75,        1,   149760, 0xb4c6be2c
+0,         76,         76,        1,   149760, 0x461d874c
+0,         77,         77,        1,   149760, 0x3be464b0
+0,         78,         78,        1,   149760, 0x06aa9443
+0,         79,         79,        1,   149760, 0xe0e625a3
+0,         80,         80,        1,   149760, 0x17e2daeb
+0,         81,         81,        1,   149760, 0x58a1a350
+0,         82,         82,        1,   149760, 0xcd4983ce
+0,         83,         83,        1,   149760, 0x90459a42
+0,         84,         84,        1,   149760, 0x899dedaa
+0,         85,         85,        1,   149760, 0x814e3529
+0,         86,         86,        1,   149760, 0x5795a2e5
+0,         87,         87,        1,   149760, 0xcedb245c
+0,         88,         88,        1,   149760, 0x37f9dd30
+0,         89,         89,        1,   149760, 0x320d899e
+0,         90,         90,        1,   149760, 0x6a33ffca
+0,         91,         91,        1,   149760, 0x6620b9eb
+0,         92,         92,        1,   149760, 0xfc8b1e1b
+0,         93,         93,        1,   149760, 0x835a0dd9
+0,         94,         94,        1,   149760, 0xcee4a9b0
+0,         95,         95,        1,   149760, 0x2c2972f0
+0,         96,         96,        1,   149760, 0x0a39aa8b
+0,         97,         97,        1,   149760, 0xa8a9c0bf
+0,         98,         98,        1,   149760, 0xd563c087
+0,         99,         99,        1,   149760, 0xb0f88320
+0,        100,        100,        1,   149760, 0x0ffffd6b
+0,        101,        101,        1,   149760, 0x95269e8c
+0,        102,        102,        1,   149760, 0xd0d4acd9
+0,        103,        103,        1,   149760, 0x7cf06805
+0,        104,        104,        1,   149760, 0xa5192bbe
+0,        105,        105,        1,   149760, 0x2fed928b
+0,        106,        106,        1,   149760, 0x549edd04
+0,        107,        107,        1,   149760, 0xa42b55d7
+0,        108,        108,        1,   149760, 0xeab32579
+0,        109,        109,        1,   149760, 0x95a727c3
+0,        110,        110,        1,   149760, 0x76714576
+0,        111,        111,        1,   149760, 0x5efc352a
+0,        112,        112,        1,   149760, 0x154a2c06
+0,        113,        113,        1,   149760, 0x516faf62
+0,        114,        114,        1,   149760, 0x622b6d64
+0,        115,        115,        1,   149760, 0x2ada08a9
+0,        116,        116,        1,   149760, 0xf24efa06
+0,        117,        117,        1,   149760, 0x5979b33e
+0,        118,        118,        1,   149760, 0x2130a282
+0,        119,        119,        1,   149760, 0x1ee8b3d1
+0,        120,        120,        1,   149760, 0x840c6913
+0,        121,        121,        1,   149760, 0xa37049b8
+0,        122,        122,        1,   149760, 0x8d95efb0
+0,        123,        123,        1,   149760, 0x22d3afb2
+0,        124,        124,        1,   149760, 0x113d6c6f
+0,        125,        125,        1,   149760, 0xb407014d
+0,        126,        126,        1,   149760, 0x33a8e5c9
+0,        127,        127,        1,   149760, 0x2689ced2
+0,        128,        128,        1,   149760, 0x3eaf3f55
+0,        129,        129,        1,   149760, 0x93ad7fa5
+0,        130,        130,        1,   149760, 0x30c15154
+0,        131,        131,        1,   149760, 0xdce68c7a
+0,        132,        132,        1,   149760, 0xea092d4c
+0,        133,        133,        1,   149760, 0xed679468
+0,        134,        134,        1,   149760, 0x9128c0d5
+0,        135,        135,        1,   149760, 0xd4f121ba
+0,        136,        136,        1,   149760, 0xe5e228f0
+0,        137,        137,        1,   149760, 0x8246dae3
+0,        138,        138,        1,   149760, 0x8a3b430c
+0,        139,        139,        1,   149760, 0x9a8edc3d
+0,        140,        140,        1,   149760, 0x68b0af97
+0,        141,        141,        1,   149760, 0x90d54b52
+0,        142,        142,        1,   149760, 0xd6395796
+0,        143,        143,        1,   149760, 0x70986b40
+0,        144,        144,        1,   149760, 0xc0b4a9c8
+0,        145,        145,        1,   149760, 0x760b973b
+0,        146,        146,        1,   149760, 0xe8fe9846
+0,        147,        147,        1,   149760, 0x61062c97
+0,        148,        148,        1,   149760, 0x9148e99b
+0,        149,        149,        1,   149760, 0x962c6a1e
+0,        150,        150,        1,   149760, 0x57bb088f
+0,        151,        151,        1,   149760, 0x2b0fa8c5
+0,        152,        152,        1,   149760, 0x00f932fc
+0,        153,        153,        1,   149760, 0x4cc58697
+0,        154,        154,        1,   149760, 0xd2bf178f
+0,        155,        155,        1,   149760, 0xc510c1cd
+0,        156,        156,        1,   149760, 0xc48e0192
+0,        157,        157,        1,   149760, 0xa03e7fe5
+0,        158,        158,        1,   149760, 0xb68ce060
+0,        159,        159,        1,   149760, 0x653951c8
+0,        160,        160,        1,   149760, 0xbd1abe11
+0,        161,        161,        1,   149760, 0xad7a2366
+0,        162,        162,        1,   149760, 0xb018279e
+0,        163,        163,        1,   149760, 0xd5994bff
+0,        164,        164,        1,   149760, 0x3eb7e082
+0,        165,        165,        1,   149760, 0x87257b3a
+0,        166,        166,        1,   149760, 0x12fc4c4d
+0,        167,        167,        1,   149760, 0x9fbfa94d
+0,        168,        168,        1,   149760, 0x61714cae
+0,        169,        169,        1,   149760, 0xae291b59
+0,        170,        170,        1,   149760, 0x8f161442
+0,        171,        171,        1,   149760, 0x603cf3a5
+0,        172,        172,        1,   149760, 0xf9f214a0
+0,        173,        173,        1,   149760, 0xbbf5dcb9
+0,        174,        174,        1,   149760, 0x8af1a1ab
+0,        175,        175,        1,   149760, 0x16f581e5
+0,        176,        176,        1,   149760, 0xdadd8eed
+0,        177,        177,        1,   149760, 0x2f1acd8e
+0,        178,        178,        1,   149760, 0xa28bd660
+0,        179,        179,        1,   149760, 0x7902dd67
+0,        180,        180,        1,   149760, 0x9b771dc2
+0,        181,        181,        1,   149760, 0x0fc82bda
+0,        182,        182,        1,   149760, 0xd6128167
+0,        183,        183,        1,   149760, 0xe57b7a2f
+0,        184,        184,        1,   149760, 0x1e158d0e
+0,        185,        185,        1,   149760, 0x682c7c60
+0,        186,        186,        1,   149760, 0x32096bbe
+0,        187,        187,        1,   149760, 0x297652f2
+0,        188,        188,        1,   149760, 0x056c7432
+0,        189,        189,        1,   149760, 0x0469b39a
+0,        190,        190,        1,   149760, 0x00044bc9
+0,        191,        191,        1,   149760, 0x766c0bad
+0,        192,        192,        1,   149760, 0xd6720a40
+0,        193,        193,        1,   149760, 0x814895eb
+0,        194,        194,        1,   149760, 0x1a84fcbc
+0,        195,        195,        1,   149760, 0x8b9442aa
+0,        196,        196,        1,   149760, 0x290187d1
+0,        197,        197,        1,   149760, 0x8f87294f
+0,        198,        198,        1,   149760, 0x8c49a125
+0,        199,        199,        1,   149760, 0xe169806a
+0,        200,        200,        1,   149760, 0x18c0e2f1
+0,        201,        201,        1,   149760, 0xb92b0e67
+0,        202,        202,        1,   149760, 0x98d2acef
+0,        203,        203,        1,   149760, 0x179eeaec
+0,        204,        204,        1,   149760, 0xa054a7bb
+0,        205,        205,        1,   149760, 0x5f78d160
+0,        206,        206,        1,   149760, 0x09f9a40f
+0,        207,        207,        1,   149760, 0xfb4a59f5
+0,        208,        208,        1,   149760, 0xdc5ca1f2
+0,        209,        209,        1,   149760, 0xf2254927
+0,        210,        210,        1,   149760, 0xfda4fab3
+0,        211,        211,        1,   149760, 0x45ab23cc
+0,        212,        212,        1,   149760, 0x1f69c006
+0,        213,        213,        1,   149760, 0x326bb5a1
+0,        214,        214,        1,   149760, 0x810dad28
+0,        215,        215,        1,   149760, 0x96dfc515
+0,        216,        216,        1,   149760, 0xc685fd80
+0,        217,        217,        1,   149760, 0x18da42f4
+0,        218,        218,        1,   149760, 0x11773807
+0,        219,        219,        1,   149760, 0x3f54c458
+0,        220,        220,        1,   149760, 0xa5dff146
+0,        221,        221,        1,   149760, 0x4bc3ffcb
+0,        222,        222,        1,   149760, 0x84801971
+0,        223,        223,        1,   149760, 0x2ff65539
+0,        224,        224,        1,   149760, 0x8a7f716d
+0,        225,        225,        1,   149760, 0xe7e8cdd0
+0,        226,        226,        1,   149760, 0xc8567d5f
+0,        227,        227,        1,   149760, 0x63986bcd
+0,        228,        228,        1,   149760, 0x8817f648
+0,        229,        229,        1,   149760, 0xa0152e36
+0,        230,        230,        1,   149760, 0x2eca851e
+0,        231,        231,        1,   149760, 0x09c0f0cb
+0,        232,        232,        1,   149760, 0xf1c81b23
+0,        233,        233,        1,   149760, 0x93096c98
+0,        234,        234,        1,   149760, 0x1fe47331
+0,        235,        235,        1,   149760, 0x79c0b70e
+0,        236,        236,        1,   149760, 0xb1929b60
+0,        237,        237,        1,   149760, 0xb42ea35a
+0,        238,        238,        1,   149760, 0x42d5bf86
+0,        239,        239,        1,   149760, 0xa83efbd4
+0,        240,        240,        1,   149760, 0xbdd2f313
+0,        241,        241,        1,   149760, 0x85a5dbd4
+0,        242,        242,        1,   149760, 0xc475b180
+0,        243,        243,        1,   149760, 0x63911e68
+0,        244,        244,        1,   149760, 0x5b79baab
+0,        245,        245,        1,   149760, 0xa22d310e
+0,        246,        246,        1,   149760, 0x243ef7b5
+0,        247,        247,        1,   149760, 0x813fdc95
+0,        248,        248,        1,   149760, 0xbb7d19fa
+0,        249,        249,        1,   149760, 0x199ae62c
+0,        250,        250,        1,   149760, 0x7a4ce5b2
+0,        251,        251,        1,   149760, 0xd632a9d3
+0,        252,        252,        1,   149760, 0xc07b75fe
+0,        253,        253,        1,   149760, 0x5bae6a88
+0,        254,        254,        1,   149760, 0x29b411e0
+0,        255,        255,        1,   149760, 0x78706cbe
+0,        256,        256,        1,   149760, 0x2659a6cb
+0,        257,        257,        1,   149760, 0xefb170f8
+0,        258,        258,        1,   149760, 0x9dd107b8
+0,        259,        259,        1,   149760, 0xf38b5ce5
+0,        260,        260,        1,   149760, 0xd7e0f10e
+0,        261,        261,        1,   149760, 0x080b9e49
+0,        262,        262,        1,   149760, 0xa2274c3b
+0,        263,        263,        1,   149760, 0x3d3376c9
+0,        264,        264,        1,   149760, 0xe04719e3
+0,        265,        265,        1,   149760, 0xfe4123e3
+0,        266,        266,        1,   149760, 0x769a3cf6
+0,        267,        267,        1,   149760, 0xaf0be9e6
+0,        268,        268,        1,   149760, 0xe9baa873
+0,        269,        269,        1,   149760, 0x4f5fb405
+0,        270,        270,        1,   149760, 0x207b401e
+0,        271,        271,        1,   149760, 0xb1483351
+0,        272,        272,        1,   149760, 0x5fe3dc9f
+0,        273,        273,        1,   149760, 0xb35dcae7
+0,        274,        274,        1,   149760, 0x8cc69de4
+0,        275,        275,        1,   149760, 0xd6e29308
+0,        276,        276,        1,   149760, 0xf8f53227
+0,        277,        277,        1,   149760, 0xaf483e80
+0,        278,        278,        1,   149760, 0x287cdfc9
+0,        279,        279,        1,   149760, 0xf72b93eb
+0,        280,        280,        1,   149760, 0x09c26976
+0,        281,        281,        1,   149760, 0xae58601f
+0,        282,        282,        1,   149760, 0x7f951546
+0,        283,        283,        1,   149760, 0x81e742b2
+0,        284,        284,        1,   149760, 0xb16554a6
+0,        285,        285,        1,   149760, 0xcdafc4c0
+0,        286,        286,        1,   149760, 0x0bb335bc
+0,        287,        287,        1,   149760, 0xe1e4ba60
+0,        288,        288,        1,   149760, 0xcce3eb48
+0,        289,        289,        1,   149760, 0x8b8992a9
+0,        290,        290,        1,   149760, 0x0a5ff2f6
+0,        291,        291,        1,   149760, 0xb04b8ed1
+0,        292,        292,        1,   149760, 0x0c874aae
+0,        293,        293,        1,   149760, 0x19d6f138
+0,        294,        294,        1,   149760, 0x30e322f2
+0,        295,        295,        1,   149760, 0x67a5700c
+0,        296,        296,        1,   149760, 0xb65bd462
+0,        297,        297,        1,   149760, 0xe267d09e
+0,        298,        298,        1,   149760, 0x8824c043
+0,        299,        299,        1,   149760, 0x680cfc20
diff --git a/tests/ref/fate/hevc-conformance-RPS_C_ericsson_4 b/tests/ref/fate/hevc-conformance-RPS_C_ericsson_4
new file mode 100644
index 0000000..e97e7ea
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_C_ericsson_4
@@ -0,0 +1,41 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8ce7200b
+0,          1,          1,        1,   149760, 0x85340cda
+0,          2,          2,        1,   149760, 0x16fd1f91
+0,          3,          3,        1,   149760, 0x7d8d312d
+0,          4,          4,        1,   149760, 0xae6ed875
+0,          5,          5,        1,   149760, 0xccac730a
+0,          6,          6,        1,   149760, 0x3d321c3f
+0,          7,          7,        1,   149760, 0x18e05688
+0,          8,          8,        1,   149760, 0x23fec4de
+0,          9,          9,        1,   149760, 0x3e0de0ca
+0,         10,         10,        1,   149760, 0x4789e861
+0,         11,         11,        1,   149760, 0x34550f71
+0,         12,         12,        1,   149760, 0xb0b1b4a7
+0,         13,         13,        1,   149760, 0xb9b8967e
+0,         14,         14,        1,   149760, 0x92e7f3c5
+0,         15,         15,        1,   149760, 0x61c0f62e
+0,         16,         16,        1,   149760, 0x819648c5
+0,         17,         17,        1,   149760, 0xe0286f95
+0,         18,         18,        1,   149760, 0xc2d85311
+0,         19,         19,        1,   149760, 0xbb07ec4e
+0,         20,         20,        1,   149760, 0xe073f10b
+0,         21,         21,        1,   149760, 0xd2e8c52f
+0,         22,         22,        1,   149760, 0x12020583
+0,         23,         23,        1,   149760, 0x0dfecaba
+0,         24,         24,        1,   149760, 0xe35f8ee5
+0,         25,         25,        1,   149760, 0x267bbf14
+0,         26,         26,        1,   149760, 0x371037a8
+0,         27,         27,        1,   149760, 0x3d188434
+0,         28,         28,        1,   149760, 0xce81fd31
+0,         29,         29,        1,   149760, 0xfbbf2801
+0,         30,         30,        1,   149760, 0x9af9d1b6
+0,         31,         31,        1,   149760, 0x14e2feea
+0,         32,         32,        1,   149760, 0x83f04b3a
+0,         33,         33,        1,   149760, 0xfc30687f
+0,         34,         34,        1,   149760, 0xaec2be07
+0,         35,         35,        1,   149760, 0xc7da6926
+0,         36,         36,        1,   149760, 0x50d20e8e
+0,         37,         37,        1,   149760, 0xd0fa63e9
+0,         38,         38,        1,   149760, 0x9d15906a
+0,         39,         39,        1,   149760, 0x4c685317
diff --git a/tests/ref/fate/hevc-conformance-RPS_D_ericsson_5 b/tests/ref/fate/hevc-conformance-RPS_D_ericsson_5
new file mode 100644
index 0000000..1a58c0d
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_D_ericsson_5
@@ -0,0 +1,69 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8ce7200b
+0,          2,          2,        1,   149760, 0x73610669
+0,          3,          3,        1,   149760, 0xc01620f4
+0,          4,          4,        1,   149760, 0x847a4297
+0,          5,          5,        1,   149760, 0xb4d3e870
+0,          6,          6,        1,   149760, 0xc2dd98a6
+0,          7,          7,        1,   149760, 0xefd02009
+0,          8,          8,        1,   149760, 0x3ae86ed0
+0,          9,          9,        1,   149760, 0x92f3cfb6
+0,         10,         10,        1,   149760, 0x0393e437
+0,         11,         11,        1,   149760, 0x6b29ea60
+0,         12,         12,        1,   149760, 0x9cb1216a
+0,         13,         13,        1,   149760, 0x82c2b1c4
+0,         14,         14,        1,   149760, 0x74899241
+0,         15,         15,        1,   149760, 0xa561f720
+0,         16,         16,        1,   149760, 0x339a11f6
+0,         17,         17,        1,   149760, 0x6bd9772b
+0,         18,         18,        1,   149760, 0x0a0c7c7d
+0,         19,         19,        1,   149760, 0x38426f65
+0,         20,         20,        1,   149760, 0x134ee7b3
+0,         21,         21,        1,   149760, 0xe436e35c
+0,         22,         22,        1,   149760, 0x4174d949
+0,         23,         23,        1,   149760, 0x44e60f0d
+0,         24,         24,        1,   149760, 0xbb6fb0a4
+0,         25,         25,        1,   149760, 0x715a653e
+0,         26,         26,        1,   149760, 0xad11b160
+0,         27,         27,        1,   149760, 0xfa6b368e
+0,         28,         28,        1,   149760, 0x60ff970f
+0,         29,         29,        1,   149760, 0x16430649
+0,         30,         30,        1,   149760, 0xa6cc0767
+0,         31,         31,        1,   149760, 0x59b0c566
+0,         32,         32,        1,   149760, 0xc9e3dfa9
+0,         33,         33,        1,   149760, 0x82873917
+0,         34,         34,        1,   149760, 0xc49e5d22
+0,         35,         35,        1,   149760, 0x416890a8
+0,         36,         36,        1,   149760, 0x386e57e8
+0,         37,         37,        1,   149760, 0x1c27e9d7
+0,         38,         38,        1,   149760, 0x85425596
+0,         39,         39,        1,   149760, 0xe6107df8
+0,         40,         40,        1,   149760, 0x056a3977
+0,         41,         41,        1,   149760, 0x753cf7f7
+0,         42,         42,        1,   149760, 0xc4005218
+0,         43,         43,        1,   149760, 0xce7edcf2
+0,         44,         44,        1,   149760, 0x93465fee
+0,         45,         45,        1,   149760, 0xa21b040a
+0,         46,         46,        1,   149760, 0xd82a53d5
+0,         47,         47,        1,   149760, 0x8f8fd3ae
+0,         48,         48,        1,   149760, 0x52420da5
+0,         49,         49,        1,   149760, 0xa899a9be
+0,         50,         50,        1,   149760, 0xcd85e363
+0,         51,         51,        1,   149760, 0x1a9240c4
+0,         52,         52,        1,   149760, 0xf0b11a36
+0,         53,         53,        1,   149760, 0xcf175809
+0,         54,         54,        1,   149760, 0x24afecc2
+0,         55,         55,        1,   149760, 0x874f7176
+0,         56,         56,        1,   149760, 0xb126dff9
+0,         57,         57,        1,   149760, 0x825ba060
+0,         58,         58,        1,   149760, 0x18c55eed
+0,         59,         59,        1,   149760, 0xf09b03f0
+0,         60,         60,        1,   149760, 0xf4dafd64
+0,         61,         61,        1,   149760, 0x08b49190
+0,         62,         62,        1,   149760, 0xcf336dc7
+0,         63,         63,        1,   149760, 0x51c65c08
+0,         64,         64,        1,   149760, 0x6cfe3433
+0,         65,         65,        1,   149760, 0x4b0af196
+0,         66,         66,        1,   149760, 0xffaeb2db
+0,         67,         67,        1,   149760, 0xa990a19f
+0,         68,         68,        1,   149760, 0x7ed944a3
diff --git a/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5 b/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5
new file mode 100644
index 0000000..82c25e1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5
@@ -0,0 +1,301 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x8edb27d7
+0,          1,          1,        1,   149760, 0xd62a31bc
+0,          2,          2,        1,   149760, 0xec822f84
+0,          3,          3,        1,   149760, 0x7a0a0f25
+0,          4,          4,        1,   149760, 0x461dd882
+0,          5,          5,        1,   149760, 0x62777923
+0,          6,          6,        1,   149760, 0x063c2559
+0,          7,          7,        1,   149760, 0x03b34c02
+0,          8,          8,        1,   149760, 0xe999bdad
+0,          9,          9,        1,   149760, 0x3285f731
+0,         10,         10,        1,   149760, 0x1f8ffaaa
+0,         11,         11,        1,   149760, 0xd7c956f4
+0,         12,         12,        1,   149760, 0xb9e3da56
+0,         13,         13,        1,   149760, 0x1200953f
+0,         14,         14,        1,   149760, 0x06c212cc
+0,         15,         15,        1,   149760, 0xaaa84f01
+0,         16,         16,        1,   149760, 0x7a606de8
+0,         17,         17,        1,   149760, 0x47e49e5a
+0,         18,         18,        1,   149760, 0x666a3370
+0,         19,         19,        1,   149760, 0x187b6b6c
+0,         20,         20,        1,   149760, 0x3c8f0ef4
+0,         21,         21,        1,   149760, 0xc3e59d36
+0,         22,         22,        1,   149760, 0xecb40b3b
+0,         23,         23,        1,   149760, 0x0ae9e31e
+0,         24,         24,        1,   149760, 0xd324746b
+0,         25,         25,        1,   149760, 0xc337c3d5
+0,         26,         26,        1,   149760, 0xd3883c16
+0,         27,         27,        1,   149760, 0xa28b836c
+0,         28,         28,        1,   149760, 0x1cd61f86
+0,         29,         29,        1,   149760, 0x52b51344
+0,         30,         30,        1,   149760, 0x3980a396
+0,         31,         31,        1,   149760, 0x85d0e262
+0,         32,         32,        1,   149760, 0xbd342d08
+0,         33,         33,        1,   149760, 0xc6114038
+0,         34,         34,        1,   149760, 0xc3ab6ca9
+0,         35,         35,        1,   149760, 0x6db56aa7
+0,         36,         36,        1,   149760, 0x22df9ab0
+0,         37,         37,        1,   149760, 0xfa6d2caf
+0,         38,         38,        1,   149760, 0xc1b64e52
+0,         39,         39,        1,   149760, 0x4b9c1d64
+0,         40,         40,        1,   149760, 0xbab6de8f
+0,         41,         41,        1,   149760, 0xfc0e1193
+0,         42,         42,        1,   149760, 0x8fa0a268
+0,         43,         43,        1,   149760, 0x80cf5e07
+0,         44,         44,        1,   149760, 0xe9720cd6
+0,         45,         45,        1,   149760, 0xa9bb2593
+0,         46,         46,        1,   149760, 0xc2e3e7c6
+0,         47,         47,        1,   149760, 0xc9a4ffd6
+0,         48,         48,        1,   149760, 0x9acebbe2
+0,         49,         49,        1,   149760, 0xb3a6bee1
+0,         50,         50,        1,   149760, 0xd1f12057
+0,         51,         51,        1,   149760, 0x9a2306c0
+0,         52,         52,        1,   149760, 0xd1ee37ff
+0,         53,         53,        1,   149760, 0xb0e1dca1
+0,         54,         54,        1,   149760, 0x35646e46
+0,         55,         55,        1,   149760, 0x803baac5
+0,         56,         56,        1,   149760, 0x7ee17b15
+0,         57,         57,        1,   149760, 0x03274ce1
+0,         58,         58,        1,   149760, 0xf3db2fea
+0,         59,         59,        1,   149760, 0xc3c4ff33
+0,         60,         60,        1,   149760, 0x0fc4786e
+0,         61,         61,        1,   149760, 0x27505756
+0,         62,         62,        1,   149760, 0x4c797266
+0,         63,         63,        1,   149760, 0xeba43f1b
+0,         64,         64,        1,   149760, 0x1ae5f13d
+0,         65,         65,        1,   149760, 0x97e186b1
+0,         66,         66,        1,   149760, 0xc0556895
+0,         67,         67,        1,   149760, 0x4e4d18ed
+0,         68,         68,        1,   149760, 0x39811c80
+0,         69,         69,        1,   149760, 0x6bca8c2f
+0,         70,         70,        1,   149760, 0x27ec4807
+0,         71,         71,        1,   149760, 0x50cea38b
+0,         72,         72,        1,   149760, 0x7ec4c09d
+0,         73,         73,        1,   149760, 0xb2a8afee
+0,         74,         74,        1,   149760, 0x0e943cbf
+0,         75,         75,        1,   149760, 0x7c119ea8
+0,         76,         76,        1,   149760, 0x71e194e5
+0,         77,         77,        1,   149760, 0x6a5d792d
+0,         78,         78,        1,   149760, 0xb8aeb406
+0,         79,         79,        1,   149760, 0x263767f2
+0,         80,         80,        1,   149760, 0xcfbef5ae
+0,         81,         81,        1,   149760, 0xad7eb01c
+0,         82,         82,        1,   149760, 0x612d937d
+0,         83,         83,        1,   149760, 0x90a591fd
+0,         84,         84,        1,   149760, 0x582a60dd
+0,         85,         85,        1,   149760, 0x2640124e
+0,         86,         86,        1,   149760, 0x1c12b037
+0,         87,         87,        1,   149760, 0xc916c4e7
+0,         88,         88,        1,   149760, 0x43d2bfe6
+0,         89,         89,        1,   149760, 0xdc7460c4
+0,         90,         90,        1,   149760, 0xc46e21a8
+0,         91,         91,        1,   149760, 0xe08dbd50
+0,         92,         92,        1,   149760, 0xf40bceed
+0,         93,         93,        1,   149760, 0x0ab01b81
+0,         94,         94,        1,   149760, 0xe6ab1f16
+0,         95,         95,        1,   149760, 0x6b4f6a62
+0,         96,         96,        1,   149760, 0x8ff7a1a1
+0,         97,         97,        1,   149760, 0x079be281
+0,         98,         98,        1,   149760, 0xa24bc187
+0,         99,         99,        1,   149760, 0xfbed7e79
+0,        100,        100,        1,   149760, 0xa27c2048
+0,        101,        101,        1,   149760, 0xe6119831
+0,        102,        102,        1,   149760, 0xc75684c6
+0,        103,        103,        1,   149760, 0x76575ef4
+0,        104,        104,        1,   149760, 0xebd32a7e
+0,        105,        105,        1,   149760, 0x6e5c703a
+0,        106,        106,        1,   149760, 0x3c43d0b3
+0,        107,        107,        1,   149760, 0xcc3354af
+0,        108,        108,        1,   149760, 0xa7bc26f3
+0,        109,        109,        1,   149760, 0xb04b0400
+0,        110,        110,        1,   149760, 0x3e5d3995
+0,        111,        111,        1,   149760, 0x549331ae
+0,        112,        112,        1,   149760, 0xd39031c0
+0,        113,        113,        1,   149760, 0xada1a1bd
+0,        114,        114,        1,   149760, 0xd08a4bcb
+0,        115,        115,        1,   149760, 0xcbefb4fa
+0,        116,        116,        1,   149760, 0xb311a7e0
+0,        117,        117,        1,   149760, 0xab23a6f2
+0,        118,        118,        1,   149760, 0xa90a6dfb
+0,        119,        119,        1,   149760, 0xafcc72b7
+0,        120,        120,        1,   149760, 0xe7c48044
+0,        121,        121,        1,   149760, 0x4449cf72
+0,        122,        122,        1,   149760, 0xfe4ba9d7
+0,        123,        123,        1,   149760, 0x76623bda
+0,        124,        124,        1,   149760, 0x8d071b0b
+0,        125,        125,        1,   149760, 0x777aaefa
+0,        126,        126,        1,   149760, 0xab995bab
+0,        127,        127,        1,   149760, 0xfd0e8e0c
+0,        128,        128,        1,   149760, 0xb6d651e5
+0,        129,        129,        1,   149760, 0x0646c2d0
+0,        130,        130,        1,   149760, 0xefc2561a
+0,        131,        131,        1,   149760, 0xaa86dcd1
+0,        132,        132,        1,   149760, 0x0caf821e
+0,        133,        133,        1,   149760, 0x55a5e7fa
+0,        134,        134,        1,   149760, 0x1a011bae
+0,        135,        135,        1,   149760, 0xe7a922b2
+0,        136,        136,        1,   149760, 0x4b968175
+0,        137,        137,        1,   149760, 0xc0bc1018
+0,        138,        138,        1,   149760, 0x58775461
+0,        139,        139,        1,   149760, 0x77dad082
+0,        140,        140,        1,   149760, 0x995e78d7
+0,        141,        141,        1,   149760, 0xc6360898
+0,        142,        142,        1,   149760, 0xbd0b48ce
+0,        143,        143,        1,   149760, 0x6d076602
+0,        144,        144,        1,   149760, 0xc3459e98
+0,        145,        145,        1,   149760, 0x8e53625e
+0,        146,        146,        1,   149760, 0xd1ba7915
+0,        147,        147,        1,   149760, 0xf41a48e7
+0,        148,        148,        1,   149760, 0xc3fbdcc3
+0,        149,        149,        1,   149760, 0x1f726dcf
+0,        150,        150,        1,   149760, 0x6f882d61
+0,        151,        151,        1,   149760, 0x2e02c8c5
+0,        152,        152,        1,   149760, 0x35ed54c6
+0,        153,        153,        1,   149760, 0x11dd8c48
+0,        154,        154,        1,   149760, 0xc95bf20b
+0,        155,        155,        1,   149760, 0x64f96433
+0,        156,        156,        1,   149760, 0x1ab5d8d5
+0,        157,        157,        1,   149760, 0x3af856f0
+0,        158,        158,        1,   149760, 0xdaa3bd1b
+0,        159,        159,        1,   149760, 0x25c64816
+0,        160,        160,        1,   149760, 0x6a4cc5d7
+0,        161,        161,        1,   149760, 0xf8e815f5
+0,        162,        162,        1,   149760, 0xa0bf431e
+0,        163,        163,        1,   149760, 0x09567fc4
+0,        164,        164,        1,   149760, 0x2d9408d7
+0,        165,        165,        1,   149760, 0xe09fff24
+0,        166,        166,        1,   149760, 0x6d58a81b
+0,        167,        167,        1,   149760, 0x0280e181
+0,        168,        168,        1,   149760, 0x465e63d1
+0,        169,        169,        1,   149760, 0xedb432a0
+0,        170,        170,        1,   149760, 0xdff70d73
+0,        171,        171,        1,   149760, 0x9386fdb4
+0,        172,        172,        1,   149760, 0xdcb03cb9
+0,        173,        173,        1,   149760, 0x3538dbd4
+0,        174,        174,        1,   149760, 0xc637709d
+0,        175,        175,        1,   149760, 0x7a1a6681
+0,        176,        176,        1,   149760, 0x403ca1e0
+0,        177,        177,        1,   149760, 0xe562d48a
+0,        178,        178,        1,   149760, 0x90a2e933
+0,        179,        179,        1,   149760, 0x0e9e167a
+0,        180,        180,        1,   149760, 0x2da90c4d
+0,        181,        181,        1,   149760, 0x2ce92218
+0,        182,        182,        1,   149760, 0x164a613d
+0,        183,        183,        1,   149760, 0x336d9e2e
+0,        184,        184,        1,   149760, 0x598986e6
+0,        185,        185,        1,   149760, 0xd0039cfc
+0,        186,        186,        1,   149760, 0x8e74c5e6
+0,        187,        187,        1,   149760, 0xb95fa63c
+0,        188,        188,        1,   149760, 0xc688c596
+0,        189,        189,        1,   149760, 0x4757034b
+0,        190,        190,        1,   149760, 0xc9ac948a
+0,        191,        191,        1,   149760, 0x580b9d60
+0,        192,        192,        1,   149760, 0xf39031d6
+0,        193,        193,        1,   149760, 0x2d68ad7b
+0,        194,        194,        1,   149760, 0xf72815ea
+0,        195,        195,        1,   149760, 0xc16323fa
+0,        196,        196,        1,   149760, 0x8a65665e
+0,        197,        197,        1,   149760, 0xcf1d5a89
+0,        198,        198,        1,   149760, 0x03f3011a
+0,        199,        199,        1,   149760, 0x24c47cbc
+0,        200,        200,        1,   149760, 0xcc89db6d
+0,        201,        201,        1,   149760, 0xd8332e3c
+0,        202,        202,        1,   149760, 0x8a73af5f
+0,        203,        203,        1,   149760, 0x9079e1c5
+0,        204,        204,        1,   149760, 0x7b70b098
+0,        205,        205,        1,   149760, 0x8a0fc720
+0,        206,        206,        1,   149760, 0x92644eef
+0,        207,        207,        1,   149760, 0x75cc5f7a
+0,        208,        208,        1,   149760, 0xf04b9756
+0,        209,        209,        1,   149760, 0x156b33cd
+0,        210,        210,        1,   149760, 0x4876d087
+0,        211,        211,        1,   149760, 0x393c01c8
+0,        212,        212,        1,   149760, 0x29b0a5d9
+0,        213,        213,        1,   149760, 0xd76249a1
+0,        214,        214,        1,   149760, 0xb946135e
+0,        215,        215,        1,   149760, 0x4968f245
+0,        216,        216,        1,   149760, 0xb91e27b2
+0,        217,        217,        1,   149760, 0x485bfa6c
+0,        218,        218,        1,   149760, 0xe7f9fe28
+0,        219,        219,        1,   149760, 0x46a6a837
+0,        220,        220,        1,   149760, 0xd2cf971c
+0,        221,        221,        1,   149760, 0xcb518e01
+0,        222,        222,        1,   149760, 0x7870fcd4
+0,        223,        223,        1,   149760, 0x8af73981
+0,        224,        224,        1,   149760, 0xa90281a7
+0,        225,        225,        1,   149760, 0x3fd9c634
+0,        226,        226,        1,   149760, 0x5c4e7e8a
+0,        227,        227,        1,   149760, 0x520d80e9
+0,        228,        228,        1,   149760, 0xd94a7e31
+0,        229,        229,        1,   149760, 0x2a846f4e
+0,        230,        230,        1,   149760, 0x71f027f1
+0,        231,        231,        1,   149760, 0x6edbe368
+0,        232,        232,        1,   149760, 0x5c9923eb
+0,        233,        233,        1,   149760, 0xff230eab
+0,        234,        234,        1,   149760, 0xc7a5ca99
+0,        235,        235,        1,   149760, 0x50732f2a
+0,        236,        236,        1,   149760, 0xa9f3c8bc
+0,        237,        237,        1,   149760, 0x7fa53464
+0,        238,        238,        1,   149760, 0xe4c2edcd
+0,        239,        239,        1,   149760, 0x43f1e758
+0,        240,        240,        1,   149760, 0xdb6b153b
+0,        241,        241,        1,   149760, 0x0979d792
+0,        242,        242,        1,   149760, 0xaae4a6fd
+0,        243,        243,        1,   149760, 0x7ffd1046
+0,        244,        244,        1,   149760, 0x083becd8
+0,        245,        245,        1,   149760, 0xba86428d
+0,        246,        246,        1,   149760, 0xd4cf652a
+0,        247,        247,        1,   149760, 0xe518a1e4
+0,        248,        248,        1,   149760, 0xfbcf0017
+0,        249,        249,        1,   149760, 0xd827b5b1
+0,        250,        250,        1,   149760, 0x6b95eb0d
+0,        251,        251,        1,   149760, 0x625bf8f9
+0,        252,        252,        1,   149760, 0xde17b8b8
+0,        253,        253,        1,   149760, 0xfd731e76
+0,        254,        254,        1,   149760, 0xae0ce756
+0,        255,        255,        1,   149760, 0x15ec506d
+0,        256,        256,        1,   149760, 0xfc9dba5c
+0,        257,        257,        1,   149760, 0x87e46ba1
+0,        258,        258,        1,   149760, 0x31f1d787
+0,        259,        259,        1,   149760, 0xfbde528e
+0,        260,        260,        1,   149760, 0x152becf8
+0,        261,        261,        1,   149760, 0x008386d7
+0,        262,        262,        1,   149760, 0x53c00ef9
+0,        263,        263,        1,   149760, 0x322d4f0b
+0,        264,        264,        1,   149760, 0xd31bf0ec
+0,        265,        265,        1,   149760, 0x66b5097e
+0,        266,        266,        1,   149760, 0xa9cd719f
+0,        267,        267,        1,   149760, 0x427cdc52
+0,        268,        268,        1,   149760, 0x6647dabc
+0,        269,        269,        1,   149760, 0x651df15f
+0,        270,        270,        1,   149760, 0x4ce124c7
+0,        271,        271,        1,   149760, 0x8ad42ad7
+0,        272,        272,        1,   149760, 0x7303ce98
+0,        273,        273,        1,   149760, 0x0c8ad3ab
+0,        274,        274,        1,   149760, 0x86859065
+0,        275,        275,        1,   149760, 0x97f23fc7
+0,        276,        276,        1,   149760, 0x6fde3d1a
+0,        277,        277,        1,   149760, 0xca12860e
+0,        278,        278,        1,   149760, 0xd0c98709
+0,        279,        279,        1,   149760, 0x8f234c79
+0,        280,        280,        1,   149760, 0xbc6987fa
+0,        281,        281,        1,   149760, 0x40246698
+0,        282,        282,        1,   149760, 0x7f83b9ad
+0,        283,        283,        1,   149760, 0x87a3596b
+0,        284,        284,        1,   149760, 0x0ba5d7f6
+0,        285,        285,        1,   149760, 0x2a015c97
+0,        286,        286,        1,   149760, 0xa1a73e7b
+0,        287,        287,        1,   149760, 0x3c1d8178
+0,        288,        288,        1,   149760, 0x2207f0b6
+0,        289,        289,        1,   149760, 0x1f56738a
+0,        290,        290,        1,   149760, 0x0014e5b6
+0,        291,        291,        1,   149760, 0xe0113ffa
+0,        292,        292,        1,   149760, 0x7df23683
+0,        293,        293,        1,   149760, 0x2a1afb23
+0,        294,        294,        1,   149760, 0x072ced03
+0,        295,        295,        1,   149760, 0x7afca5d3
+0,        296,        296,        1,   149760, 0x6055b3da
+0,        297,        297,        1,   149760, 0xa785c79c
+0,        298,        298,        1,   149760, 0x3606db52
+0,        299,        299,        1,   149760, 0x007fdd05
diff --git a/tests/ref/fate/hevc-conformance-RQT_A_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_A_HHI_4
new file mode 100644
index 0000000..5f2b9da
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_A_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x5c0f5423
+0,          1,          1,        1,   599040, 0x3d23be58
diff --git a/tests/ref/fate/hevc-conformance-RQT_B_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_B_HHI_4
new file mode 100644
index 0000000..dcf2691
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_B_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x69854954
+0,          1,          1,        1,   599040, 0x695ebc85
diff --git a/tests/ref/fate/hevc-conformance-RQT_C_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_C_HHI_4
new file mode 100644
index 0000000..2e88350
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_C_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x65433cfe
+0,          1,          1,        1,   599040, 0x9309e2c5
diff --git a/tests/ref/fate/hevc-conformance-RQT_D_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_D_HHI_4
new file mode 100644
index 0000000..7f73896
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_D_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x88d741bf
+0,          1,          1,        1,   599040, 0xbbd9ab22
diff --git a/tests/ref/fate/hevc-conformance-RQT_E_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_E_HHI_4
new file mode 100644
index 0000000..f062318
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_E_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xce2e511d
+0,          1,          1,        1,   599040, 0xe55192d0
diff --git a/tests/ref/fate/hevc-conformance-RQT_F_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_F_HHI_4
new file mode 100644
index 0000000..26bf5ac
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_F_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x65433cfe
+0,          1,          1,        1,   599040, 0x6f99cc5f
diff --git a/tests/ref/fate/hevc-conformance-RQT_G_HHI_4 b/tests/ref/fate/hevc-conformance-RQT_G_HHI_4
new file mode 100644
index 0000000..d36ea01
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-RQT_G_HHI_4
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x5c0f5423
+0,          1,          1,        1,   599040, 0xe805b181
diff --git a/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4 b/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4
new file mode 100644
index 0000000..01226d9
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x304198c2
+0,          1,          1,        1,   149760, 0xe765e30d
+0,          2,          2,        1,   149760, 0x0130a054
+0,          3,          3,        1,   149760, 0x169ed0c3
+0,          4,          4,        1,   149760, 0x334881a5
+0,          5,          5,        1,   149760, 0x06cadd37
+0,          6,          6,        1,   149760, 0x5ec4a7ee
+0,          7,          7,        1,   149760, 0x595fd534
+0,          8,          8,        1,   149760, 0xa1d97197
+0,          9,          9,        1,   149760, 0xf79a9d84
+0,         10,         10,        1,   149760, 0x10d84f28
+0,         11,         11,        1,   149760, 0xab375848
+0,         12,         12,        1,   149760, 0x3079f8ca
+0,         13,         13,        1,   149760, 0xac101dfb
+0,         14,         14,        1,   149760, 0x5354f852
+0,         15,         15,        1,   149760, 0x64d709d5
+0,         16,         16,        1,   149760, 0xff669ff2
+0,         17,         17,        1,   149760, 0xd20dd474
+0,         18,         18,        1,   149760, 0x32439e22
+0,         19,         19,        1,   149760, 0x3ae5a118
+0,         20,         20,        1,   149760, 0xebe245ef
+0,         21,         21,        1,   149760, 0x9d046e35
+0,         22,         22,        1,   149760, 0x2e5b2347
+0,         23,         23,        1,   149760, 0x0e683e86
+0,         24,         24,        1,   149760, 0xccc1019e
+0,         25,         25,        1,   149760, 0x42a9571a
+0,         26,         26,        1,   149760, 0x8999386c
+0,         27,         27,        1,   149760, 0x3d164645
+0,         28,         28,        1,   149760, 0x657afc5e
+0,         29,         29,        1,   149760, 0x06f832f9
+0,         30,         30,        1,   149760, 0xfbedfe1e
+0,         31,         31,        1,   149760, 0x1edc2fc5
+0,         32,         32,        1,   149760, 0xe1cee4e7
+0,         33,         33,        1,   149760, 0x43a823e0
+0,         34,         34,        1,   149760, 0xc2f42916
+0,         35,         35,        1,   149760, 0x51db1483
+0,         36,         36,        1,   149760, 0x54a9d6bf
+0,         37,         37,        1,   149760, 0x7324e246
+0,         38,         38,        1,   149760, 0x2523cc9d
+0,         39,         39,        1,   149760, 0xfa3bdce3
+0,         40,         40,        1,   149760, 0xcf9fb7bb
+0,         41,         41,        1,   149760, 0xe914e23c
+0,         42,         42,        1,   149760, 0x6c9fd72a
+0,         43,         43,        1,   149760, 0x3580cca9
+0,         44,         44,        1,   149760, 0x1d4ec5c0
+0,         45,         45,        1,   149760, 0x52c4d418
+0,         46,         46,        1,   149760, 0xb728ae3e
+0,         47,         47,        1,   149760, 0x6616ae50
+0,         48,         48,        1,   149760, 0x6f1a919d
+0,         49,         49,        1,   149760, 0x6e76b774
+0,         50,         50,        1,   149760, 0x6075b37d
+0,         51,         51,        1,   149760, 0xeeb7b8df
+0,         52,         52,        1,   149760, 0xfd979056
+0,         53,         53,        1,   149760, 0xc0fda5ee
+0,         54,         54,        1,   149760, 0xd1329055
+0,         55,         55,        1,   149760, 0x9b179f0f
+0,         56,         56,        1,   149760, 0x7461850a
+0,         57,         57,        1,   149760, 0xe63a86ea
+0,         58,         58,        1,   149760, 0xe85c6f94
+0,         59,         59,        1,   149760, 0x0b857d13
diff --git a/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5 b/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5
new file mode 100644
index 0000000..9da0268
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xe56f6a5c
+0,          1,          1,        1,   599040, 0x31ec1bb9
+0,          2,          2,        1,   599040, 0xf3ce0311
+0,          3,          3,        1,   599040, 0x1ae1c223
+0,          4,          4,        1,   599040, 0x4369499d
+0,          5,          5,        1,   599040, 0xd7366bd6
+0,          6,          6,        1,   599040, 0x6d3a9099
+0,          7,          7,        1,   599040, 0x49dea495
+0,          8,          8,        1,   599040, 0x375640e7
+0,          9,          9,        1,   599040, 0x76b6f9b0
+0,         10,         10,        1,   599040, 0x7d1f48cf
+0,         11,         11,        1,   599040, 0x4a01899c
+0,         12,         12,        1,   599040, 0x34ff06e6
+0,         13,         13,        1,   599040, 0x270d874f
+0,         14,         14,        1,   599040, 0x5a091d5c
+0,         15,         15,        1,   599040, 0x36406961
+0,         16,         16,        1,   599040, 0xd32f2687
+0,         17,         17,        1,   599040, 0x8d533cb5
+0,         18,         18,        1,   599040, 0x5f189f98
+0,         19,         19,        1,   599040, 0x32b76de3
+0,         20,         20,        1,   599040, 0x2dd0e738
+0,         21,         21,        1,   599040, 0xbc24fe31
+0,         22,         22,        1,   599040, 0xfd5e6578
+0,         23,         23,        1,   599040, 0x23ea676c
+0,         24,         24,        1,   599040, 0xa86d1f70
+0,         25,         25,        1,   599040, 0xef35e81e
+0,         26,         26,        1,   599040, 0x19e5b355
+0,         27,         27,        1,   599040, 0x9dab17b3
+0,         28,         28,        1,   599040, 0x1aebe590
+0,         29,         29,        1,   599040, 0x6fd9b16e
+0,         30,         30,        1,   599040, 0xd2f3087b
+0,         31,         31,        1,   599040, 0x4bdc5019
+0,         32,         32,        1,   599040, 0xeccd10a0
+0,         33,         33,        1,   599040, 0x1eacd33c
+0,         34,         34,        1,   599040, 0xc73d2b6d
+0,         35,         35,        1,   599040, 0xe1305f2b
+0,         36,         36,        1,   599040, 0xb66c5e54
+0,         37,         37,        1,   599040, 0x0ac17870
+0,         38,         38,        1,   599040, 0x9d976180
+0,         39,         39,        1,   599040, 0x0be7d418
+0,         40,         40,        1,   599040, 0x5c4fb909
+0,         41,         41,        1,   599040, 0x7a4de7c2
+0,         42,         42,        1,   599040, 0x9c0d3ed3
+0,         43,         43,        1,   599040, 0xf9b2ba7e
+0,         44,         44,        1,   599040, 0x78e77b58
+0,         45,         45,        1,   599040, 0xc30ead17
+0,         46,         46,        1,   599040, 0x647c9095
+0,         47,         47,        1,   599040, 0x070d61a3
+0,         48,         48,        1,   599040, 0x0ec33c61
+0,         49,         49,        1,   599040, 0x0adcf4f3
+0,         50,         50,        1,   599040, 0x5cbb5aa6
+0,         51,         51,        1,   599040, 0xb9f99f74
+0,         52,         52,        1,   599040, 0xebc3c13e
+0,         53,         53,        1,   599040, 0x40e76036
+0,         54,         54,        1,   599040, 0xf08d2df3
+0,         55,         55,        1,   599040, 0x47442b55
+0,         56,         56,        1,   599040, 0x147622c1
+0,         57,         57,        1,   599040, 0xc95508a3
+0,         58,         58,        1,   599040, 0x361b8995
+0,         59,         59,        1,   599040, 0x51086ed4
diff --git a/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4 b/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4
new file mode 100644
index 0000000..f87921d
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xf923a1a0
+0,          1,          1,        1,   149760, 0x614d851a
+0,          2,          2,        1,   149760, 0xc3976ce4
+0,          3,          3,        1,   149760, 0x39925bdc
+0,          4,          4,        1,   149760, 0x86067422
+0,          5,          5,        1,   149760, 0x60dc6078
+0,          6,          6,        1,   149760, 0xac79a412
+0,          7,          7,        1,   149760, 0x3b1bab1e
+0,          8,          8,        1,   149760, 0x7562555f
+0,          9,          9,        1,   149760, 0xf0a2385f
+0,         10,         10,        1,   149760, 0xd2661fa6
+0,         11,         11,        1,   149760, 0x89b30a0a
+0,         12,         12,        1,   149760, 0x3c59f8cb
+0,         13,         13,        1,   149760, 0x70e4da0a
+0,         14,         14,        1,   149760, 0x5e60caa8
+0,         15,         15,        1,   149760, 0x9828a7e0
+0,         16,         16,        1,   149760, 0x11e069a1
+0,         17,         17,        1,   149760, 0xe98a55c2
+0,         18,         18,        1,   149760, 0xaa9f64e5
+0,         19,         19,        1,   149760, 0x03c32cea
+0,         20,         20,        1,   149760, 0x869e0f6e
+0,         21,         21,        1,   149760, 0x54baeff8
+0,         22,         22,        1,   149760, 0xf1f8cc04
+0,         23,         23,        1,   149760, 0x1724aafb
+0,         24,         24,        1,   149760, 0xaf01b9f8
+0,         25,         25,        1,   149760, 0xb1b5bbe9
+0,         26,         26,        1,   149760, 0xd9e6d5a4
+0,         27,         27,        1,   149760, 0x8351ca2d
+0,         28,         28,        1,   149760, 0x38dceffe
+0,         29,         29,        1,   149760, 0x3bffe1c4
+0,         30,         30,        1,   149760, 0x4075b534
+0,         31,         31,        1,   149760, 0x0e8fb246
+0,         32,         32,        1,   149760, 0x70fceafb
+0,         33,         33,        1,   149760, 0x940bec8d
+0,         34,         34,        1,   149760, 0x7d34f896
+0,         35,         35,        1,   149760, 0x39a1d77f
+0,         36,         36,        1,   149760, 0x9755e104
+0,         37,         37,        1,   149760, 0xd584cb48
+0,         38,         38,        1,   149760, 0x06ecdd44
+0,         39,         39,        1,   149760, 0x0226a40d
+0,         40,         40,        1,   149760, 0xb53aaf56
+0,         41,         41,        1,   149760, 0xdad4a984
+0,         42,         42,        1,   149760, 0xa58c9eb0
+0,         43,         43,        1,   149760, 0x7330bde6
+0,         44,         44,        1,   149760, 0x98fcabd9
+0,         45,         45,        1,   149760, 0x9570b74a
+0,         46,         46,        1,   149760, 0x3c1eab60
+0,         47,         47,        1,   149760, 0x2038a069
+0,         48,         48,        1,   149760, 0x672fa347
+0,         49,         49,        1,   149760, 0xa7328b16
+0,         50,         50,        1,   149760, 0x677b6a87
+0,         51,         51,        1,   149760, 0xb036b028
+0,         52,         52,        1,   149760, 0x7a7f9966
+0,         53,         53,        1,   149760, 0xc34b7c39
+0,         54,         54,        1,   149760, 0xb44345ed
+0,         55,         55,        1,   149760, 0x90193c4a
+0,         56,         56,        1,   149760, 0x90986e7b
+0,         57,         57,        1,   149760, 0x5e8e6545
+0,         58,         58,        1,   149760, 0x3ac7758e
+0,         59,         59,        1,   149760, 0x4dd271fb
diff --git a/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4 b/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4
new file mode 100644
index 0000000..ce1cefe
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x0d2edbbc
+0,          1,          1,        1,   149760, 0x4830af95
+0,          2,          2,        1,   149760, 0x39e8d3bb
+0,          3,          3,        1,   149760, 0x3cc8d639
+0,          4,          4,        1,   149760, 0xfcfe8415
+0,          5,          5,        1,   149760, 0xa6cf9a48
+0,          6,          6,        1,   149760, 0x0fe191b3
+0,          7,          7,        1,   149760, 0x71d26e20
+0,          8,          8,        1,   149760, 0x1ee5541a
+0,          9,          9,        1,   149760, 0x4ac56652
+0,         10,         10,        1,   149760, 0x967e7c2c
+0,         11,         11,        1,   149760, 0x2011ba0c
+0,         12,         12,        1,   149760, 0x2da4bc05
+0,         13,         13,        1,   149760, 0x6354fac2
+0,         14,         14,        1,   149760, 0x799e66ce
+0,         15,         15,        1,   149760, 0x2ca24940
+0,         16,         16,        1,   149760, 0x2a102e28
+0,         17,         17,        1,   149760, 0x652edcce
+0,         18,         18,        1,   149760, 0xb1c34a9a
+0,         19,         19,        1,   149760, 0xfae6ce90
+0,         20,         20,        1,   149760, 0xf42fddbf
+0,         21,         21,        1,   149760, 0x2a8532c3
+0,         22,         22,        1,   149760, 0xbe43addc
+0,         23,         23,        1,   149760, 0x3545f94a
+0,         24,         24,        1,   149760, 0xa35fa6fa
+0,         25,         25,        1,   149760, 0xfed8577f
+0,         26,         26,        1,   149760, 0xac03b492
+0,         27,         27,        1,   149760, 0x1fbdabc9
+0,         28,         28,        1,   149760, 0x99707175
+0,         29,         29,        1,   149760, 0x95e69481
+0,         30,         30,        1,   149760, 0xd68412d8
+0,         31,         31,        1,   149760, 0x9f900e37
+0,         32,         32,        1,   149760, 0x7e6eceba
+0,         33,         33,        1,   149760, 0xd1ca85af
+0,         34,         34,        1,   149760, 0x352b1d50
+0,         35,         35,        1,   149760, 0xdef3e377
+0,         36,         36,        1,   149760, 0x08efcc16
+0,         37,         37,        1,   149760, 0xc20a7c74
+0,         38,         38,        1,   149760, 0xa8e45939
+0,         39,         39,        1,   149760, 0x322546cf
+0,         40,         40,        1,   149760, 0xf7167766
+0,         41,         41,        1,   149760, 0x959f808f
+0,         42,         42,        1,   149760, 0xcca5ccc3
+0,         43,         43,        1,   149760, 0x18789407
+0,         44,         44,        1,   149760, 0xf6c97e87
+0,         45,         45,        1,   149760, 0x58aaba55
+0,         46,         46,        1,   149760, 0xc3529005
+0,         47,         47,        1,   149760, 0x3847adb4
+0,         48,         48,        1,   149760, 0xa4d589db
+0,         49,         49,        1,   149760, 0x9c50dd88
+0,         50,         50,        1,   149760, 0xad087c44
+0,         51,         51,        1,   149760, 0x4a6b656d
+0,         52,         52,        1,   149760, 0x6ec79bcf
+0,         53,         53,        1,   149760, 0x82756cb6
+0,         54,         54,        1,   149760, 0x8b3a9a6a
+0,         55,         55,        1,   149760, 0x775c0430
+0,         56,         56,        1,   149760, 0xbaa08d27
+0,         57,         57,        1,   149760, 0x686cd03f
+0,         58,         58,        1,   149760, 0x1b10dc94
+0,         59,         59,        1,   149760, 0xde81e414
diff --git a/tests/ref/fate/hevc-conformance-SAO_E_Canon_4 b/tests/ref/fate/hevc-conformance-SAO_E_Canon_4
new file mode 100644
index 0000000..92aa7f4
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_E_Canon_4
@@ -0,0 +1,17 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x1613b277
+0,          1,          1,        1,   149760, 0xf92d5543
+0,          2,          2,        1,   149760, 0xf119ba8e
+0,          3,          3,        1,   149760, 0xbce35d0a
+0,          4,          4,        1,   149760, 0x0f4dc325
+0,          5,          5,        1,   149760, 0xc95379ae
+0,          6,          6,        1,   149760, 0xbf4e9b84
+0,          7,          7,        1,   149760, 0x3a7c3cdf
+0,          8,          8,        1,   149760, 0x8d5e8895
+0,          9,          9,        1,   149760, 0x3128397e
+0,         10,         10,        1,   149760, 0x4389dee6
+0,         11,         11,        1,   149760, 0x8a6a7236
+0,         12,         12,        1,   149760, 0x638049ef
+0,         13,         13,        1,   149760, 0x0075da54
+0,         14,         14,        1,   149760, 0x5fd84a25
+0,         15,         15,        1,   149760, 0xfbd4af2b
diff --git a/tests/ref/fate/hevc-conformance-SAO_F_Canon_3 b/tests/ref/fate/hevc-conformance-SAO_F_Canon_3
new file mode 100644
index 0000000..cf24055
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_F_Canon_3
@@ -0,0 +1,17 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x92b5107a
+0,          1,          1,        1,   149760, 0x97eb31ef
+0,          2,          2,        1,   149760, 0xeb743e30
+0,          3,          3,        1,   149760, 0x5fc53434
+0,          4,          4,        1,   149760, 0x75fb1d63
+0,          5,          5,        1,   149760, 0xba0aeb27
+0,          6,          6,        1,   149760, 0x3f0f1780
+0,          7,          7,        1,   149760, 0xf5d0f052
+0,          8,          8,        1,   149760, 0x598ee54e
+0,          9,          9,        1,   149760, 0x09fcf908
+0,         10,         10,        1,   149760, 0x68209041
+0,         11,         11,        1,   149760, 0x05f519e9
+0,         12,         12,        1,   149760, 0xfdecf9b3
+0,         13,         13,        1,   149760, 0x40c96df8
+0,         14,         14,        1,   149760, 0x4b3d1b7b
+0,         15,         15,        1,   149760, 0xc0691cd9
diff --git a/tests/ref/fate/hevc-conformance-SAO_G_Canon_3 b/tests/ref/fate/hevc-conformance-SAO_G_Canon_3
new file mode 100644
index 0000000..5ce6772
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SAO_G_Canon_3
@@ -0,0 +1,17 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xc4f239e0
+0,          1,          1,        1,   149760, 0xf57a2e44
+0,          2,          2,        1,   149760, 0xbf1e9995
+0,          3,          3,        1,   149760, 0x5fa25087
+0,          4,          4,        1,   149760, 0x709b4c3f
+0,          5,          5,        1,   149760, 0x63abbd5c
+0,          6,          6,        1,   149760, 0xbd87092a
+0,          7,          7,        1,   149760, 0x59156f4a
+0,          8,          8,        1,   149760, 0xf8ed7d88
+0,          9,          9,        1,   149760, 0xdac1cecf
+0,         10,         10,        1,   149760, 0x7ba3b408
+0,         11,         11,        1,   149760, 0xad4bd5f5
+0,         12,         12,        1,   149760, 0x4b1f83c6
+0,         13,         13,        1,   149760, 0x7329797f
+0,         14,         14,        1,   149760, 0x1d201f16
+0,         15,         15,        1,   149760, 0xde263a30
diff --git a/tests/ref/fate/hevc-conformance-SDH_A_Orange_3 b/tests/ref/fate/hevc-conformance-SDH_A_Orange_3
new file mode 100644
index 0000000..caf90ee
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SDH_A_Orange_3
@@ -0,0 +1,3 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0x0117aa5d
+0,          1,          1,        1,  3110400, 0xa737bc56
diff --git a/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3 b/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3
new file mode 100644
index 0000000..f884f7f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3
@@ -0,0 +1,10 @@
+#tb 0: 1/25
+0,          0,          0,        1,   460800, 0x7f06cb02
+0,          1,          1,        1,   460800, 0x1ad483aa
+0,          2,          2,        1,   460800, 0x1bbbc991
+0,          3,          3,        1,   460800, 0x8fe7afa5
+0,          4,          4,        1,   460800, 0xe609cb0b
+0,          5,          5,        1,   460800, 0xcc65fec8
+0,          6,          6,        1,   460800, 0xa0601519
+0,          7,          7,        1,   460800, 0x8b0d3002
+0,          8,          8,        1,   460800, 0x7b1191af
diff --git a/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4 b/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4
new file mode 100644
index 0000000..ebb65c3
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4
@@ -0,0 +1,66 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xbd0eb43e
+0,          1,          1,        1,   599040, 0x4c3a98b5
+0,          2,          2,        1,   599040, 0x105410dc
+0,          3,          3,        1,   599040, 0xffaff69c
+0,          4,          4,        1,   599040, 0x39cb22ea
+0,          5,          5,        1,   599040, 0xa19296c3
+0,          6,          6,        1,   599040, 0x84cad39d
+0,          7,          7,        1,   599040, 0x5dc5c5a9
+0,          8,          8,        1,   599040, 0xc6a2c0dd
+0,          9,          9,        1,   599040, 0xeb5947bf
+0,         10,         10,        1,   599040, 0x9f8f9ce5
+0,         11,         11,        1,   599040, 0xdce5be4e
+0,         12,         12,        1,   599040, 0x07141c84
+0,         13,         13,        1,   599040, 0x3a05273d
+0,         14,         14,        1,   599040, 0xa16a112c
+0,         15,         15,        1,   599040, 0x6fa79123
+0,         16,         16,        1,   599040, 0xbda4cf46
+0,         17,         17,        1,   599040, 0xa5a81a05
+0,         18,         18,        1,   599040, 0x7370af29
+0,         19,         19,        1,   599040, 0xbd70e89e
+0,         20,         20,        1,   599040, 0xe7850613
+0,         21,         21,        1,   599040, 0xfaa8cf89
+0,         22,         22,        1,   599040, 0x30a78a21
+0,         23,         23,        1,   599040, 0x5520a8cf
+0,         24,         24,        1,   599040, 0xbcd93ea7
+0,         25,         25,        1,   599040, 0xd8ce632c
+0,         26,         26,        1,   599040, 0x87c6476f
+0,         27,         27,        1,   599040, 0xf6799dcc
+0,         28,         28,        1,   599040, 0xc0370664
+0,         29,         29,        1,   599040, 0x17196bd3
+0,         30,         30,        1,   599040, 0xe7ae6de3
+0,         31,         31,        1,   599040, 0x0345bc72
+0,         32,         32,        1,   599040, 0x7b86141e
+0,         33,         33,        1,   599040, 0x65564792
+0,         34,         34,        1,   599040, 0xf90c7f54
+0,         35,         35,        1,   599040, 0x00ce2f3c
+0,         36,         36,        1,   599040, 0xe6b185f2
+0,         37,         37,        1,   599040, 0x513942f1
+0,         38,         38,        1,   599040, 0x7c27b03a
+0,         39,         39,        1,   599040, 0xa201fea3
+0,         40,         40,        1,   599040, 0x5023fd92
+0,         41,         41,        1,   599040, 0xe05ba218
+0,         42,         42,        1,   599040, 0x84b61765
+0,         43,         43,        1,   599040, 0xfa6c8f65
+0,         44,         44,        1,   599040, 0xede8ef78
+0,         45,         45,        1,   599040, 0xcd2763f2
+0,         46,         46,        1,   599040, 0xb83e3bc6
+0,         47,         47,        1,   599040, 0x99fb3a3e
+0,         48,         48,        1,   599040, 0x3dd1e5ac
+0,         49,         49,        1,   599040, 0x776d7464
+0,         50,         50,        1,   599040, 0xaea89891
+0,         51,         51,        1,   599040, 0xfc0f1ec9
+0,         52,         52,        1,   599040, 0x2621f36f
+0,         53,         53,        1,   599040, 0x41101bbc
+0,         54,         54,        1,   599040, 0x7a5d4d0e
+0,         55,         55,        1,   599040, 0xc04fb148
+0,         56,         56,        1,   599040, 0x889d8186
+0,         57,         57,        1,   599040, 0x26f091bf
+0,         58,         58,        1,   599040, 0xe6644a2d
+0,         59,         59,        1,   599040, 0xd48efb7f
+0,         60,         60,        1,   599040, 0xe25204e3
+0,         61,         61,        1,   599040, 0x928f2efd
+0,         62,         62,        1,   599040, 0x535a4f2d
+0,         63,         63,        1,   599040, 0x2672ad63
+0,         64,         64,        1,   599040, 0x194f1463
diff --git a/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8 b/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8
new file mode 100644
index 0000000..fc39039
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8
@@ -0,0 +1,66 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xbd0eb43e
+0,          1,          1,        1,   599040, 0x3ea696c4
+0,          2,          2,        1,   599040, 0x866beffc
+0,          3,          3,        1,   599040, 0x89622860
+0,          4,          4,        1,   599040, 0x416bcaf8
+0,          5,          5,        1,   599040, 0x4098709b
+0,          6,          6,        1,   599040, 0x8d1ef343
+0,          7,          7,        1,   599040, 0xbd1bbc79
+0,          8,          8,        1,   599040, 0xc6a2c0dd
+0,          9,          9,        1,   599040, 0x438cc40e
+0,         10,         10,        1,   599040, 0xb666a438
+0,         11,         11,        1,   599040, 0x114580e4
+0,         12,         12,        1,   599040, 0xb75c41dc
+0,         13,         13,        1,   599040, 0x52e1e32f
+0,         14,         14,        1,   599040, 0x22835865
+0,         15,         15,        1,   599040, 0xfb0e0003
+0,         16,         16,        1,   599040, 0xebcb1ef9
+0,         17,         17,        1,   599040, 0xd6939619
+0,         18,         18,        1,   599040, 0xe22afdd8
+0,         19,         19,        1,   599040, 0xff4a248f
+0,         20,         20,        1,   599040, 0x9fc3878e
+0,         21,         21,        1,   599040, 0xce2f6499
+0,         22,         22,        1,   599040, 0x04aa9986
+0,         23,         23,        1,   599040, 0x68ba9838
+0,         24,         24,        1,   599040, 0x62e950a9
+0,         25,         25,        1,   599040, 0x5161526d
+0,         26,         26,        1,   599040, 0xcdde709e
+0,         27,         27,        1,   599040, 0x8c48ded1
+0,         28,         28,        1,   599040, 0x3451ecbb
+0,         29,         29,        1,   599040, 0xfc5a5fca
+0,         30,         30,        1,   599040, 0x7c0090fe
+0,         31,         31,        1,   599040, 0xbc4eb1de
+0,         32,         32,        1,   599040, 0x5350cf4f
+0,         33,         33,        1,   599040, 0x175152d6
+0,         34,         34,        1,   599040, 0xcf65acea
+0,         35,         35,        1,   599040, 0x099a7298
+0,         36,         36,        1,   599040, 0x31b7a2a2
+0,         37,         37,        1,   599040, 0xd6a71415
+0,         38,         38,        1,   599040, 0xe68880e7
+0,         39,         39,        1,   599040, 0x0c7d0373
+0,         40,         40,        1,   599040, 0xfb56ac78
+0,         41,         41,        1,   599040, 0x1177b0dd
+0,         42,         42,        1,   599040, 0x1393026f
+0,         43,         43,        1,   599040, 0xc6346b58
+0,         44,         44,        1,   599040, 0x2949cd11
+0,         45,         45,        1,   599040, 0xff867f22
+0,         46,         46,        1,   599040, 0xef196e4d
+0,         47,         47,        1,   599040, 0x17a2332c
+0,         48,         48,        1,   599040, 0x45d59fbc
+0,         49,         49,        1,   599040, 0x5f51575c
+0,         50,         50,        1,   599040, 0x6049a451
+0,         51,         51,        1,   599040, 0x4d6086ac
+0,         52,         52,        1,   599040, 0xd709596b
+0,         53,         53,        1,   599040, 0xacdbc22f
+0,         54,         54,        1,   599040, 0x45c11bb5
+0,         55,         55,        1,   599040, 0x608a7c7e
+0,         56,         56,        1,   599040, 0x242a67c9
+0,         57,         57,        1,   599040, 0x2d186d8a
+0,         58,         58,        1,   599040, 0x07ed9fd5
+0,         59,         59,        1,   599040, 0xaee9a49b
+0,         60,         60,        1,   599040, 0xaeb2b2a2
+0,         61,         61,        1,   599040, 0x4ca2d84b
+0,         62,         62,        1,   599040, 0x4254b5f6
+0,         63,         63,        1,   599040, 0x105c7a25
+0,         64,         64,        1,   599040, 0x87b51bce
diff --git a/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3 b/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3
new file mode 100644
index 0000000..482e56f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3
@@ -0,0 +1,66 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xc3e98658
+0,          1,          1,        1,   599040, 0x621fa0b7
+0,          2,          2,        1,   599040, 0x53b2e637
+0,          3,          3,        1,   599040, 0x1db118c2
+0,          4,          4,        1,   599040, 0xa25003ba
+0,          5,          5,        1,   599040, 0x51de524b
+0,          6,          6,        1,   599040, 0x5f01f648
+0,          7,          7,        1,   599040, 0x43d8c9cb
+0,          8,          8,        1,   599040, 0xf7f6c7f6
+0,          9,          9,        1,   599040, 0xb08885ec
+0,         10,         10,        1,   599040, 0x1e6e91a7
+0,         11,         11,        1,   599040, 0x18549abd
+0,         12,         12,        1,   599040, 0xef523cbc
+0,         13,         13,        1,   599040, 0x87985e99
+0,         14,         14,        1,   599040, 0x37521482
+0,         15,         15,        1,   599040, 0xe9fbc0ce
+0,         16,         16,        1,   599040, 0x20bab233
+0,         17,         17,        1,   599040, 0xbe3525e6
+0,         18,         18,        1,   599040, 0xace46e50
+0,         19,         19,        1,   599040, 0xf709b3a9
+0,         20,         20,        1,   599040, 0xf2690bc8
+0,         21,         21,        1,   599040, 0x7eacdec3
+0,         22,         22,        1,   599040, 0xaed66c65
+0,         23,         23,        1,   599040, 0x066b2fa6
+0,         24,         24,        1,   599040, 0x5dc050bd
+0,         25,         25,        1,   599040, 0x170e7de1
+0,         26,         26,        1,   599040, 0x2ccd7b16
+0,         27,         27,        1,   599040, 0x4f7bc972
+0,         28,         28,        1,   599040, 0x72d7f274
+0,         29,         29,        1,   599040, 0x44d2396e
+0,         30,         30,        1,   599040, 0xe4dc9b54
+0,         31,         31,        1,   599040, 0xfacba54d
+0,         32,         32,        1,   599040, 0x7b86141e
+0,         33,         33,        1,   599040, 0x65564792
+0,         34,         34,        1,   599040, 0xf90c7f54
+0,         35,         35,        1,   599040, 0x00ce2f3c
+0,         36,         36,        1,   599040, 0xe6b185f2
+0,         37,         37,        1,   599040, 0x513942f1
+0,         38,         38,        1,   599040, 0x7c27b03a
+0,         39,         39,        1,   599040, 0xa201fea3
+0,         40,         40,        1,   599040, 0x5023fd92
+0,         41,         41,        1,   599040, 0xe05ba218
+0,         42,         42,        1,   599040, 0x84b61765
+0,         43,         43,        1,   599040, 0xfa6c8f65
+0,         44,         44,        1,   599040, 0xede8ef78
+0,         45,         45,        1,   599040, 0xcd2763f2
+0,         46,         46,        1,   599040, 0xb83e3bc6
+0,         47,         47,        1,   599040, 0x99fb3a3e
+0,         48,         48,        1,   599040, 0x3dd1e5ac
+0,         49,         49,        1,   599040, 0x776d7464
+0,         50,         50,        1,   599040, 0xaea89891
+0,         51,         51,        1,   599040, 0xfc0f1ec9
+0,         52,         52,        1,   599040, 0x2621f36f
+0,         53,         53,        1,   599040, 0x41101bbc
+0,         54,         54,        1,   599040, 0x7a5d4d0e
+0,         55,         55,        1,   599040, 0xc04fb148
+0,         56,         56,        1,   599040, 0x889d8186
+0,         57,         57,        1,   599040, 0x26f091bf
+0,         58,         58,        1,   599040, 0xe6644a2d
+0,         59,         59,        1,   599040, 0xd48efb7f
+0,         60,         60,        1,   599040, 0xe25204e3
+0,         61,         61,        1,   599040, 0x928f2efd
+0,         62,         62,        1,   599040, 0x535a4f2d
+0,         63,         63,        1,   599040, 0x2672ad63
+0,         64,         64,        1,   599040, 0x194f1463
diff --git a/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9 b/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9
new file mode 100644
index 0000000..384f81f
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9
@@ -0,0 +1,66 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0xf3038515
+0,          1,          1,        1,   599040, 0xb1bc9386
+0,          2,          2,        1,   599040, 0xa069e86f
+0,          3,          3,        1,   599040, 0xdf7c4cb7
+0,          4,          4,        1,   599040, 0xefaa2ac5
+0,          5,          5,        1,   599040, 0x81c67c18
+0,          6,          6,        1,   599040, 0xeb1a0669
+0,          7,          7,        1,   599040, 0xbab3c0b8
+0,          8,          8,        1,   599040, 0x82b99936
+0,          9,          9,        1,   599040, 0x027a90d1
+0,         10,         10,        1,   599040, 0x5d6d7489
+0,         11,         11,        1,   599040, 0xeaaf6d39
+0,         12,         12,        1,   599040, 0x7788f8fa
+0,         13,         13,        1,   599040, 0x654393e8
+0,         14,         14,        1,   599040, 0xc6c2237c
+0,         15,         15,        1,   599040, 0x8b16d890
+0,         16,         16,        1,   599040, 0x2c36eed0
+0,         17,         17,        1,   599040, 0x02792aa8
+0,         18,         18,        1,   599040, 0xf4088e47
+0,         19,         19,        1,   599040, 0xea9796ad
+0,         20,         20,        1,   599040, 0xa4aecc01
+0,         21,         21,        1,   599040, 0x2ec8c1c4
+0,         22,         22,        1,   599040, 0xcfa87d49
+0,         23,         23,        1,   599040, 0x012b62f1
+0,         24,         24,        1,   599040, 0xd8b72ae0
+0,         25,         25,        1,   599040, 0xe0ca1977
+0,         26,         26,        1,   599040, 0x3f048981
+0,         27,         27,        1,   599040, 0xe416a928
+0,         28,         28,        1,   599040, 0xdfef9086
+0,         29,         29,        1,   599040, 0xd810cd6a
+0,         30,         30,        1,   599040, 0x11fab789
+0,         31,         31,        1,   599040, 0x90a890d5
+0,         32,         32,        1,   599040, 0x0dabef8d
+0,         33,         33,        1,   599040, 0x7a32557d
+0,         34,         34,        1,   599040, 0xc3427914
+0,         35,         35,        1,   599040, 0x65266a45
+0,         36,         36,        1,   599040, 0x8b5e9213
+0,         37,         37,        1,   599040, 0x4e2e2b0a
+0,         38,         38,        1,   599040, 0xaebdb406
+0,         39,         39,        1,   599040, 0xca35eadb
+0,         40,         40,        1,   599040, 0xb711adc7
+0,         41,         41,        1,   599040, 0x594d28b9
+0,         42,         42,        1,   599040, 0x27fec3c9
+0,         43,         43,        1,   599040, 0x35fe73ce
+0,         44,         44,        1,   599040, 0x3069c845
+0,         45,         45,        1,   599040, 0x2df2a12d
+0,         46,         46,        1,   599040, 0x96d42f5c
+0,         47,         47,        1,   599040, 0x95d9319b
+0,         48,         48,        1,   599040, 0x4f8c92aa
+0,         49,         49,        1,   599040, 0x29620b31
+0,         50,         50,        1,   599040, 0x3d1441f7
+0,         51,         51,        1,   599040, 0x7040914d
+0,         52,         52,        1,   599040, 0x95a73274
+0,         53,         53,        1,   599040, 0xda51c6c7
+0,         54,         54,        1,   599040, 0x41592676
+0,         55,         55,        1,   599040, 0xf21c682b
+0,         56,         56,        1,   599040, 0x5d6b65cf
+0,         57,         57,        1,   599040, 0x13fc6e8e
+0,         58,         58,        1,   599040, 0xe05ec001
+0,         59,         59,        1,   599040, 0x06113d89
+0,         60,         60,        1,   599040, 0x1d74bd0d
+0,         61,         61,        1,   599040, 0x757ffab3
+0,         62,         62,        1,   599040, 0x0599c7fb
+0,         63,         63,        1,   599040, 0x8aaa91ed
+0,         64,         64,        1,   599040, 0x79582f08
diff --git a/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5 b/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5
new file mode 100644
index 0000000..da5cfa1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x479fa7ca
+0,          1,          1,        1,   149760, 0x761fb3a3
+0,          2,          2,        1,   149760, 0xa0f4cd97
+0,          3,          3,        1,   149760, 0x22a0c92b
+0,          4,          4,        1,   149760, 0xdedc8cb2
+0,          5,          5,        1,   149760, 0x38da8674
+0,          6,          6,        1,   149760, 0xe5d77e68
+0,          7,          7,        1,   149760, 0x31cc6196
+0,          8,          8,        1,   149760, 0xdb70f4d3
+0,          9,          9,        1,   149760, 0x966b6f89
+0,         10,         10,        1,   149760, 0x2297ff66
+0,         11,         11,        1,   149760, 0x2a2fa4e7
+0,         12,         12,        1,   149760, 0x217442b7
+0,         13,         13,        1,   149760, 0x5341ff7f
+0,         14,         14,        1,   149760, 0xb413af37
+0,         15,         15,        1,   149760, 0x61c86ce5
+0,         16,         16,        1,   149760, 0x6b1a0c63
+0,         17,         17,        1,   149760, 0x4596d2e5
+0,         18,         18,        1,   149760, 0xafc0abbd
+0,         19,         19,        1,   149760, 0xb9197a81
+0,         20,         20,        1,   149760, 0xf67d43f3
+0,         21,         21,        1,   149760, 0xe7ef11f2
+0,         22,         22,        1,   149760, 0x89180592
+0,         23,         23,        1,   149760, 0xf6900816
+0,         24,         24,        1,   149760, 0x7cb2f3c0
+0,         25,         25,        1,   149760, 0x71c269f5
+0,         26,         26,        1,   149760, 0x19720666
+0,         27,         27,        1,   149760, 0x5794f402
+0,         28,         28,        1,   149760, 0xe08bf8d2
+0,         29,         29,        1,   149760, 0x11638859
+0,         30,         30,        1,   149760, 0x5024fddc
+0,         31,         31,        1,   149760, 0x8b3d4a37
+0,         32,         32,        1,   149760, 0x5f727144
+0,         33,         33,        1,   149760, 0xb6cf2d76
+0,         34,         34,        1,   149760, 0xf528b070
+0,         35,         35,        1,   149760, 0x3e95f116
+0,         36,         36,        1,   149760, 0x1db5f92a
+0,         37,         37,        1,   149760, 0xf8331667
+0,         38,         38,        1,   149760, 0x57ca4161
+0,         39,         39,        1,   149760, 0x7add32bd
+0,         40,         40,        1,   149760, 0x4b84af44
+0,         41,         41,        1,   149760, 0xf3e1eeaf
+0,         42,         42,        1,   149760, 0x0d602ea8
+0,         43,         43,        1,   149760, 0x420bfdf8
+0,         44,         44,        1,   149760, 0x6e2eb72f
+0,         45,         45,        1,   149760, 0x0450e4ba
+0,         46,         46,        1,   149760, 0xbfa60971
+0,         47,         47,        1,   149760, 0x89791529
+0,         48,         48,        1,   149760, 0x4e32e37b
+0,         49,         49,        1,   149760, 0x273f0927
+0,         50,         50,        1,   149760, 0x0373f961
+0,         51,         51,        1,   149760, 0x5f105bd2
+0,         52,         52,        1,   149760, 0x6b1b290a
+0,         53,         53,        1,   149760, 0xeaad4ccb
+0,         54,         54,        1,   149760, 0xeb21c2e6
+0,         55,         55,        1,   149760, 0x342ff483
+0,         56,         56,        1,   149760, 0x0ac70398
+0,         57,         57,        1,   149760, 0x5366fd7c
+0,         58,         58,        1,   149760, 0xc05249b6
+0,         59,         59,        1,   149760, 0x32279e70
diff --git a/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4 b/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4
new file mode 100644
index 0000000..c03111c
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4
@@ -0,0 +1,61 @@
+#tb 0: 1/25
+0,          0,          0,        1,   599040, 0x4b489a60
+0,          1,          1,        1,   599040, 0x80369c9a
+0,          2,          2,        1,   599040, 0x33189b1a
+0,          3,          3,        1,   599040, 0x01d73abb
+0,          4,          4,        1,   599040, 0xd5de0ab7
+0,          5,          5,        1,   599040, 0xf7b9f1c3
+0,          6,          6,        1,   599040, 0xe72b6446
+0,          7,          7,        1,   599040, 0xf78cc5d6
+0,          8,          8,        1,   599040, 0x9c6d33a2
+0,          9,          9,        1,   599040, 0xacb6cb08
+0,         10,         10,        1,   599040, 0x2a215019
+0,         11,         11,        1,   599040, 0xcd89d5be
+0,         12,         12,        1,   599040, 0x60403ebb
+0,         13,         13,        1,   599040, 0xc5c62e88
+0,         14,         14,        1,   599040, 0x93403d23
+0,         15,         15,        1,   599040, 0x6b86071d
+0,         16,         16,        1,   599040, 0xfaaad32f
+0,         17,         17,        1,   599040, 0x68651db5
+0,         18,         18,        1,   599040, 0xfbedeba6
+0,         19,         19,        1,   599040, 0x7fa3a0c0
+0,         20,         20,        1,   599040, 0x76b34545
+0,         21,         21,        1,   599040, 0x34e4c1cd
+0,         22,         22,        1,   599040, 0xfad3eda9
+0,         23,         23,        1,   599040, 0xf4324901
+0,         24,         24,        1,   599040, 0x991b4fde
+0,         25,         25,        1,   599040, 0xd9d7823d
+0,         26,         26,        1,   599040, 0xd8a80ca5
+0,         27,         27,        1,   599040, 0x19ae0251
+0,         28,         28,        1,   599040, 0xfa68cda7
+0,         29,         29,        1,   599040, 0xb9c72f07
+0,         30,         30,        1,   599040, 0xf1df5f78
+0,         31,         31,        1,   599040, 0xda75192b
+0,         32,         32,        1,   599040, 0x1102b6e6
+0,         33,         33,        1,   599040, 0x259ec490
+0,         34,         34,        1,   599040, 0xee1dabe5
+0,         35,         35,        1,   599040, 0xf6bf5454
+0,         36,         36,        1,   599040, 0x058061be
+0,         37,         37,        1,   599040, 0x2f9aebeb
+0,         38,         38,        1,   599040, 0x169c0bff
+0,         39,         39,        1,   599040, 0xeffb5a9f
+0,         40,         40,        1,   599040, 0xb3bbebac
+0,         41,         41,        1,   599040, 0x174af746
+0,         42,         42,        1,   599040, 0x8359db57
+0,         43,         43,        1,   599040, 0xdd7693ad
+0,         44,         44,        1,   599040, 0x05aebad4
+0,         45,         45,        1,   599040, 0xc34fd8bc
+0,         46,         46,        1,   599040, 0x2798f32e
+0,         47,         47,        1,   599040, 0x319b9b8c
+0,         48,         48,        1,   599040, 0xa28d783f
+0,         49,         49,        1,   599040, 0x5c79026f
+0,         50,         50,        1,   599040, 0xd4ae9b08
+0,         51,         51,        1,   599040, 0x79b19064
+0,         52,         52,        1,   599040, 0xe773bd75
+0,         53,         53,        1,   599040, 0xfbeda52a
+0,         54,         54,        1,   599040, 0x2ed916e6
+0,         55,         55,        1,   599040, 0xd3243fe7
+0,         56,         56,        1,   599040, 0xfdbc20e8
+0,         57,         57,        1,   599040, 0x80983226
+0,         58,         58,        1,   599040, 0x51c66b23
+0,         59,         59,        1,   599040, 0x30816b80
diff --git a/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2 b/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2
new file mode 100644
index 0000000..63c9722
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0xfc052e85
+0,          1,          1,        1,  3110400, 0xfb49bf20
+0,          2,          2,        1,  3110400, 0x549eef2b
+0,          3,          3,        1,  3110400, 0xc3857801
+0,          4,          4,        1,  3110400, 0xb27d6aea
+0,          5,          5,        1,  3110400, 0xa52e1d58
+0,          6,          6,        1,  3110400, 0x02d348e6
+0,          7,          7,        1,  3110400, 0x45a9c47c
+0,          8,          8,        1,  3110400, 0xc308e886
+0,          9,          9,        1,  3110400, 0x43cd6ed6
+0,         10,         10,        1,  3110400, 0x29a054ce
+0,         11,         11,        1,  3110400, 0x76fbd08e
+0,         12,         12,        1,  3110400, 0x8638d5e2
+0,         13,         13,        1,  3110400, 0xfb4b7823
+0,         14,         14,        1,  3110400, 0x66185e15
+0,         15,         15,        1,  3110400, 0x82eaea0a
+0,         16,         16,        1,  3110400, 0x5895f1c6
+0,         17,         17,        1,  3110400, 0x0a28a1c7
+0,         18,         18,        1,  3110400, 0x37f2ecc8
+0,         19,         19,        1,  3110400, 0x0ad8b6c1
+0,         20,         20,        1,  3110400, 0x90300dcb
+0,         21,         21,        1,  3110400, 0x9731112d
+0,         22,         22,        1,  3110400, 0x5078ba88
+0,         23,         23,        1,  3110400, 0xdcfbacae
+0,         24,         24,        1,  3110400, 0x40769123
+0,         25,         25,        1,  3110400, 0xa09f4d29
+0,         26,         26,        1,  3110400, 0xa3749feb
+0,         27,         27,        1,  3110400, 0xb04c36ae
+0,         28,         28,        1,  3110400, 0x4d30c177
+0,         29,         29,        1,  3110400, 0xe247070a
+0,         30,         30,        1,  3110400, 0x84c669d5
+0,         31,         31,        1,  3110400, 0x3e0529e6
+0,         32,         32,        1,  3110400, 0xd0d58b7a
+0,         33,         33,        1,  3110400, 0x05de0ffa
+0,         34,         34,        1,  3110400, 0x7d10a27f
+0,         35,         35,        1,  3110400, 0x87dd43fe
+0,         36,         36,        1,  3110400, 0xc6f39e98
+0,         37,         37,        1,  3110400, 0x9bf5a18b
+0,         38,         38,        1,  3110400, 0x4880f4e6
+0,         39,         39,        1,  3110400, 0xbba7a2fd
+0,         40,         40,        1,  3110400, 0x82fe2a14
+0,         41,         41,        1,  3110400, 0x7e701e1c
+0,         42,         42,        1,  3110400, 0x23cdbc0c
+0,         43,         43,        1,  3110400, 0xf15977e6
+0,         44,         44,        1,  3110400, 0x50df6fe2
+0,         45,         45,        1,  3110400, 0x8913ddde
+0,         46,         46,        1,  3110400, 0x633c8c0e
+0,         47,         47,        1,  3110400, 0xea604347
+0,         48,         48,        1,  3110400, 0xa5049365
+0,         49,         49,        1,  3110400, 0x35da77a8
+0,         50,         50,        1,  3110400, 0xcfa4af57
+0,         51,         51,        1,  3110400, 0x5a3bfe64
+0,         52,         52,        1,  3110400, 0x91f9ee34
+0,         53,         53,        1,  3110400, 0x21b0df73
+0,         54,         54,        1,  3110400, 0x7807baf2
+0,         55,         55,        1,  3110400, 0x96dbaf03
+0,         56,         56,        1,  3110400, 0xb8d29f57
+0,         57,         57,        1,  3110400, 0x1a04f732
+0,         58,         58,        1,  3110400, 0x54a34b35
+0,         59,         59,        1,  3110400, 0x4850a07a
+0,         60,         60,        1,  3110400, 0x7010be29
+0,         61,         61,        1,  3110400, 0x7178d2e7
+0,         62,         62,        1,  3110400, 0x17483898
+0,         63,         63,        1,  3110400, 0x4c55872a
+0,         64,         64,        1,  3110400, 0xe67b0f06
+0,         65,         65,        1,  3110400, 0x958789cf
+0,         66,         66,        1,  3110400, 0x5cd6ba06
+0,         67,         67,        1,  3110400, 0xb7852fe2
+0,         68,         68,        1,  3110400, 0x8b67bd9f
+0,         69,         69,        1,  3110400, 0x9555c0ff
+0,         70,         70,        1,  3110400, 0x6b99aab7
+0,         71,         71,        1,  3110400, 0xcab904b7
+0,         72,         72,        1,  3110400, 0xeb915c25
+0,         73,         73,        1,  3110400, 0xd3066bd8
+0,         74,         74,        1,  3110400, 0xa2d45cb5
+0,         75,         75,        1,  3110400, 0x011db978
+0,         76,         76,        1,  3110400, 0xf35b9f2c
+0,         77,         77,        1,  3110400, 0x6afd3bde
+0,         78,         78,        1,  3110400, 0xa1ad77b7
+0,         79,         79,        1,  3110400, 0x8b4d3823
+0,         80,         80,        1,  3110400, 0xd806be79
+0,         81,         81,        1,  3110400, 0x29dcff87
+0,         82,         82,        1,  3110400, 0x202fb0f7
+0,         83,         83,        1,  3110400, 0xacfc7d1d
+0,         84,         84,        1,  3110400, 0xf04bdcb8
+0,         85,         85,        1,  3110400, 0x89cef288
+0,         86,         86,        1,  3110400, 0x657315e2
+0,         87,         87,        1,  3110400, 0x1615cb5f
+0,         88,         88,        1,  3110400, 0xc6986395
+0,         89,         89,        1,  3110400, 0x6b77258e
+0,         90,         90,        1,  3110400, 0xcd9975ae
+0,         91,         91,        1,  3110400, 0x5044fd0f
+0,         92,         92,        1,  3110400, 0x20dd1132
+0,         93,         93,        1,  3110400, 0xdb5a0b84
+0,         94,         94,        1,  3110400, 0xf40d29ae
+0,         95,         95,        1,  3110400, 0xe88bffed
+0,         96,         96,        1,  3110400, 0x3e50146a
+0,         97,         97,        1,  3110400, 0xaacd9bfa
+0,         98,         98,        1,  3110400, 0x270b2c2a
+0,         99,         99,        1,  3110400, 0xc727f760
diff --git a/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1 b/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1
new file mode 100644
index 0000000..9c37121
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1
@@ -0,0 +1,101 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3110400, 0x3471f473
+0,          1,          1,        1,  3110400, 0xb371a3e8
+0,          2,          2,        1,  3110400, 0x6d83c623
+0,          3,          3,        1,  3110400, 0x62d68b96
+0,          4,          4,        1,  3110400, 0xa8ed6ea9
+0,          5,          5,        1,  3110400, 0xcabe52be
+0,          6,          6,        1,  3110400, 0xbbb23578
+0,          7,          7,        1,  3110400, 0xb1609c77
+0,          8,          8,        1,  3110400, 0x61e7c2a7
+0,          9,          9,        1,  3110400, 0x6d8b34ad
+0,         10,         10,        1,  3110400, 0xde0dfa96
+0,         11,         11,        1,  3110400, 0x48c2b0b0
+0,         12,         12,        1,  3110400, 0x647b6f90
+0,         13,         13,        1,  3110400, 0xd37f2dda
+0,         14,         14,        1,  3110400, 0x1b0dd122
+0,         15,         15,        1,  3110400, 0x0b050786
+0,         16,         16,        1,  3110400, 0xcd9ce7e5
+0,         17,         17,        1,  3110400, 0xb92a4ee4
+0,         18,         18,        1,  3110400, 0x4fa4d97c
+0,         19,         19,        1,  3110400, 0x109777eb
+0,         20,         20,        1,  3110400, 0xc3d2236a
+0,         21,         21,        1,  3110400, 0x1cd12d07
+0,         22,         22,        1,  3110400, 0xdd1ef75d
+0,         23,         23,        1,  3110400, 0xd00c0906
+0,         24,         24,        1,  3110400, 0x8de79207
+0,         25,         25,        1,  3110400, 0x18017e1e
+0,         26,         26,        1,  3110400, 0x4329f68a
+0,         27,         27,        1,  3110400, 0x6a402bae
+0,         28,         28,        1,  3110400, 0x90eb1a20
+0,         29,         29,        1,  3110400, 0xe3474876
+0,         30,         30,        1,  3110400, 0xd652e216
+0,         31,         31,        1,  3110400, 0xeb458ebb
+0,         32,         32,        1,  3110400, 0xc5aff075
+0,         33,         33,        1,  3110400, 0xcb4d72e7
+0,         34,         34,        1,  3110400, 0x5504d9c5
+0,         35,         35,        1,  3110400, 0xcd0147b4
+0,         36,         36,        1,  3110400, 0xe2f0001e
+0,         37,         37,        1,  3110400, 0xa2199fe5
+0,         38,         38,        1,  3110400, 0x2f269683
+0,         39,         39,        1,  3110400, 0x7cf11244
+0,         40,         40,        1,  3110400, 0xf39cb39d
+0,         41,         41,        1,  3110400, 0x0e195a06
+0,         42,         42,        1,  3110400, 0x195e31e3
+0,         43,         43,        1,  3110400, 0xc43cd272
+0,         44,         44,        1,  3110400, 0x9dc1c4ea
+0,         45,         45,        1,  3110400, 0x846cd55f
+0,         46,         46,        1,  3110400, 0xe9468052
+0,         47,         47,        1,  3110400, 0xc5bb38ff
+0,         48,         48,        1,  3110400, 0xd1886697
+0,         49,         49,        1,  3110400, 0x23f2012b
+0,         50,         50,        1,  3110400, 0x669d63ff
+0,         51,         51,        1,  3110400, 0xced83804
+0,         52,         52,        1,  3110400, 0x005f5f3d
+0,         53,         53,        1,  3110400, 0x772efc80
+0,         54,         54,        1,  3110400, 0x94012838
+0,         55,         55,        1,  3110400, 0x99770054
+0,         56,         56,        1,  3110400, 0x8654c655
+0,         57,         57,        1,  3110400, 0xed3d19f4
+0,         58,         58,        1,  3110400, 0x8efc2172
+0,         59,         59,        1,  3110400, 0x9aaf930d
+0,         60,         60,        1,  3110400, 0xbe32f43e
+0,         61,         61,        1,  3110400, 0x6008f53e
+0,         62,         62,        1,  3110400, 0xb87897b9
+0,         63,         63,        1,  3110400, 0xe2406eb1
+0,         64,         64,        1,  3110400, 0xbdfa067b
+0,         65,         65,        1,  3110400, 0x82a16dbd
+0,         66,         66,        1,  3110400, 0x909aa5f0
+0,         67,         67,        1,  3110400, 0xc63836b5
+0,         68,         68,        1,  3110400, 0xaf7ad199
+0,         69,         69,        1,  3110400, 0xfa010078
+0,         70,         70,        1,  3110400, 0x00c0c24e
+0,         71,         71,        1,  3110400, 0xbda7cc4e
+0,         72,         72,        1,  3110400, 0xda97f9d5
+0,         73,         73,        1,  3110400, 0xd359e94a
+0,         74,         74,        1,  3110400, 0xcd48c131
+0,         75,         75,        1,  3110400, 0xb52ca032
+0,         76,         76,        1,  3110400, 0x55a69650
+0,         77,         77,        1,  3110400, 0x7241c1a9
+0,         78,         78,        1,  3110400, 0xf06c5744
+0,         79,         79,        1,  3110400, 0xe1befd73
+0,         80,         80,        1,  3110400, 0xe8ffea92
+0,         81,         81,        1,  3110400, 0xd76e40b6
+0,         82,         82,        1,  3110400, 0xbf5f5b4c
+0,         83,         83,        1,  3110400, 0x0eb8d128
+0,         84,         84,        1,  3110400, 0x453dd680
+0,         85,         85,        1,  3110400, 0x7114fada
+0,         86,         86,        1,  3110400, 0xa3b4e7a8
+0,         87,         87,        1,  3110400, 0xbca356f0
+0,         88,         88,        1,  3110400, 0x80a83fa3
+0,         89,         89,        1,  3110400, 0x713a33d4
+0,         90,         90,        1,  3110400, 0x4fda8aea
+0,         91,         91,        1,  3110400, 0x31ed1a88
+0,         92,         92,        1,  3110400, 0x736312a0
+0,         93,         93,        1,  3110400, 0x60aff0c5
+0,         94,         94,        1,  3110400, 0xee66bd76
+0,         95,         95,        1,  3110400, 0xe8f9a352
+0,         96,         96,        1,  3110400, 0xb51520de
+0,         97,         97,        1,  3110400, 0xd0542466
+0,         98,         98,        1,  3110400, 0x92c2f3e1
+0,         99,         99,        1,  3110400, 0xbbe1839a
diff --git a/tests/ref/fate/hevc-conformance-TMVP_A_MS_2 b/tests/ref/fate/hevc-conformance-TMVP_A_MS_2
new file mode 100644
index 0000000..a626af8
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TMVP_A_MS_2
@@ -0,0 +1,18 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xdb5e3b56
+0,          1,          1,        1,   149760, 0x496f2a41
+0,          2,          2,        1,   149760, 0x0690ee0a
+0,          3,          3,        1,   149760, 0x5648fb4e
+0,          4,          4,        1,   149760, 0xd58bbe51
+0,          5,          5,        1,   149760, 0x647c4520
+0,          6,          6,        1,   149760, 0x0e361335
+0,          7,          7,        1,   149760, 0xd1a4289b
+0,          8,          8,        1,   149760, 0x04d29f74
+0,          9,          9,        1,   149760, 0x3bbffc55
+0,         10,         10,        1,   149760, 0xefe30f2b
+0,         11,         11,        1,   149760, 0x3a336f52
+0,         12,         12,        1,   149760, 0x0dffed51
+0,         13,         13,        1,   149760, 0x5a9db757
+0,         14,         14,        1,   149760, 0x5e7313c5
+0,         15,         15,        1,   149760, 0xbffb3a0e
+0,         16,         16,        1,   149760, 0x073966e9
diff --git a/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5 b/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5
new file mode 100644
index 0000000..84d4219
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5
@@ -0,0 +1,74 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xcfffa013
+0,          1,          1,        1,   149760, 0x5166146a
+0,          2,          2,        1,   149760, 0xc3cc318e
+0,          3,          3,        1,   149760, 0xcedf65a0
+0,          4,          4,        1,   149760, 0x10c97bd4
+0,          5,          5,        1,   149760, 0xd9d5c4ab
+0,          6,          6,        1,   149760, 0x5112e11d
+0,          7,          7,        1,   149760, 0xde3803d6
+0,          8,          8,        1,   149760, 0x82c62409
+0,          9,          9,        1,   149760, 0x69a587f2
+0,         10,         10,        1,   149760, 0x90e2ac16
+0,         11,         11,        1,   149760, 0xdc2ed2ba
+0,         12,         12,        1,   149760, 0xcabec51f
+0,         13,         13,        1,   149760, 0x915de948
+0,         14,         14,        1,   149760, 0xd824e422
+0,         15,         15,        1,   149760, 0x10f91769
+0,         16,         16,        1,   149760, 0xf8ea1f0a
+0,         17,         17,        1,   149760, 0x88306494
+0,         18,         18,        1,   149760, 0x4b667403
+0,         19,         19,        1,   149760, 0x190b939f
+0,         20,         20,        1,   149760, 0xe754929d
+0,         21,         21,        1,   149760, 0xdd1eb9b5
+0,         22,         22,        1,   149760, 0x5ef1c64b
+0,         23,         23,        1,   149760, 0xab92e9f9
+0,         24,         24,        1,   149760, 0x873fec38
+0,         25,         25,        1,   149760, 0x1f0ca11f
+0,         26,         26,        1,   149760, 0xa2f591ca
+0,         27,         27,        1,   149760, 0x2713a994
+0,         28,         28,        1,   149760, 0xfbdba1f9
+0,         29,         29,        1,   149760, 0x3742ed2e
+0,         30,         30,        1,   149760, 0xf43fe43c
+0,         31,         31,        1,   149760, 0xa84ff250
+0,         32,         32,        1,   149760, 0xd4437e12
+0,         33,         33,        1,   149760, 0xcf08c736
+0,         34,         34,        1,   149760, 0x0cedd0d6
+0,         35,         35,        1,   149760, 0xc317e9bc
+0,         36,         36,        1,   149760, 0x0dcbd636
+0,         37,         37,        1,   149760, 0x4e6501b0
+0,         38,         38,        1,   149760, 0x5f9c02bb
+0,         39,         39,        1,   149760, 0x43052939
+0,         40,         40,        1,   149760, 0x8ec12318
+0,         41,         41,        1,   149760, 0xc51577f3
+0,         42,         42,        1,   149760, 0xbda1775b
+0,         43,         43,        1,   149760, 0x62b7b2a2
+0,         44,         44,        1,   149760, 0x5dd68203
+0,         45,         45,        1,   149760, 0xe004b4bf
+0,         46,         46,        1,   149760, 0x1469769f
+0,         47,         47,        1,   149760, 0x96f57e0a
+0,         48,         48,        1,   149760, 0x75e58819
+0,         49,         49,        1,   149760, 0xf826a158
+0,         50,         50,        1,   149760, 0xf789a3bd
+0,         51,         51,        1,   149760, 0x9d8fb09a
+0,         52,         52,        1,   149760, 0x1d33bbe5
+0,         53,         53,        1,   149760, 0x7e93e014
+0,         54,         54,        1,   149760, 0x04ade2e6
+0,         55,         55,        1,   149760, 0xb93a2c32
+0,         56,         56,        1,   149760, 0x5fa73dc3
+0,         57,         57,        1,   149760, 0xa70099ee
+0,         58,         58,        1,   149760, 0xcc5aaf3e
+0,         59,         59,        1,   149760, 0x4e83f938
+0,         60,         60,        1,   149760, 0x9faae668
+0,         61,         61,        1,   149760, 0x7a5cbf24
+0,         62,         62,        1,   149760, 0x4b23714c
+0,         63,         63,        1,   149760, 0x55d246ad
+0,         64,         64,        1,   149760, 0xd3378be9
+0,         65,         65,        1,   149760, 0xf5ef9731
+0,         66,         66,        1,   149760, 0xc4ba3ad7
+0,         67,         67,        1,   149760, 0xd9182d2c
+0,         68,         68,        1,   149760, 0x0ff5eaa5
+0,         69,         69,        1,   149760, 0xefe21a58
+0,         70,         70,        1,   149760, 0x4cad2a57
+0,         71,         71,        1,   149760, 0x24a35d1a
+0,         72,         72,        1,   149760, 0xeb1b6a6e
diff --git a/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4 b/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4
new file mode 100644
index 0000000..6ee24ac
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4
@@ -0,0 +1,74 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x88619f80
+0,          1,          1,        1,   149760, 0x550bdaf0
+0,          2,          2,        1,   149760, 0x99440a14
+0,          3,          3,        1,   149760, 0xcc2c2049
+0,          4,          4,        1,   149760, 0x46927368
+0,          5,          5,        1,   149760, 0x53cdb3fe
+0,          6,          6,        1,   149760, 0x654df025
+0,          7,          7,        1,   149760, 0x024d24bc
+0,          8,          8,        1,   149760, 0x409138c2
+0,          9,          9,        1,   149760, 0xfbb47c48
+0,         10,         10,        1,   149760, 0x18caa19d
+0,         11,         11,        1,   149760, 0x0f88c2e5
+0,         12,         12,        1,   149760, 0x1c16aa2d
+0,         13,         13,        1,   149760, 0x60bfcce8
+0,         14,         14,        1,   149760, 0x1c38e3d3
+0,         15,         15,        1,   149760, 0x0d5b044a
+0,         16,         16,        1,   149760, 0x93d21593
+0,         17,         17,        1,   149760, 0xdf283910
+0,         18,         18,        1,   149760, 0x03324c23
+0,         19,         19,        1,   149760, 0x3b175b7b
+0,         20,         20,        1,   149760, 0xb91b9a7e
+0,         21,         21,        1,   149760, 0x734fbbe7
+0,         22,         22,        1,   149760, 0xfc3fea48
+0,         23,         23,        1,   149760, 0x6609103e
+0,         24,         24,        1,   149760, 0x3f5916fa
+0,         25,         25,        1,   149760, 0x08e43f4d
+0,         26,         26,        1,   149760, 0xc84e5471
+0,         27,         27,        1,   149760, 0xbd4e5c8d
+0,         28,         28,        1,   149760, 0x4a4d3995
+0,         29,         29,        1,   149760, 0x662163c0
+0,         30,         30,        1,   149760, 0xda28671f
+0,         31,         31,        1,   149760, 0x19e1878e
+0,         32,         32,        1,   149760, 0x19807e67
+0,         33,         33,        1,   149760, 0xf7aea3b6
+0,         34,         34,        1,   149760, 0x53f482c9
+0,         35,         35,        1,   149760, 0x7184b3ae
+0,         36,         36,        1,   149760, 0xb425b53d
+0,         37,         37,        1,   149760, 0xfb7cce6e
+0,         38,         38,        1,   149760, 0x820bc1ef
+0,         39,         39,        1,   149760, 0xbb0de30a
+0,         40,         40,        1,   149760, 0xbdcb0af2
+0,         41,         41,        1,   149760, 0xf2404ff7
+0,         42,         42,        1,   149760, 0xd6636f0a
+0,         43,         43,        1,   149760, 0x0e908b06
+0,         44,         44,        1,   149760, 0x36a158f4
+0,         45,         45,        1,   149760, 0x178d5bbd
+0,         46,         46,        1,   149760, 0xba9a6d14
+0,         47,         47,        1,   149760, 0x89145886
+0,         48,         48,        1,   149760, 0x6ec26794
+0,         49,         49,        1,   149760, 0xf6ac7551
+0,         50,         50,        1,   149760, 0xc829c66f
+0,         51,         51,        1,   149760, 0x64d50d50
+0,         52,         52,        1,   149760, 0x215dd855
+0,         53,         53,        1,   149760, 0x8b2ffec3
+0,         54,         54,        1,   149760, 0x1a0b7bcd
+0,         55,         55,        1,   149760, 0x14a5ad0e
+0,         56,         56,        1,   149760, 0x88c34286
+0,         57,         57,        1,   149760, 0xe2706fa9
+0,         58,         58,        1,   149760, 0x8de2decf
+0,         59,         59,        1,   149760, 0x1b37e5d7
+0,         60,         60,        1,   149760, 0xaf8d175a
+0,         61,         61,        1,   149760, 0x0f4aec5f
+0,         62,         62,        1,   149760, 0x3818df10
+0,         63,         63,        1,   149760, 0xe791d309
+0,         64,         64,        1,   149760, 0x6ad9aa0d
+0,         65,         65,        1,   149760, 0x1e1ab8a1
+0,         66,         66,        1,   149760, 0xd0ef526a
+0,         67,         67,        1,   149760, 0x45da3cf1
+0,         68,         68,        1,   149760, 0x3cb4eee6
+0,         69,         69,        1,   149760, 0x3e816ebc
+0,         70,         70,        1,   149760, 0x29d45e93
+0,         71,         71,        1,   149760, 0x824b5bc2
+0,         72,         72,        1,   149760, 0x015e6fd2
diff --git a/tests/ref/fate/hevc-conformance-TSKIP_A_MS_2 b/tests/ref/fate/hevc-conformance-TSKIP_A_MS_2
new file mode 100644
index 0000000..1226e11
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-TSKIP_A_MS_2
@@ -0,0 +1,18 @@
+#tb 0: 1/25
+0,          0,          0,        1,  1382400, 0xaea37937
+0,          1,          1,        1,  1382400, 0x39d687d0
+0,          2,          2,        1,  1382400, 0x8ea04595
+0,          3,          3,        1,  1382400, 0x5d5a40d2
+0,          4,          4,        1,  1382400, 0x6915eb4e
+0,          5,          5,        1,  1382400, 0xe8bb612d
+0,          6,          6,        1,  1382400, 0xd331085a
+0,          7,          7,        1,  1382400, 0x2193bc30
+0,          8,          8,        1,  1382400, 0xaeb19418
+0,          9,          9,        1,  1382400, 0xb524eac3
+0,         10,         10,        1,  1382400, 0x141908a2
+0,         11,         11,        1,  1382400, 0x527ab6ac
+0,         12,         12,        1,  1382400, 0xe9a73d9f
+0,         13,         13,        1,  1382400, 0x2eb0aa14
+0,         14,         14,        1,  1382400, 0x6981af42
+0,         15,         15,        1,  1382400, 0xbb0bbd7a
+0,         16,         16,        1,  1382400, 0xf0779b81
diff --git a/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2
new file mode 100644
index 0000000..fe46c99
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,   299520, 0xa3f96d63
+0,          1,          1,        1,   299520, 0x5f788f3f
+0,          2,          2,        1,   299520, 0x41c7d0ae
+0,          3,          3,        1,   299520, 0x14a9175c
+0,          4,          4,        1,   299520, 0x5215ed5f
+0,          5,          5,        1,   299520, 0xffa5ab17
+0,          6,          6,        1,   299520, 0x7d179b2b
+0,          7,          7,        1,   299520, 0x87280332
+0,          8,          8,        1,   299520, 0xca5e278f
+0,          9,          9,        1,   299520, 0x89d59325
+0,         10,         10,        1,   299520, 0x6593cfa5
+0,         11,         11,        1,   299520, 0x216ce552
+0,         12,         12,        1,   299520, 0x4494f2ac
+0,         13,         13,        1,   299520, 0xc9aafeb4
+0,         14,         14,        1,   299520, 0xe93a43ab
+0,         15,         15,        1,   299520, 0x89bdba99
+0,         16,         16,        1,   299520, 0xdc529079
+0,         17,         17,        1,   299520, 0xfbc29de7
+0,         18,         18,        1,   299520, 0xa8c6c853
+0,         19,         19,        1,   299520, 0xd552dc1f
+0,         20,         20,        1,   299520, 0x60a7d5d9
+0,         21,         21,        1,   299520, 0x4b784987
+0,         22,         22,        1,   299520, 0xec9bd2a0
+0,         23,         23,        1,   299520, 0x71e1d437
+0,         24,         24,        1,   299520, 0x5776a225
+0,         25,         25,        1,   299520, 0x01598543
+0,         26,         26,        1,   299520, 0x8abb1f7b
+0,         27,         27,        1,   299520, 0xa3a0bb58
+0,         28,         28,        1,   299520, 0x4a718127
+0,         29,         29,        1,   299520, 0x6b1647bc
+0,         30,         30,        1,   299520, 0x7b653009
+0,         31,         31,        1,   299520, 0xca15d4be
+0,         32,         32,        1,   299520, 0xf8075689
+0,         33,         33,        1,   299520, 0x2717f2e6
+0,         34,         34,        1,   299520, 0x53ad6267
+0,         35,         35,        1,   299520, 0x29fedd49
+0,         36,         36,        1,   299520, 0x4e8aa5db
+0,         37,         37,        1,   299520, 0xca316c94
+0,         38,         38,        1,   299520, 0x8071fd57
+0,         39,         39,        1,   299520, 0xc9915cd3
+0,         40,         40,        1,   299520, 0xab335447
+0,         41,         41,        1,   299520, 0xf733a390
+0,         42,         42,        1,   299520, 0x1fa14afb
+0,         43,         43,        1,   299520, 0xe5d7ae71
+0,         44,         44,        1,   299520, 0xb48c2ee6
+0,         45,         45,        1,   299520, 0xe288ebcc
+0,         46,         46,        1,   299520, 0xa4000bdd
+0,         47,         47,        1,   299520, 0xf3fdee3a
diff --git a/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2
new file mode 100644
index 0000000..497c802
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xfbb3d914
+0,          1,          1,        1,   149760, 0xdccd707b
+0,          2,          2,        1,   149760, 0x32008963
+0,          3,          3,        1,   149760, 0x0fcdd808
+0,          4,          4,        1,   149760, 0x69f0e1a5
+0,          5,          5,        1,   149760, 0x1be36c09
+0,          6,          6,        1,   149760, 0x18a1588f
+0,          7,          7,        1,   149760, 0xdc46acd8
+0,          8,          8,        1,   149760, 0xec46760a
+0,          9,          9,        1,   149760, 0xe87fc7b5
+0,         10,         10,        1,   149760, 0x7c78d960
+0,         11,         11,        1,   149760, 0x73e2ea91
+0,         12,         12,        1,   149760, 0x9164db8c
+0,         13,         13,        1,   149760, 0x31a6124b
+0,         14,         14,        1,   149760, 0x8a143aed
+0,         15,         15,        1,   149760, 0x15a364f4
+0,         16,         16,        1,   149760, 0x93b8560e
+0,         17,         17,        1,   149760, 0xc2aa985c
+0,         18,         18,        1,   149760, 0xe83ca4da
+0,         19,         19,        1,   149760, 0x6c79cb07
+0,         20,         20,        1,   149760, 0x2c24c739
+0,         21,         21,        1,   149760, 0x6a60f769
+0,         22,         22,        1,   149760, 0x13f00ad1
+0,         23,         23,        1,   149760, 0x59dd330d
+0,         24,         24,        1,   149760, 0x8815348c
+0,         25,         25,        1,   149760, 0x88576cd4
+0,         26,         26,        1,   149760, 0xfa3d6b9c
+0,         27,         27,        1,   149760, 0x810c8145
+0,         28,         28,        1,   149760, 0xf2357fcc
+0,         29,         29,        1,   149760, 0xc885a093
+0,         30,         30,        1,   149760, 0x5939a048
+0,         31,         31,        1,   149760, 0x9f93a489
+0,         32,         32,        1,   149760, 0xc11a879e
+0,         33,         33,        1,   149760, 0x5221c04b
+0,         34,         34,        1,   149760, 0x7dcdca90
+0,         35,         35,        1,   149760, 0xfdd8df1e
+0,         36,         36,        1,   149760, 0x3a88c802
+0,         37,         37,        1,   149760, 0x50ff1081
+0,         38,         38,        1,   149760, 0x6388f458
+0,         39,         39,        1,   149760, 0x85623a2b
+0,         40,         40,        1,   149760, 0x1bfd34a4
+0,         41,         41,        1,   149760, 0xb6037b88
+0,         42,         42,        1,   149760, 0xd24e65c7
+0,         43,         43,        1,   149760, 0xd2bd8fac
+0,         44,         44,        1,   149760, 0x602f64d0
+0,         45,         45,        1,   149760, 0x59415d5e
+0,         46,         46,        1,   149760, 0x9faf5737
+0,         47,         47,        1,   149760, 0x66ce56a9
diff --git a/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2
new file mode 100644
index 0000000..d199d38
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,   299520, 0x66b3cef3
+0,          1,          1,        1,   299520, 0x99df880f
+0,          2,          2,        1,   299520, 0xb4a03801
+0,          3,          3,        1,   299520, 0x1510c9e2
+0,          4,          4,        1,   299520, 0x42fe77b1
+0,          5,          5,        1,   299520, 0x815e1727
+0,          6,          6,        1,   299520, 0x6dd002f4
+0,          7,          7,        1,   299520, 0x2650e944
+0,          8,          8,        1,   299520, 0x3268c1e9
+0,          9,          9,        1,   299520, 0xced41a5f
+0,         10,         10,        1,   299520, 0x91334b97
+0,         11,         11,        1,   299520, 0xc5bb7ff6
+0,         12,         12,        1,   299520, 0x26e27c35
+0,         13,         13,        1,   299520, 0x482da6cb
+0,         14,         14,        1,   299520, 0xfe742e8e
+0,         15,         15,        1,   299520, 0x3f395752
+0,         16,         16,        1,   299520, 0x189936e5
+0,         17,         17,        1,   299520, 0x56a58a07
+0,         18,         18,        1,   299520, 0x798d8de9
+0,         19,         19,        1,   299520, 0x5d8e947f
+0,         20,         20,        1,   299520, 0x65477654
+0,         21,         21,        1,   299520, 0x5012d167
+0,         22,         22,        1,   299520, 0xe889bb27
+0,         23,         23,        1,   299520, 0x4611c1e6
+0,         24,         24,        1,   299520, 0xb093402b
+0,         25,         25,        1,   299520, 0xddc065d8
+0,         26,         26,        1,   299520, 0x6986e1d9
+0,         27,         27,        1,   299520, 0x0e539004
+0,         28,         28,        1,   299520, 0x4768f9ed
+0,         29,         29,        1,   299520, 0xfad20b53
+0,         30,         30,        1,   299520, 0x82f9c996
+0,         31,         31,        1,   299520, 0x6b366d79
+0,         32,         32,        1,   299520, 0x5a35d42e
+0,         33,         33,        1,   299520, 0xf3849013
+0,         34,         34,        1,   299520, 0x6b8eae50
+0,         35,         35,        1,   299520, 0x0f854274
+0,         36,         36,        1,   299520, 0x31685299
+0,         37,         37,        1,   299520, 0x77357bfb
+0,         38,         38,        1,   299520, 0xd67f1807
+0,         39,         39,        1,   299520, 0x371e7eb6
+0,         40,         40,        1,   299520, 0xe2ee3531
+0,         41,         41,        1,   299520, 0x50f242f1
+0,         42,         42,        1,   299520, 0x265ed919
+0,         43,         43,        1,   299520, 0xad496c85
+0,         44,         44,        1,   299520, 0xb2aef047
+0,         45,         45,        1,   299520, 0xac5c4451
+0,         46,         46,        1,   299520, 0x2b26a0cb
+0,         47,         47,        1,   299520, 0x5738d837
diff --git a/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2
new file mode 100644
index 0000000..bb61b10
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x3772de54
+0,          1,          1,        1,   149760, 0x571d885e
+0,          2,          2,        1,   149760, 0x71576f09
+0,          3,          3,        1,   149760, 0xf0724ce0
+0,          4,          4,        1,   149760, 0x2cc6e355
+0,          5,          5,        1,   149760, 0x0ca14365
+0,          6,          6,        1,   149760, 0x5aeb4b4d
+0,          7,          7,        1,   149760, 0xb018561c
+0,          8,          8,        1,   149760, 0x8fb07521
+0,          9,          9,        1,   149760, 0x9e1ccc5b
+0,         10,         10,        1,   149760, 0x0cf3de9f
+0,         11,         11,        1,   149760, 0x918cf512
+0,         12,         12,        1,   149760, 0x9a60e5c4
+0,         13,         13,        1,   149760, 0xc3b01d10
+0,         14,         14,        1,   149760, 0x929b34a6
+0,         15,         15,        1,   149760, 0x1f9462ac
+0,         16,         16,        1,   149760, 0xcadf511e
+0,         17,         17,        1,   149760, 0x318e9af6
+0,         18,         18,        1,   149760, 0x0860a371
+0,         19,         19,        1,   149760, 0x13e3c4d1
+0,         20,         20,        1,   149760, 0xfa27cbf6
+0,         21,         21,        1,   149760, 0x407ffed5
+0,         22,         22,        1,   149760, 0xa3c00c3b
+0,         23,         23,        1,   149760, 0x926938c6
+0,         24,         24,        1,   149760, 0xf5792acf
+0,         25,         25,        1,   149760, 0x66e16a48
+0,         26,         26,        1,   149760, 0xd46e7041
+0,         27,         27,        1,   149760, 0x814c84ee
+0,         28,         28,        1,   149760, 0x165b750a
+0,         29,         29,        1,   149760, 0x24ad9df0
+0,         30,         30,        1,   149760, 0x11189e4e
+0,         31,         31,        1,   149760, 0xb841a5b6
+0,         32,         32,        1,   149760, 0xea738605
+0,         33,         33,        1,   149760, 0xbbf0ca3f
+0,         34,         34,        1,   149760, 0xcfb5d03c
+0,         35,         35,        1,   149760, 0x0654f0b7
+0,         36,         36,        1,   149760, 0x1c2cd18d
+0,         37,         37,        1,   149760, 0x9a4602ae
+0,         38,         38,        1,   149760, 0xf2a2ff5a
+0,         39,         39,        1,   149760, 0x9c153c77
+0,         40,         40,        1,   149760, 0x5ed23e56
+0,         41,         41,        1,   149760, 0x1eb58383
+0,         42,         42,        1,   149760, 0x725e70f2
+0,         43,         43,        1,   149760, 0x652aa56c
+0,         44,         44,        1,   149760, 0x7f736ad2
+0,         45,         45,        1,   149760, 0x0827700a
+0,         46,         46,        1,   149760, 0x76a06370
+0,         47,         47,        1,   149760, 0xa7fe6f9d
diff --git a/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2
new file mode 100644
index 0000000..b1e6312
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,   299520, 0xbc71d699
+0,          1,          1,        1,   299520, 0x3207e1f9
+0,          2,          2,        1,   299520, 0xdd2087b5
+0,          3,          3,        1,   299520, 0xb512c976
+0,          4,          4,        1,   299520, 0x22957011
+0,          5,          5,        1,   299520, 0x8ce04965
+0,          6,          6,        1,   299520, 0x9cf37cba
+0,          7,          7,        1,   299520, 0xd52f8b2d
+0,          8,          8,        1,   299520, 0x2f55a94d
+0,          9,          9,        1,   299520, 0x53d3cc42
+0,         10,         10,        1,   299520, 0xbc33f3a1
+0,         11,         11,        1,   299520, 0x5e67d0de
+0,         12,         12,        1,   299520, 0x5708ecc5
+0,         13,         13,        1,   299520, 0x104869c0
+0,         14,         14,        1,   299520, 0xaf2a8638
+0,         15,         15,        1,   299520, 0xbdf1d001
+0,         16,         16,        1,   299520, 0xa3f71579
+0,         17,         17,        1,   299520, 0x68cedb09
+0,         18,         18,        1,   299520, 0xa4262d4d
+0,         19,         19,        1,   299520, 0x99320c8d
+0,         20,         20,        1,   299520, 0x57be6268
+0,         21,         21,        1,   299520, 0xc7e14cfc
+0,         22,         22,        1,   299520, 0x3d906541
+0,         23,         23,        1,   299520, 0x804b2f29
+0,         24,         24,        1,   299520, 0x93cf0ae2
+0,         25,         25,        1,   299520, 0x0fd2f932
+0,         26,         26,        1,   299520, 0xf869a25c
+0,         27,         27,        1,   299520, 0xa2dc56cd
+0,         28,         28,        1,   299520, 0x075b14a7
+0,         29,         29,        1,   299520, 0x233b0085
+0,         30,         30,        1,   299520, 0x80a69c4c
+0,         31,         31,        1,   299520, 0xf45f21af
+0,         32,         32,        1,   299520, 0x88dcab6e
+0,         33,         33,        1,   299520, 0xc1df3e99
+0,         34,         34,        1,   299520, 0xac298452
+0,         35,         35,        1,   299520, 0x6b4cc1e3
+0,         36,         36,        1,   299520, 0xfd39c597
+0,         37,         37,        1,   299520, 0xe60f808c
+0,         38,         38,        1,   299520, 0x27c47830
+0,         39,         39,        1,   299520, 0x4fd9ec76
+0,         40,         40,        1,   299520, 0x3249e084
+0,         41,         41,        1,   299520, 0x40632223
+0,         42,         42,        1,   299520, 0x9b68d213
+0,         43,         43,        1,   299520, 0x9e210ed8
+0,         44,         44,        1,   299520, 0x54489508
+0,         45,         45,        1,   299520, 0xc799df16
+0,         46,         46,        1,   299520, 0x020b2211
+0,         47,         47,        1,   299520, 0xcc1a1683
diff --git a/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2
new file mode 100644
index 0000000..49c4f21
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x0948e521
+0,          1,          1,        1,   149760, 0x37afb384
+0,          2,          2,        1,   149760, 0xe1864c4a
+0,          3,          3,        1,   149760, 0x143344eb
+0,          4,          4,        1,   149760, 0x34cce612
+0,          5,          5,        1,   149760, 0x45ce60b3
+0,          6,          6,        1,   149760, 0x17b36585
+0,          7,          7,        1,   149760, 0x6447ebe5
+0,          8,          8,        1,   149760, 0x0f4282c7
+0,          9,          9,        1,   149760, 0xa0c3dab3
+0,         10,         10,        1,   149760, 0x0f3ceb7c
+0,         11,         11,        1,   149760, 0xb861f311
+0,         12,         12,        1,   149760, 0x620fe482
+0,         13,         13,        1,   149760, 0xa3dc1603
+0,         14,         14,        1,   149760, 0x6b7a3a6c
+0,         15,         15,        1,   149760, 0x01d16e5e
+0,         16,         16,        1,   149760, 0xe12f6009
+0,         17,         17,        1,   149760, 0xc96d98bd
+0,         18,         18,        1,   149760, 0x542e9f47
+0,         19,         19,        1,   149760, 0x5bcbc3b8
+0,         20,         20,        1,   149760, 0x3be2c63a
+0,         21,         21,        1,   149760, 0xd63df815
+0,         22,         22,        1,   149760, 0x5c210d61
+0,         23,         23,        1,   149760, 0xc7fb33b8
+0,         24,         24,        1,   149760, 0xa9f13508
+0,         25,         25,        1,   149760, 0xbf636172
+0,         26,         26,        1,   149760, 0xf1966847
+0,         27,         27,        1,   149760, 0xcc0579eb
+0,         28,         28,        1,   149760, 0x467673cb
+0,         29,         29,        1,   149760, 0x4dbca3f2
+0,         30,         30,        1,   149760, 0xada29bc9
+0,         31,         31,        1,   149760, 0x2983a0d5
+0,         32,         32,        1,   149760, 0x3864832a
+0,         33,         33,        1,   149760, 0x6a06b61d
+0,         34,         34,        1,   149760, 0x90a0d994
+0,         35,         35,        1,   149760, 0x3c58f375
+0,         36,         36,        1,   149760, 0x365bd42a
+0,         37,         37,        1,   149760, 0x5665f25f
+0,         38,         38,        1,   149760, 0x75d8fe8f
+0,         39,         39,        1,   149760, 0xc67e3508
+0,         40,         40,        1,   149760, 0x2e7b428b
+0,         41,         41,        1,   149760, 0x59cf741c
+0,         42,         42,        1,   149760, 0x2cc77eb4
+0,         43,         43,        1,   149760, 0x4957970a
+0,         44,         44,        1,   149760, 0xa69f7323
+0,         45,         45,        1,   149760, 0xaf1f6772
+0,         46,         46,        1,   149760, 0x864a5a76
+0,         47,         47,        1,   149760, 0x57795407
diff --git a/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2
new file mode 100644
index 0000000..83cf10c
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,    46080, 0xc50ed6b4
+0,          1,          1,        1,    46080, 0x2aeac52d
+0,          2,          2,        1,    46080, 0xe3e36cd3
+0,          3,          3,        1,    46080, 0x81c6b317
+0,          4,          4,        1,    46080, 0x20e24e33
+0,          5,          5,        1,    46080, 0xc4a64f17
+0,          6,          6,        1,    46080, 0xf95a5014
+0,          7,          7,        1,    46080, 0x8d9e9a26
+0,          8,          8,        1,    46080, 0x5f0f4592
+0,          9,          9,        1,    46080, 0xa1b54f9f
+0,         10,         10,        1,    46080, 0x3d5c3673
+0,         11,         11,        1,    46080, 0xca6e5e83
+0,         12,         12,        1,    46080, 0x93eca575
+0,         13,         13,        1,    46080, 0xf84bab2b
+0,         14,         14,        1,    46080, 0xf22599d1
+0,         15,         15,        1,    46080, 0xf916673f
+0,         16,         16,        1,    46080, 0xbb11a29b
+0,         17,         17,        1,    46080, 0x047e1dd7
+0,         18,         18,        1,    46080, 0x9a975834
+0,         19,         19,        1,    46080, 0xa3fe84d4
+0,         20,         20,        1,    46080, 0x08e1c2f4
+0,         21,         21,        1,    46080, 0xbbbcf81b
+0,         22,         22,        1,    46080, 0x4abb0255
+0,         23,         23,        1,    46080, 0x20052dda
+0,         24,         24,        1,    46080, 0x10290ef3
+0,         25,         25,        1,    46080, 0x9e7633d0
+0,         26,         26,        1,    46080, 0x60d0fb3a
+0,         27,         27,        1,    46080, 0xe0209fb3
+0,         28,         28,        1,    46080, 0xea006c44
+0,         29,         29,        1,    46080, 0xe0b84e96
+0,         30,         30,        1,    46080, 0x35e507d7
+0,         31,         31,        1,    46080, 0x4107fcd6
+0,         32,         32,        1,    46080, 0x1b34af49
+0,         33,         33,        1,    46080, 0x4ab91078
+0,         34,         34,        1,    46080, 0x130750dd
+0,         35,         35,        1,    46080, 0x592dbe41
+0,         36,         36,        1,    46080, 0xfd39cf6b
+0,         37,         37,        1,    46080, 0xbe9ee5b7
+0,         38,         38,        1,    46080, 0x25ebde48
+0,         39,         39,        1,    46080, 0x2becd45c
+0,         40,         40,        1,    46080, 0x9b5fdfdb
+0,         41,         41,        1,    46080, 0xededa5f5
+0,         42,         42,        1,    46080, 0x476bc4e5
+0,         43,         43,        1,    46080, 0x4a4a0a4e
+0,         44,         44,        1,    46080, 0x1324f41b
+0,         45,         45,        1,    46080, 0xc503cfc8
+0,         46,         46,        1,    46080, 0x53f7c74c
+0,         47,         47,        1,    46080, 0xc861b5a3
diff --git a/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2
new file mode 100644
index 0000000..6e6fc32
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,    23040, 0x6977dbca
+0,          1,          1,        1,    23040, 0xd9bfcb5c
+0,          2,          2,        1,    23040, 0xbdd5a346
+0,          3,          3,        1,    23040, 0x021877cd
+0,          4,          4,        1,    23040, 0xb8a45933
+0,          5,          5,        1,    23040, 0xc289338e
+0,          6,          6,        1,    23040, 0x6968e57d
+0,          7,          7,        1,    23040, 0x1142c50c
+0,          8,          8,        1,    23040, 0xcf86c357
+0,          9,          9,        1,    23040, 0xf73de7ec
+0,         10,         10,        1,    23040, 0x2103ed06
+0,         11,         11,        1,    23040, 0xf0ecc0e2
+0,         12,         12,        1,    23040, 0xa7b1971f
+0,         13,         13,        1,    23040, 0x4454871a
+0,         14,         14,        1,    23040, 0xc5088346
+0,         15,         15,        1,    23040, 0x89189469
+0,         16,         16,        1,    23040, 0x320d977a
+0,         17,         17,        1,    23040, 0xbdc0a95b
+0,         18,         18,        1,    23040, 0xbcfec5c9
+0,         19,         19,        1,    23040, 0xb68ceb37
+0,         20,         20,        1,    23040, 0x41a60b0c
+0,         21,         21,        1,    23040, 0x0e662b47
+0,         22,         22,        1,    23040, 0x0e2440b7
+0,         23,         23,        1,    23040, 0x77415a77
+0,         24,         24,        1,    23040, 0x62936fdf
+0,         25,         25,        1,    23040, 0xaa987f9d
+0,         26,         26,        1,    23040, 0xaf0c8764
+0,         27,         27,        1,    23040, 0x645c913e
+0,         28,         28,        1,    23040, 0x2f249b06
+0,         29,         29,        1,    23040, 0xb54fb546
+0,         30,         30,        1,    23040, 0xc669c247
+0,         31,         31,        1,    23040, 0xe308bb8f
+0,         32,         32,        1,    23040, 0xb920b69d
+0,         33,         33,        1,    23040, 0x86d5c0ff
+0,         34,         34,        1,    23040, 0x7d5ec3e4
+0,         35,         35,        1,    23040, 0x5ca1cdb0
+0,         36,         36,        1,    23040, 0xdc11cf9e
+0,         37,         37,        1,    23040, 0x1a7fd0d5
+0,         38,         38,        1,    23040, 0x9884d5cd
+0,         39,         39,        1,    23040, 0xcafbd5fb
+0,         40,         40,        1,    23040, 0xc670ceb7
+0,         41,         41,        1,    23040, 0x63cecef7
+0,         42,         42,        1,    23040, 0xfe29c28c
+0,         43,         43,        1,    23040, 0x368dc66e
+0,         44,         44,        1,    23040, 0x2ec7c4de
+0,         45,         45,        1,    23040, 0x8954c9d6
+0,         46,         46,        1,    23040, 0xff89ca68
+0,         47,         47,        1,    23040, 0x5ae0b290
diff --git a/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2
new file mode 100644
index 0000000..dbf6f78
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,    92160, 0x591c992e
+0,          1,          1,        1,    92160, 0xe7a8cd8b
+0,          2,          2,        1,    92160, 0x2e7528bb
+0,          3,          3,        1,    92160, 0x92438eae
+0,          4,          4,        1,    92160, 0x15cc21b9
+0,          5,          5,        1,    92160, 0x3f14a50e
+0,          6,          6,        1,    92160, 0xdbc712e7
+0,          7,          7,        1,    92160, 0x277b2d3f
+0,          8,          8,        1,    92160, 0x05478988
+0,          9,          9,        1,    92160, 0x46888b9c
+0,         10,         10,        1,    92160, 0xb1f46d1b
+0,         11,         11,        1,    92160, 0xa86771fa
+0,         12,         12,        1,    92160, 0x1294944a
+0,         13,         13,        1,    92160, 0xe134cd44
+0,         14,         14,        1,    92160, 0x5fdbf1fb
+0,         15,         15,        1,    92160, 0x01f04b2e
+0,         16,         16,        1,    92160, 0x50989c28
+0,         17,         17,        1,    92160, 0x3202cf37
+0,         18,         18,        1,    92160, 0x67fbdb0f
+0,         19,         19,        1,    92160, 0x4d453062
+0,         20,         20,        1,    92160, 0x799c3e16
+0,         21,         21,        1,    92160, 0xdda76a94
+0,         22,         22,        1,    92160, 0x392d0fc9
+0,         23,         23,        1,    92160, 0x1196e850
+0,         24,         24,        1,    92160, 0x8758d8a9
+0,         25,         25,        1,    92160, 0xb632c2b3
+0,         26,         26,        1,    92160, 0xf3ba5e47
+0,         27,         27,        1,    92160, 0x3ae40182
+0,         28,         28,        1,    92160, 0xf285e2eb
+0,         29,         29,        1,    92160, 0x826aee47
+0,         30,         30,        1,    92160, 0xe06ba18b
+0,         31,         31,        1,    92160, 0xf34b6ef5
+0,         32,         32,        1,    92160, 0xf94045ab
+0,         33,         33,        1,    92160, 0xd0ae63f4
+0,         34,         34,        1,    92160, 0x4c35afc1
+0,         35,         35,        1,    92160, 0x9a150816
+0,         36,         36,        1,    92160, 0x1a4214d4
+0,         37,         37,        1,    92160, 0x9f042653
+0,         38,         38,        1,    92160, 0xf69a40a8
+0,         39,         39,        1,    92160, 0xb8462c18
+0,         40,         40,        1,    92160, 0xf42d4748
+0,         41,         41,        1,    92160, 0x4968dc19
+0,         42,         42,        1,    92160, 0xc8e6001f
+0,         43,         43,        1,    92160, 0xebb42677
+0,         44,         44,        1,    92160, 0x3fb805dd
+0,         45,         45,        1,    92160, 0x1953cfc1
+0,         46,         46,        1,    92160, 0x633108f4
+0,         47,         47,        1,    92160, 0x65aedf42
diff --git a/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2
new file mode 100644
index 0000000..ac478c6
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,    46080, 0xcd234724
+0,          1,          1,        1,    46080, 0x66649579
+0,          2,          2,        1,    46080, 0x4317d38d
+0,          3,          3,        1,    46080, 0x308dfc39
+0,          4,          4,        1,    46080, 0xe08e3015
+0,          5,          5,        1,    46080, 0xaa0a3e44
+0,          6,          6,        1,    46080, 0x491b61cf
+0,          7,          7,        1,    46080, 0x9c5a9749
+0,          8,          8,        1,    46080, 0x4384ae34
+0,          9,          9,        1,    46080, 0xfd2bf2c1
+0,         10,         10,        1,    46080, 0xf29b18d7
+0,         11,         11,        1,    46080, 0xc1912df5
+0,         12,         12,        1,    46080, 0x9cc3344b
+0,         13,         13,        1,    46080, 0x41c062a3
+0,         14,         14,        1,    46080, 0xa5ec8417
+0,         15,         15,        1,    46080, 0x94e5aed6
+0,         16,         16,        1,    46080, 0x1af6ce24
+0,         17,         17,        1,    46080, 0xd73c0272
+0,         18,         18,        1,    46080, 0xb7b41c50
+0,         19,         19,        1,    46080, 0x7fa442dc
+0,         20,         20,        1,    46080, 0x513e5f5a
+0,         21,         21,        1,    46080, 0x46a1848b
+0,         22,         22,        1,    46080, 0xcf31a1c4
+0,         23,         23,        1,    46080, 0x3ee8c90c
+0,         24,         24,        1,    46080, 0xc54fdd27
+0,         25,         25,        1,    46080, 0x59830556
+0,         26,         26,        1,    46080, 0xf8c70cc7
+0,         27,         27,        1,    46080, 0x44a519f9
+0,         28,         28,        1,    46080, 0xdd0323d3
+0,         29,         29,        1,    46080, 0x93874212
+0,         30,         30,        1,    46080, 0xba8e4d8e
+0,         31,         31,        1,    46080, 0x5c3f4fb0
+0,         32,         32,        1,    46080, 0x37084bf2
+0,         33,         33,        1,    46080, 0xad256b1b
+0,         34,         34,        1,    46080, 0x862b7a7d
+0,         35,         35,        1,    46080, 0x4a2e8d56
+0,         36,         36,        1,    46080, 0xe99d8f5a
+0,         37,         37,        1,    46080, 0xe41a9456
+0,         38,         38,        1,    46080, 0xe7339f1c
+0,         39,         39,        1,    46080, 0xfa38a6c3
+0,         40,         40,        1,    46080, 0x219e97d2
+0,         41,         41,        1,    46080, 0x652d9cc2
+0,         42,         42,        1,    46080, 0x40bf8f94
+0,         43,         43,        1,    46080, 0x2fee9e23
+0,         44,         44,        1,    46080, 0xeea39203
+0,         45,         45,        1,    46080, 0x69819b5c
+0,         46,         46,        1,    46080, 0x511ba0b5
+0,         47,         47,        1,    46080, 0x85fd892f
diff --git a/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2 b/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2
new file mode 100644
index 0000000..2f103b7
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,   138240, 0x99f196ae
+0,          1,          1,        1,   138240, 0x45f407de
+0,          2,          2,        1,   138240, 0xdaef815b
+0,          3,          3,        1,   138240, 0x6812ba5a
+0,          4,          4,        1,   138240, 0x1099912d
+0,          5,          5,        1,   138240, 0xf58ee932
+0,          6,          6,        1,   138240, 0x79df05d8
+0,          7,          7,        1,   138240, 0xa0813719
+0,          8,          8,        1,   138240, 0xe9c7c5c0
+0,          9,          9,        1,   138240, 0xe8c5aba3
+0,         10,         10,        1,   138240, 0x7f0ed0b6
+0,         11,         11,        1,   138240, 0x1bdcfd20
+0,         12,         12,        1,   138240, 0x3b1fc007
+0,         13,         13,        1,   138240, 0xf6a9d270
+0,         14,         14,        1,   138240, 0x3a2d47d4
+0,         15,         15,        1,   138240, 0xbeb9685f
+0,         16,         16,        1,   138240, 0x4cb6eb4a
+0,         17,         17,        1,   138240, 0xa456dcdf
+0,         18,         18,        1,   138240, 0x2933f8e1
+0,         19,         19,        1,   138240, 0x27de28e9
+0,         20,         20,        1,   138240, 0x557c0e51
+0,         21,         21,        1,   138240, 0x6f106540
+0,         22,         22,        1,   138240, 0xf78421a4
+0,         23,         23,        1,   138240, 0xa94029a7
+0,         24,         24,        1,   138240, 0xacfa2b8b
+0,         25,         25,        1,   138240, 0x32e7d347
+0,         26,         26,        1,   138240, 0xe4c17fac
+0,         27,         27,        1,   138240, 0x47e61949
+0,         28,         28,        1,   138240, 0xd248e34b
+0,         29,         29,        1,   138240, 0xb747dc2c
+0,         30,         30,        1,   138240, 0x3a0eaf61
+0,         31,         31,        1,   138240, 0x4e254b5f
+0,         32,         32,        1,   138240, 0xf434f578
+0,         33,         33,        1,   138240, 0xe799308e
+0,         34,         34,        1,   138240, 0xb3e67c89
+0,         35,         35,        1,   138240, 0xb6ceb379
+0,         36,         36,        1,   138240, 0xd70bea99
+0,         37,         37,        1,   138240, 0xad0717a8
+0,         38,         38,        1,   138240, 0x2b50f085
+0,         39,         39,        1,   138240, 0xb334e518
+0,         40,         40,        1,   138240, 0xe7311c3a
+0,         41,         41,        1,   138240, 0x7c46dc19
+0,         42,         42,        1,   138240, 0x18c20dfa
+0,         43,         43,        1,   138240, 0x8bc0f6ae
+0,         44,         44,        1,   138240, 0x91a8c381
+0,         45,         45,        1,   138240, 0x2ba57297
+0,         46,         46,        1,   138240, 0x99d982f0
+0,         47,         47,        1,   138240, 0x0f84942a
diff --git a/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2 b/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2
new file mode 100644
index 0000000..6256d96
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2
@@ -0,0 +1,49 @@
+#tb 0: 1/25
+0,          0,          0,        1,    69120, 0x28326a13
+0,          1,          1,        1,    69120, 0x1f41a4a7
+0,          2,          2,        1,    69120, 0x803ceeb4
+0,          3,          3,        1,    69120, 0x1eba4049
+0,          4,          4,        1,    69120, 0x61a25512
+0,          5,          5,        1,    69120, 0x4db37e41
+0,          6,          6,        1,    69120, 0x00f69308
+0,          7,          7,        1,    69120, 0x7478c70f
+0,          8,          8,        1,    69120, 0xba1bd40b
+0,          9,          9,        1,    69120, 0x31d416bc
+0,         10,         10,        1,    69120, 0xd0c042bd
+0,         11,         11,        1,    69120, 0xe7a75aba
+0,         12,         12,        1,    69120, 0xb4235b4c
+0,         13,         13,        1,    69120, 0xaad387c3
+0,         14,         14,        1,    69120, 0xb97aab7a
+0,         15,         15,        1,    69120, 0x1acdda47
+0,         16,         16,        1,    69120, 0x2c95f726
+0,         17,         17,        1,    69120, 0xba3f2ebb
+0,         18,         18,        1,    69120, 0x15fc4901
+0,         19,         19,        1,    69120, 0x56387074
+0,         20,         20,        1,    69120, 0xe9638772
+0,         21,         21,        1,    69120, 0x344db5ec
+0,         22,         22,        1,    69120, 0xf54bd087
+0,         23,         23,        1,    69120, 0x5b35fbe4
+0,         24,         24,        1,    69120, 0x052c0947
+0,         25,         25,        1,    69120, 0xe562417c
+0,         26,         26,        1,    69120, 0x502a4776
+0,         27,         27,        1,    69120, 0x46b05919
+0,         28,         28,        1,    69120, 0x103161a1
+0,         29,         29,        1,    69120, 0xd83e8318
+0,         30,         30,        1,    69120, 0xd7ce8fb1
+0,         31,         31,        1,    69120, 0xda3f8ac5
+0,         32,         32,        1,    69120, 0xecd17de1
+0,         33,         33,        1,    69120, 0x7beeab11
+0,         34,         34,        1,    69120, 0xb295b81f
+0,         35,         35,        1,    69120, 0x785ec9ab
+0,         36,         36,        1,    69120, 0x58a3c317
+0,         37,         37,        1,    69120, 0x05feda91
+0,         38,         38,        1,    69120, 0xd21fdcab
+0,         39,         39,        1,    69120, 0x0d6ce0ee
+0,         40,         40,        1,    69120, 0x40ddc715
+0,         41,         41,        1,    69120, 0x5489d3e1
+0,         42,         42,        1,    69120, 0x7f57c42b
+0,         43,         43,        1,    69120, 0xd470cca3
+0,         44,         44,        1,    69120, 0xfb80c51c
+0,         45,         45,        1,    69120, 0x76b1d068
+0,         46,         46,        1,    69120, 0x5b01d81e
+0,         47,         47,        1,    69120, 0x21cfc241
diff --git a/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3 b/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3
new file mode 100644
index 0000000..b2dadba
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3
@@ -0,0 +1,257 @@
+#tb 0: 1/25
+0,          0,          0,        1,   299520, 0x7750edc7
+0,          1,          1,        1,   299520, 0x97fb359b
+0,          2,          2,        1,   299520, 0x89ac22bc
+0,          3,          3,        1,   299520, 0x4f7e0ecc
+0,          4,          4,        1,   299520, 0x7367f210
+0,          5,          5,        1,   299520, 0x5c2274e3
+0,          6,          6,        1,   299520, 0x11f26352
+0,          7,          7,        1,   299520, 0x2c712fcc
+0,          8,          8,        1,   299520, 0x44d700aa
+0,          9,          9,        1,   299520, 0x7426fc80
+0,         10,         10,        1,   299520, 0xd31d2fef
+0,         11,         11,        1,   299520, 0xd7c8d389
+0,         12,         12,        1,   299520, 0x2a8283e7
+0,         13,         13,        1,   299520, 0x429f5e44
+0,         14,         14,        1,   299520, 0x5c818504
+0,         15,         15,        1,   299520, 0x1057090e
+0,         16,         16,        1,   299520, 0x61404e77
+0,         17,         17,        1,   299520, 0x8ce43ed3
+0,         18,         18,        1,   299520, 0xf08e6c4d
+0,         19,         19,        1,   299520, 0xb133a69f
+0,         20,         20,        1,   299520, 0xd1be15a5
+0,         21,         21,        1,   299520, 0xe875543f
+0,         22,         22,        1,   299520, 0x0310f356
+0,         23,         23,        1,   299520, 0x5ee0a7d9
+0,         24,         24,        1,   299520, 0xacd092bb
+0,         25,         25,        1,   299520, 0x878ef783
+0,         26,         26,        1,   299520, 0xed9a2c06
+0,         27,         27,        1,   299520, 0x0a4cb661
+0,         28,         28,        1,   299520, 0x69aed89b
+0,         29,         29,        1,   299520, 0xaa75d081
+0,         30,         30,        1,   299520, 0x4c0402c6
+0,         31,         31,        1,   299520, 0x7050b8f8
+0,         32,         32,        1,   299520, 0x20cf8db8
+0,         33,         33,        1,   299520, 0xa615d0cb
+0,         34,         34,        1,   299520, 0x3170b77f
+0,         35,         35,        1,   299520, 0x781f17a5
+0,         36,         36,        1,   299520, 0x8767468b
+0,         37,         37,        1,   299520, 0x8f291a78
+0,         38,         38,        1,   299520, 0x87534588
+0,         39,         39,        1,   299520, 0xb4861cee
+0,         40,         40,        1,   299520, 0x38b6ba36
+0,         41,         41,        1,   299520, 0x757ebda4
+0,         42,         42,        1,   299520, 0xeccca3c0
+0,         43,         43,        1,   299520, 0x8af415a3
+0,         44,         44,        1,   299520, 0x37064dea
+0,         45,         45,        1,   299520, 0xfea46d66
+0,         46,         46,        1,   299520, 0x038d776f
+0,         47,         47,        1,   299520, 0x2b905161
+0,         48,         48,        1,   299520, 0x60230f44
+0,         49,         49,        1,   299520, 0x828f8991
+0,         50,         50,        1,   299520, 0x7c5ded06
+0,         51,         51,        1,   299520, 0xef38fd3a
+0,         52,         52,        1,   299520, 0x4c08ea42
+0,         53,         53,        1,   299520, 0x66dd9974
+0,         54,         54,        1,   299520, 0x4af1e690
+0,         55,         55,        1,   299520, 0x3fce05be
+0,         56,         56,        1,   299520, 0x07ccca7a
+0,         57,         57,        1,   299520, 0x1113a830
+0,         58,         58,        1,   299520, 0xe095faa8
+0,         59,         59,        1,   299520, 0x01da87b4
+0,         60,         60,        1,   299520, 0xecd3ea56
+0,         61,         61,        1,   299520, 0x8b80d26b
+0,         62,         62,        1,   299520, 0x625b4844
+0,         63,         63,        1,   299520, 0x1f96bc19
+0,         64,         64,        1,   299520, 0x8de15c59
+0,         65,         65,        1,   299520, 0x8de15c59
+0,         66,         66,        1,   299520, 0xe0f88d0d
+0,         67,         67,        1,   299520, 0xe0f88d0d
+0,         68,         68,        1,   299520, 0xf951adca
+0,         69,         69,        1,   299520, 0x3159e1a0
+0,         70,         70,        1,   299520, 0xa3b9764d
+0,         71,         71,        1,   299520, 0xa294c4db
+0,         72,         72,        1,   299520, 0x9ddd0aa8
+0,         73,         73,        1,   299520, 0x47702302
+0,         74,         74,        1,   299520, 0xebd66219
+0,         75,         75,        1,   299520, 0x9daa6030
+0,         76,         76,        1,   299520, 0x74aad521
+0,         77,         77,        1,   299520, 0x74aad521
+0,         78,         78,        1,   299520, 0x6be83092
+0,         79,         79,        1,   299520, 0x87e19ded
+0,         80,         80,        1,   299520, 0x41f4552c
+0,         81,         81,        1,   299520, 0xdbbd4643
+0,         82,         82,        1,   299520, 0x85505e9d
+0,         83,         83,        1,   299520, 0x33692949
+0,         84,         84,        1,   299520, 0x2d3ded88
+0,         85,         85,        1,   299520, 0x211ed3d4
+0,         86,         86,        1,   299520, 0x9dd3c6b8
+0,         87,         87,        1,   299520, 0x96016144
+0,         88,         88,        1,   299520, 0xdb86dd3a
+0,         89,         89,        1,   299520, 0x2a07d782
+0,         90,         90,        1,   299520, 0x4baeac21
+0,         91,         91,        1,   299520, 0x9426dbd3
+0,         92,         92,        1,   299520, 0x69203a74
+0,         93,         93,        1,   299520, 0x69203a74
+0,         94,         94,        1,   299520, 0xcb3e55c2
+0,         95,         95,        1,   299520, 0xbbc8dea2
+0,         96,         96,        1,   299520, 0x19b27f0d
+0,         97,         97,        1,   299520, 0x0edb8988
+0,         98,         98,        1,   299520, 0x0b3a8feb
+0,         99,         99,        1,   299520, 0xa2a3a4b4
+0,        100,        100,        1,   299520, 0xeb26e563
+0,        101,        101,        1,   299520, 0xd3fb037e
+0,        102,        102,        1,   299520, 0x106089ed
+0,        103,        103,        1,   299520, 0x606fb6ed
+0,        104,        104,        1,   299520, 0x6e14a326
+0,        105,        105,        1,   299520, 0x875cfdab
+0,        106,        106,        1,   299520, 0xa1f316f9
+0,        107,        107,        1,   299520, 0x444fff4a
+0,        108,        108,        1,   299520, 0x9c7b6c8a
+0,        109,        109,        1,   299520, 0xffd0ffa3
+0,        110,        110,        1,   299520, 0x278941d9
+0,        111,        111,        1,   299520, 0x05a1552f
+0,        112,        112,        1,   299520, 0x5b564fbc
+0,        113,        113,        1,   299520, 0x25ffb96d
+0,        114,        114,        1,   299520, 0x6e389daf
+0,        115,        115,        1,   299520, 0x1b48132b
+0,        116,        116,        1,   299520, 0xcc9b5df0
+0,        117,        117,        1,   299520, 0xe8895d00
+0,        118,        118,        1,   299520, 0x35ea30df
+0,        119,        119,        1,   299520, 0x8dcf07b4
+0,        120,        120,        1,   299520, 0x1cf3780e
+0,        121,        121,        1,   299520, 0x5f1a6062
+0,        122,        122,        1,   299520, 0xe2ac4ed0
+0,        123,        123,        1,   299520, 0x07fe56aa
+0,        124,        124,        1,   299520, 0xe892eab8
+0,        125,        125,        1,   299520, 0xdeda11d7
+0,        126,        126,        1,   299520, 0xc8134b3f
+0,        127,        127,        1,   299520, 0x8baa039a
+0,        128,        128,        1,   299520, 0x8ec71908
+0,        129,        129,        1,   299520, 0x8ec71908
+0,        130,        130,        1,   299520, 0x73ae1f71
+0,        131,        131,        1,   299520, 0xb615e210
+0,        132,        132,        1,   299520, 0x7afe31e6
+0,        133,        133,        1,   299520, 0x38362f5b
+0,        134,        134,        1,   299520, 0xbb7c2fad
+0,        135,        135,        1,   299520, 0xe08720c1
+0,        136,        136,        1,   299520, 0xb1118297
+0,        137,        137,        1,   299520, 0x33740a04
+0,        138,        138,        1,   299520, 0x567c1e9c
+0,        139,        139,        1,   299520, 0x3911af2a
+0,        140,        140,        1,   299520, 0xec64ec95
+0,        141,        141,        1,   299520, 0x83128903
+0,        142,        142,        1,   299520, 0xd11a7835
+0,        143,        143,        1,   299520, 0xd96bc851
+0,        144,        144,        1,   299520, 0x726696ba
+0,        145,        145,        1,   299520, 0x35c6b8e4
+0,        146,        146,        1,   299520, 0xd238e317
+0,        147,        147,        1,   299520, 0xf28c861b
+0,        148,        148,        1,   299520, 0x5d49132b
+0,        149,        149,        1,   299520, 0xcbadef81
+0,        150,        150,        1,   299520, 0x1fbcfda6
+0,        151,        151,        1,   299520, 0xa18a07b6
+0,        152,        152,        1,   299520, 0xa1631bb5
+0,        153,        153,        1,   299520, 0xcb80f2d6
+0,        154,        154,        1,   299520, 0x88b23aae
+0,        155,        155,        1,   299520, 0xbaa50ebe
+0,        156,        156,        1,   299520, 0x1bc7151d
+0,        157,        157,        1,   299520, 0x7254b9a4
+0,        158,        158,        1,   299520, 0xd66682cb
+0,        159,        159,        1,   299520, 0x846c055b
+0,        160,        160,        1,   299520, 0x4d0ac94f
+0,        161,        161,        1,   299520, 0xf9a01b25
+0,        162,        162,        1,   299520, 0x193dc288
+0,        163,        163,        1,   299520, 0xf43fb875
+0,        164,        164,        1,   299520, 0xf4fd6452
+0,        165,        165,        1,   299520, 0xafcdfb2a
+0,        166,        166,        1,   299520, 0x5c342ad7
+0,        167,        167,        1,   299520, 0xfe7943ec
+0,        168,        168,        1,   299520, 0xc7e8a82d
+0,        169,        169,        1,   299520, 0x99b1ed3f
+0,        170,        170,        1,   299520, 0x4decbdb8
+0,        171,        171,        1,   299520, 0x3cb0ccc2
+0,        172,        172,        1,   299520, 0x3b210547
+0,        173,        173,        1,   299520, 0xb8dee8bf
+0,        174,        174,        1,   299520, 0x75124e85
+0,        175,        175,        1,   299520, 0xbd390ba5
+0,        176,        176,        1,   299520, 0x5030302d
+0,        177,        177,        1,   299520, 0x38a4c990
+0,        178,        178,        1,   299520, 0x6d091561
+0,        179,        179,        1,   299520, 0x4598d16a
+0,        180,        180,        1,   299520, 0xa60c8a7c
+0,        181,        181,        1,   299520, 0x1987b4ab
+0,        182,        182,        1,   299520, 0x3fc66893
+0,        183,        183,        1,   299520, 0x3fc66893
+0,        184,        184,        1,   299520, 0x84694e9d
+0,        185,        185,        1,   299520, 0x84694e9d
+0,        186,        186,        1,   299520, 0xa736933c
+0,        187,        187,        1,   299520, 0x994e35f8
+0,        188,        188,        1,   299520, 0x80999aab
+0,        189,        189,        1,   299520, 0x5cf09e35
+0,        190,        190,        1,   299520, 0x8678f05d
+0,        191,        191,        1,   299520, 0xe4ca13df
+0,        192,        192,        1,   299520, 0x0ab1fc5b
+0,        193,        193,        1,   299520, 0x949977a6
+0,        194,        194,        1,   299520, 0x0ab1fc5b
+0,        195,        195,        1,   299520, 0xb5677d4e
+0,        196,        196,        1,   299520, 0xefd5e34c
+0,        197,        197,        1,   299520, 0xfb5875da
+0,        198,        198,        1,   299520, 0x3520759c
+0,        199,        199,        1,   299520, 0xc30dbfb6
+0,        200,        200,        1,   299520, 0xcedb09c4
+0,        201,        201,        1,   299520, 0xced1dc4a
+0,        202,        202,        1,   299520, 0xcf7d3425
+0,        203,        203,        1,   299520, 0xede92113
+0,        204,        204,        1,   299520, 0x6ca1204e
+0,        205,        205,        1,   299520, 0x04a46f67
+0,        206,        206,        1,   299520, 0x1bd8fe03
+0,        207,        207,        1,   299520, 0x11dab44d
+0,        208,        208,        1,   299520, 0xc0d1109c
+0,        209,        209,        1,   299520, 0x9e19c78f
+0,        210,        210,        1,   299520, 0xcffab4cb
+0,        211,        211,        1,   299520, 0x07582785
+0,        212,        212,        1,   299520, 0x43182694
+0,        213,        213,        1,   299520, 0x76f8c058
+0,        214,        214,        1,   299520, 0x895cbd03
+0,        215,        215,        1,   299520, 0xec9f9014
+0,        216,        216,        1,   299520, 0xd9cc6c00
+0,        217,        217,        1,   299520, 0xf15c775e
+0,        218,        218,        1,   299520, 0xe4b60e06
+0,        219,        219,        1,   299520, 0x5d825ea9
+0,        220,        220,        1,   299520, 0xd39d2f4a
+0,        221,        221,        1,   299520, 0x9b8dfedc
+0,        222,        222,        1,   299520, 0xc851ce8f
+0,        223,        223,        1,   299520, 0xdc399f09
+0,        224,        224,        1,   299520, 0xbce817c6
+0,        225,        225,        1,   299520, 0x48cc865e
+0,        226,        226,        1,   299520, 0xf875c060
+0,        227,        227,        1,   299520, 0xb3b4b0a3
+0,        228,        228,        1,   299520, 0xce683731
+0,        229,        229,        1,   299520, 0xeddd5126
+0,        230,        230,        1,   299520, 0x2ecf505e
+0,        231,        231,        1,   299520, 0x631c4af2
+0,        232,        232,        1,   299520, 0x1cc7742e
+0,        233,        233,        1,   299520, 0xc5124083
+0,        234,        234,        1,   299520, 0x4a851970
+0,        235,        235,        1,   299520, 0xbfad7925
+0,        236,        236,        1,   299520, 0x92058c0e
+0,        237,        237,        1,   299520, 0x7ecd39b5
+0,        238,        238,        1,   299520, 0x58887a74
+0,        239,        239,        1,   299520, 0xb0825813
+0,        240,        240,        1,   299520, 0xbc763455
+0,        241,        241,        1,   299520, 0x3b259a45
+0,        242,        242,        1,   299520, 0xb200177c
+0,        243,        243,        1,   299520, 0x1cb15851
+0,        244,        244,        1,   299520, 0xd73a92cd
+0,        245,        245,        1,   299520, 0xe43419cf
+0,        246,        246,        1,   299520, 0xf0facff1
+0,        247,        247,        1,   299520, 0xc931e638
+0,        248,        248,        1,   299520, 0xc33e31e7
+0,        249,        249,        1,   299520, 0x03b43a26
+0,        250,        250,        1,   299520, 0x85d64d60
+0,        251,        251,        1,   299520, 0x86a8848c
+0,        252,        252,        1,   299520, 0x5f09afaf
+0,        253,        253,        1,   299520, 0xb7e92098
+0,        254,        254,        1,   299520, 0xf1957fad
+0,        255,        255,        1,   299520, 0xf29dc4b0
diff --git a/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3 b/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3
new file mode 100644
index 0000000..a8c5df3
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3
@@ -0,0 +1,257 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xf4bafc83
+0,          1,          1,        1,   149760, 0x611ca492
+0,          2,          2,        1,   149760, 0x8fa9bbb1
+0,          3,          3,        1,   149760, 0x3926aed3
+0,          4,          4,        1,   149760, 0x33e4f7f0
+0,          5,          5,        1,   149760, 0x03cc4fab
+0,          6,          6,        1,   149760, 0xbfae58e5
+0,          7,          7,        1,   149760, 0x0e6f1fea
+0,          8,          8,        1,   149760, 0x5a2ed57e
+0,          9,          9,        1,   149760, 0x5513cc3a
+0,         10,         10,        1,   149760, 0xd610ccca
+0,         11,         11,        1,   149760, 0xbf27617f
+0,         12,         12,        1,   149760, 0x878cd03b
+0,         13,         13,        1,   149760, 0x7b7ec3e9
+0,         14,         14,        1,   149760, 0xdaff0ba7
+0,         15,         15,        1,   149760, 0xce3be576
+0,         16,         16,        1,   149760, 0x16d32b84
+0,         17,         17,        1,   149760, 0xb7f6a144
+0,         18,         18,        1,   149760, 0x4dfb9b67
+0,         19,         19,        1,   149760, 0x29cb06ba
+0,         20,         20,        1,   149760, 0xcee5f14c
+0,         21,         21,        1,   149760, 0xe05bde26
+0,         22,         22,        1,   149760, 0xf717e789
+0,         23,         23,        1,   149760, 0xbbbf0ce8
+0,         24,         24,        1,   149760, 0x0e3ccfb1
+0,         25,         25,        1,   149760, 0x84204399
+0,         26,         26,        1,   149760, 0x02063b2b
+0,         27,         27,        1,   149760, 0xa4198aab
+0,         28,         28,        1,   149760, 0x4a4075aa
+0,         29,         29,        1,   149760, 0x1869435b
+0,         30,         30,        1,   149760, 0x04a12a8b
+0,         31,         31,        1,   149760, 0x7ab3f640
+0,         32,         32,        1,   149760, 0xba55f83a
+0,         33,         33,        1,   149760, 0xa8abaa48
+0,         34,         34,        1,   149760, 0x25483cb4
+0,         35,         35,        1,   149760, 0xc6925d6d
+0,         36,         36,        1,   149760, 0xc944b04d
+0,         37,         37,        1,   149760, 0xd7093017
+0,         38,         38,        1,   149760, 0x8d11c574
+0,         39,         39,        1,   149760, 0xdbaab3e1
+0,         40,         40,        1,   149760, 0xb412a3d9
+0,         41,         41,        1,   149760, 0x37b918a6
+0,         42,         42,        1,   149760, 0x6f6e7575
+0,         43,         43,        1,   149760, 0x059a55de
+0,         44,         44,        1,   149760, 0xe75aa6e6
+0,         45,         45,        1,   149760, 0x627394bf
+0,         46,         46,        1,   149760, 0xbcf99ab9
+0,         47,         47,        1,   149760, 0x29c52e30
+0,         48,         48,        1,   149760, 0x22056e1a
+0,         49,         49,        1,   149760, 0xf272fa39
+0,         50,         50,        1,   149760, 0x4b89033e
+0,         51,         51,        1,   149760, 0x0a59e138
+0,         52,         52,        1,   149760, 0x61a1a6c8
+0,         53,         53,        1,   149760, 0xe5414697
+0,         54,         54,        1,   149760, 0x6db38ec2
+0,         55,         55,        1,   149760, 0x2d09b0ba
+0,         56,         56,        1,   149760, 0x014a751e
+0,         57,         57,        1,   149760, 0x3e6f78d6
+0,         58,         58,        1,   149760, 0xed483aab
+0,         59,         59,        1,   149760, 0xcf366ee0
+0,         60,         60,        1,   149760, 0x4fc5e2dc
+0,         61,         61,        1,   149760, 0xf2a16393
+0,         62,         62,        1,   149760, 0xaa7ff5be
+0,         63,         63,        1,   149760, 0xa8c4c963
+0,         64,         64,        1,   149760, 0x3af766cf
+0,         65,         65,        1,   149760, 0x3af766cf
+0,         66,         66,        1,   149760, 0x11de29e7
+0,         67,         67,        1,   149760, 0x3aa137c0
+0,         68,         68,        1,   149760, 0x6f5bf4c4
+0,         69,         69,        1,   149760, 0xa5b8f392
+0,         70,         70,        1,   149760, 0x106ee459
+0,         71,         71,        1,   149760, 0x65dd99cc
+0,         72,         72,        1,   149760, 0x96facd15
+0,         73,         73,        1,   149760, 0x3355cb07
+0,         74,         74,        1,   149760, 0xe994f26b
+0,         75,         75,        1,   149760, 0xe955f0d5
+0,         76,         76,        1,   149760, 0xb740949e
+0,         77,         77,        1,   149760, 0x0b95963b
+0,         78,         78,        1,   149760, 0xdf7cf302
+0,         79,         79,        1,   149760, 0x8805c30d
+0,         80,         80,        1,   149760, 0xc30c832a
+0,         81,         81,        1,   149760, 0x696836a7
+0,         82,         82,        1,   149760, 0x696836a7
+0,         83,         83,        1,   149760, 0x4c7e0e68
+0,         84,         84,        1,   149760, 0xfee52485
+0,         85,         85,        1,   149760, 0xebbe8381
+0,         86,         86,        1,   149760, 0xb30ff0a9
+0,         87,         87,        1,   149760, 0x4ddafbfb
+0,         88,         88,        1,   149760, 0x5449c902
+0,         89,         89,        1,   149760, 0x79e61161
+0,         90,         90,        1,   149760, 0x72f1a340
+0,         91,         91,        1,   149760, 0xf98bae64
+0,         92,         92,        1,   149760, 0x253dd19f
+0,         93,         93,        1,   149760, 0x253dd19f
+0,         94,         94,        1,   149760, 0xc16e6af4
+0,         95,         95,        1,   149760, 0x66f2a539
+0,         96,         96,        1,   149760, 0xfccfd340
+0,         97,         97,        1,   149760, 0xd76a28c9
+0,         98,         98,        1,   149760, 0x38797af0
+0,         99,         99,        1,   149760, 0x06165c19
+0,        100,        100,        1,   149760, 0x9afee257
+0,        101,        101,        1,   149760, 0x1b2ce435
+0,        102,        102,        1,   149760, 0xb3e2de89
+0,        103,        103,        1,   149760, 0xb585e81f
+0,        104,        104,        1,   149760, 0x6743ece6
+0,        105,        105,        1,   149760, 0xfe5a001f
+0,        106,        106,        1,   149760, 0x064a778f
+0,        107,        107,        1,   149760, 0x99907eef
+0,        108,        108,        1,   149760, 0x1b9ec247
+0,        109,        109,        1,   149760, 0x52adad6c
+0,        110,        110,        1,   149760, 0xf5176bd9
+0,        111,        111,        1,   149760, 0xefdfa365
+0,        112,        112,        1,   149760, 0xa2e8447f
+0,        113,        113,        1,   149760, 0x3ea43a87
+0,        114,        114,        1,   149760, 0xbe643579
+0,        115,        115,        1,   149760, 0x518ae330
+0,        116,        116,        1,   149760, 0x49d815e6
+0,        117,        117,        1,   149760, 0xbfbb1bf0
+0,        118,        118,        1,   149760, 0x19596f6f
+0,        119,        119,        1,   149760, 0x4f6cbeec
+0,        120,        120,        1,   149760, 0xdd3f7460
+0,        121,        121,        1,   149760, 0xf2bb54f3
+0,        122,        122,        1,   149760, 0xb9d5d7cd
+0,        123,        123,        1,   149760, 0xe62736a5
+0,        124,        124,        1,   149760, 0x29c6f950
+0,        125,        125,        1,   149760, 0x99e1faed
+0,        126,        126,        1,   149760, 0x5c149afe
+0,        127,        127,        1,   149760, 0xb4118f9b
+0,        128,        128,        1,   149760, 0x262d7f30
+0,        129,        129,        1,   149760, 0x262d7f30
+0,        130,        130,        1,   149760, 0x13e286ed
+0,        131,        131,        1,   149760, 0xee6b3447
+0,        132,        132,        1,   149760, 0x9e749867
+0,        133,        133,        1,   149760, 0xdbca6bab
+0,        134,        134,        1,   149760, 0x154c9331
+0,        135,        135,        1,   149760, 0x653a3058
+0,        136,        136,        1,   149760, 0x739c1e57
+0,        137,        137,        1,   149760, 0x8e05e122
+0,        138,        138,        1,   149760, 0xe21f583a
+0,        139,        139,        1,   149760, 0xa58149fc
+0,        140,        140,        1,   149760, 0x90bd3787
+0,        141,        141,        1,   149760, 0x385aa42a
+0,        142,        142,        1,   149760, 0xf2589fc6
+0,        143,        143,        1,   149760, 0xd5233b3b
+0,        144,        144,        1,   149760, 0x2cc2d9cc
+0,        145,        145,        1,   149760, 0xb9b0eeef
+0,        146,        146,        1,   149760, 0xa9a60da9
+0,        147,        147,        1,   149760, 0xb854378a
+0,        148,        148,        1,   149760, 0xa76e2c37
+0,        149,        149,        1,   149760, 0xbe5c0542
+0,        150,        150,        1,   149760, 0x4d78b907
+0,        151,        151,        1,   149760, 0x6119f5d7
+0,        152,        152,        1,   149760, 0x195ae3c8
+0,        153,        153,        1,   149760, 0x35e9de61
+0,        154,        154,        1,   149760, 0x99f0df3b
+0,        155,        155,        1,   149760, 0x1a0ebfee
+0,        156,        156,        1,   149760, 0x4ece0a87
+0,        157,        157,        1,   149760, 0x670773b9
+0,        158,        158,        1,   149760, 0xae8c2789
+0,        159,        159,        1,   149760, 0xa145e3f8
+0,        160,        160,        1,   149760, 0x130d2ea3
+0,        161,        161,        1,   149760, 0x9afdf6dc
+0,        162,        162,        1,   149760, 0x8f8ed056
+0,        163,        163,        1,   149760, 0x8d50ad5c
+0,        164,        164,        1,   149760, 0x50b41bbb
+0,        165,        165,        1,   149760, 0xe8a89c0b
+0,        166,        166,        1,   149760, 0x4862c664
+0,        167,        167,        1,   149760, 0x9f99193f
+0,        168,        168,        1,   149760, 0x3d2ea4d8
+0,        169,        169,        1,   149760, 0xfcb83723
+0,        170,        170,        1,   149760, 0x2e135fe9
+0,        171,        171,        1,   149760, 0xcd059eeb
+0,        172,        172,        1,   149760, 0xcc2914ab
+0,        173,        173,        1,   149760, 0x63a4cf21
+0,        174,        174,        1,   149760, 0x0bdf9666
+0,        175,        175,        1,   149760, 0x8fcd46d9
+0,        176,        176,        1,   149760, 0xa2a94d81
+0,        177,        177,        1,   149760, 0x72da1124
+0,        178,        178,        1,   149760, 0x4faf50a2
+0,        179,        179,        1,   149760, 0x52168ea8
+0,        180,        180,        1,   149760, 0x766cd6e4
+0,        181,        181,        1,   149760, 0x9a76dd3f
+0,        182,        182,        1,   149760, 0xacf745bb
+0,        183,        183,        1,   149760, 0xacf745bb
+0,        184,        184,        1,   149760, 0x5d0f5914
+0,        185,        185,        1,   149760, 0x5d0f5914
+0,        186,        186,        1,   149760, 0x491b5959
+0,        187,        187,        1,   149760, 0xce9bf07f
+0,        188,        188,        1,   149760, 0x45123e08
+0,        189,        189,        1,   149760, 0x7ec1ced4
+0,        190,        190,        1,   149760, 0x7ec1ced4
+0,        191,        191,        1,   149760, 0xd383e72e
+0,        192,        192,        1,   149760, 0x29558d4c
+0,        193,        193,        1,   149760, 0xdcea6ec3
+0,        194,        194,        1,   149760, 0x29558d4c
+0,        195,        195,        1,   149760, 0x55b305ad
+0,        196,        196,        1,   149760, 0x68326c39
+0,        197,        197,        1,   149760, 0x89c8c0f7
+0,        198,        198,        1,   149760, 0x1fb33243
+0,        199,        199,        1,   149760, 0xa07b14e8
+0,        200,        200,        1,   149760, 0x6b37b02f
+0,        201,        201,        1,   149760, 0x7453171e
+0,        202,        202,        1,   149760, 0xec95ce93
+0,        203,        203,        1,   149760, 0xdbb0481b
+0,        204,        204,        1,   149760, 0xe44eaafd
+0,        205,        205,        1,   149760, 0xcdf5dfd5
+0,        206,        206,        1,   149760, 0x42695b4e
+0,        207,        207,        1,   149760, 0xe4e26db0
+0,        208,        208,        1,   149760, 0xada778f6
+0,        209,        209,        1,   149760, 0x77dab36a
+0,        210,        210,        1,   149760, 0xcabeb23d
+0,        211,        211,        1,   149760, 0x43d21021
+0,        212,        212,        1,   149760, 0xe4a5280c
+0,        213,        213,        1,   149760, 0xeb408a99
+0,        214,        214,        1,   149760, 0x0751fc6c
+0,        215,        215,        1,   149760, 0x2e770c68
+0,        216,        216,        1,   149760, 0x5a799fb0
+0,        217,        217,        1,   149760, 0x0e2e22dd
+0,        218,        218,        1,   149760, 0x276e6e88
+0,        219,        219,        1,   149760, 0xf83b9da4
+0,        220,        220,        1,   149760, 0xd4599290
+0,        221,        221,        1,   149760, 0xd4599290
+0,        222,        222,        1,   149760, 0xcf41ec75
+0,        223,        223,        1,   149760, 0x84af0bfc
+0,        224,        224,        1,   149760, 0x59db5c12
+0,        225,        225,        1,   149760, 0x0405a92a
+0,        226,        226,        1,   149760, 0xfde2c0fe
+0,        227,        227,        1,   149760, 0x96a68bab
+0,        228,        228,        1,   149760, 0x7e9d4983
+0,        229,        229,        1,   149760, 0x27b724c9
+0,        230,        230,        1,   149760, 0x402cdb15
+0,        231,        231,        1,   149760, 0x0d89328b
+0,        232,        232,        1,   149760, 0x08847a7e
+0,        233,        233,        1,   149760, 0x8eb7f52f
+0,        234,        234,        1,   149760, 0x49bf75bb
+0,        235,        235,        1,   149760, 0xbd6c77e3
+0,        236,        236,        1,   149760, 0x9eb5a5c0
+0,        237,        237,        1,   149760, 0xb5900c9b
+0,        238,        238,        1,   149760, 0xa9278bd6
+0,        239,        239,        1,   149760, 0x688d4c01
+0,        240,        240,        1,   149760, 0xe2669ce6
+0,        241,        241,        1,   149760, 0xb80590b9
+0,        242,        242,        1,   149760, 0xcdcc0036
+0,        243,        243,        1,   149760, 0xad653077
+0,        244,        244,        1,   149760, 0xe87179ae
+0,        245,        245,        1,   149760, 0x91553e8b
+0,        246,        246,        1,   149760, 0xd254f2b4
+0,        247,        247,        1,   149760, 0xe284e289
+0,        248,        248,        1,   149760, 0x09118405
+0,        249,        249,        1,   149760, 0x5f46d196
+0,        250,        250,        1,   149760, 0xfee1f4be
+0,        251,        251,        1,   149760, 0xbccf48bc
+0,        252,        252,        1,   149760, 0x48327792
+0,        253,        253,        1,   149760, 0x3d893b3c
+0,        254,        254,        1,   149760, 0xb2ae071d
+0,        255,        255,        1,   149760, 0x278e0be3
diff --git a/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3 b/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3
new file mode 100644
index 0000000..f302764
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3
@@ -0,0 +1,257 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xd8bf0c39
+0,          4,          4,        1,   149760, 0xad390a29
+0,          5,          5,        1,   149760, 0x0d310906
+0,          5,          5,        1,   149760, 0x03bcb5ac
+0,          6,          6,        1,   149760, 0x6c38226f
+0,          7,          7,        1,   149760, 0xc7d898b6
+0,          8,          8,        1,   149760, 0x1e031118
+0,          9,          9,        1,   149760, 0x7a2437f2
+0,         10,         10,        1,   149760, 0x524d616a
+0,         11,         11,        1,   149760, 0x001ac80e
+0,         12,         12,        1,   149760, 0x6fe323e4
+0,         13,         13,        1,   149760, 0x2a95a125
+0,         14,         14,        1,   149760, 0x212316e4
+0,         15,         15,        1,   149760, 0x7984e2ed
+0,         16,         16,        1,   149760, 0xb0a4a95c
+0,         17,         17,        1,   149760, 0x100566ae
+0,         18,         18,        1,   149760, 0xb21b2344
+0,         19,         19,        1,   149760, 0x0578bca2
+0,         20,         20,        1,   149760, 0xf7523964
+0,         21,         21,        1,   149760, 0x38d2ca9e
+0,         22,         22,        1,   149760, 0x77890564
+0,         23,         23,        1,   149760, 0xbdba85df
+0,         24,         24,        1,   149760, 0x646ae92d
+0,         25,         25,        1,   149760, 0xfcbb58b9
+0,         26,         26,        1,   149760, 0x0122aa96
+0,         27,         27,        1,   149760, 0x60f8e1ee
+0,         28,         28,        1,   149760, 0x3fc2d587
+0,         29,         29,        1,   149760, 0xdb622c12
+0,         30,         30,        1,   149760, 0xa8df64cf
+0,         31,         31,        1,   149760, 0x12f8d6c8
+0,         32,         32,        1,   149760, 0xf6703c4d
+0,         33,         33,        1,   149760, 0x66ef211d
+0,         34,         34,        1,   149760, 0x821b02f6
+0,         35,         35,        1,   149760, 0xc87f48a0
+0,         36,         36,        1,   149760, 0xb816ad51
+0,         37,         37,        1,   149760, 0x238e6fa0
+0,         38,         38,        1,   149760, 0x0fc06010
+0,         39,         39,        1,   149760, 0x749c71dc
+0,         40,         40,        1,   149760, 0x88c69718
+0,         41,         41,        1,   149760, 0x4b29aeb1
+0,         42,         42,        1,   149760, 0xaaefb509
+0,         43,         43,        1,   149760, 0x2975fda6
+0,         44,         44,        1,   149760, 0x613ec356
+0,         45,         45,        1,   149760, 0xf1e46db6
+0,         46,         46,        1,   149760, 0x8c8aec07
+0,         47,         47,        1,   149760, 0xb9a8be75
+0,         48,         48,        1,   149760, 0xfdce756a
+0,         49,         49,        1,   149760, 0x9c76f148
+0,         50,         50,        1,   149760, 0x5d1862dd
+0,         51,         51,        1,   149760, 0x42ae08bf
+0,         52,         52,        1,   149760, 0xc28f9247
+0,         53,         53,        1,   149760, 0x719d321c
+0,         54,         54,        1,   149760, 0x1520a7bc
+0,         55,         55,        1,   149760, 0x4fb98c9a
+0,         56,         56,        1,   149760, 0x88d410a6
+0,         57,         57,        1,   149760, 0x807ac417
+0,         58,         58,        1,   149760, 0x6de5f4ab
+0,         59,         59,        1,   149760, 0x678613c7
+0,         60,         60,        1,   149760, 0xe7d12abf
+0,         61,         61,        1,   149760, 0x23955076
+0,         62,         62,        1,   149760, 0x298d1bce
+0,         63,         63,        1,   149760, 0x18d4605d
+0,         64,         64,        1,   149760, 0x3a606618
+0,         65,         65,        1,   149760, 0x861fcb5a
+0,         66,         66,        1,   149760, 0xc6622a90
+0,         67,         67,        1,   149760, 0x62d4cd48
+0,         68,         68,        1,   149760, 0x991430e6
+0,         69,         69,        1,   149760, 0x6316503c
+0,         70,         70,        1,   149760, 0xdf2d29f2
+0,         71,         71,        1,   149760, 0xeeeb307a
+0,         72,         72,        1,   149760, 0xade9ae1d
+0,         73,         73,        1,   149760, 0x54734581
+0,         74,         74,        1,   149760, 0x5ccd7389
+0,         75,         75,        1,   149760, 0xf0588bf8
+0,         76,         76,        1,   149760, 0xf18e44e5
+0,         77,         77,        1,   149760, 0x4512602b
+0,         78,         78,        1,   149760, 0x9aac8281
+0,         79,         79,        1,   149760, 0x69bdad58
+0,         80,         80,        1,   149760, 0x04ffe580
+0,         81,         81,        1,   149760, 0x28bfe45f
+0,         82,         82,        1,   149760, 0xd7ce93b0
+0,         83,         83,        1,   149760, 0xa880b1d4
+0,         84,         84,        1,   149760, 0xf38298d0
+0,         85,         85,        1,   149760, 0x2ae05958
+0,         86,         86,        1,   149760, 0xa892151b
+0,         87,         87,        1,   149760, 0xed2cef63
+0,         88,         88,        1,   149760, 0x678fc6f5
+0,         89,         89,        1,   149760, 0xfcbaa892
+0,         90,         90,        1,   149760, 0x48cc722b
+0,         91,         91,        1,   149760, 0x32cd8975
+0,         92,         92,        1,   149760, 0x05ad8586
+0,         93,         93,        1,   149760, 0x62a0fb36
+0,         94,         94,        1,   149760, 0x41df8d45
+0,         95,         95,        1,   149760, 0x80bd938d
+0,         96,         96,        1,   149760, 0xafe414b0
+0,         97,         97,        1,   149760, 0x3077d51d
+0,         98,         98,        1,   149760, 0x65148cef
+0,         99,         99,        1,   149760, 0xadb76ef0
+0,        100,        100,        1,   149760, 0x889c3051
+0,        101,        101,        1,   149760, 0xe83b227e
+0,        102,        102,        1,   149760, 0xc373f5e0
+0,        103,        103,        1,   149760, 0x6ffa2a5f
+0,        104,        104,        1,   149760, 0x6eef18f5
+0,        105,        105,        1,   149760, 0x1b1ba6e4
+0,        106,        106,        1,   149760, 0x88e316a4
+0,        107,        107,        1,   149760, 0x4c0697f4
+0,        108,        108,        1,   149760, 0x5eb30515
+0,        109,        109,        1,   149760, 0xeeff8fa3
+0,        110,        110,        1,   149760, 0x653a07a9
+0,        111,        111,        1,   149760, 0x3faf44a8
+0,        112,        112,        1,   149760, 0xe33f740e
+0,        113,        113,        1,   149760, 0x6bea0f49
+0,        114,        114,        1,   149760, 0x4d5aa784
+0,        115,        115,        1,   149760, 0x0c85ea00
+0,        116,        116,        1,   149760, 0xf64fc40b
+0,        117,        117,        1,   149760, 0xf222e3b4
+0,        118,        118,        1,   149760, 0x6b3be6bc
+0,        119,        119,        1,   149760, 0x91447dfb
+0,        120,        120,        1,   149760, 0xfd0dd98c
+0,        121,        121,        1,   149760, 0x468eb01a
+0,        122,        122,        1,   149760, 0x928a720a
+0,        123,        123,        1,   149760, 0x0b3f576b
+0,        124,        124,        1,   149760, 0x430493df
+0,        125,        125,        1,   149760, 0x375d2221
+0,        126,        126,        1,   149760, 0x50d0a88c
+0,        127,        127,        1,   149760, 0x54363ffb
+0,        128,        128,        1,   149760, 0xc243c434
+0,        129,        129,        1,   149760, 0x26fe8f5c
+0,        130,        130,        1,   149760, 0xd936485c
+0,        131,        131,        1,   149760, 0xd936485c
+0,        132,        132,        1,   149760, 0xa0cabe5a
+0,        133,        133,        1,   149760, 0xf0956484
+0,        134,        134,        1,   149760, 0x14cda6ee
+0,        135,        135,        1,   149760, 0x0b7ada70
+0,        136,        136,        1,   149760, 0x113f0ec5
+0,        137,        137,        1,   149760, 0xc1364acc
+0,        138,        138,        1,   149760, 0x0c768a6a
+0,        139,        139,        1,   149760, 0x94fd7a00
+0,        140,        140,        1,   149760, 0x624a5ebb
+0,        141,        141,        1,   149760, 0xdd5008a0
+0,        142,        142,        1,   149760, 0xc380626c
+0,        143,        143,        1,   149760, 0xb0974c02
+0,        144,        144,        1,   149760, 0x68be6c1e
+0,        145,        145,        1,   149760, 0xb8d24677
+0,        146,        146,        1,   149760, 0x1efe195c
+0,        147,        147,        1,   149760, 0x29e9153a
+0,        148,        148,        1,   149760, 0x1b6057b7
+0,        149,        149,        1,   149760, 0x959a4461
+0,        150,        150,        1,   149760, 0x4e3d33a9
+0,        151,        151,        1,   149760, 0x206e7899
+0,        152,        152,        1,   149760, 0xcb7da081
+0,        153,        153,        1,   149760, 0xc650ed7b
+0,        154,        154,        1,   149760, 0x82832d10
+0,        155,        155,        1,   149760, 0xdf9c6218
+0,        156,        156,        1,   149760, 0xcc3489c7
+0,        157,        157,        1,   149760, 0xd284a4a1
+0,        158,        158,        1,   149760, 0x7099451c
+0,        159,        159,        1,   149760, 0xec26fc56
+0,        160,        160,        1,   149760, 0x105a496f
+0,        161,        161,        1,   149760, 0xb8756fe8
+0,        162,        162,        1,   149760, 0xb1a509df
+0,        163,        163,        1,   149760, 0x135f8f7e
+0,        164,        164,        1,   149760, 0x3419098d
+0,        165,        165,        1,   149760, 0xa55dad5f
+0,        166,        166,        1,   149760, 0x326ba794
+0,        167,        167,        1,   149760, 0x5401b03c
+0,        168,        168,        1,   149760, 0x3ace76ee
+0,        169,        169,        1,   149760, 0x140191ac
+0,        170,        170,        1,   149760, 0x3e3ca195
+0,        171,        171,        1,   149760, 0x2a8b3622
+0,        172,        172,        1,   149760, 0x9e33c765
+0,        173,        173,        1,   149760, 0xf7795367
+0,        174,        174,        1,   149760, 0xa7909e25
+0,        175,        175,        1,   149760, 0x44a5a014
+0,        176,        176,        1,   149760, 0x919bb07c
+0,        177,        177,        1,   149760, 0xd353b9a7
+0,        178,        178,        1,   149760, 0x4c3dda24
+0,        179,        179,        1,   149760, 0x1428eafb
+0,        180,        180,        1,   149760, 0x9d9fa613
+0,        181,        181,        1,   149760, 0x661475c6
+0,        182,        182,        1,   149760, 0x5f6f4180
+0,        183,        183,        1,   149760, 0xf50a4b4c
+0,        184,        184,        1,   149760, 0xf6373eb9
+0,        185,        185,        1,   149760, 0x0ab24b74
+0,        186,        186,        1,   149760, 0x6b3d58b0
+0,        187,        187,        1,   149760, 0xc4c8bd05
+0,        188,        188,        1,   149760, 0x0df172c6
+0,        189,        189,        1,   149760, 0x81a85144
+0,        190,        190,        1,   149760, 0x7f926ee5
+0,        191,        191,        1,   149760, 0x3a355d45
+0,        192,        192,        1,   149760, 0x9f645c90
+0,        193,        193,        1,   149760, 0xf42674ea
+0,        194,        194,        1,   149760, 0xa6e943ab
+0,        195,        195,        1,   149760, 0xede16b49
+0,        196,        196,        1,   149760, 0xf80c9957
+0,        197,        197,        1,   149760, 0xa7a44665
+0,        198,        198,        1,   149760, 0x08f17b20
+0,        199,        199,        1,   149760, 0x0319e942
+0,        200,        200,        1,   149760, 0xab69057c
+0,        201,        201,        1,   149760, 0xb98814f4
+0,        202,        202,        1,   149760, 0xa172e6d0
+0,        203,        203,        1,   149760, 0x6cd35cd1
+0,        204,        204,        1,   149760, 0x7352b4b9
+0,        205,        205,        1,   149760, 0x07cbdedd
+0,        206,        206,        1,   149760, 0xbe7aa3c8
+0,        207,        207,        1,   149760, 0xdcbc8993
+0,        208,        208,        1,   149760, 0x0c5dbf95
+0,        209,        209,        1,   149760, 0x107e4f2c
+0,        210,        210,        1,   149760, 0xc650e333
+0,        211,        211,        1,   149760, 0x46abae6f
+0,        212,        212,        1,   149760, 0x0e41309d
+0,        213,        213,        1,   149760, 0x831e19a1
+0,        214,        214,        1,   149760, 0xd1955874
+0,        215,        215,        1,   149760, 0x486c41bb
+0,        216,        216,        1,   149760, 0xba020143
+0,        217,        217,        1,   149760, 0x3ebedef4
+0,        218,        218,        1,   149760, 0xda7bc235
+0,        219,        219,        1,   149760, 0x0abcb13e
+0,        220,        220,        1,   149760, 0xdf5159ac
+0,        221,        221,        1,   149760, 0x4e39d893
+0,        222,        222,        1,   149760, 0x393f382d
+0,        223,        223,        1,   149760, 0x92556867
+0,        224,        224,        1,   149760, 0x2daf47a8
+0,        225,        225,        1,   149760, 0x792a4448
+0,        226,        226,        1,   149760, 0x429e05ad
+0,        227,        227,        1,   149760, 0x89caaa32
+0,        228,        228,        1,   149760, 0xa70ec97b
+0,        229,        229,        1,   149760, 0xce0d24b7
+0,        230,        230,        1,   149760, 0x04be745d
+0,        231,        231,        1,   149760, 0xfb04d3d2
+0,        232,        232,        1,   149760, 0x5b472952
+0,        233,        233,        1,   149760, 0x6cd704b5
+0,        234,        234,        1,   149760, 0x18b0db7e
+0,        235,        235,        1,   149760, 0xdfb24e07
+0,        236,        236,        1,   149760, 0x6d9bae45
+0,        237,        237,        1,   149760, 0xf2eb5756
+0,        238,        238,        1,   149760, 0xdf858203
+0,        239,        239,        1,   149760, 0xdcd4822f
+0,        240,        240,        1,   149760, 0x80ceabaf
+0,        241,        241,        1,   149760, 0x8bd1a92f
+0,        242,        242,        1,   149760, 0x981a61ca
+0,        243,        243,        1,   149760, 0x5fa92603
+0,        244,        244,        1,   149760, 0xbb28f8da
+0,        245,        245,        1,   149760, 0x1710666d
+0,        246,        246,        1,   149760, 0xf928099a
+0,        247,        247,        1,   149760, 0x2e0ae9cb
+0,        248,        248,        1,   149760, 0xcf0e402c
+0,        249,        249,        1,   149760, 0x48e5b987
+0,        250,        250,        1,   149760, 0x7dc42853
+0,        251,        251,        1,   149760, 0x25f4aef0
+0,        252,        252,        1,   149760, 0x5f1d37b3
+0,        253,        253,        1,   149760, 0xb2fabf9f
+0,        254,        254,        1,   149760, 0xe87348ee
+0,        255,        255,        1,   149760, 0xbe9ec00f
+0,        256,        256,        1,   149760, 0xd67d1fb2
+0,        257,        257,        1,   149760, 0x92db1ca8
diff --git a/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3 b/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3
new file mode 100644
index 0000000..23f03f8
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3
@@ -0,0 +1,257 @@
+#tb 0: 1/25
+0,          0,          0,        1,   299520, 0x6ecba46b
+0,          4,          4,        1,   299520, 0x54e6ef0a
+0,          5,          5,        1,   299520, 0x7a4d46c5
+0,          6,          6,        1,   299520, 0xccd57f4e
+0,          7,          7,        1,   299520, 0xbe0cb48d
+0,          8,          8,        1,   299520, 0x10e7b49f
+0,          9,          9,        1,   299520, 0x81aa72e2
+0,         10,         10,        1,   299520, 0x5bf7b51f
+0,         11,         11,        1,   299520, 0xfcedee4a
+0,         12,         12,        1,   299520, 0x586c99b6
+0,         13,         13,        1,   299520, 0x414ca13c
+0,         14,         14,        1,   299520, 0x3f0162f2
+0,         15,         15,        1,   299520, 0x4d450c05
+0,         16,         16,        1,   299520, 0x0a58bd84
+0,         17,         17,        1,   299520, 0x26e8394d
+0,         18,         18,        1,   299520, 0xfd78121b
+0,         19,         19,        1,   299520, 0x6afeaf44
+0,         20,         20,        1,   299520, 0x3e9a9270
+0,         21,         21,        1,   299520, 0x58b889ca
+0,         22,         22,        1,   299520, 0x0245ba62
+0,         23,         23,        1,   299520, 0xddecc5ab
+0,         24,         24,        1,   299520, 0x32cf3cd9
+0,         25,         25,        1,   299520, 0x5c0a0440
+0,         26,         26,        1,   299520, 0x9d3e2fee
+0,         27,         27,        1,   299520, 0x2894c708
+0,         28,         28,        1,   299520, 0x25be67d5
+0,         29,         29,        1,   299520, 0xe3ece9d6
+0,         30,         30,        1,   299520, 0xcc98e38b
+0,         31,         31,        1,   299520, 0xc448c794
+0,         32,         32,        1,   299520, 0xb4f75575
+0,         33,         33,        1,   299520, 0xac74a437
+0,         34,         34,        1,   299520, 0x09c7f2e2
+0,         35,         35,        1,   299520, 0xbfaed8ab
+0,         36,         36,        1,   299520, 0xb077d700
+0,         37,         37,        1,   299520, 0x6efa0545
+0,         38,         38,        1,   299520, 0xb8c1802d
+0,         39,         39,        1,   299520, 0x794774f8
+0,         40,         40,        1,   299520, 0x1098f4ff
+0,         41,         41,        1,   299520, 0x80ab8bfc
+0,         42,         42,        1,   299520, 0xc324c3bc
+0,         43,         43,        1,   299520, 0x1eee77cd
+0,         44,         44,        1,   299520, 0x7147e72e
+0,         45,         45,        1,   299520, 0x1a34883c
+0,         46,         46,        1,   299520, 0x74e93e31
+0,         47,         47,        1,   299520, 0x89410382
+0,         48,         48,        1,   299520, 0xfcce0ce1
+0,         49,         49,        1,   299520, 0x07bb33c6
+0,         50,         50,        1,   299520, 0xc1ee7318
+0,         51,         51,        1,   299520, 0xd1c4bd2d
+0,         52,         52,        1,   299520, 0xa670cfae
+0,         53,         53,        1,   299520, 0x718de79b
+0,         54,         54,        1,   299520, 0x85e40b78
+0,         55,         55,        1,   299520, 0x15362e72
+0,         56,         56,        1,   299520, 0xc6e523fa
+0,         57,         57,        1,   299520, 0x3e536edd
+0,         58,         58,        1,   299520, 0x9312996e
+0,         59,         59,        1,   299520, 0x9456d53c
+0,         60,         60,        1,   299520, 0x7bc01398
+0,         61,         61,        1,   299520, 0x5a40bcb4
+0,         62,         62,        1,   299520, 0xcfe126ce
+0,         63,         63,        1,   299520, 0xd9e1adf1
+0,         64,         64,        1,   299520, 0x9027b1ae
+0,         65,         65,        1,   299520, 0x4c1372fb
+0,         66,         66,        1,   299520, 0xe475a00b
+0,         67,         67,        1,   299520, 0x945bc646
+0,         68,         68,        1,   299520, 0xc33dbab3
+0,         69,         69,        1,   299520, 0x9e4afb82
+0,         70,         70,        1,   299520, 0x1bffa858
+0,         71,         71,        1,   299520, 0x3bc78ad7
+0,         72,         72,        1,   299520, 0xa096e683
+0,         73,         73,        1,   299520, 0xb889aa23
+0,         74,         74,        1,   299520, 0x8ffad857
+0,         75,         75,        1,   299520, 0x59d3cc7c
+0,         76,         76,        1,   299520, 0x47d1377a
+0,         77,         77,        1,   299520, 0xea73e864
+0,         78,         78,        1,   299520, 0x0994bd5c
+0,         79,         79,        1,   299520, 0xdf779d85
+0,         80,         80,        1,   299520, 0x8238cfa7
+0,         81,         81,        1,   299520, 0x8f2e94cc
+0,         82,         82,        1,   299520, 0x9e0b0df8
+0,         83,         83,        1,   299520, 0x98ac1ce5
+0,         84,         84,        1,   299520, 0xc1c293ed
+0,         85,         85,        1,   299520, 0x1f1dfedb
+0,         86,         86,        1,   299520, 0xe7297d56
+0,         87,         87,        1,   299520, 0xa1390726
+0,         88,         88,        1,   299520, 0xf0e828e8
+0,         89,         89,        1,   299520, 0x108b8291
+0,         90,         90,        1,   299520, 0xd8830efb
+0,         91,         91,        1,   299520, 0xeee3d2f0
+0,         92,         92,        1,   299520, 0xa35d5b29
+0,         93,         93,        1,   299520, 0xa14d0840
+0,         94,         94,        1,   299520, 0xfa894a56
+0,         95,         95,        1,   299520, 0xd50005b5
+0,         96,         96,        1,   299520, 0xba625134
+0,         97,         97,        1,   299520, 0xce7dd782
+0,         98,         98,        1,   299520, 0x9e04e32f
+0,         99,         99,        1,   299520, 0x07e6d466
+0,        100,        100,        1,   299520, 0x4e66e1d4
+0,        101,        101,        1,   299520, 0x80aa6be6
+0,        102,        102,        1,   299520, 0xa4564be8
+0,        103,        103,        1,   299520, 0x7d34e443
+0,        104,        104,        1,   299520, 0xd5a08c86
+0,        105,        105,        1,   299520, 0xa73e63e8
+0,        106,        106,        1,   299520, 0x93937eb2
+0,        107,        107,        1,   299520, 0x0c08ba8f
+0,        108,        108,        1,   299520, 0x1d6b1a8c
+0,        109,        109,        1,   299520, 0x2e0272b4
+0,        110,        110,        1,   299520, 0x47177676
+0,        111,        111,        1,   299520, 0x6af7ffce
+0,        112,        112,        1,   299520, 0x0564a4bc
+0,        113,        113,        1,   299520, 0x7f664100
+0,        114,        114,        1,   299520, 0x6decd6ae
+0,        115,        115,        1,   299520, 0xb2d94adc
+0,        116,        116,        1,   299520, 0x55d33809
+0,        117,        117,        1,   299520, 0x5b126674
+0,        118,        118,        1,   299520, 0xd25d5750
+0,        119,        119,        1,   299520, 0x789a7f89
+0,        120,        120,        1,   299520, 0xdd082ab2
+0,        121,        121,        1,   299520, 0x3e6132ee
+0,        122,        122,        1,   299520, 0xe48209ca
+0,        123,        123,        1,   299520, 0x707d3b24
+0,        124,        124,        1,   299520, 0x8af19539
+0,        125,        125,        1,   299520, 0x0bbb4c38
+0,        126,        126,        1,   299520, 0xaaba4bd6
+0,        127,        127,        1,   299520, 0xa325d79e
+0,        128,        128,        1,   299520, 0x2bd4b64a
+0,        129,        129,        1,   299520, 0xab0c59a7
+0,        130,        130,        1,   299520, 0x260a56fc
+0,        131,        131,        1,   299520, 0xa1a55847
+0,        132,        132,        1,   299520, 0xa1a55847
+0,        133,        133,        1,   299520, 0x01438514
+0,        134,        134,        1,   299520, 0xa511e8bd
+0,        135,        135,        1,   299520, 0x7ebfd5b9
+0,        136,        136,        1,   299520, 0xdf4f1365
+0,        137,        137,        1,   299520, 0x6266911a
+0,        138,        138,        1,   299520, 0xe8eefcab
+0,        139,        139,        1,   299520, 0x7e74ca0d
+0,        140,        140,        1,   299520, 0x4b21d349
+0,        141,        141,        1,   299520, 0xa8b9ef41
+0,        142,        142,        1,   299520, 0x3187ee5b
+0,        143,        143,        1,   299520, 0x3fadb935
+0,        144,        144,        1,   299520, 0x8dca0391
+0,        145,        145,        1,   299520, 0x68215cc6
+0,        146,        146,        1,   299520, 0x7c81f366
+0,        147,        147,        1,   299520, 0x1a976381
+0,        148,        148,        1,   299520, 0x8ac095f4
+0,        149,        149,        1,   299520, 0xf5f8752b
+0,        150,        150,        1,   299520, 0xd8c03c80
+0,        151,        151,        1,   299520, 0x445a2e07
+0,        152,        152,        1,   299520, 0xddb83c6f
+0,        153,        153,        1,   299520, 0xc6dfe76a
+0,        154,        154,        1,   299520, 0x860a120f
+0,        155,        155,        1,   299520, 0x1ec91a95
+0,        156,        156,        1,   299520, 0x0180cc49
+0,        157,        157,        1,   299520, 0x63a115e3
+0,        158,        158,        1,   299520, 0x8848e971
+0,        159,        159,        1,   299520, 0x49246622
+0,        160,        160,        1,   299520, 0x3169db32
+0,        161,        161,        1,   299520, 0xcf01d8a3
+0,        162,        162,        1,   299520, 0x57a1a9c1
+0,        163,        163,        1,   299520, 0x517670eb
+0,        164,        164,        1,   299520, 0x4e2e6b5a
+0,        165,        165,        1,   299520, 0x06240a68
+0,        166,        166,        1,   299520, 0xa0d076a1
+0,        167,        167,        1,   299520, 0xb73c4515
+0,        168,        168,        1,   299520, 0x9f523268
+0,        169,        169,        1,   299520, 0x6fdcc6a2
+0,        170,        170,        1,   299520, 0xf3f5b69f
+0,        171,        171,        1,   299520, 0xce33a286
+0,        172,        172,        1,   299520, 0xce46e834
+0,        173,        173,        1,   299520, 0x14a6fe0d
+0,        174,        174,        1,   299520, 0x39a8145f
+0,        175,        175,        1,   299520, 0x91981d47
+0,        176,        176,        1,   299520, 0x1507d9be
+0,        177,        177,        1,   299520, 0x4525d4a2
+0,        178,        178,        1,   299520, 0x95e058ab
+0,        179,        179,        1,   299520, 0x8de2438a
+0,        180,        180,        1,   299520, 0xf43dc0ff
+0,        181,        181,        1,   299520, 0xaf232f4b
+0,        182,        182,        1,   299520, 0x8adabd81
+0,        183,        183,        1,   299520, 0x1e837b72
+0,        184,        184,        1,   299520, 0xb79f811d
+0,        185,        185,        1,   299520, 0x1532fb05
+0,        186,        186,        1,   299520, 0x2e3f6341
+0,        187,        187,        1,   299520, 0x10c82269
+0,        188,        188,        1,   299520, 0x8c39bd0c
+0,        189,        189,        1,   299520, 0x64fefe7b
+0,        190,        190,        1,   299520, 0x3ef6d5c7
+0,        191,        191,        1,   299520, 0x571c1edc
+0,        192,        192,        1,   299520, 0xe9e1584c
+0,        193,        193,        1,   299520, 0xd150a0db
+0,        194,        194,        1,   299520, 0x5d140f2d
+0,        195,        195,        1,   299520, 0xea00f302
+0,        196,        196,        1,   299520, 0xdd4e0fc4
+0,        197,        197,        1,   299520, 0x51c760fa
+0,        198,        198,        1,   299520, 0x68d5d26e
+0,        199,        199,        1,   299520, 0xde594a02
+0,        200,        200,        1,   299520, 0xac6d361a
+0,        201,        201,        1,   299520, 0xef6506ae
+0,        202,        202,        1,   299520, 0x744737a8
+0,        203,        203,        1,   299520, 0x2bd0834b
+0,        204,        204,        1,   299520, 0x348a8d0f
+0,        205,        205,        1,   299520, 0x93e165c8
+0,        206,        206,        1,   299520, 0x208d305c
+0,        207,        207,        1,   299520, 0xb927ed9a
+0,        208,        208,        1,   299520, 0xd252b13a
+0,        209,        209,        1,   299520, 0x11a59b2d
+0,        210,        210,        1,   299520, 0xc27785d0
+0,        211,        211,        1,   299520, 0x5c654cb5
+0,        212,        212,        1,   299520, 0x3d03a387
+0,        213,        213,        1,   299520, 0xdb0dc19d
+0,        214,        214,        1,   299520, 0x2ef3bbba
+0,        215,        215,        1,   299520, 0x7d36cd79
+0,        216,        216,        1,   299520, 0xa9ceca1e
+0,        217,        217,        1,   299520, 0x33db4d99
+0,        218,        218,        1,   299520, 0x8d28a55e
+0,        219,        219,        1,   299520, 0x554864a6
+0,        220,        220,        1,   299520, 0x6a336557
+0,        221,        221,        1,   299520, 0xd2285832
+0,        222,        222,        1,   299520, 0x9509f5f8
+0,        223,        223,        1,   299520, 0x8e479b03
+0,        224,        224,        1,   299520, 0x9513a8c3
+0,        225,        225,        1,   299520, 0x81080fac
+0,        226,        226,        1,   299520, 0x6c447b69
+0,        227,        227,        1,   299520, 0xbf4c2fbd
+0,        228,        228,        1,   299520, 0x1a77306e
+0,        229,        229,        1,   299520, 0xd485864b
+0,        230,        230,        1,   299520, 0x4e87b787
+0,        231,        231,        1,   299520, 0xe28e7153
+0,        232,        232,        1,   299520, 0x2ab24b9b
+0,        233,        233,        1,   299520, 0xffcb7357
+0,        234,        234,        1,   299520, 0x5e1e2b7e
+0,        235,        235,        1,   299520, 0x58d39e6d
+0,        236,        236,        1,   299520, 0x4a2b836a
+0,        237,        237,        1,   299520, 0xa1728e1e
+0,        238,        238,        1,   299520, 0x33e5bdd4
+0,        239,        239,        1,   299520, 0x3b144d98
+0,        240,        240,        1,   299520, 0xe72c4de2
+0,        241,        241,        1,   299520, 0x031350cb
+0,        242,        242,        1,   299520, 0x146fba58
+0,        243,        243,        1,   299520, 0x1b6679c7
+0,        244,        244,        1,   299520, 0x27e9d545
+0,        245,        245,        1,   299520, 0x5105beeb
+0,        246,        246,        1,   299520, 0x80284fd3
+0,        247,        247,        1,   299520, 0x426a5d65
+0,        248,        248,        1,   299520, 0xdcc33f89
+0,        249,        249,        1,   299520, 0x29e805ec
+0,        250,        250,        1,   299520, 0x89a09ed9
+0,        251,        251,        1,   299520, 0x60ad258c
+0,        252,        252,        1,   299520, 0xb44ee9b1
+0,        253,        253,        1,   299520, 0x184d6a88
+0,        254,        254,        1,   299520, 0xb4c8cefe
+0,        255,        255,        1,   299520, 0x358a0407
+0,        256,        256,        1,   299520, 0xa5cb97eb
+0,        257,        257,        1,   299520, 0x3d6a096e
+0,        258,        258,        1,   299520, 0xcb266e78
diff --git a/tests/ref/fate/hevc-conformance-cip_B_NEC_2 b/tests/ref/fate/hevc-conformance-cip_B_NEC_2
new file mode 100644
index 0000000..016f0f1
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-cip_B_NEC_2
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xcbda260f
+0,          1,          1,        1,   149760, 0xbd8d32a9
+0,          2,          2,        1,   149760, 0x39562006
+0,          3,          3,        1,   149760, 0xbc62475b
+0,          4,          4,        1,   149760, 0x1bf1fb79
diff --git a/tests/ref/fate/hevc-conformance-ipcm_A_NEC_2 b/tests/ref/fate/hevc-conformance-ipcm_A_NEC_2
new file mode 100644
index 0000000..145f590
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ipcm_A_NEC_2
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0x2356474c
diff --git a/tests/ref/fate/hevc-conformance-ipcm_B_NEC_2 b/tests/ref/fate/hevc-conformance-ipcm_B_NEC_2
new file mode 100644
index 0000000..d917cbc
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ipcm_B_NEC_2
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xc80d43f8
diff --git a/tests/ref/fate/hevc-conformance-ipcm_C_NEC_2 b/tests/ref/fate/hevc-conformance-ipcm_C_NEC_2
new file mode 100644
index 0000000..6c89cea
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ipcm_C_NEC_2
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xb92d38ee
diff --git a/tests/ref/fate/hevc-conformance-ipcm_D_NEC_2 b/tests/ref/fate/hevc-conformance-ipcm_D_NEC_2
new file mode 100644
index 0000000..2ccff05
--- /dev/null
+++ b/tests/ref/fate/hevc-conformance-ipcm_D_NEC_2
@@ -0,0 +1,2 @@
+#tb 0: 1/25
+0,          0,          0,        1,   149760, 0xa24d17f8
diff --git a/tests/ref/fate/hmac b/tests/ref/fate/hmac
new file mode 100644
index 0000000..7d2a437
--- /dev/null
+++ b/tests/ref/fate/hmac
@@ -0,0 +1,6 @@
+9294727a3638bb1c13f48ef8158bfc9d
+750c783e6ab0b503eaa86e310a5db738
+56be34521d144c88dbb8c733f0e8b3f6
+467cb2560355d7fa3ab2d6b939e6e47c
+5a6ffd741d3e23b12f78b1baee9e609a
+8b4b9d11c9e186c58f2a53b08ddfa436
diff --git a/tests/ref/fate/id-cin-video b/tests/ref/fate/id-cin-video
index 241cae5..f55544f 100644
--- a/tests/ref/fate/id-cin-video
+++ b/tests/ref/fate/id-cin-video
@@ -104,4 +104,3 @@
 1,      78750,      78750,     1575,     6300, 0xe3bfa403
 0,         51,         51,        1,   230400, 0x488de02d
 1,      80325,      80325,     1575,     6300, 0x2c5bd9c9
-0,         52,         52,        1,   230400, 0x488de02d
diff --git a/tests/ref/fate/indeo3-2 b/tests/ref/fate/indeo3-2
new file mode 100644
index 0000000..702d06b
--- /dev/null
+++ b/tests/ref/fate/indeo3-2
@@ -0,0 +1,101 @@
+#tb 0: 200/2997
+0,          0,          0,        1,    67680, 0x532a4c40
+0,         37,         37,        1,    67680, 0x63d2757a
+0,         38,         38,        1,    67680, 0xb1dcf7d3
+0,         39,         39,        1,    67680, 0x3225ee89
+0,         40,         40,        1,    67680, 0x9a102730
+0,         41,         41,        1,    67680, 0xf266888b
+0,         42,         42,        1,    67680, 0xd3b30d01
+0,         43,         43,        1,    67680, 0x7c647901
+0,         44,         44,        1,    67680, 0x0838e924
+0,         45,         45,        1,    67680, 0x2d470a56
+0,         46,         46,        1,    67680, 0x3eb99bda
+0,         47,         47,        1,    67680, 0x2b89e9f7
+0,         48,         48,        1,    67680, 0xcc006f93
+0,         49,         49,        1,    67680, 0x967b33e8
+0,         50,         50,        1,    67680, 0xcebbbfd3
+0,         51,         51,        1,    67680, 0x68365b83
+0,         52,         52,        1,    67680, 0xf1b0e536
+0,         53,         53,        1,    67680, 0x292ecc68
+0,         54,         54,        1,    67680, 0x83329d20
+0,         55,         55,        1,    67680, 0xe6ea8f5a
+0,         56,         56,        1,    67680, 0xcef27038
+0,         57,         57,        1,    67680, 0xa30445e4
+0,         58,         58,        1,    67680, 0x61aef9f5
+0,         59,         59,        1,    67680, 0x20abe80c
+0,         60,         60,        1,    67680, 0x7182a479
+0,         61,         61,        1,    67680, 0x56db4ec8
+0,         62,         62,        1,    67680, 0x08c1c3d4
+0,         63,         63,        1,    67680, 0x0d8879ed
+0,         64,         64,        1,    67680, 0x8e4eb9b9
+0,         65,         65,        1,    67680, 0x4629639e
+0,         66,         66,        1,    67680, 0x990bcd94
+0,         67,         67,        1,    67680, 0x2ae85671
+0,         68,         68,        1,    67680, 0xec296417
+0,         69,         69,        1,    67680, 0x41adf8da
+0,         70,         70,        1,    67680, 0xa035008f
+0,         71,         71,        1,    67680, 0xf8845e14
+0,         72,         72,        1,    67680, 0x802e52c4
+0,         73,         73,        1,    67680, 0xa2582b4a
+0,         74,         74,        1,    67680, 0x9ca567d7
+0,         75,         75,        1,    67680, 0x2ec69fac
+0,         76,         76,        1,    67680, 0x3a6d35ea
+0,         77,         77,        1,    67680, 0x9df7b7f6
+0,         78,         78,        1,    67680, 0x2d9dc502
+0,         79,         79,        1,    67680, 0x0ee16604
+0,         80,         80,        1,    67680, 0xb25d31a0
+0,         81,         81,        1,    67680, 0x52c04cb4
+0,         82,         82,        1,    67680, 0xd9ddec28
+0,         83,         83,        1,    67680, 0x1732f444
+0,         84,         84,        1,    67680, 0x19e01da5
+0,         85,         85,        1,    67680, 0x9af109df
+0,         86,         86,        1,    67680, 0xc59ba581
+0,         87,         87,        1,    67680, 0x8daaa58f
+0,         88,         88,        1,    67680, 0xd560a9ae
+0,         89,         89,        1,    67680, 0xe3fe77b4
+0,         90,         90,        1,    67680, 0x2a0e6c20
+0,         91,         91,        1,    67680, 0x9741f744
+0,         92,         92,        1,    67680, 0x8ec827dd
+0,         93,         93,        1,    67680, 0x7d90551f
+0,         94,         94,        1,    67680, 0x4d8f2665
+0,         95,         95,        1,    67680, 0x21e5a86e
+0,         96,         96,        1,    67680, 0x9ba3fe8f
+0,         97,         97,        1,    67680, 0xc84b7e41
+0,         98,         98,        1,    67680, 0x8da743e2
+0,         99,         99,        1,    67680, 0x49c4e00e
+0,        100,        100,        1,    67680, 0x90fc5dab
+0,        101,        101,        1,    67680, 0x9973a011
+0,        102,        102,        1,    67680, 0xfdd58648
+0,        103,        103,        1,    67680, 0xe181e329
+0,        104,        104,        1,    67680, 0xf60065c3
+0,        105,        105,        1,    67680, 0xde9bfc23
+0,        106,        106,        1,    67680, 0x37b9f867
+0,        107,        107,        1,    67680, 0x232ce0e9
+0,        108,        108,        1,    67680, 0x3fde091d
+0,        109,        109,        1,    67680, 0x3f00a465
+0,        110,        110,        1,    67680, 0x882b0042
+0,        111,        111,        1,    67680, 0x1bc3d626
+0,        112,        112,        1,    67680, 0xd15861a7
+0,        113,        113,        1,    67680, 0x056cd815
+0,        114,        114,        1,    67680, 0xe3fc887f
+0,        115,        115,        1,    67680, 0xdbddd03a
+0,        116,        116,        1,    67680, 0xfe6d865f
+0,        117,        117,        1,    67680, 0xbea7f202
+0,        118,        118,        1,    67680, 0x6d4114b9
+0,        119,        119,        1,    67680, 0x47bc93be
+0,        120,        120,        1,    67680, 0xb6136a41
+0,        121,        121,        1,    67680, 0xf0e63ecb
+0,        122,        122,        1,    67680, 0xb014b2a0
+0,        123,        123,        1,    67680, 0xf85a4be5
+0,        124,        124,        1,    67680, 0x21457c25
+0,        125,        125,        1,    67680, 0x75ae6bfb
+0,        126,        126,        1,    67680, 0x7ced988c
+0,        127,        127,        1,    67680, 0x3bf67347
+0,        128,        128,        1,    67680, 0x43e1ace5
+0,        129,        129,        1,    67680, 0xa23f8f45
+0,        130,        130,        1,    67680, 0x29d6cd9e
+0,        131,        131,        1,    67680, 0xad41bd94
+0,        132,        132,        1,    67680, 0x58e131c8
+0,        133,        133,        1,    67680, 0x617debea
+0,        134,        134,        1,    67680, 0x8a9db524
+0,        135,        135,        1,    67680, 0x17264d55
diff --git a/tests/ref/fate/jpeg2000-dcinema b/tests/ref/fate/jpeg2000-dcinema
new file mode 100644
index 0000000..940759a
--- /dev/null
+++ b/tests/ref/fate/jpeg2000-dcinema
@@ -0,0 +1,3 @@
+#tb 0: 1/24
+0,          0,          0,        1, 12441600, 0xf0de508b
+0,          1,          1,        1, 12441600, 0x8e50c249
diff --git a/tests/ref/fate/jv b/tests/ref/fate/jv
new file mode 100644
index 0000000..0d5102d
--- /dev/null
+++ b/tests/ref/fate/jv
@@ -0,0 +1,9 @@
+#tb 0: 2/25
+0,          0,          0,        1,   192000, 0x00000000
+0,          2,          2,        1,   192000, 0x95ece4ea
+0,          3,          3,        1,   192000, 0x9abaf682
+0,          4,          4,        1,   192000, 0x9a93fed6
+0,          5,          5,        1,   192000, 0x112dfade
+0,          6,          6,        1,   192000, 0xb8f3e986
+0,          7,          7,        1,   192000, 0x21daea8e
+0,          8,          8,        1,   192000, 0x5dc1032d
diff --git a/tests/ref/fate/lossless-monkeysaudio b/tests/ref/fate/lossless-monkeysaudio-399
similarity index 100%
rename from tests/ref/fate/lossless-monkeysaudio
rename to tests/ref/fate/lossless-monkeysaudio-399
diff --git a/tests/ref/fate/mpeg2-field-enc b/tests/ref/fate/mpeg2-field-enc
index 079aae4..e302536 100644
--- a/tests/ref/fate/mpeg2-field-enc
+++ b/tests/ref/fate/mpeg2-field-enc
@@ -29,4 +29,3 @@
 0,     129600,     129600,        0,   622080, 0xa45e1d95
 0,     133200,     133200,        0,   622080, 0x6cc61d6c
 0,     136800,     136800,        0,   622080, 0x6983b417
-0,     140400,     140400,        0,   622080, 0x982363c0
diff --git a/tests/ref/fate/msvideo1-8bit b/tests/ref/fate/msvideo1-8bit
index 6e6bc0b..74d54e8 100644
--- a/tests/ref/fate/msvideo1-8bit
+++ b/tests/ref/fate/msvideo1-8bit
@@ -29,4 +29,3 @@
 0,         27,         27,        1,    57600, 0x4ec4a868
 0,         28,         28,        1,    57600, 0x7db370a1
 0,         29,         29,        1,    57600, 0x2b1e52f6
-0,         30,         30,        1,    57600, 0x2141467c
diff --git a/tests/ref/fate/noproxy b/tests/ref/fate/noproxy
new file mode 100644
index 0000000..7707609
--- /dev/null
+++ b/tests/ref/fate/noproxy
@@ -0,0 +1,9 @@
+The pattern "(null)" does not match the hostname domain.com
+The pattern "example.com domain.com" matches the hostname domain.com
+The pattern "example.com other.com" does not match the hostname domain.com
+The pattern "example.com,domain.com" matches the hostname domain.com
+The pattern "example.com,domain.com" does not match the hostname otherdomain.com
+The pattern "example.com, *.domain.com" matches the hostname sub.domain.com
+The pattern "example.com, *.domain.com" matches the hostname domain.com
+The pattern "example.com, .domain.com" matches the hostname domain.com
+The pattern "*" matches the hostname domain.com
diff --git a/tests/ref/fate/nuv-rtjpeg-fh b/tests/ref/fate/nuv-rtjpeg-fh
index 92aa122..71e6bf9 100644
--- a/tests/ref/fate/nuv-rtjpeg-fh
+++ b/tests/ref/fate/nuv-rtjpeg-fh
@@ -1,11 +1,11 @@
 #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,          0,          0,        0,   221184, 0xdaf54f83
+0,         40,         40,        0,   221184, 0xeea3e3b4
+0,         60,         60,        0,   221184, 0x5f1a8525
+0,         80,         80,        0,   221184, 0x950bb170
+0,        100,        100,        0,   221184, 0x6262e94c
+0,        120,        120,        0,   221184, 0x28752197
+0,        140,        140,        0,   221184, 0x0c2811e7
 0,        160,        160,        0,   221184, 0xb2c1a729
 0,        200,        200,        0,   221184, 0x998d6144
 0,        220,        220,        0,   221184, 0xf5d52311
diff --git a/tests/ref/fate/pngparser b/tests/ref/fate/pngparser
new file mode 100644
index 0000000..b481dcd
--- /dev/null
+++ b/tests/ref/fate/pngparser
@@ -0,0 +1,5 @@
+#tb 0: 1/25
+0,          0,          0,        1,   271040, 0xffe62f5f
+0,          1,          1,        1,   271040, 0xcf502f5f
+0,          2,          2,        1,   271040, 0x72612f5f
+0,          3,          3,        1,   271040, 0x41cb2f5f
diff --git a/tests/ref/fate/prores-alpha b/tests/ref/fate/prores-alpha
index 80442fe..97be6cf 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
+0,          0,          0,        0, 16588800, 0x8dcdb600
+0,        100,        100,        0, 16588800, 0x8dcdb600
diff --git a/tests/ref/fate/siff b/tests/ref/fate/siff
deleted file mode 100644
index 8cc6d7f..0000000
--- a/tests/ref/fate/siff
+++ /dev/null
@@ -1,41 +0,0 @@
-#tb 0: 1/12
-#tb 1: 1/22050
-0,          0,          0,        1,   230400, 0x3bd1d731
-1,          0,          0,    22050,    44100, 0xd0a49e09
-0,          1,          1,        1,   230400, 0x9d0774c3
-0,          2,          2,        1,   230400, 0xa0faafe2
-0,          3,          3,        1,   230400, 0x38325309
-0,          4,          4,        1,   230400, 0xe90a1b1e
-0,          5,          5,        1,   230400, 0x8efbc904
-0,          6,          6,        1,   230400, 0x0a8476f3
-0,          7,          7,        1,   230400, 0x5d94587d
-0,          8,          8,        1,   230400, 0x280b905d
-0,          9,          9,        1,   230400, 0x07178dd9
-0,         10,         10,        1,   230400, 0xf52b8db4
-0,         11,         11,        1,   230400, 0x2b70c1dc
-0,         12,         12,        1,   230400, 0x8157a6e9
-1,      22050,      22050,    22050,    44100, 0xf151af4d
-0,         13,         13,        1,   230400, 0xd4a3c357
-0,         14,         14,        1,   230400, 0x703861bb
-0,         15,         15,        1,   230400, 0xa13cf75e
-0,         16,         16,        1,   230400, 0x140e487f
-0,         17,         17,        1,   230400, 0x05cca333
-0,         18,         18,        1,   230400, 0x0506ee2b
-0,         19,         19,        1,   230400, 0xe3e13466
-0,         20,         20,        1,   230400, 0x8a24118c
-0,         21,         21,        1,   230400, 0x22050962
-0,         22,         22,        1,   230400, 0x0f5c8a0d
-0,         23,         23,        1,   230400, 0x3475df44
-0,         24,         24,        1,   230400, 0x65354e06
-1,      44100,      44100,    22050,    44100, 0xecd3cd08
-0,         25,         25,        1,   230400, 0xb9a01978
-0,         26,         26,        1,   230400, 0x15207ee1
-0,         27,         27,        1,   230400, 0x3b214f0b
-0,         28,         28,        1,   230400, 0xf9461bbb
-0,         29,         29,        1,   230400, 0x1469290f
-0,         30,         30,        1,   230400, 0x8ddfd514
-0,         31,         31,        1,   230400, 0x1bffa6a1
-0,         32,         32,        1,   230400, 0x5a04d712
-0,         33,         33,        1,   230400, 0xaa8de439
-0,         34,         34,        1,   230400, 0x610c5439
-0,         35,         35,        1,   230400, 0xd02d3e7c
diff --git a/tests/ref/fate/siff-demux b/tests/ref/fate/siff-demux
new file mode 100644
index 0000000..692e504
--- /dev/null
+++ b/tests/ref/fate/siff-demux
@@ -0,0 +1,112 @@
+#tb 0: 1/12
+#tb 1: 1/22050
+0,          0,          0,        1,    15152, 0x14fc0f1f
+1,          0,          0,    22050,    22050, 0xa7d60d27
+0,          1,          1,        1,    15344, 0x31614bd7
+0,          2,          2,        1,    15163, 0x88c46248
+0,          3,          3,        1,    15152, 0x43c9c0e6
+0,          4,          4,        1,    15341, 0x813f6f01
+0,          5,          5,        1,    15152, 0x7598d01c
+0,          6,          6,        1,    15152, 0x40b5cdb1
+0,          7,          7,        1,    15347, 0xe061c843
+0,          8,          8,        1,    15159, 0x2e3c2242
+0,          9,          9,        1,    15151, 0x7201abc5
+0,         10,         10,        1,    15346, 0xeb5a349e
+0,         11,         11,        1,    15154, 0xda9907c9
+0,         12,         12,        1,    15159, 0x8d4d63b0
+1,      22050,      22050,    22050,    22050, 0xeb11185c
+0,         13,         13,        1,    15337, 0xd988436d
+0,         14,         14,        1,    15162, 0x0b495da7
+0,         15,         15,        1,    15164, 0xd8837439
+0,         16,         16,        1,    15339, 0x7ad372cc
+0,         17,         17,        1,    15161, 0xc45d4590
+0,         18,         18,        1,    15159, 0x5bdd9801
+0,         19,         19,        1,    15335, 0x8e17c83e
+0,         20,         20,        1,    15160, 0x5cdbdc04
+0,         21,         21,        1,    15157, 0xf480a643
+0,         22,         22,        1,    15346, 0x0c61b206
+0,         23,         23,        1,    15160, 0x05d9acfd
+0,         24,         24,        1,    15158, 0xebdc3ac4
+1,      44100,      44100,    22050,    22050, 0xd6dc0e17
+0,         25,         25,        1,    15334, 0xb51fd1b9
+0,         26,         26,        1,    15152, 0x81f74e5c
+0,         27,         27,        1,    15161, 0xafeca32c
+0,         28,         28,        1,    15347, 0x8f5e5874
+0,         29,         29,        1,    15157, 0xdeff353c
+0,         30,         30,        1,    15160, 0x93a19aa0
+0,         31,         31,        1,    15347, 0x94224071
+0,         32,         32,        1,    15153, 0x9982aff5
+0,         33,         33,        1,    15164, 0x044bcf2b
+0,         34,         34,        1,    15347, 0x40aca6e9
+0,         35,         35,        1,    15160, 0xf820e2c7
+0,         36,         36,        1,    15154, 0x457832b5
+1,      66150,      66150,    22050,    22050, 0x020412c4
+0,         37,         37,        1,    15334, 0xbb1704f0
+0,         38,         38,        1,    15156, 0xc0672ed1
+0,         39,         39,        1,    15159, 0x9a82c7c1
+0,         40,         40,        1,    15338, 0x03857aae
+0,         41,         41,        1,    15158, 0xe6177548
+0,         42,         42,        1,    15159, 0xf8ecafc4
+0,         43,         43,        1,    15345, 0x0a10882e
+0,         44,         44,        1,    15161, 0xec4339fb
+0,         45,         45,        1,    15157, 0x071935a2
+0,         46,         46,        1,    15340, 0x68aad418
+0,         47,         47,        1,    15151, 0x891bc3fe
+0,         48,         48,        1,    15153, 0xf522e54c
+1,      88200,      88200,    22050,    22050, 0x5d9606ae
+0,         49,         49,        1,    15346, 0x5a018842
+0,         50,         50,        1,    15164, 0x6842ac50
+0,         51,         51,        1,    15156, 0x32369159
+0,         52,         52,        1,    15347, 0xf5be31aa
+0,         53,         53,        1,    15157, 0xd2da28bd
+0,         54,         54,        1,    15152, 0x389feda6
+0,         55,         55,        1,    15345, 0x69187603
+0,         56,         56,        1,    15154, 0x5dc60365
+0,         57,         57,        1,    15159, 0x8c811193
+0,         58,         58,        1,    15344, 0x3db4bf13
+0,         59,         59,        1,    15156, 0xf729ebe1
+0,         60,         60,        1,    15162, 0xf10a4ce5
+1,     110250,     110250,    22050,    22050, 0x08171bca
+0,         61,         61,        1,    15345, 0x749b0604
+0,         62,         62,        1,    15160, 0xfe3bbbce
+0,         63,         63,        1,    15160, 0x6dcc4b85
+0,         64,         64,        1,    15337, 0xab87dd97
+0,         65,         65,        1,    15163, 0x1ce60db8
+0,         66,         66,        1,    15164, 0xfc4a2002
+0,         67,         67,        1,    15345, 0x9108e072
+0,         68,         68,        1,    15153, 0x83fc9055
+0,         69,         69,        1,    15155, 0xa1101e1a
+0,         70,         70,        1,    15343, 0x6418f0e9
+0,         71,         71,        1,    15157, 0x8c743049
+0,         72,         72,        1,    15153, 0x9c0e33eb
+1,     132300,     132300,    22050,    22050, 0xd43b0cf9
+0,         73,         73,        1,    15337, 0x64bae0b6
+0,         74,         74,        1,    15162, 0x5f6b91d5
+0,         75,         75,        1,    15162, 0x44e5dd3d
+0,         76,         76,        1,    15342, 0x968dc44c
+0,         77,         77,        1,    15158, 0x0e706c4d
+0,         78,         78,        1,    15153, 0xa7d2199a
+0,         79,         79,        1,    15345, 0x834d0f2e
+0,         80,         80,        1,    15163, 0x3d5d38c3
+0,         81,         81,        1,    15151, 0xf7d49515
+0,         82,         82,        1,    15337, 0x5f362f2a
+0,         83,         83,        1,    15162, 0xea87d814
+0,         84,         84,        1,    15164, 0xeb0a2662
+1,     154350,     154350,    22050,    22050, 0x486d1bc2
+0,         85,         85,        1,    15340, 0x772109e6
+0,         86,         86,        1,    15156, 0x9459cda5
+0,         87,         87,        1,    15152, 0x4f174e2d
+0,         88,         88,        1,    15343, 0x10d42a59
+0,         89,         89,        1,    15162, 0xd65ec2ec
+0,         90,         90,        1,    15156, 0x1e382319
+0,         91,         91,        1,    15335, 0xec904c2a
+0,         92,         92,        1,    15161, 0x56d49e44
+0,         93,         93,        1,    15154, 0x51d02cd0
+0,         94,         94,        1,    15340, 0xec3e14ee
+0,         95,         95,        1,    15160, 0xe43b5305
+0,         96,         96,        1,    15156, 0x8f2876a5
+1,     176400,     176400,    22050,    22050, 0x5c5508d3
+0,         97,         97,        1,    15340, 0xb26a9059
+0,         98,         98,        1,    15156, 0xf9570ec0
+0,         99,         99,        1,    15151, 0x862ffa1f
+1,     198450,     198450,     1984,     1984, 0x9cb4dfb7
diff --git a/tests/ref/fate/srtp b/tests/ref/fate/srtp
new file mode 100644
index 0000000..687a59f
--- /dev/null
+++ b/tests/ref/fate/srtp
@@ -0,0 +1,12 @@
+80e0123412345678123456780102030405
+Decrypted content matches input
+Decrypted content matches input
+Decrypted content matches input
+81c90007123456788765432100000000000012340000069ec73069ba000001fd
+Decrypted content matches input
+Decrypted content matches input
+Decrypted content matches input
+80e0123412345678123456780102030405
+81c90007123456788765432100000000000012340000069ec73069ba000001fd
+80e0123412345678123456780102030405
+81c90007123456788765432100000000000012340000069ec73069ba000001fd
diff --git a/tests/ref/fate/vp3-coeff-level64 b/tests/ref/fate/theora-coeff-level64
similarity index 100%
rename from tests/ref/fate/vp3-coeff-level64
rename to tests/ref/fate/theora-coeff-level64
diff --git a/tests/ref/fate/timefilter b/tests/ref/fate/timefilter
new file mode 100644
index 0000000..57c1209
--- /dev/null
+++ b/tests/ref/fate/timefilter
@@ -0,0 +1,6 @@
+ [0.800000 0.000800  0.000000] [1.021025 0.998922  0.000000] [1.021025 0.998922  0.000000] [1.021025 0.998922  0.000000]
+ [0.001003 0.000000  0.004341] [0.041562 0.000996  0.045245] [0.081175 0.002874  0.074431] [0.118380 0.006568  0.108913]
+ [0.001003 0.000000  0.039073] [0.013619 0.000455  0.224390] [0.041562 0.000996  0.407205] [0.068719 0.002305  0.600848]
+ [0.001003 0.000000  0.212729] [0.022518 0.000060  0.941262] [0.015889 0.000507  1.391585] [0.041562 0.000996  2.217003]
+ [0.001003 0.000000  0.976818] [0.014412 0.000021  2.712350] [0.013691 0.000370  4.648765] [0.018915 0.000542  6.709646]
+ [0.001003 0.000000  4.172097] [0.010677 0.000007  7.809261] [0.018915 0.000032 14.578784] [0.013619 0.000387 20.628496]
diff --git a/tests/ref/fate/tscc2 b/tests/ref/fate/tscc2
new file mode 100644
index 0000000..ad71b82
--- /dev/null
+++ b/tests/ref/fate/tscc2
@@ -0,0 +1,33 @@
+#tb 0: 1/24
+0,          0,          0,        1,   230400, 0x7a2103c0
+0,          1,          1,        1,   230400, 0xd381c279
+0,          2,          2,        1,   230400, 0xd381c279
+0,          3,          3,        1,   230400, 0x110aec27
+0,          4,          4,        1,   230400, 0x4be67ee7
+0,          5,          5,        1,   230400, 0xd87fe4b4
+0,          6,          6,        1,   230400, 0xd87fe4b4
+0,          7,          7,        1,   230400, 0x9bc6a398
+0,          8,          8,        1,   230400, 0xd67d92db
+0,          9,          9,        1,   230400, 0x3df6559e
+0,         10,         10,        1,   230400, 0x3df6559e
+0,         11,         11,        1,   230400, 0x2136ff25
+0,         12,         12,        1,   230400, 0x94573fe6
+0,         13,         13,        1,   230400, 0xbf67d3f5
+0,         14,         14,        1,   230400, 0xbf67d3f5
+0,         15,         15,        1,   230400, 0x2592b5cf
+0,         16,         16,        1,   230400, 0x5b23cd93
+0,         17,         17,        1,   230400, 0x9b76d079
+0,         18,         18,        1,   230400, 0x9b76d079
+0,         19,         19,        1,   230400, 0x771a017e
+0,         20,         20,        1,   230400, 0xacfee1d0
+0,         21,         21,        1,   230400, 0x6b9ff4eb
+0,         22,         22,        1,   230400, 0x6b9ff4eb
+0,         23,         23,        1,   230400, 0xbaf643e1
+0,         24,         24,        1,   230400, 0x052efe59
+0,         25,         25,        1,   230400, 0xd751f901
+0,         26,         26,        1,   230400, 0xd751f901
+0,         27,         27,        1,   230400, 0x6f94e11f
+0,         28,         28,        1,   230400, 0x17eeabb9
+0,         29,         29,        1,   230400, 0x3733a035
+0,         30,         30,        1,   230400, 0x3733a035
+0,         31,         31,        1,   230400, 0xb0829f45
diff --git a/tests/ref/fate/vb b/tests/ref/fate/vb
new file mode 100644
index 0000000..336d426
--- /dev/null
+++ b/tests/ref/fate/vb
@@ -0,0 +1,37 @@
+#tb 0: 1/12
+0,          0,          0,        1,   230400, 0x3bd1d731
+0,          1,          1,        1,   230400, 0x9d0774c3
+0,          2,          2,        1,   230400, 0xa0faafe2
+0,          3,          3,        1,   230400, 0x38325309
+0,          4,          4,        1,   230400, 0xe90a1b1e
+0,          5,          5,        1,   230400, 0x8efbc904
+0,          6,          6,        1,   230400, 0x0a8476f3
+0,          7,          7,        1,   230400, 0x5d94587d
+0,          8,          8,        1,   230400, 0x280b905d
+0,          9,          9,        1,   230400, 0x07178dd9
+0,         10,         10,        1,   230400, 0xf52b8db4
+0,         11,         11,        1,   230400, 0x2b70c1dc
+0,         12,         12,        1,   230400, 0x8157a6e9
+0,         13,         13,        1,   230400, 0xd4a3c357
+0,         14,         14,        1,   230400, 0x703861bb
+0,         15,         15,        1,   230400, 0xa13cf75e
+0,         16,         16,        1,   230400, 0x140e487f
+0,         17,         17,        1,   230400, 0x05cca333
+0,         18,         18,        1,   230400, 0x0506ee2b
+0,         19,         19,        1,   230400, 0xe3e13466
+0,         20,         20,        1,   230400, 0x8a24118c
+0,         21,         21,        1,   230400, 0x22050962
+0,         22,         22,        1,   230400, 0x0f5c8a0d
+0,         23,         23,        1,   230400, 0x3475df44
+0,         24,         24,        1,   230400, 0x65354e06
+0,         25,         25,        1,   230400, 0xb9a01978
+0,         26,         26,        1,   230400, 0x15207ee1
+0,         27,         27,        1,   230400, 0x3b214f0b
+0,         28,         28,        1,   230400, 0xf9461bbb
+0,         29,         29,        1,   230400, 0x1469290f
+0,         30,         30,        1,   230400, 0x8ddfd514
+0,         31,         31,        1,   230400, 0x1bffa6a1
+0,         32,         32,        1,   230400, 0x5a04d712
+0,         33,         33,        1,   230400, 0xaa8de439
+0,         34,         34,        1,   230400, 0x610c5439
+0,         35,         35,        1,   230400, 0xd02d3e7c
diff --git a/tests/ref/fate/vc1_sa10143 b/tests/ref/fate/vc1_sa10143
index a008356..6a5137f 100644
--- a/tests/ref/fate/vc1_sa10143
+++ b/tests/ref/fate/vc1_sa10143
@@ -1,31 +1,31 @@
 #tb 0: 1/25
 0,          0,          0,        1,   518400, 0x89407f55
-0,          2,          2,        1,   518400, 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, 0x8611849c
+0,          3,          3,        1,   518400, 0x0e69ff59
+0,          4,          4,        1,   518400, 0xf31adb03
+0,          5,          5,        1,   518400, 0x1a5b6a69
+0,          6,          6,        1,   518400, 0x6ae6232e
+0,          7,          7,        1,   518400, 0x9a4e3c54
+0,          8,          8,        1,   518400, 0xe5852b45
+0,          9,          9,        1,   518400, 0x0fcfeebc
+0,         10,         10,        1,   518400, 0x06e22dc3
+0,         11,         11,        1,   518400, 0x9d79df09
+0,         12,         12,        1,   518400, 0xcb2c716f
+0,         13,         13,        1,   518400, 0x638a8746
+0,         14,         14,        1,   518400, 0xf7032efd
+0,         15,         15,        1,   518400, 0x306f6cef
+0,         16,         16,        1,   518400, 0xe83d2518
+0,         17,         17,        1,   518400, 0x49ab5bf5
+0,         18,         18,        1,   518400, 0x6b336b6f
+0,         19,         19,        1,   518400, 0x95ae00c9
+0,         20,         20,        1,   518400, 0x68ddb64f
+0,         21,         21,        1,   518400, 0x5205ea68
+0,         22,         22,        1,   518400, 0xb088e617
+0,         23,         23,        1,   518400, 0xa3217616
+0,         24,         24,        1,   518400, 0x1723bc53
+0,         25,         25,        1,   518400, 0xf024872a
+0,         26,         26,        1,   518400, 0x2e81a8bb
+0,         27,         27,        1,   518400, 0xa3a2418e
+0,         28,         28,        1,   518400, 0xb7beffed
+0,         29,         29,        1,   518400, 0x50fb6c94
+0,         30,         30,        1,   518400, 0x5584bb40
diff --git a/tests/ref/fate/vp9-00-quantizer-00 b/tests/ref/fate/vp9-00-quantizer-00
new file mode 100644
index 0000000..a6e701e
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-00
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, c3fbb7abbdb5bd4ed4a7e34768c17df1
+0,         33,         33,        0,   152064, 08203c2595bdb2d58ead6f921345d699
diff --git a/tests/ref/fate/vp9-00-quantizer-01 b/tests/ref/fate/vp9-00-quantizer-01
new file mode 100644
index 0000000..0d22d2b
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-01
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, f041b870cf9236d5f22e2b08a77d5958
+0,         33,         33,        0,   152064, cbdb7526986ae15592891488c9afc84c
diff --git a/tests/ref/fate/vp9-00-quantizer-02 b/tests/ref/fate/vp9-00-quantizer-02
new file mode 100644
index 0000000..023caf8
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-02
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 98048cfdb4af5059f4085c5acc94ef8f
+0,         33,         33,        0,   152064, 8160183e1eed1d0af4427be216b8b9f7
diff --git a/tests/ref/fate/vp9-00-quantizer-03 b/tests/ref/fate/vp9-00-quantizer-03
new file mode 100644
index 0000000..5abb9ee
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-03
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 15c548208f5eda243a151a42f4d64855
+0,         33,         33,        0,   152064, e96d463dc8e9b27b1c2ec40f77eee6ef
diff --git a/tests/ref/fate/vp9-00-quantizer-04 b/tests/ref/fate/vp9-00-quantizer-04
new file mode 100644
index 0000000..1be91be
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-04
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 928c64a0747ac57ab50c1520d694fea7
+0,         33,         33,        0,   152064, a6f6daa293231e95ef30ed168f582c84
diff --git a/tests/ref/fate/vp9-00-quantizer-05 b/tests/ref/fate/vp9-00-quantizer-05
new file mode 100644
index 0000000..9e359b3
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-05
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 082460718b7d7046c8fb23184b7f71ca
+0,         33,         33,        0,   152064, 4a41aad51c40a92df72333e13f47d3fe
diff --git a/tests/ref/fate/vp9-00-quantizer-06 b/tests/ref/fate/vp9-00-quantizer-06
new file mode 100644
index 0000000..e984311
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-06
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, cfca1bed96ff62a69b2d841fda01c6b9
+0,         33,         33,        0,   152064, 9b4d61f1b998745c108f8eb67925e03d
diff --git a/tests/ref/fate/vp9-00-quantizer-07 b/tests/ref/fate/vp9-00-quantizer-07
new file mode 100644
index 0000000..b1e6b54
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-07
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 6f5122064bead9d9882bec2698a6ed9c
+0,         33,         33,        0,   152064, 50dae67d2f57a76eece210dee8b6df9e
diff --git a/tests/ref/fate/vp9-00-quantizer-08 b/tests/ref/fate/vp9-00-quantizer-08
new file mode 100644
index 0000000..6bb9687
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-08
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, eb3d6985fcda5d93dd62d53354e8a093
+0,         33,         33,        0,   152064, 5b1f5b7780b4cafe1f75e56a0b526643
diff --git a/tests/ref/fate/vp9-00-quantizer-09 b/tests/ref/fate/vp9-00-quantizer-09
new file mode 100644
index 0000000..32055ca
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-09
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, d7ccaf28c59875fe91983def5490d2b1
+0,         33,         33,        0,   152064, bd98fe9492054826748de840b4495309
diff --git a/tests/ref/fate/vp9-00-quantizer-10 b/tests/ref/fate/vp9-00-quantizer-10
new file mode 100644
index 0000000..9f738a3
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-10
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 20dda6231f9801c9c237c6d09d9939b6
+0,         33,         33,        0,   152064, 23c91e93807fb9a4ed5bd5bdd449d99f
diff --git a/tests/ref/fate/vp9-00-quantizer-11 b/tests/ref/fate/vp9-00-quantizer-11
new file mode 100644
index 0000000..3449ea9
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-11
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 960833315ebcdee97f46c4d98d0f3fef
+0,         33,         33,        0,   152064, eec40507d17b64b7895a61cb87b2096a
diff --git a/tests/ref/fate/vp9-00-quantizer-12 b/tests/ref/fate/vp9-00-quantizer-12
new file mode 100644
index 0000000..1494fd9
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-12
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 6533224d3b6ba1ec0dd973bbe56c6349
+0,         33,         33,        0,   152064, 12ceadc6d28327a24a75f8c40b6084d1
diff --git a/tests/ref/fate/vp9-00-quantizer-13 b/tests/ref/fate/vp9-00-quantizer-13
new file mode 100644
index 0000000..1a75e63
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-13
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 7268de6756014f79a56dcf010c52a97f
+0,         33,         33,        0,   152064, 9e39e9b0e2295b8460dfa05f44762771
diff --git a/tests/ref/fate/vp9-00-quantizer-14 b/tests/ref/fate/vp9-00-quantizer-14
new file mode 100644
index 0000000..b614bd7
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-14
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 57e9e333c641fa952f7485b788df225a
+0,         33,         33,        0,   152064, 551f0cea83dcdf4540c3983736757874
diff --git a/tests/ref/fate/vp9-00-quantizer-15 b/tests/ref/fate/vp9-00-quantizer-15
new file mode 100644
index 0000000..e092a9a
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-15
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 17a0a2842856b9e89aede237648d5dda
+0,         33,         33,        0,   152064, c9fcade888a38621bebe3d4b41664245
diff --git a/tests/ref/fate/vp9-00-quantizer-16 b/tests/ref/fate/vp9-00-quantizer-16
new file mode 100644
index 0000000..159debc
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-16
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 6cc2089e9a3d352fe10b59ccd935c677
+0,         33,         33,        0,   152064, d165bf7b9cb901e121a65038758d8613
diff --git a/tests/ref/fate/vp9-00-quantizer-17 b/tests/ref/fate/vp9-00-quantizer-17
new file mode 100644
index 0000000..bc89173
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-17
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, bc80511c83162c09661f155cd29f6dd8
+0,         33,         33,        0,   152064, a62f1cbdb3f86d2fb4c880cfd917def5
diff --git a/tests/ref/fate/vp9-00-quantizer-18 b/tests/ref/fate/vp9-00-quantizer-18
new file mode 100644
index 0000000..a05d563
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-18
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, b2d350f6faa41cb50c2e8a9907d0f4a5
+0,         33,         33,        0,   152064, 39b4380d16bc8e093dd4dba475175fb3
diff --git a/tests/ref/fate/vp9-00-quantizer-19 b/tests/ref/fate/vp9-00-quantizer-19
new file mode 100644
index 0000000..43c1c55
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-19
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 441e09be3c15fcb240afd74bb7a10a72
+0,         33,         33,        0,   152064, 32ae5dac876ca5d5ae6ab7c74f4dc25d
diff --git a/tests/ref/fate/vp9-00-quantizer-20 b/tests/ref/fate/vp9-00-quantizer-20
new file mode 100644
index 0000000..95e5216
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-20
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 7786eb9944dba0553e129133523a98c1
+0,         33,         33,        0,   152064, 206d888f8453427f10a40aa8bf5f6df0
diff --git a/tests/ref/fate/vp9-00-quantizer-21 b/tests/ref/fate/vp9-00-quantizer-21
new file mode 100644
index 0000000..4ddd9fb
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-21
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, aab95e195be71feca050a839d7b3154d
+0,         33,         33,        0,   152064, 02a05d699bbbdc477e34bb0dad9f0391
diff --git a/tests/ref/fate/vp9-00-quantizer-22 b/tests/ref/fate/vp9-00-quantizer-22
new file mode 100644
index 0000000..bb9d945
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-22
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 41f853c3ee2d4611b645cc643d82e287
+0,         33,         33,        0,   152064, 1c240c653110ff8609ca0f0287a6496d
diff --git a/tests/ref/fate/vp9-00-quantizer-23 b/tests/ref/fate/vp9-00-quantizer-23
new file mode 100644
index 0000000..968dfc1
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-23
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, bc5b07369df50c8f97ce1a377fe513cf
+0,         33,         33,        0,   152064, ce62ddb4f3e305d0f8587ae8bb44cc79
diff --git a/tests/ref/fate/vp9-00-quantizer-24 b/tests/ref/fate/vp9-00-quantizer-24
new file mode 100644
index 0000000..8f087c5
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-24
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 982d54041221c977b6f0e37a9236cc76
+0,         33,         33,        0,   152064, 57631e7f13f645c834e2944ebfd6d40e
diff --git a/tests/ref/fate/vp9-00-quantizer-25 b/tests/ref/fate/vp9-00-quantizer-25
new file mode 100644
index 0000000..a14840b
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-25
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, b0fb55f3f2f56b3d27038e83c10123ce
+0,         33,         33,        0,   152064, 9fcac3becdcc2d30d778a55eca4c2018
diff --git a/tests/ref/fate/vp9-00-quantizer-26 b/tests/ref/fate/vp9-00-quantizer-26
new file mode 100644
index 0000000..0ccb749
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-26
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 4f645e0f354da77b9e2f2a6753c361da
+0,         33,         33,        0,   152064, b7542998ec298273ca662bc9b658d10e
diff --git a/tests/ref/fate/vp9-00-quantizer-27 b/tests/ref/fate/vp9-00-quantizer-27
new file mode 100644
index 0000000..f8c5df7
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-27
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 6edc96a3747cad43828397045764206e
+0,         33,         33,        0,   152064, 5fbc65d20fdca1abd69079851ce676d3
diff --git a/tests/ref/fate/vp9-00-quantizer-28 b/tests/ref/fate/vp9-00-quantizer-28
new file mode 100644
index 0000000..588ef1c
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-28
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 5db3e910e70da38bb91d01d73acc33dd
+0,         33,         33,        0,   152064, b920ee7f7e61b7fdf9f44b1f738d0292
diff --git a/tests/ref/fate/vp9-00-quantizer-29 b/tests/ref/fate/vp9-00-quantizer-29
new file mode 100644
index 0000000..583cfa0
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-29
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 3cb3e310be5305077efa6216f6f10654
+0,         33,         33,        0,   152064, 692d3e098af5978fe1a898ebc1a66a7a
diff --git a/tests/ref/fate/vp9-00-quantizer-30 b/tests/ref/fate/vp9-00-quantizer-30
new file mode 100644
index 0000000..45b2c69
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-30
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, e3b3cea66ea38c5dfba1aa73bb4c611d
+0,         33,         33,        0,   152064, 42bb3e54b19c3f4c4f7ee3a6ba012e19
diff --git a/tests/ref/fate/vp9-00-quantizer-31 b/tests/ref/fate/vp9-00-quantizer-31
new file mode 100644
index 0000000..22c5749
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-31
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 2523e9ecfd3781eafcd7da192dc105e9
+0,         33,         33,        0,   152064, 6d5feea012b9a1f51fc643633e728764
diff --git a/tests/ref/fate/vp9-00-quantizer-32 b/tests/ref/fate/vp9-00-quantizer-32
new file mode 100644
index 0000000..8103d96
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-32
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 0a0305eba36500ebf6cc6cc0f01f5a3b
+0,         33,         33,        0,   152064, 2c76bcd6763467f9057a726fbcf50ab1
diff --git a/tests/ref/fate/vp9-00-quantizer-33 b/tests/ref/fate/vp9-00-quantizer-33
new file mode 100644
index 0000000..ab7c061
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-33
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, c68433e0e94047c220be9b629334f744
+0,         33,         33,        0,   152064, fcfa4dff7a39bc9c5e315849ecbb46ea
diff --git a/tests/ref/fate/vp9-00-quantizer-34 b/tests/ref/fate/vp9-00-quantizer-34
new file mode 100644
index 0000000..d5719ec
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-34
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, ad9dc2f912c137b014a33e2792c88a25
+0,         33,         33,        0,   152064, 11221ee4ea5c776f43af68756682cd5a
diff --git a/tests/ref/fate/vp9-00-quantizer-35 b/tests/ref/fate/vp9-00-quantizer-35
new file mode 100644
index 0000000..623d62c
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-35
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 75031f898cccf303a64ab46b1f815389
+0,         33,         33,        0,   152064, a4fc864e7fbc470dfcab6207e0eea152
diff --git a/tests/ref/fate/vp9-00-quantizer-36 b/tests/ref/fate/vp9-00-quantizer-36
new file mode 100644
index 0000000..e6cde45
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-36
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, c7824af009fde6cafdd8d39fae6bb6cf
+0,         33,         33,        0,   152064, 516a82d5fc4dfa3daf713ed2ec36041b
diff --git a/tests/ref/fate/vp9-00-quantizer-37 b/tests/ref/fate/vp9-00-quantizer-37
new file mode 100644
index 0000000..b4c0134
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-37
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a2e5c820fd9733e18f9349fb658ca281
+0,         33,         33,        0,   152064, fb23e0bc64728a492a33d985032f21b8
diff --git a/tests/ref/fate/vp9-00-quantizer-38 b/tests/ref/fate/vp9-00-quantizer-38
new file mode 100644
index 0000000..89e45f9
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-38
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 8347bfb891317e89ef66781d6c28e24f
+0,         33,         33,        0,   152064, a5722f824d32deac042513a1a7dcdcd0
diff --git a/tests/ref/fate/vp9-00-quantizer-39 b/tests/ref/fate/vp9-00-quantizer-39
new file mode 100644
index 0000000..ed5add1
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-39
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 018968f97fac3bdff146cf22c1da5ef0
+0,         33,         33,        0,   152064, ca8b09b01e5132183395e238f1c7901e
diff --git a/tests/ref/fate/vp9-00-quantizer-40 b/tests/ref/fate/vp9-00-quantizer-40
new file mode 100644
index 0000000..8ac2b91
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-40
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 792660f6589ad5340be4bd0554435866
+0,         33,         33,        0,   152064, 68c84c8a15d679e0a73678b93215c62c
diff --git a/tests/ref/fate/vp9-00-quantizer-41 b/tests/ref/fate/vp9-00-quantizer-41
new file mode 100644
index 0000000..ccd735d
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-41
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a456bdfc6c1c07b4cb3a3848843743b9
+0,         33,         33,        0,   152064, fe41a12b8cb6bc5667ba2179e076f3b0
diff --git a/tests/ref/fate/vp9-00-quantizer-42 b/tests/ref/fate/vp9-00-quantizer-42
new file mode 100644
index 0000000..3955ebf
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-42
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, f016dd8431694d989700fb1ba71a5b2d
+0,         33,         33,        0,   152064, e89c3c5b935157b40f2fb0ab92415828
diff --git a/tests/ref/fate/vp9-00-quantizer-43 b/tests/ref/fate/vp9-00-quantizer-43
new file mode 100644
index 0000000..e458266
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-43
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 7b8ab82625f3006bac89d4fb5197e71c
+0,         33,         33,        0,   152064, 18bd3716045563dfba2c72b640b3274b
diff --git a/tests/ref/fate/vp9-00-quantizer-44 b/tests/ref/fate/vp9-00-quantizer-44
new file mode 100644
index 0000000..178c224
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-44
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 66fde04d8320c750e56406feefd29979
+0,         33,         33,        0,   152064, f9d01d8fc1722ec345e624e14b404215
diff --git a/tests/ref/fate/vp9-00-quantizer-45 b/tests/ref/fate/vp9-00-quantizer-45
new file mode 100644
index 0000000..4ab45e2
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-45
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, cc97597b015896d73f3e60e7ae44c4da
+0,         33,         33,        0,   152064, fea98bc508f92135641ab99762444b14
diff --git a/tests/ref/fate/vp9-00-quantizer-46 b/tests/ref/fate/vp9-00-quantizer-46
new file mode 100644
index 0000000..df6c212
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-46
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 79ed95c741178bb3c0954f1f6f8e21a3
+0,         33,         33,        0,   152064, f02a06a5e2b5b7619c9a52c5bea0564d
diff --git a/tests/ref/fate/vp9-00-quantizer-47 b/tests/ref/fate/vp9-00-quantizer-47
new file mode 100644
index 0000000..7e6476e
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-47
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 9b98e948b8c2a822f21bd8419e6f4410
+0,         33,         33,        0,   152064, 491382d68c16c2a3c6f1746598bc4a97
diff --git a/tests/ref/fate/vp9-00-quantizer-48 b/tests/ref/fate/vp9-00-quantizer-48
new file mode 100644
index 0000000..22a3ce2
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-48
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, f0f095b0edae7262f44d7ed7ef84ded4
+0,         33,         33,        0,   152064, 0e833889ccac81d60251007d1baf6500
diff --git a/tests/ref/fate/vp9-00-quantizer-49 b/tests/ref/fate/vp9-00-quantizer-49
new file mode 100644
index 0000000..34f74a6
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-49
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 6c1b7b7827617fb9b8417aca2cfdbcaa
+0,         33,         33,        0,   152064, 4c1fc8a89297fdcf79f0faabd42b8684
diff --git a/tests/ref/fate/vp9-00-quantizer-50 b/tests/ref/fate/vp9-00-quantizer-50
new file mode 100644
index 0000000..e9d40af
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-50
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, ca6142db68463487bc28c888ab38476c
+0,         33,         33,        0,   152064, 02a71153ec70f569524c3d814cb62f86
diff --git a/tests/ref/fate/vp9-00-quantizer-51 b/tests/ref/fate/vp9-00-quantizer-51
new file mode 100644
index 0000000..3a86326
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-51
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, eece2627df1ddf0872256eb92352e179
+0,         33,         33,        0,   152064, 0ee9f221246ad747250e4b5e8ba586e2
diff --git a/tests/ref/fate/vp9-00-quantizer-52 b/tests/ref/fate/vp9-00-quantizer-52
new file mode 100644
index 0000000..6d976d8
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-52
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 7290039d974c4e50db9d69f9864bcdbe
+0,         33,         33,        0,   152064, 264765de9d02503038a4da54133b9f85
diff --git a/tests/ref/fate/vp9-00-quantizer-53 b/tests/ref/fate/vp9-00-quantizer-53
new file mode 100644
index 0000000..5f2ab99
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-53
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 917af24da66f143a56a01eb2c2254285
+0,         33,         33,        0,   152064, 45a05d3bc644420519619e4115662a70
diff --git a/tests/ref/fate/vp9-00-quantizer-54 b/tests/ref/fate/vp9-00-quantizer-54
new file mode 100644
index 0000000..38c2496
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-54
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 6fea2820bb10a9dec9add4d2452b01f5
+0,         33,         33,        0,   152064, 74675169a4bfc2ff5463c4db5d85a79f
diff --git a/tests/ref/fate/vp9-00-quantizer-55 b/tests/ref/fate/vp9-00-quantizer-55
new file mode 100644
index 0000000..c50fdd4
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-55
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 11e5d196f6537fb7d85988d90195e556
+0,         33,         33,        0,   152064, 8536106795f7c93c5a43a11493527469
diff --git a/tests/ref/fate/vp9-00-quantizer-56 b/tests/ref/fate/vp9-00-quantizer-56
new file mode 100644
index 0000000..80bff69
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-56
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 40839b7a3a40ec10f96b8a75224f646d
+0,         33,         33,        0,   152064, 11408dd73e8c45ddaab99f5c9650102b
diff --git a/tests/ref/fate/vp9-00-quantizer-57 b/tests/ref/fate/vp9-00-quantizer-57
new file mode 100644
index 0000000..38783aa
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-57
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, d0e9fa03dd48da4592ebaadb4e3794e0
+0,         33,         33,        0,   152064, 5172e29b1e04cd543833d6a68aab297c
diff --git a/tests/ref/fate/vp9-00-quantizer-58 b/tests/ref/fate/vp9-00-quantizer-58
new file mode 100644
index 0000000..80ead0f
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-58
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, bef4a27d460e7697e038fe6f1c8bd597
+0,         33,         33,        0,   152064, 124674686cafc5f2ff5bc7ea412b8f3b
diff --git a/tests/ref/fate/vp9-00-quantizer-59 b/tests/ref/fate/vp9-00-quantizer-59
new file mode 100644
index 0000000..dbc6a5d
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-59
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, ae9d99e9d16ef20073300559566844ae
+0,         33,         33,        0,   152064, da9405e5a6bfe4ed18d927ba2004008e
diff --git a/tests/ref/fate/vp9-00-quantizer-60 b/tests/ref/fate/vp9-00-quantizer-60
new file mode 100644
index 0000000..c71532e
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-60
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 9e66bb8e1b5e206ea4afe4bf2d335ac5
+0,         33,         33,        0,   152064, 092b74c905c12c1e87e90f5a79857736
diff --git a/tests/ref/fate/vp9-00-quantizer-61 b/tests/ref/fate/vp9-00-quantizer-61
new file mode 100644
index 0000000..b453341
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-61
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, d062dc6be246c8042744018765ef50a8
+0,         33,         33,        0,   152064, 45fd9cbacb6a91060a7e49a58a85869d
diff --git a/tests/ref/fate/vp9-00-quantizer-62 b/tests/ref/fate/vp9-00-quantizer-62
new file mode 100644
index 0000000..1efa26f
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-62
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 62f7e42fe653e81c5a65a25389e045b5
+0,         33,         33,        0,   152064, cb0cdd0b25689e0a43328550011d960d
diff --git a/tests/ref/fate/vp9-00-quantizer-63 b/tests/ref/fate/vp9-00-quantizer-63
new file mode 100644
index 0000000..f473884
--- /dev/null
+++ b/tests/ref/fate/vp9-00-quantizer-63
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 8467643dceff827e04acd82eeff1d1b0
+0,         33,         33,        0,   152064, c786f49d66f4dfd685dea9605821a19f
diff --git a/tests/ref/fate/vp9-01-sharpness-1 b/tests/ref/fate/vp9-01-sharpness-1
new file mode 100644
index 0000000..406bd61
--- /dev/null
+++ b/tests/ref/fate/vp9-01-sharpness-1
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a2e5c820fd9733e18f9349fb658ca281
+0,         33,         33,        0,   152064, aa20a75be3a316193496706c9f760d08
+0,         66,         66,        0,   152064, 95567be97a64d3c9efe45f2524116a2e
+0,        100,        100,        0,   152064, 219e86cd6b3cca312856eead21776b1c
+0,        133,        133,        0,   152064, 4a67fd359ca362398e97c15eb018a2bb
+0,        166,        166,        0,   152064, 9916d4e359274d690827f0eb22547423
+0,        200,        200,        0,   152064, a07785b52561150c48f1a8eff89d5d75
+0,        233,        233,        0,   152064, a3382a92982953dfa20018e5ac975b51
+0,        266,        266,        0,   152064, 911836989ca7b148438aa3ec7fc7e303
+0,        300,        300,        0,   152064, 5627b981e3fc9e4401d35d3a5ab25917
diff --git a/tests/ref/fate/vp9-01-sharpness-2 b/tests/ref/fate/vp9-01-sharpness-2
new file mode 100644
index 0000000..78d7e91
--- /dev/null
+++ b/tests/ref/fate/vp9-01-sharpness-2
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a2e5c820fd9733e18f9349fb658ca281
+0,         33,         33,        0,   152064, cd94572239817ae7c9b07de739c3272b
+0,         66,         66,        0,   152064, 383cf752d457e122b5ff49d08960208e
+0,        100,        100,        0,   152064, 1c0a6ec9cd3ce29b8b004e7526f1b07e
+0,        133,        133,        0,   152064, 91c42a8a108d67947cabfc2a5a80df66
+0,        166,        166,        0,   152064, 08c57fc1f3fec0305883315a66c714d1
+0,        200,        200,        0,   152064, 70cb8d8dc83eac82f2d3c4b0376bb1aa
+0,        233,        233,        0,   152064, ffd62a9ef829ec81f0f74f740488a41f
+0,        266,        266,        0,   152064, bab0aa23b5854e2a70926046e4618710
+0,        300,        300,        0,   152064, fec456f38f2a43661e786a8d5f67ed15
diff --git a/tests/ref/fate/vp9-01-sharpness-3 b/tests/ref/fate/vp9-01-sharpness-3
new file mode 100644
index 0000000..541c7e9
--- /dev/null
+++ b/tests/ref/fate/vp9-01-sharpness-3
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a2e5c820fd9733e18f9349fb658ca281
+0,         33,         33,        0,   152064, 0d487a146393a0b8b84b4be1b371b507
+0,         66,         66,        0,   152064, 68372e191eba620a431cfff226026ac3
+0,        100,        100,        0,   152064, de7fd274460e36b983fe93acc208d72f
+0,        133,        133,        0,   152064, afbd36c61bab65b98ff9acf08e215721
+0,        166,        166,        0,   152064, e1e9fc2ab4e7a187a8d8d84aae48d6b9
+0,        200,        200,        0,   152064, 11d95de6a9cc5e00511e99534779faac
+0,        233,        233,        0,   152064, cd2f5539fdfc2d8eefe6b6da28c13398
+0,        266,        266,        0,   152064, a8b3aeed41da7aeb8d5b962ee4a4af93
+0,        300,        300,        0,   152064, 4283670bd1c1c506ef18d3dafca22035
diff --git a/tests/ref/fate/vp9-01-sharpness-4 b/tests/ref/fate/vp9-01-sharpness-4
new file mode 100644
index 0000000..df41b70
--- /dev/null
+++ b/tests/ref/fate/vp9-01-sharpness-4
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a2e5c820fd9733e18f9349fb658ca281
+0,         33,         33,        0,   152064, 8bad76c55b5149169d64ce6512521de6
+0,         66,         66,        0,   152064, c1d986e1f9bf46382e598ba289b9bd7c
+0,        100,        100,        0,   152064, 86c097ac6069c786023d3561dae68bac
+0,        133,        133,        0,   152064, 8c238a2831b8c7c49736b6de6ff76ed8
+0,        166,        166,        0,   152064, cb5a038ed0a74a317ee72dae93a7ee3e
+0,        200,        200,        0,   152064, f8fe330a257e3e4e4c39c1c12820a654
+0,        233,        233,        0,   152064, a73e2fcdcbb9334c0c123f8276a2c881
+0,        266,        266,        0,   152064, 24fccece8ee639e4d0e00e4060e1db0c
+0,        300,        300,        0,   152064, 46d6e9aad69a39c718c5fd1e41e86e6e
diff --git a/tests/ref/fate/vp9-01-sharpness-5 b/tests/ref/fate/vp9-01-sharpness-5
new file mode 100644
index 0000000..b183d6b
--- /dev/null
+++ b/tests/ref/fate/vp9-01-sharpness-5
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a2e5c820fd9733e18f9349fb658ca281
+0,         33,         33,        0,   152064, f1ce0a5d57a46c9ff1331804b7b03fdb
+0,         66,         66,        0,   152064, 0364a085b06bee6b980189cf5378eda9
+0,        100,        100,        0,   152064, 4b5358698d734b0ae210909a913d4c1e
+0,        133,        133,        0,   152064, dc22565aaceee77b15fd8ab3c84bd5e0
+0,        166,        166,        0,   152064, 5f6340b656536292b46ba9a647aeb6e4
+0,        200,        200,        0,   152064, b7d4bce9a04b2a6caa45801be15e331e
+0,        233,        233,        0,   152064, 534c851cfe59ffc047815ece98d8cede
+0,        266,        266,        0,   152064, 786b0e1564d5c71aabfc2dd528cff4e7
+0,        300,        300,        0,   152064, cac0366209cf471bb7cc3e64966cbbd4
diff --git a/tests/ref/fate/vp9-01-sharpness-6 b/tests/ref/fate/vp9-01-sharpness-6
new file mode 100644
index 0000000..e0189a2
--- /dev/null
+++ b/tests/ref/fate/vp9-01-sharpness-6
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a2e5c820fd9733e18f9349fb658ca281
+0,         33,         33,        0,   152064, 45d9ca07ed04210b1ebc743169bc8ec4
+0,         66,         66,        0,   152064, 5b646cc309a711f1d8814f925002d8c4
+0,        100,        100,        0,   152064, 34db8db727fa1ded0a55cc7cf85be249
+0,        133,        133,        0,   152064, 54173d08afe6369b16a9c0c9cc6ce04d
+0,        166,        166,        0,   152064, 76275b0a478cdb3c1fb527ebbce023c3
+0,        200,        200,        0,   152064, e7643cdf0c42f2af700d8730bfc1a453
+0,        233,        233,        0,   152064, 6e53097e56f680cb658d63100e7736f7
+0,        266,        266,        0,   152064, 1a407c3c8ea1d5245ae68c5ce7de70e1
+0,        300,        300,        0,   152064, 6cbca24912cadf09b20be74f14e359c9
diff --git a/tests/ref/fate/vp9-01-sharpness-7 b/tests/ref/fate/vp9-01-sharpness-7
new file mode 100644
index 0000000..3fad7dc
--- /dev/null
+++ b/tests/ref/fate/vp9-01-sharpness-7
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, a2e5c820fd9733e18f9349fb658ca281
+0,         33,         33,        0,   152064, f719d0be18d16a448b4e7da3e2d9bf28
+0,         66,         66,        0,   152064, 83ee8ebc0ca796782a2376a76f2ffc26
+0,        100,        100,        0,   152064, 7cf5afdbc229e1af50a5377cfc23d831
+0,        133,        133,        0,   152064, 44244e896e0362f6376ba5afa563ba8b
+0,        166,        166,        0,   152064, df5f518d44eb6cb91b2df5a30d27ef82
+0,        200,        200,        0,   152064, 43cc3f151b8337aca7ee659c8abeb783
+0,        233,        233,        0,   152064, 4e89573470d9b97464e10806fc81aa8b
+0,        266,        266,        0,   152064, 62e0ba70f07ece8d85372f0a42e83a9a
+0,        300,        300,        0,   152064, 45ac2928acb11326f6c4a21401f3609c
diff --git a/tests/ref/fate/vp9-02-size-08x08 b/tests/ref/fate/vp9-02-size-08x08
new file mode 100644
index 0000000..51a27b3
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-08x08
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,       96, 52def242c36123e5a8f5f53d6a971399
+0,         33,         33,        0,       96, 79c93360fbd47179400414bbfee0901c
+0,         66,         66,        0,       96, c3b1947c79537baa7838905276276a91
+0,        100,        100,        0,       96, 20f35e501bdee0bc63e87b9240265c25
+0,        133,        133,        0,       96, 5e8f1c464bafd54833c51860906b5368
+0,        166,        166,        0,       96, f57b592600dfc99e634a083278af769a
+0,        200,        200,        0,       96, 7b02191f85590cbad3f148c7b92d6436
+0,        233,        233,        0,       96, b0a1c9870447a1744f64cd4087ef55ee
+0,        266,        266,        0,       96, c82712b1ba7a95efb67cbdde0ad708b6
+0,        300,        300,        0,       96, 89f4539f8d7a7b45a91fd2f46335988e
diff --git a/tests/ref/fate/vp9-02-size-08x10 b/tests/ref/fate/vp9-02-size-08x10
new file mode 100644
index 0000000..3829cfb
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-08x10
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      120, ea3e0f807304b0eb2d3e329b0124f75c
+0,         33,         33,        0,      120, 8d13cf682d63e7eb13094f55d67fc458
+0,         66,         66,        0,      120, e729cc6c3684c94a8f6118c618efc3ea
+0,        100,        100,        0,      120, ac43a0ace8e4112e877c2491ecc14fb5
+0,        133,        133,        0,      120, 53695f90b88d8e8cb838f0faec3238d3
+0,        166,        166,        0,      120, 40afd1c4dfd4a2e3b31631c46d252bcc
+0,        200,        200,        0,      120, 2b656f76f2e84d2f82d9bda2b5be94d3
+0,        233,        233,        0,      120, b22f004d678d047bc401be5e040cf883
+0,        266,        266,        0,      120, 57c840319abfb9c31013fbde54de3fb0
+0,        300,        300,        0,      120, 0f3dfc156216d7cfb6fd1d8c77dadab9
diff --git a/tests/ref/fate/vp9-02-size-08x16 b/tests/ref/fate/vp9-02-size-08x16
new file mode 100644
index 0000000..c2e0a68
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-08x16
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      192, 0553e56a9d89aea496421885aab491f5
+0,         33,         33,        0,      192, b2a14cf676f7ebf3c50450050f76ad16
+0,         66,         66,        0,      192, a308d981e09b50571fb0c8ebdcefe505
+0,        100,        100,        0,      192, d592ec625a0ac0373e82610c3eed9864
+0,        133,        133,        0,      192, acd19642455e643023b4fb882c3891ba
+0,        166,        166,        0,      192, 5af5390fd8c29b795e0ddf83f3f34284
+0,        200,        200,        0,      192, 473505aa2a76231725cf2107d6c9dbef
+0,        233,        233,        0,      192, 84860db6887e320f2d64f80cf0032e57
+0,        266,        266,        0,      192, 408e9cf60e99ae99d204ff08f3196d1a
+0,        300,        300,        0,      192, d8af96b79258f9382e911ed38340bdf5
diff --git a/tests/ref/fate/vp9-02-size-08x18 b/tests/ref/fate/vp9-02-size-08x18
new file mode 100644
index 0000000..8b7470d
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-08x18
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      216, 4c41f93b1b280b37bc77d7047435eaa4
+0,         33,         33,        0,      216, c9c80fdba2ebc2b8c3490ae35e34f84f
+0,         66,         66,        0,      216, 089d86acb3263fa5ef4f591a7f44556d
+0,        100,        100,        0,      216, 938fca6d93b83484144f5054e4838a41
+0,        133,        133,        0,      216, e0592e2ac9f5e09525ce0d3904cadf47
+0,        166,        166,        0,      216, ea43ff5d1330986e60c08567262ea764
+0,        200,        200,        0,      216, 08b40fe109ee90188f1cba9bbb1b376e
+0,        233,        233,        0,      216, b067068a2a7e36d5c5b5b405a1e73a18
+0,        266,        266,        0,      216, 9cf2d350296288803434b7451bd2be85
+0,        300,        300,        0,      216, 3c785e21dc228d6396738fbfcb470289
diff --git a/tests/ref/fate/vp9-02-size-08x32 b/tests/ref/fate/vp9-02-size-08x32
new file mode 100644
index 0000000..7d3841f
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-08x32
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      384, f92a7777fd69aa2f2914d9a41c4828ba
+0,         33,         33,        0,      384, 62e1cc73487d2249a88a60e35a22d9c7
+0,         66,         66,        0,      384, aa2619b605cb65eda15fdd99d5775550
+0,        100,        100,        0,      384, e6f0a491c543b835d0cefe5ca62c3dbe
+0,        133,        133,        0,      384, 361be1a06913c398f09494ca1b2d288f
+0,        166,        166,        0,      384, 0497bf849a973357c0ccb8d43f5bd8b4
+0,        200,        200,        0,      384, 5ac6ac523147c409dd00820622161dd7
+0,        233,        233,        0,      384, 7d07245574a46c524360f09be29a5f19
+0,        266,        266,        0,      384, fcfa7fbcaf42f81e4e34a4ee5a029ca1
+0,        300,        300,        0,      384, 336e3fe4f15d3d6c82d82b1855dcfeb4
diff --git a/tests/ref/fate/vp9-02-size-08x34 b/tests/ref/fate/vp9-02-size-08x34
new file mode 100644
index 0000000..affba37
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-08x34
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      408, f3f2cd8f157466ff23dace85d77367ce
+0,         33,         33,        0,      408, 639d9b70a14062e95559c12d2b597f91
+0,         66,         66,        0,      408, b2ee07a6656af583f19593229fa11848
+0,        100,        100,        0,      408, 74e3b5ab4c798a0afe745694e871bbd5
+0,        133,        133,        0,      408, 35f1c30d0f8678f319a392a6c53b5989
+0,        166,        166,        0,      408, 07e2b4c0b92a394bfb11124fe80476f0
+0,        200,        200,        0,      408, 7864bd20dfc5280e5f027d67ea22bf30
+0,        233,        233,        0,      408, 10a2925a7b91dfa9b82de76069388fd4
+0,        266,        266,        0,      408, 79cc7f7a149e8d6e04e065f75e63733c
+0,        300,        300,        0,      408, 6453d10d97532d9bb03f7c06cba9fca0
diff --git a/tests/ref/fate/vp9-02-size-08x64 b/tests/ref/fate/vp9-02-size-08x64
new file mode 100644
index 0000000..506f39f
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-08x64
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      768, 764bd02b781a38c621a109c12f3d9393
+0,         33,         33,        0,      768, 79496bd2b9212026af816b3b7a0587d5
+0,         66,         66,        0,      768, 2a3afd47ba3d075033fd94d5c3746c45
+0,        100,        100,        0,      768, fca00cad8d37a6646337baebadd0ca31
+0,        133,        133,        0,      768, aca376fb3f8a5ef670ecc2430037262a
+0,        166,        166,        0,      768, 7e6c8d96d1e24855c3e380f1bf2ce02c
+0,        200,        200,        0,      768, 09e051241972969d439f27f324d78490
+0,        233,        233,        0,      768, 2566b2a425caaba41305bf04ff10ea01
+0,        266,        266,        0,      768, db3995bedee42ada1b4ee63c339daf1b
+0,        300,        300,        0,      768, b00b8f1bf4fd907f0487738f5b5442c6
diff --git a/tests/ref/fate/vp9-02-size-08x66 b/tests/ref/fate/vp9-02-size-08x66
new file mode 100644
index 0000000..6ef07a0
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-08x66
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      792, df20e8df89449fe50bb610e95a449a95
+0,         33,         33,        0,      792, 18f1a66d463274d1b0489f3a50e86857
+0,         66,         66,        0,      792, b0cc102875a94c9a92e53826617adbe9
+0,        100,        100,        0,      792, dfece7c17b4b149283ef51bdc1bd440e
+0,        133,        133,        0,      792, 6e346884f67be259fcabe493109cb63c
+0,        166,        166,        0,      792, 6d282127311eb2d958377490d7cb77f0
+0,        200,        200,        0,      792, 637ac8b14ca5ddbaf7b8910406c3cd08
+0,        233,        233,        0,      792, e7980f3fcb36969da0d218c4389fa9e8
+0,        266,        266,        0,      792, 730a1c95b9fb165f6e1a2f33a0d25de0
+0,        300,        300,        0,      792, 7bd8424d0783b1c8ad617e17408371bb
diff --git a/tests/ref/fate/vp9-02-size-10x08 b/tests/ref/fate/vp9-02-size-10x08
new file mode 100644
index 0000000..f9ea55b
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-10x08
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      120, e1e66a88615da98523ef887f1463fc42
+0,         33,         33,        0,      120, 549842fa98c8faf572882d38b0aae390
+0,         66,         66,        0,      120, 17ee85785517705fdc78c6122a4b2548
+0,        100,        100,        0,      120, 1143391d419dac30a6c11f366157c974
+0,        133,        133,        0,      120, b62d2a962c4c36809ef75a610106715c
+0,        166,        166,        0,      120, e6f143ca33fbc0e776bb149950cdedff
+0,        200,        200,        0,      120, 01716a1077ec66df00474fd4510d2789
+0,        233,        233,        0,      120, 8cb5b6a865fa2cbb15f0d7736fda88a6
+0,        266,        266,        0,      120, 0fb9fd883e895a540fe1704dddbbab04
+0,        300,        300,        0,      120, 150a3b99aa24ef102c92f87c8adb4386
diff --git a/tests/ref/fate/vp9-02-size-10x10 b/tests/ref/fate/vp9-02-size-10x10
new file mode 100644
index 0000000..cff03c2
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-10x10
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      150, 083d638f2e147295d817bb14fff5e4f4
+0,         33,         33,        0,      150, 6dbdc445b6fd6bb99f2025cc2a40977e
+0,         66,         66,        0,      150, 41714089383b181d64fbfa7de5904608
+0,        100,        100,        0,      150, 11fdb8465e1599f7a9227706646d2cba
+0,        133,        133,        0,      150, 907876b3342a10040db0851a936af4e3
+0,        166,        166,        0,      150, e7b18d47d06b25de205d873d3d941640
+0,        200,        200,        0,      150, 523ce7413c8da7f6a657a9b661f36c44
+0,        233,        233,        0,      150, 23caff863af875c66c903662a3e1e6a1
+0,        266,        266,        0,      150, ed4cc5557203e5b7a119112ee9ceb00b
+0,        300,        300,        0,      150, 4bb78a996be3188888d1c60e11a08e1b
diff --git a/tests/ref/fate/vp9-02-size-10x16 b/tests/ref/fate/vp9-02-size-10x16
new file mode 100644
index 0000000..9f9f5fe
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-10x16
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      240, fab07d6209d2413e0a434e1aaaa12154
+0,         33,         33,        0,      240, f9ffffdb96f98527ba2e553d1265edbb
+0,         66,         66,        0,      240, 56a992264cf7da2b23dd97435e9d0365
+0,        100,        100,        0,      240, b1db980423d8004bd45a789b02b92a65
+0,        133,        133,        0,      240, b29496aedc7026566367b634f55ebb28
+0,        166,        166,        0,      240, 2bc9def672da4a2fc17cbd669e2b8081
+0,        200,        200,        0,      240, 8c54721514cdf577a52a8668b9135f13
+0,        233,        233,        0,      240, 2efab81d5e039d82b3bc7b0303b022c4
+0,        266,        266,        0,      240, bd0f42b91b5d126fd0baec765b1096ad
+0,        300,        300,        0,      240, c6bfea2735a629167bc6a7a7c76eb7f3
diff --git a/tests/ref/fate/vp9-02-size-10x18 b/tests/ref/fate/vp9-02-size-10x18
new file mode 100644
index 0000000..3f1e9f1
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-10x18
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      270, 0e9182e214aae732d94d007e5fe44888
+0,         33,         33,        0,      270, 2630e2674b5611d68218fddac08815e2
+0,         66,         66,        0,      270, d5cdd7d6a3de17939f60bb60ef6877da
+0,        100,        100,        0,      270, 29d1961096061029e78963fa82581eca
+0,        133,        133,        0,      270, 5c2629f8aa59757f6b4aafa9f6cbcba1
+0,        166,        166,        0,      270, 1f1a8b61e4fbd6222ddf42e9d0a07032
+0,        200,        200,        0,      270, cfb9771190ac2d0129907102d6abb63f
+0,        233,        233,        0,      270, cd98dd856ba573a26a943cbe53221f26
+0,        266,        266,        0,      270, ca13c161f067c4a4ce22bd58a2aca55b
+0,        300,        300,        0,      270, de4bd1a474a76a35b796a5fc45b4f893
diff --git a/tests/ref/fate/vp9-02-size-10x32 b/tests/ref/fate/vp9-02-size-10x32
new file mode 100644
index 0000000..5ca7bee
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-10x32
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      480, 622e6407a051ea08706394d03330ffbf
+0,         33,         33,        0,      480, 1841a0daf7c3ef7be94e01fdb1d3968a
+0,         66,         66,        0,      480, 37790e6cb2415f7add0ac5d3ab354755
+0,        100,        100,        0,      480, 91485880e17c292096a7335566d3648f
+0,        133,        133,        0,      480, eb6f74983d5fd13d6bd90afbce8836e1
+0,        166,        166,        0,      480, 0069ab5ff7f0d4d601f7d0f9b7a08338
+0,        200,        200,        0,      480, dbf04254765f7497070387e8c34895c6
+0,        233,        233,        0,      480, 410a9b2d9855b2c29618070994adae96
+0,        266,        266,        0,      480, 7e7f34effd90209f29f1b9ae01488b3b
+0,        300,        300,        0,      480, 471530f74082c01c9b0f1fcf3d240d77
diff --git a/tests/ref/fate/vp9-02-size-10x34 b/tests/ref/fate/vp9-02-size-10x34
new file mode 100644
index 0000000..e61e65d
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-10x34
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      510, bfeeaf51f972fd0dfe9ee757083cbb54
+0,         33,         33,        0,      510, 10cd4ed6d762004846412d9cd0caa407
+0,         66,         66,        0,      510, 04cca4008d656ed180de88dd2ddb4f21
+0,        100,        100,        0,      510, ec777e377836895748c06849fa35ed2d
+0,        133,        133,        0,      510, b55633d0f9239dff3e45a4abce4a35a7
+0,        166,        166,        0,      510, 063c3ab4b4c599942c3a8a5b7bfe5029
+0,        200,        200,        0,      510, 07b920169d32b5fc51d5b9ae16fef5bf
+0,        233,        233,        0,      510, 8d49e727db9d3072b5ab7bab2133d9be
+0,        266,        266,        0,      510, 17441437203447e946a57d2f96966332
+0,        300,        300,        0,      510, 5d3f14af0e5cd81d0c7d2059f13efa5a
diff --git a/tests/ref/fate/vp9-02-size-10x64 b/tests/ref/fate/vp9-02-size-10x64
new file mode 100644
index 0000000..9a9401f
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-10x64
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      960, 835254d0eecb17bed1f2b0f3a1638165
+0,         33,         33,        0,      960, c0c95ce9890eab339a0e0f8b26cb095c
+0,         66,         66,        0,      960, f0337d645ade07cb716952b0d19352e8
+0,        100,        100,        0,      960, 7e3deb21cb3f0ead90c8af94464cde14
+0,        133,        133,        0,      960, c6b1ca6cfce358c411c0637c581157c8
+0,        166,        166,        0,      960, 10fce3f11f1ce90286ff4d74fe44fcfd
+0,        200,        200,        0,      960, ee0565a1f121bc905a35550619127a50
+0,        233,        233,        0,      960, 0624b601d379616eb792c94be60b6c91
+0,        266,        266,        0,      960, a1bb79cdf347548f1103f580f2b6930f
+0,        300,        300,        0,      960, 40e96e16c7e065aa7932e5aa57f32398
diff --git a/tests/ref/fate/vp9-02-size-10x66 b/tests/ref/fate/vp9-02-size-10x66
new file mode 100644
index 0000000..ef9fa1b
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-10x66
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      990, 1bd8b2d3bf679c4b925780bf82e12fae
+0,         33,         33,        0,      990, a0254b4cd4928fe1080cd6f8828288a9
+0,         66,         66,        0,      990, e416e99644cca481dc2806708d716ecb
+0,        100,        100,        0,      990, b1ed3203ffc77ed814f1cda7bfe721d2
+0,        133,        133,        0,      990, 0ff7b9d84765f7b0b0650775ba72b334
+0,        166,        166,        0,      990, 8b6cd91e035bad19b46b132bd411231d
+0,        200,        200,        0,      990, c714759a9a64402043ad00e5677c954c
+0,        233,        233,        0,      990, 8e4738010b724ce66bcd0a5d5afcfbc1
+0,        266,        266,        0,      990, 998a7aab8ed94f4b69bed39fb487f8d5
+0,        300,        300,        0,      990, 9964683a15a65c032631a4f608e6009b
diff --git a/tests/ref/fate/vp9-02-size-16x08 b/tests/ref/fate/vp9-02-size-16x08
new file mode 100644
index 0000000..aac95a3
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-16x08
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      192, 68dccd167f9aa18df0840ebb8715eb68
+0,         33,         33,        0,      192, 65c90bb99fdbee7abf21031d34cb18dc
+0,         66,         66,        0,      192, 9ef1feb2dcbd4d73f3ee84e9e1cd2668
+0,        100,        100,        0,      192, b6281f7c88e9aa132d3902046f8cde5a
+0,        133,        133,        0,      192, 4b439b716a294bddf9f56a229705907b
+0,        166,        166,        0,      192, d42c0a6f0d24522c90bc2233bc1df2c7
+0,        200,        200,        0,      192, 74b763a5a12c4c4a581efb1818a92970
+0,        233,        233,        0,      192, 0c3a0916ddfda5abdd3ac382f036e71f
+0,        266,        266,        0,      192, 26ff590e8ae726f70e8b36f5eaee7a19
+0,        300,        300,        0,      192, 30fa5810995d7132387ea585c4a1cc3a
diff --git a/tests/ref/fate/vp9-02-size-16x10 b/tests/ref/fate/vp9-02-size-16x10
new file mode 100644
index 0000000..bea7010
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-16x10
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      240, fb3cad61d7d9eb511758dbf87dd8abe1
+0,         33,         33,        0,      240, 4fbc1aa5559c8db2930803893bd6ba75
+0,         66,         66,        0,      240, 2d8e2ee04dcc6097ca9e3f27070cdcc8
+0,        100,        100,        0,      240, 05d419f1322855ba3620665b68ce9910
+0,        133,        133,        0,      240, b004f8d88cb2c94f4e9a13cfa5bd480a
+0,        166,        166,        0,      240, 9d9dec90e2213c0411939131aa9adf7f
+0,        200,        200,        0,      240, a00874356ff1b1e9da1a400424661f8d
+0,        233,        233,        0,      240, fda587eb6323cd98c773f05905ac1794
+0,        266,        266,        0,      240, 781c63d221a04d8130806c799d16753a
+0,        300,        300,        0,      240, f346e311829f3789dc5a94da48ada5f4
diff --git a/tests/ref/fate/vp9-02-size-16x16 b/tests/ref/fate/vp9-02-size-16x16
new file mode 100644
index 0000000..b013952
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-16x16
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      384, b5c9daafa548e54a8e33e9881fda33f4
+0,         33,         33,        0,      384, 1193acd7ea4b7aac968e35ef83c64378
+0,         66,         66,        0,      384, cd0e42c0b5a8b3be6f0e1d224062bf99
+0,        100,        100,        0,      384, ed79c71d17f68f86cbfa75ea2bfe97f3
+0,        133,        133,        0,      384, 1502a859c7e07b31faad5b80e3e27cf7
+0,        166,        166,        0,      384, df3f093da914ea947db93c3baa188ecb
+0,        200,        200,        0,      384, 480f86eb183b99277c1b38fdaafe2970
+0,        233,        233,        0,      384, 023e0114282e04963f0f52e00e65ac61
+0,        266,        266,        0,      384, e67f29cf0acc7f9b553458e1e5c59ebf
+0,        300,        300,        0,      384, a779a14ba718f0c1df8a7edc9467d12e
diff --git a/tests/ref/fate/vp9-02-size-16x18 b/tests/ref/fate/vp9-02-size-16x18
new file mode 100644
index 0000000..1795bd9
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-16x18
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      432, 5156b11cd9995d0c1638c9b0d2b0786c
+0,         33,         33,        0,      432, ef78557f93fb3ea770c7d49ab60edf21
+0,         66,         66,        0,      432, f31fb9bb14566e4538a45ac7bf398b2a
+0,        100,        100,        0,      432, 97633875537f76ade183e975fa91b0fb
+0,        133,        133,        0,      432, 602cf54f9af852175173c21abd63796f
+0,        166,        166,        0,      432, 0b3741a6842cb65d6d21eda891882033
+0,        200,        200,        0,      432, 44240a27a6b6d36c9661d499fb965f87
+0,        233,        233,        0,      432, 9050f263f9a4767f9323ec8aa42cf7e6
+0,        266,        266,        0,      432, 57fa3a8494375f588a95376bc0c3cb28
+0,        300,        300,        0,      432, 084595f2a65aa10e7d3845044a0e7213
diff --git a/tests/ref/fate/vp9-02-size-16x32 b/tests/ref/fate/vp9-02-size-16x32
new file mode 100644
index 0000000..663a456
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-16x32
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      768, c73d611490a5ddec6c690589deaf5e86
+0,         33,         33,        0,      768, 5d8eaeb222aa64abda59ce7b09b2f6d9
+0,         66,         66,        0,      768, 34321856b8dd5bbb9b63db04d3532289
+0,        100,        100,        0,      768, 947337d2fec8a09242f60e31e99f4065
+0,        133,        133,        0,      768, bb7d92f6fc055f0cf0e97bd2be56cc9e
+0,        166,        166,        0,      768, 5d343c82bcdd0e9d08581043cddfd0ca
+0,        200,        200,        0,      768, 612ded93207712e4916d584cc4a7b87c
+0,        233,        233,        0,      768, 6ba5e0d19893e1b96f5ca86e0bfd7e18
+0,        266,        266,        0,      768, 336572e1dcb110b1eb87bea81e0752f4
+0,        300,        300,        0,      768, 705f73d0a39afce59ea571e68bfe25df
diff --git a/tests/ref/fate/vp9-02-size-16x34 b/tests/ref/fate/vp9-02-size-16x34
new file mode 100644
index 0000000..54d9aaa
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-16x34
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      816, b8bf711d9a1ce49180ed56407c8a4b0a
+0,         33,         33,        0,      816, 0457929b06ce46aec63d66bd38586e3f
+0,         66,         66,        0,      816, 3b5f417ee5a936797a6f0d138b8ed73b
+0,        100,        100,        0,      816, 5d1a42aeecfd5c8513cb2df94c206c8b
+0,        133,        133,        0,      816, a0ab2dddbc810a1667d779f6ed69d010
+0,        166,        166,        0,      816, b150cd7c4ec83e6f9d948e99d7465350
+0,        200,        200,        0,      816, ea39622ad21312bd8bcecdaf09aa18fb
+0,        233,        233,        0,      816, 467a42e1226a01c8ba244f312f588bab
+0,        266,        266,        0,      816, f2311e15228ffc7fd377b89c203d0fbf
+0,        300,        300,        0,      816, 5df58b3ac0a7856796a46f27be7dcf4c
diff --git a/tests/ref/fate/vp9-02-size-16x64 b/tests/ref/fate/vp9-02-size-16x64
new file mode 100644
index 0000000..0e19d9a
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-16x64
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1536, 925fdc485f3baa1ed145ae391519d7fd
+0,         33,         33,        0,     1536, d37af656da2d7a727c8451773495d5ed
+0,         66,         66,        0,     1536, 8a0f207a99e46f3d3b2aaa3f1b061981
+0,        100,        100,        0,     1536, a3914c7b739d3af2641fd6aae35428ef
+0,        133,        133,        0,     1536, 0ba3b49970d7b029f2dfa991fdfc6e61
+0,        166,        166,        0,     1536, 55838d1d787dc5a4fa4da2994f04587f
+0,        200,        200,        0,     1536, c089f7ba2b2983df2a4dc2e07798af31
+0,        233,        233,        0,     1536, c23dcb3b109543a61ccfa404a726caae
+0,        266,        266,        0,     1536, 01aaf09960f5ca599ca32768f017d0c9
+0,        300,        300,        0,     1536, 79fe955692ecba8bbb00b20a42ca8104
diff --git a/tests/ref/fate/vp9-02-size-16x66 b/tests/ref/fate/vp9-02-size-16x66
new file mode 100644
index 0000000..2d75fc8
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-16x66
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1584, c7b0d91f362dff0a581434af6e902d43
+0,         33,         33,        0,     1584, d8b016ef59c6bc193b29d1c714f342c1
+0,         66,         66,        0,     1584, c520bd8d4b81aafc7687befff66c7396
+0,        100,        100,        0,     1584, 92e81bbd3af675c9cdb1cb00d03dabe1
+0,        133,        133,        0,     1584, a271db3defe5daa6d9e0a73a580f4f88
+0,        166,        166,        0,     1584, 4077e857321e241bb98dfd89c0aca46f
+0,        200,        200,        0,     1584, 0466e1453a94baf876e9f64b60235300
+0,        233,        233,        0,     1584, 9d2cb9c7b180d44841e0e4d8a595d912
+0,        266,        266,        0,     1584, 500f443eeb0ecef47c34d1e91f0df6ce
+0,        300,        300,        0,     1584, 83354487982915c33b1c6243d80adaeb
diff --git a/tests/ref/fate/vp9-02-size-18x08 b/tests/ref/fate/vp9-02-size-18x08
new file mode 100644
index 0000000..49129ce
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-18x08
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      216, 3219af4ef540636b0f67a989e9966059
+0,         33,         33,        0,      216, 1a3655c2cfd2ee332bc89da5b3faf778
+0,         66,         66,        0,      216, d638d5b361a6d81440e26993ed86c97d
+0,        100,        100,        0,      216, d9bc2e7cffd66db4ba9dcbce99448d4d
+0,        133,        133,        0,      216, 399f962e0a0573915bc4da4a9f1effcf
+0,        166,        166,        0,      216, 69d917e19b903e4f07f848e9e557bbe7
+0,        200,        200,        0,      216, d6311488a58acf6eb0cc45bc4fe3c2da
+0,        233,        233,        0,      216, 0ce360a84d5755307f98d65c83f190e1
+0,        266,        266,        0,      216, 2554828e6dbf94424ccac30fb153872e
+0,        300,        300,        0,      216, 598a55f9735e85b8d45105dd6be7f97b
diff --git a/tests/ref/fate/vp9-02-size-18x10 b/tests/ref/fate/vp9-02-size-18x10
new file mode 100644
index 0000000..3fcf5ca
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-18x10
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      270, bf574489e9360b6475aa012c747e7924
+0,         33,         33,        0,      270, 851100301c2937312a6fd32f5aab5a09
+0,         66,         66,        0,      270, 0f7c1209e44ea7cd4df12d82f9224684
+0,        100,        100,        0,      270, 28d121f9c40de5280435bfdeaec0c072
+0,        133,        133,        0,      270, bb00898d03ce4dff5f7bee719dd3f5b5
+0,        166,        166,        0,      270, a098cc66bc25b81f84b0e930b0915cdb
+0,        200,        200,        0,      270, 81e25f19bfcbfce17bd7138eedae04ee
+0,        233,        233,        0,      270, 69c36c5ce555a461f16a1733450f7258
+0,        266,        266,        0,      270, c95236d9e7c624bb664310bd9ef47fb4
+0,        300,        300,        0,      270, 7ab0942e686939951037314e9402d2c1
diff --git a/tests/ref/fate/vp9-02-size-18x16 b/tests/ref/fate/vp9-02-size-18x16
new file mode 100644
index 0000000..6b2a43a
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-18x16
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      432, 9535aaa2ea26fbdc16e7fe9cba3fc9b4
+0,         33,         33,        0,      432, 7f6e7ca33c0b27ff052dc2ab6721e37d
+0,         66,         66,        0,      432, d37e3f169457a9c7f2a197353e39d3d6
+0,        100,        100,        0,      432, f26d7d81dd81d051680ea2485e812705
+0,        133,        133,        0,      432, 704b01955ced6d101b9e9315d3327f28
+0,        166,        166,        0,      432, 30d46d6a0f6be383dede451cacf465f4
+0,        200,        200,        0,      432, 83c7ed04f0af61ec665041967cbce05d
+0,        233,        233,        0,      432, 152daf37dd37607886c50dd4c7796357
+0,        266,        266,        0,      432, 609d807351ba74b1c432e3d0516add91
+0,        300,        300,        0,      432, 67953f0c735984232cb6782217cdcdf6
diff --git a/tests/ref/fate/vp9-02-size-18x18 b/tests/ref/fate/vp9-02-size-18x18
new file mode 100644
index 0000000..d7103ae
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-18x18
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      486, 83790b0e7004d8d89b7134ee1a88d885
+0,         33,         33,        0,      486, 0baf0bf556ae56d2f4b04567e6ac7ed9
+0,         66,         66,        0,      486, c648854a4d49f7e407a2450cf4ba292a
+0,        100,        100,        0,      486, 510c3aca23339841ffc72ed5c75d184e
+0,        133,        133,        0,      486, 1c1f3116ec4d4ee1ad790652e49233ad
+0,        166,        166,        0,      486, f94891f4e16fd32d638a2c696f5922e6
+0,        200,        200,        0,      486, e164814c22e38cbe45312dfd48d987fc
+0,        233,        233,        0,      486, f582515fcc6c4308ad931d2f6cf371a0
+0,        266,        266,        0,      486, 0a446974bd227ee34a1621a2b7852abb
+0,        300,        300,        0,      486, beca28bdae8d1fe20036b3646f3109cd
diff --git a/tests/ref/fate/vp9-02-size-18x32 b/tests/ref/fate/vp9-02-size-18x32
new file mode 100644
index 0000000..450facc
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-18x32
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      864, 62eabc8819ded6ddba2c3a5029497cf0
+0,         33,         33,        0,      864, b760182fddf8bc05f149e80bbcb2c281
+0,         66,         66,        0,      864, 0c44be0472ebd2653ce9fb174c6180ab
+0,        100,        100,        0,      864, bbb033c3bfeeb6f59cb43013597b9d92
+0,        133,        133,        0,      864, a769975cdbc6529525f7cac8a0d9299a
+0,        166,        166,        0,      864, 15b02059bbced62f19c0626efea1ecb9
+0,        200,        200,        0,      864, 47f4b50322ed31649bdcfffb05c70fa2
+0,        233,        233,        0,      864, 8649cdd0a958047839f5b6e7bbf6f288
+0,        266,        266,        0,      864, 2c766e3fd3882a9a5aff52ffe9d1d341
+0,        300,        300,        0,      864, 184a62b7332a1c24acbf03f670fb7ac1
diff --git a/tests/ref/fate/vp9-02-size-18x34 b/tests/ref/fate/vp9-02-size-18x34
new file mode 100644
index 0000000..ef6042a
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-18x34
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      918, 612cc424eaae924cb25c7732c422f752
+0,         33,         33,        0,      918, 010e8c2a814862529fcf8d7771ba2d7f
+0,         66,         66,        0,      918, 7d791b7a5916738998f77586339d5840
+0,        100,        100,        0,      918, aeada5f59f3dda9ab3e898f305428cb2
+0,        133,        133,        0,      918, 06af894d38a1f0d3665c0081f5397ddf
+0,        166,        166,        0,      918, 24bf31323c568e652550e9d35de9c96c
+0,        200,        200,        0,      918, a9681ec47d3e6a19321b9ea47221dc3f
+0,        233,        233,        0,      918, 73ae7268df79c4012952bd3e8011e894
+0,        266,        266,        0,      918, 67aa4145398ca17036959251cb4ce17b
+0,        300,        300,        0,      918, de247b80114c722da849f5aa23adbb38
diff --git a/tests/ref/fate/vp9-02-size-18x64 b/tests/ref/fate/vp9-02-size-18x64
new file mode 100644
index 0000000..038b21b
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-18x64
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1728, 72c74de547d9ed1b17bc962dbd5e0bb1
+0,         33,         33,        0,     1728, 462849f9e2204738e9f08b40e682a6ae
+0,         66,         66,        0,     1728, f0ee17692fd816747b11d5737b511cda
+0,        100,        100,        0,     1728, 0234d23406660ede76dd22b35a708390
+0,        133,        133,        0,     1728, 6544fdb9dc225d155820d3c7dfc909eb
+0,        166,        166,        0,     1728, 1c073544794389596177512fb4dcffce
+0,        200,        200,        0,     1728, 864709daac7b091d33afa2210c145084
+0,        233,        233,        0,     1728, b049c4ac941743613ede9a41b16acde5
+0,        266,        266,        0,     1728, ad0c4adb0efec03729a79f42eec66267
+0,        300,        300,        0,     1728, 146057d941f5a47eb8b2c9eefeaf3100
diff --git a/tests/ref/fate/vp9-02-size-18x66 b/tests/ref/fate/vp9-02-size-18x66
new file mode 100644
index 0000000..6d3021b
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-18x66
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1782, c3fc4a1593b9cc2f3752106af8539386
+0,         33,         33,        0,     1782, 7f2ffe6bc1750f6749bb5ad12cbaf34b
+0,         66,         66,        0,     1782, 2539b10a981d59ef54efd77cd7276aaa
+0,        100,        100,        0,     1782, 0bff22b4dfb7485fbedd6ff5b99673d1
+0,        133,        133,        0,     1782, 6a2b38f4abee785260a61bc60f16e7fa
+0,        166,        166,        0,     1782, 2fbb69b5519b51548bf1ee425ff79c55
+0,        200,        200,        0,     1782, dbd267028be2256111b2411b91fcc117
+0,        233,        233,        0,     1782, 12b2f1003633c9e19cae3d0fda06102d
+0,        266,        266,        0,     1782, d419a756c492867523af5185fd57d989
+0,        300,        300,        0,     1782, 8a7d36760bf5db32baef349b97316b47
diff --git a/tests/ref/fate/vp9-02-size-32x08 b/tests/ref/fate/vp9-02-size-32x08
new file mode 100644
index 0000000..ae376d3
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-32x08
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      384, c7b30cde5664387b0f7a80d9b01e4fe2
+0,         33,         33,        0,      384, 2228a2a4e54ab5145525e5803c314dcd
+0,         66,         66,        0,      384, 8c048469eba24f3163c36b7461b3b42a
+0,        100,        100,        0,      384, f6b8e8e701dea09dcf1158e9a52921c6
+0,        133,        133,        0,      384, b3a5fde0daf2eef8fc08521f88f79692
+0,        166,        166,        0,      384, 653ae11cc1380ae7f39b2e007f896d81
+0,        200,        200,        0,      384, 6e66fe002a7dff95e13cc9d3d13d9686
+0,        233,        233,        0,      384, 13308c917a1e22c2f702afc32b8a23c2
+0,        266,        266,        0,      384, 4fee1e63f9452dc3f81c1d634bd7f41d
+0,        300,        300,        0,      384, 666b43ead5c7c99ae5b7637da5aa4d62
diff --git a/tests/ref/fate/vp9-02-size-32x10 b/tests/ref/fate/vp9-02-size-32x10
new file mode 100644
index 0000000..bc816e9
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-32x10
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      480, 7c5b5df373ebfd31d210ff910e02213b
+0,         33,         33,        0,      480, c5b0a5e3eceb792b15818324a43aa2a8
+0,         66,         66,        0,      480, 1d9c0eafd4638dfe4fe308174fde2faf
+0,        100,        100,        0,      480, 47301d12055944b35008028761cf5e7b
+0,        133,        133,        0,      480, 9586ac1087423dcd3b0ff96d43ae475e
+0,        166,        166,        0,      480, 26bfe1afea96c7ef2084fffd1fa99a33
+0,        200,        200,        0,      480, 0995c8a1935266159a7ef3f95d7f4697
+0,        233,        233,        0,      480, 8cfcc0ea67507ab7f3551d8ac50f93a5
+0,        266,        266,        0,      480, 658cf3cb887b055d9de7d50db4eb78a9
+0,        300,        300,        0,      480, 856bd5189688f7ccfe9995752bc0f1f6
diff --git a/tests/ref/fate/vp9-02-size-32x16 b/tests/ref/fate/vp9-02-size-32x16
new file mode 100644
index 0000000..ebb465e
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-32x16
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      768, 7c2818db2632e5c5beee17e7105d9209
+0,         33,         33,        0,      768, cead72bd22995e98b54a91c7b4a20975
+0,         66,         66,        0,      768, eb6baee5d65d778052c88ba5db2f9174
+0,        100,        100,        0,      768, 1f5f38e89e985e9e4172446de05e91fd
+0,        133,        133,        0,      768, 57b57ffcb03627942fc5868324a10feb
+0,        166,        166,        0,      768, 4b4066a452d8e9cd687cd611f5d9cb88
+0,        200,        200,        0,      768, 113e5069b2a4d2c2e802b72649eb435d
+0,        233,        233,        0,      768, e176bb233f76f9fd4c55d62d53487b60
+0,        266,        266,        0,      768, f2ff3def712a846ea7b678bd9078e32b
+0,        300,        300,        0,      768, 21007ed1c727c5ccc5955188a2cec276
diff --git a/tests/ref/fate/vp9-02-size-32x18 b/tests/ref/fate/vp9-02-size-32x18
new file mode 100644
index 0000000..6afccbb
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-32x18
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      864, 9da5409d344e7b8380688569e54803a5
+0,         33,         33,        0,      864, 9b51e14e2e624ee2b430e9eaf1a48798
+0,         66,         66,        0,      864, b8811779f363b9a595e3a92737771ea9
+0,        100,        100,        0,      864, e5a0c335e5e713a3e77fff0b65127fb9
+0,        133,        133,        0,      864, 1bffa3283b463a356794c8f7a73f8c54
+0,        166,        166,        0,      864, 97c13270621a583eb9e13c05f9d792f0
+0,        200,        200,        0,      864, a6f81a4dde1ffc352ebe9d8ab8782f35
+0,        233,        233,        0,      864, 91a955a86ce9378ff3442794ce0934c6
+0,        266,        266,        0,      864, 2e4f8938e9c88b328a258a0b99366ea6
+0,        300,        300,        0,      864, adbbbc192cf36e1fc7c308824765d482
diff --git a/tests/ref/fate/vp9-02-size-32x32 b/tests/ref/fate/vp9-02-size-32x32
new file mode 100644
index 0000000..fb3fb87
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-32x32
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1536, 117915db1856cee26f05a609c8c8de2e
+0,         33,         33,        0,     1536, 943771a98b26b174e88ed1f4e872e504
+0,         66,         66,        0,     1536, 3e0d2585e1f1cb540998d107aca5c395
+0,        100,        100,        0,     1536, e64a9e1e0232983a69ab48453025b23d
+0,        133,        133,        0,     1536, 2c6ef6637fb7b9425f7d7ea28cd84087
+0,        166,        166,        0,     1536, 419a5a31a43955d408c13ee8a5ddce9c
+0,        200,        200,        0,     1536, 2ab13e1c236553d42d59498ca350b190
+0,        233,        233,        0,     1536, b8068beb037f3232d4da38fe33a8a885
+0,        266,        266,        0,     1536, 160df68b9e3f75e9b1f8ed7cce327bc2
+0,        300,        300,        0,     1536, 1ccafa8c7babdce0983aeb20d298b0ee
diff --git a/tests/ref/fate/vp9-02-size-32x34 b/tests/ref/fate/vp9-02-size-32x34
new file mode 100644
index 0000000..4e000a5
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-32x34
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1632, 770582911fd0095ebbeae384e87665ac
+0,         33,         33,        0,     1632, f99d7e3131f04413cba2f9de6818976d
+0,         66,         66,        0,     1632, 3bfbb8c9c48f24cd596973a6deb33a3f
+0,        100,        100,        0,     1632, 0b8166afdd357f20c76f77d228bb7171
+0,        133,        133,        0,     1632, 3a3d7f2a03e19a82250d6ca0238f9791
+0,        166,        166,        0,     1632, 9b558f9b8744b016059f69f3fca90d2c
+0,        200,        200,        0,     1632, c857736342f1145d919cb77732120006
+0,        233,        233,        0,     1632, 11dc5dda4c883a3146db060dd50343d0
+0,        266,        266,        0,     1632, 7526a62ae87de174be86eac7bb36c7f3
+0,        300,        300,        0,     1632, 9ef38f47cfc461710ff0dd75690473c0
diff --git a/tests/ref/fate/vp9-02-size-32x64 b/tests/ref/fate/vp9-02-size-32x64
new file mode 100644
index 0000000..d2b9c99
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-32x64
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     3072, caa8471a8b381d53c3e8fc627946a871
+0,         33,         33,        0,     3072, 2cba86ea14c0f28e242625b08f5e9b88
+0,         66,         66,        0,     3072, cea0440ff6569fc82c3030e0340fb649
+0,        100,        100,        0,     3072, c18ef37f1356ade96a2f40af954b31c8
+0,        133,        133,        0,     3072, 21e6e549378bcff47913ef292e74dc37
+0,        166,        166,        0,     3072, a9d3d483f74a5afe5d80725ce696fd20
+0,        200,        200,        0,     3072, a436e2586b0963747deaf5e450e2b230
+0,        233,        233,        0,     3072, 9daaadf265df56974cb0950843d9fd8c
+0,        266,        266,        0,     3072, e0b84714bad2519e62b7d16705fb09d5
+0,        300,        300,        0,     3072, 8cdfce574edbe548da7f6cd9a7076b9e
diff --git a/tests/ref/fate/vp9-02-size-32x66 b/tests/ref/fate/vp9-02-size-32x66
new file mode 100644
index 0000000..65c87da
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-32x66
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     3168, 920ea4b8a00d41489d122d641d6e4fe5
+0,         33,         33,        0,     3168, 8bfc8d452a79f2978b8e973b77cbf8a8
+0,         66,         66,        0,     3168, 09f3f0d31d3377a844fa5385d9b36b9f
+0,        100,        100,        0,     3168, df43fae763da9360c8062bb92ee091a8
+0,        133,        133,        0,     3168, 445d8c675bb865d1814fcfa6b8a9afd3
+0,        166,        166,        0,     3168, dc7d43db86aac6636724de8790eda555
+0,        200,        200,        0,     3168, d3a9fc272424449ffc5b7e69f8f9948b
+0,        233,        233,        0,     3168, 11ef33b9bccca54b3703bf24ab55e2d6
+0,        266,        266,        0,     3168, ce31b8bf9b00b427ca956abb800d8034
+0,        300,        300,        0,     3168, e707f824d6e95d482bf3a0b4d52ea069
diff --git a/tests/ref/fate/vp9-02-size-34x08 b/tests/ref/fate/vp9-02-size-34x08
new file mode 100644
index 0000000..d6ccbbb
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-34x08
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      408, c14f2ba5b4582c9d3a488976814691b3
+0,         33,         33,        0,      408, 4387a4dce19007b7efb810b5a4069749
+0,         66,         66,        0,      408, ecfe868d28f4861a5612edfd57447a02
+0,        100,        100,        0,      408, 5cba54f568534d29169ac31c8fa505e0
+0,        133,        133,        0,      408, fe9aab7b3378b9fc3e373ee626b887db
+0,        166,        166,        0,      408, fce72dfc7f9c0cb50ff73761b4d82c1f
+0,        200,        200,        0,      408, d4d98f42b1377e0f0ffaa66aa81d40c3
+0,        233,        233,        0,      408, 65c027646dc95a749ce2d7ad0a6beccc
+0,        266,        266,        0,      408, 317b283a0d907270f671272771022e69
+0,        300,        300,        0,      408, d3e2c008584608502f3e24c5c5f64028
diff --git a/tests/ref/fate/vp9-02-size-34x10 b/tests/ref/fate/vp9-02-size-34x10
new file mode 100644
index 0000000..adcb22e
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-34x10
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      510, fd7212b519783cf4831ce4bff91f2312
+0,         33,         33,        0,      510, 9768722ee939d80a6716865fdebca33d
+0,         66,         66,        0,      510, 328ee0f774eeafde00dcc4b9a8f4e9af
+0,        100,        100,        0,      510, f882fa6015fcb042094eadab5fa952cf
+0,        133,        133,        0,      510, 4331a3dabeae27d2bf3590eb96ce914a
+0,        166,        166,        0,      510, 0e15106bd8e90377f6ed8b464d17159c
+0,        200,        200,        0,      510, 8f062653ac2b83f7e541393e838d0e0f
+0,        233,        233,        0,      510, eeb98c1728c1a74510f8bfaf10fc0002
+0,        266,        266,        0,      510, 30bb058a67d6a5ee3693b21cbca5349a
+0,        300,        300,        0,      510, 7ce4b79983b3abc37b141a3bea56e0b7
diff --git a/tests/ref/fate/vp9-02-size-34x16 b/tests/ref/fate/vp9-02-size-34x16
new file mode 100644
index 0000000..db88976
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-34x16
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      816, e443c43101be00470c6a61c1a2995b5a
+0,         33,         33,        0,      816, 1e79b1b46ec704d360b5fb725913b0f1
+0,         66,         66,        0,      816, 6d5e77cafab6bc43498980c515d299d3
+0,        100,        100,        0,      816, 91c3bba5fd2aa29ee54c8f3783cfe5a2
+0,        133,        133,        0,      816, 9548d07c2a6204694d34e973e8339077
+0,        166,        166,        0,      816, 6819a34c7e3c13bee3ea2b18e12e92fd
+0,        200,        200,        0,      816, f75920457f01f65bf30ba1ec41076d4e
+0,        233,        233,        0,      816, 3a04f6cc0c348c21464b173ac6005043
+0,        266,        266,        0,      816, 93a3336374e8cc4dfb2c0b4716ab60ec
+0,        300,        300,        0,      816, 148af188b8a2ee93de406a01c2af180d
diff --git a/tests/ref/fate/vp9-02-size-34x18 b/tests/ref/fate/vp9-02-size-34x18
new file mode 100644
index 0000000..d877088
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-34x18
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      918, ab7eabb355e5163e7451945018fadebd
+0,         33,         33,        0,      918, b9a77cc0c769535808996a6de7b374ff
+0,         66,         66,        0,      918, bd773f11d89091b3c9ebc22d8291dd49
+0,        100,        100,        0,      918, 278c215d6c188752818f07f4d317c0e0
+0,        133,        133,        0,      918, b59856932c675c1ba587644c23cdb002
+0,        166,        166,        0,      918, 2bcaef04f89326a56025269a68742043
+0,        200,        200,        0,      918, 5abb4a1b96b4bc003cd19a146347c54e
+0,        233,        233,        0,      918, 26e36058f451ff80d498ac1c0343489f
+0,        266,        266,        0,      918, 57ac43fcc6f1a2c863188aca68d52524
+0,        300,        300,        0,      918, 282467118b5b7a986ccd28d16dab3ea7
diff --git a/tests/ref/fate/vp9-02-size-34x32 b/tests/ref/fate/vp9-02-size-34x32
new file mode 100644
index 0000000..ce29241
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-34x32
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1632, 7e334867e27046fabf0f39365311c38c
+0,         33,         33,        0,     1632, d2a49216ecedea62f546e54c1552f163
+0,         66,         66,        0,     1632, f66e10d1779533e5b6e2b98369134833
+0,        100,        100,        0,     1632, 0054b8d4393df58eee87784862a29901
+0,        133,        133,        0,     1632, b9cdf3ebea0d1e3f1e0c42db2e11a3c2
+0,        166,        166,        0,     1632, c08a728d955a559457c82e44c3296148
+0,        200,        200,        0,     1632, d05f4c4a8b0e606525c3d388d26a9351
+0,        233,        233,        0,     1632, 78fc2544da88a1a21d6626b0f7bbcf8c
+0,        266,        266,        0,     1632, 90832c4fed05390377551359bb9a91f7
+0,        300,        300,        0,     1632, 5290a0e77081863398f36c7ae192710b
diff --git a/tests/ref/fate/vp9-02-size-34x34 b/tests/ref/fate/vp9-02-size-34x34
new file mode 100644
index 0000000..fc5b90c
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-34x34
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1734, 1bb98ba89abf6b86f47a851f8126e1ff
+0,         33,         33,        0,     1734, b960cc795c179afe7eec360c57fddd7f
+0,         66,         66,        0,     1734, a93cd094a80c542ecb7b6ac7720c5eff
+0,        100,        100,        0,     1734, f1cd34e4f0bf9b1238769f028708b742
+0,        133,        133,        0,     1734, f01437ad14450d2136a8fc971f180eb7
+0,        166,        166,        0,     1734, 8778230f1182c2227bf1e253bd85df4c
+0,        200,        200,        0,     1734, 1d1d5cf6c5cc9e73a1fa5b882e441d74
+0,        233,        233,        0,     1734, 2f7a1867487c56c252e35225f71adb55
+0,        266,        266,        0,     1734, 1d1aea21f70ceed596f22ec32d8712ee
+0,        300,        300,        0,     1734, 260e66df92f32bc853f4cd4ede692ea4
diff --git a/tests/ref/fate/vp9-02-size-34x64 b/tests/ref/fate/vp9-02-size-34x64
new file mode 100644
index 0000000..e31ad98
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-34x64
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     3264, 3856635223f578e1e7f7e7250a53cb8d
+0,         33,         33,        0,     3264, ee8d7c3a0ea165420d7e733b9e59219a
+0,         66,         66,        0,     3264, 3d33f06bac22131f04e3411fc216dc02
+0,        100,        100,        0,     3264, 7aea667775077de32250dac25fd24bb3
+0,        133,        133,        0,     3264, 43fb534551f153c5e9e60240df0bf3b4
+0,        166,        166,        0,     3264, d42b721aa2242d4258d97f840fdcc901
+0,        200,        200,        0,     3264, e876200d720cbe6e36e0ffb775c5ad6c
+0,        233,        233,        0,     3264, 453078449d8701270564086e58a1d69e
+0,        266,        266,        0,     3264, 22cb799a817d45a7591489e6faa31cb9
+0,        300,        300,        0,     3264, 628dc3f03bf5dd5cae135ad1e4b9ebf7
diff --git a/tests/ref/fate/vp9-02-size-34x66 b/tests/ref/fate/vp9-02-size-34x66
new file mode 100644
index 0000000..2182c29
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-34x66
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     3366, bf4e568217906ee4b58dc4707bee8ef6
+0,         33,         33,        0,     3366, f823f8c7b6e47ba43215f3becd35208e
+0,         66,         66,        0,     3366, 1d986d65b502e77764428e21e77503a6
+0,        100,        100,        0,     3366, 73520382bc54d6aee165402518dd7b5d
+0,        133,        133,        0,     3366, c84e943758f2d7e37126172728838640
+0,        166,        166,        0,     3366, 1d4b298da98e4b66b31ad6874f726aa6
+0,        200,        200,        0,     3366, e67748eeb3c818deb8b51d321cd16a9c
+0,        233,        233,        0,     3366, 4d1514c63e669261beef9e35b04c241e
+0,        266,        266,        0,     3366, 57705e2131e2129efbc68b74a1e0459c
+0,        300,        300,        0,     3366, 681acf1b384856d6e544d8e7a79fc628
diff --git a/tests/ref/fate/vp9-02-size-64x08 b/tests/ref/fate/vp9-02-size-64x08
new file mode 100644
index 0000000..b15296a
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-64x08
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      768, d801797c94039b0a166d46e151ec912c
+0,         33,         33,        0,      768, 161ec22caa3689b214d9ab993424584b
+0,         66,         66,        0,      768, 499b589ecf1873e388c256ce948eabb9
+0,        100,        100,        0,      768, 22bc77650e3df70e3e36f2a1b8d8aa71
+0,        133,        133,        0,      768, 750e40530257a68211596a60de18bffa
+0,        166,        166,        0,      768, 4f812a92157e7186642656b59bc28a3d
+0,        200,        200,        0,      768, a3f141cec127a2c2e16740b8dd4ce56a
+0,        233,        233,        0,      768, a5ba9959bf65ab6e254e5b359a3d59b5
+0,        266,        266,        0,      768, baa72b8a57277d9e9ad4b92aab04f5d1
+0,        300,        300,        0,      768, 4cb9aebb6c9d5bd164461726de201549
diff --git a/tests/ref/fate/vp9-02-size-64x10 b/tests/ref/fate/vp9-02-size-64x10
new file mode 100644
index 0000000..e499cc9
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-64x10
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      960, 97eb5fd0599d482662eb0a1def5c5ef2
+0,         33,         33,        0,      960, dfdc1b61b478dcca8d411021486aa2ec
+0,         66,         66,        0,      960, 2cf560f068bdcb9e345951739091808e
+0,        100,        100,        0,      960, 33cacb04c0797fc7bd774251e04b7fb9
+0,        133,        133,        0,      960, 7fca126c0542c0dcdcf769b156bd85f5
+0,        166,        166,        0,      960, 8a46c5a48cb5bd34be8e647c127f8d61
+0,        200,        200,        0,      960, 1ddf07562c0b7dc68ed61b8e1a09fcf0
+0,        233,        233,        0,      960, d75911d5eb7fc75ffc3ee40344fc7ed2
+0,        266,        266,        0,      960, 498329c8a01d950286af11e1fcf3ac07
+0,        300,        300,        0,      960, 7a6ec019df5f3e419d389699094f87c3
diff --git a/tests/ref/fate/vp9-02-size-64x16 b/tests/ref/fate/vp9-02-size-64x16
new file mode 100644
index 0000000..4810a6e
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-64x16
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1536, a43068a364cc42619e62406dcf17ddfc
+0,         33,         33,        0,     1536, 94691f93299bbf5b6ba3022b02b3e069
+0,         66,         66,        0,     1536, 3c8fc275490b4daf63ef6d8f9b7f81f6
+0,        100,        100,        0,     1536, 96c06031f0fcad49dfed256c5c737d07
+0,        133,        133,        0,     1536, f722d3a51790b55d070d57d3b9a53d0d
+0,        166,        166,        0,     1536, a753b3dfe13f5778f9f054e73e512ef1
+0,        200,        200,        0,     1536, fa12cbe6cbc38fa8a38ecbcf1af8833c
+0,        233,        233,        0,     1536, cb42303391ef6f76f77d14d2600cce12
+0,        266,        266,        0,     1536, e0c18bb1d4dcc8168b5fdd7c7963987e
+0,        300,        300,        0,     1536, 581b5291cb60e50326c0dfa6a2d09d8a
diff --git a/tests/ref/fate/vp9-02-size-64x18 b/tests/ref/fate/vp9-02-size-64x18
new file mode 100644
index 0000000..1f8fdf3
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-64x18
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1728, adf7e84a351847683f6a8dd177019e29
+0,         33,         33,        0,     1728, 8227cf283a27277fbab3d7826e340337
+0,         66,         66,        0,     1728, a5551b16db948e395537310d12128e76
+0,        100,        100,        0,     1728, 4b57ed07dbc15de9ab6143656b2a7e8e
+0,        133,        133,        0,     1728, a15489495f0acc41f446e9689e4142d6
+0,        166,        166,        0,     1728, b0a0d5d3ff756e8ae19797455432755c
+0,        200,        200,        0,     1728, 094a440243d36edcdd3e9d0d070de011
+0,        233,        233,        0,     1728, a780bd61e1abbfbb28581784531608bd
+0,        266,        266,        0,     1728, 55886a8c7aad65683aa9366a38382512
+0,        300,        300,        0,     1728, 5ae5b24383f66720a62ed1001664051f
diff --git a/tests/ref/fate/vp9-02-size-64x32 b/tests/ref/fate/vp9-02-size-64x32
new file mode 100644
index 0000000..ed1c9a5
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-64x32
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     3072, 931ab6a2482c3e84bc7ef8dfbc251307
+0,         33,         33,        0,     3072, 3552a9d8470a64ed627a6dbb799b7811
+0,         66,         66,        0,     3072, cae1863fc606a0e3df3e708b7eefdf99
+0,        100,        100,        0,     3072, 4b825a07e235c4708b12a726da8e4cdf
+0,        133,        133,        0,     3072, 0dac578ef616a13be2b9db3c0d775524
+0,        166,        166,        0,     3072, bfd47cbab8285f301777351c8bc5553c
+0,        200,        200,        0,     3072, f29f9a0cfeaaae3bdeb26933bc7c17dc
+0,        233,        233,        0,     3072, c7f3a4d24dcf72ef195a402eff77d8f6
+0,        266,        266,        0,     3072, 88ede6207441a7953cf893032c353663
+0,        300,        300,        0,     3072, 258f4e86541813e3edb1fe5332ff4ab1
diff --git a/tests/ref/fate/vp9-02-size-64x34 b/tests/ref/fate/vp9-02-size-64x34
new file mode 100644
index 0000000..c90f7e3
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-64x34
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     3264, 68d00958a78e6252dd75d632806e2022
+0,         33,         33,        0,     3264, f7b6266e74200a669eecd241db787ee2
+0,         66,         66,        0,     3264, c8b88d43aee037857310edeb74bc66f4
+0,        100,        100,        0,     3264, c6d9a52baf3ca962574bff1364fcb8dc
+0,        133,        133,        0,     3264, b384fbf3ceef0affa69f5e81681edc6e
+0,        166,        166,        0,     3264, cd473f0c8d1cde98153402123a3ee7cf
+0,        200,        200,        0,     3264, c0f320a23c3e39719a3b3590fe3c2ab5
+0,        233,        233,        0,     3264, 751207d15a791728c1022f711a25cd68
+0,        266,        266,        0,     3264, 7396df89a0d88044cf7527420d193636
+0,        300,        300,        0,     3264, b772dd247838b0c3ed12713447894323
diff --git a/tests/ref/fate/vp9-02-size-64x64 b/tests/ref/fate/vp9-02-size-64x64
new file mode 100644
index 0000000..743732b
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-64x64
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     6144, 35f17db9076fa20368fddfa01543c746
+0,         33,         33,        0,     6144, 61cd775dfc177262da9a91d3912e6718
+0,         66,         66,        0,     6144, 8b8cf175f91425d703332b22b46c1c0e
+0,        100,        100,        0,     6144, 6041afbdd81e228f8f16384d3f9e988e
+0,        133,        133,        0,     6144, d30bd08897b50f518920014c7fa55df9
+0,        166,        166,        0,     6144, fb67222a183876b502f93e48bb779b70
+0,        200,        200,        0,     6144, 60830425ca1dcf3df4ee9c6cd75f066a
+0,        233,        233,        0,     6144, 3e178df858f7fcaa2552a1c5c719b5cc
+0,        266,        266,        0,     6144, 66718eb0c3981beb7c1119df8a2cd27e
+0,        300,        300,        0,     6144, 7c1912448c7756f7451888050760d73d
diff --git a/tests/ref/fate/vp9-02-size-64x66 b/tests/ref/fate/vp9-02-size-64x66
new file mode 100644
index 0000000..7f2a052
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-64x66
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     6336, 88587de65acfc85ff56daac8ef5d12e6
+0,         33,         33,        0,     6336, be41f6c788b929b5b6b27c5674f40abd
+0,         66,         66,        0,     6336, 04ab3f88ca062a6911405fd84c7e9de4
+0,        100,        100,        0,     6336, 231436e0a68d19d3882f285d38aca3fb
+0,        133,        133,        0,     6336, 1a067e147a6740bb4ce57c4184437eea
+0,        166,        166,        0,     6336, be0c47e06c7e9439570473adf4713f5f
+0,        200,        200,        0,     6336, a213b0611247eafab0711748c25e88a0
+0,        233,        233,        0,     6336, b1df495aa3afb74399f91c74b527b93c
+0,        266,        266,        0,     6336, 46319f21069541e1ee1652621b957860
+0,        300,        300,        0,     6336, 313517a5721b2b14683e7eefc83e51b1
diff --git a/tests/ref/fate/vp9-02-size-66x08 b/tests/ref/fate/vp9-02-size-66x08
new file mode 100644
index 0000000..76ec31e
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-66x08
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      792, 3b16847e60786706fc339abc452746ff
+0,         33,         33,        0,      792, 365a5951cb127d6df183fe5d5000f493
+0,         66,         66,        0,      792, 6d4bceb815ca7717c4a3f86a6670703a
+0,        100,        100,        0,      792, 5a0a03d4788934285448c85788ae8d71
+0,        133,        133,        0,      792, 8712f9a82d07447e7a0d0a37ddc3858d
+0,        166,        166,        0,      792, cff32e6c183c16962207a86d7c6cf0a0
+0,        200,        200,        0,      792, dc933d90f87110651d7efb39854d3d46
+0,        233,        233,        0,      792, d1299562a022521f0c3cb30668f83b6d
+0,        266,        266,        0,      792, 5054254ca125d7c7e6df4001397170cd
+0,        300,        300,        0,      792, a6bd7c7c0b02afa8d25f911ec847c61a
diff --git a/tests/ref/fate/vp9-02-size-66x10 b/tests/ref/fate/vp9-02-size-66x10
new file mode 100644
index 0000000..63c775b
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-66x10
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,      990, 7cbd8c6b2fb35c0c3063cb7a379944c9
+0,         33,         33,        0,      990, 14062e74b98bed1ca982f408bc14326c
+0,         66,         66,        0,      990, f6d6868d849aa74b27df1c5f40c7096e
+0,        100,        100,        0,      990, 719c8d7e3769466ee8e3dca3f4747a0e
+0,        133,        133,        0,      990, a72e1a7a4c82ec09ea77f87b0e6f25aa
+0,        166,        166,        0,      990, a5163d142b429afa155cc2f1401a0b8a
+0,        200,        200,        0,      990, 27762d813dd1f80d6aaed5f197124fa5
+0,        233,        233,        0,      990, 02e94454660f3528abbde8f50e94288f
+0,        266,        266,        0,      990, 1d57dcfa57a55d96f14cfe471aac2e0b
+0,        300,        300,        0,      990, 7804477923c0cd067bd09ebca3529775
diff --git a/tests/ref/fate/vp9-02-size-66x16 b/tests/ref/fate/vp9-02-size-66x16
new file mode 100644
index 0000000..97d67c8
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-66x16
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1584, fa2f292d273c37dc2804a70d1cae1e9d
+0,         33,         33,        0,     1584, ba75d90652c021bc7ca061352e6e94ce
+0,         66,         66,        0,     1584, e65d9a205bd17d100e50c7b6a7ea772d
+0,        100,        100,        0,     1584, 46f9e9ff891576b9462f21d48b7b9e2b
+0,        133,        133,        0,     1584, d23cedacf3a37cf6b2774e0b18b6b9d7
+0,        166,        166,        0,     1584, 84329f7716a6db5a7e64a68a1155bfc6
+0,        200,        200,        0,     1584, ad62286b0e13f4e54df4445cdd4fd4e3
+0,        233,        233,        0,     1584, 4511529eb24b21eb63e280070f888642
+0,        266,        266,        0,     1584, 4e1c122df1785e0e9134c43c85082e05
+0,        300,        300,        0,     1584, ac3a3747a00be3f9f58155648fcf9b24
diff --git a/tests/ref/fate/vp9-02-size-66x18 b/tests/ref/fate/vp9-02-size-66x18
new file mode 100644
index 0000000..03928de
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-66x18
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     1782, fda5ad9bf70a51b3a41bdcabf2cce32a
+0,         33,         33,        0,     1782, 91916fb20ad542a7a3ad276e6505f9b0
+0,         66,         66,        0,     1782, e18e5d11aec483c76afd68f7e64415a4
+0,        100,        100,        0,     1782, c13da01c2b6c09101bda7af93ad5fd07
+0,        133,        133,        0,     1782, ed8d2568b2ad9c7bd980cba0d3b95cff
+0,        166,        166,        0,     1782, e6f3cf312b69d37579e77f2e52cc936b
+0,        200,        200,        0,     1782, e509f3682e9c4bcdb0889e044b1979b7
+0,        233,        233,        0,     1782, acc3945e557cd7a9642f08a656444976
+0,        266,        266,        0,     1782, 44ddd03aa8f03ba393f12fc6a1b3fc17
+0,        300,        300,        0,     1782, fdd3e68132c742d9f0cf0ea6fff2a074
diff --git a/tests/ref/fate/vp9-02-size-66x32 b/tests/ref/fate/vp9-02-size-66x32
new file mode 100644
index 0000000..0901a7b
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-66x32
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     3168, 013cd22aea6bfeccc8ec809abd52be5c
+0,         33,         33,        0,     3168, 0980adfb0ef879b3c960797272f025ad
+0,         66,         66,        0,     3168, d1411ffa0429befb8c71d3ab45acee92
+0,        100,        100,        0,     3168, 6c6f825379eaf21709a45be77def7a63
+0,        133,        133,        0,     3168, bab632ef00a080739a41c692f2b21c3a
+0,        166,        166,        0,     3168, fc0f6045aca252f2e904730227b8f337
+0,        200,        200,        0,     3168, c8dbea209329463bfd9238a11b8d5b17
+0,        233,        233,        0,     3168, 457247bf4186ed8459e0a1564f0e68f2
+0,        266,        266,        0,     3168, baa55e20bd7c73960b080d8a0c8db4d5
+0,        300,        300,        0,     3168, dc8933e8edc98cd0cfca44ae22997c62
diff --git a/tests/ref/fate/vp9-02-size-66x34 b/tests/ref/fate/vp9-02-size-66x34
new file mode 100644
index 0000000..a999573
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-66x34
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     3366, 6821eb3fcd1d10db32eff70468dcf9c1
+0,         33,         33,        0,     3366, ed0094d347d9f250d46b4903cbc14801
+0,         66,         66,        0,     3366, fd018555dc9a62b8074d46e7c0fd0b40
+0,        100,        100,        0,     3366, 05d5baf9f2e62bbeeb3809a099e84147
+0,        133,        133,        0,     3366, 7a150c265214269c08e05fe4f296122d
+0,        166,        166,        0,     3366, 9a7ae61d4bb125ee4c4ccce9cc1c3664
+0,        200,        200,        0,     3366, 5a88fd6d96dcbc4255e98dfe19ff96b8
+0,        233,        233,        0,     3366, 4192c273a46b2b196c871ead0e61ec71
+0,        266,        266,        0,     3366, e79ebfc47e755f5db221f392c3216278
+0,        300,        300,        0,     3366, b995c5f483a2e553baf4f66d1a47fc57
diff --git a/tests/ref/fate/vp9-02-size-66x64 b/tests/ref/fate/vp9-02-size-66x64
new file mode 100644
index 0000000..3a3d6c8
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-66x64
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     6336, 929086fbb3e117bd53110b64c1ee915b
+0,         33,         33,        0,     6336, 9ed45f5e40dd2393434e14a0c0160c63
+0,         66,         66,        0,     6336, 5cdade692b1baf23e61896da18e3e44f
+0,        100,        100,        0,     6336, 11a2ebac61a3f826ec41c8031899e55c
+0,        133,        133,        0,     6336, 621a1e0142b94d14db9c2121553a11fb
+0,        166,        166,        0,     6336, 029a29590f7255f1bc9ff9b7a000ca25
+0,        200,        200,        0,     6336, 5fde42becf6bf054d04e2a0fa1b2d55e
+0,        233,        233,        0,     6336, 5b8ba552cef1931e1412fb4f3420748b
+0,        266,        266,        0,     6336, d41cd7d418f6ec1db802a01a90cfee1e
+0,        300,        300,        0,     6336, cea99c93a84a82edff8c6069d131453f
diff --git a/tests/ref/fate/vp9-02-size-66x66 b/tests/ref/fate/vp9-02-size-66x66
new file mode 100644
index 0000000..5c4e1ac
--- /dev/null
+++ b/tests/ref/fate/vp9-02-size-66x66
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,     6534, 69f9028d52f95d2e7f986c57b19fc018
+0,         33,         33,        0,     6534, 068e611f62b3f6222f6b1699748c8fbf
+0,         66,         66,        0,     6534, 3d3fec78ff2274241a7958f17a773a19
+0,        100,        100,        0,     6534, 93d71ef1a2d00c7e70e76ccc1859143d
+0,        133,        133,        0,     6534, 5a35a640d52bc0930825b963b0b9e830
+0,        166,        166,        0,     6534, 782223239e6b1ca1bedbd25d9652a07c
+0,        200,        200,        0,     6534, a4b5e8a319cbc9a12d3e36127c7f0fbb
+0,        233,        233,        0,     6534, a3e2d9a78fa42b3c817aadfd31fd2d16
+0,        266,        266,        0,     6534, e9fc6b83535735f46006f3e4b376755f
+0,        300,        300,        0,     6534, 80223f600dfe86021bd0e83fecdc4b2b
diff --git a/tests/ref/fate/vp9-03-deltaq b/tests/ref/fate/vp9-03-deltaq
new file mode 100644
index 0000000..c8ed23f
--- /dev/null
+++ b/tests/ref/fate/vp9-03-deltaq
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   126720, 2f90d606edc511c8c960530dd915cb98
+0,         33,         33,        0,   126720, 7fd451a057d6341b2b0d116f59e41a13
diff --git a/tests/ref/fate/vp9-03-size-196x196 b/tests/ref/fate/vp9-03-size-196x196
new file mode 100644
index 0000000..39efcba
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-196x196
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    57624, 14cc1c34b8106e35238d4650a9123852
+0,         33,         33,        0,    57624, 66e0bb9136ea24e30b781a4610b428a1
+0,         66,         66,        0,    57624, 8e36679c20a3a3e974fdacf7a9343817
+0,        100,        100,        0,    57624, 2669fd03ce7ce01f4fc9db23e06fffdb
+0,        133,        133,        0,    57624, 46ced29eb6edf2136c8ee19e9a87380f
+0,        166,        166,        0,    57624, 4e4138b65a30bc56cd18663a1799f98f
+0,        200,        200,        0,    57624, 580b0431b5f808c67e50ed34e62f39ad
+0,        233,        233,        0,    57624, 1339bbe256d8499ab17d6a550f7dac70
+0,        266,        266,        0,    57624, 89b9dac29a4c4136249c40a3763dc114
+0,        300,        300,        0,    57624, a735d341d7df9dcd0b6e51a82b813f61
diff --git a/tests/ref/fate/vp9-03-size-196x198 b/tests/ref/fate/vp9-03-size-196x198
new file mode 100644
index 0000000..b328ab4
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-196x198
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    58212, d2bd2dfaf2ac22b3f2499844f228d89a
+0,         33,         33,        0,    58212, e066448baeb39da04b22d4d2ebd27b0a
+0,         66,         66,        0,    58212, aace53c0ecca2596c51dd5e70da7abc4
+0,        100,        100,        0,    58212, 077256d024ab101918d10ae61142f203
+0,        133,        133,        0,    58212, e2bfdad36b0365d41dc6813a371111ee
+0,        166,        166,        0,    58212, 17495af68b0a2c075899849382f3b046
+0,        200,        200,        0,    58212, 7853db163344798e5c37672adaac92d8
+0,        233,        233,        0,    58212, 7b2ee2e1ca709c58457c7d818e47c95c
+0,        266,        266,        0,    58212, f7eb3ce10561628f932861358a30b414
+0,        300,        300,        0,    58212, 3182374f5aa539fd0faa44ed4a7492e5
diff --git a/tests/ref/fate/vp9-03-size-196x200 b/tests/ref/fate/vp9-03-size-196x200
new file mode 100644
index 0000000..0aed802
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-196x200
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    58800, b2f2ac3e3833ae1b4dd075fe00210373
+0,         33,         33,        0,    58800, c0cce05e56a07111fe62553fa3a87074
+0,         66,         66,        0,    58800, 626aab3de03242073e03504e166b4697
+0,        100,        100,        0,    58800, 574d2c810f0bbfac57f1f06c2b97445c
+0,        133,        133,        0,    58800, 7d5bc5860bd1422d08396fe080452099
+0,        166,        166,        0,    58800, 5d47bbfb0f5cdecfe8415ca2caddc206
+0,        200,        200,        0,    58800, fbef6a0fa51029d0475975945ccf4b36
+0,        233,        233,        0,    58800, c9179c153bcb2a8e9d17ed04e5e2c39c
+0,        266,        266,        0,    58800, 107d796592cf2140d4d492beadba2d68
+0,        300,        300,        0,    58800, eee46f9ee67fc1121bffb63aeb7c768f
diff --git a/tests/ref/fate/vp9-03-size-196x202 b/tests/ref/fate/vp9-03-size-196x202
new file mode 100644
index 0000000..9f8c3f2
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-196x202
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    59388, 7109d2ef160828ece26337f36fcfc092
+0,         33,         33,        0,    59388, bdaa6612f81a956d9b20d55a04df8346
+0,         66,         66,        0,    59388, 15eb75495d2713a64415b990b058d5ca
+0,        100,        100,        0,    59388, b997c84553475ba84e8ba3d7ee19ae4e
+0,        133,        133,        0,    59388, 63a8badd691bcf643cf676d029ce8a6c
+0,        166,        166,        0,    59388, b8ca23d9b3418c4c36040a215b2b7917
+0,        200,        200,        0,    59388, 1be0da18386c35e4a5e5d5d32d9a4468
+0,        233,        233,        0,    59388, e75a03fa70fe7e6b3a8d8ce7dc8305f1
+0,        266,        266,        0,    59388, cbd2b60df9209025c8e890771a05321d
+0,        300,        300,        0,    59388, c655d6fcc3333917b66358a9ac2b1357
diff --git a/tests/ref/fate/vp9-03-size-196x208 b/tests/ref/fate/vp9-03-size-196x208
new file mode 100644
index 0000000..2e68802
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-196x208
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    61152, efa2a2a76a0fe709a78e491346cfcf29
+0,         33,         33,        0,    61152, 97de85e21b408878853fa870104707d7
+0,         66,         66,        0,    61152, 419bd1157e156d3059190d6b561c57dd
+0,        100,        100,        0,    61152, fbb6e01c524fc7c8007c6cfe2c64f467
+0,        133,        133,        0,    61152, 7453994c2e9901fa23f295ec0b556f9c
+0,        166,        166,        0,    61152, ba39dc984789fa2c4b833cd88013cc97
+0,        200,        200,        0,    61152, cea5061cac1be18d5f9a9301a5460491
+0,        233,        233,        0,    61152, 1c583018c425b1a91949e0c3eb0a4152
+0,        266,        266,        0,    61152, b48be02280ac6f97731af69bcf18de25
+0,        300,        300,        0,    61152, 6f8ab465214d8374c9ff77b939da333e
diff --git a/tests/ref/fate/vp9-03-size-196x210 b/tests/ref/fate/vp9-03-size-196x210
new file mode 100644
index 0000000..7d24b47
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-196x210
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    61740, fccc18714a9ed3840bd6e9c6ca4858e5
+0,         33,         33,        0,    61740, a8f6eb43cf6ed670eb180c5051de06f7
+0,         66,         66,        0,    61740, 6a9baf9eae6e799deaefd6e801f7ace3
+0,        100,        100,        0,    61740, 3bb44c8a45aab088c9887c11bc6a4acf
+0,        133,        133,        0,    61740, 0907a7e926be9e54bbb087251b4715d9
+0,        166,        166,        0,    61740, 10fef2876c20eb3f9570c0c23e5acc69
+0,        200,        200,        0,    61740, ffe5d2b6d874af0f878075c97940ccfb
+0,        233,        233,        0,    61740, d10fae10144ff88075048827203f7e9c
+0,        266,        266,        0,    61740, bdf35736ac625f2178902c1f24d513c0
+0,        300,        300,        0,    61740, 30882bf2c21785be6234b637c4b16b28
diff --git a/tests/ref/fate/vp9-03-size-196x224 b/tests/ref/fate/vp9-03-size-196x224
new file mode 100644
index 0000000..152de0d
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-196x224
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    65856, 13263674ea5aa619250dfd139bda872f
+0,         33,         33,        0,    65856, 39f5cbd8917f2b3a1df8cf2b786266de
+0,         66,         66,        0,    65856, f9aade31f9e3065f3d5b8645ef099ac6
+0,        100,        100,        0,    65856, 124f9664380f092e692b5e881f5a8fcc
+0,        133,        133,        0,    65856, e8e040e417830f5e911537828ace21b7
+0,        166,        166,        0,    65856, 84ce09882b9c184a787e8022e6d8c8de
+0,        200,        200,        0,    65856, b1397fd91814e4fdc4f75c89161ced26
+0,        233,        233,        0,    65856, d64f39d64d248f0223ed359e092d46cb
+0,        266,        266,        0,    65856, e04ee663dcc52eebd74255671c6f4ec9
+0,        300,        300,        0,    65856, 955303cb73bf072c693f37d9778ca2b6
diff --git a/tests/ref/fate/vp9-03-size-196x226 b/tests/ref/fate/vp9-03-size-196x226
new file mode 100644
index 0000000..974ab53
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-196x226
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    66444, 5cb240f10761f59687612ed589759800
+0,         33,         33,        0,    66444, 9d8d5b57336ddfa5c9c5100a0302197d
+0,         66,         66,        0,    66444, 9db74997d23b16f527c63e88795331dc
+0,        100,        100,        0,    66444, 52758cd901533e790334d464bee516da
+0,        133,        133,        0,    66444, 40e671b9b85d07b13acba85eb64bbbaa
+0,        166,        166,        0,    66444, 8524b2cd2c9bb3e41c6167f8269e75d2
+0,        200,        200,        0,    66444, ff194ad6fa180fde86cc05a99c0580ec
+0,        233,        233,        0,    66444, 22ab303cb37745a73c227cd7d1c70003
+0,        266,        266,        0,    66444, 01986c58e82e0b5194418f5b75a8599c
+0,        300,        300,        0,    66444, eedfc9c14cbf3fa10402dbed52103848
diff --git a/tests/ref/fate/vp9-03-size-198x196 b/tests/ref/fate/vp9-03-size-198x196
new file mode 100644
index 0000000..595299e
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-198x196
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    58212, c980866a6f17d4107ce128ee112d74cf
+0,         33,         33,        0,    58212, d4d5d2a10e73f1d09919355dc4d63d48
+0,         66,         66,        0,    58212, 82c76ed020acb68ff9d8bd81899aa6f8
+0,        100,        100,        0,    58212, 8330705fa354fb5838af56dcf9cc0980
+0,        133,        133,        0,    58212, e47b63d839a592e6372d18249bf5bc0c
+0,        166,        166,        0,    58212, b6095b6f752a50e96cab52e7c3fd52f3
+0,        200,        200,        0,    58212, fc4786f48b6ee31043d94f79c5c8a54f
+0,        233,        233,        0,    58212, 7d3d06c96496bd5ab44fe5489877771d
+0,        266,        266,        0,    58212, 5b96de089a9faa2dc01697fe9dd97f7f
+0,        300,        300,        0,    58212, d7361203b4c264067dcb7bf6912e8df2
diff --git a/tests/ref/fate/vp9-03-size-198x198 b/tests/ref/fate/vp9-03-size-198x198
new file mode 100644
index 0000000..890dd9c
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-198x198
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    58806, ee0760611da9938e72f551d219671c76
+0,         33,         33,        0,    58806, c512cb8a864c25318254438c7170f373
+0,         66,         66,        0,    58806, aaea10aeb7dfd1f9f6dc77adccfcd56f
+0,        100,        100,        0,    58806, fb4e68ce202d9c6ecbddc6fe50b1cd7b
+0,        133,        133,        0,    58806, 57a803d02f0d71ec4c3c17a112574525
+0,        166,        166,        0,    58806, 526d0beaf7ef721c3a6ae8bf3505fd78
+0,        200,        200,        0,    58806, 972ab31f81dbb79c2273bcfc98569e8b
+0,        233,        233,        0,    58806, e1f05d62691bd1a9494d57449417415c
+0,        266,        266,        0,    58806, bc39a559b25e5a1ac698e0101bd6bf29
+0,        300,        300,        0,    58806, 04caed04ac21c76af873e21899860fb2
diff --git a/tests/ref/fate/vp9-03-size-198x200 b/tests/ref/fate/vp9-03-size-198x200
new file mode 100644
index 0000000..2535ceb
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-198x200
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    59400, fb0e8171b0f91d9b2ceb5430db27a67b
+0,         33,         33,        0,    59400, 73f121e6aa0e6290cfd06ac9b033c772
+0,         66,         66,        0,    59400, 4113897efc44f49f5169a579bee03596
+0,        100,        100,        0,    59400, aec1d4cf1a15e12b689980cfe136d5d6
+0,        133,        133,        0,    59400, 1322af65f647254330120e67ddae38bd
+0,        166,        166,        0,    59400, 5d28c1684451812c9db41433e6286d85
+0,        200,        200,        0,    59400, 33843fc49d1d8655520c2f42332222ca
+0,        233,        233,        0,    59400, 92a8125d8c75eaf6159d5f431c5c71bf
+0,        266,        266,        0,    59400, 5bc96553842f65a3e37f012b72b580f5
+0,        300,        300,        0,    59400, de5eb6299ee5034dc3b01cdc94bf810a
diff --git a/tests/ref/fate/vp9-03-size-198x202 b/tests/ref/fate/vp9-03-size-198x202
new file mode 100644
index 0000000..ba4d425
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-198x202
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    59994, f5e1cf4cc56742fadddf42189a3f65e3
+0,         33,         33,        0,    59994, f3e8ca2c8deb29a6b5bfe415b39c901e
+0,         66,         66,        0,    59994, 89c513049e41e145bca46a7f7119567c
+0,        100,        100,        0,    59994, 419089035739e84f1aa14ccdf34edcb1
+0,        133,        133,        0,    59994, 4962c98c23b16b9257869a8ad5138731
+0,        166,        166,        0,    59994, fde9e858ec895c36c2d8071e69f68db6
+0,        200,        200,        0,    59994, 42e1271915f31a00be3627fa866ce3ee
+0,        233,        233,        0,    59994, c15f794933f913861a6d0041ff2fccdb
+0,        266,        266,        0,    59994, 35dab245ba952dc6fddc1a9668c30b28
+0,        300,        300,        0,    59994, 30bb4ef77cdde9cf5aea0f1287183b23
diff --git a/tests/ref/fate/vp9-03-size-198x208 b/tests/ref/fate/vp9-03-size-198x208
new file mode 100644
index 0000000..49fea91
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-198x208
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    61776, d45b561f81cbfcca8a1dddbc2bf8ca31
+0,         33,         33,        0,    61776, 3664f63b2e59e380622caadb7a05545e
+0,         66,         66,        0,    61776, 0662fa199512320704efecc10af1aaa4
+0,        100,        100,        0,    61776, d8dc00882e73be89d0585663892cbcff
+0,        133,        133,        0,    61776, ff64b8d50b7c5b484a06dab09a26147c
+0,        166,        166,        0,    61776, 1771b6a55112eb7ea10885d1390339cc
+0,        200,        200,        0,    61776, 0d5944e8a13e3c2faffb562bbe2671a8
+0,        233,        233,        0,    61776, 744bed3a88407b75a8ff27a1b0cec64e
+0,        266,        266,        0,    61776, 3887415f2ab10d2a265c4a413e7060b9
+0,        300,        300,        0,    61776, 7dd683019b19b464bc0436f41e0b7c87
diff --git a/tests/ref/fate/vp9-03-size-198x210 b/tests/ref/fate/vp9-03-size-198x210
new file mode 100644
index 0000000..899fd50
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-198x210
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    62370, 8525a27170982c059d5904c1af3b43fb
+0,         33,         33,        0,    62370, c4eb329733913360384d3917a58f6f36
+0,         66,         66,        0,    62370, ec118b87c9cba0e4bd89fd43567cca4e
+0,        100,        100,        0,    62370, 7e57c6caba7924823977e2c9bc11f7fa
+0,        133,        133,        0,    62370, f77ffb7228a5eda848acc40ff636ecad
+0,        166,        166,        0,    62370, c5dddafbe3badcbbcaaebe97076e0394
+0,        200,        200,        0,    62370, 34d69ae2e5b4c4fbcc51627237c9abc5
+0,        233,        233,        0,    62370, d9c63fa8b18d6c54e5fa31db866c06cc
+0,        266,        266,        0,    62370, 7ab392764a399328bf35977539e3148a
+0,        300,        300,        0,    62370, 7fbb7bae3ec775298aaa49a286dfb9d1
diff --git a/tests/ref/fate/vp9-03-size-198x224 b/tests/ref/fate/vp9-03-size-198x224
new file mode 100644
index 0000000..b972f6a
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-198x224
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    66528, 5f69230bfd8bb485bd85552b18339fc0
+0,         33,         33,        0,    66528, f5c365774fc1d0bffd5025ce2e931aaf
+0,         66,         66,        0,    66528, 2898234103c3624e6470ae82c916e000
+0,        100,        100,        0,    66528, d82a7fa705180b68a8ee8cb7de0cdd2d
+0,        133,        133,        0,    66528, 144a162d418deae62883a2cc4c341b4c
+0,        166,        166,        0,    66528, b3419a48385e42ca15717289ff2daa1c
+0,        200,        200,        0,    66528, d6306b5737f88f989bf2e6a1084a94fe
+0,        233,        233,        0,    66528, 5669761d7417b52b3cf81d44a13e3fb7
+0,        266,        266,        0,    66528, 3f730b8658d7a6657d1af38c75357512
+0,        300,        300,        0,    66528, 27df68d515148f732325bf821037d59f
diff --git a/tests/ref/fate/vp9-03-size-198x226 b/tests/ref/fate/vp9-03-size-198x226
new file mode 100644
index 0000000..4f622cd
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-198x226
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    67122, 412c33a8fd71c99e68e6701b050b107c
+0,         33,         33,        0,    67122, 8e69483ff8a094096dd550b30be20dde
+0,         66,         66,        0,    67122, b8df87ab3d2613be31a3743e34d7e794
+0,        100,        100,        0,    67122, ec4b08a4014950f1fe04e83f8a790af0
+0,        133,        133,        0,    67122, 030da2b60627d879730108826ce6632c
+0,        166,        166,        0,    67122, 03aab0c9b4d75bc0b47fa5237e9efe3d
+0,        200,        200,        0,    67122, fd01e369df258f340eb8e486c07ae136
+0,        233,        233,        0,    67122, 1c301f0e60c96008fd7b6e8de1ebaa29
+0,        266,        266,        0,    67122, 912723f43b2b36366c3e6ab122d31801
+0,        300,        300,        0,    67122, b2774a66f7aa0fb7dd7e64b0d67818cd
diff --git a/tests/ref/fate/vp9-03-size-200x196 b/tests/ref/fate/vp9-03-size-200x196
new file mode 100644
index 0000000..b0b7ee2
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-200x196
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    58800, 651a0627c6cdaee8b46e1f8c4121a368
+0,         33,         33,        0,    58800, 3e63075148df16f69c933cf6c63e078c
+0,         66,         66,        0,    58800, edf18e52b7d52af2bb7594ed358542d8
+0,        100,        100,        0,    58800, 30284124756d00d10f4f8428206ceab8
+0,        133,        133,        0,    58800, 6f6ecde53cd0ea5298f4529d396460c6
+0,        166,        166,        0,    58800, 0431d389278957fbef3e72f69f3ce008
+0,        200,        200,        0,    58800, a047c60c4c60d2ea1f79c86dc98cdf8e
+0,        233,        233,        0,    58800, dceda8bf128a8cdcadfa6c5db49cde51
+0,        266,        266,        0,    58800, d8a6283637f5abda17e0bf150eac2983
+0,        300,        300,        0,    58800, 33dca31ef26fdd0daf9971c8de685d01
diff --git a/tests/ref/fate/vp9-03-size-200x198 b/tests/ref/fate/vp9-03-size-200x198
new file mode 100644
index 0000000..f7c7c3f
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-200x198
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    59400, d4b3578d800c747bcabaa484a140ffb0
+0,         33,         33,        0,    59400, a40f6f8c384c5dc3d5546d960bb6d9e5
+0,         66,         66,        0,    59400, e270ae8754d9906dd88b1c7d05280801
+0,        100,        100,        0,    59400, bde7fde5012840c5e188f3b29f4f0003
+0,        133,        133,        0,    59400, 8f8510c1130615b64fb8469af66ff678
+0,        166,        166,        0,    59400, 79b9d4e0c64f82a6e9540394222a593d
+0,        200,        200,        0,    59400, 34852ac9ca5c6bfa51736296784343c7
+0,        233,        233,        0,    59400, b055218509dbed644113642f8f0ac8a8
+0,        266,        266,        0,    59400, 1628866b436f1c4b892474025226e545
+0,        300,        300,        0,    59400, 3fdec760c04e30c90e74afb38dbf757c
diff --git a/tests/ref/fate/vp9-03-size-200x200 b/tests/ref/fate/vp9-03-size-200x200
new file mode 100644
index 0000000..6f45370
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-200x200
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    60000, b339f4e563afadb25f43b8c05b12dc03
+0,         33,         33,        0,    60000, 3bd5280e7fb42400085b0b1dbba1905e
+0,         66,         66,        0,    60000, acf1c84cabff763fe2073d2c1f183bfc
+0,        100,        100,        0,    60000, eaa4983b6baf907efb11d137644569d2
+0,        133,        133,        0,    60000, 8a1871c8dc38a19dfd4ac571ad7f39be
+0,        166,        166,        0,    60000, 0be539bd51f5f364828dd0abc70360be
+0,        200,        200,        0,    60000, df60622d2c9f294f61d738be9e3bd16c
+0,        233,        233,        0,    60000, 22b3f1d51ddf92c7d2add305ba0ef405
+0,        266,        266,        0,    60000, 01ba29be721e64a5a50526de0797c7d3
+0,        300,        300,        0,    60000, 7b7aa7fa0e58202b3104671375762587
diff --git a/tests/ref/fate/vp9-03-size-200x202 b/tests/ref/fate/vp9-03-size-200x202
new file mode 100644
index 0000000..3657e80
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-200x202
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    60600, c4a13df44e66f06961dd72fc990439e9
+0,         33,         33,        0,    60600, 81c73b8d3806ad96af8f422914a253f8
+0,         66,         66,        0,    60600, 05f77526125e802be9cb306e375ded6e
+0,        100,        100,        0,    60600, ab2e224840ff89abec2c675a23a73094
+0,        133,        133,        0,    60600, c30f58f88819eb57102678b169e15188
+0,        166,        166,        0,    60600, 33e5e2799eb4a9c548c8372fd6769db9
+0,        200,        200,        0,    60600, fa53c1c7e60bd1d00335af542ec69ed7
+0,        233,        233,        0,    60600, 534cafe658af10a314d6d084e55b3620
+0,        266,        266,        0,    60600, 502529e4fbecc8b890abf665fa21f53c
+0,        300,        300,        0,    60600, bf1f73c6e77370bc51a770c8ae87bd12
diff --git a/tests/ref/fate/vp9-03-size-200x208 b/tests/ref/fate/vp9-03-size-200x208
new file mode 100644
index 0000000..cd47b57
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-200x208
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    62400, 702748bec18c500dd41d93ae74b11d56
+0,         33,         33,        0,    62400, 4fb542190dab2fd673724d47451ff6ee
+0,         66,         66,        0,    62400, dbb4d27d52797dab67e39d32092c9d44
+0,        100,        100,        0,    62400, e4a0ed1572207b7ba433896bba711148
+0,        133,        133,        0,    62400, 28ec32bc165f4f9d455efec8a7aa8737
+0,        166,        166,        0,    62400, a95910575a6423abffb28ca38c384b34
+0,        200,        200,        0,    62400, 791f1c558c5467725f4614a75a8a687e
+0,        233,        233,        0,    62400, cfd3e12f84f7a811966721e890228313
+0,        266,        266,        0,    62400, 824c5fdf938551c28ac1c996645ae52f
+0,        300,        300,        0,    62400, 7465917fdd0206e393968232a0ec5193
diff --git a/tests/ref/fate/vp9-03-size-200x210 b/tests/ref/fate/vp9-03-size-200x210
new file mode 100644
index 0000000..91eaa80
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-200x210
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    63000, 31ef44bd12ae702f306c55eba10d2ba7
+0,         33,         33,        0,    63000, 83e9d913f5aa058d79a81047ca45e4a2
+0,         66,         66,        0,    63000, b5e21313b859f1e2c67aaac5fefc9f68
+0,        100,        100,        0,    63000, 959d63c1b219c3479af673a9a8b8d82c
+0,        133,        133,        0,    63000, ffcfaf42b69c7cd92f6e3c21987ff7df
+0,        166,        166,        0,    63000, e9667d3ee4d8179da44de4fbffcb7df2
+0,        200,        200,        0,    63000, 5e2c841bcf4ec6f3a05020d36986fe5b
+0,        233,        233,        0,    63000, 19fe287c30bd4c90b00a9631409568c0
+0,        266,        266,        0,    63000, 58a8843e50b19860a0a91e1e1bb63bfd
+0,        300,        300,        0,    63000, 0ebd31e18597a567f96645acbb2500cf
diff --git a/tests/ref/fate/vp9-03-size-200x224 b/tests/ref/fate/vp9-03-size-200x224
new file mode 100644
index 0000000..14f52f6
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-200x224
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    67200, 315d69847bf752a84231a368278eb0b6
+0,         33,         33,        0,    67200, d245738f8627fc345ab38a547bc7d352
+0,         66,         66,        0,    67200, 982681cdca448919c2eead94435772ad
+0,        100,        100,        0,    67200, 7b67b2d96476e17cd407bbccb19fd070
+0,        133,        133,        0,    67200, c38dde73ca097049d1fc689e18a49b5d
+0,        166,        166,        0,    67200, 525f323b81d780c669a03655bb0d0b56
+0,        200,        200,        0,    67200, 5dbeb96f65e383771c1c877ec559044a
+0,        233,        233,        0,    67200, 7d96e976265ef0f9faf173376caaa9e9
+0,        266,        266,        0,    67200, 6047c805a724701b80a133486aae0e65
+0,        300,        300,        0,    67200, eb8895dd994076a52aa3a0c1758ccbb7
diff --git a/tests/ref/fate/vp9-03-size-200x226 b/tests/ref/fate/vp9-03-size-200x226
new file mode 100644
index 0000000..97e600c
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-200x226
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    67800, e45b6b9dce4a8509b7d26bc3cfdf7c86
+0,         33,         33,        0,    67800, ddb9d5033ecfa2d6e9a5505dce374bda
+0,         66,         66,        0,    67800, 52c495d3137143e0bce9382fe5506057
+0,        100,        100,        0,    67800, d09f3d6ad084f2966196acd48246f951
+0,        133,        133,        0,    67800, 1556d006d0119a3172b98a500b27f8d0
+0,        166,        166,        0,    67800, 904f86cfbcc3fa683d3d7744a286cd88
+0,        200,        200,        0,    67800, b35907456b8ccab0ae8efc8405b04c89
+0,        233,        233,        0,    67800, b7f2648fe0f873f7e9ea4a6d913e45ec
+0,        266,        266,        0,    67800, 2da76544bc7e295486c335e17047e12e
+0,        300,        300,        0,    67800, 10fd6424caf837d37564ef15f1c6f93d
diff --git a/tests/ref/fate/vp9-03-size-202x196 b/tests/ref/fate/vp9-03-size-202x196
new file mode 100644
index 0000000..c224ef0
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-202x196
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    59388, 1261466179df96099e598e46c50fa7c1
+0,         33,         33,        0,    59388, cc0fe373cd0399cf0c95edf92d9ab01f
+0,         66,         66,        0,    59388, 7a2dc0afd06ecfcf54321fb759f57601
+0,        100,        100,        0,    59388, db9c138503d27f87449f870ab07cab03
+0,        133,        133,        0,    59388, ddea2e5e2659e97132a537566d5ed989
+0,        166,        166,        0,    59388, c31e90b5eee032526c4e0603332fd160
+0,        200,        200,        0,    59388, 7e5b40f03b905d9ee749d3097a484ea0
+0,        233,        233,        0,    59388, 93e9f7defa94ff03c041448ae1e55cea
+0,        266,        266,        0,    59388, aef8e03f0146699faa16ec28dea49dbe
+0,        300,        300,        0,    59388, a651d949b4c8f0e455c6592dc98385f7
diff --git a/tests/ref/fate/vp9-03-size-202x198 b/tests/ref/fate/vp9-03-size-202x198
new file mode 100644
index 0000000..96a3a1f
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-202x198
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    59994, 181edc4ebeeff7f0527b93b84d5d8efb
+0,         33,         33,        0,    59994, 132c71b634fb67eed51fcdef1775b6b2
+0,         66,         66,        0,    59994, fd41144770765fc893adc5843ebe32e4
+0,        100,        100,        0,    59994, 77dcbaea101142940b6a78a271842829
+0,        133,        133,        0,    59994, 01737c38c1ac711a9744256788211177
+0,        166,        166,        0,    59994, 31cd0b5f621daac309c6f249f4c26cd8
+0,        200,        200,        0,    59994, e06d34e570dc46904fdb9eeb55811464
+0,        233,        233,        0,    59994, 71bf55030373bde1eaeb52d1e97bfa4a
+0,        266,        266,        0,    59994, e96063ff02e8a23a666222b59391de9c
+0,        300,        300,        0,    59994, 5aa0079168ab5069e8a3064f9e2a6d8b
diff --git a/tests/ref/fate/vp9-03-size-202x200 b/tests/ref/fate/vp9-03-size-202x200
new file mode 100644
index 0000000..a8d42a7
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-202x200
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    60600, 20c41d4a1271183dbbc7a44e6b90ea80
+0,         33,         33,        0,    60600, bd8c1fba8d8742f4d98b7d5097c8c828
+0,         66,         66,        0,    60600, 55cbe06a925009c1b1f9b609b60b4c1d
+0,        100,        100,        0,    60600, 78e80c7cf1f142e2dda1bc269b5b3e00
+0,        133,        133,        0,    60600, 42ee8157a4c8af6670b81e9324b251e9
+0,        166,        166,        0,    60600, 022bdf5a2e1ea5f98503cd25b383ae53
+0,        200,        200,        0,    60600, c2073865386a991da01966878ce1ce6d
+0,        233,        233,        0,    60600, 6a5b95cd4eff0836b9180a25f663d36a
+0,        266,        266,        0,    60600, 5e5498c357340d4755dc98eb0669f103
+0,        300,        300,        0,    60600, 0907d5e4020111b1ecfe707df71bcd8a
diff --git a/tests/ref/fate/vp9-03-size-202x202 b/tests/ref/fate/vp9-03-size-202x202
new file mode 100644
index 0000000..9867cc7
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-202x202
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    61206, 610cef52d35e9c641f2b8c10489c3d12
+0,         33,         33,        0,    61206, 1f84062e607d4798b0544739fe0da99c
+0,         66,         66,        0,    61206, ea379947b5c52ea3989dfc3f47c729d9
+0,        100,        100,        0,    61206, 1d06b72f06178cbb6bb5d188d22bff43
+0,        133,        133,        0,    61206, 25bd41bd7607f88a01aa0cdc336c9975
+0,        166,        166,        0,    61206, 86836a95a7a9fb1eefb20f7c5a15a9ab
+0,        200,        200,        0,    61206, d8eb3fecce1b646b9877cd4fcca9f9bf
+0,        233,        233,        0,    61206, a057e0b29e4ac9717452cc478c418c12
+0,        266,        266,        0,    61206, 9a3bab91b4f0fff174536b1609c9632c
+0,        300,        300,        0,    61206, d1cd93975f746b6cae490aae31f89e7e
diff --git a/tests/ref/fate/vp9-03-size-202x208 b/tests/ref/fate/vp9-03-size-202x208
new file mode 100644
index 0000000..a2a98f6
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-202x208
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    63024, d2128e290be81bb0700ebe19e3faed4f
+0,         33,         33,        0,    63024, dccaecb7e4ddb7e4224221a659af2a43
+0,         66,         66,        0,    63024, be8e0966aaf3a9fe9164f63695dc3b62
+0,        100,        100,        0,    63024, da944fadc3a239c2254678cadb4cf7fa
+0,        133,        133,        0,    63024, 3c270f3c02fcbd192b7f896f3f9ee6d9
+0,        166,        166,        0,    63024, 0b3ccda0a87c37e40104ae2f1060e8e9
+0,        200,        200,        0,    63024, 254253aba91758f302e7177e614596be
+0,        233,        233,        0,    63024, b1501a4e372a5249e74aab77e57a28f1
+0,        266,        266,        0,    63024, c4497fea1cefed5cf2b2908620153d26
+0,        300,        300,        0,    63024, 5ba20dfa2400b15b5394f315c5c3707d
diff --git a/tests/ref/fate/vp9-03-size-202x210 b/tests/ref/fate/vp9-03-size-202x210
new file mode 100644
index 0000000..b9fb7c2
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-202x210
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    63630, e4663a28cabbfdd3815efda2d38debcc
+0,         33,         33,        0,    63630, 3cc7dbec64e9f697f40d740a72c09fc7
+0,         66,         66,        0,    63630, f108981e0ce9c6c501b9ac61d0f1ba44
+0,        100,        100,        0,    63630, 63191c7aceb8ac6b030cc1a4b3cda18c
+0,        133,        133,        0,    63630, b0a527ae3aafe94d13573199c6f4944f
+0,        166,        166,        0,    63630, 1be14b213ebf1d653468b8c16bae03fb
+0,        200,        200,        0,    63630, 44e5a8333a043cd93b9d1cc78e5f188f
+0,        233,        233,        0,    63630, bfd7619f990f20e23b47d0738a6a8449
+0,        266,        266,        0,    63630, 800405f45ca5198014ef8d8521b044fa
+0,        300,        300,        0,    63630, dca4eda872349708f54486433efc8225
diff --git a/tests/ref/fate/vp9-03-size-202x224 b/tests/ref/fate/vp9-03-size-202x224
new file mode 100644
index 0000000..9a6b9da
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-202x224
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    67872, 1d318f05310f6d40646f23c62c7eafe4
+0,         33,         33,        0,    67872, 42870bd73e1a0c5d84b986db3d24f0f0
+0,         66,         66,        0,    67872, afaac676150286143c6fec7992a81467
+0,        100,        100,        0,    67872, 128f84400c272628e802c2369b6bf548
+0,        133,        133,        0,    67872, 9adc24d69f12349d8b17c84f5c111767
+0,        166,        166,        0,    67872, b33d2f7a1955248652701f2ade8ab55d
+0,        200,        200,        0,    67872, b8acc23721097fce6c8835f5fcfaa6ee
+0,        233,        233,        0,    67872, b63bf9a08e4dc5879bbd91efaec95960
+0,        266,        266,        0,    67872, 96e8fe29935266f6bd486b99f917eabc
+0,        300,        300,        0,    67872, 54be14f8dde6857867cd4581f8557044
diff --git a/tests/ref/fate/vp9-03-size-202x226 b/tests/ref/fate/vp9-03-size-202x226
new file mode 100644
index 0000000..38d2e60
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-202x226
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    68478, 5aa0f439c58c6335cd86d4238a8c4b68
+0,         33,         33,        0,    68478, 3616cc306ec05f89d9b0db63200e4abf
+0,         66,         66,        0,    68478, 424e98f8ec0ebf2a326a917ee0159bbe
+0,        100,        100,        0,    68478, ed5710e412f056fa8c1a277d86dd45d7
+0,        133,        133,        0,    68478, 760b850feab485f0bda6cde9943102bc
+0,        166,        166,        0,    68478, f4bd90ca72aa707f9b68e6192ac230fd
+0,        200,        200,        0,    68478, 58e4aad0bc2a9f3fc279df10208bd6f6
+0,        233,        233,        0,    68478, b42f84723dd167d5c544d539275ad537
+0,        266,        266,        0,    68478, 5f54feca21331646e68797380260932a
+0,        300,        300,        0,    68478, 8e787dd318024aff25af8b4d85040f3c
diff --git a/tests/ref/fate/vp9-03-size-208x196 b/tests/ref/fate/vp9-03-size-208x196
new file mode 100644
index 0000000..a541f14
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-208x196
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    61152, 6195975181969789e101a83a555d13f7
+0,         33,         33,        0,    61152, 2aca5e3307d68a5e969564a943b8e723
+0,         66,         66,        0,    61152, aee4b00472ee0b6b7a13e31069181db4
+0,        100,        100,        0,    61152, 7808595b650a7c14d8a4800db7c014e0
+0,        133,        133,        0,    61152, 746eb763b176286aa875ae06b81118c4
+0,        166,        166,        0,    61152, 0e8a78ec061319e27d49ca25e333e017
+0,        200,        200,        0,    61152, ac4432db2bb0971d5f70a7dda1210c19
+0,        233,        233,        0,    61152, 78870f4bd767f8ab65d369a5b322735d
+0,        266,        266,        0,    61152, eee9ddd91209348a64259db6a4a3f80c
+0,        300,        300,        0,    61152, c48d21e36a9c0d0d1c64db3f776b3002
diff --git a/tests/ref/fate/vp9-03-size-208x198 b/tests/ref/fate/vp9-03-size-208x198
new file mode 100644
index 0000000..2236687
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-208x198
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    61776, 1f1fa3cdf865d8c75183f4ba6203b675
+0,         33,         33,        0,    61776, ead33ead8fea5bd5d831a79f4c75a590
+0,         66,         66,        0,    61776, 9a406b4464989fd4bb7cbcb1b18aeaa7
+0,        100,        100,        0,    61776, fab3d228e7032f2cdc440dbfcb17c4c1
+0,        133,        133,        0,    61776, f2f3f8b8d9ece21c359c89245157c613
+0,        166,        166,        0,    61776, 321f5a8ecb2cec1780013fe72c237bde
+0,        200,        200,        0,    61776, 6f025b1f4ef61d261f05ca149a9470e6
+0,        233,        233,        0,    61776, 85abcc8d8e6b5f286ed6aa6c588cf416
+0,        266,        266,        0,    61776, b28d710dd44389f774aa02edd6327d5c
+0,        300,        300,        0,    61776, 79374bef9819eecafa7396d70c80be7f
diff --git a/tests/ref/fate/vp9-03-size-208x200 b/tests/ref/fate/vp9-03-size-208x200
new file mode 100644
index 0000000..5f924a3
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-208x200
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    62400, ff2dda3ddbe8b461d960baba0ad132bf
+0,         33,         33,        0,    62400, d6935ac8f2250316f498e8f01afa04fd
+0,         66,         66,        0,    62400, 57173ebaef7b21698c62fa959cb40ead
+0,        100,        100,        0,    62400, f354c76d7cf45e9f3adfdde0f6b3b5c9
+0,        133,        133,        0,    62400, fbc968ecd214b01509a76996e45dd09a
+0,        166,        166,        0,    62400, 9c314b51a80f2a081adf9b9cc26f5f8a
+0,        200,        200,        0,    62400, f22883a6a5b74ffa4bb16f22d496b5a5
+0,        233,        233,        0,    62400, eb4fa914fc5658d43e32c48a0c39bab3
+0,        266,        266,        0,    62400, d763c0c2f44b68e1e3fe9e165334eb0b
+0,        300,        300,        0,    62400, 344e1075a48cd61e79b0550809b4c91f
diff --git a/tests/ref/fate/vp9-03-size-208x202 b/tests/ref/fate/vp9-03-size-208x202
new file mode 100644
index 0000000..b5373d5
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-208x202
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    63024, e5164f87feadf4b65257f578affc3e04
+0,         33,         33,        0,    63024, 6aee5a3b6c3a096dfc1594762b2b248f
+0,         66,         66,        0,    63024, cb1c9dce6fdf7372e0eb2397251f0ade
+0,        100,        100,        0,    63024, 4fe5f24c08690c966b6a14ac3422510b
+0,        133,        133,        0,    63024, b22a273814523251b365f3278d8a3a9c
+0,        166,        166,        0,    63024, 190d9dff373023a25427fc859545ea24
+0,        200,        200,        0,    63024, a6307f38718ed686cb195e3833ab27ab
+0,        233,        233,        0,    63024, 79630bec5a91d69aca42a910413c2800
+0,        266,        266,        0,    63024, 2231cec9c03714b8671e5e1456b148c9
+0,        300,        300,        0,    63024, 278458f6734a24f2eb9bc877a6e9d7df
diff --git a/tests/ref/fate/vp9-03-size-208x208 b/tests/ref/fate/vp9-03-size-208x208
new file mode 100644
index 0000000..aa5bc3c
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-208x208
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    64896, 6bff7c1f4c5ef8412ebf669852c70de6
+0,         33,         33,        0,    64896, fdfd7a2308de9509a41fed2880a8f0f5
+0,         66,         66,        0,    64896, d8b464811e9c3b8a6db9cc277ac88c59
+0,        100,        100,        0,    64896, b8fa29e79be3126dd74310d6dd09c747
+0,        133,        133,        0,    64896, dad29803fed686887a0873eb78a469c6
+0,        166,        166,        0,    64896, 684de29bbf800f52aea4af9850bcc5b3
+0,        200,        200,        0,    64896, 06862dbce7571b4487766b179a596e1d
+0,        233,        233,        0,    64896, 99582a966bc7070112e214ce7912e485
+0,        266,        266,        0,    64896, a61158581a5719cb0cf13fb3301cb8c4
+0,        300,        300,        0,    64896, 9c2295332f34fee3a249262c8ba843bc
diff --git a/tests/ref/fate/vp9-03-size-208x210 b/tests/ref/fate/vp9-03-size-208x210
new file mode 100644
index 0000000..0477efa
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-208x210
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    65520, b15c7e98ddd137237b062cb51667522f
+0,         33,         33,        0,    65520, 00c594c68b19ef39a79a38e86853dc64
+0,         66,         66,        0,    65520, e6742abe3d2c178af4298e121391c299
+0,        100,        100,        0,    65520, efe5387b38c32f1c25c0fc9836921074
+0,        133,        133,        0,    65520, e0e696f4c18af09a74e052903db1468c
+0,        166,        166,        0,    65520, f1960270c6704ca47caed63161716025
+0,        200,        200,        0,    65520, a1542d7749cfa447481acd7835db838a
+0,        233,        233,        0,    65520, a91fb10a17d1d056667860cc43c81dae
+0,        266,        266,        0,    65520, b673bfbb722522b4e7b5e9c5b85cc31f
+0,        300,        300,        0,    65520, 8b4bb57d3cf609cbf9564a96a6ca6ade
diff --git a/tests/ref/fate/vp9-03-size-208x224 b/tests/ref/fate/vp9-03-size-208x224
new file mode 100644
index 0000000..18ed456
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-208x224
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    69888, 479d07bb96905ad7d5f0ec3ee12b41ba
+0,         33,         33,        0,    69888, 4b6555aaed8e5a45879773f1bf87962e
+0,         66,         66,        0,    69888, c5f42cb796dd7b6622957016ca6b502f
+0,        100,        100,        0,    69888, f06c954483560866fbff10bae7ba0785
+0,        133,        133,        0,    69888, af83aff39999852310395fe241ccb49b
+0,        166,        166,        0,    69888, 108377d6f30ceba6f2377330af2da38f
+0,        200,        200,        0,    69888, e81e6e0b37a7b92368ede9cab124567c
+0,        233,        233,        0,    69888, 59dbe51caaed8e6e825c78c5901fb22c
+0,        266,        266,        0,    69888, 24686123ea14c8d1a9b447733df0aaab
+0,        300,        300,        0,    69888, ce2035c49237c8076f8dac0d3f61848e
diff --git a/tests/ref/fate/vp9-03-size-208x226 b/tests/ref/fate/vp9-03-size-208x226
new file mode 100644
index 0000000..a7a1981
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-208x226
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    70512, 33aa4af6153570518c59960a0c959053
+0,         33,         33,        0,    70512, 024fa27dee80ad199528052aaa8d42c7
+0,         66,         66,        0,    70512, b949ef118c7e7e62a8b88e2308219ef9
+0,        100,        100,        0,    70512, 3061ee13696ced5e10a646fdd5ca6c34
+0,        133,        133,        0,    70512, c4984bd53dcb7b9e2570f2965d077b2f
+0,        166,        166,        0,    70512, d564c35c5caadcfd9f80377fa414af72
+0,        200,        200,        0,    70512, 9b7d7b10ee2f3eb7a9ffddcebff45b97
+0,        233,        233,        0,    70512, a0ede7085b04cbb3519d56b2e4347d14
+0,        266,        266,        0,    70512, 63d7af745f9e6a34b618db28fe878ffd
+0,        300,        300,        0,    70512, 85077809087e7bdfb9215bfcd1f1bbc0
diff --git a/tests/ref/fate/vp9-03-size-210x196 b/tests/ref/fate/vp9-03-size-210x196
new file mode 100644
index 0000000..0db3b00
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-210x196
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    61740, 5c69f80da667bfd20394995e93e4cd2b
+0,         33,         33,        0,    61740, 13363cd8e52ca8c1053db1c84c111bc9
+0,         66,         66,        0,    61740, 108976afdf99f59276d6f89879e3bdc3
+0,        100,        100,        0,    61740, 770ce25985e6b479d52a9185876cfe83
+0,        133,        133,        0,    61740, eba7cbb3c91989aa4c13487ed01675b5
+0,        166,        166,        0,    61740, f391c30a47c33a250dd20cb12f0a6e01
+0,        200,        200,        0,    61740, c38e12de302177d19dd744a3ea227e90
+0,        233,        233,        0,    61740, 8c9370439a0b7289919c6ee68e00570f
+0,        266,        266,        0,    61740, ac3748c4b99c4f1aba7430ae12c19cfd
+0,        300,        300,        0,    61740, e5228dc84f7933ccc9306907d737ad3c
diff --git a/tests/ref/fate/vp9-03-size-210x198 b/tests/ref/fate/vp9-03-size-210x198
new file mode 100644
index 0000000..3949dbd
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-210x198
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    62370, d83ee2413e701ae405a2b74863d4c5a9
+0,         33,         33,        0,    62370, f2ebc0f7dc171e0e5d2911c7ee2df5e1
+0,         66,         66,        0,    62370, e189ef4d8add227352a0d6ee62748ee7
+0,        100,        100,        0,    62370, 6dcb1dca1a0e2ba85034aba9f021427e
+0,        133,        133,        0,    62370, e98c633ba8912f6d65374055ec9af543
+0,        166,        166,        0,    62370, 82111cb7d5addce16d9bcba9e0a99503
+0,        200,        200,        0,    62370, bbbc73002f794ab0261fe384b2524226
+0,        233,        233,        0,    62370, 0bcdc427df47123959f7de9c44fe291e
+0,        266,        266,        0,    62370, 505776b3d82e38612393d60b6aa55c1d
+0,        300,        300,        0,    62370, feb93758242b847f3d53bb4c97b0ad9c
diff --git a/tests/ref/fate/vp9-03-size-210x200 b/tests/ref/fate/vp9-03-size-210x200
new file mode 100644
index 0000000..9c4245c
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-210x200
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    63000, 2465560246c1ee24d937cb9cbc1422f1
+0,         33,         33,        0,    63000, 8926b628dcdf2182516822c7d0d778ec
+0,         66,         66,        0,    63000, 9bd14d3ebc7fe81c4223116de1b9c2ec
+0,        100,        100,        0,    63000, 2d029d8461c20236066c0786950540fb
+0,        133,        133,        0,    63000, 39412b6e62de43bd40c58d4e2e38daf8
+0,        166,        166,        0,    63000, 3ea211c24f606b29582147bf872994dd
+0,        200,        200,        0,    63000, 261c37f88bf7f40549642578d9464aeb
+0,        233,        233,        0,    63000, 98551d44de1e23165e05975babb72446
+0,        266,        266,        0,    63000, 1d85ad052dd27e7e6bfea5d2babf5176
+0,        300,        300,        0,    63000, ad18b6a3698a3674c2488f927810eb0d
diff --git a/tests/ref/fate/vp9-03-size-210x202 b/tests/ref/fate/vp9-03-size-210x202
new file mode 100644
index 0000000..253bb1d
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-210x202
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    63630, 5d01848aee2b324f2e356627f9c39532
+0,         33,         33,        0,    63630, b671fe34bc0e5a682baff929d26ea627
+0,         66,         66,        0,    63630, e9a40f87ca5aaa5af9772e286feb9063
+0,        100,        100,        0,    63630, 4730f60d4c856e8ad877c0d8b1729ec4
+0,        133,        133,        0,    63630, 317fc01349e0984c23d15f97a3a0f442
+0,        166,        166,        0,    63630, aea89116ffe48340d1752d1ad5195529
+0,        200,        200,        0,    63630, 14694ba65b6308e5f5571486b62ca1cc
+0,        233,        233,        0,    63630, 53c6102d877c9a30eaa20ddc45207ea0
+0,        266,        266,        0,    63630, 7d1e898b1bead878224e8ff15d624bd9
+0,        300,        300,        0,    63630, 37b684bfae5dbd33e8dbb8332b94ce8a
diff --git a/tests/ref/fate/vp9-03-size-210x208 b/tests/ref/fate/vp9-03-size-210x208
new file mode 100644
index 0000000..39752a9
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-210x208
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    65520, 1156d318c00d299cf5bdc7e485966dab
+0,         33,         33,        0,    65520, a8094f8f1e7e04e54251bee8c4c800ce
+0,         66,         66,        0,    65520, e2a07d99ffe1cfe6b9fce36e93677fe1
+0,        100,        100,        0,    65520, 63d179b00816dbad75b778d2c23955c6
+0,        133,        133,        0,    65520, 407de5fb2dfdd52e6173905b09ff22f2
+0,        166,        166,        0,    65520, 36900199c56310e651723de4e3ad2f2c
+0,        200,        200,        0,    65520, 908db56e975b5db07af17fdc51b12be8
+0,        233,        233,        0,    65520, 400e32490b1262009a481cc331a00e44
+0,        266,        266,        0,    65520, dc43b786cba033cc92b9921d12f7b3d7
+0,        300,        300,        0,    65520, e8c94c5965c729f5d1ef3ba4509c97c8
diff --git a/tests/ref/fate/vp9-03-size-210x210 b/tests/ref/fate/vp9-03-size-210x210
new file mode 100644
index 0000000..efbc81c
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-210x210
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    66150, b65725c68978bdaaafdf735dfbafa9e3
+0,         33,         33,        0,    66150, 35be2f16bd5dedc9d3f7a016f0d71701
+0,         66,         66,        0,    66150, 8c2873a97b51510d7449869e24a348f5
+0,        100,        100,        0,    66150, 724a30e8ae539e797db8889dc08aec5e
+0,        133,        133,        0,    66150, e3ae1246a63ea22afd026bfb859fe165
+0,        166,        166,        0,    66150, 7e1fa363cf3f44c7a3019f29c14a6da4
+0,        200,        200,        0,    66150, c6f26619ab5687a2a698c8766b79f2eb
+0,        233,        233,        0,    66150, be5b8c50a772afe95d72bf3cc7c4fd2f
+0,        266,        266,        0,    66150, 9eab1417ac249ce31c79750143d52084
+0,        300,        300,        0,    66150, 9d2455048dbc3cdc2343a818c5a2bcb1
diff --git a/tests/ref/fate/vp9-03-size-210x224 b/tests/ref/fate/vp9-03-size-210x224
new file mode 100644
index 0000000..cfa3758
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-210x224
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    70560, bb903b926c4b34ae336e21d65ad8fd25
+0,         33,         33,        0,    70560, c4c0bc3b112487e994d22176817ace3c
+0,         66,         66,        0,    70560, 24e699f7a92ab1b0fe12e0b747470b5b
+0,        100,        100,        0,    70560, 200f403694d3acfda63f52e8373f1420
+0,        133,        133,        0,    70560, 6df417a8ec1810562301c89724b739d1
+0,        166,        166,        0,    70560, 55757b633d8fe669fc0f507dab4fa9f7
+0,        200,        200,        0,    70560, 45bc82bee02cb45422be3ac1019896d0
+0,        233,        233,        0,    70560, 4aaf5d07d2796910767d5084556c9cf9
+0,        266,        266,        0,    70560, f100fa26da47250b98d95a18915f521d
+0,        300,        300,        0,    70560, f5a8def53b4638b6ce7c8588d595d0ad
diff --git a/tests/ref/fate/vp9-03-size-210x226 b/tests/ref/fate/vp9-03-size-210x226
new file mode 100644
index 0000000..046f733
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-210x226
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    71190, 03707b2f5c392933f7336f380423a0a1
+0,         33,         33,        0,    71190, b388553c79573555a3b660f5e36d4e36
+0,         66,         66,        0,    71190, a1a7fd8ba7fb0fe7733cdf5440c7c1f3
+0,        100,        100,        0,    71190, 9daff7ef71dd54951f0b75a902065259
+0,        133,        133,        0,    71190, 60218a4b8bc0a5b0b40fa560a40fb4c0
+0,        166,        166,        0,    71190, 21229bfed833468fafc27ce93db1450c
+0,        200,        200,        0,    71190, 7aa290c6e503315d7aa3517258d5f63a
+0,        233,        233,        0,    71190, 63fd08ae2e859ff3d874ab2c2ce41a42
+0,        266,        266,        0,    71190, 725b371247fae28ef4b912368738df64
+0,        300,        300,        0,    71190, 7cf2d8d9e464307311b499ff0c3ea05e
diff --git a/tests/ref/fate/vp9-03-size-224x196 b/tests/ref/fate/vp9-03-size-224x196
new file mode 100644
index 0000000..b94c04d
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-224x196
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    65856, 3ffc096f1b42b4d319d4a9efbefc7625
+0,         33,         33,        0,    65856, 78b3655d5cad30fa6b2c2d8fd29463de
+0,         66,         66,        0,    65856, ab197553d9599b2a03aff62d1d694848
+0,        100,        100,        0,    65856, be368d1f3d3fcc710565b5433940f0df
+0,        133,        133,        0,    65856, 374c5db60ea9c110b871bb45be0efff1
+0,        166,        166,        0,    65856, ec50085400d626de5833bc0a94d9941f
+0,        200,        200,        0,    65856, d4ae69937e2a8d9bf2023d4215749635
+0,        233,        233,        0,    65856, 9b0b81eb6d62b8014e0639932fe35bc0
+0,        266,        266,        0,    65856, cd02d0cc268e6b6df0b2dbd3f3b137e6
+0,        300,        300,        0,    65856, 5322ba1085c114f93534e1761a0d8aa1
diff --git a/tests/ref/fate/vp9-03-size-224x198 b/tests/ref/fate/vp9-03-size-224x198
new file mode 100644
index 0000000..dfcc091
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-224x198
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    66528, cf35dffc80946e87bb9d3e18aab9d320
+0,         33,         33,        0,    66528, a76ac92f05e9b097f8ac5882e1ffe656
+0,         66,         66,        0,    66528, faa1e8a11c9df3e9c9a9dafbebea6d04
+0,        100,        100,        0,    66528, 905a28289c8ac793b335096ca7f84e1d
+0,        133,        133,        0,    66528, cb480fa6977baf98a74bddf213ecba82
+0,        166,        166,        0,    66528, 35224d3708e3ba1dafcc58b803d5ea77
+0,        200,        200,        0,    66528, d166d764e87854bca47ab7a2bc8b1f9b
+0,        233,        233,        0,    66528, 562f1e06ae36abba5f1fb53e3d6cd7e8
+0,        266,        266,        0,    66528, 1599cebef060f6464aeef15aacbde446
+0,        300,        300,        0,    66528, 3316ebca2864a9dc04db86069efb1dd1
diff --git a/tests/ref/fate/vp9-03-size-224x200 b/tests/ref/fate/vp9-03-size-224x200
new file mode 100644
index 0000000..f7cf72c
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-224x200
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    67200, 0819e6d715c9b4d94f05f63a7ca86199
+0,         33,         33,        0,    67200, 9b9a4b01ed4c8a93687e45245b3092a3
+0,         66,         66,        0,    67200, 3a076f5b8dba60552e84a391ee04d1c7
+0,        100,        100,        0,    67200, 7aafc561f5b96e9d286bd8deb5687774
+0,        133,        133,        0,    67200, daa43a89ab6b2761eedaa183e33a3465
+0,        166,        166,        0,    67200, c14874409872357b11b65f35a283e058
+0,        200,        200,        0,    67200, 37d2ef52a9c694b2596d58ed9ca0d90b
+0,        233,        233,        0,    67200, c97bc860c006896d80f52ccc0759f472
+0,        266,        266,        0,    67200, 5f8618114a723a017e39a1af695996f3
+0,        300,        300,        0,    67200, ee8234fc5ccd41d05eb87e1510f9795e
diff --git a/tests/ref/fate/vp9-03-size-224x202 b/tests/ref/fate/vp9-03-size-224x202
new file mode 100644
index 0000000..e957344
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-224x202
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    67872, e1e3b4af5910383ff6f66b6ab1a29544
+0,         33,         33,        0,    67872, 8668ef92b72f35728ebb456665d48b95
+0,         66,         66,        0,    67872, dffc7c28f86f07bf28451292990e9594
+0,        100,        100,        0,    67872, aebfb446fa6d48db36dbd9b5cd147f1e
+0,        133,        133,        0,    67872, e3c6cb8c5bb3a26928493bfc297ab827
+0,        166,        166,        0,    67872, 68dabae76c1d27ab0e1079d99cb6d413
+0,        200,        200,        0,    67872, d1f7745eef748688f3871d00a7e67ef8
+0,        233,        233,        0,    67872, 36738851cc2af83fd250dea4cd63941b
+0,        266,        266,        0,    67872, 16c0315c43427e7e6719806a89551703
+0,        300,        300,        0,    67872, c4d589c0ea4cdfc1dd6dff72084c61fd
diff --git a/tests/ref/fate/vp9-03-size-224x208 b/tests/ref/fate/vp9-03-size-224x208
new file mode 100644
index 0000000..b2efc65
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-224x208
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    69888, 85f08afadfd1204d4131b9ee9c8cc10b
+0,         33,         33,        0,    69888, f893de5432a082b3dffcf7499827f548
+0,         66,         66,        0,    69888, cb81e0d7b657bc5a4a9cf8ad75a76a77
+0,        100,        100,        0,    69888, 8a40842123965731c15fc23fb6366d1d
+0,        133,        133,        0,    69888, 09c6d92af14a3fcfb12705cd5da57f2a
+0,        166,        166,        0,    69888, 6bede4dc8770df534b599021b0425309
+0,        200,        200,        0,    69888, 334b0b0448e9e4e6a0cddcd2e3a0af3f
+0,        233,        233,        0,    69888, 09f491f0f3870ef96cff0384cd7183d1
+0,        266,        266,        0,    69888, c9e5f81186ac947a77b051c8f0e76eac
+0,        300,        300,        0,    69888, 917565c3327bff78b53a78ea739472ff
diff --git a/tests/ref/fate/vp9-03-size-224x210 b/tests/ref/fate/vp9-03-size-224x210
new file mode 100644
index 0000000..0996abd
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-224x210
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    70560, 427421e5fd2087c6ff7b87a27982332f
+0,         33,         33,        0,    70560, b68311fd44e189e4174ac357d5415068
+0,         66,         66,        0,    70560, 2c822ff45be7a1ea412d21ff82c7bc1d
+0,        100,        100,        0,    70560, 34659186d93516eae1dd4d9a391d1c3f
+0,        133,        133,        0,    70560, 1990dd822abc3a10f511589db5aa50f4
+0,        166,        166,        0,    70560, 4a4dc076172c79d9fde3e17b47109835
+0,        200,        200,        0,    70560, 51874c79850120537fa5c405721d0107
+0,        233,        233,        0,    70560, 15d7897a128de9be90be17f1679012c9
+0,        266,        266,        0,    70560, a8d9480accf8585e94161a5f7c371cef
+0,        300,        300,        0,    70560, 8a9d3f09561b895b423ae9428f620b9b
diff --git a/tests/ref/fate/vp9-03-size-224x224 b/tests/ref/fate/vp9-03-size-224x224
new file mode 100644
index 0000000..fba94fc
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-224x224
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    75264, bedd5d2725ffff06a50e23841bc2dfb8
+0,         33,         33,        0,    75264, 8c363f68b0b30f507563516aa99e23ac
+0,         66,         66,        0,    75264, 9cb7d51ca4439614dc3f5980507a4d32
+0,        100,        100,        0,    75264, b393a18de28ab6b8d1c6afd67a7794e0
+0,        133,        133,        0,    75264, 81f69ee1e3d89cb78cac192c352f7741
+0,        166,        166,        0,    75264, aabb51f029a9a02e71524cf3500931e9
+0,        200,        200,        0,    75264, 6581aec620c508d2b42ccceaa2c6044d
+0,        233,        233,        0,    75264, 993cde759158c30dcf0f0a9fdcdfb0d8
+0,        266,        266,        0,    75264, 85985ae8d35514d601800a06c8226625
+0,        300,        300,        0,    75264, 0eba1d7c193e473586e4a5c87d0e0d21
diff --git a/tests/ref/fate/vp9-03-size-224x226 b/tests/ref/fate/vp9-03-size-224x226
new file mode 100644
index 0000000..2bf1225
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-224x226
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    75936, dca556e648a576b3973fbe4b34d0328c
+0,         33,         33,        0,    75936, 34a49e4aba4aca5c76ab0f751341c32b
+0,         66,         66,        0,    75936, 4b7cc6d500b273efe7e30fc3a3946f74
+0,        100,        100,        0,    75936, 1960f0f1edf9196c96b0de742a3cd53c
+0,        133,        133,        0,    75936, 3cb7d90178636911c5d53a5f8e75599c
+0,        166,        166,        0,    75936, 84b56c60c2282f85102048cc2cf40b88
+0,        200,        200,        0,    75936, 3ca34d2978307ec0fca05130d81bcc26
+0,        233,        233,        0,    75936, c15560be737e02ea9d1deeca0af9bb77
+0,        266,        266,        0,    75936, 391439789a6aa7bb02d7e699795a9559
+0,        300,        300,        0,    75936, 9f681e91cbcbe9920f21236b8ff093c7
diff --git a/tests/ref/fate/vp9-03-size-226x196 b/tests/ref/fate/vp9-03-size-226x196
new file mode 100644
index 0000000..9cb72d3
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-226x196
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    66444, 4757a31842453f806de2f2256329547e
+0,         33,         33,        0,    66444, fe5fb955a4143091c5bfae7c4a4afe0f
+0,         66,         66,        0,    66444, 93766c5a03d71f99afb7705add7b63f0
+0,        100,        100,        0,    66444, 30c91162aa6fb0ed3e47325146bb6d8a
+0,        133,        133,        0,    66444, 501fe67785b970b1b62c2ae0b36b19ad
+0,        166,        166,        0,    66444, 836be5e778e3d20e75c4fcd71f765b3d
+0,        200,        200,        0,    66444, 21a9fd5e78212fe71719e173844bc6e6
+0,        233,        233,        0,    66444, 81b3919208e345d93dde62740b47dd93
+0,        266,        266,        0,    66444, df010555a929ba88a2f25c6267e3786e
+0,        300,        300,        0,    66444, d2cff8282e5e7a5bbd879c73df0670c3
diff --git a/tests/ref/fate/vp9-03-size-226x198 b/tests/ref/fate/vp9-03-size-226x198
new file mode 100644
index 0000000..f70b330
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-226x198
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    67122, b97087eb8c53cf56dc44576912654fb2
+0,         33,         33,        0,    67122, 219bb68a59dc166806a5b5689a943b66
+0,         66,         66,        0,    67122, 67b2ec19dd3b74d828b51912c25249d6
+0,        100,        100,        0,    67122, 73dd9625538e10a0f94d31ac9fe3db23
+0,        133,        133,        0,    67122, 51e68f201130da18beb0cb27adcf6fa9
+0,        166,        166,        0,    67122, 455d9753b3c0ac5ad7d9da022f69acd0
+0,        200,        200,        0,    67122, 60a8905a63db4cdd2560583fb6415030
+0,        233,        233,        0,    67122, 48c156f4b2c9f936487b43713a4573fd
+0,        266,        266,        0,    67122, a5c8f4190cb34b3ecd42ca8e09bf1646
+0,        300,        300,        0,    67122, 233a5d5187137e047993532fc2e725d3
diff --git a/tests/ref/fate/vp9-03-size-226x200 b/tests/ref/fate/vp9-03-size-226x200
new file mode 100644
index 0000000..62cea7f
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-226x200
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    67800, 0ae27db338f73f37eaed806b1c789593
+0,         33,         33,        0,    67800, 3f69273752f43699a3bc7b22a88cc3aa
+0,         66,         66,        0,    67800, ce0dfafb59910241d2b1a2275a2c2143
+0,        100,        100,        0,    67800, 8d20f404e25766c819ee728858bcbc76
+0,        133,        133,        0,    67800, 67bc5604c5b0f6c3484b605c1f93c83a
+0,        166,        166,        0,    67800, 1c82def3a06430d205cce0db7b5714de
+0,        200,        200,        0,    67800, 654d7a676e3b8b64541ed8cdefbd7286
+0,        233,        233,        0,    67800, 6c80c78c7b652c5b3b117a0960e89951
+0,        266,        266,        0,    67800, ae73e3c69ec6747c5234d58c5e1e36eb
+0,        300,        300,        0,    67800, e40d716efd8caf2d4004d299fb914328
diff --git a/tests/ref/fate/vp9-03-size-226x202 b/tests/ref/fate/vp9-03-size-226x202
new file mode 100644
index 0000000..d13634a
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-226x202
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    68478, 0cd2876640e71de3a6df7839bd6f0b51
+0,         33,         33,        0,    68478, f887db6839c0cddd1ea9ae6bfd2cc16d
+0,         66,         66,        0,    68478, ff2a890cf4c4973bf181ba8424c2eadc
+0,        100,        100,        0,    68478, f69f2e4f3036a21deb43a0bf4b95771f
+0,        133,        133,        0,    68478, 93f511739c19f1a3b356dda39d945c93
+0,        166,        166,        0,    68478, 7f79633c93765b504fef0324bd10fdba
+0,        200,        200,        0,    68478, d6c53d3937c9a40b227b4486452e0b33
+0,        233,        233,        0,    68478, 4e26625e8997ad6fe08ae68fbdfdbfd7
+0,        266,        266,        0,    68478, 3bf4c8ac0279351bf904cf57b0fc13c1
+0,        300,        300,        0,    68478, 12d64d856025185fa9e610dfa62b05af
diff --git a/tests/ref/fate/vp9-03-size-226x208 b/tests/ref/fate/vp9-03-size-226x208
new file mode 100644
index 0000000..9e88108
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-226x208
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    70512, 6006cac6628cf9e7cea58aec07471b06
+0,         33,         33,        0,    70512, f7e994921248b6933920c984880ec96c
+0,         66,         66,        0,    70512, c0aeeb9d2009538d8d5e837f45e1542d
+0,        100,        100,        0,    70512, 7dacf9d00e85bd52045eb47bae5225b3
+0,        133,        133,        0,    70512, 024fd008a099ae954e38a3f0a8ebb6c9
+0,        166,        166,        0,    70512, fb6c368a1b3578ab59aa30e0b5cc4853
+0,        200,        200,        0,    70512, 07815251f7020b627c365a7a7be694c7
+0,        233,        233,        0,    70512, db8b8f48f3693867d2bd8208cf4f929a
+0,        266,        266,        0,    70512, 88b42d943c0978d832333a8a3f7b6bbc
+0,        300,        300,        0,    70512, 7aa760190f9328ba4f6fa87d1d9e8d3e
diff --git a/tests/ref/fate/vp9-03-size-226x210 b/tests/ref/fate/vp9-03-size-226x210
new file mode 100644
index 0000000..0ff9dfc
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-226x210
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    71190, a6c1b7686202f5cc64335f92be595309
+0,         33,         33,        0,    71190, 3e573d4c693a39c5d6cd46b8873e99bb
+0,         66,         66,        0,    71190, d2388f6f641c8ddec98f11493f1a1390
+0,        100,        100,        0,    71190, 16473e33532ebc8de2f02077c406346b
+0,        133,        133,        0,    71190, 6c75d1c01276838fce40837e373f49db
+0,        166,        166,        0,    71190, b718e7445e2b08dde78fa7f30be01346
+0,        200,        200,        0,    71190, 2f556ed5afd60b1bbae76984ce073107
+0,        233,        233,        0,    71190, 4e5d59daed044c39a14c35f18cb4fb7a
+0,        266,        266,        0,    71190, c14901a9906ffcd0eb1efc068ce32941
+0,        300,        300,        0,    71190, 3d73b7f87bcd16c1ec565b5cc8d0fe93
diff --git a/tests/ref/fate/vp9-03-size-226x224 b/tests/ref/fate/vp9-03-size-226x224
new file mode 100644
index 0000000..37b39a8
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-226x224
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    75936, 80fb3a643384386beadc0991f171669d
+0,         33,         33,        0,    75936, 65a4a51163f49a75f8eeecd94cb2ba47
+0,         66,         66,        0,    75936, d5b2aac9889d2991b83fd4360ada0258
+0,        100,        100,        0,    75936, 7958ff5535358567ea7df351d78256a7
+0,        133,        133,        0,    75936, 7e7413b9a61967d0ade07b81944e9a15
+0,        166,        166,        0,    75936, 40a008016adbf9673adbbc4c0edb4454
+0,        200,        200,        0,    75936, fef7b5e2809ef79917ab394a067ef4be
+0,        233,        233,        0,    75936, 91ee2360faf46a25b95927c55eea603f
+0,        266,        266,        0,    75936, a47f14a80a529f79f97accbe23188046
+0,        300,        300,        0,    75936, 3613bcd41ff13006fbba3bd0087c44f4
diff --git a/tests/ref/fate/vp9-03-size-226x226 b/tests/ref/fate/vp9-03-size-226x226
new file mode 100644
index 0000000..01c05dc
--- /dev/null
+++ b/tests/ref/fate/vp9-03-size-226x226
@@ -0,0 +1,11 @@
+#tb 0: 1/1000
+0,          0,          0,        0,    76614, f2370fc802dafdf5082beffc1907a9c6
+0,         33,         33,        0,    76614, aad6de7b986234a1d621935b272501c9
+0,         66,         66,        0,    76614, 8a6d3784e22e3b4f735e78916fbc3821
+0,        100,        100,        0,    76614, 0c4afce19c43fdf3bb1b972810cc9126
+0,        133,        133,        0,    76614, 814a68dd76a3135221131988910f51ba
+0,        166,        166,        0,    76614, b2379c4b28dca10e67ac58631f9731c0
+0,        200,        200,        0,    76614, b16fd651884340a428cea3fe0ac18ba6
+0,        233,        233,        0,    76614, cb65cd4c421cfd6a19fb123ec27abbe6
+0,        266,        266,        0,    76614, 7f1d2686b9808de8ecc723b18136d57d
+0,        300,        300,        0,    76614, da7fd4bff4b6db0221c42492876c5c4d
diff --git a/tests/ref/fate/vp9-2pass-akiyo b/tests/ref/fate/vp9-2pass-akiyo
new file mode 100644
index 0000000..5061a76
--- /dev/null
+++ b/tests/ref/fate/vp9-2pass-akiyo
@@ -0,0 +1,51 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 043ce065a309514e1e8ebdcbb3c2458b
+0,         33,         33,        0,   152064, 8579c9cffd95b11db86158e518b2e34a
+0,         66,         66,        0,   152064, ebbba105e499604f5e69b8aa48fe86f4
+0,        100,        100,        0,   152064, b08526fab7e106021f9fb9b1e2d4b725
+0,        133,        133,        0,   152064, 92afa561d06f41ccc6d2e2bcc3ab2ee4
+0,        166,        166,        0,   152064, 50de8ec2db66c783289a3982dd1c4f97
+0,        200,        200,        0,   152064, c2ab55d114b8822adef06ccb093b5ac7
+0,        233,        233,        0,   152064, e3ee4edbe8a1f0b5486bbd8a52e7cbcb
+0,        266,        266,        0,   152064, fc33fd50566cd64e5b13911ee06c6e24
+0,        300,        300,        0,   152064, 05297e847f983a19fe2ba5e05932a110
+0,        333,        333,        0,   152064, d21db9adb27be89ab3b7f75d89175e24
+0,        367,        367,        0,   152064, 29bb87bdebd078f8dd953a70def6c4dc
+0,        400,        400,        0,   152064, c57f7bc772f6143a22edaf926f92de5f
+0,        433,        433,        0,   152064, 39f2fc755d4bc2cc5ec077035382be22
+0,        467,        467,        0,   152064, 000ec9c75374f6d74a5e61189e6fd782
+0,        500,        500,        0,   152064, 3027187c9bdb2a755d14513b7e597bb1
+0,        533,        533,        0,   152064, 2b3129659df2b3aa10b9398c50301e00
+0,        567,        567,        0,   152064, e23bcacf1cafca9a7959508b33e63907
+0,        600,        600,        0,   152064, fe0382dd155284998a0d7eb7effb5adf
+0,        633,        633,        0,   152064, e0a487860dd0df3d865971b483fab3e9
+0,        667,        667,        0,   152064, 7ca757c55b0ea4779cdfa3a535f8f234
+0,        700,        700,        0,   152064, 1a276d27f4ce0e2720e25dbed2e524ae
+0,        734,        734,        0,   152064, dd39bc322c8bdce196a9c2129bcb5d6e
+0,        767,        767,        0,   152064, 63e295427977d645462e0fb3277ccb53
+0,        800,        800,        0,   152064, e9a35655c71da22fb0c7865e0bbc91b8
+0,        834,        834,        0,   152064, 5903bcbccabb3366382b37bf08119dde
+0,        867,        867,        0,   152064, 3b6ce09353b07b193914a71ca2334d8c
+0,        900,        900,        0,   152064, cb3731eb5dbe338125c0a7d6b4bf2868
+0,        934,        934,        0,   152064, 0837c62b54912ed06f7f755894ad3f6b
+0,        967,        967,        0,   152064, 7f215dc14d8e280fc18ad3fb3122fa58
+0,       1001,       1001,        0,   152064, 6dafaf5adc45fead74f0153e3764b17d
+0,       1034,       1034,        0,   152064, e19c8274ee6377dbf005f6516a81c413
+0,       1067,       1067,        0,   152064, 358cbf29bd136d2f9dcb60ab82a2e9e5
+0,       1101,       1101,        0,   152064, 2276d4670ff35c3a76c27c3a5810eea3
+0,       1134,       1134,        0,   152064, 636dd3390d4011c377915d7d3acc9ee1
+0,       1167,       1167,        0,   152064, 5e7a1ed17d80168567d61987425f4e60
+0,       1201,       1201,        0,   152064, c10a4830c5f268888789fccd16c0cc0e
+0,       1234,       1234,        0,   152064, 298ef49418d730a031ff23311031c969
+0,       1267,       1267,        0,   152064, 4dd2249e13cda0f99fa46786d345c96a
+0,       1301,       1301,        0,   152064, 24232dbc6e35a069c60422c4c23dfa51
+0,       1334,       1334,        0,   152064, ae8751c5ac168d6aa4499fe69f018ae2
+0,       1368,       1368,        0,   152064, 6a3a7e60a569e7415f2c3a1453e4dc38
+0,       1401,       1401,        0,   152064, 5475af1c118d1b7cc0a357bc434241a8
+0,       1434,       1434,        0,   152064, c6b5ab39e630e66e8f09698fd1dfa160
+0,       1468,       1468,        0,   152064, f1c0310adf115456167e3fa790e43dde
+0,       1501,       1501,        0,   152064, 3028296307b47d10156fc9657693edc3
+0,       1534,       1534,        0,   152064, 0903dabcb8ac707b423b222ac5bb4898
+0,       1568,       1568,        0,   152064, 713cf71b994e2c85ed577062814c5732
+0,       1601,       1601,        0,   152064, 674f56b9cccf5c9d1f88f68c3996a671
+0,       1634,       1634,        0,   152064, f63732c2ff823960d8b62d866dfb5e6a
diff --git a/tests/ref/fate/vp9-segmentation-akiyo b/tests/ref/fate/vp9-segmentation-akiyo
new file mode 100644
index 0000000..63c0cae
--- /dev/null
+++ b/tests/ref/fate/vp9-segmentation-akiyo
@@ -0,0 +1,51 @@
+#tb 0: 1/1000
+0,          0,          0,        0,   152064, 20cf714300c5e28ffb77bf9c682129bc
+0,         33,         33,        0,   152064, 2f271e4de29f87d6b90511fbafdf9fbb
+0,         66,         66,        0,   152064, 2f271e4de29f87d6b90511fbafdf9fbb
+0,        100,        100,        0,   152064, a88532a043f5f2c6bce729a8e20ee5af
+0,        133,        133,        0,   152064, 8d7b5482ed8072a7c95d722783773436
+0,        166,        166,        0,   152064, 04872d8619b163b5e0c20123ccddf7dc
+0,        200,        200,        0,   152064, ed6d9677782aa6e87b6576541391557f
+0,        233,        233,        0,   152064, 689f71108e9bf024cd9ccf48800dcdc7
+0,        266,        266,        0,   152064, f7c555792884499bb62a8e739b201739
+0,        300,        300,        0,   152064, 7fed82c38ce428a178c56f6131eff5ec
+0,        333,        333,        0,   152064, fb638e587ade05baa027bb63edc7ec7c
+0,        367,        367,        0,   152064, 319295f5aa44661a80570e844050156a
+0,        400,        400,        0,   152064, de2d8635966a1cd57290eac449a5fb4b
+0,        433,        433,        0,   152064, 9ac3d711a00aac6b17004bb6451e4cab
+0,        467,        467,        0,   152064, d12eced084e72b5230493e2dc2de0f0a
+0,        500,        500,        0,   152064, 197761d11407fed723a63b8e28cb8e19
+0,        533,        533,        0,   152064, 28d8e807bc142b74f1eaf30dbbf1b7bd
+0,        567,        567,        0,   152064, abe88f1f7490d13ba3def9511beaceec
+0,        600,        600,        0,   152064, 7d297b9c989ebc0408fd41b14900242a
+0,        633,        633,        0,   152064, d5e7adfa2b207d860feff5c894585fd1
+0,        667,        667,        0,   152064, aea3e9de9de237f8379785f3467dc9c9
+0,        700,        700,        0,   152064, 211967cd949c1d83a8cc4c8267aa6034
+0,        734,        734,        0,   152064, 3f49bf8e0434114c15b867be2d53d283
+0,        767,        767,        0,   152064, 8d5e629c0e941ca6f049ed2bb59d09a8
+0,        800,        800,        0,   152064, d359620957877534bc94cd137dc652fe
+0,        834,        834,        0,   152064, 83610fc1969fdfa267e7e462a83ea40c
+0,        867,        867,        0,   152064, b2d20dcc3f77a238ce7210991eebe1a7
+0,        900,        900,        0,   152064, a42ad37808f30e1d968882bf42e9c641
+0,        934,        934,        0,   152064, 55084cded938266a2c3c658dcc162781
+0,        967,        967,        0,   152064, e392a3a7d33e10e95fc9cdf0a2080eac
+0,       1001,       1001,        0,   152064, 73977c4827463c17e63c0769bb90722f
+0,       1034,       1034,        0,   152064, cb5dd87344af7d6fd4ed0e06cb90d9c2
+0,       1067,       1067,        0,   152064, 533338860124e392cef2039468c22f75
+0,       1101,       1101,        0,   152064, da30f077490042367502a6fe11a46e0f
+0,       1134,       1134,        0,   152064, 860ab1bfbd3fe6a27bee5ef8c4e0b600
+0,       1167,       1167,        0,   152064, 339ec3863eaed689d46289ffe47bc45d
+0,       1201,       1201,        0,   152064, ffa6c990577093106796ed0dee56c483
+0,       1234,       1234,        0,   152064, 3fcdc2bc064c79f35ea81a715ff089d0
+0,       1267,       1267,        0,   152064, adaef9ec97e23a542db22bcd23c740bd
+0,       1301,       1301,        0,   152064, ddcff4bd2c9579181182eb49add0ce3c
+0,       1334,       1334,        0,   152064, b3b039c84cffb9272c8ddf9086748696
+0,       1368,       1368,        0,   152064, 70939a961ec1e4697031b79e7ebb7919
+0,       1401,       1401,        0,   152064, 6b3ff2e003749c6ffeb2d71edecf884c
+0,       1434,       1434,        0,   152064, 5e4efc96971f81218c472482b5a79374
+0,       1468,       1468,        0,   152064, 279132c87d81a5747824b06423bf6785
+0,       1501,       1501,        0,   152064, 1da48caa08007523aab41a56e21dd99b
+0,       1534,       1534,        0,   152064, 36ecffb2bfcb587d2556fddcbbd3448b
+0,       1568,       1568,        0,   152064, 7823e3c86cd5a05c2959c7ef4d1cfa89
+0,       1601,       1601,        0,   152064, b53f78afbad1a43f7aea58814eacd824
+0,       1634,       1634,        0,   152064, b9b127b4bc54123bec19b2f4a3fa157c
diff --git a/tests/ref/fate/vp9-tiling-pedestrian b/tests/ref/fate/vp9-tiling-pedestrian
new file mode 100644
index 0000000..23c760e
--- /dev/null
+++ b/tests/ref/fate/vp9-tiling-pedestrian
@@ -0,0 +1,3 @@
+#tb 0: 1/1000
+0,          0,          0,        0,  3110400, 1e6c2e768a5107e57e6d626f0511193a
+0,         40,         40,        0,  3110400, 972d3e2b5ee2e3b0907218a243e4cb7d
diff --git a/tests/ref/fate/wmv8-drm b/tests/ref/fate/wmv8-drm
index c2a6dd5..7f4b523 100644
--- a/tests/ref/fate/wmv8-drm
+++ b/tests/ref/fate/wmv8-drm
@@ -128,4 +128,3 @@
 0,       6666,       6666,        0,    84480, 0x13962590
 0,       6708,       6708,        0,    84480, 0xde79482f
 0,       6750,       6750,        0,    84480, 0x7d1ca064
-0,       6791,       6791,        0,    84480, 0x2676a064
diff --git a/tests/ref/fate/yop b/tests/ref/fate/yop
index 57f565d..1a56660 100644
--- a/tests/ref/fate/yop
+++ b/tests/ref/fate/yop
@@ -1,7 +1,7 @@
 #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,          2,          2,        1,   302760, 0x25eaa782
+0,          3,          3,        1,   302760, 0x60861c3d
+0,          4,          4,        1,   302760, 0x43552521
 0,          5,          5,        1,   302760, 0x45abca02
diff --git a/tests/ref/lavf/aiff b/tests/ref/lavf/aiff
index e5d6fc3..c713d02 100644
--- a/tests/ref/lavf/aiff
+++ b/tests/ref/lavf/aiff
@@ -1,3 +1,3 @@
-379908755146d4ead062abe9c3b5c582 *./tests/data/lavf/lavf.aif
-90166 ./tests/data/lavf/lavf.aif
-./tests/data/lavf/lavf.aif CRC=0xf1ae5536
+9d9e55431800bf6aea46a7d67509da4e *./tests/data/lavf/lavf.aif
+88254 ./tests/data/lavf/lavf.aif
+./tests/data/lavf/lavf.aif CRC=0x3a1da17e
diff --git a/tests/ref/lavf/alaw b/tests/ref/lavf/alaw
index 65bcf99..d93d6fc 100644
--- a/tests/ref/lavf/alaw
+++ b/tests/ref/lavf/alaw
@@ -1,3 +1,3 @@
-8bce9c3758b0d38da2e0718b6ab57fb4 *./tests/data/lavf/lavf.al
-45056 ./tests/data/lavf/lavf.al
-./tests/data/lavf/lavf.al CRC=0x5e6d372b
+652d96e474869ddb01403743deb35117 *./tests/data/lavf/lavf.al
+44100 ./tests/data/lavf/lavf.al
+./tests/data/lavf/lavf.al CRC=0xf9643112
diff --git a/tests/ref/lavf/asf b/tests/ref/lavf/asf
index 0137925..572cfc5 100644
--- a/tests/ref/lavf/asf
+++ b/tests/ref/lavf/asf
@@ -1,3 +1,3 @@
-528d3cbe33288ad983a8ff5b66738976 *./tests/data/lavf/lavf.asf
+327385dd5f418faa6237089a40159b78 *./tests/data/lavf/lavf.asf
 333375 ./tests/data/lavf/lavf.asf
-./tests/data/lavf/lavf.asf CRC=0xba1f5213
+./tests/data/lavf/lavf.asf CRC=0xf6340a10
diff --git a/tests/ref/lavf/au b/tests/ref/lavf/au
index 15f2a4b..71cfdcb 100644
--- a/tests/ref/lavf/au
+++ b/tests/ref/lavf/au
@@ -1,3 +1,3 @@
-dbd11f783219485cae32024e47c19dfb *./tests/data/lavf/lavf.au
-90136 ./tests/data/lavf/lavf.au
-./tests/data/lavf/lavf.au CRC=0xf1ae5536
+b9396e3775ea009094e751e7128d614e *./tests/data/lavf/lavf.au
+88224 ./tests/data/lavf/lavf.au
+./tests/data/lavf/lavf.au CRC=0x3a1da17e
diff --git a/tests/ref/lavf/avi b/tests/ref/lavf/avi
index 50646aa..08ae042 100644
--- a/tests/ref/lavf/avi
+++ b/tests/ref/lavf/avi
@@ -1,3 +1,3 @@
-e6319b86a4422a8317124fc4cc693f8c *./tests/data/lavf/lavf.avi
+e2e7b7ceaf038b259558f41df203ded9 *./tests/data/lavf/lavf.avi
 330786 ./tests/data/lavf/lavf.avi
-./tests/data/lavf/lavf.avi CRC=0xa79b84dd
+./tests/data/lavf/lavf.avi CRC=0x4c963cda
diff --git a/tests/ref/lavf/bmp b/tests/ref/lavf/bmp
index 8958855..b79ee4d 100644
--- a/tests/ref/lavf/bmp
+++ b/tests/ref/lavf/bmp
@@ -1,3 +1,3 @@
 71f4d64a6b3c71f43a4eff526f84841c *./tests/data/images/bmp/02.bmp
-./tests/data/images/bmp/%02d.bmp CRC=0xe6c71946
+./tests/data/images/bmp/%02d.bmp CRC=0x3447369b
 304182 ./tests/data/images/bmp/02.bmp
diff --git a/tests/ref/lavf/dpx b/tests/ref/lavf/dpx
index a852ae0..a9f1169 100644
--- a/tests/ref/lavf/dpx
+++ b/tests/ref/lavf/dpx
@@ -1,3 +1,3 @@
 808ea110635774252439722a48329d61 *./tests/data/images/dpx/02.dpx
-./tests/data/images/dpx/%02d.dpx CRC=0x6da01946
+./tests/data/images/dpx/%02d.dpx CRC=0x28c7369b
 305792 ./tests/data/images/dpx/02.dpx
diff --git a/tests/ref/lavf/ffm b/tests/ref/lavf/ffm
index 8921544..7518a81 100644
--- a/tests/ref/lavf/ffm
+++ b/tests/ref/lavf/ffm
@@ -1,3 +1,3 @@
-c5dcf5950031020864db57bbde0064df *./tests/data/lavf/lavf.ffm
+f3f0c42283b75bc826f499f048085c27 *./tests/data/lavf/lavf.ffm
 376832 ./tests/data/lavf/lavf.ffm
-./tests/data/lavf/lavf.ffm CRC=0x38388ba1
+./tests/data/lavf/lavf.ffm CRC=0xdd24439e
diff --git a/tests/ref/lavf/gxf b/tests/ref/lavf/gxf
index 0d28ac5..e25d4f2 100644
--- a/tests/ref/lavf/gxf
+++ b/tests/ref/lavf/gxf
@@ -1,3 +1,3 @@
-32e34e23f3740e27e5bcf1621a698aad *./tests/data/lavf/lavf.gxf
+eaa16531d0b2f3e3ade2186cf33dbf86 *./tests/data/lavf/lavf.gxf
 796392 ./tests/data/lavf/lavf.gxf
-./tests/data/lavf/lavf.gxf CRC=0x4f52fc7f
+./tests/data/lavf/lavf.gxf CRC=0xd04c769f
diff --git a/tests/ref/lavf/jpg b/tests/ref/lavf/jpg
index 9e5be55..584a97a 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=0x9d770966
 28406 ./tests/data/images/jpg/02.jpg
diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv
index 5ea3638..2bf1543 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
+7c21e1e6b4fe71f361564f8eebedf4e1 *./tests/data/lavf/lavf.mkv
+320268 ./tests/data/lavf/lavf.mkv
+./tests/data/lavf/lavf.mkv CRC=0x7d5d3cda
diff --git a/tests/ref/lavf/mmf b/tests/ref/lavf/mmf
index 756527c..947abc7 100644
--- a/tests/ref/lavf/mmf
+++ b/tests/ref/lavf/mmf
@@ -1,3 +1,3 @@
-272b91d8fc31ed43b08246d182719751 *./tests/data/lavf/lavf.mmf
-22609 ./tests/data/lavf/lavf.mmf
-./tests/data/lavf/lavf.mmf CRC=0x03633476
+1a3bbf19a41668c1e928bcafce88ff3e *./tests/data/lavf/lavf.mmf
+22617 ./tests/data/lavf/lavf.mmf
+./tests/data/lavf/lavf.mmf CRC=0x8dea1388
diff --git a/tests/ref/lavf/mov b/tests/ref/lavf/mov
index 2db01d4..f34a006 100644
--- a/tests/ref/lavf/mov
+++ b/tests/ref/lavf/mov
@@ -1,3 +1,3 @@
-a5c982910b1a1547db68ffa35cc2a05a *./tests/data/lavf/lavf.mov
-357741 ./tests/data/lavf/lavf.mov
-./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
+e46f42ed71a589ac356e9cfad4e1e56a *./tests/data/lavf/lavf.mov
+356797 ./tests/data/lavf/lavf.mov
+./tests/data/lavf/lavf.mov CRC=0xe3f4950d
diff --git a/tests/ref/lavf/mpg b/tests/ref/lavf/mpg
index e76f747..e4c8ae0 100644
--- a/tests/ref/lavf/mpg
+++ b/tests/ref/lavf/mpg
@@ -1,3 +1,3 @@
-af32acbc73ee486b05a37d53e516d5e7 *./tests/data/lavf/lavf.mpg
+7df31ba8a5909e3c88b1d1a3f93c4ec2 *./tests/data/lavf/lavf.mpg
 372736 ./tests/data/lavf/lavf.mpg
-./tests/data/lavf/lavf.mpg CRC=0x38388ba1
+./tests/data/lavf/lavf.mpg CRC=0xdd24439e
diff --git a/tests/ref/lavf/mulaw b/tests/ref/lavf/mulaw
index c6fa058..bd54084 100644
--- a/tests/ref/lavf/mulaw
+++ b/tests/ref/lavf/mulaw
@@ -1,3 +1,3 @@
-e64027a96ad5907ee281deff3286da0a *./tests/data/lavf/lavf.ul
-45056 ./tests/data/lavf/lavf.ul
-./tests/data/lavf/lavf.ul CRC=0xe028b50a
+ad492935e361f830f2f8302aa102701d *./tests/data/lavf/lavf.ul
+44100 ./tests/data/lavf/lavf.ul
+./tests/data/lavf/lavf.ul CRC=0x4515fa26
diff --git a/tests/ref/lavf/nut b/tests/ref/lavf/nut
index e658434..d7a8ab1 100644
--- a/tests/ref/lavf/nut
+++ b/tests/ref/lavf/nut
@@ -1,3 +1,3 @@
-7e44a8ed5ff2fe5442f758d48fe1b496 *./tests/data/lavf/lavf.nut
+8c9d5193a672ad0dee90f0712acc3a31 *./tests/data/lavf/lavf.nut
 319680 ./tests/data/lavf/lavf.nut
-./tests/data/lavf/lavf.nut CRC=0xa79b84dd
+./tests/data/lavf/lavf.nut CRC=0x4c963cda
diff --git a/tests/ref/lavf/ogg b/tests/ref/lavf/ogg
index 7bc66a3..ea827ac 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
-./tests/data/lavf/lavf.ogg CRC=0x37a143ea
+8ca901bc8d24b80ebe79e387e454d1e9 *./tests/data/lavf/lavf.ogg
+13476 ./tests/data/lavf/lavf.ogg
+./tests/data/lavf/lavf.ogg CRC=0x3a1da17e
diff --git a/tests/ref/lavf/pam b/tests/ref/lavf/pam
index e53132a..636a419 100644
--- a/tests/ref/lavf/pam
+++ b/tests/ref/lavf/pam
@@ -1,3 +1,3 @@
 0dce5565222cf0f8b309467f279aecd2 *./tests/data/images/pam/02.pam
-./tests/data/images/pam/%02d.pam CRC=0x6da01946
+./tests/data/images/pam/%02d.pam CRC=0x28c7369b
 304191 ./tests/data/images/pam/02.pam
diff --git a/tests/ref/lavf/pcx b/tests/ref/lavf/pcx
index bdb2204..e60ea78 100644
--- a/tests/ref/lavf/pcx
+++ b/tests/ref/lavf/pcx
@@ -1,3 +1,3 @@
 2df1d747fba23d03b6ff9c91b8b465c9 *./tests/data/images/pcx/02.pcx
-./tests/data/images/pcx/%02d.pcx CRC=0x6da01946
+./tests/data/images/pcx/%02d.pcx CRC=0x28c7369b
 364147 ./tests/data/images/pcx/02.pcx
diff --git a/tests/ref/lavf/pgm b/tests/ref/lavf/pgm
index 4043f7a..419fdaa 100644
--- a/tests/ref/lavf/pgm
+++ b/tests/ref/lavf/pgm
@@ -1,3 +1,3 @@
 388f5c51a678ca6a52cc006095c12f08 *./tests/data/images/pgm/02.pgm
-./tests/data/images/pgm/%02d.pgm CRC=0x418d2963
+./tests/data/images/pgm/%02d.pgm CRC=0xa6866b82
 101391 ./tests/data/images/pgm/02.pgm
diff --git a/tests/ref/lavf/png b/tests/ref/lavf/png
index 4343adb..f216e7e 100644
--- a/tests/ref/lavf/png
+++ b/tests/ref/lavf/png
@@ -1,3 +1,3 @@
 c162094e51dc1a3203de43e496086dfd *./tests/data/images/png/02.png
-./tests/data/images/png/%02d.png CRC=0x6da01946
+./tests/data/images/png/%02d.png CRC=0x28c7369b
 248612 ./tests/data/images/png/02.png
diff --git a/tests/ref/lavf/ppm b/tests/ref/lavf/ppm
index 97093aa..33275e2 100644
--- a/tests/ref/lavf/ppm
+++ b/tests/ref/lavf/ppm
@@ -1,3 +1,3 @@
 16d5dadf0b362fc8ba3cb676c5dde985 *./tests/data/images/ppm/02.ppm
-./tests/data/images/ppm/%02d.ppm CRC=0x6da01946
+./tests/data/images/ppm/%02d.ppm CRC=0x28c7369b
 304143 ./tests/data/images/ppm/02.ppm
diff --git a/tests/ref/lavf/rm b/tests/ref/lavf/rm
index 188d15d..993310d 100644
--- a/tests/ref/lavf/rm
+++ b/tests/ref/lavf/rm
@@ -1,2 +1,2 @@
-c002d460bc77043ced69fd00f4ae7968 *./tests/data/lavf/lavf.rm
+9eeb3b91c0a45f519fd7f2efea882cf4 *./tests/data/lavf/lavf.rm
 346414 ./tests/data/lavf/lavf.rm
diff --git a/tests/ref/lavf/rso b/tests/ref/lavf/rso
index 648c248..5878f43 100644
--- a/tests/ref/lavf/rso
+++ b/tests/ref/lavf/rso
@@ -1,3 +1,3 @@
-f41fd78f7df981802e7caeb23648b8c0 *./tests/data/lavf/lavf.rso
-45064 ./tests/data/lavf/lavf.rso
-./tests/data/lavf/lavf.rso CRC=0x74b2b546
+443b72346065d6318ca18c8395aa1d87 *./tests/data/lavf/lavf.rso
+44108 ./tests/data/lavf/lavf.rso
+./tests/data/lavf/lavf.rso CRC=0x298fd284
diff --git a/tests/ref/lavf/sgi b/tests/ref/lavf/sgi
index a43c1f4..b0cd303 100644
--- a/tests/ref/lavf/sgi
+++ b/tests/ref/lavf/sgi
@@ -1,3 +1,3 @@
 7054acafd275e51cec28d4518e213081 *./tests/data/images/sgi/02.sgi
-./tests/data/images/sgi/%02d.sgi CRC=0x6da01946
+./tests/data/images/sgi/%02d.sgi CRC=0x28c7369b
 308151 ./tests/data/images/sgi/02.sgi
diff --git a/tests/ref/lavf/sox b/tests/ref/lavf/sox
index 0026480..fc368b1 100644
--- a/tests/ref/lavf/sox
+++ b/tests/ref/lavf/sox
@@ -1,3 +1,3 @@
-e6f278256f145b69ed06f35b8d3585c1 *./tests/data/lavf/lavf.sox
-180256 ./tests/data/lavf/lavf.sox
-./tests/data/lavf/lavf.sox CRC=0xf1ae5536
+683635d5cb1344e44fa96df90c3a993c *./tests/data/lavf/lavf.sox
+176432 ./tests/data/lavf/lavf.sox
+./tests/data/lavf/lavf.sox CRC=0x3a1da17e
diff --git a/tests/ref/lavf/sunrast b/tests/ref/lavf/sunrast
index 4db0505..097235b 100644
--- a/tests/ref/lavf/sunrast
+++ b/tests/ref/lavf/sunrast
@@ -1,3 +1,3 @@
 07518bcb0841bc677ce6aea8464ea240 *./tests/data/images/sun/02.sun
-./tests/data/images/sun/%02d.sun CRC=0xe6c71946
+./tests/data/images/sun/%02d.sun CRC=0x3447369b
 304123 ./tests/data/images/sun/02.sun
diff --git a/tests/ref/lavf/tga b/tests/ref/lavf/tga
index 7efaf97..ce6b646 100644
--- a/tests/ref/lavf/tga
+++ b/tests/ref/lavf/tga
@@ -1,3 +1,3 @@
 c0305c53e6d79d4ed9f35f04f671246c *./tests/data/images/tga/02.tga
-./tests/data/images/tga/%02d.tga CRC=0xe6c71946
+./tests/data/images/tga/%02d.tga CRC=0x3447369b
 304172 ./tests/data/images/tga/02.tga
diff --git a/tests/ref/lavf/tiff b/tests/ref/lavf/tiff
index 4b0b985..b636bd9 100644
--- a/tests/ref/lavf/tiff
+++ b/tests/ref/lavf/tiff
@@ -1,3 +1,3 @@
 b3299346a8959553a437e486d8f3bf76 *./tests/data/images/tiff/02.tiff
-./tests/data/images/tiff/%02d.tiff CRC=0x6da01946
+./tests/data/images/tiff/%02d.tiff CRC=0x28c7369b
 307131 ./tests/data/images/tiff/02.tiff
diff --git a/tests/ref/lavf/ts b/tests/ref/lavf/ts
index 333149e..0fe358b 100644
--- a/tests/ref/lavf/ts
+++ b/tests/ref/lavf/ts
@@ -1,3 +1,3 @@
-ec8df9c78de8f7f20a3eb1ce8f863c02 *./tests/data/lavf/lavf.ts
+647875edb0d1afb9fd0477cbfde3fe8b *./tests/data/lavf/lavf.ts
 406456 ./tests/data/lavf/lavf.ts
-./tests/data/lavf/lavf.ts CRC=0x0fdeb4df
+./tests/data/lavf/lavf.ts CRC=0xb4ca6cdc
diff --git a/tests/ref/lavf/voc b/tests/ref/lavf/voc
index ea903b6..3131960 100644
--- a/tests/ref/lavf/voc
+++ b/tests/ref/lavf/voc
@@ -1,3 +1,3 @@
-5c4ee01048e7a8a138a97e80cf7a1924 *./tests/data/lavf/lavf.voc
-45261 ./tests/data/lavf/lavf.voc
-./tests/data/lavf/lavf.voc CRC=0x74b2b546
+ae01db5200e569371d4c27316575344c *./tests/data/lavf/lavf.voc
+44305 ./tests/data/lavf/lavf.voc
+./tests/data/lavf/lavf.voc CRC=0x298fd284
diff --git a/tests/ref/lavf/voc_s16 b/tests/ref/lavf/voc_s16
index d53c950..deb7999 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
-./tests/data/lavf/lavf.s16.voc CRC=0x7bd585ff
+e55a9c632cfeab90bcfb9ff29a71728c *./tests/data/lavf/lavf.s16.voc
+176613 ./tests/data/lavf/lavf.s16.voc
+./tests/data/lavf/lavf.s16.voc CRC=0xe61e3bd0
diff --git a/tests/ref/lavf/wav b/tests/ref/lavf/wav
index bbbacc3..fa8a859 100644
--- a/tests/ref/lavf/wav
+++ b/tests/ref/lavf/wav
@@ -1,3 +1,3 @@
-8854ea97f2d2172383941b001c69228b *./tests/data/lavf/lavf.wav
-90158 ./tests/data/lavf/lavf.wav
-./tests/data/lavf/lavf.wav CRC=0xf1ae5536
+41410d9bbe0603740d1c17050746f475 *./tests/data/lavf/lavf.wav
+88246 ./tests/data/lavf/lavf.wav
+./tests/data/lavf/lavf.wav CRC=0x3a1da17e
diff --git a/tests/ref/lavf/xwd b/tests/ref/lavf/xwd
index 41846c7..3fd20c8 100644
--- a/tests/ref/lavf/xwd
+++ b/tests/ref/lavf/xwd
@@ -1,3 +1,3 @@
 50baa5560b7d1aa3188b19c1162bf7dc *./tests/data/images/xwd/02.xwd
-./tests/data/images/xwd/%02d.xwd CRC=0x6da01946
+./tests/data/images/xwd/%02d.xwd CRC=0x28c7369b
 304239 ./tests/data/images/xwd/02.xwd
diff --git a/tests/ref/lavfi/pixdesc b/tests/ref/lavfi/pixdesc
deleted file mode 100644
index d1ccbbc..0000000
--- a/tests/ref/lavfi/pixdesc
+++ /dev/null
@@ -1,84 +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
-yuva420p10be        145366ff1632de3e300d947f49844284
-yuva420p10le        d797038552d7f698e4d1db4dfa18ceb0
-yuva420p16be        25a335f66a0670911ced818aa42fb670
-yuva420p16le        97bf252e6c030f0f0412d3826c2ea259
-yuva420p9be         06b764d85bd3c22e9b7ca4babed84d4f
-yuva420p9le         1f01cdd4fc46f98d4c11b2947307a0e3
-yuva422p            92b6815f465297284cdb843711682cee
-yuva422p10be        fb240ff9ac49b45b1b3d40df2c89e39d
-yuva422p10le        f767ede9ba1d427faadc963cf41d2412
-yuva422p16be        ef442b11b26e5e61f3c958fa309576dd
-yuva422p16le        5789009759d7a44dacc6da2194e402b1
-yuva422p9be         e0d2f45f7f5541eee988137c7ebb3495
-yuva422p9le         a4ec81f328efd3856dec430fb27f2f56
-yuva444p            c523716e4900cfe515eaab1d7124fdd9
-yuva444p10be        f5791a75fdb86da0c243511ef9ab8fbd
-yuva444p10le        578e88dfbe4ab07f280fcc7554f3a5c4
-yuva444p16be        ee7b9dd854e36b165d5b7cffb646ba6c
-yuva444p16le        ec93b2907923d5655e9fb085479260ef
-yuva444p9be         03414257d78e72c28d03e3c247319b7c
-yuva444p9le         e421d753257e36a79c2c0ec1607ac9e6
-yuvj420p            32eec78ba51857b16ce9b813a49b7189
-yuvj422p            0dfa0ed434f73be51428758c69e082cb
-yuvj440p            657501a28004e27a592757a7509f5189
-yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422             f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_copy b/tests/ref/lavfi/pixfmts_copy
deleted file mode 100644
index d1ccbbc..0000000
--- a/tests/ref/lavfi/pixfmts_copy
+++ /dev/null
@@ -1,84 +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
-yuva420p10be        145366ff1632de3e300d947f49844284
-yuva420p10le        d797038552d7f698e4d1db4dfa18ceb0
-yuva420p16be        25a335f66a0670911ced818aa42fb670
-yuva420p16le        97bf252e6c030f0f0412d3826c2ea259
-yuva420p9be         06b764d85bd3c22e9b7ca4babed84d4f
-yuva420p9le         1f01cdd4fc46f98d4c11b2947307a0e3
-yuva422p            92b6815f465297284cdb843711682cee
-yuva422p10be        fb240ff9ac49b45b1b3d40df2c89e39d
-yuva422p10le        f767ede9ba1d427faadc963cf41d2412
-yuva422p16be        ef442b11b26e5e61f3c958fa309576dd
-yuva422p16le        5789009759d7a44dacc6da2194e402b1
-yuva422p9be         e0d2f45f7f5541eee988137c7ebb3495
-yuva422p9le         a4ec81f328efd3856dec430fb27f2f56
-yuva444p            c523716e4900cfe515eaab1d7124fdd9
-yuva444p10be        f5791a75fdb86da0c243511ef9ab8fbd
-yuva444p10le        578e88dfbe4ab07f280fcc7554f3a5c4
-yuva444p16be        ee7b9dd854e36b165d5b7cffb646ba6c
-yuva444p16le        ec93b2907923d5655e9fb085479260ef
-yuva444p9be         03414257d78e72c28d03e3c247319b7c
-yuva444p9le         e421d753257e36a79c2c0ec1607ac9e6
-yuvj420p            32eec78ba51857b16ce9b813a49b7189
-yuvj422p            0dfa0ed434f73be51428758c69e082cb
-yuvj440p            657501a28004e27a592757a7509f5189
-yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422             f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_null b/tests/ref/lavfi/pixfmts_null
deleted file mode 100644
index d1ccbbc..0000000
--- a/tests/ref/lavfi/pixfmts_null
+++ /dev/null
@@ -1,84 +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
-yuva420p10be        145366ff1632de3e300d947f49844284
-yuva420p10le        d797038552d7f698e4d1db4dfa18ceb0
-yuva420p16be        25a335f66a0670911ced818aa42fb670
-yuva420p16le        97bf252e6c030f0f0412d3826c2ea259
-yuva420p9be         06b764d85bd3c22e9b7ca4babed84d4f
-yuva420p9le         1f01cdd4fc46f98d4c11b2947307a0e3
-yuva422p            92b6815f465297284cdb843711682cee
-yuva422p10be        fb240ff9ac49b45b1b3d40df2c89e39d
-yuva422p10le        f767ede9ba1d427faadc963cf41d2412
-yuva422p16be        ef442b11b26e5e61f3c958fa309576dd
-yuva422p16le        5789009759d7a44dacc6da2194e402b1
-yuva422p9be         e0d2f45f7f5541eee988137c7ebb3495
-yuva422p9le         a4ec81f328efd3856dec430fb27f2f56
-yuva444p            c523716e4900cfe515eaab1d7124fdd9
-yuva444p10be        f5791a75fdb86da0c243511ef9ab8fbd
-yuva444p10le        578e88dfbe4ab07f280fcc7554f3a5c4
-yuva444p16be        ee7b9dd854e36b165d5b7cffb646ba6c
-yuva444p16le        ec93b2907923d5655e9fb085479260ef
-yuva444p9be         03414257d78e72c28d03e3c247319b7c
-yuva444p9le         e421d753257e36a79c2c0ec1607ac9e6
-yuvj420p            32eec78ba51857b16ce9b813a49b7189
-yuvj422p            0dfa0ed434f73be51428758c69e082cb
-yuvj440p            657501a28004e27a592757a7509f5189
-yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422             f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_scale b/tests/ref/lavfi/pixfmts_scale
deleted file mode 100644
index e53580c..0000000
--- a/tests/ref/lavfi/pixfmts_scale
+++ /dev/null
@@ -1,84 +0,0 @@
-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
-yuva420p10be        d92a95061809f251175f5d5e3074930e
-yuva420p10le        bad90ba2d4c260e379a7aa6dc7760853
-yuva420p16be        a61d8ddb646e2d26020fc7ed2a48c1a9
-yuva420p16le        90ef774f86ad3177ec57eca8744b4e09
-yuva420p9be         f7655546446bfdc875243d7cdeb13b30
-yuva420p9le         ada2b719827059d70ebc57e2a3f9da92
-yuva422p            3c76ebeca0a7d3aa5f8e31ef80a86ffe
-yuva422p10be        01dd539e4a62762a3c97e965c76bb6f7
-yuva422p10le        76355d9d8fdcd085a24d48832b72e40b
-yuva422p16be        c21afa31ac18bd92e8e596b81552b52b
-yuva422p16le        0bc3720dba6076dcce3b74b1d3c6c4b7
-yuva422p9be         a60ac5b8026e9621724c033fbf79dbda
-yuva422p9le         c3eda8831e9b9c94a3eb487d33114103
-yuva444p            3268c6abe5e3cdbd16552a1eddced816
-yuva444p10be        856b37c1ee53459f46b9359d329ac9b5
-yuva444p10le        22790592361c007406d4ca9a9e0954a5
-yuva444p16be        ed5b07fe4d5b1137604568786777af1d
-yuva444p16le        3a3df23feb60d8832b566fd9765983d0
-yuva444p9be         4fc479c5b1044ad37b4e6fc6488b4f7f
-yuva444p9le         c41849b0134670d6f6253c337defbb04
-yuvj420p            30427bd6caf5bda93a173dbebe759e09
-yuvj422p            fc8288f64fd149573f73cf8da05d8e6d
-yuvj440p            508ac7a9ddeb6d1794a1100ba7a1664c
-yuvj444p            73aebe144085b22d1189caf6ca07e18c
-yuyv422             169e19ac91b257bd84ace0fdf56559ad
diff --git a/tests/ref/lavfi/pixfmts_vflip b/tests/ref/lavfi/pixfmts_vflip
deleted file mode 100644
index 9fd8bf6..0000000
--- a/tests/ref/lavfi/pixfmts_vflip
+++ /dev/null
@@ -1,84 +0,0 @@
-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
-yuva420p10be        baa5e3b0ff6d0ebbb0958560cd763c6e
-yuva420p10le        a36dc59ad55b406e5fee475236e9753c
-yuva420p16be        bf3b134eb70878df9afba61d03e930b8
-yuva420p16le        105d375154329a381aa58379a0a6ec46
-yuva420p9be         8273d591e055f48990c29dd905a6cdfd
-yuva420p9le         95ced0bb07e422d98db61a35cdb3fb8f
-yuva422p            6aed0ea657ed51cc047a4fbdd981aec8
-yuva422p10be        d69a3404984c5fd30c0fc548532bcb6b
-yuva422p10le        a40c8e6f50e12d94bf7484107ec98559
-yuva422p16be        39552c259ca242f2417e913ffc602fde
-yuva422p16le        16faa558a34291ca32f6d94dce211ee2
-yuva422p9be         a951eafb62c092c63f7566b6803f60df
-yuva422p9le         00b39cfca78666e057ee527f5e174a04
-yuva444p            da5d64f2b2bd2013c186456f595fad65
-yuva444p10be        00e74a9c0c7818a9bbd9fee95b961ee8
-yuva444p10le        cbe30f44b63cf7ed27fc2dde40315b5e
-yuva444p16be        7e9b799b057e1446dabbf0f738480cfb
-yuva444p16le        556d58b91a617fe4a83af99a4aea1c2e
-yuva444p9be         b5a31de4fac408eeecaf3aff11f40e55
-yuva444p9le         67467f1e1d9edbd59d3984ebbfe24be6
-yuvj420p            41fd02b204da0ab62452cd14b595e2e4
-yuvj422p            7f6ca9bc1812cde02036d7d29a7cce43
-yuvj440p            25711c3c0fd15ec19c59a10784fcfb96
-yuvj444p            e45dee2ac02276dfab92e8ebfbe52e00
-yuyv422             e944ff7316cd03c42c091717ce74f602
diff --git a/tests/ref/seek/lavf-alaw b/tests/ref/seek/lavf-alaw
index 84661ec..4b1f8fb 100644
--- a/tests/ref/seek/lavf-alaw
+++ b/tests/ref/seek/lavf-alaw
@@ -38,7 +38,7 @@ ret: 0         st: 0 flags:1 dts: 0.200816 pts: 0.200816 pos:   4428 size:  1024
 ret: 0         st: 0 flags:0  ts:-0.904989
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:  1024
 ret: 0         st: 0 flags:1  ts: 1.989161
-ret: 0         st: 0 flags:1 dts: 1.989161 pts: 1.989161 pos:  43861 size:  1024
+ret: 0         st: 0 flags:1 dts: 1.989161 pts: 1.989161 pos:  43861 size:   239
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.883356 pts: 0.883356 pos:  19478 size:  1024
 ret: 0         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/lavf-asf b/tests/ref/seek/lavf-asf
index e1d6d32..89ec4c2 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:    575 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.470000 pts: 0.470000 pos: 147775 size:   209
 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.941000 pts: 0.941000 pos: 301375 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.941000 pts: 0.941000 pos: 301375 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:    575 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: 330175 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: 330175 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: 147775 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:    575 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: 301375 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: 301375 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:    575 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: 330175 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: 301375 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.470000 pts: 0.470000 pos: 147775 size:   209
 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:    575 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: 301375 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: 330175 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.183000 pts: 0.183000 pos:  70975 size:   209
 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:    575 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: 301375 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.941000 pts: 0.941000 pos: 301375 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:    575 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: 330175 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: 330175 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: 147775 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:    575 size:   208
diff --git a/tests/ref/seek/lavf-mkv b/tests/ref/seek/lavf-mkv
index e51e9c9..f575165 100644
--- a/tests/ref/seek/lavf-mkv
+++ b/tests/ref/seek/lavf-mkv
@@ -1,53 +1,53 @@
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    512 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    518 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: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    734 size: 27837
 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.971000 pts: 0.971000 pos: 292156 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.971000 pts: 0.971000 pos: 292156 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: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    734 size: 27837
 ret: 0         st: 1 flags:0  ts: 2.577000
 ret:-EOF
 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.993000 pts: 0.993000 pos: 319997 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.491000 pts: 0.491000 pos: 146709 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:1 dts: 0.011000 pts: 0.011000 pos:    734 size: 27837
 ret: 0         st: 0 flags:0  ts: 2.153000
 ret:-EOF
 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.971000 pts: 0.971000 pos: 292156 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.000000 pts: 0.000000 pos:    518 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:1 dts: 0.993000 pts: 0.993000 pos: 319997 size:   209
 ret: 0         st:-1 flags:0  ts: 1.730004
 ret:-EOF
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146703 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 146709 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: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    734 size: 27837
 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: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292156 size: 27834
 ret: 0         st: 1 flags:0  ts: 1.307000
 ret:-EOF
 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.000000 pts: 0.000000 pos:    518 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: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    734 size: 27837
 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.971000 pts: 0.971000 pos: 292156 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.971000 pts: 0.971000 pos: 292156 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: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    734 size: 27837
 ret: 0         st: 1 flags:0  ts: 2.672000
 ret:-EOF
 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.993000 pts: 0.993000 pos: 319997 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.491000 pts: 0.491000 pos: 146709 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: 0 flags:1 dts: 0.011000 pts: 0.011000 pos:    734 size: 27837
diff --git a/tests/ref/seek/lavf-mpg b/tests/ref/seek/lavf-mpg
index 0f0d720..6e27064 100644
--- a/tests/ref/seek/lavf-mpg
+++ b/tests/ref/seek/lavf-mpg
@@ -1,53 +1,53 @@
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 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: 315392 size: 12800
 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: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st: 0 flags:1  ts:-0.317500
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st: 1 flags:0  ts: 2.576667
-ret: 0         st: 1 flags:1 dts: 1.772767 pts: 1.772767 pos: 368652 size:   379
+ret: 0         st: 1 flags:1 dts: 1.812767 pts: 1.812767 pos: 368652 size:   379
 ret: 0         st: 1 flags:1  ts: 1.470833
-ret: 0         st: 1 flags:1 dts: 1.250322 pts: 1.250322 pos: 145408 size:   261
+ret: 0         st: 1 flags:1 dts: 1.290322 pts: 1.290322 pos: 145408 size:   261
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 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: 0 flags:1 dts: 1.960000 pts: 2.000000 pos: 339968 size:   681
 ret: 0         st: 0 flags:1  ts: 1.047500
-ret: 0         st: 0 flags:0 dts: 1.040000 pts: 1.080000 pos:  40960 size: 16073
+ret: 0         st: 0 flags:0 dts: 1.040000 pts: 1.080000 pos:  26624 size: 16303
 ret: 0         st: 1 flags:0  ts:-0.058333
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st: 1 flags:1  ts: 2.835833
-ret: 0         st: 1 flags:1 dts: 1.772767 pts: 1.772767 pos: 368652 size:   379
+ret: 0         st: 1 flags:1 dts: 1.812767 pts: 1.812767 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: 280588 size: 13050
 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: 1 flags:1 dts: 1.029089 pts: 1.029089 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: 1 flags:1 dts: 1.029089 pts: 1.029089 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: 0 flags:1 dts: 1.960000 pts: 2.000000 pos: 339968 size:   681
 ret: 0         st: 1 flags:0  ts: 1.306667
-ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 pos: 342028 size:   314
+ret: 0         st: 1 flags:1 dts: 1.551544 pts: 1.551544 pos: 342028 size:   314
 ret: 0         st: 1 flags:1  ts: 0.200844
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 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: 0 flags:1 dts: 1.960000 pts: 2.000000 pos: 339968 size:   681
 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: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st: 0 flags:1  ts:-0.222489
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st: 1 flags:0  ts: 2.671678
-ret: 0         st: 1 flags:1 dts: 1.772767 pts: 1.772767 pos: 368652 size:   379
+ret: 0         st: 1 flags:1 dts: 1.812767 pts: 1.812767 pos: 368652 size:   379
 ret: 0         st: 1 flags:1  ts: 1.565844
-ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 pos: 342028 size:   314
+ret: 0         st: 1 flags:1 dts: 1.551544 pts: 1.551544 pos: 342028 size:   314
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
+ret: 0         st: 1 flags:1 dts: 1.029089 pts: 1.029089 pos:   2048 size:   208
diff --git a/tests/ref/seek/lavf-mulaw b/tests/ref/seek/lavf-mulaw
index 84661ec..4b1f8fb 100644
--- a/tests/ref/seek/lavf-mulaw
+++ b/tests/ref/seek/lavf-mulaw
@@ -38,7 +38,7 @@ ret: 0         st: 0 flags:1 dts: 0.200816 pts: 0.200816 pos:   4428 size:  1024
 ret: 0         st: 0 flags:0  ts:-0.904989
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:  1024
 ret: 0         st: 0 flags:1  ts: 1.989161
-ret: 0         st: 0 flags:1 dts: 1.989161 pts: 1.989161 pos:  43861 size:  1024
+ret: 0         st: 0 flags:1 dts: 1.989161 pts: 1.989161 pos:  43861 size:   239
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.883356 pts: 0.883356 pos:  19478 size:  1024
 ret: 0         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/lavf-ogg b/tests/ref/seek/lavf-ogg
index ea8eb8b..109ae32 100644
--- a/tests/ref/seek/lavf-ogg
+++ b/tests/ref/seek/lavf-ogg
@@ -1,27 +1,44 @@
 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:-1         st:-1 flags:1  ts: 1.894167
-ret:-1         st: 0 flags:0  ts: 0.788345
+ret: 0         st:-1 flags:0  ts:-1.000000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    124 size:  1364
+ret: 0         st:-1 flags:1  ts: 1.894167
+ret:-EOF
+ret: 0         st: 0 flags:0  ts: 0.788345
+ret:-EOF
 ret:-1         st: 0 flags:1  ts:-0.317506
 ret:-1         st:-1 flags:0  ts: 2.576668
-ret:-1         st:-1 flags:1  ts: 1.470835
-ret:-1         st: 0 flags:0  ts: 0.365011
+ret: 0         st:-1 flags:1  ts: 1.470835
+ret:-EOF
+ret: 0         st: 0 flags:0  ts: 0.365011
+ret:-EOF
 ret:-1         st: 0 flags:1  ts:-0.740839
 ret:-1         st:-1 flags:0  ts: 2.153336
-ret:-1         st:-1 flags:1  ts: 1.047503
-ret:-1         st: 0 flags:0  ts:-0.058322
-ret:-1         st: 0 flags:1  ts: 2.835828
+ret: 0         st:-1 flags:1  ts: 1.047503
+ret:-EOF
+ret: 0         st: 0 flags:0  ts:-0.058322
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    124 size:  1364
+ret: 0         st: 0 flags:1  ts: 2.835828
+ret:-EOF
 ret:-1         st:-1 flags:0  ts: 1.730004
-ret:-1         st:-1 flags:1  ts: 0.624171
-ret:-1         st: 0 flags:0  ts:-0.481655
-ret:-1         st: 0 flags:1  ts: 2.412494
+ret: 0         st:-1 flags:1  ts: 0.624171
+ret:-EOF
+ret: 0         st: 0 flags:0  ts:-0.481655
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    124 size:  1364
+ret: 0         st: 0 flags:1  ts: 2.412494
+ret:-EOF
 ret:-1         st:-1 flags:0  ts: 1.306672
-ret:-1         st:-1 flags:1  ts: 0.200839
-ret:-1         st: 0 flags:0  ts:-0.904989
-ret:-1         st: 0 flags:1  ts: 1.989184
-ret:-1         st:-1 flags:0  ts: 0.883340
+ret: 0         st:-1 flags:1  ts: 0.200839
+ret:-EOF
+ret: 0         st: 0 flags:0  ts:-0.904989
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    124 size:  1364
+ret: 0         st: 0 flags:1  ts: 1.989184
+ret:-EOF
+ret: 0         st:-1 flags:0  ts: 0.883340
+ret:-EOF
 ret:-1         st:-1 flags:1  ts:-0.222493
 ret:-1         st: 0 flags:0  ts: 2.671678
-ret:-1         st: 0 flags:1  ts: 1.565850
-ret:-1         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 0 flags:1  ts: 1.565850
+ret:-EOF
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret:-EOF
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf-ts b/tests/ref/seek/lavf-ts
index 81093b7..df7c4af 100644
--- a/tests/ref/seek/lavf-ts
+++ b/tests/ref/seek/lavf-ts
@@ -1,53 +1,53 @@
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:0 dts: 1.440000 pts: 1.480000 pos:  44932 size: 14502
+ret: 0         st: 0 flags:0 dts: 1.480000 pts: 1.520000 pos:  44932 size: 14502
 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: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 403636 size:   209
 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:0 dts: 1.560000 pts: 1.600000 pos:  74260 size: 13388
 ret: 0         st: 0 flags:1  ts:-0.317500
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 1 flags:0  ts: 2.576667
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 403636 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: 0 flags:0 dts: 2.120000 pts: 2.160000 pos: 294032 size: 13839
 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:0 dts: 1.480000 pts: 1.520000 pos:  44932 size: 14502
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 0 flags:0  ts: 2.153333
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 403636 size:   209
 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:0 dts: 1.720000 pts: 1.760000 pos: 130096 size: 14133
 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: 0 flags:0 dts: 1.480000 pts: 1.520000 pos:  44932 size: 14502
 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.160522 pts: 2.160522 pos: 403636 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: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 403636 size:   209
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 0 flags:0  ts:-0.481667
-ret: 0         st: 0 flags:0 dts: 1.440000 pts: 1.480000 pos:  44932 size: 14502
+ret: 0         st: 0 flags:0 dts: 1.480000 pts: 1.520000 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:1 dts: 2.160522 pts: 2.160522 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: 0 flags:0 dts: 2.040000 pts: 2.080000 pos: 265644 size: 12390
 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 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 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:0 dts: 1.480000 pts: 1.520000 pos:  44932 size: 14502
 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: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 403636 size:   209
 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:0 dts: 1.640000 pts: 1.680000 pos: 102836 size: 12781
 ret: 0         st: 0 flags:1  ts:-0.222489
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
 ret: 0         st: 1 flags:0  ts: 2.671678
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 1 flags:1 dts: 2.160522 pts: 2.160522 pos: 403636 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: 0 flags:0 dts: 2.200000 pts: 2.240000 pos: 325240 size: 12679
 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:0 dts: 1.480000 pts: 1.520000 pos:  44932 size: 14502
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1 dts: 1.400000 pts: 1.440000 pos:    564 size: 24801
diff --git a/tests/ref/seek/vsynth2-ffv1 b/tests/ref/seek/vsynth2-ffv1
index a1272f8..715a272 100644
--- a/tests/ref/seek/vsynth2-ffv1
+++ b/tests/ref/seek/vsynth2-ffv1
@@ -1,46 +1,46 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 70200
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5688 size: 71679
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 70200
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5688 size: 71679
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:2485798 size: 74128
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:2498334 size: 75937
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:1622704 size: 71128
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:1630830 size: 72682
 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:2485798 size: 74128
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:2498334 size: 75937
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 796828 size: 67971
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 801262 size: 69457
 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:1622704 size: 71128
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:1630830 size: 72682
 ret: 0         st: 0 flags:0  ts:-0.040000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 70200
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5688 size: 71679
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:3374428 size: 75606
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:3392418 size: 77461
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:3374428 size: 75606
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:3392418 size: 77461
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 796828 size: 67971
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 801262 size: 69457
 ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 70200
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5688 size: 71679
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:3374428 size: 75606
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:3392418 size: 77461
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:2485798 size: 74128
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:2498334 size: 75937
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 70200
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5688 size: 71679
 ret: 0         st: 0 flags:0  ts:-0.920000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 70200
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5688 size: 71679
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:3374428 size: 75606
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:3392418 size: 77461
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:1622704 size: 71128
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:1630830 size: 72682
 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:2485798 size: 74128
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:2498334 size: 75937
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 796828 size: 67971
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 801262 size: 69457
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/vsynth2-snow b/tests/ref/seek/vsynth2-snow
deleted file mode 100644
index d8f5aae..0000000
--- a/tests/ref/seek/vsynth2-snow
+++ /dev/null
@@ -1,46 +0,0 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size:  3035
-ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size:  3035
-ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  39714 size:  3640
-ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  27434 size:  3494
-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:  39714 size:  3640
-ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  16124 size:  3244
-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:  27434 size:  3494
-ret: 0         st: 0 flags:0  ts:-0.040000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size:  3035
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:  52604 size:  3582
-ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:  52604 size:  3582
-ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  16124 size:  3244
-ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size:  3035
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:  52604 size:  3582
-ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  39714 size:  3640
-ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size:  3035
-ret: 0         st: 0 flags:0  ts:-0.920000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size:  3035
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:  52604 size:  3582
-ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  27434 size:  3494
-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:  39714 size:  3640
-ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  16124 size:  3244
-ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/vsynth2-snow-ll b/tests/ref/seek/vsynth2-snow-ll
deleted file mode 100644
index 95a4a79..0000000
--- a/tests/ref/seek/vsynth2-snow-ll
+++ /dev/null
@@ -1,46 +0,0 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 72476
-ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 72476
-ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:1902788 size: 78837
-ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:1239090 size: 74994
-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:1902788 size: 78837
-ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 605628 size: 71059
-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:1239090 size: 74994
-ret: 0         st: 0 flags:0  ts:-0.040000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 72476
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:2585614 size: 79731
-ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:2585614 size: 79731
-ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 605628 size: 71059
-ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 72476
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:2585614 size: 79731
-ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:1902788 size: 78837
-ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 72476
-ret: 0         st: 0 flags:0  ts:-0.920000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5648 size: 72476
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos:2585614 size: 79731
-ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:1239090 size: 74994
-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:1902788 size: 78837
-ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 605628 size: 71059
-ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/vsynth2-wmv2 b/tests/ref/seek/vsynth2-wmv2
index 8ed257e..53680d0 100644
--- a/tests/ref/seek/vsynth2-wmv2
+++ b/tests/ref/seek/vsynth2-wmv2
@@ -2,45 +2,45 @@ ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83790 size: 11170
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83764 size: 11170
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54572 size:  9989
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54534 size:  9989
 ret:-1         st: 0 flags:1  ts:-0.320000
 ret:-1         st:-1 flags:0  ts: 2.576668
 ret: 0         st:-1 flags:1  ts: 1.470835
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83790 size: 11170
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83764 size: 11170
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29632 size:  8839
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29588 size:  8839
 ret:-1         st: 0 flags:1  ts:-0.760000
 ret:-1         st:-1 flags:0  ts: 2.153336
 ret: 0         st:-1 flags:1  ts: 1.047503
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54572 size:  9989
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54534 size:  9989
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116058 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116062 size: 11554
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116058 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116062 size: 11554
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29632 size:  8839
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29588 size:  8839
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116058 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116062 size: 11554
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83790 size: 11170
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83764 size: 11170
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5652 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116058 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116062 size: 11554
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54572 size:  9989
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54534 size:  9989
 ret:-1         st:-1 flags:1  ts:-0.222493
 ret:-1         st: 0 flags:0  ts: 2.680000
 ret: 0         st: 0 flags:1  ts: 1.560000
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83790 size: 11170
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83764 size: 11170
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29632 size:  8839
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29588 size:  8839
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/vsynth/vsynth1-dnxhd-1080i b/tests/ref/vsynth/vsynth1-dnxhd-1080i
index 3a990c5..8d396e8 100644
--- a/tests/ref/vsynth/vsynth1-dnxhd-1080i
+++ b/tests/ref/vsynth/vsynth1-dnxhd-1080i
@@ -1,4 +1,4 @@
-2412f206f5efcbbcc3f2bba0c86b73d4 *tests/data/fate/vsynth1-dnxhd-1080i.mov
+9e55c9ec332cc6ee002da67de34ca6d1 *tests/data/fate/vsynth1-dnxhd-1080i.mov
 3031875 tests/data/fate/vsynth1-dnxhd-1080i.mov
 34076f61254997c8157eafed1c916472 *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo
 stddev:    6.29 PSNR: 32.15 MAXDIFF:   64 bytes:  7603200/   760320
diff --git a/tests/ref/vsynth/vsynth1-ffv1 b/tests/ref/vsynth/vsynth1-ffv1
index 99787ed..a162a77 100644
--- a/tests/ref/vsynth/vsynth1-ffv1
+++ b/tests/ref/vsynth/vsynth1-ffv1
@@ -1,4 +1,4 @@
-91c237f18bc19975077c85175daed734 *tests/data/fate/vsynth1-ffv1.avi
-2655364 tests/data/fate/vsynth1-ffv1.avi
+d236e8441d7e04e24d882bb97faccd36 *tests/data/fate/vsynth1-ffv1.avi
+2689718 tests/data/fate/vsynth1-ffv1.avi
 c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-ffv1.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-ljpeg b/tests/ref/vsynth/vsynth1-ljpeg
index e229db5..702de39 100644
--- a/tests/ref/vsynth/vsynth1-ljpeg
+++ b/tests/ref/vsynth/vsynth1-ljpeg
@@ -1,4 +1,4 @@
-2b1a2d5ad7f357df955d8548320d13f7 *tests/data/fate/vsynth1-ljpeg.avi
+aed2be6710c0dddacfa410dff7ce7e79 *tests/data/fate/vsynth1-ljpeg.avi
 6312924 tests/data/fate/vsynth1-ljpeg.avi
 c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-ljpeg.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-mpeg4 b/tests/ref/vsynth/vsynth1-mpeg4
index 9a917d0..38a7294 100644
--- a/tests/ref/vsynth/vsynth1-mpeg4
+++ b/tests/ref/vsynth/vsynth1-mpeg4
@@ -1,4 +1,4 @@
-59a9e2eed314abface66aaf1b45eb8f2 *tests/data/fate/vsynth1-mpeg4.mp4
+dc927acd770e19a97456ecbd4d786938 *tests/data/fate/vsynth1-mpeg4.mp4
 540180 tests/data/fate/vsynth1-mpeg4.mp4
 8828a375448dc5c2215163ba70656f89 *tests/data/fate/vsynth1-mpeg4.out.rawvideo
 stddev:    7.97 PSNR: 30.10 MAXDIFF:  105 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-prores b/tests/ref/vsynth/vsynth1-prores
index ac30a6a..12aa758 100644
--- a/tests/ref/vsynth/vsynth1-prores
+++ b/tests/ref/vsynth/vsynth1-prores
@@ -1,4 +1,4 @@
-2566517b15c62887bd94daaab1b1a85b *tests/data/fate/vsynth1-prores.mov
+7dfcca40f50ff1d72541bc095c904784 *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
diff --git a/tests/ref/vsynth/vsynth1-qtrle b/tests/ref/vsynth/vsynth1-qtrle
index c9c8ccf..4ddd1d8 100644
--- a/tests/ref/vsynth/vsynth1-qtrle
+++ b/tests/ref/vsynth/vsynth1-qtrle
@@ -1,4 +1,4 @@
-7d75328a17e04796a39fe9be3a322946 *tests/data/fate/vsynth1-qtrle.mov
+24650c5b226d054c57be7c06c9220058 *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
diff --git a/tests/ref/vsynth/vsynth1-snow b/tests/ref/vsynth/vsynth1-snow
deleted file mode 100644
index 701b5cc..0000000
--- a/tests/ref/vsynth/vsynth1-snow
+++ /dev/null
@@ -1,4 +0,0 @@
-44fed844eb715fba0cc2433e7d7713bb *tests/data/fate/vsynth1-snow.avi
-136076 tests/data/fate/vsynth1-snow.avi
-91021b7d6d7908648fe78cc1975af8c4 *tests/data/fate/vsynth1-snow.out.rawvideo
-stddev:   22.77 PSNR: 20.98 MAXDIFF:  172 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-snow-hpel b/tests/ref/vsynth/vsynth1-snow-hpel
deleted file mode 100644
index c22ad0a..0000000
--- a/tests/ref/vsynth/vsynth1-snow-hpel
+++ /dev/null
@@ -1,4 +0,0 @@
-f60c8cb8f41b66bc38df87e9bdb84b34 *tests/data/fate/vsynth1-snow-hpel.avi
-138700 tests/data/fate/vsynth1-snow-hpel.avi
-d6845c8f1310e041afdcebc6bbfc449b *tests/data/fate/vsynth1-snow-hpel.out.rawvideo
-stddev:   22.74 PSNR: 20.99 MAXDIFF:  171 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-snow-ll b/tests/ref/vsynth/vsynth1-snow-ll
deleted file mode 100644
index 1636af5..0000000
--- a/tests/ref/vsynth/vsynth1-snow-ll
+++ /dev/null
@@ -1,4 +0,0 @@
-bdc7a025cd306f3da0d377b06bbe909b *tests/data/fate/vsynth1-snow-ll.avi
-3419968 tests/data/fate/vsynth1-snow-ll.avi
-c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-snow-ll.out.rawvideo
-stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-svq1 b/tests/ref/vsynth/vsynth1-svq1
index 0f8a6b2..f610fdc 100644
--- a/tests/ref/vsynth/vsynth1-svq1
+++ b/tests/ref/vsynth/vsynth1-svq1
@@ -1,4 +1,4 @@
-5c9d8734693f3cab57f61e76b5b6da7d *tests/data/fate/vsynth1-svq1.mov
+3c90c6c0c4db7993660cee642de05bb4 *tests/data/fate/vsynth1-svq1.mov
 1334367 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/vsynth/vsynth1-wmv2 b/tests/ref/vsynth/vsynth1-wmv2
index 82efc62..6a3cd3b 100644
--- a/tests/ref/vsynth/vsynth1-wmv2
+++ b/tests/ref/vsynth/vsynth1-wmv2
@@ -1,4 +1,4 @@
-fc0796c6c49a18034cef008d61c0d964 *tests/data/fate/vsynth1-wmv2.avi
-659840 tests/data/fate/vsynth1-wmv2.avi
-5182edba5b5e0354b39ce4f3604b62da *tests/data/fate/vsynth1-wmv2.out.rawvideo
-stddev:    7.97 PSNR: 30.09 MAXDIFF:  110 bytes:  7603200/  7603200
+3c8a93fa645574f5b11eb51cf0efd227 *tests/data/fate/vsynth1-wmv2.avi
+659162 tests/data/fate/vsynth1-wmv2.avi
+2d61f24836d54766e8d370f243d83dcd *tests/data/fate/vsynth1-wmv2.out.rawvideo
+stddev:    7.97 PSNR: 30.09 MAXDIFF:  105 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-dnxhd-1080i b/tests/ref/vsynth/vsynth2-dnxhd-1080i
index 27c79a5..35db6d2 100644
--- a/tests/ref/vsynth/vsynth2-dnxhd-1080i
+++ b/tests/ref/vsynth/vsynth2-dnxhd-1080i
@@ -1,4 +1,4 @@
-65ca6385b565b6ea9a2e28150eef1d46 *tests/data/fate/vsynth2-dnxhd-1080i.mov
+c456f2a7ac9435ea5bfea86bc69c1c41 *tests/data/fate/vsynth2-dnxhd-1080i.mov
 3031875 tests/data/fate/vsynth2-dnxhd-1080i.mov
 42262a2325441b38b3b3c8a42d888e7d *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
 stddev:    1.31 PSNR: 45.77 MAXDIFF:   23 bytes:  7603200/   760320
diff --git a/tests/ref/vsynth/vsynth2-ffv1 b/tests/ref/vsynth/vsynth2-ffv1
index 888e843..8263b01 100644
--- a/tests/ref/vsynth/vsynth2-ffv1
+++ b/tests/ref/vsynth/vsynth2-ffv1
@@ -1,4 +1,4 @@
-3a757276e299bf88c30e06dfb53f1c99 *tests/data/fate/vsynth2-ffv1.avi
-3525792 tests/data/fate/vsynth2-ffv1.avi
+9d8486fc8a260204d8ee3212d95915b5 *tests/data/fate/vsynth2-ffv1.avi
+3546258 tests/data/fate/vsynth2-ffv1.avi
 dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ffv1.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-ljpeg b/tests/ref/vsynth/vsynth2-ljpeg
index fa2f978..a7b8a2d 100644
--- a/tests/ref/vsynth/vsynth2-ljpeg
+++ b/tests/ref/vsynth/vsynth2-ljpeg
@@ -1,4 +1,4 @@
-db9fd56e154b1056c9443a82a96db6f5 *tests/data/fate/vsynth2-ljpeg.avi
+5d603cecd59db0f255a53bda837a6bae *tests/data/fate/vsynth2-ljpeg.avi
 4766902 tests/data/fate/vsynth2-ljpeg.avi
 dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ljpeg.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-mpeg4 b/tests/ref/vsynth/vsynth2-mpeg4
index 4d96557..a654c13 100644
--- a/tests/ref/vsynth/vsynth2-mpeg4
+++ b/tests/ref/vsynth/vsynth2-mpeg4
@@ -1,4 +1,4 @@
-8c9afbf564008a8ce6719cc3546deae1 *tests/data/fate/vsynth2-mpeg4.mp4
+0282105e98166fac06f7ba9e857cfbfe *tests/data/fate/vsynth2-mpeg4.mp4
 119833 tests/data/fate/vsynth2-mpeg4.mp4
 90a3577850239083a9042bef33c50e85 *tests/data/fate/vsynth2-mpeg4.out.rawvideo
 stddev:    5.34 PSNR: 33.57 MAXDIFF:   83 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-prores b/tests/ref/vsynth/vsynth2-prores
index 9a834ed..9d56b95 100644
--- a/tests/ref/vsynth/vsynth2-prores
+++ b/tests/ref/vsynth/vsynth2-prores
@@ -1,4 +1,4 @@
-28755ce05e812adbb8b7c180318ffba8 *tests/data/fate/vsynth2-prores.mov
+7d167fee27e8c34968bbecec282f927a *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
diff --git a/tests/ref/vsynth/vsynth2-qtrle b/tests/ref/vsynth/vsynth2-qtrle
index ceee854..ac2b557 100644
--- a/tests/ref/vsynth/vsynth2-qtrle
+++ b/tests/ref/vsynth/vsynth2-qtrle
@@ -1,4 +1,4 @@
-4805f35ca6e03b9279cc18f3f7356366 *tests/data/fate/vsynth2-qtrle.mov
+fe3db3dd385b8e5dc43cccc17b50f7f0 *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
diff --git a/tests/ref/vsynth/vsynth2-snow b/tests/ref/vsynth/vsynth2-snow
deleted file mode 100644
index 12f3811..0000000
--- a/tests/ref/vsynth/vsynth2-snow
+++ /dev/null
@@ -1,4 +0,0 @@
-4b6236e23ae4a52655f2c24c5a09380a *tests/data/fate/vsynth2-snow.avi
-57688 tests/data/fate/vsynth2-snow.avi
-8890189af71a0dd3447c4e8424c9a76b *tests/data/fate/vsynth2-snow.out.rawvideo
-stddev:   10.47 PSNR: 27.72 MAXDIFF:  119 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-snow-hpel b/tests/ref/vsynth/vsynth2-snow-hpel
deleted file mode 100644
index 955f1bf..0000000
--- a/tests/ref/vsynth/vsynth2-snow-hpel
+++ /dev/null
@@ -1,4 +0,0 @@
-9872032345c33cf8e8fc26ab655be3d3 *tests/data/fate/vsynth2-snow-hpel.avi
-61760 tests/data/fate/vsynth2-snow-hpel.avi
-8680d40905f423999d65b996c4dcb984 *tests/data/fate/vsynth2-snow-hpel.out.rawvideo
-stddev:   10.45 PSNR: 27.74 MAXDIFF:  123 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-snow-ll b/tests/ref/vsynth/vsynth2-snow-ll
deleted file mode 100644
index 9a72549..0000000
--- a/tests/ref/vsynth/vsynth2-snow-ll
+++ /dev/null
@@ -1,4 +0,0 @@
-30b40e0bf64f92b23d6f94056c0c6da5 *tests/data/fate/vsynth2-snow-ll.avi
-2721746 tests/data/fate/vsynth2-snow-ll.avi
-dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-snow-ll.out.rawvideo
-stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-svq1 b/tests/ref/vsynth/vsynth2-svq1
index 251f72d..e2af545 100644
--- a/tests/ref/vsynth/vsynth2-svq1
+++ b/tests/ref/vsynth/vsynth2-svq1
@@ -1,4 +1,4 @@
-138ad38281570f1a3b68d63ed896435d *tests/data/fate/vsynth2-svq1.mov
+c15de1e0b0439981dc94b927b1933889 *tests/data/fate/vsynth2-svq1.mov
 766851 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/vsynth/vsynth2-wmv2 b/tests/ref/vsynth/vsynth2-wmv2
index 043dac9..25c0dee 100644
--- a/tests/ref/vsynth/vsynth2-wmv2
+++ b/tests/ref/vsynth/vsynth2-wmv2
@@ -1,4 +1,4 @@
-0760abea07c386ab956fa1bb8b14c599 *tests/data/fate/vsynth2-wmv2.avi
+c7db61ce6fc07e8fb9a7204992c2e4c4 *tests/data/fate/vsynth2-wmv2.avi
 129848 tests/data/fate/vsynth2-wmv2.avi
-81eee429b665254d19a06607463c0b5e *tests/data/fate/vsynth2-wmv2.out.rawvideo
-stddev:    5.33 PSNR: 33.60 MAXDIFF:   77 bytes:  7603200/  7603200
+288bdf1b411b814a067ceb00ac6b9d16 *tests/data/fate/vsynth2-wmv2.out.rawvideo
+stddev:    5.33 PSNR: 33.59 MAXDIFF:   77 bytes:  7603200/  7603200
diff --git a/tests/tiny_psnr.c b/tests/tiny_psnr.c
index b1bcc16..66eaf82 100644
--- a/tests/tiny_psnr.c
+++ b/tests/tiny_psnr.c
@@ -23,8 +23,11 @@
 #include <string.h>
 #include <inttypes.h>
 #include <assert.h>
+#include <math.h>
+#include <float.h>
 
 #include "libavutil/intfloat.h"
+#include "libavutil/intreadwrite.h"
 
 #define FFMIN(a, b) ((a) > (b) ? (b) : (a))
 #define F 100
@@ -107,21 +110,26 @@ static float get_f32l(uint8_t *p)
     return v.f;
 }
 
+static double get_f64l(uint8_t *p)
+{
+    return av_int2double(AV_RL64(p));
+}
+
 int main(int argc, char *argv[])
 {
     int i, j;
     uint64_t sse = 0;
-    uint64_t dev;
+    double sse_d = 0.0;
     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]);
     int size0      = 0;
     int size1      = 0;
-    int maxdist    = 0;
+    uint64_t maxdist = 0;
+    double maxdist_d = 0.0;
 
     if (argc < 3) {
         printf("tiny_psnr <file1> <file2> [<elem size> [<shift> [<skip bytes>]]]\n");
@@ -136,6 +144,8 @@ int main(int argc, char *argv[])
             len = 2;
         } else if (!strcmp(argv[3], "f32")) {
             len = 4;
+        } else if (!strcmp(argv[3], "f64")) {
+            len = 8;
         } else {
             char *end;
             len = strtol(argv[3], &end, 0);
@@ -184,23 +194,42 @@ int main(int argc, char *argv[])
         int s1 = fread(buf[1], 1, SIZE, f[1]);
 
         for (j = 0; j < FFMIN(s0, s1); j += len) {
-            int64_t a = buf[0][j];
-            int64_t b = buf[1][j];
-            int dist;
-            if (len == 2) {
-                a = get_s16l(buf[0] + j);
-                b = get_s16l(buf[1] + j);
-            } else if (len == 4) {
-                a = get_f32l(buf[0] + j) * (1 << 24);
-                b = get_f32l(buf[1] + j) * (1 << 24);
-            } else {
-                a = buf[0][j];
-                b = buf[1][j];
+            switch (len) {
+            case 1:
+            case 2: {
+                int64_t a = buf[0][j];
+                int64_t b = buf[1][j];
+                int dist;
+                if (len == 2) {
+                    a = get_s16l(buf[0] + j);
+                    b = get_s16l(buf[1] + j);
+                } else {
+                    a = buf[0][j];
+                    b = buf[1][j];
+                }
+                sse += (a - b) * (a - b);
+                dist = abs(a - b);
+                if (dist > maxdist)
+                    maxdist = dist;
+                break;
+            }
+            case 4:
+            case 8: {
+                double dist, a, b;
+                if (len == 8) {
+                    a = get_f64l(buf[0] + j);
+                    b = get_f64l(buf[1] + j);
+                } else {
+                    a = get_f32l(buf[0] + j);
+                    b = get_f32l(buf[1] + j);
+                }
+                dist = fabs(a - b);
+                sse_d += (a - b) * (a - b);
+                if (dist > maxdist_d)
+                    maxdist_d = dist;
+                break;
+            }
             }
-            sse += (a - b) * (a - b);
-            dist = abs(a - b);
-            if (dist > maxdist)
-                maxdist = dist;
         }
         size0 += s0;
         size1 += s1;
@@ -211,16 +240,41 @@ int main(int argc, char *argv[])
     i = FFMIN(size0, size1) / len;
     if (!i)
         i = 1;
-    dev = int_sqrt(((sse / i) * F * F) + (((sse % i) * F * F) + i / 2) / i);
-    if (sse)
-        psnr = ((2 * log16(max << 16) + log16(i) - log16(sse)) *
-                284619LL * F + (1LL << 31)) / (1LL << 32);
-    else
-        psnr = 1000 * F - 1; // floating point free infinity :)
-
-    printf("stddev:%5d.%02d PSNR:%3d.%02d MAXDIFF:%5d bytes:%9d/%9d\n",
-           (int)(dev / F), (int)(dev % F),
-           (int)(psnr / F), (int)(psnr % F),
-           maxdist, size0, size1);
+    switch (len) {
+    case 1:
+    case 2: {
+        uint64_t psnr;
+        uint64_t dev = int_sqrt(((sse / i) * F * F) + (((sse % i) * F * F) + i / 2) / i);
+        if (sse)
+            psnr = ((2 * log16(max << 16) + log16(i) - log16(sse)) *
+                    284619LL * F + (1LL << 31)) / (1LL << 32);
+        else
+            psnr = 1000 * F - 1; // floating point free infinity :)
+
+        printf("stddev:%5d.%02d PSNR:%3d.%02d MAXDIFF:%5"PRIu64" bytes:%9d/%9d\n",
+               (int)(dev / F), (int)(dev % F),
+               (int)(psnr / F), (int)(psnr % F),
+               maxdist, size0, size1);
+        break;
+        }
+    case 4:
+    case 8: {
+        char psnr_str[64];
+        double dev = sqrt(sse_d / i);
+        uint64_t scale = (len == 4) ? (1ULL << 24) : (1ULL << 32);
+
+        if (sse_d) {
+            double psnr = 2 * log(DBL_MAX) - log(i / sse_d);
+            snprintf(psnr_str, sizeof(psnr_str), "%5.02f", psnr);
+        } else
+            snprintf(psnr_str, sizeof(psnr_str), "inf");
+
+        maxdist = maxdist_d * scale;
+
+        printf("stddev:%10.2f PSNR:%s MAXDIFF:%10"PRIu64" bytes:%9d/%9d\n",
+               dev * scale, psnr_str, maxdist, size0, size1);
+        break;
+    }
+    }
     return 0;
 }
diff --git a/tools/graph2dot.c b/tools/graph2dot.c
index c0142cc..12f1066 100644
--- a/tools/graph2dot.c
+++ b/tools/graph2dot.c
@@ -25,10 +25,11 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "libavutil/channel_layout.h"
 #include "libavutil/mem.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/audioconvert.h"
-#include "libavfilter/avfiltergraph.h"
+#include "libavfilter/avfilter.h"
 
 #if !HAVE_GETOPT
 #include "compat/getopt.c"
@@ -36,7 +37,7 @@
 
 static void usage(void)
 {
-    printf("Convert a libavfilter graph to a dot file\n");
+    printf("Convert a libavfilter graph to a dot file.\n");
     printf("Usage: graph2dot [OPTIONS]\n");
     printf("\n"
            "Options:\n"
@@ -58,7 +59,7 @@ static void print_digraph(FILE *outfile, AVFilterGraph *graph)
     fprintf(outfile, "node [shape=box]\n");
     fprintf(outfile, "rankdir=LR\n");
 
-    for (i = 0; i < graph->filter_count; i++) {
+    for (i = 0; i < graph->nb_filters; i++) {
         char filter_ctx_label[128];
         const AVFilterContext *filter_ctx = graph->filters[i];
 
@@ -66,7 +67,7 @@ static void print_digraph(FILE *outfile, AVFilterGraph *graph)
                  filter_ctx->name,
                  filter_ctx->filter->name);
 
-        for (j = 0; j < filter_ctx->output_count; j++) {
+        for (j = 0; j < filter_ctx->nb_outputs; j++) {
             AVFilterLink *link = filter_ctx->outputs[j];
             if (link) {
                 char dst_filter_ctx_label[128];
@@ -133,7 +134,7 @@ int main(int argc, char **argv)
         infilename = "/dev/stdin";
     infile = fopen(infilename, "r");
     if (!infile) {
-        fprintf(stderr, "Impossible to open input file '%s': %s\n",
+        fprintf(stderr, "Failed to open input file '%s': %s\n",
                 infilename, strerror(errno));
         return 1;
     }
@@ -142,7 +143,7 @@ int main(int argc, char **argv)
         outfilename = "/dev/stdout";
     outfile = fopen(outfilename, "w");
     if (!outfile) {
-        fprintf(stderr, "Impossible to open output file '%s': %s\n",
+        fprintf(stderr, "Failed to open output file '%s': %s\n",
                 outfilename, strerror(errno));
         return 1;
     }
@@ -175,7 +176,7 @@ int main(int argc, char **argv)
     avfilter_register_all();
 
     if (avfilter_graph_parse(graph, graph_string, NULL, NULL, NULL) < 0) {
-        fprintf(stderr, "Impossible to parse the graph description\n");
+        fprintf(stderr, "Failed to parse the graph description\n");
         return 1;
     }
 
diff --git a/tools/ismindex.c b/tools/ismindex.c
index bf8c69d..a51c5b7 100644
--- a/tools/ismindex.c
+++ b/tools/ismindex.c
@@ -34,13 +34,9 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <sys/stat.h>
-#ifdef _WIN32
-#include <direct.h>
-#define mkdir(a, b) _mkdir(a)
-#endif
 
 #include "libavformat/avformat.h"
+#include "libavformat/os_support.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 
@@ -53,10 +49,10 @@ static int usage(const char *argv0, int ret)
 struct MoofOffset {
     int64_t time;
     int64_t offset;
-    int duration;
+    int64_t duration;
 };
 
-struct VideoFile {
+struct Track {
     const char *name;
     int64_t duration;
     int bitrate;
@@ -74,12 +70,12 @@ struct VideoFile {
     int tag;
 };
 
-struct VideoFiles {
-    int nb_files;
+struct Tracks {
+    int nb_tracks;
     int64_t duration;
-    struct VideoFile **files;
-    int video_file, audio_file;
-    int nb_video_files, nb_audio_files;
+    struct Track **tracks;
+    int video_track, audio_track;
+    int nb_video_tracks, nb_audio_tracks;
 };
 
 static int copy_tag(AVIOContext *in, AVIOContext *out, int32_t tag_name)
@@ -120,62 +116,62 @@ static int write_fragment(const char *filename, AVIOContext *in)
     return ret;
 }
 
-static int write_fragments(struct VideoFiles *files, int start_index,
+static int write_fragments(struct Tracks *tracks, int start_index,
                            AVIOContext *in)
 {
     char dirname[100], filename[500];
     int i, j;
 
-    for (i = start_index; i < files->nb_files; i++) {
-        struct VideoFile *vf = files->files[i];
-        const char *type     = vf->is_video ? "video" : "audio";
-        snprintf(dirname, sizeof(dirname), "QualityLevels(%d)", vf->bitrate);
+    for (i = start_index; i < tracks->nb_tracks; i++) {
+        struct Track *track = tracks->tracks[i];
+        const char *type    = track->is_video ? "video" : "audio";
+        snprintf(dirname, sizeof(dirname), "QualityLevels(%d)", track->bitrate);
         mkdir(dirname, 0777);
-        for (j = 0; j < vf->chunks; j++) {
+        for (j = 0; j < track->chunks; j++) {
             snprintf(filename, sizeof(filename), "%s/Fragments(%s=%"PRId64")",
-                     dirname, type, vf->offsets[j].time);
-            avio_seek(in, vf->offsets[j].offset, SEEK_SET);
+                     dirname, type, track->offsets[j].time);
+            avio_seek(in, track->offsets[j].offset, SEEK_SET);
             write_fragment(filename, in);
         }
     }
     return 0;
 }
 
-static int read_tfra(struct VideoFiles *files, int start_index, AVIOContext *f)
+static int read_tfra(struct Tracks *tracks, int start_index, AVIOContext *f)
 {
     int ret = AVERROR_EOF, track_id;
     int version, fieldlength, i, j;
     int64_t pos   = avio_tell(f);
     uint32_t size = avio_rb32(f);
-    struct VideoFile *vf = NULL;
+    struct Track *track = NULL;
 
     if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a'))
         goto fail;
     version = avio_r8(f);
     avio_rb24(f);
     track_id = avio_rb32(f); /* track id */
-    for (i = start_index; i < files->nb_files && !vf; i++)
-        if (files->files[i]->track_id == track_id)
-            vf = files->files[i];
-    if (!vf) {
+    for (i = start_index; i < tracks->nb_tracks && !track; i++)
+        if (tracks->tracks[i]->track_id == track_id)
+            track = tracks->tracks[i];
+    if (!track) {
         /* Ok, continue parsing the next atom */
         ret = 0;
         goto fail;
     }
     fieldlength = avio_rb32(f);
-    vf->chunks  = avio_rb32(f);
-    vf->offsets = av_mallocz(sizeof(*vf->offsets) * vf->chunks);
-    if (!vf->offsets) {
+    track->chunks  = avio_rb32(f);
+    track->offsets = av_mallocz(sizeof(*track->offsets) * track->chunks);
+    if (!track->offsets) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-    for (i = 0; i < vf->chunks; i++) {
+    for (i = 0; i < track->chunks; i++) {
         if (version == 1) {
-            vf->offsets[i].time   = avio_rb64(f);
-            vf->offsets[i].offset = avio_rb64(f);
+            track->offsets[i].time   = avio_rb64(f);
+            track->offsets[i].offset = avio_rb64(f);
         } else {
-            vf->offsets[i].time   = avio_rb32(f);
-            vf->offsets[i].offset = avio_rb32(f);
+            track->offsets[i].time   = avio_rb32(f);
+            track->offsets[i].offset = avio_rb32(f);
         }
         for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
             avio_r8(f);
@@ -184,12 +180,12 @@ static int read_tfra(struct VideoFiles *files, int start_index, AVIOContext *f)
         for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
             avio_r8(f);
         if (i > 0)
-            vf->offsets[i - 1].duration = vf->offsets[i].time -
-                                          vf->offsets[i - 1].time;
+            track->offsets[i - 1].duration = track->offsets[i].time -
+                                             track->offsets[i - 1].time;
     }
-    if (vf->chunks > 0)
-        vf->offsets[vf->chunks - 1].duration = vf->duration -
-                                               vf->offsets[vf->chunks - 1].time;
+    if (track->chunks > 0)
+        track->offsets[track->chunks - 1].duration = track->duration -
+                                                     track->offsets[track->chunks - 1].time;
     ret = 0;
 
 fail:
@@ -197,7 +193,7 @@ fail:
     return ret;
 }
 
-static int read_mfra(struct VideoFiles *files, int start_index,
+static int read_mfra(struct Tracks *tracks, int start_index,
                      const char *file, int split)
 {
     int err = 0;
@@ -217,12 +213,12 @@ static int read_mfra(struct VideoFiles *files, int start_index,
         err = AVERROR_INVALIDDATA;
         goto fail;
     }
-    while (!read_tfra(files, start_index, f)) {
+    while (!read_tfra(tracks, start_index, f)) {
         /* Empty */
     }
 
     if (split)
-        write_fragments(files, start_index, f);
+        write_fragments(tracks, start_index, f);
 
 fail:
     if (f)
@@ -232,24 +228,24 @@ fail:
     return err;
 }
 
-static int get_private_data(struct VideoFile *vf, AVCodecContext *codec)
+static int get_private_data(struct Track *track, AVCodecContext *codec)
 {
-    vf->codec_private_size = codec->extradata_size;
-    vf->codec_private      = av_mallocz(codec->extradata_size);
-    if (!vf->codec_private)
+    track->codec_private_size = codec->extradata_size;
+    track->codec_private      = av_mallocz(codec->extradata_size);
+    if (!track->codec_private)
         return AVERROR(ENOMEM);
-    memcpy(vf->codec_private, codec->extradata, codec->extradata_size);
+    memcpy(track->codec_private, codec->extradata, codec->extradata_size);
     return 0;
 }
 
-static int get_video_private_data(struct VideoFile *vf, AVCodecContext *codec)
+static int get_video_private_data(struct Track *track, AVCodecContext *codec)
 {
     AVIOContext *io = NULL;
     uint16_t sps_size, pps_size;
     int err = AVERROR(EINVAL);
 
     if (codec->codec_id == AV_CODEC_ID_VC1)
-        return get_private_data(vf, codec);
+        return get_private_data(track, codec);
 
     avio_open_dyn_buf(&io);
     if (codec->extradata_size < 11 || codec->extradata[0] != 1)
@@ -267,16 +263,16 @@ static int get_video_private_data(struct VideoFile *vf, AVCodecContext *codec)
     err = 0;
 
 fail:
-    vf->codec_private_size = avio_close_dyn_buf(io, &vf->codec_private);
+    track->codec_private_size = avio_close_dyn_buf(io, &track->codec_private);
     return err;
 }
 
-static int handle_file(struct VideoFiles *files, const char *file, int split)
+static int handle_file(struct Tracks *tracks, const char *file, int split)
 {
     AVFormatContext *ctx = NULL;
-    int err = 0, i, orig_files = files->nb_files;
+    int err = 0, i, orig_tracks = tracks->nb_tracks;
     char errbuf[50], *ptr;
-    struct VideoFile *vf;
+    struct Track *track;
 
     err = avformat_open_input(&ctx, file, NULL, NULL);
     if (err < 0) {
@@ -296,72 +292,84 @@ static int handle_file(struct VideoFiles *files, const char *file, int split)
         fprintf(stderr, "No streams found in %s\n", file);
         goto fail;
     }
-    if (!files->duration)
-        files->duration = ctx->duration;
 
     for (i = 0; i < ctx->nb_streams; i++) {
+        struct Track **temp;
         AVStream *st = ctx->streams[i];
-        vf = av_mallocz(sizeof(*vf));
-        files->files = av_realloc(files->files,
-                                  sizeof(*files->files) * (files->nb_files + 1));
-        files->files[files->nb_files] = vf;
+        track = av_mallocz(sizeof(*track));
+        if (!track) {
+            err = AVERROR(ENOMEM);
+            goto fail;
+        }
+        temp = av_realloc(tracks->tracks,
+                          sizeof(*tracks->tracks) * (tracks->nb_tracks + 1));
+        if (!temp) {
+            av_free(track);
+            err = AVERROR(ENOMEM);
+            goto fail;
+        }
+        tracks->tracks = temp;
+        tracks->tracks[tracks->nb_tracks] = track;
 
-        vf->name = file;
+        track->name = file;
         if ((ptr = strrchr(file, '/')) != NULL)
-            vf->name = ptr + 1;
+            track->name = ptr + 1;
 
-        vf->bitrate   = st->codec->bit_rate;
-        vf->track_id  = st->id;
-        vf->timescale = st->time_base.den;
-        vf->duration  = av_rescale_rnd(ctx->duration, vf->timescale,
-                                       AV_TIME_BASE, AV_ROUND_UP);
-        vf->is_audio  = st->codec->codec_type == AVMEDIA_TYPE_AUDIO;
-        vf->is_video  = st->codec->codec_type == AVMEDIA_TYPE_VIDEO;
+        track->bitrate   = st->codec->bit_rate;
+        track->track_id  = st->id;
+        track->timescale = st->time_base.den;
+        track->duration  = st->duration;
+        track->is_audio  = st->codec->codec_type == AVMEDIA_TYPE_AUDIO;
+        track->is_video  = st->codec->codec_type == AVMEDIA_TYPE_VIDEO;
 
-        if (!vf->is_audio && !vf->is_video) {
+        if (!track->is_audio && !track->is_video) {
             fprintf(stderr,
                     "Track %d in %s is neither video nor audio, skipping\n",
-                    vf->track_id, file);
-            av_freep(&files->files[files->nb_files]);
+                    track->track_id, file);
+            av_freep(&tracks->tracks[tracks->nb_tracks]);
             continue;
         }
 
-        if (vf->is_audio) {
-            if (files->audio_file < 0)
-                files->audio_file = files->nb_files;
-            files->nb_audio_files++;
-            vf->channels    = st->codec->channels;
-            vf->sample_rate = st->codec->sample_rate;
+        tracks->duration = FFMAX(tracks->duration,
+                                 av_rescale_rnd(track->duration, AV_TIME_BASE,
+                                                track->timescale, AV_ROUND_UP));
+
+        if (track->is_audio) {
+            if (tracks->audio_track < 0)
+                tracks->audio_track = tracks->nb_tracks;
+            tracks->nb_audio_tracks++;
+            track->channels    = st->codec->channels;
+            track->sample_rate = st->codec->sample_rate;
             if (st->codec->codec_id == AV_CODEC_ID_AAC) {
-                vf->fourcc    = "AACL";
-                vf->tag       = 255;
-                vf->blocksize = 4;
+                track->fourcc    = "AACL";
+                track->tag       = 255;
+                track->blocksize = 4;
             } else if (st->codec->codec_id == AV_CODEC_ID_WMAPRO) {
-                vf->fourcc    = "WMAP";
-                vf->tag       = st->codec->codec_tag;
-                vf->blocksize = st->codec->block_align;
+                track->fourcc    = "WMAP";
+                track->tag       = st->codec->codec_tag;
+                track->blocksize = st->codec->block_align;
             }
-            get_private_data(vf, st->codec);
+            get_private_data(track, st->codec);
         }
-        if (vf->is_video) {
-            if (files->video_file < 0)
-                files->video_file = files->nb_files;
-            files->nb_video_files++;
-            vf->width  = st->codec->width;
-            vf->height = st->codec->height;
+        if (track->is_video) {
+            if (tracks->video_track < 0)
+                tracks->video_track = tracks->nb_tracks;
+            tracks->nb_video_tracks++;
+            track->width  = st->codec->width;
+            track->height = st->codec->height;
             if (st->codec->codec_id == AV_CODEC_ID_H264)
-                vf->fourcc = "H264";
+                track->fourcc = "H264";
             else if (st->codec->codec_id == AV_CODEC_ID_VC1)
-                vf->fourcc = "WVC1";
-            get_video_private_data(vf, st->codec);
+                track->fourcc = "WVC1";
+            get_video_private_data(track, st->codec);
         }
 
-        files->nb_files++;
+        tracks->nb_tracks++;
     }
 
     avformat_close_input(&ctx);
 
-    err = read_mfra(files, orig_files, file, split);
+    err = read_mfra(tracks, orig_tracks, file, split);
 
 fail:
     if (ctx)
@@ -369,7 +377,7 @@ fail:
     return err;
 }
 
-static void output_server_manifest(struct VideoFiles *files,
+static void output_server_manifest(struct Tracks *tracks,
                                    const char *basename)
 {
     char filename[1000];
@@ -390,13 +398,13 @@ static void output_server_manifest(struct VideoFiles *files,
     fprintf(out, "\t</head>\n");
     fprintf(out, "\t<body>\n");
     fprintf(out, "\t\t<switch>\n");
-    for (i = 0; i < files->nb_files; i++) {
-        struct VideoFile *vf = files->files[i];
-        const char *type     = vf->is_video ? "video" : "audio";
+    for (i = 0; i < tracks->nb_tracks; i++) {
+        struct Track *track = tracks->tracks[i];
+        const char *type    = track->is_video ? "video" : "audio";
         fprintf(out, "\t\t\t<%s src=\"%s\" systemBitrate=\"%d\">\n",
-                type, vf->name, vf->bitrate);
+                type, track->name, track->bitrate);
         fprintf(out, "\t\t\t\t<param name=\"trackID\" value=\"%d\" "
-                     "valueType=\"data\" />\n", vf->track_id);
+                     "valueType=\"data\" />\n", track->track_id);
         fprintf(out, "\t\t\t</%s>\n", type);
     }
     fprintf(out, "\t\t</switch>\n");
@@ -405,7 +413,24 @@ static void output_server_manifest(struct VideoFiles *files,
     fclose(out);
 }
 
-static void output_client_manifest(struct VideoFiles *files,
+static void print_track_chunks(FILE *out, struct Tracks *tracks, int main,
+                               const char *type)
+{
+    int i, j;
+    struct Track *track = tracks->tracks[main];
+    for (i = 0; i < track->chunks; i++) {
+        for (j = main + 1; j < tracks->nb_tracks; j++) {
+            if (tracks->tracks[j]->is_audio == track->is_audio &&
+                track->offsets[i].duration != tracks->tracks[j]->offsets[i].duration)
+                fprintf(stderr, "Mismatched duration of %s chunk %d in %s and %s\n",
+                        type, i, track->name, tracks->tracks[j]->name);
+        }
+        fprintf(out, "\t\t<c n=\"%d\" d=\"%"PRId64"\" />\n",
+                i, track->offsets[i].duration);
+    }
+}
+
+static void output_client_manifest(struct Tracks *tracks,
                                    const char *basename, int split)
 {
     char filename[1000];
@@ -423,108 +448,88 @@ static void output_client_manifest(struct VideoFiles *files,
     }
     fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
     fprintf(out, "<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" "
-                 "Duration=\"%"PRId64 "\">\n", files->duration * 10);
-    if (files->video_file >= 0) {
-        struct VideoFile *vf = files->files[files->video_file];
-        struct VideoFile *first_vf = vf;
+                 "Duration=\"%"PRId64 "\">\n", tracks->duration * 10);
+    if (tracks->video_track >= 0) {
+        struct Track *track = tracks->tracks[tracks->video_track];
+        struct Track *first_track = track;
         int index = 0;
         fprintf(out,
                 "\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" "
                 "Chunks=\"%d\" "
                 "Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n",
-                files->nb_video_files, vf->chunks);
-        for (i = 0; i < files->nb_files; i++) {
-            vf = files->files[i];
-            if (!vf->is_video)
+                tracks->nb_video_tracks, track->chunks);
+        for (i = 0; i < tracks->nb_tracks; i++) {
+            track = tracks->tracks[i];
+            if (!track->is_video)
                 continue;
             fprintf(out,
                     "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
                     "FourCC=\"%s\" MaxWidth=\"%d\" MaxHeight=\"%d\" "
                     "CodecPrivateData=\"",
-                    index, vf->bitrate, vf->fourcc, vf->width, vf->height);
-            for (j = 0; j < vf->codec_private_size; j++)
-                fprintf(out, "%02X", vf->codec_private[j]);
+                    index, track->bitrate, track->fourcc, track->width, track->height);
+            for (j = 0; j < track->codec_private_size; j++)
+                fprintf(out, "%02X", track->codec_private[j]);
             fprintf(out, "\" />\n");
             index++;
-            if (vf->chunks != first_vf->chunks)
+            if (track->chunks != first_track->chunks)
                 fprintf(stderr, "Mismatched number of video chunks in %s and %s\n",
-                        vf->name, first_vf->name);
-        }
-        vf = first_vf;
-        for (i = 0; i < vf->chunks; i++) {
-            for (j = files->video_file + 1; j < files->nb_files; j++) {
-                if (files->files[j]->is_video &&
-                    vf->offsets[i].duration != files->files[j]->offsets[i].duration)
-                    fprintf(stderr, "Mismatched duration of video chunk %d in %s and %s\n",
-                            i, vf->name, files->files[j]->name);
-            }
-            fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n", i,
-                    vf->offsets[i].duration);
+                        track->name, first_track->name);
         }
+        print_track_chunks(out, tracks, tracks->video_track, "video");
         fprintf(out, "\t</StreamIndex>\n");
     }
-    if (files->audio_file >= 0) {
-        struct VideoFile *vf = files->files[files->audio_file];
-        struct VideoFile *first_vf = vf;
+    if (tracks->audio_track >= 0) {
+        struct Track *track = tracks->tracks[tracks->audio_track];
+        struct Track *first_track = track;
         int index = 0;
         fprintf(out,
                 "\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" "
                 "Chunks=\"%d\" "
                 "Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n",
-                files->nb_audio_files, vf->chunks);
-        for (i = 0; i < files->nb_files; i++) {
-            vf = files->files[i];
-            if (!vf->is_audio)
+                tracks->nb_audio_tracks, track->chunks);
+        for (i = 0; i < tracks->nb_tracks; i++) {
+            track = tracks->tracks[i];
+            if (!track->is_audio)
                 continue;
             fprintf(out,
                     "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
                     "FourCC=\"%s\" SamplingRate=\"%d\" Channels=\"%d\" "
                     "BitsPerSample=\"16\" PacketSize=\"%d\" "
                     "AudioTag=\"%d\" CodecPrivateData=\"",
-                    index, vf->bitrate, vf->fourcc, vf->sample_rate,
-                    vf->channels, vf->blocksize, vf->tag);
-            for (j = 0; j < vf->codec_private_size; j++)
-                fprintf(out, "%02X", vf->codec_private[j]);
+                    index, track->bitrate, track->fourcc, track->sample_rate,
+                    track->channels, track->blocksize, track->tag);
+            for (j = 0; j < track->codec_private_size; j++)
+                fprintf(out, "%02X", track->codec_private[j]);
             fprintf(out, "\" />\n");
             index++;
-            if (vf->chunks != first_vf->chunks)
+            if (track->chunks != first_track->chunks)
                 fprintf(stderr, "Mismatched number of audio chunks in %s and %s\n",
-                        vf->name, first_vf->name);
-        }
-        vf = first_vf;
-        for (i = 0; i < vf->chunks; i++) {
-            for (j = files->audio_file + 1; j < files->nb_files; j++) {
-                if (files->files[j]->is_audio &&
-                    vf->offsets[i].duration != files->files[j]->offsets[i].duration)
-                    fprintf(stderr, "Mismatched duration of audio chunk %d in %s and %s\n",
-                            i, vf->name, files->files[j]->name);
-            }
-            fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n",
-                    i, vf->offsets[i].duration);
+                        track->name, first_track->name);
         }
+        print_track_chunks(out, tracks, tracks->audio_track, "audio");
         fprintf(out, "\t</StreamIndex>\n");
     }
     fprintf(out, "</SmoothStreamingMedia>\n");
     fclose(out);
 }
 
-static void clean_files(struct VideoFiles *files)
+static void clean_tracks(struct Tracks *tracks)
 {
     int i;
-    for (i = 0; i < files->nb_files; i++) {
-        av_freep(&files->files[i]->codec_private);
-        av_freep(&files->files[i]->offsets);
-        av_freep(&files->files[i]);
+    for (i = 0; i < tracks->nb_tracks; i++) {
+        av_freep(&tracks->tracks[i]->codec_private);
+        av_freep(&tracks->tracks[i]->offsets);
+        av_freep(&tracks->tracks[i]);
     }
-    av_freep(&files->files);
-    files->nb_files = 0;
+    av_freep(&tracks->tracks);
+    tracks->nb_tracks = 0;
 }
 
 int main(int argc, char **argv)
 {
     const char *basename = NULL;
     int split = 0, i;
-    struct VideoFiles vf = { 0, .video_file = -1, .audio_file = -1 };
+    struct Tracks tracks = { 0, .video_track = -1, .audio_track = -1 };
 
     av_register_all();
 
@@ -537,18 +542,18 @@ int main(int argc, char **argv)
         } else if (argv[i][0] == '-') {
             return usage(argv[0], 1);
         } else {
-            if (handle_file(&vf, argv[i], split))
+            if (handle_file(&tracks, argv[i], split))
                 return 1;
         }
     }
-    if (!vf.nb_files || (!basename && !split))
+    if (!tracks.nb_tracks || (!basename && !split))
         return usage(argv[0], 1);
 
     if (!split)
-        output_server_manifest(&vf, basename);
-    output_client_manifest(&vf, basename, split);
+        output_server_manifest(&tracks, basename);
+    output_client_manifest(&tracks, basename, split);
 
-    clean_files(&vf);
+    clean_tracks(&tracks);
 
     return 0;
 }
diff --git a/tools/patcheck b/tools/patcheck
index d22cf3c..e681d6d 100755
--- a/tools/patcheck
+++ b/tools/patcheck
@@ -67,7 +67,7 @@ $EGREP $OPT '^\+ *(const *|)static' $*| $EGREP --color=always '[^=]= *(0|NULL)[^
 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|doesnt|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 'av_log\( *NULL' 'Missing context in av_log' $*
 hiegrep '[^sn]printf' 'Please use av_log' $*
@@ -173,7 +173,7 @@ vertical align =
 /* and * align
 arrays fitting in smaller types
 variables written to twice with no interspaced read
-memset(block, 0, 6*64*sizeof(DCTELEM)); -> clear_blocks
+memset(block, 0, 6*64*sizeof(int16_t)); -> clear_blocks
 check existence of long_name in AVCodec
 check that the patch does not touch codec & (de)muxer layer at the same time ->split
 
diff --git a/tools/pktdumper.c b/tools/pktdumper.c
index 98b9327..c6398fe 100644
--- a/tools/pktdumper.c
+++ b/tools/pktdumper.c
@@ -31,18 +31,18 @@
 #include <io.h>
 #endif
 
-#define FILENAME_BUF_SIZE 4096
-
 #include "libavutil/avstring.h"
 #include "libavutil/time.h"
 #include "libavformat/avformat.h"
 
+#define FILENAME_BUF_SIZE 4096
 #define PKTFILESUFF "_%08" PRId64 "_%02d_%010" PRId64 "_%06d_%c.bin"
 
 static int usage(int ret)
 {
-    fprintf(stderr, "dump (up to maxpkts) AVPackets as they are demuxed by libavformat.\n");
-    fprintf(stderr, "each packet is dumped in its own file named like `basename file.ext`_$PKTNUM_$STREAMINDEX_$STAMP_$SIZE_$FLAGS.bin\n");
+    fprintf(stderr, "Dump (up to maxpkts) AVPackets as they are demuxed by libavformat.\n");
+    fprintf(stderr, "Each packet is dumped in its own file named like\n");
+    fprintf(stderr, "$(basename file.ext)_$PKTNUM_$STREAMINDEX_$STAMP_$SIZE_$FLAGS.bin\n");
     fprintf(stderr, "pktdumper [-nw] file [maxpkts]\n");
     fprintf(stderr, "-n\twrite No file at all, only demux.\n");
     fprintf(stderr, "-w\tWait at end of processing instead of quitting.\n");
@@ -79,7 +79,7 @@ int main(int argc, char **argv)
     if (strrchr(fntemplate, '.'))
         *strrchr(fntemplate, '.') = '\0';
     if (strchr(fntemplate, '%')) {
-        fprintf(stderr, "can't use filenames containing '%%'\n");
+        fprintf(stderr, "cannot use filenames containing '%%'\n");
         return usage(1);
     }
     if (strlen(fntemplate) + sizeof(PKTFILESUFF) >= sizeof(fntemplate) - 1) {

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list